From 0771fe4b28bd757f8139fe330354be29535681cc Mon Sep 17 00:00:00 2001 From: Michael Webster Date: Tue, 5 Oct 2021 12:51:49 -0400 Subject: [PATCH 01/36] Rebase onto mutter 3.36.0-0ubuntu0.20.04.1 See linuxmint/cinnamon@d6253f1cb1a1e7bf1 and subsequent commits here for further details. --- .gitignore | 213 - AUTHORS | 1 - COPYING | 41 +- ChangeLog | 15414 ---------------- HACKING | 298 - MAINTAINERS | 8 - Makefile.am | 8 - NEWS | 2876 ++- README | 6 - README-Mutter | 422 - README.md | 45 + autogen.sh | 41 - clutter/.gitignore | 1 - clutter/Makefile.am | 53 - clutter/build/Makefile.am | 1 - clutter/build/autotools/.gitignore | 8 - clutter/build/autotools/Makefile.am | 10 - clutter/build/autotools/as-compiler-flag.m4 | 62 - clutter/build/autotools/glib-tap.mk | 134 - clutter/build/autotools/glibtests.m4 | 28 - clutter/build/autotools/tap-driver.sh | 652 - clutter/build/autotools/tap-test | 5 - clutter/clutter/Makefile.am | 741 - clutter/clutter/Makefile.am.enums | 52 - clutter/clutter/Makefile.am.marshal | 52 - clutter/clutter/cally/cally-actor.c | 108 +- clutter/clutter/cally/cally-actor.h | 12 +- clutter/clutter/cally/cally-clone.h | 4 +- clutter/clutter/cally/cally-factory.h | 2 +- clutter/clutter/cally/cally-group.h | 4 +- clutter/clutter/cally/cally-main.h | 4 +- clutter/clutter/cally/cally-rectangle.h | 4 +- clutter/clutter/cally/cally-root.c | 10 +- clutter/clutter/cally/cally-root.h | 4 +- clutter/clutter/cally/cally-stage.h | 4 +- clutter/clutter/cally/cally-text.c | 20 +- clutter/clutter/cally/cally-text.h | 4 +- clutter/clutter/cally/cally-texture.c | 98 - clutter/clutter/cally/cally-texture.h | 84 - clutter/clutter/cally/cally-util.c | 10 +- clutter/clutter/cally/cally-util.h | 2 +- clutter/clutter/cally/cally.c | 5 - clutter/clutter/cally/cally.h | 1 - clutter/clutter/clutter-action.c | 2 - clutter/clutter/clutter-action.h | 18 +- clutter/clutter/clutter-actor-box.c | 29 +- clutter/clutter/clutter-actor-meta.c | 21 +- clutter/clutter/clutter-actor-meta.h | 12 +- clutter/clutter/clutter-actor-private.h | 49 +- clutter/clutter/clutter-actor.c | 2735 +-- clutter/clutter/clutter-actor.h | 434 +- clutter/clutter/clutter-align-constraint.c | 2 - clutter/clutter/clutter-align-constraint.h | 16 +- clutter/clutter/clutter-animatable.c | 88 +- clutter/clutter/clutter-animatable.h | 34 +- clutter/clutter/clutter-autocleanups.h | 8 +- clutter/clutter/clutter-backend-private.h | 35 +- clutter/clutter/clutter-backend.c | 475 +- clutter/clutter/clutter-backend.h | 27 +- clutter/clutter/clutter-base-types.c | 1200 +- clutter/clutter/clutter-bezier.h | 2 +- clutter/clutter/clutter-bin-layout.c | 188 +- clutter/clutter/clutter-bin-layout.h | 4 +- clutter/clutter/clutter-bind-constraint.c | 57 +- clutter/clutter/clutter-bind-constraint.h | 16 +- clutter/clutter/clutter-binding-pool.c | 5 +- clutter/clutter/clutter-binding-pool.h | 26 +- clutter/clutter/clutter-blur-effect.c | 32 +- clutter/clutter/clutter-blur-effect.h | 4 +- clutter/clutter/clutter-box-layout.c | 71 +- clutter/clutter/clutter-box-layout.h | 50 +- .../clutter-brightness-contrast-effect.c | 48 +- .../clutter-brightness-contrast-effect.h | 16 +- clutter/clutter/clutter-build-config.h.meson | 14 + clutter/clutter/clutter-cairo.c | 2 - clutter/clutter/clutter-cairo.h | 4 +- clutter/clutter/clutter-canvas.c | 106 +- clutter/clutter/clutter-canvas.h | 14 +- clutter/clutter/clutter-child-meta.c | 3 +- clutter/clutter/clutter-child-meta.h | 6 +- clutter/clutter/clutter-click-action.c | 76 +- clutter/clutter/clutter-click-action.h | 12 +- clutter/clutter/clutter-clone.c | 17 +- clutter/clutter/clutter-clone.h | 8 +- clutter/clutter/clutter-color.c | 2 - clutter/clutter/clutter-color.h | 50 +- clutter/clutter/clutter-colorize-effect.c | 24 +- clutter/clutter/clutter-colorize-effect.h | 8 +- clutter/clutter/clutter-constraint-private.h | 7 - clutter/clutter/clutter-constraint.c | 15 +- clutter/clutter/clutter-constraint.h | 26 +- ...ter-util.h => clutter-container-private.h} | 22 +- clutter/clutter/clutter-container.c | 239 +- clutter/clutter/clutter-container.h | 41 +- clutter/clutter/clutter-content-private.h | 7 +- clutter/clutter/clutter-content.c | 86 +- clutter/clutter/clutter-content.h | 42 +- clutter/clutter/clutter-debug.h | 42 +- clutter/clutter/clutter-deform-effect.c | 23 +- clutter/clutter/clutter-deform-effect.h | 12 +- clutter/clutter/clutter-deprecated.h | 26 - clutter/clutter/clutter-desaturate-effect.c | 27 +- clutter/clutter/clutter-desaturate-effect.h | 8 +- .../clutter/clutter-device-manager-private.h | 281 - clutter/clutter/clutter-device-manager.c | 589 - clutter/clutter/clutter-device-manager.h | 161 - clutter/clutter/clutter-drag-action.c | 36 +- clutter/clutter/clutter-drag-action.h | 30 +- clutter/clutter/clutter-drop-action.c | 16 +- clutter/clutter/clutter-drop-action.h | 4 +- clutter/clutter/clutter-effect-private.h | 12 +- clutter/clutter/clutter-effect.c | 65 +- clutter/clutter/clutter-effect.h | 43 +- clutter/clutter/clutter-enum-types.h.in | 4 +- clutter/clutter/clutter-enums.h | 339 +- clutter/clutter/clutter-event-private.h | 7 + clutter/clutter/clutter-event-translator.c | 38 - clutter/clutter/clutter-event-translator.h | 41 - clutter/clutter/clutter-event.c | 133 +- clutter/clutter/clutter-event.h | 170 +- clutter/clutter/clutter-feature.c | 23 +- clutter/clutter/clutter-feature.h | 4 +- clutter/clutter/clutter-fixed-layout.c | 2 - clutter/clutter/clutter-fixed-layout.h | 4 +- clutter/clutter/clutter-flatten-effect.c | 2 - clutter/clutter/clutter-flow-layout.c | 2 - clutter/clutter/clutter-flow-layout.h | 32 +- clutter/clutter/clutter-gesture-action.c | 27 +- clutter/clutter/clutter-gesture-action.h | 38 +- clutter/clutter/clutter-graphene.c | 111 + .../{x11/clutter-glx.h => clutter-graphene.h} | 20 +- clutter/clutter/clutter-grid-layout.c | 10 +- clutter/clutter/clutter-grid-layout.h | 36 +- clutter/clutter/clutter-group.h | 2 +- clutter/clutter/clutter-id-pool.c | 2 - clutter/clutter/clutter-image.c | 47 +- clutter/clutter/clutter-image.h | 17 +- .../clutter/clutter-input-device-private.h | 255 + clutter/clutter/clutter-input-device-tool.c | 5 +- clutter/clutter/clutter-input-device-tool.h | 8 +- clutter/clutter/clutter-input-device.c | 234 +- clutter/clutter/clutter-input-device.h | 114 +- clutter/clutter/clutter-input-focus-private.h | 2 +- clutter/clutter/clutter-input-focus.c | 40 +- clutter/clutter/clutter-input-focus.h | 33 +- .../clutter/clutter-input-method-private.h | 4 +- clutter/clutter/clutter-input-method.c | 118 +- clutter/clutter/clutter-input-method.h | 35 +- .../clutter-input-pointer-a11y-private.h | 47 + clutter/clutter/clutter-input-pointer-a11y.c | 706 + clutter/clutter/clutter-interval.c | 14 +- clutter/clutter/clutter-interval.h | 38 +- clutter/clutter/clutter-keyframe-transition.c | 10 +- clutter/clutter/clutter-keyframe-transition.h | 20 +- clutter/clutter/clutter-keymap.c | 70 + clutter/clutter/clutter-keymap.h | 60 + clutter/clutter/clutter-keysyms-update.pl | 37 - clutter/clutter/clutter-layout-manager.c | 27 +- clutter/clutter/clutter-layout-manager.h | 35 +- clutter/clutter/clutter-layout-meta.c | 3 +- clutter/clutter/clutter-layout-meta.h | 4 +- clutter/clutter/clutter-macros.h | 275 +- clutter/clutter/clutter-main.c | 1330 +- clutter/clutter/clutter-main.h | 118 +- clutter/clutter/clutter-marshal.list | 10 +- .../clutter/clutter-master-clock-default.c | 271 +- clutter/clutter/clutter-master-clock.c | 6 - clutter/clutter/clutter-master-clock.h | 15 +- clutter/clutter/clutter-muffin.h | 81 - clutter/clutter/clutter-mutter.h | 83 + clutter/clutter/clutter-offscreen-effect.c | 279 +- clutter/clutter/clutter-offscreen-effect.h | 22 +- clutter/clutter/clutter-page-turn-effect.c | 2 - clutter/clutter/clutter-page-turn-effect.h | 16 +- .../clutter/clutter-paint-context-private.h | 41 + clutter/clutter/clutter-paint-context.c | 187 + clutter/clutter/clutter-paint-context.h | 65 + clutter/clutter/clutter-paint-node-private.h | 56 +- clutter/clutter/clutter-paint-node.c | 142 +- clutter/clutter/clutter-paint-node.h | 42 +- clutter/clutter/clutter-paint-nodes.c | 388 +- clutter/clutter/clutter-paint-nodes.h | 107 +- .../clutter/clutter-paint-volume-private.h | 2 +- clutter/clutter/clutter-paint-volume.c | 63 +- clutter/clutter/clutter-pan-action.c | 6 +- clutter/clutter/clutter-pan-action.h | 30 +- clutter/clutter/clutter-path-constraint.c | 2 - clutter/clutter/clutter-path-constraint.h | 12 +- clutter/clutter/clutter-path.c | 19 +- clutter/clutter/clutter-path.h | 52 +- .../clutter/clutter-pick-context-private.h | 25 + clutter/clutter/clutter-pick-context.c | 83 + ...stage-manager.h => clutter-pick-context.h} | 39 +- clutter/clutter/clutter-private.h | 85 +- clutter/clutter/clutter-property-transition.c | 8 +- clutter/clutter/clutter-property-transition.h | 8 +- clutter/clutter/clutter-rotate-action.c | 2 - clutter/clutter/clutter-rotate-action.h | 4 +- clutter/clutter/clutter-script-parser.c | 264 +- clutter/clutter/clutter-script-private.h | 12 +- clutter/clutter/clutter-script.c | 145 +- clutter/clutter/clutter-script.h | 45 +- clutter/clutter/clutter-scriptable.c | 4 +- clutter/clutter/clutter-scriptable.h | 10 +- clutter/clutter/clutter-scroll-actor.c | 40 +- clutter/clutter/clutter-scroll-actor.h | 20 +- clutter/clutter/clutter-seat.c | 740 + clutter/clutter/clutter-seat.h | 196 + clutter/clutter/clutter-settings.c | 20 +- clutter/clutter/clutter-settings.h | 4 +- clutter/clutter/clutter-shader-effect.c | 91 +- clutter/clutter/clutter-shader-effect.h | 14 +- clutter/clutter/clutter-shader-types.c | 2 - clutter/clutter/clutter-shader-types.h | 18 +- clutter/clutter/clutter-snap-constraint.c | 2 - clutter/clutter/clutter-snap-constraint.h | 16 +- clutter/clutter/clutter-stage-manager.c | 32 +- clutter/clutter/clutter-stage-manager.h | 10 +- clutter/clutter/clutter-stage-private.h | 49 +- clutter/clutter/clutter-stage-view-private.h | 46 + clutter/clutter/clutter-stage-view.c | 259 +- clutter/clutter/clutter-stage-view.h | 33 +- clutter/clutter/clutter-stage-window.c | 162 +- clutter/clutter/clutter-stage-window.h | 62 +- clutter/clutter/clutter-stage.c | 2596 ++- clutter/clutter/clutter-stage.h | 134 +- clutter/clutter/clutter-swipe-action.c | 2 - clutter/clutter/clutter-swipe-action.h | 4 +- clutter/clutter/clutter-tap-action.c | 5 +- clutter/clutter/clutter-tap-action.h | 4 +- clutter/clutter/clutter-text-buffer.c | 28 +- clutter/clutter/clutter-text-buffer.h | 26 +- clutter/clutter/clutter-text.c | 754 +- clutter/clutter/clutter-text.h | 156 +- clutter/clutter/clutter-texture.h | 130 - clutter/clutter/clutter-timeline.c | 86 +- clutter/clutter/clutter-timeline.h | 88 +- clutter/clutter/clutter-transition-group.c | 2 - clutter/clutter/clutter-transition-group.h | 10 +- clutter/clutter/clutter-transition.c | 7 +- clutter/clutter/clutter-transition.h | 22 +- clutter/clutter/clutter-types.h | 469 +- clutter/clutter/clutter-units.c | 6 +- clutter/clutter/clutter-units.h | 36 +- clutter/clutter/clutter-util.c | 208 +- clutter/clutter/clutter-version.h.in | 347 - .../clutter/clutter-virtual-input-device.c | 45 +- .../clutter/clutter-virtual-input-device.h | 28 +- clutter/clutter/clutter-zoom-action.c | 22 +- clutter/clutter/clutter-zoom-action.h | 18 +- clutter/clutter/clutter.h | 6 +- clutter/clutter/cogl/clutter-stage-cogl.c | 944 +- clutter/clutter/cogl/clutter-stage-cogl.h | 24 +- .../deprecated/clutter-actor-deprecated.c | 411 - clutter/clutter/deprecated/clutter-actor.h | 87 +- clutter/clutter/deprecated/clutter-alpha.c | 149 +- clutter/clutter/deprecated/clutter-alpha.h | 32 +- .../clutter/deprecated/clutter-animatable.h | 47 - .../clutter/deprecated/clutter-animation.c | 843 +- .../clutter/deprecated/clutter-animation.h | 88 +- clutter/clutter/deprecated/clutter-animator.c | 2166 --- clutter/clutter/deprecated/clutter-animator.h | 188 - clutter/clutter/deprecated/clutter-backend.h | 64 - .../deprecated/clutter-behaviour-depth.c | 305 - .../deprecated/clutter-behaviour-depth.h | 101 - .../deprecated/clutter-behaviour-ellipse.c | 1061 -- .../deprecated/clutter-behaviour-ellipse.h | 159 - .../deprecated/clutter-behaviour-opacity.c | 312 - .../deprecated/clutter-behaviour-opacity.h | 115 - .../deprecated/clutter-behaviour-path.c | 467 - .../deprecated/clutter-behaviour-path.h | 135 - .../deprecated/clutter-behaviour-rotate.c | 690 - .../deprecated/clutter-behaviour-rotate.h | 119 - .../deprecated/clutter-behaviour-scale.c | 439 - .../deprecated/clutter-behaviour-scale.h | 107 - .../clutter/deprecated/clutter-behaviour.c | 660 - .../clutter/deprecated/clutter-behaviour.h | 170 - .../clutter/deprecated/clutter-bin-layout.h | 56 - clutter/clutter/deprecated/clutter-box.c | 4 +- clutter/clutter/deprecated/clutter-box.h | 22 +- .../deprecated/clutter-cairo-texture.c | 1165 -- .../deprecated/clutter-cairo-texture.h | 139 - .../clutter/deprecated/clutter-container.h | 36 +- .../clutter/deprecated/clutter-frame-source.c | 263 - .../clutter/deprecated/clutter-frame-source.h | 49 - clutter/clutter/deprecated/clutter-group.c | 51 +- clutter/clutter/deprecated/clutter-group.h | 8 +- .../clutter-input-device-deprecated.c | 38 - .../clutter/deprecated/clutter-input-device.h | 41 - clutter/clutter/deprecated/clutter-keysyms.h | 2311 --- .../clutter-layout-manager-deprecated.c | 89 - .../clutter/deprecated/clutter-list-model.c | 836 - .../clutter/deprecated/clutter-list-model.h | 95 - clutter/clutter/deprecated/clutter-main.h | 96 - clutter/clutter/deprecated/clutter-media.c | 666 - clutter/clutter/deprecated/clutter-media.h | 121 - .../deprecated/clutter-model-private.h | 52 - clutter/clutter/deprecated/clutter-model.c | 2477 --- clutter/clutter/deprecated/clutter-model.h | 436 - .../clutter/deprecated/clutter-rectangle.c | 168 +- .../clutter/deprecated/clutter-rectangle.h | 18 +- clutter/clutter/deprecated/clutter-score.c | 1168 -- clutter/clutter/deprecated/clutter-score.h | 144 - clutter/clutter/deprecated/clutter-shader.c | 933 - clutter/clutter/deprecated/clutter-shader.h | 182 - clutter/clutter/deprecated/clutter-stage.h | 26 +- clutter/clutter/deprecated/clutter-state.c | 622 +- clutter/clutter/deprecated/clutter-state.h | 64 +- .../clutter/deprecated/clutter-table-layout.c | 2611 --- .../clutter/deprecated/clutter-table-layout.h | 172 - clutter/clutter/deprecated/clutter-texture.c | 3106 ---- clutter/clutter/deprecated/clutter-texture.h | 136 - clutter/clutter/deprecated/clutter-timeline.h | 6 +- .../deprecated/clutter-timeout-interval.c | 142 - .../deprecated/clutter-timeout-interval.h | 58 - .../clutter/deprecated/clutter-timeout-pool.c | 500 - .../clutter/deprecated/clutter-timeout-pool.h | 69 - .../clutter/egl/clutter-backend-eglnative.c | 96 +- .../clutter/egl/clutter-backend-eglnative.h | 7 +- clutter/clutter/egl/clutter-egl-headers.h | 9 - clutter/clutter/egl/clutter-egl.h | 45 +- .../evdev/clutter-device-manager-evdev.c | 2747 --- .../evdev/clutter-device-manager-evdev.h | 108 - clutter/clutter/evdev/clutter-evdev.h | 181 - clutter/clutter/evdev/clutter-event-evdev.c | 191 - .../evdev/clutter-input-device-evdev.h | 157 - .../evdev/clutter-input-device-tool-evdev.h | 84 - clutter/clutter/evdev/clutter-seat-evdev.c | 893 - clutter/clutter/evdev/clutter-seat-evdev.h | 163 - .../clutter-virtual-input-device-evdev.c | 684 - clutter/clutter/evdev/clutter-xkb-utils.h | 46 - clutter/clutter/meson.build | 561 + clutter/clutter/muffin-clutter.pc.in | 24 - clutter/clutter/mutter-clutter.pc.in | 24 + .../wayland/clutter-wayland-compositor.h | 2 +- .../clutter/wayland/clutter-wayland-surface.c | 652 - .../clutter/wayland/clutter-wayland-surface.h | 117 - clutter/clutter/x11/clutter-backend-x11.c | 434 +- clutter/clutter/x11/clutter-backend-x11.h | 42 +- .../x11/clutter-device-manager-core-x11.c | 555 - .../x11/clutter-device-manager-core-x11.h | 70 - .../clutter/x11/clutter-device-manager-xi2.h | 73 - clutter/clutter/x11/clutter-event-x11.c | 394 - .../clutter/x11/clutter-glx-texture-pixmap.c | 159 - .../clutter/x11/clutter-glx-texture-pixmap.h | 93 - .../x11/clutter-input-device-core-x11.c | 78 - .../x11/clutter-input-device-core-x11.h | 44 - .../x11/clutter-input-device-tool-xi2.h | 74 - .../clutter/x11/clutter-input-device-xi2.c | 357 - .../clutter/x11/clutter-input-device-xi2.h | 69 - clutter/clutter/x11/clutter-keymap-x11.c | 667 - clutter/clutter/x11/clutter-keymap-x11.h | 56 - clutter/clutter/x11/clutter-stage-x11.c | 1604 -- clutter/clutter/x11/clutter-stage-x11.h | 98 - .../x11/clutter-virtual-input-device-x11.c | 194 - .../clutter/x11/clutter-x11-texture-pixmap.c | 1270 -- .../clutter/x11/clutter-x11-texture-pixmap.h | 116 - clutter/clutter/x11/clutter-x11.h | 71 +- .../clutter/x11/xsettings/xsettings-client.c | 2 +- clutter/configure.ac | 880 - clutter/examples/Makefile.am | 36 - clutter/examples/actor-model.c | 522 - clutter/examples/basic-actor.c | 153 - clutter/examples/bin-layout.c | 307 - clutter/examples/box-layout.c | 314 - clutter/examples/canvas.c | 170 - clutter/examples/constraints.c | 90 - clutter/examples/drag-action.c | 249 - clutter/examples/drop-action.c | 263 - clutter/examples/easing-modes.c | 241 - clutter/examples/flow-layout.c | 164 - clutter/examples/grid-layout.c | 378 - clutter/examples/image-content.c | 110 - clutter/examples/layout-manager.c | 461 - clutter/examples/pan-action.c | 194 - clutter/examples/rounded-rectangle.c | 110 - clutter/examples/scroll-actor.c | 193 - clutter/examples/threads.c | 292 - clutter/meson.build | 88 + clutter/tests/Makefile.am | 3 - clutter/tests/accessibility/.gitignore | 5 - clutter/tests/accessibility/Makefile.am | 37 - clutter/tests/conform/Makefile.am | 100 - .../conform/actor-offscreen-limit-max-size.c | 119 - clutter/tests/conform/animator.c | 199 - clutter/tests/conform/behaviours.c | 80 - clutter/tests/conform/cairo-texture.c | 198 - clutter/tests/conform/events-touch.c | 392 - clutter/tests/conform/model.c | 528 - clutter/tests/conform/score.c | 121 - .../scripts/test-script-implicit-alpha.json | 8 - clutter/tests/conform/texture.c | 84 - clutter/tests/interactive/Makefile.am | 148 - clutter/tests/interactive/redhand.png | Bin 8250 -> 0 bytes clutter/tests/interactive/test-animator.c | 138 - .../interactive/test-cogl-shader-arbfp.c | 407 - .../tests/interactive/test-cogl-tex-foreign.c | 272 - .../interactive/test-cogl-vertex-buffer.c | 390 - clutter/tests/interactive/test-depth.c | 211 - clutter/tests/interactive/test-fbo.c | 105 - clutter/tests/interactive/test-multistage.c | 149 - clutter/tests/interactive/test-pixmap.c | 331 - clutter/tests/interactive/test-scale.c | 119 - .../interactive/test-stage-read-pixels.c | 168 - .../tests/interactive/test-state-animator.c | 144 - clutter/tests/interactive/test-table-layout.c | 284 - .../tests/interactive/test-texture-async.c | 156 - .../tests/interactive/test-texture-material.c | 46 - .../tests/interactive/test-texture-quality.c | 116 - .../tests/interactive/test-texture-slicing.c | 125 - clutter/tests/micro-bench/.gitignore | 5 - clutter/tests/micro-bench/Makefile.am | 35 - clutter/tests/performance/.gitignore | 7 - clutter/tests/performance/Makefile-retrospect | 66 - clutter/tests/performance/Makefile-tests | 15 - clutter/tests/performance/Makefile.am | 43 - cogl/.gitignore | 3 +- cogl/Makefile.am | 35 - cogl/build/autotools/Makefile.am.enums | 52 - cogl/build/autotools/as-compiler-flag.m4 | 62 - cogl/build/autotools/introspection.m4 | 94 - cogl/cogl-config.h.meson | 16 + cogl/cogl-gles2/GLES2/gl2.h | 169 - cogl/cogl-gles2/GLES2/gl2ext.h | 1498 -- cogl/cogl-gles2/GLES2/gl2platform.h | 28 - cogl/cogl-gles2/Makefile.am | 35 - cogl/cogl-gles2/cogl-gles2-api.c | 1048 -- cogl/cogl-gles2/muffin-cogl-gles2.pc.in | 13 - cogl/cogl-muffin-config.h.in | 17 - cogl/cogl-mutter-config.h.in | 7 + cogl/cogl-pango/Makefile.am | 93 - cogl/cogl-pango/cogl-pango-display-list.c | 39 +- cogl/cogl-pango/cogl-pango-display-list.h | 4 +- cogl/cogl-pango/cogl-pango-fontmap.c | 16 +- cogl/cogl-pango/cogl-pango-glyph-cache.c | 26 +- cogl/cogl-pango/cogl-pango-glyph-cache.h | 20 +- cogl/cogl-pango/cogl-pango-pipeline-cache.c | 6 +- cogl/cogl-pango/cogl-pango-pipeline-cache.h | 8 +- cogl/cogl-pango/cogl-pango-private.h | 8 +- cogl/cogl-pango/cogl-pango-render.c | 114 +- cogl/cogl-pango/cogl-pango.h | 93 +- cogl/cogl-pango/cogl-pango.symbols | 3 - cogl/cogl-pango/meson.build | 81 + cogl/cogl-pango/muffin-cogl-pango.pc.in | 13 - cogl/cogl-pango/mutter-cogl-pango.pc.in | 13 + cogl/cogl-path/Makefile.am | 102 - cogl/cogl-path/cogl-path-enum-types.c.in | 2 - cogl/cogl-path/cogl-path-enum-types.h.in | 2 +- cogl/cogl-path/cogl-path-functions.h | 104 +- cogl/cogl-path/cogl-path-private.h | 8 +- cogl/cogl-path/cogl-path-types.h | 7 +- cogl/cogl-path/cogl-path.c | 113 +- cogl/cogl-path/meson.build | 87 + cogl/cogl-path/muffin-cogl-path.pc.in | 13 - cogl/cogl-path/mutter-cogl-path.pc.in | 13 + cogl/cogl-path/tesselator/GL/glu.h | 47 - cogl/cogl-path/tesselator/memalloc.h | 4 +- cogl/cogl-path/tesselator/mesh.c | 4 +- cogl/cogl-path/tesselator/mesh.h | 2 +- cogl/cogl-path/tesselator/normal.h | 1 + cogl/cogl-path/tesselator/render.h | 1 + cogl/cogl-path/tesselator/sweep.h | 1 + cogl/cogl-path/tesselator/tess.h | 1 - cogl/cogl-path/tesselator/tesselator.h | 2 +- cogl/cogl/Makefile.am | 510 - cogl/cogl/cogl-atlas-texture-private.h | 8 +- cogl/cogl/cogl-atlas-texture.c | 115 +- cogl/cogl/cogl-atlas-texture.h | 23 +- cogl/cogl/cogl-atlas.c | 74 +- cogl/cogl/cogl-atlas.h | 8 +- cogl/cogl/cogl-attribute-buffer.c | 4 +- cogl/cogl/cogl-attribute-buffer.h | 11 +- cogl/cogl/cogl-attribute-private.h | 13 +- cogl/cogl/cogl-attribute.c | 97 +- cogl/cogl/cogl-attribute.h | 45 +- cogl/cogl/cogl-bitmap-conversion.c | 49 +- cogl/cogl/cogl-bitmap-pixbuf.c | 13 +- cogl/cogl/cogl-bitmap-private.h | 78 +- cogl/cogl/cogl-bitmap.c | 153 +- cogl/cogl/cogl-bitmap.h | 38 +- cogl/cogl/cogl-bitmask.c | 8 +- cogl/cogl/cogl-bitmask.h | 20 +- cogl/cogl/cogl-blend-string.c | 121 +- cogl/cogl/cogl-blend-string.h | 14 +- cogl/cogl/cogl-blit.c | 63 +- cogl/cogl/cogl-blit.h | 4 +- cogl/cogl/cogl-boxed-value.c | 20 +- cogl/cogl/cogl-boxed-value.h | 7 +- cogl/cogl/cogl-buffer-private.h | 29 +- cogl/cogl/cogl-buffer.c | 74 +- cogl/cogl/cogl-buffer.h | 39 +- cogl/cogl/cogl-clip-stack.c | 39 +- cogl/cogl/cogl-clip-stack.h | 20 +- cogl/cogl/cogl-closure-list-private.h | 2 +- cogl/cogl/cogl-color.c | 36 +- cogl/cogl/cogl-color.h | 117 +- cogl/cogl/cogl-config.c | 135 - cogl/cogl/cogl-context-private.h | 97 +- cogl/cogl/cogl-context.c | 279 +- cogl/cogl/cogl-context.h | 86 +- cogl/cogl/cogl-debug-options.h | 30 +- cogl/cogl/cogl-debug.c | 19 +- cogl/cogl/cogl-debug.h | 24 +- cogl/cogl/cogl-defines.h.in | 5 - ...d-fixed-private.h => cogl-defines.h.meson} | 30 +- cogl/cogl/cogl-deprecated.h | 43 - cogl/cogl/cogl-depth-state.c | 26 +- cogl/cogl/cogl-depth-state.h | 37 +- cogl/cogl/cogl-display-private.h | 2 +- cogl/cogl/cogl-display.c | 14 +- cogl/cogl/cogl-display.h | 19 +- cogl/cogl/cogl-dma-buf-handle.c | 94 + cogl/cogl/cogl-dma-buf-handle.h | 83 + cogl/cogl/cogl-driver.h | 54 +- cogl/cogl/cogl-egl.h | 26 +- cogl/cogl/cogl-error-private.h | 57 - cogl/cogl/cogl-error.c | 128 - cogl/cogl/cogl-error.h | 169 - cogl/cogl/cogl-euler.c | 198 - cogl/cogl/cogl-euler.h | 265 - cogl/cogl/cogl-feature-private.c | 16 +- cogl/cogl/cogl-feature-private.h | 8 +- cogl/cogl/cogl-fence-private.h | 2 +- cogl/cogl/cogl-fence.c | 6 +- cogl/cogl/cogl-fence.h | 6 +- cogl/cogl/cogl-flags.h | 4 +- cogl/cogl/cogl-frame-info.c | 2 - cogl/cogl/cogl-frame-info.h | 16 +- cogl/cogl/cogl-framebuffer-private.h | 179 +- cogl/cogl/cogl-framebuffer.c | 660 +- cogl/cogl/cogl-framebuffer.h | 603 +- cogl/cogl/cogl-gl-header.h.in | 2 +- cogl/cogl/cogl-gles2-context-private.h | 201 - cogl/cogl/cogl-gles2-context.c | 1966 -- cogl/cogl/cogl-gles2-types.h | 475 - cogl/cogl/cogl-gles2.h | 416 - cogl/cogl/cogl-glib-source.c | 8 +- cogl/cogl/cogl-glib-source.h | 4 +- cogl/cogl/cogl-glsl-shader.c | 25 +- cogl/cogl/cogl-gpu-info-private.h | 7 +- cogl/cogl/cogl-gpu-info.c | 54 +- cogl/cogl/cogl-gtype-private.h | 2 + cogl/cogl/cogl-index-buffer.c | 2 - cogl/cogl/cogl-index-buffer.h | 10 +- cogl/cogl/cogl-indices.c | 30 +- cogl/cogl/cogl-indices.h | 23 +- cogl/cogl/cogl-journal-private.h | 10 +- cogl/cogl/cogl-journal.c | 235 +- cogl/cogl/cogl-list.c | 2 - cogl/cogl/cogl-macros.h | 209 +- cogl/cogl/cogl-magazine.c | 4 +- cogl/cogl/cogl-matrix-private.h | 4 +- cogl/cogl/cogl-matrix-stack-private.h | 48 +- cogl/cogl/cogl-matrix-stack.c | 273 +- cogl/cogl/cogl-matrix-stack.h | 67 +- cogl/cogl/cogl-matrix.c | 168 +- cogl/cogl/cogl-matrix.h | 125 +- cogl/cogl/cogl-memory-stack.c | 6 +- cogl/cogl/cogl-meta-texture.c | 95 +- cogl/cogl/cogl-meta-texture.h | 22 +- cogl/cogl/{cogl-muffin.h => cogl-mutter.h} | 12 +- cogl/cogl/cogl-node-private.h | 6 +- cogl/cogl/cogl-node.c | 6 +- cogl/cogl/cogl-object-private.h | 39 +- cogl/cogl/cogl-object.c | 22 +- cogl/cogl/cogl-object.h | 33 +- cogl/cogl/cogl-offscreen.h | 53 +- cogl/cogl/cogl-onscreen-private.h | 16 +- cogl/cogl/cogl-onscreen-template.c | 13 +- cogl/cogl/cogl-onscreen-template.h | 32 +- cogl/cogl/cogl-onscreen.c | 167 +- cogl/cogl/cogl-onscreen.h | 183 +- cogl/cogl/cogl-output-private.h | 2 +- cogl/cogl/cogl-output.c | 4 +- cogl/cogl/cogl-output.h | 26 +- cogl/cogl/cogl-pango.h | 36 - cogl/cogl/cogl-pipeline-cache.c | 10 +- cogl/cogl/cogl-pipeline-debug.c | 34 +- cogl/cogl/cogl-pipeline-hash-table.c | 4 +- cogl/cogl/cogl-pipeline-layer-private.h | 37 +- cogl/cogl/cogl-pipeline-layer-state-private.h | 26 +- cogl/cogl/cogl-pipeline-layer-state.c | 379 +- cogl/cogl/cogl-pipeline-layer-state.h | 118 +- cogl/cogl/cogl-pipeline-layer.c | 42 +- cogl/cogl/cogl-pipeline-private.h | 226 +- cogl/cogl/cogl-pipeline-snippet-private.h | 4 +- cogl/cogl/cogl-pipeline-snippet.c | 4 +- cogl/cogl/cogl-pipeline-state-private.h | 60 +- cogl/cogl/cogl-pipeline-state.c | 642 +- cogl/cogl/cogl-pipeline-state.h | 310 +- cogl/cogl/cogl-pipeline.c | 540 +- cogl/cogl/cogl-pipeline.h | 19 +- cogl/cogl/cogl-pixel-buffer-private.h | 4 +- cogl/cogl/cogl-pixel-buffer.c | 10 +- cogl/cogl/cogl-pixel-buffer.h | 40 +- cogl/cogl/cogl-pixel-format.c | 343 + cogl/cogl/cogl-pixel-format.h | 322 + cogl/cogl/cogl-point-in-poly-private.h | 4 +- cogl/cogl/cogl-point-in-poly.c | 2 - cogl/cogl/cogl-poll-private.h | 4 +- cogl/cogl/cogl-poll.c | 14 +- cogl/cogl/cogl-poll.h | 8 +- cogl/cogl/cogl-primitive-private.h | 2 +- cogl/cogl/cogl-primitive-texture.c | 8 +- cogl/cogl/cogl-primitive-texture.h | 23 +- cogl/cogl/cogl-primitive.c | 30 +- cogl/cogl/cogl-primitive.h | 57 +- cogl/cogl/cogl-primitives-private.h | 14 +- cogl/cogl/cogl-primitives.c | 476 +- cogl/cogl/cogl-primitives.h | 197 - cogl/cogl/cogl-private.h | 89 +- cogl/cogl/cogl-profile.c | 6 +- cogl/cogl/cogl-profile.h | 6 +- cogl/cogl/cogl-quaternion-private.h | 44 - cogl/cogl/cogl-quaternion.c | 673 - cogl/cogl/cogl-quaternion.h | 560 - cogl/cogl/cogl-rectangle-map.c | 24 +- cogl/cogl/cogl-rectangle-map.h | 2 +- cogl/cogl/cogl-renderer-private.h | 20 +- cogl/cogl/cogl-renderer.c | 230 +- cogl/cogl/cogl-renderer.h | 82 +- cogl/cogl/cogl-sampler-cache-private.h | 4 +- cogl/cogl/cogl-sampler-cache.c | 31 +- cogl/cogl/cogl-snippet-private.h | 2 +- cogl/cogl/cogl-snippet.c | 38 +- cogl/cogl/cogl-snippet.h | 33 +- cogl/cogl/cogl-spans.c | 8 +- cogl/cogl/cogl-spans.h | 6 +- cogl/cogl/cogl-sub-texture.c | 128 +- cogl/cogl/cogl-sub-texture.h | 10 +- cogl/cogl/cogl-swap-chain-private.h | 2 +- cogl/cogl/cogl-swap-chain.c | 4 +- cogl/cogl/cogl-swap-chain.h | 15 +- cogl/cogl/cogl-texture-2d-gl.h | 78 - cogl/cogl/cogl-texture-2d-private.h | 10 +- cogl/cogl/cogl-texture-2d-sliced-private.h | 12 +- cogl/cogl/cogl-texture-2d-sliced.c | 347 +- cogl/cogl/cogl-texture-2d-sliced.h | 25 +- cogl/cogl/cogl-texture-2d.c | 282 +- cogl/cogl/cogl-texture-2d.h | 79 +- cogl/cogl/cogl-texture-3d-private.h | 66 - cogl/cogl/cogl-texture-3d.c | 759 - cogl/cogl/cogl-texture-3d.h | 202 - cogl/cogl/cogl-texture-driver.h | 74 +- cogl/cogl/cogl-texture-private.h | 77 +- cogl/cogl/cogl-texture-rectangle-private.h | 66 - cogl/cogl/cogl-texture-rectangle.c | 777 - cogl/cogl/cogl-texture-rectangle.h | 216 - cogl/cogl/cogl-texture.c | 190 +- cogl/cogl/cogl-texture.h | 86 +- cogl/cogl/cogl-trace.c | 303 + cogl/cogl/cogl-trace.h | 117 + cogl/cogl/cogl-types.h | 439 +- cogl/cogl/cogl-util.c | 96 +- cogl/cogl/cogl-util.h | 96 +- cogl/cogl/cogl-vector.c | 300 - cogl/cogl/cogl-vector.h | 356 - cogl/cogl/cogl-version.h | 226 - cogl/cogl/cogl-wayland-server.h | 81 +- cogl/cogl/cogl-xlib-private.h | 6 - cogl/cogl/cogl-xlib-renderer-private.h | 9 +- cogl/cogl/cogl-xlib-renderer.c | 75 +- cogl/cogl/cogl-xlib-renderer.h | 80 +- cogl/cogl/cogl-xlib.c | 112 - cogl/cogl/cogl-xlib.h | 57 - cogl/cogl/cogl.c | 616 +- cogl/cogl/cogl.h | 28 +- cogl/cogl/cogl.symbols | 1087 -- cogl/cogl/cogl1-context.h | 722 +- cogl/cogl/deprecated/cogl-auto-texture.c | 168 +- cogl/cogl/deprecated/cogl-auto-texture.h | 71 +- cogl/cogl/deprecated/cogl-clutter-xlib.h | 50 - cogl/cogl/deprecated/cogl-clutter.c | 67 +- cogl/cogl/deprecated/cogl-clutter.h | 15 +- .../deprecated/cogl-framebuffer-deprecated.c | 295 - .../deprecated/cogl-framebuffer-deprecated.h | 117 +- cogl/cogl/deprecated/cogl-material-compat.c | 317 +- cogl/cogl/deprecated/cogl-material-compat.h | 832 +- cogl/cogl/deprecated/cogl-program-private.h | 9 +- cogl/cogl/deprecated/cogl-program.c | 238 +- cogl/cogl/deprecated/cogl-shader-private.h | 10 - cogl/cogl/deprecated/cogl-shader.c | 281 +- cogl/cogl/deprecated/cogl-shader.h | 278 +- cogl/cogl/deprecated/cogl-type-casts.h | 2 +- .../deprecated/cogl-vertex-buffer-private.h | 165 - cogl/cogl/deprecated/cogl-vertex-buffer.c | 1795 -- cogl/cogl/deprecated/cogl-vertex-buffer.h | 451 - .../driver/gl/cogl-attribute-gl-private.h | 3 - cogl/cogl/driver/gl/cogl-attribute-gl.c | 259 +- .../gl/cogl-bitmap-gl-private.h} | 33 +- cogl/cogl/driver/gl/cogl-bitmap-gl.c | 122 + cogl/cogl/driver/gl/cogl-buffer-gl-private.h | 8 +- cogl/cogl/driver/gl/cogl-buffer-gl.c | 57 +- cogl/cogl/driver/gl/cogl-clip-stack-gl.c | 487 +- .../driver/gl/cogl-framebuffer-gl-private.h | 11 +- cogl/cogl/driver/gl/cogl-framebuffer-gl.c | 322 +- .../driver/gl/cogl-pipeline-fragend-fixed.c | 435 - .../driver/gl/cogl-pipeline-fragend-glsl.c | 77 +- .../driver/gl/cogl-pipeline-opengl-private.h | 20 +- cogl/cogl/driver/gl/cogl-pipeline-opengl.c | 486 +- .../gl/cogl-pipeline-progend-fixed-private.h | 42 - .../driver/gl/cogl-pipeline-progend-fixed.c | 112 - .../driver/gl/cogl-pipeline-progend-glsl.c | 110 +- .../gl/cogl-pipeline-vertend-fixed-private.h | 42 - .../driver/gl/cogl-pipeline-vertend-fixed.c | 121 - .../driver/gl/cogl-pipeline-vertend-glsl.c | 58 +- .../driver/gl/cogl-texture-2d-gl-private.h | 22 +- cogl/cogl/driver/gl/cogl-texture-2d-gl.c | 423 +- cogl/cogl/driver/gl/cogl-texture-gl-private.h | 7 +- cogl/cogl/driver/gl/cogl-texture-gl.c | 52 +- cogl/cogl/driver/gl/cogl-util-gl-private.h | 17 +- cogl/cogl/driver/gl/cogl-util-gl.c | 83 +- cogl/cogl/driver/gl/gl/cogl-driver-gl.c | 342 +- .../gl/cogl-pipeline-fragend-arbfp-private.h | 42 - .../gl/gl/cogl-pipeline-fragend-arbfp.c | 988 - ...ogl-pipeline-progend-fixed-arbfp-private.h | 42 - .../gl/gl/cogl-pipeline-progend-fixed-arbfp.c | 121 - .../driver/gl/gl/cogl-texture-driver-gl.c | 218 +- cogl/cogl/driver/gl/gles/cogl-driver-gles.c | 177 +- .../driver/gl/gles/cogl-texture-driver-gles.c | 262 +- cogl/cogl/driver/nop/cogl-attribute-nop.c | 2 - cogl/cogl/driver/nop/cogl-clip-stack-nop.c | 2 - cogl/cogl/driver/nop/cogl-driver-nop.c | 24 +- .../driver/nop/cogl-framebuffer-nop-private.h | 11 +- cogl/cogl/driver/nop/cogl-framebuffer-nop.c | 15 +- .../driver/nop/cogl-texture-2d-nop-private.h | 13 +- cogl/cogl/driver/nop/cogl-texture-2d-nop.c | 16 +- cogl/cogl/gl-prototypes/cogl-all-functions.h | 117 +- cogl/cogl/gl-prototypes/cogl-core-functions.h | 51 +- .../cogl/gl-prototypes/cogl-fixed-functions.h | 119 - .../cogl/gl-prototypes/cogl-gles1-functions.h | 43 - cogl/cogl/gl-prototypes/cogl-glsl-functions.h | 82 - .../cogl-in-gles-core-functions.h | 82 - .../cogl-in-gles1-core-functions.h | 78 - .../cogl-in-gles2-core-functions.h | 43 - cogl/cogl/meson.build | 501 + .../{muffin-cogl.pc.in => mutter-cogl.pc.in} | 10 +- .../{ => winsys}/cogl-glx-display-private.h | 16 +- .../{ => winsys}/cogl-glx-renderer-private.h | 7 +- cogl/cogl/{ => winsys}/cogl-glx.h | 20 - .../winsys/cogl-texture-pixmap-x11-private.h | 4 +- cogl/cogl/winsys/cogl-texture-pixmap-x11.c | 244 +- cogl/cogl/winsys/cogl-texture-pixmap-x11.h | 60 +- .../cogl-winsys-egl-feature-functions.h | 6 + cogl/cogl/winsys/cogl-winsys-egl-private.h | 43 +- .../cogl/winsys/cogl-winsys-egl-x11-private.h | 4 +- cogl/cogl/winsys/cogl-winsys-egl-x11.c | 113 +- cogl/cogl/winsys/cogl-winsys-egl.c | 350 +- cogl/cogl/winsys/cogl-winsys-glx-private.h | 2 +- cogl/cogl/winsys/cogl-winsys-glx.c | 834 +- cogl/cogl/winsys/cogl-winsys-private.h | 72 +- cogl/cogl/winsys/cogl-winsys-stub-private.h | 37 - cogl/cogl/winsys/cogl-winsys-stub.c | 197 - cogl/cogl/winsys/cogl-winsys.c | 4 +- cogl/config-custom.h | 1 - cogl/configure.ac | 1024 - cogl/meson.build | 127 + cogl/test-fixtures/Makefile.am | 21 - cogl/test-fixtures/meson.build | 22 + cogl/test-fixtures/test-unit.h | 2 + cogl/test-fixtures/test-utils.c | 146 +- cogl/test-fixtures/test-utils.h | 13 +- cogl/tests/Makefile.am | 31 - cogl/tests/config.env.in | 1 - cogl/tests/conform/Makefile.am | 177 - cogl/tests/conform/meson.build | 129 + .../conform/meson/find-conform-unit-tests.sh | 8 + cogl/tests/conform/mutter-cogl.test.in | 4 + cogl/tests/conform/test-alpha-test.c | 1 + cogl/tests/conform/test-alpha-textures.c | 1 + cogl/tests/conform/test-atlas-migration.c | 9 +- cogl/tests/conform/test-backface-culling.c | 101 +- cogl/tests/conform/test-blend-strings.c | 198 +- cogl/tests/conform/test-blend.c | 1 + cogl/tests/conform/test-color-hsl.c | 1 + cogl/tests/conform/test-color-mask.c | 110 - cogl/tests/conform/test-conform-main.c | 19 +- .../tests/conform/test-copy-replace-texture.c | 1 + cogl/tests/conform/test-custom-attributes.c | 1 + cogl/tests/conform/test-declarations.h | 53 + cogl/tests/conform/test-depth-test.c | 78 +- .../{test-euler-quaternion.c => test-euler.c} | 21 +- cogl/tests/conform/test-fence.c | 5 +- cogl/tests/conform/test-fixed.c | 18 - .../tests/conform/test-framebuffer-get-bits.c | 1 + cogl/tests/conform/test-gles2-context.c | 962 - cogl/tests/conform/test-just-vertex-shader.c | 107 +- cogl/tests/conform/test-layer-remove.c | 1 + cogl/tests/conform/test-map-buffer-range.c | 1 + cogl/tests/conform/test-materials.c | 253 - cogl/tests/conform/test-multitexture.c | 26 +- cogl/tests/conform/test-npot-texture.c | 19 +- cogl/tests/conform/test-offscreen.c | 70 +- cogl/tests/conform/test-path-clip.c | 1 + cogl/tests/conform/test-path.c | 9 +- .../test-pipeline-cache-unrefs-texture.c | 1 + .../conform/test-pipeline-shader-state.c | 1 + cogl/tests/conform/test-pipeline-uniforms.c | 7 +- .../tests/conform/test-pipeline-user-matrix.c | 7 +- cogl/tests/conform/test-pixel-buffer.c | 9 +- .../tests/conform/test-point-size-attribute.c | 4 +- cogl/tests/conform/test-point-size.c | 4 +- cogl/tests/conform/test-point-sprite.c | 9 +- cogl/tests/conform/test-premult.c | 45 +- .../conform/test-primitive-and-journal.c | 1 + cogl/tests/conform/test-primitive.c | 5 +- .../tests/conform/test-read-texture-formats.c | 13 +- cogl/tests/conform/test-readpixels.c | 32 +- cogl/tests/conform/test-snippets.c | 7 +- cogl/tests/conform/test-sparse-pipeline.c | 1 + cogl/tests/conform/test-sub-texture.c | 23 +- cogl/tests/conform/test-texture-3d.c | 274 - .../tests/conform/test-texture-get-set-data.c | 5 +- cogl/tests/conform/test-texture-mipmaps.c | 16 +- cogl/tests/conform/test-texture-no-allocate.c | 25 +- cogl/tests/conform/test-texture-pixmap-x11.c | 20 +- cogl/tests/conform/test-texture-rectangle.c | 276 - cogl/tests/conform/test-texture-rg.c | 1 + cogl/tests/conform/test-version.c | 50 +- .../conform/test-vertex-buffer-contiguous.c | 257 - .../conform/test-vertex-buffer-interleved.c | 162 - .../conform/test-vertex-buffer-mutability.c | 198 - cogl/tests/conform/test-viewport.c | 24 +- cogl/tests/conform/test-wrap-modes.c | 101 +- .../conform/test-wrap-rectangle-textures.c | 175 - .../conform/test-write-texture-formats.c | 1 + cogl/tests/data/Makefile.am | 3 - cogl/tests/data/valgrind.suppressions | 8 - cogl/tests/meson.build | 22 + cogl/tests/micro-perf/Makefile.am | 24 - cogl/tests/micro-perf/test-journal.c | 190 - cogl/tests/run-tests.sh | 119 +- cogl/tests/test-launcher.sh | 14 +- cogl/tests/unit/Makefile.am | 84 - cogl/tests/unit/meson.build | 43 + cogl/tests/unit/meson/find-unit-tests.sh | 9 + config.h.meson | 72 + configure.ac | 543 - data/Makefile.am | 3 - data/default_icon.png | Bin 0 -> 1184 bytes data/meson.build | 45 + {src => data}/muffin.desktop.in | 2 +- data/org.cinnamon.muffin.gschema.xml.in | 188 + ...org.cinnamon.muffin.wayland.gschema.xml.in | 108 + data/org.cinnamon.muffin.x11.gschema.xml.in | 30 + data/theme/metacity-theme-3.xml | 1723 -- debian/README.Debian | 6 +- debian/changelog | 6 + debian/clean | 2 + debian/compat | 1 - debian/control | 151 +- debian/copyright | 521 +- debian/libmuffin-dev.install | 5 + debian/libmuffin0.bug-control | 1 + debian/libmuffin0.install | 6 +- debian/muffin-common.install | 1 - debian/muffin-common.maintscript | 1 - debian/muffin-doc.install | 1 - debian/muffin.docs | 1 + debian/muffin.postinst | 16 + debian/muffin.prerm | 12 + debian/not-installed | 4 - debian/rules | 117 +- debian/tests/control | 7 + debian/tests/libmutter-6-dev | 41 + doc/Makefile.am | 4 - doc/compositor-control.txt | 46 + doc/how-constraints-works.txt | 283 + doc/man/Makefile.am | 4 - doc/man/meson.build | 1 + doc/man/muffin-message.1 | 60 - doc/man/muffin-theme-viewer.1 | 43 - doc/man/muffin-window-demo.1 | 25 - doc/man/muffin.1 | 14 +- rationales.txt => doc/rationales.txt | 0 doc/reference/Makefile.am | 5 - doc/reference/clutter/ChangeLog | 1076 -- doc/reference/clutter/Makefile.am | 153 - doc/reference/clutter/actor-box.png | Bin 17917 -> 0 bytes doc/reference/clutter/actor-example.png | Bin 4966 -> 0 bytes doc/reference/clutter/animator-key-frames.png | Bin 11936 -> 0 bytes doc/reference/clutter/animator-key-frames.svg | 271 - doc/reference/clutter/bin-layout.png | Bin 13424 -> 0 bytes doc/reference/clutter/box-layout.png | Bin 10557 -> 0 bytes doc/reference/clutter/building-clutter.xml | 284 - doc/reference/clutter/clutter-docs.xml.in | 449 - doc/reference/clutter/clutter-overview.xml | 62 - doc/reference/clutter/constraints-example.png | Bin 6199 -> 0 bytes doc/reference/clutter/easing-modes.png | Bin 51834 -> 0 bytes doc/reference/clutter/easing-modes.svg | 920 - doc/reference/clutter/event-flow.dia | Bin 4543 -> 0 bytes doc/reference/clutter/event-flow.png | Bin 53730 -> 0 bytes doc/reference/clutter/flow-layout.png | Bin 1850 -> 0 bytes doc/reference/clutter/glossary.xml | 142 - .../clutter/migrating-ClutterAnimation.xml | 139 - .../clutter/migrating-ClutterBehaviour.xml | 120 - .../clutter/migrating-ClutterEffect.xml | 137 - .../clutter/migrating-ClutterPath.xml | 167 - doc/reference/clutter/offscreen-redirect.png | Bin 4821 -> 0 bytes doc/reference/clutter/path-alpha-func.png | Bin 41123 -> 0 bytes doc/reference/clutter/running-clutter.xml | 402 - doc/reference/clutter/table-layout.png | Bin 20058 -> 0 bytes doc/reference/cogl/Makefile.am | 130 - doc/reference/cogl/blend-strings.xml | 129 - doc/reference/cogl/cogl-docs.xml.in | 226 - doc/reference/cogl/cogl-sections.txt | 938 - doc/reference/cogl/cogl_ortho.png | Bin 12650 -> 0 bytes doc/reference/cogl/fill-rule-even-odd.png | Bin 3121 -> 0 bytes doc/reference/cogl/fill-rule-non-zero.png | Bin 3143 -> 0 bytes doc/reference/cogl/quad-indices-order.png | Bin 2620 -> 0 bytes doc/reference/cogl/quad-indices-triangles.png | Bin 8018 -> 0 bytes doc/reference/muffin-docs.sgml | 55 - doc/reference/muffin-docs.sgml.in | 55 - doc/reference/muffin-overview.xml | 15 - doc/reference/muffin/Makefile.am | 174 - doc/reference/muffin/muffin-docs.sgml.in | 55 - doc/reference/muffin/muffin-overrides.txt | 0 doc/reference/muffin/muffin-overview.xml | 15 - doc/reference/muffin/running-muffin.xml | 100 - doc/reference/running-muffin.xml | 100 - doc/strut-and-related-updating.txt | 54 + doc/theme-format.txt | 396 - meson.build | 480 + meson/meson-postinstall.sh | 10 + meson_options.txt | 166 + mutter.doap | 71 + po/ChangeLog | 5062 ----- po/LINGUAS | 4 + po/Makefile.in.in | 221 - po/POTFILES.in | 38 +- po/POTFILES.skip | 85 +- po/am.po | 1 + po/ar.po | 2755 ++- po/as.po | 2242 +-- po/ast.po | 226 +- po/az.po | 2 +- po/be.po | 2426 ++- po/be@latin.po | 1 + po/bg.po | 1868 +- po/bn.po | 1 + po/bn_IN.po | 2886 ++- po/br.po | 47 +- po/bs.po | 3565 +--- po/ca.po | 4187 +---- po/ca@valencia.po | 4350 +---- po/cs.po | 1953 +- po/cy.po | 3 +- po/da.po | 2710 ++- po/de.po | 2448 +-- po/dz.po | 1 + po/el.po | 2975 ++- po/en_CA.po | 1 + po/en_GB.po | 2742 ++- po/eo.po | 2337 +-- po/es.po | 3243 ++-- po/et.po | 2196 ++- po/eu.po | 2282 +-- po/fa.po | 5373 +++--- po/fi.po | 2092 +-- po/fr.po | 1989 +- po/fur.po | 772 + po/ga.po | 3314 +--- po/gd.po | 446 + po/gl.po | 2341 +-- po/gu.po | 1938 +- po/ha.po | 1 + po/he.po | 2493 +-- po/hi.po | 3695 ++-- po/hr.po | 6207 +++---- po/hu.po | 2409 +-- po/hy.po | 1 + po/id.po | 2206 +-- po/ig.po | 1 + po/is.po | 3177 +--- po/it.po | 3062 +-- po/ja.po | 3039 ++- po/ka.po | 1 + po/kk.po | 755 + po/kn.po | 3757 ++-- po/ko.po | 1934 +- po/ku.po | 1 + po/la.po | 1 + po/lt.po | 4520 +---- po/lv.po | 2794 +-- po/mai.po | 1 + po/meson.build | 1 + po/mg.po | 1 + po/mk.po | 1 + po/ml.po | 3477 ++-- po/mn.po | 3 +- po/mr.po | 3686 ++-- po/ms.po | 3776 ++-- po/nb.po | 1822 +- po/nds.po | 43 +- po/ne.po | 5166 +++--- po/nl.po | 2723 ++- po/nn.po | 1 + po/oc.po | 3331 +--- po/or.po | 3602 ++-- po/pa.po | 2717 ++- po/pl.po | 2012 +- po/pt.po | 3123 ++-- po/pt_BR.po | 2820 ++- po/ro.po | 3126 ++-- po/ru.po | 2298 +-- po/rw.po | 1 + po/si.po | 1 + po/sk.po | 4524 ++--- po/sl.po | 2023 +- po/sq.po | 1 + po/sr.po | 4413 +---- po/sr@latin.po | 4369 +---- po/sv.po | 2252 +-- po/ta.po | 2103 ++- po/te.po | 2106 ++- po/tg.po | 1663 ++ po/th.po | 3820 +--- po/tk.po | 1 + po/tr.po | 2726 ++- po/ug.po | 1630 +- po/uk.po | 4097 +--- po/vi.po | 4392 +---- po/wa.po | 1 + po/xh.po | 1 + po/yo.po | 1 + po/zh_CN.po | 2591 ++- po/zh_HK.po | 1523 +- po/zh_TW.po | 2199 +-- src/Makefile.am | 391 - src/backends/edid-parse.c | 542 + src/backends/edid.h | 193 + src/backends/gsm-inhibitor-flag.h | 36 + src/backends/meta-backend-private.h | 197 + src/backends/meta-backend-types.h | 58 + src/backends/meta-backend.c | 1496 ++ src/backends/meta-barrier-private.h | 66 + src/backends/meta-barrier.c | 361 + src/backends/meta-crtc.c | 108 + src/backends/meta-crtc.h | 115 + src/backends/meta-cursor-renderer.c | 378 + src/backends/meta-cursor-renderer.h | 85 + src/backends/meta-cursor-sprite-xcursor.c | 322 + src/backends/meta-cursor-sprite-xcursor.h | 43 + src/backends/meta-cursor-tracker-private.h | 67 + src/backends/meta-cursor-tracker.c | 464 + src/backends/meta-cursor.c | 241 + src/backends/meta-cursor.h | 84 + src/backends/meta-dbus-session-watcher.c | 237 + src/backends/meta-dbus-session-watcher.h | 52 + src/backends/meta-display-config-shared.h | 39 + src/backends/meta-dnd-private.h | 41 + src/backends/meta-egl-ext.h | 103 + src/backends/meta-egl.c | 1120 ++ src/backends/meta-egl.h | 263 + src/backends/meta-gles3-table.h | 36 + src/backends/meta-gles3.c | 163 + src/backends/meta-gles3.h | 83 + src/backends/meta-gpu.c | 225 + src/backends/meta-gpu.h | 72 + src/backends/meta-idle-monitor-dbus.c | 266 + src/backends/meta-idle-monitor-dbus.h | 28 + src/backends/meta-idle-monitor-private.h | 59 + src/backends/meta-idle-monitor.c | 515 + src/backends/meta-input-device-private.h | 48 + src/backends/meta-input-device.c | 137 + src/backends/meta-input-mapper-private.h | 49 + src/backends/meta-input-mapper.c | 703 + src/backends/meta-input-settings-private.h | 156 + src/backends/meta-input-settings.c | 2743 +++ src/backends/meta-logical-monitor.c | 338 + src/backends/meta-logical-monitor.h | 106 + src/backends/meta-monitor-config-manager.c | 2035 ++ src/backends/meta-monitor-config-manager.h | 206 + src/backends/meta-monitor-config-migration.c | 1236 ++ src/backends/meta-monitor-config-migration.h | 41 + src/backends/meta-monitor-config-store.c | 1685 ++ src/backends/meta-monitor-config-store.h | 60 + src/backends/meta-monitor-manager-dummy.c | 827 + src/backends/meta-monitor-manager-dummy.h | 36 + src/backends/meta-monitor-manager-private.h | 408 + src/backends/meta-monitor-manager.c | 3561 ++++ src/backends/meta-monitor-transform.c | 128 + src/backends/meta-monitor-transform.h | 72 + src/backends/meta-monitor.c | 1912 ++ src/backends/meta-monitor.h | 291 + src/backends/meta-orientation-manager.c | 280 + src/backends/meta-orientation-manager.h | 42 + src/backends/meta-output.c | 130 + src/backends/meta-output.h | 141 + src/backends/meta-pointer-constraint.c | 83 + src/backends/meta-pointer-constraint.h | 66 + src/backends/meta-profiler.c | 203 + src/backends/meta-profiler.h | 41 + .../meta-remote-access-controller-private.h | 34 + src/backends/meta-remote-access-controller.c | 158 + src/backends/meta-remote-desktop-session.c | 837 + src/backends/meta-remote-desktop-session.h | 56 + src/backends/meta-remote-desktop.c | 276 + src/backends/meta-remote-desktop.h | 46 + src/backends/meta-renderer-view.c | 200 + src/backends/meta-renderer-view.h | 31 + src/backends/meta-renderer.c | 293 + src/backends/meta-renderer.h | 65 + .../meta-screen-cast-monitor-stream-src.c | 609 + .../meta-screen-cast-monitor-stream-src.h | 40 + .../meta-screen-cast-monitor-stream.c | 286 + .../meta-screen-cast-monitor-stream.h | 49 + src/backends/meta-screen-cast-session.c | 599 + src/backends/meta-screen-cast-session.h | 70 + src/backends/meta-screen-cast-stream-src.c | 1170 ++ src/backends/meta-screen-cast-stream-src.h | 109 + src/backends/meta-screen-cast-stream.c | 346 + src/backends/meta-screen-cast-stream.h | 70 + .../meta-screen-cast-window-stream-src.c | 587 + .../meta-screen-cast-window-stream-src.h | 37 + src/backends/meta-screen-cast-window-stream.c | 282 + src/backends/meta-screen-cast-window-stream.h | 45 + src/backends/meta-screen-cast-window.c | 99 + src/backends/meta-screen-cast-window.h | 93 + src/backends/meta-screen-cast.c | 299 + src/backends/meta-screen-cast.h | 52 + src/backends/meta-settings-private.h | 85 + src/backends/meta-settings.c | 671 + src/backends/meta-stage-private.h | 71 + src/backends/meta-stage.c | 473 + src/backends/native/dbus-utils.c | 107 + src/backends/native/dbus-utils.h | 32 + src/backends/native/gen-default-modes.py | 127 + .../native/meta-backend-native-private.h | 32 + .../native/meta-backend-native-types.h | 26 + src/backends/native/meta-backend-native.c | 831 + src/backends/native/meta-backend-native.h | 52 + src/backends/native/meta-barrier-native.c | 602 + src/backends/native/meta-barrier-native.h | 52 + .../native/meta-clutter-backend-native.c | 151 + .../native/meta-clutter-backend-native.h | 43 + src/backends/native/meta-crtc-kms.c | 302 + src/backends/native/meta-crtc-kms.h | 72 + .../native/meta-cursor-renderer-native.c | 1744 ++ .../native/meta-cursor-renderer-native.h | 38 + src/backends/native/meta-drm-buffer-dumb.c | 65 + src/backends/native/meta-drm-buffer-dumb.h | 35 + src/backends/native/meta-drm-buffer-gbm.c | 172 + src/backends/native/meta-drm-buffer-gbm.h | 43 + src/backends/native/meta-drm-buffer-import.c | 197 + src/backends/native/meta-drm-buffer-import.h | 54 + src/backends/native/meta-drm-buffer.c | 45 + src/backends/native/meta-drm-buffer.h | 46 + src/backends/native/meta-event-native.c | 208 + src/backends/native/meta-event-native.h | 50 + src/backends/native/meta-gpu-kms.c | 643 + src/backends/native/meta-gpu-kms.h | 97 + .../native/meta-input-device-native.c | 689 +- .../native/meta-input-device-native.h | 144 + .../native/meta-input-device-tool-native.c | 95 +- .../native/meta-input-device-tool-native.h | 86 + .../native/meta-input-settings-native.c | 666 + .../native/meta-input-settings-native.h | 49 + src/backends/native/meta-keymap-native.c | 133 + src/backends/native/meta-keymap-native.h | 36 + .../native/meta-kms-connector-private.h | 38 + src/backends/native/meta-kms-connector.c | 655 + src/backends/native/meta-kms-connector.h | 89 + src/backends/native/meta-kms-crtc-private.h | 36 + src/backends/native/meta-kms-crtc.c | 252 + src/backends/native/meta-kms-crtc.h | 65 + src/backends/native/meta-kms-device-private.h | 36 + src/backends/native/meta-kms-device.c | 386 + src/backends/native/meta-kms-device.h | 60 + src/backends/native/meta-kms-impl-device.c | 503 + src/backends/native/meta-kms-impl-device.h | 81 + src/backends/native/meta-kms-impl-simple.c | 1104 ++ src/backends/native/meta-kms-impl-simple.h | 32 + src/backends/native/meta-kms-impl.c | 145 + src/backends/native/meta-kms-impl.h | 61 + .../native/meta-kms-page-flip-private.h | 57 + src/backends/native/meta-kms-page-flip.c | 196 + src/backends/native/meta-kms-plane-private.h | 37 + src/backends/native/meta-kms-plane.c | 442 + src/backends/native/meta-kms-plane.h | 65 + src/backends/native/meta-kms-private.h | 67 + src/backends/native/meta-kms-types.h | 63 + src/backends/native/meta-kms-update-private.h | 142 + src/backends/native/meta-kms-update.c | 430 + src/backends/native/meta-kms-update.h | 141 + src/backends/native/meta-kms-utils.c | 83 + src/backends/native/meta-kms-utils.h | 37 + src/backends/native/meta-kms.c | 634 + src/backends/native/meta-kms.h | 49 + src/backends/native/meta-launcher.c | 572 + src/backends/native/meta-launcher.h | 47 + .../native/meta-monitor-manager-kms.c | 668 + .../native/meta-monitor-manager-kms.h | 42 + src/backends/native/meta-output-kms.c | 412 + src/backends/native/meta-output-kms.h | 51 + .../native/meta-renderer-native-gles3.c | 160 + .../native/meta-renderer-native-gles3.h | 40 + src/backends/native/meta-renderer-native.c | 4001 ++++ src/backends/native/meta-renderer-native.h | 60 + src/backends/native/meta-seat-native.c | 3316 ++++ src/backends/native/meta-seat-native.h | 325 + src/backends/native/meta-stage-native.c | 230 + src/backends/native/meta-stage-native.h | 36 + src/backends/native/meta-udev.c | 234 + src/backends/native/meta-udev.h | 43 + .../native/meta-virtual-input-device-native.c | 761 + .../native/meta-virtual-input-device-native.h | 20 +- .../backends/native/meta-xkb-utils.c | 48 +- src/backends/native/meta-xkb-utils.h | 40 + src/backends/x11/cm/meta-backend-x11-cm.c | 447 + src/backends/x11/cm/meta-backend-x11-cm.h | 31 + .../x11/cm/meta-cursor-sprite-xfixes.c | 231 + .../x11/cm/meta-cursor-sprite-xfixes.h | 36 + src/backends/x11/cm/meta-renderer-x11-cm.c | 107 + src/backends/x11/cm/meta-renderer-x11-cm.h | 44 + src/backends/x11/meta-backend-x11.c | 891 + src/backends/x11/meta-backend-x11.h | 61 + src/backends/x11/meta-barrier-x11.c | 212 + src/backends/x11/meta-barrier-x11.h | 42 + src/backends/x11/meta-clutter-backend-x11.c | 156 + src/backends/x11/meta-clutter-backend-x11.h | 38 + src/backends/x11/meta-crtc-xrandr.c | 392 + src/backends/x11/meta-crtc-xrandr.h | 58 + src/backends/x11/meta-cursor-renderer-x11.c | 114 + src/backends/x11/meta-cursor-renderer-x11.h | 52 + src/backends/x11/meta-event-x11.c | 173 + src/backends/x11/meta-event-x11.h | 55 + src/backends/x11/meta-gpu-xrandr.c | 366 + src/backends/x11/meta-gpu-xrandr.h | 46 + .../backends/x11/meta-input-device-tool-x11.c | 22 +- src/backends/x11/meta-input-device-tool-x11.h | 51 + src/backends/x11/meta-input-device-x11.c | 500 + src/backends/x11/meta-input-device-x11.h | 75 + src/backends/x11/meta-input-settings-x11.c | 1056 ++ src/backends/x11/meta-input-settings-x11.h | 49 + src/backends/x11/meta-keymap-x11.c | 954 + src/backends/x11/meta-keymap-x11.h | 61 + .../x11/meta-monitor-manager-xrandr.c | 1446 ++ .../x11/meta-monitor-manager-xrandr.h | 41 + src/backends/x11/meta-output-xrandr.c | 839 + src/backends/x11/meta-output-xrandr.h | 43 + src/backends/x11/meta-renderer-x11.c | 102 + src/backends/x11/meta-renderer-x11.h | 42 + .../backends/x11/meta-seat-x11.c | 2133 ++- src/backends/x11/meta-seat-x11.h | 44 + src/backends/x11/meta-stage-x11.c | 910 + src/backends/x11/meta-stage-x11.h | 98 + .../x11/meta-virtual-input-device-x11.c | 215 + .../x11/meta-virtual-input-device-x11.h | 20 +- .../backends/x11/meta-xkb-a11y-x11.c | 89 +- .../backends/x11/meta-xkb-a11y-x11.h | 17 +- .../x11/nested/meta-backend-x11-nested.c | 288 + .../x11/nested/meta-backend-x11-nested.h | 40 + .../nested/meta-cursor-renderer-x11-nested.c | 91 + .../nested/meta-cursor-renderer-x11-nested.h | 38 + .../x11/nested/meta-renderer-x11-nested.c | 237 + .../x11/nested/meta-renderer-x11-nested.h | 37 + .../x11/nested/meta-stage-x11-nested.c | 229 + .../x11/nested/meta-stage-x11-nested.h | 35 + src/compositor/README | 70 + src/compositor/clutter-utils.c | 60 +- src/compositor/clutter-utils.h | 27 +- src/compositor/cogl-utils.c | 245 +- src/compositor/cogl-utils.h | 37 +- src/compositor/compositor-private.h | 134 +- src/compositor/compositor.c | 1866 +- .../meta-background-actor-private.h | 11 +- src/compositor/meta-background-actor.c | 1215 +- src/compositor/meta-background-group.c | 66 + src/compositor/meta-background-image.c | 370 + src/compositor/meta-background-private.h | 14 + src/compositor/meta-background.c | 1077 +- src/compositor/meta-background.h | 44 - src/compositor/meta-compositor-server.c | 71 + src/compositor/meta-compositor-server.h | 32 + src/compositor/meta-compositor-x11.c | 527 + src/compositor/meta-compositor-x11.h | 38 + src/compositor/meta-cullable.c | 245 + src/compositor/meta-cullable.h | 61 + src/compositor/meta-dnd-actor-private.h | 48 + src/compositor/meta-dnd-actor.c | 242 + src/compositor/meta-dnd.c | 336 + src/compositor/meta-feedback-actor-private.h | 70 + src/compositor/meta-feedback-actor.c | 283 + src/compositor/meta-module.c | 34 +- src/compositor/meta-module.h | 4 +- src/compositor/meta-plugin-manager.c | 466 +- src/compositor/meta-plugin-manager.h | 92 +- src/compositor/meta-plugin.c | 247 +- src/compositor/meta-shadow-factory-private.h | 69 - src/compositor/meta-shadow-factory.c | 274 +- src/compositor/meta-shaped-texture-private.h | 40 +- src/compositor/meta-shaped-texture.c | 1651 +- src/compositor/meta-surface-actor-wayland.c | 130 + src/compositor/meta-surface-actor-wayland.h | 57 + src/compositor/meta-surface-actor-x11.c | 443 + src/compositor/meta-surface-actor-x11.h | 60 + src/compositor/meta-surface-actor.c | 638 + src/compositor/meta-surface-actor.h | 70 + src/compositor/meta-sync-ring.c | 78 +- src/compositor/meta-sync-ring.h | 1 - src/compositor/meta-texture-rectangle.c | 63 - src/compositor/meta-texture-tower.c | 75 +- src/compositor/meta-texture-tower.h | 11 +- src/compositor/meta-window-actor-private.h | 106 +- src/compositor/meta-window-actor-wayland.c | 165 + src/compositor/meta-window-actor-wayland.h | 37 + src/compositor/meta-window-actor-x11.c | 1645 ++ src/compositor/meta-window-actor-x11.h | 47 + src/compositor/meta-window-actor.c | 3230 +--- src/compositor/meta-window-group-private.h | 23 + src/compositor/meta-window-group.c | 365 +- src/compositor/meta-window-group.h | 52 - src/compositor/meta-window-shape.c | 33 +- src/compositor/plugins/Makefile.am | 48 - src/compositor/plugins/default.c | 713 +- src/compositor/plugins/meson.build | 20 + src/compositor/region-utils.c | 194 +- src/compositor/region-utils.h | 61 +- src/core/above-tab-keycode.c | 243 - src/core/async-getprop.c | 683 - src/core/async-getprop.h | 67 - src/core/bell.c | 209 +- src/core/bell.h | 88 +- src/core/boxes-private.h | 108 +- src/core/boxes.c | 516 +- src/core/constraints.c | 1116 +- src/core/constraints.h | 35 +- src/core/core.c | 813 - src/core/core.h | 221 - src/core/delete.c | 267 +- src/core/display-private.h | 468 +- src/core/display.c | 6973 +++---- src/core/edge-resistance.c | 192 +- src/core/edge-resistance.h | 18 +- src/core/eventqueue.c | 188 - src/core/events.c | 499 + src/core/events.h | 31 + src/core/frame.c | 326 +- src/core/frame.h | 38 +- src/core/iconcache.c | 773 - src/core/keybindings-private.h | 139 +- src/core/keybindings.c | 5065 ++--- src/core/main-private.h | 54 + src/core/main.c | 782 +- src/core/meta-accel-parse.c | 358 + src/core/meta-accel-parse.h | 44 + src/core/meta-border.c | 154 + src/core/meta-border.h | 84 + src/core/meta-clipboard-manager.c | 179 + src/core/meta-clipboard-manager.h | 30 + src/core/meta-close-dialog-default-private.h | 37 + src/core/meta-close-dialog-default.c | 281 + src/core/meta-close-dialog.c | 144 + src/core/meta-fraction.c | 134 + src/core/meta-fraction.h | 31 + src/core/meta-gesture-tracker-private.h | 70 + src/core/meta-gesture-tracker.c | 581 + ...inhibit-shortcuts-dialog-default-private.h | 34 + .../meta-inhibit-shortcuts-dialog-default.c | 132 + src/core/meta-inhibit-shortcuts-dialog.c | 103 + src/core/meta-launch-context.c | 269 + src/core/meta-selection-private.h | 32 + src/core/meta-selection-source-memory.c | 128 + src/core/meta-selection-source.c | 166 + src/core/meta-selection.c | 415 + src/core/meta-sound-player.c | 291 + src/core/meta-workspace-manager-private.h | 96 + src/core/meta-workspace-manager.c | 1061 ++ src/core/{muffin.c => mutter.c} | 39 +- src/core/place.c | 831 +- src/core/place.h | 22 +- src/core/prefs.c | 1739 +- src/core/restart-helper.c | 12 +- src/core/restart.c | 83 +- src/core/screen-private.h | 250 - src/core/screen.c | 3910 ---- src/core/stack-tracker.c | 951 +- src/core/stack-tracker.h | 48 +- src/core/stack.c | 1184 +- src/core/stack.h | 382 +- src/core/startup-notification-private.h | 52 + src/core/startup-notification.c | 684 + src/core/testasyncgetprop.c | 496 - src/core/util-private.h | 18 +- src/core/util.c | 457 +- src/core/window-private.h | 850 +- src/core/window-props.h | 138 - src/core/window.c | 10910 ++++------- src/core/workspace-private.h | 44 +- src/core/workspace.c | 1107 +- src/core/xprops.h | 233 - src/libmuffin.pc.in | 19 - src/libmutter.pc.in | 14 + src/meson.build | 1015 + src/meta-marshal.list | 1 + src/meta/barrier.h | 124 + src/meta/boxes.h | 67 +- src/meta/common.h | 491 +- src/meta/compositor-muffin.h | 53 - src/meta/compositor-mutter.h | 60 + src/meta/compositor.h | 175 +- src/meta/display.h | 282 +- src/meta/gradient.h | 65 - src/meta/group.h | 34 +- src/meta/keybindings.h | 20 +- src/meta/main.h | 44 +- src/meta/meson.build | 88 + src/meta/meta-backend.h | 73 + src/meta/meta-background-actor.h | 55 +- src/meta/meta-background-group.h | 26 + src/meta/meta-background-image.h | 69 + src/meta/meta-background.h | 74 + src/meta/meta-close-dialog.h | 65 + src/meta/meta-cursor-tracker.h | 65 + src/meta/meta-dnd.h | 34 + .../meta-enum-types.c.in} | 2 +- .../meta-enum-types.h.in} | 11 +- src/meta/meta-idle-monitor.h | 66 + src/meta/meta-inhibit-shortcuts-dialog.h | 55 + src/meta/meta-launch-context.h | 39 + src/meta/meta-monitor-manager.h | 65 + src/meta/meta-plugin.h | 389 +- src/meta/meta-remote-access-controller.h | 57 + src/meta/meta-selection-source-memory.h | 39 + src/meta/meta-selection-source.h | 85 + src/meta/meta-selection.h | 70 + src/meta/meta-settings.h | 34 + src/meta/meta-shadow-factory.h | 85 +- src/meta/meta-shaped-texture.h | 64 +- src/meta/meta-sound-player.h | 46 + .../meta-stage.h} | 26 +- src/meta/meta-startup-notification.h | 76 + src/meta/meta-version.h.in | 28 + src/meta/meta-window-actor.h | 62 +- src/meta/meta-window-group.h | 16 + src/{compositor => meta}/meta-window-shape.h | 24 +- src/meta/meta-workspace-manager.h | 78 + src/meta/meta-x11-display.h | 73 + src/meta/{errors.h => meta-x11-errors.h} | 25 +- src/meta/prefs.h | 419 +- src/meta/preview-widget.h | 85 - src/meta/screen.h | 110 - src/meta/theme.h | 24 +- src/meta/types.h | 14 +- src/meta/util.h | 117 +- src/meta/window.h | 330 +- src/meta/workspace.h | 44 +- src/muffin-plugins.pc.in | 17 - src/muffin.desktop.desktop | 19 - src/org.cinnamon.muffin.gschema.xml.in | 584 - src/org.freedesktop.login1.xml | 46 + src/org.gnome.Mutter.DisplayConfig.xml | 458 + src/org.gnome.Mutter.IdleMonitor.xml | 37 + src/org.gnome.Mutter.RemoteDesktop.xml | 191 + src/org.gnome.Mutter.ScreenCast.xml | 149 + src/stock_delete.png | Bin 220 -> 0 bytes src/stock_maximize.png | Bin 166 -> 0 bytes src/stock_minimize.png | Bin 145 -> 0 bytes src/tests/README | 93 + src/{core/testboxes.c => tests/boxes-tests.c} | 177 +- src/tests/boxes-tests.h | 23 + .../tests}/clutter-test-utils.c | 69 +- .../tests}/clutter-test-utils.h | 65 +- src/tests/clutter/README | 38 + .../cally-atkcomponent-example.c | 0 .../cally-atkeditabletext-example.c | 0 .../accessibility/cally-atkevents-example.c | 0 .../accessibility/cally-atktext-example.c | 49 +- .../accessibility/cally-clone-example.c | 0 .../accessibility/cally-examples-util.c | 4 +- .../accessibility/cally-examples-util.h | 0 src/tests/clutter/accessibility/meson.build | 38 + .../tests/clutter}/clutter-1.0.suppressions | 8 - .../tests/clutter}/conform/actor-anchors.c | 13 +- src/tests/clutter/conform/actor-clone.c | 68 + .../tests/clutter}/conform/actor-destroy.c | 75 +- .../tests/clutter}/conform/actor-graph.c | 2 + .../tests/clutter}/conform/actor-invariants.c | 2 + .../tests/clutter}/conform/actor-iter.c | 8 +- .../tests/clutter}/conform/actor-layout.c | 18 +- .../tests/clutter}/conform/actor-meta.c | 2 + .../conform/actor-offscreen-redirect.c | 137 +- .../clutter}/conform/actor-paint-opacity.c | 2 + .../tests/clutter}/conform/actor-pick.c | 121 +- .../clutter}/conform/actor-shader-effect.c | 45 +- .../tests/clutter}/conform/actor-size.c | 2 + .../tests/clutter}/conform/binding-pool.c | 22 +- .../tests/clutter}/conform/cally-text.c | 4 +- .../tests/clutter}/conform/color.c | 4 +- .../tests/clutter}/conform/group.c | 2 + .../tests/clutter}/conform/interval.c | 4 +- src/tests/clutter/conform/meson.build | 79 + .../tests/clutter}/conform/path.c | 4 +- .../tests/clutter}/conform/rectangle.c | 2 + .../tests/clutter}/conform/script-parser.c | 53 +- .../conform/scripts/test-animator-1.json | 0 .../conform/scripts/test-animator-2.json | 0 .../conform/scripts/test-animator-3.json | 0 .../scripts/test-script-animation.json | 0 .../conform/scripts/test-script-child.json | 0 .../conform/scripts/test-script-interval.json | 0 .../scripts/test-script-layout-property.json | 0 .../conform/scripts/test-script-margin.json | 0 .../conform/scripts/test-script-model.json | 0 .../scripts/test-script-named-object.json | 0 .../scripts/test-script-object-property.json | 0 .../conform/scripts/test-script-single.json | 0 .../scripts/test-script-timeline-markers.json | 0 .../conform/scripts/test-state-1.json | 0 .../tests/clutter}/conform/state.c | 6 +- .../tests/clutter}/conform/text-cache.c | 4 +- .../tests/clutter}/conform/text.c | 23 +- .../tests/clutter}/conform/texture-fbo.c | 10 +- .../clutter}/conform/timeline-interpolate.c | 11 +- .../clutter}/conform/timeline-progress.c | 0 .../tests/clutter}/conform/timeline-rewind.c | 0 .../tests/clutter}/conform/timeline.c | 9 +- .../tests/clutter}/conform/units.c | 6 +- src/tests/clutter/interactive/meson.build | 84 + .../interactive/meson/gen-test-unit-names.sh | 14 + .../tests/clutter/interactive}/redhand.png | Bin .../tests/clutter}/interactive/test-actors.c | 40 +- .../clutter}/interactive/test-animation.c | 8 +- .../interactive/test-bind-constraint.c | 7 +- .../clutter}/interactive/test-binding-pool.c | 25 +- .../clutter}/interactive/test-cairo-clock.c | 7 +- .../clutter}/interactive/test-cairo-flowers.c | 6 + .../interactive/test-cogl-multitexture.c | 61 +- .../interactive/test-cogl-offscreen.c | 134 +- .../interactive/test-cogl-point-sprites.c | 47 +- .../interactive/test-cogl-shader-glsl.c | 52 +- .../interactive/test-cogl-tex-convert.c | 135 +- .../interactive/test-cogl-tex-polygon.c | 173 +- .../clutter}/interactive/test-cogl-tex-tile.c | 55 +- .../tests/clutter}/interactive/test-content.c | 24 +- .../tests/clutter}/interactive/test-devices.c | 51 +- .../tests/clutter}/interactive/test-easing.c | 36 +- .../tests/clutter}/interactive/test-events.c | 104 +- .../tests/clutter}/interactive/test-grab.c | 91 +- .../tests/clutter}/interactive/test-image.c | 24 +- .../interactive/test-keyframe-transition.c | 8 +- .../tests/clutter}/interactive/test-layout.c | 33 +- .../tests/clutter}/interactive/test-main.c | 23 +- .../clutter}/interactive/test-paint-wrapper.c | 86 +- .../interactive/test-path-constraint.c | 6 +- .../clutter}/interactive/test-rotate-zoom.c | 7 +- .../interactive/test-script-signals.json | 0 .../tests/clutter}/interactive/test-script.c | 58 +- .../clutter}/interactive/test-script.json | 22 +- .../clutter}/interactive/test-scrolling.c | 3 + .../interactive/test-shader-effects.c | 10 +- .../clutter}/interactive/test-stage-sizing.c | 61 +- .../clutter}/interactive/test-state-script.c | 12 +- .../tests/clutter}/interactive/test-state.c | 13 +- .../clutter}/interactive/test-swipe-action.c | 19 +- .../clutter}/interactive/test-text-field.c | 25 +- .../tests/clutter}/interactive/test-text.c | 7 + .../clutter}/interactive/test-touch-events.c | 53 +- .../tests/clutter}/interactive/wrapper.sh.in | 0 src/tests/clutter/meson.build | 7 + src/tests/clutter/micro-bench/meson.build | 28 + .../clutter}/micro-bench/test-cogl-perf.c | 58 +- .../tests/clutter}/micro-bench/test-picking.c | 4 +- .../clutter}/micro-bench/test-random-text.c | 0 .../clutter}/micro-bench/test-text-perf.c | 6 +- .../tests/clutter}/micro-bench/test-text.c | 4 +- .../clutter}/performance/create-report.rb | 0 .../tests/clutter}/performance/joblist | 0 .../tests/clutter}/performance/makejobs.rb | 0 src/tests/clutter/performance/meson.build | 38 + .../tests/clutter}/performance/test-common.h | 30 +- .../tests/clutter}/performance/test-picking.c | 0 .../clutter}/performance/test-state-hidden.c | 4 +- .../performance/test-state-interactive.c | 7 +- .../clutter}/performance/test-state-mini.c | 7 +- .../clutter}/performance/test-state-pick.c | 7 +- .../tests/clutter}/performance/test-state.c | 7 +- .../clutter}/performance/test-text-perf.c | 2 +- src/tests/clutter/test-utils.h | 30 + src/tests/headless-start-test.c | 218 + src/tests/meson.build | 174 + src/tests/meta-backend-test.c | 95 + src/tests/meta-backend-test.h | 34 + src/tests/meta-gpu-test.c | 55 + src/tests/meta-gpu-test.h | 26 + src/tests/meta-monitor-manager-test.c | 445 + src/tests/meta-monitor-manager-test.h | 53 + src/tests/migration/basic-new.xml | 78 + src/tests/migration/basic-old.xml | 72 + src/tests/migration/first-rotated-new.xml | 44 + src/tests/migration/first-rotated-old.xml | 37 + src/tests/migration/oneoff-new-finished.xml | 31 + src/tests/migration/oneoff-new.xml | 31 + src/tests/migration/oneoff-old.xml | 26 + src/tests/migration/rotated-new-finished.xml | 27 + src/tests/migration/rotated-new.xml | 27 + src/tests/migration/rotated-old.xml | 21 + src/tests/migration/tiled-new.xml | 23 + src/tests/migration/tiled-old.xml | 37 + src/tests/migration/wiggle-new-discarded.xml | 2 + src/tests/migration/wiggle-new-finished.xml | 27 + src/tests/migration/wiggle-new.xml | 27 + src/tests/migration/wiggle-old.xml | 21 + .../monitor-config-migration-unit-tests.c | 136 + .../monitor-config-migration-unit-tests.h | 25 + src/tests/monitor-configs/first-rotated.xml | 47 + .../monitor-configs/fractional-scale.xml | 23 + .../high-precision-fractional-scale.xml | 23 + src/tests/monitor-configs/interlaced.xml | 23 + src/tests/monitor-configs/lid-scale.xml | 23 + src/tests/monitor-configs/lid-switch.xml | 91 + src/tests/monitor-configs/mirrored.xml | 35 + .../non-preferred-tiled-custom-resolution.xml | 22 + src/tests/monitor-configs/oneoff.xml | 31 + src/tests/monitor-configs/primary.xml | 40 + src/tests/monitor-configs/scale.xml | 23 + .../monitor-configs/second-rotated-tiled.xml | 43 + src/tests/monitor-configs/second-rotated.xml | 43 + src/tests/monitor-configs/single.xml | 22 + .../tiled-custom-resolution.xml | 23 + src/tests/monitor-configs/tiled.xml | 23 + src/tests/monitor-configs/underscanning.xml | 23 + src/tests/monitor-configs/vertical.xml | 39 + src/tests/monitor-store-unit-tests.c | 864 + src/tests/monitor-store-unit-tests.h | 25 + src/tests/monitor-test-utils.c | 81 + src/tests/monitor-test-utils.h | 31 + src/tests/monitor-transform-tests.c | 100 + src/tests/monitor-transform-tests.h | 23 + src/tests/monitor-unit-tests.c | 6433 +++++++ src/tests/monitor-unit-tests.h | 29 + src/tests/mutter-all.test.in | 5 + src/tests/stacking/basic-wayland.metatest | 22 + src/tests/stacking/basic-x11.metatest | 19 + .../stacking/client-side-decorated.metatest | 22 + ...ent-no-input-no-take-focus-parent.metatest | 23 + ...nt-no-input-no-take-focus-parents.metatest | 30 + ...t-delayed-focus-default-cancelled.metatest | 36 + .../closed-transient-no-input-parent.metatest | 30 + ...ts-queued-default-focus-destroyed.metatest | 43 + ...closed-transient-no-input-parents.metatest | 46 + ...transient-only-take-focus-parents.metatest | 34 + src/tests/stacking/closed-transient.metatest | 19 + src/tests/stacking/minimized.metatest | 18 + src/tests/stacking/mixed-windows.metatest | 26 + src/tests/stacking/override-redirect.metatest | 19 + .../set-override-redirect-parent.metatest | 37 + .../stacking/set-parent-exported.metatest | 15 + src/tests/stacking/set-parent.metatest | 14 + src/tests/test-client.c | 787 + src/tests/test-runner.c | 908 + src/tests/test-utils.c | 550 + src/tests/test-utils.h | 89 + src/tests/unit-tests.c | 278 + src/tests/wayland-test-clients/meson.build | 61 + .../subsurface-remap-toplevel.c | 397 + .../wayland-test-clients/test-driver.xml | 9 + .../wayland-test-client-utils.c | 88 + .../wayland-test-client-utils.h | 8 + src/tests/wayland-unit-tests.c | 203 + src/tests/wayland-unit-tests.h | 25 + src/tools/Makefile.am | 34 - src/tools/muffin-grayscale.c | 107 - src/tools/muffin-mag.c | 301 - src/tools/muffin-message.c | 158 - src/tools/muffin-window-demo.c | 1049 -- src/tools/muffin-window-demo.png | Bin 3453 -> 0 bytes src/ui/draw-workspace.c | 184 - src/ui/draw-workspace.h | 59 - src/ui/frames.c | 2417 +-- src/ui/frames.h | 134 +- src/ui/gradient.c | 871 - src/ui/menu.c | 551 - src/ui/menu.h | 62 - src/ui/metaaccellabel.c | 453 - src/ui/metaaccellabel.h | 106 - src/ui/preview-widget.c | 515 - src/ui/resizepopup.c | 217 - src/ui/resizepopup.h | 47 - src/ui/testgradient.c | 317 - src/ui/theme-parser.c | 4419 ----- src/ui/theme-private.h | 1089 +- src/ui/theme-viewer.c | 1360 -- src/ui/theme.c | 7302 +------- src/ui/ui.c | 833 +- src/ui/ui.h | 134 +- src/wayland/meta-cursor-sprite-wayland.c | 75 + src/wayland/meta-cursor-sprite-wayland.h | 35 + .../meta-pointer-confinement-wayland.c | 738 + .../meta-pointer-confinement-wayland.h | 45 + src/wayland/meta-pointer-lock-wayland.c | 81 + src/wayland/meta-pointer-lock-wayland.h | 42 + .../meta-selection-source-wayland-private.h | 39 + src/wayland/meta-selection-source-wayland.c | 170 + src/wayland/meta-wayland-actor-surface.c | 455 + src/wayland/meta-wayland-actor-surface.h | 54 + src/wayland/meta-wayland-buffer.c | 619 + src/wayland/meta-wayland-buffer.h | 92 + src/wayland/meta-wayland-cursor-surface.c | 387 + src/wayland/meta-wayland-cursor-surface.h | 52 + .../meta-wayland-data-device-primary-legacy.c | 354 + .../meta-wayland-data-device-primary-legacy.h | 55 + .../meta-wayland-data-device-primary.c | 353 + .../meta-wayland-data-device-primary.h | 55 + src/wayland/meta-wayland-data-device.c | 1129 ++ src/wayland/meta-wayland-data-device.h | 91 + .../meta-wayland-data-offer-primary-legacy.c | 139 + .../meta-wayland-data-offer-primary-legacy.h | 31 + src/wayland/meta-wayland-data-offer-primary.c | 139 + src/wayland/meta-wayland-data-offer-primary.h | 31 + src/wayland/meta-wayland-data-offer.c | 327 + src/wayland/meta-wayland-data-offer.h | 51 + .../meta-wayland-data-source-primary-legacy.c | 117 + .../meta-wayland-data-source-primary-legacy.h | 37 + .../meta-wayland-data-source-primary.c | 117 + .../meta-wayland-data-source-primary.h | 37 + src/wayland/meta-wayland-data-source.c | 523 + src/wayland/meta-wayland-data-source.h | 112 + src/wayland/meta-wayland-dma-buf.c | 602 + src/wayland/meta-wayland-dma-buf.h | 52 + src/wayland/meta-wayland-dnd-surface.c | 153 + src/wayland/meta-wayland-dnd-surface.h | 31 + src/wayland/meta-wayland-egl-stream.c | 367 + src/wayland/meta-wayland-egl-stream.h | 54 + src/wayland/meta-wayland-gtk-shell.c | 544 + src/wayland/meta-wayland-gtk-shell.h | 31 + .../meta-wayland-inhibit-shortcuts-dialog.c | 187 + .../meta-wayland-inhibit-shortcuts-dialog.h | 31 + src/wayland/meta-wayland-inhibit-shortcuts.c | 188 + src/wayland/meta-wayland-inhibit-shortcuts.h | 39 + src/wayland/meta-wayland-input-device.c | 129 + src/wayland/meta-wayland-input-device.h | 48 + src/wayland/meta-wayland-keyboard.c | 933 + src/wayland/meta-wayland-keyboard.h | 140 + src/wayland/meta-wayland-legacy-xdg-shell.c | 2102 +++ src/wayland/meta-wayland-legacy-xdg-shell.h | 53 + src/wayland/meta-wayland-outputs.c | 748 + src/wayland/meta-wayland-outputs.h | 55 + .../meta-wayland-pointer-constraints.c | 1202 ++ .../meta-wayland-pointer-constraints.h | 47 + .../meta-wayland-pointer-gesture-pinch.c | 166 + .../meta-wayland-pointer-gesture-pinch.h | 39 + .../meta-wayland-pointer-gesture-swipe.c | 161 + .../meta-wayland-pointer-gesture-swipe.h | 39 + src/wayland/meta-wayland-pointer-gestures.c | 83 + src/wayland/meta-wayland-pointer-gestures.h | 32 + src/wayland/meta-wayland-pointer.c | 1387 ++ src/wayland/meta-wayland-pointer.h | 160 + src/wayland/meta-wayland-popup.c | 307 + src/wayland/meta-wayland-popup.h | 62 + src/wayland/meta-wayland-private.h | 96 + src/wayland/meta-wayland-region.c | 105 + src/wayland/meta-wayland-region.h | 41 + src/wayland/meta-wayland-seat.c | 561 + src/wayland/meta-wayland-seat.h | 89 + src/wayland/meta-wayland-shell-surface.c | 411 + src/wayland/meta-wayland-shell-surface.h | 68 + src/wayland/meta-wayland-subsurface.c | 600 + src/wayland/meta-wayland-subsurface.h | 58 + src/wayland/meta-wayland-surface.c | 1982 ++ src/wayland/meta-wayland-surface.h | 375 + .../meta-wayland-tablet-cursor-surface.c | 43 + .../meta-wayland-tablet-cursor-surface.h | 33 + src/wayland/meta-wayland-tablet-manager.c | 271 + src/wayland/meta-wayland-tablet-manager.h | 56 + src/wayland/meta-wayland-tablet-pad-group.c | 403 + src/wayland/meta-wayland-tablet-pad-group.h | 73 + src/wayland/meta-wayland-tablet-pad-ring.c | 206 + src/wayland/meta-wayland-tablet-pad-ring.h | 59 + src/wayland/meta-wayland-tablet-pad-strip.c | 205 + src/wayland/meta-wayland-tablet-pad-strip.h | 59 + src/wayland/meta-wayland-tablet-pad.c | 612 + src/wayland/meta-wayland-tablet-pad.h | 81 + src/wayland/meta-wayland-tablet-seat.c | 575 + src/wayland/meta-wayland-tablet-seat.h | 81 + src/wayland/meta-wayland-tablet-tool.c | 1020 + src/wayland/meta-wayland-tablet-tool.h | 91 + src/wayland/meta-wayland-tablet.c | 129 + src/wayland/meta-wayland-tablet.h | 58 + src/wayland/meta-wayland-text-input-legacy.c | 633 + src/wayland/meta-wayland-text-input-legacy.h | 43 + src/wayland/meta-wayland-text-input.c | 766 + src/wayland/meta-wayland-text-input.h | 47 + src/wayland/meta-wayland-touch.c | 697 + src/wayland/meta-wayland-touch.h | 79 + src/wayland/meta-wayland-types.h | 64 + src/wayland/meta-wayland-versions.h | 59 + src/wayland/meta-wayland-viewporter.c | 237 + src/wayland/meta-wayland-viewporter.h | 30 + .../meta-wayland-window-configuration.c | 103 + .../meta-wayland-window-configuration.h | 69 + src/wayland/meta-wayland-wl-shell.c | 780 + src/wayland/meta-wayland-wl-shell.h | 33 + src/wayland/meta-wayland-xdg-foreign.c | 462 + .../meta-wayland-xdg-foreign.h} | 34 +- src/wayland/meta-wayland-xdg-shell.c | 2422 +++ src/wayland/meta-wayland-xdg-shell.h | 53 + src/wayland/meta-wayland.c | 607 + src/wayland/meta-wayland.h | 94 + src/wayland/meta-window-wayland.c | 1217 ++ src/wayland/meta-window-wayland.h | 80 + src/wayland/meta-window-xwayland.c | 301 + src/wayland/meta-window-xwayland.h | 34 + src/wayland/meta-xwayland-dnd-private.h | 34 + src/wayland/meta-xwayland-dnd.c | 990 + src/wayland/meta-xwayland-grab-keyboard.c | 334 + src/wayland/meta-xwayland-grab-keyboard.h | 41 + src/wayland/meta-xwayland-private.h | 53 + src/wayland/meta-xwayland-surface.c | 291 + src/wayland/meta-xwayland-surface.h | 38 + src/wayland/meta-xwayland.c | 854 + src/wayland/meta-xwayland.h | 53 + .../protocol/gtk-primary-selection.xml | 225 + src/wayland/protocol/gtk-shell.xml | 87 + src/wayland/protocol/gtk-text-input.xml | 302 + src/wm-tester/Makefile.am | 29 - src/wm-tester/focus-window.c | 37 - src/wm-tester/main.c | 251 - src/wm-tester/test-attached.c | 100 - src/wm-tester/test-gravity.c | 308 - src/wm-tester/test-resizing.c | 257 - src/wm-tester/test-size-hints.c | 136 - src/{meta => x11}/atomnames.h | 35 +- src/x11/events.c | 1925 ++ src/x11/events.h | 31 + src/{core => x11}/group-private.h | 16 +- src/{core => x11}/group-props.c | 119 +- src/{core => x11}/group-props.h | 19 +- src/{core => x11}/group.c | 117 +- src/x11/iconcache.c | 575 + src/{core => x11}/iconcache.h | 45 +- src/x11/meta-selection-source-x11-private.h | 44 + src/x11/meta-selection-source-x11.c | 275 + src/x11/meta-startup-notification-x11.c | 376 + src/x11/meta-startup-notification-x11.h | 44 + src/x11/meta-x11-display-private.h | 261 + src/x11/meta-x11-display.c | 2341 +++ src/{core/errors.c => x11/meta-x11-errors.c} | 41 +- .../meta-x11-selection-input-stream-private.h | 54 + src/x11/meta-x11-selection-input-stream.c | 572 + ...meta-x11-selection-output-stream-private.h | 47 + src/x11/meta-x11-selection-output-stream.c | 686 + src/x11/meta-x11-selection-private.h | 34 + src/x11/meta-x11-selection.c | 551 + src/x11/meta-x11-stack-private.h | 33 + src/x11/meta-x11-stack.c | 353 + src/x11/meta-x11-window-control.c | 265 + src/x11/meta-x11-window-control.h | 81 + .../mutter-Xatomtype.h} | 18 +- src/{core => x11}/session.c | 287 +- src/{core => x11}/session.h | 20 +- src/{core => x11}/window-props.c | 1241 +- src/x11/window-props.h | 95 + src/x11/window-x11-private.h | 86 + src/x11/window-x11.c | 4121 +++++ src/x11/window-x11.h | 98 + src/{core => x11}/xprops.c | 722 +- src/x11/xprops.h | 196 + tools/announce-wrangler.py | 159 + tools/commit-wrangler.py | 111 + tools/patch-wrangler.py | 70 + tools/release-wrangler.py | 375 + 1863 files changed, 276005 insertions(+), 324915 deletions(-) delete mode 100644 .gitignore delete mode 100644 AUTHORS delete mode 100644 ChangeLog delete mode 100644 HACKING delete mode 100644 MAINTAINERS delete mode 100644 Makefile.am delete mode 100644 README delete mode 100644 README-Mutter create mode 100644 README.md delete mode 100755 autogen.sh delete mode 100644 clutter/Makefile.am delete mode 100644 clutter/build/Makefile.am delete mode 100644 clutter/build/autotools/.gitignore delete mode 100644 clutter/build/autotools/Makefile.am delete mode 100644 clutter/build/autotools/as-compiler-flag.m4 delete mode 100644 clutter/build/autotools/glib-tap.mk delete mode 100644 clutter/build/autotools/glibtests.m4 delete mode 100755 clutter/build/autotools/tap-driver.sh delete mode 100755 clutter/build/autotools/tap-test delete mode 100644 clutter/clutter/Makefile.am delete mode 100644 clutter/clutter/Makefile.am.enums delete mode 100644 clutter/clutter/Makefile.am.marshal delete mode 100644 clutter/clutter/cally/cally-texture.c delete mode 100644 clutter/clutter/cally/cally-texture.h create mode 100644 clutter/clutter/clutter-build-config.h.meson rename clutter/clutter/{deprecated/clutter-util.h => clutter-container-private.h} (61%) delete mode 100644 clutter/clutter/clutter-device-manager-private.h delete mode 100644 clutter/clutter/clutter-device-manager.c delete mode 100644 clutter/clutter/clutter-device-manager.h delete mode 100644 clutter/clutter/clutter-event-translator.c delete mode 100644 clutter/clutter/clutter-event-translator.h create mode 100644 clutter/clutter/clutter-graphene.c rename clutter/clutter/{x11/clutter-glx.h => clutter-graphene.h} (68%) create mode 100644 clutter/clutter/clutter-input-device-private.h create mode 100644 clutter/clutter/clutter-input-pointer-a11y-private.h create mode 100644 clutter/clutter/clutter-input-pointer-a11y.c create mode 100644 clutter/clutter/clutter-keymap.c create mode 100644 clutter/clutter/clutter-keymap.h delete mode 100644 clutter/clutter/clutter-muffin.h create mode 100644 clutter/clutter/clutter-mutter.h create mode 100644 clutter/clutter/clutter-paint-context-private.h create mode 100644 clutter/clutter/clutter-paint-context.c create mode 100644 clutter/clutter/clutter-paint-context.h create mode 100644 clutter/clutter/clutter-pick-context-private.h create mode 100644 clutter/clutter/clutter-pick-context.c rename clutter/clutter/{deprecated/clutter-stage-manager.h => clutter-pick-context.h} (51%) create mode 100644 clutter/clutter/clutter-seat.c create mode 100644 clutter/clutter/clutter-seat.h create mode 100644 clutter/clutter/clutter-stage-view-private.h delete mode 100644 clutter/clutter/clutter-texture.h delete mode 100644 clutter/clutter/clutter-version.h.in delete mode 100644 clutter/clutter/deprecated/clutter-actor-deprecated.c delete mode 100644 clutter/clutter/deprecated/clutter-animatable.h delete mode 100644 clutter/clutter/deprecated/clutter-animator.c delete mode 100644 clutter/clutter/deprecated/clutter-animator.h delete mode 100644 clutter/clutter/deprecated/clutter-backend.h delete mode 100644 clutter/clutter/deprecated/clutter-behaviour-depth.c delete mode 100644 clutter/clutter/deprecated/clutter-behaviour-depth.h delete mode 100644 clutter/clutter/deprecated/clutter-behaviour-ellipse.c delete mode 100644 clutter/clutter/deprecated/clutter-behaviour-ellipse.h delete mode 100644 clutter/clutter/deprecated/clutter-behaviour-opacity.c delete mode 100644 clutter/clutter/deprecated/clutter-behaviour-opacity.h delete mode 100644 clutter/clutter/deprecated/clutter-behaviour-path.c delete mode 100644 clutter/clutter/deprecated/clutter-behaviour-path.h delete mode 100644 clutter/clutter/deprecated/clutter-behaviour-rotate.c delete mode 100644 clutter/clutter/deprecated/clutter-behaviour-rotate.h delete mode 100644 clutter/clutter/deprecated/clutter-behaviour-scale.c delete mode 100644 clutter/clutter/deprecated/clutter-behaviour-scale.h delete mode 100644 clutter/clutter/deprecated/clutter-behaviour.c delete mode 100644 clutter/clutter/deprecated/clutter-behaviour.h delete mode 100644 clutter/clutter/deprecated/clutter-bin-layout.h delete mode 100644 clutter/clutter/deprecated/clutter-cairo-texture.c delete mode 100644 clutter/clutter/deprecated/clutter-cairo-texture.h delete mode 100644 clutter/clutter/deprecated/clutter-frame-source.c delete mode 100644 clutter/clutter/deprecated/clutter-frame-source.h delete mode 100644 clutter/clutter/deprecated/clutter-input-device-deprecated.c delete mode 100644 clutter/clutter/deprecated/clutter-input-device.h delete mode 100644 clutter/clutter/deprecated/clutter-keysyms.h delete mode 100644 clutter/clutter/deprecated/clutter-layout-manager-deprecated.c delete mode 100644 clutter/clutter/deprecated/clutter-list-model.c delete mode 100644 clutter/clutter/deprecated/clutter-list-model.h delete mode 100644 clutter/clutter/deprecated/clutter-main.h delete mode 100644 clutter/clutter/deprecated/clutter-media.c delete mode 100644 clutter/clutter/deprecated/clutter-media.h delete mode 100644 clutter/clutter/deprecated/clutter-model-private.h delete mode 100644 clutter/clutter/deprecated/clutter-model.c delete mode 100644 clutter/clutter/deprecated/clutter-model.h delete mode 100644 clutter/clutter/deprecated/clutter-score.c delete mode 100644 clutter/clutter/deprecated/clutter-score.h delete mode 100644 clutter/clutter/deprecated/clutter-shader.c delete mode 100644 clutter/clutter/deprecated/clutter-shader.h delete mode 100644 clutter/clutter/deprecated/clutter-table-layout.c delete mode 100644 clutter/clutter/deprecated/clutter-table-layout.h delete mode 100644 clutter/clutter/deprecated/clutter-texture.c delete mode 100644 clutter/clutter/deprecated/clutter-texture.h delete mode 100644 clutter/clutter/deprecated/clutter-timeout-interval.c delete mode 100644 clutter/clutter/deprecated/clutter-timeout-interval.h delete mode 100644 clutter/clutter/deprecated/clutter-timeout-pool.c delete mode 100644 clutter/clutter/deprecated/clutter-timeout-pool.h delete mode 100644 clutter/clutter/evdev/clutter-device-manager-evdev.c delete mode 100644 clutter/clutter/evdev/clutter-device-manager-evdev.h delete mode 100644 clutter/clutter/evdev/clutter-evdev.h delete mode 100644 clutter/clutter/evdev/clutter-event-evdev.c delete mode 100644 clutter/clutter/evdev/clutter-input-device-evdev.h delete mode 100644 clutter/clutter/evdev/clutter-input-device-tool-evdev.h delete mode 100644 clutter/clutter/evdev/clutter-seat-evdev.c delete mode 100644 clutter/clutter/evdev/clutter-seat-evdev.h delete mode 100644 clutter/clutter/evdev/clutter-virtual-input-device-evdev.c delete mode 100644 clutter/clutter/evdev/clutter-xkb-utils.h create mode 100644 clutter/clutter/meson.build delete mode 100644 clutter/clutter/muffin-clutter.pc.in create mode 100644 clutter/clutter/mutter-clutter.pc.in delete mode 100644 clutter/clutter/wayland/clutter-wayland-surface.c delete mode 100644 clutter/clutter/wayland/clutter-wayland-surface.h delete mode 100644 clutter/clutter/x11/clutter-device-manager-core-x11.c delete mode 100644 clutter/clutter/x11/clutter-device-manager-core-x11.h delete mode 100644 clutter/clutter/x11/clutter-device-manager-xi2.h delete mode 100644 clutter/clutter/x11/clutter-event-x11.c delete mode 100644 clutter/clutter/x11/clutter-glx-texture-pixmap.c delete mode 100644 clutter/clutter/x11/clutter-glx-texture-pixmap.h delete mode 100644 clutter/clutter/x11/clutter-input-device-core-x11.c delete mode 100644 clutter/clutter/x11/clutter-input-device-core-x11.h delete mode 100644 clutter/clutter/x11/clutter-input-device-tool-xi2.h delete mode 100644 clutter/clutter/x11/clutter-input-device-xi2.c delete mode 100644 clutter/clutter/x11/clutter-input-device-xi2.h delete mode 100644 clutter/clutter/x11/clutter-keymap-x11.c delete mode 100644 clutter/clutter/x11/clutter-keymap-x11.h delete mode 100644 clutter/clutter/x11/clutter-stage-x11.c delete mode 100644 clutter/clutter/x11/clutter-stage-x11.h delete mode 100644 clutter/clutter/x11/clutter-virtual-input-device-x11.c delete mode 100644 clutter/clutter/x11/clutter-x11-texture-pixmap.c delete mode 100644 clutter/clutter/x11/clutter-x11-texture-pixmap.h delete mode 100644 clutter/configure.ac delete mode 100644 clutter/examples/Makefile.am delete mode 100644 clutter/examples/actor-model.c delete mode 100644 clutter/examples/basic-actor.c delete mode 100644 clutter/examples/bin-layout.c delete mode 100644 clutter/examples/box-layout.c delete mode 100644 clutter/examples/canvas.c delete mode 100644 clutter/examples/constraints.c delete mode 100644 clutter/examples/drag-action.c delete mode 100644 clutter/examples/drop-action.c delete mode 100644 clutter/examples/easing-modes.c delete mode 100644 clutter/examples/flow-layout.c delete mode 100644 clutter/examples/grid-layout.c delete mode 100644 clutter/examples/image-content.c delete mode 100644 clutter/examples/layout-manager.c delete mode 100644 clutter/examples/pan-action.c delete mode 100644 clutter/examples/rounded-rectangle.c delete mode 100644 clutter/examples/scroll-actor.c delete mode 100644 clutter/examples/threads.c create mode 100644 clutter/meson.build delete mode 100644 clutter/tests/Makefile.am delete mode 100644 clutter/tests/accessibility/.gitignore delete mode 100644 clutter/tests/accessibility/Makefile.am delete mode 100644 clutter/tests/conform/Makefile.am delete mode 100644 clutter/tests/conform/actor-offscreen-limit-max-size.c delete mode 100644 clutter/tests/conform/animator.c delete mode 100644 clutter/tests/conform/behaviours.c delete mode 100644 clutter/tests/conform/cairo-texture.c delete mode 100644 clutter/tests/conform/events-touch.c delete mode 100644 clutter/tests/conform/model.c delete mode 100644 clutter/tests/conform/score.c delete mode 100644 clutter/tests/conform/scripts/test-script-implicit-alpha.json delete mode 100644 clutter/tests/conform/texture.c delete mode 100644 clutter/tests/interactive/Makefile.am delete mode 100644 clutter/tests/interactive/redhand.png delete mode 100644 clutter/tests/interactive/test-animator.c delete mode 100644 clutter/tests/interactive/test-cogl-shader-arbfp.c delete mode 100644 clutter/tests/interactive/test-cogl-tex-foreign.c delete mode 100644 clutter/tests/interactive/test-cogl-vertex-buffer.c delete mode 100644 clutter/tests/interactive/test-depth.c delete mode 100644 clutter/tests/interactive/test-fbo.c delete mode 100644 clutter/tests/interactive/test-multistage.c delete mode 100644 clutter/tests/interactive/test-pixmap.c delete mode 100644 clutter/tests/interactive/test-scale.c delete mode 100644 clutter/tests/interactive/test-stage-read-pixels.c delete mode 100644 clutter/tests/interactive/test-state-animator.c delete mode 100644 clutter/tests/interactive/test-table-layout.c delete mode 100644 clutter/tests/interactive/test-texture-async.c delete mode 100644 clutter/tests/interactive/test-texture-material.c delete mode 100644 clutter/tests/interactive/test-texture-quality.c delete mode 100644 clutter/tests/interactive/test-texture-slicing.c delete mode 100644 clutter/tests/micro-bench/.gitignore delete mode 100644 clutter/tests/micro-bench/Makefile.am delete mode 100644 clutter/tests/performance/.gitignore delete mode 100644 clutter/tests/performance/Makefile-retrospect delete mode 100644 clutter/tests/performance/Makefile-tests delete mode 100644 clutter/tests/performance/Makefile.am delete mode 100644 cogl/Makefile.am delete mode 100644 cogl/build/autotools/Makefile.am.enums delete mode 100644 cogl/build/autotools/as-compiler-flag.m4 delete mode 100644 cogl/build/autotools/introspection.m4 create mode 100644 cogl/cogl-config.h.meson delete mode 100644 cogl/cogl-gles2/GLES2/gl2.h delete mode 100644 cogl/cogl-gles2/GLES2/gl2ext.h delete mode 100644 cogl/cogl-gles2/GLES2/gl2platform.h delete mode 100644 cogl/cogl-gles2/Makefile.am delete mode 100644 cogl/cogl-gles2/cogl-gles2-api.c delete mode 100644 cogl/cogl-gles2/muffin-cogl-gles2.pc.in delete mode 100644 cogl/cogl-muffin-config.h.in create mode 100644 cogl/cogl-mutter-config.h.in delete mode 100644 cogl/cogl-pango/Makefile.am create mode 100644 cogl/cogl-pango/meson.build delete mode 100644 cogl/cogl-pango/muffin-cogl-pango.pc.in create mode 100644 cogl/cogl-pango/mutter-cogl-pango.pc.in delete mode 100644 cogl/cogl-path/Makefile.am create mode 100644 cogl/cogl-path/meson.build delete mode 100644 cogl/cogl-path/muffin-cogl-path.pc.in create mode 100644 cogl/cogl-path/mutter-cogl-path.pc.in delete mode 100644 cogl/cogl-path/tesselator/GL/glu.h delete mode 100644 cogl/cogl/Makefile.am delete mode 100644 cogl/cogl/cogl-config.c rename cogl/cogl/{driver/gl/cogl-pipeline-fragend-fixed-private.h => cogl-defines.h.meson} (63%) delete mode 100644 cogl/cogl/cogl-deprecated.h create mode 100644 cogl/cogl/cogl-dma-buf-handle.c create mode 100644 cogl/cogl/cogl-dma-buf-handle.h delete mode 100644 cogl/cogl/cogl-error-private.h delete mode 100644 cogl/cogl/cogl-error.c delete mode 100644 cogl/cogl/cogl-error.h delete mode 100644 cogl/cogl/cogl-euler.c delete mode 100644 cogl/cogl/cogl-euler.h delete mode 100644 cogl/cogl/cogl-gles2-context-private.h delete mode 100644 cogl/cogl/cogl-gles2-context.c delete mode 100644 cogl/cogl/cogl-gles2-types.h delete mode 100644 cogl/cogl/cogl-gles2.h rename cogl/cogl/{cogl-muffin.h => cogl-mutter.h} (91%) delete mode 100644 cogl/cogl/cogl-pango.h create mode 100644 cogl/cogl/cogl-pixel-format.c create mode 100644 cogl/cogl/cogl-pixel-format.h delete mode 100644 cogl/cogl/cogl-primitives.h delete mode 100644 cogl/cogl/cogl-quaternion-private.h delete mode 100644 cogl/cogl/cogl-quaternion.c delete mode 100644 cogl/cogl/cogl-quaternion.h delete mode 100644 cogl/cogl/cogl-texture-2d-gl.h delete mode 100644 cogl/cogl/cogl-texture-3d-private.h delete mode 100644 cogl/cogl/cogl-texture-3d.c delete mode 100644 cogl/cogl/cogl-texture-3d.h delete mode 100644 cogl/cogl/cogl-texture-rectangle-private.h delete mode 100644 cogl/cogl/cogl-texture-rectangle.c delete mode 100644 cogl/cogl/cogl-texture-rectangle.h create mode 100644 cogl/cogl/cogl-trace.c create mode 100644 cogl/cogl/cogl-trace.h delete mode 100644 cogl/cogl/cogl-vector.c delete mode 100644 cogl/cogl/cogl-vector.h delete mode 100644 cogl/cogl/cogl-xlib.c delete mode 100644 cogl/cogl/cogl.symbols delete mode 100644 cogl/cogl/deprecated/cogl-clutter-xlib.h delete mode 100644 cogl/cogl/deprecated/cogl-framebuffer-deprecated.c delete mode 100644 cogl/cogl/deprecated/cogl-vertex-buffer-private.h delete mode 100644 cogl/cogl/deprecated/cogl-vertex-buffer.c delete mode 100644 cogl/cogl/deprecated/cogl-vertex-buffer.h rename cogl/cogl/{cogl-config-private.h => driver/gl/cogl-bitmap-gl-private.h} (59%) create mode 100644 cogl/cogl/driver/gl/cogl-bitmap-gl.c delete mode 100644 cogl/cogl/driver/gl/cogl-pipeline-fragend-fixed.c delete mode 100644 cogl/cogl/driver/gl/cogl-pipeline-progend-fixed-private.h delete mode 100644 cogl/cogl/driver/gl/cogl-pipeline-progend-fixed.c delete mode 100644 cogl/cogl/driver/gl/cogl-pipeline-vertend-fixed-private.h delete mode 100644 cogl/cogl/driver/gl/cogl-pipeline-vertend-fixed.c delete mode 100644 cogl/cogl/driver/gl/gl/cogl-pipeline-fragend-arbfp-private.h delete mode 100644 cogl/cogl/driver/gl/gl/cogl-pipeline-fragend-arbfp.c delete mode 100644 cogl/cogl/driver/gl/gl/cogl-pipeline-progend-fixed-arbfp-private.h delete mode 100644 cogl/cogl/driver/gl/gl/cogl-pipeline-progend-fixed-arbfp.c delete mode 100644 cogl/cogl/gl-prototypes/cogl-fixed-functions.h delete mode 100644 cogl/cogl/gl-prototypes/cogl-gles1-functions.h delete mode 100644 cogl/cogl/gl-prototypes/cogl-in-gles1-core-functions.h create mode 100644 cogl/cogl/meson.build rename cogl/cogl/{muffin-cogl.pc.in => mutter-cogl.pc.in} (51%) rename cogl/cogl/{ => winsys}/cogl-glx-display-private.h (89%) rename cogl/cogl/{ => winsys}/cogl-glx-renderer-private.h (97%) rename cogl/cogl/{ => winsys}/cogl-glx.h (83%) delete mode 100644 cogl/cogl/winsys/cogl-winsys-stub-private.h delete mode 100644 cogl/cogl/winsys/cogl-winsys-stub.c delete mode 100644 cogl/configure.ac create mode 100644 cogl/meson.build delete mode 100644 cogl/test-fixtures/Makefile.am create mode 100644 cogl/test-fixtures/meson.build delete mode 100644 cogl/tests/Makefile.am delete mode 100644 cogl/tests/conform/Makefile.am create mode 100644 cogl/tests/conform/meson.build create mode 100755 cogl/tests/conform/meson/find-conform-unit-tests.sh create mode 100644 cogl/tests/conform/mutter-cogl.test.in delete mode 100644 cogl/tests/conform/test-color-mask.c create mode 100644 cogl/tests/conform/test-declarations.h rename cogl/tests/conform/{test-euler-quaternion.c => test-euler.c} (76%) delete mode 100644 cogl/tests/conform/test-fixed.c delete mode 100644 cogl/tests/conform/test-gles2-context.c delete mode 100644 cogl/tests/conform/test-materials.c delete mode 100644 cogl/tests/conform/test-texture-3d.c delete mode 100644 cogl/tests/conform/test-texture-rectangle.c delete mode 100644 cogl/tests/conform/test-vertex-buffer-contiguous.c delete mode 100644 cogl/tests/conform/test-vertex-buffer-interleved.c delete mode 100644 cogl/tests/conform/test-vertex-buffer-mutability.c delete mode 100644 cogl/tests/conform/test-wrap-rectangle-textures.c delete mode 100644 cogl/tests/data/Makefile.am create mode 100644 cogl/tests/meson.build delete mode 100644 cogl/tests/micro-perf/Makefile.am delete mode 100644 cogl/tests/micro-perf/test-journal.c delete mode 100644 cogl/tests/unit/Makefile.am create mode 100644 cogl/tests/unit/meson.build create mode 100755 cogl/tests/unit/meson/find-unit-tests.sh create mode 100644 config.h.meson delete mode 100644 configure.ac delete mode 100644 data/Makefile.am create mode 100644 data/default_icon.png create mode 100644 data/meson.build rename {src => data}/muffin.desktop.in (97%) create mode 100644 data/org.cinnamon.muffin.gschema.xml.in create mode 100644 data/org.cinnamon.muffin.wayland.gschema.xml.in create mode 100644 data/org.cinnamon.muffin.x11.gschema.xml.in delete mode 100644 data/theme/metacity-theme-3.xml create mode 100644 debian/clean delete mode 100644 debian/compat create mode 100644 debian/libmuffin-dev.install create mode 100644 debian/libmuffin0.bug-control delete mode 100644 debian/muffin-common.maintscript delete mode 100644 debian/muffin-doc.install create mode 100644 debian/muffin.docs create mode 100644 debian/muffin.postinst create mode 100644 debian/muffin.prerm delete mode 100644 debian/not-installed create mode 100644 debian/tests/control create mode 100755 debian/tests/libmutter-6-dev delete mode 100644 doc/Makefile.am create mode 100644 doc/compositor-control.txt create mode 100644 doc/how-constraints-works.txt delete mode 100644 doc/man/Makefile.am create mode 100644 doc/man/meson.build delete mode 100644 doc/man/muffin-message.1 delete mode 100644 doc/man/muffin-theme-viewer.1 delete mode 100644 doc/man/muffin-window-demo.1 rename rationales.txt => doc/rationales.txt (100%) delete mode 100644 doc/reference/Makefile.am delete mode 100644 doc/reference/clutter/ChangeLog delete mode 100644 doc/reference/clutter/Makefile.am delete mode 100644 doc/reference/clutter/actor-box.png delete mode 100644 doc/reference/clutter/actor-example.png delete mode 100644 doc/reference/clutter/animator-key-frames.png delete mode 100644 doc/reference/clutter/animator-key-frames.svg delete mode 100644 doc/reference/clutter/bin-layout.png delete mode 100644 doc/reference/clutter/box-layout.png delete mode 100644 doc/reference/clutter/building-clutter.xml delete mode 100644 doc/reference/clutter/clutter-docs.xml.in delete mode 100644 doc/reference/clutter/clutter-overview.xml delete mode 100644 doc/reference/clutter/constraints-example.png delete mode 100644 doc/reference/clutter/easing-modes.png delete mode 100644 doc/reference/clutter/easing-modes.svg delete mode 100644 doc/reference/clutter/event-flow.dia delete mode 100644 doc/reference/clutter/event-flow.png delete mode 100644 doc/reference/clutter/flow-layout.png delete mode 100644 doc/reference/clutter/glossary.xml delete mode 100644 doc/reference/clutter/migrating-ClutterAnimation.xml delete mode 100644 doc/reference/clutter/migrating-ClutterBehaviour.xml delete mode 100644 doc/reference/clutter/migrating-ClutterEffect.xml delete mode 100644 doc/reference/clutter/migrating-ClutterPath.xml delete mode 100644 doc/reference/clutter/offscreen-redirect.png delete mode 100644 doc/reference/clutter/path-alpha-func.png delete mode 100644 doc/reference/clutter/running-clutter.xml delete mode 100644 doc/reference/clutter/table-layout.png delete mode 100644 doc/reference/cogl/Makefile.am delete mode 100644 doc/reference/cogl/blend-strings.xml delete mode 100644 doc/reference/cogl/cogl-docs.xml.in delete mode 100644 doc/reference/cogl/cogl-sections.txt delete mode 100644 doc/reference/cogl/cogl_ortho.png delete mode 100644 doc/reference/cogl/fill-rule-even-odd.png delete mode 100644 doc/reference/cogl/fill-rule-non-zero.png delete mode 100644 doc/reference/cogl/quad-indices-order.png delete mode 100644 doc/reference/cogl/quad-indices-triangles.png delete mode 100644 doc/reference/muffin-docs.sgml delete mode 100644 doc/reference/muffin-docs.sgml.in delete mode 100644 doc/reference/muffin-overview.xml delete mode 100644 doc/reference/muffin/Makefile.am delete mode 100644 doc/reference/muffin/muffin-docs.sgml.in delete mode 100644 doc/reference/muffin/muffin-overrides.txt delete mode 100644 doc/reference/muffin/muffin-overview.xml delete mode 100644 doc/reference/muffin/running-muffin.xml delete mode 100644 doc/reference/running-muffin.xml create mode 100644 doc/strut-and-related-updating.txt delete mode 100644 doc/theme-format.txt create mode 100644 meson.build create mode 100755 meson/meson-postinstall.sh create mode 100644 meson_options.txt create mode 100644 mutter.doap delete mode 100644 po/ChangeLog delete mode 100644 po/Makefile.in.in create mode 100644 po/fur.po create mode 100644 po/gd.po create mode 100644 po/kk.po create mode 100644 po/meson.build create mode 100644 po/tg.po delete mode 100644 src/Makefile.am create mode 100644 src/backends/edid-parse.c create mode 100644 src/backends/edid.h create mode 100644 src/backends/gsm-inhibitor-flag.h create mode 100644 src/backends/meta-backend-private.h create mode 100644 src/backends/meta-backend-types.h create mode 100644 src/backends/meta-backend.c create mode 100644 src/backends/meta-barrier-private.h create mode 100644 src/backends/meta-barrier.c create mode 100644 src/backends/meta-crtc.c create mode 100644 src/backends/meta-crtc.h create mode 100644 src/backends/meta-cursor-renderer.c create mode 100644 src/backends/meta-cursor-renderer.h create mode 100644 src/backends/meta-cursor-sprite-xcursor.c create mode 100644 src/backends/meta-cursor-sprite-xcursor.h create mode 100644 src/backends/meta-cursor-tracker-private.h create mode 100644 src/backends/meta-cursor-tracker.c create mode 100644 src/backends/meta-cursor.c create mode 100644 src/backends/meta-cursor.h create mode 100644 src/backends/meta-dbus-session-watcher.c create mode 100644 src/backends/meta-dbus-session-watcher.h create mode 100644 src/backends/meta-display-config-shared.h create mode 100644 src/backends/meta-dnd-private.h create mode 100644 src/backends/meta-egl-ext.h create mode 100644 src/backends/meta-egl.c create mode 100644 src/backends/meta-egl.h create mode 100644 src/backends/meta-gles3-table.h create mode 100644 src/backends/meta-gles3.c create mode 100644 src/backends/meta-gles3.h create mode 100644 src/backends/meta-gpu.c create mode 100644 src/backends/meta-gpu.h create mode 100644 src/backends/meta-idle-monitor-dbus.c create mode 100644 src/backends/meta-idle-monitor-dbus.h create mode 100644 src/backends/meta-idle-monitor-private.h create mode 100644 src/backends/meta-idle-monitor.c create mode 100644 src/backends/meta-input-device-private.h create mode 100644 src/backends/meta-input-device.c create mode 100644 src/backends/meta-input-mapper-private.h create mode 100644 src/backends/meta-input-mapper.c create mode 100644 src/backends/meta-input-settings-private.h create mode 100644 src/backends/meta-input-settings.c create mode 100644 src/backends/meta-logical-monitor.c create mode 100644 src/backends/meta-logical-monitor.h create mode 100644 src/backends/meta-monitor-config-manager.c create mode 100644 src/backends/meta-monitor-config-manager.h create mode 100644 src/backends/meta-monitor-config-migration.c create mode 100644 src/backends/meta-monitor-config-migration.h create mode 100644 src/backends/meta-monitor-config-store.c create mode 100644 src/backends/meta-monitor-config-store.h create mode 100644 src/backends/meta-monitor-manager-dummy.c create mode 100644 src/backends/meta-monitor-manager-dummy.h create mode 100644 src/backends/meta-monitor-manager-private.h create mode 100644 src/backends/meta-monitor-manager.c create mode 100644 src/backends/meta-monitor-transform.c create mode 100644 src/backends/meta-monitor-transform.h create mode 100644 src/backends/meta-monitor.c create mode 100644 src/backends/meta-monitor.h create mode 100644 src/backends/meta-orientation-manager.c create mode 100644 src/backends/meta-orientation-manager.h create mode 100644 src/backends/meta-output.c create mode 100644 src/backends/meta-output.h create mode 100644 src/backends/meta-pointer-constraint.c create mode 100644 src/backends/meta-pointer-constraint.h create mode 100644 src/backends/meta-profiler.c create mode 100644 src/backends/meta-profiler.h create mode 100644 src/backends/meta-remote-access-controller-private.h create mode 100644 src/backends/meta-remote-access-controller.c create mode 100644 src/backends/meta-remote-desktop-session.c create mode 100644 src/backends/meta-remote-desktop-session.h create mode 100644 src/backends/meta-remote-desktop.c create mode 100644 src/backends/meta-remote-desktop.h create mode 100644 src/backends/meta-renderer-view.c create mode 100644 src/backends/meta-renderer-view.h create mode 100644 src/backends/meta-renderer.c create mode 100644 src/backends/meta-renderer.h create mode 100644 src/backends/meta-screen-cast-monitor-stream-src.c create mode 100644 src/backends/meta-screen-cast-monitor-stream-src.h create mode 100644 src/backends/meta-screen-cast-monitor-stream.c create mode 100644 src/backends/meta-screen-cast-monitor-stream.h create mode 100644 src/backends/meta-screen-cast-session.c create mode 100644 src/backends/meta-screen-cast-session.h create mode 100644 src/backends/meta-screen-cast-stream-src.c create mode 100644 src/backends/meta-screen-cast-stream-src.h create mode 100644 src/backends/meta-screen-cast-stream.c create mode 100644 src/backends/meta-screen-cast-stream.h create mode 100644 src/backends/meta-screen-cast-window-stream-src.c create mode 100644 src/backends/meta-screen-cast-window-stream-src.h create mode 100644 src/backends/meta-screen-cast-window-stream.c create mode 100644 src/backends/meta-screen-cast-window-stream.h create mode 100644 src/backends/meta-screen-cast-window.c create mode 100644 src/backends/meta-screen-cast-window.h create mode 100644 src/backends/meta-screen-cast.c create mode 100644 src/backends/meta-screen-cast.h create mode 100644 src/backends/meta-settings-private.h create mode 100644 src/backends/meta-settings.c create mode 100644 src/backends/meta-stage-private.h create mode 100644 src/backends/meta-stage.c create mode 100644 src/backends/native/dbus-utils.c create mode 100644 src/backends/native/dbus-utils.h create mode 100755 src/backends/native/gen-default-modes.py create mode 100644 src/backends/native/meta-backend-native-private.h create mode 100644 src/backends/native/meta-backend-native-types.h create mode 100644 src/backends/native/meta-backend-native.c create mode 100644 src/backends/native/meta-backend-native.h create mode 100644 src/backends/native/meta-barrier-native.c create mode 100644 src/backends/native/meta-barrier-native.h create mode 100644 src/backends/native/meta-clutter-backend-native.c create mode 100644 src/backends/native/meta-clutter-backend-native.h create mode 100644 src/backends/native/meta-crtc-kms.c create mode 100644 src/backends/native/meta-crtc-kms.h create mode 100644 src/backends/native/meta-cursor-renderer-native.c create mode 100644 src/backends/native/meta-cursor-renderer-native.h create mode 100644 src/backends/native/meta-drm-buffer-dumb.c create mode 100644 src/backends/native/meta-drm-buffer-dumb.h create mode 100644 src/backends/native/meta-drm-buffer-gbm.c create mode 100644 src/backends/native/meta-drm-buffer-gbm.h create mode 100644 src/backends/native/meta-drm-buffer-import.c create mode 100644 src/backends/native/meta-drm-buffer-import.h create mode 100644 src/backends/native/meta-drm-buffer.c create mode 100644 src/backends/native/meta-drm-buffer.h create mode 100644 src/backends/native/meta-event-native.c create mode 100644 src/backends/native/meta-event-native.h create mode 100644 src/backends/native/meta-gpu-kms.c create mode 100644 src/backends/native/meta-gpu-kms.h rename clutter/clutter/evdev/clutter-input-device-evdev.c => src/backends/native/meta-input-device-native.c (63%) create mode 100644 src/backends/native/meta-input-device-native.h rename clutter/clutter/evdev/clutter-input-device-tool-evdev.c => src/backends/native/meta-input-device-tool-native.c (51%) create mode 100644 src/backends/native/meta-input-device-tool-native.h create mode 100644 src/backends/native/meta-input-settings-native.c create mode 100644 src/backends/native/meta-input-settings-native.h create mode 100644 src/backends/native/meta-keymap-native.c create mode 100644 src/backends/native/meta-keymap-native.h create mode 100644 src/backends/native/meta-kms-connector-private.h create mode 100644 src/backends/native/meta-kms-connector.c create mode 100644 src/backends/native/meta-kms-connector.h create mode 100644 src/backends/native/meta-kms-crtc-private.h create mode 100644 src/backends/native/meta-kms-crtc.c create mode 100644 src/backends/native/meta-kms-crtc.h create mode 100644 src/backends/native/meta-kms-device-private.h create mode 100644 src/backends/native/meta-kms-device.c create mode 100644 src/backends/native/meta-kms-device.h create mode 100644 src/backends/native/meta-kms-impl-device.c create mode 100644 src/backends/native/meta-kms-impl-device.h create mode 100644 src/backends/native/meta-kms-impl-simple.c create mode 100644 src/backends/native/meta-kms-impl-simple.h create mode 100644 src/backends/native/meta-kms-impl.c create mode 100644 src/backends/native/meta-kms-impl.h create mode 100644 src/backends/native/meta-kms-page-flip-private.h create mode 100644 src/backends/native/meta-kms-page-flip.c create mode 100644 src/backends/native/meta-kms-plane-private.h create mode 100644 src/backends/native/meta-kms-plane.c create mode 100644 src/backends/native/meta-kms-plane.h create mode 100644 src/backends/native/meta-kms-private.h create mode 100644 src/backends/native/meta-kms-types.h create mode 100644 src/backends/native/meta-kms-update-private.h create mode 100644 src/backends/native/meta-kms-update.c create mode 100644 src/backends/native/meta-kms-update.h create mode 100644 src/backends/native/meta-kms-utils.c create mode 100644 src/backends/native/meta-kms-utils.h create mode 100644 src/backends/native/meta-kms.c create mode 100644 src/backends/native/meta-kms.h create mode 100644 src/backends/native/meta-launcher.c create mode 100644 src/backends/native/meta-launcher.h create mode 100644 src/backends/native/meta-monitor-manager-kms.c create mode 100644 src/backends/native/meta-monitor-manager-kms.h create mode 100644 src/backends/native/meta-output-kms.c create mode 100644 src/backends/native/meta-output-kms.h create mode 100644 src/backends/native/meta-renderer-native-gles3.c create mode 100644 src/backends/native/meta-renderer-native-gles3.h create mode 100644 src/backends/native/meta-renderer-native.c create mode 100644 src/backends/native/meta-renderer-native.h create mode 100644 src/backends/native/meta-seat-native.c create mode 100644 src/backends/native/meta-seat-native.h create mode 100644 src/backends/native/meta-stage-native.c create mode 100644 src/backends/native/meta-stage-native.h create mode 100644 src/backends/native/meta-udev.c create mode 100644 src/backends/native/meta-udev.h create mode 100644 src/backends/native/meta-virtual-input-device-native.c rename clutter/clutter/x11/clutter-virtual-input-device-x11.h => src/backends/native/meta-virtual-input-device-native.h (61%) rename clutter/clutter/evdev/clutter-xkb-utils.c => src/backends/native/meta-xkb-utils.c (67%) create mode 100644 src/backends/native/meta-xkb-utils.h create mode 100644 src/backends/x11/cm/meta-backend-x11-cm.c create mode 100644 src/backends/x11/cm/meta-backend-x11-cm.h create mode 100644 src/backends/x11/cm/meta-cursor-sprite-xfixes.c create mode 100644 src/backends/x11/cm/meta-cursor-sprite-xfixes.h create mode 100644 src/backends/x11/cm/meta-renderer-x11-cm.c create mode 100644 src/backends/x11/cm/meta-renderer-x11-cm.h create mode 100644 src/backends/x11/meta-backend-x11.c create mode 100644 src/backends/x11/meta-backend-x11.h create mode 100644 src/backends/x11/meta-barrier-x11.c create mode 100644 src/backends/x11/meta-barrier-x11.h create mode 100644 src/backends/x11/meta-clutter-backend-x11.c create mode 100644 src/backends/x11/meta-clutter-backend-x11.h create mode 100644 src/backends/x11/meta-crtc-xrandr.c create mode 100644 src/backends/x11/meta-crtc-xrandr.h create mode 100644 src/backends/x11/meta-cursor-renderer-x11.c create mode 100644 src/backends/x11/meta-cursor-renderer-x11.h create mode 100644 src/backends/x11/meta-event-x11.c create mode 100644 src/backends/x11/meta-event-x11.h create mode 100644 src/backends/x11/meta-gpu-xrandr.c create mode 100644 src/backends/x11/meta-gpu-xrandr.h rename clutter/clutter/x11/clutter-input-device-tool-xi2.c => src/backends/x11/meta-input-device-tool-x11.c (62%) create mode 100644 src/backends/x11/meta-input-device-tool-x11.h create mode 100644 src/backends/x11/meta-input-device-x11.c create mode 100644 src/backends/x11/meta-input-device-x11.h create mode 100644 src/backends/x11/meta-input-settings-x11.c create mode 100644 src/backends/x11/meta-input-settings-x11.h create mode 100644 src/backends/x11/meta-keymap-x11.c create mode 100644 src/backends/x11/meta-keymap-x11.h create mode 100644 src/backends/x11/meta-monitor-manager-xrandr.c create mode 100644 src/backends/x11/meta-monitor-manager-xrandr.h create mode 100644 src/backends/x11/meta-output-xrandr.c create mode 100644 src/backends/x11/meta-output-xrandr.h create mode 100644 src/backends/x11/meta-renderer-x11.c create mode 100644 src/backends/x11/meta-renderer-x11.h rename clutter/clutter/x11/clutter-device-manager-xi2.c => src/backends/x11/meta-seat-x11.c (53%) create mode 100644 src/backends/x11/meta-seat-x11.h create mode 100644 src/backends/x11/meta-stage-x11.c create mode 100644 src/backends/x11/meta-stage-x11.h create mode 100644 src/backends/x11/meta-virtual-input-device-x11.c rename clutter/clutter/evdev/clutter-virtual-input-device-evdev.h => src/backends/x11/meta-virtual-input-device-x11.h (60%) rename clutter/clutter/x11/clutter-xkb-a11y-x11.c => src/backends/x11/meta-xkb-a11y-x11.c (81%) rename clutter/clutter/x11/clutter-xkb-a11y-x11.h => src/backends/x11/meta-xkb-a11y-x11.h (66%) create mode 100644 src/backends/x11/nested/meta-backend-x11-nested.c create mode 100644 src/backends/x11/nested/meta-backend-x11-nested.h create mode 100644 src/backends/x11/nested/meta-cursor-renderer-x11-nested.c create mode 100644 src/backends/x11/nested/meta-cursor-renderer-x11-nested.h create mode 100644 src/backends/x11/nested/meta-renderer-x11-nested.c create mode 100644 src/backends/x11/nested/meta-renderer-x11-nested.h create mode 100644 src/backends/x11/nested/meta-stage-x11-nested.c create mode 100644 src/backends/x11/nested/meta-stage-x11-nested.h create mode 100644 src/compositor/README create mode 100644 src/compositor/meta-background-group.c create mode 100644 src/compositor/meta-background-image.c create mode 100644 src/compositor/meta-background-private.h delete mode 100644 src/compositor/meta-background.h create mode 100644 src/compositor/meta-compositor-server.c create mode 100644 src/compositor/meta-compositor-server.h create mode 100644 src/compositor/meta-compositor-x11.c create mode 100644 src/compositor/meta-compositor-x11.h create mode 100644 src/compositor/meta-cullable.c create mode 100644 src/compositor/meta-cullable.h create mode 100644 src/compositor/meta-dnd-actor-private.h create mode 100644 src/compositor/meta-dnd-actor.c create mode 100644 src/compositor/meta-dnd.c create mode 100644 src/compositor/meta-feedback-actor-private.h create mode 100644 src/compositor/meta-feedback-actor.c delete mode 100644 src/compositor/meta-shadow-factory-private.h create mode 100644 src/compositor/meta-surface-actor-wayland.c create mode 100644 src/compositor/meta-surface-actor-wayland.h create mode 100644 src/compositor/meta-surface-actor-x11.c create mode 100644 src/compositor/meta-surface-actor-x11.h create mode 100644 src/compositor/meta-surface-actor.c create mode 100644 src/compositor/meta-surface-actor.h delete mode 100644 src/compositor/meta-texture-rectangle.c create mode 100644 src/compositor/meta-window-actor-wayland.c create mode 100644 src/compositor/meta-window-actor-wayland.h create mode 100644 src/compositor/meta-window-actor-x11.c create mode 100644 src/compositor/meta-window-actor-x11.h create mode 100644 src/compositor/meta-window-group-private.h delete mode 100644 src/compositor/meta-window-group.h delete mode 100644 src/compositor/plugins/Makefile.am create mode 100644 src/compositor/plugins/meson.build delete mode 100644 src/core/above-tab-keycode.c delete mode 100644 src/core/async-getprop.c delete mode 100644 src/core/async-getprop.h delete mode 100644 src/core/core.c delete mode 100644 src/core/core.h delete mode 100644 src/core/eventqueue.c create mode 100644 src/core/events.c create mode 100644 src/core/events.h delete mode 100644 src/core/iconcache.c create mode 100644 src/core/main-private.h create mode 100644 src/core/meta-accel-parse.c create mode 100644 src/core/meta-accel-parse.h create mode 100644 src/core/meta-border.c create mode 100644 src/core/meta-border.h create mode 100644 src/core/meta-clipboard-manager.c create mode 100644 src/core/meta-clipboard-manager.h create mode 100644 src/core/meta-close-dialog-default-private.h create mode 100644 src/core/meta-close-dialog-default.c create mode 100644 src/core/meta-close-dialog.c create mode 100644 src/core/meta-fraction.c create mode 100644 src/core/meta-fraction.h create mode 100644 src/core/meta-gesture-tracker-private.h create mode 100644 src/core/meta-gesture-tracker.c create mode 100644 src/core/meta-inhibit-shortcuts-dialog-default-private.h create mode 100644 src/core/meta-inhibit-shortcuts-dialog-default.c create mode 100644 src/core/meta-inhibit-shortcuts-dialog.c create mode 100644 src/core/meta-launch-context.c create mode 100644 src/core/meta-selection-private.h create mode 100644 src/core/meta-selection-source-memory.c create mode 100644 src/core/meta-selection-source.c create mode 100644 src/core/meta-selection.c create mode 100644 src/core/meta-sound-player.c create mode 100644 src/core/meta-workspace-manager-private.h create mode 100644 src/core/meta-workspace-manager.c rename src/core/{muffin.c => mutter.c} (71%) delete mode 100644 src/core/screen-private.h delete mode 100644 src/core/screen.c create mode 100644 src/core/startup-notification-private.h create mode 100644 src/core/startup-notification.c delete mode 100644 src/core/testasyncgetprop.c delete mode 100644 src/core/window-props.h delete mode 100644 src/core/xprops.h delete mode 100644 src/libmuffin.pc.in create mode 100644 src/libmutter.pc.in create mode 100644 src/meson.build create mode 100644 src/meta-marshal.list create mode 100644 src/meta/barrier.h delete mode 100644 src/meta/compositor-muffin.h create mode 100644 src/meta/compositor-mutter.h delete mode 100644 src/meta/gradient.h create mode 100644 src/meta/meson.build create mode 100644 src/meta/meta-backend.h create mode 100644 src/meta/meta-background-group.h create mode 100644 src/meta/meta-background-image.h create mode 100644 src/meta/meta-background.h create mode 100644 src/meta/meta-close-dialog.h create mode 100644 src/meta/meta-cursor-tracker.h create mode 100644 src/meta/meta-dnd.h rename src/{muffin-enum-types.c.in => meta/meta-enum-types.c.in} (96%) rename src/{muffin-enum-types.h.in => meta/meta-enum-types.h.in} (60%) create mode 100644 src/meta/meta-idle-monitor.h create mode 100644 src/meta/meta-inhibit-shortcuts-dialog.h create mode 100644 src/meta/meta-launch-context.h create mode 100644 src/meta/meta-monitor-manager.h create mode 100644 src/meta/meta-remote-access-controller.h create mode 100644 src/meta/meta-selection-source-memory.h create mode 100644 src/meta/meta-selection-source.h create mode 100644 src/meta/meta-selection.h create mode 100644 src/meta/meta-settings.h create mode 100644 src/meta/meta-sound-player.h rename src/{compositor/meta-texture-rectangle.h => meta/meta-stage.h} (59%) create mode 100644 src/meta/meta-startup-notification.h create mode 100644 src/meta/meta-version.h.in create mode 100644 src/meta/meta-window-group.h rename src/{compositor => meta}/meta-window-shape.h (89%) create mode 100644 src/meta/meta-workspace-manager.h create mode 100644 src/meta/meta-x11-display.h rename src/meta/{errors.h => meta-x11-errors.h} (64%) delete mode 100644 src/meta/preview-widget.h delete mode 100644 src/meta/screen.h delete mode 100644 src/muffin-plugins.pc.in delete mode 100644 src/muffin.desktop.desktop delete mode 100644 src/org.cinnamon.muffin.gschema.xml.in create mode 100644 src/org.freedesktop.login1.xml create mode 100644 src/org.gnome.Mutter.DisplayConfig.xml create mode 100644 src/org.gnome.Mutter.IdleMonitor.xml create mode 100644 src/org.gnome.Mutter.RemoteDesktop.xml create mode 100644 src/org.gnome.Mutter.ScreenCast.xml delete mode 100644 src/stock_delete.png delete mode 100644 src/stock_maximize.png delete mode 100644 src/stock_minimize.png create mode 100644 src/tests/README rename src/{core/testboxes.c => tests/boxes-tests.c} (93%) create mode 100644 src/tests/boxes-tests.h rename {clutter/clutter => src/tests}/clutter-test-utils.c (89%) rename {clutter/clutter => src/tests}/clutter-test-utils.h (82%) create mode 100644 src/tests/clutter/README rename {clutter/tests => src/tests/clutter}/accessibility/cally-atkcomponent-example.c (100%) rename {clutter/tests => src/tests/clutter}/accessibility/cally-atkeditabletext-example.c (100%) rename {clutter/tests => src/tests/clutter}/accessibility/cally-atkevents-example.c (100%) rename {clutter/tests => src/tests/clutter}/accessibility/cally-atktext-example.c (84%) rename {clutter/tests => src/tests/clutter}/accessibility/cally-clone-example.c (100%) rename {clutter/tests => src/tests/clutter}/accessibility/cally-examples-util.c (98%) rename {clutter/tests => src/tests/clutter}/accessibility/cally-examples-util.h (100%) create mode 100644 src/tests/clutter/accessibility/meson.build rename {clutter/tests => src/tests/clutter}/clutter-1.0.suppressions (95%) rename {clutter/tests => src/tests/clutter}/conform/actor-anchors.c (98%) create mode 100644 src/tests/clutter/conform/actor-clone.c rename {clutter/tests => src/tests/clutter}/conform/actor-destroy.c (77%) rename {clutter/tests => src/tests/clutter}/conform/actor-graph.c (99%) rename {clutter/tests => src/tests/clutter}/conform/actor-invariants.c (99%) rename {clutter/tests => src/tests/clutter}/conform/actor-iter.c (98%) rename {clutter/tests => src/tests/clutter}/conform/actor-layout.c (90%) rename {clutter/tests => src/tests/clutter}/conform/actor-meta.c (96%) rename {clutter/tests => src/tests/clutter}/conform/actor-offscreen-redirect.c (69%) rename {clutter/tests => src/tests/clutter}/conform/actor-paint-opacity.c (99%) rename {clutter/tests => src/tests/clutter}/conform/actor-pick.c (67%) rename {clutter/tests => src/tests/clutter}/conform/actor-shader-effect.c (85%) rename {clutter/tests => src/tests/clutter}/conform/actor-size.c (99%) rename {clutter/tests => src/tests/clutter}/conform/binding-pool.c (92%) rename {clutter/tests => src/tests/clutter}/conform/cally-text.c (99%) rename {clutter/tests => src/tests/clutter}/conform/color.c (99%) rename {clutter/tests => src/tests/clutter}/conform/group.c (97%) rename {clutter/tests => src/tests/clutter}/conform/interval.c (98%) create mode 100644 src/tests/clutter/conform/meson.build rename {clutter/tests => src/tests/clutter}/conform/path.c (99%) rename {clutter/tests => src/tests/clutter}/conform/rectangle.c (97%) rename {clutter/tests => src/tests/clutter}/conform/script-parser.c (90%) rename {clutter/tests => src/tests/clutter}/conform/scripts/test-animator-1.json (100%) rename {clutter/tests => src/tests/clutter}/conform/scripts/test-animator-2.json (100%) rename {clutter/tests => src/tests/clutter}/conform/scripts/test-animator-3.json (100%) rename {clutter/tests => src/tests/clutter}/conform/scripts/test-script-animation.json (100%) rename {clutter/tests => src/tests/clutter}/conform/scripts/test-script-child.json (100%) rename {clutter/tests => src/tests/clutter}/conform/scripts/test-script-interval.json (100%) rename {clutter/tests => src/tests/clutter}/conform/scripts/test-script-layout-property.json (100%) rename {clutter/tests => src/tests/clutter}/conform/scripts/test-script-margin.json (100%) rename {clutter/tests => src/tests/clutter}/conform/scripts/test-script-model.json (100%) rename {clutter/tests => src/tests/clutter}/conform/scripts/test-script-named-object.json (100%) rename {clutter/tests => src/tests/clutter}/conform/scripts/test-script-object-property.json (100%) rename {clutter/tests => src/tests/clutter}/conform/scripts/test-script-single.json (100%) rename {clutter/tests => src/tests/clutter}/conform/scripts/test-script-timeline-markers.json (100%) rename {clutter/tests => src/tests/clutter}/conform/scripts/test-state-1.json (100%) rename {clutter/tests => src/tests/clutter}/conform/state.c (99%) rename {clutter/tests => src/tests/clutter}/conform/text-cache.c (98%) rename {clutter/tests => src/tests/clutter}/conform/text.c (96%) rename {clutter/tests => src/tests/clutter}/conform/texture-fbo.c (97%) rename {clutter/tests => src/tests/clutter}/conform/timeline-interpolate.c (93%) rename {clutter/tests => src/tests/clutter}/conform/timeline-progress.c (100%) rename {clutter/tests => src/tests/clutter}/conform/timeline-rewind.c (100%) rename {clutter/tests => src/tests/clutter}/conform/timeline.c (98%) rename {clutter/tests => src/tests/clutter}/conform/units.c (98%) create mode 100644 src/tests/clutter/interactive/meson.build create mode 100755 src/tests/clutter/interactive/meson/gen-test-unit-names.sh rename {clutter/examples => src/tests/clutter/interactive}/redhand.png (100%) rename {clutter/tests => src/tests/clutter}/interactive/test-actors.c (87%) rename {clutter/tests => src/tests/clutter}/interactive/test-animation.c (97%) rename {clutter/tests => src/tests/clutter}/interactive/test-bind-constraint.c (98%) rename {clutter/tests => src/tests/clutter}/interactive/test-binding-pool.c (92%) rename {clutter/tests => src/tests/clutter}/interactive/test-cairo-clock.c (97%) rename {clutter/tests => src/tests/clutter}/interactive/test-cairo-flowers.c (98%) rename {clutter/tests => src/tests/clutter}/interactive/test-cogl-multitexture.c (80%) rename {clutter/tests => src/tests/clutter}/interactive/test-cogl-offscreen.c (70%) rename {clutter/tests => src/tests/clutter}/interactive/test-cogl-point-sprites.c (87%) rename {clutter/tests => src/tests/clutter}/interactive/test-cogl-shader-glsl.c (90%) rename {clutter/tests => src/tests/clutter}/interactive/test-cogl-tex-convert.c (58%) rename {clutter/tests => src/tests/clutter}/interactive/test-cogl-tex-polygon.c (67%) rename {clutter/tests => src/tests/clutter}/interactive/test-cogl-tex-tile.c (77%) rename {clutter/tests => src/tests/clutter}/interactive/test-content.c (92%) rename {clutter/tests => src/tests/clutter}/interactive/test-devices.c (83%) rename {clutter/tests => src/tests/clutter}/interactive/test-easing.c (91%) rename {clutter/tests => src/tests/clutter}/interactive/test-events.c (87%) rename {clutter/tests => src/tests/clutter}/interactive/test-grab.c (74%) rename {clutter/tests => src/tests/clutter}/interactive/test-image.c (92%) rename {clutter/tests => src/tests/clutter}/interactive/test-keyframe-transition.c (96%) rename {clutter/tests => src/tests/clutter}/interactive/test-layout.c (97%) rename {clutter/tests => src/tests/clutter}/interactive/test-main.c (88%) rename {clutter/tests => src/tests/clutter}/interactive/test-paint-wrapper.c (80%) rename {clutter/tests => src/tests/clutter}/interactive/test-path-constraint.c (97%) rename {clutter/tests => src/tests/clutter}/interactive/test-rotate-zoom.c (96%) rename {clutter/tests => src/tests/clutter}/interactive/test-script-signals.json (100%) rename {clutter/tests => src/tests/clutter}/interactive/test-script.c (72%) rename {clutter/tests => src/tests/clutter}/interactive/test-script.json (71%) rename {clutter/tests => src/tests/clutter}/interactive/test-scrolling.c (98%) rename {clutter/tests => src/tests/clutter}/interactive/test-shader-effects.c (94%) rename {clutter/tests => src/tests/clutter}/interactive/test-stage-sizing.c (56%) rename {clutter/tests => src/tests/clutter}/interactive/test-state-script.c (82%) rename {clutter/tests => src/tests/clutter}/interactive/test-state.c (96%) rename {clutter/tests => src/tests/clutter}/interactive/test-swipe-action.c (96%) rename {clutter/tests => src/tests/clutter}/interactive/test-text-field.c (93%) rename {clutter/tests => src/tests/clutter}/interactive/test-text.c (96%) rename {clutter/tests => src/tests/clutter}/interactive/test-touch-events.c (81%) rename {clutter/tests => src/tests/clutter}/interactive/wrapper.sh.in (100%) create mode 100644 src/tests/clutter/meson.build create mode 100644 src/tests/clutter/micro-bench/meson.build rename {clutter/tests => src/tests/clutter}/micro-bench/test-cogl-perf.c (62%) rename {clutter/tests => src/tests/clutter}/micro-bench/test-picking.c (96%) rename {clutter/tests => src/tests/clutter}/micro-bench/test-random-text.c (100%) rename {clutter/tests => src/tests/clutter}/micro-bench/test-text-perf.c (96%) rename {clutter/tests => src/tests/clutter}/micro-bench/test-text.c (96%) rename {clutter/tests => src/tests/clutter}/performance/create-report.rb (100%) rename {clutter/tests => src/tests/clutter}/performance/joblist (100%) rename {clutter/tests => src/tests/clutter}/performance/makejobs.rb (100%) create mode 100644 src/tests/clutter/performance/meson.build rename {clutter/tests => src/tests/clutter}/performance/test-common.h (77%) rename {clutter/tests => src/tests/clutter}/performance/test-picking.c (100%) rename {clutter/tests => src/tests/clutter}/performance/test-state-hidden.c (99%) rename {clutter/tests => src/tests/clutter}/performance/test-state-interactive.c (98%) rename {clutter/tests => src/tests/clutter}/performance/test-state-mini.c (97%) rename {clutter/tests => src/tests/clutter}/performance/test-state-pick.c (97%) rename {clutter/tests => src/tests/clutter}/performance/test-state.c (97%) rename {clutter/tests => src/tests/clutter}/performance/test-text-perf.c (99%) create mode 100644 src/tests/clutter/test-utils.h create mode 100644 src/tests/headless-start-test.c create mode 100644 src/tests/meson.build create mode 100644 src/tests/meta-backend-test.c create mode 100644 src/tests/meta-backend-test.h create mode 100644 src/tests/meta-gpu-test.c create mode 100644 src/tests/meta-gpu-test.h create mode 100644 src/tests/meta-monitor-manager-test.c create mode 100644 src/tests/meta-monitor-manager-test.h create mode 100644 src/tests/migration/basic-new.xml create mode 100644 src/tests/migration/basic-old.xml create mode 100644 src/tests/migration/first-rotated-new.xml create mode 100644 src/tests/migration/first-rotated-old.xml create mode 100644 src/tests/migration/oneoff-new-finished.xml create mode 100644 src/tests/migration/oneoff-new.xml create mode 100644 src/tests/migration/oneoff-old.xml create mode 100644 src/tests/migration/rotated-new-finished.xml create mode 100644 src/tests/migration/rotated-new.xml create mode 100644 src/tests/migration/rotated-old.xml create mode 100644 src/tests/migration/tiled-new.xml create mode 100644 src/tests/migration/tiled-old.xml create mode 100644 src/tests/migration/wiggle-new-discarded.xml create mode 100644 src/tests/migration/wiggle-new-finished.xml create mode 100644 src/tests/migration/wiggle-new.xml create mode 100644 src/tests/migration/wiggle-old.xml create mode 100644 src/tests/monitor-config-migration-unit-tests.c create mode 100644 src/tests/monitor-config-migration-unit-tests.h create mode 100644 src/tests/monitor-configs/first-rotated.xml create mode 100644 src/tests/monitor-configs/fractional-scale.xml create mode 100644 src/tests/monitor-configs/high-precision-fractional-scale.xml create mode 100644 src/tests/monitor-configs/interlaced.xml create mode 100644 src/tests/monitor-configs/lid-scale.xml create mode 100644 src/tests/monitor-configs/lid-switch.xml create mode 100644 src/tests/monitor-configs/mirrored.xml create mode 100644 src/tests/monitor-configs/non-preferred-tiled-custom-resolution.xml create mode 100644 src/tests/monitor-configs/oneoff.xml create mode 100644 src/tests/monitor-configs/primary.xml create mode 100644 src/tests/monitor-configs/scale.xml create mode 100644 src/tests/monitor-configs/second-rotated-tiled.xml create mode 100644 src/tests/monitor-configs/second-rotated.xml create mode 100644 src/tests/monitor-configs/single.xml create mode 100644 src/tests/monitor-configs/tiled-custom-resolution.xml create mode 100644 src/tests/monitor-configs/tiled.xml create mode 100644 src/tests/monitor-configs/underscanning.xml create mode 100644 src/tests/monitor-configs/vertical.xml create mode 100644 src/tests/monitor-store-unit-tests.c create mode 100644 src/tests/monitor-store-unit-tests.h create mode 100644 src/tests/monitor-test-utils.c create mode 100644 src/tests/monitor-test-utils.h create mode 100644 src/tests/monitor-transform-tests.c create mode 100644 src/tests/monitor-transform-tests.h create mode 100644 src/tests/monitor-unit-tests.c create mode 100644 src/tests/monitor-unit-tests.h create mode 100644 src/tests/mutter-all.test.in create mode 100644 src/tests/stacking/basic-wayland.metatest create mode 100644 src/tests/stacking/basic-x11.metatest create mode 100644 src/tests/stacking/client-side-decorated.metatest create mode 100644 src/tests/stacking/closed-transient-no-input-no-take-focus-parent.metatest create mode 100644 src/tests/stacking/closed-transient-no-input-no-take-focus-parents.metatest create mode 100644 src/tests/stacking/closed-transient-no-input-parent-delayed-focus-default-cancelled.metatest create mode 100644 src/tests/stacking/closed-transient-no-input-parent.metatest create mode 100644 src/tests/stacking/closed-transient-no-input-parents-queued-default-focus-destroyed.metatest create mode 100644 src/tests/stacking/closed-transient-no-input-parents.metatest create mode 100644 src/tests/stacking/closed-transient-only-take-focus-parents.metatest create mode 100644 src/tests/stacking/closed-transient.metatest create mode 100644 src/tests/stacking/minimized.metatest create mode 100644 src/tests/stacking/mixed-windows.metatest create mode 100644 src/tests/stacking/override-redirect.metatest create mode 100644 src/tests/stacking/set-override-redirect-parent.metatest create mode 100644 src/tests/stacking/set-parent-exported.metatest create mode 100644 src/tests/stacking/set-parent.metatest create mode 100644 src/tests/test-client.c create mode 100644 src/tests/test-runner.c create mode 100644 src/tests/test-utils.c create mode 100644 src/tests/test-utils.h create mode 100644 src/tests/unit-tests.c create mode 100644 src/tests/wayland-test-clients/meson.build create mode 100644 src/tests/wayland-test-clients/subsurface-remap-toplevel.c create mode 100644 src/tests/wayland-test-clients/test-driver.xml create mode 100644 src/tests/wayland-test-clients/wayland-test-client-utils.c create mode 100644 src/tests/wayland-test-clients/wayland-test-client-utils.h create mode 100644 src/tests/wayland-unit-tests.c create mode 100644 src/tests/wayland-unit-tests.h delete mode 100644 src/tools/Makefile.am delete mode 100644 src/tools/muffin-grayscale.c delete mode 100644 src/tools/muffin-mag.c delete mode 100644 src/tools/muffin-message.c delete mode 100644 src/tools/muffin-window-demo.c delete mode 100644 src/tools/muffin-window-demo.png delete mode 100644 src/ui/draw-workspace.c delete mode 100644 src/ui/draw-workspace.h delete mode 100644 src/ui/gradient.c delete mode 100644 src/ui/menu.c delete mode 100644 src/ui/menu.h delete mode 100644 src/ui/metaaccellabel.c delete mode 100644 src/ui/metaaccellabel.h delete mode 100644 src/ui/preview-widget.c delete mode 100644 src/ui/resizepopup.c delete mode 100644 src/ui/resizepopup.h delete mode 100644 src/ui/testgradient.c delete mode 100644 src/ui/theme-parser.c delete mode 100644 src/ui/theme-viewer.c create mode 100644 src/wayland/meta-cursor-sprite-wayland.c create mode 100644 src/wayland/meta-cursor-sprite-wayland.h create mode 100644 src/wayland/meta-pointer-confinement-wayland.c create mode 100644 src/wayland/meta-pointer-confinement-wayland.h create mode 100644 src/wayland/meta-pointer-lock-wayland.c create mode 100644 src/wayland/meta-pointer-lock-wayland.h create mode 100644 src/wayland/meta-selection-source-wayland-private.h create mode 100644 src/wayland/meta-selection-source-wayland.c create mode 100644 src/wayland/meta-wayland-actor-surface.c create mode 100644 src/wayland/meta-wayland-actor-surface.h create mode 100644 src/wayland/meta-wayland-buffer.c create mode 100644 src/wayland/meta-wayland-buffer.h create mode 100644 src/wayland/meta-wayland-cursor-surface.c create mode 100644 src/wayland/meta-wayland-cursor-surface.h create mode 100644 src/wayland/meta-wayland-data-device-primary-legacy.c create mode 100644 src/wayland/meta-wayland-data-device-primary-legacy.h create mode 100644 src/wayland/meta-wayland-data-device-primary.c create mode 100644 src/wayland/meta-wayland-data-device-primary.h create mode 100644 src/wayland/meta-wayland-data-device.c create mode 100644 src/wayland/meta-wayland-data-device.h create mode 100644 src/wayland/meta-wayland-data-offer-primary-legacy.c create mode 100644 src/wayland/meta-wayland-data-offer-primary-legacy.h create mode 100644 src/wayland/meta-wayland-data-offer-primary.c create mode 100644 src/wayland/meta-wayland-data-offer-primary.h create mode 100644 src/wayland/meta-wayland-data-offer.c create mode 100644 src/wayland/meta-wayland-data-offer.h create mode 100644 src/wayland/meta-wayland-data-source-primary-legacy.c create mode 100644 src/wayland/meta-wayland-data-source-primary-legacy.h create mode 100644 src/wayland/meta-wayland-data-source-primary.c create mode 100644 src/wayland/meta-wayland-data-source-primary.h create mode 100644 src/wayland/meta-wayland-data-source.c create mode 100644 src/wayland/meta-wayland-data-source.h create mode 100644 src/wayland/meta-wayland-dma-buf.c create mode 100644 src/wayland/meta-wayland-dma-buf.h create mode 100644 src/wayland/meta-wayland-dnd-surface.c create mode 100644 src/wayland/meta-wayland-dnd-surface.h create mode 100644 src/wayland/meta-wayland-egl-stream.c create mode 100644 src/wayland/meta-wayland-egl-stream.h create mode 100644 src/wayland/meta-wayland-gtk-shell.c create mode 100644 src/wayland/meta-wayland-gtk-shell.h create mode 100644 src/wayland/meta-wayland-inhibit-shortcuts-dialog.c create mode 100644 src/wayland/meta-wayland-inhibit-shortcuts-dialog.h create mode 100644 src/wayland/meta-wayland-inhibit-shortcuts.c create mode 100644 src/wayland/meta-wayland-inhibit-shortcuts.h create mode 100644 src/wayland/meta-wayland-input-device.c create mode 100644 src/wayland/meta-wayland-input-device.h create mode 100644 src/wayland/meta-wayland-keyboard.c create mode 100644 src/wayland/meta-wayland-keyboard.h create mode 100644 src/wayland/meta-wayland-legacy-xdg-shell.c create mode 100644 src/wayland/meta-wayland-legacy-xdg-shell.h create mode 100644 src/wayland/meta-wayland-outputs.c create mode 100644 src/wayland/meta-wayland-outputs.h create mode 100644 src/wayland/meta-wayland-pointer-constraints.c create mode 100644 src/wayland/meta-wayland-pointer-constraints.h create mode 100644 src/wayland/meta-wayland-pointer-gesture-pinch.c create mode 100644 src/wayland/meta-wayland-pointer-gesture-pinch.h create mode 100644 src/wayland/meta-wayland-pointer-gesture-swipe.c create mode 100644 src/wayland/meta-wayland-pointer-gesture-swipe.h create mode 100644 src/wayland/meta-wayland-pointer-gestures.c create mode 100644 src/wayland/meta-wayland-pointer-gestures.h create mode 100644 src/wayland/meta-wayland-pointer.c create mode 100644 src/wayland/meta-wayland-pointer.h create mode 100644 src/wayland/meta-wayland-popup.c create mode 100644 src/wayland/meta-wayland-popup.h create mode 100644 src/wayland/meta-wayland-private.h create mode 100644 src/wayland/meta-wayland-region.c create mode 100644 src/wayland/meta-wayland-region.h create mode 100644 src/wayland/meta-wayland-seat.c create mode 100644 src/wayland/meta-wayland-seat.h create mode 100644 src/wayland/meta-wayland-shell-surface.c create mode 100644 src/wayland/meta-wayland-shell-surface.h create mode 100644 src/wayland/meta-wayland-subsurface.c create mode 100644 src/wayland/meta-wayland-subsurface.h create mode 100644 src/wayland/meta-wayland-surface.c create mode 100644 src/wayland/meta-wayland-surface.h create mode 100644 src/wayland/meta-wayland-tablet-cursor-surface.c create mode 100644 src/wayland/meta-wayland-tablet-cursor-surface.h create mode 100644 src/wayland/meta-wayland-tablet-manager.c create mode 100644 src/wayland/meta-wayland-tablet-manager.h create mode 100644 src/wayland/meta-wayland-tablet-pad-group.c create mode 100644 src/wayland/meta-wayland-tablet-pad-group.h create mode 100644 src/wayland/meta-wayland-tablet-pad-ring.c create mode 100644 src/wayland/meta-wayland-tablet-pad-ring.h create mode 100644 src/wayland/meta-wayland-tablet-pad-strip.c create mode 100644 src/wayland/meta-wayland-tablet-pad-strip.h create mode 100644 src/wayland/meta-wayland-tablet-pad.c create mode 100644 src/wayland/meta-wayland-tablet-pad.h create mode 100644 src/wayland/meta-wayland-tablet-seat.c create mode 100644 src/wayland/meta-wayland-tablet-seat.h create mode 100644 src/wayland/meta-wayland-tablet-tool.c create mode 100644 src/wayland/meta-wayland-tablet-tool.h create mode 100644 src/wayland/meta-wayland-tablet.c create mode 100644 src/wayland/meta-wayland-tablet.h create mode 100644 src/wayland/meta-wayland-text-input-legacy.c create mode 100644 src/wayland/meta-wayland-text-input-legacy.h create mode 100644 src/wayland/meta-wayland-text-input.c create mode 100644 src/wayland/meta-wayland-text-input.h create mode 100644 src/wayland/meta-wayland-touch.c create mode 100644 src/wayland/meta-wayland-touch.h create mode 100644 src/wayland/meta-wayland-types.h create mode 100644 src/wayland/meta-wayland-versions.h create mode 100644 src/wayland/meta-wayland-viewporter.c create mode 100644 src/wayland/meta-wayland-viewporter.h create mode 100644 src/wayland/meta-wayland-window-configuration.c create mode 100644 src/wayland/meta-wayland-window-configuration.h create mode 100644 src/wayland/meta-wayland-wl-shell.c create mode 100644 src/wayland/meta-wayland-wl-shell.h create mode 100644 src/wayland/meta-wayland-xdg-foreign.c rename src/{core/eventqueue.h => wayland/meta-wayland-xdg-foreign.h} (51%) create mode 100644 src/wayland/meta-wayland-xdg-shell.c create mode 100644 src/wayland/meta-wayland-xdg-shell.h create mode 100644 src/wayland/meta-wayland.c create mode 100644 src/wayland/meta-wayland.h create mode 100644 src/wayland/meta-window-wayland.c create mode 100644 src/wayland/meta-window-wayland.h create mode 100644 src/wayland/meta-window-xwayland.c create mode 100644 src/wayland/meta-window-xwayland.h create mode 100644 src/wayland/meta-xwayland-dnd-private.h create mode 100644 src/wayland/meta-xwayland-dnd.c create mode 100644 src/wayland/meta-xwayland-grab-keyboard.c create mode 100644 src/wayland/meta-xwayland-grab-keyboard.h create mode 100644 src/wayland/meta-xwayland-private.h create mode 100644 src/wayland/meta-xwayland-surface.c create mode 100644 src/wayland/meta-xwayland-surface.h create mode 100644 src/wayland/meta-xwayland.c create mode 100644 src/wayland/meta-xwayland.h create mode 100644 src/wayland/protocol/gtk-primary-selection.xml create mode 100644 src/wayland/protocol/gtk-shell.xml create mode 100644 src/wayland/protocol/gtk-text-input.xml delete mode 100644 src/wm-tester/Makefile.am delete mode 100644 src/wm-tester/focus-window.c delete mode 100644 src/wm-tester/main.c delete mode 100644 src/wm-tester/test-attached.c delete mode 100644 src/wm-tester/test-gravity.c delete mode 100644 src/wm-tester/test-resizing.c delete mode 100644 src/wm-tester/test-size-hints.c rename src/{meta => x11}/atomnames.h (88%) create mode 100644 src/x11/events.c create mode 100644 src/x11/events.h rename src/{core => x11}/group-private.h (77%) rename src/{core => x11}/group-props.c (56%) rename src/{core => x11}/group-props.h (76%) rename src/{core => x11}/group.c (64%) create mode 100644 src/x11/iconcache.c rename src/{core => x11}/iconcache.h (60%) create mode 100644 src/x11/meta-selection-source-x11-private.h create mode 100644 src/x11/meta-selection-source-x11.c create mode 100644 src/x11/meta-startup-notification-x11.c create mode 100644 src/x11/meta-startup-notification-x11.h create mode 100644 src/x11/meta-x11-display-private.h create mode 100644 src/x11/meta-x11-display.c rename src/{core/errors.c => x11/meta-x11-errors.c} (67%) create mode 100644 src/x11/meta-x11-selection-input-stream-private.h create mode 100644 src/x11/meta-x11-selection-input-stream.c create mode 100644 src/x11/meta-x11-selection-output-stream-private.h create mode 100644 src/x11/meta-x11-selection-output-stream.c create mode 100644 src/x11/meta-x11-selection-private.h create mode 100644 src/x11/meta-x11-selection.c create mode 100644 src/x11/meta-x11-stack-private.h create mode 100644 src/x11/meta-x11-stack.c create mode 100644 src/x11/meta-x11-window-control.c create mode 100644 src/x11/meta-x11-window-control.h rename src/{core/muffin-Xatomtype.h => x11/mutter-Xatomtype.h} (94%) rename src/{core => x11}/session.c (90%) rename src/{core => x11}/session.h (90%) rename src/{core => x11}/window-props.c (62%) create mode 100644 src/x11/window-props.h create mode 100644 src/x11/window-x11-private.h create mode 100644 src/x11/window-x11.c create mode 100644 src/x11/window-x11.h rename src/{core => x11}/xprops.c (59%) create mode 100644 src/x11/xprops.h create mode 100644 tools/announce-wrangler.py create mode 100644 tools/commit-wrangler.py create mode 100644 tools/patch-wrangler.py create mode 100644 tools/release-wrangler.py diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 2a5e363ec..000000000 --- a/.gitignore +++ /dev/null @@ -1,213 +0,0 @@ -INSTALL -Makefile -Makefile.in -aclocal.m4 -autom4te.cache/ -compile -config.guess -config.h -config.h.in -config.log -config.status -config.sub -configure -data/Makefile -data/Makefile.in -depcomp -doc/Makefile -doc/Makefile.in -doc/man/Makefile -doc/man/Makefile.in -doc/reference/*.txt -doc/reference/*.stamp -doc/reference/.libs/ -doc/reference/Makefile -doc/reference/Makefile.in -doc/reference/muffin/Makefile -doc/reference/muffin/Makefile.in -doc/reference/muffin/html/ -doc/reference/muffin/muffin-docs.sgml -doc/reference/muffin/muffin.args -doc/reference/muffin/muffin.hierarchy -doc/reference/muffin/muffin.interfaces -doc/reference/muffin/muffin.prerequisites -doc/reference/muffin/muffin.signals -doc/reference/muffin/muffin.types -doc/reference/muffin/xml/ -doc/reference/clutter/clutter-*.txt -!/doc/reference/clutter/clutter-sections.txt -doc/reference/clutter/html -doc/reference/clutter/tmpl -doc/reference/clutter/xml -doc/reference/clutter/clutter.args -doc/reference/clutter/clutter.hierarchy -doc/reference/clutter/clutter.interfaces -doc/reference/clutter/clutter.prerequisites -doc/reference/clutter/clutter.signals -doc/reference/clutter/clutter-docs.xml -doc/reference/clutter/*.stamp -doc/reference/clutter/*.bak -doc/reference/clutter/*.log -doc/reference/clutter/gtkdoc-check.* -/doc/reference/cogl/cogl-*.txt -!/doc/reference/cogl/cogl-sections.txt -/doc/reference/cogl/html -/doc/reference/cogl/tmpl -/doc/reference/cogl/xml -/doc/reference/cogl/cogl.args -/doc/reference/cogl/cogl.hierarchy -/doc/reference/cogl/cogl.interfaces -/doc/reference/cogl/cogl.prerequisites -/doc/reference/cogl/cogl.signals -/doc/reference/cogl/cogl-docs.xml -/doc/reference/cogl/*.stamp -/doc/reference/cogl/*.bak -gnome-doc-utils.make -gtk-doc.make -install-sh -intltool-extract.in -intltool-merge.in -libtool -ltmain.sh -m4/ -missing -omf.make -po/.intltool-merge-cache -po/Makefile -po/Makefile.in -po/POTFILES -po/stamp-it -po/*.gmo -src/.deps/ -src/.libs/ -src/Makefile -src/Makefile.in -src/Meta-Muffin.0.gir -src/Meta-Muffin.0.typelib -src/*/*.lo -src/*/*.o -src/compositor/.deps/ -src/compositor/.dirstamp -src/compositor/.libs/ -src/compositor/plugins/.deps/ -src/compositor/plugins/.libs/ -src/compositor/plugins/Makefile -src/compositor/plugins/Makefile.in -src/compositor/plugins/default.la -src/compositor/plugins/default_la-default.lo -src/compositor/plugins/default_la-default.o -src/core/.deps/ -src/core/.dirstamp -src/core/.libs/ -src/inlinepixbufs.h -src/libmuffin.la -src/libmuffin.pc -src/muffin -src/muffin-enum-types.c -src/muffin-enum-types.h -src/muffin-enum-types.lo -src/muffin-enum-types.o -src/muffin-plugins.pc -src/muffin-restart-helper -src/muffin-theme-viewer -src/muffin.desktop -src/org.cinnamon.muffin.gschema.valid -src/org.cinnamon.muffin.gschema.xml -src/stamp-muffin-enum-types.h -src/testasyncgetprop -src/testboxes -src/testgradient -src/tools/.deps/ -src/tools/Makefile -src/tools/Makefile.in -src/tools/muffin-grayscale -src/tools/muffin-mag -src/tools/muffin-message -src/tools/muffin-window-demo -src/ui/.deps/ -src/ui/.dirstamp -src/ui/.libs/ -src/wm-tester/.deps/ -src/wm-tester/Makefile -src/wm-tester/Makefile.in -src/wm-tester/focus-window -src/wm-tester/test-attached -src/wm-tester/test-gravity -src/wm-tester/test-resizing -src/wm-tester/test-size-hints -src/wm-tester/wm-tester -stamp-h1 -xmldocs.make -/.vscode/ -/clutter/tests/interactive/stamp* -/clutter/tests/interactive/test-actors -/clutter/tests/interactive/test-animation -/clutter/tests/interactive/test-animator -/clutter/tests/interactive/test-bind-constraint -/clutter/tests/interactive/test-binding-pool -/clutter/tests/interactive/test-cairo-clock -/clutter/tests/interactive/test-cairo-flowers -/clutter/tests/interactive/test-cogl-multitexture -/clutter/tests/interactive/test-cogl-offscreen -/clutter/tests/interactive/test-cogl-point-sprites -/clutter/tests/interactive/test-cogl-shader-arbfp -/clutter/tests/interactive/test-cogl-shader-glsl -/clutter/tests/interactive/test-cogl-tex-convert -/clutter/tests/interactive/test-cogl-tex-foreign -/clutter/tests/interactive/test-cogl-tex-polygon -/clutter/tests/interactive/test-cogl-tex-tile -/clutter/tests/interactive/test-cogl-vertex-buffer -/clutter/tests/interactive/test-content -/clutter/tests/interactive/test-devices -/clutter/tests/interactive/test-easing -/clutter/tests/interactive/test-events -/clutter/tests/interactive/test-fbo -/clutter/tests/interactive/test-grab -/clutter/tests/interactive/test-image -/clutter/tests/interactive/test-interactive -/clutter/tests/interactive/test-keyframe-transition -/clutter/tests/interactive/test-layout -/clutter/tests/interactive/test-multistage -/clutter/tests/interactive/test-paint-wrapper -/clutter/tests/interactive/test-path-constraint -/clutter/tests/interactive/test-pixmap -/clutter/tests/interactive/test-rotate-zoom -/clutter/tests/interactive/test-scale -/clutter/tests/interactive/test-script -/clutter/tests/interactive/test-scrolling -/clutter/tests/interactive/test-shader-effects -/clutter/tests/interactive/test-stage-read-pixels -/clutter/tests/interactive/test-stage-sizing -/clutter/tests/interactive/test-state -/clutter/tests/interactive/test-state-animator -/clutter/tests/interactive/test-state-script -/clutter/tests/interactive/test-swipe-action -/clutter/tests/interactive/test-table-layout -/clutter/tests/interactive/test-text -/clutter/tests/interactive/test-text-field -/clutter/tests/interactive/test-texture-async -/clutter/tests/interactive/test-texture-material -/clutter/tests/interactive/test-texture-quality -/clutter/tests/interactive/test-texture-slicing -/clutter/tests/interactive/test-touch-events -/clutter/tests/interactive/test-unit-names.h -/cogl/stamp-h2 -/debian/*.log -/debian/*.debhelper -/debian/*.substvars -/debian/.debhelper/ -/debian/libmuffin0/ -/debian/muffin-common/ -/debian/muffin-dbg/ -/debian/muffin-doc/ -/debian/muffin/ -/debian/tmp/ -/debian/autoreconf.after -/debian/autoreconf.before -/debian/debhelper-build-stamp -/debian/files -/debian/gir1.2-meta-muffin-0.0/ -/doc/reference/muffin/.libs/ -/doc/reference/muffin/*.stamp -/doc/reference/muffin/muffin-*.txt -/po/muffin.pot diff --git a/AUTHORS b/AUTHORS deleted file mode 100644 index 9971ab08a..000000000 --- a/AUTHORS +++ /dev/null @@ -1 +0,0 @@ -Havoc Pennington diff --git a/COPYING b/COPYING index dec4bd0b5..d159169d1 100644 --- a/COPYING +++ b/COPYING @@ -1,12 +1,12 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. - Preamble + Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public @@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to +the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not @@ -55,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. - - GNU GENERAL PUBLIC LICENSE + + GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains @@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions: License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) - + These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in @@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. - + 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is @@ -225,7 +225,7 @@ impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. - + 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License @@ -255,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. - NO WARRANTY + NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN @@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it @@ -303,17 +303,16 @@ the "copyright" line and a pointer to where the full notice is found. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: - Gnomovision version 69, Copyright (C) year name of author + Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. @@ -336,5 +335,5 @@ necessary. Here is a sample; alter the names: This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General +library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. diff --git a/ChangeLog b/ChangeLog deleted file mode 100644 index 7123e9cfc..000000000 --- a/ChangeLog +++ /dev/null @@ -1,15414 +0,0 @@ -2009-03-16 Thomas Thurman - - * NEWS: 2.26.0 release. - -2009-02-04 Neil Jagdish Patel - - * src/core/frame.c: queue resize on window undecorate - -2009-02-03 Luca Ferretti - - * src/include/all-keybindings.h: Fix description, focus the - desktop, not desktop backgroung (Closes bug #569649) - -2009-02-02 Matt Kraai - - * src/core/schema-bindings.c: Wrap g_error calls in braces. - -2009-02-01 Thomas Thurman - - * configure.in: Post-release bump to 2.25.233. - -2009-02-01 Thomas Thurman - - * NEWS: 2.25.144 release. - -2009-02-01 Matt Kraai - - Set prop_hooks_table to NULL after freeing it. - - * src/core/window-props.c: - -2009-01-29 Thomas Thurman - - Window properties are looked up in a hash table rather than - by iteration over an array. Saves ~44us per window, but - also makes the code cleaner. - - * src/core/display-private.h: - * src/core/window-props.c: - -2009-01-27 Matthias Claesen - - * src/core/edge-resistance.c: some lists failed to keep track - of their contents and therefore didn't free correctly. - Closes #552303. - -2009-01-27 Matthias Claesen - - * src/core/prefs.c: Free name of old theme when new theme - is loaded. Closes #552973. - -2009-01-27 Matthias Claesen - - * src/ui/ui.c: free the result of gdk_text_property_to_utf8_list() - even when it returns no data. - -2009-01-27 Owen Taylor - - GtkStyle is specific to a particular colormap. Metacity - uses different colormaps for windows with different - visuals, so it must specialize the GtkStyle. - - Closes #568365 and #513944. - - * src/ui/frames.[ch]: Keep a GtkStyle for each MetaUIFrame, which is - obtained by calling gtk_style_attach() on the style for the - MetaFrames. When the style of the MetaFrames changes, reattach - everything. When we call gtk_style_set_background() pass in the - right style. - - * src/ui/themes.[ch]: Create a _with_style() variant of functions that - previously took the style from widget->style passed in, so we - can draw with the right style for the colormap. - -2009-01-27 Thomas Thurman - - Added a gconf key to swap the meanings of the right and - middle buttons when the modifier key is held down. - Closes #437910. Thanks to Matt Kraai for looking over - the patch. - - * src/core/display.c: - * src/core/prefs.c: - * src/include/prefs.h: - * src/metacity.schemas.in.in: - -2009-01-27 Thomas Thurman - - All the window properties are now handled using simple - window property handlers. Closes #549886. - - * src/core/window-private.h: - * src/core/window-props.c: - * src/core/window.c: - -2009-01-26 Thomas Thurman - - More of the window properties are checked using simple - window property handlers. The ones which remain don't - actually look up the new value in the ordinary way, and - so are a little trickier to merge. Added an "initial" - flag to be on the safe side that the behaviour is the - same as before (so we don't do things when a window's - first mapped that we only used to do when a property - changed). Partial fix for bug #549886. - - * src/core/window-props.c: - * src/core/window-props.h: - * src/core/window.c: - -2009-01-25 Elijah Newren - - * src/core/window.c: add support for _NET_WM_MOVERESIZE_CANCEL. - -2009-01-10 Thomas Thurman - - * src/ui/theme.[ch]: add meta_theme_draw_frame_by_name, which - is needed for the theme editor. - -2008-12-26 Thomas Thurman - - * configure.in: Post-release bump to 2.25.144. - -2008-12-26 Thomas Thurman - - * NEWS: 2.25.89 release. - -2008-12-25 Thomas Thurman - - * src/include/all-keybindings.h: alt-F10 toggles maximisation, - alt-F5 only restores. Also rename "unmaximize" to "restore". - * src/ui/frames.c: Rename "unmaximize" to "restore". - Closes #343824. - -2008-12-25 Frederic Peters - - * src/core/main.c: (main): added call to g_thread_init(), as ORBit2 - stopped doing it and Metacity is using gconf; closes #565517. - -2008-12-24 Yanko Kaneti - - * src/metacity.schemas.in.in: add screenshot commands which had - mistakenly been removed; closes #564343, Launchpad bug 298463, - Red Hat bug 474635, and probably others. - -2008-12-24 Thomas Thurman - - * src/include/all-keybindings.h: fix move_to_corner_se - -2008-12-21 Colin Walters - - * src/core/window.c: windows which attempt to present themselves - but are offscreen end up demanding attention, unless they - are transient, when they move to the current workspace - as before. Closes #482354. - -2008-12-19 Thomas Thurman - - * src/ui/frames.c: when the user double-clicks the title bar, - end the grab op. Closes #401028. - -2008-12-16 Thomas Thurman - - * configure.in: Post-release bump to 2.25.89. - -2008-12-16 Thomas Thurman - - * NEWS: 2.25.55 release. - -2008-12-15 Erwann Chenede - - * configure.in: fix build on Solaris. Closes #564123. - -2008-12-02 Thomas Thurman - - * configure.in: Post-release bump to 2.25.55. - -2008-12-02 Thomas Thurman - - * NEWS: 2.25.34 release. - -2008-12-02 Matt Kraai - - * src/core/iconcache.c: patches to fixes for -Wall. Closes #562939. - -2008-12-01 Thomas Thurman - - * configure.in: Post-release bump to 2.25.34. - -2008-12-01 Thomas Thurman - - * NEWS: 2.25.21 release. - -2008-12-01 Thomas Thurman - - * configure.in: gnome-doc-tools version doesn't need to be so high. - * src/compositor/compositor-xrender.c: disable the entire file if the - compositor is disabled. - * src/core/async-getprop.[ch]: fixes for -Wall - * src/core/iconcache.c: fixes for -Wall - * src/core/testasyncgetprop.c: fixes for -Wall - * src/core/xprops.c: fixes for -Wall - -2008-11-26 Thomas Thurman - - * tools/announce-wrangler.py: linked language codes to po files - * tools/commit-wrangler.py: print revision url - -2008-11-26 Thomas Thurman - - * tools/announce-wrangler.py: renamed ini file - * tools/commit-wrangler.py: rewriting in terms of moap - -2008-11-25 Thomas Thurman - - * configure.in: Post-release bump to 2.25.21. - -2008-11-25 Thomas Thurman - - * NEWS: 2.25.13 release. - -2008-11-26 Thomas Thurman - - * tools/announce-wrangler.py (added): script to produce announcements - -2008-11-26 Thomas Thurman - - * src/core/xprops.c: add casts (#562106) - -2008-11-25 Thomas Thurman - - * metacity.doap: change to standard description. - -2008-11-23 Thomas Thurman - - * configure.in: Post-release bump to 2.25.13. - -2008-11-23 Thomas Thurman - - * NEWS: 2.25.8 release. - -2008-11-23 Thomas Thurman - - * po/POTFILES.in: add new bindings file - -2008-11-23 Daniel Macks - - reviewed by: Thomas Thurman - - * src/Makefile.am: reorder compiler flags so local includes come last. - Closes #562033. - -2008-11-23 Daniel Macks - - reviewed by: Thomas Thurman - - * configure.in: only accept --enable-compositor if we find we can - actually composite. Closes #560990. - -2008-11-23 Thomas Thurman - - * src/core/display.c: remove apparently spurious warnings about - operations on window "none" - -2008-11-23 Thomas Thurman - - * src/core/util.c: Set _POSIX_C_SOURCE to 200112L as it should always - have been, in an attempt to close #561962. - -2008-11-22 Thomas Thurman - - * configure.in: Set -ansi so people stop complaining about C99. - -2008-11-22 Thomas Thurman - - * src/core/prefs.c: fix stupid infinite loop when GConf is turned off. - -2008-11-22 Thomas Thurman - - * src/core/prefs.c: fix two places where there was a warning - if GConf was turned off. - -2008-11-22 Thomas Thurman - - * src/core/all-keybindings.h: "backward", not "backwards" throughout. - -2008-11-20 Thomas Thurman - - * configure.in: turned on -Wall and -Werror in order to - trap as many problems as possible. - * src/ui/resizepopup.c: added correct #include. - * src/ui/theme-viewer.c: initialised variable. - * src/core/xprops.c: corrected cast. - * src/core/main.c: added warning if chdir() fails. - * src/core/schema-bindings.c: checking the return - result of fgets(). - -2008-11-20 Thomas Thurman - - Merged screen and window keybinding tables so that - we can use just one file for the both. Also incidentally - closes #528337. Further efficiencies of scale to come. - - * src/include/prefs.h: replace META_PREF_*_KEYBINDINGS - with META_PREF_KEYBINDINGS - * src/core/keybindings.c: replace *_bindings with key_bindings - and similar throughout; all window-based functions are now - guaranteed to receive a window so don't need to check for - themselves - (find_handler): moved so it can also be called from - rebuild_binding_table - * src/core/display-private.h: replace *_bindings with key_bindings - * src/core/prefs.c: update_*_binding becomes update_key_binding; - (change_notify): tidy up references to "enormous if statement" - since it's almost entirely gone now - * src/core/all-keybindings.h: new merged version of - screen-bindings.h and window-bindings.h. - -2008-11-16 David Trowbridge - - This change adds support for the new _NET_WM_FULLSCREEN_MONITORS - property and client message. This allows client applications to request - that a fullscreen window cover more than one monitor. - - * src/include/boxes.h: - * src/core/boxes.c: Add meta_rectangle_union - - * src/core/window-private.h: - * src/core/window.c: - (meta_window_new_with_attrs, meta_window_free, set_net_wm_state, - meta_window_update_fullscreen_monitors, meta_window_client_message): Add - MetaWindow property to store fullscreen monitors field, update - _NET_WM_FULLSCREEN_MONITORS property on windows, and handle client - message. - - * src/core/atomnames.h: Add _NET_WM_FULLSCREEN_MONITORS atom. - - * src/core/constraints.c (setup_constraint_info): If - _NET_WM_FULLSCREEN_MONITORS is interesting, use the data stored in - MetaWindow::fullscreen_monitors to determine the fullscreen area instead - of the basic xinerama_info area. - -2008-11-11 Thomas Thurman - - Removed deprecated calls. Closes #560445. - - * src/core/delete.c: remove deprecated g_strcasecmp. - * src/include/main.h: no actual deprecated call, but - a mention of one which was out of date. - -2008-11-11 Maxim Ermilov - - Clean up #includes according to the GNOME Goal. - Closes #560449. Patch is 122467. - - * src/core/place.c: - * src/ui/draw-workspace.h: - * src/ui/gradient.h: - * src/ui/metaaccellabel.c: - * src/ui/metaaccellabel.h: - * src/ui/preview-widget.c: - * src/ui/preview-widget.h: - * src/ui/resizepopup.c: - * src/ui/theme.c: - * src/ui/theme.h: - * src/ui/themewidget.h: - -2008-11-10 Elijah Newren - - * src/metacity.schemas.in.in: updated description of - raise_on_click: - http://bugzilla.gnome.org/show_bug.cgi?id=445447#c6 - -2008-11-08 Thomas Thurman - - * configure.in: added dependency on Zenity - * src/core/keybindings.c: remove error_on_generic_command() and - error_on_terminal_command(); rewrite error_on_command - in terms of meta_show_dialog() - * src/core/util.c: add meta_show_dialog() to call Zenity - * src/include/util.h: ditto - -2008-11-03 Olav Vitters - - * src/ui/theme-parser.c: Fix build by readding accidentally removed - '}'. - -2008-10-29 Thomas Thurman - - * src/ui/theme-parser.c: variable names in messages should be - double-quoted. Closes #558309. - -2008-10-28 Thomas Thurman - - * src/include/screen-bindings.h: fix accidental name change of - run_command_terminal. Closes #557943. - -2008-10-27 Thomas Thurman - - * src/core/prefs.c (titlebar_handler, handle_preference_update_enum): - Add initialisation which I missed on the previous checkin. Also - an extra comment. - -2008-10-27 Brian Cameron - - Fix some crashes with the new GDM 2.24. Closes #558058. - - * src/ui/ui.c (meta_ui_parse_modifier): another null check - * src/core/prefs.c (titlebar_handler, button_layout_handler): - more null checks. - -2008-10-26 Thomas Thurman - - * src/core/prefs.c (mouse_button_mods_handler): Ignore values - of .../mouse_button_modifier key if the key's missing. - Closes Launchpad bug #258054, Launchpad bug #266929. - -2008-10-23 Frederic Peters - - * doc/creating_themes/C/creating-metacity-themes.xml: added missing @id - on top element. - -2008-10-23 Frederic Peters - - * doc/creating_themes/Makefile.am: - * doc/creating_themes/C/creating_metacity_themes.xml: renamed document - to creating-metacity-themes to match other manuals usage of dashes. - -2008-10-23 Thomas Thurman - - * configure.in: Post-release bump to 2.25.8. - -2008-10-23 Thomas Thurman - - * NEWS: 2.25.5 release. - -2008-10-23 Thomas Thurman - - * src/core/schema-bindings.c: fix stupid thinko which - caused defaults to be incorrect - * src/include/window-bindings.h: "space" needs to be - lowercase - -2008-10-23 Thomas Thurman - - Support _NET_WM_STATE_STICKY (i.e. allow third-party apps to decide - whether a window is on all workspaces). Bug found by Ka-Hing - Cheung. Closes #557536. - - * src/core/window.c (set_net_wm_state): report it - * src/core/window.c (meta_window_client_message): set sticky - if we receive it - * src/core/window-props.c: set sticky if we find it - * src/core/atomnames.h: add _NET_WM_STATE_STICKY - -2008-10-22 Thomas Thurman - - * src/core/schema-bindings.c: support builds outside tree properly. - * src/Makefile.am: ditto. - * po/POTFILES.skip: ditto. - -2008-10-22 Thomas Thurman - - * configure.in: Post-release bump to 2.25.5. - -2008-10-22 Thomas Thurman - - * NEWS: 2.25.3 release. - -2008-10-22 Thomas Thurman - - * configure.in: bump to 2.25.3 (thought the release script - had already done this) - -2008-10-22 Thomas Thurman - - Fixes to make distcheck work again. - - * src/Makefile.am: include *-binding.h, and make the schema - building work when builddir != srcdir - * po/POTFILES.in (src/core/keybindings.): include *-binding.h - -2008-10-22 Götz Waschk - - * configure.in: add libm reference. Closes #557357. - -2008-10-22 Murray Cumming - - * doc/creating_themes/C/creating_metacity_themes.xml: - Fixed various tags to make this validate. - Bug #557337 - -2008-10-22 Thomas Thurman - - * NEWS: 2.25.2 release. - -2008-10-22 Thomas Thurman - - * NEWS: 2.25.2 release. - -2008-10-22 Thomas Thurman - - * NEWS: 2.25.2 release. - -2008-10-22 Joe Marcus Clarke - - * src/core/main.c (meta_finalize, sigterm_handler): new functions - * src/core/main.c (main): add sigterm_handler in case we receive - a SIGTERM. Closes #553980. - -2008-10-22 Matthew Martin - - * src/core/window.c (meta_window_set_demands_attention): minimised - windows are necessarily obscured. Closes #528927. - -2008-10-22 Thomas Thurman - - Slight transformation of the x-macros used in keybindings - to make them clearer: write handler names out in full - because the old suffix system was confusing to people - skim-reading, and switched the order of the last two - parameters so more would generally fit on a screen. - - * src/core/keybindings.c, src/core/schema-bindings.c - src/core/prefs.c: sympathy changes - * src/core/window-bindings.h, src/core/screen-bindings.h: - transformation as above - -2008-10-21 Christian Persch - - * src/Makefile.am: fix build when schemas are not installed. - Closes #557335. - -2008-10-21 Tomas Frydrych - - * src/core/screen-bindings.h: Fix off-by-one error. - * src/core/window-bindings.h: Fix off-by-one error. - Closes #557201. - -2008-10-18 Thomas Thurman - - During a discussion with Rodney Dawes about making life easier - for the translators, he pointed out that the short and long - forms of almost all the keybindings say much the same thing - in different words. I believe this is an unconscionable burden - to place on translators, and have therefore merged the short - and long descriptions into the short description. The long - is now a general explanation of the format, plus possibly a - notice about reversibility. Closes #469361, and should solve - the l10n issue previously mentioned. - - * src/core/keybindings.c: reflect changes in *-bindings.h - * src/core/schema-bindings.c: reflect changes in *-bindings.h - * src/core/prefs.c: reflect changes in *-bindings.h - * src/core/window-bindings.h: Add flags field, always the same - currently, so that it's the same as screen-bindings.h. - Also, lose ONLY_BOUND_BY_DEFAULT, since we already had a - rather more elegant way to perform the same effect. - And merge the long and short descriptions. - * src/core/screen-bindings.h (, item): Merge the long and - short descriptions. - -2008-10-17 Murray Cumming - - * configure.in: Call GNOME_DOC_INIT() so we can use the gnome-doc-utils - variables in our Makefile.am: - * doc/Makefile.am: - * doc/creating_themes/Makefile.am - * doc/creating_themes/C/creating_metacity_themes.xml: - Added this new DocBook document, converted from the HTML here - http://blogs.gnome.org/metacity/2008/05/30/themes/ - This will be installed for yelp and can be translated and hosted on - library.gnome.org. - -2008-10-15 Thomas Thurman - - Since Patrick Niklaus's checkin of 2008-08-14 dealt with windows with - no icons not using fallback icons, we don't need fallback icons. - - * src/ui/theme.h: remove fallback icons from struct. - * src/core/iconcache.c (meta_read_icons): don't look for fallbacks. - * src/*/ui.[ch] (meta_ui_get_fallback_icons): removed - * src/ui/theme-parser.c (typedef, parse_toplevel_element): don't - parse fallback specifications. - -2008-10-13 Thomas Thurman - - * po/POTFILES.in: add screen-bindings.h - -2008-10-13 Thomas Thurman - - * po/POTFILES.in: raw schemas is now .in.in - * po/LINGUAS: add Latin - -2008-10-12 Thomas Thurman - - Make the bindings in src/core/*-bindings.h generate - GConf schemas too. Note that there's an i18n issue - (documented in schema-bindings.c) which will be fixed - next checkin. - - * src/core/schema-bindings.c: major fixup to make it - ready for use as part of the actual build process. - * src/Makefile.am: added magic to make it call schema-bindings - after it builds it. - * src/core/window-bindings.h: added comments; - also, window menu was listed variously as alt-Space - and alt-Print; it should have been alt-Space. - * src/metacity.schemas.in.in: renamed from s/\.in$//, - sentinel added for the generated bindings, - warning at the top now untrue, and removed. - -2008-10-12 Thomas Thurman - - Fix annoying bug where alt-tab and friends would jump - backwards a space on initial movement. - - * src/core/screen-bindings.h: although reversed bindings - are necessarily reversible, don't set both bits in the - constant, or when we test for them we'll get confused. - -2008-10-12 Thomas Thurman - - An attempt to make life a little easier for our beloved translators; - this has the same behaviour as before, but removes over thirty - translation strings. - - * src/core/session.c (start_element_handler): all "attribute not found - on element" strings are identical - * src/ui/theme-parser.c (locate_attributes): allow attribute names to - be preceded with "!" (in the code) to show they're required. - (parse_aspect_ratio, parse_distance, parse_toplevel_element, - parse_style_element, parse_gradient_element, static, parse_border, - parse_style_set_element, parse_draw_op_element): use the new "!" - prefix for locate_attributes(), or in some cases just the identical - constant, for generating this error. - * src/ui/theme.c (check_state, meta_theme_validate): add - translator comments - * src/ui/resizepopup.c (update_size_window): add - translator comments - -2008-10-06 William Lachance - - Pass modified mouse button events down to panel windows - instead of dealing with them ourselves. Closes #554428. - - * src/core/display.c (prefs_changed_callback): don't grab mouse - buttons on panels - * src/core/window.c (meta_window_new_with_attrs): ditto - -2008-10-05 Thomas Thurman - - Second half of the switch to using x-macros for keybindings so that - we don't have lots of places with the same information which must - stay in the same order. This time it's screen bindings. - - * src/core/screen-bindings.h: New file, containing screen bindings. - * src/core/schema-bindings.c: added ability to output screen bindings. - * src/core/window-bindings.h: tiny tweak to comment - * src/core/keybindings.c: generate function prototypes using s-b.h; - several handlers modified to use ints rather than ints cast into - pointers, or renamed. - * src/include/prefs.h: generate names of bindings using s-b.h; - generate screen_handlers using s-b.h; - arguments to bindings are ints and not ints cast to pointers; - several handler functions renamed to consistent names. - * src/core/prefs.c (meta_prefs_set_num_workspaces, init_bindings): - generate screen_handlers using s-b.h; - generate screen_string_bindings using s-b.h (and add check for - null bindings in init_bindings to enable this simply). - -2008-10-05 Thomas Thurman - - * tools/ppa-magic.py: experimental tool for Launchpad upload - -2008-10-05 Thomas Thurman - - * metacity.doap: Havoc is an author; Thomas has an email address; - add a ton of release information going back to the early days, - although not right to the beginning. - -2008-09-26 Thomas Thurman - - * autogen.sh: not all versions of /bin/sh can handle this script, - so specify one. Also update the error message because we don't - use CVS these days. - -2008-09-20 Thomas Thurman - - * po/POTFILES.in: fix name of window-bindings.h - -2008-09-20 Thomas Thurman - - * po/POTFILES.in: added new files and re-sorted - -2008-09-12 Vincent Untz - - Install desktop files in both - .../share/applications and .../share/gnome/wm-properties. - Copied in from the 2.23.x branch. Closes #549479. - - * src/metacity-wm.desktop.in: new file - * src/.cvsignore: include the above - * src/Makefile.am: install the above - -2008-09-06 Thomas Thurman - - An attempt to keep all information about window bindings - in the same place. Screen bindings to come. - - * src/core/window-bindings.h: new file, list of all window bindings - * src/include/prefs.h: drop all the existing window-binding macros - - * src/core/schema-bindings.c (): output all the schema blocks that - would appear in metacity.schema for these window bindings. This - ought to become part of the build process, and hopefully will soon. - When this works it will also close #469361. - - * src/core/keybindings.c: generate handle_* prototypes using - x-macros; populate window_handlers using x-macros; rename several - functions to have consistent names; do_handle_move_to_workspace(), - handle_move_to_workspace_flip(), and handle_move_to_workspace() all - merged into handle_move_to_workspace. - - * src/core/prefs.c: generate window_bindings and window_string_bindings - using x-macros; (meta_prefs_set_compositing_manager) fix unrelated - problem with use of GConf functions when GConf was disabled. - - * src/core/core.c (meta_core_get_menu_accelerator): binding names - given as literals since this is the only place in the code they - now appear - - -2008-09-03 Thomas Thurman - - * src/metacity.desktop.in: removed invalid "Window Manager" group - at request of Matthias Clasen. - -2008-09-02 Thomas Thurman - - Desktop file moved, according to policy change. Closes #549479. - - * src/metacity.desktop.in: Don't display the desktop file - * src/Makefile.am: Desktop file goes in apps directory - -2008-09-01 Thomas Thurman - - * configure.in: Post-release bump to 2.25.2. - -2008-09-01 Thomas Thurman - - * NEWS: 2.25.1 release. - -2008-09-01 Thomas Thurman - - * src/core/workspace.c: When a workspace's list of struts - is freed, free the struts too. Closes #549952, and #468075. - -2008-09-01 Thomas Thurman - - Add new move_to_center keybinding, requested by Khanh-Dang Nguyen - Thu Lam; closes #549979. - - * src/include/prefs.h (void): add name of new binding - * src/core/prefs.c: added pref for it - * src/core/keybindings.c (handle_move_to_center): new function - * src/metacity.schemas.in: included new binding - -2008-08-31 Thomas Thurman - - * src/core/prefs.[ch] (meta_prefs_set_compositing_manager): new - function. - * src/core/main.c (meta_parse_options): turn the compositing - manager on or off as necessary. - -2008-08-30 Thomas Thurman - - * src/core/window.c (process_property_notify): moving all - messages about properties to the top, as a start at #549886 - -2008-08-18 Thomas Thurman - - * NEWS: fix version number which broke - -2008-08-18 Thomas Thurman - - * configure.in: Post-release version bump to 2.25.1. - -2008-08-18 Thomas Thurman - - * configure.in: correct incorrect version number - -2008-08-18 Thomas Thurman - - * NEWS: 2.25.1 release. - -2008-08-18 Thomas Thurman - - Adding doxygen headers to some files. - - * src/core/metacity-Xatomtype.h - * src/core/main.c - * src/core/screen-private.h - * src/core/window-private.h - * src/core/keybindings.h - * src/core/session.h - * src/core/workspace.h - * src/core/window-props.h () - -2008-08-18 Eric Piel - - * src/core/workspace.c (ensure_work_areas_validated): add a copy of - each strut in a window to the workspace's strut list, instead of - using the copy in the list (which would mean it was double-freed). - Believed to fix #468075. - -2008-08-16 Ted Percival - - Ensure the user_rect is set sanely for windows that start maximized. - Prevents maximized windows from warping across the screen. - Fixes bug #504692. - - * src/core/window.c (save_user_placement): renamed version of - meta_window_save_user_rect(). - * src/core/window.c (force_save_user_placement): similar, but will - always save user_rect even if the window is maximised or fullscreen. - * src/core/window.c (meta_window_move_resize_internal): unplaced - windows have force_save_user_placement() called instead of - save_user_placement(). - -2008-08-14 Patrick Niklaus - - Icons for windows are taken from the desktop theme, not from - the Metacity theme or from the fallback icon that Metacity - provided. Closes #524343. - - * src/ui/ui.c: Use GtkIconTheme to load the default window icon. - Assumes the existence of an icon called "window", otherwise - falls back to "gtk-missing-image". Fixes #524343. - * src/ui/preview-widget: See above. - * src/include/common.h: Add META_DEFAULT_ICON_NAME. - * src/Makefile.am: Remove default_icon.png from inlinepixbufs.h. - * src/default_icon.png: Removed. - -2008-08-14 Akira TAGOH - - * doc/man/metacity-message.1: new manual page. - * doc/man/Makefile.am: added new reference. - -2008-08-13 Thomas Thurman - - * configure.in: Post-branch bump to 2.25.0. - -2008-08-04 Thomas Thurman - - * configure.in: Post-release bump to 2.23.144. - -2008-08-04 Thomas Thurman - - * NEWS: 2.23.89 release. - -2008-07-26 Thomas Thurman - - * metacity.doap (added): DOAP file (first pass, anyway). - -2008-07-14 Thomas Thurman - - * configure.in: Post-release bump to 2.23.89. - -2008-07-14 Thomas Thurman - - * NEWS: 2.23.55 release. - -2008-07-13 Thomas Thurman - - * src/core/display.c (event_callback): meta_display_screen_for_root() - can return NULL, so check for that. Fixes #422242. Also tidying. - -2008-07-13 Elijah Newren - - * src/core/workspace.c (meta_workspace_free): Don't attempt to - double-free struts, edges and regions if work areas have already - been invalidated at the time of freeing a workspace. - Possible fix to #361804. - -2008-07-12 Thomas Thurman - - * src/core/constraints.c (do_screen_and_xinerama_relative_constraints): - Don't allocate memory for log messages unless we're logging. - -2008-07-12 Thomas Thurman - - * src/core/group.c (meta_window_get_group): This function can now - officially return NULL. - * src/core/window.c (meta_window_same_application): Two windows can't - belong to the same application unless they both belong to some - application. (Both belonging to no application is not the same.) - -2008-06-30 Thomas Thurman - - * src/core/bell.c (meta_bell_set_audible): Fix typo that - slipped through. - -2008-06-30 Thomas Thurman - - * src/core/bell.[ch]: Move comments for non-statics from the .c to .h. - * Doxyfile: adapt better for C, and make quiet. - -2008-06-29 Thomas Thurman - - * src/ui/theme-viewer.c (main): display the theme name - in the title bar. Closes #430198. - -2008-06-29 Thomas Thurman - - Allow toggling of non-compositor effects (since there's a - non-Metacity key to do so: /desktop/gnome/interface/enable_animations). - Closes #92867. - - * src/include/prefs.h: add META_PREFS_GNOME_ANIMATIONS key and - meta_prefs_get_gnome_animations() function - * src/include/prefs.c: added meta_prefs_get_gnome_animations() - function, and made supporting changes to structs. - * src/core/effects.c (run_handler): checked whether enable_animations - is set before running an effect. - * src/core/effects.c (meta_effect_run_minimize): remove debug message. - -2008-06-29 Thomas Thurman - - * src/core/bell.c: remove meta_ prefix on all static functions. - -2008-06-29 Thomas Thurman - - * src/core/stack.c (stack_sync_to_server): lose meta prefix - since it's static. - * src/core/stack.c (meta_stack_remove, stack_do_window_deletions): - replace our own cast with glib macro designed to do the same thing - -2008-06-28 Thomas Thurman - - * src/core/display.c, src/compositor/compositor-xrender.c: add checks - for HAVE_SHAPE where appropriate. - * src/core/xprops.c: fix type error which was causing warnings. - -2008-06-28 Thomas Thurman - - Some refactoring, simplifying, and commenting of the non-composited - effects code. effects.c could still do with some polish, which will - come along later. - - * src/core/effects.h (meta_push_effect_handler): removed since it's - never used and does nothing very useful. - * src/core/effects.h (meta_pop_effect_handler): removed since its - only effect is to crash the program. - * src/core/effects.h (META_MINIMIZE_ANIMATION_LENGTH, - META_SHADE_ANIMATION_LENGTH): move to effects.c because they're used - nowhere else. - * src/core/effects.c: there were three versions of the box-zoom effect. - Remove the one which was never used, and make only the ones which - are used with certain configure settings be compiled. - * src/core/effects.h (meta_effect_end): move to effects.c, make static, - and rename to effect_free. - * src/core/effects.h (meta_effects_draw_box_animation): move to - effects.c, make static, and rename to draw_box_animation. - * src/core/effects.h (MetaEffectType): remove the values which weren't - used. - * src/core/window.c (meta_window_shade): remove commented-out code to - call effect for shading. - * src/core/effects.h (MetaEffectFinish): remove useless MetaEffect - parameter. - * src/core/window.c (finish_minimize): remove MetaEffect parameter. - -2008-06-27 Thomas Thurman - - * src/core/stack.h: Commented everything. - -2008-06-26 Thomas Thurman - - Keep the compiler from giving some warnings. - - * src/compositor/compositor-xrender.c (xrender_begin_move, - xrender_update_move, xrender_end_move, xrender_free_window): four - functions which were never called and contain no code #iffed out. - * src/tools/metacity-mag.c (grab_area_at_mouse): fixed typecast error. - -2008-06-26 Thomas Thurman - - Refactor so the long scary stack functions are less long and scary: - - * stack.c (stack_ensure_sorted): the five parts of this long function - broken out into the new functions stack_do_window_deletions, - stack_do_window_additions, stack_do_relayer, stack_do_constrain - (which was already separate: see next) and stack_do_resort. - * stack.c (constrain_stacking): renamed to stack_do_constrain. - * stack.c (stack_ignore_sorted): lose meta prefix since it's static. - -2008-06-16 Thomas Thurman - - * configure.in: Post-release bump to 2.23.55. - -2008-06-16 Thomas Thurman - - * NEWS: 2.23.34 release. - -2008-06-16 Thomas Thurman - - * NEWS: 2.23.34 release. - -2008-06-13 Thomas Thurman - - * src/core/window-props.c: Some commenting. - - * src/core/prefs.c: Added unified handling of integer preferences. - Re-ordered fields in existing preferences so that changing to - a union-based system will be easier in the future. - -2008-06-10 Thomas Thurman - - * test/tokentest/tokentest.c (draw_string_to_spec): doubles are - %f or %g, not %d - * test/tokentest/tokentest.ini: re-created fair copy accordingly - -2008-06-10 Thomas Thurman - - * test/tokentest: A preliminary attempt at a test for the - theme expression tokeniser. - -2008-06-05 Thomas Thurman - - * src/compositor/compositor-xrender.c (paint_root, destroy_win, - create_root_buffer, paint_windows, repair_screen, window_has_shadow, - xrender_set_active_window, paint_dock_shadows, unmap_win, restack_win, - make_shadow, resize_win, process_property_notify, free_win, - process_configure_notify, process_circulate_notify, add_damage): - defensive programming; check meta_screen_get_compositor_data() - throughout in case it returns NULL. In particular, when this - happened in a certain situation in xrender_set_active_window - this caused a segfault; refs #530702 (and LP#178953 has more data) - but this doesn't close them. - -2008-06-02 Thomas Thurman - - * NEWS: 2.23.34 release. - -2008-06-02 Thomas Thurman - - * src/core/display.c: make sure compositor things don't get - compiled when we're not using the compositor. - -2008-06-02 Thomas Thurman - - * test/metacity-test: new test script, imported from - branch. - -2008-05-30 Thomas Thurman - - * src/core/window-props.h: fix comments (number) - -2008-05-30 Thomas Thurman - - * src/core/window-props.h: commenting - -2008-05-28 Thomas Thurman - - * src/core/prefs.c (handle_preference_update_string, - meta_prefs_remove_listener, queue_changed): Make disabling - gconf work again. Closes #530870. - -2008-05-26 Thomas Thurman - - * configure.in: Post-release bump to 2.23.34. - -2008-05-26 Thomas Thurman - - * NEWS: 2.23.21 release. - -2008-05-26 Thomas Thurman - - * src/Makefile.am: added in two files needed for Iain's - changes earlier to work in a release tarball - -2008-05-24 Iain Holmes - - * src/compositor/compositor-xrender.c: Add Dropdown menu atoms so we - can add shadows to them. Fixes #517442 - Handle tooltips as well. Fixes #517524 - -2008-05-24 Iain Holmes - - * src/compositor/compositor.c: Check the compositor isn't NULL before - dereferencing it. Fixes #534569 - (meta_compositor_get_window_pixmap): Actually return a value - -2008-05-19 Iain Holmes - - * src/core/window.c: Applied patch from Ed Catmur to fix #528787 - -2008-05-19 Iain Holmes - - * src/include/frame.h - * src/include/display.h - * src/include/xprops.h - * src/include/compositor.h - * src/include/types.h - * src/include/window.h - * src/include/errors.h - * src/include/screen.h: New basic public API for compositor. - - * src/compositor/*: Separate the compositor out into its own separate - directory and set it up for backends. Initial XRender backend. - - * src/core/compositor.[ch]: Remove - - * src/core/frame.h - * src/core/screen.h - * src/core/display.h - * src/core/window.h: Rename to -private.h so as not to clash with the - new files in include - - * src/core/delete.c - * src/core/workspace.h - * src/core/stack.[ch] - * src/core/keybindings.[ch] - * src/core/errors.c - * src/core/effects.[ch] - * src/core/core.c - * src/core/group.h - * src/core/edge-resistance.[ch] - * src/core/window-props.[ch] - * src/core/constraints.h - * src/core/bell.[ch] - * src/core/iconcache.h - * src/core/session.[ch] - * src/core/main.c - * src/core/place.h - * src/core/xprops.c - * src/ui/tabpopup.c: Use the new -private headers - - * src/core/display.c - * src/core/frame.c - * src/core/window.c - * src/core/screen.c: Add the API functions required by the compositor - - * src/Makefile.am: Relocate the new files - -2008-05-13 Robert Escriva - - * src/ui/theme.h (struct): remove color_set flag - * src/ui/theme.c (meta_color_spec_render, - meta_color_spec_new_from_string): remove check of color_set flag - before rendering (we always do it now). Closes #511826. - -2008-05-12 Thomas Thurman - - * tools/xlib.py: Basic Python-based Xlib client for testing - and building upon. - -2008-05-09 Elijah Newren - - * src/ui/color.[ch]: - Remove these two unused files - -2008-05-04 Thomas Thurman - - Added curly brackets in two places to keep -pedantic happy. - - * src/core/window-props.c (meta_display_init_window_prop_hooks) - * src/core/group-props.c (meta_display_init_group_prop_hooks) - -2008-05-03 Matt Krai - - * src/core/delete.c (io_from_ping_dialog): fix type of "len" variable - (refs #526049) -2008-05-02 Thomas Thurman - - All information should live in exactly one place. This means - that the list of atoms should not be replicated anywhere. - Therefore, we include it via x-macros. Closes #530843. - - * src/core/atomnames.h: added list of atom names - * src/Makefile.am: added reference to new file - * src/core/display.h - * src/core/display.c (twice) - * src/core/screen.c: #included atomnames.h instead of having - an enormous list of atoms - * src/core/group-props.c - * src/core/window.c - * src/core/compositor.c - * src/core/window-props.c - * src/core/delete.c - * src/core/workspace.c - * src/core/stack.c - * src/core/keybindings.c - * src/core/iconcache.c - * src/core/group.c - * src/core/xprops.c: changed to new, simpler identifiers - for atoms - -2008-04-29 Chris Wang - - * src/core/window.c (meta_window_new): XGetWindowAttributes - can return an error value, and if it does its other results - are invalid! (#530485) - -2008-04-29 Thomas Thurman - - * src/ui/fixedtip.[ch]: documentation - -2008-04-27 Thomas Thurman - - * configure.in: Post-release bump to 2.23.21. - -2008-04-27 Thomas Thurman - - * NEWS: 2.23.13 release. - -2008-04-27 Erwann Chenede - - * src/core/place.c (meta_window_place): re-enable cascade - code which was wrongly removed a year ago. Closes #529925. - -2008-04-22 Carlos Garnacho - - * src/core/compositor.c (process_property_notify, - find_window_in_display): Propagate opacity to frame window. - -2008-04-22 Thomas Thurman - - * configure.in: Post-release bump to 2.23.13. - -2008-04-22 Thomas Thurman - - * NEWS: 2.23.8 release. - -2008-04-22 Thomas Thurman - - * configure.in: Post-release bump to 2.21.8. - (Which was seriously belated. Sorry, folks.) - -2008-04-22 Thomas Thurman - - * src/core/effects.c: a few comments - -2008-04-10 Lucas Rocha - - * src/Makefile.am: no need to create a symlink to .desktop file in - default-session directory anymore as gnome-session will find - metacity's .desktop in its original place. - -2008-04-07 iain - - * src/core/compositor.c (hide_overlay_window): Hide the overlay window - (meta_compositor_unmanage_screen): Release the compositor overlay. - (#526770) - -2008-04-07 Jens Granseuer - - * src/core/session.c: (save_state), - (warn_about_lame_clients_and_finish_interact): - reorder declarations so we don't break C89 compilers. - -2008-04-06 Thomas Thurman - - * NEWS: 2.23.5 release. - -2008-04-03 Thomas Thurman - - * src/core/prefs.c (handle_preference_update_bool): preferences - which have a null target don't get updated! (#526016) - -2008-03-29 Lucas Rocha - - * src/metacity.desktop.in, src/Makefile.am: make Metacity - install its desktop files in the default session directory - as required by the new gnome-session. (Closes #525051.) - -2008-03-29 Thomas Thurman - - * src/ui/preview-widget.c (meta_preview_get_clip_region): - prevent null dereference if the theme was invalid, which - caused crashes in gnome-appearance-properties. No GNOME - bug number, but I believe this is a fix for Launchpad bug - #199402 and its many duplicates. - -2008-03-28 Owen Taylor - - * src/core/window.c (meta_window_new_with_attrs): Don't - immediately unminimize an initially iconic window (#491090) - -2008-03-27 Thomas Thurman - - * src/core/session.c (regenerate_save_file, save_state, load_state): - files are saved in ~/.config/metacity/sessions and checked for there - and in ~/.metacity/sessions. Fixes #518596. - -2008-03-27 Thomas Thurman - - * src/core/display.c (meta_display_close): fix regression - where Metacity sometimes wouldn't quit when replaced - -2008-03-26 Thomas Thurman - - * src/core/display.c (event_callback): meta_display_screen_for_root - is quite capable of returning NULL. - -2008-03-25 Thomas Thurman - - * src/core/display.c (meta_display_queue_retheme_all_windows, - meta_set_syncing, meta_display_set_cursor_theme, disable_compositor, - meta_display_for_x_display, meta_display_open, meta_display_close, - meta_display_ungrab): MetaDisplay becomes a singleton. The static - variable which holds this singleton is renamed "the_display" so as - not to mask the this parameter in the methods. - - * src/core/main.c (main): - * src/core/session.c (warn_about_lame_clients_and_finish_inte, - save_state, io_from_warning_dialog): - * src/core/core.c (meta_core_increment_event_serial): - * src/core/delete.c (release_window_with_fd, search_and_destroy_window): - sympathy changes for this, and consequent simplification. - Closes #499301. - -2008-03-21 Thomas Thurman - - * configure.in: Post-release bump to 2.23.5. - -2008-03-21 Thomas Thurman - - * NEWS: 2.23.3 release. - -2008-03-21 Thomas Thurman - - * src/ui/menu.c (activate_cb, get_workspace_name_with_accel): Workspaces - whose name is the standard name plus a non-empty string are handled - correctly in menus. Closes #453678. - -2008-03-19 Iain Holmes - - * src/core/compositor.c (meta_compositor_set_active_window): Handle - compositor being disabled and don't crash. - -2008-03-19 Iain Holmes - - * src/core/compositor.c (meta_compositor_set_active_window): Add a - screen argument. - (process_property_notify): Damage the whole screen when the background - changes. Fixes 522599 - (add_repair): Use the idle instead of the timeout. Fixes 522166 - (unmap_win): If the window is also focus window NULLify it. - - * src/core/window.c (meta_window_notify_focus): Notify when a window - has lost focus, pass in screen as well. - -2008-03-18 Iain Holmes - - * src/core/compositor.c (window_has_shadow): Allow shaped windows - _with frames_ to have shadows. - (meta_compositor_set_active_window): Watch for the focus of windows - and change the size of the drop shadows. - (generate_shadows): Create differently sized shadows. - (meta_compositor_get_window_pixmap): Get the xwindow correctly. - - * src/core/window.c (meta_window_notify_focus): Set the active window - in the compositor. - -2008-03-18 Marco Pesenti Gritti - - * src/core/window.c (window_would_be_covered): newly created windows - can't be considered to be above themselves; fixes bug #519188. - -2008-03-11 Matthew Wilson - - * src/core/keybindings.c (meta_display_process_key_event, process_event, - find_handler, process_mouse_move_resize_grab): allow moving workspace - while moving window with modifier - * src/core/workspace.c (meta_workspace_activate_with_focus): remove the - correct window on jumping workspace while moving - -2008-03-10 Josh Lee - - * src/core/compositor.c (window_has_shadow): Don't shadow - shaped windows. - -2008-03-07 Thomas Thurman - - * configure.in: Post-release bump to 2.23.3. - -2008-03-07 Thomas Thurman - - * NEWS: 2.23.2 release. - -2008-03-07 Thomas Thurman - - * src/core/prefs.c (mouse_button_mods_handler): remove - debug statements (*blush*) - -2008-03-06 Thomas Thurman - - * configure.in: Post-release bump to 2.23.2. - -2008-03-06 Thomas Thurman - - * NEWS: 2.23.1 release. - -2008-03-06 Thomas Thurman - - * tools/release-wrangler.py: basic md5 printing (not used yet); - also print release announcements to stdout (eventually will - need to be emailed to release list and blogged) - -2008-03-06 Thomas Thurman - - Part three of the great prefs refactor, this time - dealing with string preferences. (This was the most - complicated part, and has been especially tested and - valground before committing. As ever, though, let us - know if you find a problem.) - - * src/core/prefs.c (MetaStringPreference): new struct. - * src/core/prefs.c (update_*): replaced with *_handler - * src/core/prefs.c (meta_prefs_init): uses new string prefs - init; uses array of gconf dirs to monitor rather than - repeating code. - * src/core/prefs.c (handle_preference_init_enum): tidying - * src/core/prefs.c (change_notify): uses new string prefs - -2008-03-04 Thomas Thurman - - * MAINTAINERS: added some spacing to see whether it - helps Pulse - -2008-03-03 Cosimo Cecchi - - Add ability to vertically and horizontally maximise - using the mouse, by clicking the titlebar in various - ways. A very similar patch was received from Jason Ribero. - Thanks also go to Tony Houghton and Carlo Wood, who - both submitted patches which solved this differently. - Closes #358674. - - * src/include/common.h (MetaActionTitlebar): new values - for the new actions - * src/core/core.c (meta_core_maximize_{vertic|horizont}ally): - new functions. - * src/ui/frames.c (meta_frame_titlebar_event): handle the - new action values - * src/core/window.h: new macros (for regularity, not really - necessary) - * src/core/prefs.c (symtab_titlebar_action): new string - representations of the action values - * src/metacity.schemas.in: documentation - -2008-02-29 Andrea Del Signore - - Add support for "spacer" as a button type which adds some - empty space. Closes #509165. - - * src/ui/theme.c (meta_frame_layout_calc_geometry), - src/include/common.h (MetaButtonLayout), - src/core/prefs.c (update_button_layout, button_layout_equal), - src/metacity.schemas.in: add spacer support - -2008-02-28 Thomas Thurman - - * src/core/compositor.h: removed unnecessary #include which - should have been in Jim's patch (not sure how it slipped - through the tests!) - -2008-02-27 Jim Huang - - * src/core/spring-model.[ch]: deleted as no longer used - * src/Makefile.am: modified accordingly - -2008-02-27 Thomas Thurman - - Lots of tiny fixes to make sure we compile with - "gcc -ansi -Werror". - -2008-02-26 Jens Granseuer - - * src/core/constraints.c (constrain_aspect_ratio, - constrain_size_limits, constrain_size_increments): - reorder declarations so we don't break C89 compilers. - Closes #518917. - -2008-02-26 Thomas Thurman - - * configure.in: Post-release bump to 2.23.1. - -2008-02-26 Thomas Thurman - - * NEWS: 2.23.0 release. - -2008-02-26 Thomas Thurman - - * tools/release-wrangler.py: ANY post-release bump is now the - most recent, not just the one that matches the current version. - Otherwise, you can't use these tools straight after a branch. - The changeset before this one was mislabelled because of this. - It has now been excised from the changelog. - -2008-02-25 Thomas Wood - - * src/ui/preview-widget.[ch] (meta_preview_get_clip_region): - allow users of the preview widget to get a mask for windows - in the correct shape for the current theme. - -2008-02-23 Thomas Thurman - - Refactor handling of boolean preferences. - - * src/core/prefs.c (handle_preference_init_bool, - handle_preference_update_bool): new functions. - * src/core/prefs.c (meta_prefs_init, change_notify): - use the new functions. - * src/core/prefs.c (update_*): several of these removed whose - only purpose was to receive boolean preferences. - * src/core/prefs.c (cleanup_error, get_bool): moved down to make - the flow of ideas more obvious. - * src/core/prefs.c (maybe_give_disable_workarounds_warning): new - function containing duplicated code from elsewhere. - * src/core/prefs.c (init_button_layout): only compiled when - HAVE_GCONF is not defined. Removed a compiler warning. - -2008-02-23 Thomas Thurman - - * tools/commit-wrangler.py: Print URL of changeset on success. - -2008-02-23 Thomas Thurman - - Refactored handling of enumerated preferences. - - * src/core/prefs.c (handle_preference_init_enum, - handle_preference_update_enum): new functions. - (meta_prefs_init, change_notify): use regularised - forms and remove old copy-and-pasted code. - Also many small similar functions removed which - only existed to deal with each kind of enum. - Also some amount of correction of which parts were - and weren't inside "#ifdef HAVE_GCONF" blocks. - - -2008-02-21 Mikkel Kamstrup Erlandsen - - * src/core/constraints.c: Respect requested position on - _NET_MOVERESIZE_WINDOW. Closes #448183. - -2008-02-18 Matthias Clasen - - * src/core/window.h: Make skip-taskbar windows appear in the - Ctrl-Alt-Tab list. Closes #106249. - -2008-02-18 Thomas Thurman - - * configure.in: if we have libSM and its headers, - that means we did find it, not that we didn't. - Closes #328210. - -2008-02-18 Thomas Thurman - - * src/core/window.c (warp_grab_pointer): When - resizing a window with the keyboard, stay one - pixels from the edges so that the cursor remains - resting on a window edge even if we escape, - whatever side it was on. Closes #436257. - -2008-02-17 Thomas Thurman - - * tools/commit-wrangler.py: added new script to manage commits - -2008-02-17 Jim Huang - - * src/core/prefs.c (update_binding): Allow compilation - when gconf mode is disabled. Closes #515019. - -2008-02-14 Jim Huang - - * src/core/display.c, src/core/util.c: fixups to allow - compilation in non-verbose mode. Closes #515152. - -2008-02-12 Thomas Thurman - - * configure.in: Correct help for verbose option name. - -2008-02-12 Thomas Thurman - - * configure.in: Post-branch bump to 2.23.0. - -2008-02-12 Thomas Thurman - - * configure.in: Post-release bump to 2.21.21. - -2008-02-11 Thomas Thurman - - * NEWS: 2.21.13 release. - -2008-02-04 Thomas Thurman - - * src/core/compositor.c: only use compositor version if - we have a compositor. Closes #514453. - -2008-02-04 Thomas Thurman - - * configure.in, src/ui/ui.c: remove workaround for a problem - in GTK 1.3.9(!) which was causing problems. Closes #513737. - -2008-01-28 Michael Meeks - - * src/core/display.c (meta_display_open), - * src/core/compositor.c: fetch & use composite - version, for remote screens that don't match the - compile system's version. - (meta_compositor_manage_screen): bin erroneous FIXME. - (add_win): remove common warning churn for (very) - transient windows - -2008-02-03 Thomas Thurman - - * tools/patch-wrangler.py: another program I use for maintenance - which other people might find useful and which should probably - be in svn. Also not very polished. - -2008-02-03 Thomas Thurman - - * test/tokentest/tokentest.c, test/tokentest/tokentest.ini: added - new files for a regression test on the tokeniser. (They aren't very - polished at the moment and aren't included in the autotools build.) - -2008-02-03 Thomas Thurman - - * configure.in: Post-release bump to 2.21.13. - -2008-02-03 Thomas Thurman - - * NEWS: 2.21.8 release. - -2008-02-03 Thomas Thurman - - * tools/release-wrangler.py: Fix quoting error and added some - more error checking. - -2008-02-03 Thomas Thurman - - * tools/release-wrangler.py: basic release script; needs work, - but probably good enough for the current unstable release - -2008-02-02 Thomas Thurman - - * src/Makefile.am: core.h is in include, not core. (Last one, I - promise.) - -2008-02-02 Thomas Thurman - - * src/Makefile.am: main.h is in include, not core. - -2008-02-02 Thomas Thurman - - * src/Makefile.am: draw-workspace.h is in ui, not core. - -2008-02-01 Alex R.M. Turner - - * src/core/display.c (meta_get_tab_entry_list): Have the list also pull - windows that are in other workspaces that have the - wm_state_needs_attention flag set - * src/core/window.c (meta_window_set_demands_attention): Make windows that - are on other workspaces that demand attention that aren't obscured - count as being obscured - Bug #333548. - -2008-01-28 Christian Persch - - * src/core/display.c (convert_property): - * src/core/screen.c (meta_screen_calc_workspace_layout): - * src/core/xprops.c (meta_prop_get_values): - Use G_STRFUNC instead of the deprecated G_GNUC_FUNCTION. - Bug #512561. - -2008-01-21 Thomas Thurman - - * src/ui/theme.[ch]: more commenting. - -2008-01-18 Thomas Thurman - - * src/ui/theme.[ch]: some more commenting. - -2008-01-16 Thomas Thurman - - * src/core/bell.c: Correct comment. - * src/core/main.c: Correct comment. - * src/ui/theme.c: Much commenting; #ifdeffed-out - debug code removed. - * src/ui/theme.h: Much commenting. - -2008-01-13 Thomas Thurman - - * src/core/bell.c: Commenting. - * src/core/main.c: Commenting, and fixing existing comments. - -2008-01-12 Thomas Thurman - - * src/core/main.c: Refactor repeated lines in main() to - iterate instead. - -2008-01-12 Thomas Thurman - - * src/core/main.[ch] (meta_get_main_loop): removed as it - was never used. - * src/core/main.c: lots of comments. - * src/core/main.c (version): copyright year is 2008. - * src/core/c-screen.[ch], src/core/c-window.[ch]: removed - files from Søren's compositor which were removed by the - merge with Iain's compositor but reintroduced by the split - to separate subdirectories. - * src/core/display.c: fix comments. - -2008-01-12 Thomas Thurman - - * src/core/display.c: reinstated missing first character! - * Doxyfile: correct reordering of blank fields. - -2008-01-12 Thomas Thurman - - * src/core/display.c: change comments from /*! to /** because the - other way makes doxygen think they are Qt comments, which messes - up brief descriptions. - * Doxyfile: check in so other people can generate documentation - too. - -2008-01-07 Thomas Thurman - - * src/core/display.c: further commenting (trying to keep comment - addings down to once a day at most so you don't all get spammed - too much). - -2008-01-07 Thomas Thurman - - * src/core/main.c (main): g_free is a no-op on nulls; there is no - need to test. - -2008-01-06 Thomas Thurman - - * src/core/display.c: Function commenting marathon; more to come. - -2008-01-02 Thomas Thurman - - * src/core/xprops.c (meta_prop_get_cardinal), src/core/compositor.c - (timeout_debug): Two really minor coding standards layout tweaks. - -2007-12-27 Iain Holmes - - * src/core/compositor.c: Don't do anything in - meta_compositor_free_window, it doesn't seem to be needed and breaks - things very badly. http://bugzilla.gnome.org/show_bug.cgi?id=504876 - -2007-12-27 Iain Holmes - - * src/core/compositor.c: When a window is mapped, don't set damaged to - TRUE. Fixes a bug when redrawing shadows. - -2007-12-25 Iain Holmes - - * src/core/compositor.c: USe the compositor overlay window instead of - the root window. - -2007-12-21 Paolo Borelli - - * src/core/core.c (meta_invalidate_default_icons): do not leak list. - - * src/core/edge-resistance.c - (meta_display_compute_resistance_and_snapping_edges): ditto. - - * src/core/workspace.c (meta_workspace_index): small cleanup in list - handling. - -2007-12-19 Havoc Pennington - - * src/core/display.c (meta_display_open): fix a third warning - about %d and long int - - * src/core/delete.c (io_from_ping_dialog): fix another warning - about long int to %d - - * src/core/compositor.c (meta_compositor_new): fix a warning about - long int to %d - - * src/core/iconcache.c (meta_read_icons): use - meta_ui_get_fallback_icons() instead of incorrectly including theme.h - - * src/ui/ui.c (meta_ui_get_fallback_icons): new function - -2007-12-19 Havoc Pennington - - * src/ui, src/core, src/include: sort source files into these - directories according to which part of the WM they are supposed to - be in. In an eventual plan, we should also create - src/compositor/render, src/compositor/fallback and move some of - the compositor stuff into that. - - * autogen.sh: require a newer automake, so we don't have to use - a recursive build - - * src/ui/tabpopup.c: put in a hack to make the build temporarily - work, want to commit the large rearrangement before fixing this - not to include workspace.h or frame.h - - * src/core/iconcache.c (meta_read_icons): temporarily break this - to get the build to work, want to commit the large rearrangement - before fixing this file not to include theme.h - -2007-12-19 Thomas Thurman - - * configure.in: Post-release bump to 2.21.8. - -2007-12-19 Thomas Thurman - - * NEWS: 2.21.5 release. - -2007-12-19 Thomas Thurman - - * configure.in: print "Subversion" and not "CVS". - -2007-12-18 Thomas Thurman - - * configure.in: compositor enabled by default. - -2007-12-18 Iain Holmes - - * configure.in, src/theme.c, src/display.c, - src/theme.h, src/display.h, src/theme-parser.c, - src/compositor.c, src/c-screen.c, src/compositor.h, - src/c-screen.h, src/ui.c, src/screen.c, src/ui.h, - src/screen.h, src/c-window.c, src/c-window.h, - src/theme-viewer.c, src/Makefile.am: Merge compositor branch. - -2007-12-14 Thomas Thurman - - * configure.in: Post-release bump to 2.21.5. - -2007-12-14 Thomas Thurman - - * NEWS: 2.21.3 release. - -2007-12-11 Thomas Thurman - - * src/theme-parser.c: remove dead code; closes #501365. - -2007-12-08 Thomas Thurman - - * src/metacity.schemas.in: rewrite long description of - /schemas/apps/metacity/general/focus_new_windows because we - love the translators really. Closes #474889. - -2007-12-08 Matthias Clasen - - * src/menu.c (meta_window_menu_new): check for null before adding - menu; closes #496054. - -2007-12-08 Thomas Thurman - - * src/keybindings.c (meta_display_process_key_event): Recur if the - keypress ended a grab, so it can be processed in its own right. - Closes #112560. - -2007-12-08 Martin Meyer - - * src/theme-parser.c (parse_draw_op_element): Fix - typo where wrong variable was checked (reported by - Kjartan Maraas). Closes #501362. - -2007-11-19 Lucas Rocha - - * src/main.c (main): try to get the session client ID from - DESKTOP_AUTOSTART_ID environment variable in case the --sm-client-id - is not used. Closes #498033. - -2007-11-17 Thomas Thurman - - * configure.in: Post-release bump to 2.21.3. - -2007-11-17 Thomas Thurman - - * NEWS: 2.21.2 release. - -2007-11-17 Benjamin Gramlich - - * src/theme-parser.c (meta_theme_load): make our theme - search compliant to the XDG Base Directory Specification. - Closes #480026. - -2007-11-15 Thomas Thurman - - * src/api.[ch]: remove almost-unused files. - * src/colors.[ch]: move the used parts of api.[ch] in here. - Closes #496947. - -2007-11-13 Peter Bloomfield - - * src/window.c: (meta_window_save_user_rect): new helper, saves - only unmaximized dimensions, and not when fullscreen. - (meta_window_move_resize_internal, - meta_window_move_resize_request): use it. (#461927) - -2007-11-11 Thomas Thurman - - * configure.in: Post-release bump to 2.21.2. - -2007-11-11 Thomas Thurman - - * NEWS: 2.21.1 release. - -2007-11-11 Thomas Thurman - - * src/window.c (meta_window_show): adjust expression which decides - whether new windows should not go on top, so that restacking happens - only the first time a window is mapped. Thanks to Olav Vitters for - pointing out the problem. Re-fixes #486445. - -2007-11-11 Alex R.M. Turner - - * src/tabpopup.c (tab_entry_new, meta_ui_tab_popup_new): Instruct the - GtkLabel in the tabpopup to ellipsize text that is too big. Set the - maximum window width of the tabpopup to screen_width/4, which seems a - sensible size for the popup. - -2007-11-09 Elijah Newren - - * src/window.c (meta_window_new_with_attrs): If a window is - launched without any kind of launch timestamp, grab the current - time and stash it away. When transients of that window are also - launched without a timestamp, we can use the stashed timestamp - from the parent. Fixes #488468. - -2007-11-07 Federico Mena Quintero - - * src/window-props.c (reload_net_wm_user_time_window): Fix typo; - the arguments to meta_window_reload_property_from_xwindow() were - reversed. This is why the wm_user_time wasn't getting initialized - properly from the _NET_WM_USER_TIME_WINDOW. Fixes part of - http://bugzilla.gnome.org/show_bug.cgi?id=488468 - -2007-11-06 Peter Bloomfield - - * src/window.c (meta_window_move_resize_internal): save - unmaximized part of client root coords. (#461927) - -2007-11-06 Peter Bloomfield - - * src/window.c (meta_window_move_resize_internal): do not save - client root coords while window is maximized. (#461927) - -2007-10-30 iain Holmes - - * src/main.c (meta_parse_options): Add --sync option - (main): Check if the --sync option was passed on command line. - -2007-10-28 Jans Granseuer - - * src/preview-widget.c (meta_preview_finalize): Free title of - preview when the preview is destroyed. Closes #469682. - -2007-10-27 Alex R.M. Turner - - * src/tabpopup.c (tab_entry_new): Truncate the string to - max_char_per_title before adding bold tags and fix general flow of - function. - -2007-10-16 Thomas Thurman - - * src/window.c (window_would_be_covered): new function. - * src/window.c (meta_window_show): rewrite assertion not - to put window on top in terms of window_would_be_covered(); - remove assertion because it's no longer valid; explicitly - don't focus windows that shouldn't be focussed; closes #486445. - -2007-10-14 Thomas Thurman - - * configure.in: Post-branch bump to 2.21.1. - -2007-10-03 Kjartan Maraas - - * configure.in: Remove circular dep metacity<->gnomecc. - -2007-09-15 Elijah Newren - - * configure.in: post-release version bump to 2.20.1 - -2007-09-15 Elijah Newren - - * configure.in: - * NEWS: - 2.20.0 release - -2007-09-15 Elijah Newren - - * src/session.c (warn_about_lame_clients_and_finish_interact): - Patch from Alexey Rusakov to prevent a crash on logout with - metacity subsequently not being restored in future sessions. - Fixes #433253. - -2007-09-01 Elijah Newren - - * HACKING: update; cvs->svn & mention GConf needed - * MAINTAINERS: Make it match idiotic format requirements (I love - you Olav!) - -2007-08-07 Thomas Thurman - - * configure.in: post-release bump to 2.19.89. - -2007-08-07 Thomas Thurman - - * NEWS: 2.19.55 release. - -2007-08-06 Thomas Thurman - - If KEY_AUTO_RAISE_DELAY is undefined or non-integer, it is not treated - as zero. - - * src/prefs.c (meta_prefs_init): check type of key, and behave sensibly - if it's unexpected. - * src/prefs.c (find_and_update_list_binding): remove old comment. - -2007-08-03 Frederic Crozat - - * src/delete.c: Fix mangled window title in "Force Quit" - dialog when using non-UTF8 locale. Close #462734. - -2007-08-02 Thomas Thurman - - Move "close" to bottom of window menu; allow workspace list to appear - at any position in the menu. Closes #104026. - - * src/menu.c (MetaMenuItemType): added new MENU_ITEM_WORKSPACE_LIST - item. - * src/menu.c (menuitems): reordered "close", added a workspace list. - * src/menu.c (menu_item_new): return null for workspace lists. - * src/menu.c (meta_window_menu_new): handle workspace lists. - -2007-07-31 Thomas Thurman - - * src/window.c (meta_window_show_menu): windows which are - always on top have the "stick" menu option insensitive. (#460997). - -2007-07-23 Thomas Thurman - - * src/window.h (MetaWindow): Put all bitfields together to - help with optimisation. Closes #450271 (for real this time). - -2007-07-23 Matthias Clasen - - * configure.in: - * src/Makefile.am: Use the correct directory when - installing keybindings. (#454055) - -2007-07-22 Thomas Thurman - - * configure.in: post-release bump to 2.19.55. - -2007-07-22 Thomas Thurman - - * NEWS: 2.19.34 release. - -2007-07-22 Rob Bradford - - Fix a bug where the window can be focused without being raised - if the maximize is aborted. Fixes #459027. - - * src/frames.c (meta_frames_button_press_event, - meta_frames_button_release_event): When maximising only focus - the window once the button press is released. - -2007-07-22 Cosimo Cecchi - - Unset fullscreen is an allowed action where relevant. Fixes #449427. - - * src/window.c (set_allowed_actions_hint): Separate FULLSCREEN action - from RESIZE action. - -2007-07-22 Yair Hershkovitz - - Reverse window buttons and align them to the left for RTL locales. - Fixed #92212. - - * src/prefs.c (button_layout, init_button_layout, update_button_layout): - Support reversing and left-aligning of buttons for both Gconf and - NO-Gconf modes. - * src/main.c (main): Call meta_ui_init() before meta_prefs_init(). - meta_prefs_init() check for RTL locales which is initialized in - meta_ui_init(). - * src/theme.c (meta_frame_layout_calc_geometry): Fixed access to - button_layout to stop iterating when getting to a - META_BUTTON_FUNCTION_LAST value. - -2007-06-23 Thomas Thurman - - * src/window.c (MetaWindow): Put all bitfields together to - help with optimisation. Closes #450271. - -2007-06-18 Thomas Thurman - - * src/main.c (version): Update copyright year because it was - five years out of date. - -2007-06-18 Thomas Thurman - - * configure.in: post-release bump to 2.19.34. - -2007-06-18 Thomas Thurman - - * NEWS: 2.19.21 release. - -2007-06-18 Thomas Thurman - - * src/place.c (find_first_fit, meta_window_place): Only open new - windows on the current xinerama. Closes #145503, for now. - -2007-06-17 Thomas Thurman - - * src/screen.[ch] (meta_screen_apply_startup_properties): return a - boolean instead a void, to show whether startup properties were - applied. Also some commenting. - * src/window-props.c: (reload_net_startup_id): Only activate the - window if the startup_id was actually changed. Closes #400167. - -2007-06-16 Damien Carbery - - * effects.h: MetaCloseEffect and MetaFocusEffect, which were empty - structs, #ifdeffed out because they broke the build on Solaris. - Closes #397296. - -2007-06-16 Damien Carbery - - * window.h: make prototype of meta_window_unqueue match - implementation. Closes #446535. - -2007-06-10 Thomas Thurman - - * configure.in: post-release bump to 2.19.21. - -2007-06-10 Thomas Thurman - - * NEWS: 2.19.13 release. - -2007-06-10 Thomas Thurman - - Refactor thrice-duplicated queue code in window.c. Closes #376760. - - * src/window.c (meta_window_queue, meta_window_unqueue): - New functiortl.patchns. - * src/window.[ch] (meta_window_unqueue_*, meta_window_queue_*): - Removed functions. - * src/window.c (meta_window_new_with_attrs, meta_window_free, - meta_window_flush_calc_showing, queue_calc_showing_func, - meta_window_minimize, meta_window_unminimize, meta_window_maximize, - meta_window_make_fullscreen, meta_window_shade, - meta_window_unshade, meta_window_move_resize_internal, - window_stick_impl, window_unstick_impl, - meta_window_client_message, process_property_notify): Modified to - use new queueing functions. - * src/window.c (idle_move_resize, idle_update_icon, - idle_calc_showing): update to receive queue number from pointer. - * src/window.h (MetaQueueType): new enum. - * src/window.h (MetaWindow): *_queued replaced with is_in_queue - bitfield. - * src/core.c (meta_core_queue_frame_resize): - * src/display.c (event_callback, - meta_display_queue_retheme_all_windows): Using new queueing functions. - * src/frame.c (meta_window_destroy_frame): Using new queueing functions. - * src/screen.c (queue_resize, meta_screen_resize_func, - queue_windows_showing): Using new queueing functions. - * src/window-props.c (reload_mwm_hints, reload_wm_hints, - reload_transient_for): Using new queueing functions. - * src/workspace.c (meta_workspace_add_window, - meta_workspace_remove_window, meta_workspace_queue_calc_showing, - meta_workspace_invalidate_work_area): Using new queueing functions. - -2007-06-09 Thomas Thurman - - * src/50-metacity-key.xml.in: added switch_group; closes #444879. - -2007-06-08 Elijah Newren - - * src/metacity.schemas.in: - Update the raise_on_click description to try to prevent misuses, - to appropriately warn users, and to stop wasting the time of - application developers. #445447, #389923 - -2007-06-06 Thomas Thurman - - * frames.c, core.[ch]: changed all tabs to spaces. - * core.[ch] (meta_core_get_client_size, meta_core_window_has_frame, - meta_core_titlebar_is_onscreen, meta_core_get_client_xwindow, - meta_core_get_frame_flags, meta_core_get_frame_type, - meta_core_get_mini_icon, meta_core_get_icon, meta_core_get_position, - meta_core_get_size, meta_core_get_frame_workspace, - meta_core_get_frame_extents, meta_core_get_screen_size): Removed - and replaced with meta_core_get(). - * core.[ch] (meta_core_get): New function. - * core.h (MetaCoreGetType): New enum. - * frames.c (meta_frames_ensure_layout, meta_frames_calc_geometry, - meta_frames_get_geometry, meta_frames_apply_shapes, - meta_frame_titlebar_event, meta_frames_button_press_event, - populate_cache, clip_to_screen, meta_frames_paint_to_drawable, - meta_frames_set_window_background, get_control): Replace use of - removed functions in ui.c with meta_core_get(). - - All this should make things a little faster. Closes #377495. - -2007-06-04 Thomas Thurman - - * NEWS: Added translators' names from 2.19.8 (sorry, folks: - I forgot to save NEWS with their names in it before shipping.) - -2007-06-04 Thomas Thurman - - * configure.in: post-release bump to 2.19.13. - -2007-06-04 Thomas Thurman - - * NEWS: 2.19.8 release. - -2007-06-04 Thomas Thurman - - * src/metaaccellabel.c (meta_accel_label_expose_event): fix - label layout for RTL languages. Closes #433400. - -2007-06-03 Thomas Thurman - - * src/frames.c (meta_frames_ensure_layout): Pango layout for - titlebars should take LTR/RTL-ness from the underlying widget - and not from sniffing the content. Closes #438944. - -2007-05-25 Yair Hershkovitz - - * src/workspace.c (meta_workspace_get_neighbor): Add support - for RTL languages so that alt-tab, etc., go the other way. - * src/keybindings.c (handle_activate_menu): In RTL locales, - pop up the menu on the right-hand side when the menu keystroke - is pressed. - * src/fixedtip.c (meta_fixed_tip_show): right-justify tooltips - in RTL locales. - * src/menu.c (popup_position_func): popup menus in RTL locales - are flush with the right-hand side of the window where possible. - * src/frames.c (show_tip_now, meta_frames_button_press_event): - tooltips are aligned with the right-hand side of buttons in - RTL locales. - * src/ui.[ch] (meta_ui_get_direction, enum MetaUIDirection): - New content. - * src/window.c (meta_window_show_menu): "move left" appears above - "move right" in the window menu for LTR locales, and vice versa - for RTL locales. - - This is all to close bug #387893. - -2007-04-24 Linus Torvalds - - * src/prefs.[ch] (init_action_meta_prefs, meta_prefs_init, - action_change_titlebar, change_notify, update_action_titlebar, - meta_preference_to_string): Add code to configure what happens - when the titlebar is right or middle clicked as well as - double clicked. - -2007-04-23 Elijah Newren - - * configure.in: post-release bump to 2.19.8. - -2007-04-23 Elijah Newren - - * NEWS: 2.19.5 release. - -2007-04-23 Elijah Newren - - Fix some uninitialized memory usage errors. #427385 - - * src/frame.c (meta_window_ensure_frame): - * src/frames.c (meta_frames_manage_window): - Do not try to set the window background in - meta_frames_manage_window() since the frame window is not yet - created and not yet registered with the corresponding MetaWindow. - Do it inside meta_window_ensure_frame() instead. - -2007-04-17 Elijah Newren - - Fix some fallout from #426519; update user_rect for all position - changes prior to the window being marked as placed. Prevents - emacs in particular from flickering on start and always being - shoved to the upper-left corner. - - * src/window.c (meta_window_move_resize_internal): - Record position in user_rect if the window is not yet marked as - placed too - - * src/window.c (struct MetaWindow, meta_window_new_with_attrs, - meta_window_move_resize_internal): - Remove window->user_has_move_resized; it's not needed or used - anymore. - - * src/window.[ch] (meta_window_get_user_position): - Remove this function as it is no longer needed or used. - -2007-04-16 Elijah Newren - - Prevent metacity from "forgetting" which machine a window is on. - #418552 - - * src/window.c (meta_window_new_with_attrs): reorder the property - loading so that we know the wm_client_machine when we load the - name of the window and can modify the window name accordingly. - -2007-04-16 Elijah Newren - - * configure.in: post-release bump to 2.19.5. - -2007-04-16 Elijah Newren - - * NEWS: 2.19.3 release. - -2007-04-15 Elijah Newren - - Preserve stacking order across restarts. - - * src/display.c (meta_display_unmanage_windows_for_screen): - unmap windows in stacking order so that stacking is preserved upon - shutdown - - * src/display.[ch] (meta_display_stack_cmp): - * src/session.c (stack_cmp, save_state): - rename stack_cmp() -> meta_display_stack_cmp() and move it to a - different function so that it can be used in both - session.c:save_state() and - meta_display_unmanage_windows_for_screen() - -2007-04-15 Elijah Newren - - Remove incorrect usage of window.h from menu.c. See #426791 & - #382962. - - * src/menu.c (enum MetaMenuItemType, variable menuitems, - meta_menu_item_new): - cleanup: add a MENU_ITEM_RADIOBUTTON for the sticky stuff - - * src/menu.c (variable menuitems): - * src/core.c (meta_core_get_menu_accelerator): - * src/window.c (menu_callback, meta_window_show_menu): - * src/common.h (enum MetaMenuOp): - reinstate META_MENU_OP_UNABOVE - - * src/menu.c (meta_window_menu_new): - remove hacks (using inappropriate data) for STICK/UNSTICK/ABOVE - and clean it up while just setting STICK/UNSTICK activeness as - necessary - - * src/menu.[ch] (meta_window_menu_new): - * src/ui.[ch] (meta_ui_window_menu_new): - make the active_workspace parameter an unsigned long - -2007-04-15 Bruno Boaventura - - * src/menu.c (meta_window_menu_new): don't show the current - workspace as a possible workspace to switch to. Fixes #426791. - -2007-04-12 Elijah Newren - - * src/place.c (meta_window_place): do not auto-maximize windows - larger than the workarea in only a single direction. Fixes - #419810. - -2007-04-11 Elijah Newren - - Make sure apps have correct info about their coordinates, even on - unmap. Fixes temporary hang with libXt (XtVaSetValues setting x & - y coordinates). #399552. - - * src/frame.c (meta_window_destroy_frame): Add a comment noting - that the current choice causes the need for a ConfigureNotify - event - - * src/window.c (meta_window_free): Send a configure notify event - due to our XReparentWindow coordinate choices on withdrawal, - (unmaximize_window_before_freeing): no need to send a configure - notify from here since it is always done in meta_window_free new, - (send_configure_notify): have to special case the coordinates used - when withdrawing the window - -2007-04-11 Thomas Thurman - - Workaround for a gdk bug which dies with BadAlloc if you try - to allocate an insanely huge rectangle for an insanely huge - window. Fixes #399529. - -2007-04-11 Elijah Newren - - Advertise support of Above and Below operations (assuming the - proposed EWMH additions of _NET_WM_ACTION_(ABOVE|BELOW) will be - accepted, otherwise these changes will have to be modified). Part - of #115247. - - * src/display.[ch] (meta_display_open, struct MetaDisplay): - * src/screen.c (set_wm_check_hint): - Add support for _NET_WM_ACTION_ABOVE and _NET_WM_ACTION_BELOW - - * src/window.c (set_allowed_actions_hints): - add active_above and action_below - -2007-04-10 Elijah Newren - - * src/window.c (recalc_window_features): make sure to set - _NET_WM_ALLOWED_ACTIONS so that libwnck menus don't have sensitive - but ineffective menu items. The "On Top" item is now buggy, but - due to the fact that _NET_WM_ACTION_ABOVE is not yet defined in - the EWMH. Fixes #115247. - -2007-04-09 Elijah Newren - - Add support for _NET_MOVERESIZE_WINDOW. Based on patch from - Magnus Therning. #344521. - - * src/display.c (handle_net_moveresize_window, event_callback): - Remove handle_net_moveresize_window() and the call to it; this - code was highly buggy, though to be fair it was never tested and - had simply been put into the code in commented out form. - - * src/screen.c (set_supported_hint): - add atom_net_moveresize_window - - * src/window.[ch]: - (meta_window_configure_request, meta_window_move_resize_request): - Split out the moving/resize part of the configure request and put - it into meta_window_move_resize_request - - (meta_window_client_message): - check for NET_MOVERESIZE_WINDOW messages and call - meta_window_move_resize_request() with the appropriate parameters - to handle them - - (meta_window_move_resize_internal): - fix some of the big comment at this function -- it wasn't quite - right, use the passed in gravity instead of - window->size_hints.win_gravity when calling adjust_for_gravity() - to make sure the correct adjustments are used. - - (meta_window_get_gravity_position, - meta_window_get_geometry, meta_window_move_resize_request): - add a gravity parameter to meta_window_get_gravity_position and - have it use that gravity instead of window->size_hints.win_gravity - -2007-04-09 Elijah Newren - - * configure.in: post-release bump to 2.19.3. - -2007-04-09 Elijah Newren - - * NEWS: 2.19.2 release. - -2007-04-08 Elijah Newren - - Remove grab_start_serial, which we expect to be an ancient attempt - to workaround sloppy/mouse focus bugs that have since been - correctly fixed. May fix some race conditions. May cause nasty - bugs in sloppy/mouse focus modes. We'll find out soon enough... - See #304430. - - * src/display.c (event_callback): - remove event->xany.serial >= display->grab_start_serial in several - event callback handlers - - * src/display.[ch] (struct _MetaDisplay, meta_display_begin_grab_op): - * src/keybindings.c (do_choose_window, handle_workspace_switch): - * src/frames.c (meta_frames_button_press_event): - * src/core.[ch] (meta_core_begin_grab_op): - * src/window.c (meta_window_client_message, meta_window_begin_grab_op): - don't require an event_serial to be passed to - meta_display_begin_grab_op () and don't record it anymore. - - * src/ui.c (struct _EventFunc, filter_func, - meta_ui_get_last_event_serial) - * src/core.h (meta_ui_get_last_event_serial): - remove meta_ui_get_last_event_serial() function (don't ask me why - it was declared in core.h) and the last_even_serial field of - _EventFunc - -2007-04-08 Elijah Newren - - Fix move/resize events in relation to combinations of - ConfigureRequest and WM_NORMAL_HINTS change notifications (plus a - few code cleanups). Fixes #426519. - - * src/window.c (meta_window_move_resize_now): - move to the user_rect position, not some weird combination of rect - and user_rect - - * src/window.c (meta_window_configure_request): - set user_rect in response to ConfigureRequest events (after the - ConfigureRequest values have been constrained) and add a big - comment explaining this change, remove unused only_resize variable - and irrelevant huge FIXME comment about it - - * src/window.[ch] (meta_window_get_client_root_coords): - new function - - * src/display.c (meta_display_begin_grab_op): - * src/keybindings.c (process_keyboard_move_grab): - * src/window.c (meta_window_unmaximize, - meta_window_move_resize_internal, meta_window_begin_wireframe, - update_move, meta_window_refresh_resize_popup, - warp_grab_pointer) - combine multi-step client rect root coord setting into a single - function call to meta_window_get_client_root_coords() - -2007-04-08 Thomas Thurman - - * ChangeLog: removed conflict line. - -2007-04-07 Elijah Newren - - * src/prefs.[ch] (screen_bindings array, - META_KEYBINDING_SET_SPEW_MARK definition): - * src/keybindings.c (handle_spew_mark, screen_handlers array): - Add an (unbound by default) keybinding for setting spew marks in - verbose debugging logs. I'm not sure why this was ever removed; - I've wanted it so many times. - - * HACKING: - valgrind wants --log-file not --logfile. - -2007-04-07 Elijah Newren - - * src/window.c (meta_window_free): Fix memory bug (invalid free) - introduced in 2007-04-02 strut cleanup commit. Part of #427385. - -2007-04-05 Thomas Thurman - - * src/theme_parser.c: if theme is invalid and therefore got - freed, don't attempt to read from it. Closes #423855. - -2007-04-05 Bastien Nocera - - * src/50-metacity-desktop-key.xml.in: - * src/50-metacity-key.xml.in: - * src/Makefile.am: - Add new control-center key bindings definitions (Closes: #420145) - -2007-04-04 Elijah Newren - - * configure.in: post-release bump to 2.19.2. - -2007-04-04 Elijah Newren - - * NEWS: 2.19.1 release. - -2007-04-04 Elijah Newren - - * src/window.c (meta_window_move_resize_internal): send synthetic - configurenotify events also in response to MapRequest events when - the window has a frame and the application specifies PPosition or - UPosition hints. I believe they are already sent for all other - cases. Should fix #322840. Fixes the testcase at least. :) - -2007-04-04 Elijah Newren - - Fix lots of little issues with min/max constraints and size - increment constraints. Fixes #329152, #418395, and possibly - others. - - * src/window-props.c (meta_set_normal_hints): - Do more checking to make sure application specified constraints - are self-consistent, modifying the size_hints as necessary to - achieve self-consistency. - - * src/constraints.c (setup_constraint_info): remove ugly - copy-pasto, (constrain_size_increments): be careful that fixing - violation of the constraints doesn't cause a violation of the - minimum size constraints. - - * src/window.c (ensure_size_hints_satisfied): new function, - (meta_window_unmaximize, meta_window_unmake_fullscreen): the - saved_rect may no longer be valid (as in the case of #329152) so - call ensure_size_hints_satisfied to fix it up. - - * doc/how-to-get-focus-right.txt: Some minor spacing and wording - fixes completely unrelated to the rest of this commit - -2007-04-03 Elijah Newren - - * src/window.c (meta_window_unmaximize): - Only use saved_rect for determining the position to unmaximize to - for the previously-maximized direction(s). Fixes #355497. - -2007-04-03 Elijah Newren - - * MAINTAINERS: Update. #412319. - -2007-04-03 Elijah Newren - - * src/display.c (meta_display_update_active_window_hint): - _NET_ACTIVE_WINDOW is a single xwindow id, not two. - -2007-04-03 Elijah Newren - - * src/keybindings.c (handle_panel_keybinding): turn mouse_mode off - to prevent focus issues with the run application dialog. Fixes - #374752. - -2007-04-03 Elijah Newren - - Avoid some crashes when dragging windows partially offscreen. - Possible (or at least partial) fix for #353513. - - * src/edge-resistance.c (apply_edge_resistance): be more careful - about calls to find_index_of_edge_near_position() returning - possibly invalid indices. Also, add a warning comment to - find_index_of_edge_near_position(). - -2007-04-03 Elijah Newren - - Patch from Carlo Wood to do some miscellaneous code cleanups found - while working on #358311. - - * src/constraints.c (do_screen_and_xinerama_relative_constraints): - nicer way of avoiding compilation warning - - * src/boxes.c (meta_rectangle_clamp_to_fit_into_region, - meta_rectangle_clip_to_region, meta_rectangle_shove_into_region): - Much cleaner way of ignoring invalid boxes in comparisons - -2007-04-02 Elijah Newren - - Patch from Carlo Wood to fix handling of unidirectional - maximization and partial struts. #358311. - - * src/constraints.c (constrain_maximization): - determine target size for unidirectionally maximized windows by - determining how far they can be maximized without hitting - orthogonal struts. Avoids weird "empty spaces". - - * src/boxes.[ch] (meta_rectangle_expand_to_avoiding_struts): - new function - -2007-04-02 Elijah Newren - - Make the strut lists (stored in workspaces) record both the - rectangle and the side that the strut is on. Lots of code - cleanups relating to struts. - - * src/boxes.h (struct MetaStrut): - new struct for struts - - * src/window.[ch] (struct MetaStruts, struct MetaWindow, - meta_window_update_struts): - overhaul to make window's struts remember their side as well as - their rectangular location, and just use a list instead of several - copies of near-identical code for left/right/top/bottom (allowing - us to nuke MetaStruts struct as well) - - * src/testboxes.c (new_meta_strut, get_strut_list): - * src/workspace.c (ensure_work_areas_validated): - * src/boxes.c (meta_rectangle_get_minimal_spanning_set_for_region, - meta_rectangle_expand_to_avoiding_struts, - get_disjoint_strut_rect_list_in_region, fix_up_edges, - meta_rectangle_find_onscreen_edges, - meta_rectangle_find_nonintersected_xinerama_edges): - modify to handle struts being rectangle + side instead of just rectangle - - * src/workspace.c (ensure_work_areas_validated): - simplify strut list creation considerably given MetaWindow change, - modify work_area computations to take advantage of region - computations being done (makes the code shorter as well as more - robust against pathological cases). - - * src/util.[ch] (meta_free_gslist_and_elements): - new convenience function - - * src/common.h (enum MetaDirection): - * src/edge-resistance.c (movement_towards_edge): - * src/boxes.c (meta_rectangle_edge_aligns, - rectangle_and_edge_intersection, split_edge): - Add more MetaDirection fields for convenience - - * src/boxes.h (enum FixedDirections): - * src/constraints.c (setup_constraint_info, place_window_if_needed): - add a FIXED_DIRECTION_NONE to the FixedDirections enum to make - code more clear - -2007-04-01 Bruno Boaventura - - * src/theme.c (kill_window_question): Fallback to NORMAL state after - checking for the middle button. Fixes bug #419043. - Patch from Benjamin Berg . - -2007-03-31 Elijah Newren - - Clean up event mask handling and meta_create_offscreen_window, to - prevent nasty metacity/gdk interactions causing hangs. See #354213. - - * src/screen.[ch] (meta_create_offscreen_window): - * src/display.c (meta_display_open): - * src/screen.c (meta_screen_new): - Add a valuemask parameter to meta_create_offscreen_window - - * src/display.c (meta_display_open): - make it explicit that we can't rely on PropertyNotify events for - the leader_window due to nasty metacity/gdk interaction - - * src/session.c (warn_about_lame_clients_and_finish_interact): - remove cut-and-paste code for timestamp pinging and just call - meta_display_get_current_time_roundtrip - -2007-03-30 Elijah Newren - - Add support for _NET_WM_USER_TIME_WINDOW in order to cut down on - context switches. Fixes #354213. - - * src/display.c (meta_display_open): - * src/display.h (struct _MetaDisplay): - * src/screen.c (set_supported_hint): - new atom - - * src/display.c (meta_display_open, - meta_display_get_current_time_roundtrip): - * src/display.h (struct _MetaDisplay): - create a dedicated timestamp pinging window instead of reusing - display->leader_window - - * src/display.c (event_callback): - * src/window-props.c (reload_net_wm_user_time_window): - * src/window.c (meta_window_new_with_attrs, meta_window_free, - process_property_notify): - * src/window.h (struct _MetaWindow): - monitor property notify events on _NET_WM_USER_TIME_WINDOW windows too - - * src/window-props.[ch]: - new meta_window_reload_propert(y|ies)_from_xwindow() functions - - * src/window-props.[ch] - (init_net_wm_user_time_window, reload_net_wm_user_time_window, - meta_display_init_window_prop_hooks): - * src/window.c (meta_window_new_with_attrs): - new hooks to handle new atom - -2007-03-26 Josselin Mouette - - * src/session.c (meta_session_init): if previous client ID - was supplied, use it in filename. - * src/session.c (set_clone_restart_commands): use --sm-client-id - in command line to restore session, not original file name. - * src/session.c (regenerate_save_file): generate filename using - client ID and not original file name. - * src/session.c (base_save_file): removed function. - Closes GNOME 407981, Debian 391287, Debian 315169. - -2007-03-25 Elijah Newren - - * configure.in: bump version to 2.19.1; doesn't make sense to have - the development version have a version number less than the stable - version. ;-) - -2007-03-20 Arthur Taylor - - * src/frames.c (meta_frames_apply_shapes): adjusted the rounded - corners so that they fit nicely with the arcs around them. - Fixes #399373. - -2007-03-17 Kjartan Maraas - - * src/ui.c: Remove #include since it's - apparently not installed anymore. Builds just fine without it too. - -2007-03-10 Charlie Brej - - * src/metacity.schemas.in: add action_{middle|right}_click_titlebar. - Closes #408903. - -2007-03-09 Linus Torvalds - - * src/frames.c (meta_frame_middle_click_event, - meta_frame_right_click_event): honour preferences. - * src/prefs.[ch] (meta_prefs_get_action_middle_click_titlebar, - meta_prefs_get_action_right_click_titlebar): new functions. - -2007-02-20 Kjartan Maraas - - * Makefile.am: Add MAINTAINERS to EXTRA_DIST so others - can find out where to send patches. Hi Linus :-) - -2007-02-17 Linus Torvalds - - * src/common.h (MetaActionTitleBar): renamed from - MetaActionDoubleClickTitleBar; added _LOWER and _MENU. - * src/frames.c (meta_frame_titlebar_event): renamed - enums as above; added code to handle _LOWER and _MENU, - which is moved in from meta_frame_{middle|right}_click_event. - * src/frames.c (meta_frame_middle_click_event, - meta_frame_right_click_event): rewrote in terms of - meta_frame_titlebar_event. - * src/prefs.c: removed "DoubleClick" from names as above. - * src/prefs.c (action_titlebar_from_string): added cases - for "lower" and "menu". - Fixes #408902. - -2007-02-17 Linus Torvalds - - * src/frames.c (meta_frames_button_press_event): Split out - code for different kinds of click into separate functions. - Fixes #408899. - * src/frames.c (meta_frame_titlebar_event, - meta_frame_double_click_event, meta_frame_middle_click_event, - meta_frame_right_click_event): new functions. - -2007-01-27 Bruno Boaventura - - * src/metacity-dialog.c (kill_window_question): Change dialog - icon because gnome-icon-theme have no more "panel-force-quit". - Patch from Jaap A. Haitsma . - -2007-01-16 Thomas Thurman - - * doc/compositor-control.txt: fix silly thinko. - -2007-01-16 Thomas Thurman - - * configure.in: post-release bump to 2.17.8. - -2007-01-16 Thomas Thurman - - * doc/compositor-control.txt: New file. - -2007-01-16 Thomas Thurman - - * src/compositor.c (meta_compositor_new): Removed - #ifdef SPIFFY_COMPOSITOR throughout the file. Replaced with check - for environment variable METACITY_BLING, which may be temporary. - -2007-01-13 Bruno Boaventura - - * src/frames.c (meta_frames_motion_notify_event): Unmaximize - button must keep preesed appearence when clicked (hold down), - move off, and back over the button. Fixes #395560. Patch from - Mad Alex . - -2007-01-02 Thomas Thurman - - * src/c-screen.c (meta_comp_screen_redirect): Remove double unref - of stacker object. Fixes #387761. - -2006-12-27 Bruno Boaventura - - Move "On Top" option in menu. Fix #382962. - - * src/common.h, src/core.c: Remove META_MENU_OP_UNABOVE. - * src/menu.c: remove unabove menu item and put above item - next "Always on Visible Viewport". - * src/window.c: remove handles of META_MENU_OP_UNABOVE. - -2006-12-21 Thomas Thurman - - * src/compositor.c: Disabled bling for now; added function for - handling CirculateNotify XEvent; some commenting. - * src/compositor.h, src/c-window.c: fix function prototype visibility. - -2006-12-12 Thomas Thurman - - * src/compositor.c (do_effect): Sanity check to avoid dereferencing - a null pointer. - -2006-12-10 Thomas Thurman - - * configure.in: post-release bump to 2.17.5. - -2006-12-10 Thomas Thurman - - * NEWS: 2.17.3 release. - -2006-12-05 Christof Krüger - - * src/window.c (update_move): Fix flickering about when dragging - maximised windows between xineramas. Closes #358715. - -2006-12-03 Federico Mena Quintero - - Fix http://bugzilla.gnome.org/show_bug.cgi?id=381127: - - * src/window.c (idle_calc_showing): Grab the server while the - windows are being shuffled. First show the windows to be shown, - and then hide the windows to be hidden, in order to minimize - the number of expose events. - -2006-11-15 Bruno Boaventura -2006-11-15 Björn Lindqvist - - * src/menu.c: added MetaMenuItemType enum; added it - to MenuItem; added values of this type to menuitems - array. - * src/menu.c (menu_item_new): rewrite to take a MenuItem - instead of a set of parameters describing the menu item. - * src/menu.c (meta_window_menu_new): use proper checkboxes - or radio buttons on the window menu. (#343108) - * src/window.c (meta_window_show_menu): unstick and stick - are always shown. - -2006-11-06 Thomas Thurman - - * configure.in: post-release bump to 2.17.3. - -2006-11-06 Thomas Thurman - - * configure.in: pre-release bump to 2.17.2. - * NEWS: 2.17.2 release. - -2006-11-05 Priit Laes - - * src/main.c, src/ui.c: remove deprecated gtk stuff. - -2006-11-05 Bruno Boaventura - - * src/theme.c, src/testgradient.c: remove deprecated gtk stuff. - -2006-11-05 Kjartan Maraas - - * src/ui.c: use g_strdup to allocate a string, not strdup. Fixes - #363354. - * src/metacity-dialog.c: add missing spaces to string. Fixes - #363355. - -2006-11-05 Justin Mason - - * src/keybindings.c: implement handle_move_to_{side|corner}_* to - allow the user to flip a window to the side or corner of the - screen. Fixes #317884. - * src/prefs.h: keybindings for the above. - * src/metacity.schemas.in: keybindings for the above. - -2006-11-05 Elijah Newren - - * src/frames.c: improved rounding of rounded corners. Fixes #360542, - mostly. - -2006-10-30 Dan Mick - - * src/window.c: (__window_is_terminal): Fix strict focus - mode by picking up on res_class. Fixes #361054, strict focus - mode still not working; should look for res_class, not res_name - -2006-10-16 Elijah Newren - - * NEWS: 2.17.1 release. - -2006-10-13 Carlo Wood - - Fix cases when titlebar is allowed offscreen and shouldn't be (and - vice-versa). #333995. - - * src/display.[ch] (struct _MetaDisplay): add grab_frame_action - member - - * src/display.[ch] (meta_display_begin_grab_op): - * src/window.[ch] (meta_window_begin_grab_op): - * src/core.[ch] (meta_core_begin_grab_op): - Add frame_action parameter (core & window versions pass it on to - display) - - * src/display.c (event_callback): - * src/window.c (meta_window_begin_grab_op, - meta_window_client_message, menu_callback): - * frames.c (meta_frames_button_press_event): - * keybindings.c (do_choose_window, handle_begin_move, - handle_begin_resize, handle_workspace_switch): - Pass whether the action should be considered a 'frame_action', - which will be used to determine whether to force the titlebar to - remain onscreen, to meta_*_begin_grab_op - - * constraints.c (constrain_titlebar_visible): - Replace previous ugly hack by using grab_frame_action (and whether - the action is a user action) to determine whether to enforce the - titlebar_visible constraint. - -2006-10-10 Elijah Newren - - * src/draw-workspace.c (draw_window, wnck_draw_workspace): Patch - from Bruno Boaventura to sync metacity workspace previews with - libwnck. #341893 - -2006-10-07 Thomas Thurman - - * configure.in: post-release bump to 2.17.1. - -2006-10-07 Thomas Thurman - - * NEWS: 2.17.0 release. - -2006-10-07 Thomas Thurman - - * src/themes/Crux/metacity-theme-2.xml: removed hide_buttons. - Closes #360498. - -2006-10-07 Thomas Thurman - - * MAINTAINERS: added myself. - -2006-10-07 Thomas Thurman - - * doc/theme-format.txt: described new theme format. - - * src/themes/Bright, src/themes/Crux: added version 2 themes. - -2006-10-07 Thomas Thurman - - * common.h: Added "above" to the list of flags a frame can have, so - that we know when to mark it as always on top. Added six grab ops, - one to do and one to undo each of the three new titlebar buttons - (shade, above, stick). Added six new button functions, similarly. - (#96229) - - * frame.c (meta_frame_get_flags): If a frame has the WM_STATE_ABOVE X - attribute, set META_FRAME_ABOVE in its flags. - - * frames.c (meta_frames_apply_shapes): Allow variable amounts of - rounding. (#113162) - - * frames.c (show_tip_now, meta_frames_paint_to_drawable, control_rect, - get_control): extend handling of existing buttons to the - 3*2 new kinds of button. (#96229) - - * frames.c (meta_frames_button_press_event): translate clicks on the 3*2 - new kinds of button to the new grab ops. (#96229) - - * frames.c (meta_frames_button_release_event): implement the various - actions for the 3*2 new kinds of button. (#96229) - - * frames.c (meta_frames_update_prelit_control, - meta_frames_motion_notify_event): extend existing motion - notifications for buttons to the 3*2 new kinds of button. (#96229) - - * frames.c (meta_frames_set_window_background): handle specified - background colours and alpha transparency. (#151261) - - * frames.h (MetaFrameControl): New control types for the 3*2 new kinds - of button. (#96229) - - * iconcache.[ch] (meta_read_icons): use theme's fallback icons if a - window has no icon; use metacity's fallback icons only if the theme - does not provide any. (#11363) - - * iconcache.[ch] (meta_invalidate_default_icons (new function)): clear - icon cache on windows using default icons, and update them. (#11363) - - * main.c (main): added \n to error message. - - * prefs.c (button_function_from_string): extend for 3 new button - types. (#96229) - - * prefs.c (button_opposite_function (new function)): return a button - function's inverse (shade -> unshade, etc) (#96229) - - * prefs.c (update_button_layout): allocate space for a button's - inverse, if it has one. (#96229) - - * theme-parser.c (ParseState): add state for fallback icons (#11363) - - * theme-parser.c (ParseInfo): add format_version; remove - menu_icon_* (#114305) - - * theme-parser.c (parse_positive_integer): add lookup for integer - constants (#331356) - - * theme-parser.c (parse_rounding (new function)): parse window - rounding amount (#113162) - - * theme-parser.c (parse_alpha): don't set error if the number can't - be parsed since it'll already be set; change tolerance in comparison - from 1e6 to 1e-6 - - * theme-parser.c (parse_color (new function)): parse colour, including - possible constant lookup. - - * theme-parser.c (parse_toplevel_element): allow defining of various - new kinds of constant; allow - hide_buttons (#121639) and more detailed rounding attributes on - (#113162); allow background and alpha attributes on - ; (#151261) remove support for except as - stub; (#114305) add support for loading stock images (#113465); add - support for . (#11363)) - - * theme-parser.c (parse_draw_op_element): add from and to attribute - for arcs. (#121603) - - * theme-parser.c (parse_style_element): add check for theme version - supporting a button function. (#96229) - - * theme-parser.c (parse_style_set_element): add ability for shaded - windows to be resizable (#114304) - - * theme-parser.c (meta_theme_load): add theme versioning routine. - - * theme.c ( meta_frame_layout_get_borders): return rectangles for - the new 3*2 kinds of button, except where they're - inapplicable. (#96229) - - * theme.c (meta_frame_layout_calc_geometry): don't format buttons on - windows with no buttons (#121639); strip the 3*2 new kinds of button - correctly (#96229); allow variable amounts of rounding (#113162). - - * theme.c (meta_frame_style_new): set alpha to 255 by - default. (#151261) - - * theme.c (meta_frame_style_unref): free colour spec if - allocated. (#151261) - - * theme.c (meta_frame_style_validate): it's only an error not to - include a button if that button is valid in the current - theme. (#96229) - - * theme.c (button_rect): return rectangles for the new 3*2 kinds - of button. (#96229) - - * theme.c (meta_frame_style_set_unref): free differently resizable - shaded styles. (#114304) - - * theme.c (get_style): look up differently resizable styles - for shaded windows. (#114304) - - * theme.c (free_menu_ops (removed function), get_menu_icon - (removed function), meta_theme_draw_menu_icon (removed function), - meta_menu_icon_type_from_string (removed function), - meta_menu_icon_type_to_string (removed function), - meta_theme_free, meta_theme_validate): removed menu icon code. (#114305) - - * theme.c (meta_theme_load_image): add size_of_theme_icons - parameter. (#113465) - - * theme.c (meta_theme_define_color_constant (new function), - meta_theme_lookup_color_constant (new function)): allow - definition of colour constants. (#129747) - - * theme.c (meta_button_type_from_string, meta_button_type_to_string): - add the 3*2 new kinds of button. (#96229) - - * theme.c (meta_theme_earliest_version_with_button (new function)): - return the theme version each button was introduced in. (#96229) - - * theme.h ( MetaFrameLayout): add "hide_buttons" flag (#121639) and - corner radiuses. (#113162) - - * theme.h (MetaFrameGeometry): add rectangles for the 3*2 new - buttons. (#96229) - - * theme.h (MetaButtonType): the 3*2 new buttons. (#96229) - - * theme.h (MetaFrameStyle): add window_background_color and - window_background_alpha so that we can specify background on a - . (#151261) - - * theme.h (MetaFrameStyleSet): shaded_styles gets resize - dimension. (#114304) - - * theme.h (MetaTheme): added format_version, color_constants - hash, (#129747) fallback_icon and fallback_mini_icon, (#11363) - and removed menu_icons. (#114305) - - * theme.h (META_THEME_ALLOWS (new macro)): return whether a theme - supports a given feature. Also, several macros representing - new features in v2. - - * ui.c (meta_ui_set_current_theme)): also invalidate default - icons. (#11363) - - * window.[ch] (meta_window_update_icon_now)): became - non-static. (#11363) - -2006-10-06 Elijah Newren - - * src/metacity-dialog.c (kill_window_question): Be nice to - translators; remove unnecessary markup from strings marked for - translation (oops, I missed this in my review before previous - commit) - -2006-10-06 Elijah Newren - - * src/metacity-dialog.c (kill_window_question): Patch from Bruno - Boaventura to improve the "Force Quit" dialog. #121936 - -2006-10-02 Elijah Newren - - Ignore edge resistance for size-increment windows when resizing - with the keyboard. #346782. - - * src/edge-resistance.c (apply_edge_resistance_to_each_side): - ignore edge resistance for size-increment windows when resizing - with the keyboard, (apply_edge_resistance_to_each_side, - meta_window_edge_resistance_for_move, - meta_window_edge_resistance_for_resize): pass a is_resize - parameter as well - -2006-10-01 Elijah Newren - - * src/display.c (meta_display_set_input_focus_window): - * src/window.c (meta_window_focus): - Don't require a push/pop trap around - meta_display_set_input_focus_window(), but rather move the - push/pop into that function surrounding the XSetInputFocus() call - directly. Follow up to #358514. - -2006-10-01 Elijah Newren - - * src/*.[ch]: Stick an emacs comment directive at the beginning of - all the code files so that people using emacs will be more likely - to get coding style correct in their patches. We still need a - similar vi directive. #358866 - -2006-10-01 Elijah Newren - - Patch from Carlo Wood to ensure that maximized and minimized - properties are maintained across restarts. #358042. - - * src/constraints.c (place_window_if_needed): fix up partial - maximization handling and add minimize_after_placement handling. - - * src/display.[ch] (struct MetaDisplay, meta_display_open): add a - new display->display_opening flag to allow handling startup - differently where needed. - - * src/window-props.c (reload_net_wm_state): handle - _net_wm_state_hidden as well, setting - window->minimize_after_placement appropriately - - * src/window.[ch] (struct MetaWindow, meta_window_new_with_attrs): - add a window->minimize_after_placement field - - * src/window.c (meta_window_new_with_attrs): only unminimize the - window and its transients if the display isn't being opened, - (unmaximize_window_before_freeing): don't reset the state unless - the window is becoming withdrawn, if the screen is being closed be - sure to save the unmaximized state of the window so the next - window manager can restore it - -2006-10-01 Elijah Newren - - * src/window-props.c (set_title_text): surround the - XDeleteProperty() call with a - meta_error_trap_push/meta_error_trap_pop pair to prevent a crash - when closing a remote instance of gedit (and perhaps other apps). - #358514. - -2006-10-01 Elijah Newren - - Fix longstanding focus bug with mouse (not sloppy) focus mode with - popup override-redirect windows, particularly mozilla and - firefox's location bar autocompletion. #357695. - - * src/display.c (event_callback -- EnterNotify & LeaveNotify events): - for mouse focus, defocus the focused window when the mouse enters - the desktop window rather than when the mouse leaves the focused - window. - - * doc/how-to-get-focus-right.txt: - update for the slightly nuanced definition of mouse focus (people - without a DESKTOP window like nautilus get sloppy focus behavior - now) - -2006-09-27 Elijah Newren - - * src/menu.c (var menuitems): Patch from Bruno Boaventura to add - notes to remind translators to keep translations in sync with - libwnck. #355620. - -2006-09-18 Elijah Newren - - * src/window.c (meta_window_show): Patch from Jens Granseuer to - fix c89 cleanness, again. #356631. - -2006-09-18 Elijah Newren - - * src/constraints.c (constrain_maximization): Ignore maximum size - hints when maximizing. Should fix #327543 (see comment 4 and comment - 5). - -2006-09-18 Elijah Newren - - * src/ui.c (filter_func): avoid a compilation warning by making - sure to return something. #348067 - -2006-09-18 Thomas Thurman - - Branched for Gnome 2.17. - - * configure.in: bump version to 2.17.0. - -2006-09-18 Thomas Thurman - - * configure.in: post-release bump to 2.16.3 - -2006-09-18 Thomas Thurman - - * NEWS: 2.16.2 release - -2006-09-18 Elijah Newren - - Partial audit to fix timestamp usage. One step towards fixing - #355180; see important comments in that bug. - - * src/core.[ch] (meta_core_unshade, meta_core_shade): - * src/delete.c (meta_window_present_delete_dialog, - delete_ping_timeout_func): - * src/display.[ch] (meta_display_open, meta_display_close, - event_callback, meta_display_begin_grab_op, - process_selection_clear, meta_display_unmanage_screen, - meta_display_unmanage_windows_for_screen): - * src/frames.c (meta_frames_button_press_event): - * src/keybindings.c (handle_toggle_shade): - * src/main.c (main): - * src/screen.[ch] (update_num_workspaces, meta_screen_new, - meta_screen_free, prefs_changed_callback): - * src/window.[ch] (meta_window_free, finish_minimize, - implement_showing, meta_window_show, meta_window_maximize, - meta_window_make_fullscreen_internal, - meta_window_unmake_fullscreen, meta_window_shade, - meta_window_unshade, window_activate, send_sync_request, - meta_window_client_message, menu_callback, - meta_window_update_keyboard_resize): - Remove usage of CurrentTime, meta_display_get_current_time() and - meta_display_get_current_time_roundtrip() where possible, or - document why it isn't possible, or at very least add a FIXME with - some explanation of my laziness and what needs to be done. - -2006-09-18 Elijah Newren - - * src/spring-model.c (on_end_move, model_is_calm): Patch from Maik - Beckmann to remove compilation warnings. Fixes #355876. - -2006-09-18 Elijah Newren - - * configure.in: Make detection of stable vs. unstable automatic - and based upon the version number. Partially based on patch from - Christian Hamar in #356122. Fixes #356122. - -2006-09-13 Elijah Newren - - * HACKING: update -- we depend on gtk+ >= 2.10 since Vincent's - July patches for #348633. - -2006-09-13 Elijah Newren - - * src/window.c (meta_window_show): Patch from Thomas Andersen to - make windows be stacked correctly before showing them, to prevent - flicker with focus stealing prevention. #332385. - -2006-09-13 Elijah Newren - - * src/common.h (MetaWindowMenuFunc): - * src/core.[ch] (meta_core_user_lower_and_unfocus, - meta_core_user_focus, meta_core_show_window_menu, - meta_core_begin_grab_op, meta_core_end_grab_op): - * src/delete.c (delete_ping_reply_func, delete_ping_timeout_func, - meta_window_delete): - * src/display.[ch] (struct MetaDisplay, struct MetaPingData, - sanity_check_timestamps, meta_display_open, event_callback, - meta_spew_event, meta_display_set_grab_op_cursor, - meta_display_begin_grab_op, meta_display_end_grab_op, - meta_display_ping_timeout, meta_display_ping_window, - process_pong_message, timestamp_too_old, - meta_display_set_input_focus_window): - * src/keybindings.[ch] (grab_keyboard, ungrab_keyboard, - meta_screen_grab_all_keys, meta_window_grab_all_keys, - meta_window_ungrab_all_keys, error_on_generic_command, - error_on_command, error_on_terminal_command): - * src/metacity-dialog.c (on_realize, warn_about_no_sm_support, - error_about_command, main): - * src/screen.[ch] (struct _MetaScreen, meta_screen_new, - meta_screen_show_desktop, meta_screen_apply_startup_properties): - * src/session.c (warn_about_lame_clients_and_finish_interact): - * src/window.[ch] (struct _MetaWindow, - intervening_user_event_occurred, window_activate, - meta_window_delete, meta_window_focus, - meta_window_send_icccm_message, meta_window_client_message, - menu_callback, meta_window_show_menu, struct EventScannerData, - check_use_this_motion_notify, meta_window_begin_grab_op, - meta_window_set_user_time): - * src/workspace.[ch] (focus_ancestor_or_mru_window, - meta_workspace_activate_with_focus, meta_workspace_activate, - meta_workspace_focus_default_window, - focus_ancestor_or_mru_window): - Fix issues on 64-bit machines with timestamps by using guint32 - (like gtk+ does) instead of Time. #348305 - -2006-09-12 Elijah Newren - - * src/theme.c (meta_gtk_arrow_from_string, - meta_gtk_arrow_to_string): patch from Bruno Boaventura de Oliveira - to fix a compiler warning about not handling GTK_ARRROW_NONE. - #355490. - -2006-09-12 Elijah Newren - - * src/compositor.c: Patch from Bruno Boaventura de Oliveira - Lacerda to fix warnings about unused function and global var. - #355489. - -2006-09-11 Thomas Thurman - - * configure.in: post-release bump to 2.16.2 - -2006-09-11 Thomas Thurman - - * NEWS: 2.16.1 release - -22006-09-09 Elijah Newren - - * src/display.c (meta_display_open): Fix build when XKB not found. - #354211 - -2006-09-09 Elijah Newren - - Avoid a stuck grab, preventing focus from being transferred - between windows. Thanks to Fryderyk Dziarmagowski for steps to - reproduce. Fixes at least part of #354422. - - * src/display.c (meta_display_begin_grab_op, - meta_display_end_grab_op): pass timestamp to - meta_screen_ungrab_all_keys, meta_screen_ungrab_all_keys, and - meta_window_ungrab_all_keys - - * src/keybindings.[ch] (grab_keyboard, ungrab_keyboard): add a - timestamp parameter and remove call to - meta_display_get_current_time(), (meta_screen_grab_all_keys, - meta_screen_ungrab_all_keys, meta_window_ungrab_all_keys): add a - timestamp parameter and pass it on to grab_keyboard and - ungrab_keyboard - -2006-09-07 Elijah Newren - - * src/constraints.c (update_onscreen_requirements): make sure - windows returning from fullscreen mode are constrained to be - "onscreen"; fixes #353699. - -2006-08-30 Colin Watson - - * src/window-props.c (reload_transient_for): Clear - window->xtransient_for after emitting the invalid window warning. - #353540 - -2006-09-07 Elijah Newren - - * src/metacity-dialog.c: Patch from Bruno Boaventura de Oliveira - Lacerda to replace copy_of_gdk_x11_window_set_user_time() with - gdk_x11_window_set_user_time(). We've long since adopted gtk+ >= - 2.6 as a dependency. #352293 - -2006-09-04 Thomas Thurman - - * configure.in: post-release version bump to 2.16.1 - -2006-09-04 Thomas Thurman - - * NEWS: 2.16.0 release - -2006-08-22 Elijah Newren - - * src/metacity-dialog.c (main): Patch from Jens Granseuer to fix - the build with c89/gcc 2.95. - -2006-08-21 Elijah Newren - - * NEWS: Oops, forgot to mention the translators in the 2.15.34 - release; add them retroactively - -2006-08-21 Elijah Newren - - * configure.in: post-release version bump to 2.15.55 - -2006-08-21 Elijah Newren - - * NEWS: 2.15.34 release - -2006-08-21 Elijah Newren - - Patch from Thomas Andersen to fix metacity-dialog handling of - arguments. #340690 - - * src/metacity-dialog.c (main): replace hackish argument parsing - with GOption parsing. Much nicer. :) - -2006-08-21 Elijah Newren - - Patch from Ed Catmur to fix keybindings with hex-values (coming - from special extended keyboard keys). #140448. - - * src/keybindings.c (struct _MetaKeyBinding): change keycode from - KeyCode to unsigned int (comment from Elijah: why???), - (reload_keycodes): only grab keysyms for keybindings that have - them, (count_bindings, rebuild_binding_table): bindings can be - valid either due to a valid keysym or a valid keycode, - (display_get_keybinding_action, meta_change_keygrab, - process_tab_grab, process_workspace_switch_grab): handle keycode - as well as keysym - - * src/prefs.[ch] (struct MetaKeyCombo, update_binding, - update_list_binding): handle keycode as well as keysym - - * src/ui.[ch] (meta_ui_accelerator_parse): new function special - cases strings of the form "0x[0-9a-fA-F]+" and otherwise calling - gtk_accelerator_parse(), (meta_ui_parse_accelerator, - meta_ui_parse_modifier): call meta_ui_accelerator_parse instead of - gtk_accelerator_parse. - -2006-08-21 Elijah Newren - - Allow drags & resizes to be reverted by hitting escape. Based on - patch from Thomas Andersen. #126497. - - * src/display.c (grab_op_is_mouse_only): new function, - (meta_display_begin_grab_op): grab the keyboard when moving or - resizing too so that we can get escape keypresses - - * src/display.h (struct _MetaDisplay): add a comment to remind - that grab_was_cancelled is only used in wireframe mode - - * src/keybindings.[ch] (process_mouse_move_resize_grab): add new - function for handling keypresses during mouse-only moving and - resizing, (meta_window_grab_all_keys): add a timestamp parameter - and pass it to meta_window_focus(), - (meta_display_process_key_event): make sure - process_mouse_move_resize_grab() gets called when needed, - (process_keyboard_move_grab, process_keyboard_resize_grab): - rearrange some code slightly and improve the comments to make it - more readable - -2006-08-21 Elijah Newren - - Fix several bugs with handling of fullscreen windows, causing them - to not actually be fullscreen. #343115 (and also #346927, - #350547, #351643, the recent additional WINE-related issue - mentioned on the mailing list, and probably others...) - - * src/constraints.c (setup_constraint_info): if a window tries to - resize to fullscreen-size and it has a fullscreen function but - isn't actually marked as fullscreen then assist it by marking it - as such, (constrain_fully_onscreen, constrain_titlebar_visible): - ignore this constraint for fullscreen windows since such windows - have a separate specialized constraint - - * src/stack.c (window_is_fullscreen_size, get_standalone_layer): - remove the old window_is_fullscreen_size() hack for detecting - windows to treat as fullscreen since it doesn't work well with the - new constraints framework (i.e. we needed a slightly different - hack) - - * src/window.[ch] (meta_window_new_with_addrs): shuffle the order - of adding the window to the stack and moveresizing the window - since moveresizing can cause stack changes if the window's initial - size is fullscreen size, (meta_window_make_fullscreen, - meta_window_make_fullscreen_internal): split - meta_window_make_fullscreen() similar to meta_window_maximize() so - that constraints can make use of it - -2006-08-19 Baptiste Mille-Mathias - - * src/stock_delete.png: Update the pixmap to a new one which - fit better with the other pixmaps of the menu. First patch in - metacity, woot! #345498 - -2006-08-18 Elijah Newren - - * src/tabpopup.c (meta_ui_tab_popup_new): Patch from Willie Walker - to restore the part of the patch that I should not have reverted - in #123372, in order to fix accessibility. #350624 - -2006-08-09 Elijah Newren - - * src/window.c (intervening_user_event_occurred): Vytautus Liuolia - totally rocks; he tested and debugged and tracked down where we - were using the focus window's net_wm_user_time even when it was - uninitialized. This may fix bug 311868 and others I've heard - about (with Valknut, IIRC). It definitely fixes the issues Vytas - was seeing with his single instance library. :-) - -2006-08-07 Elijah Newren - - * src/constraints.c (setup_constraint_info): patch from Stéphane - Rosi to allow moving maximized windows between xineramas again. - #323820 - -2006-08-07 Elijah Newren - - * configure.in: post-release version bump to 2.15.34 - -2006-08-07 Elijah Newren - - * NEWS: 2.15.21 release - -2006-08-07 Elijah Newren - - Add a constrain_titlebar_visible constraint; should fix both bug - 333328 and bug 345522. Not perfect (minor annoying snap pulling - windows back onscreen, plus an ugly hack almost as bad as the old - one), but tarballs are due in less than half an hour. ;-) - - * src/boxes.[ch] (meta_rectangle_overlaps_with_region): - new function - - * src/constraints.c (constrain_titlebar_visible): new function, - (enum ConstraintPriority, array all_constraints, - update_onscreen_requirements): various small changes to - accomodate the new function - - * src/edge-resistance.c: remove the infinite edge resistance, - which was a big hack of a way to workaround the lack of a - titlebar_visible constraint - - * src/window.[ch] (MetaWindow): new require_titlebar_visible - bitfield, (meta_window_new_with_attrs): initialized here - -2006-08-07 Elijah Newren - - * src/frames.c (meta_frames_button_press_event): Patch from Chris - Ball to not minimize in response to double clicks on the titlebar - when minimiziation should not be allowed. #347377 - -2006-08-07 Elijah Newren - - Patch from Björn Lindqvist to fix button lighting with dragged - clicks. #321474. - - * src/frames.c (meta_frames_button_press_event): update the - prelit_control, (meta_frames_button_release_event): some code - refactoring to simplify things a bit, and make sure to update the - prelit_control - -2006-08-07 Elijah Newren - - * src/keybindings.c (process_keyboard_move_grab): Patch from - Thomas Andersen to return the window to maximized state if the - window was "shaken loose" from maximized state during a resize but - the resize is later aborted. #346719. - -2006-08-07 Elijah Newren - - Patch from Vytautas Liuolia to react to _NET_STARTUP_ID changes, - as proposed for the new startup-notification/EWMH spec. #347515 - - * src/window-props.c (reload_net_startup_id): be sure to act on - the new id instead of just recording it - - * src/window.[ch] (window_activate, meta_window_activate, - meta_window_activate_with_workspace, meta_window_client_message): - change window_activate() to take a workspace parameter instead of - hardcoding to the current workspace, add - meta_window_activate_with_workspace() function needed by - reload_net_startup_id(). - -2006-08-07 Thomas Thurman - - * src/frames.h: add new MetaButtonSpace struct; use it for - close_rect, max_rect, min_rect and menu_rect. (#97703) - - * src/frames.c (control_rect, get_control): modify to support - the new fields in MetaButtonSpace. - - * src/theme.c (meta_frame_layout_get_borders, rect_for_function, - meta_frame_layout_calc_geometry, button_rect): add support for - the new fields in MetaButtonSpace. - -2006-08-07 Elijah Newren - - * src/screen.c (meta_screen_resize_func): patch from Dmitry - Timoshkov to make sure window features get recalculated when the - screen is resized via XRandR. Part of #346927. - -2006-08-04 Elijah Newren - - Patch from Dmitry Timoshkov to fix the heuristic for determining - if windows can be made fullscreen (needed for WINE and possible - also some legacy applications). Part of #346927. - - * src/window.c (recalc_window_features): ignore window decoration - when checking size for determing whether an unresizable window - should be allowed ot be considered for fullscreening - -2006-07-31 Björn Lindqvist - - * src/window.c: Make it so maximized windows do not have rounded - corners. #336850. - -2006-07-30 Jens Granseuer - - * src/tabpopup.c: Fix another C89 vs. C99 issue. #347621. - -2006-07-26 Vincent Untz - - * src/update-from-egg.sh: also kill this - -2006-07-25 Vincent Untz - - * src/Makefile.am, ui.c: Kill usage of libegg. #348633. - -2006-07-24 Thomas Thurman - - * configure.in: post-release version bump to 2.15.21 - -2006-07-24 Thomas Thurman - - * NEWS: 2.15.13 release - -2006-07-24 Björn Lindqvist - - * src/display.c (meta_display_grab_window_buttons): Grab - Alt+Shift+Button1 as well to partially fix operation ordering - issues when trying to snap-move windows. Part of #112478. - -2006-07-21 Thomas Thurman - - * ui.[ch] (filter_func): Avoid a case where a struct's - fields might be updated after it was freed. #348067. - -2006-07-10 Elijah Newren - - * configure.in: post-release version bump to 2.15.13 - -2006-07-10 Elijah Newren - - * NEWS: 2.15.8 release - -2006-06-12 Elijah Newren - - * configure.in: post-release version bump to 2.15.8 - -2006-06-12 Elijah Newren - - * NEWS: 2.15.5 release - -2006-06-10 Elijah Newren - - Patch from Aidan Delaney to tidy tabpopup.c by factoring out - tab_entry_new(). #166890. - - * src/tabpopup.c (tab_entry_new): new function, - (meta_ui_tab_popup_new): use tab_entry_new() to remove a big chunk - of code, plus a few other small cleanups. - -Tue Jun 6 12:46:42 2006 Søren Sandmann - - * configure.in (GETTEXT_PACKAGE): Bunp intltool requirement to - 0.35.0. - -2006-05-29 Elijah Newren - - * HACKING: Slightly more detailed instructions on setting up a - build environment to mention relevant development tools in - addition to the needed development libraries. - -Fri May 26 16:48:29 2006 Søren Sandmann - - * src/effects.c (meta_effect_run_unminimize): Run an unminimize effect - - * src/window.c (meta_window_unminimize): Store a "was_minimized" - boolean in the window. - - * src/window.c (meta_window_show): If the window was minimized, - run an unminimize animation. - - * src/c-window.c (meta_comp_window_run_unminimize): Add an - unminimize animation, running the minimize one in reverse. - -Fri May 26 14:55:07 2006 Søren Sandmann - - * src/c-window.c (meta_comp_window_run_focus): Rename from - _bounce() to _focus(). - -2006-05-26 Elijah Newren - - * src/display.c (meta_display_close): Fix a crash on exit/logout - from assuming a compositor would always exist - -2006-05-25 Elijah Newren - - * src/place.h: - * src/common.h: - Remove MetaWindowEdgePosition enum that isn't used anymore - -Thu May 25 15:56:43 2006 Søren Sandmann - - * src/effects.h (struct MetaEffect): Move duplicated window field - outside the union - - * src/compositor.c: delete duplicated code to get at the window. - -Thu May 25 15:17:29 2006 Søren Sandmann - - * src/c-window.c: Fix compilation in non-compositor case, by - moving the stack functions into the HAVE_COMPOSITOR defines. - -Thu May 25 15:11:58 2006 Søren Sandmann - - * src/c-window.h: Add a destroy notifier to the window. - - * src/c-screen.c (on_window_destroy): New function. - - * src/c-screen.c (meta_comp_screen_add_window): Use the destroy - notifier here. - - * src/c-window.c (generate_phases): New function. Simplify the - minimize animation a lot by generating all the rectangle - information into an array, then processing that. - -2006-05-25 Adam Jackson - - * src/c-window.c: - * src/c-window.h: - * src/compositor.c: - * src/compositor.h: - * src/effects.c: - * src/effects.h: - * src/spring-model.c: - * src/window.c: - Bounce on window focus. - -Wed May 24 22:15:01 2006 Søren Sandmann - - * src/compositor.c (do_effect): Make sure windows are kept on top - of the panel during minimize. - -Wed May 24 21:17:59 2006 Søren Sandmann - - * src/compositor.c (do_effect): Shrink the window instead of - explode it. - - * src/compositor.c (do_effect): don't read the frame if it is - NULL. - - * src/c-window.c (meta_comp_window_run_minimize): Resurrect the - shrinking minimize animation. - - * src/c-window.c (meta_comp_window_fade_in): Make dialogs 90% - translucent. - - * src/c-window.c (update_fade): End at end_fade, not 1.0. - -Wed May 24 19:15:45 2006 Søren Sandmann - - * src/c-window.c (cancel_fade): Add a fade-in animation when - windows are mapped. - -Wed May 24 16:37:11 2006 Søren Sandmann - - * src/c-window.c (private_metacity_window): New function - - * src/c-window.c (meta_comp_window_refresh_attrs): Map metacity's - own windows directly. - -Wed May 24 16:35:54 2006 Søren Sandmann - - * src/c-window.c (private_metacity_window): - -Wed May 24 14:36:42 2006 Søren Sandmann - - * src/c-window.c (meta_comp_window_{freeze,thaw}_stack: Add a - stack-freeze feature to CWindow. - - * src/c-screen.c (meta_comp_screen_restack): Don't restack if the - window is frozen. - -Wed May 24 13:09:49 2006 Søren Sandmann - - * src/c-window.c: Fix compilation in the non-composited case. - -Wed May 24 12:57:32 2006 Søren Sandmann - - * src/c-window.c (meta_comp_window_free): return TRUE when the - window is actually freed. - - * src/compositor.c (do_effect): Disable updating before exploding - the window. - - * src/c-window.c: Make MetaCompWindow refcounted. - - * src/c-window.[ch]: New functions meta_comp_window_{show,hide} - - * src/c-screen.c (meta_comp_screen_unmap): Call - meta_comp_window_hide() instead of directly setting the viewable - status of the node. - - * src/c-screen.c (meta_comp_screen_remove_window): Only remove the - window when it is actually freed. - -Wed May 24 12:45:21 2006 Søren Sandmann - - * src/c-screen.c: Delete unused meta_comp_screen_hide_window(). - -2006-05-23 Adam Jackson - - * src/c-window.c: - * src/c-window.h: - * src/compositor.c: - * src/effects.c: - * src/effects.h: - * src/window.c: - Move shrink effect code from compositor.c to c-window.c. Stubs for - restore effect. Notes in various places for where to hook in - other effects. - -Tue May 23 16:36:04 2006 Søren Sandmann - - * src/compositor.c (do_effect): Also use explode when windows close. - - * src/c-window.c (meta_comp_window_explode): Add refcounting to - comp window, and use it in the explosion effect - - * src/effects.h (struct MetaEffect): Add new MetaCloseEffect. - - * src/display.c (event_callback): Run it from the UnmapNotify - event handler. - -Tue May 23 15:23:58 2006 Søren Sandmann - - * src/c-window.c (send_sync_request): New function to send a sync - request to newly mapped windows. - (on_request_alarm): Show the window here. - -2006-05-23 Adam Jackson - - * src/effects.h: - Add more effect tokens. - -Mon May 22 17:35:52 2006 Søren Sandmann - - * src/effects.[ch]: Beginning of new layer that abstracts - transition effects. - - New functions: - (meta_push_effect_handler): Install an effect handler - (meta_pop_effect_handler): Remove last effect handler - (meta_effect_run_minimize): Create a minimize effect and pass it - to the handler. - (meta_effect_end): Called by handler when the effect is finished. - - * src/compositor.c: Move explosion code form there to src/c-window.c. - - * src/c-screen.c: Delete explosion related code. - -2006-05-22 Björn Lindqvist - - * common.h (enum MetaCursor): - * display.c (meta_display_create_x_cursor): Make mouse cursor when - moving windows become a hand. Fixes #337376. - -2006-05-19 Björn Lindqvist - - * frames.c: Fix a logic bug so that the whole titlebar becomes - sensitive to mouse clicks. Fixes #336320. - -2006-05-18 Björn Lindqvist - - * resizepopup.c: Remove the unused attributes resize_gravity, - width_inc, height_inc, min_width, min_height, frame_left, - frame_right, frame_top, frame_bottom, tick_origin_x, tick_origin_y - from the MetaResizePopup struct. Delete all code that references - those attributes. - -2006-05-15 Elijah Newren - - * configure.in: post-release version bump to 2.15.5 - -2006-05-15 Elijah Newren - - * NEWS: 2.15.3 release - -2006-05-15 Elijah Newren - - Revert the accessibility module loading workaround from Gnome - 2.6, since gtk+ has long since fixed this for us. #123372. - - * src/Makefile.am: remove METACITY_LIBDIR define - - * src/main.c (find_accessibility_module, - accessibility_invoke_module, accessibility_invoke, main): remove - the first three of these functions and all calls to them - - * src/tabpopup.c (meta_ui_tab_popup_new): not sure if this part of - 120025 needed to be reverted but doing the reversion, if wrong, is - the best way to get someone from the accessibility team to scream, - er, I mean comment. ;-) - -2006-05-15 Elijah Newren - - * src/screen.c (reload_xinerama_infos): Patch from - jylefort@FreeBSD.org to prevent a crash when changing resolution. - Fixes #340847. - -2006-05-15 Björn Lindqvist - - * places.[ch] (intcmp, window_get_edges, - get_windows_showing_on_same_screen, get_vertical_edges, - get_horizontal_edges, meta_window_find_next_vertical_edge, - meta_window_find_next_horizontal_edge, - meta_window_find_nearest_vertical_edge, - meta_window_find_nearest_horizontal_edge): Remove the preceeding - functions as they are all obsoleted by the new edge-resistance - stuff. Fixes #341561. - -2006-05-15 Paolo Borelli - - * src/prefs.c (update_binding): plug a small leak. - -2006-05-12 Elijah Newren - - * configure.in: I don't think we want a config file for the - no-gconf case; embedded people would prefer hard-coding things - into the binary - (http://mail.gnome.org/archives/metacity-devel-list/2006-May/msg00010.html) - -2006-04-25 Elijah Newren - - * HACKING: Clarify that gnome-common is needed now that autogen.sh - has been rewritten to use gnome-autogen.sh - -Fri May 5 12:50:58 2006 Søren Sandmann - - * src/c-window.c (has_counter): Some experimental code to handle - sync counter notifications on a window. - - * src/c-screen.c (meta_comp_screen_add_window): Pass a MetaDisplay - -2006-04-25 Elijah Newren - - Clear _NET_WM_VISIBLE_NAME (and the ICON_ equivalent) when no - longer being used. Fixes #330671. - - * src/window.[ch] (struct MetaWindow): new - using_net_wm_visible_name and using_net_wm_visible_icon_name bits, - (meta_window_new_with_attrs): initialize these new bits to false - - * src/window-props.c (set_title_text, set_window_title, set_icon_title): - if the _NET_WM_VISIBLE_(ICON_)NAME property was previously set but - doesn't need to be this time, make sure to clear it - -2006-04-25 Elijah Newren - - * rationales.txt: add three new tracker bugs - -Thu May 4 13:30:04 2006 Søren Sandmann - - * src/ui.h: Delete unused META_PRIORITY_COMPOSITE - - * src/ui.c: Delete argument from meta_ui_get_display(). - - * src/c-window.c: Remove the xid->window hashtable and associated - code. - - * src/c-screen.[ch]: Rename MetaScreenInfo to MetaCompScreen. Put the - xid->windows table here instaed of as a static variable. Also make - sure that CompWindows are freed when the screen is unredirected. - - * src/display.c: Delete non USE_GDK_DISPLAY case, as it didn't - work and hasn't been compiled for a long time. - - * src/display.[ch] (meta_display_open): Remove argument as it was - always NULL (and couldn't possibly be anything else in the - USE_GDK_DISPLAY case). - -Tue May 2 17:12:54 2006 Søren Sandmann - - * src/c-window.[ch]: New files - - * src/c-screen.c: Move WindowInfo struct to new c-window.[ch] - files. Delete various bits of obsolete, commented-out code. - -Fri Apr 28 12:53:23 2006 Søren Sandmann - - * src/core.c (get_window): New function. - * src/core.c: Use get_window() instead of cutted-and-pasted code - all over the place. - -2006-04-25 Elijah Newren - - * configure.in: post-release version bump to 2.15.3 - -2006-04-25 Elijah Newren - - * NEWS: 2.15.2 release - -2006-04-25 Elijah Newren - - * autogen.sh: Nuke the old version, copy one from gcalctool that - uses gnome-autogen.sh. Seems to fix the - translations-aren't-included-in-the-tarball problem. Fix from - Rodney in IRC. - -2006-04-25 Elijah Newren - - * configure.in: post-release version bump to 2.15.2 - -2006-04-25 Elijah Newren - - * NEWS: 2.15.1 release - * configure.in: belated post-release version bump to 2.15.1 - * src/Makefile.am: Include boxes.h so that control-center won't - fail to build #339708. - -2006-04-24 Elijah Newren - - * NEWS: 2.15.0 release - -2006-04-20 Brian Pepple - - #337951. - - * po/LINGUAS: New file listing all supported languages. - - * configure.in: Use po/LINGUAS instead of including all languages - directly in this file. See the wiki for more information: - http://live.gnome.org/GnomeGoals/PoLinguas. - -2006-04-19 Thomas Andersen - - * src/window-props.c (reload_transient_for): warn and ignore if - transient_for is set to a non-top-level window. Fixes #335524. - -2006-04-19 Björn Lindqvist - - * src/frames.c (struct CachedPixels, meta_frames_destroy, - invalidate_cache, generate_pixmap, populate_cache, - cached_pixels_draw, meta_frames_expose_event, - meta_frames_paint_to_drawable): - - Replace while loops iterating over sequences with for loops. Also, - replace the attributes in the CachedPixels struct with a list of - four CachedFramePiece:s, this allows iteration over the four - pixmaps instead of treating each one separately. Fixes #338359. - -2006-04-18 Björn Lindqvist - - * makefile.am: Add boxes.{c,h} to libmetacity_private - * src/theme-parser.c (check_expression): - * src/theme-viewer.c (run_position_expression_tests): - Use meta_rect (). - - * src/theme.c: Replace while loops iterating over sequences with - for loops. - - * src/theme.c, src/theme.h (struct _MetaPositionExprEnv, - meta_draw_op_draw, meta_draw_op_list_draw, - meta_theme_draw_menu_icon): Use MetaRectangles in function - prototypes instead of x, y, with, height ints where applicable. - -2006-04-18 Kjartan Maraas - - * configure.in: Remove obsolete entry for no_NO - * po/no.po: And the translation. - -2004-04-17 Thomas Thurman - - * keybindings.c (count_bindings, rebuild_binding_table): - * prefs.c (change_notify, screen_bindings, - window_bindings, init_bindings, update_binding, - find_and_update_list_binding, update_list_binding, - meta_prefs_get_window_binding): Allow any keybinding pref - to be specified either with , a string, or _list, - a list of strings, or both. Fixes #164831. - -2006-04-16 Elijah Newren - - Patch from Dan Sanders to fix #334899. - - * window.c (meta_window_new_with_attrs): Unminimize ancestors of - new windows when mapped; this prevents e.g. confirmation windows - from causing applications to appear locked when closing via the - window list. - -2006-04-15 Elijah Newren - - Patch from Dan Sanders to fix #335076. - - * src/core.c (meta_core_maximize, meta_core_toggle_maximize, - meta_core_unmaximize): - * src/window.c (meta_window_client_message): - Raise windows on maximize/unmaximize. - -2006-04-15 Elijah Newren - - * src/display.h: Patch from Andy Morum to fix the build with - --disable-xsync. #336605 - -2006-04-14 Elijah Newren - - * HACKING: Include instructions on setting up a minimal - building/testing environment - -2006-04-14 Thomas Thurman - - Add a tabbing function, bound to alt-f6 by default, to cycle - through the windows of the current application. Fixes #94682. - - * src/common.h: two new MetaGrabOpts values for group switching - * src/display.c (ping_data_free, meta_display_in_grab_op, - IN_TAB_CHAIN): adapt to new MetaGrabOpts - * src/display.h: new enum value for MetaTabList for group switching - * src/keybindings.c (meta_display_process_key_event): - adapt to new MetaGrabOpts - (process_tab_grab): adapt to new MetaGrabOpts, and use switch - statement for cancelling instead of if statement - * src/metacity.schemas.in: new keybindings - * src/prefs.c, src/prefs.h: handle new keybindings - * src/window.h: define META_WINDOW_IN_GROUP_TAB_CHAIN macro - -2006-04-14 Elijah Newren - - * HACKING: Include reasons why gdk/gtk.h and core includes like - display.h/window.h must be kept separate. Taken from a private - email from Havoc. - -2006-04-13 Alejandro Andres - - * README: Fixed broken links. #333303 - -Thu Apr 13 12:23:28 2006 Søren Sandmann - - * src/c-screen.c (meta_screen_info_add_window): Check for both - POPUP and DROPDOWN. - -2006-04-13 Björn Lindqvist - - * src/async-getprop.c, src/async-getprop.h - (async_get_property_handler, ag_task_get_reply_and_free): - * src/testasyncgetprop.c (try_get_reply, run_speed_comparison): - Change unsigned chars to chars. - - * src/display.h (struct MetaDisplay): - * src/keybindings.c (reload_modmap): - Change unsigned ints to ints. - - * src/screen.c (set_workspace_names) - * src/stack.c (meta_stack_sync_to_server): - * src/xprops.c (utf8_string_from_results, utf8_list_from_results, - class_hint_from_results, meta_prop_get_values): - Introduce casts. - - Add a number of casts and change signedness on a number of - variables so that Metacity compiles with many fewer - warnings. Fixes #336032. - -2006-04-12 Elijah Newren - - Patch from Ron Yorston to add a focus_new_windows option. Default - is 'smart' (focus by default but normal focus-stealing-prevention - can kick in); 'strict' is current other choice (like 'smart' - except that programs launched by the terminal will not be - focused). Fixes remainder of #326159. Should also close #152004 - and a bunch of others. - - * src/common.h: - Add a MetaFocusNewWindows enum giving the current types allowed - - * src/display.h: - Update docs on allow_terminal_deactivation to note that it is only - relevant when focus_new_windows is 'strict' - - * src/metacity.schemas.in: add the new gconf key and explanation - - * src/prefs.[ch] (#define KEY_FOCUS_NEW_WINDOWS, static gboolean - focus_new_windows, update_focus_new_windows, meta_prefs_init, - change_notify, meta_prefs_get_focus_new_windows, - meta_preference_to_string): - Add all the normal preference handling stuff for this new - focus-new-windows option. - - * src/window.c (window_state_on_map, meta_window_set_user_time): - Don't focus windows launched from a terminal - -Mon Apr 10 16:44:51 2006 Søren Sandmann - - * src/c-screen.c (is_menu): Check if the window is a menu and make - it 90% opaque in that case. - - * src/c-screen.c (claim_selection): Handle CM_Sn selection - properly. - - * src/c-screen.c: Remove debug spew - - * src/screen.c (meta_screen_composite_all_windows): Remove debug spew - -2006-04-10 Björn Lindqvist - - * display.c (meta_display_open, event_callback): - * ui.c (meta_ui_get_double_click_timeout): - - Delete dead code that used to handle double click on the - titlebar. Remove the attributes last_button_time, - last_button_xwindow, last_button_num and is_double_click from - MetaDisplay and the functions meta_ui_get_double_click_timeout() - and meta_display_is_double_click() from their respective - files. Fixes #337507. - -2006-03-27 Gora Mohanty - - * src/metacity.schemas.in: - * src/theme.c: - Changes strings to make them more readable, and more translatable. - Fixes #335720. - -2006-04-02 Elijah Newren - - Fix constraints bug causing negative width windows and crashes. - #336651 - - * src/constraints.c (constrain_partially_onscreen): Don't - accidentally shove & resize the window by requiring more pixels to - be onscreen than the size of the window. - -Fri Mar 31 16:44:56 2006 Søren Sandmann - - * src/c-screen.c (meta_screen_info_unredirect): Release the GL - window here. Disconect from the magnifier, not the stacker. - -Fri Mar 31 12:24:26 2006 Søren Sandmann - - * src/c-screen.c (meta_screen_info_redirect): Only use magnifier - when USE_MAGNIFIER is set. - - * src/compositor.c (meta_compositor_free_window): Only wobble when - USE_WOBBLE is set. - -Fri Mar 31 12:13:21 2006 Søren Sandmann - - * src/c-screen.c (meta_screen_info_redirect): Don't hardcode - screen size. - -Thu Mar 30 17:01:12 2006 Søren Sandmann - - * src/compositor.c (struct MetaCompositor): Fix the memory - corruption in a better way. - -Thu Mar 30 16:38:35 2006 Søren Sandmann - - * src/compositor.c (meta_compositor_begin_move): Fix an illegal write. - -Thu Mar 30 16:13:52 2006 Søren Sandmann - - * composite.c: Turn wobbling back on Add new explosion effect. - -2006-03-29 Elijah Newren - - Fix grouping in the presence of ancestors; caught by Björn. - #336184 - - * src/group.c (meta_window_compute_group): Use new - meta_window_find_root_ancestor() function to get ancestor; for the - computed group, use the ancestor's group instead of the ancestor - itself - - * src/window.[ch] (meta_window_find_root_ancestor, - meta_window_raise): split meta_window_find_root_ancestor() - functionality of meta_window_raise() and make it available - elsewhere - -2006-03-29 Elijah Newren - - * rationales.txt: Add bugs about pointer warping; update - raise-on-click ones. - -2006-03-29 Thomas Thurman - - Abstract out the functions for setting/unsetting demands attention - hint and avoid doing it when the window isn't obscured. Fixes the - remainder of #305882. - - * src/window.c, src/window.h (meta_window_set_demands_attention, - meta_window_unset_demands_attention): new functions to mark a - window as needing or not needing the user's attention - * src/window.c (meta_window_show, window_activate, - meta_window_focus, meta_window_configure_request, - meta_window_client_message): use the new set/unset - demands attention functions. - -2006-03-29 Björn Lindqvist - - * src/resizepopup.c: - * src/resizepopup.h: - * src/window.c (meta_window_refresh_resize_popup): - Aggregate the x, y, width and height attributes of MetaResizePopup - to one MetaRectangle rect attribute and update code using the - MetaResizePopup struct. Fixes #335177. - -2006-03-28 Elijah Newren - - * MAINTAINERS: New file. #335026. ;-) - -Tue Mar 28 09:57:26 2006 Søren Sandmann - - * src/c-screen.c (meta_screen_info_add_window): Also check for overlay_window. - - * src/c-screen.c (meta_screen_info_redirect): Trap errors out of - unredirect(). - -2006-03-25 Thomas Thurman - - * src/window.c, src/window.h (update_net_wm_state, - update_mwm_hints, update_wm_class, update_transient_for): - deleted and moved into window-props.c - (meta_window_new_with_attrs): added constructing field - and four new initial properties (as above) - (meta_window_recalc_features, - meta_window_recalc_window_type): new functions - - * src/window-props.c (init_net_wm_state, reload_net_wm_state - init_mwm_hints, reload_mwm_hints, init_wm_class, - reload_mwm_class, init_transient_for, reload_transient_for): - new functions, moved in from window.c - - (meta_display_init_window_prop_hooks): initialise new properties - - Closes #309567. - -2006-03-25 Paolo Borelli - - * src/prefs.c: use g_str_has_prefix instead of a local copy - of the function. - -2006-03-16 Ray Strode - - Add patch from Elijah Newren to fix type - for compositing_manager schema entry (bug 335901) - - * src/metacity.schemas.in: Change type from "boolean" to "bool" - and default value from "FALSE" to "false" - -Wed Mar 22 13:16:48 2006 Søren Sandmann - - * src/compositor.c (meta_compositor_remove_window): Actually - remove the window. - - * src/c-screen.c (meta_screen_info_remove_window): Only remove - node if non-NULL - -Wed Mar 22 10:33:21 2006 Søren Sandmann - - * src/c-screen.c (meta_screen_info_redirect): Put a square below - the desktop stack. - -Mon Mar 20 11:50:44 2006 Søren Sandmann - - * src/c-screen.c (meta_screen_info_redirect): Put the desktop into - a magnifier. - - * src/c-screen.c (struct MetaScreenInfo): Add a CmMagnifier - - * src/c-screen.c (meta_screen_info_redirect): Move some of the gl - window related stuff here. - -2006-03-16 Soren Sandmann (sandmann@daimi.au.dk) - - * src/c-screen.c (meta_screen_info_set_target_rect): Put inside - COMPOSIT_EXTENSIONS - -2006-03-03 Thomas Thurman - - Always set _NET_WM_STATE when a window is shown or - hidden, even if it wasn't mapped. Fixes #315142. - - * src/window.c (meta_window_hide, meta_window_show): - call set_net_wm_state unconditionally - -2006-03-16 Elijah Newren - - Add debugging information for edge resistance - - * src/edge-resistance.c (cache_edges): print out the edges that - are being cached if in verbose mode, - (meta_window_edge_resistance_for_move, - meta_window_edge_resistance_for_resize): if edge resistance kicked - in then print out a message about it - - * src/util.c: - * src/util.h: - Add META_DEBUG_EDGE_RESISTANCE to MetaDebugTopic enum list - -Thu Mar 16 14:55:18 2006 Søren Sandmann - - * src/c-screen.c (struct WindowInfo): Maintain the size of the - window. - -Wed Mar 15 16:30:09 2006 Søren Sandmann - - * src/compositor.c (set_geometry): Use set_target_rect() instead - of set_size(). - - * src/c-screen.c: Add set_target_rect() as a way of scaling windows. - - * src/window.c (meta_window_handle_mouse_grab_op_event): Turn - updates on after a button release. - - * src/window.c (meta_window_move_resize_internal): Fix - indentation. - -Wed Mar 15 11:34:54 2006 Søren Sandmann - - * src/c-screen.c (meta_screen_info_add_window): Use unset_patch() - instead of unset_geometry(). - -Tue Mar 14 11:57:46 2006 Søren Sandmann - - * src/compositor.c: Comment out wobbling - - * src/compositor.c (blow_up): remove this function - - * src/compositor.c (process_configure_notify): Uncomment - set_size(). - - * src/c-screen.c (meta_screen_info_set_updates): When updates are - true, set all the properties such as size and shape. - - * src/c-screen.c (meta_screen_info_add_window): Create a special - WindowInfo structure for each window. - - * src/c-screen.c (meta_screen_info_set_size): Set size and output - shape of the drawable node. - -2006-03-13 Elijah Newren - - * README: - * configure.in: - Update to reflect that we're now targetting 2.15 development. - -2006-03-12 Thomas Thurman - - * src/window-props.c (set_title_text): Mark a particular - string for translation. #334332. - -2006-03-06 Ryan Lortie - - * src/window.c (meta_window_free): Only unmaximise window before - freeing if the window is actually maximised. #333563. - -Fri Mar 3 15:31:04 2006 Søren Sandmann - - * src/c-screen.c (meta_screen_info_new): Update for libcm API - change. - -Wed Mar 3 13:25:03 2006 Søren Sandmann - - * src/compositor.c, src/c-screen.[ch]: Split the ScreenInfo data - structure into separate, new files c-screen.[ch]. - - * src/errors.c (x_error_handler): Forward foreign errors to - foreign displays. - - * src/errors.c (meta_errors_register_foreign_display): Implement - this function - - * src/errors.h: Add new meta_errors_register_foreign_display() - -Tue Feb 28 14:49:23 2006 Søren Sandmann - - * src/compositor.c: Put the windows in a stacker rather than - do the traversing outselves. - -2006-02-27 Elijah Newren - - Patch from Thomas Thurman to prevent setting cycle_windows to - keybindings that won't work. #329676 - - * src/prefs.c (update_binding): - Make sure that bindings which require a modifier key are set to a - keybinding with one or else that the binding is reverted. - - * src/ui.[ch] (meta_ui_accelerator_name): - New function - -2006-02-27 Elijah Newren - - Patch from Thomas Thurman to work around buggy application - grouping with transient windows. #328211 - - * src/group.c (meta_window_compute_group): - Put transients in the same group with their parent, always. - - * src/window.c (update_transient_for): - Update group too - -2006-02-27 Elijah Newren - - * configure.in: - Patch from Sylvain Bertrand to fix build issues with library - search order. #330695. - -Sat Feb 25 14:50:17 2006 Søren Sandmann - - * src/window.c: Remove include of flash.h - -Sat Feb 25 11:46:14 2006 Søren Sandmann - - * src/display.c (meta_display_begin_grab_op): Call - meta_compositor_begin_move if there is a compositor - - * src/compositor.c (meta_compositor_begin/update/end_move): - Implement those functions. - - * src/spring-model.[ch]: New files - -Thu Feb 23 15:40:52 2006 Søren Sandmann - - * src/compositor.c (meta_compositor_manage_screen): Don't attempt - to manage the screen if it already is managed. - - * src/compositor.c (meta_compositor_unmanage_screen): Synchronize - the display. - -2006-02-19 Thomas Thurman - - Removed "move to another workspace" menu when there are - exactly two workspaces. Fixes #151183. - - * src/menu.c (meta_window_menu_new): clear - META_MENU_OP_WORKSPACES bit when n_workspaces==2 - -Fri Feb 17 11:56:35 2006 Søren Sandmann - - * src/screen.c (meta_screen_free): Only uncomposite the screen if - there is a compositor. - - * src/compositor.c (meta_compositor_new): Warn and fail if the - server doesn't have composite - -Thu Feb 16 18:57:48 2006 Søren Sandmann - - * src/compositor.c: Fix the build when --enable-compositor is - there. - -Thu Feb 16 15:54:48 2006 Søren Sandmann - - * src/compositor.c: Insert #ifdef's to make it build again - -Thu Feb 16 15:24:42 2006 Søren Sandmann - - * src/screen.c (meta_screen_composite_all_windows): New function. - - * src/prefs.[ch], src/metacity.schemas.in: Add new - compositing_manager key. - - * src/display.c (prefs_changed_callback): Handle - META_PREF_COMPOSITOR_MANAGER - - * src/display.c (event_callback): Only call - meta_compositor_process_event() if there is in fact a compositor. - - * src/display.c (enable/disable_compositor): Add code to - enable/disable compositor at runtime - -Wed Feb 15 18:42:03 2006 Søren Sandmann - - * src/compositor.[ch]: Add code to destroy compositor. Implement - unmanage_screen() functionality. - -Wed Feb 15 14:47:50 2006 Søren Sandmann - - * src/compositor.c (meta_compositor_unminimize): Add unused wobbly - unminimize animation by Kristian - - * src/compositor.c (meta_compositor_minimize): Add wobbly minimize - animation by Kristian. - - * src/compositor.c: Add support for turning updates on and off. - - * src/window.c (meta_window_move_resize_internal): Use - sync counter to make composited resizing tear free - -2006-02-14 Elijah Newren - - Patch from Jens Granseuer to fix more build issues with gcc 2.95. - #331166. - - * src/prefs.c (meta_prefs_init): - Remove C99 style variable initiailization - -2006-02-13 Elijah Newren - - * configure.in: post-release version bump to 2.13.144 - -2006-02-13 Elijah Newren - - * NEWS: 2.13.89 release - -2006-02-13 Elijah Newren - - * src/keybindings.c (process_tab_grab): - We had that prev_window code in multiple places and it was all - identical. Let's just stick it in one place to make the function - easier to read. - -2006-02-13 Thomas Thurman - - * src/keybindings.c (process_tab_grab): - Allow alt-escape to cancel alt-tabbing, and vice versa. Fixes - #141425. - -2006-02-11 Thomas Thurman - - Disable alt-f7 if a window can't be moved, and alt-f8 if it - can't be resized. Fixes #328920. - - * src/keybindings.c (handle_begin_move, handle_begin_resize): - check window->has_*_func before beginning operation - -2006-02-11 Elijah Newren - - Add a man page for metacity. Original version taken from Debian - (written by Thom May and Akira Tagoh) and updated by Luke Morton - and Philip O'Brien. Necessary auto-fu supplied by Philip O'Brien. - Fixes #321279. - -2006-02-11 Elijah Newren - - * src/stack.h (enum MetaStackLayer): - * src/stack.c (get_standalone_layer): - actually use META_LAYER_TOP but just manually make it equal to - META_LAYER_DOCK. Add a note point to the EWMH for why we do this. - #330717 - -2006-02-11 Elijah Newren - - * src/window.c (enum GnomeWinLayer): remove this legacy cruft that - we stopped using years ago - -2006-02-10 Thomas Thurman - - Avoid a memory leak when checking which workspace(s) a window is - on. Fixes #322059. - - * src/workspace.h (struct MetaWorkspace): - * src/workspace.c (meta_workspace_new, meta_workspace_free): - added list_containing_self member to MetaWorkspace - - * src/window.c (meta_window_get_workspaces): use - window->workspace->list_containing_self instead of allocating (and - leaking) such a list on the fly. - -2006-02-09 Thomas Thurman - - * src/testboxes.c (test_regions_okay, test_clamping_to_region): - add messages to explain that warnings are harmless - -Tue Feb 7 00:58:05 2006 Soeren Sandmann - - * src/compositor.c: Wrap fade code in #ifdef HAVE_COMPOSITE_EXTENSIONS - -Mon Feb 6 17:45:39 2006 Søren Sandmann - - * src/compositor.c: New fancy minimize animation. Fade windows in - and out. - -2006-02-03 Thomas Thurman - - * src/display.c (event_callback): produce warning when invalid - events with no timestamp are received, rather than failing an - assertion - -Thu Feb 2 17:58:22 2006 Søren Sandmann - - * compositor.c (process_map): update the pixmap. - (update) print out framerate. - (dump_stacking_order) new debug - function. - (meta_compositor_add_window) error trap fixes - (MiniInfo): Make the minimize animation fade out. - -2006-01-30 Elijah Newren - - * configure.in: post-release version bump to 2.13.89 - -2006-01-30 Elijah Newren - - * NEWS: 2.13.55 release - -2006-01-30 Elijah Newren - - * src/display.[ch] (struct MetaDisplay), meta_display_open, - meta_display_set_input_focus_window, - meta_display_focus_the_no_focus_window): Track the active_screen, - (event_callback): If the mouse enters a window on a different - screen, activate the default window on the new screen. May need - to be modified for click-to-focus; we'll wait for feedback. Fixes - #319348. - -2006-01-23 Elijah Newren - - * src/display.c (meta_display_check_threshold_reached): change the - order of the ||'ed items in the if to avoid using an uninitialized - value - - * src/prefs.c (meta_prefs_init): fix a couple uninitialized value - problems - -2006-01-21 Elijah Newren - - Patch from Christian Kirbach to prevent a critical warning crasher - when switching themes. #327847. - - * src/theme.c (meta_theme_free): since themes are only constructed - as needed and may be NULL, check for that before freeing theme - hash tables - -2006-01-21 Elijah Newren - - * src/common.h (enum MetaActionDoubleClickTitlebar): - * src/frames.c (meta_frames_button_press_event): - * src/prefs.c (action_double_click_titlebar_from_string): - * src/metacity.schemas.in: - Patch from Dick Marinus to add a minimize - double-click-titlebar-action; slightly modified to also include a - none action. #300210. - -2006-01-20 Elijah Newren - - * configure.in: post-release version bump to 2.13.55 - -2006-01-20 Elijah Newren - - * NEWS: 2.13.34 release - -2006-01-20 Elijah Newren - - * src/constraints.c (setup_constraint_info): fixed_directions is - only meant for explicit user interactions; disable it for - everything else. There are other bugs and improvements that could - be made with fixed_directions that I should be filing too, but at - least put a FIXME there for now--I'm so lame. Fixes #327822. - -2006-01-20 Elijah Newren - - Avoid flashing when closing a maximized window. Fixes #317254. - - * src/window.c (unmaximize_window_before_freeing): new function - that just fixes the net_wm_state and sends a configure_notify, - (meta_window_free): use unmaximize_window_before_freeing() instead - of meta_window_unmaximize() to avoid flicker - -2006-01-20 Elijah Newren - - Fix unitialized value problem when in raise-on-click mode. Søren, - #327572. - - * src/display.c (meta_display_check_threshold_reached): make - function be a no op if raise_on_click!=FALSE - - * src/display.h (struct MetaDisplay): point out that - grab_initial_[xy] and grab_threshold_movement_reached are only for - raise_on_click==FALSE mode. - -2006-01-20 Elijah Newren - - Patch from Søren to fix some reading-from-free'd-data errors. - #327575 - - * src/edge-resistance.c (meta_display_cleanup_edges): store the - edges in a hash table so that we can still read their values - within the loop from the other array they are stored in, then free - them all at the end. - -2006-01-20 Elijah Newren - - Fix various initialization and default issues, especially for - --disable-gconf. Make --disable-gconf actually work. #326661. - - * configure.in: Fix compilation with --disable-gconf - * src/metacity.schemas.in: Add a note that if any defaults are - changed in this file, src/prefs.c may need to be updated to - reflect the change - * src/prefs.c: set various static global vars to the right default - value, (meta_prefs_init): get the titlebar_font and current_theme - handled better when not using gconf, (struct MetaSimpleKeyMapping, - screen_string_bindings, window_string_bindings): helper vars to - allow some keybindings to work even without gconf, - (init_bindings): initialize bindings for the without-gconf case - too, (init_commands): make sure these are all NULL for the - non-gconf case so that we don't access random memory, - (init_workspace_names): just give these all a default name for the - non-gconf case, - (meta_prefs_change_workspace_name): actually change the name for - the non-gconf case too - -2006-01-20 Elijah Newren - - More careful error handling of values returned by GConf. Fixes - #326615. - - * src/prefs.c (get_bool): new helper function, (meta_prefs_init): - use get_bool to handle the case of a gconf key not existing, - (update_cursor_size): sanity check for sane values - -2006-01-20 Elijah Newren - - Prevent rapidly repeated visual bells from hanging metacity. - Fixes #322032. - - * src/display.h (struct MetaDisplay): add a last_bell_time field, - (XSERVER_TIME_IS_BEFORE_ASSUMING_REAL_TIMESTAMPS macro, - XERVER_TIME_IS_BEFORE macro): add parentheses around usage of - macro parameter - - * src/display.c (meta_display_open): initialize last_bell_time, - (event_callback): don't allow more than one bell per second - -2006-01-20 Elijah Newren - - * src/async-getprop.c: - * src/common.h: - * src/display.c: - * src/eggaccelerators.c: - * src/frames.c: - * src/gradient.c: - * src/iconcache.c: - * src/keybindings.c: - * src/metaaccellabel.c: - * src/place.c: - * src/prefs.c: - * src/preview-widget.c: - * src/screen.c: - * src/session.c: - * src/stack.c: - * src/tabpopup.c: - * src/theme-viewer.c: - * src/theme.c: - * src/window-props.c: - * src/window.c: - * src/workspace.c: - * src/tools/metacity-window-demo.c: - * src/wm-tester/test-gravity.c: - * src/wm-tester/test-resizing.c: - * src/wm-tester/test-size-hints.c: - Patch from Kjartan Maraas to fix a lot of tiny issues (unused - variable removal, making unused variables used again, correction - of types passed/declared for printf arguments, removal of unneeded - breaks and returns, dead code removal, dead code revival, renaming - to prevent shadowed variables, declaring unexported functions as - static) spotted by the intel compiler. #321439 - -2006-01-20 Elijah Newren - - Patch from Björn Lindqvist to fix #98340. - - * src/screen.c (meta_screen_ensure_tab_popup): Make sure an - outline border is shown even if a window frame's width is 0. - Also, correctly handle window outlines in showing desktop mode. - -Fri Jan 20 16:42:25 2006 Søren Sandmann - - * src/compositor.c: Make minimize animation update again. - -Thu Jan 19 18:05:47 2006 Søren Sandmann - - * src/compositor.c (meta_compositor_manage_screen): - g_object_unref() rather than ws_region_unref(). - -Thu Jan 19 16:50:50 2006 Søren Sandmann - - * src/compositor.c: Port to changes in libcm - -Tue Jan 17 17:25:29 2006 Søren Sandmann - - * src/compositor.c: Port to changes in libcm. - -2006-01-16 Elijah Newren - - * src/window-props.c: manually define HOST_NAME_MAX if not already - defined to fix Solaris compilation issue. Caught by Damien - Carbery, patch from Havoc. #326745 - -2006-01-16 Elijah Newren - - * configure.in: post-release version bump to 2.13.34 - -2006-01-16 Elijah Newren - - * NEWS: 2.13.21 release - -Mon Jan 16 11:55:20 2006 Søren Sandmann - - * src/compositor.c (meta_compositor_manage_screen): Really turn - off draw-in-a-loop. - -2006-01-15 Kyle Ambroff - - * src/workspace.c (focus_ancestor_or_mru_window): - If no valid window is found in the MRU list, then set focus to the - desktop window. (#317405) - -2006-01-15 Elijah Newren - - Fix accidental overzealous focus holding by the terminal - introduced by the original patch in bug 326159. Windows launched - from panel icons, the panel menu, or global keybindings should get - focus now. #326159. - - * src/display.c (meta_display_open, event_callback): - * src/display.h (struct MetaDisplay): - * src/keybindings.c (process_event): - * src/window.c (meta_window_set_user_time): - Add a new allow_terminal_deactivation field to MetaDisplay and use - it to track whether the user's last action was interaction with - the terminal or some outside action (global keybinding, clicking - on a dock, etc.) likely to launch a new window. - - * src/window.c (window_state_on_map): - Allow the focus switch from a terminal to something else if - allow_terminal_deactiviation is true. - - * src/keybindings.c (handle_panel_keybinding): - Remove some unneeded code. - -2006-01-15 Elijah Newren - - Patch from Jens Granseuer to fix more build issues with gcc 2.95. - #327050. - - * src/boxes.c (meta_rectangle_edge_cmp_ignore_type): - * src/window.c (meta_window_show): - Remove C99 style variable initiailization - -2006-01-14 Elijah Newren - - * src/window.c (__window_is_terminal): Don't dereference a NULL - string. Fixes #327013. - -2006-01-14 Elijah Newren - - * src/compositor.[ch]: fix compilation when - HAVE_COMPOSITE_EXTENSIONS is undefined. #326912 - -Fri Jan 13 16:37:26 2006 Søren Sandmann - - * src/compositor.c (update): Only update on damage events. - -2006-01-13 Elijah Newren - - Patch from Damien Carbery. Fixes #326746. - - * src/util.c: explicitly #include Xlib.h to fix a compilation - issue on Solaris. - -Fri Jan 13 14:40:19 2006 Søren Sandmann - - * configure.in: Add a dependency on libcm when building with - compositor. - - * src/window.c (meta_window_hide): Make this function static. - - * src/window.c (implement_showing): Use meta_compositor_minimize() - to do a weird minimize effect. - - * src/compositor.[ch]: Beginning of new GL based compositor. - - * src/screen.h (struct _MetaScreen): Add void pointer to - compositor data. - - * src/screen.c (meta_screen_new): Remove obsolete compositor - stuff; initialize compositor_data. Don't composite manage screen - out of this function. - - * src/errors.c (x_error_handler): Check that display is non-NULL - before using it. Add comment about how that can happen. - - * src/display.c (meta_display_{begin,end}_grab_op): Remove - explicity damage of windows. - - * src/display.c (meta_display_open): Composite manage all the - screens. - -2006-01-11 Elijah Newren - - * src/textboxes.c (test_area, test_intersect, test_equal, - test_overlap_funcs, test_basic_fitting, test_merge_regions, - test_regions_okay, test_region_fitting, test_clamping_to_region, - test_clipping_to_region, test_shoving_into_region, - test_find_onscreen_edges, - test_find_nonintersected_xinerama_edges, test_gravity_resize, - test_find_closest_point_to_line): - Replace __PRETTY_FUNCTION__ with G_STRFUNC, because lesser - compilers don't support the former. Caught by Damien Carbery, fix - suggested by Ray Strode. #326281. - -2006-01-10 Elijah Newren - - * configure.in: post-release version bump to 2.13.21 - -2006-01-10 Elijah Newren - - * NEWS: 2.13.13 release - -2006-01-10 Elijah Newren - - * src/bell.c: - * src/boxes.c: - * src/boxes.h: - * src/constraints.c: - * src/core.c: - * src/display.c: - * src/display.h: - * src/edge-resistance.c: - * src/frames.c: - * src/keybindings.c: - * src/main.c: - * src/prefs.c: - * src/prefs.h: - * src/screen.c: - * src/screen.h: - * src/window.c: - * src/window.h: - Whoops, I forgot to keep my copyright info updated with my previous - commits as Havoc had asked me to do. Doing that now... - -2006-01-10 Elijah Newren - - Add a raise on click option, basically only because all the major - distros are patching it in anyway. See #326156. - - * src/metacity.schemas.in: add the new gconf key and explanation - - * src/prefs.[ch] (#define KEY_RAISE_ON_CLICK, static gboolean - raise_on_click, update_raise_on_click, meta_prefs_init, - change_notify, meta_prefs_get_raise_on_click, - meta_preference_to_string): - Add all the normal preference handling stuff for this new - raise-on-click option. - - * src/core.c (meta_core_show_window_menu): - * src/display.c (event_callback, meta_display_begin_grab_op): - * src/window.c (window_activate, meta_window_configure_request, ): - Only raise the window if in raise_on_click mode. - - * src/display.c (meta_display_begin_grab_op, - meta_display_end_grab_op, meta_display_check_threshold_reached): - * src/display.h (struct MetaDisplay): - * src/window.c (meta_window_handle_mouse_grab_op_event): - if not in raise-on-click mode only raise on button release if the - click didn't start a move or resize operation; needs a few extra - MetaDisplay fields to handle this - - * src/core.c (meta_core_user_lower_and_unfocus): - no need to do the MRU shuffling if not maintaining the stacking - order == MRU order invariant - - * src/frames.c (meta_frames_button_press_event): - * src/window.c (meta_window_begin_grab_op): - remove an unneeded window raising that is already handled elsewhere - -2006-01-10 Elijah Newren - - Don't "steal" focus from terminal windows for new window mappings - as the difference in usage between terminals and other apps seems - to suggest this difference in treatment. See #326159 for details, - feedback welcome. - - * src/window.[ch] (__window_is_terminal): New function, currently - an ugly hack and should be replaced by a new property set by - applications if the behavior works to our liking, - (window_state_on_map): don't transfer focus to new windows from - terminals unless the new window is a transient of the focused - terminal - - * src/keybindigns.c (handle_panel_keybinding): panel run dialog - keybinding should be counted as an explicit transfer of focus to - the new window, so override the - don't-transfer-focus-from-terminals in this case - -2006-01-09 Elijah Newren - - More thorough handling of source indication. Part of #326041. - - * src/window.c (window_activate): new function based off the old - meta_window_activate but which also takes source indication into - account, (meta_window_active): just call window_activate() with - the necessary source indication to get the behavior wanted, - (meta_window_client_message): check source indication too for - _net_active_window messages - - * src/window.h (enum MetaClientType): convenience enum for source - indication handling - -2006-01-09 Elijah Newren - - Make the taskbar less flash happy and fix up some related stacking - issues. #326035. - - * src/window.c (windows_overlap): new function, - (meta_window_show): if a window is denied focus but doesn't - overlap with the focus window there is no need to set the demands - attention hint nor stack that window below the focus window, - (meta_window_get_outer_rect): we're not modifying the window so - declare it to be const - -2006-01-09 Elijah Newren - - Fix window outline for minimized windows when using alt-esc. - #325092. - - * src/display.c (meta_display_begin_grab_op): Specify the showing - type of tabbing operation (Alt tab vs. alt-esc) in addition to the - listing type of tabbing operation (docks vs normal windows) to - meta_screen_ensure_tab_popup(). - - * src/display.h (enum MetaTabShowType): new convenience enum - - * src/screen.[ch] (meta_screen_ensure_tab_popup): require the - showing type be specified in addition to the tabbing type; put the - outline around the window instead of the icon when in alt-esc - mode. - -2006-01-09 Elijah Newren - - Fix reduced resources resize handling for windows with sizing or - resizing constraints. #325774. - - * src/display.c (meta_display_end_grab_op): Provide constraints.c - with the correct gravity information. - -2006-01-09 Elijah Newren - - Be more strict about what is considered a valid region with - partial struts. Fixes #322070. - - * src/boxes.[ch]: - (meta_rectangle_expand_region_conditionally): - new function behaving like meta_rectangle_expand_region() but - which only does so when the width and height of the rectangles - meet a certain threshold - - (replace_rect_with_list): - Remove a compiling warning - - * src/constraints.c: - (constrain_partially_onscreen): - provide minimum thresholds in each direction for the size of the - rectangles to avoid cases where only a single pixel thick layer of - a window might be showing - -2006-01-09 Elijah Newren - - * src/bell.c (meta_bell_notify_frame_destroy): Use the right - function to remove the timeout so that we don't crash if removed - at an inopportune time. Fixes #322031. - -2006-01-09 Elijah Newren - - * src/edge-resistance.c (apply_edge_resistance): Remove the - "pull-away" edge resistance. Fixes another of the zillions of - issues covered in #321905. - -2006-01-09 Elijah Newren - - * src/edge-resistance.c (apply_edge_resistance): Revert to the old - edge resistance behavior for keyboard movement/resizing based - resistance. Not only makes the code much simpler and shorter, but - also fixes another of the zillions of issues covered in #321905. - -2006-01-09 Elijah Newren - - * src/edge-resistance.c (apply_edge_resistance): Remove the - timeout resistance at screen/xinerama edges for the whiners. - Okay, it made sense. Fixes another of the zillions of issues - covered in #321905. - -2006-01-09 Elijah Newren - - * src/edge-resistance.c (apply_edge_resistance): Make extra - timeout edge resistance apply even if one edge already offscreen. - Fixes another of the zillions of issues covered in #321905. - -2006-01-09 Elijah Newren - - Allow edge resistance at both sides of a window and also when - edges don't overlap but are a single pixel away from doing so. - Fixes one of the zillions of issues covered in #321905. - - * src/boxes.[ch]: - (meta_rectangle_edges_align): - new function to handle the overlap or off by one determining - whether edge resistance should kick in for an edge. - - (meta_rectangle_edge_cmp_ignore_type): - new function to sort edges but ignore the type so that e.g. left & - right edges of windows can be used interchangeably. - - (meta_rectangle_edge_cmp): - now uses meta_rectangle_edge_cmp_ignore_type() to do most the work - and just adds an extra condition - - * src/edge-resistance.c: - (find_nearest_position): - use meta_rectangle_edges_align() now to determine whether the - edges align, - - (apply_edge_resistance, apply_edge_resistance_to_each_side): - have the edge resistance kick in if either the beginning or ending - positions would cause overlap in the given direction -- fixes an - uncommon but annoying corner case, - - (apply_edge_snapping, apply_edge_resistance_to_each_side, - meta_display_cleanup_edges, - stupid_sort_requiring_extra_pointer_dereference, cache_edges): - mix edges from both sides now - -2006-01-09 Elijah Newren - - Plug a few leaks. Fixes #309178. - - * src/main.c (main): remove an unneeded g_set_prgname() call, free - some strings allocated by the GOptions parsing - -2006-01-02 Elijah Newren - - Patch from Björn Lindqvist to fix a logic error. #322149. - - * src/window.c (update_resize): && should have been ||. - -2006-01-02 Elijah Newren - - Patch from Jens Granseuer to fix build with gcc 2.95. #322622. - - * src/boxes.c (meta_rectangle_region_to_string, - meta_rectangle_edge_list_to_string, fix_up_edges): - * src/constraints.c (meta_window_constrain, setup_constraint_info, - place_window_if_needed, constrain_maximization, - constrain_fullscreen, constrain_size_increments, - constrain_size_limits, constrain_aspect_ratio, - do_screen_and_xinerama_relative_constrai, - constrain_to_single_xinerama, constrain_fully_onscreen, - constrain_partially_onscreen): - * src/edge-resistance.c (find_nearest_position, - apply_edge_resistance, apply_edge_resistance_to_each_side): - * src/testboxes.c (test_clamping_to_region, - test_clipping_to_region, test_shoving_into_region): - * src/window.c (meta_window_new_with_attrs, - meta_window_apply_session_info, meta_window_resize, - meta_window_resize_with_gravity, meta_window_configure_request): - Remove C99 style variable initiailization - -2006-01-02 Elijah Newren - - * configure.in: post-release version bump to 2.13.13 - -2006-01-02 Elijah Newren - - * NEWS: 2.13.8 release - -2005-12-27 Elijah Newren - - Make the workspace switcher work with dual-head (non-xinerama) - setups. Fixes #319423. - - * src/display.c (meta_display_open, event_callback, - meta_display_focus_the_no_focus_window): - * src/display.h (struct MetaDisplay, - meta_display_focus_the_no_focus_window): - * src/keybindings.c (primary_modifier_still_pressed): - * src/screen.c (meta_screen_new): - * src/screen.h (struct MetaScreen): - * src/window.c (meta_window_new_with_attrs, meta_window_show): - * src/workspace.c (meta_workspace_focus_default_window): - Replace display->no_focus_window with a no_focus_window for each - screen. - - * src/display.[ch] (meta_display_xwindow_is_a_no_focus_window, - event_callback): - * src/window.c (meta_window_new_with_attrs): - New utility function, meta_display_xwindow_is_a_no_focus_window(), - for checking if the given xwindow is a no_focus_window for one of - the screens. - -2005-12-27 Elijah Newren - - * src/tabpopup.c (meta_ui_tab_popup_new): since the title is going - to be treated as markup, escape it. Fixes #324846. - -2005-12-13 Kang Jeong-Hee - - * src/compositor.c: replace old call to width and height - of MetaScreen struct with rect.width and rect.height. - Now compile ok. - * src/delete.c: make an int variable into unsigned int. - Now compile warning has gone. - -2005-12-12 Elijah Newren - - * configure.in: post-release version bump to 2.13.8 - -2005-12-12 Elijah Newren - - * NEWS: 2.13.5 release - -2005-12-12 Elijah Newren - - * src/window.c (update_net_frame_extents): make the debugging - message actually correspond to the code. Patch from Björn - Lindqvist. Fixes #322051. - -2005-11-29 Kjartan Maraas - - * src/screen.h: Make the wireframe a bit slimmer. - Closes bug #320051. - -2005-11-24 Davyd Madeley - - * src/window-props.c: display hostname in titlebar for remote X - clients. Closes bug #322202. - -2005-11-22 Elijah Newren - - * configure.in: post-release version bump to 2.13.5 - -2005-11-22 Elijah Newren - - * NEWS: 2.13.3 release - -2005-11-22 Elijah Newren - - Don't allow removing a window from maximized or fullscreened state - to place the titlebar under the top panel. Fixes #322075. - - * src/display.c (handle_net_moveresize_window): fix up previous - comments now that I know a little more, modify the code just - slightly to clarify that this is NOT a manual user move/resize - operation - - * src/window.c (meta_window_unmaximize, - meta_window_unmake_fullscreen, - meta_window_shove_titlebar_onscreen): - don't claim that these are manual user move/resize operations - -2005-11-21 Elijah Newren - - * src/constraints.c (constrain_partially_onscreen): Relax the - partially onscreen constraint to allow the titlebar to touch the - bottom panel in order to make the new constraints code function - the same as the old version. Fixes #322071. - -2005-11-21 Elijah Newren - - * src/constraints.c (place_window_if_needed): When updating the - xinerama due to placement, update which maximal/spanning rect set - to use as well. Fixes #322068. - -2005-11-21 Elijah Newren - - * doc/strut-and-related-updating.txt: It took me a little while to - figure out how struts & workareas are updated and to learn what - all the related functions were used for so I thought I'd clean up - my notes and make them available. This will probably be more - useful now since regions and edges are also computed and stored at - the same time as the workareas. - -2005-11-20 Elijah Newren - - * src/constraints.c (place_window_if_needed): compute the frame - geometry due to maximization only after actually maximizing. - Fixes #321902. - -2005-11-21 Davyd Madeley - - * src/edge-resistance.c (meta_display_compute_resistance_and_snap): - Use GPOINTER_TO_INT() macro instead of cast to allow compilation on - 64-bit architectures without warning. - -2005-11-19 Elijah Newren - - * src/edge-resistance.c (apply_edge_resistance): differentiate - between movement towards an edge and movement away from one. Pick - smaller constants for movement away from an edge. - -2005-11-19 Elijah Newren - - * configure.in: post-release version bump to 2.13.3 - -2005-11-19 Elijah Newren - - * NEWS: 2.13.2 release - -2005-11-18 Elijah Newren - - Merge of all the changes on the constraints_experiments branch. - This is just a summary, to get the full ChangeLog of those - changes (approx. 2000 lines): - cvs -q -z3 update -Pd -r constraints_experiments - cvs -q -z3 diff -pu -r CONSTRAINTS_EXPERIMENTS_BRANCHPOINT ChangeLog - - Bugs fixed: - unfiled - constraints.c is overly complicated[1] - unfiled - constraints.c is not robust when all constraints - cannot simultaneously be met (constraints need to be - prioritized) - unfiled - keep-titlebar-onscreen constraint is decoration - unaware (since get_outermost_onscreen_positions() - forgets to include decorations) - unfiled - keyboard snap-moving and snap-resizing snap to hidden - edges - 86644 - resize should have a shift option like move does - 109553 - gravity w/ simultaneous move & resize doesn't work - 113601 - maximize vertical and horizontal should toggle and be - constrained - 122196 - windows show up under vertical panels - 122670 - jerky/random resizing of window via keyboard[2] - 124582 - keyboard and mouse snap-resizing and snap-moving - erroneously moves the window multidimensionally - 136307 - don't allow apps to resize themselves off the screen - (*cough* filechooser *cough*) - 142016, 143784 - windows should not span multiple xineramas - unless placed there by the user - 143145 - clamp new windows to screensize and force them - onscreen, if they'll fit - 144126 - Handle pathological strut lists sanely[3] - 149867 - fixed aspect ratio windows are difficult to resize[4] - 152898 - make screen edges consistent; allow easy slamming of - windows into the left, right, and bottom edges of the - screen too. - 154706 - bouncing weirdness at screen edge with keyboard moving - or resizing - 156699 - avoid struts when placing windows, if possible (nasty - a11y blocker) - 302456 - dragging offscreen too restrictive - 304857 - wireframe moving off the top of the screen is misleading - 308521 - make uni-directional resizing easier with - alt-middle-drag and prevent the occasional super - annoying resize-the-wrong-side(s) behavior - 312007 - snap-resize moves windows with a minimum size - constraint - 312104 - resizing the top of a window can cause the bottom to - grow - 319351 - don't instantly snap on mouse-move-snapping, remove - braindeadedness of having order of releasing shift and - releasing button press matter so much - - [1] fixed in my opinion, anyway. - [2] Actually, it's not totally fixed--it's just annoying - instead of almost completely unusable. Matthias had a - suggestion that may fix the remainder of the problems (see - http://tinyurl.com/bwzuu). - [3] This bug was originally about not-quite-so-pathological - cases but was left open for the worse cases. The code from - the branch handles the remainder of the cases mentioned in - this bug. - [4] Actually, although it's far better there's still some minor - issues left: a slight drift that's only noticeable after - lots of resizing, and potential problems with partially - onscreen constraints due to not clearing any - fixed_directions flags (aspect ratio windows get resized in - both directions and thus aren't fixed in one of them) - - New feature: - 81704 - edge resistance for user move and resize operations; - in particular 3 different kinds of resistance are - implemented: - Pixel-Distance: window movement is resisted when it - aligns with an edge unless the movement is greater than - a threshold number of pixels - Timeout: window movement past an edge is prevented until - a certain amount of time has elapsed during the - operation since the first request to move it past that - edge - Keyboard-Buildup: when moving or resizing with the - keyboard, once a window is aligned with a certain edge - it cannot move past until the correct direction has - been pressed enough times (e.g. 2 or 3 times) - - Major changes: - - constraints.c has been rewritten; very few lines of code from - the old version remain. There is a comment near the top of - the function explaining the basics of how the new framework - works. A more detailed explanation can be found in - doc/how-constraints-works.txt - - edge-resistance.[ch] are new files implementing edge-resistance. - - boxes.[ch] are new files containing low-level error-prone - functions used heavily in constraints.c and edge-resistance.c, - among various places throughout the code. testboxes.c - contains a thorough testsuite for the boxes.[ch] functions - compiled into a program, testboxes. - - meta_window_move_resize_internal() *must* be told the gravity - of the associated operation (if it's just a move operation, - the gravity will be ignored, but for resize and move+resize - the correct value is needed) - - the craziness of different values that - meta_window_move_resize_internal() accepts has been documented - in a large comment at the beginning of the function. It may - be possible to clean this up some, but until then things will - remain as they were before--caller beware. - - screen and xinerama usable areas (i.e. places not covered by - e.g. panels) are cached in the workspace now, as are the - screen and xinerama edges. These get updated with the - workarea in src/workspace.c:ensure_work_areas_validated() - -2005-11-14 Elijah Newren - - * configure.in: post-release version bump to 2.13.2 - -2005-11-14 Elijah Newren - - * NEWS: 2.13.1 release - -2005-11-11 Aidan Delaney - - * src/tabpopup.h: (struct _MetaTabEntry): - * src/tabpopup.c: (meta_ui_tab_popup_new): - * src/screen.c: (meta_screen_ensure_tab_popup): - Changed the 'minimized' field of the MetaTabEntry struct to - 'hidden'. Fixes reopened bug #168455. - -2005-10-29 Kjartan Maraas - - * src/eventqueue.c: (meta_event_queue_new): Merge fix - for bug #320050 from stable. - -2005-10-27 Erdal Ronahi - - * configure.in: Added ku (Kurdish) to ALL_LINGUAS - -2005-10-25 Philip O'Brien - - * src/prefs.c (meta_preference_to_string): add handling for - META_PREF_CURSOR_THEME and META_PREF_CURSOR_SIZE for more complete - debug info - -2005-10-24 Elijah Newren - - * configure.in: post-release version bump to 2.13.1 - -2005-10-24 Elijah Newren - - * NEWS: 2.13.0 release - -2005-10-23 Elijah Newren - - Fix edge snapping for multi-screen (non-xinerama) setups. #319425 - - * src/place.c (get_windows_showing_on_same_screen, - get_vertical_edges, get_horizontal_edges): rename - get_windows_on_same_workspace() to - get_windows_showing_on_same_screen() - - * src/place.c (get_windows_showing_on_same_screen): exclude windows - in the list that are on a different screen - -2005-10-20 Elijah Newren - - * HACKING: Clarify why METACITY_VERBOSE=1 is bad without - META_USE_LOGFILE=1; point to bug 305091 for details. - -2005-10-13 Muktha - - * src/themes/Simple/metacity-theme-1.xml: Make the unfocussed - Simple window border visible with high contrast inverse theme. - Fixes #121361. - -2005-10-08 Elijah Newren - - Fix a crash that occurs when removing some virtual desktops and - windows happen to be on those desktops. #318306. - - * src/workspace.c (meta_workspace_relocate_windows): Since windows - cannot be on more than one workspace at a time, remove the window - from the old workspace before adding it to the new one. - -2005-10-08 Elijah Newren - - Add my copyright notice to a number of files on which it should - already exist. - -2005-10-03 Elijah Newren - - * src/metacity.schemas.in: clarify the meaning of the auto_raise - preference. Fixes one of the issues in #312421. - -2005-10-03 Elijah Newren - - Patch from Ross Cohen to make alt-esc consistent with alt-tab by - leaving stacking of unselected windows unchanged. Fixes #314285. - - * src/keybindings.c (process_tab_grab): before raising and showing - the next candidate, reset the stack positions to what they were - at the beginning of the grab - -2005-10-03 Elijah Newren - - Patch from Ross Cohen to make alt-esc (show windows instantly) - actually show minimized windows too. Fixes #107072. - - * src/keybindings.c (process_tab_grab): initialize tab_unminimized - to FALSE for the target window when starting the grab, when - advancing through the list check to find the previous window and - re-minimize it if it was tab-unminimized, unminimize the new - window we're alt-esc'ing to if it's minimized, (do_choose_window): - raise and unminimize the initial window as well in alt-esc'ing - - * src/window.h (struct _MetaWindow): add a tab_unminimized field - - * src/window.c (meta_window_new_with_attrs): initialize - tab_unminimized to false - -2005-10-03 Elijah Newren - - Branched for Gnome 2.13. :-) - - * configure.in: bump version to 2.13.0. Add UNSTABLE warning. - * README: add 2.13.x to the list of unstable branches - -2005-10-03 Elijah Newren - - A combination of a couple memory leaks fixes, from Kjartan, - Soeren, and I. Fixes #313030. - - * src/bell.c (meta_bell_flash_screen): call XFreeGC() - - * src/frames.c (invalidate_cache): free pixels - - * src/window.c (meta_window_show_menu): call - meta_screen_free_workspace_layout() - -2005-10-03 Elijah Newren - - Patch from Björn Lindqvist fix the workspace switcher tabpopup to - display the right windows and to fix the - pick-a-new-window-to-focus algorithm in order to not select - windows that aren't showing. Fixes #170475. - - * src/tabpopup.c (meta_convert_meta_to_wnck, - meta_select_workspace_expose_event): factor out conversion code - from meta_select_workspace_expose_event() into the new - meta_convert_meta_to_wnck() function - - * src/tabpopup.c (meta_select_workspace_expose_event): - * src/workspace.c (focus_ancestor_or_mru_window): - replace the buggy window->minimized logic with - !meta_window_showing_on_its_workspace (window) - -2005-10-03 Elijah Newren - - Patch from Björn Lindqvist to have ancestors come along with the - transient when moving the window from one workspace to another. - Fixes #314977. - - * src/window.c (meta_window_change_workspace): have all ancestors - change workspaces too - -2005-10-03 Elijah Newren - - * configure.in: post-release version bump to 2.12.2 - -2005-10-03 Elijah Newren - - * NEWS: 2.12.1 release - -2005-10-03 Elijah Newren - - Truncate ridiculously long titles to avoid crashing or letting the - pager crash. Based on patch from Ray, incorporating suggestions - from Havoc and some extensions of my own. Fixes #315070. - - * src/display.c (set_utf8_string_hint, meta_display_open): - * src/xprops.[ch] (meta_prop_set_utf8_string_hint): - Move set_utf8_string_hint() to props.[ch], namespace it - ("meta_prop_"), and make it public - - * src/tabpopup.c (utf8_strndup, meta_ui_tab_popup_new): - * src/util.[ch] (meta_g_utf8_strndup): - Move utf8_strndup() to util.[ch], namespace it ("meta_g_"), and - make it public - - * src/display.c (meta_display_open): - * src/display.h (struct _MetaDisplay): - add net_wm_visible_name and net_wm_visible_icon_name atoms to the - list of atoms we work with - - * src/window-props.c (set_window_title, set_icon_title): If title - length is greater than 512, truncate it and set - _NET_WM_VISIBLE_NAME or _NET_WM_VISIBLE_ICON_NAME accordingly - -2005-10-03 Elijah Newren - - Get the tabbing window outline to work with gtk+ 2.8.4 again. - Fixes #317528. - - * src/tabpopup.c (display_entry): gtk+ 2.8.4 needs to know the - mapped state of its windows (see bug 316180), and since we - manually map with gdk_window_show_unraised() we need to manually - set the mapped state too - -2005-09-05 Elijah Newren - - * configure.in: post-release version bump to 2.12.1 - -2005-09-05 Elijah Newren - - * configure.in: - * README: - * NEWS: - 2.12.0 release - -2005-09-04 Danilo Šegan - - * configure.in: Added Armenian (hy) to ALL_LINGUAS. - -2005-09-03 Elijah Newren - - * HACKING: Add tips on how to more easily get the ids of windows, - and how to shorten xprop output. - -2005-09-02 Brent Smith - - * src/place.c: (meta_window_place): Moved the call to - meta_screen_get_natural_xinerama_list to earlier in - function so that xineramas_list is allocated before - find_first_fit is called. Fixes #315000 - -2005-08-22 Elijah Newren - - * configure.in: post-release version bump to 2.11.5 - -2005-08-22 Elijah Newren - - * NEWS: 2.11.3 release - -2005-08-22 Elijah Newren - - * configure.in: Patch from Björn Lindqvist to check for the - appropriate versions of glib and gtk. Fixes #314116. - -2005-08-12 Elijah Newren - - * src/place.c (meta_window_place): Avoid obscuring - centered-on-desktop windows which are denied focus. Fixes - #313234. - -2005-08-08 Elijah Newren - - * configure.in: post-release version bump to 2.11.3 - -2005-08-08 Elijah Newren - - * NEWS: 2.11.2 release - -2005-08-08 Elijah Newren - - Patch from Brent Smith to fix a duplicate string. Fixes #309774. - - * src/theme-parser.c (parse_toplevel_element, parse_draw_op_element): - Change "No \"%s\" attribute on element <%s>" string to "No \"%s\" - attribute on <%s> element" - -2005-08-03 Ray Strode - - Improve the behavior of keyboard move/resize and edge - snapping. Still not perfect, bug 310888. - - * src/effects.c (draw_xor_rect): Make the outside of a - wireframe rectangle line up with the outside edge of its - window, instead of centering the wireframe edges on the - window edges. - - * src/keybindings.c (process_keyboard_move_grab): allow - edge snapping in wireframe mode. Adjust code to take - into account changed semantics of find_next_*_edge - functions. - (process_keyboard_resize_grab_op_change): new function - to take some orthogonal logic out of - process_keyboard_resize_grab_op. Only allow keyboard - resize cursor to go to flat edges, not corners. - (process_keyboard_resize_grab): allow edge snapping in - wireframe mode. Fix up snapping logic. - - * src/place.c (get_{vertical,horizontal}_edges): use - GArray instead of int *, since the number of output - edges isn't known until the middle of the function now. - Use xor rect extents instead of window extends if in - wireframe mode. - (meta_window_find_next_{vertical,horizontal}_edge: add - new source_edge_position parameter to specify which edge - on the active window to start from when looking for next - edge on the screen. Return the coordinate of the edge - found and not the coordinate of where the window should be - moved to snap to where the edge was found. - - * src/window.c (update_move): all the user to specify - an edge to resize with mouse in keyboard resize mode. - window - -2005-08-01 Elijah Newren - - * src/metacity.schemas.in: Change default theme from "Simple" to - "Clearlooks". - -2005-07-31 Elijah Newren - - * src/stack.c (is_focused_foreach, get_standalone_layer): use only - the expected_focus_window instead of both the focused_window and - the expected_focus_window. Removes an infinite flicker loop in - sloppy and mouse focus, and an ugly one time flicker in click to - focus. Fixes #311400. - -2005-07-30 Elijah Newren - - Patch from Jaap Haitsma to make sure that Metacity dialogs have - icons. Fixes #309876. - - * src/metacity-dialog.c (kill_window_question, - warn_about_no_sm_support, error_about_command): call - gtk_window_set_icon_name() to set the dialog icon - -2005-07-28 Elijah Newren - - * src/place.c (avoid_being_obscured_as_second_modal_dialog): - remove some unneeded debug spew that was causing crashes. Fixes - #311819. - -2005-07-24 Elijah Newren - - * configure.in: post-release version bump to 2.11.2 - -2005-07-24 Elijah Newren - - * NEWS: 2.11.1 release - -2005-07-24 Elijah Newren - - * src/place.c (find_most_freespace): try to place windows denied - focus near the focus window and fix a xinerama bug with the - placement, (avoid_being_obscured_as_a_second_modal_dialog): avoid - modal dialogs being obscured in somewhat pathologically strange - circumstances that Eclipse seems to be good at triggering, - (meta_window_place): have dialog windows make use of - avoid_being_obscured_as_a_second_modal_dialog(). Fixes one of the - issues found in #307875. - -2005-07-24 Elijah Newren - - * src/window.c (meta_window_raise): raise the window as well as - its ancestor; fixes a stacking bug with an ancestor that has more - than one child window. Fixes one of the issues in #307875. - -2005-07-24 Elijah Newren - - * src/window.c (meta_window_free): restore original window size if - the window was maximized, as the FIXME says. ;-) Fixes #137185. - Thanks to Christian Persch for the testcase that made this easier - to track down. - -2005-07-23 Elijah Newren - - * src/window.c (meta_window_activate): revert the patch from - #128380--change _NET_ACTIVE_WINDOW behavior to what it originally - was. - -2005-07-18 Matthias Clasen - - * configure.in: Add checks for Xcursor, to make the changes - done on 2005-07-11 effective. - -2005-07-14 Elijah Newren - - Patch from Ken Harris to provide a more lenient threshold for - drawing rounded corners. Fixes #122065. - - * src/theme.c (meta_frame_layout_calc_geometry): use height + - width > 5 instead of height > 3 && width > 3 as criterion - -2005-07-13 Elijah Newren - - Fix a slight bug (causing possible miscoloring of parts of the - titlebar) introduced by the patch from #169982. - - * src/gradient.c: - (meta_gradient_create_interwoven): - (meta_gradient_create_multi_vertical): - - bitshifting operators do not take precedence over typecasting, so - make sure to use parentheses to get the right operation order. - -2005-07-12 Elijah Newren - - * configure.in: post-release version bump to 2.11.1 - -2005-07-12 Elijah Newren - - * NEWS: 2.11.0 release - -2005-07-12 Elijah Newren - - Patch from Andrew Johnson to speed up vertical gradients. Fixes - #169982. - - * src/gradient.c: - (meta_gradient_create_interwoven): - (meta_gradient_create_vertical): - (meta_gradient_create_multi_vertical): - - use memcpy instead of really long loops to set values in memory to - a given pattern. - -2005-07-12 Elijah Newren - - Patch from Björn Lindqvist to split up main() into more manageable - chunks and make use of GOpt. Closes #305331. - - * src/main.c (usage): remove this function, - (meta_print_compilation_info): new function taken from main(), - (meta_print_self_identity): new function taken from main(), - (struct MetaArguments) new struct to replace some free variables, - (meta_parse_options): new funcion taken from main() but now using - GOpt, (meta_select_display): new function taken from main() - -2005-07-12 Aivars Kalvans - - * src/screen.c (meta_screen_free): free ->xinerama_infos - Closes #307884 - -2005-07-11 Elijah Newren - - Stuff I forgot to do when I branched an hour or so ago before - Matthias' commit... - - * configure.in: bump version to 2.11.0. Add UNSTABLE warning. - * README: add 2.11.x to the list of unstable branches - -2005-07-11 Matthias Clasen - - React to cursor theme changes: (#308106) - - * src/prefs.h: - * src/prefs.c: Expose the GConf keys for cursor theme - and size as preferences META_PREF_CURSOR_THEME and - META_PREF_CURSOR_SIZE with getters meta_prefs_get_cursor_theme() - and meta_prefs_get_cursor_size(). - - * src/display.c (meta_display_open): Initialize the cursor - theme and size. - - * src/display.h: - * src/display.c (meta_display_set_cursor_theme): New function - to change the cursor theme and update all cursors. - - * src/screen.h - * src/screen.c (meta_screen_update_cursor): New function to - refesh the root cursor of a screen. - - * src/main.c (prefs_changed_callback): Update the cursor - theme when the cursor preferences change. - -2005-06-27 Elijah Newren - - * configure.in: post-release version bump to 2.10.3 - -2005-06-27 Elijah Newren - - * NEWS: 2.10.2 release - -Sun Jun 26 11:19:18 2005 Soeren Sandmann - - * src/frames.c: Add a cache of pixmaps for recently exposed frame - areas. Makes metacity a bit faster when dragging windows around. - See bug 141813. - -2005-06-10 Ryan Lortie - - * src/frames.c: Prevent using the address of a local variable - as a hash key. (Bug #307209) - - * src/xprops.c (meta_prop_get_values): Fix a small leak in the - case of a SYNC_COUNTER property value and HAVE_XSYNC not - defined. (Bug #307214) - -2005-06-07 Ray Strode - - Cleanup font data when done with it (bug 306720). - - * src/effects.c (draw_xor_rect): free font info structure. - * src/screen.c (meta_screen_new): pass a 1 not a 0 to - XFreeFontInfo to free font info structure. - (meta_screen_free): call XUnloadFont on GC font before freeing - the GC. - -2005-06-02 Elijah Newren - - * src/window.c (meta_window_focus): if the window has a modal - transient which is being unmanaged, don't focus it. Fixes the - Metacity issue reported in #305362. - -2005-05-30 Ray Strode - - Bug 305564 again. - - When drawing XOR resize popup use "fixed" font instead of - -misc-fixed-*-16-* xlfd. Should work on more xservers. - - Also take steps to fail better if the xserver isn't - cooperating. - - * src/effects.c (draw_xor_rect): if we can't draw font box - for whatever reason, at least draw grid frames. - - * src/screen.c (meta_screen_new): use fixed alias instead - of a xfld. Don't pass GCFont to XCreateGC if font couldn't - be loaded. Print a warning if font couldn't be loaded. - -2005-05-26 Elijah Newren - - * HACKING: Add a clarification that METACITY_VERBOSE needs to be - accompanied by METACITY_USE_LOGFILE - -2005-05-26 Elijah Newren - - * src/window.c (meta_window_configure_request): Patch from Greg - Hudson to make sure window position is calculated correctly for - reconfigure requests when part of the XWindowChanges structure is - uninitialized. Fixes #305257. - -2005-05-26 Ray Strode - - Actually commit the stuff mentioned in the last - ChangeLog entry. - -2005-05-26 Ray Strode - - Add a resize popup when resizing constrained - windows, (bug 305564). - - * src/display.c: - (meta_display_begin_grab_op), - (meta_display_end_grab_op): - * src/keybindings.c (process_keyboard_move_grab), - (process_keyboard_resize_grab): Call - meta_window_{begin,update,end}_wireframe convenience - functions instead of the meta_effects counterparts. - - * src/display.h: keep track of old wireframe geometry to - clean up xor popup on resize - - * src/effects.[ch] (meta_effects_begin_wireframe), - (meta_effects_update_wireframe), - (meta_effects_end_wireframe), - (draw_xor_rect): take optional width and height arguments - to show to user in resize popup. Draw resize popup if - width and height >= 0 and wireframe isn't smaller than - the popup would be. - - * src/screen.c (meta_screen_new): load a largish font for - the resize popup - - * src/window.[ch] - (meta_window_move_resize_internal): update - wireframe resize popup when the window is resized. - (meta_window_get_wireframe_geometry): new function to - calculate the numbers to display in resize popup - (meta_window_begin_wireframe), - (meta_window_update_wireframe), - (meta_window_end_wireframe): new functions to reduce - repetitive wireframe code. Functions handle updating - wireframe and resize popup geometry. - (update_move), (update_resize), - (meta_window_refresh_resize_popup): remove fixme and - add debug message. - -2005-05-26 Elijah Newren - - * src/window.c (check_maximize_to_work_area): don't accidentally - treat maximize vertically as maximize in both directions. Fixes - #302204. - -2005-05-26 Elijah Newren - - * src/window.c (meta_window_new_with_attrs): put all transients - of the new window, if any exist, in the calc_showing queue. Fixes - #303284. Thanks to Billy Biggs for the testcase that made this - easy to track down. - -2005-04-11 Elijah Newren - - * configure.in: post-release version bump to 2.10.2 - -2005-04-11 Elijah Newren - - * NEWS: 2.10.1 release - -2005-04-05 Dan Winship - - * src/metacity-dialog.c (warn_about_no_sm_support): Make sure the - "Close" button has the focus, not the table. (#172703) - -2005-04-05 Pawan Chitrakar - - * configure.in: Added ne in ALL_LINGUAS - -2005-03-31 Steve Murphy - - * configure.in: Added "rw" to ALL_LINGUAS. - -2005-03-17 Lex Hider - - * doc/Makefile.am (EXTRA_DIST): add doc/code-overview.txt and - doc/how-to-get-focus-right.txt - -2005-03-10 Adi Attar - - * configure.in: Added "xh" to ALL_LINGUAS. - -2005-03-07 Elijah Newren - - * configure.in: post-release version bump to 2.10.1 - -2005-03-07 Elijah Newren - - * configure.in: - * README: - * NEWS: - 2.10.0 release - -2005-02-28 Elijah Newren - - * configure.in: post-release version bump to 2.9.55 - -2005-02-28 Elijah Newren - - * NEWS: Metacity 2.9.34 unstable release - -2005-02-28 Elijah Newren - - Patch from Aidan Delaney to make sure that icons in the alt-tab - popup are dimmed for all hidden windows, not just minimized ones. - Fixes #168455. - - * src/screen.c: (meta_screen_ensure_tab_popup): make use - meta_window_showing_on_its_workspace() instead of just checking if - the window is minimized. - -2005-02-25 Elijah Newren - - Prevent the visual bell from changing the focus window. Fixes - #123366. - - * src/bell.c: (meta_bell_flash_screen): if not in click-to-focus - mode and mouse_mode is also false, increment the focus sentinel so - that we can ignore spurious EnterNotify and LeaveNotify events. - - * src.display.c: (event_callback): make sure to also ignore - LeaveNotify events when the focus sentinel isn't clear - -2005-02-23 Elijah Newren - - * src/window.c: (meta_window_new_with_attrs): Fix crash that - occurs when stupid apps claim that a window is its own parent. - #168207 - -2005-02-21 Elijah Newren - - * configure.in: post-release version bump to 2.9.34 - -2005-02-21 Elijah Newren - - * NEWS: Metacity 2.9.21 unstable release - -2005-02-21 Elijah Newren - - Handle keynav vs. mousenav in mouse and sloppy focus modes. Fixes - #167545. - - * doc/how-to-get-focus-right.txt: Update due to this new method - for handling keynav vs. mousenav, plus various other updates that - I previously forgot. - - * src/display.h: (struct _MetaDisplay): add a mouse_mode boolean - - * src/display.c: (meta_display_open): initialize mouse_mode to - true, (event_callback): have EnterNotify and LeaveNotify events - set mouse_mode to true when focusing a window - - * src/keybindings.c: (process_tab_grab): set mouse_mode to false - when using alt-tab/alt-esc, (do_choose_window): likewise, - (do_handle_move_to_workspace): set mouse_mode to false on - move-window-to-workspace- keybindings - - * src/window.c (idle_calc_showing): if we're in keynav mode while - using sloppy or mouse focus, use metacity_sentinel to avoid - EnterNotify events being generated from events other than mouse - movement. - - * src/workspace.c (meta_workspace_activate_with_focus): add a - FIXME in a potentially duplicate section of code, - (meta_workspace_focus_default_window): use the same focus choice - as click-to-focus if in keynav mode. - -2005-02-20 Elijah Newren - - * src/display.c: (event_callback): Handle _NET_CURRENT_DESKTOP - messages that come with timestamps. Fixes the metacity portion of - #161361 other than the portion handled by #128380. - -2005-02-20 Elijah Newren - - * src/window.c: (meta_window_activate): when receiving a - _NET_ACTIVE_WINDOW message, switch to the desktop where the window - is located before activating instead of moving the window to the - current desktop. Thanks to Lubos Lunak for catching this issue. - Fixes #128380. - -2005-02-20 Elijah Newren - - * src/window.c (meta_window_show): Ignore all focus and - focus-stealing-prevention code in meta_window_show when not - showing the window for the first time. Fixes #167199. - -2005-02-20 Elijah Newren - - Fix an obscure xinerama placement bug with windows that are too - large to fit in the workarea in both dimensions. #166757 - - * src/place.c: (meta_window_place): use the current xinerama - instead of arbitrarily resetting to 0 - -2005-02-20 Elijah Newren - - Patch from Joe Marcus Clarke to fix a possible crash on logout. - #167935. Thanks for fixing my mistakes, Joe! - - * src/display.c: (meta_display_open): initialize - display->grab_old_window_stacking to NULL. - -2005-02-20 Elijah Newren - - Big patch to cover about 6 different issues in order to correct - rare problems with timestamps (make sure window selected in - tasklist actually gets focus, sanity check timestamps to avoid - rogue apps hosing the system, correct the updating of - net_wm_user_time, correctly handle timestamps of 0 when comparing - xserver timestamps for those who have had their systems up for - over 25 days or so, add some debugging information to verbose - logs, some code cleanups). Fixes all issues listed in #167358. - - * src/display.h: (struct _MetaDisplay): clarify comment on - last_focus_time, introduce a new variable--last_user_time, - (XSERVER_TIME_IS_BEFORE macro): put this functionality into a - separate macro and then introduce a new macro with this name that - uses the old one but adds additional special-case checks for - timestamps that are 0, (comment to - meta_display_set_input_focus_window): add information about how - last_user_time should be used in this function - - * src/display.c (santiy_check_timestamps): new function, - (meta_display_open): intialize display->last_user_time, - (meta_display_get_current_time_roundtrip): use the timestamp, - which is known to be good, in order to sanity_check_timestamps, - (event_callback): use the new meta_window_ste_user_time() function - in order to correct problems, use the timestamp of KeyPress and - ButtonPress events, which are known to be good, in order to - sanity_check_timestamps, (timestamp_too_old): new function for - common behavior of meta_display_focus_the_no_focus_window and - meta_display_set_input_focus_window, with added checking for - display->last_user_time in addition to display->last_focus_time, - (meta_display_set_input_focus_window): replace some of the code - with a call to timestamp_too_old(), - (meta_display_focus_the_no_focus_window): replace some of th ecode - with a call to timestamp_too_old() - - * src/window.h: (meta_window_set_user_time): new function to - abstract the many things that need to be done when updating the - net_wm_user_time of any window - - * src/window.c: (meta_window_activate): add debugging spew, make - sure the comparison is made with last_user_time NOT - last_focus_time, use meta_window_set_user_time() function in order - to correct problems, (meta_window_client_message): add a newline - to a debugging message to make them easier to read, - (meta_window_set_user_time): new function - - * src/window-props.c (reload_net_wm_user_time): use the new - meta_window_ste_user_time() function in order to correct problems - -2005-02-16 Elijah Newren - - * src/display.c: (event_callback): trivial fix to a log message: - change %d to %lu (see debugging log from bug 167358). - -2005-02-12 Elijah Newren - - Raise the ancestor of a window instead of the window itself. - Fixes #166894. - - * src/window.c: (find_root_ancestor): new function, - (meta_window_raise): get the ancestor of the given window and - raise it if possible instead of the window - -2005-02-12 Elijah Newren - - Don't unconditionally place splashscreens (and other - not-to-be-focused windows) below the focus window. Fixes #167042. - - * src/window.c: (intervening_user_event_occurred): new function - taken from the timestamp comparison portion of the old - window_takes_focus_on_map function, (window_state_on_map): new - function with remainder of old window_takes_focus_on_map function - that determines both whether the window will take focus and - whether it should be placed on top, (meta_window_show): use - place_on_top_on_map to determine window stacking instead of trying - to infer it from takes_focus_on_map - -2005-02-11 Elijah Newren - - Avoid new windows being obscured by the focus window (and thus - possibly lost). Fixes #166524. - - * src/place.c: new MetaWindowDirection enum, - (find_most_freespace): new function to find where there is the - most space available around the focused window, - (meta_window_place): if a window is denied focus and the window - overlaps the focused window, retry the first-fit algorithm only - paying attention to the focus window position and if that fails - just find the location on the screen with the most space - available. - - * src/window.h: (struct MetaWindow): new - denied_focus_and_not_transient bitfield - - * src/window.c: (meta_window_new_with_attrs): initialize - denied_focus_and_not_transient, (meta_window_show): set and unset - the denied_focus_and_not_transient field appropriately - -2005-02-08 Aidan Delaney - - Removed useless function call. #166730 - - * src/tabpopup.c: (outline_window_expose): Removed unused - references to variables and an unnecessary function call to - gdk_window_get_size(). - -2005-02-08 Elijah Newren - - Avoid using CurrentTime when focusing, handle it better in case we - miss any cases. Fixes #166732. - - * src/window.c: (meta_window_shade): use - meta_display_get_current_time_roundtrip() to ensure we have a - valid timestamp, (meta_window_unshade): same - - * src/display.c: (meta_display_set_input_focus_window): If - CurrentTime was passed, get one from the XServer in addition to - throwing a warning, (meta_display_focus_the_no_focus_window): same - -2005-02-08 Elijah Newren - - * src/window.c: (meta_window_activate): If we're not passed a - timestamp, make sure to manually get one. Fixes #166728. - -2005-02-07 Elijah Newren - - * configure.in: post-release version bump to 2.9.21 - -2005-02-07 Elijah Newren - - * NEWS: Metacity 2.9.13 unstable release - -2005-02-06 Elijah Newren - - Set a _METACITY_VERSION property (a utf8 string) on the WM check - window. #165350. - - * src/display.h: (struct MetaDisplay): add a atom_metacity_version - field - - * src/display.c: (meta_display_open): initialize the - _METACITY_VERSION property on the WM check window to the current - version of Metacity. - -2005-02-06 Elijah Newren - - Ignore xconfigurerequest events for stacking when it should be - safe to do so. Again, thanks to Crispin Flowerday for the test - case. Thanks to KWin for the inspiration (and to Google for - indexing their source code). Fixes the other half of #166395. - - * src/window.c: (meta_window_configure_request): if the - active_window is from a separate application than the one getting - the configure request and the net_wm_user_time of the active - window is later than that of the window getting the configure - request, then ignore the request. - -2005-02-06 Elijah Newren - - If activation requests are too old, set the demands_attention hint - instead of actually activating. Thanks to Crispin Flowerday for - the test case and for testing the patch. Fixes half of #166395. - - * src/window.c: (meta_window_activate): if the request came before - the last focus time, set the demands attention hint instead - -2005-02-04 Dave Ahlswede - - * src/metacity.schemas.in: Add period to the end of - reduced_resources' description. Fixes #165780. - -2005-02-04 Elijah Newren - - Make sure window->border_only is initialized so we don't get - random windows without decorations. Thanks to Sinisa Segvic and - Owen Taylor for providing test cases. Fixes #145131. - - * src/window.c: (update_mwm_hints): Be sure to call - recalc_window_features even if no MWM hints are set - -2005-02-02 Elijah Newren - - Focus parents of dismissed transient windows in preference to the - window that most recently had keyboard focus. Fixes #157360. - - * doc/how-to-get-focus-right.txt: Note the distinction between - "most recently used window" and "most recent to have keyboard - focus" that we are now making. - - * src/workspace.c: (focus_ancestor_or_mru_window): rename from - meta_workspace_focus_mru_window, and first check whether we need - to focus an ancestor window before looking for the mru window, - (record_ancestor): helper function for - focus_ancestor_or_mru_window, - (meta_workspace_focus_default_window): update due to the function - rename from meta_workspace_focus_mru_window to - focus_ancestor_or_mru_window - -2005-01-31 Elijah Newren - - Try 2 to correct misleading and inaccurate wording. Hopefully, - really fixes #165380. - - * src/menu.c: Change wording of menu from "Always on Current - Workspace" to "Always on Visible Workspace". "Always on Current - Workspace" could sound like a synonym of "Only on This Workspace" - when it was supposed to be the opposite. - -2005-01-31 Elijah Newren - - Correct the stacking when return from fullscreen mode. Fixes - #165718. - - * src/window.c: (meta_window_unmake_fullscreen): Update the layer - after resizing the window - -2005-01-31 Muktha - - src/themes/Atlanta/metacity-theme-1.xml: - src/themes/Simple/metacity-theme-1.xml: - src/themes/Bright/metacity-theme-1.xml: - Make the unfocussed title bar distinguishable. Fixes #125291. - -2005-01-28 Elijah Newren - - Patch from RHEL-3 (Havoc doesn't remember how it got there) that - Havoc posted in bug 156511 to fix the problem with fullscreen - windows on a different xinerama monitor not staying on top. I - updated to HEAD. Should fix #156511. - - * src/stack.c: (windows_on_different_xinerama): new function, - (get_standalone_layer): let windows on a different screen than the - one with the focus window stay in the fullscreen layer - -2005-01-28 Elijah Newren - - * src/metacity-dialog.c: (warn_about_no_sm_support): make this - dialog be sticky. Fixes #164745. - -2005-01-28 Elijah Newren - - Patch from Tim Herold to handle xcomposite pkgconfig version - regression. Fixes #149368. - - * configure.in: Change XCOMPOSITE_VERSION from 1.0 to 0.2 - -2005-01-28 Elijah Newren - - Correct misleading and inaccurate wording. Fixes #165380. - - * src/menu.c: Change wording of menu to "Always on Current - Workspace" from "Put on All Workspaces", remove a quick-key - conflict between "On _Top" and "Only on _This Workspace" by - switching the latter to "_Only on This Workspace" - - * src/window.c: Remove a comment that is no longer necessary - (since bug 87531 has been fixed) - -2005-01-28 Elijah Newren - - Take into account the appropriate list of windows when placing a - new one. Fixes #165381. - - * src/place.c: (meta_window_place): use - meta_window_showing_on_its_workspace(w) instead of !w->minimzed, - also take into account sticky windows - - * src/window.[ch]: rename window_showing_on_its_workspace to - meta_window_showing_on_its_workspace and export it - -2005-01-27 Elijah Newren - - Plug a pair of leaks. Fixes #165378 - - * src/place.c: (meta_window_place, get_windows_on_same_workspace): - free list returned by meta_display_list_windows. - -2005-01-27 Elijah Newren - - Treat splashscreens same as other windows for stacking. Fixes - #165243. - - * src/stack.h: (MetaStackLayer enum): remove META_LAYER_SPLASH - from the list - - * src/stack.c: (get_standalone_layer): remove the special casing - of META_WINDOW_SPLASHSCREEN - -2005-01-27 Elijah Newren - - * src/window.c: (set_net_wm_state): shaded windows should not show - up in pagers. Fixes #165377. - -2005-01-26 Elijah Newren - - Stick and unstick transients with their parent automatically. - Fixes #152283. - - * src/window.c: (window_stick_impl, window_unstick_impl): rename - from meta_window_stick and meta_window_unstick respectively, - (stick_foreach_func): a function to assist calling - window_(un)stick_impl on each transient, (meta_window_stick, - meta_window_unstick): new functions that call window_stick_impl or - window_unstick_impl for the window and each of its transients. - -2005-01-26 Elijah Newren - - Patch from John Paul Wallington to keep tooltip on screen - horizontally for xinerama. Fixes #165261. - - * src/fixedtip.c: (meta_fixed_tip_show): rename screen_width and - screen_height to screen_right_edge and screen_bottom_edge, set - them using xinerama info instead of just screen geometry, and use - them to determine where to place the tooltip window. - -2005-01-26 Arvind Samptur - - Don't wireframe when accessibility is on, it apparently - causes a desktop wide freeze. - - * src/prefs.[ch] (meta_prefs_init) (change_notify) - (update_gnome_accessibility) (meta_preference_to_string) - (meta_prefs_get_gnome_accessibility) : Add code to monitor - accessibility status. - - * src/display.c (meta_display_begin_grab_op): Check - accessibility status before going ahead with wireframe. - Fixes #159538 - -2005-01-25 Elijah Newren - - * src/tabpopup.c: (meta_select_workspace_expose_event): ignore - sticky windows for non-active workspaces. Fixes #165259. - -2005-01-25 Elijah Newren - - * src/window.c: (meta_window_new_with_attrs): set the window state - hints _after_ applying session information. Fixes #164677. - -2005-01-25 Elijah Newren - - Add man pages for metacity-window-demo and metacity-theme-viewer. - Man pages from Jose Moya, auto-fu from Dave Ahlswede. (#143513) - - * doc/man/metacity-theme-viewer.1: - * doc/man/metacity-window-demo.1: - - New man pages - - * doc/man/Makefile.am: - * doc/Makefile.am: - * configure.in: - - Make sure to install the man pages - - * doc/man/.cvsignore: - - Silence cvs - -2005-01-25 Benjamin Kahn - - New 48x48 default icon as specified in bug #160660 - -2005-01-25 Elijah Newren - - Patch from Stephane LOEUILLET in bug #151850. - - * src/metacity.desktop.in: specify encoding - -2005-01-25 Balamurali Viswanathan - - * src/prefs.c (meta_prefs_init): Get gconf to load the - terminal dir so that we get the notifications when - the command is changed. Fixes bug #160934 - -2005-01-25 Elijah Newren - - Refuse to focus a window with a modal transient, and focus the - transient instead. Fixes #164716. - - * src/window.c: (get_modal_transient): new function, - (meta_window_focus): if the window has a modal transient, make - sure it is on the current workspace and then focus it instead. - -2005-01-24 Elijah Newren - - * configure.in: post-release version bump to 2.9.13 - -2005-01-24 Elijah Newren - - * NEWS: Metacity 2.9.8 unstable release - -2005-01-24 Elijah Newren - - * src/display.c: (meta_display_begin_grab_op): don't forget to - initialize display->grab_old_window_stacking. Thanks to Sebastien - Bacher and the bleeding edge Ubuntu users for catching the - occasional crash this could cause so quickly, and for verifying - that the patch worked (I couldn't duplicate). Fixes #165093. - -2005-01-23 Elijah Newren - - * configure.in: post-release version bump to 2.9.8 - -2005-01-23 Elijah Newren - - * NEWS: Metacity 2.9.5 unstable release - * README: there are more stable releases beyond 2.8.6... - -2005-01-23 Elijah Newren - - Restore original stacking when aborting an alt-esc window switch - operation. Fixes #123576. - - * src/display.c: (GRAB_OP_IS_WINDOW_SWITCH): new macro, - (meta_display_close): clear grab_old_window_stacking if non-NULL, - (event_callback): restore stack positions if alt-esc op cancelled - with button press, (meta_display_begin_grab_op): store the old - stacking positions, (meta_display_end_grab_op): free the old stack - positions - - * src/display.h: (struct _MetaDisplay): add a - grab_old_window_stacking list - - * src/keybindings.c: (process_tab_grab): restore stack positions - if alt-esc op cancelled with an errant key press - - * src/stack.c: (compare_just_window_stack_position): new - GCompareFunc function, (meta_stack_get_positions): get current - stack positions, (compare_pointers): new GCompareFunc function, - (lists_contain_same_windows): simple utility func to see if two - lists contains the same windows, (meta_stack_set_positions): new - function to set the positions of all the windows in the stack - - * src/stack.h: (meta_stack_get_postions, - meta_stack_set_positions): new functions - -2005-01-23 Elijah Newren - - Patch from John Paul Wallington to fix #163420. - - * src/window.c: (check_maximize_to_work_area): fix vertical - maximization for second screen - -2005-01-21 Elijah Newren - - * rationales.txt: Add a tracker bug for modal dialog issues - -2005-01-20 Elijah Newren - - * src/tabpopup.c (dimm_icon): use pixbuf, not dimmed_pixbuf (which - isn't defined yet). Fixes crash from #136666. - -2005-01-20 Vincent Noel - - * src/screen.c: (meta_screen_ensure_tab_popup), - (meta_screen_ensure_workspace_popup): - * src/tabpopup.c: (meta_ui_tab_popup_new), (display_entry): - * src/tabpopup.h: Show labels in bold for windows that demand - attention. Fixes #164590. - -2005-01-18 Vincent Noel - - * src/screen.c: (meta_screen_ensure_tab_popup), - (meta_screen_ensure_workspace_popup): - * src/tabpopup.c: (dimm_icon), (meta_ui_tab_popup_new), - (free_entry): - * src/tabpopup.h: In the tab task switcher popup, dim the window - icon and put its name between brackets when the window is - minimized. Fixes #136666. - -2005-01-11 Elijah Newren - - Correct highlighting of windows in workspace switcher popup. - Fixes #163450. - - * src/tabpopup.c (meta_select_workspace_expose_event): Remove race - between FocusIn/FocusOut events and the expose event by replacing - window->has_focus with - window==window->display->expected_focus_window. - -2005-01-09 Elijah Newren - - * configure.in: post-release version bump to 2.9.5 - -2005-01-09 Elijah Newren - - * NEWS: Metacity 2.9.3 unstable release - -2005-01-09 Elijah Newren - - * src/display.c (meta_display_open): - * src/display.h (struct _MetaDisplay): - * src/window.c (meta_window_free, meta_window_client_message, - meta_window_notify_focus): - - Remove the hack from bug 128200; it isn't needed anymore with the - fix from bug #160470. - -2005-01-09 Elijah Newren - - Don't focus the panel on click. Fixes #160470 (and 100470 and - removes the need for the hack from 128200) - - * doc/how-to-get-focus-right.txt: Update section on focusing - non-decorated windows (specifically, DOCKS and DESKTOPS) - - * src/display.c (event_callback): don't focus dock windows on - click - -2005-01-06 Elijah Newren - - Make sure the save session dialog appears focused. Fixes #162983. - - * src/session.c (warn_about_lame_clients_and_finish_inter): Get a - timestamp by explicit request from Xserver, since none is - available otherwise. - -2005-01-06 Leena Gunda - - * src/window.c (meta_window_unmaximize): Restore the wireframe - rectangle co-ordinates to saved window co-ordinates. Fixes - bug #161236. - -2005-01-03 Thomas Fitzsimmons - - * src/Makefile.am (install-data-local): Install schema data from - builddir not srcdir. - -2005-01-02 Elijah Newren - - Provide more documentation to make it easier for people to - contribute to Metacity. (#162646) - - * HACKING: Add lots of information to extend this document: more - on relevant standards and X properties, lots of information on - debugging and testing, and add a list of some other important - things to read; also move some information to - src/code-overview.txt and organize this file into sections. - - * doc/code-overview.txt: New file including some small parts from - the old HACKING file and lots of new stuff. This file gives a - brief overview of some of the bigger structures and files, with - guides for a variety of task categories providing places to start - looking in the code and things to look for. - -2004-12-28 Elijah Newren - - Allow users to move the window around immediately after - double-clicking to shade (#90290) - - * src/display.c (event_callback): only end the grab op if either - there is no frame or else the frame is not mapped - -2004-12-27 Elijah Newren - - Focus windows that manually position themselves too (fixes - #107347). - - * src/window.h (struct _MetaWindow): add a new - showing_for_first_time flag - - * src/window.c (meta_window_new_with_attrs): initialize - showing_for_first_time flag to !mapped, (meta_window_show): - replace did_placement with showing_for_first_time in the section - to decided whether to focus since did_placement isn't quite what - we want - -2004-12-27 Elijah Newren - - * src/display.c (meta_display_set_input_focus_window, - meta_display_focus_the_no_focus_window): Spew warning if - CurrentTime is passed to the function, but don't exit prematurely. - (fixes #162353) - -2004-12-24 Elijah Newren - - * src/window.c (meta_window_show_menu): Don't show menu if all - options are invalid (fixes #148915) - -2004-12-24 Elijah Newren - - * src/window.c (window_takes_focus_on_map): Fix error in - distinguishing < vs. <= introduced by the patch in #154598, - restructure code so that verbose log matches code better in order - ensure such mistakes are harder to make in the future (fixes - #162172) - -2004-12-24 Elijah Newren - - Thanks to mild7@users.sourceforge.net for this fix. - - * src/window.h: (META_WINDOW_IN_NORMAL_TAB_CHAIN): Excludes - windows with skip_taskbar hint set from the alt-tab list; they'll - appear in the ctrl-alt-tab list instead. (fixes #106249) - -2004-12-22 Elijah Newren - - Wrap XSetInputFocus, making display->expected_focus_window a - little more reliable (see #154598) - - * src/display.h: (struct _MetaDisplay): add a large comment about - the expected_focus_window, add a last_focus_time field, - (XSERVER_TIME_IS_BEFORE): new macro moved from window.c but fixed - for 64-bit systems, (meta_display_set_input_focus_window): new - function - - * src/display.c (meta_display_open): initialize last_focus_time, - add a comment about brokenness of trying to set intial focus - window, (meta_display_set_input_focus_window): new function that - wraps XSetInputFocus, - (meta_display_focus_the_no_focus_window): make this function - closer to a wrapping of XSetInputFocus for the no_focus_window. - - * src/window.c (XSERVER_TIME_IS_LATER): remove this macro in favor - of the improved one added to display.h - - * src/display.c (meta_display_open): - * src/window.c (meta_window_focus): - use meta_display_focus_the_no_focus_window and - meta_display_set_input_focus instead of XSetInputFocus - -2004-12-22 Elijah Newren - - * src/core.c (meta_core_user_lower_and_unfocus): - * src/display.c (meta_display_get_current_tab): - * src/stack.c (get_default_focus_window, meta_stack_list_windows): - * src/window.c (set_net_wm_state, meta_window_should_be_showing, - implement_showing, meta_window_activate, - meta_window_notify_focus): - * src/window.h: - * src/workspace.c (meta_workspace_list_windows): - - Rename meta_window_visible_on_workspace to - meta_window_located_on_workspace (whether or not the window was - showing wasn't taken into account, which made "visible" - confusing). Fixes #136314. - -2004-12-22 Elijah Newren - - Partially resolve the conflicting requirements of windows on - multiple workspaces and hidden being a global quantity for windows - (fixes bug 156182; the remainder of the work is bug 87531 and is a - libwnck issue) - - * src/display.c (event_callback): - * src/window.c (meta_window_visible_on_workspace, meta_window_unstick): - * src/workspace.c (meta_workspace_add_window, - meta_workspace_contains_window, - meta_workspace_queue_calc_showing): - * src/workspace.h: - - Remove meta_workspace_contains_window, replace with simple - comparison utilizing window->workspace - - * src/place.c (meta_window_place): - * src/window.c (meta_window_shares_some_workspace): - * src/window.h: - - Remove meta_window_shares_some_workspace, replace with a simple - comparison utilizing window->workspace - - * src/session.c (save_state), - * src/window.c (meta_window_new_with_attrs, - meta_window_apply_session_info, meta_window_free, - window_showing_on_its_workspace, - meta_window_change_workspace_without_transients, - meta_window_unstick, meta_window_set_current_workspace_hint, - meta_window_get_workspaces): - * src/window.h: - * src/workspace.c (meta_workspace_free, meta_workspace_add_window, - meta_workspace_remove_window): - - Only one workspace now - -2004-12-20 Elijah Newren - - * configure.in: post-release version bump to 2.9.3 - -2004-12-20 Elijah Newren - - * NEWS: Metacity 2.9.2 unstable release - -2004-12-20 Elijah Newren - - * configure.in: re-add the note about Fibonacci sequence micro - version numbers that was lost with 2.8.5 - -2004-12-19 Elijah Newren - - Thanks to Baptiste Mille-Mathias for this fix. - - * src/metacity.schemas.in: Add a missing period at the end of a - sentence. - -2004-12-19 Elijah Newren - - When snap-moving, don't snap to transients of minimized windows - since they are hidden. Fixes #157180 - - * src/place.c (get_windows_on_same_workspace): make the logic to - determine hidden windows more thorough by calling - meta_window_should_be_showing() - - * src/window.c (meta_window_should_be_showing): rename this - function from window_should_be_showing and also export it, - (implement_showing): - s/window_should_be_showing/meta_window_should_be_showing/, - (idle_calc_showing): - s/window_should_be_showing/meta_window_should_be_showing/ - - * src/window.h (meta_window_should_be_showing): Add this function - to the list so that it can be used in src/place.c - -2004-12-19 Elijah Newren - - Focus the desktop when showing it. Fixes #159257. - - * src/display.c (event_callback): obtain a timestamp to pass to - meta_screen_show_desktop - - * src/keybindings.c (handle_toggle_desktop): obtain a timestamp to - pass to meta_screen_show_desktop - - * src/screen.c (meta_screen_show_desktop): add a timestamp - parameter, get the most recently used window of type DESKTOP (if - there is one) and focus it - - * src/screen.h (meta_screen_show_desktop): add a timestamp - parameter - -2004-12-19 Elijah Newren - - Thanks to ash@contact.bg for this fix. - - * po/POTFILES.in: Remove reference to metacity-properties.* files - since Alex removed them in his 2004-12-07 commit. - -2004-12-13 Elijah Newren - - * configure.in: post-release version bump to 2.9.2 that I forgot - to do last week (oops) - -2004-12-07 Alex Duggan - - * configure.in: - * src/tools/Makefile.am: - - Remove deprecated capplet from GNOME 2.0 - - * src/tools/metacity-properties.c: - * src/tools/metacity-properties.desktop.in: - * src/tools/metacity-properties.glade: - * src/tools/metacity-properties.png: - - Removed from cvs - -2004-12-06 Elijah Newren - - * NEWS: Metacity 2.9.1 unstable release - -2004-12-06 Benjamin Kahn - - * src/default_icon.png: Use a better default application - icon. Fixes bug #160373 - -2004-11-16 Marco Pesenti Gritti - - * src/Makefile.am: - - Fix build out of src directory. Bug #158325 - -2004-11-10 James Henstridge - - * Makefile.am (DISTCLEANFILES): remove intltool stuff on distclean. - - * src/themes/Makefile.am (uninstall-local): add uninstall rule. - - * src/Makefile.am (libmetacity_private_la_CFLAGS): set this - variable so that the files shared with metacity get compiled with - different names. - - * configure.in: use more modern macros in some places, and make - sure that $ACLOCAL_AMFLAGS is set so that rebuilds work better. - - * autogen.sh (conf_flags): use newer automake. - -2004-11-06 Vincent Untz - - * src/metacity.schemas.in: gnome-panel-screenshot was renamed to - gnome-screenshot - -2004-11-01 Elijah Newren - - * configure.in: bump version to 2.9.1 - -2004-11-01 Elijah Newren - - * NEWS, README: Metacity 2.9.0 (unstable release) - -2004-10-25 Elijah Newren - - Don't lower newly mapped windows when they're denied focus, if - they are transients of the focused window. Instead, defocus the - currently focused window. (fixes #151996). - - (Also, reenable focus stealing prevention and do a small spacing - cleanup) - - * src/window-props.c (init_net_startup_id): fix spacing - - * src/window.c (window_takes_focus_on_map): re-enable focus - stealing prevention, (meta_window_show): if the new window is - denied focus and is a transient of the currently focused window, - defocus the currently focused window but keep the transient on - top; remove some old code about transients and focus; make sure - that EnterNotify events won't accidentally focus the new window. - -2004-10-25 Elijah Newren - - Fix the alt-tab order--if the most recently used window is not - focused, start alt tabbing with that window instead of the one - after it (fixes #156251) - - * src/display.c (find_tab_forward): add a skip_first parameter, - (find_tab_backward): add a skip_last parameter, - (meta_display_get_tab_next): if a beginning window wasn't given - and the focused window isn't the tab chain, don't skip the MRU - window - -2004-10-22 Elijah Newren - - Update _NET_WM_STATE_HIDDEN so the pager on the panel will know - whether to display windows as visible or hidden (#105665) - - * src/screen.c (queue_windows_showing): Revert the - queue_windows_showing portion of the patch committed on 2004-10-16 - for #142198--it was an ill-advised optimization. - - * src/window.c (window_showing_on_its_workspace, - window_should_be_showing): split the old window_should_be_showing - into these two functions, (set_net_wm_state): hidden state is more - complex; use window_showing_on_its_workspace to determine the - correct value - -2004-10-20 Elijah Newren - - Patch from Soeren to fix the modifier key breakage introduced by - an Xorg change. (fixes #151554) - - * src/keybindings.c: include X11/XKBlib.h if available, - (handle_spew_mark): remove this unused function declaration, - (end_keyboard_grab): new function, uses XKB if available, - (process_tab_grab): use end_keyboard_grab to determine whether to - end the grab, (error_on_command): make key a const char *, - (process_workspace_switch_grab): use end_keyboard_grab to - determine whether to end the grab - -2004-10-19 Anders Carlsson - - * src/frame.c: (meta_window_ensure_frame): - Don't try to use an ARGB visual at all if the depth isn't - 32-bit. This caused major slowdowns with Composite enabled. - -2004-10-16 Elijah Newren - - Make the "showing desktop" mode be per-workspace instead of - per-screen. (fixes #142198) - - * src/keybindings.c (handle_toggle_desktop): access - showing_desktop through the active workspace - - * src/screen.c (meta_screen_new): remove initialization of - screen->showing_desktop, - (meta_screen_update_showing_desktop_hint): rename and make not - static and access showing_desktop through the active workspace, - (queue_windows_showing): replace meta_display_list_windows() with - screen->active_workspace->windows, - (meta_screen_minimize_all_on_active_workspace_except): renamed - from meta_screen_minimize_all_except since it now only works on - the active workspace, (meta_screen_show_desktop, - meta_screen_unshow_desktop): access showing_desktop through the - active workspace - - * src/screen.h (struct _MetaScreen): remove showing_desktop field, - (meta_screen_minimize_all_on_active_workspace_except): rename from - meta_screen_minimize_all_except, - (meta_screen_update)_showing_desktop_hint): export this function too - - * src/window.c (maybe_leave_show_desktop_mode): access - showing_desktop through the active workspace and use new name for - meta_screen_minimize_all_on_active_workspace_except, - (window_should_be_showing): access showing_desktop through the - active workspace - - * src/workspace.c (meta_workspace_new): initialize - workspace->showing_desktop, (meta_workspace_activate_with_focus): - add note that old can be NULL, update showing_desktop_hint if - different on this workspace than the previous one - - * src/workspace.h (struct _MetaWorkspace): add showing_desktop - field - -2004-10-16 Elijah Newren - - * rationales.txt: Add new tracker bugs - -2004-10-15 Elijah Newren - - * src/keybindings.c (reload_keymap): Fix from Rob to correct - requested number of keycodes (#155247) - -2004-10-13 Elijah Newren - - Code cleanup - - * src/window.c (is_in_dock_group, docks_at_end_cmp, - shuffle_docks_to_end): removed functions, - (meta_window_notify_focus): no need to call is_in_dock_group or - shuffle_docks_to_end because of the patch from #120100 that was - committed. - -2004-10-13 Vincent Untz - - Add a keybinding to launch a terminal - - * src/keybindings.c: (handle_run_terminal): new function, - (error_on_generic_command): new function, (error_on_command): wrapper - around error_on_generic_command(), (error_on_terminal_command): new - function - - * src/metacity.schemas.in: add run_command_terminal key - - * src/prefs.[ch]: (meta_prefs_init): cache the terminal command and - register a gconf callback to update it, (change_notify): handle the - notification of terminal command changes, (meta_preference_to_string): - add the terminal command case, (update_terminal_command): new function, - (meta_prefs_get_terminal_command): new function, - (meta_prefs_get_gconf_key_for_terminal_command): new function - -2004-10-11 Rob Adams - - * configure.in: bump version to 2.9.0. Add UNSTABLE warning. - -2004-10-11 Rob Adams - - * NEWS, README: Metacity 2.8.6 (stable release) - -2004-10-08 Elijah Newren - - Fix middle-frame-click-to-lower focus inconsistency (#154601) - - * src/core.c (meta_core_user_lower_and_unfocus): focus the default - window in all focus modes, not just click-to-focus (EnterNotify - events will not handle this case for sloppy and mouse focus) - - * src/display.c (event_callback): replace window->has_focus with - window == display->expected_focus_window to avoid a race issue - -2004-10-08 Elijah Newren - - Alter the meaning of expected_focus_window; doesn't affect - current operation but assists in fixing some other bugs - (#154598) - - * src/display.c (meta_display_focus_the_no_focus_window): set the - expected_focus_window to NULL. - - * src/window.c (meta_window_notify_focus): don't NULL the - expected_focus_window when that window receives a FocusIn event - -2004-10-04 Elijah Newren - - * src/display.c (event_callback): if the root window gets focused, - set the focus to the default window; this fixes the - "focus-follows-mouse" behavior seen for click-to-focus mode after - cancelling log out (fixes #153220) - -2004-10-04 Elijah Newren - - Fix a variety of issues with autoraise (#134206) - - * src/display.h: (struct _MetaDisplay): add an autoraise_window - parameter - - * src/display.[hc] (meta_display_focus_the_no_focus_window): new - function, (meta_display_queue_autoraise_callback): new function, - (meta_display_remove_autoraise_callback): new function - - * src/display.c (meta_display_open): intialize - display->autoraise_window too, (meta_display_close): remove any - pending autoraise callback, (window_raise_with_delay_callback): - clear out auto_raise->display->autoraise_window too, - (event_callback): call meta_display_queue_autoraise_callback - instead of having the code inline, call - meta_display_focus_the_no_focus_window to handle focusing that - window - - * src/window.c (meta_window_focus): If there's a window with an - autoraise timeout that isn't the window being focused, remove the - autoraise timeout - - * src/workspace.c (meta_workspace_focus_default_window): If no - autoraise timeout is queued for the given window then queue one - now, call meta_display_focus_the_no_focus_window to handle - focusing that window, (meta_workspace_focus_mru_window): call - meta_display_focus_the_no_focus_window to handle focusing that - window - -2004-10-04 Elijah Newren - - * src/display.c (event_callback): When no window becomes focused, - focus the default window instead of punting to the - no_focus_window. Also, change the warning to a verbose - message--this will happen frequently due to brain-damage in the X - protocol. (see #125492) - -2004-10-04 Elijah Newren - - Fix a variety of focus race conditions in all focus modes, or at - least make them harder to trigger (fixes #152000) - - * src/core.[ch] (meta_core_user_lower_and_unfocus): add a - timestamp parameter; pass it along to - meta_workspace_focus_default_window - - * src/display.[ch] (meta_display_get_current_time_roundtrip): new - function - - * src/display.c (event_callback): pass a timestamp to the - meta_workspace_activate and meta_workspace_focus_default_window - function calls - - * src/frames.c (meta_frames_button_press_event): pass a timestamp - to meta_core_user_lower_and_unfocus - - * src/keybindings.c (handle_activate_workspace): pass a timestamp - to meta_workspace_activate, (process_workspace_switch_grab): pass - a timestamp to meta_workspace_focus_default_window and - meta_workspace_activate, (handle_toggle_desktop): pass a timestamp - to meta_workspace_focus_default_window, - (do_handle_move_to_workspace): pass a timestamp to - meta_workspace_activate_with_focus, (handle_workspace_switch): - meta_workspace_activate - - * src/screen.c (meta_screen_new): pass a timestamp to - meta_workspace_activate - - * src/window.c (meta_window_free): pass a timestamp to - meta_workspace_focus_default_window, (idle_calc_showing): don't - increment the focus sentinel here, (meta_window_minimize): pass a - timestamp to meta_workspace_focus_default_window, - (meta_window_client_message), pass a timestamp to - meta_workspace_focus_default_window - - * src/workspace.h (meta_workspace_activate): add timestamp - parameter, (meta_workspace_activate_with_focus): add timestamp - parameter, (meta_workspace_focus_default_window): add timestamp - parameter - - * src/workspace.c (meta_workspace_focus_mru_window): make this - function take a timestamp and use it for meta_window_focus or - XSetInputFocus, (meta_workspace_activate_with_focus): make this - function take a timestamp and pass it along to meta_window_focus - and meta_workspace_focus_default_window, - (meta_workspace_activate): make this function take a timestamp and - pass it to meta_workspace_activate_with_focus), - (meta_workspace_focus_default_window): make this function take a - timestamp, warn if its 0 but try to handle that case sanely, and - pass the timestamp on to meta_window_focus or - meta_workspace_focus_mru_window or XSetInputFocus - -2004-09-22 Elijah Newren - - * src/keybindings.c (process_workspace_switch_grab): Focus the - default window after the user dismisses the workspace switcher - popup (fixes #123803; note that an alternate fix was made - independently by David Baron for sloppy and mouse focus users) - -2004-09-22 Elijah Newren - - Fix some uninitialized variable errors reported by valgrind (see - #153338) - - * src/display.c (meta_display_open): initialize - display->grab_resize_timeout_id, and display->grab_have_keyboard - - * src/ui.c (meta_ui_create_frame_window): initialize attrs.width - and attrs.height - -2004-09-17 Elijah Newren - - * src/workspace.c (meta_workspace_focus_mru_window): Don't focus a - window that is minimized (fixes #147947) - -2004-09-17 Kjartan Maraas - - * src/bell.c: (meta_bell_flash_screen): - * src/compositor.c: - * src/effects.c: (meta_effects_draw_box_animation): - * src/fixedtip.c: (meta_fixed_tip_show): - * src/frame.c: (find_argb_visual): - * src/frames.c: (unsigned_long_hash), (meta_frames_manage_window), - (meta_frames_apply_shapes): - * src/iconcache.c: (find_largest_sizes), (find_best_size): - * src/keybindings.c: (meta_spawn_command_line_async_on_screen): - * src/main.c: (main): - * src/menu.c: (meta_window_menu_new): - * src/prefs.c: (meta_prefs_get_visual_bell), - (meta_prefs_bell_is_audible), (meta_prefs_get_visual_bell_type), - (meta_prefs_get_action_double_click_titlebar), - (meta_prefs_get_auto_raise), (meta_prefs_get_auto_raise_delay), - (meta_prefs_get_reduced_resources): - * src/screen.c: (meta_create_offscreen_window): - * src/tabpopup.c: (meta_ui_tab_popup_get_selected): - * src/theme-parser.c: (meta_theme_load): - * src/theme.c: (meta_gtk_widget_get_font_desc): - * src/tools/metacity-mag.c: (mouse_press), (begin_area_grab): - * src/util.c: (meta_unsigned_long_hash): A load of fixes of issues - reported by sparse. Closes bug #152849 - -2004-09-15 Elijah Newren - - * src/display.c (event_callback): Remove some redundant code - regarding focusing the default window (#152117) - -2004-09-15 Elijah Newren - - Patch from Ken Harris in #135786 to focus a new default window - when lowering via middle-click on the frame. - - * src/core.[hc], src/frames.c: rename meta_core_user_lower to - meta_core_user_lower_and_unfocus - - * src/core.c (meta_core_user_lower_and_unfocus): if in - click-to-focus mode then also move the window to the back of the - mru list and focus the new default window for the active workspace - -2004-09-15 Elijah Newren - - Focus the no_focus_window if no suitable window is in the mru list - (should fix the almost contrived extra issue found in #147475) - - * doc/how-to-get-focus-right.txt: We no longer need to lie about - only focusing panels upon explicit request. - - * src/workspace.c: (meta_workspace_focus_top_window): removed this - function--it was more code than needed and was unreliable anyway, - (meta_workspace_focus_mru_window): if a suitable window isn't in - the mru list, focus the no_focus_window instead of calling - focus_top_window. - -2004-09-15 Elijah Newren - - Prevent focus inconsistencies by only providing one focus method - (fixes #151990) - - * src/screen.c (meta_screen_show_desktop): remove call to - meta_workspace_focus_top_window (it was merely focusing a window - that was going to be hidden anyway, and likely the one that - already had focus) - - * src/workspace.[hc]: remove meta_workspace_focus_mru_window and - meta_workspace_focus_top_window from workspace.h, make them static - functions in workspace.c - -2004-09-15 Elijah Newren - - Remove race condition for focus window choice on window close - followed by rapid mouse movement in sloppy and mouse focus modes - (partially fixes #152000) - - * src/window.c (meta_window_free): Don't increment the focus - sentinel for windows being freed, (idle_calc_showing): don't - increment the focus sentinel for windows being minimized - -2004-09-15 Elijah Newren - - Fix unwanted loss of focus to the mouse window when using keynav - (fixes #101190) - - * src/display.c (event_callback): Ignore EnterNotify events with - xcrossing.mode of either NotifyGrab or NotifyUngrab - -2004-09-15 Elijah Newren - - Focus correct window after minimizing via the tasklist (fixes - #128200; see also #107681) - - * src/display.h (struct _MetaDisplay): track the - previously_focused_window - - * src/display.c (meta_display_open): initialize - previously_focused_window - - * src/window.c (meta_window_free): clear the - previously_focused_window if it's being freed, - (meta_window_client_message): if we get a request to minimize the - previously_focused_window and the focus_window is a dock or the - desktop, focus the default window, (meta_window_notify_focus): - update the previously_focused_window - -2004-09-13 Rob Adams - - * configure.in: post-release increment - -2004-09-13 Rob Adams - - * configure.in: bump version number - - * NEWS: 2.8.5 release - - * README: 2.8.5 release - -2004-09-14 Gora Mohanty - - * configure.in: Added 'or' to ALL_LINGUAS. - -2004-09-07 Elijah Newren - - Add a new write-up on making window focus consistent (see #152004) - - * doc/how-to-get-focus-right.txt: New document - - * rationales.txt: Remove references to focus bugs, instead point - to doc/how-to-get-focus-right.txt - -2004-09-06 Elijah Newren - - * rationales.txt: Add bugs regarding window focus - -2004-08-29 Elijah Newren - - * NEWS: 2.8.4 release - -2004-08-29 Elijah Newren - - * src/window.c (window_takes_focus_on_map): Disable - focus-stealing-prevention for now; there are still some issues and - hard code freeze is tomorrow...so this will have to wait until - Gnome 2.10. - -2004-08-27 Havoc Pennington - - * src/compositor.c (meta_compositor_new): disable NameWindowPixmap - stuff always for now, it seemed kind of busted - (paint_screen): don't grab the server during repaint, adds to the - speed, though only slightly. - - * src/frames.c (meta_frames_set_window_background): factor out all - the set_background stuff to one function; disable setting - background to transparent, because it breaks existing themes. We - need to add a flag in the theme XML file to say "start me with a - transparent background" - -2004-08-27 Elijah Newren - - Prevent an assertion failure that can occur after increasing the - number of workspaces; also fix a warning and stacking order when a - window is denied focus (fixes #150615) - - * src/window.c (meta_window_stack_just_below): the position of the - window should be set equal to that of the one we want to be below, - not 1 lower than that number - - * src/workspace.c (maybe_add_to_list): new function to add - on_all_workspace windows to an mru_list, (meta_workspace_new): - call maybe_add_to_list for all windows on the screen in order to - initialize the mru_list - -2004-08-26 Havoc Pennington - - * src/frame.c: delete extra copy of find_argb_visual so things - compile - - * src/compositor.c (HAS_NAME_WINDOW_PIXMAP): copy the - XCompositeNameWindowPixmap() stuff from xcompmgr, though I can't - say I really know what it's supposed to help with (painting the - window border?) - -2004-08-26 Havoc Pennington - - * src/frame.c, src/theme.c: couple of cosmetic tweaks from - resolving my local patch with the bugzilla patch from the 8-19 - entry below - -2004-08-26 Havoc Pennington - - * configure.in: move the have_xrender variable initialization up - in the file since it can be set as part of composite check - -2004-08-19 Havoc Pennington - - Fixes from Rich Wareham - - * src/display.h (struct _MetaDisplay): add render extension check - to the display - - * src/display.c: check for render - - * configure.in: don't build compositing manager by default, don't - want any nasty surprises; check for render separately from - compositing manager - - * src/frame.c: use an ARGB visual when available for the window - frame, so we can be all cool-ass - -2004-08-25 Elijah Newren - - Make dialogs that Metacity shows follow focus-stealing-prevention - conventions. (fixes one issue in #149028; see comments 47-54) - - * src/delete.c (delete_ping_reply_func, - delete_ping_timeout_func): Make callback functions take a - timestamp arg, (delete_ping_timeout_func): pass the timestamp to - metacity-dialog - - * src/display.c (meta_display_ping_timeout): add a timestamp to - the call to the ping_timeout_func, (meta_display_ping_window, - process_pong_message): add a timestamp to the call to the - ping_reply_func - - * src/display.h (MetaWindowPingFunc typedef): add a timestamp to - this function typedef - - * src/keybindings.c (error_on_command): require a timestamp and - pass the timestamp on to metacity-dialog, (handle_run_command): - pass a timestamp to error_on_command - - * src/metacity-dialog.c (copy_of_gdk_x11_window_set_user_time): - new function (temporary; only for use while using gtk+-2.4), - (kill_window_question, warn_about_no_sm_support, - error_about_command): make these functions take a timestamp and - call copy_of_gdk_x11_window_set_user_time, (main): require the - first two args to the program to be "--timestamp " - - * src/session.c (warn_about_lame_clients_and_finish_inter): pass a - timestamp of 0 to metacity-dialog to prevent focus (it's a popup - not generated by and kind of user request). - -Fri Aug 20 12:54:12 2004 Soeren Sandmann - - * src/display.c (meta_display_end_grab_op): Move wireframe code - before grab is released to prevent endless loops with fullscreen - windows. - -2004-08-18 Havoc Pennington - - * src/display.h (struct _MetaDisplay): track the last_xor_rect - separately from the current window size, and then use that to - paint the wireframe including the frame, and taking into - account shaded windows. - - * src/window.c (meta_window_get_xor_rect): new function to compute - the xor rect; it is not really 100% right, because it uses the - frame dimensions from the window at the start of the move/resize. - But probably won't break in practice. - -2004-08-17 Christian Rose - - * configure.in: Added "bs" to ALL_LINGUAS. - -2004-08-16 Kjartan Maraas - - * configure.in: Added nb to ALL_LINGUAS. - -2004-08-15 Rob Adams - - * configure.in: Bump version to 2.8.4 - -2004-08-15 Rob Adams - - * NEWS: 2.8.3 release - -2004-08-15 Rob Adams - - * src/windows.c (meta_window_update_struts): use height and - top/bottom struts to compute gap (copy/paste bug). - -2004-08-15 Rob Adams - - * src/window.c (meta_window_update_struts): Allow struts larger - than 1/2 the screen width/height, as long as there's a minimum - sized gap between them. Patch from Bill Haneman - for bug #144126. - -2004-08-13 Gurban M. Tewekgeli - * po/tk.po: Added Turkmen translation. - * configure.in: Added "tk" to ALL_LINGUAS. - -Mon Aug 9 05:38:33 2004 Soeren Sandmann - - * src/effects.c (graphics_sync): New function. - * src/effects.c (effects_draw_box_animation_timeout): Use it here - to synchronize with the hardware between each frame. - -2004-08-08 Rob Adams - - * src/window.c (meta_window_move_resize_internal): Add #ifdef - around XSYNC code; fixes compile problem if XSYNC is disabled. - Path for #149314 from Peter O'Shea and independently Mike Castle. - -Sun Aug 8 14:20:00 2004 Soeren Sandmann - - * src/frame.c (meta_frame_set_screen_cursor): Flush after setting - cursor. (Rest of #149413). - -2004-08-07 Elijah Newren - - * src/display.c (event_callback): activating the current workspace - should be a no-op. This prevents a race condition in focus window - choice when activating a window via the taskbar. Fix for #149589. - -2004-08-07 Elijah Newren - - * src/window.c, src/window.h: Revert Rob's 2004-07-31 patch that - ignored net_wm_user_time when unminimizing a window - - * src/window.c (meta_window_activate): If a nonzero timestamp is - passed, update the window's net_wm_user_time accordingly. (see - comments 102-108 of bug 118372) - -2004-08-07 Rob Adams - - Remove some extraneous items that could sometimes appear in the - window menu. Fix for #144493. - - * src/menu.c (menuitems): Change the second separator to key on - whether there are any workspaces. - (meta_window_menu_new): use NULL label instead of 0 op to identify - separator - - * src/window.c (meta_window_show_menu): Change the conditions on - the directions to take into account "holes" in the workspace - layout and also only set META_MENU_OP_WORKSPACES when there's more - than one workspace. - -2004-08-07 Havoc Pennington - - * src/screen.c (meta_screen_set_cursor): add XFlush() after - setting cursor, #149413 - -2004-08-06 Elijah Newren - - * src/display.c (event_callback): Focusing a window upon unshowing - the desktop in various ways (panel applet or keybinding) was - inconsistent for sloppy and click focus modes. Fix this by - calling meta_workspace_focus_default_window after unshowing the - desktop via a _NET_SHOWING_DESKTOP message. (resolves #149543) - -2004-08-06 Elijah Newren - - * src/workspace.c (meta_workspace_focus_default_window): prevent - keyboard from "getting locked" upon workspace switch, by making - sure that the no_focus_window has focus if no other window does. - (fixes #147475) - -2004-08-05 Elijah Newren - - Have newly mapped windows that are denied focus appear after the - focused window in the alt-tab list. This allows one to switch to - such a window with a single alt-tab press. (fixes #149366) - - * src/window.c (ensure_mru_position_after): new function, - (meta_window_show): If newly mapped window is denied focus, call - ensure_mru_position_after to make the window appear after the - focus window in the mru list. - -2004-08-05 Elijah Newren - - * src/window.c (meta_window_stick): prepend window to mru list - instead of appending, since making the window sticky should imply - that it is the most recently used, not the least recently. (fixes - #149369) - -2004-08-04 Elijah Newren - - * configure.in: post-release version bump (2.8.3) that I forgot to - do yesterday. - -2004-08-03 Elijah Newren - - Released 2.8.2 - - * NEWS, README: update - -2004-08-02 Elijah Newren - - Fix some bugs (reported in #120100) regarding the focus window - when using the workspace switcher. - - * src/display.c (event_callback): When switching workspaces due to - a _NET_CURRENT_DESKTOP message, make sure to focus the default - window as well. - - * src/workspace.c (meta_workspace_focus_default_window, - meta_workspace_focus_mru_window): Make DOCK or DESKTOP windows - have lower priority than others when choosing a window to focus. - (For the former function, this means don't focus them at all; for - the latter, this means only focus them (via the - meta_workspace_focus_top_window call) if no other mru window can - be found.) - -2004-07-31 Rob Adams - - Fix bug that caused windows to not be focused on unminimizing - because of user time support. - - * src/window.c (meta_window_new_with_attrs): initialize - focus_despite_user_time bit - (window_takes_focus_on_map): focus if focus_despite_user_time - despite user time, interestingly enough - (meta_window_show): reset focus_despite_user_time after showing - - * src/window.h (_MetaWindow): add focus_despite_user_time bit - -2004-07-31 Rob Adams - - Fix some support for EWMH hints, and fix USER_TIME support to - include the DEMANDS_ATTENTION hint. Also includes some code for - implementing _NET_RESTACK_WINDOW and _NET_MOVERESIZE_WINDOW, but - this is disabled pending feature thaw. - - * COMPLIANCE: update with new information - - * src/display.c (meta_display_open): add new hints to list - - * src/display.h (_MetaDisplay): Add new atoms to struct - - * src/screen.c (set_supported_hint): update the list of support - hints. - (set_desktop_viewport_hint): new function sets the viewport hint - to (0,0) as required by the spec for WMs with no viewport support. - (set_desktop_geometry_hint): new function to set the desktop size - hint to the size of the display, since we don't implement large - desktop support, as required by the spec. - (meta_screen_resize): update the geometry hint on screen resize - - * src/window.c (meta_window_new_with_attrs): Initialize - demands_attention state - (set_net_wm_state): Set demands_attention hint in the window state - (meta_window_show): If we don't pop up a window because of - USER_TIME, set DEMANDS_ATTENTION on the window. - (meta_window_focus): When a window receives focus, remove - DEMANDS_ATTENTION hint - (meta_window_client_message): Allow other apps to set - DEMANDS_ATTENTION on a window. Also, if the _NET_ACTIVE_WINDOW - hint includes a timestamp, use it. - (update_net_wm_state): Read DEMANDS_ATTENTION state also - - * src/window.h (_MetaWindow): add wm_state_demands_attention bit. - -2004-07-22 Rob Adams - - * src/metacity.schemas.in: Add trailing quotes to keybinding - explanation text. Patch from Emil Soleyman-Zomalan. - -Fri Jun 25 17:41:53 2004 Soeren Sandmann - - * configure.in: Require startup-notification 0.7 - -2004-06-25 Rob Adams - - * COMPLIANCE: indicate that _NET_WM_USER_TIME is now supported - -2004-06-24 Elijah Newren - - * src/keybindings.c: (handle_toggle_desktop): Choose correct - window to focus when "un-showing" the desktop. Fixes #144900. - -2004-06-24 Elijah Newren - - Make choice of focus window be consistent for each focus mode. - Fixes #135810. - - * src/delete.c: (meta_window_delete): In some #if 0'ed code, - replace meta_workspace_focus_mru_window with - meta_workspace_focus_default_window (just in case the code becomes - un-#if 0'ed out). - - * src/screen.c, src/screen.h: Change - meta_screen_focus_mouse_window to meta_screen_get_mouse_window, - and don't focus the window when found but rather return it. - - * src/window.c: (meta_window_free, meta_window_minimize): replace - meta_workspace_focus_mru_window with - meta_workspace_focus_default_window. - - * src/workspace.c: (meta_workspace_focus_default_window): Focus - appropriately for the given focus method: - click-to-focus: focus MRU window (== toplevel window) - sloppy focus: focus the window under the pointer if there is - such a window, otherwise focus the mru window - mouse focus: focus the window under the pointer if there is - such a window, otherwise don't focus anything - -2004-06-24 Elijah Newren - - * src/window.c: Avoid a race condition on the choice of window to - focus after the previously focused window gets closed or - minimized. Fixes #131582. - -2004-06-24 Elijah Newren - - * src/metacity.schemas.in: make naming for "move a window"/"move - the window"/"move window" more consistent. Patch from Michael - Terry for #142235. - -2004-06-24 Elijah Newren - - * src/session.c: Change meta_warning to meta_topic on failure to - connect to a session manager. Fixes #136218. - -2004-06-17 Elijah Newren - - Add support for _NET_WM_USER_TIME - - * src/display.c: - (meta_display_open): Add _NET_WM_USER_TIME to atom_names[], - (event_callback): Manually set _NET_WM_USER_TIME upon KeyPress - (doesn't work since keyboard isn't grabbed) and ButtonPress (does - work), this is just a fallback for applications that don't update - this themselves. - - * src/display.h: (struct _MetaDisplay): Add atom_net_wm_user_time field - - * src/screen.c: (meta_screen_apply_startup_properties): Check for - TIMESTAMP provided from startup sequence as well. - - * src/stack.c: - s/meta_window_set_stack_position/meta_window_set_stack_position_no_sync/, - (meta_window_set_stack_position): New function which calls the - meta_window_set_stack_position_no_sync function followed immediately - by calling meta_stack_sync_to_server. - - * src/window-props.c: - (init_net_wm_user_time), (reload_net_wm_user_time): new functions, - (reload_wm_hints): also load atom_net_wm_user_time - - * src/window.c: - new XSERVER_TIME_IS_LATER macro (accounts for timestamp wraparound), - (meta_window_new_with_attrs): add timestamp attributes, - (window_takes_focus_on_map): use TIMESTAMP from startup - notification and _NET_WM_USER_TIME to decide whether to focus new - windows, - (meta_window_show): if app doesn't take focus on map, place it - just below the focused window in the stack - (process_property_notify): check for changes to _NET_WM_USRE_TIME, - (meta_window_stack_just_below): new function - - * src/window.h: - (_MetaWindow struct): new fields for initial_timestamp, - initial_timestamp_set, net_wm_user_time_set, and net_wm_user_time, - (meta_window_stack_just_below): new function - -2004-06-21 Anders Carlsson - - * src/common.h: - * src/menu.c: (menu_closed), (activate_cb): - * src/window.c: (menu_callback): - Add a timestamp argument to menu functions and - use it in meta_window_delete. - -2004-06-21 Anders Carlsson - - * src/window.c: (meta_window_client_message): - Get the timestamp from the client message. - -Sat Jun 19 02:21:08 2004 Soeren Sandmann - - Fix bug 143333, support for update counter spec, and 109362, - schedule compensation events when events are ignored. - - * src/display.c (meta_display_open): Add _NET_WM_SYNC_REQUEST and - _NET_WM_SYNC_REQUEST_COUNTER atoms. Remove the old - METACITY_SYNC_COUNTER stuff. - (meta_display_begin_op): Setup the sync counter - - * src/xprops.c, src/xprops.h, src/window-props.c, src/display.h: - Add new atoms. - - * src/window.c (send_sync_request): new function. - (meta_window_move_resize_internal): send a sync request before - resizing. - (check_move_resize_frequence): Rework logic to also check the SYNC - case. If an event is ignored return the remaining time. - (update_resize_timeout): Timeout that gets called when a - compensation event is scheduled. - (uddate_resize): schedule compensation events when an event is - ignored. - (meta_window_handle_mouse_grap_op_event): When an alarm is - received and sync was turned off, turn it back on. - - * src/window.h (struct MetaWindow) Add some variables - -2004-06-16 Havoc Pennington - - * configure.in: bump version, add the UNSTABLE note - - * Branch off GNOME 2.6, we are now officially unstable - -2004-06-04 Jeff Waugh - - * src/metacity.schemas.in: Set titlebar_uses_system_font = false. The - previous default was almost violent in its lack of appreciation for - human beings. In fact, this entire setting should probably be removed, but - for now, let's just fix the default. Permission granted by Havoc. - -2004-05-04 Elijah Newren - - * configure.in: 2.8.1 - - * NEWS: update - -2004-05-02 Rob Adams - - * src/metacity-dialog.c (warn_about_no_sm_support): make the no sm - support warning dialog resizable, since the default GTK warning - dialog not has default not resizable. Fix for #141672 from - Olivier Crete. - -2004-04-29 Rob Adams - - * src/prefs.c (change_notify): Add a value type check for the - visual bell/audible bell gconf settings. Patch from Jarrod - Johnson for #141409. - -2004-04-19 Mark McLoughlin - - Syncing across this change from libwnck. - Patch from Neil Muller in bug #133979. - - * src/iconcache.c: (find_largest_sizes), (find_best_size): - Don't down-size nitems from a gulong to an int. Fixes a - crash with enlightenment, apparently. - -2004-04-16 Iñaki Larrañaga - - * configure.in: Added "eu" (Basque) to ALL_LINGUAS. - -2004-04-15 Elijah Newren - - * src/display.c: Prevent unwanted grab op from occurring. - Previously, for some people under certain conditions, clicking and - releasing the mouse button rapidly enough would result in Metacity - starting a move operation due to ignoring the button release. - This should fix that problem (it does for me). See bug 136587. - -2004-04-11 Rob Adams - - * configure.in: Make the --enable-xinerama switch work properly. - Fix for #138562 from foser@gentoo.org. - -2004-04-09 Guntupalli Karunakar - - * configure.in: Added "gu" (Gujarati) to ALL_LINGUAS. - -2004-03-27 Tõivo Leedjärv - - * configure.in: Added et to ALL_LINGUAS. - -2004-03-24 Guntupalli Karunakar - - * configure.in: Added "pa" (Punjabi) to ALL_LINGUAS. - -2004-03-21 Havoc Pennington - - * configure.in: 2.8.0 - - * NEWS: update - -2004-03-07 Elijah Newren - - * rationales.txt: Bring up to date (see bug 136252). - -2004-03-07 Havoc Pennington - - * configure.in: 2.7.1 - -2004-03-04 Paisa Seeluangsawat - - * configure.in: Added "th" (Thai) to ALL_LINGUAS. - -2004-03-01 Rob Adams - - * src/stack.c (compute_layer): don't promote due to transiency; we - handle that elsewhere now. - (ensure_above): perform layer promotion here as well as stack - position promotion. Note that this means that we need to do stack - constraints now on layer change now. - (get_maximum_layer_of_ancestor): remove function - (max_layer_func): remove function - (MaxLayerData): remove struct - -2004-02-28 Rob Adams - - Revert 2/27 patch for layer promotion. - -2004-02-27 Rob Adams - - * src/window.c (meta_window_notify_focus): only move on MRU list - if the window belongs on the workspace, since the FocusIn event - could be for a window whose workspace we've since switched away - from. Possible fix for #122016. - - * src/workspace.c (meta_workspace_contains_window): search for the - workspace in window->workspaces rather than the window in - workspace->windows. Since the number of workspaces is at most 36, - this is a O(1) lookup rather than a O(n) lookup. Sorry; couldn't - resist. - -2004-02-27 Rob Adams - - * src/metacity.schemas.in: Change - move_to_workspace_left/right/up/down keybindings to - arrow to avoid conflicting with new - keybindings in spacial nautilus. - -2004-02-27 Rob Adams - - Handle layer promotion of transient descendants of layer-promoted - windows to also be layer promoted, using a simple iterative - algorithm. - - * src/stack.c (compute_layer): change name to promote_layer, and - convert to simply perform any necessary layer promotion without - computing the standalone layer. - (max_layer_func): use window->layer instead of - get_standalone_layer - (get_maximum_layer_of_ancestor): use window->layer instead of - get_standalone_layer - (meta_stack_ensure_sorted): implement iterative algorithm, - explained in a long comment. - - * src/window.h: add a tmp_layer field used by stack.c for - determining if the stack is dirty or not, since maintaining this - information in meta_stack_ensure_sorted is no longer practical. - -2004-02-23 Rob Adams - - Add my copyright notice to a number of files on which it should - already exist. - - * src/window.c (meta_window_notify_focus): modify code to move to - front of MRU list so that we can have an assert that it was there - in the first place. This code may be causing some crashes. See - #131196. - -2004-02-22 Christian Rose - - * configure.in: Added "en_CA" to ALL_LINGUAS. - -2004-02-19 Rob Adams - - * src/prefs.h: remove trailing comma in MetaKeyBindingAction enum. - Fix for #134868 thanks to bugzilla-gnome@thewrittenword.com. - -2004-02-16 Rob Adams - - * src/window.c (update_move): reset drag state after shaking loose - or reattaching. Fix for #132625. - -2004-02-15 Anders Carlsson - - * src/menu.c (meta_window_menu_new): Actually translate a message, - don't just mark it for translation. - -2004-02-14 Elijah Newren - - * src/workspace.c: When moving a window to a different workspace, - prepend it to the mru list insted of appending it. Fixes #134368. - -2004-02-14 Rob Adams - - If we're moving a window and receive a _NET_CURRENT_DESKTOP - message indicating a workspace switch, bring along the drag window - to the new workspace, solving a potentially weird bug where the - window would be lost on the old workspace. This also makes it - possible to implement edge flipping in an external program with - just a few lines of code. Patch for #131630 from ed@catmur.co.uk. - - * src/keybindings.c (switch_to_workspace): remove function -- no - longer needed. - (handle_activate_workspace): call meta_workspace_activate instead - of switch_to_workspace - - * src/workspace.c (meta_workspace_activate_with_focus): if we're - in a move grab op, bring along the drag window. - -2004-02-14 Rob Adams - - * configure.in: Add configure option to not even try using - xinerama, to make metacity buildable on systems with no shared - library version of the xinerama libraries. Patch for #134203 from - Julio M. Merino Vidal. - -2004-02-01 Rob Adams - - * COMPLIANCE: Bring up to date with current draft EWHM. - -2004-01-27 James M. Cape - - * src/themes/Esco/metacity-theme-1.xml: Use the 'utility' frame - for dialogs too. - -2004-01-24 James M. Cape - - * src/themes/Esco/metacity-theme-1.xml: Updated this theme. - -2004-01-21 Elijah Newren - - * src/screen.c (set_supported_hint): Removed some duplicate - entries. - -2004-01-17 Rob Adams - - * src/metacity.schemas.in: Default binding removed for - toggle_shaded, since we don't have anything in the graphical UI - for it any more. - -2004-01-17 Rob Adams - - * src/window.c (meta_window_show_menu): Don't show - left/right/up/down if a window is sticky. Make "On Top" - insensitive for docks, splash screens, and desktops since it has - no effect anyway. - -2004-01-10 Rob Adams - - * src/metacity.schemas.in: update default - action_double_click_titlebar to be toggle_maximize instead of - toggle_shade. See #131126. - -2004-01-10 Rob Adams - - * src/constraints.c (meta_window_constrain): if we maximize after - placement, and the window is too big to fix in the work area, - define a sane saved_rect approximately with dimensions - three-quarters approximately three quarters the size of the work - area. This avoids the problem where large windows would - unmaximize and actually get bigger. See #93590. - -2004-01-09 Thomas Fitzsimmons - - Add _NET_FRAME_EXTENTS and _NET_REQUEST_FRAME_EXTENTS. - - * src/display.c: include xprops.h - (process_request_frame_extents): new function - (meta_display_open): add _NET_FRAME_EXTENTS and - _NET_REQUEST_FRAME_EXTENTS atoms - (event_callback): handle frame extents message - - * src/display.h (struct _MetaDisplay): add atom_net_frame_extents - and atom_net_request_frame_extents - - * src/theme.c (meta_pango_font_desc_get_text_height): make font_desc - parameter const - - * src/ui.c: include prefs.h - (meta_ui_theme_get_frame_borders): new function - - * src/window.c (update_net_frame_extents): new function - (meta_window_move_resize_internal): update frame extents - property when frame geometry changes - - * src/screen.c (set_supported_hint): add atom_net_frame_extents - and atom_net_request_frame_extents - -2004-01-09 Calum Benson - - * src/themes/Atlanta/metacity-theme-1.xml: - - Ensure Atlanta window buttons get larger when using large - print themes. Fixes #123469. - -2003-01-04 Rob Adams - - Maintain the button grab for sloppy and mouse focus all the time. - This fixes a number of problem introduced by trying to drop the - grab; we now do this only for click to focus mode. This has the - unfortunate effect that #102209 reappears for sloppy and mouse - focus, but this seems unavoidable, because of limitations in the X - protocol. See #115072. - - * src/display.c (meta_display_grab_focus_window_button): #if 0 the - section on not grabbing unless in click-to-focus mode. - - * src/window.c (meta_window_notify_focus): drop focus button grab - on FocusIn and acquire it on FocusOut only when in click-to-focus - mode. - -2004-01-03 Robert Sedak - - * configure.in: Added "hr" in ALL_LINGUAS. - -2003-01-02 Rob Adams - - * README: Update reference to EWMH. - - * HACKING: Add a reference to COMPLIANCE and to the ICCCM and - EWHM. - -2003-12-25 Havoc Pennington - - * src/compositor.c (process_reparent): handle ReparentNotify, and - add a lot of debug output. - -2003-12-25 Havoc Pennington - - * src/compositor.c (meta_compositor_process_event): change to - track all children of the root window, not only mapped children; - this keeps us from losing track of the stacking order - - * src/display.c (event_callback): don't do any of the compositor - event handling inline, do it all in compositor.c - -2003-12-21 Rob Adams - - Reorganize the window menu according to discussion on #110904. - The workspace name mnemonic chunk of the patch is thanks to - Jonathan Blandford. - - * src/common.h: add MENU_OP_ABOVE, MENU_OP_UNABOVE, MENU_UP_MOVE_TO_* - menu ops. - - * src/core.c (meta_core_get_menu_accelerator): add accelerator for - the new menu ops. - - * src/menu.c: add checked attribute in _MenuItem struct to display - a checkmark next to a menu item. Add the new menu items to - menuitems. - (get_workspace_name_with_accel): Add mnemonics even to renamed - workspaces. - (menu_item_new): provide support for the checked attribute - (meta_window_menu_new): construct new submenu for workspace - switching. - - * src/window.c (menu_callback): implement support for the new menu - ops. - (meta_window_show_menu): don't use the OP_*SHAPE operations, and - compute which of the OP_MOVE_TO_* ops should be used for the - current workspace and workspace layout. Add the OP_*ABOVE - operations. - -2003-12-20 Arafat Medini - - * configure.in: Added Arabic locale "ar" to ALL_LINGUAS - -2003-12-17 Rob Adams - - * src/display.c (meta_display_open): initialize - grab_wireframe_active to FALSE. Fix for #128090. - -2003-12-17 Rob Adams - - * src/tabpopup.c (meta_ui_tab_popup_new): Don't try to call - utf8_strndup on a null title for an entry. Fix for #128566. - - * src/workspace.c (meta_workspace_free): Call g_list_free on the - mru_list, since with sticky windows that MRU list could well not - be emtpy. See #122016. - -2003-12-13 Rob Adams - - * src/window.c (meta_window_new_with_attrs): set on_all_workspaces - in all cases _before_ adding to the workspaces, so that windows - initially on all workspaces are added correctly to the MRU lists. - Fix for #120907. - - * src/workspace.c (meta_workspace_add_window): handle sticky - windows so that we add to add mru lists if needed - (meta_workspace_remove_window): handle sticky windows so that they - are removed from all mru lists if needed. - -2003-12-12 Havoc Pennington - - * src/window.c (meta_window_free): unstick window to get it out of - mru_list it should not be in; assert that window has been removed - from all mru_list. Perhaps fixes #122016 crash. - -2003-11-29 Havoc Pennington - - * fix up compositing manager to somewhat work - -2003-11-26 Rob Adams - - * COMPLIANCE: fix a couple of minor typos. - -2003-11-24 Havoc Pennington - - * src/compositor.c (meta_compositor_new): fix the extension checks - -2003-11-24 Havoc Pennington - - * src/iconcache.c (meta_icon_cache_init): init prev_mask field - - * src/window.c (meta_window_new_with_attrs): init xgroup_leader - prior to use - -2003-11-24 Havoc Pennington - - * src/display.c (meta_display_begin_grab_op): add an event_serial - argument and use it when the pointer is already grabbed - automatically on the button press. May fix bug #126871 - -2003-11-24 Havoc Pennington - - * Apply patch from Gregory Merchan to avoid using CurrentTime when - setting input focus. Bug #108881 - -2003-11-23 Havoc Pennington - - * src/compositor.c: move xcompmgr code in here (minus drop - shadows), untested since Keith's server just crashes at the - moment. "It compiles" - -2003-11-20 Havoc Pennington - - * src/window.c (meta_window_new_with_attrs): new function - - * src/display.c, src/screen.c: create the compositor and feed - windows and events to it - -2003-11-20 Havoc Pennington - - * src/window.c (meta_window_notify_focus): revert the change here - -2003-11-17 Rob Adams - - Create COMPLIANCE document describing metacity specification - compliance. Right now gives detailed EWMH compliance; still need - to add ICCCM compliance information. Also some minor fixes to - bring metacity into compliance on some points. - - * COMPLIANCE: new file - - * src/display.h, src/display.c (meta_display_open), - src/screen.c (set_supported_hint): add - atom_net_wm_action_fullscreen and atom_net_wm_action_minimize - - * src/window.c (set_allowed_actions_hint): some fixes to which - hints to set and add fullscreen and minimize. - -2003-11-16 Rob Adams - - * src/window.c (meta_window_notify_focus): add paranoia check to - make sure a window is really on a workspace before inserting it at - the beginning of the MRU list. Maybe there's a race condition - with focusing and workspace switching. Hopefully a fix for - #122016. - -2003-11-15 Havoc Pennington - - * src/main.c (main): fix warning - - * src/compositor.c: add a new file to contain compositing manager - functionality; not yet implemented at all. - -2003-11-15 Rob Adams - - Inherit visual from frame window so that metacity will work with - the new compositing manager extension work by Keith on - freedesktop.org, so that ARGB windows can be full - alpha-transparent without a metacity frame getting drawn in the - background. In the long term, we need to actually set alpha - values when drawing the frame so that it will really work; this is - a stopgap solution. Patch from Keith Packard; see Bug 126875. - - * src/frame.c (meta_window_ensure_frame): pass client visual to - frame. - - * src/ui.[ch] (meta_ui_create_frame_window): add new xvisual - parameter and use it to create new window. - -2003-11-15 Rob Adams - - * src/window.c (update_net_wm_type): don't set window->type_atom - here so that the type-inference code will actually be called. Fix - for #126873 from Keith Packard. - -2003-11-08 Rob Adams - - * src/window.c (meta_window_move_resize_internal): configure frame - first if we grow more than we shrink combined in both dimensions. - Patch from Soren Sandmann for #108925. - -2003-11-07 Rob Adams - - * src/place.c (meta_window_place): use maximize_after_placement to - automaximize in meta_window_place; avoids a problem with not - recalculating the frame geometry after auto-maximizing. - -2003-11-07 Rob Adams - - * src/window.c (window_should_be_showing): show the window if it's - a transient of a dock or desktop, since otherwise such windows are - invisible in show desktop mode. Fix for #124648. - -2003-11-07 Rob Adams - - * src/main.c (main): Try harder to find a theme in the event that - the theme in the preference cannot be found. Patch from Marcin - Krzyzanowski. See #125815. - - * src/place.c (meta_window_place): use "visual" centering for - dialog placement and clip new dialogs to an xinerama workspace. - Fix for #118336. - -2003-10-30 Havoc Pennington - - * src/menu.c (meta_window_menu_new): patch to avoid creating - stick/unstick menu items when only one workspace, bug #116563 - from Michael Terry - -2003-10-25 Havoc Pennington - - * src/window.c (meta_window_notify_focus): if a window is focused - which is not either a dock or a transient in the same group as a - dock, shuffle all dock/desktop windows to the end of the MRU list - so they won't annoyingly get focus all the time. #123816 - -2003-10-15 Yukihiro Nakai - - Gettextize metacity-theme-viewer. #121747 - - * src/theme-viewer.c: gettextize. - * po/POTFILES.in: Add src/theme-viewer.c - -2003-10-13 Havoc Pennington - - In the "prefs cause code complexity" department, here's a "sloppy - focus die die die" kind of moment. - - * src/display.c (meta_display_grab_focus_window_button): don't - grab in sloppy focus mode, since we were dropping the grab on - window enter anyway this just removes races from the current - behavior. - - * src/display.c (prefs_changed_callback): ungrab/grab on focus - mode changes, since we treat sloppy and click differently. - -2003-10-12 Havoc Pennington - - Merge reduced_resources mode patch from the branch. Offers - wireframe and no-animations. - - * src/window.c (implement_showing): no animation if we are - in reduced resources mode - - * src/prefs.c: add REDUCED_RESOURCES pref - - * src/window.c (meta_window_update_keyboard_resize): fix to - modify grab_anchor_window_pos to grab_wireframe_rect if - appropriate instead of window->rect - - * src/display.h (struct _MetaDisplay): add grab_start_serial used - to avoid responding to events that occurred prior to the grab - initialization. - - Still broken in various ways, specifically EnterNotify that - occurred prior to XGrabPointer is processed as if it occurred - after. - - * src/window.c (meta_window_update_keyboard_move): add this - instead of meta_window_warp_pointer() crack - - * src/effects.c (meta_effects_update_wireframe): draw a kind of - grid for the wireframe, instead of just a rectangle, like twm - - * src/screen.c (meta_screen_new): line width of 3 for the XOR gc - - "Reduced resources" mode based on wireframe patch from - Erwann Chenede. Still pretty buggy. - - * src/keybindings.c (process_keyboard_move_grab) - (process_keyboard_resize_grab): add gruesome wireframe hacks - - * src/display.c (meta_display_end_grab_op): end wireframe - (meta_display_begin_grab_op): begin wireframe - - * src/effects.c (meta_effects_end_wireframe) - (meta_effects_update_wireframe, meta_effects_begin_wireframe): - routines to draw the wireframe stuff - - * src/window.c (window_should_be_showing): hide window when - doing wireframe, commented out as it breaks grab - * src/window.c (meta_window_refresh_resize_popup): handle wireframe - - * src/screen.c (meta_screen_new): create a screen->root_xor_gc - for use in drawing wireframes - - * src/frames.c (meta_frames_push_delay_exposes): repaint - everything before we delay - -2003-10-11 Havoc Pennington - - * src/display.c (meta_display_begin_grab_op): initialize - display->grab_have_pointer to FALSE, previously I think you could - get a case where we didn't have the grab and thought we did. - Bugs were reported with this happening. Of course we still have - the "why did the grab fail" problem, but it should be less - noticeable with this fixed. - -2003-10-06 Rob Adams - - * src/constraints.c (constraint_onscreen_*_func): disable onscreen - resize constraints for right, left, and bottom, since there is no - way to violate onscreen constraints by resizing in these - directions and the code to implement the constraints made some - incorrect assumptions. Fix for #120701, #120756, #123165, - #123631, #123838. - -2003-10-06 Žygimantas Beručka - - * configure.in: Added "lt" to ALL_LINGUAS - -2003-10-01 Havoc Pennington - - * NEWS: update - - * configure.in: 2.6.2 - -2003-09-30 Havoc Pennington - - * src/window.c (meta_window_queue_move_resize): add the moveresize - idle at META_PRIORITY_RESIZE so it runs before GTK does any - drawing, may fix bug #109211 (seems to for me) - - * src/ui.h (META_PRIORITY_RESIZE): add this between GTK - resize/redraw priorities - - * src/display.c (meta_display_queue_retheme_all_windows): remove - some debug spew from meta_warning - -2003-09-30 Havoc Pennington - - * src/testasyncgetprop.c: remove nonstandard header include, - #121870 - -2003-09-30 Havoc Pennington - - * src/tools/metacity-message.c (main): call - bind_textdomain_codeset(), fix from Yukihiro Nakai bug #121743 - -2003-07-28 Rached Ben Mustapha - - Fix bug #118428 - - * src/window.c (redraw_icon): Also redraw window icon if the window - is not mapped but its frame is. - (idle_update_icon): Unset the window->update_icon_queued flag. - -2003-09-29 Havoc Pennington - - * src/tabpopup.c (meta_ui_tab_popup_new): put a random cap on - number of characters in the title of each window, bug #109301 - -2003-09-29 Havoc Pennington - - * configure.in: put -lXext in Xrandr check, bug #115996 - -2003-09-29 Havoc Pennington - - * src/wm-tester/test-size-hints.c: a little program to test size - hints, for now just a 0x0 min size to verify bug #113320 - -2003-09-29 Havoc Pennington - - * src/async-getprop.c (async_get_property_handler): attempt to fix - this to return the data as an array of long even on 64-bit as with - XGetWindowProperty() breakage, bug #114035, credit to Gwenole - Beauchesne for tracking down. - -2003-09-29 Havoc Pennington - - * src/xprops.c (cvtINT16toInt): fix the 64-bit check not to use - macros from the X tree that don't get set - - * configure.in: check for sizes of various types - -2003-09-29 Havoc Pennington - - * src/delete.c (meta_window_delete): don't move the focus after - you click the close button on a window. bug #108706 - -2003-09-29 Havoc Pennington - - * src/main.c (find_accessibility_module): fix warnings (one was a - real bug) - - * src/ui.c (meta_gdk_pixbuf_get_from_pixmap): fix warning that - probably explains remaining crash on bug #116923. Jeez, need to - use -Werror here or something. - - Fix #103575, spawn child processes on proper screen. - - * src/keybindings.c (error_on_command): pass --screen to - metacity-dialog - (handle_run_command): launch user command with DISPLAY reflecting - the screen you launch it from - - * src/delete.c (delete_ping_timeout_func): pass --screen to - metacity-dialog - -2003-09-26 Havoc Pennington - - * src/display.c (event_callback): when focus on root window - becomes None, set it to something other than None so keybindings - keep working and print a warning about how some application sucks. - #84564 - (event_callback): Fix debug spew to print focus event details - properly - (meta_display_open): when setting initial focus, always use - RevertToPointerRoot and fix the focus if it's None or PointerRoot - -2003-09-26 Padraig O'Briain - - * src/Makefile.am: Add -DMETACITY_LIBDIR to support loading of modules - * src/main.c: Add functions find_accessibility_module, - accessibility_invoke_module and accessibility_invoke - (main); Check whether GConf accessibility key is true and if so - load accessibility modules. This code is based on the libgnome code. - - src/tabpopup.c (meta_ui_tab_popup_new): Set accessible role of - accessible for label containing window name to STATUSBAR so - AT can be aware of window name. - - This fixes bug #120025 - -2003-09-24 Havoc Pennington - - * src/session.c (io_from_warning_dialog): fix hang when we get - EOF, #121376 from Laurent Vivier - -2003-09-22 Taneem Ahmed - - * configure.in: Added "bn" to ALL_LINGUAS. - -2003-09-20 Åsmund Skjæveland - - * configure.in: Added Norwegian (nynorsk) translation code to - ALL_LINGUAS - -2003-09-20 Rob Adams - - Fix bug where multiple entries could appear in MRU lists, or no - entry when sticking/unsticking windows. Fix for #122016 - - * src/window.c (meta_window_stick): use window->screen->workspaces - instead of window->workspaces. - (meta_window_unstick): use window->screen->workspaces instead of - window->workspaces. - -2003-09-19 Rob Adams - - Fix a bug with partial-width panel struts caused by incorrect - computation of rectangle widths, and another when using different - screen resolutions on xineramas. See #122404. Also fix a crash - bug with the MRU list when sticking and unsticking windows. See - #120809. - - * src/constraints.c (get_outermost_onscreen_positions): Fix - off-by-one error with partial-width struts. - - * src/window.c (meta_window_update_struts): Fix off-by-one error - with partial-width struts. - (meta_window_stick): assign back to GList after g_list_append - (meta_window_unstick): assign back to GList after g_list_append - - * src/workspace.c (ensure_work_areas_validated): For right and - bottom struts, compute strut relative to root window and not to - xinerama edge in compliance with EWMH recommendations. - - -2003-09-17 Fatih Demir - - * configure.in: Added "ta" (Tamil) to the languages' list. - -Wed Sep 10 15:38:09 2003 Jonathan Blandford - - * configure.in: Rerelease 2.4.0.1 to fix glib-gettext problem. - -2003-09-08 Havoc Pennington - - * configure.in: remove "this is the unstable branch" warning - -2003-09-08 Havoc Pennington - - * configure.in: 2.6.0 - -2003-09-04 Havoc Pennington - - * configure.in: 2.5.5 - - * HACKING: add instructions on how to make a release - -2003-08-29 Rob Adams - - * src/ui.c (meta_gdk_pixbuf_get_from_pixmap): harden against null - return from gdk_pixmap_foreign_new. Fix for #116923. - -2003-08-26 Guntupalli Karunakar - - * configure.in: Added "hi" (Hindi) to ALL_LINGUAS. - -2003-08-20 Rob Adams - - Complete the transition to using the MRU window as the default - focus window instead of the topmost window; fixes a number of - problems with sloppy focus and utility windows. See #112031. - - * src/window.c (meta_window_free): call - meta_workspace_focus_mru_window - (meta_window_minimize): call meta_workspace_focus_mru_window - -2003-08-20 Rob Adams - - * src/constraints.c (meta_window_constrain): do northwest resize - when maximizing and fullscreening to avoid potential "off-by-one" - problems. - -2003-08-19 Rob Adams - - * src/stack.c (get_standalone_layer): put windows with - wm_state_below at the bottom. Make this higher priority than full - screen layer; see #120238. - -2003-08-18 Rob Adams - - * src/constraints.c (meta_window_constrain): recalculate frame - geometry if the window gets maximized after placement, since it's - likely to change. Fix for #120117. - -2003-08-17 Ray Strode - - * src/delete.c (meta_window_delete): Use MRU list to find focusing - window after a window is deleted instead of using top window. Fix - for #108643. - -2003-08-16 Havoc Pennington - - Patch from Soeren Sandmann #108926 to improve opaque resize - - * src/frame.c (meta_window_ensure_frame): new function - - * src/ui.c (meta_ui_create_frame_window): new function to create - a frame with GDK, so that GDK's invalidation etc. work properly - -2003-08-16 Havoc Pennington - - * src/display.c (xcursor_for_op): fix cursor for - META_GRAB_OP_MOVING, #111943 from John Paul Wallington - -2003-08-15 Rob Adams - - * src/constraints.c (meta_window_constrain): move to upper left - corner since we're resizing/moving instead of moving/resizing. - Fix for #119988. - -2003-08-15 Ray Strode - - Changed MRU list to be per workspace instead of per display, so - sticky windows don't hijack the window focus after workspace - switching (Bug #97635). - - * src/delete.c (meta_window_delete): Use - meta_workspace_focus_top_window instead of - meta_screen_focus_top_window. - - * src/display.c (meta_display_open): Stop using display->mru_list. - (find_tab_forward): - (find_tab_backward): - (meta_display_get_tab_list): Use workspace->mru_list instead of - display->mru_list and remove unneeded calls to - meta_window_visible_on_workspace - - * src/display.h: Remove mru_list from MetaDisplay - - * src/keybindings.c (handle_toggle_desktop): Use - meta_workspace_focus_top_window instead of - meta_screen_focus_top_window. - - * src/screen.c (meta_screen_focus_top_window): - (meta_screen_focus_default_window): Remove functions. - (meta_screen_show_desktop): Use meta_workspace_focus_top_window - instead of meta_screen_focus_top_window. - - * src/screen.h: Remove meta_screen_focus_top_window and - meta_screen_focus_default_window declarations. - - * src/window.c (meta_window_new): Stop using display->mru_list. - (meta_window_free): Use meta_workspace_focus_top_window - instead of meta_screen_focus_top_window and stop using - display->mru_list. - (meta_window_stick): Add sticky window to all workspace MRU lists. - (meta_window_unstick): Remove non-sticky window from the workspace - MRU lists it doesn't belong in. - (meta_window_notify_focus): Move newly focused window to the front - of active workspace's MRU list. - - * src/workspace.c (meta_workspace_new): Initialize - workspace->mru_list to NULL. - (meta_workspace_add_window): Add window to workspace's MRU list. - (meta_workspace_remove_window): Remove window from workspace's MRU - list. - (meta_workspace_activate_with_focus): Use - meta_workspace_focus_default_window instead of - meta_screen_focus_default_window. - (meta_workspace_focus_default_window): - (meta_workspace_focus_mru_window): - (meta_workspace_focus_top_window): Add functions. - - * src/workspace.h: Add mru_list to MetaWorkspace and add function - declarations for meta_workspace_focus_default_window, - meta_workspace_focus_mru_window, meta_workspace_focus_top_window. - -2003-08-14 Rob Adams - - Allow windows that are too tall for the workarea to break the - onscreen constraints just enough so that their bottom edges can be - made visible. Fix for #106740. Also, changes constraints to - constrain the resize and then the move to avoid complexities in - the code for the above fix. - - * src/constraints.c (get_outermost_onscreen_positions) - Compute the "effective" height of the work area and the minimum - size for the window to compute a value by which a window is - allowed to violate the top constraint. - (meta_window_constrain): convert to a resize then a move instead - of a move then resize. - -2003-08-13 Rob Adams - - * configure.in: remove metacity.spec from AC_OUTPUT - -2003-08-13 Havoc Pennington - - * metacity.spec.in: remove, nobody is maintaining it. - -2003-08-13 Laurent Dhima - - * configure.in: Added "sq" to ALL_LINGUAS. - -2003-08-10 Havoc Pennington - - * src/screen.c (meta_screen_new): don't select for button - press/release events, as that keeps other clients from doing so, - and it doesn't seem that metacity has any reason to do it. - Patch from Andreas Volz. - -2003-08-08 Bastien Nocera - - * src/metacity-dialog.c: (kill_window_question), - (warn_about_no_sm_support): fix markup being ignored when a window - title has a forbidden character in it (eg. "Send & Receive") - * src/tools/metacity-window-demo.c: fix warning - -2003-07-29 Arvind Samptur - - * src/xprops.c (utf8_list_from_results): Number of - strings we are processing is one more than required. - - Also get the string count right even without a null byte at the end. - Pointed out by Havoc. - -2003-07-27 Rob Adams - - * src/window.c (update_move): Update window shaking loose so that - the window is moved to the pointer and certain drag state is - properly restored once windows "reattach". Fix for #115000 based - on the patch by Jurg Billeter. - - * src/screen.c (meta_screen_resize): Invalidate work areas after - an xrandr screen size update. Fix for #117230. - - * src/stack.c (window_is_fullscreen_size): Check the bottom corner - of the window in addition to the top corner. Fix for #118194. - - * src/constraints.c (meta_window_constrain): Support aspect ratio - hints in the new constraints code. Fix for #113798. - - * src/tools/metacity-window-demo.c (toggle_aspect_ratio): toggle - the aspect ratio hints to force a 16:9 aspect ratio. - (do_appwindow): add a button to toggle aspect ratio. - -2003-07-27 Havoc Pennington - - * src/theme-viewer.c (run_theme_benchmark): also measure wall - clock time, and run over a number of window sizes. - -2003-07-15 Havoc Pennington - - * NEWS: update - - * configure.in: 2.5.3 - -2003-07-12 Pablo Saratxaga - - * configure.in: Added Walloon (wa) to ALL_LINGUAS - -2003-07-04 Havoc Pennington - - * Makefile.am (EXTRA_DIST): add rationales.txt - -2003-07-02 Jordi Mallach - - * src/metacity.desktop.in: Add X-GNOME-Bugzilla entries. - -2003-07-01 Padraig O'Briain - - * src/keybindings.c (process_tab_grab): Activate window before ending - grab. This fixes bug #114037. - -2003-06-20 Rob Adams - - * src/window.c (meta_window_unmaximize): Update grab state when we - unmaximize so double-clicking doesn't cause weird window-jumping - problems. See #116292. - -2003-06-29 Rob Adams - - * src/constraints.c (meta_window_constrain): Actually maximize - after placement. See #116285. - -2003-06-26 Havoc Pennington - - * src/workspace.c (meta_workspace_invalidate_work_area): nuke the - lists of struts here, to improve confidence that we never try to - use them after a window with rects in the list gets freed. - (it wasn't broken before I don't think, just making the - code more robust against future mods) - - * src/window.c (meta_window_update_struts): replace magic "75" - with a macro - - * src/constraints.c (constraint_hints_applies_func): don't apply - hints to maximized or fullscreen, rather than only fullscreen - (constrain_move): add paranoia max number of iterations to the - heuristic loop - -2003-06-26 Rob Adams - - Add keybinding to allow the user to toggle _NET_WM_STATE_ABOVE on - windows. Disabled by default. See #98387. - - * src/keybindings.c (handle_toggle_above): new function implements - the keybinding - - * src/metacity.schemas.in: add toggle_above keybinding - - * src/prefs.[ch]: add toggle_above keybinding - - * src/window.[ch] (meta_window_make_above): new function to put a - window into the above state - (meta_window_unmake_above): new function takes a window out of the - above state - -2003-06-26 Mohammad DAMT - - * po/id.po: Added Indonesian translation - * configure.in: Added "id" to ALL_LINGUAS - -2003-06-25 Rob Adams - - Update constraints code to support the new _NET_WM_STRUT_PARTIAL - EWMH draft specification. See #86682. Also, fix a bug involving - work area invalidation on metacity startup. Fix for #108497. - Finally, some minor fixes for full screen windows. - - * src/window.h: Add new MetaStruts structure to store strut rects - for a window. Remove has_struts and do_not_cover flag, and - support new MetaStruts instead of the four ints. - - * src/window.c (meta_window_new): change initialization to work - with new struts. Also, move meta_window_update_struts call to - after the workspaces are initialized to fix #108497. Remove - do_not_cover and related code. - (process_property_notify): add strut_partial - (update_struts): change function name to meta_window_update_struts - and expose in external MetaWindow API. Support partial width - struts and the new strut rects. - - * src/workspace.h: add new GSLists containing pointers to all - relevant struts for this workspace. - - * src/workspace.c (meta_workspace_new): initialize the list of - strut rects for this workspace. - (meta_workspace_free): free the strut rect lists - (ensure_work_areas_validated): support new struts and new strut - rect lists. Unleash the per-xinerama work areas. - - * src/constraints.c (get_outermost_onscreen_positions): Use the - current window position along with the new per-workspace strut - rects to compute the constraints that apply to a particular - window. - (constraint_hint_applies_func): don't do hints constraints on - fullscreen windows - (update_position_limits): for maximized windows use the work areas - to set the position limits; for other windows rely on the struts - constraints to be computed later in - get_outermost_onscreen_positions - (meta_window_constrain): don't apply aspect ratio hints to full - screen windows - - * src/display.c (meta_display_open): add _NET_WM_STRUT_PARTIAL atom - (meta_rectangle_equal): new helper function for MetaRectangles - (event_queue_callback): #ifndef out if USE_GDK_DISPLAY not set to - avoid compiler warning - - * src/display.h: add atom_net_wm_strut_partial, and add - meta_rectangle_equal. - - * src/screen.c (meta_screen_rect_intersects_xinerama): change - _window_intersects_ to _rect_intersects_ which is more useful now. - (meta_screen_resize_func): update struts on windows with struts - since struts are relative to the screen size, and this function is - called when the screen size updates. - - * src/screen.h (meta_screen_rect_intersects_xinerama): change - _window_intersects_ to _rect_intersects_ which is more useful now. - - * src/window-props.c (meta_display_init_window_prop_hooks): add - hook for strut_partial - - * src/tools/metacity-window-demo.c: Support partial-width struts - on the dock window tests for metacity testing purposes. - -2003-06-22 Samúel Jón Gunnarsson - - * configure.in: Added "is" to ALL_LINGUAS - -2003-06-12 Rob Adams - - * src/display.c (event_callback): Focus on mouse click in - sloppy/mouse to fix keynav. Fix for #115072. - -2003-06-12 Rob Adams - - * src/Makefile.am: honor --disable-schemas-install. Fix for - #106123 from Julio Merino - -2003-06-12 Rob Adams - - Remove legacy support for Gnome 1 hints, since we deem it unlikely - that anyone is running a current metacity with Gnome 1. The - removed hints are _WIN_WORKSPACE, _WIN_LAYER, _WIN_PROTOCOLS, - _WIN_SUPPORTING_WM_CHECK, and _WIN_HINTS. Thanks to Ben Jansens - for much of this patch. - - * display.c (meta_display_open): remove hints - - * display.h: remove atoms for hints - - * screen.c (set_wm_check_hint): don't set legacy hint - (set_supported_hint): don't set legacy hint - - * window-props.c (init_win_workspace): removed - (reload_win_workspace): removed - (meta_display_init_window_prop_hooks): remove hints - - * window.h: remove do_not_cover flag - - * window.c: remove GnomeWinHints enum - (recalc_do_not_cover_struts): removed - (meta_window_new): don't initialize removed flags or compute - legacy struts - (move_resize_cmp): removed - (idle_move_resize): Don't bother sorting the idle queue - (meta_window_client_message): don't set legacy hint - (process_property_notify): remove hints - (update_net_wm_type): don't fall back to WIN_LAYER hint - (update_struts): remove legacy struts - -2003-06-12 Havoc Pennington - - * src/display.c (event_callback): make raise-on-click explicitly - only happen in click to focus mode. - - * src/window.c (update_move): apply patch from Jurg Billeter to - allow you to "shake loose" maximized windows and move them between - Xinerama heads. #93586 - - * src/display.c: delete event_queue_callback - - * src/display.h (struct _MetaDisplay): get rid of - grab_current_window_pos and grab_current_root_[xy] as I could find - absolutely no code using them for anything. They were just sort of - randomly assigned to for no apparent reason. - - * src/display.c (event_callback): double-click timeout is per - screen, so get the screen and pass screen->ui to - meta_ui_get_double_click_timeout() - - * src/ui.c (meta_ui_get_double_click_timeout): take a MetaUI - argument so we get the right settings for each screen - (meta_ui_get_drag_threshold): new function - -2003-06-09 Rob Adams - - Revamp placement policy for windows that are maximized when they - are mapped, including windows that set a hint to be maximized or - windows that are auto-maximized using our heuristic. See #111902. - - * src/window.h: add new flag maximize_after_placement and new - function meta_window_maximize_internal. - - * src/window.c (meta_window_new): initialize - maximize_after_placement to FALSE and remove the automaximize - heuristic. - (meta_window_maximize_internal): new function accepts a saved_rect - argument to be used as the new saved_rect for the window, and does - not queue a move_resize. - (meta_window_maximize): re-implement using - meta_window_maximize_internal. - (update_net_wm_state): If a window has a maximize hint set on - startup set maximize_after_placement to TRUE - - * src/constraints.c (meta_window_constrain): Update the xinerama - information in the ConstraintInfo after placing the window, and - maximize the window after placement if - window->maximize_after_placement - - * src/place.c (find_first_fit): take a natural xinerama list as an - argument instead of generating it here - (constrain_placement): remove function, since it is no longer - needed - (meta_window_place): generate the natural xinerama list here and - pass it into find_first_fit. If find_first_fit fails, use the - list to find empty xineramas where we can place windows that may - be maximized later. This makes maximized windows follow the - correct placement policy. Move the automaximize heuristic here. - -2003-06-09 Rob Adams - - * src/metacity-dialog.c (warn_about_no_sm_support): install an - alarm to timeout the no-sm-dialog after 4 minutes of inactivity. - Patch from Ximian. See #114789. - -2003-06-07 Rob Adams - - * src/window.c (meta_window_new): call meta_group_compute_group - after setting window->desc to avoid SIGSEGV when verbose mode is - enabled. - -2003-06-07 Havoc Pennington - - * src/window.c (meta_window_notify_focus): drop the mouse button - grabs for the focused window; we'll see if this breaks anything. - It should fix #102209 - -Fri Jun 6 19:27:53 2003 Jonathan Blandford - - * src/metacity.schemas.in: fix the location of the schemas file. - -2003-06-04 Rob Adams - - * src/window.c (meta_window_new): don't be stupid and set - window->group = NULL after calling meta_window_compute_group. - - * src/group.c (meta_window_get_group): assert that window->group - != NULL in here instead of computing the group to ensure - robustness. - -2003-06-04 Rob Adams - - Precompute groups to guarantee that meta_group_list_windows always - returns the correct list of windows. See Bug #96973 - - * src/window.h: change cached_group variable to group - - * src/window.c (meta_window_new): change cached_group to group and - call meta_window_compute_group - - * src/groups.c (meta_window_get_group): simply return - window->group rather than computing it and returning - window->cached_group - (meta_window_compute_group): new function computes window->group. - Designed to be called once from meta_window_new - (remove_window_from_group): change cached_group to group - (meta_window_group_leader_changed): call meta_window_compute_group - instead of meta_window_get_group - -2003-05-29 Rob Adams - - Use a new property _METACITY_SENTINEL to eliminate a race - condition that causes focus to behave badly with sloppy/mouse - focus when lots of windows are mapped/unmapped, such as with a - workspace switch. The EnterNotify events on a display are ignored - until the PropertyNotify sent after all the window maps is - received. This is a fix for #110970. - - * src/display.[ch]: New _METACITY_SENTINEL atom. - (event_callback): ignore EnterNotify if the sentinel isn't clear, - and decrement the sentinel counter when the PropertyNotify is - received. - (meta_display_increment_focus_sentinel): new function. Increments - the sentinel counter and updates the property on a root window on - this display. - (meta_display_decrement_focus_sentinel): Decrement the sentinel - counter. - (meta_display_focus_sentinel_clear): returns whether the sentinel - counter is zero. - - * src/window.c (idle_calc_showing): after showing windows, call - meta_display_increment_focus_sentinel on each display for windows - to be shown. - - * src/workspace.[ch] (meta_workspace_activate_with_focus): new - function activates a workspace and focuses a particular window - after the workspace is activated. - (meta_workspace_activate): now just a wrapper for - meta_workspace_activate_with_focus - - * src/keybindings.c: use new meta_workspace_activate_with_focus - function to ensure that focus will follow the focused window - through the workspace switch. - -2003-05-29 Havoc Pennington - - * src/theme-parser.c (meta_theme_load): s/int/gsize/ for - g_file_get_contents() (found independently by - marcus@freebsd.org on SPARC and James Laska on s390x; - #113661 - - * src/main.c (main): fix theme location mentioned in error message - -2003-05-29 Ray Strode - - Get and use double-click speed from GtkSettings (Bug #103218). - - * src/ui.c, src/ui.h: - add function meta_ui_get_double_click_timeout for looking up - the global double-click speed. - - * src/display.c, src/display.h: remove double_click_time - field from MetaDisplay and use meta_ui_get_double_click_timeout - instead. - -2003-05-29 Rob Adams - - * src/main.c (main): chdir to the user's home directory on - startup. See #113755. - - * src/stack.c (get_standalone_layer): a window should be in the - fullscreen layer if it or any of its transient descendants are - focused or expecting the focus and it is either fullscreen or - fullscreen sized. Fix for #104369. - - * src/stack.c (is_focused_foreach): foreach used by - get_standalone_layer to find focused transient descendants. - -2003-05-20 Havoc Pennington - - * src/keybindings.c (meta_change_keygrab): the mask - display->ignored_modifier_mask wasn't being bound, - due to "<" instead of "<=" (most people didn't notice - as display->ignored_modifier_mask included Scroll_Lock). - Red Hat bugzilla #91301 reported by Youssef Makki - - * src/display.c (meta_change_button_grab): make corresponding - change for button grabs. - -2003-05-20 Havoc Pennington - - * NEWS: update - - * configure.in: 2.5.2 - -2003-05-20 Anders Carlsson - - * src/metacity-dialog.c: (kill_window_question): - Split up the strings to make life easier for translators. - -2003-05-20 Anders Carlsson - - * src/metacity-dialog.c: (kill_window_question): - Fix the wording and HIGify the dialog. - -2003-05-18 Havoc Pennington - - * src/window.c (unminimize_window_and_all_transient_parents): - revert broken change that assumed foreach_ancestor iterated - over the window itself. Andrew Sobala, Rob Adams, - #113232 - -2003-05-16 Rob Adams - - Flip the workspace when using up/down/left/right for move window - to, but not when specifying a workspace explicitly as in move to - workspace 4. Possible fix for #105492. - - * src/keybindings.c (do_handle_move_to_workspace): new function - moves a window to a workspace with the option to flip to that - workspace. - (handle_move_to_workspace): Use new do_handle_move_to_workspace - function without flipping (a keybinding) - (handle_move_to_workspace_flip): Use new - do_handle_move_to_workspace function with flipping (a keybinding) - -2003-05-16 Havoc Pennington - - * src/frames.c (meta_frames_paint_to_drawable): fix for - bug #104018 from David Santiago, change button state to - normal while it's being pressed if you move the mouse - outside it. Do this by tracking prelit_control for whether - to draw a button as active, not just for whether to draw - it as prelit. - (meta_frames_motion_notify_event): also update prelit_control - while clicking a button - -2003-05-16 Havoc Pennington - - * src/window.c (meta_window_new): fill in window->desc sooner - since we use it sooner now. - - * src/display.c (meta_display_open): init - display->grab_update_alarm - - * src/window.c (meta_window_new): initialize the always_sticky - field - (meta_window_new): initialize the update_icon_queued field - - Patch from Julien Olivier bug #92335 for converting "show desktop - mode" to "all windows are minimized" when you open a new window, - instead of just mapping all the windows again. - - * src/window.c (meta_window_activate): minimize all windows before - coming out of show desktop mode. - (meta_window_unminimize): don't toggle show desktop mode here - - * src/screen.c (meta_screen_minimize_all_except): new function - -2003-05-01 Havoc Pennington - - * src/theme-parser.c (meta_theme_load): fix memleak on error - -2003-05-16 Telsa Gwynne - - * configure.in: Added "cy" (Welsh) to ALL_LINGUAS. - -2003-05-06 Danilo Å egan - - * configure.in: Added "sr" and "sr@Latn" to ALL_LINGUAS. - -2003-05-03 Havoc Pennington - - * src/keybindings.c (handle_move_to_workspace): when moving - window to another workspace, don't switch to that workspace. - - * src/window.c (menu_callback): when moving window to another - workspace, don't switch to that workspace. - -2003-05-03 Havoc Pennington - - * configure.in: 2.5.1 - - * NEWS: update - -2003-05-01 Rob Adams - - * src/constraints.c (constraint_onscreen_applies_func): Don't - apply onscreen constraints to full screen windows. Fix for - #110048 - -2003-04-29 Havoc Pennington - - * src/bell.h: include Xlib.h before XKBlib.h which is required on - Solaris. #111877 from Peter O'Shea - -2003-04-23 Havoc Pennington - - * src/keybindings.c (process_keyboard_move_grab): support - diagonal keypad keybindings, from Dafydd Harries - -2003-04-21 Havoc Pennington - - * purge HAVE_GTK_MULTIHEAD from the source code, not just from - configure.in. Yes I am a loser. - -2003-04-19 Masahiro Sakai - - * configure.in: call AC_LIBTOOL_WIN32_DLL. - - * src/Makefile.am: add -no-undefined to libmetacity_private_la_LDFLAGS - and write dependency libraries in libmetacity_private_la_LIBADD. - -2003-04-06 Rob Adams - - * src/place.c (find_next_cascade): cascade on xinerama with - pointer instead of on first xinerama. - -2003-04-05 Rob Adams - - Update placement policy for screen with multiple xineramas. - Windows will be placed preferentially on the xinerama with the - pointer, and progressively further away as needed to find a place - where the window does not overlap other windows. - - * src/place.c (rect_fits_in_work_area): function - fit_rect_in_xinerama greatly simplified to work with new placement - policy. - (find_first_fit): implement new first fit placement scheme - - * src/screen.c (meta_screen_get_xinerama_neighbor): look for an - xinerama in the xinerama list that is adjacent to the specified - xinerama. - (meta_screen_get_natural_xinerama_list): return a list of - xineramas in the order to be preferred by the placement algorithm - as determined by the current location of the pointer. - - * src/screen.h: add function prototypes and an enum used by - meta_screen_get_xinerama_neighbor. - -2003-04-05 Rob Adams - - * src/place.c (center_tile_rect_in_area): Fix a minor off-by-one - error. See #110079. - -2003-03-30 Rob Adams - - * src/window.c (meta_window_move_resize_internal): When passing - frame geometry to meta_window_constrain, send null if no frame. - Possible fix for #109039. - -2003-03-29 Havoc Pennington - - * src/wm-tester/test-gravity.c (main): add --noframes option for - testing, showing how broken we currently are. - -Fri Mar 28 14:13:37 2003 Soeren Sandmann - - * src/window.c (update_resize): Only cap refresh rate when not - using SYNC. Remove bogus update-if-we-moved-more-than-a-delta. - - * src/window.c (update_move): Don't cap refresh rate during - moves. Remove bogus update-if-we-moved-more-than-a-delta. - -2003-03-26 Havoc Pennington - - * NEWS: update - - * configure.in: release 2.5.0 - -Sun Mar 23 23:04:06 2003 Soeren Sandmann - - * src/display.c (meta_spew_event): just return if we are not - verbose. - -2003-03-11 Havoc Pennington - - Should fix #108108, #106217, tracked down by Owen Taylor and - Frederic Crozat - - * src/window.c (meta_window_foreach_transient): change - MetaWindowForeachFunc to return a boolean for whether to continue - (meta_window_foreach_ancestor): new function - (window_should_be_showing): use meta_window_foreach_ancestor - (unminimize_window_and_all_transient_parents): ditto - (update_sm_hints): ditto - (meta_window_is_ancestor_of_transient): ditto - - * src/stack.c (get_maximum_layer_of_ancestor): use - meta_window_foreach_ancestor - -2003-03-16 Rob Adams - - * window.c (meta_window_show_menu): Free old window menu if it - already exists so we don't end up with more than one. Fix for - #108392. - -2003-03-14 Rob Adams - - * contraints.c (get_outermost_screen_positions): Don't try to - force a window onscreen by more than its width. Fix for #94815. - -2003-03-13 Rob Adams - - Make it so that the alt-tabbing won't try to go to a minimized - window by default. Fix for #107071. - - * display.c (meta_display_get_tab_list): use a GList instead of a - GSList - (meta_display_get_tab_next): use meta_display_get_tab_list to - decide what the next/previous tab window should be. - - * display.h (meta_display_get_tab_list): update function prototype - to return GList instead of GSList. - - * screen.c (meta_screen_ensure_tab_popup): update function to deal - with GList returned by meta_display_get_tab_list instead of GSList. - -2003-03-13 Christian Rose - - * configure.in: Added "ml" to ALL_LINGUAS. - -2003-03-11 Paul Duffy - - * configure.in: Added "ga" to ALL_LINGUAS - -2003-03-11 Rob Adams - - * src/constraints.c (meta_window_constrain): include left frame - geometry when maximizing or fullscreening windows. Fix for - #108127. - -2003-03-10 Roozbeh Pournader - - * configure.in: Added "fa" to ALL_LINGUAS. - -2003-02-27 Havoc Pennington - - Switch over to new constraints code, unquestionably introduces - some bugs, but should get us on the right path. - - * src/window.c (meta_window_get_work_area_all_xineramas): create - this function again as it turned out to be legitimate for window - position constraint - (adjust_for_gravity): use the width/height from the configure - request to compute the requested move - (meta_window_move_resize_internal): use meta_window_constrain - (update_size_hints): clamp max size to MAXSHORT to avoid worrying - about overflow stuff - - * src/constraints.c (meta_window_constrain): don't base placement - on uninitialized variables, general hacking - - * src/Makefile.am (metacity_SOURCES): add constraints.c, - constraints.h - - * src/constraints.c (meta_window_constrain): update the - cut-and-paste aspect ratio code to have latest bugfixes - -2003-03-08 Rob Adams - - * src/window-props.c (reload_normal_hints): Check that window min - and max size hints are at least 1. Fix for #107110. - -2003-02-27 Havoc Pennington - - Changes made on plane from FOSDEM, syncing from laptop. - - * src/main.c (main): add more debug spew about conditional - build stuff - (main): panic to "Simple" theme - - * src/window.c, src/window-props.c: move WM_NORMAL_HINTS and - WM_PROTOCOLS to new property system; don't queue move resize on - updating WM_PROTOCOLS; move WM_HINTS to new property system; - reload icon in an idle handler. - -2003-02-28 Mark McLoughlin - - Give me back my keys. - - * src/keybindings.c: (meta_window_grab_keys): don't - grab keys on DOCK windows. - - * src/window.c: (recalc_window_type): re-grab the - keys. - -2003-02-26 Dmitry G. Mastrukov - - * configure.in: Added Belarusian to ALL_LINGUAS. - -2003-02-26 Mark McLoughlin - - * src/keybindings.c: (handle_panel_keybinding): release - the keyboard grab before sending the action message to - the panel. - -2003-02-24 Mark McLoughlin - - Take control of the panel's global keybindings. The - screenshot utility is hooked up using a special case - run_command and the menu and run dialog bindings are - done using the _GNOME_PANEL_ACTION ClientMessage - protocol. - - * src/display.[ch]: (meta_display_open): add some atoms. - - * src/keybindings.c: - (handle_panel_keybinding): impl to handle a keybinding - by sending an action message to the panel. - - * src/metacity.schemas.in: add schemas for the panel and - screenshot keybindings and the screenshot commands. - - * src/prefs.[ch]: (update_command), - (meta_prefs_get_gconf_key_for_command): impl special case - handling for the screenshot commands. They are stored at - the the end of the commands array but have named keys. - -2003-02-23 Havoc Pennington - - Patch from Rob Adams addresses #95014 (placement issues), - makes first fit algorithm "center tile", adds most code - for per-xinerama workspaces (#86682) but disables it for now. - - * src/workspace.c (meta_workspace_get_work_area_for_xinerama) - (meta_workspace_get_work_area_all_xineramas): new xinerama - functions, maintain workspace->work_areas with a different - work area for each xinerama. However for now all the work - areas are the same, because haven't quite figured out how - _NET_WM_STRUT is supposed to work - - * src/window.c: adapt to new meta_window_* xinerama APIs - (meta_window_get_work_area_current_xinerama): new xinerama - API - (meta_window_get_work_area_for_xinerama): new xinerama API - (constrain_position): be a bit more clever about which xinerama's - work area we choose to use. - - * src/stack.c: adapt to new Xinerama API - - * src/screen.c (reload_xinerama_infos): invalidate all work areas - (meta_screen_get_xinerama_for_rect): new function - (meta_screen_window_intersects_xinerama): new function - - * src/place.c (find_first_fit): change to use - "center tiling" (center a screen full of tiled windows, - rather than aligning them top left). Adapt to new - xinerama functions. - -2003-02-22 Rob Adams - - * src/metacity.schemas.in: change toggle_maximized to - toggle_maximize and toggle_shaded to toggle_shade in - action_double_click_titlebar long description to match the values - used by metacity - - * po/*.po: change toggle_maximized to toggle_maximize and - toggle_shaded to toggle_shade in action_double_click_titlebar long - description to match the values used by metacity - -2003-02-22 Rob Adams - - * window.c (set_wm_state): modify comment to explain why the icon - window element is set to None. Fix for #97357 thanks to Gregory - Merchan. - -2003-02-22 Havoc Pennington - - * README: fix a typo, pointed out by Steve Kemp - -2003-02-22 Havoc Pennington - - * src/prefs.c (MAX_REASONABLE_WORKSPACES): change max workspaces - to 36 #81855 - -2003-02-22 Havoc Pennington - - * src/display.c (event_callback): fix to unfocus window only when - you leave the window frame, not when you leave the window itself, - unless window has no frame. #100248 fix from Orien Vandenbergh - -2003-02-22 Havoc Pennington - - * src/display.c (meta_display_get_tab_next): when tabbing - backward, we are still tabbing *from* the most recently used - window, not from the least recently used window. - - * src/keybindings.c (struct _MetaKeyBinding): make keycode - unsigned to match XEvent - - Patch for #84999 based on patch from Mark McLoughlin - - * src/prefs.c: add an add_shift field to MetaKeyPref to - add shift when grabbing the given keybinding. - - * src/keybindings.c (rebuild_screen_binding_table) - (rebuild_window_binding_table): refactor to share code, - and honor add_shift field in MetaKeyPref - -2003-02-20 Havoc Pennington - - * src/stack.c (create_constraints): don't create constraints - between windows on different screens, #106086 tracked down - by Arvind - -2003-02-14 Arvind Samptur - - * src/screen.c: (meta_screen_new) : Update the workspace - names from gconf and set the NET_DESKTOP_NAMES atom. - Renamed update_workspace_names() to set_workspace_names(). - Fixes #105498 - -2003-02-13 Havoc Pennington - - * configure.in: require GTK+ 2.2.0 - - * src/ui.c (meta_ui_init): remove hackaround for Pango X core - fonts backend - -2003-02-05 Abel Cheung - - * configure.in: Added "en_GB" and "nl" to ALL_LINGUAS. - -2003-02-05 Akira TAGOH - - * src/main.c (usage): fix a typo and missing option. (#105186) - -2003-02-04 Havoc Pennington - - * src/themes/Simple/ChangeLog: nuke subdir ChangeLog, - there can be only one true ChangeLog. - -2003-01-30 Havoc Pennington - - * src/keybindings.c (process_event): match handlers to key events - using key codes, not key syms - -Thu Jan 30 22:55:16 2003 Jonathan Blandford - - * src/themes/Makefile.am (THEMES): add Simple to the list of - themes. - - * src/metacity.schemas.in: change default theme to Simple. - -2003-01-29 Havoc Pennington - - * src/menu.c (meta_window_menu_new): don't create workspaces - menu items if only 1 workspace. Fix for #101952 from - Orien Vandenbergh - -2003-01-28 Bill Haneman - - * Re-instated visual-bell patch - (please see ChangeLog entry for 2002-12-16 for details). - - * src/prefs.c: - (visual_bell_type_from_string): - Accept a NULL string for 'visual-bell-type'. - -2003-01-25 Havoc Pennington - - * src/stack.c (window_is_fullscreen_size): When checking if a - window is fullscreen size, only require it to be at the origin - of the work area, not at the origin of the screen/xinerama. - Still require it to be full screen in width x height. - May fix xine in the case where the user has a top panel. - - * src/window.c (constrain_position): restore the ability for - undecorated windows to position themselves overlapping the top - panel, but don't let decorated windows do so. Oh the hacks... - -2003-01-08 Havoc Pennington - - * src/screen.c (meta_screen_apply_startup_properties): small code - snippet to fix startup sequences that set legacy class/name - -2003-01-22 Havoc Pennington - - * src/async-getprop.c (async_get_property_handler): do not read - sizeof(long) off the X connection. The X protocol does not vary - by architecture. Fixes longstanding hang on all 64-bit platforms. - -2003-01-22 Havoc Pennington - - * src/tools/Makefile.am: fix conditional so we get - metacity-properties.c in the distribution #103071 - -2003-01-22 Havoc Pennington - - * src/window.c (update_struts): be robust against the panel's - lame "set a negative number for struts" thing, even though - we'll also fix the panel. - -2003-01-21 Havoc Pennington - - Fix for the "mangles focus window when switching workspaces - and using mouse focus" bug - - * src/stack.c (meta_stack_get_default_focus_window_at_point): new - function - - * src/screen.c (meta_screen_focus_mouse_window): new function - (meta_screen_focus_default_window): new function - - * src/workspace.c (meta_workspace_activate): use the - new meta_screen_focus_default_window() - -2003-01-17 Havoc Pennington - - * src/window.c (meta_window_handle_mouse_grab_op_event): fix event - compression code to use GDK algorithm suggested by Owen, should be - more efficient. - -2003-01-22 Christian Rose - - * configure.in: Added "mn" to ALL_LINGUAS. - -2003-01-21 Havoc Pennington - - * src/display.c (event_callback): only hop window to the current - workspace if the window was previously minimized. Should keep - mozilla from popping windows over to your current workspace. - -2003-01-20 Havoc Pennington - - Attempt to fix #85916 - - * src/keybindings.c (primary_modifier_still_pressed): new function - (handle_workspace_switch): handle modifier release prior to - getting the grab - (do_choose_window): handle modifier release prior to getting the - grab - - * src/keybindings.c (grab_keyboard): properly return failure - if the GrabKeyboard doesn't work - -2003-01-19 Havoc Pennington - - * configure.in: add note about how this is the unstable branch, - set version to 2.5.0 - -2003-01-14 Havoc Pennington - - * src/window.c (meta_window_maximize, meta_window_unmaximize) - (meta_window_make_fullscreen, meta_window_unmake_fullscreen): - recalc_window_features() after making these changes, should fix - #103317 - -2003-01-14 Rob Adams - - * src/prefs.c: Increase the number of run_command bindings in - screen_bindings from 12 to 32. - - * src/prefs.h: Increase the number of META_KEYBINDING_COMMAND_N - macros from 12 to 32. - - * src/keybindings.c: Increase the number of run_command handlers - from 12 to 32. - -2003-01-11 Havoc Pennington - - * src/window.c (meta_window_handle_mouse_grab_op_event): implement - compression of motion events (drop all but the most recently - received), guessing at fixes for #103009 - -2003-01-11 Havoc Pennington - - * configure.in: add ability to --disable-shape - -2003-01-11 Akira TAGOH - - * configure.in: fix the behavior of --enable-*. - -2003-01-10 Havoc Pennington - - * src/Makefile.am (desktopfiles_in_files): revert that change, I - got the wrong .desktop file. doh. - -2003-01-10 Havoc Pennington - - * src/Makefile.am (desktopfiles_DATA): don't install .desktop file - for properties dialog if we aren't building/installing the - properties dialog. - -2003-01-10 Havoc Pennington - - * NEWS: update - - * configure.in: bump to 2.4.13, require 2.2.0 for multihead - -2003-01-09 James M. Cape - - * src/themes/Esco/metacity-theme-1.xml: Use a line for the titlebar - text bg. - -2003-01-09 Havoc Pennington - - * src/window.c (recalc_window_features): argh, we were making all - dialogs skip taskbar; when did that get added. Fix to match - libwnck, only skip taskbar when the dialog is transient for some - other app window. - -2003-01-09 Havoc Pennington - - * src/metacity.schemas.in: change Windows+click back to Alt+click, - Windows+click just surprised everybody and didn't work half the - time. Maya users can configure it, and GTK DND can change its - default. - -2003-01-08 Havoc Pennington - - * src/metacity.schemas.in: assign Alt+F12 to shade window, - per #102658 - -2003-01-07 Havoc Pennington - - * src/screen.c (update_num_workspaces): fix off-by-one, patch from - readams@hmc.edu, #102806 - -2003-01-06 Arvind Samptur - - * src/window.c: (constrain_position) don't apply - offscreen height difference. This would get the - window under the panel on a resize or a move. - Fixes #102418 - -2003-01-05 Havoc Pennington - - * src/screen.c (meta_screen_calc_workspace_layout): invert - vertical_workspaces cases (we want to go down each column if - it's vertical, and across each row if horizontal). Patch - from readams@hmc.edu - -2003-01-05 Pablo Saratxaga - - * configure.in: Added Macedonian (mk) to ALL_LINGUAS - -2003-01-05 Havoc Pennington - - * src/frames.c (meta_frames_apply_shapes): put in the - HAVE_GTK_MULTIHEAD conditionals so we build with GTK 2.0 - -2003-01-05 Havoc Pennington - - * src/window.c (meta_window_show): focus new windows even in - mouse focus mode, #89981, patch from readams@hmc.edu - -2003-01-05 Havoc Pennington - - * src/workspace.c (meta_workspace_get_neighbor): redo using new - calc_workspace_layout to fix #98302 - - * src/util.c (topic_name): shorten default prefix - - * src/screen.c (meta_screen_calc_workspace_layout): enhance this - to handle all the funky layouts and calculate more information - than before - -2003-01-05 Pauli Virtanen - - * configure.in (ALL_LINGUAS): Added "fi" (Finnish). - -2003-01-05 Havoc Pennington - - * src/frames.c (meta_frames_apply_shapes): handle - the client having a shape mask, fixes #101806 - - * src/core.c (meta_core_get_client_xwindow): new function - - * src/frame.c, src/frame.h: keep a flag for whether we need to - update the frame shape - - * src/window.c (meta_window_new): select for ShapeNotify - - * src/display.h, src/display.c: actually query the shape - extension, instead of just using it all over the place. - - * src/prefs.c (update_application_based): don't let people turn on - application_based, as it just causes funky bugs. We can reenable - the pref when/if it ever does something useful. - -2003-01-03 Havoc Pennington - - * src/display.c: include the Xrandr header file - - * src/window.c (meta_window_fill_horizontal) - (meta_window_fill_vertical): maximize to work area, not entire - screen. doh. - -2002-12-19 Ross Burton - - * doc/metacity-theme.dtd: Fix a typo and loosen the requirements - for the resize element. - -2002-12-19 Havoc Pennington - - * Reverted visual bell patch, #99886 - -2002-12-19 Yanko Kaneti - - * configure.in: (ALL_LINGUAS) Added Bulgarian (bg). - -2002-12-18 Havoc Pennington - - * src/window.c (meta_window_new): select ColormapChangeMask - on toplevel windows, maybe a partial fix for #101478 - -Tue Dec 17 17:50:19 2002 HideToshi Tajima - - * src/themes/AgingGorilla/metacity-theme-1.xml: added support for - border only windows. #100984. - -2002-12-17 Havoc Pennington - - * src/display.c (meta_display_begin_grab_op): don't use "(null)" - for null pointers, use "none", so I can distinguish - glibc-generated (null) which is a bug. - (key_event_description): ditto - (meta_display_begin_grab_op): ditto - - * src/window.c (update_sm_hints): ditto - - * src/keybindings.c (reload_modmap): ditto - (meta_display_process_key_event): ditto - -2002-12-17 Havoc Pennington - - * src/metacity.schemas.in: s/focussed/focused/ - -2002-12-17 Havoc Pennington - - * src/xprops.c (validate_or_free_results): add a comma to message #101401 - -2002-12-16 Bill Haneman - - * configure.in: - Check for XKB extension. - - * src/Makefile.am: - Added bell.c and bell.h to metacity sources. - - * src/common.h: - (MetaFrameFlags): - Added META_FRAME_IS_FLASHING flag. - - * src/frame.h: - (MetaFrame): Added is_flashing field. - - * src/frame.c: - (meta_window_ensure_frame): - Initialize the is_flashing flag to FALSE. - (meta_frame_get_flags): - Handle the FRAME_IS_FLASHING flag. - (meta_window_destroy_frame): - Call meta_bell_notify_frame_destroy. - - * src/prefs.h: - (MetaPreference): - Added META_PREF_VISUAL_BELL, META_PREF_AUDIBLE_BELL, - META_PREF_VISUAL_BELL_TYPE. - (MetaVisualBellType): New enum. - (meta_prefs_get_visual_bell, meta_prefs_bell_is_audible): - (meta_prefs_get_visual_bell_type): - New accessor declarations. - - * src/prefs.c: - (#includes): Include "display.h", since we now call - meta_displays_list() in our update func. - (#defines): - Define KEY_VISUAL_BELL, KEY_AUDIBLE_BELL, - and KEY_VISUAL_BELL_TYPE. - (provide_visual_bell, bell_is_audible, visual_bell_type): - New static state variables. - (update_visual_bell): New method to update visual-bell - boolean settings from keys "visual_bell" and "audible_bell". - (update_visual_bell_type): - New method to update visual-bell type setting. - (visual_bell_type_from_string) : - New method to convert from gconf string to visual-bell - type enum. Only currently recognized values are "fullscreen" - and "frame_flash". - (change_notify): - Handle changes to visual and audible bell properties. - (meta_prefs_get_visual_bell, meta_prefs_bell_is_audible): - (meta_prefs_get_visual_bell_type): - New accessor definitions. - (meta_prefs_init): Added a second call to notify_add, - listens to "/desktop/gnome/interface" as well as "apps/metacity". - Also call the update funcs for the new visual-bell gconf keys. - (meta_preference_to_string): - Handle the visual/audible bell cases. - - * src/bell.h: - (meta_bell_notify); - New method, calls a visual notifucation - method based on the visual-bell-type, or none if the type - is unrecognized or invalid. - (meta_bell_set_audible): - New public method for setting the audible bell setting, - used in updater for new gconf key "audible_bell". - (meta_bell_init): - Initialize the bell notification for a display. - (meta_bell_shutdown): - Shutdown the bell notification for a display. - (meta_bell_notify_frame_destroy): - Remove pending idle handlers on notification. - - * src/bell.c: - Include "bell.h", and conditionally include . - (meta_bell_set_audible): - If XKB is present, enable/disable the audible system - bell based on the gconf key /desktop/gnome/interface/audible_bell. - (meta_bell_init): - Query and initialize XKB if present, register for notification - on the bell, and set audible bell according to gconf settings. - (meta_bell_flash_screen): - Maps and unmaps a fullscreen X window (painted white, then - black), which causes a fullscreen 'flash' transient. - (meta_bell_flash_window_frame): - Flashes the titlebar of a specified window. - (meta_bell_flash_frame): - Calls meta_bell_flash_window_frame on the window which - was the source of the current bell event, or the currently - focussed window if the event source cannot be determined. - (meta_bell_unflash_frame): - Restore the frame's appearance to normal. - (meta_bell_flash_fullscreen): - Call meta_bell_flash_fullscreen for all screens. - (meta_bell_shutdown): - New method. - (meta_bell_notify_frame_destroy): - Remove pending idle handlers on notification, - testing for frame->is_flashing first. - - * src/display.h: - (MetaDisplay): Added xkb_base_event_type field. - - * src/display.c: - Check for XKB and include "X11/XKBlib.h" if present. - (meta_display_open): Call meta_bell_init. - (event_callback): Call meta_bell_notify - when event comes from XKB and is XkbBellNotify - (prefs_changed_callback): - Handle META_PREF_AUDIBLE_BELL notification. - - * src/screen.h: - (MetaScreen): Add flash_window field. - - * src/screen.c: - (meta_screen_new): - Initialize flash_window field. - - * src/theme.c: - (theme_get_style): - New heuristic for focus-style, to invert sense of focus - flag when META_FRAME_IS_FLASHING flag is set. - - * src/metacity.schemas.in: - Added scheme information for - /apps/metacity/general/visual_bell, - /apps/metacity/general/audible_bell, and - /apps/metacity/general/visual_bell_type. - -2002-12-16 Havoc Pennington - - * src/window-props.c (init_wm_name): argh, screwed that up. get - WM_NAME as VALUE_TEXT_PROPERTY #101383 - -2002-12-16 Bill Haneman - - * configure.in: - Check for XKB extension. - - * src/Makefile.am: - Added bell.c and bell.h to metacity sources. - - * src/common.h: - (MetaFrameFlags): - Added META_FRAME_IS_FLASHING flag. - - * src/frame.h: - (MetaFrame): Added is_flashing field. - - * src/frame.c: - (meta_window_ensure_frame): - Initialize the is_flashing flag to FALSE. - (meta_frame_get_flags): - Handle the FRAME_IS_FLASHING flag. - (meta_window_destroy_frame): - Call meta_bell_notify_frame_destroy. - - * src/prefs.h: - (MetaPreference): - Added META_PREF_VISUAL_BELL, META_PREF_AUDIBLE_BELL, - META_PREF_VISUAL_BELL_TYPE. - (MetaVisualBellType): New enum. - (meta_prefs_get_visual_bell, meta_prefs_bell_is_audible): - (meta_prefs_get_visual_bell_type): - New accessor declarations. - - * src/prefs.c: - (#includes): Include "display.h", since we now call - meta_displays_list() in our update func. - (#defines): - Define KEY_VISUAL_BELL, KEY_AUDIBLE_BELL, - and KEY_VISUAL_BELL_TYPE. - (provide_visual_bell, bell_is_audible, visual_bell_type): - New static state variables. - (update_visual_bell): New method to update visual-bell - boolean settings from keys "visual_bell" and "audible_bell". - (update_visual_bell_type): - New method to update visual-bell type setting. - (visual_bell_type_from_string) : - New method to convert from gconf string to visual-bell - type enum. Only currently recognized values are "fullscreen" - and "frame_flash". - (change_notify): - Handle changes to visual and audible bell properties. - (meta_prefs_get_visual_bell, meta_prefs_bell_is_audible): - (meta_prefs_get_visual_bell_type): - New accessor definitions. - (meta_prefs_init): Added a second call to notify_add, - listens to "/desktop/gnome/interface" as well as "apps/metacity". - Also call the update funcs for the new visual-bell gconf keys. - (meta_preference_to_string): - Handle the visual/audible bell cases. - - * src/bell.h: - (meta_bell_notify); - New method, calls a visual notifucation - method based on the visual-bell-type, or none if the type - is unrecognized or invalid. - (meta_bell_set_audible): - New public method for setting the audible bell setting, - used in updater for new gconf key "audible_bell". - (meta_bell_init): - Initialize the bell notification for a display. - (meta_bell_shutdown): - Shutdown the bell notification for a display. - (meta_bell_notify_frame_destroy): - Remove pending idle handlers on notification. - - * src/bell.c: - Include "bell.h", and conditionally include . - (meta_bell_set_audible): - If XKB is present, enable/disable the audible system - bell based on the gconf key /desktop/gnome/interface/audible_bell. - (meta_bell_init): - Query and initialize XKB if present, register for notification - on the bell, and set audible bell according to gconf settings. - (meta_bell_flash_screen): - Maps and unmaps a fullscreen X window (painted white, then - black), which causes a fullscreen 'flash' transient. - (meta_bell_flash_window_frame): - Flashes the titlebar of a specified window. - (meta_bell_flash_frame): - Calls meta_bell_flash_window_frame on the window which - was the source of the current bell event, or the currently - focussed window if the event source cannot be determined. - (meta_bell_unflash_frame): - Restore the frame's appearance to normal. - (meta_bell_flash_fullscreen): - Call meta_bell_flash_fullscreen for all screens. - (meta_bell_shutdown): - New method. - (meta_bell_notify_frame_destroy): - Remove pending idle handlers on notification, - testing for frame->is_flashing first. - - * src/display.h: - (MetaDisplay): Added xkb_base_event_type field. - - * src/display.c: - Check for XKB and include "X11/XKBlib.h" if present. - (meta_display_open): Call meta_bell_init. - (event_callback): Call meta_bell_notify - when event comes from XKB and is XkbBellNotify - (prefs_changed_callback): - Handle META_PREF_AUDIBLE_BELL notification. - - * src/screen.h: - (MetaScreen): Add flash_window field. - - * src/screen.c: - (meta_screen_new): - Initialize flash_window field. - - * src/theme.c: - (theme_get_style): - New heuristic for focus-style, to invert sense of focus - flag when META_FRAME_IS_FLASHING flag is set. - - * src/metacity.schemas.in: - Added scheme information for - /apps/metacity/general/visual_bell, - /apps/metacity/general/audible_bell, and - /apps/metacity/general/visual_bell_type. - -2002-12-16 Havoc Pennington - - * src/window-props.c: use META_PROP_VALUE_STRING_AS_UTF8 so - we convert old Latin-1 WM_NAME to UTF-8 - - * src/xprops.h (enum): add META_PROP_VALUE_STRING_AS_UTF8 to get a - latin1 string then convert. - -2002-12-15 Havoc Pennington - - * src/window.c (meta_window_new): get window name before anything - else. - - * src/xprops.c (validate_or_free_results): instead of suggesting - how to get window title etc. with xprop, just print out the - window title. much better. - -2002-12-15 Havoc Pennington - - * src/xprops.c (validate_or_free_results): make the warning about - strange property contents blame the application and explain how to - use xprop to diagnose which app is causing the problem. - -2002-12-15 Havoc Pennington - - * src/prefs.c (meta_prefs_change_workspace_name): don't pass NULL - string to gconf_client_set_string #101237 - -2002-12-13 Havoc Pennington - - * src/tools/Makefile.am (Desktop_in_files): only install .desktop - file for metacity-properties if we actually install - metacity-properties - - * src/display.c (event_callback): not focusing on button 2 click - was crack, revert that change. - -2002-12-09 Havoc Pennington - - * AUTHORS: add myself here, bug #100789 - - * src/display.c (meta_display_set_grab_op_cursor): drop - PointerMotionHintMask - - * src/window.c (meta_window_handle_mouse_grab_op_event): don't use - XQueryPointer, as we aren't using PointerMotionHint now - - * src/display.c (event_callback): rearrange a bit of code - for slight speedup and clarity - - * src/window.c (update_resize) - (meta_window_handle_mouse_grab_op_event): implement - usage of the _METACITY_UPDATE_COUNTER - (meta_window_handle_mouse_grab_op_event): fix code that - used event->xbutton with a motion event - - * src/display.c (meta_display_open): add new atoms, and - initialize Xsync if we have it - (grab_op_is_resizing): new function - (meta_display_begin_grab_op): create an alarm monitoring - window's _METACITY_UPDATE_COUNTER - (meta_spew_event): conditionalize this on WITH_VERBOSE_MODE - and print alarm events. - - * src/window.c (meta_window_new): fetch _METACITY_UPDATE_COUNTER - - * configure.in (HAVE_XSYNC): check for Xsync extension - -Mon Dec 9 22:09:56 2002 Soeren Sandmann - - * src/display.c, src/window.c: Handle crossing events during - resizing. (#93384). - -2002-12-09 Havoc Pennington - - * configure.in: 2.4.8 - -2002-12-08 Havoc Pennington - - * README: updates - - * src/window.c (MAX_RESIZES_PER_SECOND): change to 20 instead of - 30, just as an experiment. - (MOVE_THRESHOLD): change 15 to 20 - (RESIZE_THRESHOLD): change 15 to 20 - - * src/util.c (ensure_logfile): kill this function when verbose - mode is disabled. - -2002-12-08 Havoc Pennington - - * src/window.c (meta_window_fill_vertical) - (meta_window_fill_horizontal): new functions to resize to - fill screen - - * src/keybindings.c: add vert, horiz maximize - - * src/prefs.c: had vert, horiz maximize - - * src/metacity.schemas.in: shorten some overlong short - descriptions that make the keybindings capplet look ugly. - Add maximize_vertically, maximize_horizontally keys. - -2002-12-08 Havoc Pennington - - * src/prefs.c (meta_prefs_get_application_based): make this always - return FALSE for now, to avoid bug reports. - - * src/util.c (ensure_logfile): put "opened log file" message on - stderr so it will normally land in ~/.xsession-errors - - * configure.in: remove extra AC_ARG_PROGRAM - - * src/display.c (event_callback): handle the toggle-verbose message - - * src/tools/metacity-message.c: add a toggle-verbose message, been - meaning to do this for a while. - - * src/util.c (meta_set_verbose): if verbose mode is enabled and we - don't support it, then exit. - - * src/prefs.c: allow building without gconf (currently means some - prefs are no-ops) - - * src/util.c, src/util.h: support defining macros to - kill all verbose output entirely. (Removes the code and strings - associated with it) - - * configure.in: don't get METACITY_PROPS_LIBS if not building the - config dialog. - (HAVE_GCONF): allow building sans gconf, if you are size-sensitive - and not using gnome. - (WITH_VERBOSE_MODE): add ability to disable all the verbose debug - spew strings, to shrink the binary. - (--disable-sm): allow SM support to be forced on or off - (--disable-startup-notification): allow forcing this on or off - -2002-12-08 Havoc Pennington - - * src/prefs.c (update_workspace_name): also treat empty string as - "unset" in this function. - -Thu Dec 5 18:41:02 2002 HideToshi Tajima - - * src/window.h (META_WINDOW_IN_NORMAL_TAB_CHAIN, - META_WINDOW_IN_DOCK_TAB_CHAIN) : never use a window with input = - FALSE take_focus = FALSE in the normal and dock tab chains. #90409 - -Thu Dec 5 13:56:52 2002 HideToshi Tajima - - * src/display.c (event_callback): move a window to the current - space on the MapRequest when it's not on the space yet. #100390 - -2002-12-01 Havoc Pennington - - * src/frames.c (get_control): rearrange this function a bit, so - that we return CONTROL_TITLE for anything above the bottom of the - titlebar, in the fallback case where no other control was found. - Also, don't return RESIZE_N for title rect above the top resize - size, unless the window is resizable. - (meta_frames_button_press_event): only start a move when clicking - control TITLE, not control NONE. This way you don't start moving - a nonresizable window if you click its edges. - -2002-12-01 Havoc Pennington - - * src/tools/Makefile.am: conditionalize building the config dialog - - * configure.in (BUILD_CONFIG_DIALOG): add --enable-config-dialog - option to turn on the "window focus" dialog. This is part of - deprecating this dialog. - -2002-11-30 Havoc Pennington - - * src/screen.c (STARTUP_TIMEOUT): lengthen to 15 seconds - - * src/util.c (utf8_fputs): hmm, return a value - - * src/screen.c (meta_screen_apply_startup_properties): new - function to apply initial workspace based on startup sequence. - - * src/window.c (meta_window_new): load _NET_STARTUP_ID - (meta_window_get_startup_id): new function - - * src/window-props.c (meta_display_init_window_prop_hooks): add - hooks for _NET_STARTUP_ID - - * src/display.c (event_callback): send property events to - groups. - - * src/xprops.c (meta_prop_get_values): make a type of INVALID - mean to ignore that property (don't fetch its value). - - * src/group.c (meta_group_property_notify): new function - - * src/screen.c (set_supported_hint): support _NET_STARTUP_ID - - * src/display.c (meta_display_open): add _NET_STARTUP_ID to atoms - we initialize - - * src/group-private.h: private header shared between - group-props.c, group.c - - * src/group-props.h, src/group-props.c: new files to contain - functions for retrieving group properties - - * src/window.c (meta_window_same_application): change this a bit - to work with new definition of group - - * src/group.c (meta_window_get_group): always create a group for - every window, using the window's own ID as group leader if - required. - - * src/window.c (update_wm_hints): handle changes to group leader - - * src/group.c (meta_window_group_leader_changed): new function - - * src/display.h (struct _MetaDisplay): _NET_WM_WINDOW_TYPE_SPLASH, - not SPLASHSCREEN. Reported by Gregory Merchan and Matthias Clasen. - - * src/screen.c (startup_sequence_timeout): when timing out a - startup sequence, send a remove message, don't just time it out - locally. - -2002-11-26 Calum Benson - - * src/themes/Crux : - - Removed alpha layers from the pixmaps that don't need them. - Fixes #98389, results in 10-15% speedup on most machines. - -2002-11-26 Glynn Foster - - * configure.in: 2.4.5 - -2002-11-23 Dan Mills - - * Makefile.am: remove theme-format.txt, it's now in doc/. - -2002-11-22 Havoc Pennington - - * src/window.c (meta_window_change_workspace): patch from - Hidetoshi Tajima to move a window's transients when moving - the window between workspaces. #98900 - -2002-11-21 Havoc Pennington - - * src/display.c (meta_display_open): init ret_to to - RevertToPointerRoot out of sheer paranoia; don't want no - RevertToNone in my code! - -2002-11-21 Havoc Pennington - - * src/window.c (update_initial_workspace): delete - (meta_window_new): add getting initial workspace to the batch - property get call - - * src/window-props.c (meta_display_init_window_prop_hooks): add - net_wm_desktop and win_workspace support - -2002-11-20 Havoc Pennington - - * src/window-props.c (set_icon_title): remove unused variable - - * src/screen.c (meta_screen_new): read an existing - _NET_CURRENT_DESKTOP and restore it if set. Makes a restart even - less visible. - - * src/workspace.c (set_active_space_hint): don't set the hint - during the process of unmanaging a screen - -2002-11-20 Havoc Pennington - - * configure.in: add doc/Makefile - - * doc/metacity-theme.dtd: add DTD for themes from Ross Burton - - * doc/Makefile.am: doc subdir - - * doc/theme-format.txt: move to doc subdir - -2002-11-19 Havoc Pennington - - Should really fix #98303 - - * src/prefs.c (meta_prefs_change_workspace_name): add - bad hack to treat empty string the same as null - - * src/menu.c (get_workspace_name_with_accel): allocate one more - than the length of "name" so we have room for a nul byte (and - don't malloc(0) on empty strings). Also some formatting cleanups. - -2002-11-19 Havoc Pennington - - * src/window.c (meta_window_client_message): do a - recalc_window_features after setting new wm_state in order - to update skip_pager in addition to wm_state_skip_pager - (set_net_wm_state): base _NET_WM_STATE on skip_pager not - wm_state_skip_pager, ditto for skip_taskbar - -2002-11-19 Havoc Pennington - - Fix #98303 and assorted cleanup - - * src/prefs.c (meta_preference_to_string): handle - META_PREF_WORKSPACE_NAMES - - * src/menu.c (get_workspace_name_with_accel): assert that the - workspace has a name - - * src/screen.c (meta_screen_ensure_workspace_popup): assert that - we got a workspace name - (meta_screen_ensure_workspace_popup): assert that we got a - workspace name - - * src/prefs.c (update_workspace_name): fix screwiness (strcmp with - a freed string, assorted bad logic) - (init_workspace_names): assert that we filled in a default - workspace name - (meta_prefs_get_workspace_name): assert non-NULL workspace name - -2002-11-16 Bill Haneman - - * src/themes/Atlanta/metacity-theme-1.xml: - Changed outer bevel and focus line color to - work better with inverse themes (no effect on - Default or other existing gtk+ themes). - -2002-11-13 Havoc Pennington - - * src/ui.c (get_cmap): fix a multihead safety thing (use proper - system colormap for the drawable's screen) - -Thu Nov 14 17:30:10 2002 Jonathan Blandford - - * src/Makefile.am (libmetacityinclude_HEADERS): include common.h. - -2002-11-12 Havoc Pennington - - * src/theme.c (draw_op_as_pixbuf): don't read from op->data.image - when the op is an icon - -2002-11-12 Havoc Pennington - - * src/stack.c (meta_stack_get_default_focus_window): never use a - window with input = FALSE take_focus = FALSE as the default focus - window #95454 fix from Hidetoshi Tajima - -2002-11-10 James M. Cape - - * src/themes/Esco/metacity-theme-1.xml: Major changes - to look of theme. I'd also recommend "minimize,maximize:close" - for the button_layout, it looks really slick :-). - -2002-11-08 Mark McLoughlin - - * src/workspace.c: - (meta_motion_direction_to_string), - (meta_screen_corner_to_string): impl for nice debugging. - (meta_workspace_get_neighbor): fix broken logic and - cleanup debugging. - -Thu Nov 7 17:07:21 2002 Jonathan Blandford - - * src/libmetacity-private.pc.in: add a pc file for - libmetacity-private - - * src/Makefile.am: Install a few files as a shared library so that - others can draw metacity themes. - -2002-11-06 Havoc Pennington - - * src/keybindings.c (grab_keys): push an error trap around the - whole window-key-grab loop - (ungrab_all_keys): avoid requiring return value from the error - trap, unless in debugging mode - (regrab_window_bindings, regrab_screen_bindings): push traps - around the loops, for efficiency - - * src/display.c (event_callback): fix from Padraig O'Briain to - compress extra MappingNotify events to avoid extra work. - -2002-11-05 Calum Benson - - * src/themes/Crux/active-restore-button.png: - * src/themes/Crux/inactive-restore-button.png: - * src/themes/Crux/metacity-theme-1.xml: add a restore button - for maximized windows, and un-hard-code titlebar text colors. - Fixes #97759. - -2002-11-05 Havoc Pennington - - * src/workspace.c (meta_workspace_get_neighbor): apply patch from - Nikos Mouat to fix this function - -2002-11-04 Havoc Pennington - - * src/theme.c (scale_and_alpha_pixbuf): fix bug I introduced in - case where scaling was done in both directions. - -2002-11-04 Havoc Pennington - - Patch from Brian Cameron to implement the vertical/horizontal - striped image accelerated scaling from the gtk pixbuf engine. - - * src/theme.c (scale_and_alpha_pixbuf): if an image is - vertical/horizontal stripes, use special extra-fast scaling - routines. - - * src/theme-parser.c (parse_draw_op_element): when loading an - image, mark it as vertically/horizontally striped when appropriate - -2002-11-04 Erwann Chenede - - - * src/xprops.c (meta_prop_get_values): changed __FUNCTION__ - to G_GNUC_FUNCTION as __FUNCTION__ is not portable. - -2002-11-03 Havoc Pennington - - * src/display.c (meta_display_grab): remove XSync calls from here - (meta_display_ungrab): remove XSync from here, but put in - an XFlush to be sure we get the ungrab sent. - - * src/util.c (meta_topic): track sync count here - - * src/errors.c: move sync count out of here - - Throughout: error spew on all XSync() calls - - * src/run-metacity.sh: don't set METACITY_DEBUG - -2002-11-03 Havoc Pennington - - * src/window-props.c (meta_display_init_window_prop_hooks): add - _NET_WM_NAME, WM_NAME, _NET_WM_ICON_NAME, WM_ICON_NAME support - - * src/window.c (meta_window_new): use window-props.h for - _NET_WM_NAME, WM_NAME, _NET_WM_ICON_NAME, WM_ICON_NAME - -2002-11-03 Havoc Pennington - - * src/window.c (meta_window_new): use window-props.h stuff for a - couple of properties - (implement_showing): fix printf string - - * src/xprops.c (meta_prop_free_values): new function - - * src/window-props.h, src/window-props.c: start moving code that - handles loading window properties into this file. - -2002-11-03 Havoc Pennington - - * src/stack.c (create_constraints): filter out windows that aren't - in the stack for whatever reason, avoids a crash - -2002-11-03 Havoc Pennington - - * src/window.c (meta_window_calc_showing): split into "see if we - should be showing" and "actually show/hide" functions - (idle_calc_showing): rework to first unmap all newly-hidden - windows from bottom to top then map all newly-showing windows from - top to bottom resulting in fewer exposes, #95220 - -2002-11-03 Havoc Pennington - - * src/theme.c (meta_frame_layout_calc_geometry): fix from Garrett - LeSage for which button backgrounds we draw when - -2002-11-03 Havoc Pennington - - * src/workspace.c (meta_workspace_get_name): new function, - and remove workspace->name field, instead just get the - name from prefs each time - - * src/screen.c (meta_screen_update_workspace_names): update the - gconf key to persist workspace names here, instead of changing - the names we use - - * src/util.c (topic_name): add META_DEBUG_PREFS - - * src/prefs.c: change NUM_COMMANDS to 32 to allow more custom - commands, implement workspace names - - * src/metacity.schemas.in: add workspace_names/name_NN gconf keys. - -2002-11-01 Christian Neumair - - * configure.in: We want at least autoconf 2.5. - -2002-10-29 Havoc Pennington - - * configure.in: 2.4.3, why not - -2002-10-28 Havoc Pennington - - * src/window.c (update_size_hints): use meta_prop_get_size_hints - - * src/xprops.c: add support for getting XSizeHints - -2002-10-28 Havoc Pennington - - * src/window.c, src/display.c: store the window menu on the - display and blow it away when a window closes, so we don't - get funny stuck menus. Patch from Martin Garton #87514 - -2002-10-27 Anders Carlsson - - * configure.in: Make XRandr detection work better. - -2002-10-27 Havoc Pennington - - * src/window.c (meta_window_free): move - meta_window_shutdown_group() much earlier in the destroy process. - May fix #96928 tracked down by Kjartan Maraas and Martin Garton. - - * src/group.c (meta_window_get_group): never add window to a group - after we've started unmanaging the window - -2002-10-26 Havoc Pennington - - * src/iconcache.c: include config.h - - * src/group.c: include config.h - - * src/frame.c: include config.h - - * src/core.c: include config.h so it doesn't crash all over the - place due to #ifdef HAVE_STARTUP_NOTIFICATION - - * src/util.c (meta_print_backtrace): export from this file - - * src/main.c (log_handler): print backtrace here - -2002-10-26 Havoc Pennington - - * src/wm-tester/main.c (evil_timeout): make windows randomly - transient for each other http://bugzilla.gnome.org/show_bug.cgi?id=96928 - -2002-10-26 Havoc Pennington - - * src/xprops.c (meta_prop_get_text_property): new function - (meta_prop_get_wm_hints): new function - (meta_prop_get_class_hint): new function - -2002-10-26 Havoc Pennington - - * src/window.c (meta_window_new): use multi-value-get on a couple - of properties for testing - - * src/xprops.c (meta_prop_get_values): implement multi-value-get - - * src/window.c (update_mwm_hints): XFree motif hints as we changed - it to use Xmalloc - - * src/xprops.c: massively rework this to set up a - get-multiple-properties-at-once API. - - * src/async-getprop.c (ag_Xmalloc): new function - -2002-10-25 Havoc Pennington - - Add "busy cursor on app startup" support, conditionally - works - only if libstartup-notification is found, and in practice requires - a GTK patch that's not in yet. - - * src/screen.c: monitor startup events and set busy cursor if - appropriate - - * src/display.c (meta_display_open): create SnDisplay - - * configure.in: check for startup notification, - and add the cute "configure summary" at the end - -2002-10-24 Havoc Pennington - - * src/theme.c (meta_frame_layout_calc_geometry): if only one - right-corner button, use right_right_background not - right_left_background - -2002-10-24 Havoc Pennington - - * src/window.c (meta_window_get_icon_geometry): make public - - * src/screen.c (meta_screen_ensure_tab_popup): put the alt+tab - highlight-window indicator on the icon, not the window itself, - if the window is minimized. - -2002-10-24 Havoc Pennington - - * src/display.c (meta_display_get_tab_list): put minimized windows - at the end of Alt+Tab, #89416 - -2002-10-23 Havoc Pennington - - * src/theme.c (meta_frame_layout_calc_geometry): initialize the - left button background rectangles. - -2002-10-21 Havoc Pennington - - Optimizations for managing new windows (do not all take effect if - METACITY_DEBUG=1). Bug #96404 - - * src/keybindings.c (meta_change_keygrab): use error trap nesting - and conditionalize on meta_is_verbose() to avoid a ton of XSync - - * src/display.c (meta_change_button_grab): ditto - - Throughout: move to new error trap setup to save on XSync calls, - new setup is: - - * src/errors.c (meta_error_trap_push_with_return): new function, - an error trap that needs to care about return value and thus - sync even if an outer trap still exists - (meta_error_trap_pop_with_return): new function - (meta_error_trap_pop): add "last_request_was_roundtrip" - argument allowing us to avoid XSync() if we just did - a GetProperty or whatever. - - * src/util.c (meta_warning): flush the warning file descriptor - - * src/Makefile.am (INCLUDES): define G_LOG_DOMAIN - -2002-10-20 Havoc Pennington - - * src/ui.c (meta_image_window_new): put multihead stuff in - HAVE_GTK_MULTIHEAD, reported by John Palmieri - -2002-10-20 Havoc Pennington - - * src/keybindings.c (handle_raise_or_lower): check above->mapped - before deciding if it overlaps the window being raiselowered, - fix from Stephane Chauveau - -2002-10-19 Jeremy Katz - - * configure.in: make Xrandr check less noisy - -2002-10-18 Havoc Pennington - - * src/effects.c (meta_effects_draw_box_animation): call - meta_image_window_new in multihead-safe way - - * src/ui.c (meta_image_window_new): multihead safety - -2002-10-18 Havoc Pennington - - * src/window.c (meta_window_refresh_resize_popup): only create the - resize popup if width_inc or height_inc are > 1 - - * src/resizepopup.c: Clear out all the weird tickmark cruft, - saves us about 2.5K of binary size, whee - (meta_ui_resize_popup_new): take display/screen arguments and make - multihead-safe #94349 - -2002-10-18 Havoc Pennington - - * src/keybindings.c (do_choose_window): don't start the cycle - process if the binding for switching windows has no modifier bits, - just focus the window immediately. - - * src/prefs.c, src/keybindings.c: add a keybinding to move between - windows that goes in the opposite direction. This is mostly - useful if you want to bind unmodified keys to the switch windows - functions, e.g. if you have "Forward" and "Back" keys on your - keyboard. Patch from Shilad Sen - -2002-10-18 Havoc Pennington - - * src/prefs.c, src/frames.c: add "what happens when you double - click the titlebar" setting, patch from Sean Middleditch bug - #95625. This is basically an "add Windows emulation mode" patch. - -2002-10-18 Havoc Pennington - - * src/metacity.schemas.in: move window-click to Super+click not - Alt+click by default. Super should be the Windows key on keyboards - that have one and are so configured. Prepare for the FAQ on this. - -2002-10-18 Havoc Pennington - - * src/window.c (constrain_size): fix min aspect handling, - patch from Martin Garton #94943 - -2002-10-18 Andras Timar - - * configure.in: Added hu to ALL_LINGUAS. - -2002-10-18 Havoc Pennington - - * src/stack.c (constrain_stacking): replace the old - apply_constraints with wacky new approach involving graphing all - the constraints then walking the graph. Fixes #94876 and probably - other stacking bugs as well, thanks to Arvind for tracking down - the issue. - - (compute_layer): add FIXME and reference to bug #96140 - -2002-10-17 Havoc Pennington - - * src/stack.c (apply_constraints): don't place - transient-for-whole-group windows above _each other_, only - above other windows in the group that aren't themselves - transient-for-whole-group. Should help with part of #94876 - -2002-10-17 Havoc Pennington - - * src/stack.c (apply_constraints): fix memory leak of - group_windows, and don't use the variable name "tmp" twice. Shadow - variables bad. - -2002-10-17 Havoc Pennington - - * src/tools/metacity-window-demo.c (dialog_cb): add code to create - big stacks of dialogs transient for each other, for testing. - -2002-10-16 Havoc Pennington - - * src/workspace.c: workspaces are all per-screen now, fix - accordingly - - * src/core.c: fix multihead workspace stuff - - * src/keybindings.c: multihead-rama - - * src/screen.c (meta_screen_show_desktop): new functions to - replace display equivalents - - * src/display.c (meta_display_get_workspace_by_screen_index): get - rid of this - (meta_display_get_workspace_by_index): get rid of this - (event_callback): handle _NET_SHOWING_DESKTOP message per-screen - - * src/screen.c (meta_screen_get_workspace_by_index): new function - - * src/screen.h (struct _MetaScreen): move workspace list, and - showing_desktop flag, to be per-screen - - * src/window.c (window_query_root_pointer): return whether pointer - is on window's screen - (meta_window_handle_mouse_grab_op_event): don't use coordinates - from other screens when updating a window operation on the current - screen. I can't believe no one has reported this... - -2002-10-16 Havoc Pennington - - * src/window.c (meta_window_client_message): update window layer - when above/below state is changed. Fixed by Ross Burton. - -2002-10-14 Federico Mena Quintero - - * src/display.c (event_callback): Ignore EnterNotify events when - the detail field is set to NotifyInferior. Fixes #95747. - -2002-10-12 Havoc Pennington - - * src/metacity.schemas.in: button layout key - - * src/prefs.c: Add button layout gconf key - (change_notify): use some "else if" instead of "if" where we - should have been - -2002-10-11 Havoc Pennington - - * src/display.c (event_callback): don't raise window on button 2 - click, only on button 1 and button 3. - - * src/frames.c (meta_frames_button_press_event): lower on button 2 - press on frame - - * src/core.c (meta_core_user_lower): new function - -2002-10-11 Havoc Pennington - - * src/stack.c (window_is_fullscreen_size): make the checks here - allow windows larger than the screen in addition to - exactly-screen-size - - * src/window.c (meta_window_configure_request): delete the "try to - auto-enter-fullscreen-state" hack here, because it was broken, and - the changes to the stacking code to move screen-size focused - windows to the fullscreen layer should work better. - (meta_window_new): remove auto-fullscreen hack from here too - -2002-10-09 Havoc Pennington - - * src/stack.c (apply_constraints): also keep utility/menu/toolbar - windows above their whole group. - - (get_standalone_layer): don't use META_LAYER_FOCUSED_WINDOW, but - only use META_LAYER_FULLSCREEN while the fullscreen window has - focus. Also, put screen-sized windows in the fullscreen layer, - even if we didn't dare to actually put them in the fullscreen - state. - -2002-10-07 Havoc Pennington - - Add a modifier key preference for the Alt+click stuff. - Can be set to "disabled" as well. - - * src/run-metacity.sh: load .Xmodmap in the Xnest if it exists - - * src/display.c (meta_display_ungrab_window_buttons): ungrab - AnyModifier in case the modifier changed since we grabbed - (meta_display_open): rearrange code to use meta_display_close() to - mop up when we can't find any screens, avoiding the need to - keep the bail-out code in sync with meta_display_close. - - * src/keybindings.c (devirtualize_modifiers): move this function - to a public place in display.c - - * src/metacity.schemas.in: add setting for the modifier key - to use for Alt+left/middle/right click. - - * src/prefs.c (update_binding): add a missing newline to a warning - (meta_prefs_get_mouse_button_mods): new function - - * src/ui.c (meta_ui_parse_modifier): new function - -2002-10-07 Havoc Pennington - - * src/async-getprop.c: don't include unportable Xproto.h, fix from - Glynn Foster. - -2002-10-06 Havoc Pennington - - * src/async-getprop.c: change to add only one _XAsyncHandler per - display, speeding things up a bit. - -2002-10-06 Havoc Pennington - - * src/async-getprop.c: Add wacky hack suggested by Keith Packard - to get X properties asynchronously. Not actually used by metacity - yet, but thinking about it. - -2002-10-04 Havoc Pennington - - * configure.in: actually link to RANDR_LIBS - -2002-10-04 Havoc Pennington - - * src/display.c (event_callback): do XRRUpdateConfiguration() - if we have RandR extension, else poke in Xlib's screen struct to - update the screen size. - - * configure.in: fix a bogus overwrite of cppflags, - add a check for RandR extension - -2002-10-04 Arvind Samptur - - * src/window.c (meta_window_change_workspace): call - meta_window_unstick before adding window to workspace. - (menu_callback): call meta_workspace_activate before - meta_window_change_workspace. This would avoid us running an - extra loop for determining the window workspace list. - - Patches from Jeyasudha and Arvind. Fixes #92575 - -2002-10-03 Havoc Pennington - - * src/themes/Esco/metacity-theme-1.xml: only specify the - middle backgrounds, let left/right fall back to middle - - * src/theme.c (get_button): fall back to middle_background draw - routines when missing the left/right button backgrounds. - (button_rect): fix to handle drawing middle button backgrounds - (meta_frame_style_draw): draw middle background once per middle - button - -2002-10-03 Havoc Pennington - - Button-reordering patch. Has all the code except actually - installing a gconf schema and reading the gconf key in prefs.c. - metacity-theme-viewer displays the button layouts for testing - themes. - - * src/preview-widget.c (meta_preview_size_request): make up a - width/height if no child widget - - * src/prefs.c (meta_prefs_get_button_layout): new function - - * src/frames.c: get the button layout from prefs and - use it when drawing - - * src/theme.c (meta_frame_layout_calc_geometry): enhance to be - able to lay out buttons in different arrangements - (button_rect): draw the new button background rectangles - (meta_theme_draw_frame): require a button layout argument - (meta_theme_calc_geometry): pass in the button layout - - * src/preview-widget.h: mod to handle button layouts - - * src/theme-viewer.c: mod to handle button layouts - -2002-10-03 Havoc Pennington - - * configure.in: 2.4.2 - -2002-10-03 Havoc Pennington - - * src/window.c (check_moveresize_frequency): handle the case where - the clock is set backward - -2002-10-01 Havoc Pennington - - * src/place.c (find_next_cascade): try extra cascades alongside - the first, if the first fails; patch from readams@hmc.edu - -2002-10-01 Havoc Pennington - - * src/stack.c (get_standalone_layer): put ABOVE windows in same - layer as docks. - -2002-10-01 Havoc Pennington - - * src/screen.c (meta_screen_resize_func): make it static - - * src/stack.c (get_standalone_layer): put above/below windows - in an appropriate layer. - - * src/screen.c (set_supported_hint): say we support above/below - - * src/display.h (struct _MetaDisplay): add _NET_WM_STATE_ABOVE, - _NET_WM_STATE_BELOW atoms - - * src/window.c (meta_window_client_message): handle above/below - state messages - (set_net_wm_state): handler above/below state - (update_net_wm_state): handle above/below states - -2002-10-01 Mark McLoughlin - - * src/screen.c: (meta_screen_new): default to - topleft starting corner. - (meta_screen_update_workspace_layout): handle - new property format : orient,x,y,starting corner. - Fixes #89373. - - * src/screen.h: add MetaScreenCorner enum. - -2002-10-01 Havoc Pennington - - * src/window.c (constrain_position): always align fullscreen - windows to top, as we do with maximized windows. - -2002-10-01 Stanislav Brabec - - * configure.in: Added cs to ALL_LINGUAS. - -2002-09-30 Havoc Pennington - - * src/screen.c (reload_xinerama_infos): fix compilation on - Solaris, patch from Satyajit Kanungo - -2002-09-29 Havoc Pennington - - * src/eggaccelerators.c: update from libegg to get fix from Ralph - Loader for parsing, #93005 - -2002-09-29 Havoc Pennington - - * src/effects.h (META_MINIMIZE_ANIMATION_LENGTH): shorten minimize - animation a bit - -2002-09-28 Havoc Pennington - - Patch from Keith Packard to handle root window resizes. - - * src/screen.c (reload_xinerama_infos): factor out Xinerama code - (meta_screen_resize): implement this, to be called from display.c - on screen resize - - * src/display.c (event_callback): handle ConfigureNotify on root - windows - -2002-09-28 Havoc Pennington - - * src/stack.c (get_standalone_layer): re-enable the FOCUSED_WINDOW - layer, should now work correctly. - -2002-09-28 Havoc Pennington - - * src/window.c, src/stack.c: Rewrite stack code to work a lot - differently. Should be better now, and not lose relative positions - of windows when moving among layers. Also should now be possible - to get session management to restore the stacking order. Probably - breaks some stuff, and makes all the stack.c changes I made - yesterday sort of irrelevant. - -2002-09-27 Havoc Pennington - - * src/stack.c (get_standalone_layer): Temporarily disable use of - the FOCUSED_WINDOW layer, because given the fact that moving - multiple windows into the same layer changes the Z-order of those - windows, it was breaking click-to-focus. - -2002-09-27 Havoc Pennington - - * src/screen.c (meta_screen_focus_top_window): raise the focused - window, since it may not be the window on top, given the below - change. - - * src/stack.c (meta_stack_get_default_focus_window): make this - more complex to prefer to focus the transient parent, followed by - other windows in group, followed by topmost non-dock, followed by - dock. Previously was just topmost non-dock followed by dock - ignoring groups and transiency. - -2002-09-27 Havoc Pennington - - * src/place.c (constrain_placement): constrain placement to try to - keep windows from going offscreen to the right/bottom - - * src/stack.c (compute_layer): rearrange the logic here to say - that a window must always be in at least as high a layer as any of - its transient parents or group members, rather than special-casing - fullscreen. Also, group_member_is_fullscreen was leaking the list - of group members every time, a fairly major memory leak. - -2002-09-27 Havoc Pennington - - * src/themes/Makefile.am (THEMES): use AgingGorilla not Gorilla - (renamed on the CVS server) - -2002-09-27 Havoc Pennington - - Try to handle Solaris Xinerama, all coded blind, someone - on Solaris will need to debug the typos. - - * src/display.c: updates for Solaris Xinerama - - * src/screen.c: updates for Solaris Xinerama - - * configure.in: make Xinerama check more complicated to catch - Solaris Xinerama - -2002-09-27 Havoc Pennington - - * src/window.c (update_transient_for): keep a flag - transient_parent_is_root_window for whether the - root-window-as-parent convention was used. - -2002-09-25 Arvind Samptur - - * src/stack.c (sort_window_list): Keep dialogs without - transient parent above entire app. Fixes #88926 - -2002-09-26 Havoc Pennington - - * src/menu.c (meta_window_menu_new): use MetaAccelLabel to display - accelerators for the menu items - - * src/metaaccellabel.c: cut-and-paste GtkAccelLabel and port to - use virtual modifiers - - * src/Makefile.am (metacity_SOURCES): add metaaccellabel.[hc] - - * src/prefs.c (meta_prefs_get_window_binding): new function - - * src/core.c (meta_core_get_menu_accelerator): new function - -2002-09-25 Havoc Pennington - - * src/metacity.schemas.in: Change short desc of switch_windows and - cycle_windows to be different - -2002-09-24 Havoc Pennington - - * src/place.c (fit_rect_in_xinerama): update best_overlap as we go - through the loop - doh. Fix from readams@hmc.edu for #90799. - (find_first_fit): try the origin of each xinerama screen - after the first. Also from readams@hmc.edu - -2002-09-24 Havoc Pennington - - * src/window.c (meta_window_save_rect): new function, - only saves rect after checking current state, #93795 - (meta_window_make_fullscreen): use new function - (meta_window_maximize): use new function - -2002-09-24 Havoc Pennington - - * src/window.c (meta_window_update_layer): new function - - * src/stack.c (compute_layer): put focused window in a layer above - all other windows, in click-to-focus mode. #93022 - - * src/window.c (meta_window_notify_focus): update window layer on - focus change. - -2002-09-24 Havoc Pennington - - * src/main.c (main): support --version, #92796 patch from - Christian Neumair - - * autogen.sh: change gettext test to be happy with - glib-gettextize, #81425 - - * src/menu.c: change mnemonics to match bug #78999 - - * src/theme.c (meta_theme_validate): consolidate some - nearly-identical themes for ease of translation, #70962 - -2002-09-24 Arvind Samptur - - * src/menu.c: Replace strings Shade with Roll Up and - Unshade with Unroll. - -2002-09-23 Havoc Pennington - - * src/main.c (main): re-enable the log handler, maybe it will - break something, I don't remember why I turned it off. - - * src/display.c: s/_NET_SHOW_DESKTOP/_NET_SHOWING_DESKTOP/ which - is what's in the spec - -2002-09-22 Havoc Pennington - - * src/window.c (recalc_window_features): small reordering of - code - - * src/display.c (meta_spew_event): more spew for MapNotify, - UnmapNotify - - * src/window.c (recalc_window_features): spew more stuff - - * src/display.c (meta_spew_event): spew override_redirect field of - ConfigureNotify - -2002-09-20 Arvind Samptur - * src/metacity.schemas.in: added keybindings for - moving windows between workspaces. - - Patch from Jeyasudha. Fixes #91944. - -2002-09-19 Arvind Samptur - * src/tools/metacity-properties.desktop.in : - change in the tooltip suggested in ui-review. - -2002-09-18 Havoc Pennington - - * src/window.c (update_net_wm_state): handle fullscreen state - here. - -2002-09-15 Havoc Pennington - - * src/session.c (save_state): escape the window title before - saving in the session file, reported by Jos Vos - -2002-09-12 Havoc Pennington - - * src/workspace.c (meta_workspace_screen_index) - (meta_workspace_index): fix compiler warnings - - * src/tools/metacity-window-demo.c (menu_items): add a test for - dialogs with no transient parent - - * src/place.c (find_first_fit): Try placing window at origin of - first Xinerama, even if there are no windows to place next to; - makes placement work when no other windows are open on the screen. - -2002-09-09 Havoc Pennington - - * configure.in: 2.4.1 - -2002-09-09 Christian Neumair - - * src/keybindings.c: Make virtual desktops apply - instantly and still show the pager popup by - Benjamin Kahn , fixes #86590. - -2002-09-06 Frederic Crozat - - * src/themes/Crux/metacity-theme-1.xml: Fix titlebar - glitch on small dialogs. - -2002-09-06 Arvind Samptur - * theme-format.txt : corrected some of the attributes - which were not in sync with theme-parser.c - Patch from Jim Bowen. #92057. - -2002-09-05 Havoc Pennington - - * configure.in: put ro back in ALL_LINGUAS - -2002-09-05 Havoc Pennington - - * configure.in (ALL_LINGUAS): remove 'ro' from ALL_LINGUAS, it - contained invalid XML and broke the build. No <> in the - translations of gconf keys! - -2002-09-04 Marius Andreiana - - * configure.in: added 'ro' to ALL_LINGUAS - -2002-09-03 Havoc Pennington - - * src/display.c (meta_display_get_tab_current): new function - - * src/keybindings.c (do_choose_window): apply modified patch from - JeyaSudha to still display tab popup if only one window is on the - desktop. - -2002-06-25 JeyaSudha - - * src/session.c, src/window.c: Session saves the unmaximized - postion, size of a maximized window. #86059 - -2002-09-03 Havoc Pennington - - * src/frames.c (meta_frames_update_prelit_control): don't filter - out prelight for unmaximize button. #83860 - (meta_frames_paint_to_drawable): handle unmaximize here as well - -2002-08-27 Havoc Pennington - - * src/theme.c (meta_frame_layout_calc_geometry): always apply - rounding for shaded windows, fixes Bluecurve theme when shaded - -2002-08-25 Havoc Pennington - - * src/window.c (meta_window_free): when freeing a fullscreen - window, update layers of the window's group. - -2002-08-25 Havoc Pennington - - * src/display.c (meta_display_open): _NET_SUPPORTING_WM_CHECK is - supposed to have type WINDOW not CARDINAL. reported by - Ben Jansens - -2002-08-24 Havoc Pennington - - * src/window.c (process_property_notify): recalculate mapped-ness - of frame after toggling decorations on/off, so that windows don't - disappear when decorations are toggled on. - - * src/tools/metacity-window-demo.c (toggle_decorated_cb): add a - test for toggling decoration state on the fly - -2002-08-24 Havoc Pennington - - * src/window.c (update_sm_hints): hack around bug in kmail etc. - where SM_CLIENT_ID was set on the window, not the client leader. - - * src/theme.c (meta_frame_layout_calc_geometry): don't round - corners unless we have enough frame to chop off. - -2002-08-24 Havoc Pennington - - * src/util.c: translate some strings that should have been, and - convert to locale encoding before printing stuff. - - * src/stack.c (group_member_is_fullscreen): if window itself is - fullscreen, return TRUE immediately. - - * src/window.c (meta_window_configure_request): add hack to - fullscreenize large undecorated windows. - -2002-08-21 Deepa Natarajan - - * src/keybindings.c, src/metacity.schemas.in, src/prefs.[ch]: - add maximize and unmaximize keybinding setting. Partly fixes - bug# 78999. - -2002-08-20 Steve Fox - - * metacity.spec.in: Add so that the spec file gets auto-updated - whenever configure.in gets bumped. Include some missing - directories. - - * Makefile.am - * configure.in: Necessary changes for spec file magic - -2002-08-20 Havoc Pennington - - * src/frames.c (get_control): if in the title rect check for y - <= TOP_RESIZE_HEIGHT - - * src/display.c (meta_spew_event): put x/y coordinates in spew for - enter/leave notify - - * src/frames.c (meta_frames_motion_notify_event): move cursor - changing from here to update_prelit_control so it happens on enter - notify as well - (get_control): change test "y < TOP_RESIZE_HEIGHT" to - "y <= TOP_RESIZE_HEIGHT" - - * src/Makefile.am (EXTRA_DIST): include .in files in EXTRA_DIST - -2002-08-17 Simos Xenitellis - - * configure.in (ALL_LINGUAS): Added Greek (el). - -2002-08-17 Evandro Fernandes Giovanini - - * configure.in (ALL_LINGUAS): Added Brazilian Portuguese (pt_BR). - -2002-08-15 Havoc Pennington - - * src/metacity.schemas.in: default to "Sans Bold 10" for the - titlebar font. - -2002-08-15 Havoc Pennington - - * src/window.c (recalc_window_features): leave has_fullscreen_func - set to TRUE if the window is screen sized and undecorated, even if - the window isn't resizable. idea from Christian - Manny Calavera - - Neumair - - * src/keybindings.c (handle_toggle_fullscreen) - (handle_toggle_maximize): these disabled fullscreen/maximize if - the window wasn't resizable, should have used has_fullscreen_func - has_maximize_func instead. - -2002-08-15 Havoc Pennington - - * src/keybindings.c: implement raise/lower - - * src/metacity.schemas.in: add raise/lower - - * src/prefs.c: add "raise" and "lower" prefs to keybindings - - * src/display.c (meta_display_set_grab_op_cursor): assert that - the screen arg is non-NULL in appropriate cases - -2002-08-14 Jayaraj Rajappan - - * src/display.c (meta_display_set_grab_op_cursor): - In XGrabPointer, set the confine_to argument to the root window - of the screen the window is on. - - * src/display.h: add screen argument. - - * src/window.c (meta_window_update_resize_grab_op): - pass screen argument as NULL. - -2002-08-14 James M. Cape - - * src/themes/Esco/metacity-theme-1.xml: use button positioning - theme stuff. - -2002-08-14 Mark McLoughlin - - * src/screen.c: (set_number_of_spaces_hint), move from - workspace.c. - (update_num_workspaces): set the hint here. Fixes #90123. - - * src/workspace.c: - (meta_workspace_new), (meta_workspace_free): don't set - the hint here. - (update_num_workspaces): move to screen.c - -2002-08-12 Havoc Pennington - - * src/stack.c (compute_layer): window is in fullscreen layer if - any member of its group is fullscreen - - * src/window.c (meta_window_unmake_fullscreen): update layer for - whole window group - (meta_window_make_fullscreen): ditto - - * src/util.c (meta_unsigned_long_hash): move hash/equal funcs for - Window in here. - - * src/group.c: track window groups so we can do stuff with them. - -2002-08-11 Havoc Pennington - - * src/menu.c: don't include nonexistent stock-icons.h file - -2002-08-10 Havoc Pennington - - * src/metacity.schemas.in: default keybindings for move, resize, - maximize, etc. from Deepa #78999 - -2002-08-10 Havoc Pennington - - * src/window.c (meta_window_maximize): unshade window if shaded, - from JeyaSudha - (meta_window_make_fullscreen): ditto - -2002-08-10 Havoc Pennington - - * src/menu.c: reorder the menu items so that Close is at the - bottom - - * src/theme-viewer.c (main): set debugging mode if METACITY_DEBUG - enabled - -2002-08-10 Havoc Pennington - - * src/xprops.c (meta_prop_get_motif_hints): allow Motif hints to - be smaller than expected; GLUT for example seems to set a smaller - struct. #89841 - - * src/window.c (update_mwm_hints): use g_free on motif hints as we - don't use the XGetWindowProperty return directly anymore - -2002-08-10 Havoc Pennington - - * src/window.c (meta_window_free): be sure window is - mapped if we unmanage it and it's not withdrawn; - bug #90369 - - * src/screen.c (meta_screen_new): change string - s/override/replace/ bug #89077 - - * src/theme.c (scale_and_alpha_pixbuf): dump the - sometimes-use-NEAREST-instead-of-BILINEAR optimization, - bug #87489 - -2002-08-10 Havoc Pennington - - * src/window.c (menu_callback): raise window when moving to - another workspace bug #88896 - - * src/keybindings.c (switch_to_workspace): raise window when - moving between spaces - -2002-08-10 Jorn Baayen - - Register window menu icons with the Gtk stock system, instead - of using the ones from the Metacity theme (which looked very bad with - some themes). - - * src/Makefile.am: - * src/main.c: - * src/menu.c: - * src/stock_delete.png: added these files - * src/stock_minimize.png: - * src/stock_maximize.png: - * src/ui.c - -2002-08-10 Havoc Pennington - - * src/keybindings.c (meta_display_process_key_event): filter out - key events that happen on popup menus etc. - - * src/ui.c (meta_ui_window_is_widget): new function to check - whether a window belongs to a GtkWidget such as the popup menu - - * src/prefs.c (change_notify): put in a no-op line for AIX - compiler, #84252 - -2002-08-10 Havoc Pennington - - * src/window.c (update_resize): track time to avoid sending a - deluge of move/resize requests, suggestion from - xavier.bestel@free.fr bug #86830. Not really sure if this will - make a difference or not. We'll see I guess. - (update_move): do same on move though it seems less important - here. - - * src/display.h (struct _MetaDisplay): store the - last time we sent a move/resize event. - -2002-08-10 Havoc Pennington - - * src/window.c (meta_window_notify_focus): add a FIXME comment - with a link to bug #90382 - -2002-08-09 Havoc Pennington - - * src/keybindings.c (handle_toggle_maximize): disable maximize, - fullscreen, shade via keybindings on windows that don't support - it. - -2002-08-08 Craig Black - - Patch to provide extra cues when using the window menu - move and resize items, #85724. - - * src/common.h: add new cursors - - * src/display.c: (grab_op_is_mouse) - (meta_display_create_x_cursor), (xcursor_for_op), - (meta_display_set_grab_op_cursor), - (meta_display_begin_grab_op): - The keyboard move and resize grab ops now also use the mouse. - Allow the grab cursor to be changed during the grab op. - Hold onto the initial grab position in case of reset. - - * src/display.h: save the initial grab position - - * src/keybindings.c: (process_keyboard_move_grab), - (process_keyboard_resize_grab), (handle_begin_move), - (handle_begin_resize): - The keyboard move and resize grab ops now also use the mouse. - - * src/window.c: (meta_window_client_message), (menu_callback), - (update_move), (update_resize), - (meta_window_handle_mouse_grab_op_event), (warp_pointer), - (meta_window_warp_pointer), (meta_window_begin_grab_op), - (meta_window_update_resize_grab_op): - When moving or resizing a window use the last grab position - in computing change increment. - Provide support for warping the mouse pointer. - - * src/window.h: new warp pointer and grab op helper functions - -2002-08-08 Craig Black - - * src/display.h: update comment - * src/window.c: (meta_window_focus): also set expected - focus window when setting input focus. - -2002-08-07 Craig Black - - * src/display.c: (meta_display_unshow_desktop): focus - top window after showing desktop, fixes #88080. - -2002-08-07 Craig Black - - * src/core.c: (meta_core_show_window_menu): focus window - on right click for menu, #87299. - -2002-08-07 Craig Black - - * src/display.c: (meta_display_open): clear expected focus window - on open - - * src/display.h: add expected_focus_window field - - * src/window.c: (meta_window_make_fullscreen), - (meta_window_unmake_fullscreen): change meta_window_update_layer() - to meta_stack_update_layer() so build works again. - (meta_window_free), (meta_window_make_fullscreen), - (meta_window_focus), (meta_window_notify_focus): keep track of - expected focus window after sending WM_TAKE_FOCUS event, - previously if a UnmapNotify event arrived before the FocusIn event - we would lose focus, fixes #84564. - -2002-08-07 Havoc Pennington - - * src/window.c (meta_window_unmake_fullscreen): update layer - (meta_window_make_fullscreen): update layer - - * src/stack.c (compute_layer): put window on fullscreen layer if - fullscreen - -2002-08-06 Craig Black - - * src/window.c: (meta_window_client_message): implement - _NET_WM_MOVERESIZE enhancements, see #90077. - -2002-08-06 Havoc Pennington - - * configure.in: 2.4.0 (this version number has no special - significance, just didn't want to go to 4-digit micro version ;-) - -2002-07-28 Havoc Pennington - - * src/window.c (meta_window_shade): disable animation when shading - windows, just doesn't really convey the idea anyway. - - * src/effects.c: Move to using a shaped window instead of - IncludeInferiors to do the animations, looks a lot better - because we don't have to grab the server. - - * src/window.c (meta_window_change_workspace): remove bogus - assertion that was causing a crash - (meta_window_new): auto-fullscreen huge undecorated windows. - - * src/keybindings.c (switch_to_workspace): use - meta_window_change_workspace() to avoid same bug in cut-and-paste - code from there - -2002-08-06 He Qiangqiang - - * configure.in: Added "zh_CN" to ALL_LINGUAS. - -2002-08-05 Ross Burton - - * src/window.c: (meta_window_client_message): Set - ->wm_state_skip_pager (ditto for _taskbar) instead of ->skip_pager - so that these hints actually work. Fixes #89850. - -2002-08-04 Havoc Pennington - - * src/frames.c (meta_frames_paint_to_drawable): init button - states for the button backgrounds - - * src/themes/Atlanta/metacity-theme-1.xml: adapt to work correctly - with button repositioning - -2002-08-04 Havoc Pennington - - * src/frames.c (meta_frames_button_press_event): raise/focus - on click, even if the click was on the client area - (this makes Alt+button1 raise windows again, yay) - - * src/stack.c (compute_layer): put panels in the DOCK layer always - (keep them on top of other windows). Still sloppy-focus raised - with respect to other docks. - - * configure.in: remove -Wshadow for now as GTK headers make all - kinds of noise with it. - -2002-08-02 Mark McLoughlin - - * src/screen.c: (meta_screen_new): set active_workspace - to NULL. Also actually activate the first workspace instead - of just setting active_workspace. Fixes #87367. - (meta_screen_ensure_workspace_popup): don't re-use our - iterator for setting the entries list, stop iterating - when we've gone beyond the last workspace (there may - be empty spaces in the last row). - - * src/workspace.c: (meta_workspace_activate): if no workspace - was previously activated, return. - -2002-08-04 Havoc Pennington - - * src/theme.c (free_menu_ops): use MetaMenuIconType not button - type for the size of the menu ops array - (meta_theme_define_int_constant): return TRUE on success (how the - heck did this ever work?) - (meta_theme_define_float_constant): return TRUE on success - (meta_frame_style_validate): allow the "positional" buttons to - be omitted for now. - - * src/testgradient.c (render_multi): don't define N_COLORS twice - - * src/theme-viewer.c (run_theme_benchmark): don't define - ITERATIONS twice - - * src/theme.c (button_rect): handle new button types - (meta_button_type_to_string): update - (meta_button_type_from_string): update - - * src/theme.h (enum): add button types for the 6 possible button - positions. No way to reposition buttons still but this will allow - themes to go ahead and support doing so. - -2002-08-03 Craig Black - - * src/keybindings.c: (meta_display_process_key_event), - (process_tab_grab), (do_choose_window): change alt+tab to a - windowless grab, fixes #83499 - -2002-08-03 Craig Black - - * src/display.c: (event_callback): Have ButtonPress and - UnmapNotify events account for a null grab window, fixes #87896 - -2002-08-03 Gaute Lindkvist - - Corrected some issues with the Bright theme. Mainly - making sure the text does not clip, as well as increasing - the size of the menu icon. - -2002-08-01 Mark McLoughlin - - Implements support for _NET_WM_ALLOWED_ACTIONS. - Fixes #84282. - - * src/display.[ch]: (meta_display_open): add - _NET_WM_ALLOWED_ACTIONS atoms. - - * src/screen.c: (set_supported_hint): set them - as being supported. - - * src/window.c: - (set_allowed_actions_hint): impl setting - _NET_WM_ALLOWED_ACTIONS. - (recalc_window_features): use it here, but only - if things have changed. - -2002-08-01 Christophe Fergeau - - * src/metacity-dialog.c: focus the "Close" button by default on - the dialog which appears at exit when some apps can't be session - managed - -2002-08-01 Mark McLoughlin - - * src/session.c: - (save_yourself_possibly_done): send a SaveYourselfDone - if we're skipping this global save. - (save_yourself_callback): don't not save session state - if the save style is Global. Fixes #89390. - - * theme-format.txt: update. - -2002-07-30 Pablo Saratxaga - - * configure.in: Added Vietnamese (vi) to ALL_LINGUAS - -2002-07-24 Havoc Pennington - - * src/themes/Makefile.am (THEMES): add Metabox theme from Garrett - - * README: updates - -2002-07-21 Havoc Pennington - - * src/window.c (meta_window_new): don't automaximize fullscreen - windows. - -2002-07-14 Havoc Pennington - - * src/window.c (recalc_window_features): don't allow shading of - border-only windows. - -2002-07-24 Havoc Pennington - - * src/theme-parser.c (meta_theme_load): look for themes in - ~/.themes/NAME/metacity-1/ and datadir/themes/NAME/metacity-1 - instead of the old locations. - - * src/themes/Makefile.am: install themes to - datadir/themes/NAME/metacity-1/ to match how GTK works, breaking - third-party themes yet again! woot! - -2002-07-20 Havoc Pennington - - * src/display.c (meta_display_open): grab display across managing - each screen; XGetInputFocus() on startup. - -2002-07-19 Havoc Pennington - - * src/window.c (meta_window_configure_request): disable configure - requests during a user move/resize operation, mostly a workaround - for stoopid apps. - -2002-07-24 jacob berkman - - * configure.in: fix x11 header checks when x11 is not in the - default include path - -2002-07-23 Ross Burton - - * src/menu.c (meta_window_menu_new): Use the real workspace names - instead of making up numbers. - -2002-07-23 Havoc Pennington - - * src/themes/Makefile.am (THEMES): put Gorilla back in the build - - * src/themes/Gorilla/metacity-theme-1.xml, - src/themes/Crux/metacity-theme-1.xml: fixes from - Sebastien Delestaing so that these themes work properly with - different font sizes. - - * src/frames.c (get_control): patch from Balamurali Viswanathan - for #81984 (resize titlebar from the top not the bottom) - -2002-07-23 Havoc Pennington - - * src/keybindings.c (meta_display_process_key_event): handle - NULL screen from screen_for_xwindow - - * src/display.c (meta_display_screen_for_xwindow): put an error - trap around the XGetWindowAttributes(), should fix the popular - "closing a window results in a crash" bug. - - * src/util.c (print_backtrace): support optional backtrace - feature using gnu libc backtrace() call - -2002-07-15 jacob berkman - - * src/update-from-egg.sh: steal from profterm to fix build - -2002-07-13 Havoc Pennington - - * src/workspace.c (meta_workspace_new): don't put a newline after - the default workspace name - -2002-07-13 Havoc Pennington - - * src/keybindings.c: adapt to virtual modifiers - (meta_display_process_mapping_event): we need to reload the - binding tables now when the modmap changes. - - * src/prefs.c (update_binding): parse virtual modifiers, not - plain modmask - - * src/common.h (MetaVirtualModifer): new enum - - * src/ui.c (meta_ui_parse_accelerator): use - egg_accelerator_parse_virtual() - - * src/Makefile.am: add eggaccelerators.[hc] for the virtual - accelerator parsing function - -2002-07-13 Christophe Fergeau - - * configure.in: added fr to ALL_LINGUAS - -2002-07-12 Havoc Pennington - - * src/session.c (warn_about_lame_clients_and_finish_interact): - don't display the dialog if all the apps were session managed. - -2002-07-12 Havoc Pennington - - * src/session.c: don't send SmInteractDone until the warning - dialog about crappy clients has been closed. - -2002-07-12 Havoc Pennington - - * src/window.c (meta_window_new): try to maximize windows that - are too big for the work area - - * src/place.c (find_next_cascade): don't let the cascade algorithm - place windows off the screen, and fix it to always exhaustively - search the window list for cascade parents. - -2002-07-11 Havoc Pennington - - * src/metacity-dialog.c (main): option to display error when a - command fails to run. - - * src/keybindings.c (handle_run_command): run commands - in response to keybindings. - - * src/prefs.c: add command keybinding stuff - - * src/metacity.schemas.in: add keybindings for running commands, - and keys to store the commands themselves. - -2002-07-10 Havoc Pennington - - * src/display.c: properly attribute selection code to Matthias - Clasen - -2002-07-10 Havoc Pennington - - * README: couple of updates - - * src/main.c (usage): add --replace to usage, reported by Matthias - Clasen - -2002-07-09 Havoc Pennington - - * src/metacity.schemas.in: fix short description for - begin_resize, patch from Jayaraj, #87654 - - * src/keybindings.c (handle_begin_resize): apply patch from - Jayaraj to actually handle the begin resize keybinding. - -2002-07-09 Havoc Pennington - - * src/window.c (constrain_position): don't center vertically for - maximized windows that don't fill the screen, just leave them at - the top. - -2002-07-06 Havoc Pennington - - * src/tabpopup.c (selectable_workspace_new): increase the size of - the mini workspaces - -2002-07-06 Havoc Pennington - - Apply blackc@speakeasy.net patch, bug #83940, to do - mini-workspaces similar to the pager, when switching - spaces. - - * src/window.c (update_net_wm_state): actually fill in - wm_state_skip_taskbar, wm_state_skip_pager flags - - * src/tabpopup.c: support drawing a mini-workspace similar to the - one the pager draws. - - * src/stack.c (meta_stack_list_windows): new function to list - the windows in stacking order - - * src/screen.c (meta_screen_ensure_workspace_popup): don't pass in - the ugly default app icon for workspaces - - * src/display.c (event_callback): fix from blackc@speakeasy.net - to avoid dereferencing a NULL grab window. - -2002-07-06 Havoc Pennington - - * src/display.c (meta_display_open): put _NET_DESKTOP_NAMES in the - array of atom names, so desktop names might work and we don't read - uninitialized memory. - - * src/main.c (main): add VERSION/timestamp verbose message. - - * src/keybindings.c: implement cycle_windows cycle_panels - - * src/metacity.schemas.in: add the cycle_windows cycle_panels - keybindings - - * src/prefs.h (META_KEYBINDING_FOCUS_PREVIOUS): replace - FOCUS_PREVIOUS key binding with CYCLE_WINDOWS and CYCLE_PANELS - (not good names really, but I don't have ideas). - - * src/common.h: add a grab op for alt+esc window cycling - -2002-07-05 Havoc Pennington - - * src/themes/Makefile.am (THEMES): Take Gorilla out until it gets - repaired. - -2002-07-05 Havoc Pennington - - * src/window.c (update_wm_hints): Change default value of input - hint (if not specified) to true instead of false. This is what - some clients assume, such as Visual SlickEdit. - -2002-07-02 Havoc Pennington - - * src/window.c (meta_window_show_menu): use new macros to get - whether we allow move/resize correct - - * src/frame.c (meta_frame_get_flags): use new macros to get - whether we can move/resize correct, considering - maximized/fullscreen for the move case. - - * src/window.h (META_WINDOW_ALLOWS_RESIZE, - META_WINDOW_ALLOWS_MOVE): new macros - - * src/keybindings.c (process_keyboard_resize_grab): finish the - right/left resize, patch from Jayaraj #78179. - - Has the same old move/resize bug, if it hits a constraint it - starts to break because we move without resizing. - -2002-07-02 Mark McLoughlin - - * src/keybindings.c: - (grab_keyboard), (ungrab_keyboard): rename from - {un}grab_all_keys_and_keyboard and only do an XKeyboardGrab, - the XKeyGrab isn't neccessary. - (meta_screen_grab_all_keys), (meta_screen_ungrab_all_keys), - (meta_window_grab_all_keys), (meta_window_ungrab_all_keys): - update for above change. - (handle_workspace_switch): don't use a MetaWindow when - workspace switching, use the root window instead. - -2002-07-01 Mark McLoughlin - - Fix broken workspace switching from my previous commit. - - * src/display.c: (meta_display_begin_grab_op): don't - leak a pointer grab if we fail to grab the keyboard. - - * src/keybindings.c: (meta_screen_grab_keys): check - screen->all_keys_grabbed. - (meta_screen_grab_all_keys): regrab our standard - bindings if we fail. - (handle_workspace_switch): revert to our previous - behaviour of using the last focused window to do - the grab upon. Only use the RootWindow if there - isn't anything else to use. - - * src/screen.c: (meta_screen_new): initialise - all_keys_grabbed. - -2002-06-26 Mark McLoughlin - - Fixes not being able to tab out of a - workspace which contains no windows. - - * src/core.c: (meta_core_begin_grab_op): upd - for meta_display_begin_grab_op change. - (meta_core_get_grab_frame): allow for - grab_window == NULL. - - * src/display.[ch]: - (meta_display_screen_for_xwindow): implement. - (meta_display_begin_grab_op): grab on the root window - if window == NULL. - (meta_display_end_grab_op): use grab_screen instead of - grab_window. - - * src/keybindings.c: - (grab_all_keys_and_keyboard): split out from - meta_window_grab_all_keys. - (ungrab_all_keys_and_keyboard): split out from - meta_window_ungrab_all_keys. - (meta_screen_grab_all_keys), (meta_screen_ungrab_all_keys): - implement grabbing and ungrabbing on the root window. - (meta_display_process_key_event): if window == NULL, - check the event is from the same screen and process. Only - happens with workspace switching. - (process_workspace_switch_grab): kill window param and - don't use grab_window. - (handle_tab_forward), (handle_begin_move): upd for - meta_display_begin_grab_op change. - (handle_workspace_switch): remove brokeness. Always do - the grab op on the root window. - - * src/keybindings.h: add meta_screen_{un}grab_all_keys. - - * src/window.c: (meta_window_client_message), (menu_callback): - update for meta_display_begin_grab_op change. - -2002-06-25 Mark McLoughlin - - * src/fixedtip.c: (meta_fixed_tip_show): - * src/frames.c: (meta_frames_new): - * src/tabpopup.c: (meta_ui_tab_popup_new): - s/gdk_get_default_display/gdk_display_get_default/ - s/gdk_get_default_screen/gdk_screen_get_default/ - -2002-06-25 Mark McLoughlin - - * src/themes/Crux/active-border-top-left-border.png: - * src/themes/Crux/active-border-top-right-border.png: - * src/themes/Crux/active-top-left-corner.png: - * src/themes/Crux/active-top-mid-left-border.png: - * src/themes/Crux/active-top-mid-right-border.png: - * src/themes/Crux/active-top-right-corner.png: - * src/themes/Crux/inactive-border-top-left-border.png: - * src/themes/Crux/inactive-border-top-right-border.png: - * src/themes/Crux/inactive-top-left-corner.png: - * src/themes/Crux/inactive-top-mid-border.png: - * src/themes/Crux/inactive-top-right-corner.png: - * src/themes/Crux/metacity-theme-1.xml: added support - for border only windows. - -2002-06-24 James M. Cape - - * src/themes/Esco/metacity-theme-1.xml: Added some stuff to - the window buttons, so they use the ACTIVE bg/fg. - -2002-06-25 Mark McLoughlin - - * src/display.[ch]: (meta_display_open): - src/screen.c: (set_supported_hint), (set_work_area_hint): - Its _NET_WORKAREA, not _NET_WM_WORKAREA silly :-) - -2002-06-25 Mark McLoughlin - - * src/screen.[ch]: - (update_num_workspaces), recalc workarea hint when - new workspaces created. Fixes bug that workarea - not calculated until first non-dock window is - mapped. - (set_work_area_hint), (set_work_area_idle_func), - (meta_screen_queue_workarea_recalc): move all this - stuff from workspace.c. - - * src/workspace.c: (meta_workspace_invalidate_work_area): - use meta_screen_queue_workarea_recalc. - -2002-06-23 Gediminas Paulauskas - - * src/themes/Bright/metacity-theme-1.xml: Update with border-only - window stuff from Atlanta. - -2002-06-22 James M. Cape - - * src/themes/Esco/metacity-theme-1.xml: Update for "border" - frame stuff, minor button/spacing improvements. - -2002-06-22 Havoc Pennington - - Partially fix Jacob's SM bugs. - - * src/window.c (meta_window_apply_session_info): restore the extra - stuff we're saving, except stack position I didn't figure out yet. - - * src/session.c: save stack position, minimized, maximized, - in the session file. - -2002-06-22 Havoc Pennington - - * src/workspace.c (set_number_of_spaces_hint): do nothing if - screen is being unmanaged, we don't want to blow away state, - we want to remember it for the next window manager. - -2002-06-22 Havoc Pennington - - * src/workspace.c (meta_screen_ensure_workspace_popup): rename - from meta_workspace_ensure_tab_popup, and use workspace->name - instead of a hardcoded name - -2002-06-22 Havoc Pennington - - * src/xprops.c (meta_prop_get_utf8_list): new utility function - - * src/display.c (meta_display_open): _NET_DESKTOP_NAMES atom - (event_callback): update workspace names when the property changes - - * src/screen.c (set_supported_hint): "support" _NET_DESKTOP_NAMES - (nothing to do really) - -2002-06-21 Havoc Pennington - - Theme breakage! Themes have to implement "border" frames - now, see Atlanta for an example. Fixes #84285 - - * src/tools/metacity-window-demo.c (do_appwindow): add a - border-only window - - * src/window.c (update_mwm_hints): read border only from the MWM - hints - - * src/window.h (struct _MetaWindow): add border_only flag - - * src/core.c (meta_core_get_frame_type): report border type if - required - - * src/common.h (enum): add META_FRAME_TYPE_BORDER - -2002-06-20 Mark McLoughlin - - * src/window.c: (meta_window_visible_on_workspace): sticky - windows aren't visibile on all screens. Check the workspace - is on the same screen as the window. - - * src/workspace.c: (meta_workspace_list_windows): use - meta_window_visible_on_workspace here. - -2002-06-19 Havoc Pennington - - * src/display.c (meta_resize_gravity_from_grab_op): handle UNKNOWN - keyboard resizing state - - * src/keybindings.c (process_keyboard_resize_grab): implement - keyboard resize key handling somewhat (only vertical resize works, - left/right arrow not implemented, and visual feedback of the - edge we're resizing isn't implemented) - - * src/window.c (menu_callback): start keyboard resize grab when - it's chosen from the menu - -2002-06-17 Havoc Pennington - - * src/stack.c (meta_stack_get_default_focus_window): don't use a - minimized window as the next focus window, patch from - blackc@speakeasy.net - -2002-06-17 Havoc Pennington - - * src/place.c (find_next_cascade): increase the cascade threshold - a bit. - (find_first_fit): implement a somewhat lame first fit algorithm - -2002-06-17 Havoc Pennington - - * src/window.c (meta_window_change_workspace): fix from Gaute - Lindkvist #82977 for unsticking windows - -2002-06-17 Frederic Crozat - - * src/metacity.schemas.in: associate close_window keybinding to - Alt-F4 - -2002-06-16 Havoc Pennington - - * src/main.c (main): fix spelling error, #85452 - -2002-06-15 Havoc Pennington - - * src/keybindings.c (meta_display_process_key_event): don't pass a - null string to printf - - * src/display.c (key_event_description): don't pass a null string - to printf - - * src/keybindings.c (meta_set_keybindings_disabled): allow - enable/disable keybindings regardless of debug mode. - -2002-06-15 Havoc Pennington - - * src/draw-workspace.h, src/draw-workspace.c: workspace-drawing - code factored out of libwnck, needs wiring up to tabpopup.c - (which is kind of annoying since you have to get the list of - workspaces and MetaWindow across the barrier between the GDK-aware - and non-GDK-aware sides of metacity) - -2002-06-14 Havoc Pennington - - * src/window.c (meta_window_show): always focus new windows, - trying to be smart about it was a flop. - -2002-06-14 Jayaraj Rajappan - - * src/delete.c (io_from_ping_dialog): Check for NULL string - before calling strlen(). Fixes the core dump issue reported in #84873. - -2002-06-13 Anders Carlsson - - * src/theme.c (meta_frame_layout_calc_geometry): Set client height - as 0 when the window actually is shaded, not the other way around. - -2002-06-12 Havoc Pennington - - * src/theme.c (meta_frame_layout_calc_geometry): when a window is - shaded, don't include client height in the height calculation. - - * src/workspace.c (meta_workspace_get_neighbor): apply fix from - Mads Villadsen for the Up arrow key, #84582 - -2002-06-12 Havoc Pennington - - * src/theme.c (meta_frame_style_draw): Draw the buttons right - before the "overlay" piece. - -2002-06-12 Jayaraj Rajappan - - * src/tools/metacity-properties.glade: accessibility work for - metacity-properties capplet. Set appropriate atk relations. - Fixes bug #84749 - -2002-06-11 Havoc Pennington - - * src/window.c (meta_window_show): allow dialogs to steal focus - from panels/desktop - -2002-06-10 Jayaraj Rajappan - - * src/fixedtip.c: include - fix for #83960 - -2002-06-10 Erwann Chenede - - - * src/keybindings.c : (handle_close_window, handle_minimize_window) - verify the active window has the appropriate close/minimize function - before closing or minimizing the window. - -2002-06-09 Havoc Pennington - - * configure.in: 2.3.987 - -2002-06-09 Havoc Pennington - - * src/delete.c (delete_ping_timeout_func): add G_IO_NVAL to watch - condition, patch from Gustavo Giraldez, avoids another 100% CPU - thingy - -2002-06-09 Havoc Pennington - - * src/place.c (meta_window_place): don't run constrain_placement - on windows we allow to go anywhere (docks, etc.). Fixes - positioning of panel windows in certain cases. - -2002-06-09 Havoc Pennington - - * src/frames.c (meta_frames_button_press_event): don't raise/focus - the window if minimize/close are clicked, patch from Gaute - Lindkvist #75460 - -2002-06-08 Havoc Pennington - - Cleanups to workspace popup patch. Space before all parens - in a couple places. - - * src/prefs.c (meta_prefs_get_keybinding_action): fix brace - indentation, and use while instead of for loop. Take a "mask" - argument to avoid ambiguity issues. - - * src/keybindings.c (handle_workspace_switch): rename from - handle_workspace_forward since there's no directionality here - (handle_workspace_switch): add a FIXME about how screwed it is - that we need a window in order to do our grab. Should be able to - grab on a dummy window like no_focus_window or the root window. - (process_workspace_switch_grab): rename from tab_grab for clarity, - no tab involved here. - - * src/common.h (enum): have only one grab op for all workspace - switching directions, instead of one for each. - -2002-06-08 Havoc Pennington - - Apply big patch from blackc@speakeasy.net adding a popup window - to the Ctrl+Alt+arrows shortcuts. #83940 - -2002-06-08 Havoc Pennington - - * src/screen.c (meta_screen_new): select key press/release on the - display->no_focus_window, another attempted fix for not getting - keybindings when no window is focused. Still doesn't seem to work - though. I don't get what's going wrong. - (meta_create_offscreen_window): new function, used instead of - XCreateSimpleWindow so we get override redirect offscreen windows. - -2002-06-08 Havoc Pennington - - * src/display.c (meta_display_open): set net_supporting_wm_check - in addition to win_supporting_wm_check, patch from - JeyaSudha for #83365 - - * src/screen.c (set_wm_check_hint): remove setting - win_supporting_wm_check on leader window here, done already in - display.c - -2002-06-08 Havoc Pennington - - * src/keybindings.c (meta_window_ungrab_keys): set keys_grabbed to - FALSE, patch from Jayaraj for #81857 - -2002-06-08 Havoc Pennington - - * src/xprops.c (meta_prop_get_utf8_string): don't die on bad atom - name - - * src/display.c (meta_display_close): don't unmanage windows here, - do it in screen_free and then closing the display unmanages - windows as a side effect of unmanaging the screen - (meta_display_unmanage_screen): new function - (process_selection_clear, process_selection_request): handle - selection stuff - (meta_spew_event): don't crash on client message containing - invalid atom - (meta_spew_event): don't crash on property notify with invalid - atom - - * src/main.c (main): add --replace option to replace existing - window manager. - - * src/screen.c: implement holding manager selection. - - * src/display.c (meta_display_open): add new selection-related - atoms. - -2002-06-08 Havoc Pennington - - * src/screen.c (meta_screen_new): select keypress/keyrelease - events on root window, this may fix the bug where keybindings - didn't work if you didn't have a focused window. - -2002-06-08 Havoc Pennington - - * src/main.c (main): call meta_session_shutdown when exiting - cleanly - - * src/session.c (meta_session_shutdown): function to change use to - RestartIfRunning - (meta_session_init): change normal restart hint to - RestartImmediately - -2002-06-08 Havoc Pennington - - Yeah I know maximization is broken, I'm too tired to fix it. - Probably because of the change to update_struts() that was - supposed to fix the 100% CPU bug. - - * src/place.c (meta_window_place): don't run docks and things - through the placement algorithm. Thought it might fix - metacity-window-demo but it didn't. - - * src/window.c (constrain_size): only get work area when needed - (meta_window_new): init the do_not_cover field - -2002-06-08 Havoc Pennington - - * src/screen.c (meta_screen_get_xinerama_for_window): - short-circuit the "only one xinerama" case, and use outer rect of - window instead of window->rect, so we get root window coords. - - * src/theme.c (meta_frame_layout_get_borders): if fullscreen all - frame edges are zero-width. - - * src/frame.c (meta_frame_get_flags): init fullscreen flag. - - * src/common.h (enum): add META_FRAME_FULLSCREEN frame flag - - * src/place.c: fix up calls to meta_window_get_work_area - - * src/window.c (meta_window_get_work_area): add an arg for whether - the work area is for the screen or the xinerama subscreen. - (constrain_position): fix up calls to meta_window_get_work_area - (constrain_size): ditto - - * src/screen.c (meta_screen_new): add METACITY_DEBUG_XINERAMA - environment variable which simulates xinerama on a single head. - -2002-06-08 Havoc Pennington - - * src/window.c (update_struts): only invalidate things if the - struts actually change, since the panel likes to set them over and - over. May fix the infinite loop that caused 100% CPU usage. - -2002-06-07 Havoc Pennington - - * src/screen.c (meta_screen_new): use XineramaIsActive() not - XineramaQueryExtension() - -2002-06-07 Havoc Pennington - - * src/screen.c (meta_screen_get_current_xinerama): don't return - null on non-multihead - -2002-06-06 Havoc Pennington - - * src/screen.c (meta_screen_get_current_xinerama): implement - - * src/place.c (meta_window_place): cascade windows on the active - Xinerama screen - - * src/window.c (meta_window_move_resize_internal): strip out the - #if 0 cruft about guessing fullscreen mode - (constrain_position, constrain_size): fullscreen/maximize to the - Xinerama head, not the whole screen - (meta_window_get_work_area): autocreate struts at the Xinerama - physical screen edges for the screen the window is on. - - * src/screen.c (meta_screen_get_xinerama_for_window): someone - snuck in a for loop, fix it. ;-) - -2002-06-06 James M. Cape - - * src/themes/Esco/metacity-theme-1.xml: Increase the border size - of the buttons so they aren't quite so huge on my box. Also get - a *little* closer to finally fixing the horizontal line behind - the icon. It now works decently with common font sizes (in pixels). - -2002-06-05 Havoc Pennington - - * src/theme.c (meta_color_spec_new_from_string): parse - "shade/foo/factor" as a color - (colorize_pixbuf): remove the unused hsv_to_rgb and vice-versa - stuff, add the gtk_style_shade stuff. - (meta_color_spec_render): render the shaded color spec - - * src/theme.h (struct _MetaColorSpec): add "shade" mode to - MetaColorSpec. - -2002-06-04 Seth Nickell - - * src/metacity.desktop.in: - - Add X-GnomeWMSettingsLibrary to desktop file to support new - Window capplet. - -2002-06-04 Havoc Pennington - - * src/window.c (update_wm_hints): fix for how we read the input - hint, from Hidetoshi Tajima - - (meta_window_show): from Hidetoshi, don't autofocus windows with - input = FALSE wm_take_focus = FALSE when they first appear. We do - allow these windows to be focused (so keynav works), but they - don't get focused automatically. Now how do we keep them out of - the task list? - -2002-06-04 Gustavo GirÃ�¡ldez - - * src/theme.c (draw_op_as_pixbuf): Use icon's instead of image's - fill_type when type is META_DRAW_ICON. - -2002-06-03 Havoc Pennington - - * src/window.c (meta_window_new): don't automatically fullscreen - things opened fullscreen, because there's no GUI to un-fullscreen - them. - -2002-06-03 Havoc Pennington - - * src/theme-parser.c (parse_aspect_ratio): fix error message about - bad aspect ratio name. - -2002-06-03 Havoc Pennington - - * src/themes/Esco/metacity-theme-1.xml: test button aspect ratio - instead of hardcoded button size, James feel free to revert if you - don't like it this way. - - * src/theme-parser.c: parse the aspect_ratio element for button - aspect ratios. - - * src/theme.h (struct _MetaFrameLayout): allow button sizes to be - given as an aspect ratio derived from the titlebar height, - instead of as a fixed size. - - * src/theme.c (meta_frame_layout_validate): validate new button - sizing parameters - - * src/theme.c (meta_frame_layout_calc_geometry): use new button - layout params - -Mon Jun 3 15:12:11 2002 HideToshi Tajima - - * configure.in (METACITY_LIBS): put -lXext into SHAPE_LIBS - -2002-06-03 Kjartan Maraas - - * src/tools/metacity-properties.desktop.in: Someone forgot to mark - the two strings in here for translation :) - -2002-06-02 Havoc Pennington - - * configure.in: 2.3.610 - -2002-06-01 Havoc Pennington - - * src/frames.c (meta_frames_finalize): move the remove_listener - to finalize instead of destroy, thanks to Jayaraj for tracking - down the bug. - -2002-06-01 Havoc Pennington - - * src/session.c: add some missing \n - (meta_session_init): remove the #if 0 interact callback from our - initial SmcOpenConnection call, this arg to SmcOpenConnection - doesn't exist. - -2002-06-01 Havoc Pennington - - * src/session.c: put in more debug spew about the session - -2002-05-30 Havoc Pennington - - * src/Makefile.am (INCLUDES): use $(prefix)/@DATADIRNAME@/locale - for localedir to work with Solaris native gettext, patch from - Hidetoshi Tajima - - * src/tools/Makefile.am: ditto - -2002-05-31 Havoc Pennington - - * src/theme.c: add MetaImageFillType and implement TILE in - addition to the existing SCALE - - * src/theme.h (struct _MetaDrawOp): remove no-longer-used "alpha" - field - -2002-05-31 Havoc Pennington - - * src/theme.c (multiply_alpha): now just uses - meta_gradient_add_alpha - (draw_op_as_pixbuf): implement alpha gradients for tint, gradient, - and image draw ops, so I can implement garrett's stuff. - - * src/gradient.c (meta_gradient_add_alpha): new function to - multiply the alpha channel of a pixbuf by an alpha gradient - -2002-05-30 Havoc Pennington - - * src/main.c (main): verbose-log on startup whether we were - compiled with various extensions - - * src/display.c (meta_display_queue_retheme_all_windows): reapply - shape mask when changing themes, sucks to do it here though, makes - theme changing slower. Needs fixing. - - * src/theme-parser.c (parse_toplevel_element): parse rounded - corner options to frame_geometry - - * src/frames.c (meta_frames_apply_shapes): apply rounded corners - if requested by the theme - - * configure.in (HAVE_SHAPE): check for shape extension - -2002-05-30 Stephen Browne - - * src/tools/metacity-properties.c: - Some day I'll make all my changes in one commit :) - Needed to rip out code for adding icon to the dialog since it was - removed from teh galde file in my previous change. - -2002-05-30 Stephen Browne - - * src/tools/metacity-properties.glade: - Some UI changes demanded by Pat and Calum. - Make Close default response - Change mnemonic for Click so as not to clash with Close - -2002-05-30 Stephen Browne - - * src/tools/metacity-properties.glade: changed window title - to match other control center dialogs - -2002-05-29 Havoc Pennington - - * src/session.c (meta_session_init): improve error about failing - to open session manager. - (shutdown_cancelled_callback): send SmcSaveYourselfDone when we - get cancelled - (interact_callback): implement an interact callback that complains - about lame clients that can't be saved. Still somewhat buggy - in that it sends InteractDone before the user has closed the - dialog. - -2002-05-29 Havoc Pennington - - * src/tools/metacity-mag.c: add a magnifier I'm using when making - themes. Not installed. - - * src/tools/metacity-properties.c: reindentation, show window, add - copyright info. - - * src/tools/metacity-properties.glade: make main window !visible - on startup, to avoid funkiness. - -2002-05-29 Jacob Berkman - - * src/tools/Makefile.am (EXTRA_DIST): dist .desktop.in files - -2002-05-29 Stephen Browne - - New simple metacity-properties dialog to configure focus mode - and auto raise. - - * configure.in: added build support for metacity-properties - * src/tools/Makefile: more build stuff - * src/tools/metacity-properties.c: added these files - * src/tools/metacity-properties.glade: - * src/tools/metacity-properties.desktop.in: - * src/tools/metacity-properties.png: - -2002-05-29 Havoc Pennington - - * src/window.c (meta_window_move_resize_internal): add code to - also guess that client wants to come out of fullscreen, then - #if 0 the whole deal, I'm not sure it's such a good idea. - -2002-05-29 Havoc Pennington - - * src/window.c (meta_window_move_resize_internal): guess if a - window meant to be fullscreen, and if so put it in that state. - -2002-05-28 Havoc Pennington - - * src/window.c (redraw_icon): handle missing frame, prevents segv - with undecorated windows. #83298 - -2002-05-28 Havoc Pennington - - Patch from Erwann Chenede for raise_or_lower keybinding - - * src/display.c, src/common.h: META_POINT_IN_RECT moved to a common - location, removed from here - (meta_rectangle_intersect): move here and make it public - - * src/prefs.c: add raise_or_lower keybinding - - * src/stack.c (meta_stack_get_below, meta_stack_get_above): add an - arg to only get windows within the same layer - - * src/keybindings.c (handle_raise_or_lower): add handling for a - "raise window if obscured, else lower" keybinding - -2002-05-28 Havoc Pennington - - * src/window.c (meta_window_configure_request): handle CWStackMode - in configure requests - (meta_window_new): if a window is opened at 0,0 and screen size, - put it in the fullscreen state. - (meta_window_new): remove old code that set the window position to - 0,0 if PPosition/USPosition unset, that will be handled by whether - we place the window or not. - -2002-05-28 Abel Cheung - - * configure.in: Added "zh_TW" to ALL_LINGUAS. - -2002-05-27 Havoc Pennington - - * src/window.c (meta_window_new): search for the window's screen - by root window instead of Screen*, maybe it will help with - bug #82664 - -2002-05-27 Kjartan Maraas - - * autogen.sh: Hook up intltoolize here. - * configure.in: Initialize intltool. - * src/metacity.schemas.in: Add this. - * src/metacity.desktop.in: Add this too - * src/Makefile.am: Hook up intltool support for .schemas and .desktop. - * Makefile.am: Dist the intltool files. - -2002-05-27 Anders Carlsson - - * src/themes/Gorilla/metacity-theme-1.xml: Apparently someone - thinks my name is Anders Carlsom. Well, it's not. - (Thanks to Carl-Johan Kjellander for noticing.) - -2002-05-26 James M. Cape - - * src/themes/Esco/metacity-theme-1.xml: Remove borders from - Esco theme as well (didn't know you could), apparently fixed - the problem where the spacing between the icon & the title - got larger as the fontsize went up. - -2002-05-26 Havoc Pennington - - * src/themes/Atlanta/metacity-theme-1.xml: totally drop the - borders off of maximized windows. - -2002-05-26 Havoc Pennington - - Patch from Gaute Lindkvist so you can't move the panel or desktop - to only one workspace. - - * src/keybindings.c (handle_move_to_workspace): don't allow moving - window to another space if the window is always_sticky - - * src/window.c (recalc_window_features): set the always_sticky - field for desktop/dock windows. - (meta_window_show_menu): disable unsticking always sticky windows - via the menus - - * src/menu.c (meta_window_menu_new): disable workspace items - if requested - -2002-05-26 Matthias Warkus - - * po/de.po: Added. - * configure.in: de added to ALL_LINGUAS - -2002-05-25 Erwann Chenede - - - * src/keybindings.c (rebuild_screen_binding_table, - rebuild_window_binding_table, - meta_change_keygrab): allow key grabbing for - unmodified keys (e.g F1, etc) fix #82630 - -2002-05-25 Anders Carlsson - - * src/place.c: (get_vertical_edges), (get_horizontal_edges): - Take Xinerama screen edges into consideration. - - * src/screen.c: (meta_rectangle_intersect), - (meta_screen_get_xinerama_for_window): - * src/screen.h: - Add a new function that returns the xinerama monitor that - a window is on. - -2002-05-24 Havoc Pennington - - * src/window.c (menu_callback): follow windows to their new - workspace - - * src/keybindings.c (handle_move_to_workspace): follow windows to - their new workspace - -2002-05-24 Havoc Pennington - - * src/metacity.schemas: add minimize window binding - - * src/keybindings.c (handle_minimize_window): add minimize keybinding - -2002-05-24 Havoc Pennington - - * src/window.c (meta_window_show): change how focusing windows - on initial map works, so that we only steal focus from our - transient parent or from a panel/desktop, never from other - normal windows. - -2002-05-24 Havoc Pennington - - * src/window.c (meta_window_configure_request): modify to ignore - PPosition and USPosition once the window has been placed - -2002-05-24 Anders Carlsson - - * src/window.c: Redraw the window frame when the icon changes. - Fixes #78543, reported by Kang Jeong-Hee. - -2002-05-23 Havoc Pennington - - * src/display.c (event_callback): also filter out LeaveNotify - with NotifyInferior - -2002-05-23 Jayaraj Rajappan - - * src/display.c (event_callback): fix for bugzilla bug #72314, - filter out LeaveNotify caused by grabs when in mouse focus mode. - -2002-05-23 Havoc Pennington - - * src/metacity.schemas: clean up the font preference - - * src/prefs.c: font pref - - * src/frames.c: pay attention to the font pref - -2002-05-23 Havoc Pennington - - Crack from Erwann - - * src/metacity.schemas: add autoraise crackrock - - * src/display.c (event_callback): autoraise window if autoraise is - enabled - - * src/prefs.c: autoraise crack - -2002-05-21 Havoc Pennington - - * src/window.c (constrain_position): fix positioning in fullscreen - mode, patch from Gustavo GirÃ�¡ldez - -2002-05-20 Alessio Frusciante - - * configure.in: Added Italian to ALL_LINGUAS. - -2002-05-20 Pablo Saratxaga - - * configure.in: Added Catalan (ca) and Azeri (az) to ALL_LINGUAS - -2002-05-17 Havoc Pennington - - * configure.in: 2.3.377 - -2002-05-16 Havoc Pennington - - * src/workspace.c (meta_workspace_get_neighbor): fix it, maybe - -2002-05-16 Havoc Pennington - - * src/window.c (constrain_position): lock desktop to position 0,0 - -2002-05-16 Havoc Pennington - - * src/window.c (meta_window_show): don't focus dock, desktop, - etc. windows on initial map, only windows that should have focus. - -2002-05-15 Havoc Pennington - - * src/workspace.c (meta_workspace_get_neighbor): use the layout - information to figure out up/down neighbors - - * src/display.c (event_callback): catch propertynotify on - _NET_DESKTOP_LAYOUT - - * src/screen.c (meta_screen_update_workspace_layout): keep track - of the layout of workspaces as set by the pager - -2002-05-15 James M. Cape - - * src/themes/Esco/metacity-theme-1.xml: Minor tweak to minimize - button. - -2002-05-14 Havoc Pennington - - * src/themes/Makefile.am (THEMES): add Esco theme from James Cape - -2002-05-12 Havoc Pennington - - * src/place.c (meta_window_place): move pposition/usposition - honoring code into here, instead of putting it in window.c. - Makes focusing new windows work, and cleans things up a bit. - #81585 - -2002-05-12 Havoc Pennington - - * src/main.c (main): turn on --g-fatal-warnings if - METACITY_G_FATAL_WARNINGS env variable is set. - -2002-05-11 Anders Carlsson - - * src/display.c: (find_tab_forward), (find_tab_backward), - (meta_display_get_tab_next): - * src/display.h: - * src/keybindings.c: (handle_tab_forward), (handle_focus_previous): - Add screen argument to meta_display_get_tab_next, since we only - want windows on the same screen to appear in the tab chain. - - * src/screen.c: (meta_screen_new): - Or the event mask with existing events since gtk+ may listen to - certain events and we don't want to disable those events. - - (meta_screen_ensure_tab_popup): - * src/tabpopup.c: (meta_ui_tab_popup_new): - * src/tabpopup.h: - Add a screen number argument to meta_ui_tab_popup_new so we - can position the popup on the correct screen. - -2002-05-11 Havoc Pennington - - * src/main.c: include locale.h, fix from Hidetoshi Tajima - - * src/window.c (meta_window_new): disable show desktop mode when a - new window is managed. - -2002-05-11 Havoc Pennington - - * src/fixedtip.c (meta_fixed_tip_show): keep the tooltip - on the screen horizontally, #76825 - - * src/window.c (meta_window_handle_mouse_grab_op_event): end grab - op _after_ doing the final update of the move or resize. - Hopefully I didn't have a reason for the order I was using before. - -2002-05-10 Havoc Pennington - - * src/tools/metacity-window-demo.c: add override redirect test - window - - * src/stack.c (raise_window_relative_to_managed_windows): new - function, used to avoid moving windows above override redirect - popup windows. - - * src/display.c (event_callback): don't lower panels on - LeaveNotify if they have focus, #70895 - -2002-05-10 Havoc Pennington - - * src/window.c (constrain_position): when maximizing/fullscreening - something with a grid, like a terminal, center it in the - maximization area in case it can't fill the whole area. - #70554 - - * src/main.c (main): use g_strerror() to get proper UTF-8. - -2002-05-10 Havoc Pennington - - * src/keybindings.c (reload_modmap): put LockMask into the - ignored_modifier_mask so that caps lock doesn't mess up - keybindings. - -2002-05-10 Havoc Pennington - - * src/window.c (meta_window_focus): if window is not mapped after - the calc_showing, don't focus it, it's probably on another - workspace or something. - -2002-05-09 Havoc Pennington - - * src/frames.c (show_tip_now): DefaultScreen() returns the screen - number not Screen* - - * src/frame.c (meta_frame_sync_to_window): immediately repaint - frame whenever we resize it, if we're inside a grab operation. - - * src/frames.c (meta_frames_repaint_frame): new function - - * src/window.c (meta_window_new): initialize window's colormap - (meta_window_notify_focus): install the colormap for a window when - it gets focus, uninstall on unfocus. - - * src/window.h (struct _MetaWindow): store window's colormap - - * src/display.c (event_callback): note changes to window colormap - - * src/frame.c (EVENT_MASK): add ColormapChangeMask - -2002-05-09 Havoc Pennington - - * src/display.c (event_callback): make Alt+button2 do a resize - -2002-05-08 Anders Carlsson - - * src/fixedtip.c (meta_fixed_tip_show): - #ifdef out call to gtk_window_set_screen, reported by - Erwann Chenede. - -2002-05-08 Anders Carlsson - - * configure.in: - * src/display.c: (meta_display_open): - * src/fixedtip.c: (meta_fixed_tip_show): - * src/fixedtip.h: - * src/frames.c: (meta_frames_new), (show_tip_now): - * src/frames.h: - * src/menu.c: (meta_window_menu_new): - * src/ui.c: (meta_ui_new): - Add multi-screen support. Also add patch by Erwann Chenede - to make tooltips appear on the correct screen. - -2002-05-07 Anders Carlsson - - * src/workspace.c (set_work_area_hint): Doh, only update - the tmp pointer when the screen matches. Fixes a segfault - when running with multiple screens. - - * src/display.c: (meta_display_open), (event_callback), - (meta_display_update_show_desktop_hint): - * src/display.h: - * src/screen.c: (set_supported_hint): - Fix atom name; it's _NET_SHOW_DESKTOP, not - _NET_WM_SHOW_DESKTOP. - - * src/frames.c: (meta_frames_unmanage_window): - Restore the mouse cursor to default when unmanaging a window. - -2002-05-06 Anders Carlsson - - * src/display.c: (set_utf8_string_hint): - Fix an off-by-one error. - - (meta_display_open), - (event_callback), (meta_display_update_show_desktop_hint), - (meta_display_show_desktop), (meta_display_unshow_desktop): - * src/display.h: - * src/screen.c: (set_supported_hint): - Add support for _NET_WM_SHOW_DESKTOP, both as a message and - as a root window property. - -2002-05-05 Havoc Pennington - - * src/window.c (meta_window_unminimize): on unminimize, queue - calc_showing on all transients - (meta_window_activate): on activate, unminimize all a window's - ancestors, not just the window itself. - - * src/workspace.c (set_work_area_hint): don't increment "tmp" by - 16 unsigned long, increment by 4 - - * src/window.c (meta_window_free): if a window isn't minimized, - restore its WM_STATE to NormalState instead of IconicState, - since IconicState on initial window map means that the window - should be minimized. - - * src/workspace.c (meta_workspace_invalidate_work_area): queue an - idle to recompute the work area hint. - (set_work_area_hint): we need 4*num_workspaces ints, not just - num_workspaces. - - * src/screen.c (meta_screen_new): add work_area_idle field, - handle it on screen shutdown - - * src/common.h (META_PRIORITY_PREFS_NOTIFY, - META_PRIORITY_WORK_AREA_HINT): define some idle priorities - - * src/window.c (meta_window_calc_showing): hide windows if - their parent window is minimized - (meta_window_minimize): also queue_calc_showing on all - transients of the window being minimized - - * src/place.c (constrain_placement): function to apply - placement-time-only constraints, such as "not off the left of the - screen" - (meta_window_place): put dialogs down a bit over their parent, - not right at the top. - (meta_window_place): when centering a dialog, center it - on the current xinerama screen, rather than the entire - screen. - - * src/screen.c (meta_screen_get_current_xinerama): new function, - but not implemented - -2002-05-04 Havoc Pennington - - * src/frames.c (meta_frames_paint_to_drawable): chop out the - portion of the region that's outside the screen. - - * src/core.c (meta_core_get_screen_size): new function - (meta_core_get_frame_extents): new function - -2002-05-04 Havoc Pennington - - * src/frames.c (meta_frames_init): disable automatic GTK double - buffering, since it resulted in gigantic backing pixmaps the size - of the whole screen. - (meta_frames_paint_to_drawable): change to take a region argument; - punch the client area out of the expose region, then iterate over - rectangles in the region and draw each, manually doing - begin_paint_rect. Results in 4 long thin backing pixmaps - per frame repaint, instead of one large backing pixmap. - Suggested by Owen. - -2002-05-05 Bastien Nocera - - * src/workspace.c: (meta_workspace_get_neighbor): - Wrap-around workspaces (ie. when on the last workspace, - "switch_to_workspace_right" goes back to the - first one) - -2002-05-05 Anders Carlsson - - * src/metacity.schemas: Fix a spelling error and change - switch_to_workspace_up and switch_to_workspace_down to use - Ctrl+Alt since Nautilus uses Alt now. - -2002-05-04 Havoc Pennington - - * src/window.c (update_net_wm_type): correctly print things if the - type_atom is unset - (meta_window_new): with workarounds disabled, always allow - self-placement for windows with PPosition or USPosition set. - -2002-05-03 Havoc Pennington - - * src/Makefile.am: fix for automake 1.5, patch from Tomasz Kloczko - -2002-05-03 Laszlo Peter - - * configure.in: add the X libs to METACITY_MESSAGE_LIBS and - METACITY_WINDOW_DEMO_LIBS - -2002-05-02 Havoc Pennington - - * README: updates - - * configure.in: 2.3.233 - -2002-05-02 Bastien Nocera - - * src/metacity.schemas: change the default for switch_to_workspace_* - to be arrow as just arrow collides with some apps - (especially web browsers) - -2002-05-01 Havoc Pennington - - * src/screen.c (meta_screen_new): Xlib doesn't like NULL for out - arguments; fix for #80472 from lbedford - -2002-04-30 Havoc Pennington - - * src/keybindings.c: finish mopping up mode_switch_mask field - - * src/display.h (struct _MetaDisplay): remove mode_switch_mask - field - -2002-04-30 Havoc Pennington - - * src/window.c (recalc_window_features): don't try to decorate - toolbars. - - * src/tools/metacity-window-demo.c: add menu and toolbar tests - - * src/place.c (meta_window_place): only dialogs should be centered - over parent, not anything with transient for set. - - * src/window.c (meta_window_configure_request): become more - fascist about window positioning if workarounds are disabled, and - less fascist if they are enabled. - - * src/metacity.schemas: add a "disable_workarounds" option. Kind - of crack-smoking. But we just can't get all applications - fixed. And I need no-workarounds mode to monitor which apps are - broken and what needs fixing in specs. - - * src/window.c (meta_window_configure_request): always allow - windows to resize themselves - - * src/keybindings.c (reload_modmap): don't filter out Mode_switch, - apparently some people bind window manager shortcuts to that. - -2002-04-30 Havoc Pennington - - * src/window.c (constrain_position): oops, fix - maximization. Pointed out by Gustavo GirÃ�¡ldez - -Tue Apr 30 06:24:09 2002 Jonathan Blandford - - * src/menu.c: give Maximize/Unmaximize and Shade/Unshade the same - mnemonic for consistency's sake. - -2002-04-29 Havoc Pennington - - * src/window.c (TITLEBAR_LENGTH_ONSCREEN): require 36 pixels - onscreen so you typically get a sliver of titlebar, suggested by - tigert. Should still fix this to consider actual theme geometry. - (constrain_position): change to allow movement off the left - -2002-04-29 Havoc Pennington - - * src/display.c (event_callback): always raise windows on focus - click, regardless of focus mode. - -2002-04-29 Havoc Pennington - - * configure.in: 2.3.144 - -2002-04-29 Havoc Pennington - - * src/ui.c (meta_ui_init): don't leak the PangoContext - -2002-04-28 Anders Carlsson - - * src/display.c: (meta_display_open): - * src/display.h: - * src/screen.c: (set_supported_hint): - * src/workspace.c: (set_number_of_spaces_hint), - (set_workarea_hint): - Add support for setting the _NET_WM_WORKAREA hint. No code - does it yet though. - -2002-04-28 Havoc Pennington - - * README: remove caveats about keybindings - - * src/metacity.schemas: add schemas for all the keybindings. - - * src/window.c (meta_window_activate): if in "show desktop" mode - when a window is activated, leave show desktop mode. So e.g. - when you click on a task in the task list, show desktop mode - will be turned off. - - * src/workspace.c (meta_workspace_get_neighbor): new function - that doesn't quite work yet (needs support for getting - workspace layout from the pager) - - * src/prefs.c: keybindings stuff - - * src/keybindings.c: make keybindings configurable - - * src/ui.c (meta_ui_parse_accelerator): new function - -2002-04-25 Havoc Pennington - - * metacity.spec: fix to install gconf schemas - -2002-04-25 jacob berkman - - * src/session.c (load_state): g_file_get_contents() takes a gsize - not int (fixes bus error on 64-bit platforms) - -2002-04-22 Havoc Pennington - - * src/main.c (main): call setlocale ourselves because due to a - GLib bug that sticks us in ASCII if you call g_print or anything - prior to setlocale, and print a warning if we don't set the locale - successfully. #79280 - - * src/workspace.c (meta_workspace_get_work_area): be more verbose - about how the work area was computed, to help find bugs here. - - * src/main.c (main): put locale and codeset in the log file - -2002-04-21 Havoc Pennington - - * src/window.c (meta_window_send_icccm_message): add error trap, - fixes a possible BadWindow if a window closed itself in response - to the delete window message prior to us sending the ping message. - -2002-04-21 Havoc Pennington - - * src/window.c (meta_window_move_resize_now): never revert to - user_rect.width, user_rect.height. Maybe fixes assorted resize - screwups e.g. with gnome-terminal. - -2002-04-21 Anders Carlsson - - * src/iconcache.c (scaled_from_pixdata): Add padding if - icon width and height differ. - -2002-04-17 Havoc Pennington - - * src/screen.c (meta_screen_new): query Xinerama screen - information if HAVE_XINERAMA - - * configure.in (found_xinerama): check for Xinerama - -2002-04-17 Changwoo Ryu - - * configure.in (ALL_LINGUAS): Added ko (Korean). - -2002-04-16 Akira TAGOH - - * configure.in (ALL_LINGUAS): add ja.po entry. - -2002-04-15 Havoc Pennington - - * src/window.c (update_title): fix issue with GNU libc - mangling %.10s format - - * metacity.spec: Fix up spec file - - * README: update README - - * configure.in (ALL_LINGUAS): require GTK 2.0.0 - -2002-04-15 Havoc Pennington - - * src/display.c (meta_display_ping_window): reply immediately for - windows that don't support _NET_WM_PING - - * src/window.c (update_protocols): check whether windows - support _NET_WM_PING - -2002-04-13 Havoc Pennington - - * src/ui.c (get_cmap): same fix as libwnck, avoid using cmap - with the wrong depth - -2002-04-13 Havoc Pennington - - * src/delete.c: new file containing all the - wacky mess I just added to a simple "click the close button", - contains all the dealing-with-dead-application cruft. - Use metacity-window-demo to test by clicking the - toolbar button that locks it up. - -2002-04-12 Havoc Pennington - - * src/tools/metacity-window-demo.c (do_appwindow): make one of the - toolbar buttons lock up the demo - - * src/window.c (meta_window_delete): move error trap to be around - a narrower part of the function, and add part of the ping stuff, - nothing user-visible yet - - * src/metacity-dialog.c (main): metacity-dialog executable to - live in libexecdir and pop up dialogs for us. - -2002-04-09 Havoc Pennington - - * src/theme.c (multiply_alpha): fix alpha multiplication routine - to perhaps work correctly, reported by tigert. Also, be sure - we always copy the image if necessary before modifying the - alpha channel. - -2002-04-05 Havoc Pennington - - * src/stack.c: remove the unused tab stuff - - * src/display.c: implement tab list among panels - - * src/keybindings.c: fill in move-between-panels keybindings - -2002-03-31 Johan Dahlin - - * src/menu.c (meta_window_menu_new): Make sure all menu items are - translated. - -2002-03-27 Havoc Pennington - - * src/window.c (meta_window_free): remove - unmanaged windows from save set, and unselect - input so we don't get events from them. Fixes annoying - bug where withdrawn windows would decide to map themselves - due to save set stuff. - -2002-03-22 Zbigniew Chyla - - * configure.in (ALL_LINGUAS): Added pl (Polish). - -2002-03-21 Havoc Pennington - - * src/themes/Bright/metacity-theme-1.xml: Added "Bright" theme - from Gaute Lindkvist, with some small clipping tweaks to keep - text/icons from overlapping their frames. - -2002-03-19 Havoc Pennington - - * src/resizepopup.c (place_vertical_size_window) - (place_horizontal_size_window): disable the little shaped windows - with the window size, they caused a crash anytime you tried to - resize with Xft. And they were kind of on crack anyway. - -2002-03-17 Havoc Pennington - - * src/resizepopup.c (ensure_tick_windows): turn off the tick - marks, that got annoying after about 5 minutes. One big shape - window instead of lots of little windows might fix it. - -2002-03-17 Havoc Pennington - - * src/resizepopup.c: Add some total crackrock resize-grid - indication for windows that have width_inc/height_inc - so I can debug gnome-terminal sizing. - -2002-03-17 Havoc Pennington - - * src/session.c (set_clone_restart_commands): use proper property - name for SmDiscardCommand (instead of setting the clone command to - "rm"). Also fix typo that iterated over clonev not discardv to - fill in prop list, and NULL-terminate discardv. #74584 from Kang - Jeong-Hee. - -2002-03-13 Havoc Pennington - - * src/main.c (main): put back --sm-client-id argument, needed - for including us in a default session - -2002-03-13 Havoc Pennington - - * src/session.c (meta_session_init): don't save a file here, only - in response to SaveYourself. Change the code to properly use a - unique state file for each SaveYourself. Totally, totally - untested. - -2002-03-12 Havoc Pennington - - * src/theme-viewer.c: improve the theme viewer so people - can see the broken aspects of their themes. - -2002-03-11 Havoc Pennington - - * src/keybindings.c: use new functions - - * src/display.c (meta_display_get_tab_next): - (meta_display_get_tab_list): new tab order functions using - MRU list instead of map order - - * src/window.c (meta_window_notify_focus): maintain focus MRU list - - * src/display.h (struct _MetaDisplay): Keep an MRU list of - windows. - -2002-03-10 Havoc Pennington - - * src/display.c (event_callback): support _NET_NUMBER_OF_DESKTOPS - message so you can change number of desktops with the pager - - * src/prefs.c (meta_prefs_set_num_workspaces): new function - - * src/display.c (meta_spew_event): print stacking aspects of - configure requests - -2002-03-10 Havoc Pennington - - * src/screen.c (set_supported_hint): we didn't claim to support - _NET_ACTIVE_WINDOW so gtk_window_present() didn't work. Mumble. - Only worked with tasklist because libwnck didn't check for - WM support. - - * src/window.c (meta_window_free): clean off window state - when windows are withdrawn, to avoid sticking dialogs - to their initial desktop. - (meta_window_queue_calc_showing): return if window is withdrawn - -2002-03-08 Laszlo Peter - - * configure.in: fix the X linker flags - -2002-03-06 Havoc Pennington - - * src/core.c (meta_core_get_grab_frame): add some assertions - - * src/menu.c (meta_window_menu_new): make another warning - into a verbose - - * src/display.c (meta_change_button_grab): use verbose rather than - warning to log failures to grab button, since these are typically - BadWindow from a destroyed window. - -2002-03-06 Havoc Pennington - - * src/frames.c (meta_frames_manage_window): use hash_table_replace - instead of g_hash_table_insert - - * src/main.c (main): only enable verbose/debug if you set - METACITY_VERBOSE/METACITY_DEBUG - - * src/util.c (ensure_logfile): only use a log file if - METACITY_USE_LOGFILE is set - - * src/display.c (meta_display_for_x_display): add warning if - MetaDisplay isn't found - - * src/window.c (meta_window_free): add an assertion that we - successfully cleared the grab window - -2002-03-05 Havoc Pennington - - Work on opaque animations more, still suck too much - to turn on. Not sure how to make them good. - - * src/effects.c (meta_effects_draw_box_animation): - add a slide-up mode for shading - - * src/ui.c (meta_image_window_set): change image window to work by - setting back pixmap on the GtkWindow, instead of using GtkImage. - -2002-03-04 Havoc Pennington - - * src/main.c (main): try ignoring SIGXFSZ, though I'm not - sure what that does exactly. I'm hoping it gives me EFBIG. - - * src/util.c (ensure_logfile): log to a file in /tmp instead - of to ~/metacity.log. - -2002-03-04 Havoc Pennington - - * configure.in: fix configure.in since GTK no longer gives us - -L/usr/X11R6/lib - -2002-03-03 Havoc Pennington - - * src/window.c: improve debug spew about initial workspace - -2002-03-02 Havoc Pennington - - * src/window.c (recalc_window_features): disable resize etc. if - we're fullscreen - (constrain_size): fix size constraints when fullscreen - - * src/display.c (meta_display_open): fix missing comma that - ended up concatenating two of the properties breaking - FULLSCREEN state and PING protocol - -2002-03-02 Havoc Pennington - - * src/display.c: Add hacking to fix the problem that we made our - XGrabPointer() during Alt+Tab actually succeed, so on popping down - Alt+Tab we got an EnterNotify from the ungrab, which resulted in - focusing the window under the mouse. i.e. Alt+Tab didn't work with - sloppy focus. - -2002-02-26 Havoc Pennington - - Screw around with Anders's ping patch so he'll get plenty of CVS - conflicts. ;-) - - * src/display.c (meta_display_ping_window): spew warnings - if we try to call this with CurrentTime - (meta_display_ping_timeout): remove ping from the pending pings - after it times out. - - * src/util.h: added PING debug category - - * src/display.c (remove_pending_pings_for_window): don't remove - "tmp" just before "tmp->next", don't break out of loop after - finding the first match - (meta_display_open): no trailing comma in array init - (event_callback): move the processing of ping replies into a - separate function - - * src/screen.c (set_supported_hint): add _NET_WM_PING to supported - list - - * src/display.h: change gpointer to void* - -2002-02-26 Anders Carlsson - - * src/display.c: (ping_data_free), - (remove_pending_pings_for_window), (meta_display_open), - (event_callback), (meta_display_unregister_x_window), - (meta_display_ping_timeout), (meta_display_ping_window), - (meta_display_window_has_pending_pings): - Implement meta_display_ping_window, and filter out scroll wheel - events. - - * src/display.h: - Add MetaWindowPingFunc, meta_display_ping_window and - meta_display_window_has_pending_pings. - -2002-02-24 Havoc Pennington - - * src/display.c (xcursor_for_op): switch on the op passed in, not - the active op. Gives us the right cursor during resizing, etc. - - * src/errors.c: rearrange all the error stuff to adapt to the GDK - change a while back, so now we print our X errors again - - * src/display.c (meta_display_begin_grab_op): remove KeyPressMask - and KeyReleaseMask from the XGrabPointer(), this caused BadValue - and kept the grab from ever succeeding. Fixes the problem with the - GTK resize grip - this is why you shouldn't break your X error - spew. ;-) - - * src/display.c: debug spew tweaks - - * src/window.c (meta_window_client_message): do some - s/verbose/topic/ stuff - -2002-02-23 Havoc Pennington - - * src/ui.c (meta_ui_init): fix the - be-sure-we-create-coverage-cache hack - -2002-02-19 Havoc Pennington - - * src/ui.c (meta_ui_init): put in hack to keep Pango from mangling - our server grab and locking up on startup. (hack doesn't work - but I want to fix it on my real computer not this laptop) - - * src/window.c: Implement _NET_WM_STATE_FULLSCREEN - - * src/display.c (meta_display_open): add atoms for - _NET_WM_STATE_FULLSCREEN - -2002-02-16 Kjartan Maraas - - * src/main.c: Use bind_textdomain_codeset etc. - -2002-02-14 Havoc Pennington - - * src/theme-viewer.c: use the preview widget here - - * src/preview-widget.h, src/preview-widget.c: make the theme - preview into a nice widget - - * src/frames.c (meta_frames_ensure_layout): replace frame layout - if the frame style changes, this only ends up mattering if you - e.g. changed the font size for windows in a different state such - as maximized, which is crack, but the code may as well be correct - - * src/theme.c (meta_theme_get_frame_style): new function so we can - detect an invalid cache of the PangoLayout in a frame - -2002-02-14 Anders Carlsson - - * src/themes/Crux/metacity-theme-1.xml: Fix some bugs with - prelighting. - -2002-02-13 Anders Carlsson - - * src/theme.c (meta_pango_font_desc_get_text_height): Use - pango_context_get_metrics instead of loading the font. - -2002-02-12 Anders Carlsson - - * src/frames.c (meta_frames_manage_window): Set prelit_control - to META_FRAME_CONTROL_NONE. - (meta_frames_update_prelit_control): New function for setting - the prelit control. - (meta_frames_paint_to_drawable): Set prelight state. - (meta_frames_enter_notify_event): Update prelit control. - (meta_frames_leave_notify_event): Likewise. - (meta_frames_motion_notify_event): Likewise. - - * src/frames.h (struct _MetaUIFrame): add prelit_control. - - * src/window.c (update_mwm_hints): and MWM_FUNC_ALL - with hints->functions instead of hints->flags. - -2002-02-11 Anders Carlsson - - * src/theme.c (meta_frame_layout_new): Set title_scale to 1.0 - -2002-02-11 Bastien Nocera - - * src/theme-viewer.c: (main): change default theme to be Atlanta - like in the .schema file - -2002-02-10 Havoc Pennington - - * src/tools/Makefile.am (EXTRA_DIST): add $(icon_DATA) - - * configure.in: 2.3.55 - - * HACKING: update - - * README: update - -2002-02-09 Havoc Pennington - - * src/theme.c (meta_theme_set_current): add a newline to an error - message - - * src/themes/Gorilla: add Gorilla theme by Jakub Steiner ported to - metacity by Kenneth Christiansen - -2002-02-09 Havoc Pennington - - * src/theme.c (meta_draw_op_draw_with_env): implement wacky "tile" - draw op to lose some of the PNG files in Gorilla theme - - * src/theme-parser.c: parse the tile primitive - -2002-02-09 Havoc Pennington - - * src/window.c (update_icon): port to icon cache - - * src/iconcache.c, src/iconcache.c: begin process of cleaning up - window.c by moving the icon-reading code in here, based on the - code in libwnck, which was in turn based on the earlier metacity - code - -2002-02-09 Havoc Pennington - - * src/stack.c (meta_stack_sync_to_server): hmm, and don't set - last_window at all if we don't ++newp. Fixes even more obscure - stacking bug. - -2002-02-09 Havoc Pennington - - * src/stack.c (meta_stack_sync_to_server): assign last_window - prior to ++newp, so we don't try to stack windows with respect to - themselves. Fixes some obscure stacking bugs. - -2002-02-09 Havoc Pennington - - * src/theme-parser.c: try to make more error message strings the - same, easier for translators - - * src/theme.c (meta_draw_op_free): free color spec for line op - (meta_theme_free): free the integer_constants hash - - * src/theme-parser.c (parse_boolean): move above first use - - * src/theme-viewer.c: fixes for theme.h changes - - * src/frames.c (queue_recalc_func): don't recreate layout - immediately, just save title text. should speed things up. - (meta_frames_set_title): just remove the layout here also, - and save title text. - - * src/theme-parser.c (parse_toplevel_element): parse title_scale - attribute on frame_geometry - - * src/theme.c: support setting the text size - - * src/frames.c: support setting the text size - - * theme-format.txt: updates - -2002-02-09 Havoc Pennington - - * src/themes/Atlanta/metacity-theme-1.xml: put in some kind of - distinctive frame for UTILITY, though it's ugly. Also put in the - borderless look for maximized windows. - - * src/stack.c (compute_layer): put splash screen in the splash - layer - - * src/stack.h (enum): create a splash screen layer - - * src/place.c (meta_window_place): center splashscreen, and fix a - typo in the centering code - - * src/window.c (recalc_window_features): disable most features on - splash screens - - * src/screen.c (set_supported_hint): add UTILITY and SPLASHSCREEN - hints - - * src/window.c: add UTILITY, SPLASHSCREEN implementation - - * src/window.h (enum): add UTILITY, SPLASHSCREEN types - - * src/theme-parser.c (parse_toplevel_element): parser support - for has_title attribute - - * src/theme.c (meta_frame_layout_get_borders): handle a has_title - field in the layout, for utility windows that don't display a - title (would be better to be able to shrink the title text, - but that's kind of tricky to implement :-/) - -2002-02-08 Havoc Pennington - - * src/screen.c (set_supported_hint): add _NET_WM_STATE_HIDDEN - to _NET_SUPPORTED - - * src/keybindings.c (meta_set_keybindings_disabled): put in header - file, to fix warning. - - * src/display.c (meta_display_open): add _NET_WM_STATE_HIDDEN atom - - * src/window.c (set_net_wm_state): set _NET_WM_STATE_HIDDEN for - shaded and minimized windows - (meta_window_show): call set_net_wm_state() if we map the window - or frame - (meta_window_hide): call set_net_wm_state() if we unmap the window - or frame - -2002-02-08 Havoc Pennington - - * src/window.c (set_net_wm_state): only set skip pager/tasklist if - the app set it, don't set it again based on semantic type. - -2002-02-08 Anders Carlsson - - * src/theme.c (scale_and_alpha_pixbuf): If we're only - scaling horizontally or vertically, use GDK_INTERP_NEAREST. - -2002-02-08 Havoc Pennington - - * autogen.sh: unbreak - -2002-02-08 Havoc Pennington - - * src/display.c (meta_display_grab_focus_window_button): grab - buttons 2 and 3 also, so you can focus a window with those, - #70840 - (event_callback): fix this to let you focus a window with any - unmodified click, and also with Alt+button1 - - * configure.in (AC_OUTPUT): add po/Makefile.in - - * autogen.sh: port to glib-gettextize, remove stupid - auto-find-subdirs crap - - * Makefile.am (SUBDIRS): add po to subdirs, #70615 - - * src/window.c (meta_window_activate): unshaded window if shaded, - I thought this was in bugzilla but I don't see it. anyway thanks - whoever mentioned it to me. - -2002-02-08 Havoc Pennington - - * src/tools/metacity-window-demo.c (menu_items): add modal dialog test - -2002-02-08 Havoc Pennington - - * src/window.c (meta_window_show): when mapping a window with - struts, invalidate the work areas it's on. Should fix at least - part of the problem with windows maximizing over panels. - - * src/workspace.c (meta_workspace_invalidate_work_area): also - queue move/resize on sticky windows - - * src/tools/Makefile.am: consolidate reload-theme, restart into a - "metacity-message" app and add enable/disable keybindings to the - messages it knows about. - - * src/keybindings.c: - (meta_change_keygrab): grab keyboard synchronously - (meta_display_process_key_event): if all keybindings are toggled - off, ReplayKeyboard, else AsyncKeyboard, except that the debug - binding for toggling back on is always processed - (meta_set_keybindings_disabled): function to disable/enable - all keybindings - -2002-02-07 Havoc Pennington - - * src/run-metacity.sh: if DEMO_TEST is set then run the window - demo - - * src/tools/metacity-window-demo.c: Create an app with all the - semantic window types, for testing and for designing themes. - -2002-02-07 Havoc Pennington - - Throughout: move to meta_topic rather than meta_verbose so - metacity.log can start being more useful - - * src/util.h (enum): add more debug topics - - * src/frames.c: clean up some cruft that caused warnings - -2002-02-07 Havoc Pennington - - * src/theme.c (colorize_pixbuf): do random voodoo on the algorithm - -2002-02-07 Havoc Pennington - - * src/theme.c (colorize_pixbuf): use the intensity of the gray - pixel for both saturation and value, not just value. - -2002-02-07 Havoc Pennington - - * src/theme.c (INTENSITY): don't define the macro twice - -2002-02-07 Havoc Pennington - - * src/theme.c (colorize_pixbuf): get algorithm right (use HSV/RGB - conversion) at cost of making it a lot slower. It doesn't matter - anyhow with the cache, though. - -2002-02-06 Havoc Pennington - - * src/theme.c (colorize_pixbuf): handle out-of-memory creating - target pixbuf - - * src/themes/Crux/*.png: convert the green-channel images to grayscale - -2002-02-06 Havoc Pennington - - * src/prefs.c (change_notify): s/update_focus_mode/update_theme/ - in case of theme key changing - -2002-02-06 Havoc Pennington - - * src/theme-viewer.c: benchmark theme on startup - - * src/theme-parser.c (parse_draw_op_element): fix "colorize != - NULL" to "colorize_spec != NULL" and free pixbuf on color spec - failure - - * src/theme.c (colorize_pixbuf): minor reformatting, raise - function calls out of inner loop, clamp r/g/b values to uchar - range before assigning to uchar - (draw_op_as_pixbuf): cache the colorized pixbuf - (meta_draw_op_free): free the cache pixbuf - -2002-02-07 Anders Carlsson - - * src/theme-parser.c: (parse_draw_op_element): - Add support for "colorize" image attribute. - - * src/theme.c: (colorize_pixbuf): - New function that colorizes a pixbuf. - - (pos_tokenize): Allow "\n" as a whitespace character. - - (meta_draw_op_free): Free colorize_spec; - - (draw_op_as_pixbuf): Colorize image if needed. - - * src/theme.h: Add colorize_spec to struct. - -2002-02-07 Anders Carlsson - - * src/themes/Crux/metacity-theme-1.xml: Add maximized and - shaded_and_maximized frame styles. - -2002-02-06 Havoc Pennington - - * src/main.c (prefs_changed_callback): redo window - sizes/appearance when the theme changes - - * src/display.c (meta_display_retheme_all): new function - - * src/theme-parser.c (locate_attributes): remove error handling - for MAX_ATTRS reached, add an assert instead, the way this code - ended up the attrs in the array depend on the code not the theme - file. - -2002-02-06 Havoc Pennington - - * src/main.c (main): disable custom log handler and fatal mask for - now - - * src/theme.c (meta_draw_op_list_draw): - Add META_DRAW_CLIP - - * src/main.c: load theme, monitor current theme setting - - * src/prefs.c: add "current theme" setting - - * src/stack.c (meta_stack_free): don't try to free - last_root_children_stacked if it doesn't exist - - * src/themewidget.c: pluggable GtkMisc subclass to use - for menu icons - - * src/screen.c (meta_screen_manage_all_windows): fix - signed/unsigned warning - - * src/frames.c: port to theme system - (meta_frames_style_set): chain up - - * theme-format.txt: new file - - * configure.in: add more compiler warnings - - * src/theme.c: add various stuff needed to get theme parser - working. Remove the "spacer" concept from FrameLayout object. - Add draw op that references a draw op list. - - * configure.in: require GTK 1.3.13 - - * src/Makefile.am: add theme-parser.[hc], implement loading a - theme - - * src/theme.c: add "draw title" and "draw window icon" operations - (meta_draw_op_draw): put object_width/object_height in expression - environment before computing x/y. Handle out-of-memory when - creating pixbufs. Assorted other cleanups. - -2002-02-07 Anders Carlsson - - * src/themes/Crux/metacity-theme-1.xml: - Simplify things so we can remove some - now unnecessary .png files. - * src/themes/Crux/*.png: Remove some files. - -2002-02-07 Anders Carlsson - - * src/themes/Crux/metacity-theme-1.xml - * src/themes/Crux/*.png: - Add Crux theme - -2002-02-07 Kenneth Rohde Christiansen - - * configure.in: add da to ALL_LINGUAS - * po/da.po: add Danish translation - -2002-02-02 Havoc Pennington - - * src/theme-viewer.c: test % operator - - * src/theme.c (pos_tokenize): add % to switch for operators - - * src/theme.c: rework theme stuff so we have - MetaDrawOp/MetaDrawOpList instead of MetaTextureSpec/MetaShapeSpec - -2002-01-28 Havoc Pennington - - * src/theme.c (meta_texture_spec_render): fix shadowed variable - (stupid -Wall should have that) - - * src/theme-viewer.c (main): implement a simple - viewer for frame styles - - * src/theme.c (meta_frame_style_get_test): create partial - frame style to test drawing - -2002-01-27 Havoc Pennington - - * src/theme.c (meta_shape_spec_draw): implement - (meta_texture_spec_draw): implement shape spec and blank - texture support - (meta_frame_style_draw): implement - -2002-01-27 Havoc Pennington - - * src/display.c (meta_set_syncing): move in here so util.c doesn't - require display.[hc] - - * src/theme.h, src/theme.c: implement coordinate expression - parser, write MetaShapeSpec declaration - - * src/util.c (meta_exit): move in here so we can link - to util.c with a different main() - - * src/theme.h: rename the MetaWindow* enums to MetaFrame* - -2002-01-27 Peteris Krisjanis - - * configure.in - Added lv to ALL_LINGUAS - -2002-01-27 Havoc Pennington - - * src/frames.c (get_control): Only consider the bottom of the - titlebar a resize control; I keep accidentally resizing windows - instead of activating them. Also, give south resizing priority - over north, if the window is so small the active regions overlap - - * src/theme.c: add MetaTheme, get MetaFrameStyleSet into - a usable state - - * src/common.h: move window type back to window.h, decided - not to use it on frame side - (MetaFrameType): add this instead - -2002-01-27 Havoc Pennington - - * src/theme.h, src/theme.c: implement all kinds of crazy - compositing-one-texture-onto-another BS. - -2002-01-27 Havoc Pennington - - * src/display.c (event_callback): make the check for whether to - eat focus click a lot more complicated - - * src/window.c (meta_window_same_application): new function - - * src/prefs.h, src/prefs.c: add application based pref - - * src/metacity.schemas: add "application_based" setting to - give me a mode to fool with being application based, - without being unusable in the meantime. Yeah the crack flows - freely these days. Everyone knew it would happen. - -2002-01-27 Havoc Pennington - - * src/frames.c: separate code to draw frame from the - expose_event handler, so in principle we can draw the - frame to a pixmap, but this isn't used yet. - -2002-01-22 Hasbullah Bin Pit - - * configure.in: Added Malay (ms)to ALL_LINGUAS. - * po/ms.po: Added Malay Translation. - -2002-01-19 Havoc Pennington - - * src/wm-tester/test-resizing.c: cheesy client with static - bit gravity, used to test the below change. - - * src/window.c (meta_window_move_resize_internal): implement - Owen's proposal for window resizing. - http://mail.gnome.org/archives/wm-spec-list/1999-November/msg00088.html - - Currently you have to do METACITY_USE_STATIC_GRAVITY=1 in order to - use it, because some GDK bug is screwing up exposes on my frames - when it's enabled. - - * src/display.c (meta_display_create_x_cursor): fix glyph for - NE/NW cursors - - * src/frames.c (get_control): add ability to resize from top - - * src/frame.c (meta_frame_get_flags): can't resize shaded windows - (meta_frame_sync_to_window): add gravity arg - - * src/common.h (MetaWindowType): move here from window.h so - it can be used in themes stuff. - (MetaFrameFlags): remove META_FRAME_TRANSIENT since it - overlaps with window type and was unused. - -2002-01-18 Havoc Pennington - - * src/window.c (constrain_position): give priority to keeping NW - corner onscreen rather than SE, if we need to shift the window - to fit inside constraints - - * src/frames.c (meta_frames_get_geometry): don't depend on the - current window size - - * src/theme.c: move geometry stuff in here, to be calculated as - part of the theme - - * src/core.c (meta_core_get_client_size): new function to replace - meta_core_get_frame_size() so we don't have weird cycles - in the geometry calculation - -2002-01-12 Havoc Pennington - - * src/window.c (meta_window_queue_move_resize): make this actually - queue, rather than being synchronous as it was before. We'll see - what breaks. Should be more efficient and reduce flickery stuff a - bit in some cases. - -2002-01-15 Havoc Pennington - - * src/keybindings.c (handle_tab_backward): fix crash - when grab failed due to another operation in progress - (handle_tab_forward): fix crash when grab failed - -2002-01-10 Havoc Pennington - - * src/frame.c (meta_window_destroy_frame): only bump - unmaps_pending if the window was mapped - (meta_window_ensure_frame): ditto - - * src/keybindings.c: change arrow key bindings to use Ctrl+Alt not - just Alt, and add debug mode key bindings - - * src/stack.c (meta_stack_get_default_focus_window): don't choose - a default focus window with unmaps pending, since we probably just - unmapped it. - - * src/display.c (event_callback): move notify_focus on UnmapNotify - after the window_free check, so we can move focus to another - window when we unmanage - - * src/window.c (meta_window_hide): invalidate work areas when - hiding a window with struts - (meta_window_free): invalidate work areas when unmanaging a window - with struts - -2002-01-09 Havoc Pennington - - * src/window.c, src/window.h: store strut information, - update it on property changes, etc. etc. so we avoid panel - on maximize. - - * src/workspace.c (meta_workspace_get_work_area): add accessor for - work area so we can compute it lazily - - * src/display.h, src/display.c: add _NET_WM_STRUT atom - and _WIN_HINTS atom - -2002-01-08 Havoc Pennington - - * configure.in (ACLOCAL): add code to save ACLOCAL_FLAGS - - * src/frames.c (meta_frames_expose_event): max dither - - * src/testgradient.c (render_simple): change dither mode to MAX - to avoid banding - - * src/theme.c: lose the gradient cache, and put in some initial - data types for the theme format - -2002-01-07 Havoc Pennington - - * src/frames.c (meta_frames_expose_event): make gradient a bit - more subtle (don't go to the full background, but to a blend of - selection and background; put lighter color on top) - -2002-01-06 Havoc Pennington - - * src/window.c (meta_window_notify_focus): rearrange code a bit to - make it clear that has_focus flag always follows - display->focus_window - -2002-01-06 Havoc Pennington - - * src/window.c (meta_window_notify_focus): put in attempted fix - for the GTK 1.2 plug/socket screwup, now that my fixed debug spew - reveals what's actually happening. ;-) - - * src/gradient.c (meta_gradient_description_new): object - to store gradient descriptions - - * src/window.c (meta_window_notify_focus): fix the debug spew - that was confusing me - - * src/wm-tester/focus-window.c: add little program to focus - a window ID - -2002-01-06 Havoc Pennington - - * src/theme.c (meta_theme_get_gradient): change to use spiffy - gradient code. - - * src/gradient.c: copy lovely gradient code from WindowMaker, - as usual Dan and Alfredo have very nice code - -2002-01-06 Fatih Demir - - * configure.in: Added "tr" to the languages list. - -2002-01-05 Havoc Pennington - - * src/frames.c (meta_frames_expose_event): draw titlebar highlight - with snazzy gradient that needs some tweaking to be less - dumb-looking - - * src/theme.c: replace old theme.[hc] contents with newer stuff - that doesn't do anything - -2002-01-05 Havoc Pennington - - GTK 1.2 plug/socket clients still broken, don't know why. - - * src/screen.c (meta_screen_new): select focus change on root - window, for debugging - - * src/display.c (event_callback): when unfocusing, use - no_focus_window to hold the focus - - * src/display.h (struct _MetaDisplay): have a no_focus_window to - hold the focus when we don't want to have anything focused. - Then we can avoid confusing focusing-the-frame stuff. - - * src/window.c (meta_window_notify_focus): improve some debug spew - (meta_window_notify_focus): add hack from WindowMaker to ignore - focus in events with detail > NotifyNonlinearVirtual - -2002-01-04 Havoc Pennington - - * src/display.c (event_callback): don't lower docks when a grab - causes them to get LeaveNotify - -2002-01-04 Havoc Pennington - - * src/screen.c (meta_screen_free): set event mask on root window - to 0 so other window managers (such as ourselves restarting) can - start up; addresses race condition on restart where the old WM - still had RedirectMask when the new WM was trying to start up. - - * src/display.c (meta_display_close): free each screen - - * src/window.c (meta_window_show): always focus new windows in - click-to-focus mode - -2002-01-03 Havoc Pennington - - * src/window.c: use meta_XFree not XFree - - * src/display.h (meta_XFree): add null-safe XFree - - * src/util.c (meta_warning): have message prefix indicate that - it's a warning - (meta_fatal): indicate it's an error - - * src/window.c (update_sm_hints): clean up using - meta_prop_get_latin1_string - (update_role): ditto - (read_client_leader): clean up using meta_prop_get_window - (update_net_wm_type): clean up using meta_prop_get_cardinal - (update_initial_workspace): ditto - (update_net_wm_type): clean up using meta_prop_get_atom_list - (read_rgb_icon): get result from XGetWindowProperty return value - not from error trap - (update_kwm_icon): ditto - (meta_window_new): fix to read WM_STATE correctly - -2002-01-03 Havoc Pennington - - * src/window.c (update_net_wm_state): clean up using - meta_prop_get_atom_list - (update_mwm_hints): clean up using meta_prop_get_motif_hints - - * src/Makefile.am (metacity_SOURCES): add xprops.[hc] - - * src/xprops.c: new file with convenience functions for X - properties - -2002-01-03 Havoc Pennington - - * src/workspace.c (meta_workspace_activate): focus top window when - switching to a new workspace - - * src/util.c (meta_topic): start putting verbose output in - categories - - * src/window.c (meta_window_shade): focus frame after we queue - the calc_showing so the maps/unmaps have already happened. - - * src/display.c (meta_display_get_current_time): add the "get time - of current event" function and call it occasionally. - - * src/window.c (meta_window_free): if we have focus, call - meta_screen_focus_top_window(). - (meta_window_minimize): ditto - (meta_window_delete): ditto - - * src/screen.c (meta_screen_ensure_tab_popup): fix memory leak - - didn't free tab list - (meta_screen_focus_top_window): new function to use when we unmap - or unmanage a focused window - - * src/stack.c (meta_stack_get_default_focus_window): function used - in meta_screen_focus_top_window - -2001-12-21 Havoc Pennington - - * src/frame.c (meta_window_ensure_frame): add a server grab - here since we were failing to have one when calling the function - -2001-12-27 Duarte Loreto - - * configure.in: Added portuguese to ALL_LINGUAS - -2001-12-16 Kjartan Maraas - - * configure.in: Added "no" to ALL_LINGUAS. - -2001-12-11 Stanislav Visnovsky - - * configure.in: Added "sk" to ALL_LINGUAS. - -2001-12-10 Havoc Pennington - - Rework the click-client-area-to-focus support to use synchronous - grabs, avoids a big mess, lets us pass through click when - required (for dock/desktop). Disadvantage is all left-button - clicks now require window manager approval. ;-) - - * src/display.c (event_callback): don't focus dock/desktop when - the mouse enters them; require a click. - (meta_change_button_grab): allow sync grabs - (meta_display_grab_unfocused_window_buttons): establish a - synchronous grab and maintain it all the time, rename to - meta_display_grab_focus_window_button - - * src/window.c: change to reflect display.c - -2001-12-10 Havoc Pennington - - * src/window.c (meta_window_update_unfocused_button_grabs): oops, - unbreak this _again_ - reported by Josh Barrow - -2001-12-10 Havoc Pennington - - * src/window.c (meta_window_update_unfocused_button_grabs): don't - allow grab on docks/desktop for now; needs fixing later to - do the grab, but pass thru click, so we can focus those windows. - And in fact we need to do that even in sloppy mode. - -2001-12-10 Havoc Pennington - - * src/screen.c (meta_screen_foreach_window): fix broken - "tmp = tmp->data" - - Implement do-not-pass-thru-click for click-to-focus mode. - - * src/screen.c (update_focus_mode): when focus mode changes, - update all the window grabs - - * src/display.c (meta_display_grab_unfocused_window_buttons): - implement grabbing button 1 on client area of unfocused - click-to-focus windows - - * src/window.c (meta_window_update_unfocused_button_grabs): update - whether we're grabbing unmodified button 1 on client area - according to focus state and focus mode - (meta_window_new): start out with proper grab state - -2001-12-10 Havoc Pennington - - * src/menu.c (meta_window_menu_new): don't do mnemonics for - workspaces above 9 - -2001-12-10 Havoc Pennington - - * src/screen.c (meta_screen_new): oops, remove extra workspace - creation, and update to current pref. - -2001-12-09 Havoc Pennington - - * src/workspace.c (meta_workspace_free): update number of - workspaces hint - - * src/screen.c (update_num_workspaces): implement number of - workspaces setting - - * src/window.c (meta_window_configure_request): honor configure - requests on windows of type NORMAL, but still be mean to those of - type DIALOG - - * src/main.c (main): add more log domains to those we set a log - handler for, and only set warnings fatal in debug mode - - * src/metacity.schemas: add number of workspaces setting - -2001-12-09 Havoc Pennington - - * src/display.c (event_callback): in click-to-focus mode don't - focus on enter notify. Implement unfocusing on LeaveNotify in - mouse focus mode. Click to focus just ends up working if we - do nothing on enter/leave, because of the way things already - worked. Except I need to add some relatively complex hack to - allow clicking on client area, right now you have to click - on the frame. - -2001-12-09 Havoc Pennington - - * src/main.c (main): move SM init a bit later in the process, and - init prefs - - * src/session.c: fix no SM case (though I hardly know why I'm - bothering) - - * src/main.c (main): call bindtextdomain - - * src/util.h (_): actually call gettext - - * configure.in: put in AM_GLIB_GNU_GETTEXT and gconf stuff - - * src/prefs.c: Preferences - this marks the beginning of our doom. - None of them are actually implemented yet, but we monitor - some stuff from gconf. - -2001-12-07 Havoc Pennington - - * src/window.c (meta_window_unminimize): when unminimizing an app, - if we're in "show desktop" (all windows minimized) mode, leave - show desktop mode. Will occasionally be a bit weird, but allows - people to recover via task list if they accidentally do the show - desktop thing, and don't know what's going on. - -2001-12-06 Havoc Pennington - - * src/ui.c (meta_text_property_to_utf8): fix gdkatom/xatom screwup - - gee, I should read my warnings - -2001-12-03 Laszlo Peter - - * src/frames.c: add a dummy element to the enum so - the signals array is not empty. (breaks the build with Forte C) - - * src/window.c: s/__FUNCTION__/G_GNUC_FUNCTION/ - -2001-11-27 Havoc Pennington - - * src/window.c (constrain_position): change so that window can be - offscreen to the bottom or the right, as long as a small top-left - corner of the window remains onscreen. However, windows still - can't go off the left or top. - -2001-11-26 Havoc Pennington - - * src/window.c (window_query_root_pointer): add error trap - -2001-11-27 Jesus Bravo Alvarez - - * configure.in: Added gl (Galician) to ALL_LINGUAS. - -Tue Nov 20 18:49:16 2001 Owen Taylor - - * configure.in (found_sm): Add some additional quoting to - make it work with autoconf-2.5x. - -2001-11-02 Laszlo Peter - - * src/window.c (update_sm_hints): protect meta_verbose from - a NULL pointer. - -2001-10-29 Havoc Pennington - - * configure.in: bump version - -2001-10-29 Havoc Pennington - - * src/window.c (idle_calc_showing): handle queue/unqueue of - calc showings as we are iterating over the pending list - (meta_window_show): focus placed transients in here instead - of in meta_window_place - now it should actually work, yay - - * src/place.c (meta_window_place): remove focusing of transient - child from here; this was really broken - -2001-10-29 Yuriy Syrota - - * configure.in: Added "uk" to ALL_LINGUAS. - -2001-10-29 Havoc Pennington - - * README: note exciting new unminimize feature for the tab popup - - * src/keybindings.c (process_tab_grab): use meta_window_activate() - when choosing a window with tab popup, this should deiconify it - - * src/window.c (meta_window_client_message): use - meta_window_activate for _NET_ACTIVE_WINDOW message - (meta_window_activate): new function to raise/focus/unminimize - (meta_window_flush_calc_showing): new function - (meta_window_focus): force a calc showing on focus, so that we can - focus the window if appropriate (it must be mapped) - -2001-10-26 Havoc Pennington - - * src/display.c (meta_display_grab_window_buttons): fix for - ignoring NumLock on Alt-windowclick (previous NumLock fix - was only for key grabs not button grabs) - -2001-10-25 Havoc Pennington - - * src/window.c (meta_window_new): set the current workspace hint - -2001-10-25 Havoc Pennington - - * src/window.c (meta_window_visible_on_workspace): - I was using meta_workspace_contains_window() in a number of - places where on_all_workspaces should also have been considered, - thus this new function. Fixes bugs such as pinned windows - not appearing in the tab order. - (meta_window_client_message): use meta_window_visible_on_workspace - - * src/stack.c (find_tab_forward): ditto - (find_tab_backward): ditto - (meta_stack_get_tab_next): ditto - (meta_stack_get_tab_list): ditto - - * src/place.c (get_windows_on_same_workspace): ditto - - * src/keybindings.c (handle_focus_previous): ditto - (handle_focus_previous): ditto - -2001-10-24 Havoc Pennington - - * src/frames.c (meta_frames_expose_event): use bg/fg not base/text - for the window title area. - -2001-10-24 Havoc Pennington - - * src/window.c (meta_window_new): support initial - on-all-workspaces setting - -2001-10-22 Havoc Pennington - - * src/stack.c (meta_stack_sync_to_server): fix to keep desktop - window from appearing on top of everything else, among other stack - bugs. Untested. - -2001-10-15 Havoc Pennington - - * src/window.c (meta_window_new): use queried attributes to check - whether window should be initially maximized, rather than window - rect - -2001-10-15 Havoc Pennington - - * src/main.c (meta_restart): add a restart feature, for debugging - - * src/tools/metacity-restart.c: little utility program to trigger - the restart - -2001-10-14 Havoc Pennington - - * src/frames.c (meta_frames_button_press_event): raise/focus - windows on left-click, seem to have broken that yesterday - - * src/keybindings.c, src/display.c, src/window.c: add keybinding - to show/hide all normal windows (so you can see the desktop). - Currently Ctrl+Alt+D, which I don't like, but yay. - -2001-10-14 Havoc Pennington - - * src/window.c (meta_window_new): take a window mapped at - fullscreen size/pos to desire maximization; once I add a - fullscreen state, will change to copy kwin and take this mapping - as a desire for fullscreen, but for now testing with maximization. - - * src/window.h: remove fullscreen window type, now proposing it - as a window state instead. - -2001-10-14 Havoc Pennington - - * src/window.c (meta_window_maximize): always raise windows on - maximize - (meta_window_client_message): when activating a window, move - it to current workspace, instead of moving user to the - window's workspace. - -2001-10-14 HÃ�©ctor GarcÃ�­a Ã�lvarez - - * configure.in: Added "es" to ALL_LINGUAS for Spanish translation. - -2001-10-14 Havoc Pennington - - * src/display.c (event_callback): only handle events here if - the modmask from our button grab is active. i.e. only the - Alt-click is handled here. - - * src/frames.c: add check for whether button presses are in the - frame client area before handling them, so we don't weirdly let - you move a frame by clicking in its client area if the client - hasn't selected button press events. - -2001-10-13 Havoc Pennington - - * src/stack.c (meta_stack_sync_to_server): set last window before - setting newp, so we don't get the current window as the last - window and screw everything up - (IN_TAB_CHAIN): use type not layer to decide if a window is - in the tab chain, keeps panel out of alt-tab choices - -2001-10-13 Havoc Pennington - - * configure.in: add bad hack to work with GTK 1.3.9.90 RPMs from - gnomehide for now - - * src/ui.c: another piece of bad hack in here - -2001-10-13 Havoc Pennington - - * configure.in: bump version - -2001-10-13 Havoc Pennington - - * src/session.c (meta_session_init): hmm, fix build - -2001-10-12 Havoc Pennington - - * src/session.c (meta_session_init): set the session manager - priority so we start up before other apps. - -2001-10-12 Mikael Hallendal - - * src/ui.c (meta_ui_get_default_window_icon): use - gdk_pixbuf_new_from_inline - (meta_ui_get_default_mini_icon): use - gdk_pixbuf_new_from_inline - -2001-10-11 Christian Rose - - * configure.in: Added "sv" to ALL_LINGUAS. - -2001-10-10 Havoc Pennington - - * src/stack.c (meta_stack_free): fix mem leak of the MetaStack - object - (meta_stack_sync_to_server): try to avoid the restack-flicker - thing - -2001-10-07 Havoc Pennington - - * src/display.c (meta_display_update_active_window_hint): - set _NET_ACTIVE_WINDOW hint - - * src/window.c (meta_window_client_message): support - _NET_ACTIVE_WINDOW client message - -2001-10-07 Havoc Pennington - - * src/window.c (meta_window_client_message): don't allow - shade/maximize/minimize for windows that don't support those - operations. (minimizing the panel = bad) - -2001-10-04 Havoc Pennington - - * src/keybindings.c (meta_change_keygrab): add code to grab all - modifier combinations, so keybindings work with NumLock etc. - - * src/menu.c (meta_window_menu_new): remove newlines from menu - items - -2001-09-27 Havoc Pennington - - * src/session.c (save_state): when encoding text for session file, - escape XML entities - -2001-09-21 Alex Graveley - - * src/Makefile.am (metacity_SOURCES): Add inlinepixbufs.h so - that it gets generated. - - * src/frames.c (meta_frames_style_set): Update for new opaque - PangoFontMetrics. - -2001-09-17 Havoc Pennington - - * src/ui.c (meta_ui_init): add hackaround for the warning about - gtk-menu-bar-accel - -2001-09-17 Havoc Pennington - - * src/ui.c (meta_ui_get_default_mini_icon): - (meta_ui_get_default_window_icon): ref the returned icon, oops. - - * src/main.c (main): get the GLib warning/error output into - the metacity logfile, set warnings to be always fatal - - * configure.in: bump version to 2.3.13 - - * src/window.c (get_text_property): hrm, fix bug where we didn't - check errors on XGetTextProperty - -2001-09-17 Havoc Pennington - - * src/Makefile.am (VARIABLES): fix srcdir != builddir glitch - -2001-09-17 Havoc Pennington - - * src/ui.c: use the inline image data for default icon - - * src/common.h (META_MINI_ICON_HEIGHT): move icon size defines - here - - * src/Makefile.am: Create an inlinepixbufs.h header with inline - images - -2001-09-16 Havoc Pennington - - * src/session.c (process_ice_messages): disconnect this callback - on error - -2001-09-16 Havoc Pennington - - * src/window.c (meta_window_lower): new function - - * configure.in: bump version to 2.3.8 - - * src/display.c (event_callback): raise dock on enter notify, - lower it on leave notify (need to refine this behavior) - - * src/stack.c (compute_layer): experiment with putting the panel - in the normal layer, and raising it on mouseover - -2001-09-15 Havoc Pennington - - * src/window.c: add support for a mini icon in the titlebar - (update_icon): re-enable support for _NET_WM_ICON - - * src/session.c (save_state): add an ferror check when writing - session file - -2001-09-11 Havoc Pennington - - * src/main.c (usage): exit with error code on usage() (kind of - wrong for --help, but oh well). - -2001-09-11 Havoc Pennington - - * src/window.c: fix up handling of text properties, so we - get UTF8_STRING as that type and not as text list, and so - we properly convert from text list to UTF-8 - -2001-09-10 Havoc Pennington - - * src/menu.c (meta_window_menu_new): icon for unmaximize - - * src/ui.c (meta_ui_init): fix call to XDisplayName - - * src/util.c: add missing header - - * src/frames.c: draw an unmaximize control if already maximized - -2001-09-10 Havoc Pennington - - * src/window.c: Don't separate user_has_moved/user_has_resized, - fixes bug in east-resizing Emacs, among other things - - * src/frame.c (meta_frame_sync_to_window): return immediately if - nothing to do - - * src/util.c (ensure_logfile): replace rather than truncate old - logfiles - -2001-09-08 Havoc Pennington - - * src/ui.c (meta_ui_init): don't use gdk_display_name - - * src/frame.c (meta_window_ensure_frame): create frame - with screen default visual, rather than client window visual; - for DRI games, the client window visual was not allowed to be - a child of another window with the same visual, apparently. - Anyhow now we copy twm, etc. so it must be correct. - - * src/place.c (meta_window_place): if a transient is placed and - its parent has focus, focus the transient. - -2001-09-06 Havoc Pennington - - * configure.in: bump version 2.3.5, require newer GTK release - -2001-09-04 Havoc Pennington - - * src/wm-tester/Makefile.am (noinst_PROGRAMS): make test apps - noinst - - * src/metacity.desktop: for the capplet - - * src/Makefile.am: add .desktop file - -2001-09-01 Havoc Pennington - - * src/errors.c: clean up the code, and replace GDK X error handler - with one that chains up to GDK but first logs the error to logfile. - -2001-08-31 Havoc Pennington - - * src/tabpopup.c (meta_ui_tab_popup_new): fix args to - gtk_alignment_new() - -2001-08-29 Havoc Pennington - - * src/display.c (event_callback): avoid focusing a window on tab - popup popdown - - * src/screen.c (meta_screen_ensure_tab_popup): compute frame - outline size here - -2001-08-29 Havoc Pennington - - * src/tabpopup.c: Switch back to outline. - -2001-08-29 Havoc Pennington - - * src/tabpopup.c: experiment with window-cover-with-icon - instead of just the outline; can't decide. - -2001-08-29 Havoc Pennington - - * src/tabpopup.c: add crackrock window-outlining feature - - * src/session.c (window_type_to_string): handle fullscreen - -2001-08-29 Havoc Pennington - - * src/display.c (meta_display_open): wrong atom name - - _NET_SUPPORTED not _NET_WM_SUPPORTED - - * src/window.c (meta_window_configure_request): geez, why were we - honoring configure requests for width/height for normal windows. - Denied! - (meta_window_client_message): _NET_WM_MOVERESIZE support, sort of - (doesn't quite work, acts like owner_events = true?) - - * src/display.c: add _NET_WM_MOVERESIZE atom - -2001-08-28 Havoc Pennington - - Unbreak tab popup a bit. - - * src/stack.c (meta_stack_get_tab_list): add workspace argument - (meta_stack_get_tab_next): add workspace argument - - * src/window.c: implement recording of the last user-initiated - window position, so we can magically handle moving panels around - really nicely. - - * src/wm-tester/main.c (set_up_icon_windows): fix to use new GTK - API - -2001-08-24 Havoc Pennington - - * src/window.c (constrain_position): force fullscreen windows to - be at 0,0 - - * src/ui.c: use NULL colormap to get bitmaps, requires - very latest GTK from CVS or it will spew warnings - and not work. - - * src/window.c (constrain_size): disallow larger than screen in - all cases, even if user has performed a resize operation. - (constrain_position): keep window boxed onscreen. - - * src/keybindings.c (meta_display_process_key_event): revert an - earlier change that disabled global keybindings when a grab is in - effect; instead, only disable global keybindings if a _keyboard_ - grab is in effect. The earlier change was just a broken - workaround, the problems it fixed should have been solved by the - addition of XGrabKeyboard() on the metacity keyboard grabs. - - This should fix the problem with - pick-up-window-and-move-to-another-desktop. - -2001-08-23 Havoc Pennington - - * src/window.c (update_icon): attempt to use the mask as well as - the pixmap. Probably doesn't work so well. - - * src/tabpopup.c: make this look a little nicer - -2001-08-22 Havoc Pennington - - * src/window.c (update_mwm_hints): all the MWM flag tests were - backward - -2001-08-22 Havoc Pennington - - * src/window.c (update_icon): half-ass implementation of - getting pixmap icons (WM_NORMAL_HINTS and KWM_WIN_ICON). - Ignores mask for now, with possibly ugly results for - some apps. - (read_rgb_icon): fixage - -2001-08-19 Havoc Pennington - - * src/window.c: add a "fullscreen" semantic type; if a window - requests the screen size exactly, and is undecorated, and is not a - desktop window, we consider it a fullscreen window and keep it on - top. - - Totally untested. - -2001-08-19 Havoc Pennington - - * src/screen.c (set_supported_hint): we support _NET_WM_ICON - - * src/wm-tester/main.c: add stuff to test _NET_WM_ICON - (but it doesn't work, so it isn't tested yet) - - * src/window.c (update_icon): read _NET_WM_ICON - - * src/screen.c (meta_screen_new): set the WM_ICON_SIZE hint - - * src/tabpopup.c (meta_ui_tab_popup_select): remove assertion - - * src/window.c (meta_window_get_icon_geometry): fix obscure - memleak - -2001-08-19 Havoc Pennington - - * src/display.c (meta_display_grab_window_buttons): remove XSync, - error traps already do that - (meta_display_grab_window_buttons): implement - - * src/keybindings.c: - src/display.c: wire up the tab window, it rulez! - -2001-08-19 Havoc Pennington - - * src/tabpopup.c: add prototype thingy to display windows we're - cycling through with tab. Not wired up to keybindings yet. - -2001-08-18 Havoc Pennington - - * src/effects.c (meta_effects_draw_box_animation): put an XFlush() - right after starting things moving - -2001-08-18 Havoc Pennington - - * src/window.c (meta_window_configure_request): - (meta_window_move_resize_internal): Make a half-hearted - not-very-tested attempt to handle window resizes correctly with - respect to window gravity. - -2001-08-18 Havoc Pennington - - * src/window.c (meta_window_get_gravity_position): hrm, I fixed - this wrong the other day. Fixes static gravity when moving - windows. - -2001-08-18 Havoc Pennington - - * src/ui.c (meta_image_window_set_position): also set the current - size. Lame hack of the day. - - * src/effects.c (effects_draw_box_animation_timeout): use the - delay exposes feature to avoid the screen dirt - - * src/ui.c - (meta_ui_push_delay_exposes): - (meta_ui_pop_delay_exposes): feature to let us delay redraws until - after we do server-grabbed draw-on-inferiors effects - -2001-08-17 Havoc Pennington - - * src/window.c (meta_window_get_gravity_position): fix for - StaticGravity - -2001-08-09 Havoc Pennington - - * src/window.c (meta_window_configure_request): Honor USPosition - even post-map. I know I'll regret this. - -2001-08-07 Havoc Pennington - - * src/display.c (meta_display_open): set _NET_WM_NAME - hint as a UTF8_STRING not STRING. Patch from Anders. - -2001-08-06 Havoc Pennington - - * src/effects.c: disable opaque animations by default, current - implementation suXors. - -2001-08-06 Havoc Pennington - - * src/effects.c (meta_effects_draw_box_animation): Get start - time after we do the pixbuf from drawable, so we don't count - time spent getting pixbuf from drawable in the animation time. - -2001-08-06 Havoc Pennington - - * src/effects.c: add opaque minimize/shade feature. The wireframe - seemed kind of confusing and unclear from a UI standpoint. - I know, I know. The bloat begins here. - - Also, we don't need to grab the server during opaque min/shade, - which has some nice implications. - - * src/ui.c: Add features to render a window with an image in it, - and also wrap pixbuf_from_drawable - - * src/effects.c (meta_effects_draw_box_animation): - modify to be smoother (at least theoretically) by - syncing to current time and "dropping frames" - as appropriate. - - * src/window.c (meta_window_shade): draw animation - for shading too - -2001-08-05 Anders Carlsson - - * src/display.h, src/display.c: Add _NET_WM_ICON_GEOMETRY atom. - - * src/window.c (meta_window_calc_showing): See if the window has - an icon geometry and show a morphing animation from the window's - coordinates to the icon's coordinates. - (meta_window_get_icon_geometry): New function that fetches a - window's icon geometry. - - * src/Makefile.am: Add effects.[ch]. - - * src/effects.c: New file with cool effects. - -2001-08-03 Havoc Pennington - - * src/keybindings.c: Add Alt + left/right arrow to - move between workspaces. - - * src/screen.c (set_wm_check_hint): put property pointing back to - itself on the _WIN_SUPPORTING_WM_CHECK window. - -2001-08-03 Havoc Pennington - - * src/display.c (event_callback): push error trap around configure - of withdrawn window, fixes a crash caused by rapidly - creating/destroying a window. - - * src/window.c (recalc_window_features): don't allow shading - undecorated windows. - - * src/wm-tester/main.c: add a program to torture window managers. - -2001-08-01 Havoc Pennington - - * src/window.c (recalc_window_features): if a window isn't - resizeable, turn off maximize function. If min size is equal to - max size, turn off resize function. - diff --git a/HACKING b/HACKING deleted file mode 100644 index 3240b8d17..000000000 --- a/HACKING +++ /dev/null @@ -1,298 +0,0 @@ -Intro... - -Window managers have a few ways in which they are significantly different -from other applications. This file, combined with the code overview in -doc/code-overview.txt, should hopefully provide a series of relatively -quick pointers (hopefully only a few minutes each) to some of the places -one can look to orient themselves and get started. Some of this will be -general to window managers on X, much will be specific to Metacity, and -there's probably some information that's common to programs in general but -is nonetheless useful. - -Overview - Administrative issues - Minimal Building/Testing Environment - Relevant standards and X properties - Debugging and testing - Debugging logs - Adding information to the log - Valgrind - Testing Utilities - Technical gotchas to keep in mind - Other important reading - Extra reading - Ideas for tasks to work on - - -Administrative issues - Don't commit substantive code in here without asking hp@redhat.com. - Adding translations, no-brainer typo fixes, etc. is fine. - - The code could use cleanup in a lot of places, feel free to do so. - - See http://developer.gnome.org/dotplan/for_maintainers.html for - information on how to make a release. The only difference from those - instructions is that the minor version number of a Metacity release - should always be a number from the Fibonacci sequence. - -Minimal Building/Testing Environment - You do not need to _install_ a development version of Metacity to - build, run and test it; you can run it from some temporary - directory. Also, you do not need to build all of Gnome in order to - build a development version of Metacity -- odds are, you may be able - to build metacity from CVS without building any other modules. - - As long as you have gtk+ >= 3.0 and GIO >= 2.25.10 with your distro - (gtk+ >= 2.6 if you manually revert the change from bug 348633), you - should be able to install your distro's development packagesh - (e.g. gtk2-devel, glib-devel, startup-notification-devel on - Fedora; also, remember to install the gnome-common package which is - needed for building cvs versions of Gnome modules like Metacity) as - well as the standard development tools (gcc, autoconf, automake, - pkg-config, intltool, and libtool) and be ready to build and test - Metacity. Steps to do so: - - $ svn checkout http://svn.gnome.org/svn/metacity/trunk metacity - $ cd metacity - $ ./autogen.sh --prefix /usr - $ make - $ ./src/metacity --replace - - Again, note that you do not need to run 'make install'. - -Relevant standards and X properties - There are two documents that describe some basics about how window - managers should behave: the ICCCM (Inter-Client Communication Conventions - Manual) and EWMH (Extended Window Manager Hints). You can find these at - the following locations: - ICCCM - http://tronche.com/gui/x/icccm/ - EWMH - :pserver:anoncvs@pdx.freedesktop.org:/cvs - The ICCCM is usually available in RPM or DEB format as well. There is - actually an online version of the EWMH, but it is almost always woefully - out of date. Just get it from cvs with these commands (the backslash - means include the stuff from the next line): - cvs -d :pserver:anoncvs@cvs.freedesktop.org:/cvs/icccm-extensions login - cvs -d :pserver:anoncvs@cvs.freedesktop.org:/cvs/icccm-extensions \ - checkout wm-spec - - DO NOT GO AND READ THOSE THINGS. THEY ARE REALLY, REALLY BORING. - - If you do, you'll probably end up catching up on your sleep instead of - hacking on Metacity. ;-) Instead, just look at the table of contents and - glance at a page or two to get an idea of what's in there. Then only - refer to it if you see something weird in the code and you don't know - what it is but has some funny looking name like you see in one of those - two documents. - - You can refer to the COMPLIANCE file for additional information on these - specifications and Metacity's compliance therewith. - - One of the major things those documents cover that are useful to learn - about immediately are X properties. The right way to learn about those, - though, is through hand on experimentation with the xprop command (and - then look up things you find from xprop in those two manuals if you're - curious enough). First, try running - xprop - in a terminal and click on one of the windows on your screen. That gives - you the x properties for that window. Look through them and get a basic - idea of what's there for kicks. Note that you can get rid of some of the - verboseness by grepping out the _NET_WM_ICON stuff, i.e. - xprop | grep -v _NET_WM_ICON - Next, try running - xprop -root - in a terminal. There's all the properties of the root window (which you - can think of as the "main" Xserver window). You can also manually - specify individual windows that you want the properties of with - xprop -id - if you know the id of the window in question. You can get the id of a - given window by either running xwininfo, e.g. - xwininfo | grep "Window id" | cut -f 4 -d ' ' - or by looking at the _NET_CLIENT_STACKING property of the root - window. Finally, it can also be useful to add "-spy" (without the - quotes) to the xprop command to get it to continually monitor that - window and report any changes to you. - -Debugging information - Trying to run a window manager under a typical debugger, such as gdb, - unfortunately just doesn't work very well. So, we have to resort to - other methods. - - Debugging logs - - First, note that you can start a new version of metacity to replace the - existing one by running - metacity --replace - (which also comes in handy in the form "./src/metacity --replace" when - trying to quickly test a small change while hacking on metacity without - doing a full "make install", though I'm going off topic...) This will - allow you to see any warnings printed at the terminal. Sometimes it's - useful to have these directed to a logfile instead, which you can do by - running - METACITY_USE_LOGFILE=1 metacity --replace - The logfile it uses will be printed in the terminal. Sometimes, it's - useful to get more information than just warnings. You can set - METACITY_VERBOSE to do that, like so: - METACITY_VERBOSE=1 METACITY_USE_LOGFILE=1 metacity --replace - (note that METACITY_VERBOSE=1 can be problematic without - METACITY_USE_LOGFILE=1; avoid it unless running in from something that - won't be managed by the new Metacity--see bug 305091 for more details). - There are also other flags, such as METACITY_DEBUG, most of which I - haven't tried and don't know what they do. Go to the source code - directory and run - grep "METACITY_" * | grep getenv - to find out what the other ones are. - - Adding information to the log - - Since we can't single step with a debugger, we often have to fall back to - the primitive method of getting information we want to know: adding - "print" statements. Metacity has a fairly structured way to do this, - using the functions meta_warning, meta_topic, and meta_verbose. All - three have the same basic format as printf, except that meta_topic also - takes a leading enumeration parameter to specify the type of message - being shown (makes it easier for grepping in a verbose log). You'll find - tons of examples in the source code if you need them; just do a quick - grep or look in most any file. Note that meta_topic and meta_verbose - messages only appear if verbosity is turned on. I tend to frequently add - temporary meta_warning statements (or switch meta_topic or meta_verbose - ones to meta_warning ones) and then undo the changes once I've learned - the info that I needed. - - There is also a meta_print_backtrace (which again is only active if - verbosity is turned on) that can also be useful if you want to learn how - a particular line of code gets called. And, of course, there's always - g_assert if you want to make sure some section isn't executed (or isn't - executed under certain conditions). - - Valgrind - - Valgrind is awesome for finding memory leaks or corruption and - uninitialized variables. But I also tend to use it in a non-traditional - way as a partial substitute for a normal debugger: it can provide me with - a stack trace of where metacity is crashing if I made a change that - caused it to do so, which is one of the major uses of debuggers. (And, - what makes it cooler than a debugger is that there will also often be - warnings pinpointing the cause of the crash from either some kind of - simple memory corruption or an uninitialized variable). Sometimes, when - I merely want to know what is calling a particular function I'll just - throw in an "int i; printf("%d\n", i);" just because valgrind will give - me a full stacktrace whenever it sees that uninitialized variable being - used (yes, I could use meta_print_backtrace, but that means I have to - turn verbosity on). - - To run metacity under valgrind, use options typical for any Gnome - program, such as - valgrind --log-file=metacity.log --tool=memcheck --num-callers=48 \ - --leak-check=yes --leak-resolution=high --show-reachable=yes \ - ./src/metacity --replace - where, again, the backslashes mean to join all the stuff on the following - line with the previous one. - - However, there is a downside. Things run a little bit slowly, and it - appears that you'll need about 1.5GB of ram, which unfortunately prevents - most people from trying this. - - Testing Utilities - - src/run-metacity.sh - The script src/run-metacity.sh is useful to hack on the window manager. - It runs metacity in an Xnest. e.g.: - CLIENTS=3 ./run-metacity.sh - or - DEBUG=memprof ./run-metacity.sh - or - DEBUG_TEST=1 ./run-metacity-sh - or whatever. - - metacity-message - The tool metacity-message can be used as follows: - metacity-message reload-theme - metacity-message restart - metacity-message enable-keybindings - metacity-message disable-keybindings - The first of these is useful for testing themes, the second is just - another way (besides the --restart flag to metacity itself) of - restarting metacity, and the third is useful for testing Metacity when - running it under an Xnest (typically, the Metacity under the Xnest - wouldn't get keybinding notifications--making keyboard navigation not - work--but if you disable the keybindings for the global Metacity then - the Metacity under the Xnest can then get those keybinding notifications). - - metacity-window-demo - metacity-window-demo is good for trying behavior of various kinds - of window without launching a full desktop. - -Technical gotchas to keep in mind - Files that include gdk.h or gtk.h are not supposed to include - display.h or window.h or other core files. Files in the core - (display.[hc], window.[hc]) are not supposed to include gdk.h or - gtk.h. Reasons: - - "Basically you don't want GDK most of the time. It adds - abstractions that cause problems, because they aren't designed to - be used in a WM where we do weird stuff (display grabs, and just - being the WM). At best GDK adds inefficiency, at worst it breaks - things in weird ways where you have to be a GDK guru to figure - them out. Owen also told me that they didn't want to start adding - a lot of hacks to GDK to let a WM use it; we both agreed back in - the mists of time that metacity would only use it for the "UI" - bits as it does. - - Having the split in the source code contains and makes very clear - the interface between the WM and GDK/GTK. This keeps people from - introducing extra GDK/GTK usage when it isn't needed or - appropriate. Also, it speeds up the compilation a bit, though this - was perhaps more relevant 5 years ago than it is now. - - There was also a very old worry that the GDK stuff might have to - be in a separate process to work right; that turned out to be - untrue. Though who knows what issues the CM will introduce." - - Remember that strings stored in X properties are not in UTF-8, and they - have to end up in UTF-8 before we try putting them through Pango. - - If you make any X request involving a client window, you have to - meta_error_trap_push() around the call; this is not necessary for X - requests on the frame windows. - - Remember that not all windows have frames, and window->frame can be NULL. - -Other important reading & where to get started - Extra reading - - There are some other important things to read to get oriented as well. - These are: - http://pobox.com/~hp/features.html - rationales.txt - doc/code-overview.txt - - It pays to read http://pobox.com/~hp/features.html in order - to understand the philosophy of Metacity. - - The rationales.txt file has two things: (1) a list of design choices with - links in the form of bugzilla bugs that discuss the issue, and (2) a list - outstanding bug categories, each of which is tracked by a particular - tracker bug in bugzilla from which you can find several closely related - bug reports. - - doc/code-overview.txt provides a fairly good overview of the code, - including coverage of the function of the various files, the main - structures and their relationships, and places to start looking in the - code tailored to general categories of tasks. - - Ideas for tasks to work on - - There are a variety of things you could work on in the code. You may - have ideas of your own, but in case you don't, let me provide a list of - ideas you could choose from: - - If you're ambitious, there's a list of things Havoc made that he'd really - like to see tackled, which you can find at - http://log.ometer.com/2004-05.html. Be sure to double check with someone - to make sure the item is still relevant if you're interested in one of - these. Another place to look for ideas, of course, is bugzilla. One can - just do queries and look for things that look fixable. - - However, perhaps the best way of getting ideas of related tasks to work - on, is to look at the second half of the rationales.txt file, which tries - to group bugs by type. diff --git a/MAINTAINERS b/MAINTAINERS deleted file mode 100644 index 0031c7f9c..000000000 --- a/MAINTAINERS +++ /dev/null @@ -1,8 +0,0 @@ -Tomas Frydrych -Email: tf linux intel com -Userid: tomasf - -Owen Taylor -Email: otaylor redhat com -Userid: otaylor - diff --git a/Makefile.am b/Makefile.am deleted file mode 100644 index c5d589ff7..000000000 --- a/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ - -SUBDIRS=cogl clutter src src/compositor/plugins po doc data - -EXTRA_DIST = HACKING MAINTAINERS rationales.txt - -DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc - -DISTCLEANFILES = intltool-extract intltool-merge intltool-update po/stamp-it po/.intltool-merge-cache diff --git a/NEWS b/NEWS index a51038896..c710f4d9a 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,2785 @@ +3.36.9 +====== +* Do not ping unmanaging windows [Florian; gnome-shell#2467] +* Improve freezes when switching workspace [Jonas Å.; !1616] +* Fix drag cancel animation when using geometry scaling [Robert; !1683] +* Fix stuck icon in DND operation between X11 and wayland [Carlos; !1720] +* Fix restoring focus to windows using globally active input [Olivier; !1716] +* Fix order in which subsurface placement operations are handled [Robert; !1768] + +Contributors: + Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, Robert Mader, Florian Müllner + +3.36.8 +====== +* Fix _NET_WM_FRAME_DRAWN timestamps [Jonas; !1360] +* Fix unwanted position changes on window resize + [Jonas, Olivier, Robert; !1477, !1495] +* Fix device configuration not being picked up on X11 [Carlos; !1553] +* Fix size hints with CSD [Christian, Olivier; !1598] +* Disable CRTCs if there is no monitor [Kai-Heng; !1561] +* Fixed crashes [Olivier, Robert, Jonas; !1529, !1534, #1521, !1563, !1653] +* Plugged memory leaks [Ray; !1225] +* Misc. bug fixes and cleanups [Olivier, Robert, Daniel, Carlos; !1575, + !1565, !1572, !1655] + +Contributors: + Jonas Ådahl, Kai-Heng Feng, Olivier Fourdan, Carlos Garnacho, Robert Mader, + Christian Rauch, Ray Strode, Daniel van Vugt + + +3.36.7 +====== +* Fix Night Light updates after DPMS [Jonas, Benjamin; #1392] +* Fix IM handling on X11 [Carlos; #1413] +* Fix resizing of attached modal dialogs on wayland [Jonas; !1446] +* Fix jumps when resizing windows using discrete steps [Jonas; #1447] +* Fixed crashes [Marco; !1371, #1345] +* Plugged Memory leaks [Ray; !1449, !1451] +* Misc. bug fixes and cleanups [Jonas, Carlos, Robert; !1218, !1460, !1463] + +Contributors: + Marco Trevisan (Treviño), Benjamin Berg, Carlos Garnacho, Robert Mader, + Ray Strode, Jonas Ådahl + +Translators: + Juliano de Souza Camargo [pt] + +3.36.6 +====== +* Fix stale cursor positions in remote desktop sessions [Georges; !1417] +* Limit mipmap levels when rendering background [Daniel; !1003] +* Improve support for Hangul input method [Carlos; !1423] +* Fixed crashes [Robert, Benjamin; !1411, !1409, !1408, !1415, !1392] +* Plugged memory leaks [Robert; #1292] +* Misc. bug fixes and cleanups [Daniel; !1298, !983] + +Contributors: + Benjamin Berg, Carlos Garnacho, Robert Mader, Georges Basile Stavracas Neto, + Daniel van Vugt + +3.36.5 +====== +* Screencast fixes and improvements [Jonas; !1351, !1365] +* Fix glitches when subsurfaces extend outside the toplevel [Robert; #1316] +* Mipmap background texture rendering [Daniel; !1347] +* Fix wine copy & paste [Sebastian; !1369] +* Plugged memory leaks [Marco, Thomas; !1195] + +Contributors: + Jonas Ådahl, Thomas Hindoe Paaboel Andersen, Sebastian Keller, Robert Mader, + Marco Trevisan (Treviño), Daniel van Vugt + +Translators: + Rafael Fontenelle [pt_BR] + +3.36.4 +====== +* Fix crash on area screenshots with fractional scaling [Sebastian; !1320] +* Do not paint textures of fully obscured windows [Robert; !1326] +* Turn off CRTCs as well when enabling DPMS [Michel; !1240] +* Improve selection support + [Robert, Carlos, Sebastian; !1330, !1193, !1253, !1255, !1293, !1350] +* Use a more appropriate combine function on opaque areas [Daniel; !1331] +* Fix remote desktop being broken without screencast session [Olivier; #1307] +* Fix popovers disappearing on wayland and HiDPI [Robert; #1312] +* Fixed crashes [Jonas Å.; !1317] +* Plugged memory leaks [Jonas Å.; !1283] +* Misc. bug fixes and cleanups + [Corentin, Sebastian, Jonas Å., Jonas D.; !1314, !1321, !1295, !1333] + +Contributors: + Jonas Dreßler, Michel Dänzer, Olivier Fourdan, Carlos Garnacho, + Sebastian Keller, Robert Mader, Corentin Noël, Daniel van Vugt, Jonas Ådahl + + +3.36.3 +====== +* Broadcast clipboard/primary offers [Carlos; !1262] +* Fix monitor screen cast on X11 [Jonas Å.; !1251] +* Implement touch-mode detecation for the X11 backend [Carlos; !1278] +* Drop external keyboard detection from touch-mode heuristics [Carlos; !1277] +* Fix leaked DMA buffers in screencasts [Jonas; !1283] +* Fixed crashes [Daniel, Carlos, Jonas D.; !1256, !1258, !1280] + +Contributors: + Carlos Garnacho, Daniel van Vugt, Jonas Ådahl + +3.36.2 +====== +* Sync timelines to hardware vsync [Daniel; !724] +* Fix screencasting non-maximized windows [Jonas; !1174] +* Make window-aliveness checks less aggressive [Jonas; !1182] +* Fix stylus coordinates when using screen rotation [Jonas T.; #1118] +* Preserve keyboard state on VT switch [Olivier; !1185] +* Fix trackball button scrolling [Phillip; #1120] +* Fix tiled monitor support [Jonas Å.; !1199] +* Fix various clipboard issues [Carlos; !1198, !1203, !1204, !1186, !1206] +* Synchronize shadows to server-side decorations [Olivier; !1214] +* Fix overview key on X11 when using multiple keyboard layouts [Olivier; !1219] +* Fix capturing with multiple stage views [Jonas Å.; !1222] +* Fixed crashes [Jonas D., Carlos; !1173, !1183] +* Misc. bug fixes and cleanups [Andre, Georges, Simon, Christian, Carlos, Marco, + Pekka, Laurent, Jonas D.; !1169, !1170, !1172, !1168, !1184, !1200, !1209, + #1074, !1208] + +Contributors: + Marco Trevisan (Treviño), Laurent Bigonville, Jonas Dreßler, Olivier Fourdan, + Carlos Garnacho, Andre Moreira Magalhaes, Simon McVittie, + Georges Basile Stavracas Neto, Pekka Paalanen, Christian Rauch, Jonas Troeger, + Daniel van Vugt, Phillip Wood, Jonas Ådahl + +Translators: + Dušan Kazik [sk], Christian Kirbach [de] + +3.36.1 +====== +* Fix hardware cursor on GPU hotplpug [Pekka; !1097] +* Fix black areas around XWayland windows when resizing [Robert, Olivier; !1091] +* Fix applying wrong scale to monitors on X11 [Jonas; !1118] +* Fix moving/resizing windows via keyboard on wayland [Alynx; !997] +* Fix locate-pointer feature interfering with keybindings [Carlos; !1014] +* Add support for middle-click emulation [Andrew; !256] +* Fix freeze when moving cursor between scaled monitors [Robert; !1125] +* Fix popup misplacement with focus-follows-mouse [Jonas Å.; !1122] +* Fix misplaced cursor in preedit strings [Carlos; !1132] +* Support mirroring with proprietary Nvidia driver [Jonas Å.; !1098] +* Support tablets with multiple mode switch buttons in a group [Carlos; !970] +* Ignore foreground color for color glyphs (emojis) [Carlos; !1148] +* Allow pad mode switches while showing OSD [Carlos; !975] +* Fix positioning of OSD for display-attached tablets [Carlos; !971] +* Respect configured RANDR panning on X11 [Jonas Å.; !1085] +* Use correct texture filtering with scaled displays [Jonas; !1124] +* Fix cursor hotspots in virtual machines [Jonas Å.; !1136] +* Fix build with GLES and no GL [Georges; !1151] +* Work around Firefox bug when copying images on wayland [Robert; !1141] +* Fix wrong cursor rotation on rotated displays [Hans; !1153] +* Fix glitches in window screencasts [Georges; !1129] +* Fix IM support for deleting surrounding text [Takao, Carlos; #539] +* Fix map animation of maximized windows [Robert; !1164] +* Fixed crashes [Jonas Å., Carlos, Florian, Robert; !1120, !1121, + #917, #1132, #1083, !1147, #1147] +* Misc. bug fixes and cleanups [Jonas Å., Olivier, Mart, Sebastian, Corentin, + Andre, Daniel, Robert, Carlos, Peter, Georges, Jonas D., Florian, Christian; + !1115, !1102, !1104, !1106, !1117, !1119, !1101, !1123, #1124, !1130, !1131, + !1133, #1065, !1108, !1144, !1145, !1109, !1059, !1107, !999, !1152, #1128, + !1155, !1156, !1158, !1157, #1146, !1161, !1163] + +Contributors: + Jonas Dreßler, Olivier Fourdan, Takao Fujiwara, Carlos Garnacho, Andrew Gaul, + Hans de Goede, Peter Hutterer, Sebastian Keller, Robert Mader, + Andre Moreira Magalhaes, Florian Müllner, Georges Basile Stavracas Neto, + Corentin Noël, Pekka Paalanen, Christian Rauch, Mart Raudsepp, + Daniel van Vugt, Alynx Zhou, Jonas Ådahl + +Translators: + Марко Костић [sr], Daniel Șerbănescu [ro] + +3.36.0 +====== +* Fix placement of popup windows in multi-monitor setups [Jonas; !1110] +* Fix invisible mouse cursor on some hardware [Jonas; !1079] + +Contributors: + Jonas Ådahl + +Translators: + Aurimas Černius [lt], Goran Vidović [hr], Anders Jonsson [sv], + Guillaume Bernard [fr], Milo Casagrande [it], Daniel Korostil [uk], + Andre Klapper [cy], Aman Alam [pa], Nathan Follens [nl] + +3.35.92 +======= +* Fix visibility of initially hidden windows [Jonas Å.; !1066] +* Avoid flicker when (un)redirecting windows [Sebastian; #997] +* Let BindConstraints update the preferred size [Emmanuele; !1070] +* Learn about GLES3 [Adam; !882] +* Ping windows on every window focus [Jonas D.; !891] +* Remove overhead from hot code paths [Christian; + #1056, !1081, !1083, !1071, !1087] +* Allow remote desktop services to inhibit animations [Jonas Å.; !838] +* Update screen-cast code to PipeWire 0.3 API [Wim; !1062] +* Make check-alive timeouts configurable [Jonas Å.; !1080] +* Make each stage view correspond to a single CRTC [Jonas Å.; !1042] +* Implement scaled/transformed hardware cursors [Robert; !526] +* Use DMA buffers for screencasting if possible [Georges; !1086] +* Make Xwayland startup asynchronous [Carlos; !944] +* Fix clipping glitches in long text entries [Jonas D.; !1096] +* Add side channel for starting required X11 services [Carlos; !945] +* Support synchronized wayland popup moving [Jonas Å.; !705] +* Fixed crashes [Olivier, Jonas Å.; !1073, !1093] +* Plugged memory leaks [Sebastian, Jonas Å.; !1089, !1095] +* Misc. bug fixes and cleanups [Jonas Å, Olivier, Florian, Daniel, Jonas D., + Robert, Sebastian, Christian, Arun, Carlos, worldofpeace; !1061, #1043, + !1067, !1068, !1065, !835, !1058, !1069, !1075, #1060, !1077, !423, !1090, + !1088, !1094, #1067, !1064, !1099, !957, !1000, !1082] + +Contributors: + Emmanuele Bassi, Jonas Dreßler, Olivier Fourdan, Carlos Garnacho, + Christian Hergert, Adam Jackson, Sebastian Keller, Robert Mader, + Florian Müllner, Georges Basile Stavracas Neto, Arun Raghavan, Wim Taymans, + Daniel van Vugt, worldofpeace, Jonas Ådahl + +Translators: + Yi-Jyun Pan [zh_TW], Asier Sarasua Garmendia [eu], Rafael Fontenelle [pt_BR], + Emin Tufan Çetin [tr], Daniel Mustieles [es], Balázs Úr [hu], + Gwan-gyeong Mun [ko], Marek Černocký [cs], Fran Dieguez [gl], + Kukuh Syafaat [id], Alan Mortensen [da], Piotr Drąg [pl], sicklylife [ja], + Matej Urbančič [sl] + +3.35.91 +======= +* Honor accelerometer orientation on monitor config changes [Hans; !959] +* Enable culling for integer-scaled actors [Robert; !1036] +* Add ClutterSeat::touch-mode property [Carlos; !1044] +* Fix mis-scaling when streaming windows [Olivier; !1022] +* Make the cursor renderer use the transactional KMS API [Jonas; !930] +* Advertise MetaMonitor as wl_output [Olivier; !994] +* Fix culling of XWayland windows [Robert; !1049] +* Only consider enabled effects when disabling culling [Robert; !1052] +* Misc. bug fixes and cleanups [Olivier, Sergio, Adam, Carlos, Björn; !1040, + #985, !1024, !1039, !1051] + +Contributors: + Sergio Costas, Björn Daase, Olivier Fourdan, Carlos Garnacho, Hans de Goede, + Adam Jackson, Robert Mader, Jonas Ådahl + +Translators: + sicklylife [ja] + +3.35.90 +======= +* Cull out clip region [Robert; !985] +* Always enable tap-to-click/drag on opaque Wacom tablets [Carlos; !968] +* Fix visual glitches with offscreen effects applied [Georges; !992] +* Fix "sticky corner" in multi-head setups [Jonas D.; #774] +* Fix black shadows around XWayland windows during resizes [Ray, Olivier; #858] +* Zero-copy path for GPU-less secondary GPUs [Pekka; !810] +* Cancel DND on Esc [Carlos; #1020] +* Sync XWayland window shadows to frame during resizes [Olivier; !1009] +* Add support for per-monitor workareas [Alberts; !370] +* Ensure newly mapped wayland windows receive ENTER event [Olivier; !1026] +* Add ClutterSeat object [Carlos; !852] +* Honour CLUTTER_ACTOR_NO_LAYOUT flag more efficiently [Daniel; !575] +* Fix interoperation with wl_data_device_manager v1 [Carlos; #965] +* Favor text over images in clipboard manager [Carlos; #919] +* Apply monitor scale after background texture creation [Daniel; !1004] +* Plugged memory leaks [Sebastian, Adam; !991, #1000, !1011, !1020, !1030, + !1001, !1033] +* Fixed crashes [Jonas Å., Florian, Olivier; !961, #1029, !1037] +* Misc. bug fixes and cleanups [Björn, Jonas Å., Adam, Sebastian, Jonas D., + Daniel, Carlos, Corentin, Sebastian, Robert, Daniel; #385, !998, !1007, !995, + !1016, !1018, !1017, !1005, !1019, !1025, !1028, !1029, !1031, !1015, !1032, + !1034, #1025] + +Contributors: + Björn Daase, Jonas Dreßler, Olivier Fourdan, Carlos Garnacho, Adam Jackson, + Sebastian Keller, Robert Mader, Alberts Muktupāvels, Florian Müllner, + Georges Basile Stavracas Neto, Corentin Noël, Pekka Paalanen, Ray Strode, + Daniel van Vugt, Jonas Ådahl + +Translators: + sicklylife [ja], Umarzuki Bin Mochlis Moktar [ms] + +3.35.3 +====== +* backends/native: Correct dy value in pinch gesture event [Yariv; !974] +* Upload clipping rectangles in parallel [Daniel; !969] +* More cogl API cleanups [Adam; !978, !977, !973] +* Fix window recording on HiDPI [Pascal; !976] +* Fix top-left pixel being insensitive to clicks [Sebastian; #893] +* Misc. bug fixes and cleanups [Daniel, Adam; !979, !980] + +Contributors: + Yariv Barkan, Adam Jackson, Sebastian Keller, Pascal Nowack, Daniel van Vugt + +Translators: + Fran Dieguez [gl], Dz Chen [zh_CN] + +3.35.2 +====== +* Don't emit focus event after destruction [Marco; gnome-shell#1704, !860] +* Add a notion of pixel format planes [Niels; !858] +* Replace various Cogl/Clutter types with Graphene [Georges; !458] +* Improve CoglJournal [Georges, Jasper; !402] +* Split pick and paint [Georges; !865] +* Remove deprecated/unused cogl/clutter APIs [Adam; !866, !878, !879, !880, + !885, !900, !902, !904, !896, !913, !922, !883, !903, !921, !933, !819] +* Fix hang when opening not-responding dialog on Xorg [Carlos; !876] +* Allow changing Clutter debug flags at runtime [Georges; !862] +* Fix frozen grabs on Xorg after weeks of inactivity [Jonas; !886] +* Fix triggering popups from stylus devices o wayland [Carlos; #886] +* Fix fallback to GLES2 [Adam; #635] +* Fix buffer age checks on multiple monitors [Carlos; !906] +* Adjust to Sysprof API change [Christian; !908] +* Improve support for (X11) fullscreen games under wayland [Hans; !739] +* Support shadow framebuffers for offscreen rendering [Olivier; !877] +* Fix hang after interacting with desktop icons on X11 [Marco; !909] +* Don't double scale when getting absolute surface coordinates [Xiang; !915] +* Respect NET_WM_TRANSIENT_FOR for override-redirect windows [Marco; !920] +* Kill window effects on destroy [Robert; !924] +* Remove deprecated ClutterTexture [Jonas; !932] +* Use regions instead of bounding box for clipping and culling [Carlos; !867] +* Use partial damage for dma-buf and EGLImage buffers on wayland [Robert; #947] +* Do not stack transients underneath their always-on-top parent [Florian; #587] +* Add explicit paint/pick contexts [Jonas; !935] +* Fix KMS freeze after pageflip fallback [Pekka; !953] +* Fixed crashes [Robert, Carlos, Jonas, Marco, Hans, Tim; !856, !869, !912, + !895, !928, #591, !823, !960] +* Plugged memory leaks [Niels, Robert, Carlos, Marco; !847, !868, !873, #908] +* Misc. bug fixes and cleanups [Niels, Robert, Jonas, Marco, Carlos, Daniel, + Jan, Adam, Cosimo, Florian, Thomas, Georges, Hans, Corentin, Christian, + Benjamin; !853, !822, !451, !854, !816, !857, !859, !734, !844, !851, #876, + !874, !673, !692, !888, !889, !894, !901, !905, !872, !898, !911, !918, !863, + #878, !811, !893, !925, !926, !890, !931, !927, !934, !938, !940, !947, !941, + !929, !949, !952, !871, !955, !956, !958, !907, !965, !964, !966] + +Contributors: + Marco Trevisan (Treviño), Jan Alexander Steffens (heftig), + Thomas Hindoe Paaboel Andersen, Benjamin Berg, Cosimo Cecchi, Tim Crawford, + Piotr Drąg, Xiang Fan, Olivier Fourdan, Carlos Garnacho, Hans de Goede, + Niels De Graef, Christian Hergert, Adam Jackson, Robert Mader, + Florian Müllner, Georges Basile Stavracas Neto, Bastien Nocera, Corentin Noël, + Pekka Paalanen, Jasper St. Pierre, Christian Rauch, Daniel van Vugt, + Jonas Ådahl + +Translators: + Bruce Cowan [en_GB] + +3.35.1 +====== +* Fix immediate screen blank after releaseing inhibitor [Tim; #573] +* Respond to frame callbacks regardless of damage [Jonas; !839] +* selection [Carlos; !842] +* Fix Night Light on wayland [Jonas; !840] +* Fix various copy+paste/DND regressions [Carlos; !848, #789, #842, + #793, #845, #854] +* Misc. bug fixes and cleanups [Daniel, Marco, Jonas, Georges; + !841, !764, !837, !846] + +Contributors: + Marco Trevisan (Treviño), Carlos Garnacho, Tim Klocke, + Georges Basile Stavracas Neto, Daniel van Vugt, Jonas Ådahl + +3.34.1 +====== +* Fix startup of X11 session services on wayland [Carlos; #771] +* Fix _NET_ACTIVE_WINDOW emission [Carlos; #751] +* Fix initial view perspective [Marco; !803] +* Fix screenshots and window animations when scaled [Robert; !758] +* Re-enable coredumps when capabilities are set [Jonas; !811] +* Fix scaling of DND surface actors [Robert; !780] +* Optimize blitting of untransformed offscreen stage views [Olivier; !809, !820] +* Fix freeze of pointer event delivery on X11 [Olivier; !821] +* Fix scaling of stylus input coordinates with HiDPI [Dorian; !830] +* Fix memory leak when using implicit animations [Jonas; !828] +* Fix numlock state for native backend [Carlos; #769] +* Fixed crashes [Marco, Olivier, Jonas Å.; !805, #823, !808, !825, + #844, !826, #779] +* Misc. bug fixes and cleanups [Jonas Å., Georges, Jonas D., Michal, Daniel, + Iain, Adam, Marco, Carlos, Ting-Wei, Hans, Robert; !787, !795, !791, !797, + !772, !775, !799, !778, !785, !782, !796, #819, !814, !769, !817, !783, !786, + !829, !774, #822] + +Contributors: + Marco Trevisan (Treviño), Jonas Dreßler, Olivier Fourdan, Carlos Garnacho, + Hans de Goede, Adam Jackson, Ting-Wei Lan, Iain Lane, Michal Lazo, + Robert Mader, Georges Basile Stavracas Neto, Dorian Stoll, Daniel van Vugt, + Jonas Ådahl + +Translators: + Milo Casagrande [it], Nathan Follens [nl], Matej Urbančič [sl], + Ask Hjorth Larsen [da], Alan Mortensen [da], Jordi Mas [ca] + +3.34.0 +====== +* Fix xdg-output v3 support [Olivier; !771] +* Fix crash when changing decoration state [Jonas; !773] +* Add and remove connectors on hot-plug [Jonas; !743] + +Contributors: + Olivier Fourdan, Jonas Ådahl + +Translators: + Rafael Fontenelle [pt_BR], Gwan-gyeong Mun [ko], Christian Kirbach [de], + Claude Paroz [fr], Milo Casagrande [it], Emin Tufan Çetin [tr], + Ryuta Fujii [ja] + +3.33.92 +======= +* Turn MetaShapedTexture into a ClutterContent implementation [Georges; !409] +* Restore inhibit shortcut for overlay key [Olivier; #734] +* Misc. pointer a11y improvements [Jonas D., Olivier; !746, !747, !745, !761] +* Fix position of drag surfaces [Robert; !684] +* Implement subsurface.place_below() for parents [Robert; !664] +* Add meta_window_actor_get_image() [Jonas Å.; !752] +* Revert faulty optimization from !719 [Jonas Å.; #735] +* Add additional sysprof trace points [Jonas Å.; !757, !765] +* Remove GLX "threaded swap wait" used on Nvidia [Daniel; !602] +* Implement geometric picking [Daniel; !189] +* Fix lost keyboard focus after DND [Olivier; #747] +* Misc. bug fixes and cleanups [Florian, Carlos, Piotr, Hans, Georges, Robert, + Ray, Mart, Rémi; !740, !672, !749, !751, !753, !730, !755, !756, !750, !715, + #738944, !657, !768] + +Contributors: + Jonas Ådahl, Rémi Bernon, Piotr Drąg, Jonas Dreßler, Olivier Fourdan, + Carlos Garnacho, Hans de Goede, Robert Mader, Florian Müllner, + Georges Basile Stavracas Neto, Mart Raudsepp, Ray Strode, Daniel van Vugt + +Translators: + Piotr Drąg [pl], Марко Костић [sr], Rūdolfs Mazurs [lv], Matej Urbančič [sl], + Balázs Úr [hu], Fran Dieguez [gl], Jordi Mas [ca], Anders Jonsson [sv], + Trần Ngọc Quân [vi], Tim Sabsch [de], Fabio Tomat [fur], Goran Vidović [hr], + Marek Černocký [cs] + +3.33.91 +======= +* Fix primary selection copy and paste between X11 and wayland [Hans; #702] +* Improve monitor hotplug support [Hans; !713] +* Remove a source of frame skips [Daniel; !719] +* Fix windows being lowered after unmaximizing with double click [Olivier; #88] +* Remove Clutter API for global grabs [Jonas D.; !536] +* Improve processing of incompressible events [Daniel; !711] +* Add xdg-output v3 support [Olivier; !704] +* Misc. bug fixes and cleanups [Jonas Å., Marco, Carlos, Adam, Albert, Niels, + Olivier, Florian; !722, !385, !728, !726, !500, !731, !727, !700, !735, !738] + +Contributors: + Jonas Ådahl, Albert Vaca Cintora, Jonas Dreßler, Olivier Fourdan, + Carlos Garnacho, Hans de Goede, Niels De Graef, Adam Jackson, Florian Müllner, + Marco Trevisan (Treviño), Daniel van Vugt + +Translators: + Asier Sarasua Garmendia [eu], Kukuh Syafaat [id], Florentina Mușat [ro], + Aurimas Černius [lt], Daniel Mustieles [es] + +3.33.90 +======= +* Fix visibility of clones with hidden source [Florian; #683] +* Reduce freezes when opening some popup windows [Carlos; #556] +* Be more thorough when excluding obscured areas from painting [Carlos; !698] +* Make it possible to start Xwayland on demand [Carlos; !709] +* clutter: Expose layout_manager to transitions [Florian; !716] +* Misc. bug fixes and cleanups [Mark, Florian, Iain, Niels, Carlos, Ray; !671, + !691, !694, !696, !703, !707, !697, !710, !708, !714, #719, !721] + +Contributors: + Mark Blakeney, Carlos Garnacho, Niels De Graef, Iain Lane, Florian Müllner, + Ray Strode + +Translators: + Asier Sarasua Garmendia [eu], Rafael Fontenelle [pt_BR], Fabio Tomat [fur], + Florentina Mușat [ro] + +3.33.4 +====== +* Discard page flip retries on hotplug [Jonas; !630] +* Add xdg-output v2 support [Olivier; #645] +* Restore DRM format fallbacks [Jonas; !662] +* Don't emit ::size-changed when only position changed [Daniel; !568] +* Expose workspace layout properties [Florian; !618] +* Don't use grab modifiers when shortcuts are inhibited [Olivier; #642] +* Fix stuttering due to unchanged power save mode notifications [Georges; !674] +* Add API to reorder workspaces [Adam; !670] +* Make picking a new focus window more reliable [Marco; !669] +* Defer actor allocation till shown [Carlos; !677] +* Try to use primary GPU for copy instead of glReadPixels [Pekka; !615] +* Unset pointer focus when the cursor is hidden [Jonas D.; !448] +* Fix modifier-drag on wayland subsurfaces [Robert; !604] +* Fix background corruption on Nvidia after resuming from suspend [Daniel; !600] +* Only grab the locate-pointer key when necessary [Olivier; !685, #647] +* Misc. bug fixes and cleanups [Florian, Jonas, Daniel, Robert, Olivier, + Georges, Marco, Carlos, Emmanuele; !648, !650, !647, !656, !658, !637, + !663, !660, !659, !665, !666, !668, !667, #667, !676, !678, #672, !680, + !683, !688, !689, !687] + +Contributors: + Jonas Ådahl, Emmanuele Bassi, Adam Bieńkowski, Piotr Drąg, Jonas Dreßler, + Olivier Fourdan, Carlos Garnacho, Robert Mader, Florian Müllner, + Georges Basile Stavracas Neto, Pekka Paalanen, Marco Trevisan (Treviño), + Daniel van Vugt + +Translators: + Fabio Tomat [fur], Kukuh Syafaat [id] + +3.33.3 +====== +* Prepare for running Xwayland on demand [Carlos; !420] +* Fix text selection color rendering [Florian; #494] +* Fix black shadows when using fractional scaling [Robert; #609] +* Honor startup sequence workspace on wayland [Carlos; gnome-shell#674] +* Only emit 'grab-op-end` signal after dropping grabs [Marco; !596] +* Add a Sysprof-based profiler [Jonas, Georges; !197, !603] +* Relax "xwayland-allow-grabs" setting [Olivier; #597] +* Implement locate-pointer accessibility feature [Olivier; !453] +* Implement mouse accessibility [Olivier; !512] +* Consolidate frame throttling [Daniel, Georges; !363] +* Fix setting blank cursor under wayland [Jonas; #630] +* Pixel-align OpenGL cursors [Jonas; !610] +* Handle returning from fullscreen/maximization better [Jonas; !621] +* Improve screencast support on multi-monitor systems [Georges; !623] +* Fix running X11 applications with sudo under wayland [Hans; #643] +* Implement toggle-keys notification [Olivier; #637] +* Add initial KMS transactional support [Jonas; !525] +* Improve finding new focus window when the old one is closed [Marco; #308] +* Misc. bug fixes and cleanups [Jonas, Carlos, Marco, Florian, Pekka, Robert, + Douglas, Georges, Daniel, Emil, Niels, Hans, Olivier, Ting-Wei, Corentin; + !591, #398, !592, !581, !597, !598, !593, !497, #591, !545, gtk#1675, !601, + #568, !564, !605, !609, !115, !214, !611, !617, !616, !619, !624, !622, !627, + !628, !629, !632, !633, !631, !636, !639, !638, !634, !640, !529, !644, !590] + +Contributors: + Jonas Ådahl, Piotr Drąg, Olivier Fourdan, Carlos Garnacho, Hans de Goede, + Niels De Graef, Ting-Wei Lan, Robert Mader, Florian Müllner, + Georges Basile Stavracas Neto, Corentin Noël, Pekka Paalanen, Douglas R. Reno, + Marco Trevisan (Treviño), Emil Velikov, Daniel van Vugt + +Translators: + Balázs Úr [hu], Daniel Mustieles [es], Nathan Follens [nl], Goran Vidović [hr] + +3.33.2 +====== +* Fix rendering lag on Xorg [Daniel; !520, !281] +* Misc. bug fixes and cleanups [Carlos, Marco, Jonas D., Florian, Niels, + Daniel, Benjamin, Jonas Å., Ignacio, Vasilis; #598, !576, !547, !578, + !583, !582, !469, !524, !119, !571, !584, !585, !586, #425] + +Contributors: + Jonas Ådahl, Benjamin Berg, Jonas Dreßler, Carlos Garnacho, Niels De Graef, + Vasilis Liaskovitis, Florian Müllner, Ignacio Casal Quinteiro, + Marco Trevisan (Treviño), Daniel van Vugt + +Translators: + Daniel Mustieles [es] + +3.33.1 +====== +* Remove unused APIs and outdated driver support + [Adam; !481, !468, !489, !487, !546] +* Enable EGL_IMG_context_priority [Adam; !454] +* Disable mouse keys with Numlock on [Olivier; #530] +* Fix crash when restarting on X11 [Marco; #576] +* Implement clipboard manager [Carlos; !320] +* Fix spurious idle signals that prevent session unblank [Jonas Å.; !543] +* Fix mapping of touchscreens that don't report dimensions [Carlos; #581] +* Fix propagating fractional scaling factor [Robert; !537] +* Add experimental RT scheduling support [Carlos; !460] +* Misc. bug fixes and cleanups [Robert, Carlos, Olivier, Ray, Marco, Jonas D., + Georges, Daniel V., Daniel M; !467, !504, !551, !552, #575, #556, !557, !442, + !562, !535, !548, #586, !567, !396, !422, !507] + +Contributors: + Jonas Ådahl, Piotr Drąg, Jonas Dreßler, Olivier Fourdan, Carlos Garnacho, + Adam Jackson, Robert Mader, Daniel García Moreno, Florian Müllner, + Georges Basile Stavracas Neto, Ray Strode, Marco Trevisan (Treviño), + Daniel van Vugt + +Translators: + Daniel Mustieles [es], Fabio Tomat [fur], Kukuh Syafaat [id] + +3.32.1 +====== +* Fix fallback app menu on wayland [Florian; #493] +* Fix elogind support [Tom; !491] +* Fix startup notifications not timing out [Carlos; #501] +* Fix keyboard accessibility toggle from keys + [Olivier, Carlos; !501, #529, !531] +* Fix touchscreen input on rotated displays [Carlos; #514] +* Work around hangul text input bug [Carlos; #1365] +* Fix blurry wallpaper scaling [Daniel; !505] +* Fix placement of window menu when using fractional scaling [Jan; #527] +* Fix repaint issues of offscreen effects on secondary monitors [Daniel; !511] +* Fix windows not getting focus after launch [Daniel; #505] +* Properly advertise support for 'underscan' property [Jonas; !507] +* Improve power-saving handling [Jonas; !506] +* Fix moving windows by super+touch [Jonas D.; !495] +* Misc. bug fixes and cleanups [Benjamin, Florian, Adam, Marco, Pablo, + Erik, Jonas, Heiher, Pekka, Daniel, Olivier, Carlos; !478, !475, !480, + !482, #490, !488, #491, #480, !477, !496, !492, !485, !515, !519, !521, + !216, !538, #541, #523] + +Contributors: + Jonas Ådahl, Pablo Barciela, Benjamin Berg, Tom Briden, Jonas Dreßler, + Olivier Fourdan, Carlos Garnacho, Jan Alexander Steffens (heftig), Heiher, + Adam Jackson, Erik Kurzinger, Florian Müllner, Pekka Paalanen, + Marco Trevisan (Treviño), Daniel van Vugt + +Translators: + Khaled Hosny [ar], Goran Vidović [hr], Daniel Mustieles [es] + +3.32.0 +====== +* Fix deadlock when cancelling a theme sound [Andrea; !474] +* Stop swizzling BGRA buffers (bye-bye inverted colors in screenshots + and animations) [Carlos; !486] + +Contributors: + Andrea Azzarone, Carlos Garnacho, Robert Mader + +3.31.92 +======= +* Fix flicker of apps that use multiple SHM buffers [Jonas Å.; #199] +* Don't disable page flips after temporary failues [Jonas Å.; #460] +* Improve redraw performance [Carlos; !196] +* Add cursor-mode support to window screencasting [Jonas Å.; !413] +* Add back support for system-wide monitor configurations [Jonas Å.; !253] +* Add fractional scaling support [Marco, Jonas Å.; !3] +* Consider remapped keys when guessing keycode from keysym [Andrea; #443] +* Stop turning on-screen-keyboard off on focus changes [Carlos; !432] +* Fix crashes [Robert, Carlos, Jonas D., Florian; !447, #361, !426, #479] +* Misc. bug fixes and cleanups [Benjamin, Adam, Olivier, Niels, Piotr; !457, + !452, !459, !380, !361, !461, !464, !471, !473, !463] + +Contributors: + Jonas Ådahl, Andrea Azzarone, Benjamin Berg, Piotr Drąg, Jonas Dreßler, + Olivier Fourdan, Carlos Garnacho, Niels De Graef, Adam Jackson, Robert Mader, + Florian Müllner, Marco Trevisan (Treviño) + +Translators: + Milo Casagrande [it], Tim Sabsch [de], Trần Ngọc Quân [vi], + Gwan-gyeong Mun [ko], Марко Костић [sr], Daniel Mustieles [es], + Rūdolfs Mazurs [lv], Nathan Follens [nl] + +3.31.91 +======= +* Fix infinite loop in EDID matching [Marco; #459] +* wayland: Don't resetin text-input state prematurely [Carlos; !410] +* wayland: Don't maximize windows if minimum size is too big [Olivier; #463] +* Fix crash when using "restore shortcuts" without focus window [Olivier; #464] +* Add flag parameter to grab accelerator API [Andrea; !169] +* Reuse old CRTC if possible to avoid flicker on hotplug [Pekka, Emilio; #373] +* Misc. bug fixes and cleanups [Marco, Jonas, Niels, Adam, Olivier; !436, + !421, #462, !439, !440, !444, !321, !445, !456] + +Contributors: + Jonas Ådahl, Andrea Azzarone, Olivier Fourdan, Carlos Garnacho, + Niels De Graef, Adam Jackson, Emilio Pozuelo Monfort, Pekka Paalanen, + Marco Trevisan (Treviño) + +Translators: + Jiri Grönroos [fi], Charles Monzat [fr], Claude Paroz [fr], Fran Dieguez [gl], + Emin Tufan Çetin [tr], Aurimas Černius [lt], Anders Jonsson [sv], + Matej Urbančič [sl], Marek Cernocky [cs], Daniel Șerbănescu [ro], + Alan Mortensen [da], Baurzhan Muftakhidinov [kk], Yi-Jyun Pan [zh_TW], + Daniel Mustieles [es], Rafael Fontenelle [pt_BR] + +3.31.90 +======= +* Fix support of extended characters in on-screen keyboard [Andrea; #109] +* Improve selection of the primary GPU [Pekka, Emilio; !271] +* Screen-cast cursor updates as PipeWire stream metadata [Jonas; !357] +* Fix rendering glitches in magnifier [Daniel; gnome-shell#387] +* Fix monitor recording on HiDPI [Jonas; !415] +* Honour secondary GPU supported pixel formats [Pekka; !341] +* Fall back to CPU copy path when using a software renderer [Emilio; !325] +* Remove fallback app menu [Florian; gnome-shell#624] +* wayland: Add support for viewporter protocol [Robert; !323] +* Misc. bug fixes and cleanups [Florian, Carlos, Olivier, Marco, Robert, + Daniel, Pekka, Jonas, Ole, Georges; !391, #335, #442, !406, !395, #447, + !375, gnome-shell#349, #451, !416, #784199, !408, !181, !405] + +Contributors: + Jonas Ådahl, Andrea Azzarone, Ole Jørgen Brønner, Piotr Drąg, Olivier Fourdan, + Dariusz Gadomski, Carlos Garnacho, Antoine Jacoutot, Iain Lane, Robert Mader, + Emilio Pozuelo Monfort, Florian Müllner, Georges Basile Stavracas Neto, + Pekka Paalanen, Marco Trevisan (Treviño), Josh Triplett, Daniel van Vugt + +Translators: + Fabio Tomat [fur], Balázs Úr [hu], Daniel Mustieles [es], Kukuh Syafaat [id], + Jordi Mas [ca], Piotr Drąg [pl] + +3.31.4 +====== +* keybindings: Limit corner move to current monitor [Jānis; #320] +* xdg-output: Report rotated physical dimensions [Olivier; #369] +* Add continuous integration pipeline [Jonas; #193] +* Improve performance on secondary GPUs [Pekka; #323, !313] +* Use the actual hardware refresh rate [Daniel; #781296] +* Remove hide-titlebar-when-maximized support [Florian; !221] +* wayland: Implement buffer transforms [Robert; !322] +* Remove ability to externally set sync-to-vblank [Georges; !191] +* Turn off touchscreens together with DPMS [Carlos; gnome-settings-daemon#29] +* Mipmap the wallpaper when shrinking [Daniel; gnome-shell#254] +* Implement RecordWindow method for screen-casts [Olivier; !306] +* Fix EGLStream texture downloading [Jonas; !362] +* Split out display-server-specific code from MetaWindowActor [Georges; !368] +* Improve render performance on some KMS devices with software GL [Jonas; #106] +* Fix damage area of transformed surfaces [Robert; !366] +* Remove autotools support [George] +* Misc. bug fixes and cleanups [Jonas, Alan, Olivier, Carlos, Javier, Peter, + Daniel, Robert, Florian; !309, #790207, #272, #393, #276, #404, #104, !343, + #765011, #786663, #342, !356, #414, #782344, #781034, #423, !374, !382, !383] + +Contributors: + Jonas Ådahl, Nikita Churaev, Alan Coopersmith, Jānis Džeriņš, Olivier Fourdan, + Carlos Garnacho, Niels De Graef, Peter Hutterer, Javier Jardón, + Abderrahim Kitouni, Andre Klapper, Ting-Wei Lan, Robert Mader, + Emilio Pozuelo Monfort, Florian Müllner, Georges Basile Stavracas Neto, + Pekka Paalanen, Daniel Stone, Marco Trevisan (Treviño), Daniel van Vugt + +3.31.2 +====== +* Fix handling of non-UTF8 encodings [Florian; !227] +* Fix memory leaks introduced in 3.30.1 [Jonas; #653] +* Fix regression when overriding workspace layout [Ron; #270] +* Fix crash when restarting window manager [Andrea; gnome-shell#595] +* Add meson build support [Jonas; !167] +* Freeze clock when headless [Jonas; !170] +* Fix crash on monitor hotplug [Olivier; #189] +* Misc. bug fixes [Jonas; #353, !132, #382] + +Contributors: + Jonas Ådahl, Andrea Azzarone, Olivier Fourdan, Niels De Graef, + Alexander Mikhaylenko, Florian Müllner, Akira Nakajima, + Georges Basile Stavracas Neto, Pekka Paalanen, Peter Uithoven, + Daniel van Vugt, Ron Yorston + +3.30.1 +====== +* Improve trackball detection [Tony; #258] +* Fix clipping of scaled surfaces [Jonas; #300] +* Improve tracking of monitor switch configuration [Daniel; !213] +* Fix parent-relative positioning of constrained windows [Jonas; #332] +* Add clutter_input_method_forward_key() method [Carlos; gnome-shell#531] +* Various crash fixes [Olivier, Jonas; #194, #336] +* Misc. bug fixes [Carlos, Florian, Olivier, Jonas; gnome-shell#540, #294, + #221, !229, #30, #331] + +Contributors: + Jonas Ådahl, Daniel Drake, Olivier Fourdan, Carlos Garnacho, Peter Hutterer, + Ting-Wei Lan, Florian Müllner, Tony Novak, Pekka Paalanen, Sam Spilsbury + +Translators: + Yuras Shumovich [be], Марко Костић [sr], Marek Cernocky [cs] + +3.30.0 +====== + +Translators: + Fran Dieguez [gl], Balázs Meskó [hu], Rūdolfs Mazurs [lv], + Trần Ngọc Quân [vi], Ask Hjorth Larsen [da], gogo [hr] + +3.29.92 +======= +* Avoid crash when a cursor is not found [Sebastian; #254] +* Fix screen rotation regression [Jonas; #216] +* Handle requests to unmanaged windows gracefully [Jonas; #240] +* Move popups together with their parent [Jonas; #274] +* Fix non-lowercase letters on virtual key devices [Carlos; gnome-shell#135] +* Misc. bug fixes [Iain, Jonas; #223, #192, #279] + +Contributors: + Jonas Ådahl, Carlos Garnacho, Sebastian Keller, Iain Lane, Robert Mader, + Daniel van Vugt + +Translators: + Gwan-gyeong Mun [ko], Kukuh Syafaat [id], Milo Casagrande [it], + Anders Jonsson [sv], Rafael Fontenelle [pt_BR], Marek Cernocky [cs] + +3.29.91 +======= +* Various crash fixes [Olivier, Iain; #255, #223] +* Fix lock up with some DRI drivers [Alex; #127] +* Send correct button codes from virtual evdev devices [Jonas; !190] +* Improve grab-device clock updates on X11 [Jeff; !174] +* Fix popups closing immediately on key down [Jonas; !180] +* Prevent clients from modifying the shared keymap [Jonas; #784206] + +Contributors: + Jonas Ådahl, Andrea Azzarone, Piotr Drąg, Olivier Fourdan, Carlos Garnacho, + Jan Grulich, Iain Lane, Alex Villacís Lasso, Jeff Smith, Daniel van Vugt + +Translators: + Matej Urbančič [sl], Mario Blättermann [de], Piotr Drąg [pl], + Aurimas Černius [lt], Yi-Jyun Pan [zh_TW], Emin Tufan Çetin [tr], + Fabio Tomat [fur], Bruce Cowan [en_GB] + +3.29.90 +======= +* Various crash fixes [Olivier, Jonas, Florian; #189, #70, #194, #15, #130] +* Don't expose resolutions that are below the minimum [Andrea; #793223] +* Remove support for preference overrides [Florian; #786496] +* Misc. bug fixes and cleanups [Daniel, Jonas, Florian; #131, #245, !176] + +Contributors: + Jonas Ådahl, Andrea Azzarone, Olivier Fourdan, Florian Müllner, Kevin Tamool, + Daniel van Vugt + +Translators: + Daniel Mustieles [es], Claude Paroz [fr] + +3.29.4 +====== +* Fix crash with parent-less modal dialogs [Olivier; #174] +* Preserve paint volumes where possible to optimize CPU usage [Carlos; #782344] + +Contributors: + Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, Iain Lane, Bastien Nocera + +Translators: + Daniel Șerbănescu [ro] + +3.29.3 +====== +* Fix Korean Hangul support on wayland [Changwoo; #152] +* Improve support for proprietary Nvidia driver [Jonas; #790316] +* Only upload HW cursor sprite to the GPU that will display them [Jonas; #77] +* Improve EGLstream support [Miguel; #2, #782575] +* Remove MetaScreen to prepare for non-mandatary X11 dependency + [Armin, Jonas; #759538] +* Misc. bug fixes [Olivier, Jonas, Sam; #160, !130, #786929, #788834] + +Contributors: + Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, Armin Krezović, Corentin Noël, + Changwoo Ryu, Sam Spilsbury, Daniel Stone, Marco Trevisan (Treviño), + Miguel A. Vico, Daniel van Vugt + +Translators: + Yi-Jyun Pan [zh_TW], Jordi Mas [ca], Daniel Șerbănescu [ro], Fabio Tomat [fur] + +3.29.2 +====== +* Fix size change animations on wayland [Georges; #780292] +* Handle touch events on server-side titlebars [Carlos; #770185] +* Misc. bug fixes [Florian, Olivier, Jonas, Georges; #134, #124, !96, #138, + !102, #781471, #150] + +Contributors: + Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, Florian Müllner, + Georges Basile Stavracas Neto, Marco Trevisan (Treviño), Daniel van Vugt + +Translators: + Daniel Șerbănescu [ro], Marcos Lans [gl], Dz Chen [zh_CN] + +3.29.1 +====== +* Fix various input-method regressions [Carlos, Olivier; #65, #74, #66, #112] +* Fix wayland build on FreeBSD [Ting-Wei; #792280, #792717] +* Fix swapped colors in screenshots (again) [Carlos; #72] +* Allow building with elogind [Rasmus; !46] +* Consider display rotation for cursor [Olivier; #85] +* Fall back to non-modifier GBM surfaces [Daniel; #84] +* Take inhibitors into account for monitoring idle [Bastien; #705942] +* Misc. bug fixes [handsome-feng, Olivier, Mario, Jonas; !45, #83, #104, + gnome-shell#157, #130, #21] + +Contributors: + Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, handsome-feng, Yussuf Khalil, + Ting-Wei Lan, Aleksandr Mezin, Alberts Muktupāvels, + Georges Basile Stavracas Neto, Bastien Nocera, Benjamin Otte, + Mario Sanchez Prada, Daniel Stone, Ray Strode, Rasmus Thomsen, + Marco Trevisan (Treviño), Daniel van Vugt + +Translators: + Emin Tufan Çetin [tr], Dušan Kazik [sk], Matej Urbančič [sl] + +3.28.0 +====== +* Fix xdg-foreign regression [Carlos; #63] + +Contributors: + Carlos Garnacho, Georges Basile Stavracas Neto + +Translators: + Marek Cernocky [cs], Ask Hjorth Larsen [da], Chao-Hsiung Liao [zh_TW], + Anders Jonsson [sv], Mart Raudsepp [et] + +3.27.92 +======= +* Fix use of modifiers with multi-GPU systems [Louis-Francis; #18] +* Add xdg-shell stable support [Jonas; #791938] +* Fix scaling of icons in titlebar buttons [Egmont; #23] +* Implement missing wacom functionality on X11 [Carlos; #48] +* Force 8-bit RGB config [Jonas; #2] +* Misc. bug fixes [Jonas, Olivier, Robert; #6, #27, #792203] + +Contributors: + Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, Egmont Koblinger, Robert Mader, + Bastien Nocera, Louis-Francis Ratté-Boulianne + +Translators: + Daniel Mustieles [es], Марко Костић [sr], Милош Поповић [sr@latin], + Fran Dieguez [gl], Balázs Úr [hu], Gwan-gyeong Mun [ko], Rūdolfs Mazurs [lv], + Milo Casagrande [it], Mario Blättermann [de], GNOME Translation Robot [gd, + nl], Claude Paroz [fr], Aurimas Černius [lt] + +3.27.91 +======= +* Fix handling of trackball settings on wayland [Carlos; #787804] +* Apply font settings on wayland [Daniel; #645433] +* Fix keybindings getting mixed up with some layouts [Jonas; #789300] +* Fix bluetooth mouse cursor disappearing after idle [Benoit; #761067] +* Support platforms that export EGL_KHR_platform_gbm [memeka; #780668] +* Add keyboard accessibility support on wayland [Olivier; #788564] +* Fix missing cursor when using screen magnifier [Carlos; #754806] +* Fix external monitor shutting off on wayland when lid closes [Jonas; #788915] +* Add xdg-output support [Olivier; #787363] +* Add Xwayland grab keyboard support [Olivier; #783342] +* Allow shortcut inhibition of the super key [Olivier; #790627] +* Take "panel orientation" drm_connector property into account [Hans; #782294] +* Fix focus window ending up below other windows on wayland [Olivier; #780820] +* Fix maximized windows restoring to a tiny size on wayland [Olivier; #783901] +* Fix tap-and-drag setting on X11 [Jonas; #775755] +* Fix handling of single-touch devices on wayland [Carlos; #792005] +* Support tiled/compressed buffers [Daniel; #785779] +* Port screencast support to pipewire 0.1.8 [Jonas; #792854] +* Add support for third stylus button on newer tablets [Jason; #790033] +* Fix background corruption regression on nvidia [Jonas; #739178] +* Misc. bug fixes [Jonas, Rui, Michael, Marco, Carlos, Olivier, Philip, Piotr, + Ting-Wei, Daniel, Jeremy, Hans, Florian, Ray, Jeff, George, Gwan-gyeong; + #789153, #788493, #784314, #789227, #789223, #789277, #782344, #789552, + #789553, #788695, #789984, #788764, #789386, #784545, #790336, #790358, + #791022, #791006, #789070, #772218, #791383, #791809, #776220, #791916, + #792281, #790309, #791371, #792527, #792599, #788834, #792765, #792062, + #645460, #792853, !2, #792818, #8, #12, #789501, #10, #789961, #13, !15, #1, + #26, #28, #35, #36, #38] + +Contributors: + Jonas Ådahl, Jeremy Bicha, Michael Catanzaro, Piotr Drąg, Olivier Fourdan, + Carlos Garnacho, Jason Gerecke, Hans de Goede, Benoit Gschwind, + Peter Hutterer, George Kiagiadakis, Ting-Wei Lan, Rui Matos, memeka, + Florian Müllner, Gwan-gyeong Mun, Jeremy Nickurak, Marc-Antoine Perennou, + Jeff Smith, Daniel Stone, Ray Strode, Marco Trevisan (Treviño), + Daniel van Vugt, Philip Withnall + +Translators: + Khaled Hosny [ar], Kjartan Maraas [nb], Piotr Drąg [pl], + Rafael Fontenelle [pt_BR], Christian Kirbach [de], Anders Jonsson [sv], + Charles Monzat [fr], Marek Cernocky [cs], Muhammet Kara [tr], + Milo Casagrande [it], Pawan Chitrakar [ne], Yosef Or Boczko [he], + Kukuh Syafaat [id], Daniel Mustieles [es], Fabio Tomat [fur], + Kristjan SCHMIDT [eo], Balázs Úr [hu], Andika Triwidada [id], + Fran Dieguez [gl], gogo [hr] + +3.27.1 +====== +* Work with clients that require older linux_dmabuf protocol [Daniel; #788558] +* Support hybrid GPU systems [Jonas; #785381] +* Prevent crash when closing maximized windows [Jonni; #788666] +* Use the correct monitor for HiDPI scaling of shell chrome [Jonas; #788820] +* Fix unredirection of fullscreen windows [Rui, Jonas; #788493] +* Fix list of supported monitor scales on X11 [Jonas; #788901] +* Misc. bug fixes [Florian, Jonas, Marco; #788572, #788569, #788607, #788860, + #788921] + +Contributors: + Jonas Ådahl, Carlos Garnacho, Rui Matos, Florian Müllner, Daniel Stone, + Marco Trevisan, Jonni Westphalen + +Translations: + Xavi Ivars [ca@valencia] + +3.26.1 +====== +* Fix crash when respawning shortcut inhibitor dialog [Olivier; #787568] +* Fix crash during monitor configuration migration [Carlos, Jonas; #787668] +* Fix multihead regressions in X11 session [Jonas; #787477] +* Fix screen rotation regressions [Hans; #787836] +* Fix keybindings not being resolved with non-latin layouts [Jonas; #787016] +* Support snap packages for sandboxed app IDs [Marco; #788217] +* Fix crash when reconnecting tablet device [Jason; #787649] +* Support running headless [Jonas; #730551, #787637] +* Support _NET_RESTACK_WINDOW and ConfigureRequest siblings [Vasilis; #786365] +* Fix monitor layout not being remembered across sessions [Jonas; #787629] +* Make sure to export _NET_NUMBER_OF_DESKTOPS [Florian; #760651] +* Allow resizing of tiled windows [Georges, Florian; #645153] +* Export tiling information to clients [Georges; #751857] +* Misc. bug fixes [Jonas, Florian, Jeremy, Rico; #787570, #787715, #787953, + #788049, #788199, #788292, #788197] + +Contributors: + Jonas Ådahl, Andrea Azzarone, Georges Basile Stavracas Neto, Hans de Goede, + Olivier Fourdan, Carlos Garnacho, Jason Gerecke, Vasilis Liaskovitis, + Rui Matos, Florian Müllner, Jeremy Soller, Marco Trevisan, Rico Tzschichholz + +Translations: + Matej Urbančič [sl], gogo [hr], Cheng-Chia Tseng [zh_TW] + +3.26.0 +====== +Contributors: + Florian Müllner + +Translations: + Trần Ngọc Quân [vi], Inaki Larranaga Murgoitio [eu], Jordi Mas [ca], + Anders Jonsson [sv], Alexander Shopov [bg], Ask Hjorth Larsen [da], + Jean-Baptiste Holcroft [fr], A S Alam [pa] + +3.25.92 +======= +* Add screencast and remote desktop support [Jonas; #784199] +* Support running with no attached monitors [Jonas; #730551] +* Add a vertical gradient effect to background actor [Alessandro; #786618] +* Misc. bug fixes [Mario, Daniel, Piotr, Jonas, Bastien; #786619, #786677, + #772218, #786918, #760670] + +Contributors: + Jonas Ådahl, Alessandro Bono, Piotr Drąg, Bastien Nocera, + Mario Sanchez Prada, Daniel Stone + +Translations: + Marek Cernocky [cs], Aurimas Černius [lt], Piotr Drąg [pl], + Fran Dieguez [gl], gogo [hr], Dušan Kazik [sk], Milo Casagrande [it], + Jordi Mas [ca], Cheng-Chia Tseng [zh_TW], Марко Костић [sr], + Милош Поповић [sr@latin], Rūdolfs Mazurs [lv], Matej Urbančič [sl], + Ask Hjorth Larsen [da], Piotr Drąg [it, lt], Jiri Grönroos [fi], + Emin Tufan Çetin [tr], Wolfgang Stöggl [de], Kukuh Syafaat [id], + Yuras Shumovich [be], Changwoo Ryu [ko], Alexander Shopov [bg], + Rafael Fontenelle [pt_BR], Balázs Úr [hu] + +3.25.91 +======= +* Reduce memory use of suspended instances [Jonas; #786299] +* Make supported scales determination saner [Rui; #786474] +* Fix crash on inhibit-shortcuts dialog reponse [Jonas; #786385] +* Support libinput's tag-and-drag setting [freeroot; #775755] +* Avoid overlapping keybindings with multiple layouts [Jonas; #786408] +* Fix non-transformed cursor on rotated monitors [Jonas; #786023] +* Avoid unnecessary work during background painting [Alessandro; #783512] +* Misc. bug fixes [Alberts, Jonas, Mario; #691611, #786300, #777732, #786568] + +Contributors: + freeroot, Jonas Ådahl, Alessandro Bono, Carlos Garnacho, Rui Matos, + Alberts Muktupāvels, Mario Sanchez Prada + +Translations: + Muhammet Kara [tr], Claude Paroz [fr], Мирослав Николић [sr, sr@latin], + Pawan Chitrakar [ne], Kukuh Syafaat [id] + +3.25.90 +======= +* Add zwp_linux_dmabuf_v1 support [Daniel; #785262] +* Add (x)wayland shortcut inhibitor support [Olivier; #783342] +* Misc. bug fixes [Daniel, Carlos, Cosimo; #785263, #785347, #767805] + +Contributors: + Jonas Ådahl, Cosimo Cecchi, Olivier Fourdan, Carlos Garnacho, Daniel Stone + +Translations: + Fabio Tomat [fur], Kukuh Syafaat [id], Aurimas Černius [lt], + Daniel Mustieles [es], Baurzhan Muftakhidinov [kk], Jordi Mas [ca], + Matej Urbančič [sl], Marek Cernocky [cs], gogo [hr], Fran Dieguez [gl], + Balázs Meskó [hu] + +3.25.4 +====== +* Do not throttle motion events on tablet tools [Carlos; #783535] +* Handle left-handed mode on pen/eraser devices [Carlos; #782027] +* Add wl_surface.damage_buffer() support [Jonas; #784080] +* Fix crash when moving across on-adjacent monitors [Jonas; #783630] +* Fix window moving/resizing via tablet tools [Jason; #777333] +* Support fractional monitor scaling [Jonas, Marco; #765011] +* Keep override-redirect windows stacked on top [Rui; #780485] +* Implement tablet rings/strips configuration [Carlos; #782033] +* Support tablet wheel events on wayland [Jason; #783716] +* Move g-s-d xrandr functionality into mutter [Rui; #781906] +* Misc. bug fixes [Florian, Jason, Miguel, Carlos, Jonas; #783502, #784009, + #784223, #784272, #784402, #784881, #762083, #784867, #781723] + +Contributors: + Jonas Ådahl, Miguel A. Vico, Emmanuele Bassi, Carlos Garnacho, Jason Gerecke, + Rui Matos, Florian Müllner, Marco Trevisan (Treviño) + +3.25.3 +====== +* Ignore hotplug-mode-update value on startup [Marco; #783073] +* Implement configurable monitor scales on X11 [Jonas; #777732] +* Fix handling of tiled monitors [Jonas; #781723] +* Handle multiple keycodes for keysym [Christian; #781223] +* Consider subsurfaces when grabbing [mindtree; #781811] +* Fix logic for HiPDPI scaling of TV outputs [Christian; #777347] +* Fix handling of left-handed mode on pen/eraser devices [Carlos; #782027] +* Fix output cycling in non-display-attached tablets [Carlos; #782032] +* Fix wacom cursor offset on wayland [Jason; #784009] +* Handle EXIF orientation of backgrounds [Silvère; #783125] +* Misc. bug fixes [Piotr, Tim, Bastien, Jonas, Florian, Benoit, Carlos; #772218, + #783161, #780407, #783113, #783293, #783505, #781703] + +Contributors: + mitchmindtree, Jonas Ådahl, Ikey Doherty, Piotr Drąg, Carlos Garnacho, + Jason Gerecke, Benoit Gschwind, Christian Kellner, Silvère Latchurié, + Tim Lunn, Florian Müllner, Bastien Nocera, Marco Trevisan (Treviño) + +Translations: + Fabio Tomat [fur], Kukuh Syafaat [id], Khaled Hosny [ar], + Daniel Mustieles [es] + +3.25.2 +====== +* Fix frame updates on hide-titlebar-when-maximized changes [Florian; #781862] +* Fix accessible screen coordinates on X11 [Florian; #781902] +* Use less CPU when rendering fast-updating windows [Carlos, Emmanuele; #782344] +* Compute geometry of clients that don't set one explicitly [Olivier; #782213] +* Fix copy+paste of UTF8 strings between X11 and wayland [Carlos; #782472] +* Fix non-wayland builds [Chris; #780533] +* Add plugin vfunc to implement a custom force-quit dialog [Carlos; #711619] +* Fix swapped red and blue channels in CoglTexture data [Carlos; #779234 +* Fix build where libtool's link_all_deplibs defaults to 'no' [Marco; #782821] +* Fix glitches when opening a window maximized [Olivier; #781353, #782183] +* Fix wrong cursor after window underneath the pointer changed [Carlos; #755164] +* Implement support for disable-while-typing option [Evan; #764852] +* Emit size-change signal when tiling [Alessandro; #782968] +* Misc. bug fixes [Nigel, Matthias, Jonas; #759085, #780215, #782156, #782152] + +Contributors: + Jonas Ådahl, Emmanuele Bassi, Alessandro Bono, Olivier Fourdan, + Carlos Garnacho, Matthias Liertzer, Florian Müllner, Nigel Taylor, + Marco Trevisan (Treviño), Chris Vine, Evan Welsh + +Translations: + Fabio Tomat [fur], Jordi Mas [ca], Mario Blättermann [de], + Emin Tufan Çetin [tr], Balázs Úr [hu] + +3.25.1 +====== +* Always sync window geometry on state changes [Jonas; #780292] +* Use EGL instead of GLX when drawing using GLES [Jonas; #771636] +* Fix HiDPI detection on vertical monitor layouts [Carlos; #777687] +* Get double-click timing from desktop mouse settings [Armin; #771576] +* Scale relative motion deltas with monitor scale [Jonas, Carlos; #778119] +* Use texture fallback when setting hardware cursor fails [Jente; #770020] +* Fix lock-up when using additional theme variants [Shantanu; #780254] +* Rework low-level monitor configuration [Jonas; #777732] +* Fix building with GLES2 instead of GL [Mario; #781398] +* Misc. bug fixes [Jonas, Piotr, Philip; #780304, #772218, #781242, #781391] + +Contributors: + Jonas Ådahl, Philip Chimento, Piotr Drąg, Carlos Garnacho, Shantanu Goel, + Jente Hidskes, Armin Krezović, Rui Matos, Florian Müllner, Mario Sanchez Prada + +Translations: + Yuras Shumovich [be], Yosef Or Boczko [he], Tom Tryfonidis [el], + Fabio Tomat [fur], Kukuh Syafaat [id] + +3.24.0 +====== + +Translations: + Yuri Myasoedov [ru], Rūdolfs Mazurs [lv], Jordi Mas [ca] + +3.23.92 +======= +* Properly handle EGLOutput acquire errors [Jonas, Miguel; #779112] +* Fix crash when a window closes during Alt+Tab [Rui; #779483] +* Implement DnD handling code in wayland [Hyungwon; #765003] +* Fix fallout from pixel conversion optimization in 3.23.91 [Carlos; #779234] +* Fix mouse input stopping to work in applications [Carlos; #763246] +* Fix DnD between QT5 and GTK3 applications on wayland [Carlos; #779757] +* Make EDID reading less fragile [Jonas; #779837] +* Add support for tablet grouping [Carlos; #779986] +* Misc. bug fixes and cleanups [Rui, Jonas; #779436, #779001, #779745] + +Contributors: + Jonas Ådahl, Miguel A. Vico, Olivier Fourdan, Carlos Garnacho, + Hyungwon Hwang, Rui Matos + +Translations: + Chao-Hsiung Liao [zh_TW], Sveinn í Felli [is], Ask Hjorth Larsen [da], + Changwoo Ryu [ko], Aurimas Černius [lt], GNOME Translation Robot [gd], + Marek Černocký [cs], Fran Dieguez [gl], Dušan Kazik [sk] + +3.23.91 +======= +* Give libinput read-only access to /sys [Carlos; #778472] +* Allow edge-scrolling without 2-finger-scroll capable devices [Rui; #778554] +* Fullscreen windows on the requested monitor on wayland [Rui; #772525] +* Implement threaded swap_event fallback for NVIDIA driver [Owen; #779039] +* Avoid pixel conversions when storing textures from cairo [Carlos; #779234] +* Misc. bug fixes [Piotr, Rui, Florian; #772218, #776919, #778831, #642652] + +Contributors: + Piotr Drąg, Carlos Garnacho, Rui Matos, Florian Müllner, Owen W. Taylor + +Translations: + Inaki Larranaga Murgoitio [eu], Daniel Mustieles [es], Claude Paroz [fr], + Mario Blättermann [de], Kjartan Maraas [nb], Piotr Drąg [pl], + Andika Triwidada [id], Anders Jonsson [sv], Milo Casagrande [it], + Fabio Tomat [fur], Rafael Fontenelle [pt_BR], + Мирослав Николић [sr, sr@latin], Balázs Meskó [hu], Chao-Hsiung Liao [zh_TW] + +3.23.90 +======= +* Fix window menu placement with HiDPI [Jonas; #776055] +* Improve EGLStream support [Jonas; #773629] +* Start moving low-level monitor configuration into mutter [Jonas; #777732] +* Fix erroneous key event repeats [Rui; #774989] +* Don't hardcode seat ID in ClutterDeviceManager [Carlos; #778092] +* Fix "ghost" cursors in multi-monitor setups [Jonas; #771056] +* Use eglGetPlatformDisplay [Adam; #772422] +* Fix erratic raise_or_lower behavior [Jose; #705200] +* Fix coordinate mapping of absolute devices [Carlos; #774115] +* Show OSD on tablet mode switches [Carlos; #771098] +* Make mutter libs parallel installable [Jonas; #777317] +* Only apply keymap when not running nested [Jonas; #777800] +* Set right scale for tablet tool cursors on HiDPI [Carlos; #778474] +* Adjust server-side shadows to match Adwaita [Juraj; #744667] +* Misc. bug fixes [Jonas, Bastien, Carlos, Peter, Lionel, Jeremy, Florian; + #774891, #777389, #777691, #778262, #776543, #778684, #778699, #744667] + +Contributors: + Jonas Ådahl, Jeremy Bicha, Piotr Drąg, Juraj Fiala, Carlos Garnacho, + Peter Hutterer, Adam Jackson, Lionel Landwerlin, Jose Marino, Rui Matos, + Florian Müllner, Bastien Nocera + +Translations: + Kjartan Maraas [nb], Mandy Wang [zh_CN], Marek Černocký [cs], + Anders Jonsson [sv], Dušan Kazik [sk], Piotr Drąg [pl], Matej Urbančič [sl] + +3.23.3 +====== +* Fix frequent freezes in multihead setups on wayland [Rui; #774557] +* Preserve root window mask on XSelectionRequest [Olivier; #776128] +* Misc. bug fixes [Carlos, Florian, Rui, Olivier; #775478, #774891, #775986, + #776036] + +Contributors: + Olivier Fourdan, Carlos Garnacho, Rui Matos, Florian Müllner + +3.23.2 +====== +* Stack docks below other windows on fullscreen monitors [Rui; #772937] +* Fix popup grabs blocking screen lock on wayland [Rui; #771235] +* Handle touchpad pinch gestures with more than two fingers [Carlos; #765937] +* Implement drawing tablet support on X11 [Carlos; #773779] +* Fix some Wine games starting minimized [Carlos; #774333] +* Fix switching between two finger- and edge scrolling on wayland [Rui; #771744] +* Implement support for EGLStream/EGLDevice [Jonas; #773629] +* Add size_changed vfunc to handle async client size changes [Rui; #770345] +* Change focus window on clicks with any modifiers [Rui; #746642] +* Misc. bug fixes and cleanups [Carlos, Daniel, Jonas, Rui; #771067, #774330, #774613, + #771297, #774135, #774827, #774923] + +Contributors: + Jonas Ådahl, Carlos Garnacho, Rui Matos, Florian Müllner, Daniel Stone + +Translations: + Kjartan Maraas [nb] + +3.23.1 +====== +* Fix handling of Escape shortcut in force-quit dialog [Landry; #737109] +* Improve pointer constraints support [Jonas; #771859] +* Really fix framebuffer capture origin offset [Rui; #771502] +* Fix session going into idle mode immediately on startup [Rui; #772839] +* Fix mirror mode with stage views [Rui; #773115] +* Fall back to X with connectors spread across multiple GPUs [Ray; #771442] +* Fix various crashes on wayland [Jonas, Carlos; #771646, #771858, #772929] +* Fix various placement issues on wayland [Olivier, Jonas, Sjoerd; #772729, + #768039, #771841, #771841, #773141] +* Misc. bug fixes [Rui, Jonas, Olivier; #771019, #773116, #772914, #773210] + +Contributors: + Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, Rui Matos, Landry MINOZA, + Sjoerd Simons, Ray Strode + +Translations: + Theppitak Karoonboonyanan [th], Kjartan Maraas [nb], Hannie Dumoleyn [nl], + liushuyu [zh_CN] + +3.22.1 +====== +* Fix feedback loop between StClipboard and X11 bridge [Carlos; #760745] +* Fall back gracefully if DRM plane rotation fails [Carlos; #772512] +* Approximate native monitor backend behavior to X [Rui; #772176] +* Fix crash on VT switch on wayland [Jonas; #771646] +* Expose Flatpak ID for application matching [Florian; #772613, #772614] + +Contributors: + Jonas Ådahl, Carlos Garnacho, Rui Matos, Florian Müllner, Olav Vitters + +Translations: + Inaki Larranaga Murgoitio [eu], Milo Casagrande [it] + +3.22.0 +====== +* Fix wayland crashes [Jonas; #771305, #771345, #770940, #771495] +* Fix display rotation on wayland [Jonas; #770672] +* Fix framebuffer capture origin offset [Rui; #771502] +* Misc. bug fixes [Jonas, Florian, Carlos; #770937, #771536, #771628, #771549] + +Contributors: + Jonas Ådahl, Carlos Garnacho, Rui Matos, Florian Müllner + +Translations: + Ask Hjorth Larsen [da], Charles Monzat [fr], Stas Solovey [ru], + Tom Tryfonidis [el], David King [en_GB] + +3.21.92 +======= +* Fix absolute pointer motion events on wayland [Jonas; #770557] +* Default to using stage views [Jonas; #770366] +* Fix animated cursors on wayland [Rui; #749913] +* Fix various crashes on wayland [Jonas; #757568, #770727, #770992] +* Fix screen capture for stage views not at (0, 0) [Jonas; #770127] +* Compress motion events instead of discarding them [Jonas; #771049] +* Fix XWayland pointer warp emulation [Jonas; #771050] +* Add common monitor modes in KMS backend [Rui; #744544] +* Temporarily use g-s-d schemas for tablet configuration [Carlos; #771315] +* Misc. bug fixes [Jonas, Carlos; #770402, #770647, #770991, #770994, #770929] + +Contributors: + Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, Rui Matos, Florian Müllner + +Translations: + Changwoo Ryu [ko], Baurzhan Muftakhidinov [kk], Anders Jonsson [sv], + Tiago Santos [pt], Rafael Fontenelle [pt_BR], Mario Blättermann [de], + Alexander Shopov [bg], Rūdolfs Mazurs [lv], Fran Dieguez [gl], + Trần Ngọc Quân [vi], Piotr Drąg [pl], Мирослав Николић [sr, sr@latin] + +3.21.91 +======= +* Add support for xdg-foreign protocol [Jonas; #769786] +* Support monitor rotation on wayland [Carlos; #745079] +* Port xdg-shell implementation to unstable v6 [Jonas; #769936] +* Handle unsupported buffer sizes more gracefully [Olivier; #770387] +* Use the same output naming logic as the X server on wayland [Rui; #770338] +* Fix replies in gnome-shell's chat notifications on wayland [Florian; #758167] +* Misc. bug fixes and cleanups [Bastien, Sjoerd, Jonas; #769276, #769636, + #770131, #770324, #769731] + +Contributors: + Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, Rui Matos, Florian Müllner, + Bastien Nocera, Sjoerd Simons + +Translations: + Piotr Drąg [pl], Mario Blättermann [de], Andika Triwidada [id], + Enrico Nicoletto [pt_BR], Мирослав Николић [sr, sr@latin] + +3.21.90 +======= +* Consider XDG_SESSION_TYPE when determining session type [Jouke; #759388] +* Re-add support for edge scrolling on some touchpads [Bastien; #768245] +* Support mouse and trackball acceleration profile [Jonas; #769179] +* Draw monitor contentn to individual framebuffer [Jonas; #768976] +* Support virtual input devices [Jonas, Carlos; #765009] +* Set correct output scale on hotplug [Jonas; #769505] +* Misc. bug fixes and cleanups [Florian, Jonas, Thomas, Bastien, Carlos; + #769014, #769024, #769054, #769070, #769036, #769305, #769578, #769800, + #769073] + +Contributors: + Jonas Ådahl, Carlos Garnacho, Thomas Hindoe Paaboel Andersen, Simon McVittie, + Alberts Muktupāvels, Florian Müllner, Bastien Nocera, Jouke Witteveen + +Translations: + Daniel Mustieles [es], Aurimas Černius [lt], Dušan Kazik [sk], + Fabio Tomat [fur], Balázs Úr [hu], Yosef Or Boczko [he], Marek Černocký [cs], + Matej Urbančič [sl] + +3.21.4 +====== +* Fix missing frame border around GTK+ dialogs [Florian; #745060] +* Improve X11 <-> wayland copy and paste interaction [Carlos; #768007] +* Add support for NV_robustness_video_memory_purge extension [Rui; #739178] +* Fix restoring the old focused window on restart [Owen; #766243] +* Fix fullscreen windows on other monitors stealing focus after closing + a window [Rui; #768221] +* Draw monitor content to individual framebuffer [Jonas; #768976] +* Provide screen capture API [Jonas; #768978] +* Misc. bug fixes and cleanups [Rui, Owen, Luca, Olivier, Jonas, Carlos; + #767969, #768243, #762407, #767997, #768039, #768977, #768977] + +Contributors: + Jonas Ådahl, Luca Bruno, Olivier Fourdan, Carlos Garnacho, Rui Matos, + Florian Müllner, Owen W. Taylor + +Translations: + Andika Triwidada [id] + +3.21.3 +====== +* Don't create invalid UTF-8 window description strings [Rui; #765535] +* Convert window titles and wm_class to UTF-8 [Rui; #752788] +* Communicate tiled state to GTK+ on wayland [Olivier; #766860] +* Use kill() to force-quit unresponsive wayland clients [Olivier; #767464] +* Fix window position when unmaximizing via DND on wayland [Olivier; #764180] +* Avoid full window redraws when using extended frame sync [Florian; #767798] + +Contributors: + Olivier Fourdan, Rui Matos, Florian Müllner + +Translations: + Cédric Valmary [oc] + +3.21.2 +====== +* Clean up surface <-> shell interaction [Jonas; #763431] +* Fix grabbing random keys for disabled shortcuts [Rui; #766270] +* Fix stacking of hidden windows on wayland [Rui; #764844] +* Misc. bug fixes [Victor, Florian, Marek, Rui; #766306, #766326, #751847, + #763832, #766528] + +Contributors: + Jonas Ådahl, Emmanuele Bassi, Marek Chalupa, Matthias Clasen, + Carlos Garnacho, Rui Matos, Florian Müllner, Victor Toso + +Translations: + Tiago Santos [pt], Cédric Valmary [oc], Muhammet Kara [tr] + +3.21.1 +====== +* Notify clients of pending modifier state changes [Rui; #748526] +* Add get_is_builtin_display_on() method [Florian; #765267] +* Fix 2-finger titlebar taps on wayland [Carlos; #764519] +* Merge clutter and cogl forks into mutter [Rui; #760439] +* Misc. bug fixes [Florian, Victor, Jonas; #765058, #765252, #765062] + +Contributors: + Jonas Ådahl, Emmanuele Bassi, Olivier Fourdan, Carlos Garnacho, Rui Matos, + Florian Müllner, Victor Toso, Rico Tzschichholz + +Translations: + GNOME Translation Robot [ja, gd] + +3.20.1 +====== +* Constrain window move/resizes on wayland as on X11 [Rui; #748819] +* Don't crash with invalid previous monitor configurations [Rui; #764286] +* Misc. bug fixes and cleanups [Jonas, Cosimo; #762828, #764807] + +Contributors: + Jonas Ådahl, Cosimo Cecchi, Rui Matos, Jasper St. Pierre + +Translations: + Inaki Larranaga Murgoitio [eu], Reinout van Schouwen [nl], Fabio Tomat [fur], + Trần Ngọc Quân [vi] + +3.20.0 +====== +* Fix crash when using visual bell [Jonas; #763858] + +Contributors: + Jonas Ådahl, Jasper St. Pierre + +Translations: + Milo Casagrande [it], Ask Hjorth Larsen [da] + +3.19.92 +======= +* Add system bell support on wayland [Jonas; #763284] +* Add gtk_surface.present to gtk-shell [Jonas; #763295] +* Handle DND drops on the root window [Carlos; #762104] +* Misc. bug fixes [Jonas, Carlos, Rui; #762828, #760745, #763125, #762763, + #762661, #762639, #763159] + +Contributors: + Jonas Ådahl, Carlos Garnacho, Rui Matos, Florian Müllner + +Translations: + Rūdolfs Mazurs [lv], Balázs Úr [hu], Claude Paroz [fr], Matej Urbančič [sl], + Мирослав Николић [sr, sr@latin], Sebastian Rasmussen [sv], Changwoo Ryu [ko], + Gil Forcada [ca], Tom Tryfonidis [el] + +3.19.91 +======= +* Add --nested CLI argument to fix nested wayland session [Jonas; #758658] +* Fix stack - scene graph stacking synchronization issues [Jonas; #755605] +* Rate-limit last-device changes to fix freezes [Carlos; #753527] +* Implement primary selection protocol [Carlos; #762560] +* Misc. bug fixes [Carlos, Jonas; #762878, #762716] + +Contributors: + Jonas Ådahl, Carlos Garnacho, Tim Lunn + +Translations: + Piotr Drąg [pl], Artur de Aquino Morais [pt_BR], Marek Černocký [cs], + Cédric Valmary [oc], Mario Blättermann [de], Dušan Kazik [sk], + Fran Dieguez [gl], Aurimas Černius [lt], Daniel Mustieles [es], + Stas Solovey [ru], Yosef Or Boczko [he] + +3.19.90 +======= +* Release buffer after processing commit [Ray; #761312, #761613] +* Implement pointer motion, locks and confinement on wayland [Jonas; #744104] +* Add basic startup notification support on wayland [Carlos; #762268] +* Misc. bug fixes [Rui, Alberts, Florian; #760670, #761543, #752794, #761557] + +Contributors: + Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, Rui Matos, + Alberts Muktupāvels, Florian Müllner, Jasper St. Pierre, Ray Strode + +3.19.4 +====== +* Fix updating stacking order when setting transient_for [Jonas; #755606] +* Support screen rotation when supported by the driver [Carlos; #745079] +* Protect against broken WM_CLASS property implementations [Sebastian; #759658] +* Handle wl_pointer v5 events on wayland [Carlos; #760637] +* Implement DND actions on wayland [Carlos; #760805] +* Misc. bug fixes [Jonas, Rui, Ray, Marek; #754711, #756789, #759297, #758613, + #760330, #760476, #759222, #760670] + +Contributors: + Jonas Ådahl, Marek Chalupa, Carlos Garnacho, Sebastian Keller, Rui Matos, + Florian Müllner, Jasper St. Pierre, Ray Strode + +Translations: + Aurimas Černius [lt] + +3.19.3 +====== +* Correct refresh rate units on KMS/Wayland [Daniel; #758653] +* Fix crash when initial cursor position is not on a monitor [Marek; #756698] +* Fix crash when more CRTs are enabled than outputs connected [Rui; #751638] +* Fix touch pointer emulation on wayland [Carlos; #756754] +* Allow minimizing windows that don't advertise supporting it [Jasper; #758186] +* Force 2-finger scroll by default if available [Bastien; #759304] +* Fix crash during XWayland initialization [Marek; #751845] +* Ensure to send a ConfigureNotify to just mapped windows [Rui; #759492] +* Misc. bug fixes and cleanups [Carlos, Jonas, Lionel; #758239, #758633, + #755503, #759374] + +Contributors: + Jonas Ådahl, Marek Chalupa, Carlos Garnacho, Lionel Landwerlin, Rui Matos, + Bastien Nocera, Daniel Stone, Jasper St. Pierre + +3.19.2 +====== +* Fix crash on monitor unplug [Rui; #756796] +* Exit cleanly on initialization errors [Owen; #757311] +* Allow to determine backend setting from session type [Ray; #741666] +* Fix DRM device detection for non-PCI devices [Alban; #754911] +* Don't force placement of windows without buffer on wayland [Marek; #751887] +* Fix initialization of bypass compositor hint [Rui; #758544] + +Contributors: + Alban Browaeys, Marek Chalupa, Rui Matos, Florian Müllner, Ray Strode, + Owen W. Taylor + +3.19.1 +====== +* wayland: Allow to trigger popups through keyboard/touch [Carlos; #756296] +* Fix modifiers-only input source switching on Ubuntu [Alberts; #756543] +* Misc. bug fixes [Jonas, Rui, Giovanni, Florian; #756675, #756660, #746420, + #756548, #756796, #757101, #757148] + +Contributors: + Jonas Ådahl, Giovanni Campagna, Carlos Garnacho, Rui Matos, + Alberts Muktupāvels, Florian Müllner + +Translations: + Daniel Șerbănescu [ro] + +3.18.1 +====== +* Misc. crash fixes [Jonas, Rui, Carlos, Owen, Florian; #755096, #754979, + #755490, #754357, #745785, #756642] +* Improve HiDPI support on wayland [Jonas; #755097] +* Fix doubly-scaled cursor on XWayland HiDPI [Jonas; #755099] +* Stop hiding titlebar buttons in dialogs [Florian; #641630] +* Add support for fullscreen/unfullscreen animations [Cosimo; #707248] +* Misc. bug fixes [Rui, Colin, Florian; #743339, #752047, #756074, #756649] + +Contributors: + Jonas Ådahl, Cosimo Cecchi, Carlos Garnacho, Rui Matos, Florian Müllner, + Jasper St. Pierre, Colin Walters, Owen W. Taylor + +3.18.0 +====== +* Misc. fixes [Florian, Jonas; #753434] + +Contributors: + Jonas Ådahl, Florian Müllner + +Translations: + Rūdolfs Mazurs [lv] + +3.17.92 +======= +* Don't omit the background color for backgrounds that don't fill the screen + [Ray; #754476] +* Fix up key state on FocusIn when running nested [Owen; #753948] +* Find the right DRM device instead of hardcoding card0 [Marek; #753434] +* Scale cursor on HiDPI screens [Jonas; #744932] +* Misc. fixes and cleanups [Lan, Jonas, Javier, Olivier; #754545, #754215, + #754621, #754715] + +Contributors: + Jonas Ådahl, Marek Chalupa, Olivier Fourdan, Javier Jardón, Ting-Wei Lan, + Ray Strode, Owen W. Taylor + +3.17.91 +======= +* Send error on pointer-gesture protocol version mismatch [Jonas; #753855] +* Misc. cleanups [Jonas; #744932] + +Contributors: + Jonas Ådahl + +Translations: + Chao-Hsiung Liao [zh_TW], Piotr Drąg [pl] + +3.17.90 +======= +* Fix glitch with some fullscreen apps [Rui; #753020] +* Fix screen update issue with NVidia driver [Aaron, Rui; #728464] +* Only call frame callbacks for surfaces that get drawn [Adel; #739163] +* Misc. bug fixes and cleanups [Jonas, Rui, Ting-Wei; #753222, #752753, #753237, + #753380, #744104, #744932] + +Contributors: + Jonas Ådahl, Adel Gadllah, Carlos Garnacho, Ting-Wei Lan, Rui Matos, + Florian Müllner, Aaron Plattner, Jasper St. Pierre + +Translations: + Akom Chotiphantawanon [th] + +3.17.4 +====== +* nested: Allow basic configuration of dummy outputs [Jonas; #747089] +* Send wl_surface.enter and wl_surface.leave on output changes [Jonas; #744453] +* Improve HiDPI handling on wayland [Jonas; #745655, #744934] +* Implement compositor-side animated cursors [Carlos; #752342] +* Misc. bug fixes [Peter, Marek, Carlos, Matthias, Rui; #750816, #751884, + #752248, #752551, #752552, #752673, #752674] + +Contributors: + Jonas Ådahl, Marek Chalupa, Matthias Clasen, Carlos Garnacho, Peter Hutterer, + Rui Matos, Florian Müllner, Jasper St. Pierre + +3.17.3 +====== +* Add X11/wayland clipboard interaction [Carlos; #738312] +* Support VM monitor layout hints on wayland [Thomas; #750363] +* Misc. bug fixes [Rui, Jonas, Olivier, Carlos, Ting-Wei, Peter, Florian; + #749994, #750256, #749716, #748705, #750552, #751036, #750007, #751136, + #750552, #751471, #751715, #750680] + +Contributors: + Jonas Ådahl, Dave Airlie, Cosimo Cecchi, Olivier Fourdan, Carlos Garnacho, + Thomas Hellstrom, Peter Hutterer, Ting-Wei Lan, Jasper Lievisse Adriaanse, + Rui Matos, Florian Müllner, Jasper St. Pierre + +Translations: + Marek Černocký [cs], Christian Kirbach [de], Pedro Albuquerque [pt] + +3.17.2 +====== +* Honor default value for click method setting [Rui; #746290] +* Add X11/wayland clipboard interoperation [Carlos; #738312] +* Misc. bug fixes [Rui; #749076, #749711] + +Contributors: + Carlos Garnacho, Rui Matos, Jasper St. Pierre + +3.17.1 +====== +* Add public method to get neighboring monitor [Florian; #633994] +* Apply the right settings to the right input devices [Carlos; #747886] +* Fix scroll button setting [Ondrej; #747967] +* Add support for modal hint on wayland [Jonas; #745720] +* Don't reset idle time for non-hardware events [Rui; #748541] +* Misc. bug fixes [Ray, Rui; #748380, #748478] + +Contributors: + Jonas Ådahl, Carlos Garnacho, Ondrej Holy, Rui Matos, Florian Müllner, + Jasper St. Pierre, Ray Strode, Tomeu Vizoso + +3.16.1 +====== +* Add function to refresh all background instances [Rui; #739178] +* Fix swapped scroll methods on wayland [Ondrej; #746870] +* Manually activate stage to fix accessibility on wayland [Ray, Rui; #746670] +* Center pointer on primary monitor on startup [Carlos; #746896] +* wayland: Reword synchronized state application semantics [Jonas; #743617] +* Ensure input settings are applied on startup [Rui; #747434] +* Misc. bug fixes [Jonas, Giovanni, Calvin, Ray, Rui; #744932, #746509, #746692, + #746510, #746545, #747263] + +Contributors: + Jonas Ådahl, Giovanni Campagna, Carlos Garnacho, Ondrej Holy, Rui Matos, + Jasper St. Pierre, Ray Strode, Calvin Walton + +Translations: + Khaled Hosny [ar], Marek Černocký [cs] + +3.16.0 +====== +* wayland: Don't skip notifying about initial maximized state [Jonas; #745303] + +Contributors: + Jonas Ådahl + +Translations: + Kjartan Maraas [nb], Jiri Grönroos [fi], Andika Triwidada [id], + Inaki Larranaga Murgoitio [eu], Ask H. Larsen [da], Muhammet Kara [tr] + +3.15.92 +======= +* Ensure pointer visibility on monitor changes [Rui, Marek; #745121, #745752] +* Fix geometry of shaded windows [Florian; #746145] +* Take over cursor visibility handling from gsd [Carlos; #712775] +* Fix touch interaction on window decorations [Carlos; #745335] +* Add options for libinput_config_click_method [Carlos; #746290] +* Scale window decorations on HiDPI displays [Florian; #744354] +* Misc. bug fixes [Carlos, Ray, Rui; #745163, #746295, #746098, #745734] + +Contributors: + Marek Chalupa, Carlos Garnacho, Rui Matos, Florian Müllner, + Jasper St. Pierre, Ray Strode + +Translations: + Piotr Drąg [pl], Milo Casagrande [it], Changwoo Ryu [ko], + Daniel Korostil [uk], Baurzhan Muftakhidinov [kk], Trần Ngọc Quân [vi], + Alexander Shopov [bg], Jordi Mas [ca], Samir Ribic [bs], A S Alam [pa], + Matej Urbančič [sl] + +3.15.91 +======= +* wayland: Fix nested compositor mode [Jonas; #745401] +* wayland: Fix pointer constraining [Marek; #727337] +* wayland: Fix input region on HiDPI [Jonas; #744933] +* Allow themes to style buttons differently based on function [Horst; #745108] +* Misc. bug fixes and cleanups [Ray, Rui, Alban; #745141, #745118, #745476, + #745442] + +Contributors: + Jonas Ådahl, Alban Browaeys, Marek Chalupa, Horst, Rui Matos, + Jasper St. Pierre, Ray Strode + +Translations: + Chao-Hsiung Liao [zh_TW], Efstathios Iosifidis [el], Dušan Kazik [sk], + Balázs Úr [hu], Daniel Mustieles [es], Claude Paroz [fr], Stas Solovey [ru], + Yosef Or Boczko [he], Rafael Ferreira [pt_BR], Aurimas Černius [lt], + Fran Dieguez [gl], Anders Jonsson [sv], Мирослав Николић [sr, sr@latin] + +3.15.90 +======= +* Initialize MetaOutput even when we can't get the EDID [Rui; #743412] +* Expose MetaMonitorManager to introspection [Rui; #743745] +* Fix flash on unredirection [Chris; #743858] +* Update xdg-shell implementation to v5 [Jonas; #744452] +* Do not try to use seat devices that aren't (yet) present [Ray; #744640] +* Add keybindings for switching to VT8-VT12 [Ray; #744800] +* Misc bug fixes [Jonas, Cosimo; #743678, #744500] + +Contributors: + Jonas Ådahl, Cosimo Cecchi, Carlos Garnacho, Rui Matos, Jasper St. Pierre, + Ray Strode, Chris Wilson + +Translations: + Yosef Or Boczko [he], Yuri Myasoedov [ru], Kristjan SCHMIDT [eo], + Matej Urbančič [sl], Dušan Kazik [sk] + +3.15.4 +====== +* Use GTK+ theme for window decorations instead of metacity [Florian; #741917] +* Export the same EDID information on X11 and wayland [Carlos; #742882] +* Apply input device configuration on wayland [Carlos; #739397] +* Implement pointer barriers on wayland [Jonas; #706655] +* Misc. bug fixes (Ting-Wei, Rui, Ikey, Florian, Marek, Jonas; #741829, + #738630, #737463, #698995, #727893, #742825, #742824, #742841, #743173, + #743189, #743217, #743254] + +Contributors: + Jonas Ådahl, Giovanni Campagna, Marek Chalupa, Ikey Doherty, Adel Gadllah, + Carlos Garnacho, Ting-Wei Lan, Rui Matos, Florian Müllner, Jasper St. Pierre, + Rico Tzschichholz + +Translations: + Matej Urbančič [sl], Balázs Úr [hu], Marek Černocký [cs], + Inaki Larranaga Murgoitio [eu], Rafael Ferreira [pt_BR], + Daniel Mustieles [es], Fran Dieguez [gl] + +3.15.3 +====== +* Don't leave left-over frames queued [Owen; #738686] +* Set CRTC configuration even if it might be redundant [Rui; #740838] + +Contributors: + Rui Matos, Jasper St. Pierre, Rico Tzschichholz, Owen W. Taylor + +Translations: + Trần Ngọc Quân [vi], Muhammet Kara [tr] + +3.15.2 +====== +* Don't enable hiDPI on monitors with broken EDID [Bastien; #734839] +* Prevent crash applying monitor config for a closed lid [Rui; #739450] +* Fix "flicker" during startup transition [Ray; #740377] +* Misc. bug fixes [Lan, Florian, Carlos; #731521, #740133, #738890] + +Contributors: + Emmanuele Bassi, Carlos Garnacho, Jonathon Jongsma, Ting-Wei Lan, Rui Matos, + Florian Müllner, Bastien Nocera, Jasper St. Pierre, Ray Strode + +Translations: + Kjartan Maraas [nb] + +3.15.1 +====== +* Use GResources for theme loading [Cosimo; #736936] +* Fix headerbar drag getting stuck on xwayland [Carlos; #738411] +* Fix wayland hiDPI regressions [Adel; #739161] +* Misc bug fixes and cleanups [Jasper, Rui, Carlos; #662962, #738630, #738888, + #738890] + +Contributors: + Cosimo Cecchi, Adel Gadllah, Carlos Garnacho, Rui Matos, Florian Müllner, + Jasper St. Pierre + +3.14.1 +====== +* Fix move-titlebar-onscreen function [Florian; #736915] +* Fix stacking of the guard window [Owen; #737233] +* Fix keycode lookup for non-default layouts [Rui; #737134] +* Fix workspaces-only-on-primary handling [Florian; #737178] +* Don't unstick sticky windows on workspace removal [Florian; #737625] +* Do not auto-minimize fullscreen windows [Jasper; #705177] +* Upload keymap to newly added keyboard devices [Rui; #737673] +* Apply keyboard repeat settings [Rui; #728055] +* Don't send pressed keys on enter [Rui; #727178] +* Fix build without wayland/native [Rico; #738225] +* Send modifiers after the key event [Rui; #738238] +* Fix unredirect heuristic [Adel; #738271] +* Do not show system chrome over fullscreen windows [Florian; #693991] +* Misc. bug fixes [Florian, Adel, Tom; #737135, #737581, #738146, #738384] + +Contributors: + Tom Beckmann, Adel Gadllah, Carlos Garnacho, Rui Matos, Florian Müllner, + Jasper St. Pierre, Rico Tzschichholz, Owen W. Taylor + +Translations: + Krishnababu Krothapalli [te], Мирослав Николић [sr, sr@latin], + Alexander Shopov [bg], Saibal Ray [bn_IN], Milo Casagrande [it], + Rūdolfs Mazurs [lv] + +3.14.0 +====== +* Fix placement of popup windows on wayland [Jasper; #736812] +* Only increment serial once per event [Jasper; #736840] +* Fix window positioning regression with non-GTK+ toolkits [Owen; #736719] + +Contributors: + Jasper St. Pierre, Owen W. Taylor + +Translations: + Saibal Ray [bn_IN], Dušan Kazik [sk], Manoj Kumar Giri [or], + Christian Kirbach [de], Ask H. Larsen [da], YunQiang Su [zh_CN], + Bernd Homuth [de], Shankar Prasad [kn], Petr Kovar [cs], Rajesh Ranjan [hi] + +3.13.92 +======= +* Rewrite background code [Owen; #735637, #736568] +* Fix size in nested mode [Owen; #736279] +* Fix destroy animation of background windows [Florian; #735927] +* Wire keymap changes up to the wayland frontend [Rui; #736433] +* Add a test framework and stacking tests [Owen; #736505] +* Simplify handling of the merged X and wayland stack [Owen; #736559] +* Fix cursor size on HiDPI [Adel; #729337] +* Misc. bug fixes [Owen; #735632, #736589, #736694] + +Contributors: + Adel Gadllah, Rui Matos, Florian Müllner, Jasper St. Pierre, Owen W. Taylor + +Translations: + Andika Triwidada [id], Piotr Drąg [pl], Changwoo Ryu [ko], + Kjartan Maraas [nb], Ville-Pekka Vainio [fi], Yuri Myasoedov [ru], + Aurimas Černius [lt], Balázs Úr [hu], Sweta Kothari [gu], A S Alam [pa], + Sandeep Sheshrao Shedmake [mr], Shantha kumar [ta], Gil Forcada [ca], + Carles Ferrando [ca@valencia], Mattias Eriksson [sv] + +3.13.91 +======= +* Misc. bug fixes [Carlos; #735452] + +Contributors: + Adel Gadllah, Carlos Garnacho, Rui Matos, Jasper St. Pierre, + Rico Tzschichholz + +Translations: + Chao-Hsiung Liao po/zh_HK, zh_TW.po, Enrico Nicoletto [pt_BR], + Kjartan Maraas [nb], Fran Diéguez [gl], Yosef Or Boczko [he], + Maria Mavridou [el], Claude Paroz [fr] + +3.13.90 +======= +* Only call XSync() once per frame [Rui; #728464] +* Update capabilities on device list changes [Carlos; #733563] +* Make use of GLSL optional [Adel; #733623] +* Handle gestures and touch events on wayland [Carlos; #733631] +* Add support for unminimize compositor effects [Cosimo; #733789] +* Always set the frame background to None [Giovanni; #734054] +* Add backend methods to handle keymaps [Rui; #734301] +* Actually mark revalidated MetaTextureTower levels as valid [Owen; #734400] +* Rely on explicit -backward switcher keybindings instead of -magic + [Christophe; #732295, #732385] +* Misc. bug fixes and cleanups [Rui, Adel, Christophe; #727178, #734852, + #734960] + +Contributors: + Emmanuele Bassi, Giovanni Campagna, Cosimo Cecchi, Piotr Drąg, + Christophe Fergeau, Adel Gadllah, Carlos Garnacho, Rui Matos, + Florian Müllner, Jasper St. Pierre, Rico Tzschichholz, Olav Vitters, + Owen W. Taylor + +Translations: + Kjartan Maraas [nb], Inaki Larranaga Murgoitio [eu], Lasse Liehu [fi], + ngoswami [as], Daniel Mustieles [es] + +3.13.4 +====== +* Fix move/resize operations for wayland clients [Marek; #731237] +* Add ::first-frame signal to MetaWindowActor [Owen; #732343] +* Handle keysyms without the XF86 prefix [Owen; #727993] +* Add touch gesture support [Carlos] +* Fix a deadlock when exiting [Owen; #733068] +* Add framework for restarting the compositor with nice visuals + [Owen; #733026] +* Toggle seat capabilities on VT switch [Carlos; #733563] +* Misc bug fixes [Florian, Owen; #732695, #732350] + +Contributors: + Tom Beckmann, Giovanni Campagna, Marek Chalupa, Adel Gadllah, + Carlos Garnacho, Florian Müllner, Jasper St. Pierre, Rico Tzschichholz, + Owen W. Taylor + +Translations: + Yuri Myasoedov [ru], Fran Diéguez [gl], Aurimas Černius [lt], MarMav [el], + Enrico Nicoletto [pt_BR] + +3.13.3 +====== +* Improve behavior of window buttons with compositor menus [Florian; #731058] +* Implement touch support on wayland [Carlos; #724442] +* Update window shadows [Nikita; #731866] +* Keep windows on the preferred output [Florian; #731760] +* Misc bug fixes [Jonas, Florian, Jasper; #729601, #730681, #731353, #731332, + #730527, #662962] + +Contributors: + Jonas Ådahl, Nikita Churaev, Carlos Garnacho, Florian Müllner, + Jasper St. Pierre, Rico Tzschichholz + +3.13.2 +====== +* Add basic HiDPI support on wayland [Adel; #728902] +* Fix crash when monitors change during suspend [Giovanni; #725637] +* Replace mutter-launch with logind integration [Jasper; #724604] +* Move window menu into the compositor [Jasper; #726352] +* Fix delayed focus-follows-mouse support [Florian; #730541] +* Support fallback app menu in window decorations [Florian; #730752] +* Misc. bug fixes and cleanups [Giovanni, Jonas, Jasper; #729732, #729602, + #726714] + +Contributors: + Jonas Ådahl, Giovanni Campagna, Adel Gadllah, Florian Müllner, + Jasper St. Pierre, Rico Tzschichholz + +Translations: + Pau Iranzo [ca], Daniel Mustieles [es] + +3.13.1 +====== +* Fix opacity values from _NET_WM_WINDOW_OPACITY [Nirbheek; #727874] +* Merge wayland branch [Jasper, Giovanni, Robert B., Neil, Adel, Rui, Jonas, + Lionel, Tim, Owen, Florian, Colin W., Cosimo, Ray, Kalev, Pavel, Robert A., + Magdalen, Marek, Matthias, Alban, Seán, Daniel, Stefano, Carlos, Colin G., + Andreas, Alexander, Ryan, Marc-André, Asad, Alberto, Bastien, Hans, + Debarshi, Sindhu, Andika, Rico, Olav] +* Don't prevent workspace switches for present_with_time() [Florian; #728018] +* Add shortcuts for switching to the last workspace [Elad; #659288] +* Make move/resize menu items behave like the keybindings [Jasper; #728617] +* Misc. bug fixes and cleanups [Jasper, Bastien, Florian, Adel; #720631, + #727979, #728423, #728395, #729044] + +Contributors: + Jonas Ådahl, Elad Alfassa, Robert Ancell, Magdalen Berns, Robert Bragg, + Giovanni Campagna, Cosimo Cecchi, Marek Chalupa, Nirbheek Chauhan, + Matthias Clasen, Alban Crequy, Seán de Búrca, Daniel Drake, Jason Ekstrand, + Stefano Facchini, Adel Gadllah, Carlos Garnacho, Colin Guthrie, + Andreas Heider, Lionel Landwerlin, Alexander Larsson, Kalev Lember, + Ryan Lortie, Tim Lunn, Marc-André Lureau, Rui Matos, Asad Mehmood, + Alberto Milone, Florian Müllner, Bastien Nocera, Hans Petter Jansson, + Debarshi Ray, Neil Roberts, Sindhu S, Jasper St. Pierre, Ray Strode, + Andika Triwidada, Rico Tzschichholz, Pavel Vasin, Olav Vitters, + Colin Walters, A. Walton, Owen W. Taylor + +Translations: + Inaki Larranaga Murgoitio [eu], marablack3 [el], Daniel Mustieles [es], + Fran Diéguez [gl], Yosef Or Boczko [he], Dirgita [id] + +3.12.0 +====== +* Fix grab issue with SSD xwayland windows [Rui; #726123] +* Misc. bug fixes [Jasper, Ray, Rui, Florian; #727011] + +Contributors: + Rui Matos, Florian Müllner, Jasper St. Pierre, Ray Strode + +3.11.92 +======= +* Fix identification of CSD windows [Owen; #723029] +* Update keyboard state unconditionally [Rui; #722847] +* Misc bug fixes and cleanups [Owen, Rui, Giovanni, Matthias, Adel, Ryan, + Jasper, Marek, Florian; #723580, #726123, #726683] + +Contributors: + Giovanni Campagna, Marek Chalupa, Matthias Clasen, Adel Gadllah, Ryan Lortie, + Rui Matos, Florian Müllner, Jasper St. Pierre, Owen W. Taylor + +3.11.91 +======= +* Don't use keysym to match keybindings [Rui; #678001] +* Fix message tray icons showing up blank (again) [Adel; #725180] +* Improve keybinding lookups [Rui; #725588] +* Fix dynamic updates of titlebar style properties [Owen; #725751] +* Fix positioning of manually positioned windows [Owen; #724049] +* Misc bug fixes and cleanups [Jasper, Carlos, Adel, Giovanni, Florian; #720631, + #724969, #725216, #724402, #722266, #725338, #725525] + +Contributors: + Giovanni Campagna, Adel Gadllah, Carlos Garnacho, Rui Matos, Florian Müllner, + Jasper St. Pierre, Owen W. Taylor + +3.11.90 +======= +* Fix double-scaling on high DPI resolutions [Adel; #723931] +* Make tile previews a compositor effect [Stefano, Florian; #665758] +* Misc. bug fixes and cleanups [Ryan, Giovanni, Jasper, Adel; #722530, #724257, + #724258, #720631, #724364, #724472] + +Contributors: + Giovanni Campagna, Marek Chalupa, Stefano Facchini, Adel Gadllah, + Ryan Lortie, Florian Müllner, Jasper St. Pierre, Rico Tzschichholz + +3.11.5 +====== +* Fix CSD titlebars being placed off-screen [Jasper; #719772] +* Add support for subsurfaces [Jonas; #705502] +* Expose MetaWindow:skip-taskbar property [Florian; #723307] +* Fix legacy tray icons showing up blank [Adel; #721596] +* Fix configuration of cloned monitors [Adel; #710610] +* Misc bug fixes and cleanups [Jasper, Adel, Marek, Jonas; #720631, #723468, + #720818, #723563, #723564] + +Contributors: + Jonas Ådahl, Marek Ch, Adel Gadllah, Florian Müllner, Jasper St. Pierre + +3.11.4 +====== +* Don't leave focus on windows that are being unmanaged [Owen; #711618] +* Reduce server grabs [Daniel Drake; #721345, #721709] +* Improve heuristic to determine display output name [Cosimo Cecchi; #721674] +* Atomically unmaximize both directions [Jasper; #722108] +* Misc bug fixes [Debarshi, Andika, Florian; #721517, #721674, #722347] + +Contributors: + Cosimo Cecchi, Daniel Drake, Florian Müllner, Debarshi Ray, Jasper St. Pierre, + Andika Triwidada, Owen W. Taylor + +3.11.3 +====== +* Fix focus issues with external OSKs[Jasper; #715030] +* Add a MetaCullable interface [Jasper; #714706] +* Fix window keybindings [Rui; #719724] +* Fix settings keyboard/pointer focus for new clients [Rui; #719725] +* Fix window group paint volume [Owen; #719669] +* Fix frame extents problems [Owen; #714707] +* Add shortcut to move windows between monitors [Florian; #671054] +* Fix problems with focus tracking [Owen; #720558] +* Misc. bug fixes and cleanups: [Rui, Colin, Lionel, Jasper, Owen; #712833, + #719557, #719695, #719833, #678989, #720417, #720630] + +Contributors: + Lionel Landwerlin, Rui Matos, Alberto Milone, Florian Müllner, + Jasper St. Pierre, Rico Tzschichholz, Owen W. Taylor, Colin Walters + +3.11.2 +====== +* Support setting a NULL opaque region [Andreas; #711518] +* Sync keymap from X to wayland [Giovanni; #707446] +* Implement support for subsurfaces [Jonas; #705502] +* Don't focus the no-focus-window for globally active windows [Jasper; #710296] +* Support "hotplug_mode_update" property [Marc-André; #711216] +* Fix resize operations using mouse-button-modifier [Lionel; #710251] +* Fix position of attached modals for CSD windows [Giovanni, Owen; #707194] +* Misc. bug fixes [Rui, Jasper, Neil, Florian; #712247, #711731] + +Contributors: + Giovanni Campagna, Andreas Heider, Lionel Landwerlin, Marc-André Lureau, + Rui Matos, Florian Müllner, Neil Roberts, Sindhu S, Jasper St. Pierre, + Rico Tzschichholz, Owen W. Taylor, Jonas Ådahl + +3.11.1 +====== +* Fix tile previews getting stuck on right click during drags [Lionel; #704759] +* Use new UPower API [Bastien] +* Set hot spot when cursor set from wl_buffer [Jonas; #709593] +* Expose min-backlight-step [Asad; #710380] +* Misc. bug fixes and cleanups [Jasper, Olav, Magdalen; #709776] + +Contributors: + Magdalen Berns, Lionel Landwerlin, Asad Mehmood, Bastien Nocera, + Jasper St. Pierre, Olav Vitters, Jonas Ådahl + +3.10.1 +====== +* Don't apply fullscreen workarounds to CSD windows [Giovanni; #708718] +* Fix hangs during DND operations [Adel; #709340] +* Misc bug fixes [Dan, Giovanni, Jasper; #708813, #708420] + +Contributors: + Giovanni Campagna, Adel Gadllah, Dan Horák, Hans Petter Jansson, + Jasper St. Pierre + +3.10.0.1 +======== +* Fix bug when a window changed size twice in a single frame - this + can happen with GTK+ client-side decorations [Giovanni, Owen; #708367] + +Contributors: + Giovanni Campagna, Owen Taylor + +3.10.0 +====== +* Update dependencies [Giovanni; #708210] + +3.9.92 +====== +* Constrain the pointer position onto visible monitors [Giovanni; #706655] +* Fix keyboard state handling in face of event compression [Giovanni; #706963] +* Extend the MetaCursorTracker API with query pointer and cursor visibility [Giovanni; #707474] +* Be stricter in checking and exposing the wayland protocol version [#707851] +* Don't require plugins to pass event to Clutter [Giovanni; #707482] +* Move the --wayland option from the binary to the library [Giovanni; #707897] +* Implement running from gnome-session (environment variable setting, process group + handling, Clutter backend variables) [Giovanni; #706421] +* Add support for more cursor types [Giovanni; #707919] +* Drop man pages for removed utilities [Kalev; #706579] +* Implement monitor configuration on KMS [Giovanni; #706308] +* Implement HW cursors [Giovanni; #707573] +* Implement minimal support for resizing and maximizing wayland clients [Giovanni; #707401] +* Implement transient hints for wayland clients [Giovanni; #707401] +* Implement popup menu surfaces and grabs [Giovanni; #707863] +* Immediately fire idle watches that are already expired [Giovanni; #707302] +* Remove holes generated by disabling the laptop lid [Giovanni; #707473] +* Misc bug fixes [Giovanni, Pavel, Adel; #707649, #706124, #707584, #707851, #707929, + #708070] + +Contributors: + Adel Gadllah, Giovanni Campagna, Kalev Lember, Pavel Vasin + +Translations: + Мирослав Николић po/sr, sr@latin.po, Мирослав Николић [sr, sr@latin], + Chao-Hsiung Liao [zh_HK, zh_TW], Yuri Myasoedov [ru], + Ville-Pekka Vainio [fi], Changwoo Ryu [ko], A S Alam [pa], + Mattias Põldaru [et], Rūdolfs Mazurs [lv], Ihar Hrachyshka [be], + Nilamdyuti Goswami [as], Andika Triwidada [id], Baurzhan Muftakhidinov [kk], + Benjamin Steinwender [de] + +3.9.91 +====== +* Drop man pages for removed utilities [Kalev; #706579] +* Add support for idle tracking [Giovanni, Cosimo; #706005, #707250] +* Skip CRTC reconfigurations that have no effect [Giovanni; #706672] +* Ignore skip-taskbar hints on parentless dialogs [Giovanni; #673399] +* Don't save pixbuf data in user data [Tim; #706777] +* Don't queue redraws for obscured regions [Adel; #703332] +* Suppor the opaque region hints for wayland clients [Jasper; #707019] +* Turn blending off when drawing entirely opaque regions [Jasper; #707019] +* Check event timestamps before reconfiguring [Giovanni; #706735] +* Merge the DBus API for display configuration in the wayland branch [Giovanni] +* Install an X IO error handler for XWayland [Giovanni; #706962] +* Use the clutter xkbcommon integration for the wayland keyboard [Giovanni; #705862] +* Add a setuid helper for running on KMS+evdev [Giovanni, Colin; #705861] +* Add keybindings for switching VT [Giovanni; #705861] +* Implement plugin modality when running as a wayland compositor [Giovanni; #705917] +* Add support for the application menu for wayland clients [Giovanni; #707128] +* Several Coverity spotted fixes [Jasper] +* Don't create a dummy texture for the texture template [Neil; #707458] +* Use a more conservative paint volume for obscured windows [Adel] +* Misc bug fixes [Giovanni, Colin, Seán, Jasper, Cosimo; #706582, #706598, + #706787, #706729, #706825, #707081, #707090, #707267, #706982, #706289] + +Contributors: + Giovanni Campagna, Cosimo Cecchi, Adel Gadllah, Colin Guthrie, Kalev Lember, + Tim Lunn, Jasper St. Pierre, Neil Roberts, Rico Tzschichholz, Seán de Búrca + +Translations: + Piotr Drąg [pl], Alexandre Franke [fr], Kjartan Maraas [nb], + Milo Casagrande [it], Balázs Úr [hu], Seán de Búrca [ga], Fran Diéguez [gl], + Daniel Mustieles [es], Aurimas Černius [lt], Gil Forcada [ca] + +3.9.90 +====== +* First release from the wayland branch, includes basic support for running + as a wayland compositor [Robert, Neil, Giovanni] +* Add support for _GTK_FRAME_EXTENTS [Jasper; #705766] +* Fix quick consecutive presses breaking keyboard input [Alban; #666101] +* Work towards running as wayland compositor [Giovanni] + - Add DBus API for display configuration + [#705670, #706231, #706233, #706322, #706382] + - Add abstraction layer for cursor tracking [#705911] + - Add support for plugin modality under wayland [#705917] +* Disable GTK+ scaling [Alexander; #706388] +* Disable blending while updating tower [Robert] +* Misc bug fixes and cleanups [Adel, Jasper, Giovanni, Colin, Rico, Florian; + #703332, #704437, #706207] + +Contributors: + Robert Bragg, Giovanni Campagna, Alban Crequy, Adel Gadllah, + Alexander Larsson, Florian Müllner, Jasper St. Pierre, Neil Roberts, + Rico Tzschichholz, Colin Walters + +Translations: + Jiro Matsuzawa [ja], Kjartan Maraas [nb], Matej Urbančič [sl], + Marek Černocký [cs], Daniel Mustieles [es], Rafael Ferreira [pt_BR], + Yaron Shahrabani [he], Ján Kyselica [sk] + +3.9.5 +===== +* Don't select for touch events on the stage [Jasper; #697192] +* Don't queue redraws for obscured regions [Adel; #703332] +* Export timestamp of global keybinding events [Bastien; #704858] +* Misc bug fixes and cleanups [Jasper, Rico; #703970] + +Contributors: + Adel Gadllah, Bastien Nocera, Jasper St. Pierre, Rico Tzschichholz + +3.9.4 +===== +* Tweak window shadows [Allan; #702141] +* Ignore our own focus events for focus prediction [Jasper; #701017] +* Add API to query if the stage is focused [Jasper; #700735] +* Add API to query the monitor for a given position [Adel] +* Don't force attached dialogs to be border-only [Florian; #702764] +* Allow slicing of backgrounds to avoid texture size limits [Ray; #702283] +* Miscellaneous bug fixes and cleanups [Adel; #701224, #702564] + +Contributors: + Allan Day, Adel Gadllah, Florian Müllner, Jasper St. Pierre, Ray Strode + +3.9.3 +===== +* Ensure events are always reported to the grab window [Rui; #701219] +* Use new clutter_stage_set_paint_callback() function to prevent dropping + frames with frame synced toolkits [Owen; #698794] + +Contributors: + Rui Matos, Owen W. Taylor + +3.9.2 +===== +* Add meta_window_can_close() function [Jasper; #699269] +* Add support for string-array preferences [Florian; #700223] +* Fix a potential race condition with _NET_WM_MOVERESIZE [Jasper; #699777] +* Fix shade window action [Stef; #693714] +* Remove overlay_group [Giovanni; #700735] +* Improve tracking of the focus window [Dan, Jasper; #647706] +* Add API to freeze/unfreeze the keyboard [Rui; #697001] +* Grab and emit a signal when XK_ISO_Next_Group is pressed [Rui; #697002] +* Misc bug fixes and cleanups [Dieter, Jasper, Rui; #699636, #700735, #697000] + +Contributors: + Giovanni Campagna, Rui Matos, Florian Müllner, Jasper St. Pierre, + Dieter Verfaillie, Stef Walter, Dan Winship + +Translations: + Kjartan Maraas [nb], Ján Kyselica [sk] + +3.9.1 +===== +* Fix miscellaneous memory leaks [Pavel; #698710] +* Misc fixes and cleanups [Stef, Simon; #698179, #697758] + +Contributors: + Simon McVittie, Pavel Vasin, Stef Walter + +3.8.1 +===== +* Fix crash when getting default font [Bastien; #696814] +* Fix ungrabbing of keybindings [Rui; #697003] +* Misc fixes and cleanups [Jasper, Simon; #697758] + +Contributors: + Jasper Lievisse Adriaanse, Rui Matos, Simon McVittie, Bastien Nocera + +Translations: + Guillaume Desmottes [fr], Shankar Prasad [kn], Bruce Cowan [en_GB], + Andika Triwidada [id], Yaron Shahrabani [he], Kjartan Maraas [nb], + Gheyret Kenji [ug] + +3.8.0 +===== +* Address major memory leak when changing backgrounds [Ray; #696157] + +Contributors: + Ray Strode + +Translations: + Sandeep Sheshrao Shedmake [mr], Victor Ibragimov [tg], Gabor Kelemen [hu], + Ville-Pekka Vainio [fi], Rajesh Ranjan [hi], Dr.T.Vasudevan [ta], + ManojKumar Giri [or], Yuri Myasoedov [ru], Petr Kovar [cs], + Jiro Matsuzawa [ja], Krishnababu Krothapalli [te], Ani Peter [ml], + Inaki Larranaga Murgoitio [eu] + +3.7.92 +====== +* Build and improve reference docs [Tomeu; #676856, #695641, #695935] +* Add tracking of whether there are fullscreen windows [Owen; 649748] +* Misc bug fixes and cleanups [Adel, Giovanni, Owen, Jasper, Florian; #695269, + #695711, #694046, #695813, #695881, #676856, #696053, #682779, #696089, + #696091, #696087] + +Contributors: + Giovanni Campagna, Adel Gadllah, Florian Müllner, Jasper St. Pierre, + Tomeu Vizoso, Owen W. Taylor + +Translations: + Chao-Hsiung Liao [zh_HK, zh_TW], Rafael Ferreira [pt_BR], + Ihar Hrachyshka [be], Nilamdyuti Goswami [as], Matej Urbančič [sl], + Dimitris Spingos [el], Jan Kyselica [sk], Khaled Hosny [ar], + Мирослав Николић [sr, sr@latin], Duarte Loreto [pt], Sweta Kothari [gu], + Milo Casagrande [it], Changwoo Ryu [ko], Gil Forcada [ca], + Carles Ferrando [ca@valencia], Mattias Põldaru [et], Alexandre Franke [fr], + Ask H. Larsen [da], Rūdolfs Mazurs [lv], Nguyễn Thái Ngọc Duy [vi] + +3.7.91 +====== +* Fix windows being treated as remote after hostname changes [Ray; #688716] +* Add meta_window_get_all_monitors() method [Adel; #646861] +* Add grab API for externally defined accelerators [Florian; #643111] +* Make session registration an explicit step [Ray; #694876] +* Avoid unnecessary stage redraws [Adel; #694988, #695006] +* Misc fixes [Giovanni, Ray, Jasper, Rui, Pavel, Owen; #694801, #694725, + #694641, #694393, #678917, #695093, #694837, #695135, #694771, #694321] + +Contributors: + Giovanni Campagna, Adel Gadllah, Rui Matos, Florian Müllner, + Jasper St. Pierre, Ray Strode, Owen Taylor, Pavel Vasin + +Translations: + Daniel Mustieles [es], Yaron Shahrabani [he], A S Alam [pa], Piotr Drąg [pl], + Gheyret Kenji [ug], Alexandre Franke [fr], Milo Casagrande [it], + Fran Diéguez [gl], Dimitris Spingos [el], Мирослав Николић [sr, sr@latin], + Chao-Hsiung Liao [zh_HK, zh_TW], Nguyễn Thái Ngọc Duy [vi], + Aurimas Černius [lt], Mario Blättermann [de], Kjartan Maraas [nb] + +3.7.90 +====== +* Support _NET_WM_OPAQUE_REGION [Jasper, Adel; #679901] +* Add wrapper for XI2.3 pointer barriers [Jasper; #677215] +* Update style of resize popups [Cosimo; #692741] +* Implement compositor <-> application frame synchronization [Owen; #685463] +* Handle animated backgrounds [Ray; #682427] +* Add a new window group for override-redirect windows [Gayan; #633620] +* Pass on pointer events on guard window to Clutter [Jasper; #681540] +* Show correct shortcut in window menus [Giovanni; #694045] +* Don't put minimized windows at the back of alt-tab [Jasper; #693991] +* Misc bug fixes and cleanups [Jasper, Rico, Adel, Florian, Rui, Giovanni, + Owen; #692679, #693354, #690581, #693439, #692718, #693475, #693482, #693540, + #690580, #680990, #693833, #693922, #693854, #694224] + +Contributors: + Giovanni Campagna, Cosimo Cecchi, Adel Gadllah, Rui Matos, Florian Müllner, + Gayan Perera, Jasper St. Pierre, Ray Strode, Owen Taylor, Rico Tzschichholz + +Translations: + Fran Diéguez [gl], A S Alam [pa], Alexandre Franke [fr], Aurimas Černius [lt], + Мирослав Николић [sr, sr@latin], Fran Diéguez [gl], Piotr Drąg [pl], + Luca Ferretti [it], Daniel Mustieles [es] + +3.7.5 +===== +* Don't allow multiline window titles [Jon; #683056] +* Make meta_window_located_on_workspace() public [Jasper; #691744] +* Request XI2.3 [Colin; #692877] +* Add meta_window_set_icon_geometry() method [Florian; #692997] +* Require XFixes 5.0 [Jasper; #677215] +* Change unredirection hints to match spec changes [Adel; #693064] +* Improve unredict heuristicts [Adel; #683786] +* Misc bug fixes and cleanups [Florian, Jasper, Adel; #691874, #679901, + #692952, #693042] + +Contributors: + Adel Gadllah, William Jon McCann, Florian Müllner, Jasper St. Pierre, + Colin Walters + +Translations: + Daniel Mustieles [es], Ihar Hrachyshka [be], Nilamdyuti Goswami [as], + Gheyret Kenji [ug], Kjartan Maraas [nb], Yaron Shahrabani [he], + Piotr Drąg [pl], Chao-Hsiung Liao [zh_HK,zh_TW], Milo Casagrande [it] + +3.7.4 +===== +* Add support for bypass compositor hints [Adel; #683020] +* Make automaximization optional [Adel; #680990] +* Add method for checking if the application is responding [Giovanni; #684340] +* Expose the xinput opcode [Jasper; #690590] +* Rebrand "minimize" as "hide" [Florian; #682887] +* Misc bug fixes and cleanups [Giovanni, Ray, Jasper, Matthias, Debarshi, + Florian, Rui; #690454, #690573, #690593, #690956, #691363, #690609, #690317, + #689263] + +Contributors: + Giovanni Campagna, Matthias Clasen, Adel Gadllah, Rui Matos, Florian Müllner, + Debarshi Ray, Jasper St. Pierre, Ray Strode + +Translations: + Mattias Põldaru [et], Yaron Shahrabani [he], Daniel Mustieles [es], + Khaled Hosny [ar], Fran Diéguez [gl], A S Alam [pa], Piotr Drąg [pl], + Rafael Ferreira [pt_BR], Nilamdyuti Goswami [as], Alexander Shopov [bg], + Matej Urbančič [sl] + +3.7.3 +===== +* Fix maximized windows jumping to other monitors [Alban; #556696] +* Add 'switch-applications' keybinding [Florian; #688913] +* Add a convenience method to focus the default window [Jasper; #689652] +* Increase typical icon size to 96 [Jasper; #689651] +* Port to XInput2 [Jasper; #688779] +* Give dynamic keybindings a keybinding action [Florian; #682315] +* Misc. fixes and cleanups [Jasper, Rui; #688777] + +Contributors: + Alban Crequy, Rui Matos, Florian Müllner, Jasper St. Pierre + +Translations: + Nilamdyuti Goswami [as], Piotr Drąg [pl], Yaron Shahrabani [he], + Dr.T.Vasudevan [ta], ManojKumar Giri [or], Shankar Prasad [kn] + +3.7.2 +===== +* Fix spurious focus changes when showing desktop [Florian; #686928] +* MetaPluginManager: don't send events to Clutter twice [Owen; #686406] +* Add the ability to add shader hooks to MetaBackgroundActor [Giovanni; #669798] +* Only process keyboard mapping events for the core X keyboard [Rui; #674859] +* Import keybinding files from Metacity [Florian; #687672] +* Add compositor hook to process keybindings selectively [Florian; #688202] +* MetaBackgroundActor: add a setter for GLSL uniforms [Giovanni; #682536] +* Misc. fixes and cleanups [Jasper, Rui, Florian, Rico; #688182] + +Contributors: + Giovanni Campagna, Rui Matos, Florian Müllner, Jasper St. Pierre, + Owen Taylor, Rico Tzschichholz + +Translations: + Rafael Ferreira [pt_BR], Tobias Endrigkeit [de], Yaron Shahrabani [he] + +3.7.1 +===== +* screen: Ignore num-workspaces when using dynamic workspaces [Florian; #685439] + +Contributors: + Florian Müllner + +Translations: + Mattias Põldaru [et], Kjartan Maraas [nb], Мирослав Николић [sr, sr@latin], + Marek Černocký [cs], Andika Triwidada [id], Daniel Mustieles [es], + Fran Diéguez [gl], Matej Urbančič [sl] + +3.6.1 +===== +* Fix crash when opening large popup menus [Jasper; #681676] +* window: Don't move the desktop window after monitor hotplug [Jasper; #681159] +* Expose MetaPlugin to introspection [Evan; #671098] +* Optionally delay focus changes in focus-follows-mouse mode [Florian; #678169] +* Resize the guard window when the X screen is resized [Benjamin; #670396] +* display: Only manage the default X screen [Jürg; #648156] +* Misc cleanups: [Owen; #587255] + +Contributors: + Benjamin Berg, Jürg Billeter, Evan Broder, Florian Müllner, Jasper St. Pierre, + Owen Taylor + +Translations: + Alexandre Franke [fr], Theppitak Karoonboonyanan [th], Sayak Sarkar [bn_IN], + Sandeep Sheshrao Shedmake [mr], Ask H. Larsen [da], Shankar Prasad [kn], + Alexander Shopov [bg], Aurimas Černius [lt], Ihar Hrachyshka [be], + Kjartan Maraas [nb], Daniel Mustieles [es], Changwoo Ryu [ko], + Yuri Myasoedov [ru], Tom Tryfonidis [el], Rūdolfs Mazurs [lv], + Chris Leonard [en_GB], Piotr Drąg [pl], Fran Diéguez [gl], Gil Forcada [ca], + Matej Urbančič [sl], Andika Triwidada [id], Carles Ferrando [ca] + +3.6.0 +===== + +Translations: + Alexander Shopov [bg], Daniel Korostil [uk], Rajesh Ranjan [hi], + Krishnababu Krothapalli [te], Ani Peter [ml], Rūdolfs Mazurs [lv], + Sweta Kothari [gu], Ihar Hrachyshka [be], Noriko Mizumoto [ja], + Timo Jyrinki [fi], Mattias Põldaru [et] + +3.5.92 +====== +* screen: Allow NULL out arguments in meta_screen_get_size [Tomeu] +* display: Add API to set wm_name / wm_keybindings [Florian; #671010] +* Improve the not responding dialog [Jon, Florian; #684306] +* Misc. bugfixes [Jasper] + +Contributors: + William Jon McCann, Florian Müllner, Jasper St. Pierre, Tomeu Vizoso + +Translations: + Gabor Kelemen [hu], Piotr Drąg [pl], Dr.T.Vasudevan [ta], Bruce Cowan [en_GB], + Alexandre Franke [fr], Theppitak Karoonboonyanan [th], Gil Forcada [ca], + Carles Ferrando [ca@valencia], Tobias Endrigkeit [de], Tom Tryfonidis [el], + Nguyễn Thái Ngọc Duy [vi], Changwoo Ryu [ko], Ask H. Larsen [da], + Rafael Ferreira [pt_BR], Marek Černocký [cs] + +3.5.91 +====== +* Do not include markup in app not responding dialog [Alex] +* Fix subtracting unredirected windows from visible region [Jasper; #677116] +* Minor improvements and bugfixes [Jasper, Florian; #682648, #682993] + +Contributors: + Alexander Larsson, Florian Müllner, Jasper St. Pierre + +Translations: + Dirgita [id], Piotr Drąg [pl], A S Alam [pa], Yuri Myasoedov [ru], + Milo Casagrande [it], Nilamdyuti Goswami [as], Tom Tryfonidis [el], + Duarte Loreto [pt], Fran Diéguez [gl], Nguyễn Thái Ngọc Duy [vi], + Aurimas Černius [lt], Daniel Nylander [sv] + +3.5.90 +====== +* Fix logic for handling translations of the windows group [Owen; #681221] +* Handle painting inside a Clutter clone [Owen; #681953] +* Update overlay-key on settings changes [Florian; #681906] +* Add keybinding for overlay-key [Florian; #665547] +* Minor fixes and improvements [Javier, Florian] + +Contributors: + Javier Jardón, Florian Müllner, Owen Taylor + +Translations: + Sweta Kothari [gu], Muhammet Kara [tr], Khaled Hosny [ar], + Sandeep Sheshrao Shedmake [mr] + +3.5.5 +===== +* Fix flickering around windows when using window group [Tom; #681221] + +Contributor(s): + Tom Beckmann + +Translations: + Chao-Hsiung Liao [zh_HK, zh_TW], Matej Urbančič [sl], Fran Diéguez [gl], + Мирослав Николић [sr, sr@latin], Yaron Shahrabani [he], Kjartan Maraas [nb] + +3.5.4 +===== +* Make it possible to reimplement move-to-workspace keybindings from plugins + [Giovanni; #674104] +* Add a preference to ignore hide-titlebar-when-maximized hint [Rico; #678947] +* window: Also use hide-titlebar-when-maximized when tiled [Florian; #679290] +* Center modal dialogs on their parent instead [Florian; #674499] +* Reduce amount of markup in translated messages [Matthias; #679660] +* Fix focus problem after closing a window with focus-follows-mouse + [Jasper; #675982] +* Handle changes of the attach-modal-dialogs preference [Florian; #679904] +* Do not restore tiling on unmaximize [Florian; #677565] +* Misc. fixes and cleanups [Jasper Adriaanse, Jasper, Debarshi, Pavel; + #679153, 673824] + +Contributors: + Jasper Lievisse Adriaanse, Giovanni Campagna, Matthias Clasen, Florian Müllner, + Debarshi Ray, Jasper St. Pierre, Rico Tzschichholz, Pavel Vasin + +Translations: + Alexander Shopov [bg], Kjartan Maraas [nb], Yaron Shahrabani [he], + Nilamdyuti Goswami [as], Ihar Hrachyshka [be], Daniel Mustieles [es] + +3.5.3 +===== +* Simplify plugin system [Jasper; #676855] +* meta-window-actor: Don't unredirect shaped windows [Jasper; #677657] +* screen: Add new public meta_screen_get_current_monitor API [Tim; #642591] +* frames: Increase the size of resize corners [Jasper; #677669] +* window: Make some window methods public [Jasper; #678126] +* Fix crash when running mutter stand-alone [Jasper; #678238] +* meta-window-actor: Fix potential crash in shaping code [Jasper; #677977] +* Misc. fixes [Jasper, Marc-Antoine, Rico] + +Contributors: + Tim L, Marc-Antoine Perennou, Jasper St. Pierre, Rico Tzschichholz + +Translations: + + Daniel Mustieles [es], Matej Urbančič [sl], Khaled Hosny [ar], + Bruno Brouard [fr], Fran Diéguez [gl] + +3.5.2 +===== +* keybindings: Remove 'toggle-recording' binding [Florian; #674376] +* Switch to gtk-doc syntax [Jasper; #673752] +* shaped-texture: never slice shape mask texture [Robert; #674731] +* Make Mutter stop relying on Cogl including a GL header [Neil; #672711] +* Make support for "XFree86" Xinerama mandatory [Owen; #674727] +* meta_window_move_frame(): fix crash when frame is NULL [Owen; #675254] +* Fix memory leaks [Pavel; #672640] +* Code cleanups [Jasper; #671104 #674876 #676052] +* Look for themes in XDG user data dir [Jasper; #675316] +* Remove frame pixel caching [Jasper; #675111] +* stack: Ignore keep-on-top property on maximized windows [Florian; #673581] +* Misc. fixes [Javier, Jasper, Owen, Rico] + +Contributors: + Robert Bragg, Javier Járdon, Florian Müllner, Neil Roberts, Jasper St. Pierre, + Owen Taylor, Rico Tzschichholz, Pavel Vasin + +Translations: + Praveen Illa [te], Luca Ferretti [it], Daniel Mustieles [es] + +3.4.1 +===== +* API change: the meta_display_add_keybinding() function added in 3.4 + wasn't usable from a GNOME Shell extension, so has been changed to take + a GSettings object rather than the name of a schema [Jasper; #673014] +* Don't try to auto-maximize not-maximizable windows; this fixes the problem + with the Nautilus desktop window being mis-positioned when enabled + [Owen; #673566] +* Fix a crash in the default plugin (not used in GNOME) [Giovanni; #673809] +* Make the key work when set as the mouse button modifier + [Florian; #662476] + +Contributors: + Giovanni Campagna, Florian Muellner, Jasper St. Pierre, Owen Taylor + +Translations: + Khaled Hosny [ar], Jordi Serratosa [ca], Carles Ferrando [ca@valencia], + Christian Kirbach [de], Kristjan Schmidt [eo], Arash Mousavi [fa], + Jiro Matsuzawa [ja], Shankar Prasad [kn], Aurimas Černius [lt], + Yinghua Wang [zh_CN] + +3.4.0 +===== +* Fix crash when a full-screen window is opened [Jasper; #672797] +* Fix memory leaks [Pavel; #672640] + +Contributors: + Jasper St. Pierre, Pavel Vasin + +Translations: + Marek Černocký, Petr Kovar [cz], Bruno Brouard [fr], Sweta Kothari [gu], + Yaron Shahrabani [he], Changwoo Ryu [kr], Enrico Nicoletto [pt_BR], + Yuri Myasoedov [ru], Muhammet Kara [tr], Nguyễn Thái Ngọc Duy [vi] + +3.3.92 +====== +* Automaximize large windows on map [Adel; #671677] +* When unmaximizing windows, make sure the unminimized size + is signficantly less than the maximized size [Adel; #671677] +* Don't offer maximize option for windows larger than the screen + [Jasper; #643606] +* Always focus the window immediately underneath without restacking + when closing a window [Jasper; #620744] +* Avoid drawing shadows when two windows are tiled together [Rui; #643075] +* Remove tooltips for window decorations [Florian; #645101] +* Add org.gnome.mutter.dynamic-workspaces GSetting - when this is set + to true, workspace counts are never saved to GSettings, avoiding + pointless disk traffic for GNOME dynamic workspaces [Florian; #671568] +* Add ::grab-op-begin, ::grab-op-end signals to MetaDisplay [Jasper; #670658] +* Add meta_display_get_ignored_modifier_mask() [Florian; #665215] +* Remove pointless wrapper methods on MetaPlugin [Jasper; #671103] +* Fix frame drawing with 3.3.x GTK+ releases [Florian; #671796] +* Build fixes [Jasper, Rico, Rui] +* Misc bug fixes [Damien, Jasper, Lionel, Marius, Owen, Rui; + #661256, #667437, #671601, #671087, #672374] + +Contributors: + Stefano Facchini, Adel Gadllah, Lionel Landwerlin, Mariusz Libera, + Rui Matos, Florian Müllner, Jasper St. Pierre, Damien Radtke, Owen Taylor, + Rico Tzschichholz + +Translations: + Nilamdyuti Goswami [as], Ihar Hrachyshka [be], Alexander Shopov [bg], + David Planella [ca], Carles Ferrando [ca@valencia], Kenneth Nielsen [dk], + Bruce Cowan [en_GB], Daniel Mustieles [es], Mattias Põldaru [et], + Inaki Larranaga Murgoitio [eu], Timo Jyrinki [fi], Fran Diéguez [gl], + Gabor Kelemen [hu], Changwoo Ryu [ko], Anita Reitere [lv], + Kjartan Maraas [nb], Wouter Bolsterlee [nl], A S Alam [pa], Piotr Drąg [pl], + Duarte Loreto [pt], Yuri Myasoedov [ru], Daniel Nylander [se], + Matej Urbančič [sl], Miroslav Nikolić [sr], Tirumurti Vasudevan [ta], + Sasi Bhushan [te], Daniel Korostil [uk], Nguyễn Thái Ngọc Duy [vi], + YunQiang Su [zh_CN], Chao-Hsiung Liao [zh_HK, zh_TW] + +3.3.90 +====== +* Update for Cogl API changes [Robert] +* Bug fixes [Adel, Jasper; #659643] +* Build fixes [Jasper, Owen] + +Contributors: + Robert Bragg, Adel Gadllah, Jasper St. Pierre, Owen Taylor + +Translations: + Ask H. Larsen [dk], Miroslav Nikolić [sr] + +3.3.5 +===== +* MetaShapedTexture no longer is a ClutterTexture subclass [Jasper; #660941] +* Add meta_shaped_texture_get_image() [Jasper; #660941] +* Cleanups [Rui, Jasper; #657639] +* Depend on GTK+ 3.3.7 [Rico] + +Contributors: + Rui Matos, Jasper St. Pierre, Rico Tzschichholz + +Translations: + Kjartan Maraas [nb], Chao-Hsiung Liao [zh_HK, zh_TW] + +3.3.4 +===== +* Adapt to changes in GtkStateFlags [Owen] +* Redo properties for applications menu corresponding to GTK+ changes - + they are now _GTK_* not DBUS_*. [Ryan] +* Fix crash on gnome-shell restart when a modal dialog is open [Owen; #668299] +* Code cleanup [Florian; #666039] + +Contributors: + Ryan Lortie, Florian Müllner, Owen Taylor + +Translations: + Alexander Shopov [bg], Fran Diéguez [gl] + +3.3.3 +===== +* Add keybindings for tiling to left or right [Florian; #648700] +* Support GTK+'s hide-titlebar-when-maximized hint [Florian; #665617] +* Load _DBUS_APPLICATION_ID, _DBUS_UNIQUE_NAME, _DBUS_OBJECT_PATH + property [Colin, Ryan; #664851] +* Handle changes to workspaces-only-on-primary GSetting [Florian; #664853] +* Don't use the Clutter default stage [Jasper; #664028] +* Fix compilation with --disable-introspection [Lionel; #661871] +* Fix problem where stage could end up mis-sized on startup with + multiple monitors [Lionel] +* Misc bug fixes [Adel, Lionel, Jasper; #666015] + +Contributors: + Adel Gadllah, Lionel Landwerlin, Florian Müllner, Jasper St. Pierre + +Translations: + Daniel Mustieles [es], Yaron Shahrabani [he], Kjartan Maraas [nb], + Matej Urbančič [sk], Muhammet Kara [tr] + +3.3.2 +===== + +* Move from GConf to GSettings for preferences [Florian; #635378] +* Add meta_display_add_keybinding()/meta_display_remove_keybinding() + to allow creating new keybindings at runtime [Florian; #663428] +* Add suport for new _NET_WM_STATE_FOCUSED atom in _NET_WM_STATE + to allow applications to draw unfocused windows differently + [Rui; #661427] +* Add meta_window_move_resize_frame() to allow specifying the + size and position of a window via the outside dimensions of the + window frame. +* Don't activate window tiling when moving in snap mode + [Rui; #662270] +* Remove the ability to resize a window from the inner edge of + the titlebar [Jasper; #660129] +* Fix for deprecations in GTK+ [Jasper, Rico; #662574, #662895] +* Misc bug fixes [Jasper, Rico, Rui; #662895, #642652, #660941, #662225] + +Contributors: + Tim Cuthbertson, Rui Matos, Florian Müllner, Jasper St. Pierre, Rico Tzschichholz + +Translations: + Jorge González (es), Kjartan Maraas (nb), Krishnababu Krothapalli (te), Nguyễn Thái Ngọc Duy (vi) + 3.2.1 ===== * Allow keyboard window switching (alt-Tab) during drag-and-drop @@ -57,7 +2839,7 @@ Translations: slow [#658228, Jasper, Adel] * When a monitor is plugged or unplugged, keep existing windows on their current monitor [#645408, Alex] -* Remove 'Muffin' title from alerts such as +* Remove 'Mutter' title from alerts such as "The widow '%s' is not responding" [Matthias] * Remove pointless warning: Received a _NET_WM_MOVERESIZE message for %s; these @@ -95,7 +2877,7 @@ Contributors: * Unredirect override-redirect fullscreen windows, such as full-screen 3D games to avoid any performance impact [Adel; #597014] * Add :resizable and :above properties to MetaWindow. [Tim; #653858] -* Add MUFFIN_DISABLE_FALLBACK_COLOR environment variable to allow visualizing +* Add MUTTER_DISABLE_FALLBACK_COLOR environment variable to allow visualizing places where a color is missing for gtk:custom() colors [Florian; #656112] * Don't attach modal dialogs to special windows like the desktop; add meta_window_is_attached_dialog() [Dan, #646761] @@ -166,7 +2948,7 @@ Translations: compositors that get it wrong. [Colin, Owen; #653121] * Remove behavior where left clicking on a window border with the titlebar offscreen gave the window menu [Florian; #652369] -* Don't set the global default textdomain, since Muffin is +* Don't set the global default textdomain, since Mutter is a library as well as an application [Dan; #649202] * Exit with the right (success or failure) exit status [Dan] * Code cleanup [Florian] @@ -184,7 +2966,7 @@ Translations: 3.0.2.1 ======= * When saving the session, use the "program name" rather than - harcoding muffin, fixing session saving for gnome-shell [Matthias] + harcoding mutter, fixing session saving for gnome-shell [Matthias] https://bugzilla.gnome.org/show_bug.cgi?id=648828 Contributors: @@ -294,11 +3076,11 @@ Translations: - Allow resizing [Florian] - Constrain to be on the current monitor [Florian] * Don't turn on XSMP autorestart [Colin] - * Combine libmuffin-wm and libmuffin-private into a single libmuffin + * Combine libmutter-wm and libmutter-private into a single libmutter [Frédéric] * Export methods to move and resize windows [Jeffery] meta_window_move(), meta_window_resize(), meta_window_move_frame() - * Add a MUFFIN_WM_CLASS_FILTER environment variable to allow existing + * Add a MUTTER_WM_CLASS_FILTER environment variable to allow existing windows to be ignored when performance testing. [Owen] * Add a new compositor-based flash for visual bell [Dan] * Fix bug where application specified values for properties like @@ -329,9 +3111,9 @@ Bugs fixed: 642787 MetaWindowActor has a dangling reference to its MetaWindow 643597 Attached dialogs not resizable, even by app request 644188 Broken build of 2.91.91 - 644252 Add MUFFIN_WM_CLASS_FILTER environment variable + 644252 Add MUTTER_WM_CLASS_FILTER environment variable 644529 session: Change XSMP restart style to Never - 644565 Kill libmuffin-private ? + 644565 Kill libmutter-private ? 644961 auto-tiling makes moving already-tiled windows hard 645224 Translation message doesn't make much sense 645247 Methods of Meta.Rectangle are missing annotations. @@ -340,15 +3122,15 @@ Bugs fixed: 2.91.91 ======= - * Build a libmuffin-wm that contains all of the logic and that - can be linked to to create custom executables. The muffin executable + * Build a libmutter-wm that contains all of the logic and that + can be linked to to create custom executables. The mutter executable becomes a small stub linked to this library [Dan] * Move installed headers files into a meta/ subdirectory instead of polluting the toplevel namespace [Dan] * Remove various unused complications: [Dan] - Ability to set the set of plugins via GConf - Plugin 'params' - - meta_restart() and "muffin-message restart" + - meta_restart() and "mutter-message restart" * Don't exit when we are requested to exit via XSMP, assume we'll be killed along with the X server; this avoids visual artifacts from unmanaging windows when logging out [Colin] @@ -363,7 +3145,7 @@ Translations: Bugs fixed: 643194 patch: expose new meta_window_get_window_rect 643437 Don't exit on XSMP request - 643959 Make muffin into a library + 643959 Make mutter into a library 2.91.90 ======= @@ -417,7 +3199,7 @@ Translations: * Add a Above_Tab key symbol that can be used in key bindings to mean the key above the Tab key. This is now the default binding for - cycle_group in both Muffin and Metacity. [Owen] + cycle_group in both Mutter and Metacity. [Owen] * Add new frame states for tiled-on-the-left and tiled-on-the-right [Florian] * Add new background drawing functions that can be defined in a theme for single buttons. [Florian] @@ -433,7 +3215,7 @@ Translations: Mattias Põldaru, Ivar Smolin [et], Gheyret T. Kenji [ug] Bugs fixed: - 613124 Invalid visibility-related asserts in MuffinWindow + 613124 Invalid visibility-related asserts in MutterWindow 626875 Fix handling of --composite and --no-composite command line options 629282 [PATCH] Fix errors building for gles-systems (clutter-eglx) 635569 Add an "Above_Tab" pseudo-keysym @@ -481,7 +3263,7 @@ Bugs fixed: - Pay attention to partial stage repaints in obscured window calculations - Better optimization of painting obscured shadows; turn off shadows for maximized windows. - - Move background repainting into Muffin; doing it here rather than + - Move background repainting into Mutter; doing it here rather than in plugins allows not painting obscured parts of the background. * A new frame type 'attached' is added for attached modal dialogs and can be referenced in theme files with a theme version of 3.2. @@ -536,11 +3318,11 @@ Bugs fixed: ====== * Default build is now GTK+ 3 build -* Muffin namespace prefix is removed, in favor of consistent +* Mutter namespace prefix is removed, in favor of consistent meta_ namespace prefixing [Owen]. Naming changes: - MuffinWindow => MetaWindowActor - muffin_get_windows => meta_get_window_actors - muffin_plugin_get_windows => meta_plugin_get_window_actors + MutterWindow => MetaWindowActor + mutter_get_windows => meta_get_window_actors + mutter_plugin_get_windows => meta_plugin_get_window_actors * Add missing values in MetaKeyBindingAction - this fixes a problem where key binding lookup wasn't working properly for some key bindings. [Dan] * Remove keysym parameter to meta_display_get_keybinding_action() - the @@ -582,8 +3364,8 @@ Fixed bugs: * Draw with Cairo rather than GDK [Florian, Benjamin] * Add compatibility for changes in GTK+ 3 [Benjamin, Alban, Florian, Jasper, Matthias, Owen, Thierry] - - libmuffin-private is now only installed for GTK+ 3 builds - - Theme parts of libmuffin-private API are changed to take cairo_t + - libmutter-private is now only installed for GTK+ 3 builds + - Theme parts of libmutter-private API are changed to take cairo_t rather than GdkDrawable * Update introspection build and annotations for new behavior of g-ir-scanner [Colin] @@ -618,22 +3400,22 @@ Fixed Bugs: 613126 Do not cancel Alt+Tab grab due to Shift key events 623235 BadDamage error from XSubtractDamage 624757 Check for TFP usage after actually setting the pixmap - 625712 [muffin-shaped-texture] Remove material_workaround + 625712 [mutter-shaped-texture] Remove material_workaround 626583 Replace Gdk drawing API with cairo 627087 Mipmap emulation not working 627210 Crash with X error 628544 introspection: Build with --warn-fatal, drop fix-meta-rectangle.py hack 629127 build problem with recent gtk3 - 629232 Multiple syntax errors in file muffin-message.c when building Muffin for + 629232 Multiple syntax errors in file mutter-message.c when building Mutter for GNOME Shell dependencies - 629350 [muffin-shaped-texture] Use a base material for all instances + 629350 [mutter-shaped-texture] Use a base material for all instances 629931 Allow breaking out from maximization/tiling during a mouse resize 630195 Use GDK error trapping straight-up - 630203 Prepare muffin code for GTK3 rendering-cleanup - 630671 prepare muffin for the demise of GtkObject + 630203 Prepare mutter code for GTK3 rendering-cleanup + 630671 prepare mutter for the demise of GtkObject 630843 gtk_window_set_visual was replaced by gtk_widget_set_visua 631147 Adapt to GTK API changes - 631175 Muffin error compiling Gnome Shell + 631175 Mutter error compiling Gnome Shell 2.31.5 ====== @@ -657,7 +3439,7 @@ Fixed Bugs: 587991 - Remove deprecated GTK+ symbols 616275 - -Werror should not be enabled by default (or should be possible to disable) 622303 - Allow building with Gtk+-3.0 - 622800 - Make muffin more gtk+ 3.0 friendly + 622800 - Make mutter more gtk+ 3.0 friendly 623335 - Make MetaRectangle a boxed type 623639 - Work around g-ir-scanner problem with Gdk.Rectangle 624166 - src/core/util.c: Fix warning in case WITH_VERBOSE_MODE is not set @@ -665,7 +3447,7 @@ Fixed Bugs: 2.31.4 ====== -* Clean up MuffinPlugin effect interface [Maxim] +* Clean up MutterPlugin effect interface [Maxim] * Track damage as the bounding box, a significant optimizations for rapidly drawing clients [Robert] * Add meta_window_is_remote() [Colin] @@ -683,7 +3465,7 @@ Fixed Bugs: 611838 - expose sub-stage redraws by streaming raw updates to ClutterX11TexturePixmap 620585 - Add meta_window_is_remote 620860 - function ‘meta_display_open’ - 621082 - MuffinPluginManager should call plugin->switch_workspace, + 621082 - MutterPluginManager should call plugin->switch_workspace, when screen doesn't have any window. Or function should be renamed. 621413 - Maximize/Unmaximize not behaving properly for some non-gnome based programs @@ -704,7 +3486,7 @@ Fixed Bugs: * Add meta_prefs_override_preference_location(); this allows a plugin like GNOME Shell to redirect preferences to a plugin-specific location. [Owen] -* Support a _MUFFIN_HINTS window property; this is a string +* Support a _MUTTER_HINTS window property; this is a string property holding key-value pairs with plugin-specific interpretation [Tomas] * Build with GSEAL_ENABLE [Florian, Javier] @@ -744,10 +3526,10 @@ Fixed Bugs: 613136 - remove over-restrictive assert from meta_prefs_get_workspace_name() 613398 - Don't trap XErrors in meta_compositor_process_event 615586 - Allow redirecting preferences to a different GConf key - 615672 - cant' compile muffin error: dereferencing pointer ‘p’ does break + 615672 - cant' compile mutter error: dereferencing pointer ‘p’ does break strict-aliasing rules 616050 - alt-tab infrastructure patches - 616274 - muffin from git fails with gcc 4.5 (on new warning) + 616274 - mutter from git fails with gcc 4.5 (on new warning) 616546 - On dual screen maximized windows dragged to the second screen no longer update their contents 618138 - Work around COGL bug causing flash for new windows @@ -773,7 +3555,7 @@ Translations: Fixed Bugs: 610862 Support and require Clutter 1.1 - 612506 muffin 2.29.0 fails to compile on Solaris + 612506 mutter 2.29.0 fails to compile on Solaris 613100 [MetaDisplay] Expose meta_display_get_keybinding_action 613121 Remove workaround for multitexturing with old intel drivers 613128 [MetaWindow] Accessor for the instance part of WM_CLASS property @@ -811,26 +3593,26 @@ Fixed Bugs: 588065 Adds demands-attention signal to the window class 591913 Fails to skip current window on alt+tab when another window is asking for attention - 592567 Dereferencing NULL in muffin_window_get_workspace() + 592567 Dereferencing NULL in mutter_window_get_workspace() 597052 Add signal to MetaDisplay so we know when a window has demanded-attention 598289 Add "window-created" signal to MetaDisplay, "unmanaged" signal for MetaWindow 598473 "XXX specified twice for this theme" messages not in sync with metacity. - 598600 "Visual Bell" option in Metacity causes Muffin to crash + 598600 "Visual Bell" option in Metacity causes Mutter to crash 600068 notifications for window urgency hint 601228 rdesktop does not get keypress signals - 602349 [PATCH] trivial - fix compilation warning in muffin + 602349 [PATCH] trivial - fix compilation warning in mutter 602740 Remove XOR gc only used in removed reduced-resources mode 602870 Fix compilation with older libGL 604200 Compile issue: Use of deprecated clutter functions - 606388 muffin fails to build when using ld with --no-add-needed + 606388 mutter fails to build when using ld with --no-add-needed 607125 Fails to build with latest introspection data 607398 Do not use CGL_* symbols 607746 reduce gconf roundtrips at startup 608800 alt-dragging gimp windows crashes gnome-shell - 609350 Muffin does not support the COGL_DEBUG environment variable + 609350 Mutter does not support the COGL_DEBUG environment variable 609546 meta_workspace_set_builtin_struts(): optimize out non-changes 609585 Merge libcanberra usage from Metacity - 609657 Use cogl multitexture API when drawing MuffinShapedTexture + 609657 Use cogl multitexture API when drawing MutterShapedTexture 609665 Bug fixes from Fedora RPM 609710 screencast recording broke 610391 Fix crash on startup with list bindings @@ -841,7 +3623,7 @@ Fixed Bugs: * New exported API: meta_window_get_stable_sequence() [Colin] meta_window_get_transient_for_as_xid() [Tomas] - MuffinScreen::workareas-changed signal [Tomas] + MutterScreen::workareas-changed signal [Tomas] * Fix a problem where changes processed from a Clutter event callback wouldn't get handled before the screen was next repainted, causing flashing [Owen] @@ -881,9 +3663,9 @@ Translation: [Colin, Dan] -* Set _GNOME_WM_KEYBINDINGS=Metacity,Muffin on the _NET_SUPPORTING_WM_CHECK +* Set _GNOME_WM_KEYBINDINGS=Metacity,Mutter on the _NET_SUPPORTING_WM_CHECK window so that gnome-keybinding-properties can figure out to show the - Metacity keybindings when Muffin is running. [Owen] + Metacity keybindings when Mutter is running. [Owen] * Bug and build fixes [Colin, Owen] @@ -899,7 +3681,7 @@ Bugs fixed: 592393 - Clicking on a minimized window in the overview doesn't focus the window 593399 - Add meta_display_get_grab_op() - 593404 - Make MUFFIN_DEBUG_XINERAMA override active Xinerama + 593404 - Make MUTTER_DEBUG_XINERAMA override active Xinerama 593407 - Add 'skip-taskbar' accessor to MetaWindow. 593686 - Add meta_screen_get_monitors() 594067 - Export a _GNOME_WM_KEYBINDINGS property @@ -910,7 +3692,7 @@ Bugs fixed: * Key handling improvements: - enforce that every key is handled no more than once. - - muffin_plugin_begin_modal() and muffin_plugin_begin_modal() allow + - mutter_plugin_begin_modal() and mutter_plugin_begin_modal() allow putting a plugin into a "modal" state where it has exclusive access to key and pointer events. - Add "tab_popup_select", "tab_pop_cancel" pseudo-keypress-handlers @@ -948,13 +3730,13 @@ Bugs fixed: 591367 - Be silent by default 591566 - install errors.h header ... 591788 - Add meta_window_is_override_redirect - 591836 - muffin mishandles opacity + 591836 - mutter mishandles opacity 591913 - Fails to skip current window on alt+tab when another window is asking for attention 592393 - Clicking on a minimized window in the overview doesn't focus the window 592699 - Remove deprecated Encoding key from desktop files 592742 - Avoid accessing freed memory when being replaced 593399 - Add meta_display_get_grab_op() - 593404 - Make MUFFIN_DEBUG_XINERAMA override active Xinerama + 593404 - Make MUTTER_DEBUG_XINERAMA override active Xinerama 593407 - Add 'skip-taskbar' accessor to MetaWindow. ----------------------------- Older Metacity News ----------------------------- diff --git a/README b/README deleted file mode 100644 index c9fcbadf1..000000000 --- a/README +++ /dev/null @@ -1,6 +0,0 @@ -Muffin -====== - -The Cinnamon Window Manager - -Based on Mutter 3.2.1 diff --git a/README-Mutter b/README-Mutter deleted file mode 100644 index e129c104f..000000000 --- a/README-Mutter +++ /dev/null @@ -1,422 +0,0 @@ -Metacity is not a meta-City as in an urban center, but rather -Meta-ness as in the state of being meta. i.e. metacity : meta as -opacity : opaque. Also it may have something to do with the Meta key -on UNIX keyboards. - -The first release of Metacity was version 2.3. Metacity has no need for -your petty hangups about version numbers. - -The stable releases so far are 2.4.x, 2.6.x, 2.8.[01], 2.8.1.x, 2.8.5-, -2.10.x, 2.12.x, 2.14.x, 2.16.x. - -Unstable branches are 2.3.x, 2.5.x, 2.8.2-4, 2.9.x, 2.11.x, 2.13.x, -2.15.x, 2.17.x. - -COMPILING MUFFIN -=== - -You need GTK+ 2.2. For startup notification to work you need -libstartup-notification at -http://www.freedesktop.org/software/startup-notification/ or on the -GNOME ftp site. -You need Clutter 1.0. You need gobject-introspection 0.6.3. - -REPORTING BUGS AND SUBMITTING PATCHES -=== - -Report new bugs on http://bugzilla.gnome.org. Please check for -duplicates, *especially* if you are reporting a feature request. - -Please do *not* add "me too!" or "yes I really want this!" comments to -feature requests in bugzilla. Please read -http://pobox.com/~hp/features.html prior to adding any kind of flame -about missing features or misfeatures. - -Feel free to send patches too; Metacity is relatively small and -simple, so if you find a bug or want to add a feature it should be -pretty easy. Send me mail, or put the patch in bugzilla. - -See the HACKING file for some notes on hacking Muffin. - -MUFFIN FEATURES -=== - - - Uses GTK+ 2.0 for drawing window frames. This means colors, fonts, - etc. come from GTK+ theme. - - - Does not expose the concept of "window manager" to the user. Some - of the features in the GNOME control panel and other parts of the - desktop happen to be implemented in metacity, such as changing your - window border theme, or changing your window navigation shortcuts, - but the user doesn't need to know this. - - - Includes only the window manager; does not try to be a desktop - environment. The pager, configuration, etc. are all separate and - modular. The "libwnck" library (which I also wrote) is available - for writing metacity extensions, pagers, and so on. (But libwnck - isn't metacity specific, or GNOME-dependent; it requires only GTK, - and should work with KWin, fvwm2, and other EWMH-compliant WMs.) - - - Has a simple theme system and a couple of extra themes come with it. - Change themes via gsettings: - gsettings set org.cinnamon.desktop.wm.preferences theme Crux - gsettings set org.cinnamon.desktop.wm.preferences theme Gorilla - gsettings set org.cinnamon.desktop.wm.preferences theme Atlanta - gsettings set org.cinnamon.desktop.wm.preferences theme Bright - - See theme-format.txt for docs on the theme format. Use - metacity-theme-viewer to preview themes. - - - Change number of workspaces via gsettings: - gsettings set org.cinnamon.desktop.wm.preferences num-workspaces 5 - - Can also change workspaces from GNOME 2 pager. - - - Change focus mode: - gsettings set org.cinnamon.desktop.wm.preferences focus-mode mouse - gsettings set org.cinnamon.desktop.wm.preferences focus-mode sloppy - gsettings set org.cinnamon.desktop.wm.preferences focus-mode click - - - Global keybinding defaults include: - - Alt-Tab forward cycle window focus - Alt-Shift-Tab backward cycle focus - Alt-Ctrl-Tab forward cycle focus among panels - Alt-Ctrl-Shift-Tab backward cycle focus among panels - Alt-Escape cycle window focus without a popup thingy - Ctrl-Alt-Left Arrow previous workspace - Ctrl-Alt-Right Arrow next workspace - Ctrl-Alt-D minimize/unminimize all, to show desktop - - Change keybindings for example: - - gsettings set org.cinnamon.desktop.wm.keybindings switch-to-workspace-1 '[F1]' - - Also try the GNOME keyboard shortcuts control panel. - - - Window keybindings: - - Alt-space window menu - - Mnemonics work in the menu. That is, Alt-space then underlined - letter in the menu item works. - - Choose Move from menu, and arrow keys to move the window. - - While moving, hold down Control to move slower, and - Shift to snap to edges. - - Choose Resize from menu, and nothing happens yet, but - eventually I might implement something. - - Keybindings for things like maximize window, vertical maximize, - etc. can be bound, but may not all exist by default. See - metacity.schemas. - - - Window mouse bindings: - - Clicking anywhere on frame with button 1 will raise/focus window - - If you click a window control, such as the close button, then the - control will activate on button release if you are still over it - on release (as with most GUI toolkits) - - If you click and drag borders with button 1 it resizes the window - - If you click and drag the titlebar with button 1 it moves the - window. - - If you click anywhere on the frame with button 2 it lowers the - window. - - If you click anywhere on the frame with button 3 it shows the - window menu. - - If you hold down Super (windows key) and click inside a window, it - will move the window (buttons 1 and 2) or show menu (button 3). - Or you can configure a different modifier for this. - - If you pick up a window with button 1 and then switch workspaces - the window will come with you to the new workspace, this is - a feature copied from Enlightenment. - - If you hold down Shift while moving a window, the window snaps - to edges of other windows and the screen. - - - Session management: - - Muffin connects to the session manager and will set itself up to - be respawned. It theoretically restores sizes/positions/workspace - for session-aware applications. - - - Muffin implements much of the EWMH window manager specification - from freedesktop.org, as well as the older ICCCM. Please refer to - the COMPLIANCE file for information on muffin compliance with - these standards. - - - Uses Pango to render text, so has cool i18n capabilities. - Supports UTF-8 window titles and such. - - - There are simple animations for actions such as minimization, - to help users see what is happening. Should probably - have a few more of these and make them nicer. - - - if you have the proper X setup, set the GDK_USE_XFT=1 - environment variable to get antialiased window titles. - - - considers the panel when placing windows and maximizing - them. - - - handles the window manager selection from the ICCCM. Will exit if - another WM claims it, and can claim it from another WM if you pass - the --replace argument. So if you're running another - ICCCM-compliant WM, you can run "muffin --replace" to replace it - with Metacity. - - - does basic colormap handling - - - and much more! well, maybe not a lot more. - -HOW TO ADD EXTERNAL FEATURES -=== - -You can write a muffin "plugin" such as a pager, window list, icon -box, task menu, or even things like "window matching" using the -Extended Window Manager Hints. See http://www.freedesktop.org for the -EWMH specification. An easy-to-use library called "libwnck" is -available that uses the EWMH and is specifically designed for writing -WM accessories. - -You might be interested in existing accessories such as "Devil's Pie" -by Ross Burton, which add features to Muffin (or other -EWMH-compliant WMs). - -MUFFIN BUGS, NON-FEATURES, AND CAVEATS -=== - -See bugzilla: http://bugzilla.gnome.org/query.cgi - -FAQ -=== - -Q: Will you add my feature? - -A: If it makes sense to turn on unconditionally, or is genuinely a - harmless preference that I would not be embarrassed to put in a - simple, uncluttered, user-friendly configuration dialog. - - If the only rationale for your feature is that other window - managers have it, or that you are personally used to it, or - something like that, then I will not be impressed. Metacity is - firmly in the "choose good defaults" camp rather than the "offer 6 - equally broken ways to do it, and let the user pick one" camp. - - This is part of a "no crackrock" policy, despite some exceptions - I'm mildly embarrassed about. For example, multiple workspaces - probably constitute crackrock, they confuse most users and really - are not that useful if you have a decent tasklist and so on. But I - am too used to them to turn them off. Or alternatively - iconification/tasklist is crack, and workspaces/pager are good. But - having both is certainly a bit wrong. Sloppy focus is probably - crackrock too. - - But don't think unlimited crack is OK just because I slipped up a - little. No slippery slope here. - - Don't let this discourage patches and fixes - I love those. ;-) - Just be prepared to hear the above objections if your patch adds - some crack-ridden configuration option. - - http://pobox.com/~hp/free-software-ui.html - http://pobox.com/~hp/features.html - -Q: Will Muffin be part of GNOME? - -A: It is not officially part of GNOME as of GNOME 2.27. We are - hoping to have muffin officially included as of GNOME 2.28. - -Q: Why does Muffin remember the workspace/position of some apps - but not others across logout/login? - -A: Muffin only stores sizes/positions for apps that are session - managed. As far as I can determine, there is no way to attempt to - remember workspace/position for non-session-aware apps without - causing a lot of weird effects. - - The reason is that you don't know which non-SM-aware apps were - launched by the session. When you initially log in, Metacity sees a - bunch of new windows appear. But it can't distinguish between - windows that were stored in your session, or windows you just - launched after logging in. If Metacity tried to guess that a window - was from the session, it could e.g. end up maximizing a dialog, or - put a window you just launched on another desktop or in a weird - place. And in fact I see a lot of bugs like this in window managers - that try to handle non-session-aware apps. - - However, for session-aware apps, Muffin can tell that the - application instance is from the session and thus restore it - reliably, assuming the app properly restores the windows it had - open on session save. - - So the correct way to fix the situation is to make apps - session-aware. libSM has come with X for years, it's very - standardized, it's shared by GNOME and KDE - even twm is - session-aware. So anyone who won't take a patch to add SM is more - archaic than twm - and you should flame them. ;-) - - Docs on session management: - http://www.fifi.org/doc/xspecs/xsmp.txt.gz - http://www.fifi.org/doc/xspecs/SMlib.txt.gz - - See also the ICCCM section on SM. For GNOME apps, use the - GnomeClient object. For a simple example of using libSM directly, - twm/session.c in the twm source code is pretty easy to understand. - -Q: How about adding viewports in addition to workspaces? - -A: I could conceivably be convinced to use viewports _instead_ of - workspaces, though currently I'm not thinking that. But I don't - think it makes any sense to have both; it's just confusing. They - are functionally equivalent. - - You may think this means that you won't have certain keybindings, - or something like that. This is a misconception. The only - _fundamental_ difference between viewports and workspaces is that - with viewports, windows can "overlap" and appear partially on - one and partially on another. All other differences that - traditionally exist in other window managers are accidental - - the features commonly associated with viewports can be implemented - for workspaces, and vice versa. - - So I don't want to have two kinds of - workspace/desktop/viewport/whatever, but I'm willing to add - features traditionally associated with either kind if those - features make sense. - -Q: Why is the panel always on top? - -A: Because it's a better user interface, and until we made this not - configurable a bunch of apps were not getting fixed (the app - authors were just saying "put your panel on the bottom" instead of - properly supporting fullscreen mode, and such). - - rationales.txt has the bugzilla URL for some flamefesting on this, - if you want to go back and relive the glory. - Read these and the bugzilla stuff before asking/commenting: - http://pobox.com/~hp/free-software-ui.html - http://pobox.com/~hp/features.html - -Q: Why is there no edge flipping? - -A: This one is also in rationales.txt. Because "ouija board" UI, where - you just move the mouse around and the computer guesses what you - mean, has a lot of issues. This includes mouse focus, shade-hover - mode, edge flipping, autoraise, etc. Metacity has mouse focus and - autoraise as a compromise, but these features are all confusing for - many users, and cause problems with accessibility, fitt's law, and - so on. - - Read these and the bugzilla stuff before asking/commenting: - http://pobox.com/~hp/free-software-ui.html - http://pobox.com/~hp/features.html - -Q: Why does wireframe move/resize suck? - -A: You can turn it on with the reduced_resources setting. - - But: it has low usability, and is a pain - to implement, and there's no reason opaque move/resize should be a - problem on any setup that can run a modern desktop worth a darn to - begin with. - - Read these and the bugzilla stuff before asking/commenting: - http://pobox.com/~hp/free-software-ui.html - http://pobox.com/~hp/features.html - - The reason we had to add wireframe anyway was broken - proprietary apps that can't handle lots of resize events. - -Q: Why no XYZ? - -A: You are probably getting the idea by now - check rationales.txt, - query/search bugzilla, and read http://pobox.com/~hp/features.html - and http://pobox.com/~hp/free-software-ui.html - - Then sit down and answer the question for yourself. Is the feature - good? What's the rationale for it? Answer "why" not just "why not." - Justify in terms of users as a whole, not just users like - yourself. How else can you solve the same problem? etc. If that - leads you to a strong opinion, then please, post the rationale for - discussion to an appropriate bugzilla bug, or to - usability@gnome.org. - - Please don't just "me too!" on bugzilla bugs, please don't think - flames will get you anywhere, and please don't repeat rationale - that's already been offered. - -Q: Your dumb web pages you made me read talk about solving problems in - fundamental ways instead of adding preferences or workarounds. - What are some examples where metacity has done this? - -A: There are quite a few, though many opportunities remain. Sometimes - the real fix involves application changes. The metacity approach is - that it's OK to require apps to change, though there are also - plenty of workarounds in metacity for battles considered too hard - to fight. - - Here are some examples: - - - fullscreen mode was introduced to allow position constraints, - panel-on-top, and other such things to apply to normal windows - while still allowing video players etc. to "just work" - - - "whether to include minimized windows in Alt+Tab" was solved - by putting minimized windows at the *end* of the tab order. - - - Whether to pop up a feedback display during Alt+Tab was solved by - having both Alt+Tab and Alt+Esc - - - Whether to have a "kill" feature was solved by automatically - detecting and offering to kill stuck apps. Better, metacity - actually does "kill -9" on the process, it doesn't just - disconnect the process from the X server. You'll appreciate this - if you ever did a "kill" on Netscape 4, and watched it keep - eating 100% CPU even though the X server had booted it. - - - The workspaces vs. viewports mess was avoided by adding - directional navigation and such to workspaces, see discussion - earlier in this file. - - - Instead of configurable placement algorithms, there's just one - that works fairly well most of the time. - - - To avoid excess CPU use during opaque move/resize, we rate limit - the updates to the application window's size. - - - Instead of configurable "show size of window while resizing," - it's only shown for windows where it matters, such as terminals. - (Only use-case given for all windows is for web designers - choosing their web browser size, but there are web sites and - desktop backgrounds that do this for you.) - - - Using startup notification, applications open on the workspace - where you launched them, not the active workspace when their - window is opened. - - - and much more. - -Q: I think muffin sucks. - -A: Feel free to use any WM you like. The reason metacity follows the - ICCCM and EWMH specifications is that it makes metacity a modular, - interchangeable part in the desktop. libwnck-based apps such as the - GNOME window list will work just fine with any EWMH-compliant WM. - -Q: Did you spend a lot of time on this? - -A: Originally the answer was no. Sadly the answer is now yes. - -Q: How can you claim that you are anti-crack, while still - writing a window manager? - -A: I have no comment on that. diff --git a/README.md b/README.md new file mode 100644 index 000000000..964b04d46 --- /dev/null +++ b/README.md @@ -0,0 +1,45 @@ +# Mutter + +Mutter is a Wayland display server and X11 window manager and compositor library. + +When used as a Wayland display server, it runs on top of KMS and libinput. It +implements the compositor side of the Wayland core protocol as well as various +protocol extensions. It also has functionality related to running X11 +applications using Xwayland. + +When used on top of Xorg it acts as a X11 window manager and compositing manager. + +It contains functionality related to, among other things, window management, +window compositing, focus tracking, workspace management, keybindings and +monitor configuration. + +Internally it uses a fork of Cogl, a hardware acceleration abstraction library +used to simplify usage of OpenGL pipelines, as well as a fork af Clutter, a +scene graph and user interface toolkit. + +Mutter is used by, for example, GNOME Shell, the GNOME core user interface, and +by Gala, elementary OS's window manager. It can also be run standalone, using +the command "mutter", but just running plain mutter is only intended for +debugging purposes. + +## Contributing + +To contribute, open merge requests at https://gitlab.gnome.org/GNOME/mutter. + +The coding style used is primarily the GNU flavor of the [GNOME coding +style](https://developer.gnome.org/programming-guidelines/stable/c-coding-style.html.en) +with some minor additions such as preferring `stdint.h` types over GLib +fundamental types, and a soft 80 character line limit. However, in general, +look at the file you're editing for inspiration. + +Commit messages should follow the [GNOME commit message +guidelines](https://wiki.gnome.org/Git/CommitMessages). We require an URL +to either an issue or a merge request in each commit. + +## License + +Mutter is distributed under the terms of the GNU General Public License, +version 2 or later. See the [COPYING][license] file for detalis. + +[bug-tracker]: https://gitlab.gnome.org/GNOME/mutter/issues +[license]: COPYING diff --git a/autogen.sh b/autogen.sh deleted file mode 100755 index 68b090195..000000000 --- a/autogen.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/sh -# Run this to generate all the initial makefiles, etc. -test -n "$srcdir" || srcdir=$(dirname "$0") -test -n "$srcdir" || srcdir=. - -olddir=$(pwd) - -cd $srcdir - -(test -f configure.ac) || { - echo "*** ERROR: Directory '$srcdir' does not look like the top-level project directory ***" - exit 1 -} - -# shellcheck disable=SC2016 -PKG_NAME=$(autoconf --trace 'AC_INIT:$1' configure.ac) - -if [ "$#" = 0 -a "x$NOCONFIGURE" = "x" ]; then - echo "*** WARNING: I am going to run 'configure' with no arguments." >&2 - echo "*** If you wish to pass any to it, please specify them on the" >&2 - echo "*** '$0' command line." >&2 - echo "" >&2 -fi - -mkdir -p m4 - -glib-gettextize --force --copy || exit 1 -gtkdocize --copy || exit 1 -intltoolize --force --copy --automake || exit 1 -autoreconf --verbose --force --install || exit 1 - -cd "$olddir" -if [ "$NOCONFIGURE" = "" ]; then - $srcdir/configure "$@" || exit 1 - - if [ "$1" = "--help" ]; then exit 0 else - echo "Now type 'make' to compile $PKG_NAME" || exit 1 - fi -else - echo "Skipping configure process." -fi diff --git a/clutter/.gitignore b/clutter/.gitignore index 362a24379..77be91036 100644 --- a/clutter/.gitignore +++ b/clutter/.gitignore @@ -23,7 +23,6 @@ clutter-build-config.h.in clutter-config.h clutter-enum-types.[ch] clutter-marshal.[ch] -clutter-version.h gcov-report.txt clutter-json.h clutter-lcov.info diff --git a/clutter/Makefile.am b/clutter/Makefile.am deleted file mode 100644 index eeaa7222e..000000000 --- a/clutter/Makefile.am +++ /dev/null @@ -1,53 +0,0 @@ -NULL = - -SUBDIRS = build clutter tests - -if BUILD_EXAMPLES -SUBDIRS += examples -endif - -DIST_SUBDIRS = clutter tests examples build - -# XXX - this is a massive hack to make autoreconf honour the ACLOCAL_FLAGS -# that jhbuild sets while still retaining build/autotools as the authoritative -# source for m4 macros -ACLOCAL_AMFLAGS = -I build/autotools ${ACLOCAL_FLAGS} - -CLEANFILES = $(pcfiles) - -DISTCLEANFILES = - -DISTCHECK_CONFIGURE_FLAGS = --enable-maintainer-flags - -# proxy rules for tests -test-report full-report: - $(MAKE) -C tests/conform $(@) - -perf-report: - $(MAKE) -C tests/performance $(@) - -if ENABLE_GCOV -# use recursive makes in order to ignore errors during check/perf -lcov: - -$(MAKE) $(AM_MAKEFLAGS) -C clutter check - -$(MAKE) $(AM_MAKEFLAGS) -C tests/conform test - $(MAKE) $(AM_MAKEFLAGS) genlcov - -# we have to massage the lcov.info file slightly to hide the effect of libtool -# placing the objects files in the .libs/ directory separate from the *.c -genlcov: - $(LTP) --directory $(top_builddir) --capture --output-file clutter-lcov.info --test-name CLUTTER_TEST --no-checksum - $(SED) -e 's#.libs/##' < clutter-lcov.info > clutter-lcov.info.tmp - LANG=C $(LTP_GENHTML) --prefix $(top_builddir) --output-directory clutter-lcov --title "Clutter Code Coverage" --show-details clutter-lcov.info.tmp - rm -f clutter-lcov.info.tmp - -lcov-clean: - -$(LTP) --directory $(top_builddir) -z - -$(RM) -rf clutter-lcov.info clutter-lcov -else -lcov genlcov lcov-clean: - @echo You need to configure Clutter with support for gcov enabled. - @echo e.g., ./configure --enable-gcov -endif - -.PHONY: test-report full-report perf-report lcov genlcov lcov-clean diff --git a/clutter/build/Makefile.am b/clutter/build/Makefile.am deleted file mode 100644 index 8c902377b..000000000 --- a/clutter/build/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -SUBDIRS = autotools diff --git a/clutter/build/autotools/.gitignore b/clutter/build/autotools/.gitignore deleted file mode 100644 index b7e485538..000000000 --- a/clutter/build/autotools/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -gtk-doc.m4 -libtool.m4 -ltoptions.m4 -ltsugar.m4 -ltversion.m4 -lt~obsolete.m4 -shave -shave-libtool diff --git a/clutter/build/autotools/Makefile.am b/clutter/build/autotools/Makefile.am deleted file mode 100644 index 0a74d8202..000000000 --- a/clutter/build/autotools/Makefile.am +++ /dev/null @@ -1,10 +0,0 @@ -NULL = - -EXTRA_DIST = \ - introspection.m4 \ - as-compiler-flag.m4 \ - glibtests.m4 \ - glib-tap.mk \ - tap-driver.sh \ - tap-test \ - $(NULL) diff --git a/clutter/build/autotools/as-compiler-flag.m4 b/clutter/build/autotools/as-compiler-flag.m4 deleted file mode 100644 index 0f660cf07..000000000 --- a/clutter/build/autotools/as-compiler-flag.m4 +++ /dev/null @@ -1,62 +0,0 @@ -dnl as-compiler-flag.m4 0.1.0 - -dnl autostars m4 macro for detection of compiler flags - -dnl David Schleef - -dnl $Id: as-compiler-flag.m4,v 1.1 2005/12/15 23:35:19 ds Exp $ - -dnl AS_COMPILER_FLAG(CFLAGS, ACTION-IF-ACCEPTED, [ACTION-IF-NOT-ACCEPTED]) -dnl Tries to compile with the given CFLAGS. -dnl Runs ACTION-IF-ACCEPTED if the compiler can compile with the flags, -dnl and ACTION-IF-NOT-ACCEPTED otherwise. - -AC_DEFUN([AS_COMPILER_FLAG], -[ - AC_MSG_CHECKING([to see if compiler understands $1]) - - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $1" - - AC_TRY_COMPILE([ ], [], [flag_ok=yes], [flag_ok=no]) - CFLAGS="$save_CFLAGS" - - if test "X$flag_ok" = Xyes ; then - m4_ifvaln([$2],[$2]) - true - else - m4_ifvaln([$3],[$3]) - true - fi - AC_MSG_RESULT([$flag_ok]) -]) - -dnl AS_COMPILER_FLAGS(VAR, FLAGS) -dnl Tries to compile with the given CFLAGS. - -AC_DEFUN([AS_COMPILER_FLAGS], -[ - list=$2 - flags_supported="" - flags_unsupported="" - AC_MSG_CHECKING([for supported compiler flags]) - for each in $list - do - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $each" - AC_TRY_COMPILE([ ], [], [flag_ok=yes], [flag_ok=no]) - CFLAGS="$save_CFLAGS" - - if test "X$flag_ok" = Xyes ; then - flags_supported="$flags_supported $each" - else - flags_unsupported="$flags_unsupported $each" - fi - done - AC_MSG_RESULT([$flags_supported]) - if test "X$flags_unsupported" != X ; then - AC_MSG_WARN([unsupported compiler flags: $flags_unsupported]) - fi - $1="$$1 $flags_supported" -]) - diff --git a/clutter/build/autotools/glib-tap.mk b/clutter/build/autotools/glib-tap.mk deleted file mode 100644 index 7c5f82b9a..000000000 --- a/clutter/build/autotools/glib-tap.mk +++ /dev/null @@ -1,134 +0,0 @@ -# GLIB - Library of useful C routines - -TESTS_ENVIRONMENT= \ - G_TEST_SRCDIR="$(abs_srcdir)" \ - G_TEST_BUILDDIR="$(abs_builddir)" \ - G_DEBUG=gc-friendly \ - MALLOC_CHECK_=2 \ - MALLOC_PERTURB_=$$(($${RANDOM:-256} % 256)) -LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) $(top_srcdir)/build/autotools/tap-driver.sh -LOG_COMPILER = $(top_srcdir)/build/autotools/tap-test - -NULL = - -# initialize variables for unconditional += appending -BUILT_SOURCES = -BUILT_EXTRA_DIST = -CLEANFILES = *.log *.trs -DISTCLEANFILES = -MAINTAINERCLEANFILES = -EXTRA_DIST = -TESTS = - -installed_test_LTLIBRARIES = -installed_test_PROGRAMS = -installed_test_SCRIPTS = -nobase_installed_test_DATA = - -noinst_LTLIBRARIES = -noinst_PROGRAMS = -noinst_SCRIPTS = -noinst_DATA = - -check_LTLIBRARIES = -check_PROGRAMS = -check_SCRIPTS = -check_DATA = - -# We support a fairly large range of possible variables. It is expected that all types of files in a test suite -# will belong in exactly one of the following variables. -# -# First, we support the usual automake suffixes, but in lowercase, with the customary meaning: -# -# test_programs, test_scripts, test_data, test_ltlibraries -# -# The above are used to list files that are involved in both uninstalled and installed testing. The -# test_programs and test_scripts are taken to be actual testcases and will be run as part of the test suite. -# Note that _data is always used with the nobase_ automake variable name to ensure that installed test data is -# installed in the same way as it appears in the package layout. -# -# In order to mark a particular file as being only for one type of testing, use 'installed' or 'uninstalled', -# like so: -# -# installed_test_programs, uninstalled_test_programs -# installed_test_scripts, uninstalled_test_scripts -# installed_test_data, uninstalled_test_data -# installed_test_ltlibraries, uninstalled_test_ltlibraries -# -# Additionally, we support 'extra' infixes for programs and scripts. This is used for support programs/scripts -# that should not themselves be run as testcases (but exist to be used from other testcases): -# -# test_extra_programs, installed_test_extra_programs, uninstalled_test_extra_programs -# test_extra_scripts, installed_test_extra_scripts, uninstalled_test_extra_scripts -# -# Additionally, for _scripts and _data, we support the customary dist_ prefix so that the named script or data -# file automatically end up in the tarball. -# -# dist_test_scripts, dist_test_data, dist_test_extra_scripts -# dist_installed_test_scripts, dist_installed_test_data, dist_installed_test_extra_scripts -# dist_uninstalled_test_scripts, dist_uninstalled_test_data, dist_uninstalled_test_extra_scripts -# -# Note that no file is automatically disted unless it appears in one of the dist_ variables. This follows the -# standard automake convention of not disting programs scripts or data by default. -# -# test_programs, test_scripts, uninstalled_test_programs and uninstalled_test_scripts (as well as their disted -# variants) will be run as part of the in-tree 'make check'. These are all assumed to be runnable under -# gtester. That's a bit strange for scripts, but it's possible. - -TESTS += $(test_programs) $(test_scripts) $(uninstalled_test_programs) $(uninstalled_test_scripts) \ - $(dist_test_scripts) $(dist_uninstalled_test_scripts) - -# Note: build even the installed-only targets during 'make check' to ensure that they still work. -# We need to do a bit of trickery here and manage disting via EXTRA_DIST instead of using dist_ prefixes to -# prevent automake from mistreating gmake functions like $(wildcard ...) and $(addprefix ...) as if they were -# filenames, including removing duplicate instances of the opening part before the space, eg. '$(addprefix'. -all_test_programs = $(test_programs) $(uninstalled_test_programs) $(installed_test_programs) \ - $(test_extra_programs) $(uninstalled_test_extra_programs) $(installed_test_extra_programs) -all_test_scripts = $(test_scripts) $(uninstalled_test_scripts) $(installed_test_scripts) \ - $(test_extra_scripts) $(uninstalled_test_extra_scripts) $(installed_test_extra_scripts) -all_dist_test_scripts = $(dist_test_scripts) $(dist_uninstalled_test_scripts) $(dist_installed_test_scripts) \ - $(dist_test_extra_scripts) $(dist_uninstalled_test_extra_scripts) $(dist_installed_test_extra_scripts) -all_test_scripts += $(all_dist_test_scripts) -EXTRA_DIST += $(all_dist_test_scripts) -all_test_data = $(test_data) $(uninstalled_test_data) $(installed_test_data) -all_dist_test_data = $(dist_test_data) $(dist_uninstalled_test_data) $(dist_installed_test_data) -all_test_data += $(all_dist_test_data) -EXTRA_DIST += $(all_dist_test_data) -all_test_ltlibs = $(test_ltlibraries) $(uninstalled_test_ltlibraries) $(installed_test_ltlibraries) - -if ENABLE_ALWAYS_BUILD_TESTS -noinst_LTLIBRARIES += $(all_test_ltlibs) -noinst_PROGRAMS += $(all_test_programs) -noinst_SCRIPTS += $(all_test_scripts) -noinst_DATA += $(all_test_data) -else -check_LTLIBRARIES += $(all_test_ltlibs) -check_PROGRAMS += $(all_test_programs) -check_SCRIPTS += $(all_test_scripts) -check_DATA += $(all_test_data) -endif - -if ENABLE_INSTALLED_TESTS -installed_test_PROGRAMS += $(test_programs) $(installed_test_programs) \ - $(test_extra_programs) $(installed_test_extra_programs) -installed_test_SCRIPTS += $(test_scripts) $(installed_test_scripts) \ - $(test_extra_scripts) $(test_installed_extra_scripts) -installed_test_SCRIPTS += $(dist_test_scripts) $(dist_test_extra_scripts) \ - $(dist_installed_test_scripts) $(dist_installed_test_extra_scripts) -nobase_installed_test_DATA += $(test_data) $(installed_test_data) -nobase_installed_test_DATA += $(dist_test_data) $(dist_installed_test_data) -installed_test_LTLIBRARIES += $(test_ltlibraries) $(installed_test_ltlibraries) -installed_testcases = $(test_programs) $(installed_test_programs) \ - $(test_scripts) $(installed_test_scripts) \ - $(dist_test_scripts) $(dist_installed_test_scripts) - -installed_test_meta_DATA = $(installed_testcases:=.test) - -%.test: %$(EXEEXT) Makefile - $(AM_V_GEN) (echo '[Test]' > $@.tmp; \ - echo 'Type=session' >> $@.tmp; \ - echo 'Exec=env G_ENABLE_DIAGNOSTIC=0 CLUTTER_ENABLE_DIAGNOSTIC=0 $(installed_testdir)/$<' >> $@.tmp; \ - mv $@.tmp $@) - -CLEANFILES += $(installed_test_meta_DATA) -endif diff --git a/clutter/build/autotools/glibtests.m4 b/clutter/build/autotools/glibtests.m4 deleted file mode 100644 index 7d5920a43..000000000 --- a/clutter/build/autotools/glibtests.m4 +++ /dev/null @@ -1,28 +0,0 @@ -dnl GLIB_TESTS -dnl - -AC_DEFUN([GLIB_TESTS], -[ - AC_ARG_ENABLE(installed-tests, - AS_HELP_STRING([--enable-installed-tests], - [Enable installation of some test cases]), - [case ${enableval} in - yes) ENABLE_INSTALLED_TESTS="1" ;; - no) ENABLE_INSTALLED_TESTS="" ;; - *) AC_MSG_ERROR([bad value ${enableval} for --enable-installed-tests]) ;; - esac]) - AM_CONDITIONAL([ENABLE_INSTALLED_TESTS], test "$ENABLE_INSTALLED_TESTS" = "1") - AC_ARG_ENABLE(always-build-tests, - AS_HELP_STRING([--enable-always-build-tests], - [Enable always building tests during 'make all']), - [case ${enableval} in - yes) ENABLE_ALWAYS_BUILD_TESTS="1" ;; - no) ENABLE_ALWAYS_BUILD_TESTS="" ;; - *) AC_MSG_ERROR([bad value ${enableval} for --enable-always-build-tests]) ;; - esac]) - AM_CONDITIONAL([ENABLE_ALWAYS_BUILD_TESTS], test "$ENABLE_ALWAYS_BUILD_TESTS" = "1") - if test "$ENABLE_INSTALLED_TESTS" = "1"; then - AC_SUBST(installed_test_metadir, [${datadir}/installed-tests/]AC_PACKAGE_NAME) - AC_SUBST(installed_testdir, [${libexecdir}/installed-tests/]AC_PACKAGE_NAME) - fi -]) diff --git a/clutter/build/autotools/tap-driver.sh b/clutter/build/autotools/tap-driver.sh deleted file mode 100755 index 19aa531de..000000000 --- a/clutter/build/autotools/tap-driver.sh +++ /dev/null @@ -1,652 +0,0 @@ -#! /bin/sh -# Copyright (C) 2011-2013 Free Software Foundation, Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# This file is maintained in Automake, please report -# bugs to or send patches to -# . - -scriptversion=2011-12-27.17; # UTC - -# Make unconditional expansion of undefined variables an error. This -# helps a lot in preventing typo-related bugs. -set -u - -me=tap-driver.sh - -fatal () -{ - echo "$me: fatal: $*" >&2 - exit 1 -} - -usage_error () -{ - echo "$me: $*" >&2 - print_usage >&2 - exit 2 -} - -print_usage () -{ - cat < - # - trap : 1 3 2 13 15 - if test $merge -gt 0; then - exec 2>&1 - else - exec 2>&3 - fi - "$@" - echo $? - ) | LC_ALL=C ${AM_TAP_AWK-awk} \ - -v me="$me" \ - -v test_script_name="$test_name" \ - -v log_file="$log_file" \ - -v trs_file="$trs_file" \ - -v expect_failure="$expect_failure" \ - -v merge="$merge" \ - -v ignore_exit="$ignore_exit" \ - -v comments="$comments" \ - -v diag_string="$diag_string" \ -' -# FIXME: the usages of "cat >&3" below could be optimized when using -# FIXME: GNU awk, and/on on systems that supports /dev/fd/. - -# Implementation note: in what follows, `result_obj` will be an -# associative array that (partly) simulates a TAP result object -# from the `TAP::Parser` perl module. - -## ----------- ## -## FUNCTIONS ## -## ----------- ## - -function fatal(msg) -{ - print me ": " msg | "cat >&2" - exit 1 -} - -function abort(where) -{ - fatal("internal error " where) -} - -# Convert a boolean to a "yes"/"no" string. -function yn(bool) -{ - return bool ? "yes" : "no"; -} - -function add_test_result(result) -{ - if (!test_results_index) - test_results_index = 0 - test_results_list[test_results_index] = result - test_results_index += 1 - test_results_seen[result] = 1; -} - -# Whether the test script should be re-run by "make recheck". -function must_recheck() -{ - for (k in test_results_seen) - if (k != "XFAIL" && k != "PASS" && k != "SKIP") - return 1 - return 0 -} - -# Whether the content of the log file associated to this test should -# be copied into the "global" test-suite.log. -function copy_in_global_log() -{ - for (k in test_results_seen) - if (k != "PASS") - return 1 - return 0 -} - -# FIXME: this can certainly be improved ... -function get_global_test_result() -{ - if ("ERROR" in test_results_seen) - return "ERROR" - if ("FAIL" in test_results_seen || "XPASS" in test_results_seen) - return "FAIL" - all_skipped = 1 - for (k in test_results_seen) - if (k != "SKIP") - all_skipped = 0 - if (all_skipped) - return "SKIP" - return "PASS"; -} - -function stringify_result_obj(result_obj) -{ - if (result_obj["is_unplanned"] || result_obj["number"] != testno) - return "ERROR" - - if (plan_seen == LATE_PLAN) - return "ERROR" - - if (result_obj["directive"] == "TODO") - return result_obj["is_ok"] ? "XPASS" : "XFAIL" - - if (result_obj["directive"] == "SKIP") - return result_obj["is_ok"] ? "SKIP" : COOKED_FAIL; - - if (length(result_obj["directive"])) - abort("in function stringify_result_obj()") - - return result_obj["is_ok"] ? COOKED_PASS : COOKED_FAIL -} - -function decorate_result(result) -{ - color_name = color_for_result[result] - if (color_name) - return color_map[color_name] "" result "" color_map["std"] - # If we are not using colorized output, or if we do not know how - # to colorize the given result, we should return it unchanged. - return result -} - -function report(result, details) -{ - if (result ~ /^(X?(PASS|FAIL)|SKIP|ERROR)/) - { - msg = ": " test_script_name - add_test_result(result) - } - else if (result == "#") - { - msg = " " test_script_name ":" - } - else - { - abort("in function report()") - } - if (length(details)) - msg = msg " " details - # Output on console might be colorized. - print decorate_result(result) msg - # Log the result in the log file too, to help debugging (this is - # especially true when said result is a TAP error or "Bail out!"). - print result msg | "cat >&3"; -} - -function testsuite_error(error_message) -{ - report("ERROR", "- " error_message) -} - -function handle_tap_result() -{ - details = result_obj["number"]; - if (length(result_obj["description"])) - details = details " " result_obj["description"] - - if (plan_seen == LATE_PLAN) - { - details = details " # AFTER LATE PLAN"; - } - else if (result_obj["is_unplanned"]) - { - details = details " # UNPLANNED"; - } - else if (result_obj["number"] != testno) - { - details = sprintf("%s # OUT-OF-ORDER (expecting %d)", - details, testno); - } - else if (result_obj["directive"]) - { - details = details " # " result_obj["directive"]; - if (length(result_obj["explanation"])) - details = details " " result_obj["explanation"] - } - - report(stringify_result_obj(result_obj), details) -} - -# `skip_reason` should be empty whenever planned > 0. -function handle_tap_plan(planned, skip_reason) -{ - planned += 0 # Avoid getting confused if, say, `planned` is "00" - if (length(skip_reason) && planned > 0) - abort("in function handle_tap_plan()") - if (plan_seen) - { - # Error, only one plan per stream is acceptable. - testsuite_error("multiple test plans") - return; - } - planned_tests = planned - # The TAP plan can come before or after *all* the TAP results; we speak - # respectively of an "early" or a "late" plan. If we see the plan line - # after at least one TAP result has been seen, assume we have a late - # plan; in this case, any further test result seen after the plan will - # be flagged as an error. - plan_seen = (testno >= 1 ? LATE_PLAN : EARLY_PLAN) - # If testno > 0, we have an error ("too many tests run") that will be - # automatically dealt with later, so do not worry about it here. If - # $plan_seen is true, we have an error due to a repeated plan, and that - # has already been dealt with above. Otherwise, we have a valid "plan - # with SKIP" specification, and should report it as a particular kind - # of SKIP result. - if (planned == 0 && testno == 0) - { - if (length(skip_reason)) - skip_reason = "- " skip_reason; - report("SKIP", skip_reason); - } -} - -function extract_tap_comment(line) -{ - if (index(line, diag_string) == 1) - { - # Strip leading `diag_string` from `line`. - line = substr(line, length(diag_string) + 1) - # And strip any leading and trailing whitespace left. - sub("^[ \t]*", "", line) - sub("[ \t]*$", "", line) - # Return what is left (if any). - return line; - } - return ""; -} - -# When this function is called, we know that line is a TAP result line, -# so that it matches the (perl) RE "^(not )?ok\b". -function setup_result_obj(line) -{ - # Get the result, and remove it from the line. - result_obj["is_ok"] = (substr(line, 1, 2) == "ok" ? 1 : 0) - sub("^(not )?ok[ \t]*", "", line) - - # If the result has an explicit number, get it and strip it; otherwise, - # automatically assing the next progresive number to it. - if (line ~ /^[0-9]+$/ || line ~ /^[0-9]+[^a-zA-Z0-9_]/) - { - match(line, "^[0-9]+") - # The final `+ 0` is to normalize numbers with leading zeros. - result_obj["number"] = substr(line, 1, RLENGTH) + 0 - line = substr(line, RLENGTH + 1) - } - else - { - result_obj["number"] = testno - } - - if (plan_seen == LATE_PLAN) - # No further test results are acceptable after a "late" TAP plan - # has been seen. - result_obj["is_unplanned"] = 1 - else if (plan_seen && testno > planned_tests) - result_obj["is_unplanned"] = 1 - else - result_obj["is_unplanned"] = 0 - - # Strip trailing and leading whitespace. - sub("^[ \t]*", "", line) - sub("[ \t]*$", "", line) - - # This will have to be corrected if we have a "TODO"/"SKIP" directive. - result_obj["description"] = line - result_obj["directive"] = "" - result_obj["explanation"] = "" - - if (index(line, "#") == 0) - return # No possible directive, nothing more to do. - - # Directives are case-insensitive. - rx = "[ \t]*#[ \t]*([tT][oO][dD][oO]|[sS][kK][iI][pP])[ \t]*" - - # See whether we have the directive, and if yes, where. - pos = match(line, rx "$") - if (!pos) - pos = match(line, rx "[^a-zA-Z0-9_]") - - # If there was no TAP directive, we have nothing more to do. - if (!pos) - return - - # Let`s now see if the TAP directive has been escaped. For example: - # escaped: ok \# SKIP - # not escaped: ok \\# SKIP - # escaped: ok \\\\\# SKIP - # not escaped: ok \ # SKIP - if (substr(line, pos, 1) == "#") - { - bslash_count = 0 - for (i = pos; i > 1 && substr(line, i - 1, 1) == "\\"; i--) - bslash_count += 1 - if (bslash_count % 2) - return # Directive was escaped. - } - - # Strip the directive and its explanation (if any) from the test - # description. - result_obj["description"] = substr(line, 1, pos - 1) - # Now remove the test description from the line, that has been dealt - # with already. - line = substr(line, pos) - # Strip the directive, and save its value (normalized to upper case). - sub("^[ \t]*#[ \t]*", "", line) - result_obj["directive"] = toupper(substr(line, 1, 4)) - line = substr(line, 5) - # Now get the explanation for the directive (if any), with leading - # and trailing whitespace removed. - sub("^[ \t]*", "", line) - sub("[ \t]*$", "", line) - result_obj["explanation"] = line -} - -function get_test_exit_message(status) -{ - if (status == 0) - return "" - if (status !~ /^[1-9][0-9]*$/) - abort("getting exit status") - if (status < 127) - exit_details = "" - else if (status == 127) - exit_details = " (command not found?)" - else if (status >= 128 && status <= 255) - exit_details = sprintf(" (terminated by signal %d?)", status - 128) - else if (status > 256 && status <= 384) - # We used to report an "abnormal termination" here, but some Korn - # shells, when a child process die due to signal number n, can leave - # in $? an exit status of 256+n instead of the more standard 128+n. - # Apparently, both behaviours are allowed by POSIX (2008), so be - # prepared to handle them both. See also Austing Group report ID - # 0000051 - exit_details = sprintf(" (terminated by signal %d?)", status - 256) - else - # Never seen in practice. - exit_details = " (abnormal termination)" - return sprintf("exited with status %d%s", status, exit_details) -} - -function write_test_results() -{ - print ":global-test-result: " get_global_test_result() > trs_file - print ":recheck: " yn(must_recheck()) > trs_file - print ":copy-in-global-log: " yn(copy_in_global_log()) > trs_file - for (i = 0; i < test_results_index; i += 1) - print ":test-result: " test_results_list[i] > trs_file - close(trs_file); -} - -BEGIN { - -## ------- ## -## SETUP ## -## ------- ## - -'"$init_colors"' - -# Properly initialized once the TAP plan is seen. -planned_tests = 0 - -COOKED_PASS = expect_failure ? "XPASS": "PASS"; -COOKED_FAIL = expect_failure ? "XFAIL": "FAIL"; - -# Enumeration-like constants to remember which kind of plan (if any) -# has been seen. It is important that NO_PLAN evaluates "false" as -# a boolean. -NO_PLAN = 0 -EARLY_PLAN = 1 -LATE_PLAN = 2 - -testno = 0 # Number of test results seen so far. -bailed_out = 0 # Whether a "Bail out!" directive has been seen. - -# Whether the TAP plan has been seen or not, and if yes, which kind -# it is ("early" is seen before any test result, "late" otherwise). -plan_seen = NO_PLAN - -## --------- ## -## PARSING ## -## --------- ## - -is_first_read = 1 - -while (1) - { - # Involutions required so that we are able to read the exit status - # from the last input line. - st = getline - if (st < 0) # I/O error. - fatal("I/O error while reading from input stream") - else if (st == 0) # End-of-input - { - if (is_first_read) - abort("in input loop: only one input line") - break - } - if (is_first_read) - { - is_first_read = 0 - nextline = $0 - continue - } - else - { - curline = nextline - nextline = $0 - $0 = curline - } - # Copy any input line verbatim into the log file. - print | "cat >&3" - # Parsing of TAP input should stop after a "Bail out!" directive. - if (bailed_out) - continue - - # TAP test result. - if ($0 ~ /^(not )?ok$/ || $0 ~ /^(not )?ok[^a-zA-Z0-9_]/) - { - testno += 1 - setup_result_obj($0) - handle_tap_result() - } - # TAP plan (normal or "SKIP" without explanation). - else if ($0 ~ /^1\.\.[0-9]+[ \t]*$/) - { - # The next two lines will put the number of planned tests in $0. - sub("^1\\.\\.", "") - sub("[^0-9]*$", "") - handle_tap_plan($0, "") - continue - } - # TAP "SKIP" plan, with an explanation. - else if ($0 ~ /^1\.\.0+[ \t]*#/) - { - # The next lines will put the skip explanation in $0, stripping - # any leading and trailing whitespace. This is a little more - # tricky in truth, since we want to also strip a potential leading - # "SKIP" string from the message. - sub("^[^#]*#[ \t]*(SKIP[: \t][ \t]*)?", "") - sub("[ \t]*$", ""); - handle_tap_plan(0, $0) - } - # "Bail out!" magic. - # Older versions of prove and TAP::Harness (e.g., 3.17) did not - # recognize a "Bail out!" directive when preceded by leading - # whitespace, but more modern versions (e.g., 3.23) do. So we - # emulate the latter, "more modern" behaviour. - else if ($0 ~ /^[ \t]*Bail out!/) - { - bailed_out = 1 - # Get the bailout message (if any), with leading and trailing - # whitespace stripped. The message remains stored in `$0`. - sub("^[ \t]*Bail out![ \t]*", ""); - sub("[ \t]*$", ""); - # Format the error message for the - bailout_message = "Bail out!" - if (length($0)) - bailout_message = bailout_message " " $0 - testsuite_error(bailout_message) - } - # Maybe we have too look for dianogtic comments too. - else if (comments != 0) - { - comment = extract_tap_comment($0); - if (length(comment)) - report("#", comment); - } - } - -## -------- ## -## FINISH ## -## -------- ## - -# A "Bail out!" directive should cause us to ignore any following TAP -# error, as well as a non-zero exit status from the TAP producer. -if (!bailed_out) - { - if (!plan_seen) - { - testsuite_error("missing test plan") - } - else if (planned_tests != testno) - { - bad_amount = testno > planned_tests ? "many" : "few" - testsuite_error(sprintf("too %s tests run (expected %d, got %d)", - bad_amount, planned_tests, testno)) - } - if (!ignore_exit) - { - # Fetch exit status from the last line. - exit_message = get_test_exit_message(nextline) - if (exit_message) - testsuite_error(exit_message) - } - } - -write_test_results() - -exit 0 - -} # End of "BEGIN" block. -' - -# TODO: document that we consume the file descriptor 3 :-( -} 3>"$log_file" - -test $? -eq 0 || fatal "I/O or internal error" - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" -# time-stamp-end: "; # UTC" -# End: diff --git a/clutter/build/autotools/tap-test b/clutter/build/autotools/tap-test deleted file mode 100755 index 481e333ec..000000000 --- a/clutter/build/autotools/tap-test +++ /dev/null @@ -1,5 +0,0 @@ -#! /bin/sh - -# run a GTest in tap mode. The test binary is passed as $1 - -$1 -k --tap diff --git a/clutter/clutter/Makefile.am b/clutter/clutter/Makefile.am deleted file mode 100644 index ecfa568b7..000000000 --- a/clutter/clutter/Makefile.am +++ /dev/null @@ -1,741 +0,0 @@ -AUTOMAKE_OPTIONS = subdir-objects - -# preamble -NULL = - -# common definitions -CLEANFILES = -DISTCLEANFILES = -EXTRA_DIST = -BUILT_SOURCES = - -AM_CPPFLAGS = \ - -DCLUTTER_PREFIX=\""$(prefix)"\" \ - -DCLUTTER_LIBDIR=\""$(libdir)"\" \ - -DCLUTTER_DATADIR=\""$(datadir)"\" \ - -DCLUTTER_LOCALEDIR=\""$(localedir)"\" \ - -DCLUTTER_SYSCONFDIR=\""$(sysconfdir)"\" \ - -DCLUTTER_COMPILATION=1 \ - -DCOGL_DISABLE_DEPRECATION_WARNINGS \ - -DG_LOG_DOMAIN=\"Clutter\" \ - -I$(top_srcdir) \ - -I$(top_srcdir)/clutter \ - -I$(top_srcdir)/clutter/cally \ - -I$(top_builddir) \ - -I$(top_builddir)/clutter \ - -I$(top_srcdir)/../cogl \ - -I$(top_builddir)/../cogl \ - -I$(top_builddir)/../cogl/cogl \ - $(CLUTTER_DEPRECATED_CFLAGS) \ - $(CLUTTER_DEBUG_CFLAGS) \ - $(CLUTTER_HIDDEN_VISIBILITY_CFLAGS) \ - $(NULL) - -AM_CFLAGS = $(CLUTTER_CFLAGS) $(MAINTAINER_CFLAGS) - -# these are the gir files we generate using g-ir-scanner -INTROSPECTION_GIRS = - -# the base include path for headers -clutter_base_includedir = $(includedir)/muffin/clutter-$(MUFFIN_PLUGIN_API_VERSION) -clutter_includedir = $(clutter_base_includedir)/clutter -clutter_deprecateddir = $(clutter_base_includedir)/clutter/deprecated - -# pkg-config files -pc_files = - -# common sources - please, keep these sorted alphabetically -source_h = \ - clutter-action.h \ - clutter-actor-meta.h \ - clutter-actor.h \ - clutter-align-constraint.h \ - clutter-animatable.h \ - clutter-backend.h \ - clutter-bind-constraint.h \ - clutter-binding-pool.h \ - clutter-bin-layout.h \ - clutter-blur-effect.h \ - clutter-box-layout.h \ - clutter-brightness-contrast-effect.h \ - clutter-cairo.h \ - clutter-canvas.h \ - clutter-child-meta.h \ - clutter-click-action.h \ - clutter-clone.h \ - clutter-color-static.h \ - clutter-color.h \ - clutter-colorize-effect.h \ - clutter-constraint.h \ - clutter-container.h \ - clutter-content.h \ - clutter-deform-effect.h \ - clutter-deprecated.h \ - clutter-desaturate-effect.h \ - clutter-device-manager.h \ - clutter-drag-action.h \ - clutter-drop-action.h \ - clutter-effect.h \ - clutter-enums.h \ - clutter-event.h \ - clutter-feature.h \ - clutter-fixed-layout.h \ - clutter-flow-layout.h \ - clutter-gesture-action.h \ - clutter-grid-layout.h \ - clutter-group.h \ - clutter-image.h \ - clutter-input-device.h \ - clutter-input-device-tool.h \ - clutter-input-focus.h \ - clutter-input-method.h \ - clutter-interval.h \ - clutter-keyframe-transition.h \ - clutter-keysyms.h \ - clutter-layout-manager.h \ - clutter-layout-meta.h \ - clutter-macros.h \ - clutter-main.h \ - clutter-offscreen-effect.h \ - clutter-page-turn-effect.h \ - clutter-paint-nodes.h \ - clutter-paint-node.h \ - clutter-pan-action.h \ - clutter-path-constraint.h \ - clutter-path.h \ - clutter-property-transition.h \ - clutter-rotate-action.h \ - clutter-script.h \ - clutter-scriptable.h \ - clutter-scroll-actor.h \ - clutter-settings.h \ - clutter-shader-effect.h \ - clutter-shader-types.h \ - clutter-swipe-action.h \ - clutter-snap-constraint.h \ - clutter-stage.h \ - clutter-stage-manager.h \ - clutter-tap-action.h \ - clutter-test-utils.h \ - clutter-texture.h \ - clutter-text.h \ - clutter-text-buffer.h \ - clutter-timeline.h \ - clutter-transition-group.h \ - clutter-transition.h \ - clutter-types.h \ - clutter-units.h \ - clutter-virtual-input-device.h \ - clutter-zoom-action.h \ - $(NULL) - -source_c = \ - clutter-action.c \ - clutter-actor-box.c \ - clutter-actor-meta.c \ - clutter-actor.c \ - clutter-align-constraint.c \ - clutter-animatable.c \ - clutter-backend.c \ - clutter-base-types.c \ - clutter-bezier.c \ - clutter-bind-constraint.c \ - clutter-binding-pool.c \ - clutter-bin-layout.c \ - clutter-blur-effect.c \ - clutter-box-layout.c \ - clutter-brightness-contrast-effect.c \ - clutter-cairo.c \ - clutter-canvas.c \ - clutter-child-meta.c \ - clutter-click-action.c \ - clutter-clone.c \ - clutter-color.c \ - clutter-colorize-effect.c \ - clutter-constraint.c \ - clutter-container.c \ - clutter-content.c \ - clutter-deform-effect.c \ - clutter-desaturate-effect.c \ - clutter-device-manager.c \ - clutter-drag-action.c \ - clutter-drop-action.c \ - clutter-effect.c \ - clutter-event.c \ - clutter-feature.c \ - clutter-fixed-layout.c \ - clutter-flatten-effect.c \ - clutter-flow-layout.c \ - clutter-gesture-action.c \ - clutter-grid-layout.c \ - clutter-image.c \ - clutter-input-device.c \ - clutter-input-device-tool.c \ - clutter-input-focus.c \ - clutter-input-method.c \ - clutter-virtual-input-device.c \ - clutter-interval.c \ - clutter-keyframe-transition.c \ - clutter-keysyms-table.c \ - clutter-layout-manager.c \ - clutter-layout-meta.c \ - clutter-main.c \ - clutter-master-clock.c \ - clutter-master-clock-default.c \ - clutter-offscreen-effect.c \ - clutter-page-turn-effect.c \ - clutter-paint-nodes.c \ - clutter-paint-node.c \ - clutter-pan-action.c \ - clutter-path-constraint.c \ - clutter-path.c \ - clutter-property-transition.c \ - clutter-rotate-action.c \ - clutter-script.c \ - clutter-script-parser.c \ - clutter-scriptable.c \ - clutter-scroll-actor.c \ - clutter-settings.c \ - clutter-shader-effect.c \ - clutter-shader-types.c \ - clutter-swipe-action.c \ - clutter-snap-constraint.c \ - clutter-stage.c \ - clutter-stage-manager.c \ - clutter-stage-window.c \ - clutter-tap-action.c \ - clutter-test-utils.c \ - clutter-text.c \ - clutter-text-buffer.c \ - clutter-transition-group.c \ - clutter-transition.c \ - clutter-timeline.c \ - clutter-units.c \ - clutter-util.c \ - clutter-paint-volume.c \ - clutter-zoom-action.c \ - $(NULL) - -# private headers; these should not be distributed or introspected -source_h_priv = \ - clutter-actor-meta-private.h \ - clutter-actor-private.h \ - clutter-backend-private.h \ - clutter-bezier.h \ - clutter-constraint-private.h \ - clutter-content-private.h \ - clutter-debug.h \ - clutter-device-manager-private.h \ - clutter-easing.h \ - clutter-effect-private.h \ - clutter-event-translator.h \ - clutter-event-private.h \ - clutter-flatten-effect.h \ - clutter-gesture-action-private.h \ - clutter-id-pool.h \ - clutter-input-focus-private.h \ - clutter-input-method-private.h \ - clutter-master-clock.h \ - clutter-master-clock-default.h \ - clutter-offscreen-effect-private.h \ - clutter-paint-node-private.h \ - clutter-paint-volume-private.h \ - clutter-private.h \ - clutter-script-private.h \ - clutter-settings-private.h \ - clutter-stage-manager-private.h \ - clutter-stage-private.h \ - clutter-stage-view.h \ - clutter-stage-window.h \ - $(NULL) - -# private source code; these should not be introspected -source_c_priv = \ - clutter-easing.c \ - clutter-event-translator.c \ - clutter-id-pool.c \ - clutter-stage-view.c \ - $(NULL) - -# deprecated installed headers -deprecated_h = \ - deprecated/clutter-actor.h \ - deprecated/clutter-alpha.h \ - deprecated/clutter-animatable.h \ - deprecated/clutter-animation.h \ - deprecated/clutter-animator.h \ - deprecated/clutter-backend.h \ - deprecated/clutter-behaviour.h \ - deprecated/clutter-behaviour-depth.h \ - deprecated/clutter-behaviour-ellipse.h \ - deprecated/clutter-behaviour-opacity.h \ - deprecated/clutter-behaviour-path.h \ - deprecated/clutter-behaviour-rotate.h \ - deprecated/clutter-behaviour-scale.h \ - deprecated/clutter-bin-layout.h \ - deprecated/clutter-box.h \ - deprecated/clutter-cairo-texture.h \ - deprecated/clutter-container.h \ - deprecated/clutter-frame-source.h \ - deprecated/clutter-group.h \ - deprecated/clutter-input-device.h \ - deprecated/clutter-keysyms.h \ - deprecated/clutter-list-model.h \ - deprecated/clutter-main.h \ - deprecated/clutter-media.h \ - deprecated/clutter-model.h \ - deprecated/clutter-rectangle.h \ - deprecated/clutter-score.h \ - deprecated/clutter-shader.h \ - deprecated/clutter-stage-manager.h \ - deprecated/clutter-stage.h \ - deprecated/clutter-state.h \ - deprecated/clutter-table-layout.h \ - deprecated/clutter-texture.h \ - deprecated/clutter-timeline.h \ - deprecated/clutter-timeout-pool.h \ - deprecated/clutter-util.h \ - $(NULL) - -# deprecated source code -deprecated_c = \ - deprecated/clutter-actor-deprecated.c \ - deprecated/clutter-alpha.c \ - deprecated/clutter-animation.c \ - deprecated/clutter-animator.c \ - deprecated/clutter-behaviour.c \ - deprecated/clutter-behaviour-depth.c \ - deprecated/clutter-behaviour-ellipse.c \ - deprecated/clutter-behaviour-opacity.c \ - deprecated/clutter-behaviour-path.c \ - deprecated/clutter-behaviour-rotate.c \ - deprecated/clutter-behaviour-scale.c \ - deprecated/clutter-box.c \ - deprecated/clutter-cairo-texture.c \ - deprecated/clutter-frame-source.c \ - deprecated/clutter-group.c \ - deprecated/clutter-input-device-deprecated.c \ - deprecated/clutter-layout-manager-deprecated.c \ - deprecated/clutter-list-model.c \ - deprecated/clutter-media.c \ - deprecated/clutter-model.c \ - deprecated/clutter-rectangle.c \ - deprecated/clutter-score.c \ - deprecated/clutter-shader.c \ - deprecated/clutter-state.c \ - deprecated/clutter-table-layout.c \ - deprecated/clutter-texture.c \ - deprecated/clutter-timeout-pool.c \ - $(NULL) - -# deprecated private headers; these should not be installed -deprecated_h_priv = \ - deprecated/clutter-model-private.h \ - deprecated/clutter-timeout-interval.h \ - $(NULL) - -# deprecated private source code; these should not be introspected -deprecated_c_priv = \ - deprecated/clutter-timeout-interval.c \ - $(NULL) - -# built sources -built_source_c = \ - clutter-enum-types.c \ - clutter-marshal.c \ - $(NULL) - -# built headers -built_source_h = \ - clutter-enum-types.h \ - clutter-marshal.h \ - $(NULL) - -# config header -DISTCLEANFILES += clutter-config.h -EXTRA_DIST += clutter-config.h.in - -# version header -DISTCLEANFILES += clutter-version.h -EXTRA_DIST += clutter-version.h.in clutter-version.h - -# key symbol update script -EXTRA_DIST += clutter-keysyms-update.pl - -pc_files += muffin-clutter-$(MUFFIN_PLUGIN_API_VERSION).pc - -# in order to be compatible with Clutter < 1.10, when we shipped a single -# shared library whose name was determined by the single backend it -# supported, we need to install symbolic links so that existing applications -# using Clutter won't break in the Brave New World of multi-backend support -# in the same shared object. -compat_libs = - -# backends source listings -# -# backend_source_c := source code -# backend_source_h := installed public headers -# backend_source_c_priv := source that should not be scanned by g-i -# backend_source_h_priv := private headers -# backend_source_built := built sources -# -backend_source_c = -backend_source_h = -backend_source_c_priv = -backend_source_h_priv = -backend_source_built = - -# X11 backend rules -x11_source_c = \ - x11/clutter-backend-x11.c \ - x11/clutter-device-manager-core-x11.c \ - x11/clutter-event-x11.c \ - x11/clutter-input-device-core-x11.c \ - x11/clutter-keymap-x11.c \ - x11/clutter-stage-x11.c \ - x11/clutter-x11-texture-pixmap.c \ - x11/clutter-xkb-a11y-x11.c \ - $(NULL) - -x11_source_h = \ - x11/clutter-x11.h \ - x11/clutter-x11-texture-pixmap.h \ - $(NULL) - -x11_source_h_priv = \ - x11/clutter-backend-x11.h \ - x11/clutter-device-manager-core-x11.h \ - x11/clutter-input-device-core-x11.h \ - x11/clutter-keymap-x11.h \ - x11/clutter-settings-x11.h \ - x11/clutter-stage-x11.h \ - x11/clutter-xkb-a11y-x11.h \ - $(NULL) - -x11_source_c_priv = \ - x11/xsettings/xsettings-client.c \ - x11/xsettings/xsettings-client.h \ - x11/xsettings/xsettings-common.c \ - x11/xsettings/xsettings-common.h \ - $(NULL) - -x11_source_c += \ - x11/clutter-device-manager-xi2.c \ - x11/clutter-input-device-xi2.c \ - x11/clutter-input-device-tool-xi2.c \ - $(NULL) - -x11_source_h_priv += \ - x11/clutter-device-manager-xi2.h \ - x11/clutter-input-device-xi2.h \ - x11/clutter-input-device-tool-xi2.h \ - $(NULL) - -x11_source_c += \ - x11/clutter-virtual-input-device-x11.c \ - $(NULL) - -x11_source_h_priv += \ - x11/clutter-virtual-input-device-x11.h \ - $(NULL) - -backend_source_h += $(x11_source_h) -backend_source_c += $(x11_source_c) -backend_source_h_priv += $(x11_source_h_priv) -backend_source_c_priv += $(x11_source_c_priv) - -# the list of files we want to introspect on X11 -x11_introspection = $(x11_source_c) $(x11_source_h) - -clutterx11_includedir = $(clutter_includedir)/x11 -clutterx11_include_HEADERS = $(x11_source_h) - -muffin-clutter-x11-@MUFFIN_PLUGIN_API_VERSION@.pc: muffin-clutter-$(MUFFIN_PLUGIN_API_VERSION).pc - $(QUIET_GEN)cp -f $< $(@F) - -pc_files += muffin-clutter-x11-$(MUFFIN_PLUGIN_API_VERSION).pc - -# Shared cogl backend files -cogl_source_h = - -cogl_source_c = \ - cogl/clutter-stage-cogl.c \ - $(NULL) - -cogl_source_h_priv = \ - cogl/clutter-stage-cogl.h \ - $(NULL) - -cogl_source_c_priv = - -backend_source_h += $(cogl_source_h) -backend_source_c += $(cogl_source_c) -backend_source_h_priv += $(cogl_source_h_priv) -backend_source_c_priv += $(cogl_source_c_priv) - -backend_source_h += $(glx_source_h) -backend_source_c += $(glx_source_c) - -evdev_c_priv = \ - evdev/clutter-device-manager-evdev.c \ - evdev/clutter-input-device-evdev.c \ - evdev/clutter-seat-evdev.c \ - evdev/clutter-virtual-input-device-evdev.c \ - evdev/clutter-event-evdev.c \ - evdev/clutter-input-device-tool-evdev.c \ - $(NULL) -evdev_h_priv = \ - evdev/clutter-device-manager-evdev.h \ - evdev/clutter-input-device-evdev.h \ - evdev/clutter-seat-evdev.h \ - evdev/clutter-input-device-tool-evdev.h \ - evdev/clutter-virtual-input-device-evdev.h \ - $(NULL) -evdev_h = evdev/clutter-evdev.h - -if SUPPORT_WAYLAND -backend_source_c_priv += $(evdev_c_priv) -backend_source_h_priv += $(evdev_h_priv) -backend_source_h += $(evdev_h) - -clutterevdev_includedir = $(clutter_includedir)/evdev -clutterevdev_include_HEADERS = $(evdev_h) - -backend_source_c += evdev/clutter-xkb-utils.c -backend_source_h_priv += evdev/clutter-xkb-utils.h - -# EGL backend rules -egl_source_h = \ - egl/clutter-egl-headers.h \ - egl/clutter-egl.h \ - $(NULL) - -egl_source_h_priv = egl/clutter-backend-eglnative.h -egl_source_c = egl/clutter-backend-eglnative.c - -wayland_compositor_source_h = \ - wayland/clutter-wayland-compositor.h \ - wayland/clutter-wayland-surface.h -backend_source_h += $(wayland_compositor_source_h) -backend_source_c += \ - wayland/clutter-wayland-surface.c - -wayland_compositor_includedir = $(clutter_includedir)/wayland -wayland_compositor_include_HEADERS = $(wayland_compositor_source_h) - -backend_source_h += $(egl_source_h) -backend_source_c += $(egl_source_c) -backend_source_h_priv += $(egl_source_h_priv) - -clutteregl_includedir = $(clutter_includedir)/egl -clutteregl_include_HEADERS = $(egl_source_h) -endif # SUPPORT_WAYLAND - -# cally -cally_sources_h = \ - cally/cally-actor.h \ - cally/cally-clone.h \ - cally/cally-factory.h \ - cally/cally-group.h \ - cally/cally.h \ - cally/cally-main.h \ - cally/cally-rectangle.h \ - cally/cally-root.h \ - cally/cally-stage.h \ - cally/cally-text.h \ - cally/cally-texture.h \ - cally/cally-util.h \ - $(NULL) - -cally_sources_c = \ - cally/cally-actor.c \ - cally/cally.c \ - cally/cally-clone.c \ - cally/cally-group.c \ - cally/cally-rectangle.c \ - cally/cally-root.c \ - cally/cally-stage.c \ - cally/cally-text.c \ - cally/cally-texture.c \ - cally/cally-util.c \ - $(NULL) - -cally_sources_private = \ - cally/cally-actor-private.h \ - $(NULL) - -cally_includedir = $(clutter_base_includedir)/cally -cally_include_HEADERS = $(cally_sources_h) - -# general build rules: -# you should not need to modify anything below this point - -# glib-genmarshal rules -glib_marshal_list = clutter-marshal.list -glib_marshal_prefix = _clutter_marshal -include $(srcdir)/Makefile.am.marshal - -# glib-mkenums rules -glib_enum_h = clutter-enum-types.h -glib_enum_c = clutter-enum-types.c -glib_enum_headers = $(source_h) $(deprecated_h) -include $(srcdir)/Makefile.am.enums - -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = $(pc_files) -DISTCLEANFILES += $(pc_files) - -clutter_include_HEADERS = $(source_h) clutter.h clutter-version.h clutter-autocleanups.h clutter-muffin.h -nodist_clutter_include_HEADERS = clutter-config.h $(built_source_h) - -clutter_deprecated_HEADERS = $(deprecated_h) - -muffinlibdir = $(libdir)/muffin -muffinlib_LTLIBRARIES = libmuffin-clutter-@MUFFIN_PLUGIN_API_VERSION@.la - -libmuffin_clutter_@MUFFIN_PLUGIN_API_VERSION@_la_LIBADD = \ - $(LIBM) \ - $(CLUTTER_LIBS) \ - $(top_builddir)/../cogl/cogl/libmuffin-cogl-$(MUFFIN_PLUGIN_API_VERSION).la \ - $(top_builddir)/../cogl/cogl-pango/libmuffin-cogl-pango-$(MUFFIN_PLUGIN_API_VERSION).la \ - $(top_builddir)/../cogl/cogl-path/libmuffin-cogl-path-$(MUFFIN_PLUGIN_API_VERSION).la \ - $(NULL) - -libmuffin_clutter_@MUFFIN_PLUGIN_API_VERSION@_la_SOURCES = \ - $(backend_source_c) \ - $(backend_source_h) \ - $(backend_source_c_priv) \ - $(backend_source_h_priv) \ - $(source_c) \ - $(source_h) \ - $(source_c_priv) \ - $(source_h_priv) \ - $(deprecated_c) \ - $(deprecated_h) \ - $(deprecated_c_priv) \ - $(deprecated_h_priv) \ - $(cally_sources_c) \ - $(cally_sources_h) \ - $(cally_sources_private) \ - $(NULL) - -nodist_libmuffin_clutter_@MUFFIN_PLUGIN_API_VERSION@_la_SOURCES = \ - $(backend_source_built) \ - $(built_source_c) \ - $(built_source_h) - -libmuffin_clutter_@MUFFIN_PLUGIN_API_VERSION@_la_LDFLAGS = \ - $(CLUTTER_LINK_FLAGS) \ - $(CLUTTER_LT_LDFLAGS) \ - -export-dynamic \ - -rpath $(muffinlibdir) \ - $(NULL) - -install-exec-local: - test -z "$(muffinlibdir)" || $(MKDIR_P) "$(DESTDIR)$(muffinlibdir)" - for lib in `echo $(compat_libs)`; do \ - (cd $(DESTDIR)$(muffinlibdir) && \ - rm -f $$lib.0.$(CLUTTER_LT_CURRENT).$(CLUTTER_LT_REVISION); \ - ) ; \ - (cd $(DESTDIR)$(muffinlibdir) && \ - { ln -s -f libmuffin-clutter-$(MUFFIN_PLUGIN_API_VERSION).so.0.$(CLUTTER_LT_CURRENT).$(CLUTTER_LT_REVISION) $$lib.0 || \ - { rm -f $$lib.0 && ln -s libmuffin-clutter-$(MUFFIN_PLUGIN_API_VERSION).so.0.$(CLUTTER_LT_CURRENT).$(CLUTTER_LT_REVISION) $$lib.0; }; \ - } \ - ) ; \ - (cd $(DESTDIR)$(muffinlibdir) && \ - { ln -s -f libmuffin-clutter-$(MUFFIN_PLUGIN_API_VERSION).so.0.$(CLUTTER_LT_CURRENT).$(CLUTTER_LT_REVISION) $$lib || \ - { rm -f $$lib && ln -s libmuffin-clutter-$(MUFFIN_PLUGIN_API_VERSION).so.0.$(CLUTTER_LT_CURRENT).$(CLUTTER_LT_REVISION) $$lib; }; \ - } \ - ) ; \ - done - -if HAVE_INTROSPECTION -# gobject-introspection rules --include $(INTROSPECTION_MAKEFILE) - -INTROSPECTION_SCANNER_ARGS = \ - --add-include-path=$(top_builddir)/../cogl/cogl \ - --add-include-path=$(top_builddir)/../cogl/cogl-pango -INTROSPECTION_COMPILER_ARGS = \ - --includedir=$(top_builddir)/../cogl/cogl \ - --includedir=$(top_builddir)/../cogl/cogl-pango -INTROSPECTION_SCANNER_ENV = \ - PKG_CONFIG_PATH=$(top_builddir)/../cogl/cogl/:$(top_builddir)/../cogl/cogl-pango/:$${PKG_CONFIG_PATH} - -Clutter-@MUFFIN_PLUGIN_API_VERSION@.gir: libmuffin-clutter-@MUFFIN_PLUGIN_API_VERSION@.la Makefile - -Clutter_@MUFFIN_PLUGIN_API_VERSION@_gir_NAMESPACE = Clutter -Clutter_@MUFFIN_PLUGIN_API_VERSION@_gir_VERSION = @MUFFIN_PLUGIN_API_VERSION@ -Clutter_@MUFFIN_PLUGIN_API_VERSION@_gir_LIBS = \ - libmuffin-clutter-@MUFFIN_PLUGIN_API_VERSION@.la \ - $(top_builddir)/../cogl/cogl/libmuffin-cogl-@MUFFIN_PLUGIN_API_VERSION@.la \ - $(top_builddir)/../cogl/cogl-pango/libmuffin-cogl-pango-@MUFFIN_PLUGIN_API_VERSION@.la \ - $(top_builddir)/../cogl/cogl-path/libmuffin-cogl-path-@MUFFIN_PLUGIN_API_VERSION@.la -Clutter_@MUFFIN_PLUGIN_API_VERSION@_gir_FILES = \ - $(clutter_include_HEADERS) \ - $(clutter_deprecated_HEADERS) \ - $(nodist_clutter_include_HEADERS) \ - $(source_c) \ - $(deprecated_c) \ - $(built_source_c) -Clutter_@MUFFIN_PLUGIN_API_VERSION@_gir_CFLAGS = $(AM_CPPFLAGS) $(CLUTTER_CFLAGS) -Clutter_@MUFFIN_PLUGIN_API_VERSION@_gir_INCLUDES = GL-1.0 GObject-2.0 cairo-1.0 Cogl-@MUFFIN_PLUGIN_API_VERSION@ CoglPango-@MUFFIN_PLUGIN_API_VERSION@ Atk-1.0 Json-1.0 -Clutter_@MUFFIN_PLUGIN_API_VERSION@_gir_SCANNERFLAGS = \ - --warn-all \ - --c-include='clutter/clutter.h' \ - --pkg-export=muffin-clutter-@MUFFIN_PLUGIN_API_VERSION@ - -INTROSPECTION_GIRS += Clutter-@MUFFIN_PLUGIN_API_VERSION@.gir - -Cally-@MUFFIN_PLUGIN_API_VERSION@.gir: Makefile Clutter-@MUFFIN_PLUGIN_API_VERSION@.gir - -Cally_@MUFFIN_PLUGIN_API_VERSION@_gir_NAMESPACE = Cally -Cally_@MUFFIN_PLUGIN_API_VERSION@_gir_VERSION = @MUFFIN_PLUGIN_API_VERSION@ -Cally_@MUFFIN_PLUGIN_API_VERSION@_gir_LIBS = \ - libmuffin-clutter-@MUFFIN_PLUGIN_API_VERSION@.la \ - $(top_builddir)/../cogl/cogl/libmuffin-cogl-@MUFFIN_PLUGIN_API_VERSION@.la \ - $(top_builddir)/../cogl/cogl-pango/libmuffin-cogl-pango-@MUFFIN_PLUGIN_API_VERSION@.la \ - $(top_builddir)/../cogl/cogl-path/libmuffin-cogl-path-@MUFFIN_PLUGIN_API_VERSION@.la -Cally_@MUFFIN_PLUGIN_API_VERSION@_gir_FILES = $(cally_sources_h) $(cally_sources_c) -Cally_@MUFFIN_PLUGIN_API_VERSION@_gir_CFLAGS = $(AM_CPPFLAGS) $(CLUTTER_CFLAGS) -Cally_@MUFFIN_PLUGIN_API_VERSION@_gir_SCANNERFLAGS = \ - --warn-all \ - --c-include='cally/cally.h' \ - --pkg-export=muffin-clutter-@MUFFIN_PLUGIN_API_VERSION@ \ - --include-uninstalled=$(top_builddir)/clutter/Clutter-@MUFFIN_PLUGIN_API_VERSION@.gir - -INTROSPECTION_GIRS += Cally-@MUFFIN_PLUGIN_API_VERSION@.gir - -ClutterX11-@MUFFIN_PLUGIN_API_VERSION@.gir: Makefile Clutter-@MUFFIN_PLUGIN_API_VERSION@.gir - -ClutterX11_@MUFFIN_PLUGIN_API_VERSION@_gir_NAMESPACE = ClutterX11 -ClutterX11_@MUFFIN_PLUGIN_API_VERSION@_gir_INCLUDES = xlib-2.0 -ClutterX11_@MUFFIN_PLUGIN_API_VERSION@_gir_LIBS = \ - libmuffin-clutter-@MUFFIN_PLUGIN_API_VERSION@.la \ - $(top_builddir)/../cogl/cogl/libmuffin-cogl-@MUFFIN_PLUGIN_API_VERSION@.la \ - $(top_builddir)/../cogl/cogl-pango/libmuffin-cogl-pango-@MUFFIN_PLUGIN_API_VERSION@.la \ - $(top_builddir)/../cogl/cogl-path/libmuffin-cogl-path-@MUFFIN_PLUGIN_API_VERSION@.la -ClutterX11_@MUFFIN_PLUGIN_API_VERSION@_gir_FILES = $(x11_introspection) -ClutterX11_@MUFFIN_PLUGIN_API_VERSION@_gir_CFLAGS = $(AM_CPPFLAGS) $(CLUTTER_CFLAGS) -ClutterX11_@MUFFIN_PLUGIN_API_VERSION@_gir_SCANNERFLAGS = \ - --warn-all \ - --c-include='clutter/x11/clutter-x11.h' \ - --pkg-export=muffin-clutter-x11-@MUFFIN_PLUGIN_API_VERSION@ \ - --include-uninstalled=$(top_builddir)/clutter/Clutter-@MUFFIN_PLUGIN_API_VERSION@.gir - -INTROSPECTION_GIRS += ClutterX11-@MUFFIN_PLUGIN_API_VERSION@.gir - -# INTROSPECTION_GIRDIR/INTROSPECTION_TYPELIBDIR aren't the right place to -# install anything - we need to install inside our prefix. -girdir = $(muffinlibdir) -gir_DATA = $(INTROSPECTION_GIRS) - -typelibdir = $(muffinlibdir) -typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib) - -CLEANFILES += $(gir_DATA) $(typelib_DATA) -endif - -EXTRA_DIST += \ - Makefile.am.marshal \ - Makefile.am.enums diff --git a/clutter/clutter/Makefile.am.enums b/clutter/clutter/Makefile.am.enums deleted file mode 100644 index 2fd69d5bd..000000000 --- a/clutter/clutter/Makefile.am.enums +++ /dev/null @@ -1,52 +0,0 @@ -# Rules for generating enumeration types using glib-mkenums -# -# Define: -# glib_enum_h = header template file -# glib_enum_c = source template file -# glib_enum_headers = list of headers to parse -# -# before including Makefile.am.enums. You will also need to have -# the following targets already defined: -# -# CLEANFILES -# DISTCLEANFILES -# BUILT_SOURCES -# EXTRA_DIST -# -# Author: Emmanuele Bassi - -# Basic sanity checks -$(if $(GLIB_MKENUMS),,$(error Need to define GLIB_MKENUMS)) - -$(if $(or $(glib_enum_h), \ - $(glib_enum_c)),, \ - $(error Need to define glib_enum_h and glib_enum_c)) - -$(if $(glib_enum_headers),,$(error Need to define glib_enum_headers)) - -enum_tmpl_h=$(addprefix $(srcdir)/, $(glib_enum_h:.h=.h.in)) -enum_tmpl_c=$(addprefix $(srcdir)/, $(glib_enum_c:.c=.c.in)) -enum_headers=$(addprefix $(srcdir)/, $(glib_enum_headers)) - -CLEANFILES += stamp-enum-types -DISTCLEANFILES += $(glib_enum_h) $(glib_enum_c) -BUILT_SOURCES += $(glib_enum_h) $(glib_enum_c) -EXTRA_DIST += $(enum_tmpl_h) $(enum_tmpl_c) - -stamp-enum-types: $(enum_headers) $(enum_tmpl_h) - $(AM_V_GEN)$(GLIB_MKENUMS) \ - --template $(enum_tmpl_h) \ - $(enum_headers) > xgen-eh \ - && (cmp -s xgen-eh $(glib_enum_h) || cp -f xgen-eh $(glib_enum_h)) \ - && rm -f xgen-eh \ - && echo timestamp > $(@F) - -$(glib_enum_h): stamp-enum-types - @true - -$(glib_enum_c): $(enum_headers) $(enum_tmpl_h) $(enum_tmpl_c) - $(AM_V_GEN)$(GLIB_MKENUMS) \ - --template $(enum_tmpl_c) \ - $(enum_headers) > xgen-ec \ - && cp -f xgen-ec $(glib_enum_c) \ - && rm -f xgen-ec diff --git a/clutter/clutter/Makefile.am.marshal b/clutter/clutter/Makefile.am.marshal deleted file mode 100644 index 89d3222eb..000000000 --- a/clutter/clutter/Makefile.am.marshal +++ /dev/null @@ -1,52 +0,0 @@ -# Rules for generating marshal files using glib-genmarshal -# -# Define: -# glib_marshal_list = marshal list file -# glib_marshal_prefix = prefix for marshal functions -# -# before including Makefile.am.marshal. You will also need to have -# the following targets already defined: -# -# CLEANFILES -# DISTCLEANFILES -# BUILT_SOURCES -# EXTRA_DIST -# -# Author: Emmanuele Bassi - -# Basic sanity checks -$(if $(GLIB_GENMARSHAL),,$(error Need to define GLIB_GENMARSHAL)) - -$(if $(or $(glib_marshal_list), \ - $(glib_marshal_prefix)),, \ - $(error Need to define glib_marshal_list and glib_marshal_prefix)) - -marshal_h = $(glib_marshal_list:.list=.h) -marshal_c = $(glib_marshal_list:.list=.c) -marshal_list = $(addprefix $(srcdir)/, $(glib_marshal_list)) - -CLEANFILES += stamp-marshal -DISTCLEANFILES += $(marshal_h) $(marshal_c) -BUILT_SOURCES += $(marshal_h) $(marshal_c) -EXTRA_DIST += $(marshal_list) - -stamp-marshal: $(marshal_list) - $(AM_V_GEN)$(GLIB_GENMARSHAL) \ - --prefix=$(glib_marshal_prefix) \ - --header \ - $(marshal_list) > xgen-mh \ - && (cmp -s xgen-mh $(marshal_h) || cp -f xgen-mh $(marshal_h)) \ - && rm -f xgen-mh \ - && echo timestamp > $(@F) - -$(marshal_h): stamp-marshal - @true - -$(marshal_c): $(marshal_h) - $(AM_V_GEN)(echo "#include \"$(marshal_h)\"" ; \ - $(GLIB_GENMARSHAL) \ - --prefix=$(glib_marshal_prefix) \ - --body \ - $(marshal_list)) > xgen-mc \ - && cp xgen-mc $(marshal_c) \ - && rm -f xgen-mc diff --git a/clutter/clutter/cally/cally-actor.c b/clutter/clutter/cally/cally-actor.c index b7f3ed7cf..a1f92ffe3 100644 --- a/clutter/clutter/cally/cally-actor.c +++ b/clutter/clutter/cally/cally-actor.c @@ -67,9 +67,7 @@ * */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include #include @@ -312,11 +310,7 @@ cally_actor_finalize (GObject *obj) _cally_actor_clean_action_list (cally_actor); - if (priv->action_idle_handler) - { - g_source_remove (priv->action_idle_handler); - priv->action_idle_handler = 0; - } + g_clear_handle_id (&priv->action_idle_handler, g_source_remove); if (priv->action_queue) { @@ -606,10 +600,11 @@ cally_actor_real_remove_actor (ClutterActor *container, g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), 0); atk_parent = ATK_OBJECT (data); - atk_child = clutter_actor_get_accessible (actor); - if (atk_child) + if (clutter_actor_has_accessible (actor)) { + atk_child = clutter_actor_get_accessible (actor); + g_value_init (&values.old_value, G_TYPE_POINTER); g_value_set_pointer (&values.old_value, atk_parent); @@ -659,7 +654,7 @@ cally_actor_get_extents (AtkComponent *component, ClutterActor *actor = NULL; gint top_level_x, top_level_y; gfloat f_width, f_height; - ClutterVertex verts[4]; + graphene_point3d_t verts[4]; ClutterActor *stage = NULL; g_return_if_fail (CALLY_IS_ACTOR (component)); @@ -739,11 +734,7 @@ cally_actor_grab_focus (AtkComponent *component) * * This gets the top level origin, it is, the position of the stage in * the global screen. You can see it as the absolute display position - * of the stage. - * - * FIXME: only the case with x11 is implemented, other backends are - * required - * + * of the stage. This is 0,0 for a compositor. */ void _cally_actor_get_top_level_origin (ClutterActor *actor, @@ -751,54 +742,11 @@ _cally_actor_get_top_level_origin (ClutterActor *actor, gint *yp) { /* default values */ - gint x = 0; - gint y = 0; - -#ifdef CLUTTER_WINDOWING_X11 - if (clutter_check_windowing_backend (CLUTTER_WINDOWING_X11)) - { - ClutterActor *stage = NULL; - Display *display = NULL; - Window root_window; - Window stage_window; - Window child; - gint return_val = 0; - - stage = clutter_actor_get_stage (actor); - - /* FIXME: what happens if you use another display with - clutter_backend_x11_set_display ?*/ - display = clutter_x11_get_default_display (); - root_window = clutter_x11_get_root_window (); - stage_window = clutter_x11_get_stage_window (CLUTTER_STAGE (stage)); - - return_val = XTranslateCoordinates (display, stage_window, root_window, - 0, 0, &x, &y, - &child); - - if (!return_val) - g_warning ("[x11] We were not able to get proper absolute " - "position of the stage"); - } - else -#endif - { - static gboolean yet_warned = FALSE; - - if (!yet_warned) - { - yet_warned = TRUE; - - g_warning ("The current Clutter backend does not support using " - "atk_component_get_extents() with ATK_XY_SCREEN."); - } - } - if (xp) - *xp = x; + *xp = 0; if (yp) - *yp = y; + *yp = 0; } /* AtkAction implementation */ @@ -819,10 +767,11 @@ static gboolean cally_actor_action_do_action (AtkAction *action, gint index) { - CallyActor *cally_actor = NULL; - AtkStateSet *set = NULL; - CallyActorPrivate *priv = NULL; - CallyActorActionInfo *info = NULL; + CallyActor *cally_actor = NULL; + AtkStateSet *set = NULL; + CallyActorPrivate *priv = NULL; + CallyActorActionInfo *info = NULL; + gboolean did_action = FALSE; cally_actor = CALLY_ACTOR (action); priv = cally_actor->priv; @@ -830,21 +779,19 @@ cally_actor_action_do_action (AtkAction *action, set = atk_object_ref_state_set (ATK_OBJECT (cally_actor)); if (atk_state_set_contains_state (set, ATK_STATE_DEFUNCT)) - return FALSE; + goto out; if (!atk_state_set_contains_state (set, ATK_STATE_SENSITIVE) || !atk_state_set_contains_state (set, ATK_STATE_SHOWING)) - return FALSE; - - g_object_unref (set); + goto out; info = _cally_actor_get_action_info (cally_actor, index); if (info == NULL) - return FALSE; + goto out; if (info->do_action_func == NULL) - return FALSE; + goto out; if (!priv->action_queue) priv->action_queue = g_queue_new (); @@ -854,7 +801,12 @@ cally_actor_action_do_action (AtkAction *action, if (!priv->action_idle_handler) priv->action_idle_handler = g_idle_add (idle_do_action, cally_actor); - return TRUE; + did_action = TRUE; + +out: + g_clear_object (&set); + + return did_action; } static gboolean @@ -947,7 +899,7 @@ cally_actor_action_set_description (AtkAction *action, if (info == NULL) return FALSE; - free (info->description); + g_free (info->description); info->description = g_strdup (desc); return TRUE; @@ -1046,10 +998,8 @@ _cally_actor_clean_action_list (CallyActor *cally_actor) if (priv->action_list) { - g_list_foreach (priv->action_list, - (GFunc) _cally_actor_destroy_action_info, - NULL); - g_list_free (priv->action_list); + g_list_free_full (priv->action_list, + (GDestroyNotify) _cally_actor_destroy_action_info); priv->action_list = NULL; } } @@ -1236,9 +1186,9 @@ _cally_actor_destroy_action_info (gpointer action_info, g_assert (info != NULL); - free (info->name); - free (info->description); - free (info->keybinding); + g_free (info->name); + g_free (info->description); + g_free (info->keybinding); if (info->notify) info->notify (info->user_data); diff --git a/clutter/clutter/cally/cally-actor.h b/clutter/clutter/cally/cally-actor.h index c17c26ea6..f67bcafb2 100644 --- a/clutter/clutter/cally/cally-actor.h +++ b/clutter/clutter/cally/cally-actor.h @@ -126,19 +126,19 @@ struct _CallyActorClass gpointer _padding_dummy[32]; }; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT GType cally_actor_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT AtkObject* cally_actor_new (ClutterActor *actor); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT guint cally_actor_add_action (CallyActor *cally_actor, const gchar *action_name, const gchar *action_description, const gchar *action_keybinding, CallyActionFunc action_func); -CLUTTER_AVAILABLE_IN_1_6 +CLUTTER_EXPORT guint cally_actor_add_action_full (CallyActor *cally_actor, const gchar *action_name, const gchar *action_description, @@ -147,11 +147,11 @@ guint cally_actor_add_action_full (CallyActor *cally_actor, gpointer user_data, GDestroyNotify notify); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT gboolean cally_actor_remove_action (CallyActor *cally_actor, gint action_id); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT gboolean cally_actor_remove_action_by_name (CallyActor *cally_actor, const gchar *action_name); diff --git a/clutter/clutter/cally/cally-clone.h b/clutter/clutter/cally/cally-clone.h index 3a3777035..24b0def86 100644 --- a/clutter/clutter/cally/cally-clone.h +++ b/clutter/clutter/cally/cally-clone.h @@ -74,9 +74,9 @@ struct _CallyCloneClass gpointer _padding_dummy[8]; }; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT GType cally_clone_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT AtkObject *cally_clone_new (ClutterActor *actor); G_END_DECLS diff --git a/clutter/clutter/cally/cally-factory.h b/clutter/clutter/cally/cally-factory.h index 514d8c2eb..432844fb6 100644 --- a/clutter/clutter/cally/cally-factory.h +++ b/clutter/clutter/cally/cally-factory.h @@ -93,7 +93,7 @@ type_as_function ## _factory_get_type (void) \ name = g_strconcat (g_type_name (type), "Factory", NULL); \ t = g_type_register_static ( \ ATK_TYPE_OBJECT_FACTORY, name, &tinfo, 0); \ - free (name); \ + g_free (name); \ } \ \ return t; \ diff --git a/clutter/clutter/cally/cally-group.h b/clutter/clutter/cally/cally-group.h index 4efd25902..d97240a9d 100644 --- a/clutter/clutter/cally/cally-group.h +++ b/clutter/clutter/cally/cally-group.h @@ -77,9 +77,9 @@ struct _CallyGroupClass gpointer _padding_dummy[8]; }; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT GType cally_group_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT AtkObject* cally_group_new (ClutterActor *actor); G_END_DECLS diff --git a/clutter/clutter/cally/cally-main.h b/clutter/clutter/cally/cally-main.h index 62931979b..07d668b03 100644 --- a/clutter/clutter/cally/cally-main.h +++ b/clutter/clutter/cally/cally-main.h @@ -34,9 +34,9 @@ G_BEGIN_DECLS -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT gboolean cally_get_cally_initialized (void); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT gboolean cally_accessibility_init (void); G_END_DECLS diff --git a/clutter/clutter/cally/cally-rectangle.h b/clutter/clutter/cally/cally-rectangle.h index 0a205c5e6..db45a482a 100644 --- a/clutter/clutter/cally/cally-rectangle.h +++ b/clutter/clutter/cally/cally-rectangle.h @@ -74,9 +74,9 @@ struct _CallyRectangleClass gpointer _padding_dummy[8]; }; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT GType cally_rectangle_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT AtkObject* cally_rectangle_new (ClutterActor *actor); G_END_DECLS diff --git a/clutter/clutter/cally/cally-root.c b/clutter/clutter/cally/cally-root.c index 2f16296bc..34473fcd7 100644 --- a/clutter/clutter/cally/cally-root.c +++ b/clutter/clutter/cally/cally-root.c @@ -75,8 +75,8 @@ struct _CallyRootPrivate GSList *stage_list; /* signals id */ - guint stage_added_id; - guint stage_removed_id; + gulong stage_added_id; + gulong stage_removed_id; }; G_DEFINE_TYPE_WITH_PRIVATE (CallyRoot, cally_root, ATK_TYPE_GOBJECT_ACCESSIBLE) @@ -149,11 +149,9 @@ cally_root_finalize (GObject *object) stage_manager = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (root)); - g_signal_handler_disconnect (stage_manager, - root->priv->stage_added_id); + g_clear_signal_handler (&root->priv->stage_added_id, stage_manager); - g_signal_handler_disconnect (stage_manager, - root->priv->stage_added_id); + g_clear_signal_handler (&root->priv->stage_removed_id, stage_manager); G_OBJECT_CLASS (cally_root_parent_class)->finalize (object); } diff --git a/clutter/clutter/cally/cally-root.h b/clutter/clutter/cally/cally-root.h index 10674942f..16bba36ef 100644 --- a/clutter/clutter/cally/cally-root.h +++ b/clutter/clutter/cally/cally-root.h @@ -74,9 +74,9 @@ struct _CallyRootClass gpointer _padding_dummy[16]; }; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT GType cally_root_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT AtkObject *cally_root_new (void); G_END_DECLS diff --git a/clutter/clutter/cally/cally-stage.h b/clutter/clutter/cally/cally-stage.h index c95d2ca13..e8f676de5 100644 --- a/clutter/clutter/cally/cally-stage.h +++ b/clutter/clutter/cally/cally-stage.h @@ -74,9 +74,9 @@ struct _CallyStageClass gpointer _padding_dummy[16]; }; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT GType cally_stage_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT AtkObject *cally_stage_new (ClutterActor *actor); G_END_DECLS diff --git a/clutter/clutter/cally/cally-text.c b/clutter/clutter/cally/cally-text.c index 3d26b72b5..2b34f098c 100644 --- a/clutter/clutter/cally/cally-text.c +++ b/clutter/clutter/cally/cally-text.c @@ -39,9 +39,7 @@ * */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include "cally-text.h" #include "cally-actor-private.h" @@ -249,11 +247,7 @@ cally_text_finalize (GObject *obj) /* g_object_unref (cally_text->priv->textutil); */ /* cally_text->priv->textutil = NULL; */ - if (cally_text->priv->insert_idle_handler) - { - g_source_remove (cally_text->priv->insert_idle_handler); - cally_text->priv->insert_idle_handler = 0; - } + g_clear_handle_id (&cally_text->priv->insert_idle_handler, g_source_remove); G_OBJECT_CLASS (cally_text_parent_class)->finalize (obj); } @@ -750,7 +744,7 @@ pango_layout_get_line_after (PangoLayout *layout, * atk_text_get_text_after_offset(). * * Returns: a newly allocated string containing a slice of text - * from layout. Free with free(). + * from layout. Free with g_free(). */ static gchar * _gtk_pango_get_text_at (PangoLayout *layout, @@ -849,7 +843,7 @@ _gtk_pango_get_text_at (PangoLayout *layout, * atk_text_get_text_before_offset(). * * Returns: a newly allocated string containing a slice of text - * from layout. Free with free(). + * from layout. Free with g_free(). */ static gchar * _gtk_pango_get_text_before (PangoLayout *layout, @@ -950,7 +944,7 @@ _gtk_pango_get_text_before (PangoLayout *layout, * atk_text_get_text_after_offset(). * * Returns: a newly allocated string containing a slice of text - * from layout. Free with free(). + * from layout. Free with g_free(). */ static gchar * _gtk_pango_get_text_after (PangoLayout *layout, @@ -1440,7 +1434,7 @@ static void cally_text_get_character_extents (AtkText *text, PangoLayout *layout; PangoRectangle extents; const gchar *text_value; - ClutterVertex verts[4]; + graphene_point3d_t verts[4]; actor = CALLY_GET_CLUTTER_ACTOR (text); if (actor == NULL) /* State is defunct */ @@ -1860,7 +1854,7 @@ _cally_misc_add_attribute (AtkAttributeSet *attrib_set, gchar *value) { AtkAttributeSet *return_set; - AtkAttribute *at = malloc (sizeof (AtkAttribute)); + AtkAttribute *at = g_malloc (sizeof (AtkAttribute)); at->name = g_strdup (atk_text_attribute_get_name (attr)); at->value = value; return_set = g_slist_prepend(attrib_set, at); @@ -2296,7 +2290,7 @@ _cally_misc_get_index_at_point (ClutterText *clutter_text, gint index, x_window, y_window, x_toplevel, y_toplevel; gint x_temp, y_temp; gboolean ret; - ClutterVertex verts[4]; + graphene_point3d_t verts[4]; PangoLayout *layout; gint x_layout, y_layout; diff --git a/clutter/clutter/cally/cally-text.h b/clutter/clutter/cally/cally-text.h index ce3c0cba0..070ac9139 100644 --- a/clutter/clutter/cally/cally-text.h +++ b/clutter/clutter/cally/cally-text.h @@ -74,9 +74,9 @@ struct _CallyTextClass gpointer _padding_dummy[8]; }; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT GType cally_text_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT AtkObject* cally_text_new (ClutterActor *actor); G_END_DECLS diff --git a/clutter/clutter/cally/cally-texture.c b/clutter/clutter/cally/cally-texture.c deleted file mode 100644 index e7df6190d..000000000 --- a/clutter/clutter/cally/cally-texture.c +++ /dev/null @@ -1,98 +0,0 @@ -/* CALLY - The Clutter Accessibility Implementation Library - * - * Copyright (C) 2009 Igalia, S.L. - * - * Author: Alejandro Piñeiro Iglesias - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/** - * SECTION:cally-texture - * @Title: CallyTexture - * @short_description: Implementation of the ATK interfaces for a #ClutterTexture - * @see_also: #ClutterTexture - * - * #CallyTexture implements the required ATK interfaces of #ClutterTexture - * - * In particular it sets a proper role for the texture. - */ -#include "clutter-build-config.h" - -#define CLUTTER_DISABLE_DEPRECATION_WARNINGS - -#include "cally-texture.h" -#include "cally-actor-private.h" - -#include "deprecated/clutter-texture.h" - -/* AtkObject */ -static void cally_texture_real_initialize (AtkObject *obj, - gpointer data); - -G_DEFINE_TYPE (CallyTexture, cally_texture, CALLY_TYPE_ACTOR) - -static void -cally_texture_class_init (CallyTextureClass *klass) -{ -/* GObjectClass *gobject_class = G_OBJECT_CLASS (klass); */ - AtkObjectClass *class = ATK_OBJECT_CLASS (klass); - - class->initialize = cally_texture_real_initialize; -} - -static void -cally_texture_init (CallyTexture *texture) -{ - /* nothing to do yet */ -} - -/** - * cally_texture_new: - * @actor: a #ClutterActor - * - * Creates a new #CallyTexture for the given @actor. @actor must be - * a #ClutterTexture. - * - * Return value: the newly created #AtkObject - * - * Since: 1.4 - */ -AtkObject* -cally_texture_new (ClutterActor *actor) -{ - GObject *object = NULL; - AtkObject *accessible = NULL; - - g_return_val_if_fail (CLUTTER_IS_TEXTURE (actor), NULL); - - object = g_object_new (CALLY_TYPE_TEXTURE, NULL); - - accessible = ATK_OBJECT (object); - atk_object_initialize (accessible, actor); - - return accessible; -} - -static void -cally_texture_real_initialize (AtkObject *obj, - gpointer data) -{ - ATK_OBJECT_CLASS (cally_texture_parent_class)->initialize (obj, data); - - /* default role */ - obj->role = ATK_ROLE_IMAGE; -} diff --git a/clutter/clutter/cally/cally-texture.h b/clutter/clutter/cally/cally-texture.h deleted file mode 100644 index dad576c14..000000000 --- a/clutter/clutter/cally/cally-texture.h +++ /dev/null @@ -1,84 +0,0 @@ -/* CALLY - The Clutter Accessibility Implementation Library - * - * Copyright (C) 2009 Igalia, S.L. - * - * Author: Alejandro Piñeiro Iglesias - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#ifndef __CALLY_TEXTURE_H__ -#define __CALLY_TEXTURE_H__ - -#if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include -#include - -G_BEGIN_DECLS - -#define CALLY_TYPE_TEXTURE (cally_texture_get_type ()) -#define CALLY_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALLY_TYPE_TEXTURE, CallyTexture)) -#define CALLY_TEXTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CALLY_TYPE_TEXTURE, CallyTextureClass)) -#define CALLY_IS_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALLY_TYPE_TEXTURE)) -#define CALLY_IS_TEXTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CALLY_TYPE_TEXTURE)) -#define CALLY_TEXTURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CALLY_TYPE_TEXTURE, CallyTextureClass)) - -typedef struct _CallyTexture CallyTexture; -typedef struct _CallyTextureClass CallyTextureClass; -typedef struct _CallyTexturePrivate CallyTexturePrivate; - -/** - * CallyTexture: - * - * The CallyTexture structure contains only - * private data and should be accessed using the provided API - * - * Since: 1.4 - */ -struct _CallyTexture -{ - /*< private >*/ - CallyActor parent; - - CallyTexturePrivate *priv; -}; - -/** - * CallyTextureClass: - * - * The CallyTextureClass structure contains - * only private data - * - * Since: 1.4 - */ -struct _CallyTextureClass -{ - /*< private >*/ - CallyActorClass parent_class; - - /* padding for future expansion */ - gpointer _padding_dummy[8]; -}; - -CLUTTER_AVAILABLE_IN_1_4 -GType cally_texture_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_4 -AtkObject *cally_texture_new (ClutterActor *actor); - -G_END_DECLS - -#endif /* __CALLY_TEXTURE_H__ */ diff --git a/clutter/clutter/cally/cally-util.c b/clutter/clutter/cally/cally-util.c index 783c7dc12..ebb69f8ee 100644 --- a/clutter/clutter/cally/cally-util.c +++ b/clutter/clutter/cally/cally-util.c @@ -38,9 +38,7 @@ * available any accessible object. */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include #include @@ -144,7 +142,7 @@ cally_util_get_toolkit_name (void) static const gchar * cally_util_get_toolkit_version (void) { - return CLUTTER_VERSION_S; + return MUTTER_VERSION; } static guint @@ -156,7 +154,7 @@ cally_util_add_key_event_listener (AtkKeySnoopFunc listener, if (!key_listener_list) { - key_listener_list = g_hash_table_new_full (NULL, NULL, NULL, free); + key_listener_list = g_hash_table_new_full (NULL, NULL, NULL, g_free); cally_util_simulate_snooper_install (); } @@ -414,8 +412,8 @@ cally_key_snooper (ClutterActor *actor, consumed = g_hash_table_foreach_steal (new_hash, notify_hf, key_event); g_hash_table_destroy (new_hash); - free (key_event->string); - free (key_event); + g_free (key_event->string); + g_free (key_event); } return (consumed ? 1 : 0); diff --git a/clutter/clutter/cally/cally-util.h b/clutter/clutter/cally/cally-util.h index 76f36be7e..dcc5deb1d 100644 --- a/clutter/clutter/cally/cally-util.h +++ b/clutter/clutter/cally/cally-util.h @@ -74,7 +74,7 @@ struct _CallyUtilClass gpointer _padding_dummy[8]; }; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT GType cally_util_get_type (void) G_GNUC_CONST; void _cally_util_override_atk_util (void); diff --git a/clutter/clutter/cally/cally.c b/clutter/clutter/cally/cally.c index 8cee69a93..8b92682db 100644 --- a/clutter/clutter/cally/cally.c +++ b/clutter/clutter/cally/cally.c @@ -29,9 +29,7 @@ * */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #define CLUTTER_DISABLE_DEPRECATION_WARNINGS @@ -41,7 +39,6 @@ #include "cally-group.h" #include "cally-stage.h" #include "cally-text.h" -#include "cally-texture.h" #include "cally-rectangle.h" #include "cally-clone.h" @@ -58,7 +55,6 @@ CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_ACTOR, cally_actor, cally_actor_new) CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_GROUP, cally_group, cally_group_new) CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_STAGE, cally_stage, cally_stage_new) CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_TEXT, cally_text, cally_text_new) -CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_TEXTURE, cally_texture, cally_texture_new) CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_RECTANGLE, cally_rectangle, cally_rectangle_new) CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_CLONE, cally_clone, cally_clone_new) @@ -80,7 +76,6 @@ cally_accessibility_init (void) CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_GROUP, cally_group); CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_STAGE, cally_stage); CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_TEXT, cally_text); - CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_TEXTURE, cally_texture); CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_RECTANGLE, cally_rectangle); CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_CLONE, cally_clone); diff --git a/clutter/clutter/cally/cally.h b/clutter/clutter/cally/cally.h index 11fa9fc6c..440c30be3 100644 --- a/clutter/clutter/cally/cally.h +++ b/clutter/clutter/cally/cally.h @@ -32,7 +32,6 @@ #include "cally-root.h" #include "cally-stage.h" #include "cally-text.h" -#include "cally-texture.h" #include "cally-util.h" #undef __CALLY_H_INSIDE__ diff --git a/clutter/clutter/clutter-action.c b/clutter/clutter/clutter-action.c index 020b37f27..a3410f184 100644 --- a/clutter/clutter/clutter-action.c +++ b/clutter/clutter/clutter-action.c @@ -41,9 +41,7 @@ * #ClutterAction is available since Clutter 1.4 */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include "clutter-action.h" diff --git a/clutter/clutter/clutter-action.h b/clutter/clutter/clutter-action.h index fe9f19fbe..8a7f14abc 100644 --- a/clutter/clutter/clutter-action.h +++ b/clutter/clutter/clutter-action.h @@ -78,32 +78,32 @@ struct _ClutterActionClass void (* _clutter_action8) (void); }; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT GType clutter_action_get_type (void) G_GNUC_CONST; /* ClutterActor API */ -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_actor_add_action (ClutterActor *self, ClutterAction *action); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_actor_add_action_with_name (ClutterActor *self, const gchar *name, ClutterAction *action); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_actor_remove_action (ClutterActor *self, ClutterAction *action); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_actor_remove_action_by_name (ClutterActor *self, const gchar *name); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT ClutterAction *clutter_actor_get_action (ClutterActor *self, const gchar *name); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT GList * clutter_actor_get_actions (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_actor_clear_actions (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT gboolean clutter_actor_has_actions (ClutterActor *self); G_END_DECLS diff --git a/clutter/clutter/clutter-actor-box.c b/clutter/clutter/clutter-actor-box.c index 319eec3a9..a2308ac31 100644 --- a/clutter/clutter/clutter-actor-box.c +++ b/clutter/clutter/clutter-actor-box.c @@ -1,6 +1,4 @@ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include @@ -342,7 +340,7 @@ clutter_actor_box_contains (const ClutterActorBox *box, /** * clutter_actor_box_from_vertices: * @box: a #ClutterActorBox - * @verts: (array fixed-size=4): array of four #ClutterVertex + * @verts: (array fixed-size=4): array of four #graphene_point3d_t * * Calculates the bounding box represented by the four vertices; for details * of the vertex array see clutter_actor_get_abs_allocation_vertices(). @@ -350,8 +348,8 @@ clutter_actor_box_contains (const ClutterActorBox *box, * Since: 1.0 */ void -clutter_actor_box_from_vertices (ClutterActorBox *box, - const ClutterVertex verts[]) +clutter_actor_box_from_vertices (ClutterActorBox *box, + const graphene_point3d_t verts[]) { gfloat x_1, x_2, y_1, y_2; @@ -596,6 +594,27 @@ _clutter_actor_box_enlarge_for_effects (ClutterActorBox *box) box->y1 = box->y2 - height - 3; } +/** + * clutter_actor_box_scale: + * @box: a #ClutterActorBox + * @scale: scale factor for resizing this box + * + * Rescale the @box by provided @scale factor. + * + * Since: 1.6 + */ +void +clutter_actor_box_scale (ClutterActorBox *box, + gfloat scale) +{ + g_return_if_fail (box != NULL); + + box->x1 *= scale; + box->x2 *= scale; + box->y1 *= scale; + box->y2 *= scale; +} + G_DEFINE_BOXED_TYPE_WITH_CODE (ClutterActorBox, clutter_actor_box, clutter_actor_box_copy, clutter_actor_box_free, diff --git a/clutter/clutter/clutter-actor-meta.c b/clutter/clutter/clutter-actor-meta.c index 594de9a99..eba098584 100644 --- a/clutter/clutter/clutter-actor-meta.c +++ b/clutter/clutter/clutter-actor-meta.c @@ -41,9 +41,7 @@ * #ClutterActorMeta is available since Clutter 1.4 */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include "clutter-actor-meta-private.h" @@ -53,7 +51,7 @@ struct _ClutterActorMetaPrivate { ClutterActor *actor; - guint destroy_id; + gulong destroy_id; gchar *name; @@ -93,11 +91,7 @@ clutter_actor_meta_real_set_actor (ClutterActorMeta *meta, if (meta->priv->actor == actor) return; - if (meta->priv->destroy_id != 0) - { - g_signal_handler_disconnect (meta->priv->actor, meta->priv->destroy_id); - meta->priv->destroy_id = 0; - } + g_clear_signal_handler (&meta->priv->destroy_id, meta->priv->actor); meta->priv->actor = actor; @@ -164,10 +158,10 @@ clutter_actor_meta_finalize (GObject *gobject) { ClutterActorMetaPrivate *priv = CLUTTER_ACTOR_META (gobject)->priv; - if (priv->destroy_id != 0 && priv->actor != NULL) - g_signal_handler_disconnect (priv->actor, priv->destroy_id); + if (priv->actor != NULL) + g_clear_signal_handler (&priv->destroy_id, priv->actor); - free (priv->name); + g_free (priv->name); G_OBJECT_CLASS (clutter_actor_meta_parent_class)->finalize (gobject); } @@ -257,7 +251,7 @@ clutter_actor_meta_set_name (ClutterActorMeta *meta, if (g_strcmp0 (meta->priv->name, name) == 0) return; - free (meta->priv->name); + g_free (meta->priv->name); meta->priv->name = g_strdup (name); g_object_notify_by_pspec (G_OBJECT (meta), obj_props[PROP_NAME]); @@ -579,8 +573,7 @@ _clutter_meta_group_clear_metas (ClutterMetaGroup *group) { g_list_foreach (group->meta, (GFunc) _clutter_actor_meta_set_actor, NULL); - g_list_foreach (group->meta, (GFunc) g_object_unref, NULL); - g_list_free (group->meta); + g_list_free_full (group->meta, g_object_unref); group->meta = NULL; } diff --git a/clutter/clutter/clutter-actor-meta.h b/clutter/clutter/clutter-actor-meta.h index e954f36d4..ecc9523a9 100644 --- a/clutter/clutter/clutter-actor-meta.h +++ b/clutter/clutter/clutter-actor-meta.h @@ -97,21 +97,21 @@ struct _ClutterActorMetaClass void (* _clutter_meta7) (void); }; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT GType clutter_actor_meta_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_actor_meta_set_name (ClutterActorMeta *meta, const gchar *name); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT const gchar * clutter_actor_meta_get_name (ClutterActorMeta *meta); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_actor_meta_set_enabled (ClutterActorMeta *meta, gboolean is_enabled); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT gboolean clutter_actor_meta_get_enabled (ClutterActorMeta *meta); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT ClutterActor * clutter_actor_meta_get_actor (ClutterActorMeta *meta); G_END_DECLS diff --git a/clutter/clutter/clutter-actor-private.h b/clutter/clutter/clutter-actor-private.h index 4dc767b54..9ff4b2d4b 100644 --- a/clutter/clutter/clutter-actor-private.h +++ b/clutter/clutter/clutter-actor-private.h @@ -53,7 +53,8 @@ typedef enum * Controls some options for how clutter_actor_traverse() iterates * through the graph. */ -typedef enum { +typedef enum +{ CLUTTER_ACTOR_TRAVERSE_DEPTH_FIRST = 1L<<0, CLUTTER_ACTOR_TRAVERSE_BREADTH_FIRST = 1L<<1 } ClutterActorTraverseFlags; @@ -74,7 +75,8 @@ typedef enum { * the continuing traversal. It may stop traversal completely, just * skip over children for the current actor or continue as normal. */ -typedef enum { +typedef enum +{ CLUTTER_ACTOR_TRAVERSE_VISIT_CONTINUE = 1L<<0, CLUTTER_ACTOR_TRAVERSE_VISIT_SKIP_CHILDREN = 1L<<1, CLUTTER_ACTOR_TRAVERSE_VISIT_BREAK = 1L<<2 @@ -133,7 +135,7 @@ struct _AnchorCoord } fraction; /* Use when is_fractional == FALSE */ - ClutterVertex units; + graphene_point3d_t units; } v; }; @@ -161,7 +163,7 @@ struct _SizeRequest struct _ClutterLayoutInfo { /* fixed position coordinates */ - ClutterPoint fixed_pos; + graphene_point_t fixed_pos; ClutterMargin margin; @@ -171,8 +173,8 @@ struct _ClutterLayoutInfo guint x_expand : 1; guint y_expand : 1; - ClutterSize minimum; - ClutterSize natural; + graphene_size_t minimum; + graphene_size_t natural; }; const ClutterLayoutInfo * _clutter_actor_get_layout_info_or_defaults (ClutterActor *self); @@ -201,13 +203,13 @@ struct _ClutterTransformInfo AnchorCoord anchor; /* translation */ - ClutterVertex translation; + graphene_point3d_t translation; /* z_position */ gfloat z_position; /* transformation center */ - ClutterPoint pivot; + graphene_point_t pivot; gfloat pivot_z; CoglMatrix transform; @@ -240,9 +242,6 @@ ClutterAnimationInfo * _clutter_actor_get_animation_info ClutterTransition * _clutter_actor_create_transition (ClutterActor *self, GParamSpec *pspec, ...); -ClutterTransition * _clutter_actor_get_transition (ClutterActor *self, - GParamSpec *pspec); - gboolean _clutter_actor_foreach_child (ClutterActor *self, ClutterForeachCallback callback, gpointer user_data); @@ -275,17 +274,17 @@ void _clutter_actor_set_enable_paint_unmapped void _clutter_actor_set_has_pointer (ClutterActor *self, gboolean has_pointer); -void _clutter_actor_queue_redraw_with_clip (ClutterActor *self, - ClutterRedrawFlags flags, - ClutterPaintVolume *clip_volume); -void _clutter_actor_queue_redraw_full (ClutterActor *self, - ClutterRedrawFlags flags, - ClutterPaintVolume *volume, - ClutterEffect *effect); - -ClutterPaintVolume * _clutter_actor_get_queue_redraw_clip (ClutterActor *self); -void _clutter_actor_set_queue_redraw_clip (ClutterActor *self, - ClutterPaintVolume *clip_volume); +void _clutter_actor_set_has_key_focus (ClutterActor *self, + gboolean has_key_focus); + +void _clutter_actor_queue_redraw_with_clip (ClutterActor *self, + ClutterRedrawFlags flags, + const ClutterPaintVolume *clip_volume); +void _clutter_actor_queue_redraw_full (ClutterActor *self, + ClutterRedrawFlags flags, + const ClutterPaintVolume *volume, + ClutterEffect *effect); + void _clutter_actor_finish_queue_redraw (ClutterActor *self, ClutterPaintVolume *clip); @@ -298,8 +297,6 @@ const gchar * _clutter_actor_get_debug_name void _clutter_actor_push_clone_paint (void); void _clutter_actor_pop_clone_paint (void); -guint32 _clutter_actor_get_pick_id (ClutterActor *self); - void _clutter_actor_shader_pre_paint (ClutterActor *actor, gboolean repeat); void _clutter_actor_shader_post_paint (ClutterActor *actor); @@ -316,8 +313,10 @@ void _clutter_actor_detach_clone void _clutter_actor_queue_redraw_on_clones (ClutterActor *actor); void _clutter_actor_queue_relayout_on_clones (ClutterActor *actor); void _clutter_actor_queue_only_relayout (ClutterActor *actor); +void _clutter_actor_queue_update_resource_scale_recursive (ClutterActor *actor); -CoglFramebuffer * _clutter_actor_get_active_framebuffer (ClutterActor *actor); +gboolean _clutter_actor_get_real_resource_scale (ClutterActor *actor, + float *resource_scale); ClutterPaintNode * clutter_actor_create_texture_paint_node (ClutterActor *self, CoglTexture *texture); diff --git a/clutter/clutter/clutter-actor.c b/clutter/clutter/clutter-actor.c index 24de2fcb2..a67c35f85 100644 --- a/clutter/clutter/clutter-actor.c +++ b/clutter/clutter/clutter-actor.c @@ -24,7 +24,7 @@ /** * SECTION:clutter-actor - * @short_description: The basic element of the scene graph + * @short_description: The basic element of the scene graph * * The ClutterActor class is the basic element of the scene graph in Clutter, * and it encapsulates the position, size, and transformations of a node in @@ -433,7 +433,7 @@ * * #ClutterActor allows accessing properties of #ClutterAction, * #ClutterEffect, and #ClutterConstraint instances associated to an actor - * instance for animation purposes. + * instance for animation purposes, as well as its #ClutterLayoutManager. * * In order to access a specific #ClutterAction or a #ClutterConstraint * property it is necessary to set the #ClutterActorMeta:name property on the @@ -457,6 +457,13 @@ * on the `origin` actor, and in its initial state is overlapping the actor * to which is bound to. * + * As the actor has only one #ClutterLayoutManager, the syntax for accessing its + * properties is simpler: + * + * |[ + * @layout. + * ]| + * * |[ * constraint = clutter_bind_constraint_new (origin, CLUTTER_BIND_X, 0.0); * clutter_actor_meta_set_name (CLUTTER_ACTOR_META (constraint), "bind-x"); @@ -624,7 +631,7 @@ #include "clutter-color-static.h" #include "clutter-color.h" #include "clutter-constraint-private.h" -#include "clutter-container.h" +#include "clutter-container-private.h" #include "clutter-content-private.h" #include "clutter-debug.h" #include "clutter-easing.h" @@ -635,6 +642,8 @@ #include "clutter-interval.h" #include "clutter-main.h" #include "clutter-marshal.h" +#include "clutter-mutter.h" +#include "clutter-paint-context-private.h" #include "clutter-paint-nodes.h" #include "clutter-paint-node-private.h" #include "clutter-paint-volume-private.h" @@ -648,14 +657,14 @@ #include "clutter-units.h" #include "deprecated/clutter-actor.h" -#include "deprecated/clutter-behaviour.h" #include "deprecated/clutter-container.h" /* Internal enum used to control mapped state update. This is a hint * which indicates when to do something other than just enforce * invariants. */ -typedef enum { +typedef enum +{ MAP_STATE_CHECK, /* just enforce invariants. */ MAP_STATE_MAKE_UNREALIZED, /* force unrealize, ignoring invariants, * used when about to unparent. @@ -692,13 +701,16 @@ struct _ClutterActorPrivate ClutterAllocationFlags allocation_flags; /* clip, in actor coordinates */ - ClutterRect clip; + graphene_rect_t clip; /* the cached transformation matrix; see apply_transform() */ CoglMatrix transform; + float resource_scale; + guint8 opacity; gint opacity_override; + unsigned int inhibit_culling_counter; ClutterOffscreenRedirect offscreen_redirect; @@ -725,8 +737,6 @@ struct _ClutterActorPrivate gchar *name; /* a non-unique name, used for debugging */ - gint32 pick_id; /* per-stage unique id, used for picking */ - /* a back-pointer to the Pango context that we can use * to create pre-configured PangoLayout */ @@ -737,9 +747,6 @@ struct _ClutterActorPrivate */ ClutterTextDirection text_direction; - /* a counter used to toggle the CLUTTER_INTERNAL_CHILD flag */ - gint internal_child; - /* meta classes */ ClutterMetaGroup *actions; ClutterMetaGroup *constraints; @@ -803,6 +810,9 @@ struct _ClutterActorPrivate gpointer create_child_data; GDestroyNotify create_child_notify; + gulong resolution_changed_id; + gulong font_changed_id; + /* bitfields: KEEP AT THE END */ /* fixed position and sizes */ @@ -823,6 +833,7 @@ struct _ClutterActorPrivate guint enable_model_view_transform : 1; guint enable_paint_unmapped : 1; guint has_pointer : 1; + guint has_key_focus : 1; guint propagated_one_redraw : 1; guint paint_volume_valid : 1; guint last_paint_volume_valid : 1; @@ -841,6 +852,8 @@ struct _ClutterActorPrivate guint needs_x_expand : 1; guint needs_y_expand : 1; guint needs_paint_volume_update : 1; + guint had_effects_on_last_paint_volume_update : 1; + guint needs_compute_resource_scale : 1; }; enum @@ -890,7 +903,6 @@ enum PROP_DEPTH, /* XXX:2.0 remove */ PROP_Z_POSITION, - PROP_CLIP, /* XXX:2.0 remove */ PROP_CLIP_RECT, PROP_HAS_CLIP, PROP_CLIP_TO_ALLOCATION, @@ -913,6 +925,7 @@ enum PROP_SCALE_CENTER_X, /* XXX:2.0 remove */ PROP_SCALE_CENTER_Y, /* XXX:2.0 remove */ PROP_SCALE_GRAVITY, /* XXX:2.0 remove */ + PROP_RESOURCE_SCALE, PROP_ROTATION_ANGLE_X, /* XXX:2.0 rename to rotation-x */ PROP_ROTATION_ANGLE_Y, /* XXX:2.0 rename to rotation-y */ @@ -1016,12 +1029,11 @@ typedef struct _TransitionClosure ClutterTransition *transition; gchar *name; gulong completed_id; - guint is_implicit : 1; } TransitionClosure; static void clutter_container_iface_init (ClutterContainerIface *iface); static void clutter_scriptable_iface_init (ClutterScriptableIface *iface); -static void clutter_animatable_iface_init (ClutterAnimatableIface *iface); +static void clutter_animatable_iface_init (ClutterAnimatableInterface *iface); static void atk_implementor_iface_init (AtkImplementorIface *iface); /* These setters are all static for now, maybe they should be in the @@ -1092,6 +1104,13 @@ static void clutter_actor_set_child_transform_internal (ClutterActor *sel static void clutter_actor_realize_internal (ClutterActor *self); static void clutter_actor_unrealize_internal (ClutterActor *self); +static gboolean clutter_actor_update_resource_scale (ClutterActor *self); +static void clutter_actor_ensure_resource_scale (ClutterActor *self); + +static void clutter_actor_push_in_cloned_branch (ClutterActor *self, + gulong count); +static void clutter_actor_pop_in_cloned_branch (ClutterActor *self, + gulong count); /* Helper macro which translates by the anchor coord, applies the given transformation and then translates back */ @@ -1102,11 +1121,25 @@ static void clutter_actor_unrealize_internal (ClutterActor *self); { _transform; } \ cogl_matrix_translate ((m), -_tx, -_ty, -_tz); } G_STMT_END -static GQuark quark_shader_data = 0; static GQuark quark_actor_layout_info = 0; static GQuark quark_actor_transform_info = 0; static GQuark quark_actor_animation_info = 0; +static GQuark quark_key = 0; +static GQuark quark_motion = 0; +static GQuark quark_pointer_focus = 0; +static GQuark quark_button = 0; +static GQuark quark_scroll = 0; +static GQuark quark_stage = 0; +static GQuark quark_destroy = 0; +static GQuark quark_client = 0; +static GQuark quark_delete = 0; +static GQuark quark_touch = 0; +static GQuark quark_touchpad = 0; +static GQuark quark_proximity = 0; +static GQuark quark_pad = 0; +static GQuark quark_im = 0; + G_DEFINE_TYPE_WITH_CODE (ClutterActor, clutter_actor, G_TYPE_INITIALLY_UNOWNED, @@ -1267,6 +1300,112 @@ clutter_actor_verify_map_state (ClutterActor *self) #endif /* CLUTTER_ENABLE_DEBUG */ +static gboolean +_clutter_actor_transform_local_box_to_stage (ClutterActor *self, + ClutterStage *stage, + ClutterPickContext *pick_context, + const ClutterActorBox *box, + graphene_point_t vertices[4]) +{ + CoglFramebuffer *fb = + clutter_pick_context_get_framebuffer (pick_context); + CoglMatrix stage_transform, inv_stage_transform; + CoglMatrix modelview, transform_to_stage; + int v; + + clutter_actor_get_transform (CLUTTER_ACTOR (stage), &stage_transform); + if (!cogl_matrix_get_inverse (&stage_transform, &inv_stage_transform)) + return FALSE; + cogl_framebuffer_get_modelview_matrix (fb, &modelview); + cogl_matrix_multiply (&transform_to_stage, &inv_stage_transform, &modelview); + + vertices[0].x = box->x1; + vertices[0].y = box->y1; + + vertices[1].x = box->x2; + vertices[1].y = box->y1; + + vertices[2].x = box->x2; + vertices[2].y = box->y2; + + vertices[3].x = box->x1; + vertices[3].y = box->y2; + + for (v = 0; v < 4; v++) + { + float z = 0.f; + float w = 1.f; + + cogl_matrix_transform_point (&transform_to_stage, + &vertices[v].x, + &vertices[v].y, + &z, + &w); + } + + return TRUE; +} + +/** + * clutter_actor_pick_box: + * @self: The #ClutterActor being "pick" painted. + * @pick_context: The #ClutterPickContext + * @box: A rectangle in the actor's own local coordinates. + * + * Logs (does a virtual paint of) a rectangle for picking. Note that @box is + * in the actor's own local coordinates, so is usually {0,0,width,height} + * to include the whole actor. That is unless the actor has a shaped input + * region in which case you may wish to log the (multiple) smaller rectangles + * that make up the input region. + */ +void +clutter_actor_pick_box (ClutterActor *self, + ClutterPickContext *pick_context, + const ClutterActorBox *box) +{ + ClutterStage *stage; + graphene_point_t vertices[4]; + + g_return_if_fail (CLUTTER_IS_ACTOR (self)); + g_return_if_fail (box != NULL); + + if (box->x1 >= box->x2 || box->y1 >= box->y2) + return; + + stage = CLUTTER_STAGE (_clutter_actor_get_stage_internal (self)); + + if (_clutter_actor_transform_local_box_to_stage (self, stage, pick_context, + box, vertices)) + clutter_stage_log_pick (stage, vertices, self); +} + +static gboolean +_clutter_actor_push_pick_clip (ClutterActor *self, + ClutterPickContext *pick_context, + const ClutterActorBox *clip) +{ + ClutterStage *stage; + graphene_point_t vertices[4]; + + stage = CLUTTER_STAGE (_clutter_actor_get_stage_internal (self)); + + if (!_clutter_actor_transform_local_box_to_stage (self, stage, pick_context, + clip, vertices)) + return FALSE; + + clutter_stage_push_pick_clip (stage, vertices); + return TRUE; +} + +static void +_clutter_actor_pop_pick_clip (ClutterActor *self) +{ + ClutterActor *stage; + + stage = _clutter_actor_get_stage_internal (self); + clutter_stage_pop_pick_clip (CLUTTER_STAGE (stage)); +} + static void clutter_actor_set_mapped (ClutterActor *self, gboolean mapped) @@ -1495,8 +1634,7 @@ clutter_actor_update_map_state (ClutterActor *self, static void clutter_actor_real_map (ClutterActor *self) { - ClutterActorPrivate *priv = self->priv; - ClutterActor *stage, *iter; + ClutterActor *iter; g_assert (!CLUTTER_ACTOR_IS_MAPPED (self)); @@ -1507,12 +1645,7 @@ clutter_actor_real_map (ClutterActor *self) self->priv->needs_paint_volume_update = TRUE; - stage = _clutter_actor_get_stage_internal (self); - priv->pick_id = _clutter_stage_acquire_pick_id (CLUTTER_STAGE (stage), self); - - CLUTTER_NOTE (ACTOR, "Pick id '%d' for actor '%s'", - priv->pick_id, - _clutter_actor_get_debug_name (self)); + clutter_actor_ensure_resource_scale (self); /* notify on parent mapped before potentially mapping * children, so apps see a top-down notification. @@ -1578,6 +1711,20 @@ clutter_actor_is_mapped (ClutterActor *self) return CLUTTER_ACTOR_IS_MAPPED (self); } +static void +maybe_unset_key_focus (ClutterActor *self) +{ + ClutterActor *stage; + + if (!self->priv->has_key_focus) + return; + + stage = _clutter_actor_get_stage_internal (self); + + if (stage) + clutter_stage_set_key_focus (CLUTTER_STAGE (stage), NULL); +} + static void clutter_actor_real_unmap (ClutterActor *self) { @@ -1611,22 +1758,7 @@ clutter_actor_real_unmap (ClutterActor *self) /* relinquish keyboard focus if we were unmapped while owning it */ if (!CLUTTER_ACTOR_IS_TOPLEVEL (self)) - { - ClutterStage *stage; - - stage = CLUTTER_STAGE (_clutter_actor_get_stage_internal (self)); - - if (stage != NULL) - _clutter_stage_release_pick_id (stage, priv->pick_id); - - priv->pick_id = -1; - - if (stage != NULL && - clutter_stage_get_key_focus (stage) == self) - { - clutter_stage_set_key_focus (stage, NULL); - } - } + maybe_unset_key_focus (self); } /** @@ -1662,6 +1794,15 @@ clutter_actor_unmap (ClutterActor *self) clutter_actor_update_map_state (self, MAP_STATE_MAKE_UNMAPPED); } +static void +clutter_actor_queue_shallow_relayout (ClutterActor *self) +{ + ClutterActor *stage = _clutter_actor_get_stage_internal (self); + + if (stage != NULL) + clutter_stage_queue_actor_relayout (CLUTTER_STAGE (stage), self); +} + static void clutter_actor_real_show (ClutterActor *self) { @@ -1695,6 +1836,11 @@ clutter_actor_real_show (ClutterActor *self) clutter_actor_queue_relayout (self); } + else /* but still don't leave the actor un-allocated before showing it */ + { + clutter_actor_queue_shallow_relayout (self); + clutter_actor_queue_redraw (self); + } } static inline void @@ -1716,6 +1862,22 @@ set_show_on_set_parent (ClutterActor *self, } } +static void +clutter_actor_queue_redraw_on_parent (ClutterActor *self) +{ + const ClutterPaintVolume *pv; + + if (!self->priv->parent) + return; + + /* A relayout/redraw is underway */ + if (self->priv->needs_allocation) + return; + + pv = clutter_actor_get_transformed_paint_volume (self, self->priv->parent); + _clutter_actor_queue_redraw_with_clip (self->priv->parent, 0, pv); +} + /** * clutter_actor_show: * @self: A #ClutterActor @@ -1771,7 +1933,7 @@ clutter_actor_show (ClutterActor *self) g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_VISIBLE]); if (priv->parent != NULL) - clutter_actor_queue_redraw (priv->parent); + clutter_actor_queue_redraw (self); g_object_thaw_notify (G_OBJECT (self)); } @@ -1896,35 +2058,14 @@ clutter_actor_hide (ClutterActor *self) g_signal_emit (self, actor_signals[HIDE], 0); g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_VISIBLE]); - if (priv->parent != NULL) + if (priv->parent != NULL && priv->needs_allocation) clutter_actor_queue_redraw (priv->parent); + else + clutter_actor_queue_redraw_on_parent (self); g_object_thaw_notify (G_OBJECT (self)); } -/** - * clutter_actor_hide_all: - * @self: a #ClutterActor - * - * Calls clutter_actor_hide() on all child actors (if any). - * - * Since: 0.2 - * - * Deprecated: 1.10: Using clutter_actor_hide() on the actor will - * prevent its children from being painted as well. - */ -void -clutter_actor_hide_all (ClutterActor *self) -{ - ClutterActorClass *klass; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - klass = CLUTTER_ACTOR_GET_CLASS (self); - if (klass->hide_all) - klass->hide_all (self); -} - /** * clutter_actor_realize: * @self: A #ClutterActor @@ -2219,27 +2360,18 @@ _clutter_actor_rerealize (ClutterActor *self, static void clutter_actor_real_pick (ClutterActor *self, - const ClutterColor *color) + ClutterPickContext *pick_context) { - /* the default implementation is just to paint a rectangle - * with the same size of the actor using the passed color - */ if (clutter_actor_should_pick_paint (self)) { - ClutterActorBox box = { 0, }; - float width, height; + ClutterActorBox box = { + .x1 = 0, + .y1 = 0, + .x2 = clutter_actor_get_width (self), + .y2 = clutter_actor_get_height (self), + }; - clutter_actor_get_allocation_box (self, &box); - - width = box.x2 - box.x1; - height = box.y2 - box.y1; - - cogl_set_source_color4ub (color->red, - color->green, - color->blue, - color->alpha); - - cogl_rectangle (0, 0, width, height); + clutter_actor_pick_box (self, pick_context, &box); } /* XXX - this thoroughly sucks, but we need to maintain compatibility @@ -2256,7 +2388,7 @@ clutter_actor_real_pick (ClutterActor *self, for (iter = self->priv->first_child; iter != NULL; iter = iter->priv->next_sibling) - clutter_actor_paint (iter); + clutter_actor_pick (iter, pick_context); } } @@ -2279,6 +2411,7 @@ clutter_actor_should_pick_paint (ClutterActor *self) g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); if (CLUTTER_ACTOR_IS_MAPPED (self) && + clutter_actor_has_allocation (self) && (_clutter_context_get_pick_mode () == CLUTTER_PICK_ALL || CLUTTER_ACTOR_IS_REACTIVE (self))) return TRUE; @@ -2472,6 +2605,9 @@ clutter_actor_set_allocation_internal (ClutterActor *self, gboolean retval; ClutterActorBox old_alloc = { 0, }; + g_return_val_if_fail (!isnan (box->x1) && !isnan (box->x2) && + !isnan (box->y1) && !isnan (box->y2), FALSE); + obj = G_OBJECT (self); g_object_freeze_notify (obj); @@ -2644,9 +2780,12 @@ clutter_actor_real_allocate (ClutterActor *self, } static void -_clutter_actor_signal_queue_redraw (ClutterActor *self, - ClutterActor *origin) +_clutter_actor_propagate_queue_redraw (ClutterActor *self, + ClutterActor *origin, + ClutterPaintVolume *pv) { + gboolean stop = FALSE; + /* no point in queuing a redraw on a destroyed actor */ if (CLUTTER_ACTOR_IN_DESTRUCTION (self)) return; @@ -2655,27 +2794,33 @@ _clutter_actor_signal_queue_redraw (ClutterActor *self, * the actor bas been cloned. In this case the clone will need to * receive the signal so it can queue its own redraw. */ + while (self) + { + _clutter_actor_queue_redraw_on_clones (self); - _clutter_actor_queue_redraw_on_clones (self); - - /* calls klass->queue_redraw in default handler */ - if (g_signal_has_handler_pending (self, actor_signals[QUEUE_REDRAW], + /* calls klass->queue_redraw in default handler */ + if (g_signal_has_handler_pending (self, actor_signals[QUEUE_REDRAW], 0, TRUE)) - { - g_signal_emit (self, actor_signals[QUEUE_REDRAW], 0, origin); - } - else - { - CLUTTER_ACTOR_GET_CLASS (self)->queue_redraw (self, origin); + { + g_signal_emit (self, actor_signals[QUEUE_REDRAW], 0, origin, pv, &stop); + } + else + { + stop = CLUTTER_ACTOR_GET_CLASS (self)->queue_redraw (self, origin, pv); + } + + if (stop) + break; + + self = clutter_actor_get_parent (self); } } -static void -clutter_actor_real_queue_redraw (ClutterActor *self, - ClutterActor *origin) +static gboolean +clutter_actor_real_queue_redraw (ClutterActor *self, + ClutterActor *origin, + ClutterPaintVolume *paint_volume) { - ClutterActor *parent; - CLUTTER_NOTE (PAINT, "Redraw queued on '%s' (from: '%s')", _clutter_actor_get_debug_name (self), origin != NULL ? _clutter_actor_get_debug_name (origin) @@ -2683,7 +2828,7 @@ clutter_actor_real_queue_redraw (ClutterActor *self, /* no point in queuing a redraw on a destroyed actor */ if (CLUTTER_ACTOR_IN_DESTRUCTION (self)) - return; + return TRUE; /* If the queue redraw is coming from a child then the actor has become dirty and any queued effect is no longer valid */ @@ -2698,7 +2843,7 @@ clutter_actor_real_queue_redraw (ClutterActor *self, * won't change so we don't have to propagate up the hierarchy. */ if (!CLUTTER_ACTOR_IS_VISIBLE (self)) - return; + return TRUE; /* Although we could determine here that a full stage redraw * has already been queued and immediately bail out, we actually @@ -2712,7 +2857,7 @@ clutter_actor_real_queue_redraw (ClutterActor *self, ClutterActor *stage = _clutter_actor_get_stage_internal (self); if (stage != NULL && _clutter_stage_has_full_redraw_queued (CLUTTER_STAGE (stage))) - return; + return TRUE; } self->priv->propagated_one_redraw = TRUE; @@ -2720,12 +2865,17 @@ clutter_actor_real_queue_redraw (ClutterActor *self, /* notify parents, if they are all visible eventually we'll * queue redraw on the stage, which queues the redraw idle. */ - parent = clutter_actor_get_parent (self); - if (parent != NULL) - { - /* this will go up recursively */ - _clutter_actor_signal_queue_redraw (parent, origin); - } + return FALSE; +} + +static inline gboolean +clutter_actor_needs_relayout (ClutterActor *self) +{ + ClutterActorPrivate *priv = self->priv; + + return (priv->needs_width_request || + priv->needs_height_request || + priv->needs_allocation); } static void @@ -2748,9 +2898,23 @@ clutter_actor_real_queue_relayout (ClutterActor *self) memset (priv->height_requests, 0, N_CACHED_SIZE_REQUESTS * sizeof (SizeRequest)); - /* We need to go all the way up the hierarchy */ + /* We may need to go all the way up the hierarchy */ if (priv->parent != NULL) - _clutter_actor_queue_only_relayout (priv->parent); + { + if (priv->parent->flags & CLUTTER_ACTOR_NO_LAYOUT) + { + clutter_actor_queue_shallow_relayout (self); + + /* The above might have invalidated the parent's paint volume if self + * has moved or resized. DnD seems to require this... + */ + priv->parent->priv->needs_paint_volume_update = TRUE; + } + else + { + _clutter_actor_queue_only_relayout (priv->parent); + } + } } /** @@ -2758,8 +2922,8 @@ clutter_actor_real_queue_relayout (ClutterActor *self) * @self: A #ClutterActor * @ancestor: (allow-none): A #ClutterActor ancestor, or %NULL to use the * default #ClutterStage - * @point: A point as #ClutterVertex - * @vertex: (out caller-allocates): The translated #ClutterVertex + * @point: A point as #graphene_point3d_t + * @vertex: (out caller-allocates): The translated #graphene_point3d_t * * Transforms @point in coordinates relative to the actor into * ancestor-relative coordinates using the relevant transform @@ -2773,10 +2937,10 @@ clutter_actor_real_queue_relayout (ClutterActor *self) * Since: 0.6 */ void -clutter_actor_apply_relative_transform_to_point (ClutterActor *self, - ClutterActor *ancestor, - const ClutterVertex *point, - ClutterVertex *vertex) +clutter_actor_apply_relative_transform_to_point (ClutterActor *self, + ClutterActor *ancestor, + const graphene_point3d_t *point, + graphene_point3d_t *vertex) { gfloat w; CoglMatrix matrix; @@ -2803,10 +2967,10 @@ clutter_actor_apply_relative_transform_to_point (ClutterActor *self, } static gboolean -_clutter_actor_fully_transform_vertices (ClutterActor *self, - const ClutterVertex *vertices_in, - ClutterVertex *vertices_out, - int n_vertices) +_clutter_actor_fully_transform_vertices (ClutterActor *self, + const graphene_point3d_t *vertices_in, + graphene_point3d_t *vertices_out, + int n_vertices) { ClutterActor *stage; CoglMatrix modelview; @@ -2848,8 +3012,8 @@ _clutter_actor_fully_transform_vertices (ClutterActor *self, /** * clutter_actor_apply_transform_to_point: * @self: A #ClutterActor - * @point: A point as #ClutterVertex - * @vertex: (out caller-allocates): The translated #ClutterVertex + * @point: A point as #graphene_point3d_t + * @vertex: (out caller-allocates): The translated #graphene_point3d_t * * Transforms @point in coordinates relative to the actor * into screen-relative coordinates with the current actor @@ -2858,9 +3022,9 @@ _clutter_actor_fully_transform_vertices (ClutterActor *self, * Since: 0.4 **/ void -clutter_actor_apply_transform_to_point (ClutterActor *self, - const ClutterVertex *point, - ClutterVertex *vertex) +clutter_actor_apply_transform_to_point (ClutterActor *self, + const graphene_point3d_t *point, + graphene_point3d_t *vertex) { g_return_if_fail (point != NULL); g_return_if_fail (vertex != NULL); @@ -2910,10 +3074,10 @@ _clutter_actor_get_relative_transformation_matrix (ClutterActor *self, * transformed vertices to @verts[]. */ static gboolean _clutter_actor_transform_and_project_box (ClutterActor *self, - const ClutterActorBox *box, - ClutterVertex verts[]) + const ClutterActorBox *box, + graphene_point3d_t *verts) { - ClutterVertex box_vertices[4]; + graphene_point3d_t box_vertices[4]; box_vertices[0].x = box->x1; box_vertices[0].y = box->y1; @@ -2937,8 +3101,8 @@ _clutter_actor_transform_and_project_box (ClutterActor *self, * @self: A #ClutterActor * @ancestor: (allow-none): A #ClutterActor to calculate the vertices * against, or %NULL to use the #ClutterStage - * @verts: (out) (array fixed-size=4) (element-type Clutter.Vertex): return - * location for an array of 4 #ClutterVertex in which to store the result + * @verts: (out) (array fixed-size=4): return + * location for an array of 4 #graphene_point3d_t in which to store the result * * Calculates the transformed coordinates of the four corners of the * actor in the plane of @ancestor. The returned vertices relate to @@ -2957,13 +3121,13 @@ _clutter_actor_transform_and_project_box (ClutterActor *self, * Since: 0.6 */ void -clutter_actor_get_allocation_vertices (ClutterActor *self, - ClutterActor *ancestor, - ClutterVertex verts[]) +clutter_actor_get_allocation_vertices (ClutterActor *self, + ClutterActor *ancestor, + graphene_point3d_t *verts) { ClutterActorPrivate *priv; ClutterActorBox box; - ClutterVertex vertices[4]; + graphene_point3d_t vertices[4]; CoglMatrix modelview; g_return_if_fail (CLUTTER_IS_ACTOR (self)); @@ -3015,9 +3179,9 @@ clutter_actor_get_allocation_vertices (ClutterActor *self, cogl_matrix_transform_points (&modelview, 3, - sizeof (ClutterVertex), + sizeof (graphene_point3d_t), vertices, - sizeof (ClutterVertex), + sizeof (graphene_point3d_t), vertices, 4); } @@ -3026,7 +3190,7 @@ clutter_actor_get_allocation_vertices (ClutterActor *self, * clutter_actor_get_abs_allocation_vertices: * @self: A #ClutterActor * @verts: (out) (array fixed-size=4): Pointer to a location of an array - * of 4 #ClutterVertex where to store the result. + * of 4 #graphene_point3d_t where to store the result. * * Calculates the transformed screen coordinates of the four corners of * the actor; the returned vertices relate to the #ClutterActorBox @@ -3040,8 +3204,8 @@ clutter_actor_get_allocation_vertices (ClutterActor *self, * Since: 0.4 */ void -clutter_actor_get_abs_allocation_vertices (ClutterActor *self, - ClutterVertex verts[]) +clutter_actor_get_abs_allocation_vertices (ClutterActor *self, + graphene_point3d_t *verts) { ClutterActorPrivate *priv; ClutterActorBox actor_space_allocation; @@ -3275,20 +3439,20 @@ _clutter_actor_apply_relative_transformation_matrix (ClutterActor *self, } static void -_clutter_actor_draw_paint_volume_full (ClutterActor *self, +_clutter_actor_draw_paint_volume_full (ClutterActor *self, ClutterPaintVolume *pv, - const char *label, - const CoglColor *color) + const char *label, + const ClutterColor *color, + ClutterPaintNode *node) { + g_autoptr (ClutterPaintNode) pipeline_node = NULL; static CoglPipeline *outline = NULL; CoglPrimitive *prim; - ClutterVertex line_ends[12 * 2]; + graphene_point3d_t line_ends[12 * 2]; int n_vertices; CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); - /* XXX: at some point we'll query this from the stage but we can't - * do that until the osx backend uses Cogl natively. */ - CoglFramebuffer *fb = cogl_get_draw_framebuffer (); + CoglColor cogl_color; if (outline == NULL) outline = cogl_pipeline_new (ctx); @@ -3322,29 +3486,50 @@ _clutter_actor_draw_paint_volume_full (ClutterActor *self, n_vertices, (CoglVertexP3 *)line_ends); - cogl_pipeline_set_color (outline, color); - cogl_framebuffer_draw_primitive (fb, outline, prim); + cogl_color_init_from_4ub (&cogl_color, + color->red, + color->green, + color->blue, + color->alpha); + cogl_pipeline_set_color (outline, &cogl_color); + + pipeline_node = clutter_pipeline_node_new (outline); + clutter_paint_node_set_static_name (pipeline_node, + "ClutterActor (paint volume outline)"); + clutter_paint_node_add_primitive (pipeline_node, prim); + clutter_paint_node_add_child (node, pipeline_node); cogl_object_unref (prim); if (label) { + g_autoptr (ClutterPaintNode) text_node = NULL; PangoLayout *layout; + layout = pango_layout_new (clutter_actor_get_pango_context (self)); pango_layout_set_text (layout, label, -1); - cogl_pango_render_layout (layout, - pv->vertices[0].x, - pv->vertices[0].y, - color, - 0); + + text_node = clutter_text_node_new (layout, color); + clutter_paint_node_set_static_name (text_node, + "ClutterActor (paint volume label)"); + clutter_paint_node_add_rectangle (text_node, + &(ClutterActorBox) { + .x1 = pv->vertices[0].x, + .y1 = pv->vertices[0].y, + .x2 = pv->vertices[2].x, + .y2 = pv->vertices[2].y, + }); + clutter_paint_node_add_child (node, text_node); + g_object_unref (layout); } } static void -_clutter_actor_draw_paint_volume (ClutterActor *self) +_clutter_actor_draw_paint_volume (ClutterActor *self, + ClutterPaintNode *node) { ClutterPaintVolume *pv; - CoglColor color; + ClutterColor color; pv = _clutter_actor_get_paint_volume_mutable (self); if (!pv) @@ -3359,62 +3544,80 @@ _clutter_actor_draw_paint_volume (ClutterActor *self) clutter_paint_volume_set_width (&fake_pv, width); clutter_paint_volume_set_height (&fake_pv, height); - cogl_color_init_from_4f (&color, 0, 0, 1, 1); + clutter_color_init (&color, 0, 0, 255, 255); _clutter_actor_draw_paint_volume_full (self, &fake_pv, _clutter_actor_get_debug_name (self), - &color); + &color, + node); clutter_paint_volume_free (&fake_pv); } else { - cogl_color_init_from_4f (&color, 0, 1, 0, 1); + clutter_color_init (&color, 0, 255, 0, 255); _clutter_actor_draw_paint_volume_full (self, pv, _clutter_actor_get_debug_name (self), - &color); + &color, + node); } } static void -_clutter_actor_paint_cull_result (ClutterActor *self, - gboolean success, - ClutterCullResult result) +_clutter_actor_paint_cull_result (ClutterActor *self, + gboolean success, + ClutterCullResult result, + ClutterPaintNode *node) { + ClutterActorPrivate *priv = self->priv; ClutterPaintVolume *pv; - CoglColor color; + ClutterColor color; if (success) { if (result == CLUTTER_CULL_RESULT_IN) - cogl_color_init_from_4f (&color, 0, 1, 0, 1); + clutter_color_init (&color, 0, 255, 0, 255); else if (result == CLUTTER_CULL_RESULT_OUT) - cogl_color_init_from_4f (&color, 0, 0, 1, 1); + clutter_color_init (&color, 0, 0, 255, 255); else - cogl_color_init_from_4f (&color, 0, 1, 1, 1); + clutter_color_init (&color, 0, 255, 255, 255); } else - cogl_color_init_from_4f (&color, 1, 1, 1, 1); + clutter_color_init (&color, 255, 255, 255, 255); if (success && (pv = _clutter_actor_get_paint_volume_mutable (self))) _clutter_actor_draw_paint_volume_full (self, pv, _clutter_actor_get_debug_name (self), - &color); + &color, + node); else { + g_autoptr (ClutterPaintNode) text_node = NULL; PangoLayout *layout; + float width; + float height; char *label = g_strdup_printf ("CULL FAILURE: %s", _clutter_actor_get_debug_name (self)); - cogl_color_init_from_4f (&color, 1, 1, 1, 1); - cogl_set_source_color (&color); + clutter_color_init (&color, 255, 255, 255, 255); + + width = clutter_actor_box_get_width (&priv->allocation); + height = clutter_actor_box_get_height (&priv->allocation); layout = pango_layout_new (clutter_actor_get_pango_context (self)); pango_layout_set_text (layout, label, -1); - cogl_pango_render_layout (layout, - 0, - 0, - &color, - 0); - free (label); + + text_node = clutter_text_node_new (layout, &color); + clutter_paint_node_set_static_name (text_node, + "ClutterActor (paint volume text)"); + clutter_paint_node_add_rectangle (text_node, + &(ClutterActorBox) { + .x1 = 0.f, + .y1 = 0.f, + .x2 = width, + .y2 = height, + }); + clutter_paint_node_add_child (node, text_node); + + g_free (label); g_object_unref (layout); } } @@ -3445,8 +3648,9 @@ in_clone_paint (void) * means there's no point in trying to cull descendants of the current * node. */ static gboolean -cull_actor (ClutterActor *self, - ClutterCullResult *result_out) +cull_actor (ClutterActor *self, + ClutterPaintContext *paint_context, + ClutterCullResult *result_out) { ClutterActorPrivate *priv = self->priv; ClutterStage *stage; @@ -3473,10 +3677,10 @@ cull_actor (ClutterActor *self, return FALSE; } - if (cogl_get_draw_framebuffer () != _clutter_stage_get_active_framebuffer (stage)) + if (clutter_paint_context_is_drawing_off_stage (paint_context)) { CLUTTER_NOTE (CLIPPING, "Bail from cull_actor without culling (%s): " - "Current framebuffer doesn't correspond to stage", + "Drawing off stage", _clutter_actor_get_debug_name (self)); return FALSE; } @@ -3516,21 +3720,6 @@ _clutter_actor_update_last_paint_volume (ClutterActor *self) priv->last_paint_volume_valid = TRUE; } -static inline gboolean -actor_has_shader_data (ClutterActor *self) -{ - return g_object_get_qdata (G_OBJECT (self), quark_shader_data) != NULL; -} - -guint32 -_clutter_actor_get_pick_id (ClutterActor *self) -{ - if (self->priv->pick_id < 0) - return 0; - - return self->priv->pick_id; -} - /* This is the same as clutter_actor_add_effect except that it doesn't queue a redraw and it doesn't notify on the effect property */ static void @@ -3574,7 +3763,13 @@ needs_flatten_effect (ClutterActor *self) CLUTTER_DEBUG_DISABLE_OFFSCREEN_REDIRECT)) return FALSE; - if (priv->offscreen_redirect & CLUTTER_OFFSCREEN_REDIRECT_ALWAYS) + /* We need to enable the effect immediately even in ON_IDLE because that can + * only be implemented efficiently within the effect itself. + * If it was implemented here using just priv->is_dirty then we would lose + * the ability to animate opacity without repaints. + */ + if ((priv->offscreen_redirect & CLUTTER_OFFSCREEN_REDIRECT_ALWAYS) || + (priv->offscreen_redirect & CLUTTER_OFFSCREEN_REDIRECT_ON_IDLE)) return TRUE; else if (priv->offscreen_redirect & CLUTTER_OFFSCREEN_REDIRECT_AUTOMATIC_FOR_OPACITY) { @@ -3629,7 +3824,8 @@ add_or_remove_flatten_effect (ClutterActor *self) } static void -clutter_actor_real_paint (ClutterActor *actor) +clutter_actor_real_paint (ClutterActor *actor, + ClutterPaintContext *paint_context) { ClutterActorPrivate *priv = actor->priv; ClutterActor *iter; @@ -3646,21 +3842,19 @@ clutter_actor_real_paint (ClutterActor *actor) iter->priv->allocation.x2 - iter->priv->allocation.x1, iter->priv->allocation.y2 - iter->priv->allocation.y1); - clutter_actor_paint (iter); + clutter_actor_paint (iter, paint_context); } } static gboolean -clutter_actor_paint_node (ClutterActor *actor, - ClutterPaintNode *root) +clutter_actor_paint_node (ClutterActor *actor, + ClutterPaintNode *root, + ClutterPaintContext *paint_context) { ClutterActorPrivate *priv = actor->priv; ClutterActorBox box; ClutterColor bg_color; - if (root == NULL) - return FALSE; - box.x1 = 0.f; box.y1 = 0.f; box.x2 = clutter_actor_box_get_width (&priv->allocation); @@ -3674,7 +3868,7 @@ clutter_actor_paint_node (ClutterActor *actor, CoglFramebuffer *fb; CoglBufferBit clear_flags; - fb = _clutter_stage_get_active_framebuffer (CLUTTER_STAGE (actor)); + fb = clutter_paint_context_get_base_framebuffer (paint_context); if (clutter_stage_get_use_alpha (CLUTTER_STAGE (actor))) { @@ -3692,11 +3886,9 @@ clutter_actor_paint_node (ClutterActor *actor, bg_color.alpha); clear_flags = COGL_BUFFER_BIT_DEPTH; - if (!clutter_stage_get_no_clear_hint (CLUTTER_STAGE (actor))) - clear_flags |= COGL_BUFFER_BIT_COLOR; - node = _clutter_root_node_new (fb, &bg_color, clear_flags); - clutter_paint_node_set_name (node, "stageClear"); + node = clutter_root_node_new (fb, &bg_color, clear_flags); + clutter_paint_node_set_static_name (node, "stageClear"); clutter_paint_node_add_rectangle (node, &box); clutter_paint_node_add_child (root, node); clutter_paint_node_unref (node); @@ -3711,14 +3903,14 @@ clutter_actor_paint_node (ClutterActor *actor, / 255; node = clutter_color_node_new (&bg_color); - clutter_paint_node_set_name (node, "backgroundColor"); + clutter_paint_node_set_static_name (node, "backgroundColor"); clutter_paint_node_add_rectangle (node, &box); clutter_paint_node_add_child (root, node); clutter_paint_node_unref (node); } if (priv->content != NULL) - _clutter_content_paint_content (priv->content, actor, root); + _clutter_content_paint_content (priv->content, actor, root, paint_context); if (CLUTTER_ACTOR_GET_CLASS (actor)->paint_node != NULL) CLUTTER_ACTOR_GET_CLASS (actor)->paint_node (actor, root); @@ -3734,7 +3926,7 @@ clutter_actor_paint_node (ClutterActor *actor, } #endif /* CLUTTER_ENABLE_DEBUG */ - _clutter_paint_node_paint (root); + clutter_paint_node_paint (root, paint_context); return TRUE; } @@ -3758,13 +3950,15 @@ clutter_actor_paint_node (ClutterActor *actor, * unless it is performing a pick paint. */ void -clutter_actor_paint (ClutterActor *self) +clutter_actor_paint (ClutterActor *self, + ClutterPaintContext *paint_context) { + g_autoptr (ClutterPaintNode) actor_node = NULL; + g_autoptr (ClutterPaintNode) root_node = NULL; ClutterActorPrivate *priv; - ClutterPickMode pick_mode; + ClutterActorBox clip; + gboolean culling_inhibited; gboolean clip_set = FALSE; - gboolean shader_applied = FALSE; - ClutterStage *stage; g_return_if_fail (CLUTTER_IS_ACTOR (self)); @@ -3772,16 +3966,11 @@ clutter_actor_paint (ClutterActor *self) return; priv = self->priv; - - pick_mode = _clutter_context_get_pick_mode (); - - if (pick_mode == CLUTTER_PICK_NONE) - priv->propagated_one_redraw = FALSE; + priv->propagated_one_redraw = FALSE; /* It's an important optimization that we consider painting of * actors with 0 opacity to be a NOP... */ - if (pick_mode == CLUTTER_PICK_NONE && - /* ignore top-levels, since they might be transparent */ + if (/* ignore top-levels, since they might be transparent */ !CLUTTER_ACTOR_IS_TOPLEVEL (self) && /* Use the override opacity if its been set */ ((priv->opacity_override >= 0) ? @@ -3794,22 +3983,55 @@ clutter_actor_paint (ClutterActor *self) if (!CLUTTER_ACTOR_IS_MAPPED (self)) return; - stage = (ClutterStage *) _clutter_actor_get_stage_internal (self); + clutter_actor_ensure_resource_scale (self); - /* mark that we are in the paint process */ - CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_IN_PAINT); + actor_node = clutter_actor_node_new (self); + root_node = clutter_paint_node_ref (actor_node); + + if (priv->has_clip) + { + clip.x1 = priv->clip.origin.x; + clip.y1 = priv->clip.origin.y; + clip.x2 = priv->clip.origin.x + priv->clip.size.width; + clip.y2 = priv->clip.origin.y + priv->clip.size.height; + clip_set = TRUE; + } + else if (priv->clip_to_allocation) + { + clip.x1 = 0.f; + clip.y1 = 0.f; + clip.x2 = priv->allocation.x2 - priv->allocation.x1; + clip.y2 = priv->allocation.y2 - priv->allocation.y1; + clip_set = TRUE; + } + + if (clip_set) + { + ClutterPaintNode *clip_node; - cogl_push_matrix (); + clip_node = clutter_clip_node_new (); + clutter_paint_node_add_rectangle (clip_node, &clip); + clutter_paint_node_add_child (clip_node, root_node); + clutter_paint_node_unref (root_node); + + root_node = g_steal_pointer (&clip_node); + } if (priv->enable_model_view_transform) { - CoglMatrix matrix; + ClutterPaintNode *transform_node; + CoglMatrix transform; + + clutter_actor_get_transform (self, &transform); + + if (!cogl_matrix_is_identity (&transform)) + { + transform_node = clutter_transform_node_new (&transform); + clutter_paint_node_add_child (transform_node, root_node); + clutter_paint_node_unref (root_node); - /* XXX: It could be better to cache the modelview with the actor - * instead of progressively building up the transformations on - * the matrix stack every time we paint. */ - cogl_get_modelview_matrix (&matrix); - _clutter_actor_apply_modelview_transform (self, &matrix); + root_node = g_steal_pointer (&transform_node); + } #ifdef CLUTTER_ENABLE_DEBUG /* Catch when out-of-band transforms have been made by actors not as part @@ -3821,7 +4043,7 @@ clutter_actor_paint (ClutterActor *self) _clutter_actor_get_relative_transformation_matrix (self, NULL, &expected_matrix); - if (!cogl_matrix_equal (&matrix, &expected_matrix)) + if (!cogl_matrix_equal (&transform, &expected_matrix)) { GString *buf = g_string_sized_new (1024); ClutterActor *parent; @@ -3848,40 +4070,14 @@ clutter_actor_paint (ClutterActor *self) } } #endif /* CLUTTER_ENABLE_DEBUG */ - - cogl_set_modelview_matrix (&matrix); - } - - if (priv->has_clip) - { - CoglFramebuffer *fb = _clutter_stage_get_active_framebuffer (stage); - cogl_framebuffer_push_rectangle_clip (fb, - priv->clip.origin.x, - priv->clip.origin.y, - priv->clip.origin.x + priv->clip.size.width, - priv->clip.origin.y + priv->clip.size.height); - clip_set = TRUE; - } - else if (priv->clip_to_allocation) - { - CoglFramebuffer *fb = _clutter_stage_get_active_framebuffer (stage); - gfloat width, height; - - width = priv->allocation.x2 - priv->allocation.x1; - height = priv->allocation.y2 - priv->allocation.y1; - - cogl_framebuffer_push_rectangle_clip (fb, 0, 0, width, height); - clip_set = TRUE; } - if (pick_mode == CLUTTER_PICK_NONE) - { - /* We check whether we need to add the flatten effect before - each paint so that we can avoid having a mechanism for - applications to notify when the value of the - has_overlaps virtual changes. */ - add_or_remove_flatten_effect (self); - } + /* We check whether we need to add the flatten effect before + * each paint so that we can avoid having a mechanism for + * applications to notify when the value of the + * has_overlaps virtual changes. + */ + add_or_remove_flatten_effect (self); /* We save the current paint volume so that the next time the * actor queues a redraw we can constrain the redraw to just @@ -3910,7 +4106,8 @@ clutter_actor_paint (ClutterActor *self) * paint then the last-paint-volume would likely represent the new * actor position not the old. */ - if (!in_clone_paint () && pick_mode == CLUTTER_PICK_NONE) + culling_inhibited = priv->inhibit_culling_counter > 0; + if (!culling_inhibited && !in_clone_paint ()) { gboolean success; /* annoyingly gcc warns if uninitialized even though @@ -3924,55 +4121,28 @@ clutter_actor_paint (ClutterActor *self) CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS))) _clutter_actor_update_last_paint_volume (self); - success = cull_actor (self, &result); + success = cull_actor (self, paint_context, &result); if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_REDRAWS)) - _clutter_actor_paint_cull_result (self, success, result); + _clutter_actor_paint_cull_result (self, success, result, actor_node); else if (result == CLUTTER_CULL_RESULT_OUT && success) - goto done; + return; } if (priv->effects == NULL) - { - if (pick_mode == CLUTTER_PICK_NONE && - actor_has_shader_data (self)) - { - _clutter_actor_shader_pre_paint (self, FALSE); - shader_applied = TRUE; - } - - priv->next_effect_to_paint = NULL; - } + priv->next_effect_to_paint = NULL; else priv->next_effect_to_paint = _clutter_meta_group_peek_metas (priv->effects); - clutter_actor_continue_paint (self); + if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_VOLUMES)) + _clutter_actor_draw_paint_volume (self, actor_node); - if (shader_applied) - _clutter_actor_shader_post_paint (self); - - if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_VOLUMES && - pick_mode == CLUTTER_PICK_NONE)) - _clutter_actor_draw_paint_volume (self); + clutter_paint_node_paint (root_node, paint_context); /* If we make it here then the actor has run through a complete paint run including all the effects so it's no longer dirty */ - if (pick_mode == CLUTTER_PICK_NONE) - priv->is_dirty = FALSE; - -done: - if (clip_set) - { - CoglFramebuffer *fb = _clutter_stage_get_active_framebuffer (stage); - - cogl_framebuffer_pop_clip (fb); - } - - cogl_pop_matrix (); - - /* paint sequence complete */ - CLUTTER_UNSET_PRIVATE_FLAGS (self, CLUTTER_IN_PAINT); + priv->is_dirty = FALSE; } /** @@ -3988,7 +4158,8 @@ clutter_actor_paint (ClutterActor *self) * Since: 1.8 */ void -clutter_actor_continue_paint (ClutterActor *self) +clutter_actor_continue_paint (ClutterActor *self, + ClutterPaintContext *paint_context) { ClutterActorPrivate *priv; @@ -4008,49 +4179,32 @@ clutter_actor_continue_paint (ClutterActor *self) actual actor */ if (priv->next_effect_to_paint == NULL) { - if (_clutter_context_get_pick_mode () == CLUTTER_PICK_NONE) - { - ClutterPaintNode *dummy; - - /* XXX - this will go away in 2.0, when we can get rid of this - * stuff and switch to a pure retained render tree of PaintNodes - * for the entire frame, starting from the Stage; the paint() - * virtual function can then be called directly. - */ - dummy = _clutter_dummy_node_new (self); - clutter_paint_node_set_name (dummy, "Root"); + CoglFramebuffer *framebuffer; + ClutterPaintNode *dummy; - /* XXX - for 1.12, we use the return value of paint_node() to - * decide whether we should emit the ::paint signal. - */ - clutter_actor_paint_node (self, dummy); - clutter_paint_node_unref (dummy); + /* XXX - this will go away in 2.0, when we can get rid of this + * stuff and switch to a pure retained render tree of PaintNodes + * for the entire frame, starting from the Stage; the paint() + * virtual function can then be called directly. + */ + framebuffer = clutter_paint_context_get_base_framebuffer (paint_context); + dummy = _clutter_dummy_node_new (self, framebuffer); + clutter_paint_node_set_static_name (dummy, "Root"); - /* XXX:2.0 - Call the paint() virtual directly */ - if (g_signal_has_handler_pending (self, actor_signals[PAINT], - 0, TRUE)) - g_signal_emit (self, actor_signals[PAINT], 0); - else - CLUTTER_ACTOR_GET_CLASS (self)->paint (self); - } + /* XXX - for 1.12, we use the return value of paint_node() to + * decide whether we should emit the ::paint signal. + */ + clutter_actor_paint_node (self, dummy, paint_context); + clutter_paint_node_unref (dummy); + + /* XXX:2.0 - Call the paint() virtual directly */ + if (!(clutter_paint_context_get_paint_flags (paint_context) & + CLUTTER_PAINT_FLAG_NO_PAINT_SIGNAL) && + g_signal_has_handler_pending (self, actor_signals[PAINT], + 0, TRUE)) + g_signal_emit (self, actor_signals[PAINT], 0, paint_context); else - { - ClutterColor col = { 0, }; - - _clutter_id_to_color (_clutter_actor_get_pick_id (self), &col); - - /* Actor will then paint silhouette of itself in supplied - * color. See clutter_stage_get_actor_at_pos() for where - * picking is enabled. - * - * XXX:2.0 - Call the pick() virtual directly - */ - if (g_signal_has_handler_pending (self, actor_signals[PICK], - 0, TRUE)) - g_signal_emit (self, actor_signals[PICK], 0, &col); - else - CLUTTER_ACTOR_GET_CLASS (self)->pick (self, &col); - } + CLUTTER_ACTOR_GET_CLASS (self)->paint (self, paint_context); } else { @@ -4064,31 +4218,166 @@ clutter_actor_continue_paint (ClutterActor *self) priv->current_effect = priv->next_effect_to_paint->data; priv->next_effect_to_paint = priv->next_effect_to_paint->next; - if (_clutter_context_get_pick_mode () == CLUTTER_PICK_NONE) + if (priv->is_dirty) { - if (priv->is_dirty) - { - /* If there's an effect queued with this redraw then all - effects up to that one will be considered dirty. It - is expected the queued effect will paint the cached - image and not call clutter_actor_continue_paint again - (although it should work ok if it does) */ - if (priv->effect_to_redraw == NULL || - priv->current_effect != priv->effect_to_redraw) - run_flags |= CLUTTER_EFFECT_PAINT_ACTOR_DIRTY; - } - - _clutter_effect_paint (priv->current_effect, run_flags); + /* If there's an effect queued with this redraw then all + * effects up to that one will be considered dirty. It + * is expected the queued effect will paint the cached + * image and not call clutter_actor_continue_paint again + * (although it should work ok if it does) + */ + if (priv->effect_to_redraw == NULL || + priv->current_effect != priv->effect_to_redraw) + run_flags |= CLUTTER_EFFECT_PAINT_ACTOR_DIRTY; } + + if (priv->current_effect == priv->flatten_effect && + priv->offscreen_redirect & CLUTTER_OFFSCREEN_REDIRECT_ON_IDLE && + run_flags & CLUTTER_EFFECT_PAINT_ACTOR_DIRTY) + run_flags |= CLUTTER_EFFECT_PAINT_BYPASS_EFFECT; + + _clutter_effect_paint (priv->current_effect, paint_context, run_flags); + + priv->current_effect = old_current_effect; + } +} + +/** + * clutter_actor_pick: + * @actor: A #ClutterActor + * + * Asks @actor to perform a pick. + */ +void +clutter_actor_pick (ClutterActor *actor, + ClutterPickContext *pick_context) +{ + ClutterActorPrivate *priv; + CoglFramebuffer *framebuffer; + ClutterActorBox clip; + gboolean clip_set = FALSE; + + if (CLUTTER_ACTOR_IN_DESTRUCTION (actor)) + return; + + priv = actor->priv; + + /* if we aren't paintable (not in a toplevel with all + * parents paintable) then do nothing. + */ + if (!CLUTTER_ACTOR_IS_MAPPED (actor)) + return; + + clutter_actor_ensure_resource_scale (actor); + + /* mark that we are in the paint process */ + CLUTTER_SET_PRIVATE_FLAGS (actor, CLUTTER_IN_PICK); + + framebuffer = clutter_pick_context_get_framebuffer (pick_context); + cogl_framebuffer_push_matrix (framebuffer); + + if (priv->enable_model_view_transform) + { + CoglMatrix matrix; + + cogl_framebuffer_get_modelview_matrix (framebuffer, &matrix); + _clutter_actor_apply_modelview_transform (actor, &matrix); + cogl_framebuffer_set_modelview_matrix (framebuffer, &matrix); + } + + if (priv->has_clip) + { + clip.x1 = priv->clip.origin.x; + clip.y1 = priv->clip.origin.y; + clip.x2 = priv->clip.origin.x + priv->clip.size.width; + clip.y2 = priv->clip.origin.y + priv->clip.size.height; + clip_set = TRUE; + } + else if (priv->clip_to_allocation) + { + clip.x1 = 0.f; + clip.y1 = 0.f; + clip.x2 = priv->allocation.x2 - priv->allocation.x1; + clip.y2 = priv->allocation.y2 - priv->allocation.y1; + clip_set = TRUE; + } + + if (clip_set) + clip_set = _clutter_actor_push_pick_clip (actor, pick_context, &clip); + + priv->next_effect_to_paint = NULL; + if (priv->effects) + { + priv->next_effect_to_paint = + _clutter_meta_group_peek_metas (priv->effects); + } + + clutter_actor_continue_pick (actor, pick_context); + + if (clip_set) + _clutter_actor_pop_pick_clip (actor); + + cogl_framebuffer_pop_matrix (framebuffer); + + /* paint sequence complete */ + CLUTTER_UNSET_PRIVATE_FLAGS (actor, CLUTTER_IN_PICK); +} + +/** + * clutter_actor_continue_pick: + * @actor: A #ClutterActor + * + * Run the next stage of the pick sequence. This function should only + * be called within the implementation of the ‘pick’ virtual of a + * #ClutterEffect. It will cause the run method of the next effect to + * be applied, or it will pick the actual actor if the current effect + * is the last effect in the chain. + */ +void +clutter_actor_continue_pick (ClutterActor *actor, + ClutterPickContext *pick_context) +{ + ClutterActorPrivate *priv; + + g_return_if_fail (CLUTTER_IS_ACTOR (actor)); + + g_return_if_fail (CLUTTER_ACTOR_IN_PICK (actor)); + + priv = actor->priv; + + /* Skip any effects that are disabled */ + while (priv->next_effect_to_paint && + !clutter_actor_meta_get_enabled (priv->next_effect_to_paint->data)) + priv->next_effect_to_paint = priv->next_effect_to_paint->next; + + /* If this has come from the last effect then we'll just pick the + * actual actor. + */ + if (priv->next_effect_to_paint == NULL) + { + /* The actor will log a silhouette of itself to the stage pick log. + * + * XXX:2.0 - Call the pick() virtual directly + */ + if (g_signal_has_handler_pending (actor, actor_signals[PICK], + 0, TRUE)) + g_signal_emit (actor, actor_signals[PICK], 0, pick_context); else - { - /* We can't determine when an actor has been modified since - its last pick so lets just assume it has always been - modified */ - run_flags |= CLUTTER_EFFECT_PAINT_ACTOR_DIRTY; + CLUTTER_ACTOR_GET_CLASS (actor)->pick (actor, pick_context); + } + else + { + ClutterEffect *old_current_effect; - _clutter_effect_pick (priv->current_effect, run_flags); - } + /* Cache the current effect so that we can put it back before + * returning. + */ + old_current_effect = priv->current_effect; + + priv->current_effect = priv->next_effect_to_paint->data; + priv->next_effect_to_paint = priv->next_effect_to_paint->next; + + _clutter_effect_pick (priv->current_effect, pick_context); priv->current_effect = old_current_effect; } @@ -4110,11 +4399,7 @@ _clutter_actor_stop_transitions (ClutterActor *self) { TransitionClosure *closure = value; - /* implicit transitions, and automatically managed explicit ones, - * should be removed at this point - */ - if (closure->is_implicit || - clutter_transition_get_remove_on_complete (closure->transition)) + if (clutter_transition_get_remove_on_complete (closure->transition)) { g_hash_table_iter_remove (&iter); } @@ -4171,7 +4456,8 @@ remove_child (ClutterActor *self, child->priv->next_sibling = NULL; } -typedef enum { +typedef enum +{ REMOVE_CHILD_DESTROY_META = 1 << 0, REMOVE_CHILD_EMIT_PARENT_SET = 1 << 1, REMOVE_CHILD_EMIT_ACTOR_REMOVED = 1 << 2, @@ -4289,6 +4575,9 @@ clutter_actor_remove_child_internal (ClutterActor *self, self->priv->age += 1; + if (self->priv->in_cloned_branch) + clutter_actor_pop_in_cloned_branch (child, self->priv->in_cloned_branch); + /* if the child that got removed was visible and set to * expand then we want to reset the parent's state in * case the child was the only thing that was making it @@ -4302,9 +4591,12 @@ clutter_actor_remove_child_internal (ClutterActor *self, clutter_actor_queue_compute_expand (self); } - /* clutter_actor_reparent() will emit ::parent-set for us */ - if (emit_parent_set && !CLUTTER_ACTOR_IN_REPARENT (child)) - g_signal_emit (child, actor_signals[PARENT_SET], 0, self); + if (emit_parent_set && !CLUTTER_ACTOR_IN_REPARENT (child) && + !CLUTTER_ACTOR_IN_DESTRUCTION (child)) + { + child->priv->needs_compute_resource_scale = TRUE; + g_signal_emit (child, actor_signals[PARENT_SET], 0, self); + } /* if the child was mapped then we need to relayout ourselves to account * for the removed child @@ -4314,7 +4606,7 @@ clutter_actor_remove_child_internal (ClutterActor *self, /* we need to emit the signal before dropping the reference */ if (emit_actor_removed) - g_signal_emit_by_name (self, "actor-removed", child); + _clutter_container_emit_actor_removed (CLUTTER_CONTAINER (self), child); if (notify_first_last) { @@ -4340,11 +4632,11 @@ static const ClutterTransformInfo default_transform_info = { { 0, }, /* anchor XXX:2.0 - remove*/ - CLUTTER_VERTEX_INIT_ZERO, /* translation */ + GRAPHENE_POINT3D_INIT_ZERO, /* translation */ 0.f, /* z-position */ - CLUTTER_POINT_INIT_ZERO, /* pivot */ + GRAPHENE_POINT_INIT_ZERO, /* pivot */ 0.f, /* pivot-z */ CLUTTER_MATRIX_INIT_IDENTITY, @@ -4423,8 +4715,8 @@ _clutter_actor_get_transform_info (ClutterActor *self) } static inline void -clutter_actor_set_pivot_point_internal (ClutterActor *self, - const ClutterPoint *pivot) +clutter_actor_set_pivot_point_internal (ClutterActor *self, + const graphene_point_t *pivot) { ClutterTransformInfo *info; @@ -4729,11 +5021,11 @@ clutter_actor_get_rotation_angle (ClutterActor *self, * rotation angle. */ static inline void -clutter_actor_set_rotation_center_internal (ClutterActor *self, - ClutterRotateAxis axis, - const ClutterVertex *center) +clutter_actor_set_rotation_center_internal (ClutterActor *self, + ClutterRotateAxis axis, + const graphene_point3d_t *center) { - ClutterVertex v = CLUTTER_VERTEX_INIT_ZERO; + graphene_point3d_t v = GRAPHENE_POINT3D_INIT_ZERO; GObject *obj = G_OBJECT (self); ClutterTransformInfo *info; @@ -4832,7 +5124,8 @@ clutter_actor_set_scale_factor (ClutterActor *self, g_assert (pspec != NULL); g_assert (scale_p != NULL); - _clutter_actor_create_transition (self, pspec, *scale_p, factor); + if (*scale_p != factor) + _clutter_actor_create_transition (self, pspec, *scale_p, factor); } static inline void @@ -4959,8 +5252,8 @@ clutter_actor_set_anchor_coord (ClutterActor *self, } static void -clutter_actor_set_clip_rect (ClutterActor *self, - const ClutterRect *clip) +clutter_actor_set_clip_rect (ClutterActor *self, + const graphene_rect_t *clip) { ClutterActorPrivate *priv = self->priv; GObject *obj = G_OBJECT (self); @@ -4975,7 +5268,6 @@ clutter_actor_set_clip_rect (ClutterActor *self, clutter_actor_queue_redraw (self); - g_object_notify_by_pspec (obj, obj_props[PROP_CLIP]); /* XXX:2.0 - remove */ g_object_notify_by_pspec (obj, obj_props[PROP_CLIP_RECT]); g_object_notify_by_pspec (obj, obj_props[PROP_HAS_CLIP]); } @@ -5001,7 +5293,7 @@ clutter_actor_set_property (GObject *object, case PROP_POSITION: { - const ClutterPoint *pos = g_value_get_boxed (value); + const graphene_point_t *pos = g_value_get_boxed (value); if (pos != NULL) clutter_actor_set_position (actor, pos->x, pos->y); @@ -5020,7 +5312,7 @@ clutter_actor_set_property (GObject *object, case PROP_SIZE: { - const ClutterSize *size = g_value_get_boxed (value); + const graphene_size_t *size = g_value_get_boxed (value); if (size != NULL) clutter_actor_set_size (actor, size->width, size->height); @@ -5106,10 +5398,10 @@ clutter_actor_set_property (GObject *object, case PROP_PIVOT_POINT: { - const ClutterPoint *pivot = g_value_get_boxed (value); + const graphene_point_t *pivot = g_value_get_boxed (value); if (pivot == NULL) - pivot = clutter_point_zero (); + pivot = graphene_point_zero (); clutter_actor_set_pivot_point (actor, pivot->x, pivot->y); } @@ -5163,16 +5455,6 @@ clutter_actor_set_property (GObject *object, clutter_actor_set_scale_gravity (actor, g_value_get_enum (value)); break; - case PROP_CLIP: /* XXX:2.0 - remove */ - { - const ClutterGeometry *geom = g_value_get_boxed (value); - - clutter_actor_set_clip (actor, - geom->x, geom->y, - geom->width, geom->height); - } - break; - case PROP_CLIP_RECT: clutter_actor_set_clip_rect (actor, g_value_get_boxed (value)); break; @@ -5365,11 +5647,11 @@ clutter_actor_get_property (GObject *object, case PROP_POSITION: { - ClutterPoint position; + graphene_point_t position; - clutter_point_init (&position, - clutter_actor_get_x (actor), - clutter_actor_get_y (actor)); + graphene_point_init (&position, + clutter_actor_get_x (actor), + clutter_actor_get_y (actor)); g_value_set_boxed (value, &position); } break; @@ -5384,11 +5666,11 @@ clutter_actor_get_property (GObject *object, case PROP_SIZE: { - ClutterSize size; + graphene_size_t size; - clutter_size_init (&size, - clutter_actor_get_width (actor), - clutter_actor_get_height (actor)); + graphene_size_init (&size, + clutter_actor_get_width (actor), + clutter_actor_get_height (actor)); g_value_set_boxed (value, &size); } break; @@ -5511,19 +5793,6 @@ clutter_actor_get_property (GObject *object, g_value_set_boolean (value, priv->has_clip); break; - case PROP_CLIP: /* XXX:2.0 - remove */ - { - ClutterGeometry clip; - - clip.x = CLUTTER_NEARBYINT (priv->clip.origin.x); - clip.y = CLUTTER_NEARBYINT (priv->clip.origin.y); - clip.width = CLUTTER_NEARBYINT (priv->clip.size.width); - clip.height = CLUTTER_NEARBYINT (priv->clip.size.height); - - g_value_set_boxed (value, &clip); - } - break; - case PROP_CLIP_RECT: g_value_set_boxed (value, &priv->clip); break; @@ -5628,6 +5897,16 @@ clutter_actor_get_property (GObject *object, g_value_set_enum (value, clutter_actor_get_scale_gravity (actor)); break; + case PROP_RESOURCE_SCALE: + if (priv->needs_compute_resource_scale) + { + if (!clutter_actor_update_resource_scale (actor)) + g_warning ("Getting invalid resource scale property"); + } + + g_value_set_float (value, priv->resource_scale); + break; + case PROP_REACTIVE: g_value_set_boolean (value, clutter_actor_get_reactive (actor)); break; @@ -5661,7 +5940,7 @@ clutter_actor_get_property (GObject *object, case PROP_ROTATION_CENTER_X: /* XXX:2.0 - remove */ { - ClutterVertex center; + graphene_point3d_t center; clutter_actor_get_rotation (actor, CLUTTER_X_AXIS, ¢er.x, @@ -5674,7 +5953,7 @@ clutter_actor_get_property (GObject *object, case PROP_ROTATION_CENTER_Y: /* XXX:2.0 - remove */ { - ClutterVertex center; + graphene_point3d_t center; clutter_actor_get_rotation (actor, CLUTTER_Y_AXIS, ¢er.x, @@ -5687,7 +5966,7 @@ clutter_actor_get_property (GObject *object, case PROP_ROTATION_CENTER_Z: /* XXX:2.0 - remove */ { - ClutterVertex center; + graphene_point3d_t center; clutter_actor_get_rotation (actor, CLUTTER_Z_AXIS, ¢er.x, @@ -5914,30 +6193,25 @@ clutter_actor_dispose (GObject *object) { ClutterActor *self = CLUTTER_ACTOR (object); ClutterActorPrivate *priv = self->priv; + ClutterBackend *backend = clutter_get_default_backend (); CLUTTER_NOTE (MISC, "Dispose actor (name='%s', ref_count:%d) of type '%s'", _clutter_actor_get_debug_name (self), object->ref_count, g_type_name (G_OBJECT_TYPE (self))); + maybe_unset_key_focus (self); + + /* Stop the emission of any property change */ + g_object_freeze_notify (object); + g_signal_emit (self, actor_signals[DESTROY], 0); /* avoid recursing when called from clutter_actor_destroy() */ if (priv->parent != NULL) { ClutterActor *parent = priv->parent; - - /* go through the Container implementation unless this - * is an internal child and has been marked as such. - * - * removing the actor from its parent will reset the - * realized and mapped states. - */ - if (!CLUTTER_ACTOR_IS_INTERNAL_CHILD (self)) - clutter_container_remove_actor (CLUTTER_CONTAINER (parent), self); - else - clutter_actor_remove_child_internal (parent, self, - REMOVE_CHILD_LEGACY_FLAGS); + clutter_container_remove_actor (CLUTTER_CONTAINER (parent), self); } /* parent must be gone at this point */ @@ -5950,6 +6224,9 @@ clutter_actor_dispose (GObject *object) g_assert (!CLUTTER_ACTOR_IS_REALIZED (self)); } + g_clear_signal_handler (&priv->resolution_changed_id, backend); + g_clear_signal_handler (&priv->font_changed_id, backend); + g_clear_object (&priv->pango_context); g_clear_object (&priv->actions); g_clear_object (&priv->constraints); @@ -5998,10 +6275,10 @@ clutter_actor_finalize (GObject *object) _clutter_actor_get_debug_name ((ClutterActor *) object), g_type_name (G_OBJECT_TYPE (object))); - free (priv->name); + g_free (priv->name); #ifdef CLUTTER_ENABLE_DEBUG - free (priv->debug_name); + g_free (priv->debug_name); #endif G_OBJECT_CLASS (clutter_actor_parent_class)->finalize (object); @@ -6097,7 +6374,7 @@ clutter_actor_update_default_paint_volume (ClutterActor *self, priv->clip.size.width >= 0 && priv->clip.size.height >= 0) { - ClutterVertex origin; + graphene_point3d_t origin; origin.x = priv->clip.origin.x; origin.y = priv->clip.origin.y; @@ -6288,11 +6565,25 @@ clutter_actor_class_init (ClutterActorClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - quark_shader_data = g_quark_from_static_string ("-clutter-actor-shader-data"); quark_actor_layout_info = g_quark_from_static_string ("-clutter-actor-layout-info"); quark_actor_transform_info = g_quark_from_static_string ("-clutter-actor-transform-info"); quark_actor_animation_info = g_quark_from_static_string ("-clutter-actor-animation-info"); + quark_key = g_quark_from_static_string ("key"); + quark_motion = g_quark_from_static_string ("motion"); + quark_pointer_focus = g_quark_from_static_string ("pointer-focus"); + quark_button = g_quark_from_static_string ("button"); + quark_scroll = g_quark_from_static_string ("scroll"); + quark_stage = g_quark_from_static_string ("stage"); + quark_destroy = g_quark_from_static_string ("destroy"); + quark_client = g_quark_from_static_string ("client"); + quark_delete = g_quark_from_static_string ("delete"); + quark_touch = g_quark_from_static_string ("touch"); + quark_touchpad = g_quark_from_static_string ("touchpad"); + quark_proximity = g_quark_from_static_string ("proximity"); + quark_pad = g_quark_from_static_string ("pad"); + quark_im = g_quark_from_static_string ("im"); + object_class->constructor = clutter_actor_constructor; object_class->set_property = clutter_actor_set_property; object_class->get_property = clutter_actor_get_property; @@ -6374,7 +6665,7 @@ clutter_actor_class_init (ClutterActorClass *klass) g_param_spec_boxed ("position", P_("Position"), P_("The position of the origin of the actor"), - CLUTTER_TYPE_POINT, + GRAPHENE_TYPE_POINT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | CLUTTER_PARAM_ANIMATABLE); @@ -6392,7 +6683,7 @@ clutter_actor_class_init (ClutterActorClass *klass) g_param_spec_float ("width", P_("Width"), P_("Width of the actor"), - 0.0, G_MAXFLOAT, + -1.0f, G_MAXFLOAT, 0.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | @@ -6411,7 +6702,7 @@ clutter_actor_class_init (ClutterActorClass *klass) g_param_spec_float ("height", P_("Height"), P_("Height of the actor"), - 0.0, G_MAXFLOAT, + -1.0f, G_MAXFLOAT, 0.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | @@ -6433,7 +6724,7 @@ clutter_actor_class_init (ClutterActorClass *klass) g_param_spec_boxed ("size", P_("Size"), P_("The size of the actor"), - CLUTTER_TYPE_SIZE, + GRAPHENE_TYPE_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | CLUTTER_PARAM_ANIMATABLE); @@ -6875,25 +7166,11 @@ clutter_actor_class_init (ClutterActorClass *klass) FALSE, CLUTTER_PARAM_READABLE); - /** - * ClutterActor:clip: - * - * The visible region of the actor, in actor-relative coordinates - * - * Deprecated: 1.12: Use #ClutterActor:clip-rect instead. - */ - obj_props[PROP_CLIP] = /* XXX:2.0 - remove */ - g_param_spec_boxed ("clip", - P_("Clip"), - P_("The clip region for the actor"), - CLUTTER_TYPE_GEOMETRY, - CLUTTER_PARAM_READWRITE); - /** * ClutterActor:clip-rect: * * The visible region of the actor, in actor-relative coordinates, - * expressed as a #ClutterRect. + * expressed as a #graphene_rect_t. * * Setting this property to %NULL will unset the existing clip. * @@ -6906,7 +7183,7 @@ clutter_actor_class_init (ClutterActorClass *klass) g_param_spec_boxed ("clip-rect", P_("Clip Rectangle"), P_("The visible region of the actor"), - CLUTTER_TYPE_RECT, + GRAPHENE_TYPE_RECT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); @@ -6943,7 +7220,7 @@ clutter_actor_class_init (ClutterActorClass *klass) g_param_spec_boxed ("pivot-point", P_("Pivot Point"), P_("The point around which the scaling and rotation occur"), - CLUTTER_TYPE_POINT, + GRAPHENE_TYPE_POINT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | CLUTTER_PARAM_ANIMATABLE); @@ -7082,6 +7359,19 @@ clutter_actor_class_init (ClutterActorClass *klass) G_PARAM_STATIC_STRINGS | G_PARAM_DEPRECATED); + /** + * ClutterActor:resource-scale: + * + * The resource-scale of the #ClutterActor if any or -1 if not available + */ + obj_props[PROP_RESOURCE_SCALE] = + g_param_spec_float ("resource-scale", + P_("Resource Scale"), + P_("The Scaling factor for resources painting"), + -1.0f, G_MAXFLOAT, + 1.0f, + CLUTTER_PARAM_READABLE); + /** * ClutterActor:rotation-angle-x: * @@ -7152,7 +7442,7 @@ clutter_actor_class_init (ClutterActorClass *klass) g_param_spec_boxed ("rotation-center-x", P_("Rotation Center X"), P_("The rotation center on the X axis"), - CLUTTER_TYPE_VERTEX, + GRAPHENE_TYPE_POINT3D, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_DEPRECATED); @@ -7170,7 +7460,7 @@ clutter_actor_class_init (ClutterActorClass *klass) g_param_spec_boxed ("rotation-center-y", P_("Rotation Center Y"), P_("The rotation center on the Y axis"), - CLUTTER_TYPE_VERTEX, + GRAPHENE_TYPE_POINT3D, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_DEPRECATED); @@ -7188,7 +7478,7 @@ clutter_actor_class_init (ClutterActorClass *klass) g_param_spec_boxed ("rotation-center-z", P_("Rotation Center Z"), P_("The rotation center on the Z axis"), - CLUTTER_TYPE_VERTEX, + GRAPHENE_TYPE_POINT3D, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_DEPRECATED); @@ -7901,8 +8191,7 @@ clutter_actor_class_init (ClutterActorClass *klass) G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_CLEANUP | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, G_STRUCT_OFFSET (ClutterActorClass, destroy), - NULL, NULL, - _clutter_marshal_VOID__VOID, + NULL, NULL, NULL, G_TYPE_NONE, 0); /** * ClutterActor::show: @@ -7918,8 +8207,7 @@ clutter_actor_class_init (ClutterActorClass *klass) G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (ClutterActorClass, show), - NULL, NULL, - _clutter_marshal_VOID__VOID, + NULL, NULL, NULL, G_TYPE_NONE, 0); /** * ClutterActor::hide: @@ -7935,8 +8223,7 @@ clutter_actor_class_init (ClutterActorClass *klass) G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (ClutterActorClass, hide), - NULL, NULL, - _clutter_marshal_VOID__VOID, + NULL, NULL, NULL, G_TYPE_NONE, 0); /** * ClutterActor::parent-set: @@ -7952,8 +8239,7 @@ clutter_actor_class_init (ClutterActorClass *klass) G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ClutterActorClass, parent_set), - NULL, NULL, - _clutter_marshal_VOID__OBJECT, + NULL, NULL, NULL, G_TYPE_NONE, 1, CLUTTER_TYPE_ACTOR); @@ -7961,6 +8247,7 @@ clutter_actor_class_init (ClutterActorClass *klass) * ClutterActor::queue-redraw: * @actor: the actor we're bubbling the redraw request through * @origin: the actor which initiated the redraw request + * @volume: paint volume to redraw * * The ::queue_redraw signal is emitted when clutter_actor_queue_redraw() * is called on @origin. @@ -8014,10 +8301,15 @@ clutter_actor_class_init (ClutterActorClass *klass) G_SIGNAL_RUN_LAST | G_SIGNAL_NO_HOOKS, G_STRUCT_OFFSET (ClutterActorClass, queue_redraw), - NULL, NULL, - _clutter_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - CLUTTER_TYPE_ACTOR); + g_signal_accumulator_true_handled, + NULL, + _clutter_marshal_BOOLEAN__OBJECT_BOXED, + G_TYPE_BOOLEAN, 2, + CLUTTER_TYPE_ACTOR, + CLUTTER_TYPE_PAINT_VOLUME); + g_signal_set_va_marshaller (actor_signals[QUEUE_REDRAW], + G_TYPE_FROM_CLASS (object_class), + _clutter_marshal_BOOLEAN__OBJECT_BOXEDv); /** * ClutterActor::queue-relayout: @@ -8042,8 +8334,7 @@ clutter_actor_class_init (ClutterActorClass *klass) G_SIGNAL_RUN_LAST | G_SIGNAL_NO_HOOKS, G_STRUCT_OFFSET (ClutterActorClass, queue_relayout), - NULL, NULL, - _clutter_marshal_VOID__VOID, + NULL, NULL, NULL, G_TYPE_NONE, 0); /** @@ -8070,6 +8361,9 @@ clutter_actor_class_init (ClutterActorClass *klass) _clutter_marshal_BOOLEAN__BOXED, G_TYPE_BOOLEAN, 1, CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); + g_signal_set_va_marshaller (actor_signals[EVENT], + G_TYPE_FROM_CLASS (object_class), + _clutter_marshal_BOOLEAN__BOXEDv); /** * ClutterActor::button-press-event: * @actor: the actor which received the event @@ -8092,6 +8386,9 @@ clutter_actor_class_init (ClutterActorClass *klass) _clutter_marshal_BOOLEAN__BOXED, G_TYPE_BOOLEAN, 1, CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); + g_signal_set_va_marshaller (actor_signals[BUTTON_PRESS_EVENT], + G_TYPE_FROM_CLASS (object_class), + _clutter_marshal_BOOLEAN__BOXEDv); /** * ClutterActor::button-release-event: * @actor: the actor which received the event @@ -8114,6 +8411,9 @@ clutter_actor_class_init (ClutterActorClass *klass) _clutter_marshal_BOOLEAN__BOXED, G_TYPE_BOOLEAN, 1, CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); + g_signal_set_va_marshaller (actor_signals[BUTTON_RELEASE_EVENT], + G_TYPE_FROM_CLASS (object_class), + _clutter_marshal_BOOLEAN__BOXEDv); /** * ClutterActor::scroll-event: * @actor: the actor which received the event @@ -8136,6 +8436,9 @@ clutter_actor_class_init (ClutterActorClass *klass) _clutter_marshal_BOOLEAN__BOXED, G_TYPE_BOOLEAN, 1, CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); + g_signal_set_va_marshaller (actor_signals[SCROLL_EVENT], + G_TYPE_FROM_CLASS (object_class), + _clutter_marshal_BOOLEAN__BOXEDv); /** * ClutterActor::key-press-event: * @actor: the actor which received the event @@ -8158,6 +8461,9 @@ clutter_actor_class_init (ClutterActorClass *klass) _clutter_marshal_BOOLEAN__BOXED, G_TYPE_BOOLEAN, 1, CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); + g_signal_set_va_marshaller (actor_signals[KEY_PRESS_EVENT], + G_TYPE_FROM_CLASS (object_class), + _clutter_marshal_BOOLEAN__BOXEDv); /** * ClutterActor::key-release-event: * @actor: the actor which received the event @@ -8181,6 +8487,9 @@ clutter_actor_class_init (ClutterActorClass *klass) _clutter_marshal_BOOLEAN__BOXED, G_TYPE_BOOLEAN, 1, CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); + g_signal_set_va_marshaller (actor_signals[KEY_RELEASE_EVENT], + G_TYPE_FROM_CLASS (object_class), + _clutter_marshal_BOOLEAN__BOXEDv); /** * ClutterActor::motion-event: * @actor: the actor which received the event @@ -8203,6 +8512,9 @@ clutter_actor_class_init (ClutterActorClass *klass) _clutter_marshal_BOOLEAN__BOXED, G_TYPE_BOOLEAN, 1, CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); + g_signal_set_va_marshaller (actor_signals[MOTION_EVENT], + G_TYPE_FROM_CLASS (object_class), + _clutter_marshal_BOOLEAN__BOXEDv); /** * ClutterActor::key-focus-in: @@ -8217,8 +8529,7 @@ clutter_actor_class_init (ClutterActorClass *klass) G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ClutterActorClass, key_focus_in), - NULL, NULL, - _clutter_marshal_VOID__VOID, + NULL, NULL, NULL, G_TYPE_NONE, 0); /** @@ -8234,8 +8545,7 @@ clutter_actor_class_init (ClutterActorClass *klass) G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ClutterActorClass, key_focus_out), - NULL, NULL, - _clutter_marshal_VOID__VOID, + NULL, NULL, NULL, G_TYPE_NONE, 0); /** @@ -8259,6 +8569,9 @@ clutter_actor_class_init (ClutterActorClass *klass) _clutter_marshal_BOOLEAN__BOXED, G_TYPE_BOOLEAN, 1, CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); + g_signal_set_va_marshaller (actor_signals[ENTER_EVENT], + G_TYPE_FROM_CLASS (object_class), + _clutter_marshal_BOOLEAN__BOXEDv); /** * ClutterActor::leave-event: @@ -8281,6 +8594,9 @@ clutter_actor_class_init (ClutterActorClass *klass) _clutter_marshal_BOOLEAN__BOXED, G_TYPE_BOOLEAN, 1, CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); + g_signal_set_va_marshaller (actor_signals[LEAVE_EVENT], + G_TYPE_FROM_CLASS (object_class), + _clutter_marshal_BOOLEAN__BOXEDv); /** * ClutterActor::captured-event: @@ -8303,16 +8619,20 @@ clutter_actor_class_init (ClutterActorClass *klass) actor_signals[CAPTURED_EVENT] = g_signal_new (I_("captured-event"), G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, + G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, G_STRUCT_OFFSET (ClutterActorClass, captured_event), _clutter_boolean_handled_accumulator, NULL, _clutter_marshal_BOOLEAN__BOXED, G_TYPE_BOOLEAN, 1, CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); + g_signal_set_va_marshaller (actor_signals[CAPTURED_EVENT], + G_TYPE_FROM_CLASS (object_class), + _clutter_marshal_BOOLEAN__BOXEDv); /** * ClutterActor::paint: * @actor: the #ClutterActor that received the signal + * @paint_context: a #ClutterPaintContext * * The ::paint signal is emitted each time an actor is being painted. * @@ -8339,9 +8659,9 @@ clutter_actor_class_init (ClutterActorClass *klass) G_SIGNAL_NO_HOOKS | G_SIGNAL_DEPRECATED, G_STRUCT_OFFSET (ClutterActorClass, paint), - NULL, NULL, - _clutter_marshal_VOID__VOID, - G_TYPE_NONE, 0); + NULL, NULL, NULL, + G_TYPE_NONE, 1, + CLUTTER_TYPE_PAINT_CONTEXT); /** * ClutterActor::realize: * @actor: the #ClutterActor that received the signal @@ -8359,8 +8679,7 @@ clutter_actor_class_init (ClutterActorClass *klass) G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST | G_SIGNAL_DEPRECATED, G_STRUCT_OFFSET (ClutterActorClass, realize), - NULL, NULL, - _clutter_marshal_VOID__VOID, + NULL, NULL, NULL, G_TYPE_NONE, 0); /** * ClutterActor::unrealize: @@ -8379,19 +8698,17 @@ clutter_actor_class_init (ClutterActorClass *klass) G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST | G_SIGNAL_DEPRECATED, G_STRUCT_OFFSET (ClutterActorClass, unrealize), - NULL, NULL, - _clutter_marshal_VOID__VOID, + NULL, NULL, NULL, G_TYPE_NONE, 0); /** * ClutterActor::pick: * @actor: the #ClutterActor that received the signal - * @color: the #ClutterColor to be used when picking + * @pick_context: a #ClutterPickContext * * The ::pick signal is emitted each time an actor is being painted * in "pick mode". The pick mode is used to identify the actor during * the event handling phase, or by clutter_stage_get_actor_at_pos(). - * The actor should paint its shape using the passed @pick_color. * * Subclasses of #ClutterActor should override the class signal handler * and paint themselves in that function. @@ -8408,10 +8725,9 @@ clutter_actor_class_init (ClutterActorClass *klass) G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST | G_SIGNAL_DEPRECATED, G_STRUCT_OFFSET (ClutterActorClass, pick), - NULL, NULL, - _clutter_marshal_VOID__BOXED, + NULL, NULL, NULL, G_TYPE_NONE, 1, - CLUTTER_TYPE_COLOR | G_SIGNAL_TYPE_STATIC_SCOPE); + CLUTTER_TYPE_PICK_CONTEXT); /** * ClutterActor::allocation-changed: @@ -8438,6 +8754,9 @@ clutter_actor_class_init (ClutterActorClass *klass) G_TYPE_NONE, 2, CLUTTER_TYPE_ACTOR_BOX | G_SIGNAL_TYPE_STATIC_SCOPE, CLUTTER_TYPE_ALLOCATION_FLAGS); + g_signal_set_va_marshaller (actor_signals[ALLOCATION_CHANGED], + G_TYPE_FROM_CLASS (object_class), + _clutter_marshal_VOID__BOXED_FLAGSv); /** * ClutterActor::transitions-completed: @@ -8453,8 +8772,7 @@ clutter_actor_class_init (ClutterActorClass *klass) G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, 0, - NULL, NULL, - _clutter_marshal_VOID__VOID, + NULL, NULL, NULL, G_TYPE_NONE, 0); /** @@ -8482,6 +8800,9 @@ clutter_actor_class_init (ClutterActorClass *klass) G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_BOOLEAN); + g_signal_set_va_marshaller (actor_signals[TRANSITION_STOPPED], + G_TYPE_FROM_CLASS (object_class), + _clutter_marshal_VOID__STRING_BOOLEANv); /** * ClutterActor::touch-event: @@ -8505,6 +8826,9 @@ clutter_actor_class_init (ClutterActorClass *klass) _clutter_marshal_BOOLEAN__BOXED, G_TYPE_BOOLEAN, 1, CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); + g_signal_set_va_marshaller (actor_signals[TOUCH_EVENT], + G_TYPE_FROM_CLASS (object_class), + _clutter_marshal_BOOLEAN__BOXEDv); } static void @@ -8514,15 +8838,15 @@ clutter_actor_init (ClutterActor *self) self->priv = priv = clutter_actor_get_instance_private (self); - priv->pick_id = -1; - priv->opacity = 0xff; priv->show_on_set_parent = TRUE; + priv->resource_scale = -1.0f; priv->needs_width_request = TRUE; priv->needs_height_request = TRUE; priv->needs_allocation = TRUE; priv->needs_paint_volume_update = TRUE; + priv->needs_compute_resource_scale = TRUE; priv->cached_width_age = 1; priv->cached_height_age = 1; @@ -8616,8 +8940,7 @@ _clutter_actor_finish_queue_redraw (ClutterActor *self, ClutterPaintVolume *clip) { ClutterActorPrivate *priv = self->priv; - ClutterPaintVolume *pv; - gboolean clipped; + ClutterPaintVolume *pv = NULL; /* Remove queue entry early in the process, otherwise a new queue_redraw() during signal handling could put back this @@ -8644,8 +8967,7 @@ _clutter_actor_finish_queue_redraw (ClutterActor *self, */ if (clip) { - _clutter_actor_set_queue_redraw_clip (self, clip); - clipped = TRUE; + pv = clip; } else if (G_LIKELY (priv->last_paint_volume_valid)) { @@ -8655,36 +8977,12 @@ _clutter_actor_finish_queue_redraw (ClutterActor *self, ClutterActor *stage = _clutter_actor_get_stage_internal (self); /* make sure we redraw the actors old position... */ - _clutter_actor_set_queue_redraw_clip (stage, - &priv->last_paint_volume); - _clutter_actor_signal_queue_redraw (stage, stage); - _clutter_actor_set_queue_redraw_clip (stage, NULL); - - /* XXX: Ideally the redraw signal would take a clip volume - * argument, but that would be an ABI break. Until we can - * break the ABI we pass the argument out-of-band - */ - - /* setup the clip for the actors new position... */ - _clutter_actor_set_queue_redraw_clip (self, pv); - clipped = TRUE; + _clutter_actor_propagate_queue_redraw (stage, stage, + &priv->last_paint_volume); } - else - clipped = FALSE; } - else - clipped = FALSE; - - _clutter_actor_signal_queue_redraw (self, self); - /* Just in case anyone is manually firing redraw signals without - * using the public queue_redraw() API we are careful to ensure that - * our out-of-band clip member is cleared before returning... - * - * Note: A NULL clip denotes a full-stage, un-clipped redraw - */ - if (G_LIKELY (clipped)) - _clutter_actor_set_queue_redraw_clip (self, NULL); + _clutter_actor_propagate_queue_redraw (self, self, pv); } static void @@ -8714,15 +9012,14 @@ _clutter_actor_get_allocation_clip (ClutterActor *self, } void -_clutter_actor_queue_redraw_full (ClutterActor *self, - ClutterRedrawFlags flags, - ClutterPaintVolume *volume, - ClutterEffect *effect) +_clutter_actor_queue_redraw_full (ClutterActor *self, + ClutterRedrawFlags flags, + const ClutterPaintVolume *volume, + ClutterEffect *effect) { ClutterActorPrivate *priv = self->priv; ClutterPaintVolume allocation_pv; - ClutterPaintVolume *pv; - gboolean should_free_pv; + ClutterPaintVolume *pv = NULL; ClutterActor *stage; /* Here's an outline of the actor queue redraw mechanism: @@ -8774,9 +9071,9 @@ _clutter_actor_queue_redraw_full (ClutterActor *self, * * later during _clutter_stage_do_update(), once relayouting is done * and the scenegraph has been updated we will call: - * _clutter_stage_finish_queue_redraws(). + * clutter_stage_maybe_finish_queue_redraws(). * - * _clutter_stage_finish_queue_redraws() will call + * clutter_stage_maybe_finish_queue_redraws() will call * _clutter_actor_finish_queue_redraw() for each listed actor. * * Note: actors *are* allowed to queue further redraws during this @@ -8837,7 +9134,7 @@ _clutter_actor_queue_redraw_full (ClutterActor *self, if (flags & CLUTTER_REDRAW_CLIPPED_TO_ALLOCATION) { ClutterActorBox allocation_clip; - ClutterVertex origin; + graphene_point3d_t origin; /* If the actor doesn't have a valid allocation then we will * queue a full stage redraw. */ @@ -8845,8 +9142,7 @@ _clutter_actor_queue_redraw_full (ClutterActor *self, { /* NB: NULL denotes an undefined clip which will result in a * full redraw... */ - _clutter_actor_set_queue_redraw_clip (self, NULL); - _clutter_actor_signal_queue_redraw (self, self); + _clutter_actor_propagate_queue_redraw (self, self, NULL); return; } @@ -8864,22 +9160,15 @@ _clutter_actor_queue_redraw_full (ClutterActor *self, clutter_paint_volume_set_height (pv, allocation_clip.y2 - allocation_clip.y1); - should_free_pv = TRUE; - } - else - { - pv = volume; - should_free_pv = FALSE; - self->priv->needs_paint_volume_update = TRUE; } self->priv->queue_redraw_entry = _clutter_stage_queue_actor_redraw (CLUTTER_STAGE (stage), priv->queue_redraw_entry, self, - pv); + pv ? pv : volume); - if (should_free_pv) + if (pv) clutter_paint_volume_free (pv); /* If this is the first redraw queued then we can directly use the @@ -8993,9 +9282,9 @@ clutter_actor_queue_redraw (ClutterActor *self) * picking of your actor. */ void -_clutter_actor_queue_redraw_with_clip (ClutterActor *self, - ClutterRedrawFlags flags, - ClutterPaintVolume *volume) +_clutter_actor_queue_redraw_with_clip (ClutterActor *self, + ClutterRedrawFlags flags, + const ClutterPaintVolume *volume) { _clutter_actor_queue_redraw_full (self, flags, /* flags */ @@ -9016,7 +9305,7 @@ _clutter_actor_queue_only_relayout (ClutterActor *self) priv->needs_allocation) return; /* save some cpu cycles */ -#if CLUTTER_ENABLE_DEBUG +#ifdef CLUTTER_ENABLE_DEBUG if (!CLUTTER_ACTOR_IS_TOPLEVEL (self) && CLUTTER_ACTOR_IN_RELAYOUT (self)) { g_warning ("The actor '%s' is currently inside an allocation " @@ -9049,7 +9338,7 @@ clutter_actor_queue_redraw_with_clip (ClutterActor *self, const cairo_rectangle_int_t *clip) { ClutterPaintVolume volume; - ClutterVertex origin; + graphene_point3d_t origin; g_return_if_fail (CLUTTER_IS_ACTOR (self)); @@ -9517,6 +9806,25 @@ clutter_actor_get_preferred_width (ClutterActor *self, return; } + /* if the request mode is CONTENT_SIZE we simply return the content width */ + if (priv->request_mode == CLUTTER_REQUEST_CONTENT_SIZE) + { + float content_width = 0.f; + + if (priv->content != NULL) + clutter_content_get_preferred_size (priv->content, &content_width, NULL); + + if (min_width_p != NULL) + *min_width_p = content_width; + + if (natural_width_p != NULL) + *natural_width_p = content_width; + + return; + } + + CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_IN_PREF_WIDTH); + /* the remaining cases are: * * - either min_width or natural_width have been set @@ -9608,6 +9916,8 @@ clutter_actor_get_preferred_width (ClutterActor *self, if (natural_width_p) *natural_width_p = request_natural_width; + + CLUTTER_UNSET_PRIVATE_FLAGS (self, CLUTTER_IN_PREF_WIDTH); } /** @@ -9661,6 +9971,25 @@ clutter_actor_get_preferred_height (ClutterActor *self, return; } + /* if the request mode is CONTENT_SIZE we simply return the content height */ + if (priv->request_mode == CLUTTER_REQUEST_CONTENT_SIZE) + { + float content_height = 0.f; + + if (priv->content != NULL) + clutter_content_get_preferred_size (priv->content, NULL, &content_height); + + if (min_height_p != NULL) + *min_height_p = content_height; + + if (natural_height_p != NULL) + *natural_height_p = content_height; + + return; + } + + CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_IN_PREF_HEIGHT); + /* the remaining cases are: * * - either min_height or natural_height have been set @@ -9751,6 +10080,8 @@ clutter_actor_get_preferred_height (ClutterActor *self, if (natural_height_p) *natural_height_p = request_natural_height; + + CLUTTER_UNSET_PRIVATE_FLAGS (self, CLUTTER_IN_PREF_HEIGHT); } /** @@ -10032,11 +10363,19 @@ clutter_actor_allocate (ClutterActor *self, return; } + if (!clutter_actor_is_visible (self)) + return; + priv = self->priv; old_allocation = priv->allocation; real_allocation = *box; + g_return_if_fail (!isnan (real_allocation.x1) && + !isnan (real_allocation.x2) && + !isnan (real_allocation.y1) && + !isnan (real_allocation.y2)); + /* constraints are allowed to modify the allocation only here; we do * this prior to all the other checks so that we can bail out if the * allocation did not change @@ -10093,6 +10432,9 @@ clutter_actor_allocate (ClutterActor *self, if (CLUTTER_ACTOR_IS_MAPPED (self)) self->priv->needs_paint_volume_update = TRUE; + if (stage_allocation_changed) + priv->needs_compute_resource_scale = TRUE; + if (!stage_allocation_changed) { /* If the actor didn't move but needs_allocation is set, we just @@ -10262,19 +10604,20 @@ clutter_actor_set_position (ClutterActor *self, gfloat x, gfloat y) { - ClutterPoint new_position; - ClutterPoint cur_position; + graphene_point_t new_position; + graphene_point_t cur_position; g_return_if_fail (CLUTTER_IS_ACTOR (self)); - clutter_point_init (&new_position, x, y); + graphene_point_init (&new_position, x, y); cur_position.x = clutter_actor_get_x (self); cur_position.y = clutter_actor_get_y (self); - _clutter_actor_create_transition (self, obj_props[PROP_POSITION], - &cur_position, - &new_position); + if (!graphene_point_equal (&cur_position, &new_position)) + _clutter_actor_create_transition (self, obj_props[PROP_POSITION], + &cur_position, + &new_position); } /** @@ -10706,8 +11049,8 @@ clutter_actor_set_height_internal (ClutterActor *self, } static void -clutter_actor_set_size_internal (ClutterActor *self, - const ClutterSize *size) +clutter_actor_set_size_internal (ClutterActor *self, + const graphene_size_t *size) { if (size != NULL) { @@ -10743,11 +11086,11 @@ clutter_actor_set_size (ClutterActor *self, gfloat width, gfloat height) { - ClutterSize new_size; + graphene_size_t new_size; g_return_if_fail (CLUTTER_IS_ACTOR (self)); - clutter_size_init (&new_size, width, height); + graphene_size_init (&new_size, width, height); /* minor optimization: if we don't have a duration then we can * skip the get_size() below, to avoid the chance of going through @@ -10766,11 +11109,11 @@ clutter_actor_set_size (ClutterActor *self, } else { - ClutterSize cur_size; + graphene_size_t cur_size; - clutter_size_init (&cur_size, - clutter_actor_get_width (self), - clutter_actor_get_height (self)); + graphene_size_init (&cur_size, + clutter_actor_get_width (self), + clutter_actor_get_height (self)); _clutter_actor_create_transition (self, obj_props[PROP_SIZE], @@ -10856,8 +11199,8 @@ clutter_actor_get_transformed_position (ClutterActor *self, gfloat *x, gfloat *y) { - ClutterVertex v1; - ClutterVertex v2; + graphene_point3d_t v1; + graphene_point3d_t v2; v1.x = v1.y = v1.z = 0; clutter_actor_apply_transform_to_point (self, &v1, &v2); @@ -10903,7 +11246,7 @@ clutter_actor_get_transformed_size (ClutterActor *self, gfloat *height) { ClutterActorPrivate *priv; - ClutterVertex v[4]; + graphene_point3d_t v[4]; gfloat x_min, x_max, y_min, y_max; gint i; @@ -11178,25 +11521,6 @@ clutter_actor_set_height (ClutterActor *self, height); } -static void -_clutter_actor_maybe_queue_relayout (ClutterActor *self) -{ - ClutterActorPrivate *priv = self->priv; - ClutterActor *stage = _clutter_actor_get_stage_internal (self); - - if (priv->parent && - (priv->parent->flags & CLUTTER_ACTOR_NO_LAYOUT) && - CLUTTER_IS_ACTOR (stage)) - { - clutter_actor_allocate_preferred_size (self, CLUTTER_ALLOCATION_NONE); - clutter_actor_queue_redraw (self); - } - else - { - clutter_actor_queue_relayout (self); - } -} - static inline void clutter_actor_set_x_internal (ClutterActor *self, float x) @@ -11217,7 +11541,7 @@ clutter_actor_set_x_internal (ClutterActor *self, clutter_actor_notify_if_geometry_changed (self, &old); - _clutter_actor_maybe_queue_relayout (self); + clutter_actor_queue_relayout (self); } static inline void @@ -11240,12 +11564,12 @@ clutter_actor_set_y_internal (ClutterActor *self, clutter_actor_notify_if_geometry_changed (self, &old); - _clutter_actor_maybe_queue_relayout (self); + clutter_actor_queue_relayout (self); } static void -clutter_actor_set_position_internal (ClutterActor *self, - const ClutterPoint *position) +clutter_actor_set_position_internal (ClutterActor *self, + const graphene_point_t *position) { ClutterActorPrivate *priv = self->priv; ClutterLayoutInfo *linfo; @@ -11254,7 +11578,7 @@ clutter_actor_set_position_internal (ClutterActor *self, linfo = _clutter_actor_get_layout_info (self); if (priv->position_set && - clutter_point_equals (position, &linfo->fixed_pos)) + graphene_point_equal (position, &linfo->fixed_pos)) return; clutter_actor_store_old_geometry (self, &old); @@ -11269,7 +11593,7 @@ clutter_actor_set_position_internal (ClutterActor *self, clutter_actor_notify_if_geometry_changed (self, &old); - _clutter_actor_maybe_queue_relayout (self); + clutter_actor_queue_relayout (self); } /** @@ -11339,8 +11663,7 @@ clutter_actor_set_y (ClutterActor *self, * the X coordinate of the origin of the allocation box. * * If the actor has any fixed coordinate set using clutter_actor_set_x(), - * clutter_actor_set_position() or clutter_actor_set_geometry(), this - * function will return that coordinate. + * clutter_actor_set_position(), this function will return that coordinate. * * If both the allocation and a fixed position are missing, this function * will return 0. @@ -11387,8 +11710,7 @@ clutter_actor_get_x (ClutterActor *self) * the Y coordinate of the origin of the allocation box. * * If the actor has any fixed coordinate set using clutter_actor_set_y(), - * clutter_actor_set_position() or clutter_actor_set_geometry(), this - * function will return that coordinate. + * clutter_actor_set_position(), this function will return that coordinate. * * If both the allocation and a fixed position are missing, this function * will return 0. @@ -11513,45 +11835,6 @@ clutter_actor_set_scale_full (ClutterActor *self, g_object_thaw_notify (G_OBJECT (self)); } -/** - * clutter_actor_set_scale_with_gravity: - * @self: A #ClutterActor - * @scale_x: double factor to scale actor by horizontally. - * @scale_y: double factor to scale actor by vertically. - * @gravity: the location of the scale center expressed as a compass - * direction. - * - * Scales an actor with the given factors around the given - * center point. The center point is specified as one of the compass - * directions in #ClutterGravity. For example, setting it to north - * will cause the top of the actor to remain unchanged and the rest of - * the actor to expand left, right and downwards. - * - * The #ClutterActor:scale-x and #ClutterActor:scale-y properties are - * animatable. - * - * Since: 1.0 - * - * Deprecated: 1.12: Use clutter_actor_set_pivot_point() to set the - * scale center using normalized coordinates instead. - */ -void -clutter_actor_set_scale_with_gravity (ClutterActor *self, - gdouble scale_x, - gdouble scale_y, - ClutterGravity gravity) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - g_object_freeze_notify (G_OBJECT (self)); - - clutter_actor_set_scale_factor (self, CLUTTER_X_AXIS, scale_x); - clutter_actor_set_scale_factor (self, CLUTTER_Y_AXIS, scale_y); - clutter_actor_set_scale_gravity (self, gravity); - - g_object_thaw_notify (G_OBJECT (self)); -} - /** * clutter_actor_get_scale: * @self: A #ClutterActor @@ -11919,7 +12202,7 @@ clutter_actor_set_name (ClutterActor *self, { g_return_if_fail (CLUTTER_IS_ACTOR (self)); - free (self->priv->name); + g_free (self->priv->name); self->priv->name = g_strdup (name); g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_NAME]); @@ -11942,30 +12225,9 @@ clutter_actor_get_name (ClutterActor *self) return self->priv->name; } -/** - * clutter_actor_get_gid: - * @self: A #ClutterActor - * - * Retrieves the unique id for @self. - * - * Return value: Globally unique value for this object instance. - * - * Since: 0.6 - * - * Deprecated: 1.8: The id is not used any longer, and this function - * always returns 0. - */ -guint32 -clutter_actor_get_gid (ClutterActor *self) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), 0); - - return 0; -} - -static inline void -clutter_actor_set_depth_internal (ClutterActor *self, - float depth) +static inline void +clutter_actor_set_depth_internal (ClutterActor *self, + float depth) { ClutterTransformInfo *info; @@ -12073,7 +12335,7 @@ clutter_actor_set_pivot_point (ClutterActor *self, gfloat pivot_x, gfloat pivot_y) { - ClutterPoint pivot = CLUTTER_POINT_INIT (pivot_x, pivot_y); + graphene_point_t pivot = GRAPHENE_POINT_INIT (pivot_x, pivot_y); const ClutterTransformInfo *info; g_return_if_fail (CLUTTER_IS_ACTOR (self)); @@ -12234,7 +12496,7 @@ clutter_actor_set_rotation (ClutterActor *self, gfloat y, gfloat z) { - ClutterVertex v; + graphene_point3d_t v; g_return_if_fail (CLUTTER_IS_ACTOR (self)); @@ -12431,7 +12693,6 @@ clutter_actor_set_clip (ClutterActor *self, clutter_actor_queue_redraw (self); - g_object_notify_by_pspec (obj, obj_props[PROP_CLIP]); g_object_notify_by_pspec (obj, obj_props[PROP_CLIP_RECT]); g_object_notify_by_pspec (obj, obj_props[PROP_HAS_CLIP]); } @@ -12773,7 +13034,8 @@ typedef void (* ClutterActorAddChildFunc) (ClutterActor *parent, ClutterActor *child, gpointer data); -typedef enum { +typedef enum +{ ADD_CHILD_CREATE_META = 1 << 0, ADD_CHILD_EMIT_PARENT_SET = 1 << 1, ADD_CHILD_EMIT_ACTOR_ADDED = 1 << 2, @@ -12930,11 +13192,8 @@ clutter_actor_add_child_internal (ClutterActor *self, self->priv->age += 1; - /* if push_internal() has been called then we automatically set - * the flag on the actor - */ - if (self->priv->internal_child) - CLUTTER_SET_PRIVATE_FLAGS (child, CLUTTER_INTERNAL_CHILD); + if (self->priv->in_cloned_branch) + clutter_actor_push_in_cloned_branch (child, self->priv->in_cloned_branch); /* children may cause their parent to expand, if they are set * to expand; if a child is not expanded then it cannot change @@ -12953,9 +13212,11 @@ clutter_actor_add_child_internal (ClutterActor *self, clutter_actor_queue_compute_expand (self); } - /* clutter_actor_reparent() will emit ::parent-set for us */ if (emit_parent_set && !CLUTTER_ACTOR_IN_REPARENT (child)) - g_signal_emit (child, actor_signals[PARENT_SET], 0, NULL); + { + child->priv->needs_compute_resource_scale = TRUE; + g_signal_emit (child, actor_signals[PARENT_SET], 0, NULL); + } if (check_state) { @@ -12988,9 +13249,7 @@ clutter_actor_add_child_internal (ClutterActor *self, /* maintain the invariant that if an actor needs layout, * its parents do as well */ - if (child->priv->needs_width_request || - child->priv->needs_height_request || - child->priv->needs_allocation) + if (clutter_actor_needs_relayout (child)) { /* we work around the short-circuiting we do * in clutter_actor_queue_relayout() since we @@ -13011,7 +13270,7 @@ clutter_actor_add_child_internal (ClutterActor *self, } if (emit_actor_added) - g_signal_emit_by_name (self, "actor-added", child); + _clutter_container_emit_actor_added (CLUTTER_CONTAINER (self), child); if (notify_first_last) { @@ -13473,104 +13732,6 @@ clutter_actor_unparent (ClutterActor *self) REMOVE_CHILD_LEGACY_FLAGS); } -/** - * clutter_actor_reparent: - * @self: a #ClutterActor - * @new_parent: the new #ClutterActor parent - * - * Resets the parent actor of @self. - * - * This function is logically equivalent to calling clutter_actor_unparent() - * and clutter_actor_set_parent(), but more efficiently implemented, as it - * ensures the child is not finalized when unparented, and emits the - * #ClutterActor::parent-set signal only once. - * - * In reality, calling this function is less useful than it sounds, as some - * application code may rely on changes in the intermediate state between - * removal and addition of the actor from its old parent to the @new_parent. - * Thus, it is strongly encouraged to avoid using this function in application - * code. - * - * Since: 0.2 - * - * Deprecated: 1.10: Use clutter_actor_remove_child() and - * clutter_actor_add_child() instead; remember to take a reference on - * the actor being removed before calling clutter_actor_remove_child() - * to avoid the reference count dropping to zero and the actor being - * destroyed. - */ -void -clutter_actor_reparent (ClutterActor *self, - ClutterActor *new_parent) -{ - ClutterActorPrivate *priv; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (CLUTTER_IS_ACTOR (new_parent)); - g_return_if_fail (self != new_parent); - - if (CLUTTER_ACTOR_IS_TOPLEVEL (self)) - { - g_warning ("Cannot set a parent on a toplevel actor"); - return; - } - - if (CLUTTER_ACTOR_IN_DESTRUCTION (self)) - { - g_warning ("Cannot set a parent currently being destroyed"); - return; - } - - priv = self->priv; - - if (priv->parent != new_parent) - { - ClutterActor *old_parent; - - CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_IN_REPARENT); - - old_parent = priv->parent; - - g_object_ref (self); - - if (old_parent != NULL) - { - /* go through the Container implementation if this is a regular - * child and not an internal one - */ - if (!CLUTTER_ACTOR_IS_INTERNAL_CHILD (self)) - { - ClutterContainer *parent = CLUTTER_CONTAINER (old_parent); - - /* this will have to call unparent() */ - clutter_container_remove_actor (parent, self); - } - else - clutter_actor_remove_child_internal (old_parent, self, - REMOVE_CHILD_LEGACY_FLAGS); - } - - /* Note, will call set_parent() */ - if (!CLUTTER_ACTOR_IS_INTERNAL_CHILD (self)) - clutter_container_add_actor (CLUTTER_CONTAINER (new_parent), self); - else - clutter_actor_add_child_internal (new_parent, self, - ADD_CHILD_LEGACY_FLAGS, - insert_child_at_depth, - NULL); - - /* we emit the ::parent-set signal once */ - g_signal_emit (self, actor_signals[PARENT_SET], 0, old_parent); - - CLUTTER_UNSET_PRIVATE_FLAGS (self, CLUTTER_IN_REPARENT); - - /* the IN_REPARENT flag suspends state updates */ - clutter_actor_update_map_state (self, MAP_STATE_CHECK); - - g_object_unref (self); - } -} - /** * clutter_actor_contains: * @self: A #ClutterActor @@ -13649,7 +13810,7 @@ clutter_actor_set_child_above_sibling (ClutterActor *self, sibling); g_object_unref(child); - clutter_actor_queue_relayout (self); + clutter_actor_queue_redraw_on_parent (child); } /** @@ -13696,7 +13857,7 @@ clutter_actor_set_child_below_sibling (ClutterActor *self, sibling); g_object_unref(child); - clutter_actor_queue_relayout (self); + clutter_actor_queue_redraw_on_parent (child); } /** @@ -13738,134 +13899,6 @@ clutter_actor_set_child_at_index (ClutterActor *self, clutter_actor_queue_relayout (self); } -/** - * clutter_actor_raise: - * @self: A #ClutterActor - * @below: (allow-none): A #ClutterActor to raise above. - * - * Puts @self above @below. - * - * Both actors must have the same parent, and the parent must implement - * the #ClutterContainer interface - * - * This function calls clutter_container_raise_child() internally. - * - * Deprecated: 1.10: Use clutter_actor_set_child_above_sibling() instead. - */ -void -clutter_actor_raise (ClutterActor *self, - ClutterActor *below) -{ - ClutterActor *parent; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - parent = clutter_actor_get_parent (self); - if (parent == NULL) - { - g_warning ("%s: Actor '%s' is not inside a container", - G_STRFUNC, - _clutter_actor_get_debug_name (self)); - return; - } - - if (below != NULL) - { - if (parent != clutter_actor_get_parent (below)) - { - g_warning ("%s Actor '%s' is not in the same container as " - "actor '%s'", - G_STRFUNC, - _clutter_actor_get_debug_name (self), - _clutter_actor_get_debug_name (below)); - return; - } - } - - clutter_container_raise_child (CLUTTER_CONTAINER (parent), self, below); -} - -/** - * clutter_actor_lower: - * @self: A #ClutterActor - * @above: (allow-none): A #ClutterActor to lower below - * - * Puts @self below @above. - * - * Both actors must have the same parent, and the parent must implement - * the #ClutterContainer interface. - * - * This function calls clutter_container_lower_child() internally. - * - * Deprecated: 1.10: Use clutter_actor_set_child_below_sibling() instead. - */ -void -clutter_actor_lower (ClutterActor *self, - ClutterActor *above) -{ - ClutterActor *parent; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - parent = clutter_actor_get_parent (self); - if (parent == NULL) - { - g_warning ("%s: Actor of type %s is not inside a container", - G_STRFUNC, - _clutter_actor_get_debug_name (self)); - return; - } - - if (above) - { - if (parent != clutter_actor_get_parent (above)) - { - g_warning ("%s: Actor '%s' is not in the same container as " - "actor '%s'", - G_STRFUNC, - _clutter_actor_get_debug_name (self), - _clutter_actor_get_debug_name (above)); - return; - } - } - - clutter_container_lower_child (CLUTTER_CONTAINER (parent), self, above); -} - -/** - * clutter_actor_raise_top: - * @self: A #ClutterActor - * - * Raises @self to the top. - * - * This function calls clutter_actor_raise() internally. - * - * Deprecated: 1.10: Use clutter_actor_set_child_above_sibling() with - * a %NULL sibling, instead. - */ -void -clutter_actor_raise_top (ClutterActor *self) -{ - clutter_actor_raise (self, NULL); -} - -/** - * clutter_actor_lower_bottom: - * @self: A #ClutterActor - * - * Lowers @self to the bottom. - * - * This function calls clutter_actor_lower() internally. - * - * Deprecated: 1.10: Use clutter_actor_set_child_below_sibling() with - * a %NULL sibling, instead. - */ -void -clutter_actor_lower_bottom (ClutterActor *self) -{ - clutter_actor_lower (self, NULL); -} - /* * Event handling */ @@ -13901,8 +13934,78 @@ clutter_actor_event (ClutterActor *actor, if (capture) { - g_signal_emit (actor, actor_signals[CAPTURED_EVENT], 0, - event, + GQuark detail = 0; + + switch (event->type) + { + case CLUTTER_NOTHING: + break; + case CLUTTER_KEY_PRESS: + case CLUTTER_KEY_RELEASE: + detail = quark_key; + break; + case CLUTTER_MOTION: + detail = quark_motion; + break; + case CLUTTER_ENTER: + case CLUTTER_LEAVE: + detail = quark_pointer_focus; + break; + case CLUTTER_BUTTON_PRESS: + case CLUTTER_BUTTON_RELEASE: + detail = quark_button; + break; + case CLUTTER_SCROLL: + detail = quark_scroll; + break; + case CLUTTER_STAGE_STATE: + detail = quark_stage; + break; + case CLUTTER_DESTROY_NOTIFY: + detail = quark_destroy; + break; + case CLUTTER_CLIENT_MESSAGE: + detail = quark_client; + break; + case CLUTTER_DELETE: + detail = quark_delete; + break; + case CLUTTER_TOUCH_BEGIN: + case CLUTTER_TOUCH_UPDATE: + case CLUTTER_TOUCH_END: + case CLUTTER_TOUCH_CANCEL: + detail = quark_touch; + break; + case CLUTTER_TOUCHPAD_PINCH: + case CLUTTER_TOUCHPAD_SWIPE: + detail = quark_touchpad; + break; + case CLUTTER_PROXIMITY_IN: + case CLUTTER_PROXIMITY_OUT: + detail = quark_proximity; + break; + case CLUTTER_PAD_BUTTON_PRESS: + case CLUTTER_PAD_BUTTON_RELEASE: + case CLUTTER_PAD_STRIP: + case CLUTTER_PAD_RING: + detail = quark_pad; + break; + case CLUTTER_IM_COMMIT: + case CLUTTER_IM_DELETE: + case CLUTTER_IM_PREEDIT: + detail = quark_im; + break; + case CLUTTER_DEVICE_ADDED: + case CLUTTER_DEVICE_REMOVED: + break; + case CLUTTER_EVENT_LAST: /* Just keep compiler warnings quiet */ + break; + } + + g_signal_emit (actor, + actor_signals[CAPTURED_EVENT], + detail, + event, &retval); goto out; } @@ -13948,6 +14051,9 @@ clutter_actor_event (ClutterActor *actor, case CLUTTER_DELETE: case CLUTTER_DESTROY_NOTIFY: case CLUTTER_CLIENT_MESSAGE: + case CLUTTER_IM_COMMIT: + case CLUTTER_IM_DELETE: + case CLUTTER_IM_PREEDIT: default: signal_num = -1; break; @@ -14008,34 +14114,6 @@ clutter_actor_get_reactive (ClutterActor *actor) return CLUTTER_ACTOR_IS_REACTIVE (actor) ? TRUE : FALSE; } -/** - * clutter_actor_get_anchor_point: - * @self: a #ClutterActor - * @anchor_x: (out): return location for the X coordinate of the anchor point - * @anchor_y: (out): return location for the Y coordinate of the anchor point - * - * Gets the current anchor point of the @actor in pixels. - * - * Since: 0.6 - * - * Deprecated: 1.12: Use #ClutterActor:pivot-point instead - */ -void -clutter_actor_get_anchor_point (ClutterActor *self, - gfloat *anchor_x, - gfloat *anchor_y) -{ - const ClutterTransformInfo *info; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - info = _clutter_actor_get_transform_info_or_defaults (self); - clutter_anchor_coord_get_units (self, &info->anchor, - anchor_x, - anchor_y, - NULL); -} - /** * clutter_actor_set_anchor_point: * @self: a #ClutterActor @@ -14138,7 +14216,7 @@ clutter_actor_get_anchor_point_gravity (ClutterActor *self) * * Since: 0.6 * - * Deprecated: 1.12: Use #ClutterActor:pivot-point and + * Deprecated: 1.12: Use #ClutterActor:pivot-point and * clutter_actor_set_translation() instead. */ void @@ -14186,7 +14264,7 @@ clutter_actor_move_anchor_point (ClutterActor *self, * * Since: 0.6 * - * Deprecated: 1.12: Use #ClutterActor:pivot-point and + * Deprecated: 1.12: Use #ClutterActor:pivot-point and * clutter_actor_set_translation() instead. */ void @@ -14238,7 +14316,7 @@ clutter_actor_move_anchor_point_from_gravity (ClutterActor *self, * * Since: 0.6 * - * Deprecated: 1.12: Use #ClutterActor:pivot-point and + * Deprecated: 1.12: Use #ClutterActor:pivot-point and * clutter_actor_set_translation() instead. E.g. For %CLUTTER_GRAVITY_CENTER set * pivot_point to (0.5,0.5) and the translation to (width/2,height/2). */ @@ -14550,40 +14628,6 @@ parse_actor_metas (ClutterScript *script, return g_slist_reverse (retval); } -static GSList * -parse_behaviours (ClutterScript *script, - ClutterActor *actor, - JsonNode *node) -{ - GList *elements, *l; - GSList *retval = NULL; - - if (!JSON_NODE_HOLDS_ARRAY (node)) - return NULL; - - elements = json_array_get_elements (json_node_get_array (node)); - - for (l = elements; l != NULL; l = l->next) - { - JsonNode *element = l->data; - const gchar *id_ = _clutter_script_get_id_from_node (element); - GObject *behaviour; - - if (id_ == NULL || *id_ == '\0') - continue; - - behaviour = clutter_script_get_object (script, id_); - if (behaviour == NULL) - continue; - - retval = g_slist_prepend (retval, behaviour); - } - - g_list_free (elements); - - return g_slist_reverse (retval); -} - static ClutterMargin * parse_margin (ClutterActor *self, JsonNode *node) @@ -14699,24 +14743,6 @@ clutter_actor_parse_custom_node (ClutterScriptable *scriptable, else g_slice_free (RotationInfo, info); } - else if (strcmp (name, "behaviours") == 0) - { - GSList *l; - -#ifdef CLUTTER_ENABLE_DEBUG - if (G_UNLIKELY (_clutter_diagnostic_enabled ())) - _clutter_diagnostic_message ("The 'behaviours' key is deprecated " - "and it should not be used in newly " - "written ClutterScript definitions."); -#endif - - l = parse_behaviours (script, actor, node); - - g_value_init (value, G_TYPE_POINTER); - g_value_set_pointer (value, l); - - retval = TRUE; - } else if (strcmp (name, "actions") == 0 || strcmp (name, "constraints") == 0 || strcmp (name, "effects") == 0) @@ -14763,7 +14789,7 @@ clutter_actor_set_custom_property (ClutterScriptable *scriptable, name, tmp); - free (tmp); + g_free (tmp); } #endif /* CLUTTER_ENABLE_DEBUG */ @@ -14787,26 +14813,6 @@ clutter_actor_set_custom_property (ClutterScriptable *scriptable, return; } - if (strcmp (name, "behaviours") == 0) - { - GSList *behaviours, *l; - - if (!G_VALUE_HOLDS (value, G_TYPE_POINTER)) - return; - - behaviours = g_value_get_pointer (value); - for (l = behaviours; l != NULL; l = l->next) - { - ClutterBehaviour *behaviour = l->data; - - clutter_behaviour_apply (behaviour, actor); - } - - g_slist_free (behaviours); - - return; - } - if (strcmp (name, "actions") == 0 || strcmp (name, "constraints") == 0 || strcmp (name, "effects") == 0) @@ -14849,6 +14855,30 @@ clutter_scriptable_iface_init (ClutterScriptableIface *iface) iface->set_custom_property = clutter_actor_set_custom_property; } +static gboolean +get_layout_from_animation_property (ClutterActor *actor, + const gchar *name, + gchar **name_p) +{ + g_auto (GStrv) tokens = NULL; + + if (!g_str_has_prefix (name, "@layout")) + return FALSE; + + tokens = g_strsplit (name, ".", -1); + if (tokens == NULL || g_strv_length (tokens) != 2) + { + CLUTTER_NOTE (ANIMATION, "Invalid property name '%s'", + name + 1); + return FALSE; + } + + if (name_p != NULL) + *name_p = g_strdup (tokens[1]); + + return TRUE; +} + static ClutterActorMeta * get_meta_from_animation_property (ClutterActor *actor, const gchar *name, @@ -14911,19 +14941,32 @@ static GParamSpec * clutter_actor_find_property (ClutterAnimatable *animatable, const gchar *property_name) { + ClutterActor *actor = CLUTTER_ACTOR (animatable); ClutterActorMeta *meta = NULL; GObjectClass *klass = NULL; GParamSpec *pspec = NULL; gchar *p_name = NULL; + gboolean use_layout; - meta = get_meta_from_animation_property (CLUTTER_ACTOR (animatable), - property_name, - &p_name); + use_layout = get_layout_from_animation_property (actor, + property_name, + &p_name); + + if (!use_layout) + meta = get_meta_from_animation_property (actor, + property_name, + &p_name); if (meta != NULL) { klass = G_OBJECT_GET_CLASS (meta); + pspec = g_object_class_find_property (klass, p_name); + } + else if (use_layout) + { + klass = G_OBJECT_GET_CLASS (actor->priv->layout_manager); + pspec = g_object_class_find_property (klass, p_name); } else @@ -14933,7 +14976,7 @@ clutter_actor_find_property (ClutterAnimatable *animatable, pspec = g_object_class_find_property (klass, property_name); } - free (p_name); + g_free (p_name); return pspec; } @@ -14943,19 +14986,28 @@ clutter_actor_get_initial_state (ClutterAnimatable *animatable, const gchar *property_name, GValue *initial) { + ClutterActor *actor = CLUTTER_ACTOR (animatable); ClutterActorMeta *meta = NULL; gchar *p_name = NULL; + gboolean use_layout; + + use_layout = get_layout_from_animation_property (actor, + property_name, + &p_name); - meta = get_meta_from_animation_property (CLUTTER_ACTOR (animatable), - property_name, - &p_name); + if (!use_layout) + meta = get_meta_from_animation_property (actor, + property_name, + &p_name); if (meta != NULL) g_object_get_property (G_OBJECT (meta), p_name, initial); + else if (use_layout) + g_object_get_property (G_OBJECT (actor->priv->layout_manager), p_name, initial); else g_object_get_property (G_OBJECT (animatable), property_name, initial); - free (p_name); + g_free (p_name); } /* @@ -15104,12 +15156,21 @@ clutter_actor_set_final_state (ClutterAnimatable *animatable, ClutterActor *actor = CLUTTER_ACTOR (animatable); ClutterActorMeta *meta = NULL; gchar *p_name = NULL; + gboolean use_layout; + + use_layout = get_layout_from_animation_property (actor, + property_name, + &p_name); + + if (!use_layout) + meta = get_meta_from_animation_property (actor, + property_name, + &p_name); - meta = get_meta_from_animation_property (actor, - property_name, - &p_name); if (meta != NULL) g_object_set_property (G_OBJECT (meta), p_name, final); + else if (use_layout) + g_object_set_property (G_OBJECT (actor->priv->layout_manager), p_name, final); else { GObjectClass *obj_class = G_OBJECT_GET_CLASS (animatable); @@ -15129,11 +15190,11 @@ clutter_actor_set_final_state (ClutterAnimatable *animatable, } } - free (p_name); + g_free (p_name); } static void -clutter_animatable_iface_init (ClutterAnimatableIface *iface) +clutter_animatable_iface_init (ClutterAnimatableInterface *iface) { iface->find_property = clutter_actor_find_property; iface->get_initial_state = clutter_actor_get_initial_state; @@ -15175,7 +15236,7 @@ clutter_actor_transform_stage_point (ClutterActor *self, gfloat *x_out, gfloat *y_out) { - ClutterVertex v[4]; + graphene_point3d_t v[4]; double ST[3][3]; double RQ[3][3]; int du, dv; @@ -15198,9 +15259,8 @@ clutter_actor_transform_stage_point (ClutterActor *self, * http://www.cs.cmu.edu/~ph/src/texfund/ * * Our texture is a rectangle with origin [0, 0], so we are mapping from - * quad to rectangle only, which significantly simplifies things; the - * function calls have been unrolled, and most of the math is done in fixed - * point. + * quad to rectangle only, which significantly simplifies things. + * Function calls have been unrolled. */ clutter_actor_get_abs_allocation_vertices (self, v); @@ -15753,6 +15813,9 @@ clutter_actor_grab_key_focus (ClutterActor *self) g_return_if_fail (CLUTTER_IS_ACTOR (self)); + if (self->priv->has_key_focus) + return; + stage = _clutter_actor_get_stage_internal (self); if (stage != NULL) clutter_stage_set_key_focus (CLUTTER_STAGE (stage), self); @@ -15795,7 +15858,7 @@ update_pango_context (ClutterBackend *backend, pango_cairo_context_set_resolution (context, resolution); pango_font_description_free (font_desc); - free (font_name); + g_free (font_name); } /** @@ -15811,7 +15874,7 @@ update_pango_context (ClutterBackend *backend, * stored by the #ClutterBackend change. * * You can use the returned #PangoContext to create a #PangoLayout - * and render text using cogl_pango_render_layout() to reuse the + * and render text using cogl_pango_show_layout() to reuse the * glyphs cache also used by Clutter. * * Return value: (transfer none): the #PangoContext for a #ClutterActor. @@ -15834,10 +15897,12 @@ clutter_actor_get_pango_context (ClutterActor *self) { priv->pango_context = clutter_actor_create_pango_context (self); - g_signal_connect_object (backend, "resolution-changed", - G_CALLBACK (update_pango_context), priv->pango_context, 0); - g_signal_connect_object (backend, "font-changed", - G_CALLBACK (update_pango_context), priv->pango_context, 0); + priv->resolution_changed_id = + g_signal_connect_object (backend, "resolution-changed", + G_CALLBACK (update_pango_context), priv->pango_context, 0); + priv->font_changed_id = + g_signal_connect_object (backend, "font-changed", + G_CALLBACK (update_pango_context), priv->pango_context, 0); } else update_pango_context (backend, priv->pango_context); @@ -15961,7 +16026,64 @@ clutter_actor_get_opacity_override (ClutterActor *self) { g_return_val_if_fail (CLUTTER_IS_ACTOR (self), -1); - return self->priv->opacity_override; + return self->priv->opacity_override; +} + +/** + * clutter_actor_inhibit_culling: + * @actor: a #ClutterActor + * + * Increases the culling inhibitor counter. Inhibiting culling + * forces the actor to be painted even when outside the visible + * bounds of the stage view. + * + * This is usually necessary when an actor is being painted on + * another paint context. + * + * Pair with clutter_actor_uninhibit_culling() when the actor doesn't + * need to be painted anymore. + */ +void +clutter_actor_inhibit_culling (ClutterActor *actor) +{ + ClutterActorPrivate *priv; + + g_return_if_fail (CLUTTER_IS_ACTOR (actor)); + + priv = actor->priv; + + priv->inhibit_culling_counter++; + _clutter_actor_set_enable_paint_unmapped (actor, TRUE); +} + +/** + * clutter_actor_uninhibit_culling: + * @actor: a #ClutterActor + * + * Decreases the culling inhibitor counter. See clutter_actor_inhibit_culling() + * for when inhibit culling is necessary. + * + * Calling this function without a matching call to + * clutter_actor_inhibit_culling() is a programming error. + */ +void +clutter_actor_uninhibit_culling (ClutterActor *actor) +{ + ClutterActorPrivate *priv; + + g_return_if_fail (CLUTTER_IS_ACTOR (actor)); + + priv = actor->priv; + + if (priv->inhibit_culling_counter == 0) + { + g_critical ("Unpaired call to clutter_actor_uninhibit_culling"); + return; + } + + priv->inhibit_culling_counter--; + if (priv->inhibit_culling_counter == 0) + _clutter_actor_set_enable_paint_unmapped (actor, FALSE); } /* Allows you to disable applying the actors model view transform during @@ -16308,25 +16430,6 @@ clutter_actor_unset_flags (ClutterActor *self, g_object_thaw_notify (obj); } -/** - * clutter_actor_get_transformation_matrix: - * @self: a #ClutterActor - * @matrix: (out caller-allocates): the return location for a #ClutterMatrix - * - * Retrieves the transformations applied to @self relative to its - * parent. - * - * Since: 1.0 - * - * Deprecated: 1.12: Use clutter_actor_get_transform() instead - */ -void -clutter_actor_get_transformation_matrix (ClutterActor *self, - ClutterMatrix *matrix) -{ - clutter_actor_get_transform (self, matrix); -} - static void clutter_actor_set_transform_internal (ClutterActor *self, const ClutterMatrix *transform) @@ -16462,6 +16565,12 @@ clutter_actor_is_in_clone_paint (ClutterActor *self) return FALSE; } +gboolean +clutter_actor_has_damage (ClutterActor *actor) +{ + return actor->priv->is_dirty; +} + static gboolean set_direction_recursive (ClutterActor *actor, gpointer user_data) @@ -16534,6 +16643,23 @@ _clutter_actor_set_has_pointer (ClutterActor *self, } } +void +_clutter_actor_set_has_key_focus (ClutterActor *self, + gboolean has_key_focus) +{ + ClutterActorPrivate *priv = self->priv; + + if (priv->has_key_focus != has_key_focus) + { + priv->has_key_focus = has_key_focus; + + if (has_key_focus) + g_signal_emit (self, actor_signals[KEY_FOCUS_IN], 0); + else + g_signal_emit (self, actor_signals[KEY_FOCUS_OUT], 0); + } +} + /** * clutter_actor_get_text_direction: * @self: a #ClutterActor @@ -16565,100 +16691,6 @@ clutter_actor_get_text_direction (ClutterActor *self) return priv->text_direction; } -/** - * clutter_actor_push_internal: - * @self: a #ClutterActor - * - * Should be used by actors implementing the #ClutterContainer and with - * internal children added through clutter_actor_set_parent(), for instance: - * - * |[ - * static void - * my_actor_init (MyActor *self) - * { - * self->priv = my_actor_get_instance_private (self); - * - * clutter_actor_push_internal (CLUTTER_ACTOR (self)); - * - * // calling clutter_actor_set_parent() now will result in - * // the internal flag being set on a child of MyActor - * - * // internal child - a background texture - * self->priv->background_tex = clutter_texture_new (); - * clutter_actor_set_parent (self->priv->background_tex, - * CLUTTER_ACTOR (self)); - * - * // internal child - a label - * self->priv->label = clutter_text_new (); - * clutter_actor_set_parent (self->priv->label, - * CLUTTER_ACTOR (self)); - * - * clutter_actor_pop_internal (CLUTTER_ACTOR (self)); - * - * // calling clutter_actor_set_parent() now will not result in - * // the internal flag being set on a child of MyActor - * } - * ]| - * - * This function will be used by Clutter to toggle an "internal child" - * flag whenever clutter_actor_set_parent() is called; internal children - * are handled differently by Clutter, specifically when destroying their - * parent. - * - * Call clutter_actor_pop_internal() when you finished adding internal - * children. - * - * Nested calls to clutter_actor_push_internal() are allowed, but each - * one must by followed by a clutter_actor_pop_internal() call. - * - * Since: 1.2 - * - * Deprecated: 1.10: All children of an actor are accessible through - * the #ClutterActor API, and #ClutterActor implements the - * #ClutterContainer interface, so this function is only useful - * for legacy containers overriding the default implementation. - */ -void -clutter_actor_push_internal (ClutterActor *self) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - self->priv->internal_child += 1; -} - -/** - * clutter_actor_pop_internal: - * @self: a #ClutterActor - * - * Disables the effects of clutter_actor_push_internal(). - * - * Since: 1.2 - * - * Deprecated: 1.10: All children of an actor are accessible through - * the #ClutterActor API. This function is only useful for legacy - * containers overriding the default implementation of the - * #ClutterContainer interface. - */ -void -clutter_actor_pop_internal (ClutterActor *self) -{ - ClutterActorPrivate *priv; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - - priv = self->priv; - - if (priv->internal_child == 0) - { - g_warning ("Mismatched %s: you need to call " - "clutter_actor_push_composite() at least once before " - "calling this function", G_STRFUNC); - return; - } - - priv->internal_child -= 1; -} - /** * clutter_actor_has_pointer: * @self: a #ClutterActor @@ -16679,26 +16711,6 @@ clutter_actor_has_pointer (ClutterActor *self) return self->priv->has_pointer; } -/* XXX: This is a workaround for not being able to break the ABI of - * the QUEUE_REDRAW signal. It is an out-of-band argument. See - * clutter_actor_queue_clipped_redraw() for details. - */ -ClutterPaintVolume * -_clutter_actor_get_queue_redraw_clip (ClutterActor *self) -{ - return g_object_get_data (G_OBJECT (self), - "-clutter-actor-queue-redraw-clip"); -} - -void -_clutter_actor_set_queue_redraw_clip (ClutterActor *self, - ClutterPaintVolume *clip) -{ - g_object_set_data (G_OBJECT (self), - "-clutter-actor-queue-redraw-clip", - clip); -} - /** * clutter_actor_has_allocation: * @self: a #ClutterActor @@ -17402,15 +17414,9 @@ clutter_actor_clear_effects (ClutterActor *self) gboolean clutter_actor_has_key_focus (ClutterActor *self) { - ClutterActor *stage; - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); - stage = _clutter_actor_get_stage_internal (self); - if (stage == NULL) - return FALSE; - - return clutter_stage_get_key_focus (CLUTTER_STAGE (stage)) == self; + return self->priv->has_key_focus; } static gboolean @@ -17494,10 +17500,10 @@ _clutter_actor_get_paint_volume_real (ClutterActor *self, */ effects = _clutter_meta_group_peek_metas (priv->effects); for (l = effects; - l != NULL || (l != NULL && l->data != priv->current_effect); + l != NULL && l->data != priv->current_effect; l = l->next) { - if (!_clutter_effect_get_paint_volume (l->data, pv)) + if (!_clutter_effect_modify_paint_volume (l->data, pv)) { clutter_paint_volume_free (pv); CLUTTER_NOTE (CLIPPING, "Bail from get_paint_volume (%s): " @@ -17515,7 +17521,7 @@ _clutter_actor_get_paint_volume_real (ClutterActor *self, /* otherwise, get the cumulative volume */ effects = _clutter_meta_group_peek_metas (priv->effects); for (l = effects; l != NULL; l = l->next) - if (!_clutter_effect_get_paint_volume (l->data, pv)) + if (!_clutter_effect_modify_paint_volume (l->data, pv)) { clutter_paint_volume_free (pv); CLUTTER_NOTE (CLIPPING, "Bail from get_paint_volume (%s): " @@ -17530,6 +17536,32 @@ _clutter_actor_get_paint_volume_real (ClutterActor *self, return TRUE; } +static gboolean +_clutter_actor_has_active_paint_volume_override_effects (ClutterActor *self) +{ + const GList *l; + + if (self->priv->effects == NULL) + return FALSE; + + /* We just need to all effects current effect to see + * if anyone wants to override the paint volume. If so, then + * we need to recompute, since the paint volume returned can + * change from call to call. */ + for (l = _clutter_meta_group_peek_metas (self->priv->effects); + l != NULL; + l = l->next) + { + ClutterEffect *effect = l->data; + + if (clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)) && + _clutter_effect_has_custom_paint_volume (effect)) + return TRUE; + } + + return FALSE; +} + /* The public clutter_actor_get_paint_volume API returns a const * pointer since we return a pointer directly to the cached * PaintVolume associated with the actor and don't want the user to @@ -17540,17 +17572,33 @@ _clutter_actor_get_paint_volume_real (ClutterActor *self, static ClutterPaintVolume * _clutter_actor_get_paint_volume_mutable (ClutterActor *self) { + gboolean has_paint_volume_override_effects; ClutterActorPrivate *priv; priv = self->priv; + has_paint_volume_override_effects = _clutter_actor_has_active_paint_volume_override_effects (self); + if (priv->paint_volume_valid) { - if (!priv->needs_paint_volume_update) + /* If effects are applied, the actor paint volume + * needs to be recomputed on each paint, since those + * paint volumes could change over the duration of the + * effect. + * + * We also need to update the paint volume if we went + * from having effects to not having effects on the last + * paint volume update. */ + if (!priv->needs_paint_volume_update && + priv->current_effect == NULL && + !has_paint_volume_override_effects && + !priv->had_effects_on_last_paint_volume_update) return &priv->paint_volume; clutter_paint_volume_free (&priv->paint_volume); } + priv->had_effects_on_last_paint_volume_update = has_paint_volume_override_effects; + if (_clutter_actor_get_paint_volume_real (self, &priv->paint_volume)) { priv->paint_volume_valid = TRUE; @@ -17701,6 +17749,203 @@ clutter_actor_get_paint_box (ClutterActor *self, return TRUE; } +static gboolean +_clutter_actor_get_resource_scale_for_rect (ClutterActor *self, + graphene_rect_t *bounding_rect, + float *resource_scale) +{ + ClutterActor *stage; + float max_scale = 0; + + stage = _clutter_actor_get_stage_internal (self); + if (!stage) + return FALSE; + + if (!_clutter_stage_get_max_view_scale_factor_for_rect (CLUTTER_STAGE (stage), + bounding_rect, + &max_scale)) + return FALSE; + + *resource_scale = max_scale; + + return TRUE; +} + +static gboolean +_clutter_actor_compute_resource_scale (ClutterActor *self, + float *resource_scale) +{ + graphene_rect_t bounding_rect; + ClutterActorPrivate *priv = self->priv; + + if (CLUTTER_ACTOR_IN_DESTRUCTION (self) || + CLUTTER_ACTOR_IN_PREF_SIZE (self) || + !clutter_actor_is_mapped (self)) + { + return FALSE; + } + + clutter_actor_get_transformed_position (self, + &bounding_rect.origin.x, + &bounding_rect.origin.y); + clutter_actor_get_transformed_size (self, + &bounding_rect.size.width, + &bounding_rect.size.height); + + if (bounding_rect.size.width == 0.0 || + bounding_rect.size.height == 0.0 || + !_clutter_actor_get_resource_scale_for_rect (self, + &bounding_rect, + resource_scale)) + { + if (priv->parent) + { + gboolean in_clone_paint; + gboolean was_parent_in_clone_paint; + gboolean was_parent_unmapped; + gboolean was_parent_paint_unmapped; + gboolean ret; + + in_clone_paint = clutter_actor_is_in_clone_paint (self); + was_parent_unmapped = !clutter_actor_is_mapped (priv->parent); + was_parent_in_clone_paint = + clutter_actor_is_in_clone_paint (priv->parent); + was_parent_paint_unmapped = priv->parent->priv->enable_paint_unmapped; + + if (in_clone_paint && was_parent_unmapped) + { + _clutter_actor_set_in_clone_paint (priv->parent, TRUE); + _clutter_actor_set_enable_paint_unmapped (priv->parent, TRUE); + } + + ret = _clutter_actor_compute_resource_scale (priv->parent, + resource_scale); + + if (in_clone_paint && was_parent_unmapped) + { + _clutter_actor_set_in_clone_paint (priv->parent, + was_parent_in_clone_paint); + _clutter_actor_set_enable_paint_unmapped (priv->parent, + was_parent_paint_unmapped); + } + + return ret; + } + else + { + return FALSE; + } + } + + return TRUE; +} + +static ClutterActorTraverseVisitFlags +queue_update_resource_scale_cb (ClutterActor *actor, + int depth, + void *user_data) +{ + actor->priv->needs_compute_resource_scale = TRUE; + return CLUTTER_ACTOR_TRAVERSE_VISIT_CONTINUE; +} + +void +_clutter_actor_queue_update_resource_scale_recursive (ClutterActor *self) +{ + _clutter_actor_traverse (self, + CLUTTER_ACTOR_TRAVERSE_DEPTH_FIRST, + queue_update_resource_scale_cb, + NULL, + NULL); +} + +static gboolean +clutter_actor_update_resource_scale (ClutterActor *self) +{ + ClutterActorPrivate *priv; + float resource_scale; + float old_resource_scale; + priv = self->priv; + + g_return_val_if_fail (priv->needs_compute_resource_scale, FALSE); + + old_resource_scale = priv->resource_scale; + priv->resource_scale = -1.0f; + + if (_clutter_actor_compute_resource_scale (self, &resource_scale)) + { + priv->resource_scale = resource_scale; + priv->needs_compute_resource_scale = FALSE; + + return fabsf (old_resource_scale - resource_scale) > FLT_EPSILON; + } + + return FALSE; +} + +static void +clutter_actor_ensure_resource_scale (ClutterActor *self) +{ + ClutterActorPrivate *priv = self->priv; + + if (!priv->needs_compute_resource_scale) + return; + + if (clutter_actor_update_resource_scale (self)) + g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_RESOURCE_SCALE]); +} + +gboolean +_clutter_actor_get_real_resource_scale (ClutterActor *self, + gfloat *resource_scale) +{ + ClutterActorPrivate *priv = self->priv; + + clutter_actor_ensure_resource_scale (self); + + if (!priv->needs_compute_resource_scale) + { + *resource_scale = priv->resource_scale; + return TRUE; + } + + *resource_scale = -1.0f; + return FALSE; +} + +/** + * clutter_actor_get_resource_scale: + * @self: A #ClutterActor + * @resource_scale: (out): return location for the resource scale + * + * Retrieves the resource scale for this actor, if available. + * + * The resource scale refers to the scale the actor should use for its resources. + * For example if an actor draws a a picture of size 100 x 100 in the stage + * coordinate space, it should use a texture of twice the size (i.e. 200 x 200) + * if the resource scale is 2. + * + * The resource scale is determined by calculating the highest #ClutterStageView + * scale the actor will get painted on. + * + * Returns: TRUE if resource scale is set for the actor, otherwise FALSE + */ +gboolean +clutter_actor_get_resource_scale (ClutterActor *self, + gfloat *resource_scale) +{ + g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); + g_return_val_if_fail (resource_scale != NULL, FALSE); + + if (_clutter_actor_get_real_resource_scale (self, resource_scale)) + { + *resource_scale = ceilf (*resource_scale); + return TRUE; + } + + return FALSE; +} + /** * clutter_actor_has_overlaps: * @self: A #ClutterActor @@ -18106,13 +18351,13 @@ clutter_actor_get_layout_manager (ClutterActor *self) } static const ClutterLayoutInfo default_layout_info = { - CLUTTER_POINT_INIT_ZERO, /* fixed-pos */ + GRAPHENE_POINT_INIT_ZERO, /* fixed-pos */ { 0, 0, 0, 0 }, /* margin */ CLUTTER_ACTOR_ALIGN_FILL, /* x-align */ CLUTTER_ACTOR_ALIGN_FILL, /* y-align */ FALSE, FALSE, /* expand */ - CLUTTER_SIZE_INIT_ZERO, /* minimum */ - CLUTTER_SIZE_INIT_ZERO, /* natural */ + GRAPHENE_SIZE_INIT_ZERO, /* minimum */ + GRAPHENE_SIZE_INIT_ZERO, /* natural */ }; static void @@ -18988,9 +19233,9 @@ clutter_actor_iter_destroy (ClutterActorIter *iter) } static const ClutterAnimationInfo default_animation_info = { - NULL, /* transitions */ NULL, /* states */ NULL, /* cur_state */ + NULL, /* transitions */ }; static void @@ -19044,20 +19289,6 @@ _clutter_actor_get_animation_info (ClutterActor *self) return res; } -ClutterTransition * -_clutter_actor_get_transition (ClutterActor *actor, - GParamSpec *pspec) -{ - const ClutterAnimationInfo *info; - - info = _clutter_actor_get_animation_info_or_defaults (actor); - - if (info->transitions == NULL) - return NULL; - - return g_hash_table_lookup (info->transitions, pspec->name); -} - static void transition_closure_free (gpointer data) { @@ -19072,15 +19303,17 @@ transition_closure_free (gpointer data) * so that we don't end up inside on_transition_stopped() from * a call to g_hash_table_remove(). */ - g_signal_handler_disconnect (clos->transition, clos->completed_id); + g_clear_signal_handler (&clos->completed_id, clos->transition); if (clutter_timeline_is_playing (timeline)) clutter_timeline_stop (timeline); + else if (clutter_timeline_get_delay (timeline) > 0) + clutter_timeline_cancel_delay (timeline); /* remove the reference added in add_transition_internal() */ g_object_unref (clos->transition); - free (clos->name); + g_free (clos->name); g_slice_free (TransitionClosure, clos); } @@ -19110,15 +19343,8 @@ on_transition_stopped (ClutterTransition *transition, t_quark = g_quark_from_string (clos->name); t_name = g_strdup (clos->name); - if (clos->is_implicit || - clutter_transition_get_remove_on_complete (transition)) + if (clutter_transition_get_remove_on_complete (transition)) { - /* we take a reference here because removing the closure - * will release the reference on the transition, and we - * want the transition to survive the signal emission - */ - g_object_ref (transition); - /* this is safe, because the timeline has now stopped, * so we won't recurse; the reference on the Animatable * will be dropped by the ::stopped signal closure in @@ -19136,7 +19362,7 @@ on_transition_stopped (ClutterTransition *transition, t_name, is_finished); - free (t_name); + g_free (t_name); /* if it's the last transition then we clean up */ if (g_hash_table_size (info->transitions) == 0) @@ -19154,8 +19380,7 @@ on_transition_stopped (ClutterTransition *transition, static void clutter_actor_add_transition_internal (ClutterActor *self, const gchar *name, - ClutterTransition *transition, - gboolean is_implicit) + ClutterTransition *transition) { ClutterTimeline *timeline; TransitionClosure *clos; @@ -19185,7 +19410,6 @@ clutter_actor_add_transition_internal (ClutterActor *self, clos->actor = self; clos->transition = g_object_ref (transition); clos->name = g_strdup (name); - clos->is_implicit = is_implicit; clos->completed_id = g_signal_connect (timeline, "stopped", G_CALLBACK (on_transition_stopped), clos); @@ -19261,8 +19485,8 @@ _clutter_actor_create_transition (ClutterActor *actor, gboolean call_restore = FALSE; TransitionClosure *clos; va_list var_args; - GValue initial = G_VALUE_INIT; - GValue final = G_VALUE_INIT; + g_auto (GValue) initial = G_VALUE_INIT; + g_auto (GValue) final = G_VALUE_INIT; GType ptype; char *error; @@ -19301,7 +19525,7 @@ _clutter_actor_create_transition (ClutterActor *actor, if (error != NULL) { g_critical ("%s: %s", G_STRLOC, error); - free (error); + g_free (error); goto out; } @@ -19311,8 +19535,7 @@ _clutter_actor_create_transition (ClutterActor *actor, if (error != NULL) { g_critical ("%s: %s", G_STRLOC, error); - g_value_unset (&initial); - free (error); + g_free (error); goto out; } @@ -19333,9 +19556,6 @@ _clutter_actor_create_transition (ClutterActor *actor, &final, pspec); - g_value_unset (&initial); - g_value_unset (&final); - goto out; } @@ -19344,6 +19564,8 @@ _clutter_actor_create_transition (ClutterActor *actor, { res = clutter_property_transition_new (pspec->name); + clutter_transition_set_remove_on_complete (res, TRUE); + interval = clutter_interval_new_with_values (ptype, &initial, &final); clutter_transition_set_interval (res, interval); @@ -19371,19 +19593,16 @@ _clutter_actor_create_transition (ClutterActor *actor, info->cur_state->easing_delay, initial_v, final_v); - free (initial_v); - free (final_v); + g_free (initial_v); + g_free (final_v); } #endif /* CLUTTER_ENABLE_DEBUG */ /* this will start the transition as well */ - clutter_actor_add_transition_internal (actor, pspec->name, res, TRUE); + clutter_actor_add_transition_internal (actor, pspec->name, res); /* the actor now owns the transition */ g_object_unref (res); - - g_value_unset (&initial); - g_value_unset (&final); } else { @@ -19451,7 +19670,7 @@ clutter_actor_add_transition (ClutterActor *self, g_return_if_fail (name != NULL); g_return_if_fail (CLUTTER_IS_TRANSITION (transition)); - clutter_actor_add_transition_internal (self, name, transition, FALSE); + clutter_actor_add_transition_internal (self, name, transition); } /** @@ -19518,7 +19737,7 @@ clutter_actor_remove_transition (ClutterActor *self, FALSE); } - free (t_name); + g_free (t_name); } /** @@ -20740,29 +20959,31 @@ clutter_actor_get_child_transform (ClutterActor *self, } static void -clutter_actor_push_in_cloned_branch (ClutterActor *self) +clutter_actor_push_in_cloned_branch (ClutterActor *self, + gulong count) { ClutterActor *iter; for (iter = self->priv->first_child; iter != NULL; iter = iter->priv->next_sibling) - clutter_actor_push_in_cloned_branch (iter); + clutter_actor_push_in_cloned_branch (iter, count); - self->priv->in_cloned_branch += 1; + self->priv->in_cloned_branch += count; } static void -clutter_actor_pop_in_cloned_branch (ClutterActor *self) +clutter_actor_pop_in_cloned_branch (ClutterActor *self, + gulong count) { ClutterActor *iter; - self->priv->in_cloned_branch -= 1; + self->priv->in_cloned_branch -= count; for (iter = self->priv->first_child; iter != NULL; iter = iter->priv->next_sibling) - clutter_actor_pop_in_cloned_branch (iter); + clutter_actor_pop_in_cloned_branch (iter, count); } void @@ -20778,7 +20999,7 @@ _clutter_actor_attach_clone (ClutterActor *actor, g_hash_table_add (priv->clones, clone); - clutter_actor_push_in_cloned_branch (actor); + clutter_actor_push_in_cloned_branch (actor, 1); } void @@ -20793,7 +21014,7 @@ _clutter_actor_detach_clone (ClutterActor *actor, g_hash_table_lookup (priv->clones, clone) == NULL) return; - clutter_actor_pop_in_cloned_branch (actor); + clutter_actor_pop_in_cloned_branch (actor, 1); g_hash_table_remove (priv->clones, clone); @@ -20868,32 +21089,6 @@ clutter_actor_has_mapped_clones (ClutterActor *self) return FALSE; } -CoglFramebuffer * -_clutter_actor_get_active_framebuffer (ClutterActor *self) -{ - ClutterStage *stage; - - if (!CLUTTER_ACTOR_IN_PAINT (self)) - { - g_critical ("The active framebuffer of actor '%s' can only be " - "retrieved during the paint sequence. Please, check " - "your code.", - _clutter_actor_get_debug_name (self)); - return NULL; - } - - stage = (ClutterStage *) _clutter_actor_get_stage_internal (self); - if (stage == NULL) - { - g_critical ("The active framebuffer of actor '%s' is only available " - "if the actor is associated to a ClutterStage.", - _clutter_actor_get_debug_name (self)); - return NULL; - } - - return _clutter_stage_get_active_framebuffer (stage); -} - static void clutter_actor_child_model__items_changed (GListModel *model, guint position, @@ -21136,6 +21331,7 @@ clutter_actor_bind_model_with_properties (ClutterActor *self, model_property = va_arg (args, char *); } + va_end (args); clutter_actor_bind_model (self, model, bind_child_with_properties, clos, bind_closure_free); } @@ -21181,7 +21377,7 @@ clutter_actor_create_texture_paint_node (ClutterActor *self, color.alpha = clutter_actor_get_paint_opacity_internal (self); node = clutter_texture_node_new (texture, &color, priv->min_filter, priv->mag_filter); - clutter_paint_node_set_name (node, "Texture"); + clutter_paint_node_set_static_name (node, "Texture"); if (priv->content_repeat == CLUTTER_REPEAT_NONE) clutter_paint_node_add_rectangle (node, &box); @@ -21202,3 +21398,14 @@ clutter_actor_create_texture_paint_node (ClutterActor *self, return node; } + +gboolean +clutter_actor_has_accessible (ClutterActor *actor) +{ + g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), FALSE); + + if (CLUTTER_ACTOR_GET_CLASS (actor)->has_accessible) + return CLUTTER_ACTOR_GET_CLASS (actor)->has_accessible (actor); + + return TRUE; +} diff --git a/clutter/clutter/clutter-actor.h b/clutter/clutter/clutter-actor.h index 0c5a08c8c..a4140022e 100644 --- a/clutter/clutter/clutter-actor.h +++ b/clutter/clutter/clutter-actor.h @@ -39,6 +39,8 @@ #include #include +#include +#include G_BEGIN_DECLS @@ -61,7 +63,7 @@ G_BEGIN_DECLS * internal state. */ #define CLUTTER_ACTOR_SET_FLAGS(a,f) \ - CLUTTER_MACRO_DEPRECATED_IN_1_24 \ + CLUTTER_MACRO_DEPRECATED \ (((ClutterActor*)(a))->flags |= (f)) /** @@ -76,23 +78,23 @@ G_BEGIN_DECLS * internal state. */ #define CLUTTER_ACTOR_UNSET_FLAGS(a,f) \ - CLUTTER_MACRO_DEPRECATED_IN_1_24 \ + CLUTTER_MACRO_DEPRECATED \ (((ClutterActor*)(a))->flags &= ~(f)) #define CLUTTER_ACTOR_IS_MAPPED(a) \ - CLUTTER_MACRO_DEPRECATED_IN_1_24_FOR ("Deprecated macro. Use clutter_actor_is_mapped instead") \ + CLUTTER_MACRO_DEPRECATED_FOR ("Deprecated macro. Use clutter_actor_is_mapped instead") \ ((((ClutterActor*)(a))->flags & CLUTTER_ACTOR_MAPPED) != FALSE) #define CLUTTER_ACTOR_IS_REALIZED(a) \ - CLUTTER_MACRO_DEPRECATED_IN_1_24_FOR ("Deprecated macro. Use clutter_actor_is_realized instead") \ + CLUTTER_MACRO_DEPRECATED_FOR ("Deprecated macro. Use clutter_actor_is_realized instead") \ ((((ClutterActor*)(a))->flags & CLUTTER_ACTOR_REALIZED) != FALSE) #define CLUTTER_ACTOR_IS_VISIBLE(a) \ - CLUTTER_MACRO_DEPRECATED_IN_1_24_FOR ("Deprecated macro. Use clutter_actor_is_visible instead") \ + CLUTTER_MACRO_DEPRECATED_FOR ("Deprecated macro. Use clutter_actor_is_visible instead") \ ((((ClutterActor*)(a))->flags & CLUTTER_ACTOR_VISIBLE) != FALSE) #define CLUTTER_ACTOR_IS_REACTIVE(a) \ - CLUTTER_MACRO_DEPRECATED_IN_1_24_FOR ("Deprecated macro. Use clutter_actor_get_reactive instead") \ + CLUTTER_MACRO_DEPRECATED_FOR ("Deprecated macro. Use clutter_actor_get_reactive instead") \ ((((ClutterActor*)(a))->flags & CLUTTER_ACTOR_REACTIVE) != FALSE) typedef struct _ClutterActorClass ClutterActorClass; @@ -228,16 +230,18 @@ struct _ClutterActorClass void (* unrealize) (ClutterActor *self); void (* map) (ClutterActor *self); void (* unmap) (ClutterActor *self); - void (* paint) (ClutterActor *self); + void (* paint) (ClutterActor *self, + ClutterPaintContext *paint_context); void (* parent_set) (ClutterActor *actor, ClutterActor *old_parent); void (* destroy) (ClutterActor *self); void (* pick) (ClutterActor *actor, - const ClutterColor *color); + ClutterPickContext *pick_context); - void (* queue_redraw) (ClutterActor *actor, - ClutterActor *leaf_that_queued); + gboolean (* queue_redraw) (ClutterActor *actor, + ClutterActor *leaf_that_queued, + ClutterPaintVolume *paint_volume); /* size negotiation */ void (* get_preferred_width) (ClutterActor *self, @@ -295,10 +299,11 @@ struct _ClutterActorClass gboolean (* touch_event) (ClutterActor *self, ClutterTouchEvent *event); + gboolean (* has_accessible) (ClutterActor *self); /*< private >*/ /* padding for future expansion */ - gpointer _padding_dummy[26]; + gpointer _padding_dummy[25]; }; /** @@ -322,97 +327,107 @@ struct _ClutterActorIter gpointer CLUTTER_PRIVATE_FIELD (dummy5); }; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT GType clutter_actor_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT ClutterActor * clutter_actor_new (void); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_set_flags (ClutterActor *self, ClutterActorFlags flags); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_unset_flags (ClutterActor *self, ClutterActorFlags flags); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterActorFlags clutter_actor_get_flags (ClutterActor *self); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_show (ClutterActor *self); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_hide (ClutterActor *self); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_realize (ClutterActor *self); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_unrealize (ClutterActor *self); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_map (ClutterActor *self); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_unmap (ClutterActor *self); -CLUTTER_AVAILABLE_IN_ALL -void clutter_actor_paint (ClutterActor *self); -CLUTTER_AVAILABLE_IN_ALL -void clutter_actor_continue_paint (ClutterActor *self); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT +void clutter_actor_paint (ClutterActor *self, + ClutterPaintContext *paint_context); +CLUTTER_EXPORT +void clutter_actor_continue_paint (ClutterActor *self, + ClutterPaintContext *paint_context); +CLUTTER_EXPORT +void clutter_actor_pick (ClutterActor *actor, + ClutterPickContext *pick_context); +CLUTTER_EXPORT +void clutter_actor_continue_pick (ClutterActor *actor, + ClutterPickContext *pick_context); +CLUTTER_EXPORT void clutter_actor_queue_redraw (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_queue_redraw_with_clip (ClutterActor *self, const cairo_rectangle_int_t *clip); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_queue_relayout (ClutterActor *self); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_destroy (ClutterActor *self); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_set_name (ClutterActor *self, const gchar *name); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT const gchar * clutter_actor_get_name (ClutterActor *self); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT AtkObject * clutter_actor_get_accessible (ClutterActor *self); +CLUTTER_EXPORT +gboolean clutter_actor_has_accessible (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_24 +CLUTTER_EXPORT gboolean clutter_actor_is_visible (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_24 +CLUTTER_EXPORT gboolean clutter_actor_is_mapped (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_24 +CLUTTER_EXPORT gboolean clutter_actor_is_realized (ClutterActor *self); /* Size negotiation */ -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_set_request_mode (ClutterActor *self, ClutterRequestMode mode); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterRequestMode clutter_actor_get_request_mode (ClutterActor *self); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_get_preferred_width (ClutterActor *self, gfloat for_height, gfloat *min_width_p, gfloat *natural_width_p); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_get_preferred_height (ClutterActor *self, gfloat for_width, gfloat *min_height_p, gfloat *natural_height_p); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_get_preferred_size (ClutterActor *self, gfloat *min_width_p, gfloat *min_height_p, gfloat *natural_width_p, gfloat *natural_height_p); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_allocate (ClutterActor *self, const ClutterActorBox *box, ClutterAllocationFlags flags); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_allocate_preferred_size (ClutterActor *self, ClutterAllocationFlags flags); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_allocate_available_size (ClutterActor *self, gfloat x, gfloat y, gfloat available_width, gfloat available_height, ClutterAllocationFlags flags); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_allocate_align_fill (ClutterActor *self, const ClutterActorBox *box, gdouble x_align, @@ -420,450 +435,460 @@ void clutter_actor_allocate_align_fill gboolean x_fill, gboolean y_fill, ClutterAllocationFlags flags); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_set_allocation (ClutterActor *self, const ClutterActorBox *box, ClutterAllocationFlags flags); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_get_allocation_box (ClutterActor *self, ClutterActorBox *box); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_get_allocation_vertices (ClutterActor *self, ClutterActor *ancestor, - ClutterVertex verts[]); -CLUTTER_AVAILABLE_IN_ALL + graphene_point3d_t *verts); +CLUTTER_EXPORT gboolean clutter_actor_has_allocation (ClutterActor *self); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_set_size (ClutterActor *self, gfloat width, gfloat height); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_get_size (ClutterActor *self, gfloat *width, gfloat *height); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_set_position (ClutterActor *self, gfloat x, gfloat y); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_get_position (ClutterActor *self, gfloat *x, gfloat *y); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gboolean clutter_actor_get_fixed_position_set (ClutterActor *self); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_set_fixed_position_set (ClutterActor *self, gboolean is_set); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_move_by (ClutterActor *self, gfloat dx, gfloat dy); /* Actor geometry */ -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gfloat clutter_actor_get_width (ClutterActor *self); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gfloat clutter_actor_get_height (ClutterActor *self); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_set_width (ClutterActor *self, gfloat width); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_set_height (ClutterActor *self, gfloat height); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gfloat clutter_actor_get_x (ClutterActor *self); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gfloat clutter_actor_get_y (ClutterActor *self); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_set_x (ClutterActor *self, gfloat x); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_set_y (ClutterActor *self, gfloat y); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_actor_set_z_position (ClutterActor *self, gfloat z_position); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT gfloat clutter_actor_get_z_position (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_set_layout_manager (ClutterActor *self, ClutterLayoutManager *manager); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT ClutterLayoutManager * clutter_actor_get_layout_manager (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_set_x_align (ClutterActor *self, ClutterActorAlign x_align); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT ClutterActorAlign clutter_actor_get_x_align (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_set_y_align (ClutterActor *self, ClutterActorAlign y_align); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT ClutterActorAlign clutter_actor_get_y_align (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_set_margin_top (ClutterActor *self, gfloat margin); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT gfloat clutter_actor_get_margin_top (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_set_margin_bottom (ClutterActor *self, gfloat margin); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT gfloat clutter_actor_get_margin_bottom (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_set_margin_left (ClutterActor *self, gfloat margin); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT gfloat clutter_actor_get_margin_left (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_set_margin_right (ClutterActor *self, gfloat margin); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT gfloat clutter_actor_get_margin_right (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_set_margin (ClutterActor *self, const ClutterMargin *margin); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_get_margin (ClutterActor *self, ClutterMargin *margin); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_actor_set_x_expand (ClutterActor *self, gboolean expand); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT gboolean clutter_actor_get_x_expand (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_actor_set_y_expand (ClutterActor *self, gboolean expand); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT gboolean clutter_actor_get_y_expand (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT gboolean clutter_actor_needs_expand (ClutterActor *self, ClutterOrientation orientation); /* Paint */ -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_set_clip (ClutterActor *self, gfloat xoff, gfloat yoff, gfloat width, gfloat height); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_remove_clip (ClutterActor *self); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gboolean clutter_actor_has_clip (ClutterActor *self); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_get_clip (ClutterActor *self, gfloat *xoff, gfloat *yoff, gfloat *width, gfloat *height); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_set_clip_to_allocation (ClutterActor *self, gboolean clip_set); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gboolean clutter_actor_get_clip_to_allocation (ClutterActor *self); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_set_opacity (ClutterActor *self, guint8 opacity); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT guint8 clutter_actor_get_opacity (ClutterActor *self); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT guint8 clutter_actor_get_paint_opacity (ClutterActor *self); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gboolean clutter_actor_get_paint_visibility (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_8 +CLUTTER_EXPORT void clutter_actor_set_offscreen_redirect (ClutterActor *self, ClutterOffscreenRedirect redirect); -CLUTTER_AVAILABLE_IN_1_8 +CLUTTER_EXPORT ClutterOffscreenRedirect clutter_actor_get_offscreen_redirect (ClutterActor *self); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gboolean clutter_actor_should_pick_paint (ClutterActor *self); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gboolean clutter_actor_is_in_clone_paint (ClutterActor *self); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gboolean clutter_actor_get_paint_box (ClutterActor *self, ClutterActorBox *box); -CLUTTER_AVAILABLE_IN_1_8 + +CLUTTER_EXPORT +gboolean clutter_actor_get_resource_scale (ClutterActor *self, + gfloat *resource_scale); + +CLUTTER_EXPORT gboolean clutter_actor_has_overlaps (ClutterActor *self); /* Content */ -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_set_content (ClutterActor *self, ClutterContent *content); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT ClutterContent * clutter_actor_get_content (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_set_content_gravity (ClutterActor *self, ClutterContentGravity gravity); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT ClutterContentGravity clutter_actor_get_content_gravity (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_set_content_scaling_filters (ClutterActor *self, ClutterScalingFilter min_filter, ClutterScalingFilter mag_filter); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_get_content_scaling_filters (ClutterActor *self, ClutterScalingFilter *min_filter, ClutterScalingFilter *mag_filter); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_actor_set_content_repeat (ClutterActor *self, ClutterContentRepeat repeat); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT ClutterContentRepeat clutter_actor_get_content_repeat (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_get_content_box (ClutterActor *self, ClutterActorBox *box); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_set_background_color (ClutterActor *self, const ClutterColor *color); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_get_background_color (ClutterActor *self, ClutterColor *color); -CLUTTER_AVAILABLE_IN_1_6 +CLUTTER_EXPORT const ClutterPaintVolume * clutter_actor_get_paint_volume (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_6 +CLUTTER_EXPORT const ClutterPaintVolume * clutter_actor_get_transformed_paint_volume (ClutterActor *self, ClutterActor *relative_to_ancestor); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT const ClutterPaintVolume * clutter_actor_get_default_paint_volume (ClutterActor *self); /* Events */ -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_set_reactive (ClutterActor *actor, gboolean reactive); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gboolean clutter_actor_get_reactive (ClutterActor *actor); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gboolean clutter_actor_has_key_focus (ClutterActor *self); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_grab_key_focus (ClutterActor *self); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gboolean clutter_actor_event (ClutterActor *actor, const ClutterEvent *event, gboolean capture); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gboolean clutter_actor_has_pointer (ClutterActor *self); /* Text */ -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT PangoContext * clutter_actor_get_pango_context (ClutterActor *self); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT PangoContext * clutter_actor_create_pango_context (ClutterActor *self); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT PangoLayout * clutter_actor_create_pango_layout (ClutterActor *self, const gchar *text); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_set_text_direction (ClutterActor *self, ClutterTextDirection text_dir); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterTextDirection clutter_actor_get_text_direction (ClutterActor *self); /* Actor hierarchy */ -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_add_child (ClutterActor *self, ClutterActor *child); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_insert_child_at_index (ClutterActor *self, ClutterActor *child, gint index_); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_insert_child_above (ClutterActor *self, ClutterActor *child, ClutterActor *sibling); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_insert_child_below (ClutterActor *self, ClutterActor *child, ClutterActor *sibling); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_replace_child (ClutterActor *self, ClutterActor *old_child, ClutterActor *new_child); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_remove_child (ClutterActor *self, ClutterActor *child); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_remove_all_children (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_destroy_all_children (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT GList * clutter_actor_get_children (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT gint clutter_actor_get_n_children (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT ClutterActor * clutter_actor_get_child_at_index (ClutterActor *self, gint index_); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT ClutterActor * clutter_actor_get_previous_sibling (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT ClutterActor * clutter_actor_get_next_sibling (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT ClutterActor * clutter_actor_get_first_child (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT ClutterActor * clutter_actor_get_last_child (ClutterActor *self); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterActor * clutter_actor_get_parent (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT gboolean clutter_actor_contains (ClutterActor *self, ClutterActor *descendant); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterActor* clutter_actor_get_stage (ClutterActor *actor); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_set_child_below_sibling (ClutterActor *self, ClutterActor *child, ClutterActor *sibling); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_set_child_above_sibling (ClutterActor *self, ClutterActor *child, ClutterActor *sibling); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_set_child_at_index (ClutterActor *self, ClutterActor *child, gint index_); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_iter_init (ClutterActorIter *iter, ClutterActor *root); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT gboolean clutter_actor_iter_next (ClutterActorIter *iter, ClutterActor **child); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT gboolean clutter_actor_iter_prev (ClutterActorIter *iter, ClutterActor **child); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_iter_remove (ClutterActorIter *iter); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_iter_destroy (ClutterActorIter *iter); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT gboolean clutter_actor_iter_is_valid (const ClutterActorIter *iter); /* Transformations */ -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gboolean clutter_actor_is_rotated (ClutterActor *self); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gboolean clutter_actor_is_scaled (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_actor_set_pivot_point (ClutterActor *self, gfloat pivot_x, gfloat pivot_y); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_actor_get_pivot_point (ClutterActor *self, gfloat *pivot_x, gfloat *pivot_y); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_actor_set_pivot_point_z (ClutterActor *self, gfloat pivot_z); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT gfloat clutter_actor_get_pivot_point_z (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_actor_set_rotation_angle (ClutterActor *self, ClutterRotateAxis axis, gdouble angle); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT gdouble clutter_actor_get_rotation_angle (ClutterActor *self, ClutterRotateAxis axis); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_set_scale (ClutterActor *self, gdouble scale_x, gdouble scale_y); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_get_scale (ClutterActor *self, gdouble *scale_x, gdouble *scale_y); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_actor_set_scale_z (ClutterActor *self, gdouble scale_z); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT gdouble clutter_actor_get_scale_z (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_actor_set_translation (ClutterActor *self, gfloat translate_x, gfloat translate_y, gfloat translate_z); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_actor_get_translation (ClutterActor *self, gfloat *translate_x, gfloat *translate_y, gfloat *translate_z); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_actor_set_transform (ClutterActor *self, const ClutterMatrix *transform); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_actor_get_transform (ClutterActor *self, ClutterMatrix *transform); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_actor_set_child_transform (ClutterActor *self, const ClutterMatrix *transform); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_actor_get_child_transform (ClutterActor *self, ClutterMatrix *transform); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_get_transformed_position (ClutterActor *self, gfloat *x, gfloat *y); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_get_transformed_size (ClutterActor *self, gfloat *width, gfloat *height); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gboolean clutter_actor_transform_stage_point (ClutterActor *self, gfloat x, gfloat y, gfloat *x_out, gfloat *y_out); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_get_abs_allocation_vertices (ClutterActor *self, - ClutterVertex verts[]); -CLUTTER_AVAILABLE_IN_ALL + graphene_point3d_t *verts); +CLUTTER_EXPORT void clutter_actor_apply_transform_to_point (ClutterActor *self, - const ClutterVertex *point, - ClutterVertex *vertex); -CLUTTER_AVAILABLE_IN_ALL + const graphene_point3d_t *point, + graphene_point3d_t *vertex); +CLUTTER_EXPORT void clutter_actor_apply_relative_transform_to_point (ClutterActor *self, ClutterActor *ancestor, - const ClutterVertex *point, - ClutterVertex *vertex); + const graphene_point3d_t *point, + graphene_point3d_t *vertex); /* Implicit animations */ -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_save_easing_state (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_restore_easing_state (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_set_easing_mode (ClutterActor *self, ClutterAnimationMode mode); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT ClutterAnimationMode clutter_actor_get_easing_mode (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_set_easing_duration (ClutterActor *self, guint msecs); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT guint clutter_actor_get_easing_duration (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_set_easing_delay (ClutterActor *self, guint msecs); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT guint clutter_actor_get_easing_delay (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT ClutterTransition * clutter_actor_get_transition (ClutterActor *self, const char *name); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_add_transition (ClutterActor *self, const char *name, ClutterTransition *transition); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_remove_transition (ClutterActor *self, const char *name); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_actor_remove_all_transitions (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_16 +CLUTTER_EXPORT gboolean clutter_actor_has_mapped_clones (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_22 +CLUTTER_EXPORT void clutter_actor_set_opacity_override (ClutterActor *self, gint opacity); -CLUTTER_AVAILABLE_IN_1_22 +CLUTTER_EXPORT gint clutter_actor_get_opacity_override (ClutterActor *self); +CLUTTER_EXPORT +void clutter_actor_inhibit_culling (ClutterActor *actor); +CLUTTER_EXPORT +void clutter_actor_uninhibit_culling (ClutterActor *actor); + /** * ClutterActorCreateChildFunc: * @item: (type GObject): the item in the model @@ -883,19 +908,24 @@ gint clutter_actor_get_opacity_override typedef ClutterActor * (* ClutterActorCreateChildFunc) (gpointer item, gpointer user_data); -CLUTTER_AVAILABLE_IN_1_24 +CLUTTER_EXPORT void clutter_actor_bind_model (ClutterActor *self, GListModel *model, ClutterActorCreateChildFunc create_child_func, gpointer user_data, GDestroyNotify notify); -CLUTTER_AVAILABLE_IN_1_24 +CLUTTER_EXPORT void clutter_actor_bind_model_with_properties (ClutterActor *self, GListModel *model, GType child_type, const char *first_model_property, ...); +CLUTTER_EXPORT +void clutter_actor_pick_box (ClutterActor *self, + ClutterPickContext *pick_context, + const ClutterActorBox *box); + G_END_DECLS #endif /* __CLUTTER_ACTOR_H__ */ diff --git a/clutter/clutter/clutter-align-constraint.c b/clutter/clutter/clutter-align-constraint.c index 345228a0d..a2694aa63 100644 --- a/clutter/clutter/clutter-align-constraint.c +++ b/clutter/clutter/clutter-align-constraint.c @@ -34,9 +34,7 @@ * #ClutterAlignConstraint is available since Clutter 1.4 */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include "clutter-align-constraint.h" diff --git a/clutter/clutter/clutter-align-constraint.h b/clutter/clutter/clutter-align-constraint.h index 212be8bf5..2a42d8920 100644 --- a/clutter/clutter/clutter-align-constraint.h +++ b/clutter/clutter/clutter-align-constraint.h @@ -48,28 +48,28 @@ G_BEGIN_DECLS typedef struct _ClutterAlignConstraint ClutterAlignConstraint; typedef struct _ClutterAlignConstraintClass ClutterAlignConstraintClass; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT GType clutter_align_constraint_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT ClutterConstraint *clutter_align_constraint_new (ClutterActor *source, ClutterAlignAxis axis, gfloat factor); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_align_constraint_set_source (ClutterAlignConstraint *align, ClutterActor *source); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT ClutterActor * clutter_align_constraint_get_source (ClutterAlignConstraint *align); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_align_constraint_set_align_axis (ClutterAlignConstraint *align, ClutterAlignAxis axis); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT ClutterAlignAxis clutter_align_constraint_get_align_axis (ClutterAlignConstraint *align); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_align_constraint_set_factor (ClutterAlignConstraint *align, gfloat factor); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT gfloat clutter_align_constraint_get_factor (ClutterAlignConstraint *align); G_END_DECLS diff --git a/clutter/clutter/clutter-animatable.c b/clutter/clutter/clutter-animatable.c index ea285b82e..e8c951110 100644 --- a/clutter/clutter/clutter-animatable.c +++ b/clutter/clutter/clutter-animatable.c @@ -30,7 +30,7 @@ * to control how a #ClutterAnimation will animate a property. * * Each #ClutterAnimatable should implement the - * #ClutterAnimatableIface.interpolate_property() virtual function of the + * #ClutterAnimatableInterface.interpolate_property() virtual function of the * interface to compute the animation state between two values of an interval * depending on a progress factor, expressed as a floating point value. * @@ -45,9 +45,7 @@ * #ClutterAnimatable is available since Clutter 1.0 */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #define CLUTTER_DISABLE_DEPRECATION_WARNINGS @@ -56,10 +54,8 @@ #include "clutter-debug.h" #include "clutter-private.h" -#include "deprecated/clutter-animatable.h" #include "deprecated/clutter-animation.h" -typedef ClutterAnimatableIface ClutterAnimatableInterface; G_DEFINE_INTERFACE (ClutterAnimatable, clutter_animatable, G_TYPE_OBJECT); static void @@ -67,80 +63,6 @@ clutter_animatable_default_init (ClutterAnimatableInterface *iface) { } -/** - * clutter_animatable_animate_property: - * @animatable: a #ClutterAnimatable - * @animation: a #ClutterAnimation - * @property_name: the name of the animated property - * @initial_value: the initial value of the animation interval - * @final_value: the final value of the animation interval - * @progress: the progress factor - * @value: return location for the animation value - * - * Calls the animate_property() virtual function for @animatable. - * - * The @initial_value and @final_value #GValues must contain - * the same type; @value must have been initialized to the same - * type of @initial_value and @final_value. - * - * All implementation of the #ClutterAnimatable interface must - * implement this function. - * - * Return value: %TRUE if the value has been validated and can - * be applied to the #ClutterAnimatable, and %FALSE otherwise - * - * Since: 1.0 - * - * Deprecated: 1.8: Use clutter_animatable_interpolate_value() - * instead - */ -gboolean -clutter_animatable_animate_property (ClutterAnimatable *animatable, - ClutterAnimation *animation, - const gchar *property_name, - const GValue *initial_value, - const GValue *final_value, - gdouble progress, - GValue *value) -{ - ClutterAnimatableIface *iface; - gboolean res; - - g_return_val_if_fail (CLUTTER_IS_ANIMATABLE (animatable), FALSE); - g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), FALSE); - g_return_val_if_fail (property_name != NULL, FALSE); - g_return_val_if_fail (initial_value != NULL && final_value != NULL, FALSE); - g_return_val_if_fail (G_VALUE_TYPE (initial_value) != G_TYPE_INVALID, FALSE); - g_return_val_if_fail (G_VALUE_TYPE (final_value) != G_TYPE_INVALID, FALSE); - g_return_val_if_fail (value != NULL, FALSE); - g_return_val_if_fail (G_VALUE_TYPE (value) == G_VALUE_TYPE (initial_value) && - G_VALUE_TYPE (value) == G_VALUE_TYPE (final_value), - FALSE); - - iface = CLUTTER_ANIMATABLE_GET_IFACE (animatable); - if (iface->animate_property == NULL) - { - ClutterInterval *interval; - - interval = clutter_animation_get_interval (animation, property_name); - if (interval == NULL) - return FALSE; - - res = clutter_animatable_interpolate_value (animatable, property_name, - interval, - progress, - value); - } - else - res = iface->animate_property (animatable, animation, - property_name, - initial_value, final_value, - progress, - value); - - return res; -} - /** * clutter_animatable_find_property: * @animatable: a #ClutterAnimatable @@ -157,7 +79,7 @@ GParamSpec * clutter_animatable_find_property (ClutterAnimatable *animatable, const gchar *property_name) { - ClutterAnimatableIface *iface; + ClutterAnimatableInterface *iface; g_return_val_if_fail (CLUTTER_IS_ANIMATABLE (animatable), NULL); g_return_val_if_fail (property_name != NULL, NULL); @@ -187,7 +109,7 @@ clutter_animatable_get_initial_state (ClutterAnimatable *animatable, const gchar *property_name, GValue *value) { - ClutterAnimatableIface *iface; + ClutterAnimatableInterface *iface; g_return_if_fail (CLUTTER_IS_ANIMATABLE (animatable)); g_return_if_fail (property_name != NULL); @@ -216,7 +138,7 @@ clutter_animatable_set_final_state (ClutterAnimatable *animatable, const gchar *property_name, const GValue *value) { - ClutterAnimatableIface *iface; + ClutterAnimatableInterface *iface; g_return_if_fail (CLUTTER_IS_ANIMATABLE (animatable)); g_return_if_fail (property_name != NULL); @@ -262,7 +184,7 @@ clutter_animatable_interpolate_value (ClutterAnimatable *animatable, gdouble progress, GValue *value) { - ClutterAnimatableIface *iface; + ClutterAnimatableInterface *iface; g_return_val_if_fail (CLUTTER_IS_ANIMATABLE (animatable), FALSE); g_return_val_if_fail (property_name != NULL, FALSE); diff --git a/clutter/clutter/clutter-animatable.h b/clutter/clutter/clutter-animatable.h index 7d20c5a57..0b194514a 100644 --- a/clutter/clutter/clutter-animatable.h +++ b/clutter/clutter/clutter-animatable.h @@ -33,24 +33,15 @@ G_BEGIN_DECLS -#define CLUTTER_TYPE_ANIMATABLE (clutter_animatable_get_type ()) -#define CLUTTER_ANIMATABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ANIMATABLE, ClutterAnimatable)) -#define CLUTTER_IS_ANIMATABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ANIMATABLE)) -#define CLUTTER_ANIMATABLE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), CLUTTER_TYPE_ANIMATABLE, ClutterAnimatableIface)) +#define CLUTTER_TYPE_ANIMATABLE (clutter_animatable_get_type ()) -typedef struct _ClutterAnimatableIface ClutterAnimatableIface; +CLUTTER_EXPORT +G_DECLARE_INTERFACE (ClutterAnimatable, clutter_animatable, + CLUTTER, ANIMATABLE, + GObject) /** - * ClutterAnimatable: - * - * #ClutterAnimatable is an opaque structure whose members cannot be directly - * accessed - * - * Since: 1.0 - */ - -/** - * ClutterAnimatableIface: + * ClutterAnimatableInterface: * @animate_property: virtual function for custom interpolation of a * property. This virtual function is deprecated * @find_property: virtual function for retrieving the #GParamSpec of @@ -67,7 +58,7 @@ typedef struct _ClutterAnimatableIface ClutterAnimatableIface; * * Since: 1.0 */ -struct _ClutterAnimatableIface +struct _ClutterAnimatableInterface { /*< private >*/ GTypeInterface parent_iface; @@ -95,21 +86,18 @@ struct _ClutterAnimatableIface GValue *value); }; -CLUTTER_AVAILABLE_IN_1_0 -GType clutter_animatable_get_type (void) G_GNUC_CONST; - -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT GParamSpec *clutter_animatable_find_property (ClutterAnimatable *animatable, const gchar *property_name); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_animatable_get_initial_state (ClutterAnimatable *animatable, const gchar *property_name, GValue *value); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_animatable_set_final_state (ClutterAnimatable *animatable, const gchar *property_name, const GValue *value); -CLUTTER_AVAILABLE_IN_1_8 +CLUTTER_EXPORT gboolean clutter_animatable_interpolate_value (ClutterAnimatable *animatable, const gchar *property_name, ClutterInterval *interval, diff --git a/clutter/clutter/clutter-autocleanups.h b/clutter/clutter/clutter-autocleanups.h index 10c73fdd4..8e17d002e 100644 --- a/clutter/clutter/clutter-autocleanups.h +++ b/clutter/clutter/clutter-autocleanups.h @@ -34,7 +34,6 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterAction, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterActor, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterActorMeta, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterAlignConstraint, g_object_unref) -G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterAnimatable, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBackend, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBindConstraint, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBindingPool, g_object_unref) @@ -49,10 +48,8 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterClone, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterColorizeEffect, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterConstraint, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterContainer, g_object_unref) -G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterContent, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDeformEffect, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDesaturateEffect, g_object_unref) -G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDeviceManager, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDragAction, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDropAction, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterEffect, g_object_unref) @@ -93,13 +90,10 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterActorBox, clutter_actor_box_free) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterColor, clutter_color_free) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterMargin, clutter_margin_free) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterMatrix, clutter_matrix_free) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPaintContext, clutter_paint_context_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPaintNode, clutter_paint_node_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPaintVolume, clutter_paint_volume_free) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPathNode, clutter_path_node_free) -G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPoint, clutter_point_free) -G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterRect, clutter_rect_free) -G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterSize, clutter_size_free) -G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterVertex, clutter_vertex_free) #endif /* __GI_SCANNER__ */ diff --git a/clutter/clutter/clutter-backend-private.h b/clutter/clutter/clutter-backend-private.h index 5fd211435..c7c54f85b 100644 --- a/clutter/clutter/clutter-backend-private.h +++ b/clutter/clutter/clutter-backend-private.h @@ -23,11 +23,9 @@ #define __CLUTTER_BACKEND_PRIVATE_H__ #include -#include +#include #include -#include "clutter-event-translator.h" - #define CLUTTER_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BACKEND, ClutterBackendClass)) #define CLUTTER_IS_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BACKEND)) #define CLUTTER_BACKEND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_BACKEND, ClutterBackendClass)) @@ -48,8 +46,6 @@ struct _ClutterBackend CoglOnscreen *dummy_onscreen; - ClutterDeviceManager *device_manager; - cairo_font_options_t *font_options; gchar *font_name; @@ -57,7 +53,7 @@ struct _ClutterBackend gfloat units_per_em; gint32 units_serial; - GList *event_translators; + ClutterStageWindow *stage_window; ClutterInputMethod *input_method; }; @@ -88,21 +84,12 @@ struct _ClutterBackendClass GError **error); gboolean (* create_context) (ClutterBackend *backend, GError **error); - ClutterDeviceManager *(* get_device_manager) (ClutterBackend *backend); - - void (* copy_event_data) (ClutterBackend *backend, - const ClutterEvent *src, - ClutterEvent *dest); - void (* free_event_data) (ClutterBackend *backend, - ClutterEvent *event); gboolean (* translate_event) (ClutterBackend *backend, gpointer native, ClutterEvent *event); - PangoDirection (* get_keymap_direction) (ClutterBackend *backend); - - void (* bell_notify) (ClutterBackend *backend); + ClutterSeat * (* get_default_seat) (ClutterBackend *backend); /* signals */ void (* resolution_changed) (ClutterBackend *backend); @@ -131,31 +118,21 @@ void _clutter_backend_copy_event_data (Clutter ClutterEvent *dest); void _clutter_backend_free_event_data (ClutterBackend *backend, ClutterEvent *event); +CLUTTER_EXPORT gboolean _clutter_backend_translate_event (ClutterBackend *backend, gpointer native, ClutterEvent *event); -CLUTTER_AVAILABLE_IN_MUFFIN -void _clutter_backend_add_event_translator (ClutterBackend *backend, - ClutterEventTranslator *translator); - -void _clutter_backend_remove_event_translator (ClutterBackend *backend, - ClutterEventTranslator *translator); - ClutterFeatureFlags _clutter_backend_get_features (ClutterBackend *backend); gfloat _clutter_backend_get_units_per_em (ClutterBackend *backend, PangoFontDescription *font_desc); gint32 _clutter_backend_get_units_serial (ClutterBackend *backend); -PangoDirection _clutter_backend_get_keymap_direction (ClutterBackend *backend); - -CLUTTER_AVAILABLE_IN_MUFFIN -void _clutter_backend_reset_cogl_framebuffer (ClutterBackend *backend); - void clutter_set_allowed_drivers (const char *drivers); -void clutter_try_set_windowing_backend (const char *drivers); +CLUTTER_EXPORT +ClutterStageWindow * clutter_backend_get_stage_window (ClutterBackend *backend); G_END_DECLS diff --git a/clutter/clutter/clutter-backend.c b/clutter/clutter/clutter-backend.c index c398ae80c..3cc4ca297 100644 --- a/clutter/clutter/clutter-backend.c +++ b/clutter/clutter/clutter-backend.c @@ -38,9 +38,7 @@ * #ClutterBackend is available since Clutter 0.4 */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #define CLUTTER_ENABLE_EXPERIMENTAL_API @@ -48,16 +46,11 @@ #include "clutter-debug.h" #include "clutter-event-private.h" #include "clutter-marshal.h" -#include "clutter-muffin.h" +#include "clutter-mutter.h" #include "clutter-private.h" #include "clutter-stage-manager-private.h" #include "clutter-stage-private.h" #include "clutter-stage-window.h" -#include "clutter-version.h" -#include "clutter-device-manager-private.h" - -#define CLUTTER_DISABLE_DEPRECATION_WARNINGS -#include "deprecated/clutter-backend.h" #ifdef CLUTTER_HAS_WAYLAND_COMPOSITOR_SUPPORT #include "wayland/clutter-wayland-compositor.h" @@ -68,9 +61,6 @@ #ifdef CLUTTER_INPUT_X11 #include "x11/clutter-backend-x11.h" #endif -#ifdef CLUTTER_INPUT_EVDEV -#include "evdev/clutter-device-manager-evdev.h" -#endif #ifdef CLUTTER_WINDOWING_EGL #include "egl/clutter-backend-eglnative.h" #endif @@ -110,10 +100,12 @@ clutter_backend_dispose (GObject *gobject) /* clear the events still in the queue of the main context */ _clutter_clear_events_queue (); - /* remove all event translators */ - g_clear_pointer (&backend->event_translators, g_list_free); - g_clear_pointer (&backend->dummy_onscreen, cogl_object_unref); + if (backend->stage_window) + { + g_object_remove_weak_pointer (G_OBJECT (backend->stage_window), + (gpointer *) &backend->stage_window); + } G_OBJECT_CLASS (clutter_backend_parent_class)->dispose (gobject); } @@ -125,7 +117,7 @@ clutter_backend_finalize (GObject *gobject) g_source_destroy (backend->cogl_source); - free (backend->font_name); + g_free (backend->font_name); clutter_backend_set_font_options (backend, NULL); g_clear_object (&backend->input_method); @@ -155,7 +147,7 @@ get_units_per_em (ClutterBackend *backend, font_desc = pango_font_description_from_string (font_name); free_font_desc = TRUE; - free (font_name); + g_free (font_name); } } @@ -403,7 +395,7 @@ clutter_backend_real_create_context (ClutterBackend *backend, else g_set_error_literal (error, CLUTTER_INIT_ERROR, CLUTTER_INIT_ERROR_BACKEND, - _("Unable to initialize the Clutter backend: no available drivers found.")); + "Unable to initialize the Clutter backend: no available drivers found."); return FALSE; } @@ -433,7 +425,7 @@ clutter_backend_real_get_features (ClutterBackend *backend) if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_THROTTLE)) { CLUTTER_NOTE (BACKEND, "Cogl supports swap buffers throttling"); - flags |= CLUTTER_FEATURE_SYNC_TO_VBLANK; + flags |= CLUTTER_FEATURE_SWAP_THROTTLE; } else CLUTTER_NOTE (BACKEND, "Cogl doesn't support swap buffers throttling"); @@ -532,80 +524,7 @@ _clutter_create_backend (void) static void clutter_backend_real_init_events (ClutterBackend *backend) { - const char *input_backend = NULL; - - input_backend = g_getenv ("CLUTTER_INPUT_BACKEND"); - if (input_backend != NULL) - input_backend = g_intern_string (input_backend); - -#ifdef CLUTTER_INPUT_X11 - if (clutter_check_windowing_backend (CLUTTER_WINDOWING_X11) && - (input_backend == NULL || input_backend == I_(CLUTTER_INPUT_X11))) - { - _clutter_backend_x11_events_init (backend); - } - else -#endif -#ifdef CLUTTER_INPUT_EVDEV - /* Evdev can be used regardless of the windowing system */ - if ((input_backend != NULL && strcmp (input_backend, CLUTTER_INPUT_EVDEV) == 0) -#ifdef CLUTTER_WINDOWING_EGL - /* but we do want to always use it for EGL native */ - || clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL) -#endif - ) - { - _clutter_events_evdev_init (backend); - } - else -#endif - if (input_backend != NULL) - { - if (input_backend != I_(CLUTTER_INPUT_NULL)) - g_error ("Unrecognized input backend '%s'", input_backend); - } - else - g_error ("Unknown input backend"); -} - -static ClutterDeviceManager * -clutter_backend_real_get_device_manager (ClutterBackend *backend) -{ - if (G_UNLIKELY (backend->device_manager == NULL)) - { - g_critical ("No device manager available, expect broken input"); - return NULL; - } - - return backend->device_manager; -} - -static gboolean -clutter_backend_real_translate_event (ClutterBackend *backend, - gpointer native, - ClutterEvent *event) -{ - GList *l; - - for (l = backend->event_translators; - l != NULL; - l = l->next) - { - ClutterEventTranslator *translator = l->data; - ClutterTranslateReturn retval; - - retval = _clutter_event_translator_translate_event (translator, - native, - event); - - if (retval == CLUTTER_TRANSLATE_QUEUE) - return TRUE; - - if (retval == CLUTTER_TRANSLATE_REMOVE) - return FALSE; - } - - return FALSE; + g_error ("Unknown input backend"); } static void @@ -630,8 +549,7 @@ clutter_backend_class_init (ClutterBackendClass *klass) G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (ClutterBackendClass, resolution_changed), - NULL, NULL, - _clutter_marshal_VOID__VOID, + NULL, NULL, NULL, G_TYPE_NONE, 0); /** @@ -648,8 +566,7 @@ clutter_backend_class_init (ClutterBackendClass *klass) G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (ClutterBackendClass, font_changed), - NULL, NULL, - _clutter_marshal_VOID__VOID, + NULL, NULL, NULL, G_TYPE_NONE, 0); /** @@ -666,16 +583,13 @@ clutter_backend_class_init (ClutterBackendClass *klass) G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (ClutterBackendClass, settings_changed), - NULL, NULL, - _clutter_marshal_VOID__VOID, + NULL, NULL, NULL, G_TYPE_NONE, 0); klass->resolution_changed = clutter_backend_real_resolution_changed; klass->font_changed = clutter_backend_real_font_changed; klass->init_events = clutter_backend_real_init_events; - klass->get_device_manager = clutter_backend_real_get_device_manager; - klass->translate_event = clutter_backend_real_translate_event; klass->create_context = clutter_backend_real_create_context; klass->get_features = clutter_backend_real_get_features; } @@ -686,7 +600,7 @@ clutter_backend_init (ClutterBackend *self) self->units_per_em = -1.0; self->units_serial = 1; - self->dummy_onscreen = COGL_INVALID_HANDLE; + self->dummy_onscreen = NULL; } void @@ -754,6 +668,10 @@ _clutter_backend_create_stage (ClutterBackend *backend, g_assert (CLUTTER_IS_STAGE_WINDOW (stage_window)); + backend->stage_window = stage_window; + g_object_add_weak_pointer (G_OBJECT (backend->stage_window), + (gpointer *) &backend->stage_window); + return stage_window; } @@ -804,7 +722,7 @@ _clutter_backend_get_features (ClutterBackend *backend) if (klass->get_features) return klass->get_features (backend); - + return 0; } @@ -838,37 +756,24 @@ _clutter_backend_copy_event_data (ClutterBackend *backend, const ClutterEvent *src, ClutterEvent *dest) { - ClutterEventExtenderInterface *iface; - ClutterBackendClass *klass; + ClutterSeatClass *seat_class; + ClutterSeat *seat; - klass = CLUTTER_BACKEND_GET_CLASS (backend); - if (CLUTTER_IS_EVENT_EXTENDER (backend->device_manager)) - { - iface = CLUTTER_EVENT_EXTENDER_GET_IFACE (backend->device_manager); - iface->copy_event_data (CLUTTER_EVENT_EXTENDER (backend->device_manager), - src, dest); - } - else if (klass->copy_event_data != NULL) - klass->copy_event_data (backend, src, dest); + seat = clutter_backend_get_default_seat (backend); + seat_class = CLUTTER_SEAT_GET_CLASS (seat); + seat_class->copy_event_data (seat, src, dest); } void _clutter_backend_free_event_data (ClutterBackend *backend, ClutterEvent *event) { - ClutterEventExtenderInterface *iface; - ClutterBackendClass *klass; + ClutterSeatClass *seat_class; + ClutterSeat *seat; - klass = CLUTTER_BACKEND_GET_CLASS (backend); - - if (CLUTTER_IS_EVENT_EXTENDER (backend->device_manager)) - { - iface = CLUTTER_EVENT_EXTENDER_GET_IFACE (backend->device_manager); - iface->free_event_data (CLUTTER_EVENT_EXTENDER (backend->device_manager), - event); - } - else if (klass->free_event_data != NULL) - klass->free_event_data (backend, event); + seat = clutter_backend_get_default_seat (backend); + seat_class = CLUTTER_SEAT_GET_CLASS (seat); + seat_class->free_event_data (seat, event); } /** @@ -893,129 +798,6 @@ clutter_get_default_backend (void) return clutter_context->backend; } -/** - * clutter_backend_set_double_click_time: - * @backend: a #ClutterBackend - * @msec: milliseconds between two button press events - * - * Sets the maximum time between two button press events, used to - * verify whether it's a double click event or not. - * - * Since: 0.4 - * - * Deprecated: 1.4: Use #ClutterSettings:double-click-time instead - */ -void -clutter_backend_set_double_click_time (ClutterBackend *backend, - guint msec) -{ - ClutterSettings *settings = clutter_settings_get_default (); - - g_object_set (settings, "double-click-time", msec, NULL); -} - -/** - * clutter_backend_get_double_click_time: - * @backend: a #ClutterBackend - * - * Gets the maximum time between two button press events, as set - * by clutter_backend_set_double_click_time(). - * - * Return value: a time in milliseconds - * - * Since: 0.4 - * - * Deprecated: 1.4: Use #ClutterSettings:double-click-time instead - */ -guint -clutter_backend_get_double_click_time (ClutterBackend *backend) -{ - ClutterSettings *settings = clutter_settings_get_default (); - gint retval; - - g_object_get (settings, "double-click-time", &retval, NULL); - - return retval; -} - -/** - * clutter_backend_set_double_click_distance: - * @backend: a #ClutterBackend - * @distance: a distance, in pixels - * - * Sets the maximum distance used to verify a double click event. - * - * Since: 0.4 - * - * Deprecated: 1.4: Use #ClutterSettings:double-click-distance instead - */ -void -clutter_backend_set_double_click_distance (ClutterBackend *backend, - guint distance) -{ - ClutterSettings *settings = clutter_settings_get_default (); - - g_object_set (settings, "double-click-distance", distance, NULL); -} - -/** - * clutter_backend_get_double_click_distance: - * @backend: a #ClutterBackend - * - * Retrieves the distance used to verify a double click event - * - * Return value: a distance, in pixels. - * - * Since: 0.4 - * - * Deprecated: 1.4: Use #ClutterSettings:double-click-distance instead - */ -guint -clutter_backend_get_double_click_distance (ClutterBackend *backend) -{ - ClutterSettings *settings = clutter_settings_get_default (); - gint retval; - - g_object_get (settings, "double-click-distance", &retval, NULL); - - return retval; -} - -/** - * clutter_backend_set_resolution: - * @backend: a #ClutterBackend - * @dpi: the resolution in "dots per inch" (Physical inches aren't - * actually involved; the terminology is conventional). - * - * Sets the resolution for font handling on the screen. This is a - * scale factor between points specified in a #PangoFontDescription - * and cairo units. The default value is 96, meaning that a 10 point - * font will be 13 units high. (10 * 96. / 72. = 13.3). - * - * Applications should never need to call this function. - * - * Since: 0.4 - * - * Deprecated: 1.4: Use #ClutterSettings:font-dpi instead - */ -void -clutter_backend_set_resolution (ClutterBackend *backend, - gdouble dpi) -{ - ClutterSettings *settings; - gint resolution; - - g_return_if_fail (CLUTTER_IS_BACKEND (backend)); - - if (dpi < 0) - resolution = -1; - else - resolution = dpi * 1024; - - settings = clutter_settings_get_default (); - g_object_set (settings, "font-dpi", resolution, NULL); -} - /** * clutter_backend_get_resolution: * @backend: a #ClutterBackend @@ -1121,61 +903,6 @@ clutter_backend_get_font_options (ClutterBackend *backend) return backend->font_options; } -/** - * clutter_backend_set_font_name: - * @backend: a #ClutterBackend - * @font_name: the name of the font - * - * Sets the default font to be used by Clutter. The @font_name string - * must either be %NULL, which means that the font name from the - * default #ClutterBackend will be used; or be something that can - * be parsed by the pango_font_description_from_string() function. - * - * Since: 1.0 - * - * Deprecated: 1.4: Use #ClutterSettings:font-name instead - */ -void -clutter_backend_set_font_name (ClutterBackend *backend, - const gchar *font_name) -{ - ClutterSettings *settings = clutter_settings_get_default (); - - g_object_set (settings, "font-name", font_name, NULL); -} - -/** - * clutter_backend_get_font_name: - * @backend: a #ClutterBackend - * - * Retrieves the default font name as set by - * clutter_backend_set_font_name(). - * - * Return value: the font name for the backend. The returned string is - * owned by the #ClutterBackend and should never be modified or freed - * - * Since: 1.0 - * - * Deprecated: 1.4: Use #ClutterSettings:font-name instead - */ -const gchar * -clutter_backend_get_font_name (ClutterBackend *backend) -{ - ClutterSettings *settings; - - g_return_val_if_fail (CLUTTER_IS_BACKEND (backend), NULL); - - settings = clutter_settings_get_default (); - - /* XXX yuck. but we return a const pointer, so we need to - * store it in the backend - */ - free (backend->font_name); - g_object_get (settings, "font-name", &backend->font_name, NULL); - - return backend->font_name; -} - gint32 _clutter_backend_get_units_serial (ClutterBackend *backend) { @@ -1192,28 +919,6 @@ _clutter_backend_translate_event (ClutterBackend *backend, event); } -void -_clutter_backend_add_event_translator (ClutterBackend *backend, - ClutterEventTranslator *translator) -{ - if (g_list_find (backend->event_translators, translator) != NULL) - return; - - backend->event_translators = - g_list_prepend (backend->event_translators, translator); -} - -void -_clutter_backend_remove_event_translator (ClutterBackend *backend, - ClutterEventTranslator *translator) -{ - if (g_list_find (backend->event_translators, translator) == NULL) - return; - - backend->event_translators = - g_list_remove (backend->event_translators, translator); -} - /** * clutter_backend_get_cogl_context: (skip) * @backend: a #ClutterBackend @@ -1265,94 +970,6 @@ clutter_wayland_set_compositor_display (void *display) } #endif -/** - * clutter_set_windowing_backend: - * @backend_type: a comma separated list of windowing backends - * - * Restricts Clutter to only use the specified backend or list of backends. - * - * You can use one of the `CLUTTER_WINDOWING_*` symbols, e.g. - * - * |[ - * clutter_set_windowing_backend (CLUTTER_WINDOWING_X11); - * ]| - * - * Will force Clutter to use the X11 windowing and input backend, and terminate - * if the X11 backend could not be initialized successfully. - * - * Since Clutter 1.26, you can also use a comma-separated list of windowing - * system backends to provide a fallback in case backends are not available or - * enabled, e.g.: - * - * |[ - * clutter_set_windowing_backend ("gdk,wayland,x11"); - * ]| - * - * Will make Clutter test for the GDK, Wayland, and X11 backends in that order. - * - * You can use the `*` special value to ask Clutter to use the internally - * defined list of backends. For instance: - * - * |[ - * clutter_set_windowing_backend ("x11,wayland,*"); - * ]| - * - * Will make Clutter test the X11 and Wayland backends, and then fall back - * to the internal list of available backends. - * - * This function must be called before the first API call to Clutter, including - * clutter_get_option_context() - * - * Since: 1.16 - */ -void -clutter_set_windowing_backend (const char *backend_type) -{ - g_return_if_fail (backend_type != NULL); - - allowed_backends = g_strdup (backend_type); -} - -void -clutter_try_set_windowing_backend (const char *backend_type) -{ - if (allowed_backends == NULL) - clutter_set_windowing_backend (backend_type); -} - -PangoDirection -_clutter_backend_get_keymap_direction (ClutterBackend *backend) -{ - ClutterBackendClass *klass; - - klass = CLUTTER_BACKEND_GET_CLASS (backend); - if (klass->get_keymap_direction != NULL) - return klass->get_keymap_direction (backend); - - return PANGO_DIRECTION_NEUTRAL; -} - -void -_clutter_backend_reset_cogl_framebuffer (ClutterBackend *backend) -{ - if (backend->dummy_onscreen == COGL_INVALID_HANDLE) - { - CoglError *internal_error = NULL; - - backend->dummy_onscreen = cogl_onscreen_new (backend->cogl_context, 1, 1); - - if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (backend->dummy_onscreen), - &internal_error)) - { - g_critical ("Unable to create dummy onscreen: %s", internal_error->message); - cogl_error_free (internal_error); - return; - } - } - - cogl_set_framebuffer (COGL_FRAMEBUFFER (backend->dummy_onscreen)); -} - void clutter_set_allowed_drivers (const char *drivers) { @@ -1365,16 +982,6 @@ clutter_set_allowed_drivers (const char *drivers) allowed_drivers = g_strdup (drivers); } -void -clutter_backend_bell_notify (ClutterBackend *backend) -{ - ClutterBackendClass *klass; - - klass = CLUTTER_BACKEND_GET_CLASS (backend); - if (klass->bell_notify) - klass->bell_notify (backend); -} - /** * clutter_backend_get_input_method: * @backend: the #CLutterBackend @@ -1402,3 +1009,25 @@ clutter_backend_set_input_method (ClutterBackend *backend, { g_set_object (&backend->input_method, method); } + +ClutterStageWindow * +clutter_backend_get_stage_window (ClutterBackend *backend) +{ + return backend->stage_window; +} + +/** + * clutter_backend_get_default_seat: + * @backend: the #ClutterBackend + * + * Returns the default seat + * + * Returns: (transfer none): the default seat + **/ +ClutterSeat * +clutter_backend_get_default_seat (ClutterBackend *backend) +{ + g_return_val_if_fail (CLUTTER_IS_BACKEND (backend), NULL); + + return CLUTTER_BACKEND_GET_CLASS (backend)->get_default_seat (backend); +} diff --git a/clutter/clutter/clutter-backend.h b/clutter/clutter/clutter-backend.h index 29f6a18a3..14f6c24d4 100644 --- a/clutter/clutter/clutter-backend.h +++ b/clutter/clutter/clutter-backend.h @@ -34,7 +34,9 @@ #include #include +#include #include +#include G_BEGIN_DECLS @@ -53,36 +55,33 @@ G_BEGIN_DECLS typedef struct _ClutterBackend ClutterBackend; typedef struct _ClutterBackendClass ClutterBackendClass; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT GType clutter_backend_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterBackend * clutter_get_default_backend (void); -CLUTTER_AVAILABLE_IN_1_16 -void clutter_set_windowing_backend (const char *backend_type); - -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gdouble clutter_backend_get_resolution (ClutterBackend *backend); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_backend_set_font_options (ClutterBackend *backend, const cairo_font_options_t *options); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT const cairo_font_options_t * clutter_backend_get_font_options (ClutterBackend *backend); -CLUTTER_AVAILABLE_IN_1_8 +CLUTTER_EXPORT CoglContext * clutter_backend_get_cogl_context (ClutterBackend *backend); -CLUTTER_AVAILABLE_IN_ALL -void clutter_backend_bell_notify (ClutterBackend *backend); - -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT ClutterInputMethod * clutter_backend_get_input_method (ClutterBackend *backend); -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT void clutter_backend_set_input_method (ClutterBackend *backend, ClutterInputMethod *method); +CLUTTER_EXPORT +ClutterSeat * clutter_backend_get_default_seat (ClutterBackend *backend); + G_END_DECLS #endif /* __CLUTTER_BACKEND_H__ */ diff --git a/clutter/clutter/clutter-base-types.c b/clutter/clutter/clutter-base-types.c index 1705ff98e..fcbcd2ec7 100644 --- a/clutter/clutter/clutter-base-types.c +++ b/clutter/clutter/clutter-base-types.c @@ -30,9 +30,7 @@ * across the whole API. */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include "clutter-types.h" #include "clutter-private.h" @@ -43,286 +41,6 @@ -/* - * ClutterGeometry - */ - -static ClutterGeometry* -clutter_geometry_copy (const ClutterGeometry *geometry) -{ - return g_slice_dup (ClutterGeometry, geometry); -} - -static void -clutter_geometry_free (ClutterGeometry *geometry) -{ - if (G_LIKELY (geometry != NULL)) - g_slice_free (ClutterGeometry, geometry); -} - -/** - * clutter_geometry_union: - * @geometry_a: a #ClutterGeometry - * @geometry_b: another #ClutterGeometry - * @result: (out): location to store the result - * - * Find the union of two rectangles represented as #ClutterGeometry. - * - * Since: 1.4 - * - * Deprecated: 1.16: Use #ClutterRect and clutter_rect_union() - */ -void -clutter_geometry_union (const ClutterGeometry *geometry_a, - const ClutterGeometry *geometry_b, - ClutterGeometry *result) -{ - /* We don't try to handle rectangles that can't be represented - * as a signed integer box */ - gint x_1 = MIN (geometry_a->x, geometry_b->x); - gint y_1 = MIN (geometry_a->y, geometry_b->y); - gint x_2 = MAX (geometry_a->x + (gint)geometry_a->width, - geometry_b->x + (gint)geometry_b->width); - gint y_2 = MAX (geometry_a->y + (gint)geometry_a->height, - geometry_b->y + (gint)geometry_b->height); - result->x = x_1; - result->y = y_1; - result->width = x_2 - x_1; - result->height = y_2 - y_1; -} - -/** - * clutter_geometry_intersects: - * @geometry0: The first geometry to test - * @geometry1: The second geometry to test - * - * Determines if @geometry0 and geometry1 intersect returning %TRUE if - * they do else %FALSE. - * - * Return value: %TRUE of @geometry0 and geometry1 intersect else - * %FALSE. - * - * Since: 1.4 - * - * Deprecated: 1.16: Use #ClutterRect and clutter_rect_intersection() - */ -gboolean -clutter_geometry_intersects (const ClutterGeometry *geometry0, - const ClutterGeometry *geometry1) -{ - if (geometry1->x >= (geometry0->x + (gint)geometry0->width) || - geometry1->y >= (geometry0->y + (gint)geometry0->height) || - (geometry1->x + (gint)geometry1->width) <= geometry0->x || - (geometry1->y + (gint)geometry1->height) <= geometry0->y) - return FALSE; - else - return TRUE; -} - -static gboolean -clutter_geometry_progress (const GValue *a, - const GValue *b, - gdouble progress, - GValue *retval) -{ - const ClutterGeometry *a_geom = g_value_get_boxed (a); - const ClutterGeometry *b_geom = g_value_get_boxed (b); - ClutterGeometry res = { 0, }; - gint a_width = a_geom->width; - gint b_width = b_geom->width; - gint a_height = a_geom->height; - gint b_height = b_geom->height; - - res.x = a_geom->x + (b_geom->x - a_geom->x) * progress; - res.y = a_geom->y + (b_geom->y - a_geom->y) * progress; - - res.width = a_width + (b_width - a_width) * progress; - res.height = a_height + (b_height - a_height) * progress; - - g_value_set_boxed (retval, &res); - - return TRUE; -} - -G_DEFINE_BOXED_TYPE_WITH_CODE (ClutterGeometry, clutter_geometry, - clutter_geometry_copy, - clutter_geometry_free, - CLUTTER_REGISTER_INTERVAL_PROGRESS (clutter_geometry_progress)); - - - -/* - * ClutterVertices - */ - -/** - * clutter_vertex_new: - * @x: X coordinate - * @y: Y coordinate - * @z: Z coordinate - * - * Creates a new #ClutterVertex for the point in 3D space - * identified by the 3 coordinates @x, @y, @z. - * - * This function is the logical equivalent of: - * - * |[ - * clutter_vertex_init (clutter_vertex_alloc (), x, y, z); - * ]| - * - * Return value: (transfer full): the newly allocated #ClutterVertex. - * Use clutter_vertex_free() to free the resources - * - * Since: 1.0 - */ -ClutterVertex * -clutter_vertex_new (gfloat x, - gfloat y, - gfloat z) -{ - return clutter_vertex_init (clutter_vertex_alloc (), x, y, z); -} - -/** - * clutter_vertex_alloc: (constructor) - * - * Allocates a new, empty #ClutterVertex. - * - * Return value: (transfer full): the newly allocated #ClutterVertex. - * Use clutter_vertex_free() to free its resources - * - * Since: 1.12 - */ -ClutterVertex * -clutter_vertex_alloc (void) -{ - return g_slice_new0 (ClutterVertex); -} - -/** - * clutter_vertex_init: - * @vertex: a #ClutterVertex - * @x: X coordinate - * @y: Y coordinate - * @z: Z coordinate - * - * Initializes @vertex with the given coordinates. - * - * Return value: (transfer none): the initialized #ClutterVertex - * - * Since: 1.10 - */ -ClutterVertex * -clutter_vertex_init (ClutterVertex *vertex, - gfloat x, - gfloat y, - gfloat z) -{ - g_return_val_if_fail (vertex != NULL, NULL); - - vertex->x = x; - vertex->y = y; - vertex->z = z; - - return vertex; -} - -/** - * clutter_vertex_copy: - * @vertex: a #ClutterVertex - * - * Copies @vertex - * - * Return value: (transfer full): a newly allocated copy of #ClutterVertex. - * Use clutter_vertex_free() to free the allocated resources - * - * Since: 1.0 - */ -ClutterVertex * -clutter_vertex_copy (const ClutterVertex *vertex) -{ - if (G_LIKELY (vertex != NULL)) - return g_slice_dup (ClutterVertex, vertex); - - return NULL; -} - -/** - * clutter_vertex_free: - * @vertex: a #ClutterVertex - * - * Frees a #ClutterVertex allocated using clutter_vertex_alloc() or - * clutter_vertex_copy(). - * - * Since: 1.0 - */ -void -clutter_vertex_free (ClutterVertex *vertex) -{ - if (G_UNLIKELY (vertex != NULL)) - g_slice_free (ClutterVertex, vertex); -} - -/** - * clutter_vertex_equal: - * @vertex_a: a #ClutterVertex - * @vertex_b: a #ClutterVertex - * - * Compares @vertex_a and @vertex_b for equality - * - * Return value: %TRUE if the passed #ClutterVertex are equal - * - * Since: 1.0 - */ -gboolean -clutter_vertex_equal (const ClutterVertex *vertex_a, - const ClutterVertex *vertex_b) -{ - g_return_val_if_fail (vertex_a != NULL && vertex_b != NULL, FALSE); - - if (vertex_a == vertex_b) - return TRUE; - - return fabsf (vertex_a->x - vertex_b->x) < FLOAT_EPSILON && - fabsf (vertex_a->y - vertex_b->y) < FLOAT_EPSILON && - fabsf (vertex_a->z - vertex_b->z) < FLOAT_EPSILON; -} - -static void -clutter_vertex_interpolate (const ClutterVertex *a, - const ClutterVertex *b, - double progress, - ClutterVertex *res) -{ - res->x = a->x + (b->x - a->x) * progress; - res->y = a->y + (b->y - a->y) * progress; - res->z = a->z + (b->z - a->z) * progress; -} - -static gboolean -clutter_vertex_progress (const GValue *a, - const GValue *b, - gdouble progress, - GValue *retval) -{ - const ClutterVertex *av = g_value_get_boxed (a); - const ClutterVertex *bv = g_value_get_boxed (b); - ClutterVertex res; - - clutter_vertex_interpolate (av, bv, progress, &res); - - g_value_set_boxed (retval, &res); - - return TRUE; -} - -G_DEFINE_BOXED_TYPE_WITH_CODE (ClutterVertex, clutter_vertex, - clutter_vertex_copy, - clutter_vertex_free, - CLUTTER_REGISTER_INTERVAL_PROGRESS (clutter_vertex_progress)); - - - /* * ClutterMargin */ @@ -384,900 +102,6 @@ G_DEFINE_BOXED_TYPE (ClutterMargin, clutter_margin, clutter_margin_copy, clutter_margin_free) - - -/* - * ClutterPoint - */ - -static const ClutterPoint _clutter_point_zero = CLUTTER_POINT_INIT_ZERO; - -/** - * clutter_point_zero: - * - * A point centered at (0, 0). - * - * The returned value can be used as a guard. - * - * Return value: a point centered in (0, 0); the returned #ClutterPoint - * is owned by Clutter and it should not be modified or freed. - * - * Since: 1.12 - */ -const ClutterPoint * -clutter_point_zero (void) -{ - return &_clutter_point_zero; -} - -/** - * clutter_point_alloc: (constructor) - * - * Allocates a new #ClutterPoint. - * - * Return value: (transfer full): the newly allocated #ClutterPoint. - * Use clutter_point_free() to free its resources. - * - * Since: 1.12 - */ -ClutterPoint * -clutter_point_alloc (void) -{ - return g_slice_new0 (ClutterPoint); -} - -/** - * clutter_point_init: - * @point: a #ClutterPoint - * @x: the X coordinate of the point - * @y: the Y coordinate of the point - * - * Initializes @point with the given coordinates. - * - * Return value: (transfer none): the initialized #ClutterPoint - * - * Since: 1.12 - */ -ClutterPoint * -clutter_point_init (ClutterPoint *point, - float x, - float y) -{ - g_return_val_if_fail (point != NULL, NULL); - - point->x = x; - point->y = y; - - return point; -} - -/** - * clutter_point_copy: - * @point: a #ClutterPoint - * - * Creates a new #ClutterPoint with the same coordinates of @point. - * - * Return value: (transfer full): a newly allocated #ClutterPoint. - * Use clutter_point_free() to free its resources. - * - * Since: 1.12 - */ -ClutterPoint * -clutter_point_copy (const ClutterPoint *point) -{ - return g_slice_dup (ClutterPoint, point); -} - -/** - * clutter_point_free: - * @point: a #ClutterPoint - * - * Frees the resources allocated for @point. - * - * Since: 1.12 - */ -void -clutter_point_free (ClutterPoint *point) -{ - if (point != NULL && point != &_clutter_point_zero) - g_slice_free (ClutterPoint, point); -} - -/** - * clutter_point_equals: - * @a: the first #ClutterPoint to compare - * @b: the second #ClutterPoint to compare - * - * Compares two #ClutterPoint for equality. - * - * Return value: %TRUE if the #ClutterPoints are equal - * - * Since: 1.12 - */ -gboolean -clutter_point_equals (const ClutterPoint *a, - const ClutterPoint *b) -{ - if (a == b) - return TRUE; - - if (a == NULL || b == NULL) - return FALSE; - - return fabsf (a->x - b->x) < FLOAT_EPSILON && - fabsf (a->y - b->y) < FLOAT_EPSILON; -} - -/** - * clutter_point_distance: - * @a: a #ClutterPoint - * @b: a #ClutterPoint - * @x_distance: (out) (allow-none): return location for the horizontal - * distance between the points - * @y_distance: (out) (allow-none): return location for the vertical - * distance between the points - * - * Computes the distance between two #ClutterPoint. - * - * Return value: the distance between the points. - * - * Since: 1.12 - */ -float -clutter_point_distance (const ClutterPoint *a, - const ClutterPoint *b, - float *x_distance, - float *y_distance) -{ - float x_d, y_d; - - g_return_val_if_fail (a != NULL, 0.f); - g_return_val_if_fail (b != NULL, 0.f); - - if (clutter_point_equals (a, b)) - return 0.f; - - x_d = (a->x - b->x); - y_d = (a->y - b->y); - - if (x_distance != NULL) - *x_distance = fabsf (x_d); - - if (y_distance != NULL) - *y_distance = fabsf (y_d); - - return sqrt ((x_d * x_d) + (y_d * y_d)); -} - -static gboolean -clutter_point_progress (const GValue *a, - const GValue *b, - gdouble progress, - GValue *retval) -{ - const ClutterPoint *ap = g_value_get_boxed (a); - const ClutterPoint *bp = g_value_get_boxed (b); - ClutterPoint res = CLUTTER_POINT_INIT (0, 0); - - res.x = ap->x + (bp->x - ap->x) * progress; - res.y = ap->y + (bp->y - ap->y) * progress; - - g_value_set_boxed (retval, &res); - - return TRUE; -} - -G_DEFINE_BOXED_TYPE_WITH_CODE (ClutterPoint, clutter_point, - clutter_point_copy, - clutter_point_free, - CLUTTER_REGISTER_INTERVAL_PROGRESS (clutter_point_progress)) - - - -/* - * ClutterSize - */ - -/** - * clutter_size_alloc: (constructor) - * - * Allocates a new #ClutterSize. - * - * Return value: (transfer full): the newly allocated #ClutterSize. - * Use clutter_size_free() to free its resources. - * - * Since: 1.12 - */ -ClutterSize * -clutter_size_alloc (void) -{ - return g_slice_new0 (ClutterSize); -} - -/** - * clutter_size_init: - * @size: a #ClutterSize - * @width: the width - * @height: the height - * - * Initializes a #ClutterSize with the given dimensions. - * - * Return value: (transfer none): the initialized #ClutterSize - * - * Since: 1.12 - */ -ClutterSize * -clutter_size_init (ClutterSize *size, - float width, - float height) -{ - g_return_val_if_fail (size != NULL, NULL); - - size->width = width; - size->height = height; - - return size; -} - -/** - * clutter_size_copy: - * @size: a #ClutterSize - * - * Creates a new #ClutterSize and duplicates @size. - * - * Return value: (transfer full): the newly allocated #ClutterSize. - * Use clutter_size_free() to free its resources. - * - * Since: 1.12 - */ -ClutterSize * -clutter_size_copy (const ClutterSize *size) -{ - return g_slice_dup (ClutterSize, size); -} - -/** - * clutter_size_free: - * @size: a #ClutterSize - * - * Frees the resources allocated for @size. - * - * Since: 1.12 - */ -void -clutter_size_free (ClutterSize *size) -{ - if (size != NULL) - g_slice_free (ClutterSize, size); -} - -/** - * clutter_size_equals: - * @a: a #ClutterSize to compare - * @b: a #ClutterSize to compare - * - * Compares two #ClutterSize for equality. - * - * Return value: %TRUE if the two #ClutterSize are equal - * - * Since: 1.12 - */ -gboolean -clutter_size_equals (const ClutterSize *a, - const ClutterSize *b) -{ - if (a == b) - return TRUE; - - if (a == NULL || b == NULL) - return FALSE; - - return fabsf (a->width - b->width) < FLOAT_EPSILON && - fabsf (a->height - b->height) < FLOAT_EPSILON; -} - -static gboolean -clutter_size_progress (const GValue *a, - const GValue *b, - gdouble progress, - GValue *retval) -{ - const ClutterSize *as = g_value_get_boxed (a); - const ClutterSize *bs = g_value_get_boxed (b); - ClutterSize res = CLUTTER_SIZE_INIT (0, 0); - - res.width = as->width + (bs->width - as->width) * progress; - res.height = as->height + (bs->height - as->height) * progress; - - g_value_set_boxed (retval, &res); - - return TRUE; -} - -G_DEFINE_BOXED_TYPE_WITH_CODE (ClutterSize, clutter_size, - clutter_size_copy, - clutter_size_free, - CLUTTER_REGISTER_INTERVAL_PROGRESS (clutter_size_progress)) - - - -/* - * ClutterRect - */ - -static const ClutterRect _clutter_rect_zero = CLUTTER_RECT_INIT_ZERO; - -static gboolean clutter_rect_progress (const GValue *a, - const GValue *b, - gdouble progress, - GValue *res); - -G_DEFINE_BOXED_TYPE_WITH_CODE (ClutterRect, clutter_rect, - clutter_rect_copy, - clutter_rect_free, - CLUTTER_REGISTER_INTERVAL_PROGRESS (clutter_rect_progress)) - -static inline void -clutter_rect_normalize_internal (ClutterRect *rect) -{ - if (rect->size.width >= 0.f && rect->size.height >= 0.f) - return; - - if (rect->size.width < 0.f) - { - float size = fabsf (rect->size.width); - - rect->origin.x -= size; - rect->size.width = size; - } - - if (rect->size.height < 0.f) - { - float size = fabsf (rect->size.height); - - rect->origin.y -= size; - rect->size.height = size; - } -} - -/** - * clutter_rect_zero: - * - * A #ClutterRect with #ClutterRect.origin set at (0, 0) and a size - * of 0. - * - * The returned value can be used as a guard. - * - * Return value: a rectangle with origin in (0, 0) and a size of 0. - * The returned #ClutterRect is owned by Clutter and it should not - * be modified or freed. - * - * Since: 1.12 - */ -const ClutterRect * -clutter_rect_zero (void) -{ - return &_clutter_rect_zero; -} - -/** - * clutter_rect_alloc: (constructor) - * - * Creates a new, empty #ClutterRect. - * - * You can use clutter_rect_init() to initialize the returned rectangle, - * for instance: - * - * |[ - * rect = clutter_rect_init (clutter_rect_alloc (), x, y, width, height); - * ]| - * - * Return value: (transfer full): the newly allocated #ClutterRect. - * Use clutter_rect_free() to free its resources - * - * Since: 1.12 - */ -ClutterRect * -clutter_rect_alloc (void) -{ - return g_slice_new0 (ClutterRect); -} - -/** - * clutter_rect_init: - * @rect: a #ClutterRect - * @x: X coordinate of the origin - * @y: Y coordinate of the origin - * @width: width of the rectangle - * @height: height of the rectangle - * - * Initializes a #ClutterRect with the given origin and size. - * - * Return value: (transfer none): the updated rectangle - * - * Since: 1.12 - */ -ClutterRect * -clutter_rect_init (ClutterRect *rect, - float x, - float y, - float width, - float height) -{ - g_return_val_if_fail (rect != NULL, NULL); - - rect->origin.x = x; - rect->origin.y = y; - - rect->size.width = width; - rect->size.height = height; - - return rect; -} - -/** - * clutter_rect_copy: - * @rect: a #ClutterRect - * - * Copies @rect into a new #ClutterRect instance. - * - * Return value: (transfer full): the newly allocate copy of @rect. - * Use clutter_rect_free() to free the associated resources - * - * Since: 1.12 - */ -ClutterRect * -clutter_rect_copy (const ClutterRect *rect) -{ - if (rect != NULL) - { - ClutterRect *res; - - res = g_slice_dup (ClutterRect, rect); - clutter_rect_normalize_internal (res); - - return res; - } - - return NULL; -} - -/** - * clutter_rect_free: - * @rect: a #ClutterRect - * - * Frees the resources allocated by @rect. - * - * Since: 1.12 - */ -void -clutter_rect_free (ClutterRect *rect) -{ - if (rect != NULL && rect != &_clutter_rect_zero) - g_slice_free (ClutterRect, rect); -} - -/** - * clutter_rect_equals: - * @a: a #ClutterRect - * @b: a #ClutterRect - * - * Checks whether @a and @b are equals. - * - * This function will normalize both @a and @b before comparing - * their origin and size. - * - * Return value: %TRUE if the rectangles match in origin and size. - * - * Since: 1.12 - */ -gboolean -clutter_rect_equals (ClutterRect *a, - ClutterRect *b) -{ - if (a == b) - return TRUE; - - if (a == NULL || b == NULL) - return FALSE; - - clutter_rect_normalize_internal (a); - clutter_rect_normalize_internal (b); - - return clutter_point_equals (&a->origin, &b->origin) && - clutter_size_equals (&a->size, &b->size); -} - -/** - * clutter_rect_normalize: - * @rect: a #ClutterRect - * - * Normalizes a #ClutterRect. - * - * A #ClutterRect is defined by the area covered by its size; this means - * that a #ClutterRect with #ClutterRect.origin in [ 0, 0 ] and a - * #ClutterRect.size of [ 10, 10 ] is equivalent to a #ClutterRect with - * #ClutterRect.origin in [ 10, 10 ] and a #ClutterRect.size of [ -10, -10 ]. - * - * This function is useful to ensure that a rectangle has positive width - * and height; it will modify the passed @rect and normalize its size. - * - * Since: 1.12 - */ -ClutterRect * -clutter_rect_normalize (ClutterRect *rect) -{ - g_return_val_if_fail (rect != NULL, NULL); - - clutter_rect_normalize_internal (rect); - - return rect; -} - -/** - * clutter_rect_get_center: - * @rect: a #ClutterRect - * @center: (out caller-allocates): a #ClutterPoint - * - * Retrieves the center of @rect, after normalizing the rectangle, - * and updates @center with the correct coordinates. - * - * Since: 1.12 - */ -void -clutter_rect_get_center (ClutterRect *rect, - ClutterPoint *center) -{ - g_return_if_fail (rect != NULL); - g_return_if_fail (center != NULL); - - clutter_rect_normalize_internal (rect); - - center->x = rect->origin.x + (rect->size.width / 2.0f); - center->y = rect->origin.y + (rect->size.height / 2.0f); -} - -/** - * clutter_rect_contains_point: - * @rect: a #ClutterRect - * @point: the point to check - * - * Checks whether @point is contained by @rect, after normalizing the - * rectangle. - * - * Return value: %TRUE if the @point is contained by @rect. - * - * Since: 1.12 - */ -gboolean -clutter_rect_contains_point (ClutterRect *rect, - ClutterPoint *point) -{ - g_return_val_if_fail (rect != NULL, FALSE); - g_return_val_if_fail (point != NULL, FALSE); - - clutter_rect_normalize_internal (rect); - - return (point->x >= rect->origin.x) && - (point->y >= rect->origin.y) && - (point->x <= (rect->origin.x + rect->size.width)) && - (point->y <= (rect->origin.y + rect->size.height)); -} - -/** - * clutter_rect_contains_rect: - * @a: a #ClutterRect - * @b: a #ClutterRect - * - * Checks whether @a contains @b. - * - * The first rectangle contains the second if the union of the - * two #ClutterRect is equal to the first rectangle. - * - * Return value: %TRUE if the first rectangle contains the second. - * - * Since: 1.12 - */ -gboolean -clutter_rect_contains_rect (ClutterRect *a, - ClutterRect *b) -{ - ClutterRect res; - - g_return_val_if_fail (a != NULL, FALSE); - g_return_val_if_fail (b != NULL, FALSE); - - clutter_rect_union (a, b, &res); - - return clutter_rect_equals (a, &res); -} - -/** - * clutter_rect_union: - * @a: a #ClutterRect - * @b: a #ClutterRect - * @res: (out caller-allocates): a #ClutterRect - * - * Computes the smallest possible rectangle capable of fully containing - * both @a and @b, and places it into @res. - * - * This function will normalize both @a and @b prior to computing their - * union. - * - * Since: 1.12 - */ -void -clutter_rect_union (ClutterRect *a, - ClutterRect *b, - ClutterRect *res) -{ - g_return_if_fail (a != NULL); - g_return_if_fail (b != NULL); - g_return_if_fail (res != NULL); - - clutter_rect_normalize_internal (a); - clutter_rect_normalize_internal (b); - - res->origin.x = MIN (a->origin.x, b->origin.x); - res->origin.y = MIN (a->origin.y, b->origin.y); - - res->size.width = MAX (a->size.width, b->size.width); - res->size.height = MAX (a->size.height, b->size.height); -} - -/** - * clutter_rect_intersection: - * @a: a #ClutterRect - * @b: a #ClutterRect - * @res: (out caller-allocates) (allow-none): a #ClutterRect, or %NULL - * - * Computes the intersection of @a and @b, and places it in @res, if @res - * is not %NULL. - * - * This function will normalize both @a and @b prior to computing their - * intersection. - * - * This function can be used to simply check if the intersection of @a and @b - * is not empty, by using %NULL for @res. - * - * Return value: %TRUE if the intersection of @a and @b is not empty - * - * Since: 1.12 - */ -gboolean -clutter_rect_intersection (ClutterRect *a, - ClutterRect *b, - ClutterRect *res) -{ - float x_1, y_1, x_2, y_2; - - g_return_val_if_fail (a != NULL, FALSE); - g_return_val_if_fail (b != NULL, FALSE); - - clutter_rect_normalize_internal (a); - clutter_rect_normalize_internal (b); - - x_1 = MAX (a->origin.x, b->origin.x); - y_1 = MAX (a->origin.y, b->origin.y); - x_2 = MIN (a->origin.x + a->size.width, b->origin.x + b->size.width); - y_2 = MIN (a->origin.y + a->size.height, b->origin.y + b->size.height); - - if (x_1 >= x_2 || y_1 >= y_2) - { - if (res != NULL) - clutter_rect_init (res, 0.f, 0.f, 0.f, 0.f); - - return FALSE; - } - - if (res != NULL) - clutter_rect_init (res, x_1, y_1, x_2 - x_1, y_2 - y_1); - - return TRUE; -} - -/** - * clutter_rect_offset: - * @rect: a #ClutterRect - * @d_x: the horizontal offset value - * @d_y: the vertical offset value - * - * Offsets the origin of @rect by the given values, after normalizing - * the rectangle. - * - * Since: 1.12 - */ -void -clutter_rect_offset (ClutterRect *rect, - float d_x, - float d_y) -{ - g_return_if_fail (rect != NULL); - - clutter_rect_normalize_internal (rect); - - rect->origin.x += d_x; - rect->origin.y += d_y; -} - -/** - * clutter_rect_inset: - * @rect: a #ClutterRect - * @d_x: an horizontal value; a positive @d_x will create an inset rectangle, - * and a negative value will create a larger rectangle - * @d_y: a vertical value; a positive @d_x will create an inset rectangle, - * and a negative value will create a larger rectangle - * - * Normalizes the @rect and offsets its origin by the @d_x and @d_y values; - * the size is adjusted by (2 * @d_x, 2 * @d_y). - * - * If @d_x and @d_y are positive the size of the rectangle is decreased; if - * the values are negative, the size of the rectangle is increased. - * - * If the resulting rectangle has a negative width or height, the size is - * set to 0. - * - * Since: 1.12 - */ -void -clutter_rect_inset (ClutterRect *rect, - float d_x, - float d_y) -{ - g_return_if_fail (rect != NULL); - - clutter_rect_normalize_internal (rect); - - rect->origin.x += d_x; - rect->origin.y += d_y; - - if (d_x >= 0.f) - rect->size.width -= (d_x * 2.f); - else - rect->size.width += (d_x * -2.f); - - if (d_y >= 0.f) - rect->size.height -= (d_y * 2.f); - else - rect->size.height += (d_y * -2.f); - - if (rect->size.width < 0.f) - rect->size.width = 0.f; - - if (rect->size.height < 0.f) - rect->size.height = 0.f; -} - -/** - * clutter_rect_clamp_to_pixel: - * @rect: a #ClutterRect - * - * Rounds the origin of @rect downwards to the nearest integer, and rounds - * the size of @rect upwards to the nearest integer, so that @rect is - * updated to the smallest rectangle capable of fully containing the - * original, fractional rectangle. - * - * Since: 1.12 - */ -void -clutter_rect_clamp_to_pixel (ClutterRect *rect) -{ - g_return_if_fail (rect != NULL); - - clutter_rect_normalize_internal (rect); - - rect->origin.x = floorf (rect->origin.x); - rect->origin.y = floorf (rect->origin.y); - - rect->size.width = ceilf (rect->size.width); - rect->size.height = ceilf (rect->size.height); -} - -/** - * clutter_rect_get_x: - * @rect: a #ClutterRect - * - * Retrieves the X coordinate of the origin of @rect. - * - * Return value: the X coordinate of the origin of the rectangle - * - * Since: 1.12 - */ -float -clutter_rect_get_x (ClutterRect *rect) -{ - g_return_val_if_fail (rect != NULL, 0.f); - - clutter_rect_normalize_internal (rect); - - return rect->origin.x; -} - -/** - * clutter_rect_get_y: - * @rect: a #ClutterRect - * - * Retrieves the Y coordinate of the origin of @rect. - * - * Return value: the Y coordinate of the origin of the rectangle - * - * Since: 1.12 - */ -float -clutter_rect_get_y (ClutterRect *rect) -{ - g_return_val_if_fail (rect != NULL, 0.f); - - clutter_rect_normalize_internal (rect); - - return rect->origin.y; -} - -/** - * clutter_rect_get_width: - * @rect: a #ClutterRect - * - * Retrieves the width of @rect. - * - * Return value: the width of the rectangle - * - * Since: 1.12 - */ -float -clutter_rect_get_width (ClutterRect *rect) -{ - g_return_val_if_fail (rect != NULL, 0.f); - - clutter_rect_normalize_internal (rect); - - return rect->size.width; -} - -/** - * clutter_rect_get_height: - * @rect: a #ClutterRect - * - * Retrieves the height of @rect. - * - * Return value: the height of the rectangle - * - * Since: 1.12 - */ -float -clutter_rect_get_height (ClutterRect *rect) -{ - g_return_val_if_fail (rect != NULL, 0.f); - - clutter_rect_normalize_internal (rect); - - return rect->size.height; -} - -static gboolean -clutter_rect_progress (const GValue *a, - const GValue *b, - gdouble progress, - GValue *retval) -{ - const ClutterRect *rect_a = g_value_get_boxed (a); - const ClutterRect *rect_b = g_value_get_boxed (b); - ClutterRect res = CLUTTER_RECT_INIT_ZERO; - -#define INTERPOLATE(r_a,r_b,member,field,factor) ((r_a)->member.field + (((r_b)->member.field - ((r_a)->member.field)) * (factor))) - - res.origin.x = INTERPOLATE (rect_a, rect_b, origin, x, progress); - res.origin.y = INTERPOLATE (rect_a, rect_b, origin, y, progress); - - res.size.width = INTERPOLATE (rect_a, rect_b, size, width, progress); - res.size.height = INTERPOLATE (rect_a, rect_b, size, height, progress); - -#undef INTERPOLATE - - g_value_set_boxed (retval, &res); - - return TRUE; -} - /** * ClutterMatrix: * @@ -1302,20 +126,20 @@ clutter_matrix_progress (const GValue *a, { const ClutterMatrix *matrix1 = g_value_get_boxed (a); const ClutterMatrix *matrix2 = g_value_get_boxed (b); - ClutterVertex scale1 = CLUTTER_VERTEX_INIT (1.f, 1.f, 1.f); + graphene_point3d_t scale1 = GRAPHENE_POINT3D_INIT (1.f, 1.f, 1.f); float shear1[3] = { 0.f, 0.f, 0.f }; - ClutterVertex rotate1 = CLUTTER_VERTEX_INIT_ZERO; - ClutterVertex translate1 = CLUTTER_VERTEX_INIT_ZERO; + graphene_point3d_t rotate1 = GRAPHENE_POINT3D_INIT_ZERO; + graphene_point3d_t translate1 = GRAPHENE_POINT3D_INIT_ZERO; ClutterVertex4 perspective1 = { 0.f, 0.f, 0.f, 0.f }; - ClutterVertex scale2 = CLUTTER_VERTEX_INIT (1.f, 1.f, 1.f); + graphene_point3d_t scale2 = GRAPHENE_POINT3D_INIT (1.f, 1.f, 1.f); float shear2[3] = { 0.f, 0.f, 0.f }; - ClutterVertex rotate2 = CLUTTER_VERTEX_INIT_ZERO; - ClutterVertex translate2 = CLUTTER_VERTEX_INIT_ZERO; + graphene_point3d_t rotate2 = GRAPHENE_POINT3D_INIT_ZERO; + graphene_point3d_t translate2 = GRAPHENE_POINT3D_INIT_ZERO; ClutterVertex4 perspective2 = { 0.f, 0.f, 0.f, 0.f }; - ClutterVertex scale_res = CLUTTER_VERTEX_INIT (1.f, 1.f, 1.f); + graphene_point3d_t scale_res = GRAPHENE_POINT3D_INIT (1.f, 1.f, 1.f); float shear_res = 0.f; - ClutterVertex rotate_res = CLUTTER_VERTEX_INIT_ZERO; - ClutterVertex translate_res = CLUTTER_VERTEX_INIT_ZERO; + graphene_point3d_t rotate_res = GRAPHENE_POINT3D_INIT_ZERO; + graphene_point3d_t translate_res = GRAPHENE_POINT3D_INIT_ZERO; ClutterVertex4 perspective_res = { 0.f, 0.f, 0.f, 0.f }; ClutterMatrix res; @@ -1336,11 +160,11 @@ clutter_matrix_progress (const GValue *a, res.ww = perspective_res.w; /* translation */ - clutter_vertex_interpolate (&translate1, &translate2, progress, &translate_res); + graphene_point3d_interpolate (&translate1, &translate2, progress, &translate_res); cogl_matrix_translate (&res, translate_res.x, translate_res.y, translate_res.z); /* rotation */ - clutter_vertex_interpolate (&rotate1, &rotate2, progress, &rotate_res); + graphene_point3d_interpolate (&rotate1, &rotate2, progress, &rotate_res); cogl_matrix_rotate (&res, rotate_res.x, 1.0f, 0.0f, 0.0f); cogl_matrix_rotate (&res, rotate_res.y, 0.0f, 1.0f, 0.0f); cogl_matrix_rotate (&res, rotate_res.z, 0.0f, 0.0f, 1.0f); @@ -1359,7 +183,7 @@ clutter_matrix_progress (const GValue *a, _clutter_util_matrix_skew_xy (&res, shear_res); /* scale */ - clutter_vertex_interpolate (&scale1, &scale2, progress, &scale_res); + graphene_point3d_interpolate (&scale1, &scale2, progress, &scale_res); cogl_matrix_scale (&res, scale_res.x, scale_res.y, scale_res.z); g_value_set_boxed (retval, &res); diff --git a/clutter/clutter/clutter-bezier.h b/clutter/clutter/clutter-bezier.h index df9f61767..a58c589c2 100644 --- a/clutter/clutter/clutter-bezier.h +++ b/clutter/clutter/clutter-bezier.h @@ -36,7 +36,7 @@ G_BEGIN_DECLS typedef struct _ClutterBezier ClutterBezier; -ClutterBezier *_clutter_bezier_new (); +ClutterBezier *_clutter_bezier_new (void); void _clutter_bezier_free (ClutterBezier * b); diff --git a/clutter/clutter/clutter-bin-layout.c b/clutter/clutter/clutter-bin-layout.c index 764f5bcf1..8c63b802c 100644 --- a/clutter/clutter/clutter-bin-layout.c +++ b/clutter/clutter/clutter-bin-layout.c @@ -43,18 +43,16 @@ * #ClutterBinLayout is available since Clutter 1.2 */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include #define CLUTTER_DISABLE_DEPRECATION_WARNINGS #include "deprecated/clutter-container.h" -#include "deprecated/clutter-bin-layout.h" #include "clutter-actor-private.h" #include "clutter-animatable.h" +#include "clutter-bin-layout.h" #include "clutter-child-meta.h" #include "clutter-debug.h" #include "clutter-enum-types.h" @@ -700,187 +698,3 @@ clutter_bin_layout_new (ClutterBinAlignment x_align, "y-align", y_align, NULL); } - -/** - * clutter_bin_layout_set_alignment: - * @self: a #ClutterBinLayout - * @child: (allow-none): a child of @container - * @x_align: the horizontal alignment policy to be used for the @child - * inside @container - * @y_align: the vertical aligment policy to be used on the @child - * inside @container - * - * Sets the horizontal and vertical alignment policies to be applied - * to a @child of @self - * - * If @child is %NULL then the @x_align and @y_align values will - * be set as the default alignment policies - * - * Since: 1.2 - * - * Deprecated: 1.12: Use the #ClutterActor:x-align and - * #ClutterActor:y-align properties of #ClutterActor instead. - */ -void -clutter_bin_layout_set_alignment (ClutterBinLayout *self, - ClutterActor *child, - ClutterBinAlignment x_align, - ClutterBinAlignment y_align) -{ - ClutterBinLayoutPrivate *priv; - ClutterLayoutManager *manager; - ClutterLayoutMeta *meta; - - g_return_if_fail (CLUTTER_IS_BIN_LAYOUT (self)); - g_return_if_fail (child == NULL || CLUTTER_IS_ACTOR (child)); - - priv = self->priv; - - if (priv->container == NULL) - { - if (child == NULL) - { - set_x_align (self, x_align); - set_y_align (self, y_align); - } - else - g_warning ("The layout of type '%s' must be associated to " - "a ClutterContainer before setting the alignment " - "on its children", - G_OBJECT_TYPE_NAME (self)); - - return; - } - - manager = CLUTTER_LAYOUT_MANAGER (self); - meta = clutter_layout_manager_get_child_meta (manager, - priv->container, - child); - g_assert (CLUTTER_IS_BIN_LAYER (meta)); - - set_layer_x_align (CLUTTER_BIN_LAYER (meta), x_align); - set_layer_y_align (CLUTTER_BIN_LAYER (meta), y_align); -} - -/** - * clutter_bin_layout_get_alignment: - * @self: a #ClutterBinLayout - * @child: (allow-none): a child of @container - * @x_align: (out) (allow-none): return location for the horizontal - * alignment policy - * @y_align: (out) (allow-none): return location for the vertical - * alignment policy - * - * Retrieves the horizontal and vertical alignment policies for - * a child of @self - * - * If @child is %NULL the default alignment policies will be returned - * instead - * - * Since: 1.2 - * - * Deprecated: 1.12: Use the #ClutterActor:x-align and the - * #ClutterActor:y-align properties of #ClutterActor instead. - */ -void -clutter_bin_layout_get_alignment (ClutterBinLayout *self, - ClutterActor *child, - ClutterBinAlignment *x_align, - ClutterBinAlignment *y_align) -{ - ClutterBinLayoutPrivate *priv; - ClutterLayoutManager *manager; - ClutterLayoutMeta *meta; - ClutterBinLayer *layer; - - g_return_if_fail (CLUTTER_IS_BIN_LAYOUT (self)); - - priv = self->priv; - - if (priv->container == NULL) - { - if (child == NULL) - { - if (x_align) - *x_align = priv->x_align; - - if (y_align) - *y_align = priv->y_align; - } - else - g_warning ("The layout of type '%s' must be associated to " - "a ClutterContainer before getting the alignment " - "of its children", - G_OBJECT_TYPE_NAME (self)); - - return; - } - - manager = CLUTTER_LAYOUT_MANAGER (self); - meta = clutter_layout_manager_get_child_meta (manager, - priv->container, - child); - g_assert (CLUTTER_IS_BIN_LAYER (meta)); - - layer = CLUTTER_BIN_LAYER (meta); - - if (x_align) - *x_align = layer->x_align; - - if (y_align) - *y_align = layer->y_align; -} - -/** - * clutter_bin_layout_add: - * @self: a #ClutterBinLayout - * @child: a #ClutterActor - * @x_align: horizontal alignment policy for @child - * @y_align: vertical alignment policy for @child - * - * Adds a #ClutterActor to the container using @self and - * sets the alignment policies for it - * - * This function is equivalent to clutter_container_add_actor() - * and clutter_layout_manager_child_set_property() but it does not - * require a pointer to the #ClutterContainer associated to the - * #ClutterBinLayout - * - * Since: 1.2 - * - * Deprecated: 1.12: Use clutter_actor_add_child() instead. - */ -void -clutter_bin_layout_add (ClutterBinLayout *self, - ClutterActor *child, - ClutterBinAlignment x_align, - ClutterBinAlignment y_align) -{ - ClutterBinLayoutPrivate *priv; - ClutterLayoutManager *manager; - ClutterLayoutMeta *meta; - - g_return_if_fail (CLUTTER_IS_BIN_LAYOUT (self)); - g_return_if_fail (CLUTTER_IS_ACTOR (child)); - - priv = self->priv; - - if (priv->container == NULL) - { - g_warning ("The layout of type '%s' must be associated to " - "a ClutterContainer before adding children", - G_OBJECT_TYPE_NAME (self)); - return; - } - - clutter_container_add_actor (priv->container, child); - - manager = CLUTTER_LAYOUT_MANAGER (self); - meta = clutter_layout_manager_get_child_meta (manager, - priv->container, - child); - g_assert (CLUTTER_IS_BIN_LAYER (meta)); - - set_layer_x_align (CLUTTER_BIN_LAYER (meta), x_align); - set_layer_y_align (CLUTTER_BIN_LAYER (meta), y_align); -} diff --git a/clutter/clutter/clutter-bin-layout.h b/clutter/clutter/clutter-bin-layout.h index f823b70f6..fa826d628 100644 --- a/clutter/clutter/clutter-bin-layout.h +++ b/clutter/clutter/clutter-bin-layout.h @@ -74,10 +74,10 @@ struct _ClutterBinLayoutClass ClutterLayoutManagerClass parent_class; }; -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT GType clutter_bin_layout_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT ClutterLayoutManager * clutter_bin_layout_new (ClutterBinAlignment x_align, ClutterBinAlignment y_align); diff --git a/clutter/clutter/clutter-bind-constraint.c b/clutter/clutter/clutter-bind-constraint.c index 93831f5c2..11eb5110e 100644 --- a/clutter/clutter/clutter-bind-constraint.c +++ b/clutter/clutter/clutter-bind-constraint.c @@ -80,9 +80,7 @@ * #ClutterBindConstraint is available since Clutter 1.4 */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include @@ -146,6 +144,55 @@ source_destroyed (ClutterActor *actor, bind->source = NULL; } +static void +clutter_bind_constraint_update_preferred_size (ClutterConstraint *constraint, + ClutterActor *actor, + ClutterOrientation direction, + float for_size, + float *minimum_size, + float *natural_size) +{ + ClutterBindConstraint *bind = CLUTTER_BIND_CONSTRAINT (constraint); + float source_min, source_nat; + + if (bind->source == NULL) + return; + + /* only these bindings affect the preferred size */ + if (!(bind->coordinate == CLUTTER_BIND_WIDTH || + bind->coordinate == CLUTTER_BIND_HEIGHT || + bind->coordinate == CLUTTER_BIND_SIZE || + bind->coordinate == CLUTTER_BIND_ALL)) + return; + + switch (direction) + { + case CLUTTER_ORIENTATION_HORIZONTAL: + if (bind->coordinate != CLUTTER_BIND_HEIGHT) + { + clutter_actor_get_preferred_width (bind->source, for_size, + &source_min, + &source_nat); + + *minimum_size = source_min; + *natural_size = source_nat; + } + break; + + case CLUTTER_ORIENTATION_VERTICAL: + if (bind->coordinate != CLUTTER_BIND_WIDTH) + { + clutter_actor_get_preferred_height (bind->source, for_size, + &source_min, + &source_nat); + + *minimum_size = source_min; + *natural_size = source_nat; + } + break; + } +} + static void clutter_bind_constraint_update_allocation (ClutterConstraint *constraint, ClutterActor *actor, @@ -154,7 +201,9 @@ clutter_bind_constraint_update_allocation (ClutterConstraint *constraint, ClutterBindConstraint *bind = CLUTTER_BIND_CONSTRAINT (constraint); gfloat source_width, source_height; gfloat actor_width, actor_height; - ClutterVertex source_position = { 0., }; + graphene_point3d_t source_position; + + source_position = GRAPHENE_POINT3D_INIT (0.f, 0.f, 0.f); if (bind->source == NULL) return; @@ -328,6 +377,8 @@ clutter_bind_constraint_class_init (ClutterBindConstraintClass *klass) meta_class->set_actor = clutter_bind_constraint_set_actor; constraint_class->update_allocation = clutter_bind_constraint_update_allocation; + constraint_class->update_preferred_size = clutter_bind_constraint_update_preferred_size; + /** * ClutterBindConstraint:source: * diff --git a/clutter/clutter/clutter-bind-constraint.h b/clutter/clutter/clutter-bind-constraint.h index 523fb18d3..16bf47899 100644 --- a/clutter/clutter/clutter-bind-constraint.h +++ b/clutter/clutter/clutter-bind-constraint.h @@ -48,28 +48,28 @@ G_BEGIN_DECLS typedef struct _ClutterBindConstraint ClutterBindConstraint; typedef struct _ClutterBindConstraintClass ClutterBindConstraintClass; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT GType clutter_bind_constraint_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT ClutterConstraint * clutter_bind_constraint_new (ClutterActor *source, ClutterBindCoordinate coordinate, gfloat offset); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_bind_constraint_set_source (ClutterBindConstraint *constraint, ClutterActor *source); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT ClutterActor * clutter_bind_constraint_get_source (ClutterBindConstraint *constraint); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_bind_constraint_set_coordinate (ClutterBindConstraint *constraint, ClutterBindCoordinate coordinate); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT ClutterBindCoordinate clutter_bind_constraint_get_coordinate (ClutterBindConstraint *constraint); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_bind_constraint_set_offset (ClutterBindConstraint *constraint, gfloat offset); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT gfloat clutter_bind_constraint_get_offset (ClutterBindConstraint *constraint); G_END_DECLS diff --git a/clutter/clutter/clutter-binding-pool.c b/clutter/clutter/clutter-binding-pool.c index 9c24b639e..60144baf9 100644 --- a/clutter/clutter/clutter-binding-pool.c +++ b/clutter/clutter/clutter-binding-pool.c @@ -94,9 +94,7 @@ * #ClutterBindingPool is available since Clutter 1.0 */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include "clutter-binding-pool.h" #include "clutter-debug.h" @@ -237,8 +235,7 @@ clutter_binding_pool_finalize (GObject *gobject) g_hash_table_destroy (pool->entries_hash); - g_slist_foreach (pool->entries, (GFunc) binding_entry_free, NULL); - g_slist_free (pool->entries); + g_slist_free_full (pool->entries, (GDestroyNotify) binding_entry_free); G_OBJECT_CLASS (clutter_binding_pool_parent_class)->finalize (gobject); } diff --git a/clutter/clutter/clutter-binding-pool.h b/clutter/clutter/clutter-binding-pool.h index 2830d2711..dcf771d24 100644 --- a/clutter/clutter/clutter-binding-pool.h +++ b/clutter/clutter/clutter-binding-pool.h @@ -71,17 +71,17 @@ typedef gboolean (* ClutterBindingActionFunc) (GObject *gobject, ClutterModifierType modifiers, gpointer user_data); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT GType clutter_binding_pool_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT ClutterBindingPool * clutter_binding_pool_new (const gchar *name); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT ClutterBindingPool * clutter_binding_pool_get_for_class (gpointer klass); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT ClutterBindingPool * clutter_binding_pool_find (const gchar *name); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_binding_pool_install_action (ClutterBindingPool *pool, const gchar *action_name, guint key_val, @@ -89,44 +89,44 @@ void clutter_binding_pool_install_action (ClutterBindingPool GCallback callback, gpointer data, GDestroyNotify notify); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_binding_pool_install_closure (ClutterBindingPool *pool, const gchar *action_name, guint key_val, ClutterModifierType modifiers, GClosure *closure); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_binding_pool_override_action (ClutterBindingPool *pool, guint key_val, ClutterModifierType modifiers, GCallback callback, gpointer data, GDestroyNotify notify); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_binding_pool_override_closure (ClutterBindingPool *pool, guint key_val, ClutterModifierType modifiers, GClosure *closure); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT const gchar * clutter_binding_pool_find_action (ClutterBindingPool *pool, guint key_val, ClutterModifierType modifiers); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_binding_pool_remove_action (ClutterBindingPool *pool, guint key_val, ClutterModifierType modifiers); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT gboolean clutter_binding_pool_activate (ClutterBindingPool *pool, guint key_val, ClutterModifierType modifiers, GObject *gobject); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_binding_pool_block_action (ClutterBindingPool *pool, const gchar *action_name); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_binding_pool_unblock_action (ClutterBindingPool *pool, const gchar *action_name); diff --git a/clutter/clutter/clutter-blur-effect.c b/clutter/clutter/clutter-blur-effect.c index 21cb3b4f3..5236042de 100644 --- a/clutter/clutter/clutter-blur-effect.c +++ b/clutter/clutter/clutter-blur-effect.c @@ -37,9 +37,7 @@ #define CLUTTER_IS_BLUR_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BLUR_EFFECT)) #define CLUTTER_BLUR_EFFECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_BLUR_EFFECT, ClutterBlurEffectClass)) -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #define CLUTTER_ENABLE_EXPERIMENTAL_API @@ -101,7 +99,8 @@ G_DEFINE_TYPE (ClutterBlurEffect, CLUTTER_TYPE_OFFSCREEN_EFFECT); static gboolean -clutter_blur_effect_pre_paint (ClutterEffect *effect) +clutter_blur_effect_pre_paint (ClutterEffect *effect, + ClutterPaintContext *paint_context) { ClutterBlurEffect *self = CLUTTER_BLUR_EFFECT (effect); ClutterEffectClass *parent_class; @@ -126,7 +125,7 @@ clutter_blur_effect_pre_paint (ClutterEffect *effect) } parent_class = CLUTTER_EFFECT_CLASS (clutter_blur_effect_parent_class); - if (parent_class->pre_paint (effect)) + if (parent_class->pre_paint (effect, paint_context)) { ClutterOffscreenEffect *offscreen_effect = CLUTTER_OFFSCREEN_EFFECT (effect); @@ -159,9 +158,12 @@ clutter_blur_effect_pre_paint (ClutterEffect *effect) } static void -clutter_blur_effect_paint_target (ClutterOffscreenEffect *effect) +clutter_blur_effect_paint_target (ClutterOffscreenEffect *effect, + ClutterPaintContext *paint_context) { ClutterBlurEffect *self = CLUTTER_BLUR_EFFECT (effect); + CoglFramebuffer *framebuffer = + clutter_paint_context_get_framebuffer (paint_context); guint8 paint_opacity; paint_opacity = clutter_actor_get_paint_opacity (self->actor); @@ -171,19 +173,19 @@ clutter_blur_effect_paint_target (ClutterOffscreenEffect *effect) paint_opacity, paint_opacity, paint_opacity); - cogl_push_source (self->pipeline); - cogl_rectangle (0, 0, self->tex_width, self->tex_height); - - cogl_pop_source (); + cogl_framebuffer_draw_rectangle (framebuffer, + self->pipeline, + 0, 0, + self->tex_width, self->tex_height); } static gboolean -clutter_blur_effect_get_paint_volume (ClutterEffect *effect, - ClutterPaintVolume *volume) +clutter_blur_effect_modify_paint_volume (ClutterEffect *effect, + ClutterPaintVolume *volume) { gfloat cur_width, cur_height; - ClutterVertex origin; + graphene_point3d_t origin; clutter_paint_volume_get_origin (volume, &origin); cur_width = clutter_paint_volume_get_width (volume); @@ -224,7 +226,7 @@ clutter_blur_effect_class_init (ClutterBlurEffectClass *klass) gobject_class->dispose = clutter_blur_effect_dispose; effect_class->pre_paint = clutter_blur_effect_pre_paint; - effect_class->get_paint_volume = clutter_blur_effect_get_paint_volume; + effect_class->modify_paint_volume = clutter_blur_effect_modify_paint_volume; offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass); offscreen_class->paint_target = clutter_blur_effect_paint_target; @@ -250,9 +252,7 @@ clutter_blur_effect_init (ClutterBlurEffect *self) cogl_pipeline_add_layer_snippet (klass->base_pipeline, 0, snippet); cogl_object_unref (snippet); - cogl_pipeline_set_layer_null_texture (klass->base_pipeline, - 0, /* layer number */ - COGL_TEXTURE_TYPE_2D); + cogl_pipeline_set_layer_null_texture (klass->base_pipeline, 0); } self->pipeline = cogl_pipeline_copy (klass->base_pipeline); diff --git a/clutter/clutter/clutter-blur-effect.h b/clutter/clutter/clutter-blur-effect.h index 4e1b83ed2..0739a75bd 100644 --- a/clutter/clutter/clutter-blur-effect.h +++ b/clutter/clutter/clutter-blur-effect.h @@ -48,10 +48,10 @@ G_BEGIN_DECLS typedef struct _ClutterBlurEffect ClutterBlurEffect; typedef struct _ClutterBlurEffectClass ClutterBlurEffectClass; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT GType clutter_blur_effect_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT ClutterEffect *clutter_blur_effect_new (void); G_END_DECLS diff --git a/clutter/clutter/clutter-box-layout.c b/clutter/clutter/clutter-box-layout.c index 49c8d45d4..223b5204c 100644 --- a/clutter/clutter/clutter-box-layout.c +++ b/clutter/clutter/clutter-box-layout.c @@ -48,9 +48,7 @@ * #ClutterBoxLayout is available since Clutter 1.2 */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include @@ -152,9 +150,9 @@ typedef struct _RequestedSize gfloat natural_size; } RequestedSize; -static gint distribute_natural_allocation (gint extra_space, - guint n_requested_sizes, - RequestedSize *sizes); +static float distribute_natural_allocation (float extra_space, + unsigned int n_requested_sizes, + RequestedSize *sizes); static void count_expand_children (ClutterLayoutManager *layout, ClutterContainer *container, gint *visible_children, @@ -477,8 +475,10 @@ get_preferred_size_for_orientation (ClutterBoxLayout *self, ClutterActor *child; gint n_children = 0; gfloat minimum, natural; + float largest_min_size, largest_nat_size; minimum = natural = 0; + largest_min_size = largest_nat_size = 0; clutter_actor_iter_init (&iter, container); while (clutter_actor_iter_next (&iter, &child)) @@ -493,8 +493,22 @@ get_preferred_size_for_orientation (ClutterBoxLayout *self, get_child_size (child, priv->orientation, for_size, &child_min, &child_nat); - minimum += child_min; - natural += child_nat; + if (priv->is_homogeneous) + { + largest_min_size = MAX (largest_min_size, child_min); + largest_nat_size = MAX (largest_nat_size, child_nat); + } + else + { + minimum += child_min; + natural += child_nat; + } + } + + if (priv->is_homogeneous) + { + minimum = largest_min_size * n_children; + natural = largest_nat_size * n_children; } if (n_children > 1) @@ -625,8 +639,22 @@ get_preferred_size_for_opposite_orientation (ClutterBoxLayout *self, } else { + size -= (nvis_children - 1) * priv->spacing; + /* Bring children up to size first */ - size = distribute_natural_allocation (MAX (0, size), nvis_children, sizes); + if (isnormal (size) || size == 0) + { + size = distribute_natural_allocation (MAX (0, size), + nvis_children, + sizes); + } + else + { + g_critical ("Actor %s (%p) received the invalid " + "value %f as minimum/natural size\n", + G_OBJECT_TYPE_NAME (container), container, size); + size = 0; + } /* Calculate space which hasn't distributed yet, * and is available for expanding children. @@ -881,17 +909,18 @@ compare_gap (gconstpointer p1, * * Pulled from gtksizerequest.c from Gtk+ */ -static gint -distribute_natural_allocation (gint extra_space, - guint n_requested_sizes, +static float +distribute_natural_allocation (float extra_space, + unsigned int n_requested_sizes, RequestedSize *sizes) { - guint *spreading; - gint i; + unsigned int *spreading; + int i; + g_return_val_if_fail (isnormal (extra_space) || extra_space == 0, 0); g_return_val_if_fail (extra_space >= 0, 0); - spreading = g_newa (guint, n_requested_sizes); + spreading = g_newa (unsigned int, n_requested_sizes); for (i = 0; i < n_requested_sizes; i++) spreading[i] = i; @@ -915,7 +944,7 @@ distribute_natural_allocation (gint extra_space, /* Sort descending by gap and position. */ g_qsort_with_data (spreading, - n_requested_sizes, sizeof (guint), + n_requested_sizes, sizeof (unsigned int), compare_gap, sizes); /* Distribute available space. @@ -927,11 +956,11 @@ distribute_natural_allocation (gint extra_space, * Sort order and reducing remaining space by assigned space * ensures that space is distributed equally. */ - gint glue = (extra_space + i) / (i + 1); - gint gap = sizes[(spreading[i])].natural_size - - sizes[(spreading[i])].minimum_size; + int glue = (extra_space + i) / (i + 1); + int gap = sizes[(spreading[i])].natural_size + - sizes[(spreading[i])].minimum_size; - gint extra = MIN (glue, gap); + int extra = MIN (glue, gap); sizes[spreading[i]].minimum_size += extra; @@ -1058,7 +1087,9 @@ clutter_box_layout_allocate (ClutterLayoutManager *layout, else { /* Bring children up to size first */ - size = distribute_natural_allocation (MAX (0, size), nvis_children, sizes); + size = (gint) distribute_natural_allocation (MAX (0, (float) size), + nvis_children, + sizes); /* Calculate space which hasn't distributed yet, * and is available for expanding children. diff --git a/clutter/clutter/clutter-box-layout.h b/clutter/clutter/clutter-box-layout.h index a5c085c1f..fdced8f41 100644 --- a/clutter/clutter/clutter-box-layout.h +++ b/clutter/clutter/clutter-box-layout.h @@ -77,41 +77,41 @@ struct _ClutterBoxLayoutClass ClutterLayoutManagerClass parent_class; }; -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT GType clutter_box_layout_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT ClutterLayoutManager * clutter_box_layout_new (void); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_box_layout_set_orientation (ClutterBoxLayout *layout, ClutterOrientation orientation); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT ClutterOrientation clutter_box_layout_get_orientation (ClutterBoxLayout *layout); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT void clutter_box_layout_set_spacing (ClutterBoxLayout *layout, guint spacing); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT guint clutter_box_layout_get_spacing (ClutterBoxLayout *layout); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT void clutter_box_layout_set_homogeneous (ClutterBoxLayout *layout, gboolean homogeneous); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT gboolean clutter_box_layout_get_homogeneous (ClutterBoxLayout *layout); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT void clutter_box_layout_set_pack_start (ClutterBoxLayout *layout, gboolean pack_start); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT gboolean clutter_box_layout_get_pack_start (ClutterBoxLayout *layout); -CLUTTER_DEPRECATED_IN_1_12_FOR(clutter_box_layout_set_orientation) +CLUTTER_DEPRECATED_FOR(clutter_box_layout_set_orientation) void clutter_box_layout_set_vertical (ClutterBoxLayout *layout, gboolean vertical); -CLUTTER_DEPRECATED_IN_1_12_FOR(clutter_box_layout_get_orientation) +CLUTTER_DEPRECATED_FOR(clutter_box_layout_get_orientation) gboolean clutter_box_layout_get_vertical (ClutterBoxLayout *layout); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT void clutter_box_layout_pack (ClutterBoxLayout *layout, ClutterActor *actor, gboolean expand, @@ -119,48 +119,48 @@ void clutter_box_layout_pack (ClutterBoxLayou gboolean y_fill, ClutterBoxAlignment x_align, ClutterBoxAlignment y_align); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED void clutter_box_layout_set_alignment (ClutterBoxLayout *layout, ClutterActor *actor, ClutterBoxAlignment x_align, ClutterBoxAlignment y_align); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED void clutter_box_layout_get_alignment (ClutterBoxLayout *layout, ClutterActor *actor, ClutterBoxAlignment *x_align, ClutterBoxAlignment *y_align); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED void clutter_box_layout_set_fill (ClutterBoxLayout *layout, ClutterActor *actor, gboolean x_fill, gboolean y_fill); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED void clutter_box_layout_get_fill (ClutterBoxLayout *layout, ClutterActor *actor, gboolean *x_fill, gboolean *y_fill); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED void clutter_box_layout_set_expand (ClutterBoxLayout *layout, ClutterActor *actor, gboolean expand); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED gboolean clutter_box_layout_get_expand (ClutterBoxLayout *layout, ClutterActor *actor); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED void clutter_box_layout_set_use_animations (ClutterBoxLayout *layout, gboolean animate); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED gboolean clutter_box_layout_get_use_animations (ClutterBoxLayout *layout); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED void clutter_box_layout_set_easing_mode (ClutterBoxLayout *layout, gulong mode); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED gulong clutter_box_layout_get_easing_mode (ClutterBoxLayout *layout); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED void clutter_box_layout_set_easing_duration (ClutterBoxLayout *layout, guint msecs); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED guint clutter_box_layout_get_easing_duration (ClutterBoxLayout *layout); G_END_DECLS diff --git a/clutter/clutter/clutter-brightness-contrast-effect.c b/clutter/clutter/clutter-brightness-contrast-effect.c index 7b3839153..be1df01cc 100644 --- a/clutter/clutter/clutter-brightness-contrast-effect.c +++ b/clutter/clutter/clutter-brightness-contrast-effect.c @@ -37,9 +37,7 @@ #define CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BRIGHTNESS_CONTRAST_EFFECT)) #define CLUTTER_BRIGHTNESS_CONTRAST_EFFECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_BRIGHTNESS_CONTRAST_EFFECT, ClutterBrightnessContrastEffectClass)) -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include @@ -123,16 +121,17 @@ G_DEFINE_TYPE (ClutterBrightnessContrastEffect, static gboolean will_have_no_effect (ClutterBrightnessContrastEffect *self) { - return (self->brightness_red == no_change && - self->brightness_green == no_change && - self->brightness_blue == no_change && - self->contrast_red == no_change && - self->contrast_green == no_change && - self->contrast_blue == no_change); + return (G_APPROX_VALUE (self->brightness_red, no_change, FLT_EPSILON) && + G_APPROX_VALUE (self->brightness_green, no_change, FLT_EPSILON) && + G_APPROX_VALUE (self->brightness_blue, no_change, FLT_EPSILON) && + G_APPROX_VALUE (self->contrast_red, no_change, FLT_EPSILON) && + G_APPROX_VALUE (self->contrast_green, no_change, FLT_EPSILON) && + G_APPROX_VALUE (self->contrast_blue, no_change, FLT_EPSILON)); } static gboolean -clutter_brightness_contrast_effect_pre_paint (ClutterEffect *effect) +clutter_brightness_contrast_effect_pre_paint (ClutterEffect *effect, + ClutterPaintContext *paint_context) { ClutterBrightnessContrastEffect *self = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (effect); ClutterEffectClass *parent_class; @@ -158,7 +157,7 @@ clutter_brightness_contrast_effect_pre_paint (ClutterEffect *effect) parent_class = CLUTTER_EFFECT_CLASS (clutter_brightness_contrast_effect_parent_class); - if (parent_class->pre_paint (effect)) + if (parent_class->pre_paint (effect, paint_context)) { ClutterOffscreenEffect *offscreen_effect = CLUTTER_OFFSCREEN_EFFECT (effect); @@ -177,9 +176,12 @@ clutter_brightness_contrast_effect_pre_paint (ClutterEffect *effect) } static void -clutter_brightness_contrast_effect_paint_target (ClutterOffscreenEffect *effect) +clutter_brightness_contrast_effect_paint_target (ClutterOffscreenEffect *effect, + ClutterPaintContext *paint_context) { ClutterBrightnessContrastEffect *self = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (effect); + CoglFramebuffer *framebuffer = + clutter_paint_context_get_framebuffer (paint_context); ClutterActor *actor; guint8 paint_opacity; @@ -191,11 +193,11 @@ clutter_brightness_contrast_effect_paint_target (ClutterOffscreenEffect *effect) paint_opacity, paint_opacity, paint_opacity); - cogl_push_source (self->pipeline); - cogl_rectangle (0, 0, self->tex_width, self->tex_height); - - cogl_pop_source (); + cogl_framebuffer_draw_rectangle (framebuffer, + self->pipeline, + 0, 0, + self->tex_width, self->tex_height); } static void @@ -439,9 +441,7 @@ clutter_brightness_contrast_effect_init (ClutterBrightnessContrastEffect *self) cogl_pipeline_add_snippet (klass->base_pipeline, snippet); cogl_object_unref (snippet); - cogl_pipeline_set_layer_null_texture (klass->base_pipeline, - 0, /* layer number */ - COGL_TEXTURE_TYPE_2D); + cogl_pipeline_set_layer_null_texture (klass->base_pipeline, 0); } self->pipeline = cogl_pipeline_copy (klass->base_pipeline); @@ -497,9 +497,9 @@ clutter_brightness_contrast_effect_set_brightness_full (ClutterBrightnessContras { g_return_if_fail (CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT (effect)); - if (red == effect->brightness_red && - green == effect->brightness_green && - blue == effect->brightness_blue) + if (G_APPROX_VALUE (red, effect->brightness_red, FLT_EPSILON) && + G_APPROX_VALUE (green, effect->brightness_green, FLT_EPSILON) && + G_APPROX_VALUE (blue, effect->brightness_blue, FLT_EPSILON)) return; effect->brightness_red = red; @@ -587,9 +587,9 @@ clutter_brightness_contrast_effect_set_contrast_full (ClutterBrightnessContrastE { g_return_if_fail (CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT (effect)); - if (red == effect->contrast_red && - green == effect->contrast_green && - blue == effect->contrast_blue) + if (G_APPROX_VALUE (red, effect->contrast_red, FLT_EPSILON) && + G_APPROX_VALUE (green, effect->contrast_green, FLT_EPSILON) && + G_APPROX_VALUE (blue, effect->contrast_blue, FLT_EPSILON)) return; effect->contrast_red = red; diff --git a/clutter/clutter/clutter-brightness-contrast-effect.h b/clutter/clutter/clutter-brightness-contrast-effect.h index 0d9094a19..d474ed5b8 100644 --- a/clutter/clutter/clutter-brightness-contrast-effect.h +++ b/clutter/clutter/clutter-brightness-contrast-effect.h @@ -49,35 +49,35 @@ G_BEGIN_DECLS typedef struct _ClutterBrightnessContrastEffect ClutterBrightnessContrastEffect; typedef struct _ClutterBrightnessContrastEffectClass ClutterBrightnessContrastEffectClass; -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT GType clutter_brightness_contrast_effect_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT ClutterEffect * clutter_brightness_contrast_effect_new (void); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_brightness_contrast_effect_set_brightness_full (ClutterBrightnessContrastEffect *effect, float red, float green, float blue); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_brightness_contrast_effect_set_brightness (ClutterBrightnessContrastEffect *effect, float brightness); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_brightness_contrast_effect_get_brightness (ClutterBrightnessContrastEffect *effect, float *red, float *green, float *blue); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_brightness_contrast_effect_set_contrast_full (ClutterBrightnessContrastEffect *effect, float red, float green, float blue); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_brightness_contrast_effect_set_contrast (ClutterBrightnessContrastEffect *effect, float contrast); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_brightness_contrast_effect_get_contrast (ClutterBrightnessContrastEffect *effect, float *red, float *green, diff --git a/clutter/clutter/clutter-build-config.h.meson b/clutter/clutter/clutter-build-config.h.meson new file mode 100644 index 000000000..db77698c3 --- /dev/null +++ b/clutter/clutter/clutter-build-config.h.meson @@ -0,0 +1,14 @@ +/* Mutter version */ +#mesondefine MUTTER_VERSION + +/* List of Cogl drivers */ +#mesondefine CLUTTER_DRIVERS + +/* Have evdev support for input handling */ +#mesondefine HAVE_EVDEV + +/* Building with libwacom for advanced tablet management */ +#mesondefine HAVE_LIBWACOM + +/* Supports PangoFt2 */ +#mesondefine HAVE_PANGO_FT2 diff --git a/clutter/clutter/clutter-cairo.c b/clutter/clutter/clutter-cairo.c index b5c24b24f..164eac310 100644 --- a/clutter/clutter/clutter-cairo.c +++ b/clutter/clutter/clutter-cairo.c @@ -27,9 +27,7 @@ * Clutter provides some utility functions for using Cairo. */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include "clutter-cairo.h" #include "clutter-color.h" diff --git a/clutter/clutter/clutter-cairo.h b/clutter/clutter/clutter-cairo.h index 9b2ad05a2..5fba04d10 100644 --- a/clutter/clutter/clutter-cairo.h +++ b/clutter/clutter/clutter-cairo.h @@ -50,9 +50,9 @@ G_BEGIN_DECLS #define CLUTTER_CAIRO_FORMAT_ARGB32 (COGL_PIXEL_FORMAT_ARGB_8888_PRE) #endif -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_cairo_clear (cairo_t *cr); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_cairo_set_source_color (cairo_t *cr, const ClutterColor *color); diff --git a/clutter/clutter/clutter-canvas.c b/clutter/clutter/clutter-canvas.c index 42e54ce9d..43af0b98f 100644 --- a/clutter/clutter/clutter-canvas.c +++ b/clutter/clutter/clutter-canvas.c @@ -42,10 +42,9 @@ * #ClutterCanvas is available since Clutter 1.10. */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif +#include #include #include @@ -71,6 +70,7 @@ struct _ClutterCanvasPrivate int width; int height; + float scale_factor; CoglTexture *texture; gboolean dirty; @@ -84,6 +84,7 @@ enum PROP_WIDTH, PROP_HEIGHT, + PROP_SCALE_FACTOR, LAST_PROP }; @@ -99,7 +100,7 @@ enum static guint canvas_signals[LAST_SIGNAL] = { 0, }; -static void clutter_content_iface_init (ClutterContentIface *iface); +static void clutter_content_iface_init (ClutterContentInterface *iface); G_DEFINE_TYPE_WITH_CODE (ClutterCanvas, clutter_canvas, G_TYPE_OBJECT, G_ADD_PRIVATE (ClutterCanvas) @@ -180,6 +181,19 @@ clutter_canvas_set_property (GObject *gobject, } break; + case PROP_SCALE_FACTOR: + { + gfloat new_scale_factor = g_value_get_float (value); + + if (priv->scale_factor != new_scale_factor) + { + priv->scale_factor = new_scale_factor; + + clutter_content_invalidate (CLUTTER_CONTENT (gobject)); + } + } + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); break; @@ -204,6 +218,10 @@ clutter_canvas_get_property (GObject *gobject, g_value_set_int (value, priv->height); break; + case PROP_SCALE_FACTOR: + g_value_set_float (value, priv->scale_factor); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); break; @@ -247,6 +265,19 @@ clutter_canvas_class_init (ClutterCanvasClass *klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** + * ClutterCanvas:scale-factor: + * + * The height of the canvas. + */ + obj_props[PROP_SCALE_FACTOR] = + g_param_spec_float ("scale-factor", + P_("Scale Factor"), + P_("The Scale factor of the canvas"), + 0.01f, G_MAXFLOAT, + 1.0f, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS); /** * ClutterCanvas::draw: @@ -293,12 +324,14 @@ clutter_canvas_init (ClutterCanvas *self) self->priv->width = -1; self->priv->height = -1; + self->priv->scale_factor = 1.0f; } static void -clutter_canvas_paint_content (ClutterContent *content, - ClutterActor *actor, - ClutterPaintNode *root) +clutter_canvas_paint_content (ClutterContent *content, + ClutterActor *actor, + ClutterPaintNode *root, + ClutterPaintContext *paint_context) { ClutterCanvas *self = CLUTTER_CANVAS (content); ClutterCanvasPrivate *priv = self->priv; @@ -319,7 +352,7 @@ clutter_canvas_paint_content (ClutterContent *content, return; node = clutter_actor_create_texture_paint_node (actor, priv->texture); - clutter_paint_node_set_name (node, "Canvas Content"); + clutter_paint_node_set_static_name (node, "Canvas Content"); clutter_paint_node_add_child (root, node); clutter_paint_node_unref (node); @@ -342,8 +375,8 @@ clutter_canvas_emit_draw (ClutterCanvas *self) priv->dirty = TRUE; - real_width = priv->width; - real_height = priv->height; + real_width = ceilf (priv->width * priv->scale_factor); + real_height = ceilf (priv->height * priv->scale_factor); CLUTTER_NOTE (MISC, "Creating Cairo surface with size %d x %d", priv->width, priv->height); @@ -389,6 +422,10 @@ clutter_canvas_emit_draw (ClutterCanvas *self) mapped_buffer = FALSE; } + cairo_surface_set_device_scale (surface, + priv->scale_factor, + priv->scale_factor); + self->priv->cr = cr = cairo_create (surface); g_signal_emit (self, canvas_signals[DRAW], 0, @@ -450,16 +487,16 @@ clutter_canvas_get_preferred_size (ClutterContent *content, return FALSE; if (width != NULL) - *width = priv->width; + *width = ceilf (priv->width * priv->scale_factor); if (height != NULL) - *height = priv->height; + *height = ceilf (priv->height * priv->scale_factor); return TRUE; } static void -clutter_content_iface_init (ClutterContentIface *iface) +clutter_content_iface_init (ClutterContentInterface *iface) { iface->invalidate = clutter_canvas_invalidate; iface->paint_content = clutter_canvas_paint_content; @@ -562,3 +599,48 @@ clutter_canvas_set_size (ClutterCanvas *canvas, return clutter_canvas_invalidate_internal (canvas, width, height); } + +/** + * clutter_canvas_set_scale_factor: + * @canvas: a #ClutterCanvas + * @scale: the integer scaling factor of the canvas + * + * Sets the scaling factor of the @canvas, and invalidates the content. + * + * This function will cause the @canvas to be invalidated only + * if the scale factor of the canvas surface has changed. + */ +void +clutter_canvas_set_scale_factor (ClutterCanvas *canvas, + float scale) +{ + g_return_if_fail (CLUTTER_IS_CANVAS (canvas)); + g_return_if_fail (scale > 0.0f); + + if (canvas->priv->scale_factor != scale) + { + canvas->priv->scale_factor = scale; + + g_object_freeze_notify (G_OBJECT (canvas)); + clutter_content_invalidate (CLUTTER_CONTENT (canvas)); + g_object_thaw_notify (G_OBJECT (canvas)); + + g_object_notify_by_pspec (G_OBJECT (canvas), obj_props[PROP_SCALE_FACTOR]); + } +} + +/** + * clutter_canvas_get_scale_factor: + * @canvas: a #ClutterCanvas + * + * Gets the scale factor of the @canvas. + * + * Return value: the current @canvas scale factor or -1 if invalid + */ +float +clutter_canvas_get_scale_factor (ClutterCanvas *canvas) +{ + g_return_val_if_fail (CLUTTER_IS_CANVAS (canvas), -1.0f); + + return canvas->priv->scale_factor; +} diff --git a/clutter/clutter/clutter-canvas.h b/clutter/clutter/clutter-canvas.h index ed62dd4ee..ed13f49e3 100644 --- a/clutter/clutter/clutter-canvas.h +++ b/clutter/clutter/clutter-canvas.h @@ -85,21 +85,21 @@ struct _ClutterCanvasClass gpointer _padding[16]; }; -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT GType clutter_canvas_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT ClutterContent * clutter_canvas_new (void); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT gboolean clutter_canvas_set_size (ClutterCanvas *canvas, int width, int height); -CLUTTER_AVAILABLE_IN_1_18 +CLUTTER_EXPORT void clutter_canvas_set_scale_factor (ClutterCanvas *canvas, - int scale); -CLUTTER_AVAILABLE_IN_1_18 -int clutter_canvas_get_scale_factor (ClutterCanvas *canvas); + float scale); +CLUTTER_EXPORT +float clutter_canvas_get_scale_factor (ClutterCanvas *canvas); G_END_DECLS diff --git a/clutter/clutter/clutter-child-meta.c b/clutter/clutter/clutter-child-meta.c index 4267090f7..b0fe5611f 100644 --- a/clutter/clutter/clutter-child-meta.c +++ b/clutter/clutter/clutter-child-meta.c @@ -36,9 +36,8 @@ * * #ClutterChildMeta is available since Clutter 0.8 */ -#ifdef HAVE_CONFIG_H + #include "clutter-build-config.h" -#endif #include "clutter-child-meta.h" #include "clutter-container.h" diff --git a/clutter/clutter/clutter-child-meta.h b/clutter/clutter/clutter-child-meta.h index 02d9e9ad5..1c473bd32 100644 --- a/clutter/clutter/clutter-child-meta.h +++ b/clutter/clutter/clutter-child-meta.h @@ -109,12 +109,12 @@ struct _ClutterChildMetaClass GObjectClass parent_class; }; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT GType clutter_child_meta_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterContainer * clutter_child_meta_get_container (ClutterChildMeta *data); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterActor * clutter_child_meta_get_actor (ClutterChildMeta *data); G_END_DECLS diff --git a/clutter/clutter/clutter-click-action.c b/clutter/clutter/clutter-click-action.c index c10eec2e5..cb35d7253 100644 --- a/clutter/clutter/clutter-click-action.c +++ b/clutter/clutter/clutter-click-action.c @@ -92,9 +92,7 @@ * #ClutterClickAction is available since Clutter 1.4 */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include "clutter-click-action.h" @@ -107,8 +105,8 @@ struct _ClutterClickActionPrivate { ClutterActor *stage; - guint event_id; - guint capture_id; + gulong event_id; + gulong capture_id; guint long_press_id; gint long_press_threshold; @@ -204,11 +202,7 @@ click_action_emit_long_press (gpointer data) CLUTTER_LONG_PRESS_ACTIVATE, &result); - if (priv->capture_id != 0) - { - g_signal_handler_disconnect (priv->stage, priv->capture_id); - priv->capture_id = 0; - } + g_clear_signal_handler (&priv->capture_id, priv->stage); click_action_set_pressed (action, FALSE); click_action_set_held (action, FALSE); @@ -263,8 +257,7 @@ click_action_cancel_long_press (ClutterClickAction *action) actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action)); - g_source_remove (priv->long_press_id); - priv->long_press_id = 0; + g_clear_handle_id (&priv->long_press_id, g_source_remove); g_signal_emit (action, click_signals[LONG_PRESS], 0, actor, @@ -353,10 +346,20 @@ on_captured_event (ClutterActor *stage, ClutterModifierType modifier_state; gboolean has_button = TRUE; + if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (action))) + { + clutter_click_action_release (action); + return CLUTTER_EVENT_PROPAGATE; + } + actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action)); switch (clutter_event_type (event)) { + case CLUTTER_TOUCH_CANCEL: + clutter_click_action_release (action); + break; + case CLUTTER_TOUCH_END: has_button = FALSE; case CLUTTER_BUTTON_RELEASE: @@ -373,17 +376,9 @@ on_captured_event (ClutterActor *stage, click_action_cancel_long_press (action); /* disconnect the capture */ - if (priv->capture_id != 0) - { - g_signal_handler_disconnect (priv->stage, priv->capture_id); - priv->capture_id = 0; - } + g_clear_signal_handler (&priv->capture_id, priv->stage); - if (priv->long_press_id != 0) - { - g_source_remove (priv->long_press_id); - priv->long_press_id = 0; - } + g_clear_handle_id (&priv->long_press_id, g_source_remove); if (!clutter_actor_contains (actor, clutter_event_get_source (event))) return CLUTTER_EVENT_PROPAGATE; @@ -451,7 +446,7 @@ clutter_click_action_set_actor (ClutterActorMeta *meta, ClutterActor *old_actor = clutter_actor_meta_get_actor (meta); if (old_actor != NULL) - g_signal_handler_disconnect (old_actor, priv->event_id); + g_clear_signal_handler (&priv->event_id, old_actor); priv->event_id = 0; } @@ -459,17 +454,13 @@ clutter_click_action_set_actor (ClutterActorMeta *meta, if (priv->capture_id != 0) { if (priv->stage != NULL) - g_signal_handler_disconnect (priv->stage, priv->capture_id); + g_clear_signal_handler (&priv->capture_id, priv->stage); priv->capture_id = 0; priv->stage = NULL; } - if (priv->long_press_id != 0) - { - g_source_remove (priv->long_press_id); - priv->long_press_id = 0; - } + g_clear_handle_id (&priv->long_press_id, g_source_remove); click_action_set_pressed (action, FALSE); click_action_set_held (action, FALSE); @@ -543,24 +534,12 @@ clutter_click_action_dispose (GObject *gobject) { ClutterClickActionPrivate *priv = CLUTTER_CLICK_ACTION (gobject)->priv; - if (priv->event_id) - { - g_signal_handler_disconnect (clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (gobject)), - priv->event_id); - priv->event_id = 0; - } + g_clear_signal_handler (&priv->event_id, + clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (gobject))); - if (priv->capture_id) - { - g_signal_handler_disconnect (priv->stage, priv->capture_id); - priv->capture_id = 0; - } + g_clear_signal_handler (&priv->capture_id, priv->stage); - if (priv->long_press_id) - { - g_source_remove (priv->long_press_id); - priv->long_press_id = 0; - } + g_clear_handle_id (&priv->long_press_id, g_source_remove); G_OBJECT_CLASS (clutter_click_action_parent_class)->dispose (gobject); } @@ -664,8 +643,7 @@ clutter_click_action_class_init (ClutterClickActionClass *klass) G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ClutterClickActionClass, clicked), - NULL, NULL, - _clutter_marshal_VOID__OBJECT, + NULL, NULL, NULL, G_TYPE_NONE, 1, CLUTTER_TYPE_ACTOR); @@ -759,11 +737,7 @@ clutter_click_action_release (ClutterClickAction *action) return; /* disconnect the capture */ - if (priv->capture_id != 0) - { - g_signal_handler_disconnect (priv->stage, priv->capture_id); - priv->capture_id = 0; - } + g_clear_signal_handler (&priv->capture_id, priv->stage); click_action_cancel_long_press (action); click_action_set_held (action, FALSE); diff --git a/clutter/clutter/clutter-click-action.h b/clutter/clutter/clutter-click-action.h index 942efd0a0..c5ffdb2b7 100644 --- a/clutter/clutter/clutter-click-action.h +++ b/clutter/clutter/clutter-click-action.h @@ -97,22 +97,22 @@ struct _ClutterClickActionClass void (* _clutter_click_action7) (void); }; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT GType clutter_click_action_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT ClutterAction * clutter_click_action_new (void); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT guint clutter_click_action_get_button (ClutterClickAction *action); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT ClutterModifierType clutter_click_action_get_state (ClutterClickAction *action); -CLUTTER_AVAILABLE_IN_1_8 +CLUTTER_EXPORT void clutter_click_action_get_coords (ClutterClickAction *action, gfloat *press_x, gfloat *press_y); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_click_action_release (ClutterClickAction *action); G_END_DECLS diff --git a/clutter/clutter/clutter-clone.c b/clutter/clutter/clutter-clone.c index f0eea2459..8c805725a 100644 --- a/clutter/clutter/clutter-clone.c +++ b/clutter/clutter/clutter-clone.c @@ -37,9 +37,7 @@ * #ClutterClone is available since Clutter 1.0 */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #define CLUTTER_ENABLE_EXPERIMENTAL_API #include "clutter-actor-private.h" @@ -154,7 +152,8 @@ clutter_clone_apply_transform (ClutterActor *self, CoglMatrix *matrix) } static void -clutter_clone_paint (ClutterActor *actor) +clutter_clone_paint (ClutterActor *actor, + ClutterPaintContext *paint_context) { ClutterClone *self = CLUTTER_CLONE (actor); ClutterClonePrivate *priv = self->priv; @@ -191,7 +190,7 @@ clutter_clone_paint (ClutterActor *actor) if (clutter_actor_is_realized (priv->clone_source)) { _clutter_actor_push_clone_paint (); - clutter_actor_paint (priv->clone_source); + clutter_actor_paint (priv->clone_source, paint_context); _clutter_actor_pop_clone_paint (); } @@ -254,6 +253,13 @@ clutter_clone_allocate (ClutterActor *self, if (priv->clone_source == NULL) return; + /* ClutterActor delays allocating until the actor is shown; however + * we cannot paint it correctly in that case, so force an allocation. + */ + if (clutter_actor_get_parent (priv->clone_source) != NULL && + !clutter_actor_has_allocation (priv->clone_source)) + clutter_actor_allocate_preferred_size (priv->clone_source, flags); + #if 0 /* XXX - this is wrong: ClutterClone cannot clone unparented * actors, as it will break all invariants @@ -395,8 +401,7 @@ clutter_clone_set_source_internal (ClutterClone *self, if (priv->clone_source != NULL) { - g_signal_handler_disconnect (priv->clone_source, priv->source_destroy_id); - priv->source_destroy_id = 0; + g_clear_signal_handler (&priv->source_destroy_id, priv->clone_source); _clutter_actor_detach_clone (priv->clone_source, CLUTTER_ACTOR (self)); g_object_unref (priv->clone_source); priv->clone_source = NULL; diff --git a/clutter/clutter/clutter-clone.h b/clutter/clutter/clutter-clone.h index 6cc503cac..ce4e6f43f 100644 --- a/clutter/clutter/clutter-clone.h +++ b/clutter/clutter/clutter-clone.h @@ -78,15 +78,15 @@ struct _ClutterCloneClass void (*_clutter_actor_clone4) (void); }; -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT GType clutter_clone_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT ClutterActor * clutter_clone_new (ClutterActor *source); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_clone_set_source (ClutterClone *self, ClutterActor *source); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT ClutterActor * clutter_clone_get_source (ClutterClone *self); G_END_DECLS diff --git a/clutter/clutter/clutter-color.c b/clutter/clutter/clutter-color.c index 59db3946a..424fee22a 100644 --- a/clutter/clutter/clutter-color.c +++ b/clutter/clutter/clutter-color.c @@ -33,9 +33,7 @@ * The alpha channel is fully opaque at 255 and fully transparent at 0. */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include diff --git a/clutter/clutter/clutter-color.h b/clutter/clutter/clutter-color.h index 913ed69aa..cff493789 100644 --- a/clutter/clutter/clutter-color.h +++ b/clutter/clutter/clutter-color.h @@ -68,76 +68,76 @@ struct _ClutterColor */ #define CLUTTER_COLOR_INIT(r,g,b,a) { (r), (g), (b), (a) } -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT GType clutter_color_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterColor *clutter_color_new (guint8 red, guint8 green, guint8 blue, guint8 alpha); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT ClutterColor *clutter_color_alloc (void); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT ClutterColor *clutter_color_init (ClutterColor *color, guint8 red, guint8 green, guint8 blue, guint8 alpha); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterColor *clutter_color_copy (const ClutterColor *color); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_color_free (ClutterColor *color); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_color_add (const ClutterColor *a, const ClutterColor *b, ClutterColor *result); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_color_subtract (const ClutterColor *a, const ClutterColor *b, ClutterColor *result); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_color_lighten (const ClutterColor *color, ClutterColor *result); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_color_darken (const ClutterColor *color, ClutterColor *result); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_color_shade (const ClutterColor *color, gdouble factor, ClutterColor *result); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gchar * clutter_color_to_string (const ClutterColor *color); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT gboolean clutter_color_from_string (ClutterColor *color, const gchar *str); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_color_to_hls (const ClutterColor *color, gfloat *hue, gfloat *luminance, gfloat *saturation); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_color_from_hls (ClutterColor *color, gfloat hue, gfloat luminance, gfloat saturation); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT guint32 clutter_color_to_pixel (const ClutterColor *color); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_color_from_pixel (ClutterColor *color, guint32 pixel); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT guint clutter_color_hash (gconstpointer v); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gboolean clutter_color_equal (gconstpointer v1, gconstpointer v2); -CLUTTER_AVAILABLE_IN_1_6 +CLUTTER_EXPORT void clutter_color_interpolate (const ClutterColor *initial, const ClutterColor *final, gdouble progress, @@ -177,22 +177,22 @@ struct _ClutterParamSpecColor ClutterColor *default_value; }; -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_value_set_color (GValue *value, const ClutterColor *color); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT const ClutterColor * clutter_value_get_color (const GValue *value); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT GType clutter_param_color_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT GParamSpec * clutter_param_spec_color (const gchar *name, const gchar *nick, const gchar *blurb, const ClutterColor *default_value, GParamFlags flags); -CLUTTER_AVAILABLE_IN_1_6 +CLUTTER_EXPORT const ClutterColor *clutter_color_get_static (ClutterStaticColor color); G_END_DECLS diff --git a/clutter/clutter/clutter-colorize-effect.c b/clutter/clutter/clutter-colorize-effect.c index 960708eb9..db372a9cb 100644 --- a/clutter/clutter/clutter-colorize-effect.c +++ b/clutter/clutter/clutter-colorize-effect.c @@ -37,9 +37,7 @@ #define CLUTTER_IS_COLORIZE_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_COLORIZE_EFFECT)) #define CLUTTER_COLORIZE_EFFECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_COLORIZE_EFFECT, ClutterColorizeEffectClass)) -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #define CLUTTER_ENABLE_EXPERIMENTAL_API @@ -107,7 +105,8 @@ G_DEFINE_TYPE (ClutterColorizeEffect, CLUTTER_TYPE_OFFSCREEN_EFFECT); static gboolean -clutter_colorize_effect_pre_paint (ClutterEffect *effect) +clutter_colorize_effect_pre_paint (ClutterEffect *effect, + ClutterPaintContext *paint_context) { ClutterColorizeEffect *self = CLUTTER_COLORIZE_EFFECT (effect); ClutterEffectClass *parent_class; @@ -128,7 +127,7 @@ clutter_colorize_effect_pre_paint (ClutterEffect *effect) } parent_class = CLUTTER_EFFECT_CLASS (clutter_colorize_effect_parent_class); - if (parent_class->pre_paint (effect)) + if (parent_class->pre_paint (effect, paint_context)) { ClutterOffscreenEffect *offscreen_effect = CLUTTER_OFFSCREEN_EFFECT (effect); @@ -147,9 +146,12 @@ clutter_colorize_effect_pre_paint (ClutterEffect *effect) } static void -clutter_colorize_effect_paint_target (ClutterOffscreenEffect *effect) +clutter_colorize_effect_paint_target (ClutterOffscreenEffect *effect, + ClutterPaintContext *paint_context) { ClutterColorizeEffect *self = CLUTTER_COLORIZE_EFFECT (effect); + CoglFramebuffer *framebuffer = + clutter_paint_context_get_framebuffer (paint_context); ClutterActor *actor; guint8 paint_opacity; @@ -161,11 +163,11 @@ clutter_colorize_effect_paint_target (ClutterOffscreenEffect *effect) paint_opacity, paint_opacity, paint_opacity); - cogl_push_source (self->pipeline); - cogl_rectangle (0, 0, self->tex_width, self->tex_height); - - cogl_pop_source (); + cogl_framebuffer_draw_rectangle (framebuffer, + self->pipeline, + 0, 0, + self->tex_width, self->tex_height); } static void @@ -294,9 +296,7 @@ clutter_colorize_effect_init (ClutterColorizeEffect *self) cogl_pipeline_add_snippet (klass->base_pipeline, snippet); cogl_object_unref (snippet); - cogl_pipeline_set_layer_null_texture (klass->base_pipeline, - 0, /* layer number */ - COGL_TEXTURE_TYPE_2D); + cogl_pipeline_set_layer_null_texture (klass->base_pipeline, 0); } self->pipeline = cogl_pipeline_copy (klass->base_pipeline); diff --git a/clutter/clutter/clutter-colorize-effect.h b/clutter/clutter/clutter-colorize-effect.h index f8f8436c0..92e878735 100644 --- a/clutter/clutter/clutter-colorize-effect.h +++ b/clutter/clutter/clutter-colorize-effect.h @@ -49,16 +49,16 @@ G_BEGIN_DECLS typedef struct _ClutterColorizeEffect ClutterColorizeEffect; typedef struct _ClutterColorizeEffectClass ClutterColorizeEffectClass; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT GType clutter_colorize_effect_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT ClutterEffect *clutter_colorize_effect_new (const ClutterColor *tint); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_colorize_effect_set_tint (ClutterColorizeEffect *effect, const ClutterColor *tint); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_colorize_effect_get_tint (ClutterColorizeEffect *effect, ClutterColor *tint); diff --git a/clutter/clutter/clutter-constraint-private.h b/clutter/clutter/clutter-constraint-private.h index 2bed47be2..5fbddef00 100644 --- a/clutter/clutter/clutter-constraint-private.h +++ b/clutter/clutter/clutter-constraint-private.h @@ -30,13 +30,6 @@ gboolean clutter_constraint_update_allocation (ClutterConstraint *constraint, ClutterActor *actor, ClutterActorBox *allocation); -void clutter_constraint_update_preferred_size (ClutterConstraint *constraint, - ClutterActor *actor, - ClutterOrientation direction, - float for_size, - float *minimum_size, - float *natural_size); - G_END_DECLS #endif /* __CLUTTER_CONSTRAINT_PRIVATE_H__ */ diff --git a/clutter/clutter/clutter-constraint.c b/clutter/clutter/clutter-constraint.c index c3d3f7da4..b575fc63d 100644 --- a/clutter/clutter/clutter-constraint.c +++ b/clutter/clutter/clutter-constraint.c @@ -48,7 +48,7 @@ * Constraints provide a way to build user interfaces by using * relations between #ClutterActors, without explicit fixed * positioning and sizing, similarly to how fluid layout managers like - * #ClutterBoxLayout and #ClutterTableLayout lay out their children. + * #ClutterBoxLayout lay out their children. * * Constraints are attached to a #ClutterActor, and are available * for inspection using clutter_actor_get_constraints(). @@ -128,9 +128,7 @@ * can be recovered at any point using clutter_actor_meta_get_actor(). */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include @@ -224,6 +222,17 @@ clutter_constraint_update_allocation (ClutterConstraint *constraint, return !clutter_actor_box_equal (allocation, &old_alloc); } +/** + * clutter_constraint_update_preferred_size: + * @constraint: a #ClutterConstraint + * @actor: a #ClutterActor + * @direction: a #ClutterOrientation + * @for_size: the size in the opposite direction + * @minimum_size: (inout): the minimum size to modify + * @natural_size: (inout): the natural size to modify + * + * Asks the @constraint to update the size request of a #ClutterActor. + */ void clutter_constraint_update_preferred_size (ClutterConstraint *constraint, ClutterActor *actor, diff --git a/clutter/clutter/clutter-constraint.h b/clutter/clutter/clutter-constraint.h index aba07f6f4..420e7de75 100644 --- a/clutter/clutter/clutter-constraint.h +++ b/clutter/clutter/clutter-constraint.h @@ -96,32 +96,40 @@ struct _ClutterConstraintClass void (* _clutter_constraint7) (void); }; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT GType clutter_constraint_get_type (void) G_GNUC_CONST; +CLUTTER_EXPORT +void clutter_constraint_update_preferred_size (ClutterConstraint *constraint, + ClutterActor *actor, + ClutterOrientation direction, + float for_size, + float *minimum_size, + float *natural_size); + /* ClutterActor API */ -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_actor_add_constraint (ClutterActor *self, ClutterConstraint *constraint); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_actor_add_constraint_with_name (ClutterActor *self, const gchar *name, ClutterConstraint *constraint); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_actor_remove_constraint (ClutterActor *self, ClutterConstraint *constraint); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_actor_remove_constraint_by_name (ClutterActor *self, const gchar *name); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT GList * clutter_actor_get_constraints (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT ClutterConstraint *clutter_actor_get_constraint (ClutterActor *self, const gchar *name); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_actor_clear_constraints (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT gboolean clutter_actor_has_constraints (ClutterActor *self); G_END_DECLS diff --git a/clutter/clutter/deprecated/clutter-util.h b/clutter/clutter/clutter-container-private.h similarity index 61% rename from clutter/clutter/deprecated/clutter-util.h rename to clutter/clutter/clutter-container-private.h index ff9b325df..d619a6531 100644 --- a/clutter/clutter/deprecated/clutter-util.h +++ b/clutter/clutter/clutter-container-private.h @@ -3,9 +3,7 @@ * * An OpenGL based 'interactive canvas' library. * - * Authored By Matthew Allum - * - * Copyright (C) 2006 OpenedHand + * Copyright 2020 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -21,20 +19,18 @@ * License along with this library. If not, see . */ -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __CLUTTER_UTIL_H__ -#define __CLUTTER_UTIL_H__ +#ifndef __CLUTTER_CONTAINER_PRIVATE_H__ +#define __CLUTTER_CONTAINER_PRIVATE_H__ -#include +#include G_BEGIN_DECLS -CLUTTER_DEPRECATED_IN_1_2 -gint clutter_util_next_p2 (gint a); +void _clutter_container_emit_actor_added (ClutterContainer *container, + ClutterActor *actor); +void _clutter_container_emit_actor_removed (ClutterContainer *container, + ClutterActor *actor); G_END_DECLS -#endif /* __CLUTTER_UTIL_H__ */ +#endif /* __CLUTTER_CONTAINER_PRIVATE_H__ */ diff --git a/clutter/clutter/clutter-container.c b/clutter/clutter/clutter-container.c index ba1700dbb..23169332f 100644 --- a/clutter/clutter/clutter-container.c +++ b/clutter/clutter/clutter-container.c @@ -26,9 +26,7 @@ * Author: Emmanuele Bassi */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include #include @@ -39,6 +37,7 @@ #include "clutter-actor-private.h" #include "clutter-child-meta.h" +#include "clutter-container-private.h" #include "clutter-debug.h" #include "clutter-main.h" #include "clutter-marshal.h" @@ -120,37 +119,6 @@ container_real_remove (ClutterContainer *container, clutter_actor_remove_child (CLUTTER_ACTOR (container), actor); } -typedef struct { - ClutterCallback callback; - gpointer data; -} ForeachClosure; - -static gboolean -foreach_cb (ClutterActor *actor, - gpointer data) -{ - ForeachClosure *clos = data; - - clos->callback (actor, clos->data); - - return TRUE; -} - -static void -container_real_foreach (ClutterContainer *container, - ClutterCallback callback, - gpointer user_data) -{ - ForeachClosure clos; - - clos.callback = callback; - clos.data = user_data; - - _clutter_actor_foreach_child (CLUTTER_ACTOR (container), - foreach_cb, - &clos); -} - static void container_real_raise (ClutterContainer *container, ClutterActor *child, @@ -199,8 +167,7 @@ clutter_container_default_init (ClutterContainerInterface *iface) iface_type, G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (ClutterContainerIface, actor_added), - NULL, NULL, - _clutter_marshal_VOID__OBJECT, + NULL, NULL, NULL, G_TYPE_NONE, 1, CLUTTER_TYPE_ACTOR); /** @@ -218,8 +185,7 @@ clutter_container_default_init (ClutterContainerInterface *iface) iface_type, G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (ClutterContainerIface, actor_removed), - NULL, NULL, - _clutter_marshal_VOID__OBJECT, + NULL, NULL, NULL, G_TYPE_NONE, 1, CLUTTER_TYPE_ACTOR); @@ -247,7 +213,6 @@ clutter_container_default_init (ClutterContainerInterface *iface) iface->add = container_real_add; iface->remove = container_real_remove; - iface->foreach = container_real_foreach; iface->raise = container_real_raise; iface->lower = container_real_lower; iface->sort_depth_order = container_real_sort_depth_order; @@ -420,33 +385,6 @@ clutter_container_add_actor (ClutterContainer *container, container_add_actor (container, actor); } -/** - * clutter_container_add_valist: (skip) - * @container: a #ClutterContainer - * @first_actor: the first #ClutterActor to add - * @var_args: list of actors to add, followed by %NULL - * - * Alternative va_list version of clutter_container_add(). - * - * This function will call #ClutterContainerIface.add(), which is a - * deprecated virtual function. The default implementation will - * call clutter_actor_add_child(). - * - * Since: 0.4 - * - * Deprecated: 1.10: Use clutter_actor_add_child() instead. - */ -void -clutter_container_add_valist (ClutterContainer *container, - ClutterActor *first_actor, - va_list var_args) -{ - g_return_if_fail (CLUTTER_IS_CONTAINER (container)); - g_return_if_fail (CLUTTER_IS_ACTOR (first_actor)); - - container_add_valist (container, first_actor, var_args); -} - /** * clutter_container_remove: (skip) * @container: a #ClutterContainer @@ -510,42 +448,6 @@ clutter_container_remove_actor (ClutterContainer *container, container_remove_actor (container, actor); } -/** - * clutter_container_remove_valist: (skip) - * @container: a #ClutterContainer - * @first_actor: the first #ClutterActor to add - * @var_args: list of actors to remove, followed by %NULL - * - * Alternative va_list version of clutter_container_remove(). - * - * This function will call #ClutterContainerIface.remove(), which is a - * deprecated virtual function. The default implementation will call - * clutter_actor_remove_child(). - * - * Since: 0.4 - * - * Deprecated: 1.10: Use clutter_actor_remove_child() instead. - */ -void -clutter_container_remove_valist (ClutterContainer *container, - ClutterActor *first_actor, - va_list var_args) -{ - g_return_if_fail (CLUTTER_IS_CONTAINER (container)); - g_return_if_fail (CLUTTER_IS_ACTOR (first_actor)); - - container_remove_valist (container, first_actor, var_args); -} - -static void -get_children_cb (ClutterActor *child, - gpointer data) -{ - GList **children = data; - - *children = g_list_prepend (*children, child); -} - /** * clutter_container_get_children: * @container: a #ClutterContainer @@ -563,108 +465,9 @@ get_children_cb (ClutterActor *child, GList * clutter_container_get_children (ClutterContainer *container) { - GList *retval; - g_return_val_if_fail (CLUTTER_IS_CONTAINER (container), NULL); - retval = NULL; - clutter_container_foreach (container, get_children_cb, &retval); - - return g_list_reverse (retval); -} - -/** - * clutter_container_foreach: - * @container: a #ClutterContainer - * @callback: (scope call): a function to be called for each child - * @user_data: data to be passed to the function, or %NULL - * - * Calls @callback for each child of @container that was added - * by the application (with clutter_container_add_actor()). Does - * not iterate over "internal" children that are part of the - * container's own implementation, if any. - * - * This function calls the #ClutterContainerIface.foreach() - * virtual function, which has been deprecated. - * - * Since: 0.4 - * - * Deprecated: 1.10: Use clutter_actor_get_first_child() or - * clutter_actor_get_last_child() to retrieve the beginning of - * the list of children, and clutter_actor_get_next_sibling() - * and clutter_actor_get_previous_sibling() to iterate over it; - * alternatively, use the #ClutterActorIter API. - */ -void -clutter_container_foreach (ClutterContainer *container, - ClutterCallback callback, - gpointer user_data) -{ - g_return_if_fail (CLUTTER_IS_CONTAINER (container)); - g_return_if_fail (callback != NULL); - -#ifdef CLUTTER_ENABLE_DEBUG - if (G_UNLIKELY (_clutter_diagnostic_enabled ())) - { - ClutterContainerIface *iface = CLUTTER_CONTAINER_GET_IFACE (container); - - if (iface->foreach != container_real_foreach) - _clutter_diagnostic_message ("The ClutterContainer::foreach() " - "virtual function has been deprecated " - "and it should not be overridden by " - "newly written code"); - } -#endif /* CLUTTER_ENABLE_DEBUG */ - - CLUTTER_CONTAINER_GET_IFACE (container)->foreach (container, - callback, - user_data); -} - -/** - * clutter_container_foreach_with_internals: - * @container: a #ClutterContainer - * @callback: (scope call): a function to be called for each child - * @user_data: data to be passed to the function, or %NULL - * - * Calls @callback for each child of @container, including "internal" - * children built in to the container itself that were never added - * by the application. - * - * This function calls the #ClutterContainerIface.foreach_with_internals() - * virtual function, which has been deprecated. - * - * Since: 1.0 - * - * Deprecated: 1.10: See clutter_container_foreach(). - */ -void -clutter_container_foreach_with_internals (ClutterContainer *container, - ClutterCallback callback, - gpointer user_data) -{ - ClutterContainerIface *iface; - - g_return_if_fail (CLUTTER_IS_CONTAINER (container)); - g_return_if_fail (callback != NULL); - - iface = CLUTTER_CONTAINER_GET_IFACE (container); - -#ifdef CLUTTER_ENABLE_DEBUG - if (G_UNLIKELY (_clutter_diagnostic_enabled ())) - { - if (iface->foreach_with_internals != NULL) - _clutter_diagnostic_message ("The ClutterContainer::foreach_with_internals() " - "virtual function has been deprecated " - "and it should not be overridden by " - "newly written code"); - } -#endif /* CLUTTER_ENABLE_DEBUG */ - - if (iface->foreach_with_internals != NULL) - iface->foreach_with_internals (container, callback, user_data); - else - iface->foreach (container, callback, user_data); + return clutter_actor_get_children (CLUTTER_ACTOR (container)); } /** @@ -1222,7 +1025,7 @@ clutter_container_child_set (ClutterContainer *container, GObjectClass *klass; const gchar *name; va_list var_args; - + g_return_if_fail (CLUTTER_IS_CONTAINER (container)); g_return_if_fail (CLUTTER_IS_ACTOR (actor)); @@ -1236,7 +1039,7 @@ clutter_container_child_set (ClutterContainer *container, GValue value = G_VALUE_INIT; gchar *error = NULL; GParamSpec *pspec; - + pspec = clutter_container_class_find_child_property (klass, name); if (!pspec) { @@ -1265,7 +1068,7 @@ clutter_container_child_set (ClutterContainer *container, * on it might crash */ g_warning ("%s: %s", G_STRLOC, error); - free (error); + g_free (error); break; } @@ -1357,7 +1160,7 @@ clutter_container_child_get_property (ClutterContainer *container, * * In general, a copy is made of the property contents and the caller is * responsible for freeing the memory in the appropriate manner for the type, for - * instance by calling free() or g_object_unref(). + * instance by calling g_free() or g_object_unref(). * * Since: 0.8 */ @@ -1370,7 +1173,7 @@ clutter_container_child_get (ClutterContainer *container, GObjectClass *klass; const gchar *name; va_list var_args; - + g_return_if_fail (CLUTTER_IS_CONTAINER (container)); g_return_if_fail (CLUTTER_IS_ACTOR (actor)); @@ -1384,7 +1187,7 @@ clutter_container_child_get (ClutterContainer *container, GValue value = G_VALUE_INIT; gchar *error = NULL; GParamSpec *pspec; - + pspec = clutter_container_class_find_child_property (klass, name); if (!pspec) { @@ -1408,7 +1211,7 @@ clutter_container_child_get (ClutterContainer *container, if (error) { g_warning ("%s: %s", G_STRLOC, error); - free (error); + g_free (error); g_value_unset (&value); break; } @@ -1448,3 +1251,23 @@ clutter_container_child_notify (ClutterContainer *container, child, pspec); } + +void +_clutter_container_emit_actor_added (ClutterContainer *container, + ClutterActor *actor) +{ + g_return_if_fail (CLUTTER_IS_CONTAINER (container)); + g_return_if_fail (CLUTTER_IS_ACTOR (actor)); + + g_signal_emit (container, container_signals[ACTOR_ADDED], 0, actor); +} + +void +_clutter_container_emit_actor_removed (ClutterContainer *container, + ClutterActor *actor) +{ + g_return_if_fail (CLUTTER_IS_CONTAINER (container)); + g_return_if_fail (CLUTTER_IS_ACTOR (actor)); + + g_signal_emit (container, container_signals[ACTOR_REMOVED], 0, actor); +} diff --git a/clutter/clutter/clutter-container.h b/clutter/clutter/clutter-container.h index 0fc3cefca..26b991c9c 100644 --- a/clutter/clutter/clutter-container.h +++ b/clutter/clutter/clutter-container.h @@ -59,14 +59,6 @@ typedef struct _ClutterContainerIface ClutterContainerIface; * function is deprecated, and it should not be overridden. * @remove: virtual function for removing an actor from the container. This * virtual function is deprecated, and it should not be overridden. - * @foreach: virtual function for iterating over the container's children. - * This virtual function is deprecated, and it should not be overridden. - * @foreach_with_internals: virtual functions for iterating over the - * container's children, both added using the #ClutterContainer API - * and internal children. The implementation of this virtual function - * is required only if the #ClutterContainer implementation has - * internal children. This virtual function is deprecated, and it should - * not be overridden. * @raise: virtual function for raising a child. This virtual function is * deprecated and it should not be overridden. * @lower: virtual function for lowering a child. This virtual function is @@ -88,7 +80,7 @@ typedef struct _ClutterContainerIface ClutterContainerIface; * @actor_removed: class handler for #ClutterContainer::actor-removed * @child_notify: class handler for #ClutterContainer::child-notify * - * Base interface for container actors. The @add, @remove and @foreach + * Base interface for container actors. The @add and @remove * virtual functions must be provided by any implementation; the other * virtual functions are optional. * @@ -104,13 +96,6 @@ struct _ClutterContainerIface ClutterActor *actor); void (* remove) (ClutterContainer *container, ClutterActor *actor); - void (* foreach) (ClutterContainer *container, - ClutterCallback callback, - gpointer user_data); - - void (* foreach_with_internals) (ClutterContainer *container, - ClutterCallback callback, - gpointer user_data); /* child stacking */ void (* raise) (ClutterContainer *container, @@ -141,52 +126,52 @@ struct _ClutterContainerIface GParamSpec *pspec); }; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT GType clutter_container_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterActor * clutter_container_find_child_by_name (ClutterContainer *container, const gchar *child_name); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT GParamSpec * clutter_container_class_find_child_property (GObjectClass *klass, const gchar *property_name); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT GParamSpec ** clutter_container_class_list_child_properties (GObjectClass *klass, guint *n_properties); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_container_create_child_meta (ClutterContainer *container, ClutterActor *actor); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_container_destroy_child_meta (ClutterContainer *container, ClutterActor *actor); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterChildMeta * clutter_container_get_child_meta (ClutterContainer *container, ClutterActor *actor); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_container_child_set_property (ClutterContainer *container, ClutterActor *child, const gchar * property, const GValue *value); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_container_child_get_property (ClutterContainer *container, ClutterActor *child, const gchar *property, GValue *value); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_container_child_set (ClutterContainer *container, ClutterActor *actor, const gchar *first_prop, ...) G_GNUC_NULL_TERMINATED; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_container_child_get (ClutterContainer *container, ClutterActor *actor, const gchar *first_prop, ...) G_GNUC_NULL_TERMINATED; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_container_child_notify (ClutterContainer *container, ClutterActor *child, GParamSpec *pspec); diff --git a/clutter/clutter/clutter-content-private.h b/clutter/clutter/clutter-content-private.h index 009ae41c8..1654b3bbf 100644 --- a/clutter/clutter/clutter-content-private.h +++ b/clutter/clutter/clutter-content-private.h @@ -34,9 +34,10 @@ void _clutter_content_attached (ClutterContent *conte void _clutter_content_detached (ClutterContent *content, ClutterActor *actor); -void _clutter_content_paint_content (ClutterContent *content, - ClutterActor *actor, - ClutterPaintNode *node); +void _clutter_content_paint_content (ClutterContent *content, + ClutterActor *actor, + ClutterPaintNode *node, + ClutterPaintContext *paint_context); G_END_DECLS diff --git a/clutter/clutter/clutter-content.c b/clutter/clutter/clutter-content.c index 76ca65d77..31abd1135 100644 --- a/clutter/clutter/clutter-content.c +++ b/clutter/clutter/clutter-content.c @@ -36,18 +36,15 @@ * #ClutterContent is available since Clutter 1.10. */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif +#include "clutter-actor-private.h" #include "clutter-content-private.h" #include "clutter-debug.h" #include "clutter-marshal.h" #include "clutter-private.h" -typedef struct _ClutterContentIface ClutterContentInterface; - enum { ATTACHED, @@ -94,9 +91,15 @@ clutter_content_real_invalidate (ClutterContent *content) } static void -clutter_content_real_paint_content (ClutterContent *content, - ClutterActor *actor, - ClutterPaintNode *context) +clutter_content_real_invalidate_size (ClutterContent *content) +{ +} + +static void +clutter_content_real_paint_content (ClutterContent *content, + ClutterActor *actor, + ClutterPaintNode *context, + ClutterPaintContext *paint_context) { } @@ -110,6 +113,7 @@ clutter_content_default_init (ClutterContentInterface *iface) iface->attached = clutter_content_real_attached; iface->detached = clutter_content_real_detached; iface->invalidate = clutter_content_real_invalidate; + iface->invalidate_size = clutter_content_real_invalidate_size; /** * ClutterContent::attached: @@ -125,9 +129,8 @@ clutter_content_default_init (ClutterContentInterface *iface) g_signal_new (I_("attached"), G_TYPE_FROM_INTERFACE (iface), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (ClutterContentIface, attached), - NULL, NULL, - _clutter_marshal_VOID__OBJECT, + G_STRUCT_OFFSET (ClutterContentInterface, attached), + NULL, NULL, NULL, G_TYPE_NONE, 1, CLUTTER_TYPE_ACTOR); @@ -145,9 +148,8 @@ clutter_content_default_init (ClutterContentInterface *iface) g_signal_new (I_("detached"), G_TYPE_FROM_INTERFACE (iface), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (ClutterContentIface, detached), - NULL, NULL, - _clutter_marshal_VOID__OBJECT, + G_STRUCT_OFFSET (ClutterContentInterface, detached), + NULL, NULL, NULL, G_TYPE_NONE, 1, CLUTTER_TYPE_ACTOR); } @@ -190,6 +192,45 @@ clutter_content_invalidate (ClutterContent *content) } } +/** + * clutter_content_invalidate_size: + * @content: a #ClutterContent + * + * Signals that @content's size changed. Attached actors with request mode + * set to %CLUTTER_REQUEST_CONTENT_SIZE will have a relayout queued. + * + * Attached actors with other request modes are not redrawn. To redraw them + * too, use clutter_content_invalidate(). + */ +void +clutter_content_invalidate_size (ClutterContent *content) +{ + ClutterActor *actor; + GHashTable *actors; + GHashTableIter iter; + + g_return_if_fail (CLUTTER_IS_CONTENT (content)); + + CLUTTER_CONTENT_GET_IFACE (content)->invalidate_size (content); + + actors = g_object_get_qdata (G_OBJECT (content), quark_content_actors); + if (actors == NULL) + return; + + g_hash_table_iter_init (&iter, actors); + while (g_hash_table_iter_next (&iter, (gpointer *) &actor, NULL)) + { + ClutterRequestMode request_mode; + + g_assert (actor != NULL); + + request_mode = clutter_actor_get_request_mode (actor); + + if (request_mode == CLUTTER_REQUEST_CONTENT_SIZE) + _clutter_actor_queue_only_relayout (actor); + } +} + /*< private > * _clutter_content_attached: * @content: a #ClutterContent @@ -201,7 +242,7 @@ clutter_content_invalidate (ClutterContent *content) * is associated to a #ClutterContent, to set up a backpointer from * the @content to the @actor. * - * This function will invoke the #ClutterContentIface.attached() virtual + * This function will invoke the #ClutterContentInterface.attached() virtual * function. */ void @@ -235,7 +276,7 @@ _clutter_content_attached (ClutterContent *content, * This function should be used internally every time a #ClutterActor * removes the association with a #ClutterContent. * - * This function will invoke the #ClutterContentIface.detached() virtual + * This function will invoke the #ClutterContentInterface.detached() virtual * function. */ void @@ -260,19 +301,22 @@ _clutter_content_detached (ClutterContent *content, * _clutter_content_paint_content: * @content: a #ClutterContent * @actor: a #ClutterActor - * @context: a #ClutterPaintNode + * @node: a #ClutterPaintNode + * @paint_context: a #ClutterPaintContext * * Creates the render tree for the @content and @actor. * - * This function will invoke the #ClutterContentIface.paint_content() + * This function will invoke the #ClutterContentInterface.paint_content() * virtual function. */ void -_clutter_content_paint_content (ClutterContent *content, - ClutterActor *actor, - ClutterPaintNode *node) +_clutter_content_paint_content (ClutterContent *content, + ClutterActor *actor, + ClutterPaintNode *node, + ClutterPaintContext *paint_context) { - CLUTTER_CONTENT_GET_IFACE (content)->paint_content (content, actor, node); + CLUTTER_CONTENT_GET_IFACE (content)->paint_content (content, actor, node, + paint_context); } /** diff --git a/clutter/clutter/clutter-content.h b/clutter/clutter/clutter-content.h index 84bfa0ec3..77b44dc3f 100644 --- a/clutter/clutter/clutter-content.h +++ b/clutter/clutter/clutter-content.h @@ -33,24 +33,13 @@ G_BEGIN_DECLS -#define CLUTTER_TYPE_CONTENT (clutter_content_get_type ()) -#define CLUTTER_CONTENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_CONTENT, ClutterContent)) -#define CLUTTER_IS_CONTENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_CONTENT)) -#define CLUTTER_CONTENT_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), CLUTTER_TYPE_CONTENT, ClutterContentIface)) +#define CLUTTER_TYPE_CONTENT (clutter_content_get_type ()) -typedef struct _ClutterContentIface ClutterContentIface; +CLUTTER_EXPORT +G_DECLARE_INTERFACE (ClutterContent, clutter_content, CLUTTER, CONTENT, GObject) /** - * ClutterContent: - * - * The #ClutterContent structure is an opaque type - * whose members cannot be acccessed directly. - * - * Since: 1.10 - */ - -/** - * ClutterContentIface: + * ClutterContentInterface: * @get_preferred_size: virtual function; should be overridden by subclasses * of #ClutterContent that have a natural size * @paint_content: virtual function; called each time the content needs to @@ -62,12 +51,12 @@ typedef struct _ClutterContentIface ClutterContentIface; * @invalidate: virtual function; called each time a #ClutterContent state * is changed. * - * The #ClutterContentIface structure contains only + * The #ClutterContentInterface structure contains only * private data. * * Since: 1.10 */ -struct _ClutterContentIface +struct _ClutterContentInterface { /*< private >*/ GTypeInterface g_iface; @@ -76,9 +65,10 @@ struct _ClutterContentIface gboolean (* get_preferred_size) (ClutterContent *content, gfloat *width, gfloat *height); - void (* paint_content) (ClutterContent *content, - ClutterActor *actor, - ClutterPaintNode *node); + void (* paint_content) (ClutterContent *content, + ClutterActor *actor, + ClutterPaintNode *node, + ClutterPaintContext *paint_context); void (* attached) (ClutterContent *content, ClutterActor *actor); @@ -86,18 +76,20 @@ struct _ClutterContentIface ClutterActor *actor); void (* invalidate) (ClutterContent *content); -}; -CLUTTER_AVAILABLE_IN_1_10 -GType clutter_content_get_type (void) G_GNUC_CONST; + void (* invalidate_size) (ClutterContent *content); +}; -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT gboolean clutter_content_get_preferred_size (ClutterContent *content, gfloat *width, gfloat *height); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_content_invalidate (ClutterContent *content); +CLUTTER_EXPORT +void clutter_content_invalidate_size (ClutterContent *content); + G_END_DECLS #endif /* __CLUTTER_CONTENT_H__ */ diff --git a/clutter/clutter/clutter-debug.h b/clutter/clutter/clutter-debug.h index be14b08f0..76b8505cb 100644 --- a/clutter/clutter/clutter-debug.h +++ b/clutter/clutter/clutter-debug.h @@ -6,42 +6,6 @@ G_BEGIN_DECLS -typedef enum { - CLUTTER_DEBUG_MISC = 1 << 0, - CLUTTER_DEBUG_ACTOR = 1 << 1, - CLUTTER_DEBUG_TEXTURE = 1 << 2, - CLUTTER_DEBUG_EVENT = 1 << 3, - CLUTTER_DEBUG_PAINT = 1 << 4, - CLUTTER_DEBUG_PANGO = 1 << 5, - CLUTTER_DEBUG_BACKEND = 1 << 6, - CLUTTER_DEBUG_SCHEDULER = 1 << 7, - CLUTTER_DEBUG_SCRIPT = 1 << 8, - CLUTTER_DEBUG_SHADER = 1 << 9, - CLUTTER_DEBUG_MULTISTAGE = 1 << 10, - CLUTTER_DEBUG_ANIMATION = 1 << 11, - CLUTTER_DEBUG_LAYOUT = 1 << 12, - CLUTTER_DEBUG_PICK = 1 << 13, - CLUTTER_DEBUG_EVENTLOOP = 1 << 14, - CLUTTER_DEBUG_CLIPPING = 1 << 15, - CLUTTER_DEBUG_OOB_TRANSFORMS = 1 << 16 -} ClutterDebugFlag; - -typedef enum { - CLUTTER_DEBUG_NOP_PICKING = 1 << 0, - CLUTTER_DEBUG_DUMP_PICK_BUFFERS = 1 << 1 -} ClutterPickDebugFlag; - -typedef enum { - CLUTTER_DEBUG_DISABLE_SWAP_EVENTS = 1 << 0, - CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS = 1 << 1, - CLUTTER_DEBUG_REDRAWS = 1 << 2, - CLUTTER_DEBUG_PAINT_VOLUMES = 1 << 3, - CLUTTER_DEBUG_DISABLE_CULLING = 1 << 4, - CLUTTER_DEBUG_DISABLE_OFFSCREEN_REDIRECT = 1 << 5, - CLUTTER_DEBUG_CONTINUOUS_REDRAW = 1 << 6, - CLUTTER_DEBUG_PAINT_DEFORM_TILES = 1 << 7 -} ClutterDrawDebugFlag; - #ifdef CLUTTER_ENABLE_DEBUG #define CLUTTER_HAS_DEBUG(type) ((clutter_debug_flags & CLUTTER_DEBUG_##type) != FALSE) @@ -63,7 +27,7 @@ typedef enum { if (G_UNLIKELY (CLUTTER_HAS_DEBUG (type))) { \ gchar *_fmt = g_strdup_printf (__VA_ARGS__); \ _clutter_debug_message ("[" #type "]:" G_STRLOC ": %s", _fmt); \ - free (_fmt); \ + g_free (_fmt); \ } } G_STMT_END #endif @@ -79,9 +43,9 @@ extern guint clutter_pick_debug_flags; extern guint clutter_paint_debug_flags; void _clutter_debug_messagev (const char *format, - va_list var_args); + va_list var_args) G_GNUC_PRINTF (1, 0); void _clutter_debug_message (const char *format, - ...); + ...) G_GNUC_PRINTF (1, 2); G_END_DECLS diff --git a/clutter/clutter/clutter-deform-effect.c b/clutter/clutter/clutter-deform-effect.c index d14c8b106..59ef1ff75 100644 --- a/clutter/clutter/clutter-deform-effect.c +++ b/clutter/clutter/clutter-deform-effect.c @@ -51,9 +51,7 @@ * deformation algorithm. */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #define CLUTTER_ENABLE_EXPERIMENTAL_API #include "clutter-deform-effect.h" @@ -149,7 +147,7 @@ clutter_deform_effect_set_actor (ClutterActorMeta *meta, ClutterActor *old_actor = clutter_actor_meta_get_actor (meta); if (old_actor != NULL) - g_signal_handler_disconnect (old_actor, priv->allocation_id); + g_clear_signal_handler (&priv->allocation_id, old_actor); priv->allocation_id = 0; } @@ -168,18 +166,20 @@ clutter_deform_effect_set_actor (ClutterActorMeta *meta, } static void -clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect) +clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect, + ClutterPaintContext *paint_context) { ClutterDeformEffect *self= CLUTTER_DEFORM_EFFECT (effect); ClutterDeformEffectPrivate *priv = self->priv; CoglHandle material; CoglPipeline *pipeline; CoglDepthState depth_state; - CoglFramebuffer *fb = cogl_get_draw_framebuffer (); + CoglFramebuffer *fb = + clutter_paint_context_get_framebuffer (paint_context); if (priv->is_dirty) { - ClutterRect rect; + graphene_rect_t rect; gboolean mapped_buffer; CoglVertexP3T2C4 *verts; ClutterActor *actor; @@ -195,8 +195,8 @@ clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect) */ if (clutter_offscreen_effect_get_target_rect (effect, &rect)) { - width = clutter_rect_get_width (&rect); - height = clutter_rect_get_height (&rect); + width = graphene_rect_get_width (&rect); + height = graphene_rect_get_height (&rect); } else clutter_actor_get_size (actor, &width, &height); @@ -215,7 +215,7 @@ clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect) if (verts == NULL) { mapped_buffer = FALSE; - verts = malloc (sizeof (*verts) * priv->n_vertices); + verts = g_malloc (sizeof (*verts) * priv->n_vertices); } else mapped_buffer = TRUE; @@ -272,7 +272,7 @@ clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect) 0, /* offset */ verts, sizeof (*verts) * priv->n_vertices); - free (verts); + g_free (verts); } priv->is_dirty = FALSE; @@ -284,6 +284,7 @@ clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect) /* enable depth testing */ cogl_depth_state_init (&depth_state); cogl_depth_state_set_test_enabled (&depth_state, TRUE); + cogl_depth_state_set_test_function (&depth_state, COGL_DEPTH_TEST_FUNCTION_LEQUAL); cogl_pipeline_set_depth_state (pipeline, &depth_state, NULL); /* enable backface culling if we have a back material */ @@ -425,7 +426,7 @@ clutter_deform_effect_init_arrays (ClutterDeformEffect *self) static_indices, n_indices); - free (static_indices); + g_free (static_indices); priv->n_vertices = (priv->x_tiles + 1) * (priv->y_tiles + 1); diff --git a/clutter/clutter/clutter-deform-effect.h b/clutter/clutter/clutter-deform-effect.h index 08d0ca964..bc0fa210d 100644 --- a/clutter/clutter/clutter-deform-effect.h +++ b/clutter/clutter/clutter-deform-effect.h @@ -92,24 +92,24 @@ struct _ClutterDeformEffectClass void (*_clutter_deform7) (void); }; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT GType clutter_deform_effect_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_deform_effect_set_back_material (ClutterDeformEffect *effect, CoglHandle material); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT CoglHandle clutter_deform_effect_get_back_material (ClutterDeformEffect *effect); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_deform_effect_set_n_tiles (ClutterDeformEffect *effect, guint x_tiles, guint y_tiles); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_deform_effect_get_n_tiles (ClutterDeformEffect *effect, guint *x_tiles, guint *y_tiles); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_deform_effect_invalidate (ClutterDeformEffect *effect); G_END_DECLS diff --git a/clutter/clutter/clutter-deprecated.h b/clutter/clutter/clutter-deprecated.h index c54440d88..e793c3f6b 100644 --- a/clutter/clutter/clutter-deprecated.h +++ b/clutter/clutter/clutter-deprecated.h @@ -5,40 +5,14 @@ #include "deprecated/clutter-actor.h" #include "deprecated/clutter-alpha.h" -#include "deprecated/clutter-animatable.h" #include "deprecated/clutter-animation.h" -#include "deprecated/clutter-animator.h" -#include "deprecated/clutter-backend.h" -#include "deprecated/clutter-behaviour.h" -#include "deprecated/clutter-behaviour-depth.h" -#include "deprecated/clutter-behaviour-ellipse.h" -#include "deprecated/clutter-behaviour-opacity.h" -#include "deprecated/clutter-behaviour-path.h" -#include "deprecated/clutter-behaviour-rotate.h" -#include "deprecated/clutter-behaviour-scale.h" -#include "deprecated/clutter-bin-layout.h" #include "deprecated/clutter-box.h" -#include "deprecated/clutter-cairo-texture.h" #include "deprecated/clutter-container.h" -#include "deprecated/clutter-frame-source.h" #include "deprecated/clutter-group.h" -#include "deprecated/clutter-input-device.h" -#include "deprecated/clutter-keysyms.h" -#include "deprecated/clutter-list-model.h" -#include "deprecated/clutter-main.h" -#include "deprecated/clutter-media.h" -#include "deprecated/clutter-model.h" #include "deprecated/clutter-rectangle.h" -#include "deprecated/clutter-score.h" -#include "deprecated/clutter-shader.h" -#include "deprecated/clutter-stage-manager.h" #include "deprecated/clutter-stage.h" #include "deprecated/clutter-state.h" -#include "deprecated/clutter-table-layout.h" -#include "deprecated/clutter-texture.h" #include "deprecated/clutter-timeline.h" -#include "deprecated/clutter-timeout-pool.h" -#include "deprecated/clutter-util.h" #undef __CLUTTER_DEPRECATED_H_INSIDE__ diff --git a/clutter/clutter/clutter-desaturate-effect.c b/clutter/clutter/clutter-desaturate-effect.c index 7e1804b74..82d9911ff 100644 --- a/clutter/clutter/clutter-desaturate-effect.c +++ b/clutter/clutter/clutter-desaturate-effect.c @@ -39,9 +39,7 @@ #define CLUTTER_IS_DESATURATE_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_DESATURATE_EFFECT)) #define CLUTTER_DESATURATE_EFFECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_DESATURATE_EFFECT, ClutterDesaturateEffectClass)) -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #define CLUTTER_ENABLE_EXPERIMENTAL_API @@ -114,7 +112,8 @@ G_DEFINE_TYPE (ClutterDesaturateEffect, CLUTTER_TYPE_OFFSCREEN_EFFECT); static gboolean -clutter_desaturate_effect_pre_paint (ClutterEffect *effect) +clutter_desaturate_effect_pre_paint (ClutterEffect *effect, + ClutterPaintContext *paint_context) { ClutterDesaturateEffect *self = CLUTTER_DESATURATE_EFFECT (effect); ClutterEffectClass *parent_class; @@ -135,7 +134,7 @@ clutter_desaturate_effect_pre_paint (ClutterEffect *effect) } parent_class = CLUTTER_EFFECT_CLASS (clutter_desaturate_effect_parent_class); - if (parent_class->pre_paint (effect)) + if (parent_class->pre_paint (effect, paint_context)) { ClutterOffscreenEffect *offscreen_effect = CLUTTER_OFFSCREEN_EFFECT (effect); @@ -154,9 +153,12 @@ clutter_desaturate_effect_pre_paint (ClutterEffect *effect) } static void -clutter_desaturate_effect_paint_target (ClutterOffscreenEffect *effect) +clutter_desaturate_effect_paint_target (ClutterOffscreenEffect *effect, + ClutterPaintContext *paint_context) { ClutterDesaturateEffect *self = CLUTTER_DESATURATE_EFFECT (effect); + CoglFramebuffer *framebuffer = + clutter_paint_context_get_framebuffer (paint_context); ClutterActor *actor; CoglHandle texture; guint8 paint_opacity; @@ -172,13 +174,12 @@ clutter_desaturate_effect_paint_target (ClutterOffscreenEffect *effect) paint_opacity, paint_opacity, paint_opacity); - cogl_push_source (self->pipeline); - cogl_rectangle (0, 0, - cogl_texture_get_width (texture), - cogl_texture_get_height (texture)); - - cogl_pop_source (); + cogl_framebuffer_draw_rectangle (framebuffer, + self->pipeline, + 0, 0, + cogl_texture_get_width (texture), + cogl_texture_get_height (texture)); } static void @@ -299,9 +300,7 @@ clutter_desaturate_effect_init (ClutterDesaturateEffect *self) cogl_pipeline_add_snippet (klass->base_pipeline, snippet); cogl_object_unref (snippet); - cogl_pipeline_set_layer_null_texture (klass->base_pipeline, - 0, /* layer number */ - COGL_TEXTURE_TYPE_2D); + cogl_pipeline_set_layer_null_texture (klass->base_pipeline, 0); } self->pipeline = cogl_pipeline_copy (klass->base_pipeline); diff --git a/clutter/clutter/clutter-desaturate-effect.h b/clutter/clutter/clutter-desaturate-effect.h index 58f10a498..b832dbaca 100644 --- a/clutter/clutter/clutter-desaturate-effect.h +++ b/clutter/clutter/clutter-desaturate-effect.h @@ -48,16 +48,16 @@ G_BEGIN_DECLS typedef struct _ClutterDesaturateEffect ClutterDesaturateEffect; typedef struct _ClutterDesaturateEffectClass ClutterDesaturateEffectClass; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT GType clutter_desaturate_effect_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT ClutterEffect *clutter_desaturate_effect_new (gdouble factor); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_desaturate_effect_set_factor (ClutterDesaturateEffect *effect, gdouble factor); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT gdouble clutter_desaturate_effect_get_factor (ClutterDesaturateEffect *effect); G_END_DECLS diff --git a/clutter/clutter/clutter-device-manager-private.h b/clutter/clutter/clutter-device-manager-private.h deleted file mode 100644 index 2364fd27c..000000000 --- a/clutter/clutter/clutter-device-manager-private.h +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -#ifndef __CLUTTER_DEVICE_MANAGER_PRIVATE_H__ -#define __CLUTTER_DEVICE_MANAGER_PRIVATE_H__ - -#include -#include -#include - -G_BEGIN_DECLS - -typedef struct _ClutterAxisInfo -{ - ClutterInputAxis axis; - - gdouble min_axis; - gdouble max_axis; - - gdouble min_value; - gdouble max_value; - - gdouble resolution; -} ClutterAxisInfo; - -typedef struct _ClutterKeyInfo -{ - guint keyval; - ClutterModifierType modifiers; -} ClutterKeyInfo; - -typedef struct _ClutterScrollInfo -{ - guint axis_id; - ClutterScrollDirection direction; - gdouble increment; - - gdouble last_value; - guint last_value_valid : 1; -} ClutterScrollInfo; - -typedef struct _ClutterTouchInfo -{ - ClutterEventSequence *sequence; - ClutterActor *actor; - - gfloat current_x; - gfloat current_y; -} ClutterTouchInfo; - -struct _ClutterInputDevice -{ - GObject parent_instance; - - gint id; - - ClutterInputDeviceType device_type; - ClutterInputMode device_mode; - - gchar *device_name; - - ClutterDeviceManager *device_manager; - - ClutterBackend *backend; - - /* the associated device */ - ClutterInputDevice *associated; - - GList *slaves; - - /* the actor underneath the pointer */ - ClutterActor *cursor_actor; - GHashTable *inv_touch_sequence_actors; - - /* the actor that has a grab in place for the device */ - ClutterActor *pointer_grab_actor; - ClutterActor *keyboard_grab_actor; - GHashTable *sequence_grab_actors; - GHashTable *inv_sequence_grab_actors; - - /* the current click count */ - gint click_count; - - /* the stage the device is on */ - ClutterStage *stage; - - /* the current state */ - gfloat current_x; - gfloat current_y; - guint32 current_time; - gint current_button_number; - ClutterModifierType current_state; - - /* the current touch points states */ - GHashTable *touch_sequences_info; - - /* the previous state, used for click count generation */ - gint previous_x; - gint previous_y; - guint32 previous_time; - gint previous_button_number; - ClutterModifierType previous_state; - - GArray *axes; - - guint n_keys; - GArray *keys; - - GArray *scroll_info; - - gchar *vendor_id; - gchar *product_id; - gchar *node_path; - - GPtrArray *tools; - - gint n_rings; - gint n_strips; - gint n_mode_groups; - - ClutterInputDeviceMapping mapping_mode; - - guint has_cursor : 1; - guint is_enabled : 1; -}; - -typedef void (*ClutterEmitInputDeviceEvent) (ClutterEvent *event, - ClutterInputDevice *device); - -struct _ClutterInputDeviceClass -{ - GObjectClass parent_class; - - gboolean (* keycode_to_evdev) (ClutterInputDevice *device, - guint hardware_keycode, - guint *evdev_keycode); - void (* update_from_tool) (ClutterInputDevice *device, - ClutterInputDeviceTool *tool); - - gboolean (* is_mode_switch_button) (ClutterInputDevice *device, - guint group, - guint button); - gint (* get_group_n_modes) (ClutterInputDevice *device, - gint group); - - gboolean (* is_grouped) (ClutterInputDevice *device, - ClutterInputDevice *other_device); - - /* Keyboard accessbility */ - void (* process_kbd_a11y_event) (ClutterEvent *event, - ClutterInputDevice *device, - ClutterEmitInputDeviceEvent emit_event_func); -}; - -/* Platform-dependent interface */ -typedef struct _ClutterEventExtender ClutterEventExtender; -typedef struct _ClutterEventExtenderInterface ClutterEventExtenderInterface; - -#define CLUTTER_TYPE_EVENT_EXTENDER (clutter_event_extender_get_type ()) -#define CLUTTER_EVENT_EXTENDER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CLUTTER_TYPE_EVENT_EXTENDER, ClutterEventExtender)) -#define CLUTTER_IS_EVENT_EXTENDER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CLUTTER_TYPE_EVENT_EXTENDER)) -#define CLUTTER_EVENT_EXTENDER_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), CLUTTER_TYPE_EVENT_EXTENDER, ClutterEventExtenderInterface)) - -struct _ClutterEventExtenderInterface -{ - GTypeInterface g_iface; - - void (* copy_event_data) (ClutterEventExtender *event_extender, - const ClutterEvent *src, - ClutterEvent *dest); - void (* free_event_data) (ClutterEventExtender *event_extender, - ClutterEvent *event); -}; - -GType clutter_event_extender_get_type (void) G_GNUC_CONST; - -/* device manager */ -void _clutter_device_manager_add_device (ClutterDeviceManager *device_manager, - ClutterInputDevice *device); -void _clutter_device_manager_remove_device (ClutterDeviceManager *device_manager, - ClutterInputDevice *device); -void _clutter_device_manager_update_devices (ClutterDeviceManager *device_manager); -void _clutter_device_manager_select_stage_events (ClutterDeviceManager *device_manager, - ClutterStage *stage); -ClutterBackend *_clutter_device_manager_get_backend (ClutterDeviceManager *device_manager); - -void _clutter_device_manager_compress_motion (ClutterDeviceManager *device_manger, - ClutterEvent *event, - const ClutterEvent *to_discard); - -/* input device */ -gboolean _clutter_input_device_has_sequence (ClutterInputDevice *device, - ClutterEventSequence *sequence); -void _clutter_input_device_add_event_sequence (ClutterInputDevice *device, - ClutterEvent *event); -void _clutter_input_device_remove_event_sequence (ClutterInputDevice *device, - ClutterEvent *event); -void _clutter_input_device_set_coords (ClutterInputDevice *device, - ClutterEventSequence *sequence, - gfloat x, - gfloat y, - ClutterStage *stage); -void _clutter_input_device_set_state (ClutterInputDevice *device, - ClutterModifierType state); -void _clutter_input_device_set_time (ClutterInputDevice *device, - guint32 time_); -void _clutter_input_device_set_stage (ClutterInputDevice *device, - ClutterStage *stage); -ClutterStage * _clutter_input_device_get_stage (ClutterInputDevice *device); -void _clutter_input_device_set_actor (ClutterInputDevice *device, - ClutterEventSequence *sequence, - ClutterActor *actor, - gboolean emit_crossing); -ClutterActor * _clutter_input_device_update (ClutterInputDevice *device, - ClutterEventSequence *sequence, - gboolean emit_crossing); -void _clutter_input_device_set_n_keys (ClutterInputDevice *device, - guint n_keys); -guint _clutter_input_device_add_axis (ClutterInputDevice *device, - ClutterInputAxis axis, - gdouble min_value, - gdouble max_value, - gdouble resolution); -void _clutter_input_device_reset_axes (ClutterInputDevice *device); - -void _clutter_input_device_set_associated_device (ClutterInputDevice *device, - ClutterInputDevice *associated); -void _clutter_input_device_add_slave (ClutterInputDevice *master, - ClutterInputDevice *slave); -void _clutter_input_device_remove_slave (ClutterInputDevice *master, - ClutterInputDevice *slave); - -gboolean _clutter_input_device_translate_axis (ClutterInputDevice *device, - guint index_, - gdouble value, - gdouble *axis_value); - -void _clutter_input_device_add_scroll_info (ClutterInputDevice *device, - guint index_, - ClutterScrollDirection direction, - gdouble increment); -void _clutter_input_device_reset_scroll_info (ClutterInputDevice *device); -gboolean _clutter_input_device_get_scroll_delta (ClutterInputDevice *device, - guint index_, - gdouble value, - ClutterScrollDirection *direction_p, - gdouble *delta_p); - -ClutterInputDeviceTool * clutter_input_device_lookup_tool (ClutterInputDevice *device, - guint64 serial, - ClutterInputDeviceToolType type); -void clutter_input_device_add_tool (ClutterInputDevice *device, - ClutterInputDeviceTool *tool); - -void clutter_input_device_update_from_tool (ClutterInputDevice *device, - ClutterInputDeviceTool *tool); - -G_END_DECLS - -#endif /* __CLUTTER_DEVICE_MANAGER_PRIVATE_H__ */ diff --git a/clutter/clutter/clutter-device-manager.c b/clutter/clutter/clutter-device-manager.c deleted file mode 100644 index 20ef03388..000000000 --- a/clutter/clutter/clutter-device-manager.c +++ /dev/null @@ -1,589 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2009 Intel Corp. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Emmanuele Bassi - */ - -/** - * SECTION:clutter-device-manager - * @short_description: Maintains the list of input devices - * - * #ClutterDeviceManager is a singleton object, owned by Clutter, which - * maintains the list of #ClutterInputDevices. - * - * Depending on the backend used by Clutter it is possible to use the - * #ClutterDeviceManager::device-added and - * #ClutterDeviceManager::device-removed to monitor addition and removal - * of devices. - * - * #ClutterDeviceManager is available since Clutter 1.2 - */ - -#ifdef HAVE_CONFIG_H -#include "clutter-build-config.h" -#endif - -#include "clutter-backend-private.h" -#include "clutter-debug.h" -#include "clutter-device-manager-private.h" -#include "clutter-enum-types.h" -#include "clutter-marshal.h" -#include "clutter-private.h" -#include "clutter-stage-private.h" -#include "clutter-virtual-input-device.h" -#include "clutter-input-device-tool.h" - -struct _ClutterDeviceManagerPrivate -{ - /* back-pointer to the backend */ - ClutterBackend *backend; - - /* Keyboard a11y */ - ClutterKbdA11ySettings kbd_a11y_settings; -}; - -enum -{ - PROP_0, - - PROP_BACKEND, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST]; - -enum -{ - DEVICE_ADDED, - DEVICE_REMOVED, - TOOL_CHANGED, - KBD_A11Y_MASK_CHANGED, - KBD_A11Y_FLAGS_CHANGED, - - LAST_SIGNAL -}; - -static guint manager_signals[LAST_SIGNAL] = { 0, }; - -G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterDeviceManager, - clutter_device_manager, - G_TYPE_OBJECT) - -G_DEFINE_INTERFACE (ClutterEventExtender, - clutter_event_extender, - CLUTTER_TYPE_DEVICE_MANAGER) - -static void -clutter_event_extender_default_init (ClutterEventExtenderInterface *iface) -{ -} - -static void -clutter_device_manager_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterDeviceManagerPrivate *priv = CLUTTER_DEVICE_MANAGER (gobject)->priv; - - switch (prop_id) - { - case PROP_BACKEND: - priv->backend = g_value_get_object (value); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - } -} - -static void -clutter_device_manager_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterDeviceManagerPrivate *priv = CLUTTER_DEVICE_MANAGER (gobject)->priv; - - switch (prop_id) - { - case PROP_BACKEND: - g_value_set_object (value, priv->backend); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - } -} - -static void -clutter_device_manager_class_init (ClutterDeviceManagerClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - obj_props[PROP_BACKEND] = - g_param_spec_object ("backend", - P_("Backend"), - P_("The ClutterBackend of the device manager"), - CLUTTER_TYPE_BACKEND, - CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); - - gobject_class->set_property = clutter_device_manager_set_property; - gobject_class->get_property = clutter_device_manager_get_property; - g_object_class_install_properties (gobject_class, - PROP_LAST, - obj_props); - - /** - * ClutterDeviceManager::device-added: - * @manager: the #ClutterDeviceManager that emitted the signal - * @device: the newly added #ClutterInputDevice - * - * The ::device-added signal is emitted each time a device has been - * added to the #ClutterDeviceManager - * - * Since: 1.2 - */ - manager_signals[DEVICE_ADDED] = - g_signal_new (I_("device-added"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - _clutter_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - CLUTTER_TYPE_INPUT_DEVICE); - - /** - * ClutterDeviceManager::device-removed: - * @manager: the #ClutterDeviceManager that emitted the signal - * @device: the removed #ClutterInputDevice - * - * The ::device-removed signal is emitted each time a device has been - * removed from the #ClutterDeviceManager - * - * Since: 1.2 - */ - manager_signals[DEVICE_REMOVED] = - g_signal_new (I_("device-removed"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - _clutter_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - CLUTTER_TYPE_INPUT_DEVICE); - - manager_signals[TOOL_CHANGED] = - g_signal_new (I_("tool-changed"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, - _clutter_marshal_VOID__OBJECT_OBJECT, - G_TYPE_NONE, 2, - CLUTTER_TYPE_INPUT_DEVICE, - CLUTTER_TYPE_INPUT_DEVICE_TOOL); - - /** - * ClutterDeviceManager::kbd-a11y-mods-state-changed: - * @manager: the #ClutterDeviceManager that emitted the signal - * @latched_mask: the latched modifier mask from stickykeys - * @locked_mask: the locked modifier mask from stickykeys - * - * The ::kbd-a11y-mods-state-changed signal is emitted each time either the - * latched modifiers mask or locked modifiers mask are changed as the - * result of keyboard accessibilty's sticky keys operations. - */ - manager_signals[KBD_A11Y_MASK_CHANGED] = - g_signal_new (I_("kbd-a11y-mods-state-changed"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, - _clutter_marshal_VOID__UINT_UINT, - G_TYPE_NONE, 2, - G_TYPE_UINT, - G_TYPE_UINT); - - /** - * ClutterDeviceManager::kbd-a11y-flags-changed: - * @manager: the #ClutterDeviceManager that emitted the signal - * @settings_flags: the new ClutterKeyboardA11yFlags configuration - * @changed_mask: the ClutterKeyboardA11yFlags changed - * - * The ::kbd-a11y-flags-changed signal is emitted each time the - * ClutterKeyboardA11yFlags configuration is changed as the result of - * keyboard accessibilty operations. - */ - manager_signals[KBD_A11Y_FLAGS_CHANGED] = - g_signal_new (I_("kbd-a11y-flags-changed"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, - _clutter_marshal_VOID__UINT_UINT, - G_TYPE_NONE, 2, - G_TYPE_UINT, - G_TYPE_UINT); -} - -static void -clutter_device_manager_init (ClutterDeviceManager *self) -{ - self->priv = clutter_device_manager_get_instance_private (self); -} - -/** - * clutter_device_manager_get_default: - * - * Retrieves the device manager singleton - * - * Return value: (transfer none): the #ClutterDeviceManager singleton. - * The returned instance is owned by Clutter and it should not be - * modified or freed - * - * Since: 1.2 - */ -ClutterDeviceManager * -clutter_device_manager_get_default (void) -{ - ClutterBackend *backend = clutter_get_default_backend (); - - return backend->device_manager; -} - -/** - * clutter_device_manager_list_devices: - * @device_manager: a #ClutterDeviceManager - * - * Lists all currently registered input devices - * - * Return value: (transfer container) (element-type Clutter.InputDevice): - * a newly allocated list of #ClutterInputDevice objects. Use - * g_slist_free() to deallocate it when done - * - * Since: 1.2 - */ -GSList * -clutter_device_manager_list_devices (ClutterDeviceManager *device_manager) -{ - const GSList *devices; - - g_return_val_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager), NULL); - - devices = clutter_device_manager_peek_devices (device_manager); - - return g_slist_copy ((GSList *) devices); -} - -/** - * clutter_device_manager_peek_devices: - * @device_manager: a #ClutterDeviceManager - * - * Lists all currently registered input devices - * - * Return value: (transfer none) (element-type Clutter.InputDevice): - * a pointer to the internal list of #ClutterInputDevice objects. The - * returned list is owned by the #ClutterDeviceManager and should never - * be modified or freed - * - * Since: 1.2 - */ -const GSList * -clutter_device_manager_peek_devices (ClutterDeviceManager *device_manager) -{ - ClutterDeviceManagerClass *manager_class; - - g_return_val_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager), NULL); - - manager_class = CLUTTER_DEVICE_MANAGER_GET_CLASS (device_manager); - return manager_class->get_devices (device_manager); -} - -/** - * clutter_device_manager_get_device: - * @device_manager: a #ClutterDeviceManager - * @device_id: the integer id of a device - * - * Retrieves the #ClutterInputDevice with the given @device_id - * - * Return value: (transfer none): a #ClutterInputDevice or %NULL. The - * returned device is owned by the #ClutterDeviceManager and should - * never be modified or freed - * - * Since: 1.2 - */ -ClutterInputDevice * -clutter_device_manager_get_device (ClutterDeviceManager *device_manager, - gint device_id) -{ - ClutterDeviceManagerClass *manager_class; - - g_return_val_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager), NULL); - - manager_class = CLUTTER_DEVICE_MANAGER_GET_CLASS (device_manager); - return manager_class->get_device (device_manager, device_id); -} - -/** - * clutter_device_manager_get_core_device: - * @device_manager: a #ClutterDeviceManager - * @device_type: the type of the core device - * - * Retrieves the core #ClutterInputDevice of type @device_type - * - * Core devices are devices created automatically by the default - * Clutter backend - * - * Return value: (transfer none): a #ClutterInputDevice or %NULL. The - * returned device is owned by the #ClutterDeviceManager and should - * not be modified or freed - * - * Since: 1.2 - */ -ClutterInputDevice * -clutter_device_manager_get_core_device (ClutterDeviceManager *device_manager, - ClutterInputDeviceType device_type) -{ - ClutterDeviceManagerClass *manager_class; - - g_return_val_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager), NULL); - - manager_class = CLUTTER_DEVICE_MANAGER_GET_CLASS (device_manager); - return manager_class->get_core_device (device_manager, device_type); -} - -void -_clutter_device_manager_select_stage_events (ClutterDeviceManager *device_manager, - ClutterStage *stage) -{ - ClutterDeviceManagerClass *manager_class; - - g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager)); - - manager_class = CLUTTER_DEVICE_MANAGER_GET_CLASS (device_manager); - if (manager_class->select_stage_events) - manager_class->select_stage_events (device_manager, stage); -} - -/* - * _clutter_device_manager_add_device: - * @device_manager: a #ClutterDeviceManager - * @device: a #ClutterInputDevice - * - * Adds @device to the list of #ClutterInputDevices maintained - * by @device_manager - * - * The reference count of @device is not increased - * - * The #ClutterDeviceManager::device-added signal is emitted after - * adding @device to the list - */ -void -_clutter_device_manager_add_device (ClutterDeviceManager *device_manager, - ClutterInputDevice *device) -{ - ClutterDeviceManagerClass *manager_class; - - g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager)); - - manager_class = CLUTTER_DEVICE_MANAGER_GET_CLASS (device_manager); - g_assert (manager_class->add_device != NULL); - - manager_class->add_device (device_manager, device); - - g_signal_emit (device_manager, manager_signals[DEVICE_ADDED], 0, device); -} - -/* - * _clutter_device_manager_remove_device: - * @device_manager: a #ClutterDeviceManager - * @device: a #ClutterInputDevice - * - * Removes @device from the list of #ClutterInputDevices - * maintained by @device_manager - * - * The reference count of @device is not decreased - * - * The #ClutterDeviceManager::device-removed signal is emitted after - * removing @device from the list - */ -void -_clutter_device_manager_remove_device (ClutterDeviceManager *device_manager, - ClutterInputDevice *device) -{ - ClutterDeviceManagerClass *manager_class; - - g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager)); - - manager_class = CLUTTER_DEVICE_MANAGER_GET_CLASS (device_manager); - g_assert (manager_class->remove_device != NULL); - - /* The subclass remove_device() method will likely unref it but we - have to keep it alive during the signal emission. */ - g_object_ref (device); - - manager_class->remove_device (device_manager, device); - g_signal_emit (device_manager, manager_signals[DEVICE_REMOVED], 0, device); - - g_object_unref (device); -} - -/* - * _clutter_device_manager_update_devices: - * @device_manager: a #ClutterDeviceManager - * - * Updates every #ClutterInputDevice handled by @device_manager - * by performing a pick paint at the coordinates of each pointer - * device - */ -void -_clutter_device_manager_update_devices (ClutterDeviceManager *device_manager) -{ - const GSList *d; - - for (d = clutter_device_manager_peek_devices (device_manager); - d != NULL; - d = d->next) - { - ClutterInputDevice *device = d->data; - ClutterInputDeviceType device_type; - - /* we only care about pointer devices */ - device_type = clutter_input_device_get_device_type (device); - if (device_type != CLUTTER_POINTER_DEVICE) - continue; - - /* out of stage */ - if (device->stage == NULL) - continue; - - /* the user disabled motion events delivery on actors for - * the stage the device is on; we don't perform any picking - * since the source of the events will always be set to be - * the stage - */ - if (!clutter_stage_get_motion_events_enabled (device->stage)) - continue; - - _clutter_input_device_update (device, NULL, TRUE); - } -} - -ClutterBackend * -_clutter_device_manager_get_backend (ClutterDeviceManager *manager) -{ - g_return_val_if_fail (CLUTTER_IS_DEVICE_MANAGER (manager), NULL); - - return manager->priv->backend; -} - -/** - * clutter_device_manager_create_virtual_device: - * @device_manager: a #ClutterDeviceManager - * @device_type: the type of the virtual device - * - * Creates a virtual input device. - * - * Returns: (transfer full): a newly created virtual device - **/ -ClutterVirtualInputDevice * -clutter_device_manager_create_virtual_device (ClutterDeviceManager *device_manager, - ClutterInputDeviceType device_type) -{ - ClutterDeviceManagerClass *manager_class; - - g_return_val_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager), NULL); - - manager_class = CLUTTER_DEVICE_MANAGER_GET_CLASS (device_manager); - return manager_class->create_virtual_device (device_manager, - device_type); -} - -/** - * clutter_device_manager_supported_virtua_device_types: (skip) - */ -ClutterVirtualDeviceType -clutter_device_manager_get_supported_virtual_device_types (ClutterDeviceManager *device_manager) -{ - ClutterDeviceManagerClass *manager_class; - - g_return_val_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager), - CLUTTER_VIRTUAL_DEVICE_TYPE_NONE); - - manager_class = CLUTTER_DEVICE_MANAGER_GET_CLASS (device_manager); - return manager_class->get_supported_virtual_device_types (device_manager); -} - -void -_clutter_device_manager_compress_motion (ClutterDeviceManager *device_manager, - ClutterEvent *event, - const ClutterEvent *to_discard) -{ - ClutterDeviceManagerClass *manager_class; - - g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager)); - - - manager_class = CLUTTER_DEVICE_MANAGER_GET_CLASS (device_manager); - if (!manager_class->compress_motion) - return; - - manager_class->compress_motion (device_manager, event, to_discard); -} - -static gboolean -are_kbd_a11y_settings_equal (ClutterKbdA11ySettings *a, - ClutterKbdA11ySettings *b) -{ - return (a->controls == b->controls && - a->slowkeys_delay == b->slowkeys_delay && - a->debounce_delay == b->debounce_delay && - a->timeout_delay == b->timeout_delay && - a->mousekeys_init_delay == b->mousekeys_init_delay && - a->mousekeys_max_speed == b->mousekeys_max_speed && - a->mousekeys_accel_time == b->mousekeys_accel_time); -} - -void -clutter_device_manager_set_kbd_a11y_settings (ClutterDeviceManager *device_manager, - ClutterKbdA11ySettings *settings) -{ - ClutterDeviceManagerClass *manager_class; - - g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager)); - - if (are_kbd_a11y_settings_equal (&device_manager->priv->kbd_a11y_settings, settings)) - return; - - device_manager->priv->kbd_a11y_settings = *settings; - - manager_class = CLUTTER_DEVICE_MANAGER_GET_CLASS (device_manager); - if (manager_class->apply_kbd_a11y_settings) - manager_class->apply_kbd_a11y_settings (device_manager, settings); -} - -void -clutter_device_manager_get_kbd_a11y_settings (ClutterDeviceManager *device_manager, - ClutterKbdA11ySettings *settings) -{ - g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager)); - - *settings = device_manager->priv->kbd_a11y_settings; -} diff --git a/clutter/clutter/clutter-device-manager.h b/clutter/clutter/clutter-device-manager.h deleted file mode 100644 index aebfc4b5d..000000000 --- a/clutter/clutter/clutter-device-manager.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2009 Intel Corp. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Emmanuele Bassi - */ - -#ifndef __CLUTTER_DEVICE_MANAGER_H__ -#define __CLUTTER_DEVICE_MANAGER_H__ - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include -#include - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_DEVICE_MANAGER (clutter_device_manager_get_type ()) -#define CLUTTER_DEVICE_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_DEVICE_MANAGER, ClutterDeviceManager)) -#define CLUTTER_IS_DEVICE_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_DEVICE_MANAGER)) -#define CLUTTER_DEVICE_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_DEVICE_MANAGER, ClutterDeviceManagerClass)) -#define CLUTTER_IS_DEVICE_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_DEVICE_MANAGER)) -#define CLUTTER_DEVICE_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_DEVICE_MANAGER, ClutterDeviceManagerClass)) - -typedef struct _ClutterDeviceManager ClutterDeviceManager; -typedef struct _ClutterDeviceManagerPrivate ClutterDeviceManagerPrivate; -typedef struct _ClutterDeviceManagerClass ClutterDeviceManagerClass; - -/** - * ClutterVirtualDeviceType: - */ -typedef enum _ClutterVirtualDeviceType -{ - CLUTTER_VIRTUAL_DEVICE_TYPE_NONE = 0, - CLUTTER_VIRTUAL_DEVICE_TYPE_KEYBOARD = 1 << 0, - CLUTTER_VIRTUAL_DEVICE_TYPE_POINTER = 1 << 1, - CLUTTER_VIRTUAL_DEVICE_TYPE_TOUCHSCREEN = 1 << 2, -} ClutterVirtualDeviceType; - -/** - * ClutterKbdA11ySettings: - * - * The #ClutterKbdA11ySettings structure contains keyboard accessibility - * settings - * - */ -typedef struct _ClutterKbdA11ySettings -{ - ClutterKeyboardA11yFlags controls; - gint slowkeys_delay; - gint debounce_delay; - gint timeout_delay; - gint mousekeys_init_delay; - gint mousekeys_max_speed; - gint mousekeys_accel_time; -} ClutterKbdA11ySettings; - -/** - * ClutterDeviceManager: - * - * The #ClutterDeviceManager structure contains only private data - * - * Since: 1.2 - */ -struct _ClutterDeviceManager -{ - /*< private >*/ - GObject parent_instance; - - ClutterDeviceManagerPrivate *priv; -}; - -/** - * ClutterDeviceManagerClass: - * - * The #ClutterDeviceManagerClass structure contains only private data - * - * Since: 1.2 - */ -struct _ClutterDeviceManagerClass -{ - /*< private >*/ - GObjectClass parent_class; - - const GSList * (* get_devices) (ClutterDeviceManager *device_manager); - ClutterInputDevice *(* get_core_device) (ClutterDeviceManager *device_manager, - ClutterInputDeviceType device_type); - ClutterInputDevice *(* get_device) (ClutterDeviceManager *device_manager, - gint device_id); - - void (* add_device) (ClutterDeviceManager *manager, - ClutterInputDevice *device); - void (* remove_device) (ClutterDeviceManager *manager, - ClutterInputDevice *device); - void (* select_stage_events) (ClutterDeviceManager *manager, - ClutterStage *stage); - ClutterVirtualInputDevice *(* create_virtual_device) (ClutterDeviceManager *device_manager, - ClutterInputDeviceType device_type); - ClutterVirtualDeviceType (* get_supported_virtual_device_types) (ClutterDeviceManager *device_manager); - void (* compress_motion) (ClutterDeviceManager *device_manger, - ClutterEvent *event, - const ClutterEvent *to_discard); - /* Keyboard accessbility */ - void (* apply_kbd_a11y_settings) (ClutterDeviceManager *device_manger, - ClutterKbdA11ySettings *settings); - /* padding */ - gpointer _padding[6]; -}; - -CLUTTER_AVAILABLE_IN_1_2 -GType clutter_device_manager_get_type (void) G_GNUC_CONST; - -CLUTTER_AVAILABLE_IN_1_2 -ClutterDeviceManager *clutter_device_manager_get_default (void); -CLUTTER_AVAILABLE_IN_1_2 -GSList * clutter_device_manager_list_devices (ClutterDeviceManager *device_manager); -CLUTTER_AVAILABLE_IN_1_2 -const GSList * clutter_device_manager_peek_devices (ClutterDeviceManager *device_manager); - -CLUTTER_AVAILABLE_IN_1_2 -ClutterInputDevice * clutter_device_manager_get_device (ClutterDeviceManager *device_manager, - gint device_id); -CLUTTER_AVAILABLE_IN_1_2 -ClutterInputDevice * clutter_device_manager_get_core_device (ClutterDeviceManager *device_manager, - ClutterInputDeviceType device_type); - -CLUTTER_AVAILABLE_IN_ALL -ClutterVirtualInputDevice *clutter_device_manager_create_virtual_device (ClutterDeviceManager *device_manager, - ClutterInputDeviceType device_type); - -CLUTTER_AVAILABLE_IN_ALL -ClutterVirtualDeviceType clutter_device_manager_get_supported_virtual_device_types (ClutterDeviceManager *device_manager); - -CLUTTER_AVAILABLE_IN_ALL -void clutter_device_manager_set_kbd_a11y_settings (ClutterDeviceManager *device_manager, - ClutterKbdA11ySettings *settings); -CLUTTER_AVAILABLE_IN_ALL -void clutter_device_manager_get_kbd_a11y_settings (ClutterDeviceManager *device_manager, - ClutterKbdA11ySettings *settings); - -G_END_DECLS - -#endif /* __CLUTTER_DEVICE_MANAGER_H__ */ diff --git a/clutter/clutter/clutter-drag-action.c b/clutter/clutter/clutter-drag-action.c index 57dae7266..162ebb3d4 100644 --- a/clutter/clutter/clutter-drag-action.c +++ b/clutter/clutter/clutter-drag-action.c @@ -63,9 +63,7 @@ * #ClutterDragAction is available since Clutter 1.4 */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include "clutter-drag-action.h" @@ -83,7 +81,7 @@ struct _ClutterDragActionPrivate gint y_drag_threshold; ClutterActor *drag_handle; ClutterDragAxis drag_axis; - ClutterRect drag_area; + graphene_rect_t drag_area; ClutterInputDevice *device; ClutterEventSequence *sequence; @@ -317,11 +315,7 @@ emit_drag_end (ClutterDragAction *action, goto out; /* disconnect the capture */ - if (priv->capture_id != 0) - { - g_signal_handler_disconnect (priv->stage, priv->capture_id); - priv->capture_id = 0; - } + g_clear_signal_handler (&priv->capture_id, priv->stage); clutter_stage_set_motion_events_enabled (priv->stage, priv->motion_events_enabled); @@ -480,8 +474,8 @@ clutter_drag_action_set_actor (ClutterActorMeta *meta, old_actor = clutter_actor_meta_get_actor (meta); if (old_actor != NULL) { - g_signal_handler_disconnect (old_actor, priv->button_press_id); - g_signal_handler_disconnect (old_actor, priv->touch_begin_id); + g_clear_signal_handler (&priv->button_press_id, old_actor); + g_clear_signal_handler (&priv->touch_begin_id, old_actor); } priv->button_press_id = 0; @@ -491,7 +485,7 @@ clutter_drag_action_set_actor (ClutterActorMeta *meta, if (priv->capture_id != 0) { if (priv->stage != NULL) - g_signal_handler_disconnect (priv->stage, priv->capture_id); + g_clear_signal_handler (&priv->capture_id, priv->stage); priv->capture_id = 0; priv->stage = NULL; @@ -544,7 +538,7 @@ clutter_drag_action_real_drag_motion (ClutterDragAction *action, if (action->priv->drag_area_set) { - ClutterRect *drag_area = &action->priv->drag_area; + graphene_rect_t *drag_area = &action->priv->drag_area; x = CLAMP (x, drag_area->origin.x, drag_area->origin.x + drag_area->size.width); y = CLAMP (y, drag_area->origin.y, drag_area->origin.y + drag_area->size.height); @@ -670,7 +664,7 @@ clutter_drag_action_dispose (GObject *gobject) priv->motion_events_enabled); if (priv->stage != NULL) - g_signal_handler_disconnect (priv->stage, priv->capture_id); + g_clear_signal_handler (&priv->capture_id, priv->stage); priv->capture_id = 0; priv->stage = NULL; @@ -683,8 +677,8 @@ clutter_drag_action_dispose (GObject *gobject) actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (gobject)); if (actor != NULL) { - g_signal_handler_disconnect (actor, priv->button_press_id); - g_signal_handler_disconnect (actor, priv->touch_begin_id); + g_clear_signal_handler (&priv->button_press_id, actor); + g_clear_signal_handler (&priv->touch_begin_id, actor); } priv->button_press_id = 0; @@ -813,7 +807,7 @@ clutter_drag_action_class_init (ClutterDragActionClass *klass) g_param_spec_boxed ("drag-area", P_("Drag Area"), P_("Constrains the dragging to a rectangle"), - CLUTTER_TYPE_RECT, + GRAPHENE_TYPE_RECT, CLUTTER_PARAM_READWRITE); /** @@ -1269,10 +1263,10 @@ clutter_drag_action_get_motion_coords (ClutterDragAction *action, /** * clutter_drag_action_get_drag_area: * @action: a #ClutterDragAction - * @drag_area: (out caller-allocates): a #ClutterRect to be filled + * @drag_area: (out caller-allocates): a #graphene_rect_t to be filled * * Retrieves the "drag area" associated with @action, that - * is a #ClutterRect that constrains the actor movements, + * is a #graphene_rect_t that constrains the actor movements, * in parents coordinates. * * Returns: %TRUE if the actor is actually constrained (and thus @@ -1280,7 +1274,7 @@ clutter_drag_action_get_motion_coords (ClutterDragAction *action, */ gboolean clutter_drag_action_get_drag_area (ClutterDragAction *action, - ClutterRect *drag_area) + graphene_rect_t *drag_area) { g_return_val_if_fail (CLUTTER_IS_DRAG_ACTION (action), FALSE); @@ -1300,8 +1294,8 @@ clutter_drag_action_get_drag_area (ClutterDragAction *action, * If @drag_area is %NULL, the actor is not constrained. */ void -clutter_drag_action_set_drag_area (ClutterDragAction *action, - const ClutterRect *drag_area) +clutter_drag_action_set_drag_area (ClutterDragAction *action, + const graphene_rect_t *drag_area) { ClutterDragActionPrivate *priv; diff --git a/clutter/clutter/clutter-drag-action.h b/clutter/clutter/clutter-drag-action.h index a11d7381e..6904dc5ed 100644 --- a/clutter/clutter/clutter-drag-action.h +++ b/clutter/clutter/clutter-drag-action.h @@ -105,47 +105,47 @@ struct _ClutterDragActionClass void (* _clutter_drag_action4) (void); }; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT GType clutter_drag_action_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT ClutterAction * clutter_drag_action_new (void); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_drag_action_set_drag_threshold (ClutterDragAction *action, gint x_threshold, gint y_threshold); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_drag_action_get_drag_threshold (ClutterDragAction *action, guint *x_threshold, guint *y_threshold); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_drag_action_set_drag_handle (ClutterDragAction *action, ClutterActor *handle); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT ClutterActor * clutter_drag_action_get_drag_handle (ClutterDragAction *action); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_drag_action_set_drag_axis (ClutterDragAction *action, ClutterDragAxis axis); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT ClutterDragAxis clutter_drag_action_get_drag_axis (ClutterDragAction *action); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_drag_action_get_press_coords (ClutterDragAction *action, gfloat *press_x, gfloat *press_y); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_drag_action_get_motion_coords (ClutterDragAction *action, gfloat *motion_x, gfloat *motion_y); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT gboolean clutter_drag_action_get_drag_area (ClutterDragAction *action, - ClutterRect *drag_area); + graphene_rect_t *drag_area); -CLUTTER_AVAILABLE_IN_1_12 -void clutter_drag_action_set_drag_area (ClutterDragAction *action, - const ClutterRect *drag_area); +CLUTTER_EXPORT +void clutter_drag_action_set_drag_area (ClutterDragAction *action, + const graphene_rect_t *drag_area); G_END_DECLS diff --git a/clutter/clutter/clutter-drop-action.c b/clutter/clutter/clutter-drop-action.c index b0fb66d49..f9e934aaa 100644 --- a/clutter/clutter/clutter-drop-action.c +++ b/clutter/clutter/clutter-drop-action.c @@ -58,9 +58,7 @@ * #ClutterDropAction is available since Clutter 1.8 */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include "clutter-drop-action.h" @@ -109,9 +107,9 @@ drop_target_free (gpointer _data) { DropTarget *data = _data; - g_signal_handler_disconnect (data->stage, data->capture_id); + g_clear_signal_handler (&data->capture_id, data->stage); g_hash_table_destroy (data->actions); - free (data); + g_free (data); } static gboolean @@ -328,12 +326,10 @@ clutter_drop_action_set_actor (ClutterActorMeta *meta, { drop_action_unregister (CLUTTER_DROP_ACTION (meta)); - if (priv->mapped_id != 0) - g_signal_handler_disconnect (priv->actor, priv->mapped_id); + g_clear_signal_handler (&priv->mapped_id, priv->actor); priv->stage = NULL; priv->actor = NULL; - priv->mapped_id = 0; } priv->actor = actor; @@ -430,8 +426,7 @@ clutter_drop_action_class_init (ClutterDropActionClass *klass) G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ClutterDropActionClass, over_in), - NULL, NULL, - _clutter_marshal_VOID__OBJECT, + NULL, NULL, NULL, G_TYPE_NONE, 1, CLUTTER_TYPE_ACTOR); @@ -450,8 +445,7 @@ clutter_drop_action_class_init (ClutterDropActionClass *klass) G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ClutterDropActionClass, over_out), - NULL, NULL, - _clutter_marshal_VOID__OBJECT, + NULL, NULL, NULL, G_TYPE_NONE, 1, CLUTTER_TYPE_ACTOR); diff --git a/clutter/clutter/clutter-drop-action.h b/clutter/clutter/clutter-drop-action.h index 2d2b40d1e..d3b973d96 100644 --- a/clutter/clutter/clutter-drop-action.h +++ b/clutter/clutter/clutter-drop-action.h @@ -104,10 +104,10 @@ struct _ClutterDropActionClass void (*_clutter_drop_action8) (void); }; -CLUTTER_AVAILABLE_IN_1_8 +CLUTTER_EXPORT GType clutter_drop_action_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_8 +CLUTTER_EXPORT ClutterAction * clutter_drop_action_new (void); G_END_DECLS diff --git a/clutter/clutter/clutter-effect-private.h b/clutter/clutter/clutter-effect-private.h index 578b6a13a..f081a0535 100644 --- a/clutter/clutter/clutter-effect-private.h +++ b/clutter/clutter/clutter-effect-private.h @@ -5,14 +5,18 @@ G_BEGIN_DECLS -gboolean _clutter_effect_pre_paint (ClutterEffect *effect); -void _clutter_effect_post_paint (ClutterEffect *effect); -gboolean _clutter_effect_get_paint_volume (ClutterEffect *effect, +gboolean _clutter_effect_pre_paint (ClutterEffect *effect, + ClutterPaintContext *paint_context); +void _clutter_effect_post_paint (ClutterEffect *effect, + ClutterPaintContext *paint_context); +gboolean _clutter_effect_modify_paint_volume (ClutterEffect *effect, ClutterPaintVolume *volume); +gboolean _clutter_effect_has_custom_paint_volume (ClutterEffect *effect); void _clutter_effect_paint (ClutterEffect *effect, + ClutterPaintContext *paint_context, ClutterEffectPaintFlags flags); void _clutter_effect_pick (ClutterEffect *effect, - ClutterEffectPaintFlags flags); + ClutterPickContext *pick_context); G_END_DECLS diff --git a/clutter/clutter/clutter-effect.c b/clutter/clutter/clutter-effect.c index 06df7ffbd..cde26fc4d 100644 --- a/clutter/clutter/clutter-effect.c +++ b/clutter/clutter/clutter-effect.c @@ -100,13 +100,13 @@ * // Clear the previous state // * if (self->rect_1) * { - * cogl_handle_unref (self->rect_1); + * cogl_object_unref (self->rect_1); * self->rect_1 = NULL; * } * * if (self->rect_2) * { - * cogl_handle_unref (self->rect_2); + * cogl_object_unref (self->rect_2); * self->rect_2 = NULL; * } * @@ -160,9 +160,7 @@ * #ClutterEffect is available since Clutter 1.4 */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include "clutter-effect.h" @@ -179,25 +177,28 @@ G_DEFINE_ABSTRACT_TYPE (ClutterEffect, CLUTTER_TYPE_ACTOR_META); static gboolean -clutter_effect_real_pre_paint (ClutterEffect *effect) +clutter_effect_real_pre_paint (ClutterEffect *effect, + ClutterPaintContext *paint_context) { return TRUE; } static void -clutter_effect_real_post_paint (ClutterEffect *effect) +clutter_effect_real_post_paint (ClutterEffect *effect, + ClutterPaintContext *paint_context) { } static gboolean -clutter_effect_real_get_paint_volume (ClutterEffect *effect, - ClutterPaintVolume *volume) +clutter_effect_real_modify_paint_volume (ClutterEffect *effect, + ClutterPaintVolume *volume) { return TRUE; } static void clutter_effect_real_paint (ClutterEffect *effect, + ClutterPaintContext *paint_context, ClutterEffectPaintFlags flags) { ClutterActorMeta *actor_meta = CLUTTER_ACTOR_META (effect); @@ -208,24 +209,24 @@ clutter_effect_real_paint (ClutterEffect *effect, effects that haven't migrated to use the 'paint' virtual yet. This just calls the old pre and post virtuals before chaining on */ - pre_paint_succeeded = _clutter_effect_pre_paint (effect); + pre_paint_succeeded = _clutter_effect_pre_paint (effect, paint_context); actor = clutter_actor_meta_get_actor (actor_meta); - clutter_actor_continue_paint (actor); + clutter_actor_continue_paint (actor, paint_context); if (pre_paint_succeeded) - _clutter_effect_post_paint (effect); + _clutter_effect_post_paint (effect, paint_context); } static void -clutter_effect_real_pick (ClutterEffect *effect, - ClutterEffectPaintFlags flags) +clutter_effect_real_pick (ClutterEffect *effect, + ClutterPickContext *pick_context) { ClutterActorMeta *actor_meta = CLUTTER_ACTOR_META (effect); ClutterActor *actor; actor = clutter_actor_meta_get_actor (actor_meta); - clutter_actor_continue_paint (actor); + clutter_actor_continue_pick (actor, pick_context); } static void @@ -254,7 +255,7 @@ clutter_effect_class_init (ClutterEffectClass *klass) klass->pre_paint = clutter_effect_real_pre_paint; klass->post_paint = clutter_effect_real_post_paint; - klass->get_paint_volume = clutter_effect_real_get_paint_volume; + klass->modify_paint_volume = clutter_effect_real_modify_paint_volume; klass->paint = clutter_effect_real_paint; klass->pick = clutter_effect_real_pick; } @@ -265,47 +266,59 @@ clutter_effect_init (ClutterEffect *self) } gboolean -_clutter_effect_pre_paint (ClutterEffect *effect) +_clutter_effect_pre_paint (ClutterEffect *effect, + ClutterPaintContext *paint_context) { g_return_val_if_fail (CLUTTER_IS_EFFECT (effect), FALSE); - return CLUTTER_EFFECT_GET_CLASS (effect)->pre_paint (effect); + return CLUTTER_EFFECT_GET_CLASS (effect)->pre_paint (effect, paint_context); } void -_clutter_effect_post_paint (ClutterEffect *effect) +_clutter_effect_post_paint (ClutterEffect *effect, + ClutterPaintContext *paint_context) { g_return_if_fail (CLUTTER_IS_EFFECT (effect)); - CLUTTER_EFFECT_GET_CLASS (effect)->post_paint (effect); + CLUTTER_EFFECT_GET_CLASS (effect)->post_paint (effect, paint_context); } void _clutter_effect_paint (ClutterEffect *effect, + ClutterPaintContext *paint_context, ClutterEffectPaintFlags flags) { g_return_if_fail (CLUTTER_IS_EFFECT (effect)); - CLUTTER_EFFECT_GET_CLASS (effect)->paint (effect, flags); + CLUTTER_EFFECT_GET_CLASS (effect)->paint (effect, paint_context, flags); } void -_clutter_effect_pick (ClutterEffect *effect, - ClutterEffectPaintFlags flags) +_clutter_effect_pick (ClutterEffect *effect, + ClutterPickContext *pick_context) { g_return_if_fail (CLUTTER_IS_EFFECT (effect)); - CLUTTER_EFFECT_GET_CLASS (effect)->pick (effect, flags); + CLUTTER_EFFECT_GET_CLASS (effect)->pick (effect, pick_context); } gboolean -_clutter_effect_get_paint_volume (ClutterEffect *effect, - ClutterPaintVolume *volume) +_clutter_effect_modify_paint_volume (ClutterEffect *effect, + ClutterPaintVolume *volume) { g_return_val_if_fail (CLUTTER_IS_EFFECT (effect), FALSE); g_return_val_if_fail (volume != NULL, FALSE); - return CLUTTER_EFFECT_GET_CLASS (effect)->get_paint_volume (effect, volume); + return CLUTTER_EFFECT_GET_CLASS (effect)->modify_paint_volume (effect, + volume); +} + +gboolean +_clutter_effect_has_custom_paint_volume (ClutterEffect *effect) +{ + g_return_val_if_fail (CLUTTER_IS_EFFECT (effect), FALSE); + + return CLUTTER_EFFECT_GET_CLASS (effect)->modify_paint_volume != clutter_effect_real_modify_paint_volume; } /** diff --git a/clutter/clutter/clutter-effect.h b/clutter/clutter/clutter-effect.h index 6cfc2f228..8e8b57b92 100644 --- a/clutter/clutter/clutter-effect.h +++ b/clutter/clutter/clutter-effect.h @@ -30,6 +30,8 @@ #endif #include +#include +#include G_BEGIN_DECLS @@ -60,7 +62,7 @@ struct _ClutterEffect * ClutterEffectClass: * @pre_paint: virtual function * @post_paint: virtual function - * @get_paint_volume: virtual function + * @modify_paint_volume: virtual function * @paint: virtual function * @pick: virtual function * @@ -74,16 +76,19 @@ struct _ClutterEffectClass ClutterActorMetaClass parent_class; /*< public >*/ - gboolean (* pre_paint) (ClutterEffect *effect); - void (* post_paint) (ClutterEffect *effect); + gboolean (* pre_paint) (ClutterEffect *effect, + ClutterPaintContext *paint_context); + void (* post_paint) (ClutterEffect *effect, + ClutterPaintContext *paint_context); - gboolean (* get_paint_volume) (ClutterEffect *effect, - ClutterPaintVolume *volume); + gboolean (* modify_paint_volume) (ClutterEffect *effect, + ClutterPaintVolume *volume); - void (* paint) (ClutterEffect *effect, - ClutterEffectPaintFlags flags); - void (* pick) (ClutterEffect *effect, - ClutterEffectPaintFlags flags); + void (* paint) (ClutterEffect *effect, + ClutterPaintContext *paint_context, + ClutterEffectPaintFlags flags); + void (* pick) (ClutterEffect *effect, + ClutterPickContext *pick_context); /*< private >*/ void (* _clutter_effect4) (void); @@ -91,38 +96,38 @@ struct _ClutterEffectClass void (* _clutter_effect6) (void); }; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT GType clutter_effect_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_8 +CLUTTER_EXPORT void clutter_effect_queue_repaint (ClutterEffect *effect); /* * ClutterActor API */ -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_actor_add_effect (ClutterActor *self, ClutterEffect *effect); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_actor_add_effect_with_name (ClutterActor *self, const gchar *name, ClutterEffect *effect); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_actor_remove_effect (ClutterActor *self, ClutterEffect *effect); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_actor_remove_effect_by_name (ClutterActor *self, const gchar *name); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT GList * clutter_actor_get_effects (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT ClutterEffect *clutter_actor_get_effect (ClutterActor *self, const gchar *name); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_actor_clear_effects (ClutterActor *self); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT gboolean clutter_actor_has_effects (ClutterActor *self); G_END_DECLS diff --git a/clutter/clutter/clutter-enum-types.h.in b/clutter/clutter/clutter-enum-types.h.in index aea757ed0..17f9ee644 100644 --- a/clutter/clutter/clutter-enum-types.h.in +++ b/clutter/clutter/clutter-enum-types.h.in @@ -13,11 +13,11 @@ G_BEGIN_DECLS /*** END file-header ***/ /*** BEGIN file-production ***/ -/* enumerations from "@filename@" */ +/* enumerations from "@basename@" */ /*** END file-production ***/ /*** BEGIN value-header ***/ -CLUTTER_AVAILABLE_IN_ALL GType @enum_name@_get_type (void) G_GNUC_CONST; +CLUTTER_EXPORT GType @enum_name@_get_type (void) G_GNUC_CONST; #define CLUTTER_TYPE_@ENUMSHORT@ (@enum_name@_get_type()) /*** END value-header ***/ diff --git a/clutter/clutter/clutter-enums.h b/clutter/clutter/clutter-enums.h index b9987d875..a12e7ec63 100644 --- a/clutter/clutter/clutter-enums.h +++ b/clutter/clutter/clutter-enums.h @@ -51,7 +51,8 @@ G_BEGIN_DECLS * * Deprecated: 1.22: Use the normalized #ClutterActor pivot point instead */ -typedef enum { /*< prefix=CLUTTER_GRAVITY >*/ +typedef enum /*< prefix=CLUTTER_GRAVITY >*/ +{ CLUTTER_GRAVITY_NONE = 0, CLUTTER_GRAVITY_NORTH, CLUTTER_GRAVITY_NORTH_EAST, @@ -74,7 +75,8 @@ typedef enum { /*< prefix=CLUTTER_GRAVITY >*/ * * Since: 0.4 */ -typedef enum { /*< prefix=CLUTTER >*/ +typedef enum /*< prefix=CLUTTER >*/ +{ CLUTTER_X_AXIS, CLUTTER_Y_AXIS, CLUTTER_Z_AXIS @@ -91,7 +93,8 @@ typedef enum { /*< prefix=CLUTTER >*/ * * Deprecated: 1.22 */ -typedef enum { /*< prefix=CLUTTER_ROTATE >*/ +typedef enum /*< prefix=CLUTTER_ROTATE >*/ +{ CLUTTER_ROTATE_CW, CLUTTER_ROTATE_CCW } ClutterRotateDirection; @@ -107,7 +110,8 @@ typedef enum { /*< prefix=CLUTTER_ROTATE >*/ * * Since: 0.8 */ -typedef enum { /*< prefix=CLUTTER_REQUEST >*/ +typedef enum /*< prefix=CLUTTER_REQUEST >*/ +{ CLUTTER_REQUEST_HEIGHT_FOR_WIDTH, CLUTTER_REQUEST_WIDTH_FOR_HEIGHT, CLUTTER_REQUEST_CONTENT_SIZE @@ -200,7 +204,8 @@ typedef enum { /*< prefix=CLUTTER_REQUEST >*/ * * Since: 1.0 */ -typedef enum { +typedef enum +{ CLUTTER_CUSTOM_MODE = 0, /* linear */ @@ -272,23 +277,6 @@ typedef enum { CLUTTER_ANIMATION_LAST } ClutterAnimationMode; -/** - * ClutterFontFlags: - * @CLUTTER_FONT_MIPMAPPING: Set to use mipmaps for the glyph cache textures. - * @CLUTTER_FONT_HINTING: Set to enable hinting on the glyphs. - * - * Runtime flags to change the font quality. To be used with - * clutter_set_font_flags(). - * - * Since: 1.0 - * - * Deprecated: 1.22: Use #cairo_font_options_t instead - */ -typedef enum { /*< prefix=CLUTTER_FONT >*/ - CLUTTER_FONT_MIPMAPPING = (1 << 0), - CLUTTER_FONT_HINTING = (1 << 1) -} ClutterFontFlags; - /** * ClutterTextDirection: * @CLUTTER_TEXT_DIRECTION_DEFAULT: Use the default setting, as returned @@ -300,7 +288,8 @@ typedef enum { /*< prefix=CLUTTER_FONT >*/ * * Since: 1.2 */ -typedef enum { +typedef enum +{ CLUTTER_TEXT_DIRECTION_DEFAULT, CLUTTER_TEXT_DIRECTION_LTR, CLUTTER_TEXT_DIRECTION_RTL @@ -315,7 +304,8 @@ typedef enum { * * Since: 1.4 */ -typedef enum { +typedef enum +{ CLUTTER_VERTEX_SHADER, CLUTTER_FRAGMENT_SHADER } ClutterShaderType; @@ -350,7 +340,8 @@ typedef enum { * * Since: 0.4 */ -typedef enum { +typedef enum +{ CLUTTER_SHIFT_MASK = 1 << 0, CLUTTER_LOCK_MASK = 1 << 1, CLUTTER_CONTROL_MASK = 1 << 2, @@ -416,7 +407,8 @@ typedef enum { * Keyboard accessibility features applied to a ClutterInputDevice keyboard. * */ -typedef enum { +typedef enum +{ CLUTTER_A11Y_KEYBOARD_ENABLED = 1 << 0, CLUTTER_A11Y_TIMEOUT_ENABLED = 1 << 1, CLUTTER_A11Y_MOUSE_KEYS_ENABLED = 1 << 2, @@ -433,6 +425,88 @@ typedef enum { CLUTTER_A11Y_FEATURE_STATE_CHANGE_BEEP = 1 << 13, } ClutterKeyboardA11yFlags; +/** + * ClutterPointerA11yFlags: + * @CLUTTER_A11Y_POINTER_ENABLED: + * @CLUTTER_A11Y_SECONDARY_CLICK_ENABLED: + * @CLUTTER_A11Y_DWELL_ENABLED: + * + * Pointer accessibility features applied to a ClutterInputDevice pointer. + * + */ +typedef enum { + CLUTTER_A11Y_SECONDARY_CLICK_ENABLED = 1 << 0, + CLUTTER_A11Y_DWELL_ENABLED = 1 << 1, +} ClutterPointerA11yFlags; + +/** + * ClutterPointerA11yDwellClickType: + * @CLUTTER_A11Y_DWELL_CLICK_TYPE_NONE: Internal use only + * @CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY: + * @CLUTTER_A11Y_DWELL_CLICK_TYPE_SECONDARY: + * @CLUTTER_A11Y_DWELL_CLICK_TYPE_MIDDLE: + * @CLUTTER_A11Y_DWELL_CLICK_TYPE_DOUBLE: + * @CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG: + * + * Dwell click types. + * + */ +typedef enum { + CLUTTER_A11Y_DWELL_CLICK_TYPE_NONE, + CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY, + CLUTTER_A11Y_DWELL_CLICK_TYPE_SECONDARY, + CLUTTER_A11Y_DWELL_CLICK_TYPE_MIDDLE, + CLUTTER_A11Y_DWELL_CLICK_TYPE_DOUBLE, + CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG, +} ClutterPointerA11yDwellClickType; + +/** + * ClutterPointerA11yDwellDirection: + * @CLUTTER_A11Y_DWELL_DIRECTION_NONE: + * @CLUTTER_A11Y_DWELL_DIRECTION_LEFT: + * @CLUTTER_A11Y_DWELL_DIRECTION_RIGHT: + * @CLUTTER_A11Y_DWELL_DIRECTION_UP: + * @CLUTTER_A11Y_DWELL_DIRECTION_DOWN: + * + * Dwell gesture directions. + * + */ +typedef enum { + CLUTTER_A11Y_DWELL_DIRECTION_NONE, + CLUTTER_A11Y_DWELL_DIRECTION_LEFT, + CLUTTER_A11Y_DWELL_DIRECTION_RIGHT, + CLUTTER_A11Y_DWELL_DIRECTION_UP, + CLUTTER_A11Y_DWELL_DIRECTION_DOWN, +} ClutterPointerA11yDwellDirection; + +/** + * ClutterPointerA11yDwellMode: + * @CLUTTER_A11Y_DWELL_MODE_WINDOW: + * @CLUTTER_A11Y_DWELL_MODE_GESTURE: + * + * Dwell mode. + * + */ +typedef enum { + CLUTTER_A11Y_DWELL_MODE_WINDOW, + CLUTTER_A11Y_DWELL_MODE_GESTURE, +} ClutterPointerA11yDwellMode; + +/** + * ClutterPointerA11yTimeoutType: + * @CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK: + * @CLUTTER_A11Y_TIMEOUT_TYPE_DWELL: + * @CLUTTER_A11Y_TIMEOUT_TYPE_GESTURE: + * + * Pointer accessibility timeout type. + * + */ +typedef enum { + CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK, + CLUTTER_A11Y_TIMEOUT_TYPE_DWELL, + CLUTTER_A11Y_TIMEOUT_TYPE_GESTURE, +} ClutterPointerA11yTimeoutType; + /** * ClutterActorFlags: * @CLUTTER_ACTOR_MAPPED: the actor will be painted (is visible, and inside @@ -448,7 +522,8 @@ typedef enum { * * Flags used to signal the state of an actor. */ -typedef enum { /*< prefix=CLUTTER_ACTOR >*/ +typedef enum /*< prefix=CLUTTER_ACTOR >*/ +{ CLUTTER_ACTOR_MAPPED = 1 << 1, CLUTTER_ACTOR_REALIZED = 1 << 2, CLUTTER_ACTOR_REACTIVE = 1 << 3, @@ -460,17 +535,23 @@ typedef enum { /*< prefix=CLUTTER_ACTOR >*/ * ClutterOffscreenRedirect: * @CLUTTER_OFFSCREEN_REDIRECT_AUTOMATIC_FOR_OPACITY: Only redirect * the actor if it is semi-transparent and its has_overlaps() - * virtual returns %TRUE. This is the default. + * virtual returns %TRUE. * @CLUTTER_OFFSCREEN_REDIRECT_ALWAYS: Always redirect the actor to an * offscreen buffer even if it is fully opaque. + * @CLUTTER_OFFSCREEN_REDIRECT_ON_IDLE: Only redirect the actor if it is the + * most efficient thing to do based on its recent repaint behaviour. That + * means when its contents are changing less frequently than it's being used + * on stage. * * Possible flags to pass to clutter_actor_set_offscreen_redirect(). * * Since: 1.8 */ -typedef enum { /*< prefix=CLUTTER_OFFSCREEN_REDIRECT >*/ - CLUTTER_OFFSCREEN_REDIRECT_AUTOMATIC_FOR_OPACITY = 1<<0, - CLUTTER_OFFSCREEN_REDIRECT_ALWAYS = 1<<1 +typedef enum /*< prefix=CLUTTER_OFFSCREEN_REDIRECT >*/ +{ + CLUTTER_OFFSCREEN_REDIRECT_AUTOMATIC_FOR_OPACITY = 1 << 0, + CLUTTER_OFFSCREEN_REDIRECT_ALWAYS = 1 << 1, + CLUTTER_OFFSCREEN_REDIRECT_ON_IDLE = 1 << 2 } ClutterOffscreenRedirect; /** @@ -492,7 +573,8 @@ typedef enum { /*< prefix=CLUTTER_OFFSCREEN_REDIRECT >*/ * * Since: 1.0 */ -typedef enum { +typedef enum +{ CLUTTER_ALLOCATION_NONE = 0, CLUTTER_ABSOLUTE_ORIGIN_CHANGED = 1 << 1, CLUTTER_DELEGATE_LAYOUT = 1 << 2 @@ -509,7 +591,8 @@ typedef enum { * * Since: 1.4 */ -typedef enum { /*< prefix=CLUTTER_ALIGN >*/ +typedef enum /*< prefix=CLUTTER_ALIGN >*/ +{ CLUTTER_ALIGN_X_AXIS, CLUTTER_ALIGN_Y_AXIS, CLUTTER_ALIGN_BOTH @@ -526,7 +609,8 @@ typedef enum { /*< prefix=CLUTTER_ALIGN >*/ * * Deprecated: 1.22 */ -typedef enum { +typedef enum +{ CLUTTER_INTERPOLATION_LINEAR, CLUTTER_INTERPOLATION_CUBIC } ClutterInterpolation; @@ -551,7 +635,8 @@ typedef enum { * Deprecated: 1.12: Use #ClutterActorAlign and the #ClutterActor * API instead */ -typedef enum { +typedef enum +{ CLUTTER_BIN_ALIGNMENT_FIXED, CLUTTER_BIN_ALIGNMENT_FILL, CLUTTER_BIN_ALIGNMENT_START, @@ -576,7 +661,8 @@ typedef enum { * * Since: 1.4 */ -typedef enum { /*< prefix=CLUTTER_BIND >*/ +typedef enum /*< prefix=CLUTTER_BIND >*/ +{ CLUTTER_BIND_X, CLUTTER_BIND_Y, CLUTTER_BIND_WIDTH, @@ -592,11 +678,15 @@ typedef enum { /*< prefix=CLUTTER_BIND >*/ * has queued a redraw before this paint. This implies that the effect * should call clutter_actor_continue_paint() to chain to the next * effect and can not cache any results from a previous paint. + * @CLUTTER_EFFECT_PAINT_BYPASS_EFFECT: The effect should not be used + * on this frame, but it will be asked to paint the actor still. * * Flags passed to the ‘paint’ or ‘pick’ method of #ClutterEffect. */ -typedef enum { /*< prefix=CLUTTER_EFFECT_PAINT >*/ - CLUTTER_EFFECT_PAINT_ACTOR_DIRTY = (1 << 0) +typedef enum /*< prefix=CLUTTER_EFFECT_PAINT >*/ +{ + CLUTTER_EFFECT_PAINT_ACTOR_DIRTY = (1 << 0), + CLUTTER_EFFECT_PAINT_BYPASS_EFFECT = (1 << 1) } ClutterEffectPaintFlags; /** @@ -611,7 +701,8 @@ typedef enum { /*< prefix=CLUTTER_EFFECT_PAINT >*/ * * Since: 1.2 */ -typedef enum { +typedef enum +{ CLUTTER_BOX_ALIGNMENT_START, CLUTTER_BOX_ALIGNMENT_END, CLUTTER_BOX_ALIGNMENT_CENTER @@ -628,7 +719,8 @@ typedef enum { * * Since: 1.8 */ -typedef enum { /*< prefix=CLUTTER_LONG_PRESS >*/ +typedef enum /*< prefix=CLUTTER_LONG_PRESS >*/ +{ CLUTTER_LONG_PRESS_QUERY, CLUTTER_LONG_PRESS_ACTIVATE, CLUTTER_LONG_PRESS_CANCEL @@ -686,7 +778,8 @@ typedef enum { /*< prefix=CLUTTER_LONG_PRESS >*/ * * Since: 1.6 */ -typedef enum { /*< prefix=CLUTTER_COLOR >*/ +typedef enum /*< prefix=CLUTTER_COLOR >*/ +{ /* CGA/EGA-like palette */ CLUTTER_COLOR_WHITE = 0, CLUTTER_COLOR_BLACK, @@ -750,7 +843,8 @@ typedef enum { /*< prefix=CLUTTER_COLOR >*/ * * Since: 1.4 */ -typedef enum { /*< prefix=CLUTTER_DRAG >*/ +typedef enum /*< prefix=CLUTTER_DRAG >*/ +{ CLUTTER_DRAG_AXIS_NONE = 0, CLUTTER_DRAG_X_AXIS, @@ -761,15 +855,18 @@ typedef enum { /*< prefix=CLUTTER_DRAG >*/ * ClutterEventFlags: * @CLUTTER_EVENT_NONE: No flag set * @CLUTTER_EVENT_FLAG_SYNTHETIC: Synthetic event + * @CLUTTER_EVENT_FLAG_REPEATED: Auto-repeated event * * Flags for the #ClutterEvent * * Since: 0.6 */ -typedef enum { /*< flags prefix=CLUTTER_EVENT >*/ +typedef enum /*< flags prefix=CLUTTER_EVENT >*/ +{ CLUTTER_EVENT_NONE = 0, CLUTTER_EVENT_FLAG_SYNTHETIC = 1 << 0, - CLUTTER_EVENT_FLAG_INPUT_METHOD = 1 << 1 + CLUTTER_EVENT_FLAG_INPUT_METHOD = 1 << 1, + CLUTTER_EVENT_FLAG_REPEATED = 1 << 2 } ClutterEventFlags; /** @@ -810,7 +907,8 @@ typedef enum { /*< flags prefix=CLUTTER_EVENT >*/ * * Since: 0.4 */ -typedef enum { /*< prefix=CLUTTER >*/ +typedef enum /*< prefix=CLUTTER >*/ +{ CLUTTER_NOTHING = 0, CLUTTER_KEY_PRESS, CLUTTER_KEY_RELEASE, @@ -836,6 +934,11 @@ typedef enum { /*< prefix=CLUTTER >*/ CLUTTER_PAD_BUTTON_RELEASE, CLUTTER_PAD_STRIP, CLUTTER_PAD_RING, + CLUTTER_IM_COMMIT, + CLUTTER_IM_DELETE, + CLUTTER_IM_PREEDIT, + CLUTTER_DEVICE_ADDED, + CLUTTER_DEVICE_REMOVED, CLUTTER_EVENT_LAST /* helper */ } ClutterEventType; @@ -855,7 +958,8 @@ typedef enum { /*< prefix=CLUTTER >*/ * * Since: 0.4 */ -typedef enum { /*< prefix=CLUTTER_SCROLL >*/ +typedef enum /*< prefix=CLUTTER_SCROLL >*/ +{ CLUTTER_SCROLL_UP, CLUTTER_SCROLL_DOWN, CLUTTER_SCROLL_LEFT, @@ -865,28 +969,21 @@ typedef enum { /*< prefix=CLUTTER_SCROLL >*/ /** * ClutterStageState: - * @CLUTTER_STAGE_STATE_FULLSCREEN: Fullscreen mask - * @CLUTTER_STAGE_STATE_OFFSCREEN: Offscreen mask (deprecated) * @CLUTTER_STAGE_STATE_ACTIVATED: Activated mask * * Stage state masks, used by the #ClutterEvent of type %CLUTTER_STAGE_STATE. * * Since: 0.4 */ -typedef enum { - CLUTTER_STAGE_STATE_FULLSCREEN = (1 << 1), - CLUTTER_STAGE_STATE_OFFSCREEN = (1 << 2), +typedef enum +{ CLUTTER_STAGE_STATE_ACTIVATED = (1 << 3) } ClutterStageState; /** * ClutterFeatureFlags: - * @CLUTTER_FEATURE_TEXTURE_NPOT: Set if NPOTS textures supported. - * @CLUTTER_FEATURE_SYNC_TO_VBLANK: Set if vblank syncing supported. - * @CLUTTER_FEATURE_TEXTURE_YUV: Set if YUV based textures supported. - * @CLUTTER_FEATURE_TEXTURE_READ_PIXELS: Set if texture pixels can be read. + * @CLUTTER_FEATURE_SWAP_THROTTLE: Set if backend throttles buffer swaps. * @CLUTTER_FEATURE_STAGE_STATIC: Set if stage size if fixed (i.e framebuffer) - * @CLUTTER_FEATURE_STAGE_USER_RESIZE: Set if stage is able to be user resized. * @CLUTTER_FEATURE_STAGE_CURSOR: Set if stage has a graphical cursor. * @CLUTTER_FEATURE_SHADERS_GLSL: Set if the backend supports GLSL shaders. * @CLUTTER_FEATURE_OFFSCREEN: Set if the backend supports offscreen rendering. @@ -900,12 +997,8 @@ typedef enum { */ typedef enum { - CLUTTER_FEATURE_TEXTURE_NPOT = (1 << 2), - CLUTTER_FEATURE_SYNC_TO_VBLANK = (1 << 3), - CLUTTER_FEATURE_TEXTURE_YUV = (1 << 4), - CLUTTER_FEATURE_TEXTURE_READ_PIXELS = (1 << 5), + CLUTTER_FEATURE_SWAP_THROTTLE = (1 << 3), CLUTTER_FEATURE_STAGE_STATIC = (1 << 6), - CLUTTER_FEATURE_STAGE_USER_RESIZE = (1 << 7), CLUTTER_FEATURE_STAGE_CURSOR = (1 << 8), CLUTTER_FEATURE_SHADERS_GLSL = (1 << 9), CLUTTER_FEATURE_OFFSCREEN = (1 << 10), @@ -925,7 +1018,8 @@ typedef enum * * Since: 1.2 */ -typedef enum { /*< prefix=CLUTTER_FLOW >*/ +typedef enum /*< prefix=CLUTTER_FLOW >*/ +{ CLUTTER_FLOW_HORIZONTAL, CLUTTER_FLOW_VERTICAL } ClutterFlowOrientation; @@ -952,7 +1046,8 @@ typedef enum { /*< prefix=CLUTTER_FLOW >*/ * * Since: 1.0 */ -typedef enum { +typedef enum +{ CLUTTER_POINTER_DEVICE, CLUTTER_KEYBOARD_DEVICE, CLUTTER_EXTENSION_DEVICE, @@ -980,7 +1075,8 @@ typedef enum { * * Since: 1.6 */ -typedef enum { +typedef enum +{ CLUTTER_INPUT_MODE_MASTER, CLUTTER_INPUT_MODE_SLAVE, CLUTTER_INPUT_MODE_FLOATING @@ -1005,7 +1101,8 @@ typedef enum { * * Since: 1.6 */ -typedef enum { +typedef enum +{ CLUTTER_INPUT_AXIS_IGNORE, CLUTTER_INPUT_AXIS_X, @@ -1032,7 +1129,8 @@ typedef enum { * * Since: 1.6 */ -typedef enum { +typedef enum +{ CLUTTER_SNAP_EDGE_TOP, CLUTTER_SNAP_EDGE_RIGHT, CLUTTER_SNAP_EDGE_BOTTOM, @@ -1049,7 +1147,8 @@ typedef enum { * * Since: 1.0 */ -typedef enum { +typedef enum +{ CLUTTER_PICK_NONE = 0, CLUTTER_PICK_REACTIVE, CLUTTER_PICK_ALL @@ -1066,7 +1165,8 @@ typedef enum { * * Since: 1.8 */ -typedef enum { /*< prefix=CLUTTER_SWIPE_DIRECTION >*/ +typedef enum /*< prefix=CLUTTER_SWIPE_DIRECTION >*/ +{ CLUTTER_SWIPE_DIRECTION_UP = 1 << 0, CLUTTER_SWIPE_DIRECTION_DOWN = 1 << 1, CLUTTER_SWIPE_DIRECTION_LEFT = 1 << 2, @@ -1086,7 +1186,8 @@ typedef enum { /*< prefix=CLUTTER_SWIPE_DIRECTION >*/ * * Since: 1.12 */ -typedef enum { /*< prefix=CLUTTER_PAN >*/ +typedef enum /*< prefix=CLUTTER_PAN >*/ +{ CLUTTER_PAN_AXIS_NONE = 0, CLUTTER_PAN_X_AXIS, @@ -1095,28 +1196,6 @@ typedef enum { /*< prefix=CLUTTER_PAN >*/ CLUTTER_PAN_AXIS_AUTO } ClutterPanAxis; - -/** - * ClutterTableAlignment: - * @CLUTTER_TABLE_ALIGNMENT_START: Align the child to the top or to the - * left of a cell in the table, depending on the axis - * @CLUTTER_TABLE_ALIGNMENT_CENTER: Align the child to the center of - * a cell in the table - * @CLUTTER_TABLE_ALIGNMENT_END: Align the child to the bottom or to the - * right of a cell in the table, depending on the axis - * - * The alignment policies available on each axis of the #ClutterTableLayout - * - * Since: 1.4 - * - * Deprecated: 1.22: Use the alignment properties of #ClutterActor - */ -typedef enum { - CLUTTER_TABLE_ALIGNMENT_START, - CLUTTER_TABLE_ALIGNMENT_CENTER, - CLUTTER_TABLE_ALIGNMENT_END -} ClutterTableAlignment; - /** * ClutterTextureFlags: * @CLUTTER_TEXTURE_NONE: No flags @@ -1124,15 +1203,15 @@ typedef enum { * @CLUTTER_TEXTURE_RGB_FLAG_PREMULT: Unused flag * @CLUTTER_TEXTURE_YUV_FLAG_YUV2: Unused flag * - * Flags for clutter_texture_set_from_rgb_data() and - * clutter_texture_set_from_yuv_data(). + * Flags for clutter_texture_set_from_rgb_data(). * * Since: 0.4 * * Deprecated: 1.22: The #ClutterTexture class was the only user of * this API */ -typedef enum { /*< prefix=CLUTTER_TEXTURE >*/ +typedef enum /*< prefix=CLUTTER_TEXTURE >*/ +{ CLUTTER_TEXTURE_NONE = 0, CLUTTER_TEXTURE_RGB_FLAG_BGR = 1 << 1, CLUTTER_TEXTURE_RGB_FLAG_PREMULT = 1 << 2, /* FIXME: not handled */ @@ -1156,7 +1235,8 @@ typedef enum { /*< prefix=CLUTTER_TEXTURE >*/ * this API; use #ClutterImage and clutter_actor_set_content_scaling_filters() * instead. */ -typedef enum { /*< prefix=CLUTTER_TEXTURE_QUALITY >*/ +typedef enum /*< prefix=CLUTTER_TEXTURE_QUALITY >*/ +{ CLUTTER_TEXTURE_QUALITY_LOW, CLUTTER_TEXTURE_QUALITY_MEDIUM, CLUTTER_TEXTURE_QUALITY_HIGH @@ -1171,7 +1251,8 @@ typedef enum { /*< prefix=CLUTTER_TEXTURE_QUALITY >*/ * * Since: 0.6 */ -typedef enum { +typedef enum +{ CLUTTER_TIMELINE_FORWARD, CLUTTER_TIMELINE_BACKWARD } ClutterTimelineDirection; @@ -1190,7 +1271,8 @@ typedef enum { * * Since: 1.0 */ -typedef enum { /*< prefix=CLUTTER_UNIT >*/ +typedef enum /*< prefix=CLUTTER_UNIT >*/ +{ CLUTTER_UNIT_PIXEL, CLUTTER_UNIT_EM, CLUTTER_UNIT_MM, @@ -1220,7 +1302,8 @@ typedef enum { /*< prefix=CLUTTER_UNIT >*/ * * Since: 1.0 */ -typedef enum { +typedef enum +{ CLUTTER_PATH_MOVE_TO = 0, CLUTTER_PATH_LINE_TO = 1, CLUTTER_PATH_CURVE_TO = 2, @@ -1251,7 +1334,8 @@ typedef enum { * * Since: 1.10 */ -typedef enum { +typedef enum +{ CLUTTER_ACTOR_ALIGN_FILL, CLUTTER_ACTOR_ALIGN_START, CLUTTER_ACTOR_ALIGN_CENTER, @@ -1271,7 +1355,8 @@ typedef enum { * * Since: 1.10 */ -typedef enum { +typedef enum +{ CLUTTER_REPAINT_FLAGS_PRE_PAINT = 1 << 0, CLUTTER_REPAINT_FLAGS_POST_PAINT = 1 << 1, CLUTTER_REPAINT_FLAGS_QUEUE_REDRAW_ON_ADD = 1 << 2 @@ -1296,7 +1381,8 @@ typedef enum { * * Since: 1.10 */ -typedef enum { +typedef enum +{ CLUTTER_CONTENT_GRAVITY_TOP_LEFT, CLUTTER_CONTENT_GRAVITY_TOP, CLUTTER_CONTENT_GRAVITY_TOP_RIGHT, @@ -1326,7 +1412,8 @@ typedef enum { * * Since: 1.10 */ -typedef enum { +typedef enum +{ CLUTTER_SCALING_FILTER_LINEAR, CLUTTER_SCALING_FILTER_NEAREST, CLUTTER_SCALING_FILTER_TRILINEAR @@ -1341,7 +1428,8 @@ typedef enum { * * Since: 1.12 */ -typedef enum { +typedef enum +{ CLUTTER_ORIENTATION_HORIZONTAL, CLUTTER_ORIENTATION_VERTICAL } ClutterOrientation; @@ -1357,7 +1445,8 @@ typedef enum { * * Since: 1.12 */ -typedef enum { /*< prefix=CLUTTER_SCROLL >*/ +typedef enum /*< prefix=CLUTTER_SCROLL >*/ +{ CLUTTER_SCROLL_NONE = 0, CLUTTER_SCROLL_HORIZONTALLY = 1 << 0, @@ -1377,7 +1466,8 @@ typedef enum { /*< prefix=CLUTTER_SCROLL >*/ * * Since: 1.12 */ -typedef enum { +typedef enum +{ CLUTTER_GRID_POSITION_LEFT, CLUTTER_GRID_POSITION_RIGHT, CLUTTER_GRID_POSITION_TOP, @@ -1395,7 +1485,8 @@ typedef enum { * * Since: 1.12 */ -typedef enum { +typedef enum +{ CLUTTER_REPEAT_NONE = 0, CLUTTER_REPEAT_X_AXIS = 1 << 0, CLUTTER_REPEAT_Y_AXIS = 1 << 1, @@ -1417,7 +1508,8 @@ typedef enum { * * Since: 1.12 */ -typedef enum { +typedef enum +{ CLUTTER_STEP_MODE_START, CLUTTER_STEP_MODE_END } ClutterStepMode; @@ -1433,7 +1525,8 @@ typedef enum { * * Since: 1.12 */ -typedef enum { /*< prefix=CLUTTER_ZOOM >*/ +typedef enum /*< prefix=CLUTTER_ZOOM >*/ +{ CLUTTER_ZOOM_X_AXIS, CLUTTER_ZOOM_Y_AXIS, CLUTTER_ZOOM_BOTH @@ -1456,7 +1549,8 @@ typedef enum { /*< prefix=CLUTTER_ZOOM >*/ * * Since: 1.18 */ -typedef enum { +typedef enum +{ CLUTTER_GESTURE_TRIGGER_EDGE_NONE = 0, CLUTTER_GESTURE_TRIGGER_EDGE_AFTER, CLUTTER_GESTURE_TRIGGER_EDGE_BEFORE @@ -1492,7 +1586,8 @@ typedef enum { * * Since: 1.24 */ -typedef enum { +typedef enum +{ CLUTTER_TOUCHPAD_GESTURE_PHASE_BEGIN, CLUTTER_TOUCHPAD_GESTURE_PHASE_UPDATE, CLUTTER_TOUCHPAD_GESTURE_PHASE_END, @@ -1514,7 +1609,8 @@ typedef enum { * * Since: 1.26 */ -typedef enum { +typedef enum +{ CLUTTER_SCROLL_SOURCE_UNKNOWN, CLUTTER_SCROLL_SOURCE_WHEEL, CLUTTER_SCROLL_SOURCE_FINGER, @@ -1532,7 +1628,8 @@ typedef enum { * * Since: 1.26 */ -typedef enum { +typedef enum +{ CLUTTER_SCROLL_FINISHED_NONE = 0, CLUTTER_SCROLL_FINISHED_HORIZONTAL = 1 << 0, CLUTTER_SCROLL_FINISHED_VERTICAL = 1 << 1 @@ -1553,7 +1650,8 @@ typedef enum { * * Since: 1.28 */ -typedef enum { +typedef enum +{ CLUTTER_INPUT_DEVICE_TOOL_NONE, CLUTTER_INPUT_DEVICE_TOOL_PEN, CLUTTER_INPUT_DEVICE_TOOL_ERASER, @@ -1564,17 +1662,20 @@ typedef enum { CLUTTER_INPUT_DEVICE_TOOL_LENS } ClutterInputDeviceToolType; -typedef enum { +typedef enum +{ CLUTTER_INPUT_DEVICE_PAD_SOURCE_UNKNOWN, CLUTTER_INPUT_DEVICE_PAD_SOURCE_FINGER, } ClutterInputDevicePadSource; -typedef enum { +typedef enum +{ CLUTTER_INPUT_DEVICE_MAPPING_ABSOLUTE, CLUTTER_INPUT_DEVICE_MAPPING_RELATIVE, } ClutterInputDeviceMapping; -typedef enum { +typedef enum +{ CLUTTER_INPUT_CONTENT_HINT_COMPLETION = 1 << 0, CLUTTER_INPUT_CONTENT_HINT_SPELLCHECK = 1 << 1, CLUTTER_INPUT_CONTENT_HINT_AUTO_CAPITALIZATION = 1 << 2, @@ -1587,7 +1688,8 @@ typedef enum { CLUTTER_INPUT_CONTENT_HINT_MULTILINE = 1 << 9, } ClutterInputContentHintFlags; -typedef enum { +typedef enum +{ CLUTTER_INPUT_CONTENT_PURPOSE_NORMAL, CLUTTER_INPUT_CONTENT_PURPOSE_ALPHA, CLUTTER_INPUT_CONTENT_PURPOSE_DIGITS, @@ -1603,7 +1705,8 @@ typedef enum { CLUTTER_INPUT_CONTENT_PURPOSE_TERMINAL, } ClutterInputContentPurpose; -typedef enum { +typedef enum +{ CLUTTER_INPUT_PANEL_STATE_OFF, CLUTTER_INPUT_PANEL_STATE_ON, CLUTTER_INPUT_PANEL_STATE_TOGGLE, diff --git a/clutter/clutter/clutter-event-private.h b/clutter/clutter/clutter-event-private.h index 00d627d12..668be6ef9 100644 --- a/clutter/clutter/clutter-event-private.h +++ b/clutter/clutter/clutter-event-private.h @@ -5,22 +5,28 @@ G_BEGIN_DECLS +CLUTTER_EXPORT void _clutter_event_set_pointer_emulated (ClutterEvent *event, gboolean is_emulated); /* Reinjecting queued events for processing */ +CLUTTER_EXPORT void _clutter_process_event (ClutterEvent *event); +CLUTTER_EXPORT gboolean _clutter_event_process_filters (ClutterEvent *event); /* clears the event queue inside the main context */ void _clutter_clear_events_queue (void); void _clutter_clear_events_queue_for_stage (ClutterStage *stage); +CLUTTER_EXPORT void _clutter_event_set_platform_data (ClutterEvent *event, gpointer data); +CLUTTER_EXPORT gpointer _clutter_event_get_platform_data (const ClutterEvent *event); +CLUTTER_EXPORT void _clutter_event_set_state_full (ClutterEvent *event, ClutterModifierType button_state, ClutterModifierType base_state, @@ -28,6 +34,7 @@ void _clutter_event_set_state_full (ClutterEvent *ev ClutterModifierType locked_state, ClutterModifierType effective_state); +CLUTTER_EXPORT void _clutter_event_push (const ClutterEvent *event, gboolean do_copy); diff --git a/clutter/clutter/clutter-event-translator.c b/clutter/clutter/clutter-event-translator.c deleted file mode 100644 index b98957d80..000000000 --- a/clutter/clutter/clutter-event-translator.c +++ /dev/null @@ -1,38 +0,0 @@ -#include "clutter-build-config.h" - -#include "clutter-event-translator.h" - -#include "clutter-backend.h" -#include "clutter-private.h" - -#define clutter_event_translator_get_type _clutter_event_translator_get_type - -typedef ClutterEventTranslatorIface ClutterEventTranslatorInterface; - -G_DEFINE_INTERFACE (ClutterEventTranslator, clutter_event_translator, G_TYPE_OBJECT); - -static ClutterTranslateReturn -default_translate_event (ClutterEventTranslator *translator, - gpointer native, - ClutterEvent *event) -{ - return CLUTTER_TRANSLATE_CONTINUE; -} - -static void -clutter_event_translator_default_init (ClutterEventTranslatorIface *iface) -{ - iface->translate_event = default_translate_event; -} - -ClutterTranslateReturn -_clutter_event_translator_translate_event (ClutterEventTranslator *translator, - gpointer native, - ClutterEvent *translated) -{ - ClutterEventTranslatorIface *iface; - - iface = CLUTTER_EVENT_TRANSLATOR_GET_IFACE (translator); - - return iface->translate_event (translator, native, translated); -} diff --git a/clutter/clutter/clutter-event-translator.h b/clutter/clutter/clutter-event-translator.h deleted file mode 100644 index 98a6cf3df..000000000 --- a/clutter/clutter/clutter-event-translator.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef __CLUTTER_EVENT_TRANSLATOR_H__ -#define __CLUTTER_EVENT_TRANSLATOR_H__ - -#include -#include - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_EVENT_TRANSLATOR (_clutter_event_translator_get_type ()) -#define CLUTTER_EVENT_TRANSLATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_EVENT_TRANSLATOR, ClutterEventTranslator)) -#define CLUTTER_IS_EVENT_TRANSLATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_EVENT_TRANSLATOR)) -#define CLUTTER_EVENT_TRANSLATOR_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), CLUTTER_TYPE_EVENT_TRANSLATOR, ClutterEventTranslatorIface)) - -typedef struct _ClutterEventTranslator ClutterEventTranslator; -typedef struct _ClutterEventTranslatorIface ClutterEventTranslatorIface; - -typedef enum { - CLUTTER_TRANSLATE_CONTINUE, - CLUTTER_TRANSLATE_REMOVE, - CLUTTER_TRANSLATE_QUEUE -} ClutterTranslateReturn; - -struct _ClutterEventTranslatorIface -{ - GTypeInterface g_iface; - - ClutterTranslateReturn (* translate_event) (ClutterEventTranslator *translator, - gpointer native, - ClutterEvent *translated); -}; - -CLUTTER_AVAILABLE_IN_MUFFIN -GType _clutter_event_translator_get_type (void) G_GNUC_CONST; - -ClutterTranslateReturn _clutter_event_translator_translate_event (ClutterEventTranslator *translator, - gpointer native, - ClutterEvent *translated); - -G_END_DECLS - -#endif /* __CLUTTER_EVENT_TRANSLATOR_H__ */ diff --git a/clutter/clutter/clutter-event.c b/clutter/clutter/clutter-event.c index 84995b127..7586a59c5 100644 --- a/clutter/clutter/clutter-event.c +++ b/clutter/clutter/clutter-event.c @@ -23,9 +23,7 @@ * */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include "clutter-backend-private.h" #include "clutter-debug.h" @@ -372,7 +370,7 @@ clutter_event_get_coords (const ClutterEvent *event, gfloat *x, gfloat *y) { - ClutterPoint coords; + graphene_point_t coords; g_return_if_fail (event != NULL); @@ -388,15 +386,15 @@ clutter_event_get_coords (const ClutterEvent *event, /** * clutter_event_get_position: * @event: a #ClutterEvent - * @position: a #ClutterPoint + * @position: a #graphene_point_t * - * Retrieves the event coordinates as a #ClutterPoint. + * Retrieves the event coordinates as a #graphene_point_t. * * Since: 1.12 */ void clutter_event_get_position (const ClutterEvent *event, - ClutterPoint *position) + graphene_point_t *position) { g_return_if_fail (event != NULL); g_return_if_fail (position != NULL); @@ -417,42 +415,47 @@ clutter_event_get_position (const ClutterEvent *event, case CLUTTER_PAD_BUTTON_RELEASE: case CLUTTER_PAD_STRIP: case CLUTTER_PAD_RING: - clutter_point_init (position, 0.f, 0.f); + case CLUTTER_IM_COMMIT: + case CLUTTER_IM_DELETE: + case CLUTTER_IM_PREEDIT: + case CLUTTER_DEVICE_ADDED: + case CLUTTER_DEVICE_REMOVED: + graphene_point_init (position, 0.f, 0.f); break; case CLUTTER_ENTER: case CLUTTER_LEAVE: - clutter_point_init (position, event->crossing.x, event->crossing.y); + graphene_point_init (position, event->crossing.x, event->crossing.y); break; case CLUTTER_BUTTON_PRESS: case CLUTTER_BUTTON_RELEASE: - clutter_point_init (position, event->button.x, event->button.y); + graphene_point_init (position, event->button.x, event->button.y); break; case CLUTTER_MOTION: - clutter_point_init (position, event->motion.x, event->motion.y); + graphene_point_init (position, event->motion.x, event->motion.y); break; case CLUTTER_TOUCH_BEGIN: case CLUTTER_TOUCH_UPDATE: case CLUTTER_TOUCH_END: case CLUTTER_TOUCH_CANCEL: - clutter_point_init (position, event->touch.x, event->touch.y); + graphene_point_init (position, event->touch.x, event->touch.y); break; case CLUTTER_SCROLL: - clutter_point_init (position, event->scroll.x, event->scroll.y); + graphene_point_init (position, event->scroll.x, event->scroll.y); break; case CLUTTER_TOUCHPAD_PINCH: - clutter_point_init (position, event->touchpad_pinch.x, - event->touchpad_pinch.y); + graphene_point_init (position, event->touchpad_pinch.x, + event->touchpad_pinch.y); break; case CLUTTER_TOUCHPAD_SWIPE: - clutter_point_init (position, event->touchpad_swipe.x, - event->touchpad_swipe.y); + graphene_point_init (position, event->touchpad_swipe.x, + event->touchpad_swipe.y); break; } @@ -491,6 +494,11 @@ clutter_event_set_coords (ClutterEvent *event, case CLUTTER_PAD_BUTTON_RELEASE: case CLUTTER_PAD_STRIP: case CLUTTER_PAD_RING: + case CLUTTER_IM_COMMIT: + case CLUTTER_IM_DELETE: + case CLUTTER_IM_PREEDIT: + case CLUTTER_DEVICE_ADDED: + case CLUTTER_DEVICE_REMOVED: break; case CLUTTER_ENTER: @@ -1023,13 +1031,16 @@ clutter_event_get_event_sequence (const ClutterEvent *event) event->type == CLUTTER_TOUCH_END || event->type == CLUTTER_TOUCH_CANCEL) return event->touch.sequence; + else if (event->type == CLUTTER_ENTER || + event->type == CLUTTER_LEAVE) + return event->crossing.sequence; return NULL; } /** * clutter_event_get_device_id: - * @event: a clutter event + * @event: a clutter event * * Retrieves the events device id if set. * @@ -1095,7 +1106,7 @@ clutter_event_set_device (ClutterEvent *event, { ClutterEventPrivate *real_event = (ClutterEventPrivate *) event; - real_event->device = device; + g_set_object (&real_event->device, device); } switch (event->type) @@ -1106,6 +1117,9 @@ clutter_event_set_device (ClutterEvent *event, case CLUTTER_CLIENT_MESSAGE: case CLUTTER_DELETE: case CLUTTER_EVENT_LAST: + case CLUTTER_IM_COMMIT: + case CLUTTER_IM_DELETE: + case CLUTTER_IM_PREEDIT: break; case CLUTTER_ENTER: @@ -1160,6 +1174,11 @@ clutter_event_set_device (ClutterEvent *event, case CLUTTER_PAD_RING: event->pad_ring.device = device; break; + + case CLUTTER_DEVICE_ADDED: + case CLUTTER_DEVICE_REMOVED: + event->device.device = device; + break; } } @@ -1202,6 +1221,9 @@ clutter_event_get_device (const ClutterEvent *event) case CLUTTER_DESTROY_NOTIFY: case CLUTTER_CLIENT_MESSAGE: case CLUTTER_DELETE: + case CLUTTER_IM_COMMIT: + case CLUTTER_IM_DELETE: + case CLUTTER_IM_PREEDIT: case CLUTTER_EVENT_LAST: break; @@ -1257,6 +1279,11 @@ clutter_event_get_device (const ClutterEvent *event) case CLUTTER_PAD_RING: device = event->pad_ring.device; break; + + case CLUTTER_DEVICE_ADDED: + case CLUTTER_DEVICE_REMOVED: + device = event->device.device; + break; } return device; @@ -1364,8 +1391,8 @@ clutter_event_copy (const ClutterEvent *event) { ClutterEventPrivate *real_event = (ClutterEventPrivate *) event; - new_real_event->device = real_event->device; - new_real_event->source_device = real_event->source_device; + g_set_object (&new_real_event->device, real_event->device); + g_set_object (&new_real_event->source_device, real_event->source_device); new_real_event->delta_x = real_event->delta_x; new_real_event->delta_y = real_event->delta_y; new_real_event->is_pointer_emulated = real_event->is_pointer_emulated; @@ -1410,6 +1437,16 @@ clutter_event_copy (const ClutterEvent *event) sizeof (gdouble) * n_axes); break; + case CLUTTER_IM_COMMIT: + case CLUTTER_IM_PREEDIT: + new_event->im.text = g_strdup (event->im.text); + break; + + case CLUTTER_DEVICE_ADDED: + case CLUTTER_DEVICE_REMOVED: + new_event->device.device = event->device.device; + break; + default: break; } @@ -1435,26 +1472,39 @@ clutter_event_free (ClutterEvent *event) { _clutter_backend_free_event_data (clutter_get_default_backend (), event); + if (is_event_allocated (event)) + { + ClutterEventPrivate *real_event = (ClutterEventPrivate *) event; + + g_clear_object (&real_event->device); + g_clear_object (&real_event->source_device); + } + switch (event->type) { case CLUTTER_BUTTON_PRESS: case CLUTTER_BUTTON_RELEASE: - free (event->button.axes); + g_free (event->button.axes); break; case CLUTTER_MOTION: - free (event->motion.axes); + g_free (event->motion.axes); break; case CLUTTER_SCROLL: - free (event->scroll.axes); + g_free (event->scroll.axes); break; case CLUTTER_TOUCH_BEGIN: case CLUTTER_TOUCH_UPDATE: case CLUTTER_TOUCH_END: case CLUTTER_TOUCH_CANCEL: - free (event->touch.axes); + g_free (event->touch.axes); + break; + + case CLUTTER_IM_COMMIT: + case CLUTTER_IM_PREEDIT: + g_free (event->im.text); break; default: @@ -1469,7 +1519,7 @@ clutter_event_free (ClutterEvent *event) /** * clutter_event_get: * - * Pops an event off the event queue. Applications should not need to call + * Pops an event off the event queue. Applications should not need to call * this. * * Return value: A #ClutterEvent or NULL if queue empty @@ -1492,9 +1542,9 @@ clutter_event_get (void) /** * clutter_event_peek: - * - * Returns a pointer to the first event from the event queue but - * does not remove it. + * + * Returns a pointer to the first event from the event queue but + * does not remove it. * * Return value: (transfer none): A #ClutterEvent or NULL if queue empty. * @@ -1506,7 +1556,7 @@ clutter_event_peek (void) ClutterMainContext *context = _clutter_context_get_default (); g_return_val_if_fail (context != NULL, NULL); - + if (context->events_queue == NULL) return NULL; @@ -1532,7 +1582,9 @@ _clutter_event_push (const ClutterEvent *event, device = clutter_event_get_device (event); if (device != NULL) { - if (!clutter_input_device_get_enabled (device)) + if (event->type != CLUTTER_DEVICE_ADDED && + event->type != CLUTTER_DEVICE_REMOVED && + !clutter_input_device_get_enabled (device)) return; } @@ -1689,7 +1741,7 @@ clutter_event_set_source_device (ClutterEvent *event, return; real_event = (ClutterEventPrivate *) event; - real_event->source_device = device; + g_set_object (&real_event->source_device, device); } /** @@ -1724,6 +1776,8 @@ clutter_event_get_axes (const ClutterEvent *event, case CLUTTER_EVENT_LAST: case CLUTTER_PROXIMITY_IN: case CLUTTER_PROXIMITY_OUT: + case CLUTTER_DEVICE_ADDED: + case CLUTTER_DEVICE_REMOVED: break; case CLUTTER_SCROLL: @@ -1752,6 +1806,9 @@ clutter_event_get_axes (const ClutterEvent *event, case CLUTTER_PAD_BUTTON_RELEASE: case CLUTTER_PAD_STRIP: case CLUTTER_PAD_RING: + case CLUTTER_IM_COMMIT: + case CLUTTER_IM_DELETE: + case CLUTTER_IM_PREEDIT: break; } @@ -1787,12 +1844,12 @@ float clutter_event_get_distance (const ClutterEvent *source, const ClutterEvent *target) { - ClutterPoint p0, p1; + graphene_point_t p0, p1; clutter_event_get_position (source, &p0); clutter_event_get_position (source, &p1); - return clutter_point_distance (&p0, &p1, NULL, NULL); + return graphene_point_distance (&p0, &p1, NULL, NULL); } /** @@ -1813,17 +1870,17 @@ double clutter_event_get_angle (const ClutterEvent *source, const ClutterEvent *target) { - ClutterPoint p0, p1; + graphene_point_t p0, p1; float x_distance, y_distance; double angle; clutter_event_get_position (source, &p0); clutter_event_get_position (target, &p1); - if (clutter_point_equals (&p0, &p1)) + if (graphene_point_equal (&p0, &p1)) return 0; - clutter_point_distance (&p0, &p1, &x_distance, &y_distance); + graphene_point_distance (&p0, &p1, &x_distance, &y_distance); angle = atan2 (x_distance, y_distance); @@ -2152,9 +2209,9 @@ clutter_event_get_scroll_source (const ClutterEvent *event) ClutterScrollFinishFlags clutter_event_get_scroll_finish_flags (const ClutterEvent *event) { - g_return_val_if_fail (event != NULL, CLUTTER_SCROLL_SOURCE_UNKNOWN); + g_return_val_if_fail (event != NULL, CLUTTER_SCROLL_FINISHED_NONE); g_return_val_if_fail (event->type == CLUTTER_SCROLL, - CLUTTER_SCROLL_SOURCE_UNKNOWN); + CLUTTER_SCROLL_FINISHED_NONE); return event->scroll.finish_flags; } diff --git a/clutter/clutter/clutter-event.h b/clutter/clutter/clutter-event.h index 035fe43cd..7afdb4a6d 100644 --- a/clutter/clutter/clutter-event.h +++ b/clutter/clutter/clutter-event.h @@ -121,6 +121,8 @@ typedef struct _ClutterProximityEvent ClutterProximityEvent; typedef struct _ClutterPadButtonEvent ClutterPadButtonEvent; typedef struct _ClutterPadStripEvent ClutterPadStripEvent; typedef struct _ClutterPadRingEvent ClutterPadRingEvent; +typedef struct _ClutterIMEvent ClutterIMEvent; +typedef struct _ClutterDeviceEvent ClutterDeviceEvent; /** * ClutterAnyEvent: @@ -269,6 +271,7 @@ struct _ClutterCrossingEvent gfloat x; gfloat y; ClutterInputDevice *device; + ClutterEventSequence *sequence; ClutterActor *related; }; @@ -383,7 +386,7 @@ struct _ClutterStageStateEvent * @modifier_state: (type ClutterModifierType): a bit-mask representing the state * of modifier keys (e.g. Control, Shift, and Alt) and the pointer * buttons. See #ClutterModifierType - * @axes: reserved + * @axes: reserved * @device: the device that originated the event. If you want the physical * device the event originated from, use clutter_event_get_source_device() * @@ -543,6 +546,30 @@ struct _ClutterPadRingEvent guint32 mode; }; +struct _ClutterIMEvent +{ + ClutterEventType type; + guint32 time; + ClutterEventFlags flags; + ClutterStage *stage; + ClutterActor *source; + + char *text; + int32_t offset; + uint32_t len; +}; + +struct _ClutterDeviceEvent +{ + ClutterEventType type; + guint32 time; + ClutterEventFlags flags; + ClutterStage *stage; + ClutterActor *source; + + ClutterInputDevice *device; +}; + /** * ClutterEvent: * @@ -569,6 +596,8 @@ union _ClutterEvent ClutterPadButtonEvent pad_button; ClutterPadStripEvent pad_strip; ClutterPadRingEvent pad_ring; + ClutterIMEvent im; + ClutterDeviceEvent device; }; /** @@ -589,196 +618,199 @@ union _ClutterEvent typedef gboolean (* ClutterEventFilterFunc) (const ClutterEvent *event, gpointer user_data); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT GType clutter_event_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_20 +CLUTTER_EXPORT GType clutter_event_sequence_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gboolean clutter_events_pending (void); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterEvent * clutter_event_get (void); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterEvent * clutter_event_peek (void); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_event_put (const ClutterEvent *event); -CLUTTER_AVAILABLE_IN_1_18 +CLUTTER_EXPORT guint clutter_event_add_filter (ClutterStage *stage, ClutterEventFilterFunc func, GDestroyNotify notify, gpointer user_data); -CLUTTER_AVAILABLE_IN_1_18 +CLUTTER_EXPORT void clutter_event_remove_filter (guint id); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterEvent * clutter_event_new (ClutterEventType type); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterEvent * clutter_event_copy (const ClutterEvent *event); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_event_free (ClutterEvent *event); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterEventType clutter_event_type (const ClutterEvent *event); -CLUTTER_AVAILABLE_IN_1_8 +CLUTTER_EXPORT void clutter_event_set_flags (ClutterEvent *event, ClutterEventFlags flags); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT ClutterEventFlags clutter_event_get_flags (const ClutterEvent *event); -CLUTTER_AVAILABLE_IN_1_8 +CLUTTER_EXPORT void clutter_event_set_time (ClutterEvent *event, guint32 time_); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT guint32 clutter_event_get_time (const ClutterEvent *event); -CLUTTER_AVAILABLE_IN_1_8 +CLUTTER_EXPORT void clutter_event_set_state (ClutterEvent *event, ClutterModifierType state); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterModifierType clutter_event_get_state (const ClutterEvent *event); -CLUTTER_AVAILABLE_IN_1_16 +CLUTTER_EXPORT void clutter_event_get_state_full (const ClutterEvent *event, ClutterModifierType *button_state, ClutterModifierType *base_state, ClutterModifierType *latched_state, ClutterModifierType *locked_state, ClutterModifierType *effective_state); -CLUTTER_AVAILABLE_IN_1_6 +CLUTTER_EXPORT void clutter_event_set_device (ClutterEvent *event, ClutterInputDevice *device); -CLUTTER_AVAILABLE_IN_1_6 +CLUTTER_EXPORT ClutterInputDevice * clutter_event_get_device (const ClutterEvent *event); -CLUTTER_AVAILABLE_IN_1_6 +CLUTTER_EXPORT void clutter_event_set_source_device (ClutterEvent *event, ClutterInputDevice *device); -CLUTTER_AVAILABLE_IN_1_6 +CLUTTER_EXPORT ClutterInputDevice * clutter_event_get_source_device (const ClutterEvent *event); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_event_set_device_tool (ClutterEvent *event, ClutterInputDeviceTool *tool); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterInputDeviceTool *clutter_event_get_device_tool (const ClutterEvent *event); -CLUTTER_AVAILABLE_IN_1_8 +CLUTTER_EXPORT void clutter_event_set_source (ClutterEvent *event, ClutterActor *actor); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterActor * clutter_event_get_source (const ClutterEvent *event); -CLUTTER_AVAILABLE_IN_1_8 +CLUTTER_EXPORT void clutter_event_set_stage (ClutterEvent *event, ClutterStage *stage); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterStage * clutter_event_get_stage (const ClutterEvent *event); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gint clutter_event_get_device_id (const ClutterEvent *event); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT ClutterInputDeviceType clutter_event_get_device_type (const ClutterEvent *event); -CLUTTER_AVAILABLE_IN_1_8 +CLUTTER_EXPORT void clutter_event_set_coords (ClutterEvent *event, gfloat x, gfloat y); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_event_get_coords (const ClutterEvent *event, gfloat *x, gfloat *y); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_event_get_position (const ClutterEvent *event, - ClutterPoint *position); -CLUTTER_AVAILABLE_IN_1_12 + graphene_point_t *position); +CLUTTER_EXPORT float clutter_event_get_distance (const ClutterEvent *source, const ClutterEvent *target); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT double clutter_event_get_angle (const ClutterEvent *source, const ClutterEvent *target); -CLUTTER_AVAILABLE_IN_1_6 +CLUTTER_EXPORT gdouble * clutter_event_get_axes (const ClutterEvent *event, guint *n_axes); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT gboolean clutter_event_has_shift_modifier (const ClutterEvent *event); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT gboolean clutter_event_has_control_modifier (const ClutterEvent *event); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT gboolean clutter_event_is_pointer_emulated (const ClutterEvent *event); -CLUTTER_AVAILABLE_IN_1_8 +CLUTTER_EXPORT void clutter_event_set_key_symbol (ClutterEvent *event, guint key_sym); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT guint clutter_event_get_key_symbol (const ClutterEvent *event); -CLUTTER_AVAILABLE_IN_1_8 +CLUTTER_EXPORT void clutter_event_set_key_code (ClutterEvent *event, guint16 key_code); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT guint16 clutter_event_get_key_code (const ClutterEvent *event); -CLUTTER_AVAILABLE_IN_1_8 +CLUTTER_EXPORT void clutter_event_set_key_unicode (ClutterEvent *event, gunichar key_unicode); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT gunichar clutter_event_get_key_unicode (const ClutterEvent *event); -CLUTTER_AVAILABLE_IN_1_8 +CLUTTER_EXPORT void clutter_event_set_button (ClutterEvent *event, guint32 button); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT guint32 clutter_event_get_button (const ClutterEvent *event); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT guint clutter_event_get_click_count (const ClutterEvent *event); -CLUTTER_AVAILABLE_IN_1_8 +CLUTTER_EXPORT void clutter_event_set_related (ClutterEvent *event, ClutterActor *actor); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT ClutterActor * clutter_event_get_related (const ClutterEvent *event); -CLUTTER_AVAILABLE_IN_1_8 +CLUTTER_EXPORT void clutter_event_set_scroll_direction (ClutterEvent *event, ClutterScrollDirection direction); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT ClutterScrollDirection clutter_event_get_scroll_direction (const ClutterEvent *event); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_event_set_scroll_delta (ClutterEvent *event, gdouble dx, gdouble dy); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_event_get_scroll_delta (const ClutterEvent *event, gdouble *dx, gdouble *dy); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT ClutterEventSequence * clutter_event_get_event_sequence (const ClutterEvent *event); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT guint32 clutter_keysym_to_unicode (guint keyval); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT guint clutter_unicode_to_keysym (guint32 wc); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT guint32 clutter_get_current_event_time (void); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT const ClutterEvent * clutter_get_current_event (void); -CLUTTER_AVAILABLE_IN_1_24 +CLUTTER_EXPORT guint clutter_event_get_touchpad_gesture_finger_count (const ClutterEvent *event); -CLUTTER_AVAILABLE_IN_1_24 +CLUTTER_EXPORT gdouble clutter_event_get_gesture_pinch_angle_delta (const ClutterEvent *event); -CLUTTER_AVAILABLE_IN_1_24 +CLUTTER_EXPORT gdouble clutter_event_get_gesture_pinch_scale (const ClutterEvent *event); -CLUTTER_AVAILABLE_IN_1_24 +CLUTTER_EXPORT ClutterTouchpadGesturePhase clutter_event_get_gesture_phase (const ClutterEvent *event); -CLUTTER_AVAILABLE_IN_1_24 +CLUTTER_EXPORT void clutter_event_get_gesture_motion_delta (const ClutterEvent *event, gdouble *dx, gdouble *dy); +CLUTTER_EXPORT ClutterScrollSource clutter_event_get_scroll_source (const ClutterEvent *event); + +CLUTTER_EXPORT ClutterScrollFinishFlags clutter_event_get_scroll_finish_flags (const ClutterEvent *event); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT guint clutter_event_get_mode_group (const ClutterEvent *event); -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT gboolean clutter_event_get_pad_event_details (const ClutterEvent *event, guint *number, guint *mode, diff --git a/clutter/clutter/clutter-feature.c b/clutter/clutter/clutter-feature.c index a2280649a..663d1c089 100644 --- a/clutter/clutter/clutter-feature.c +++ b/clutter/clutter/clutter-feature.c @@ -33,13 +33,9 @@ * * It is possible to ask whether Clutter has support for specific features at * run-time. - * - * See also cogl_get_features() and #CoglFeatureFlags */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include #include @@ -62,24 +58,13 @@ typedef struct ClutterFeatures static ClutterFeatures* __features = NULL; static ClutterFeatureFlags -clutter_features_from_cogl (guint cogl_flags) +clutter_features_from_cogl (void) { ClutterFeatureFlags clutter_flags = 0; - if (cogl_flags & COGL_FEATURE_TEXTURE_NPOT) - clutter_flags |= CLUTTER_FEATURE_TEXTURE_NPOT; - - if (cogl_flags & COGL_FEATURE_TEXTURE_YUV) - clutter_flags |= CLUTTER_FEATURE_TEXTURE_YUV; - - if (cogl_flags & COGL_FEATURE_TEXTURE_READ_PIXELS) - clutter_flags |= CLUTTER_FEATURE_TEXTURE_READ_PIXELS; - - if (cogl_flags & COGL_FEATURE_SHADERS_GLSL) - clutter_flags |= CLUTTER_FEATURE_SHADERS_GLSL; + clutter_flags |= CLUTTER_FEATURE_SHADERS_GLSL; - if (cogl_flags & COGL_FEATURE_OFFSCREEN) - clutter_flags |= CLUTTER_FEATURE_OFFSCREEN; + clutter_flags |= CLUTTER_FEATURE_OFFSCREEN; return clutter_flags; } @@ -107,7 +92,7 @@ _clutter_feature_init (GError **error) if (!_clutter_backend_create_context (context->backend, error)) return FALSE; - __features->flags = (clutter_features_from_cogl (cogl_get_features ()) + __features->flags = (clutter_features_from_cogl () | _clutter_backend_get_features (context->backend)); __features->features_set = TRUE; diff --git a/clutter/clutter/clutter-feature.h b/clutter/clutter/clutter-feature.h index 1427e2271..5c1b12449 100644 --- a/clutter/clutter/clutter-feature.h +++ b/clutter/clutter/clutter-feature.h @@ -32,9 +32,9 @@ G_BEGIN_DECLS -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gboolean clutter_feature_available (ClutterFeatureFlags feature); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterFeatureFlags clutter_feature_get_all (void); G_END_DECLS diff --git a/clutter/clutter/clutter-fixed-layout.c b/clutter/clutter/clutter-fixed-layout.c index 7034af7cd..959f7652e 100644 --- a/clutter/clutter/clutter-fixed-layout.c +++ b/clutter/clutter/clutter-fixed-layout.c @@ -34,9 +34,7 @@ * #ClutterFixedLayout is available since Clutter 1.2 */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include "clutter-debug.h" #include "clutter-fixed-layout.h" diff --git a/clutter/clutter/clutter-fixed-layout.h b/clutter/clutter/clutter-fixed-layout.h index 01a2fd6ed..d67e4a8d7 100644 --- a/clutter/clutter/clutter-fixed-layout.h +++ b/clutter/clutter/clutter-fixed-layout.h @@ -71,10 +71,10 @@ struct _ClutterFixedLayoutClass ClutterLayoutManagerClass parent_class; }; -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT GType clutter_fixed_layout_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT ClutterLayoutManager *clutter_fixed_layout_new (void); G_END_DECLS diff --git a/clutter/clutter/clutter-flatten-effect.c b/clutter/clutter/clutter-flatten-effect.c index d61930a4d..e35485da8 100644 --- a/clutter/clutter/clutter-flatten-effect.c +++ b/clutter/clutter/clutter-flatten-effect.c @@ -27,9 +27,7 @@ need to do anything on top of the ClutterOffscreenEffect class so it only exists because that class is abstract */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include "clutter-flatten-effect.h" #include "clutter-private.h" diff --git a/clutter/clutter/clutter-flow-layout.c b/clutter/clutter/clutter-flow-layout.c index 13df8825c..365c5d9d8 100644 --- a/clutter/clutter/clutter-flow-layout.c +++ b/clutter/clutter/clutter-flow-layout.c @@ -52,9 +52,7 @@ * #ClutterFlowLayout is available since Clutter 1.2 */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include diff --git a/clutter/clutter/clutter-flow-layout.h b/clutter/clutter/clutter-flow-layout.h index d44857be6..0980bc3cb 100644 --- a/clutter/clutter/clutter-flow-layout.h +++ b/clutter/clutter/clutter-flow-layout.h @@ -74,54 +74,54 @@ struct _ClutterFlowLayoutClass ClutterLayoutManagerClass parent_class; }; -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT GType clutter_flow_layout_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT ClutterLayoutManager * clutter_flow_layout_new (ClutterFlowOrientation orientation); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT void clutter_flow_layout_set_orientation (ClutterFlowLayout *layout, ClutterFlowOrientation orientation); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT ClutterFlowOrientation clutter_flow_layout_get_orientation (ClutterFlowLayout *layout); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT void clutter_flow_layout_set_homogeneous (ClutterFlowLayout *layout, gboolean homogeneous); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT gboolean clutter_flow_layout_get_homogeneous (ClutterFlowLayout *layout); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT void clutter_flow_layout_set_column_spacing (ClutterFlowLayout *layout, gfloat spacing); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT gfloat clutter_flow_layout_get_column_spacing (ClutterFlowLayout *layout); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT void clutter_flow_layout_set_row_spacing (ClutterFlowLayout *layout, gfloat spacing); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT gfloat clutter_flow_layout_get_row_spacing (ClutterFlowLayout *layout); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT void clutter_flow_layout_set_column_width (ClutterFlowLayout *layout, gfloat min_width, gfloat max_width); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT void clutter_flow_layout_get_column_width (ClutterFlowLayout *layout, gfloat *min_width, gfloat *max_width); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT void clutter_flow_layout_set_row_height (ClutterFlowLayout *layout, gfloat min_height, gfloat max_height); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT void clutter_flow_layout_get_row_height (ClutterFlowLayout *layout, gfloat *min_height, gfloat *max_height); -CLUTTER_AVAILABLE_IN_1_16 +CLUTTER_EXPORT void clutter_flow_layout_set_snap_to_grid (ClutterFlowLayout *layout, gboolean snap_to_grid); -CLUTTER_AVAILABLE_IN_1_16 +CLUTTER_EXPORT gboolean clutter_flow_layout_get_snap_to_grid (ClutterFlowLayout *layout); G_END_DECLS diff --git a/clutter/clutter/clutter-gesture-action.c b/clutter/clutter/clutter-gesture-action.c index 668112f81..bd345eacb 100644 --- a/clutter/clutter/clutter-gesture-action.c +++ b/clutter/clutter/clutter-gesture-action.c @@ -83,9 +83,7 @@ * Since: 1.8 */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include "clutter-gesture-action-private.h" @@ -120,7 +118,7 @@ struct _ClutterGestureActionPrivate gint requested_nb_points; GArray *points; - guint actor_capture_id; + gulong actor_capture_id; gulong stage_capture_id; ClutterGestureTriggerEdge edge; @@ -310,11 +308,7 @@ cancel_gesture (ClutterGestureAction *action) priv->in_gesture = FALSE; - if (priv->stage_capture_id != 0) - { - g_signal_handler_disconnect (priv->stage, priv->stage_capture_id); - priv->stage_capture_id = 0; - } + g_clear_signal_handler (&priv->stage_capture_id, priv->stage); actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action)); g_signal_emit (action, gesture_signals[GESTURE_CANCEL], 0, actor); @@ -483,11 +477,8 @@ stage_captured_event_cb (ClutterActor *stage, break; } - if (priv->points->len == 0 && priv->stage_capture_id) - { - g_signal_handler_disconnect (priv->stage, priv->stage_capture_id); - priv->stage_capture_id = 0; - } + if (priv->points->len == 0) + g_clear_signal_handler (&priv->stage_capture_id, priv->stage); return CLUTTER_EVENT_PROPAGATE; } @@ -540,7 +531,7 @@ clutter_gesture_action_set_actor (ClutterActorMeta *meta, ClutterActor *old_actor = clutter_actor_meta_get_actor (meta); if (old_actor != NULL) - g_signal_handler_disconnect (old_actor, priv->actor_capture_id); + g_clear_signal_handler (&priv->actor_capture_id, old_actor); priv->actor_capture_id = 0; } @@ -548,7 +539,7 @@ clutter_gesture_action_set_actor (ClutterActorMeta *meta, if (priv->stage_capture_id != 0) { if (priv->stage != NULL) - g_signal_handler_disconnect (priv->stage, priv->stage_capture_id); + g_clear_signal_handler (&priv->stage_capture_id, priv->stage); priv->stage_capture_id = 0; priv->stage = NULL; @@ -806,8 +797,7 @@ clutter_gesture_action_class_init (ClutterGestureActionClass *klass) G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ClutterGestureActionClass, gesture_end), - NULL, NULL, - _clutter_marshal_VOID__OBJECT, + NULL, NULL, NULL, G_TYPE_NONE, 1, CLUTTER_TYPE_ACTOR); @@ -829,8 +819,7 @@ clutter_gesture_action_class_init (ClutterGestureActionClass *klass) G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ClutterGestureActionClass, gesture_cancel), - NULL, NULL, - _clutter_marshal_VOID__OBJECT, + NULL, NULL, NULL, G_TYPE_NONE, 1, CLUTTER_TYPE_ACTOR); } diff --git a/clutter/clutter/clutter-gesture-action.h b/clutter/clutter/clutter-gesture-action.h index 46d3c4505..e73bf52bb 100644 --- a/clutter/clutter/clutter-gesture-action.h +++ b/clutter/clutter/clutter-gesture-action.h @@ -101,75 +101,75 @@ struct _ClutterGestureActionClass void (* _clutter_gesture_action6) (void); }; -CLUTTER_AVAILABLE_IN_1_8 +CLUTTER_EXPORT GType clutter_gesture_action_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_8 +CLUTTER_EXPORT ClutterAction * clutter_gesture_action_new (void); -CLUTTER_AVAILABLE_IN_1_8 +CLUTTER_EXPORT gint clutter_gesture_action_get_n_touch_points (ClutterGestureAction *action); -CLUTTER_AVAILABLE_IN_1_8 +CLUTTER_EXPORT void clutter_gesture_action_set_n_touch_points (ClutterGestureAction *action, gint nb_points); -CLUTTER_AVAILABLE_IN_1_8 +CLUTTER_EXPORT void clutter_gesture_action_get_press_coords (ClutterGestureAction *action, guint point, gfloat *press_x, gfloat *press_y); -CLUTTER_AVAILABLE_IN_1_8 +CLUTTER_EXPORT void clutter_gesture_action_get_motion_coords (ClutterGestureAction *action, guint point, gfloat *motion_x, gfloat *motion_y); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT gfloat clutter_gesture_action_get_motion_delta (ClutterGestureAction *action, guint point, gfloat *delta_x, gfloat *delta_y); -CLUTTER_AVAILABLE_IN_1_8 +CLUTTER_EXPORT void clutter_gesture_action_get_release_coords (ClutterGestureAction *action, guint point, gfloat *release_x, gfloat *release_y); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT gfloat clutter_gesture_action_get_velocity (ClutterGestureAction *action, guint point, gfloat *velocity_x, gfloat *velocity_y); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT guint clutter_gesture_action_get_n_current_points (ClutterGestureAction *action); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT ClutterEventSequence * clutter_gesture_action_get_sequence (ClutterGestureAction *action, guint point); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT ClutterInputDevice * clutter_gesture_action_get_device (ClutterGestureAction *action, guint point); -CLUTTER_AVAILABLE_IN_1_14 +CLUTTER_EXPORT const ClutterEvent * clutter_gesture_action_get_last_event (ClutterGestureAction *action, guint point); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_gesture_action_cancel (ClutterGestureAction *action); -CLUTTER_AVAILABLE_IN_1_18 +CLUTTER_EXPORT void clutter_gesture_action_set_threshold_trigger_edge (ClutterGestureAction *action, ClutterGestureTriggerEdge edge); -CLUTTER_DEPRECATED_IN_1_20_FOR(clutter_gesture_action_get_threshold_trigger_edge) +CLUTTER_DEPRECATED_FOR(clutter_gesture_action_get_threshold_trigger_edge) ClutterGestureTriggerEdge clutter_gesture_action_get_threshold_trigger_egde (ClutterGestureAction *action); -CLUTTER_AVAILABLE_IN_1_20 +CLUTTER_EXPORT ClutterGestureTriggerEdge clutter_gesture_action_get_threshold_trigger_edge (ClutterGestureAction *action); -CLUTTER_AVAILABLE_IN_1_18 +CLUTTER_EXPORT void clutter_gesture_action_set_threshold_trigger_distance (ClutterGestureAction *action, float x, float y); -CLUTTER_AVAILABLE_IN_1_18 +CLUTTER_EXPORT void clutter_gesture_action_get_threshold_trigger_distance (ClutterGestureAction *action, float *x, float *y); diff --git a/clutter/clutter/clutter-graphene.c b/clutter/clutter/clutter-graphene.c new file mode 100644 index 000000000..d1c447a5e --- /dev/null +++ b/clutter/clutter/clutter-graphene.c @@ -0,0 +1,111 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Authored By Georges Basile Stavracas Neto + * + * Copyright (C) 2019 Endless, Inc + * Copyright (C) 2009, 2010 Intel Corp + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#include "clutter-build-config.h" + +#include "clutter-graphene.h" + +#include "clutter-private.h" +#include "clutter-types.h" + +static gboolean +graphene_point_progress (const GValue *a, + const GValue *b, + double progress, + GValue *retval) +{ + const graphene_point_t *ap = g_value_get_boxed (a); + const graphene_point_t *bp = g_value_get_boxed (b); + graphene_point_t res; + + graphene_point_interpolate (ap, bp, progress, &res); + + g_value_set_boxed (retval, &res); + + return TRUE; +} + +static gboolean +graphene_point3d_progress (const GValue *a, + const GValue *b, + double progress, + GValue *retval) +{ + const graphene_point3d_t *av = g_value_get_boxed (a); + const graphene_point3d_t *bv = g_value_get_boxed (b); + graphene_point3d_t res; + + graphene_point3d_interpolate (av, bv, progress, &res); + + g_value_set_boxed (retval, &res); + + return TRUE; +} + +static gboolean +graphene_rect_progress (const GValue *a, + const GValue *b, + double progress, + GValue *retval) +{ + const graphene_rect_t *rect_a = g_value_get_boxed (a); + const graphene_rect_t *rect_b = g_value_get_boxed (b); + graphene_rect_t res; + + graphene_rect_interpolate (rect_a, rect_b, progress, &res); + + g_value_set_boxed (retval, &res); + + return TRUE; +} + +static gboolean +graphene_size_progress (const GValue *a, + const GValue *b, + double progress, + GValue *retval) +{ + const graphene_size_t *as = g_value_get_boxed (a); + const graphene_size_t *bs = g_value_get_boxed (b); + graphene_size_t res; + + graphene_size_interpolate (as, bs, progress, &res); + + g_value_set_boxed (retval, &res); + + return TRUE; +} + +void +clutter_graphene_init (void) +{ + clutter_interval_register_progress_func (GRAPHENE_TYPE_POINT, + graphene_point_progress); + clutter_interval_register_progress_func (GRAPHENE_TYPE_POINT3D, + graphene_point3d_progress); + clutter_interval_register_progress_func (GRAPHENE_TYPE_RECT, + graphene_rect_progress); + clutter_interval_register_progress_func (GRAPHENE_TYPE_SIZE, + graphene_size_progress); +} diff --git a/clutter/clutter/x11/clutter-glx.h b/clutter/clutter/clutter-graphene.h similarity index 68% rename from clutter/clutter/x11/clutter-glx.h rename to clutter/clutter/clutter-graphene.h index 04b001e99..ddea3ca4a 100644 --- a/clutter/clutter/x11/clutter-glx.h +++ b/clutter/clutter/clutter-graphene.h @@ -3,9 +3,10 @@ * * An OpenGL based 'interactive canvas' library. * - * Authored By Matthew Allum + * Authored By Georges Basile Stavracas Neto * - * Copyright (C) 2006 OpenedHand + * Copyright (C) 2019 Endless, Inc + * Copyright (C) 2009, 2010 Intel Corp * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -19,18 +20,11 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . - * - * */ -#ifndef __CLUTTER_GLX_H__ -#define __CLUTTER_GLX_H__ +#ifndef CLUTTER_GRAPHENE_H +#define CLUTTER_GRAPHENE_H -#include -#include -#include -#include -#include -#include +void clutter_graphene_init (void); -#endif /* __CLUTTER_GLX_H__ */ +#endif diff --git a/clutter/clutter/clutter-grid-layout.c b/clutter/clutter/clutter-grid-layout.c index 069ccb6f4..29ec54759 100644 --- a/clutter/clutter/clutter-grid-layout.c +++ b/clutter/clutter/clutter-grid-layout.c @@ -26,9 +26,7 @@ * Matthias Clasen */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include #include @@ -46,12 +44,12 @@ * SECTION:clutter-grid-layout * @Short_description: A layout manager for a grid of actors * @Title: ClutterGridLayout - * @See_also: #ClutterTableLayout, #ClutterBoxLayout + * @See_also: #ClutterBoxLayout * * #ClutterGridLayout is a layout manager which arranges its child widgets in - * rows and columns. It is a very similar to #ClutterTableLayout and - * #ClutterBoxLayout, but it consistently uses #ClutterActor's - * alignment and expansion flags instead of custom child properties. + * rows and columns. It is a very similar to #ClutterBoxLayout, but it + * consistently uses #ClutterActor's alignment and expansion flags instead of + * custom child properties. * * Children are added using clutter_grid_layout_attach(). They can span * multiple rows or columns. It is also possible to add a child next to an diff --git a/clutter/clutter/clutter-grid-layout.h b/clutter/clutter/clutter-grid-layout.h index c04a5ba4f..88603265d 100644 --- a/clutter/clutter/clutter-grid-layout.h +++ b/clutter/clutter/clutter-grid-layout.h @@ -80,13 +80,13 @@ struct _ClutterGridLayoutClass gpointer _padding[8]; }; -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT GType clutter_grid_layout_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT ClutterLayoutManager * clutter_grid_layout_new (void); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_grid_layout_attach (ClutterGridLayout *layout, ClutterActor *child, gint left, @@ -94,7 +94,7 @@ void clutter_grid_layout_attach (ClutterGrid gint width, gint height); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_grid_layout_attach_next_to (ClutterGridLayout *layout, ClutterActor *child, ClutterActor *sibling, @@ -102,58 +102,58 @@ void clutter_grid_layout_attach_next_to (ClutterGrid gint width, gint height); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT ClutterActor * clutter_grid_layout_get_child_at (ClutterGridLayout *layout, gint left, gint top); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_grid_layout_insert_row (ClutterGridLayout *layout, gint position); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_grid_layout_insert_column (ClutterGridLayout *layout, gint position); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_grid_layout_insert_next_to (ClutterGridLayout *layout, ClutterActor *sibling, ClutterGridPosition side); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_grid_layout_set_orientation (ClutterGridLayout *layout, ClutterOrientation orientation); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT ClutterOrientation clutter_grid_layout_get_orientation (ClutterGridLayout *layout); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_grid_layout_set_column_spacing (ClutterGridLayout *layout, guint spacing); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT guint clutter_grid_layout_get_column_spacing (ClutterGridLayout *layout); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_grid_layout_set_row_spacing (ClutterGridLayout *layout, guint spacing); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT guint clutter_grid_layout_get_row_spacing (ClutterGridLayout *layout); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_grid_layout_set_column_homogeneous (ClutterGridLayout *layout, gboolean homogeneous); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT gboolean clutter_grid_layout_get_column_homogeneous (ClutterGridLayout *layout); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_grid_layout_set_row_homogeneous (ClutterGridLayout *layout, gboolean homogeneous); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT gboolean clutter_grid_layout_get_row_homogeneous (ClutterGridLayout *layout); G_END_DECLS diff --git a/clutter/clutter/clutter-group.h b/clutter/clutter/clutter-group.h index 40f71bc74..7f8e5f346 100644 --- a/clutter/clutter/clutter-group.h +++ b/clutter/clutter/clutter-group.h @@ -88,7 +88,7 @@ struct _ClutterGroupClass void (*_clutter_reserved6) (void); }; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT GType clutter_group_get_type (void) G_GNUC_CONST; G_END_DECLS diff --git a/clutter/clutter/clutter-id-pool.c b/clutter/clutter/clutter-id-pool.c index a56543650..39fe00231 100644 --- a/clutter/clutter/clutter-id-pool.c +++ b/clutter/clutter/clutter-id-pool.c @@ -28,9 +28,7 @@ * */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include "clutter-debug.h" #include "clutter-id-pool.h" diff --git a/clutter/clutter/clutter-image.c b/clutter/clutter/clutter-image.c index 722b0375d..eb6c2f50a 100644 --- a/clutter/clutter/clutter-image.c +++ b/clutter/clutter/clutter-image.c @@ -36,9 +36,7 @@ * #ClutterImage is available since Clutter 1.10. */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #define CLUTTER_ENABLE_EXPERIMENTAL_API @@ -55,9 +53,11 @@ struct _ClutterImagePrivate { CoglTexture *texture; + gint width; + gint height; }; -static void clutter_content_iface_init (ClutterContentIface *iface); +static void clutter_content_iface_init (ClutterContentInterface *iface); G_DEFINE_TYPE_WITH_CODE (ClutterImage, clutter_image, G_TYPE_OBJECT, G_ADD_PRIVATE (ClutterImage) @@ -70,6 +70,27 @@ clutter_image_error_quark (void) return g_quark_from_static_string ("clutter-image-error-quark"); } +static void +update_image_size (ClutterImage *self) +{ + gint width, height; + + if (self->priv->texture == NULL) + return; + + width = cogl_texture_get_width (self->priv->texture); + height = cogl_texture_get_height (self->priv->texture); + + if (self->priv->width == width && + self->priv->height == height) + return; + + self->priv->width = width; + self->priv->height = height; + + clutter_content_invalidate_size (CLUTTER_CONTENT (self)); +} + static void clutter_image_finalize (GObject *gobject) { @@ -97,9 +118,10 @@ clutter_image_init (ClutterImage *self) } static void -clutter_image_paint_content (ClutterContent *content, - ClutterActor *actor, - ClutterPaintNode *root) +clutter_image_paint_content (ClutterContent *content, + ClutterActor *actor, + ClutterPaintNode *root, + ClutterPaintContext *paint_context) { ClutterImagePrivate *priv = CLUTTER_IMAGE (content)->priv; ClutterPaintNode *node; @@ -108,7 +130,7 @@ clutter_image_paint_content (ClutterContent *content, return; node = clutter_actor_create_texture_paint_node (actor, priv->texture); - clutter_paint_node_set_name (node, "Image Content"); + clutter_paint_node_set_static_name (node, "Image Content"); clutter_paint_node_add_child (root, node); clutter_paint_node_unref (node); } @@ -133,7 +155,7 @@ clutter_image_get_preferred_size (ClutterContent *content, } static void -clutter_content_iface_init (ClutterContentIface *iface) +clutter_content_iface_init (ClutterContentInterface *iface) { iface->get_preferred_size = clutter_image_get_preferred_size; iface->paint_content = clutter_image_paint_content; @@ -235,11 +257,12 @@ clutter_image_set_data (ClutterImage *image, { g_set_error_literal (error, CLUTTER_IMAGE_ERROR, CLUTTER_IMAGE_ERROR_INVALID_DATA, - _("Unable to load image data")); + "Unable to load image data"); return FALSE; } clutter_content_invalidate (CLUTTER_CONTENT (image)); + update_image_size (image); return TRUE; } @@ -303,11 +326,12 @@ clutter_image_set_bytes (ClutterImage *image, { g_set_error_literal (error, CLUTTER_IMAGE_ERROR, CLUTTER_IMAGE_ERROR_INVALID_DATA, - _("Unable to load image data")); + "Unable to load image data"); return FALSE; } clutter_content_invalidate (CLUTTER_CONTENT (image)); + update_image_size (image); return TRUE; } @@ -396,11 +420,12 @@ clutter_image_set_area (ClutterImage *image, { g_set_error_literal (error, CLUTTER_IMAGE_ERROR, CLUTTER_IMAGE_ERROR_INVALID_DATA, - _("Unable to load image data")); + "Unable to load image data"); return FALSE; } clutter_content_invalidate (CLUTTER_CONTENT (image)); + update_image_size (image); return TRUE; } diff --git a/clutter/clutter/clutter-image.h b/clutter/clutter/clutter-image.h index 5a4d06307..7f02099e6 100644 --- a/clutter/clutter/clutter-image.h +++ b/clutter/clutter/clutter-image.h @@ -63,7 +63,8 @@ typedef struct _ClutterImageClass ClutterImageClass; * * Since: 1.10 */ -typedef enum { +typedef enum +{ CLUTTER_IMAGE_ERROR_INVALID_DATA } ClutterImageError; @@ -100,14 +101,14 @@ struct _ClutterImageClass gpointer _padding[16]; }; -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT GQuark clutter_image_error_quark (void); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT GType clutter_image_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT ClutterContent * clutter_image_new (void); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT gboolean clutter_image_set_data (ClutterImage *image, const guint8 *data, CoglPixelFormat pixel_format, @@ -115,14 +116,14 @@ gboolean clutter_image_set_data (ClutterImage guint height, guint row_stride, GError **error); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT gboolean clutter_image_set_area (ClutterImage *image, const guint8 *data, CoglPixelFormat pixel_format, const cairo_rectangle_int_t *rect, guint row_stride, GError **error); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT gboolean clutter_image_set_bytes (ClutterImage *image, GBytes *data, CoglPixelFormat pixel_format, @@ -131,7 +132,7 @@ gboolean clutter_image_set_bytes (ClutterImage guint row_stride, GError **error); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT CoglTexture * clutter_image_get_texture (ClutterImage *image); G_END_DECLS diff --git a/clutter/clutter/clutter-input-device-private.h b/clutter/clutter/clutter-input-device-private.h new file mode 100644 index 000000000..dc55abd34 --- /dev/null +++ b/clutter/clutter/clutter-input-device-private.h @@ -0,0 +1,255 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Copyright © 2009, 2010, 2011 Intel Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Author: Emmanuele Bassi + */ + +#ifndef CLUTTER_INPUT_DEVICE_PRIVATE_H +#define CLUTTER_INPUT_DEVICE_PRIVATE_H + +#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +typedef struct _ClutterAxisInfo +{ + ClutterInputAxis axis; + + double min_axis; + double max_axis; + + double min_value; + double max_value; + + double resolution; +} ClutterAxisInfo; + +typedef struct _ClutterKeyInfo +{ + guint keyval; + ClutterModifierType modifiers; +} ClutterKeyInfo; + +typedef struct _ClutterScrollInfo +{ + guint axis_id; + ClutterScrollDirection direction; + double increment; + + double last_value; + guint last_value_valid : 1; +} ClutterScrollInfo; + +typedef struct _ClutterTouchInfo +{ + ClutterEventSequence *sequence; + ClutterActor *actor; + + float current_x; + float current_y; +} ClutterTouchInfo; + +typedef struct _ClutterPtrA11yData +{ + int n_btn_pressed; + float current_x; + float current_y; + + float dwell_x; + float dwell_y; + gboolean dwell_drag_started; + gboolean dwell_gesture_started; + guint dwell_timer; + guint dwell_position_timer; + + guint secondary_click_timer; + gboolean secondary_click_triggered; +} ClutterPtrA11yData; + +struct _ClutterInputDevice +{ + GObject parent_instance; + + int id; + + ClutterInputDeviceType device_type; + ClutterInputMode device_mode; + + char *device_name; + + ClutterSeat *seat; + + ClutterBackend *backend; + + /* the associated device */ + ClutterInputDevice *associated; + + GList *slaves; + + /* the actor underneath the pointer */ + ClutterActor *cursor_actor; + GHashTable *inv_touch_sequence_actors; + + /* the actor that has a grab in place for the device */ + ClutterActor *pointer_grab_actor; + ClutterActor *keyboard_grab_actor; + GHashTable *sequence_grab_actors; + GHashTable *inv_sequence_grab_actors; + + /* the current click count */ + int click_count; + + /* the stage the device is on */ + ClutterStage *stage; + + /* the current state */ + float current_x; + float current_y; + uint32_t current_time; + int current_button_number; + ClutterModifierType current_state; + + /* the current touch points states */ + GHashTable *touch_sequences_info; + + /* the previous state, used for click count generation */ + int previous_x; + int previous_y; + uint32_t previous_time; + int previous_button_number; + ClutterModifierType previous_state; + + GArray *axes; + + guint n_keys; + GArray *keys; + + GArray *scroll_info; + + char *vendor_id; + char *product_id; + char *node_path; + + GPtrArray *tools; + + int n_rings; + int n_strips; + int n_mode_groups; + + ClutterInputDeviceMapping mapping_mode; + + guint has_cursor : 1; + guint is_enabled : 1; + + /* Accessiblity */ + ClutterVirtualInputDevice *accessibility_virtual_device; + ClutterPtrA11yData *ptr_a11y_data; +}; + +CLUTTER_EXPORT +void _clutter_input_device_set_associated_device (ClutterInputDevice *device, + ClutterInputDevice *associated); +CLUTTER_EXPORT +void _clutter_input_device_add_slave (ClutterInputDevice *master, + ClutterInputDevice *slave); +CLUTTER_EXPORT +void _clutter_input_device_remove_slave (ClutterInputDevice *master, + ClutterInputDevice *slave); +CLUTTER_EXPORT +void clutter_input_device_update_from_tool (ClutterInputDevice *device, + ClutterInputDeviceTool *tool); +CLUTTER_EXPORT +ClutterStage * _clutter_input_device_get_stage (ClutterInputDevice *device); +CLUTTER_EXPORT +void _clutter_input_device_set_stage (ClutterInputDevice *device, + ClutterStage *stage); +CLUTTER_EXPORT +void _clutter_input_device_set_coords (ClutterInputDevice *device, + ClutterEventSequence *sequence, + gfloat x, + gfloat y, + ClutterStage *stage); +CLUTTER_EXPORT +void _clutter_input_device_set_state (ClutterInputDevice *device, + ClutterModifierType state); +CLUTTER_EXPORT +void _clutter_input_device_set_time (ClutterInputDevice *device, + guint32 time_); +void _clutter_input_device_set_actor (ClutterInputDevice *device, + ClutterEventSequence *sequence, + ClutterActor *actor, + gboolean emit_crossing); +CLUTTER_EXPORT +ClutterActor * clutter_input_device_update (ClutterInputDevice *device, + ClutterEventSequence *sequence, + gboolean emit_crossing); +CLUTTER_EXPORT +void _clutter_input_device_add_event_sequence (ClutterInputDevice *device, + ClutterEvent *event); +CLUTTER_EXPORT +void _clutter_input_device_remove_event_sequence (ClutterInputDevice *device, + ClutterEvent *event); +CLUTTER_EXPORT +void _clutter_input_device_set_n_keys (ClutterInputDevice *device, + guint n_keys); +CLUTTER_EXPORT +gboolean _clutter_input_device_translate_axis (ClutterInputDevice *device, + guint index_, + gdouble value, + gdouble *axis_value); +CLUTTER_EXPORT +guint _clutter_input_device_add_axis (ClutterInputDevice *device, + ClutterInputAxis axis, + gdouble minimum, + gdouble maximum, + gdouble resolution); + +CLUTTER_EXPORT +void _clutter_input_device_reset_axes (ClutterInputDevice *device); + +CLUTTER_EXPORT +void _clutter_input_device_add_scroll_info (ClutterInputDevice *device, + guint index_, + ClutterScrollDirection direction, + gdouble increment); +CLUTTER_EXPORT +gboolean _clutter_input_device_get_scroll_delta (ClutterInputDevice *device, + guint index_, + gdouble value, + ClutterScrollDirection *direction_p, + gdouble *delta_p); +CLUTTER_EXPORT +void _clutter_input_device_reset_scroll_info (ClutterInputDevice *device); + +CLUTTER_EXPORT +void clutter_input_device_add_tool (ClutterInputDevice *device, + ClutterInputDeviceTool *tool); + +CLUTTER_EXPORT +ClutterInputDeviceTool * + clutter_input_device_lookup_tool (ClutterInputDevice *device, + guint64 serial, + ClutterInputDeviceToolType type); + +#endif /* CLUTTER_INPUT_DEVICE_PRIVATE_H */ diff --git a/clutter/clutter/clutter-input-device-tool.c b/clutter/clutter/clutter-input-device-tool.c index 0835ddff9..982d94ce4 100644 --- a/clutter/clutter/clutter-input-device-tool.c +++ b/clutter/clutter/clutter-input-device-tool.c @@ -21,9 +21,7 @@ * Author: Carlos Garnacho */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include "clutter-input-device-tool.h" #include "clutter-private.h" @@ -37,7 +35,8 @@ struct _ClutterInputDeviceToolPrivate guint64 id; }; -enum { +enum +{ PROP_0, PROP_TYPE, PROP_SERIAL, diff --git a/clutter/clutter/clutter-input-device-tool.h b/clutter/clutter/clutter-input-device-tool.h index 0b7beef5b..36c8add83 100644 --- a/clutter/clutter/clutter-input-device-tool.h +++ b/clutter/clutter/clutter-input-device-tool.h @@ -52,16 +52,16 @@ struct _ClutterInputDeviceToolClass GObjectClass parent_class; }; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT GType clutter_input_device_tool_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT guint64 clutter_input_device_tool_get_serial (ClutterInputDeviceTool *tool); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterInputDeviceToolType clutter_input_device_tool_get_tool_type (ClutterInputDeviceTool *tool); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT guint64 clutter_input_device_tool_get_id (ClutterInputDeviceTool *tool); G_END_DECLS diff --git a/clutter/clutter/clutter-input-device.c b/clutter/clutter/clutter-input-device.c index 91433752e..e7b5bff96 100644 --- a/clutter/clutter/clutter-input-device.c +++ b/clutter/clutter/clutter-input-device.c @@ -31,20 +31,18 @@ * its contents are usually defined by the Clutter backend in use. */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include "clutter-input-device.h" #include "clutter-actor-private.h" #include "clutter-debug.h" -#include "clutter-device-manager-private.h" #include "clutter-enum-types.h" #include "clutter-event-private.h" #include "clutter-marshal.h" #include "clutter-private.h" #include "clutter-stage-private.h" +#include "clutter-input-device-private.h" #include "clutter-input-device-tool.h" #include @@ -59,7 +57,7 @@ enum PROP_NAME, PROP_DEVICE_TYPE, - PROP_DEVICE_MANAGER, + PROP_SEAT, PROP_DEVICE_MODE, PROP_HAS_CURSOR, @@ -95,9 +93,10 @@ clutter_input_device_dispose (GObject *gobject) { ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (gobject); - g_clear_pointer (&device->device_name, free); - g_clear_pointer (&device->vendor_id, free); - g_clear_pointer (&device->product_id, free); + g_clear_pointer (&device->device_name, g_free); + g_clear_pointer (&device->vendor_id, g_free); + g_clear_pointer (&device->product_id, g_free); + g_clear_pointer (&device->node_path, g_free); if (device->associated != NULL) { @@ -109,6 +108,9 @@ clutter_input_device_dispose (GObject *gobject) device->associated = NULL; } + if (device->accessibility_virtual_device) + g_clear_object (&device->accessibility_virtual_device); + g_clear_pointer (&device->axes, g_array_unref); g_clear_pointer (&device->keys, g_array_unref); g_clear_pointer (&device->scroll_info, g_array_unref); @@ -169,8 +171,8 @@ clutter_input_device_set_property (GObject *gobject, self->device_type = g_value_get_enum (value); break; - case PROP_DEVICE_MANAGER: - self->device_manager = g_value_get_object (value); + case PROP_SEAT: + self->seat = g_value_get_object (value); break; case PROP_DEVICE_MODE: @@ -245,8 +247,8 @@ clutter_input_device_get_property (GObject *gobject, g_value_set_enum (value, self->device_type); break; - case PROP_DEVICE_MANAGER: - g_value_set_object (value, self->device_manager); + case PROP_SEAT: + g_value_set_object (value, self->seat); break; case PROP_DEVICE_MODE: @@ -360,17 +362,15 @@ clutter_input_device_class_init (ClutterInputDeviceClass *klass) G_PARAM_CONSTRUCT_ONLY); /** - * ClutterInputDevice:device-manager: - * - * The #ClutterDeviceManager instance which owns the device + * ClutterInputDevice:seat: * - * Since: 1.6 + * The #ClutterSeat instance which owns the device */ - obj_props[PROP_DEVICE_MANAGER] = - g_param_spec_object ("device-manager", - P_("Device Manager"), - P_("The device manager instance"), - CLUTTER_TYPE_DEVICE_MANAGER, + obj_props[PROP_SEAT] = + g_param_spec_object ("seat", + P_("Seat"), + P_("Seat"), + CLUTTER_TYPE_SEAT, CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); /** @@ -798,7 +798,7 @@ on_cursor_actor_reactive_changed (ClutterActor *actor, * * Sets the actor under the pointer coordinates of @device * - * This function is called by _clutter_input_device_update() + * This function is called by clutter_input_device_update() * and it will: * * - queue a %CLUTTER_LEAVE event on the previous pointer actor @@ -836,6 +836,7 @@ _clutter_input_device_set_actor (ClutterInputDevice *device, event->crossing.x = device->current_x; event->crossing.y = device->current_y; event->crossing.related = actor; + event->crossing.sequence = sequence; clutter_event_set_device (event, device); /* we need to make sure that this event is processed @@ -872,6 +873,7 @@ _clutter_input_device_set_actor (ClutterInputDevice *device, event->crossing.y = device->current_y; event->crossing.source = actor; event->crossing.related = old_actor; + event->crossing.sequence = sequence; clutter_event_set_device (event, device); /* see above */ @@ -988,7 +990,7 @@ clutter_input_device_get_enabled (ClutterInputDevice *device) gboolean clutter_input_device_get_coords (ClutterInputDevice *device, ClutterEventSequence *sequence, - ClutterPoint *point) + graphene_point_t *point) { g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE); g_return_val_if_fail (point != NULL, FALSE); @@ -1014,7 +1016,7 @@ clutter_input_device_get_coords (ClutterInputDevice *device, } /* - * _clutter_input_device_update: + * clutter_input_device_update: * @device: a #ClutterInputDevice * * Updates the input @device by determining the #ClutterActor underneath the @@ -1028,17 +1030,18 @@ clutter_input_device_get_coords (ClutterInputDevice *device, * Since: 1.2 */ ClutterActor * -_clutter_input_device_update (ClutterInputDevice *device, - ClutterEventSequence *sequence, - gboolean emit_crossing) +clutter_input_device_update (ClutterInputDevice *device, + ClutterEventSequence *sequence, + gboolean emit_crossing) { ClutterStage *stage; ClutterActor *new_cursor_actor; ClutterActor *old_cursor_actor; - ClutterPoint point = { -1, -1 }; + graphene_point_t point = GRAPHENE_POINT_INIT (-1.0f, -1.0f); + ClutterInputDeviceType device_type = device->device_type; - if (device->device_type == CLUTTER_KEYBOARD_DEVICE) - return NULL; + g_assert (device_type != CLUTTER_KEYBOARD_DEVICE && + device_type != CLUTTER_PAD_DEVICE); stage = device->stage; if (G_UNLIKELY (stage == NULL)) @@ -1220,11 +1223,11 @@ clutter_input_device_get_device_mode (ClutterInputDevice *device) * * translate_native_event_to_clutter (native_event, &c_event); * - * // get the device manager - * manager = clutter_device_manager_get_default (); + * // get the seat + * seat = clutter_backend_get_deafult_seat (clutter_get_default_backend ()); * * // use the default Core Pointer that Clutter backends register by default - * device = clutter_device_manager_get_core_device (manager, %CLUTTER_POINTER_DEVICE); + * device = clutter_seat_get_pointer (seat); * * // update the state of the input device * clutter_input_device_update_from_event (device, &c_event, FALSE); @@ -1921,6 +1924,157 @@ _clutter_input_device_reset_scroll_info (ClutterInputDevice *device) } } +static void +on_grab_actor_destroy (ClutterActor *actor, + ClutterInputDevice *device) +{ + switch (device->device_type) + { + case CLUTTER_POINTER_DEVICE: + case CLUTTER_TABLET_DEVICE: + device->pointer_grab_actor = NULL; + break; + + case CLUTTER_KEYBOARD_DEVICE: + device->keyboard_grab_actor = NULL; + break; + + default: + g_assert_not_reached (); + } +} + +/** + * clutter_input_device_grab: + * @device: a #ClutterInputDevice + * @actor: a #ClutterActor + * + * Acquires a grab on @actor for the given @device. + * + * Any event coming from @device will be delivered to @actor, bypassing + * the usual event delivery mechanism, until the grab is released by + * calling clutter_input_device_ungrab(). + * + * The grab is client-side: even if the windowing system used by the Clutter + * backend has the concept of "device grabs", Clutter will not use them. + * + * Only #ClutterInputDevice of types %CLUTTER_POINTER_DEVICE, + * %CLUTTER_TABLET_DEVICE and %CLUTTER_KEYBOARD_DEVICE can hold a grab. + * + * Since: 1.10 + */ +void +clutter_input_device_grab (ClutterInputDevice *device, + ClutterActor *actor) +{ + ClutterActor **grab_actor; + + g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device)); + g_return_if_fail (CLUTTER_IS_ACTOR (actor)); + + switch (device->device_type) + { + case CLUTTER_POINTER_DEVICE: + case CLUTTER_TABLET_DEVICE: + grab_actor = &device->pointer_grab_actor; + break; + + case CLUTTER_KEYBOARD_DEVICE: + grab_actor = &device->keyboard_grab_actor; + break; + + default: + g_critical ("Only pointer and keyboard devices can grab an actor"); + return; + } + + if (*grab_actor != NULL) + { + g_signal_handlers_disconnect_by_func (*grab_actor, + G_CALLBACK (on_grab_actor_destroy), + device); + } + + *grab_actor = actor; + + g_signal_connect (*grab_actor, + "destroy", + G_CALLBACK (on_grab_actor_destroy), + device); +} + +/** + * clutter_input_device_ungrab: + * @device: a #ClutterInputDevice + * + * Releases the grab on the @device, if one is in place. + * + * Since: 1.10 + */ +void +clutter_input_device_ungrab (ClutterInputDevice *device) +{ + ClutterActor **grab_actor; + + g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device)); + + switch (device->device_type) + { + case CLUTTER_POINTER_DEVICE: + case CLUTTER_TABLET_DEVICE: + grab_actor = &device->pointer_grab_actor; + break; + + case CLUTTER_KEYBOARD_DEVICE: + grab_actor = &device->keyboard_grab_actor; + break; + + default: + return; + } + + if (*grab_actor == NULL) + return; + + g_signal_handlers_disconnect_by_func (*grab_actor, + G_CALLBACK (on_grab_actor_destroy), + device); + + *grab_actor = NULL; +} + +/** + * clutter_input_device_get_grabbed_actor: + * @device: a #ClutterInputDevice + * + * Retrieves a pointer to the #ClutterActor currently grabbing all + * the events coming from @device. + * + * Return value: (transfer none): a #ClutterActor, or %NULL + * + * Since: 1.10 + */ +ClutterActor * +clutter_input_device_get_grabbed_actor (ClutterInputDevice *device) +{ + g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL); + + switch (device->device_type) + { + case CLUTTER_POINTER_DEVICE: + case CLUTTER_TABLET_DEVICE: + return device->pointer_grab_actor; + + case CLUTTER_KEYBOARD_DEVICE: + return device->keyboard_grab_actor; + + default: + g_critical ("Only pointer and keyboard devices can grab an actor"); + } + + return NULL; +} + static void on_grab_sequence_actor_destroy (ClutterActor *actor, ClutterInputDevice *device) @@ -2286,3 +2440,19 @@ clutter_input_device_is_grouped (ClutterInputDevice *device, return CLUTTER_INPUT_DEVICE_GET_CLASS (device)->is_grouped (device, other_device); } + +/** + * clutter_input_device_get_seat: + * @device: a #ClutterInputDevice + * + * Returns the seat the device belongs to + * + * Returns: (transfer none): the device seat + **/ +ClutterSeat * +clutter_input_device_get_seat (ClutterInputDevice *device) +{ + g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL); + + return device->seat; +} diff --git a/clutter/clutter/clutter-input-device.h b/clutter/clutter/clutter-input-device.h index 3961b5027..68b74ced8 100644 --- a/clutter/clutter/clutter-input-device.h +++ b/clutter/clutter/clutter-input-device.h @@ -28,10 +28,40 @@ #error "Only can be included directly." #endif +#include #include +#include G_BEGIN_DECLS +typedef void (*ClutterEmitInputDeviceEvent) (ClutterEvent *event, + ClutterInputDevice *device); + +struct _ClutterInputDeviceClass +{ + GObjectClass parent_class; + + gboolean (* keycode_to_evdev) (ClutterInputDevice *device, + guint hardware_keycode, + guint *evdev_keycode); + void (* update_from_tool) (ClutterInputDevice *device, + ClutterInputDeviceTool *tool); + + gboolean (* is_mode_switch_button) (ClutterInputDevice *device, + guint group, + guint button); + gint (* get_group_n_modes) (ClutterInputDevice *device, + gint group); + + gboolean (* is_grouped) (ClutterInputDevice *device, + ClutterInputDevice *other_device); + + /* Keyboard accessbility */ + void (* process_kbd_a11y_event) (ClutterEvent *event, + ClutterInputDevice *device, + ClutterEmitInputDeviceEvent emit_event_func); +}; + #define CLUTTER_TYPE_INPUT_DEVICE (clutter_input_device_get_type ()) #define CLUTTER_INPUT_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_INPUT_DEVICE, ClutterInputDevice)) #define CLUTTER_IS_INPUT_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_INPUT_DEVICE)) @@ -47,130 +77,132 @@ G_BEGIN_DECLS */ typedef struct _ClutterInputDeviceClass ClutterInputDeviceClass; -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT GType clutter_input_device_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT ClutterInputDeviceType clutter_input_device_get_device_type (ClutterInputDevice *device); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT gint clutter_input_device_get_device_id (ClutterInputDevice *device); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT gboolean clutter_input_device_get_coords (ClutterInputDevice *device, ClutterEventSequence *sequence, - ClutterPoint *point); -CLUTTER_AVAILABLE_IN_1_16 + graphene_point_t *point); +CLUTTER_EXPORT ClutterModifierType clutter_input_device_get_modifier_state (ClutterInputDevice *device); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT ClutterActor * clutter_input_device_get_pointer_actor (ClutterInputDevice *device); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT ClutterStage * clutter_input_device_get_pointer_stage (ClutterInputDevice *device); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT const gchar * clutter_input_device_get_device_name (ClutterInputDevice *device); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT ClutterInputMode clutter_input_device_get_device_mode (ClutterInputDevice *device); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT gboolean clutter_input_device_get_has_cursor (ClutterInputDevice *device); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT void clutter_input_device_set_enabled (ClutterInputDevice *device, gboolean enabled); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT gboolean clutter_input_device_get_enabled (ClutterInputDevice *device); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT guint clutter_input_device_get_n_axes (ClutterInputDevice *device); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT ClutterInputAxis clutter_input_device_get_axis (ClutterInputDevice *device, guint index_); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT gboolean clutter_input_device_get_axis_value (ClutterInputDevice *device, gdouble *axes, ClutterInputAxis axis, gdouble *value); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT guint clutter_input_device_get_n_keys (ClutterInputDevice *device); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT void clutter_input_device_set_key (ClutterInputDevice *device, guint index_, guint keyval, ClutterModifierType modifiers); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT gboolean clutter_input_device_get_key (ClutterInputDevice *device, guint index_, guint *keyval, ClutterModifierType *modifiers); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT ClutterInputDevice * clutter_input_device_get_associated_device (ClutterInputDevice *device); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT GList * clutter_input_device_get_slave_devices (ClutterInputDevice *device); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT void clutter_input_device_update_from_event (ClutterInputDevice *device, ClutterEvent *event, gboolean update_stage); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_input_device_grab (ClutterInputDevice *device, ClutterActor *actor); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_input_device_ungrab (ClutterInputDevice *device); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT ClutterActor * clutter_input_device_get_grabbed_actor (ClutterInputDevice *device); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_input_device_sequence_grab (ClutterInputDevice *device, ClutterEventSequence *sequence, ClutterActor *actor); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_input_device_sequence_ungrab (ClutterInputDevice *device, ClutterEventSequence *sequence); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT ClutterActor * clutter_input_device_sequence_get_grabbed_actor (ClutterInputDevice *device, ClutterEventSequence *sequence); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT gboolean clutter_input_device_keycode_to_evdev (ClutterInputDevice *device, guint hardware_keycode, guint *evdev_keycode); -CLUTTER_AVAILABLE_IN_1_22 +CLUTTER_EXPORT const gchar * clutter_input_device_get_vendor_id (ClutterInputDevice *device); -CLUTTER_AVAILABLE_IN_1_22 +CLUTTER_EXPORT const gchar * clutter_input_device_get_product_id (ClutterInputDevice *device); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gint clutter_input_device_get_n_rings (ClutterInputDevice *device); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gint clutter_input_device_get_n_strips (ClutterInputDevice *device); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gint clutter_input_device_get_n_mode_groups (ClutterInputDevice *device); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gint clutter_input_device_get_group_n_modes (ClutterInputDevice *device, gint group); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gboolean clutter_input_device_is_mode_switch_button (ClutterInputDevice *device, guint group, guint button); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gint clutter_input_device_get_mode_switch_button_group (ClutterInputDevice *device, guint button); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT const gchar * clutter_input_device_get_device_node (ClutterInputDevice *device); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterInputDeviceMapping clutter_input_device_get_mapping_mode (ClutterInputDevice *device); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_input_device_set_mapping_mode (ClutterInputDevice *device, ClutterInputDeviceMapping mapping); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gboolean clutter_input_device_is_grouped (ClutterInputDevice *device, ClutterInputDevice *other_device); +CLUTTER_EXPORT +ClutterSeat * clutter_input_device_get_seat (ClutterInputDevice *device); G_END_DECLS diff --git a/clutter/clutter/clutter-input-focus-private.h b/clutter/clutter/clutter-input-focus-private.h index 563e58978..ccde45d0e 100644 --- a/clutter/clutter/clutter-input-focus-private.h +++ b/clutter/clutter/clutter-input-focus-private.h @@ -29,7 +29,7 @@ void clutter_input_focus_focus_out (ClutterInputFocus *focus); void clutter_input_focus_commit (ClutterInputFocus *focus, const gchar *text); void clutter_input_focus_delete_surrounding (ClutterInputFocus *focus, - guint offset, + int offset, guint len); void clutter_input_focus_request_surrounding (ClutterInputFocus *focus); diff --git a/clutter/clutter/clutter-input-focus.c b/clutter/clutter/clutter-input-focus.c index 51381ace6..2aea51e24 100644 --- a/clutter/clutter/clutter-input-focus.c +++ b/clutter/clutter/clutter-input-focus.c @@ -89,8 +89,8 @@ clutter_input_focus_reset (ClutterInputFocus *focus) } void -clutter_input_focus_set_cursor_location (ClutterInputFocus *focus, - const ClutterRect *rect) +clutter_input_focus_set_cursor_location (ClutterInputFocus *focus, + const graphene_rect_t *rect) { ClutterInputFocusPrivate *priv; @@ -147,8 +147,8 @@ clutter_input_focus_set_content_purpose (ClutterInputFocus *focus, } gboolean -clutter_input_focus_filter_key_event (ClutterInputFocus *focus, - const ClutterKeyEvent *key) +clutter_input_focus_filter_event (ClutterInputFocus *focus, + const ClutterEvent *event) { ClutterInputFocusPrivate *priv; @@ -157,7 +157,30 @@ clutter_input_focus_filter_key_event (ClutterInputFocus *focus, priv = clutter_input_focus_get_instance_private (focus); - return clutter_input_method_filter_key_event (priv->im, key); + if (event->type == CLUTTER_KEY_PRESS || + event->type == CLUTTER_KEY_RELEASE) + { + return clutter_input_method_filter_key_event (priv->im, &event->key); + } + else if (event->type == CLUTTER_IM_COMMIT) + { + clutter_input_focus_commit (focus, event->im.text); + return TRUE; + } + else if (event->type == CLUTTER_IM_DELETE) + { + clutter_input_focus_delete_surrounding (focus, event->im.offset, + event->im.len); + return TRUE; + } + else if (event->type == CLUTTER_IM_PREEDIT) + { + clutter_input_focus_set_preedit_text (focus, event->im.text, + event->im.offset); + return TRUE; + } + + return FALSE; } void @@ -175,7 +198,8 @@ clutter_input_focus_set_can_show_preedit (ClutterInputFocus *focus, } void -clutter_input_focus_request_toggle_input_panel (ClutterInputFocus *focus) +clutter_input_focus_set_input_panel_state (ClutterInputFocus *focus, + ClutterInputPanelState state) { ClutterInputFocusPrivate *priv; @@ -184,7 +208,7 @@ clutter_input_focus_request_toggle_input_panel (ClutterInputFocus *focus) priv = clutter_input_focus_get_instance_private (focus); - clutter_input_method_toggle_input_panel (priv->im); + clutter_input_method_set_input_panel_state (priv->im, state); } void @@ -216,7 +240,7 @@ clutter_input_focus_commit (ClutterInputFocus *focus, void clutter_input_focus_delete_surrounding (ClutterInputFocus *focus, - guint offset, + int offset, guint len) { g_return_if_fail (CLUTTER_IS_INPUT_FOCUS (focus)); diff --git a/clutter/clutter/clutter-input-focus.h b/clutter/clutter/clutter-input-focus.h index 0eb6c57d3..77f5d9076 100644 --- a/clutter/clutter/clutter-input-focus.h +++ b/clutter/clutter/clutter-input-focus.h @@ -26,7 +26,7 @@ #define CLUTTER_TYPE_INPUT_FOCUS (clutter_input_focus_get_type ()) -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT G_DECLARE_DERIVABLE_TYPE (ClutterInputFocus, clutter_input_focus, CLUTTER, INPUT_FOCUS, GObject) @@ -41,7 +41,7 @@ struct _ClutterInputFocusClass void (* request_surrounding) (ClutterInputFocus *focus); void (* delete_surrounding) (ClutterInputFocus *focus, - guint offset, + int offset, guint len); void (* commit_text) (ClutterInputFocus *focus, const gchar *text); @@ -51,33 +51,34 @@ struct _ClutterInputFocusClass guint cursor); }; -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT gboolean clutter_input_focus_is_focused (ClutterInputFocus *focus); -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT void clutter_input_focus_reset (ClutterInputFocus *focus); -CLUTTER_AVAILABLE_IN_MUFFIN -void clutter_input_focus_set_cursor_location (ClutterInputFocus *focus, - const ClutterRect *rect); +CLUTTER_EXPORT +void clutter_input_focus_set_cursor_location (ClutterInputFocus *focus, + const graphene_rect_t *rect); -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT void clutter_input_focus_set_surrounding (ClutterInputFocus *focus, const gchar *text, guint cursor, guint anchor); -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT void clutter_input_focus_set_content_hints (ClutterInputFocus *focus, ClutterInputContentHintFlags hint); -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT void clutter_input_focus_set_content_purpose (ClutterInputFocus *focus, ClutterInputContentPurpose purpose); -CLUTTER_AVAILABLE_IN_MUFFIN -gboolean clutter_input_focus_filter_key_event (ClutterInputFocus *focus, - const ClutterKeyEvent *key); -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT +gboolean clutter_input_focus_filter_event (ClutterInputFocus *focus, + const ClutterEvent *event); +CLUTTER_EXPORT void clutter_input_focus_set_can_show_preedit (ClutterInputFocus *focus, gboolean can_show_preedit); -CLUTTER_AVAILABLE_IN_MUFFIN -void clutter_input_focus_request_toggle_input_panel (ClutterInputFocus *focus); +CLUTTER_EXPORT +void clutter_input_focus_set_input_panel_state (ClutterInputFocus *focus, + ClutterInputPanelState state); #endif /* __CLUTTER_INPUT_FOCUS_H__ */ diff --git a/clutter/clutter/clutter-input-method-private.h b/clutter/clutter/clutter-input-method-private.h index e8ab2cabf..61e575e7e 100644 --- a/clutter/clutter/clutter-input-method-private.h +++ b/clutter/clutter/clutter-input-method-private.h @@ -26,8 +26,8 @@ ClutterInputFocus * clutter_input_method_get_focus (ClutterInputMethod *method); void clutter_input_method_reset (ClutterInputMethod *method); -void clutter_input_method_set_cursor_location (ClutterInputMethod *method, - const ClutterRect *rect); +void clutter_input_method_set_cursor_location (ClutterInputMethod *method, + const graphene_rect_t *rect); void clutter_input_method_set_surrounding (ClutterInputMethod *method, const gchar *text, guint cursor, diff --git a/clutter/clutter/clutter-input-method.c b/clutter/clutter/clutter-input-method.c index 11d726d7b..69d72f3de 100644 --- a/clutter/clutter/clutter-input-method.c +++ b/clutter/clutter/clutter-input-method.c @@ -22,6 +22,7 @@ #include "clutter-build-config.h" #include "clutter-private.h" +#include "clutter/clutter-input-device-private.h" #include "clutter/clutter-input-method.h" #include "clutter/clutter-input-method-private.h" #include "clutter/clutter-input-focus-private.h" @@ -36,7 +37,8 @@ struct _ClutterInputMethodPrivate gboolean can_show_preedit; }; -enum { +enum +{ COMMIT, DELETE_SURROUNDING, REQUEST_SURROUNDING, @@ -45,7 +47,8 @@ enum { N_SIGNALS, }; -enum { +enum +{ PROP_0, PROP_CONTENT_HINTS, PROP_CONTENT_PURPOSE, @@ -165,7 +168,7 @@ clutter_input_method_class_init (ClutterInputMethodClass *klass) G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, - G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT); + G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_UINT); signals[REQUEST_SURROUNDING] = g_signal_new ("request-surrounding", G_TYPE_FROM_CLASS (object_class), @@ -184,7 +187,7 @@ clutter_input_method_class_init (ClutterInputMethodClass *klass) G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, - G_TYPE_NONE, 1, CLUTTER_TYPE_RECT); + G_TYPE_NONE, 1, GRAPHENE_TYPE_RECT); pspecs[PROP_CONTENT_HINTS] = g_param_spec_flags ("content-hints", @@ -263,9 +266,6 @@ clutter_input_method_focus_out (ClutterInputMethod *im) klass = CLUTTER_INPUT_METHOD_GET_CLASS (im); klass->focus_out (im); - - g_signal_emit (im, signals[INPUT_PANEL_STATE], - 0, CLUTTER_INPUT_PANEL_STATE_OFF); } ClutterInputFocus * @@ -277,31 +277,55 @@ clutter_input_method_get_focus (ClutterInputMethod *im) return priv->focus; } +static void +clutter_input_method_put_im_event (ClutterInputMethod *im, + ClutterEventType event_type, + const gchar *text, + int32_t offset, + uint32_t len) +{ + ClutterInputDevice *keyboard; + ClutterSeat *seat; + ClutterStage *stage; + ClutterEvent *event; + + seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); + keyboard = clutter_seat_get_keyboard (seat); + stage = _clutter_input_device_get_stage (keyboard); + if (stage == NULL) + return; + + event = clutter_event_new (event_type); + event->im.text = g_strdup (text); + event->im.offset = offset; + event->im.len = len; + clutter_event_set_device (event, keyboard); + clutter_event_set_source_device (event, keyboard); + clutter_event_set_flags (event, CLUTTER_EVENT_FLAG_INPUT_METHOD); + + clutter_event_set_stage (event, stage); + + clutter_event_put (event); + clutter_event_free (event); +} + void clutter_input_method_commit (ClutterInputMethod *im, const gchar *text) { - ClutterInputMethodPrivate *priv; - g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im)); - priv = clutter_input_method_get_instance_private (im); - if (priv->focus) - clutter_input_focus_commit (priv->focus, text); + clutter_input_method_put_im_event (im, CLUTTER_IM_COMMIT, text, 0, 0); } void clutter_input_method_delete_surrounding (ClutterInputMethod *im, - guint offset, + int offset, guint len) { - ClutterInputMethodPrivate *priv; - g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im)); - priv = clutter_input_method_get_instance_private (im); - if (priv->focus) - clutter_input_focus_delete_surrounding (priv->focus, offset, len); + clutter_input_method_put_im_event (im, CLUTTER_IM_DELETE, NULL, offset, len); } void @@ -329,13 +353,9 @@ clutter_input_method_set_preedit_text (ClutterInputMethod *im, const gchar *preedit, guint cursor) { - ClutterInputMethodPrivate *priv; - g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im)); - priv = clutter_input_method_get_instance_private (im); - if (priv->focus) - clutter_input_focus_set_preedit_text (priv->focus, preedit, cursor); + clutter_input_method_put_im_event (im, CLUTTER_IM_PREEDIT, preedit, cursor, 0); } void @@ -360,12 +380,12 @@ clutter_input_method_notify_key_event (ClutterInputMethod *im, } void -clutter_input_method_toggle_input_panel (ClutterInputMethod *im) +clutter_input_method_set_input_panel_state (ClutterInputMethod *im, + ClutterInputPanelState state) { g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im)); - g_signal_emit (im, signals[INPUT_PANEL_STATE], 0, - CLUTTER_INPUT_PANEL_STATE_TOGGLE); + g_signal_emit (im, signals[INPUT_PANEL_STATE], 0, state); } void @@ -377,8 +397,8 @@ clutter_input_method_reset (ClutterInputMethod *im) } void -clutter_input_method_set_cursor_location (ClutterInputMethod *im, - const ClutterRect *rect) +clutter_input_method_set_cursor_location (ClutterInputMethod *im, + const graphene_rect_t *rect) { g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im)); @@ -442,3 +462,45 @@ clutter_input_method_filter_key_event (ClutterInputMethod *im, return im_class->filter_key_event (im, (const ClutterEvent *) key); } + +void +clutter_input_method_forward_key (ClutterInputMethod *im, + uint32_t keyval, + uint32_t keycode, + uint32_t state, + uint64_t time_, + gboolean press) +{ + ClutterInputMethodPrivate *priv; + ClutterInputDevice *keyboard; + ClutterSeat *seat; + ClutterStage *stage; + ClutterEvent *event; + + g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im)); + + priv = clutter_input_method_get_instance_private (im); + if (!priv->focus) + return; + + seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); + keyboard = clutter_seat_get_keyboard (seat); + stage = _clutter_input_device_get_stage (keyboard); + if (stage == NULL) + return; + + event = clutter_event_new (press ? CLUTTER_KEY_PRESS : CLUTTER_KEY_RELEASE); + event->key.time = time_; + event->key.flags = CLUTTER_EVENT_FLAG_INPUT_METHOD; + event->key.modifier_state = state; + event->key.keyval = keyval; + event->key.hardware_keycode = keycode; + event->key.unicode_value = clutter_keysym_to_unicode (keyval); + + clutter_event_set_device (event, keyboard); + clutter_event_set_source_device (event, keyboard); + clutter_event_set_stage (event, stage); + + clutter_event_put (event); + clutter_event_free (event); +} diff --git a/clutter/clutter/clutter-input-method.h b/clutter/clutter/clutter-input-method.h index eef86dfdd..b7f9a474e 100644 --- a/clutter/clutter/clutter-input-method.h +++ b/clutter/clutter/clutter-input-method.h @@ -26,7 +26,7 @@ #define CLUTTER_TYPE_INPUT_METHOD (clutter_input_method_get_type ()) -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT G_DECLARE_DERIVABLE_TYPE (ClutterInputMethod, clutter_input_method, CLUTTER, INPUT_METHOD, GObject) @@ -42,8 +42,8 @@ struct _ClutterInputMethodClass void (* reset) (ClutterInputMethod *im); - void (* set_cursor_location) (ClutterInputMethod *im, - const ClutterRect *rect); + void (* set_cursor_location) (ClutterInputMethod *im, + const graphene_rect_t *rect); void (* set_surrounding) (ClutterInputMethod *im, const gchar *text, guint cursor, @@ -57,32 +57,41 @@ struct _ClutterInputMethodClass const ClutterEvent *key); }; -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT void clutter_input_method_focus_in (ClutterInputMethod *im, ClutterInputFocus *focus); -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT void clutter_input_method_focus_out (ClutterInputMethod *im); -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT void clutter_input_method_commit (ClutterInputMethod *im, const gchar *text); -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT void clutter_input_method_delete_surrounding (ClutterInputMethod *im, - guint offset, + int offset, guint len); -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT void clutter_input_method_request_surrounding (ClutterInputMethod *im); -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT void clutter_input_method_set_preedit_text (ClutterInputMethod *im, const gchar *preedit, guint cursor); -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT void clutter_input_method_notify_key_event (ClutterInputMethod *im, const ClutterEvent *event, gboolean filtered); -CLUTTER_AVAILABLE_IN_MUFFIN -void clutter_input_method_request_toggle_input_panel (ClutterInputMethod *im); +CLUTTER_EXPORT +void clutter_input_method_set_input_panel_state (ClutterInputMethod *im, + ClutterInputPanelState state); + +CLUTTER_EXPORT +void clutter_input_method_forward_key (ClutterInputMethod *im, + uint32_t keyval, + uint32_t keycode, + uint32_t state, + uint64_t time_, + gboolean press); #endif /* __CLUTTER_INPUT_METHOD_H__ */ diff --git a/clutter/clutter/clutter-input-pointer-a11y-private.h b/clutter/clutter/clutter-input-pointer-a11y-private.h new file mode 100644 index 000000000..fbbe04101 --- /dev/null +++ b/clutter/clutter/clutter-input-pointer-a11y-private.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2019 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Olivier Fourdan + */ + +#ifndef __CLUTTER_INPUT_POINTER_A11Y_H__ +#define __CLUTTER_INPUT_POINTER_A11Y_H__ + +#include +#include "clutter-enum-types.h" + +G_BEGIN_DECLS + +CLUTTER_EXPORT +void _clutter_input_pointer_a11y_add_device (ClutterInputDevice *device); +CLUTTER_EXPORT +void _clutter_input_pointer_a11y_remove_device (ClutterInputDevice *device); +CLUTTER_EXPORT +void _clutter_input_pointer_a11y_on_motion_event (ClutterInputDevice *device, + float x, + float y); +CLUTTER_EXPORT +void _clutter_input_pointer_a11y_on_button_event (ClutterInputDevice *device, + int button, + gboolean pressed); +CLUTTER_EXPORT +gboolean _clutter_is_input_pointer_a11y_enabled (ClutterInputDevice *device); + +G_END_DECLS + +#endif /* __CLUTTER_INPUT_POINTER_A11Y_H__ */ diff --git a/clutter/clutter/clutter-input-pointer-a11y.c b/clutter/clutter/clutter-input-pointer-a11y.c new file mode 100644 index 000000000..b57ee81c0 --- /dev/null +++ b/clutter/clutter/clutter-input-pointer-a11y.c @@ -0,0 +1,706 @@ +/* + * Copyright (C) 2019 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Olivier Fourdan + * + * This reimplements in Clutter the same behavior as mousetweaks original + * implementation by Gerd Kohlberger + * mousetweaks Copyright (C) 2007-2010 Gerd Kohlberger + */ + +#include "clutter-build-config.h" + +#include "clutter-enum-types.h" +#include "clutter-input-device.h" +#include "clutter-input-device-private.h" +#include "clutter-input-pointer-a11y-private.h" +#include "clutter-main.h" +#include "clutter-virtual-input-device.h" + +static gboolean +is_secondary_click_enabled (ClutterInputDevice *device) +{ + ClutterPointerA11ySettings settings; + + clutter_seat_get_pointer_a11y_settings (device->seat, &settings); + + return (settings.controls & CLUTTER_A11Y_SECONDARY_CLICK_ENABLED); +} + +static gboolean +is_dwell_click_enabled (ClutterInputDevice *device) +{ + ClutterPointerA11ySettings settings; + + clutter_seat_get_pointer_a11y_settings (device->seat, &settings); + + return (settings.controls & CLUTTER_A11Y_DWELL_ENABLED); +} + +static unsigned int +get_secondary_click_delay (ClutterInputDevice *device) +{ + ClutterPointerA11ySettings settings; + + clutter_seat_get_pointer_a11y_settings (device->seat, &settings); + + return settings.secondary_click_delay; +} + +static unsigned int +get_dwell_delay (ClutterInputDevice *device) +{ + ClutterPointerA11ySettings settings; + + clutter_seat_get_pointer_a11y_settings (device->seat, &settings); + + return settings.dwell_delay; +} + +static unsigned int +get_dwell_threshold (ClutterInputDevice *device) +{ + ClutterPointerA11ySettings settings; + + clutter_seat_get_pointer_a11y_settings (device->seat, &settings); + + return settings.dwell_threshold; +} + +static ClutterPointerA11yDwellMode +get_dwell_mode (ClutterInputDevice *device) +{ + ClutterPointerA11ySettings settings; + + clutter_seat_get_pointer_a11y_settings (device->seat, &settings); + + return settings.dwell_mode; +} + +static ClutterPointerA11yDwellClickType +get_dwell_click_type (ClutterInputDevice *device) +{ + ClutterPointerA11ySettings settings; + + clutter_seat_get_pointer_a11y_settings (device->seat, &settings); + + return settings.dwell_click_type; +} + +static ClutterPointerA11yDwellClickType +get_dwell_click_type_for_direction (ClutterInputDevice *device, + ClutterPointerA11yDwellDirection direction) +{ + ClutterPointerA11ySettings settings; + + clutter_seat_get_pointer_a11y_settings (device->seat, &settings); + + if (direction == settings.dwell_gesture_single) + return CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY; + else if (direction == settings.dwell_gesture_double) + return CLUTTER_A11Y_DWELL_CLICK_TYPE_DOUBLE; + else if (direction == settings.dwell_gesture_drag) + return CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG; + else if (direction == settings.dwell_gesture_secondary) + return CLUTTER_A11Y_DWELL_CLICK_TYPE_SECONDARY; + + return CLUTTER_A11Y_DWELL_CLICK_TYPE_NONE; +} + +static void +emit_button_press (ClutterInputDevice *device, + gint button) +{ + clutter_virtual_input_device_notify_button (device->accessibility_virtual_device, + g_get_monotonic_time (), + button, + CLUTTER_BUTTON_STATE_PRESSED); +} + +static void +emit_button_release (ClutterInputDevice *device, + gint button) +{ + clutter_virtual_input_device_notify_button (device->accessibility_virtual_device, + g_get_monotonic_time (), + button, + CLUTTER_BUTTON_STATE_RELEASED); +} + +static void +emit_button_click (ClutterInputDevice *device, + gint button) +{ + emit_button_press (device, button); + emit_button_release (device, button); +} + +static void +restore_dwell_position (ClutterInputDevice *device) +{ + clutter_virtual_input_device_notify_absolute_motion (device->accessibility_virtual_device, + g_get_monotonic_time (), + device->ptr_a11y_data->dwell_x, + device->ptr_a11y_data->dwell_y); +} + +static gboolean +trigger_secondary_click (gpointer data) +{ + ClutterInputDevice *device = data; + + device->ptr_a11y_data->secondary_click_triggered = TRUE; + device->ptr_a11y_data->secondary_click_timer = 0; + + g_signal_emit_by_name (device->seat, + "ptr-a11y-timeout-stopped", + device, + CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK, + TRUE); + + return G_SOURCE_REMOVE; +} + +static void +start_secondary_click_timeout (ClutterInputDevice *device) +{ + unsigned int delay = get_secondary_click_delay (device); + + device->ptr_a11y_data->secondary_click_timer = + clutter_threads_add_timeout (delay, trigger_secondary_click, device); + + g_signal_emit_by_name (device->seat, + "ptr-a11y-timeout-started", + device, + CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK, + delay); +} + +static void +stop_secondary_click_timeout (ClutterInputDevice *device) +{ + if (device->ptr_a11y_data->secondary_click_timer) + { + g_clear_handle_id (&device->ptr_a11y_data->secondary_click_timer, + g_source_remove); + + g_signal_emit_by_name (device->seat, + "ptr-a11y-timeout-stopped", + device, + CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK, + FALSE); + } + device->ptr_a11y_data->secondary_click_triggered = FALSE; +} + +static gboolean +pointer_has_moved (ClutterInputDevice *device) +{ + float dx, dy; + gint threshold; + + dx = device->ptr_a11y_data->dwell_x - device->ptr_a11y_data->current_x; + dy = device->ptr_a11y_data->dwell_y - device->ptr_a11y_data->current_y; + threshold = get_dwell_threshold (device); + + /* Pythagorean theorem */ + return ((dx * dx) + (dy * dy)) > (threshold * threshold); +} + +static gboolean +is_secondary_click_pending (ClutterInputDevice *device) +{ + return device->ptr_a11y_data->secondary_click_timer != 0; +} + +static gboolean +is_secondary_click_triggered (ClutterInputDevice *device) +{ + return device->ptr_a11y_data->secondary_click_triggered; +} + +static gboolean +is_dwell_click_pending (ClutterInputDevice *device) +{ + return device->ptr_a11y_data->dwell_timer != 0; +} + +static gboolean +is_dwell_dragging (ClutterInputDevice *device) +{ + return device->ptr_a11y_data->dwell_drag_started; +} + +static gboolean +is_dwell_gesturing (ClutterInputDevice *device) +{ + return device->ptr_a11y_data->dwell_gesture_started; +} + +static gboolean +has_button_pressed (ClutterInputDevice *device) +{ + return device->ptr_a11y_data->n_btn_pressed > 0; +} + +static gboolean +should_start_secondary_click_timeout (ClutterInputDevice *device) +{ + return !is_dwell_dragging (device); +} + +static gboolean +should_start_dwell (ClutterInputDevice *device) +{ + /* We should trigger a dwell if we've not already started one, and if + * no button is currently pressed or we are in the middle of a dwell + * drag action. + */ + return !is_dwell_click_pending (device) && + (is_dwell_dragging (device) || + !has_button_pressed (device)); +} + +static gboolean +should_stop_dwell (ClutterInputDevice *device) +{ + /* We should stop a dwell if the motion exceeds the threshold, unless + * we've started a gesture, because we want to keep the original dwell + * location to both detect a gesture and restore the original pointer + * location once the gesture is finished. + */ + return pointer_has_moved (device) && + !is_dwell_gesturing (device); +} + + +static gboolean +should_update_dwell_position (ClutterInputDevice *device) +{ + return !is_dwell_gesturing (device) && + !is_dwell_click_pending (device) && + !is_secondary_click_pending (device); +} + +static void +update_dwell_click_type (ClutterInputDevice *device) +{ + ClutterPointerA11ySettings settings; + ClutterPointerA11yDwellClickType dwell_click_type; + + clutter_seat_get_pointer_a11y_settings (device->seat, &settings); + + dwell_click_type = settings.dwell_click_type; + switch (dwell_click_type) + { + case CLUTTER_A11Y_DWELL_CLICK_TYPE_DOUBLE: + case CLUTTER_A11Y_DWELL_CLICK_TYPE_SECONDARY: + case CLUTTER_A11Y_DWELL_CLICK_TYPE_MIDDLE: + dwell_click_type = CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY; + break; + + case CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG: + if (!is_dwell_dragging (device)) + dwell_click_type = CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY; + break; + + case CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY: + case CLUTTER_A11Y_DWELL_CLICK_TYPE_NONE: + default: + break; + } + + if (dwell_click_type != settings.dwell_click_type) + { + settings.dwell_click_type = dwell_click_type; + clutter_seat_set_pointer_a11y_settings (device->seat, &settings); + + g_signal_emit_by_name (device->seat, + "ptr-a11y-dwell-click-type-changed", + dwell_click_type); + } +} + +static void +emit_dwell_click (ClutterInputDevice *device, + ClutterPointerA11yDwellClickType dwell_click_type) +{ + switch (dwell_click_type) + { + case CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY: + emit_button_click (device, CLUTTER_BUTTON_PRIMARY); + break; + + case CLUTTER_A11Y_DWELL_CLICK_TYPE_DOUBLE: + emit_button_click (device, CLUTTER_BUTTON_PRIMARY); + emit_button_click (device, CLUTTER_BUTTON_PRIMARY); + break; + + case CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG: + if (is_dwell_dragging (device)) + { + emit_button_release (device, CLUTTER_BUTTON_PRIMARY); + device->ptr_a11y_data->dwell_drag_started = FALSE; + } + else + { + emit_button_press (device, CLUTTER_BUTTON_PRIMARY); + device->ptr_a11y_data->dwell_drag_started = TRUE; + } + break; + + case CLUTTER_A11Y_DWELL_CLICK_TYPE_SECONDARY: + emit_button_click (device, CLUTTER_BUTTON_SECONDARY); + break; + + case CLUTTER_A11Y_DWELL_CLICK_TYPE_MIDDLE: + emit_button_click (device, CLUTTER_BUTTON_MIDDLE); + break; + + case CLUTTER_A11Y_DWELL_CLICK_TYPE_NONE: + default: + break; + } +} + +static ClutterPointerA11yDwellDirection +get_dwell_direction (ClutterInputDevice *device) +{ + float dx, dy; + + dx = ABS (device->ptr_a11y_data->dwell_x - device->ptr_a11y_data->current_x); + dy = ABS (device->ptr_a11y_data->dwell_y - device->ptr_a11y_data->current_y); + + /* The pointer hasn't moved */ + if (!pointer_has_moved (device)) + return CLUTTER_A11Y_DWELL_DIRECTION_NONE; + + if (device->ptr_a11y_data->dwell_x < device->ptr_a11y_data->current_x) + { + if (dx > dy) + return CLUTTER_A11Y_DWELL_DIRECTION_LEFT; + } + else + { + if (dx > dy) + return CLUTTER_A11Y_DWELL_DIRECTION_RIGHT; + } + + if (device->ptr_a11y_data->dwell_y < device->ptr_a11y_data->current_y) + return CLUTTER_A11Y_DWELL_DIRECTION_UP; + + return CLUTTER_A11Y_DWELL_DIRECTION_DOWN; +} + +static gboolean +trigger_clear_dwell_gesture (gpointer data) +{ + ClutterInputDevice *device = data; + + device->ptr_a11y_data->dwell_timer = 0; + device->ptr_a11y_data->dwell_gesture_started = FALSE; + + return G_SOURCE_REMOVE; +} + +static gboolean +trigger_dwell_gesture (gpointer data) +{ + ClutterInputDevice *device = data; + ClutterPointerA11yDwellDirection direction; + unsigned int delay = get_dwell_delay (device); + + restore_dwell_position (device); + direction = get_dwell_direction (device); + emit_dwell_click (device, + get_dwell_click_type_for_direction (device, + direction)); + + /* Do not clear the gesture right away, otherwise we'll start another one */ + device->ptr_a11y_data->dwell_timer = + clutter_threads_add_timeout (delay, trigger_clear_dwell_gesture, device); + + g_signal_emit_by_name (device->seat, + "ptr-a11y-timeout-stopped", + device, + CLUTTER_A11Y_TIMEOUT_TYPE_GESTURE, + TRUE); + + return G_SOURCE_REMOVE; +} + +static void +start_dwell_gesture_timeout (ClutterInputDevice *device) +{ + unsigned int delay = get_dwell_delay (device); + + device->ptr_a11y_data->dwell_timer = + clutter_threads_add_timeout (delay, trigger_dwell_gesture, device); + device->ptr_a11y_data->dwell_gesture_started = TRUE; + + g_signal_emit_by_name (device->seat, + "ptr-a11y-timeout-started", + device, + CLUTTER_A11Y_TIMEOUT_TYPE_GESTURE, + delay); +} + +static gboolean +trigger_dwell_click (gpointer data) +{ + ClutterInputDevice *device = data; + + device->ptr_a11y_data->dwell_timer = 0; + + g_signal_emit_by_name (device->seat, + "ptr-a11y-timeout-stopped", + device, + CLUTTER_A11Y_TIMEOUT_TYPE_DWELL, + TRUE); + + if (get_dwell_mode (device) == CLUTTER_A11Y_DWELL_MODE_GESTURE) + { + if (is_dwell_dragging (device)) + emit_dwell_click (device, CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG); + else + start_dwell_gesture_timeout (device); + } + else + { + emit_dwell_click (device, get_dwell_click_type (device)); + update_dwell_click_type (device); + } + + return G_SOURCE_REMOVE; +} + +static void +start_dwell_timeout (ClutterInputDevice *device) +{ + unsigned int delay = get_dwell_delay (device); + + device->ptr_a11y_data->dwell_timer = + clutter_threads_add_timeout (delay, trigger_dwell_click, device); + + g_signal_emit_by_name (device->seat, + "ptr-a11y-timeout-started", + device, + CLUTTER_A11Y_TIMEOUT_TYPE_DWELL, + delay); +} + +static void +stop_dwell_timeout (ClutterInputDevice *device) +{ + if (device->ptr_a11y_data->dwell_timer) + { + g_clear_handle_id (&device->ptr_a11y_data->dwell_timer, g_source_remove); + device->ptr_a11y_data->dwell_gesture_started = FALSE; + + g_signal_emit_by_name (device->seat, + "ptr-a11y-timeout-stopped", + device, + CLUTTER_A11Y_TIMEOUT_TYPE_DWELL, + FALSE); + } +} + +static gboolean +trigger_dwell_position_timeout (gpointer data) +{ + ClutterInputDevice *device = data; + + device->ptr_a11y_data->dwell_position_timer = 0; + + if (is_dwell_click_enabled (device)) + { + if (!pointer_has_moved (device)) + start_dwell_timeout (device); + } + + return G_SOURCE_REMOVE; +} + +static void +start_dwell_position_timeout (ClutterInputDevice *device) +{ + device->ptr_a11y_data->dwell_position_timer = + clutter_threads_add_timeout (100, trigger_dwell_position_timeout, device); +} + +static void +stop_dwell_position_timeout (ClutterInputDevice *device) +{ + g_clear_handle_id (&device->ptr_a11y_data->dwell_position_timer, + g_source_remove); +} + +static void +update_dwell_position (ClutterInputDevice *device) +{ + device->ptr_a11y_data->dwell_x = device->ptr_a11y_data->current_x; + device->ptr_a11y_data->dwell_y = device->ptr_a11y_data->current_y; +} + +static void +update_current_position (ClutterInputDevice *device, + float x, + float y) +{ + device->ptr_a11y_data->current_x = x; + device->ptr_a11y_data->current_y = y; +} + +static gboolean +is_device_core_pointer (ClutterInputDevice *device) +{ + ClutterInputDevice *core_pointer; + + core_pointer = clutter_seat_get_pointer (device->seat); + if (core_pointer == NULL) + return FALSE; + + return (core_pointer == device); +} + +void +_clutter_input_pointer_a11y_add_device (ClutterInputDevice *device) +{ + if (!is_device_core_pointer (device)) + return; + + device->accessibility_virtual_device = + clutter_seat_create_virtual_device (device->seat, + CLUTTER_POINTER_DEVICE); + + device->ptr_a11y_data = g_new0 (ClutterPtrA11yData, 1); +} + +void +_clutter_input_pointer_a11y_remove_device (ClutterInputDevice *device) +{ + if (!is_device_core_pointer (device)) + return; + + /* Terminate a drag if started */ + if (is_dwell_dragging (device)) + emit_dwell_click (device, CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG); + + stop_dwell_position_timeout (device); + stop_dwell_timeout (device); + stop_secondary_click_timeout (device); + + g_clear_pointer (&device->ptr_a11y_data, g_free); +} + +void +_clutter_input_pointer_a11y_on_motion_event (ClutterInputDevice *device, + float x, + float y) +{ + if (!is_device_core_pointer (device)) + return; + + if (!_clutter_is_input_pointer_a11y_enabled (device)) + return; + + update_current_position (device, x, y); + + if (is_secondary_click_enabled (device)) + { + if (pointer_has_moved (device)) + stop_secondary_click_timeout (device); + } + + if (is_dwell_click_enabled (device)) + { + stop_dwell_position_timeout (device); + + if (should_stop_dwell (device)) + stop_dwell_timeout (device); + + if (should_start_dwell (device)) + start_dwell_position_timeout (device); + } + + if (should_update_dwell_position (device)) + update_dwell_position (device); +} + +void +_clutter_input_pointer_a11y_on_button_event (ClutterInputDevice *device, + int button, + gboolean pressed) +{ + if (!is_device_core_pointer (device)) + return; + + if (!_clutter_is_input_pointer_a11y_enabled (device)) + return; + + if (pressed) + { + device->ptr_a11y_data->n_btn_pressed++; + + stop_dwell_position_timeout (device); + + if (is_dwell_click_enabled (device)) + stop_dwell_timeout (device); + + if (is_dwell_dragging (device)) + stop_dwell_timeout (device); + + if (is_secondary_click_enabled (device)) + { + if (button == CLUTTER_BUTTON_PRIMARY) + { + if (should_start_secondary_click_timeout (device)) + start_secondary_click_timeout (device); + } + else if (is_secondary_click_pending (device)) + { + stop_secondary_click_timeout (device); + } + } + } + else + { + if (has_button_pressed (device)) + device->ptr_a11y_data->n_btn_pressed--; + + if (is_secondary_click_triggered (device)) + { + emit_button_click (device, CLUTTER_BUTTON_SECONDARY); + stop_secondary_click_timeout (device); + } + + if (is_secondary_click_pending (device)) + stop_secondary_click_timeout (device); + + if (is_dwell_dragging (device)) + emit_dwell_click (device, CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG); + } +} + +gboolean +_clutter_is_input_pointer_a11y_enabled (ClutterInputDevice *device) +{ + g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE); + + return (is_secondary_click_enabled (device) || is_dwell_click_enabled (device)); +} diff --git a/clutter/clutter/clutter-interval.c b/clutter/clutter/clutter-interval.c index e0085af38..6f14287b4 100644 --- a/clutter/clutter/clutter-interval.c +++ b/clutter/clutter/clutter-interval.c @@ -398,7 +398,7 @@ clutter_interval_finalize (GObject *gobject) if (G_IS_VALUE (&priv->values[RESULT])) g_value_unset (&priv->values[RESULT]); - free (priv->values); + g_free (priv->values); G_OBJECT_CLASS (clutter_interval_parent_class)->finalize (gobject); } @@ -445,7 +445,7 @@ clutter_interval_get_property (GObject *gobject, GParamSpec *pspec) { ClutterIntervalPrivate *priv; - + priv = clutter_interval_get_instance_private (CLUTTER_INTERVAL (gobject)); switch (prop_id) @@ -578,7 +578,7 @@ clutter_interval_init (ClutterInterval *self) self->priv = clutter_interval_get_instance_private (self); self->priv->value_type = G_TYPE_INVALID; - self->priv->values = calloc (1, sizeof (GValue) * N_VALUES); + self->priv->values = g_malloc0 (sizeof (GValue) * N_VALUES); } static inline void @@ -661,7 +661,7 @@ clutter_interval_set_initial_internal (ClutterInterval *interval, * given the error and calling g_value_unset() might lead to * undefined behaviour */ - free (error); + g_free (error); return FALSE; } @@ -690,7 +690,7 @@ clutter_interval_set_final_internal (ClutterInterval *interval, * given the error and calling g_value_unset() might lead to * undefined behaviour */ - free (error); + g_free (error); return FALSE; } @@ -715,7 +715,7 @@ clutter_interval_get_interval_valist (ClutterInterval *interval, if (error) { g_warning ("%s: %s", G_STRLOC, error); - free (error); + g_free (error); g_value_unset (&value); return; } @@ -729,7 +729,7 @@ clutter_interval_get_interval_valist (ClutterInterval *interval, if (error) { g_warning ("%s: %s", G_STRLOC, error); - free (error); + g_free (error); g_value_unset (&value); return; } diff --git a/clutter/clutter/clutter-interval.h b/clutter/clutter/clutter-interval.h index f3d62cbcf..99b0cc099 100644 --- a/clutter/clutter/clutter-interval.h +++ b/clutter/clutter/clutter-interval.h @@ -92,66 +92,66 @@ struct _ClutterIntervalClass void (*_clutter_reserved6) (void); }; -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT GType clutter_interval_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT ClutterInterval *clutter_interval_new (GType gtype, ...); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT ClutterInterval *clutter_interval_new_with_values (GType gtype, const GValue *initial, const GValue *final); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT ClutterInterval *clutter_interval_clone (ClutterInterval *interval); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT GType clutter_interval_get_value_type (ClutterInterval *interval); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_interval_set_initial (ClutterInterval *interval, ...); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_interval_set_initial_value (ClutterInterval *interval, const GValue *value); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_interval_get_initial_value (ClutterInterval *interval, GValue *value); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT GValue * clutter_interval_peek_initial_value (ClutterInterval *interval); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_interval_set_final (ClutterInterval *interval, ...); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_interval_set_final_value (ClutterInterval *interval, const GValue *value); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_interval_get_final_value (ClutterInterval *interval, GValue *value); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT GValue * clutter_interval_peek_final_value (ClutterInterval *interval); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_interval_set_interval (ClutterInterval *interval, ...); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_interval_get_interval (ClutterInterval *interval, ...); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT gboolean clutter_interval_validate (ClutterInterval *interval, GParamSpec *pspec); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT gboolean clutter_interval_compute_value (ClutterInterval *interval, gdouble factor, GValue *value); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT const GValue * clutter_interval_compute (ClutterInterval *interval, gdouble factor); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT gboolean clutter_interval_is_valid (ClutterInterval *interval); G_END_DECLS diff --git a/clutter/clutter/clutter-keyframe-transition.c b/clutter/clutter/clutter-keyframe-transition.c index 608fe2020..d278109cb 100644 --- a/clutter/clutter/clutter-keyframe-transition.c +++ b/clutter/clutter/clutter-keyframe-transition.c @@ -62,9 +62,7 @@ * #ClutterKeyframeTransition is available since Clutter 1.12. */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include "clutter-keyframe-transition.h" @@ -121,7 +119,7 @@ sort_by_key (gconstpointer a, if (fabs (k_a->key - k_b->key) < 0.0001) return 0; - if (k_a->key > k_a->key) + if (k_a->key > k_b->key) return 1; return -1; @@ -321,8 +319,8 @@ clutter_keyframe_transition_compute_value (ClutterTransition *transition, to, p, real_progress); - free (from); - free (to); + g_free (from); + g_free (to); } #endif /* CLUTTER_ENABLE_DEBUG */ @@ -593,7 +591,7 @@ clutter_keyframe_transition_set (ClutterKeyframeTransition *transition, if (error != NULL) { g_warning ("%s: %s", G_STRLOC, error); - free (error); + g_free (error); break; } diff --git a/clutter/clutter/clutter-keyframe-transition.h b/clutter/clutter/clutter-keyframe-transition.h index d0fe84e01..2b3746f71 100644 --- a/clutter/clutter/clutter-keyframe-transition.h +++ b/clutter/clutter/clutter-keyframe-transition.h @@ -75,46 +75,46 @@ struct _ClutterKeyframeTransitionClass gpointer _padding[8]; }; -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT GType clutter_keyframe_transition_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT ClutterTransition * clutter_keyframe_transition_new (const char *property_name); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_keyframe_transition_set_key_frames (ClutterKeyframeTransition *transition, guint n_key_frames, const double *key_frames); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_keyframe_transition_set_values (ClutterKeyframeTransition *transition, guint n_values, const GValue *values); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_keyframe_transition_set_modes (ClutterKeyframeTransition *transition, guint n_modes, const ClutterAnimationMode *modes); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_keyframe_transition_set (ClutterKeyframeTransition *transition, GType gtype, guint n_key_frames, ...); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_keyframe_transition_set_key_frame (ClutterKeyframeTransition *transition, guint index_, double key, ClutterAnimationMode mode, const GValue *value); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_keyframe_transition_get_key_frame (ClutterKeyframeTransition *transition, guint index_, double *key, ClutterAnimationMode *mode, GValue *value); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT guint clutter_keyframe_transition_get_n_key_frames (ClutterKeyframeTransition *transition); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_keyframe_transition_clear (ClutterKeyframeTransition *transition); G_END_DECLS diff --git a/clutter/clutter/clutter-keymap.c b/clutter/clutter/clutter-keymap.c new file mode 100644 index 000000000..cdeb8f257 --- /dev/null +++ b/clutter/clutter/clutter-keymap.c @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2018 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho + */ + +#include "clutter-build-config.h" + +#include "clutter-keymap.h" +#include "clutter-private.h" + +G_DEFINE_ABSTRACT_TYPE (ClutterKeymap, clutter_keymap, G_TYPE_OBJECT) + +enum +{ + STATE_CHANGED, + N_SIGNALS +}; + +static guint signals[N_SIGNALS] = { 0, }; + +static void +clutter_keymap_class_init (ClutterKeymapClass *klass) +{ + signals[STATE_CHANGED] = + g_signal_new (I_("state-changed"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +static void +clutter_keymap_init (ClutterKeymap *keymap) +{ +} + +gboolean +clutter_keymap_get_num_lock_state (ClutterKeymap *keymap) +{ + return CLUTTER_KEYMAP_GET_CLASS (keymap)->get_num_lock_state (keymap); +} + +gboolean +clutter_keymap_get_caps_lock_state (ClutterKeymap *keymap) +{ + return CLUTTER_KEYMAP_GET_CLASS (keymap)->get_caps_lock_state (keymap); +} + +PangoDirection +clutter_keymap_get_direction (ClutterKeymap *keymap) +{ + return CLUTTER_KEYMAP_GET_CLASS (keymap)->get_direction (keymap); +} diff --git a/clutter/clutter/clutter-keymap.h b/clutter/clutter/clutter-keymap.h new file mode 100644 index 000000000..40be12ea3 --- /dev/null +++ b/clutter/clutter/clutter-keymap.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2018 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho + */ + +#ifndef CLUTTER_KEYMAP_H +#define CLUTTER_KEYMAP_H + +#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +#include +#include + +typedef struct _ClutterKeymap ClutterKeymap; +typedef struct _ClutterKeymapClass ClutterKeymapClass; + +struct _ClutterKeymapClass +{ + GObjectClass parent_class; + + gboolean (* get_num_lock_state) (ClutterKeymap *keymap); + gboolean (* get_caps_lock_state) (ClutterKeymap *keymap); + PangoDirection (* get_direction) (ClutterKeymap *keymap); +}; + +#define CLUTTER_TYPE_KEYMAP (clutter_keymap_get_type ()) +CLUTTER_EXPORT +G_DECLARE_DERIVABLE_TYPE (ClutterKeymap, clutter_keymap, + CLUTTER, KEYMAP, + GObject) + +CLUTTER_EXPORT +gboolean clutter_keymap_get_num_lock_state (ClutterKeymap *keymap); + +CLUTTER_EXPORT +gboolean clutter_keymap_get_caps_lock_state (ClutterKeymap *keymap); + +PangoDirection clutter_keymap_get_direction (ClutterKeymap *keymap); + +#endif /* CLUTTER_KEYMAP_H */ diff --git a/clutter/clutter/clutter-keysyms-update.pl b/clutter/clutter/clutter-keysyms-update.pl index 35440ee97..37469e9e9 100755 --- a/clutter/clutter/clutter-keysyms-update.pl +++ b/clutter/clutter/clutter-keysyms-update.pl @@ -58,10 +58,6 @@ die "Could not open file clutter-keysyms.h: $!\n" unless open(OUT_KEYSYMS, ">:utf8", "clutter-keysyms.h"); -# Output: clutter/clutter/deprecated/clutter-keysyms.h -die "Could not open file clutter-keysyms-compat.h: $!\n" - unless open(OUT_KEYSYMS_COMPAT, ">:utf8", "deprecated/clutter-keysyms.h"); - my $LICENSE_HEADER= <) { next if ( ! /^#define / ); @@ -137,13 +115,8 @@ my $element = $keysymelements[1]; my $binding = $element; $binding =~ s/^XK_/CLUTTER_KEY_/g; - my $compat_binding = $element; - $compat_binding =~ s/^XK_/CLUTTER_/g; - - my $deprecation = "CLUTTER_DEPRECATED_MACRO_FOR(\"Deprecated key symbol. Use $binding instead.\")"; printf OUT_KEYSYMS "#define %s 0x%03x\n", $binding, hex($keysymelements[2]); - printf OUT_KEYSYMS_COMPAT "#define %s 0x%03x %s\n", $compat_binding, hex($keysymelements[2]), $deprecation; } close IN_KEYSYMDEF; @@ -187,11 +160,8 @@ my $element = $keysymelements[1]; my $binding = $element; $binding =~ s/^XF86XK_/CLUTTER_KEY_/g; - my $compat_binding = $element; - $compat_binding =~ s/^XF86XK_/CLUTTER_/g; printf OUT_KEYSYMS "#define %s 0x%03x\n", $binding, hex($keysymelements[2]); - printf OUT_KEYSYMS_COMPAT "#define %s 0x%03x\n", $compat_binding, hex($keysymelements[2]); } close IN_XF86KEYSYM; @@ -202,13 +172,6 @@ #endif /* __CLUTTER_KEYSYMS_H__ */ EOF -print OUT_KEYSYMS_COMPAT< #include @@ -331,9 +329,6 @@ layout_manager_real_begin_animation (ClutterLayoutManager *manager, /* let the alpha take ownership of the timeline */ g_object_unref (timeline); - g_signal_connect_swapped (timeline, "completed", - G_CALLBACK (clutter_layout_manager_end_animation), - manager); g_signal_connect_swapped (timeline, "new-frame", G_CALLBACK (clutter_layout_manager_layout_changed), manager); @@ -377,9 +372,6 @@ layout_manager_real_end_animation (ClutterLayoutManager *manager) if (clutter_timeline_is_playing (timeline)) clutter_timeline_stop (timeline); - g_signal_handlers_disconnect_by_func (timeline, - G_CALLBACK (clutter_layout_manager_end_animation), - manager); g_signal_handlers_disconnect_by_func (timeline, G_CALLBACK (clutter_layout_manager_layout_changed), manager); @@ -446,8 +438,7 @@ clutter_layout_manager_class_init (ClutterLayoutManagerClass *klass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ClutterLayoutManagerClass, layout_changed), - NULL, NULL, - _clutter_marshal_VOID__VOID, + NULL, NULL, NULL, G_TYPE_NONE, 0); } @@ -817,7 +808,7 @@ clutter_layout_manager_child_set (ClutterLayoutManager *manager, if (error) { g_warning ("%s: %s", G_STRLOC, error); - free (error); + g_free (error); break; } @@ -965,7 +956,7 @@ clutter_layout_manager_child_get (ClutterLayoutManager *manager, if (error) { g_warning ("%s: %s", G_STRLOC, error); - free (error); + g_free (error); g_value_unset (&value); break; } @@ -1083,7 +1074,7 @@ clutter_layout_manager_find_child_property (ClutterLayoutManager *manager, * stored inside the #ClutterLayoutMeta sub-class used by @manager * * Return value: (transfer full) (array length=n_pspecs): the newly-allocated, - * %NULL-terminated array of #GParamSpecs. Use free() to free the + * %NULL-terminated array of #GParamSpecs. Use g_free() to free the * resources allocated for the array * * Since: 1.2 diff --git a/clutter/clutter/clutter-layout-manager.h b/clutter/clutter/clutter-layout-manager.h index 8bb909991..00f711803 100644 --- a/clutter/clutter/clutter-layout-manager.h +++ b/clutter/clutter/clutter-layout-manager.h @@ -149,79 +149,70 @@ struct _ClutterLayoutManagerClass void (* _clutter_padding_8) (void); }; -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT GType clutter_layout_manager_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT void clutter_layout_manager_get_preferred_width (ClutterLayoutManager *manager, ClutterContainer *container, gfloat for_height, gfloat *min_width_p, gfloat *nat_width_p); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT void clutter_layout_manager_get_preferred_height (ClutterLayoutManager *manager, ClutterContainer *container, gfloat for_width, gfloat *min_height_p, gfloat *nat_height_p); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT void clutter_layout_manager_allocate (ClutterLayoutManager *manager, ClutterContainer *container, const ClutterActorBox *allocation, ClutterAllocationFlags flags); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT void clutter_layout_manager_set_container (ClutterLayoutManager *manager, ClutterContainer *container); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT void clutter_layout_manager_layout_changed (ClutterLayoutManager *manager); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT GParamSpec * clutter_layout_manager_find_child_property (ClutterLayoutManager *manager, const gchar *name); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT GParamSpec ** clutter_layout_manager_list_child_properties (ClutterLayoutManager *manager, guint *n_pspecs); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT ClutterLayoutMeta *clutter_layout_manager_get_child_meta (ClutterLayoutManager *manager, ClutterContainer *container, ClutterActor *actor); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT void clutter_layout_manager_child_set (ClutterLayoutManager *manager, ClutterContainer *container, ClutterActor *actor, const gchar *first_property, ...) G_GNUC_NULL_TERMINATED; -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT void clutter_layout_manager_child_get (ClutterLayoutManager *manager, ClutterContainer *container, ClutterActor *actor, const gchar *first_property, ...) G_GNUC_NULL_TERMINATED; -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT void clutter_layout_manager_child_set_property (ClutterLayoutManager *manager, ClutterContainer *container, ClutterActor *actor, const gchar *property_name, const GValue *value); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT void clutter_layout_manager_child_get_property (ClutterLayoutManager *manager, ClutterContainer *container, ClutterActor *actor, const gchar *property_name, GValue *value); -CLUTTER_DEPRECATED_IN_1_12 -ClutterAlpha * clutter_layout_manager_begin_animation (ClutterLayoutManager *manager, - guint duration, - gulong mode); -CLUTTER_DEPRECATED_IN_1_12 -void clutter_layout_manager_end_animation (ClutterLayoutManager *manager); -CLUTTER_DEPRECATED_IN_1_12 -gdouble clutter_layout_manager_get_animation_progress (ClutterLayoutManager *manager); - G_END_DECLS #endif /* __CLUTTER_LAYOUT_MANAGER_H__ */ diff --git a/clutter/clutter/clutter-layout-meta.c b/clutter/clutter/clutter-layout-meta.c index 971079e4a..7360725ce 100644 --- a/clutter/clutter/clutter-layout-meta.c +++ b/clutter/clutter/clutter-layout-meta.c @@ -34,9 +34,8 @@ * * #ClutterLayoutMeta is available since Clutter 1.2 */ -#ifdef HAVE_CONFIG_H + #include "clutter-build-config.h" -#endif #include "clutter-layout-meta.h" #include "clutter-debug.h" diff --git a/clutter/clutter/clutter-layout-meta.h b/clutter/clutter/clutter-layout-meta.h index 6de0b479d..a4f6abe92 100644 --- a/clutter/clutter/clutter-layout-meta.h +++ b/clutter/clutter/clutter-layout-meta.h @@ -92,10 +92,10 @@ struct _ClutterLayoutMetaClass void (*_clutter_padding4) (void); }; -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT GType clutter_layout_meta_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT ClutterLayoutManager *clutter_layout_meta_get_manager (ClutterLayoutMeta *data); G_END_DECLS diff --git a/clutter/clutter/clutter-macros.h b/clutter/clutter/clutter-macros.h index a9d5cc189..8a6702194 100644 --- a/clutter/clutter/clutter-macros.h +++ b/clutter/clutter/clutter-macros.h @@ -26,8 +26,6 @@ #error "Only can be included directly." #endif -#include - /** * CLUTTER_FLAVOUR: * @@ -92,9 +90,7 @@ #define CLUTTER_PRIVATE_FIELD(x) clutter_private_ ## x #endif -#ifndef _CLUTTER_EXTERN -#define _CLUTTER_EXTERN extern -#endif +#define _CLUTTER_EXTERN __attribute__((visibility("default"))) extern #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || \ __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 4) @@ -115,281 +111,18 @@ #ifdef CLUTTER_DISABLE_DEPRECATION_WARNINGS #define CLUTTER_DEPRECATED _CLUTTER_EXTERN #define CLUTTER_DEPRECATED_FOR(f) _CLUTTER_EXTERN -#define CLUTTER_UNAVAILABLE(maj,min) _CLUTTER_EXTERN #define CLUTTER_DEPRECATED_MACRO #define CLUTTER_DEPRECATED_MACRO_FOR(f) #else #define CLUTTER_DEPRECATED G_DEPRECATED _CLUTTER_EXTERN #define CLUTTER_DEPRECATED_FOR(f) G_DEPRECATED_FOR(f) _CLUTTER_EXTERN -#define CLUTTER_UNAVAILABLE(maj,min) G_UNAVAILABLE(maj,min) _CLUTTER_EXTERN #define CLUTTER_DEPRECATED_MACRO _CLUTTER_DEPRECATED_MACRO #define CLUTTER_DEPRECATED_MACRO_FOR(f) _CLUTTER_DEPRECATED_MACRO_FOR(f) #endif -#define CLUTTER_AVAILABLE_IN_ALL _CLUTTER_EXTERN - -#define CLUTTER_AVAILABLE_IN_MUFFIN _CLUTTER_EXTERN - -/** - * CLUTTER_VERSION_MIN_REQUIRED: - * - * A macro that should be defined by the user prior to including the - * clutter.h header. - * - * The definition should be one of the predefined Clutter version macros, - * such as: %CLUTTER_VERSION_1_0, %CLUTTER_VERSION_1_2, ... - * - * This macro defines the lower bound for the Clutter API to be used. - * - * If a function has been deprecated in a newer version of Clutter, it - * is possible to use this symbol to avoid the compiler warnings without - * disabling warnings for every deprecated function. - * - * Since: 1.10 - */ -#ifndef CLUTTER_VERSION_MIN_REQUIRED -# define CLUTTER_VERSION_MIN_REQUIRED (CLUTTER_VERSION_CUR_STABLE) -#endif - -/** - * CLUTTER_VERSION_MAX_ALLOWED: - * - * A macro that should be define by the user prior to including the - * clutter.h header. - * - * The definition should be one of the predefined Clutter version macros, - * such as: %CLUTTER_VERSION_1_0, %CLUTTER_VERSION_1_2, ... - * - * This macro defines the upper bound for the Clutter API to be used. - * - * If a function has been introduced in a newer version of Clutter, it - * is possible to use this symbol to get compiler warnings when trying - * to use that function. - * - * Since: 1.10 - */ -#ifndef CLUTTER_VERSION_MAX_ALLOWED -# if CLUTTER_VERSION_MIN_REQUIRED > CLUTTER_VERSION_PREV_STABLE -# define CLUTTER_VERSION_MAX_ALLOWED CLUTTER_VERSION_MIN_REQUIRED -# else -# define CLUTTER_VERSION_MAX_ALLOWED CLUTTER_VERSION_CUR_STABLE -# endif -#endif - -/* sanity checks */ -#if CLUTTER_VERSION_MAX_ALLOWED < CLUTTER_VERSION_MIN_REQUIRED -# error "CLUTTER_VERSION_MAX_ALLOWED must be >= CLUTTER_VERSION_MIN_REQUIRED" -#endif -#if CLUTTER_VERSION_MIN_REQUIRED < CLUTTER_VERSION_1_0 -# error "CLUTTER_VERSION_MIN_REQUIRED must be >= CLUTTER_VERSION_1_0" -#endif - -/* XXX: Every new stable minor release should add a set of macros here */ - -#if CLUTTER_VERSION_MIN_REQUIRED >= CLUTTER_VERSION_1_0 -# define CLUTTER_DEPRECATED_IN_1_0 CLUTTER_DEPRECATED -# define CLUTTER_DEPRECATED_IN_1_0_FOR(f) CLUTTER_DEPRECATED_FOR(f) -#else -# define CLUTTER_DEPRECATED_IN_1_0 _CLUTTER_EXTERN -# define CLUTTER_DEPRECATED_IN_1_0_FOR(f) _CLUTTER_EXTERN -#endif - -#if CLUTTER_VERSION_MAX_ALLOWED < CLUTTER_VERSION_1_0 -# define CLUTTER_AVAILABLE_IN_1_0 CLUTTER_UNAVAILABLE(1, 0) -#else -# define CLUTTER_AVAILABLE_IN_1_0 _CLUTTER_EXTERN -#endif - -#if CLUTTER_VERSION_MIN_REQUIRED >= CLUTTER_VERSION_1_2 -# define CLUTTER_DEPRECATED_IN_1_2 CLUTTER_DEPRECATED -# define CLUTTER_DEPRECATED_IN_1_2_FOR(f) CLUTTER_DEPRECATED_FOR(f) -#else -# define CLUTTER_DEPRECATED_IN_1_2 _CLUTTER_EXTERN -# define CLUTTER_DEPRECATED_IN_1_2_FOR(f) _CLUTTER_EXTERN -#endif - -#if CLUTTER_VERSION_MAX_ALLOWED < CLUTTER_VERSION_1_2 -# define CLUTTER_AVAILABLE_IN_1_2 CLUTTER_UNAVAILABLE(1, 2) -#else -# define CLUTTER_AVAILABLE_IN_1_2 _CLUTTER_EXTERN -#endif - -#if CLUTTER_VERSION_MIN_REQUIRED >= CLUTTER_VERSION_1_4 -# define CLUTTER_DEPRECATED_IN_1_4 CLUTTER_DEPRECATED -# define CLUTTER_DEPRECATED_IN_1_4_FOR(f) CLUTTER_DEPRECATED_FOR(f) -#else -# define CLUTTER_DEPRECATED_IN_1_4 _CLUTTER_EXTERN -# define CLUTTER_DEPRECATED_IN_1_4_FOR(f) _CLUTTER_EXTERN -#endif - -#if CLUTTER_VERSION_MAX_ALLOWED < CLUTTER_VERSION_1_4 -# define CLUTTER_AVAILABLE_IN_1_4 CLUTTER_UNAVAILABLE(1, 4) -#else -# define CLUTTER_AVAILABLE_IN_1_4 _CLUTTER_EXTERN -#endif - -#if CLUTTER_VERSION_MIN_REQUIRED >= CLUTTER_VERSION_1_6 -# define CLUTTER_DEPRECATED_IN_1_6 CLUTTER_DEPRECATED -# define CLUTTER_DEPRECATED_IN_1_6_FOR(f) CLUTTER_DEPRECATED_FOR(f) -#else -# define CLUTTER_DEPRECATED_IN_1_6 _CLUTTER_EXTERN -# define CLUTTER_DEPRECATED_IN_1_6_FOR(f) _CLUTTER_EXTERN -#endif - -#if CLUTTER_VERSION_MAX_ALLOWED < CLUTTER_VERSION_1_6 -# define CLUTTER_AVAILABLE_IN_1_6 CLUTTER_UNAVAILABLE(1, 6) -#else -# define CLUTTER_AVAILABLE_IN_1_6 _CLUTTER_EXTERN -#endif - -#if CLUTTER_VERSION_MIN_REQUIRED >= CLUTTER_VERSION_1_8 -# define CLUTTER_DEPRECATED_IN_1_8 CLUTTER_DEPRECATED -# define CLUTTER_DEPRECATED_IN_1_8_FOR(f) CLUTTER_DEPRECATED_FOR(f) -#else -# define CLUTTER_DEPRECATED_IN_1_8 _CLUTTER_EXTERN -# define CLUTTER_DEPRECATED_IN_1_8_FOR(f) _CLUTTER_EXTERN -#endif - -#if CLUTTER_VERSION_MAX_ALLOWED < CLUTTER_VERSION_1_8 -# define CLUTTER_AVAILABLE_IN_1_8 CLUTTER_UNAVAILABLE(1, 8) -#else -# define CLUTTER_AVAILABLE_IN_1_8 _CLUTTER_EXTERN -#endif +#define CLUTTER_MACRO_DEPRECATED CLUTTER_DEPRECATED_MACRO +#define CLUTTER_MACRO_DEPRECATED_FOR(f) CLUTTER_DEPRECATED_MACRO_FOR(f) -#if CLUTTER_VERSION_MIN_REQUIRED >= CLUTTER_VERSION_1_10 -# define CLUTTER_DEPRECATED_IN_1_10 CLUTTER_DEPRECATED -# define CLUTTER_DEPRECATED_IN_1_10_FOR(f) CLUTTER_DEPRECATED_FOR(f) -#else -# define CLUTTER_DEPRECATED_IN_1_10 _CLUTTER_EXTERN -# define CLUTTER_DEPRECATED_IN_1_10_FOR(f) _CLUTTER_EXTERN -#endif - -#if CLUTTER_VERSION_MAX_ALLOWED < CLUTTER_VERSION_1_10 -# define CLUTTER_AVAILABLE_IN_1_10 CLUTTER_UNAVAILABLE(1, 10) -#else -# define CLUTTER_AVAILABLE_IN_1_10 _CLUTTER_EXTERN -#endif - -#if CLUTTER_VERSION_MIN_REQUIRED >= CLUTTER_VERSION_1_12 -# define CLUTTER_DEPRECATED_IN_1_12 CLUTTER_DEPRECATED -# define CLUTTER_DEPRECATED_IN_1_12_FOR(f) CLUTTER_DEPRECATED_FOR(f) -#else -# define CLUTTER_DEPRECATED_IN_1_12 _CLUTTER_EXTERN -# define CLUTTER_DEPRECATED_IN_1_12_FOR(f) _CLUTTER_EXTERN -#endif - -#define CLUTTER_DEPRECATED_IN_MUFFIN CLUTTER_DEPRECATED - -#if CLUTTER_VERSION_MAX_ALLOWED < CLUTTER_VERSION_1_12 -# define CLUTTER_AVAILABLE_IN_1_12 CLUTTER_UNAVAILABLE(1, 12) -#else -# define CLUTTER_AVAILABLE_IN_1_12 _CLUTTER_EXTERN -#endif - -#if CLUTTER_VERSION_MIN_REQUIRED >= CLUTTER_VERSION_1_14 -# define CLUTTER_DEPRECATED_IN_1_14 CLUTTER_DEPRECATED -# define CLUTTER_DEPRECATED_IN_1_14_FOR(f) CLUTTER_DEPRECATED_FOR(f) -#else -# define CLUTTER_DEPRECATED_IN_1_14 _CLUTTER_EXTERN -# define CLUTTER_DEPRECATED_IN_1_14_FOR(f) _CLUTTER_EXTERN -#endif - -#if CLUTTER_VERSION_MAX_ALLOWED < CLUTTER_VERSION_1_14 -# define CLUTTER_AVAILABLE_IN_1_14 CLUTTER_UNAVAILABLE(1, 14) -#else -# define CLUTTER_AVAILABLE_IN_1_14 _CLUTTER_EXTERN -#endif - -#if CLUTTER_VERSION_MIN_REQUIRED >= CLUTTER_VERSION_1_16 -# define CLUTTER_DEPRECATED_IN_1_16 CLUTTER_DEPRECATED -# define CLUTTER_DEPRECATED_IN_1_16_FOR(f) CLUTTER_DEPRECATED_FOR(f) -#else -# define CLUTTER_DEPRECATED_IN_1_16 _CLUTTER_EXTERN -# define CLUTTER_DEPRECATED_IN_1_16_FOR(f) _CLUTTER_EXTERN -#endif - -#if CLUTTER_VERSION_MAX_ALLOWED < CLUTTER_VERSION_1_16 -# define CLUTTER_AVAILABLE_IN_1_16 CLUTTER_UNAVAILABLE(1, 16) -#else -# define CLUTTER_AVAILABLE_IN_1_16 _CLUTTER_EXTERN -#endif - -#if CLUTTER_VERSION_MIN_REQUIRED >= CLUTTER_VERSION_1_18 -# define CLUTTER_DEPRECATED_IN_1_18 CLUTTER_DEPRECATED -# define CLUTTER_DEPRECATED_IN_1_18_FOR(f) CLUTTER_DEPRECATED_FOR(f) -#else -# define CLUTTER_DEPRECATED_IN_1_18 _CLUTTER_EXTERN -# define CLUTTER_DEPRECATED_IN_1_18_FOR(f) _CLUTTER_EXTERN -#endif - -#if CLUTTER_VERSION_MAX_ALLOWED < CLUTTER_VERSION_1_18 -# define CLUTTER_AVAILABLE_IN_1_18 CLUTTER_UNAVAILABLE(1, 18) -#else -# define CLUTTER_AVAILABLE_IN_1_18 _CLUTTER_EXTERN -#endif - -#if CLUTTER_VERSION_MIN_REQUIRED >= CLUTTER_VERSION_1_20 -# define CLUTTER_DEPRECATED_IN_1_20 CLUTTER_DEPRECATED -# define CLUTTER_DEPRECATED_IN_1_20_FOR(f) CLUTTER_DEPRECATED_FOR(f) -#else -# define CLUTTER_DEPRECATED_IN_1_20 _CLUTTER_EXTERN -# define CLUTTER_DEPRECATED_IN_1_20_FOR(f) _CLUTTER_EXTERN -#endif - -#if CLUTTER_VERSION_MAX_ALLOWED < CLUTTER_VERSION_1_20 -# define CLUTTER_AVAILABLE_IN_1_20 CLUTTER_UNAVAILABLE(1, 20) -#else -# define CLUTTER_AVAILABLE_IN_1_20 _CLUTTER_EXTERN -#endif - -#if CLUTTER_VERSION_MIN_REQUIRED >= CLUTTER_VERSION_1_22 -# define CLUTTER_DEPRECATED_IN_1_22 CLUTTER_DEPRECATED -# define CLUTTER_DEPRECATED_IN_1_22_FOR(f) CLUTTER_DEPRECATED_FOR(f) -#else -# define CLUTTER_DEPRECATED_IN_1_22 _CLUTTER_EXTERN -# define CLUTTER_DEPRECATED_IN_1_22_FOR(f) _CLUTTER_EXTERN -#endif - -#if CLUTTER_VERSION_MAX_ALLOWED < CLUTTER_VERSION_1_22 -# define CLUTTER_AVAILABLE_IN_1_22 CLUTTER_UNAVAILABLE(1, 22) -#else -# define CLUTTER_AVAILABLE_IN_1_22 _CLUTTER_EXTERN -#endif - -#if CLUTTER_VERSION_MIN_REQUIRED >= CLUTTER_VERSION_1_24 -# define CLUTTER_DEPRECATED_IN_1_24 CLUTTER_DEPRECATED -# define CLUTTER_DEPRECATED_IN_1_24_FOR(f) CLUTTER_DEPRECATED_FOR(f) -# define CLUTTER_MACRO_DEPRECATED_IN_1_24 CLUTTER_DEPRECATED_MACRO -# define CLUTTER_MACRO_DEPRECATED_IN_1_24_FOR(f) CLUTTER_DEPRECATED_MACRO_FOR(f) -#else -# define CLUTTER_DEPRECATED_IN_1_24 _CLUTTER_EXTERN -# define CLUTTER_DEPRECATED_IN_1_24_FOR(f) _CLUTTER_EXTERN -# define CLUTTER_MACRO_DEPRECATED_IN_1_24 -# define CLUTTER_MACRO_DEPRECATED_IN_1_24_FOR(f) -#endif - -#if CLUTTER_VERSION_MAX_ALLOWED < CLUTTER_VERSION_1_24 -# define CLUTTER_AVAILABLE_IN_1_24 CLUTTER_UNAVAILABLE(1, 24) -#else -# define CLUTTER_AVAILABLE_IN_1_24 _CLUTTER_EXTERN -#endif - -#if CLUTTER_VERSION_MIN_REQUIRED >= CLUTTER_VERSION_1_26 -# define CLUTTER_DEPRECATED_IN_1_26 CLUTTER_DEPRECATED -# define CLUTTER_DEPRECATED_IN_1_26_FOR(f) CLUTTER_DEPRECATED_FOR(f) -# define CLUTTER_MACRO_DEPRECATED_IN_1_26 CLUTTER_DEPRECATED_MACRO -# define CLUTTER_MACRO_DEPRECATED_IN_1_26_FOR(f) CLUTTER_DEPRECATED_MACRO_FOR(f) -#else -# define CLUTTER_DEPRECATED_IN_1_26 _CLUTTER_EXTERN -# define CLUTTER_DEPRECATED_IN_1_26_FOR(f) _CLUTTER_EXTERN -# define CLUTTER_MACRO_DEPRECATED_IN_1_26 -# define CLUTTER_MACRO_DEPRECATED_IN_1_26_FOR(f) -#endif - -#if CLUTTER_VERSION_MAX_ALLOWED < CLUTTER_VERSION_1_26 -# define CLUTTER_AVAILABLE_IN_1_26 CLUTTER_UNAVAILABLE(1, 26) -#else -# define CLUTTER_AVAILABLE_IN_1_26 _CLUTTER_EXTERN -#endif +#define CLUTTER_EXPORT _CLUTTER_EXTERN #endif /* __CLUTTER_MACROS_H__ */ diff --git a/clutter/clutter/clutter-main.c b/clutter/clutter/clutter-main.c index 64519efe9..d6149e13f 100644 --- a/clutter/clutter/clutter-main.c +++ b/clutter/clutter/clutter-main.c @@ -47,9 +47,7 @@ * [threads.c](https://git.gnome.org/browse/clutter/tree/examples/threads.c?h=clutter-1.18) */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include @@ -57,17 +55,19 @@ #include "clutter-backend-private.h" #include "clutter-config.h" #include "clutter-debug.h" -#include "clutter-device-manager-private.h" #include "clutter-event-private.h" #include "clutter-feature.h" +#include "clutter-input-device-private.h" +#include "clutter-input-pointer-a11y-private.h" +#include "clutter-graphene.h" #include "clutter-main.h" #include "clutter-master-clock.h" -#include "clutter-muffin.h" +#include "clutter-mutter.h" +#include "clutter-paint-node-private.h" #include "clutter-private.h" #include "clutter-settings-private.h" #include "clutter-stage-manager.h" #include "clutter-stage-private.h" -#include "clutter-version.h" /* For flavour define */ #ifdef CLUTTER_WINDOWING_X11 #include "x11/clutter-backend-x11.h" @@ -79,7 +79,7 @@ #include #include -#include "cally.h" /* For accessibility support */ +#include "cally/cally.h" /* For accessibility support */ /* main context */ static ClutterMainContext *ClutterCntx = NULL; @@ -87,8 +87,6 @@ G_LOCK_DEFINE_STATIC (ClutterCntx); /* main lock and locking/unlocking functions */ static GMutex clutter_threads_mutex; -static GCallback clutter_threads_lock = NULL; -static GCallback clutter_threads_unlock = NULL; /* command line options */ static gboolean clutter_is_initialized = FALSE; @@ -98,7 +96,6 @@ static gboolean clutter_disable_mipmap_text = FALSE; static gboolean clutter_use_fuzzy_picking = FALSE; static gboolean clutter_enable_accessibility = TRUE; static gboolean clutter_sync_to_vblank = TRUE; -SyncMethod clutter_sync_method = SYNC_PRESENTATION_TIME; static guint clutter_default_fps = 60; @@ -112,10 +109,6 @@ guint clutter_debug_flags = 0; guint clutter_paint_debug_flags = 0; guint clutter_pick_debug_flags = 0; -const guint clutter_major_version = CLUTTER_MAJOR_VERSION; -const guint clutter_minor_version = CLUTTER_MINOR_VERSION; -const guint clutter_micro_version = CLUTTER_MICRO_VERSION; - #ifdef CLUTTER_ENABLE_DEBUG static const GDebugKey clutter_debug_keys[] = { { "misc", CLUTTER_DEBUG_MISC }, @@ -138,7 +131,6 @@ static const GDebugKey clutter_debug_keys[] = { static const GDebugKey clutter_pick_debug_keys[] = { { "nop-picking", CLUTTER_DEBUG_NOP_PICKING }, - { "dump-pick-buffers", CLUTTER_DEBUG_DUMP_PICK_BUFFERS }, }; static const GDebugKey clutter_paint_debug_keys[] = { @@ -150,40 +142,13 @@ static const GDebugKey clutter_paint_debug_keys[] = { { "disable-offscreen-redirect", CLUTTER_DEBUG_DISABLE_OFFSCREEN_REDIRECT }, { "continuous-redraw", CLUTTER_DEBUG_CONTINUOUS_REDRAW }, { "paint-deform-tiles", CLUTTER_DEBUG_PAINT_DEFORM_TILES }, + { "damage-region", CLUTTER_DEBUG_PAINT_DAMAGE_REGION }, }; -static void -clutter_threads_impl_lock (void) -{ - g_mutex_lock (&clutter_threads_mutex); -} - -static void -clutter_threads_impl_unlock (void) -{ - /* we need to trylock here, in case the lock hasn't been acquired; on - * various systems trying to release a mutex that hasn't been acquired - * will cause a run-time error. trylock() will either fail, in which - * case we can release the lock we own; or it will succeeds, in which - * case we need to release the lock we just acquired. so we ignore the - * returned value. - * - * see: https://bugs.gnome.org/679439 - */ - g_mutex_trylock (&clutter_threads_mutex); - g_mutex_unlock (&clutter_threads_mutex); -} - static inline void clutter_threads_init_default (void) { g_mutex_init (&clutter_threads_mutex); - - if (clutter_threads_lock == NULL) - clutter_threads_lock = clutter_threads_impl_lock; - - if (clutter_threads_unlock == NULL) - clutter_threads_unlock = clutter_threads_impl_unlock; } #define ENVIRONMENT_GROUP "Environment" @@ -200,17 +165,6 @@ clutter_config_read_from_key_file (GKeyFile *keyfile) if (!g_key_file_has_group (keyfile, ENVIRONMENT_GROUP)) return; - str_value = - g_key_file_get_string (keyfile, ENVIRONMENT_GROUP, - "Backends", - &key_error); - if (key_error != NULL) - g_clear_error (&key_error); - else - clutter_try_set_windowing_backend (str_value); - - free (str_value); - str_value = g_key_file_get_string (keyfile, ENVIRONMENT_GROUP, "Drivers", @@ -220,7 +174,7 @@ clutter_config_read_from_key_file (GKeyFile *keyfile) else clutter_set_allowed_drivers (str_value); - free (str_value); + g_free (str_value); bool_value = g_key_file_get_boolean (keyfile, ENVIRONMENT_GROUP, @@ -262,16 +216,6 @@ clutter_config_read_from_key_file (GKeyFile *keyfile) else clutter_enable_accessibility = bool_value; - bool_value = - g_key_file_get_boolean (keyfile, ENVIRONMENT_GROUP, - "SyncToVblank", - &key_error); - - if (key_error != NULL) - g_clear_error (&key_error); - else - clutter_sync_to_vblank = bool_value; - int_value = g_key_file_get_integer (keyfile, ENVIRONMENT_GROUP, "DefaultFps", @@ -297,7 +241,7 @@ clutter_config_read_from_key_file (GKeyFile *keyfile) clutter_text_direction = CLUTTER_TEXT_DIRECTION_LTR; } - free (str_value); + g_free (str_value); } #ifdef CLUTTER_ENABLE_DEBUG @@ -323,7 +267,7 @@ clutter_debug_read_from_key_file (GKeyFile *keyfile) else g_clear_error (&key_error); - free (value); + g_free (value); value = g_key_file_get_value (keyfile, DEBUG_GROUP, "PaintDebug", @@ -338,7 +282,7 @@ clutter_debug_read_from_key_file (GKeyFile *keyfile) else g_clear_error (&key_error); - free (value); + g_free (value); value = g_key_file_get_value (keyfile, DEBUG_GROUP, "PickDebug", @@ -353,7 +297,7 @@ clutter_debug_read_from_key_file (GKeyFile *keyfile) else g_clear_error (&key_error); - free (value); + g_free (value); } #endif @@ -398,7 +342,7 @@ clutter_config_read (void) if (g_file_test (config_path, G_FILE_TEST_EXISTS)) clutter_config_read_from_file (config_path); - free (config_path); + g_free (config_path); config_path = g_build_filename (g_get_user_config_dir (), "clutter-1.0", @@ -407,29 +351,7 @@ clutter_config_read (void) if (g_file_test (config_path, G_FILE_TEST_EXISTS)) clutter_config_read_from_file (config_path); - free (config_path); -} - -/** - * clutter_get_show_fps: - * - * Returns whether Clutter should print out the frames per second on the - * console. You can enable this setting either using the - * CLUTTER_SHOW_FPS environment variable or passing - * the --clutter-show-fps command line argument. * - * - * Return value: %TRUE if Clutter should show the FPS. - * - * Since: 0.4 - * - * Deprecated: 1.10: This function does not do anything. Use the environment - * variable or the configuration file to determine whether Clutter should - * print out the FPS counter on the console. - */ -gboolean -clutter_get_show_fps (void) -{ - return FALSE; + g_free (config_path); } gboolean @@ -480,205 +402,6 @@ clutter_disable_accessibility (void) clutter_enable_accessibility = FALSE; } -/** - * clutter_redraw: - * - * Forces a redraw of the entire stage. Applications should never use this - * function, but queue a redraw using clutter_actor_queue_redraw(). - * - * This function should only be used by libraries integrating Clutter from - * within another toolkit. - * - * Deprecated: 1.10: Use clutter_stage_ensure_redraw() instead. - */ -void -clutter_redraw (ClutterStage *stage) -{ - g_return_if_fail (CLUTTER_IS_STAGE (stage)); - - clutter_stage_ensure_redraw (stage); -} - -/** - * clutter_set_motion_events_enabled: - * @enable: %TRUE to enable per-actor motion events - * - * Sets whether per-actor motion events should be enabled or not on - * all #ClutterStages managed by Clutter. - * - * If @enable is %FALSE the following events will not work: - * - * - ClutterActor::motion-event, except on the #ClutterStage - * - ClutterActor::enter-event - * - ClutterActor::leave-event - * - * Since: 0.6 - * - * Deprecated: 1.8: Use clutter_stage_set_motion_events_enabled() instead. - */ -void -clutter_set_motion_events_enabled (gboolean enable) -{ - ClutterStageManager *stage_manager; - ClutterMainContext *context; - const GSList *l; - - enable = !!enable; - - context = _clutter_context_get_default (); - if (context->motion_events_per_actor == enable) - return; - - /* store the flag for later query and for newly created stages */ - context->motion_events_per_actor = enable; - - /* propagate the change to all stages */ - stage_manager = clutter_stage_manager_get_default (); - - for (l = clutter_stage_manager_peek_stages (stage_manager); - l != NULL; - l = l->next) - { - clutter_stage_set_motion_events_enabled (l->data, enable); - } -} - -/** - * clutter_get_motion_events_enabled: - * - * Gets whether the per-actor motion events are enabled. - * - * Return value: %TRUE if the motion events are enabled - * - * Since: 0.6 - * - * Deprecated: 1.8: Use clutter_stage_get_motion_events_enabled() instead. - */ -gboolean -clutter_get_motion_events_enabled (void) -{ - return _clutter_context_get_motion_events_enabled (); -} - -void -_clutter_id_to_color (guint id_, - ClutterColor *col) -{ - ClutterMainContext *ctx; - gint red, green, blue; - - ctx = _clutter_context_get_default (); - - if (ctx->fb_g_mask == 0) - { - /* Figure out framebuffer masks used for pick */ - cogl_get_bitmasks (&ctx->fb_r_mask, - &ctx->fb_g_mask, - &ctx->fb_b_mask, NULL); - - ctx->fb_r_mask_used = ctx->fb_r_mask; - ctx->fb_g_mask_used = ctx->fb_g_mask; - ctx->fb_b_mask_used = ctx->fb_b_mask; - - /* XXX - describe what "fuzzy picking" is */ - if (clutter_use_fuzzy_picking) - { - ctx->fb_r_mask_used--; - ctx->fb_g_mask_used--; - ctx->fb_b_mask_used--; - } - } - - /* compute the numbers we'll store in the components */ - red = (id_ >> (ctx->fb_g_mask_used+ctx->fb_b_mask_used)) - & (0xff >> (8-ctx->fb_r_mask_used)); - green = (id_ >> ctx->fb_b_mask_used) - & (0xff >> (8-ctx->fb_g_mask_used)); - blue = (id_) - & (0xff >> (8-ctx->fb_b_mask_used)); - - /* shift left bits a bit and add one, this circumvents - * at least some potential rounding errors in GL/GLES - * driver / hw implementation. - */ - if (ctx->fb_r_mask_used != ctx->fb_r_mask) - red = red * 2; - if (ctx->fb_g_mask_used != ctx->fb_g_mask) - green = green * 2; - if (ctx->fb_b_mask_used != ctx->fb_b_mask) - blue = blue * 2; - - /* shift up to be full 8bit values */ - red = (red << (8 - ctx->fb_r_mask)) | (0x7f >> (ctx->fb_r_mask_used)); - green = (green << (8 - ctx->fb_g_mask)) | (0x7f >> (ctx->fb_g_mask_used)); - blue = (blue << (8 - ctx->fb_b_mask)) | (0x7f >> (ctx->fb_b_mask_used)); - - col->red = red; - col->green = green; - col->blue = blue; - col->alpha = 0xff; - - /* XXX: We rotate the nibbles of the colors here so that there is a - * visible variation between colors of sequential actor identifiers; - * otherwise pick buffers dumped to an image will pretty much just look - * black. - */ - if (G_UNLIKELY (clutter_pick_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS)) - { - col->red = (col->red << 4) | (col->red >> 4); - col->green = (col->green << 4) | (col->green >> 4); - col->blue = (col->blue << 4) | (col->blue >> 4); - } -} - -guint -_clutter_pixel_to_id (guchar pixel[4]) -{ - ClutterMainContext *ctx; - gint red, green, blue; - guint retval; - - ctx = _clutter_context_get_default (); - - /* reduce the pixel components to the number of bits actually used of the - * 8bits. - */ - if (G_UNLIKELY (clutter_pick_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS)) - { - guchar tmp; - - /* XXX: In _clutter_id_to_color we rotated the nibbles of the colors so - * that there is a visible variation between colors of sequential actor - * identifiers (otherwise pick buffers dumped to an image will pretty - * much just look black.) Here we reverse that rotation. - */ - tmp = ((pixel[0] << 4) | (pixel[0] >> 4)); - red = tmp >> (8 - ctx->fb_r_mask); - tmp = ((pixel[1] << 4) | (pixel[1] >> 4)); - green = tmp >> (8 - ctx->fb_g_mask); - tmp = ((pixel[2] << 4) | (pixel[2] >> 4)); - blue = tmp >> (8 - ctx->fb_b_mask); - } - else - { - red = pixel[0] >> (8 - ctx->fb_r_mask); - green = pixel[1] >> (8 - ctx->fb_g_mask); - blue = pixel[2] >> (8 - ctx->fb_b_mask); - } - - /* divide potentially by two if 'fuzzy' */ - red = red >> (ctx->fb_r_mask - ctx->fb_r_mask_used); - green = green >> (ctx->fb_g_mask - ctx->fb_g_mask_used); - blue = blue >> (ctx->fb_b_mask - ctx->fb_b_mask_used); - - /* combine the correct per component values into the final id */ - retval = blue - + (green << ctx->fb_b_mask_used) - + (red << (ctx->fb_b_mask_used + ctx->fb_g_mask_used)); - - return retval; -} - static CoglPangoFontMap * clutter_context_get_pango_fontmap (void) { @@ -811,69 +534,6 @@ clutter_main (void) clutter_main_loop_level--; } -/** - * clutter_threads_init: - * - * Initialises the Clutter threading mechanism, so that Clutter API can be - * called by multiple threads, using clutter_threads_enter() and - * clutter_threads_leave() to mark the critical sections. - * - * You must call g_thread_init() before this function. - * - * This function must be called before clutter_init(). - * - * It is safe to call this function multiple times. - * - * Since: 0.4 - * - * Deprecated: 1.10: This function does not do anything. Threading support - * is initialized when Clutter is initialized. - */ -void -clutter_threads_init (void) -{ -} - -/** - * clutter_threads_set_lock_functions: (skip) - * @enter_fn: function called when aquiring the Clutter main lock - * @leave_fn: function called when releasing the Clutter main lock - * - * Allows the application to replace the standard method that - * Clutter uses to protect its data structures. Normally, Clutter - * creates a single #GMutex that is locked by clutter_threads_enter(), - * and released by clutter_threads_leave(); using this function an - * application provides, instead, a function @enter_fn that is - * called by clutter_threads_enter() and a function @leave_fn that is - * called by clutter_threads_leave(). - * - * The functions must provide at least same locking functionality - * as the default implementation, but can also do extra application - * specific processing. - * - * As an example, consider an application that has its own recursive - * lock that when held, holds the Clutter lock as well. When Clutter - * unlocks the Clutter lock when entering a recursive main loop, the - * application must temporarily release its lock as well. - * - * Most threaded Clutter apps won't need to use this method. - * - * This method must be called before clutter_init(), and cannot - * be called multiple times. - * - * Since: 0.4 - */ -void -clutter_threads_set_lock_functions (GCallback enter_fn, - GCallback leave_fn) -{ - g_return_if_fail (clutter_threads_lock == NULL && - clutter_threads_unlock == NULL); - - clutter_threads_lock = enter_fn; - clutter_threads_unlock = leave_fn; -} - gboolean _clutter_threads_dispatch (gpointer data) { @@ -930,17 +590,11 @@ _clutter_threads_dispatch_free (gpointer data) * SafeClosure *closure = data; * gboolean res = FALSE; * - * // mark the critical section // - * - * clutter_threads_enter(); - * * // the callback does not need to acquire the Clutter * / lock itself, as it is held by the this proxy handler * // * res = closure->callback (closure->data); * - * clutter_threads_leave(); - * * return res; * } * static gulong @@ -955,7 +609,7 @@ _clutter_threads_dispatch_free (gpointer data) * return g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, * idle_safe_callback, * closure, - * free) + * g_free) * } *]| * @@ -979,7 +633,7 @@ _clutter_threads_dispatch_free (gpointer data) * closure->text); * * g_object_unref (closure->label); - * free (closure); + * g_free (closure); * * return FALSE; * } @@ -1120,69 +774,23 @@ clutter_threads_add_timeout (guint interval, void _clutter_threads_acquire_lock (void) { - if (clutter_threads_lock != NULL) - (* clutter_threads_lock) (); + g_mutex_lock (&clutter_threads_mutex); } void _clutter_threads_release_lock (void) { - if (clutter_threads_unlock != NULL) - (* clutter_threads_unlock) (); -} - -/** - * clutter_threads_enter: - * - * Locks the Clutter thread lock. - * - * Since: 0.4 - * - * Deprecated: 1.12: This function should not be used by application - * code; marking critical sections is not portable on various - * platforms. Instead of acquiring the Clutter lock, schedule UI - * updates from the main loop using clutter_threads_add_idle() or - * clutter_threads_add_timeout(). - */ -void -clutter_threads_enter (void) -{ - _clutter_threads_acquire_lock (); -} - -/** - * clutter_threads_leave: - * - * Unlocks the Clutter thread lock. - * - * Since: 0.4 - * - * Deprecated: 1.12: This function should not be used by application - * code; marking critical sections is not portable on various - * platforms. Instead of acquiring the Clutter lock, schedule UI - * updates from the main loop using clutter_threads_add_idle() or - * clutter_threads_add_timeout(). - */ -void -clutter_threads_leave (void) -{ - _clutter_threads_release_lock (); -} - - -/** - * clutter_get_debug_enabled: - * - * Check if Clutter has debugging enabled. - * - * Return value: %FALSE - * - * Deprecated: 1.10: This function does not do anything. - */ -gboolean -clutter_get_debug_enabled (void) -{ - return FALSE; + /* we need to trylock here, in case the lock hasn't been acquired; on + * various systems trying to release a mutex that hasn't been acquired + * will cause a run-time error. trylock() will either fail, in which + * case we can release the lock we own; or it will succeeds, in which + * case we need to release the lock we just acquired. so we ignore the + * returned value. + * + * see: https://bugs.gnome.org/679439 + */ + g_mutex_trylock (&clutter_threads_mutex); + g_mutex_unlock (&clutter_threads_mutex); } void @@ -1232,7 +840,6 @@ clutter_context_get_default_unlocked (void) ctx->settings = clutter_settings_get_default (); _clutter_settings_set_backend (ctx->settings, ctx->backend); - ctx->motion_events_per_actor = TRUE; ctx->last_repaint_id = 1; } @@ -1253,36 +860,6 @@ _clutter_context_get_default (void) return retval; } -/** - * clutter_get_timestamp: - * - * Returns the approximate number of microseconds passed since Clutter was - * intialised. - * - * This function shdould not be used by application code. - * - * The output of this function depends on whether Clutter was configured to - * enable its debugging code paths, so it's less useful than intended. - * - * Since Clutter 1.10, this function is an alias to g_get_monotonic_time() - * if Clutter was configured to enable the debugging code paths. - * - * Return value: Number of microseconds since clutter_init() was called, or - * zero if Clutter was not configured with debugging code paths. - * - * Deprecated: 1.10: Use #GTimer or g_get_monotonic_time() for a proper - * timing source - */ -gulong -clutter_get_timestamp (void) -{ -#ifdef CLUTTER_ENABLE_DEBUG - return (gulong) g_get_monotonic_time (); -#else - return 0L; -#endif -} - static gboolean clutter_arg_direction_cb (const char *key, const char *value, @@ -1373,6 +950,9 @@ clutter_init_real (GError **error) CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS | CLUTTER_DEBUG_DISABLE_CULLING; } + if (clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DAMAGE_REGION) + g_message ("Enabling damaged region"); + /* this will take care of initializing Cogl's state and * query the GL machinery for features */ @@ -1391,6 +971,9 @@ clutter_init_real (GError **error) if (clutter_enable_accessibility) cally_accessibility_init (); + /* Initialize types required for paint nodes */ + _clutter_paint_node_init_types (); + return CLUTTER_INIT_SUCCESS; } @@ -1495,10 +1078,6 @@ pre_parse_hook (GOptionContext *context, if (env_string) clutter_use_fuzzy_picking = TRUE; - env_string = g_getenv ("CLUTTER_VBLANK"); - if (g_strcmp0 (env_string, "none") == 0) - clutter_sync_to_vblank = FALSE; - return _clutter_backend_pre_parse (backend, error); } @@ -1585,8 +1164,8 @@ clutter_get_option_group (void) context = _clutter_context_get_default (); group = g_option_group_new ("clutter", - _("Clutter Options"), - _("Show Clutter Options"), + "Clutter Options", + "Show Clutter Options", NULL, NULL); @@ -1948,7 +1527,7 @@ event_click_count_generate (ClutterEvent *event) previous_y = event->button.y; previous_time = event->button.time; - /* fallthrough */ + G_GNUC_FALLTHROUGH; case CLUTTER_BUTTON_RELEASE: event->button.click_count = click_count; break; @@ -2007,30 +1586,40 @@ static inline void emit_pointer_event (ClutterEvent *event, ClutterInputDevice *device) { - ClutterMainContext *context = _clutter_context_get_default (); + if (_clutter_event_process_filters (event)) + return; + + if (device != NULL && device->pointer_grab_actor != NULL) + clutter_actor_event (device->pointer_grab_actor, event, FALSE); + else + emit_event_chain (event); +} + +static inline void +emit_crossing_event (ClutterEvent *event, + ClutterInputDevice *device) +{ + ClutterEventSequence *sequence = clutter_event_get_event_sequence (event); + ClutterActor *grab_actor = NULL; if (_clutter_event_process_filters (event)) return; - if (context->pointer_grab_actor == NULL && - (device == NULL || device->pointer_grab_actor == NULL)) + if (sequence) { - /* no grab, time to capture and bubble */ - emit_event_chain (event); + if (device->sequence_grab_actors != NULL) + grab_actor = g_hash_table_lookup (device->sequence_grab_actors, sequence); } else { - if (context->pointer_grab_actor != NULL) - { - /* global grab */ - clutter_actor_event (context->pointer_grab_actor, event, FALSE); - } - else if (device != NULL && device->pointer_grab_actor != NULL) - { - /* per device grab */ - clutter_actor_event (device->pointer_grab_actor, event, FALSE); - } + if (device != NULL && device->pointer_grab_actor != NULL) + grab_actor = device->pointer_grab_actor; } + + if (grab_actor != NULL) + clutter_actor_event (grab_actor, event, FALSE); + else + emit_event_chain (event); } static inline void @@ -2064,30 +1653,13 @@ static inline void emit_keyboard_event (ClutterEvent *event, ClutterInputDevice *device) { - ClutterMainContext *context = _clutter_context_get_default (); - if (_clutter_event_process_filters (event)) return; - if (context->keyboard_grab_actor == NULL && - (device == NULL || device->keyboard_grab_actor == NULL)) - { - /* no grab, time to capture and bubble */ - emit_event_chain (event); - } + if (device != NULL && device->keyboard_grab_actor != NULL) + clutter_actor_event (device->keyboard_grab_actor, event, FALSE); else - { - if (context->keyboard_grab_actor != NULL) - { - /* global key grab */ - clutter_actor_event (context->keyboard_grab_actor, event, FALSE); - } - else if (device != NULL && device->keyboard_grab_actor != NULL) - { - /* per-device key grab */ - clutter_actor_event (context->keyboard_grab_actor, event, FALSE); - } - } + emit_event_chain (event); } static inline void @@ -2177,6 +1749,9 @@ _clutter_process_event_details (ClutterActor *stage, case CLUTTER_PAD_BUTTON_RELEASE: case CLUTTER_PAD_STRIP: case CLUTTER_PAD_RING: + case CLUTTER_IM_COMMIT: + case CLUTTER_IM_DELETE: + case CLUTTER_IM_PREEDIT: { ClutterActor *actor = NULL; @@ -2206,9 +1781,9 @@ _clutter_process_event_details (ClutterActor *stage, { ClutterActor *actor = NULL; - emit_pointer_event (event, device); + emit_crossing_event (event, device); - actor = _clutter_input_device_update (device, NULL, FALSE); + actor = clutter_input_device_update (device, NULL, FALSE); if (actor != stage) { ClutterEvent *crossing; @@ -2218,12 +1793,12 @@ _clutter_process_event_details (ClutterActor *stage, crossing->crossing.related = stage; crossing->crossing.source = actor; - emit_pointer_event (crossing, device); + emit_crossing_event (crossing, device); clutter_event_free (crossing); } } else - emit_pointer_event (event, device); + emit_crossing_event (event, device); break; case CLUTTER_LEAVE: @@ -2242,10 +1817,10 @@ _clutter_process_event_details (ClutterActor *stage, crossing->crossing.related = stage; crossing->crossing.source = device->cursor_actor; - emit_pointer_event (crossing, device); + emit_crossing_event (crossing, device); clutter_event_free (crossing); } - emit_pointer_event (event, device); + emit_crossing_event (event, device); break; case CLUTTER_DESTROY_NOTIFY: @@ -2260,6 +1835,19 @@ _clutter_process_event_details (ClutterActor *stage, break; case CLUTTER_MOTION: +#ifdef CLUTTER_WINDOWING_X11 + if (!clutter_check_windowing_backend (CLUTTER_WINDOWING_X11) && + !(event->any.flags & CLUTTER_EVENT_FLAG_SYNTHETIC)) + { + if (_clutter_is_input_pointer_a11y_enabled (device)) + { + gfloat x, y; + + clutter_event_get_coords (event, &x, &y); + _clutter_input_pointer_a11y_on_motion_event (device, x, y); + } + } +#endif /* CLUTTER_WINDOWING_X11 */ /* only the stage gets motion events if they are enabled */ if (!clutter_stage_get_motion_events_enabled (CLUTTER_STAGE (stage)) && event->any.source == NULL) @@ -2270,15 +1858,7 @@ _clutter_process_event_details (ClutterActor *stage, if (_clutter_event_process_filters (event)) break; - /* global grabs */ - if (context->pointer_grab_actor != NULL) - { - clutter_actor_event (context->pointer_grab_actor, - event, - FALSE); - break; - } - else if (device != NULL && device->pointer_grab_actor != NULL) + if (device != NULL && device->pointer_grab_actor != NULL) { clutter_actor_event (device->pointer_grab_actor, event, @@ -2295,9 +1875,20 @@ _clutter_process_event_details (ClutterActor *stage, break; } - /* fallthrough from motion */ + G_GNUC_FALLTHROUGH; case CLUTTER_BUTTON_PRESS: case CLUTTER_BUTTON_RELEASE: +#ifdef CLUTTER_WINDOWING_X11 + if (!clutter_check_windowing_backend (CLUTTER_WINDOWING_X11)) + { + if (_clutter_is_input_pointer_a11y_enabled (device) && (event->type != CLUTTER_MOTION)) + { + _clutter_input_pointer_a11y_on_button_event (device, + event->button.button, + event->type == CLUTTER_BUTTON_PRESS); + } + } +#endif /* CLUTTER_WINDOWING_X11 */ case CLUTTER_SCROLL: case CLUTTER_TOUCHPAD_PINCH: case CLUTTER_TOUCHPAD_SWIPE: @@ -2351,7 +1942,7 @@ _clutter_process_event_details (ClutterActor *stage, * get the actor underneath */ if (device != NULL) - actor = _clutter_input_device_update (device, NULL, TRUE); + actor = clutter_input_device_update (device, NULL, TRUE); else { CLUTTER_NOTE (EVENT, "No device found: picking"); @@ -2424,7 +2015,7 @@ _clutter_process_event_details (ClutterActor *stage, break; } - /* fallthrough from motion */ + G_GNUC_FALLTHROUGH; case CLUTTER_TOUCH_BEGIN: case CLUTTER_TOUCH_CANCEL: case CLUTTER_TOUCH_END: @@ -2468,7 +2059,7 @@ _clutter_process_event_details (ClutterActor *stage, } if (device != NULL) - actor = _clutter_input_device_update (device, sequence, TRUE); + actor = clutter_input_device_update (device, sequence, TRUE); else { CLUTTER_NOTE (EVENT, "No device found: picking"); @@ -2519,7 +2110,7 @@ _clutter_process_event_details (ClutterActor *stage, break; case CLUTTER_STAGE_STATE: - /* fullscreen / focus - forward to stage */ + /* focus - forward to stage */ event->any.source = stage; if (!_clutter_event_process_filters (event)) clutter_stage_event (CLUTTER_STAGE (stage), event); @@ -2528,6 +2119,17 @@ _clutter_process_event_details (ClutterActor *stage, case CLUTTER_CLIENT_MESSAGE: break; + case CLUTTER_DEVICE_ADDED: + case CLUTTER_DEVICE_REMOVED: + if (!_clutter_event_process_filters (event)) + { + ClutterSeat *seat; + + seat = clutter_backend_get_default_seat (context->backend); + clutter_seat_handle_device_event (seat, event); + } + break; + case CLUTTER_EVENT_LAST: break; } @@ -2603,6 +2205,8 @@ clutter_base_init (void) /* initialise the Big Clutter Lock™ if necessary */ clutter_threads_init_default (); + + clutter_graphene_init (); } } @@ -2625,589 +2229,6 @@ clutter_get_default_frame_rate (void) return context->frame_rate; } -/** - * clutter_set_default_frame_rate: - * @frames_per_sec: the new default frame rate - * - * Sets the default frame rate. This frame rate will be used to limit - * the number of frames drawn if Clutter is not able to synchronize - * with the vertical refresh rate of the display. When synchronization - * is possible, this value is ignored. - * - * Since: 0.6 - * - * Deprecated: 1.10: This function does not do anything any more. - */ -void -clutter_set_default_frame_rate (guint frames_per_sec) -{ -} - -static void -on_grab_actor_destroy (ClutterActor *actor, - ClutterInputDevice *device) -{ - if (device == NULL) - { - ClutterMainContext *context = _clutter_context_get_default (); - - if (context->pointer_grab_actor == actor) - clutter_ungrab_pointer (); - - if (context->keyboard_grab_actor == actor) - clutter_ungrab_keyboard (); - - return; - } - - switch (device->device_type) - { - case CLUTTER_POINTER_DEVICE: - device->pointer_grab_actor = NULL; - break; - - case CLUTTER_KEYBOARD_DEVICE: - device->keyboard_grab_actor = NULL; - break; - - default: - g_assert_not_reached (); - } -} - -/** - * clutter_grab_pointer: - * @actor: a #ClutterActor - * - * Grabs pointer events, after the grab is done all pointer related events - * (press, motion, release, enter, leave and scroll) are delivered to this - * actor directly without passing through both capture and bubble phases of - * the event delivery chain. The source set in the event will be the actor - * that would have received the event if the pointer grab was not in effect. - * - * Grabs completely override the entire event delivery chain - * done by Clutter. Pointer grabs should only be used as a last resource; - * using the #ClutterActor::captured-event signal should always be the - * preferred way to intercept event delivery to reactive actors. - * - * This function should rarely be used. - * - * If a grab is required, you are strongly encouraged to use a specific - * input device by calling clutter_input_device_grab(). - * - * Since: 0.6 - */ -void -clutter_grab_pointer (ClutterActor *actor) -{ - ClutterMainContext *context; - - g_return_if_fail (actor == NULL || CLUTTER_IS_ACTOR (actor)); - - context = _clutter_context_get_default (); - - if (context->pointer_grab_actor == actor) - return; - - if (context->pointer_grab_actor != NULL) - { - g_signal_handlers_disconnect_by_func (context->pointer_grab_actor, - G_CALLBACK (on_grab_actor_destroy), - NULL); - context->pointer_grab_actor = NULL; - } - - if (actor != NULL) - { - context->pointer_grab_actor = actor; - - g_signal_connect (context->pointer_grab_actor, "destroy", - G_CALLBACK (on_grab_actor_destroy), - NULL); - } -} - -/** - * clutter_input_device_grab: - * @device: a #ClutterInputDevice - * @actor: a #ClutterActor - * - * Acquires a grab on @actor for the given @device. - * - * Any event coming from @device will be delivered to @actor, bypassing - * the usual event delivery mechanism, until the grab is released by - * calling clutter_input_device_ungrab(). - * - * The grab is client-side: even if the windowing system used by the Clutter - * backend has the concept of "device grabs", Clutter will not use them. - * - * Only #ClutterInputDevice of types %CLUTTER_POINTER_DEVICE and - * %CLUTTER_KEYBOARD_DEVICE can hold a grab. - * - * Since: 1.10 - */ -void -clutter_input_device_grab (ClutterInputDevice *device, - ClutterActor *actor) -{ - ClutterActor **grab_actor; - - g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device)); - g_return_if_fail (CLUTTER_IS_ACTOR (actor)); - - switch (device->device_type) - { - case CLUTTER_POINTER_DEVICE: - grab_actor = &(device->pointer_grab_actor); - break; - - case CLUTTER_KEYBOARD_DEVICE: - grab_actor = &(device->keyboard_grab_actor); - break; - - default: - g_critical ("Only pointer and keyboard devices can grab an actor"); - return; - } - - if (*grab_actor != NULL) - { - g_signal_handlers_disconnect_by_func (*grab_actor, - G_CALLBACK (on_grab_actor_destroy), - device); - } - - *grab_actor = actor; - - g_signal_connect (*grab_actor, - "destroy", - G_CALLBACK (on_grab_actor_destroy), - device); -} - -/** - * clutter_input_device_ungrab: - * @device: a #ClutterInputDevice - * - * Releases the grab on the @device, if one is in place. - * - * Since: 1.10 - */ -void -clutter_input_device_ungrab (ClutterInputDevice *device) -{ - ClutterActor **grab_actor; - - g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device)); - - switch (device->device_type) - { - case CLUTTER_POINTER_DEVICE: - grab_actor = &(device->pointer_grab_actor); - break; - - case CLUTTER_KEYBOARD_DEVICE: - grab_actor = &(device->keyboard_grab_actor); - break; - - default: - return; - } - - if (*grab_actor == NULL) - return; - - g_signal_handlers_disconnect_by_func (*grab_actor, - G_CALLBACK (on_grab_actor_destroy), - device); - - *grab_actor = NULL; -} - -/** - * clutter_input_device_get_grabbed_actor: - * @device: a #ClutterInputDevice - * - * Retrieves a pointer to the #ClutterActor currently grabbing all - * the events coming from @device. - * - * Return value: (transfer none): a #ClutterActor, or %NULL - * - * Since: 1.10 - */ -ClutterActor * -clutter_input_device_get_grabbed_actor (ClutterInputDevice *device) -{ - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL); - - switch (device->device_type) - { - case CLUTTER_POINTER_DEVICE: - return device->pointer_grab_actor; - - case CLUTTER_KEYBOARD_DEVICE: - return device->keyboard_grab_actor; - - default: - g_critical ("Only pointer and keyboard devices can grab an actor"); - } - - return NULL; -} - -/** - * clutter_grab_pointer_for_device: - * @actor: a #ClutterActor - * @id_: a device id, or -1 - * - * Grabs all the pointer events coming from the device @id for @actor. - * - * If @id is -1 then this function is equivalent to clutter_grab_pointer(). - * - * Since: 0.8 - * - * Deprecated: 1.10: Use clutter_input_device_grab() instead. - */ -void -clutter_grab_pointer_for_device (ClutterActor *actor, - gint id_) -{ - ClutterDeviceManager *manager; - ClutterInputDevice *dev; - - g_return_if_fail (actor == NULL || CLUTTER_IS_ACTOR (actor)); - - /* essentially a global grab */ - if (id_ == -1) - { - if (actor == NULL) - clutter_ungrab_pointer (); - else - clutter_grab_pointer (actor); - - return; - } - - manager = clutter_device_manager_get_default (); - if (manager == NULL) - return; - - dev = clutter_device_manager_get_device (manager, id_); - if (dev == NULL) - return; - - if (dev->device_type != CLUTTER_POINTER_DEVICE) - return; - - if (actor == NULL) - clutter_input_device_ungrab (dev); - else - clutter_input_device_grab (dev, actor); -} - - -/** - * clutter_ungrab_pointer: - * - * Removes an existing grab of the pointer. - * - * Since: 0.6 - */ -void -clutter_ungrab_pointer (void) -{ - clutter_grab_pointer (NULL); -} - -/** - * clutter_ungrab_pointer_for_device: - * @id_: a device id - * - * Removes an existing grab of the pointer events for device @id_. - * - * Since: 0.8 - * - * Deprecated: 1.10: Use clutter_input_device_ungrab() instead. - */ -void -clutter_ungrab_pointer_for_device (gint id_) -{ - ClutterDeviceManager *manager; - ClutterInputDevice *device; - - manager = clutter_device_manager_get_default (); - if (manager == NULL) - return; - - device = clutter_device_manager_get_device (manager, id_); - if (device != NULL) - clutter_input_device_ungrab (device); -} - - -/** - * clutter_get_pointer_grab: - * - * Queries the current pointer grab of clutter. - * - * Return value: (transfer none): the actor currently holding the pointer grab, or NULL if there is no grab. - * - * Since: 0.6 - */ -ClutterActor * -clutter_get_pointer_grab (void) -{ - ClutterMainContext *context; - context = _clutter_context_get_default (); - - return context->pointer_grab_actor; -} - - -/** - * clutter_grab_keyboard: - * @actor: a #ClutterActor - * - * Grabs keyboard events, after the grab is done keyboard - * events (#ClutterActor::key-press-event and #ClutterActor::key-release-event) - * are delivered to this actor directly. The source set in the event will be - * the actor that would have received the event if the keyboard grab was not - * in effect. - * - * Like pointer grabs, keyboard grabs should only be used as a last - * resource. - * - * See also clutter_stage_set_key_focus() and clutter_actor_grab_key_focus() - * to perform a "soft" key grab and assign key focus to a specific actor. - * - * Since: 0.6 - */ -void -clutter_grab_keyboard (ClutterActor *actor) -{ - ClutterMainContext *context; - - g_return_if_fail (actor == NULL || CLUTTER_IS_ACTOR (actor)); - - context = _clutter_context_get_default (); - - if (context->keyboard_grab_actor == actor) - return; - - if (context->keyboard_grab_actor != NULL) - { - g_signal_handlers_disconnect_by_func (context->keyboard_grab_actor, - G_CALLBACK (on_grab_actor_destroy), - NULL); - context->keyboard_grab_actor = NULL; - } - - if (actor != NULL) - { - context->keyboard_grab_actor = actor; - - g_signal_connect (context->keyboard_grab_actor, "destroy", - G_CALLBACK (on_grab_actor_destroy), - NULL); - } -} - -/** - * clutter_ungrab_keyboard: - * - * Removes an existing grab of the keyboard. - * - * Since: 0.6 - */ -void -clutter_ungrab_keyboard (void) -{ - clutter_grab_keyboard (NULL); -} - -/** - * clutter_get_keyboard_grab: - * - * Queries the current keyboard grab of clutter. - * - * Return value: (transfer none): the actor currently holding the keyboard grab, or NULL if there is no grab. - * - * Since: 0.6 - */ -ClutterActor * -clutter_get_keyboard_grab (void) -{ - ClutterMainContext *context; - - context = _clutter_context_get_default (); - - return context->keyboard_grab_actor; -} - -/** - * clutter_clear_glyph_cache: - * - * Clears the internal cache of glyphs used by the Pango - * renderer. This will free up some memory and GL texture - * resources. The cache will be automatically refilled as more text is - * drawn. - * - * Since: 0.8 - * - * Deprecated: 1.10: Use clutter_get_font_map() and - * cogl_pango_font_map_clear_glyph_cache() instead. - */ -void -clutter_clear_glyph_cache (void) -{ - CoglPangoFontMap *font_map; - - font_map = clutter_context_get_pango_fontmap (); - cogl_pango_font_map_clear_glyph_cache (font_map); -} - -/** - * clutter_set_font_flags: - * @flags: The new flags - * - * Sets the font quality options for subsequent text rendering - * operations. - * - * Using mipmapped textures will improve the quality for scaled down - * text but will use more texture memory. - * - * Enabling hinting improves text quality for static text but may - * introduce some artifacts if the text is animated. - * - * Since: 1.0 - * - * Deprecated: 1.10: Use clutter_backend_set_font_options() and the - * #cairo_font_option_t API. - */ -void -clutter_set_font_flags (ClutterFontFlags flags) -{ - CoglPangoFontMap *font_map; - ClutterFontFlags old_flags, changed_flags; - const cairo_font_options_t *font_options; - cairo_font_options_t *new_font_options; - cairo_hint_style_t hint_style; - gboolean use_mipmapping; - ClutterBackend *backend; - - backend = clutter_get_default_backend (); - font_map = clutter_context_get_pango_fontmap (); - font_options = clutter_backend_get_font_options (backend); - old_flags = 0; - - if (cogl_pango_font_map_get_use_mipmapping (font_map)) - old_flags |= CLUTTER_FONT_MIPMAPPING; - - hint_style = cairo_font_options_get_hint_style (font_options); - if (hint_style != CAIRO_HINT_STYLE_DEFAULT && - hint_style != CAIRO_HINT_STYLE_NONE) - old_flags |= CLUTTER_FONT_HINTING; - - if (old_flags == flags) - return; - - new_font_options = cairo_font_options_copy (font_options); - - /* Only set the font options that have actually changed so we don't - override a detailed setting from the backend */ - changed_flags = old_flags ^ flags; - - if ((changed_flags & CLUTTER_FONT_MIPMAPPING)) - { - use_mipmapping = (changed_flags & CLUTTER_FONT_MIPMAPPING) != 0; - - cogl_pango_font_map_set_use_mipmapping (font_map, use_mipmapping); - } - - if ((changed_flags & CLUTTER_FONT_HINTING)) - { - hint_style = (flags & CLUTTER_FONT_HINTING) - ? CAIRO_HINT_STYLE_FULL - : CAIRO_HINT_STYLE_NONE; - - cairo_font_options_set_hint_style (new_font_options, hint_style); - } - - clutter_backend_set_font_options (backend, new_font_options); - - cairo_font_options_destroy (new_font_options); -} - -/** - * clutter_get_font_flags: - * - * Gets the current font flags for rendering text. See - * clutter_set_font_flags(). - * - * Return value: The font flags - * - * Since: 1.0 - * - * Deprecated: 1.10: Use clutter_backend_get_font_options() and the - * #cairo_font_options_t API. - */ -ClutterFontFlags -clutter_get_font_flags (void) -{ - CoglPangoFontMap *font_map = NULL; - const cairo_font_options_t *font_options; - ClutterFontFlags flags = 0; - cairo_hint_style_t hint_style; - - font_map = clutter_context_get_pango_fontmap (); - if (cogl_pango_font_map_get_use_mipmapping (font_map)) - flags |= CLUTTER_FONT_MIPMAPPING; - - font_options = - clutter_backend_get_font_options (clutter_get_default_backend ()); - - hint_style = cairo_font_options_get_hint_style (font_options); - if (hint_style != CAIRO_HINT_STYLE_DEFAULT && - hint_style != CAIRO_HINT_STYLE_NONE) - flags |= CLUTTER_FONT_HINTING; - - return flags; -} - -/** - * clutter_get_input_device_for_id: - * @id_: the unique id for a device - * - * Retrieves the #ClutterInputDevice from its @id_. This is a convenience - * wrapper for clutter_device_manager_get_device() and it is functionally - * equivalent to: - * - * |[ - * ClutterDeviceManager *manager; - * ClutterInputDevice *device; - * - * manager = clutter_device_manager_get_default (); - * device = clutter_device_manager_get_device (manager, id); - * ]| - * - * Return value: (transfer none): a #ClutterInputDevice, or %NULL - * - * Since: 0.8 - * - * Deprecated: 1.10: Use clutter_device_manager_get_device() instead. - */ -ClutterInputDevice * -clutter_get_input_device_for_id (gint id_) -{ - ClutterDeviceManager *manager; - - manager = clutter_device_manager_get_default (); - if (manager == NULL) - return NULL; - - return clutter_device_manager_get_device (manager, id_); -} - /** * clutter_get_font_map: * @@ -3300,8 +2321,7 @@ clutter_threads_remove_repaint_func (guint handle_id) * that it does not block, otherwise the frame time budget may be lost. * * A repaint function is useful to ensure that an update of the scenegraph - * is performed before the scenegraph is repainted; for instance, uploading - * a frame from a video into a #ClutterTexture. By default, a repaint + * is performed before the scenegraph is repainted. By default, a repaint * function added using this function will be invoked prior to the frame * being processed. * @@ -3350,8 +2370,7 @@ clutter_threads_add_repaint_func (GSourceFunc func, * that it does not block, otherwise the frame time budget may be lost. * * A repaint function is useful to ensure that an update of the scenegraph - * is performed before the scenegraph is repainted; for instance, uploading - * a frame from a video into a #ClutterTexture. The @flags passed to this + * is performed before the scenegraph is repainted. The @flags passed to this * function will determine the section of the frame processing that will * result in @func being called. * @@ -3470,36 +2489,6 @@ _clutter_run_repaint_functions (ClutterRepaintFlags flags) context->repaint_funcs = g_list_reverse (reinvoke_list); } -/** - * clutter_check_version: - * @major: major version, like 1 in 1.2.3 - * @minor: minor version, like 2 in 1.2.3 - * @micro: micro version, like 3 in 1.2.3 - * - * Run-time version check, to check the version the Clutter library - * that an application is currently linked against - * - * This is the run-time equivalent of the compile-time %CLUTTER_CHECK_VERSION - * pre-processor macro - * - * Return value: %TRUE if the version of the Clutter library is - * greater than (@major, @minor, @micro), and %FALSE otherwise - * - * Since: 1.2 - */ -gboolean -clutter_check_version (guint major, - guint minor, - guint micro) -{ - return (clutter_major_version > major || - (clutter_major_version == major && - clutter_minor_version > minor) || - (clutter_major_version == major && - clutter_minor_version == minor && - clutter_micro_version >= micro)); -} - /** * clutter_get_default_text_direction: * @@ -3572,43 +2561,6 @@ _clutter_context_get_pick_mode (void) return context->pick_mode; } -void -_clutter_context_push_shader_stack (ClutterActor *actor) -{ - ClutterMainContext *context = _clutter_context_get_default (); - - context->shaders = g_slist_prepend (context->shaders, actor); -} - -ClutterActor * -_clutter_context_peek_shader_stack (void) -{ - ClutterMainContext *context = _clutter_context_get_default (); - - if (context->shaders != NULL) - return context->shaders->data; - - return NULL; -} - -ClutterActor * -_clutter_context_pop_shader_stack (ClutterActor *actor) -{ - ClutterMainContext *context = _clutter_context_get_default (); - - context->shaders = g_slist_remove (context->shaders, actor); - - return _clutter_context_peek_shader_stack (); -} - -gboolean -_clutter_context_get_motion_events_enabled (void) -{ - ClutterMainContext *context = _clutter_context_get_default (); - - return context->motion_events_per_actor; -} - /** * clutter_check_windowing_backend: * @backend_type: the name of the backend to check @@ -3661,28 +2613,40 @@ clutter_check_windowing_backend (const char *backend_type) return FALSE; } +/** + * clutter_add_debug_flags: (skip) + * + * Adds the debug flags passed to the list of debug flags. + */ void -_clutter_set_sync_to_vblank (gboolean sync_to_vblank) +clutter_add_debug_flags (ClutterDebugFlag debug_flags, + ClutterDrawDebugFlag draw_flags, + ClutterPickDebugFlag pick_flags) { - clutter_sync_to_vblank = !!sync_to_vblank; -} - -gboolean -_clutter_get_sync_to_vblank (void) -{ - return clutter_sync_to_vblank; + clutter_debug_flags |= debug_flags; + clutter_paint_debug_flags |= draw_flags; + clutter_pick_debug_flags |= pick_flags; } +/** + * clutter_remove_debug_flags: (skip) + * + * Removes the debug flags passed from the list of debug flags. + */ void -_clutter_set_sync_method (SyncMethod sync_method) +clutter_remove_debug_flags (ClutterDebugFlag debug_flags, + ClutterDrawDebugFlag draw_flags, + ClutterPickDebugFlag pick_flags) { - clutter_sync_method = sync_method; + clutter_debug_flags &= ~debug_flags; + clutter_paint_debug_flags &= ~draw_flags; + clutter_pick_debug_flags &= ~pick_flags; } -SyncMethod -_clutter_get_sync_method (void) +void +_clutter_set_sync_to_vblank (gboolean sync_to_vblank) { - return clutter_sync_method; + clutter_sync_to_vblank = !!sync_to_vblank; } void @@ -3714,11 +2678,11 @@ _clutter_debug_messagev (const char *format, } fmt = g_strconcat (stamp, ":", format, NULL); - free (stamp); + g_free (stamp); g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, fmt, var_args); - free (fmt); + g_free (fmt); } void @@ -3759,5 +2723,5 @@ _clutter_diagnostic_message (const char *format, ...) g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, fmt, args); va_end (args); - free (fmt); + g_free (fmt); } diff --git a/clutter/clutter/clutter-main.h b/clutter/clutter/clutter-main.h index 21bdb06c3..32653f61a 100644 --- a/clutter/clutter/clutter-main.h +++ b/clutter/clutter/clutter-main.h @@ -34,6 +34,45 @@ G_BEGIN_DECLS +typedef enum +{ + CLUTTER_DEBUG_MISC = 1 << 0, + CLUTTER_DEBUG_ACTOR = 1 << 1, + CLUTTER_DEBUG_TEXTURE = 1 << 2, + CLUTTER_DEBUG_EVENT = 1 << 3, + CLUTTER_DEBUG_PAINT = 1 << 4, + CLUTTER_DEBUG_PANGO = 1 << 5, + CLUTTER_DEBUG_BACKEND = 1 << 6, + CLUTTER_DEBUG_SCHEDULER = 1 << 7, + CLUTTER_DEBUG_SCRIPT = 1 << 8, + CLUTTER_DEBUG_SHADER = 1 << 9, + CLUTTER_DEBUG_MULTISTAGE = 1 << 10, + CLUTTER_DEBUG_ANIMATION = 1 << 11, + CLUTTER_DEBUG_LAYOUT = 1 << 12, + CLUTTER_DEBUG_PICK = 1 << 13, + CLUTTER_DEBUG_EVENTLOOP = 1 << 14, + CLUTTER_DEBUG_CLIPPING = 1 << 15, + CLUTTER_DEBUG_OOB_TRANSFORMS = 1 << 16, +} ClutterDebugFlag; + +typedef enum +{ + CLUTTER_DEBUG_NOP_PICKING = 1 << 0, +} ClutterPickDebugFlag; + +typedef enum +{ + CLUTTER_DEBUG_DISABLE_SWAP_EVENTS = 1 << 0, + CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS = 1 << 1, + CLUTTER_DEBUG_REDRAWS = 1 << 2, + CLUTTER_DEBUG_PAINT_VOLUMES = 1 << 3, + CLUTTER_DEBUG_DISABLE_CULLING = 1 << 4, + CLUTTER_DEBUG_DISABLE_OFFSCREEN_REDIRECT = 1 << 5, + CLUTTER_DEBUG_CONTINUOUS_REDRAW = 1 << 6, + CLUTTER_DEBUG_PAINT_DEFORM_TILES = 1 << 7, + CLUTTER_DEBUG_PAINT_DAMAGE_REGION = 1 << 8, +} ClutterDrawDebugFlag; + /** * CLUTTER_INIT_ERROR: * @@ -53,7 +92,8 @@ G_BEGIN_DECLS * * Since: 0.2 */ -typedef enum { +typedef enum +{ CLUTTER_INIT_SUCCESS = 1, CLUTTER_INIT_ERROR_UNKNOWN = 0, CLUTTER_INIT_ERROR_THREADS = -1, @@ -61,7 +101,7 @@ typedef enum { CLUTTER_INIT_ERROR_INTERNAL = -3 } ClutterInitError; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT GQuark clutter_init_error_quark (void); /** @@ -78,12 +118,12 @@ GQuark clutter_init_error_quark (void); #define CLUTTER_PRIORITY_REDRAW (G_PRIORITY_HIGH_IDLE + 50) /* Initialisation */ -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_base_init (void); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterInitError clutter_init (int *argc, char ***argv) G_GNUC_WARN_UNUSED_RESULT; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterInitError clutter_init_with_args (int *argc, char ***argv, const char *parameter_string, @@ -91,93 +131,81 @@ ClutterInitError clutter_init_with_args (int *a const char *translation_domain, GError **error) G_GNUC_WARN_UNUSED_RESULT; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT GOptionGroup * clutter_get_option_group (void); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT GOptionGroup * clutter_get_option_group_without_init (void); /* Mainloop */ -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_main (void); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_main_quit (void); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gint clutter_main_level (void); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_do_event (ClutterEvent *event); /* Debug utility functions */ -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT gboolean clutter_get_accessibility_enabled (void); -CLUTTER_AVAILABLE_IN_1_14 +CLUTTER_EXPORT void clutter_disable_accessibility (void); /* Threading functions */ -CLUTTER_AVAILABLE_IN_ALL -void clutter_threads_set_lock_functions (GCallback enter_fn, - GCallback leave_fn); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT guint clutter_threads_add_idle (GSourceFunc func, gpointer data); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT guint clutter_threads_add_idle_full (gint priority, GSourceFunc func, gpointer data, GDestroyNotify notify); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT guint clutter_threads_add_timeout (guint interval, GSourceFunc func, gpointer data); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT guint clutter_threads_add_timeout_full (gint priority, guint interval, GSourceFunc func, gpointer data, GDestroyNotify notify); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT guint clutter_threads_add_repaint_func (GSourceFunc func, gpointer data, GDestroyNotify notify); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT guint clutter_threads_add_repaint_func_full (ClutterRepaintFlags flags, GSourceFunc func, gpointer data, GDestroyNotify notify); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_threads_remove_repaint_func (guint handle_id); -CLUTTER_AVAILABLE_IN_ALL -void clutter_grab_pointer (ClutterActor *actor); -CLUTTER_AVAILABLE_IN_ALL -void clutter_ungrab_pointer (void); -CLUTTER_AVAILABLE_IN_ALL -ClutterActor * clutter_get_pointer_grab (void); -CLUTTER_AVAILABLE_IN_ALL -void clutter_grab_keyboard (ClutterActor *actor); -CLUTTER_AVAILABLE_IN_ALL -void clutter_ungrab_keyboard (void); -CLUTTER_AVAILABLE_IN_ALL -ClutterActor * clutter_get_keyboard_grab (void); - -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT PangoFontMap * clutter_get_font_map (void); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterTextDirection clutter_get_default_text_direction (void); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT guint clutter_get_default_frame_rate (void); -CLUTTER_AVAILABLE_IN_1_2 -gboolean clutter_check_version (guint major, - guint minor, - guint micro); - -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT gboolean clutter_check_windowing_backend (const char *backend_type); +CLUTTER_EXPORT +void clutter_add_debug_flags (ClutterDebugFlag debug_flags, + ClutterDrawDebugFlag draw_flags, + ClutterPickDebugFlag pick_flags); + +CLUTTER_EXPORT +void clutter_remove_debug_flags (ClutterDebugFlag debug_flags, + ClutterDrawDebugFlag draw_flags, + ClutterPickDebugFlag pick_flags); G_END_DECLS diff --git a/clutter/clutter/clutter-marshal.list b/clutter/clutter/clutter-marshal.list index 0584df03c..cb64b2dfa 100644 --- a/clutter/clutter/clutter-marshal.list +++ b/clutter/clutter/clutter-marshal.list @@ -1,6 +1,7 @@ BOOLEAN:BOXED BOOLEAN:BOXED,INT,INT BOOLEAN:OBJECT,BOOLEAN +BOOLEAN:OBJECT,BOXED BOOLEAN:OBJECT,BOXED,DOUBLE BOOLEAN:OBJECT,DOUBLE BOOLEAN:OBJECT,ENUM @@ -11,29 +12,24 @@ BOOLEAN:OBJECT,FLOAT,FLOAT BOXED:UINT,UINT DOUBLE:VOID UINT:VOID -VOID:BOOLEAN -VOID:BOXED VOID:BOXED,FLAGS -VOID:INT VOID:INT64,INT64,FLOAT,BOOLEAN VOID:INT,INT VOID:INT,POINTER VOID:FLOAT,FLOAT VOID:INT,INT,INT,INT -VOID:OBJECT VOID:OBJECT,FLAGS +VOID:OBJECT,FLAGS,BOOLEAN +VOID:OBJECT,FLAGS,UINT VOID:OBJECT,FLOAT,FLOAT VOID:OBJECT,FLOAT,FLOAT,FLAGS VOID:OBJECT,OBJECT VOID:OBJECT,PARAM VOID:OBJECT,POINTER VOID:OBJECT,UINT -VOID:POINTER VOID:STRING,BOOLEAN VOID:STRING,BOOLEAN,BOOLEAN VOID:STRING,INT -VOID:UINT VOID:UINT,STRING,UINT VOID:UINT,UINT -VOID:VOID VOID:STRING,INT,POINTER diff --git a/clutter/clutter/clutter-master-clock-default.c b/clutter/clutter/clutter-master-clock-default.c index 45938b107..d419a89f8 100644 --- a/clutter/clutter/clutter-master-clock-default.c +++ b/clutter/clutter/clutter-master-clock-default.c @@ -29,9 +29,9 @@ * of #ClutterMasterClock. */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif + +#include #include "clutter-master-clock.h" #include "clutter-master-clock-default.h" @@ -39,7 +39,6 @@ #include "clutter-private.h" #include "clutter-stage-manager-private.h" #include "clutter-stage-private.h" -#include "clutter-muffin.h" #ifdef CLUTTER_ENABLE_DEBUG #define clutter_warn_if_over_budget(master_clock,start_time,section) G_STMT_START { \ @@ -64,14 +63,9 @@ struct _ClutterMasterClockDefault /* the list of timelines handled by the clock */ GSList *timelines; - SyncMethod preferred_sync_method, active_sync_method; - /* the current state of the clock, in usecs */ gint64 cur_tick; - /* the previous state of the clock, in usecs, used to compute the delta */ - gint64 prev_tick; - #ifdef CLUTTER_ENABLE_DEBUG gint64 frame_budget; gint64 remaining_budget; @@ -85,7 +79,6 @@ struct _ClutterMasterClockDefault guint ensure_next_iteration : 1; guint paused : 1; - guint sync_available : 1; }; struct _ClutterClockSource @@ -109,9 +102,8 @@ static GSourceFuncs clock_funcs = { NULL }; -static void clutter_master_clock_iface_init (ClutterMasterClockIface *iface); - -static gint64 master_clock_next_frame_time (ClutterMasterClockDefault *); +static void +clutter_master_clock_iface_init (ClutterMasterClockInterface *iface); #define clutter_master_clock_default_get_type _clutter_master_clock_default_get_type @@ -121,8 +113,6 @@ G_DEFINE_TYPE_WITH_CODE (ClutterMasterClockDefault, G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_MASTER_CLOCK, clutter_master_clock_iface_init)); -static ClutterMasterClockDefault *master_clock_global = NULL; - /* * master_clock_is_running: * @master_clock: a #ClutterMasterClock @@ -139,20 +129,14 @@ master_clock_is_running (ClutterMasterClockDefault *master_clock) ClutterStageManager *stage_manager = clutter_stage_manager_get_default (); const GSList *stages, *l; + stages = clutter_stage_manager_peek_stages (stage_manager); + if (master_clock->paused) return FALSE; if (master_clock->timelines) return TRUE; - if (master_clock->ensure_next_iteration) - { - master_clock->ensure_next_iteration = FALSE; - return TRUE; - } - - stages = stage_manager->stages; - for (l = stages; l; l = l->next) { if (clutter_actor_is_mapped (l->data) && @@ -161,17 +145,23 @@ master_clock_is_running (ClutterMasterClockDefault *master_clock) return TRUE; } + if (master_clock->ensure_next_iteration) + { + master_clock->ensure_next_iteration = FALSE; + return TRUE; + } + return FALSE; } -static gint64 -master_clock_get_hw_update_time (ClutterMasterClockDefault *master_clock) +static gint +master_clock_get_swap_wait_time (ClutterMasterClockDefault *master_clock) { ClutterStageManager *stage_manager = clutter_stage_manager_get_default (); const GSList *stages, *l; gint64 min_update_time = -1; - stages = stage_manager->stages;; + stages = clutter_stage_manager_peek_stages (stage_manager); for (l = stages; l != NULL; l = l->next) { @@ -181,7 +171,43 @@ master_clock_get_hw_update_time (ClutterMasterClockDefault *master_clock) min_update_time = update_time; } - return min_update_time; + if (min_update_time == -1) + { + return -1; + } + else + { + gint64 now = g_source_get_time (master_clock->source); + if (min_update_time < now) + { + return 0; + } + else + { + gint64 delay_us = min_update_time - now; + return (delay_us + 999) / 1000; + } + } +} + +static int64_t +master_clock_get_next_presentation_time (ClutterMasterClockDefault *master_clock) +{ + ClutterStageManager *stage_manager = clutter_stage_manager_get_default (); + const GSList *stages, *l; + int64_t earliest = -1; + + stages = clutter_stage_manager_peek_stages (stage_manager); + + for (l = stages; l != NULL; l = l->next) + { + gint64 t = _clutter_stage_get_next_presentation_time (l->data); + + if (earliest == -1 || (t != -1 && t < earliest)) + earliest = t; + } + + return earliest; } static void @@ -190,10 +216,10 @@ master_clock_schedule_stage_updates (ClutterMasterClockDefault *master_clock) ClutterStageManager *stage_manager = clutter_stage_manager_get_default (); const GSList *stages, *l; - stages = stage_manager->stages; + stages = clutter_stage_manager_peek_stages (stage_manager); for (l = stages; l != NULL; l = l->next) - _clutter_stage_schedule_update (l->data); + clutter_stage_schedule_update (l->data); } static GSList * @@ -203,24 +229,28 @@ master_clock_list_ready_stages (ClutterMasterClockDefault *master_clock) const GSList *stages, *l; GSList *result; - stages = stage_manager->stages;; + stages = clutter_stage_manager_peek_stages (stage_manager); result = NULL; for (l = stages; l != NULL; l = l->next) { - gint64 update_time = -1; - - if (master_clock->active_sync_method == SYNC_PRESENTATION_TIME) - update_time = _clutter_stage_get_update_time (l->data); - + gint64 update_time = _clutter_stage_get_update_time (l->data); /* We carefully avoid to update stages that aren't mapped, because * they have nothing to render and this could cause a deadlock with * some of the SwapBuffers implementations (in particular * GLX_INTEL_swap_event is not emitted if nothing was rendered). + * + * Also, if a stage has a swap-buffers pending we don't want to draw + * to it in case the driver may block the CPU while it waits for the + * next backbuffer to become available. + * + * TODO: We should be able to identify if we are running triple or N + * buffered and in these cases we can still draw if there is 1 swap + * pending so we can hopefully always be ready to swap for the next + * vblank and really match the vsync frequency. */ - if (clutter_actor_is_mapped (l->data) && - update_time <= master_clock->cur_tick) + update_time != -1 && update_time <= master_clock->cur_tick) result = g_slist_prepend (result, g_object_ref (l->data)); } @@ -242,62 +272,8 @@ master_clock_reschedule_stage_updates (ClutterMasterClockDefault *master_clock, if (master_clock->timelines || _clutter_stage_has_queued_events (l->data) || _clutter_stage_needs_update (l->data)) - _clutter_stage_schedule_update (l->data); - } -} - -/* - * master_clock_next_frame_time: - * @master_clock: a #ClutterMasterClock - * - * Computes the optimal next frame time for dispatching the master clock. - * Wherever possible this will be higher than master_clock->prev_tick. - * - * The goal here is to trigger dispatches as seldom as possible, but often - * enough to maintain full frame rate. - * - * Return value: A valid timestamp in microseconds. Never fails. - */ -static gint64 -master_clock_next_frame_time (ClutterMasterClockDefault *master_clock) -{ - gint64 next, now, interval; - - if (master_clock->preferred_sync_method >= SYNC_PRESENTATION_TIME) - { - next = master_clock_get_hw_update_time (master_clock); - if (next >= 0) - { - master_clock->active_sync_method = SYNC_PRESENTATION_TIME; - return next; - } - } - - now = g_source_get_time (master_clock->source); - - if (!master_clock->prev_tick || - master_clock->preferred_sync_method == SYNC_NONE) - { - master_clock->active_sync_method = SYNC_NONE; - return now; + clutter_stage_schedule_update (l->data); } - - /* We will usually have backend hardware features available to throttle our - * frame rate so no additional delay is needed to start the next frame. - */ - if (master_clock->preferred_sync_method >= SYNC_SWAP_THROTTLING || - master_clock->sync_available) - { - master_clock->active_sync_method = SYNC_SWAP_THROTTLING; - return now; - } - - master_clock->active_sync_method = SYNC_FALLBACK; - interval = 1000000 / clutter_get_default_frame_rate (); - next = master_clock->prev_tick + interval; - if (next < (now - interval)) /* Too old? Must have been sleeping. */ - next = now; - return next; } /* @@ -312,30 +288,12 @@ master_clock_next_frame_time (ClutterMasterClockDefault *master_clock) static gint master_clock_next_frame_delay (ClutterMasterClockDefault *master_clock) { - gint64 now, next; - gint delay_ms; - if (!master_clock_is_running (master_clock)) return -1; - now = g_source_get_time (master_clock->source); - next = master_clock_next_frame_time (master_clock); - - /* Round your microseconds UP to milliseconds! If we were to round down - * then we'd spend an entire millisecond per frame continuously - * dispatching without any throttling. Thus spinning the CPU at around 6% - * for a 60Hz display. - */ - if (next > now) - delay_ms = (next - now + 999) / 1000; /* Always round up! */ - else - delay_ms = 0; - -#ifdef CLUTTER_ENABLE_DEBUG - CLUTTER_NOTE (SCHEDULER, "Waiting %d ms", delay_ms); -#endif - - return delay_ms; + /* If all of the stages are busy waiting for a swap-buffers to complete + * then we wait for one to be ready.. */ + return master_clock_get_swap_wait_time (master_clock); } static void @@ -401,8 +359,7 @@ master_clock_advance_timelines (ClutterMasterClockDefault *master_clock) for (l = timelines; l != NULL; l = l->next) _clutter_timeline_do_tick (l->data, master_clock->cur_tick / 1000); - g_slist_foreach (timelines, (GFunc) g_object_unref, NULL); - g_slist_free (timelines); + g_slist_free_full (timelines, g_object_unref); #ifdef CLUTTER_ENABLE_DEBUG if (_clutter_diagnostic_enabled ()) @@ -460,6 +417,8 @@ clutter_clock_source_new (ClutterMasterClockDefault *master_clock) ClutterClockSource *clock_source = (ClutterClockSource *) source; g_source_set_name (source, "Clutter master clock"); + g_source_set_priority (source, CLUTTER_PRIORITY_REDRAW); + g_source_set_can_recurse (source, FALSE); clock_source->master_clock = master_clock; return source; @@ -473,13 +432,15 @@ clutter_clock_prepare (GSource *source, ClutterMasterClockDefault *master_clock = clock_source->master_clock; int delay; + _clutter_threads_acquire_lock (); + if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_CONTINUOUS_REDRAW)) { ClutterStageManager *stage_manager = clutter_stage_manager_get_default (); const GSList *stages, *l; - stages = stage_manager->stages;; + stages = clutter_stage_manager_peek_stages (stage_manager); /* Queue a full redraw on all of the stages */ for (l = stages; l != NULL; l = l->next) @@ -488,6 +449,8 @@ clutter_clock_prepare (GSource *source, delay = master_clock_next_frame_delay (master_clock); + _clutter_threads_release_lock (); + *timeout = delay; return delay == 0; @@ -500,7 +463,9 @@ clutter_clock_check (GSource *source) ClutterMasterClockDefault *master_clock = clock_source->master_clock; int delay; + _clutter_threads_acquire_lock (); delay = master_clock_next_frame_delay (master_clock); + _clutter_threads_release_lock (); return delay == 0; } @@ -514,12 +479,18 @@ clutter_clock_dispatch (GSource *source, ClutterMasterClockDefault *master_clock = clock_source->master_clock; GSList *stages; -#ifdef CLUTTER_ENABLE_DEBUG CLUTTER_NOTE (SCHEDULER, "Master clock [tick]"); -#endif + + _clutter_threads_acquire_lock (); + + COGL_TRACE_BEGIN (ClutterMasterClockTick, "Master Clock (tick)"); /* Get the time to use for this frame */ - master_clock->cur_tick = master_clock_next_frame_time (master_clock); + master_clock->cur_tick = master_clock_get_next_presentation_time (master_clock); + + /* On the first frame the backend might not have an answer */ + if (master_clock->cur_tick <= 0) + master_clock->cur_tick = g_source_get_time (source); #ifdef CLUTTER_ENABLE_DEBUG master_clock->remaining_budget = master_clock->frame_budget; @@ -547,10 +518,11 @@ clutter_clock_dispatch (GSource *source, master_clock_reschedule_stage_updates (master_clock, stages); - g_slist_foreach (stages, (GFunc) g_object_unref, NULL); - g_slist_free (stages); + g_slist_free_full (stages, g_object_unref); + + COGL_TRACE_END (ClutterMasterClockTick); - master_clock->prev_tick = master_clock->cur_tick; + _clutter_threads_release_lock (); return TRUE; } @@ -573,62 +545,21 @@ clutter_master_clock_default_class_init (ClutterMasterClockDefaultClass *klass) gobject_class->finalize = clutter_master_clock_default_finalize; } -void -clutter_master_clock_set_sync_method (SyncMethod method) -{ - const GSList *stages, *l; - ClutterStageManager *stage_manager = clutter_stage_manager_get_default (); - - switch (method) - { - case SYNC_NONE: - g_message ("Sync method: NONE"); - break; - case SYNC_PRESENTATION_TIME: - g_message ("Sync method: PRESENTATION TIME"); - break; - case SYNC_FALLBACK: - g_message ("Sync method: FALLBACK"); - break; - case SYNC_SWAP_THROTTLING: - g_message ("Sync method: SWAP THROTTLING"); - break; - default: - g_warning ("Invalid sync state passed to clutter_master_clock_set_sync_method: %i", method); - } - - master_clock_global->preferred_sync_method = method; - - stages = stage_manager->stages; - - for (l = stages; l; l = l->next) - { - _clutter_stage_clear_update_time (l->data); - } -} - static void clutter_master_clock_default_init (ClutterMasterClockDefault *self) { - GSource *source = clutter_clock_source_new (self); - SyncMethod method = _clutter_get_sync_method (); + GSource *source; + source = clutter_clock_source_new (self); self->source = source; - master_clock_global = self; - - self->active_sync_method = method; - clutter_master_clock_set_sync_method (method); self->ensure_next_iteration = FALSE; self->paused = FALSE; - self->sync_available = clutter_feature_available (CLUTTER_FEATURE_SYNC_TO_VBLANK); #ifdef CLUTTER_ENABLE_DEBUG self->frame_budget = G_USEC_PER_SEC / 60; #endif - g_source_set_priority (source, CLUTTER_PRIORITY_REDRAW); - g_source_set_can_recurse (source, FALSE); g_source_attach (source, NULL); } @@ -687,11 +618,21 @@ clutter_master_clock_default_set_paused (ClutterMasterClock *clock, { ClutterMasterClockDefault *master_clock = (ClutterMasterClockDefault *) clock; + if (paused && !master_clock->paused) + { + g_clear_pointer (&master_clock->source, g_source_destroy); + } + else if (!paused && master_clock->paused) + { + master_clock->source = clutter_clock_source_new (master_clock); + g_source_attach (master_clock->source, NULL); + } + master_clock->paused = !!paused; } static void -clutter_master_clock_iface_init (ClutterMasterClockIface *iface) +clutter_master_clock_iface_init (ClutterMasterClockInterface *iface) { iface->add_timeline = clutter_master_clock_default_add_timeline; iface->remove_timeline = clutter_master_clock_default_remove_timeline; diff --git a/clutter/clutter/clutter-master-clock.c b/clutter/clutter/clutter-master-clock.c index 379df3a5e..c4dff9676 100644 --- a/clutter/clutter/clutter-master-clock.c +++ b/clutter/clutter/clutter-master-clock.c @@ -31,18 +31,12 @@ * painting it. */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include "clutter-master-clock.h" #include "clutter-master-clock-default.h" #include "clutter-private.h" -#define clutter_master_clock_get_type _clutter_master_clock_get_type - -typedef ClutterMasterClockIface ClutterMasterClockInterface; - G_DEFINE_INTERFACE (ClutterMasterClock, clutter_master_clock, G_TYPE_OBJECT) static void diff --git a/clutter/clutter/clutter-master-clock.h b/clutter/clutter/clutter-master-clock.h index 542b9176b..36e974f53 100644 --- a/clutter/clutter/clutter-master-clock.h +++ b/clutter/clutter/clutter-master-clock.h @@ -28,15 +28,12 @@ G_BEGIN_DECLS -#define CLUTTER_TYPE_MASTER_CLOCK (_clutter_master_clock_get_type ()) -#define CLUTTER_MASTER_CLOCK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_MASTER_CLOCK, ClutterMasterClock)) -#define CLUTTER_IS_MASTER_CLOCK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_MASTER_CLOCK)) -#define CLUTTER_MASTER_CLOCK_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), CLUTTER_TYPE_MASTER_CLOCK, ClutterMasterClockIface)) +#define CLUTTER_TYPE_MASTER_CLOCK (clutter_master_clock_get_type ()) +G_DECLARE_INTERFACE (ClutterMasterClock, clutter_master_clock, + CLUTTER, MASTER_CLOCK, + GObject) -typedef struct _ClutterMasterClock ClutterMasterClock; /* dummy */ -typedef struct _ClutterMasterClockIface ClutterMasterClockIface; - -struct _ClutterMasterClockIface +struct _ClutterMasterClockInterface { /*< private >*/ GTypeInterface parent_iface; @@ -51,8 +48,6 @@ struct _ClutterMasterClockIface gboolean paused); }; -GType _clutter_master_clock_get_type (void) G_GNUC_CONST; - ClutterMasterClock * _clutter_master_clock_get_default (void); void _clutter_master_clock_add_timeline (ClutterMasterClock *master_clock, ClutterTimeline *timeline); diff --git a/clutter/clutter/clutter-muffin.h b/clutter/clutter/clutter-muffin.h deleted file mode 100644 index d5872c187..000000000 --- a/clutter/clutter/clutter-muffin.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2016 Red Hat Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - */ - -#ifndef __CLUTTER_MUFFIN_H__ -#define __CLUTTER_MUFFIN_H__ - -#define __CLUTTER_H_INSIDE__ - -#include "clutter-backend.h" -#include "clutter-macros.h" -#include "clutter-stage-view.h" -#include "cogl/clutter-stage-cogl.h" -#include "x11/clutter-stage-x11.h" - -typedef enum _SyncMethod /* In order of priority */ -{ /* SUPPORTED LATENCY SMOOTHNESS */ - SYNC_NONE = 0, /* Always High Poor */ - SYNC_FALLBACK, /* Always Medium Medium */ - SYNC_SWAP_THROTTLING, /* Usually Medium-high Medium, sometimes best */ - SYNC_PRESENTATION_TIME /* Usually Low Good, sometimes best */ - /* ^ As you can see SWAP_THROTTLING doesn't add much - value. And it does create the the very real - risk of blocking the main loop for up to 16ms - at a time. So it might be a good idea to retire - it in future and instead just make the backends - use swap interval 0 + PRESENTATION_TIME. */ -} SyncMethod; - -CLUTTER_AVAILABLE_IN_MUFFIN -SyncMethod _clutter_get_sync_method (void); - -CLUTTER_AVAILABLE_IN_MUFFIN -void _clutter_set_sync_method (SyncMethod sync_method); - -CLUTTER_AVAILABLE_IN_MUFFIN -void clutter_set_custom_backend_func (ClutterBackend *(* func) (void)); - -CLUTTER_AVAILABLE_IN_MUFFIN -gboolean _clutter_get_sync_to_vblank (void); - -CLUTTER_AVAILABLE_IN_MUFFIN -void _clutter_set_sync_to_vblank (gboolean sync_to_vblank); - -CLUTTER_AVAILABLE_IN_MUFFIN -void clutter_master_clock_set_sync_method (SyncMethod method); - -CLUTTER_AVAILABLE_IN_MUFFIN -void clutter_stage_x11_update_sync_state (ClutterStage *stage, - SyncMethod method); - -CLUTTER_AVAILABLE_IN_MUFFIN -int64_t clutter_stage_get_frame_counter (ClutterStage *stage); - -CLUTTER_AVAILABLE_IN_MUFFIN -void clutter_stage_capture_into (ClutterStage *stage, - gboolean paint, - cairo_rectangle_int_t *rect, - uint8_t *data); - -#undef __CLUTTER_H_INSIDE__ - -#endif /* __CLUTTER_MUFFIN_H__ */ diff --git a/clutter/clutter/clutter-mutter.h b/clutter/clutter/clutter-mutter.h new file mode 100644 index 000000000..d61746d5f --- /dev/null +++ b/clutter/clutter/clutter-mutter.h @@ -0,0 +1,83 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Copyright (C) 2016 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + */ + +#ifndef __CLUTTER_MUTTER_H__ +#define __CLUTTER_MUTTER_H__ + +#define __CLUTTER_H_INSIDE__ + +#include "clutter-backend.h" +#include "clutter-event-private.h" +#include "clutter-input-device-private.h" +#include "clutter-input-pointer-a11y-private.h" +#include "clutter-macros.h" +#include "clutter-paint-context-private.h" +#include "clutter-private.h" +#include "clutter-stage-private.h" +#include "clutter-stage-view.h" +#include "cogl/clutter-stage-cogl.h" +#include "clutter/x11/clutter-backend-x11.h" + +CLUTTER_EXPORT +void clutter_set_custom_backend_func (ClutterBackend *(* func) (void)); + +CLUTTER_EXPORT +int64_t clutter_stage_get_frame_counter (ClutterStage *stage); + +CLUTTER_EXPORT +void clutter_stage_capture_into (ClutterStage *stage, + gboolean paint, + cairo_rectangle_int_t *rect, + uint8_t *data); + +CLUTTER_EXPORT +void clutter_stage_paint_to_framebuffer (ClutterStage *stage, + CoglFramebuffer *framebuffer, + const cairo_rectangle_int_t *rect, + float scale, + ClutterPaintFlag paint_flags); + +CLUTTER_EXPORT +gboolean clutter_stage_paint_to_buffer (ClutterStage *stage, + const cairo_rectangle_int_t *rect, + float scale, + uint8_t *data, + int stride, + CoglPixelFormat format, + ClutterPaintFlag paint_flags, + GError **error); + +CLUTTER_EXPORT +void clutter_stage_freeze_updates (ClutterStage *stage); + +CLUTTER_EXPORT +void clutter_stage_thaw_updates (ClutterStage *stage); + +CLUTTER_EXPORT +void clutter_stage_update_resource_scales (ClutterStage *stage); + +CLUTTER_EXPORT +gboolean clutter_actor_has_damage (ClutterActor *actor); + +#undef __CLUTTER_H_INSIDE__ + +#endif /* __CLUTTER_MUTTER_H__ */ diff --git a/clutter/clutter/clutter-offscreen-effect.c b/clutter/clutter/clutter-offscreen-effect.c index 465b92b1e..ac4ea98e2 100644 --- a/clutter/clutter/clutter-offscreen-effect.c +++ b/clutter/clutter/clutter-offscreen-effect.c @@ -62,18 +62,19 @@ * case. */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include "clutter-offscreen-effect.h" +#include + #include "cogl/cogl.h" #include "clutter-actor-private.h" #include "clutter-debug.h" #include "clutter-private.h" #include "clutter-stage-private.h" +#include "clutter-paint-context-private.h" #include "clutter-paint-volume-private.h" #include "clutter-actor-box-private.h" @@ -86,7 +87,7 @@ struct _ClutterOffscreenEffectPrivate ClutterActor *actor; ClutterActor *stage; - ClutterVertex position; + graphene_point3d_t position; int fbo_offset_x; int fbo_offset_y; @@ -95,8 +96,8 @@ struct _ClutterOffscreenEffectPrivate through create_texture(). This needs to be tracked separately so that we can detect when a different size is calculated and regenerate the fbo */ - int fbo_width; - int fbo_height; + int target_width; + int target_height; gint old_opacity_override; }; @@ -117,11 +118,7 @@ clutter_offscreen_effect_set_actor (ClutterActorMeta *meta, meta_class->set_actor (meta, actor); /* clear out the previous state */ - if (priv->offscreen != NULL) - { - cogl_handle_unref (priv->offscreen); - priv->offscreen = NULL; - } + g_clear_pointer (&priv->offscreen, cogl_object_unref); /* we keep a back pointer here, to avoid going through the ActorMeta */ priv->actor = clutter_actor_meta_get_actor (meta); @@ -137,8 +134,35 @@ clutter_offscreen_effect_real_create_texture (ClutterOffscreenEffect *effect, COGL_PIXEL_FORMAT_RGBA_8888_PRE); } +static void +ensure_pipeline_filter_for_scale (ClutterOffscreenEffect *self, + float resource_scale) +{ + CoglPipelineFilter filter; + + if (!self->priv->target) + return; + + /* If no fractional scaling is set, we're always going to render the texture + at a 1:1 texel:pixel ratio so, in such case we can use 'nearest' filtering + to decrease the effects of rounding errors in the geometry calculation; + if instead we we're using a global fractional scaling we need to make sure + that we're using the default linear effect, not to create artifacts when + scaling down the texture */ + if (fmodf (resource_scale, 1.0f) == 0) + filter = COGL_PIPELINE_FILTER_NEAREST; + else + filter = COGL_PIPELINE_FILTER_LINEAR; + + cogl_pipeline_set_layer_filters (self->priv->target, 0 /* layer_index */, + filter, filter); +} + static gboolean -update_fbo (ClutterEffect *effect, int fbo_width, int fbo_height) +update_fbo (ClutterEffect *effect, + int target_width, + int target_height, + float resource_scale) { ClutterOffscreenEffect *self = CLUTTER_OFFSCREEN_EFFECT (effect); ClutterOffscreenEffectPrivate *priv = self->priv; @@ -153,10 +177,13 @@ update_fbo (ClutterEffect *effect, int fbo_width, int fbo_height) return FALSE; } - if (priv->fbo_width == fbo_width && - priv->fbo_height == fbo_height && + if (priv->target_width == target_width && + priv->target_height == target_height && priv->offscreen != NULL) + { + ensure_pipeline_filter_for_scale (self, resource_scale); return TRUE; + } if (priv->target == NULL) { @@ -164,48 +191,32 @@ update_fbo (ClutterEffect *effect, int fbo_width, int fbo_height) clutter_backend_get_cogl_context (clutter_get_default_backend ()); priv->target = cogl_pipeline_new (ctx); - - /* We're always going to render the texture at a 1:1 texel:pixel - ratio so we can use 'nearest' filtering to decrease the - effects of rounding errors in the geometry calculation */ - cogl_pipeline_set_layer_filters (priv->target, - 0, /* layer_index */ - COGL_PIPELINE_FILTER_NEAREST, - COGL_PIPELINE_FILTER_NEAREST); - } - - if (priv->texture != NULL) - { - cogl_handle_unref (priv->texture); - priv->texture = NULL; + ensure_pipeline_filter_for_scale (self, resource_scale); } - if (priv->offscreen != NULL) - { - cogl_handle_unref (priv->offscreen); - priv->offscreen = NULL; - } + g_clear_pointer (&priv->texture, cogl_object_unref); + g_clear_pointer (&priv->offscreen, cogl_object_unref); priv->texture = - clutter_offscreen_effect_create_texture (self, fbo_width, fbo_height); + clutter_offscreen_effect_create_texture (self, target_width, target_height); if (priv->texture == NULL) return FALSE; cogl_pipeline_set_layer_texture (priv->target, 0, priv->texture); - priv->fbo_width = fbo_width; - priv->fbo_height = fbo_height; + priv->target_width = target_width; + priv->target_height = target_height; priv->offscreen = cogl_offscreen_new_to_texture (priv->texture); if (priv->offscreen == NULL) { g_warning ("%s: Unable to create an Offscreen buffer", G_STRLOC); - cogl_handle_unref (priv->target); + cogl_object_unref (priv->target); priv->target = NULL; - priv->fbo_width = 0; - priv->fbo_height = 0; + priv->target_width = 0; + priv->target_height = 0; return FALSE; } @@ -214,7 +225,8 @@ update_fbo (ClutterEffect *effect, int fbo_width, int fbo_height) } static gboolean -clutter_offscreen_effect_pre_paint (ClutterEffect *effect) +clutter_offscreen_effect_pre_paint (ClutterEffect *effect, + ClutterPaintContext *paint_context) { ClutterOffscreenEffect *self = CLUTTER_OFFSCREEN_EFFECT (effect); ClutterOffscreenEffectPrivate *priv = self->priv; @@ -224,10 +236,15 @@ clutter_offscreen_effect_pre_paint (ClutterEffect *effect) const ClutterPaintVolume *volume; CoglColor transparent; gfloat stage_width, stage_height; - gfloat fbo_width = -1, fbo_height = -1; - ClutterVertex local_offset = { 0.f, 0.f, 0.f }; + gfloat target_width = -1, target_height = -1; + CoglFramebuffer *framebuffer; + gfloat resource_scale; + gfloat ceiled_resource_scale; + graphene_point3d_t local_offset; gfloat old_viewport[4]; + local_offset = GRAPHENE_POINT3D_INIT (0.0f, 0.0f, 0.0f); + if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect))) return FALSE; @@ -237,6 +254,18 @@ clutter_offscreen_effect_pre_paint (ClutterEffect *effect) stage = _clutter_actor_get_stage_internal (priv->actor); clutter_actor_get_size (stage, &stage_width, &stage_height); + if (_clutter_actor_get_real_resource_scale (priv->actor, &resource_scale)) + { + ceiled_resource_scale = ceilf (resource_scale); + stage_width *= ceiled_resource_scale; + stage_height *= ceiled_resource_scale; + } + else + { + /* We are sure we have a resource scale set to a good value at paint */ + g_assert_not_reached (); + } + /* Get the minimal bounding box for what we want to paint, relative to the * parent of priv->actor. Note that we may actually be painting a clone of * priv->actor so we need to be careful to avoid querying the transformation @@ -263,16 +292,20 @@ clutter_offscreen_effect_pre_paint (ClutterEffect *effect) priv->fbo_offset_x = box.x1 - raw_box.x1; priv->fbo_offset_y = box.y1 - raw_box.y1; - clutter_actor_box_get_size (&box, &fbo_width, &fbo_height); + clutter_actor_box_scale (&box, ceiled_resource_scale); + clutter_actor_box_get_size (&box, &target_width, &target_height); + + target_width = ceilf (target_width); + target_height = ceilf (target_height); /* First assert that the framebuffer is the right size... */ - if (!update_fbo (effect, fbo_width, fbo_height)) + if (!update_fbo (effect, target_width, target_height, resource_scale)) return FALSE; - cogl_get_modelview_matrix (&old_modelview); + framebuffer = clutter_paint_context_get_framebuffer (paint_context); + cogl_framebuffer_get_modelview_matrix (framebuffer, &old_modelview); - /* let's draw offscreen */ - cogl_push_framebuffer (priv->offscreen); + clutter_paint_context_push_framebuffer (paint_context, priv->offscreen); /* We don't want the FBO contents to be transformed. That could waste memory * (e.g. during zoom), or result in something that's not rectangular (clipped @@ -282,11 +315,7 @@ clutter_offscreen_effect_pre_paint (ClutterEffect *effect) * contents on screen... */ clutter_actor_get_transform (priv->stage, &modelview); - cogl_matrix_translate (&modelview, - -priv->fbo_offset_x, - -priv->fbo_offset_y, - 0.0f); - cogl_set_modelview_matrix (&modelview); + cogl_framebuffer_set_modelview_matrix (priv->offscreen, &modelview); /* Save the original viewport for calculating priv->position */ _clutter_stage_get_viewport (CLUTTER_STAGE (priv->stage), @@ -295,8 +324,14 @@ clutter_offscreen_effect_pre_paint (ClutterEffect *effect) &old_viewport[2], &old_viewport[3]); - /* Set up the viewport so that it has the same size as the stage. */ - cogl_set_viewport (0, 0, stage_width, stage_height); + /* Set up the viewport so that it has the same size as the stage (avoid + * distortion), but translated to account for the FBO offset... + */ + cogl_framebuffer_set_viewport (priv->offscreen, + -priv->fbo_offset_x, + -priv->fbo_offset_y, + stage_width, + stage_height); /* Copy the stage's projection matrix across to the framebuffer */ _clutter_stage_get_projection_matrix (CLUTTER_STAGE (priv->stage), @@ -313,14 +348,15 @@ clutter_offscreen_effect_pre_paint (ClutterEffect *effect) &priv->position, 1); - cogl_set_projection_matrix (&projection); + cogl_framebuffer_set_projection_matrix (priv->offscreen, &projection); cogl_color_init_from_4ub (&transparent, 0, 0, 0, 0); - cogl_clear (&transparent, - COGL_BUFFER_BIT_COLOR | - COGL_BUFFER_BIT_DEPTH); + cogl_framebuffer_clear (priv->offscreen, + COGL_BUFFER_BIT_COLOR | + COGL_BUFFER_BIT_DEPTH, + &transparent); - cogl_push_matrix (); + cogl_framebuffer_push_matrix (priv->offscreen); /* Override the actor's opacity to fully opaque - we paint the offscreen * texture with the actor's paint opacity, so we need to do this to avoid @@ -334,9 +370,12 @@ clutter_offscreen_effect_pre_paint (ClutterEffect *effect) } static void -clutter_offscreen_effect_real_paint_target (ClutterOffscreenEffect *effect) +clutter_offscreen_effect_real_paint_target (ClutterOffscreenEffect *effect, + ClutterPaintContext *paint_context) { ClutterOffscreenEffectPrivate *priv = effect->priv; + CoglFramebuffer *framebuffer = + clutter_paint_context_get_framebuffer (paint_context); guint8 paint_opacity; paint_opacity = clutter_actor_get_paint_opacity (priv->actor); @@ -346,51 +385,66 @@ clutter_offscreen_effect_real_paint_target (ClutterOffscreenEffect *effect) paint_opacity, paint_opacity, paint_opacity); - cogl_set_source (priv->target); /* At this point we are in stage coordinates translated so if * we draw our texture using a textured quad the size of the paint * box then we will overlay where the actor would have drawn if it * hadn't been redirected offscreen. */ - cogl_rectangle_with_texture_coords (0, 0, - cogl_texture_get_width (priv->texture), - cogl_texture_get_height (priv->texture), - 0.0, 0.0, - 1.0, 1.0); + cogl_framebuffer_draw_textured_rectangle (framebuffer, + priv->target, + 0, 0, + cogl_texture_get_width (priv->texture), + cogl_texture_get_height (priv->texture), + 0.0, 0.0, + 1.0, 1.0); } static void -clutter_offscreen_effect_paint_texture (ClutterOffscreenEffect *effect) +clutter_offscreen_effect_paint_texture (ClutterOffscreenEffect *effect, + ClutterPaintContext *paint_context) { ClutterOffscreenEffectPrivate *priv = effect->priv; + CoglFramebuffer *framebuffer = + clutter_paint_context_get_framebuffer (paint_context); CoglMatrix modelview; + float resource_scale; - cogl_push_matrix (); + cogl_framebuffer_push_matrix (framebuffer); /* The current modelview matrix is *almost* perfect already. It's only * missing a correction for the expanded FBO and offset rendering within... */ - cogl_get_modelview_matrix (&modelview); + cogl_framebuffer_get_modelview_matrix (framebuffer, &modelview); + + if (clutter_actor_get_resource_scale (priv->actor, &resource_scale) && + resource_scale != 1.0f) + { + float paint_scale = 1.0f / resource_scale; + cogl_matrix_scale (&modelview, paint_scale, paint_scale, 1); + } + cogl_matrix_translate (&modelview, priv->fbo_offset_x, priv->fbo_offset_y, 0.0f); - cogl_set_modelview_matrix (&modelview); + cogl_framebuffer_set_modelview_matrix (framebuffer, &modelview); /* paint the target material; this is virtualized for * sub-classes that require special hand-holding */ - clutter_offscreen_effect_paint_target (effect); + clutter_offscreen_effect_paint_target (effect, paint_context); - cogl_pop_matrix (); + cogl_framebuffer_pop_matrix (framebuffer); } static void -clutter_offscreen_effect_post_paint (ClutterEffect *effect) +clutter_offscreen_effect_post_paint (ClutterEffect *effect, + ClutterPaintContext *paint_context) { ClutterOffscreenEffect *self = CLUTTER_OFFSCREEN_EFFECT (effect); ClutterOffscreenEffectPrivate *priv = self->priv; + CoglFramebuffer *framebuffer; if (priv->offscreen == NULL || priv->target == NULL || @@ -400,34 +454,60 @@ clutter_offscreen_effect_post_paint (ClutterEffect *effect) /* Restore the previous opacity override */ clutter_actor_set_opacity_override (priv->actor, priv->old_opacity_override); - cogl_pop_matrix (); - cogl_pop_framebuffer (); + framebuffer = clutter_paint_context_get_framebuffer (paint_context); + cogl_framebuffer_pop_matrix (framebuffer); + clutter_paint_context_pop_framebuffer (paint_context); - clutter_offscreen_effect_paint_texture (self); + clutter_offscreen_effect_paint_texture (self, paint_context); } static void clutter_offscreen_effect_paint (ClutterEffect *effect, + ClutterPaintContext *paint_context, ClutterEffectPaintFlags flags) { ClutterOffscreenEffect *self = CLUTTER_OFFSCREEN_EFFECT (effect); ClutterOffscreenEffectPrivate *priv = self->priv; - CoglMatrix matrix; - cogl_get_modelview_matrix (&matrix); + if (flags & CLUTTER_EFFECT_PAINT_BYPASS_EFFECT) + { + clutter_actor_continue_paint (priv->actor, paint_context); + cogl_clear_object (&priv->offscreen); + return; + } /* If we've already got a cached image and the actor hasn't been redrawn * then we can just use the cached image in the FBO. */ if (priv->offscreen == NULL || (flags & CLUTTER_EFFECT_PAINT_ACTOR_DIRTY)) { - /* Chain up to the parent paint method which will call the pre and - post paint functions to update the image */ - CLUTTER_EFFECT_CLASS (clutter_offscreen_effect_parent_class)-> - paint (effect, flags); + ClutterEffectClass *effect_class = CLUTTER_EFFECT_GET_CLASS (effect); + gboolean pre_paint_succeeded; + + pre_paint_succeeded = effect_class->pre_paint (effect, paint_context); + + clutter_actor_continue_paint (priv->actor, paint_context); + + if (pre_paint_succeeded) + effect_class->post_paint (effect, paint_context); + else + g_clear_pointer (&priv->offscreen, cogl_object_unref); } else - clutter_offscreen_effect_paint_texture (self); + clutter_offscreen_effect_paint_texture (self, paint_context); +} + +static void +clutter_offscreen_effect_notify (GObject *gobject, + GParamSpec *pspec) +{ + ClutterOffscreenEffect *offscreen_effect = CLUTTER_OFFSCREEN_EFFECT (gobject); + ClutterOffscreenEffectPrivate *priv = offscreen_effect->priv; + + if (strcmp (pspec->name, "enabled") == 0) + g_clear_pointer (&priv->offscreen, cogl_object_unref); + + G_OBJECT_CLASS (clutter_offscreen_effect_parent_class)->notify (gobject, pspec); } static void @@ -436,14 +516,9 @@ clutter_offscreen_effect_finalize (GObject *gobject) ClutterOffscreenEffect *self = CLUTTER_OFFSCREEN_EFFECT (gobject); ClutterOffscreenEffectPrivate *priv = self->priv; - if (priv->offscreen) - cogl_handle_unref (priv->offscreen); - - if (priv->target) - cogl_handle_unref (priv->target); - - if (priv->texture) - cogl_handle_unref (priv->texture); + g_clear_pointer (&priv->offscreen, cogl_object_unref); + g_clear_pointer (&priv->texture, cogl_object_unref); + g_clear_pointer (&priv->target, cogl_object_unref); G_OBJECT_CLASS (clutter_offscreen_effect_parent_class)->finalize (gobject); } @@ -465,6 +540,7 @@ clutter_offscreen_effect_class_init (ClutterOffscreenEffectClass *klass) effect_class->paint = clutter_offscreen_effect_paint; gobject_class->finalize = clutter_offscreen_effect_finalize; + gobject_class->notify = clutter_offscreen_effect_notify; } static void @@ -487,7 +563,7 @@ clutter_offscreen_effect_init (ClutterOffscreenEffect *self) * used instead of clutter_offscreen_effect_get_target() when the * effect subclass wants to paint using its own material. * - * Return value: (transfer none): a #CoglHandle or %COGL_INVALID_HANDLE. The + * Return value: (transfer none): a #CoglHandle or %NULL. The * returned texture is owned by Clutter and it should not be * modified or freed * @@ -530,17 +606,20 @@ clutter_offscreen_effect_get_target (ClutterOffscreenEffect *effect) /** * clutter_offscreen_effect_paint_target: * @effect: a #ClutterOffscreenEffect + * @paint_context: a #ClutterPaintContext * * Calls the paint_target() virtual function of the @effect * * Since: 1.4 */ void -clutter_offscreen_effect_paint_target (ClutterOffscreenEffect *effect) +clutter_offscreen_effect_paint_target (ClutterOffscreenEffect *effect, + ClutterPaintContext *paint_context) { g_return_if_fail (CLUTTER_IS_OFFSCREEN_EFFECT (effect)); - CLUTTER_OFFSCREEN_EFFECT_GET_CLASS (effect)->paint_target (effect); + CLUTTER_OFFSCREEN_EFFECT_GET_CLASS (effect)->paint_target (effect, + paint_context); } /** @@ -552,7 +631,7 @@ clutter_offscreen_effect_paint_target (ClutterOffscreenEffect *effect) * Calls the create_texture() virtual function of the @effect * * Return value: (transfer full): a handle to a Cogl texture, or - * %COGL_INVALID_HANDLE. The returned handle has its reference + * %NULL. The returned handle has its reference * count increased. * * Since: 1.4 @@ -632,7 +711,7 @@ clutter_offscreen_effect_get_target_size (ClutterOffscreenEffect *effect, */ gboolean clutter_offscreen_effect_get_target_rect (ClutterOffscreenEffect *effect, - ClutterRect *rect) + graphene_rect_t *rect) { ClutterOffscreenEffectPrivate *priv; @@ -644,11 +723,11 @@ clutter_offscreen_effect_get_target_rect (ClutterOffscreenEffect *effect, if (priv->texture == NULL) return FALSE; - clutter_rect_init (rect, - priv->position.x, - priv->position.y, - cogl_texture_get_width (priv->texture), - cogl_texture_get_height (priv->texture)); + graphene_rect_init (rect, + priv->position.x, + priv->position.y, + cogl_texture_get_width (priv->texture), + cogl_texture_get_height (priv->texture)); return TRUE; } diff --git a/clutter/clutter/clutter-offscreen-effect.h b/clutter/clutter/clutter-offscreen-effect.h index 3c88f6788..2de98bb0a 100644 --- a/clutter/clutter/clutter-offscreen-effect.h +++ b/clutter/clutter/clutter-offscreen-effect.h @@ -79,7 +79,8 @@ struct _ClutterOffscreenEffectClass CoglHandle (* create_texture) (ClutterOffscreenEffect *effect, gfloat width, gfloat height); - void (* paint_target) (ClutterOffscreenEffect *effect); + void (* paint_target) (ClutterOffscreenEffect *effect, + ClutterPaintContext *paint_context); /*< private >*/ void (* _clutter_offscreen1) (void); @@ -91,30 +92,31 @@ struct _ClutterOffscreenEffectClass void (* _clutter_offscreen7) (void); }; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT GType clutter_offscreen_effect_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT CoglMaterial * clutter_offscreen_effect_get_target (ClutterOffscreenEffect *effect); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT CoglHandle clutter_offscreen_effect_get_texture (ClutterOffscreenEffect *effect); -CLUTTER_AVAILABLE_IN_1_4 -void clutter_offscreen_effect_paint_target (ClutterOffscreenEffect *effect); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT +void clutter_offscreen_effect_paint_target (ClutterOffscreenEffect *effect, + ClutterPaintContext *paint_context); +CLUTTER_EXPORT CoglHandle clutter_offscreen_effect_create_texture (ClutterOffscreenEffect *effect, gfloat width, gfloat height); -CLUTTER_DEPRECATED_IN_1_14_FOR (clutter_offscreen_effect_get_target_rect) +CLUTTER_DEPRECATED_FOR (clutter_offscreen_effect_get_target_rect) gboolean clutter_offscreen_effect_get_target_size (ClutterOffscreenEffect *effect, gfloat *width, gfloat *height); -CLUTTER_AVAILABLE_IN_1_14 +CLUTTER_EXPORT gboolean clutter_offscreen_effect_get_target_rect (ClutterOffscreenEffect *effect, - ClutterRect *rect); + graphene_rect_t *rect); G_END_DECLS diff --git a/clutter/clutter/clutter-page-turn-effect.c b/clutter/clutter/clutter-page-turn-effect.c index 4146b1328..2c0bc0ac6 100644 --- a/clutter/clutter/clutter-page-turn-effect.c +++ b/clutter/clutter/clutter-page-turn-effect.c @@ -35,9 +35,7 @@ * #ClutterPageTurnEffect is available since Clutter 1.4 */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include diff --git a/clutter/clutter/clutter-page-turn-effect.h b/clutter/clutter/clutter-page-turn-effect.h index b3fb80434..dd036bac8 100644 --- a/clutter/clutter/clutter-page-turn-effect.h +++ b/clutter/clutter/clutter-page-turn-effect.h @@ -51,28 +51,28 @@ G_BEGIN_DECLS typedef struct _ClutterPageTurnEffect ClutterPageTurnEffect; typedef struct _ClutterPageTurnEffectClass ClutterPageTurnEffectClass; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT GType clutter_page_turn_effect_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT ClutterEffect *clutter_page_turn_effect_new (gdouble period, gdouble angle, gfloat radius); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_page_turn_effect_set_period (ClutterPageTurnEffect *effect, gdouble period); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT gdouble clutter_page_turn_effect_get_period (ClutterPageTurnEffect *effect); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_page_turn_effect_set_angle (ClutterPageTurnEffect *effect, gdouble angle); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT gdouble clutter_page_turn_effect_get_angle (ClutterPageTurnEffect *effect); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_page_turn_effect_set_radius (ClutterPageTurnEffect *effect, gfloat radius); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT gfloat clutter_page_turn_effect_get_radius (ClutterPageTurnEffect *effect); G_END_DECLS diff --git a/clutter/clutter/clutter-paint-context-private.h b/clutter/clutter/clutter-paint-context-private.h new file mode 100644 index 000000000..598f8e1ac --- /dev/null +++ b/clutter/clutter/clutter-paint-context-private.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2019 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#ifndef CLUTTER_PAINT_CONTEXT_PRIVATE_H +#define CLUTTER_PAINT_CONTEXT_PRIVATE_H + +#include "clutter-paint-context.h" + +typedef enum _ClutterPaintFlag +{ + CLUTTER_PAINT_FLAG_NONE = 0, + CLUTTER_PAINT_FLAG_NO_CURSORS = 1 << 0, + CLUTTER_PAINT_FLAG_NO_PAINT_SIGNAL = 1 << 1, +} ClutterPaintFlag; + +ClutterPaintContext * clutter_paint_context_new_for_view (ClutterStageView *view, + const cairo_region_t *redraw_clip, + ClutterPaintFlag paint_flags); + +gboolean clutter_paint_context_is_drawing_off_stage (ClutterPaintContext *paint_context); + +CoglFramebuffer * clutter_paint_context_get_base_framebuffer (ClutterPaintContext *paint_context); + +CLUTTER_EXPORT +ClutterPaintFlag clutter_paint_context_get_paint_flags (ClutterPaintContext *paint_context); + +#endif /* CLUTTER_PAINT_CONTEXT_PRIVATE_H */ diff --git a/clutter/clutter/clutter-paint-context.c b/clutter/clutter/clutter-paint-context.c new file mode 100644 index 000000000..6787a5b5c --- /dev/null +++ b/clutter/clutter/clutter-paint-context.c @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2019 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#include "clutter-build-config.h" + +#include "clutter-paint-context-private.h" + +struct _ClutterPaintContext +{ + grefcount ref_count; + + ClutterPaintFlag paint_flags; + + GList *framebuffers; + + ClutterStageView *view; + + cairo_region_t *redraw_clip; +}; + +G_DEFINE_BOXED_TYPE (ClutterPaintContext, clutter_paint_context, + clutter_paint_context_ref, + clutter_paint_context_unref) + +ClutterPaintContext * +clutter_paint_context_new_for_view (ClutterStageView *view, + const cairo_region_t *redraw_clip, + ClutterPaintFlag paint_flags) +{ + ClutterPaintContext *paint_context; + CoglFramebuffer *framebuffer; + + paint_context = g_new0 (ClutterPaintContext, 1); + g_ref_count_init (&paint_context->ref_count); + paint_context->view = view; + paint_context->redraw_clip = cairo_region_copy (redraw_clip); + paint_context->paint_flags = paint_flags; + + framebuffer = clutter_stage_view_get_framebuffer (view); + clutter_paint_context_push_framebuffer (paint_context, framebuffer); + + return paint_context; +} + +/** + * clutter_paint_context_new_for_framebuffer: (skip) + */ +ClutterPaintContext * +clutter_paint_context_new_for_framebuffer (CoglFramebuffer *framebuffer) +{ + ClutterPaintContext *paint_context; + + paint_context = g_new0 (ClutterPaintContext, 1); + g_ref_count_init (&paint_context->ref_count); + paint_context->paint_flags = (CLUTTER_PAINT_FLAG_NO_CURSORS | + CLUTTER_PAINT_FLAG_NO_PAINT_SIGNAL); + + clutter_paint_context_push_framebuffer (paint_context, framebuffer); + + return paint_context; +} + +ClutterPaintContext * +clutter_paint_context_ref (ClutterPaintContext *paint_context) +{ + g_ref_count_inc (&paint_context->ref_count); + return paint_context; +} + +static void +clutter_paint_context_dispose (ClutterPaintContext *paint_context) +{ + g_list_free_full (paint_context->framebuffers, + cogl_object_unref); + paint_context->framebuffers = NULL; + g_clear_pointer (&paint_context->redraw_clip, cairo_region_destroy); +} + +void +clutter_paint_context_unref (ClutterPaintContext *paint_context) +{ + if (g_ref_count_dec (&paint_context->ref_count)) + { + clutter_paint_context_dispose (paint_context); + g_free (paint_context); + } +} + +void +clutter_paint_context_destroy (ClutterPaintContext *paint_context) +{ + clutter_paint_context_dispose (paint_context); + clutter_paint_context_unref (paint_context); +} + +void +clutter_paint_context_push_framebuffer (ClutterPaintContext *paint_context, + CoglFramebuffer *framebuffer) +{ + paint_context->framebuffers = g_list_prepend (paint_context->framebuffers, + cogl_object_ref (framebuffer)); +} + +void +clutter_paint_context_pop_framebuffer (ClutterPaintContext *paint_context) +{ + g_return_if_fail (paint_context->framebuffers); + + cogl_object_unref (paint_context->framebuffers->data); + paint_context->framebuffers = + g_list_delete_link (paint_context->framebuffers, + paint_context->framebuffers); +} + +const cairo_region_t * +clutter_paint_context_get_redraw_clip (ClutterPaintContext *paint_context) +{ + return paint_context->redraw_clip; +} + +/** + * clutter_paint_context_get_framebuffer: + * @paint_context: The #ClutterPaintContext + * + * Returns: (transfer none): The #CoglFramebuffer used for drawing + */ +CoglFramebuffer * +clutter_paint_context_get_framebuffer (ClutterPaintContext *paint_context) +{ + g_return_val_if_fail (paint_context->framebuffers, NULL); + + return paint_context->framebuffers->data; +} + +CoglFramebuffer * +clutter_paint_context_get_base_framebuffer (ClutterPaintContext *paint_context) +{ + return g_list_last (paint_context->framebuffers)->data; +} + +/** + * clutter_paint_context_get_stage_view: (skip) + */ +ClutterStageView * +clutter_paint_context_get_stage_view (ClutterPaintContext *paint_context) +{ + return paint_context->view; +} + +/** + * clutter_paint_context_is_drawing_off_stage: (skip) + * + * Return %TRUE if the paint context is currently drawing off stage. + * This happens if there are any framebuffers pushed, and the base framebuffer + * comes from the stage view. + */ +gboolean +clutter_paint_context_is_drawing_off_stage (ClutterPaintContext *paint_context) +{ + if (g_list_length (paint_context->framebuffers) > 1) + return TRUE; + + return !paint_context->view; +} + +/** + * clutter_paint_context_get_paint_flags: (skip) + */ +ClutterPaintFlag +clutter_paint_context_get_paint_flags (ClutterPaintContext *paint_context) +{ + return paint_context->paint_flags; +} diff --git a/clutter/clutter/clutter-paint-context.h b/clutter/clutter/clutter-paint-context.h new file mode 100644 index 000000000..c54f95c03 --- /dev/null +++ b/clutter/clutter/clutter-paint-context.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2019 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#ifndef CLUTTER_PAINT_CONTEXT_H +#define CLUTTER_PAINT_CONTEXT_H + +#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +#include "clutter-macros.h" +#include "clutter-stage-view.h" + +typedef struct _ClutterPaintContext ClutterPaintContext; + +#define CLUTTER_TYPE_PAINT_CONTEXT (clutter_paint_context_get_type ()) + +CLUTTER_EXPORT +GType clutter_paint_context_get_type (void); + +CLUTTER_EXPORT +ClutterPaintContext * clutter_paint_context_new_for_framebuffer (CoglFramebuffer *framebuffer); + +CLUTTER_EXPORT +ClutterPaintContext * clutter_paint_context_ref (ClutterPaintContext *paint_context); + +CLUTTER_EXPORT +void clutter_paint_context_unref (ClutterPaintContext *paint_context); + +CLUTTER_EXPORT +void clutter_paint_context_destroy (ClutterPaintContext *paint_context); + +CLUTTER_EXPORT +CoglFramebuffer * clutter_paint_context_get_framebuffer (ClutterPaintContext *paint_context); + +CLUTTER_EXPORT +ClutterStageView * clutter_paint_context_get_stage_view (ClutterPaintContext *paint_context); + +CLUTTER_EXPORT +void clutter_paint_context_push_framebuffer (ClutterPaintContext *paint_context, + CoglFramebuffer *framebuffer); + +CLUTTER_EXPORT +void clutter_paint_context_pop_framebuffer (ClutterPaintContext *paint_context); + +CLUTTER_EXPORT +const cairo_region_t * clutter_paint_context_get_redraw_clip (ClutterPaintContext *paint_context); + +#endif /* CLUTTER_PAINT_CONTEXT_H */ diff --git a/clutter/clutter/clutter-paint-node-private.h b/clutter/clutter/clutter-paint-node-private.h index 2945b78a4..f912a6a10 100644 --- a/clutter/clutter/clutter-paint-node-private.h +++ b/clutter/clutter/clutter-paint-node-private.h @@ -27,6 +27,7 @@ #include #include +#include #include G_BEGIN_DECLS @@ -48,11 +49,11 @@ struct _ClutterPaintNode ClutterPaintNode *next_sibling; ClutterPaintNode *last_child; - guint n_children; - GArray *operations; - gchar *name; + const gchar *name; + + guint n_children; volatile int ref_count; }; @@ -63,9 +64,12 @@ struct _ClutterPaintNodeClass void (* finalize) (ClutterPaintNode *node); - gboolean (* pre_draw) (ClutterPaintNode *node); - void (* draw) (ClutterPaintNode *node); - void (* post_draw) (ClutterPaintNode *node); + gboolean (* pre_draw) (ClutterPaintNode *node, + ClutterPaintContext *paint_context); + void (* draw) (ClutterPaintNode *node, + ClutterPaintContext *paint_context); + void (* post_draw) (ClutterPaintNode *node, + ClutterPaintContext *paint_context); JsonNode*(* serialize) (ClutterPaintNode *node); @@ -74,9 +78,11 @@ struct _ClutterPaintNodeClass #define PAINT_OP_INIT { PAINT_OP_INVALID } -typedef enum { +typedef enum +{ PAINT_OP_INVALID = 0, PAINT_OP_TEX_RECT, + PAINT_OP_MULTITEX_RECT, PAINT_OP_PATH, PAINT_OP_PRIMITIVE } PaintOpCode; @@ -85,6 +91,8 @@ struct _ClutterPaintOperation { PaintOpCode opcode; + GArray *multitex_coords; + union { float texrect[8]; @@ -94,7 +102,6 @@ struct _ClutterPaintOperation } op; }; -GType _clutter_root_node_get_type (void) G_GNUC_CONST; GType _clutter_transform_node_get_type (void) G_GNUC_CONST; GType _clutter_dummy_node_get_type (void) G_GNUC_CONST; @@ -107,13 +114,10 @@ void _clutter_paint_operation_paint_primitive (const C void _clutter_paint_node_init_types (void); gpointer _clutter_paint_node_create (GType gtype); -ClutterPaintNode * _clutter_root_node_new (CoglFramebuffer *framebuffer, - const ClutterColor *clear_color, - CoglBufferBit clear_flags); ClutterPaintNode * _clutter_transform_node_new (const CoglMatrix *matrix); -ClutterPaintNode * _clutter_dummy_node_new (ClutterActor *actor); +ClutterPaintNode * _clutter_dummy_node_new (ClutterActor *actor, + CoglFramebuffer *framebuffer); -void _clutter_paint_node_paint (ClutterPaintNode *root); void _clutter_paint_node_dump_tree (ClutterPaintNode *root); G_GNUC_INTERNAL @@ -139,32 +143,6 @@ G_GNUC_INTERNAL ClutterPaintNode * clutter_paint_node_get_last_child (ClutterPaintNode *node); G_GNUC_INTERNAL ClutterPaintNode * clutter_paint_node_get_parent (ClutterPaintNode *node); -G_GNUC_INTERNAL -CoglFramebuffer * clutter_paint_node_get_framebuffer (ClutterPaintNode *node); - -#define CLUTTER_TYPE_LAYER_NODE (_clutter_layer_node_get_type ()) -#define CLUTTER_LAYER_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_LAYER_NODE, ClutterLayerNode)) -#define CLUTTER_IS_LAYER_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_LAYER_NODE)) - -/* - * ClutterLayerNode: - * - * The #ClutterLayerNode structure is an opaque - * type whose members cannot be directly accessed. - * - * Since: 1.10 - */ -typedef struct _ClutterLayerNode ClutterLayerNode; -typedef struct _ClutterLayerNodeClass ClutterLayerNodeClass; - -GType _clutter_layer_node_get_type (void) G_GNUC_CONST; - -ClutterPaintNode * _clutter_layer_node_new (const CoglMatrix *projection, - const cairo_rectangle_t *viewport, - float width, - float height, - guint8 opacity); - G_END_DECLS diff --git a/clutter/clutter/clutter-paint-node.c b/clutter/clutter/clutter-paint-node.c index 3f1484a6d..138a64652 100644 --- a/clutter/clutter/clutter-paint-node.c +++ b/clutter/clutter/clutter-paint-node.c @@ -58,9 +58,7 @@ * Since: 1.10 */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #define CLUTTER_ENABLE_EXPERIMENTAL_API @@ -173,8 +171,6 @@ clutter_paint_node_real_finalize (ClutterPaintNode *node) { ClutterPaintNode *iter; - free (node->name); - if (node->operations != NULL) { guint i; @@ -204,18 +200,21 @@ clutter_paint_node_real_finalize (ClutterPaintNode *node) } static gboolean -clutter_paint_node_real_pre_draw (ClutterPaintNode *node) +clutter_paint_node_real_pre_draw (ClutterPaintNode *node, + ClutterPaintContext *paint_context) { return FALSE; } static void -clutter_paint_node_real_draw (ClutterPaintNode *node) +clutter_paint_node_real_draw (ClutterPaintNode *node, + ClutterPaintContext *paint_context) { } static void -clutter_paint_node_real_post_draw (ClutterPaintNode *node) +clutter_paint_node_real_post_draw (ClutterPaintNode *node, + ClutterPaintContext *paint_context) { } @@ -296,7 +295,8 @@ clutter_paint_node_get_type (void) * * The @name will be used for debugging purposes. * - * The @node will copy the passed string. + * The @node will intern @name using g_intern_string(). If you have access to a + * static string, use clutter_paint_node_set_static_name() instead. * * Since: 1.10 */ @@ -306,8 +306,22 @@ clutter_paint_node_set_name (ClutterPaintNode *node, { g_return_if_fail (CLUTTER_IS_PAINT_NODE (node)); - free (node->name); - node->name = g_strdup (name); + node->name = g_intern_string (name); +} + +/** + * clutter_paint_node_set_static_name: (skip) + * + * Like clutter_paint_node_set_name() but uses a static or interned string + * containing the name. + */ +void +clutter_paint_node_set_static_name (ClutterPaintNode *node, + const char *name) +{ + g_return_if_fail (CLUTTER_IS_PAINT_NODE (node)); + + node->name = name; } /** @@ -763,6 +777,11 @@ clutter_paint_operation_clear (ClutterPaintOperation *op) case PAINT_OP_TEX_RECT: break; + case PAINT_OP_MULTITEX_RECT: + if (op->multitex_coords != NULL) + g_array_unref (op->multitex_coords); + break; + case PAINT_OP_PATH: if (op->op.path != NULL) cogl_object_unref (op->op.path); @@ -796,6 +815,27 @@ clutter_paint_op_init_tex_rect (ClutterPaintOperation *op, op->op.texrect[7] = y_2; } +static inline void +clutter_paint_op_init_multitex_rect (ClutterPaintOperation *op, + const ClutterActorBox *rect, + const float *tex_coords, + unsigned int tex_coords_len) +{ + clutter_paint_operation_clear (op); + + op->opcode = PAINT_OP_MULTITEX_RECT; + op->multitex_coords = g_array_sized_new (FALSE, FALSE, + sizeof (float), + tex_coords_len); + + g_array_append_vals (op->multitex_coords, tex_coords, tex_coords_len); + + op->op.texrect[0] = rect->x1; + op->op.texrect[1] = rect->y1; + op->op.texrect[2] = rect->x2; + op->op.texrect[3] = rect->y2; +} + static inline void clutter_paint_op_init_path (ClutterPaintOperation *op, CoglPath *path) @@ -883,6 +923,33 @@ clutter_paint_node_add_texture_rectangle (ClutterPaintNode *node, g_array_append_val (node->operations, operation); } + +/** + * clutter_paint_node_add_multitexture_rectangle: + * @node: a #ClutterPaintNode + * @rect: a #ClutterActorBox + * @text_coords: array of multitexture values + * @text_coords_len: number of items of @text_coords + * + * Adds a rectangle region to the @node, with multitexture coordinates. + */ +void +clutter_paint_node_add_multitexture_rectangle (ClutterPaintNode *node, + const ClutterActorBox *rect, + const float *text_coords, + unsigned int text_coords_len) +{ + ClutterPaintOperation operation = PAINT_OP_INIT; + + g_return_if_fail (CLUTTER_IS_PAINT_NODE (node)); + g_return_if_fail (rect != NULL); + + clutter_paint_node_maybe_init_operations (node); + + clutter_paint_op_init_multitex_rect (&operation, rect, text_coords, text_coords_len); + g_array_append_val (node->operations, operation); +} + /** * clutter_paint_node_add_path: (skip) * @node: a #ClutterPaintNode @@ -938,37 +1005,38 @@ clutter_paint_node_add_primitive (ClutterPaintNode *node, g_array_append_val (node->operations, operation); } -/*< private > - * _clutter_paint_node_paint: +/** + * clutter_paint_node_paint: * @node: a #ClutterPaintNode * * Paints the @node using the class implementation, traversing * its children, if any. */ void -_clutter_paint_node_paint (ClutterPaintNode *node) +clutter_paint_node_paint (ClutterPaintNode *node, + ClutterPaintContext *paint_context) { ClutterPaintNodeClass *klass = CLUTTER_PAINT_NODE_GET_CLASS (node); ClutterPaintNode *iter; gboolean res; - res = klass->pre_draw (node); + res = klass->pre_draw (node, paint_context); if (res) { - klass->draw (node); + klass->draw (node, paint_context); } for (iter = node->first_child; iter != NULL; iter = iter->next_sibling) { - _clutter_paint_node_paint (iter); + clutter_paint_node_paint (iter, paint_context); } if (res) { - klass->post_draw (node); + klass->post_draw (node, paint_context); } } @@ -1008,7 +1076,7 @@ clutter_paint_node_to_json (ClutterPaintNode *node) if (node->operations != NULL) { - guint i; + guint i, j; for (i = 0; i < node->operations->len; i++) { @@ -1033,14 +1101,27 @@ clutter_paint_node_to_json (ClutterPaintNode *node) json_builder_end_array (builder); break; + case PAINT_OP_MULTITEX_RECT: + json_builder_set_member_name (builder, "texrect"); + json_builder_begin_array (builder); + + for (j = 0; i < op->multitex_coords->len; j++) + { + float coord = g_array_index (op->multitex_coords, float, j); + json_builder_add_double_value (builder, coord); + } + + json_builder_end_array (builder); + break; + case PAINT_OP_PATH: json_builder_set_member_name (builder, "path"); - json_builder_add_int_value (builder, (gint64) op->op.path); + json_builder_add_int_value (builder, (intptr_t) op->op.path); break; case PAINT_OP_PRIMITIVE: json_builder_set_member_name (builder, "primitive"); - json_builder_add_int_value (builder, (gint64) op->op.primitive); + json_builder_add_int_value (builder, (intptr_t) op->op.primitive); break; case PAINT_OP_INVALID: @@ -1095,7 +1176,7 @@ _clutter_paint_node_dump_tree (ClutterPaintNode *node) g_print ("Render tree starting from %p:\n%s\n", node, str); - free (str); + g_free (str); #endif /* CLUTTER_ENABLE_DEBUG */ } @@ -1113,8 +1194,6 @@ _clutter_paint_node_create (GType gtype) { g_return_val_if_fail (g_type_is_a (gtype, CLUTTER_TYPE_PAINT_NODE), NULL); - _clutter_paint_node_init_types (); - return (gpointer) g_type_create_instance (gtype); } @@ -1130,18 +1209,25 @@ clutter_paint_node_get_root (ClutterPaintNode *node) return iter; } +/** + * clutter_paint_node_get_framebuffer: + * @node: a #ClutterPaintNode + * + * Retrieves the #CoglFramebuffer that @node will draw + * into, if it the root node has a custom framebuffer set. + * + * Returns: (transfer none): a #CoglFramebuffer or %NULL if no custom one is + * set. + */ CoglFramebuffer * clutter_paint_node_get_framebuffer (ClutterPaintNode *node) { ClutterPaintNode *root = clutter_paint_node_get_root (node); ClutterPaintNodeClass *klass; - if (root == NULL) - return NULL; - klass = CLUTTER_PAINT_NODE_GET_CLASS (root); if (klass->get_framebuffer != NULL) return klass->get_framebuffer (root); - - return cogl_get_draw_framebuffer (); + else + return NULL; } diff --git a/clutter/clutter/clutter-paint-node.h b/clutter/clutter/clutter-paint-node.h index 5f3e962e4..9623d8bca 100644 --- a/clutter/clutter/clutter-paint-node.h +++ b/clutter/clutter/clutter-paint-node.h @@ -41,25 +41,35 @@ G_BEGIN_DECLS typedef struct _ClutterPaintNodePrivate ClutterPaintNodePrivate; typedef struct _ClutterPaintNodeClass ClutterPaintNodeClass; -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT GType clutter_paint_node_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT ClutterPaintNode * clutter_paint_node_ref (ClutterPaintNode *node); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_paint_node_unref (ClutterPaintNode *node); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT +void clutter_paint_node_paint (ClutterPaintNode *node, + ClutterPaintContext *paint_context); + +CLUTTER_EXPORT void clutter_paint_node_set_name (ClutterPaintNode *node, const char *name); +CLUTTER_EXPORT +void clutter_paint_node_set_static_name (ClutterPaintNode *node, + const char *name); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT +CoglFramebuffer * clutter_paint_node_get_framebuffer (ClutterPaintNode *node); + +CLUTTER_EXPORT void clutter_paint_node_add_child (ClutterPaintNode *node, ClutterPaintNode *child); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_paint_node_add_rectangle (ClutterPaintNode *node, const ClutterActorBox *rect); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_paint_node_add_texture_rectangle (ClutterPaintNode *node, const ClutterActorBox *rect, float x_1, @@ -67,10 +77,16 @@ void clutter_paint_node_add_texture_rectangle (Clutter float x_2, float y_2); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT +void clutter_paint_node_add_multitexture_rectangle (ClutterPaintNode *node, + const ClutterActorBox *rect, + const float *text_coords, + unsigned int text_coords_len); + +CLUTTER_EXPORT void clutter_paint_node_add_path (ClutterPaintNode *node, CoglPath *path); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_paint_node_add_primitive (ClutterPaintNode *node, CoglPrimitive *primitive); @@ -85,15 +101,15 @@ void clutter_paint_node_add_primitive (Clutter */ #define CLUTTER_VALUE_HOLDS_PAINT_NODE(value) (G_VALUE_HOLDS (value, CLUTTER_TYPE_PAINT_NODE)) -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_value_set_paint_node (GValue *value, gpointer node); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_value_take_paint_node (GValue *value, gpointer node); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT gpointer clutter_value_get_paint_node (const GValue *value); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT gpointer clutter_value_dup_paint_node (const GValue *value); G_END_DECLS diff --git a/clutter/clutter/clutter-paint-nodes.c b/clutter/clutter/clutter-paint-nodes.c index 614e00ab1..5cc8fb3ae 100644 --- a/clutter/clutter/clutter-paint-nodes.c +++ b/clutter/clutter/clutter-paint-nodes.c @@ -31,9 +31,7 @@ * that cover all the state changes available. */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #define CLUTTER_ENABLE_EXPERIMENTAL_API @@ -46,6 +44,7 @@ #include "clutter-color.h" #include "clutter-debug.h" #include "clutter-private.h" +#include "clutter-paint-context-private.h" #include "clutter-paint-nodes.h" @@ -77,24 +76,20 @@ _clutter_paint_node_init_types (void) cogl_pipeline_set_color (default_color_pipeline, &cogl_color); default_texture_pipeline = cogl_pipeline_new (ctx); - cogl_pipeline_set_layer_null_texture (default_texture_pipeline, 0, - COGL_TEXTURE_TYPE_2D); + cogl_pipeline_set_layer_null_texture (default_texture_pipeline, 0); cogl_pipeline_set_color (default_texture_pipeline, &cogl_color); cogl_pipeline_set_layer_wrap_mode (default_texture_pipeline, 0, COGL_PIPELINE_WRAP_MODE_AUTOMATIC); } /* - * Root node, private + * Root node * * any frame can only have a since RootNode instance for each * top-level actor. */ -#define clutter_root_node_get_type _clutter_root_node_get_type - -typedef struct _ClutterRootNode ClutterRootNode; -typedef struct _ClutterPaintNodeClass ClutterRootNodeClass; +#define clutter_root_node_get_type clutter_root_node_get_type struct _ClutterRootNode { @@ -109,10 +104,13 @@ struct _ClutterRootNode G_DEFINE_TYPE (ClutterRootNode, clutter_root_node, CLUTTER_TYPE_PAINT_NODE) static gboolean -clutter_root_node_pre_draw (ClutterPaintNode *node) +clutter_root_node_pre_draw (ClutterPaintNode *node, + ClutterPaintContext *paint_context) { ClutterRootNode *rnode = (ClutterRootNode *) node; + clutter_paint_context_push_framebuffer (paint_context, rnode->framebuffer); + cogl_framebuffer_clear (rnode->framebuffer, rnode->clear_flags, &rnode->clear_color); @@ -121,8 +119,10 @@ clutter_root_node_pre_draw (ClutterPaintNode *node) } static void -clutter_root_node_post_draw (ClutterPaintNode *node) +clutter_root_node_post_draw (ClutterPaintNode *node, + ClutterPaintContext *paint_context) { + clutter_paint_context_pop_framebuffer (paint_context); } static void @@ -160,13 +160,15 @@ clutter_root_node_init (ClutterRootNode *self) } ClutterPaintNode * -_clutter_root_node_new (CoglFramebuffer *framebuffer, - const ClutterColor *clear_color, - CoglBufferBit clear_flags) +clutter_root_node_new (CoglFramebuffer *framebuffer, + const ClutterColor *clear_color, + CoglBufferBit clear_flags) { ClutterRootNode *res; - res = _clutter_paint_node_create (_clutter_root_node_get_type ()); + g_return_val_if_fail (framebuffer, NULL); + + res = _clutter_paint_node_create (CLUTTER_TYPE_ROOT_NODE); cogl_color_init_from_4ub (&res->clear_color, clear_color->red, @@ -175,54 +177,52 @@ _clutter_root_node_new (CoglFramebuffer *framebuffer, clear_color->alpha); cogl_color_premultiply (&res->clear_color); - if (G_LIKELY (framebuffer != NULL)) - res->framebuffer = cogl_object_ref (framebuffer); - else - res->framebuffer = cogl_object_ref (cogl_get_draw_framebuffer ()); - + res->framebuffer = cogl_object_ref (framebuffer); res->clear_flags = clear_flags; return (ClutterPaintNode *) res; } /* - * Transform node - * - * A private PaintNode, that changes the modelview of its child - * nodes. + * ClutterTransformNode */ -#define clutter_transform_node_get_type _clutter_transform_node_get_type - -typedef struct _ClutterTransformNode { +struct _ClutterTransformNode +{ ClutterPaintNode parent_instance; - CoglMatrix modelview; -} ClutterTransformNode; + CoglMatrix transform; +}; -typedef struct _ClutterPaintNodeClass ClutterTransformNodeClass; +struct _ClutterTransformNodeClass +{ + ClutterPaintNodeClass parent_class; +}; G_DEFINE_TYPE (ClutterTransformNode, clutter_transform_node, CLUTTER_TYPE_PAINT_NODE) static gboolean -clutter_transform_node_pre_draw (ClutterPaintNode *node) +clutter_transform_node_pre_draw (ClutterPaintNode *node, + ClutterPaintContext *paint_context) { - ClutterTransformNode *tnode = (ClutterTransformNode *) node; - CoglMatrix matrix; - - cogl_push_matrix (); + ClutterTransformNode *transform_node = (ClutterTransformNode *) node; + CoglFramebuffer *fb = + clutter_paint_context_get_framebuffer (paint_context); - cogl_get_modelview_matrix (&matrix); - cogl_matrix_multiply (&matrix, &matrix, &tnode->modelview); - cogl_set_modelview_matrix (&matrix); + cogl_framebuffer_push_matrix (fb); + cogl_framebuffer_transform (fb, &transform_node->transform); return TRUE; } static void -clutter_transform_node_post_draw (ClutterPaintNode *node) +clutter_transform_node_post_draw (ClutterPaintNode *node, + ClutterPaintContext *paint_context) { - cogl_pop_matrix (); + CoglFramebuffer *fb = + clutter_paint_context_get_framebuffer (paint_context); + + cogl_framebuffer_pop_matrix (fb); } static void @@ -238,18 +238,24 @@ clutter_transform_node_class_init (ClutterTransformNodeClass *klass) static void clutter_transform_node_init (ClutterTransformNode *self) { - cogl_matrix_init_identity (&self->modelview); + cogl_matrix_init_identity (&self->transform); } +/* + * clutter_transform_node_new: + * @transform: (nullable): the transform matrix to apply + * + * Return value: (transfer full): the newly created #ClutterTransformNode. + * Use clutter_paint_node_unref() when done. + */ ClutterPaintNode * -_clutter_transform_node_new (const CoglMatrix *modelview) +clutter_transform_node_new (const CoglMatrix *transform) { ClutterTransformNode *res; - res = _clutter_paint_node_create (_clutter_transform_node_get_type ()); - - if (modelview != NULL) - res->modelview = *modelview; + res = _clutter_paint_node_create (CLUTTER_TYPE_TRANSFORM_NODE); + if (transform) + res->transform = *transform; return (ClutterPaintNode *) res; } @@ -277,7 +283,8 @@ struct _ClutterDummyNode G_DEFINE_TYPE (ClutterDummyNode, clutter_dummy_node, CLUTTER_TYPE_PAINT_NODE) static gboolean -clutter_dummy_node_pre_draw (ClutterPaintNode *node) +clutter_dummy_node_pre_draw (ClutterPaintNode *node, + ClutterPaintContext *paint_context) { return TRUE; } @@ -314,6 +321,16 @@ clutter_dummy_node_get_framebuffer (ClutterPaintNode *node) return dnode->framebuffer; } +static void +clutter_dummy_node_finalize (ClutterPaintNode *node) +{ + ClutterDummyNode *dnode = (ClutterDummyNode *) node; + + cogl_clear_object (&dnode->framebuffer); + + CLUTTER_PAINT_NODE_CLASS (clutter_dummy_node_parent_class)->finalize (node); +} + static void clutter_dummy_node_class_init (ClutterDummyNodeClass *klass) { @@ -322,6 +339,7 @@ clutter_dummy_node_class_init (ClutterDummyNodeClass *klass) node_class->pre_draw = clutter_dummy_node_pre_draw; node_class->serialize = clutter_dummy_node_serialize; node_class->get_framebuffer = clutter_dummy_node_get_framebuffer; + node_class->finalize = clutter_dummy_node_finalize; } static void @@ -330,7 +348,8 @@ clutter_dummy_node_init (ClutterDummyNode *self) } ClutterPaintNode * -_clutter_dummy_node_new (ClutterActor *actor) +_clutter_dummy_node_new (ClutterActor *actor, + CoglFramebuffer *framebuffer) { ClutterPaintNode *res; ClutterDummyNode *dnode; @@ -339,7 +358,7 @@ _clutter_dummy_node_new (ClutterActor *actor) dnode = (ClutterDummyNode *) res; dnode->actor = actor; - dnode->framebuffer = _clutter_actor_get_active_framebuffer (actor); + dnode->framebuffer = cogl_object_ref (framebuffer); return res; } @@ -382,22 +401,34 @@ clutter_pipeline_node_finalize (ClutterPaintNode *node) } static gboolean -clutter_pipeline_node_pre_draw (ClutterPaintNode *node) +clutter_pipeline_node_pre_draw (ClutterPaintNode *node, + ClutterPaintContext *paint_context) { ClutterPipelineNode *pnode = CLUTTER_PIPELINE_NODE (node); if (node->operations != NULL && pnode->pipeline != NULL) - { - cogl_push_source (pnode->pipeline); - return TRUE; - } + return TRUE; return FALSE; } +static CoglFramebuffer * +get_target_framebuffer (ClutterPaintNode *node, + ClutterPaintContext *paint_context) +{ + CoglFramebuffer *framebuffer; + + framebuffer = clutter_paint_node_get_framebuffer (node); + if (framebuffer) + return framebuffer; + + return clutter_paint_context_get_framebuffer (paint_context); +} + static void -clutter_pipeline_node_draw (ClutterPaintNode *node) +clutter_pipeline_node_draw (ClutterPaintNode *node, + ClutterPaintContext *paint_context) { ClutterPipelineNode *pnode = CLUTTER_PIPELINE_NODE (node); CoglFramebuffer *fb; @@ -409,7 +440,7 @@ clutter_pipeline_node_draw (ClutterPaintNode *node) if (node->operations == NULL) return; - fb = clutter_paint_node_get_framebuffer (node); + fb = clutter_paint_context_get_framebuffer (paint_context); for (i = 0; i < node->operations->len; i++) { @@ -423,18 +454,31 @@ clutter_pipeline_node_draw (ClutterPaintNode *node) break; case PAINT_OP_TEX_RECT: - cogl_rectangle_with_texture_coords (op->op.texrect[0], - op->op.texrect[1], - op->op.texrect[2], - op->op.texrect[3], - op->op.texrect[4], - op->op.texrect[5], - op->op.texrect[6], - op->op.texrect[7]); + cogl_framebuffer_draw_textured_rectangle (fb, + pnode->pipeline, + op->op.texrect[0], + op->op.texrect[1], + op->op.texrect[2], + op->op.texrect[3], + op->op.texrect[4], + op->op.texrect[5], + op->op.texrect[6], + op->op.texrect[7]); + break; + + case PAINT_OP_MULTITEX_RECT: + cogl_framebuffer_draw_multitextured_rectangle (fb, + pnode->pipeline, + op->op.texrect[0], + op->op.texrect[1], + op->op.texrect[2], + op->op.texrect[3], + (float*) op->multitex_coords->data, + op->multitex_coords->len); break; case PAINT_OP_PATH: - cogl_path_fill (op->op.path); + cogl_framebuffer_fill_path (fb, pnode->pipeline, op->op.path); break; case PAINT_OP_PRIMITIVE: @@ -447,9 +491,9 @@ clutter_pipeline_node_draw (ClutterPaintNode *node) } static void -clutter_pipeline_node_post_draw (ClutterPaintNode *node) +clutter_pipeline_node_post_draw (ClutterPaintNode *node, + ClutterPaintContext *paint_context) { - cogl_pop_source (); } static JsonNode * @@ -768,7 +812,8 @@ clutter_text_node_finalize (ClutterPaintNode *node) } static gboolean -clutter_text_node_pre_draw (ClutterPaintNode *node) +clutter_text_node_pre_draw (ClutterPaintNode *node, + ClutterPaintContext *paint_context) { ClutterTextNode *tnode = CLUTTER_TEXT_NODE (node); @@ -776,7 +821,8 @@ clutter_text_node_pre_draw (ClutterPaintNode *node) } static void -clutter_text_node_draw (ClutterPaintNode *node) +clutter_text_node_draw (ClutterPaintNode *node, + ClutterPaintContext *paint_context) { ClutterTextNode *tnode = CLUTTER_TEXT_NODE (node); PangoRectangle extents; @@ -786,7 +832,7 @@ clutter_text_node_draw (ClutterPaintNode *node) if (node->operations == NULL) return; - fb = clutter_paint_node_get_framebuffer (node); + fb = get_target_framebuffer (node, paint_context); pango_layout_get_pixel_extents (tnode->layout, NULL, &extents); @@ -819,16 +865,17 @@ clutter_text_node_draw (ClutterPaintNode *node) clipped = TRUE; } - cogl_pango_render_layout (tnode->layout, - op->op.texrect[0], - op->op.texrect[1], - &tnode->color, - 0); + cogl_pango_show_layout (fb, + tnode->layout, + op->op.texrect[0], + op->op.texrect[1], + &tnode->color); if (clipped) cogl_framebuffer_pop_clip (fb); break; + case PAINT_OP_MULTITEX_RECT: case PAINT_OP_PATH: case PAINT_OP_PRIMITIVE: case PAINT_OP_INVALID: @@ -857,7 +904,7 @@ clutter_text_node_serialize (ClutterPaintNode *node) str = g_strndup (text, 12); json_builder_add_string_value (builder, str); - free (str); + g_free (str); } else json_builder_add_string_value (builder, pango_layout_get_text (tnode->layout)); @@ -961,7 +1008,8 @@ struct _ClutterClipNodeClass G_DEFINE_TYPE (ClutterClipNode, clutter_clip_node, CLUTTER_TYPE_PAINT_NODE) static gboolean -clutter_clip_node_pre_draw (ClutterPaintNode *node) +clutter_clip_node_pre_draw (ClutterPaintNode *node, + ClutterPaintContext *paint_context) { gboolean retval = FALSE; CoglFramebuffer *fb; @@ -970,7 +1018,7 @@ clutter_clip_node_pre_draw (ClutterPaintNode *node) if (node->operations == NULL) return FALSE; - fb = clutter_paint_node_get_framebuffer (node); + fb = get_target_framebuffer (node, paint_context); for (i = 0; i < node->operations->len; i++) { @@ -994,6 +1042,7 @@ clutter_clip_node_pre_draw (ClutterPaintNode *node) retval = TRUE; break; + case PAINT_OP_MULTITEX_RECT: case PAINT_OP_PRIMITIVE: case PAINT_OP_INVALID: break; @@ -1004,7 +1053,8 @@ clutter_clip_node_pre_draw (ClutterPaintNode *node) } static void -clutter_clip_node_post_draw (ClutterPaintNode *node) +clutter_clip_node_post_draw (ClutterPaintNode *node, + ClutterPaintContext *paint_context) { CoglFramebuffer *fb; guint i; @@ -1012,7 +1062,7 @@ clutter_clip_node_post_draw (ClutterPaintNode *node) if (node->operations == NULL) return; - fb = clutter_paint_node_get_framebuffer (node); + fb = get_target_framebuffer (node, paint_context); for (i = 0; i < node->operations->len; i++) { @@ -1027,6 +1077,7 @@ clutter_clip_node_post_draw (ClutterPaintNode *node) cogl_framebuffer_pop_clip (fb); break; + case PAINT_OP_MULTITEX_RECT: case PAINT_OP_PRIMITIVE: case PAINT_OP_INVALID: break; @@ -1067,10 +1118,118 @@ clutter_clip_node_new (void) } /* - * ClutterLayerNode (private) + * ClutterActorNode + */ + +struct _ClutterActorNode +{ + ClutterPaintNode parent_instance; + + ClutterActor *actor; +}; + +struct _ClutterActorNodeClass +{ + ClutterPaintNodeClass parent_class; +}; + +G_DEFINE_TYPE (ClutterActorNode, clutter_actor_node, CLUTTER_TYPE_PAINT_NODE) + +static gboolean +clutter_actor_node_pre_draw (ClutterPaintNode *node, + ClutterPaintContext *paint_context) +{ + ClutterActorNode *actor_node = CLUTTER_ACTOR_NODE (node); + + CLUTTER_SET_PRIVATE_FLAGS (actor_node->actor, CLUTTER_IN_PAINT); + + return TRUE; +} + +static void +clutter_actor_node_draw (ClutterPaintNode *node, + ClutterPaintContext *paint_context) +{ + ClutterActorNode *actor_node = CLUTTER_ACTOR_NODE (node); + + clutter_actor_continue_paint (actor_node->actor, paint_context); +} + +static void +clutter_actor_node_post_draw (ClutterPaintNode *node, + ClutterPaintContext *paint_context) +{ + ClutterActorNode *actor_node = CLUTTER_ACTOR_NODE (node); + + CLUTTER_UNSET_PRIVATE_FLAGS (actor_node->actor, CLUTTER_IN_PAINT); +} + +static JsonNode * +clutter_actor_node_serialize (ClutterPaintNode *node) +{ + ClutterActorNode *actor_node = CLUTTER_ACTOR_NODE (node); + g_autoptr (JsonBuilder) builder = NULL; + const char *debug_name; + + debug_name = _clutter_actor_get_debug_name (actor_node->actor); + + builder = json_builder_new (); + + json_builder_begin_object (builder); + json_builder_set_member_name (builder, "actor"); + json_builder_add_string_value (builder, debug_name); + json_builder_end_object (builder); + + return json_builder_get_root (builder); +} + +static void +clutter_actor_node_class_init (ClutterActorNodeClass *klass) +{ + ClutterPaintNodeClass *node_class; + + node_class = CLUTTER_PAINT_NODE_CLASS (klass); + node_class->pre_draw = clutter_actor_node_pre_draw; + node_class->draw = clutter_actor_node_draw; + node_class->post_draw = clutter_actor_node_post_draw; + node_class->serialize = clutter_actor_node_serialize; +} + +static void +clutter_actor_node_init (ClutterActorNode *self) +{ +} + +/* + * clutter_actor_node_new: + * @actor: the actor to paint + * + * Creates a new #ClutterActorNode. + * + * The actor is painted together with any effects + * applied to it. Children of this node will draw + * over the actor contents. + * + * Return value: (transfer full): the newly created #ClutterActorNode. + * Use clutter_paint_node_unref() when done. */ +ClutterPaintNode * +clutter_actor_node_new (ClutterActor *actor) +{ + ClutterActorNode *res; -#define clutter_layer_node_get_type _clutter_layer_node_get_type + g_assert (actor != NULL); + + res = _clutter_paint_node_create (CLUTTER_TYPE_ACTOR_NODE); + res->actor = actor; + + return (ClutterPaintNode *) res; +} + + +/* + * ClutterLayerNode + */ struct _ClutterLayerNode { @@ -1098,9 +1257,11 @@ struct _ClutterLayerNodeClass G_DEFINE_TYPE (ClutterLayerNode, clutter_layer_node, CLUTTER_TYPE_PAINT_NODE) static gboolean -clutter_layer_node_pre_draw (ClutterPaintNode *node) +clutter_layer_node_pre_draw (ClutterPaintNode *node, + ClutterPaintContext *paint_context) { ClutterLayerNode *lnode = (ClutterLayerNode *) node; + CoglFramebuffer *framebuffer; CoglMatrix matrix; /* if we were unable to create an offscreen buffer for this node, then @@ -1116,9 +1277,10 @@ clutter_layer_node_pre_draw (ClutterPaintNode *node) /* copy the same modelview from the current framebuffer to the one we * are going to use */ - cogl_get_modelview_matrix (&matrix); + framebuffer = clutter_paint_context_get_framebuffer (paint_context); + cogl_framebuffer_get_modelview_matrix (framebuffer, &matrix); - cogl_push_framebuffer (lnode->offscreen); + clutter_paint_context_push_framebuffer (paint_context, lnode->offscreen); cogl_framebuffer_set_modelview_matrix (lnode->offscreen, &matrix); @@ -1136,7 +1298,7 @@ clutter_layer_node_pre_draw (ClutterPaintNode *node) COGL_BUFFER_BIT_COLOR | COGL_BUFFER_BIT_DEPTH, 0.f, 0.f, 0.f, 0.f); - cogl_push_matrix (); + cogl_framebuffer_push_matrix (lnode->offscreen); /* every draw operation after this point will happen an offscreen * framebuffer @@ -1146,17 +1308,18 @@ clutter_layer_node_pre_draw (ClutterPaintNode *node) } static void -clutter_layer_node_post_draw (ClutterPaintNode *node) +clutter_layer_node_post_draw (ClutterPaintNode *node, + ClutterPaintContext *paint_context) { ClutterLayerNode *lnode = CLUTTER_LAYER_NODE (node); CoglFramebuffer *fb; guint i; /* switch to the previous framebuffer */ - cogl_pop_matrix (); - cogl_pop_framebuffer (); + cogl_framebuffer_pop_matrix (lnode->offscreen); + clutter_paint_context_pop_framebuffer (paint_context); - fb = cogl_get_draw_framebuffer (); + fb = clutter_paint_context_get_framebuffer (paint_context); for (i = 0; i < node->operations->len; i++) { @@ -1170,22 +1333,31 @@ clutter_layer_node_post_draw (ClutterPaintNode *node) case PAINT_OP_TEX_RECT: /* now we need to paint the texture */ - cogl_push_source (lnode->state); - cogl_rectangle_with_texture_coords (op->op.texrect[0], - op->op.texrect[1], - op->op.texrect[2], - op->op.texrect[3], - op->op.texrect[4], - op->op.texrect[5], - op->op.texrect[6], - op->op.texrect[7]); - cogl_pop_source (); + cogl_framebuffer_draw_textured_rectangle (fb, + lnode->state, + op->op.texrect[0], + op->op.texrect[1], + op->op.texrect[2], + op->op.texrect[3], + op->op.texrect[4], + op->op.texrect[5], + op->op.texrect[6], + op->op.texrect[7]); + break; + + case PAINT_OP_MULTITEX_RECT: + cogl_framebuffer_draw_multitextured_rectangle (fb, + lnode->state, + op->op.texrect[0], + op->op.texrect[1], + op->op.texrect[2], + op->op.texrect[3], + (float*) op->multitex_coords->data, + op->multitex_coords->len); break; case PAINT_OP_PATH: - cogl_push_source (lnode->state); - cogl_path_fill (op->op.path); - cogl_pop_source (); + cogl_framebuffer_fill_path (fb, lnode->state, op->op.path); break; case PAINT_OP_PRIMITIVE: @@ -1246,11 +1418,11 @@ clutter_layer_node_init (ClutterLayerNode *self) * Since: 1.10 */ ClutterPaintNode * -_clutter_layer_node_new (const CoglMatrix *projection, - const cairo_rectangle_t *viewport, - float width, - float height, - guint8 opacity) +clutter_layer_node_new (const CoglMatrix *projection, + const cairo_rectangle_t *viewport, + float width, + float height, + guint8 opacity) { ClutterLayerNode *res; CoglColor color; diff --git a/clutter/clutter/clutter-paint-nodes.h b/clutter/clutter/clutter-paint-nodes.h index c86132c3d..235f4bc45 100644 --- a/clutter/clutter/clutter-paint-nodes.h +++ b/clutter/clutter/clutter-paint-nodes.h @@ -49,10 +49,10 @@ G_BEGIN_DECLS typedef struct _ClutterColorNode ClutterColorNode; typedef struct _ClutterColorNodeClass ClutterColorNodeClass; -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT GType clutter_color_node_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT ClutterPaintNode * clutter_color_node_new (const ClutterColor *color); #define CLUTTER_TYPE_TEXTURE_NODE (clutter_texture_node_get_type ()) @@ -70,10 +70,10 @@ ClutterPaintNode * clutter_color_node_new (const ClutterColor * typedef struct _ClutterTextureNode ClutterTextureNode; typedef struct _ClutterTextureNodeClass ClutterTextureNodeClass; -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT GType clutter_texture_node_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT ClutterPaintNode * clutter_texture_node_new (CoglTexture *texture, const ClutterColor *color, ClutterScalingFilter min_filter, @@ -94,10 +94,10 @@ ClutterPaintNode * clutter_texture_node_new (CoglTexture * typedef struct _ClutterClipNode ClutterClipNode; typedef struct _ClutterClipNodeClass ClutterClipNodeClass; -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT GType clutter_clip_node_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT ClutterPaintNode * clutter_clip_node_new (void); #define CLUTTER_TYPE_PIPELINE_NODE (clutter_pipeline_node_get_type ()) @@ -115,10 +115,10 @@ ClutterPaintNode * clutter_clip_node_new (void); typedef struct _ClutterPipelineNode ClutterPipelineNode; typedef struct _ClutterPipelineNodeClass ClutterPipelineNodeClass; -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT GType clutter_pipeline_node_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT ClutterPaintNode * clutter_pipeline_node_new (CoglPipeline *pipeline); #define CLUTTER_TYPE_TEXT_NODE (clutter_text_node_get_type ()) @@ -136,13 +136,100 @@ ClutterPaintNode * clutter_pipeline_node_new (CoglPipeline * typedef struct _ClutterTextNode ClutterTextNode; typedef struct _ClutterTextNodeClass ClutterTextNodeClass; -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT GType clutter_text_node_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT ClutterPaintNode * clutter_text_node_new (PangoLayout *layout, const ClutterColor *color); +#define CLUTTER_TYPE_ACTOR_NODE (clutter_actor_node_get_type ()) +#define CLUTTER_ACTOR_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ACTOR_NODE, ClutterActorNode)) +#define CLUTTER_IS_ACTOR_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ACTOR_NODE)) + +/** + * ClutterActorNode: + * + * The #ClutterActorNode structure is an opaque + * type whose members cannot be directly accessed. + */ +typedef struct _ClutterActorNode ClutterActorNode; +typedef struct _ClutterActorNode ClutterActorNodeClass; + +CLUTTER_EXPORT +GType clutter_actor_node_get_type (void) G_GNUC_CONST; + +CLUTTER_EXPORT +ClutterPaintNode * clutter_actor_node_new (ClutterActor *actor); + +#define CLUTTER_TYPE_ROOT_NODE (clutter_root_node_get_type ()) +#define CLUTTER_ROOT_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ROOT_NODE, ClutterRootNode)) +#define CLUTTER_IS_ROOT_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ROOT_NODE)) + +/** + * ClutterRootNode: + * + * The #ClutterRootNode structure is an opaque + * type whose members cannot be directly accessed. + */ +typedef struct _ClutterRootNode ClutterRootNode; +typedef struct _ClutterPaintNodeClass ClutterRootNodeClass; + +CLUTTER_EXPORT +GType clutter_root_node_get_type (void) G_GNUC_CONST; + +CLUTTER_EXPORT +ClutterPaintNode * clutter_root_node_new (CoglFramebuffer *framebuffer, + const ClutterColor *clear_color, + CoglBufferBit clear_flags); + +#define CLUTTER_TYPE_LAYER_NODE (clutter_layer_node_get_type ()) +#define CLUTTER_LAYER_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_LAYER_NODE, ClutterLayerNode)) +#define CLUTTER_IS_LAYER_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_LAYER_NODE)) + +/* + * ClutterLayerNode: + * + * The #ClutterLayerNode structure is an opaque + * type whose members cannot be directly accessed. + * + * Since: 1.10 + */ +typedef struct _ClutterLayerNode ClutterLayerNode; +typedef struct _ClutterLayerNodeClass ClutterLayerNodeClass; + +CLUTTER_EXPORT +GType clutter_layer_node_get_type (void) G_GNUC_CONST; + +CLUTTER_EXPORT +ClutterPaintNode * clutter_layer_node_new (const CoglMatrix *projection, + const cairo_rectangle_t *viewport, + float width, + float height, + guint8 opacity); + + +#define CLUTTER_TYPE_TRANSFORM_NODE (clutter_transform_node_get_type ()) +#define CLUTTER_TRANSFORM_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_TRANSFORM_NODE, ClutterTransformNode)) +#define CLUTTER_IS_TRANSFORM_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_TRANSFORM_NODE)) + +/* + * ClutterTransformNode: + * + * The #ClutterLayerNode structure is an opaque + * type whose members cannot be directly accessed. + * + * Since: 1.10 + */ +typedef struct _ClutterTransformNode ClutterTransformNode; +typedef struct _ClutterPaintNodeClass ClutterTransformNodeClass; + +CLUTTER_EXPORT +GType clutter_transform_node_get_type (void) G_GNUC_CONST; + +CLUTTER_EXPORT +ClutterPaintNode * clutter_transform_node_new (const CoglMatrix *projection); + G_END_DECLS #endif /* __CLUTTER_PAINT_NODES_H__ */ diff --git a/clutter/clutter/clutter-paint-volume-private.h b/clutter/clutter/clutter-paint-volume-private.h index 72bc7aee3..21e35c202 100644 --- a/clutter/clutter/clutter-paint-volume-private.h +++ b/clutter/clutter/clutter-paint-volume-private.h @@ -58,7 +58,7 @@ struct _ClutterPaintVolume * elements 4, 5, 6 and 7 most of the time for 2D actors when * calculating the projected paint box. */ - ClutterVertex vertices[8]; + graphene_point3d_t vertices[8]; /* As an optimization for internally managed PaintVolumes we allow * initializing ClutterPaintVolume variables allocated on the stack diff --git a/clutter/clutter/clutter-paint-volume.c b/clutter/clutter/clutter-paint-volume.c index ddcca5c34..09edeb6f0 100644 --- a/clutter/clutter/clutter-paint-volume.c +++ b/clutter/clutter/clutter-paint-volume.c @@ -24,9 +24,7 @@ * Emmanuele Bassi */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include @@ -65,7 +63,7 @@ _clutter_paint_volume_new (ClutterActor *actor) pv->actor = actor; - memset (pv->vertices, 0, 8 * sizeof (ClutterVertex)); + memset (pv->vertices, 0, 8 * sizeof (graphene_point3d_t)); pv->is_static = FALSE; pv->is_empty = TRUE; @@ -98,7 +96,7 @@ _clutter_paint_volume_init_static (ClutterPaintVolume *pv, { pv->actor = actor; - memset (pv->vertices, 0, 8 * sizeof (ClutterVertex)); + memset (pv->vertices, 0, 8 * sizeof (graphene_point3d_t)); pv->is_static = TRUE; pv->is_empty = TRUE; @@ -172,7 +170,7 @@ clutter_paint_volume_free (ClutterPaintVolume *pv) /** * clutter_paint_volume_set_origin: * @pv: a #ClutterPaintVolume - * @origin: a #ClutterVertex + * @origin: a #graphene_point3d_t * * Sets the origin of the paint volume. * @@ -184,8 +182,8 @@ clutter_paint_volume_free (ClutterPaintVolume *pv) * Since: 1.6 */ void -clutter_paint_volume_set_origin (ClutterPaintVolume *pv, - const ClutterVertex *origin) +clutter_paint_volume_set_origin (ClutterPaintVolume *pv, + const graphene_point3d_t *origin) { static const int key_vertices[4] = { 0, 1, 3, 4 }; float dx, dy, dz; @@ -212,7 +210,7 @@ clutter_paint_volume_set_origin (ClutterPaintVolume *pv, /** * clutter_paint_volume_get_origin: * @pv: a #ClutterPaintVolume - * @vertex: (out): the return location for a #ClutterVertex + * @vertex: (out): the return location for a #graphene_point3d_t * * Retrieves the origin of the #ClutterPaintVolume. * @@ -220,7 +218,7 @@ clutter_paint_volume_set_origin (ClutterPaintVolume *pv, */ void clutter_paint_volume_get_origin (const ClutterPaintVolume *pv, - ClutterVertex *vertex) + graphene_point3d_t *vertex) { g_return_if_fail (pv != NULL); g_return_if_fail (vertex != NULL); @@ -661,7 +659,7 @@ clutter_paint_volume_union_box (ClutterPaintVolume *pv, const ClutterActorBox *box) { ClutterPaintVolume volume; - ClutterVertex origin; + graphene_point3d_t origin; g_return_if_fail (pv != NULL); g_return_if_fail (box != NULL); @@ -759,7 +757,7 @@ _clutter_paint_volume_get_bounding_box (ClutterPaintVolume *pv, ClutterActorBox *box) { gfloat x_min, y_min, x_max, y_max; - ClutterVertex *vertices; + graphene_point3d_t *vertices; int count; gint i; @@ -880,9 +878,9 @@ _clutter_paint_volume_transform (ClutterPaintVolume *pv, cogl_matrix_transform_points (matrix, 3, - sizeof (ClutterVertex), + sizeof (graphene_point3d_t), pv->vertices, - sizeof (ClutterVertex), + sizeof (graphene_point3d_t), pv->vertices, transform_count); @@ -898,7 +896,7 @@ _clutter_paint_volume_axis_align (ClutterPaintVolume *pv) { int count; int i; - ClutterVertex origin; + graphene_point3d_t origin; float max_x; float max_y; float max_z; @@ -1077,7 +1075,7 @@ _clutter_paint_volume_cull (ClutterPaintVolume *pv, const ClutterPlane *planes) { int vertex_count; - ClutterVertex *vertices = pv->vertices; + graphene_point3d_t *vertices = pv->vertices; gboolean partial = FALSE; int i; int j; @@ -1099,24 +1097,18 @@ _clutter_paint_volume_cull (ClutterPaintVolume *pv, for (i = 0; i < 4; i++) { + const ClutterPlane *plane = &planes[i]; int out = 0; for (j = 0; j < vertex_count; j++) { - ClutterVertex p; - float distance; + graphene_vec3_t v; - /* XXX: for perspective projections this can be optimized - * out because all the planes should pass through the origin - * so (0,0,0) is a valid v0. */ - p.x = vertices[j].x - planes[i].v0[0]; - p.y = vertices[j].y - planes[i].v0[1]; - p.z = vertices[j].z - planes[i].v0[2]; + graphene_vec3_init (&v, + vertices[j].x - graphene_vec3_get_x (&plane->v0), + vertices[j].y - graphene_vec3_get_y (&plane->v0), + vertices[j].z - graphene_vec3_get_z (&plane->v0)); - distance = (planes[i].n[0] * p.x + - planes[i].n[1] * p.y + - planes[i].n[2] * p.z); - - if (distance < 0) + if (graphene_vec3_dot (&plane->n, &v) < 0) out++; } @@ -1165,6 +1157,21 @@ _clutter_paint_volume_get_stage_paint_box (ClutterPaintVolume *pv, _clutter_paint_volume_get_bounding_box (&projected_pv, box); + if (pv->is_2d && pv->actor && + clutter_actor_get_z_position (pv->actor) == 0) + { + /* If the volume/actor are perfectly 2D, take the bounding box as + * good. We won't need to add any extra room for sub-pixel positioning + * in this case. + */ + clutter_paint_volume_free (&projected_pv); + box->x1 = CLUTTER_NEARBYINT (box->x1); + box->y1 = CLUTTER_NEARBYINT (box->y1); + box->x2 = CLUTTER_NEARBYINT (box->x2); + box->y2 = CLUTTER_NEARBYINT (box->y2); + return; + } + _clutter_actor_box_enlarge_for_effects (box); clutter_paint_volume_free (&projected_pv); diff --git a/clutter/clutter/clutter-pan-action.c b/clutter/clutter/clutter-pan-action.c index 582a7d72b..07d819e52 100644 --- a/clutter/clutter/clutter-pan-action.c +++ b/clutter/clutter/clutter-pan-action.c @@ -53,9 +53,7 @@ * Since: 1.12 */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include "clutter-pan-action.h" @@ -581,8 +579,7 @@ clutter_pan_action_class_init (ClutterPanActionClass *klass) G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ClutterPanActionClass, pan_stopped), - NULL, NULL, - _clutter_marshal_VOID__OBJECT, + NULL, NULL, NULL, G_TYPE_NONE, 1, CLUTTER_TYPE_ACTOR); } @@ -963,6 +960,7 @@ clutter_pan_action_get_motion_delta (ClutterPanAction *self, return clutter_pan_action_get_interpolated_delta (self, delta_x, delta_y); default: g_assert_not_reached (); + return 0.0f; } } diff --git a/clutter/clutter/clutter-pan-action.h b/clutter/clutter/clutter-pan-action.h index 866ec97ee..64115b69b 100644 --- a/clutter/clutter/clutter-pan-action.h +++ b/clutter/clutter/clutter-pan-action.h @@ -99,50 +99,50 @@ struct _ClutterPanActionClass void (* _clutter_pan_action6) (void); }; -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT GType clutter_pan_action_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT ClutterAction * clutter_pan_action_new (void); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_pan_action_set_pan_axis (ClutterPanAction *self, ClutterPanAxis axis); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT ClutterPanAxis clutter_pan_action_get_pan_axis (ClutterPanAction *self); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_pan_action_set_interpolate (ClutterPanAction *self, gboolean should_interpolate); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT gboolean clutter_pan_action_get_interpolate (ClutterPanAction *self); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_pan_action_set_deceleration (ClutterPanAction *self, gdouble rate); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT gdouble clutter_pan_action_get_deceleration (ClutterPanAction *self); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_pan_action_set_acceleration_factor (ClutterPanAction *self, gdouble factor); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT gdouble clutter_pan_action_get_acceleration_factor (ClutterPanAction *self); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_pan_action_get_interpolated_coords (ClutterPanAction *self, gfloat *interpolated_x, gfloat *interpolated_y); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT gfloat clutter_pan_action_get_interpolated_delta (ClutterPanAction *self, gfloat *delta_x, gfloat *delta_y); -CLUTTER_AVAILABLE_IN_1_14 +CLUTTER_EXPORT gfloat clutter_pan_action_get_motion_delta (ClutterPanAction *self, guint point, gfloat *delta_x, gfloat *delta_y); -CLUTTER_AVAILABLE_IN_1_14 +CLUTTER_EXPORT void clutter_pan_action_get_motion_coords (ClutterPanAction *self, guint point, gfloat *motion_x, gfloat *motion_y); -CLUTTER_AVAILABLE_IN_1_24 +CLUTTER_EXPORT gfloat clutter_pan_action_get_constrained_motion_delta (ClutterPanAction *self, guint point, gfloat *delta_x, diff --git a/clutter/clutter/clutter-path-constraint.c b/clutter/clutter/clutter-path-constraint.c index fc9720b70..b2eb918db 100644 --- a/clutter/clutter/clutter-path-constraint.c +++ b/clutter/clutter/clutter-path-constraint.c @@ -36,9 +36,7 @@ * ClutterPathConstraint is available since Clutter 1.6. */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include "clutter-path-constraint.h" diff --git a/clutter/clutter/clutter-path-constraint.h b/clutter/clutter/clutter-path-constraint.h index f6d65ead3..cd66a0350 100644 --- a/clutter/clutter/clutter-path-constraint.h +++ b/clutter/clutter/clutter-path-constraint.h @@ -49,22 +49,22 @@ G_BEGIN_DECLS typedef struct _ClutterPathConstraint ClutterPathConstraint; typedef struct _ClutterPathConstraintClass ClutterPathConstraintClass; -CLUTTER_AVAILABLE_IN_1_6 +CLUTTER_EXPORT GType clutter_path_constraint_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_6 +CLUTTER_EXPORT ClutterConstraint *clutter_path_constraint_new (ClutterPath *path, gfloat offset); -CLUTTER_AVAILABLE_IN_1_6 +CLUTTER_EXPORT void clutter_path_constraint_set_path (ClutterPathConstraint *constraint, ClutterPath *path); -CLUTTER_AVAILABLE_IN_1_6 +CLUTTER_EXPORT ClutterPath * clutter_path_constraint_get_path (ClutterPathConstraint *constraint); -CLUTTER_AVAILABLE_IN_1_6 +CLUTTER_EXPORT void clutter_path_constraint_set_offset (ClutterPathConstraint *constraint, gfloat offset); -CLUTTER_AVAILABLE_IN_1_6 +CLUTTER_EXPORT gfloat clutter_path_constraint_get_offset (ClutterPathConstraint *constraint); G_END_DECLS diff --git a/clutter/clutter/clutter-path.c b/clutter/clutter/clutter-path.c index 1b55d7ee3..facb7b07a 100644 --- a/clutter/clutter/clutter-path.c +++ b/clutter/clutter/clutter-path.c @@ -27,8 +27,7 @@ * and bezier curves. * * A #ClutterPath contains a description of a path consisting of - * straight lines and bezier curves. This can be used in a - * #ClutterBehaviourPath to animate an actor moving along the path. + * straight lines and bezier curves. * * The path consists of a series of nodes. Each node is one of the * following four types: @@ -61,9 +60,7 @@ * #ClutterPath is available since Clutter 1.0 */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include #include @@ -246,9 +243,6 @@ clutter_path_finalize (GObject *object) * * Creates a new #ClutterPath instance with no nodes. * - * The object has a floating reference so if you add it to a - * #ClutterBehaviourPath then you do not need to unref it. - * * Return value: the newly created #ClutterPath * * Since: 1.0 @@ -269,9 +263,6 @@ clutter_path_new (void) * @desc. See clutter_path_add_string() for details of the format of * the string. * - * The object has a floating reference so if you add it to a - * #ClutterBehaviourPath then you do not need to unref it. - * * Return value: the newly created #ClutterPath * * Since: 1.0 @@ -297,8 +288,7 @@ clutter_path_clear (ClutterPath *path) { ClutterPathPrivate *priv = path->priv; - g_slist_foreach (priv->nodes, (GFunc) clutter_path_node_full_free, NULL); - g_slist_free (priv->nodes); + g_slist_free_full (priv->nodes, (GDestroyNotify) clutter_path_node_full_free); priv->nodes = priv->nodes_tail = NULL; priv->nodes_dirty = TRUE; @@ -661,8 +651,7 @@ clutter_path_parse_description (const gchar *p, return TRUE; fail: - g_slist_foreach (nodes, (GFunc) clutter_path_node_full_free, NULL); - g_slist_free (nodes); + g_slist_free_full (nodes, (GDestroyNotify) clutter_path_node_full_free); return FALSE; } @@ -1135,7 +1124,7 @@ clutter_path_set_description (ClutterPath *path, * Returns a newly allocated string describing the path in the same * format as used by clutter_path_add_string(). * - * Return value: a string description of the path. Free with free(). + * Return value: a string description of the path. Free with g_free(). * * Since: 1.0 */ diff --git a/clutter/clutter/clutter-path.h b/clutter/clutter/clutter-path.h index 38133a554..8ec4d93f5 100644 --- a/clutter/clutter/clutter-path.h +++ b/clutter/clutter/clutter-path.h @@ -86,30 +86,30 @@ struct _ClutterPathClass GInitiallyUnownedClass parent_class; }; -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT GType clutter_path_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT ClutterPath *clutter_path_new (void); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT ClutterPath *clutter_path_new_with_description (const gchar *desc); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_path_add_move_to (ClutterPath *path, gint x, gint y); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_path_add_rel_move_to (ClutterPath *path, gint x, gint y); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_path_add_line_to (ClutterPath *path, gint x, gint y); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_path_add_rel_line_to (ClutterPath *path, gint x, gint y); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_path_add_curve_to (ClutterPath *path, gint x_1, gint y_1, @@ -117,7 +117,7 @@ void clutter_path_add_curve_to (ClutterPath *path, gint y_2, gint x_3, gint y_3); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_path_add_rel_curve_to (ClutterPath *path, gint x_1, gint y_1, @@ -125,55 +125,55 @@ void clutter_path_add_rel_curve_to (ClutterPath *path, gint y_2, gint x_3, gint y_3); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_path_add_close (ClutterPath *path); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT gboolean clutter_path_add_string (ClutterPath *path, const gchar *str); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_path_add_node (ClutterPath *path, const ClutterPathNode *node); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_path_add_cairo_path (ClutterPath *path, const cairo_path_t *cpath); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT guint clutter_path_get_n_nodes (ClutterPath *path); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_path_get_node (ClutterPath *path, guint index_, ClutterPathNode *node); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT GSList * clutter_path_get_nodes (ClutterPath *path); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_path_foreach (ClutterPath *path, ClutterPathCallback callback, gpointer user_data); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_path_insert_node (ClutterPath *path, gint index_, const ClutterPathNode *node); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_path_remove_node (ClutterPath *path, guint index_); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_path_replace_node (ClutterPath *path, guint index_, const ClutterPathNode *node); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT gchar * clutter_path_get_description (ClutterPath *path); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT gboolean clutter_path_set_description (ClutterPath *path, const gchar *str); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_path_clear (ClutterPath *path); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_path_to_cairo_path (ClutterPath *path, cairo_t *cr); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT guint clutter_path_get_position (ClutterPath *path, gdouble progress, ClutterKnot *position); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT guint clutter_path_get_length (ClutterPath *path); G_END_DECLS diff --git a/clutter/clutter/clutter-pick-context-private.h b/clutter/clutter/clutter-pick-context-private.h new file mode 100644 index 000000000..4e6db156b --- /dev/null +++ b/clutter/clutter/clutter-pick-context-private.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2019 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#ifndef CLUTTER_PICK_CONTEXT_PRIVATE_H +#define CLUTTER_PICK_CONTEXT_PRIVATE_H + +#include "clutter-pick-context.h" + +ClutterPickContext * clutter_pick_context_new_for_view (ClutterStageView *view); + +#endif /* CLUTTER_PICK_CONTEXT_PRIVATE_H */ diff --git a/clutter/clutter/clutter-pick-context.c b/clutter/clutter/clutter-pick-context.c new file mode 100644 index 000000000..a02d6e795 --- /dev/null +++ b/clutter/clutter/clutter-pick-context.c @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2019 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#include "clutter-build-config.h" + +#include "clutter-pick-context-private.h" + +struct _ClutterPickContext +{ + grefcount ref_count; + + CoglFramebuffer *framebuffer; +}; + +G_DEFINE_BOXED_TYPE (ClutterPickContext, clutter_pick_context, + clutter_pick_context_ref, + clutter_pick_context_unref) + +ClutterPickContext * +clutter_pick_context_new_for_view (ClutterStageView *view) +{ + ClutterPickContext *pick_context; + + pick_context = g_new0 (ClutterPickContext, 1); + g_ref_count_init (&pick_context->ref_count); + pick_context->framebuffer = + cogl_object_ref (clutter_stage_view_get_framebuffer (view)); + + return pick_context; +} + +ClutterPickContext * +clutter_pick_context_ref (ClutterPickContext *pick_context) +{ + g_ref_count_inc (&pick_context->ref_count); + return pick_context; +} + +static void +clutter_pick_context_dispose (ClutterPickContext *pick_context) +{ + g_clear_pointer (&pick_context->framebuffer, cogl_object_unref); +} + +void +clutter_pick_context_unref (ClutterPickContext *pick_context) +{ + if (g_ref_count_dec (&pick_context->ref_count)) + { + clutter_pick_context_dispose (pick_context); + g_free (pick_context); + } +} + +void +clutter_pick_context_destroy (ClutterPickContext *pick_context) +{ + clutter_pick_context_dispose (pick_context); + clutter_pick_context_unref (pick_context); +} + +/** + * clutter_pick_context_get_framebuffer: (skip) + */ +CoglFramebuffer * +clutter_pick_context_get_framebuffer (ClutterPickContext *pick_context) +{ + return pick_context->framebuffer; +} diff --git a/clutter/clutter/deprecated/clutter-stage-manager.h b/clutter/clutter/clutter-pick-context.h similarity index 51% rename from clutter/clutter/deprecated/clutter-stage-manager.h rename to clutter/clutter/clutter-pick-context.h index df19298dd..a1f8dec41 100644 --- a/clutter/clutter/deprecated/clutter-stage-manager.h +++ b/clutter/clutter/clutter-pick-context.h @@ -1,9 +1,5 @@ /* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2008 OpenedHand + * Copyright (C) 2019 Red Hat Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -17,26 +13,37 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . - * - * Author: Emmanuele Bassi */ +#ifndef CLUTTER_PICK_CONTEXT_H +#define CLUTTER_PICK_CONTEXT_H + #if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) #error "Only can be included directly." #endif -#ifndef __CLUTTER_STAGE_MANAGER_DEPRECATED_H__ -#define __CLUTTER_STAGE_MANAGER_DEPRECATED_H__ +#include + +#include "clutter-macros.h" +#include "clutter-stage-view.h" + +typedef struct _ClutterPickContext ClutterPickContext; + +#define CLUTTER_TYPE_PICK_CONTEXT (clutter_pick_context_get_type ()) -#include +CLUTTER_EXPORT +GType clutter_pick_context_get_type (void); -G_BEGIN_DECLS +CLUTTER_EXPORT +ClutterPickContext * clutter_pick_context_ref (ClutterPickContext *pick_context); -CLUTTER_DEPRECATED_IN_1_2 -void clutter_stage_manager_set_default_stage (ClutterStageManager *stage_manager, - ClutterStage *stage); +CLUTTER_EXPORT +void clutter_pick_context_unref (ClutterPickContext *pick_context); -G_END_DECLS +CLUTTER_EXPORT +void clutter_pick_context_destroy (ClutterPickContext *pick_context); -#endif /*__CLUTTER_STAGE_MANAGER_DEPRECATED_H__ */ +CLUTTER_EXPORT +CoglFramebuffer * clutter_pick_context_get_framebuffer (ClutterPickContext *pick_context); +#endif /* CLUTTER_PICK_CONTEXT_H */ diff --git a/clutter/clutter/clutter-private.h b/clutter/clutter/clutter-private.h index ee075bd5d..e2a139f07 100644 --- a/clutter/clutter/clutter-private.h +++ b/clutter/clutter/clutter-private.h @@ -64,11 +64,14 @@ typedef struct _ClutterVertex4 ClutterVertex4; #define CLUTTER_UNSET_PRIVATE_FLAGS(a,f) (CLUTTER_PRIVATE_FLAGS (a) &= ~(f)) #define CLUTTER_ACTOR_IS_TOPLEVEL(a) ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IS_TOPLEVEL) != FALSE) -#define CLUTTER_ACTOR_IS_INTERNAL_CHILD(a) ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_INTERNAL_CHILD) != FALSE) #define CLUTTER_ACTOR_IN_DESTRUCTION(a) ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_DESTRUCTION) != FALSE) #define CLUTTER_ACTOR_IN_REPARENT(a) ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_REPARENT) != FALSE) #define CLUTTER_ACTOR_IN_PAINT(a) ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_PAINT) != FALSE) +#define CLUTTER_ACTOR_IN_PICK(a) ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_PICK) != FALSE) #define CLUTTER_ACTOR_IN_RELAYOUT(a) ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_RELAYOUT) != FALSE) +#define CLUTTER_ACTOR_IN_PREF_WIDTH(a) ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_PREF_WIDTH) != FALSE) +#define CLUTTER_ACTOR_IN_PREF_HEIGHT(a) ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_PREF_HEIGHT) != FALSE) +#define CLUTTER_ACTOR_IN_PREF_SIZE(a) ((CLUTTER_PRIVATE_FLAGS (a) & (CLUTTER_IN_PREF_HEIGHT|CLUTTER_IN_PREF_WIDTH)) != FALSE) #define CLUTTER_PARAM_READABLE (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS) #define CLUTTER_PARAM_WRITABLE (G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS) @@ -82,7 +85,6 @@ typedef struct _ClutterVertex4 ClutterVertex4; /* keep this for source compatibility with clutter */ #define P_(String) (String) #define N_(String) (String) -#define _(String) (String) /* This is a replacement for the nearbyint function which always rounds to the * nearest integer. nearbyint is apparently a C99 function so it might not @@ -91,21 +93,22 @@ typedef struct _ClutterVertex4 ClutterVertex4; * because it will break for negative numbers. */ #define CLUTTER_NEARBYINT(x) ((int) ((x) < 0.0f ? (x) - 0.5f : (x) + 0.5f)) -typedef enum { +typedef enum +{ CLUTTER_ACTOR_UNUSED_FLAG = 0, CLUTTER_IN_DESTRUCTION = 1 << 0, CLUTTER_IS_TOPLEVEL = 1 << 1, CLUTTER_IN_REPARENT = 1 << 2, + CLUTTER_IN_PREF_WIDTH = 1 << 3, + CLUTTER_IN_PREF_HEIGHT = 1 << 4, /* Used to avoid recursion */ - CLUTTER_IN_PAINT = 1 << 3, + CLUTTER_IN_PAINT = 1 << 5, + CLUTTER_IN_PICK = 1 << 6, /* Used to avoid recursion */ - CLUTTER_IN_RELAYOUT = 1 << 4, - - /* a flag for internal children of Containers (DEPRECATED) */ - CLUTTER_INTERNAL_CHILD = 1 << 5 + CLUTTER_IN_RELAYOUT = 1 << 7, } ClutterPrivateFlags; /* @@ -136,13 +139,6 @@ struct _ClutterMainContext /* default FPS; this is only used if we cannot sync to vblank */ guint frame_rate; - /* actors with a grab on all devices */ - ClutterActor *pointer_grab_actor; - ClutterActor *keyboard_grab_actor; - - /* stack of actors with shaders during paint */ - GSList *shaders; - /* fb bit masks for col<->id mapping in picking */ gint fb_r_mask; gint fb_g_mask; @@ -167,7 +163,6 @@ struct _ClutterMainContext /* boolean flags */ guint is_initialized : 1; - guint motion_events_per_actor : 1; guint defer_display_setup : 1; guint options_parsed : 1; guint show_fps : 1; @@ -184,7 +179,9 @@ typedef struct gboolean _clutter_threads_dispatch (gpointer data); void _clutter_threads_dispatch_free (gpointer data); +CLUTTER_EXPORT void _clutter_threads_acquire_lock (void); +CLUTTER_EXPORT void _clutter_threads_release_lock (void); ClutterMainContext * _clutter_context_get_default (void); @@ -192,22 +189,16 @@ void _clutter_context_lock (void); void _clutter_context_unlock (void); gboolean _clutter_context_is_initialized (void); ClutterPickMode _clutter_context_get_pick_mode (void); -void _clutter_context_push_shader_stack (ClutterActor *actor); -ClutterActor * _clutter_context_pop_shader_stack (ClutterActor *actor); -ClutterActor * _clutter_context_peek_shader_stack (void); -gboolean _clutter_context_get_motion_events_enabled (void); gboolean _clutter_context_get_show_fps (void); gboolean _clutter_feature_init (GError **error); /* Diagnostic mode */ gboolean _clutter_diagnostic_enabled (void); -void _clutter_diagnostic_message (const char *fmt, ...); +void _clutter_diagnostic_message (const char *fmt, ...) G_GNUC_PRINTF (1, 2); -/* Picking code */ -guint _clutter_pixel_to_id (guchar pixel[4]); -void _clutter_id_to_color (guint id, - ClutterColor *col); +CLUTTER_EXPORT +void _clutter_set_sync_to_vblank (gboolean sync_to_vblank); /* use this function as the accumulator if you have a signal with * a G_TYPE_BOOLEAN return value; this will stop the emission as @@ -231,12 +222,23 @@ void _clutter_run_repaint_functions (ClutterRepaintFlags flags); GType _clutter_layout_manager_get_child_meta_type (ClutterLayoutManager *manager); -void _clutter_util_fully_transform_vertices (const CoglMatrix *modelview, - const CoglMatrix *projection, - const float *viewport, - const ClutterVertex *vertices_in, - ClutterVertex *vertices_out, - int n_vertices); +void _clutter_util_fully_transform_vertices (const CoglMatrix *modelview, + const CoglMatrix *projection, + const float *viewport, + const graphene_point3d_t *vertices_in, + graphene_point3d_t *vertices_out, + int n_vertices); + +void _clutter_util_rect_from_rectangle (const cairo_rectangle_int_t *src, + graphene_rect_t *dest); + +void _clutter_util_rectangle_int_extents (const graphene_rect_t *src, + cairo_rectangle_int_t *dest); + +void _clutter_util_rectangle_offset (const cairo_rectangle_int_t *src, + int x, + int y, + cairo_rectangle_int_t *dest); void _clutter_util_rectangle_union (const cairo_rectangle_int_t *src1, const cairo_rectangle_int_t *src2, @@ -246,6 +248,9 @@ gboolean _clutter_util_rectangle_intersection (const cairo_rectangle_int_t *src1 const cairo_rectangle_int_t *src2, cairo_rectangle_int_t *dest); +gboolean clutter_util_rectangle_equal (const cairo_rectangle_int_t *src1, + const cairo_rectangle_int_t *src2); + struct _ClutterVertex4 { @@ -278,16 +283,22 @@ void _clutter_util_matrix_skew_yz (ClutterMatrix *matrix, float factor); gboolean _clutter_util_matrix_decompose (const ClutterMatrix *src, - ClutterVertex *scale_p, + graphene_point3d_t *scale_p, float shear_p[3], - ClutterVertex *rotate_p, - ClutterVertex *translate_p, + graphene_point3d_t *rotate_p, + graphene_point3d_t *translate_p, ClutterVertex4 *perspective_p); +CLUTTER_EXPORT +PangoDirection _clutter_pango_unichar_direction (gunichar ch); + +PangoDirection _clutter_pango_find_base_dir (const gchar *text, + gint length); + typedef struct _ClutterPlane { - float v0[3]; - float n[3]; + graphene_vec3_t v0; + graphene_vec3_t n; } ClutterPlane; typedef enum _ClutterCullResult @@ -305,6 +316,8 @@ gboolean _clutter_run_progress_function (GType gtype, gdouble progress, GValue *retval); +void clutter_timeline_cancel_delay (ClutterTimeline *timeline); + G_END_DECLS #endif /* __CLUTTER_PRIVATE_H__ */ diff --git a/clutter/clutter/clutter-property-transition.c b/clutter/clutter/clutter-property-transition.c index c62baf6ee..d18acf39e 100644 --- a/clutter/clutter/clutter-property-transition.c +++ b/clutter/clutter/clutter-property-transition.c @@ -30,9 +30,7 @@ * #ClutterPropertyTransition is available since Clutter 1.10 */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include "clutter-property-transition.h" @@ -125,7 +123,7 @@ clutter_property_transition_detached (ClutterTransition *transition, ClutterPropertyTransition *self = CLUTTER_PROPERTY_TRANSITION (transition); ClutterPropertyTransitionPrivate *priv = self->priv; - priv->pspec = NULL; + priv->pspec = NULL; } static void @@ -238,7 +236,7 @@ clutter_property_transition_finalize (GObject *gobject) priv = CLUTTER_PROPERTY_TRANSITION (gobject)->priv; - free (priv->property_name); + g_free (priv->property_name); G_OBJECT_CLASS (clutter_property_transition_parent_class)->finalize (gobject); } @@ -322,7 +320,7 @@ clutter_property_transition_set_property_name (ClutterPropertyTransition *transi if (g_strcmp0 (priv->property_name, property_name) == 0) return; - free (priv->property_name); + g_free (priv->property_name); priv->property_name = g_strdup (property_name); priv->pspec = NULL; diff --git a/clutter/clutter/clutter-property-transition.h b/clutter/clutter/clutter-property-transition.h index a53f03402..0a3766876 100644 --- a/clutter/clutter/clutter-property-transition.h +++ b/clutter/clutter/clutter-property-transition.h @@ -75,15 +75,15 @@ struct _ClutterPropertyTransitionClass gpointer _padding[8]; }; -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT GType clutter_property_transition_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT ClutterTransition * clutter_property_transition_new (const char *property_name); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_property_transition_set_property_name (ClutterPropertyTransition *transition, const char *property_name); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT const char * clutter_property_transition_get_property_name (ClutterPropertyTransition *transition); G_END_DECLS diff --git a/clutter/clutter/clutter-rotate-action.c b/clutter/clutter/clutter-rotate-action.c index b1c28db7d..7a21607d5 100644 --- a/clutter/clutter/clutter-rotate-action.c +++ b/clutter/clutter/clutter-rotate-action.c @@ -33,9 +33,7 @@ * Since: 1.12 */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include diff --git a/clutter/clutter/clutter-rotate-action.h b/clutter/clutter/clutter-rotate-action.h index c73905482..faa240e6c 100644 --- a/clutter/clutter/clutter-rotate-action.h +++ b/clutter/clutter/clutter-rotate-action.h @@ -89,10 +89,10 @@ struct _ClutterRotateActionClass void (* _clutter_rotate_action7) (void); }; -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT GType clutter_rotate_action_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT ClutterAction *clutter_rotate_action_new (void); G_END_DECLS diff --git a/clutter/clutter/clutter-script-parser.c b/clutter/clutter/clutter-script-parser.c index 48e370a6b..ea14b4166 100644 --- a/clutter/clutter/clutter-script-parser.c +++ b/clutter/clutter/clutter-script-parser.c @@ -24,9 +24,7 @@ * Emmanuele Bassi */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include #include @@ -81,10 +79,10 @@ _clutter_script_get_type_from_symbol (const gchar *symbol) if (!module) module = g_module_open (NULL, 0); - + if (g_module_symbol (module, symbol, (gpointer)&func)) gtype = func (); - + return gtype; } @@ -100,7 +98,7 @@ _clutter_script_get_type_from_class (const gchar *name) if (G_UNLIKELY (!module)) module = g_module_open (NULL, 0); - + for (i = 0; name[i] != '\0'; i++) { gchar c = name[i]; @@ -138,7 +136,7 @@ _clutter_script_get_type_from_class (const gchar *name) } g_string_append (symbol_name, "_get_type"); - + symbol = g_string_free (symbol_name, FALSE); if (g_module_symbol (module, symbol, (gpointer)&func)) @@ -146,8 +144,8 @@ _clutter_script_get_type_from_class (const gchar *name) CLUTTER_NOTE (SCRIPT, "Type function: %s", symbol); gtype = func (); } - - free (symbol); + + g_free (symbol); return gtype; } @@ -176,10 +174,10 @@ _clutter_script_enum_from_string (GType type, gchar *endptr; gint value; gboolean retval = TRUE; - + g_return_val_if_fail (G_TYPE_IS_ENUM (type), 0); g_return_val_if_fail (string != NULL, 0); - + value = strtoul (string, &endptr, 0); if (endptr != string) /* parsed a number */ *enum_value = value; @@ -194,7 +192,7 @@ _clutter_script_enum_from_string (GType type, *enum_value = ev->value; else retval = FALSE; - + g_type_class_unref (eclass); } @@ -216,7 +214,7 @@ _clutter_script_flags_from_string (GType type, g_return_val_if_fail (string != NULL, 0); ret = TRUE; - + value = strtoul (string, &endptr, 0); if (endptr != string) /* parsed a number */ *flags_value = value; @@ -230,19 +228,19 @@ _clutter_script_flags_from_string (GType type, for (value = i = j = 0; ; i++) { gboolean eos = (flagstr[i] == '\0') ? TRUE : FALSE; - + if (!eos && flagstr[i] != '|') continue; - + flag = &flagstr[j]; endptr = &flagstr[i]; - + if (!eos) { flagstr[i++] = '\0'; j = i; } - + /* trim spaces */ for (;;) { @@ -252,7 +250,7 @@ _clutter_script_flags_from_string (GType type, flag = g_utf8_next_char (flag); } - + while (endptr > flag) { gunichar ch; @@ -265,16 +263,16 @@ _clutter_script_flags_from_string (GType type, endptr = prevptr; } - + if (endptr > flag) { *endptr = '\0'; fv = g_flags_get_value_by_name (fclass, flag); - + if (!fv) fv = g_flags_get_value_by_nick (fclass, flag); - + if (fv) value |= fv->value; else @@ -283,16 +281,16 @@ _clutter_script_flags_from_string (GType type, break; } } - + if (eos) { *flags_value = value; break; } } - - free (flagstr); - + + g_free (flagstr); + g_type_class_unref (fclass); } @@ -354,63 +352,64 @@ _clutter_script_parse_knot (ClutterScript *script, } static gboolean -parse_geometry_from_array (JsonArray *array, - ClutterGeometry *geometry) +parse_rect_from_array (JsonArray *array, + graphene_rect_t *rect) { if (json_array_get_length (array) != 4) return FALSE; - geometry->x = json_array_get_int_element (array, 0); - geometry->y = json_array_get_int_element (array, 1); - geometry->width = json_array_get_int_element (array, 2); - geometry->height = json_array_get_int_element (array, 3); + graphene_rect_init (rect, + json_array_get_int_element (array, 0), + json_array_get_int_element (array, 1), + json_array_get_int_element (array, 2), + json_array_get_int_element (array, 3)); return TRUE; } static gboolean -parse_geometry_from_object (JsonObject *object, - ClutterGeometry *geometry) +parse_rect_from_object (JsonObject *object, + graphene_rect_t *rect) { if (json_object_has_member (object, "x")) - geometry->x = json_object_get_int_member (object, "x"); + rect->origin.x = json_object_get_int_member (object, "x"); else - geometry->x = 0; + rect->origin.x = 0; if (json_object_has_member (object, "y")) - geometry->y = json_object_get_int_member (object, "y"); + rect->origin.y = json_object_get_int_member (object, "y"); else - geometry->y = 0; + rect->origin.y = 0; if (json_object_has_member (object, "width")) - geometry->width = json_object_get_int_member (object, "width"); + rect->size.width = json_object_get_int_member (object, "width"); else - geometry->width = 0; + rect->size.width = 0; if (json_object_has_member (object, "height")) - geometry->height = json_object_get_int_member (object, "height"); + rect->size.height = json_object_get_int_member (object, "height"); else - geometry->height = 0; + rect->size.height = 0; return TRUE; } gboolean -_clutter_script_parse_geometry (ClutterScript *script, - JsonNode *node, - ClutterGeometry *geometry) +_clutter_script_parse_rect (ClutterScript *script, + JsonNode *node, + graphene_rect_t *rect) { g_return_val_if_fail (CLUTTER_IS_SCRIPT (script), FALSE); g_return_val_if_fail (node != NULL, FALSE); - g_return_val_if_fail (geometry != NULL, FALSE); + g_return_val_if_fail (rect != NULL, FALSE); switch (JSON_NODE_TYPE (node)) { case JSON_NODE_ARRAY: - return parse_geometry_from_array (json_node_get_array (node), geometry); + return parse_rect_from_array (json_node_get_array (node), rect); case JSON_NODE_OBJECT: - return parse_geometry_from_object (json_node_get_object (node), geometry); + return parse_rect_from_object (json_node_get_object (node), rect); default: break; @@ -494,8 +493,8 @@ _clutter_script_parse_color (ClutterScript *script, } static gboolean -parse_point_from_array (JsonArray *array, - ClutterPoint *point) +parse_point_from_array (JsonArray *array, + graphene_point_t *point) { if (json_array_get_length (array) != 2) return FALSE; @@ -507,8 +506,8 @@ parse_point_from_array (JsonArray *array, } static gboolean -parse_point_from_object (JsonObject *object, - ClutterPoint *point) +parse_point_from_object (JsonObject *object, + graphene_point_t *point) { if (json_object_has_member (object, "x")) point->x = json_object_get_double_member (object, "x"); @@ -524,9 +523,9 @@ parse_point_from_object (JsonObject *object, } gboolean -_clutter_script_parse_point (ClutterScript *script, - JsonNode *node, - ClutterPoint *point) +_clutter_script_parse_point (ClutterScript *script, + JsonNode *node, + graphene_point_t *point) { g_return_val_if_fail (CLUTTER_IS_SCRIPT (script), FALSE); g_return_val_if_fail (node != NULL, FALSE); @@ -548,8 +547,8 @@ _clutter_script_parse_point (ClutterScript *script, } static gboolean -parse_size_from_array (JsonArray *array, - ClutterSize *size) +parse_size_from_array (JsonArray *array, + graphene_size_t *size) { if (json_array_get_length (array) != 2) return FALSE; @@ -561,8 +560,8 @@ parse_size_from_array (JsonArray *array, } static gboolean -parse_size_from_object (JsonObject *object, - ClutterSize *size) +parse_size_from_object (JsonObject *object, + graphene_size_t *size) { if (json_object_has_member (object, "width")) size->width = json_object_get_double_member (object, "width"); @@ -578,9 +577,9 @@ parse_size_from_object (JsonObject *object, } gboolean -_clutter_script_parse_size (ClutterScript *script, - JsonNode *node, - ClutterSize *size) +_clutter_script_parse_size (ClutterScript *script, + JsonNode *node, + graphene_size_t *size) { g_return_val_if_fail (CLUTTER_IS_SCRIPT (script), FALSE); g_return_val_if_fail (node != NULL, FALSE); @@ -1059,7 +1058,7 @@ clutter_script_parser_object_end (JsonParser *json_parser, json_object_get_string_member (object, "id"), json_object_get_string_member (object, "type")); - free (fake); + g_free (fake); } if (!json_object_has_member (object, "type")) @@ -1330,11 +1329,11 @@ _clutter_script_parse_node (ClutterScript *script, return TRUE; } } - else if (p_type == CLUTTER_TYPE_GEOMETRY) + else if (p_type == GRAPHENE_TYPE_RECT) { - ClutterGeometry geom = { 0, }; + graphene_rect_t rect = GRAPHENE_RECT_INIT_ZERO; - /* geometry := { + /* rect := { * "x" : (int), * "y" : (int), * "width" : (int), @@ -1342,9 +1341,9 @@ _clutter_script_parse_node (ClutterScript *script, * } */ - if (_clutter_script_parse_geometry (script, node, &geom)) + if (_clutter_script_parse_rect (script, node, &rect)) { - g_value_set_boxed (value, &geom); + g_value_set_boxed (value, &rect); return TRUE; } } @@ -1366,9 +1365,9 @@ _clutter_script_parse_node (ClutterScript *script, return TRUE; } } - else if (p_type == CLUTTER_TYPE_POINT) + else if (p_type == GRAPHENE_TYPE_POINT) { - ClutterPoint point = CLUTTER_POINT_INIT_ZERO; + graphene_point_t point = GRAPHENE_POINT_INIT_ZERO; if (_clutter_script_parse_point (script, node, &point)) { @@ -1376,9 +1375,9 @@ _clutter_script_parse_node (ClutterScript *script, return TRUE; } } - else if (p_type == CLUTTER_TYPE_SIZE) + else if (p_type == GRAPHENE_TYPE_SIZE) { - ClutterSize size = CLUTTER_SIZE_INIT_ZERO; + graphene_size_t size = GRAPHENE_SIZE_INIT_ZERO; if (_clutter_script_parse_size (script, node, &size)) { @@ -1419,15 +1418,15 @@ _clutter_script_parse_node (ClutterScript *script, return TRUE; } } - else if (G_VALUE_HOLDS (value, CLUTTER_TYPE_GEOMETRY)) + else if (G_VALUE_HOLDS (value, GRAPHENE_TYPE_RECT)) { - ClutterGeometry geom = { 0, }; + graphene_rect_t rect = GRAPHENE_RECT_INIT_ZERO; - /* geometry := [ (int), (int), (int), (int) ] */ + /* rect := [ (int), (int), (int), (int) ] */ - if (_clutter_script_parse_geometry (script, node, &geom)) + if (_clutter_script_parse_rect (script, node, &rect)) { - g_value_set_boxed (value, &geom); + g_value_set_boxed (value, &rect); return TRUE; } } @@ -1443,9 +1442,9 @@ _clutter_script_parse_node (ClutterScript *script, return TRUE; } } - else if (G_VALUE_HOLDS (value, CLUTTER_TYPE_POINT)) + else if (G_VALUE_HOLDS (value, GRAPHENE_TYPE_POINT)) { - ClutterPoint point = CLUTTER_POINT_INIT_ZERO; + graphene_point_t point = GRAPHENE_POINT_INIT_ZERO; if (_clutter_script_parse_point (script, node, &point)) { @@ -1453,9 +1452,9 @@ _clutter_script_parse_node (ClutterScript *script, return TRUE; } } - else if (G_VALUE_HOLDS (value, CLUTTER_TYPE_SIZE)) + else if (G_VALUE_HOLDS (value, GRAPHENE_TYPE_SIZE)) { - ClutterSize size = CLUTTER_SIZE_INIT_ZERO; + graphene_size_t size = GRAPHENE_SIZE_INIT_ZERO; if (_clutter_script_parse_size (script, node, &size)) { @@ -1638,14 +1637,17 @@ clutter_script_translate_parameters (ClutterScript *script, GObject *object, const gchar *name, GList *properties, - GArray **params) + GPtrArray **param_names, + GArray **param_values) { ClutterScriptable *scriptable = NULL; ClutterScriptableIface *iface = NULL; GList *l, *unparsed; gboolean parse_custom = FALSE; - *params = g_array_new (FALSE, FALSE, sizeof (GParameter)); + *param_names = g_ptr_array_new_with_free_func (g_free); + *param_values = g_array_new (FALSE, FALSE, sizeof (GValue)); + g_array_set_clear_func (*param_values, (GDestroyNotify) g_value_unset); if (CLUTTER_IS_SCRIPTABLE (object)) { @@ -1661,7 +1663,7 @@ clutter_script_translate_parameters (ClutterScript *script, for (l = properties; l != NULL; l = l->next) { PropertyInfo *pinfo = l->data; - GParameter param = { NULL }; + GValue value = G_VALUE_INIT; gboolean res = FALSE; if (pinfo->is_child || pinfo->is_layout) @@ -1678,12 +1680,12 @@ clutter_script_translate_parameters (ClutterScript *script, pinfo->name); if (parse_custom) - res = iface->parse_custom_node (scriptable, script, ¶m.value, + res = iface->parse_custom_node (scriptable, script, &value, pinfo->name, pinfo->node); if (!res) - res = _clutter_script_parse_node (script, ¶m.value, + res = _clutter_script_parse_node (script, &value, pinfo->name, pinfo->node, pinfo->pspec); @@ -1695,9 +1697,8 @@ clutter_script_translate_parameters (ClutterScript *script, continue; } - param.name = g_strdup (pinfo->name); - - g_array_append_val (*params, param); + g_ptr_array_add (*param_names, g_strdup (pinfo->name)); + g_array_append_val (*param_values, value); property_info_free (pinfo); } @@ -1712,7 +1713,8 @@ clutter_script_construct_parameters (ClutterScript *script, GType gtype, const gchar *name, GList *properties, - GArray **construct_params) + GPtrArray **construct_param_names, + GArray **construct_param_values) { GObjectClass *klass; GList *l, *unparsed; @@ -1720,14 +1722,17 @@ clutter_script_construct_parameters (ClutterScript *script, klass = g_type_class_ref (gtype); g_assert (klass != NULL); - *construct_params = g_array_new (FALSE, FALSE, sizeof (GParameter)); + *construct_param_names = g_ptr_array_new_with_free_func (g_free); + *construct_param_values = g_array_new (FALSE, FALSE, sizeof (GValue)); + g_array_set_clear_func (*construct_param_values, + (GDestroyNotify) g_value_unset); unparsed = NULL; for (l = properties; l != NULL; l = l->next) { PropertyInfo *pinfo = l->data; - GParameter param = { NULL }; + GValue value = G_VALUE_INIT; GParamSpec *pspec = NULL; /* we allow custom property names for classes, so if we @@ -1751,9 +1756,7 @@ clutter_script_construct_parameters (ClutterScript *script, continue; } - param.name = g_strdup (pinfo->name); - - if (!_clutter_script_parse_node (script, ¶m.value, + if (!_clutter_script_parse_node (script, &value, pinfo->name, pinfo->node, pinfo->pspec)) @@ -1762,7 +1765,8 @@ clutter_script_construct_parameters (ClutterScript *script, continue; } - g_array_append_val (*construct_params, param); + g_ptr_array_add (*construct_param_names, g_strdup (pinfo->name)); + g_array_append_val (*construct_param_values, value); property_info_free (pinfo); } @@ -1953,7 +1957,7 @@ apply_child_properties (ClutterScript *script, continue; } - + CLUTTER_NOTE (SCRIPT, "Setting %s child property '%s' (type:%s) to " "object '%s' (id:%s)", @@ -2023,8 +2027,7 @@ add_children (ClutterScript *script, clutter_container_add_actor (container, CLUTTER_ACTOR (object)); } - g_list_foreach (oinfo->children, (GFunc) free, NULL); - g_list_free (oinfo->children); + g_list_free_full (oinfo->children, g_free); oinfo->children = unresolved; } @@ -2090,7 +2093,8 @@ _clutter_script_apply_properties (ClutterScript *script, gboolean set_custom_property = FALSE; GObject *object = oinfo->object; GList *properties; - GArray *params; + g_autoptr (GPtrArray) param_names = NULL; + g_autoptr (GArray) param_values = NULL; guint i; if (!oinfo->has_unresolved) @@ -2114,34 +2118,31 @@ _clutter_script_apply_properties (ClutterScript *script, object, oinfo->id, properties, - ¶ms); + ¶m_names, + ¶m_values); /* consume all the properties we could translate in this pass */ - for (i = 0; i < params->len; i++) + for (i = 0; i < param_names->len; i++) { - GParameter *param = &g_array_index (params, GParameter, i); + char *name = g_ptr_array_index (param_names, i); + GValue *value = &g_array_index (param_values, GValue, i); CLUTTER_NOTE (SCRIPT, "Setting %s property '%s' (type:%s) to object '%s' (id:%s)", set_custom_property ? "custom" : "regular", - param->name, - g_type_name (G_VALUE_TYPE (¶m->value)), + name, + g_type_name (G_VALUE_TYPE (value)), g_type_name (oinfo->gtype), oinfo->id); if (set_custom_property) iface->set_custom_property (scriptable, script, - param->name, - ¶m->value); + name, + value); else - g_object_set_property (object, param->name, ¶m->value); - - free ((gchar *) param->name); - g_value_unset (¶m->value); + g_object_set_property (object, name, value); } - g_array_free (params, TRUE); - _clutter_script_check_unresolved (script, oinfo); } @@ -2149,8 +2150,8 @@ void _clutter_script_construct_object (ClutterScript *script, ObjectInfo *oinfo) { - GArray *params = NULL; - guint i; + g_autoptr (GPtrArray) param_names = NULL; + g_autoptr (GArray) param_values = NULL; /* we have completely updated the object */ if (oinfo->object != NULL) @@ -2193,25 +2194,15 @@ _clutter_script_construct_object (ClutterScript *script, oinfo->gtype, oinfo->id, properties, - ¶ms); + ¶m_names, + ¶m_values); default_stage = clutter_stage_manager_get_default_stage (manager); oinfo->object = G_OBJECT (default_stage); - - for (i = 0; i < params->len; i++) - { - GParameter *param = &g_array_index (params, GParameter, i); - - free ((gchar *) param->name); - g_value_unset (¶m->value); - } - - g_array_free (params, TRUE); } else { GList *properties = oinfo->properties; - GParameter *parameters; /* every other object: first, we get the construction parameters */ oinfo->properties = @@ -2219,28 +2210,19 @@ _clutter_script_construct_object (ClutterScript *script, oinfo->gtype, oinfo->id, properties, - ¶ms); + ¶m_names, + ¶m_values); - parameters = (GParameter *) (void *) params->data; - oinfo->object = g_object_newv (oinfo->gtype, - params->len, - parameters); + oinfo->object = g_object_new_with_properties (oinfo->gtype, + param_names->len, + (const gchar **) param_names->pdata, + (const GValue *) param_values->data); /* by sinking the floating reference, we make sure that the reference * count is correct whether the object is referenced from somewhere * else too or only by this ClutterScript object. */ g_object_ref_sink (oinfo->object); - - for (i = 0; i < params->len; i++) - { - GParameter *param = &g_array_index (params, GParameter, i); - - free ((gchar *) param->name); - g_value_unset (¶m->value); - } - - g_array_free (params, TRUE); } g_assert (oinfo->object != NULL); @@ -2250,7 +2232,7 @@ _clutter_script_construct_object (ClutterScript *script, else g_object_set_data_full (oinfo->object, "clutter-script-id", g_strdup (oinfo->id), - free); + g_free); _clutter_script_check_unresolved (script, oinfo); } diff --git a/clutter/clutter/clutter-script-private.h b/clutter/clutter/clutter-script-private.h index 52a67bcdc..9c08d82d6 100644 --- a/clutter/clutter/clutter-script-private.h +++ b/clutter/clutter/clutter-script-private.h @@ -122,20 +122,20 @@ gboolean _clutter_script_flags_from_string (GType gtype, gboolean _clutter_script_parse_knot (ClutterScript *script, JsonNode *node, ClutterKnot *knot); -gboolean _clutter_script_parse_geometry (ClutterScript *script, +gboolean _clutter_script_parse_rect (ClutterScript *script, JsonNode *node, - ClutterGeometry *geometry); + graphene_rect_t *rect); gboolean _clutter_script_parse_color (ClutterScript *script, JsonNode *node, ClutterColor *color); GObject *_clutter_script_parse_alpha (ClutterScript *script, JsonNode *node); -gboolean _clutter_script_parse_point (ClutterScript *script, - JsonNode *node, - ClutterPoint *point); +gboolean _clutter_script_parse_point (ClutterScript *script, + JsonNode *node, + graphene_point_t *point); gboolean _clutter_script_parse_size (ClutterScript *script, JsonNode *node, - ClutterSize *size); + graphene_size_t *size); gboolean _clutter_script_parse_translatable_string (ClutterScript *script, JsonNode *node, diff --git a/clutter/clutter/clutter-script.c b/clutter/clutter/clutter-script.c index 694353de0..c3221c8f2 100644 --- a/clutter/clutter/clutter-script.c +++ b/clutter/clutter/clutter-script.c @@ -75,65 +75,6 @@ * packing rules of Clutter still apply, and an actor cannot be packed * in multiple containers without unparenting it in between). * - * Behaviours and timelines can also be defined inside a UI definition - * buffer: - * - * - * - * And then to apply a defined behaviour to an actor defined inside the - * definition of an actor, the "behaviour" member can be used: - * - * - * - * A #ClutterAlpha belonging to a #ClutterBehaviour can only be defined - * implicitly like in the example above, or explicitly by setting the - * "alpha" property to point to a previously defined #ClutterAlpha, e.g.: - * - * - * - * Implicitely defined #ClutterAlphas and #ClutterTimelines - * can omit the `id`, as well as the `type` members, but will not be available - * using clutter_script_get_object() (they can, however, be extracted using the - * #ClutterBehaviour and #ClutterAlpha API respectively). - * * Signal handlers can be defined inside a Clutter UI definition file and * then autoconnected to their respective signals using the * clutter_script_connect_signals() function: @@ -210,7 +151,6 @@ * function * "type_func" := the GType function name, for non-standard classes * "children" := an array of names or objects to add as children - * "behaviours" := an array of names or objects to apply to an actor * "signals" := an array of signal definitions to connect to an object * "is-default" := a boolean flag used when defining the #ClutterStage; * if set to "true" the default stage will be used instead @@ -220,9 +160,7 @@ * #ClutterScript is available since Clutter 0.6 */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include #include @@ -237,7 +175,6 @@ #include "clutter-actor.h" #include "clutter-stage.h" -#include "clutter-texture.h" #include "clutter-script.h" #include "clutter-script-private.h" @@ -248,7 +185,6 @@ #include "clutter-debug.h" #include "deprecated/clutter-alpha.h" -#include "deprecated/clutter-behaviour.h" #include "deprecated/clutter-container.h" #include "deprecated/clutter-state.h" @@ -265,8 +201,6 @@ enum static GParamSpec *obj_props[PROP_LAST]; -#define CLUTTER_SCRIPT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_SCRIPT, ClutterScriptPrivate)) - struct _ClutterScriptPrivate { GHashTable *objects; @@ -314,7 +248,7 @@ property_info_free (gpointer data) if (pinfo->pspec) g_param_spec_unref (pinfo->pspec); - free (pinfo->name); + g_free (pinfo->name); g_slice_free (PropertyInfo, pinfo); } @@ -327,11 +261,11 @@ signal_info_free (gpointer data) { SignalInfo *sinfo = data; - free (sinfo->name); - free (sinfo->handler); - free (sinfo->object); - free (sinfo->state); - free (sinfo->target); + g_free (sinfo->name); + g_free (sinfo->handler); + g_free (sinfo->object); + g_free (sinfo->state); + g_free (sinfo->target); g_slice_free (SignalInfo, sinfo); } @@ -344,19 +278,16 @@ object_info_free (gpointer data) { ObjectInfo *oinfo = data; - free (oinfo->id); - free (oinfo->class_name); - free (oinfo->type_func); + g_free (oinfo->id); + g_free (oinfo->class_name); + g_free (oinfo->type_func); - g_list_foreach (oinfo->properties, (GFunc) property_info_free, NULL); - g_list_free (oinfo->properties); + g_list_free_full (oinfo->properties, property_info_free); - g_list_foreach (oinfo->signals, (GFunc) signal_info_free, NULL); - g_list_free (oinfo->signals); + g_list_free_full (oinfo->signals, signal_info_free); /* these are ids */ - g_list_foreach (oinfo->children, (GFunc) free, NULL); - g_list_free (oinfo->children); + g_list_free_full (oinfo->children, g_free); /* we unref top-level objects and leave the actors alone, * unless we are unmerging in which case we have to destroy @@ -382,14 +313,14 @@ object_info_free (gpointer data) static void clutter_script_finalize (GObject *gobject) { - ClutterScriptPrivate *priv = CLUTTER_SCRIPT_GET_PRIVATE (gobject); + ClutterScriptPrivate *priv = CLUTTER_SCRIPT (gobject)->priv; g_object_unref (priv->parser); g_hash_table_destroy (priv->objects); g_strfreev (priv->search_paths); - free (priv->filename); + g_free (priv->filename); g_hash_table_destroy (priv->states); - free (priv->translation_domain); + g_free (priv->translation_domain); G_OBJECT_CLASS (clutter_script_parent_class)->finalize (gobject); } @@ -524,18 +455,17 @@ clutter_script_init (ClutterScript *script) NULL, object_info_free); priv->states = g_hash_table_new_full (g_str_hash, g_str_equal, - free, + g_free, (GDestroyNotify) g_object_unref); } /** * clutter_script_new: * - * Creates a new #ClutterScript instance. #ClutterScript can be used - * to load objects definitions for scenegraph elements, like actors, - * or behavioural elements, like behaviours and timelines. The - * definitions must be encoded using the JavaScript Object Notation (JSON) - * language. + * Creates a new #ClutterScript instance. #ClutterScript can be used to load + * objects definitions for scenegraph elements, like actors, or behavioural + * elements, like timelines. The definitions must be encoded using the + * JavaScript Object Notation (JSON) language. * * Return value: the newly created #ClutterScript instance. Use * g_object_unref() when done. @@ -576,7 +506,7 @@ clutter_script_load_from_file (ClutterScript *script, priv = script->priv; - free (priv->filename); + g_free (priv->filename); priv->filename = g_strdup (filename); priv->is_filename = TRUE; priv->last_merge_id += 1; @@ -629,7 +559,7 @@ clutter_script_load_from_data (ClutterScript *script, priv = script->priv; - free (priv->filename); + g_free (priv->filename); priv->filename = NULL; priv->is_filename = FALSE; priv->last_merge_id += 1; @@ -731,7 +661,7 @@ clutter_script_get_objects_valist (ClutterScript *script, while (name) { GObject **obj = NULL; - + obj = va_arg (args, GObject**); *obj = clutter_script_get_object (script, name); @@ -848,8 +778,7 @@ clutter_script_unmerge_objects (ClutterScript *script, for (l = data.ids; l != NULL; l = l->next) g_hash_table_remove (priv->objects, l->data); - g_slist_foreach (data.ids, (GFunc) free, NULL); - g_slist_free (data.ids); + g_slist_free_full (data.ids, g_free); clutter_script_ensure_objects (script); } @@ -871,9 +800,7 @@ construct_each_objects (gpointer key, if (oinfo->object == NULL) _clutter_script_construct_object (script, oinfo); - /* this will take care of setting up properties, - * adding children and applying behaviours - */ + /* this will take care of setting up properties and adding children */ _clutter_script_apply_properties (script, oinfo); } } @@ -903,7 +830,7 @@ clutter_script_ensure_objects (ClutterScript *script) * @script: a #ClutterScript * @type_name: name of the type to look up * - * Looks up a type by name, using the virtual function that + * Looks up a type by name, using the virtual function that * #ClutterScript has for that purpose. This function should * rarely be used. * @@ -1011,7 +938,7 @@ clutter_script_default_connect (ClutterScript *script, * This method invokes clutter_script_connect_signals_full() internally * and uses #GModule's introspective features (by opening the current * module's scope) to look at the application's symbol table. - * + * * Note that this function will not work if #GModule is not supported by * the platform Clutter is running on. * @@ -1042,7 +969,7 @@ clutter_script_connect_signals (ClutterScript *script, g_module_close (cd->module); - free (cd); + g_free (cd); } typedef struct { @@ -1067,7 +994,7 @@ hook_data_free (gpointer data) { HookData *hook_data = data; - free (hook_data->target); + g_free (hook_data->target); g_slice_free (HookData, hook_data); } } @@ -1358,7 +1285,7 @@ clutter_script_lookup_filename (ClutterScript *script, return retval; else { - free (retval); + g_free (retval); retval = NULL; } } @@ -1369,15 +1296,15 @@ clutter_script_lookup_filename (ClutterScript *script, dirname = g_path_get_dirname (script->priv->filename); else dirname = g_get_current_dir (); - + retval = g_build_filename (dirname, filename, NULL); if (!g_file_test (retval, G_FILE_TEST_EXISTS)) { - free (retval); + g_free (retval); retval = NULL; } - - free (dirname); + + g_free (dirname); return retval; } @@ -1509,7 +1436,7 @@ clutter_script_set_translation_domain (ClutterScript *script, if (g_strcmp0 (domain, script->priv->translation_domain) == 0) return; - free (script->priv->translation_domain); + g_free (script->priv->translation_domain); script->priv->translation_domain = g_strdup (domain); g_object_notify_by_pspec (G_OBJECT (script), obj_props[PROP_TRANSLATION_DOMAIN]); @@ -1543,7 +1470,7 @@ clutter_script_get_translation_domain (ClutterScript *script) * an "id" member * * Return value: a newly-allocated string containing the fake - * id. Use free() to free the resources allocated by the + * id. Use g_free() to free the resources allocated by the * returned value * */ diff --git a/clutter/clutter/clutter-script.h b/clutter/clutter/clutter-script.h index 37f4a0537..a2ad3721b 100644 --- a/clutter/clutter/clutter-script.h +++ b/clutter/clutter/clutter-script.h @@ -79,7 +79,8 @@ typedef void (* ClutterScriptConnectFunc) (ClutterScript *script, * * Since: 0.6 */ -typedef enum { +typedef enum +{ CLUTTER_SCRIPT_ERROR_INVALID_TYPE_FUNCTION, CLUTTER_SCRIPT_ERROR_INVALID_PROPERTY, CLUTTER_SCRIPT_ERROR_INVALID_VALUE @@ -93,7 +94,7 @@ typedef enum { * Since: 0.6 */ #define CLUTTER_SCRIPT_ERROR (clutter_script_error_quark ()) -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT GQuark clutter_script_error_quark (void); /** @@ -144,75 +145,75 @@ struct _ClutterScriptClass void (*_clutter_reserved8) (void); }; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT GType clutter_script_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterScript * clutter_script_new (void); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT guint clutter_script_load_from_file (ClutterScript *script, const gchar *filename, GError **error); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT guint clutter_script_load_from_data (ClutterScript *script, const gchar *data, gssize length, GError **error); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT guint clutter_script_load_from_resource (ClutterScript *script, const gchar *resource_path, GError **error); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT GObject * clutter_script_get_object (ClutterScript *script, const gchar *name); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gint clutter_script_get_objects (ClutterScript *script, const gchar *first_name, ...) G_GNUC_NULL_TERMINATED; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT GList * clutter_script_list_objects (ClutterScript *script); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_script_unmerge_objects (ClutterScript *script, guint merge_id); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_script_ensure_objects (ClutterScript *script); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED void clutter_script_add_states (ClutterScript *script, const gchar *name, ClutterState *state); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED ClutterState * clutter_script_get_states (ClutterScript *script, const gchar *name); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_script_connect_signals (ClutterScript *script, gpointer user_data); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_script_connect_signals_full (ClutterScript *script, ClutterScriptConnectFunc func, gpointer user_data); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_script_add_search_paths (ClutterScript *script, const gchar * const paths[], gsize n_paths); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gchar * clutter_script_lookup_filename (ClutterScript *script, const gchar *filename) G_GNUC_MALLOC; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT GType clutter_script_get_type_from_name (ClutterScript *script, const gchar *type_name); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_script_set_translation_domain (ClutterScript *script, const gchar *domain); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT const gchar * clutter_script_get_translation_domain (ClutterScript *script); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT const gchar * clutter_get_script_id (GObject *gobject); G_END_DECLS diff --git a/clutter/clutter/clutter-scriptable.c b/clutter/clutter/clutter-scriptable.c index 76dcfe856..25b983c16 100644 --- a/clutter/clutter/clutter-scriptable.c +++ b/clutter/clutter/clutter-scriptable.c @@ -36,9 +36,7 @@ * #ClutterScriptable is available since Clutter 0.6 */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include #include @@ -90,7 +88,7 @@ clutter_scriptable_set_id (ClutterScriptable *scriptable, g_object_set_data_full (G_OBJECT (scriptable), "clutter-script-id", g_strdup (id_), - free); + g_free); } /** diff --git a/clutter/clutter/clutter-scriptable.h b/clutter/clutter/clutter-scriptable.h index 61beb2935..82d187b36 100644 --- a/clutter/clutter/clutter-scriptable.h +++ b/clutter/clutter/clutter-scriptable.h @@ -87,21 +87,21 @@ struct _ClutterScriptableIface const GValue *value); }; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT GType clutter_scriptable_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_scriptable_set_id (ClutterScriptable *scriptable, const gchar *id_); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT const gchar * clutter_scriptable_get_id (ClutterScriptable *scriptable); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gboolean clutter_scriptable_parse_custom_node (ClutterScriptable *scriptable, ClutterScript *script, GValue *value, const gchar *name, JsonNode *node); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_scriptable_set_custom_property (ClutterScriptable *scriptable, ClutterScript *script, const gchar *name, diff --git a/clutter/clutter/clutter-scroll-actor.c b/clutter/clutter/clutter-scroll-actor.c index 941f64305..969ba5370 100644 --- a/clutter/clutter/clutter-scroll-actor.c +++ b/clutter/clutter/clutter-scroll-actor.c @@ -42,9 +42,7 @@ * #ClutterScrollActor is available since Clutter 1.12. */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include "clutter-scroll-actor.h" @@ -58,7 +56,7 @@ struct _ClutterScrollActorPrivate { - ClutterPoint scroll_to; + graphene_point_t scroll_to; ClutterScrollMode scroll_mode; @@ -86,9 +84,9 @@ enum static GParamSpec *obj_props[PROP_LAST] = { NULL, }; static GParamSpec *animatable_props[ANIM_PROP_LAST] = { NULL, }; -static ClutterAnimatableIface *parent_animatable_iface = NULL; +static ClutterAnimatableInterface *parent_animatable_iface = NULL; -static void clutter_animatable_iface_init (ClutterAnimatableIface *iface); +static void clutter_animatable_iface_init (ClutterAnimatableInterface *iface); G_DEFINE_TYPE_WITH_CODE (ClutterScrollActor, clutter_scroll_actor, CLUTTER_TYPE_ACTOR, G_ADD_PRIVATE (ClutterScrollActor) @@ -96,19 +94,19 @@ G_DEFINE_TYPE_WITH_CODE (ClutterScrollActor, clutter_scroll_actor, CLUTTER_TYPE_ clutter_animatable_iface_init)) static void -clutter_scroll_actor_set_scroll_to_internal (ClutterScrollActor *self, - const ClutterPoint *point) +clutter_scroll_actor_set_scroll_to_internal (ClutterScrollActor *self, + const graphene_point_t *point) { ClutterScrollActorPrivate *priv = self->priv; ClutterActor *actor = CLUTTER_ACTOR (self); ClutterMatrix m = CLUTTER_MATRIX_INIT_IDENTITY; float dx, dy; - if (clutter_point_equals (&priv->scroll_to, point)) + if (graphene_point_equal (&priv->scroll_to, point)) return; if (point == NULL) - clutter_point_init (&priv->scroll_to, 0.f, 0.f); + graphene_point_init (&priv->scroll_to, 0.f, 0.f); else priv->scroll_to = *point; @@ -218,7 +216,7 @@ clutter_scroll_actor_set_final_state (ClutterAnimatable *animatable, if (strcmp (property_name, "scroll-to") == 0) { ClutterScrollActor *self = CLUTTER_SCROLL_ACTOR (animatable); - const ClutterPoint *point = g_value_get_boxed (value); + const graphene_point_t *point = g_value_get_boxed (value); clutter_scroll_actor_set_scroll_to_internal (self, point); } @@ -242,7 +240,7 @@ clutter_scroll_actor_get_initial_state (ClutterAnimatable *animatable, } static void -clutter_animatable_iface_init (ClutterAnimatableIface *iface) +clutter_animatable_iface_init (ClutterAnimatableInterface *iface) { parent_animatable_iface = g_type_interface_peek_parent (iface); @@ -250,7 +248,7 @@ clutter_animatable_iface_init (ClutterAnimatableIface *iface) g_param_spec_boxed ("scroll-to", "Scroll To", "The point to scroll the actor to", - CLUTTER_TYPE_POINT, + GRAPHENE_TYPE_POINT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | CLUTTER_PARAM_ANIMATABLE); @@ -324,7 +322,7 @@ clutter_scroll_actor_get_scroll_mode (ClutterScrollActor *actor) /** * clutter_scroll_actor_scroll_to_point: * @actor: a #ClutterScrollActor - * @point: a #ClutterPoint + * @point: a #graphene_point_t * * Scrolls the contents of @actor so that @point is the new origin * of the visible area. @@ -337,8 +335,8 @@ clutter_scroll_actor_get_scroll_mode (ClutterScrollActor *actor) * Since: 1.12 */ void -clutter_scroll_actor_scroll_to_point (ClutterScrollActor *actor, - const ClutterPoint *point) +clutter_scroll_actor_scroll_to_point (ClutterScrollActor *actor, + const graphene_point_t *point) { ClutterScrollActorPrivate *priv; const ClutterAnimationInfo *info; @@ -392,10 +390,10 @@ clutter_scroll_actor_scroll_to_point (ClutterScrollActor *actor, /* if a transition already exist, update its bounds */ clutter_transition_set_from (priv->transition, - CLUTTER_TYPE_POINT, + GRAPHENE_TYPE_POINT, &priv->scroll_to); clutter_transition_set_to (priv->transition, - CLUTTER_TYPE_POINT, + GRAPHENE_TYPE_POINT, point); /* always use the current easing state */ @@ -419,10 +417,10 @@ clutter_scroll_actor_scroll_to_point (ClutterScrollActor *actor, * Since: 1.12 */ void -clutter_scroll_actor_scroll_to_rect (ClutterScrollActor *actor, - const ClutterRect *rect) +clutter_scroll_actor_scroll_to_rect (ClutterScrollActor *actor, + const graphene_rect_t *rect) { - ClutterRect n_rect; + graphene_rect_t n_rect; g_return_if_fail (CLUTTER_IS_SCROLL_ACTOR (actor)); g_return_if_fail (rect != NULL); @@ -430,7 +428,7 @@ clutter_scroll_actor_scroll_to_rect (ClutterScrollActor *actor, n_rect = *rect; /* normalize, so that we have a valid origin */ - clutter_rect_normalize (&n_rect); + graphene_rect_normalize (&n_rect); clutter_scroll_actor_scroll_to_point (actor, &n_rect.origin); } diff --git a/clutter/clutter/clutter-scroll-actor.h b/clutter/clutter/clutter-scroll-actor.h index be3cbc27b..e6a176521 100644 --- a/clutter/clutter/clutter-scroll-actor.h +++ b/clutter/clutter/clutter-scroll-actor.h @@ -73,24 +73,24 @@ struct _ClutterScrollActorClass gpointer _padding[8]; }; -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT GType clutter_scroll_actor_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT ClutterActor * clutter_scroll_actor_new (void); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_scroll_actor_set_scroll_mode (ClutterScrollActor *actor, ClutterScrollMode mode); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT ClutterScrollMode clutter_scroll_actor_get_scroll_mode (ClutterScrollActor *actor); -CLUTTER_AVAILABLE_IN_1_12 -void clutter_scroll_actor_scroll_to_point (ClutterScrollActor *actor, - const ClutterPoint *point); -CLUTTER_AVAILABLE_IN_1_12 -void clutter_scroll_actor_scroll_to_rect (ClutterScrollActor *actor, - const ClutterRect *rect); +CLUTTER_EXPORT +void clutter_scroll_actor_scroll_to_point (ClutterScrollActor *actor, + const graphene_point_t *point); +CLUTTER_EXPORT +void clutter_scroll_actor_scroll_to_rect (ClutterScrollActor *actor, + const graphene_rect_t *rect); G_END_DECLS diff --git a/clutter/clutter/clutter-seat.c b/clutter/clutter/clutter-seat.c new file mode 100644 index 000000000..fca0722a7 --- /dev/null +++ b/clutter/clutter/clutter-seat.c @@ -0,0 +1,740 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Copyright (C) 2019 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Author: Carlos Garnacho + */ + +#include "clutter-build-config.h" + +#include "clutter-backend-private.h" +#include "clutter-input-device-tool.h" +#include "clutter-input-pointer-a11y-private.h" +#include "clutter-marshal.h" +#include "clutter-private.h" +#include "clutter-seat.h" +#include "clutter-virtual-input-device.h" + +enum +{ + DEVICE_ADDED, + DEVICE_REMOVED, + TOOL_CHANGED, + KBD_A11Y_MASK_CHANGED, + KBD_A11Y_FLAGS_CHANGED, + PTR_A11Y_DWELL_CLICK_TYPE_CHANGED, + PTR_A11Y_TIMEOUT_STARTED, + PTR_A11Y_TIMEOUT_STOPPED, + IS_UNFOCUS_INHIBITED_CHANGED, + N_SIGNALS, +}; + +static guint signals[N_SIGNALS] = { 0 }; + +enum +{ + PROP_0, + PROP_BACKEND, + PROP_TOUCH_MODE, + N_PROPS +}; + +static GParamSpec *props[N_PROPS]; + +typedef struct _ClutterSeatPrivate ClutterSeatPrivate; + +struct _ClutterSeatPrivate +{ + ClutterBackend *backend; + + unsigned int inhibit_unfocus_count; + + /* Keyboard a11y */ + ClutterKbdA11ySettings kbd_a11y_settings; + + /* Pointer a11y */ + ClutterPointerA11ySettings pointer_a11y_settings; +}; + +G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterSeat, clutter_seat, G_TYPE_OBJECT) + +static void +clutter_seat_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + ClutterSeat *seat = CLUTTER_SEAT (object); + ClutterSeatPrivate *priv = clutter_seat_get_instance_private (seat); + + switch (prop_id) + { + case PROP_BACKEND: + priv->backend = g_value_get_object (value); + break; + case PROP_TOUCH_MODE: + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +clutter_seat_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + ClutterSeat *seat = CLUTTER_SEAT (object); + ClutterSeatPrivate *priv = clutter_seat_get_instance_private (seat); + + switch (prop_id) + { + case PROP_BACKEND: + g_value_set_object (value, priv->backend); + break; + case PROP_TOUCH_MODE: + g_value_set_boolean (value, FALSE); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +clutter_seat_finalize (GObject *object) +{ + ClutterSeat *seat = CLUTTER_SEAT (object); + ClutterSeatPrivate *priv = clutter_seat_get_instance_private (seat); + + g_clear_object (&priv->backend); + + G_OBJECT_CLASS (clutter_seat_parent_class)->finalize (object); +} + +static void +clutter_seat_class_init (ClutterSeatClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->set_property = clutter_seat_set_property; + object_class->get_property = clutter_seat_get_property; + object_class->finalize = clutter_seat_finalize; + + signals[DEVICE_ADDED] = + g_signal_new (I_("device-added"), + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 1, + CLUTTER_TYPE_INPUT_DEVICE); + + signals[DEVICE_REMOVED] = + g_signal_new (I_("device-removed"), + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 1, + CLUTTER_TYPE_INPUT_DEVICE); + signals[TOOL_CHANGED] = + g_signal_new (I_("tool-changed"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, + _clutter_marshal_VOID__OBJECT_OBJECT, + G_TYPE_NONE, 2, + CLUTTER_TYPE_INPUT_DEVICE, + CLUTTER_TYPE_INPUT_DEVICE_TOOL); + g_signal_set_va_marshaller (signals[TOOL_CHANGED], + G_TYPE_FROM_CLASS (object_class), + _clutter_marshal_VOID__OBJECT_OBJECTv); + + /** + * ClutterSeat::kbd-a11y-mods-state-changed: + * @seat: the #ClutterSeat that emitted the signal + * @latched_mask: the latched modifier mask from stickykeys + * @locked_mask: the locked modifier mask from stickykeys + * + * The ::kbd-a11y-mods-state-changed signal is emitted each time either the + * latched modifiers mask or locked modifiers mask are changed as the + * result of keyboard accessibilty's sticky keys operations. + */ + signals[KBD_A11Y_MASK_CHANGED] = + g_signal_new (I_("kbd-a11y-mods-state-changed"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, + _clutter_marshal_VOID__UINT_UINT, + G_TYPE_NONE, 2, + G_TYPE_UINT, + G_TYPE_UINT); + g_signal_set_va_marshaller (signals[KBD_A11Y_MASK_CHANGED], + G_TYPE_FROM_CLASS (object_class), + _clutter_marshal_VOID__UINT_UINTv); + + /** + * ClutterSeat::kbd-a11y-flags-changed: + * @seat: the #ClutterSeat that emitted the signal + * @settings_flags: the new ClutterKeyboardA11yFlags configuration + * @changed_mask: the ClutterKeyboardA11yFlags changed + * + * The ::kbd-a11y-flags-changed signal is emitted each time the + * ClutterKeyboardA11yFlags configuration is changed as the result of + * keyboard accessibility operations. + */ + signals[KBD_A11Y_FLAGS_CHANGED] = + g_signal_new (I_("kbd-a11y-flags-changed"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, + _clutter_marshal_VOID__UINT_UINT, + G_TYPE_NONE, 2, + G_TYPE_UINT, + G_TYPE_UINT); + g_signal_set_va_marshaller (signals[KBD_A11Y_FLAGS_CHANGED], + G_TYPE_FROM_CLASS (object_class), + _clutter_marshal_VOID__UINT_UINTv); + + /** + * ClutterSeat::ptr-a11y-dwell-click-type-changed: + * @seat: the #ClutterSeat that emitted the signal + * @click_type: the new #ClutterPointerA11yDwellClickType mode + * + * The ::ptr-a11y-dwell-click-type-changed signal is emitted each time + * the ClutterPointerA11yDwellClickType mode is changed as the result + * of pointer accessibility operations. + */ + signals[PTR_A11Y_DWELL_CLICK_TYPE_CHANGED] = + g_signal_new (I_("ptr-a11y-dwell-click-type-changed"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 1, + CLUTTER_TYPE_POINTER_A11Y_DWELL_CLICK_TYPE); + + /** + * ClutterSeat::ptr-a11y-timeout-started: + * @seat: the #ClutterSeat that emitted the signal + * @device: the core pointer #ClutterInputDevice + * @timeout_type: the type of timeout #ClutterPointerA11yTimeoutType + * @delay: the delay in ms before secondary-click is triggered. + * + * The ::ptr-a11y-timeout-started signal is emitted when a + * pointer accessibility timeout delay is started, so that upper + * layers can notify the user with some visual feedback. + */ + signals[PTR_A11Y_TIMEOUT_STARTED] = + g_signal_new (I_("ptr-a11y-timeout-started"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, + _clutter_marshal_VOID__OBJECT_FLAGS_UINT, + G_TYPE_NONE, 3, + CLUTTER_TYPE_INPUT_DEVICE, + CLUTTER_TYPE_POINTER_A11Y_TIMEOUT_TYPE, + G_TYPE_UINT); + g_signal_set_va_marshaller (signals[PTR_A11Y_TIMEOUT_STARTED], + G_TYPE_FROM_CLASS (object_class), + _clutter_marshal_VOID__OBJECT_FLAGS_UINTv); + + /** + * ClutterSeat::ptr-a11y-timeout-stopped: + * @seat: the #ClutterSeat that emitted the signal + * @device: the core pointer #ClutterInputDevice + * @timeout_type: the type of timeout #ClutterPointerA11yTimeoutType + * @clicked: %TRUE if the timeout finished and triggered a click + * + * The ::ptr-a11y-timeout-stopped signal is emitted when a running + * pointer accessibility timeout delay is stopped, either because + * it's triggered at the end of the delay or cancelled, so that + * upper layers can notify the user with some visual feedback. + */ + signals[PTR_A11Y_TIMEOUT_STOPPED] = + g_signal_new (I_("ptr-a11y-timeout-stopped"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, + _clutter_marshal_VOID__OBJECT_FLAGS_BOOLEAN, + G_TYPE_NONE, 3, + CLUTTER_TYPE_INPUT_DEVICE, + CLUTTER_TYPE_POINTER_A11Y_TIMEOUT_TYPE, + G_TYPE_BOOLEAN); + g_signal_set_va_marshaller (signals[PTR_A11Y_TIMEOUT_STOPPED], + G_TYPE_FROM_CLASS (object_class), + _clutter_marshal_VOID__OBJECT_FLAGS_BOOLEANv); + + /** + * ClutterSeat::is-unfocus-inhibited-changed: + * @seat: the #ClutterSeat that emitted the signal + * + * The ::is-unfocus-inhibited-changed signal is emitted when the + * property to inhibit the unsetting of the focus-surface of the + * #ClutterSeat changed. To get the current state of this property, + * use clutter_seat_is_unfocus_inhibited(). + */ + signals[IS_UNFOCUS_INHIBITED_CHANGED] = + g_signal_new (I_("is-unfocus-inhibited-changed"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 0); + + props[PROP_BACKEND] = + g_param_spec_object ("backend", + P_("Backend"), + P_("Backend"), + CLUTTER_TYPE_BACKEND, + CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + + /** + * ClutterSeat:touch-mode: + * + * The current touch-mode of the #ClutterSeat, it is set to %TRUE if the + * requirements documented in clutter_seat_get_touch_mode() are fulfilled. + **/ + props[PROP_TOUCH_MODE] = + g_param_spec_boolean ("touch-mode", + P_("Touch mode"), + P_("Touch mode"), + FALSE, + CLUTTER_PARAM_READABLE); + + g_object_class_install_properties (object_class, N_PROPS, props); +} + +static void +clutter_seat_init (ClutterSeat *seat) +{ +} + +/** + * clutter_seat_get_pointer: + * @seat: a #ClutterSeat + * + * Returns the master pointer + * + * Returns: (transfer none): the master pointer + **/ +ClutterInputDevice * +clutter_seat_get_pointer (ClutterSeat *seat) +{ + g_return_val_if_fail (CLUTTER_IS_SEAT (seat), NULL); + + return CLUTTER_SEAT_GET_CLASS (seat)->get_pointer (seat); +} + +/** + * clutter_seat_get_keyboard: + * @seat: a #ClutterSeat + * + * Returns the master keyboard + * + * Returns: (transfer none): the master keyboard + **/ +ClutterInputDevice * +clutter_seat_get_keyboard (ClutterSeat *seat) +{ + g_return_val_if_fail (CLUTTER_IS_SEAT (seat), NULL); + + return CLUTTER_SEAT_GET_CLASS (seat)->get_keyboard (seat); +} + +/** + * clutter_seat_list_devices: + * @seat: a #ClutterSeat + * + * Returns the list of HW devices + * + * Returns: (transfer container) (element-type Clutter.InputDevice): A list + * of #ClutterInputDevice. The elements of the returned list are owned by + * Clutter and may not be freed, the returned list should be freed using + * g_list_free() when done. + **/ +GList * +clutter_seat_list_devices (ClutterSeat *seat) +{ + g_return_val_if_fail (CLUTTER_IS_SEAT (seat), NULL); + + return CLUTTER_SEAT_GET_CLASS (seat)->list_devices (seat); +} + +void +clutter_seat_bell_notify (ClutterSeat *seat) +{ + CLUTTER_SEAT_GET_CLASS (seat)->bell_notify (seat); +} + +/** + * clutter_seat_get_keymap: + * @seat: a #ClutterSeat + * + * Returns the seat keymap + * + * Returns: (transfer none): the seat keymap + **/ +ClutterKeymap * +clutter_seat_get_keymap (ClutterSeat *seat) +{ + return CLUTTER_SEAT_GET_CLASS (seat)->get_keymap (seat); +} + +static gboolean +are_kbd_a11y_settings_equal (ClutterKbdA11ySettings *a, + ClutterKbdA11ySettings *b) +{ + return (memcmp (a, b, sizeof (ClutterKbdA11ySettings)) == 0); +} + +void +clutter_seat_set_kbd_a11y_settings (ClutterSeat *seat, + ClutterKbdA11ySettings *settings) +{ + ClutterSeatClass *seat_class; + ClutterSeatPrivate *priv = clutter_seat_get_instance_private (seat); + + g_return_if_fail (CLUTTER_IS_SEAT (seat)); + + if (are_kbd_a11y_settings_equal (&priv->kbd_a11y_settings, settings)) + return; + + priv->kbd_a11y_settings = *settings; + + seat_class = CLUTTER_SEAT_GET_CLASS (seat); + if (seat_class->apply_kbd_a11y_settings) + seat_class->apply_kbd_a11y_settings (seat, settings); +} + +void +clutter_seat_get_kbd_a11y_settings (ClutterSeat *seat, + ClutterKbdA11ySettings *settings) +{ + ClutterSeatPrivate *priv = clutter_seat_get_instance_private (seat); + + g_return_if_fail (CLUTTER_IS_SEAT (seat)); + + *settings = priv->kbd_a11y_settings; +} + +void +clutter_seat_ensure_a11y_state (ClutterSeat *seat) +{ + ClutterInputDevice *core_pointer; + + core_pointer = clutter_seat_get_pointer (seat); + + if (core_pointer) + { + if (_clutter_is_input_pointer_a11y_enabled (core_pointer)) + _clutter_input_pointer_a11y_add_device (core_pointer); + } +} + +static gboolean +are_pointer_a11y_settings_equal (ClutterPointerA11ySettings *a, + ClutterPointerA11ySettings *b) +{ + return (memcmp (a, b, sizeof (ClutterPointerA11ySettings)) == 0); +} + +static void +clutter_seat_enable_pointer_a11y (ClutterSeat *seat) +{ + ClutterInputDevice *core_pointer; + + core_pointer = clutter_seat_get_pointer (seat); + + _clutter_input_pointer_a11y_add_device (core_pointer); +} + +static void +clutter_seat_disable_pointer_a11y (ClutterSeat *seat) +{ + ClutterInputDevice *core_pointer; + + core_pointer = clutter_seat_get_pointer (seat); + + _clutter_input_pointer_a11y_remove_device (core_pointer); +} + +/** + * clutter_seat_set_pointer_a11y_settings: + * @seat: a #ClutterSeat + * @settings: a pointer to a #ClutterPointerA11ySettings + * + * Sets the pointer accessibility settings + **/ +void +clutter_seat_set_pointer_a11y_settings (ClutterSeat *seat, + ClutterPointerA11ySettings *settings) +{ + ClutterSeatPrivate *priv = clutter_seat_get_instance_private (seat); + + g_return_if_fail (CLUTTER_IS_SEAT (seat)); + + if (are_pointer_a11y_settings_equal (&priv->pointer_a11y_settings, settings)) + return; + + if (priv->pointer_a11y_settings.controls == 0 && settings->controls != 0) + clutter_seat_enable_pointer_a11y (seat); + else if (priv->pointer_a11y_settings.controls != 0 && settings->controls == 0) + clutter_seat_disable_pointer_a11y (seat); + + priv->pointer_a11y_settings = *settings; +} + +/** + * clutter_seat_get_pointer_a11y_settings: + * @seat: a #ClutterSeat + * @settings: a pointer to a #ClutterPointerA11ySettings + * + * Gets the current pointer accessibility settings + **/ +void +clutter_seat_get_pointer_a11y_settings (ClutterSeat *seat, + ClutterPointerA11ySettings *settings) +{ + ClutterSeatPrivate *priv = clutter_seat_get_instance_private (seat); + + g_return_if_fail (CLUTTER_IS_SEAT (seat)); + + *settings = priv->pointer_a11y_settings; +} + +/** + * clutter_seat_set_pointer_a11y_dwell_click_type: + * @seat: a #ClutterSeat + * @click_type: type of click as #ClutterPointerA11yDwellClickType + * + * Sets the dwell click type + **/ +void +clutter_seat_set_pointer_a11y_dwell_click_type (ClutterSeat *seat, + ClutterPointerA11yDwellClickType click_type) +{ + ClutterSeatPrivate *priv = clutter_seat_get_instance_private (seat); + + g_return_if_fail (CLUTTER_IS_SEAT (seat)); + + priv->pointer_a11y_settings.dwell_click_type = click_type; +} + +/** + * clutter_seat_inhibit_unfocus: + * @seat: a #ClutterSeat + * + * Inhibits unsetting of the pointer focus-surface for the #ClutterSeat @seat, + * this allows to keep using the pointer even when it's hidden. + * + * This property is refcounted, so clutter_seat_uninhibit_unfocus() must be + * called the exact same number of times as clutter_seat_inhibit_unfocus() + * was called before. + **/ +void +clutter_seat_inhibit_unfocus (ClutterSeat *seat) +{ + ClutterSeatPrivate *priv; + + g_return_if_fail (CLUTTER_IS_SEAT (seat)); + + priv = clutter_seat_get_instance_private (seat); + + priv->inhibit_unfocus_count++; + + if (priv->inhibit_unfocus_count == 1) + g_signal_emit (G_OBJECT (seat), signals[IS_UNFOCUS_INHIBITED_CHANGED], 0); +} + +/** + * clutter_seat_uninhibit_unfocus: + * @seat: a #ClutterSeat + * + * Disables the inhibiting of unsetting of the pointer focus-surface + * previously enabled by calling clutter_seat_inhibit_unfocus(). + * + * This property is refcounted, so clutter_seat_uninhibit_unfocus() must be + * called the exact same number of times as clutter_seat_inhibit_unfocus() + * was called before. + **/ +void +clutter_seat_uninhibit_unfocus (ClutterSeat *seat) +{ + ClutterSeatPrivate *priv; + + g_return_if_fail (CLUTTER_IS_SEAT (seat)); + + priv = clutter_seat_get_instance_private (seat); + + if (priv->inhibit_unfocus_count == 0) + { + g_warning ("Called clutter_seat_uninhibit_unfocus without inhibiting before"); + return; + } + + priv->inhibit_unfocus_count--; + + if (priv->inhibit_unfocus_count == 0) + g_signal_emit (G_OBJECT (seat), signals[IS_UNFOCUS_INHIBITED_CHANGED], 0); +} + +/** + * clutter_seat_is_unfocus_inhibited: + * @seat: a #ClutterSeat + * + * Gets whether unsetting of the pointer focus-surface is inhibited + * for the #ClutterSeat @seat. + * + * Returns: %TRUE if unsetting is inhibited, %FALSE otherwise + **/ +gboolean +clutter_seat_is_unfocus_inhibited (ClutterSeat *seat) +{ + ClutterSeatPrivate *priv; + + g_return_val_if_fail (CLUTTER_IS_SEAT (seat), FALSE); + + priv = clutter_seat_get_instance_private (seat); + + return priv->inhibit_unfocus_count > 0; +} + +/** + * clutter_seat_create_virtual_device: + * @seat: a #ClutterSeat + * @device_type: the type of the virtual device + * + * Creates a virtual input device. + * + * Returns: (transfer full): a newly created virtual device + **/ +ClutterVirtualInputDevice * +clutter_seat_create_virtual_device (ClutterSeat *seat, + ClutterInputDeviceType device_type) +{ + ClutterSeatClass *seat_class; + + g_return_val_if_fail (CLUTTER_IS_SEAT (seat), NULL); + + seat_class = CLUTTER_SEAT_GET_CLASS (seat); + return seat_class->create_virtual_device (seat, device_type); +} + +/** + * clutter_seat_supported_virtual_device_types: (skip) + */ +ClutterVirtualDeviceType +clutter_seat_get_supported_virtual_device_types (ClutterSeat *seat) +{ + ClutterSeatClass *seat_class; + + g_return_val_if_fail (CLUTTER_IS_SEAT (seat), + CLUTTER_VIRTUAL_DEVICE_TYPE_NONE); + + seat_class = CLUTTER_SEAT_GET_CLASS (seat); + return seat_class->get_supported_virtual_device_types (seat); +} + +void +clutter_seat_compress_motion (ClutterSeat *seat, + ClutterEvent *event, + const ClutterEvent *to_discard) +{ + ClutterSeatClass *seat_class; + + g_return_if_fail (CLUTTER_IS_SEAT (seat)); + + seat_class = CLUTTER_SEAT_GET_CLASS (seat); + + if (seat_class->compress_motion) + seat_class->compress_motion (seat, event, to_discard); +} + +gboolean +clutter_seat_handle_device_event (ClutterSeat *seat, + ClutterEvent *event) +{ + ClutterSeatClass *seat_class; + ClutterInputDevice *device; + + g_return_val_if_fail (CLUTTER_IS_SEAT (seat), FALSE); + g_return_val_if_fail (event, FALSE); + + g_assert (event->type == CLUTTER_DEVICE_ADDED || + event->type == CLUTTER_DEVICE_REMOVED); + + seat_class = CLUTTER_SEAT_GET_CLASS (seat); + + if (seat_class->handle_device_event) + { + if (!seat_class->handle_device_event (seat, event)) + return FALSE; + } + + device = clutter_event_get_source_device (event); + g_assert_true (CLUTTER_IS_INPUT_DEVICE (device)); + + switch (event->type) + { + case CLUTTER_DEVICE_ADDED: + g_signal_emit (seat, signals[DEVICE_ADDED], 0, device); + break; + case CLUTTER_DEVICE_REMOVED: + g_signal_emit (seat, signals[DEVICE_REMOVED], 0, device); + g_object_run_dispose (G_OBJECT (device)); + break; + default: + break; + } + + return TRUE; +} + +void +clutter_seat_warp_pointer (ClutterSeat *seat, + int x, + int y) +{ + g_return_if_fail (CLUTTER_IS_SEAT (seat)); + + CLUTTER_SEAT_GET_CLASS (seat)->warp_pointer (seat, x, y); +} + +/** + * clutter_seat_get_touch_mode: + * @seat: a #ClutterSeat + * + * Gets the current touch-mode state of the #ClutterSeat @seat. + * The #ClutterSeat:touch-mode property is set to %TRUE if the following + * requirements are fulfilled: + * + * - A touchscreen is available + * - A tablet mode switch, if present, is enabled + * + * Returns: %TRUE if the device is a tablet that doesn't have an external + * keyboard attached, %FALSE otherwise. + **/ +gboolean +clutter_seat_get_touch_mode (ClutterSeat *seat) +{ + gboolean touch_mode; + + g_return_val_if_fail (CLUTTER_IS_SEAT (seat), FALSE); + + g_object_get (G_OBJECT (seat), "touch-mode", &touch_mode, NULL); + + return touch_mode; +} diff --git a/clutter/clutter/clutter-seat.h b/clutter/clutter/clutter-seat.h new file mode 100644 index 000000000..eb1dd82bf --- /dev/null +++ b/clutter/clutter/clutter-seat.h @@ -0,0 +1,196 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Copyright (C) 2019 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Author: Carlos Garnacho + */ +#ifndef CLUTTER_SEAT_H +#define CLUTTER_SEAT_H + +#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) +#error "Only can be included directly." +#endif + +#include "clutter/clutter-types.h" +#include "clutter/clutter-keymap.h" +#include "clutter/clutter-virtual-input-device.h" + +#define CLUTTER_TYPE_SEAT (clutter_seat_get_type ()) + +CLUTTER_EXPORT +G_DECLARE_DERIVABLE_TYPE (ClutterSeat, clutter_seat, + CLUTTER, SEAT, GObject) + +/** + * ClutterKbdA11ySettings: + * + * The #ClutterKbdA11ySettings structure contains keyboard accessibility + * settings + * + */ +typedef struct _ClutterKbdA11ySettings +{ + ClutterKeyboardA11yFlags controls; + gint slowkeys_delay; + gint debounce_delay; + gint timeout_delay; + gint mousekeys_init_delay; + gint mousekeys_max_speed; + gint mousekeys_accel_time; +} ClutterKbdA11ySettings; + +/** + * ClutterPointerA11ySettings: + * + * The #ClutterPointerA11ySettings structure contains pointer accessibility + * settings + * + */ +typedef struct _ClutterPointerA11ySettings +{ + ClutterPointerA11yFlags controls; + ClutterPointerA11yDwellClickType dwell_click_type; + ClutterPointerA11yDwellMode dwell_mode; + ClutterPointerA11yDwellDirection dwell_gesture_single; + ClutterPointerA11yDwellDirection dwell_gesture_double; + ClutterPointerA11yDwellDirection dwell_gesture_drag; + ClutterPointerA11yDwellDirection dwell_gesture_secondary; + gint secondary_click_delay; + gint dwell_delay; + gint dwell_threshold; +} ClutterPointerA11ySettings; + +/** + * ClutterVirtualDeviceType: + */ +typedef enum +{ + CLUTTER_VIRTUAL_DEVICE_TYPE_NONE = 0, + CLUTTER_VIRTUAL_DEVICE_TYPE_KEYBOARD = 1 << 0, + CLUTTER_VIRTUAL_DEVICE_TYPE_POINTER = 1 << 1, + CLUTTER_VIRTUAL_DEVICE_TYPE_TOUCHSCREEN = 1 << 2, +} ClutterVirtualDeviceType; + +typedef struct _ClutterSeatClass ClutterSeatClass; + +struct _ClutterSeatClass +{ + GObjectClass parent_class; + + ClutterInputDevice * (* get_pointer) (ClutterSeat *seat); + ClutterInputDevice * (* get_keyboard) (ClutterSeat *seat); + + GList * (* list_devices) (ClutterSeat *seat); + + void (* bell_notify) (ClutterSeat *seat); + + ClutterKeymap * (* get_keymap) (ClutterSeat *seat); + + void (* compress_motion) (ClutterSeat *seat, + ClutterEvent *event, + const ClutterEvent *to_discard); + + gboolean (* handle_device_event) (ClutterSeat *seat, + ClutterEvent *event); + + void (* warp_pointer) (ClutterSeat *seat, + int x, + int y); + + /* Event platform data */ + void (* copy_event_data) (ClutterSeat *seat, + const ClutterEvent *src, + ClutterEvent *dest); + void (* free_event_data) (ClutterSeat *seat, + ClutterEvent *event); + + /* Keyboard accessibility */ + void (* apply_kbd_a11y_settings) (ClutterSeat *seat, + ClutterKbdA11ySettings *settings); + + /* Virtual devices */ + ClutterVirtualInputDevice * (* create_virtual_device) (ClutterSeat *seat, + ClutterInputDeviceType device_type); + ClutterVirtualDeviceType (* get_supported_virtual_device_types) (ClutterSeat *seat); +}; + +CLUTTER_EXPORT +ClutterInputDevice * clutter_seat_get_pointer (ClutterSeat *seat); +CLUTTER_EXPORT +ClutterInputDevice * clutter_seat_get_keyboard (ClutterSeat *seat); +CLUTTER_EXPORT +GList * clutter_seat_list_devices (ClutterSeat *seat); +CLUTTER_EXPORT +void clutter_seat_bell_notify (ClutterSeat *seat); + +CLUTTER_EXPORT +ClutterKeymap * clutter_seat_get_keymap (ClutterSeat *seat); + +CLUTTER_EXPORT +void clutter_seat_set_kbd_a11y_settings (ClutterSeat *seat, + ClutterKbdA11ySettings *settings); +CLUTTER_EXPORT +void clutter_seat_get_kbd_a11y_settings (ClutterSeat *seat, + ClutterKbdA11ySettings *settings); +CLUTTER_EXPORT +void clutter_seat_ensure_a11y_state (ClutterSeat *seat); + +CLUTTER_EXPORT +void clutter_seat_set_pointer_a11y_settings (ClutterSeat *seat, + ClutterPointerA11ySettings *settings); + +CLUTTER_EXPORT +void clutter_seat_get_pointer_a11y_settings (ClutterSeat *seat, + ClutterPointerA11ySettings *settings); + +CLUTTER_EXPORT +void clutter_seat_set_pointer_a11y_dwell_click_type (ClutterSeat *seat, + ClutterPointerA11yDwellClickType click_type); + +CLUTTER_EXPORT +void clutter_seat_inhibit_unfocus (ClutterSeat *seat); + +CLUTTER_EXPORT +void clutter_seat_uninhibit_unfocus (ClutterSeat *seat); + +CLUTTER_EXPORT +gboolean clutter_seat_is_unfocus_inhibited (ClutterSeat *seat); + +CLUTTER_EXPORT +ClutterVirtualInputDevice *clutter_seat_create_virtual_device (ClutterSeat *seat, + ClutterInputDeviceType device_type); + +CLUTTER_EXPORT +ClutterVirtualDeviceType clutter_seat_get_supported_virtual_device_types (ClutterSeat *seat); + +void clutter_seat_compress_motion (ClutterSeat *seat, + ClutterEvent *event, + const ClutterEvent *to_discard); + +gboolean clutter_seat_handle_device_event (ClutterSeat *seat, + ClutterEvent *event); + +CLUTTER_EXPORT +void clutter_seat_warp_pointer (ClutterSeat *seat, + int x, + int y); +CLUTTER_EXPORT +gboolean clutter_seat_get_touch_mode (ClutterSeat *seat); + +#endif /* CLUTTER_SEAT_H */ diff --git a/clutter/clutter/clutter-settings.c b/clutter/clutter/clutter-settings.c index 77893c9d6..9f39cb77a 100644 --- a/clutter/clutter/clutter-settings.c +++ b/clutter/clutter/clutter-settings.c @@ -17,9 +17,7 @@ * #ClutterSettings is available since Clutter 1.4 */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include "clutter-settings.h" @@ -274,9 +272,9 @@ clutter_settings_finalize (GObject *gobject) { ClutterSettings *self = CLUTTER_SETTINGS (gobject); - free (self->font_name); - free (self->xft_hint_style); - free (self->xft_rgba); + g_free (self->font_name); + g_free (self->xft_hint_style); + g_free (self->xft_rgba); G_OBJECT_CLASS (clutter_settings_parent_class)->finalize (gobject); } @@ -308,7 +306,7 @@ clutter_settings_set_property (GObject *gobject, break; case PROP_FONT_NAME: - free (self->font_name); + g_free (self->font_name); self->font_name = g_value_dup_string (value); settings_update_font_name (self); break; @@ -329,13 +327,13 @@ clutter_settings_set_property (GObject *gobject, break; case PROP_FONT_HINT_STYLE: - free (self->xft_hint_style); + g_free (self->xft_hint_style); self->xft_hint_style = g_value_dup_string (value); settings_update_font_options (self); break; case PROP_FONT_RGBA: - free (self->xft_rgba); + g_free (self->xft_rgba); self->xft_rgba = g_value_dup_string (value); settings_update_font_options (self); break; @@ -487,7 +485,7 @@ clutter_settings_class_init (ClutterSettingsClass *klass) P_("Double Click Time"), P_("The time between clicks necessary to detect a multiple click"), 0, G_MAXINT, - 250, + 400, CLUTTER_PARAM_READWRITE); /** @@ -697,7 +695,7 @@ clutter_settings_init (ClutterSettings *self) self->font_dpi = -1; self->unscaled_font_dpi = -1; - self->double_click_time = 250; + self->double_click_time = 400; self->double_click_distance = 5; self->dnd_drag_threshold = 8; @@ -844,5 +842,5 @@ _clutter_settings_read_from_key_file (ClutterSettings *settings, g_value_unset (&value); } - free (pspecs); + g_free (pspecs); } diff --git a/clutter/clutter/clutter-settings.h b/clutter/clutter/clutter-settings.h index 7c9fe427d..bb3911e9d 100644 --- a/clutter/clutter/clutter-settings.h +++ b/clutter/clutter/clutter-settings.h @@ -16,10 +16,10 @@ G_BEGIN_DECLS typedef struct _ClutterSettings ClutterSettings; typedef struct _ClutterSettingsClass ClutterSettingsClass; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT GType clutter_settings_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterSettings *clutter_settings_get_default (void); G_END_DECLS diff --git a/clutter/clutter/clutter-shader-effect.c b/clutter/clutter/clutter-shader-effect.c index ae14ff5e5..59fc1a891 100644 --- a/clutter/clutter/clutter-shader-effect.c +++ b/clutter/clutter/clutter-shader-effect.c @@ -111,9 +111,7 @@ * ]| */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include "cogl/cogl.h" @@ -179,18 +177,18 @@ clutter_shader_effect_clear (ClutterShaderEffect *self, { ClutterShaderEffectPrivate *priv = self->priv; - if (priv->shader != COGL_INVALID_HANDLE) + if (priv->shader != NULL) { - cogl_handle_unref (priv->shader); + cogl_object_unref (priv->shader); - priv->shader = COGL_INVALID_HANDLE; + priv->shader = NULL; } - if (priv->program != COGL_INVALID_HANDLE) + if (priv->program != NULL) { - cogl_handle_unref (priv->program); + cogl_object_unref (priv->program); - priv->program = COGL_INVALID_HANDLE; + priv->program = NULL; } if (reset_uniforms && priv->uniforms != NULL) @@ -210,7 +208,7 @@ clutter_shader_effect_update_uniforms (ClutterShaderEffect *effect) gpointer key, value; gsize size; - if (priv->program == COGL_INVALID_HANDLE) + if (priv->program == NULL) return; if (priv->uniforms == NULL) @@ -335,6 +333,7 @@ clutter_shader_effect_create_shader (ClutterShaderEffect *self) default: g_assert_not_reached (); + return NULL; } } @@ -354,7 +353,7 @@ clutter_shader_effect_try_static_source (ClutterShaderEffect *self) CLUTTER_TYPE_SHADER_EFFECT, ClutterShaderEffectClassPrivate); - if (class_priv->shader == COGL_INVALID_HANDLE) + if (class_priv->shader == NULL) { gchar *source; @@ -364,39 +363,28 @@ clutter_shader_effect_try_static_source (ClutterShaderEffect *self) cogl_shader_source (class_priv->shader, source); - free (source); + g_free (source); CLUTTER_NOTE (SHADER, "Compiling shader effect"); - cogl_shader_compile (class_priv->shader); + class_priv->program = cogl_create_program (); - if (cogl_shader_is_compiled (class_priv->shader)) - { - class_priv->program = cogl_create_program (); + cogl_program_attach_shader (class_priv->program, + class_priv->shader); - cogl_program_attach_shader (class_priv->program, - class_priv->shader); - - cogl_program_link (class_priv->program); - } - else - { - gchar *log_buf = cogl_shader_get_info_log (class_priv->shader); - - g_warning (G_STRLOC ": Unable to compile the GLSL shader: %s", log_buf); - free (log_buf); - } + cogl_program_link (class_priv->program); } - priv->shader = cogl_handle_ref (class_priv->shader); + priv->shader = cogl_object_ref (class_priv->shader); - if (class_priv->program != COGL_INVALID_HANDLE) - priv->program = cogl_handle_ref (class_priv->program); + if (class_priv->program != NULL) + priv->program = cogl_object_ref (class_priv->program); } } static void -clutter_shader_effect_paint_target (ClutterOffscreenEffect *effect) +clutter_shader_effect_paint_target (ClutterOffscreenEffect *effect, + ClutterPaintContext *paint_context) { ClutterShaderEffect *self = CLUTTER_SHADER_EFFECT (effect); ClutterShaderEffectPrivate *priv = self->priv; @@ -405,13 +393,13 @@ clutter_shader_effect_paint_target (ClutterOffscreenEffect *effect) /* If the source hasn't been set then we'll try to get it from the static source instead */ - if (priv->shader == COGL_INVALID_HANDLE) + if (priv->shader == NULL) clutter_shader_effect_try_static_source (self); /* we haven't been prepared or we don't have support for * GLSL shaders in Clutter */ - if (priv->program == COGL_INVALID_HANDLE) + if (priv->program == NULL) goto out; CLUTTER_NOTE (SHADER, "Applying the shader effect of type '%s'", @@ -426,7 +414,7 @@ clutter_shader_effect_paint_target (ClutterOffscreenEffect *effect) out: /* paint the offscreen buffer */ parent = CLUTTER_OFFSCREEN_EFFECT_CLASS (clutter_shader_effect_parent_class); - parent->paint_target (effect); + parent->paint_target (effect, paint_context); } @@ -501,6 +489,7 @@ static void clutter_shader_effect_init (ClutterShaderEffect *effect) { effect->priv = clutter_shader_effect_get_instance_private (effect); + effect->priv->shader_type = CLUTTER_FRAGMENT_SHADER; } /** @@ -534,7 +523,7 @@ clutter_shader_effect_new (ClutterShaderType shader_type) * Retrieves a pointer to the shader's handle * * Return value: (transfer none): a pointer to the shader's handle, - * or %COGL_INVALID_HANDLE + * or %NULL * * Since: 1.4 */ @@ -542,7 +531,7 @@ CoglHandle clutter_shader_effect_get_shader (ClutterShaderEffect *effect) { g_return_val_if_fail (CLUTTER_IS_SHADER_EFFECT (effect), - COGL_INVALID_HANDLE); + NULL); return effect->priv->shader; } @@ -554,7 +543,7 @@ clutter_shader_effect_get_shader (ClutterShaderEffect *effect) * Retrieves a pointer to the program's handle * * Return value: (transfer none): a pointer to the program's handle, - * or %COGL_INVALID_HANDLE + * or %NULL * * Since: 1.4 */ @@ -562,7 +551,7 @@ CoglHandle clutter_shader_effect_get_program (ClutterShaderEffect *effect) { g_return_val_if_fail (CLUTTER_IS_SHADER_EFFECT (effect), - COGL_INVALID_HANDLE); + NULL); return effect->priv->program; } @@ -575,7 +564,7 @@ shader_uniform_free (gpointer data) ShaderUniform *uniform = data; g_value_unset (&uniform->value); - free (uniform->name); + g_free (uniform->name); g_slice_free (ShaderUniform, uniform); } @@ -732,7 +721,7 @@ clutter_shader_effect_set_uniform_valist (ClutterShaderEffect *effect, g_value_init (&value, CLUTTER_TYPE_SHADER_INT); clutter_value_set_shader_int (&value, n_values, int_values); - free (int_values); + g_free (int_values); } goto add_uniform; @@ -764,7 +753,7 @@ clutter_shader_effect_set_uniform_valist (ClutterShaderEffect *effect, g_value_init (&value, CLUTTER_TYPE_SHADER_FLOAT); clutter_value_set_shader_float (&value, n_values, float_values); - free (float_values); + g_free (float_values); } goto add_uniform; @@ -892,7 +881,7 @@ clutter_shader_effect_set_shader_source (ClutterShaderEffect *effect, priv = effect->priv; - if (priv->shader != COGL_INVALID_HANDLE) + if (priv->shader != NULL) return TRUE; priv->shader = clutter_shader_effect_create_shader (effect); @@ -901,23 +890,11 @@ clutter_shader_effect_set_shader_source (ClutterShaderEffect *effect, CLUTTER_NOTE (SHADER, "Compiling shader effect"); - cogl_shader_compile (priv->shader); + priv->program = cogl_create_program (); - if (cogl_shader_is_compiled (priv->shader)) - { - priv->program = cogl_create_program (); + cogl_program_attach_shader (priv->program, priv->shader); - cogl_program_attach_shader (priv->program, priv->shader); - - cogl_program_link (priv->program); - } - else - { - gchar *log_buf = cogl_shader_get_info_log (priv->shader); - - g_warning (G_STRLOC ": Unable to compile the GLSL shader: %s", log_buf); - free (log_buf); - } + cogl_program_link (priv->program); return TRUE; } diff --git a/clutter/clutter/clutter-shader-effect.h b/clutter/clutter/clutter-shader-effect.h index fc9775e5a..7df050ee7 100644 --- a/clutter/clutter/clutter-shader-effect.h +++ b/clutter/clutter/clutter-shader-effect.h @@ -90,30 +90,30 @@ struct _ClutterShaderEffectClass void (*_clutter_shader5) (void); }; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT GType clutter_shader_effect_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT ClutterEffect * clutter_shader_effect_new (ClutterShaderType shader_type); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT gboolean clutter_shader_effect_set_shader_source (ClutterShaderEffect *effect, const gchar *source); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_shader_effect_set_uniform (ClutterShaderEffect *effect, const gchar *name, GType gtype, gsize n_values, ...); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT void clutter_shader_effect_set_uniform_value (ClutterShaderEffect *effect, const gchar *name, const GValue *value); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT CoglHandle clutter_shader_effect_get_shader (ClutterShaderEffect *effect); -CLUTTER_AVAILABLE_IN_1_4 +CLUTTER_EXPORT CoglHandle clutter_shader_effect_get_program (ClutterShaderEffect *effect); G_END_DECLS diff --git a/clutter/clutter/clutter-shader-types.c b/clutter/clutter/clutter-shader-types.c index c956ef3f8..c0265b697 100644 --- a/clutter/clutter/clutter-shader-types.c +++ b/clutter/clutter/clutter-shader-types.c @@ -24,9 +24,7 @@ * */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include #include diff --git a/clutter/clutter/clutter-shader-types.h b/clutter/clutter/clutter-shader-types.h index f144b6c20..629cf515a 100644 --- a/clutter/clutter/clutter-shader-types.h +++ b/clutter/clutter/clutter-shader-types.h @@ -70,32 +70,32 @@ typedef struct _ClutterShaderMatrix ClutterShaderMatrix; */ #define CLUTTER_VALUE_HOLDS_SHADER_MATRIX(x) (G_VALUE_HOLDS ((x), CLUTTER_TYPE_SHADER_MATRIX)) -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT GType clutter_shader_float_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT GType clutter_shader_int_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT GType clutter_shader_matrix_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_value_set_shader_float (GValue *value, gint size, const gfloat *floats); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_value_set_shader_int (GValue *value, gint size, const gint *ints); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_value_set_shader_matrix (GValue *value, gint size, const gfloat *matrix); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT const gfloat * clutter_value_get_shader_float (const GValue *value, gsize *length); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT const gint * clutter_value_get_shader_int (const GValue *value, gsize *length); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT const gfloat * clutter_value_get_shader_matrix (const GValue *value, gsize *length); diff --git a/clutter/clutter/clutter-snap-constraint.c b/clutter/clutter/clutter-snap-constraint.c index 5b6db9b54..5d526aab3 100644 --- a/clutter/clutter/clutter-snap-constraint.c +++ b/clutter/clutter/clutter-snap-constraint.c @@ -35,9 +35,7 @@ * #ClutterSnapConstraint is available since Clutter 1.6 */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include diff --git a/clutter/clutter/clutter-snap-constraint.h b/clutter/clutter/clutter-snap-constraint.h index 5a788dcf8..4ee46d03d 100644 --- a/clutter/clutter/clutter-snap-constraint.h +++ b/clutter/clutter/clutter-snap-constraint.h @@ -48,32 +48,32 @@ G_BEGIN_DECLS typedef struct _ClutterSnapConstraint ClutterSnapConstraint; typedef struct _ClutterSnapConstraintClass ClutterSnapConstraintClass; -CLUTTER_AVAILABLE_IN_1_6 +CLUTTER_EXPORT GType clutter_snap_constraint_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_6 +CLUTTER_EXPORT ClutterConstraint * clutter_snap_constraint_new (ClutterActor *source, ClutterSnapEdge from_edge, ClutterSnapEdge to_edge, gfloat offset); -CLUTTER_AVAILABLE_IN_1_6 +CLUTTER_EXPORT void clutter_snap_constraint_set_source (ClutterSnapConstraint *constraint, ClutterActor *source); -CLUTTER_AVAILABLE_IN_1_6 +CLUTTER_EXPORT ClutterActor * clutter_snap_constraint_get_source (ClutterSnapConstraint *constraint); -CLUTTER_AVAILABLE_IN_1_6 +CLUTTER_EXPORT void clutter_snap_constraint_set_edges (ClutterSnapConstraint *constraint, ClutterSnapEdge from_edge, ClutterSnapEdge to_edge); -CLUTTER_AVAILABLE_IN_1_6 +CLUTTER_EXPORT void clutter_snap_constraint_get_edges (ClutterSnapConstraint *constraint, ClutterSnapEdge *from_edge, ClutterSnapEdge *to_edge); -CLUTTER_AVAILABLE_IN_1_6 +CLUTTER_EXPORT void clutter_snap_constraint_set_offset (ClutterSnapConstraint *constraint, gfloat offset); -CLUTTER_AVAILABLE_IN_1_6 +CLUTTER_EXPORT gfloat clutter_snap_constraint_get_offset (ClutterSnapConstraint *constraint); G_END_DECLS diff --git a/clutter/clutter/clutter-stage-manager.c b/clutter/clutter/clutter-stage-manager.c index 3a44c8209..0132e1983 100644 --- a/clutter/clutter/clutter-stage-manager.c +++ b/clutter/clutter/clutter-stage-manager.c @@ -36,18 +36,13 @@ * #ClutterStageManager is available since Clutter 0.8 */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include "clutter-stage-manager-private.h" #include "clutter-marshal.h" #include "clutter-debug.h" #include "clutter-private.h" -#include "clutter-version.h" - -#include "deprecated/clutter-stage-manager.h" enum { @@ -92,8 +87,8 @@ clutter_stage_manager_dispose (GObject *gobject) stage_manager = CLUTTER_STAGE_MANAGER (gobject); - g_slist_foreach (stage_manager->stages, (GFunc) clutter_actor_destroy, NULL); - g_slist_free (stage_manager->stages); + g_slist_free_full (stage_manager->stages, + (GDestroyNotify) clutter_actor_destroy); stage_manager->stages = NULL; G_OBJECT_CLASS (clutter_stage_manager_parent_class)->dispose (gobject); @@ -137,8 +132,7 @@ clutter_stage_manager_class_init (ClutterStageManagerClass *klass) G_OBJECT_CLASS_TYPE (gobject_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ClutterStageManagerClass, stage_added), - NULL, NULL, - _clutter_marshal_VOID__OBJECT, + NULL, NULL, NULL, G_TYPE_NONE, 1, CLUTTER_TYPE_STAGE); /** @@ -156,8 +150,7 @@ clutter_stage_manager_class_init (ClutterStageManagerClass *klass) G_OBJECT_CLASS_TYPE (gobject_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ClutterStageManagerClass, stage_removed), - NULL, NULL, - _clutter_marshal_VOID__OBJECT, + NULL, NULL, NULL, G_TYPE_NONE, 1, CLUTTER_TYPE_STAGE); } @@ -188,23 +181,6 @@ clutter_stage_manager_get_default (void) return context->stage_manager; } -/** - * clutter_stage_manager_set_default_stage: - * @stage_manager: a #ClutterStageManager - * @stage: a #ClutterStage - * - * Sets @stage as the default stage. - * - * Since: 0.8 - * - * Deprecated: 1.2: Calling this function has no effect - */ -void -clutter_stage_manager_set_default_stage (ClutterStageManager *stage_manager, - ClutterStage *stage) -{ -} - /*< private > * _clutter_stage_manager_set_default_stage: * @stage_manager: a #ClutterStageManager diff --git a/clutter/clutter/clutter-stage-manager.h b/clutter/clutter/clutter-stage-manager.h index fa3badddf..27da12e2e 100644 --- a/clutter/clutter/clutter-stage-manager.h +++ b/clutter/clutter/clutter-stage-manager.h @@ -69,16 +69,16 @@ struct _ClutterStageManagerClass ClutterStage *stage); }; -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT GType clutter_stage_manager_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT ClutterStageManager *clutter_stage_manager_get_default (void); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT ClutterStage * clutter_stage_manager_get_default_stage (ClutterStageManager *stage_manager); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT GSList * clutter_stage_manager_list_stages (ClutterStageManager *stage_manager); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT const GSList * clutter_stage_manager_peek_stages (ClutterStageManager *stage_manager); G_END_DECLS diff --git a/clutter/clutter/clutter-stage-private.h b/clutter/clutter/clutter-stage-private.h index 517c9adda..0bda81d9a 100644 --- a/clutter/clutter/clutter-stage-private.h +++ b/clutter/clutter/clutter-stage-private.h @@ -36,12 +36,16 @@ typedef struct _ClutterStageQueueRedrawEntry ClutterStageQueueRedrawEntry; /* stage */ ClutterStageWindow *_clutter_stage_get_default_window (void); -void _clutter_stage_paint_view (ClutterStage *stage, - ClutterStageView *view, - const cairo_rectangle_int_t *clip); +void clutter_stage_paint_view (ClutterStage *stage, + ClutterStageView *view, + const cairo_region_t *redraw_clip); +void _clutter_stage_emit_after_paint (ClutterStage *stage); + +CLUTTER_EXPORT void _clutter_stage_set_window (ClutterStage *stage, ClutterStageWindow *stage_window); +CLUTTER_EXPORT ClutterStageWindow *_clutter_stage_get_window (ClutterStage *stage); void _clutter_stage_get_projection_matrix (ClutterStage *stage, CoglMatrix *projection); @@ -63,20 +67,30 @@ void _clutter_stage_maybe_relayout (ClutterActor gboolean _clutter_stage_needs_update (ClutterStage *stage); gboolean _clutter_stage_do_update (ClutterStage *stage); +CLUTTER_EXPORT void _clutter_stage_queue_event (ClutterStage *stage, ClutterEvent *event, gboolean copy_event); gboolean _clutter_stage_has_queued_events (ClutterStage *stage); void _clutter_stage_process_queued_events (ClutterStage *stage); void _clutter_stage_update_input_devices (ClutterStage *stage); -void _clutter_stage_schedule_update (ClutterStage *stage); gint64 _clutter_stage_get_update_time (ClutterStage *stage); void _clutter_stage_clear_update_time (ClutterStage *stage); gboolean _clutter_stage_has_full_redraw_queued (ClutterStage *stage); +int64_t _clutter_stage_get_next_presentation_time (ClutterStage *stage); + +void clutter_stage_log_pick (ClutterStage *stage, + const graphene_point_t *vertices, + ClutterActor *actor); + +void clutter_stage_push_pick_clip (ClutterStage *stage, + const graphene_point_t *vertices); + +void clutter_stage_pop_pick_clip (ClutterStage *stage); ClutterActor *_clutter_stage_do_pick (ClutterStage *stage, - gint x, - gint y, + float x, + float y, ClutterPickMode mode); ClutterPaintVolume *_clutter_stage_paint_volume_stack_allocate (ClutterStage *stage); @@ -87,18 +101,9 @@ const ClutterPlane *_clutter_stage_get_clip (ClutterStage *stage); ClutterStageQueueRedrawEntry *_clutter_stage_queue_actor_redraw (ClutterStage *stage, ClutterStageQueueRedrawEntry *entry, ClutterActor *actor, - ClutterPaintVolume *clip); + const ClutterPaintVolume *clip); void _clutter_stage_queue_redraw_entry_invalidate (ClutterStageQueueRedrawEntry *entry); -CoglFramebuffer *_clutter_stage_get_active_framebuffer (ClutterStage *stage); - -gint32 _clutter_stage_acquire_pick_id (ClutterStage *stage, - ClutterActor *actor); -void _clutter_stage_release_pick_id (ClutterStage *stage, - gint32 pick_id); -ClutterActor * _clutter_stage_get_actor_by_pick_id (ClutterStage *stage, - gint32 pick_id); - void _clutter_stage_add_pointer_drag_actor (ClutterStage *stage, ClutterInputDevice *device, ClutterActor *actor); @@ -115,20 +120,30 @@ ClutterActor * _clutter_stage_get_touch_drag_actor (ClutterStage *st void _clutter_stage_remove_touch_drag_actor (ClutterStage *stage, ClutterEventSequence *sequence); +CLUTTER_EXPORT ClutterStageState _clutter_stage_get_state (ClutterStage *stage); +CLUTTER_EXPORT gboolean _clutter_stage_is_activated (ClutterStage *stage); -gboolean _clutter_stage_is_fullscreen (ClutterStage *stage); +CLUTTER_EXPORT gboolean _clutter_stage_update_state (ClutterStage *stage, ClutterStageState unset_state, ClutterStageState set_state); void _clutter_stage_set_scale_factor (ClutterStage *stage, int factor); +gboolean _clutter_stage_get_max_view_scale_factor_for_rect (ClutterStage *stage, + graphene_rect_t *rect, + float *view_scale); void _clutter_stage_presented (ClutterStage *stage, CoglFrameEvent frame_event, ClutterFrameInfo *frame_info); +GList * _clutter_stage_peek_stage_views (ClutterStage *stage); + +void clutter_stage_queue_actor_relayout (ClutterStage *stage, + ClutterActor *actor); + G_END_DECLS #endif /* __CLUTTER_STAGE_PRIVATE_H__ */ diff --git a/clutter/clutter/clutter-stage-view-private.h b/clutter/clutter/clutter-stage-view-private.h new file mode 100644 index 000000000..3b0d419fc --- /dev/null +++ b/clutter/clutter/clutter-stage-view-private.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2019 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#ifndef __CLUTTER_STAGE_VIEW_PRIVATE_H__ +#define __CLUTTER_STAGE_VIEW_PRIVATE_H__ + +#include "clutter/clutter-stage-view.h" + +void clutter_stage_view_after_paint (ClutterStageView *view); + +gboolean clutter_stage_view_is_dirty_viewport (ClutterStageView *view); + +void clutter_stage_view_set_dirty_viewport (ClutterStageView *view, + gboolean dirty); + +gboolean clutter_stage_view_is_dirty_projection (ClutterStageView *view); + +void clutter_stage_view_set_dirty_projection (ClutterStageView *view, + gboolean dirty); + +void clutter_stage_view_add_redraw_clip (ClutterStageView *view, + const cairo_rectangle_int_t *clip); + +gboolean clutter_stage_view_has_full_redraw_clip (ClutterStageView *view); + +gboolean clutter_stage_view_has_redraw_clip (ClutterStageView *view); + +const cairo_region_t * clutter_stage_view_peek_redraw_clip (ClutterStageView *view); + +cairo_region_t * clutter_stage_view_take_redraw_clip (ClutterStageView *view); + +#endif /* __CLUTTER_STAGE_VIEW_PRIVATE_H__ */ diff --git a/clutter/clutter/clutter-stage-view.c b/clutter/clutter/clutter-stage-view.c index cd6cd35cb..d93cf573f 100644 --- a/clutter/clutter/clutter-stage-view.c +++ b/clutter/clutter/clutter-stage-view.c @@ -18,10 +18,13 @@ #include "clutter-build-config.h" #include "clutter/clutter-stage-view.h" +#include "clutter/clutter-stage-view-private.h" #include #include +#include "clutter/clutter-private.h" + enum { PROP_0, @@ -29,6 +32,7 @@ enum PROP_LAYOUT, PROP_FRAMEBUFFER, PROP_OFFSCREEN, + PROP_SHADOWFB, PROP_SCALE, PROP_LAST @@ -43,7 +47,13 @@ typedef struct _ClutterStageViewPrivate CoglFramebuffer *framebuffer; CoglOffscreen *offscreen; - CoglPipeline *pipeline; + CoglPipeline *offscreen_pipeline; + + CoglOffscreen *shadowfb; + CoglPipeline *shadowfb_pipeline; + + gboolean has_redraw_clip; + cairo_region_t *redraw_clip; guint dirty_viewport : 1; guint dirty_projection : 1; @@ -61,6 +71,14 @@ clutter_stage_view_get_layout (ClutterStageView *view, *rect = priv->layout; } +/** + * clutter_stage_view_get_framebuffer: + * @view: a #ClutterStageView + * + * Retrieves the framebuffer of @view to draw to. + * + * Returns: (transfer none): a #CoglFramebuffer + */ CoglFramebuffer * clutter_stage_view_get_framebuffer (ClutterStageView *view) { @@ -69,10 +87,20 @@ clutter_stage_view_get_framebuffer (ClutterStageView *view) if (priv->offscreen) return priv->offscreen; + else if (priv->shadowfb) + return priv->shadowfb; else return priv->framebuffer; } +/** + * clutter_stage_view_get_onscreen: + * @view: a #ClutterStageView + * + * Retrieves the onscreen framebuffer of @view if available. + * + * Returns: (transfer none): a #CoglFramebuffer + */ CoglFramebuffer * clutter_stage_view_get_onscreen (ClutterStageView *view) { @@ -82,6 +110,24 @@ clutter_stage_view_get_onscreen (ClutterStageView *view) return priv->framebuffer; } +static CoglPipeline * +clutter_stage_view_create_framebuffer_pipeline (CoglFramebuffer *framebuffer) +{ + CoglPipeline *pipeline; + + pipeline = cogl_pipeline_new (cogl_framebuffer_get_context (framebuffer)); + + cogl_pipeline_set_layer_filters (pipeline, 0, + COGL_PIPELINE_FILTER_NEAREST, + COGL_PIPELINE_FILTER_NEAREST); + cogl_pipeline_set_layer_texture (pipeline, 0, + cogl_offscreen_get_texture (framebuffer)); + cogl_pipeline_set_layer_wrap_mode (pipeline, 0, + COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE); + + return pipeline; +} + static void clutter_stage_view_ensure_offscreen_blit_pipeline (ClutterStageView *view) { @@ -92,56 +138,117 @@ clutter_stage_view_ensure_offscreen_blit_pipeline (ClutterStageView *view) g_assert (priv->offscreen != NULL); - if (priv->pipeline) + if (priv->offscreen_pipeline) return; - priv->pipeline = - cogl_pipeline_new (cogl_framebuffer_get_context (priv->offscreen)); - cogl_pipeline_set_layer_filters (priv->pipeline, 0, - COGL_PIPELINE_FILTER_NEAREST, - COGL_PIPELINE_FILTER_NEAREST); - cogl_pipeline_set_layer_texture (priv->pipeline, 0, - cogl_offscreen_get_texture (priv->offscreen)); - cogl_pipeline_set_layer_wrap_mode (priv->pipeline, 0, - COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE); + priv->offscreen_pipeline = + clutter_stage_view_create_framebuffer_pipeline (priv->offscreen); if (view_class->setup_offscreen_blit_pipeline) - view_class->setup_offscreen_blit_pipeline (view, priv->pipeline); + view_class->setup_offscreen_blit_pipeline (view, priv->offscreen_pipeline); } -void -clutter_stage_view_invalidate_offscreen_blit_pipeline (ClutterStageView *view) +static void +clutter_stage_view_ensure_shadowfb_blit_pipeline (ClutterStageView *view) { ClutterStageViewPrivate *priv = clutter_stage_view_get_instance_private (view); - g_clear_pointer (&priv->pipeline, cogl_object_unref); + if (priv->shadowfb_pipeline) + return; + + priv->shadowfb_pipeline = + clutter_stage_view_create_framebuffer_pipeline (priv->shadowfb); } void -clutter_stage_view_blit_offscreen (ClutterStageView *view, - const cairo_rectangle_int_t *rect) +clutter_stage_view_invalidate_offscreen_blit_pipeline (ClutterStageView *view) { ClutterStageViewPrivate *priv = clutter_stage_view_get_instance_private (view); + + g_clear_pointer (&priv->offscreen_pipeline, cogl_object_unref); +} + +static void +clutter_stage_view_copy_to_framebuffer (ClutterStageView *view, + CoglPipeline *pipeline, + CoglFramebuffer *src_framebuffer, + CoglFramebuffer *dst_framebuffer, + gboolean can_blit) +{ CoglMatrix matrix; - clutter_stage_view_ensure_offscreen_blit_pipeline (view); - cogl_framebuffer_push_matrix (priv->framebuffer); + /* First, try with blit */ + if (can_blit) + { + if (cogl_blit_framebuffer (src_framebuffer, + dst_framebuffer, + 0, 0, + 0, 0, + cogl_framebuffer_get_width (dst_framebuffer), + cogl_framebuffer_get_height (dst_framebuffer), + NULL)) + return; + } + + /* If blit fails, fallback to the slower painting method */ + cogl_framebuffer_push_matrix (dst_framebuffer); - /* Set transform so 0,0 is on the top left corner and 1,1 on - * the bottom right corner. - */ cogl_matrix_init_identity (&matrix); cogl_matrix_translate (&matrix, -1, 1, 0); cogl_matrix_scale (&matrix, 2, -2, 0); - cogl_framebuffer_set_projection_matrix (priv->framebuffer, &matrix); + cogl_framebuffer_set_projection_matrix (dst_framebuffer, &matrix); - cogl_framebuffer_draw_rectangle (priv->framebuffer, - priv->pipeline, + cogl_framebuffer_draw_rectangle (dst_framebuffer, + pipeline, 0, 0, 1, 1); - cogl_framebuffer_pop_matrix (priv->framebuffer); + cogl_framebuffer_pop_matrix (dst_framebuffer); +} + +void +clutter_stage_view_after_paint (ClutterStageView *view) +{ + ClutterStageViewPrivate *priv = + clutter_stage_view_get_instance_private (view); + + if (priv->offscreen) + { + gboolean can_blit; + CoglMatrix matrix; + + clutter_stage_view_ensure_offscreen_blit_pipeline (view); + clutter_stage_view_get_offscreen_transformation_matrix (view, &matrix); + can_blit = cogl_matrix_is_identity (&matrix); + + if (priv->shadowfb) + { + clutter_stage_view_copy_to_framebuffer (view, + priv->offscreen_pipeline, + priv->offscreen, + priv->shadowfb, + can_blit); + } + else + { + clutter_stage_view_copy_to_framebuffer (view, + priv->offscreen_pipeline, + priv->offscreen, + priv->framebuffer, + can_blit); + } + } + + if (priv->shadowfb) + { + clutter_stage_view_ensure_shadowfb_blit_pipeline (view); + clutter_stage_view_copy_to_framebuffer (view, + priv->shadowfb_pipeline, + priv->shadowfb, + priv->framebuffer, + TRUE); + } } float @@ -200,6 +307,86 @@ clutter_stage_view_get_offscreen_transformation_matrix (ClutterStageView *view, view_class->get_offscreen_transformation_matrix (view, matrix); } +void +clutter_stage_view_add_redraw_clip (ClutterStageView *view, + const cairo_rectangle_int_t *clip) +{ + ClutterStageViewPrivate *priv = + clutter_stage_view_get_instance_private (view); + + if (priv->has_redraw_clip && !priv->redraw_clip) + return; + + if (!clip) + { + g_clear_pointer (&priv->redraw_clip, cairo_region_destroy); + priv->has_redraw_clip = TRUE; + return; + } + + if (clip->width == 0 || clip->height == 0) + return; + + if (!priv->redraw_clip) + { + if (!clutter_util_rectangle_equal (&priv->layout, clip)) + priv->redraw_clip = cairo_region_create_rectangle (clip); + } + else + { + cairo_region_union_rectangle (priv->redraw_clip, clip); + + if (cairo_region_num_rectangles (priv->redraw_clip) == 1) + { + cairo_rectangle_int_t redraw_clip_extents; + + cairo_region_get_extents (priv->redraw_clip, &redraw_clip_extents); + if (clutter_util_rectangle_equal (&priv->layout, &redraw_clip_extents)) + g_clear_pointer (&priv->redraw_clip, cairo_region_destroy); + } + } + + priv->has_redraw_clip = TRUE; +} + +gboolean +clutter_stage_view_has_redraw_clip (ClutterStageView *view) +{ + ClutterStageViewPrivate *priv = + clutter_stage_view_get_instance_private (view); + + return priv->has_redraw_clip; +} + +gboolean +clutter_stage_view_has_full_redraw_clip (ClutterStageView *view) +{ + ClutterStageViewPrivate *priv = + clutter_stage_view_get_instance_private (view); + + return priv->has_redraw_clip && !priv->redraw_clip; +} + +const cairo_region_t * +clutter_stage_view_peek_redraw_clip (ClutterStageView *view) +{ + ClutterStageViewPrivate *priv = + clutter_stage_view_get_instance_private (view); + + return priv->redraw_clip; +} + +cairo_region_t * +clutter_stage_view_take_redraw_clip (ClutterStageView *view) +{ + ClutterStageViewPrivate *priv = + clutter_stage_view_get_instance_private (view); + + priv->has_redraw_clip = FALSE; + + return g_steal_pointer (&priv->redraw_clip); +} + void clutter_stage_view_transform_to_onscreen (ClutterStageView *view, gfloat *x, @@ -241,6 +428,9 @@ clutter_stage_view_get_property (GObject *object, case PROP_OFFSCREEN: g_value_set_boxed (value, priv->offscreen); break; + case PROP_SHADOWFB: + g_value_set_boxed (value, priv->shadowfb); + break; case PROP_SCALE: g_value_set_float (value, priv->scale); break; @@ -286,6 +476,9 @@ clutter_stage_view_set_property (GObject *object, case PROP_OFFSCREEN: priv->offscreen = g_value_dup_boxed (value); break; + case PROP_SHADOWFB: + priv->shadowfb = g_value_dup_boxed (value); + break; case PROP_SCALE: priv->scale = g_value_get_float (value); break; @@ -302,8 +495,11 @@ clutter_stage_view_dispose (GObject *object) clutter_stage_view_get_instance_private (view); g_clear_pointer (&priv->framebuffer, cogl_object_unref); + g_clear_pointer (&priv->shadowfb, cogl_object_unref); g_clear_pointer (&priv->offscreen, cogl_object_unref); - g_clear_pointer (&priv->pipeline, cogl_object_unref); + g_clear_pointer (&priv->offscreen_pipeline, cogl_object_unref); + g_clear_pointer (&priv->shadowfb_pipeline, cogl_object_unref); + g_clear_pointer (&priv->redraw_clip, cairo_region_destroy); G_OBJECT_CLASS (clutter_stage_view_parent_class)->dispose (object); } @@ -358,6 +554,15 @@ clutter_stage_view_class_init (ClutterStageViewClass *klass) G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + obj_props[PROP_SHADOWFB] = + g_param_spec_boxed ("shadowfb", + "Shadow framebuffer", + "Framebuffer used as intermediate shadow buffer", + COGL_TYPE_HANDLE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + obj_props[PROP_SCALE] = g_param_spec_float ("scale", "View scale", diff --git a/clutter/clutter/clutter-stage-view.h b/clutter/clutter/clutter-stage-view.h index 99171e374..26bf10e79 100644 --- a/clutter/clutter/clutter-stage-view.h +++ b/clutter/clutter/clutter-stage-view.h @@ -18,6 +18,10 @@ #ifndef __CLUTTER_STAGE_VIEW_H__ #define __CLUTTER_STAGE_VIEW_H__ +#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) +#error "Only can be included directly." +#endif + #include #include #include @@ -25,7 +29,7 @@ #include "clutter-macros.h" #define CLUTTER_TYPE_STAGE_VIEW (clutter_stage_view_get_type ()) -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT G_DECLARE_DERIVABLE_TYPE (ClutterStageView, clutter_stage_view, CLUTTER, STAGE_VIEW, GObject) @@ -41,39 +45,26 @@ struct _ClutterStageViewClass CoglMatrix *matrix); }; -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT void clutter_stage_view_get_layout (ClutterStageView *view, cairo_rectangle_int_t *rect); -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT CoglFramebuffer *clutter_stage_view_get_framebuffer (ClutterStageView *view); -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT CoglFramebuffer *clutter_stage_view_get_onscreen (ClutterStageView *view); -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT void clutter_stage_view_invalidate_offscreen_blit_pipeline (ClutterStageView *view); -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT void clutter_stage_view_transform_to_onscreen (ClutterStageView *view, gfloat *x, gfloat *y); -void clutter_stage_view_blit_offscreen (ClutterStageView *view, - const cairo_rectangle_int_t *clip); - -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT float clutter_stage_view_get_scale (ClutterStageView *view); -gboolean clutter_stage_view_is_dirty_viewport (ClutterStageView *view); - -void clutter_stage_view_set_dirty_viewport (ClutterStageView *view, - gboolean dirty); - -gboolean clutter_stage_view_is_dirty_projection (ClutterStageView *view); - -void clutter_stage_view_set_dirty_projection (ClutterStageView *view, - gboolean dirty); - -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT void clutter_stage_view_get_offscreen_transformation_matrix (ClutterStageView *view, CoglMatrix *matrix); diff --git a/clutter/clutter/clutter-stage-window.c b/clutter/clutter/clutter-stage-window.c index c9a227b8b..a3782a175 100644 --- a/clutter/clutter/clutter-stage-window.c +++ b/clutter/clutter/clutter-stage-window.c @@ -1,6 +1,4 @@ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include @@ -8,9 +6,13 @@ #include "clutter-stage-window.h" #include "clutter-private.h" -#define clutter_stage_window_get_type _clutter_stage_window_get_type - -typedef ClutterStageWindowIface ClutterStageWindowInterface; +/** + * SECTION:clutter-stage-window + * @short_description: Handles the implementation for ClutterStage + * + * #ClutterStageWindow is an interface that provides the implementation for the + * #ClutterStage actor, abstracting away the specifics of the windowing system. + */ G_DEFINE_INTERFACE (ClutterStageWindow, clutter_stage_window, G_TYPE_OBJECT); @@ -38,6 +40,12 @@ clutter_stage_window_default_init (ClutterStageWindowInterface *iface) g_object_interface_install_property (iface, pspec); } +/** + * _clutter_stage_window_get_wrapper: + * @window: a #ClutterStageWindow object + * + * Returns the pointer to the #ClutterStage it's part of. + */ ClutterActor * _clutter_stage_window_get_wrapper (ClutterStageWindow *window) { @@ -48,40 +56,22 @@ void _clutter_stage_window_set_title (ClutterStageWindow *window, const gchar *title) { - ClutterStageWindowIface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window); + ClutterStageWindowInterface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window); if (iface->set_title) iface->set_title (window, title); } -void -_clutter_stage_window_set_fullscreen (ClutterStageWindow *window, - gboolean is_fullscreen) -{ - ClutterStageWindowIface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window); - - if (iface->set_fullscreen) - iface->set_fullscreen (window, is_fullscreen); -} - void _clutter_stage_window_set_cursor_visible (ClutterStageWindow *window, gboolean is_visible) { - ClutterStageWindowIface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window); + ClutterStageWindowInterface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window); if (iface->set_cursor_visible) iface->set_cursor_visible (window, is_visible); } -void -_clutter_stage_window_set_user_resizable (ClutterStageWindow *window, - gboolean is_resizable) -{ - CLUTTER_STAGE_WINDOW_GET_IFACE (window)->set_user_resizable (window, - is_resizable); -} - gboolean _clutter_stage_window_realize (ClutterStageWindow *window) { @@ -126,7 +116,7 @@ void _clutter_stage_window_schedule_update (ClutterStageWindow *window, int sync_delay) { - ClutterStageWindowIface *iface; + ClutterStageWindowInterface *iface; g_return_if_fail (CLUTTER_IS_STAGE_WINDOW (window)); @@ -140,10 +130,18 @@ _clutter_stage_window_schedule_update (ClutterStageWindow *window, iface->schedule_update (window, sync_delay); } +/** + * _clutter_stage_window_get_update_time: + * @window: a #ClutterStageWindow object + * + * See _clutter_stage_get_update_time() for more info. + * + * Returns: The timestamp of the update time + */ gint64 _clutter_stage_window_get_update_time (ClutterStageWindow *window) { - ClutterStageWindowIface *iface; + ClutterStageWindowInterface *iface; g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), 0); @@ -157,10 +155,16 @@ _clutter_stage_window_get_update_time (ClutterStageWindow *window) return iface->get_update_time (window); } +/** + * _clutter_stage_window_clear_update_time: + * @window: a #ClutterStageWindow object + * + * Clears the update time. See _clutter_stage_clear_update_time() for more info. + */ void _clutter_stage_window_clear_update_time (ClutterStageWindow *window) { - ClutterStageWindowIface *iface; + ClutterStageWindowInterface *iface; g_return_if_fail (CLUTTER_IS_STAGE_WINDOW (window)); @@ -174,83 +178,27 @@ _clutter_stage_window_clear_update_time (ClutterStageWindow *window) iface->clear_update_time (window); } -void -_clutter_stage_window_add_redraw_clip (ClutterStageWindow *window, - cairo_rectangle_int_t *stage_clip) -{ - ClutterStageWindowIface *iface; - - g_return_if_fail (CLUTTER_IS_STAGE_WINDOW (window)); - - iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window); - if (iface->add_redraw_clip != NULL) - iface->add_redraw_clip (window, stage_clip); -} - -/* Determines if the backend will clip the rendering of the next - * frame. - * - * Note: at the start of each new frame there is an implied clip that - * clips everything (i.e. nothing would be drawn) so this function - * will return True at the start of a new frame if the backend - * supports clipped redraws. - */ -gboolean -_clutter_stage_window_has_redraw_clips (ClutterStageWindow *window) -{ - ClutterStageWindowIface *iface; - - g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), FALSE); - - iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window); - if (iface->has_redraw_clips != NULL) - return iface->has_redraw_clips (window); - - return FALSE; -} - -/* Determines if the backend will discard any additional redraw clips - * and instead promote them to a full stage redraw. - * - * The ideas is that backend may have some heuristics that cause it to - * give up tracking redraw clips so this can be used to avoid the cost - * of calculating a redraw clip when we know it's going to be ignored - * anyway. - */ -gboolean -_clutter_stage_window_ignoring_redraw_clips (ClutterStageWindow *window) +int64_t +_clutter_stage_window_get_next_presentation_time (ClutterStageWindow *window) { - ClutterStageWindowIface *iface; + ClutterStageWindowInterface *iface; - g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), FALSE); + g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), 0); iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window); - if (iface->ignoring_redraw_clips != NULL) - return iface->ignoring_redraw_clips (window); - - return TRUE; -} - -gboolean -_clutter_stage_window_get_redraw_clip_bounds (ClutterStageWindow *window, - cairo_rectangle_int_t *stage_clip) -{ - ClutterStageWindowIface *iface; - - g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), FALSE); - iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window); - if (iface->get_redraw_clip_bounds != NULL) - return iface->get_redraw_clip_bounds (window, stage_clip); + /* If not implemented then just revert to the old behaviour... */ + if (iface->get_next_presentation_time == NULL) + return _clutter_stage_window_get_update_time (window); - return FALSE; + return iface->get_next_presentation_time (window); } void _clutter_stage_window_set_accept_focus (ClutterStageWindow *window, gboolean accept_focus) { - ClutterStageWindowIface *iface; + ClutterStageWindowInterface *iface; g_return_if_fail (CLUTTER_IS_STAGE_WINDOW (window)); @@ -262,7 +210,7 @@ _clutter_stage_window_set_accept_focus (ClutterStageWindow *window, void _clutter_stage_window_redraw (ClutterStageWindow *window) { - ClutterStageWindowIface *iface; + ClutterStageWindowInterface *iface; g_return_if_fail (CLUTTER_IS_STAGE_WINDOW (window)); @@ -271,28 +219,10 @@ _clutter_stage_window_redraw (ClutterStageWindow *window) iface->redraw (window); } - -void -_clutter_stage_window_get_dirty_pixel (ClutterStageWindow *window, - ClutterStageView *view, - int *x, int *y) -{ - ClutterStageWindowIface *iface; - - *x = 0; - *y = 0; - - g_return_if_fail (CLUTTER_IS_STAGE_WINDOW (window)); - - iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window); - if (iface->get_dirty_pixel) - iface->get_dirty_pixel (window, view, x, y); -} - gboolean _clutter_stage_window_can_clip_redraws (ClutterStageWindow *window) { - ClutterStageWindowIface *iface; + ClutterStageWindowInterface *iface; g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), FALSE); @@ -306,7 +236,7 @@ _clutter_stage_window_can_clip_redraws (ClutterStageWindow *window) GList * _clutter_stage_window_get_views (ClutterStageWindow *window) { - ClutterStageWindowIface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window); + ClutterStageWindowInterface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window); return iface->get_views (window); } @@ -314,7 +244,7 @@ _clutter_stage_window_get_views (ClutterStageWindow *window) void _clutter_stage_window_finish_frame (ClutterStageWindow *window) { - ClutterStageWindowIface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window); + ClutterStageWindowInterface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window); if (iface->finish_frame) iface->finish_frame (window); @@ -323,7 +253,7 @@ _clutter_stage_window_finish_frame (ClutterStageWindow *window) int64_t _clutter_stage_window_get_frame_counter (ClutterStageWindow *window) { - ClutterStageWindowIface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window); + ClutterStageWindowInterface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window); if (iface->get_frame_counter) return iface->get_frame_counter (window); diff --git a/clutter/clutter/clutter-stage-window.h b/clutter/clutter/clutter-stage-window.h index 33234759d..78d15b743 100644 --- a/clutter/clutter/clutter-stage-window.h +++ b/clutter/clutter/clutter-stage-window.h @@ -7,30 +7,21 @@ G_BEGIN_DECLS -#define CLUTTER_TYPE_STAGE_WINDOW (_clutter_stage_window_get_type ()) -#define CLUTTER_STAGE_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_STAGE_WINDOW, ClutterStageWindow)) -#define CLUTTER_IS_STAGE_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_STAGE_WINDOW)) -#define CLUTTER_STAGE_WINDOW_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), CLUTTER_TYPE_STAGE_WINDOW, ClutterStageWindowIface)) +#define CLUTTER_TYPE_STAGE_WINDOW (clutter_stage_window_get_type ()) -/* - * ClutterStageWindow: (skip) - * - * #ClutterStageWindow is an opaque structure - * whose members should not be accessed directly - * - * Since: 0.8 - */ -typedef struct _ClutterStageWindow ClutterStageWindow; /* dummy */ -typedef struct _ClutterStageWindowIface ClutterStageWindowIface; +CLUTTER_EXPORT +G_DECLARE_INTERFACE (ClutterStageWindow, clutter_stage_window, + CLUTTER, STAGE_WINDOW, + GObject) /* - * ClutterStageWindowIface: (skip) + * ClutterStageWindowInterface: (skip) * * The interface implemented by backends for stage windows * * Since: 0.8 */ -struct _ClutterStageWindowIface +struct _ClutterStageWindowInterface { /*< private >*/ GTypeInterface parent_iface; @@ -39,12 +30,8 @@ struct _ClutterStageWindowIface void (* set_title) (ClutterStageWindow *stage_window, const gchar *title); - void (* set_fullscreen) (ClutterStageWindow *stage_window, - gboolean is_fullscreen); void (* set_cursor_visible) (ClutterStageWindow *stage_window, gboolean cursor_visible); - void (* set_user_resizable) (ClutterStageWindow *stage_window, - gboolean is_resizable); gboolean (* realize) (ClutterStageWindow *stage_window); void (* unrealize) (ClutterStageWindow *stage_window); @@ -64,43 +51,26 @@ struct _ClutterStageWindowIface gint64 (* get_update_time) (ClutterStageWindow *stage_window); void (* clear_update_time) (ClutterStageWindow *stage_window); - void (* add_redraw_clip) (ClutterStageWindow *stage_window, - cairo_rectangle_int_t *stage_rectangle); - gboolean (* has_redraw_clips) (ClutterStageWindow *stage_window); - gboolean (* ignoring_redraw_clips) (ClutterStageWindow *stage_window); - gboolean (* get_redraw_clip_bounds) (ClutterStageWindow *stage_window, - cairo_rectangle_int_t *clip); - - void (* set_accept_focus) (ClutterStageWindow *stage_window, gboolean accept_focus); void (* redraw) (ClutterStageWindow *stage_window); - void (* get_dirty_pixel) (ClutterStageWindow *stage_window, - ClutterStageView *view, - int *x, int *y); - gboolean (* can_clip_redraws) (ClutterStageWindow *stage_window); GList *(* get_views) (ClutterStageWindow *stage_window); int64_t (* get_frame_counter) (ClutterStageWindow *stage_window); void (* finish_frame) (ClutterStageWindow *stage_window); -}; -CLUTTER_AVAILABLE_IN_MUFFIN -GType _clutter_stage_window_get_type (void) G_GNUC_CONST; + int64_t (* get_next_presentation_time) (ClutterStageWindow *stage_window); +}; ClutterActor * _clutter_stage_window_get_wrapper (ClutterStageWindow *window); void _clutter_stage_window_set_title (ClutterStageWindow *window, const gchar *title); -void _clutter_stage_window_set_fullscreen (ClutterStageWindow *window, - gboolean is_fullscreen); void _clutter_stage_window_set_cursor_visible (ClutterStageWindow *window, gboolean is_visible); -void _clutter_stage_window_set_user_resizable (ClutterStageWindow *window, - gboolean is_resizable); gboolean _clutter_stage_window_realize (ClutterStageWindow *window); void _clutter_stage_window_unrealize (ClutterStageWindow *window); @@ -112,6 +82,7 @@ void _clutter_stage_window_hide (ClutterStageWin void _clutter_stage_window_resize (ClutterStageWindow *window, gint width, gint height); +CLUTTER_EXPORT void _clutter_stage_window_get_geometry (ClutterStageWindow *window, cairo_rectangle_int_t *geometry); void _clutter_stage_window_schedule_update (ClutterStageWindow *window, @@ -119,22 +90,11 @@ void _clutter_stage_window_schedule_update (ClutterStageWin gint64 _clutter_stage_window_get_update_time (ClutterStageWindow *window); void _clutter_stage_window_clear_update_time (ClutterStageWindow *window); -void _clutter_stage_window_add_redraw_clip (ClutterStageWindow *window, - cairo_rectangle_int_t *stage_clip); -gboolean _clutter_stage_window_has_redraw_clips (ClutterStageWindow *window); -gboolean _clutter_stage_window_ignoring_redraw_clips (ClutterStageWindow *window); -gboolean _clutter_stage_window_get_redraw_clip_bounds (ClutterStageWindow *window, - cairo_rectangle_int_t *clip); - void _clutter_stage_window_set_accept_focus (ClutterStageWindow *window, gboolean accept_focus); void _clutter_stage_window_redraw (ClutterStageWindow *window); -void _clutter_stage_window_get_dirty_pixel (ClutterStageWindow *window, - ClutterStageView *view, - int *x, int *y); - gboolean _clutter_stage_window_can_clip_redraws (ClutterStageWindow *window); GList * _clutter_stage_window_get_views (ClutterStageWindow *window); @@ -143,6 +103,8 @@ void _clutter_stage_window_finish_frame (ClutterStageWin int64_t _clutter_stage_window_get_frame_counter (ClutterStageWindow *window); +int64_t _clutter_stage_window_get_next_presentation_time (ClutterStageWindow *window); + G_END_DECLS #endif /* __CLUTTER_STAGE_WINDOW_H__ */ diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c index bc135b45c..9723ce49e 100644 --- a/clutter/clutter/clutter-stage.c +++ b/clutter/clutter/clutter-stage.c @@ -36,15 +36,13 @@ * using clutter_actor_destroy(), which will take care of destroying all the * actors contained inside them. * - * #ClutterStage is a proxy actor, wrapping the backend-specific - * implementation of the windowing system. It is possible to subclass - * #ClutterStage, as long as every overridden virtual function chains up to - * the parent class corresponding function. + * #ClutterStage is a proxy actor, wrapping the backend-specific implementation + * (a #StageWindow) of the windowing system. It is possible to subclass + * #ClutterStage, as long as every overridden virtual function chains up to the + * parent class corresponding function. */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include #include @@ -62,42 +60,25 @@ #include "clutter-color.h" #include "clutter-container.h" #include "clutter-debug.h" -#include "clutter-device-manager-private.h" #include "clutter-enum-types.h" #include "clutter-event-private.h" #include "clutter-id-pool.h" +#include "clutter-input-device-private.h" #include "clutter-main.h" #include "clutter-marshal.h" #include "clutter-master-clock.h" -#include "clutter-muffin.h" +#include "clutter-mutter.h" +#include "clutter-paint-context-private.h" #include "clutter-paint-volume-private.h" +#include "clutter-pick-context-private.h" #include "clutter-private.h" #include "clutter-stage-manager-private.h" #include "clutter-stage-private.h" -#include "clutter-version.h" /* For flavour */ +#include "clutter-stage-view-private.h" #include "clutter-private.h" #include "cogl/cogl.h" -/* - * ClutterStageHint: - * @CLUTTER_STAGE_NONE: No hint set - * @CLUTTER_STAGE_NO_CLEAR_ON_PAINT: When this hint is set, the stage - * should not clear the viewport; this flag is useful when painting - * fully opaque actors covering the whole visible area of the stage, - * i.e. when no blending with the stage color happens over the whole - * stage viewport - * - * A series of hints that enable or disable behaviours on the stage - */ -typedef enum { /*< prefix=CLUTTER_STAGE >*/ - CLUTTER_STAGE_HINT_NONE = 0, - - CLUTTER_STAGE_NO_CLEAR_ON_PAINT = 1 << 0 -} ClutterStageHint; - -#define STAGE_NO_CLEAR_ON_PAINT(s) ((((ClutterStage *) (s))->priv->stage_hints & CLUTTER_STAGE_NO_CLEAR_ON_PAINT) != 0) - struct _ClutterStageQueueRedrawEntry { ClutterActor *actor; @@ -105,6 +86,19 @@ struct _ClutterStageQueueRedrawEntry ClutterPaintVolume clip; }; +typedef struct _PickRecord +{ + graphene_point_t vertex[4]; + ClutterActor *actor; + int clip_stack_top; +} PickRecord; + +typedef struct _PickClipRecord +{ + int prev; + graphene_point_t vertex[4]; +} PickClipRecord; + struct _ClutterStagePrivate { /* the stage implementation */ @@ -116,29 +110,29 @@ struct _ClutterStagePrivate CoglMatrix view; float viewport[4]; - ClutterFog fog; - gchar *title; ClutterActor *key_focused_actor; GQueue *event_queue; - ClutterStageHint stage_hints; - GArray *paint_volume_stack; ClutterPlane current_clip_planes[4]; + GHashTable *pending_relayouts; + unsigned int pending_relayouts_version; GList *pending_queue_redraws; - CoglFramebuffer *active_framebuffer; - gint sync_delay; GTimer *fps_timer; gint32 timer_n_frames; - ClutterIDPool *pick_id_pool; + GArray *pick_stack; + GArray *pick_clip_stack; + int pick_clip_stack_top; + gboolean pick_stack_frozen; + ClutterPickMode cached_pick_mode; #ifdef CLUTTER_ENABLE_DEBUG gulong redraw_count; @@ -149,12 +143,12 @@ struct _ClutterStagePrivate gpointer paint_data; GDestroyNotify paint_notify; - guint relayout_pending : 1; + int update_freeze_count; + + gboolean needs_update; + guint redraw_pending : 1; - guint is_fullscreen : 1; guint is_cursor_visible : 1; - guint is_user_resizable : 1; - guint use_fog : 1; guint throttle_motion_events : 1; guint use_alpha : 1; guint min_size_changed : 1; @@ -169,28 +163,24 @@ enum PROP_0, PROP_COLOR, - PROP_FULLSCREEN_SET, - PROP_OFFSCREEN, PROP_CURSOR_VISIBLE, PROP_PERSPECTIVE, PROP_TITLE, - PROP_USER_RESIZABLE, - PROP_USE_FOG, - PROP_FOG, PROP_USE_ALPHA, PROP_KEY_FOCUS, - PROP_NO_CLEAR_HINT, - PROP_ACCEPT_FOCUS + PROP_ACCEPT_FOCUS, + PROP_LAST }; +static GParamSpec *obj_props[PROP_LAST] = { NULL, }; + enum { - FULLSCREEN, - UNFULLSCREEN, ACTIVATE, DEACTIVATE, DELETE_EVENT, AFTER_PAINT, + PAINT_VIEW, PRESENTED, LAST_SIGNAL @@ -202,6 +192,13 @@ static const ClutterColor default_stage_color = { 255, 255, 255, 255 }; static void clutter_stage_maybe_finish_queue_redraws (ClutterStage *stage); static void free_queue_redraw_entry (ClutterStageQueueRedrawEntry *entry); +static void capture_view_into (ClutterStage *stage, + gboolean paint, + ClutterStageView *view, + cairo_rectangle_int_t *rect, + uint8_t *data, + int stride); +static void clutter_stage_update_view_perspective (ClutterStage *stage); static void clutter_container_iface_init (ClutterContainerIface *iface); @@ -224,20 +221,6 @@ clutter_stage_real_remove (ClutterContainer *container, clutter_actor_remove_child (CLUTTER_ACTOR (container), child); } -static void -clutter_stage_real_foreach (ClutterContainer *container, - ClutterCallback callback, - gpointer user_data) -{ - ClutterActorIter iter; - ClutterActor *child; - - clutter_actor_iter_init (&iter, CLUTTER_ACTOR (container)); - - while (clutter_actor_iter_next (&iter, &child)) - callback (child, user_data); -} - static void clutter_stage_real_raise (ClutterContainer *container, ClutterActor *child, @@ -268,7 +251,6 @@ clutter_container_iface_init (ClutterContainerIface *iface) { iface->add = clutter_stage_real_add; iface->remove = clutter_stage_real_remove; - iface->foreach = clutter_stage_real_foreach; iface->raise = clutter_stage_real_raise; iface->lower = clutter_stage_real_lower; iface->sort_depth_order = clutter_stage_real_sort_depth_order; @@ -316,6 +298,293 @@ clutter_stage_get_preferred_height (ClutterActor *self, *natural_height_p = geom.height; } +static void +add_pick_stack_weak_refs (ClutterStage *stage) +{ + ClutterStagePrivate *priv = stage->priv; + int i; + + if (priv->pick_stack_frozen) + return; + + for (i = 0; i < priv->pick_stack->len; i++) + { + PickRecord *rec = &g_array_index (priv->pick_stack, PickRecord, i); + + if (rec->actor) + g_object_add_weak_pointer (G_OBJECT (rec->actor), + (gpointer) &rec->actor); + } + + priv->pick_stack_frozen = TRUE; +} + +static void +remove_pick_stack_weak_refs (ClutterStage *stage) +{ + ClutterStagePrivate *priv = stage->priv; + int i; + + if (!priv->pick_stack_frozen) + return; + + for (i = 0; i < priv->pick_stack->len; i++) + { + PickRecord *rec = &g_array_index (priv->pick_stack, PickRecord, i); + + if (rec->actor) + g_object_remove_weak_pointer (G_OBJECT (rec->actor), + (gpointer) &rec->actor); + } + + priv->pick_stack_frozen = FALSE; +} + +static void +_clutter_stage_clear_pick_stack (ClutterStage *stage) +{ + ClutterStagePrivate *priv = stage->priv; + + remove_pick_stack_weak_refs (stage); + g_array_set_size (priv->pick_stack, 0); + g_array_set_size (priv->pick_clip_stack, 0); + priv->pick_clip_stack_top = -1; + priv->cached_pick_mode = CLUTTER_PICK_NONE; +} + +void +clutter_stage_log_pick (ClutterStage *stage, + const graphene_point_t *vertices, + ClutterActor *actor) +{ + ClutterStagePrivate *priv; + PickRecord rec; + + g_return_if_fail (CLUTTER_IS_STAGE (stage)); + g_return_if_fail (actor != NULL); + + priv = stage->priv; + + g_assert (!priv->pick_stack_frozen); + + memcpy (rec.vertex, vertices, 4 * sizeof (graphene_point_t)); + rec.actor = actor; + rec.clip_stack_top = priv->pick_clip_stack_top; + + g_array_append_val (priv->pick_stack, rec); +} + +void +clutter_stage_push_pick_clip (ClutterStage *stage, + const graphene_point_t *vertices) +{ + ClutterStagePrivate *priv; + PickClipRecord clip; + + g_return_if_fail (CLUTTER_IS_STAGE (stage)); + + priv = stage->priv; + + g_assert (!priv->pick_stack_frozen); + + clip.prev = priv->pick_clip_stack_top; + memcpy (clip.vertex, vertices, 4 * sizeof (graphene_point_t)); + + g_array_append_val (priv->pick_clip_stack, clip); + priv->pick_clip_stack_top = priv->pick_clip_stack->len - 1; +} + +void +clutter_stage_pop_pick_clip (ClutterStage *stage) +{ + ClutterStagePrivate *priv; + const PickClipRecord *top; + + g_return_if_fail (CLUTTER_IS_STAGE (stage)); + + priv = stage->priv; + + g_assert (!priv->pick_stack_frozen); + g_assert (priv->pick_clip_stack_top >= 0); + + /* Individual elements of pick_clip_stack are not freed. This is so they + * can be shared as part of a tree of different stacks used by different + * actors in the pick_stack. The whole pick_clip_stack does however get + * freed later in _clutter_stage_clear_pick_stack. + */ + + top = &g_array_index (priv->pick_clip_stack, + PickClipRecord, + priv->pick_clip_stack_top); + + priv->pick_clip_stack_top = top->prev; +} + +static gboolean +is_quadrilateral_axis_aligned_rectangle (const graphene_point_t *vertices) +{ + int i; + + for (i = 0; i < 4; i++) + { + if (!G_APPROX_VALUE (vertices[i].x, + vertices[(i + 1) % 4].x, + FLT_EPSILON) && + !G_APPROX_VALUE (vertices[i].y, + vertices[(i + 1) % 4].y, + FLT_EPSILON)) + return FALSE; + } + return TRUE; +} + +static gboolean +is_inside_axis_aligned_rectangle (const graphene_point_t *point, + const graphene_point_t *vertices) +{ + float min_x = FLT_MAX; + float max_x = -FLT_MAX; + float min_y = FLT_MAX; + float max_y = -FLT_MAX; + int i; + + for (i = 0; i < 3; i++) + { + min_x = MIN (min_x, vertices[i].x); + min_y = MIN (min_y, vertices[i].y); + max_x = MAX (max_x, vertices[i].x); + max_y = MAX (max_y, vertices[i].y); + } + + return (point->x >= min_x && + point->y >= min_y && + point->x < max_x && + point->y < max_y); +} + +static int +clutter_point_compare_line (const graphene_point_t *p, + const graphene_point_t *a, + const graphene_point_t *b) +{ + graphene_vec3_t vec_pa; + graphene_vec3_t vec_pb; + graphene_vec3_t cross; + float cross_z; + + graphene_vec3_init (&vec_pa, p->x - a->x, p->y - a->y, 0.f); + graphene_vec3_init (&vec_pb, p->x - b->x, p->y - b->y, 0.f); + graphene_vec3_cross (&vec_pa, &vec_pb, &cross); + cross_z = graphene_vec3_get_z (&cross); + + if (cross_z > 0.f) + return 1; + else if (cross_z < 0.f) + return -1; + else + return 0; +} + +static gboolean +is_inside_unaligned_rectangle (const graphene_point_t *point, + const graphene_point_t *vertices) +{ + unsigned int i; + int first_side; + + first_side = 0; + + for (i = 0; i < 4; i++) + { + int side; + + side = clutter_point_compare_line (point, + &vertices[i], + &vertices[(i + 1) % 4]); + + if (side) + { + if (first_side == 0) + first_side = side; + else if (side != first_side) + return FALSE; + } + } + + if (first_side == 0) + return FALSE; + + return TRUE; +} + +static gboolean +is_inside_input_region (const graphene_point_t *point, + const graphene_point_t *vertices) +{ + + if (is_quadrilateral_axis_aligned_rectangle (vertices)) + return is_inside_axis_aligned_rectangle (point, vertices); + else + return is_inside_unaligned_rectangle (point, vertices); +} + +static gboolean +pick_record_contains_point (ClutterStage *stage, + const PickRecord *rec, + float x, + float y) +{ + const graphene_point_t point = GRAPHENE_POINT_INIT (x, y); + ClutterStagePrivate *priv; + int clip_index; + + if (!is_inside_input_region (&point, rec->vertex)) + return FALSE; + + priv = stage->priv; + clip_index = rec->clip_stack_top; + while (clip_index >= 0) + { + const PickClipRecord *clip = &g_array_index (priv->pick_clip_stack, + PickClipRecord, + clip_index); + + if (!is_inside_input_region (&point, clip->vertex)) + return FALSE; + + clip_index = clip->prev; + } + + return TRUE; +} + +static void +clutter_stage_add_redraw_clip (ClutterStage *stage, + cairo_rectangle_int_t *clip) +{ + GList *l; + + for (l = _clutter_stage_peek_stage_views (stage); l; l = l->next) + { + ClutterStageView *view = l->data; + + if (!clip) + { + clutter_stage_view_add_redraw_clip (view, NULL); + } + else + { + cairo_rectangle_int_t view_layout; + cairo_rectangle_int_t intersection; + + clutter_stage_view_get_layout (view, &view_layout); + if (_clutter_util_rectangle_intersection (&view_layout, clip, + &intersection)) + clutter_stage_view_add_redraw_clip (view, &intersection); + } + } +} + static inline void queue_full_redraw (ClutterStage *stage) { @@ -334,7 +603,7 @@ queue_full_redraw (ClutterStage *stage) if (stage_window == NULL) return; - _clutter_stage_window_add_redraw_clip (stage_window, NULL); + clutter_stage_add_redraw_clip (stage, NULL); } static gboolean @@ -386,53 +655,48 @@ clutter_stage_allocate (ClutterActor *self, */ if (!clutter_feature_available (CLUTTER_FEATURE_STAGE_STATIC)) { -#ifdef CLUTTER_ENABLE_DEBUG CLUTTER_NOTE (LAYOUT, "Following allocation to %.2fx%.2f (absolute origin %s)", width, height, (flags & CLUTTER_ABSOLUTE_ORIGIN_CHANGED) ? "changed" : "not changed"); -#endif clutter_actor_set_allocation (self, box, flags | CLUTTER_DELEGATE_LAYOUT); /* Ensure the window is sized correctly */ - if (!priv->is_fullscreen) + if (priv->min_size_changed) { - if (priv->min_size_changed) - { - gfloat min_width, min_height; - gboolean min_width_set, min_height_set; - - g_object_get (G_OBJECT (self), - "min-width", &min_width, - "min-width-set", &min_width_set, - "min-height", &min_height, - "min-height-set", &min_height_set, - NULL); - - if (!min_width_set) - min_width = 1; - if (!min_height_set) - min_height = 1; - - if (width < min_width) - width = min_width; - if (height < min_height) - height = min_height; - - priv->min_size_changed = FALSE; - } + gfloat min_width, min_height; + gboolean min_width_set, min_height_set; + + g_object_get (G_OBJECT (self), + "min-width", &min_width, + "min-width-set", &min_width_set, + "min-height", &min_height, + "min-height-set", &min_height_set, + NULL); + + if (!min_width_set) + min_width = 1; + if (!min_height_set) + min_height = 1; + + if (width < min_width) + width = min_width; + if (height < min_height) + height = min_height; + + priv->min_size_changed = FALSE; + } - if (window_size.width != CLUTTER_NEARBYINT (width) || - window_size.height != CLUTTER_NEARBYINT (height)) - { - _clutter_stage_window_resize (priv->impl, - CLUTTER_NEARBYINT (width), - CLUTTER_NEARBYINT (height)); - } + if (window_size.width != CLUTTER_NEARBYINT (width) || + window_size.height != CLUTTER_NEARBYINT (height)) + { + _clutter_stage_window_resize (priv->impl, + CLUTTER_NEARBYINT (width), + CLUTTER_NEARBYINT (height)); } } else @@ -445,7 +709,6 @@ clutter_stage_allocate (ClutterActor *self, override.x2 = window_size.width; override.y2 = window_size.height; -#ifdef CLUTTER_ENABLE_DEBUG CLUTTER_NOTE (LAYOUT, "Overriding original allocation of %.2fx%.2f " "with %.2fx%.2f (absolute origin %s)", @@ -454,24 +717,12 @@ clutter_stage_allocate (ClutterActor *self, (flags & CLUTTER_ABSOLUTE_ORIGIN_CHANGED) ? "changed" : "not changed"); -#endif /* and store the overridden allocation */ clutter_actor_set_allocation (self, &override, flags | CLUTTER_DELEGATE_LAYOUT); } - /* XXX: Until Cogl becomes fully responsible for backend windows - * Clutter need to manually keep it informed of the current window - * size. We do this after the allocation above so that the stage - * window has a chance to update the window size based on the - * allocation. - */ - _clutter_stage_window_get_geometry (priv->impl, &window_size); - - cogl_onscreen_clutter_backend_set_size (window_size.width, - window_size.height); - /* reset the viewport if the allocation effectively changed */ clutter_actor_get_allocation_box (self, &alloc); clutter_actor_box_get_size (&alloc, &new_width, &new_height); @@ -512,8 +763,9 @@ _cogl_util_get_eye_planes_for_screen_poly (float *polygon, Vector4 *tmp_poly; ClutterPlane *plane; int i; - float b[3]; - float c[3]; + Vector4 *poly; + graphene_vec3_t b; + graphene_vec3_t c; int count; tmp_poly = g_alloca (sizeof (Vector4) * n_vertices * 2); @@ -580,37 +832,37 @@ _cogl_util_get_eye_planes_for_screen_poly (float *polygon, for (i = 0; i < count; i++) { plane = &planes[i]; - memcpy (plane->v0, tmp_poly + i, sizeof (float) * 3); - memcpy (b, tmp_poly + n_vertices + i, sizeof (float) * 3); - memcpy (c, tmp_poly + n_vertices + i + 1, sizeof (float) * 3); - cogl_vector3_subtract (b, b, plane->v0); - cogl_vector3_subtract (c, c, plane->v0); - cogl_vector3_cross_product (plane->n, b, c); - cogl_vector3_normalize (plane->n); + + poly = &tmp_poly[i]; + graphene_vec3_init (&plane->v0, poly->x, poly->y, poly->z); + + poly = &tmp_poly[n_vertices + i]; + graphene_vec3_init (&b, poly->x, poly->y, poly->z); + + poly = &tmp_poly[n_vertices + i + 1]; + graphene_vec3_init (&c, poly->x, poly->y, poly->z); + + graphene_vec3_subtract (&b, &plane->v0, &b); + graphene_vec3_subtract (&c, &plane->v0, &c); + graphene_vec3_cross (&b, &c, &plane->n); + graphene_vec3_normalize (&plane->n, &plane->n); } plane = &planes[n_vertices - 1]; - memcpy (plane->v0, tmp_poly + 0, sizeof (float) * 3); - memcpy (b, tmp_poly + (2 * n_vertices - 1), sizeof (float) * 3); - memcpy (c, tmp_poly + n_vertices, sizeof (float) * 3); - cogl_vector3_subtract (b, b, plane->v0); - cogl_vector3_subtract (c, c, plane->v0); - cogl_vector3_cross_product (plane->n, b, c); - cogl_vector3_normalize (plane->n); -} -static void -_clutter_stage_update_active_framebuffer (ClutterStage *stage, - CoglFramebuffer *framebuffer) -{ - ClutterStagePrivate *priv = stage->priv; + poly = &tmp_poly[0]; + graphene_vec3_init (&plane->v0, poly->x, poly->y, poly->z); - /* We track the CoglFramebuffer that corresponds to the stage itself - * so, for example, we can disable culling when rendering to an - * offscreen framebuffer. - */ + poly = &tmp_poly[2 * n_vertices - 1]; + graphene_vec3_init (&b, poly->x, poly->y, poly->z); + + poly = &tmp_poly[n_vertices]; + graphene_vec3_init (&c, poly->x, poly->y, poly->z); - priv->active_framebuffer = framebuffer; + graphene_vec3_subtract (&b, &plane->v0, &b); + graphene_vec3_subtract (&c, &plane->v0, &c); + graphene_vec3_cross (&b, &c, &plane->n); + graphene_vec3_normalize (&plane->n, &plane->n); } /* XXX: Instead of having a toplevel 2D clip region, it might be @@ -619,17 +871,22 @@ _clutter_stage_update_active_framebuffer (ClutterStage *stage, * be able to cull them. */ static void -clutter_stage_do_paint_view (ClutterStage *stage, - ClutterStageView *view, - const cairo_rectangle_int_t *clip) +setup_view_for_pick_or_paint (ClutterStage *stage, + ClutterStageView *view, + const cairo_rectangle_int_t *clip) { ClutterStagePrivate *priv = stage->priv; - CoglFramebuffer *framebuffer = clutter_stage_view_get_framebuffer (view); cairo_rectangle_int_t view_layout; float clip_poly[8]; float viewport[4]; cairo_rectangle_int_t geom; + /* Any mode of painting/picking invalidates the pick cache, unless we're + * in the middle of building it. So we reset the cached flag but don't + * completely clear the pick stack. + */ + priv->cached_pick_mode = CLUTTER_PICK_NONE; + _clutter_stage_window_get_geometry (priv->impl, &geom); viewport[0] = priv->viewport[0]; @@ -669,24 +926,51 @@ clutter_stage_do_paint_view (ClutterStage *stage, priv->current_clip_planes); _clutter_stage_paint_volume_stack_free_all (stage); - _clutter_stage_update_active_framebuffer (stage, framebuffer); - clutter_actor_paint (CLUTTER_ACTOR (stage)); +} + +static void +clutter_stage_do_paint_view (ClutterStage *stage, + ClutterStageView *view, + const cairo_region_t *redraw_clip) +{ + ClutterPaintContext *paint_context; + cairo_rectangle_int_t clip_rect; + + paint_context = clutter_paint_context_new_for_view (view, redraw_clip, + CLUTTER_PAINT_FLAG_NONE); + + cairo_region_get_extents (redraw_clip, &clip_rect); + setup_view_for_pick_or_paint (stage, view, &clip_rect); + + clutter_actor_paint (CLUTTER_ACTOR (stage), paint_context); + clutter_paint_context_destroy (paint_context); } /* This provides a common point of entry for painting the scenegraph * for picking or painting... */ void -_clutter_stage_paint_view (ClutterStage *stage, - ClutterStageView *view, - const cairo_rectangle_int_t *clip) +clutter_stage_paint_view (ClutterStage *stage, + ClutterStageView *view, + const cairo_region_t *redraw_clip) { ClutterStagePrivate *priv = stage->priv; if (!priv->impl) return; - clutter_stage_do_paint_view (stage, view, clip); + COGL_TRACE_BEGIN_SCOPED (ClutterStagePaintView, "Paint (view)"); + + if (g_signal_has_handler_pending (stage, stage_signals[PAINT_VIEW], + 0, TRUE)) + g_signal_emit (stage, stage_signals[PAINT_VIEW], 0, view, redraw_clip); + else + CLUTTER_STAGE_GET_CLASS (stage)->paint_view (stage, view, redraw_clip); +} + +void +_clutter_stage_emit_after_paint (ClutterStage *stage) +{ g_signal_emit (stage, stage_signals[AFTER_PAINT], 0); } @@ -695,19 +979,20 @@ _clutter_stage_paint_view (ClutterStage *stage, * respect the Z order as it uses our empty sort_depth_order. */ static void -clutter_stage_paint (ClutterActor *self) +clutter_stage_paint (ClutterActor *self, + ClutterPaintContext *paint_context) { ClutterActorIter iter; ClutterActor *child; clutter_actor_iter_init (&iter, self); while (clutter_actor_iter_next (&iter, &child)) - clutter_actor_paint (child); + clutter_actor_paint (child, paint_context); } static void clutter_stage_pick (ClutterActor *self, - const ClutterColor *color) + ClutterPickContext *pick_context) { ClutterActorIter iter; ClutterActor *child; @@ -718,7 +1003,7 @@ clutter_stage_pick (ClutterActor *self, */ clutter_actor_iter_init (&iter, self); while (clutter_actor_iter_next (&iter, &child)) - clutter_actor_paint (child); + clutter_actor_pick (child, pick_context); } static gboolean @@ -822,12 +1107,9 @@ clutter_stage_emit_key_focus_event (ClutterStage *stage, if (priv->key_focused_actor == NULL) return; - if (focus_in) - g_signal_emit_by_name (priv->key_focused_actor, "key-focus-in"); - else - g_signal_emit_by_name (priv->key_focused_actor, "key-focus-out"); + _clutter_actor_set_has_key_focus (CLUTTER_ACTOR (stage), focus_in); - g_object_notify (G_OBJECT (stage), "key-focus"); + g_object_notify_by_pspec (G_OBJECT (stage), obj_props[PROP_KEY_FOCUS]); } static void @@ -842,40 +1124,6 @@ clutter_stage_real_deactivate (ClutterStage *stage) clutter_stage_emit_key_focus_event (stage, FALSE); } -static void -clutter_stage_real_fullscreen (ClutterStage *stage) -{ - ClutterStagePrivate *priv = stage->priv; - cairo_rectangle_int_t geom; - ClutterActorBox box; - - /* we need to force an allocation here because the size - * of the stage might have been changed by the backend - * - * this is a really bad solution to the issues caused by - * the fact that fullscreening the stage on the X11 backends - * is really an asynchronous operation - */ - _clutter_stage_window_get_geometry (priv->impl, &geom); - - box.x1 = 0; - box.y1 = 0; - box.x2 = geom.width; - box.y2 = geom.height; - - /* we need to blow the caching on the Stage size, given that - * we're about to force an allocation, because if anything - * ends up querying the size of the stage during the allocate() - * call, like constraints or signal handlers, we'll get into an - * inconsistent state: the stage will report the old cached size, - * but the allocation will be updated anyway. - */ - clutter_actor_set_size (CLUTTER_ACTOR (stage), -1.0, -1.0); - clutter_actor_allocate (CLUTTER_ACTOR (stage), - &box, - CLUTTER_ALLOCATION_NONE); -} - void _clutter_stage_queue_event (ClutterStage *stage, ClutterEvent *event, @@ -894,15 +1142,6 @@ _clutter_stage_queue_event (ClutterStage *stage, if (copy_event) event = clutter_event_copy (event); - g_queue_push_tail (priv->event_queue, event); - - if (first_event) - { - ClutterMasterClock *master_clock = _clutter_master_clock_get_default (); - _clutter_master_clock_start_running (master_clock); - _clutter_stage_schedule_update (stage); - } - /* if needed, update the state of the input device of the event. * we do it here to avoid calling the same code from every backend * event processing function @@ -923,6 +1162,28 @@ _clutter_stage_queue_event (ClutterStage *stage, _clutter_input_device_set_state (device, event_state); _clutter_input_device_set_time (device, event_time); } + + if (first_event) + { + gboolean compressible = event->type == CLUTTER_MOTION || + event->type == CLUTTER_TOUCH_UPDATE; + + if (!compressible) + { + _clutter_process_event (event); + clutter_event_free (event); + return; + } + } + + g_queue_push_tail (priv->event_queue, event); + + if (first_event) + { + ClutterMasterClock *master_clock = _clutter_master_clock_get_default (); + _clutter_master_clock_start_running (master_clock); + clutter_stage_schedule_update (stage); + } } gboolean @@ -1005,11 +1266,9 @@ _clutter_stage_process_queued_events (ClutterStage *stage) if (next_event->type == CLUTTER_MOTION) { - ClutterDeviceManager *device_manager = - clutter_device_manager_get_default (); + ClutterSeat *seat = clutter_input_device_get_seat (device); - _clutter_device_manager_compress_motion (device_manager, - next_event, event); + clutter_seat_compress_motion (seat, next_event, event); } goto next_event; @@ -1055,7 +1314,22 @@ _clutter_stage_needs_update (ClutterStage *stage) priv = stage->priv; - return priv->relayout_pending || priv->redraw_pending; + return (priv->redraw_pending || + priv->needs_update || + g_hash_table_size (priv->pending_relayouts) > 0); +} + +void +clutter_stage_queue_actor_relayout (ClutterStage *stage, + ClutterActor *actor) +{ + ClutterStagePrivate *priv = stage->priv; + + if (g_hash_table_size (priv->pending_relayouts) == 0) + clutter_stage_schedule_update (stage); + + g_hash_table_add (priv->pending_relayouts, g_object_ref (actor)); + priv->pending_relayouts_version++; } void @@ -1063,45 +1337,58 @@ _clutter_stage_maybe_relayout (ClutterActor *actor) { ClutterStage *stage = CLUTTER_STAGE (actor); ClutterStagePrivate *priv = stage->priv; - gfloat natural_width, natural_height; - ClutterActorBox box = { 0, }; + GHashTableIter iter; + gpointer key; + int count = 0; - if (!priv->relayout_pending) + /* No work to do? Avoid the extraneous debug log messages too. */ + if (g_hash_table_size (priv->pending_relayouts) == 0) return; - /* avoid reentrancy */ - if (!CLUTTER_ACTOR_IN_RELAYOUT (stage)) + CLUTTER_NOTE (ACTOR, ">>> Recomputing layout"); + + g_hash_table_iter_init (&iter, priv->pending_relayouts); + while (g_hash_table_iter_next (&iter, &key, NULL)) { - priv->relayout_pending = FALSE; - priv->stage_was_relayout = TRUE; + g_autoptr (ClutterActor) queued_actor = key; + unsigned int old_version; -#ifdef CLUTTER_ENABLE_DEBUG - CLUTTER_NOTE (ACTOR, "Recomputing layout"); -#endif + g_hash_table_iter_steal (&iter); + priv->pending_relayouts_version++; - CLUTTER_SET_PRIVATE_FLAGS (stage, CLUTTER_IN_RELAYOUT); + if (CLUTTER_ACTOR_IN_RELAYOUT (queued_actor)) /* avoid reentrancy */ + continue; - natural_width = natural_height = 0; - clutter_actor_get_preferred_size (CLUTTER_ACTOR (stage), - NULL, NULL, - &natural_width, &natural_height); + /* An actor may have been destroyed or hidden between queuing and now */ + if (clutter_actor_get_stage (queued_actor) != actor) + continue; - box.x1 = 0; - box.y1 = 0; - box.x2 = natural_width; - box.y2 = natural_height; + if (queued_actor == actor) + CLUTTER_NOTE (ACTOR, " Deep relayout of stage %s", + _clutter_actor_get_debug_name (queued_actor)); + else + CLUTTER_NOTE (ACTOR, " Shallow relayout of actor %s", + _clutter_actor_get_debug_name (queued_actor)); -#ifdef CLUTTER_ENABLE_DEBUG - CLUTTER_NOTE (ACTOR, "Allocating (0, 0 - %d, %d) for the stage", - (int) natural_width, - (int) natural_height); -#endif + CLUTTER_SET_PRIVATE_FLAGS (queued_actor, CLUTTER_IN_RELAYOUT); - clutter_actor_allocate (CLUTTER_ACTOR (stage), - &box, CLUTTER_ALLOCATION_NONE); + old_version = priv->pending_relayouts_version; + clutter_actor_allocate_preferred_size (queued_actor, + CLUTTER_ALLOCATION_NONE); - CLUTTER_UNSET_PRIVATE_FLAGS (stage, CLUTTER_IN_RELAYOUT); + CLUTTER_UNSET_PRIVATE_FLAGS (queued_actor, CLUTTER_IN_RELAYOUT); + + count++; + + /* Prevent using an iterator that's been invalidated */ + if (old_version != priv->pending_relayouts_version) + g_hash_table_iter_init (&iter, priv->pending_relayouts); } + + CLUTTER_NOTE (ACTOR, "<<< Completed recomputing layout of %d subtrees", count); + + if (count) + priv->stage_was_relayout = TRUE; } static void @@ -1109,7 +1396,6 @@ clutter_stage_do_redraw (ClutterStage *stage) { ClutterActor *actor = CLUTTER_ACTOR (stage); ClutterStagePrivate *priv = stage->priv; - static gboolean show_fps; if (CLUTTER_ACTOR_IN_DESTRUCTION (stage)) return; @@ -1117,21 +1403,20 @@ clutter_stage_do_redraw (ClutterStage *stage) if (priv->impl == NULL) return; - show_fps = _clutter_context_get_show_fps (); - -#ifdef CLUTTER_ENABLE_DEBUG CLUTTER_NOTE (PAINT, "Redraw started for stage '%s'[%p]", _clutter_actor_get_debug_name (actor), stage); -#endif - if (show_fps) + if (_clutter_context_get_show_fps ()) { if (priv->fps_timer == NULL) priv->fps_timer = g_timer_new (); + } - _clutter_stage_window_redraw (priv->impl); + _clutter_stage_window_redraw (priv->impl); + if (_clutter_context_get_show_fps ()) + { priv->timer_n_frames += 1; if (g_timer_elapsed (priv->fps_timer, NULL) >= 1.0) @@ -1143,37 +1428,31 @@ clutter_stage_do_redraw (ClutterStage *stage) priv->timer_n_frames = 0; g_timer_start (priv->fps_timer); } - return; } - _clutter_stage_window_redraw (priv->impl); - -#ifdef CLUTTER_ENABLE_DEBUG CLUTTER_NOTE (PAINT, "Redraw finished for stage '%s'[%p]", _clutter_actor_get_debug_name (actor), stage); -#endif } static GSList * _clutter_stage_check_updated_pointers (ClutterStage *stage) { - ClutterStagePrivate *priv = stage->priv; - ClutterDeviceManager *device_manager; + ClutterBackend *backend; + ClutterSeat *seat; GSList *updating = NULL; - const GSList *devices; - cairo_rectangle_int_t clip; - ClutterPoint point; - gboolean has_clip; - - has_clip = _clutter_stage_window_get_redraw_clip_bounds (priv->impl, &clip); + GList *l, *devices; + graphene_point_t point; - device_manager = clutter_device_manager_get_default (); - devices = clutter_device_manager_peek_devices (device_manager); + backend = clutter_get_default_backend (); + seat = clutter_backend_get_default_seat (backend); + devices = clutter_seat_list_devices (seat); - for (; devices != NULL; devices = devices->next) + for (l = devices; l; l = l->next) { - ClutterInputDevice *dev = devices->data; + ClutterInputDevice *dev = l->data; + ClutterStageView *view; + const cairo_region_t *clip; if (clutter_input_device_get_device_mode (dev) != CLUTTER_INPUT_MODE_MASTER) @@ -1189,9 +1468,12 @@ _clutter_stage_check_updated_pointers (ClutterStage *stage) if (!clutter_input_device_get_coords (dev, NULL, &point)) continue; - if (!has_clip || - (point.x >= clip.x && point.x < clip.x + clip.width && - point.y >= clip.y && point.y < clip.y + clip.height)) + view = clutter_stage_get_view_at (stage, point.x, point.y); + if (!view) + continue; + + clip = clutter_stage_view_peek_redraw_clip (view); + if (!clip || cairo_region_contains_point (clip, point.x, point.y)) updating = g_slist_prepend (updating, dev); break; default: @@ -1204,6 +1486,8 @@ _clutter_stage_check_updated_pointers (ClutterStage *stage) } } + g_list_free (devices); + return updating; } @@ -1224,6 +1508,8 @@ _clutter_stage_do_update (ClutterStage *stage) priv->stage_was_relayout = FALSE; + priv->needs_update = FALSE; + /* if the stage is being destroyed, or if the destruction already * happened and we don't have an StageWindow any more, then we * should bail out @@ -1234,22 +1520,31 @@ _clutter_stage_do_update (ClutterStage *stage) if (!CLUTTER_ACTOR_IS_REALIZED (stage)) return FALSE; + COGL_TRACE_BEGIN_SCOPED (ClutterStageDoUpdate, "Update"); + /* NB: We need to ensure we have an up to date layout *before* we * check or clear the pending redraws flag since a relayout may * queue a redraw. */ + COGL_TRACE_BEGIN (ClutterStageRelayout, "Layout"); + _clutter_stage_maybe_relayout (CLUTTER_ACTOR (stage)); + COGL_TRACE_END (ClutterStageRelayout); + if (!priv->redraw_pending) return FALSE; if (stage_was_relayout) pointers = _clutter_stage_check_updated_pointers (stage); - clutter_stage_maybe_finish_queue_redraws (stage); + COGL_TRACE_BEGIN (ClutterStagePaint, "Paint"); + clutter_stage_maybe_finish_queue_redraws (stage); clutter_stage_do_redraw (stage); + COGL_TRACE_END (ClutterStagePaint); + /* reset the guard, so that new redraws are possible */ priv->redraw_pending = FALSE; @@ -1263,12 +1558,16 @@ _clutter_stage_do_update (ClutterStage *stage) } #endif /* CLUTTER_ENABLE_DEBUG */ + COGL_TRACE_BEGIN (ClutterStagePick, "Pick"); + while (pointers) { - _clutter_input_device_update (pointers->data, NULL, TRUE); + clutter_input_device_update (pointers->data, NULL, TRUE); pointers = g_slist_delete_link (pointers, pointers); } + COGL_TRACE_END (ClutterStagePick); + return TRUE; } @@ -1276,60 +1575,66 @@ static void clutter_stage_real_queue_relayout (ClutterActor *self) { ClutterStage *stage = CLUTTER_STAGE (self); - ClutterStagePrivate *priv = stage->priv; ClutterActorClass *parent_class; - if (!priv->relayout_pending) - { - _clutter_stage_schedule_update (stage); - priv->relayout_pending = TRUE; - } + clutter_stage_queue_actor_relayout (stage, self); /* chain up */ parent_class = CLUTTER_ACTOR_CLASS (clutter_stage_parent_class); parent_class->queue_relayout (self); } -static void -clutter_stage_real_queue_redraw (ClutterActor *actor, - ClutterActor *leaf) +static gboolean +is_full_stage_redraw_queued (ClutterStage *stage) +{ + GList *l; + + for (l = _clutter_stage_peek_stage_views (stage); l; l = l->next) + { + ClutterStageView *view = l->data; + + if (!clutter_stage_view_has_full_redraw_clip (view)) + return FALSE; + } + + return TRUE; +} + +static gboolean +clutter_stage_real_queue_redraw (ClutterActor *actor, + ClutterActor *leaf, + ClutterPaintVolume *redraw_clip) { ClutterStage *stage = CLUTTER_STAGE (actor); ClutterStageWindow *stage_window; - ClutterPaintVolume *redraw_clip; ClutterActorBox bounding_box; ClutterActorBox intersection_box; cairo_rectangle_int_t geom, stage_clip; if (CLUTTER_ACTOR_IN_DESTRUCTION (actor)) - return; + return TRUE; /* If the backend can't do anything with redraw clips (e.g. it already knows * it needs to redraw everything anyway) then don't spend time transforming * any clip volume into stage coordinates... */ stage_window = _clutter_stage_get_window (stage); if (stage_window == NULL) - return; + return TRUE; - if (_clutter_stage_window_ignoring_redraw_clips (stage_window)) - { - _clutter_stage_window_add_redraw_clip (stage_window, NULL); - return; - } + if (is_full_stage_redraw_queued (stage)) + return FALSE; - /* Convert the clip volume into stage coordinates and then into an - * axis aligned stage coordinates bounding box... - */ - redraw_clip = _clutter_actor_get_queue_redraw_clip (leaf); if (redraw_clip == NULL) { - _clutter_stage_window_add_redraw_clip (stage_window, NULL); - return; + clutter_stage_add_redraw_clip (stage, NULL); + return FALSE; } if (redraw_clip->is_empty) - return; + return TRUE; + /* Convert the clip volume into stage coordinates and then into an + * axis aligned stage coordinates bounding box... */ _clutter_paint_volume_get_stage_paint_box (redraw_clip, stage, &bounding_box); @@ -1344,7 +1649,7 @@ clutter_stage_real_queue_redraw (ClutterActor *actor, /* There is no need to track degenerate/empty redraw clips */ if (intersection_box.x2 <= intersection_box.x1 || intersection_box.y2 <= intersection_box.y1) - return; + return TRUE; /* when converting to integer coordinates make sure we round the edges of the * clip rectangle outwards... */ @@ -1353,237 +1658,76 @@ clutter_stage_real_queue_redraw (ClutterActor *actor, stage_clip.width = intersection_box.x2 - stage_clip.x; stage_clip.height = intersection_box.y2 - stage_clip.y; - _clutter_stage_window_add_redraw_clip (stage_window, &stage_clip); + clutter_stage_add_redraw_clip (stage, &stage_clip); + return FALSE; } gboolean _clutter_stage_has_full_redraw_queued (ClutterStage *stage) { - ClutterStageWindow *stage_window = _clutter_stage_get_window (stage); - - if (CLUTTER_ACTOR_IN_DESTRUCTION (stage) || stage_window == NULL) + if (CLUTTER_ACTOR_IN_DESTRUCTION (stage)) return FALSE; - if (stage->priv->redraw_pending && - !_clutter_stage_window_has_redraw_clips (stage_window)) - return TRUE; - else + if (!stage->priv->redraw_pending) return FALSE; -} - -/** - * clutter_stage_get_redraw_clip_bounds: - * @stage: A #ClutterStage - * @clip: (out caller-allocates): Return location for the clip bounds - * - * Gets the bounds of the current redraw for @stage in stage pixel - * coordinates. E.g., if only a single actor has queued a redraw then - * Clutter may redraw the stage with a clip so that it doesn't have to - * paint every pixel in the stage. This function would then return the - * bounds of that clip. An application can use this information to - * avoid some extra work if it knows that some regions of the stage - * aren't going to be painted. This should only be called while the - * stage is being painted. If there is no current redraw clip then - * this function will set @clip to the full extents of the stage. - * - * Since: 1.8 - */ -void -clutter_stage_get_redraw_clip_bounds (ClutterStage *stage, - cairo_rectangle_int_t *clip) -{ - ClutterStagePrivate *priv; - - g_return_if_fail (CLUTTER_IS_STAGE (stage)); - g_return_if_fail (clip != NULL); - - priv = stage->priv; - - if (!_clutter_stage_window_get_redraw_clip_bounds (priv->impl, clip)) - { - /* Set clip to the full extents of the stage */ - _clutter_stage_window_get_geometry (priv->impl, clip); - } -} - -static void -read_pixels_to_file (char *filename_stem, - int x, - int y, - int width, - int height) -{ - guint8 *data; - cairo_surface_t *surface; - static int read_count = 0; - char *filename = g_strdup_printf ("%s-%05d.png", - filename_stem, - read_count); - - data = malloc (4 * width * height); - cogl_read_pixels (x, y, width, height, - COGL_READ_PIXELS_COLOR_BUFFER, - CLUTTER_CAIRO_FORMAT_ARGB32, - data); - - surface = cairo_image_surface_create_for_data (data, CAIRO_FORMAT_RGB24, - width, height, - width * 4); - - cairo_surface_write_to_png (surface, filename); - cairo_surface_destroy (surface); - - free (data); - free (filename); - read_count++; + return is_full_stage_redraw_queued (stage); } static ClutterActor * _clutter_stage_do_pick_on_view (ClutterStage *stage, - gint x, - gint y, + float x, + float y, ClutterPickMode mode, ClutterStageView *view) { - ClutterActor *actor = CLUTTER_ACTOR (stage); + ClutterMainContext *context = _clutter_context_get_default (); ClutterStagePrivate *priv = stage->priv; - CoglFramebuffer *fb = clutter_stage_view_get_framebuffer (view); - cairo_rectangle_int_t view_layout; - ClutterMainContext *context; - guchar pixel[4] = { 0xff, 0xff, 0xff, 0xff }; - CoglColor stage_pick_id; - gboolean dither_enabled_save; - ClutterActor *retval; - gint dirty_x; - gint dirty_y; - gint read_x; - gint read_y; - float fb_width, fb_height; - float fb_scale; - float viewport_offset_x; - float viewport_offset_y; - - context = _clutter_context_get_default (); - fb_scale = clutter_stage_view_get_scale (view); - clutter_stage_view_get_layout (view, &view_layout); - - fb_width = view_layout.width * fb_scale; - fb_height = view_layout.height * fb_scale; - cogl_push_framebuffer (fb); - - /* needed for when a context switch happens */ - _clutter_stage_maybe_setup_viewport (stage, view); - - /* FIXME: For some reason leaving the cogl clip stack empty causes the - * picking to not work at all, so setting it the whole framebuffer content - * for now. */ - cogl_framebuffer_push_scissor_clip (fb, 0, 0, - view_layout.width * fb_scale, - view_layout.height * fb_scale); - - _clutter_stage_window_get_dirty_pixel (priv->impl, view, &dirty_x, &dirty_y); - - if (G_LIKELY (!(clutter_pick_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS))) - { - CLUTTER_NOTE (PICK, "Pushing pick scissor clip x: %d, y: %d, 1x1", - (int) dirty_x * fb_scale, - (int) dirty_y * fb_scale); - cogl_framebuffer_push_scissor_clip (fb, dirty_x * fb_scale, dirty_y * fb_scale, 1, 1); - } + int i; - viewport_offset_x = x * fb_scale - dirty_x * fb_scale; - viewport_offset_y = y * fb_scale - dirty_y * fb_scale; - CLUTTER_NOTE (PICK, "Setting viewport to %f, %f, %f, %f", - priv->viewport[0] * fb_scale - viewport_offset_x, - priv->viewport[1] * fb_scale - viewport_offset_y, - priv->viewport[2] * fb_scale, - priv->viewport[3] * fb_scale); - cogl_framebuffer_set_viewport (fb, - priv->viewport[0] * fb_scale - viewport_offset_x, - priv->viewport[1] * fb_scale - viewport_offset_y, - priv->viewport[2] * fb_scale, - priv->viewport[3] * fb_scale); - - read_x = dirty_x * fb_scale; - read_y = dirty_y * fb_scale; - - CLUTTER_NOTE (PICK, "Performing pick at %i,%i on view %dx%d+%d+%d s: %d", - x, y, - view_layout.width, view_layout.height, - view_layout.x, view_layout.y, fb_scale); - - cogl_color_init_from_4ub (&stage_pick_id, 255, 255, 255, 255); - cogl_clear (&stage_pick_id, COGL_BUFFER_BIT_COLOR | COGL_BUFFER_BIT_DEPTH); - - /* Disable dithering (if any) when doing the painting in pick mode */ - dither_enabled_save = cogl_framebuffer_get_dither_enabled (fb); - cogl_framebuffer_set_dither_enabled (fb, FALSE); - - /* Render the entire scence in pick mode - just single colored silhouette's - * are drawn offscreen (as we never swap buffers) - */ - context->pick_mode = mode; - /* Paint without emitting AFTER_PAINT */ - clutter_stage_do_paint_view (stage, view, NULL); - context->pick_mode = CLUTTER_PICK_NONE; - - /* Read the color of the screen co-ords pixel. RGBA_8888_PRE is used - even though we don't care about the alpha component because under - GLES this is the only format that is guaranteed to work so Cogl - will end up having to do a conversion if any other format is - used. The format is requested as pre-multiplied because Cogl - assumes that all pixels in the framebuffer are premultiplied so - it avoids a conversion. */ - cogl_framebuffer_read_pixels (fb, - read_x, read_y, 1, 1, - COGL_PIXEL_FORMAT_RGBA_8888_PRE, - pixel); - - if (G_UNLIKELY (clutter_pick_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS)) - { - char *file_name = - g_strdup_printf ("pick-buffer-%s-view-x-%d", - _clutter_actor_get_debug_name (actor), - view_layout.x); + g_assert (context->pick_mode == CLUTTER_PICK_NONE); - read_pixels_to_file (file_name, 0, 0, fb_width, fb_height); + if (mode != priv->cached_pick_mode) + { + ClutterPickContext *pick_context; - free (file_name); - } + _clutter_stage_clear_pick_stack (stage); - /* Restore whether GL_DITHER was enabled */ - cogl_framebuffer_set_dither_enabled (fb, dither_enabled_save); + pick_context = clutter_pick_context_new_for_view (view); - if (G_LIKELY (!(clutter_pick_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS))) - cogl_framebuffer_pop_clip (fb); + context->pick_mode = mode; + setup_view_for_pick_or_paint (stage, view, NULL); + clutter_actor_pick (CLUTTER_ACTOR (stage), pick_context); + context->pick_mode = CLUTTER_PICK_NONE; + priv->cached_pick_mode = mode; - cogl_framebuffer_pop_clip (fb); + clutter_pick_context_destroy (pick_context); - _clutter_stage_dirty_viewport (stage); + add_pick_stack_weak_refs (stage); + } - if (pixel[0] == 0xff && pixel[1] == 0xff && pixel[2] == 0xff) - retval = actor; - else + /* Search all "painted" pickable actors from front to back. A linear search + * is required, and also performs fine since there is typically only + * on the order of dozens of actors in the list (on screen) at a time. + */ + for (i = priv->pick_stack->len - 1; i >= 0; i--) { - guint32 id_ = _clutter_pixel_to_id (pixel); + const PickRecord *rec = &g_array_index (priv->pick_stack, PickRecord, i); - retval = _clutter_stage_get_actor_by_pick_id (stage, id_); - CLUTTER_NOTE (PICK, "Picking actor %s with id %u (pixel: 0x%x%x%x%x", - G_OBJECT_TYPE_NAME (retval), - id_, - pixel[0], pixel[1], pixel[2], pixel[3]); + if (rec->actor && pick_record_contains_point (stage, rec, x, y)) + return rec->actor; } - cogl_pop_framebuffer (); - - return retval; + return CLUTTER_ACTOR (stage); } -static ClutterStageView * -get_view_at (ClutterStage *stage, - int x, - int y) +/** + * clutter_stage_get_view_at: (skip) + */ +ClutterStageView * +clutter_stage_get_view_at (ClutterStage *stage, + float x, + float y) { ClutterStagePrivate *priv = stage->priv; GList *l; @@ -1606,8 +1750,8 @@ get_view_at (ClutterStage *stage, ClutterActor * _clutter_stage_do_pick (ClutterStage *stage, - gint x, - gint y, + float x, + float y, ClutterPickMode mode) { ClutterActor *actor = CLUTTER_ACTOR (stage); @@ -1630,7 +1774,7 @@ _clutter_stage_do_pick (ClutterStage *stage, if (x < 0 || x >= stage_width || y < 0 || y >= stage_height) return actor; - view = get_view_at (stage, x, y); + view = clutter_stage_get_view_at (stage, x, y); if (view) return _clutter_stage_do_pick_on_view (stage, x, y, mode, view); @@ -1709,11 +1853,6 @@ clutter_stage_set_property (GObject *object, clutter_value_get_color (value)); break; - case PROP_OFFSCREEN: - if (g_value_get_boolean (value)) - g_warning ("Offscreen stages are currently not supported\n"); - break; - case PROP_CURSOR_VISIBLE: if (g_value_get_boolean (value)) clutter_stage_show_cursor (stage); @@ -1729,18 +1868,6 @@ clutter_stage_set_property (GObject *object, clutter_stage_set_title (stage, g_value_get_string (value)); break; - case PROP_USER_RESIZABLE: - clutter_stage_set_user_resizable (stage, g_value_get_boolean (value)); - break; - - case PROP_USE_FOG: - clutter_stage_set_use_fog (stage, g_value_get_boolean (value)); - break; - - case PROP_FOG: - clutter_stage_set_fog (stage, g_value_get_boxed (value)); - break; - case PROP_USE_ALPHA: clutter_stage_set_use_alpha (stage, g_value_get_boolean (value)); break; @@ -1749,10 +1876,6 @@ clutter_stage_set_property (GObject *object, clutter_stage_set_key_focus (stage, g_value_get_object (value)); break; - case PROP_NO_CLEAR_HINT: - clutter_stage_set_no_clear_hint (stage, g_value_get_boolean (value)); - break; - case PROP_ACCEPT_FOCUS: clutter_stage_set_accept_focus (stage, g_value_get_boolean (value)); break; @@ -1783,14 +1906,6 @@ clutter_stage_get_property (GObject *gobject, } break; - case PROP_OFFSCREEN: - g_value_set_boolean (value, FALSE); - break; - - case PROP_FULLSCREEN_SET: - g_value_set_boolean (value, priv->is_fullscreen); - break; - case PROP_CURSOR_VISIBLE: g_value_set_boolean (value, priv->is_cursor_visible); break; @@ -1803,18 +1918,6 @@ clutter_stage_get_property (GObject *gobject, g_value_set_string (value, priv->title); break; - case PROP_USER_RESIZABLE: - g_value_set_boolean (value, priv->is_user_resizable); - break; - - case PROP_USE_FOG: - g_value_set_boolean (value, priv->use_fog); - break; - - case PROP_FOG: - g_value_set_boxed (value, &priv->fog); - break; - case PROP_USE_ALPHA: g_value_set_boolean (value, priv->use_alpha); break; @@ -1823,15 +1926,6 @@ clutter_stage_get_property (GObject *gobject, g_value_set_object (value, priv->key_focused_actor); break; - case PROP_NO_CLEAR_HINT: - { - gboolean hint = - (priv->stage_hints & CLUTTER_STAGE_NO_CLEAR_ON_PAINT) != 0; - - g_value_set_boolean (value, hint); - } - break; - case PROP_ACCEPT_FOCUS: g_value_set_boolean (value, priv->accept_focus); break; @@ -1870,6 +1964,8 @@ clutter_stage_dispose (GObject *object) (GDestroyNotify) free_queue_redraw_entry); priv->pending_queue_redraws = NULL; + g_clear_pointer (&priv->pending_relayouts, g_hash_table_destroy); + /* this will release the reference on the stage */ stage_manager = clutter_stage_manager_get_default (); _clutter_stage_manager_remove_stage (stage_manager, stage); @@ -1886,11 +1982,13 @@ clutter_stage_finalize (GObject *object) g_queue_foreach (priv->event_queue, (GFunc) clutter_event_free, NULL); g_queue_free (priv->event_queue); - free (priv->title); + g_free (priv->title); g_array_free (priv->paint_volume_stack, TRUE); - _clutter_id_pool_free (priv->pick_id_pool); + _clutter_stage_clear_pick_stack (stage); + g_array_free (priv->pick_clip_stack, TRUE); + g_array_free (priv->pick_stack, TRUE); if (priv->fps_timer != NULL) g_timer_destroy (priv->fps_timer); @@ -1901,12 +1999,19 @@ clutter_stage_finalize (GObject *object) G_OBJECT_CLASS (clutter_stage_parent_class)->finalize (object); } +static void +clutter_stage_real_paint_view (ClutterStage *stage, + ClutterStageView *view, + const cairo_region_t *redraw_clip) +{ + clutter_stage_do_paint_view (stage, view, redraw_clip); +} + static void clutter_stage_class_init (ClutterStageClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); - GParamSpec *pspec; gobject_class->constructed = clutter_stage_constructed; gobject_class->set_property = clutter_stage_set_property; @@ -1930,70 +2035,20 @@ clutter_stage_class_init (ClutterStageClass *klass) actor_class->queue_redraw = clutter_stage_real_queue_redraw; actor_class->apply_transform = clutter_stage_real_apply_transform; - /** - * ClutterStage:fullscreen: - * - * Whether the stage should be fullscreen or not. - * - * This property is set by calling clutter_stage_set_fullscreen() - * but since the actual implementation is delegated to the backend - * you should connect to the notify::fullscreen-set signal in order - * to get notification if the fullscreen state has been successfully - * achieved. - * - * Since: 1.0 - */ - pspec = g_param_spec_boolean ("fullscreen-set", - P_("Fullscreen Set"), - P_("Whether the main stage is fullscreen"), - FALSE, - CLUTTER_PARAM_READABLE); - g_object_class_install_property (gobject_class, - PROP_FULLSCREEN_SET, - pspec); - /** - * ClutterStage:offscreen: - * - * Whether the stage should be rendered in an offscreen buffer. - * - * Deprecated: 1.10: This property does not do anything. - */ - pspec = g_param_spec_boolean ("offscreen", - P_("Offscreen"), - P_("Whether the main stage should be rendered offscreen"), - FALSE, - CLUTTER_PARAM_READWRITE | G_PARAM_DEPRECATED); - g_object_class_install_property (gobject_class, - PROP_OFFSCREEN, - pspec); + klass->paint_view = clutter_stage_real_paint_view; + /** * ClutterStage:cursor-visible: * * Whether the mouse pointer should be visible */ - pspec = g_param_spec_boolean ("cursor-visible", - P_("Cursor Visible"), - P_("Whether the mouse pointer is visible on the main stage"), - TRUE, - CLUTTER_PARAM_READWRITE); - g_object_class_install_property (gobject_class, - PROP_CURSOR_VISIBLE, - pspec); - /** - * ClutterStage:user-resizable: - * - * Whether the stage is resizable via user interaction. - * - * Since: 0.4 - */ - pspec = g_param_spec_boolean ("user-resizable", - P_("User Resizable"), - P_("Whether the stage is able to be resized via user interaction"), - FALSE, - CLUTTER_PARAM_READWRITE); - g_object_class_install_property (gobject_class, - PROP_USER_RESIZABLE, - pspec); + obj_props[PROP_CURSOR_VISIBLE] = + g_param_spec_boolean ("cursor-visible", + P_("Cursor Visible"), + P_("Whether the mouse pointer is visible on the main stage"), + TRUE, + CLUTTER_PARAM_READWRITE); + /** * ClutterStage:color: * @@ -2002,79 +2057,42 @@ clutter_stage_class_init (ClutterStageClass *klass) * Deprecated: 1.10: Use the #ClutterActor:background-color property of * #ClutterActor instead. */ - pspec = clutter_param_spec_color ("color", - P_("Color"), - P_("The color of the stage"), - &default_stage_color, - CLUTTER_PARAM_READWRITE | - G_PARAM_DEPRECATED); - g_object_class_install_property (gobject_class, PROP_COLOR, pspec); + obj_props[PROP_COLOR] = + clutter_param_spec_color ("color", + P_("Color"), + P_("The color of the stage"), + &default_stage_color, + CLUTTER_PARAM_READWRITE | + G_PARAM_DEPRECATED); /** * ClutterStage:perspective: * - * The parameters used for the perspective projection from 3D - * coordinates to 2D - * - * Since: 0.8 - */ - pspec = g_param_spec_boxed ("perspective", - P_("Perspective"), - P_("Perspective projection parameters"), - CLUTTER_TYPE_PERSPECTIVE, - CLUTTER_PARAM_READWRITE); - g_object_class_install_property (gobject_class, - PROP_PERSPECTIVE, - pspec); - - /** - * ClutterStage:title: - * - * The stage's title - usually displayed in stage windows title decorations. - * - * Since: 0.4 - */ - pspec = g_param_spec_string ("title", - P_("Title"), - P_("Stage Title"), - NULL, - CLUTTER_PARAM_READWRITE); - g_object_class_install_property (gobject_class, PROP_TITLE, pspec); - - /** - * ClutterStage:use-fog: - * - * Whether the stage should use a linear GL "fog" in creating the - * depth-cueing effect, to enhance the perception of depth by fading - * actors farther from the viewpoint. - * - * Since: 0.6 + * The parameters used for the perspective projection from 3D + * coordinates to 2D * - * Deprecated: 1.10: This property does not do anything. + * Since: 0.8 */ - pspec = g_param_spec_boolean ("use-fog", - P_("Use Fog"), - P_("Whether to enable depth cueing"), - FALSE, - CLUTTER_PARAM_READWRITE | G_PARAM_DEPRECATED); - g_object_class_install_property (gobject_class, PROP_USE_FOG, pspec); + obj_props[PROP_PERSPECTIVE] = + g_param_spec_boxed ("perspective", + P_("Perspective"), + P_("Perspective projection parameters"), + CLUTTER_TYPE_PERSPECTIVE, + CLUTTER_PARAM_READWRITE); /** - * ClutterStage:fog: - * - * The settings for the GL "fog", used only if #ClutterStage:use-fog - * is set to %TRUE + * ClutterStage:title: * - * Since: 1.0 + * The stage's title - usually displayed in stage windows title decorations. * - * Deprecated: 1.10: This property does not do anything. + * Since: 0.4 */ - pspec = g_param_spec_boxed ("fog", - P_("Fog"), - P_("Settings for the depth cueing"), - CLUTTER_TYPE_FOG, - CLUTTER_PARAM_READWRITE | G_PARAM_DEPRECATED); - g_object_class_install_property (gobject_class, PROP_FOG, pspec); + obj_props[PROP_TITLE] = + g_param_spec_string ("title", + P_("Title"), + P_("Stage Title"), + NULL, + CLUTTER_PARAM_READWRITE); /** * ClutterStage:use-alpha: @@ -2086,12 +2104,12 @@ clutter_stage_class_init (ClutterStageClass *klass) * * Since: 1.2 */ - pspec = g_param_spec_boolean ("use-alpha", - P_("Use Alpha"), - P_("Whether to honour the alpha component of the stage color"), - FALSE, - CLUTTER_PARAM_READWRITE); - g_object_class_install_property (gobject_class, PROP_USE_ALPHA, pspec); + obj_props[PROP_USE_ALPHA] = + g_param_spec_boolean ("use-alpha", + P_("Use Alpha"), + P_("Whether to honour the alpha component of the stage color"), + FALSE, + CLUTTER_PARAM_READWRITE); /** * ClutterStage:key-focus: @@ -2103,29 +2121,12 @@ clutter_stage_class_init (ClutterStageClass *klass) * * Since: 1.2 */ - pspec = g_param_spec_object ("key-focus", - P_("Key Focus"), - P_("The currently key focused actor"), - CLUTTER_TYPE_ACTOR, - CLUTTER_PARAM_READWRITE); - g_object_class_install_property (gobject_class, PROP_KEY_FOCUS, pspec); - - /** - * ClutterStage:no-clear-hint: - * - * Whether or not the #ClutterStage should clear its contents - * before each paint cycle. - * - * See clutter_stage_set_no_clear_hint() for further information. - * - * Since: 1.4 - */ - pspec = g_param_spec_boolean ("no-clear-hint", - P_("No Clear Hint"), - P_("Whether the stage should clear its contents"), - FALSE, - CLUTTER_PARAM_READWRITE); - g_object_class_install_property (gobject_class, PROP_NO_CLEAR_HINT, pspec); + obj_props[PROP_KEY_FOCUS] = + g_param_spec_object ("key-focus", + P_("Key Focus"), + P_("The currently key focused actor"), + CLUTTER_TYPE_ACTOR, + CLUTTER_PARAM_READWRITE); /** * ClutterStage:accept-focus: @@ -2134,46 +2135,15 @@ clutter_stage_class_init (ClutterStageClass *klass) * * Since: 1.6 */ - pspec = g_param_spec_boolean ("accept-focus", - P_("Accept Focus"), - P_("Whether the stage should accept focus on show"), - TRUE, - CLUTTER_PARAM_READWRITE); - g_object_class_install_property (gobject_class, PROP_ACCEPT_FOCUS, pspec); + obj_props[PROP_ACCEPT_FOCUS] = + g_param_spec_boolean ("accept-focus", + P_("Accept Focus"), + P_("Whether the stage should accept focus on show"), + TRUE, + CLUTTER_PARAM_READWRITE); + + g_object_class_install_properties (gobject_class, PROP_LAST, obj_props); - /** - * ClutterStage::fullscreen: - * @stage: the stage which was fullscreened - * - * The ::fullscreen signal is emitted when the stage is made fullscreen. - * - * Since: 0.6 - */ - stage_signals[FULLSCREEN] = - g_signal_new (I_("fullscreen"), - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (ClutterStageClass, fullscreen), - NULL, NULL, - _clutter_marshal_VOID__VOID, - G_TYPE_NONE, 0); - /** - * ClutterStage::unfullscreen: - * @stage: the stage which has left a fullscreen state. - * - * The ::unfullscreen signal is emitted when the stage leaves a fullscreen - * state. - * - * Since: 0.6 - */ - stage_signals[UNFULLSCREEN] = - g_signal_new (I_("unfullscreen"), - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterStageClass, unfullscreen), - NULL, NULL, - _clutter_marshal_VOID__VOID, - G_TYPE_NONE, 0); /** * ClutterStage::activate: * @stage: the stage which was activated @@ -2188,8 +2158,7 @@ clutter_stage_class_init (ClutterStageClass *klass) G_TYPE_FROM_CLASS (gobject_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ClutterStageClass, activate), - NULL, NULL, - _clutter_marshal_VOID__VOID, + NULL, NULL, NULL, G_TYPE_NONE, 0); /** * ClutterStage::deactivate: @@ -2205,8 +2174,7 @@ clutter_stage_class_init (ClutterStageClass *klass) G_TYPE_FROM_CLASS (gobject_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ClutterStageClass, deactivate), - NULL, NULL, - _clutter_marshal_VOID__VOID, + NULL, NULL, NULL, G_TYPE_NONE, 0); /** @@ -2243,6 +2211,7 @@ clutter_stage_class_init (ClutterStageClass *klass) /** * ClutterStage::after-paint: * @stage: the stage that received the event + * @paint_Context: the paint context * * The ::after-paint signal is emitted after the stage is painted, * but before the results are displayed on the screen. @@ -2257,11 +2226,36 @@ clutter_stage_class_init (ClutterStageClass *klass) NULL, NULL, NULL, G_TYPE_NONE, 0); + /** + * ClutterStage::paint-view: + * @stage: the stage that received the event + * @view: a #ClutterStageView + * @redraw_clip: a #cairo_region_t with the redraw clip + * + * The ::paint-view signal is emitted before a #ClutterStageView is being + * painted. + * + * The view is painted in the default handler. Hence, if you want to perform + * some action after the view is painted, like reading the contents of the + * framebuffer, use g_signal_connect_after() or pass %G_CONNECT_AFTER. + */ + stage_signals[PAINT_VIEW] = + g_signal_new (I_("paint-view"), + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ClutterStageClass, paint_view), + NULL, NULL, NULL, + G_TYPE_NONE, 2, + CLUTTER_TYPE_STAGE_VIEW, + G_TYPE_POINTER); + /** * ClutterStage::presented: (skip) * @stage: the stage that received the event * @frame_event: a #CoglFrameEvent * @frame_info: a #ClutterFrameInfo + * + * Signals that the #ClutterStage was presented on the screen to the user. */ stage_signals[PRESENTED] = g_signal_new (I_("presented"), @@ -2272,7 +2266,6 @@ clutter_stage_class_init (ClutterStageClass *klass) G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_POINTER); - klass->fullscreen = clutter_stage_real_fullscreen; klass->activate = clutter_stage_real_activate; klass->deactivate = clutter_stage_real_deactivate; klass->delete_event = clutter_stage_real_delete_event; @@ -2323,53 +2316,20 @@ clutter_stage_init (ClutterStage *self) priv->event_queue = g_queue_new (); - priv->is_fullscreen = FALSE; - priv->is_user_resizable = FALSE; priv->is_cursor_visible = TRUE; - priv->use_fog = FALSE; priv->throttle_motion_events = TRUE; priv->min_size_changed = FALSE; priv->sync_delay = -1; - - /* XXX - we need to keep the invariant that calling - * clutter_set_motion_event_enabled() before the stage creation - * will cause motion event delivery to be disabled on any newly - * created stage. this can go away when we break API and remove - * deprecated functions. - */ - priv->motion_events_enabled = _clutter_context_get_motion_events_enabled (); + priv->motion_events_enabled = TRUE; clutter_actor_set_background_color (CLUTTER_ACTOR (self), &default_stage_color); - priv->perspective.fovy = 60.0; /* 60 Degrees */ - priv->perspective.aspect = (float) geom.width / (float) geom.height; - priv->perspective.z_near = 0.1; - priv->perspective.z_far = 100.0; - - cogl_matrix_init_identity (&priv->projection); - cogl_matrix_perspective (&priv->projection, - priv->perspective.fovy, - priv->perspective.aspect, - priv->perspective.z_near, - priv->perspective.z_far); - cogl_matrix_get_inverse (&priv->projection, - &priv->inverse_projection); - cogl_matrix_init_identity (&priv->view); - cogl_matrix_view_2d_in_perspective (&priv->view, - priv->perspective.fovy, - priv->perspective.aspect, - priv->perspective.z_near, - 50, /* distance to 2d plane */ - geom.width, - geom.height); - - - /* FIXME - remove for 2.0 */ - priv->fog.z_near = 1.0; - priv->fog.z_far = 2.0; - - priv->relayout_pending = TRUE; + priv->pending_relayouts = g_hash_table_new_full (NULL, + NULL, + g_object_unref, + NULL); + clutter_stage_queue_actor_relayout (self, CLUTTER_ACTOR (self)); clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE); clutter_stage_set_title (self, g_get_prgname ()); @@ -2388,7 +2348,10 @@ clutter_stage_init (ClutterStage *self) priv->paint_volume_stack = g_array_new (FALSE, FALSE, sizeof (ClutterPaintVolume)); - priv->pick_id_pool = _clutter_id_pool_new (256); + priv->pick_stack = g_array_new (FALSE, FALSE, sizeof (PickRecord)); + priv->pick_clip_stack = g_array_new (FALSE, FALSE, sizeof (PickClipRecord)); + priv->pick_clip_stack_top = -1; + priv->cached_pick_mode = CLUTTER_PICK_NONE; } /** @@ -2456,7 +2419,7 @@ clutter_stage_set_color (ClutterStage *stage, { clutter_actor_set_background_color (CLUTTER_ACTOR (stage), color); - g_object_notify (G_OBJECT (stage), "color"); + g_object_notify_by_pspec (G_OBJECT (stage), obj_props[PROP_COLOR]); } /** @@ -2529,6 +2492,7 @@ clutter_stage_set_perspective (ClutterStage *stage, priv->has_custom_perspective = TRUE; clutter_stage_set_perspective_internal (stage, perspective); + clutter_stage_update_view_perspective (stage); } /** @@ -2655,6 +2619,7 @@ _clutter_stage_set_viewport (ClutterStage *stage, priv->viewport[2] = width; priv->viewport[3] = height; + clutter_stage_update_view_perspective (stage); _clutter_stage_dirty_viewport (stage); queue_full_redraw (stage); @@ -2720,136 +2685,6 @@ _clutter_stage_get_viewport (ClutterStage *stage, *height = priv->viewport[3]; } -/** - * clutter_stage_set_fullscreen: - * @stage: a #ClutterStage - * @fullscreen: %TRUE to to set the stage fullscreen - * - * Asks to place the stage window in the fullscreen or unfullscreen - * states. - * - ( Note that you shouldn't assume the window is definitely full screen - * afterward, because other entities (e.g. the user or window manager) - * could unfullscreen it again, and not all window managers honor - * requests to fullscreen windows. - * - * If you want to receive notification of the fullscreen state you - * should either use the #ClutterStage::fullscreen and - * #ClutterStage::unfullscreen signals, or use the notify signal - * for the #ClutterStage:fullscreen-set property - * - * Since: 1.0 - */ -void -clutter_stage_set_fullscreen (ClutterStage *stage, - gboolean fullscreen) -{ - ClutterStagePrivate *priv; - - g_return_if_fail (CLUTTER_IS_STAGE (stage)); - - priv = stage->priv; - - if (priv->is_fullscreen != fullscreen) - { - ClutterStageWindow *impl = CLUTTER_STAGE_WINDOW (priv->impl); - ClutterStageWindowIface *iface; - - iface = CLUTTER_STAGE_WINDOW_GET_IFACE (impl); - - /* Only set if backend implements. - * - * Also see clutter_stage_event() for setting priv->is_fullscreen - * on state change event. - */ - if (iface->set_fullscreen) - iface->set_fullscreen (impl, fullscreen); - } - - /* If the backend did fullscreen the stage window then we need to resize - * the stage and update its viewport so we queue a relayout. Note: if the - * fullscreen request is handled asynchronously we can't rely on this - * queue_relayout to update the viewport, but for example the X backend - * will recieve a ConfigureNotify after a successful resize which is how - * we ensure the viewport is updated on X. - */ - clutter_actor_queue_relayout (CLUTTER_ACTOR (stage)); -} - -/** - * clutter_stage_get_fullscreen: - * @stage: a #ClutterStage - * - * Retrieves whether the stage is full screen or not - * - * Return value: %TRUE if the stage is full screen - * - * Since: 1.0 - */ -gboolean -clutter_stage_get_fullscreen (ClutterStage *stage) -{ - g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE); - - return stage->priv->is_fullscreen; -} - -/** - * clutter_stage_set_user_resizable: - * @stage: a #ClutterStage - * @resizable: whether the stage should be user resizable. - * - * Sets if the stage is resizable by user interaction (e.g. via - * window manager controls) - * - * Since: 0.4 - */ -void -clutter_stage_set_user_resizable (ClutterStage *stage, - gboolean resizable) -{ - ClutterStagePrivate *priv; - - g_return_if_fail (CLUTTER_IS_STAGE (stage)); - - priv = stage->priv; - - if (clutter_feature_available (CLUTTER_FEATURE_STAGE_USER_RESIZE) - && priv->is_user_resizable != resizable) - { - ClutterStageWindow *impl = CLUTTER_STAGE_WINDOW (priv->impl); - ClutterStageWindowIface *iface; - - iface = CLUTTER_STAGE_WINDOW_GET_IFACE (impl); - if (iface->set_user_resizable) - { - priv->is_user_resizable = resizable; - - iface->set_user_resizable (impl, resizable); - - g_object_notify (G_OBJECT (stage), "user-resizable"); - } - } -} - -/** - * clutter_stage_get_user_resizable: - * @stage: a #ClutterStage - * - * Retrieves the value set with clutter_stage_set_user_resizable(). - * - * Return value: %TRUE if the stage is resizable by the user. - * - * Since: 0.4 - */ -gboolean -clutter_stage_get_user_resizable (ClutterStage *stage) -{ - g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE); - - return stage->priv->is_user_resizable; -} - /** * clutter_stage_show_cursor: * @stage: a #ClutterStage @@ -2867,7 +2702,7 @@ clutter_stage_show_cursor (ClutterStage *stage) if (!priv->is_cursor_visible) { ClutterStageWindow *impl = CLUTTER_STAGE_WINDOW (priv->impl); - ClutterStageWindowIface *iface; + ClutterStageWindowInterface *iface; iface = CLUTTER_STAGE_WINDOW_GET_IFACE (impl); if (iface->set_cursor_visible) @@ -2876,7 +2711,8 @@ clutter_stage_show_cursor (ClutterStage *stage) iface->set_cursor_visible (impl, TRUE); - g_object_notify (G_OBJECT (stage), "cursor-visible"); + g_object_notify_by_pspec (G_OBJECT (stage), + obj_props[PROP_CURSOR_VISIBLE]); } } } @@ -2900,7 +2736,7 @@ clutter_stage_hide_cursor (ClutterStage *stage) if (priv->is_cursor_visible) { ClutterStageWindow *impl = CLUTTER_STAGE_WINDOW (priv->impl); - ClutterStageWindowIface *iface; + ClutterStageWindowInterface *iface; iface = CLUTTER_STAGE_WINDOW_GET_IFACE (impl); if (iface->set_cursor_visible) @@ -2909,7 +2745,8 @@ clutter_stage_hide_cursor (ClutterStage *stage) iface->set_cursor_visible (impl, FALSE); - g_object_notify (G_OBJECT (stage), "cursor-visible"); + g_object_notify_by_pspec (G_OBJECT (stage), + obj_props[PROP_CURSOR_VISIBLE]); } } } @@ -2931,7 +2768,7 @@ clutter_stage_hide_cursor (ClutterStage *stage) * and not guaranteed to hold any sensible value. * * Return value: (transfer full) (array): a pointer to newly allocated memory with the buffer - * or %NULL if the read failed. Use free() on the returned data + * or %NULL if the read failed. Use g_free() on the returned data * to release the resources it has allocated. */ guchar * @@ -2948,8 +2785,13 @@ clutter_stage_read_pixels (ClutterStage *stage, cairo_region_t *clip; cairo_rectangle_int_t clip_rect; CoglFramebuffer *framebuffer; + float view_scale; + float pixel_width; + float pixel_height; uint8_t *pixels; + COGL_TRACE_BEGIN_SCOPED (ClutterStageReadPixels, "Read Pixels"); + g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL); priv = stage->priv; @@ -2981,24 +2823,30 @@ clutter_stage_read_pixels (ClutterStage *stage, .height = height, }); cairo_region_get_extents (clip, &clip_rect); - cairo_region_destroy (clip); if (clip_rect.width == 0 || clip_rect.height == 0) - return NULL; + { + cairo_region_destroy (clip); + return NULL; + } framebuffer = clutter_stage_view_get_framebuffer (view); - cogl_push_framebuffer (framebuffer); - clutter_stage_do_paint_view (stage, view, &clip_rect); + clutter_stage_do_paint_view (stage, view, clip); + + cairo_region_destroy (clip); + + view_scale = clutter_stage_view_get_scale (view); + pixel_width = roundf (clip_rect.width * view_scale); + pixel_height = roundf (clip_rect.height * view_scale); - pixels = calloc (1, clip_rect.width * clip_rect.height * 4); + pixels = g_malloc0 (pixel_width * pixel_height * 4); cogl_framebuffer_read_pixels (framebuffer, - clip_rect.x, clip_rect.y, - clip_rect.width, clip_rect.height, + clip_rect.x * view_scale, + clip_rect.y * view_scale, + pixel_width, pixel_height, COGL_PIXEL_FORMAT_RGBA_8888, pixels); - cogl_pop_framebuffer (); - return pixels; } @@ -3010,7 +2858,11 @@ clutter_stage_read_pixels (ClutterStage *stage, * @y: Y coordinate to check * * Checks the scene at the coordinates @x and @y and returns a pointer - * to the #ClutterActor at those coordinates. + * to the #ClutterActor at those coordinates. The result is the actor which + * would be at the specified location on the next redraw, and is not + * necessarily that which was there on the previous redraw. This allows the + * function to perform chronologically correctly after any queued changes to + * the scene, and even if nothing has been drawn. * * By using @pick_mode it is possible to control which actors will be * painted and thus available. @@ -3021,8 +2873,8 @@ clutter_stage_read_pixels (ClutterStage *stage, ClutterActor * clutter_stage_get_actor_at_pos (ClutterStage *stage, ClutterPickMode pick_mode, - gint x, - gint y) + float x, + float y) { g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL); @@ -3047,13 +2899,9 @@ gboolean clutter_stage_event (ClutterStage *stage, ClutterEvent *event) { - ClutterStagePrivate *priv; - g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE); g_return_val_if_fail (event != NULL, FALSE); - priv = stage->priv; - if (event->type == CLUTTER_DELETE) { gboolean retval = FALSE; @@ -3073,24 +2921,6 @@ clutter_stage_event (ClutterStage *stage, if (clutter_actor_event (CLUTTER_ACTOR (stage), event, FALSE)) return TRUE; - if (event->stage_state.changed_mask & CLUTTER_STAGE_STATE_FULLSCREEN) - { - if (event->stage_state.new_state & CLUTTER_STAGE_STATE_FULLSCREEN) - { - priv->is_fullscreen = TRUE; - g_signal_emit (stage, stage_signals[FULLSCREEN], 0); - - g_object_notify (G_OBJECT (stage), "fullscreen-set"); - } - else - { - priv->is_fullscreen = FALSE; - g_signal_emit (stage, stage_signals[UNFULLSCREEN], 0); - - g_object_notify (G_OBJECT (stage), "fullscreen-set"); - } - } - if (event->stage_state.changed_mask & CLUTTER_STAGE_STATE_ACTIVATED) { if (event->stage_state.new_state & CLUTTER_STAGE_STATE_ACTIVATED) @@ -3122,14 +2952,14 @@ clutter_stage_set_title (ClutterStage *stage, priv = stage->priv; - free (priv->title); + g_free (priv->title); priv->title = g_strdup (title); impl = CLUTTER_STAGE_WINDOW (priv->impl); if (CLUTTER_STAGE_WINDOW_GET_IFACE(impl)->set_title != NULL) CLUTTER_STAGE_WINDOW_GET_IFACE (impl)->set_title (impl, priv->title); - g_object_notify (G_OBJECT (stage), "title"); + g_object_notify_by_pspec (G_OBJECT (stage), obj_props[PROP_TITLE]); } /** @@ -3152,14 +2982,6 @@ clutter_stage_get_title (ClutterStage *stage) return stage->priv->title; } -static void -on_key_focus_destroy (ClutterActor *actor, - ClutterStage *stage) -{ - /* unset the key focus */ - clutter_stage_set_key_focus (stage, NULL); -} - /** * clutter_stage_set_key_focus: * @stage: the #ClutterStage @@ -3199,18 +3021,14 @@ clutter_stage_set_key_focus (ClutterStage *stage, old_focused_actor = priv->key_focused_actor; /* set key_focused_actor to NULL before emitting the signal or someone - * might hide the previously focused actor in the signal handler and we'd - * get re-entrant call and get glib critical from g_object_weak_unref + * might hide the previously focused actor in the signal handler */ - g_signal_handlers_disconnect_by_func (priv->key_focused_actor, - G_CALLBACK (on_key_focus_destroy), - stage); priv->key_focused_actor = NULL; - g_signal_emit_by_name (old_focused_actor, "key-focus-out"); + _clutter_actor_set_has_key_focus (old_focused_actor, FALSE); } else - g_signal_emit_by_name (stage, "key-focus-out"); + _clutter_actor_set_has_key_focus (CLUTTER_ACTOR (stage), FALSE); /* Note, if someone changes key focus in focus-out signal handler we'd be * overriding the latter call below moving the focus where it was originally @@ -3220,16 +3038,12 @@ clutter_stage_set_key_focus (ClutterStage *stage, if (actor != NULL) { priv->key_focused_actor = actor; - - g_signal_connect (actor, - "destroy", G_CALLBACK (on_key_focus_destroy), - stage); - g_signal_emit_by_name (priv->key_focused_actor, "key-focus-in"); + _clutter_actor_set_has_key_focus (actor, TRUE); } else - g_signal_emit_by_name (stage, "key-focus-in"); + _clutter_actor_set_has_key_focus (CLUTTER_ACTOR (stage), TRUE); - g_object_notify (G_OBJECT (stage), "key-focus"); + g_object_notify_by_pspec (G_OBJECT (stage), obj_props[PROP_KEY_FOCUS]); } /** @@ -3253,136 +3067,6 @@ clutter_stage_get_key_focus (ClutterStage *stage) return CLUTTER_ACTOR (stage); } -/** - * clutter_stage_get_use_fog: - * @stage: the #ClutterStage - * - * Gets whether the depth cueing effect is enabled on @stage. - * - * Return value: %TRUE if the depth cueing effect is enabled - * - * Since: 0.6 - * - * Deprecated: 1.10: This function will always return %FALSE - */ -gboolean -clutter_stage_get_use_fog (ClutterStage *stage) -{ - g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE); - - return stage->priv->use_fog; -} - -/** - * clutter_stage_set_use_fog: - * @stage: the #ClutterStage - * @fog: %TRUE for enabling the depth cueing effect - * - * Sets whether the depth cueing effect on the stage should be enabled - * or not. - * - * Depth cueing is a 3D effect that makes actors farther away from the - * viewing point less opaque, by fading them with the stage color. - - * The parameters of the GL fog used can be changed using the - * clutter_stage_set_fog() function. - * - * Since: 0.6 - * - * Deprecated: 1.10: Calling this function produces no visible effect - */ -void -clutter_stage_set_use_fog (ClutterStage *stage, - gboolean fog) -{ -} - -/** - * clutter_stage_set_fog: - * @stage: the #ClutterStage - * @fog: a #ClutterFog structure - * - * Sets the fog (also known as "depth cueing") settings for the @stage. - * - * A #ClutterStage will only use a linear fog progression, which - * depends solely on the distance from the viewer. The cogl_set_fog() - * function in COGL exposes more of the underlying implementation, - * and allows changing the for progression function. It can be directly - * used by disabling the #ClutterStage:use-fog property and connecting - * a signal handler to the #ClutterActor::paint signal on the @stage, - * like: - * - * |[ - * clutter_stage_set_use_fog (stage, FALSE); - * g_signal_connect (stage, "paint", G_CALLBACK (on_stage_paint), NULL); - * ]| - * - * The paint signal handler will call cogl_set_fog() with the - * desired settings: - * - * |[ - * static void - * on_stage_paint (ClutterActor *actor) - * { - * ClutterColor stage_color = { 0, }; - * CoglColor fog_color = { 0, }; - * - * // set the fog color to the stage background color - * clutter_stage_get_color (CLUTTER_STAGE (actor), &stage_color); - * cogl_color_init_from_4ub (&fog_color, - * stage_color.red, - * stage_color.green, - * stage_color.blue, - * stage_color.alpha); - * - * // enable fog // - * cogl_set_fog (&fog_color, - * COGL_FOG_MODE_EXPONENTIAL, // mode - * 0.5, // density - * 5.0, 30.0); // z_near and z_far - * } - * ]| - * - * The fogging functions only work correctly when the visible actors use - * unmultiplied alpha colors. By default Cogl will premultiply textures and - * cogl_set_source_color() will premultiply colors, so unless you explicitly - * load your textures requesting an unmultiplied internal format and use - * cogl_material_set_color() you can only use fogging with fully opaque actors. - * Support for premultiplied colors will improve in the future when we can - * depend on fragment shaders. - * - * Since: 0.6 - * - * Deprecated: 1.10: Fog settings are ignored. - */ -void -clutter_stage_set_fog (ClutterStage *stage, - ClutterFog *fog) -{ -} - -/** - * clutter_stage_get_fog: - * @stage: the #ClutterStage - * @fog: (out): return location for a #ClutterFog structure - * - * Retrieves the current depth cueing settings from the stage. - * - * Since: 0.6 - * - * Deprecated: 1.10: This function will always return the default - * values of #ClutterFog - */ -void -clutter_stage_get_fog (ClutterStage *stage, - ClutterFog *fog) -{ - g_return_if_fail (CLUTTER_IS_STAGE (stage)); - g_return_if_fail (fog != NULL); - - *fog = stage->priv->fog; -} - /*** Perspective boxed type ******/ static gpointer @@ -3405,24 +3089,6 @@ G_DEFINE_BOXED_TYPE (ClutterPerspective, clutter_perspective, clutter_perspective_copy, clutter_perspective_free); -static gpointer -clutter_fog_copy (gpointer data) -{ - if (G_LIKELY (data)) - return g_slice_dup (ClutterFog, data); - - return NULL; -} - -static void -clutter_fog_free (gpointer data) -{ - if (G_LIKELY (data)) - g_slice_free (ClutterFog, data); -} - -G_DEFINE_BOXED_TYPE (ClutterFog, clutter_fog, clutter_fog_copy, clutter_fog_free); - /** * clutter_stage_new: * @@ -3458,7 +3124,7 @@ clutter_stage_new (void) * be used by applications. * * Since: 0.8 - * Deprecated: muffin: This function does not do anything. + * Deprecated: mutter: This function does not do anything. */ void clutter_stage_ensure_current (ClutterStage *stage) @@ -3627,6 +3293,50 @@ calculate_z_translation (float z_near) + z_near; } +static void +clutter_stage_update_view_perspective (ClutterStage *stage) +{ + ClutterStagePrivate *priv = stage->priv; + ClutterPerspective perspective; + float z_2d; + + perspective = priv->perspective; + + /* Ideally we want to regenerate the perspective matrix whenever + * the size changes but if the user has provided a custom matrix + * then we don't want to override it */ + if (!priv->has_custom_perspective) + { + perspective.fovy = 60.0; /* 60 Degrees */ + perspective.z_near = 0.1; + perspective.aspect = priv->viewport[2] / priv->viewport[3]; + z_2d = calculate_z_translation (perspective.z_near); + + /* NB: z_2d is only enough room for 85% of the stage_height between + * the stage and the z_near plane. For behind the stage plane we + * want a more consistent gap of 10 times the stage_height before + * hitting the far plane so we calculate that relative to the final + * height of the stage plane at the z_2d_distance we got... */ + perspective.z_far = z_2d + + tanf (_DEG_TO_RAD (perspective.fovy / 2.0f)) * z_2d * 20.0f; + + clutter_stage_set_perspective_internal (stage, &perspective); + } + else + { + z_2d = calculate_z_translation (perspective.z_near); + } + + cogl_matrix_init_identity (&priv->view); + cogl_matrix_view_2d_in_perspective (&priv->view, + perspective.fovy, + perspective.aspect, + perspective.z_near, + z_2d, + priv->viewport[2], + priv->viewport[3]); +} + void _clutter_stage_maybe_setup_viewport (ClutterStage *stage, ClutterStageView *view) @@ -3637,11 +3347,13 @@ _clutter_stage_maybe_setup_viewport (ClutterStage *stage, if (clutter_stage_view_is_dirty_viewport (view)) { cairo_rectangle_int_t view_layout; - ClutterPerspective perspective; float fb_scale; float viewport_offset_x; float viewport_offset_y; - float z_2d; + float viewport_x; + float viewport_y; + float viewport_width; + float viewport_height; CLUTTER_NOTE (PAINT, "Setting up the viewport { w:%f, h:%f }", @@ -3653,43 +3365,13 @@ _clutter_stage_maybe_setup_viewport (ClutterStage *stage, viewport_offset_x = view_layout.x * fb_scale; viewport_offset_y = view_layout.y * fb_scale; + viewport_x = roundf (priv->viewport[0] * fb_scale - viewport_offset_x); + viewport_y = roundf (priv->viewport[1] * fb_scale - viewport_offset_y); + viewport_width = roundf (priv->viewport[2] * fb_scale); + viewport_height = roundf (priv->viewport[3] * fb_scale); cogl_framebuffer_set_viewport (fb, - priv->viewport[0] * fb_scale - viewport_offset_x, - priv->viewport[1] * fb_scale - viewport_offset_y, - priv->viewport[2] * fb_scale, - priv->viewport[3] * fb_scale); - - perspective = priv->perspective; - - /* Ideally we want to regenerate the perspective matrix whenever - * the size changes but if the user has provided a custom matrix - * then we don't want to override it */ - if (!priv->has_custom_perspective) - { - perspective.aspect = priv->viewport[2] / priv->viewport[3]; - z_2d = calculate_z_translation (perspective.z_near); - - /* NB: z_2d is only enough room for 85% of the stage_height between - * the stage and the z_near plane. For behind the stage plane we - * want a more consistent gap of 10 times the stage_height before - * hitting the far plane so we calculate that relative to the final - * height of the stage plane at the z_2d_distance we got... */ - perspective.z_far = z_2d + - tanf (_DEG_TO_RAD (perspective.fovy / 2.0f)) * z_2d * 20.0f; - - clutter_stage_set_perspective_internal (stage, &perspective); - } - else - z_2d = calculate_z_translation (perspective.z_near); - - cogl_matrix_init_identity (&priv->view); - cogl_matrix_view_2d_in_perspective (&priv->view, - perspective.fovy, - perspective.aspect, - perspective.z_near, - z_2d, - priv->viewport[2], - priv->viewport[3]); + viewport_x, viewport_y, + viewport_width, viewport_height); clutter_stage_view_set_dirty_viewport (view, FALSE); } @@ -3726,14 +3408,24 @@ clutter_stage_ensure_redraw (ClutterStage *stage) priv = stage->priv; - if (!priv->relayout_pending && !priv->redraw_pending) - _clutter_stage_schedule_update (stage); + if (!_clutter_stage_needs_update (stage)) + clutter_stage_schedule_update (stage); - priv->relayout_pending = TRUE; priv->redraw_pending = TRUE; - master_clock = _clutter_master_clock_get_default (); - _clutter_master_clock_start_running (master_clock); + master_clock = _clutter_master_clock_get_default (); + _clutter_master_clock_start_running (master_clock); +} + +/** + * clutter_stage_is_redraw_queued: (skip) + */ +gboolean +clutter_stage_is_redraw_queued (ClutterStage *stage) +{ + ClutterStagePrivate *priv = stage->priv; + + return priv->redraw_pending; } /** @@ -3890,7 +3582,7 @@ clutter_stage_set_use_alpha (ClutterStage *stage, clutter_actor_queue_redraw (CLUTTER_ACTOR (stage)); - g_object_notify (G_OBJECT (stage), "use-alpha"); + g_object_notify_by_pspec (G_OBJECT (stage), obj_props[PROP_USE_ALPHA]); } } @@ -3928,8 +3620,6 @@ clutter_stage_get_use_alpha (ClutterStage *stage) * If the current size of @stage is smaller than the minimum size, the * @stage will be resized to the new @width and @height * - * This function has no effect if @stage is fullscreen - * * Since: 1.2 */ void @@ -3996,8 +3686,14 @@ clutter_stage_get_minimum_size (ClutterStage *stage, *height_p = (guint) height; } +/** + * clutter_stage_schedule_update: + * @stage: a #ClutterStage actor + * + * Schedules a redraw of the #ClutterStage at the next optimal timestamp. + */ void -_clutter_stage_schedule_update (ClutterStage *stage) +clutter_stage_schedule_update (ClutterStage *stage) { ClutterStageWindow *stage_window; @@ -4008,11 +3704,24 @@ _clutter_stage_schedule_update (ClutterStage *stage) if (stage_window == NULL) return; + stage->priv->needs_update = TRUE; + return _clutter_stage_window_schedule_update (stage_window, stage->priv->sync_delay); } -/* Returns the earliest time the stage is ready to update */ +/** + * _clutter_stage_get_update_time: + * @stage: a #ClutterStage actor + * + * Returns the earliest time in which the stage is ready to update. The update + * time is set when clutter_stage_schedule_update() is called. This can then + * be used by e.g. the #ClutterMasterClock to know when the stage needs to be + * redrawn. + * + * Returns: -1 if no redraw is needed; 0 if the backend doesn't know, or the + * timestamp (in microseconds) otherwise. + */ gint64 _clutter_stage_get_update_time (ClutterStage *stage) { @@ -4028,6 +3737,13 @@ _clutter_stage_get_update_time (ClutterStage *stage) return _clutter_stage_window_get_update_time (stage_window); } +/** + * _clutter_stage_clear_update_time: + * @stage: a #ClutterStage actor + * + * Resets the update time. Call this after a redraw, so that the update time + * can again be updated. + */ void _clutter_stage_clear_update_time (ClutterStage *stage) { @@ -4038,70 +3754,19 @@ _clutter_stage_clear_update_time (ClutterStage *stage) _clutter_stage_window_clear_update_time (stage_window); } -/** - * clutter_stage_set_no_clear_hint: - * @stage: a #ClutterStage - * @no_clear: %TRUE if the @stage should not clear itself on every - * repaint cycle - * - * Sets whether the @stage should clear itself at the beginning - * of each paint cycle or not. - * - * Clearing the #ClutterStage can be a costly operation, especially - * if the stage is always covered - for instance, in a full-screen - * video player or in a game with a background texture. - * - * This setting is a hint; Clutter might discard this hint - * depending on its internal state. - * - * If parts of the stage are visible and you disable clearing you - * might end up with visual artifacts while painting the contents of - * the stage. - * - * Since: 1.4 - */ -void -clutter_stage_set_no_clear_hint (ClutterStage *stage, - gboolean no_clear) +int64_t +_clutter_stage_get_next_presentation_time (ClutterStage *stage) { - ClutterStagePrivate *priv; - ClutterStageHint new_hints; - - g_return_if_fail (CLUTTER_IS_STAGE (stage)); - - priv = stage->priv; - new_hints = priv->stage_hints; - - if (no_clear) - new_hints |= CLUTTER_STAGE_NO_CLEAR_ON_PAINT; - else - new_hints &= ~CLUTTER_STAGE_NO_CLEAR_ON_PAINT; - - if (priv->stage_hints == new_hints) - return; - - priv->stage_hints = new_hints; + ClutterStageWindow *stage_window; - g_object_notify (G_OBJECT (stage), "no-clear-hint"); -} + if (CLUTTER_ACTOR_IN_DESTRUCTION (stage)) + return 0; -/** - * clutter_stage_get_no_clear_hint: - * @stage: a #ClutterStage - * - * Retrieves the hint set with clutter_stage_set_no_clear_hint() - * - * Return value: %TRUE if the stage should not clear itself on every paint - * cycle, and %FALSE otherwise - * - * Since: 1.4 - */ -gboolean -clutter_stage_get_no_clear_hint (ClutterStage *stage) -{ - g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE); + stage_window = _clutter_stage_get_window (stage); + if (stage_window == NULL) + return 0; - return (stage->priv->stage_hints & CLUTTER_STAGE_NO_CLEAR_ON_PAINT) != 0; + return _clutter_stage_window_get_next_presentation_time (stage_window); } ClutterPaintVolume * @@ -4153,25 +3818,29 @@ _clutter_stage_get_clip (ClutterStage *stage) * didn't explicitly do so. */ ClutterStageQueueRedrawEntry * -_clutter_stage_queue_actor_redraw (ClutterStage *stage, +_clutter_stage_queue_actor_redraw (ClutterStage *stage, ClutterStageQueueRedrawEntry *entry, - ClutterActor *actor, - ClutterPaintVolume *clip) + ClutterActor *actor, + const ClutterPaintVolume *clip) { ClutterStagePrivate *priv = stage->priv; CLUTTER_NOTE (CLIPPING, "stage_queue_actor_redraw (actor=%s, clip=%p): ", _clutter_actor_get_debug_name (actor), clip); + /* Queuing a redraw or clip change invalidates the pick cache, unless we're + * in the middle of building it. So we reset the cached flag but don't + * completely clear the pick stack... + */ + priv->cached_pick_mode = CLUTTER_PICK_NONE; + if (!priv->redraw_pending) { ClutterMasterClock *master_clock; -#ifdef CLUTTER_ENABLE_DEBUG CLUTTER_NOTE (PAINT, "First redraw request"); -#endif - _clutter_stage_schedule_update (stage); + clutter_stage_schedule_update (stage); priv->redraw_pending = TRUE; master_clock = _clutter_master_clock_get_default (); @@ -4326,7 +3995,7 @@ clutter_stage_set_accept_focus (ClutterStage *stage, if (priv->accept_focus != accept_focus) { _clutter_stage_window_set_accept_focus (priv->impl, accept_focus); - g_object_notify (G_OBJECT (stage), "accept-focus"); + g_object_notify_by_pspec (G_OBJECT (stage), obj_props[PROP_ACCEPT_FOCUS]); } } @@ -4413,51 +4082,6 @@ clutter_stage_get_motion_events_enabled (ClutterStage *stage) return stage->priv->motion_events_enabled; } -/* NB: The presumption shouldn't be that a stage can't be comprised - * of multiple internal framebuffers, so instead of simply naming - * this function _clutter_stage_get_framebuffer(), the "active" - * infix is intended to clarify that it gets the framebuffer that - * is currently in use/being painted. - */ -CoglFramebuffer * -_clutter_stage_get_active_framebuffer (ClutterStage *stage) -{ - return stage->priv->active_framebuffer; -} - -gint32 -_clutter_stage_acquire_pick_id (ClutterStage *stage, - ClutterActor *actor) -{ - ClutterStagePrivate *priv = stage->priv; - - g_assert (priv->pick_id_pool != NULL); - - return _clutter_id_pool_add (priv->pick_id_pool, actor); -} - -void -_clutter_stage_release_pick_id (ClutterStage *stage, - gint32 pick_id) -{ - ClutterStagePrivate *priv = stage->priv; - - g_assert (priv->pick_id_pool != NULL); - - _clutter_id_pool_remove (priv->pick_id_pool, pick_id); -} - -ClutterActor * -_clutter_stage_get_actor_by_pick_id (ClutterStage *stage, - gint32 pick_id) -{ - ClutterStagePrivate *priv = stage->priv; - - g_assert (priv->pick_id_pool != NULL); - - return _clutter_id_pool_lookup (priv->pick_id_pool, pick_id); -} - void _clutter_stage_add_pointer_drag_actor (ClutterStage *stage, ClutterInputDevice *device, @@ -4594,20 +4218,6 @@ _clutter_stage_is_activated (ClutterStage *stage) return (stage->priv->current_state & CLUTTER_STAGE_STATE_ACTIVATED) != 0; } -/*< private > - * _clutter_stage_is_fullscreen: - * @stage: a #ClutterStage - * - * Checks whether the @stage state includes %CLUTTER_STAGE_STATE_FULLSCREEN. - * - * Return value: %TRUE if the @stage is fullscreen - */ -gboolean -_clutter_stage_is_fullscreen (ClutterStage *stage) -{ - return (stage->priv->current_state & CLUTTER_STAGE_STATE_FULLSCREEN) != 0; -} - /*< private > * _clutter_stage_update_state: * @stage: a #ClutterStage @@ -4628,7 +4238,7 @@ _clutter_stage_update_state (ClutterStage *stage, ClutterStageState set_flags) { ClutterStageState new_state; - ClutterEvent event; + ClutterEvent *event; new_state = stage->priv->current_state; new_state |= set_flags; @@ -4637,16 +4247,16 @@ _clutter_stage_update_state (ClutterStage *stage, if (new_state == stage->priv->current_state) return FALSE; - memset (&event, 0, sizeof (event)); - event.type = CLUTTER_STAGE_STATE; - clutter_event_set_stage (&event, stage); + event = clutter_event_new (CLUTTER_STAGE_STATE); + clutter_event_set_stage (event, stage); - event.stage_state.new_state = new_state; - event.stage_state.changed_mask = new_state ^ stage->priv->current_state; + event->stage_state.new_state = new_state; + event->stage_state.changed_mask = new_state ^ stage->priv->current_state; stage->priv->current_state = new_state; - clutter_stage_event (stage, &event); + clutter_stage_event (stage, event); + clutter_event_free (event); return TRUE; } @@ -4728,64 +4338,48 @@ static void capture_view (ClutterStage *stage, gboolean paint, ClutterStageView *view, - cairo_rectangle_int_t *rect, ClutterCapture *capture) { - CoglFramebuffer *framebuffer; - ClutterBackend *backend; - CoglContext *context; cairo_surface_t *image; uint8_t *data; int stride; - CoglBitmap *bitmap; - cairo_rectangle_int_t view_layout; + cairo_rectangle_int_t *rect; float view_scale; + float texture_width; + float texture_height; - framebuffer = clutter_stage_view_get_framebuffer (view); - - if (paint) - { - cogl_push_framebuffer (framebuffer); - _clutter_stage_maybe_setup_viewport (stage, view); - clutter_stage_do_paint_view (stage, view, rect); - } + rect = &capture->rect; view_scale = clutter_stage_view_get_scale (view); + texture_width = roundf (rect->width * view_scale); + texture_height = roundf (rect->height * view_scale); image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, - rect->width * view_scale, - rect->height * view_scale); + texture_width, texture_height); cairo_surface_set_device_scale (image, view_scale, view_scale); data = cairo_image_surface_get_data (image); stride = cairo_image_surface_get_stride (image); - backend = clutter_get_default_backend (); - context = clutter_backend_get_cogl_context (backend); - bitmap = cogl_bitmap_new_for_data (context, - rect->width * view_scale, - rect->height * view_scale, - CLUTTER_CAIRO_FORMAT_ARGB32, - stride, - data); - - clutter_stage_view_get_layout (view, &view_layout); - - cogl_framebuffer_read_pixels_into_bitmap (framebuffer, - (rect->x - view_layout.x) * view_scale, - (rect->y - view_layout.y) * view_scale, - COGL_READ_PIXELS_COLOR_BUFFER, - bitmap); - - if (paint) - cogl_pop_framebuffer (); - - capture->rect = *rect; + capture_view_into (stage, paint, view, rect, data, stride); capture->image = image; cairo_surface_mark_dirty (capture->image); - cogl_object_unref (bitmap); } +/** + * clutter_stage_capture: + * @stage: a #ClutterStage + * @paint: whether to pain the frame + * @rect: a #cairo_rectangle_int_t in stage coordinates + * @out_captures: (out) (array length=out_n_captures): an array of + * #ClutterCapture + * @out_n_captures: (out): the number of captures in @out_captures + * + * Captures the stage pixels of @rect into @captures. @rect is in stage + * coordinates. + * + * Returns: %TRUE if a #ClutterCapture has been created, %FALSE otherwise + */ gboolean clutter_stage_capture (ClutterStage *stage, gboolean paint, @@ -4799,123 +4393,341 @@ clutter_stage_capture (ClutterStage *stage, ClutterCapture *captures; int n_captures; + g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE); + captures = g_new0 (ClutterCapture, g_list_length (views)); n_captures = 0; for (l = views; l; l = l->next) { ClutterStageView *view = l->data; + ClutterCapture *capture; cairo_rectangle_int_t view_layout; cairo_region_t *region; - cairo_rectangle_int_t view_capture_rect; clutter_stage_view_get_layout (view, &view_layout); region = cairo_region_create_rectangle (&view_layout); cairo_region_intersect_rectangle (region, rect); - cairo_region_get_extents (region, &view_capture_rect); + + capture = &captures[n_captures]; + cairo_region_get_extents (region, &capture->rect); cairo_region_destroy (region); - if (view_capture_rect.width == 0 || view_capture_rect.height == 0) + if (capture->rect.width == 0 || capture->rect.height == 0) continue; - capture_view (stage, paint, view, &view_capture_rect, - &captures[n_captures]); + capture_view (stage, paint, view, capture); n_captures++; } + if (n_captures == 0) + g_clear_pointer (&captures, g_free); + *out_captures = captures; *out_n_captures = n_captures; + return n_captures > 0; +} + +gboolean +clutter_stage_get_capture_final_size (ClutterStage *stage, + cairo_rectangle_int_t *rect, + int *out_width, + int *out_height, + float *out_scale) +{ + float max_scale; + + g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE); + + if (rect) + { + graphene_rect_t capture_rect; + + _clutter_util_rect_from_rectangle (rect, &capture_rect); + if (!_clutter_stage_get_max_view_scale_factor_for_rect (stage, + &capture_rect, + &max_scale)) + return FALSE; + + if (out_width) + *out_width = (gint) roundf (rect->width * max_scale); + + if (out_height) + *out_height = (gint) roundf (rect->height * max_scale); + } + else + { + ClutterActorBox alloc; + float stage_width, stage_height; + + clutter_actor_get_allocation_box (CLUTTER_ACTOR (stage), &alloc); + clutter_actor_box_get_size (&alloc, &stage_width, &stage_height); + if (!_clutter_actor_get_real_resource_scale (CLUTTER_ACTOR (stage), + &max_scale)) + return FALSE; + + if (out_width) + *out_width = (gint) roundf (stage_width * max_scale); + + if (out_height) + *out_height = (gint) roundf (stage_height * max_scale); + } + + if (out_scale) + *out_scale = max_scale; + return TRUE; } -static void -capture_view_into (ClutterStage *stage, - gboolean paint, - ClutterStageView *view, - cairo_rectangle_int_t *rect, - uint8_t *data, - int stride) +/** + * clutter_stage_paint_to_framebuffer: (skip) + */ +void +clutter_stage_paint_to_framebuffer (ClutterStage *stage, + CoglFramebuffer *framebuffer, + const cairo_rectangle_int_t *rect, + float scale, + ClutterPaintFlag paint_flags) { + ClutterStagePrivate *priv = stage->priv; + ClutterPaintContext *paint_context; + cairo_region_t *redraw_clip; + + redraw_clip = cairo_region_create_rectangle (rect); + paint_context = clutter_paint_context_new_for_framebuffer (framebuffer); + cairo_region_destroy (redraw_clip); + + cogl_framebuffer_push_matrix (framebuffer); + cogl_framebuffer_set_projection_matrix (framebuffer, &priv->projection); + cogl_framebuffer_set_viewport (framebuffer, + -(rect->x * scale), + -(rect->y * scale), + priv->viewport[2] * scale, + priv->viewport[3] * scale); + clutter_actor_paint (CLUTTER_ACTOR (stage), paint_context); + cogl_framebuffer_pop_matrix (framebuffer); + + clutter_paint_context_destroy (paint_context); +} + +/** + * clutter_stage_paint_to_buffer: (skip) + */ +gboolean +clutter_stage_paint_to_buffer (ClutterStage *stage, + const cairo_rectangle_int_t *rect, + float scale, + uint8_t *data, + int stride, + CoglPixelFormat format, + ClutterPaintFlag paint_flags, + GError **error) +{ + ClutterBackend *clutter_backend = clutter_get_default_backend (); + CoglContext *cogl_context = + clutter_backend_get_cogl_context (clutter_backend); + int texture_width, texture_height; + CoglTexture2D *texture; + CoglOffscreen *offscreen; CoglFramebuffer *framebuffer; - ClutterBackend *backend; - CoglContext *context; CoglBitmap *bitmap; - cairo_rectangle_int_t view_layout; - framebuffer = clutter_stage_view_get_framebuffer (view); - - if (paint) + texture_width = (int) roundf (rect->width * scale); + texture_height = (int) roundf (rect->height * scale); + texture = cogl_texture_2d_new_with_size (cogl_context, + texture_width, + texture_height); + if (!texture) { - cogl_push_framebuffer (framebuffer); - _clutter_stage_maybe_setup_viewport (stage, view); - clutter_stage_do_paint_view (stage, view, rect); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Failed to create %dx%d texture", + texture_width, texture_height); + return FALSE; } - backend = clutter_get_default_backend (); - context = clutter_backend_get_cogl_context (backend); - bitmap = cogl_bitmap_new_for_data (context, - rect->width, rect->height, - CLUTTER_CAIRO_FORMAT_ARGB32, + offscreen = cogl_offscreen_new_with_texture (COGL_TEXTURE (texture)); + framebuffer = COGL_FRAMEBUFFER (offscreen); + + cogl_object_unref (texture); + + if (!cogl_framebuffer_allocate (framebuffer, error)) + return FALSE; + + clutter_stage_paint_to_framebuffer (stage, framebuffer, + rect, scale, paint_flags); + + bitmap = cogl_bitmap_new_for_data (cogl_context, + texture_width, texture_height, + format, stride, data); - clutter_stage_view_get_layout (view, &view_layout); - cogl_framebuffer_read_pixels_into_bitmap (framebuffer, - rect->x - view_layout.x, - rect->y - view_layout.y, + 0, 0, COGL_READ_PIXELS_COLOR_BUFFER, bitmap); - if (paint) - cogl_pop_framebuffer (); - cogl_object_unref (bitmap); + cogl_object_unref (framebuffer); + + return TRUE; +} + +static void +capture_view_into (ClutterStage *stage, + gboolean paint, + ClutterStageView *view, + cairo_rectangle_int_t *rect, + uint8_t *data, + int stride) +{ + g_autoptr (GError) error = NULL; + float view_scale; + + g_return_if_fail (CLUTTER_IS_STAGE (stage)); + + view_scale = clutter_stage_view_get_scale (view); + if (!clutter_stage_paint_to_buffer (stage, rect, view_scale, data, stride, + CLUTTER_CAIRO_FORMAT_ARGB32, + CLUTTER_PAINT_FLAG_NO_CURSORS, + &error)) + g_warning ("Failed to capture stage: %s", error->message); } -static ClutterStageView * -get_view_at_rect (ClutterStage *stage, - cairo_rectangle_int_t *rect) +void +clutter_stage_capture_into (ClutterStage *stage, + gboolean paint, + cairo_rectangle_int_t *rect, + uint8_t *data) { ClutterStagePrivate *priv = stage->priv; - GList *views = _clutter_stage_window_get_views (priv->impl); GList *l; + int bpp = 4; + int stride; - for (l = views; l; l = l->next) + stride = rect->width * 4; + + for (l = _clutter_stage_window_get_views (priv->impl); l; l = l->next) { ClutterStageView *view = l->data; cairo_rectangle_int_t view_layout; cairo_region_t *region; - cairo_rectangle_int_t view_capture_rect; + cairo_rectangle_int_t capture_rect; + int x_offset, y_offset; clutter_stage_view_get_layout (view, &view_layout); region = cairo_region_create_rectangle (&view_layout); cairo_region_intersect_rectangle (region, rect); - cairo_region_get_extents (region, &view_capture_rect); + + cairo_region_get_extents (region, &capture_rect); cairo_region_destroy (region); - if (view_capture_rect.width == 0 || view_capture_rect.height == 0) - continue; + x_offset = capture_rect.x - rect->x; + y_offset = capture_rect.y - rect->y; - g_assert (view_capture_rect.width == rect->width && - view_capture_rect.height == rect->height); - return view; + capture_view_into (stage, paint, view, + &capture_rect, + data + (x_offset * bpp) + (y_offset * stride), + stride); } +} - return NULL; +/** + * clutter_stage_freeze_updates: + * + * Freezing updates makes Clutter stop processing events, + * redrawing, and advancing timelines, by pausing the master clock. This is + * necessary when implementing a display server, to ensure that Clutter doesn't + * keep trying to page flip when DRM master has been dropped, e.g. when VT + * switched away. + * + * The master clock starts out running, so if you are VT switched away on + * startup, you need to call this immediately. + * + * To thaw updates, use clutter_stage_thaw_updates(). + */ +void +clutter_stage_freeze_updates (ClutterStage *stage) +{ + ClutterStagePrivate *priv = stage->priv; + + priv->update_freeze_count++; + if (priv->update_freeze_count == 1) + { + ClutterMasterClock *master_clock; + + master_clock = _clutter_master_clock_get_default (); + _clutter_master_clock_set_paused (master_clock, TRUE); + } } +/** + * clutter_stage_thaw_updates: + * + * Resumes a master clock that has previously been frozen with + * clutter_stage_freeze_updates(), and start pumping the master clock + * again at the next iteration. Note that if you're switching back to your + * own VT, you should probably also queue a stage redraw with + * clutter_stage_ensure_redraw(). + */ void -clutter_stage_capture_into (ClutterStage *stage, - gboolean paint, - cairo_rectangle_int_t *rect, - uint8_t *data) +clutter_stage_thaw_updates (ClutterStage *stage) { - ClutterStageView *view; - int bpp = 4; + ClutterStagePrivate *priv = stage->priv; + + g_assert (priv->update_freeze_count > 0); + + priv->update_freeze_count--; + if (priv->update_freeze_count == 0) + { + ClutterMasterClock *master_clock; + + master_clock = _clutter_master_clock_get_default (); + _clutter_master_clock_set_paused (master_clock, FALSE); + } +} + +GList * +_clutter_stage_peek_stage_views (ClutterStage *stage) +{ + ClutterStagePrivate *priv = stage->priv; + + return _clutter_stage_window_get_views (priv->impl); +} + +void +clutter_stage_update_resource_scales (ClutterStage *stage) +{ + _clutter_actor_queue_update_resource_scale_recursive (CLUTTER_ACTOR (stage)); +} + +gboolean +_clutter_stage_get_max_view_scale_factor_for_rect (ClutterStage *stage, + graphene_rect_t *rect, + float *view_scale) +{ + ClutterStagePrivate *priv = stage->priv; + float scale = 0.0f; + GList *l; + + for (l = _clutter_stage_window_get_views (priv->impl); l; l = l->next) + { + ClutterStageView *view = l->data; + cairo_rectangle_int_t view_layout; + graphene_rect_t view_rect; + + clutter_stage_view_get_layout (view, &view_layout); + _clutter_util_rect_from_rectangle (&view_layout, &view_rect); + + if (graphene_rect_intersection (&view_rect, rect, NULL)) + scale = MAX (clutter_stage_view_get_scale (view), scale); + } + + if (scale == 0.0) + return FALSE; - view = get_view_at_rect (stage, rect); - capture_view_into (stage, paint, view, rect, data, rect->width * bpp); + *view_scale = scale; + return TRUE; } diff --git a/clutter/clutter/clutter-stage.h b/clutter/clutter/clutter-stage.h index 975a7391b..7afe4c297 100644 --- a/clutter/clutter/clutter-stage.h +++ b/clutter/clutter/clutter-stage.h @@ -30,6 +30,7 @@ #include #include +#include G_BEGIN_DECLS @@ -61,8 +62,6 @@ struct _ClutterStage }; /** * ClutterStageClass: - * @fullscreen: handler for the #ClutterStage::fullscreen signal - * @unfullscreen: handler for the #ClutterStage::unfullscreen signal * @activate: handler for the #ClutterStage::activate signal * @deactivate: handler for the #ClutterStage::deactivate signal * @delete_event: handler for the #ClutterStage::delete-event signal @@ -79,17 +78,19 @@ struct _ClutterStageClass /*< public >*/ /* signals */ - void (* fullscreen) (ClutterStage *stage); - void (* unfullscreen) (ClutterStage *stage); void (* activate) (ClutterStage *stage); void (* deactivate) (ClutterStage *stage); gboolean (* delete_event) (ClutterStage *stage, ClutterEvent *event); + void (* paint_view) (ClutterStage *stage, + ClutterStageView *view, + const cairo_region_t *redraw_clip); + /*< private >*/ /* padding for future expansion */ - gpointer _padding_dummy[31]; + gpointer _padding_dummy[30]; }; /** @@ -115,26 +116,6 @@ struct _ClutterPerspective gfloat z_far; }; -/** - * ClutterFog: - * @z_near: starting distance from the viewer to the near clipping - * plane (always positive) - * @z_far: final distance from the viewer to the far clipping - * plane (always positive) - * - * Fog settings used to create the depth cueing effect. - * - * Since: 0.6 - * - * Deprecated: 1.10: The fog-related API in #ClutterStage has been - * deprecated as well. - */ -struct _ClutterFog -{ - gfloat z_near; - gfloat z_far; -}; - /** * ClutterFrameInfo: (skip) */ @@ -151,119 +132,116 @@ typedef struct _ClutterCapture cairo_rectangle_int_t rect; } ClutterCapture; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT GType clutter_perspective_get_type (void) G_GNUC_CONST; -CLUTTER_DEPRECATED_IN_1_10 -GType clutter_fog_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT GType clutter_stage_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterActor * clutter_stage_new (void); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_stage_set_perspective (ClutterStage *stage, ClutterPerspective *perspective); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_stage_get_perspective (ClutterStage *stage, ClutterPerspective *perspective); -CLUTTER_AVAILABLE_IN_ALL -void clutter_stage_set_fullscreen (ClutterStage *stage, - gboolean fullscreen); -CLUTTER_AVAILABLE_IN_ALL -gboolean clutter_stage_get_fullscreen (ClutterStage *stage); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_stage_show_cursor (ClutterStage *stage); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_stage_hide_cursor (ClutterStage *stage); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_stage_set_title (ClutterStage *stage, const gchar *title); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT const gchar * clutter_stage_get_title (ClutterStage *stage); -CLUTTER_AVAILABLE_IN_ALL -void clutter_stage_set_user_resizable (ClutterStage *stage, - gboolean resizable); -CLUTTER_AVAILABLE_IN_ALL -gboolean clutter_stage_get_user_resizable (ClutterStage *stage); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_stage_set_minimum_size (ClutterStage *stage, guint width, guint height); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_stage_get_minimum_size (ClutterStage *stage, guint *width, guint *height); -CLUTTER_AVAILABLE_IN_ALL -void clutter_stage_set_no_clear_hint (ClutterStage *stage, - gboolean no_clear); -CLUTTER_AVAILABLE_IN_ALL -gboolean clutter_stage_get_no_clear_hint (ClutterStage *stage); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_stage_set_use_alpha (ClutterStage *stage, gboolean use_alpha); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gboolean clutter_stage_get_use_alpha (ClutterStage *stage); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_stage_set_key_focus (ClutterStage *stage, ClutterActor *actor); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterActor * clutter_stage_get_key_focus (ClutterStage *stage); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_stage_set_throttle_motion_events (ClutterStage *stage, gboolean throttle); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gboolean clutter_stage_get_throttle_motion_events (ClutterStage *stage); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_stage_set_motion_events_enabled (ClutterStage *stage, gboolean enabled); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gboolean clutter_stage_get_motion_events_enabled (ClutterStage *stage); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_stage_set_accept_focus (ClutterStage *stage, gboolean accept_focus); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gboolean clutter_stage_get_accept_focus (ClutterStage *stage); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gboolean clutter_stage_event (ClutterStage *stage, ClutterEvent *event); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterActor * clutter_stage_get_actor_at_pos (ClutterStage *stage, ClutterPickMode pick_mode, - gint x, - gint y); -CLUTTER_AVAILABLE_IN_ALL + float x, + float y); +CLUTTER_EXPORT guchar * clutter_stage_read_pixels (ClutterStage *stage, gint x, gint y, gint width, gint height); -CLUTTER_AVAILABLE_IN_ALL -void clutter_stage_get_redraw_clip_bounds (ClutterStage *stage, - cairo_rectangle_int_t *clip); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_stage_ensure_viewport (ClutterStage *stage); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_stage_ensure_redraw (ClutterStage *stage); +CLUTTER_EXPORT +gboolean clutter_stage_is_redraw_queued (ClutterStage *stage); + #ifdef CLUTTER_ENABLE_EXPERIMENTAL_API -CLUTTER_AVAILABLE_IN_1_14 +CLUTTER_EXPORT void clutter_stage_set_sync_delay (ClutterStage *stage, gint sync_delay); -CLUTTER_AVAILABLE_IN_1_14 +CLUTTER_EXPORT void clutter_stage_skip_sync_delay (ClutterStage *stage); #endif -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT +void clutter_stage_schedule_update (ClutterStage *stage); + +CLUTTER_EXPORT +gboolean clutter_stage_get_capture_final_size (ClutterStage *stage, + cairo_rectangle_int_t *rect, + int *width, + int *height, + float *scale); + +CLUTTER_EXPORT gboolean clutter_stage_capture (ClutterStage *stage, gboolean paint, cairo_rectangle_int_t *rect, - ClutterCapture **captures, - int *n_captures); + ClutterCapture **out_captures, + int *out_n_captures); +CLUTTER_EXPORT +ClutterStageView * clutter_stage_get_view_at (ClutterStage *stage, + float x, + float y); G_END_DECLS diff --git a/clutter/clutter/clutter-swipe-action.c b/clutter/clutter/clutter-swipe-action.c index 554f360fc..2706e1d82 100644 --- a/clutter/clutter/clutter-swipe-action.c +++ b/clutter/clutter/clutter-swipe-action.c @@ -37,9 +37,7 @@ * Since: 1.8 */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include "clutter-swipe-action.h" diff --git a/clutter/clutter/clutter-swipe-action.h b/clutter/clutter/clutter-swipe-action.h index 9c18e94ad..1bf50c6bf 100644 --- a/clutter/clutter/clutter-swipe-action.h +++ b/clutter/clutter/clutter-swipe-action.h @@ -98,10 +98,10 @@ struct _ClutterSwipeActionClass void (* _clutter_swipe_action6) (void); }; -CLUTTER_AVAILABLE_IN_1_8 +CLUTTER_EXPORT GType clutter_swipe_action_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_8 +CLUTTER_EXPORT ClutterAction * clutter_swipe_action_new (void); G_END_DECLS diff --git a/clutter/clutter/clutter-tap-action.c b/clutter/clutter/clutter-tap-action.c index ae9f69da7..e5353f040 100644 --- a/clutter/clutter/clutter-tap-action.c +++ b/clutter/clutter/clutter-tap-action.c @@ -53,9 +53,7 @@ * Since: 1.14 */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include "clutter-tap-action.h" @@ -124,8 +122,7 @@ clutter_tap_action_class_init (ClutterTapActionClass *klass) G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ClutterTapActionClass, tap), - NULL, NULL, - _clutter_marshal_VOID__OBJECT, + NULL, NULL, NULL, G_TYPE_NONE, 1, CLUTTER_TYPE_ACTOR); } diff --git a/clutter/clutter/clutter-tap-action.h b/clutter/clutter/clutter-tap-action.h index ade9c42ec..97fd604f3 100644 --- a/clutter/clutter/clutter-tap-action.h +++ b/clutter/clutter/clutter-tap-action.h @@ -92,10 +92,10 @@ struct _ClutterTapActionClass void (* _clutter_tap_action6) (void); }; -CLUTTER_AVAILABLE_IN_1_14 +CLUTTER_EXPORT GType clutter_tap_action_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_14 +CLUTTER_EXPORT ClutterAction * clutter_tap_action_new (void); G_END_DECLS diff --git a/clutter/clutter/clutter-text-buffer.c b/clutter/clutter/clutter-text-buffer.c index b7daf2336..1436921d1 100644 --- a/clutter/clutter/clutter-text-buffer.c +++ b/clutter/clutter/clutter-text-buffer.c @@ -19,9 +19,7 @@ * Author: Stef Walter */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include "clutter-text-buffer.h" #include "clutter-marshal.h" @@ -52,7 +50,8 @@ /* Initial size of buffer, in bytes */ #define MIN_SIZE 16 -enum { +enum +{ PROP_0, PROP_TEXT, PROP_LENGTH, @@ -62,7 +61,8 @@ enum { static GParamSpec *obj_props[PROP_LAST] = { NULL, }; -enum { +enum +{ INSERTED_TEXT, DELETED_TEXT, LAST_SIGNAL @@ -162,16 +162,16 @@ clutter_text_buffer_normal_insert_text (ClutterTextBuffer *buffer, } /* Could be a password, so can't leave stuff in memory. */ - et_new = malloc (pv->normal_text_size); + et_new = g_malloc (pv->normal_text_size); memcpy (et_new, pv->normal_text, MIN (prev_size, pv->normal_text_size)); trash_area (pv->normal_text, prev_size); - free (pv->normal_text); + g_free (pv->normal_text); pv->normal_text = et_new; } /* Actual text insertion */ at = g_utf8_offset_to_pointer (pv->normal_text, position) - pv->normal_text; - g_memmove (pv->normal_text + at + n_bytes, pv->normal_text + at, pv->normal_text_bytes - at); + memmove (pv->normal_text + at + n_bytes, pv->normal_text + at, pv->normal_text_bytes - at); memcpy (pv->normal_text + at, chars, n_bytes); /* Book keeping */ @@ -201,7 +201,7 @@ clutter_text_buffer_normal_delete_text (ClutterTextBuffer *buffer, start = g_utf8_offset_to_pointer (pv->normal_text, position) - pv->normal_text; end = g_utf8_offset_to_pointer (pv->normal_text, position + n_chars) - pv->normal_text; - g_memmove (pv->normal_text + start, pv->normal_text + end, pv->normal_text_bytes + 1 - end); + memmove (pv->normal_text + start, pv->normal_text + end, pv->normal_text_bytes + 1 - end); pv->normal_text_chars -= n_chars; pv->normal_text_bytes -= (end - start); @@ -228,8 +228,8 @@ clutter_text_buffer_real_inserted_text (ClutterTextBuffer *buffer, const gchar *chars, guint n_chars) { - g_object_notify (G_OBJECT (buffer), "text"); - g_object_notify (G_OBJECT (buffer), "length"); + g_object_notify_by_pspec (G_OBJECT (buffer), obj_props[PROP_TEXT]); + g_object_notify_by_pspec (G_OBJECT (buffer), obj_props[PROP_LENGTH]); } static void @@ -237,8 +237,8 @@ clutter_text_buffer_real_deleted_text (ClutterTextBuffer *buffer, guint position, guint n_chars) { - g_object_notify (G_OBJECT (buffer), "text"); - g_object_notify (G_OBJECT (buffer), "length"); + g_object_notify_by_pspec (G_OBJECT (buffer), obj_props[PROP_TEXT]); + g_object_notify_by_pspec (G_OBJECT (buffer), obj_props[PROP_LENGTH]); } /* -------------------------------------------------------------------------------- @@ -265,7 +265,7 @@ clutter_text_buffer_finalize (GObject *obj) if (pv->normal_text) { trash_area (pv->normal_text, pv->normal_text_size); - free (pv->normal_text); + g_free (pv->normal_text); pv->normal_text = NULL; pv->normal_text_bytes = pv->normal_text_size = 0; pv->normal_text_chars = 0; @@ -598,7 +598,7 @@ clutter_text_buffer_set_max_length (ClutterTextBuffer *buffer, clutter_text_buffer_delete_text (buffer, max_length, -1); buffer->priv->max_length = max_length; - g_object_notify (G_OBJECT (buffer), "max-length"); + g_object_notify_by_pspec (G_OBJECT (buffer), obj_props[PROP_MAX_LENGTH]); } /** diff --git a/clutter/clutter/clutter-text-buffer.h b/clutter/clutter/clutter-text-buffer.h index 468b06070..344e4cbdc 100644 --- a/clutter/clutter/clutter-text-buffer.h +++ b/clutter/clutter/clutter-text-buffer.h @@ -123,46 +123,46 @@ struct _ClutterTextBufferClass void (*_clutter_reserved8) (void); }; -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT GType clutter_text_buffer_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT ClutterTextBuffer* clutter_text_buffer_new (void); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT ClutterTextBuffer* clutter_text_buffer_new_with_text (const gchar *text, gssize text_len); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT gsize clutter_text_buffer_get_bytes (ClutterTextBuffer *buffer); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT guint clutter_text_buffer_get_length (ClutterTextBuffer *buffer); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT const gchar* clutter_text_buffer_get_text (ClutterTextBuffer *buffer); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_text_buffer_set_text (ClutterTextBuffer *buffer, const gchar *chars, gint n_chars); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_text_buffer_set_max_length (ClutterTextBuffer *buffer, gint max_length); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT gint clutter_text_buffer_get_max_length (ClutterTextBuffer *buffer); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT guint clutter_text_buffer_insert_text (ClutterTextBuffer *buffer, guint position, const gchar *chars, gint n_chars); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT guint clutter_text_buffer_delete_text (ClutterTextBuffer *buffer, guint position, gint n_chars); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_text_buffer_emit_inserted_text (ClutterTextBuffer *buffer, guint position, const gchar *chars, guint n_chars); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_text_buffer_emit_deleted_text (ClutterTextBuffer *buffer, guint position, guint n_chars); diff --git a/clutter/clutter/clutter-text.c b/clutter/clutter/clutter-text.c index aced707e1..3da410f2b 100644 --- a/clutter/clutter/clutter-text.c +++ b/clutter/clutter/clutter-text.c @@ -38,9 +38,7 @@ * #ClutterText is available since Clutter 1.0 */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include #include @@ -146,18 +144,20 @@ struct _ClutterTextPrivate */ gint x_pos; - /* the x position of the PangoLayout when in - * single line mode, to scroll the contents of the + /* the x position of the PangoLayout (in both physical and logical pixels) + * when in single line mode, to scroll the contents of the * text actor */ gint text_x; + gint text_logical_x; - /* the y position of the PangoLayout, fixed to 0 by - * default for now */ + /* the y position of the PangoLayout (in both physical and logical pixels), + * fixed to 0 by default for now */ gint text_y; + gint text_logical_y; /* Where to draw the cursor */ - ClutterRect cursor_rect; + graphene_rect_t cursor_rect; ClutterColor cursor_color; guint cursor_size; @@ -178,15 +178,18 @@ struct _ClutterTextPrivate guint password_hint_timeout; /* Signal handler for when the backend changes its font settings */ - guint settings_changed_id; + gulong settings_changed_id; /* Signal handler for when the :text-direction changes */ - guint direction_changed_id; + gulong direction_changed_id; ClutterInputFocus *input_focus; ClutterInputContentHintFlags input_hints; ClutterInputContentPurpose input_purpose; + /* Signal handler for when the :resource-scale changes */ + gulong resource_scale_changed_id; + /* bitfields */ guint alignment : 2; guint wrap : 1; @@ -279,7 +282,9 @@ static const ClutterColor default_selection_color = { 0, 0, 0, 255 }; static const ClutterColor default_text_color = { 0, 0, 0, 255 }; static const ClutterColor default_selected_text_color = { 0, 0, 0, 255 }; -static ClutterAnimatableIface *parent_animatable_iface = NULL; +static CoglPipeline *default_color_pipeline = NULL; + +static ClutterAnimatableInterface *parent_animatable_iface = NULL; static ClutterScriptableIface *parent_scriptable_iface = NULL; /* ClutterTextInputFocus */ @@ -290,6 +295,33 @@ G_DECLARE_FINAL_TYPE (ClutterTextInputFocus, clutter_text_input_focus, G_DEFINE_TYPE (ClutterTextInputFocus, clutter_text_input_focus, CLUTTER_TYPE_INPUT_FOCUS) +/* Utilities pango to (logical) pixels functions */ +static float +pixels_to_pango (float px) +{ + return ceilf (px * (float) PANGO_SCALE); +} + +static float +logical_pixels_to_pango (float px, + float scale) +{ + return pixels_to_pango (px * scale); +} + +static float +pango_to_pixels (float size) +{ + return ceilf (size / (float) PANGO_SCALE); +} + +static float +pango_to_logical_pixels (float size, + float scale) +{ + return pango_to_pixels (size / scale); +} + static void clutter_text_input_focus_request_surrounding (ClutterInputFocus *focus) { @@ -316,13 +348,23 @@ clutter_text_input_focus_request_surrounding (ClutterInputFocus *focus) static void clutter_text_input_focus_delete_surrounding (ClutterInputFocus *focus, - guint offset, + int offset, guint len) { ClutterText *clutter_text = CLUTTER_TEXT_INPUT_FOCUS (focus)->text; + int cursor; + int start; + cursor = clutter_text_get_cursor_position (clutter_text); + start = cursor + offset; + if (start < 0) + { + g_warning ("The offset '%d' of deleting surrounding is larger than the cursor pos '%d'", + offset, cursor); + return; + } if (clutter_text_get_editable (clutter_text)) - clutter_text_delete_text (clutter_text, offset, len); + clutter_text_delete_text (clutter_text, start, len); } static void @@ -389,7 +431,7 @@ clutter_text_input_focus_new (ClutterText *text) /* ClutterText */ static void clutter_scriptable_iface_init (ClutterScriptableIface *iface); -static void clutter_animatable_iface_init (ClutterAnimatableIface *iface); +static void clutter_animatable_iface_init (ClutterAnimatableInterface *iface); G_DEFINE_TYPE_WITH_CODE (ClutterText, clutter_text, @@ -550,6 +592,63 @@ clutter_text_get_display_text (ClutterText *self) } } +static void +ensure_effective_pango_scale_attribute (ClutterText *self) +{ + float resource_scale; + ClutterTextPrivate *priv = self->priv; + + if (!clutter_actor_get_resource_scale (CLUTTER_ACTOR (self), &resource_scale) || + resource_scale == 1.0) + return; + + if (priv->effective_attrs != NULL) + { + PangoAttrIterator *iter; + PangoAttribute *scale_attrib; + PangoAttrList *old_attributes; + + old_attributes = priv->effective_attrs; + priv->effective_attrs = pango_attr_list_copy (priv->effective_attrs); + pango_attr_list_unref (old_attributes); + + iter = pango_attr_list_get_iterator (priv->effective_attrs); + scale_attrib = pango_attr_iterator_get (iter, PANGO_ATTR_SCALE); + + if (scale_attrib != NULL) + resource_scale *= ((PangoAttrFloat *) scale_attrib)->value; + + pango_attr_iterator_destroy (iter); + } + else + priv->effective_attrs = pango_attr_list_new (); + + pango_attr_list_change (priv->effective_attrs, + pango_attr_scale_new (resource_scale)); +} + +static void +set_effective_pango_attributes (ClutterText *self, + PangoAttrList *attributes) +{ + ClutterTextPrivate *priv = self->priv; + + if (attributes != NULL) + { + PangoAttrList *old_attributes = priv->effective_attrs; + priv->effective_attrs = pango_attr_list_ref (attributes); + + if (old_attributes != NULL) + pango_attr_list_unref (old_attributes); + } + else + { + g_clear_pointer (&priv->effective_attrs, pango_attr_list_unref); + } + + ensure_effective_pango_scale_attribute (self); +} + static inline void clutter_text_ensure_effective_attributes (ClutterText *self) { @@ -563,21 +662,25 @@ clutter_text_ensure_effective_attributes (ClutterText *self) /* Same as if we don't have any attribute at all. * We also ignore markup attributes for editable. */ if (priv->attrs == NULL && (priv->editable || priv->markup_attrs == NULL)) - return; + { + set_effective_pango_attributes (self, NULL); + return; + } if (priv->attrs != NULL) { /* If there are no markup attributes, or if this is editable (in which * case we ignore markup), then we can just use these attrs directly */ if (priv->editable || priv->markup_attrs == NULL) - priv->effective_attrs = pango_attr_list_ref (priv->attrs); + set_effective_pango_attributes (self, priv->attrs); else { /* Otherwise we need to merge the two lists */ + PangoAttrList *effective_attrs; PangoAttrIterator *iter; GSList *attributes, *l; - priv->effective_attrs = pango_attr_list_copy (priv->markup_attrs); + effective_attrs = pango_attr_list_copy (priv->markup_attrs); iter = pango_attr_list_get_iterator (priv->attrs); do @@ -588,7 +691,7 @@ clutter_text_ensure_effective_attributes (ClutterText *self) { PangoAttribute *attr = l->data; - pango_attr_list_insert (priv->effective_attrs, attr); + pango_attr_list_insert (effective_attrs, attr); } g_slist_free (attributes); @@ -596,12 +699,14 @@ clutter_text_ensure_effective_attributes (ClutterText *self) while (pango_attr_iterator_next (iter)); pango_attr_iterator_destroy (iter); + + set_effective_pango_attributes (self, effective_attrs); + pango_attr_list_unref (effective_attrs); } } else if (priv->markup_attrs != NULL) { - /* We can just use the markup attributes directly */ - priv->effective_attrs = pango_attr_list_ref (priv->markup_attrs); + set_effective_pango_attributes (self, priv->markup_attrs); } } @@ -656,7 +761,7 @@ clutter_text_create_layout_no_cache (ClutterText *text, if (priv->password_char != 0) pango_dir = PANGO_DIRECTION_NEUTRAL; else - pango_dir = pango_find_base_dir (contents, contents_len); + pango_dir = _clutter_pango_find_base_dir (contents, contents_len); if (pango_dir == PANGO_DIRECTION_NEUTRAL) { @@ -664,7 +769,14 @@ clutter_text_create_layout_no_cache (ClutterText *text, ClutterTextDirection text_dir; if (clutter_actor_has_key_focus (CLUTTER_ACTOR (text))) - pango_dir = _clutter_backend_get_keymap_direction (backend); + { + ClutterSeat *seat; + ClutterKeymap *keymap; + + seat = clutter_backend_get_default_seat (backend); + keymap = clutter_seat_get_keymap (seat); + pango_dir = clutter_keymap_get_direction (keymap); + } else { text_dir = clutter_actor_get_text_direction (CLUTTER_ACTOR (text)); @@ -699,7 +811,7 @@ clutter_text_create_layout_no_cache (ClutterText *text, pango_layout_set_width (layout, width); pango_layout_set_height (layout, height); - free (contents); + g_free (contents); return layout; } @@ -754,7 +866,7 @@ clutter_text_set_font_description_internal (ClutterText *self, priv->font_desc = pango_font_description_copy (desc); /* update the font name string we use */ - free (priv->font_name); + g_free (priv->font_name); priv->font_name = pango_font_description_to_string (priv->font_desc); clutter_text_dirty_cache (self); @@ -794,7 +906,7 @@ clutter_text_settings_changed_cb (ClutterText *text) clutter_text_set_font_description_internal (text, font_desc, TRUE); pango_font_description_free (font_desc); - free (font_name); + g_free (font_name); } clutter_text_dirty_cache (text); @@ -810,6 +922,18 @@ clutter_text_direction_changed_cb (GObject *gobject, /* no need to queue a relayout: set_text_direction() will do that for us */ } +static void +clutter_text_resource_scale_changed_cb (GObject *gobject, + GParamSpec *pspec) +{ + ClutterText *self = CLUTTER_TEXT (gobject); + ClutterTextPrivate *priv = self->priv; + + g_clear_pointer (&priv->effective_attrs, pango_attr_list_unref); + clutter_text_dirty_cache (self); + clutter_actor_queue_relayout (CLUTTER_ACTOR (gobject)); +} + /* * clutter_text_create_layout: * @text: a #ClutterText @@ -877,7 +1001,7 @@ clutter_text_create_layout (ClutterText *text, !((priv->editable && priv->single_line_mode) || (priv->ellipsize == PANGO_ELLIPSIZE_NONE && !priv->wrap)))) { - width = allocation_width * 1024 + 0.5f; + width = pixels_to_pango (allocation_width); } /* Pango only uses height if ellipsization is enabled, so don't set @@ -894,7 +1018,7 @@ clutter_text_create_layout (ClutterText *text, priv->ellipsize != PANGO_ELLIPSIZE_NONE && !priv->single_line_mode) { - height = allocation_height * 1024 + 0.5f; + height = pixels_to_pango (allocation_height); } /* Search for a cached layout with the same width and keep @@ -991,6 +1115,37 @@ clutter_text_create_layout (ClutterText *text, return oldest_cache->layout; } +static PangoLayout * +create_text_layout_with_scale (ClutterText *text, + gfloat allocation_width, + gfloat allocation_height, + gfloat scale) +{ + if (allocation_width > 0) + allocation_width = roundf (allocation_width * scale); + + if (allocation_height > 0) + allocation_height = roundf (allocation_height * scale); + + return clutter_text_create_layout (text, allocation_width, allocation_height); +} + +static PangoLayout * +maybe_create_text_layout_with_resource_scale (ClutterText *text, + gfloat allocation_width, + gfloat allocation_height) +{ + float resource_scale; + + if (!clutter_actor_get_resource_scale (CLUTTER_ACTOR (text), &resource_scale)) + return NULL; + + return create_text_layout_with_scale (text, + allocation_width, + allocation_height, + resource_scale); +} + /** * clutter_text_coords_to_position: * @self: a #ClutterText @@ -1011,14 +1166,18 @@ clutter_text_coords_to_position (ClutterText *self, gint index_; gint px, py; gint trailing; + gfloat resource_scale; g_return_val_if_fail (CLUTTER_IS_TEXT (self), 0); + if (!clutter_actor_get_resource_scale (CLUTTER_ACTOR (self), &resource_scale)) + return 0; + /* Take any offset due to scrolling into account, and normalize * the coordinates to PangoScale units */ - px = (x - self->priv->text_x) * PANGO_SCALE; - py = (y - self->priv->text_y) * PANGO_SCALE; + px = logical_pixels_to_pango (x - self->priv->text_logical_x, resource_scale); + py = logical_pixels_to_pango (y - self->priv->text_logical_y, resource_scale); pango_layout_xy_to_index (clutter_text_get_layout (self), px, py, @@ -1027,26 +1186,12 @@ clutter_text_coords_to_position (ClutterText *self, return index_ + trailing; } -/** - * clutter_text_position_to_coords: - * @self: a #ClutterText - * @position: position in characters - * @x: (out): return location for the X coordinate, or %NULL - * @y: (out): return location for the Y coordinate, or %NULL - * @line_height: (out): return location for the line height, or %NULL - * - * Retrieves the coordinates of the given @position. - * - * Return value: %TRUE if the conversion was successful - * - * Since: 1.0 - */ -gboolean -clutter_text_position_to_coords (ClutterText *self, - gint position, - gfloat *x, - gfloat *y, - gfloat *line_height) +static gboolean +clutter_text_position_to_coords_internal (ClutterText *self, + gint position, + gfloat *x, + gfloat *y, + gfloat *line_height) { ClutterTextPrivate *priv; PangoRectangle rect; @@ -1102,7 +1247,7 @@ clutter_text_position_to_coords (ClutterText *self, else index_ = position * password_char_bytes; - free (text); + g_free (text); g_string_free (tmp, TRUE); } @@ -1112,7 +1257,7 @@ clutter_text_position_to_coords (ClutterText *self, if (x) { - *x = (gfloat) rect.x / 1024.0f; + *x = pango_to_pixels (rect.x); /* Take any offset due to scrolling into account */ if (priv->single_line_mode) @@ -1120,19 +1265,63 @@ clutter_text_position_to_coords (ClutterText *self, } if (y) - *y = (gfloat) rect.y / 1024.0f; + *y = pango_to_pixels (rect.y); if (line_height) - *line_height = (gfloat) rect.height / 1024.0f; + *line_height = pango_to_pixels (rect.height); return TRUE; } +/** + * clutter_text_position_to_coords: + * @self: a #ClutterText + * @position: position in characters + * @x: (out): return location for the X coordinate, or %NULL + * @y: (out): return location for the Y coordinate, or %NULL + * @line_height: (out): return location for the line height, or %NULL + * + * Retrieves the coordinates of the given @position. + * + * Return value: %TRUE if the conversion was successful + * + * Since: 1.0 + */ +gboolean +clutter_text_position_to_coords (ClutterText *self, + gint position, + gfloat *x, + gfloat *y, + gfloat *line_height) +{ + gfloat resource_scale; + gboolean ret; + + g_return_val_if_fail (CLUTTER_IS_TEXT (self), FALSE); + + if (!clutter_actor_get_resource_scale (CLUTTER_ACTOR (self), &resource_scale)) + return FALSE; + + ret = clutter_text_position_to_coords_internal (self, position, + x, y, line_height); + + if (x) + *x /= resource_scale; + + if (y) + *y /= resource_scale; + + if (line_height) + *line_height /= resource_scale; + + return ret; +} + static inline void update_cursor_location (ClutterText *self) { ClutterTextPrivate *priv = self->priv; - ClutterRect rect; + graphene_rect_t rect; float x, y; if (!priv->editable) @@ -1140,16 +1329,17 @@ update_cursor_location (ClutterText *self) rect = priv->cursor_rect; clutter_actor_get_transformed_position (CLUTTER_ACTOR (self), &x, &y); - clutter_rect_offset (&rect, x, y); + graphene_rect_offset (&rect, x, y); clutter_input_focus_set_cursor_location (priv->input_focus, &rect); } static inline void -clutter_text_ensure_cursor_position (ClutterText *self) +clutter_text_ensure_cursor_position (ClutterText *self, + float scale) { ClutterTextPrivate *priv = self->priv; gfloat x, y, cursor_height; - ClutterRect cursor_rect = CLUTTER_RECT_INIT_ZERO; + graphene_rect_t cursor_rect = GRAPHENE_RECT_INIT_ZERO; gint position; position = priv->position; @@ -1168,34 +1358,24 @@ clutter_text_ensure_cursor_position (ClutterText *self) priv->preedit_set ? priv->preedit_cursor_pos : 0); x = y = cursor_height = 0; - clutter_text_position_to_coords (self, position, - &x, &y, - &cursor_height); + clutter_text_position_to_coords_internal (self, position, + &x, &y, + &cursor_height); - clutter_rect_init (&cursor_rect, - x, - y + CURSOR_Y_PADDING, - priv->cursor_size, - cursor_height - 2 * CURSOR_Y_PADDING); + graphene_rect_init (&cursor_rect, + x, + y + CURSOR_Y_PADDING * scale, + priv->cursor_size * scale, + cursor_height - 2 * CURSOR_Y_PADDING * scale); - if (!clutter_rect_equals (&priv->cursor_rect, &cursor_rect)) + if (!graphene_rect_equal (&priv->cursor_rect, &cursor_rect)) { - ClutterGeometry cursor_pos; - priv->cursor_rect = cursor_rect; - /* XXX:2.0 - remove */ - cursor_pos.x = clutter_rect_get_x (&priv->cursor_rect); - cursor_pos.y = clutter_rect_get_y (&priv->cursor_rect); - cursor_pos.width = clutter_rect_get_width (&priv->cursor_rect); - cursor_pos.height = clutter_rect_get_height (&priv->cursor_rect); - g_signal_emit (self, text_signals[CURSOR_EVENT], 0, &cursor_pos); - + g_signal_emit (self, text_signals[CURSOR_EVENT], 0, &cursor_rect); g_signal_emit (self, text_signals[CURSOR_CHANGED], 0); -#ifdef __CLUTTER_WAYLAND_COMPOSITOR_H__ update_cursor_location (self); -#endif } } @@ -1317,7 +1497,7 @@ clutter_text_set_markup_internal (ClutterText *self, if (text) { clutter_text_buffer_set_text (get_buffer (self), text, -1); - free (text); + g_free (text); } /* Store the new markup attributes */ @@ -1595,24 +1775,12 @@ clutter_text_dispose (GObject *gobject) /* get rid of the entire cache */ clutter_text_dirty_cache (self); - if (priv->direction_changed_id) - { - g_signal_handler_disconnect (self, priv->direction_changed_id); - priv->direction_changed_id = 0; - } + g_clear_signal_handler (&priv->direction_changed_id, self); + g_clear_signal_handler (&priv->resource_scale_changed_id, self); + g_clear_signal_handler (&priv->settings_changed_id, + clutter_get_default_backend ()); - if (priv->settings_changed_id) - { - g_signal_handler_disconnect (clutter_get_default_backend (), - priv->settings_changed_id); - priv->settings_changed_id = 0; - } - - if (priv->password_hint_id) - { - g_source_remove (priv->password_hint_id); - priv->password_hint_id = 0; - } + g_clear_handle_id (&priv->password_hint_id, g_source_remove); clutter_text_set_buffer (self, NULL); @@ -1640,7 +1808,7 @@ clutter_text_finalize (GObject *gobject) clutter_text_dirty_paint_volume (self); clutter_text_set_buffer (self, NULL); - free (priv->font_name); + g_free (priv->font_name); g_clear_object (&priv->input_focus); @@ -1653,6 +1821,7 @@ typedef void (* ClutterTextSelectionFunc) (ClutterText *text, static void clutter_text_foreach_selection_rectangle (ClutterText *self, + float scale, ClutterTextSelectionFunc func, gpointer user_data) { @@ -1704,9 +1873,9 @@ clutter_text_foreach_selection_rectangle (ClutterText *self, &n_ranges); pango_layout_line_x_to_index (line, 0, &index_, NULL); - clutter_text_position_to_coords (self, - bytes_to_offset (utf8, index_), - NULL, &y, &height); + clutter_text_position_to_coords_internal (self, + bytes_to_offset (utf8, index_), + NULL, &y, &height); box.y1 = y; box.y2 = y + height; @@ -1716,26 +1885,26 @@ clutter_text_foreach_selection_rectangle (ClutterText *self, gfloat range_x; gfloat range_width; - range_x = ranges[i * 2] / PANGO_SCALE; + range_x = pango_to_pixels (ranges[i * 2]); /* Account for any scrolling in single line mode */ if (priv->single_line_mode) range_x += priv->text_x; - range_width = ((gfloat) ranges[i * 2 + 1] - (gfloat) ranges[i * 2]) - / PANGO_SCALE; - + range_width = pango_to_pixels (ranges[i * 2 + 1] - ranges[i * 2]); box.x1 = range_x; - box.x2 = ceilf (range_x + range_width + .5f); + box.x2 = ceilf (range_x + range_width); + + clutter_actor_box_scale (&box, scale); func (self, &box, user_data); } - free (ranges); + g_free (ranges); } - free (utf8); + g_free (utf8); } static void @@ -1746,9 +1915,18 @@ add_selection_rectangle_to_path (ClutterText *text, cogl_path_rectangle (user_data, box->x1, box->y1, box->x2, box->y2); } +static void +clutter_text_foreach_selection_rectangle_prescaled (ClutterText *self, + ClutterTextSelectionFunc func, + gpointer user_data) +{ + clutter_text_foreach_selection_rectangle (self, 1.0f, func, user_data); +} + /* Draws the selected text, its background, and the cursor */ static void -selection_paint (ClutterText *self) +selection_paint (ClutterText *self, + CoglFramebuffer *fb) { ClutterTextPrivate *priv = self->priv; ClutterActor *actor = CLUTTER_ACTOR (self); @@ -1760,33 +1938,38 @@ selection_paint (ClutterText *self) if (priv->position == priv->selection_bound) { + CoglPipeline *color_pipeline = cogl_pipeline_copy (default_color_pipeline); + CoglColor cogl_color; + /* No selection, just draw the cursor */ if (priv->cursor_color_set) color = &priv->cursor_color; else color = &priv->text_color; - cogl_set_source_color4ub (color->red, + + cogl_color_init_from_4ub (&cogl_color, + color->red, color->green, color->blue, paint_opacity * color->alpha / 255); - - cogl_rectangle (priv->cursor_rect.origin.x, - priv->cursor_rect.origin.y, - priv->cursor_rect.origin.x + priv->cursor_rect.size.width, - priv->cursor_rect.origin.y + priv->cursor_rect.size.height); + cogl_color_premultiply (&cogl_color); + cogl_pipeline_set_color (color_pipeline, &cogl_color); + + cogl_framebuffer_draw_rectangle (fb, + color_pipeline, + priv->cursor_rect.origin.x, + priv->cursor_rect.origin.y, + priv->cursor_rect.origin.x + priv->cursor_rect.size.width, + priv->cursor_rect.origin.y + priv->cursor_rect.size.height); } else { /* Paint selection background first */ + CoglPipeline *color_pipeline = cogl_pipeline_copy (default_color_pipeline); PangoLayout *layout = clutter_text_get_layout (self); CoglPath *selection_path = cogl_path_new (); CoglColor cogl_color = { 0, }; - CoglFramebuffer *fb; - - fb = _clutter_actor_get_active_framebuffer (actor); - if (G_UNLIKELY (fb == NULL)) - return; /* Paint selection background */ if (priv->selection_color_set) @@ -1796,16 +1979,19 @@ selection_paint (ClutterText *self) else color = &priv->text_color; - cogl_set_source_color4ub (color->red, + cogl_color_init_from_4ub (&cogl_color, + color->red, color->green, color->blue, paint_opacity * color->alpha / 255); + cogl_color_premultiply (&cogl_color); + cogl_pipeline_set_color (color_pipeline, &cogl_color); - clutter_text_foreach_selection_rectangle (self, - add_selection_rectangle_to_path, - selection_path); + clutter_text_foreach_selection_rectangle_prescaled (self, + add_selection_rectangle_to_path, + selection_path); - cogl_path_fill (selection_path); + cogl_framebuffer_fill_path (fb, color_pipeline, selection_path); /* Paint selected text */ cogl_framebuffer_push_path_clip (fb, selection_path); @@ -1822,7 +2008,7 @@ selection_paint (ClutterText *self) color->blue, paint_opacity * color->alpha / 255); - cogl_pango_render_layout (layout, priv->text_x, 0, &cogl_color, 0); + cogl_pango_show_layout (fb, layout, priv->text_x, 0, &cogl_color); cogl_framebuffer_pop_clip (fb); } @@ -1846,7 +2032,7 @@ clutter_text_move_word_backward (ClutterText *self, while (retval > 0 && !log_attrs[retval].is_word_start) retval -= 1; - free (log_attrs); + g_free (log_attrs); } return retval; @@ -1872,7 +2058,7 @@ clutter_text_move_word_forward (ClutterText *self, while (retval < n_chars && !log_attrs[retval].is_word_end) retval += 1; - free (log_attrs); + g_free (log_attrs); } return retval; @@ -2000,7 +2186,8 @@ clutter_text_press (ClutterActor *actor, return CLUTTER_EVENT_PROPAGATE; clutter_actor_grab_key_focus (actor); - // clutter_input_focus_request_toggle_input_panel (priv->input_focus); + clutter_input_focus_set_input_panel_state (priv->input_focus, + CLUTTER_INPUT_PANEL_STATE_TOGGLE); /* if the actor is empty we just reset everything and not * set up the dragging of the selection since there's nothing @@ -2064,7 +2251,10 @@ clutter_text_press (ClutterActor *actor, priv->in_select_drag = TRUE; if (type == CLUTTER_BUTTON_PRESS) - clutter_grab_pointer (actor); + { + clutter_input_device_grab (clutter_event_get_device (event), + actor); + } else { clutter_input_device_sequence_grab (clutter_event_get_device (event), @@ -2122,7 +2312,7 @@ clutter_text_release (ClutterActor *actor, { if (!priv->in_select_touch) { - clutter_ungrab_pointer (); + clutter_input_device_ungrab (clutter_event_get_device (event)); priv->in_select_drag = FALSE; return CLUTTER_EVENT_STOP; @@ -2228,7 +2418,7 @@ clutter_text_key_press (ClutterActor *actor, if (!(event->flags & CLUTTER_EVENT_FLAG_INPUT_METHOD) && clutter_input_focus_is_focused (priv->input_focus) && - clutter_input_focus_filter_key_event (priv->input_focus, event)) + clutter_input_focus_filter_event (priv->input_focus, (ClutterEvent *) event)) return CLUTTER_EVENT_STOP; /* we allow passing synthetic events that only contain @@ -2273,8 +2463,7 @@ clutter_text_key_press (ClutterActor *actor, if (priv->show_password_hint) { - if (priv->password_hint_id != 0) - g_source_remove (priv->password_hint_id); + g_clear_handle_id (&priv->password_hint_id, g_source_remove); priv->password_hint_visible = TRUE; priv->password_hint_id = @@ -2298,7 +2487,7 @@ clutter_text_key_release (ClutterActor *actor, ClutterTextPrivate *priv = self->priv; if (clutter_input_focus_is_focused (priv->input_focus) && - clutter_input_focus_filter_key_event (priv->input_focus, event)) + clutter_input_focus_filter_event (priv->input_focus, (ClutterEvent *) event)) return CLUTTER_EVENT_STOP; return CLUTTER_EVENT_PROPAGATE; @@ -2376,7 +2565,8 @@ clutter_text_compute_layout_offsets (ClutterText *self, #define TEXT_PADDING 2 static void -clutter_text_paint (ClutterActor *self) +clutter_text_paint (ClutterActor *self, + ClutterPaintContext *paint_context) { ClutterText *text = CLUTTER_TEXT (self); ClutterTextPrivate *priv = text->priv; @@ -2392,14 +2582,9 @@ clutter_text_paint (ClutterActor *self) guint n_chars; float alloc_width; float alloc_height; + float resource_scale; - /* FIXME: this should not be needed, but apparently the text-cache - * test unit manages to get in a situation where the active frame - * buffer is NULL - */ - fb = _clutter_actor_get_active_framebuffer (self); - if (fb == NULL) - fb = cogl_get_draw_framebuffer (); + fb = clutter_paint_context_get_framebuffer (paint_context); /* Note that if anything in this paint method changes it needs to be reflected in the get_paint_volume implementation which is tightly @@ -2407,12 +2592,20 @@ clutter_text_paint (ClutterActor *self) n_chars = clutter_text_buffer_get_length (get_buffer (text)); clutter_actor_get_allocation_box (self, &alloc); - alloc_width = alloc.x2 - alloc.x1; - alloc_height = alloc.y2 - alloc.y1; + + if (G_UNLIKELY (default_color_pipeline == NULL)) + { + CoglContext *ctx = + clutter_backend_get_cogl_context (clutter_get_default_backend ()); + default_color_pipeline = cogl_pipeline_new (ctx); + } + + g_assert (default_color_pipeline != NULL); g_object_get (self, "background-color-set", &bg_color_set, NULL); if (bg_color_set) { + CoglPipeline *color_pipeline = cogl_pipeline_copy (default_color_pipeline); ClutterColor bg_color; clutter_actor_get_background_color (self, &bg_color); @@ -2420,11 +2613,21 @@ clutter_text_paint (ClutterActor *self) * bg_color.alpha / 255; - cogl_set_source_color4ub (bg_color.red, + cogl_color_init_from_4ub (&color, + bg_color.red, bg_color.green, bg_color.blue, bg_color.alpha); - cogl_rectangle (0, 0, alloc_width, alloc_height); + cogl_color_premultiply (&color); + cogl_pipeline_set_color (color_pipeline, &color); + + cogl_framebuffer_draw_rectangle (fb, + color_pipeline, + 0, 0, + clutter_actor_box_get_width (&alloc), + clutter_actor_box_get_height (&alloc)); + + cogl_object_unref (color_pipeline); } /* don't bother painting an empty text actor, unless it's @@ -2435,6 +2638,12 @@ clutter_text_paint (ClutterActor *self) !clutter_text_should_draw_cursor (text)) return; + if (!clutter_actor_get_resource_scale (CLUTTER_ACTOR (self), &resource_scale)) + return; + + clutter_actor_box_scale (&alloc, resource_scale); + clutter_actor_box_get_size (&alloc, &alloc_width, &alloc_height); + if (priv->editable && priv->single_line_mode) layout = clutter_text_create_layout (text, -1, -1); else @@ -2466,8 +2675,15 @@ clutter_text_paint (ClutterActor *self) } } + if (resource_scale != 1.0f) + { + float paint_scale = 1.0f / resource_scale; + cogl_framebuffer_push_matrix (fb); + cogl_framebuffer_scale (fb, paint_scale, paint_scale, 1.0f); + } + if (clutter_text_should_draw_cursor (text)) - clutter_text_ensure_cursor_position (text); + clutter_text_ensure_cursor_position (text, resource_scale); if (priv->editable && priv->single_line_mode) { @@ -2481,13 +2697,13 @@ clutter_text_paint (ClutterActor *self) clip_set = TRUE; actor_width = alloc_width - 2 * TEXT_PADDING; - text_width = logical_rect.width / PANGO_SCALE; + text_width = pango_to_pixels (logical_rect.width); rtl = priv->resolved_direction == PANGO_DIRECTION_RTL; if (actor_width < text_width) { - gint cursor_x = clutter_rect_get_x (&priv->cursor_rect); + gint cursor_x = graphene_rect_get_x (&priv->cursor_rect); if (priv->position == -1) { @@ -2538,8 +2754,10 @@ clutter_text_paint (ClutterActor *self) { priv->text_x = text_x; priv->text_y = text_y; + priv->text_logical_x = roundf ((float) text_x / resource_scale); + priv->text_logical_y = roundf ((float) text_y / resource_scale); - clutter_text_ensure_cursor_position (text); + clutter_text_ensure_cursor_position (text, resource_scale); } real_opacity = clutter_actor_get_paint_opacity (self) @@ -2554,9 +2772,12 @@ clutter_text_paint (ClutterActor *self) priv->text_color.green, priv->text_color.blue, real_opacity); - cogl_pango_render_layout (layout, priv->text_x, priv->text_y, &color, 0); + cogl_pango_show_layout (fb, layout, priv->text_x, priv->text_y, &color); - selection_paint (text); + selection_paint (text, fb); + + if (resource_scale != 1.0f) + cogl_framebuffer_pop_matrix (fb); if (clip_set) cogl_framebuffer_pop_clip (fb); @@ -2569,7 +2790,7 @@ add_selection_to_paint_volume (ClutterText *text, { ClutterPaintVolume *total_volume = user_data; ClutterPaintVolume rect_volume; - ClutterVertex vertex; + graphene_point3d_t vertex; _clutter_paint_volume_init_static (&rect_volume, CLUTTER_ACTOR (text)); @@ -2587,26 +2808,32 @@ add_selection_to_paint_volume (ClutterText *text, static void clutter_text_get_paint_volume_for_cursor (ClutterText *text, + float resource_scale, ClutterPaintVolume *volume) { ClutterTextPrivate *priv = text->priv; - ClutterVertex origin; + graphene_point3d_t origin; - clutter_text_ensure_cursor_position (text); + clutter_text_ensure_cursor_position (text, resource_scale); if (priv->position == priv->selection_bound) { - origin.x = priv->cursor_rect.origin.x; - origin.y = priv->cursor_rect.origin.y; + float width, height; + + width = priv->cursor_rect.size.width / resource_scale; + height = priv->cursor_rect.size.height / resource_scale; + origin.x = priv->cursor_rect.origin.x / resource_scale; + origin.y = priv->cursor_rect.origin.y / resource_scale; origin.z = 0; clutter_paint_volume_set_origin (volume, &origin); - clutter_paint_volume_set_width (volume, priv->cursor_rect.size.width); - clutter_paint_volume_set_height (volume, priv->cursor_rect.size.height); + clutter_paint_volume_set_width (volume, width); + clutter_paint_volume_set_height (volume, height); } else { clutter_text_foreach_selection_rectangle (text, + 1.0f / resource_scale, add_selection_to_paint_volume, volume); } @@ -2628,7 +2855,8 @@ clutter_text_get_paint_volume (ClutterActor *self, { PangoLayout *layout; PangoRectangle ink_rect; - ClutterVertex origin; + graphene_point3d_t origin; + float resource_scale; /* If the text is single line editable then it gets clipped to the allocation anyway so we can just use that */ @@ -2643,19 +2871,24 @@ clutter_text_get_paint_volume (ClutterActor *self, if (!clutter_actor_has_allocation (self)) return FALSE; + if (!clutter_actor_get_resource_scale (self, &resource_scale)) + return FALSE; + _clutter_paint_volume_init_static (&priv->paint_volume, self); layout = clutter_text_get_layout (text); pango_layout_get_extents (layout, &ink_rect, NULL); - origin.x = ink_rect.x / (float) PANGO_SCALE; - origin.y = ink_rect.y / (float) PANGO_SCALE; + origin.x = pango_to_logical_pixels (ink_rect.x, resource_scale); + origin.y = pango_to_logical_pixels (ink_rect.y, resource_scale); origin.z = 0; clutter_paint_volume_set_origin (&priv->paint_volume, &origin); clutter_paint_volume_set_width (&priv->paint_volume, - ink_rect.width / (float) PANGO_SCALE); + pango_to_logical_pixels (ink_rect.width, + resource_scale)); clutter_paint_volume_set_height (&priv->paint_volume, - ink_rect.height / (float) PANGO_SCALE); + pango_to_logical_pixels (ink_rect.height, + resource_scale)); /* If the cursor is visible then that will likely be drawn outside of the ink rectangle so we should merge that in */ @@ -2665,7 +2898,8 @@ clutter_text_get_paint_volume (ClutterActor *self, _clutter_paint_volume_init_static (&cursor_paint_volume, self); - clutter_text_get_paint_volume_for_cursor (text, &cursor_paint_volume); + clutter_text_get_paint_volume_for_cursor (text, resource_scale, + &cursor_paint_volume); clutter_paint_volume_union (&priv->paint_volume, &cursor_paint_volume); @@ -2693,9 +2927,12 @@ clutter_text_get_preferred_width (ClutterActor *self, PangoLayout *layout; gint logical_width; gfloat layout_width; + gfloat resource_scale; - layout = clutter_text_create_layout (text, -1, -1); + if (!clutter_actor_get_resource_scale (self, &resource_scale)) + resource_scale = 1; + layout = clutter_text_create_layout (text, -1, -1); pango_layout_get_extents (layout, NULL, &logical_rect); /* the X coordinate of the logical rectangle might be non-zero @@ -2705,7 +2942,7 @@ clutter_text_get_preferred_width (ClutterActor *self, logical_width = logical_rect.x + logical_rect.width; layout_width = logical_width > 0 - ? ceilf (logical_width / 1024.0f) + ? pango_to_logical_pixels (logical_width, resource_scale) : 1; if (min_width_p) @@ -2747,12 +2984,16 @@ clutter_text_get_preferred_height (ClutterActor *self, PangoRectangle logical_rect = { 0, }; gint logical_height; gfloat layout_height; + gfloat resource_scale; + + if (!clutter_actor_get_resource_scale (self, &resource_scale)) + resource_scale = 1; if (priv->single_line_mode) for_width = -1; - layout = clutter_text_create_layout (CLUTTER_TEXT (self), - for_width, -1); + layout = create_text_layout_with_scale (CLUTTER_TEXT (self), + for_width, -1, resource_scale); pango_layout_get_extents (layout, NULL, &logical_rect); @@ -2761,7 +3002,7 @@ clutter_text_get_preferred_height (ClutterActor *self, * the height accordingly */ logical_height = logical_rect.y + logical_rect.height; - layout_height = ceilf (logical_height / 1024.0f); + layout_height = pango_to_logical_pixels (logical_height, resource_scale); if (min_height_p) { @@ -2777,7 +3018,8 @@ clutter_text_get_preferred_height (ClutterActor *self, pango_layout_line_get_extents (line, NULL, &logical_rect); logical_height = logical_rect.y + logical_rect.height; - line_height = ceilf (logical_height / 1024.0f); + line_height = pango_to_logical_pixels (logical_height, + resource_scale); *min_height_p = line_height; } @@ -2808,9 +3050,9 @@ clutter_text_allocate (ClutterActor *self, if (text->priv->editable && text->priv->single_line_mode) clutter_text_create_layout (text, -1, -1); else - clutter_text_create_layout (text, - box->x2 - box->x1, - box->y2 - box->y1); + maybe_create_text_layout_with_resource_scale (text, + box->x2 - box->x1, + box->y2 - box->y1); parent_class = CLUTTER_ACTOR_CLASS (clutter_text_parent_class); parent_class->allocate (self, box, flags); @@ -2822,25 +3064,50 @@ clutter_text_has_overlaps (ClutterActor *self) return clutter_text_should_draw_cursor ((ClutterText *) self); } +static gboolean +clutter_text_event (ClutterActor *self, + ClutterEvent *event) +{ + ClutterText *text = CLUTTER_TEXT (self); + ClutterTextPrivate *priv = text->priv; + + if (clutter_input_focus_is_focused (priv->input_focus) && + (event->type == CLUTTER_IM_COMMIT || + event->type == CLUTTER_IM_DELETE || + event->type == CLUTTER_IM_PREEDIT)) + { + return clutter_input_focus_filter_event (priv->input_focus, event); + } + + return CLUTTER_EVENT_PROPAGATE; +} + static void -clutter_text_key_focus_in (ClutterActor *actor) +clutter_text_im_focus (ClutterText *text) { - ClutterTextPrivate *priv = CLUTTER_TEXT (actor)->priv; + ClutterTextPrivate *priv = text->priv; ClutterBackend *backend = clutter_get_default_backend (); ClutterInputMethod *method = clutter_backend_get_input_method (backend); - if (method && priv->editable) - { - clutter_input_method_focus_in (method, priv->input_focus); - clutter_input_focus_set_content_purpose (priv->input_focus, - priv->input_purpose); - clutter_input_focus_set_content_hints (priv->input_focus, - priv->input_hints); - -#ifdef __CLUTTER_WAYLAND_COMPOSITOR_H__ - update_cursor_location (CLUTTER_TEXT (actor)); -#endif - } + if (!method) + return; + + clutter_input_method_focus_in (method, priv->input_focus); + clutter_input_focus_set_content_purpose (priv->input_focus, + priv->input_purpose); + clutter_input_focus_set_content_hints (priv->input_focus, + priv->input_hints); + clutter_input_focus_set_can_show_preedit (priv->input_focus, TRUE); + update_cursor_location (text); +} + +static void +clutter_text_key_focus_in (ClutterActor *actor) +{ + ClutterTextPrivate *priv = CLUTTER_TEXT (actor)->priv; + + if (priv->editable) + clutter_text_im_focus (CLUTTER_TEXT (actor)); priv->has_focus = TRUE; @@ -3529,7 +3796,7 @@ clutter_text_set_final_state (ClutterAnimatable *animatable, } static void -clutter_animatable_iface_init (ClutterAnimatableIface *iface) +clutter_animatable_iface_init (ClutterAnimatableInterface *iface) { parent_animatable_iface = g_type_interface_peek_parent (iface); @@ -3563,6 +3830,7 @@ clutter_text_class_init (ClutterTextClass *klass) actor_class->key_focus_in = clutter_text_key_focus_in; actor_class->key_focus_out = clutter_text_key_focus_out; actor_class->has_overlaps = clutter_text_has_overlaps; + actor_class->event = clutter_text_event; /** * ClutterText:buffer: @@ -4085,8 +4353,7 @@ clutter_text_class_init (ClutterTextClass *klass) G_TYPE_FROM_CLASS (gobject_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ClutterTextClass, text_changed), - NULL, NULL, - _clutter_marshal_VOID__VOID, + NULL, NULL, NULL, G_TYPE_NONE, 0); /** @@ -4142,10 +4409,10 @@ clutter_text_class_init (ClutterTextClass *klass) /** * ClutterText::cursor-event: * @self: the #ClutterText that emitted the signal - * @geometry: the coordinates of the cursor + * @rect: the coordinates of the cursor * * The ::cursor-event signal is emitted whenever the cursor position - * changes inside a #ClutterText actor. Inside @geometry it is stored + * changes inside a #ClutterText actor. Inside @rect it is stored * the current position and size of the cursor, relative to the actor * itself. * @@ -4158,10 +4425,9 @@ clutter_text_class_init (ClutterTextClass *klass) G_TYPE_FROM_CLASS (gobject_class), G_SIGNAL_RUN_LAST | G_SIGNAL_DEPRECATED, G_STRUCT_OFFSET (ClutterTextClass, cursor_event), - NULL, NULL, - _clutter_marshal_VOID__BOXED, + NULL, NULL, NULL, G_TYPE_NONE, 1, - CLUTTER_TYPE_GEOMETRY | G_SIGNAL_TYPE_STATIC_SCOPE); + GRAPHENE_TYPE_RECT | G_SIGNAL_TYPE_STATIC_SCOPE); /** * ClutterText::cursor-changed: @@ -4177,8 +4443,7 @@ clutter_text_class_init (ClutterTextClass *klass) G_TYPE_FROM_CLASS (gobject_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ClutterTextClass, cursor_changed), - NULL, NULL, - _clutter_marshal_VOID__VOID, + NULL, NULL, NULL, G_TYPE_NONE, 0); /** @@ -4196,8 +4461,7 @@ clutter_text_class_init (ClutterTextClass *klass) G_TYPE_FROM_CLASS (gobject_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ClutterTextClass, activate), - NULL, NULL, - _clutter_marshal_VOID__VOID, + NULL, NULL, NULL, G_TYPE_NONE, 0); binding_pool = clutter_binding_pool_get_for_class (klass); @@ -4374,6 +4638,11 @@ clutter_text_init (ClutterText *self) NULL); priv->input_focus = clutter_text_input_focus_new (self); + + priv->resource_scale_changed_id = + g_signal_connect (self, "notify::resource-scale", + G_CALLBACK (clutter_text_resource_scale_changed_cb), + NULL); } /** @@ -4561,7 +4830,7 @@ buffer_notify_max_length (ClutterTextBuffer *buffer, GParamSpec *spec, ClutterText *self) { - g_object_notify (G_OBJECT (self), "max-length"); + g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_MAX_LENGTH]); } static void @@ -4660,9 +4929,9 @@ clutter_text_set_buffer (ClutterText *self, obj = G_OBJECT (self); g_object_freeze_notify (obj); - g_object_notify (obj, "buffer"); - g_object_notify (obj, "text"); - g_object_notify (obj, "max-length"); + g_object_notify_by_pspec (obj, obj_props[PROP_BUFFER]); + g_object_notify_by_pspec (obj, obj_props[PROP_TEXT]); + g_object_notify_by_pspec (obj, obj_props[PROP_MAX_LENGTH]); g_object_thaw_notify (obj); } @@ -4700,7 +4969,7 @@ clutter_text_set_editable (ClutterText *self, if (!priv->editable && clutter_input_focus_is_focused (priv->input_focus)) clutter_input_method_focus_out (method); else if (priv->has_focus) - clutter_input_method_focus_in (method, priv->input_focus); + clutter_text_im_focus (self); } clutter_text_queue_redraw (CLUTTER_ACTOR (self)); @@ -5007,7 +5276,7 @@ clutter_text_set_selection (ClutterText *self, * Retrieves the currently selected text. * * Return value: a newly allocated string containing the currently - * selected text, or %NULL. Use free() to free the returned + * selected text, or %NULL. Use g_free() to free the returned * string. * * Since: 1.0 @@ -5045,7 +5314,7 @@ clutter_text_get_selection (ClutterText *self) end_offset = offset_to_bytes (text, end_index); len = end_offset - start_offset; - str = malloc (len + 1); + str = g_malloc (len + 1); g_utf8_strncpy (str, text + start_offset, end_index - start_index); return str; @@ -5338,7 +5607,7 @@ clutter_text_set_font_name (ClutterText *self, out: if (is_default_font) - free ((gchar *) font_name); + g_free ((gchar *) font_name); } /** @@ -5484,6 +5753,7 @@ clutter_text_set_markup (ClutterText *self, PangoLayout * clutter_text_get_layout (ClutterText *self) { + PangoLayout *layout; gfloat width, height; g_return_val_if_fail (CLUTTER_IS_TEXT (self), NULL); @@ -5492,8 +5762,12 @@ clutter_text_get_layout (ClutterText *self) return clutter_text_create_layout (self, -1, -1); clutter_actor_get_size (CLUTTER_ACTOR (self), &width, &height); + layout = maybe_create_text_layout_with_resource_scale (self, width, height); + + if (!layout) + layout = clutter_text_create_layout (self, width, height); - return clutter_text_create_layout (self, width, height); + return layout; } /** @@ -5701,6 +5975,55 @@ clutter_text_get_line_wrap_mode (ClutterText *self) return self->priv->wrap_mode; } +static gboolean +attr_list_equal (PangoAttrList *old_attrs, PangoAttrList *new_attrs) +{ + PangoAttrIterator *i, *j; + gboolean equal = TRUE; + + if (old_attrs == new_attrs) + return TRUE; + + if (old_attrs == NULL || new_attrs == NULL) + return FALSE; + + i = pango_attr_list_get_iterator (old_attrs); + j = pango_attr_list_get_iterator (new_attrs); + + do + { + GSList *old_attributes, *new_attributes, *a, *b; + + old_attributes = pango_attr_iterator_get_attrs (i); + new_attributes = pango_attr_iterator_get_attrs (j); + + for (a = old_attributes, b = new_attributes; + a != NULL && b != NULL && equal; + a = a->next, b = b->next) + { + if (!pango_attribute_equal (a->data, b->data)) + equal = FALSE; + } + + if (a != NULL || b != NULL) + equal = FALSE; + + g_slist_free_full (old_attributes, + (GDestroyNotify) pango_attribute_destroy); + g_slist_free_full (new_attributes, + (GDestroyNotify) pango_attribute_destroy); + } + while (equal && pango_attr_iterator_next (i) && pango_attr_iterator_next (j)); + + if (pango_attr_iterator_next (i) || pango_attr_iterator_next (j)) + equal = FALSE; + + pango_attr_iterator_destroy (i); + pango_attr_iterator_destroy (j); + + return equal; +} + /** * clutter_text_set_attributes: * @self: a #ClutterText @@ -5724,10 +6047,7 @@ clutter_text_set_attributes (ClutterText *self, priv = self->priv; - /* While we should probably test for equality, Pango doesn't - * provide us an easy method to check for AttrList equality. - */ - if (priv->attrs == attrs) + if (attr_list_equal (priv->attrs, attrs)) return; if (attrs) @@ -6305,7 +6625,7 @@ clutter_text_delete_chars (ClutterText *self, * The positions are specified in characters, not in bytes. * * Return value: a newly allocated string with the contents of - * the text actor between the specified positions. Use free() + * the text actor between the specified positions. Use g_free() * to free the resources when done * * Since: 1.0 @@ -6438,7 +6758,7 @@ clutter_text_set_preedit_string (ClutterText *self, priv = self->priv; - free (priv->preedit_str); + g_free (priv->preedit_str); priv->preedit_str = NULL; if (priv->preedit_attrs != NULL) @@ -6497,10 +6817,10 @@ clutter_text_get_layout_offsets (ClutterText *self, priv = self->priv; if (x != NULL) - *x = priv->text_x; + *x = priv->text_logical_x; if (y != NULL) - *y = priv->text_y; + *y = priv->text_logical_y; } /** @@ -6516,8 +6836,8 @@ clutter_text_get_layout_offsets (ClutterText *self, * Since: 1.16 */ void -clutter_text_get_cursor_rect (ClutterText *self, - ClutterRect *rect) +clutter_text_get_cursor_rect (ClutterText *self, + graphene_rect_t *rect) { g_return_if_fail (CLUTTER_IS_TEXT (self)); g_return_if_fail (rect != NULL); diff --git a/clutter/clutter/clutter-text.h b/clutter/clutter/clutter-text.h index 2bed704bf..7fa8116da 100644 --- a/clutter/clutter/clutter-text.h +++ b/clutter/clutter/clutter-text.h @@ -82,7 +82,7 @@ struct _ClutterTextClass void (* text_changed) (ClutterText *self); void (* activate) (ClutterText *self); void (* cursor_event) (ClutterText *self, - const ClutterGeometry *geometry); + const graphene_rect_t *rect); void (* cursor_changed) (ClutterText *self); /*< private >*/ @@ -96,224 +96,224 @@ struct _ClutterTextClass void (* _clutter_reserved7) (void); }; -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT GType clutter_text_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT ClutterActor * clutter_text_new (void); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT ClutterActor * clutter_text_new_full (const gchar *font_name, const gchar *text, const ClutterColor *color); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT ClutterActor * clutter_text_new_with_text (const gchar *font_name, const gchar *text); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT ClutterActor * clutter_text_new_with_buffer (ClutterTextBuffer *buffer); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT ClutterTextBuffer * clutter_text_get_buffer (ClutterText *self); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_text_set_buffer (ClutterText *self, ClutterTextBuffer *buffer); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT const gchar * clutter_text_get_text (ClutterText *self); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_text_set_text (ClutterText *self, const gchar *text); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_text_set_markup (ClutterText *self, const gchar *markup); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_text_set_color (ClutterText *self, const ClutterColor *color); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_text_get_color (ClutterText *self, ClutterColor *color); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_text_set_font_name (ClutterText *self, const gchar *font_name); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT const gchar * clutter_text_get_font_name (ClutterText *self); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT void clutter_text_set_font_description (ClutterText *self, PangoFontDescription *font_desc); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT PangoFontDescription *clutter_text_get_font_description (ClutterText *self); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_text_set_ellipsize (ClutterText *self, PangoEllipsizeMode mode); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT PangoEllipsizeMode clutter_text_get_ellipsize (ClutterText *self); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_text_set_line_wrap (ClutterText *self, gboolean line_wrap); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT gboolean clutter_text_get_line_wrap (ClutterText *self); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_text_set_line_wrap_mode (ClutterText *self, PangoWrapMode wrap_mode); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT PangoWrapMode clutter_text_get_line_wrap_mode (ClutterText *self); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT PangoLayout * clutter_text_get_layout (ClutterText *self); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_text_set_attributes (ClutterText *self, PangoAttrList *attrs); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT PangoAttrList * clutter_text_get_attributes (ClutterText *self); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_text_set_use_markup (ClutterText *self, gboolean setting); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT gboolean clutter_text_get_use_markup (ClutterText *self); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_text_set_line_alignment (ClutterText *self, PangoAlignment alignment); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT PangoAlignment clutter_text_get_line_alignment (ClutterText *self); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_text_set_justify (ClutterText *self, gboolean justify); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT gboolean clutter_text_get_justify (ClutterText *self); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_text_insert_unichar (ClutterText *self, gunichar wc); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_text_delete_chars (ClutterText *self, guint n_chars); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_text_insert_text (ClutterText *self, const gchar *text, gssize position); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_text_delete_text (ClutterText *self, gssize start_pos, gssize end_pos); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT gchar * clutter_text_get_chars (ClutterText *self, gssize start_pos, gssize end_pos); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_text_set_editable (ClutterText *self, gboolean editable); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT gboolean clutter_text_get_editable (ClutterText *self); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_text_set_activatable (ClutterText *self, gboolean activatable); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT gboolean clutter_text_get_activatable (ClutterText *self); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT gint clutter_text_get_cursor_position (ClutterText *self); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_text_set_cursor_position (ClutterText *self, gint position); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_text_set_cursor_visible (ClutterText *self, gboolean cursor_visible); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT gboolean clutter_text_get_cursor_visible (ClutterText *self); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_text_set_cursor_color (ClutterText *self, const ClutterColor *color); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_text_get_cursor_color (ClutterText *self, ClutterColor *color); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_text_set_cursor_size (ClutterText *self, gint size); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT guint clutter_text_get_cursor_size (ClutterText *self); -CLUTTER_AVAILABLE_IN_1_16 +CLUTTER_EXPORT void clutter_text_get_cursor_rect (ClutterText *self, - ClutterRect *rect); -CLUTTER_AVAILABLE_IN_1_0 + graphene_rect_t *rect); +CLUTTER_EXPORT void clutter_text_set_selectable (ClutterText *self, gboolean selectable); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT gboolean clutter_text_get_selectable (ClutterText *self); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_text_set_selection_bound (ClutterText *self, gint selection_bound); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT gint clutter_text_get_selection_bound (ClutterText *self); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_text_set_selection (ClutterText *self, gssize start_pos, gssize end_pos); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT gchar * clutter_text_get_selection (ClutterText *self); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_text_set_selection_color (ClutterText *self, const ClutterColor *color); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_text_get_selection_color (ClutterText *self, ClutterColor *color); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT gboolean clutter_text_delete_selection (ClutterText *self); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_text_set_password_char (ClutterText *self, gunichar wc); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT gunichar clutter_text_get_password_char (ClutterText *self); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_text_set_max_length (ClutterText *self, gint max); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT gint clutter_text_get_max_length (ClutterText *self); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_text_set_single_line_mode (ClutterText *self, gboolean single_line); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT gboolean clutter_text_get_single_line_mode (ClutterText *self); -CLUTTER_AVAILABLE_IN_1_8 +CLUTTER_EXPORT void clutter_text_set_selected_text_color (ClutterText *self, const ClutterColor *color); -CLUTTER_AVAILABLE_IN_1_8 +CLUTTER_EXPORT void clutter_text_get_selected_text_color (ClutterText *self, ClutterColor *color); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT gboolean clutter_text_activate (ClutterText *self); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT gint clutter_text_coords_to_position (ClutterText *self, gfloat x, gfloat y); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT gboolean clutter_text_position_to_coords (ClutterText *self, gint position, gfloat *x, gfloat *y, gfloat *line_height); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT void clutter_text_set_preedit_string (ClutterText *self, const gchar *preedit_str, PangoAttrList *preedit_attrs, guint cursor_pos); -CLUTTER_AVAILABLE_IN_1_8 +CLUTTER_EXPORT void clutter_text_get_layout_offsets (ClutterText *self, gint *x, gint *y); -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT void clutter_text_set_input_hints (ClutterText *self, ClutterInputContentHintFlags hints); -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT void clutter_text_set_input_purpose (ClutterText *self, ClutterInputContentPurpose purpose); -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT ClutterInputContentHintFlags clutter_text_get_input_hints (ClutterText *self); -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT ClutterInputContentPurpose clutter_text_get_input_purpose (ClutterText *self); -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT gboolean clutter_text_has_preedit (ClutterText *self); G_END_DECLS diff --git a/clutter/clutter/clutter-texture.h b/clutter/clutter/clutter-texture.h deleted file mode 100644 index f890969da..000000000 --- a/clutter/clutter/clutter-texture.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * Copyright (C) 2006 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __CLUTTER_TEXTURE_H__ -#define __CLUTTER_TEXTURE_H__ - -#include -#include - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_TEXTURE (clutter_texture_get_type ()) -#define CLUTTER_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_TEXTURE, ClutterTexture)) -#define CLUTTER_TEXTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_TEXTURE, ClutterTextureClass)) -#define CLUTTER_IS_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_TEXTURE)) -#define CLUTTER_IS_TEXTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_TEXTURE)) -#define CLUTTER_TEXTURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_TEXTURE, ClutterTextureClass)) - -/** - * ClutterTextureError: - * @CLUTTER_TEXTURE_ERROR_OUT_OF_MEMORY: OOM condition - * @CLUTTER_TEXTURE_ERROR_NO_YUV: YUV operation attempted but no YUV support - * found - * @CLUTTER_TEXTURE_ERROR_BAD_FORMAT: The requested format for - * clutter_texture_set_from_rgb_data or - * clutter_texture_set_from_yuv_data is unsupported. - * - * Error enumeration for #ClutterTexture - * - * Since: 0.4 - */ -typedef enum { - CLUTTER_TEXTURE_ERROR_OUT_OF_MEMORY, - CLUTTER_TEXTURE_ERROR_NO_YUV, - CLUTTER_TEXTURE_ERROR_BAD_FORMAT -} ClutterTextureError; - -/** - * CLUTTER_TEXTURE_ERROR: - * - * Error domain for #ClutterTexture errors - * - * Since: 0.4 - */ -#define CLUTTER_TEXTURE_ERROR (clutter_texture_error_quark ()) -CLUTTER_AVAILABLE_IN_ALL -GQuark clutter_texture_error_quark (void); - -typedef struct _ClutterTexture ClutterTexture; -typedef struct _ClutterTextureClass ClutterTextureClass; -typedef struct _ClutterTexturePrivate ClutterTexturePrivate; - -/** - * ClutterTexture: - * - * The #ClutterTexture structure contains only private data - * and should be accessed using the provided API - * - * Since: 0.2 - */ -struct _ClutterTexture -{ - /*< private >*/ - ClutterActor parent; - - ClutterTexturePrivate *priv; -}; - -/** - * ClutterTextureClass: - * @size_change: handler for the #ClutterTexture::size-change signal - * @pixbuf_change: handler for the #ClutterTexture::pixbuf-change signal - * @load_finished: handler for the #ClutterTexture::load-finished signal - * - * The #ClutterTextureClass structure contains only private data - * - * Since: 0.2 - */ -struct _ClutterTextureClass -{ - /*< private >*/ - ClutterActorClass parent_class; - - /*< public >*/ - void (* size_change) (ClutterTexture *texture, - gint width, - gint height); - void (* pixbuf_change) (ClutterTexture *texture); - void (* load_finished) (ClutterTexture *texture, - const GError *error); - - /*< private >*/ - /* padding, for future expansion */ - void (*_clutter_texture1) (void); - void (*_clutter_texture2) (void); - void (*_clutter_texture3) (void); - void (*_clutter_texture4) (void); - void (*_clutter_texture5) (void); -}; - -CLUTTER_AVAILABLE_IN_ALL -GType clutter_texture_get_type (void) G_GNUC_CONST; - -G_END_DECLS - -#endif /* __CLUTTER_TEXTURE_H__ */ diff --git a/clutter/clutter/clutter-timeline.c b/clutter/clutter/clutter-timeline.c index ba18e7f60..b6f7ac666 100644 --- a/clutter/clutter/clutter-timeline.c +++ b/clutter/clutter/clutter-timeline.c @@ -93,9 +93,7 @@ * ]| */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include "clutter-timeline.h" @@ -147,8 +145,8 @@ struct _ClutterTimelinePrivate ClutterStepMode step_mode; /* cubic-bezier() parameters */ - ClutterPoint cb_1; - ClutterPoint cb_2; + graphene_point_t cb_1; + graphene_point_t cb_2; guint is_playing : 1; @@ -244,7 +242,7 @@ timeline_marker_free (gpointer data) { TimelineMarker *marker = data; - free (marker->name); + g_free (marker->name); g_slice_free (TimelineMarker, marker); } } @@ -426,6 +424,11 @@ clutter_timeline_set_custom_property (ClutterScriptable *scriptable, g_object_set_property (G_OBJECT (scriptable), name, value); } +void +clutter_timeline_cancel_delay (ClutterTimeline *timeline) +{ + g_clear_handle_id (&timeline->priv->delay_id, g_source_remove); +} static void clutter_scriptable_iface_init (ClutterScriptableIface *iface) @@ -552,11 +555,7 @@ clutter_timeline_dispose (GObject *object) priv = self->priv; - if (priv->delay_id) - { - g_source_remove (priv->delay_id); - priv->delay_id = 0; - } + clutter_timeline_cancel_delay (self); if (priv->progress_notify != NULL) { @@ -711,8 +710,7 @@ clutter_timeline_class_init (ClutterTimelineClass *klass) G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ClutterTimelineClass, new_frame), - NULL, NULL, - _clutter_marshal_VOID__INT, + NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_INT); /** @@ -735,8 +733,7 @@ clutter_timeline_class_init (ClutterTimelineClass *klass) G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ClutterTimelineClass, completed), - NULL, NULL, - _clutter_marshal_VOID__VOID, + NULL, NULL, NULL, G_TYPE_NONE, 0); /** * ClutterTimeline::started: @@ -752,8 +749,7 @@ clutter_timeline_class_init (ClutterTimelineClass *klass) G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ClutterTimelineClass, started), - NULL, NULL, - _clutter_marshal_VOID__VOID, + NULL, NULL, NULL, G_TYPE_NONE, 0); /** * ClutterTimeline::paused: @@ -766,8 +762,7 @@ clutter_timeline_class_init (ClutterTimelineClass *klass) G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ClutterTimelineClass, paused), - NULL, NULL, - _clutter_marshal_VOID__VOID, + NULL, NULL, NULL, G_TYPE_NONE, 0); /** * ClutterTimeline::marker-reached: @@ -834,8 +829,7 @@ clutter_timeline_class_init (ClutterTimelineClass *klass) G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ClutterTimelineClass, stopped), - NULL, NULL, - _clutter_marshal_VOID__BOOLEAN, + NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); } @@ -852,8 +846,8 @@ clutter_timeline_init (ClutterTimeline *self) self->priv->step_mode = CLUTTER_STEP_MODE_END; /* default cubic-bezier() paramereters are (0, 0, 1, 1) */ - clutter_point_init (&self->priv->cb_1, 0, 0); - clutter_point_init (&self->priv->cb_2, 1, 1); + graphene_point_init (&self->priv->cb_1, 0, 0); + graphene_point_init (&self->priv->cb_2, 1, 1); } struct CheckIfMarkerHitClosure @@ -1044,15 +1038,15 @@ clutter_timeline_do_frame (ClutterTimeline *timeline) * to correpondingly reduce elapsed_time_delta to reflect the correct * range of times */ if (priv->direction == CLUTTER_TIMELINE_FORWARD) - { - elapsed_time_delta -= (priv->elapsed_time - priv->duration); - priv->elapsed_time = priv->duration; - } + { + elapsed_time_delta -= (priv->elapsed_time - priv->duration); + priv->elapsed_time = priv->duration; + } else if (priv->direction == CLUTTER_TIMELINE_BACKWARD) - { - elapsed_time_delta -= - priv->elapsed_time; - priv->elapsed_time = 0; - } + { + elapsed_time_delta -= - priv->elapsed_time; + priv->elapsed_time = 0; + } end_msecs = priv->elapsed_time; @@ -1220,14 +1214,10 @@ clutter_timeline_pause (ClutterTimeline *timeline) priv = timeline->priv; - if (priv->delay_id == 0 && !priv->is_playing) - return; + clutter_timeline_cancel_delay (timeline); - if (priv->delay_id) - { - g_source_remove (priv->delay_id); - priv->delay_id = 0; - } + if (!priv->is_playing) + return; priv->msecs_delta = 0; set_is_playing (timeline, FALSE); @@ -1766,12 +1756,12 @@ _clutter_timeline_do_tick (ClutterTimeline *timeline, } if (msecs != 0) - { - /* Avoid accumulating error */ + { + /* Avoid accumulating error */ priv->last_frame_time += msecs; - priv->msecs_delta = msecs; - clutter_timeline_do_frame (timeline); - } + priv->msecs_delta = msecs; + clutter_timeline_do_frame (timeline); + } } } @@ -2495,9 +2485,9 @@ clutter_timeline_get_step_progress (ClutterTimeline *timeline, * Since: 1.12 */ void -clutter_timeline_set_cubic_bezier_progress (ClutterTimeline *timeline, - const ClutterPoint *c_1, - const ClutterPoint *c_2) +clutter_timeline_set_cubic_bezier_progress (ClutterTimeline *timeline, + const graphene_point_t *c_1, + const graphene_point_t *c_2) { ClutterTimelinePrivate *priv; @@ -2532,9 +2522,9 @@ clutter_timeline_set_cubic_bezier_progress (ClutterTimeline *timeline, * Since: 1.12 */ gboolean -clutter_timeline_get_cubic_bezier_progress (ClutterTimeline *timeline, - ClutterPoint *c_1, - ClutterPoint *c_2) +clutter_timeline_get_cubic_bezier_progress (ClutterTimeline *timeline, + graphene_point_t *c_1, + graphene_point_t *c_2) { g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), FALSE); diff --git a/clutter/clutter/clutter-timeline.h b/clutter/clutter/clutter-timeline.h index 267dc63d8..656a4c503 100644 --- a/clutter/clutter/clutter-timeline.h +++ b/clutter/clutter/clutter-timeline.h @@ -115,110 +115,110 @@ struct _ClutterTimelineClass void (*_clutter_timeline_4) (void); }; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT GType clutter_timeline_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterTimeline * clutter_timeline_new (guint msecs); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT guint clutter_timeline_get_duration (ClutterTimeline *timeline); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_timeline_set_duration (ClutterTimeline *timeline, guint msecs); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterTimelineDirection clutter_timeline_get_direction (ClutterTimeline *timeline); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_timeline_set_direction (ClutterTimeline *timeline, ClutterTimelineDirection direction); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_timeline_start (ClutterTimeline *timeline); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_timeline_pause (ClutterTimeline *timeline); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_timeline_stop (ClutterTimeline *timeline); -CLUTTER_AVAILABLE_IN_1_6 +CLUTTER_EXPORT void clutter_timeline_set_auto_reverse (ClutterTimeline *timeline, gboolean reverse); -CLUTTER_AVAILABLE_IN_1_6 +CLUTTER_EXPORT gboolean clutter_timeline_get_auto_reverse (ClutterTimeline *timeline); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_timeline_set_repeat_count (ClutterTimeline *timeline, gint count); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT gint clutter_timeline_get_repeat_count (ClutterTimeline *timeline); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_timeline_rewind (ClutterTimeline *timeline); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_timeline_skip (ClutterTimeline *timeline, guint msecs); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_timeline_advance (ClutterTimeline *timeline, guint msecs); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT guint clutter_timeline_get_elapsed_time (ClutterTimeline *timeline); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gdouble clutter_timeline_get_progress (ClutterTimeline *timeline); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gboolean clutter_timeline_is_playing (ClutterTimeline *timeline); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_timeline_set_delay (ClutterTimeline *timeline, guint msecs); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT guint clutter_timeline_get_delay (ClutterTimeline *timeline); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT guint clutter_timeline_get_delta (ClutterTimeline *timeline); -CLUTTER_AVAILABLE_IN_1_14 +CLUTTER_EXPORT void clutter_timeline_add_marker (ClutterTimeline *timeline, const gchar *marker_name, gdouble progress); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_timeline_add_marker_at_time (ClutterTimeline *timeline, const gchar *marker_name, guint msecs); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_timeline_remove_marker (ClutterTimeline *timeline, const gchar *marker_name); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gchar ** clutter_timeline_list_markers (ClutterTimeline *timeline, gint msecs, gsize *n_markers) G_GNUC_MALLOC; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gboolean clutter_timeline_has_marker (ClutterTimeline *timeline, const gchar *marker_name); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_timeline_advance_to_marker (ClutterTimeline *timeline, const gchar *marker_name); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_timeline_set_progress_func (ClutterTimeline *timeline, ClutterTimelineProgressFunc func, gpointer data, GDestroyNotify notify); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_timeline_set_progress_mode (ClutterTimeline *timeline, ClutterAnimationMode mode); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT ClutterAnimationMode clutter_timeline_get_progress_mode (ClutterTimeline *timeline); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_timeline_set_step_progress (ClutterTimeline *timeline, gint n_steps, ClutterStepMode step_mode); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT gboolean clutter_timeline_get_step_progress (ClutterTimeline *timeline, gint *n_steps, ClutterStepMode *step_mode); -CLUTTER_AVAILABLE_IN_1_12 -void clutter_timeline_set_cubic_bezier_progress (ClutterTimeline *timeline, - const ClutterPoint *c_1, - const ClutterPoint *c_2); -CLUTTER_AVAILABLE_IN_1_12 -gboolean clutter_timeline_get_cubic_bezier_progress (ClutterTimeline *timeline, - ClutterPoint *c_1, - ClutterPoint *c_2); - -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT +void clutter_timeline_set_cubic_bezier_progress (ClutterTimeline *timeline, + const graphene_point_t *c_1, + const graphene_point_t *c_2); +CLUTTER_EXPORT +gboolean clutter_timeline_get_cubic_bezier_progress (ClutterTimeline *timeline, + graphene_point_t *c_1, + graphene_point_t *c_2); + +CLUTTER_EXPORT gint64 clutter_timeline_get_duration_hint (ClutterTimeline *timeline); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT gint clutter_timeline_get_current_repeat (ClutterTimeline *timeline); G_END_DECLS diff --git a/clutter/clutter/clutter-transition-group.c b/clutter/clutter/clutter-transition-group.c index 00635644d..59801af44 100644 --- a/clutter/clutter/clutter-transition-group.c +++ b/clutter/clutter/clutter-transition-group.c @@ -37,9 +37,7 @@ * #ClutterTransitionGroup is available since Clutter 1.12 */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include "clutter-transition-group.h" diff --git a/clutter/clutter/clutter-transition-group.h b/clutter/clutter/clutter-transition-group.h index b2a9ce107..a98b7715c 100644 --- a/clutter/clutter/clutter-transition-group.h +++ b/clutter/clutter/clutter-transition-group.h @@ -75,19 +75,19 @@ struct _ClutterTransitionGroupClass gpointer _padding[8]; }; -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT GType clutter_transition_group_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT ClutterTransition * clutter_transition_group_new (void); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_transition_group_add_transition (ClutterTransitionGroup *group, ClutterTransition *transition); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_transition_group_remove_transition (ClutterTransitionGroup *group, ClutterTransition *transition); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_transition_group_remove_all (ClutterTransitionGroup *group); G_END_DECLS diff --git a/clutter/clutter/clutter-transition.c b/clutter/clutter/clutter-transition.c index fadac0e6f..34f357c48 100644 --- a/clutter/clutter/clutter-transition.c +++ b/clutter/clutter/clutter-transition.c @@ -30,9 +30,7 @@ * computes the interpolation between two values, stored by a #ClutterInterval. */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include "clutter-transition.h" @@ -136,7 +134,6 @@ clutter_transition_stopped (ClutterTimeline *timeline, clutter_transition_detach (CLUTTER_TRANSITION (timeline), priv->animatable); g_clear_object (&priv->animatable); - g_object_unref (timeline); } } @@ -618,7 +615,7 @@ clutter_transition_set_from (ClutterTransition *transition, if (error != NULL) { g_warning ("%s: %s", G_STRLOC, error); - free (error); + g_free (error); return; } @@ -671,7 +668,7 @@ clutter_transition_set_to (ClutterTransition *transition, if (error != NULL) { g_warning ("%s: %s", G_STRLOC, error); - free (error); + g_free (error); return; } diff --git a/clutter/clutter/clutter-transition.h b/clutter/clutter/clutter-transition.h index 7ea9bfa01..6f8e4dc1a 100644 --- a/clutter/clutter/clutter-transition.h +++ b/clutter/clutter/clutter-transition.h @@ -93,38 +93,38 @@ struct _ClutterTransitionClass gpointer _padding[8]; }; -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT GType clutter_transition_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_transition_set_interval (ClutterTransition *transition, ClutterInterval *interval); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT ClutterInterval * clutter_transition_get_interval (ClutterTransition *transition); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_transition_set_from_value (ClutterTransition *transition, const GValue *value); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_transition_set_to_value (ClutterTransition *transition, const GValue *value); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_transition_set_from (ClutterTransition *transition, GType value_type, ...); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_transition_set_to (ClutterTransition *transition, GType value_type, ...); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_transition_set_animatable (ClutterTransition *transition, ClutterAnimatable *animatable); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT ClutterAnimatable * clutter_transition_get_animatable (ClutterTransition *transition); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_transition_set_remove_on_complete (ClutterTransition *transition, gboolean remove_complete); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT gboolean clutter_transition_get_remove_on_complete (ClutterTransition *transition); G_END_DECLS diff --git a/clutter/clutter/clutter-types.h b/clutter/clutter/clutter-types.h index 93eb69163..05c51b603 100644 --- a/clutter/clutter/clutter-types.h +++ b/clutter/clutter/clutter-types.h @@ -28,26 +28,21 @@ #error "Only can be included directly." #endif -#include #include #include #include #include +#include + G_BEGIN_DECLS #define CLUTTER_TYPE_ACTOR_BOX (clutter_actor_box_get_type ()) -#define CLUTTER_TYPE_FOG (clutter_fog_get_type ()) -#define CLUTTER_TYPE_GEOMETRY (clutter_geometry_get_type ()) #define CLUTTER_TYPE_KNOT (clutter_knot_get_type ()) #define CLUTTER_TYPE_MARGIN (clutter_margin_get_type ()) #define CLUTTER_TYPE_MATRIX (clutter_matrix_get_type ()) #define CLUTTER_TYPE_PAINT_VOLUME (clutter_paint_volume_get_type ()) #define CLUTTER_TYPE_PERSPECTIVE (clutter_perspective_get_type ()) -#define CLUTTER_TYPE_VERTEX (clutter_vertex_get_type ()) -#define CLUTTER_TYPE_POINT (clutter_point_get_type ()) -#define CLUTTER_TYPE_SIZE (clutter_size_get_type ()) -#define CLUTTER_TYPE_RECT (clutter_rect_get_type ()) typedef struct _ClutterActor ClutterActor; @@ -80,18 +75,12 @@ typedef struct _ClutterPathNode ClutterPathNode; typedef struct _ClutterActorBox ClutterActorBox; typedef struct _ClutterColor ClutterColor; -typedef struct _ClutterGeometry ClutterGeometry; /* XXX:2.0 - remove */ typedef struct _ClutterKnot ClutterKnot; typedef struct _ClutterMargin ClutterMargin; typedef struct _ClutterPerspective ClutterPerspective; -typedef struct _ClutterPoint ClutterPoint; -typedef struct _ClutterRect ClutterRect; -typedef struct _ClutterSize ClutterSize; -typedef struct _ClutterVertex ClutterVertex; typedef struct _ClutterAlpha ClutterAlpha; typedef struct _ClutterAnimation ClutterAnimation; -typedef struct _ClutterAnimator ClutterAnimator; typedef struct _ClutterState ClutterState; typedef struct _ClutterInputDeviceTool ClutterInputDeviceTool; @@ -115,8 +104,6 @@ typedef union _ClutterEvent ClutterEvent; */ typedef struct _ClutterEventSequence ClutterEventSequence; -typedef struct _ClutterFog ClutterFog; /* deprecated */ -typedef struct _ClutterBehaviour ClutterBehaviour; /* deprecated */ typedef struct _ClutterShader ClutterShader; /* deprecated */ /** @@ -139,303 +126,6 @@ typedef struct _ClutterShader ClutterShader; /* deprecated */ */ typedef struct _ClutterPaintVolume ClutterPaintVolume; -/** - * ClutterPoint: - * @x: X coordinate, in pixels - * @y: Y coordinate, in pixels - * - * A point in 2D space. - * - * Since: 1.12 - */ -struct _ClutterPoint -{ - float x; - float y; -}; - -/** - * CLUTTER_POINT_INIT: - * @x: X coordinate - * @y: Y coordinate - * - * A simple macro for initializing a #ClutterPoint when declaring it, e.g.: - * - * |[ - * ClutterPoint p = CLUTTER_POINT_INIT (100, 100); - * ]| - * - * Since: 1.12 - */ -#define CLUTTER_POINT_INIT(x,y) { (x), (y) } - -/** - * CLUTTER_POINT_INIT_ZERO: - * - * A simple macro for initializing a #ClutterPoint to (0, 0) when - * declaring it. - * - * Since: 1.12 - */ -#define CLUTTER_POINT_INIT_ZERO CLUTTER_POINT_INIT (0.f, 0.f) - -CLUTTER_AVAILABLE_IN_1_12 -GType clutter_point_get_type (void) G_GNUC_CONST; - -CLUTTER_AVAILABLE_IN_1_12 -const ClutterPoint * clutter_point_zero (void); -CLUTTER_AVAILABLE_IN_1_12 -ClutterPoint * clutter_point_alloc (void); -CLUTTER_AVAILABLE_IN_1_12 -ClutterPoint * clutter_point_init (ClutterPoint *point, - float x, - float y); -CLUTTER_AVAILABLE_IN_1_12 -ClutterPoint * clutter_point_copy (const ClutterPoint *point); -CLUTTER_AVAILABLE_IN_1_12 -void clutter_point_free (ClutterPoint *point); -CLUTTER_AVAILABLE_IN_1_12 -gboolean clutter_point_equals (const ClutterPoint *a, - const ClutterPoint *b); -CLUTTER_AVAILABLE_IN_1_12 -float clutter_point_distance (const ClutterPoint *a, - const ClutterPoint *b, - float *x_distance, - float *y_distance); - -/** - * ClutterSize: - * @width: the width, in pixels - * @height: the height, in pixels - * - * A size, in 2D space. - * - * Since: 1.12 - */ -struct _ClutterSize -{ - float width; - float height; -}; - -/** - * CLUTTER_SIZE_INIT: - * @width: the width - * @height: the height - * - * A simple macro for initializing a #ClutterSize when declaring it, e.g.: - * - * |[ - * ClutterSize s = CLUTTER_SIZE_INIT (200, 200); - * ]| - * - * Since: 1.12 - */ -#define CLUTTER_SIZE_INIT(width,height) { (width), (height) } - -/** - * CLUTTER_SIZE_INIT_ZERO: - * - * A simple macro for initializing a #ClutterSize to (0, 0) when - * declaring it. - * - * Since: 1.12 - */ -#define CLUTTER_SIZE_INIT_ZERO CLUTTER_SIZE_INIT (0.f, 0.f) - -CLUTTER_AVAILABLE_IN_1_12 -GType clutter_size_get_type (void) G_GNUC_CONST; - -CLUTTER_AVAILABLE_IN_1_12 -ClutterSize * clutter_size_alloc (void); -CLUTTER_AVAILABLE_IN_1_12 -ClutterSize * clutter_size_init (ClutterSize *size, - float width, - float height); -CLUTTER_AVAILABLE_IN_1_12 -ClutterSize * clutter_size_copy (const ClutterSize *size); -CLUTTER_AVAILABLE_IN_1_12 -void clutter_size_free (ClutterSize *size); -CLUTTER_AVAILABLE_IN_1_12 -gboolean clutter_size_equals (const ClutterSize *a, - const ClutterSize *b); - -/** - * ClutterRect: - * @origin: the origin of the rectangle - * @size: the size of the rectangle - * - * The location and size of a rectangle. - * - * The width and height of a #ClutterRect can be negative; Clutter considers - * a rectangle with an origin of [ 0.0, 0.0 ] and a size of [ 10.0, 10.0 ] to - * be equivalent to a rectangle with origin of [ 10.0, 10.0 ] and size of - * [ -10.0, -10.0 ]. - * - * Application code can normalize rectangles using clutter_rect_normalize(): - * this function will ensure that the width and height of a #ClutterRect are - * positive values. All functions taking a #ClutterRect as an argument will - * implicitly normalize it before computing eventual results. For this reason - * it is safer to access the contents of a #ClutterRect by using the provided - * API at all times, instead of directly accessing the structure members. - * - * Since: 1.12 - */ -struct _ClutterRect -{ - ClutterPoint origin; - ClutterSize size; -}; - -/** - * CLUTTER_RECT_INIT: - * @x: the X coordinate - * @y: the Y coordinate - * @width: the width - * @height: the height - * - * A simple macro for initializing a #ClutterRect when declaring it, e.g.: - * - * |[ - * ClutterRect r = CLUTTER_RECT_INIT (100, 100, 200, 200); - * ]| - * - * Since: 1.12 - */ -#define CLUTTER_RECT_INIT(x,y,width,height) { { (x), (y) }, { (width), (height) } } - -/** - * CLUTTER_RECT_INIT_ZERO: - * - * A simple macro for initializing a #ClutterRect to (0, 0, 0, 0) when - * declaring it. - * - * Since: 1.12 - */ -#define CLUTTER_RECT_INIT_ZERO CLUTTER_RECT_INIT (0.f, 0.f, 0.f, 0.f) - -CLUTTER_AVAILABLE_IN_1_12 -GType clutter_rect_get_type (void) G_GNUC_CONST; - -CLUTTER_AVAILABLE_IN_1_12 -const ClutterRect * clutter_rect_zero (void); -CLUTTER_AVAILABLE_IN_1_12 -ClutterRect * clutter_rect_alloc (void); -CLUTTER_AVAILABLE_IN_1_12 -ClutterRect * clutter_rect_init (ClutterRect *rect, - float x, - float y, - float width, - float height); -CLUTTER_AVAILABLE_IN_1_12 -ClutterRect * clutter_rect_copy (const ClutterRect *rect); -CLUTTER_AVAILABLE_IN_1_12 -void clutter_rect_free (ClutterRect *rect); -CLUTTER_AVAILABLE_IN_1_12 -gboolean clutter_rect_equals (ClutterRect *a, - ClutterRect *b); - -CLUTTER_AVAILABLE_IN_1_12 -ClutterRect * clutter_rect_normalize (ClutterRect *rect); -CLUTTER_AVAILABLE_IN_1_12 -void clutter_rect_get_center (ClutterRect *rect, - ClutterPoint *center); -CLUTTER_AVAILABLE_IN_1_12 -gboolean clutter_rect_contains_point (ClutterRect *rect, - ClutterPoint *point); -CLUTTER_AVAILABLE_IN_1_12 -gboolean clutter_rect_contains_rect (ClutterRect *a, - ClutterRect *b); -CLUTTER_AVAILABLE_IN_1_12 -void clutter_rect_union (ClutterRect *a, - ClutterRect *b, - ClutterRect *res); -CLUTTER_AVAILABLE_IN_1_12 -gboolean clutter_rect_intersection (ClutterRect *a, - ClutterRect *b, - ClutterRect *res); -CLUTTER_AVAILABLE_IN_1_12 -void clutter_rect_offset (ClutterRect *rect, - float d_x, - float d_y); -CLUTTER_AVAILABLE_IN_1_12 -void clutter_rect_inset (ClutterRect *rect, - float d_x, - float d_y); -CLUTTER_AVAILABLE_IN_1_12 -void clutter_rect_clamp_to_pixel (ClutterRect *rect); -CLUTTER_AVAILABLE_IN_1_12 -float clutter_rect_get_x (ClutterRect *rect); -CLUTTER_AVAILABLE_IN_1_12 -float clutter_rect_get_y (ClutterRect *rect); -CLUTTER_AVAILABLE_IN_1_12 -float clutter_rect_get_width (ClutterRect *rect); -CLUTTER_AVAILABLE_IN_1_12 -float clutter_rect_get_height (ClutterRect *rect); - -/** - * ClutterVertex: - * @x: X coordinate of the vertex - * @y: Y coordinate of the vertex - * @z: Z coordinate of the vertex - * - * A point in 3D space, expressed in pixels - * - * Since: 0.4 - */ -struct _ClutterVertex -{ - gfloat x; - gfloat y; - gfloat z; -}; - -/** - * CLUTTER_VERTEX_INIT: - * @x: the X coordinate of the vertex - * @y: the Y coordinate of the vertex - * @z: the Z coordinate of the vertex - * - * A simple macro for initializing a #ClutterVertex when declaring it, e.g.: - * - * |[ - * ClutterVertex v = CLUTTER_VERTEX_INIT (x, y, z); - * ]| - * - * Since: 1.10 - */ -#define CLUTTER_VERTEX_INIT(x,y,z) { (x), (y), (z) } - -/** - * CLUTTER_VERTEX_INIT_ZERO: - * - * A simple macro for initializing a #ClutterVertex to (0, 0, 0). - * - * Since: 1.12 - */ -#define CLUTTER_VERTEX_INIT_ZERO CLUTTER_VERTEX_INIT (0.f, 0.f, 0.f) - -CLUTTER_AVAILABLE_IN_ALL -GType clutter_vertex_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_ALL -ClutterVertex *clutter_vertex_new (gfloat x, - gfloat y, - gfloat z); -CLUTTER_AVAILABLE_IN_1_12 -ClutterVertex *clutter_vertex_alloc (void); -CLUTTER_AVAILABLE_IN_ALL -ClutterVertex *clutter_vertex_init (ClutterVertex *vertex, - gfloat x, - gfloat y, - gfloat z); -CLUTTER_AVAILABLE_IN_ALL -ClutterVertex *clutter_vertex_copy (const ClutterVertex *vertex); -CLUTTER_AVAILABLE_IN_ALL -void clutter_vertex_free (ClutterVertex *vertex); -CLUTTER_AVAILABLE_IN_ALL -gboolean clutter_vertex_equal (const ClutterVertex *vertex_a, - const ClutterVertex *vertex_b); - /** * ClutterActorBox: * @x1: X coordinate of the top left corner @@ -488,114 +178,83 @@ struct _ClutterActorBox */ #define CLUTTER_ACTOR_BOX_INIT_ZERO CLUTTER_ACTOR_BOX_INIT (0.f, 0.f, 0.f, 0.f) -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT GType clutter_actor_box_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterActorBox *clutter_actor_box_new (gfloat x_1, gfloat y_1, gfloat x_2, gfloat y_2); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT ClutterActorBox *clutter_actor_box_alloc (void); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterActorBox *clutter_actor_box_init (ClutterActorBox *box, gfloat x_1, gfloat y_1, gfloat x_2, gfloat y_2); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_box_init_rect (ClutterActorBox *box, gfloat x, gfloat y, gfloat width, gfloat height); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterActorBox *clutter_actor_box_copy (const ClutterActorBox *box); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_box_free (ClutterActorBox *box); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gboolean clutter_actor_box_equal (const ClutterActorBox *box_a, const ClutterActorBox *box_b); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gfloat clutter_actor_box_get_x (const ClutterActorBox *box); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gfloat clutter_actor_box_get_y (const ClutterActorBox *box); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gfloat clutter_actor_box_get_width (const ClutterActorBox *box); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gfloat clutter_actor_box_get_height (const ClutterActorBox *box); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_box_get_origin (const ClutterActorBox *box, gfloat *x, gfloat *y); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_box_get_size (const ClutterActorBox *box, gfloat *width, gfloat *height); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gfloat clutter_actor_box_get_area (const ClutterActorBox *box); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gboolean clutter_actor_box_contains (const ClutterActorBox *box, gfloat x, gfloat y); -CLUTTER_AVAILABLE_IN_ALL -void clutter_actor_box_from_vertices (ClutterActorBox *box, - const ClutterVertex verts[]); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT +void clutter_actor_box_from_vertices (ClutterActorBox *box, + const graphene_point3d_t verts[]); +CLUTTER_EXPORT void clutter_actor_box_interpolate (const ClutterActorBox *initial, const ClutterActorBox *final, gdouble progress, ClutterActorBox *result); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_box_clamp_to_pixel (ClutterActorBox *box); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_box_union (const ClutterActorBox *a, const ClutterActorBox *b, ClutterActorBox *result); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_box_set_origin (ClutterActorBox *box, gfloat x, gfloat y); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_actor_box_set_size (ClutterActorBox *box, gfloat width, gfloat height); -/** - * ClutterGeometry: - * @x: X coordinate of the top left corner of an actor - * @y: Y coordinate of the top left corner of an actor - * @width: width of an actor - * @height: height of an actor - * - * The rectangle containing an actor's bounding box, measured in pixels. - * - * You should not use #ClutterGeometry, or operate on its fields - * directly; you should use #cairo_rectangle_int_t or #ClutterRect if you - * need a rectangle type, depending on the precision required. - * - * Deprecated: 1.16 - */ -struct _ClutterGeometry -{ - /*< public >*/ - gint x; - gint y; - guint width; - guint height; -}; - -CLUTTER_AVAILABLE_IN_ALL -GType clutter_geometry_get_type (void) G_GNUC_CONST; - -CLUTTER_DEPRECATED_IN_1_16 -void clutter_geometry_union (const ClutterGeometry *geometry_a, - const ClutterGeometry *geometry_b, - ClutterGeometry *result); -CLUTTER_DEPRECATED_IN_1_16 -gboolean clutter_geometry_intersects (const ClutterGeometry *geometry0, - const ClutterGeometry *geometry1); +CLUTTER_EXPORT +void clutter_actor_box_scale (ClutterActorBox *box, + gfloat scale); /** * ClutterKnot: @@ -612,13 +271,13 @@ struct _ClutterKnot gint y; }; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT GType clutter_knot_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT ClutterKnot *clutter_knot_copy (const ClutterKnot *knot); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_knot_free (ClutterKnot *knot); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gboolean clutter_knot_equal (const ClutterKnot *knot_a, const ClutterKnot *knot_b); @@ -643,14 +302,14 @@ struct _ClutterPathNode ClutterKnot points[3]; }; -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT GType clutter_path_node_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT ClutterPathNode *clutter_path_node_copy (const ClutterPathNode *node); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_path_node_free (ClutterPathNode *node); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT gboolean clutter_path_node_equal (const ClutterPathNode *node_a, const ClutterPathNode *node_b); @@ -658,43 +317,43 @@ gboolean clutter_path_node_equal (const ClutterPathNode *node_a, * ClutterPaintVolume */ -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT GType clutter_paint_volume_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT ClutterPaintVolume *clutter_paint_volume_copy (const ClutterPaintVolume *pv); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT void clutter_paint_volume_free (ClutterPaintVolume *pv); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT void clutter_paint_volume_set_origin (ClutterPaintVolume *pv, - const ClutterVertex *origin); -CLUTTER_AVAILABLE_IN_1_2 + const graphene_point3d_t *origin); +CLUTTER_EXPORT void clutter_paint_volume_get_origin (const ClutterPaintVolume *pv, - ClutterVertex *vertex); -CLUTTER_AVAILABLE_IN_1_2 + graphene_point3d_t *vertex); +CLUTTER_EXPORT void clutter_paint_volume_set_width (ClutterPaintVolume *pv, gfloat width); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT gfloat clutter_paint_volume_get_width (const ClutterPaintVolume *pv); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT void clutter_paint_volume_set_height (ClutterPaintVolume *pv, gfloat height); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT gfloat clutter_paint_volume_get_height (const ClutterPaintVolume *pv); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT void clutter_paint_volume_set_depth (ClutterPaintVolume *pv, gfloat depth); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT gfloat clutter_paint_volume_get_depth (const ClutterPaintVolume *pv); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT void clutter_paint_volume_union (ClutterPaintVolume *pv, const ClutterPaintVolume *another_pv); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_paint_volume_union_box (ClutterPaintVolume *pv, const ClutterActorBox *box); -CLUTTER_AVAILABLE_IN_1_2 +CLUTTER_EXPORT gboolean clutter_paint_volume_set_from_allocation (ClutterPaintVolume *pv, ClutterActor *actor); @@ -717,14 +376,14 @@ struct _ClutterMargin float bottom; }; -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT GType clutter_margin_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT ClutterMargin * clutter_margin_new (void) G_GNUC_MALLOC; -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT ClutterMargin * clutter_margin_copy (const ClutterMargin *margin_); -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_margin_free (ClutterMargin *margin_); /** @@ -755,24 +414,24 @@ typedef gboolean (* ClutterProgressFunc) (const GValue *a, gdouble progress, GValue *retval); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_interval_register_progress_func (GType value_type, ClutterProgressFunc func); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT GType clutter_matrix_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT ClutterMatrix * clutter_matrix_alloc (void); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT ClutterMatrix * clutter_matrix_init_identity (ClutterMatrix *matrix); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT ClutterMatrix * clutter_matrix_init_from_array (ClutterMatrix *matrix, const float values[16]); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT ClutterMatrix * clutter_matrix_init_from_matrix (ClutterMatrix *a, const ClutterMatrix *b); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_matrix_free (ClutterMatrix *matrix); G_END_DECLS diff --git a/clutter/clutter/clutter-units.c b/clutter/clutter/clutter-units.c index cf6b47de9..447e55d42 100644 --- a/clutter/clutter/clutter-units.c +++ b/clutter/clutter/clutter-units.c @@ -62,9 +62,7 @@ * #ClutterUnits is available since Clutter 1.0 */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include @@ -600,7 +598,7 @@ clutter_unit_type_name (ClutterUnitType unit_type) * typographic points. Pixels are integers. * * Return value: a newly allocated string containing the encoded - * #ClutterUnits value. Use free() to free the string + * #ClutterUnits value. Use g_free() to free the string * * Since: 1.0 */ @@ -826,7 +824,7 @@ param_units_validate (GParamSpec *pspec, str, clutter_unit_type_name (uspec->default_type)); - free (str); + g_free (str); return FALSE; } diff --git a/clutter/clutter/clutter-units.h b/clutter/clutter/clutter-units.h index 549be9f8f..900f90d2b 100644 --- a/clutter/clutter/clutter-units.h +++ b/clutter/clutter/clutter-units.h @@ -70,45 +70,45 @@ struct _ClutterUnits gint64 __padding_2; }; -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT GType clutter_units_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT ClutterUnitType clutter_units_get_unit_type (const ClutterUnits *units); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT gfloat clutter_units_get_unit_value (const ClutterUnits *units); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT ClutterUnits * clutter_units_copy (const ClutterUnits *units); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_units_free (ClutterUnits *units); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_units_from_pixels (ClutterUnits *units, gint px); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_units_from_em (ClutterUnits *units, gfloat em); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_units_from_em_for_font (ClutterUnits *units, const gchar *font_name, gfloat em); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_units_from_mm (ClutterUnits *units, gfloat mm); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_units_from_cm (ClutterUnits *units, gfloat cm); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_units_from_pt (ClutterUnits *units, gfloat pt); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT gfloat clutter_units_to_pixels (ClutterUnits *units); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT gboolean clutter_units_from_string (ClutterUnits *units, const gchar *str); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT gchar * clutter_units_to_string (const ClutterUnits *units); /* shorthands for the constructors */ @@ -160,10 +160,10 @@ struct _ClutterParamSpecUnits gfloat maximum; }; -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT GType clutter_param_units_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT GParamSpec * clutter_param_spec_units (const gchar *name, const gchar *nick, const gchar *blurb, @@ -173,10 +173,10 @@ GParamSpec * clutter_param_spec_units (const gchar *name, gfloat default_value, GParamFlags flags); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT void clutter_value_set_units (GValue *value, const ClutterUnits *units); -CLUTTER_AVAILABLE_IN_1_0 +CLUTTER_EXPORT const ClutterUnits * clutter_value_get_units (const GValue *value); G_END_DECLS diff --git a/clutter/clutter/clutter-util.c b/clutter/clutter/clutter-util.c index 14ef740f4..6e59889a8 100644 --- a/clutter/clutter/clutter-util.c +++ b/clutter/clutter/clutter-util.c @@ -30,10 +30,9 @@ * Various miscellaneous utilility functions. */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif +#include #include #include "clutter-debug.h" @@ -41,29 +40,6 @@ #include "clutter-interval.h" #include "clutter-private.h" -#include "deprecated/clutter-util.h" - -/** - * clutter_util_next_p2: - * @a: Value to get the next power - * - * Calculates the nearest power of two, greater than or equal to @a. - * - * Return value: The nearest power of two, greater or equal to @a. - * - * Deprecated: 1.2 - */ -gint -clutter_util_next_p2 (gint a) -{ - int rval = 1; - - while (rval < a) - rval <<= 1; - - return rval; -} - /* Help macros to scale from OpenGL <-1,1> coordinates system to * window coordinates ranging [0,window-size] */ @@ -75,8 +51,8 @@ void _clutter_util_fully_transform_vertices (const CoglMatrix *modelview, const CoglMatrix *projection, const float *viewport, - const ClutterVertex *vertices_in, - ClutterVertex *vertices_out, + const graphene_point3d_t *vertices_in, + graphene_point3d_t *vertices_out, int n_vertices) { CoglMatrix modelview_projection; @@ -93,7 +69,7 @@ _clutter_util_fully_transform_vertices (const CoglMatrix *modelview, modelview); cogl_matrix_project_points (&modelview_projection, 3, - sizeof (ClutterVertex), + sizeof (graphene_point3d_t), vertices_in, sizeof (ClutterVertex4), vertices_tmp, @@ -103,7 +79,7 @@ _clutter_util_fully_transform_vertices (const CoglMatrix *modelview, { cogl_matrix_transform_points (modelview, 3, - sizeof (ClutterVertex), + sizeof (graphene_point3d_t), vertices_in, sizeof (ClutterVertex4), vertices_tmp, @@ -121,7 +97,7 @@ _clutter_util_fully_transform_vertices (const CoglMatrix *modelview, for (i = 0; i < n_vertices; i++) { ClutterVertex4 vertex_tmp = vertices_tmp[i]; - ClutterVertex *vertex_out = &vertices_out[i]; + graphene_point3d_t *vertex_out = &vertices_out[i]; /* Finally translate from OpenGL coords to window coords */ vertex_out->x = MTX_GL_SCALE_X (vertex_tmp.x, vertex_tmp.w, viewport[2], viewport[0]); @@ -130,6 +106,50 @@ _clutter_util_fully_transform_vertices (const CoglMatrix *modelview, } } +void +_clutter_util_rect_from_rectangle (const cairo_rectangle_int_t *src, + graphene_rect_t *dest) +{ + *dest = (graphene_rect_t) { + .origin = { + .x = src->x, + .y = src->y + }, + .size = { + .width = src->width, + .height = src->height + } + }; +} + +void +_clutter_util_rectangle_int_extents (const graphene_rect_t *src, + cairo_rectangle_int_t *dest) +{ + graphene_rect_t tmp = *src; + + graphene_rect_round_extents (&tmp, &tmp); + + *dest = (cairo_rectangle_int_t) { + .x = tmp.origin.x, + .y = tmp.origin.y, + .width = tmp.size.width, + .height = tmp.size.height, + }; +} + +void +_clutter_util_rectangle_offset (const cairo_rectangle_int_t *src, + int x, + int y, + cairo_rectangle_int_t *dest) +{ + *dest = *src; + + dest->x += x; + dest->y += y; +} + /*< private > * _clutter_util_rectangle_union: * @src1: first rectangle to union @@ -194,6 +214,16 @@ _clutter_util_rectangle_intersection (const cairo_rectangle_int_t *src1, } } +gboolean +clutter_util_rectangle_equal (const cairo_rectangle_int_t *src1, + const cairo_rectangle_int_t *src2) +{ + return ((src1->x == src2->x) && + (src1->y == src2->y) && + (src1->width == src2->width) && + (src1->height == src2->height)); +} + float _clutter_util_matrix_determinant (const ClutterMatrix *matrix) { @@ -279,48 +309,12 @@ _clutter_util_matrix_skew_yz (ClutterMatrix *matrix, matrix->zw += matrix->yw * factor; } -static float -_clutter_util_vertex_length (const ClutterVertex *vertex) -{ - return sqrtf (vertex->x * vertex->x + vertex->y * vertex->y + vertex->z * vertex->z); -} - -static void -_clutter_util_vertex_normalize (ClutterVertex *vertex) -{ - float factor = _clutter_util_vertex_length (vertex); - - if (factor == 0.f) - return; - - vertex->x /= factor; - vertex->y /= factor; - vertex->z /= factor; -} - -static float -_clutter_util_vertex_dot (const ClutterVertex *v1, - const ClutterVertex *v2) -{ - return v1->x * v2->x + v1->y * v2->y + v1->z * v2->z; -} - -static void -_clutter_util_vertex_cross (const ClutterVertex *v1, - const ClutterVertex *v2, - ClutterVertex *res) -{ - res->x = v1->y * v2->z - v2->y * v1->z; - res->y = v1->z * v2->x - v2->z * v1->x; - res->z = v1->x * v2->y - v2->x * v1->y; -} - static void -_clutter_util_vertex_combine (const ClutterVertex *a, - const ClutterVertex *b, - double ascl, - double bscl, - ClutterVertex *res) +_clutter_util_vertex_combine (const graphene_point3d_t *a, + const graphene_point3d_t *b, + double ascl, + double bscl, + graphene_point3d_t *res) { res->x = (ascl * a->x) + (bscl * b->x); res->y = (ascl * a->y) + (bscl * b->y); @@ -368,16 +362,16 @@ _clutter_util_vertex4_interpolate (const ClutterVertex4 *a, */ gboolean _clutter_util_matrix_decompose (const ClutterMatrix *src, - ClutterVertex *scale_p, + graphene_point3d_t *scale_p, float shear_p[3], - ClutterVertex *rotate_p, - ClutterVertex *translate_p, + graphene_point3d_t *rotate_p, + graphene_point3d_t *translate_p, ClutterVertex4 *perspective_p) { CoglMatrix matrix = *src; CoglMatrix perspective; ClutterVertex4 vertex_tmp; - ClutterVertex row[3], pdum; + graphene_point3d_t row[3], pdum; int i, j; #define XY_SHEAR 0 @@ -465,34 +459,34 @@ _clutter_util_matrix_decompose (const ClutterMatrix *src, } /* compute scale.x and normalize the first row */ - scale_p->x = _clutter_util_vertex_length (&row[0]); - _clutter_util_vertex_normalize (&row[0]); + scale_p->x = graphene_point3d_length (&row[0]); + graphene_point3d_normalize (&row[0], &row[0]); /* compute XY shear and make the second row orthogonal to the first */ - shear_p[XY_SHEAR] = _clutter_util_vertex_dot (&row[0], &row[1]); + shear_p[XY_SHEAR] = graphene_point3d_dot (&row[0], &row[1]); _clutter_util_vertex_combine (&row[1], &row[0], 1.0, -shear_p[XY_SHEAR], &row[1]); /* compute the Y scale and normalize the second row */ - scale_p->y = _clutter_util_vertex_length (&row[1]); - _clutter_util_vertex_normalize (&row[1]); + scale_p->y = graphene_point3d_length (&row[1]); + graphene_point3d_normalize (&row[1], &row[1]); shear_p[XY_SHEAR] /= scale_p->y; /* compute XZ and YZ shears, orthogonalize the third row */ - shear_p[XZ_SHEAR] = _clutter_util_vertex_dot (&row[0], &row[2]); + shear_p[XZ_SHEAR] = graphene_point3d_dot (&row[0], &row[2]); _clutter_util_vertex_combine (&row[2], &row[0], 1.0, -shear_p[XZ_SHEAR], &row[2]); - shear_p[YZ_SHEAR] = _clutter_util_vertex_dot (&row[1], &row[2]); + shear_p[YZ_SHEAR] = graphene_point3d_dot (&row[1], &row[2]); _clutter_util_vertex_combine (&row[2], &row[1], 1.0, -shear_p[YZ_SHEAR], &row[2]); /* get the Z scale and normalize the third row*/ - scale_p->z = _clutter_util_vertex_length (&row[2]); - _clutter_util_vertex_normalize (&row[2]); + scale_p->z = graphene_point3d_length (&row[2]); + graphene_point3d_normalize (&row[2], &row[2]); shear_p[XZ_SHEAR] /= scale_p->z; shear_p[YZ_SHEAR] /= scale_p->z; @@ -500,8 +494,8 @@ _clutter_util_matrix_decompose (const ClutterMatrix *src, * check for a coordinate system flip; if the determinant * is -1, then negate the matrix and scaling factors */ - _clutter_util_vertex_cross (&row[1], &row[2], &pdum); - if (_clutter_util_vertex_dot (&row[0], &pdum) < 0.f) + graphene_point3d_cross (&row[1], &row[2], &pdum); + if (graphene_point3d_dot (&row[0], &pdum) < 0.f) { scale_p->x *= -1.f; @@ -680,3 +674,45 @@ clutter_interval_register_progress_func (GType value_type, G_UNLOCK (progress_funcs); } + +PangoDirection +_clutter_pango_unichar_direction (gunichar ch) +{ + FriBidiCharType fribidi_ch_type; + + G_STATIC_ASSERT (sizeof (FriBidiChar) == sizeof (gunichar)); + + fribidi_ch_type = fribidi_get_bidi_type (ch); + + if (!FRIBIDI_IS_STRONG (fribidi_ch_type)) + return PANGO_DIRECTION_NEUTRAL; + else if (FRIBIDI_IS_RTL (fribidi_ch_type)) + return PANGO_DIRECTION_RTL; + else + return PANGO_DIRECTION_LTR; +} + +PangoDirection +_clutter_pango_find_base_dir (const gchar *text, + gint length) +{ + PangoDirection dir = PANGO_DIRECTION_NEUTRAL; + const gchar *p; + + g_return_val_if_fail (text != NULL || length == 0, PANGO_DIRECTION_NEUTRAL); + + p = text; + while ((length < 0 || p < text + length) && *p) + { + gunichar wc = g_utf8_get_char (p); + + dir = _clutter_pango_unichar_direction (wc); + + if (dir != PANGO_DIRECTION_NEUTRAL) + break; + + p = g_utf8_next_char (p); + } + + return dir; +} diff --git a/clutter/clutter/clutter-version.h.in b/clutter/clutter/clutter-version.h.in deleted file mode 100644 index 08ddd5871..000000000 --- a/clutter/clutter/clutter-version.h.in +++ /dev/null @@ -1,347 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * Copyright (C) 2006 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __CLUTTER_VERSION_H__ -#define __CLUTTER_VERSION_H__ - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -/** - * SECTION:clutter-version - * @short_description: Versioning utility macros - * - * Clutter offers a set of macros for checking the version of the library - * at compile time; it also provides a function to perform the same check - * at run time. - * - * Clutter adds version information to both API deprecations and additions; - * by definining the macros %CLUTTER_VERSION_MIN_REQUIRED and - * %CLUTTER_VERSION_MAX_ALLOWED, you can specify the range of Clutter versions - * whose API you want to use. Functions that were deprecated before, or - * introduced after, this range will trigger compiler warnings. For instance, - * if we define the following symbols: - * - * |[ - * CLUTTER_VERSION_MIN_REQUIRED = CLUTTER_VERSION_1_6 - * CLUTTER_VERSION_MAX_ALLOWED = CLUTTER_VERSION_1_8 - * ]| - * - * and we have the following functions annotated in the Clutter headers: - * - * |[ - * void clutter_function_A (void) CLUTTER_DEPRECATED_IN_1_4; - * void clutter_function_B (void) CLUTTER_DEPRECATED_IN_1_6; - * void clutter_function_C (void) CLUTTER_AVAILABLE_IN_1_8; - * void clutter_function_D (void) CLUTTER_AVAILABLE_IN_1_10; - * ]| - * - * then any application code using the functions above will get the output: - * - * |[ - * clutter_function_A: deprecation warning - * clutter_function_B: no warning - * clutter_function_C: no warning - * clutter_function_D: symbol not available warning - * ]| - * - * It is possible to disable the compiler warnings by defining the macro - * %CLUTTER_DISABLE_DEPRECATION_WARNINGS before including the clutter.h - * header. - */ - -#include - -G_BEGIN_DECLS - -/** - * CLUTTER_MAJOR_VERSION: - * - * The major version of the Clutter library (1, if %CLUTTER_VERSION is 1.2.3) - */ -#define CLUTTER_MAJOR_VERSION (@CLUTTER_MAJOR_VERSION@) - -/** - * CLUTTER_MINOR_VERSION: - * - * The minor version of the Clutter library (2, if %CLUTTER_VERSION is 1.2.3) - */ -#define CLUTTER_MINOR_VERSION (@CLUTTER_MINOR_VERSION@) - -/** - * CLUTTER_MICRO_VERSION: - * - * The micro version of the Clutter library (3, if %CLUTTER_VERSION is 1.2.3) - */ -#define CLUTTER_MICRO_VERSION (@CLUTTER_MICRO_VERSION@) - -/** - * CLUTTER_VERSION: - * - * The full version of the Clutter library, like 1.2.3 - */ -#define CLUTTER_VERSION @CLUTTER_VERSION@ - -/** - * CLUTTER_VERSION_S: - * - * The full version of the Clutter library, in string form (suited for - * string concatenation) - */ -#define CLUTTER_VERSION_S "@CLUTTER_VERSION@" - -/** - * CLUTTER_VERSION_HEX: - * - * Numerically encoded version of the Clutter library, like 0x010203 - */ -#define CLUTTER_VERSION_HEX ((CLUTTER_MAJOR_VERSION << 24) | \ - (CLUTTER_MINOR_VERSION << 16) | \ - (CLUTTER_MICRO_VERSION << 8)) - -/* XXX - Every new stable minor release bump should add a macro here */ - -/** - * CLUTTER_VERSION_1_0: - * - * A macro that evaluates to the 1.0 version of Clutter, in a format - * that can be used by the C pre-processor. - * - * Since: 1.10 - */ -#define CLUTTER_VERSION_1_0 (G_ENCODE_VERSION (1, 0)) - -/** - * CLUTTER_VERSION_1_2: - * - * A macro that evaluates to the 1.2 version of Clutter, in a format - * that can be used by the C pre-processor. - * - * Since: 1.10 - */ -#define CLUTTER_VERSION_1_2 (G_ENCODE_VERSION (1, 2)) - -/** - * CLUTTER_VERSION_1_4: - * - * A macro that evaluates to the 1.4 version of Clutter, in a format - * that can be used by the C pre-processor. - * - * Since: 1.10 - */ -#define CLUTTER_VERSION_1_4 (G_ENCODE_VERSION (1, 4)) - -/** - * CLUTTER_VERSION_1_6: - * - * A macro that evaluates to the 1.6 version of Clutter, in a format - * that can be used by the C pre-processor. - * - * Since: 1.10 - */ -#define CLUTTER_VERSION_1_6 (G_ENCODE_VERSION (1, 6)) - -/** - * CLUTTER_VERSION_1_8: - * - * A macro that evaluates to the 1.8 version of Clutter, in a format - * that can be used by the C pre-processor. - * - * Since: 1.10 - */ -#define CLUTTER_VERSION_1_8 (G_ENCODE_VERSION (1, 8)) - -/** - * CLUTTER_VERSION_1_10: - * - * A macro that evaluates to the 1.10 version of Clutter, in a format - * that can be used by the C pre-processor. - * - * Since: 1.10 - */ -#define CLUTTER_VERSION_1_10 (G_ENCODE_VERSION (1, 10)) - -/** - * CLUTTER_VERSION_1_12: - * - * A macro that evaluates to the 1.12 version of Clutter, in a format - * that can be used by the C pre-processor. - * - * Since: 1.12 - */ -#define CLUTTER_VERSION_1_12 (G_ENCODE_VERSION (1, 12)) - -/** - * CLUTTER_VERSION_1_14: - * - * A macro that evaluates to the 1.14 version of Clutter, in a format - * that can be used by the C pre-processor. - * - * Since: 1.14 - */ -#define CLUTTER_VERSION_1_14 (G_ENCODE_VERSION (1, 14)) - -/** - * CLUTTER_VERSION_1_16: - * - * A macro that evaluates to the 1.16 version of Clutter, in a format - * that can be used by the C pre-processor. - * - * Since: 1.16 - */ -#define CLUTTER_VERSION_1_16 (G_ENCODE_VERSION (1, 16)) - -/** - * CLUTTER_VERSION_1_18: - * - * A macro that evaluates to the 1.18 version of Clutter, in a format - * that can be used by the C pre-processor. - * - * Since: 1.18 - */ -#define CLUTTER_VERSION_1_18 (G_ENCODE_VERSION (1, 18)) - -/** - * CLUTTER_VERSION_1_20: - * - * A macro that evaluates to the 1.20 version of Clutter, in a format - * that can be used by the C pre-processor. - * - * Since: 1.20 - */ -#define CLUTTER_VERSION_1_20 (G_ENCODE_VERSION (1, 20)) - -/** - * CLUTTER_VERSION_1_22: - * - * A macro that evaluates to the 1.22 version of Clutter, in a format - * that can be used by the C pre-processor. - * - * Since: 1.22 - */ -#define CLUTTER_VERSION_1_22 (G_ENCODE_VERSION (1, 22)) - -/** - * CLUTTER_VERSION_1_24: - * - * A macro that evaluates to the 1.24 version of Clutter, in a format - * that can be used by the C pre-processor. - * - * Since: 1.24 - */ -#define CLUTTER_VERSION_1_24 (G_ENCODE_VERSION (1, 24)) - -/** - * CLUTTER_VERSION_1_26: - * - * A macro that evaluates to the 1.26 version of Clutter, in a format - * that can be used by the C pre-processor. - * - * Since: 1.26 - */ -#define CLUTTER_VERSION_1_26 (G_ENCODE_VERSION (1, 26)) - -/* evaluates to the current stable version; for development cycles, - * this means the next stable target - */ -#if (CLUTTER_MINOR_VERSION % 2) -# define CLUTTER_VERSION_CUR_STABLE (G_ENCODE_VERSION (CLUTTER_MAJOR_VERSION, CLUTTER_MINOR_VERSION + 1)) -#else -# define CLUTTER_VERSION_CUR_STABLE (G_ENCODE_VERSION (CLUTTER_MAJOR_VERSION, CLUTTER_MINOR_VERSION)) -#endif - -/* evaluates to the previous stable version */ -#if (CLUTTER_MINOR_VERSION % 2) -# define CLUTTER_VERSION_PREV_STABLE (G_ENCODE_VERSION (CLUTTER_MAJOR_VERSION, CLUTTER_MINOR_VERSION - 1)) -#else -# define CLUTTER_VERSION_PREV_STABLE (G_ENCODE_VERSION (CLUTTER_MAJOR_VERSION, CLUTTER_MINOR_VERSION - 2)) -#endif - -/** - * CLUTTER_CHECK_VERSION: - * @major: major version, like 1 in 1.2.3 - * @minor: minor version, like 2 in 1.2.3 - * @micro: micro version, like 3 in 1.2.3 - * - * Evaluates to %TRUE if the version of the Clutter library is greater - * than @major, @minor and @micro - */ -#define CLUTTER_CHECK_VERSION(major,minor,micro) \ - (CLUTTER_MAJOR_VERSION > (major) || \ - (CLUTTER_MAJOR_VERSION == (major) && CLUTTER_MINOR_VERSION > (minor)) || \ - (CLUTTER_MAJOR_VERSION == (major) && CLUTTER_MINOR_VERSION == (minor) && CLUTTER_MICRO_VERSION >= (micro))) - -#ifndef _CLUTTER_EXTERN -#define _CLUTTER_EXTERN extern -#endif - -#define CLUTTER_VAR _CLUTTER_EXTERN - -/** - * clutter_major_version: - * - * The major component of the Clutter library version, e.g. 1 if the version - * is 1.2.3 - * - * This value can be used for run-time version checks - * - * For a compile-time check, use %CLUTTER_MAJOR_VERSION - * - * Since: 1.2 - */ -extern const guint clutter_major_version; - -/** - * clutter_minor_version: - * - * The minor component of the Clutter library version, e.g. 2 if the version - * is 1.2.3 - * - * This value can be used for run-time version checks - * - * For a compile-time check, use %CLUTTER_MINOR_VERSION - * - * Since: 1.2 - */ -extern const guint clutter_minor_version; - -/** - * clutter_micro_version: - * - * The micro component of the Clutter library version, e.g. 3 if the version - * is 1.2.3 - * - * This value can be used for run-time version checks - * - * For a compile-time check, use %CLUTTER_MICRO_VERSION - * - * Since: 1.2 - */ -extern const guint clutter_micro_version; - -G_END_DECLS - -#endif /* __CLUTTER_VERSION_H__ */ diff --git a/clutter/clutter/clutter-virtual-input-device.c b/clutter/clutter/clutter-virtual-input-device.c index d86433361..522a6596f 100644 --- a/clutter/clutter/clutter-virtual-input-device.c +++ b/clutter/clutter/clutter-virtual-input-device.c @@ -21,23 +21,21 @@ * Author: Jonas Ådahl */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include #include "clutter-virtual-input-device.h" -#include "clutter-device-manager.h" -#include "clutter-private.h" #include "clutter-enum-types.h" +#include "clutter-private.h" +#include "clutter-seat.h" enum { PROP_0, - PROP_DEVICE_MANAGER, + PROP_SEAT, PROP_DEVICE_TYPE, PROP_LAST @@ -47,7 +45,7 @@ static GParamSpec *obj_props[PROP_LAST]; typedef struct _ClutterVirtualInputDevicePrivate { - ClutterDeviceManager *manager; + ClutterSeat *seat; ClutterInputDeviceType device_type; } ClutterVirtualInputDevicePrivate; @@ -183,23 +181,6 @@ clutter_virtual_input_device_notify_touch_up (ClutterVirtualInputDevice *virtual slot); } -/** - * clutter_virtual_input_device_get_manager: - * @virtual_device: a virtual device - * - * Gets the device manager of this virtual device. - * - * Returns: (transfer none): The #ClutterDeviceManager of this virtual device - **/ -ClutterDeviceManager * -clutter_virtual_input_device_get_manager (ClutterVirtualInputDevice *virtual_device) -{ - ClutterVirtualInputDevicePrivate *priv = - clutter_virtual_input_device_get_instance_private (virtual_device); - - return priv->manager; -} - int clutter_virtual_input_device_get_device_type (ClutterVirtualInputDevice *virtual_device) { @@ -222,8 +203,8 @@ clutter_virtual_input_device_get_property (GObject *object, switch (prop_id) { - case PROP_DEVICE_MANAGER: - g_value_set_object (value, priv->manager); + case PROP_SEAT: + g_value_set_object (value, priv->seat); break; case PROP_DEVICE_TYPE: g_value_set_enum (value, priv->device_type); @@ -247,8 +228,8 @@ clutter_virtual_input_device_set_property (GObject *object, switch (prop_id) { - case PROP_DEVICE_MANAGER: - priv->manager = g_value_get_object (value); + case PROP_SEAT: + priv->seat = g_value_get_object (value); break; case PROP_DEVICE_TYPE: priv->device_type = g_value_get_enum (value); @@ -272,11 +253,11 @@ clutter_virtual_input_device_class_init (ClutterVirtualInputDeviceClass *klass) object_class->get_property = clutter_virtual_input_device_get_property; object_class->set_property = clutter_virtual_input_device_set_property; - obj_props[PROP_DEVICE_MANAGER] = - g_param_spec_object ("device-manager", - P_("Device Manager"), - P_("The device manager instance"), - CLUTTER_TYPE_DEVICE_MANAGER, + obj_props[PROP_SEAT] = + g_param_spec_object ("seat", + P_("Seat"), + P_("Seat"), + CLUTTER_TYPE_SEAT, CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); obj_props[PROP_DEVICE_TYPE] = g_param_spec_enum ("device-type", diff --git a/clutter/clutter/clutter-virtual-input-device.h b/clutter/clutter/clutter-virtual-input-device.h index 11b747a7f..b829c04ad 100644 --- a/clutter/clutter/clutter-virtual-input-device.h +++ b/clutter/clutter/clutter-virtual-input-device.h @@ -27,11 +27,11 @@ #include #include -#include "clutter-device-manager.h" +#include "clutter-seat.h" #define CLUTTER_TYPE_VIRTUAL_INPUT_DEVICE (clutter_virtual_input_device_get_type ()) -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT G_DECLARE_DERIVABLE_TYPE (ClutterVirtualInputDevice, clutter_virtual_input_device, CLUTTER, VIRTUAL_INPUT_DEVICE, @@ -106,43 +106,43 @@ struct _ClutterVirtualInputDeviceClass int slot); }; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_virtual_input_device_notify_relative_motion (ClutterVirtualInputDevice *virtual_device, uint64_t time_us, double dx, double dy); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_virtual_input_device_notify_absolute_motion (ClutterVirtualInputDevice *virtual_device, uint64_t time_us, double x, double y); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_virtual_input_device_notify_button (ClutterVirtualInputDevice *virtual_device, uint64_t time_us, uint32_t button, ClutterButtonState button_state); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_virtual_input_device_notify_key (ClutterVirtualInputDevice *virtual_device, uint64_t time_us, uint32_t key, ClutterKeyState key_state); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_virtual_input_device_notify_keyval (ClutterVirtualInputDevice *virtual_device, uint64_t time_us, uint32_t keyval, ClutterKeyState key_state); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_virtual_input_device_notify_discrete_scroll (ClutterVirtualInputDevice *virtual_device, uint64_t time_us, ClutterScrollDirection direction, ClutterScrollSource scroll_source); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_virtual_input_device_notify_scroll_continuous (ClutterVirtualInputDevice *virtual_device, uint64_t time_us, double dx, @@ -150,28 +150,26 @@ void clutter_virtual_input_device_notify_scroll_continuous (ClutterVirtualInputD ClutterScrollSource scroll_source, ClutterScrollFinishFlags finish_flags); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_virtual_input_device_notify_touch_down (ClutterVirtualInputDevice *virtual_device, uint64_t time_us, int slot, double x, double y); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_virtual_input_device_notify_touch_motion (ClutterVirtualInputDevice *virtual_device, uint64_t time_us, int slot, double x, double y); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_virtual_input_device_notify_touch_up (ClutterVirtualInputDevice *virtual_device, uint64_t time_us, int slot); -CLUTTER_AVAILABLE_IN_ALL -ClutterDeviceManager * clutter_virtual_input_device_get_manager (ClutterVirtualInputDevice *virtual_device); - +CLUTTER_EXPORT int clutter_virtual_input_device_get_device_type (ClutterVirtualInputDevice *virtual_device); #endif /* __CLUTTER_VIRTUAL_INPUT_DEVICE_H__ */ diff --git a/clutter/clutter/clutter-zoom-action.c b/clutter/clutter/clutter-zoom-action.c index b60973d7d..c25b79688 100644 --- a/clutter/clutter/clutter-zoom-action.c +++ b/clutter/clutter/clutter-zoom-action.c @@ -46,9 +46,7 @@ * Since: 1.12 */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include @@ -82,9 +80,9 @@ struct _ClutterZoomActionPrivate ZoomPoint points[2]; - ClutterPoint initial_focal_point; - ClutterPoint focal_point; - ClutterPoint transformed_focal_point; + graphene_point_t initial_focal_point; + graphene_point_t focal_point; + graphene_point_t transformed_focal_point; gfloat initial_x; gfloat initial_y; @@ -240,13 +238,13 @@ clutter_zoom_action_gesture_cancel (ClutterGestureAction *action, static gboolean clutter_zoom_action_real_zoom (ClutterZoomAction *action, ClutterActor *actor, - ClutterPoint *focal_point, + graphene_point_t *focal_point, gdouble factor) { ClutterZoomActionPrivate *priv = action->priv; gfloat x, y, z; gdouble scale_x, scale_y; - ClutterVertex out, in; + graphene_point3d_t out, in; in.x = priv->transformed_focal_point.x; in.y = priv->transformed_focal_point.y; @@ -402,7 +400,7 @@ clutter_zoom_action_class_init (ClutterZoomActionClass *klass) _clutter_marshal_BOOLEAN__OBJECT_BOXED_DOUBLE, G_TYPE_BOOLEAN, 3, CLUTTER_TYPE_ACTOR, - CLUTTER_TYPE_POINT, + GRAPHENE_TYPE_POINT, G_TYPE_DOUBLE); } @@ -480,7 +478,7 @@ clutter_zoom_action_get_zoom_axis (ClutterZoomAction *action) /** * clutter_zoom_action_get_focal_point: * @action: a #ClutterZoomAction - * @point: (out): a #ClutterPoint + * @point: (out): a #graphene_point_t * * Retrieves the focal point of the current zoom * @@ -488,7 +486,7 @@ clutter_zoom_action_get_zoom_axis (ClutterZoomAction *action) */ void clutter_zoom_action_get_focal_point (ClutterZoomAction *action, - ClutterPoint *point) + graphene_point_t *point) { g_return_if_fail (CLUTTER_IS_ZOOM_ACTION (action)); g_return_if_fail (point != NULL); @@ -499,7 +497,7 @@ clutter_zoom_action_get_focal_point (ClutterZoomAction *action, /** * clutter_zoom_action_get_transformed_focal_point: * @action: a #ClutterZoomAction - * @point: (out): a #ClutterPoint + * @point: (out): a #graphene_point_t * * Retrieves the focal point relative to the actor's coordinates of * the current zoom @@ -508,7 +506,7 @@ clutter_zoom_action_get_focal_point (ClutterZoomAction *action, */ void clutter_zoom_action_get_transformed_focal_point (ClutterZoomAction *action, - ClutterPoint *point) + graphene_point_t *point) { g_return_if_fail (CLUTTER_IS_ZOOM_ACTION (action)); g_return_if_fail (point != NULL); diff --git a/clutter/clutter/clutter-zoom-action.h b/clutter/clutter/clutter-zoom-action.h index 496b36ea9..f1f7e572d 100644 --- a/clutter/clutter/clutter-zoom-action.h +++ b/clutter/clutter/clutter-zoom-action.h @@ -79,7 +79,7 @@ struct _ClutterZoomActionClass /*< public >*/ gboolean (* zoom) (ClutterZoomAction *action, ClutterActor *actor, - ClutterPoint *focal_point, + graphene_point_t *focal_point, gdouble factor); /*< private >*/ @@ -90,24 +90,24 @@ struct _ClutterZoomActionClass void (* _clutter_zoom_action5) (void); }; -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT GType clutter_zoom_action_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT ClutterAction * clutter_zoom_action_new (void); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_zoom_action_set_zoom_axis (ClutterZoomAction *action, ClutterZoomAxis axis); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT ClutterZoomAxis clutter_zoom_action_get_zoom_axis (ClutterZoomAction *action); -CLUTTER_AVAILABLE_IN_1_12 +CLUTTER_EXPORT void clutter_zoom_action_get_focal_point (ClutterZoomAction *action, - ClutterPoint *point); -CLUTTER_AVAILABLE_IN_1_12 + graphene_point_t *point); +CLUTTER_EXPORT void clutter_zoom_action_get_transformed_focal_point (ClutterZoomAction *action, - ClutterPoint *point); + graphene_point_t *point); G_END_DECLS diff --git a/clutter/clutter/clutter.h b/clutter/clutter/clutter.h index 721e30e7e..9dd69c3d3 100644 --- a/clutter/clutter/clutter.h +++ b/clutter/clutter/clutter.h @@ -56,7 +56,6 @@ #include "clutter-content.h" #include "clutter-deform-effect.h" #include "clutter-desaturate-effect.h" -#include "clutter-device-manager.h" #include "clutter-drag-action.h" #include "clutter-drop-action.h" #include "clutter-effect.h" @@ -76,6 +75,7 @@ #include "clutter-input-focus.h" #include "clutter-interval.h" #include "clutter-keyframe-transition.h" +#include "clutter-keymap.h" #include "clutter-keysyms.h" #include "clutter-layout-manager.h" #include "clutter-layout-meta.h" @@ -100,15 +100,13 @@ #include "clutter-snap-constraint.h" #include "clutter-stage.h" #include "clutter-stage-manager.h" +#include "clutter-stage-view.h" #include "clutter-tap-action.h" -#include "clutter-test-utils.h" -#include "clutter-texture.h" #include "clutter-text.h" #include "clutter-timeline.h" #include "clutter-transition-group.h" #include "clutter-transition.h" #include "clutter-units.h" -#include "clutter-version.h" #include "clutter-virtual-input-device.h" #include "clutter-zoom-action.h" diff --git a/clutter/clutter/cogl/clutter-stage-cogl.c b/clutter/clutter/cogl/clutter-stage-cogl.c index 7a9099088..0d99ba4bc 100644 --- a/clutter/clutter/cogl/clutter-stage-cogl.c +++ b/clutter/clutter/cogl/clutter-stage-cogl.c @@ -25,10 +25,7 @@ * Emmanuele Bassi */ - -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #define CLUTTER_ENABLE_EXPERIMENTAL_API @@ -48,7 +45,9 @@ #include "clutter-main.h" #include "clutter-private.h" #include "clutter-stage-private.h" -#include "clutter-muffin.h" +#include "clutter-stage-view-private.h" + +#define MAX_STACK_RECTS 256 typedef struct _ClutterStageViewCoglPrivate { @@ -57,14 +56,15 @@ typedef struct _ClutterStageViewCoglPrivate */ #define DAMAGE_HISTORY_MAX 16 #define DAMAGE_HISTORY(x) ((x) & (DAMAGE_HISTORY_MAX - 1)) - cairo_rectangle_int_t damage_history[DAMAGE_HISTORY_MAX]; + cairo_region_t * damage_history[DAMAGE_HISTORY_MAX]; unsigned int damage_index; } ClutterStageViewCoglPrivate; G_DEFINE_TYPE_WITH_PRIVATE (ClutterStageViewCogl, clutter_stage_view_cogl, CLUTTER_TYPE_STAGE_VIEW) -static void clutter_stage_window_iface_init (ClutterStageWindowIface *iface); +static void +clutter_stage_window_iface_init (ClutterStageWindowInterface *iface); G_DEFINE_TYPE_WITH_CODE (ClutterStageCogl, _clutter_stage_cogl, @@ -72,13 +72,18 @@ G_DEFINE_TYPE_WITH_CODE (ClutterStageCogl, G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_STAGE_WINDOW, clutter_stage_window_iface_init)); -enum { +enum +{ PROP_0, PROP_WRAPPER, PROP_BACKEND, PROP_LAST }; +static void +clutter_stage_cogl_schedule_update (ClutterStageWindow *stage_window, + gint sync_delay); + static void clutter_stage_cogl_unrealize (ClutterStageWindow *stage_window) { @@ -124,6 +129,16 @@ _clutter_stage_cogl_presented (ClutterStageCogl *stage_cogl, } _clutter_stage_presented (stage_cogl->wrapper, frame_event, frame_info); + + if (frame_event == COGL_FRAME_EVENT_COMPLETE && + stage_cogl->update_time != -1) + { + ClutterStageWindow *stage_window = CLUTTER_STAGE_WINDOW (stage_cogl); + + stage_cogl->update_time = -1; + clutter_stage_cogl_schedule_update (stage_window, + stage_cogl->last_sync_delay); + } } static gboolean @@ -152,82 +167,80 @@ clutter_stage_cogl_schedule_update (ClutterStageWindow *stage_window, { ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window); gint64 now; - gint64 target_presentation_time; + float refresh_rate; gint64 refresh_interval; - /* - * want_prerender_frames must be at least 1 (double buffered). - * Feel free to try triple buffering: want_prerender_frames = 2 - * but it's not a good idea to default to that yet because filling all the - * buffers will cause the backend to block and throttle buffer releases even - * to unthrottled clients (swap interval 0). - */ - gint want_prerender_frames = 1; - gint can_prerender_frames; - gint will_prerender_frames; - gint64 prerender_time; + int64_t min_render_time_allowed; + int64_t max_render_time_allowed; + int64_t next_presentation_time; if (stage_cogl->update_time != -1) return; + stage_cogl->last_sync_delay = sync_delay; + now = g_get_monotonic_time (); - if (sync_delay < 0 || - stage_cogl->last_presentation_time <= 0 || - stage_cogl->refresh_rate <= 0.0) + if (sync_delay < 0) { - /* -1 now means that hardware presentation times are unsupported and - * that the caller needs to find a different way to achieve frame - * scheduling. - */ - stage_cogl->update_time = -1; + stage_cogl->update_time = now; return; } - /* FIXME (?) - On X11 this is performing worse than swap throttling. */ + refresh_rate = stage_cogl->refresh_rate; + if (refresh_rate <= 0.0) + refresh_rate = clutter_get_default_frame_rate (); - if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_REGION)) - refresh_interval = (gint64) (0.5 + 1000000 / stage_cogl->refresh_rate); - else - refresh_interval = 0; + refresh_interval = (gint64) (0.5 + G_USEC_PER_SEC / refresh_rate); + if (refresh_interval == 0) + { + stage_cogl->update_time = now; + return; + } - target_presentation_time = stage_cogl->last_presentation_time - + stage_cogl->pending_swaps * refresh_interval - + refresh_interval; + min_render_time_allowed = refresh_interval / 2; + max_render_time_allowed = refresh_interval - 1000 * sync_delay; - if (target_presentation_time < now) + /* Be robust in the case of incredibly bogus refresh rate */ + if (max_render_time_allowed <= 0) { - /* If we missed some frames then find a more current target time that's - * in phase with the display hardware. This is logically equivalent to: - * - * while (target_presentation_time < now) - * target_presentation_time += refresh_interval; - * - * but with a better worst-case execution time... - */ - target_presentation_time = now - - now % refresh_interval - + stage_cogl->last_presentation_time % - refresh_interval; + g_warning ("Unsupported monitor refresh rate detected. " + "(Refresh rate: %.3f, refresh interval: %" G_GINT64_FORMAT ")", + refresh_rate, + refresh_interval); + stage_cogl->update_time = now; + return; + } + + if (min_render_time_allowed > max_render_time_allowed) + min_render_time_allowed = max_render_time_allowed; - if (target_presentation_time < now) - target_presentation_time += refresh_interval; + next_presentation_time = stage_cogl->last_presentation_time + refresh_interval; + + /* Get next_presentation_time closer to its final value, to reduce + * the number of while iterations below. + */ + if (next_presentation_time < now) + { + int64_t last_virtual_presentation_time = now - now % refresh_interval; + int64_t hardware_clock_phase = + stage_cogl->last_presentation_time % refresh_interval; + + next_presentation_time = + last_virtual_presentation_time + hardware_clock_phase; } - can_prerender_frames = MAX (1, stage_cogl->max_buffer_age - 1); - will_prerender_frames = MIN (want_prerender_frames, can_prerender_frames); + while (next_presentation_time < now + min_render_time_allowed) + next_presentation_time += refresh_interval; - prerender_time = will_prerender_frames * refresh_interval - - 1000 * sync_delay; + stage_cogl->update_time = next_presentation_time - max_render_time_allowed; - stage_cogl->update_time = target_presentation_time - prerender_time; + if (stage_cogl->update_time == stage_cogl->last_update_time) + { + stage_cogl->update_time += refresh_interval; + next_presentation_time += refresh_interval; + } - /* Are we repeating ourselves? If a clear and reschedule occur too close - * together while a swap is pending then we will often land on the same - * result as last time. That's not useful because it only suggests to the - * caller to try and render the same frame twice. - */ - if (stage_cogl->update_time <= stage_cogl->last_update_time) - stage_cogl->update_time = stage_cogl->last_update_time + refresh_interval; + stage_cogl->next_presentation_time = next_presentation_time; } static gint64 @@ -235,6 +248,9 @@ clutter_stage_cogl_get_update_time (ClutterStageWindow *stage_window) { ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window); + if (stage_cogl->pending_swaps) + return -1; /* in the future, indefinite */ + return stage_cogl->update_time; } @@ -245,6 +261,29 @@ clutter_stage_cogl_clear_update_time (ClutterStageWindow *stage_window) stage_cogl->last_update_time = stage_cogl->update_time; stage_cogl->update_time = -1; + stage_cogl->next_presentation_time = -1; +} + +static int64_t +clutter_stage_cogl_get_next_presentation_time (ClutterStageWindow *stage_window) +{ + ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window); + int64_t now = g_get_monotonic_time (); + + if (stage_cogl->next_presentation_time > 0 && + stage_cogl->next_presentation_time <= now) + { + CLUTTER_NOTE (BACKEND, + "Missed some frames. Something blocked for over " + "%" G_GINT64_FORMAT "ms.", + (now - stage_cogl->next_presentation_time) / 1000); + + stage_cogl->update_time = -1; + clutter_stage_cogl_schedule_update (stage_window, + stage_cogl->last_sync_delay); + } + + return stage_cogl->next_presentation_time; } static ClutterActor * @@ -277,155 +316,124 @@ clutter_stage_cogl_resize (ClutterStageWindow *stage_window, { } -static gboolean -clutter_stage_cogl_has_redraw_clips (ClutterStageWindow *stage_window) +static inline gboolean +valid_buffer_age (ClutterStageViewCogl *view_cogl, + int age) { - ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window); + ClutterStageViewCoglPrivate *view_priv = + clutter_stage_view_cogl_get_instance_private (view_cogl); - /* NB: at the start of each new frame there is an implied clip that - * clips everything (i.e. nothing would be drawn) so we need to make - * sure we return True in the un-initialized case here. - * - * NB: a clip width of 0 means a full stage redraw has been queued - * so we effectively don't have any redraw clips in that case. - */ - if (!stage_cogl->initialized_redraw_clip || - (stage_cogl->initialized_redraw_clip && - stage_cogl->bounding_redraw_clip.width != 0)) - return TRUE; - else + if (age <= 0) return FALSE; -} -static gboolean -clutter_stage_cogl_ignoring_redraw_clips (ClutterStageWindow *stage_window) -{ - ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window); - - /* NB: a clip width of 0 means a full stage redraw is required */ - if (stage_cogl->initialized_redraw_clip && - stage_cogl->bounding_redraw_clip.width == 0) - return TRUE; - else - return FALSE; + return age < MIN (view_priv->damage_index, DAMAGE_HISTORY_MAX); } -/* A redraw clip represents (in stage coordinates) the bounding box of - * something that needs to be redraw. Typically they are added to the - * StageWindow as a result of clutter_actor_queue_clipped_redraw() by - * actors such as ClutterGLXTexturePixmap. All redraw clips are - * discarded after the next paint. - * - * A NULL stage_clip means the whole stage needs to be redrawn. - * - * What we do with this information: - * - we keep track of the bounding box for all redraw clips - * - when we come to redraw; we scissor the redraw to that box and use - * glBlitFramebuffer to present the redraw to the front - * buffer. - */ static void -clutter_stage_cogl_add_redraw_clip (ClutterStageWindow *stage_window, - cairo_rectangle_int_t *stage_clip) +paint_damage_region (ClutterStageWindow *stage_window, + ClutterStageView *view, + cairo_region_t *swap_region, + cairo_region_t *queued_redraw_clip) { + CoglFramebuffer *framebuffer = clutter_stage_view_get_onscreen (view); + CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); + static CoglPipeline *overlay_blue = NULL; ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window); + ClutterActor *actor = CLUTTER_ACTOR (stage_cogl->wrapper); + CoglMatrix transform; + int n_rects, i; - /* If we are already forced to do a full stage redraw then bail early */ - if (clutter_stage_cogl_ignoring_redraw_clips (stage_window)) - return; + cogl_framebuffer_push_matrix (framebuffer); + clutter_actor_get_transform (actor, &transform); + cogl_framebuffer_transform (framebuffer, &transform); - /* A NULL stage clip means a full stage redraw has been queued and - * we keep track of this by setting a zero width - * stage_cogl->bounding_redraw_clip */ - if (stage_clip == NULL) + /* Blue for the swap region */ + if (G_UNLIKELY (overlay_blue == NULL)) { - stage_cogl->bounding_redraw_clip.width = 0; - stage_cogl->initialized_redraw_clip = TRUE; - return; + overlay_blue = cogl_pipeline_new (ctx); + cogl_pipeline_set_color4ub (overlay_blue, 0x00, 0x00, 0x33, 0x33); } - /* Ignore requests to add degenerate/empty clip rectangles */ - if (stage_clip->width == 0 || stage_clip->height == 0) - return; - - if (!stage_cogl->initialized_redraw_clip) + n_rects = cairo_region_num_rectangles (swap_region); + for (i = 0; i < n_rects; i++) { - stage_cogl->bounding_redraw_clip = *stage_clip; - } - else if (stage_cogl->bounding_redraw_clip.width > 0) - { - _clutter_util_rectangle_union (&stage_cogl->bounding_redraw_clip, - stage_clip, - &stage_cogl->bounding_redraw_clip); - } + cairo_rectangle_int_t rect; + float x_1, x_2, y_1, y_2; - stage_cogl->initialized_redraw_clip = TRUE; -} + cairo_region_get_rectangle (swap_region, i, &rect); + x_1 = rect.x; + x_2 = rect.x + rect.width; + y_1 = rect.y; + y_2 = rect.y + rect.height; -static gboolean -clutter_stage_cogl_get_redraw_clip_bounds (ClutterStageWindow *stage_window, - cairo_rectangle_int_t *stage_clip) -{ - ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window); + cogl_framebuffer_draw_rectangle (framebuffer, overlay_blue, x_1, y_1, x_2, y_2); + } - if (stage_cogl->using_clipped_redraw) + /* Red for the clip */ + if (queued_redraw_clip) { - *stage_clip = stage_cogl->bounding_redraw_clip; + static CoglPipeline *overlay_red = NULL; - return TRUE; - } + if (G_UNLIKELY (overlay_red == NULL)) + { + overlay_red = cogl_pipeline_new (ctx); + cogl_pipeline_set_color4ub (overlay_red, 0x33, 0x00, 0x00, 0x33); + } - return FALSE; -} + n_rects = cairo_region_num_rectangles (queued_redraw_clip); + for (i = 0; i < n_rects; i++) + { + cairo_rectangle_int_t rect; + float x_1, x_2, y_1, y_2; -static inline gboolean -valid_buffer_age (ClutterStageViewCogl *view_cogl, - int age) -{ - ClutterStageViewCoglPrivate *view_priv = - clutter_stage_view_cogl_get_instance_private (view_cogl); + cairo_region_get_rectangle (queued_redraw_clip, i, &rect); + x_1 = rect.x; + x_2 = rect.x + rect.width; + y_1 = rect.y; + y_2 = rect.y + rect.height; - if (age <= 0) - return FALSE; + cogl_framebuffer_draw_rectangle (framebuffer, overlay_red, x_1, y_1, x_2, y_2); + } + } - return age < MIN (view_priv->damage_index, DAMAGE_HISTORY_MAX); + cogl_framebuffer_pop_matrix (framebuffer); } static gboolean -swap_framebuffer (ClutterStageWindow *stage_window, - ClutterStageView *view, - cairo_rectangle_int_t *swap_region, - gboolean swap_with_damage) +swap_framebuffer (ClutterStageWindow *stage_window, + ClutterStageView *view, + cairo_region_t *swap_region, + gboolean swap_with_damage) { CoglFramebuffer *framebuffer = clutter_stage_view_get_onscreen (view); - int damage[4], ndamage; + int *damage, n_rects, i; - damage[0] = swap_region->x; - damage[1] = swap_region->y; - damage[2] = swap_region->width; - damage[3] = swap_region->height; + n_rects = cairo_region_num_rectangles (swap_region); + damage = g_newa (int, n_rects * 4); + for (i = 0; i < n_rects; i++) + { + cairo_rectangle_int_t rect; - if (swap_region->width != 0) - ndamage = 1; - else - ndamage = 0; + cairo_region_get_rectangle (swap_region, i, &rect); + damage[i * 4] = rect.x; + damage[i * 4 + 1] = rect.y; + damage[i * 4 + 2] = rect.width; + damage[i * 4 + 3] = rect.height; + } if (cogl_is_onscreen (framebuffer)) { CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer); /* push on the screen */ - if (ndamage == 1 && !swap_with_damage) + if (n_rects > 0 && !swap_with_damage) { CLUTTER_NOTE (BACKEND, - "cogl_onscreen_swap_region (onscreen: %p, " - "x: %d, y: %d, " - "width: %d, height: %d)", - onscreen, - damage[0], damage[1], damage[2], damage[3]); + "cogl_onscreen_swap_region (onscreen: %p)", + onscreen); cogl_onscreen_swap_region (onscreen, - damage, ndamage); + damage, n_rects); return FALSE; } @@ -435,7 +443,7 @@ swap_framebuffer (ClutterStageWindow *stage_window, onscreen); cogl_onscreen_swap_buffers_with_damage (onscreen, - damage, ndamage); + damage, n_rects); return TRUE; } @@ -451,80 +459,139 @@ swap_framebuffer (ClutterStageWindow *stage_window, } static void -paint_stage (ClutterStageCogl *stage_cogl, - ClutterStageView *view, - const cairo_rectangle_int_t *clip) +scale_and_clamp_rect (const graphene_rect_t *rect, + float scale, + cairo_rectangle_int_t *dest) + { - ClutterStage *stage = stage_cogl->wrapper; + graphene_rect_t tmp = *rect; - _clutter_stage_maybe_setup_viewport (stage, view); - _clutter_stage_paint_view (stage, view, clip); + graphene_rect_scale (&tmp, scale, scale, &tmp); + _clutter_util_rectangle_int_extents (&tmp, dest); +} - if (clutter_stage_view_get_onscreen (view) != - clutter_stage_view_get_framebuffer (view)) +static cairo_region_t * +offset_scale_and_clamp_region (const cairo_region_t *region, + int offset_x, + int offset_y, + float scale) +{ + int n_rects, i; + cairo_rectangle_int_t *rects; + g_autofree cairo_rectangle_int_t *freeme = NULL; + + n_rects = cairo_region_num_rectangles (region); + + if (n_rects == 0) + return cairo_region_create (); + + if (n_rects < MAX_STACK_RECTS) + rects = g_newa (cairo_rectangle_int_t, n_rects); + else + rects = freeme = g_new (cairo_rectangle_int_t, n_rects); + + for (i = 0; i < n_rects; i++) + cairo_region_get_rectangle (region, i, &rects[i]); + + for (i = 0; i < n_rects; i++) { - clutter_stage_view_blit_offscreen (view, clip); + graphene_rect_t tmp; + + _clutter_util_rect_from_rectangle (&rects[i], &tmp); + graphene_rect_offset (&tmp, offset_x, offset_y); + scale_and_clamp_rect (&tmp, scale, &rects[i]); } + + return cairo_region_create_rectangles (rects, n_rects); } static void -fill_current_damage_history_and_step (ClutterStageView *view) +paint_stage (ClutterStageCogl *stage_cogl, + ClutterStageView *view, + cairo_region_t *redraw_clip) +{ + ClutterStage *stage = stage_cogl->wrapper; + + _clutter_stage_maybe_setup_viewport (stage, view); + clutter_stage_paint_view (stage, view, redraw_clip); + + clutter_stage_view_after_paint (view); +} + +static void +fill_current_damage_history (ClutterStageView *view, + cairo_region_t *damage) { ClutterStageViewCogl *view_cogl = CLUTTER_STAGE_VIEW_COGL (view); ClutterStageViewCoglPrivate *view_priv = clutter_stage_view_cogl_get_instance_private (view_cogl); - cairo_rectangle_int_t view_rect; - float fb_scale; - cairo_rectangle_int_t *current_fb_damage; + cairo_region_t **current_fb_damage; current_fb_damage = &view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index)]; - clutter_stage_view_get_layout (view, &view_rect); - fb_scale = clutter_stage_view_get_scale (view); - *current_fb_damage = (cairo_rectangle_int_t) { - .x = 0, - .y = 0, - .width = view_rect.width * fb_scale, - .height = view_rect.height * fb_scale - }; + g_clear_pointer (current_fb_damage, cairo_region_destroy); + *current_fb_damage = cairo_region_copy (damage); view_priv->damage_index++; } static void -transform_swap_region_to_onscreen (ClutterStageView *view, - cairo_rectangle_int_t *swap_region) +fill_current_damage_history_rectangle (ClutterStageView *view, + const cairo_rectangle_int_t *rect) +{ + cairo_region_t *damage; + + damage = cairo_region_create_rectangle (rect); + fill_current_damage_history (view, damage); + cairo_region_destroy (damage); +} + +static cairo_region_t * +transform_swap_region_to_onscreen (ClutterStageView *view, + cairo_region_t *swap_region) { CoglFramebuffer *framebuffer; cairo_rectangle_int_t layout; - gfloat x1, y1, x2, y2; gint width, height; + int n_rects, i; + cairo_rectangle_int_t *rects; + cairo_region_t *transformed_region; framebuffer = clutter_stage_view_get_onscreen (view); clutter_stage_view_get_layout (view, &layout); - x1 = (float) swap_region->x / layout.width; - y1 = (float) swap_region->y / layout.height; - x2 = (float) (swap_region->x + swap_region->width) / layout.width; - y2 = (float) (swap_region->y + swap_region->height) / layout.height; - - clutter_stage_view_transform_to_onscreen (view, &x1, &y1); - clutter_stage_view_transform_to_onscreen (view, &x2, &y2); - width = cogl_framebuffer_get_width (framebuffer); height = cogl_framebuffer_get_height (framebuffer); - x1 = floor (x1 * width); - y1 = floor (height - (y1 * height)); - x2 = ceil (x2 * width); - y2 = ceil (height - (y2 * height)); - - *swap_region = (cairo_rectangle_int_t) { - .x = x1, - .y = y1, - .width = x2 - x1, - .height = y2 - y1 - }; + n_rects = cairo_region_num_rectangles (swap_region); + rects = g_newa (cairo_rectangle_int_t, n_rects); + for (i = 0; i < n_rects; i++) + { + gfloat x1, y1, x2, y2; + + cairo_region_get_rectangle (swap_region, i, &rects[i]); + + x1 = (float) rects[i].x / layout.width; + y1 = (float) rects[i].y / layout.height; + x2 = (float) (rects[i].x + rects[i].width) / layout.width; + y2 = (float) (rects[i].y + rects[i].height) / layout.height; + + clutter_stage_view_transform_to_onscreen (view, &x1, &y1); + clutter_stage_view_transform_to_onscreen (view, &x2, &y2); + + x1 = floor (x1 * width); + y1 = floor (height - (y1 * height)); + x2 = ceil (x2 * width); + y2 = ceil (height - (y2 * height)); + + rects[i].x = x1; + rects[i].y = y1; + rects[i].width = x2 - x1; + rects[i].height = y2 - y1; + } + transformed_region = cairo_region_create_rectangles (rects, n_rects); + + return transformed_region; } static void @@ -534,31 +601,28 @@ calculate_scissor_region (cairo_rectangle_int_t *fb_clip_region, int fb_height, cairo_rectangle_int_t *out_scissor_rect) { - int scissor_x; - int scissor_y; - int scissor_width; - int scissor_height; + *out_scissor_rect = *fb_clip_region; - scissor_x = fb_clip_region->x; - scissor_y = fb_clip_region->y; - scissor_width = fb_clip_region->width; - scissor_height = fb_clip_region->height; + if (subpixel_compensation == 0) + return; if (fb_clip_region->x > 0) - scissor_x += subpixel_compensation; + out_scissor_rect->x += subpixel_compensation; if (fb_clip_region->y > 0) - scissor_y += subpixel_compensation; + out_scissor_rect->y += subpixel_compensation; if (fb_clip_region->x + fb_clip_region->width < fb_width) - scissor_width -= 2 * subpixel_compensation; + out_scissor_rect->width -= 2 * subpixel_compensation; if (fb_clip_region->y + fb_clip_region->height < fb_height) - scissor_height -= 2 * subpixel_compensation; - - *out_scissor_rect = (cairo_rectangle_int_t) { - .x = scissor_x, - .y = scissor_y, - .width = scissor_width, - .height = scissor_height - }; + out_scissor_rect->height -= 2 * subpixel_compensation; +} + +static inline gboolean +is_buffer_age_enabled (void) +{ + /* Buffer age is disabled when running with CLUTTER_PAINT=damage-region, + * to ensure the red damage represents the currently damaged area */ + return !(clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DAMAGE_REGION) && + cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_BUFFER_AGE); } static gboolean @@ -571,7 +635,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window, clutter_stage_view_cogl_get_instance_private (view_cogl); CoglFramebuffer *fb = clutter_stage_view_get_framebuffer (view); cairo_rectangle_int_t view_rect; - gboolean have_clip; + gboolean is_full_redraw; gboolean may_use_clipped_redraw; gboolean use_clipped_redraw; gboolean can_blit_sub_buffer; @@ -579,13 +643,16 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window, gboolean do_swap_buffer; gboolean swap_with_damage; ClutterActor *wrapper; - cairo_rectangle_int_t redraw_clip; - cairo_rectangle_int_t swap_region; - cairo_rectangle_int_t fb_clip_region; + cairo_region_t *redraw_clip; + cairo_region_t *queued_redraw_clip = NULL; + cairo_region_t *fb_clip_region; + cairo_region_t *swap_region; + cairo_rectangle_int_t redraw_rect; gboolean clip_region_empty; float fb_scale; int subpixel_compensation = 0; int fb_width, fb_height; + int buffer_age; wrapper = CLUTTER_ACTOR (stage_cogl->wrapper); @@ -598,53 +665,76 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window, cogl_is_onscreen (fb) && cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_REGION); - has_buffer_age = - cogl_is_onscreen (fb) && - cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_BUFFER_AGE); + has_buffer_age = cogl_is_onscreen (fb) && is_buffer_age_enabled (); + + redraw_clip = clutter_stage_view_take_redraw_clip (view); + if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DAMAGE_REGION)) + queued_redraw_clip = cairo_region_copy (redraw_clip); - /* NB: a zero width redraw clip == full stage redraw */ - if (stage_cogl->bounding_redraw_clip.width == 0) - have_clip = FALSE; + /* NB: a NULL redraw clip == full stage redraw */ + if (!redraw_clip) + is_full_redraw = TRUE; else + is_full_redraw = FALSE; + + may_use_clipped_redraw = + _clutter_stage_window_can_clip_redraws (stage_window) && + (can_blit_sub_buffer || has_buffer_age) && + !is_full_redraw && + /* some drivers struggle to get going and produce some junk + * frames when starting up... */ + cogl_onscreen_get_frame_counter (COGL_ONSCREEN (fb)) > 3; + + if (has_buffer_age) { - redraw_clip = stage_cogl->bounding_redraw_clip; - _clutter_util_rectangle_intersection (&redraw_clip, - &view_rect, - &redraw_clip); - - have_clip = !(redraw_clip.x == view_rect.x && - redraw_clip.y == view_rect.y && - redraw_clip.width == view_rect.width && - redraw_clip.height == view_rect.height); + buffer_age = cogl_onscreen_get_buffer_age (COGL_ONSCREEN (fb)); + if (!valid_buffer_age (view_cogl, buffer_age)) + { + CLUTTER_NOTE (CLIPPING, "Invalid back buffer(age=%d): forcing full redraw\n", buffer_age); + may_use_clipped_redraw = FALSE; + } } - may_use_clipped_redraw = FALSE; - if (_clutter_stage_window_can_clip_redraws (stage_window) && - (can_blit_sub_buffer || has_buffer_age) && - have_clip && - /* some drivers struggle to get going and produce some junk - * frames when starting up... */ - cogl_onscreen_get_frame_counter (COGL_ONSCREEN (fb)) > 3) + if (may_use_clipped_redraw) { - may_use_clipped_redraw = TRUE; + fb_clip_region = offset_scale_and_clamp_region (redraw_clip, + -view_rect.x, + -view_rect.y, + fb_scale); if (fb_scale != floorf (fb_scale)) - subpixel_compensation = ceilf (fb_scale); - - fb_clip_region = (cairo_rectangle_int_t) { - .x = (floorf ((redraw_clip.x - view_rect.x) * fb_scale) - - subpixel_compensation), - .y = (floorf ((redraw_clip.y - view_rect.y) * fb_scale) - - subpixel_compensation), - .width = (ceilf (redraw_clip.width * fb_scale) + - (2 * subpixel_compensation)), - .height = (ceilf (redraw_clip.height * fb_scale) + - (2 * subpixel_compensation)) - }; + { + int n_rects, i; + cairo_rectangle_int_t *rects; + + subpixel_compensation = ceilf (fb_scale); + + n_rects = cairo_region_num_rectangles (fb_clip_region); + rects = g_newa (cairo_rectangle_int_t, n_rects); + for (i = 0; i < n_rects; i++) + { + cairo_region_get_rectangle (fb_clip_region, i, &rects[i]); + rects[i].x -= subpixel_compensation; + rects[i].y -= subpixel_compensation; + rects[i].width += 2 * subpixel_compensation; + rects[i].height += 2 * subpixel_compensation; + } + cairo_region_destroy (fb_clip_region); + fb_clip_region = cairo_region_create_rectangles (rects, n_rects); + } } else { - fb_clip_region = (cairo_rectangle_int_t) { 0 }; + cairo_rectangle_int_t fb_rect; + + fb_rect = (cairo_rectangle_int_t) { + .width = fb_width, + .height = fb_height, + }; + fb_clip_region = cairo_region_create_rectangle (&fb_rect); + + g_clear_pointer (&redraw_clip, cairo_region_destroy); + redraw_clip = cairo_region_create_rectangle (&view_rect); } if (may_use_clipped_redraw && @@ -653,128 +743,121 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window, else use_clipped_redraw = FALSE; - clip_region_empty = may_use_clipped_redraw && fb_clip_region.width == 0; + clip_region_empty = may_use_clipped_redraw && cairo_region_is_empty (fb_clip_region); swap_with_damage = FALSE; if (has_buffer_age) { if (use_clipped_redraw && !clip_region_empty) { - int age, i; - cairo_rectangle_int_t *current_fb_damage = - &view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index++)]; + cairo_region_t *fb_damage; + cairo_region_t *view_damage; + int i; - age = cogl_onscreen_get_buffer_age (COGL_ONSCREEN (fb)); + fill_current_damage_history (view, fb_clip_region); - if (valid_buffer_age (view_cogl, age)) - { - cairo_rectangle_int_t damage_region; - - if (age > stage_cogl->max_buffer_age) - stage_cogl->max_buffer_age = age; - - *current_fb_damage = fb_clip_region; - - for (i = 1; i <= age; i++) - { - cairo_rectangle_int_t *fb_damage = - &view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index - i - 1)]; - - _clutter_util_rectangle_union (&fb_clip_region, - fb_damage, - &fb_clip_region); - } - - /* Update the bounding redraw clip state with the extra damage. */ - damage_region = (cairo_rectangle_int_t) { - .x = view_rect.x + floorf (fb_clip_region.x / fb_scale), - .y = view_rect.y + floorf (fb_clip_region.y / fb_scale), - .width = ceilf (fb_clip_region.width / fb_scale), - .height = ceilf (fb_clip_region.height / fb_scale) - }; - _clutter_util_rectangle_union (&stage_cogl->bounding_redraw_clip, - &damage_region, - &stage_cogl->bounding_redraw_clip); - - CLUTTER_NOTE (CLIPPING, "Reusing back buffer(age=%d) - repairing region: x=%d, y=%d, width=%d, height=%d\n", - age, - fb_clip_region.x, - fb_clip_region.y, - fb_clip_region.width, - fb_clip_region.height); - - swap_with_damage = TRUE; - } - else + fb_damage = cairo_region_create (); + + for (i = 1; i <= buffer_age; i++) { - CLUTTER_NOTE (CLIPPING, "Invalid back buffer(age=%d): forcing full redraw\n", age); - use_clipped_redraw = FALSE; - *current_fb_damage = (cairo_rectangle_int_t) { - .x = 0, - .y = 0, - .width = view_rect.width * fb_scale, - .height = view_rect.height * fb_scale - }; + int damage_index; + + damage_index = DAMAGE_HISTORY (view_priv->damage_index - i - 1); + cairo_region_union (fb_damage, + view_priv->damage_history[damage_index]); } + + /* Update the fb clip region with the extra damage. */ + cairo_region_union (fb_clip_region, fb_damage); + + view_damage = offset_scale_and_clamp_region (fb_damage, + 0, 0, + 1.0f / fb_scale); + cairo_region_translate (view_damage, view_rect.x, view_rect.y); + cairo_region_intersect_rectangle (view_damage, &view_rect); + + /* Update the redraw clip region with the extra damage. */ + cairo_region_union (redraw_clip, view_damage); + + cairo_region_destroy (view_damage); + cairo_region_destroy (fb_damage); + + CLUTTER_NOTE (CLIPPING, "Reusing back buffer(age=%d) - repairing region: num rects: %d\n", + buffer_age, + cairo_region_num_rectangles (fb_clip_region)); + + swap_with_damage = TRUE; } else if (!use_clipped_redraw) { - fill_current_damage_history_and_step (view); + cairo_rectangle_int_t fb_damage; + + fb_damage = (cairo_rectangle_int_t) { + .x = 0, + .y = 0, + .width = ceilf (view_rect.width * fb_scale), + .height = ceilf (view_rect.height * fb_scale) + }; + fill_current_damage_history_rectangle (view, &fb_damage); } } - cogl_push_framebuffer (fb); if (use_clipped_redraw && clip_region_empty) { CLUTTER_NOTE (CLIPPING, "Empty stage output paint\n"); } else if (use_clipped_redraw) { + cairo_rectangle_int_t clip_rect; cairo_rectangle_int_t scissor_rect; - calculate_scissor_region (&fb_clip_region, - subpixel_compensation, - fb_width, fb_height, - &scissor_rect); - - CLUTTER_NOTE (CLIPPING, - "Stage clip pushed: x=%d, y=%d, width=%d, height=%d\n", - scissor_rect.x, - scissor_rect.y, - scissor_rect.width, - scissor_rect.height); - - stage_cogl->using_clipped_redraw = TRUE; - - cogl_framebuffer_push_scissor_clip (fb, - scissor_rect.x, - scissor_rect.y, - scissor_rect.width, - scissor_rect.height); - paint_stage (stage_cogl, view, - &(cairo_rectangle_int_t) { - .x = view_rect.x + floorf ((fb_clip_region.x - 0) / fb_scale), - .y = view_rect.y + floorf ((fb_clip_region.y - 0) / fb_scale), - .width = ceilf ((fb_clip_region.width + 0) / fb_scale), - .height = ceilf ((fb_clip_region.height + 0) / fb_scale) - }); - cogl_framebuffer_pop_clip (fb); + if (cairo_region_num_rectangles (fb_clip_region) == 1) + { + cairo_region_get_extents (fb_clip_region, &clip_rect); + + calculate_scissor_region (&clip_rect, + subpixel_compensation, + fb_width, fb_height, + &scissor_rect); + + CLUTTER_NOTE (CLIPPING, + "Stage clip pushed: x=%d, y=%d, width=%d, height=%d\n", + scissor_rect.x, + scissor_rect.y, + scissor_rect.width, + scissor_rect.height); - stage_cogl->using_clipped_redraw = FALSE; + cogl_framebuffer_push_scissor_clip (fb, + scissor_rect.x, + scissor_rect.y, + scissor_rect.width, + scissor_rect.height); + } + else + { + cogl_framebuffer_push_region_clip (fb, fb_clip_region); + } + + paint_stage (stage_cogl, view, redraw_clip); + + cogl_framebuffer_pop_clip (fb); } else { CLUTTER_NOTE (CLIPPING, "Unclipped stage paint\n"); /* If we are trying to debug redraw issues then we want to pass - * the bounding_redraw_clip so it can be visualized */ + * the redraw_clip so it can be visualized */ if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS) && may_use_clipped_redraw && !clip_region_empty) { + cairo_rectangle_int_t clip_rect; cairo_rectangle_int_t scissor_rect; - calculate_scissor_region (&fb_clip_region, + cairo_region_get_extents (fb_clip_region, &clip_rect); + + calculate_scissor_region (&clip_rect, subpixel_compensation, fb_width, fb_height, &scissor_rect); @@ -784,19 +867,18 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window, scissor_rect.y, scissor_rect.width, scissor_rect.height); - paint_stage (stage_cogl, view, - &(cairo_rectangle_int_t) { - .x = view_rect.x + floorf (fb_clip_region.x / fb_scale), - .y = view_rect.y + floorf (fb_clip_region.y / fb_scale), - .width = ceilf (fb_clip_region.width / fb_scale), - .height = ceilf (fb_clip_region.height / fb_scale) - }); + + paint_stage (stage_cogl, view, redraw_clip); + cogl_framebuffer_pop_clip (fb); } else - paint_stage (stage_cogl, view, &view_rect); + { + paint_stage (stage_cogl, view, redraw_clip); + } } - cogl_pop_framebuffer (); + + cairo_region_get_extents (redraw_clip, &redraw_rect); if (may_use_clipped_redraw && G_UNLIKELY ((clutter_paint_debug_flags & CLUTTER_DEBUG_REDRAWS))) @@ -804,10 +886,10 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window, CoglContext *ctx = cogl_framebuffer_get_context (fb); static CoglPipeline *outline = NULL; ClutterActor *actor = CLUTTER_ACTOR (wrapper); - float x_1 = redraw_clip.x; - float x_2 = redraw_clip.x + redraw_clip.width; - float y_1 = redraw_clip.y; - float y_2 = redraw_clip.y + redraw_clip.height; + float x_1 = redraw_rect.x; + float x_2 = redraw_rect.x + redraw_rect.width; + float y_1 = redraw_rect.y; + float y_2 = redraw_rect.y + redraw_rect.height; CoglVertexP2 quad[4] = { { x_1, y_1 }, { x_2, y_1 }, @@ -847,48 +929,62 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window, */ if (use_clipped_redraw) { - if (use_clipped_redraw && clip_region_empty) + if (clip_region_empty) { do_swap_buffer = FALSE; } - else if (use_clipped_redraw) - { - swap_region = fb_clip_region; - g_assert (swap_region.width > 0); - do_swap_buffer = TRUE; - } else { - swap_region = (cairo_rectangle_int_t) { - .x = 0, - .y = 0, - .width = view_rect.width * fb_scale, - .height = view_rect.height * fb_scale, - }; + swap_region = cairo_region_reference (fb_clip_region); do_swap_buffer = TRUE; } } else { - swap_region = (cairo_rectangle_int_t) { 0 }; + swap_region = cairo_region_create (); do_swap_buffer = TRUE; } + g_clear_pointer (&redraw_clip, cairo_region_destroy); + g_clear_pointer (&fb_clip_region, cairo_region_destroy); + if (do_swap_buffer) { + gboolean res; + + COGL_TRACE_BEGIN_SCOPED (ClutterStageCoglRedrawViewSwapFramebuffer, + "Paint (swap framebuffer)"); + if (clutter_stage_view_get_onscreen (view) != clutter_stage_view_get_framebuffer (view)) { - transform_swap_region_to_onscreen (view, &swap_region); + cairo_region_t *transformed_swap_region; + + transformed_swap_region = + transform_swap_region_to_onscreen (view, swap_region); + cairo_region_destroy (swap_region); + swap_region = transformed_swap_region; + } + + if (queued_redraw_clip) + { + paint_damage_region (stage_window, view, + swap_region, queued_redraw_clip); + cairo_region_destroy (queued_redraw_clip); } - return swap_framebuffer (stage_window, - view, - &swap_region, - swap_with_damage); + res = swap_framebuffer (stage_window, + view, + swap_region, + swap_with_damage); + + cairo_region_destroy (swap_region); + + return res; } else { + g_clear_pointer (&queued_redraw_clip, cairo_region_destroy); return FALSE; } } @@ -900,14 +996,20 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window) gboolean swap_event = FALSE; GList *l; + COGL_TRACE_BEGIN (ClutterStageCoglRedraw, "Paint (Cogl Redraw)"); + for (l = _clutter_stage_window_get_views (stage_window); l; l = l->next) { ClutterStageView *view = l->data; - swap_event = - clutter_stage_cogl_redraw_view (stage_window, view) || swap_event; + if (!clutter_stage_view_has_redraw_clip (view)) + continue; + + swap_event |= clutter_stage_cogl_redraw_view (stage_window, view); } + _clutter_stage_emit_after_paint (stage_cogl->wrapper); + _clutter_stage_window_finish_frame (stage_window); if (swap_event) @@ -919,60 +1021,13 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window) stage_cogl->pending_swaps++; } - /* reset the redraw clipping for the next paint... */ - stage_cogl->initialized_redraw_clip = FALSE; - stage_cogl->frame_count++; -} -static void -clutter_stage_cogl_get_dirty_pixel (ClutterStageWindow *stage_window, - ClutterStageView *view, - int *x, - int *y) -{ - CoglFramebuffer *framebuffer = clutter_stage_view_get_framebuffer (view); - gboolean has_buffer_age = - cogl_is_onscreen (framebuffer) && - cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_BUFFER_AGE); - float fb_scale; - gboolean scale_is_fractional; - - fb_scale = clutter_stage_view_get_scale (view); - if (fb_scale != floorf (fb_scale)) - scale_is_fractional = TRUE; - else - scale_is_fractional = FALSE; - - /* - * Buffer damage is tracked in the framebuffer coordinate space - * using the damage history. When fractional scaling is used, a - * coordinate on the stage might not correspond to the exact position of any - * physical pixel, which causes issues when painting using the pick mode. - * - * For now, always use the (0, 0) pixel for picking when using fractional - * framebuffer scaling. - */ - if (!has_buffer_age || scale_is_fractional) - { - *x = 0; - *y = 0; - } - else - { - ClutterStageViewCogl *view_cogl = CLUTTER_STAGE_VIEW_COGL (view); - ClutterStageViewCoglPrivate *view_priv = - clutter_stage_view_cogl_get_instance_private (view_cogl); - cairo_rectangle_int_t *fb_damage; - - fb_damage = &view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index - 1)]; - *x = fb_damage->x / fb_scale; - *y = fb_damage->y / fb_scale; - } + COGL_TRACE_END (ClutterStageCoglRedraw); } static void -clutter_stage_window_iface_init (ClutterStageWindowIface *iface) +clutter_stage_window_iface_init (ClutterStageWindowInterface *iface) { iface->realize = clutter_stage_cogl_realize; iface->unrealize = clutter_stage_cogl_unrealize; @@ -983,12 +1038,8 @@ clutter_stage_window_iface_init (ClutterStageWindowIface *iface) iface->schedule_update = clutter_stage_cogl_schedule_update; iface->get_update_time = clutter_stage_cogl_get_update_time; iface->clear_update_time = clutter_stage_cogl_clear_update_time; - iface->add_redraw_clip = clutter_stage_cogl_add_redraw_clip; - iface->has_redraw_clips = clutter_stage_cogl_has_redraw_clips; - iface->ignoring_redraw_clips = clutter_stage_cogl_ignoring_redraw_clips; - iface->get_redraw_clip_bounds = clutter_stage_cogl_get_redraw_clip_bounds; + iface->get_next_presentation_time = clutter_stage_cogl_get_next_presentation_time; iface->redraw = clutter_stage_cogl_redraw; - iface->get_dirty_pixel = clutter_stage_cogl_get_dirty_pixel; } static void @@ -1033,6 +1084,7 @@ _clutter_stage_cogl_init (ClutterStageCogl *stage) stage->refresh_rate = 0.0; stage->update_time = -1; + stage->next_presentation_time = -1; } static void diff --git a/clutter/clutter/cogl/clutter-stage-cogl.h b/clutter/clutter/cogl/clutter-stage-cogl.h index 44f53715a..634f856d4 100644 --- a/clutter/clutter/cogl/clutter-stage-cogl.h +++ b/clutter/clutter/cogl/clutter-stage-cogl.h @@ -5,12 +5,6 @@ #include #include -#ifdef COGL_HAS_X11_SUPPORT -#include -#include -#include -#endif - #include "clutter/clutter-stage-window.h" G_BEGIN_DECLS @@ -28,7 +22,7 @@ typedef struct _ClutterStageCoglClass ClutterStageCoglClass; G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterStageCogl, g_object_unref) #define CLUTTER_TYPE_STAGE_VIEW_COGL (clutter_stage_view_cogl_get_type ()) -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT G_DECLARE_DERIVABLE_TYPE (ClutterStageViewCogl, clutter_stage_view_cogl, CLUTTER, STAGE_VIEW_COGL, ClutterStageView) @@ -50,24 +44,18 @@ struct _ClutterStageCogl float refresh_rate; int pending_swaps; - int max_buffer_age; - gint64 last_update_time; gint64 last_presentation_time; gint64 update_time; + int64_t last_update_time; + int64_t next_presentation_time; /* We only enable clipped redraws after 2 frames, since we've seen * a lot of drivers can struggle to get going and may output some * junk frames to start with. */ unsigned int frame_count; - cairo_rectangle_int_t bounding_redraw_clip; - - guint initialized_redraw_clip : 1; - - /* TRUE if the current paint cycle has a clipped redraw. In that - case bounding_redraw_clip specifies the the bounds. */ - guint using_clipped_redraw : 1; + gint last_sync_delay; }; struct _ClutterStageCoglClass @@ -75,10 +63,10 @@ struct _ClutterStageCoglClass GObjectClass parent_class; }; -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT GType _clutter_stage_cogl_get_type (void) G_GNUC_CONST; -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT void _clutter_stage_cogl_presented (ClutterStageCogl *stage_cogl, CoglFrameEvent frame_event, ClutterFrameInfo *frame_info); diff --git a/clutter/clutter/deprecated/clutter-actor-deprecated.c b/clutter/clutter/deprecated/clutter-actor-deprecated.c deleted file mode 100644 index 8729d8d58..000000000 --- a/clutter/clutter/deprecated/clutter-actor-deprecated.c +++ /dev/null @@ -1,411 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include "clutter-build-config.h" -#endif - -#include - -#define CLUTTER_DISABLE_DEPRECATION_WARNINGS -#include "deprecated/clutter-actor.h" - -#include "clutter-actor-private.h" -#include "clutter-private.h" -#include "clutter-shader.h" - -typedef struct _ShaderData ShaderData; - -struct _ShaderData -{ - ClutterShader *shader; - - /* back pointer to the actor */ - ClutterActor *actor; - - /* list of values that should be set on the shader - * before each paint cycle - */ - GHashTable *value_hash; -}; - -static void -shader_value_free (gpointer data) -{ - GValue *var = data; - g_value_unset (var); - g_slice_free (GValue, var); -} - -static void -destroy_shader_data (gpointer data) -{ - ShaderData *shader_data = data; - - if (shader_data == NULL) - return; - - if (shader_data->shader != NULL) - { - g_object_unref (shader_data->shader); - shader_data->shader = NULL; - } - - if (shader_data->value_hash != NULL) - { - g_hash_table_destroy (shader_data->value_hash); - shader_data->value_hash = NULL; - } - - g_slice_free (ShaderData, shader_data); -} - -/** - * clutter_actor_get_shader: - * @self: a #ClutterActor - * - * Queries the currently set #ClutterShader on @self. - * - * Return value: (transfer none): The currently set #ClutterShader - * or %NULL if no shader is set. - * - * Since: 0.6 - * - * Deprecated: 1.8: Use clutter_actor_get_effect() instead. - */ -ClutterShader * -clutter_actor_get_shader (ClutterActor *self) -{ - ShaderData *shader_data; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL); - - shader_data = g_object_get_data (G_OBJECT (self), "-clutter-actor-shader-data"); - if (shader_data != NULL) - return shader_data->shader; - - return NULL; -} - -/** - * clutter_actor_set_shader: - * @self: a #ClutterActor - * @shader: (allow-none): a #ClutterShader or %NULL to unset the shader. - * - * Sets the #ClutterShader to be used when rendering @self. - * - * If @shader is %NULL this function will unset any currently set shader - * for the actor. - * - * Any #ClutterEffect applied to @self will take the precedence - * over the #ClutterShader set using this function. - * - * Return value: %TRUE if the shader was successfully applied - * or removed - * - * Since: 0.6 - * - * Deprecated: 1.8: Use #ClutterShaderEffect and - * clutter_actor_add_effect() instead. - */ -gboolean -clutter_actor_set_shader (ClutterActor *self, - ClutterShader *shader) -{ - ShaderData *shader_data; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); - g_return_val_if_fail (shader == NULL || CLUTTER_IS_SHADER (shader), FALSE); - - if (shader != NULL) - g_object_ref (shader); - else - { - /* if shader passed in is NULL we destroy the shader */ - g_object_set_data (G_OBJECT (self), "-clutter-actor-shader-data", NULL); - return TRUE; - } - - shader_data = g_object_get_data (G_OBJECT (self), "-clutter-actor-shader-data"); - if (shader_data == NULL) - { - shader_data = g_slice_new (ShaderData); - shader_data->actor = self; - shader_data->shader = NULL; - shader_data->value_hash = - g_hash_table_new_full (g_str_hash, g_str_equal, - free, - shader_value_free); - - g_object_set_data_full (G_OBJECT (self), "-clutter-actor-shader-data", - shader_data, - destroy_shader_data); - } - - if (shader_data->shader != NULL) - g_object_unref (shader_data->shader); - - shader_data->shader = shader; - - clutter_actor_queue_redraw (self); - - return TRUE; -} - -static void -set_each_param (gpointer key, - gpointer value, - gpointer user_data) -{ - ClutterShader *shader = user_data; - const gchar *uniform = key; - GValue *var = value; - - clutter_shader_set_uniform (shader, uniform, var); -} - -void -_clutter_actor_shader_pre_paint (ClutterActor *actor, - gboolean repeat) -{ - ShaderData *shader_data; - ClutterShader *shader; - - shader_data = g_object_get_data (G_OBJECT (actor), "-clutter-actor-shader-data"); - if (shader_data == NULL) - return; - - shader = shader_data->shader; - if (shader != NULL) - { - clutter_shader_set_is_enabled (shader, TRUE); - - g_hash_table_foreach (shader_data->value_hash, set_each_param, shader); - - if (!repeat) - _clutter_context_push_shader_stack (actor); - } -} - -void -_clutter_actor_shader_post_paint (ClutterActor *actor) -{ - ShaderData *shader_data; - ClutterShader *shader; - - shader_data = g_object_get_data (G_OBJECT (actor), "-clutter-actor-shader-data"); - if (G_LIKELY (shader_data == NULL)) - return; - - shader = shader_data->shader; - if (shader != NULL) - { - ClutterActor *head; - - clutter_shader_set_is_enabled (shader, FALSE); - - /* remove the actor from the shaders stack; if there is another - * actor inside it, then call pre-paint again to set its shader - * but this time with the second argument being TRUE, indicating - * that we are re-applying an existing shader and thus should it - * not be prepended to the stack - */ - head = _clutter_context_pop_shader_stack (actor); - if (head != NULL) - _clutter_actor_shader_pre_paint (head, TRUE); - } -} - -static inline void -clutter_actor_set_shader_param_internal (ClutterActor *self, - const gchar *param, - const GValue *value) -{ - ShaderData *shader_data; - GValue *var; - - shader_data = g_object_get_data (G_OBJECT (self), "-clutter-actor-shader-data"); - if (shader_data == NULL) - return; - - var = g_slice_new0 (GValue); - g_value_init (var, G_VALUE_TYPE (value)); - g_value_copy (value, var); - g_hash_table_insert (shader_data->value_hash, g_strdup (param), var); - - clutter_actor_queue_redraw (self); -} - -/** - * clutter_actor_set_shader_param: - * @self: a #ClutterActor - * @param: the name of the parameter - * @value: the value of the parameter - * - * Sets the value for a named parameter of the shader applied - * to @actor. - * - * Since: 1.0 - * - * Deprecated: 1.8: Use clutter_shader_effect_set_uniform_value() instead - */ -void -clutter_actor_set_shader_param (ClutterActor *self, - const gchar *param, - const GValue *value) -{ - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (param != NULL); - g_return_if_fail (CLUTTER_VALUE_HOLDS_SHADER_FLOAT (value) || - CLUTTER_VALUE_HOLDS_SHADER_INT (value) || - CLUTTER_VALUE_HOLDS_SHADER_MATRIX (value) || - G_VALUE_HOLDS_FLOAT (value) || - G_VALUE_HOLDS_INT (value)); - - clutter_actor_set_shader_param_internal (self, param, value); -} - -/** - * clutter_actor_set_shader_param_float: - * @self: a #ClutterActor - * @param: the name of the parameter - * @value: the value of the parameter - * - * Sets the value for a named float parameter of the shader applied - * to @actor. - * - * Since: 0.8 - * - * Deprecated: 1.8: Use clutter_shader_effect_set_uniform() instead - */ -void -clutter_actor_set_shader_param_float (ClutterActor *self, - const gchar *param, - gfloat value) -{ - GValue var = { 0, }; - - g_value_init (&var, G_TYPE_FLOAT); - g_value_set_float (&var, value); - - clutter_actor_set_shader_param_internal (self, param, &var); - - g_value_unset (&var); -} - -/** - * clutter_actor_set_shader_param_int: - * @self: a #ClutterActor - * @param: the name of the parameter - * @value: the value of the parameter - * - * Sets the value for a named int parameter of the shader applied to - * @actor. - * - * Since: 0.8 - * - * Deprecated: 1.8: Use clutter_shader_effect_set_uniform() instead - */ -void -clutter_actor_set_shader_param_int (ClutterActor *self, - const gchar *param, - gint value) -{ - GValue var = { 0, }; - - g_value_init (&var, G_TYPE_INT); - g_value_set_int (&var, value); - - clutter_actor_set_shader_param_internal (self, param, &var); - - g_value_unset (&var); -} - -/** - * clutter_actor_set_geometry: - * @self: A #ClutterActor - * @geometry: A #ClutterGeometry - * - * Sets the actor's fixed position and forces its minimum and natural - * size, in pixels. This means the untransformed actor will have the - * given geometry. This is the same as calling clutter_actor_set_position() - * and clutter_actor_set_size(). - * - * Deprecated: 1.10: Use clutter_actor_set_position() and - * clutter_actor_set_size() instead. - */ -void -clutter_actor_set_geometry (ClutterActor *self, - const ClutterGeometry *geometry) -{ - g_object_freeze_notify (G_OBJECT (self)); - - clutter_actor_set_position (self, geometry->x, geometry->y); - clutter_actor_set_size (self, geometry->width, geometry->height); - - g_object_thaw_notify (G_OBJECT (self)); -} - -/** - * clutter_actor_get_geometry: - * @self: A #ClutterActor - * @geometry: (out caller-allocates): A location to store actors #ClutterGeometry - * - * Gets the size and position of an actor relative to its parent - * actor. This is the same as calling clutter_actor_get_position() and - * clutter_actor_get_size(). It tries to "do what you mean" and get the - * requested size and position if the actor's allocation is invalid. - * - * Deprecated: 1.10: Use clutter_actor_get_position() and - * clutter_actor_get_size(), or clutter_actor_get_allocation_geometry() - * instead. - */ -void -clutter_actor_get_geometry (ClutterActor *self, - ClutterGeometry *geometry) -{ - gfloat x, y, width, height; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (geometry != NULL); - - clutter_actor_get_position (self, &x, &y); - clutter_actor_get_size (self, &width, &height); - - geometry->x = (int) x; - geometry->y = (int) y; - geometry->width = (int) width; - geometry->height = (int) height; -} - -/** - * clutter_actor_get_allocation_geometry: - * @self: A #ClutterActor - * @geom: (out): allocation geometry in pixels - * - * Gets the layout box an actor has been assigned. The allocation can - * only be assumed valid inside a paint() method; anywhere else, it - * may be out-of-date. - * - * An allocation does not incorporate the actor's scale or anchor point; - * those transformations do not affect layout, only rendering. - * - * The returned rectangle is in pixels. - * - * Since: 0.8 - * - * Deprecated: 1.12: Use clutter_actor_get_allocation_box() instead. - */ -void -clutter_actor_get_allocation_geometry (ClutterActor *self, - ClutterGeometry *geom) -{ - ClutterActorBox box; - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - g_return_if_fail (geom != NULL); - - clutter_actor_get_allocation_box (self, &box); - - geom->x = CLUTTER_NEARBYINT (clutter_actor_box_get_x (&box)); - geom->y = CLUTTER_NEARBYINT (clutter_actor_box_get_y (&box)); - geom->width = CLUTTER_NEARBYINT (clutter_actor_box_get_width (&box)); - geom->height = CLUTTER_NEARBYINT (clutter_actor_box_get_height (&box)); -} diff --git a/clutter/clutter/deprecated/clutter-actor.h b/clutter/clutter/deprecated/clutter-actor.h index 9302e9423..1b447ea32 100644 --- a/clutter/clutter/deprecated/clutter-actor.h +++ b/clutter/clutter/deprecated/clutter-actor.h @@ -33,128 +33,81 @@ G_BEGIN_DECLS -CLUTTER_DEPRECATED_IN_1_10 -void clutter_actor_set_geometry (ClutterActor *self, - const ClutterGeometry *geometry); - -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_get_allocation_geometry) -void clutter_actor_get_geometry (ClutterActor *self, - ClutterGeometry *geometry); -CLUTTER_DEPRECATED_IN_1_8 -guint32 clutter_actor_get_gid (ClutterActor *self); - -CLUTTER_DEPRECATED_IN_1_8 +CLUTTER_DEPRECATED ClutterActor * clutter_get_actor_by_gid (guint32 id_); -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_remove_child() and clutter_actor_add_child()) -void clutter_actor_reparent (ClutterActor *self, - ClutterActor *new_parent); - -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_add_child) +CLUTTER_DEPRECATED_FOR(clutter_actor_add_child) void clutter_actor_set_parent (ClutterActor *self, ClutterActor *parent); -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_remove_child) +CLUTTER_DEPRECATED_FOR(clutter_actor_remove_child) void clutter_actor_unparent (ClutterActor *self); -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_set_child_above_sibling) -void clutter_actor_raise (ClutterActor *self, - ClutterActor *below); - -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_set_child_below_sibling) -void clutter_actor_lower (ClutterActor *self, - ClutterActor *above); - -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_set_child_above_sibling() with NULL sibling) -void clutter_actor_raise_top (ClutterActor *self); - -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_set_child_below_sibling() with NULL sibling) -void clutter_actor_lower_bottom (ClutterActor *self); - -CLUTTER_DEPRECATED_IN_1_10 +CLUTTER_DEPRECATED void clutter_actor_push_internal (ClutterActor *self); -CLUTTER_DEPRECATED_IN_1_10 +CLUTTER_DEPRECATED void clutter_actor_pop_internal (ClutterActor *self); -CLUTTER_DEPRECATED_IN_1_10 +CLUTTER_DEPRECATED void clutter_actor_show_all (ClutterActor *self); -CLUTTER_DEPRECATED_IN_1_10 -void clutter_actor_hide_all (ClutterActor *self); - -CLUTTER_DEPRECATED_IN_1_12_FOR(clutter_actor_set_z_position) +CLUTTER_DEPRECATED_FOR(clutter_actor_set_z_position) void clutter_actor_set_depth (ClutterActor *self, gfloat depth); -CLUTTER_DEPRECATED_IN_1_12_FOR(clutter_actor_get_z_position) +CLUTTER_DEPRECATED_FOR(clutter_actor_get_z_position) gfloat clutter_actor_get_depth (ClutterActor *self); -CLUTTER_DEPRECATED_IN_1_12_FOR(clutter_actor_set_rotation_angle) +CLUTTER_DEPRECATED_FOR(clutter_actor_set_rotation_angle) void clutter_actor_set_rotation (ClutterActor *self, ClutterRotateAxis axis, gdouble angle, gfloat x, gfloat y, gfloat z); -CLUTTER_DEPRECATED_IN_1_12_FOR(clutter_actor_set_rotation_angle and clutter_actor_set_pivot_point) +CLUTTER_DEPRECATED_FOR(clutter_actor_set_rotation_angle and clutter_actor_set_pivot_point) void clutter_actor_set_z_rotation_from_gravity (ClutterActor *self, gdouble angle, ClutterGravity gravity); -CLUTTER_DEPRECATED_IN_1_12_FOR(clutter_actor_get_rotation_angle) +CLUTTER_DEPRECATED_FOR(clutter_actor_get_rotation_angle) gdouble clutter_actor_get_rotation (ClutterActor *self, ClutterRotateAxis axis, gfloat *x, gfloat *y, gfloat *z); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED ClutterGravity clutter_actor_get_z_rotation_gravity (ClutterActor *self); -CLUTTER_DEPRECATED_IN_1_12_FOR(clutter_actor_set_scale and clutter_actor_set_pivot_point) +CLUTTER_DEPRECATED_FOR(clutter_actor_set_scale and clutter_actor_set_pivot_point) void clutter_actor_set_scale_full (ClutterActor *self, gdouble scale_x, gdouble scale_y, gfloat center_x, gfloat center_y); -CLUTTER_DEPRECATED_IN_1_12_FOR(clutter_actor_set_scale and clutter_actor_set_pivot_point) -void clutter_actor_set_scale_with_gravity (ClutterActor *self, - gdouble scale_x, - gdouble scale_y, - ClutterGravity gravity); -CLUTTER_DEPRECATED_IN_1_12_FOR(clutter_actor_get_pivot_point) +CLUTTER_DEPRECATED_FOR(clutter_actor_get_pivot_point) void clutter_actor_get_scale_center (ClutterActor *self, gfloat *center_x, gfloat *center_y); -CLUTTER_DEPRECATED_IN_1_12_FOR(clutter_actor_get_pivot_point) +CLUTTER_DEPRECATED_FOR(clutter_actor_get_pivot_point) ClutterGravity clutter_actor_get_scale_gravity (ClutterActor *self); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED void clutter_actor_set_anchor_point (ClutterActor *self, gfloat anchor_x, gfloat anchor_y); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED void clutter_actor_move_anchor_point (ClutterActor *self, gfloat anchor_x, gfloat anchor_y); -CLUTTER_DEPRECATED_IN_1_12 -void clutter_actor_get_anchor_point (ClutterActor *self, - gfloat *anchor_x, - gfloat *anchor_y); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED ClutterGravity clutter_actor_get_anchor_point_gravity (ClutterActor *self); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED void clutter_actor_set_anchor_point_from_gravity (ClutterActor *self, ClutterGravity gravity); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED void clutter_actor_move_anchor_point_from_gravity (ClutterActor *self, ClutterGravity gravity); -CLUTTER_DEPRECATED_IN_1_12 -void clutter_actor_get_transformation_matrix (ClutterActor *self, - ClutterMatrix *matrix); - -CLUTTER_DEPRECATED_IN_1_12_FOR (clutter_actor_get_allocation_box) -void clutter_actor_get_allocation_geometry (ClutterActor *self, - ClutterGeometry *geom); G_END_DECLS diff --git a/clutter/clutter/deprecated/clutter-alpha.c b/clutter/clutter/deprecated/clutter-alpha.c index c3936da6f..9560c2ead 100644 --- a/clutter/clutter/deprecated/clutter-alpha.c +++ b/clutter/clutter/deprecated/clutter-alpha.c @@ -39,15 +39,12 @@ * be available any more in the next major version of Clutter. * * A #ClutterAlpha binds a #ClutterTimeline to a progress function which - * translates the time T into an adimensional factor alpha. The factor can - * then be used to drive a #ClutterBehaviour, which will translate the - * alpha value into something meaningful for a #ClutterActor. + * translates the time T into an adimensional factor alpha. * * You should provide a #ClutterTimeline and bind it to the #ClutterAlpha * instance using clutter_alpha_set_timeline(). You should also set an - * "animation mode", either by using the #ClutterAnimationMode values that - * Clutter itself provides or by registering custom functions using - * clutter_alpha_register_func(). + * "animation mode", by using the #ClutterAnimationMode values that + * Clutter provides. * * Instead of a #ClutterAnimationMode you may provide a function returning * the alpha value depending on the progress of the timeline, using @@ -59,9 +56,6 @@ * pause, stop or resume the #ClutterAlpha from calling the alpha function by * using the appropriate functions of the #ClutterTimeline object. * - * #ClutterAlpha is used to "drive" a #ClutterBehaviour instance, and it - * is internally used by the #ClutterAnimation API. - * * #ClutterAlpha is available since Clutter 0.2. * * #ClutterAlpha is deprecated since Clutter 1.12. #ClutterTimeline and @@ -78,9 +72,7 @@ * * The following JSON fragment defines a #ClutterAlpha * using a #ClutterTimeline with id "sine-timeline" and an alpha - * function called `my_sine_alpha`. The defined #ClutterAlpha - * instance can be reused in multiple #ClutterBehaviour - * definitions or for #ClutterAnimation definitions. + * function called `my_sine_alpha`. * * |[ * { @@ -95,9 +87,7 @@ * ]| */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include @@ -371,9 +361,8 @@ clutter_alpha_class_init (ClutterAlphaClass *klass) /** * ClutterAlpha:mode: * - * The progress function logical id - either a value from the - * #ClutterAnimationMode enumeration or a value returned by - * clutter_alpha_register_func(). + * The progress function logical id - a value from the + * #ClutterAnimationMode enumeration. * * If %CLUTTER_CUSTOM_MODE is used then the function set using * clutter_alpha_set_closure() or clutter_alpha_set_func() @@ -647,9 +636,6 @@ clutter_alpha_get_timeline (ClutterAlpha *alpha) * bind a #ClutterTimeline object to the #ClutterAlpha instance * using clutter_alpha_set_timeline(). * - * You should use the newly created #ClutterAlpha instance inside - * a #ClutterBehaviour object. - * * Return value: the newly created empty #ClutterAlpha instance. * * Since: 0.2 @@ -691,44 +677,6 @@ clutter_alpha_new_full (ClutterTimeline *timeline, NULL); } -/** - * clutter_alpha_new_with_func: - * @timeline: a #ClutterTimeline - * @func: a #ClutterAlphaFunc - * @data: data to pass to the function, or %NULL - * @destroy: function to call when removing the alpha function, or %NULL - * - * Creates a new #ClutterAlpha instances and sets the timeline - * and the alpha function. - * - * This function will not register @func as a global alpha function. - * - * See also clutter_alpha_set_timeline() and clutter_alpha_set_func(). - * - * Return value: the newly created #ClutterAlpha - * - * Since: 1.0 - * - * Deprecated: 1.12: Use #ClutterTimeline instead - */ -ClutterAlpha * -clutter_alpha_new_with_func (ClutterTimeline *timeline, - ClutterAlphaFunc func, - gpointer data, - GDestroyNotify destroy) -{ - ClutterAlpha *retval; - - g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), NULL); - g_return_val_if_fail (func != NULL, NULL); - - retval = clutter_alpha_new (); - clutter_alpha_set_timeline (retval, timeline); - clutter_alpha_set_func (retval, func, data, destroy); - - return retval; -} - /** * clutter_alpha_get_mode: * @alpha: a #ClutterAlpha @@ -783,8 +731,7 @@ clutter_alpha_easing_func (ClutterAlpha *alpha, * @mode: a #ClutterAnimationMode * * Sets the progress function of @alpha using the symbolic value - * of @mode, as taken by the #ClutterAnimationMode enumeration or - * using the value returned by clutter_alpha_register_func(). + * of @mode, as taken by the #ClutterAnimationMode enumeration. * * Since: 1.0 * @@ -838,9 +785,7 @@ clutter_alpha_set_mode (ClutterAlpha *alpha, if (G_UNLIKELY (clutter_alphas == NULL)) { - g_warning ("No alpha functions defined for ClutterAlpha to use. " - "Use clutter_alpha_register_func() to register an " - "alpha function."); + g_warning ("No alpha functions defined for ClutterAlpha to use. "); return; } @@ -872,81 +817,3 @@ clutter_alpha_set_mode (ClutterAlpha *alpha, g_object_notify_by_pspec (G_OBJECT (alpha), obj_props[PROP_MODE]); } - -static gulong -register_alpha_internal (AlphaData *alpha_data) -{ - if (G_UNLIKELY (clutter_alphas == NULL)) - clutter_alphas = g_ptr_array_new (); - - g_ptr_array_add (clutter_alphas, alpha_data); - - return clutter_alphas->len + CLUTTER_ANIMATION_LAST; -} - -/** - * clutter_alpha_register_func: (skip) - * @func: a #ClutterAlphaFunc - * @data: user data to pass to @func, or %NULL - * - * Registers a global alpha function and returns its logical id - * to be used by clutter_alpha_set_mode() or by #ClutterAnimation. - * - * The logical id is always greater than %CLUTTER_ANIMATION_LAST. - * - * Return value: the logical id of the alpha function - * - * Since: 1.0 - * - * Deprecated: 1.12: There is no direct replacement for this - * function. Use clutter_timeline_set_progress_func() on each - * specific #ClutterTimeline instance - */ -gulong -clutter_alpha_register_func (ClutterAlphaFunc func, - gpointer data) -{ - AlphaData *alpha_data; - - g_return_val_if_fail (func != NULL, 0); - - alpha_data = g_slice_new (AlphaData); - alpha_data->closure_set = FALSE; - alpha_data->func = func; - alpha_data->data = data; - - return register_alpha_internal (alpha_data); -} - -/** - * clutter_alpha_register_closure: (rename-to clutter_alpha_register_func) - * @closure: a #GClosure - * - * #GClosure variant of clutter_alpha_register_func(). - * - * Registers a global alpha function and returns its logical id - * to be used by clutter_alpha_set_mode() or by #ClutterAnimation. - * - * The logical id is always greater than %CLUTTER_ANIMATION_LAST. - * - * Return value: the logical id of the alpha function - * - * Since: 1.0 - * - * Deprecated: 1.12: There is no direct replacement for this - * function. Use clutter_timeline_set_progress_func() on each - * specific #ClutterTimeline instance - */ -gulong -clutter_alpha_register_closure (GClosure *closure) -{ - AlphaData *alpha_data; - - g_return_val_if_fail (closure != NULL, 0); - - alpha_data = g_slice_new (AlphaData); - alpha_data->closure_set = TRUE; - alpha_data->closure = closure; - - return register_alpha_internal (alpha_data); -} diff --git a/clutter/clutter/deprecated/clutter-alpha.h b/clutter/clutter/deprecated/clutter-alpha.h index 8a0dff661..fc030a567 100644 --- a/clutter/clutter/deprecated/clutter-alpha.h +++ b/clutter/clutter/deprecated/clutter-alpha.h @@ -104,47 +104,35 @@ struct _ClutterAlphaClass void (*_clutter_alpha_5) (void); }; -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED GType clutter_alpha_get_type (void) G_GNUC_CONST; -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED ClutterAlpha * clutter_alpha_new (void); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED ClutterAlpha * clutter_alpha_new_full (ClutterTimeline *timeline, gulong mode); -CLUTTER_DEPRECATED_IN_1_12 -ClutterAlpha * clutter_alpha_new_with_func (ClutterTimeline *timeline, - ClutterAlphaFunc func, - gpointer data, - GDestroyNotify destroy); - -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED gdouble clutter_alpha_get_alpha (ClutterAlpha *alpha); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED void clutter_alpha_set_func (ClutterAlpha *alpha, ClutterAlphaFunc func, gpointer data, GDestroyNotify destroy); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED void clutter_alpha_set_closure (ClutterAlpha *alpha, GClosure *closure); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED void clutter_alpha_set_timeline (ClutterAlpha *alpha, ClutterTimeline *timeline); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED ClutterTimeline *clutter_alpha_get_timeline (ClutterAlpha *alpha); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED void clutter_alpha_set_mode (ClutterAlpha *alpha, gulong mode); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED gulong clutter_alpha_get_mode (ClutterAlpha *alpha); -CLUTTER_DEPRECATED_IN_1_12 -gulong clutter_alpha_register_func (ClutterAlphaFunc func, - gpointer data); -CLUTTER_DEPRECATED_IN_1_12 -gulong clutter_alpha_register_closure (GClosure *closure); - G_END_DECLS #endif /* __CLUTTER_ALPHA_H__ */ diff --git a/clutter/clutter/deprecated/clutter-animatable.h b/clutter/clutter/deprecated/clutter-animatable.h deleted file mode 100644 index df40e288e..000000000 --- a/clutter/clutter/deprecated/clutter-animatable.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -#ifndef __CLUTTER_ANIMATABLE_DEPRECATED_H__ -#define __CLUTTER_ANIMATABLE_DEPRECATED_H__ - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include - -G_BEGIN_DECLS - -CLUTTER_DEPRECATED_IN_1_8_FOR(clutter_animatable_interpolate_value) -gboolean clutter_animatable_animate_property (ClutterAnimatable *animatable, - ClutterAnimation *animation, - const gchar *property_name, - const GValue *initial_value, - const GValue *final_value, - gdouble progress, - GValue *value); - -G_END_DECLS - -#endif /* __CLUTTER_ANIMATABLE_DEPRECATED_H__ */ diff --git a/clutter/clutter/deprecated/clutter-animation.c b/clutter/clutter/deprecated/clutter-animation.c index 4d39beedb..0b5ac5112 100644 --- a/clutter/clutter/deprecated/clutter-animation.c +++ b/clutter/clutter/deprecated/clutter-animation.c @@ -50,20 +50,10 @@ * emitted if #ClutterAnimation:loop is set to %TRUE - that is, a looping * animation never completes. * - * If your animation depends on user control you can force its completion - * using clutter_animation_completed(). - * * If the #GObject instance bound to a #ClutterAnimation implements the * #ClutterAnimatable interface it is possible for that instance to * control the way the initial and final states are interpolated. * - * #ClutterAnimations are distinguished from #ClutterBehaviours - * because the former can only control #GObject properties of a single - * #GObject instance, while the latter can control multiple properties - * using accessor functions inside the #ClutterBehaviour - * `alpha_notify` virtual function, and can control multiple #ClutterActors - * as well. - * * For convenience, it is possible to use the clutter_actor_animate() * function call which will take care of setting up and tearing down * a #ClutterAnimation instance and animate an actor between its current @@ -97,9 +87,7 @@ * - easeInBounce, easeOutBounce, easeInOutBounce */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include #include @@ -569,8 +557,7 @@ clutter_animation_class_init (ClutterAnimationClass *klass) G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ClutterAnimationClass, started), - NULL, NULL, - _clutter_marshal_VOID__VOID, + NULL, NULL, NULL, G_TYPE_NONE, 0); /** @@ -591,8 +578,7 @@ clutter_animation_class_init (ClutterAnimationClass *klass) G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ClutterAnimationClass, completed), - NULL, NULL, - _clutter_marshal_VOID__VOID, + NULL, NULL, NULL, G_TYPE_NONE, 0); } @@ -603,7 +589,7 @@ clutter_animation_init (ClutterAnimation *self) self->priv->properties = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) free, + (GDestroyNotify) g_free, (GDestroyNotify) g_object_unref); } @@ -649,231 +635,6 @@ clutter_animation_update_property_internal (ClutterAnimation *animation, g_object_ref_sink (interval)); } -static GParamSpec * -clutter_animation_validate_bind (ClutterAnimation *animation, - const char *property_name, - GType argtype) -{ - ClutterAnimationPrivate *priv; - GParamSpec *pspec; - GType pspec_type; - - priv = animation->priv; - - if (G_UNLIKELY (!priv->object)) - { - g_warning ("Cannot bind property '%s': the animation has no " - "object set. You need to call clutter_animation_set_object() " - "first to be able to bind a property", - property_name); - return NULL; - } - - if (G_UNLIKELY (clutter_animation_has_property (animation, property_name))) - { - g_warning ("Cannot bind property '%s': the animation already has " - "a bound property with the same name", - property_name); - return NULL; - } - - if (CLUTTER_IS_ANIMATABLE (priv->object)) - { - ClutterAnimatable *animatable = CLUTTER_ANIMATABLE (priv->object); - - pspec = clutter_animatable_find_property (animatable, property_name); - } - else - { - GObjectClass *klass = G_OBJECT_GET_CLASS (priv->object); - - pspec = g_object_class_find_property (klass, property_name); - } - - if (pspec == NULL) - { - g_warning ("Cannot bind property '%s': objects of type '%s' have " - "no such property", - property_name, - g_type_name (G_OBJECT_TYPE (priv->object))); - return NULL; - } - - if (!(pspec->flags & G_PARAM_WRITABLE)) - { - g_warning ("Cannot bind property '%s': the property is not writable", - property_name); - return NULL; - } - - pspec_type = G_PARAM_SPEC_VALUE_TYPE (pspec); - - if (g_value_type_transformable (argtype, pspec_type)) - return pspec; - else - { - g_warning ("Cannot bind property '%s': the interval value of " - "type '%s' is not compatible with the property value " - "of type '%s'", - property_name, - g_type_name (argtype), - g_type_name (pspec_type)); - return NULL; - } -} - -/** - * clutter_animation_bind_interval: - * @animation: a #ClutterAnimation - * @property_name: the property to control - * @interval: (transfer full): a #ClutterInterval - * - * Binds @interval to the @property_name of the #GObject - * attached to @animation. The #ClutterAnimation will take - * ownership of the passed #ClutterInterval. For more information - * about animations, see clutter_actor_animate(). - * - * If you need to update the interval instance use - * clutter_animation_update_interval() instead. - * - * Return value: (transfer none): The animation itself. - * Since: 1.0 - * Deprecated: 1.12: Use #ClutterPropertyTransition instead - */ -ClutterAnimation * -clutter_animation_bind_interval (ClutterAnimation *animation, - const gchar *property_name, - ClutterInterval *interval) -{ - GParamSpec *pspec; - - g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), NULL); - g_return_val_if_fail (property_name != NULL, NULL); - g_return_val_if_fail (CLUTTER_IS_INTERVAL (interval), NULL); - - pspec = clutter_animation_validate_bind (animation, property_name, - clutter_interval_get_value_type (interval)); - if (pspec == NULL) - return NULL; - - clutter_animation_bind_property_internal (animation, property_name, - pspec, - interval); - - return animation; -} - - -/** - * clutter_animation_bind: - * @animation: a #ClutterAnimation - * @property_name: the property to control - * @final: The final value of the property - * - * Adds a single property with name @property_name to the - * animation @animation. For more information about animations, - * see clutter_actor_animate(). - * - * This method returns the animation primarily to make chained - * calls convenient in language bindings. - * - * Return value: (transfer none): The animation itself. - * - * Since: 1.0 - * Deprecated: 1.12: Use #ClutterPropertyTransition instead - */ -ClutterAnimation * -clutter_animation_bind (ClutterAnimation *animation, - const gchar *property_name, - const GValue *final) -{ - ClutterAnimationPrivate *priv; - GParamSpec *pspec; - ClutterInterval *interval; - GType type; - GValue initial = G_VALUE_INIT; - GValue real_final = G_VALUE_INIT; - - g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), NULL); - g_return_val_if_fail (property_name != NULL, NULL); - - priv = animation->priv; - - type = G_VALUE_TYPE (final); - pspec = clutter_animation_validate_bind (animation, property_name, type); - if (pspec == NULL) - return NULL; - - g_value_init (&real_final, G_PARAM_SPEC_VALUE_TYPE (pspec)); - if (!g_value_transform (final, &real_final)) - { - g_value_unset (&real_final); - g_warning ("Unable to transform the value of type '%s' to a value " - "of '%s' compatible with the property '%s'of the object " - "of type '%s'", - g_type_name (type), - g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)), - property_name, - G_OBJECT_TYPE_NAME (priv->object)); - return NULL; - } - - g_value_init (&initial, G_PARAM_SPEC_VALUE_TYPE (pspec)); - - if (CLUTTER_IS_ANIMATABLE (priv->object)) - clutter_animatable_get_initial_state (CLUTTER_ANIMATABLE (priv->object), - property_name, - &initial); - else - g_object_get_property (priv->object, property_name, &initial); - - interval = clutter_interval_new_with_values (G_PARAM_SPEC_VALUE_TYPE (pspec), - &initial, - &real_final); - - g_value_unset (&initial); - g_value_unset (&real_final); - - clutter_animation_bind_property_internal (animation, property_name, - pspec, - interval); - - return animation; -} - - -/** - * clutter_animation_unbind_property: - * @animation: a #ClutterAnimation - * @property_name: name of the property - * - * Removes @property_name from the list of animated properties. - * - * Since: 1.0 - * Deprecated: 1.12: Use #ClutterPropertyTransition instead - */ -void -clutter_animation_unbind_property (ClutterAnimation *animation, - const gchar *property_name) -{ - ClutterAnimationPrivate *priv; - - g_return_if_fail (CLUTTER_IS_ANIMATION (animation)); - g_return_if_fail (property_name != NULL); - - priv = animation->priv; - - if (!clutter_animation_has_property (animation, property_name)) - { - g_warning ("Cannot unbind property '%s': the animation has " - "no bound property with that name", - property_name); - return; - } - - g_hash_table_remove (priv->properties, property_name); -} - /** * clutter_animation_has_property: * @animation: a #ClutterAnimation @@ -901,137 +662,6 @@ clutter_animation_has_property (ClutterAnimation *animation, return g_hash_table_lookup (priv->properties, property_name) != NULL; } -/** - * clutter_animation_update_interval: - * @animation: a #ClutterAnimation - * @property_name: name of the property - * @interval: a #ClutterInterval - * - * Changes the @interval for @property_name. The #ClutterAnimation - * will take ownership of the passed #ClutterInterval. - * - * Since: 1.0 - * Deprecated: 1.12: Use #ClutterPropertyTransition instead - */ -void -clutter_animation_update_interval (ClutterAnimation *animation, - const gchar *property_name, - ClutterInterval *interval) -{ - ClutterAnimationPrivate *priv; - GParamSpec *pspec; - GType pspec_type, int_type; - - g_return_if_fail (CLUTTER_IS_ANIMATION (animation)); - g_return_if_fail (property_name != NULL); - g_return_if_fail (CLUTTER_IS_INTERVAL (interval)); - - priv = animation->priv; - - if (!clutter_animation_has_property (animation, property_name)) - { - g_warning ("Cannot update property '%s': the animation has " - "no bound property with that name", - property_name); - return; - } - - if (CLUTTER_IS_ANIMATABLE (priv->object)) - { - ClutterAnimatable *animatable = CLUTTER_ANIMATABLE (priv->object); - - pspec = clutter_animatable_find_property (animatable, property_name); - } - else - { - GObjectClass *klass = G_OBJECT_GET_CLASS (priv->object); - - pspec = g_object_class_find_property (klass, property_name); - } - - if (pspec == NULL) - { - g_warning ("Cannot update property '%s': objects of type '%s' have " - "no such property", - property_name, - g_type_name (G_OBJECT_TYPE (priv->object))); - return; - } - - pspec_type = G_PARAM_SPEC_VALUE_TYPE (pspec); - int_type = clutter_interval_get_value_type (interval); - - if (!g_value_type_compatible (int_type, pspec_type) || - !g_value_type_transformable (int_type, pspec_type)) - { - g_warning ("Cannot update property '%s': the interval value of " - "type '%s' is not compatible with the property value " - "of type '%s'", - property_name, - g_type_name (int_type), - g_type_name (pspec_type)); - return; - } - - clutter_animation_update_property_internal (animation, property_name, - pspec, - interval); -} - -/** - * clutter_animation_update: - * @animation: a #ClutterAnimation - * @property_name: name of the property - * @final: The final value of the property - * - * Updates the @final value of the interval for @property_name - * - * Return value: (transfer none): The animation itself. - * - * Since: 1.0 - * Deprecated: 1.12: Use #ClutterPropertyTransition instead - */ -ClutterAnimation * -clutter_animation_update (ClutterAnimation *animation, - const gchar *property_name, - const GValue *final) -{ - ClutterInterval *interval; - GType int_type; - - g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), NULL); - g_return_val_if_fail (property_name != NULL, NULL); - g_return_val_if_fail (final != NULL, NULL); - g_return_val_if_fail (G_VALUE_TYPE (final) != G_TYPE_INVALID, NULL); - - interval = clutter_animation_get_interval (animation, property_name); - if (interval == NULL) - { - g_warning ("Cannot update property '%s': the animation has " - "no bound property with that name", - property_name); - return NULL; - } - - int_type = clutter_interval_get_value_type (interval); - - if (!g_value_type_compatible (G_VALUE_TYPE (final), int_type) || - !g_value_type_transformable (G_VALUE_TYPE (final), int_type)) - { - g_warning ("Cannot update property '%s': the interval value of " - "type '%s' is not compatible with the property value " - "of type '%s'", - property_name, - g_type_name (int_type), - g_type_name (G_VALUE_TYPE (final))); - return NULL; - } - - clutter_interval_set_final_value (interval, final); - - return animation; -} - /** * clutter_animation_get_interval: * @animation: a #ClutterAnimation @@ -1295,10 +925,6 @@ clutter_animation_set_alpha_internal (ClutterAnimation *animation, * set the duration with clutter_animation_set_duration() and the * easing mode using clutter_animation_set_mode(). * - * Use clutter_animation_bind() or clutter_animation_bind_interval() - * to define the properties to be animated. The interval and the - * animated properties can be updated at runtime. - * * The clutter_actor_animate() and relative family of functions provide * an easy way to animate a #ClutterActor and automatically manage the * lifetime of a #ClutterAnimation instance, so you should consider using @@ -1352,25 +978,6 @@ clutter_animation_set_object (ClutterAnimation *animation, g_object_notify_by_pspec (G_OBJECT (animation), obj_props[PROP_OBJECT]); } -/** - * clutter_animation_get_object: - * @animation: a #ClutterAnimation - * - * Retrieves the #GObject attached to @animation. - * - * Return value: (transfer none): a #GObject - * - * Since: 1.0 - * Deprecated: 1.12: Use #ClutterPropertyTransition instead - */ -GObject * -clutter_animation_get_object (ClutterAnimation *animation) -{ - g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), NULL); - - return animation->priv->object; -} - /** * clutter_animation_set_mode: * @animation: a #ClutterAnimation @@ -1661,76 +1268,6 @@ clutter_animation_get_timeline (ClutterAnimation *animation) return clutter_animation_get_timeline_internal (animation); } -/** - * clutter_animation_set_alpha: - * @animation: a #ClutterAnimation - * @alpha: a #ClutterAlpha, or %NULL to unset the current #ClutterAlpha - * - * Sets @alpha as the #ClutterAlpha used by @animation. - * - * If @alpha is not %NULL, the #ClutterAnimation will take ownership - * of the #ClutterAlpha instance. - * - * Since: 1.0 - * - * Deprecated: 1.10: Use clutter_animation_get_timeline() and - * clutter_timeline_set_progress_mode() instead. - */ -void -clutter_animation_set_alpha (ClutterAnimation *animation, - ClutterAlpha *alpha) -{ - g_return_if_fail (CLUTTER_IS_ANIMATION (animation)); - g_return_if_fail (alpha == NULL || CLUTTER_IS_ALPHA (alpha)); - - clutter_animation_set_alpha_internal (animation, alpha); -} - -/** - * clutter_animation_get_alpha: - * @animation: a #ClutterAnimation - * - * Retrieves the #ClutterAlpha used by @animation. - * - * Return value: (transfer none): the alpha object used by the animation - * - * Since: 1.0 - * - * Deprecated: 1.10: Use clutter_animation_get_timeline() and - * clutter_timeline_get_progress_mode() instead. - */ -ClutterAlpha * -clutter_animation_get_alpha (ClutterAnimation *animation) -{ - g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), NULL); - - return clutter_animation_get_alpha_internal (animation); -} - -/** - * clutter_animation_completed: - * @animation: a #ClutterAnimation - * - * Emits the ::completed signal on @animation - * - * When using this function with a #ClutterAnimation created - * by the clutter_actor_animate() family of functions, @animation - * will be unreferenced and it will not be valid anymore, - * unless g_object_ref() was called before calling this function - * or unless a reference was taken inside a handler for the - * #ClutterAnimation::completed signal - * - * Since: 1.0 - * Deprecated: 1.12: Use #ClutterPropertyTransition instead - */ -void -clutter_animation_completed (ClutterAnimation *animation) -{ - g_return_if_fail (CLUTTER_IS_ANIMATION (animation)); - - g_signal_emit (animation, animation_signals[COMPLETED], 0); -} - /* * starts the timeline */ @@ -1864,55 +1401,6 @@ clutter_animation_setup_property (ClutterAnimation *animation, g_value_unset (&real_value); } -static void -clutter_animation_setupv (ClutterAnimation *animation, - gint n_properties, - const gchar * const properties[], - const GValue *values) -{ - ClutterAnimationPrivate *priv = animation->priv; - ClutterAnimatable *animatable = NULL; - GObjectClass *klass = NULL; - gint i; - - if (CLUTTER_IS_ANIMATABLE (priv->object)) - animatable = CLUTTER_ANIMATABLE (priv->object); - else - klass = G_OBJECT_GET_CLASS (priv->object); - - for (i = 0; i < n_properties; i++) - { - const gchar *property_name = properties[i]; - GParamSpec *pspec; - gboolean is_fixed = FALSE; - - if (g_str_has_prefix (property_name, "fixed::")) - { - property_name += 7; /* strlen("fixed::") */ - is_fixed = TRUE; - } - - if (animatable != NULL) - pspec = clutter_animatable_find_property (animatable, property_name); - else - pspec = g_object_class_find_property (klass, property_name); - - if (pspec == NULL) - { - g_warning ("Cannot bind property '%s': objects of type '%s' do " - "not have this property", - property_name, - g_type_name (G_OBJECT_TYPE (priv->object))); - break; - } - - clutter_animation_setup_property (animation, property_name, - &values[i], - pspec, - is_fixed); - } -} - static const struct { const gchar *name; @@ -2013,7 +1501,7 @@ clutter_animation_setup_valist (ClutterAnimation *animation, if (error) { g_warning ("%s: %s", G_STRLOC, error); - free (error); + g_free (error); break; } @@ -2066,67 +1554,6 @@ animation_create_for_actor (ClutterActor *actor) return animation; } -/** - * clutter_actor_animate_with_alpha: - * @actor: a #ClutterActor - * @alpha: a #ClutterAlpha - * @first_property_name: the name of a property - * @...: a %NULL terminated list of property names and - * property values - * - * Animates the given list of properties of @actor between the current - * value for each property and a new final value. The animation has a - * definite behaviour given by the passed @alpha. - * - * See clutter_actor_animate() for further details. - * - * This function is useful if you want to use an existing #ClutterAlpha - * to animate @actor. - * - * Return value: (transfer none): a #ClutterAnimation object. The object is owned by the - * #ClutterActor and should not be unreferenced with g_object_unref() - * - * Since: 1.0 - * - * Deprecated: 1.10: Use the implicit transition for animatable properties - * in #ClutterActor instead. See clutter_actor_save_easing_state(), - * clutter_actor_set_easing_mode(), clutter_actor_set_easing_duration(), - * clutter_actor_set_easing_delay(), and clutter_actor_restore_easing_state(). - */ -ClutterAnimation * -clutter_actor_animate_with_alpha (ClutterActor *actor, - ClutterAlpha *alpha, - const gchar *first_property_name, - ...) -{ - ClutterAnimation *animation; - ClutterTimeline *timeline; - va_list args; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), NULL); - g_return_val_if_fail (CLUTTER_IS_ALPHA (alpha), NULL); - g_return_val_if_fail (first_property_name != NULL, NULL); - - timeline = clutter_alpha_get_timeline (alpha); - if (timeline == NULL) - { - g_warning ("The passed ClutterAlpha does not have an " - "associated ClutterTimeline."); - return NULL; - } - - animation = animation_create_for_actor (actor); - clutter_animation_set_alpha_internal (animation, alpha); - - va_start (args, first_property_name); - clutter_animation_setup_valist (animation, first_property_name, args); - va_end (args); - - clutter_animation_start (animation); - - return animation; -} - /** * clutter_actor_animate_with_timeline: * @actor: a #ClutterActor @@ -2224,7 +1651,7 @@ clutter_actor_animate_with_timeline (ClutterActor *actor, * * Will animate the "rotation-angle-z" property between the current value * and 360 degrees, and set the "rotation-center-z" property to the fixed - * value of the #ClutterVertex "center". + * value of the #graphene_point3d_t "center". * * This function will implicitly create a #ClutterAnimation object which * will be assigned to the @actor and will be returned to the developer @@ -2370,263 +1797,3 @@ clutter_actor_animate (ClutterActor *actor, return animation; } - -/** - * clutter_actor_animatev: - * @actor: a #ClutterActor - * @mode: an animation mode logical id - * @duration: duration of the animation, in milliseconds - * @n_properties: number of property names and values - * @properties: (array length=n_properties) (element-type utf8): a vector - * containing the property names to set - * @values: (array length=n_properties): a vector containing the - * property values to set - * - * Animates the given list of properties of @actor between the current - * value for each property and a new final value. The animation has a - * definite duration and a speed given by the @mode. - * - * This is the vector-based variant of clutter_actor_animate(), useful - * for language bindings. - * - * Unlike clutter_actor_animate(), this function will not - * allow you to specify "signal::" names and callbacks. - * - * Return value: (transfer none): a #ClutterAnimation object. The object is - * owned by the #ClutterActor and should not be unreferenced with - * g_object_unref() - * - * Since: 1.0 - * Deprecated: 1.12: Use the implicit transition for animatable properties - * in #ClutterActor instead. See clutter_actor_save_easing_state(), - * clutter_actor_set_easing_mode(), clutter_actor_set_easing_duration(), - * clutter_actor_set_easing_delay(), and clutter_actor_restore_easing_state(). - */ -ClutterAnimation * -clutter_actor_animatev (ClutterActor *actor, - gulong mode, - guint duration, - gint n_properties, - const gchar * const properties[], - const GValue *values) -{ - ClutterAnimation *animation; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), NULL); - g_return_val_if_fail (mode != CLUTTER_CUSTOM_MODE, NULL); - g_return_val_if_fail (duration > 0, NULL); - g_return_val_if_fail (properties != NULL, NULL); - g_return_val_if_fail (values != NULL, NULL); - - animation = animation_create_for_actor (actor); - clutter_animation_set_mode (animation, mode); - clutter_animation_set_duration (animation, duration); - clutter_animation_setupv (animation, n_properties, properties, values); - clutter_animation_start (animation); - - return animation; -} - -/** - * clutter_actor_animate_with_timelinev: - * @actor: a #ClutterActor - * @mode: an animation mode logical id - * @timeline: a #ClutterTimeline - * @n_properties: number of property names and values - * @properties: (array length=n_properties) (element-type utf8): a vector - * containing the property names to set - * @values: (array length=n_properties): a vector containing the - * property values to set - * - * Animates the given list of properties of @actor between the current - * value for each property and a new final value. The animation has a - * definite duration given by @timeline and a speed given by the @mode. - * - * See clutter_actor_animate() for further details. - * - * This function is useful if you want to use an existing timeline - * to animate @actor. - * - * This is the vector-based variant of clutter_actor_animate_with_timeline(), - * useful for language bindings. - * - * Unlike clutter_actor_animate_with_timeline(), this function - * will not allow you to specify "signal::" names and callbacks. - * - * Return value: (transfer none): a #ClutterAnimation object. The object is - * owned by the #ClutterActor and should not be unreferenced with - * g_object_unref() - * - * Since: 1.0 - * Deprecated: 1.12: Use the implicit transition for animatable properties - * in #ClutterActor instead. See clutter_actor_save_easing_state(), - * clutter_actor_set_easing_mode(), clutter_actor_set_easing_duration(), - * clutter_actor_set_easing_delay(), and clutter_actor_restore_easing_state(). - */ -ClutterAnimation * -clutter_actor_animate_with_timelinev (ClutterActor *actor, - gulong mode, - ClutterTimeline *timeline, - gint n_properties, - const gchar * const properties[], - const GValue *values) -{ - ClutterAnimation *animation; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), NULL); - g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), NULL); - g_return_val_if_fail (properties != NULL, NULL); - g_return_val_if_fail (values != NULL, NULL); - - animation = animation_create_for_actor (actor); - clutter_animation_set_mode (animation, mode); - clutter_animation_set_timeline (animation, timeline); - clutter_animation_setupv (animation, n_properties, properties, values); - clutter_animation_start (animation); - - return animation; -} - -/** - * clutter_actor_animate_with_alphav: - * @actor: a #ClutterActor - * @alpha: a #ClutterAlpha - * @n_properties: number of property names and values - * @properties: (array length=n_properties) (element-type utf8): a vector - * containing the property names to set - * @values: (array length=n_properties): a vector containing the - * property values to set - * - * Animates the given list of properties of @actor between the current - * value for each property and a new final value. The animation has a - * definite behaviour given by the passed @alpha. - * - * See clutter_actor_animate() for further details. - * - * This function is useful if you want to use an existing #ClutterAlpha - * to animate @actor. - * - * This is the vector-based variant of clutter_actor_animate_with_alpha(), - * useful for language bindings. - * - * Unlike clutter_actor_animate_with_alpha(), this function will - * not allow you to specify "signal::" names and callbacks. - * - * Return value: (transfer none): a #ClutterAnimation object. The object is owned by the - * #ClutterActor and should not be unreferenced with g_object_unref() - * - * Since: 1.0 - * - * Deprecated: 1.10: Use the implicit transition for animatable properties - * in #ClutterActor instead. See clutter_actor_save_easing_state(), - * clutter_actor_set_easing_mode(), clutter_actor_set_easing_duration(), - * clutter_actor_set_easing_delay(), and clutter_actor_restore_easing_state(). - */ -ClutterAnimation * -clutter_actor_animate_with_alphav (ClutterActor *actor, - ClutterAlpha *alpha, - gint n_properties, - const gchar * const properties[], - const GValue *values) -{ - ClutterAnimation *animation; - ClutterTimeline *timeline; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), NULL); - g_return_val_if_fail (CLUTTER_IS_ALPHA (alpha), NULL); - g_return_val_if_fail (properties != NULL, NULL); - g_return_val_if_fail (values != NULL, NULL); - - timeline = clutter_alpha_get_timeline (alpha); - if (timeline == NULL) - { - g_warning ("The passed ClutterAlpha does not have an " - "associated ClutterTimeline."); - return NULL; - } - - animation = animation_create_for_actor (actor); - clutter_animation_set_alpha_internal (animation, alpha); - clutter_animation_setupv (animation, n_properties, properties, values); - clutter_animation_start (animation); - - return animation; -} - -/** - * clutter_actor_get_animation: - * @actor: a #ClutterActor - * - * Retrieves the #ClutterAnimation used by @actor, if clutter_actor_animate() - * has been called on @actor. - * - * Return value: (transfer none): a #ClutterAnimation, or %NULL - * - * Since: 1.0 - * Deprecated: 1.12: Use the implicit transition for animatable properties - * in #ClutterActor instead, and clutter_actor_get_transition() to retrieve - * the transition. - */ -ClutterAnimation * -clutter_actor_get_animation (ClutterActor *actor) -{ - g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), NULL); - - return g_object_get_qdata (G_OBJECT (actor), quark_object_animation); -} - -/** - * clutter_actor_detach_animation: - * @actor: a #ClutterActor - * - * Detaches the #ClutterAnimation used by @actor, if clutter_actor_animate() - * has been called on @actor. - * - * Once the animation has been detached, it loses a reference. If it was - * the only reference then the #ClutterAnimation becomes invalid. - * - * The #ClutterAnimation::completed signal will not be emitted. - * - * Since: 1.4 - * Deprecated: 1.12: Use the implicit transition for animatable properties - * in #ClutterActor instead, and clutter_actor_remove_transition() to - * remove the transition. - */ -void -clutter_actor_detach_animation (ClutterActor *actor) -{ - ClutterAnimation *animation; - ClutterAnimationPrivate *priv; - - g_return_if_fail (CLUTTER_IS_ACTOR (actor)); - - animation = g_object_get_qdata (G_OBJECT (actor), quark_object_animation); - if (animation == NULL) - return; - - priv = animation->priv; - - g_assert (priv->object == G_OBJECT (actor)); - - /* we can't call get_timeline_internal() here because it would be - * pointless to create a timeline on an animation we want to detach - */ - if (priv->alpha != NULL) - { - ClutterTimeline *timeline; - - timeline = clutter_alpha_get_timeline (priv->alpha); - if (timeline != NULL) - clutter_timeline_stop (timeline); - } - - /* disconnect the ::destroy handler added by animation_create_for_actor() */ - g_signal_handlers_disconnect_by_func (actor, - G_CALLBACK (on_actor_destroy), - animation); - - clutter_animation_set_object (animation, NULL); - - /* drop the reference on the animation */ - g_object_unref (animation); -} diff --git a/clutter/clutter/deprecated/clutter-animation.h b/clutter/clutter/deprecated/clutter-animation.h index 3b2310bb4..012cf44e7 100644 --- a/clutter/clutter/deprecated/clutter-animation.h +++ b/clutter/clutter/deprecated/clutter-animation.h @@ -94,116 +94,58 @@ struct _ClutterAnimationClass void (*_clutter_reserved8) (void); }; -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED GType clutter_animation_get_type (void) G_GNUC_CONST; -CLUTTER_DEPRECATED_IN_1_12_FOR(clutter_property_transition_new) +CLUTTER_DEPRECATED_FOR(clutter_property_transition_new) ClutterAnimation * clutter_animation_new (void); -CLUTTER_DEPRECATED_IN_1_12_FOR(clutter_transition_set_animatable) +CLUTTER_DEPRECATED_FOR(clutter_transition_set_animatable) void clutter_animation_set_object (ClutterAnimation *animation, GObject *object); -CLUTTER_DEPRECATED_IN_1_12_FOR(clutter_transition_get_animatable) -GObject * clutter_animation_get_object (ClutterAnimation *animation); -CLUTTER_DEPRECATED_IN_1_12_FOR(clutter_timeline_set_progress_mode) +CLUTTER_DEPRECATED_FOR(clutter_timeline_set_progress_mode) void clutter_animation_set_mode (ClutterAnimation *animation, gulong mode); -CLUTTER_DEPRECATED_IN_1_12_FOR(clutter_timeline_get_progress_mode) +CLUTTER_DEPRECATED_FOR(clutter_timeline_get_progress_mode) gulong clutter_animation_get_mode (ClutterAnimation *animation); -CLUTTER_DEPRECATED_IN_1_12_FOR(clutter_timeline_set_duration) +CLUTTER_DEPRECATED_FOR(clutter_timeline_set_duration) void clutter_animation_set_duration (ClutterAnimation *animation, guint msecs); -CLUTTER_DEPRECATED_IN_1_12_FOR(clutter_timeline_get_duration) +CLUTTER_DEPRECATED_FOR(clutter_timeline_get_duration) guint clutter_animation_get_duration (ClutterAnimation *animation); -CLUTTER_DEPRECATED_IN_1_12_FOR(clutter_timeline_set_repeat_count) +CLUTTER_DEPRECATED_FOR(clutter_timeline_set_repeat_count) void clutter_animation_set_loop (ClutterAnimation *animation, gboolean loop); -CLUTTER_DEPRECATED_IN_1_12_FOR(clutter_timeline_get_repeat_count) +CLUTTER_DEPRECATED_FOR(clutter_timeline_get_repeat_count) gboolean clutter_animation_get_loop (ClutterAnimation *animation); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED void clutter_animation_set_timeline (ClutterAnimation *animation, ClutterTimeline *timeline); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED ClutterTimeline * clutter_animation_get_timeline (ClutterAnimation *animation); -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_animation_set_timeline) -void clutter_animation_set_alpha (ClutterAnimation *animation, - ClutterAlpha *alpha); -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_animation_get_timeline) -ClutterAlpha * clutter_animation_get_alpha (ClutterAnimation *animation); -CLUTTER_DEPRECATED_IN_1_12 -ClutterAnimation * clutter_animation_bind (ClutterAnimation *animation, - const gchar *property_name, - const GValue *final); -CLUTTER_DEPRECATED_IN_1_12_FOR(clutter_transition_set_interval) -ClutterAnimation * clutter_animation_bind_interval (ClutterAnimation *animation, - const gchar *property_name, - ClutterInterval *interval); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED gboolean clutter_animation_has_property (ClutterAnimation *animation, const gchar *property_name); -CLUTTER_DEPRECATED_IN_1_12 -ClutterAnimation * clutter_animation_update (ClutterAnimation *animation, - const gchar *property_name, - const GValue *final); -CLUTTER_DEPRECATED_IN_1_12 -void clutter_animation_update_interval (ClutterAnimation *animation, - const gchar *property_name, - ClutterInterval *interval); -CLUTTER_DEPRECATED_IN_1_12 -void clutter_animation_unbind_property (ClutterAnimation *animation, - const gchar *property_name); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED ClutterInterval * clutter_animation_get_interval (ClutterAnimation *animation, const gchar *property_name); -CLUTTER_DEPRECATED_IN_1_12 -void clutter_animation_completed (ClutterAnimation *animation); /* * ClutterActor API */ -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED ClutterAnimation * clutter_actor_animate (ClutterActor *actor, gulong mode, guint duration, const gchar *first_property_name, ...) G_GNUC_NULL_TERMINATED; -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED ClutterAnimation * clutter_actor_animate_with_timeline (ClutterActor *actor, gulong mode, ClutterTimeline *timeline, const gchar *first_property_name, ...) G_GNUC_NULL_TERMINATED; -CLUTTER_DEPRECATED_IN_1_12 -ClutterAnimation * clutter_actor_animatev (ClutterActor *actor, - gulong mode, - guint duration, - gint n_properties, - const gchar * const properties[], - const GValue *values); -CLUTTER_DEPRECATED_IN_1_12 -ClutterAnimation * clutter_actor_animate_with_timelinev (ClutterActor *actor, - gulong mode, - ClutterTimeline *timeline, - gint n_properties, - const gchar * const properties[], - const GValue *values); -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_animate_with_timeline) -ClutterAnimation * clutter_actor_animate_with_alpha (ClutterActor *actor, - ClutterAlpha *alpha, - const gchar *first_property_name, - ...) G_GNUC_NULL_TERMINATED; -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_animate_with_timelinev) -ClutterAnimation * clutter_actor_animate_with_alphav (ClutterActor *actor, - ClutterAlpha *alpha, - gint n_properties, - const gchar * const properties[], - const GValue *values); - -CLUTTER_DEPRECATED_IN_1_12 -ClutterAnimation * clutter_actor_get_animation (ClutterActor *actor); -CLUTTER_DEPRECATED_IN_1_12 -void clutter_actor_detach_animation (ClutterActor *actor); G_END_DECLS diff --git a/clutter/clutter/deprecated/clutter-animator.c b/clutter/clutter/deprecated/clutter-animator.c deleted file mode 100644 index 80a3836e5..000000000 --- a/clutter/clutter/deprecated/clutter-animator.c +++ /dev/null @@ -1,2166 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Øyvind Kolås - */ - -/** - * SECTION:clutter-animator - * @short_description: Multi-actor tweener - * @See_Also: #ClutterAnimatable, #ClutterInterval, #ClutterAlpha, - * #ClutterTimeline - * - * #ClutterAnimator is an object providing declarative animations for - * #GObject properties belonging to one or more #GObjects to - * #ClutterIntervals. - * - * #ClutterAnimator is used to build and describe complex animations - * in terms of "key frames". #ClutterAnimator is meant to be used - * through the #ClutterScript definition format, but it comes with a - * convenience C API. - * - * #ClutterAnimator is available since Clutter 1.2 - * - * #ClutterAnimator has been deprecated in Clutter 1.12. If you - * want to combine multiple transitions using key frames, use - * #ClutterKeyframeTransition and #ClutterTransitionGroup instead. - * - * ## Key Frames - * - * Every animation handled by a #ClutterAnimator can be - * described in terms of "key frames". For each #GObject property - * there can be multiple key frames, each one defined by the end - * value for the property to be computed starting from the current - * value to a specific point in time, using a given easing - * mode. - * - * The point in time is defined using a value representing - * the progress in the normalized interval of [ 0, 1 ]. This maps - * the value returned by clutter_timeline_get_duration(). - * - * ## ClutterAnimator description for ClutterScript - * - * #ClutterAnimator defines a custom "properties" key - * which allows describing the key frames for objects as - * an array of key frames. - * - * The `properties` array has the following syntax: - * - * |[ - * { - * "properties" : [ - * { - * "object" : object_id - * "name" : property_name - * "ease-in" : true_or_false - * "interpolation" : interpolation_value - * "keys" : [ - * [ progress, easing_mode, final_value ] - * ] - * ] - * } - * ]| - * - * The following JSON fragment defines a #ClutterAnimator - * with the duration of 1 second and operating on the x and y - * properties of a #ClutterActor named "rect-01", with two frames - * for each property. The first frame will linearly move the actor - * from its current position to the 100, 100 position in 20 percent - * of the duration of the animation; the second will using a cubic - * easing to move the actor to the 200, 200 coordinates. - * - * |[ - * { - * "type" : "ClutterAnimator", - * "duration" : 1000, - * "properties" : [ - * { - * "object" : "rect-01", - * "name" : "x", - * "ease-in" : true, - * "keys" : [ - * [ 0.2, "linear", 100.0 ], - * [ 1.0, "easeOutCubic", 200.0 ] - * ] - * }, - * { - * "object" : "rect-01", - * "name" : "y", - * "ease-in" : true, - * "keys" : [ - * [ 0.2, "linear", 100.0 ], - * [ 1.0, "easeOutCubic", 200.0 ] - * ] - * } - * ] - * } - * ]| - */ - -#ifdef HAVE_CONFIG_H -#include "clutter-build-config.h" -#endif - -#include -#include - -#include - -#define CLUTTER_DISABLE_DEPRECATION_WARNINGS - -#include "clutter-animator.h" - -#include "clutter-alpha.h" -#include "clutter-debug.h" -#include "clutter-enum-types.h" -#include "clutter-interval.h" -#include "clutter-private.h" -#include "clutter-script-private.h" -#include "clutter-scriptable.h" - -/* progress values varying by less than this are considered equal */ -#define PROGRESS_EPSILON 0.00001 - -struct _ClutterAnimatorPrivate -{ - ClutterTimeline *timeline; - ClutterTimeline *slave_timeline; - - GList *score; - - GHashTable *properties; -}; - -struct _ClutterAnimatorKey -{ - GObject *object; - const gchar *property_name; - guint mode; - - GValue value; - - /* normalized progress, between 0.0 and 1.0 */ - gdouble progress; - - /* back-pointer to the animator which owns the key */ - ClutterAnimator *animator; - - /* interpolation mode */ - ClutterInterpolation interpolation; - - /* ease from the current object state into the animation when it starts */ - guint ease_in : 1; - - /* This key is already being destroyed and shouldn't - * trigger additional weak unrefs - */ - guint is_inert : 1; - - gint ref_count; -}; - -enum -{ - PROP_0, - - PROP_DURATION, - PROP_TIMELINE, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST]; - -static void clutter_scriptable_init (ClutterScriptableIface *iface); - -G_DEFINE_TYPE_WITH_CODE (ClutterAnimator, - clutter_animator, - G_TYPE_OBJECT, - G_ADD_PRIVATE (ClutterAnimator) - G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_SCRIPTABLE, - clutter_scriptable_init)); -/** - * clutter_animator_new: - * - * Creates a new #ClutterAnimator instance - * - * Return value: a new #ClutterAnimator. - * - * Since: 1.2 - * - * Deprecated: 1.12: Use #ClutterKeyframeTransition instead - */ -ClutterAnimator * -clutter_animator_new (void) -{ - return g_object_new (CLUTTER_TYPE_ANIMATOR, NULL); -} - -/***/ - -typedef struct _PropObjectKey { - GObject *object; - const gchar *property_name; - guint mode; - gdouble progress; -} PropObjectKey; - -/* Iterator that walks the keys of a property*/ -typedef struct _PropertyIter { - PropObjectKey *key; - ClutterInterval *interval; - ClutterAlpha *alpha; - - GList *current; - - gdouble start; /* the progress of current */ - gdouble end; /* until which progress it is valid */ - ClutterInterpolation interpolation; - - guint ease_in : 1; -} PropertyIter; - -static PropObjectKey * -prop_actor_key_new (GObject *object, - const gchar *property_name) -{ - PropObjectKey *key = g_slice_new0 (PropObjectKey); - - key->object = object; - key->property_name = g_intern_string (property_name); - - return key; -} - -static void -prop_actor_key_free (gpointer key) -{ - if (key != NULL) - g_slice_free (PropObjectKey, key); -} - -static void -property_iter_free (gpointer key) -{ - if (key != NULL) - { - PropertyIter *property_iter = key; - - g_object_unref (property_iter->interval); - g_object_unref (property_iter->alpha); - - g_slice_free (PropertyIter, property_iter); - } -} - -static PropertyIter * -property_iter_new (ClutterAnimator *animator, - PropObjectKey *key, - GType type) -{ - ClutterAnimatorPrivate *priv = animator->priv; - PropertyIter *property_iter = g_slice_new (PropertyIter); - ClutterInterval *interval = g_object_new (CLUTTER_TYPE_INTERVAL, - "value-type", type, - NULL); - - /* we own this interval */ - g_object_ref_sink (interval); - - property_iter->interval = interval; - property_iter->key = key; - property_iter->alpha = clutter_alpha_new (); - clutter_alpha_set_timeline (property_iter->alpha, priv->slave_timeline); - - /* as well as the alpha */ - g_object_ref_sink (property_iter->alpha); - - return property_iter; -} - -static guint -prop_actor_hash (gconstpointer value) -{ - const PropObjectKey *info = value; - - return GPOINTER_TO_INT (info->property_name) - ^ GPOINTER_TO_INT (info->object); -} - -static gboolean -prop_actor_equal (gconstpointer a, gconstpointer b) -{ - const PropObjectKey *infoa = a; - const PropObjectKey *infob = b; - - /* property name strings are interned so we can just compare pointers */ - if (infoa->object == infob->object && - (infoa->property_name == infob->property_name)) - return TRUE; - - return FALSE; -} - -static gint -sort_actor_prop_progress_func (gconstpointer a, - gconstpointer b) -{ - const ClutterAnimatorKey *pa = a; - const ClutterAnimatorKey *pb = b; - - if (pa->object == pb->object) - { - gint pdiff = pb->property_name - pa->property_name; - - if (pdiff) - return pdiff; - - if (fabs (pa->progress - pb->progress) < PROGRESS_EPSILON) - return 0; - - if (pa->progress > pb->progress) - return 1; - - return -1; - } - - return pa->object - pb->object; -} - -static gint -sort_actor_prop_func (gconstpointer a, - gconstpointer b) -{ - const ClutterAnimatorKey *pa = a; - const ClutterAnimatorKey *pb = b; - - if (pa->object == pb->object) - return pa->property_name - pb->property_name; - - return pa->object - pb->object; -} - -static void -clutter_animator_remove_key_internal (ClutterAnimator *animator, - GObject *object, - const gchar *property_name, - gdouble progress, - gboolean is_inert); - -static void -object_disappeared (gpointer data, - GObject *where_the_object_was) -{ - clutter_animator_remove_key_internal (data, where_the_object_was, NULL, -1.0, - TRUE); -} - -static ClutterAnimatorKey * -clutter_animator_key_new (ClutterAnimator *animator, - GObject *object, - const gchar *property_name, - gdouble progress, - guint mode) -{ - ClutterAnimatorKey *animator_key; - - animator_key = g_slice_new (ClutterAnimatorKey); - - animator_key->ref_count = 1; - animator_key->animator = animator; - animator_key->object = object; - animator_key->mode = mode; - memset (&(animator_key->value), 0, sizeof (GValue)); - animator_key->progress = progress; - animator_key->property_name = g_intern_string (property_name); - animator_key->interpolation = CLUTTER_INTERPOLATION_LINEAR; - animator_key->ease_in = FALSE; - animator_key->is_inert = FALSE; - - /* keep a weak reference on the animator, so that we can release the - * back-pointer when needed - */ - g_object_weak_ref (object, object_disappeared, - animator_key->animator); - - return animator_key; -} - -static gpointer -clutter_animator_key_copy (gpointer boxed) -{ - ClutterAnimatorKey *key = boxed; - - if (key != NULL) - key->ref_count += 1; - - return key; -} - -static void -clutter_animator_key_free (gpointer boxed) -{ - ClutterAnimatorKey *key = boxed; - - if (key == NULL) - return; - - key->ref_count -= 1; - - if (key->ref_count > 0) - return; - - if (!key->is_inert) - g_object_weak_unref (key->object, object_disappeared, key->animator); - - g_slice_free (ClutterAnimatorKey, key); -} - -static void -clutter_animator_dispose (GObject *object) -{ - ClutterAnimator *animator = CLUTTER_ANIMATOR (object); - ClutterAnimatorPrivate *priv = animator->priv; - - clutter_animator_set_timeline (animator, NULL); - g_object_unref (priv->slave_timeline); - - G_OBJECT_CLASS (clutter_animator_parent_class)->dispose (object); -} - -static void -clutter_animator_finalize (GObject *object) -{ - ClutterAnimator *animator = CLUTTER_ANIMATOR (object); - ClutterAnimatorPrivate *priv = animator->priv; - - g_list_foreach (priv->score, (GFunc) clutter_animator_key_free, NULL); - g_list_free (priv->score); - priv->score = NULL; - - g_hash_table_destroy (priv->properties); - - G_OBJECT_CLASS (clutter_animator_parent_class)->finalize (object); -} - -/* XXX: this is copied and slightly modified from glib, - * there is only one way to do this. */ -static GList * -list_find_custom_reverse (GList *list, - gconstpointer data, - GCompareFunc func) -{ - while (list) - { - if (! func (list->data, data)) - return list; - - list = list->prev; - } - - return NULL; -} - -/* Ensures that the interval provided by the animator is correct - * for the requested progress value. - */ -static void -animation_animator_ensure_animator (ClutterAnimator *animator, - PropertyIter *property_iter, - PropObjectKey *key, - gdouble progress) -{ - - if (progress > property_iter->end) - { - while (progress > property_iter->end) - { - ClutterAnimatorKey *initial_key, *next_key; - GList *initial, *next; - - initial = g_list_find_custom (property_iter->current->next, - key, - sort_actor_prop_func); - - if (initial) - { - initial_key = initial->data; - - clutter_interval_set_initial_value (property_iter->interval, - &initial_key->value); - property_iter->current = initial; - property_iter->start = initial_key->progress; - - next = g_list_find_custom (initial->next, - key, - sort_actor_prop_func); - if (next) - { - next_key = next->data; - - property_iter->end = next_key->progress; - } - else - { - next_key = initial_key; - - property_iter->end = property_iter->start; - } - - clutter_interval_set_final_value (property_iter->interval, - &next_key->value); - - if ((clutter_alpha_get_mode (property_iter->alpha) != next_key->mode)) - clutter_alpha_set_mode (property_iter->alpha, next_key->mode); - } - else /* no relevant interval */ - { - ClutterAnimatorKey *current_key = property_iter->current->data; - clutter_interval_set_initial_value (property_iter->interval, - ¤t_key->value); - clutter_interval_set_final_value (property_iter->interval, - ¤t_key->value); - break; - } - } - } - else if (progress < property_iter->start) - { - while (progress < property_iter->start) - { - ClutterAnimatorKey *initial_key, *next_key; - GList *initial; - GList *old = property_iter->current; - - initial = list_find_custom_reverse (property_iter->current->prev, - key, - sort_actor_prop_func); - - if (initial) - { - initial_key = initial->data; - - clutter_interval_set_initial_value (property_iter->interval, - &initial_key->value); - property_iter->current = initial; - property_iter->end = property_iter->start; - property_iter->start = initial_key->progress; - - if (old) - { - next_key = old->data; - - property_iter->end = next_key->progress; - } - else - { - next_key = initial_key; - - property_iter->end = 1.0; - } - - clutter_interval_set_final_value (property_iter->interval, - &next_key->value); - if ((clutter_alpha_get_mode (property_iter->alpha) != next_key->mode)) - clutter_alpha_set_mode (property_iter->alpha, next_key->mode); - } - else - break; - } - } -} - -/* XXX - this might be useful as an internal function exposed somewhere */ -static gdouble -cubic_interpolation (const gdouble dx, - const gdouble prev, - const gdouble j, - const gdouble next, - const gdouble nextnext) -{ - return (((( - prev + 3 * j - 3 * next + nextnext ) * dx + - ( 2 * prev - 5 * j + 4 * next - nextnext ) ) * dx + - ( - prev + next ) ) * dx + (j + j) ) / 2.0; -} - -/* try to get a floating point key value from a key for a property, - * failing use the closest key in that direction or the starting point. - */ -static gfloat -list_try_get_rel (GList *list, - gint count) -{ - ClutterAnimatorKey *key; - GList *iter = list; - GList *best = list; - - if (count > 0) - { - while (count -- && iter != NULL) - { - iter = g_list_find_custom (iter->next, list->data, - sort_actor_prop_func); - if (iter != NULL) - best = iter; - } - } - else - { - while (count ++ < 0 && iter != NULL) - { - iter = list_find_custom_reverse (iter->prev, list->data, - sort_actor_prop_func); - if (iter != NULL) - best = iter; - } - } - - if (best != NULL && best->data != NULL) - { - key = best->data; - - return g_value_get_float (&(key->value)); - } - - return 0; -} - -static void -animation_animator_new_frame (ClutterTimeline *timeline, - gint msecs, - ClutterAnimator *animator) -{ - gdouble progress; - GHashTableIter iter; - gpointer key, value; - - progress = 1.0 * msecs / clutter_timeline_get_duration (timeline); - - /* for each property that is managed figure out the GValue to set, - * avoid creating new ClutterInterval's for each interval crossed - */ - g_hash_table_iter_init (&iter, animator->priv->properties); - - key = value = NULL; - while (g_hash_table_iter_next (&iter, &key, &value)) - { - PropObjectKey *prop_actor_key = key; - PropertyIter *property_iter = value; - ClutterAnimatorKey *start_key; - gdouble sub_progress; - - animation_animator_ensure_animator (animator, property_iter, - key, - progress); - start_key = property_iter->current->data; - - if (property_iter->end == property_iter->start) - sub_progress = 0.0; /* we're past the final value */ - else - sub_progress = (progress - property_iter->start) - / (property_iter->end - property_iter->start); - - /* only change values if we active (delayed start) */ - if (sub_progress >= 0.0 && sub_progress <= 1.0) - { - GValue tmp_value = G_VALUE_INIT; - GType int_type; - - g_value_init (&tmp_value, G_VALUE_TYPE (&start_key->value)); - - clutter_timeline_advance (animator->priv->slave_timeline, - sub_progress * 10000); - - sub_progress = clutter_alpha_get_alpha (property_iter->alpha); - int_type = clutter_interval_get_value_type (property_iter->interval); - - if (property_iter->interpolation == CLUTTER_INTERPOLATION_CUBIC && - int_type == G_TYPE_FLOAT) - { - gdouble prev, current, next, nextnext; - gdouble res; - - if ((property_iter->ease_in == FALSE || - (property_iter->ease_in && - list_find_custom_reverse (property_iter->current->prev, - property_iter->current->data, - sort_actor_prop_func)))) - { - current = g_value_get_float (&start_key->value); - prev = list_try_get_rel (property_iter->current, -1); - } - else - { - /* interpolated and easing in */ - clutter_interval_get_initial_value (property_iter->interval, - &tmp_value); - prev = current = g_value_get_float (&tmp_value); - } - - next = list_try_get_rel (property_iter->current, 1); - nextnext = list_try_get_rel (property_iter->current, 2); - res = cubic_interpolation (sub_progress, prev, current, next, - nextnext); - - g_value_set_float (&tmp_value, res); - } - else - clutter_interval_compute_value (property_iter->interval, - sub_progress, - &tmp_value); - - g_object_set_property (prop_actor_key->object, - prop_actor_key->property_name, - &tmp_value); - - g_value_unset (&tmp_value); - } - } -} - -static void -animation_animator_started (ClutterTimeline *timeline, - ClutterAnimator *animator) -{ - GList *k; - - /* Ensure that animators exist for all involved properties */ - for (k = animator->priv->score; k != NULL; k = k->next) - { - ClutterAnimatorKey *key = k->data; - PropertyIter *property_iter; - PropObjectKey *prop_actor_key; - - prop_actor_key = prop_actor_key_new (key->object, key->property_name); - property_iter = g_hash_table_lookup (animator->priv->properties, - prop_actor_key); - if (property_iter) - { - prop_actor_key_free (prop_actor_key); - } - else - { - GObjectClass *klass = G_OBJECT_GET_CLASS (key->object); - GParamSpec *pspec; - - pspec = g_object_class_find_property (klass, key->property_name); - - property_iter = property_iter_new (animator, prop_actor_key, - G_PARAM_SPEC_VALUE_TYPE (pspec)); - g_hash_table_insert (animator->priv->properties, - prop_actor_key, - property_iter); - } - } - - /* initialize animator with initial list pointers */ - { - GHashTableIter iter; - gpointer key, value; - - g_hash_table_iter_init (&iter, animator->priv->properties); - while (g_hash_table_iter_next (&iter, &key, &value)) - { - PropertyIter *property_iter = value; - ClutterAnimatorKey *initial_key, *next_key; - GList *initial; - GList *next; - - initial = g_list_find_custom (animator->priv->score, - key, - sort_actor_prop_func); - g_assert (initial != NULL); - initial_key = initial->data; - clutter_interval_set_initial_value (property_iter->interval, - &initial_key->value); - - property_iter->current = initial; - property_iter->start = initial_key->progress; - property_iter->ease_in = initial_key->ease_in; - property_iter->interpolation = initial_key->interpolation; - - if (property_iter->ease_in) - { - GValue tmp_value = G_VALUE_INIT; - GType int_type; - - int_type = clutter_interval_get_value_type (property_iter->interval); - g_value_init (&tmp_value, int_type); - - g_object_get_property (initial_key->object, - initial_key->property_name, - &tmp_value); - - clutter_interval_set_initial_value (property_iter->interval, - &tmp_value); - - g_value_unset (&tmp_value); - } - - next = g_list_find_custom (initial->next, key, sort_actor_prop_func); - if (next) - { - next_key = next->data; - property_iter->end = next_key->progress; - } - else - { - next_key = initial_key; - property_iter->end = 1.0; - } - - clutter_interval_set_final_value (property_iter->interval, - &next_key->value); - if ((clutter_alpha_get_mode (property_iter->alpha) != next_key->mode)) - clutter_alpha_set_mode (property_iter->alpha, next_key->mode); - } - } -} - -/** - * clutter_animator_compute_value: - * @animator: a #ClutterAnimator - * @object: a #GObject - * @property_name: the name of the property on object to check - * @progress: a value between 0.0 and 1.0 - * @value: an initialized value to store the computed result - * - * Compute the value for a managed property at a given progress. - * - * If the property is an ease-in property, the current value of the property - * on the object will be used as the starting point for computation. - * - * Return value: %TRUE if the computation yields has a value, otherwise (when - * an error occurs or the progress is before any of the keys) %FALSE is - * returned and the #GValue is left untouched - * - * Since: 1.2 - * Deprecated: 1.12: Use #ClutterKeyframeTransition instead - */ -gboolean -clutter_animator_compute_value (ClutterAnimator *animator, - GObject *object, - const gchar *property_name, - gdouble progress, - GValue *value) -{ - ClutterAnimatorPrivate *priv; - ClutterAnimatorKey key; - ClutterAnimatorKey *previous; - ClutterAnimatorKey *next = NULL; - GParamSpec *pspec; - GList *initial_l; - GList *previous_l; - GList *next_l; - gboolean ease_in; - ClutterInterpolation interpolation; - - g_return_val_if_fail (CLUTTER_IS_ANIMATOR (animator), FALSE); - g_return_val_if_fail (G_IS_OBJECT (object), FALSE); - g_return_val_if_fail (property_name, FALSE); - g_return_val_if_fail (value, FALSE); - - priv = animator->priv; - - ease_in = clutter_animator_property_get_ease_in (animator, object, - property_name); - interpolation = clutter_animator_property_get_interpolation (animator, - object, property_name); - - property_name = g_intern_string (property_name); - - pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), - property_name); - - key.object = object; - key.property_name = property_name; - - initial_l = g_list_find_custom (animator->priv->score, &key, - sort_actor_prop_func); - if (initial_l == NULL) - return FALSE; - - /* first find the interval we belong in, that is the first interval - * existing between keys - */ - - for (previous_l = initial_l, next_l = previous_l->next ; - previous_l->next ; - previous_l = previous_l->next, next_l = previous_l->next) - { - previous = previous_l->data; - if (next_l) - { - next = next_l->data; - if (next->object != object || - next->property_name != property_name) - { - next_l = NULL; - next = NULL; - } - } - else - next = NULL; - - if (progress < previous->progress) - { - /* we are before the defined values */ - - /* value has not been set */ - return FALSE; - } - - if (!next && previous->progress <= progress) - { - /* we only had one key for this object/property */ - /* and we are past it, that is our value */ - g_value_copy (&previous->value, value); - return TRUE; - } - - if (next && next->progress >= progress) - { - ClutterInterval *interval; - ClutterAlpha *alpha; - - gdouble sub_progress = (progress - previous->progress) - / (next->progress - previous->progress); - /* this should be our interval */ - interval = g_object_new (CLUTTER_TYPE_INTERVAL, - "value-type", pspec->value_type, - NULL); - - if (ease_in && previous_l == initial_l) - { - GValue tmp_value = {0, }; - g_value_init (&tmp_value, pspec->value_type); - g_object_get_property (object, property_name, &tmp_value); - clutter_interval_set_initial_value (interval, &tmp_value); - g_value_unset (&tmp_value); - } - else - clutter_interval_set_initial_value (interval, &previous->value); - - clutter_interval_set_final_value (interval, &next->value); - - alpha = clutter_alpha_new (); - clutter_alpha_set_timeline (alpha, priv->slave_timeline); - clutter_alpha_set_mode (alpha, next->mode); - - clutter_timeline_advance (priv->slave_timeline, - sub_progress * 10000); - sub_progress = clutter_alpha_get_alpha (alpha); - - if (interpolation == CLUTTER_INTERPOLATION_CUBIC && - pspec->value_type == G_TYPE_FLOAT) - { - gdouble prev, current, nextv, nextnext; - gdouble res; - - if ((ease_in == FALSE || - (ease_in && - list_find_custom_reverse (previous_l->prev, - previous_l->data, - sort_actor_prop_func)))) - { - current = g_value_get_float (&previous->value); - prev = list_try_get_rel (previous_l, -1); - } - else - { - /* interpolated and easing in */ - GValue tmp_value = {0, }; - g_value_init (&tmp_value, pspec->value_type); - clutter_interval_get_initial_value (interval, - &tmp_value); - prev = current = g_value_get_float (&tmp_value); - g_value_unset (&tmp_value); - } - - nextv = list_try_get_rel (previous_l, 1); - nextnext = list_try_get_rel (previous_l, 2); - res = cubic_interpolation (sub_progress, prev, current, nextv, - nextnext); - g_value_set_float (value, res); - } - else - clutter_interval_compute_value (interval, - sub_progress, - value); - - g_object_ref_sink (interval); - g_object_unref (interval); - g_object_ref_sink (alpha); - g_object_unref (alpha); - - return TRUE; - } - - } - - if (!next) - return FALSE; - - /* We're at, or past the end, use the last value */ - g_value_copy (&next->value, value); - - return TRUE; -} - - -/** - * clutter_animator_set_timeline: - * @animator: a #ClutterAnimator - * @timeline: a #ClutterTimeline - * - * Sets an external timeline that will be used for driving the animation - * - * Since: 1.2 - * Deprecated: 1.12: Use #ClutterKeyframeTransition instead - */ -void -clutter_animator_set_timeline (ClutterAnimator *animator, - ClutterTimeline *timeline) -{ - ClutterAnimatorPrivate *priv; - - g_return_if_fail (CLUTTER_IS_ANIMATOR (animator)); - - priv = animator->priv; - - if (priv->timeline != NULL) - { - g_signal_handlers_disconnect_by_func (priv->timeline, - animation_animator_new_frame, - animator); - g_signal_handlers_disconnect_by_func (priv->timeline, - animation_animator_started, - animator); - g_object_unref (priv->timeline); - } - - priv->timeline = timeline; - if (timeline != NULL) - { - g_object_ref (priv->timeline); - - g_signal_connect (priv->timeline, "new-frame", - G_CALLBACK (animation_animator_new_frame), - animator); - g_signal_connect (priv->timeline, "started", - G_CALLBACK (animation_animator_started), - animator); - } -} - -/** - * clutter_animator_get_timeline: - * @animator: a #ClutterAnimator - * - * Get the timeline hooked up for driving the #ClutterAnimator - * - * Return value: (transfer none): the #ClutterTimeline that drives the animator - * - * Since: 1.2 - * Deprecated: 1.12: Use #ClutterKeyframeTransition instead - */ -ClutterTimeline * -clutter_animator_get_timeline (ClutterAnimator *animator) -{ - g_return_val_if_fail (CLUTTER_IS_ANIMATOR (animator), NULL); - return animator->priv->timeline; -} - -/** - * clutter_animator_start: - * @animator: a #ClutterAnimator - * - * Start the ClutterAnimator, this is a thin wrapper that rewinds - * and starts the animators current timeline. - * - * Return value: (transfer none): the #ClutterTimeline that drives - * the animator. The returned timeline is owned by the #ClutterAnimator - * and it should not be unreferenced - * - * Since: 1.2 - * Deprecated: 1.12: Use #ClutterKeyframeTransition instead - */ -ClutterTimeline * -clutter_animator_start (ClutterAnimator *animator) -{ - ClutterAnimatorPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_ANIMATOR (animator), NULL); - - priv = animator->priv; - - clutter_timeline_rewind (priv->timeline); - clutter_timeline_start (priv->timeline); - - return priv->timeline; -} - -/** - * clutter_animator_set_duration: - * @animator: a #ClutterAnimator - * @duration: milliseconds a run of the animator should last. - * - * Runs the timeline of the #ClutterAnimator with a duration in msecs - * as specified. - * - * Since: 1.2 - * Deprecated: 1.12: Use #ClutterKeyframeTransition instead - */ -void -clutter_animator_set_duration (ClutterAnimator *animator, - guint duration) -{ - g_return_if_fail (CLUTTER_IS_ANIMATOR (animator)); - - clutter_timeline_set_duration (animator->priv->timeline, duration); -} - -/** - * clutter_animator_get_duration: - * @animator: a #ClutterAnimator - * - * Retrieves the current duration of an animator - * - * Return value: the duration of the animation, in milliseconds - * - * Since: 1.2 - * Deprecated: 1.12: Use #ClutterKeyframeTransition instead - */ -guint -clutter_animator_get_duration (ClutterAnimator *animator) -{ - g_return_val_if_fail (CLUTTER_IS_ANIMATOR (animator), 0); - - return clutter_timeline_get_duration (animator->priv->timeline); -} - -/** - * clutter_animator_set: - * @animator: a #ClutterAnimator - * @first_object: a #GObject - * @first_property_name: the property to specify a key for - * @first_mode: the id of the alpha function to use - * @first_progress: at which stage of the animation this value applies; the - * range is a normalized floating point value between 0 and 1 - * @...: the value first_property_name should have for first_object - * at first_progress, followed by more (object, property_name, mode, - * progress, value) tuples, followed by %NULL - * - * Adds multiple keys to a #ClutterAnimator, specifying the value a given - * property should have at a given progress of the animation. The mode - * specified is the mode used when going to this key from the previous key of - * the @property_name - * - * If a given (object, property, progress) tuple already exist the mode and - * value will be replaced with the new values. - * - * Since: 1.2 - * Deprecated: 1.12: Use #ClutterKeyframeTransition instead - */ -void -clutter_animator_set (ClutterAnimator *animator, - gpointer first_object, - const gchar *first_property_name, - guint first_mode, - gdouble first_progress, - ...) -{ - GObject *object; - const gchar *property_name; - guint mode; - gdouble progress; - va_list args; - - g_return_if_fail (CLUTTER_IS_ANIMATOR (animator)); - - object = first_object; - property_name = first_property_name; - - g_return_if_fail (object); - g_return_if_fail (property_name); - - mode = first_mode; - progress = first_progress; - - va_start (args, first_progress); - - while (object != NULL) - { - GParamSpec *pspec; - GObjectClass *klass; - GValue value = G_VALUE_INIT; - gchar *error = NULL; - - klass = G_OBJECT_GET_CLASS (object); - pspec = g_object_class_find_property (klass, property_name); - - if (!pspec) - { - g_warning ("Cannot bind property '%s': object of type '%s' " - "do not have this property", - property_name, G_OBJECT_TYPE_NAME (object)); - break; - } - - G_VALUE_COLLECT_INIT (&value, G_PARAM_SPEC_VALUE_TYPE (pspec), - args, 0, - &error); - - if (error) - { - g_warning ("%s: %s", G_STRLOC, error); - free (error); - break; - } - - clutter_animator_set_key (animator, - object, - property_name, - mode, - progress, - &value); - - object= va_arg (args, GObject *); - if (object) - { - property_name = va_arg (args, gchar*); - if (!property_name) - { - g_warning ("%s: expected a property name", G_STRLOC); - break; - } - mode = va_arg (args, guint); - progress = va_arg (args, gdouble); - } - } - - va_end (args); -} - -static inline void -clutter_animator_set_key_internal (ClutterAnimator *animator, - ClutterAnimatorKey *key) -{ - ClutterAnimatorPrivate *priv = animator->priv; - GList *old_item; - GList *initial_item; - ClutterAnimatorKey *initial_key = NULL; - - if ((initial_item = g_list_find_custom (animator->priv->score, key, - sort_actor_prop_func))) - initial_key = initial_item->data; - - /* The first key for a property specifies ease-in and interpolation, - * if we are replacing; or becoming a new first key we should - * inherit the old flags. - */ - if (initial_key && - initial_key->progress >= key->progress) - { - key->interpolation = initial_key->interpolation; - key->ease_in = initial_key->ease_in; - } - - old_item = g_list_find_custom (priv->score, key, - sort_actor_prop_progress_func); - - /* replace the key if we already have a similar one */ - if (old_item != NULL) - { - ClutterAnimatorKey *old_key = old_item->data; - - clutter_animator_key_free (old_key); - - priv->score = g_list_remove (priv->score, old_key); - } - - priv->score = g_list_insert_sorted (priv->score, key, - sort_actor_prop_progress_func); - - /* if the animator is already running reinitialize internal iterators */ - if (clutter_timeline_is_playing (priv->timeline)) - animation_animator_started (priv->timeline, animator); -} - -/** - * clutter_animator_set_key: - * @animator: a #ClutterAnimator - * @object: a #GObject - * @property_name: the property to specify a key for - * @mode: the id of the alpha function to use - * @progress: the normalized range at which stage of the animation this - * value applies - * @value: the value property_name should have at progress. - * - * Sets a single key in the #ClutterAnimator for the @property_name of - * @object at @progress. - * - * See also: clutter_animator_set() - * - * Return value: (transfer none): The animator instance - * - * Since: 1.2 - * Deprecated: 1.12: Use #ClutterKeyframeTransition instead - */ -ClutterAnimator * -clutter_animator_set_key (ClutterAnimator *animator, - GObject *object, - const gchar *property_name, - guint mode, - gdouble progress, - const GValue *value) -{ - ClutterAnimatorKey *animator_key; - - g_return_val_if_fail (CLUTTER_IS_ANIMATOR (animator), NULL); - g_return_val_if_fail (G_IS_OBJECT (object), NULL); - g_return_val_if_fail (property_name, NULL); - g_return_val_if_fail (value, NULL); - - property_name = g_intern_string (property_name); - - animator_key = clutter_animator_key_new (animator, - object, property_name, - progress, - mode); - - g_value_init (&animator_key->value, G_VALUE_TYPE (value)); - g_value_copy (value, &animator_key->value); - - clutter_animator_set_key_internal (animator, animator_key); - - return animator; -} - -/** - * clutter_animator_get_keys: - * @animator: a #ClutterAnimator instance - * @object: (allow-none): a #GObject to search for, or %NULL for all objects - * @property_name: (allow-none): a specific property name to query for, - * or %NULL for all properties - * @progress: a specific progress to search for, or a negative value for all - * progresses - * - * Returns a list of pointers to opaque structures with accessor functions - * that describe the keys added to an animator. - * - * Return value: (transfer container) (element-type Clutter.AnimatorKey): a - * list of #ClutterAnimatorKeys; the contents of the list are owned - * by the #ClutterAnimator, but you should free the returned list when done, - * using g_list_free() - * - * Since: 1.2 - * Deprecated: 1.12: Use #ClutterKeyframeTransition instead - */ -GList * -clutter_animator_get_keys (ClutterAnimator *animator, - GObject *object, - const gchar *property_name, - gdouble progress) -{ - GList *keys = NULL; - GList *k; - - g_return_val_if_fail (CLUTTER_IS_ANIMATOR (animator), NULL); - g_return_val_if_fail (object == NULL || G_IS_OBJECT (object), NULL); - - property_name = g_intern_string (property_name); - - for (k = animator->priv->score; k; k = k->next) - { - ClutterAnimatorKey *key = k->data; - - if ((object == NULL || (object == key->object)) && - (property_name == NULL || (property_name == key->property_name)) && - (progress < 0 || fabs (progress - key->progress) < PROGRESS_EPSILON)) - { - keys = g_list_prepend (keys, key); - } - } - - return g_list_reverse (keys); -} - -static void -clutter_animator_remove_key_internal (ClutterAnimator *animator, - GObject *object, - const gchar *property_name, - gdouble progress, - gboolean is_inert) -{ - ClutterAnimatorPrivate *priv; - GList *k; - - g_return_if_fail (CLUTTER_IS_ANIMATOR (animator)); - g_return_if_fail (object == NULL || G_IS_OBJECT (object)); - - property_name = g_intern_string (property_name); - - priv = animator->priv; - -again: - for (k = priv->score; k != NULL; k = k->next) - { - ClutterAnimatorKey *key = k->data; - - if ((object == NULL || (object == key->object)) && - (property_name == NULL || ((property_name == key->property_name))) && - (progress < 0 || fabs (progress - key->progress) < PROGRESS_EPSILON) - ) - { - ClutterAnimatorKey *prev_key = NULL; - key->is_inert = is_inert; - - - /* FIXME: non performant since we reiterate the list many times */ - - prev_key = k->prev ? k->prev->data : NULL; - - if (!prev_key || prev_key->object != key->object || - prev_key->property_name != key->property_name) - { /* We are removing the first key for a property ... */ - ClutterAnimatorKey *next_key = k->next ? k->next->data : NULL; - if (next_key && next_key->object == key->object && - next_key->property_name == key->property_name) - { - /* ... and there is a key of our own type following us, - * copy interpolation/ease_in flags to the new first key - */ - next_key->interpolation = key->interpolation; - next_key->ease_in = key->ease_in; - } - } - - clutter_animator_key_free (key); - priv->score = g_list_remove (priv->score, key); - goto again; - } - } - - /* clear off cached state for all properties, this is regenerated in a - * correct state by animation_animator_started - */ - g_hash_table_remove_all (priv->properties); - - /* if the animator is already running reinitialize internal iterators */ - if (priv->timeline != NULL && clutter_timeline_is_playing (priv->timeline)) - animation_animator_started (priv->timeline, animator); -} - -/** - * clutter_animator_remove_key: - * @animator: a #ClutterAnimator - * @object: (allow-none): a #GObject to search for, or %NULL for all - * @property_name: (allow-none): a specific property name to query for, - * or %NULL for all - * @progress: a specific progress to search for or a negative value - * for all - * - * Removes all keys matching the conditions specificed in the arguments. - * - * Since: 1.2 - * Deprecated: 1.12: Use #ClutterKeyframeTransition instead - */ -void -clutter_animator_remove_key (ClutterAnimator *animator, - GObject *object, - const gchar *property_name, - gdouble progress) -{ - clutter_animator_remove_key_internal (animator, object, property_name, - progress, FALSE); -} - - - - -typedef struct _ParseClosure { - ClutterAnimator *animator; - ClutterScript *script; - - GValue *value; - - gboolean result; -} ParseClosure; - -static ClutterInterpolation -resolve_interpolation (JsonNode *node) -{ - if ((JSON_NODE_TYPE (node) != JSON_NODE_VALUE)) - return CLUTTER_INTERPOLATION_LINEAR; - - if (json_node_get_value_type (node) == G_TYPE_INT64) - { - return json_node_get_int (node); - } - else if (json_node_get_value_type (node) == G_TYPE_STRING) - { - const gchar *str = json_node_get_string (node); - gboolean res; - gint enum_value; - - res = _clutter_script_enum_from_string (CLUTTER_TYPE_INTERPOLATION, - str, - &enum_value); - if (res) - return enum_value; - } - - return CLUTTER_INTERPOLATION_LINEAR; -} - -static void -parse_animator_property (JsonArray *array, - guint index_, - JsonNode *element, - gpointer data) -{ - ParseClosure *clos = data; - JsonObject *object; - JsonArray *keys; - GObject *gobject; - const gchar *id_, *pname; - GObjectClass *klass; - GParamSpec *pspec; - GSList *valid_keys = NULL; - GList *array_keys, *k; - ClutterInterpolation interpolation = CLUTTER_INTERPOLATION_LINEAR; - gboolean ease_in = FALSE; - - if (JSON_NODE_TYPE (element) != JSON_NODE_OBJECT) - { - g_warning ("The 'properties' member of a ClutterAnimator description " - "should be an array of objects, but the element %d of the " - "array is of type '%s'. The element will be ignored.", - index_, - json_node_type_name (element)); - return; - } - - object = json_node_get_object (element); - - if (!json_object_has_member (object, "object") || - !json_object_has_member (object, "name") || - !json_object_has_member (object, "keys")) - { - g_warning ("The property description at index %d is missing one of " - "the mandatory fields: object, name and keys", - index_); - return; - } - - id_ = json_object_get_string_member (object, "object"); - gobject = clutter_script_get_object (clos->script, id_); - if (gobject == NULL) - { - g_warning ("No object with id '%s' has been defined.", id_); - return; - } - - pname = json_object_get_string_member (object, "name"); - klass = G_OBJECT_GET_CLASS (gobject); - pspec = g_object_class_find_property (klass, pname); - if (pspec == NULL) - { - g_warning ("The object of type '%s' and name '%s' has no " - "property named '%s'", - G_OBJECT_TYPE_NAME (gobject), - id_, - pname); - return; - } - - if (json_object_has_member (object, "ease-in")) - ease_in = json_object_get_boolean_member (object, "ease-in"); - - if (json_object_has_member (object, "interpolation")) - { - JsonNode *node = json_object_get_member (object, "interpolation"); - - interpolation = resolve_interpolation (node); - } - - keys = json_object_get_array_member (object, "keys"); - if (keys == NULL) - { - g_warning ("The property description at index %d has an invalid " - "key field of type '%s' when an array was expected.", - index_, - json_node_type_name (json_object_get_member (object, "keys"))); - return; - } - - if (G_IS_VALUE (clos->value)) - valid_keys = g_slist_reverse (g_value_get_pointer (clos->value)); - else - g_value_init (clos->value, G_TYPE_POINTER); - - array_keys = json_array_get_elements (keys); - for (k = array_keys; k != NULL; k = k->next) - { - JsonNode *node = k->data; - JsonArray *key = json_node_get_array (node); - ClutterAnimatorKey *animator_key; - gdouble progress; - gulong mode; - gboolean res; - - progress = json_array_get_double_element (key, 0); - mode = _clutter_script_resolve_animation_mode (json_array_get_element (key, 1)); - - animator_key = clutter_animator_key_new (clos->animator, - gobject, - pname, - progress, - mode); - - res = _clutter_script_parse_node (clos->script, - &(animator_key->value), - pname, - json_array_get_element (key, 2), - pspec); - if (!res) - { - g_warning ("Unable to parse the key value for the " - "property '%s' (progress: %.2f) at index %d", - pname, - progress, - index_); - continue; - } - - animator_key->ease_in = ease_in; - animator_key->interpolation = interpolation; - - valid_keys = g_slist_prepend (valid_keys, animator_key); - } - - g_list_free (array_keys); - - g_value_set_pointer (clos->value, g_slist_reverse (valid_keys)); - - clos->result = TRUE; -} - -static gboolean -clutter_animator_parse_custom_node (ClutterScriptable *scriptable, - ClutterScript *script, - GValue *value, - const gchar *name, - JsonNode *node) -{ - ParseClosure parse_closure; - - if (strcmp (name, "properties") != 0) - return FALSE; - - if (JSON_NODE_TYPE (node) != JSON_NODE_ARRAY) - return FALSE; - - parse_closure.animator = CLUTTER_ANIMATOR (scriptable); - parse_closure.script = script; - parse_closure.value = value; - parse_closure.result = FALSE; - - json_array_foreach_element (json_node_get_array (node), - parse_animator_property, - &parse_closure); - - /* we return TRUE if we had at least one key parsed */ - - return parse_closure.result; -} - -static void -clutter_animator_set_custom_property (ClutterScriptable *scriptable, - ClutterScript *script, - const gchar *name, - const GValue *value) -{ - if (strcmp (name, "properties") == 0) - { - ClutterAnimator *animator = CLUTTER_ANIMATOR (scriptable); - GSList *keys = g_value_get_pointer (value); - GSList *k; - - for (k = keys; k != NULL; k = k->next) - clutter_animator_set_key_internal (animator, k->data); - - g_slist_free (keys); - } - else - g_object_set_property (G_OBJECT (scriptable), name, value); -} - -static void -clutter_scriptable_init (ClutterScriptableIface *iface) -{ - iface->parse_custom_node = clutter_animator_parse_custom_node; - iface->set_custom_property = clutter_animator_set_custom_property; -} - -static void -clutter_animator_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterAnimator *self = CLUTTER_ANIMATOR (gobject); - - switch (prop_id) - { - case PROP_DURATION: - clutter_animator_set_duration (self, g_value_get_uint (value)); - break; - - case PROP_TIMELINE: - clutter_animator_set_timeline (self, g_value_get_object (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_animator_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterAnimatorPrivate *priv = CLUTTER_ANIMATOR (gobject)->priv; - - switch (prop_id) - { - case PROP_DURATION: - g_value_set_uint (value, clutter_timeline_get_duration (priv->timeline)); - break; - - case PROP_TIMELINE: - g_value_set_object (value, priv->timeline); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_animator_class_init (ClutterAnimatorClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - gobject_class->set_property = clutter_animator_set_property; - gobject_class->get_property = clutter_animator_get_property; - gobject_class->dispose = clutter_animator_dispose; - gobject_class->finalize = clutter_animator_finalize; - - /** - * ClutterAnimator:duration: - * - * The duration of the #ClutterTimeline used by the #ClutterAnimator - * to drive the animation - * - * Since: 1.2 - * Deprecated: 1.12: Use #ClutterKeyframeTransition instead - */ - obj_props[PROP_DURATION] = - g_param_spec_uint ("duration", - P_("Duration"), - P_("The duration of the animation"), - 0, G_MAXUINT, - 2000, - CLUTTER_PARAM_READWRITE); - - /** - * ClutterAnimator:timeline: - * - * The #ClutterTimeline used by the #ClutterAnimator to drive the - * animation - * - * Since: 1.2 - * Deprecated: 1.12: Use #ClutterKeyframeTransition instead - */ - obj_props[PROP_TIMELINE] = - g_param_spec_object ("timeline", - P_("Timeline"), - P_("The timeline of the animation"), - CLUTTER_TYPE_TIMELINE, - CLUTTER_PARAM_READWRITE); - - g_object_class_install_properties (gobject_class, - PROP_LAST, - obj_props); -} - -static void -clutter_animator_init (ClutterAnimator *animator) -{ - ClutterAnimatorPrivate *priv; - ClutterTimeline *timeline; - - animator->priv = priv = clutter_animator_get_instance_private (animator); - - priv->properties = g_hash_table_new_full (prop_actor_hash, - prop_actor_equal, - prop_actor_key_free, - property_iter_free); - - timeline = clutter_timeline_new (2000); - clutter_animator_set_timeline (animator, timeline); - g_object_unref (timeline); - - priv->slave_timeline = clutter_timeline_new (10000); -} - - -/** - * clutter_animator_property_get_ease_in: - * @animator: a #ClutterAnimatorKey - * @object: a #GObject - * @property_name: the name of a property on object - * - * Checks if a property value is to be eased into the animation. - * - * Return value: %TRUE if the property is eased in - * - * Since: 1.2 - * Deprecated: 1.12: Use #ClutterKeyframeTransition instead - */ -gboolean -clutter_animator_property_get_ease_in (ClutterAnimator *animator, - GObject *object, - const gchar *property_name) -{ - ClutterAnimatorKey key, *initial_key; - GList *initial; - - g_return_val_if_fail (CLUTTER_IS_ANIMATOR (animator), FALSE); - g_return_val_if_fail (G_IS_OBJECT (object), FALSE); - g_return_val_if_fail (property_name, FALSE); - - key.object = object; - key.property_name = g_intern_string (property_name); - initial = g_list_find_custom (animator->priv->score, &key, - sort_actor_prop_func); - if (initial != NULL) - { - initial_key = initial->data; - - return initial_key->ease_in; - } - - return FALSE; -} - -/** - * clutter_animator_property_set_ease_in: - * @animator: a #ClutterAnimatorKey - * @object: a #GObject - * @property_name: the name of a property on object - * @ease_in: we are going to be easing in this property - * - * Sets whether a property value is to be eased into the animation. - * - * Since: 1.2 - * Deprecated: 1.12: Use #ClutterKeyframeTransition instead - */ -void -clutter_animator_property_set_ease_in (ClutterAnimator *animator, - GObject *object, - const gchar *property_name, - gboolean ease_in) -{ - ClutterAnimatorKey key, *initial_key; - GList *initial; - - g_return_if_fail (CLUTTER_IS_ANIMATOR (animator)); - g_return_if_fail (G_IS_OBJECT (object)); - g_return_if_fail (property_name); - - key.object = object; - key.property_name = g_intern_string (property_name); - initial = g_list_find_custom (animator->priv->score, &key, - sort_actor_prop_func); - if (initial) - { - initial_key = initial->data; - initial_key->ease_in = ease_in; - } - else - g_warning ("The animator has no object of type '%s' with a " - "property named '%s'", - G_OBJECT_TYPE_NAME (object), - property_name); -} - - -/** - * clutter_animator_property_get_interpolation: - * @animator: a #ClutterAnimatorKey - * @object: a #GObject - * @property_name: the name of a property on object - * - * Get the interpolation used by animator for a property on a particular - * object. - * - * Returns: a ClutterInterpolation value. - * Since: 1.2 - * Deprecated: 1.12: Use #ClutterKeyframeTransition instead - */ -ClutterInterpolation -clutter_animator_property_get_interpolation (ClutterAnimator *animator, - GObject *object, - const gchar *property_name) -{ - GList *initial; - ClutterAnimatorKey key, *initial_key; - - g_return_val_if_fail (CLUTTER_IS_ANIMATOR (animator), - CLUTTER_INTERPOLATION_LINEAR); - g_return_val_if_fail (G_IS_OBJECT (object), - CLUTTER_INTERPOLATION_LINEAR); - g_return_val_if_fail (property_name, - CLUTTER_INTERPOLATION_LINEAR); - - key.object = object; - key.property_name = g_intern_string (property_name); - initial = g_list_find_custom (animator->priv->score, &key, - sort_actor_prop_func); - if (initial) - { - initial_key = initial->data; - - return initial_key->interpolation; - } - - return CLUTTER_INTERPOLATION_LINEAR; -} - -/** - * clutter_animator_property_set_interpolation: - * @animator: a #ClutterAnimatorKey - * @object: a #GObject - * @property_name: the name of a property on object - * @interpolation: the #ClutterInterpolation to use - * - * Set the interpolation method to use, %CLUTTER_INTERPOLATION_LINEAR causes - * the values to linearly change between the values, and - * %CLUTTER_INTERPOLATION_CUBIC causes the values to smoothly change between - * the values. - * - * Since: 1.2 - * Deprecated: 1.12: Use #ClutterKeyframeTransition instead - */ -void -clutter_animator_property_set_interpolation (ClutterAnimator *animator, - GObject *object, - const gchar *property_name, - ClutterInterpolation interpolation) -{ - GList *initial; - ClutterAnimatorKey key, *initial_key; - - g_return_if_fail (CLUTTER_IS_ANIMATOR (animator)); - g_return_if_fail (G_IS_OBJECT (object)); - g_return_if_fail (property_name); - - key.object = object; - key.property_name = g_intern_string (property_name); - initial = g_list_find_custom (animator->priv->score, &key, - sort_actor_prop_func); - if (initial) - { - initial_key = initial->data; - initial_key->interpolation = interpolation; - } -} - -G_DEFINE_BOXED_TYPE (ClutterAnimatorKey, clutter_animator_key, - clutter_animator_key_copy, - clutter_animator_key_free); - -/** - * clutter_animator_key_get_object: - * @key: a #ClutterAnimatorKey - * - * Retrieves the object a key applies to. - * - * Return value: (transfer none): the object an animator_key exist for. - * - * Since: 1.2 - * Deprecated: 1.12: Use #ClutterKeyframeTransition instead - */ -GObject * -clutter_animator_key_get_object (const ClutterAnimatorKey *key) -{ - g_return_val_if_fail (key != NULL, NULL); - - return key->object; -} - -/** - * clutter_animator_key_get_property_name: - * @key: a #ClutterAnimatorKey - * - * Retrieves the name of the property a key applies to. - * - * Return value: the name of the property an animator_key exist for. - * - * Since: 1.2 - * Deprecated: 1.12: Use #ClutterKeyframeTransition instead - */ -const gchar * -clutter_animator_key_get_property_name (const ClutterAnimatorKey *key) -{ - g_return_val_if_fail (key != NULL, NULL); - - return key->property_name; -} - -/** - * clutter_animator_key_get_property_type: - * @key: a #ClutterAnimatorKey - * - * Retrieves the #GType of the property a key applies to - * - * You can use this type to initialize the #GValue to pass to - * clutter_animator_key_get_value() - * - * Return value: the #GType of the property - * - * Since: 1.2 - * Deprecated: 1.12: Use #ClutterKeyframeTransition instead - */ -GType -clutter_animator_key_get_property_type (const ClutterAnimatorKey *key) -{ - g_return_val_if_fail (key != NULL, G_TYPE_INVALID); - - return G_VALUE_TYPE (&key->value); -} - -/** - * clutter_animator_key_get_mode: - * @key: a #ClutterAnimatorKey - * - * Retrieves the mode of a #ClutterAnimator key, for the first key of a - * property for an object this represents the whether the animation is - * open ended and or curved for the remainding keys for the property it - * represents the easing mode. - * - * Return value: the mode of a #ClutterAnimatorKey - * - * Since: 1.2 - * Deprecated: 1.12: Use #ClutterKeyframeTransition instead - */ -gulong -clutter_animator_key_get_mode (const ClutterAnimatorKey *key) -{ - g_return_val_if_fail (key != NULL, 0); - - return key->mode; -} - -/** - * clutter_animator_key_get_progress: - * @key: a #ClutterAnimatorKey - * - * Retrieves the progress of an clutter_animator_key - * - * Return value: the progress defined for a #ClutterAnimator key. - * - * Since: 1.2 - * Deprecated: 1.12: Use #ClutterKeyframeTransition instead - */ -gdouble -clutter_animator_key_get_progress (const ClutterAnimatorKey *key) -{ - g_return_val_if_fail (key != NULL, 0.0); - - return key->progress; -} - -/** - * clutter_animator_key_get_value: - * @key: a #ClutterAnimatorKey - * @value: a #GValue initialized with the correct type for the animator key - * - * Retrieves a copy of the value for a #ClutterAnimatorKey. - * - * The passed in #GValue needs to be already initialized for the value - * type of the key or to a type that allow transformation from the value - * type of the key. - * - * Use g_value_unset() when done. - * - * Return value: %TRUE if the passed #GValue was successfully set, and - * %FALSE otherwise - * - * Since: 1.2 - * Deprecated: 1.12: Use #ClutterKeyframeTransition instead - */ -gboolean -clutter_animator_key_get_value (const ClutterAnimatorKey *key, - GValue *value) -{ - g_return_val_if_fail (key != NULL, FALSE); - g_return_val_if_fail (value != NULL, FALSE); - g_return_val_if_fail (G_VALUE_TYPE (value) != G_TYPE_INVALID, FALSE); - - if (!g_type_is_a (G_VALUE_TYPE (&key->value), G_VALUE_TYPE (value))) - { - if (g_value_type_compatible (G_VALUE_TYPE (&key->value), - G_VALUE_TYPE (value))) - { - g_value_copy (&key->value, value); - return TRUE; - } - - if (g_value_type_transformable (G_VALUE_TYPE (&key->value), - G_VALUE_TYPE (value))) - { - if (g_value_transform (&key->value, value)) - return TRUE; - } - - g_warning ("%s: Unable to convert from %s to %s for the " - "property '%s' of object %s in the animator key", - G_STRLOC, - g_type_name (G_VALUE_TYPE (&key->value)), - g_type_name (G_VALUE_TYPE (value)), - key->property_name, - G_OBJECT_TYPE_NAME (key->object)); - - return FALSE; - } - else - g_value_copy (&key->value, value); - - return TRUE; -} diff --git a/clutter/clutter/deprecated/clutter-animator.h b/clutter/clutter/deprecated/clutter-animator.h deleted file mode 100644 index a72e27a4c..000000000 --- a/clutter/clutter/deprecated/clutter-animator.h +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Øyvind Kolås - */ - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __CLUTTER_ANIMATOR_H__ -#define __CLUTTER_ANIMATOR_H__ - -#include -#include - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_ANIMATOR (clutter_animator_get_type ()) -#define CLUTTER_TYPE_ANIMATOR_KEY (clutter_animator_key_get_type ()) - -#define CLUTTER_ANIMATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ANIMATOR, ClutterAnimator)) -#define CLUTTER_ANIMATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_ANIMATOR, ClutterAnimatorClass)) -#define CLUTTER_IS_ANIMATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ANIMATOR)) -#define CLUTTER_IS_ANIMATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_ANIMATOR)) -#define CLUTTER_ANIMATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_ANIMATOR, ClutterAnimatorClass)) - -/* ClutterAnimator is typedef in clutter-types.h */ - -typedef struct _ClutterAnimatorClass ClutterAnimatorClass; -typedef struct _ClutterAnimatorPrivate ClutterAnimatorPrivate; - -/** - * ClutterAnimatorKey: - * - * A key frame inside a #ClutterAnimator - * - * Since: 1.2 - * - * Deprecated: 1.12 - */ -typedef struct _ClutterAnimatorKey ClutterAnimatorKey; - -/** - * ClutterAnimator: - * - * The #ClutterAnimator structure contains only private data and - * should be accessed using the provided API - * - * Since: 1.2 - * - * Deprecated: 1.12 - */ -struct _ClutterAnimator -{ - /*< private >*/ - GObject parent_instance; - - ClutterAnimatorPrivate *priv; -}; - -/** - * ClutterAnimatorClass: - * - * The #ClutterAnimatorClass structure contains only private data - * - * Since: 1.2 - * - * Deprecated: 1.12 - */ -struct _ClutterAnimatorClass -{ - /*< private >*/ - GObjectClass parent_class; - - /* padding for future expansion */ - gpointer _padding_dummy[16]; -}; - -CLUTTER_DEPRECATED_IN_1_12 -GType clutter_animator_get_type (void) G_GNUC_CONST; - -CLUTTER_DEPRECATED_IN_1_12 -ClutterAnimator * clutter_animator_new (void); -CLUTTER_DEPRECATED_IN_1_12 -ClutterAnimator * clutter_animator_set_key (ClutterAnimator *animator, - GObject *object, - const gchar *property_name, - guint mode, - gdouble progress, - const GValue *value); -CLUTTER_DEPRECATED_IN_1_12 -void clutter_animator_set (ClutterAnimator *animator, - gpointer first_object, - const gchar *first_property_name, - guint first_mode, - gdouble first_progress, - ...) G_GNUC_NULL_TERMINATED; -CLUTTER_DEPRECATED_IN_1_12 -GList * clutter_animator_get_keys (ClutterAnimator *animator, - GObject *object, - const gchar *property_name, - gdouble progress); - -CLUTTER_DEPRECATED_IN_1_12 -void clutter_animator_remove_key (ClutterAnimator *animator, - GObject *object, - const gchar *property_name, - gdouble progress); - -CLUTTER_DEPRECATED_IN_1_12 -ClutterTimeline * clutter_animator_start (ClutterAnimator *animator); - -CLUTTER_DEPRECATED_IN_1_12 -gboolean clutter_animator_compute_value (ClutterAnimator *animator, - GObject *object, - const gchar *property_name, - gdouble progress, - GValue *value); - -CLUTTER_DEPRECATED_IN_1_12 -ClutterTimeline * clutter_animator_get_timeline (ClutterAnimator *animator); -CLUTTER_DEPRECATED_IN_1_12 -void clutter_animator_set_timeline (ClutterAnimator *animator, - ClutterTimeline *timeline); -CLUTTER_DEPRECATED_IN_1_12 -guint clutter_animator_get_duration (ClutterAnimator *animator); -CLUTTER_DEPRECATED_IN_1_12 -void clutter_animator_set_duration (ClutterAnimator *animator, - guint duration); - -CLUTTER_DEPRECATED_IN_1_12 -gboolean clutter_animator_property_get_ease_in (ClutterAnimator *animator, - GObject *object, - const gchar *property_name); -CLUTTER_DEPRECATED_IN_1_12 -void clutter_animator_property_set_ease_in (ClutterAnimator *animator, - GObject *object, - const gchar *property_name, - gboolean ease_in); - -CLUTTER_DEPRECATED_IN_1_12 -ClutterInterpolation clutter_animator_property_get_interpolation (ClutterAnimator *animator, - GObject *object, - const gchar *property_name); -CLUTTER_DEPRECATED_IN_1_12 -void clutter_animator_property_set_interpolation (ClutterAnimator *animator, - GObject *object, - const gchar *property_name, - ClutterInterpolation interpolation); - -CLUTTER_DEPRECATED_IN_1_12 -GType clutter_animator_key_get_type (void) G_GNUC_CONST; -CLUTTER_DEPRECATED_IN_1_12 -GObject * clutter_animator_key_get_object (const ClutterAnimatorKey *key); -CLUTTER_DEPRECATED_IN_1_12 -const gchar * clutter_animator_key_get_property_name (const ClutterAnimatorKey *key); -CLUTTER_DEPRECATED_IN_1_12 -GType clutter_animator_key_get_property_type (const ClutterAnimatorKey *key); -CLUTTER_DEPRECATED_IN_1_12 -gulong clutter_animator_key_get_mode (const ClutterAnimatorKey *key); -CLUTTER_DEPRECATED_IN_1_12 -gdouble clutter_animator_key_get_progress (const ClutterAnimatorKey *key); -CLUTTER_DEPRECATED_IN_1_12 -gboolean clutter_animator_key_get_value (const ClutterAnimatorKey *key, - GValue *value); - -G_END_DECLS - -#endif /* __CLUTTER_ANIMATOR_H__ */ diff --git a/clutter/clutter/deprecated/clutter-backend.h b/clutter/clutter/deprecated/clutter-backend.h deleted file mode 100644 index 3fe027449..000000000 --- a/clutter/clutter/deprecated/clutter-backend.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * Copyright (C) 2006, 2007, 2008 OpenedHand Ltd - * Copyright (C) 2009, 2010 Intel Corp - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __CLUTTER_BACKEND_DEPRECATED_H__ -#define __CLUTTER_BACKEND_DEPRECATED_H__ - -#include - -G_BEGIN_DECLS - -CLUTTER_DEPRECATED_IN_1_4_FOR(ClutterSettings:font_dpi) -void clutter_backend_set_resolution (ClutterBackend *backend, - gdouble dpi); - -CLUTTER_DEPRECATED_IN_1_4_FOR(ClutterSettings:double_click_time) -void clutter_backend_set_double_click_time (ClutterBackend *backend, - guint msec); - -CLUTTER_DEPRECATED_IN_1_4_FOR(ClutterSettings:double_click_time) -guint clutter_backend_get_double_click_time (ClutterBackend *backend); - -CLUTTER_DEPRECATED_IN_1_4_FOR(ClutterSettings:double_click_distance) -void clutter_backend_set_double_click_distance (ClutterBackend *backend, - guint distance); - -CLUTTER_DEPRECATED_IN_1_4_FOR(ClutterSettings:double_click_distance) -guint clutter_backend_get_double_click_distance (ClutterBackend *backend); - -CLUTTER_DEPRECATED_IN_1_4_FOR(ClutterSettings:font_name) -void clutter_backend_set_font_name (ClutterBackend *backend, - const gchar *font_name); - -CLUTTER_DEPRECATED_IN_1_4_FOR(ClutterSettings:font_name) -const gchar * clutter_backend_get_font_name (ClutterBackend *backend); - - -G_END_DECLS - -#endif /* __CLUTTER_BACKEND_DEPRECATED_H__ */ diff --git a/clutter/clutter/deprecated/clutter-behaviour-depth.c b/clutter/clutter/deprecated/clutter-behaviour-depth.c deleted file mode 100644 index 9282ac8ef..000000000 --- a/clutter/clutter/deprecated/clutter-behaviour-depth.c +++ /dev/null @@ -1,305 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * Jorn Baayen - * Emmanuele Bassi - * - * Copyright (C) 2006 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#ifdef HAVE_CONFIG_H -#include "clutter-build-config.h" -#endif - -#define CLUTTER_DISABLE_DEPRECATION_WARNINGS - -#include "deprecated/clutter-actor.h" -#include "clutter-alpha.h" -#include "clutter-behaviour.h" -#include "clutter-behaviour-depth.h" -#include "clutter-enum-types.h" -#include "clutter-main.h" -#include "clutter-debug.h" -#include "clutter-private.h" - -/** - * SECTION:clutter-behaviour-depth - * @Title: ClutterBehaviourDepth - * @short_description: A behaviour controlling the Z position - * @Deprecated: 1.6: Use clutter_actor_animate() instead - * - * #ClutterBehaviourDepth is a simple #ClutterBehaviour controlling the - * depth of a set of actors between a start and end depth. - * - * #ClutterBehaviourDepth is available since Clutter 0.4. - * - * Deprecated: 1.6: Use the #ClutterActor:depth property and - * clutter_actor_animate(), or #ClutterAnimator, or #ClutterState - * instead. - */ - -struct _ClutterBehaviourDepthPrivate -{ - gint depth_start; - gint depth_end; -}; - -enum -{ - PROP_0, - - PROP_DEPTH_START, - PROP_DEPTH_END -}; - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterBehaviourDepth, - clutter_behaviour_depth, - CLUTTER_TYPE_BEHAVIOUR) - -static void -alpha_notify_foreach (ClutterBehaviour *behaviour, - ClutterActor *actor, - gpointer user_data) -{ - clutter_actor_set_depth (actor, GPOINTER_TO_INT (user_data)); -} - -static void -clutter_behaviour_depth_alpha_notify (ClutterBehaviour *behaviour, - gdouble alpha_value) -{ - ClutterBehaviourDepthPrivate *priv; - gint depth; - - priv = CLUTTER_BEHAVIOUR_DEPTH (behaviour)->priv; - - /* Need to create factor as to avoid borking signedness */ - depth = (alpha_value * (priv->depth_end - priv->depth_start)) - + priv->depth_start; - - CLUTTER_NOTE (ANIMATION, "alpha: %.4f, depth: %d", alpha_value, depth); - - clutter_behaviour_actors_foreach (behaviour, - alpha_notify_foreach, - GINT_TO_POINTER (depth)); -} - -static void -clutter_behaviour_depth_applied (ClutterBehaviour *behaviour, - ClutterActor *actor) -{ - ClutterBehaviourDepth *depth = CLUTTER_BEHAVIOUR_DEPTH (behaviour); - - clutter_actor_set_depth (actor, depth->priv->depth_start); -} - -static void -clutter_behaviour_depth_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterBehaviourDepth *depth = CLUTTER_BEHAVIOUR_DEPTH (gobject); - - switch (prop_id) - { - case PROP_DEPTH_START: - depth->priv->depth_start = g_value_get_int (value); - break; - case PROP_DEPTH_END: - depth->priv->depth_end = g_value_get_int (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_behaviour_depth_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterBehaviourDepth *depth = CLUTTER_BEHAVIOUR_DEPTH (gobject); - - switch (prop_id) - { - case PROP_DEPTH_START: - g_value_set_int (value, depth->priv->depth_start); - break; - case PROP_DEPTH_END: - g_value_set_int (value, depth->priv->depth_end); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_behaviour_depth_class_init (ClutterBehaviourDepthClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterBehaviourClass *behaviour_class = CLUTTER_BEHAVIOUR_CLASS (klass); - - gobject_class->set_property = clutter_behaviour_depth_set_property; - gobject_class->get_property = clutter_behaviour_depth_get_property; - - behaviour_class->alpha_notify = clutter_behaviour_depth_alpha_notify; - behaviour_class->applied = clutter_behaviour_depth_applied; - - /** - * ClutterBehaviourDepth:depth-start: - * - * Start depth level to apply to the actors. - * - * Since: 0.4 - * - * Deprecated: 1.6 - */ - g_object_class_install_property (gobject_class, - PROP_DEPTH_START, - g_param_spec_int ("depth-start", - P_("Start Depth"), - P_("Initial depth to apply"), - G_MININT, G_MAXINT, 0, - CLUTTER_PARAM_READWRITE)); - /** - * ClutterBehaviourDepth:depth-end: - * - * End depth level to apply to the actors. - * - * Since: 0.4 - * - * Deprecated: 1.6 - */ - g_object_class_install_property (gobject_class, - PROP_DEPTH_END, - g_param_spec_int ("depth-end", - P_("End Depth"), - P_("Final depth to apply"), - G_MININT, G_MAXINT, 0, - CLUTTER_PARAM_READWRITE)); -} - -static void -clutter_behaviour_depth_init (ClutterBehaviourDepth *depth) -{ - depth->priv = clutter_behaviour_depth_get_instance_private (depth); -} - -/** - * clutter_behaviour_depth_new: - * @alpha: (allow-none): a #ClutterAlpha instance, or %NULL - * @depth_start: initial value of the depth - * @depth_end: final value of the depth - * - * Creates a new #ClutterBehaviourDepth which can be used to control - * the ClutterActor:depth property of a set of #ClutterActors. - * - * If @alpha is not %NULL, the #ClutterBehaviour will take ownership - * of the #ClutterAlpha instance. In the case when @alpha is %NULL, - * it can be set later with clutter_behaviour_set_alpha(). - * - * Return value: (transfer full): the newly created behaviour - * - * Since: 0.4 - * - * Deprecated: 1.6 - */ -ClutterBehaviour * -clutter_behaviour_depth_new (ClutterAlpha *alpha, - gint depth_start, - gint depth_end) -{ - g_return_val_if_fail (alpha == NULL || CLUTTER_IS_ALPHA (alpha), NULL); - - return g_object_new (CLUTTER_TYPE_BEHAVIOUR_DEPTH, - "alpha", alpha, - "depth-start", depth_start, - "depth-end", depth_end, - NULL); -} - -/** - * clutter_behaviour_depth_set_bounds: - * @behaviour: a #ClutterBehaviourDepth - * @depth_start: initial value of the depth - * @depth_end: final value of the depth - * - * Sets the boundaries of the @behaviour. - * - * Since: 0.6 - * - * Deprecated: 1.6 - */ -void -clutter_behaviour_depth_set_bounds (ClutterBehaviourDepth *behaviour, - gint depth_start, - gint depth_end) -{ - ClutterBehaviourDepthPrivate *priv; - - g_return_if_fail (CLUTTER_IS_BEHAVIOUR_DEPTH (behaviour)); - - priv = behaviour->priv; - - g_object_freeze_notify (G_OBJECT (behaviour)); - - if (priv->depth_start != depth_start) - { - priv->depth_start = depth_start; - g_object_notify (G_OBJECT (behaviour), "depth-start"); - } - - if (priv->depth_end != depth_end) - { - priv->depth_end = depth_end; - g_object_notify (G_OBJECT (behaviour), "depth-end"); - } - - g_object_thaw_notify (G_OBJECT (behaviour)); -} - -/** - * clutter_behaviour_depth_get_bounds: - * @behaviour: a #ClutterBehaviourDepth - * @depth_start: (out): return location for the initial depth value, or %NULL - * @depth_end: (out): return location for the final depth value, or %NULL - * - * Gets the boundaries of the @behaviour - * - * Since: 0.6 - * - * Deprecated: 1.6 - */ -void -clutter_behaviour_depth_get_bounds (ClutterBehaviourDepth *behaviour, - gint *depth_start, - gint *depth_end) -{ - g_return_if_fail (CLUTTER_IS_BEHAVIOUR_DEPTH (behaviour)); - - if (depth_start) - *depth_start = behaviour->priv->depth_start; - - if (depth_end) - *depth_end = behaviour->priv->depth_end; -} diff --git a/clutter/clutter/deprecated/clutter-behaviour-depth.h b/clutter/clutter/deprecated/clutter-behaviour-depth.h deleted file mode 100644 index b3b8ae1c2..000000000 --- a/clutter/clutter/deprecated/clutter-behaviour-depth.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * Jorn Baayen - * Emmanuele Bassi - * - * Copyright (C) 2006 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __CLUTTER_BEHAVIOUR_DEPTH__ -#define __CLUTTER_BEHAVIOUR_DEPTH__ - -#include - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_BEHAVIOUR_DEPTH (clutter_behaviour_depth_get_type ()) -#define CLUTTER_BEHAVIOUR_DEPTH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BEHAVIOUR_DEPTH, ClutterBehaviourDepth)) -#define CLUTTER_IS_BEHAVIOUR_DEPTH(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BEHAVIOUR_DEPTH)) -#define CLUTTER_BEHAVIOUR_DEPTH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BEHAVIOUR_DEPTH, ClutterBehaviourDepthClass)) -#define CLUTTER_IS_BEHAVIOUR_DEPTH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BEHAVIOUR_DEPTH)) -#define CLUTTER_BEHAVIOUR_DEPTH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_BEHAVIOUR_DEPTH, ClutterBehaviourDepthClass)) - -typedef struct _ClutterBehaviourDepth ClutterBehaviourDepth; -typedef struct _ClutterBehaviourDepthPrivate ClutterBehaviourDepthPrivate; -typedef struct _ClutterBehaviourDepthClass ClutterBehaviourDepthClass; - -/** - * ClutterBehaviourDepth: - * - * The #ClutterBehaviourDepth structure contains only private data - * and should be accessed using the provided API - * - * Since: 0.2 - * - * Deprecated: 1.6: Use clutter_actor_animate() with #ClutterActor:depth - * instead. - */ -struct _ClutterBehaviourDepth -{ - /*< private >*/ - ClutterBehaviour parent_instance; - - ClutterBehaviourDepthPrivate *priv; -}; - -/** - * ClutterBehaviourDepthClass: - * - * The #ClutterBehaviourDepthClass structure contains only private data - * - * Since: 0.2 - * - * Deprecated: 1.6 - */ -struct _ClutterBehaviourDepthClass -{ - /*< private >*/ - ClutterBehaviourClass parent_class; -}; - -CLUTTER_DEPRECATED_IN_1_6 -GType clutter_behaviour_depth_get_type (void) G_GNUC_CONST; - -CLUTTER_DEPRECATED_IN_1_6_FOR(clutter_actor_animate and ClutterActor:depth) -ClutterBehaviour *clutter_behaviour_depth_new (ClutterAlpha *alpha, - gint depth_start, - gint depth_end); - -CLUTTER_DEPRECATED_IN_1_6 -void clutter_behaviour_depth_set_bounds (ClutterBehaviourDepth *behaviour, - gint depth_start, - gint depth_end); -CLUTTER_DEPRECATED_IN_1_6 -void clutter_behaviour_depth_get_bounds (ClutterBehaviourDepth *behaviour, - gint *depth_start, - gint *depth_end); - -G_END_DECLS - -#endif /* __CLUTTER_BEHAVIOUR_DEPTH__ */ diff --git a/clutter/clutter/deprecated/clutter-behaviour-ellipse.c b/clutter/clutter/deprecated/clutter-behaviour-ellipse.c deleted file mode 100644 index 659b752e6..000000000 --- a/clutter/clutter/deprecated/clutter-behaviour-ellipse.c +++ /dev/null @@ -1,1061 +0,0 @@ - -/* -*- mode:C; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Tomas Frydrych - * - * Copyright (C) 2007 OpenedHand Ltd - * Copyright (C) 2009 Intel Corp. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -/** - * SECTION:clutter-behaviour-ellipse - * @Title: ClutterBehaviourEllipse - * @short_description: A behaviour interpolating position along an ellipse - * @Deprecated: 1.6: Use clutter_actor_animate() instead - * - * #ClutterBehaviourEllipse interpolates actors along a path defined by - * an ellipse. - * - * When applying an ellipse behaviour to an actor, the - * behaviour will update the actor's position and depth and set them - * to what is dictated by the ellipses initial position. - * - * Deprecated: 1.6: Use clutter_actor_animate(), #ClutterPath and a - * #ClutterPathConstraint instead. - * - * Since: 0.4 - */ - -#ifdef HAVE_CONFIG_H -#include "clutter-build-config.h" -#endif - -#include -#include - -#define CLUTTER_DISABLE_DEPRECATION_WARNINGS -#include "deprecated/clutter-actor.h" - -#include "clutter-alpha.h" -#include "clutter-behaviour.h" -#include "clutter-behaviour-ellipse.h" -#include "clutter-debug.h" -#include "clutter-enum-types.h" -#include "clutter-private.h" - -enum -{ - PROP_0, - - PROP_CENTER, - PROP_WIDTH, - PROP_HEIGHT, - PROP_ANGLE_START, - PROP_ANGLE_END, - PROP_ANGLE_TILT_X, - PROP_ANGLE_TILT_Y, - PROP_ANGLE_TILT_Z, - PROP_DIRECTION, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST]; - -struct _ClutterBehaviourEllipsePrivate -{ - ClutterKnot center; - - /* a = width / 2 */ - gint a; - - /* b = height / 2 */ - gint b; - - gdouble angle_start; - gdouble angle_end; - - gdouble angle_tilt_x; - gdouble angle_tilt_y; - gdouble angle_tilt_z; - - ClutterRotateDirection direction; -}; - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterBehaviourEllipse, - clutter_behaviour_ellipse, - CLUTTER_TYPE_BEHAVIOUR) - -typedef struct _knot3d -{ - gint x; - gint y; - gint z; -} knot3d; - -static void -clutter_behaviour_ellipse_advance (ClutterBehaviourEllipse *e, - float angle, - knot3d *knot) -{ - ClutterBehaviourEllipsePrivate *priv = e->priv; - gint x, y, z; - - x = priv->a * cosf (angle * (G_PI / 180.0)); - y = priv->b * sinf (angle * (G_PI / 180.0)); - z = 0; - - if (priv->angle_tilt_z) - { - /* - * x2 = r * cos (angle + tilt_z) - * y2 = r * sin (angle + tilt_z) - * - * These can be trasformed to the formulas below using properties of - * sin (a + b) and cos (a + b) - * - */ - gfloat x2, y2; - - x2 = x * cosf (priv->angle_tilt_z * (G_PI / 180.0)) - - y * sinf (priv->angle_tilt_z * (G_PI / 180.0)); - - y2 = y * cosf (priv->angle_tilt_z * (G_PI / 180.0)) - + x * sinf (priv->angle_tilt_z * (G_PI / 180.0)); - - x = (x2); - y = (y2); - } - - if (priv->angle_tilt_x) - { - gfloat z2, y2; - - z2 = - y * sinf (priv->angle_tilt_x * (G_PI / 180.0)); - y2 = y * cosf (priv->angle_tilt_x * (G_PI / 180.0)); - - z = z2; - y = y2; - } - - if (priv->angle_tilt_y) - { - gfloat x2, z2; - - x2 = x * cosf (priv->angle_tilt_y * (G_PI / 180.0)) - - z * sinf (priv->angle_tilt_y * (G_PI / 180.0)); - - z2 = z * cosf (priv->angle_tilt_y * (G_PI / 180.0)) - + x * sinf (priv->angle_tilt_y * (G_PI / 180.0)); - - x = x2; - z = z2; - } - - knot->x = x; - knot->y = y; - knot->z = z; - - CLUTTER_NOTE (ANIMATION, "advancing to angle %.2f [%d, %d] (a: %d, b: %d)", - angle, - knot->x, knot->y, - priv->a, priv->b); -} - - -static void -actor_apply_knot_foreach (ClutterBehaviour *behave, - ClutterActor *actor, - gpointer data) -{ - ClutterBehaviourEllipsePrivate *priv; - knot3d *knot = data; - - priv = ((ClutterBehaviourEllipse *) behave)->priv; - - clutter_actor_set_position (actor, knot->x, knot->y); - - if (priv->angle_tilt_x != 0 || priv->angle_tilt_y != 0) - clutter_actor_set_depth (actor, knot->z); -} - -static inline float -clamp_angle (float a) -{ - gint rounds; - - rounds = a / 360; - if (a < 0) - rounds--; - - return a - 360 * rounds; -} - -static void -clutter_behaviour_ellipse_alpha_notify (ClutterBehaviour *behave, - gdouble alpha) -{ - ClutterBehaviourEllipse *self = CLUTTER_BEHAVIOUR_ELLIPSE (behave); - ClutterBehaviourEllipsePrivate *priv = self->priv; - gfloat start, end; - gfloat angle = 0; - knot3d knot; - - /* we do everything in single precision because it's easier, even - * though all the parameters are stored in double precision for - * consistency with the equivalent ClutterActor API - */ - start = priv->angle_start; - end = priv->angle_end; - - if (priv->direction == CLUTTER_ROTATE_CW && start >= end) - end += 360; - else if (priv->direction == CLUTTER_ROTATE_CCW && start <= end) - end -= 360; - - angle = (end - start) * alpha + start; - - clutter_behaviour_ellipse_advance (self, angle, &knot); - - knot.x += priv->center.x; - knot.y += priv->center.y; - - clutter_behaviour_actors_foreach (behave, actor_apply_knot_foreach, &knot); -} - -static void -clutter_behaviour_ellipse_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterBehaviourEllipse *el = CLUTTER_BEHAVIOUR_ELLIPSE (gobject); - ClutterBehaviourEllipsePrivate *priv = el->priv; - - switch (prop_id) - { - case PROP_ANGLE_START: - priv->angle_start = g_value_get_double (value); - break; - - case PROP_ANGLE_END: - priv->angle_end = g_value_get_double (value); - break; - - case PROP_ANGLE_TILT_X: - priv->angle_tilt_x = g_value_get_double (value); - break; - - case PROP_ANGLE_TILT_Y: - priv->angle_tilt_y = g_value_get_double (value); - break; - - case PROP_ANGLE_TILT_Z: - priv->angle_tilt_z = g_value_get_double (value); - break; - - case PROP_WIDTH: - clutter_behaviour_ellipse_set_width (el, g_value_get_int (value)); - break; - - case PROP_HEIGHT: - clutter_behaviour_ellipse_set_height (el, g_value_get_int (value)); - break; - - case PROP_CENTER: - { - ClutterKnot *knot = g_value_get_boxed (value); - if (knot) - clutter_behaviour_ellipse_set_center (el, knot->x, knot->y); - } - break; - - case PROP_DIRECTION: - priv->direction = g_value_get_enum (value); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_behaviour_ellipse_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterBehaviourEllipsePrivate *priv; - - priv = CLUTTER_BEHAVIOUR_ELLIPSE (gobject)->priv; - - switch (prop_id) - { - case PROP_ANGLE_START: - g_value_set_double (value, priv->angle_start); - break; - - case PROP_ANGLE_END: - g_value_set_double (value, priv->angle_end); - break; - - case PROP_ANGLE_TILT_X: - g_value_set_double (value, priv->angle_tilt_x); - break; - - case PROP_ANGLE_TILT_Y: - g_value_set_double (value, priv->angle_tilt_y); - break; - - case PROP_ANGLE_TILT_Z: - g_value_set_double (value, priv->angle_tilt_z); - break; - - case PROP_WIDTH: - g_value_set_int (value, (priv->a * 2)); - break; - - case PROP_HEIGHT: - g_value_set_int (value, (priv->b * 2)); - break; - - case PROP_CENTER: - g_value_set_boxed (value, &priv->center); - break; - - case PROP_DIRECTION: - g_value_set_enum (value, priv->direction); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_behaviour_ellipse_applied (ClutterBehaviour *behave, - ClutterActor *actor) -{ - ClutterBehaviourEllipse *e = CLUTTER_BEHAVIOUR_ELLIPSE (behave); - ClutterBehaviourEllipsePrivate *priv = e->priv; - knot3d knot = { 0, }; - - clutter_behaviour_ellipse_advance (e, priv->angle_start, &knot); - - clutter_actor_set_position (actor, knot.x, knot.y); - - /* the depth should be changed only if there is a tilt on - * any of the X or the Y axis - */ - if (priv->angle_tilt_x != 0 || priv->angle_tilt_y != 0) - clutter_actor_set_depth (actor, knot.z); -} - -static void -clutter_behaviour_ellipse_class_init (ClutterBehaviourEllipseClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - ClutterBehaviourClass *behave_class = CLUTTER_BEHAVIOUR_CLASS (klass); - GParamSpec *pspec = NULL; - - object_class->set_property = clutter_behaviour_ellipse_set_property; - object_class->get_property = clutter_behaviour_ellipse_get_property; - - behave_class->alpha_notify = clutter_behaviour_ellipse_alpha_notify; - behave_class->applied = clutter_behaviour_ellipse_applied; - - /** - * ClutterBehaviourEllipse:angle-start: - * - * The initial angle from where the rotation should start. - * - * Since: 0.4 - */ - pspec = g_param_spec_double ("angle-start", - P_("Start Angle"), - P_("Initial angle"), - 0.0, 360.0, - 0.0, - CLUTTER_PARAM_READWRITE); - obj_props[PROP_ANGLE_START] = pspec; - g_object_class_install_property (object_class, PROP_ANGLE_START, pspec); - - /** - * ClutterBehaviourEllipse:angle-end: - * - * The final angle to where the rotation should end. - * - * Since: 0.4 - */ - pspec = g_param_spec_double ("angle-end", - P_("End Angle"), - P_("Final angle"), - 0.0, 360.0, - 0.0, - CLUTTER_PARAM_READWRITE); - obj_props[PROP_ANGLE_END] = pspec; - g_object_class_install_property (object_class, PROP_ANGLE_END, pspec); - - /** - * ClutterBehaviourEllipse:angle-tilt-x: - * - * The tilt angle for the rotation around center in X axis - * - * Since: 0.4 - */ - pspec = g_param_spec_double ("angle-tilt-x", - P_("Angle x tilt"), - P_("Tilt of the ellipse around x axis"), - 0.0, 360.0, - 360.0, - CLUTTER_PARAM_READWRITE); - obj_props[PROP_ANGLE_TILT_X] = pspec; - g_object_class_install_property (object_class, PROP_ANGLE_TILT_X, pspec); - - /** - * ClutterBehaviourEllipse:angle-tilt-y: - * - * The tilt angle for the rotation around center in Y axis - * - * Since: 0.4 - */ - pspec = g_param_spec_double ("angle-tilt-y", - P_("Angle y tilt"), - P_("Tilt of the ellipse around y axis"), - 0.0, 360.0, - 360.0, - CLUTTER_PARAM_READWRITE); - obj_props[PROP_ANGLE_TILT_Y] = pspec; - g_object_class_install_property (object_class, PROP_ANGLE_TILT_Y, pspec); - - /** - * ClutterBehaviourEllipse:angle-tilt-z: - * - * The tilt angle for the rotation on the Z axis - * - * Since: 0.4 - */ - pspec = g_param_spec_double ("angle-tilt-z", - P_("Angle z tilt"), - P_("Tilt of the ellipse around z axis"), - 0.0, 360.0, - 360.0, - CLUTTER_PARAM_READWRITE); - obj_props[PROP_ANGLE_TILT_Z] = pspec; - g_object_class_install_property (object_class, PROP_ANGLE_TILT_Z, pspec); - - /** - * ClutterBehaviourEllipse:width: - * - * Width of the ellipse, in pixels - * - * Since: 0.4 - */ - pspec = g_param_spec_int ("width", - P_("Width"), - P_("Width of the ellipse"), - 0, G_MAXINT, - 100, - CLUTTER_PARAM_READWRITE); - obj_props[PROP_WIDTH] = pspec; - g_object_class_install_property (object_class, PROP_WIDTH, pspec); - - /** - * ClutterBehaviourEllipse:height: - * - * Height of the ellipse, in pixels - * - * Since: 0.4 - */ - pspec = g_param_spec_int ("height", - P_("Height"), - P_("Height of ellipse"), - 0, G_MAXINT, - 50, - CLUTTER_PARAM_READWRITE); - obj_props[PROP_HEIGHT] = pspec; - g_object_class_install_property (object_class, PROP_HEIGHT, pspec); - - /** - * ClutterBehaviourEllipse:center: - * - * The center of the ellipse. - * - * Since: 0.4 - */ - pspec = g_param_spec_boxed ("center", - P_("Center"), - P_("Center of ellipse"), - CLUTTER_TYPE_KNOT, - CLUTTER_PARAM_READWRITE); - obj_props[PROP_CENTER] = pspec; - g_object_class_install_property (object_class, PROP_CENTER, pspec); - - /** - * ClutterBehaviourEllipse:direction: - * - * The direction of the rotation. - * - * Since: 0.4 - */ - pspec = g_param_spec_enum ("direction", - P_("Direction"), - P_("Direction of rotation"), - CLUTTER_TYPE_ROTATE_DIRECTION, - CLUTTER_ROTATE_CW, - CLUTTER_PARAM_READWRITE); - obj_props[PROP_DIRECTION] = pspec; - g_object_class_install_property (object_class, PROP_DIRECTION, pspec); -} - -static void -clutter_behaviour_ellipse_init (ClutterBehaviourEllipse * self) -{ - ClutterBehaviourEllipsePrivate *priv; - - self->priv = priv = clutter_behaviour_ellipse_get_instance_private (self); - - priv->direction = CLUTTER_ROTATE_CW; - - priv->angle_start = 0; - priv->angle_end = 0; - - priv->a = 50; - priv->b = 25; - - priv->angle_tilt_x = 360; - priv->angle_tilt_y = 360; - priv->angle_tilt_z = 360; -} - -/** - * clutter_behaviour_ellipse_new: - * @alpha: (allow-none): a #ClutterAlpha instance, or %NULL - * @x: x coordinace of the center - * @y: y coordiance of the center - * @width: width of the ellipse - * @height: height of the ellipse - * @direction: #ClutterRotateDirection of rotation - * @start: angle in degrees at which movement starts, between 0 and 360 - * @end: angle in degrees at which movement ends, between 0 and 360 - * - * Creates a behaviour that drives actors along an elliptical path with - * given center, width and height; the movement starts at @start - * degrees (with 0 corresponding to 12 o'clock) and ends at @end - * degrees. Angles greated than 360 degrees get clamped to the canonical - * interval <0, 360); if @start is equal to @end, the behaviour will - * rotate by exacly 360 degrees. - * - * If @alpha is not %NULL, the #ClutterBehaviour will take ownership - * of the #ClutterAlpha instance. In the case when @alpha is %NULL, - * it can be set later with clutter_behaviour_set_alpha(). - * - * Return value: the newly created #ClutterBehaviourEllipse - * - * Since: 0.4 - */ -ClutterBehaviour * -clutter_behaviour_ellipse_new (ClutterAlpha *alpha, - gint x, - gint y, - gint width, - gint height, - ClutterRotateDirection direction, - gdouble start, - gdouble end) -{ - ClutterKnot center; - - g_return_val_if_fail (alpha == NULL || CLUTTER_IS_ALPHA (alpha), NULL); - - center.x = x; - center.y = y; - - return g_object_new (CLUTTER_TYPE_BEHAVIOUR_ELLIPSE, - "alpha", alpha, - "center", ¢er, - "width", width, - "height", height, - "direction", direction, - "angle-start", start, - "angle-end", end, - NULL); -} - -/** - * clutter_behaviour_ellipse_set_center: - * @self: a #ClutterBehaviourEllipse - * @x: x coordinace of centre - * @y: y coordinace of centre - * - * Sets the center of the elliptical path to the point represented by knot. - * - * Since: 0.4 - */ -void -clutter_behaviour_ellipse_set_center (ClutterBehaviourEllipse *self, - gint x, - gint y) -{ - ClutterBehaviourEllipsePrivate *priv; - - g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self)); - - priv = self->priv; - - if (priv->center.x != x || priv->center.y != y) - { - priv->center.x = x; - priv->center.y = y; - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_CENTER]); - } -} - -/** - * clutter_behaviour_ellipse_get_center: - * @self: a #ClutterBehaviourEllipse - * @x: (out): return location for the X coordinate of the center, or %NULL - * @y: (out): return location for the Y coordinate of the center, or %NULL - * - * Gets the center of the elliptical path path. - * - * Since: 0.4 - */ -void -clutter_behaviour_ellipse_get_center (ClutterBehaviourEllipse *self, - gint *x, - gint *y) -{ - ClutterBehaviourEllipsePrivate *priv; - - g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self)); - - priv = self->priv; - - if (x) - *x = priv->center.x; - - if (y) - *y = priv->center.y; -} - - -/** - * clutter_behaviour_ellipse_set_width: - * @self: a #ClutterBehaviourEllipse - * @width: width of the ellipse - * - * Sets the width of the elliptical path. - * - * Since: 0.4 - */ -void -clutter_behaviour_ellipse_set_width (ClutterBehaviourEllipse *self, - gint width) -{ - ClutterBehaviourEllipsePrivate *priv; - - g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self)); - - priv = self->priv; - - if (priv->a != width / 2) - { - priv->a = width / 2; - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_WIDTH]); - } -} - -/** - * clutter_behaviour_ellipse_get_width: - * @self: a #ClutterBehaviourEllipse - * - * Gets the width of the elliptical path. - * - * Return value: the width of the path - * - * Since: 0.4 - */ -gint -clutter_behaviour_ellipse_get_width (ClutterBehaviourEllipse *self) -{ - g_return_val_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self), 0); - - return self->priv->a * 2; -} - -/** - * clutter_behaviour_ellipse_set_height: - * @self: a #ClutterBehaviourEllipse - * @height: height of the ellipse - * - * Sets the height of the elliptical path. - * - * Since: 0.4 - */ -void -clutter_behaviour_ellipse_set_height (ClutterBehaviourEllipse *self, - gint height) -{ - ClutterBehaviourEllipsePrivate *priv; - - g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self)); - - priv = self->priv; - - if (priv->b != height / 2) - { - priv->b = height / 2; - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_HEIGHT]); - } -} - -/** - * clutter_behaviour_ellipse_get_height: - * @self: a #ClutterBehaviourEllipse - * - * Gets the height of the elliptical path. - * - * Return value: the height of the path - * - * Since: 0.4 - */ -gint -clutter_behaviour_ellipse_get_height (ClutterBehaviourEllipse *self) -{ - g_return_val_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self), 0); - - return self->priv->b * 2; -} - -/** - * clutter_behaviour_ellipse_set_angle_start: - * @self: a #ClutterBehaviourEllipse - * @angle_start: angle at which movement starts in degrees, between 0 and 360. - * - * Sets the angle at which movement starts; angles >= 360 degress get clamped - * to the canonical interval <0, 360). - * - * Since: 0.6 - */ -void -clutter_behaviour_ellipse_set_angle_start (ClutterBehaviourEllipse *self, - gdouble angle_start) -{ - ClutterBehaviourEllipsePrivate *priv; - gdouble new_angle; - - g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self)); - - new_angle = clamp_angle (angle_start); - - priv = self->priv; - - if (priv->angle_start != new_angle) - { - priv->angle_start = new_angle; - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_ANGLE_START]); - } -} - -/** - * clutter_behaviour_ellipse_get_angle_start: - * @self: a #ClutterBehaviourEllipse - * - * Gets the angle at which movements starts. - * - * Return value: angle in degrees - * - * Since: 0.6 - */ -gdouble -clutter_behaviour_ellipse_get_angle_start (ClutterBehaviourEllipse *self) -{ - g_return_val_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self), 0.0); - - return self->priv->angle_start; -} - -/** - * clutter_behaviour_ellipse_set_angle_end: - * @self: a #ClutterBehaviourEllipse - * @angle_end: angle at which movement ends in degrees, between 0 and 360. - * - * Sets the angle at which movement ends; angles >= 360 degress get clamped - * to the canonical interval <0, 360). - * - * Since: 0.4 - */ -void -clutter_behaviour_ellipse_set_angle_end (ClutterBehaviourEllipse *self, - gdouble angle_end) -{ - ClutterBehaviourEllipsePrivate *priv; - gdouble new_angle; - - g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self)); - - new_angle = clamp_angle (angle_end); - - priv = self->priv; - - if (priv->angle_end != new_angle) - { - priv->angle_end = new_angle; - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_ANGLE_END]); - } -} - -/** - * clutter_behaviour_ellipse_get_angle_end: - * @self: a #ClutterBehaviourEllipse - * - * Gets the at which movements ends. - * - * Return value: angle in degrees - * - * Since: 0.4 - */ -gdouble -clutter_behaviour_ellipse_get_angle_end (ClutterBehaviourEllipse *self) -{ - g_return_val_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self), 0.0); - - return self->priv->angle_end; -} - -/** - * clutter_behaviour_ellipse_set_angle_tilt: - * @self: a #ClutterBehaviourEllipse - * @axis: a #ClutterRotateAxis - * @angle_tilt: tilt of the elipse around the center in the given axis in - * degrees. - * - * Sets the angle at which the ellipse should be tilted around it's center. - * - * Since: 0.4 - */ -void -clutter_behaviour_ellipse_set_angle_tilt (ClutterBehaviourEllipse *self, - ClutterRotateAxis axis, - gdouble angle_tilt) -{ - ClutterBehaviourEllipsePrivate *priv; - - g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self)); - - priv = self->priv; - - switch (axis) - { - case CLUTTER_X_AXIS: - if (priv->angle_tilt_x != angle_tilt) - { - priv->angle_tilt_x = angle_tilt; - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_ANGLE_TILT_X]); - } - break; - - case CLUTTER_Y_AXIS: - if (priv->angle_tilt_y != angle_tilt) - { - priv->angle_tilt_y = angle_tilt; - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_ANGLE_TILT_Y]); - } - break; - - case CLUTTER_Z_AXIS: - if (priv->angle_tilt_z != angle_tilt) - { - priv->angle_tilt_z = angle_tilt; - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_ANGLE_TILT_Z]); - } - break; - } -} - -/** - * clutter_behaviour_ellipse_get_angle_tilt: - * @self: a #ClutterBehaviourEllipse - * @axis: a #ClutterRotateAxis - * - * Gets the tilt of the ellipse around the center in the given axis. - * - * Return value: angle in degrees. - * - * Since: 0.4 - */ -gdouble -clutter_behaviour_ellipse_get_angle_tilt (ClutterBehaviourEllipse *self, - ClutterRotateAxis axis) -{ - g_return_val_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self), 0.0); - - switch (axis) - { - case CLUTTER_X_AXIS: - return self->priv->angle_tilt_x; - - case CLUTTER_Y_AXIS: - return self->priv->angle_tilt_y; - - case CLUTTER_Z_AXIS: - return self->priv->angle_tilt_z; - } - - return 0.0; -} - -/** - * clutter_behaviour_ellipse_set_tilt: - * @self: a #ClutterBehaviourEllipse - * @angle_tilt_x: tilt of the elipse around the center in X axis in degrees. - * @angle_tilt_y: tilt of the elipse around the center in Y axis in degrees. - * @angle_tilt_z: tilt of the elipse around the center in Z axis in degrees. - * - * Sets the angles at which the ellipse should be tilted around it's center. - * - * Since: 0.4 - */ -void -clutter_behaviour_ellipse_set_tilt (ClutterBehaviourEllipse *self, - gdouble angle_tilt_x, - gdouble angle_tilt_y, - gdouble angle_tilt_z) -{ - ClutterBehaviourEllipsePrivate *priv; - - g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self)); - - priv = self->priv; - - g_object_freeze_notify (G_OBJECT (self)); - - if (priv->angle_tilt_x != angle_tilt_x) - { - priv->angle_tilt_x = angle_tilt_x; - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_ANGLE_TILT_X]); - } - - if (priv->angle_tilt_y != angle_tilt_y) - { - priv->angle_tilt_y = angle_tilt_y; - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_ANGLE_TILT_Y]); - } - - if (priv->angle_tilt_z != angle_tilt_z) - { - priv->angle_tilt_z = angle_tilt_z; - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_ANGLE_TILT_Z]); - } - - g_object_thaw_notify (G_OBJECT (self)); -} - -/** - * clutter_behaviour_ellipse_get_tilt: - * @self: a #ClutterBehaviourEllipse - * @angle_tilt_x: (out): return location for tilt angle on the X axis, or %NULL. - * @angle_tilt_y: (out): return location for tilt angle on the Y axis, or %NULL. - * @angle_tilt_z: (out): return location for tilt angle on the Z axis, or %NULL. - * - * Gets the tilt of the ellipse around the center in Y axis. - * - * Since: 0.4 - */ -void -clutter_behaviour_ellipse_get_tilt (ClutterBehaviourEllipse *self, - gdouble *angle_tilt_x, - gdouble *angle_tilt_y, - gdouble *angle_tilt_z) -{ - ClutterBehaviourEllipsePrivate *priv; - - g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self)); - - priv = self->priv; - - if (angle_tilt_x) - *angle_tilt_x = priv->angle_tilt_x; - - if (angle_tilt_y) - *angle_tilt_y = priv->angle_tilt_y; - - if (angle_tilt_z) - *angle_tilt_z = priv->angle_tilt_z; -} - -/** - * clutter_behaviour_ellipse_get_direction: - * @self: a #ClutterBehaviourEllipse - * - * Retrieves the #ClutterRotateDirection used by the ellipse behaviour. - * - * Return value: the rotation direction - * - * Since: 0.4 - */ -ClutterRotateDirection -clutter_behaviour_ellipse_get_direction (ClutterBehaviourEllipse *self) -{ - g_return_val_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self), - CLUTTER_ROTATE_CW); - - return self->priv->direction; -} - -/** - * clutter_behaviour_ellipse_set_direction: - * @self: a #ClutterBehaviourEllipse - * @direction: the rotation direction - * - * Sets the rotation direction used by the ellipse behaviour. - * - * Since: 0.4 - */ -void -clutter_behaviour_ellipse_set_direction (ClutterBehaviourEllipse *self, - ClutterRotateDirection direction) -{ - ClutterBehaviourEllipsePrivate *priv; - - g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ELLIPSE (self)); - - priv = self->priv; - - if (priv->direction != direction) - { - priv->direction = direction; - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_DIRECTION]); - } -} diff --git a/clutter/clutter/deprecated/clutter-behaviour-ellipse.h b/clutter/clutter/deprecated/clutter-behaviour-ellipse.h deleted file mode 100644 index bd9983f35..000000000 --- a/clutter/clutter/deprecated/clutter-behaviour-ellipse.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Tomas Frydrych - * - * Copyright (C) 2007 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __CLUTTER_BEHAVIOUR_ELLIPSE_H__ -#define __CLUTTER_BEHAVIOUR_ELLIPSE_H__ - -#include - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_BEHAVIOUR_ELLIPSE (clutter_behaviour_ellipse_get_type ()) - -#define CLUTTER_BEHAVIOUR_ELLIPSE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ - CLUTTER_TYPE_BEHAVIOUR_ELLIPSE, ClutterBehaviourEllipse)) - -#define CLUTTER_BEHAVIOUR_ELLIPSE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), \ - CLUTTER_TYPE_BEHAVIOUR_ELLIPSE, ClutterBehaviourEllipseClass)) - -#define CLUTTER_IS_BEHAVIOUR_ELLIPSE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ - CLUTTER_TYPE_BEHAVIOUR_ELLIPSE)) - -#define CLUTTER_IS_BEHAVIOUR_ELLIPSE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), \ - CLUTTER_TYPE_BEHAVIOUR_ELLIPSE)) - -#define CLUTTER_BEHAVIOUR_ELLIPSE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), \ - CLUTTER_TYPE_BEHAVIOUR_ELLIPSE, ClutterBehaviourEllipseClass)) - -typedef struct _ClutterBehaviourEllipse ClutterBehaviourEllipse; -typedef struct _ClutterBehaviourEllipsePrivate ClutterBehaviourEllipsePrivate; -typedef struct _ClutterBehaviourEllipseClass ClutterBehaviourEllipseClass; - -/** - * ClutterBehaviourEllipse: - * - * The #ClutterBehaviourEllipse struct contains only private data - * and should be accessed using the provided API - * - * Since: 0.4 - * - * Deprecated: 1.6 - */ -struct _ClutterBehaviourEllipse -{ - /*< private >*/ - ClutterBehaviour parent_instance; - ClutterBehaviourEllipsePrivate *priv; -}; - -/** - * ClutterBehaviourEllipseClass: - * - * The #ClutterBehaviourEllipseClass struct contains only private data - * - * Since: 0.4 - * - * Deprecated: 1.6 - */ -struct _ClutterBehaviourEllipseClass -{ - /*< private >*/ - ClutterBehaviourClass parent_class; -}; - -CLUTTER_DEPRECATED_IN_1_8 -GType clutter_behaviour_ellipse_get_type (void) G_GNUC_CONST; - -CLUTTER_DEPRECATED_IN_1_8_FOR(clutter_actor_animate) -ClutterBehaviour * clutter_behaviour_ellipse_new (ClutterAlpha *alpha, - gint x, - gint y, - gint width, - gint height, - ClutterRotateDirection direction, - gdouble start, - gdouble end); - -CLUTTER_DEPRECATED_IN_1_8 -void clutter_behaviour_ellipse_set_center (ClutterBehaviourEllipse *self, - gint x, - gint y); -CLUTTER_DEPRECATED_IN_1_8 -void clutter_behaviour_ellipse_get_center (ClutterBehaviourEllipse *self, - gint *x, - gint *y); -CLUTTER_DEPRECATED_IN_1_6 -void clutter_behaviour_ellipse_set_width (ClutterBehaviourEllipse *self, - gint width); -CLUTTER_DEPRECATED_IN_1_6 -gint clutter_behaviour_ellipse_get_width (ClutterBehaviourEllipse *self); -CLUTTER_DEPRECATED_IN_1_6 -void clutter_behaviour_ellipse_set_height (ClutterBehaviourEllipse *self, - gint height); -CLUTTER_DEPRECATED_IN_1_6 -gint clutter_behaviour_ellipse_get_height (ClutterBehaviourEllipse *self); -CLUTTER_DEPRECATED_IN_1_6 -void clutter_behaviour_ellipse_set_angle_start (ClutterBehaviourEllipse *self, - gdouble angle_start); -CLUTTER_DEPRECATED_IN_1_6 -gdouble clutter_behaviour_ellipse_get_angle_start (ClutterBehaviourEllipse *self); -CLUTTER_DEPRECATED_IN_1_6 -void clutter_behaviour_ellipse_set_angle_end (ClutterBehaviourEllipse *self, - gdouble angle_end); -CLUTTER_DEPRECATED_IN_1_6 -gdouble clutter_behaviour_ellipse_get_angle_end (ClutterBehaviourEllipse *self); -CLUTTER_DEPRECATED_IN_1_6 -void clutter_behaviour_ellipse_set_angle_tilt (ClutterBehaviourEllipse *self, - ClutterRotateAxis axis, - gdouble angle_tilt); -CLUTTER_DEPRECATED_IN_1_6 -gdouble clutter_behaviour_ellipse_get_angle_tilt (ClutterBehaviourEllipse *self, - ClutterRotateAxis axis); -CLUTTER_DEPRECATED_IN_1_6 -void clutter_behaviour_ellipse_set_tilt (ClutterBehaviourEllipse *self, - gdouble angle_tilt_x, - gdouble angle_tilt_y, - gdouble angle_tilt_z); -CLUTTER_DEPRECATED_IN_1_6 -void clutter_behaviour_ellipse_get_tilt (ClutterBehaviourEllipse *self, - gdouble *angle_tilt_x, - gdouble *angle_tilt_y, - gdouble *angle_tilt_z); -CLUTTER_DEPRECATED_IN_1_6 -ClutterRotateDirection clutter_behaviour_ellipse_get_direction (ClutterBehaviourEllipse *self); -CLUTTER_DEPRECATED_IN_1_6 -void clutter_behaviour_ellipse_set_direction (ClutterBehaviourEllipse *self, - ClutterRotateDirection direction); - -G_END_DECLS - -#endif /* __CLUTTER_BEHAVIOUR_ELLIPSE_H__ */ diff --git a/clutter/clutter/deprecated/clutter-behaviour-opacity.c b/clutter/clutter/deprecated/clutter-behaviour-opacity.c deleted file mode 100644 index 26fb47fa3..000000000 --- a/clutter/clutter/deprecated/clutter-behaviour-opacity.c +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * Copyright (C) 2006 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -/** - * SECTION:clutter-behaviour-opacity - * @Title: ClutterBehaviourOpacity - * @short_description: A behaviour controlling opacity - * @Deprecated: 1.6: Use clutter_actor_animate() instead. - * - * #ClutterBehaviourOpacity controls the opacity of a set of actors. - * - * Since: 0.2 - * - * Deprecated: 1.6: Use the #ClutterActor:opacity property and - * clutter_actor_animate(), or #ClutterAnimator, or #ClutterState - * instead. - */ - -#ifdef HAVE_CONFIG_H -#include "clutter-build-config.h" -#endif - -#include - -#define CLUTTER_DISABLE_DEPRECATION_WARNINGS - -#include "clutter-alpha.h" -#include "clutter-behaviour.h" -#include "clutter-behaviour-opacity.h" -#include "clutter-private.h" -#include "clutter-debug.h" - -struct _ClutterBehaviourOpacityPrivate -{ - guint8 opacity_start; - guint8 opacity_end; -}; - -enum -{ - PROP_0, - - PROP_OPACITY_START, - PROP_OPACITY_END, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST]; - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterBehaviourOpacity, - clutter_behaviour_opacity, - CLUTTER_TYPE_BEHAVIOUR) - -static void -alpha_notify_foreach (ClutterBehaviour *behaviour, - ClutterActor *actor, - gpointer data) -{ - clutter_actor_set_opacity (actor, GPOINTER_TO_UINT(data)); -} - -static void -clutter_behaviour_alpha_notify (ClutterBehaviour *behave, - gdouble alpha_value) -{ - ClutterBehaviourOpacityPrivate *priv; - guint8 opacity; - - priv = CLUTTER_BEHAVIOUR_OPACITY (behave)->priv; - - opacity = alpha_value - * (priv->opacity_end - priv->opacity_start) - + priv->opacity_start; - - CLUTTER_NOTE (ANIMATION, "alpha: %.4f, opacity: %u", - alpha_value, - opacity); - - clutter_behaviour_actors_foreach (behave, - alpha_notify_foreach, - GUINT_TO_POINTER ((guint) opacity)); -} - -static void -clutter_behaviour_opacity_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterBehaviourOpacity *self = CLUTTER_BEHAVIOUR_OPACITY (gobject); - - switch (prop_id) - { - case PROP_OPACITY_START: - clutter_behaviour_opacity_set_bounds (self, - g_value_get_uint (value), - self->priv->opacity_end); - break; - - case PROP_OPACITY_END: - clutter_behaviour_opacity_set_bounds (self, - self->priv->opacity_start, - g_value_get_uint (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_behaviour_opacity_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterBehaviourOpacity *self = CLUTTER_BEHAVIOUR_OPACITY (gobject); - - switch (prop_id) - { - case PROP_OPACITY_START: - g_value_set_uint (value, self->priv->opacity_start); - break; - - case PROP_OPACITY_END: - g_value_set_uint (value, self->priv->opacity_end); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_behaviour_opacity_class_init (ClutterBehaviourOpacityClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterBehaviourClass *behave_class = CLUTTER_BEHAVIOUR_CLASS (klass); - GParamSpec *pspec; - - gobject_class->set_property = clutter_behaviour_opacity_set_property; - gobject_class->get_property = clutter_behaviour_opacity_get_property; - - /** - * ClutterBehaviourOpacity:opacity-start: - * - * Initial opacity level of the behaviour. - * - * Since: 0.2 - * - * Deprecated: 1.6 - */ - pspec = g_param_spec_uint ("opacity-start", - P_("Opacity Start"), - P_("Initial opacity level"), - 0, 255, - 0, - CLUTTER_PARAM_READWRITE); - obj_props[PROP_OPACITY_START] = pspec; - g_object_class_install_property (gobject_class, PROP_OPACITY_START, pspec); - - /** - * ClutterBehaviourOpacity:opacity-end: - * - * Final opacity level of the behaviour. - * - * Since: 0.2 - * - * Deprecated: 1.6 - */ - pspec = g_param_spec_uint ("opacity-end", - P_("Opacity End"), - P_("Final opacity level"), - 0, 255, - 0, - CLUTTER_PARAM_READWRITE); - obj_props[PROP_OPACITY_END] = pspec; - g_object_class_install_property (gobject_class, PROP_OPACITY_END, pspec); - - behave_class->alpha_notify = clutter_behaviour_alpha_notify; -} - -static void -clutter_behaviour_opacity_init (ClutterBehaviourOpacity *self) -{ - self->priv = clutter_behaviour_opacity_get_instance_private (self); -} - -/** - * clutter_behaviour_opacity_new: - * @alpha: (allow-none): a #ClutterAlpha instance, or %NULL - * @opacity_start: minimum level of opacity - * @opacity_end: maximum level of opacity - * - * Creates a new #ClutterBehaviourOpacity object, driven by @alpha - * which controls the opacity property of every actor, making it - * change in the interval between @opacity_start and @opacity_end. - * - * If @alpha is not %NULL, the #ClutterBehaviour will take ownership - * of the #ClutterAlpha instance. In the case when @alpha is %NULL, - * it can be set later with clutter_behaviour_set_alpha(). - * - * Return value: the newly created #ClutterBehaviourOpacity - * - * Since: 0.2 - * - * Deprecated: 1.6 - */ -ClutterBehaviour * -clutter_behaviour_opacity_new (ClutterAlpha *alpha, - guint8 opacity_start, - guint8 opacity_end) -{ - return g_object_new (CLUTTER_TYPE_BEHAVIOUR_OPACITY, - "alpha", alpha, - "opacity-start", opacity_start, - "opacity-end", opacity_end, - NULL); -} - -/** - * clutter_behaviour_opacity_set_bounds: - * @behaviour: a #ClutterBehaviourOpacity - * @opacity_start: minimum level of opacity - * @opacity_end: maximum level of opacity - * - * Sets the initial and final levels of the opacity applied by @behaviour - * on each actor it controls. - * - * Since: 0.6 - * - * Deprecated: 1.6 - */ -void -clutter_behaviour_opacity_set_bounds (ClutterBehaviourOpacity *behaviour, - guint8 opacity_start, - guint8 opacity_end) -{ - ClutterBehaviourOpacityPrivate *priv; - - g_return_if_fail (CLUTTER_IS_BEHAVIOUR_OPACITY (behaviour)); - - priv = behaviour->priv; - - g_object_freeze_notify (G_OBJECT (behaviour)); - - if (priv->opacity_start != opacity_start) - { - priv->opacity_start = opacity_start; - - g_object_notify_by_pspec (G_OBJECT (behaviour), obj_props[PROP_OPACITY_START]); - } - - if (priv->opacity_end != opacity_end) - { - priv->opacity_end = opacity_end; - - g_object_notify_by_pspec (G_OBJECT (behaviour), obj_props[PROP_OPACITY_END]); - } - - g_object_thaw_notify (G_OBJECT (behaviour)); -} - -/** - * clutter_behaviour_opacity_get_bounds: - * @behaviour: a #ClutterBehaviourOpacity - * @opacity_start: (out): return location for the minimum level of opacity, or %NULL - * @opacity_end: (out): return location for the maximum level of opacity, or %NULL - * - * Gets the initial and final levels of the opacity applied by @behaviour - * on each actor it controls. - * - * Since: 0.6 - * - * Deprecated: 1.6 - */ -void -clutter_behaviour_opacity_get_bounds (ClutterBehaviourOpacity *behaviour, - guint8 *opacity_start, - guint8 *opacity_end) -{ - g_return_if_fail (CLUTTER_IS_BEHAVIOUR_OPACITY (behaviour)); - - if (opacity_start) - *opacity_start = behaviour->priv->opacity_start; - - if (opacity_end) - *opacity_end = behaviour->priv->opacity_end; -} diff --git a/clutter/clutter/deprecated/clutter-behaviour-opacity.h b/clutter/clutter/deprecated/clutter-behaviour-opacity.h deleted file mode 100644 index a8beef1fc..000000000 --- a/clutter/clutter/deprecated/clutter-behaviour-opacity.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * Jorn Baayen - * Emmanuele Bassi - * - * Copyright (C) 2006 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __CLUTTER_BEHAVIOUR_OPACITY_H__ -#define __CLUTTER_BEHAVIOUR_OPACITY_H__ - -#include - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_BEHAVIOUR_OPACITY (clutter_behaviour_opacity_get_type ()) - -#define CLUTTER_BEHAVIOUR_OPACITY(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ - CLUTTER_TYPE_BEHAVIOUR_OPACITY, ClutterBehaviourOpacity)) - -#define CLUTTER_BEHAVIOUR_OPACITY_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), \ - CLUTTER_TYPE_BEHAVIOUR_OPACITY, ClutterBehaviourOpacityClass)) - -#define CLUTTER_IS_BEHAVIOUR_OPACITY(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ - CLUTTER_TYPE_BEHAVIOUR_OPACITY)) - -#define CLUTTER_IS_BEHAVIOUR_OPACITY_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), \ - CLUTTER_TYPE_BEHAVIOUR_OPACITY)) - -#define CLUTTER_BEHAVIOUR_OPACITY_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), \ - CLUTTER_TYPE_BEHAVIOUR_OPACITY, ClutterBehaviourOpacityClass)) - -typedef struct _ClutterBehaviourOpacity ClutterBehaviourOpacity; -typedef struct _ClutterBehaviourOpacityPrivate ClutterBehaviourOpacityPrivate; -typedef struct _ClutterBehaviourOpacityClass ClutterBehaviourOpacityClass; - -/** - * ClutterBehaviourOpacity: - * - * The #ClutterBehaviourOpacity structure contains only private data and - * should be accessed using the provided API - * - * Since: 0.2 - * - * Deprecated: 1.6: Use clutter_actor_animate() and #ClutterActor:opacity - * instead. - */ -struct _ClutterBehaviourOpacity -{ - /*< private >*/ - ClutterBehaviour parent; - ClutterBehaviourOpacityPrivate *priv; -}; - -/** - * ClutterBehaviourOpacityClass: - * - * The #ClutterBehaviourOpacityClass structure contains only private data - * - * Since: 0.2 - * - * Deprecated: 1.6 - */ -struct _ClutterBehaviourOpacityClass -{ - /*< private >*/ - ClutterBehaviourClass parent_class; -}; - -CLUTTER_DEPRECATED_IN_1_6 -GType clutter_behaviour_opacity_get_type (void) G_GNUC_CONST; - -CLUTTER_DEPRECATED_IN_1_6_FOR(clutter_actor_animate and ClutterActor:opacity) -ClutterBehaviour *clutter_behaviour_opacity_new (ClutterAlpha *alpha, - guint8 opacity_start, - guint8 opacity_end); - -CLUTTER_DEPRECATED_IN_1_6 -void clutter_behaviour_opacity_set_bounds (ClutterBehaviourOpacity *behaviour, - guint8 opacity_start, - guint8 opacity_end); -CLUTTER_DEPRECATED_IN_1_6 -void clutter_behaviour_opacity_get_bounds (ClutterBehaviourOpacity *behaviour, - guint8 *opacity_start, - guint8 *opacity_end); - -G_END_DECLS - -#endif /* __CLUTTER_BEHAVIOUR_OPACITY_H__ */ diff --git a/clutter/clutter/deprecated/clutter-behaviour-path.c b/clutter/clutter/deprecated/clutter-behaviour-path.c deleted file mode 100644 index 81064fa53..000000000 --- a/clutter/clutter/deprecated/clutter-behaviour-path.c +++ /dev/null @@ -1,467 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By: - * Matthew Allum - * Neil Roberts - * - * Copyright (C) 2006, 2007, 2008 OpenedHand Ltd - * Copyright (C) 2009, 2010 Intel Corp - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -/** - * SECTION:clutter-behaviour-path - * @Title: ClutterBehaviourPath - * @short_description: A behaviour for moving actors along a #ClutterPath - * @Deprecated: 1.6: Use #ClutterPathConstraint and clutter_actor_animate() - * with the #ClutterPathConstraint:offset property instead. - * - * #ClutterBehaviourPath interpolates actors along a defined path. - * - * A path is described by a #ClutterPath object. The path can contain - * straight line parts and bezier curves. If the path contains - * %CLUTTER_PATH_MOVE_TO parts then the actors will jump to those - * coordinates. This can be used make disjoint paths. - * - * When creating a path behaviour in a #ClutterScript, you can specify - * the path property directly as a string. For example: - * - * |[ - * { - * "id" : "spline-path", - * "type" : "ClutterBehaviourPath", - * "path" : "M 50 50 L 100 100", - * "alpha" : { - * "timeline" : "main-timeline", - * "function" : "ramp - * } - * } - * ]| - * - * If the alpha function is a periodic function, i.e. it returns to - * 0.0 after reaching 1.0, then the actors will walk the path back to the - * starting #ClutterKnot. - * - * #ClutterBehaviourPath is available since Clutter 0.2 - * - * Deprecated: 1.6: Use #ClutterPath and #ClutterPathConstraint with - * clutter_actor_animate() instead. - */ - -#ifdef HAVE_CONFIG_H -#include "clutter-build-config.h" -#endif - -#define CLUTTER_DISABLE_DEPRECATION_WARNINGS - -#include "clutter-alpha.h" -#include "clutter-behaviour.h" -#include "clutter-behaviour-path.h" -#include "clutter-bezier.h" -#include "clutter-debug.h" -#include "clutter-enum-types.h" -#include "clutter-main.h" -#include "clutter-marshal.h" -#include "clutter-private.h" -#include "clutter-script-private.h" -#include "clutter-scriptable.h" - -#include - -struct _ClutterBehaviourPathPrivate -{ - ClutterPath *path; - guint last_knot_passed; -}; - -enum -{ - KNOT_REACHED, - - LAST_SIGNAL -}; - -static guint path_signals[LAST_SIGNAL] = { 0, }; - -enum -{ - PROP_0, - - PROP_PATH, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST]; - -static void clutter_scriptable_iface_init (ClutterScriptableIface *iface); - -G_DEFINE_TYPE_WITH_CODE (ClutterBehaviourPath, - clutter_behaviour_path, - CLUTTER_TYPE_BEHAVIOUR, - G_ADD_PRIVATE (ClutterBehaviourPath) - G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_SCRIPTABLE, - clutter_scriptable_iface_init)) - -static void -actor_apply_knot_foreach (ClutterBehaviour *behaviour, - ClutterActor *actor, - gpointer data) -{ - ClutterKnot *knot = data; - - CLUTTER_NOTE (ANIMATION, "Setting actor to %ix%i", knot->x, knot->y); - - clutter_actor_set_position (actor, knot->x, knot->y); -} - -static void -clutter_behaviour_path_alpha_notify (ClutterBehaviour *behave, - gdouble alpha_value) -{ - ClutterBehaviourPath *pathb = CLUTTER_BEHAVIOUR_PATH (behave); - ClutterBehaviourPathPrivate *priv = pathb->priv; - ClutterKnot position; - guint knot_num; - - if (priv->path) - knot_num = clutter_path_get_position (priv->path, alpha_value, &position); - else - { - memset (&position, 0, sizeof (position)); - knot_num = 0; - } - - clutter_behaviour_actors_foreach (behave, - actor_apply_knot_foreach, - &position); - - if (knot_num != priv->last_knot_passed) - { - g_signal_emit (behave, path_signals[KNOT_REACHED], 0, knot_num); - priv->last_knot_passed = knot_num; - } -} - -static void -clutter_behaviour_path_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterBehaviourPath *pathb = CLUTTER_BEHAVIOUR_PATH (gobject); - - switch (prop_id) - { - case PROP_PATH: - g_value_set_object (value, clutter_behaviour_path_get_path (pathb)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_behaviour_path_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterBehaviourPath *pathb = CLUTTER_BEHAVIOUR_PATH (gobject); - - switch (prop_id) - { - case PROP_PATH: - clutter_behaviour_path_set_path (pathb, g_value_get_object (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_behaviour_path_dispose (GObject *gobject) -{ - ClutterBehaviourPath *pathb = CLUTTER_BEHAVIOUR_PATH (gobject); - - clutter_behaviour_path_set_path (pathb, NULL); - - G_OBJECT_CLASS (clutter_behaviour_path_parent_class)->dispose (gobject); -} - -static void -clutter_behaviour_path_class_init (ClutterBehaviourPathClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterBehaviourClass *behave_class = CLUTTER_BEHAVIOUR_CLASS (klass); - GParamSpec *pspec; - - gobject_class->get_property = clutter_behaviour_path_get_property; - gobject_class->set_property = clutter_behaviour_path_set_property; - gobject_class->dispose = clutter_behaviour_path_dispose; - - pspec = g_param_spec_object ("path", - P_("Path"), - P_("The ClutterPath object representing the path " - "to animate along"), - CLUTTER_TYPE_PATH, - CLUTTER_PARAM_READWRITE); - obj_props[PROP_PATH] = pspec; - g_object_class_install_property (gobject_class, PROP_PATH, pspec); - - /** - * ClutterBehaviourPath::knot-reached: - * @pathb: the object which received the signal - * @knot_num: the index of the #ClutterKnot reached - * - * This signal is emitted each time a node defined inside the path - * is reached. - * - * Since: 0.2 - * - * Deprecated: 1.6 - */ - path_signals[KNOT_REACHED] = - g_signal_new ("knot-reached", - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterBehaviourPathClass, knot_reached), - NULL, NULL, - _clutter_marshal_VOID__UINT, - G_TYPE_NONE, 1, - G_TYPE_UINT); - - behave_class->alpha_notify = clutter_behaviour_path_alpha_notify; -} - -static ClutterScriptableIface *parent_scriptable_iface = NULL; - -static gboolean -clutter_behaviour_path_parse_custom_node (ClutterScriptable *scriptable, - ClutterScript *script, - GValue *value, - const gchar *name, - JsonNode *node) -{ - if (strcmp ("path", name) == 0) - { - ClutterPath *path; - GValue node_value = { 0 }; - - path = g_object_ref_sink (clutter_path_new ()); - - json_node_get_value (node, &node_value); - - if (!G_VALUE_HOLDS (&node_value, G_TYPE_STRING) - || !clutter_path_set_description (path, - g_value_get_string (&node_value))) - g_warning ("Invalid path description"); - - g_value_unset (&node_value); - - g_value_init (value, G_TYPE_OBJECT); - g_value_take_object (value, path); - - return TRUE; - } - /* chain up */ - else if (parent_scriptable_iface->parse_custom_node) - return parent_scriptable_iface->parse_custom_node (scriptable, script, - value, name, node); - else - return FALSE; -} - -static void -clutter_scriptable_iface_init (ClutterScriptableIface *iface) -{ - parent_scriptable_iface = g_type_interface_peek_parent (iface); - - if (!parent_scriptable_iface) - parent_scriptable_iface - = g_type_default_interface_peek (CLUTTER_TYPE_SCRIPTABLE); - - iface->parse_custom_node = clutter_behaviour_path_parse_custom_node; -} - -static void -clutter_behaviour_path_init (ClutterBehaviourPath *self) -{ - self->priv = clutter_behaviour_path_get_instance_private (self); - self->priv->last_knot_passed = G_MAXUINT; -} - -/** - * clutter_behaviour_path_new: - * @alpha: (allow-none): a #ClutterAlpha instance, or %NULL - * @path: a #ClutterPath or %NULL for an empty path - * - * Creates a new path behaviour. You can use this behaviour to drive - * actors along the nodes of a path, described by @path. - * - * This will claim the floating reference on the #ClutterPath so you - * do not need to unref if it. - * - * If @alpha is not %NULL, the #ClutterBehaviour will take ownership - * of the #ClutterAlpha instance. In the case when @alpha is %NULL, - * it can be set later with clutter_behaviour_set_alpha(). - * - * Return value: (transfer full): a #ClutterBehaviour - * - * Since: 0.2 - * - * Deprecated: 1.6 - */ -ClutterBehaviour * -clutter_behaviour_path_new (ClutterAlpha *alpha, - ClutterPath *path) -{ - return g_object_new (CLUTTER_TYPE_BEHAVIOUR_PATH, - "alpha", alpha, - "path", path, - NULL); -} - -/** - * clutter_behaviour_path_new_with_description: - * @alpha: (allow-none): a #ClutterAlpha instance, or %NULL - * @desc: a string description of the path - * - * Creates a new path behaviour using the path described by @desc. See - * clutter_path_add_string() for a description of the format. - * - * If @alpha is not %NULL, the #ClutterBehaviour will take ownership - * of the #ClutterAlpha instance. In the case when @alpha is %NULL, - * it can be set later with clutter_behaviour_set_alpha(). - * - * Return value: (transfer full): a #ClutterBehaviour - * - * Since: 1.0 - * - * Deprecated: 1.6 - */ -ClutterBehaviour * -clutter_behaviour_path_new_with_description (ClutterAlpha *alpha, - const gchar *desc) -{ - return g_object_new (CLUTTER_TYPE_BEHAVIOUR_PATH, - "alpha", alpha, - "path", clutter_path_new_with_description (desc), - NULL); -} - -/** - * clutter_behaviour_path_new_with_knots: - * @alpha: (allow-none): a #ClutterAlpha instance, or %NULL - * @knots: (array length=n_knots): an array of #ClutterKnots - * @n_knots: number of entries in @knots - * - * Creates a new path behaviour that will make the actors visit all of - * the given knots in order with straight lines in between. - * - * A path will be created where the first knot is used in a - * %CLUTTER_PATH_MOVE_TO and the subsequent knots are used in - * %CLUTTER_PATH_LINE_TOs. - * - * If @alpha is not %NULL, the #ClutterBehaviour will take ownership - * of the #ClutterAlpha instance. In the case when @alpha is %NULL, - * it can be set later with clutter_behaviour_set_alpha(). - * - * Return value: (transfer full): a #ClutterBehaviour - * - * Since: 1.0 - * - * Deprecated: 1.6 - */ -ClutterBehaviour * -clutter_behaviour_path_new_with_knots (ClutterAlpha *alpha, - const ClutterKnot *knots, - guint n_knots) -{ - ClutterPath *path = clutter_path_new (); - guint i; - - if (n_knots > 0) - { - clutter_path_add_move_to (path, knots[0].x, knots[0].y); - - for (i = 1; i < n_knots; i++) - clutter_path_add_line_to (path, knots[i].x, knots[i].y); - } - - return g_object_new (CLUTTER_TYPE_BEHAVIOUR_PATH, - "alpha", alpha, - "path", path, - NULL); -} - -/** - * clutter_behaviour_path_set_path: - * @pathb: the path behaviour - * @path: the new path to follow - * - * Change the path that the actors will follow. This will take the - * floating reference on the #ClutterPath so you do not need to unref - * it. - * - * Since: 1.0 - * - * Deprecated: 1.6 - */ -void -clutter_behaviour_path_set_path (ClutterBehaviourPath *pathb, - ClutterPath *path) -{ - ClutterBehaviourPathPrivate *priv; - - g_return_if_fail (CLUTTER_IS_BEHAVIOUR_PATH (pathb)); - - priv = pathb->priv; - - if (path) - g_object_ref_sink (path); - - if (priv->path) - g_object_unref (priv->path); - - priv->path = path; - - g_object_notify_by_pspec (G_OBJECT (pathb), obj_props[PROP_PATH]); -} - -/** - * clutter_behaviour_path_get_path: - * @pathb: a #ClutterBehaviourPath instance - * - * Get the current path of the behaviour - * - * Return value: (transfer none): the path - * - * Since: 1.0 - * - * Deprecated: 1.6 - */ -ClutterPath * -clutter_behaviour_path_get_path (ClutterBehaviourPath *pathb) -{ - g_return_val_if_fail (CLUTTER_IS_BEHAVIOUR_PATH (pathb), NULL); - - return pathb->priv->path; -} diff --git a/clutter/clutter/deprecated/clutter-behaviour-path.h b/clutter/clutter/deprecated/clutter-behaviour-path.h deleted file mode 100644 index f78ebcbff..000000000 --- a/clutter/clutter/deprecated/clutter-behaviour-path.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * Jorn Baayen - * Emmanuele Bassi - * - * Copyright (C) 2006 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __CLUTTER_BEHAVIOUR_PATH_H__ -#define __CLUTTER_BEHAVIOUR_PATH_H__ - -#include -#include - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_BEHAVIOUR_PATH (clutter_behaviour_path_get_type ()) - -#define CLUTTER_BEHAVIOUR_PATH(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ - CLUTTER_TYPE_BEHAVIOUR_PATH, ClutterBehaviourPath)) - -#define CLUTTER_BEHAVIOUR_PATH_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), \ - CLUTTER_TYPE_BEHAVIOUR_PATH, ClutterBehaviourPathClass)) - -#define CLUTTER_IS_BEHAVIOUR_PATH(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ - CLUTTER_TYPE_BEHAVIOUR_PATH)) - -#define CLUTTER_IS_BEHAVIOUR_PATH_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), \ - CLUTTER_TYPE_BEHAVIOUR_PATH)) - -#define CLUTTER_BEHAVIOUR_PATH_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), \ - CLUTTER_TYPE_BEHAVIOUR_PATH, ClutterBehaviourPathClass)) - -typedef struct _ClutterBehaviourPath ClutterBehaviourPath; -typedef struct _ClutterBehaviourPathPrivate ClutterBehaviourPathPrivate; -typedef struct _ClutterBehaviourPathClass ClutterBehaviourPathClass; - -/** - * ClutterBehaviourPath: - * - * The #ClutterBehaviourPath structure contains only private data - * and should be accessed using the provided API - * - * Since: 0.2 - * - * Deprecated: 1.6: Use #ClutterPathConstraint and clutter_actor_animate() - * instead. - */ -struct _ClutterBehaviourPath -{ - /*< private >*/ - ClutterBehaviour parent; - ClutterBehaviourPathPrivate *priv; -}; - -/** - * ClutterBehaviourPathClass: - * @knot_reached: signal class handler for the - * ClutterBehaviourPath::knot_reached signal - * - * The #ClutterBehaviourPathClass struct contains only private data - * - * Since: 0.2 - * - * Deprecated: 1.6 - */ -struct _ClutterBehaviourPathClass -{ - /*< private >*/ - ClutterBehaviourClass parent_class; - - /*< public >*/ - void (*knot_reached) (ClutterBehaviourPath *pathb, - guint knot_num); - - /*< private >*/ - void (*_clutter_path_1) (void); - void (*_clutter_path_2) (void); - void (*_clutter_path_3) (void); - void (*_clutter_path_4) (void); -}; - -CLUTTER_DEPRECATED_IN_1_6 -GType clutter_behaviour_path_get_type (void) G_GNUC_CONST; - -CLUTTER_DEPRECATED_IN_1_6_FOR(clutter_actor_animate) -ClutterBehaviour *clutter_behaviour_path_new (ClutterAlpha *alpha, - ClutterPath *path); - -CLUTTER_DEPRECATED_IN_1_6_FOR(clutter_actor_animate) -ClutterBehaviour *clutter_behaviour_path_new_with_description - (ClutterAlpha *alpha, - const gchar *desc); - -CLUTTER_DEPRECATED_IN_1_6_FOR(clutter_actor_animate) -ClutterBehaviour *clutter_behaviour_path_new_with_knots - (ClutterAlpha *alpha, - const ClutterKnot *knots, - guint n_knots); - -CLUTTER_DEPRECATED_IN_1_6 -void clutter_behaviour_path_set_path (ClutterBehaviourPath *pathb, - ClutterPath *path); -CLUTTER_DEPRECATED_IN_1_6 -ClutterPath * clutter_behaviour_path_get_path (ClutterBehaviourPath *pathb); - -G_END_DECLS - -#endif /* __CLUTTER_BEHAVIOUR_PATH_H__ */ diff --git a/clutter/clutter/deprecated/clutter-behaviour-rotate.c b/clutter/clutter/deprecated/clutter-behaviour-rotate.c deleted file mode 100644 index 7096e83b6..000000000 --- a/clutter/clutter/deprecated/clutter-behaviour-rotate.c +++ /dev/null @@ -1,690 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * Copyright (C) 2007 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -/** - * SECTION:clutter-behaviour-rotate - * @short_description: A behaviour controlling rotation - * - * A #ClutterBehaviourRotate rotate actors between a starting and ending - * angle on a given axis. - * - * The #ClutterBehaviourRotate is available since version 0.4. - * - * Deprecated: 1.6: Use the #ClutterActor rotation properties and - * clutter_actor_animate(), or #ClutterAnimator, or #ClutterState - * instead. - */ - -#ifdef HAVE_CONFIG_H -#include "clutter-build-config.h" -#endif - -#include - -#define CLUTTER_DISABLE_DEPRECATION_WARNINGS -#include "deprecated/clutter-actor.h" - -#include "clutter-alpha.h" -#include "clutter-behaviour.h" -#include "clutter-behaviour-rotate.h" -#include "clutter-debug.h" -#include "clutter-enum-types.h" -#include "clutter-main.h" -#include "clutter-private.h" - -struct _ClutterBehaviourRotatePrivate -{ - gdouble angle_start; - gdouble angle_end; - - ClutterRotateAxis axis; - ClutterRotateDirection direction; - - gint center_x; - gint center_y; - gint center_z; -}; - -enum -{ - PROP_0, - - PROP_ANGLE_START, - PROP_ANGLE_END, - PROP_AXIS, - PROP_DIRECTION, - PROP_CENTER_X, - PROP_CENTER_Y, - PROP_CENTER_Z, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST]; - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterBehaviourRotate, - clutter_behaviour_rotate, - CLUTTER_TYPE_BEHAVIOUR) - -typedef struct { - gdouble angle; -} RotateFrameClosure; - -static void -alpha_notify_foreach (ClutterBehaviour *behaviour, - ClutterActor *actor, - gpointer data) -{ - RotateFrameClosure *closure = data; - ClutterBehaviourRotate *rotate_behaviour; - ClutterBehaviourRotatePrivate *priv; - - rotate_behaviour = CLUTTER_BEHAVIOUR_ROTATE (behaviour); - priv = rotate_behaviour->priv; - - clutter_actor_set_rotation (actor, priv->axis, - closure->angle, - priv->center_x, - priv->center_y, - priv->center_z); -} - -static inline float -clamp_angle (float a) -{ - float a1, a2; - gint rounds; - - rounds = a / 360.0; - a1 = rounds * 360.0; - a2 = a - a1; - - return a2; -} - -static void -clutter_behaviour_rotate_alpha_notify (ClutterBehaviour *behaviour, - gdouble alpha_value) -{ - ClutterBehaviourRotate *rotate_behaviour; - ClutterBehaviourRotatePrivate *priv; - RotateFrameClosure closure; - gdouble start, end; - - rotate_behaviour = CLUTTER_BEHAVIOUR_ROTATE (behaviour); - priv = rotate_behaviour->priv; - - closure.angle = 0; - start = priv->angle_start; - end = priv->angle_end; - - if (priv->direction == CLUTTER_ROTATE_CW && start >= end) - end += 360.0; - else if (priv->direction == CLUTTER_ROTATE_CCW && start <= end) - end -= 360.0; - - closure.angle = (end - start) * alpha_value + start; - - clutter_behaviour_actors_foreach (behaviour, - alpha_notify_foreach, - &closure); -} - -static void -clutter_behaviour_rotate_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterBehaviourRotate *rotate; - ClutterBehaviourRotatePrivate *priv; - - rotate = CLUTTER_BEHAVIOUR_ROTATE (gobject); - priv = rotate->priv; - - switch (prop_id) - { - case PROP_ANGLE_START: - priv->angle_start = g_value_get_double (value); - break; - - case PROP_ANGLE_END: - priv->angle_end = g_value_get_double (value); - break; - - case PROP_AXIS: - priv->axis = g_value_get_enum (value); - break; - - case PROP_DIRECTION: - priv->direction = g_value_get_enum (value); - break; - - case PROP_CENTER_X: - clutter_behaviour_rotate_set_center (rotate, - g_value_get_int (value), - priv->center_y, - priv->center_z); - break; - - case PROP_CENTER_Y: - clutter_behaviour_rotate_set_center (rotate, - priv->center_x, - g_value_get_int (value), - priv->center_z); - break; - - case PROP_CENTER_Z: - clutter_behaviour_rotate_set_center (rotate, - priv->center_x, - priv->center_y, - g_value_get_int (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_behaviour_rotate_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterBehaviourRotatePrivate *priv; - - priv = CLUTTER_BEHAVIOUR_ROTATE (gobject)->priv; - - switch (prop_id) - { - case PROP_ANGLE_START: - g_value_set_double (value, priv->angle_start); - break; - - case PROP_ANGLE_END: - g_value_set_double (value, priv->angle_end); - break; - - case PROP_AXIS: - g_value_set_enum (value, priv->axis); - break; - - case PROP_DIRECTION: - g_value_set_enum (value, priv->direction); - break; - - case PROP_CENTER_X: - g_value_set_int (value, priv->center_x); - break; - - case PROP_CENTER_Y: - g_value_set_int (value, priv->center_y); - break; - - case PROP_CENTER_Z: - g_value_set_int (value, priv->center_z); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_behaviour_rotate_class_init (ClutterBehaviourRotateClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterBehaviourClass *behaviour_class = CLUTTER_BEHAVIOUR_CLASS (klass); - GParamSpec *pspec = NULL; - - gobject_class->set_property = clutter_behaviour_rotate_set_property; - gobject_class->get_property = clutter_behaviour_rotate_get_property; - - behaviour_class->alpha_notify = clutter_behaviour_rotate_alpha_notify; - - /** - * ClutterBehaviourRotate:angle-start: - * - * The initial angle from whence the rotation should start. - * - * Since: 0.4 - */ - pspec = g_param_spec_double ("angle-start", - P_("Angle Begin"), - P_("Initial angle"), - 0.0, 360.0, - 0.0, - CLUTTER_PARAM_READWRITE); - obj_props[PROP_ANGLE_START] = pspec; - g_object_class_install_property (gobject_class, - PROP_ANGLE_START, - pspec); - - /** - * ClutterBehaviourRotate:angle-end: - * - * The final angle to where the rotation should end. - * - * Since: 0.4 - */ - pspec = g_param_spec_double ("angle-end", - P_("Angle End"), - P_("Final angle"), - 0.0, 360.0, - 0.0, - CLUTTER_PARAM_READWRITE); - obj_props[PROP_ANGLE_END] = pspec; - g_object_class_install_property (gobject_class, - PROP_ANGLE_END, - pspec); - - /** - * ClutterBehaviourRotate:axis: - * - * The axis of rotation. - * - * Since: 0.4 - */ - pspec = g_param_spec_enum ("axis", - P_("Axis"), - P_("Axis of rotation"), - CLUTTER_TYPE_ROTATE_AXIS, - CLUTTER_Z_AXIS, - CLUTTER_PARAM_READWRITE); - obj_props[PROP_AXIS] = pspec; - g_object_class_install_property (gobject_class, - PROP_AXIS, - pspec); - - /** - * ClutterBehaviourRotate:direction: - * - * The direction of the rotation. - * - * Since: 0.4 - */ - pspec = g_param_spec_enum ("direction", - P_("Direction"), - P_("Direction of rotation"), - CLUTTER_TYPE_ROTATE_DIRECTION, - CLUTTER_ROTATE_CW, - CLUTTER_PARAM_READWRITE); - obj_props[PROP_DIRECTION] = pspec; - g_object_class_install_property (gobject_class, - PROP_DIRECTION, - pspec); - - /** - * ClutterBehaviourRotate:center-x: - * - * The x center of rotation. - * - * Since: 0.4 - */ - pspec = g_param_spec_int ("center-x", - P_("Center X"), - P_("X coordinate of the center of rotation"), - -G_MAXINT, G_MAXINT, - 0, - CLUTTER_PARAM_READWRITE); - obj_props[PROP_CENTER_X] = pspec; - g_object_class_install_property (gobject_class, - PROP_CENTER_X, - pspec); - - /** - * ClutterBehaviourRotate:center-y: - * - * The y center of rotation. - * - * Since: 0.4 - */ - pspec = g_param_spec_int ("center-y", - P_("Center Y"), - P_("Y coordinate of the center of rotation"), - -G_MAXINT, G_MAXINT, - 0, - CLUTTER_PARAM_READWRITE); - obj_props[PROP_CENTER_Y] = pspec; - g_object_class_install_property (gobject_class, - PROP_CENTER_Y, - pspec); - - /** - * ClutterBehaviourRotate:center-z: - * - * The z center of rotation. - * - * Since: 0.4 - */ - pspec = g_param_spec_int ("center-z", - P_("Center Z"), - P_("Z coordinate of the center of rotation"), - -G_MAXINT, G_MAXINT, - 0, - CLUTTER_PARAM_READWRITE); - obj_props[PROP_CENTER_Z] = pspec; - g_object_class_install_property (gobject_class, - PROP_CENTER_Z, - pspec); -} - -static void -clutter_behaviour_rotate_init (ClutterBehaviourRotate *self) -{ - self->priv = clutter_behaviour_rotate_get_instance_private (self); - - self->priv->angle_start = 0.0; - self->priv->angle_end = 0.0; - - self->priv->axis = CLUTTER_Z_AXIS; - self->priv->direction = CLUTTER_ROTATE_CW; - - self->priv->center_x = 0; - self->priv->center_y = 0; - self->priv->center_z = 0; -} - -/** - * clutter_behaviour_rotate_new: - * @alpha: (allow-none): a #ClutterAlpha instance, or %NULL - * @axis: the rotation axis - * @direction: the rotation direction - * @angle_start: the starting angle in degrees, between 0 and 360. - * @angle_end: the final angle in degrees, between 0 and 360. - * - * Creates a new #ClutterBehaviourRotate. This behaviour will rotate actors - * bound to it on @axis, following @direction, between @angle_start and - * @angle_end. Angles >= 360 degrees will be clamped to the canonical interval - * <0, 360), if angle_start == angle_end, the behaviour will carry out a - * single rotation of 360 degrees. - * - * If @alpha is not %NULL, the #ClutterBehaviour will take ownership - * of the #ClutterAlpha instance. In the case when @alpha is %NULL, - * it can be set later with clutter_behaviour_set_alpha(). - * - * Return value: the newly created #ClutterBehaviourRotate. - * - * Since: 0.4 - */ -ClutterBehaviour * -clutter_behaviour_rotate_new (ClutterAlpha *alpha, - ClutterRotateAxis axis, - ClutterRotateDirection direction, - gdouble angle_start, - gdouble angle_end) -{ - g_return_val_if_fail (alpha == NULL || CLUTTER_IS_ALPHA (alpha), NULL); - - return g_object_new (CLUTTER_TYPE_BEHAVIOUR_ROTATE, - "alpha", alpha, - "axis", axis, - "direction", direction, - "angle-start", angle_start, - "angle-end", angle_end, - NULL); -} - -/** - * clutter_behaviour_rotate_get_axis: - * @rotate: a #ClutterBehaviourRotate - * - * Retrieves the #ClutterRotateAxis used by the rotate behaviour. - * - * Return value: the rotation axis - * - * Since: 0.4 - */ -ClutterRotateAxis -clutter_behaviour_rotate_get_axis (ClutterBehaviourRotate *rotate) -{ - g_return_val_if_fail (CLUTTER_IS_BEHAVIOUR_ROTATE (rotate), CLUTTER_Z_AXIS); - - return rotate->priv->axis; -} - -/** - * clutter_behaviour_rotate_set_axis: - * @rotate: a #ClutterBehaviourRotate - * @axis: a #ClutterRotateAxis - * - * Sets the axis used by the rotate behaviour. - * - * Since: 0.4 - */ -void -clutter_behaviour_rotate_set_axis (ClutterBehaviourRotate *rotate, - ClutterRotateAxis axis) -{ - ClutterBehaviourRotatePrivate *priv; - - g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ROTATE (rotate)); - - priv = rotate->priv; - - if (priv->axis != axis) - { - priv->axis = axis; - - g_object_notify_by_pspec (G_OBJECT (rotate), obj_props[PROP_AXIS]); - } -} - -/** - * clutter_behaviour_rotate_get_direction: - * @rotate: a #ClutterBehaviourRotate - * - * Retrieves the #ClutterRotateDirection used by the rotate behaviour. - * - * Return value: the rotation direction - * - * Since: 0.4 - */ -ClutterRotateDirection -clutter_behaviour_rotate_get_direction (ClutterBehaviourRotate *rotate) -{ - g_return_val_if_fail (CLUTTER_IS_BEHAVIOUR_ROTATE (rotate), - CLUTTER_ROTATE_CW); - - return rotate->priv->direction; -} - -/** - * clutter_behaviour_rotate_set_direction: - * @rotate: a #ClutterBehaviourRotate - * @direction: the rotation direction - * - * Sets the rotation direction used by the rotate behaviour. - * - * Since: 0.4 - */ -void -clutter_behaviour_rotate_set_direction (ClutterBehaviourRotate *rotate, - ClutterRotateDirection direction) -{ - ClutterBehaviourRotatePrivate *priv; - - g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ROTATE (rotate)); - - priv = rotate->priv; - - if (priv->direction != direction) - { - priv->direction = direction; - - g_object_notify_by_pspec (G_OBJECT (rotate), obj_props[PROP_DIRECTION]); - } -} - -/** - * clutter_behaviour_rotate_get_bounds: - * @rotate: a #ClutterBehaviourRotate - * @angle_start: (out): return value for the initial angle - * @angle_end: (out): return value for the final angle - * - * Retrieves the rotation boundaries of the rotate behaviour. - * - * Since: 0.4 - */ -void -clutter_behaviour_rotate_get_bounds (ClutterBehaviourRotate *rotate, - gdouble *angle_start, - gdouble *angle_end) -{ - ClutterBehaviourRotatePrivate *priv; - - g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ROTATE (rotate)); - - priv = rotate->priv; - - if (angle_start) - *angle_start = priv->angle_start; - - if (angle_end) - *angle_end = priv->angle_end; -} - -/** - * clutter_behaviour_rotate_set_bounds: - * @rotate: a #ClutterBehaviourRotate - * @angle_start: initial angle in degrees, between 0 and 360. - * @angle_end: final angle in degrees, between 0 and 360. - * - * Sets the initial and final angles of a rotation behaviour; angles >= 360 - * degrees get clamped to the canonical interval <0, 360). - * - * Since: 0.4 - */ -void -clutter_behaviour_rotate_set_bounds (ClutterBehaviourRotate *rotate, - gdouble angle_start, - gdouble angle_end) -{ - ClutterBehaviourRotatePrivate *priv; - - g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ROTATE (rotate)); - - priv = rotate->priv; - - g_object_freeze_notify (G_OBJECT (rotate)); - - if (priv->angle_start != angle_start) - { - priv->angle_start = clamp_angle (angle_start); - - g_object_notify_by_pspec (G_OBJECT (rotate), obj_props[PROP_ANGLE_START]); - } - - if (priv->angle_end != angle_end) - { - priv->angle_end = clamp_angle (angle_end); - - g_object_notify_by_pspec (G_OBJECT (rotate), obj_props[PROP_ANGLE_END]); - } - - g_object_thaw_notify (G_OBJECT (rotate)); -} - -/** - * clutter_behaviour_rotate_set_center: - * @rotate: a #ClutterBehaviourRotate - * @x: X axis center of rotation - * @y: Y axis center of rotation - * @z: Z axis center of rotation - * - * Sets the center of rotation. The coordinates are relative to the plane - * normal to the rotation axis set with clutter_behaviour_rotate_set_axis(). - * - * Since: 0.4 - */ -void -clutter_behaviour_rotate_set_center (ClutterBehaviourRotate *rotate, - gint x, - gint y, - gint z) -{ - ClutterBehaviourRotatePrivate *priv; - - g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ROTATE (rotate)); - - priv = rotate->priv; - - g_object_freeze_notify (G_OBJECT (rotate)); - - if (priv->center_x != x) - { - priv->center_x = x; - g_object_notify_by_pspec (G_OBJECT (rotate), obj_props[PROP_CENTER_X]); - } - - if (priv->center_y != y) - { - priv->center_y = y; - g_object_notify_by_pspec (G_OBJECT (rotate), obj_props[PROP_CENTER_Y]); - } - - if (priv->center_z != z) - { - priv->center_z = z; - g_object_notify_by_pspec (G_OBJECT (rotate), obj_props[PROP_CENTER_Z]); - } - - g_object_thaw_notify (G_OBJECT (rotate)); -} - -/** - * clutter_behaviour_rotate_get_center: - * @rotate: a #ClutterBehaviourRotate - * @x: (out): return location for the X center of rotation - * @y: (out): return location for the Y center of rotation - * @z: (out): return location for the Z center of rotation - * - * Retrieves the center of rotation set using - * clutter_behaviour_rotate_set_center(). - * - * Since: 0.4 - */ -void -clutter_behaviour_rotate_get_center (ClutterBehaviourRotate *rotate, - gint *x, - gint *y, - gint *z) -{ - ClutterBehaviourRotatePrivate *priv; - - g_return_if_fail (CLUTTER_IS_BEHAVIOUR_ROTATE (rotate)); - - priv = rotate->priv; - - if (x) - *x = priv->center_x; - - if (y) - *y = priv->center_y; - - if (z) - *z = priv->center_z; -} diff --git a/clutter/clutter/deprecated/clutter-behaviour-rotate.h b/clutter/clutter/deprecated/clutter-behaviour-rotate.h deleted file mode 100644 index 55f58b322..000000000 --- a/clutter/clutter/deprecated/clutter-behaviour-rotate.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * Copyright (C) 2007 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __CLUTTER_BEHAVIOUR_ROTATE_H__ -#define __CLUTTER_BEHAVIOUR_ROTATE_H__ - -#include - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_BEHAVIOUR_ROTATE (clutter_behaviour_rotate_get_type ()) -#define CLUTTER_BEHAVIOUR_ROTATE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BEHAVIOUR_ROTATE, ClutterBehaviourRotate)) -#define CLUTTER_IS_BEHAVIOUR_ROTATE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BEHAVIOUR_ROTATE)) -#define CLUTTER_BEHAVIOUR_ROTATE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BEHAVIOUR_ROTATE, ClutterBehaviourRotateClass)) -#define CLUTTER_IS_BEHAVIOUR_ROTATE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BEHAVIOUR_ROTATE)) -#define CLUTTER_BEHAVIOUR_ROTATE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((klass), CLUTTER_TYPE_BEHAVIOUR_ROTATE, ClutterBehaviourRotateClass)) - -typedef struct _ClutterBehaviourRotate ClutterBehaviourRotate; -typedef struct _ClutterBehaviourRotatePrivate ClutterBehaviourRotatePrivate; -typedef struct _ClutterBehaviourRotateClass ClutterBehaviourRotateClass; - -/** - * ClutterBehaviourRotate: - * - * The #ClutterBehaviourRotate struct contains only private data and - * should be accessed using the provided API - * - * Since: 0.4 - * - * Deprecated: 1.6: Use clutter_actor_animate() instead. - */ -struct _ClutterBehaviourRotate -{ - /*< private >*/ - ClutterBehaviour parent_instance; - - ClutterBehaviourRotatePrivate *priv; -}; - -/** - * ClutterBehaviourRotateClass: - * - * The #ClutterBehaviourRotateClass struct contains only private data - * - * Since: 0.4 - * - * Deprecated: 1.6 - */ -struct _ClutterBehaviourRotateClass -{ - /*< private >*/ - ClutterBehaviourClass parent_class; -}; - -CLUTTER_DEPRECATED_IN_1_6 -GType clutter_behaviour_rotate_get_type (void) G_GNUC_CONST; - -CLUTTER_DEPRECATED_IN_1_6_FOR(clutter_actor_animate) -ClutterBehaviour * clutter_behaviour_rotate_new (ClutterAlpha *alpha, - ClutterRotateAxis axis, - ClutterRotateDirection direction, - gdouble angle_start, - gdouble angle_end); -CLUTTER_DEPRECATED_IN_1_6 -void clutter_behaviour_rotate_get_center (ClutterBehaviourRotate *rotate, - gint *x, - gint *y, - gint *z); -CLUTTER_DEPRECATED_IN_1_6 -void clutter_behaviour_rotate_set_center (ClutterBehaviourRotate *rotate, - gint x, - gint y, - gint z); -CLUTTER_DEPRECATED_IN_1_6 -ClutterRotateAxis clutter_behaviour_rotate_get_axis (ClutterBehaviourRotate *rotate); -CLUTTER_DEPRECATED_IN_1_6 -void clutter_behaviour_rotate_set_axis (ClutterBehaviourRotate *rotate, - ClutterRotateAxis axis); -CLUTTER_DEPRECATED_IN_1_6 -ClutterRotateDirection clutter_behaviour_rotate_get_direction (ClutterBehaviourRotate *rotate); -CLUTTER_DEPRECATED_IN_1_6 -void clutter_behaviour_rotate_set_direction (ClutterBehaviourRotate *rotate, - ClutterRotateDirection direction); -CLUTTER_DEPRECATED_IN_1_6 -void clutter_behaviour_rotate_get_bounds (ClutterBehaviourRotate *rotate, - gdouble *angle_start, - gdouble *angle_end); -CLUTTER_DEPRECATED_IN_1_6 -void clutter_behaviour_rotate_set_bounds (ClutterBehaviourRotate *rotate, - gdouble angle_start, - gdouble angle_end); - -G_END_DECLS - -#endif /* __CLUTTER_BEHAVIOUR_ROTATE_H__ */ diff --git a/clutter/clutter/deprecated/clutter-behaviour-scale.c b/clutter/clutter/deprecated/clutter-behaviour-scale.c deleted file mode 100644 index 82976fd99..000000000 --- a/clutter/clutter/deprecated/clutter-behaviour-scale.c +++ /dev/null @@ -1,439 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * Copyright (C) 2006 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -/** - * SECTION:clutter-behaviour-scale - * @Title: ClutterBehaviourScale - * @short_description: A behaviour controlling scale - * @Deprecated: 1.6: Use clutter_actor_animate() with #ClutterActor:scale-x - * and #ClutterActor:scale-y instead. - * - * A #ClutterBehaviourScale interpolates actors size between two values. - * - * Deprecated: 1.6: Use the #ClutterActor:scale-x and #ClutterActor:scale-y - * properties, and clutter_actor_animate(), or #ClutterAnimator or - * #ClutterState instead. - */ - -#ifdef HAVE_CONFIG_H -#include "clutter-build-config.h" -#endif - -#include - -#define CLUTTER_DISABLE_DEPRECATION_WARNINGS -#include "deprecated/clutter-actor.h" - -#include "clutter-alpha.h" -#include "clutter-behaviour.h" -#include "clutter-behaviour-scale.h" -#include "clutter-debug.h" -#include "clutter-main.h" -#include "clutter-private.h" - -struct _ClutterBehaviourScalePrivate -{ - gdouble x_scale_start; - gdouble y_scale_start; - - gdouble x_scale_end; - gdouble y_scale_end; -}; - -enum -{ - PROP_0, - - PROP_X_SCALE_START, - PROP_Y_SCALE_START, - PROP_X_SCALE_END, - PROP_Y_SCALE_END, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST]; - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterBehaviourScale, - clutter_behaviour_scale, - CLUTTER_TYPE_BEHAVIOUR) - -typedef struct { - gdouble scale_x; - gdouble scale_y; -} ScaleFrameClosure; - -static void -scale_frame_foreach (ClutterBehaviour *behaviour, - ClutterActor *actor, - gpointer data) -{ - ScaleFrameClosure *closure = data; - - clutter_actor_set_scale (actor, closure->scale_x, closure->scale_y); -} - -static void -clutter_behaviour_scale_alpha_notify (ClutterBehaviour *behave, - gdouble alpha_value) -{ - ClutterBehaviourScalePrivate *priv; - ScaleFrameClosure closure = { 0, }; - - priv = CLUTTER_BEHAVIOUR_SCALE (behave)->priv; - - /* Fix the start/end values, avoids potential rounding errors on large - * values. - */ - if (alpha_value == 1.0) - { - closure.scale_x = priv->x_scale_end; - closure.scale_y = priv->y_scale_end; - } - else if (alpha_value == 0) - { - closure.scale_x = priv->x_scale_start; - closure.scale_y = priv->y_scale_start; - } - else - { - closure.scale_x = (priv->x_scale_end - priv->x_scale_start) - * alpha_value - + priv->x_scale_start; - - closure.scale_y = (priv->y_scale_end - priv->y_scale_start) - * alpha_value - + priv->y_scale_start; - } - - clutter_behaviour_actors_foreach (behave, - scale_frame_foreach, - &closure); -} - -static void -clutter_behaviour_scale_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterBehaviourScalePrivate *priv; - - priv = CLUTTER_BEHAVIOUR_SCALE (gobject)->priv; - - switch (prop_id) - { - case PROP_X_SCALE_START: - priv->x_scale_start = g_value_get_double (value); - break; - - case PROP_X_SCALE_END: - priv->x_scale_end = g_value_get_double (value); - break; - - case PROP_Y_SCALE_START: - priv->y_scale_start = g_value_get_double (value); - break; - - case PROP_Y_SCALE_END: - priv->y_scale_end = g_value_get_double (value); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_behaviour_scale_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterBehaviourScalePrivate *priv; - - priv = CLUTTER_BEHAVIOUR_SCALE (gobject)->priv; - - switch (prop_id) - { - case PROP_X_SCALE_START: - g_value_set_double (value, priv->x_scale_start); - break; - - case PROP_X_SCALE_END: - g_value_set_double (value, priv->x_scale_end); - break; - - case PROP_Y_SCALE_START: - g_value_set_double (value, priv->y_scale_start); - break; - - case PROP_Y_SCALE_END: - g_value_set_double (value, priv->y_scale_end); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_behaviour_scale_class_init (ClutterBehaviourScaleClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterBehaviourClass *behave_class = CLUTTER_BEHAVIOUR_CLASS (klass); - GParamSpec *pspec = NULL; - - gobject_class->set_property = clutter_behaviour_scale_set_property; - gobject_class->get_property = clutter_behaviour_scale_get_property; - - /** - * ClutterBehaviourScale:x-scale-start: - * - * The initial scaling factor on the X axis for the actors. - * - * Since: 0.6 - * - * Deprecated: 1.6 - */ - pspec = g_param_spec_double ("x-scale-start", - P_("X Start Scale"), - P_("Initial scale on the X axis"), - 0.0, G_MAXDOUBLE, - 1.0, - CLUTTER_PARAM_READWRITE); - obj_props[PROP_X_SCALE_START] = pspec; - g_object_class_install_property (gobject_class, - PROP_X_SCALE_START, - pspec); - /** - * ClutterBehaviourScale:x-scale-end: - * - * The final scaling factor on the X axis for the actors. - * - * Since: 0.6 - * - * Deprecated: 1.6 - */ - pspec = g_param_spec_double ("x-scale-end", - P_("X End Scale"), - P_("Final scale on the X axis"), - 0.0, G_MAXDOUBLE, - 1.0, - CLUTTER_PARAM_READWRITE); - obj_props[PROP_X_SCALE_END] = pspec; - g_object_class_install_property (gobject_class, - PROP_X_SCALE_END, - pspec); - /** - * ClutterBehaviourScale:y-scale-start: - * - * The initial scaling factor on the Y axis for the actors. - * - * Since: 0.6 - * - * Deprecated: 1.6 - */ - pspec = g_param_spec_double ("y-scale-start", - P_("Y Start Scale"), - P_("Initial scale on the Y axis"), - 0.0, G_MAXDOUBLE, - 1.0, - CLUTTER_PARAM_READWRITE); - obj_props[PROP_Y_SCALE_START] = pspec; - g_object_class_install_property (gobject_class, - PROP_Y_SCALE_START, - pspec); - /** - * ClutterBehaviourScale:y-scale-end: - * - * The final scaling factor on the Y axis for the actors. - * - * Since: 0.6 - * - * Deprecated: 1.6 - */ - pspec = g_param_spec_double ("y-scale-end", - P_("Y End Scale"), - P_("Final scale on the Y axis"), - 0.0, G_MAXDOUBLE, - 1.0, - CLUTTER_PARAM_READWRITE); - obj_props[PROP_Y_SCALE_END] = pspec; - g_object_class_install_property (gobject_class, - PROP_Y_SCALE_END, - pspec); - - behave_class->alpha_notify = clutter_behaviour_scale_alpha_notify; -} - -static void -clutter_behaviour_scale_init (ClutterBehaviourScale *self) -{ - ClutterBehaviourScalePrivate *priv; - - self->priv = priv = clutter_behaviour_scale_get_instance_private (self); - - priv->x_scale_start = priv->x_scale_end = 1.0; - priv->y_scale_start = priv->y_scale_end = 1.0; -} - -/** - * clutter_behaviour_scale_new: - * @alpha: (allow-none): a #ClutterAlpha instance, or %NULL - * @x_scale_start: initial scale factor on the X axis - * @y_scale_start: initial scale factor on the Y axis - * @x_scale_end: final scale factor on the X axis - * @y_scale_end: final scale factor on the Y axis - * - * Creates a new #ClutterBehaviourScale instance. - * - * If @alpha is not %NULL, the #ClutterBehaviour will take ownership - * of the #ClutterAlpha instance. In the case when @alpha is %NULL, - * it can be set later with clutter_behaviour_set_alpha(). - * - * Return value: (transfer full): the newly created #ClutterBehaviourScale - * - * Since: 0.2 - * - * Deprecated: 1.6 - */ -ClutterBehaviour * -clutter_behaviour_scale_new (ClutterAlpha *alpha, - gdouble x_scale_start, - gdouble y_scale_start, - gdouble x_scale_end, - gdouble y_scale_end) -{ - g_return_val_if_fail (alpha == NULL || CLUTTER_IS_ALPHA (alpha), NULL); - - return g_object_new (CLUTTER_TYPE_BEHAVIOUR_SCALE, - "alpha", alpha, - "x-scale-start", x_scale_start, - "y-scale-start", y_scale_start, - "x-scale-end", x_scale_end, - "y-scale-end", y_scale_end, - NULL); -} - -/** - * clutter_behaviour_scale_set_bounds: - * @scale: a #ClutterBehaviourScale - * @x_scale_start: initial scale factor on the X axis - * @y_scale_start: initial scale factor on the Y axis - * @x_scale_end: final scale factor on the X axis - * @y_scale_end: final scale factor on the Y axis - * - * Sets the bounds used by scale behaviour. - * - * Since: 0.6 - * - * Deprecated: 1.6 - */ -void -clutter_behaviour_scale_set_bounds (ClutterBehaviourScale *scale, - gdouble x_scale_start, - gdouble y_scale_start, - gdouble x_scale_end, - gdouble y_scale_end) -{ - ClutterBehaviourScalePrivate *priv; - - g_return_if_fail (CLUTTER_IS_BEHAVIOUR_SCALE (scale)); - - priv = scale->priv; - - g_object_freeze_notify (G_OBJECT (scale)); - - if (priv->x_scale_start != x_scale_start) - { - priv->x_scale_start = x_scale_start; - g_object_notify_by_pspec (G_OBJECT (scale), obj_props[PROP_X_SCALE_START]); - } - - if (priv->y_scale_start != y_scale_start) - { - priv->y_scale_start = y_scale_start; - g_object_notify_by_pspec (G_OBJECT (scale), obj_props[PROP_Y_SCALE_START]); - } - - if (priv->x_scale_end != x_scale_end) - { - priv->x_scale_end = x_scale_end; - g_object_notify_by_pspec (G_OBJECT (scale), obj_props[PROP_X_SCALE_END]); - } - - if (priv->y_scale_end != y_scale_end) - { - priv->y_scale_end = y_scale_end; - g_object_notify_by_pspec (G_OBJECT (scale), obj_props[PROP_Y_SCALE_END]); - } - - g_object_thaw_notify (G_OBJECT (scale)); -} - -/** - * clutter_behaviour_scale_get_bounds: - * @scale: a #ClutterBehaviourScale - * @x_scale_start: (out): return location for the initial scale factor on the X - * axis, or %NULL - * @y_scale_start: (out): return location for the initial scale factor on the Y - * axis, or %NULL - * @x_scale_end: (out): return location for the final scale factor on the X axis, - * or %NULL - * @y_scale_end: (out): return location for the final scale factor on the Y axis, - * or %NULL - * - * Retrieves the bounds used by scale behaviour. - * - * Since: 0.4 - * - * Deprecated: 1.6 - */ -void -clutter_behaviour_scale_get_bounds (ClutterBehaviourScale *scale, - gdouble *x_scale_start, - gdouble *y_scale_start, - gdouble *x_scale_end, - gdouble *y_scale_end) -{ - ClutterBehaviourScalePrivate *priv; - - g_return_if_fail (CLUTTER_IS_BEHAVIOUR_SCALE (scale)); - - priv = scale->priv; - - if (x_scale_start) - *x_scale_start = priv->x_scale_start; - - if (x_scale_end) - *x_scale_end = priv->x_scale_end; - - if (y_scale_start) - *y_scale_start = priv->y_scale_start; - - if (y_scale_end) - *y_scale_end = priv->y_scale_end; -} diff --git a/clutter/clutter/deprecated/clutter-behaviour-scale.h b/clutter/clutter/deprecated/clutter-behaviour-scale.h deleted file mode 100644 index e3f779740..000000000 --- a/clutter/clutter/deprecated/clutter-behaviour-scale.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * Jorn Baayen - * Emmanuele Bassi - * - * Copyright (C) 2006 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __CLUTTER_BEHAVIOUR_SCALE_H__ -#define __CLUTTER_BEHAVIOUR_SCALE_H__ - -#include - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_BEHAVIOUR_SCALE (clutter_behaviour_scale_get_type ()) -#define CLUTTER_BEHAVIOUR_SCALE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BEHAVIOUR_SCALE, ClutterBehaviourScale)) -#define CLUTTER_BEHAVIOUR_SCALE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BEHAVIOUR_SCALE, ClutterBehaviourScaleClass)) -#define CLUTTER_IS_BEHAVIOUR_SCALE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BEHAVIOUR_SCALE)) -#define CLUTTER_IS_BEHAVIOUR_SCALE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BEHAVIOUR_SCALE)) -#define CLUTTER_BEHAVIOUR_SCALE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_BEHAVIOUR_SCALE, ClutterBehaviourScaleClass)) - -typedef struct _ClutterBehaviourScale ClutterBehaviourScale; -typedef struct _ClutterBehaviourScalePrivate ClutterBehaviourScalePrivate; -typedef struct _ClutterBehaviourScaleClass ClutterBehaviourScaleClass; - -/** - * ClutterBehaviourScale: - * - * The #ClutterBehaviourScale struct contains only private data and - * should be accessed using the provided API - * - * Since: 0.2 - * - * Deprecated: 1.6: Use clutter_actor_animate() with #ClutterActor:scale-x - * and #ClutterActor:scale-y instead. - */ -struct _ClutterBehaviourScale -{ - /*< private >*/ - ClutterBehaviour parent_instance; - - ClutterBehaviourScalePrivate *priv; -}; - -/** - * ClutterBehaviourScaleClass: - * - * The #ClutterBehaviourScaleClass struct contains only private data - * - * Since: 0.2 - * - * Deprecated: 1.6 - */ -struct _ClutterBehaviourScaleClass -{ - /*< private >*/ - ClutterBehaviourClass parent_class; -}; - -CLUTTER_DEPRECATED_IN_1_6 -GType clutter_behaviour_scale_get_type (void) G_GNUC_CONST; - -CLUTTER_DEPRECATED_IN_1_6_FOR(clutter_actor_animate with ClutterActor:scale-x and ClutterActor:scale-y) -ClutterBehaviour *clutter_behaviour_scale_new (ClutterAlpha *alpha, - gdouble x_scale_start, - gdouble y_scale_start, - gdouble x_scale_end, - gdouble y_scale_end); - -CLUTTER_DEPRECATED_IN_1_6 -void clutter_behaviour_scale_set_bounds (ClutterBehaviourScale *scale, - gdouble x_scale_start, - gdouble y_scale_start, - gdouble x_scale_end, - gdouble y_scale_end); -CLUTTER_DEPRECATED_IN_1_6 -void clutter_behaviour_scale_get_bounds (ClutterBehaviourScale *scale, - gdouble *x_scale_start, - gdouble *y_scale_start, - gdouble *x_scale_end, - gdouble *y_scale_end); - -G_END_DECLS - -#endif /* __CLUTTER_BEHAVIOUR_SCALE_H__ */ diff --git a/clutter/clutter/deprecated/clutter-behaviour.c b/clutter/clutter/deprecated/clutter-behaviour.c deleted file mode 100644 index 11f950788..000000000 --- a/clutter/clutter/deprecated/clutter-behaviour.c +++ /dev/null @@ -1,660 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * Copyright (C) 2006 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -/** - * SECTION:clutter-behaviour - * @Title: ClutterBehaviour - * @short_description: Class for providing behaviours to actors - * @Deprecated: 1.6: Use clutter_actor_animate(), #ClutterAnimator or - * #ClutterState instead - * - * #ClutterBehaviour is the base class for implementing behaviours. A - * behaviour is a controller object for #ClutterActors; you can - * use a behaviour to control one or more properties of an actor (such - * as its opacity, or its position). A #ClutterBehaviour is driven by - * an "alpha function" stored inside a #ClutterAlpha object; an alpha - * function is a function depending solely on time. The alpha function - * computes a value which is then applied to the properties of the - * actors driven by a behaviour. - * - * Clutter provides some pre-defined behaviours, like #ClutterBehaviourPath, - * which controls the position of a set of actors making them "walk" along - * a set of nodes; #ClutterBehaviourOpacity, which controls the opacity - * of a set of actors; #ClutterBehaviourScale, which controls the width - * and height of a set of actors. - * - * To visualize the effects of different alpha functions on a - * #ClutterBehaviour implementation it is possible to take the - * #ClutterBehaviourPath as an example: - * - * ![](path-alpha-func.png) - * - * The actors position between the path's end points directly correlates - * to the #ClutterAlpha's current alpha value driving the behaviour. With - * the #ClutterAlpha's function set to a linear ramp the actor - * will follow the path at a constant velocity, but when changing to - * a sine wave the actor initially accelerates before quickly - * decelerating. - * - * In order to implement a new behaviour you should subclass #ClutterBehaviour - * and override the "alpha_notify" virtual function; inside the overridden - * function you should obtain the alpha value from the #ClutterAlpha - * instance bound to the behaviour and apply it to the desiderd property - * (or properties) of every actor controlled by the behaviour. - * - * #ClutterBehaviour is available since Clutter 0.2. - * - * #ClutterBehaviour and its sub-classes have been discouraged sing Clutter - * 1.0, and formally deprecated since Clutter 1.6. You should use the - * [implicit animation][clutter-actor-animation] support inside #ClutterActor - * if you still have code using #ClutterBehaviour. - */ - -#ifdef HAVE_CONFIG_H -#include "clutter-build-config.h" -#endif - -#define CLUTTER_DISABLE_DEPRECATION_WARNINGS -#include "clutter-behaviour.h" -#include "clutter-alpha.h" - -#include "clutter-debug.h" -#include "clutter-main.h" -#include "clutter-marshal.h" -#include "clutter-private.h" -#include "clutter-scriptable.h" -#include "clutter-script-private.h" - -struct _ClutterBehaviourPrivate -{ - ClutterAlpha *alpha; - - guint notify_id; - GSList *actors; -}; - -enum -{ - PROP_0, - PROP_ALPHA, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST]; - -enum { - APPLIED, - REMOVED, - LAST_SIGNAL -}; - -static guint behave_signals[LAST_SIGNAL] = { 0 }; - -static void clutter_scriptable_iface_init (ClutterScriptableIface *iface); - -G_DEFINE_ABSTRACT_TYPE_WITH_CODE (ClutterBehaviour, - clutter_behaviour, - G_TYPE_OBJECT, - G_ADD_PRIVATE (ClutterBehaviour) - G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_SCRIPTABLE, - clutter_scriptable_iface_init)) - -static gboolean -clutter_behaviour_parse_custom_node (ClutterScriptable *scriptable, - ClutterScript *script, - GValue *value, - const gchar *name, - JsonNode *node) -{ - if (strncmp (name, "alpha", 5) == 0) - { - GObject *alpha; - - alpha = _clutter_script_parse_alpha (script, node); - if (alpha != NULL) - { - g_value_init (value, CLUTTER_TYPE_ALPHA); - g_value_set_object (value, alpha); - - return TRUE; - } - } - - return FALSE; -} - -static void -clutter_scriptable_iface_init (ClutterScriptableIface *iface) -{ - iface->parse_custom_node = clutter_behaviour_parse_custom_node; -} - -static void -clutter_behaviour_dispose (GObject *gobject) -{ - ClutterBehaviour *self = CLUTTER_BEHAVIOUR (gobject); - - clutter_behaviour_set_alpha (self, NULL); - clutter_behaviour_remove_all (self); - - G_OBJECT_CLASS (clutter_behaviour_parent_class)->dispose (gobject); -} - -static void -clutter_behaviour_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterBehaviour *behaviour = CLUTTER_BEHAVIOUR (object); - - switch (prop_id) - { - case PROP_ALPHA: - clutter_behaviour_set_alpha (behaviour, g_value_get_object (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -clutter_behaviour_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterBehaviour *behaviour = CLUTTER_BEHAVIOUR (object); - ClutterBehaviourPrivate *priv = behaviour->priv; - - switch (prop_id) - { - case PROP_ALPHA: - g_value_set_object (value, priv->alpha); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -clutter_behaviour_alpha_notify_unimplemented (ClutterBehaviour *behaviour, - gdouble alpha_value) -{ - g_warning ("ClutterBehaviourClass::alpha_notify not implemented for '%s'", - g_type_name (G_TYPE_FROM_INSTANCE (behaviour))); -} - -static void -clutter_behaviour_class_init (ClutterBehaviourClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->dispose = clutter_behaviour_dispose; - object_class->set_property = clutter_behaviour_set_property; - object_class->get_property = clutter_behaviour_get_property; - - /** - * ClutterBehaviour:alpha: - * - * The #ClutterAlpha object used to drive this behaviour. A #ClutterAlpha - * object binds a #ClutterTimeline and a function which computes a value - * (the "alpha") depending on the time. Each time the alpha value changes - * the alpha-notify virtual function is called. - * - * Since: 0.2 - * - * Deprecated: 1.6 - */ - obj_props[PROP_ALPHA] = - g_param_spec_object ("alpha", - P_("Alpha"), - P_("Alpha Object to drive the behaviour"), - CLUTTER_TYPE_ALPHA, - CLUTTER_PARAM_READWRITE); - - g_object_class_install_properties (object_class, - PROP_LAST, - obj_props); - - klass->alpha_notify = clutter_behaviour_alpha_notify_unimplemented; - - /** - * ClutterBehaviour::applied: - * @behaviour: the #ClutterBehaviour that received the signal - * @actor: the actor the behaviour was applied to. - * - * The ::apply signal is emitted each time the behaviour is applied - * to an actor. - * - * Since: 0.4 - * - * Deprecated: 1.6 - */ - behave_signals[APPLIED] = - g_signal_new ("applied", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (ClutterBehaviourClass, applied), - NULL, NULL, - _clutter_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - CLUTTER_TYPE_ACTOR); - /** - * ClutterBehaviour::removed: - * @behaviour: the #ClutterBehaviour that received the signal - * @actor: the removed actor - * - * The ::removed signal is emitted each time a behaviour is not applied - * to an actor anymore. - * - * Since: 0.4 - * - * Deprecated: 1.6 - */ - behave_signals[REMOVED] = - g_signal_new ("removed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (ClutterBehaviourClass, removed), - NULL, NULL, - _clutter_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - CLUTTER_TYPE_ACTOR); -} - -static void -clutter_behaviour_init (ClutterBehaviour *self) -{ - self->priv = clutter_behaviour_get_instance_private (self); -} - -static void -remove_actor_on_destroy (ClutterActor *actor, - ClutterBehaviour *behaviour) -{ - clutter_behaviour_remove (behaviour, actor); -} - -/** - * clutter_behaviour_apply: - * @behave: a #ClutterBehaviour - * @actor: a #ClutterActor - * - * Applies @behave to @actor. This function adds a reference on - * the actor. - * - * Since: 0.2 - * - * Deprecated: 1.6 - */ -void -clutter_behaviour_apply (ClutterBehaviour *behave, - ClutterActor *actor) -{ - ClutterBehaviourPrivate *priv; - - g_return_if_fail (CLUTTER_IS_BEHAVIOUR (behave)); - g_return_if_fail (CLUTTER_IS_ACTOR (actor)); - - priv = behave->priv; - - if (g_slist_find (priv->actors, actor)) - { - g_warning ("The behaviour of type %s already applies " - "to the actor of type %s", - g_type_name (G_OBJECT_TYPE (behave)), - g_type_name (G_OBJECT_TYPE (actor))); - return; - } - - priv->actors = g_slist_append (priv->actors, g_object_ref (actor)); - g_signal_connect (actor, "destroy", - G_CALLBACK (remove_actor_on_destroy), - behave); - - g_signal_emit (behave, behave_signals[APPLIED], 0, actor); -} - -/** - * clutter_behaviour_is_applied: - * @behave: a #ClutterBehaviour - * @actor: a #ClutterActor - * - * Check if @behave applied to @actor. - * - * Return value: TRUE if actor has behaviour. FALSE otherwise. - * - * Since: 0.4 - * - * Deprecated: 1.6 - */ -gboolean -clutter_behaviour_is_applied (ClutterBehaviour *behave, - ClutterActor *actor) -{ - g_return_val_if_fail (CLUTTER_IS_BEHAVIOUR (behave), FALSE); - g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), FALSE); - - return (g_slist_find (behave->priv->actors, actor) != NULL); -} - -/** - * clutter_behaviour_remove: - * @behave: a #ClutterBehaviour - * @actor: a #ClutterActor - * - * Removes @actor from the list of #ClutterActors to which - * @behave applies. This function removes a reference on the actor. - * - * Since: 0.2 - * - * Deprecated: 1.6 - */ -void -clutter_behaviour_remove (ClutterBehaviour *behave, - ClutterActor *actor) -{ - ClutterBehaviourPrivate *priv; - - g_return_if_fail (CLUTTER_IS_BEHAVIOUR (behave)); - g_return_if_fail (CLUTTER_IS_ACTOR (actor)); - - priv = behave->priv; - - if (!g_slist_find (priv->actors, actor)) - { - g_warning ("The behaviour of type %s is not applied " - "to the actor of type %s", - g_type_name (G_OBJECT_TYPE (behave)), - g_type_name (G_OBJECT_TYPE (actor))); - return; - } - - g_signal_handlers_disconnect_by_func (actor, - G_CALLBACK (remove_actor_on_destroy), - behave); - - priv->actors = g_slist_remove (priv->actors, actor); - - g_signal_emit (behave, behave_signals[REMOVED], 0, actor); - - g_object_unref (actor); -} - -/** - * clutter_behaviour_get_n_actors: - * @behave: a #ClutterBehaviour - * - * Gets the number of actors this behaviour is applied too. - * - * Return value: The number of applied actors - * - * Since: 0.2 - * - * Deprecated: 1.6 - */ -gint -clutter_behaviour_get_n_actors (ClutterBehaviour *behave) -{ - g_return_val_if_fail (CLUTTER_IS_BEHAVIOUR (behave), 0); - - return g_slist_length (behave->priv->actors); -} - -/** - * clutter_behaviour_get_nth_actor: - * @behave: a #ClutterBehaviour - * @index_: the index of an actor this behaviour is applied too. - * - * Gets an actor the behaviour was applied to referenced by index num. - * - * Return value: (transfer none): A Clutter actor or NULL if @index_ is invalid. - * - * Since: 0.2 - * - * Deprecated: 1.6 - */ -ClutterActor * -clutter_behaviour_get_nth_actor (ClutterBehaviour *behave, - gint index_) -{ - g_return_val_if_fail (CLUTTER_IS_BEHAVIOUR (behave), NULL); - - return g_slist_nth_data (behave->priv->actors, index_); -} - - -/** - * clutter_behaviour_actors_foreach: - * @behave: a #ClutterBehaviour - * @func: (scope call): a function called for each actor - * @data: optional data to be passed to the function, or %NULL - * - * Calls @func for every actor driven by @behave. - * - * Since: 0.2 - * - * Deprecated: 1.6 - */ -void -clutter_behaviour_actors_foreach (ClutterBehaviour *behave, - ClutterBehaviourForeachFunc func, - gpointer data) -{ - GSList *l; - - g_return_if_fail (CLUTTER_IS_BEHAVIOUR (behave)); - g_return_if_fail (func != NULL); - - for (l = behave->priv->actors; l != NULL; l = l->next) - { - ClutterActor *actor = l->data; - - g_assert (CLUTTER_IS_ACTOR (actor)); - - func (behave, actor, data); - } -} - -/** - * clutter_behaviour_get_alpha: - * @behave: a #ClutterBehaviour - * - * Retrieves the #ClutterAlpha object bound to @behave. - * - * Return value: (transfer none): a #ClutterAlpha object, or %NULL if no alpha - * object has been bound to this behaviour. - * - * Since: 0.2 - * - * Deprecated: 1.6 - */ -ClutterAlpha * -clutter_behaviour_get_alpha (ClutterBehaviour *behave) -{ - g_return_val_if_fail (CLUTTER_IS_BEHAVIOUR (behave), NULL); - - return behave->priv->alpha; -} - -static void -notify_cb (GObject *object, - GParamSpec *param_spec, - ClutterBehaviour *behave) -{ - ClutterBehaviourClass *klass; - - klass = CLUTTER_BEHAVIOUR_GET_CLASS (behave); - - CLUTTER_NOTE (ANIMATION, "notify::alpha"); - - /* no actors, we can stop right here */ - if (behave->priv->actors == NULL) - return; - - if (klass->alpha_notify != NULL) - { - gdouble alpha_value = clutter_alpha_get_alpha (behave->priv->alpha); - - CLUTTER_NOTE (ANIMATION, "calling %s::alpha_notify (%p, %.4f)", - g_type_name (G_TYPE_FROM_CLASS (klass)), - behave, alpha_value); - - klass->alpha_notify (behave, alpha_value); - } -} - -/** - * clutter_behaviour_set_alpha: - * @behave: a #ClutterBehaviour - * @alpha: a #ClutterAlpha or %NULL to unset a previously set alpha - * - * Binds @alpha to a #ClutterBehaviour. The #ClutterAlpha object - * is what makes a behaviour work: for each tick of the timeline - * used by #ClutterAlpha a new value of the alpha parameter is - * computed by the alpha function; the value should be used by - * the #ClutterBehaviour to update one or more properties of the - * actors to which the behaviour applies. - * - * If @alpha is not %NULL, the #ClutterBehaviour will take ownership - * of the #ClutterAlpha instance. - * - * Since: 0.2 - * - * Deprecated: 1.6 - */ -void -clutter_behaviour_set_alpha (ClutterBehaviour *behave, - ClutterAlpha *alpha) -{ - ClutterBehaviourPrivate *priv; - - g_return_if_fail (CLUTTER_IS_BEHAVIOUR (behave)); - g_return_if_fail (alpha == NULL || CLUTTER_IS_ALPHA (alpha)); - - priv = behave->priv; - - if (priv->alpha == alpha) - return; - - if (priv->notify_id) - { - CLUTTER_NOTE (ANIMATION, "removing previous notify-id (%d)", - priv->notify_id); - - g_signal_handler_disconnect (priv->alpha, priv->notify_id); - priv->notify_id = 0; - } - - if (priv->alpha != NULL) - { - CLUTTER_NOTE (ANIMATION, "removing previous alpha object"); - - g_object_unref (priv->alpha); - priv->alpha = NULL; - } - - if (alpha != NULL) - { - priv->alpha = g_object_ref_sink (alpha); - - priv->notify_id = g_signal_connect (priv->alpha, "notify::alpha", - G_CALLBACK(notify_cb), - behave); - - CLUTTER_NOTE (ANIMATION, "setting new alpha object (%p, notify:%d)", - priv->alpha, priv->notify_id); - } - - g_object_notify_by_pspec (G_OBJECT (behave), obj_props[PROP_ALPHA]); -} - -/** - * clutter_behaviour_get_actors: - * @behave: a #ClutterBehaviour - * - * Retrieves all the actors to which @behave applies. It is not recommended - * for derived classes to use this in there alpha notify method but use - * #clutter_behaviour_actors_foreach as it avoids alot of needless allocations. - * - * Return value: (transfer container) (element-type Clutter.Actor): a list of - * actors. You should free the returned list with g_slist_free() when - * finished using it. - * - * Since: 0.2 - * - * Deprecated: 1.6 - */ -GSList * -clutter_behaviour_get_actors (ClutterBehaviour *behave) -{ - ClutterBehaviourPrivate *priv; - GSList *retval, *l; - - g_return_val_if_fail (CLUTTER_BEHAVIOUR (behave), NULL); - - priv = behave->priv; - retval = NULL; - for (l = priv->actors; l != NULL; l = l->next) - retval = g_slist_prepend (retval, l->data); - - return g_slist_reverse (retval); -} - -/** - * clutter_behaviour_remove_all: - * @behave: a #ClutterBehaviour - * - * Removes every actor from the list that @behave holds. - * - * Since: 0.4 - * - * Deprecated: 1.6 - */ -void -clutter_behaviour_remove_all (ClutterBehaviour *behave) -{ - ClutterBehaviourPrivate *priv; - GSList *l; - - g_return_if_fail (CLUTTER_IS_BEHAVIOUR (behave)); - - priv = behave->priv; - for (l = priv->actors; l != NULL; l = l->next) - { - ClutterActor *actor = l->data; - - g_signal_emit (behave, behave_signals[REMOVED], 0, actor); - g_signal_handlers_disconnect_by_func (actor, - G_CALLBACK (remove_actor_on_destroy), - behave); - g_object_unref (actor); - } - - g_slist_free (priv->actors); - priv->actors = NULL; -} diff --git a/clutter/clutter/deprecated/clutter-behaviour.h b/clutter/clutter/deprecated/clutter-behaviour.h deleted file mode 100644 index 295d1cfdb..000000000 --- a/clutter/clutter/deprecated/clutter-behaviour.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * Jorn Baayen - * Emmanuele Bassi - * - * Copyright (C) 2006 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __CLUTTER_BEHAVIOUR_H__ -#define __CLUTTER_BEHAVIOUR_H__ - -#include - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_BEHAVIOUR clutter_behaviour_get_type() - -#define CLUTTER_BEHAVIOUR(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ - CLUTTER_TYPE_BEHAVIOUR, ClutterBehaviour)) - -#define CLUTTER_BEHAVIOUR_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), \ - CLUTTER_TYPE_BEHAVIOUR, ClutterBehaviourClass)) - -#define CLUTTER_IS_BEHAVIOUR(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ - CLUTTER_TYPE_BEHAVIOUR)) - -#define CLUTTER_IS_BEHAVIOUR_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), \ - CLUTTER_TYPE_BEHAVIOUR)) - -#define CLUTTER_BEHAVIOUR_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), \ - CLUTTER_TYPE_BEHAVIOUR, ClutterBehaviourClass)) - -typedef struct _ClutterBehaviourPrivate ClutterBehaviourPrivate; -typedef struct _ClutterBehaviourClass ClutterBehaviourClass; - -/** - * ClutterBehaviourForeachFunc: - * @behaviour: the #ClutterBehaviour - * @actor: an actor driven by @behaviour - * @data: (closure): optional data passed to the function - * - * This function is passed to clutter_behaviour_actors_foreach() and - * will be called for each actor driven by @behaviour. - * - * Since: 0.2 - * - * Deprecated: 1.6 - */ -typedef void (*ClutterBehaviourForeachFunc) (ClutterBehaviour *behaviour, - ClutterActor *actor, - gpointer data); - -/** - * ClutterBehaviour: - * - * #ClutterBehaviour-struct contains only private data and should - * be accessed with the functions below. - * - * Since: 0.2 - * - * Deprecated: 1.6 - */ -struct _ClutterBehaviour -{ - /*< private >*/ - GObject parent; - ClutterBehaviourPrivate *priv; -}; - -/** - * ClutterBehaviourClass: - * @alpha_notify: virtual function, called each time the #ClutterAlpha - * computes a new alpha value; the actors to which the behaviour applies - * should be changed in this function. Every subclass of #ClutterBehaviour - * must implement this virtual function - * @applied: signal class handler for the ClutterBehaviour::applied signal - * @removed: signal class handler for the ClutterBehaviour::removed signal - * - * Base class for behaviours. - * - * Since: 0.2 - * - * Deprecated: 1.6 - */ -struct _ClutterBehaviourClass -{ - /*< private >*/ - GObjectClass parent_class; - - /*< public >*/ - /* vfunc, not signal */ - void (*alpha_notify) (ClutterBehaviour *behave, - gdouble alpha_value); - - /* signals */ - void (*applied) (ClutterBehaviour *behave, - ClutterActor *actor); - void (*removed) (ClutterBehaviour *behave, - ClutterActor *actor); - - /*< private >*/ - /* padding, for future expansion */ - void (*_clutter_behaviour1) (void); - void (*_clutter_behaviour2) (void); - void (*_clutter_behaviour3) (void); - void (*_clutter_behaviour4) (void); - void (*_clutter_behaviour5) (void); - void (*_clutter_behaviour6) (void); -}; - -CLUTTER_DEPRECATED_IN_1_6 -GType clutter_behaviour_get_type (void) G_GNUC_CONST; - -CLUTTER_DEPRECATED_IN_1_6 -void clutter_behaviour_apply (ClutterBehaviour *behave, - ClutterActor *actor); -CLUTTER_DEPRECATED_IN_1_6 -void clutter_behaviour_remove (ClutterBehaviour *behave, - ClutterActor *actor); -CLUTTER_DEPRECATED_IN_1_6 -void clutter_behaviour_remove_all (ClutterBehaviour *behave); -CLUTTER_DEPRECATED_IN_1_6 -void clutter_behaviour_actors_foreach (ClutterBehaviour *behave, - ClutterBehaviourForeachFunc func, - gpointer data); -CLUTTER_DEPRECATED_IN_1_6 -gint clutter_behaviour_get_n_actors (ClutterBehaviour *behave); -CLUTTER_DEPRECATED_IN_1_6 -ClutterActor *clutter_behaviour_get_nth_actor (ClutterBehaviour *behave, - gint index_); -CLUTTER_DEPRECATED_IN_1_6 -GSList * clutter_behaviour_get_actors (ClutterBehaviour *behave); -CLUTTER_DEPRECATED_IN_1_6 -ClutterAlpha *clutter_behaviour_get_alpha (ClutterBehaviour *behave); -CLUTTER_DEPRECATED_IN_1_6 -void clutter_behaviour_set_alpha (ClutterBehaviour *behave, - ClutterAlpha *alpha); -CLUTTER_DEPRECATED_IN_1_6 -gboolean clutter_behaviour_is_applied (ClutterBehaviour *behave, - ClutterActor *actor); - -G_END_DECLS - -#endif /* __CLUTTER_BEHAVIOUR_H__ */ diff --git a/clutter/clutter/deprecated/clutter-bin-layout.h b/clutter/clutter/deprecated/clutter-bin-layout.h deleted file mode 100644 index 2d56d1f8b..000000000 --- a/clutter/clutter/deprecated/clutter-bin-layout.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __CLUTTER_BIN_LAYOUT_DEPRECATED_H__ -#define __CLUTTER_BIN_LAYOUT_DEPRECATED_H__ - -#include - -G_BEGIN_DECLS - -CLUTTER_DEPRECATED_IN_1_12 -void clutter_bin_layout_set_alignment (ClutterBinLayout *self, - ClutterActor *child, - ClutterBinAlignment x_align, - ClutterBinAlignment y_align); - -CLUTTER_DEPRECATED_IN_1_12 -void clutter_bin_layout_get_alignment (ClutterBinLayout *self, - ClutterActor *child, - ClutterBinAlignment *x_align, - ClutterBinAlignment *y_align); - -CLUTTER_DEPRECATED_IN_1_12 -void clutter_bin_layout_add (ClutterBinLayout *self, - ClutterActor *child, - ClutterBinAlignment x_align, - ClutterBinAlignment y_align); - -G_END_DECLS - -#endif /* __CLUTTER_BIN_LAYOUT_DEPRECATED_H__ */ diff --git a/clutter/clutter/deprecated/clutter-box.c b/clutter/clutter/deprecated/clutter-box.c index 2df11cbc9..b60f35fe5 100644 --- a/clutter/clutter/deprecated/clutter-box.c +++ b/clutter/clutter/deprecated/clutter-box.c @@ -69,9 +69,7 @@ * layout properties while adding the new child to the box. */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include #include @@ -500,7 +498,7 @@ clutter_box_set_property_valist (ClutterBox *box, if (error) { g_warning ("%s: %s", G_STRLOC, error); - free (error); + g_free (error); break; } diff --git a/clutter/clutter/deprecated/clutter-box.h b/clutter/clutter/deprecated/clutter-box.h index 0293aac1f..6b6d821fc 100644 --- a/clutter/clutter/deprecated/clutter-box.h +++ b/clutter/clutter/deprecated/clutter-box.h @@ -83,55 +83,55 @@ struct _ClutterBoxClass void (*clutter_padding_6) (void); }; -CLUTTER_DEPRECATED_IN_1_10 +CLUTTER_DEPRECATED GType clutter_box_get_type (void) G_GNUC_CONST; -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_new) +CLUTTER_DEPRECATED_FOR(clutter_actor_new) ClutterActor * clutter_box_new (ClutterLayoutManager *manager); -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_set_layout_manager) +CLUTTER_DEPRECATED_FOR(clutter_actor_set_layout_manager) void clutter_box_set_layout_manager (ClutterBox *box, ClutterLayoutManager *manager); -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_get_layout_manager) +CLUTTER_DEPRECATED_FOR(clutter_actor_get_layout_manager) ClutterLayoutManager *clutter_box_get_layout_manager (ClutterBox *box); -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_set_background_color) +CLUTTER_DEPRECATED_FOR(clutter_actor_set_background_color) void clutter_box_set_color (ClutterBox *box, const ClutterColor *color); -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_get_background_color) +CLUTTER_DEPRECATED_FOR(clutter_actor_get_background_color) void clutter_box_get_color (ClutterBox *box, ClutterColor *color); -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_add_child) +CLUTTER_DEPRECATED_FOR(clutter_actor_add_child) void clutter_box_pack (ClutterBox *box, ClutterActor *actor, const gchar *first_property, ...); -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_add_child) +CLUTTER_DEPRECATED_FOR(clutter_actor_add_child) void clutter_box_packv (ClutterBox *box, ClutterActor *actor, guint n_properties, const gchar * const properties[], const GValue *values); -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_insert_child_above) +CLUTTER_DEPRECATED_FOR(clutter_actor_insert_child_above) void clutter_box_pack_after (ClutterBox *box, ClutterActor *actor, ClutterActor *sibling, const gchar *first_property, ...); -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_insert_child_below) +CLUTTER_DEPRECATED_FOR(clutter_actor_insert_child_below) void clutter_box_pack_before (ClutterBox *box, ClutterActor *actor, ClutterActor *sibling, const gchar *first_property, ...); -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_insert_child_at_index) +CLUTTER_DEPRECATED_FOR(clutter_actor_insert_child_at_index) void clutter_box_pack_at (ClutterBox *box, ClutterActor *actor, gint position, diff --git a/clutter/clutter/deprecated/clutter-cairo-texture.c b/clutter/clutter/deprecated/clutter-cairo-texture.c deleted file mode 100644 index 6de16d411..000000000 --- a/clutter/clutter/deprecated/clutter-cairo-texture.c +++ /dev/null @@ -1,1165 +0,0 @@ -/* - * Clutter - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By: Emmanuele Bassi - * Matthew Allum - * Chris Lord - * Iain Holmes - * Neil Roberts - * - * Copyright (C) 2008, 2009, 2010, 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -/** - * SECTION:clutter-cairo-texture - * @short_description: Texture with Cairo integration - * - * #ClutterCairoTexture is a #ClutterTexture that displays the contents - * of a Cairo context. The #ClutterCairoTexture actor will create a - * Cairo image surface which will then be uploaded to a GL texture when - * needed. - * - * Since #ClutterCairoTexture uses a Cairo image surface - * internally all the drawing operations will be performed in - * software and not using hardware acceleration. This can lead to - * performance degradation if the contents of the texture change - * frequently. - * - * In order to use a #ClutterCairoTexture you should connect to the - * #ClutterCairoTexture::draw signal; the signal is emitted each time - * the #ClutterCairoTexture has been told to invalidate its contents, - * by using clutter_cairo_texture_invalidate_rectangle() or its - * sister function, clutter_cairo_texture_invalidate(). - * - * Each callback to the #ClutterCairoTexture::draw signal will receive - * a #cairo_t context which can be used for drawing; the Cairo context - * is owned by the #ClutterCairoTexture and should not be destroyed - * explicitly. - * - * #ClutterCairoTexture is available since Clutter 1.0. - * - * #ClutterCairoTexture is deprecated since Clutter 1.12. You should - * use #ClutterCanvas instead. - */ - -#ifdef HAVE_CONFIG_H -#include "clutter-build-config.h" -#endif - -#include - -#include - -#define CLUTTER_DISABLE_DEPRECATION_WARNINGS -#include "deprecated/clutter-texture.h" -#include "deprecated/clutter-cairo-texture.h" - -#include "clutter-cairo-texture.h" - -#include "clutter-actor-private.h" -#include "clutter-cairo.h" -#include "clutter-color.h" -#include "clutter-debug.h" -#include "clutter-marshal.h" -#include "clutter-private.h" - -struct _ClutterCairoTexturePrivate -{ - cairo_surface_t *cr_surface; - - guint surface_width; - guint surface_height; - - cairo_t *cr_context; - - guint auto_resize : 1; -}; - -enum -{ - PROP_0, - - PROP_SURFACE_WIDTH, - PROP_SURFACE_HEIGHT, - PROP_AUTO_RESIZE, - - PROP_LAST -}; - -enum -{ - CREATE_SURFACE, - DRAW, - - LAST_SIGNAL -}; - -static GParamSpec *obj_props[PROP_LAST] = { NULL, }; - -static guint cairo_signals[LAST_SIGNAL] = { 0, }; - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterCairoTexture, - clutter_cairo_texture, - CLUTTER_TYPE_TEXTURE) - -#ifdef CLUTTER_ENABLE_DEBUG -#define clutter_warn_if_paint_fail(obj) G_STMT_START { \ - if (CLUTTER_ACTOR_IN_PAINT (obj)) { \ - g_warning ("%s should not be called during the paint sequence " \ - "of a ClutterCairoTexture as it will likely cause " \ - "performance issues.", G_STRFUNC); \ - } } G_STMT_END -#else -#define clutter_warn_if_paint_fail(obj) /* void */ -#endif /* CLUTTER_ENABLE_DEBUG */ - -typedef struct { - ClutterCairoTexture *texture; - - cairo_rectangle_int_t rect; - - guint is_clipped : 1; -} DrawContext; - -static const cairo_user_data_key_t clutter_cairo_texture_context_key; - -static DrawContext * -draw_context_create (ClutterCairoTexture *texture) -{ - DrawContext *context = g_slice_new0 (DrawContext); - - context->texture = g_object_ref (texture); - - return context; -} - -static void -draw_context_destroy (gpointer data) -{ - if (G_LIKELY (data != NULL)) - { - DrawContext *context = data; - - g_object_unref (context->texture); - - g_slice_free (DrawContext, data); - } -} - -static void -clutter_cairo_texture_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterCairoTexturePrivate *priv; - - priv = CLUTTER_CAIRO_TEXTURE (object)->priv; - - switch (prop_id) - { - case PROP_SURFACE_WIDTH: - /* we perform the resize on notify to coalesce separate - * surface-width/surface-height property set - */ - priv->surface_width = g_value_get_uint (value); - break; - - case PROP_SURFACE_HEIGHT: - priv->surface_height = g_value_get_uint (value); - break; - - case PROP_AUTO_RESIZE: - clutter_cairo_texture_set_auto_resize (CLUTTER_CAIRO_TEXTURE (object), - g_value_get_boolean (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -clutter_cairo_texture_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterCairoTexturePrivate *priv; - - priv = CLUTTER_CAIRO_TEXTURE (object)->priv; - - switch (prop_id) - { - case PROP_SURFACE_WIDTH: - g_value_set_uint (value, priv->surface_width); - break; - - case PROP_SURFACE_HEIGHT: - g_value_set_uint (value, priv->surface_height); - break; - - case PROP_AUTO_RESIZE: - g_value_set_boolean (value, priv->auto_resize); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -clutter_cairo_texture_finalize (GObject *object) -{ - ClutterCairoTexturePrivate *priv = CLUTTER_CAIRO_TEXTURE (object)->priv; - - if (priv->cr_surface != NULL) - { - cairo_surface_t *surface = priv->cr_surface; - - priv->cr_surface = NULL; - - cairo_surface_finish (surface); - cairo_surface_destroy (surface); - } - - G_OBJECT_CLASS (clutter_cairo_texture_parent_class)->finalize (object); -} - -static cairo_surface_t * -get_surface (ClutterCairoTexture *self) -{ - ClutterCairoTexturePrivate *priv = self->priv; - - if (priv->cr_surface == NULL) - { - g_signal_emit (self, cairo_signals[CREATE_SURFACE], 0, - priv->surface_width, - priv->surface_height, - &priv->cr_surface); - } - - return priv->cr_surface; -} - -static void -clutter_cairo_texture_context_destroy (void *data) -{ - DrawContext *ctxt = data; - ClutterCairoTexture *cairo = ctxt->texture; - ClutterCairoTexturePrivate *priv = cairo->priv; - guint8 *cairo_data; - gint cairo_width, cairo_height, cairo_stride; - gint surface_width, surface_height; - CoglHandle cogl_texture; - - if (priv->cr_surface == NULL) - { - /* the surface went away before we could use it */ - draw_context_destroy (ctxt); - return; - } - - /* for any other surface type, we presume that there exists a native - * communication between Cairo and GL that is triggered by cairo_destroy(). - * - * for instance, cairo-drm will flush the outstanding modifications to the - * surface upon context destruction and so the texture is automatically - * updated. - */ - if (cairo_surface_get_type (priv->cr_surface) != CAIRO_SURFACE_TYPE_IMAGE) - goto out; - - surface_width = cairo_image_surface_get_width (priv->cr_surface); - surface_height = cairo_image_surface_get_height (priv->cr_surface); - - cairo_width = MIN (ctxt->rect.width, surface_width); - cairo_height = MIN (ctxt->rect.height, surface_height); - - cogl_texture = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (cairo)); - if (cairo_width == 0 || - cairo_height == 0 || - cogl_texture == COGL_INVALID_HANDLE) - { - draw_context_destroy (ctxt); - return; - } - - cairo_stride = cairo_image_surface_get_stride (priv->cr_surface); - cairo_data = cairo_image_surface_get_data (priv->cr_surface); - cairo_data += cairo_stride * ctxt->rect.y; - cairo_data += 4 * ctxt->rect.x; - - cogl_texture_set_region (cogl_texture, - 0, 0, - ctxt->rect.x, ctxt->rect.y, - cairo_width, cairo_height, - cairo_width, cairo_height, - CLUTTER_CAIRO_FORMAT_ARGB32, - cairo_stride, - cairo_data); - -out: - draw_context_destroy (ctxt); - clutter_actor_queue_redraw (CLUTTER_ACTOR (cairo)); -} - -static inline void -clutter_cairo_texture_emit_draw (ClutterCairoTexture *self, - DrawContext *ctxt) -{ - gboolean result; - cairo_t *cr; - - /* 0x0 surfaces don't need a ::draw */ - if (self->priv->surface_width == 0 || - self->priv->surface_height == 0) - return; - - /* if the size is !0 then we must have a surface */ - g_assert (self->priv->cr_surface != NULL); - - cr = cairo_create (self->priv->cr_surface); - - if (ctxt->is_clipped) - { - cairo_rectangle (cr, - ctxt->rect.x, - ctxt->rect.y, - ctxt->rect.width, - ctxt->rect.height); - cairo_clip (cr); - } - - /* store the cairo_t as a guard */ - self->priv->cr_context = cr; - - g_signal_emit (self, cairo_signals[DRAW], 0, cr, &result); - - self->priv->cr_context = NULL; - - clutter_cairo_texture_context_destroy (ctxt); - - cairo_destroy (cr); -} - -static inline void -clutter_cairo_texture_surface_resize_internal (ClutterCairoTexture *cairo) -{ - ClutterCairoTexturePrivate *priv = cairo->priv; - - if (priv->cr_surface != NULL) - { - cairo_surface_t *surface = priv->cr_surface; - - /* if the surface is an image one, and the size is already the - * same, then we don't need to do anything - */ - if (cairo_surface_get_type (surface) != CAIRO_SURFACE_TYPE_IMAGE) - { - gint surface_width = cairo_image_surface_get_width (surface); - gint surface_height = cairo_image_surface_get_height (surface); - - if (priv->surface_width == surface_width && - priv->surface_height == surface_height) - return; - } - - cairo_surface_finish (surface); - cairo_surface_destroy (surface); - priv->cr_surface = NULL; - } - - if (priv->surface_width == 0 || - priv->surface_height == 0) - return; - - g_signal_emit (cairo, cairo_signals[CREATE_SURFACE], 0, - priv->surface_width, - priv->surface_height, - &priv->cr_surface); -} - -static void -clutter_cairo_texture_notify (GObject *object, - GParamSpec *pspec) -{ - /* When the surface width or height changes then resize the cairo - surface. This is done here instead of directly in set_property so - that if both the width and height properties are set using a - single call to g_object_set then the surface will only be resized - once because the notifications will be frozen in between */ - - if (obj_props[PROP_SURFACE_WIDTH]->name == pspec->name || - obj_props[PROP_SURFACE_HEIGHT]->name == pspec->name) - { - ClutterCairoTexture *cairo = CLUTTER_CAIRO_TEXTURE (object); - - clutter_cairo_texture_surface_resize_internal (cairo); - } - - if (G_OBJECT_CLASS (clutter_cairo_texture_parent_class)->notify) - G_OBJECT_CLASS (clutter_cairo_texture_parent_class)->notify (object, pspec); -} - -static void -clutter_cairo_texture_get_preferred_width (ClutterActor *actor, - gfloat for_height, - gfloat *min_width, - gfloat *natural_width) -{ - ClutterCairoTexturePrivate *priv = CLUTTER_CAIRO_TEXTURE (actor)->priv; - - if (min_width) - *min_width = 0; - - if (natural_width) - *natural_width = (gfloat) priv->surface_width; -} - -static void -clutter_cairo_texture_get_preferred_height (ClutterActor *actor, - gfloat for_width, - gfloat *min_height, - gfloat *natural_height) -{ - ClutterCairoTexturePrivate *priv = CLUTTER_CAIRO_TEXTURE (actor)->priv; - - if (min_height) - *min_height = 0; - - if (natural_height) - *natural_height = (gfloat) priv->surface_height; -} - -static void -clutter_cairo_texture_allocate (ClutterActor *self, - const ClutterActorBox *allocation, - ClutterAllocationFlags flags) -{ - ClutterCairoTexturePrivate *priv = CLUTTER_CAIRO_TEXTURE (self)->priv; - ClutterActorClass *parent_class; - - parent_class = CLUTTER_ACTOR_CLASS (clutter_cairo_texture_parent_class); - parent_class->allocate (self, allocation, flags); - - if (priv->auto_resize) - { - ClutterCairoTexture *texture = CLUTTER_CAIRO_TEXTURE (self); - gfloat width, height; - - clutter_actor_box_get_size (allocation, &width, &height); - - priv->surface_width = ceilf (width); - priv->surface_height = ceilf (height); - - clutter_cairo_texture_surface_resize_internal (texture); - clutter_cairo_texture_invalidate (texture); - } -} - -static gboolean -clutter_cairo_texture_get_paint_volume (ClutterActor *self, - ClutterPaintVolume *volume) -{ - return _clutter_actor_set_default_paint_volume (self, - CLUTTER_TYPE_CAIRO_TEXTURE, - volume); -} - -static cairo_surface_t * -clutter_cairo_texture_create_surface (ClutterCairoTexture *self, - guint width, - guint height) -{ - cairo_surface_t *surface; - guint cairo_stride; - guint8 *cairo_data; - CoglHandle cogl_texture; - - surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, - width, - height); - - cairo_stride = cairo_image_surface_get_stride (surface); - cairo_data = cairo_image_surface_get_data (surface); - - /* create a backing Cogl texture */ - cogl_texture = cogl_texture_new_from_data (width, height, - COGL_TEXTURE_NONE, - CLUTTER_CAIRO_FORMAT_ARGB32, - COGL_PIXEL_FORMAT_ANY, - cairo_stride, - cairo_data); - clutter_texture_set_cogl_texture (CLUTTER_TEXTURE (self), cogl_texture); - cogl_handle_unref (cogl_texture); - - return surface; -} - -static gboolean -create_surface_accum (GSignalInvocationHint *ihint, - GValue *return_accu, - const GValue *handler_return, - gpointer data) -{ - g_value_copy (handler_return, return_accu); - - /* stop on the first non-NULL return value */ - return g_value_get_boxed (handler_return) == NULL; -} - -static void -clutter_cairo_texture_draw_marshaller (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data) -{ - cairo_t *cr = g_value_get_boxed (¶m_values[1]); - - cairo_save (cr); - - _clutter_marshal_BOOLEAN__BOXED (closure, - return_value, - n_param_values, - param_values, - invocation_hint, - marshal_data); - - cairo_restore (cr); -} - -static void -clutter_cairo_texture_class_init (ClutterCairoTextureClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); - - gobject_class->finalize = clutter_cairo_texture_finalize; - gobject_class->set_property = clutter_cairo_texture_set_property; - gobject_class->get_property = clutter_cairo_texture_get_property; - gobject_class->notify = clutter_cairo_texture_notify; - - actor_class->get_paint_volume = - clutter_cairo_texture_get_paint_volume; - actor_class->get_preferred_width = - clutter_cairo_texture_get_preferred_width; - actor_class->get_preferred_height = - clutter_cairo_texture_get_preferred_height; - actor_class->allocate = - clutter_cairo_texture_allocate; - - klass->create_surface = clutter_cairo_texture_create_surface; - - /** - * ClutterCairoTexture:surface-width: - * - * The width of the Cairo surface used by the #ClutterCairoTexture - * actor, in pixels. - * - * Since: 1.0 - * - * Deprecated: 1.12 - */ - obj_props[PROP_SURFACE_WIDTH] = - g_param_spec_uint ("surface-width", - P_("Surface Width"), - P_("The width of the Cairo surface"), - 0, G_MAXUINT, - 0, - CLUTTER_PARAM_READWRITE | - G_PARAM_DEPRECATED); - /** - * ClutterCairoTexture:surface-height: - * - * The height of the Cairo surface used by the #ClutterCairoTexture - * actor, in pixels. - * - * Since: 1.0 - * - * Deprecated: 1.12 - */ - obj_props[PROP_SURFACE_HEIGHT] = - g_param_spec_uint ("surface-height", - P_("Surface Height"), - P_("The height of the Cairo surface"), - 0, G_MAXUINT, - 0, - CLUTTER_PARAM_READWRITE | - G_PARAM_DEPRECATED); - - /** - * ClutterCairoTexture:auto-resize: - * - * Controls whether the #ClutterCairoTexture should automatically - * resize the Cairo surface whenever the actor's allocation changes. - * If :auto-resize is set to %TRUE the surface contents will also - * be invalidated automatically. - * - * Since: 1.8 - * - * Deprecated: 1.12 - */ - obj_props[PROP_AUTO_RESIZE] = - g_param_spec_boolean ("auto-resize", - P_("Auto Resize"), - P_("Whether the surface should match the allocation"), - FALSE, - CLUTTER_PARAM_READWRITE | - G_PARAM_DEPRECATED); - - g_object_class_install_properties (gobject_class, PROP_LAST, obj_props); - - /** - * ClutterCairoTexture::create-surface: - * @texture: the #ClutterCairoTexture that emitted the signal - * @width: the width of the surface to create - * @height: the height of the surface to create - * - * The ::create-surface signal is emitted when a #ClutterCairoTexture - * news its surface (re)created, which happens either when the Cairo - * context is created with clutter_cairo_texture_create() or - * clutter_cairo_texture_create_region(), or when the surface is resized - * through clutter_cairo_texture_set_surface_size(). - * - * The first signal handler that returns a non-%NULL, valid surface will - * stop any further signal emission, and the returned surface will be - * the one used. - * - * Return value: the newly created #cairo_surface_t for the texture - * - * Since: 1.6 - * - * Deprecated: 1.12 - */ - cairo_signals[CREATE_SURFACE] = - g_signal_new (I_("create-surface"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE, - G_STRUCT_OFFSET (ClutterCairoTextureClass, create_surface), - create_surface_accum, NULL, - _clutter_marshal_BOXED__UINT_UINT, - CAIRO_GOBJECT_TYPE_SURFACE, 2, - G_TYPE_UINT, - G_TYPE_UINT); - - /** - * ClutterCairoTexture::draw: - * @texture: the #ClutterCairoTexture that emitted the signal - * @cr: the Cairo context to use to draw - * - * The ::draw signal is emitted each time a #ClutterCairoTexture has - * been invalidated. - * - * The passed Cairo context passed will be clipped to the invalidated - * area. - * - * It is safe to connect multiple callbacks to this signals; the state - * of the Cairo context passed to each callback is automatically saved - * and restored, so it's not necessary to call cairo_save() and - * cairo_restore(). - * - * Return value: %TRUE if the signal emission should stop, and %FALSE - * to continue - * - * Since: 1.8 - * - * Deprecated: 1.12 - */ - cairo_signals[DRAW] = - g_signal_new (I_("draw"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE, - G_STRUCT_OFFSET (ClutterCairoTextureClass, draw), - _clutter_boolean_handled_accumulator, NULL, - clutter_cairo_texture_draw_marshaller, - G_TYPE_BOOLEAN, 1, - CAIRO_GOBJECT_TYPE_CONTEXT); -} - -static void -clutter_cairo_texture_init (ClutterCairoTexture *self) -{ - self->priv = clutter_cairo_texture_get_instance_private (self); - - /* FIXME - we are hardcoding the format; it would be good to have - * a :surface-format construct-only property for creating - * textures with a different format and have the cairo surface - * match that format - * - * priv->format = CAIRO_FORMAT_ARGB32; - */ - - /* the Cairo surface is responsible for driving the size of - * the texture; if we let sync_size to its default of TRUE, - * the Texture will try to queue a relayout every time we - * change the size of the Cairo surface - which is not what - * we want - */ - clutter_texture_set_sync_size (CLUTTER_TEXTURE (self), FALSE); -} - -/** - * clutter_cairo_texture_new: - * @width: the width of the surface - * @height: the height of the surface - * - * Creates a new #ClutterCairoTexture actor, with a surface of @width by - * @height pixels. - * - * Return value: the newly created #ClutterCairoTexture actor - * - * Since: 1.0 - * - * Deprecated: 1.12: Use #ClutterCanvas instead - */ -ClutterActor* -clutter_cairo_texture_new (guint width, - guint height) -{ - return g_object_new (CLUTTER_TYPE_CAIRO_TEXTURE, - "surface-width", width, - "surface-height", height, - NULL); -} - -static void -intersect_rectangles (cairo_rectangle_int_t *a, - cairo_rectangle_int_t *b, - cairo_rectangle_int_t *inter) -{ - gint dest_x, dest_y; - gint dest_width, dest_height; - - dest_x = MAX (a->x, b->x); - dest_y = MAX (a->y, b->y); - dest_width = MIN (a->x + a->width, b->x + b->width) - dest_x; - dest_height = MIN (a->y + a->height, b->y + b->height) - dest_y; - - if (dest_width > 0 && dest_height > 0) - { - inter->x = dest_x; - inter->y = dest_y; - inter->width = dest_width; - inter->height = dest_height; - } - else - { - inter->x = 0; - inter->y = 0; - inter->width = 0; - inter->height = 0; - } -} - -static cairo_t * -clutter_cairo_texture_create_region_internal (ClutterCairoTexture *self, - gint x_offset, - gint y_offset, - gint width, - gint height) -{ - ClutterCairoTexturePrivate *priv = self->priv; - cairo_rectangle_int_t region, area, inter; - cairo_surface_t *surface; - DrawContext *ctxt; - cairo_t *cr; - - if (width < 0) - width = priv->surface_width; - - if (height < 0) - height = priv->surface_height; - - if (width == 0 || height == 0) - { - g_warning ("Unable to create a context for an image surface of " - "width %d and height %d. Set the surface size to be " - "at least 1 pixel by 1 pixel.", - width, height); - return NULL; - } - - surface = get_surface (self); - - ctxt = draw_context_create (self); - - region.x = x_offset; - region.y = y_offset; - region.width = width; - region.height = height; - - area.x = 0; - area.y = 0; - area.width = priv->surface_width; - area.height = priv->surface_height; - - /* Limit the region to the visible rectangle */ - intersect_rectangles (&area, ®ion, &inter); - - ctxt->rect = inter; - - cr = cairo_create (surface); - cairo_set_user_data (cr, &clutter_cairo_texture_context_key, - ctxt, - clutter_cairo_texture_context_destroy); - - return cr; -} - -/** - * clutter_cairo_texture_create_region: - * @self: a #ClutterCairoTexture - * @x_offset: offset of the region on the X axis - * @y_offset: offset of the region on the Y axis - * @width: width of the region, or -1 for the full surface width - * @height: height of the region, or -1 for the full surface height - * - * Creates a new Cairo context that will updat the region defined - * by @x_offset, @y_offset, @width and @height. - * - * Do not call this function within the paint virtual - * function or from a callback to the #ClutterActor::paint - * signal. - * - * Return value: a newly created Cairo context. Use cairo_destroy() - * to upload the contents of the context when done drawing - * - * Since: 1.0 - * - * Deprecated: 1.8: Use the #ClutterCairoTexture::draw signal and - * clutter_cairo_texture_invalidate_rectangle() to obtain a - * clipped Cairo context for 2D drawing. - */ -cairo_t * -clutter_cairo_texture_create_region (ClutterCairoTexture *self, - gint x_offset, - gint y_offset, - gint width, - gint height) -{ - g_return_val_if_fail (CLUTTER_IS_CAIRO_TEXTURE (self), NULL); - - clutter_warn_if_paint_fail (self); - - return clutter_cairo_texture_create_region_internal (self, - x_offset, y_offset, - width, height); -} - -/** - * clutter_cairo_texture_invalidate_rectangle: - * @self: a #ClutterCairoTexture - * @rect: (allow-none): a rectangle with the area to invalida, - * or %NULL to perform an unbounded invalidation - * - * Invalidates a rectangular region of a #ClutterCairoTexture. - * - * The invalidation will cause the #ClutterCairoTexture::draw signal - * to be emitted. - * - * See also: clutter_cairo_texture_invalidate() - * - * Since: 1.8 - * Deprecated: 1.12: Use #ClutterCanvas instead - */ -void -clutter_cairo_texture_invalidate_rectangle (ClutterCairoTexture *self, - cairo_rectangle_int_t *rect) -{ - DrawContext *ctxt = NULL; - - g_return_if_fail (CLUTTER_IS_CAIRO_TEXTURE (self)); - - if (self->priv->cr_context != NULL) - { - g_warning ("It is not possible to invalidate a Cairo texture" - "while drawing into it."); - return; - } - - ctxt = draw_context_create (self); - - if (rect != NULL) - { - cairo_rectangle_int_t area, inter; - - area.x = 0; - area.y = 0; - area.width = self->priv->surface_width; - area.height = self->priv->surface_height; - - /* Limit the region to the visible rectangle */ - intersect_rectangles (&area, rect, &inter); - - ctxt->is_clipped = TRUE; - ctxt->rect = inter; - } - else - { - ctxt->is_clipped = FALSE; - ctxt->rect.x = ctxt->rect.y = 0; - ctxt->rect.width = self->priv->surface_width; - ctxt->rect.height = self->priv->surface_height; - } - - /* XXX - it might be good to move the emission inside the paint cycle - * using a repaint function, to avoid blocking inside this function - */ - clutter_cairo_texture_emit_draw (self, ctxt); -} - -/** - * clutter_cairo_texture_invalidate: - * @self: a #ClutterCairoTexture - * - * Invalidates the whole surface of a #ClutterCairoTexture. - * - * This function will cause the #ClutterCairoTexture::draw signal - * to be emitted. - * - * See also: clutter_cairo_texture_invalidate_rectangle() - * - * Since: 1.8 - * Deprecated: 1.12: Use #ClutterCanvas instead - */ -void -clutter_cairo_texture_invalidate (ClutterCairoTexture *self) -{ - g_return_if_fail (CLUTTER_IS_CAIRO_TEXTURE (self)); - - clutter_cairo_texture_invalidate_rectangle (self, NULL); -} - -/** - * clutter_cairo_texture_create: - * @self: a #ClutterCairoTexture - * - * Creates a new Cairo context for the @cairo texture. It is - * similar to using clutter_cairo_texture_create_region() with @x_offset - * and @y_offset of 0, @width equal to the @cairo texture surface width - * and @height equal to the @cairo texture surface height. - * - * Do not call this function within the paint virtual - * function or from a callback to the #ClutterActor::paint - * signal. - * - * Return value: a newly created Cairo context. Use cairo_destroy() - * to upload the contents of the context when done drawing - * - * Since: 1.0 - * - * Deprecated: 1.8: Use the #ClutterCairoTexture::draw signal and - * the clutter_cairo_texture_invalidate() function to obtain a - * Cairo context for 2D drawing. - */ -cairo_t * -clutter_cairo_texture_create (ClutterCairoTexture *self) -{ - g_return_val_if_fail (CLUTTER_IS_CAIRO_TEXTURE (self), NULL); - - clutter_warn_if_paint_fail (self); - - return clutter_cairo_texture_create_region_internal (self, 0, 0, -1, -1); -} - -/** - * clutter_cairo_texture_set_surface_size: - * @self: a #ClutterCairoTexture - * @width: the new width of the surface - * @height: the new height of the surface - * - * Resizes the Cairo surface used by @self to @width and @height. - * - * This function will not invalidate the contents of the Cairo - * texture: you will have to explicitly call either - * clutter_cairo_texture_invalidate_rectangle() or - * clutter_cairo_texture_invalidate(). - * - * Since: 1.0 - * Deprecated: 1.12: Use #ClutterCanvas instead - */ -void -clutter_cairo_texture_set_surface_size (ClutterCairoTexture *self, - guint width, - guint height) -{ - ClutterCairoTexturePrivate *priv; - - g_return_if_fail (CLUTTER_IS_CAIRO_TEXTURE (self)); - - priv = self->priv; - - if (width == priv->surface_width && - height == priv->surface_height) - return; - - g_object_freeze_notify (G_OBJECT (self)); - - if (priv->surface_width != width) - { - priv->surface_width = width; - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_SURFACE_WIDTH]); - } - - if (priv->surface_height != height) - { - priv->surface_height = height; - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_SURFACE_HEIGHT]); - } - - clutter_cairo_texture_surface_resize_internal (self); - - g_object_thaw_notify (G_OBJECT (self)); -} - -/** - * clutter_cairo_texture_get_surface_size: - * @self: a #ClutterCairoTexture - * @width: (out): return location for the surface width, or %NULL - * @height: (out): return location for the surface height, or %NULL - * - * Retrieves the surface width and height for @self. - * - * Since: 1.0 - * Deprecated: 1.12: Use #ClutterCanvas instead - */ -void -clutter_cairo_texture_get_surface_size (ClutterCairoTexture *self, - guint *width, - guint *height) -{ - g_return_if_fail (CLUTTER_IS_CAIRO_TEXTURE (self)); - - if (width) - *width = self->priv->surface_width; - - if (height) - *height = self->priv->surface_height; -} - -/** - * clutter_cairo_texture_clear: - * @self: a #ClutterCairoTexture - * - * Clears @self's internal drawing surface, so that the next upload - * will replace the previous contents of the #ClutterCairoTexture - * rather than adding to it. - * - * Calling this function from within a #ClutterCairoTexture::draw - * signal handler will clear the invalidated area. - * - * Since: 1.0 - * Deprecated: 1.12: Use #ClutterCanvas instead - */ -void -clutter_cairo_texture_clear (ClutterCairoTexture *self) -{ - ClutterCairoTexturePrivate *priv; - cairo_t *cr; - - g_return_if_fail (CLUTTER_IS_CAIRO_TEXTURE (self)); - - priv = self->priv; - - /* if we got called outside of a ::draw signal handler - * then we clear the whole surface by creating a temporary - * cairo_t; otherwise, we clear the current cairo_t, which - * will take into account the clip region. - */ - if (priv->cr_context == NULL) - { - cairo_surface_t *surface; - - surface = get_surface (self); - - cr = cairo_create (surface); - } - else - cr = priv->cr_context; - - cairo_save (cr); - - cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); - cairo_paint (cr); - - cairo_restore (cr); - - if (priv->cr_context == NULL) - cairo_destroy (cr); -} - -/** - * clutter_cairo_texture_set_auto_resize: - * @self: a #ClutterCairoTexture - * @value: %TRUE if the #ClutterCairoTexture should bind the surface - * size to the allocation - * - * Sets whether the #ClutterCairoTexture should ensure that the - * backing Cairo surface used matches the allocation assigned to - * the actor. If the allocation changes, the contents of the - * #ClutterCairoTexture will also be invalidated automatically. - * - * Since: 1.8 - * Deprecated: 1.12: Use #ClutterCanvas instead - */ -void -clutter_cairo_texture_set_auto_resize (ClutterCairoTexture *self, - gboolean value) -{ - ClutterCairoTexturePrivate *priv; - - g_return_if_fail (CLUTTER_IS_CAIRO_TEXTURE (self)); - - value = !!value; - - priv = self->priv; - - if (priv->auto_resize == value) - return; - - priv->auto_resize = value; - - clutter_actor_queue_relayout (CLUTTER_ACTOR (self)); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_AUTO_RESIZE]); -} - -/** - * clutter_cairo_texture_get_auto_resize: - * @self: a #ClutterCairoTexture - * - * Retrieves the value set using clutter_cairo_texture_set_auto_resize(). - * - * Return value: %TRUE if the #ClutterCairoTexture should track the - * allocation, and %FALSE otherwise - * - * Since: 1.8 - * Deprecated: 1.12: Use #ClutterCanvas instead - */ -gboolean -clutter_cairo_texture_get_auto_resize (ClutterCairoTexture *self) -{ - g_return_val_if_fail (CLUTTER_IS_CAIRO_TEXTURE (self), FALSE); - - return self->priv->auto_resize; -} diff --git a/clutter/clutter/deprecated/clutter-cairo-texture.h b/clutter/clutter/deprecated/clutter-cairo-texture.h deleted file mode 100644 index 63b6158b7..000000000 --- a/clutter/clutter/deprecated/clutter-cairo-texture.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Clutter - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By: Emmanuele Bassi - * Matthew Allum - * Chris Lord - * Iain Holmes - * Neil Roberts - * - * Copyright (C) 2008, 2009, 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __CLUTTER_CAIRO_TEXTURE_H__ -#define __CLUTTER_CAIRO_TEXTURE_H__ - -#include - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_CAIRO_TEXTURE (clutter_cairo_texture_get_type ()) -#define CLUTTER_CAIRO_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_CAIRO_TEXTURE, ClutterCairoTexture)) -#define CLUTTER_CAIRO_TEXTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_CAIRO_TEXTURE, ClutterCairoTextureClass)) -#define CLUTTER_IS_CAIRO_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_CAIRO_TEXTURE)) -#define CLUTTER_IS_CAIRO_TEXTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_CAIRO_TEXTURE)) -#define CLUTTER_CAIRO_TEXTURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_CAIRO_TEXTURE, ClutterCairoTextureClass)) - -typedef struct _ClutterCairoTexture ClutterCairoTexture; -typedef struct _ClutterCairoTextureClass ClutterCairoTextureClass; -typedef struct _ClutterCairoTexturePrivate ClutterCairoTexturePrivate; - -/** - * ClutterCairoTexture: - * - * The #ClutterCairoTexture struct contains only private data. - * - * Since: 1.0 - * - * Deprecated: 1.12: Use #ClutterCanvas instead - */ -struct _ClutterCairoTexture -{ - /*< private >*/ - ClutterTexture parent_instance; - - ClutterCairoTexturePrivate *priv; -}; - -/** - * ClutterCairoTextureClass: - * @create_surface: class handler for the #ClutterCairoTexture::create-surface - * signal - * @draw: class handler for the #ClutterCairoTexture::draw signal - * - * The #ClutterCairoTextureClass struct contains only private data. - * - * Since: 1.0 - * - * Deprecated: 1.12: Use #ClutterCanvas instead - */ -struct _ClutterCairoTextureClass -{ - /*< private >*/ - ClutterTextureClass parent_class; - - /*< public >*/ - cairo_surface_t *(* create_surface) (ClutterCairoTexture *texture, - guint width, - guint height); - - gboolean (* draw) (ClutterCairoTexture *texture, - cairo_t *cr); - - /*< private >*/ - void (*_clutter_cairo_3) (void); - void (*_clutter_cairo_4) (void); -}; - -CLUTTER_DEPRECATED_IN_1_12_FOR(clutter_canvas_get_type) -GType clutter_cairo_texture_get_type (void) G_GNUC_CONST; - -CLUTTER_DEPRECATED_IN_1_12_FOR(clutter_canvas_new) -ClutterActor * clutter_cairo_texture_new (guint width, - guint height); - -CLUTTER_DEPRECATED_IN_1_12_FOR(clutter_canvas_set_size) -void clutter_cairo_texture_set_surface_size (ClutterCairoTexture *self, - guint width, - guint height); -CLUTTER_DEPRECATED_IN_1_12_FOR(clutter_canvas_get_size) -void clutter_cairo_texture_get_surface_size (ClutterCairoTexture *self, - guint *width, - guint *height); -CLUTTER_DEPRECATED_IN_1_12 -void clutter_cairo_texture_set_auto_resize (ClutterCairoTexture *self, - gboolean value); -CLUTTER_DEPRECATED_IN_1_12 -gboolean clutter_cairo_texture_get_auto_resize (ClutterCairoTexture *self); - -CLUTTER_DEPRECATED_IN_1_12 -void clutter_cairo_texture_clear (ClutterCairoTexture *self); - -CLUTTER_DEPRECATED_IN_1_12 -void clutter_cairo_texture_invalidate_rectangle (ClutterCairoTexture *self, - cairo_rectangle_int_t *rect); -CLUTTER_DEPRECATED_IN_1_12 -void clutter_cairo_texture_invalidate (ClutterCairoTexture *self); - -CLUTTER_DEPRECATED_IN_1_8_FOR(clutter_cairo_texture_invalidate_rectangle) -cairo_t * clutter_cairo_texture_create_region (ClutterCairoTexture *self, - gint x_offset, - gint y_offset, - gint width, - gint height); - -CLUTTER_DEPRECATED_IN_1_8_FOR(clutter_cairo_texture_invalidate) -cairo_t * clutter_cairo_texture_create (ClutterCairoTexture *self); - -G_END_DECLS - -#endif /* __CLUTTER_CAIRO_TEXTURE_DEPRECATED_H__ */ diff --git a/clutter/clutter/deprecated/clutter-container.h b/clutter/clutter/deprecated/clutter-container.h index 38e78982f..c1e256544 100644 --- a/clutter/clutter/deprecated/clutter-container.h +++ b/clutter/clutter/deprecated/clutter-container.h @@ -34,58 +34,38 @@ G_BEGIN_DECLS -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_add_child) +CLUTTER_DEPRECATED_FOR(clutter_actor_add_child) void clutter_container_add (ClutterContainer *container, ClutterActor *first_actor, ...) G_GNUC_NULL_TERMINATED; -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_add_child) +CLUTTER_DEPRECATED_FOR(clutter_actor_add_child) void clutter_container_add_actor (ClutterContainer *container, ClutterActor *actor); -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_add_child) -void clutter_container_add_valist (ClutterContainer *container, - ClutterActor *first_actor, - va_list var_args); - -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_remove_child) +CLUTTER_DEPRECATED_FOR(clutter_actor_remove_child) void clutter_container_remove (ClutterContainer *container, ClutterActor *first_actor, ...) G_GNUC_NULL_TERMINATED; -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_remove_child) +CLUTTER_DEPRECATED_FOR(clutter_actor_remove_child) void clutter_container_remove_actor (ClutterContainer *container, ClutterActor *actor); -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_remove_child) -void clutter_container_remove_valist (ClutterContainer *container, - ClutterActor *first_actor, - va_list var_args); - -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_get_children) +CLUTTER_DEPRECATED_FOR(clutter_actor_get_children) GList * clutter_container_get_children (ClutterContainer *container); -CLUTTER_DEPRECATED_IN_1_10 -void clutter_container_foreach (ClutterContainer *container, - ClutterCallback callback, - gpointer user_data); - -CLUTTER_DEPRECATED_IN_1_10 -void clutter_container_foreach_with_internals (ClutterContainer *container, - ClutterCallback callback, - gpointer user_data); - -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_set_child_above_sibling) +CLUTTER_DEPRECATED_FOR(clutter_actor_set_child_above_sibling) void clutter_container_raise_child (ClutterContainer *container, ClutterActor *actor, ClutterActor *sibling); -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_set_child_below_sibling) +CLUTTER_DEPRECATED_FOR(clutter_actor_set_child_below_sibling) void clutter_container_lower_child (ClutterContainer *container, ClutterActor *actor, ClutterActor *sibling); -CLUTTER_DEPRECATED_IN_1_10 +CLUTTER_DEPRECATED void clutter_container_sort_depth_order (ClutterContainer *container); G_END_DECLS diff --git a/clutter/clutter/deprecated/clutter-frame-source.c b/clutter/clutter/deprecated/clutter-frame-source.c deleted file mode 100644 index 5bff6089a..000000000 --- a/clutter/clutter/deprecated/clutter-frame-source.c +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Neil Roberts - * - * Copyright (C) 2008 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifdef HAVE_CONFIG_H -#include "clutter-build-config.h" -#endif - -#define CLUTTER_DISABLE_DEPRECATION_WARNINGS - -#include "clutter-main.h" -#include "clutter-private.h" - -#include "deprecated/clutter-frame-source.h" -#include "deprecated/clutter-timeout-interval.h" - -typedef struct _ClutterFrameSource ClutterFrameSource; - -struct _ClutterFrameSource -{ - GSource source; - - ClutterTimeoutInterval timeout; -}; - -static gboolean clutter_frame_source_prepare (GSource *source, - gint *timeout); -static gboolean clutter_frame_source_check (GSource *source); -static gboolean clutter_frame_source_dispatch (GSource *source, - GSourceFunc callback, - gpointer user_data); - -static GSourceFuncs clutter_frame_source_funcs = -{ - clutter_frame_source_prepare, - clutter_frame_source_check, - clutter_frame_source_dispatch, - NULL -}; - -/** - * clutter_frame_source_add_full: (rename-to clutter_frame_source_add) - * @priority: the priority of the frame source. Typically this will be in the - * range between %G_PRIORITY_DEFAULT and %G_PRIORITY_HIGH. - * @fps: the number of times per second to call the function - * @func: function to call - * @data: data to pass to the function - * @notify: function to call when the timeout source is removed - * - * Sets a function to be called at regular intervals with the given - * priority. The function is called repeatedly until it returns - * %FALSE, at which point the timeout is automatically destroyed and - * the function will not be called again. The @notify function is - * called when the timeout is destroyed. The first call to the - * function will be at the end of the first @interval. - * - * This function is similar to g_timeout_add_full() except that it - * will try to compensate for delays. For example, if @func takes half - * the interval time to execute then the function will be called again - * half the interval time after it finished. In contrast - * g_timeout_add_full() would not fire until a full interval after the - * function completes so the delay between calls would be 1.0 / @fps * - * 1.5. This function does not however try to invoke the function - * multiple times to catch up missing frames if @func takes more than - * @interval ms to execute. - * - * Return value: the ID (greater than 0) of the event source. - * - * Since: 0.8 - * - * Deprecated: 1.6: There is no direct replacement for this API. - */ -guint -clutter_frame_source_add_full (gint priority, - guint fps, - GSourceFunc func, - gpointer data, - GDestroyNotify notify) -{ - guint ret; - GSource *source = g_source_new (&clutter_frame_source_funcs, - sizeof (ClutterFrameSource)); - ClutterFrameSource *frame_source = (ClutterFrameSource *) source; - - _clutter_timeout_interval_init (&frame_source->timeout, fps); - - if (priority != G_PRIORITY_DEFAULT) - g_source_set_priority (source, priority); - - g_source_set_name (source, "Clutter frame timeout"); - g_source_set_callback (source, func, data, notify); - - ret = g_source_attach (source, NULL); - - g_source_unref (source); - - return ret; -} - -/** - * clutter_frame_source_add: (skip) - * @fps: the number of times per second to call the function - * @func: function to call - * @data: data to pass to the function - * - * Simple wrapper around clutter_frame_source_add_full(). - * - * Return value: the ID (greater than 0) of the event source. - * - * Since: 0.8 - * - * Deprecated: 1.6: There is no direct replacement for this API - */ -guint -clutter_frame_source_add (guint fps, - GSourceFunc func, - gpointer data) -{ - return clutter_frame_source_add_full (G_PRIORITY_DEFAULT, - fps, func, data, NULL); -} - -static gboolean -clutter_frame_source_prepare (GSource *source, - gint *delay) -{ - ClutterFrameSource *frame_source = (ClutterFrameSource *) source; - gint64 current_time; - -#if GLIB_CHECK_VERSION (2, 27, 3) - current_time = g_source_get_time (source) / 1000; -#else - { - GTimeVal source_time; - g_source_get_current_time (source, &source_time); - current_time = source_time.tv_sec * 1000 + source_time.tv_usec / 1000; - } -#endif - - return _clutter_timeout_interval_prepare (current_time, - &frame_source->timeout, - delay); -} - -static gboolean -clutter_frame_source_check (GSource *source) -{ - return clutter_frame_source_prepare (source, NULL); -} - -static gboolean -clutter_frame_source_dispatch (GSource *source, - GSourceFunc callback, - gpointer user_data) -{ - ClutterFrameSource *frame_source = (ClutterFrameSource *) source; - - return _clutter_timeout_interval_dispatch (&frame_source->timeout, - callback, user_data); -} - -/** - * clutter_threads_add_frame_source_full: (rename-to clutter_threads_add_frame_source) - * @priority: the priority of the frame source. Typically this will be in the - * range between %G_PRIORITY_DEFAULT and %G_PRIORITY_HIGH. - * @fps: the number of times per second to call the function - * @func: function to call - * @data: data to pass to the function - * @notify: function to call when the timeout source is removed - * - * Sets a function to be called at regular intervals holding the Clutter - * threads lock, with the given priority. The function is called repeatedly - * until it returns %FALSE, at which point the timeout is automatically - * removed and the function will not be called again. The @notify function - * is called when the timeout is removed. - * - * This function is similar to clutter_threads_add_timeout_full() - * except that it will try to compensate for delays. For example, if - * @func takes half the interval time to execute then the function - * will be called again half the interval time after it finished. In - * contrast clutter_threads_add_timeout_full() would not fire until a - * full interval after the function completes so the delay between - * calls would be @interval * 1.5. This function does not however try - * to invoke the function multiple times to catch up missing frames if - * @func takes more than @interval ms to execute. - * - * See also clutter_threads_add_idle_full(). - * - * Return value: the ID (greater than 0) of the event source. - * - * Since: 0.8 - * - * Deprecated: 1.6: There is no direct replacement for this API - */ -guint -clutter_threads_add_frame_source_full (gint priority, - guint fps, - GSourceFunc func, - gpointer data, - GDestroyNotify notify) -{ - ClutterThreadsDispatch *dispatch; - - g_return_val_if_fail (func != NULL, 0); - - dispatch = g_slice_new (ClutterThreadsDispatch); - dispatch->func = func; - dispatch->data = data; - dispatch->notify = notify; - - return clutter_frame_source_add_full (priority, - fps, - _clutter_threads_dispatch, dispatch, - _clutter_threads_dispatch_free); -} - -/** - * clutter_threads_add_frame_source: (skip) - * @fps: the number of times per second to call the function - * @func: function to call - * @data: data to pass to the function - * - * Simple wrapper around clutter_threads_add_frame_source_full(). - * - * Return value: the ID (greater than 0) of the event source. - * - * Since: 0.8 - * - * Deprecated: 1.6: There is no direct replacement for this API - */ -guint -clutter_threads_add_frame_source (guint fps, - GSourceFunc func, - gpointer data) -{ - g_return_val_if_fail (func != NULL, 0); - - return clutter_threads_add_frame_source_full (G_PRIORITY_DEFAULT, - fps, - func, data, - NULL); -} diff --git a/clutter/clutter/deprecated/clutter-frame-source.h b/clutter/clutter/deprecated/clutter-frame-source.h deleted file mode 100644 index f45134140..000000000 --- a/clutter/clutter/deprecated/clutter-frame-source.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * Copyright (C) 2008 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __CLUTTER_FRAME_SOURCE_H__ -#define __CLUTTER_FRAME_SOURCE_H__ - -#include - -G_BEGIN_DECLS - -CLUTTER_DEPRECATED_IN_1_6 -guint clutter_frame_source_add (guint fps, - GSourceFunc func, - gpointer data); - -CLUTTER_DEPRECATED_IN_1_6 -guint clutter_frame_source_add_full (gint priority, - guint fps, - GSourceFunc func, - gpointer data, - GDestroyNotify notify); - -G_END_DECLS - -#endif /* __CLUTTER_FRAME_SOURCE_H__ */ diff --git a/clutter/clutter/deprecated/clutter-group.c b/clutter/clutter/deprecated/clutter-group.c index 050cdfa4d..af602fd51 100644 --- a/clutter/clutter/deprecated/clutter-group.c +++ b/clutter/clutter/deprecated/clutter-group.c @@ -47,9 +47,7 @@ * manage child actors. */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include @@ -172,20 +170,6 @@ clutter_group_real_actor_removed (ClutterContainer *container, priv->children = g_list_remove (priv->children, actor); } -static void -clutter_group_real_foreach (ClutterContainer *container, - ClutterCallback callback, - gpointer user_data) -{ - ClutterGroupPrivate *priv = CLUTTER_GROUP (container)->priv; - - /* Using g_list_foreach instead of iterating the list manually - because it has better protection against the current node being - removed. This will happen for example if someone calls - clutter_container_foreach(container, clutter_actor_destroy) */ - g_list_foreach (priv->children, (GFunc) callback, user_data); -} - static void clutter_group_real_raise (ClutterContainer *container, ClutterActor *actor, @@ -287,21 +271,21 @@ clutter_container_iface_init (ClutterContainerIface *iface) iface->actor_added = clutter_group_real_actor_added; iface->remove = clutter_group_real_remove; iface->actor_removed = clutter_group_real_actor_removed; - iface->foreach = clutter_group_real_foreach; iface->raise = clutter_group_real_raise; iface->lower = clutter_group_real_lower; iface->sort_depth_order = clutter_group_real_sort_depth_order; } static void -clutter_group_real_paint (ClutterActor *actor) +clutter_group_real_paint (ClutterActor *actor, + ClutterPaintContext *paint_context) { ClutterGroupPrivate *priv = CLUTTER_GROUP (actor)->priv; CLUTTER_NOTE (PAINT, "ClutterGroup paint enter '%s'", _clutter_actor_get_debug_name (actor)); - g_list_foreach (priv->children, (GFunc) clutter_actor_paint, NULL); + g_list_foreach (priv->children, (GFunc) clutter_actor_paint, paint_context); CLUTTER_NOTE (PAINT, "ClutterGroup paint leave '%s'", _clutter_actor_get_debug_name (actor)); @@ -309,14 +293,14 @@ clutter_group_real_paint (ClutterActor *actor) static void clutter_group_real_pick (ClutterActor *actor, - const ClutterColor *pick) + ClutterPickContext *pick_context) { ClutterGroupPrivate *priv = CLUTTER_GROUP (actor)->priv; /* Chain up so we get a bounding box pained (if we are reactive) */ - CLUTTER_ACTOR_CLASS (clutter_group_parent_class)->pick (actor, pick); + CLUTTER_ACTOR_CLASS (clutter_group_parent_class)->pick (actor, pick_context); - g_list_foreach (priv->children, (GFunc) clutter_actor_paint, NULL); + g_list_foreach (priv->children, (GFunc) clutter_actor_pick, pick_context); } static void @@ -393,21 +377,28 @@ clutter_group_dispose (GObject *object) } static void -clutter_group_real_show_all (ClutterActor *actor) +clutter_group_real_show_all (ClutterActor *self) { - clutter_container_foreach (CLUTTER_CONTAINER (actor), - CLUTTER_CALLBACK (clutter_actor_show), - NULL); - clutter_actor_show (actor); + ClutterActorIter iter; + ClutterActor *actor; + + clutter_actor_iter_init (&iter, self); + while (clutter_actor_iter_next (&iter, &actor)) + clutter_actor_show (actor); + + clutter_actor_show (self); } static void clutter_group_real_hide_all (ClutterActor *actor) { + ClutterActorIter iter; + clutter_actor_hide (actor); - clutter_container_foreach (CLUTTER_CONTAINER (actor), - CLUTTER_CALLBACK (clutter_actor_hide), - NULL); + + clutter_actor_iter_init (&iter, actor); + while (clutter_actor_iter_next (&iter, &actor)) + clutter_actor_hide (actor); } static gboolean diff --git a/clutter/clutter/deprecated/clutter-group.h b/clutter/clutter/deprecated/clutter-group.h index 5bc378f74..650f1dfc1 100644 --- a/clutter/clutter/deprecated/clutter-group.h +++ b/clutter/clutter/deprecated/clutter-group.h @@ -31,17 +31,17 @@ G_BEGIN_DECLS -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_new) +CLUTTER_DEPRECATED_FOR(clutter_actor_new) ClutterActor * clutter_group_new (void); -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_get_child_at_index) +CLUTTER_DEPRECATED_FOR(clutter_actor_get_child_at_index) ClutterActor * clutter_group_get_nth_child (ClutterGroup *self, gint index_); -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_get_n_children) +CLUTTER_DEPRECATED_FOR(clutter_actor_get_n_children) gint clutter_group_get_n_children (ClutterGroup *self); -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_remove_all_children) +CLUTTER_DEPRECATED_FOR(clutter_actor_remove_all_children) void clutter_group_remove_all (ClutterGroup *self); #ifndef CLUTTER_DISABLE_DEPRECATED diff --git a/clutter/clutter/deprecated/clutter-input-device-deprecated.c b/clutter/clutter/deprecated/clutter-input-device-deprecated.c deleted file mode 100644 index 3b9e6978d..000000000 --- a/clutter/clutter/deprecated/clutter-input-device-deprecated.c +++ /dev/null @@ -1,38 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include "clutter-build-config.h" -#endif - -#include - -#define CLUTTER_DISABLE_DEPRECATION_WARNINGS - -#include "clutter-device-manager-private.h" -#include "deprecated/clutter-input-device.h" - -/** - * clutter_input_device_get_device_coords: - * @device: a #ClutterInputDevice of type %CLUTTER_POINTER_DEVICE - * @x: (out): return location for the X coordinate - * @y: (out): return location for the Y coordinate - * - * Retrieves the latest coordinates of the pointer of @device - * - * Since: 1.2 - * - * Deprecated: 1.12: Use clutter_input_device_get_coords() instead. - */ -void -clutter_input_device_get_device_coords (ClutterInputDevice *device, - gint *x, - gint *y) -{ - ClutterPoint point; - - clutter_input_device_get_coords (device, NULL, &point); - - if (x) - *x = point.x; - - if (y) - *y = point.y; -} diff --git a/clutter/clutter/deprecated/clutter-input-device.h b/clutter/clutter/deprecated/clutter-input-device.h deleted file mode 100644 index 692459d20..000000000 --- a/clutter/clutter/deprecated/clutter-input-device.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright © 2009, 2010, 2011 Intel Corp. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Emmanuele Bassi - */ -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __CLUTTER_INPUT_DEVICE_DEPRECATED_H__ -#define __CLUTTER_INPUT_DEVICE_DEPRECATED_H__ - -#include - -G_BEGIN_DECLS - -CLUTTER_DEPRECATED_IN_1_12_FOR(clutter_input_device_get_coords) -void clutter_input_device_get_device_coords (ClutterInputDevice *device, - gint *x, - gint *y); - -G_END_DECLS - -#endif /* __CLUTTER_INPUT_DEVICE_DEPRECATED_H__ */ diff --git a/clutter/clutter/deprecated/clutter-keysyms.h b/clutter/clutter/deprecated/clutter-keysyms.h deleted file mode 100644 index 3374b0b1c..000000000 --- a/clutter/clutter/deprecated/clutter-keysyms.h +++ /dev/null @@ -1,2311 +0,0 @@ -/* Clutter - * - * Copyright (C) 2006, 2007, 2008 OpenedHand Ltd - * Copyright (C) 2009, 2010 Intel Corp - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -/* - * Compatibility version of clutter-keysyms.h. - * - * Since Clutter 1.4, the key symbol defines have been changed to have - * a KEY_ prefix. This is a compatibility header that is included when - * deprecated symbols are enabled. Consider porting to the new names - * instead. - */ - -#ifndef __CLUTTER_KEYSYMS_DEPRECATED_H__ -#define __CLUTTER_KEYSYMS_DEPRECATED_H__ - -#ifndef CLUTTER_DISABLE_DEPRECATED - -#define CLUTTER_VoidSymbol 0xffffff CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_VoidSymbol instead.") -#define CLUTTER_BackSpace 0xff08 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_BackSpace instead.") -#define CLUTTER_Tab 0xff09 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Tab instead.") -#define CLUTTER_Linefeed 0xff0a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Linefeed instead.") -#define CLUTTER_Clear 0xff0b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Clear instead.") -#define CLUTTER_Return 0xff0d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Return instead.") -#define CLUTTER_Pause 0xff13 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Pause instead.") -#define CLUTTER_Scroll_Lock 0xff14 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Scroll_Lock instead.") -#define CLUTTER_Sys_Req 0xff15 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sys_Req instead.") -#define CLUTTER_Escape 0xff1b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Escape instead.") -#define CLUTTER_Delete 0xffff CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Delete instead.") -#define CLUTTER_Multi_key 0xff20 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Multi_key instead.") -#define CLUTTER_Codeinput 0xff37 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Codeinput instead.") -#define CLUTTER_SingleCandidate 0xff3c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_SingleCandidate instead.") -#define CLUTTER_MultipleCandidate 0xff3d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_MultipleCandidate instead.") -#define CLUTTER_PreviousCandidate 0xff3e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_PreviousCandidate instead.") -#define CLUTTER_Kanji 0xff21 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Kanji instead.") -#define CLUTTER_Muhenkan 0xff22 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Muhenkan instead.") -#define CLUTTER_Henkan_Mode 0xff23 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Henkan_Mode instead.") -#define CLUTTER_Henkan 0xff23 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Henkan instead.") -#define CLUTTER_Romaji 0xff24 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Romaji instead.") -#define CLUTTER_Hiragana 0xff25 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hiragana instead.") -#define CLUTTER_Katakana 0xff26 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Katakana instead.") -#define CLUTTER_Hiragana_Katakana 0xff27 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hiragana_Katakana instead.") -#define CLUTTER_Zenkaku 0xff28 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Zenkaku instead.") -#define CLUTTER_Hankaku 0xff29 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hankaku instead.") -#define CLUTTER_Zenkaku_Hankaku 0xff2a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Zenkaku_Hankaku instead.") -#define CLUTTER_Touroku 0xff2b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Touroku instead.") -#define CLUTTER_Massyo 0xff2c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Massyo instead.") -#define CLUTTER_Kana_Lock 0xff2d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Kana_Lock instead.") -#define CLUTTER_Kana_Shift 0xff2e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Kana_Shift instead.") -#define CLUTTER_Eisu_Shift 0xff2f CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Eisu_Shift instead.") -#define CLUTTER_Eisu_toggle 0xff30 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Eisu_toggle instead.") -#define CLUTTER_Kanji_Bangou 0xff37 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Kanji_Bangou instead.") -#define CLUTTER_Zen_Koho 0xff3d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Zen_Koho instead.") -#define CLUTTER_Mae_Koho 0xff3e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Mae_Koho instead.") -#define CLUTTER_Home 0xff50 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Home instead.") -#define CLUTTER_Left 0xff51 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Left instead.") -#define CLUTTER_Up 0xff52 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Up instead.") -#define CLUTTER_Right 0xff53 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Right instead.") -#define CLUTTER_Down 0xff54 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Down instead.") -#define CLUTTER_Prior 0xff55 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Prior instead.") -#define CLUTTER_Page_Up 0xff55 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Page_Up instead.") -#define CLUTTER_Next 0xff56 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Next instead.") -#define CLUTTER_Page_Down 0xff56 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Page_Down instead.") -#define CLUTTER_End 0xff57 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_End instead.") -#define CLUTTER_Begin 0xff58 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Begin instead.") -#define CLUTTER_Select 0xff60 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Select instead.") -#define CLUTTER_Print 0xff61 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Print instead.") -#define CLUTTER_Execute 0xff62 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Execute instead.") -#define CLUTTER_Insert 0xff63 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Insert instead.") -#define CLUTTER_Undo 0xff65 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Undo instead.") -#define CLUTTER_Redo 0xff66 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Redo instead.") -#define CLUTTER_Menu 0xff67 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Menu instead.") -#define CLUTTER_Find 0xff68 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Find instead.") -#define CLUTTER_Cancel 0xff69 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cancel instead.") -#define CLUTTER_Help 0xff6a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Help instead.") -#define CLUTTER_Break 0xff6b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Break instead.") -#define CLUTTER_Mode_switch 0xff7e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Mode_switch instead.") -#define CLUTTER_script_switch 0xff7e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_script_switch instead.") -#define CLUTTER_Num_Lock 0xff7f CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Num_Lock instead.") -#define CLUTTER_KP_Space 0xff80 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_Space instead.") -#define CLUTTER_KP_Tab 0xff89 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_Tab instead.") -#define CLUTTER_KP_Enter 0xff8d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_Enter instead.") -#define CLUTTER_KP_F1 0xff91 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_F1 instead.") -#define CLUTTER_KP_F2 0xff92 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_F2 instead.") -#define CLUTTER_KP_F3 0xff93 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_F3 instead.") -#define CLUTTER_KP_F4 0xff94 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_F4 instead.") -#define CLUTTER_KP_Home 0xff95 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_Home instead.") -#define CLUTTER_KP_Left 0xff96 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_Left instead.") -#define CLUTTER_KP_Up 0xff97 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_Up instead.") -#define CLUTTER_KP_Right 0xff98 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_Right instead.") -#define CLUTTER_KP_Down 0xff99 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_Down instead.") -#define CLUTTER_KP_Prior 0xff9a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_Prior instead.") -#define CLUTTER_KP_Page_Up 0xff9a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_Page_Up instead.") -#define CLUTTER_KP_Next 0xff9b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_Next instead.") -#define CLUTTER_KP_Page_Down 0xff9b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_Page_Down instead.") -#define CLUTTER_KP_End 0xff9c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_End instead.") -#define CLUTTER_KP_Begin 0xff9d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_Begin instead.") -#define CLUTTER_KP_Insert 0xff9e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_Insert instead.") -#define CLUTTER_KP_Delete 0xff9f CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_Delete instead.") -#define CLUTTER_KP_Equal 0xffbd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_Equal instead.") -#define CLUTTER_KP_Multiply 0xffaa CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_Multiply instead.") -#define CLUTTER_KP_Add 0xffab CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_Add instead.") -#define CLUTTER_KP_Separator 0xffac CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_Separator instead.") -#define CLUTTER_KP_Subtract 0xffad CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_Subtract instead.") -#define CLUTTER_KP_Decimal 0xffae CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_Decimal instead.") -#define CLUTTER_KP_Divide 0xffaf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_Divide instead.") -#define CLUTTER_KP_0 0xffb0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_0 instead.") -#define CLUTTER_KP_1 0xffb1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_1 instead.") -#define CLUTTER_KP_2 0xffb2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_2 instead.") -#define CLUTTER_KP_3 0xffb3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_3 instead.") -#define CLUTTER_KP_4 0xffb4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_4 instead.") -#define CLUTTER_KP_5 0xffb5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_5 instead.") -#define CLUTTER_KP_6 0xffb6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_6 instead.") -#define CLUTTER_KP_7 0xffb7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_7 instead.") -#define CLUTTER_KP_8 0xffb8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_8 instead.") -#define CLUTTER_KP_9 0xffb9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_KP_9 instead.") -#define CLUTTER_F1 0xffbe CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F1 instead.") -#define CLUTTER_F2 0xffbf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F2 instead.") -#define CLUTTER_F3 0xffc0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F3 instead.") -#define CLUTTER_F4 0xffc1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F4 instead.") -#define CLUTTER_F5 0xffc2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F5 instead.") -#define CLUTTER_F6 0xffc3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F6 instead.") -#define CLUTTER_F7 0xffc4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F7 instead.") -#define CLUTTER_F8 0xffc5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F8 instead.") -#define CLUTTER_F9 0xffc6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F9 instead.") -#define CLUTTER_F10 0xffc7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F10 instead.") -#define CLUTTER_F11 0xffc8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F11 instead.") -#define CLUTTER_L1 0xffc8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_L1 instead.") -#define CLUTTER_F12 0xffc9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F12 instead.") -#define CLUTTER_L2 0xffc9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_L2 instead.") -#define CLUTTER_F13 0xffca CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F13 instead.") -#define CLUTTER_L3 0xffca CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_L3 instead.") -#define CLUTTER_F14 0xffcb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F14 instead.") -#define CLUTTER_L4 0xffcb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_L4 instead.") -#define CLUTTER_F15 0xffcc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F15 instead.") -#define CLUTTER_L5 0xffcc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_L5 instead.") -#define CLUTTER_F16 0xffcd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F16 instead.") -#define CLUTTER_L6 0xffcd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_L6 instead.") -#define CLUTTER_F17 0xffce CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F17 instead.") -#define CLUTTER_L7 0xffce CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_L7 instead.") -#define CLUTTER_F18 0xffcf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F18 instead.") -#define CLUTTER_L8 0xffcf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_L8 instead.") -#define CLUTTER_F19 0xffd0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F19 instead.") -#define CLUTTER_L9 0xffd0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_L9 instead.") -#define CLUTTER_F20 0xffd1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F20 instead.") -#define CLUTTER_L10 0xffd1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_L10 instead.") -#define CLUTTER_F21 0xffd2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F21 instead.") -#define CLUTTER_R1 0xffd2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_R1 instead.") -#define CLUTTER_F22 0xffd3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F22 instead.") -#define CLUTTER_R2 0xffd3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_R2 instead.") -#define CLUTTER_F23 0xffd4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F23 instead.") -#define CLUTTER_R3 0xffd4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_R3 instead.") -#define CLUTTER_F24 0xffd5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F24 instead.") -#define CLUTTER_R4 0xffd5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_R4 instead.") -#define CLUTTER_F25 0xffd6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F25 instead.") -#define CLUTTER_R5 0xffd6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_R5 instead.") -#define CLUTTER_F26 0xffd7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F26 instead.") -#define CLUTTER_R6 0xffd7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_R6 instead.") -#define CLUTTER_F27 0xffd8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F27 instead.") -#define CLUTTER_R7 0xffd8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_R7 instead.") -#define CLUTTER_F28 0xffd9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F28 instead.") -#define CLUTTER_R8 0xffd9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_R8 instead.") -#define CLUTTER_F29 0xffda CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F29 instead.") -#define CLUTTER_R9 0xffda CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_R9 instead.") -#define CLUTTER_F30 0xffdb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F30 instead.") -#define CLUTTER_R10 0xffdb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_R10 instead.") -#define CLUTTER_F31 0xffdc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F31 instead.") -#define CLUTTER_R11 0xffdc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_R11 instead.") -#define CLUTTER_F32 0xffdd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F32 instead.") -#define CLUTTER_R12 0xffdd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_R12 instead.") -#define CLUTTER_F33 0xffde CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F33 instead.") -#define CLUTTER_R13 0xffde CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_R13 instead.") -#define CLUTTER_F34 0xffdf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F34 instead.") -#define CLUTTER_R14 0xffdf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_R14 instead.") -#define CLUTTER_F35 0xffe0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F35 instead.") -#define CLUTTER_R15 0xffe0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_R15 instead.") -#define CLUTTER_Shift_L 0xffe1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Shift_L instead.") -#define CLUTTER_Shift_R 0xffe2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Shift_R instead.") -#define CLUTTER_Control_L 0xffe3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Control_L instead.") -#define CLUTTER_Control_R 0xffe4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Control_R instead.") -#define CLUTTER_Caps_Lock 0xffe5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Caps_Lock instead.") -#define CLUTTER_Shift_Lock 0xffe6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Shift_Lock instead.") -#define CLUTTER_Meta_L 0xffe7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Meta_L instead.") -#define CLUTTER_Meta_R 0xffe8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Meta_R instead.") -#define CLUTTER_Alt_L 0xffe9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Alt_L instead.") -#define CLUTTER_Alt_R 0xffea CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Alt_R instead.") -#define CLUTTER_Super_L 0xffeb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Super_L instead.") -#define CLUTTER_Super_R 0xffec CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Super_R instead.") -#define CLUTTER_Hyper_L 0xffed CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hyper_L instead.") -#define CLUTTER_Hyper_R 0xffee CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hyper_R instead.") -#define CLUTTER_ISO_Lock 0xfe01 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Lock instead.") -#define CLUTTER_ISO_Level2_Latch 0xfe02 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Level2_Latch instead.") -#define CLUTTER_ISO_Level3_Shift 0xfe03 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Level3_Shift instead.") -#define CLUTTER_ISO_Level3_Latch 0xfe04 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Level3_Latch instead.") -#define CLUTTER_ISO_Level3_Lock 0xfe05 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Level3_Lock instead.") -#define CLUTTER_ISO_Level5_Shift 0xfe11 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Level5_Shift instead.") -#define CLUTTER_ISO_Level5_Latch 0xfe12 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Level5_Latch instead.") -#define CLUTTER_ISO_Level5_Lock 0xfe13 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Level5_Lock instead.") -#define CLUTTER_ISO_Group_Shift 0xff7e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Group_Shift instead.") -#define CLUTTER_ISO_Group_Latch 0xfe06 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Group_Latch instead.") -#define CLUTTER_ISO_Group_Lock 0xfe07 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Group_Lock instead.") -#define CLUTTER_ISO_Next_Group 0xfe08 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Next_Group instead.") -#define CLUTTER_ISO_Next_Group_Lock 0xfe09 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Next_Group_Lock instead.") -#define CLUTTER_ISO_Prev_Group 0xfe0a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Prev_Group instead.") -#define CLUTTER_ISO_Prev_Group_Lock 0xfe0b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Prev_Group_Lock instead.") -#define CLUTTER_ISO_First_Group 0xfe0c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_First_Group instead.") -#define CLUTTER_ISO_First_Group_Lock 0xfe0d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_First_Group_Lock instead.") -#define CLUTTER_ISO_Last_Group 0xfe0e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Last_Group instead.") -#define CLUTTER_ISO_Last_Group_Lock 0xfe0f CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Last_Group_Lock instead.") -#define CLUTTER_ISO_Left_Tab 0xfe20 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Left_Tab instead.") -#define CLUTTER_ISO_Move_Line_Up 0xfe21 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Move_Line_Up instead.") -#define CLUTTER_ISO_Move_Line_Down 0xfe22 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Move_Line_Down instead.") -#define CLUTTER_ISO_Partial_Line_Up 0xfe23 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Partial_Line_Up instead.") -#define CLUTTER_ISO_Partial_Line_Down 0xfe24 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Partial_Line_Down instead.") -#define CLUTTER_ISO_Partial_Space_Left 0xfe25 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Partial_Space_Left instead.") -#define CLUTTER_ISO_Partial_Space_Right 0xfe26 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Partial_Space_Right instead.") -#define CLUTTER_ISO_Set_Margin_Left 0xfe27 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Set_Margin_Left instead.") -#define CLUTTER_ISO_Set_Margin_Right 0xfe28 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Set_Margin_Right instead.") -#define CLUTTER_ISO_Release_Margin_Left 0xfe29 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Release_Margin_Left instead.") -#define CLUTTER_ISO_Release_Margin_Right 0xfe2a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Release_Margin_Right instead.") -#define CLUTTER_ISO_Release_Both_Margins 0xfe2b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Release_Both_Margins instead.") -#define CLUTTER_ISO_Fast_Cursor_Left 0xfe2c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Fast_Cursor_Left instead.") -#define CLUTTER_ISO_Fast_Cursor_Right 0xfe2d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Fast_Cursor_Right instead.") -#define CLUTTER_ISO_Fast_Cursor_Up 0xfe2e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Fast_Cursor_Up instead.") -#define CLUTTER_ISO_Fast_Cursor_Down 0xfe2f CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Fast_Cursor_Down instead.") -#define CLUTTER_ISO_Continuous_Underline 0xfe30 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Continuous_Underline instead.") -#define CLUTTER_ISO_Discontinuous_Underline 0xfe31 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Discontinuous_Underline instead.") -#define CLUTTER_ISO_Emphasize 0xfe32 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Emphasize instead.") -#define CLUTTER_ISO_Center_Object 0xfe33 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Center_Object instead.") -#define CLUTTER_ISO_Enter 0xfe34 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ISO_Enter instead.") -#define CLUTTER_dead_grave 0xfe50 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_grave instead.") -#define CLUTTER_dead_acute 0xfe51 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_acute instead.") -#define CLUTTER_dead_circumflex 0xfe52 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_circumflex instead.") -#define CLUTTER_dead_tilde 0xfe53 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_tilde instead.") -#define CLUTTER_dead_perispomeni 0xfe53 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_perispomeni instead.") -#define CLUTTER_dead_macron 0xfe54 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_macron instead.") -#define CLUTTER_dead_breve 0xfe55 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_breve instead.") -#define CLUTTER_dead_abovedot 0xfe56 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_abovedot instead.") -#define CLUTTER_dead_diaeresis 0xfe57 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_diaeresis instead.") -#define CLUTTER_dead_abovering 0xfe58 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_abovering instead.") -#define CLUTTER_dead_doubleacute 0xfe59 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_doubleacute instead.") -#define CLUTTER_dead_caron 0xfe5a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_caron instead.") -#define CLUTTER_dead_cedilla 0xfe5b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_cedilla instead.") -#define CLUTTER_dead_ogonek 0xfe5c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_ogonek instead.") -#define CLUTTER_dead_iota 0xfe5d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_iota instead.") -#define CLUTTER_dead_voiced_sound 0xfe5e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_voiced_sound instead.") -#define CLUTTER_dead_semivoiced_sound 0xfe5f CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_semivoiced_sound instead.") -#define CLUTTER_dead_belowdot 0xfe60 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_belowdot instead.") -#define CLUTTER_dead_hook 0xfe61 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_hook instead.") -#define CLUTTER_dead_horn 0xfe62 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_horn instead.") -#define CLUTTER_dead_stroke 0xfe63 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_stroke instead.") -#define CLUTTER_dead_abovecomma 0xfe64 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_abovecomma instead.") -#define CLUTTER_dead_psili 0xfe64 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_psili instead.") -#define CLUTTER_dead_abovereversedcomma 0xfe65 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_abovereversedcomma instead.") -#define CLUTTER_dead_dasia 0xfe65 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_dasia instead.") -#define CLUTTER_dead_doublegrave 0xfe66 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_doublegrave instead.") -#define CLUTTER_dead_belowring 0xfe67 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_belowring instead.") -#define CLUTTER_dead_belowmacron 0xfe68 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_belowmacron instead.") -#define CLUTTER_dead_belowcircumflex 0xfe69 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_belowcircumflex instead.") -#define CLUTTER_dead_belowtilde 0xfe6a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_belowtilde instead.") -#define CLUTTER_dead_belowbreve 0xfe6b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_belowbreve instead.") -#define CLUTTER_dead_belowdiaeresis 0xfe6c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_belowdiaeresis instead.") -#define CLUTTER_dead_invertedbreve 0xfe6d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_invertedbreve instead.") -#define CLUTTER_dead_belowcomma 0xfe6e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_belowcomma instead.") -#define CLUTTER_dead_currency 0xfe6f CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_currency instead.") -#define CLUTTER_dead_lowline 0xfe90 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_lowline instead.") -#define CLUTTER_dead_aboveverticalline 0xfe91 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_aboveverticalline instead.") -#define CLUTTER_dead_belowverticalline 0xfe92 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_belowverticalline instead.") -#define CLUTTER_dead_longsolidusoverlay 0xfe93 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_longsolidusoverlay instead.") -#define CLUTTER_dead_a 0xfe80 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_a instead.") -#define CLUTTER_dead_A 0xfe81 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_A instead.") -#define CLUTTER_dead_e 0xfe82 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_e instead.") -#define CLUTTER_dead_E 0xfe83 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_E instead.") -#define CLUTTER_dead_i 0xfe84 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_i instead.") -#define CLUTTER_dead_I 0xfe85 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_I instead.") -#define CLUTTER_dead_o 0xfe86 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_o instead.") -#define CLUTTER_dead_O 0xfe87 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_O instead.") -#define CLUTTER_dead_u 0xfe88 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_u instead.") -#define CLUTTER_dead_U 0xfe89 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_U instead.") -#define CLUTTER_dead_small_schwa 0xfe8a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_small_schwa instead.") -#define CLUTTER_dead_capital_schwa 0xfe8b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_capital_schwa instead.") -#define CLUTTER_dead_greek 0xfe8c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dead_greek instead.") -#define CLUTTER_First_Virtual_Screen 0xfed0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_First_Virtual_Screen instead.") -#define CLUTTER_Prev_Virtual_Screen 0xfed1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Prev_Virtual_Screen instead.") -#define CLUTTER_Next_Virtual_Screen 0xfed2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Next_Virtual_Screen instead.") -#define CLUTTER_Last_Virtual_Screen 0xfed4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Last_Virtual_Screen instead.") -#define CLUTTER_Terminate_Server 0xfed5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Terminate_Server instead.") -#define CLUTTER_AccessX_Enable 0xfe70 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_AccessX_Enable instead.") -#define CLUTTER_AccessX_Feedback_Enable 0xfe71 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_AccessX_Feedback_Enable instead.") -#define CLUTTER_RepeatKeys_Enable 0xfe72 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_RepeatKeys_Enable instead.") -#define CLUTTER_SlowKeys_Enable 0xfe73 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_SlowKeys_Enable instead.") -#define CLUTTER_BounceKeys_Enable 0xfe74 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_BounceKeys_Enable instead.") -#define CLUTTER_StickyKeys_Enable 0xfe75 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_StickyKeys_Enable instead.") -#define CLUTTER_MouseKeys_Enable 0xfe76 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_MouseKeys_Enable instead.") -#define CLUTTER_MouseKeys_Accel_Enable 0xfe77 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_MouseKeys_Accel_Enable instead.") -#define CLUTTER_Overlay1_Enable 0xfe78 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Overlay1_Enable instead.") -#define CLUTTER_Overlay2_Enable 0xfe79 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Overlay2_Enable instead.") -#define CLUTTER_AudibleBell_Enable 0xfe7a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_AudibleBell_Enable instead.") -#define CLUTTER_Pointer_Left 0xfee0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Pointer_Left instead.") -#define CLUTTER_Pointer_Right 0xfee1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Pointer_Right instead.") -#define CLUTTER_Pointer_Up 0xfee2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Pointer_Up instead.") -#define CLUTTER_Pointer_Down 0xfee3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Pointer_Down instead.") -#define CLUTTER_Pointer_UpLeft 0xfee4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Pointer_UpLeft instead.") -#define CLUTTER_Pointer_UpRight 0xfee5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Pointer_UpRight instead.") -#define CLUTTER_Pointer_DownLeft 0xfee6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Pointer_DownLeft instead.") -#define CLUTTER_Pointer_DownRight 0xfee7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Pointer_DownRight instead.") -#define CLUTTER_Pointer_Button_Dflt 0xfee8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Pointer_Button_Dflt instead.") -#define CLUTTER_Pointer_Button1 0xfee9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Pointer_Button1 instead.") -#define CLUTTER_Pointer_Button2 0xfeea CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Pointer_Button2 instead.") -#define CLUTTER_Pointer_Button3 0xfeeb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Pointer_Button3 instead.") -#define CLUTTER_Pointer_Button4 0xfeec CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Pointer_Button4 instead.") -#define CLUTTER_Pointer_Button5 0xfeed CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Pointer_Button5 instead.") -#define CLUTTER_Pointer_DblClick_Dflt 0xfeee CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Pointer_DblClick_Dflt instead.") -#define CLUTTER_Pointer_DblClick1 0xfeef CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Pointer_DblClick1 instead.") -#define CLUTTER_Pointer_DblClick2 0xfef0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Pointer_DblClick2 instead.") -#define CLUTTER_Pointer_DblClick3 0xfef1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Pointer_DblClick3 instead.") -#define CLUTTER_Pointer_DblClick4 0xfef2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Pointer_DblClick4 instead.") -#define CLUTTER_Pointer_DblClick5 0xfef3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Pointer_DblClick5 instead.") -#define CLUTTER_Pointer_Drag_Dflt 0xfef4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Pointer_Drag_Dflt instead.") -#define CLUTTER_Pointer_Drag1 0xfef5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Pointer_Drag1 instead.") -#define CLUTTER_Pointer_Drag2 0xfef6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Pointer_Drag2 instead.") -#define CLUTTER_Pointer_Drag3 0xfef7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Pointer_Drag3 instead.") -#define CLUTTER_Pointer_Drag4 0xfef8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Pointer_Drag4 instead.") -#define CLUTTER_Pointer_Drag5 0xfefd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Pointer_Drag5 instead.") -#define CLUTTER_Pointer_EnableKeys 0xfef9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Pointer_EnableKeys instead.") -#define CLUTTER_Pointer_Accelerate 0xfefa CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Pointer_Accelerate instead.") -#define CLUTTER_Pointer_DfltBtnNext 0xfefb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Pointer_DfltBtnNext instead.") -#define CLUTTER_Pointer_DfltBtnPrev 0xfefc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Pointer_DfltBtnPrev instead.") -#define CLUTTER_ch 0xfea0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ch instead.") -#define CLUTTER_Ch 0xfea1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ch instead.") -#define CLUTTER_CH 0xfea2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_CH instead.") -#define CLUTTER_c_h 0xfea3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_c_h instead.") -#define CLUTTER_C_h 0xfea4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_C_h instead.") -#define CLUTTER_C_H 0xfea5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_C_H instead.") -#define CLUTTER_3270_Duplicate 0xfd01 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_3270_Duplicate instead.") -#define CLUTTER_3270_FieldMark 0xfd02 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_3270_FieldMark instead.") -#define CLUTTER_3270_Right2 0xfd03 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_3270_Right2 instead.") -#define CLUTTER_3270_Left2 0xfd04 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_3270_Left2 instead.") -#define CLUTTER_3270_BackTab 0xfd05 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_3270_BackTab instead.") -#define CLUTTER_3270_EraseEOF 0xfd06 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_3270_EraseEOF instead.") -#define CLUTTER_3270_EraseInput 0xfd07 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_3270_EraseInput instead.") -#define CLUTTER_3270_Reset 0xfd08 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_3270_Reset instead.") -#define CLUTTER_3270_Quit 0xfd09 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_3270_Quit instead.") -#define CLUTTER_3270_PA1 0xfd0a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_3270_PA1 instead.") -#define CLUTTER_3270_PA2 0xfd0b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_3270_PA2 instead.") -#define CLUTTER_3270_PA3 0xfd0c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_3270_PA3 instead.") -#define CLUTTER_3270_Test 0xfd0d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_3270_Test instead.") -#define CLUTTER_3270_Attn 0xfd0e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_3270_Attn instead.") -#define CLUTTER_3270_CursorBlink 0xfd0f CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_3270_CursorBlink instead.") -#define CLUTTER_3270_AltCursor 0xfd10 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_3270_AltCursor instead.") -#define CLUTTER_3270_KeyClick 0xfd11 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_3270_KeyClick instead.") -#define CLUTTER_3270_Jump 0xfd12 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_3270_Jump instead.") -#define CLUTTER_3270_Ident 0xfd13 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_3270_Ident instead.") -#define CLUTTER_3270_Rule 0xfd14 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_3270_Rule instead.") -#define CLUTTER_3270_Copy 0xfd15 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_3270_Copy instead.") -#define CLUTTER_3270_Play 0xfd16 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_3270_Play instead.") -#define CLUTTER_3270_Setup 0xfd17 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_3270_Setup instead.") -#define CLUTTER_3270_Record 0xfd18 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_3270_Record instead.") -#define CLUTTER_3270_ChangeScreen 0xfd19 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_3270_ChangeScreen instead.") -#define CLUTTER_3270_DeleteWord 0xfd1a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_3270_DeleteWord instead.") -#define CLUTTER_3270_ExSelect 0xfd1b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_3270_ExSelect instead.") -#define CLUTTER_3270_CursorSelect 0xfd1c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_3270_CursorSelect instead.") -#define CLUTTER_3270_PrintScreen 0xfd1d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_3270_PrintScreen instead.") -#define CLUTTER_3270_Enter 0xfd1e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_3270_Enter instead.") -#define CLUTTER_space 0x020 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_space instead.") -#define CLUTTER_exclam 0x021 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_exclam instead.") -#define CLUTTER_quotedbl 0x022 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_quotedbl instead.") -#define CLUTTER_numbersign 0x023 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_numbersign instead.") -#define CLUTTER_dollar 0x024 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dollar instead.") -#define CLUTTER_percent 0x025 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_percent instead.") -#define CLUTTER_ampersand 0x026 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ampersand instead.") -#define CLUTTER_apostrophe 0x027 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_apostrophe instead.") -#define CLUTTER_quoteright 0x027 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_quoteright instead.") -#define CLUTTER_parenleft 0x028 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_parenleft instead.") -#define CLUTTER_parenright 0x029 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_parenright instead.") -#define CLUTTER_asterisk 0x02a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_asterisk instead.") -#define CLUTTER_plus 0x02b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_plus instead.") -#define CLUTTER_comma 0x02c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_comma instead.") -#define CLUTTER_minus 0x02d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_minus instead.") -#define CLUTTER_period 0x02e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_period instead.") -#define CLUTTER_slash 0x02f CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_slash instead.") -#define CLUTTER_0 0x030 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_0 instead.") -#define CLUTTER_1 0x031 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_1 instead.") -#define CLUTTER_2 0x032 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_2 instead.") -#define CLUTTER_3 0x033 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_3 instead.") -#define CLUTTER_4 0x034 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_4 instead.") -#define CLUTTER_5 0x035 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_5 instead.") -#define CLUTTER_6 0x036 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_6 instead.") -#define CLUTTER_7 0x037 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_7 instead.") -#define CLUTTER_8 0x038 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_8 instead.") -#define CLUTTER_9 0x039 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_9 instead.") -#define CLUTTER_colon 0x03a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_colon instead.") -#define CLUTTER_semicolon 0x03b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_semicolon instead.") -#define CLUTTER_less 0x03c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_less instead.") -#define CLUTTER_equal 0x03d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_equal instead.") -#define CLUTTER_greater 0x03e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_greater instead.") -#define CLUTTER_question 0x03f CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_question instead.") -#define CLUTTER_at 0x040 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_at instead.") -#define CLUTTER_A 0x041 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_A instead.") -#define CLUTTER_B 0x042 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_B instead.") -#define CLUTTER_C 0x043 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_C instead.") -#define CLUTTER_D 0x044 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_D instead.") -#define CLUTTER_E 0x045 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_E instead.") -#define CLUTTER_F 0x046 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_F instead.") -#define CLUTTER_G 0x047 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_G instead.") -#define CLUTTER_H 0x048 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_H instead.") -#define CLUTTER_I 0x049 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_I instead.") -#define CLUTTER_J 0x04a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_J instead.") -#define CLUTTER_K 0x04b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_K instead.") -#define CLUTTER_L 0x04c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_L instead.") -#define CLUTTER_M 0x04d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_M instead.") -#define CLUTTER_N 0x04e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_N instead.") -#define CLUTTER_O 0x04f CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_O instead.") -#define CLUTTER_P 0x050 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_P instead.") -#define CLUTTER_Q 0x051 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Q instead.") -#define CLUTTER_R 0x052 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_R instead.") -#define CLUTTER_S 0x053 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_S instead.") -#define CLUTTER_T 0x054 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_T instead.") -#define CLUTTER_U 0x055 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_U instead.") -#define CLUTTER_V 0x056 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_V instead.") -#define CLUTTER_W 0x057 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_W instead.") -#define CLUTTER_X 0x058 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_X instead.") -#define CLUTTER_Y 0x059 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Y instead.") -#define CLUTTER_Z 0x05a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Z instead.") -#define CLUTTER_bracketleft 0x05b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_bracketleft instead.") -#define CLUTTER_backslash 0x05c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_backslash instead.") -#define CLUTTER_bracketright 0x05d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_bracketright instead.") -#define CLUTTER_asciicircum 0x05e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_asciicircum instead.") -#define CLUTTER_underscore 0x05f CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_underscore instead.") -#define CLUTTER_grave 0x060 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_grave instead.") -#define CLUTTER_quoteleft 0x060 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_quoteleft instead.") -#define CLUTTER_a 0x061 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_a instead.") -#define CLUTTER_b 0x062 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_b instead.") -#define CLUTTER_c 0x063 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_c instead.") -#define CLUTTER_d 0x064 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_d instead.") -#define CLUTTER_e 0x065 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_e instead.") -#define CLUTTER_f 0x066 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_f instead.") -#define CLUTTER_g 0x067 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_g instead.") -#define CLUTTER_h 0x068 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_h instead.") -#define CLUTTER_i 0x069 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_i instead.") -#define CLUTTER_j 0x06a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_j instead.") -#define CLUTTER_k 0x06b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_k instead.") -#define CLUTTER_l 0x06c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_l instead.") -#define CLUTTER_m 0x06d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_m instead.") -#define CLUTTER_n 0x06e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_n instead.") -#define CLUTTER_o 0x06f CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_o instead.") -#define CLUTTER_p 0x070 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_p instead.") -#define CLUTTER_q 0x071 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_q instead.") -#define CLUTTER_r 0x072 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_r instead.") -#define CLUTTER_s 0x073 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_s instead.") -#define CLUTTER_t 0x074 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_t instead.") -#define CLUTTER_u 0x075 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_u instead.") -#define CLUTTER_v 0x076 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_v instead.") -#define CLUTTER_w 0x077 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_w instead.") -#define CLUTTER_x 0x078 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_x instead.") -#define CLUTTER_y 0x079 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_y instead.") -#define CLUTTER_z 0x07a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_z instead.") -#define CLUTTER_braceleft 0x07b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braceleft instead.") -#define CLUTTER_bar 0x07c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_bar instead.") -#define CLUTTER_braceright 0x07d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braceright instead.") -#define CLUTTER_asciitilde 0x07e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_asciitilde instead.") -#define CLUTTER_nobreakspace 0x0a0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_nobreakspace instead.") -#define CLUTTER_exclamdown 0x0a1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_exclamdown instead.") -#define CLUTTER_cent 0x0a2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_cent instead.") -#define CLUTTER_sterling 0x0a3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_sterling instead.") -#define CLUTTER_currency 0x0a4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_currency instead.") -#define CLUTTER_yen 0x0a5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_yen instead.") -#define CLUTTER_brokenbar 0x0a6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_brokenbar instead.") -#define CLUTTER_section 0x0a7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_section instead.") -#define CLUTTER_diaeresis 0x0a8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_diaeresis instead.") -#define CLUTTER_copyright 0x0a9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_copyright instead.") -#define CLUTTER_ordfeminine 0x0aa CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ordfeminine instead.") -#define CLUTTER_guillemotleft 0x0ab CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_guillemotleft instead.") -#define CLUTTER_notsign 0x0ac CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_notsign instead.") -#define CLUTTER_hyphen 0x0ad CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hyphen instead.") -#define CLUTTER_registered 0x0ae CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_registered instead.") -#define CLUTTER_macron 0x0af CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_macron instead.") -#define CLUTTER_degree 0x0b0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_degree instead.") -#define CLUTTER_plusminus 0x0b1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_plusminus instead.") -#define CLUTTER_twosuperior 0x0b2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_twosuperior instead.") -#define CLUTTER_threesuperior 0x0b3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_threesuperior instead.") -#define CLUTTER_acute 0x0b4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_acute instead.") -#define CLUTTER_mu 0x0b5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_mu instead.") -#define CLUTTER_paragraph 0x0b6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_paragraph instead.") -#define CLUTTER_periodcentered 0x0b7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_periodcentered instead.") -#define CLUTTER_cedilla 0x0b8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_cedilla instead.") -#define CLUTTER_onesuperior 0x0b9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_onesuperior instead.") -#define CLUTTER_masculine 0x0ba CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_masculine instead.") -#define CLUTTER_guillemotright 0x0bb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_guillemotright instead.") -#define CLUTTER_onequarter 0x0bc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_onequarter instead.") -#define CLUTTER_onehalf 0x0bd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_onehalf instead.") -#define CLUTTER_threequarters 0x0be CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_threequarters instead.") -#define CLUTTER_questiondown 0x0bf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_questiondown instead.") -#define CLUTTER_Agrave 0x0c0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Agrave instead.") -#define CLUTTER_Aacute 0x0c1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Aacute instead.") -#define CLUTTER_Acircumflex 0x0c2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Acircumflex instead.") -#define CLUTTER_Atilde 0x0c3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Atilde instead.") -#define CLUTTER_Adiaeresis 0x0c4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Adiaeresis instead.") -#define CLUTTER_Aring 0x0c5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Aring instead.") -#define CLUTTER_AE 0x0c6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_AE instead.") -#define CLUTTER_Ccedilla 0x0c7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ccedilla instead.") -#define CLUTTER_Egrave 0x0c8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Egrave instead.") -#define CLUTTER_Eacute 0x0c9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Eacute instead.") -#define CLUTTER_Ecircumflex 0x0ca CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ecircumflex instead.") -#define CLUTTER_Ediaeresis 0x0cb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ediaeresis instead.") -#define CLUTTER_Igrave 0x0cc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Igrave instead.") -#define CLUTTER_Iacute 0x0cd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Iacute instead.") -#define CLUTTER_Icircumflex 0x0ce CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Icircumflex instead.") -#define CLUTTER_Idiaeresis 0x0cf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Idiaeresis instead.") -#define CLUTTER_ETH 0x0d0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ETH instead.") -#define CLUTTER_Eth 0x0d0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Eth instead.") -#define CLUTTER_Ntilde 0x0d1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ntilde instead.") -#define CLUTTER_Ograve 0x0d2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ograve instead.") -#define CLUTTER_Oacute 0x0d3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Oacute instead.") -#define CLUTTER_Ocircumflex 0x0d4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ocircumflex instead.") -#define CLUTTER_Otilde 0x0d5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Otilde instead.") -#define CLUTTER_Odiaeresis 0x0d6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Odiaeresis instead.") -#define CLUTTER_multiply 0x0d7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_multiply instead.") -#define CLUTTER_Oslash 0x0d8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Oslash instead.") -#define CLUTTER_Ooblique 0x0d8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ooblique instead.") -#define CLUTTER_Ugrave 0x0d9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ugrave instead.") -#define CLUTTER_Uacute 0x0da CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Uacute instead.") -#define CLUTTER_Ucircumflex 0x0db CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ucircumflex instead.") -#define CLUTTER_Udiaeresis 0x0dc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Udiaeresis instead.") -#define CLUTTER_Yacute 0x0dd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Yacute instead.") -#define CLUTTER_THORN 0x0de CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_THORN instead.") -#define CLUTTER_Thorn 0x0de CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thorn instead.") -#define CLUTTER_ssharp 0x0df CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ssharp instead.") -#define CLUTTER_agrave 0x0e0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_agrave instead.") -#define CLUTTER_aacute 0x0e1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_aacute instead.") -#define CLUTTER_acircumflex 0x0e2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_acircumflex instead.") -#define CLUTTER_atilde 0x0e3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_atilde instead.") -#define CLUTTER_adiaeresis 0x0e4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_adiaeresis instead.") -#define CLUTTER_aring 0x0e5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_aring instead.") -#define CLUTTER_ae 0x0e6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ae instead.") -#define CLUTTER_ccedilla 0x0e7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ccedilla instead.") -#define CLUTTER_egrave 0x0e8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_egrave instead.") -#define CLUTTER_eacute 0x0e9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_eacute instead.") -#define CLUTTER_ecircumflex 0x0ea CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ecircumflex instead.") -#define CLUTTER_ediaeresis 0x0eb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ediaeresis instead.") -#define CLUTTER_igrave 0x0ec CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_igrave instead.") -#define CLUTTER_iacute 0x0ed CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_iacute instead.") -#define CLUTTER_icircumflex 0x0ee CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_icircumflex instead.") -#define CLUTTER_idiaeresis 0x0ef CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_idiaeresis instead.") -#define CLUTTER_eth 0x0f0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_eth instead.") -#define CLUTTER_ntilde 0x0f1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ntilde instead.") -#define CLUTTER_ograve 0x0f2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ograve instead.") -#define CLUTTER_oacute 0x0f3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_oacute instead.") -#define CLUTTER_ocircumflex 0x0f4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ocircumflex instead.") -#define CLUTTER_otilde 0x0f5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_otilde instead.") -#define CLUTTER_odiaeresis 0x0f6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_odiaeresis instead.") -#define CLUTTER_division 0x0f7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_division instead.") -#define CLUTTER_oslash 0x0f8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_oslash instead.") -#define CLUTTER_ooblique 0x0f8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ooblique instead.") -#define CLUTTER_ugrave 0x0f9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ugrave instead.") -#define CLUTTER_uacute 0x0fa CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_uacute instead.") -#define CLUTTER_ucircumflex 0x0fb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ucircumflex instead.") -#define CLUTTER_udiaeresis 0x0fc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_udiaeresis instead.") -#define CLUTTER_yacute 0x0fd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_yacute instead.") -#define CLUTTER_thorn 0x0fe CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_thorn instead.") -#define CLUTTER_ydiaeresis 0x0ff CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ydiaeresis instead.") -#define CLUTTER_Aogonek 0x1a1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Aogonek instead.") -#define CLUTTER_breve 0x1a2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_breve instead.") -#define CLUTTER_Lstroke 0x1a3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Lstroke instead.") -#define CLUTTER_Lcaron 0x1a5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Lcaron instead.") -#define CLUTTER_Sacute 0x1a6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sacute instead.") -#define CLUTTER_Scaron 0x1a9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Scaron instead.") -#define CLUTTER_Scedilla 0x1aa CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Scedilla instead.") -#define CLUTTER_Tcaron 0x1ab CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Tcaron instead.") -#define CLUTTER_Zacute 0x1ac CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Zacute instead.") -#define CLUTTER_Zcaron 0x1ae CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Zcaron instead.") -#define CLUTTER_Zabovedot 0x1af CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Zabovedot instead.") -#define CLUTTER_aogonek 0x1b1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_aogonek instead.") -#define CLUTTER_ogonek 0x1b2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ogonek instead.") -#define CLUTTER_lstroke 0x1b3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_lstroke instead.") -#define CLUTTER_lcaron 0x1b5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_lcaron instead.") -#define CLUTTER_sacute 0x1b6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_sacute instead.") -#define CLUTTER_caron 0x1b7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_caron instead.") -#define CLUTTER_scaron 0x1b9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_scaron instead.") -#define CLUTTER_scedilla 0x1ba CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_scedilla instead.") -#define CLUTTER_tcaron 0x1bb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_tcaron instead.") -#define CLUTTER_zacute 0x1bc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_zacute instead.") -#define CLUTTER_doubleacute 0x1bd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_doubleacute instead.") -#define CLUTTER_zcaron 0x1be CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_zcaron instead.") -#define CLUTTER_zabovedot 0x1bf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_zabovedot instead.") -#define CLUTTER_Racute 0x1c0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Racute instead.") -#define CLUTTER_Abreve 0x1c3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Abreve instead.") -#define CLUTTER_Lacute 0x1c5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Lacute instead.") -#define CLUTTER_Cacute 0x1c6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cacute instead.") -#define CLUTTER_Ccaron 0x1c8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ccaron instead.") -#define CLUTTER_Eogonek 0x1ca CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Eogonek instead.") -#define CLUTTER_Ecaron 0x1cc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ecaron instead.") -#define CLUTTER_Dcaron 0x1cf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Dcaron instead.") -#define CLUTTER_Dstroke 0x1d0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Dstroke instead.") -#define CLUTTER_Nacute 0x1d1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Nacute instead.") -#define CLUTTER_Ncaron 0x1d2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ncaron instead.") -#define CLUTTER_Odoubleacute 0x1d5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Odoubleacute instead.") -#define CLUTTER_Rcaron 0x1d8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Rcaron instead.") -#define CLUTTER_Uring 0x1d9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Uring instead.") -#define CLUTTER_Udoubleacute 0x1db CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Udoubleacute instead.") -#define CLUTTER_Tcedilla 0x1de CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Tcedilla instead.") -#define CLUTTER_racute 0x1e0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_racute instead.") -#define CLUTTER_abreve 0x1e3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_abreve instead.") -#define CLUTTER_lacute 0x1e5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_lacute instead.") -#define CLUTTER_cacute 0x1e6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_cacute instead.") -#define CLUTTER_ccaron 0x1e8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ccaron instead.") -#define CLUTTER_eogonek 0x1ea CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_eogonek instead.") -#define CLUTTER_ecaron 0x1ec CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ecaron instead.") -#define CLUTTER_dcaron 0x1ef CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dcaron instead.") -#define CLUTTER_dstroke 0x1f0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dstroke instead.") -#define CLUTTER_nacute 0x1f1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_nacute instead.") -#define CLUTTER_ncaron 0x1f2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ncaron instead.") -#define CLUTTER_odoubleacute 0x1f5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_odoubleacute instead.") -#define CLUTTER_rcaron 0x1f8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_rcaron instead.") -#define CLUTTER_uring 0x1f9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_uring instead.") -#define CLUTTER_udoubleacute 0x1fb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_udoubleacute instead.") -#define CLUTTER_tcedilla 0x1fe CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_tcedilla instead.") -#define CLUTTER_abovedot 0x1ff CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_abovedot instead.") -#define CLUTTER_Hstroke 0x2a1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hstroke instead.") -#define CLUTTER_Hcircumflex 0x2a6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hcircumflex instead.") -#define CLUTTER_Iabovedot 0x2a9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Iabovedot instead.") -#define CLUTTER_Gbreve 0x2ab CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Gbreve instead.") -#define CLUTTER_Jcircumflex 0x2ac CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Jcircumflex instead.") -#define CLUTTER_hstroke 0x2b1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hstroke instead.") -#define CLUTTER_hcircumflex 0x2b6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hcircumflex instead.") -#define CLUTTER_idotless 0x2b9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_idotless instead.") -#define CLUTTER_gbreve 0x2bb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_gbreve instead.") -#define CLUTTER_jcircumflex 0x2bc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_jcircumflex instead.") -#define CLUTTER_Cabovedot 0x2c5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cabovedot instead.") -#define CLUTTER_Ccircumflex 0x2c6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ccircumflex instead.") -#define CLUTTER_Gabovedot 0x2d5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Gabovedot instead.") -#define CLUTTER_Gcircumflex 0x2d8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Gcircumflex instead.") -#define CLUTTER_Ubreve 0x2dd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ubreve instead.") -#define CLUTTER_Scircumflex 0x2de CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Scircumflex instead.") -#define CLUTTER_cabovedot 0x2e5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_cabovedot instead.") -#define CLUTTER_ccircumflex 0x2e6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ccircumflex instead.") -#define CLUTTER_gabovedot 0x2f5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_gabovedot instead.") -#define CLUTTER_gcircumflex 0x2f8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_gcircumflex instead.") -#define CLUTTER_ubreve 0x2fd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ubreve instead.") -#define CLUTTER_scircumflex 0x2fe CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_scircumflex instead.") -#define CLUTTER_kra 0x3a2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kra instead.") -#define CLUTTER_kappa 0x3a2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kappa instead.") -#define CLUTTER_Rcedilla 0x3a3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Rcedilla instead.") -#define CLUTTER_Itilde 0x3a5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Itilde instead.") -#define CLUTTER_Lcedilla 0x3a6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Lcedilla instead.") -#define CLUTTER_Emacron 0x3aa CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Emacron instead.") -#define CLUTTER_Gcedilla 0x3ab CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Gcedilla instead.") -#define CLUTTER_Tslash 0x3ac CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Tslash instead.") -#define CLUTTER_rcedilla 0x3b3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_rcedilla instead.") -#define CLUTTER_itilde 0x3b5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_itilde instead.") -#define CLUTTER_lcedilla 0x3b6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_lcedilla instead.") -#define CLUTTER_emacron 0x3ba CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_emacron instead.") -#define CLUTTER_gcedilla 0x3bb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_gcedilla instead.") -#define CLUTTER_tslash 0x3bc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_tslash instead.") -#define CLUTTER_ENG 0x3bd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ENG instead.") -#define CLUTTER_eng 0x3bf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_eng instead.") -#define CLUTTER_Amacron 0x3c0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Amacron instead.") -#define CLUTTER_Iogonek 0x3c7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Iogonek instead.") -#define CLUTTER_Eabovedot 0x3cc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Eabovedot instead.") -#define CLUTTER_Imacron 0x3cf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Imacron instead.") -#define CLUTTER_Ncedilla 0x3d1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ncedilla instead.") -#define CLUTTER_Omacron 0x3d2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Omacron instead.") -#define CLUTTER_Kcedilla 0x3d3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Kcedilla instead.") -#define CLUTTER_Uogonek 0x3d9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Uogonek instead.") -#define CLUTTER_Utilde 0x3dd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Utilde instead.") -#define CLUTTER_Umacron 0x3de CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Umacron instead.") -#define CLUTTER_amacron 0x3e0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_amacron instead.") -#define CLUTTER_iogonek 0x3e7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_iogonek instead.") -#define CLUTTER_eabovedot 0x3ec CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_eabovedot instead.") -#define CLUTTER_imacron 0x3ef CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_imacron instead.") -#define CLUTTER_ncedilla 0x3f1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ncedilla instead.") -#define CLUTTER_omacron 0x3f2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_omacron instead.") -#define CLUTTER_kcedilla 0x3f3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kcedilla instead.") -#define CLUTTER_uogonek 0x3f9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_uogonek instead.") -#define CLUTTER_utilde 0x3fd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_utilde instead.") -#define CLUTTER_umacron 0x3fe CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_umacron instead.") -#define CLUTTER_Wcircumflex 0x1000174 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Wcircumflex instead.") -#define CLUTTER_wcircumflex 0x1000175 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_wcircumflex instead.") -#define CLUTTER_Ycircumflex 0x1000176 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ycircumflex instead.") -#define CLUTTER_ycircumflex 0x1000177 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ycircumflex instead.") -#define CLUTTER_Babovedot 0x1001e02 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Babovedot instead.") -#define CLUTTER_babovedot 0x1001e03 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_babovedot instead.") -#define CLUTTER_Dabovedot 0x1001e0a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Dabovedot instead.") -#define CLUTTER_dabovedot 0x1001e0b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dabovedot instead.") -#define CLUTTER_Fabovedot 0x1001e1e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Fabovedot instead.") -#define CLUTTER_fabovedot 0x1001e1f CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_fabovedot instead.") -#define CLUTTER_Mabovedot 0x1001e40 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Mabovedot instead.") -#define CLUTTER_mabovedot 0x1001e41 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_mabovedot instead.") -#define CLUTTER_Pabovedot 0x1001e56 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Pabovedot instead.") -#define CLUTTER_pabovedot 0x1001e57 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_pabovedot instead.") -#define CLUTTER_Sabovedot 0x1001e60 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sabovedot instead.") -#define CLUTTER_sabovedot 0x1001e61 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_sabovedot instead.") -#define CLUTTER_Tabovedot 0x1001e6a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Tabovedot instead.") -#define CLUTTER_tabovedot 0x1001e6b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_tabovedot instead.") -#define CLUTTER_Wgrave 0x1001e80 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Wgrave instead.") -#define CLUTTER_wgrave 0x1001e81 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_wgrave instead.") -#define CLUTTER_Wacute 0x1001e82 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Wacute instead.") -#define CLUTTER_wacute 0x1001e83 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_wacute instead.") -#define CLUTTER_Wdiaeresis 0x1001e84 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Wdiaeresis instead.") -#define CLUTTER_wdiaeresis 0x1001e85 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_wdiaeresis instead.") -#define CLUTTER_Ygrave 0x1001ef2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ygrave instead.") -#define CLUTTER_ygrave 0x1001ef3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ygrave instead.") -#define CLUTTER_OE 0x13bc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_OE instead.") -#define CLUTTER_oe 0x13bd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_oe instead.") -#define CLUTTER_Ydiaeresis 0x13be CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ydiaeresis instead.") -#define CLUTTER_overline 0x47e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_overline instead.") -#define CLUTTER_kana_fullstop 0x4a1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_fullstop instead.") -#define CLUTTER_kana_openingbracket 0x4a2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_openingbracket instead.") -#define CLUTTER_kana_closingbracket 0x4a3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_closingbracket instead.") -#define CLUTTER_kana_comma 0x4a4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_comma instead.") -#define CLUTTER_kana_conjunctive 0x4a5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_conjunctive instead.") -#define CLUTTER_kana_middledot 0x4a5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_middledot instead.") -#define CLUTTER_kana_WO 0x4a6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_WO instead.") -#define CLUTTER_kana_a 0x4a7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_a instead.") -#define CLUTTER_kana_i 0x4a8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_i instead.") -#define CLUTTER_kana_u 0x4a9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_u instead.") -#define CLUTTER_kana_e 0x4aa CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_e instead.") -#define CLUTTER_kana_o 0x4ab CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_o instead.") -#define CLUTTER_kana_ya 0x4ac CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_ya instead.") -#define CLUTTER_kana_yu 0x4ad CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_yu instead.") -#define CLUTTER_kana_yo 0x4ae CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_yo instead.") -#define CLUTTER_kana_tsu 0x4af CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_tsu instead.") -#define CLUTTER_kana_tu 0x4af CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_tu instead.") -#define CLUTTER_prolongedsound 0x4b0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_prolongedsound instead.") -#define CLUTTER_kana_A 0x4b1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_A instead.") -#define CLUTTER_kana_I 0x4b2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_I instead.") -#define CLUTTER_kana_U 0x4b3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_U instead.") -#define CLUTTER_kana_E 0x4b4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_E instead.") -#define CLUTTER_kana_O 0x4b5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_O instead.") -#define CLUTTER_kana_KA 0x4b6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_KA instead.") -#define CLUTTER_kana_KI 0x4b7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_KI instead.") -#define CLUTTER_kana_KU 0x4b8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_KU instead.") -#define CLUTTER_kana_KE 0x4b9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_KE instead.") -#define CLUTTER_kana_KO 0x4ba CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_KO instead.") -#define CLUTTER_kana_SA 0x4bb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_SA instead.") -#define CLUTTER_kana_SHI 0x4bc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_SHI instead.") -#define CLUTTER_kana_SU 0x4bd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_SU instead.") -#define CLUTTER_kana_SE 0x4be CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_SE instead.") -#define CLUTTER_kana_SO 0x4bf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_SO instead.") -#define CLUTTER_kana_TA 0x4c0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_TA instead.") -#define CLUTTER_kana_CHI 0x4c1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_CHI instead.") -#define CLUTTER_kana_TI 0x4c1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_TI instead.") -#define CLUTTER_kana_TSU 0x4c2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_TSU instead.") -#define CLUTTER_kana_TU 0x4c2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_TU instead.") -#define CLUTTER_kana_TE 0x4c3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_TE instead.") -#define CLUTTER_kana_TO 0x4c4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_TO instead.") -#define CLUTTER_kana_NA 0x4c5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_NA instead.") -#define CLUTTER_kana_NI 0x4c6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_NI instead.") -#define CLUTTER_kana_NU 0x4c7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_NU instead.") -#define CLUTTER_kana_NE 0x4c8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_NE instead.") -#define CLUTTER_kana_NO 0x4c9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_NO instead.") -#define CLUTTER_kana_HA 0x4ca CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_HA instead.") -#define CLUTTER_kana_HI 0x4cb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_HI instead.") -#define CLUTTER_kana_FU 0x4cc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_FU instead.") -#define CLUTTER_kana_HU 0x4cc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_HU instead.") -#define CLUTTER_kana_HE 0x4cd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_HE instead.") -#define CLUTTER_kana_HO 0x4ce CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_HO instead.") -#define CLUTTER_kana_MA 0x4cf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_MA instead.") -#define CLUTTER_kana_MI 0x4d0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_MI instead.") -#define CLUTTER_kana_MU 0x4d1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_MU instead.") -#define CLUTTER_kana_ME 0x4d2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_ME instead.") -#define CLUTTER_kana_MO 0x4d3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_MO instead.") -#define CLUTTER_kana_YA 0x4d4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_YA instead.") -#define CLUTTER_kana_YU 0x4d5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_YU instead.") -#define CLUTTER_kana_YO 0x4d6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_YO instead.") -#define CLUTTER_kana_RA 0x4d7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_RA instead.") -#define CLUTTER_kana_RI 0x4d8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_RI instead.") -#define CLUTTER_kana_RU 0x4d9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_RU instead.") -#define CLUTTER_kana_RE 0x4da CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_RE instead.") -#define CLUTTER_kana_RO 0x4db CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_RO instead.") -#define CLUTTER_kana_WA 0x4dc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_WA instead.") -#define CLUTTER_kana_N 0x4dd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_N instead.") -#define CLUTTER_voicedsound 0x4de CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_voicedsound instead.") -#define CLUTTER_semivoicedsound 0x4df CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_semivoicedsound instead.") -#define CLUTTER_kana_switch 0xff7e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_kana_switch instead.") -#define CLUTTER_Farsi_0 0x10006f0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Farsi_0 instead.") -#define CLUTTER_Farsi_1 0x10006f1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Farsi_1 instead.") -#define CLUTTER_Farsi_2 0x10006f2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Farsi_2 instead.") -#define CLUTTER_Farsi_3 0x10006f3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Farsi_3 instead.") -#define CLUTTER_Farsi_4 0x10006f4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Farsi_4 instead.") -#define CLUTTER_Farsi_5 0x10006f5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Farsi_5 instead.") -#define CLUTTER_Farsi_6 0x10006f6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Farsi_6 instead.") -#define CLUTTER_Farsi_7 0x10006f7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Farsi_7 instead.") -#define CLUTTER_Farsi_8 0x10006f8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Farsi_8 instead.") -#define CLUTTER_Farsi_9 0x10006f9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Farsi_9 instead.") -#define CLUTTER_Arabic_percent 0x100066a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_percent instead.") -#define CLUTTER_Arabic_superscript_alef 0x1000670 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_superscript_alef instead.") -#define CLUTTER_Arabic_tteh 0x1000679 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_tteh instead.") -#define CLUTTER_Arabic_peh 0x100067e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_peh instead.") -#define CLUTTER_Arabic_tcheh 0x1000686 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_tcheh instead.") -#define CLUTTER_Arabic_ddal 0x1000688 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_ddal instead.") -#define CLUTTER_Arabic_rreh 0x1000691 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_rreh instead.") -#define CLUTTER_Arabic_comma 0x5ac CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_comma instead.") -#define CLUTTER_Arabic_fullstop 0x10006d4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_fullstop instead.") -#define CLUTTER_Arabic_0 0x1000660 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_0 instead.") -#define CLUTTER_Arabic_1 0x1000661 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_1 instead.") -#define CLUTTER_Arabic_2 0x1000662 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_2 instead.") -#define CLUTTER_Arabic_3 0x1000663 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_3 instead.") -#define CLUTTER_Arabic_4 0x1000664 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_4 instead.") -#define CLUTTER_Arabic_5 0x1000665 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_5 instead.") -#define CLUTTER_Arabic_6 0x1000666 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_6 instead.") -#define CLUTTER_Arabic_7 0x1000667 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_7 instead.") -#define CLUTTER_Arabic_8 0x1000668 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_8 instead.") -#define CLUTTER_Arabic_9 0x1000669 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_9 instead.") -#define CLUTTER_Arabic_semicolon 0x5bb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_semicolon instead.") -#define CLUTTER_Arabic_question_mark 0x5bf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_question_mark instead.") -#define CLUTTER_Arabic_hamza 0x5c1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_hamza instead.") -#define CLUTTER_Arabic_maddaonalef 0x5c2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_maddaonalef instead.") -#define CLUTTER_Arabic_hamzaonalef 0x5c3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_hamzaonalef instead.") -#define CLUTTER_Arabic_hamzaonwaw 0x5c4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_hamzaonwaw instead.") -#define CLUTTER_Arabic_hamzaunderalef 0x5c5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_hamzaunderalef instead.") -#define CLUTTER_Arabic_hamzaonyeh 0x5c6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_hamzaonyeh instead.") -#define CLUTTER_Arabic_alef 0x5c7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_alef instead.") -#define CLUTTER_Arabic_beh 0x5c8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_beh instead.") -#define CLUTTER_Arabic_tehmarbuta 0x5c9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_tehmarbuta instead.") -#define CLUTTER_Arabic_teh 0x5ca CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_teh instead.") -#define CLUTTER_Arabic_theh 0x5cb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_theh instead.") -#define CLUTTER_Arabic_jeem 0x5cc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_jeem instead.") -#define CLUTTER_Arabic_hah 0x5cd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_hah instead.") -#define CLUTTER_Arabic_khah 0x5ce CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_khah instead.") -#define CLUTTER_Arabic_dal 0x5cf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_dal instead.") -#define CLUTTER_Arabic_thal 0x5d0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_thal instead.") -#define CLUTTER_Arabic_ra 0x5d1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_ra instead.") -#define CLUTTER_Arabic_zain 0x5d2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_zain instead.") -#define CLUTTER_Arabic_seen 0x5d3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_seen instead.") -#define CLUTTER_Arabic_sheen 0x5d4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_sheen instead.") -#define CLUTTER_Arabic_sad 0x5d5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_sad instead.") -#define CLUTTER_Arabic_dad 0x5d6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_dad instead.") -#define CLUTTER_Arabic_tah 0x5d7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_tah instead.") -#define CLUTTER_Arabic_zah 0x5d8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_zah instead.") -#define CLUTTER_Arabic_ain 0x5d9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_ain instead.") -#define CLUTTER_Arabic_ghain 0x5da CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_ghain instead.") -#define CLUTTER_Arabic_tatweel 0x5e0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_tatweel instead.") -#define CLUTTER_Arabic_feh 0x5e1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_feh instead.") -#define CLUTTER_Arabic_qaf 0x5e2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_qaf instead.") -#define CLUTTER_Arabic_kaf 0x5e3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_kaf instead.") -#define CLUTTER_Arabic_lam 0x5e4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_lam instead.") -#define CLUTTER_Arabic_meem 0x5e5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_meem instead.") -#define CLUTTER_Arabic_noon 0x5e6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_noon instead.") -#define CLUTTER_Arabic_ha 0x5e7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_ha instead.") -#define CLUTTER_Arabic_heh 0x5e7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_heh instead.") -#define CLUTTER_Arabic_waw 0x5e8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_waw instead.") -#define CLUTTER_Arabic_alefmaksura 0x5e9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_alefmaksura instead.") -#define CLUTTER_Arabic_yeh 0x5ea CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_yeh instead.") -#define CLUTTER_Arabic_fathatan 0x5eb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_fathatan instead.") -#define CLUTTER_Arabic_dammatan 0x5ec CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_dammatan instead.") -#define CLUTTER_Arabic_kasratan 0x5ed CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_kasratan instead.") -#define CLUTTER_Arabic_fatha 0x5ee CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_fatha instead.") -#define CLUTTER_Arabic_damma 0x5ef CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_damma instead.") -#define CLUTTER_Arabic_kasra 0x5f0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_kasra instead.") -#define CLUTTER_Arabic_shadda 0x5f1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_shadda instead.") -#define CLUTTER_Arabic_sukun 0x5f2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_sukun instead.") -#define CLUTTER_Arabic_madda_above 0x1000653 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_madda_above instead.") -#define CLUTTER_Arabic_hamza_above 0x1000654 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_hamza_above instead.") -#define CLUTTER_Arabic_hamza_below 0x1000655 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_hamza_below instead.") -#define CLUTTER_Arabic_jeh 0x1000698 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_jeh instead.") -#define CLUTTER_Arabic_veh 0x10006a4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_veh instead.") -#define CLUTTER_Arabic_keheh 0x10006a9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_keheh instead.") -#define CLUTTER_Arabic_gaf 0x10006af CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_gaf instead.") -#define CLUTTER_Arabic_noon_ghunna 0x10006ba CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_noon_ghunna instead.") -#define CLUTTER_Arabic_heh_doachashmee 0x10006be CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_heh_doachashmee instead.") -#define CLUTTER_Farsi_yeh 0x10006cc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Farsi_yeh instead.") -#define CLUTTER_Arabic_farsi_yeh 0x10006cc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_farsi_yeh instead.") -#define CLUTTER_Arabic_yeh_baree 0x10006d2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_yeh_baree instead.") -#define CLUTTER_Arabic_heh_goal 0x10006c1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_heh_goal instead.") -#define CLUTTER_Arabic_switch 0xff7e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Arabic_switch instead.") -#define CLUTTER_Cyrillic_GHE_bar 0x1000492 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_GHE_bar instead.") -#define CLUTTER_Cyrillic_ghe_bar 0x1000493 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_ghe_bar instead.") -#define CLUTTER_Cyrillic_ZHE_descender 0x1000496 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_ZHE_descender instead.") -#define CLUTTER_Cyrillic_zhe_descender 0x1000497 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_zhe_descender instead.") -#define CLUTTER_Cyrillic_KA_descender 0x100049a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_KA_descender instead.") -#define CLUTTER_Cyrillic_ka_descender 0x100049b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_ka_descender instead.") -#define CLUTTER_Cyrillic_KA_vertstroke 0x100049c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_KA_vertstroke instead.") -#define CLUTTER_Cyrillic_ka_vertstroke 0x100049d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_ka_vertstroke instead.") -#define CLUTTER_Cyrillic_EN_descender 0x10004a2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_EN_descender instead.") -#define CLUTTER_Cyrillic_en_descender 0x10004a3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_en_descender instead.") -#define CLUTTER_Cyrillic_U_straight 0x10004ae CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_U_straight instead.") -#define CLUTTER_Cyrillic_u_straight 0x10004af CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_u_straight instead.") -#define CLUTTER_Cyrillic_U_straight_bar 0x10004b0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_U_straight_bar instead.") -#define CLUTTER_Cyrillic_u_straight_bar 0x10004b1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_u_straight_bar instead.") -#define CLUTTER_Cyrillic_HA_descender 0x10004b2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_HA_descender instead.") -#define CLUTTER_Cyrillic_ha_descender 0x10004b3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_ha_descender instead.") -#define CLUTTER_Cyrillic_CHE_descender 0x10004b6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_CHE_descender instead.") -#define CLUTTER_Cyrillic_che_descender 0x10004b7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_che_descender instead.") -#define CLUTTER_Cyrillic_CHE_vertstroke 0x10004b8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_CHE_vertstroke instead.") -#define CLUTTER_Cyrillic_che_vertstroke 0x10004b9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_che_vertstroke instead.") -#define CLUTTER_Cyrillic_SHHA 0x10004ba CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_SHHA instead.") -#define CLUTTER_Cyrillic_shha 0x10004bb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_shha instead.") -#define CLUTTER_Cyrillic_SCHWA 0x10004d8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_SCHWA instead.") -#define CLUTTER_Cyrillic_schwa 0x10004d9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_schwa instead.") -#define CLUTTER_Cyrillic_I_macron 0x10004e2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_I_macron instead.") -#define CLUTTER_Cyrillic_i_macron 0x10004e3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_i_macron instead.") -#define CLUTTER_Cyrillic_O_bar 0x10004e8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_O_bar instead.") -#define CLUTTER_Cyrillic_o_bar 0x10004e9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_o_bar instead.") -#define CLUTTER_Cyrillic_U_macron 0x10004ee CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_U_macron instead.") -#define CLUTTER_Cyrillic_u_macron 0x10004ef CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_u_macron instead.") -#define CLUTTER_Serbian_dje 0x6a1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Serbian_dje instead.") -#define CLUTTER_Macedonia_gje 0x6a2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Macedonia_gje instead.") -#define CLUTTER_Cyrillic_io 0x6a3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_io instead.") -#define CLUTTER_Ukrainian_ie 0x6a4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ukrainian_ie instead.") -#define CLUTTER_Ukranian_je 0x6a4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ukranian_je instead.") -#define CLUTTER_Macedonia_dse 0x6a5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Macedonia_dse instead.") -#define CLUTTER_Ukrainian_i 0x6a6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ukrainian_i instead.") -#define CLUTTER_Ukranian_i 0x6a6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ukranian_i instead.") -#define CLUTTER_Ukrainian_yi 0x6a7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ukrainian_yi instead.") -#define CLUTTER_Ukranian_yi 0x6a7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ukranian_yi instead.") -#define CLUTTER_Cyrillic_je 0x6a8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_je instead.") -#define CLUTTER_Serbian_je 0x6a8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Serbian_je instead.") -#define CLUTTER_Cyrillic_lje 0x6a9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_lje instead.") -#define CLUTTER_Serbian_lje 0x6a9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Serbian_lje instead.") -#define CLUTTER_Cyrillic_nje 0x6aa CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_nje instead.") -#define CLUTTER_Serbian_nje 0x6aa CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Serbian_nje instead.") -#define CLUTTER_Serbian_tshe 0x6ab CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Serbian_tshe instead.") -#define CLUTTER_Macedonia_kje 0x6ac CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Macedonia_kje instead.") -#define CLUTTER_Ukrainian_ghe_with_upturn 0x6ad CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ukrainian_ghe_with_upturn instead.") -#define CLUTTER_Byelorussian_shortu 0x6ae CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Byelorussian_shortu instead.") -#define CLUTTER_Cyrillic_dzhe 0x6af CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_dzhe instead.") -#define CLUTTER_Serbian_dze 0x6af CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Serbian_dze instead.") -#define CLUTTER_numerosign 0x6b0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_numerosign instead.") -#define CLUTTER_Serbian_DJE 0x6b1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Serbian_DJE instead.") -#define CLUTTER_Macedonia_GJE 0x6b2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Macedonia_GJE instead.") -#define CLUTTER_Cyrillic_IO 0x6b3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_IO instead.") -#define CLUTTER_Ukrainian_IE 0x6b4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ukrainian_IE instead.") -#define CLUTTER_Ukranian_JE 0x6b4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ukranian_JE instead.") -#define CLUTTER_Macedonia_DSE 0x6b5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Macedonia_DSE instead.") -#define CLUTTER_Ukrainian_I 0x6b6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ukrainian_I instead.") -#define CLUTTER_Ukranian_I 0x6b6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ukranian_I instead.") -#define CLUTTER_Ukrainian_YI 0x6b7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ukrainian_YI instead.") -#define CLUTTER_Ukranian_YI 0x6b7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ukranian_YI instead.") -#define CLUTTER_Cyrillic_JE 0x6b8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_JE instead.") -#define CLUTTER_Serbian_JE 0x6b8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Serbian_JE instead.") -#define CLUTTER_Cyrillic_LJE 0x6b9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_LJE instead.") -#define CLUTTER_Serbian_LJE 0x6b9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Serbian_LJE instead.") -#define CLUTTER_Cyrillic_NJE 0x6ba CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_NJE instead.") -#define CLUTTER_Serbian_NJE 0x6ba CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Serbian_NJE instead.") -#define CLUTTER_Serbian_TSHE 0x6bb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Serbian_TSHE instead.") -#define CLUTTER_Macedonia_KJE 0x6bc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Macedonia_KJE instead.") -#define CLUTTER_Ukrainian_GHE_WITH_UPTURN 0x6bd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ukrainian_GHE_WITH_UPTURN instead.") -#define CLUTTER_Byelorussian_SHORTU 0x6be CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Byelorussian_SHORTU instead.") -#define CLUTTER_Cyrillic_DZHE 0x6bf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_DZHE instead.") -#define CLUTTER_Serbian_DZE 0x6bf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Serbian_DZE instead.") -#define CLUTTER_Cyrillic_yu 0x6c0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_yu instead.") -#define CLUTTER_Cyrillic_a 0x6c1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_a instead.") -#define CLUTTER_Cyrillic_be 0x6c2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_be instead.") -#define CLUTTER_Cyrillic_tse 0x6c3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_tse instead.") -#define CLUTTER_Cyrillic_de 0x6c4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_de instead.") -#define CLUTTER_Cyrillic_ie 0x6c5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_ie instead.") -#define CLUTTER_Cyrillic_ef 0x6c6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_ef instead.") -#define CLUTTER_Cyrillic_ghe 0x6c7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_ghe instead.") -#define CLUTTER_Cyrillic_ha 0x6c8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_ha instead.") -#define CLUTTER_Cyrillic_i 0x6c9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_i instead.") -#define CLUTTER_Cyrillic_shorti 0x6ca CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_shorti instead.") -#define CLUTTER_Cyrillic_ka 0x6cb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_ka instead.") -#define CLUTTER_Cyrillic_el 0x6cc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_el instead.") -#define CLUTTER_Cyrillic_em 0x6cd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_em instead.") -#define CLUTTER_Cyrillic_en 0x6ce CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_en instead.") -#define CLUTTER_Cyrillic_o 0x6cf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_o instead.") -#define CLUTTER_Cyrillic_pe 0x6d0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_pe instead.") -#define CLUTTER_Cyrillic_ya 0x6d1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_ya instead.") -#define CLUTTER_Cyrillic_er 0x6d2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_er instead.") -#define CLUTTER_Cyrillic_es 0x6d3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_es instead.") -#define CLUTTER_Cyrillic_te 0x6d4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_te instead.") -#define CLUTTER_Cyrillic_u 0x6d5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_u instead.") -#define CLUTTER_Cyrillic_zhe 0x6d6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_zhe instead.") -#define CLUTTER_Cyrillic_ve 0x6d7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_ve instead.") -#define CLUTTER_Cyrillic_softsign 0x6d8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_softsign instead.") -#define CLUTTER_Cyrillic_yeru 0x6d9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_yeru instead.") -#define CLUTTER_Cyrillic_ze 0x6da CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_ze instead.") -#define CLUTTER_Cyrillic_sha 0x6db CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_sha instead.") -#define CLUTTER_Cyrillic_e 0x6dc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_e instead.") -#define CLUTTER_Cyrillic_shcha 0x6dd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_shcha instead.") -#define CLUTTER_Cyrillic_che 0x6de CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_che instead.") -#define CLUTTER_Cyrillic_hardsign 0x6df CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_hardsign instead.") -#define CLUTTER_Cyrillic_YU 0x6e0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_YU instead.") -#define CLUTTER_Cyrillic_A 0x6e1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_A instead.") -#define CLUTTER_Cyrillic_BE 0x6e2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_BE instead.") -#define CLUTTER_Cyrillic_TSE 0x6e3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_TSE instead.") -#define CLUTTER_Cyrillic_DE 0x6e4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_DE instead.") -#define CLUTTER_Cyrillic_IE 0x6e5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_IE instead.") -#define CLUTTER_Cyrillic_EF 0x6e6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_EF instead.") -#define CLUTTER_Cyrillic_GHE 0x6e7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_GHE instead.") -#define CLUTTER_Cyrillic_HA 0x6e8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_HA instead.") -#define CLUTTER_Cyrillic_I 0x6e9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_I instead.") -#define CLUTTER_Cyrillic_SHORTI 0x6ea CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_SHORTI instead.") -#define CLUTTER_Cyrillic_KA 0x6eb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_KA instead.") -#define CLUTTER_Cyrillic_EL 0x6ec CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_EL instead.") -#define CLUTTER_Cyrillic_EM 0x6ed CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_EM instead.") -#define CLUTTER_Cyrillic_EN 0x6ee CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_EN instead.") -#define CLUTTER_Cyrillic_O 0x6ef CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_O instead.") -#define CLUTTER_Cyrillic_PE 0x6f0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_PE instead.") -#define CLUTTER_Cyrillic_YA 0x6f1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_YA instead.") -#define CLUTTER_Cyrillic_ER 0x6f2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_ER instead.") -#define CLUTTER_Cyrillic_ES 0x6f3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_ES instead.") -#define CLUTTER_Cyrillic_TE 0x6f4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_TE instead.") -#define CLUTTER_Cyrillic_U 0x6f5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_U instead.") -#define CLUTTER_Cyrillic_ZHE 0x6f6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_ZHE instead.") -#define CLUTTER_Cyrillic_VE 0x6f7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_VE instead.") -#define CLUTTER_Cyrillic_SOFTSIGN 0x6f8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_SOFTSIGN instead.") -#define CLUTTER_Cyrillic_YERU 0x6f9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_YERU instead.") -#define CLUTTER_Cyrillic_ZE 0x6fa CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_ZE instead.") -#define CLUTTER_Cyrillic_SHA 0x6fb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_SHA instead.") -#define CLUTTER_Cyrillic_E 0x6fc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_E instead.") -#define CLUTTER_Cyrillic_SHCHA 0x6fd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_SHCHA instead.") -#define CLUTTER_Cyrillic_CHE 0x6fe CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_CHE instead.") -#define CLUTTER_Cyrillic_HARDSIGN 0x6ff CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Cyrillic_HARDSIGN instead.") -#define CLUTTER_Greek_ALPHAaccent 0x7a1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_ALPHAaccent instead.") -#define CLUTTER_Greek_EPSILONaccent 0x7a2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_EPSILONaccent instead.") -#define CLUTTER_Greek_ETAaccent 0x7a3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_ETAaccent instead.") -#define CLUTTER_Greek_IOTAaccent 0x7a4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_IOTAaccent instead.") -#define CLUTTER_Greek_IOTAdieresis 0x7a5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_IOTAdieresis instead.") -#define CLUTTER_Greek_IOTAdiaeresis 0x7a5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_IOTAdiaeresis instead.") -#define CLUTTER_Greek_OMICRONaccent 0x7a7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_OMICRONaccent instead.") -#define CLUTTER_Greek_UPSILONaccent 0x7a8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_UPSILONaccent instead.") -#define CLUTTER_Greek_UPSILONdieresis 0x7a9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_UPSILONdieresis instead.") -#define CLUTTER_Greek_OMEGAaccent 0x7ab CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_OMEGAaccent instead.") -#define CLUTTER_Greek_accentdieresis 0x7ae CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_accentdieresis instead.") -#define CLUTTER_Greek_horizbar 0x7af CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_horizbar instead.") -#define CLUTTER_Greek_alphaaccent 0x7b1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_alphaaccent instead.") -#define CLUTTER_Greek_epsilonaccent 0x7b2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_epsilonaccent instead.") -#define CLUTTER_Greek_etaaccent 0x7b3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_etaaccent instead.") -#define CLUTTER_Greek_iotaaccent 0x7b4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_iotaaccent instead.") -#define CLUTTER_Greek_iotadieresis 0x7b5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_iotadieresis instead.") -#define CLUTTER_Greek_iotaaccentdieresis 0x7b6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_iotaaccentdieresis instead.") -#define CLUTTER_Greek_omicronaccent 0x7b7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_omicronaccent instead.") -#define CLUTTER_Greek_upsilonaccent 0x7b8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_upsilonaccent instead.") -#define CLUTTER_Greek_upsilondieresis 0x7b9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_upsilondieresis instead.") -#define CLUTTER_Greek_upsilonaccentdieresis 0x7ba CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_upsilonaccentdieresis instead.") -#define CLUTTER_Greek_omegaaccent 0x7bb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_omegaaccent instead.") -#define CLUTTER_Greek_ALPHA 0x7c1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_ALPHA instead.") -#define CLUTTER_Greek_BETA 0x7c2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_BETA instead.") -#define CLUTTER_Greek_GAMMA 0x7c3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_GAMMA instead.") -#define CLUTTER_Greek_DELTA 0x7c4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_DELTA instead.") -#define CLUTTER_Greek_EPSILON 0x7c5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_EPSILON instead.") -#define CLUTTER_Greek_ZETA 0x7c6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_ZETA instead.") -#define CLUTTER_Greek_ETA 0x7c7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_ETA instead.") -#define CLUTTER_Greek_THETA 0x7c8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_THETA instead.") -#define CLUTTER_Greek_IOTA 0x7c9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_IOTA instead.") -#define CLUTTER_Greek_KAPPA 0x7ca CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_KAPPA instead.") -#define CLUTTER_Greek_LAMDA 0x7cb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_LAMDA instead.") -#define CLUTTER_Greek_LAMBDA 0x7cb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_LAMBDA instead.") -#define CLUTTER_Greek_MU 0x7cc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_MU instead.") -#define CLUTTER_Greek_NU 0x7cd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_NU instead.") -#define CLUTTER_Greek_XI 0x7ce CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_XI instead.") -#define CLUTTER_Greek_OMICRON 0x7cf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_OMICRON instead.") -#define CLUTTER_Greek_PI 0x7d0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_PI instead.") -#define CLUTTER_Greek_RHO 0x7d1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_RHO instead.") -#define CLUTTER_Greek_SIGMA 0x7d2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_SIGMA instead.") -#define CLUTTER_Greek_TAU 0x7d4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_TAU instead.") -#define CLUTTER_Greek_UPSILON 0x7d5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_UPSILON instead.") -#define CLUTTER_Greek_PHI 0x7d6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_PHI instead.") -#define CLUTTER_Greek_CHI 0x7d7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_CHI instead.") -#define CLUTTER_Greek_PSI 0x7d8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_PSI instead.") -#define CLUTTER_Greek_OMEGA 0x7d9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_OMEGA instead.") -#define CLUTTER_Greek_alpha 0x7e1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_alpha instead.") -#define CLUTTER_Greek_beta 0x7e2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_beta instead.") -#define CLUTTER_Greek_gamma 0x7e3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_gamma instead.") -#define CLUTTER_Greek_delta 0x7e4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_delta instead.") -#define CLUTTER_Greek_epsilon 0x7e5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_epsilon instead.") -#define CLUTTER_Greek_zeta 0x7e6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_zeta instead.") -#define CLUTTER_Greek_eta 0x7e7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_eta instead.") -#define CLUTTER_Greek_theta 0x7e8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_theta instead.") -#define CLUTTER_Greek_iota 0x7e9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_iota instead.") -#define CLUTTER_Greek_kappa 0x7ea CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_kappa instead.") -#define CLUTTER_Greek_lamda 0x7eb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_lamda instead.") -#define CLUTTER_Greek_lambda 0x7eb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_lambda instead.") -#define CLUTTER_Greek_mu 0x7ec CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_mu instead.") -#define CLUTTER_Greek_nu 0x7ed CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_nu instead.") -#define CLUTTER_Greek_xi 0x7ee CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_xi instead.") -#define CLUTTER_Greek_omicron 0x7ef CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_omicron instead.") -#define CLUTTER_Greek_pi 0x7f0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_pi instead.") -#define CLUTTER_Greek_rho 0x7f1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_rho instead.") -#define CLUTTER_Greek_sigma 0x7f2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_sigma instead.") -#define CLUTTER_Greek_finalsmallsigma 0x7f3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_finalsmallsigma instead.") -#define CLUTTER_Greek_tau 0x7f4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_tau instead.") -#define CLUTTER_Greek_upsilon 0x7f5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_upsilon instead.") -#define CLUTTER_Greek_phi 0x7f6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_phi instead.") -#define CLUTTER_Greek_chi 0x7f7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_chi instead.") -#define CLUTTER_Greek_psi 0x7f8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_psi instead.") -#define CLUTTER_Greek_omega 0x7f9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_omega instead.") -#define CLUTTER_Greek_switch 0xff7e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Greek_switch instead.") -#define CLUTTER_leftradical 0x8a1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_leftradical instead.") -#define CLUTTER_topleftradical 0x8a2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_topleftradical instead.") -#define CLUTTER_horizconnector 0x8a3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_horizconnector instead.") -#define CLUTTER_topintegral 0x8a4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_topintegral instead.") -#define CLUTTER_botintegral 0x8a5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_botintegral instead.") -#define CLUTTER_vertconnector 0x8a6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_vertconnector instead.") -#define CLUTTER_topleftsqbracket 0x8a7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_topleftsqbracket instead.") -#define CLUTTER_botleftsqbracket 0x8a8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_botleftsqbracket instead.") -#define CLUTTER_toprightsqbracket 0x8a9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_toprightsqbracket instead.") -#define CLUTTER_botrightsqbracket 0x8aa CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_botrightsqbracket instead.") -#define CLUTTER_topleftparens 0x8ab CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_topleftparens instead.") -#define CLUTTER_botleftparens 0x8ac CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_botleftparens instead.") -#define CLUTTER_toprightparens 0x8ad CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_toprightparens instead.") -#define CLUTTER_botrightparens 0x8ae CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_botrightparens instead.") -#define CLUTTER_leftmiddlecurlybrace 0x8af CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_leftmiddlecurlybrace instead.") -#define CLUTTER_rightmiddlecurlybrace 0x8b0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_rightmiddlecurlybrace instead.") -#define CLUTTER_topleftsummation 0x8b1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_topleftsummation instead.") -#define CLUTTER_botleftsummation 0x8b2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_botleftsummation instead.") -#define CLUTTER_topvertsummationconnector 0x8b3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_topvertsummationconnector instead.") -#define CLUTTER_botvertsummationconnector 0x8b4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_botvertsummationconnector instead.") -#define CLUTTER_toprightsummation 0x8b5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_toprightsummation instead.") -#define CLUTTER_botrightsummation 0x8b6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_botrightsummation instead.") -#define CLUTTER_rightmiddlesummation 0x8b7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_rightmiddlesummation instead.") -#define CLUTTER_lessthanequal 0x8bc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_lessthanequal instead.") -#define CLUTTER_notequal 0x8bd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_notequal instead.") -#define CLUTTER_greaterthanequal 0x8be CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_greaterthanequal instead.") -#define CLUTTER_integral 0x8bf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_integral instead.") -#define CLUTTER_therefore 0x8c0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_therefore instead.") -#define CLUTTER_variation 0x8c1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_variation instead.") -#define CLUTTER_infinity 0x8c2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_infinity instead.") -#define CLUTTER_nabla 0x8c5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_nabla instead.") -#define CLUTTER_approximate 0x8c8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_approximate instead.") -#define CLUTTER_similarequal 0x8c9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_similarequal instead.") -#define CLUTTER_ifonlyif 0x8cd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ifonlyif instead.") -#define CLUTTER_implies 0x8ce CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_implies instead.") -#define CLUTTER_identical 0x8cf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_identical instead.") -#define CLUTTER_radical 0x8d6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_radical instead.") -#define CLUTTER_includedin 0x8da CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_includedin instead.") -#define CLUTTER_includes 0x8db CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_includes instead.") -#define CLUTTER_intersection 0x8dc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_intersection instead.") -#define CLUTTER_union 0x8dd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_union instead.") -#define CLUTTER_logicaland 0x8de CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_logicaland instead.") -#define CLUTTER_logicalor 0x8df CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_logicalor instead.") -#define CLUTTER_partialderivative 0x8ef CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_partialderivative instead.") -#define CLUTTER_function 0x8f6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_function instead.") -#define CLUTTER_leftarrow 0x8fb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_leftarrow instead.") -#define CLUTTER_uparrow 0x8fc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_uparrow instead.") -#define CLUTTER_rightarrow 0x8fd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_rightarrow instead.") -#define CLUTTER_downarrow 0x8fe CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_downarrow instead.") -#define CLUTTER_blank 0x9df CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_blank instead.") -#define CLUTTER_soliddiamond 0x9e0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_soliddiamond instead.") -#define CLUTTER_checkerboard 0x9e1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_checkerboard instead.") -#define CLUTTER_ht 0x9e2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ht instead.") -#define CLUTTER_ff 0x9e3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ff instead.") -#define CLUTTER_cr 0x9e4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_cr instead.") -#define CLUTTER_lf 0x9e5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_lf instead.") -#define CLUTTER_nl 0x9e8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_nl instead.") -#define CLUTTER_vt 0x9e9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_vt instead.") -#define CLUTTER_lowrightcorner 0x9ea CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_lowrightcorner instead.") -#define CLUTTER_uprightcorner 0x9eb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_uprightcorner instead.") -#define CLUTTER_upleftcorner 0x9ec CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_upleftcorner instead.") -#define CLUTTER_lowleftcorner 0x9ed CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_lowleftcorner instead.") -#define CLUTTER_crossinglines 0x9ee CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_crossinglines instead.") -#define CLUTTER_horizlinescan1 0x9ef CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_horizlinescan1 instead.") -#define CLUTTER_horizlinescan3 0x9f0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_horizlinescan3 instead.") -#define CLUTTER_horizlinescan5 0x9f1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_horizlinescan5 instead.") -#define CLUTTER_horizlinescan7 0x9f2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_horizlinescan7 instead.") -#define CLUTTER_horizlinescan9 0x9f3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_horizlinescan9 instead.") -#define CLUTTER_leftt 0x9f4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_leftt instead.") -#define CLUTTER_rightt 0x9f5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_rightt instead.") -#define CLUTTER_bott 0x9f6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_bott instead.") -#define CLUTTER_topt 0x9f7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_topt instead.") -#define CLUTTER_vertbar 0x9f8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_vertbar instead.") -#define CLUTTER_emspace 0xaa1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_emspace instead.") -#define CLUTTER_enspace 0xaa2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_enspace instead.") -#define CLUTTER_em3space 0xaa3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_em3space instead.") -#define CLUTTER_em4space 0xaa4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_em4space instead.") -#define CLUTTER_digitspace 0xaa5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_digitspace instead.") -#define CLUTTER_punctspace 0xaa6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_punctspace instead.") -#define CLUTTER_thinspace 0xaa7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_thinspace instead.") -#define CLUTTER_hairspace 0xaa8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hairspace instead.") -#define CLUTTER_emdash 0xaa9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_emdash instead.") -#define CLUTTER_endash 0xaaa CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_endash instead.") -#define CLUTTER_signifblank 0xaac CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_signifblank instead.") -#define CLUTTER_ellipsis 0xaae CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ellipsis instead.") -#define CLUTTER_doubbaselinedot 0xaaf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_doubbaselinedot instead.") -#define CLUTTER_onethird 0xab0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_onethird instead.") -#define CLUTTER_twothirds 0xab1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_twothirds instead.") -#define CLUTTER_onefifth 0xab2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_onefifth instead.") -#define CLUTTER_twofifths 0xab3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_twofifths instead.") -#define CLUTTER_threefifths 0xab4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_threefifths instead.") -#define CLUTTER_fourfifths 0xab5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_fourfifths instead.") -#define CLUTTER_onesixth 0xab6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_onesixth instead.") -#define CLUTTER_fivesixths 0xab7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_fivesixths instead.") -#define CLUTTER_careof 0xab8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_careof instead.") -#define CLUTTER_figdash 0xabb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_figdash instead.") -#define CLUTTER_leftanglebracket 0xabc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_leftanglebracket instead.") -#define CLUTTER_decimalpoint 0xabd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_decimalpoint instead.") -#define CLUTTER_rightanglebracket 0xabe CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_rightanglebracket instead.") -#define CLUTTER_marker 0xabf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_marker instead.") -#define CLUTTER_oneeighth 0xac3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_oneeighth instead.") -#define CLUTTER_threeeighths 0xac4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_threeeighths instead.") -#define CLUTTER_fiveeighths 0xac5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_fiveeighths instead.") -#define CLUTTER_seveneighths 0xac6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_seveneighths instead.") -#define CLUTTER_trademark 0xac9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_trademark instead.") -#define CLUTTER_signaturemark 0xaca CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_signaturemark instead.") -#define CLUTTER_trademarkincircle 0xacb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_trademarkincircle instead.") -#define CLUTTER_leftopentriangle 0xacc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_leftopentriangle instead.") -#define CLUTTER_rightopentriangle 0xacd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_rightopentriangle instead.") -#define CLUTTER_emopencircle 0xace CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_emopencircle instead.") -#define CLUTTER_emopenrectangle 0xacf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_emopenrectangle instead.") -#define CLUTTER_leftsinglequotemark 0xad0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_leftsinglequotemark instead.") -#define CLUTTER_rightsinglequotemark 0xad1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_rightsinglequotemark instead.") -#define CLUTTER_leftdoublequotemark 0xad2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_leftdoublequotemark instead.") -#define CLUTTER_rightdoublequotemark 0xad3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_rightdoublequotemark instead.") -#define CLUTTER_prescription 0xad4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_prescription instead.") -#define CLUTTER_permille 0xad5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_permille instead.") -#define CLUTTER_minutes 0xad6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_minutes instead.") -#define CLUTTER_seconds 0xad7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_seconds instead.") -#define CLUTTER_latincross 0xad9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_latincross instead.") -#define CLUTTER_hexagram 0xada CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hexagram instead.") -#define CLUTTER_filledrectbullet 0xadb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_filledrectbullet instead.") -#define CLUTTER_filledlefttribullet 0xadc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_filledlefttribullet instead.") -#define CLUTTER_filledrighttribullet 0xadd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_filledrighttribullet instead.") -#define CLUTTER_emfilledcircle 0xade CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_emfilledcircle instead.") -#define CLUTTER_emfilledrect 0xadf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_emfilledrect instead.") -#define CLUTTER_enopencircbullet 0xae0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_enopencircbullet instead.") -#define CLUTTER_enopensquarebullet 0xae1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_enopensquarebullet instead.") -#define CLUTTER_openrectbullet 0xae2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_openrectbullet instead.") -#define CLUTTER_opentribulletup 0xae3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_opentribulletup instead.") -#define CLUTTER_opentribulletdown 0xae4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_opentribulletdown instead.") -#define CLUTTER_openstar 0xae5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_openstar instead.") -#define CLUTTER_enfilledcircbullet 0xae6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_enfilledcircbullet instead.") -#define CLUTTER_enfilledsqbullet 0xae7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_enfilledsqbullet instead.") -#define CLUTTER_filledtribulletup 0xae8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_filledtribulletup instead.") -#define CLUTTER_filledtribulletdown 0xae9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_filledtribulletdown instead.") -#define CLUTTER_leftpointer 0xaea CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_leftpointer instead.") -#define CLUTTER_rightpointer 0xaeb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_rightpointer instead.") -#define CLUTTER_club 0xaec CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_club instead.") -#define CLUTTER_diamond 0xaed CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_diamond instead.") -#define CLUTTER_heart 0xaee CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_heart instead.") -#define CLUTTER_maltesecross 0xaf0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_maltesecross instead.") -#define CLUTTER_dagger 0xaf1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dagger instead.") -#define CLUTTER_doubledagger 0xaf2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_doubledagger instead.") -#define CLUTTER_checkmark 0xaf3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_checkmark instead.") -#define CLUTTER_ballotcross 0xaf4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ballotcross instead.") -#define CLUTTER_musicalsharp 0xaf5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_musicalsharp instead.") -#define CLUTTER_musicalflat 0xaf6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_musicalflat instead.") -#define CLUTTER_malesymbol 0xaf7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_malesymbol instead.") -#define CLUTTER_femalesymbol 0xaf8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_femalesymbol instead.") -#define CLUTTER_telephone 0xaf9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_telephone instead.") -#define CLUTTER_telephonerecorder 0xafa CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_telephonerecorder instead.") -#define CLUTTER_phonographcopyright 0xafb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_phonographcopyright instead.") -#define CLUTTER_caret 0xafc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_caret instead.") -#define CLUTTER_singlelowquotemark 0xafd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_singlelowquotemark instead.") -#define CLUTTER_doublelowquotemark 0xafe CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_doublelowquotemark instead.") -#define CLUTTER_cursor 0xaff CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_cursor instead.") -#define CLUTTER_leftcaret 0xba3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_leftcaret instead.") -#define CLUTTER_rightcaret 0xba6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_rightcaret instead.") -#define CLUTTER_downcaret 0xba8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_downcaret instead.") -#define CLUTTER_upcaret 0xba9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_upcaret instead.") -#define CLUTTER_overbar 0xbc0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_overbar instead.") -#define CLUTTER_downtack 0xbc2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_downtack instead.") -#define CLUTTER_upshoe 0xbc3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_upshoe instead.") -#define CLUTTER_downstile 0xbc4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_downstile instead.") -#define CLUTTER_underbar 0xbc6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_underbar instead.") -#define CLUTTER_jot 0xbca CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_jot instead.") -#define CLUTTER_quad 0xbcc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_quad instead.") -#define CLUTTER_uptack 0xbce CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_uptack instead.") -#define CLUTTER_circle 0xbcf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_circle instead.") -#define CLUTTER_upstile 0xbd3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_upstile instead.") -#define CLUTTER_downshoe 0xbd6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_downshoe instead.") -#define CLUTTER_rightshoe 0xbd8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_rightshoe instead.") -#define CLUTTER_leftshoe 0xbda CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_leftshoe instead.") -#define CLUTTER_lefttack 0xbdc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_lefttack instead.") -#define CLUTTER_righttack 0xbfc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_righttack instead.") -#define CLUTTER_hebrew_doublelowline 0xcdf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_doublelowline instead.") -#define CLUTTER_hebrew_aleph 0xce0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_aleph instead.") -#define CLUTTER_hebrew_bet 0xce1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_bet instead.") -#define CLUTTER_hebrew_beth 0xce1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_beth instead.") -#define CLUTTER_hebrew_gimel 0xce2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_gimel instead.") -#define CLUTTER_hebrew_gimmel 0xce2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_gimmel instead.") -#define CLUTTER_hebrew_dalet 0xce3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_dalet instead.") -#define CLUTTER_hebrew_daleth 0xce3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_daleth instead.") -#define CLUTTER_hebrew_he 0xce4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_he instead.") -#define CLUTTER_hebrew_waw 0xce5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_waw instead.") -#define CLUTTER_hebrew_zain 0xce6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_zain instead.") -#define CLUTTER_hebrew_zayin 0xce6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_zayin instead.") -#define CLUTTER_hebrew_chet 0xce7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_chet instead.") -#define CLUTTER_hebrew_het 0xce7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_het instead.") -#define CLUTTER_hebrew_tet 0xce8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_tet instead.") -#define CLUTTER_hebrew_teth 0xce8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_teth instead.") -#define CLUTTER_hebrew_yod 0xce9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_yod instead.") -#define CLUTTER_hebrew_finalkaph 0xcea CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_finalkaph instead.") -#define CLUTTER_hebrew_kaph 0xceb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_kaph instead.") -#define CLUTTER_hebrew_lamed 0xcec CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_lamed instead.") -#define CLUTTER_hebrew_finalmem 0xced CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_finalmem instead.") -#define CLUTTER_hebrew_mem 0xcee CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_mem instead.") -#define CLUTTER_hebrew_finalnun 0xcef CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_finalnun instead.") -#define CLUTTER_hebrew_nun 0xcf0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_nun instead.") -#define CLUTTER_hebrew_samech 0xcf1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_samech instead.") -#define CLUTTER_hebrew_samekh 0xcf1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_samekh instead.") -#define CLUTTER_hebrew_ayin 0xcf2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_ayin instead.") -#define CLUTTER_hebrew_finalpe 0xcf3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_finalpe instead.") -#define CLUTTER_hebrew_pe 0xcf4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_pe instead.") -#define CLUTTER_hebrew_finalzade 0xcf5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_finalzade instead.") -#define CLUTTER_hebrew_finalzadi 0xcf5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_finalzadi instead.") -#define CLUTTER_hebrew_zade 0xcf6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_zade instead.") -#define CLUTTER_hebrew_zadi 0xcf6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_zadi instead.") -#define CLUTTER_hebrew_qoph 0xcf7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_qoph instead.") -#define CLUTTER_hebrew_kuf 0xcf7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_kuf instead.") -#define CLUTTER_hebrew_resh 0xcf8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_resh instead.") -#define CLUTTER_hebrew_shin 0xcf9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_shin instead.") -#define CLUTTER_hebrew_taw 0xcfa CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_taw instead.") -#define CLUTTER_hebrew_taf 0xcfa CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_hebrew_taf instead.") -#define CLUTTER_Hebrew_switch 0xff7e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hebrew_switch instead.") -#define CLUTTER_Thai_kokai 0xda1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_kokai instead.") -#define CLUTTER_Thai_khokhai 0xda2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_khokhai instead.") -#define CLUTTER_Thai_khokhuat 0xda3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_khokhuat instead.") -#define CLUTTER_Thai_khokhwai 0xda4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_khokhwai instead.") -#define CLUTTER_Thai_khokhon 0xda5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_khokhon instead.") -#define CLUTTER_Thai_khorakhang 0xda6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_khorakhang instead.") -#define CLUTTER_Thai_ngongu 0xda7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_ngongu instead.") -#define CLUTTER_Thai_chochan 0xda8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_chochan instead.") -#define CLUTTER_Thai_choching 0xda9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_choching instead.") -#define CLUTTER_Thai_chochang 0xdaa CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_chochang instead.") -#define CLUTTER_Thai_soso 0xdab CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_soso instead.") -#define CLUTTER_Thai_chochoe 0xdac CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_chochoe instead.") -#define CLUTTER_Thai_yoying 0xdad CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_yoying instead.") -#define CLUTTER_Thai_dochada 0xdae CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_dochada instead.") -#define CLUTTER_Thai_topatak 0xdaf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_topatak instead.") -#define CLUTTER_Thai_thothan 0xdb0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_thothan instead.") -#define CLUTTER_Thai_thonangmontho 0xdb1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_thonangmontho instead.") -#define CLUTTER_Thai_thophuthao 0xdb2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_thophuthao instead.") -#define CLUTTER_Thai_nonen 0xdb3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_nonen instead.") -#define CLUTTER_Thai_dodek 0xdb4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_dodek instead.") -#define CLUTTER_Thai_totao 0xdb5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_totao instead.") -#define CLUTTER_Thai_thothung 0xdb6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_thothung instead.") -#define CLUTTER_Thai_thothahan 0xdb7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_thothahan instead.") -#define CLUTTER_Thai_thothong 0xdb8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_thothong instead.") -#define CLUTTER_Thai_nonu 0xdb9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_nonu instead.") -#define CLUTTER_Thai_bobaimai 0xdba CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_bobaimai instead.") -#define CLUTTER_Thai_popla 0xdbb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_popla instead.") -#define CLUTTER_Thai_phophung 0xdbc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_phophung instead.") -#define CLUTTER_Thai_fofa 0xdbd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_fofa instead.") -#define CLUTTER_Thai_phophan 0xdbe CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_phophan instead.") -#define CLUTTER_Thai_fofan 0xdbf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_fofan instead.") -#define CLUTTER_Thai_phosamphao 0xdc0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_phosamphao instead.") -#define CLUTTER_Thai_moma 0xdc1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_moma instead.") -#define CLUTTER_Thai_yoyak 0xdc2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_yoyak instead.") -#define CLUTTER_Thai_rorua 0xdc3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_rorua instead.") -#define CLUTTER_Thai_ru 0xdc4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_ru instead.") -#define CLUTTER_Thai_loling 0xdc5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_loling instead.") -#define CLUTTER_Thai_lu 0xdc6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_lu instead.") -#define CLUTTER_Thai_wowaen 0xdc7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_wowaen instead.") -#define CLUTTER_Thai_sosala 0xdc8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_sosala instead.") -#define CLUTTER_Thai_sorusi 0xdc9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_sorusi instead.") -#define CLUTTER_Thai_sosua 0xdca CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_sosua instead.") -#define CLUTTER_Thai_hohip 0xdcb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_hohip instead.") -#define CLUTTER_Thai_lochula 0xdcc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_lochula instead.") -#define CLUTTER_Thai_oang 0xdcd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_oang instead.") -#define CLUTTER_Thai_honokhuk 0xdce CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_honokhuk instead.") -#define CLUTTER_Thai_paiyannoi 0xdcf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_paiyannoi instead.") -#define CLUTTER_Thai_saraa 0xdd0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_saraa instead.") -#define CLUTTER_Thai_maihanakat 0xdd1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_maihanakat instead.") -#define CLUTTER_Thai_saraaa 0xdd2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_saraaa instead.") -#define CLUTTER_Thai_saraam 0xdd3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_saraam instead.") -#define CLUTTER_Thai_sarai 0xdd4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_sarai instead.") -#define CLUTTER_Thai_saraii 0xdd5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_saraii instead.") -#define CLUTTER_Thai_saraue 0xdd6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_saraue instead.") -#define CLUTTER_Thai_sarauee 0xdd7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_sarauee instead.") -#define CLUTTER_Thai_sarau 0xdd8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_sarau instead.") -#define CLUTTER_Thai_sarauu 0xdd9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_sarauu instead.") -#define CLUTTER_Thai_phinthu 0xdda CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_phinthu instead.") -#define CLUTTER_Thai_maihanakat_maitho 0xdde CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_maihanakat_maitho instead.") -#define CLUTTER_Thai_baht 0xddf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_baht instead.") -#define CLUTTER_Thai_sarae 0xde0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_sarae instead.") -#define CLUTTER_Thai_saraae 0xde1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_saraae instead.") -#define CLUTTER_Thai_sarao 0xde2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_sarao instead.") -#define CLUTTER_Thai_saraaimaimuan 0xde3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_saraaimaimuan instead.") -#define CLUTTER_Thai_saraaimaimalai 0xde4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_saraaimaimalai instead.") -#define CLUTTER_Thai_lakkhangyao 0xde5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_lakkhangyao instead.") -#define CLUTTER_Thai_maiyamok 0xde6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_maiyamok instead.") -#define CLUTTER_Thai_maitaikhu 0xde7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_maitaikhu instead.") -#define CLUTTER_Thai_maiek 0xde8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_maiek instead.") -#define CLUTTER_Thai_maitho 0xde9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_maitho instead.") -#define CLUTTER_Thai_maitri 0xdea CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_maitri instead.") -#define CLUTTER_Thai_maichattawa 0xdeb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_maichattawa instead.") -#define CLUTTER_Thai_thanthakhat 0xdec CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_thanthakhat instead.") -#define CLUTTER_Thai_nikhahit 0xded CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_nikhahit instead.") -#define CLUTTER_Thai_leksun 0xdf0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_leksun instead.") -#define CLUTTER_Thai_leknung 0xdf1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_leknung instead.") -#define CLUTTER_Thai_leksong 0xdf2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_leksong instead.") -#define CLUTTER_Thai_leksam 0xdf3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_leksam instead.") -#define CLUTTER_Thai_leksi 0xdf4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_leksi instead.") -#define CLUTTER_Thai_lekha 0xdf5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_lekha instead.") -#define CLUTTER_Thai_lekhok 0xdf6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_lekhok instead.") -#define CLUTTER_Thai_lekchet 0xdf7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_lekchet instead.") -#define CLUTTER_Thai_lekpaet 0xdf8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_lekpaet instead.") -#define CLUTTER_Thai_lekkao 0xdf9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Thai_lekkao instead.") -#define CLUTTER_Hangul 0xff31 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul instead.") -#define CLUTTER_Hangul_Start 0xff32 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_Start instead.") -#define CLUTTER_Hangul_End 0xff33 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_End instead.") -#define CLUTTER_Hangul_Hanja 0xff34 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_Hanja instead.") -#define CLUTTER_Hangul_Jamo 0xff35 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_Jamo instead.") -#define CLUTTER_Hangul_Romaja 0xff36 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_Romaja instead.") -#define CLUTTER_Hangul_Codeinput 0xff37 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_Codeinput instead.") -#define CLUTTER_Hangul_Jeonja 0xff38 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_Jeonja instead.") -#define CLUTTER_Hangul_Banja 0xff39 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_Banja instead.") -#define CLUTTER_Hangul_PreHanja 0xff3a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_PreHanja instead.") -#define CLUTTER_Hangul_PostHanja 0xff3b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_PostHanja instead.") -#define CLUTTER_Hangul_SingleCandidate 0xff3c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_SingleCandidate instead.") -#define CLUTTER_Hangul_MultipleCandidate 0xff3d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_MultipleCandidate instead.") -#define CLUTTER_Hangul_PreviousCandidate 0xff3e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_PreviousCandidate instead.") -#define CLUTTER_Hangul_Special 0xff3f CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_Special instead.") -#define CLUTTER_Hangul_switch 0xff7e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_switch instead.") -#define CLUTTER_Hangul_Kiyeog 0xea1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_Kiyeog instead.") -#define CLUTTER_Hangul_SsangKiyeog 0xea2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_SsangKiyeog instead.") -#define CLUTTER_Hangul_KiyeogSios 0xea3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_KiyeogSios instead.") -#define CLUTTER_Hangul_Nieun 0xea4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_Nieun instead.") -#define CLUTTER_Hangul_NieunJieuj 0xea5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_NieunJieuj instead.") -#define CLUTTER_Hangul_NieunHieuh 0xea6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_NieunHieuh instead.") -#define CLUTTER_Hangul_Dikeud 0xea7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_Dikeud instead.") -#define CLUTTER_Hangul_SsangDikeud 0xea8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_SsangDikeud instead.") -#define CLUTTER_Hangul_Rieul 0xea9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_Rieul instead.") -#define CLUTTER_Hangul_RieulKiyeog 0xeaa CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_RieulKiyeog instead.") -#define CLUTTER_Hangul_RieulMieum 0xeab CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_RieulMieum instead.") -#define CLUTTER_Hangul_RieulPieub 0xeac CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_RieulPieub instead.") -#define CLUTTER_Hangul_RieulSios 0xead CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_RieulSios instead.") -#define CLUTTER_Hangul_RieulTieut 0xeae CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_RieulTieut instead.") -#define CLUTTER_Hangul_RieulPhieuf 0xeaf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_RieulPhieuf instead.") -#define CLUTTER_Hangul_RieulHieuh 0xeb0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_RieulHieuh instead.") -#define CLUTTER_Hangul_Mieum 0xeb1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_Mieum instead.") -#define CLUTTER_Hangul_Pieub 0xeb2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_Pieub instead.") -#define CLUTTER_Hangul_SsangPieub 0xeb3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_SsangPieub instead.") -#define CLUTTER_Hangul_PieubSios 0xeb4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_PieubSios instead.") -#define CLUTTER_Hangul_Sios 0xeb5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_Sios instead.") -#define CLUTTER_Hangul_SsangSios 0xeb6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_SsangSios instead.") -#define CLUTTER_Hangul_Ieung 0xeb7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_Ieung instead.") -#define CLUTTER_Hangul_Jieuj 0xeb8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_Jieuj instead.") -#define CLUTTER_Hangul_SsangJieuj 0xeb9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_SsangJieuj instead.") -#define CLUTTER_Hangul_Cieuc 0xeba CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_Cieuc instead.") -#define CLUTTER_Hangul_Khieuq 0xebb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_Khieuq instead.") -#define CLUTTER_Hangul_Tieut 0xebc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_Tieut instead.") -#define CLUTTER_Hangul_Phieuf 0xebd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_Phieuf instead.") -#define CLUTTER_Hangul_Hieuh 0xebe CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_Hieuh instead.") -#define CLUTTER_Hangul_A 0xebf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_A instead.") -#define CLUTTER_Hangul_AE 0xec0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_AE instead.") -#define CLUTTER_Hangul_YA 0xec1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_YA instead.") -#define CLUTTER_Hangul_YAE 0xec2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_YAE instead.") -#define CLUTTER_Hangul_EO 0xec3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_EO instead.") -#define CLUTTER_Hangul_E 0xec4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_E instead.") -#define CLUTTER_Hangul_YEO 0xec5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_YEO instead.") -#define CLUTTER_Hangul_YE 0xec6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_YE instead.") -#define CLUTTER_Hangul_O 0xec7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_O instead.") -#define CLUTTER_Hangul_WA 0xec8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_WA instead.") -#define CLUTTER_Hangul_WAE 0xec9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_WAE instead.") -#define CLUTTER_Hangul_OE 0xeca CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_OE instead.") -#define CLUTTER_Hangul_YO 0xecb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_YO instead.") -#define CLUTTER_Hangul_U 0xecc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_U instead.") -#define CLUTTER_Hangul_WEO 0xecd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_WEO instead.") -#define CLUTTER_Hangul_WE 0xece CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_WE instead.") -#define CLUTTER_Hangul_WI 0xecf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_WI instead.") -#define CLUTTER_Hangul_YU 0xed0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_YU instead.") -#define CLUTTER_Hangul_EU 0xed1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_EU instead.") -#define CLUTTER_Hangul_YI 0xed2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_YI instead.") -#define CLUTTER_Hangul_I 0xed3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_I instead.") -#define CLUTTER_Hangul_J_Kiyeog 0xed4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_J_Kiyeog instead.") -#define CLUTTER_Hangul_J_SsangKiyeog 0xed5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_J_SsangKiyeog instead.") -#define CLUTTER_Hangul_J_KiyeogSios 0xed6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_J_KiyeogSios instead.") -#define CLUTTER_Hangul_J_Nieun 0xed7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_J_Nieun instead.") -#define CLUTTER_Hangul_J_NieunJieuj 0xed8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_J_NieunJieuj instead.") -#define CLUTTER_Hangul_J_NieunHieuh 0xed9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_J_NieunHieuh instead.") -#define CLUTTER_Hangul_J_Dikeud 0xeda CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_J_Dikeud instead.") -#define CLUTTER_Hangul_J_Rieul 0xedb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_J_Rieul instead.") -#define CLUTTER_Hangul_J_RieulKiyeog 0xedc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_J_RieulKiyeog instead.") -#define CLUTTER_Hangul_J_RieulMieum 0xedd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_J_RieulMieum instead.") -#define CLUTTER_Hangul_J_RieulPieub 0xede CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_J_RieulPieub instead.") -#define CLUTTER_Hangul_J_RieulSios 0xedf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_J_RieulSios instead.") -#define CLUTTER_Hangul_J_RieulTieut 0xee0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_J_RieulTieut instead.") -#define CLUTTER_Hangul_J_RieulPhieuf 0xee1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_J_RieulPhieuf instead.") -#define CLUTTER_Hangul_J_RieulHieuh 0xee2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_J_RieulHieuh instead.") -#define CLUTTER_Hangul_J_Mieum 0xee3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_J_Mieum instead.") -#define CLUTTER_Hangul_J_Pieub 0xee4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_J_Pieub instead.") -#define CLUTTER_Hangul_J_PieubSios 0xee5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_J_PieubSios instead.") -#define CLUTTER_Hangul_J_Sios 0xee6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_J_Sios instead.") -#define CLUTTER_Hangul_J_SsangSios 0xee7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_J_SsangSios instead.") -#define CLUTTER_Hangul_J_Ieung 0xee8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_J_Ieung instead.") -#define CLUTTER_Hangul_J_Jieuj 0xee9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_J_Jieuj instead.") -#define CLUTTER_Hangul_J_Cieuc 0xeea CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_J_Cieuc instead.") -#define CLUTTER_Hangul_J_Khieuq 0xeeb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_J_Khieuq instead.") -#define CLUTTER_Hangul_J_Tieut 0xeec CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_J_Tieut instead.") -#define CLUTTER_Hangul_J_Phieuf 0xeed CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_J_Phieuf instead.") -#define CLUTTER_Hangul_J_Hieuh 0xeee CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_J_Hieuh instead.") -#define CLUTTER_Hangul_RieulYeorinHieuh 0xeef CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_RieulYeorinHieuh instead.") -#define CLUTTER_Hangul_SunkyeongeumMieum 0xef0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_SunkyeongeumMieum instead.") -#define CLUTTER_Hangul_SunkyeongeumPieub 0xef1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_SunkyeongeumPieub instead.") -#define CLUTTER_Hangul_PanSios 0xef2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_PanSios instead.") -#define CLUTTER_Hangul_KkogjiDalrinIeung 0xef3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_KkogjiDalrinIeung instead.") -#define CLUTTER_Hangul_SunkyeongeumPhieuf 0xef4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_SunkyeongeumPhieuf instead.") -#define CLUTTER_Hangul_YeorinHieuh 0xef5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_YeorinHieuh instead.") -#define CLUTTER_Hangul_AraeA 0xef6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_AraeA instead.") -#define CLUTTER_Hangul_AraeAE 0xef7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_AraeAE instead.") -#define CLUTTER_Hangul_J_PanSios 0xef8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_J_PanSios instead.") -#define CLUTTER_Hangul_J_KkogjiDalrinIeung 0xef9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_J_KkogjiDalrinIeung instead.") -#define CLUTTER_Hangul_J_YeorinHieuh 0xefa CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Hangul_J_YeorinHieuh instead.") -#define CLUTTER_Korean_Won 0xeff CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Korean_Won instead.") -#define CLUTTER_Armenian_ligature_ew 0x1000587 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_ligature_ew instead.") -#define CLUTTER_Armenian_full_stop 0x1000589 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_full_stop instead.") -#define CLUTTER_Armenian_verjaket 0x1000589 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_verjaket instead.") -#define CLUTTER_Armenian_separation_mark 0x100055d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_separation_mark instead.") -#define CLUTTER_Armenian_but 0x100055d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_but instead.") -#define CLUTTER_Armenian_hyphen 0x100058a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_hyphen instead.") -#define CLUTTER_Armenian_yentamna 0x100058a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_yentamna instead.") -#define CLUTTER_Armenian_exclam 0x100055c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_exclam instead.") -#define CLUTTER_Armenian_amanak 0x100055c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_amanak instead.") -#define CLUTTER_Armenian_accent 0x100055b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_accent instead.") -#define CLUTTER_Armenian_shesht 0x100055b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_shesht instead.") -#define CLUTTER_Armenian_question 0x100055e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_question instead.") -#define CLUTTER_Armenian_paruyk 0x100055e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_paruyk instead.") -#define CLUTTER_Armenian_AYB 0x1000531 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_AYB instead.") -#define CLUTTER_Armenian_ayb 0x1000561 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_ayb instead.") -#define CLUTTER_Armenian_BEN 0x1000532 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_BEN instead.") -#define CLUTTER_Armenian_ben 0x1000562 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_ben instead.") -#define CLUTTER_Armenian_GIM 0x1000533 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_GIM instead.") -#define CLUTTER_Armenian_gim 0x1000563 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_gim instead.") -#define CLUTTER_Armenian_DA 0x1000534 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_DA instead.") -#define CLUTTER_Armenian_da 0x1000564 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_da instead.") -#define CLUTTER_Armenian_YECH 0x1000535 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_YECH instead.") -#define CLUTTER_Armenian_yech 0x1000565 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_yech instead.") -#define CLUTTER_Armenian_ZA 0x1000536 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_ZA instead.") -#define CLUTTER_Armenian_za 0x1000566 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_za instead.") -#define CLUTTER_Armenian_E 0x1000537 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_E instead.") -#define CLUTTER_Armenian_e 0x1000567 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_e instead.") -#define CLUTTER_Armenian_AT 0x1000538 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_AT instead.") -#define CLUTTER_Armenian_at 0x1000568 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_at instead.") -#define CLUTTER_Armenian_TO 0x1000539 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_TO instead.") -#define CLUTTER_Armenian_to 0x1000569 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_to instead.") -#define CLUTTER_Armenian_ZHE 0x100053a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_ZHE instead.") -#define CLUTTER_Armenian_zhe 0x100056a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_zhe instead.") -#define CLUTTER_Armenian_INI 0x100053b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_INI instead.") -#define CLUTTER_Armenian_ini 0x100056b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_ini instead.") -#define CLUTTER_Armenian_LYUN 0x100053c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_LYUN instead.") -#define CLUTTER_Armenian_lyun 0x100056c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_lyun instead.") -#define CLUTTER_Armenian_KHE 0x100053d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_KHE instead.") -#define CLUTTER_Armenian_khe 0x100056d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_khe instead.") -#define CLUTTER_Armenian_TSA 0x100053e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_TSA instead.") -#define CLUTTER_Armenian_tsa 0x100056e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_tsa instead.") -#define CLUTTER_Armenian_KEN 0x100053f CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_KEN instead.") -#define CLUTTER_Armenian_ken 0x100056f CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_ken instead.") -#define CLUTTER_Armenian_HO 0x1000540 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_HO instead.") -#define CLUTTER_Armenian_ho 0x1000570 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_ho instead.") -#define CLUTTER_Armenian_DZA 0x1000541 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_DZA instead.") -#define CLUTTER_Armenian_dza 0x1000571 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_dza instead.") -#define CLUTTER_Armenian_GHAT 0x1000542 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_GHAT instead.") -#define CLUTTER_Armenian_ghat 0x1000572 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_ghat instead.") -#define CLUTTER_Armenian_TCHE 0x1000543 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_TCHE instead.") -#define CLUTTER_Armenian_tche 0x1000573 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_tche instead.") -#define CLUTTER_Armenian_MEN 0x1000544 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_MEN instead.") -#define CLUTTER_Armenian_men 0x1000574 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_men instead.") -#define CLUTTER_Armenian_HI 0x1000545 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_HI instead.") -#define CLUTTER_Armenian_hi 0x1000575 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_hi instead.") -#define CLUTTER_Armenian_NU 0x1000546 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_NU instead.") -#define CLUTTER_Armenian_nu 0x1000576 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_nu instead.") -#define CLUTTER_Armenian_SHA 0x1000547 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_SHA instead.") -#define CLUTTER_Armenian_sha 0x1000577 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_sha instead.") -#define CLUTTER_Armenian_VO 0x1000548 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_VO instead.") -#define CLUTTER_Armenian_vo 0x1000578 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_vo instead.") -#define CLUTTER_Armenian_CHA 0x1000549 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_CHA instead.") -#define CLUTTER_Armenian_cha 0x1000579 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_cha instead.") -#define CLUTTER_Armenian_PE 0x100054a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_PE instead.") -#define CLUTTER_Armenian_pe 0x100057a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_pe instead.") -#define CLUTTER_Armenian_JE 0x100054b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_JE instead.") -#define CLUTTER_Armenian_je 0x100057b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_je instead.") -#define CLUTTER_Armenian_RA 0x100054c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_RA instead.") -#define CLUTTER_Armenian_ra 0x100057c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_ra instead.") -#define CLUTTER_Armenian_SE 0x100054d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_SE instead.") -#define CLUTTER_Armenian_se 0x100057d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_se instead.") -#define CLUTTER_Armenian_VEV 0x100054e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_VEV instead.") -#define CLUTTER_Armenian_vev 0x100057e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_vev instead.") -#define CLUTTER_Armenian_TYUN 0x100054f CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_TYUN instead.") -#define CLUTTER_Armenian_tyun 0x100057f CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_tyun instead.") -#define CLUTTER_Armenian_RE 0x1000550 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_RE instead.") -#define CLUTTER_Armenian_re 0x1000580 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_re instead.") -#define CLUTTER_Armenian_TSO 0x1000551 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_TSO instead.") -#define CLUTTER_Armenian_tso 0x1000581 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_tso instead.") -#define CLUTTER_Armenian_VYUN 0x1000552 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_VYUN instead.") -#define CLUTTER_Armenian_vyun 0x1000582 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_vyun instead.") -#define CLUTTER_Armenian_PYUR 0x1000553 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_PYUR instead.") -#define CLUTTER_Armenian_pyur 0x1000583 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_pyur instead.") -#define CLUTTER_Armenian_KE 0x1000554 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_KE instead.") -#define CLUTTER_Armenian_ke 0x1000584 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_ke instead.") -#define CLUTTER_Armenian_O 0x1000555 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_O instead.") -#define CLUTTER_Armenian_o 0x1000585 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_o instead.") -#define CLUTTER_Armenian_FE 0x1000556 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_FE instead.") -#define CLUTTER_Armenian_fe 0x1000586 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_fe instead.") -#define CLUTTER_Armenian_apostrophe 0x100055a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Armenian_apostrophe instead.") -#define CLUTTER_Georgian_an 0x10010d0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_an instead.") -#define CLUTTER_Georgian_ban 0x10010d1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_ban instead.") -#define CLUTTER_Georgian_gan 0x10010d2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_gan instead.") -#define CLUTTER_Georgian_don 0x10010d3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_don instead.") -#define CLUTTER_Georgian_en 0x10010d4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_en instead.") -#define CLUTTER_Georgian_vin 0x10010d5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_vin instead.") -#define CLUTTER_Georgian_zen 0x10010d6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_zen instead.") -#define CLUTTER_Georgian_tan 0x10010d7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_tan instead.") -#define CLUTTER_Georgian_in 0x10010d8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_in instead.") -#define CLUTTER_Georgian_kan 0x10010d9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_kan instead.") -#define CLUTTER_Georgian_las 0x10010da CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_las instead.") -#define CLUTTER_Georgian_man 0x10010db CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_man instead.") -#define CLUTTER_Georgian_nar 0x10010dc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_nar instead.") -#define CLUTTER_Georgian_on 0x10010dd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_on instead.") -#define CLUTTER_Georgian_par 0x10010de CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_par instead.") -#define CLUTTER_Georgian_zhar 0x10010df CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_zhar instead.") -#define CLUTTER_Georgian_rae 0x10010e0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_rae instead.") -#define CLUTTER_Georgian_san 0x10010e1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_san instead.") -#define CLUTTER_Georgian_tar 0x10010e2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_tar instead.") -#define CLUTTER_Georgian_un 0x10010e3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_un instead.") -#define CLUTTER_Georgian_phar 0x10010e4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_phar instead.") -#define CLUTTER_Georgian_khar 0x10010e5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_khar instead.") -#define CLUTTER_Georgian_ghan 0x10010e6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_ghan instead.") -#define CLUTTER_Georgian_qar 0x10010e7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_qar instead.") -#define CLUTTER_Georgian_shin 0x10010e8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_shin instead.") -#define CLUTTER_Georgian_chin 0x10010e9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_chin instead.") -#define CLUTTER_Georgian_can 0x10010ea CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_can instead.") -#define CLUTTER_Georgian_jil 0x10010eb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_jil instead.") -#define CLUTTER_Georgian_cil 0x10010ec CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_cil instead.") -#define CLUTTER_Georgian_char 0x10010ed CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_char instead.") -#define CLUTTER_Georgian_xan 0x10010ee CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_xan instead.") -#define CLUTTER_Georgian_jhan 0x10010ef CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_jhan instead.") -#define CLUTTER_Georgian_hae 0x10010f0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_hae instead.") -#define CLUTTER_Georgian_he 0x10010f1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_he instead.") -#define CLUTTER_Georgian_hie 0x10010f2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_hie instead.") -#define CLUTTER_Georgian_we 0x10010f3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_we instead.") -#define CLUTTER_Georgian_har 0x10010f4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_har instead.") -#define CLUTTER_Georgian_hoe 0x10010f5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_hoe instead.") -#define CLUTTER_Georgian_fi 0x10010f6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Georgian_fi instead.") -#define CLUTTER_Xabovedot 0x1001e8a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Xabovedot instead.") -#define CLUTTER_Ibreve 0x100012c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ibreve instead.") -#define CLUTTER_Zstroke 0x10001b5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Zstroke instead.") -#define CLUTTER_Gcaron 0x10001e6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Gcaron instead.") -#define CLUTTER_Ocaron 0x10001d1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ocaron instead.") -#define CLUTTER_Obarred 0x100019f CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Obarred instead.") -#define CLUTTER_xabovedot 0x1001e8b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_xabovedot instead.") -#define CLUTTER_ibreve 0x100012d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ibreve instead.") -#define CLUTTER_zstroke 0x10001b6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_zstroke instead.") -#define CLUTTER_gcaron 0x10001e7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_gcaron instead.") -#define CLUTTER_ocaron 0x10001d2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ocaron instead.") -#define CLUTTER_obarred 0x1000275 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_obarred instead.") -#define CLUTTER_SCHWA 0x100018f CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_SCHWA instead.") -#define CLUTTER_schwa 0x1000259 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_schwa instead.") -#define CLUTTER_EZH 0x10001b7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_EZH instead.") -#define CLUTTER_ezh 0x1000292 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ezh instead.") -#define CLUTTER_Lbelowdot 0x1001e36 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Lbelowdot instead.") -#define CLUTTER_lbelowdot 0x1001e37 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_lbelowdot instead.") -#define CLUTTER_Abelowdot 0x1001ea0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Abelowdot instead.") -#define CLUTTER_abelowdot 0x1001ea1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_abelowdot instead.") -#define CLUTTER_Ahook 0x1001ea2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ahook instead.") -#define CLUTTER_ahook 0x1001ea3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ahook instead.") -#define CLUTTER_Acircumflexacute 0x1001ea4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Acircumflexacute instead.") -#define CLUTTER_acircumflexacute 0x1001ea5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_acircumflexacute instead.") -#define CLUTTER_Acircumflexgrave 0x1001ea6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Acircumflexgrave instead.") -#define CLUTTER_acircumflexgrave 0x1001ea7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_acircumflexgrave instead.") -#define CLUTTER_Acircumflexhook 0x1001ea8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Acircumflexhook instead.") -#define CLUTTER_acircumflexhook 0x1001ea9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_acircumflexhook instead.") -#define CLUTTER_Acircumflextilde 0x1001eaa CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Acircumflextilde instead.") -#define CLUTTER_acircumflextilde 0x1001eab CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_acircumflextilde instead.") -#define CLUTTER_Acircumflexbelowdot 0x1001eac CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Acircumflexbelowdot instead.") -#define CLUTTER_acircumflexbelowdot 0x1001ead CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_acircumflexbelowdot instead.") -#define CLUTTER_Abreveacute 0x1001eae CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Abreveacute instead.") -#define CLUTTER_abreveacute 0x1001eaf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_abreveacute instead.") -#define CLUTTER_Abrevegrave 0x1001eb0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Abrevegrave instead.") -#define CLUTTER_abrevegrave 0x1001eb1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_abrevegrave instead.") -#define CLUTTER_Abrevehook 0x1001eb2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Abrevehook instead.") -#define CLUTTER_abrevehook 0x1001eb3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_abrevehook instead.") -#define CLUTTER_Abrevetilde 0x1001eb4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Abrevetilde instead.") -#define CLUTTER_abrevetilde 0x1001eb5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_abrevetilde instead.") -#define CLUTTER_Abrevebelowdot 0x1001eb6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Abrevebelowdot instead.") -#define CLUTTER_abrevebelowdot 0x1001eb7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_abrevebelowdot instead.") -#define CLUTTER_Ebelowdot 0x1001eb8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ebelowdot instead.") -#define CLUTTER_ebelowdot 0x1001eb9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ebelowdot instead.") -#define CLUTTER_Ehook 0x1001eba CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ehook instead.") -#define CLUTTER_ehook 0x1001ebb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ehook instead.") -#define CLUTTER_Etilde 0x1001ebc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Etilde instead.") -#define CLUTTER_etilde 0x1001ebd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_etilde instead.") -#define CLUTTER_Ecircumflexacute 0x1001ebe CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ecircumflexacute instead.") -#define CLUTTER_ecircumflexacute 0x1001ebf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ecircumflexacute instead.") -#define CLUTTER_Ecircumflexgrave 0x1001ec0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ecircumflexgrave instead.") -#define CLUTTER_ecircumflexgrave 0x1001ec1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ecircumflexgrave instead.") -#define CLUTTER_Ecircumflexhook 0x1001ec2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ecircumflexhook instead.") -#define CLUTTER_ecircumflexhook 0x1001ec3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ecircumflexhook instead.") -#define CLUTTER_Ecircumflextilde 0x1001ec4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ecircumflextilde instead.") -#define CLUTTER_ecircumflextilde 0x1001ec5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ecircumflextilde instead.") -#define CLUTTER_Ecircumflexbelowdot 0x1001ec6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ecircumflexbelowdot instead.") -#define CLUTTER_ecircumflexbelowdot 0x1001ec7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ecircumflexbelowdot instead.") -#define CLUTTER_Ihook 0x1001ec8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ihook instead.") -#define CLUTTER_ihook 0x1001ec9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ihook instead.") -#define CLUTTER_Ibelowdot 0x1001eca CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ibelowdot instead.") -#define CLUTTER_ibelowdot 0x1001ecb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ibelowdot instead.") -#define CLUTTER_Obelowdot 0x1001ecc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Obelowdot instead.") -#define CLUTTER_obelowdot 0x1001ecd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_obelowdot instead.") -#define CLUTTER_Ohook 0x1001ece CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ohook instead.") -#define CLUTTER_ohook 0x1001ecf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ohook instead.") -#define CLUTTER_Ocircumflexacute 0x1001ed0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ocircumflexacute instead.") -#define CLUTTER_ocircumflexacute 0x1001ed1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ocircumflexacute instead.") -#define CLUTTER_Ocircumflexgrave 0x1001ed2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ocircumflexgrave instead.") -#define CLUTTER_ocircumflexgrave 0x1001ed3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ocircumflexgrave instead.") -#define CLUTTER_Ocircumflexhook 0x1001ed4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ocircumflexhook instead.") -#define CLUTTER_ocircumflexhook 0x1001ed5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ocircumflexhook instead.") -#define CLUTTER_Ocircumflextilde 0x1001ed6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ocircumflextilde instead.") -#define CLUTTER_ocircumflextilde 0x1001ed7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ocircumflextilde instead.") -#define CLUTTER_Ocircumflexbelowdot 0x1001ed8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ocircumflexbelowdot instead.") -#define CLUTTER_ocircumflexbelowdot 0x1001ed9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ocircumflexbelowdot instead.") -#define CLUTTER_Ohornacute 0x1001eda CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ohornacute instead.") -#define CLUTTER_ohornacute 0x1001edb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ohornacute instead.") -#define CLUTTER_Ohorngrave 0x1001edc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ohorngrave instead.") -#define CLUTTER_ohorngrave 0x1001edd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ohorngrave instead.") -#define CLUTTER_Ohornhook 0x1001ede CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ohornhook instead.") -#define CLUTTER_ohornhook 0x1001edf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ohornhook instead.") -#define CLUTTER_Ohorntilde 0x1001ee0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ohorntilde instead.") -#define CLUTTER_ohorntilde 0x1001ee1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ohorntilde instead.") -#define CLUTTER_Ohornbelowdot 0x1001ee2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ohornbelowdot instead.") -#define CLUTTER_ohornbelowdot 0x1001ee3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ohornbelowdot instead.") -#define CLUTTER_Ubelowdot 0x1001ee4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ubelowdot instead.") -#define CLUTTER_ubelowdot 0x1001ee5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ubelowdot instead.") -#define CLUTTER_Uhook 0x1001ee6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Uhook instead.") -#define CLUTTER_uhook 0x1001ee7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_uhook instead.") -#define CLUTTER_Uhornacute 0x1001ee8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Uhornacute instead.") -#define CLUTTER_uhornacute 0x1001ee9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_uhornacute instead.") -#define CLUTTER_Uhorngrave 0x1001eea CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Uhorngrave instead.") -#define CLUTTER_uhorngrave 0x1001eeb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_uhorngrave instead.") -#define CLUTTER_Uhornhook 0x1001eec CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Uhornhook instead.") -#define CLUTTER_uhornhook 0x1001eed CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_uhornhook instead.") -#define CLUTTER_Uhorntilde 0x1001eee CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Uhorntilde instead.") -#define CLUTTER_uhorntilde 0x1001eef CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_uhorntilde instead.") -#define CLUTTER_Uhornbelowdot 0x1001ef0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Uhornbelowdot instead.") -#define CLUTTER_uhornbelowdot 0x1001ef1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_uhornbelowdot instead.") -#define CLUTTER_Ybelowdot 0x1001ef4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ybelowdot instead.") -#define CLUTTER_ybelowdot 0x1001ef5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ybelowdot instead.") -#define CLUTTER_Yhook 0x1001ef6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Yhook instead.") -#define CLUTTER_yhook 0x1001ef7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_yhook instead.") -#define CLUTTER_Ytilde 0x1001ef8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ytilde instead.") -#define CLUTTER_ytilde 0x1001ef9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ytilde instead.") -#define CLUTTER_Ohorn 0x10001a0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Ohorn instead.") -#define CLUTTER_ohorn 0x10001a1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ohorn instead.") -#define CLUTTER_Uhorn 0x10001af CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Uhorn instead.") -#define CLUTTER_uhorn 0x10001b0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_uhorn instead.") -#define CLUTTER_EcuSign 0x10020a0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_EcuSign instead.") -#define CLUTTER_ColonSign 0x10020a1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ColonSign instead.") -#define CLUTTER_CruzeiroSign 0x10020a2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_CruzeiroSign instead.") -#define CLUTTER_FFrancSign 0x10020a3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_FFrancSign instead.") -#define CLUTTER_LiraSign 0x10020a4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_LiraSign instead.") -#define CLUTTER_MillSign 0x10020a5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_MillSign instead.") -#define CLUTTER_NairaSign 0x10020a6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_NairaSign instead.") -#define CLUTTER_PesetaSign 0x10020a7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_PesetaSign instead.") -#define CLUTTER_RupeeSign 0x10020a8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_RupeeSign instead.") -#define CLUTTER_WonSign 0x10020a9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_WonSign instead.") -#define CLUTTER_NewSheqelSign 0x10020aa CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_NewSheqelSign instead.") -#define CLUTTER_DongSign 0x10020ab CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_DongSign instead.") -#define CLUTTER_EuroSign 0x20ac CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_EuroSign instead.") -#define CLUTTER_zerosuperior 0x1002070 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_zerosuperior instead.") -#define CLUTTER_foursuperior 0x1002074 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_foursuperior instead.") -#define CLUTTER_fivesuperior 0x1002075 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_fivesuperior instead.") -#define CLUTTER_sixsuperior 0x1002076 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_sixsuperior instead.") -#define CLUTTER_sevensuperior 0x1002077 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_sevensuperior instead.") -#define CLUTTER_eightsuperior 0x1002078 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_eightsuperior instead.") -#define CLUTTER_ninesuperior 0x1002079 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ninesuperior instead.") -#define CLUTTER_zerosubscript 0x1002080 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_zerosubscript instead.") -#define CLUTTER_onesubscript 0x1002081 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_onesubscript instead.") -#define CLUTTER_twosubscript 0x1002082 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_twosubscript instead.") -#define CLUTTER_threesubscript 0x1002083 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_threesubscript instead.") -#define CLUTTER_foursubscript 0x1002084 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_foursubscript instead.") -#define CLUTTER_fivesubscript 0x1002085 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_fivesubscript instead.") -#define CLUTTER_sixsubscript 0x1002086 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_sixsubscript instead.") -#define CLUTTER_sevensubscript 0x1002087 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_sevensubscript instead.") -#define CLUTTER_eightsubscript 0x1002088 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_eightsubscript instead.") -#define CLUTTER_ninesubscript 0x1002089 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_ninesubscript instead.") -#define CLUTTER_partdifferential 0x1002202 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_partdifferential instead.") -#define CLUTTER_emptyset 0x1002205 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_emptyset instead.") -#define CLUTTER_elementof 0x1002208 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_elementof instead.") -#define CLUTTER_notelementof 0x1002209 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_notelementof instead.") -#define CLUTTER_containsas 0x100220b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_containsas instead.") -#define CLUTTER_squareroot 0x100221a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_squareroot instead.") -#define CLUTTER_cuberoot 0x100221b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_cuberoot instead.") -#define CLUTTER_fourthroot 0x100221c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_fourthroot instead.") -#define CLUTTER_dintegral 0x100222c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_dintegral instead.") -#define CLUTTER_tintegral 0x100222d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_tintegral instead.") -#define CLUTTER_because 0x1002235 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_because instead.") -#define CLUTTER_approxeq 0x1002248 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_approxeq instead.") -#define CLUTTER_notapproxeq 0x1002247 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_notapproxeq instead.") -#define CLUTTER_notidentical 0x1002262 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_notidentical instead.") -#define CLUTTER_stricteq 0x1002263 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_stricteq instead.") -#define CLUTTER_braille_dot_1 0xfff1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dot_1 instead.") -#define CLUTTER_braille_dot_2 0xfff2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dot_2 instead.") -#define CLUTTER_braille_dot_3 0xfff3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dot_3 instead.") -#define CLUTTER_braille_dot_4 0xfff4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dot_4 instead.") -#define CLUTTER_braille_dot_5 0xfff5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dot_5 instead.") -#define CLUTTER_braille_dot_6 0xfff6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dot_6 instead.") -#define CLUTTER_braille_dot_7 0xfff7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dot_7 instead.") -#define CLUTTER_braille_dot_8 0xfff8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dot_8 instead.") -#define CLUTTER_braille_dot_9 0xfff9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dot_9 instead.") -#define CLUTTER_braille_dot_10 0xfffa CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dot_10 instead.") -#define CLUTTER_braille_blank 0x1002800 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_blank instead.") -#define CLUTTER_braille_dots_1 0x1002801 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1 instead.") -#define CLUTTER_braille_dots_2 0x1002802 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_2 instead.") -#define CLUTTER_braille_dots_12 0x1002803 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_12 instead.") -#define CLUTTER_braille_dots_3 0x1002804 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_3 instead.") -#define CLUTTER_braille_dots_13 0x1002805 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_13 instead.") -#define CLUTTER_braille_dots_23 0x1002806 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_23 instead.") -#define CLUTTER_braille_dots_123 0x1002807 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_123 instead.") -#define CLUTTER_braille_dots_4 0x1002808 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_4 instead.") -#define CLUTTER_braille_dots_14 0x1002809 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_14 instead.") -#define CLUTTER_braille_dots_24 0x100280a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_24 instead.") -#define CLUTTER_braille_dots_124 0x100280b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_124 instead.") -#define CLUTTER_braille_dots_34 0x100280c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_34 instead.") -#define CLUTTER_braille_dots_134 0x100280d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_134 instead.") -#define CLUTTER_braille_dots_234 0x100280e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_234 instead.") -#define CLUTTER_braille_dots_1234 0x100280f CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1234 instead.") -#define CLUTTER_braille_dots_5 0x1002810 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_5 instead.") -#define CLUTTER_braille_dots_15 0x1002811 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_15 instead.") -#define CLUTTER_braille_dots_25 0x1002812 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_25 instead.") -#define CLUTTER_braille_dots_125 0x1002813 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_125 instead.") -#define CLUTTER_braille_dots_35 0x1002814 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_35 instead.") -#define CLUTTER_braille_dots_135 0x1002815 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_135 instead.") -#define CLUTTER_braille_dots_235 0x1002816 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_235 instead.") -#define CLUTTER_braille_dots_1235 0x1002817 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1235 instead.") -#define CLUTTER_braille_dots_45 0x1002818 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_45 instead.") -#define CLUTTER_braille_dots_145 0x1002819 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_145 instead.") -#define CLUTTER_braille_dots_245 0x100281a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_245 instead.") -#define CLUTTER_braille_dots_1245 0x100281b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1245 instead.") -#define CLUTTER_braille_dots_345 0x100281c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_345 instead.") -#define CLUTTER_braille_dots_1345 0x100281d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1345 instead.") -#define CLUTTER_braille_dots_2345 0x100281e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_2345 instead.") -#define CLUTTER_braille_dots_12345 0x100281f CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_12345 instead.") -#define CLUTTER_braille_dots_6 0x1002820 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_6 instead.") -#define CLUTTER_braille_dots_16 0x1002821 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_16 instead.") -#define CLUTTER_braille_dots_26 0x1002822 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_26 instead.") -#define CLUTTER_braille_dots_126 0x1002823 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_126 instead.") -#define CLUTTER_braille_dots_36 0x1002824 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_36 instead.") -#define CLUTTER_braille_dots_136 0x1002825 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_136 instead.") -#define CLUTTER_braille_dots_236 0x1002826 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_236 instead.") -#define CLUTTER_braille_dots_1236 0x1002827 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1236 instead.") -#define CLUTTER_braille_dots_46 0x1002828 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_46 instead.") -#define CLUTTER_braille_dots_146 0x1002829 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_146 instead.") -#define CLUTTER_braille_dots_246 0x100282a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_246 instead.") -#define CLUTTER_braille_dots_1246 0x100282b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1246 instead.") -#define CLUTTER_braille_dots_346 0x100282c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_346 instead.") -#define CLUTTER_braille_dots_1346 0x100282d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1346 instead.") -#define CLUTTER_braille_dots_2346 0x100282e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_2346 instead.") -#define CLUTTER_braille_dots_12346 0x100282f CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_12346 instead.") -#define CLUTTER_braille_dots_56 0x1002830 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_56 instead.") -#define CLUTTER_braille_dots_156 0x1002831 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_156 instead.") -#define CLUTTER_braille_dots_256 0x1002832 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_256 instead.") -#define CLUTTER_braille_dots_1256 0x1002833 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1256 instead.") -#define CLUTTER_braille_dots_356 0x1002834 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_356 instead.") -#define CLUTTER_braille_dots_1356 0x1002835 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1356 instead.") -#define CLUTTER_braille_dots_2356 0x1002836 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_2356 instead.") -#define CLUTTER_braille_dots_12356 0x1002837 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_12356 instead.") -#define CLUTTER_braille_dots_456 0x1002838 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_456 instead.") -#define CLUTTER_braille_dots_1456 0x1002839 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1456 instead.") -#define CLUTTER_braille_dots_2456 0x100283a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_2456 instead.") -#define CLUTTER_braille_dots_12456 0x100283b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_12456 instead.") -#define CLUTTER_braille_dots_3456 0x100283c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_3456 instead.") -#define CLUTTER_braille_dots_13456 0x100283d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_13456 instead.") -#define CLUTTER_braille_dots_23456 0x100283e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_23456 instead.") -#define CLUTTER_braille_dots_123456 0x100283f CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_123456 instead.") -#define CLUTTER_braille_dots_7 0x1002840 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_7 instead.") -#define CLUTTER_braille_dots_17 0x1002841 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_17 instead.") -#define CLUTTER_braille_dots_27 0x1002842 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_27 instead.") -#define CLUTTER_braille_dots_127 0x1002843 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_127 instead.") -#define CLUTTER_braille_dots_37 0x1002844 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_37 instead.") -#define CLUTTER_braille_dots_137 0x1002845 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_137 instead.") -#define CLUTTER_braille_dots_237 0x1002846 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_237 instead.") -#define CLUTTER_braille_dots_1237 0x1002847 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1237 instead.") -#define CLUTTER_braille_dots_47 0x1002848 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_47 instead.") -#define CLUTTER_braille_dots_147 0x1002849 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_147 instead.") -#define CLUTTER_braille_dots_247 0x100284a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_247 instead.") -#define CLUTTER_braille_dots_1247 0x100284b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1247 instead.") -#define CLUTTER_braille_dots_347 0x100284c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_347 instead.") -#define CLUTTER_braille_dots_1347 0x100284d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1347 instead.") -#define CLUTTER_braille_dots_2347 0x100284e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_2347 instead.") -#define CLUTTER_braille_dots_12347 0x100284f CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_12347 instead.") -#define CLUTTER_braille_dots_57 0x1002850 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_57 instead.") -#define CLUTTER_braille_dots_157 0x1002851 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_157 instead.") -#define CLUTTER_braille_dots_257 0x1002852 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_257 instead.") -#define CLUTTER_braille_dots_1257 0x1002853 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1257 instead.") -#define CLUTTER_braille_dots_357 0x1002854 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_357 instead.") -#define CLUTTER_braille_dots_1357 0x1002855 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1357 instead.") -#define CLUTTER_braille_dots_2357 0x1002856 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_2357 instead.") -#define CLUTTER_braille_dots_12357 0x1002857 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_12357 instead.") -#define CLUTTER_braille_dots_457 0x1002858 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_457 instead.") -#define CLUTTER_braille_dots_1457 0x1002859 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1457 instead.") -#define CLUTTER_braille_dots_2457 0x100285a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_2457 instead.") -#define CLUTTER_braille_dots_12457 0x100285b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_12457 instead.") -#define CLUTTER_braille_dots_3457 0x100285c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_3457 instead.") -#define CLUTTER_braille_dots_13457 0x100285d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_13457 instead.") -#define CLUTTER_braille_dots_23457 0x100285e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_23457 instead.") -#define CLUTTER_braille_dots_123457 0x100285f CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_123457 instead.") -#define CLUTTER_braille_dots_67 0x1002860 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_67 instead.") -#define CLUTTER_braille_dots_167 0x1002861 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_167 instead.") -#define CLUTTER_braille_dots_267 0x1002862 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_267 instead.") -#define CLUTTER_braille_dots_1267 0x1002863 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1267 instead.") -#define CLUTTER_braille_dots_367 0x1002864 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_367 instead.") -#define CLUTTER_braille_dots_1367 0x1002865 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1367 instead.") -#define CLUTTER_braille_dots_2367 0x1002866 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_2367 instead.") -#define CLUTTER_braille_dots_12367 0x1002867 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_12367 instead.") -#define CLUTTER_braille_dots_467 0x1002868 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_467 instead.") -#define CLUTTER_braille_dots_1467 0x1002869 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1467 instead.") -#define CLUTTER_braille_dots_2467 0x100286a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_2467 instead.") -#define CLUTTER_braille_dots_12467 0x100286b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_12467 instead.") -#define CLUTTER_braille_dots_3467 0x100286c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_3467 instead.") -#define CLUTTER_braille_dots_13467 0x100286d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_13467 instead.") -#define CLUTTER_braille_dots_23467 0x100286e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_23467 instead.") -#define CLUTTER_braille_dots_123467 0x100286f CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_123467 instead.") -#define CLUTTER_braille_dots_567 0x1002870 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_567 instead.") -#define CLUTTER_braille_dots_1567 0x1002871 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1567 instead.") -#define CLUTTER_braille_dots_2567 0x1002872 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_2567 instead.") -#define CLUTTER_braille_dots_12567 0x1002873 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_12567 instead.") -#define CLUTTER_braille_dots_3567 0x1002874 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_3567 instead.") -#define CLUTTER_braille_dots_13567 0x1002875 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_13567 instead.") -#define CLUTTER_braille_dots_23567 0x1002876 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_23567 instead.") -#define CLUTTER_braille_dots_123567 0x1002877 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_123567 instead.") -#define CLUTTER_braille_dots_4567 0x1002878 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_4567 instead.") -#define CLUTTER_braille_dots_14567 0x1002879 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_14567 instead.") -#define CLUTTER_braille_dots_24567 0x100287a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_24567 instead.") -#define CLUTTER_braille_dots_124567 0x100287b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_124567 instead.") -#define CLUTTER_braille_dots_34567 0x100287c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_34567 instead.") -#define CLUTTER_braille_dots_134567 0x100287d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_134567 instead.") -#define CLUTTER_braille_dots_234567 0x100287e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_234567 instead.") -#define CLUTTER_braille_dots_1234567 0x100287f CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1234567 instead.") -#define CLUTTER_braille_dots_8 0x1002880 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_8 instead.") -#define CLUTTER_braille_dots_18 0x1002881 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_18 instead.") -#define CLUTTER_braille_dots_28 0x1002882 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_28 instead.") -#define CLUTTER_braille_dots_128 0x1002883 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_128 instead.") -#define CLUTTER_braille_dots_38 0x1002884 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_38 instead.") -#define CLUTTER_braille_dots_138 0x1002885 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_138 instead.") -#define CLUTTER_braille_dots_238 0x1002886 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_238 instead.") -#define CLUTTER_braille_dots_1238 0x1002887 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1238 instead.") -#define CLUTTER_braille_dots_48 0x1002888 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_48 instead.") -#define CLUTTER_braille_dots_148 0x1002889 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_148 instead.") -#define CLUTTER_braille_dots_248 0x100288a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_248 instead.") -#define CLUTTER_braille_dots_1248 0x100288b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1248 instead.") -#define CLUTTER_braille_dots_348 0x100288c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_348 instead.") -#define CLUTTER_braille_dots_1348 0x100288d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1348 instead.") -#define CLUTTER_braille_dots_2348 0x100288e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_2348 instead.") -#define CLUTTER_braille_dots_12348 0x100288f CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_12348 instead.") -#define CLUTTER_braille_dots_58 0x1002890 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_58 instead.") -#define CLUTTER_braille_dots_158 0x1002891 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_158 instead.") -#define CLUTTER_braille_dots_258 0x1002892 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_258 instead.") -#define CLUTTER_braille_dots_1258 0x1002893 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1258 instead.") -#define CLUTTER_braille_dots_358 0x1002894 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_358 instead.") -#define CLUTTER_braille_dots_1358 0x1002895 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1358 instead.") -#define CLUTTER_braille_dots_2358 0x1002896 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_2358 instead.") -#define CLUTTER_braille_dots_12358 0x1002897 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_12358 instead.") -#define CLUTTER_braille_dots_458 0x1002898 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_458 instead.") -#define CLUTTER_braille_dots_1458 0x1002899 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1458 instead.") -#define CLUTTER_braille_dots_2458 0x100289a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_2458 instead.") -#define CLUTTER_braille_dots_12458 0x100289b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_12458 instead.") -#define CLUTTER_braille_dots_3458 0x100289c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_3458 instead.") -#define CLUTTER_braille_dots_13458 0x100289d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_13458 instead.") -#define CLUTTER_braille_dots_23458 0x100289e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_23458 instead.") -#define CLUTTER_braille_dots_123458 0x100289f CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_123458 instead.") -#define CLUTTER_braille_dots_68 0x10028a0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_68 instead.") -#define CLUTTER_braille_dots_168 0x10028a1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_168 instead.") -#define CLUTTER_braille_dots_268 0x10028a2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_268 instead.") -#define CLUTTER_braille_dots_1268 0x10028a3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1268 instead.") -#define CLUTTER_braille_dots_368 0x10028a4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_368 instead.") -#define CLUTTER_braille_dots_1368 0x10028a5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1368 instead.") -#define CLUTTER_braille_dots_2368 0x10028a6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_2368 instead.") -#define CLUTTER_braille_dots_12368 0x10028a7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_12368 instead.") -#define CLUTTER_braille_dots_468 0x10028a8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_468 instead.") -#define CLUTTER_braille_dots_1468 0x10028a9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1468 instead.") -#define CLUTTER_braille_dots_2468 0x10028aa CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_2468 instead.") -#define CLUTTER_braille_dots_12468 0x10028ab CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_12468 instead.") -#define CLUTTER_braille_dots_3468 0x10028ac CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_3468 instead.") -#define CLUTTER_braille_dots_13468 0x10028ad CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_13468 instead.") -#define CLUTTER_braille_dots_23468 0x10028ae CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_23468 instead.") -#define CLUTTER_braille_dots_123468 0x10028af CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_123468 instead.") -#define CLUTTER_braille_dots_568 0x10028b0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_568 instead.") -#define CLUTTER_braille_dots_1568 0x10028b1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1568 instead.") -#define CLUTTER_braille_dots_2568 0x10028b2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_2568 instead.") -#define CLUTTER_braille_dots_12568 0x10028b3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_12568 instead.") -#define CLUTTER_braille_dots_3568 0x10028b4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_3568 instead.") -#define CLUTTER_braille_dots_13568 0x10028b5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_13568 instead.") -#define CLUTTER_braille_dots_23568 0x10028b6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_23568 instead.") -#define CLUTTER_braille_dots_123568 0x10028b7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_123568 instead.") -#define CLUTTER_braille_dots_4568 0x10028b8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_4568 instead.") -#define CLUTTER_braille_dots_14568 0x10028b9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_14568 instead.") -#define CLUTTER_braille_dots_24568 0x10028ba CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_24568 instead.") -#define CLUTTER_braille_dots_124568 0x10028bb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_124568 instead.") -#define CLUTTER_braille_dots_34568 0x10028bc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_34568 instead.") -#define CLUTTER_braille_dots_134568 0x10028bd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_134568 instead.") -#define CLUTTER_braille_dots_234568 0x10028be CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_234568 instead.") -#define CLUTTER_braille_dots_1234568 0x10028bf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1234568 instead.") -#define CLUTTER_braille_dots_78 0x10028c0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_78 instead.") -#define CLUTTER_braille_dots_178 0x10028c1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_178 instead.") -#define CLUTTER_braille_dots_278 0x10028c2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_278 instead.") -#define CLUTTER_braille_dots_1278 0x10028c3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1278 instead.") -#define CLUTTER_braille_dots_378 0x10028c4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_378 instead.") -#define CLUTTER_braille_dots_1378 0x10028c5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1378 instead.") -#define CLUTTER_braille_dots_2378 0x10028c6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_2378 instead.") -#define CLUTTER_braille_dots_12378 0x10028c7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_12378 instead.") -#define CLUTTER_braille_dots_478 0x10028c8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_478 instead.") -#define CLUTTER_braille_dots_1478 0x10028c9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1478 instead.") -#define CLUTTER_braille_dots_2478 0x10028ca CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_2478 instead.") -#define CLUTTER_braille_dots_12478 0x10028cb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_12478 instead.") -#define CLUTTER_braille_dots_3478 0x10028cc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_3478 instead.") -#define CLUTTER_braille_dots_13478 0x10028cd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_13478 instead.") -#define CLUTTER_braille_dots_23478 0x10028ce CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_23478 instead.") -#define CLUTTER_braille_dots_123478 0x10028cf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_123478 instead.") -#define CLUTTER_braille_dots_578 0x10028d0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_578 instead.") -#define CLUTTER_braille_dots_1578 0x10028d1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1578 instead.") -#define CLUTTER_braille_dots_2578 0x10028d2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_2578 instead.") -#define CLUTTER_braille_dots_12578 0x10028d3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_12578 instead.") -#define CLUTTER_braille_dots_3578 0x10028d4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_3578 instead.") -#define CLUTTER_braille_dots_13578 0x10028d5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_13578 instead.") -#define CLUTTER_braille_dots_23578 0x10028d6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_23578 instead.") -#define CLUTTER_braille_dots_123578 0x10028d7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_123578 instead.") -#define CLUTTER_braille_dots_4578 0x10028d8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_4578 instead.") -#define CLUTTER_braille_dots_14578 0x10028d9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_14578 instead.") -#define CLUTTER_braille_dots_24578 0x10028da CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_24578 instead.") -#define CLUTTER_braille_dots_124578 0x10028db CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_124578 instead.") -#define CLUTTER_braille_dots_34578 0x10028dc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_34578 instead.") -#define CLUTTER_braille_dots_134578 0x10028dd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_134578 instead.") -#define CLUTTER_braille_dots_234578 0x10028de CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_234578 instead.") -#define CLUTTER_braille_dots_1234578 0x10028df CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1234578 instead.") -#define CLUTTER_braille_dots_678 0x10028e0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_678 instead.") -#define CLUTTER_braille_dots_1678 0x10028e1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1678 instead.") -#define CLUTTER_braille_dots_2678 0x10028e2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_2678 instead.") -#define CLUTTER_braille_dots_12678 0x10028e3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_12678 instead.") -#define CLUTTER_braille_dots_3678 0x10028e4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_3678 instead.") -#define CLUTTER_braille_dots_13678 0x10028e5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_13678 instead.") -#define CLUTTER_braille_dots_23678 0x10028e6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_23678 instead.") -#define CLUTTER_braille_dots_123678 0x10028e7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_123678 instead.") -#define CLUTTER_braille_dots_4678 0x10028e8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_4678 instead.") -#define CLUTTER_braille_dots_14678 0x10028e9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_14678 instead.") -#define CLUTTER_braille_dots_24678 0x10028ea CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_24678 instead.") -#define CLUTTER_braille_dots_124678 0x10028eb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_124678 instead.") -#define CLUTTER_braille_dots_34678 0x10028ec CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_34678 instead.") -#define CLUTTER_braille_dots_134678 0x10028ed CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_134678 instead.") -#define CLUTTER_braille_dots_234678 0x10028ee CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_234678 instead.") -#define CLUTTER_braille_dots_1234678 0x10028ef CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1234678 instead.") -#define CLUTTER_braille_dots_5678 0x10028f0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_5678 instead.") -#define CLUTTER_braille_dots_15678 0x10028f1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_15678 instead.") -#define CLUTTER_braille_dots_25678 0x10028f2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_25678 instead.") -#define CLUTTER_braille_dots_125678 0x10028f3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_125678 instead.") -#define CLUTTER_braille_dots_35678 0x10028f4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_35678 instead.") -#define CLUTTER_braille_dots_135678 0x10028f5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_135678 instead.") -#define CLUTTER_braille_dots_235678 0x10028f6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_235678 instead.") -#define CLUTTER_braille_dots_1235678 0x10028f7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1235678 instead.") -#define CLUTTER_braille_dots_45678 0x10028f8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_45678 instead.") -#define CLUTTER_braille_dots_145678 0x10028f9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_145678 instead.") -#define CLUTTER_braille_dots_245678 0x10028fa CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_245678 instead.") -#define CLUTTER_braille_dots_1245678 0x10028fb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1245678 instead.") -#define CLUTTER_braille_dots_345678 0x10028fc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_345678 instead.") -#define CLUTTER_braille_dots_1345678 0x10028fd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_1345678 instead.") -#define CLUTTER_braille_dots_2345678 0x10028fe CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_2345678 instead.") -#define CLUTTER_braille_dots_12345678 0x10028ff CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_braille_dots_12345678 instead.") -#define CLUTTER_Sinh_ng 0x1000d82 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_ng instead.") -#define CLUTTER_Sinh_h2 0x1000d83 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_h2 instead.") -#define CLUTTER_Sinh_a 0x1000d85 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_a instead.") -#define CLUTTER_Sinh_aa 0x1000d86 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_aa instead.") -#define CLUTTER_Sinh_ae 0x1000d87 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_ae instead.") -#define CLUTTER_Sinh_aee 0x1000d88 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_aee instead.") -#define CLUTTER_Sinh_i 0x1000d89 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_i instead.") -#define CLUTTER_Sinh_ii 0x1000d8a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_ii instead.") -#define CLUTTER_Sinh_u 0x1000d8b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_u instead.") -#define CLUTTER_Sinh_uu 0x1000d8c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_uu instead.") -#define CLUTTER_Sinh_ri 0x1000d8d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_ri instead.") -#define CLUTTER_Sinh_rii 0x1000d8e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_rii instead.") -#define CLUTTER_Sinh_lu 0x1000d8f CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_lu instead.") -#define CLUTTER_Sinh_luu 0x1000d90 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_luu instead.") -#define CLUTTER_Sinh_e 0x1000d91 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_e instead.") -#define CLUTTER_Sinh_ee 0x1000d92 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_ee instead.") -#define CLUTTER_Sinh_ai 0x1000d93 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_ai instead.") -#define CLUTTER_Sinh_o 0x1000d94 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_o instead.") -#define CLUTTER_Sinh_oo 0x1000d95 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_oo instead.") -#define CLUTTER_Sinh_au 0x1000d96 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_au instead.") -#define CLUTTER_Sinh_ka 0x1000d9a CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_ka instead.") -#define CLUTTER_Sinh_kha 0x1000d9b CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_kha instead.") -#define CLUTTER_Sinh_ga 0x1000d9c CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_ga instead.") -#define CLUTTER_Sinh_gha 0x1000d9d CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_gha instead.") -#define CLUTTER_Sinh_ng2 0x1000d9e CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_ng2 instead.") -#define CLUTTER_Sinh_nga 0x1000d9f CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_nga instead.") -#define CLUTTER_Sinh_ca 0x1000da0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_ca instead.") -#define CLUTTER_Sinh_cha 0x1000da1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_cha instead.") -#define CLUTTER_Sinh_ja 0x1000da2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_ja instead.") -#define CLUTTER_Sinh_jha 0x1000da3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_jha instead.") -#define CLUTTER_Sinh_nya 0x1000da4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_nya instead.") -#define CLUTTER_Sinh_jnya 0x1000da5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_jnya instead.") -#define CLUTTER_Sinh_nja 0x1000da6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_nja instead.") -#define CLUTTER_Sinh_tta 0x1000da7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_tta instead.") -#define CLUTTER_Sinh_ttha 0x1000da8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_ttha instead.") -#define CLUTTER_Sinh_dda 0x1000da9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_dda instead.") -#define CLUTTER_Sinh_ddha 0x1000daa CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_ddha instead.") -#define CLUTTER_Sinh_nna 0x1000dab CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_nna instead.") -#define CLUTTER_Sinh_ndda 0x1000dac CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_ndda instead.") -#define CLUTTER_Sinh_tha 0x1000dad CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_tha instead.") -#define CLUTTER_Sinh_thha 0x1000dae CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_thha instead.") -#define CLUTTER_Sinh_dha 0x1000daf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_dha instead.") -#define CLUTTER_Sinh_dhha 0x1000db0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_dhha instead.") -#define CLUTTER_Sinh_na 0x1000db1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_na instead.") -#define CLUTTER_Sinh_ndha 0x1000db3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_ndha instead.") -#define CLUTTER_Sinh_pa 0x1000db4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_pa instead.") -#define CLUTTER_Sinh_pha 0x1000db5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_pha instead.") -#define CLUTTER_Sinh_ba 0x1000db6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_ba instead.") -#define CLUTTER_Sinh_bha 0x1000db7 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_bha instead.") -#define CLUTTER_Sinh_ma 0x1000db8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_ma instead.") -#define CLUTTER_Sinh_mba 0x1000db9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_mba instead.") -#define CLUTTER_Sinh_ya 0x1000dba CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_ya instead.") -#define CLUTTER_Sinh_ra 0x1000dbb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_ra instead.") -#define CLUTTER_Sinh_la 0x1000dbd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_la instead.") -#define CLUTTER_Sinh_va 0x1000dc0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_va instead.") -#define CLUTTER_Sinh_sha 0x1000dc1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_sha instead.") -#define CLUTTER_Sinh_ssha 0x1000dc2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_ssha instead.") -#define CLUTTER_Sinh_sa 0x1000dc3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_sa instead.") -#define CLUTTER_Sinh_ha 0x1000dc4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_ha instead.") -#define CLUTTER_Sinh_lla 0x1000dc5 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_lla instead.") -#define CLUTTER_Sinh_fa 0x1000dc6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_fa instead.") -#define CLUTTER_Sinh_al 0x1000dca CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_al instead.") -#define CLUTTER_Sinh_aa2 0x1000dcf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_aa2 instead.") -#define CLUTTER_Sinh_ae2 0x1000dd0 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_ae2 instead.") -#define CLUTTER_Sinh_aee2 0x1000dd1 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_aee2 instead.") -#define CLUTTER_Sinh_i2 0x1000dd2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_i2 instead.") -#define CLUTTER_Sinh_ii2 0x1000dd3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_ii2 instead.") -#define CLUTTER_Sinh_u2 0x1000dd4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_u2 instead.") -#define CLUTTER_Sinh_uu2 0x1000dd6 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_uu2 instead.") -#define CLUTTER_Sinh_ru2 0x1000dd8 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_ru2 instead.") -#define CLUTTER_Sinh_e2 0x1000dd9 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_e2 instead.") -#define CLUTTER_Sinh_ee2 0x1000dda CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_ee2 instead.") -#define CLUTTER_Sinh_ai2 0x1000ddb CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_ai2 instead.") -#define CLUTTER_Sinh_o2 0x1000ddc CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_o2 instead.") -#define CLUTTER_Sinh_oo2 0x1000ddd CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_oo2 instead.") -#define CLUTTER_Sinh_au2 0x1000dde CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_au2 instead.") -#define CLUTTER_Sinh_lu2 0x1000ddf CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_lu2 instead.") -#define CLUTTER_Sinh_ruu2 0x1000df2 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_ruu2 instead.") -#define CLUTTER_Sinh_luu2 0x1000df3 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_luu2 instead.") -#define CLUTTER_Sinh_kunddaliya 0x1000df4 CLUTTER_DEPRECATED_MACRO_FOR("Deprecated key symbol. Use CLUTTER_KEY_Sinh_kunddaliya instead.") -#define CLUTTER_ModeLock 0x1008ff01 -#define CLUTTER_MonBrightnessUp 0x1008ff02 -#define CLUTTER_MonBrightnessDown 0x1008ff03 -#define CLUTTER_KbdLightOnOff 0x1008ff04 -#define CLUTTER_KbdBrightnessUp 0x1008ff05 -#define CLUTTER_KbdBrightnessDown 0x1008ff06 -#define CLUTTER_Standby 0x1008ff10 -#define CLUTTER_AudioLowerVolume 0x1008ff11 -#define CLUTTER_AudioMute 0x1008ff12 -#define CLUTTER_AudioRaiseVolume 0x1008ff13 -#define CLUTTER_AudioPlay 0x1008ff14 -#define CLUTTER_AudioStop 0x1008ff15 -#define CLUTTER_AudioPrev 0x1008ff16 -#define CLUTTER_AudioNext 0x1008ff17 -#define CLUTTER_HomePage 0x1008ff18 -#define CLUTTER_Mail 0x1008ff19 -#define CLUTTER_Start 0x1008ff1a -#define CLUTTER_Search 0x1008ff1b -#define CLUTTER_AudioRecord 0x1008ff1c -#define CLUTTER_Calculator 0x1008ff1d -#define CLUTTER_Memo 0x1008ff1e -#define CLUTTER_ToDoList 0x1008ff1f -#define CLUTTER_Calendar 0x1008ff20 -#define CLUTTER_PowerDown 0x1008ff21 -#define CLUTTER_ContrastAdjust 0x1008ff22 -#define CLUTTER_RockerUp 0x1008ff23 -#define CLUTTER_RockerDown 0x1008ff24 -#define CLUTTER_RockerEnter 0x1008ff25 -#define CLUTTER_Back 0x1008ff26 -#define CLUTTER_Forward 0x1008ff27 -#define CLUTTER_Stop 0x1008ff28 -#define CLUTTER_Refresh 0x1008ff29 -#define CLUTTER_PowerOff 0x1008ff2a -#define CLUTTER_WakeUp 0x1008ff2b -#define CLUTTER_Eject 0x1008ff2c -#define CLUTTER_ScreenSaver 0x1008ff2d -#define CLUTTER_WWW 0x1008ff2e -#define CLUTTER_Sleep 0x1008ff2f -#define CLUTTER_Favorites 0x1008ff30 -#define CLUTTER_AudioPause 0x1008ff31 -#define CLUTTER_AudioMedia 0x1008ff32 -#define CLUTTER_MyComputer 0x1008ff33 -#define CLUTTER_VendorHome 0x1008ff34 -#define CLUTTER_LightBulb 0x1008ff35 -#define CLUTTER_Shop 0x1008ff36 -#define CLUTTER_History 0x1008ff37 -#define CLUTTER_OpenURL 0x1008ff38 -#define CLUTTER_AddFavorite 0x1008ff39 -#define CLUTTER_HotLinks 0x1008ff3a -#define CLUTTER_BrightnessAdjust 0x1008ff3b -#define CLUTTER_Finance 0x1008ff3c -#define CLUTTER_Community 0x1008ff3d -#define CLUTTER_AudioRewind 0x1008ff3e -#define CLUTTER_BackForward 0x1008ff3f -#define CLUTTER_Launch0 0x1008ff40 -#define CLUTTER_Launch1 0x1008ff41 -#define CLUTTER_Launch2 0x1008ff42 -#define CLUTTER_Launch3 0x1008ff43 -#define CLUTTER_Launch4 0x1008ff44 -#define CLUTTER_Launch5 0x1008ff45 -#define CLUTTER_Launch6 0x1008ff46 -#define CLUTTER_Launch7 0x1008ff47 -#define CLUTTER_Launch8 0x1008ff48 -#define CLUTTER_Launch9 0x1008ff49 -#define CLUTTER_LaunchA 0x1008ff4a -#define CLUTTER_LaunchB 0x1008ff4b -#define CLUTTER_LaunchC 0x1008ff4c -#define CLUTTER_LaunchD 0x1008ff4d -#define CLUTTER_LaunchE 0x1008ff4e -#define CLUTTER_LaunchF 0x1008ff4f -#define CLUTTER_ApplicationLeft 0x1008ff50 -#define CLUTTER_ApplicationRight 0x1008ff51 -#define CLUTTER_Book 0x1008ff52 -#define CLUTTER_CD 0x1008ff53 -#define CLUTTER_WindowClear 0x1008ff55 -#define CLUTTER_Close 0x1008ff56 -#define CLUTTER_Copy 0x1008ff57 -#define CLUTTER_Cut 0x1008ff58 -#define CLUTTER_Display 0x1008ff59 -#define CLUTTER_DOS 0x1008ff5a -#define CLUTTER_Documents 0x1008ff5b -#define CLUTTER_Excel 0x1008ff5c -#define CLUTTER_Explorer 0x1008ff5d -#define CLUTTER_Game 0x1008ff5e -#define CLUTTER_Go 0x1008ff5f -#define CLUTTER_iTouch 0x1008ff60 -#define CLUTTER_LogOff 0x1008ff61 -#define CLUTTER_Market 0x1008ff62 -#define CLUTTER_Meeting 0x1008ff63 -#define CLUTTER_MenuKB 0x1008ff65 -#define CLUTTER_MenuPB 0x1008ff66 -#define CLUTTER_MySites 0x1008ff67 -#define CLUTTER_New 0x1008ff68 -#define CLUTTER_News 0x1008ff69 -#define CLUTTER_OfficeHome 0x1008ff6a -#define CLUTTER_Open 0x1008ff6b -#define CLUTTER_Option 0x1008ff6c -#define CLUTTER_Paste 0x1008ff6d -#define CLUTTER_Phone 0x1008ff6e -#define CLUTTER_Reply 0x1008ff72 -#define CLUTTER_Reload 0x1008ff73 -#define CLUTTER_RotateWindows 0x1008ff74 -#define CLUTTER_RotationPB 0x1008ff75 -#define CLUTTER_RotationKB 0x1008ff76 -#define CLUTTER_Save 0x1008ff77 -#define CLUTTER_ScrollUp 0x1008ff78 -#define CLUTTER_ScrollDown 0x1008ff79 -#define CLUTTER_ScrollClick 0x1008ff7a -#define CLUTTER_Send 0x1008ff7b -#define CLUTTER_Spell 0x1008ff7c -#define CLUTTER_SplitScreen 0x1008ff7d -#define CLUTTER_Support 0x1008ff7e -#define CLUTTER_TaskPane 0x1008ff7f -#define CLUTTER_Terminal 0x1008ff80 -#define CLUTTER_Tools 0x1008ff81 -#define CLUTTER_Travel 0x1008ff82 -#define CLUTTER_UserPB 0x1008ff84 -#define CLUTTER_User1KB 0x1008ff85 -#define CLUTTER_User2KB 0x1008ff86 -#define CLUTTER_Video 0x1008ff87 -#define CLUTTER_WheelButton 0x1008ff88 -#define CLUTTER_Word 0x1008ff89 -#define CLUTTER_Xfer 0x1008ff8a -#define CLUTTER_ZoomIn 0x1008ff8b -#define CLUTTER_ZoomOut 0x1008ff8c -#define CLUTTER_Away 0x1008ff8d -#define CLUTTER_Messenger 0x1008ff8e -#define CLUTTER_WebCam 0x1008ff8f -#define CLUTTER_MailForward 0x1008ff90 -#define CLUTTER_Pictures 0x1008ff91 -#define CLUTTER_Music 0x1008ff92 -#define CLUTTER_Battery 0x1008ff93 -#define CLUTTER_Bluetooth 0x1008ff94 -#define CLUTTER_WLAN 0x1008ff95 -#define CLUTTER_UWB 0x1008ff96 -#define CLUTTER_AudioForward 0x1008ff97 -#define CLUTTER_AudioRepeat 0x1008ff98 -#define CLUTTER_AudioRandomPlay 0x1008ff99 -#define CLUTTER_Subtitle 0x1008ff9a -#define CLUTTER_AudioCycleTrack 0x1008ff9b -#define CLUTTER_CycleAngle 0x1008ff9c -#define CLUTTER_FrameBack 0x1008ff9d -#define CLUTTER_FrameForward 0x1008ff9e -#define CLUTTER_Time 0x1008ff9f -#define CLUTTER_SelectButton 0x1008ffa0 -#define CLUTTER_View 0x1008ffa1 -#define CLUTTER_TopMenu 0x1008ffa2 -#define CLUTTER_Red 0x1008ffa3 -#define CLUTTER_Green 0x1008ffa4 -#define CLUTTER_Yellow 0x1008ffa5 -#define CLUTTER_Blue 0x1008ffa6 -#define CLUTTER_Suspend 0x1008ffa7 -#define CLUTTER_Hibernate 0x1008ffa8 -#define CLUTTER_TouchpadToggle 0x1008ffa9 -#define CLUTTER_TouchpadOn 0x1008ffb0 -#define CLUTTER_TouchpadOff 0x1008ffb1 -#define CLUTTER_AudioMicMute 0x1008ffb2 -#define CLUTTER_Switch_VT_1 0x1008fe01 -#define CLUTTER_Switch_VT_2 0x1008fe02 -#define CLUTTER_Switch_VT_3 0x1008fe03 -#define CLUTTER_Switch_VT_4 0x1008fe04 -#define CLUTTER_Switch_VT_5 0x1008fe05 -#define CLUTTER_Switch_VT_6 0x1008fe06 -#define CLUTTER_Switch_VT_7 0x1008fe07 -#define CLUTTER_Switch_VT_8 0x1008fe08 -#define CLUTTER_Switch_VT_9 0x1008fe09 -#define CLUTTER_Switch_VT_10 0x1008fe0a -#define CLUTTER_Switch_VT_11 0x1008fe0b -#define CLUTTER_Switch_VT_12 0x1008fe0c -#define CLUTTER_Ungrab 0x1008fe20 -#define CLUTTER_ClearGrab 0x1008fe21 -#define CLUTTER_Next_VMode 0x1008fe22 -#define CLUTTER_Prev_VMode 0x1008fe23 -#define CLUTTER_LogWindowTree 0x1008fe24 -#define CLUTTER_LogGrabInfo 0x1008fe25 - -#endif /* CLUTTER_DISABLE_DEPRECATED */ - -#endif /* __CLUTTER_KEYSYMS_DEPRECATED_H__ */ diff --git a/clutter/clutter/deprecated/clutter-layout-manager-deprecated.c b/clutter/clutter/deprecated/clutter-layout-manager-deprecated.c deleted file mode 100644 index 94f0e350b..000000000 --- a/clutter/clutter/deprecated/clutter-layout-manager-deprecated.c +++ /dev/null @@ -1,89 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include "clutter-build-config.h" -#endif - -#include "clutter-layout-manager.h" - -/** - * clutter_layout_manager_begin_animation: - * @manager: a #ClutterLayoutManager - * @duration: the duration of the animation, in milliseconds - * @mode: the easing mode of the animation - * - * Begins an animation of @duration milliseconds, using the provided - * easing @mode - * - * The easing mode can be specified either as a #ClutterAnimationMode - * or as a logical id returned by clutter_alpha_register_func() - * - * The result of this function depends on the @manager implementation - * - * Return value: (transfer none): The #ClutterAlpha created by the - * layout manager; the returned instance is owned by the layout - * manager and should not be unreferenced - * - * Since: 1.2 - * - * Deprecated: 1.12 - */ -ClutterAlpha * -clutter_layout_manager_begin_animation (ClutterLayoutManager *manager, - guint duration, - gulong mode) -{ - ClutterLayoutManagerClass *klass; - - g_return_val_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager), NULL); - - klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager); - - return klass->begin_animation (manager, duration, mode); -} - -/** - * clutter_layout_manager_end_animation: - * @manager: a #ClutterLayoutManager - * - * Ends an animation started by clutter_layout_manager_begin_animation() - * - * The result of this call depends on the @manager implementation - * - * Since: 1.2 - * - * Deprecated: 1.12 - */ -void -clutter_layout_manager_end_animation (ClutterLayoutManager *manager) -{ - g_return_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager)); - - CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager)->end_animation (manager); -} - -/** - * clutter_layout_manager_get_animation_progress: - * @manager: a #ClutterLayoutManager - * - * Retrieves the progress of the animation, if one has been started by - * clutter_layout_manager_begin_animation() - * - * The returned value has the same semantics of the #ClutterAlpha:alpha - * value - * - * Return value: the progress of the animation - * - * Since: 1.2 - * - * Deprecated: 1.12 - */ -gdouble -clutter_layout_manager_get_animation_progress (ClutterLayoutManager *manager) -{ - ClutterLayoutManagerClass *klass; - - g_return_val_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager), 1.0); - - klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager); - - return klass->get_animation_progress (manager); -} diff --git a/clutter/clutter/deprecated/clutter-list-model.c b/clutter/clutter/deprecated/clutter-list-model.c deleted file mode 100644 index 057b104bc..000000000 --- a/clutter/clutter/deprecated/clutter-list-model.c +++ /dev/null @@ -1,836 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * Neil Jagdish Patel - * Emmanuele Bassi - * - * Copyright (C) 2006 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -/** - * SECTION:clutter-list-model - * @short_description: List model implementation - * - * #ClutterListModel is a #ClutterModel implementation provided by - * Clutter. #ClutterListModel uses a #GSequence for storing the - * values for each row, so it's optimized for insertion and look up - * in sorted lists. - * - * #ClutterListModel is available since Clutter 0.6 - * - * Deprecated: 1.24: Use a #GListStore instance containing a custom - * object type with properties for each column instead. - */ - -#ifdef HAVE_CONFIG_H -#include "clutter-build-config.h" -#endif - -#include -#include - -#include - -#define CLUTTER_DISABLE_DEPRECATION_WARNINGS -#include "clutter-list-model.h" - -#include "clutter-model.h" -#include "clutter-model-private.h" -#include "clutter-private.h" -#include "clutter-debug.h" - -#define CLUTTER_TYPE_LIST_MODEL_ITER \ - (clutter_list_model_iter_get_type()) -#define CLUTTER_LIST_MODEL_ITER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - CLUTTER_TYPE_LIST_MODEL_ITER, \ - ClutterListModelIter)) -#define CLUTTER_IS_LIST_MODEL_ITER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), \ - CLUTTER_TYPE_LIST_MODEL_ITER)) -#define CLUTTER_LIST_MODEL_ITER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), \ - CLUTTER_TYPE_LIST_MODEL_ITER, \ - ClutterListModelIterClass)) -#define CLUTTER_IS_LIST_MODEL_ITER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), \ - CLUTTER_TYPE_LIST_MODEL_ITER)) -#define CLUTTER_LIST_MODEL_ITER_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), \ - CLUTTER_TYPE_LIST_MODEL_ITER, \ - ClutterListModelIterClass)) - -typedef struct _ClutterListModelIter ClutterListModelIter; -typedef struct _ClutterModelIterClass ClutterListModelIterClass; - -struct _ClutterListModelPrivate -{ - GSequence *sequence; - - ClutterModelIter *temp_iter; -}; - -struct _ClutterListModelIter -{ - ClutterModelIter parent_instance; - - GSequenceIter *seq_iter; -}; - - - -GType clutter_list_model_iter_get_type (void); - -/* - * ClutterListModel - */ - -G_DEFINE_TYPE (ClutterListModelIter, - clutter_list_model_iter, - CLUTTER_TYPE_MODEL_ITER) - -static void -clutter_list_model_iter_get_value (ClutterModelIter *iter, - guint column, - GValue *value) -{ - ClutterListModelIter *iter_default; - GValue *values; - GValue *iter_value; - GValue real_value = G_VALUE_INIT; - gboolean converted = FALSE; - - iter_default = CLUTTER_LIST_MODEL_ITER (iter); - g_assert (iter_default->seq_iter != NULL); - - values = g_sequence_get (iter_default->seq_iter); - iter_value = &values[column]; - g_assert (iter_value != NULL); - - if (!g_type_is_a (G_VALUE_TYPE (value), G_VALUE_TYPE (iter_value))) - { - if (!g_value_type_compatible (G_VALUE_TYPE (value), - G_VALUE_TYPE (iter_value)) && - !g_value_type_compatible (G_VALUE_TYPE (iter_value), - G_VALUE_TYPE (value))) - { - g_warning ("%s: Unable to convert from %s to %s", - G_STRLOC, - g_type_name (G_VALUE_TYPE (value)), - g_type_name (G_VALUE_TYPE (iter_value))); - return; - } - - if (!g_value_transform (iter_value, &real_value)) - { - g_warning ("%s: Unable to make conversion from %s to %s", - G_STRLOC, - g_type_name (G_VALUE_TYPE (value)), - g_type_name (G_VALUE_TYPE (iter_value))); - g_value_unset (&real_value); - } - - converted = TRUE; - } - - if (converted) - { - g_value_copy (&real_value, value); - g_value_unset (&real_value); - } - else - g_value_copy (iter_value, value); -} - -static void -clutter_list_model_iter_set_value (ClutterModelIter *iter, - guint column, - const GValue *value) -{ - ClutterListModelIter *iter_default; - GValue *values; - GValue *iter_value; - GValue real_value = G_VALUE_INIT; - gboolean converted = FALSE; - - iter_default = CLUTTER_LIST_MODEL_ITER (iter); - g_assert (iter_default->seq_iter != NULL); - - values = g_sequence_get (iter_default->seq_iter); - iter_value = &values[column]; - g_assert (iter_value != NULL); - - if (!g_type_is_a (G_VALUE_TYPE (value), G_VALUE_TYPE (iter_value))) - { - if (!g_value_type_compatible (G_VALUE_TYPE (value), - G_VALUE_TYPE (iter_value)) && - !g_value_type_compatible (G_VALUE_TYPE (iter_value), - G_VALUE_TYPE (value))) - { - g_warning ("%s: Unable to convert from %s to %s\n", - G_STRLOC, - g_type_name (G_VALUE_TYPE (value)), - g_type_name (G_VALUE_TYPE (iter_value))); - return; - } - - if (!g_value_transform (value, &real_value)) - { - g_warning ("%s: Unable to make conversion from %s to %s\n", - G_STRLOC, - g_type_name (G_VALUE_TYPE (value)), - g_type_name (G_VALUE_TYPE (iter_value))); - g_value_unset (&real_value); - } - - converted = TRUE; - } - - if (converted) - { - g_value_copy (&real_value, iter_value); - g_value_unset (&real_value); - } - else - g_value_copy (value, iter_value); -} - -static gboolean -clutter_list_model_iter_is_first (ClutterModelIter *iter) -{ - ClutterListModelIter *iter_default; - ClutterModel *model; - ClutterModelIter *temp_iter; - GSequence *sequence; - GSequenceIter *begin, *end; - - iter_default = CLUTTER_LIST_MODEL_ITER (iter); - g_assert (iter_default->seq_iter != NULL); - - model = clutter_model_iter_get_model (iter); - - sequence = CLUTTER_LIST_MODEL (model)->priv->sequence; - - begin = g_sequence_get_begin_iter (sequence); - end = iter_default->seq_iter; - - temp_iter = CLUTTER_LIST_MODEL (model)->priv->temp_iter; - - while (!g_sequence_iter_is_begin (begin)) - { - CLUTTER_LIST_MODEL_ITER (temp_iter)->seq_iter = begin; - - if (clutter_model_filter_iter (model, temp_iter)) - { - end = begin; - break; - } - - begin = g_sequence_iter_next (begin); - } - - /* This is because the 'begin_iter' is always *before* the last valid - * iter, otherwise we'd have endless loops - */ - end = g_sequence_iter_prev (end); - - return iter_default->seq_iter == end; -} - -static gboolean -clutter_list_model_iter_is_last (ClutterModelIter *iter) -{ - ClutterListModelIter *iter_default; - ClutterModelIter *temp_iter; - ClutterModel *model; - GSequence *sequence; - GSequenceIter *begin, *end; - - iter_default = CLUTTER_LIST_MODEL_ITER (iter); - g_assert (iter_default->seq_iter != NULL); - - if (g_sequence_iter_is_end (iter_default->seq_iter)) - return TRUE; - - model = clutter_model_iter_get_model (iter); - - sequence = CLUTTER_LIST_MODEL (model)->priv->sequence; - - begin = g_sequence_get_end_iter (sequence); - begin = g_sequence_iter_prev (begin); - end = iter_default->seq_iter; - - temp_iter = CLUTTER_LIST_MODEL (model)->priv->temp_iter; - - while (!g_sequence_iter_is_begin (begin)) - { - CLUTTER_LIST_MODEL_ITER (temp_iter)->seq_iter = begin; - - if (clutter_model_filter_iter (model, temp_iter)) - { - end = begin; - break; - } - - begin = g_sequence_iter_prev (begin); - } - - /* This is because the 'end_iter' is always *after* the last valid iter. - * Otherwise we'd have endless loops - */ - end = g_sequence_iter_next (end); - - return iter_default->seq_iter == end; -} - -static ClutterModelIter * -clutter_list_model_iter_next (ClutterModelIter *iter) -{ - ClutterListModelIter *iter_default; - ClutterModelIter *temp_iter; - ClutterModel *model = NULL; - GSequenceIter *filter_next; - guint row; - - iter_default = CLUTTER_LIST_MODEL_ITER (iter); - g_assert (iter_default->seq_iter != NULL); - - model = clutter_model_iter_get_model (iter); - row = clutter_model_iter_get_row (iter); - - filter_next = g_sequence_iter_next (iter_default->seq_iter); - g_assert (filter_next != NULL); - - temp_iter = CLUTTER_LIST_MODEL (model)->priv->temp_iter; - - while (!g_sequence_iter_is_end (filter_next)) - { - CLUTTER_LIST_MODEL_ITER (temp_iter)->seq_iter = filter_next; - - if (clutter_model_filter_iter (model, temp_iter)) - { - row += 1; - break; - } - - filter_next = g_sequence_iter_next (filter_next); - } - - if (g_sequence_iter_is_end (filter_next)) - row += 1; - - /* update the iterator and return it */ - _clutter_model_iter_set_row (CLUTTER_MODEL_ITER (iter_default), row); - iter_default->seq_iter = filter_next; - - return CLUTTER_MODEL_ITER (iter_default); -} - -static ClutterModelIter * -clutter_list_model_iter_prev (ClutterModelIter *iter) -{ - ClutterListModelIter *iter_default; - ClutterModelIter *temp_iter; - ClutterModel *model; - GSequenceIter *filter_prev; - guint row; - - iter_default = CLUTTER_LIST_MODEL_ITER (iter); - g_assert (iter_default->seq_iter != NULL); - - model = clutter_model_iter_get_model (iter); - row = clutter_model_iter_get_row (iter); - - filter_prev = g_sequence_iter_prev (iter_default->seq_iter); - g_assert (filter_prev != NULL); - - temp_iter = CLUTTER_LIST_MODEL (model)->priv->temp_iter; - - while (!g_sequence_iter_is_begin (filter_prev)) - { - CLUTTER_LIST_MODEL_ITER (temp_iter)->seq_iter = filter_prev; - - if (clutter_model_filter_iter (model, temp_iter)) - { - row -= 1; - break; - } - - filter_prev = g_sequence_iter_prev (filter_prev); - } - - if (g_sequence_iter_is_begin (filter_prev)) - row -= 1; - - /* update the iterator and return it */ - _clutter_model_iter_set_row (CLUTTER_MODEL_ITER (iter_default), row); - iter_default->seq_iter = filter_prev; - - return CLUTTER_MODEL_ITER (iter_default); -} - -static ClutterModelIter * -clutter_list_model_iter_copy (ClutterModelIter *iter) -{ - ClutterListModelIter *iter_default; - ClutterListModelIter *iter_copy; - ClutterModel *model; - guint row; - - iter_default = CLUTTER_LIST_MODEL_ITER (iter); - - model = clutter_model_iter_get_model (iter); - row = clutter_model_iter_get_row (iter) - 1; - - iter_copy = g_object_new (CLUTTER_TYPE_LIST_MODEL_ITER, - "model", model, - "row", row, - NULL); - - /* this is safe, because the seq_iter pointer on the passed - * iterator will be always be overwritten in ::next or ::prev - */ - iter_copy->seq_iter = iter_default->seq_iter; - - return CLUTTER_MODEL_ITER (iter_copy); -} - -static void -clutter_list_model_iter_class_init (ClutterListModelIterClass *klass) -{ - ClutterModelIterClass *iter_class = CLUTTER_MODEL_ITER_CLASS (klass); - - iter_class->get_value = clutter_list_model_iter_get_value; - iter_class->set_value = clutter_list_model_iter_set_value; - iter_class->is_first = clutter_list_model_iter_is_first; - iter_class->is_last = clutter_list_model_iter_is_last; - iter_class->next = clutter_list_model_iter_next; - iter_class->prev = clutter_list_model_iter_prev; - iter_class->copy = clutter_list_model_iter_copy; -} - -static void -clutter_list_model_iter_init (ClutterListModelIter *iter) -{ - iter->seq_iter = NULL; -} - -/* - * ClutterListModel - */ - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterListModel, clutter_list_model, CLUTTER_TYPE_MODEL) - -static ClutterModelIter * -clutter_list_model_get_iter_at_row (ClutterModel *model, - guint row) -{ - ClutterListModel *model_default = CLUTTER_LIST_MODEL (model); - GSequence *sequence = model_default->priv->sequence; - GSequenceIter *filter_next; - gint seq_length = g_sequence_get_length (sequence); - ClutterListModelIter *retval; - gint count = -1; - - if (row >= seq_length) - return NULL; - - retval = g_object_new (CLUTTER_TYPE_LIST_MODEL_ITER, - "model", model, - "row", row, - NULL); - - /* short-circuit in case we don't have a filter in place */ - if (!clutter_model_get_filter_set (model)) - { - retval->seq_iter = g_sequence_get_iter_at_pos (sequence, row); - - return CLUTTER_MODEL_ITER (retval); - } - - filter_next = g_sequence_get_begin_iter (sequence); - g_assert (filter_next != NULL); - - while (!g_sequence_iter_is_end (filter_next)) - { - retval->seq_iter = filter_next; - - if (clutter_model_filter_iter (model, CLUTTER_MODEL_ITER (retval))) - { - /* We've found a row that is valid under the filter */ - count++; - if (count == row) - break; - } - - filter_next = g_sequence_iter_next (filter_next); - } - - if (count != row) - { - g_object_unref (retval); - return NULL; - } - return CLUTTER_MODEL_ITER (retval); -} - -static ClutterModelIter * -clutter_list_model_insert_row (ClutterModel *model, - gint index_) -{ - ClutterListModel *model_default = CLUTTER_LIST_MODEL (model); - GSequence *sequence = model_default->priv->sequence; - ClutterListModelIter *retval; - guint n_columns, i, pos; - GValue *values; - GSequenceIter *seq_iter; - - n_columns = clutter_model_get_n_columns (model); - values = g_new0 (GValue, n_columns); - - for (i = 0; i < n_columns; i++) - g_value_init (&values[i], clutter_model_get_column_type (model, i)); - - if (index_ < 0) - { - seq_iter = g_sequence_append (sequence, values); - pos = g_sequence_get_length (sequence) - 1; - } - else if (index_ == 0) - { - seq_iter = g_sequence_prepend (sequence, values); - pos = 0; - } - else - { - seq_iter = g_sequence_get_iter_at_pos (sequence, index_); - seq_iter = g_sequence_insert_before (seq_iter, values); - pos = index_; - } - - retval = g_object_new (CLUTTER_TYPE_LIST_MODEL_ITER, - "model", model, - "row", pos, - NULL); - retval->seq_iter = seq_iter; - - return CLUTTER_MODEL_ITER (retval); -} - -static void -clutter_list_model_remove_row (ClutterModel *model, - guint row) -{ - ClutterListModel *model_default = CLUTTER_LIST_MODEL (model); - GSequence *sequence = model_default->priv->sequence; - GSequenceIter *seq_iter; - guint pos = 0; - - seq_iter = g_sequence_get_begin_iter (sequence); - while (!g_sequence_iter_is_end (seq_iter)) - { - if (clutter_model_filter_row (model, pos)) - { - if (pos == row) - { - ClutterModelIter *iter; - - iter = g_object_new (CLUTTER_TYPE_LIST_MODEL_ITER, - "model", model, - "row", pos, - NULL); - CLUTTER_LIST_MODEL_ITER (iter)->seq_iter = seq_iter; - - /* the actual row is removed from the sequence inside - * the ::row-removed signal class handler, so that every - * handler connected to ::row-removed will still get - * a valid iterator, and every signal connected to - * ::row-removed with the AFTER flag will get an updated - * model - */ - g_signal_emit_by_name (model, "row-removed", iter); - - g_object_unref (iter); - - break; - } - } - - pos += 1; - seq_iter = g_sequence_iter_next (seq_iter); - } -} - -typedef struct -{ - ClutterModel *model; - guint column; - ClutterModelSortFunc func; - gpointer data; -} SortClosure; - -static gint -sort_model_default (gconstpointer a, - gconstpointer b, - gpointer data) -{ - const GValue *row_a = a; - const GValue *row_b = b; - SortClosure *clos = data; - - return clos->func (clos->model, - &row_a[clos->column], - &row_b[clos->column], - clos->data); -} - -static void -clutter_list_model_resort (ClutterModel *model, - ClutterModelSortFunc func, - gpointer data) -{ - SortClosure sort_closure = { NULL, 0, NULL, NULL }; - - sort_closure.model = model; - sort_closure.column = clutter_model_get_sorting_column (model); - sort_closure.func = func; - sort_closure.data = data; - - g_sequence_sort (CLUTTER_LIST_MODEL (model)->priv->sequence, - sort_model_default, - &sort_closure); -} - -static guint -clutter_list_model_get_n_rows (ClutterModel *model) -{ - ClutterListModel *list_model = CLUTTER_LIST_MODEL (model); - - /* short-circuit in case we don't have a filter in place */ - if (!clutter_model_get_filter_set (model)) - return g_sequence_get_length (list_model->priv->sequence); - - return CLUTTER_MODEL_CLASS (clutter_list_model_parent_class)->get_n_rows (model); -} - -static void -clutter_list_model_row_removed (ClutterModel *model, - ClutterModelIter *iter) -{ - ClutterListModelIter *iter_default; - guint i, n_columns; - GValue *values; - - n_columns = clutter_model_get_n_columns (model); - - iter_default = CLUTTER_LIST_MODEL_ITER (iter); - - values = g_sequence_get (iter_default->seq_iter); - - for (i = 0; i < n_columns; i++) - g_value_unset (&values[i]); - - free (values); - - g_sequence_remove (iter_default->seq_iter); - iter_default->seq_iter = NULL; -} - -static void -clutter_list_model_finalize (GObject *gobject) -{ - ClutterListModel *model = CLUTTER_LIST_MODEL (gobject); - GSequence *sequence = model->priv->sequence; - GSequenceIter *iter; - guint n_columns, i; - - n_columns = clutter_model_get_n_columns (CLUTTER_MODEL (gobject)); - - iter = g_sequence_get_begin_iter (sequence); - while (!g_sequence_iter_is_end (iter)) - { - GValue *values = g_sequence_get (iter); - - for (i = 0; i < n_columns; i++) - g_value_unset (&values[i]); - - free (values); - - iter = g_sequence_iter_next (iter); - } - g_sequence_free (sequence); - - G_OBJECT_CLASS (clutter_list_model_parent_class)->finalize (gobject); -} - -static void -clutter_list_model_dispose (GObject *gobject) -{ - ClutterListModel *model = CLUTTER_LIST_MODEL (gobject); - - if (model->priv->temp_iter) - { - g_object_unref (model->priv->temp_iter); - model->priv->temp_iter = NULL; - } - - G_OBJECT_CLASS (clutter_list_model_parent_class)->dispose (gobject); -} - -static void -clutter_list_model_class_init (ClutterListModelClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterModelClass *model_class = CLUTTER_MODEL_CLASS (klass); - - gobject_class->finalize = clutter_list_model_finalize; - gobject_class->dispose = clutter_list_model_dispose; - - model_class->get_iter_at_row = clutter_list_model_get_iter_at_row; - model_class->insert_row = clutter_list_model_insert_row; - model_class->remove_row = clutter_list_model_remove_row; - model_class->resort = clutter_list_model_resort; - model_class->get_n_rows = clutter_list_model_get_n_rows; - model_class->row_removed = clutter_list_model_row_removed; -} - -static void -clutter_list_model_init (ClutterListModel *model) -{ - model->priv = clutter_list_model_get_instance_private (model); - - model->priv->sequence = g_sequence_new (NULL); - model->priv->temp_iter = g_object_new (CLUTTER_TYPE_LIST_MODEL_ITER, - "model", - model, - NULL); -} - -/** - * clutter_list_model_new: - * @n_columns: number of columns in the model - * @...: @n_columns number of #GType and string pairs - * - * Creates a new default model with @n_columns columns with the types - * and names passed in. - * - * For example: - * - * - * model = clutter_list_model_new (3, - * G_TYPE_INT, "Score", - * G_TYPE_STRING, "Team", - * GDK_TYPE_PIXBUF, "Logo"); - * - * - * will create a new #ClutterModel with three columns of type int, - * string and #GdkPixbuf respectively. - * - * Note that the name of the column can be set to %NULL, in which case - * the canonical name of the type held by the column will be used as - * the title. - * - * Return value: a new #ClutterListModel - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListStore instead - */ -ClutterModel * -clutter_list_model_new (guint n_columns, - ...) -{ - ClutterModel *model; - va_list args; - gint i; - - g_return_val_if_fail (n_columns > 0, NULL); - - model = g_object_new (CLUTTER_TYPE_LIST_MODEL, NULL); - _clutter_model_set_n_columns (model, n_columns, TRUE, TRUE); - - va_start (args, n_columns); - - for (i = 0; i < n_columns; i++) - { - GType type = va_arg (args, GType); - const gchar *name = va_arg (args, gchar*); - - if (!_clutter_model_check_type (type)) - { - g_warning ("%s: Invalid type %s\n", G_STRLOC, g_type_name (type)); - g_object_unref (model); - model = NULL; - goto out; - } - - _clutter_model_set_column_type (model, i, type); - _clutter_model_set_column_name (model, i, name); - } - - out: - va_end (args); - return model; -} - -/** - * clutter_list_model_newv: - * @n_columns: number of columns in the model - * @types: (array length=n_columns): an array of #GType types for the columns, from first to last - * @names: (array length=n_columns): an array of names for the columns, from first to last - * - * Non-vararg version of clutter_list_model_new(). This function is - * useful for language bindings. - * - * Return value: (transfer full): a new default #ClutterModel - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListStore instead - */ -ClutterModel * -clutter_list_model_newv (guint n_columns, - GType *types, - const gchar * const names[]) -{ - ClutterModel *model; - gint i; - - g_return_val_if_fail (n_columns > 0, NULL); - - model = g_object_new (CLUTTER_TYPE_LIST_MODEL, NULL); - _clutter_model_set_n_columns (model, n_columns, TRUE, TRUE); - - for (i = 0; i < n_columns; i++) - { - if (!_clutter_model_check_type (types[i])) - { - g_warning ("%s: Invalid type %s\n", G_STRLOC, g_type_name (types[i])); - g_object_unref (model); - return NULL; - } - - _clutter_model_set_column_type (model, i, types[i]); - _clutter_model_set_column_name (model, i, names[i]); - } - - return model; -} diff --git a/clutter/clutter/deprecated/clutter-list-model.h b/clutter/clutter/deprecated/clutter-list-model.h deleted file mode 100644 index 021b3cde4..000000000 --- a/clutter/clutter/deprecated/clutter-list-model.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * Neil Jagdish Patel - * Emmanuele Bassi - * - * Copyright (C) 2006 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * NB: Inspiration for column storage taken from GtkListStore - */ - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __CLUTTER_LIST_MODEL_H__ -#define __CLUTTER_LIST_MODEL_H__ - -#include - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_LIST_MODEL (clutter_list_model_get_type ()) -#define CLUTTER_LIST_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_LIST_MODEL, ClutterListModel)) -#define CLUTTER_IS_LIST_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_LIST_MODEL)) -#define CLUTTER_LIST_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_LIST_MODEL, ClutterListModeClass)) -#define CLUTTER_IS_LIST_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_LIST_MODEL)) -#define CLUTTER_LIST_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_LIST_MODEL, ClutterListModeClass)) - -typedef struct _ClutterListModel ClutterListModel; -typedef struct _ClutterListModelPrivate ClutterListModelPrivate; -typedef struct _ClutterListModelClass ClutterListModelClass; - -/** - * ClutterListModel: - * - * The #ClutterListModel struct contains only private data. - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListStore instead - */ -struct _ClutterListModel -{ - /*< private >*/ - ClutterModel parent_instance; - - ClutterListModelPrivate *priv; -}; - -/** - * ClutterListModelClass: - * - * The #ClutterListModelClass struct contains only private data. - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListStore instead - */ -struct _ClutterListModelClass -{ - /*< private >*/ - ClutterModelClass parent_class; -}; - -CLUTTER_DEPRECATED_IN_1_24_FOR(g_list_store_get_type) -GType clutter_list_model_get_type (void) G_GNUC_CONST; - -CLUTTER_DEPRECATED_IN_1_24_FOR(g_list_store_new) -ClutterModel *clutter_list_model_new (guint n_columns, - ...); -CLUTTER_DEPRECATED_IN_1_24_FOR(g_list_store_new) -ClutterModel *clutter_list_model_newv (guint n_columns, - GType *types, - const gchar * const names[]); - -G_END_DECLS - -#endif /* __CLUTTER_LIST_MODEL_H__ */ diff --git a/clutter/clutter/deprecated/clutter-main.h b/clutter/clutter/deprecated/clutter-main.h deleted file mode 100644 index 257ac5a70..000000000 --- a/clutter/clutter/deprecated/clutter-main.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2011 Intel Corp - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __CLUTTER_MAIN_DEPRECATED_H__ -#define __CLUTTER_MAIN_DEPRECATED_H__ - -#include -#include - -G_BEGIN_DECLS - -CLUTTER_DEPRECATED_IN_1_10 -void clutter_threads_init (void); - -CLUTTER_DEPRECATED_IN_1_12 -void clutter_threads_enter (void); - -CLUTTER_DEPRECATED_IN_1_12 -void clutter_threads_leave (void); - -CLUTTER_DEPRECATED_IN_1_6 -guint clutter_threads_add_frame_source (guint fps, - GSourceFunc func, - gpointer data); -CLUTTER_DEPRECATED_IN_1_6 -guint clutter_threads_add_frame_source_full (gint priority, - guint fps, - GSourceFunc func, - gpointer data, - GDestroyNotify notify); - -CLUTTER_DEPRECATED_IN_1_8_FOR(clutter_stage_set_motion_events_enabled) -void clutter_set_motion_events_enabled (gboolean enable); - -CLUTTER_DEPRECATED_IN_1_8_FOR(clutter_stage_get_motion_events_enabled) -gboolean clutter_get_motion_events_enabled (void); - -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_stage_ensure_redraw) -void clutter_redraw (ClutterStage *stage); - -CLUTTER_DEPRECATED_IN_1_10_FOR(cogl_pango_font_map_clear_glyph_cache) -void clutter_clear_glyph_cache (void); - -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_backend_set_font_options) -void clutter_set_font_flags (ClutterFontFlags flags); - -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_backend_get_font_options) -ClutterFontFlags clutter_get_font_flags (void); - -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_device_manager_get_device) -ClutterInputDevice * clutter_get_input_device_for_id (gint id_); - -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_input_device_grab) -void clutter_grab_pointer_for_device (ClutterActor *actor, - gint id_); - -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_input_device_ungrab) -void clutter_ungrab_pointer_for_device (gint id_); - -CLUTTER_DEPRECATED_IN_1_10 -void clutter_set_default_frame_rate (guint frames_per_sec); - -CLUTTER_DEPRECATED_IN_1_10 -gulong clutter_get_timestamp (void); - -CLUTTER_DEPRECATED_IN_1_10 -gboolean clutter_get_debug_enabled (void); - -CLUTTER_DEPRECATED_IN_1_10 -gboolean clutter_get_show_fps (void); - -G_END_DECLS - -#endif /* __CLUTTER_MAIN_DEPRECATED_H__ */ diff --git a/clutter/clutter/deprecated/clutter-media.c b/clutter/clutter/deprecated/clutter-media.c deleted file mode 100644 index 75c49333f..000000000 --- a/clutter/clutter/deprecated/clutter-media.c +++ /dev/null @@ -1,666 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By: Matthew Allum - * Emmanuele Bassi - * - * Copyright (C) 2006 OpenedHand - * Copyright (C) 2009 Intel Corp. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -/** - * SECTION:clutter-media - * @short_description: An interface for controlling playback of media data - * - * #ClutterMedia is an interface for controlling playback of media sources. - * - * Clutter core does not provide an implementation of this interface, but - * other integration libraries like Clutter-GStreamer implement it to offer - * a uniform API for applications. - * - * #ClutterMedia is available since Clutter 0.2 - * - * #ClutterMedia is deprecated since Clutter 1.12. Use the Clutter-GStreamer - * API directly instead. - */ - -#ifdef HAVE_CONFIG_H -#include "clutter-build-config.h" -#endif - -#define CLUTTER_DISABLE_DEPRECATION_WARNINGS - -#include "clutter-debug.h" -#include "clutter-enum-types.h" -#include "clutter-marshal.h" -#include "clutter-media.h" -#include "clutter-main.h" -#include "clutter-private.h" /* for DBG */ - -enum -{ - EOS_SIGNAL, - ERROR_SIGNAL, /* can't be called 'ERROR' otherwise it clashes with wingdi.h */ - - LAST_SIGNAL -}; - -static guint media_signals[LAST_SIGNAL] = { 0, }; - -typedef ClutterMediaIface ClutterMediaInterface; - -G_DEFINE_INTERFACE (ClutterMedia, clutter_media, G_TYPE_OBJECT); - -static void -clutter_media_default_init (ClutterMediaInterface *iface) -{ - GParamSpec *pspec = NULL; - - /** - * ClutterMedia:uri: - * - * The location of a media file, expressed as a valid URI. - * - * Since: 0.2 - * - * Deprecated: 1.12 - */ - pspec = g_param_spec_string ("uri", - P_("URI"), - P_("URI of a media file"), - NULL, - CLUTTER_PARAM_READWRITE | - G_PARAM_DEPRECATED); - g_object_interface_install_property (iface, pspec); - - /** - * ClutterMedia:playing: - * - * Whether the #ClutterMedia actor is playing. - * - * Since: 0.2 - * - * Deprecated: 1.12 - */ - pspec = g_param_spec_boolean ("playing", - P_("Playing"), - P_("Whether the actor is playing"), - FALSE, - CLUTTER_PARAM_READWRITE | - G_PARAM_DEPRECATED); - g_object_interface_install_property (iface, pspec); - - /** - * ClutterMedia:progress: - * - * The current progress of the playback, as a normalized - * value between 0.0 and 1.0. - * - * Since: 1.0 - * - * Deprecated: 1.12 - */ - pspec = g_param_spec_double ("progress", - P_("Progress"), - P_("Current progress of the playback"), - 0.0, 1.0, 0.0, - CLUTTER_PARAM_READWRITE | - G_PARAM_DEPRECATED); - g_object_interface_install_property (iface, pspec); - - /** - * ClutterMedia:subtitle-uri: - * - * The location of a subtitle file, expressed as a valid URI. - * - * Since: 1.2 - * - * Deprecated: 1.12 - */ - pspec = g_param_spec_string ("subtitle-uri", - P_("Subtitle URI"), - P_("URI of a subtitle file"), - NULL, - CLUTTER_PARAM_READWRITE | - G_PARAM_DEPRECATED); - g_object_interface_install_property (iface, pspec); - - /** - * ClutterMedia:subtitle-font-name: - * - * The font used to display subtitles. The font description has to - * follow the same grammar as the one recognized by - * pango_font_description_from_string(). - * - * Since: 1.2 - * - * Deprecated: 1.12 - */ - pspec = g_param_spec_string ("subtitle-font-name", - P_("Subtitle Font Name"), - P_("The font used to display subtitles"), - NULL, - CLUTTER_PARAM_READWRITE | - G_PARAM_DEPRECATED); - g_object_interface_install_property (iface, pspec); - - /** - * ClutterMedia:audio-volume: - * - * The volume of the audio, as a normalized value between - * 0.0 and 1.0. - * - * Since: 1.0 - * - * Deprecated: 1.12 - */ - pspec = g_param_spec_double ("audio-volume", - P_("Audio Volume"), - P_("The volume of the audio"), - 0.0, 1.0, 0.5, - CLUTTER_PARAM_READWRITE | - G_PARAM_DEPRECATED); - g_object_interface_install_property (iface, pspec); - - /** - * ClutterMedia:can-seek: - * - * Whether the current stream is seekable. - * - * Since: 0.2 - * - * Deprecated: 1.12 - */ - pspec = g_param_spec_boolean ("can-seek", - P_("Can Seek"), - P_("Whether the current stream is seekable"), - FALSE, - CLUTTER_PARAM_READABLE | - G_PARAM_DEPRECATED); - g_object_interface_install_property (iface, pspec); - - /** - * ClutterMedia:buffer-fill: - * - * The fill level of the buffer for the current stream, - * as a value between 0.0 and 1.0. - * - * Since: 1.0 - * - * Deprecated: 1.12 - */ - pspec = g_param_spec_double ("buffer-fill", - P_("Buffer Fill"), - P_("The fill level of the buffer"), - 0.0, 1.0, 0.0, - CLUTTER_PARAM_READABLE | - G_PARAM_DEPRECATED); - g_object_interface_install_property (iface, pspec); - - /** - * ClutterMedia:duration: - * - * The duration of the current stream, in seconds - * - * Since: 0.2 - * - * Deprecated: 1.12 - */ - pspec = g_param_spec_double ("duration", - P_("Duration"), - P_("The duration of the stream, in seconds"), - 0, G_MAXDOUBLE, 0, - CLUTTER_PARAM_READABLE); - g_object_interface_install_property (iface, pspec); - - /** - * ClutterMedia::eos: - * @media: the #ClutterMedia instance that received the signal - * - * The ::eos signal is emitted each time the media stream ends. - * - * Since: 0.2 - * - * Deprecated: 1.12 - */ - media_signals[EOS_SIGNAL] = - g_signal_new (I_("eos"), - CLUTTER_TYPE_MEDIA, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterMediaIface, eos), - NULL, NULL, - _clutter_marshal_VOID__VOID, - G_TYPE_NONE, 0); - /** - * ClutterMedia::error: - * @media: the #ClutterMedia instance that received the signal - * @error: the #GError - * - * The ::error signal is emitted each time an error occurred. - * - * Since: 0.2 - * - * Deprecated: 1.12 - */ - media_signals[ERROR_SIGNAL] = - g_signal_new (I_("error"), - CLUTTER_TYPE_MEDIA, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterMediaIface, error), - NULL, NULL, - _clutter_marshal_VOID__BOXED, - G_TYPE_NONE, 1, - G_TYPE_ERROR); -} - - -/** - * clutter_media_set_uri: - * @media: a #ClutterMedia - * @uri: the URI of the media stream - * - * Sets the URI of @media to @uri. - * - * Since: 0.2 - * - * Deprecated: 1.12 - */ -void -clutter_media_set_uri (ClutterMedia *media, - const gchar *uri) -{ - g_return_if_fail (CLUTTER_IS_MEDIA(media)); - - g_object_set (G_OBJECT (media), "uri", uri, NULL); -} - -/** - * clutter_media_get_uri: - * @media: a #ClutterMedia - * - * Retrieves the URI from @media. - * - * Return value: the URI of the media stream. Use free() - * to free the returned string - * - * Since: 0.2 - * - * Deprecated: 1.12 - */ -gchar * -clutter_media_get_uri (ClutterMedia *media) -{ - gchar *retval = NULL; - - g_return_val_if_fail (CLUTTER_IS_MEDIA(media), NULL); - - g_object_get (G_OBJECT (media), "uri", &retval, NULL); - - return retval; -} - -/** - * clutter_media_set_playing: - * @media: a #ClutterMedia - * @playing: %TRUE to start playing - * - * Starts or stops playing of @media. - - * The implementation might be asynchronous, so the way to know whether - * the actual playing state of the @media is to use the #GObject::notify - * signal on the #ClutterMedia:playing property and then retrieve the - * current state with clutter_media_get_playing(). ClutterGstVideoTexture - * in clutter-gst is an example of such an asynchronous implementation. - * - * Since: 0.2 - * - * Deprecated: 1.12 - */ -void -clutter_media_set_playing (ClutterMedia *media, - gboolean playing) -{ - g_return_if_fail (CLUTTER_IS_MEDIA(media)); - - g_object_set (G_OBJECT (media), "playing", playing, NULL); -} - -/** - * clutter_media_get_playing: - * @media: A #ClutterMedia object - * - * Retrieves the playing status of @media. - * - * Return value: %TRUE if playing, %FALSE if stopped. - * - * Since: 0.2 - * - * Deprecated: 1.12 - */ -gboolean -clutter_media_get_playing (ClutterMedia *media) -{ - gboolean is_playing = FALSE; - - g_return_val_if_fail (CLUTTER_IS_MEDIA (media), FALSE); - - g_object_get (G_OBJECT (media), "playing", &is_playing, NULL); - - return is_playing; -} - -/** - * clutter_media_set_progress: - * @media: a #ClutterMedia - * @progress: the progress of the playback, between 0.0 and 1.0 - * - * Sets the playback progress of @media. The @progress is - * a normalized value between 0.0 (begin) and 1.0 (end). - * - * Since: 1.0 - * - * Deprecated: 1.12 - */ -void -clutter_media_set_progress (ClutterMedia *media, - gdouble progress) -{ - g_return_if_fail (CLUTTER_IS_MEDIA (media)); - - g_object_set (G_OBJECT (media), "progress", progress, NULL); -} - -/** - * clutter_media_get_progress: - * @media: a #ClutterMedia - * - * Retrieves the playback progress of @media. - * - * Return value: the playback progress, between 0.0 and 1.0 - * - * Since: 1.0 - * - * Deprecated: 1.12 - */ -gdouble -clutter_media_get_progress (ClutterMedia *media) -{ - gdouble retval = 0.0; - - g_return_val_if_fail (CLUTTER_IS_MEDIA (media), 0); - - g_object_get (G_OBJECT (media), "progress", &retval, NULL); - - return retval; -} - -/** - * clutter_media_set_subtitle_uri: - * @media: a #ClutterMedia - * @uri: the URI of a subtitle file - * - * Sets the location of a subtitle file to display while playing @media. - * - * Since: 1.2 - * - * Deprecated: 1.12 - */ -void -clutter_media_set_subtitle_uri (ClutterMedia *media, - const char *uri) -{ - g_return_if_fail (CLUTTER_IS_MEDIA (media)); - - g_object_set (G_OBJECT (media), "subtitle-uri", uri, NULL); -} - -/** - * clutter_media_get_subtitle_uri: - * @media: a #ClutterMedia - * - * Retrieves the URI of the subtitle file in use. - * - * Return value: the URI of the subtitle file. Use free() - * to free the returned string - * - * Since: 1.2 - * - * Deprecated: 1.12 - */ -gchar * -clutter_media_get_subtitle_uri (ClutterMedia *media) -{ - gchar *retval = NULL; - - g_return_val_if_fail (CLUTTER_IS_MEDIA(media), NULL); - - g_object_get (G_OBJECT (media), "subtitle-uri", &retval, NULL); - - return retval; -} - -/** - * clutter_media_set_subtitle_font_name: - * @media: a #ClutterMedia - * @font_name: a font name, or %NULL to set the default font name - * - * Sets the font used by the subtitle renderer. The @font_name string must be - * either %NULL, which means that the default font name of the underlying - * implementation will be used; or must follow the grammar recognized by - * pango_font_description_from_string() like: - * - * |[ - * clutter_media_set_subtitle_font_name (media, "Sans 24pt"); - * ]| - * - * Since: 1.2 - * - * Deprecated: 1.12 - */ -void -clutter_media_set_subtitle_font_name (ClutterMedia *media, - const char *font_name) -{ - g_return_if_fail (CLUTTER_IS_MEDIA (media)); - - g_object_set (G_OBJECT (media), "subtitle-font-name", font_name, NULL); -} - -/** - * clutter_media_get_subtitle_font_name: - * @media: a #ClutterMedia - * - * Retrieves the font name currently used. - * - * Return value: a string containing the font name. Use free() - * to free the returned string - * - * Since: 1.2 - * - * Deprecated: 1.12 - */ -gchar * -clutter_media_get_subtitle_font_name (ClutterMedia *media) -{ - gchar *retval = NULL; - - g_return_val_if_fail (CLUTTER_IS_MEDIA(media), NULL); - - g_object_get (G_OBJECT (media), "subtitle-font-name", &retval, NULL); - - return retval; -} - -/** - * clutter_media_set_audio_volume: - * @media: a #ClutterMedia - * @volume: the volume as a double between 0.0 and 1.0 - * - * Sets the playback volume of @media to @volume. - * - * Since: 1.0 - * - * Deprecated: 1.12 - */ -void -clutter_media_set_audio_volume (ClutterMedia *media, - gdouble volume) -{ - g_return_if_fail (CLUTTER_IS_MEDIA(media)); - - g_object_set (G_OBJECT (media), "audio-volume", volume, NULL); -} - -/** - * clutter_media_get_audio_volume: - * @media: a #ClutterMedia - * - * Retrieves the playback volume of @media. - * - * Return value: The playback volume between 0.0 and 1.0 - * - * Since: 1.0 - * - * Deprecated: 1.12 - */ -gdouble -clutter_media_get_audio_volume (ClutterMedia *media) -{ - gdouble retval = 0.0; - - g_return_val_if_fail (CLUTTER_IS_MEDIA (media), 0.0); - - g_object_get (G_OBJECT (media), "audio-volume", &retval, NULL); - - return retval; -} - -/** - * clutter_media_get_can_seek: - * @media: a #ClutterMedia - * - * Retrieves whether @media is seekable or not. - * - * Return value: %TRUE if @media can seek, %FALSE otherwise. - * - * Since: 0.2 - * - * Deprecated: 1.12 - */ -gboolean -clutter_media_get_can_seek (ClutterMedia *media) -{ - gboolean retval = FALSE; - - g_return_val_if_fail (CLUTTER_IS_MEDIA (media), FALSE); - - g_object_get (G_OBJECT (media), "can-seek", &retval, NULL); - - return retval; -} - -/** - * clutter_media_get_buffer_fill: - * @media: a #ClutterMedia - * - * Retrieves the amount of the stream that is buffered. - * - * Return value: the fill level, between 0.0 and 1.0 - * - * Since: 1.0 - * - * Deprecated: 1.12 - */ -gdouble -clutter_media_get_buffer_fill (ClutterMedia *media) -{ - gdouble retval = 0.0; - - g_return_val_if_fail (CLUTTER_IS_MEDIA (media), 0); - - g_object_get (G_OBJECT (media), "buffer-fill", &retval, NULL); - - return retval; -} - -/** - * clutter_media_get_duration: - * @media: a #ClutterMedia - * - * Retrieves the duration of the media stream that @media represents. - * - * Return value: the duration of the media stream, in seconds - * - * Since: 0.2 - * - * Deprecated: 1.12 - */ -gdouble -clutter_media_get_duration (ClutterMedia *media) -{ - gdouble retval = 0; - - g_return_val_if_fail (CLUTTER_IS_MEDIA(media), 0); - - g_object_get (G_OBJECT (media), "duration", &retval, NULL); - - return retval; -} - -/* helper funcs */ - -/** - * clutter_media_set_filename: - * @media: a #ClutterMedia - * @filename: A filename - * - * Sets the source of @media using a file path. - * - * Since: 0.2 - * - * Deprecated: 1.12 - */ -void -clutter_media_set_filename (ClutterMedia *media, - const gchar *filename) -{ - gchar *uri; - GError *uri_error = NULL; - - if (!g_path_is_absolute (filename)) - { - gchar *abs_path; - - abs_path = g_build_filename (g_get_current_dir (), filename, NULL); - uri = g_filename_to_uri (abs_path, NULL, &uri_error); - free (abs_path); - } - else - uri = g_filename_to_uri (filename, NULL, &uri_error); - - if (uri_error) - { - g_signal_emit (media, media_signals[ERROR_SIGNAL], 0, uri_error); - g_error_free (uri_error); - return; - } - - clutter_media_set_uri (media, uri); - - free (uri); -} diff --git a/clutter/clutter/deprecated/clutter-media.h b/clutter/clutter/deprecated/clutter-media.h deleted file mode 100644 index ad1068ad4..000000000 --- a/clutter/clutter/deprecated/clutter-media.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By: Matthew Allum - * Emmanuele Bassi - * - * Copyright (C) 2006 OpenedHand - * Copyright (C) 2009 Intel Corp. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __CLUTTER_MEDIA_H__ -#define __CLUTTER_MEDIA_H__ - -#include - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_MEDIA (clutter_media_get_type ()) -#define CLUTTER_MEDIA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_MEDIA, ClutterMedia)) -#define CLUTTER_IS_MEDIA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_MEDIA)) -#define CLUTTER_MEDIA_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), CLUTTER_TYPE_MEDIA, ClutterMediaIface)) - -typedef struct _ClutterMedia ClutterMedia; /* dummy typedef */ -typedef struct _ClutterMediaIface ClutterMediaIface; - -/** - * ClutterMedia: - * - * #ClutterMedia is an opaque structure whose members cannot be directly - * accessed - * - * Since: 0.2 - */ - -/** - * ClutterMediaIface: - * @eos: handler for the #ClutterMedia::eos signal - * @error: handler for the #ClutterMedia::error signal - * - * Interface vtable for #ClutterMedia implementations - * - * Since: 0.2 - */ -struct _ClutterMediaIface -{ - /*< private >*/ - GTypeInterface base_iface; - - /*< public >*/ - /* signals */ - void (* eos) (ClutterMedia *media); - void (* error) (ClutterMedia *media, - const GError *error); -}; - -CLUTTER_DEPRECATED_IN_1_12 -GType clutter_media_get_type (void) G_GNUC_CONST; - -CLUTTER_DEPRECATED_IN_1_12 -void clutter_media_set_uri (ClutterMedia *media, - const gchar *uri); -CLUTTER_DEPRECATED_IN_1_12 -gchar * clutter_media_get_uri (ClutterMedia *media); -CLUTTER_DEPRECATED_IN_1_12 -void clutter_media_set_filename (ClutterMedia *media, - const gchar *filename); - -CLUTTER_DEPRECATED_IN_1_12 -void clutter_media_set_playing (ClutterMedia *media, - gboolean playing); -CLUTTER_DEPRECATED_IN_1_12 -gboolean clutter_media_get_playing (ClutterMedia *media); -CLUTTER_DEPRECATED_IN_1_12 -void clutter_media_set_progress (ClutterMedia *media, - gdouble progress); -CLUTTER_DEPRECATED_IN_1_12 -gdouble clutter_media_get_progress (ClutterMedia *media); -CLUTTER_DEPRECATED_IN_1_12 -void clutter_media_set_subtitle_uri (ClutterMedia *media, - const gchar *uri); -CLUTTER_DEPRECATED_IN_1_12 -gchar * clutter_media_get_subtitle_uri (ClutterMedia *media); -CLUTTER_DEPRECATED_IN_1_12 -void clutter_media_set_subtitle_font_name (ClutterMedia *media, - const char *font_name); -CLUTTER_DEPRECATED_IN_1_12 -gchar * clutter_media_get_subtitle_font_name (ClutterMedia *media); -CLUTTER_DEPRECATED_IN_1_12 -void clutter_media_set_audio_volume (ClutterMedia *media, - gdouble volume); -CLUTTER_DEPRECATED_IN_1_12 -gdouble clutter_media_get_audio_volume (ClutterMedia *media); -CLUTTER_DEPRECATED_IN_1_12 -gboolean clutter_media_get_can_seek (ClutterMedia *media); -CLUTTER_DEPRECATED_IN_1_12 -gdouble clutter_media_get_buffer_fill (ClutterMedia *media); -CLUTTER_DEPRECATED_IN_1_12 -gdouble clutter_media_get_duration (ClutterMedia *media); - -G_END_DECLS - -#endif /* __CLUTTER_MEDIA_H__ */ diff --git a/clutter/clutter/deprecated/clutter-model-private.h b/clutter/clutter/deprecated/clutter-model-private.h deleted file mode 100644 index 2791c837b..000000000 --- a/clutter/clutter/deprecated/clutter-model-private.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * Neil Jagdish Patel - * Emmanuele Bassi - * - * Copyright (C) 2006 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#ifndef __CLUTTER_MODEL_PRIVATE_H__ -#define __CLUTTER_MODEL_PRIVATE_H__ - -#include "clutter-types.h" -#include "clutter-model.h" - -G_BEGIN_DECLS - -void _clutter_model_set_n_columns (ClutterModel *model, - gint n_columns, - gboolean set_types, - gboolean set_names); -gboolean _clutter_model_check_type (GType gtype); - -void _clutter_model_set_column_type (ClutterModel *model, - gint column, - GType gtype); -void _clutter_model_set_column_name (ClutterModel *model, - gint column, - const gchar *name); - -void _clutter_model_iter_set_row (ClutterModelIter *iter, - guint row); - -G_END_DECLS - -#endif /* __CLUTTER_MODEL_PRIVATE_H__ */ diff --git a/clutter/clutter/deprecated/clutter-model.c b/clutter/clutter/deprecated/clutter-model.c deleted file mode 100644 index 53ecd98d9..000000000 --- a/clutter/clutter/deprecated/clutter-model.c +++ /dev/null @@ -1,2477 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * Neil Jagdish Patel - * Emmanuele Bassi - * - * Copyright (C) 2006 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * NB: Inspiration for column storage taken from GtkListStore - */ - -/** - * SECTION:clutter-model - * @short_description: A generic model implementation - * - * #ClutterModel is a generic list model API which can be used to implement - * the model-view-controller architectural pattern in Clutter. - * - * The #ClutterModel class is a list model which can accept most GObject - * types as a column type. - * - * ## Creating a simple ClutterModel - * - * The example below shows how to create a simple list model. - * - * |[ - * enum - * { - * COLUMN_INT, - * COLUMN_STRING, - * - * N_COLUMNS - * }; - * - * { - * ClutterModel *model; - * gint i; - * - * model = clutter_list_model_new (N_COLUMNS, - * // column type, title - * G_TYPE_INT, "my integers", - * G_TYPE_STRING, "my strings"); - * for (i = 0; i < 10; i++) - * { - * gchar *string = g_strdup_printf ("String %d", i); - * clutter_model_append (model, - * COLUMN_INT, i, - * COLUMN_STRING, string, - * -1); - * free (string); - * } - * - * - * } - * ]| - * - * ## Iterating through a ClutterModel - * - * Iterating through the model consists of retrieving a new #ClutterModelIter - * pointing to the starting row, and calling clutter_model_iter_next() or - * clutter_model_iter_prev() to move forward or backwards, repectively. - * - * A valid #ClutterModelIter represents the position between two rows in the - * model. For example, the "first" iterator represents the gap immediately - * before the first row, and the "last" iterator represents the gap immediately - * after the last row. In an empty sequence, the first and last iterators are - * the same. - * - * |[ - * enum - * { - * COLUMN_INT, - * COLUMN_STRING. - * - * N_COLUMNS - * }; - * - * { - * ClutterModel *model; - * ClutterModelIter *iter = NULL; - * - * // fill the model - * model = populate_model (); - * - * // get the iterator for the first row in the model - * iter = clutter_model_get_first_iter (model); - * while (!clutter_model_iter_is_last (iter)) - * { - * print_row (iter); - * - * iter = clutter_model_iter_next (iter); - * } - * - * // Make sure to unref the iter - * g_object_unref (iter); - * } - * ]| - * - * #ClutterModel is an abstract class. Clutter provides a list model - * implementation called #ClutterListModel which has been optimised - * for insertion and look up in sorted lists. - * - * #ClutterModel is available since Clutter 0.6 - * - * ## ClutterModel custom properties for ClutterScript - * - * #ClutterModel defines a custom property "columns" for #ClutterScript - * which allows defining the column names and types. It also defines a custom - * "rows" property which allows filling the #ClutterModel with some - * data. - * - * The definition below will create a #ClutterListModel with three - * columns: the first one with name "Name" and containing strings; the - * second one with name "Score" and containing integers; the third one with - * name "Icon" and containing #ClutterTextures. The model is filled - * with three rows. A row can be defined either with an array that holds - * all columns of a row, or an object that holds "column-name" : - * "column-value" pairs. - * - * |[ - * { - * "type" : "ClutterListModel", - * "id" : "teams-model", - * "columns" : [ - * [ "Name", "gchararray" ], - * [ "Score", "gint" ], - * [ "Icon", "ClutterTexture" ] - * ], - * "rows" : [ - * [ "Team 1", 42, { "type" : "ClutterTexture", "filename" : "team1.png" } ], - * [ "Team 2", 23, "team2-icon-script-id" ], - * { "Name" : "Team 3", "Icon" : "team3-icon-script-id" } - * ] - * } - * - * Deprecated: 1.24: You should implement the #GListModel interface on your - * own storage data type instead. - */ - -#ifdef HAVE_CONFIG_H -#include "clutter-build-config.h" -#endif - -#include -#include -#include - -#define CLUTTER_DISABLE_DEPRECATION_WARNINGS - -#include "clutter-model.h" -#include "clutter-model-private.h" - -#include "clutter-marshal.h" -#include "clutter-private.h" -#include "clutter-debug.h" -#include "clutter-scriptable.h" -#include "clutter-script-private.h" - -enum -{ - PROP_0, - - PROP_FILTER_SET -}; - -enum -{ - ROW_ADDED, - ROW_REMOVED, - ROW_CHANGED, - - SORT_CHANGED, - FILTER_CHANGED, - - LAST_SIGNAL -}; - -static guint model_signals[LAST_SIGNAL] = { 0, }; - -struct _ClutterModelPrivate -{ - GType *column_types; - gchar **column_names; - - /* we use an integer here because we want to be able to use -1 as a - * guard value, to allow calling set_names() and set_types() from - * sub-classes of ClutterModel. see bug: - * - * http://bugzilla.openedhand.com/show_bug.cgi?id=2032 - * - * for a reference. - */ - gint n_columns; - - ClutterModelFilterFunc filter_func; - gpointer filter_data; - GDestroyNotify filter_notify; - - gint sort_column; - ClutterModelSortFunc sort_func; - gpointer sort_data; - GDestroyNotify sort_notify; -}; - -static void clutter_scriptable_iface_init (ClutterScriptableIface *iface); - -G_DEFINE_ABSTRACT_TYPE_WITH_CODE (ClutterModel, clutter_model, G_TYPE_OBJECT, - G_ADD_PRIVATE (ClutterModel) - G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_SCRIPTABLE, - clutter_scriptable_iface_init)) - -static GType -clutter_model_real_get_column_type (ClutterModel *model, - guint column) -{ - ClutterModelPrivate *priv = model->priv; - - if (column >= clutter_model_get_n_columns (model)) - return G_TYPE_INVALID; - - return priv->column_types[column]; -} - -static const gchar * -clutter_model_real_get_column_name (ClutterModel *model, - guint column) -{ - ClutterModelPrivate *priv = model->priv; - - if (column >= clutter_model_get_n_columns (model)) - return NULL; - - if (priv->column_names && priv->column_names[column]) - return priv->column_names[column]; - - return g_type_name (priv->column_types[column]); -} - -static guint -clutter_model_real_get_n_columns (ClutterModel *model) -{ - ClutterModelPrivate *priv = model->priv; - - if (priv->n_columns < 0) - return 0; - - return priv->n_columns; -} - -static guint -clutter_model_real_get_n_rows (ClutterModel *model) -{ - ClutterModelIter *iter; - guint row_count; - - g_return_val_if_fail (CLUTTER_IS_MODEL (model), 0); - - iter = clutter_model_get_first_iter (model); - if (iter == NULL) - return 0; - - row_count = 0; - while (!clutter_model_iter_is_last (iter)) - { - if (clutter_model_filter_iter (model, iter)) - row_count += 1; - - iter = clutter_model_iter_next (iter); - } - - g_object_unref (iter); - - return row_count; -} - -static void -clutter_model_finalize (GObject *object) -{ - ClutterModelPrivate *priv = CLUTTER_MODEL (object)->priv; - gint i; - - if (priv->sort_notify) - priv->sort_notify (priv->sort_data); - - if (priv->filter_notify) - priv->filter_notify (priv->filter_data); - - free (priv->column_types); - - if (priv->column_names != NULL) - { - /* the column_names vector might have holes in it, so we need - * to use the columns number to clear up everything - */ - for (i = 0; i < priv->n_columns; i++) - free (priv->column_names[i]); - - free (priv->column_names); - } - - G_OBJECT_CLASS (clutter_model_parent_class)->finalize (object); -} - -static void -clutter_model_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterModelPrivate *priv = CLUTTER_MODEL (gobject)->priv; - - switch (prop_id) - { - case PROP_FILTER_SET: - g_value_set_boolean (value, priv->filter_func != NULL); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_model_class_init (ClutterModelClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GParamSpec *pspec; - - gobject_class->get_property = clutter_model_get_property; - gobject_class->finalize = clutter_model_finalize; - - klass->get_column_name = clutter_model_real_get_column_name; - klass->get_column_type = clutter_model_real_get_column_type; - klass->get_n_columns = clutter_model_real_get_n_columns; - klass->get_n_rows = clutter_model_real_get_n_rows; - - /** - * ClutterModel:filter-set: - * - * Whether the #ClutterModel has a filter set - * - * This property is set to %TRUE if a filter function has been - * set using clutter_model_set_filter() - * - * Since: 1.0 - * - * Deprecated: 1.24: Use #GListModel instead - */ - pspec = g_param_spec_boolean ("filter-set", - "Filter Set", - "Whether the model has a filter", - FALSE, - CLUTTER_PARAM_READABLE); - g_object_class_install_property (gobject_class, PROP_FILTER_SET, pspec); - - /** - * ClutterModel::row-added: - * @model: the #ClutterModel on which the signal is emitted - * @iter: a #ClutterModelIter pointing to the new row - * - * The ::row-added signal is emitted when a new row has been added. - * The data on the row has already been set when the ::row-added signal - * has been emitted. - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ - model_signals[ROW_ADDED] = - g_signal_new ("row-added", - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterModelClass, row_added), - NULL, NULL, - _clutter_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - CLUTTER_TYPE_MODEL_ITER); - /** - * ClutterModel::row-removed: - * @model: the #ClutterModel on which the signal is emitted - * @iter: a #ClutterModelIter pointing to the removed row - * - * The ::row-removed signal is emitted when a row has been removed. - * The data on the row pointed by the passed iterator is still valid - * when the ::row-removed signal has been emitted. - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ - model_signals[ROW_REMOVED] = - g_signal_new ("row-removed", - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterModelClass, row_removed), - NULL, NULL, - _clutter_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - CLUTTER_TYPE_MODEL_ITER); - /** - * ClutterModel::row-changed: - * @model: the #ClutterModel on which the signal is emitted - * @iter: a #ClutterModelIter pointing to the changed row - * - * The ::row-removed signal is emitted when a row has been changed. - * The data on the row has already been updated when the ::row-changed - * signal has been emitted. - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ - model_signals[ROW_CHANGED] = - g_signal_new ("row-changed", - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterModelClass, row_changed), - NULL, NULL, - _clutter_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - CLUTTER_TYPE_MODEL_ITER); - /** - * ClutterModel::sort-changed: - * @model: the #ClutterModel on which the signal is emitted - * - * The ::sort-changed signal is emitted after the model has been sorted - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ - model_signals[SORT_CHANGED] = - g_signal_new ("sort-changed", - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterModelClass, sort_changed), - NULL, NULL, - _clutter_marshal_VOID__VOID, - G_TYPE_NONE, 0); - /** - * ClutterModel::filter-changed: - * @model: the #ClutterModel on which the signal is emitted - * - * The ::filter-changed signal is emitted when a new filter has been applied - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ - model_signals[FILTER_CHANGED] = - g_signal_new ("filter-changed", - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterModelClass, filter_changed), - NULL, NULL, - _clutter_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - -static void -clutter_model_init (ClutterModel *self) -{ - ClutterModelPrivate *priv; - - self->priv = priv = clutter_model_get_instance_private (self); - - priv->n_columns = -1; - priv->column_types = NULL; - priv->column_names = NULL; - - priv->filter_func = NULL; - priv->filter_data = NULL; - priv->filter_notify = NULL; - - priv->sort_column = -1; - priv->sort_func = NULL; - priv->sort_data = NULL; - priv->sort_notify = NULL; -} - -/* XXX - is this whitelist really necessary? we accept every fundamental - * type. - */ -gboolean -_clutter_model_check_type (GType gtype) -{ - gint i = 0; - static const GType type_list[] = - { - G_TYPE_BOOLEAN, - G_TYPE_CHAR, - G_TYPE_UCHAR, - G_TYPE_INT, - G_TYPE_UINT, - G_TYPE_LONG, - G_TYPE_ULONG, - G_TYPE_INT64, - G_TYPE_UINT64, - G_TYPE_ENUM, - G_TYPE_FLAGS, - G_TYPE_FLOAT, - G_TYPE_DOUBLE, - G_TYPE_STRING, - G_TYPE_POINTER, - G_TYPE_BOXED, - G_TYPE_OBJECT, - G_TYPE_INVALID - }; - - if (! G_TYPE_IS_VALUE_TYPE (gtype)) - return FALSE; - - while (type_list[i] != G_TYPE_INVALID) - { - if (g_type_is_a (gtype, type_list[i])) - return TRUE; - i++; - } - return FALSE; -} - - -typedef struct { - gchar *name; - GType type; -} ColumnInfo; - -static gboolean -clutter_model_parse_custom_node (ClutterScriptable *scriptable, - ClutterScript *script, - GValue *value, - const gchar *name, - JsonNode *node) -{ - if (strcmp (name, "columns") == 0) - { - GSList *columns = NULL; - GList *elements, *l; - - if (JSON_NODE_TYPE (node) != JSON_NODE_ARRAY) - return FALSE; - - elements = json_array_get_elements (json_node_get_array (node)); - - for (l = elements; l != NULL; l = l->next) - { - JsonNode *child_node = l->data; - JsonArray *array = json_node_get_array (child_node); - ColumnInfo *cinfo; - const gchar *column_name; - const gchar *type_name; - - if (JSON_NODE_TYPE (node) != JSON_NODE_ARRAY || - json_array_get_length (array) != 2) - { - g_warning ("A column must be an array of " - "[\"column-name\", \"GType-name\"] pairs"); - return FALSE; - } - - column_name = json_array_get_string_element (array, 0); - type_name = json_array_get_string_element (array, 1); - - cinfo = g_slice_new0 (ColumnInfo); - cinfo->name = g_strdup (column_name); - cinfo->type = clutter_script_get_type_from_name (script, type_name); - - columns = g_slist_prepend (columns, cinfo); - } - - g_list_free (elements); - - g_value_init (value, G_TYPE_POINTER); - g_value_set_pointer (value, g_slist_reverse (columns)); - - return TRUE; - } - else if (strcmp (name, "rows") == 0) - { - GSList *rows = NULL; - GList *elements, *l; - - if (JSON_NODE_TYPE (node) != JSON_NODE_ARRAY) - return FALSE; - - /* - * at this point we have no information about the column types, so - * we just copy the json elements and resolve them in the - * set_custom_property method - */ - elements = json_array_get_elements (json_node_get_array (node)); - for (l = elements; l != NULL; l = l->next) - rows = g_slist_prepend (rows, json_node_copy (l->data)); - g_list_free (elements); - - g_value_init (value, G_TYPE_POINTER); - g_value_set_pointer (value, g_slist_reverse (rows)); - - return TRUE; - } - return FALSE; -} - -static void -clutter_model_set_custom_property (ClutterScriptable *scriptable, - ClutterScript *script, - const gchar *name, - const GValue *value) -{ - if (strcmp (name, "columns") == 0) - { - ClutterModel *model = CLUTTER_MODEL (scriptable); - GSList *columns, *l; - guint n_columns; - gint i; - - columns = g_value_get_pointer (value); - n_columns = g_slist_length (columns); - - _clutter_model_set_n_columns (model, n_columns, TRUE, TRUE); - - for (i = 0, l = columns; l != NULL; l = l->next, i++) - { - ColumnInfo *cinfo = l->data; - - _clutter_model_set_column_name (model, i, cinfo->name); - _clutter_model_set_column_type (model, i, cinfo->type); - - free (cinfo->name); - g_slice_free (ColumnInfo, cinfo); - } - - g_slist_free (columns); - } - else if (strcmp (name, "rows") == 0) - { - ClutterModel *model = CLUTTER_MODEL (scriptable); - GSList *rows, *l; - guint n_columns, row = 0; - - rows = g_value_get_pointer (value); - n_columns = clutter_model_get_n_columns (model); - - for (l = rows; l; l = l->next) - { - JsonNode *node = l->data; - guint *columns = NULL, i, n_values = 0; - GValue *values = NULL; - - if (JSON_NODE_TYPE (node) == JSON_NODE_ARRAY) - { - JsonArray *array = json_node_get_array (node); - - if (json_array_get_length (array) != n_columns) - { - g_warning ("Row %d contains the wrong count of columns", - g_slist_position (rows, l) + 1); - row += 1; - continue; - } - - /* array more requires all columns */ - n_values = n_columns; - - columns = g_new (guint, n_values); - values = g_new0 (GValue, n_values); - - for (i = 0; i < n_values; i++) - { - GType column_type; - const gchar *column_name; - - column_type = clutter_model_get_column_type (model, i); - column_name = clutter_model_get_column_name (model, i); - - columns[i] = i; - g_value_init (&values[i], column_type); - - _clutter_script_parse_node (script, &values[i], column_name, - json_array_get_element (array, i), - NULL); - } - } - else if (JSON_NODE_TYPE (node) == JSON_NODE_OBJECT) - { - JsonObject *object = json_node_get_object (node); - GList *members, *m; - guint column = 0; - - /* object mode does not require all columns */ - n_values = json_object_get_size (object); - - columns = g_new (guint, n_values); - values = g_new0 (GValue, n_values); - - members = json_object_get_members (object); - for (m = members; m; m = m->next) - { - const gchar *mname = m->data; - - for (i = 0; i < clutter_model_get_n_columns (model); i++) - { - const gchar *cname; - - cname = clutter_model_get_column_name (model, i); - if (strcmp (mname, cname) == 0) - { - JsonNode *member; - GType col_type; - const gchar *col_name; - - member = json_object_get_member (object, mname); - - col_type = clutter_model_get_column_type (model, i); - col_name = clutter_model_get_column_name (model, i); - - columns[column] = i; - g_value_init (&values[column], col_type); - - _clutter_script_parse_node (script, &values[column], - col_name, member, - NULL); - break; - } - } - - column += 1; - } - } - else - { - row += 1; - continue; - } - - clutter_model_insertv (model, row, n_values, columns, values); - - free (values); - free (columns); - json_node_free (node); - - row += 1; - } - g_slist_free (rows); - } -} - - -static void -clutter_scriptable_iface_init (ClutterScriptableIface *iface) -{ - iface->parse_custom_node = clutter_model_parse_custom_node; - iface->set_custom_property = clutter_model_set_custom_property; -} - -/** - * clutter_model_resort: - * @model: a #ClutterModel - * - * Force a resort on the @model. This function should only be - * used by subclasses of #ClutterModel. - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -void -clutter_model_resort (ClutterModel *model) -{ - ClutterModelPrivate *priv; - ClutterModelClass *klass; - - g_return_if_fail (CLUTTER_IS_MODEL (model)); - priv = model->priv; - - klass = CLUTTER_MODEL_GET_CLASS (model); - - if (klass->resort) - klass->resort (model, priv->sort_func, priv->sort_data); -} - -/** - * clutter_model_filter_row: - * @model: a #ClutterModel - * @row: the row to filter - * - * Checks whether @row should be filtered or not using the - * filtering function set on @model. - * - * This function should be used only by subclasses of #ClutterModel. - * - * Return value: %TRUE if the row should be displayed, - * %FALSE otherwise - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -gboolean -clutter_model_filter_row (ClutterModel *model, - guint row) -{ - ClutterModelPrivate *priv; - ClutterModelIter *iter; - gboolean res = TRUE; - - g_return_val_if_fail (CLUTTER_IS_MODEL (model), TRUE); - - priv = model->priv; - - if (!priv->filter_func) - return TRUE; - - iter = clutter_model_get_iter_at_row (model, row); - if (iter == NULL) - return FALSE; - - res = priv->filter_func (model, iter, priv->filter_data); - - g_object_unref (iter); - - return res; -} - -/** - * clutter_model_filter_iter: - * @model: a #ClutterModel - * @iter: the row to filter - * - * Checks whether the row pointer by @iter should be filtered or not using - * the filtering function set on @model. - * - * This function should be used only by subclasses of #ClutterModel. - * - * Return value: %TRUE if the row should be displayed, - * %FALSE otherwise - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -gboolean -clutter_model_filter_iter (ClutterModel *model, - ClutterModelIter *iter) -{ - ClutterModelPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_MODEL (model), TRUE); - g_return_val_if_fail (CLUTTER_IS_MODEL_ITER (iter), TRUE); - - priv = model->priv; - - if (!priv->filter_func) - return TRUE; - - return priv->filter_func (model, iter, priv->filter_data); -} - -/*< private > - * clutter_model_set_n_columns: - * @model: a #ClutterModel - * @n_columns: number of columns - * @set_types: set the columns type - * @set_names: set the columns name - * - * Sets the number of columns in @model to @n_columns. If @set_types - * or @set_names are %TRUE, initialises the columns type and name - * arrays as well. - * - * This function can only be called once. - * - * Deprecated: 1.24: Use #GListModel instead - */ -void -_clutter_model_set_n_columns (ClutterModel *model, - gint n_columns, - gboolean set_types, - gboolean set_names) -{ - ClutterModelPrivate *priv = model->priv; - - if (priv->n_columns > 0 && priv->n_columns != n_columns) - return; - - priv->n_columns = n_columns; - - if (set_types && !priv->column_types) - priv->column_types = g_new0 (GType, n_columns); - - if (set_names && !priv->column_names) - priv->column_names = g_new0 (gchar*, n_columns); -} - -/*< private > - * _clutter_model_set_column_type: - * @model: a #ClutterModel - * @column: column index - * @gtype: type of the column - * - * Sets the type of @column inside @model - */ -void -_clutter_model_set_column_type (ClutterModel *model, - gint column, - GType gtype) -{ - ClutterModelPrivate *priv = model->priv; - - priv->column_types[column] = gtype; -} - -/*< private > - * _clutter_model_set_column_name: - * @model: a #ClutterModel - * @column: column index - * @name: name of the column, or %NULL - * - * Sets the name of @column inside @model - */ -void -_clutter_model_set_column_name (ClutterModel *model, - gint column, - const gchar *name) -{ - ClutterModelPrivate *priv = model->priv; - - priv->column_names[column] = g_strdup (name); -} - -/** - * clutter_model_set_types: - * @model: a #ClutterModel - * @n_columns: number of columns for the model - * @types: (array length=n_columns): an array of #GType types - * - * Sets the types of the columns inside a #ClutterModel. - * - * This function is meant primarily for #GObjects that inherit from - * #ClutterModel, and should only be used when contructing a #ClutterModel. - * It will not work after the initial creation of the #ClutterModel. - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -void -clutter_model_set_types (ClutterModel *model, - guint n_columns, - GType *types) -{ - ClutterModelPrivate *priv; - gint i; - - g_return_if_fail (CLUTTER_IS_MODEL (model)); - g_return_if_fail (n_columns > 0); - - priv = model->priv; - - g_return_if_fail (priv->n_columns < 0 || priv->n_columns == n_columns); - g_return_if_fail (priv->column_types == NULL); - - _clutter_model_set_n_columns (model, n_columns, TRUE, FALSE); - - for (i = 0; i < n_columns; i++) - { - if (!_clutter_model_check_type (types[i])) - { - g_warning ("%s: Invalid type %s\n", G_STRLOC, g_type_name (types[i])); - return; - } - - _clutter_model_set_column_type (model, i, types[i]); - } -} - -/** - * clutter_model_set_names: - * @model: a #ClutterModel - * @n_columns: the number of column names - * @names: (array length=n_columns): an array of strings - * - * Assigns a name to the columns of a #ClutterModel. - * - * This function is meant primarily for #GObjects that inherit from - * #ClutterModel, and should only be used when contructing a #ClutterModel. - * It will not work after the initial creation of the #ClutterModel. - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -void -clutter_model_set_names (ClutterModel *model, - guint n_columns, - const gchar * const names[]) -{ - ClutterModelPrivate *priv; - gint i; - - g_return_if_fail (CLUTTER_IS_MODEL (model)); - g_return_if_fail (n_columns > 0); - - priv = model->priv; - - g_return_if_fail (priv->n_columns < 0 || priv->n_columns == n_columns); - g_return_if_fail (priv->column_names == NULL); - - _clutter_model_set_n_columns (model, n_columns, FALSE, TRUE); - - for (i = 0; i < n_columns; i++) - _clutter_model_set_column_name (model, i, names[i]); -} - -/** - * clutter_model_get_n_columns: - * @model: a #ClutterModel - * - * Retrieves the number of columns inside @model. - * - * Return value: the number of columns - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -guint -clutter_model_get_n_columns (ClutterModel *model) -{ - g_return_val_if_fail (CLUTTER_IS_MODEL (model), 0); - - return CLUTTER_MODEL_GET_CLASS (model)->get_n_columns (model); -} - -/** - * clutter_model_appendv: - * @model: a #ClutterModel - * @n_columns: the number of columns and values - * @columns: (array length=n_columns): a vector with the columns to set - * @values: (array length=n_columns): a vector with the values - * - * Creates and appends a new row to the #ClutterModel, setting the row - * values for the given @columns upon creation. - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -void -clutter_model_appendv (ClutterModel *model, - guint n_columns, - guint *columns, - GValue *values) -{ - ClutterModelPrivate *priv; - ClutterModelIter *iter; - gint i; - gboolean resort = FALSE; - - g_return_if_fail (CLUTTER_IS_MODEL (model)); - g_return_if_fail (n_columns <= clutter_model_get_n_columns (model)); - g_return_if_fail (columns != NULL); - g_return_if_fail (values != NULL); - - priv = model->priv; - - iter = CLUTTER_MODEL_GET_CLASS (model)->insert_row (model, -1); - g_assert (CLUTTER_IS_MODEL_ITER (iter)); - - for (i = 0; i < n_columns; i++) - { - if (priv->sort_column == columns[i]) - resort = TRUE; - - clutter_model_iter_set_value (iter, columns[i], &values[i]); - } - - g_signal_emit (model, model_signals[ROW_ADDED], 0, iter); - - if (resort) - clutter_model_resort (model); - - g_object_unref (iter); -} - -/* forward declaration */ -static void clutter_model_iter_set_internal_valist (ClutterModelIter *iter, - va_list args); - -/** - * clutter_model_append: - * @model: a #ClutterModel - * @...: pairs of column number and value, terminated with -1 - * - * Creates and appends a new row to the #ClutterModel, setting the - * row values upon creation. For example, to append a new row where - * column 0 is type %G_TYPE_INT and column 1 is of type %G_TYPE_STRING: - * - * - * ClutterModel *model; - * model = clutter_model_default_new (2, - * G_TYPE_INT, "Score", - * G_TYPE_STRING, "Team"); - * clutter_model_append (model, 0, 42, 1, "Team #1", -1); - * - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -void -clutter_model_append (ClutterModel *model, - ...) -{ - ClutterModelIter *iter; - va_list args; - - g_return_if_fail (CLUTTER_IS_MODEL (model)); - - iter = CLUTTER_MODEL_GET_CLASS (model)->insert_row (model, -1); - g_assert (CLUTTER_IS_MODEL_ITER (iter)); - - /* do not emit the ::row-changed signal */ - va_start (args, model); - clutter_model_iter_set_internal_valist (iter, args); - va_end (args); - - g_signal_emit (model, model_signals[ROW_ADDED], 0, iter); - - g_object_unref (iter); -} - -/** - * clutter_model_prependv: - * @model: a #ClutterModel - * @n_columns: the number of columns and values to set - * @columns: (array length=n_columns): a vector containing the columns to set - * @values: (array length=n_columns): a vector containing the values for the cells - * - * Creates and prepends a new row to the #ClutterModel, setting the row - * values for the given @columns upon creation. - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -void -clutter_model_prependv (ClutterModel *model, - guint n_columns, - guint *columns, - GValue *values) -{ - ClutterModelPrivate *priv; - ClutterModelIter *iter; - gint i; - gboolean resort = FALSE; - - g_return_if_fail (CLUTTER_IS_MODEL (model)); - g_return_if_fail (n_columns <= clutter_model_get_n_columns (model)); - g_return_if_fail (columns != NULL); - g_return_if_fail (values != NULL); - - priv = model->priv; - - iter = CLUTTER_MODEL_GET_CLASS (model)->insert_row (model, 0); - g_assert (CLUTTER_IS_MODEL_ITER (iter)); - - for (i = 0; i < n_columns; i++) - { - if (priv->sort_column == columns[i]) - resort = TRUE; - - clutter_model_iter_set_value (iter, columns[i], &values[i]); - } - - g_signal_emit (model, model_signals[ROW_ADDED], 0, iter); - - if (resort) - clutter_model_resort (model); - - g_object_unref (iter); -} - -/** - * clutter_model_prepend: - * @model: a #ClutterModel - * @...: pairs of column number and value, terminated with -1 - * - * Creates and prepends a new row to the #ClutterModel, setting the row - * values upon creation. For example, to prepend a new row where column 0 - * is type %G_TYPE_INT and column 1 is of type %G_TYPE_STRING: - * - * - * ClutterModel *model; - * model = clutter_model_default_new (2, - * G_TYPE_INT, "Score", - * G_TYPE_STRING, "Team"); - * clutter_model_prepend (model, 0, 42, 1, "Team #1", -1); - * - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -void -clutter_model_prepend (ClutterModel *model, - ...) -{ - ClutterModelIter *iter; - va_list args; - - g_return_if_fail (CLUTTER_IS_MODEL (model)); - - iter = CLUTTER_MODEL_GET_CLASS (model)->insert_row (model, 0); - g_assert (CLUTTER_IS_MODEL_ITER (iter)); - - va_start (args, model); - clutter_model_iter_set_internal_valist (iter, args); - va_end (args); - - g_signal_emit (model, model_signals[ROW_ADDED], 0, iter); - - g_object_unref (iter); -} - - -/** - * clutter_model_insert: - * @model: a #ClutterModel - * @row: the position to insert the new row - * @...: pairs of column number and value, terminated with -1 - * - * Inserts a new row to the #ClutterModel at @row, setting the row - * values upon creation. For example, to insert a new row at index 100, - * where column 0 is type %G_TYPE_INT and column 1 is of type - * %G_TYPE_STRING: - * - * - * ClutterModel *model; - * model = clutter_model_default_new (2, - * G_TYPE_INT, "Score", - * G_TYPE_STRING, "Team"); - * clutter_model_insert (model, 3, 0, 42, 1, "Team #1", -1); - * - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -void -clutter_model_insert (ClutterModel *model, - guint row, - ...) -{ - ClutterModelIter *iter; - va_list args; - - g_return_if_fail (CLUTTER_IS_MODEL (model)); - - iter = CLUTTER_MODEL_GET_CLASS (model)->insert_row (model, row); - g_assert (CLUTTER_IS_MODEL_ITER (iter)); - - /* set_valist() will call clutter_model_resort() if one of the - * passed columns matches the model sorting column index - */ - va_start (args, row); - clutter_model_iter_set_internal_valist (iter, args); - va_end (args); - - g_signal_emit (model, model_signals[ROW_ADDED], 0, iter); - - g_object_unref (iter); -} - -/** - * clutter_model_insertv: - * @model: a #ClutterModel - * @row: row index - * @n_columns: the number of columns and values to set - * @columns: (array length=n_columns): a vector containing the columns to set - * @values: (array length=n_columns): a vector containing the values for the cells - * - * Inserts data at @row into the #ClutterModel, setting the row - * values for the given @columns upon creation. - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -void -clutter_model_insertv (ClutterModel *model, - guint row, - guint n_columns, - guint *columns, - GValue *values) -{ - ClutterModelPrivate *priv; - ClutterModelIter *iter; - gint i; - gboolean resort = FALSE; - - g_return_if_fail (CLUTTER_IS_MODEL (model)); - g_return_if_fail (n_columns <= clutter_model_get_n_columns (model)); - g_return_if_fail (columns != NULL); - g_return_if_fail (values != NULL); - - priv = model->priv; - - iter = CLUTTER_MODEL_GET_CLASS (model)->insert_row (model, row); - g_assert (CLUTTER_IS_MODEL_ITER (iter)); - - for (i = 0; i < n_columns; i++) - { - if (priv->sort_column == columns[i]) - resort = TRUE; - - clutter_model_iter_set_value (iter, columns[i], &values[i]); - } - - g_signal_emit (model, model_signals[ROW_ADDED], 0, iter); - - if (resort) - clutter_model_resort (model); - - g_object_unref (iter); -} - -/** - * clutter_model_insert_value: - * @model: a #ClutterModel - * @row: position of the row to modify - * @column: column to modify - * @value: new value for the cell - * - * Sets the data in the cell specified by @iter and @column. The type of - * @value must be convertable to the type of the column. If the row does - * not exist then it is created. - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -void -clutter_model_insert_value (ClutterModel *model, - guint row, - guint column, - const GValue *value) -{ - ClutterModelPrivate *priv; - ClutterModelClass *klass; - ClutterModelIter *iter; - gboolean added = FALSE; - - g_return_if_fail (CLUTTER_IS_MODEL (model)); - - priv = model->priv; - klass = CLUTTER_MODEL_GET_CLASS (model); - - iter = klass->get_iter_at_row (model, row); - if (!iter) - { - iter = klass->insert_row (model, row); - added = TRUE; - } - - g_assert (CLUTTER_IS_MODEL_ITER (iter)); - - clutter_model_iter_set_value (iter, column, value); - - if (added) - g_signal_emit (model, model_signals[ROW_ADDED], 0, iter); - - if (priv->sort_column == column) - clutter_model_resort (model); - - g_object_unref (iter); -} - -/** - * clutter_model_remove: - * @model: a #ClutterModel - * @row: position of row to remove - * - * Removes the row at the given position from the model. - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -void -clutter_model_remove (ClutterModel *model, - guint row) -{ - ClutterModelClass *klass; - - g_return_if_fail (CLUTTER_IS_MODEL (model)); - - klass = CLUTTER_MODEL_GET_CLASS (model); - if (klass->remove_row) - klass->remove_row (model, row); -} - -/** - * clutter_model_get_column_name: - * @model: #ClutterModel - * @column: the column number - * - * Retrieves the name of the @column - * - * Return value: the name of the column. The model holds the returned - * string, and it should not be modified or freed - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -const gchar * -clutter_model_get_column_name (ClutterModel *model, - guint column) -{ - ClutterModelClass *klass; - - g_return_val_if_fail (CLUTTER_IS_MODEL (model), NULL); - - if (column >= clutter_model_get_n_columns (model)) - { - g_warning ("%s: Invalid column id value %d\n", G_STRLOC, column); - return NULL; - } - - klass = CLUTTER_MODEL_GET_CLASS (model); - if (klass->get_column_name) - return klass->get_column_name (model, column); - - return NULL; -} - -/** - * clutter_model_get_column_type: - * @model: #ClutterModel - * @column: the column number - * - * Retrieves the type of the @column. - * - * Return value: the type of the column. - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -GType -clutter_model_get_column_type (ClutterModel *model, - guint column) -{ - ClutterModelClass *klass; - - g_return_val_if_fail (CLUTTER_IS_MODEL (model), G_TYPE_INVALID); - - if (column >= clutter_model_get_n_columns (model)) - { - g_warning ("%s: Invalid column id value %d\n", G_STRLOC, column); - return G_TYPE_INVALID; - } - - klass = CLUTTER_MODEL_GET_CLASS (model); - if (klass->get_column_type) - return klass->get_column_type (model, column); - - return G_TYPE_INVALID; -} - -/** - * clutter_model_get_iter_at_row: - * @model: a #ClutterModel - * @row: position of the row to retrieve - * - * Retrieves a #ClutterModelIter representing the row at the given index. - * - * If a filter function has been set using clutter_model_set_filter() - * then the @model implementation will return the first non filtered - * row. - * - * Return value: (transfer full): A new #ClutterModelIter, or %NULL if @row was - * out of bounds. When done using the iterator object, call g_object_unref() - * to deallocate its resources - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -ClutterModelIter * -clutter_model_get_iter_at_row (ClutterModel *model, - guint row) -{ - ClutterModelClass *klass; - - g_return_val_if_fail (CLUTTER_IS_MODEL (model), NULL); - - klass = CLUTTER_MODEL_GET_CLASS (model); - if (klass->get_iter_at_row) - return klass->get_iter_at_row (model, row); - - return NULL; -} - - -/** - * clutter_model_get_first_iter: - * @model: a #ClutterModel - * - * Retrieves a #ClutterModelIter representing the first non-filtered - * row in @model. - * - * Return value: (transfer full): A new #ClutterModelIter. - * Call g_object_unref() when done using it - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -ClutterModelIter * -clutter_model_get_first_iter (ClutterModel *model) -{ - ClutterModelIter *retval; - - g_return_val_if_fail (CLUTTER_IS_MODEL (model), NULL); - - retval = clutter_model_get_iter_at_row (model, 0); - if (retval != NULL) - { - g_assert (clutter_model_filter_iter (model, retval) != FALSE); - g_assert (clutter_model_iter_get_row (retval) == 0); - } - - return retval; -} - -/** - * clutter_model_get_last_iter: - * @model: a #ClutterModel - * - * Retrieves a #ClutterModelIter representing the last non-filtered - * row in @model. - * - * Return value: (transfer full): A new #ClutterModelIter. - * Call g_object_unref() when done using it - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -ClutterModelIter * -clutter_model_get_last_iter (ClutterModel *model) -{ - ClutterModelIter *retval; - guint length; - - g_return_val_if_fail (CLUTTER_IS_MODEL (model), NULL); - - length = clutter_model_get_n_rows (model); - retval = clutter_model_get_iter_at_row (model, length - 1); - if (retval != NULL) - g_assert (clutter_model_filter_iter (model, retval) != FALSE); - - return retval; -} - -/** - * clutter_model_get_n_rows: - * @model: a #ClutterModel - * - * Retrieves the number of rows inside @model, eventually taking - * into account any filtering function set using clutter_model_set_filter(). - * - * Return value: The length of the @model. If there is a filter set, then - * the length of the filtered @model is returned. - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -guint -clutter_model_get_n_rows (ClutterModel *model) -{ - g_return_val_if_fail (CLUTTER_IS_MODEL (model), 0); - - return CLUTTER_MODEL_GET_CLASS (model)->get_n_rows (model); -} - -/** - * clutter_model_set_sorting_column: - * @model: a #ClutterModel - * @column: the column of the @model to sort, or -1 - * - * Sets the model to sort by @column. If @column is a negative value - * the sorting column will be unset. - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -void -clutter_model_set_sorting_column (ClutterModel *model, - gint column) -{ - ClutterModelPrivate *priv; - - g_return_if_fail (CLUTTER_IS_MODEL (model)); - priv = model->priv; - - /* The extra comparison for >= 0 is because column gets promoted to - unsigned in the second comparison */ - if (column >= 0 && column >= clutter_model_get_n_columns (model)) - { - g_warning ("%s: Invalid column id value %d\n", G_STRLOC, column); - return; - } - - priv->sort_column = column; - - if (priv->sort_column >= 0) - clutter_model_resort (model); - - g_signal_emit (model, model_signals[SORT_CHANGED], 0); -} - -/** - * clutter_model_get_sorting_column: - * @model: a #ClutterModel - * - * Retrieves the number of column used for sorting the @model. - * - * Return value: a column number, or -1 if the model is not sorted - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -gint -clutter_model_get_sorting_column (ClutterModel *model) -{ - g_return_val_if_fail (CLUTTER_IS_MODEL (model), -1); - - return model->priv->sort_column; -} - -/** - * clutter_model_foreach: - * @model: a #ClutterModel - * @func: (scope call): a #ClutterModelForeachFunc - * @user_data: user data to pass to @func - * - * Calls @func for each row in the model. - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -void -clutter_model_foreach (ClutterModel *model, - ClutterModelForeachFunc func, - gpointer user_data) -{ - ClutterModelIter *iter; - - g_return_if_fail (CLUTTER_IS_MODEL (model)); - - iter = clutter_model_get_first_iter (model); - if (!iter) - return; - - while (!clutter_model_iter_is_last (iter)) - { - if (clutter_model_filter_iter (model, iter)) - { - if (!func (model, iter, user_data)) - break; - } - - iter = clutter_model_iter_next (iter); - } - - g_object_unref (iter); -} - -/** - * clutter_model_set_sort: - * @model: a #ClutterModel - * @column: the column to sort on - * @func: (allow-none): a #ClutterModelSortFunc, or #NULL - * @user_data: user data to pass to @func, or #NULL - * @notify: destroy notifier of @user_data, or #NULL - * - * Sorts @model using the given sorting function. - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -void -clutter_model_set_sort (ClutterModel *model, - gint column, - ClutterModelSortFunc func, - gpointer user_data, - GDestroyNotify notify) -{ - ClutterModelPrivate *priv; - - g_return_if_fail (CLUTTER_IS_MODEL (model)); - g_return_if_fail ((func != NULL && column >= 0) || - (func == NULL && column == -1)); - - priv = model->priv; - - if (priv->sort_notify) - priv->sort_notify (priv->sort_data); - - priv->sort_func = func; - priv->sort_data = user_data; - priv->sort_notify = notify; - - /* This takes care of calling _model_sort & emitting the signal*/ - clutter_model_set_sorting_column (model, column); -} - -/** - * clutter_model_set_filter: - * @model: a #ClutterModel - * @func: (allow-none): a #ClutterModelFilterFunc, or #NULL - * @user_data: user data to pass to @func, or #NULL - * @notify: destroy notifier of @user_data, or #NULL - * - * Filters the @model using the given filtering function. - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -void -clutter_model_set_filter (ClutterModel *model, - ClutterModelFilterFunc func, - gpointer user_data, - GDestroyNotify notify) -{ - ClutterModelPrivate *priv; - - g_return_if_fail (CLUTTER_IS_MODEL (model)); - priv = model->priv; - - if (priv->filter_notify) - priv->filter_notify (priv->filter_data); - - priv->filter_func = func; - priv->filter_data = user_data; - priv->filter_notify = notify; - - g_signal_emit (model, model_signals[FILTER_CHANGED], 0); - g_object_notify (G_OBJECT (model), "filter-set"); -} - -/** - * clutter_model_get_filter_set: - * @model: a #ClutterModel - * - * Returns whether the @model has a filter in place, set - * using clutter_model_set_filter() - * - * Return value: %TRUE if a filter is set - * - * Since: 1.0 - * - * Deprecated: 1.24: Use #GListModel instead - */ -gboolean -clutter_model_get_filter_set (ClutterModel *model) -{ - g_return_val_if_fail (CLUTTER_IS_MODEL (model), FALSE); - - return model->priv->filter_func != NULL; -} - -/* - * ClutterModelIter Object - */ - -/** - * SECTION:clutter-model-iter - * @short_description: Iterates through a model - * - * #ClutterModelIter is an object used for iterating through all the rows - * of a #ClutterModel. It allows setting and getting values on the row - * which is currently pointing at. - * - * A #ClutterModelIter represents a position between two elements - * of the sequence. For example, the iterator returned by - * clutter_model_get_first_iter() represents the gap immediately before - * the first row of the #ClutterModel, and the iterator returned by - * clutter_model_get_last_iter() represents the gap immediately after the - * last row. - * - * A #ClutterModelIter can only be created by a #ClutterModel implementation - * and it is valid as long as the model does not change. - * - * #ClutterModelIter is available since Clutter 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ - -struct _ClutterModelIterPrivate -{ - ClutterModel *model; - - gint row; -}; - -G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterModelIter, clutter_model_iter, G_TYPE_OBJECT) - -enum -{ - ITER_PROP_0, - - ITER_PROP_MODEL, - ITER_PROP_ROW -}; - -static ClutterModel * -clutter_model_iter_real_get_model (ClutterModelIter *iter) -{ - return iter->priv->model; -} - -static guint -clutter_model_iter_real_get_row (ClutterModelIter *iter) -{ - return iter->priv->row; -} - -/* private function */ -void -_clutter_model_iter_set_row (ClutterModelIter *iter, - guint row) -{ - iter->priv->row = row; -} - -static void -clutter_model_iter_get_value_unimplemented (ClutterModelIter *iter, - guint column, - GValue *value) -{ - g_warning ("%s: Iterator of type '%s' does not implement the " - "ClutterModelIter::get_value() virtual function", - G_STRLOC, - g_type_name (G_OBJECT_TYPE (iter))); -} - -static void -clutter_model_iter_set_value_unimplemented (ClutterModelIter *iter, - guint column, - const GValue *value) -{ - g_warning ("%s: Iterator of type '%s' does not implement the " - "ClutterModelIter::set_value() virtual function", - G_STRLOC, - g_type_name (G_OBJECT_TYPE (iter))); -} - -static gboolean -clutter_model_iter_is_first_unimplemented (ClutterModelIter *iter) -{ - g_warning ("%s: Iterator of type '%s' does not implement the " - "ClutterModelIter::is_first() virtual function", - G_STRLOC, - g_type_name (G_OBJECT_TYPE (iter))); - return FALSE; -} - -static gboolean -clutter_model_iter_is_last_unimplemented (ClutterModelIter *iter) -{ - g_warning ("%s: Iterator of type '%s' does not implement the " - "ClutterModelIter::is_last() virtual function", - G_STRLOC, - g_type_name (G_OBJECT_TYPE (iter))); - return FALSE; -} - -static ClutterModelIter * -clutter_model_iter_next_unimplemented (ClutterModelIter *iter) -{ - g_warning ("%s: Iterator of type '%s' does not implement the " - "ClutterModelIter::next() virtual function", - G_STRLOC, - g_type_name (G_OBJECT_TYPE (iter))); - return NULL; -} - -static ClutterModelIter * -clutter_model_iter_prev_unimplemented (ClutterModelIter *iter) -{ - g_warning ("%s: Iterator of type '%s' does not implement the " - "ClutterModelIter::prev() virtual function", - G_STRLOC, - g_type_name (G_OBJECT_TYPE (iter))); - return NULL; -} - -static ClutterModelIter * -clutter_model_iter_copy_unimplemented (ClutterModelIter *iter) -{ - g_warning ("%s: Iterator of type '%s' does not implement the " - "ClutterModelIter::copy() virtual function", - G_STRLOC, - g_type_name (G_OBJECT_TYPE (iter))); - return NULL; -} - -static void -clutter_model_iter_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterModelIter *iter = CLUTTER_MODEL_ITER (object); - ClutterModelIterPrivate *priv = iter->priv; - - switch (prop_id) - { - case ITER_PROP_MODEL: - g_value_set_object (value, priv->model); - break; - case ITER_PROP_ROW: - g_value_set_uint (value, priv->row); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -clutter_model_iter_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterModelIter *iter = CLUTTER_MODEL_ITER (object); - ClutterModelIterPrivate *priv = iter->priv; - - switch (prop_id) - { - case ITER_PROP_MODEL: - priv->model = g_value_get_object (value); - break; - case ITER_PROP_ROW: - priv->row = g_value_get_uint (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -clutter_model_iter_class_init (ClutterModelIterClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GParamSpec *pspec; - - gobject_class->get_property = clutter_model_iter_get_property; - gobject_class->set_property = clutter_model_iter_set_property; - - klass->get_model = clutter_model_iter_real_get_model; - klass->get_row = clutter_model_iter_real_get_row; - klass->is_first = clutter_model_iter_is_first_unimplemented; - klass->is_last = clutter_model_iter_is_last_unimplemented; - klass->next = clutter_model_iter_next_unimplemented; - klass->prev = clutter_model_iter_prev_unimplemented; - klass->get_value = clutter_model_iter_get_value_unimplemented; - klass->set_value = clutter_model_iter_set_value_unimplemented; - klass->copy = clutter_model_iter_copy_unimplemented; - - /* Properties */ - - /** - * ClutterModelIter:model: - * - * A reference to the #ClutterModel that this iter belongs to. - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ - pspec = g_param_spec_object ("model", - "Model", - "The model to which the iterator belongs to", - CLUTTER_TYPE_MODEL, - CLUTTER_PARAM_READWRITE); - g_object_class_install_property (gobject_class, ITER_PROP_MODEL, pspec); - - /** - * ClutterModelIter:row: - * - * The row number to which this iter points to. - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ - pspec = g_param_spec_uint ("row", - "Row", - "The row to which the iterator points to", - 0, G_MAXUINT, 0, - CLUTTER_PARAM_READWRITE); - g_object_class_install_property (gobject_class, ITER_PROP_ROW, pspec); -} - -static void -clutter_model_iter_init (ClutterModelIter *self) -{ - self->priv = clutter_model_iter_get_instance_private (self); -} - -/* - * Public functions - */ - -static inline void -clutter_model_iter_set_value_internal (ClutterModelIter *iter, - guint column, - const GValue *value) -{ - CLUTTER_MODEL_ITER_GET_CLASS (iter)->set_value (iter, column, value); -} - -static void -clutter_model_iter_set_internal_valist (ClutterModelIter *iter, - va_list args) -{ - ClutterModelIterPrivate *priv = iter->priv; - ClutterModel *model = priv->model; - guint column = 0; - gboolean sort = FALSE; - - g_assert (CLUTTER_IS_MODEL (model)); - - column = va_arg (args, gint); - - while (column != -1) - { - GValue value = G_VALUE_INIT; - gchar *error = NULL; - GType col_type; - - if (column >= clutter_model_get_n_columns (model)) - { - g_warning ("%s: Invalid column number %d added to iter " - "(remember to end you list of columns with a -1)", - G_STRLOC, column); - break; - } - - col_type = clutter_model_get_column_type (model, column); - - G_VALUE_COLLECT_INIT (&value, col_type, args, 0, &error); - if (error) - { - g_warning ("%s: %s", G_STRLOC, error); - free (error); - - /* Leak value as it might not be in a sane state */ - break; - } - - clutter_model_iter_set_value_internal (iter, column, &value); - - g_value_unset (&value); - - if (column == clutter_model_get_sorting_column (model)) - sort = TRUE; - - column = va_arg (args, gint); - } - - if (sort) - clutter_model_resort (model); -} - -static void inline -clutter_model_iter_emit_row_changed (ClutterModelIter *iter) -{ - ClutterModelIterPrivate *priv = iter->priv; - ClutterModel *model = priv->model; - - g_assert (CLUTTER_IS_MODEL (model)); - - g_signal_emit (model, model_signals[ROW_CHANGED], 0, iter); -} - -/** - * clutter_model_iter_set_valist: - * @iter: a #ClutterModelIter - * @args: va_list of column/value pairs, terminiated by -1 - * - * See clutter_model_iter_set(); this version takes a va_list for language - * bindings. - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -void -clutter_model_iter_set_valist (ClutterModelIter *iter, - va_list args) -{ - g_return_if_fail (CLUTTER_IS_MODEL_ITER (iter)); - - clutter_model_iter_set_internal_valist (iter, args); - clutter_model_iter_emit_row_changed (iter); -} - -/** - * clutter_model_iter_get: - * @iter: a #ClutterModelIter - * @...: a list of column/return location pairs, terminated by -1 - * - * Gets the value of one or more cells in the row referenced by @iter. The - * variable argument list should contain integer column numbers, each column - * column number followed by a place to store the value being retrieved. The - * list is terminated by a -1. - * - * For example, to get a value from column 0 with type %G_TYPE_STRING use: - * - * clutter_model_iter_get (iter, 0, &place_string_here, -1); - * - * - * where place_string_here is a gchar* to be filled with the string. If - * appropriate, the returned values have to be freed or unreferenced. - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -void -clutter_model_iter_get (ClutterModelIter *iter, - ...) -{ - va_list args; - - g_return_if_fail (CLUTTER_IS_MODEL_ITER (iter)); - - va_start (args, iter); - clutter_model_iter_get_valist (iter, args); - va_end (args); -} - -static inline void -clutter_model_iter_get_value_internal (ClutterModelIter *iter, - guint column, - GValue *value) -{ - CLUTTER_MODEL_ITER_GET_CLASS (iter)->get_value (iter, column, value); -} - -/** - * clutter_model_iter_get_value: - * @iter: a #ClutterModelIter - * @column: column number to retrieve the value from - * @value: (out): an empty #GValue to set - * - * Sets an initializes @value to that at @column. When done with @value, - * g_value_unset() needs to be called to free any allocated memory. - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -void -clutter_model_iter_get_value (ClutterModelIter *iter, - guint column, - GValue *value) -{ - ClutterModel *model; - - g_return_if_fail (CLUTTER_IS_MODEL_ITER (iter)); - - model = iter->priv->model; - - if (G_VALUE_TYPE (value) == G_TYPE_INVALID) - g_value_init (value, clutter_model_get_column_type (model, column)); - - CLUTTER_MODEL_ITER_GET_CLASS (iter)->get_value (iter, column, value); -} - -/** - * clutter_model_iter_get_valist: - * @iter: a #ClutterModelIter - * @args: a list of column/return location pairs, terminated by -1 - * - * See clutter_model_iter_get(). This version takes a va_list for language - * bindings. - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -void -clutter_model_iter_get_valist (ClutterModelIter *iter, - va_list args) -{ - ClutterModelIterPrivate *priv; - ClutterModel *model; - guint column = 0; - - g_return_if_fail (CLUTTER_IS_MODEL_ITER (iter)); - - priv = iter->priv; - model = priv->model; - g_assert (CLUTTER_IS_MODEL (model)); - - column = va_arg (args, gint); - - while (column != -1) - { - GValue value = G_VALUE_INIT; - gchar *error = NULL; - GType col_type; - - if (column >= clutter_model_get_n_columns (model)) - { - g_warning ("%s: Invalid column number %d added to iter " - "(remember to end you list of columns with a -1)", - G_STRLOC, column); - break; - } - - col_type = clutter_model_get_column_type (model, column); - g_value_init (&value, col_type); - - clutter_model_iter_get_value_internal (iter, column, &value); - - G_VALUE_LCOPY (&value, args, 0, &error); - if (error) - { - g_warning ("%s: %s", G_STRLOC, error); - free (error); - - /* Leak value as it might not be in a sane state */ - break; - } - - g_value_unset (&value); - - column = va_arg (args, gint); - } -} - -/** - * clutter_model_iter_set: - * @iter: a #ClutterModelIter - * @...: a list of column/return location pairs, terminated by -1 - * - * Sets the value of one or more cells in the row referenced by @iter. The - * variable argument list should contain integer column numbers, each column - * column number followed by the value to be set. The list is terminated by a - * -1. - * - * For example, to set column 0 with type %G_TYPE_STRING, use: - * - * clutter_model_iter_set (iter, 0, "foo", -1); - * - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -void -clutter_model_iter_set (ClutterModelIter *iter, - ...) -{ - va_list args; - - g_return_if_fail (CLUTTER_IS_MODEL_ITER (iter)); - - va_start (args, iter); - clutter_model_iter_set_internal_valist (iter, args); - clutter_model_iter_emit_row_changed (iter); - va_end (args); -} - -/** - * clutter_model_iter_set_value: - * @iter: a #ClutterModelIter - * @column: column number to retrieve the value from - * @value: new value for the cell - * - * Sets the data in the cell specified by @iter and @column. The type of - * @value must be convertable to the type of the column. - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -void -clutter_model_iter_set_value (ClutterModelIter *iter, - guint column, - const GValue *value) -{ - g_return_if_fail (CLUTTER_IS_MODEL_ITER (iter)); - - clutter_model_iter_set_value_internal (iter, column, value); - clutter_model_iter_emit_row_changed (iter); -} - -/** - * clutter_model_iter_is_first: - * @iter: a #ClutterModelIter - * - * Gets whether the current iterator is at the beginning of the model - * to which it belongs. - * - * Return value: #TRUE if @iter is the first iter in the filtered model - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -gboolean -clutter_model_iter_is_first (ClutterModelIter *iter) -{ - g_return_val_if_fail (CLUTTER_IS_MODEL_ITER (iter), FALSE); - - return CLUTTER_MODEL_ITER_GET_CLASS (iter)->is_first (iter); -} - -/** - * clutter_model_iter_is_last: - * @iter: a #ClutterModelIter - * - * Gets whether the iterator is at the end of the model to which it - * belongs. - * - * Return value: #TRUE if @iter is the last iter in the filtered model. - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -gboolean -clutter_model_iter_is_last (ClutterModelIter *iter) -{ - g_return_val_if_fail (CLUTTER_IS_MODEL_ITER (iter), FALSE); - - return CLUTTER_MODEL_ITER_GET_CLASS (iter)->is_last (iter); -} - -/** - * clutter_model_iter_next: - * @iter: a #ClutterModelIter - * - * Updates the @iter to point at the next position in the model. - * The model implementation should take into account the presence of - * a filter function. - * - * Return value: (transfer none): The passed iterator, updated to point at the next - * row in the model. - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -ClutterModelIter * -clutter_model_iter_next (ClutterModelIter *iter) -{ - g_return_val_if_fail (CLUTTER_IS_MODEL_ITER (iter), NULL); - - return CLUTTER_MODEL_ITER_GET_CLASS (iter)->next (iter); -} - -/** - * clutter_model_iter_prev: - * @iter: a #ClutterModelIter - * - * Sets the @iter to point at the previous position in the model. - * The model implementation should take into account the presence of - * a filter function. - * - * Return value: (transfer none): The passed iterator, updated to point at the previous - * row in the model. - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -ClutterModelIter * -clutter_model_iter_prev (ClutterModelIter *iter) -{ - g_return_val_if_fail (CLUTTER_IS_MODEL_ITER (iter), NULL); - - return CLUTTER_MODEL_ITER_GET_CLASS (iter)->prev (iter); -} - -/** - * clutter_model_iter_get_model: - * @iter: a #ClutterModelIter - * - * Retrieves a pointer to the #ClutterModel that this iter is part of. - * - * Return value: (transfer none): a pointer to a #ClutterModel. - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -ClutterModel * -clutter_model_iter_get_model (ClutterModelIter *iter) -{ - g_return_val_if_fail (CLUTTER_IS_MODEL_ITER (iter), NULL); - - return CLUTTER_MODEL_ITER_GET_CLASS (iter)->get_model (iter); -} - -/** - * clutter_model_iter_get_row: - * @iter: a #ClutterModelIter - * - * Retrieves the position of the row that the @iter points to. - * - * Return value: the position of the @iter in the model - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -guint -clutter_model_iter_get_row (ClutterModelIter *iter) -{ - g_return_val_if_fail (CLUTTER_IS_MODEL_ITER (iter), 0); - - return CLUTTER_MODEL_ITER_GET_CLASS (iter)->get_row (iter); -} - -/** - * clutter_model_iter_copy: - * @iter: a #ClutterModelIter - * - * Copies the passed iterator. - * - * Return value: (transfer full): a copy of the iterator, or %NULL - * - * Since: 0.8 - * - * Deprecated: 1.24: Use #GListModel instead - */ -ClutterModelIter * -clutter_model_iter_copy (ClutterModelIter *iter) -{ - g_return_val_if_fail (CLUTTER_IS_MODEL_ITER (iter), NULL); - - return CLUTTER_MODEL_ITER_GET_CLASS (iter)->copy (iter); -} diff --git a/clutter/clutter/deprecated/clutter-model.h b/clutter/clutter/deprecated/clutter-model.h deleted file mode 100644 index f598f3978..000000000 --- a/clutter/clutter/deprecated/clutter-model.h +++ /dev/null @@ -1,436 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * Neil Jagdish Patel - * Emmanuele Bassi - * - * Copyright (C) 2006 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __CLUTTER_MODEL_H__ -#define __CLUTTER_MODEL_H__ - -#include - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_MODEL (clutter_model_get_type ()) -#define CLUTTER_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_MODEL, ClutterModel)) -#define CLUTTER_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_MODEL, ClutterModelClass)) -#define CLUTTER_IS_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_MODEL)) -#define CLUTTER_IS_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_MODEL)) -#define CLUTTER_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_MODEL, ClutterModelClass)) - -typedef struct _ClutterModel ClutterModel; -typedef struct _ClutterModelClass ClutterModelClass; -typedef struct _ClutterModelPrivate ClutterModelPrivate; -typedef struct _ClutterModelIter ClutterModelIter; -typedef struct _ClutterModelIterClass ClutterModelIterClass; -typedef struct _ClutterModelIterPrivate ClutterModelIterPrivate; - - -/** - * ClutterModelFilterFunc: - * @model: a #ClutterModel - * @iter: the iterator for the row - * @user_data: data passed to clutter_model_set_filter() - * - * Filters the content of a row in the model. - * - * Return value: If the row should be displayed, return %TRUE - * - * Since: 0.6 - * - * Deprecated: 1.24: Implement filters using a custom #GListModel instead - */ -typedef gboolean (*ClutterModelFilterFunc) (ClutterModel *model, - ClutterModelIter *iter, - gpointer user_data); - -/** - * ClutterModelSortFunc: - * @model: a #ClutterModel - * @a: a #GValue representing the contents of the row - * @b: a #GValue representing the contents of the second row - * @user_data: data passed to clutter_model_set_sort() - * - * Compares the content of two rows in the model. - * - * Return value: a positive integer if @a is after @b, a negative integer if - * @a is before @b, or 0 if the rows are the same - * - * Since: 0.6 - * - * Deprecated: 1.24: Implement sorting using a custom #GListModel instead - */ -typedef gint (*ClutterModelSortFunc) (ClutterModel *model, - const GValue *a, - const GValue *b, - gpointer user_data); - -/** - * ClutterModelForeachFunc: - * @model: a #ClutterModel - * @iter: the iterator for the row - * @user_data: data passed to clutter_model_foreach() - * - * Iterates on the content of a row in the model - * - * Return value: %TRUE if the iteration should continue, %FALSE otherwise - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel - */ -typedef gboolean (*ClutterModelForeachFunc) (ClutterModel *model, - ClutterModelIter *iter, - gpointer user_data); - -/** - * ClutterModel: - * - * Base class for list models. The #ClutterModel structure contains - * only private data and should be manipulated using the provided - * API. - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -struct _ClutterModel -{ - /*< private >*/ - GObject parent_instance; - - ClutterModelPrivate *priv; -}; - -/** - * ClutterModelClass: - * @row_added: signal class handler for ClutterModel::row-added - * @row_removed: signal class handler for ClutterModel::row-removed - * @row_changed: signal class handler for ClutterModel::row-changed - * @sort_changed: signal class handler for ClutterModel::sort-changed - * @filter_changed: signal class handler for ClutterModel::filter-changed - * @get_column_name: virtual function for returning the name of a column - * @get_column_type: virtual function for returning the type of a column - * @get_iter_at_row: virtual function for returning an iterator for the - * given row - * @get_n_rows: virtual function for returning the number of rows - * of the model - * @get_n_columns: virtual function for retuning the number of columns - * of the model - * @resort: virtual function for sorting the model using the passed - * sorting function - * @insert_row: virtual function for inserting a row at the given index - * and returning an iterator pointing to it; if the index is a negative - * integer, the row should be appended to the model - * @remove_row: virtual function for removing a row at the given index - * - * Class for #ClutterModel instances. - * - * Since: 0.6 - * - * Deprecated: 1.24: Use #GListModel instead - */ -struct _ClutterModelClass -{ - /*< private >*/ - GObjectClass parent_class; - - /*< public >*/ - /* vtable */ - guint (* get_n_rows) (ClutterModel *model); - guint (* get_n_columns) (ClutterModel *model); - const gchar * (* get_column_name) (ClutterModel *model, - guint column); - GType (* get_column_type) (ClutterModel *model, - guint column); - ClutterModelIter *(* insert_row) (ClutterModel *model, - gint index_); - void (* remove_row) (ClutterModel *model, - guint row); - ClutterModelIter *(* get_iter_at_row) (ClutterModel *model, - guint row); - void (* resort) (ClutterModel *model, - ClutterModelSortFunc func, - gpointer data); - - /* signals */ - void (* row_added) (ClutterModel *model, - ClutterModelIter *iter); - void (* row_removed) (ClutterModel *model, - ClutterModelIter *iter); - void (* row_changed) (ClutterModel *model, - ClutterModelIter *iter); - void (* sort_changed) (ClutterModel *model); - void (* filter_changed) (ClutterModel *model); - - /*< private >*/ - /* padding for future expansion */ - void (*_clutter_model_1) (void); - void (*_clutter_model_2) (void); - void (*_clutter_model_3) (void); - void (*_clutter_model_4) (void); - void (*_clutter_model_5) (void); - void (*_clutter_model_6) (void); - void (*_clutter_model_7) (void); - void (*_clutter_model_8) (void); -}; - -CLUTTER_DEPRECATED_IN_1_24_FOR(g_list_model_get_type) -GType clutter_model_get_type (void) G_GNUC_CONST; - -CLUTTER_DEPRECATED_IN_1_24_FOR(GListModel) -void clutter_model_set_types (ClutterModel *model, - guint n_columns, - GType *types); -CLUTTER_DEPRECATED_IN_1_24_FOR(GListModel) -void clutter_model_set_names (ClutterModel *model, - guint n_columns, - const gchar * const names[]); - -CLUTTER_DEPRECATED_IN_1_24_FOR(GListModel) -void clutter_model_append (ClutterModel *model, - ...); -CLUTTER_DEPRECATED_IN_1_24_FOR(GListModel) -void clutter_model_appendv (ClutterModel *model, - guint n_columns, - guint *columns, - GValue *values); -CLUTTER_DEPRECATED_IN_1_24_FOR(GListModel) -void clutter_model_prepend (ClutterModel *model, - ...); -CLUTTER_DEPRECATED_IN_1_24_FOR(GListModel) -void clutter_model_prependv (ClutterModel *model, - guint n_columns, - guint *columns, - GValue *values); -CLUTTER_DEPRECATED_IN_1_24_FOR(GListModel) -void clutter_model_insert (ClutterModel *model, - guint row, - ...); -CLUTTER_DEPRECATED_IN_1_24_FOR(GListModel) -void clutter_model_insertv (ClutterModel *model, - guint row, - guint n_columns, - guint *columns, - GValue *values); -CLUTTER_DEPRECATED_IN_1_24_FOR(GListModel) -void clutter_model_insert_value (ClutterModel *model, - guint row, - guint column, - const GValue *value); -CLUTTER_DEPRECATED_IN_1_24_FOR(GListModel) -void clutter_model_remove (ClutterModel *model, - guint row); - -CLUTTER_DEPRECATED_IN_1_24_FOR(GListModel) -guint clutter_model_get_n_rows (ClutterModel *model); -CLUTTER_DEPRECATED_IN_1_24_FOR(GListModel) -guint clutter_model_get_n_columns (ClutterModel *model); -CLUTTER_DEPRECATED_IN_1_24_FOR(GListModel) -const gchar * clutter_model_get_column_name (ClutterModel *model, - guint column); -CLUTTER_DEPRECATED_IN_1_24_FOR(GListModel) -GType clutter_model_get_column_type (ClutterModel *model, - guint column); - -CLUTTER_DEPRECATED_IN_1_24_FOR(GListModel) -ClutterModelIter * clutter_model_get_first_iter (ClutterModel *model); -CLUTTER_DEPRECATED_IN_1_24_FOR(GListModel) -ClutterModelIter * clutter_model_get_last_iter (ClutterModel *model); -CLUTTER_DEPRECATED_IN_1_24_FOR(GListModel) -ClutterModelIter * clutter_model_get_iter_at_row (ClutterModel *model, - guint row); - -CLUTTER_DEPRECATED_IN_1_24_FOR(GListModel) -void clutter_model_set_sorting_column (ClutterModel *model, - gint column); -CLUTTER_DEPRECATED_IN_1_24_FOR(GListModel) -gint clutter_model_get_sorting_column (ClutterModel *model); - -CLUTTER_DEPRECATED_IN_1_24_FOR(GListModel) -void clutter_model_foreach (ClutterModel *model, - ClutterModelForeachFunc func, - gpointer user_data); -CLUTTER_DEPRECATED_IN_1_24_FOR(GListModel) -void clutter_model_set_sort (ClutterModel *model, - gint column, - ClutterModelSortFunc func, - gpointer user_data, - GDestroyNotify notify); -CLUTTER_DEPRECATED_IN_1_24_FOR(GListModel) -void clutter_model_set_filter (ClutterModel *model, - ClutterModelFilterFunc func, - gpointer user_data, - GDestroyNotify notify); -CLUTTER_DEPRECATED_IN_1_24_FOR(GListModel) -gboolean clutter_model_get_filter_set (ClutterModel *model); - -CLUTTER_DEPRECATED_IN_1_24_FOR(GListModel) -void clutter_model_resort (ClutterModel *model); -CLUTTER_DEPRECATED_IN_1_24_FOR(GListModel) -gboolean clutter_model_filter_row (ClutterModel *model, - guint row); -CLUTTER_DEPRECATED_IN_1_24_FOR(GListModel) -gboolean clutter_model_filter_iter (ClutterModel *model, - ClutterModelIter *iter); - -/* - * ClutterModelIter - */ - -#define CLUTTER_TYPE_MODEL_ITER (clutter_model_iter_get_type ()) -#define CLUTTER_MODEL_ITER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_MODEL_ITER, ClutterModelIter)) -#define CLUTTER_MODEL_ITER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_MODEL_ITER, ClutterModelIterClass)) -#define CLUTTER_IS_MODEL_ITER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_MODEL_ITER)) -#define CLUTTER_IS_MODEL_ITER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_MODEL_ITER)) -#define CLUTTER_MODEL_ITER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_MODEL_ITER, ClutterModelIterClass)) - -/** - * ClutterModelIter: - * - * Base class for list models iters. The #ClutterModelIter structure - * contains only private data and should be manipulated using the - * provided API. - * - * Since: 0.6 - * - * Deprecated: 1.24: Use custom iterators for #GListModel - */ -struct _ClutterModelIter -{ - /*< private >*/ - GObject parent_instance; - - ClutterModelIterPrivate *priv; -}; - -/** - * ClutterModelIterClass: - * @get_value: Virtual function for retrieving the value at the given - * column of the row pointed by the iterator - * @set_value: Virtual function for setting the value at the given - * column of the row pointer by the iterator - * @is_last: Virtual function for knowing whether the iterator points - * at the last row in the model - * @is_first: Virtual function for knowing whether the iterator points - * at the first row in the model - * @next: Virtual function for moving the iterator to the following - * row in the model - * @prev: Virtual function for moving the iterator toe the previous - * row in the model - * @get_model: Virtual function for getting the model to which the - * iterator belongs to - * @get_row: Virtual function for getting the row to which the iterator - * points - * @copy: Virtual function for copying a #ClutterModelIter. - * - * Class for #ClutterModelIter instances. - * - * Since: 0.6 - * - * Deprecated: 1.24: Use custom iterators for #GListModel - */ -struct _ClutterModelIterClass -{ - /*< private >*/ - GObjectClass parent_class; - - /*< public >*/ - /* vtable not signals */ - void (* get_value) (ClutterModelIter *iter, - guint column, - GValue *value); - void (* set_value) (ClutterModelIter *iter, - guint column, - const GValue *value); - - gboolean (* is_first) (ClutterModelIter *iter); - gboolean (* is_last) (ClutterModelIter *iter); - - ClutterModelIter *(* next) (ClutterModelIter *iter); - ClutterModelIter *(* prev) (ClutterModelIter *iter); - - ClutterModel * (* get_model) (ClutterModelIter *iter); - guint (* get_row) (ClutterModelIter *iter); - - ClutterModelIter *(* copy) (ClutterModelIter *iter); - - /*< private >*/ - /* padding for future expansion */ - void (*_clutter_model_iter_1) (void); - void (*_clutter_model_iter_2) (void); - void (*_clutter_model_iter_3) (void); - void (*_clutter_model_iter_4) (void); - void (*_clutter_model_iter_5) (void); - void (*_clutter_model_iter_6) (void); - void (*_clutter_model_iter_7) (void); - void (*_clutter_model_iter_8) (void); -}; - -CLUTTER_DEPRECATED_IN_1_24 -GType clutter_model_iter_get_type (void) G_GNUC_CONST; - -CLUTTER_DEPRECATED_IN_1_24 -void clutter_model_iter_get (ClutterModelIter *iter, - ...); -CLUTTER_DEPRECATED_IN_1_24 -void clutter_model_iter_get_valist (ClutterModelIter *iter, - va_list args); -CLUTTER_DEPRECATED_IN_1_24 -void clutter_model_iter_get_value (ClutterModelIter *iter, - guint column, - GValue *value); -CLUTTER_DEPRECATED_IN_1_24 -void clutter_model_iter_set (ClutterModelIter *iter, - ...); -CLUTTER_DEPRECATED_IN_1_24 -void clutter_model_iter_set_valist (ClutterModelIter *iter, - va_list args); -CLUTTER_DEPRECATED_IN_1_24 -void clutter_model_iter_set_value (ClutterModelIter *iter, - guint column, - const GValue *value); - -CLUTTER_DEPRECATED_IN_1_24 -gboolean clutter_model_iter_is_first (ClutterModelIter *iter); -CLUTTER_DEPRECATED_IN_1_24 -gboolean clutter_model_iter_is_last (ClutterModelIter *iter); -CLUTTER_DEPRECATED_IN_1_24 -ClutterModelIter *clutter_model_iter_next (ClutterModelIter *iter); -CLUTTER_DEPRECATED_IN_1_24 -ClutterModelIter *clutter_model_iter_prev (ClutterModelIter *iter); - -CLUTTER_DEPRECATED_IN_1_24 -ClutterModel * clutter_model_iter_get_model (ClutterModelIter *iter); -CLUTTER_DEPRECATED_IN_1_24 -guint clutter_model_iter_get_row (ClutterModelIter *iter); - -CLUTTER_DEPRECATED_IN_1_24 -ClutterModelIter *clutter_model_iter_copy (ClutterModelIter *iter); - -G_END_DECLS - -#endif /* __CLUTTER_MODEL_H__ */ diff --git a/clutter/clutter/deprecated/clutter-rectangle.c b/clutter/clutter/deprecated/clutter-rectangle.c index e4cfeb48a..fafcafa26 100644 --- a/clutter/clutter/deprecated/clutter-rectangle.c +++ b/clutter/clutter/deprecated/clutter-rectangle.c @@ -36,9 +36,7 @@ * Cairo 2D API instead. */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #define CLUTTER_DISABLE_DEPRECATION_WARNINGS #include "deprecated/clutter-rectangle.h" @@ -80,70 +78,105 @@ static const ClutterColor default_border_color = { 0, 0, 0, 255 }; G_DEFINE_TYPE_WITH_PRIVATE (ClutterRectangle, clutter_rectangle, CLUTTER_TYPE_ACTOR) static void -clutter_rectangle_paint (ClutterActor *self) +clutter_rectangle_paint (ClutterActor *self, + ClutterPaintContext *paint_context) { ClutterRectanglePrivate *priv = CLUTTER_RECTANGLE (self)->priv; - ClutterGeometry geom; + CoglFramebuffer *framebuffer = + clutter_paint_context_get_framebuffer (paint_context); + static CoglPipeline *default_color_pipeline = NULL; + CoglPipeline *content_pipeline; + ClutterActorBox alloc; + CoglColor color; guint8 tmp_alpha; CLUTTER_NOTE (PAINT, "painting rect '%s'", clutter_actor_get_name (self) ? clutter_actor_get_name (self) : "unknown"); - clutter_actor_get_allocation_geometry (self, &geom); + clutter_actor_get_allocation_box (self, &alloc); + + if (G_UNLIKELY (default_color_pipeline == NULL)) + { + CoglContext *ctx = + clutter_backend_get_cogl_context (clutter_get_default_backend ()); + default_color_pipeline = cogl_pipeline_new (ctx); + } + + g_assert (default_color_pipeline != NULL); + content_pipeline = cogl_pipeline_copy (default_color_pipeline); + + /* compute the composited opacity of the actor taking into + * account the opacity of the color set by the user + */ + tmp_alpha = clutter_actor_get_paint_opacity (self) + * priv->color.alpha + / 255; + + cogl_color_init_from_4ub (&color, + priv->color.red, + priv->color.green, + priv->color.blue, + tmp_alpha); + cogl_color_premultiply (&color); + cogl_pipeline_set_color (content_pipeline, &color); if (priv->has_border) { + CoglPipeline *border_pipeline; + + border_pipeline = cogl_pipeline_copy (default_color_pipeline); + + tmp_alpha = clutter_actor_get_paint_opacity (self) + * priv->border_color.alpha + / 255; + + cogl_color_init_from_4ub (&color, + priv->border_color.red, + priv->border_color.green, + priv->border_color.blue, + tmp_alpha); + cogl_color_premultiply (&color); + cogl_pipeline_set_color (border_pipeline, &color); + /* We paint the border and the content only if the rectangle * is big enough to show them */ - if ((priv->border_width * 2) < geom.width && - (priv->border_width * 2) < geom.height) + if ((priv->border_width * 2) < clutter_actor_box_get_width (&alloc) && + (priv->border_width * 2) < clutter_actor_box_get_height (&alloc)) { - /* compute the composited opacity of the actor taking into - * account the opacity of the color set by the user - */ - tmp_alpha = clutter_actor_get_paint_opacity (self) - * priv->border_color.alpha - / 255; - - /* paint the border */ - cogl_set_source_color4ub (priv->border_color.red, - priv->border_color.green, - priv->border_color.blue, - tmp_alpha); - - /* this sucks, but it's the only way to make a border */ - cogl_rectangle (priv->border_width, 0, - geom.width, - priv->border_width); - - cogl_rectangle (geom.width - priv->border_width, - priv->border_width, - geom.width, - geom.height); - - cogl_rectangle (0, geom.height - priv->border_width, - geom.width - priv->border_width, - geom.height); - - cogl_rectangle (0, 0, - priv->border_width, - geom.height - priv->border_width); - - tmp_alpha = clutter_actor_get_paint_opacity (self) - * priv->color.alpha - / 255; + /* paint the border. this sucks, but it's the only way to make a border */ + cogl_framebuffer_draw_rectangle (framebuffer, + border_pipeline, + priv->border_width, 0, + clutter_actor_box_get_width (&alloc), + priv->border_width); + + cogl_framebuffer_draw_rectangle (framebuffer, + border_pipeline, + clutter_actor_box_get_width (&alloc) - priv->border_width, + priv->border_width, + clutter_actor_box_get_width (&alloc), + clutter_actor_box_get_height (&alloc)); + + cogl_framebuffer_draw_rectangle (framebuffer, + border_pipeline, + 0, clutter_actor_box_get_height (&alloc) - priv->border_width, + clutter_actor_box_get_width (&alloc) - priv->border_width, + clutter_actor_box_get_height (&alloc)); + + cogl_framebuffer_draw_rectangle (framebuffer, + border_pipeline, + 0, 0, + priv->border_width, + clutter_actor_box_get_height (&alloc) - priv->border_width); /* now paint the rectangle */ - cogl_set_source_color4ub (priv->color.red, - priv->color.green, - priv->color.blue, - tmp_alpha); - - cogl_rectangle (priv->border_width, priv->border_width, - geom.width - priv->border_width, - geom.height - priv->border_width); + cogl_framebuffer_draw_rectangle (framebuffer, + content_pipeline, + priv->border_width, priv->border_width, + clutter_actor_box_get_width (&alloc) - priv->border_width, + clutter_actor_box_get_height (&alloc) - priv->border_width); } else { @@ -151,34 +184,25 @@ clutter_rectangle_paint (ClutterActor *self) * as the border, since we can only fit that into the * allocation. */ - tmp_alpha = clutter_actor_get_paint_opacity (self) - * priv->border_color.alpha - / 255; - - cogl_set_source_color4ub (priv->border_color.red, - priv->border_color.green, - priv->border_color.blue, - tmp_alpha); - - cogl_rectangle (0, 0, geom.width, geom.height); + cogl_framebuffer_draw_rectangle (framebuffer, + border_pipeline, + 0, 0, + clutter_actor_box_get_width (&alloc), + clutter_actor_box_get_height (&alloc)); } + + cogl_object_unref (border_pipeline); } else { - /* compute the composited opacity of the actor taking into - * account the opacity of the color set by the user - */ - tmp_alpha = clutter_actor_get_paint_opacity (self) - * priv->color.alpha - / 255; - - cogl_set_source_color4ub (priv->color.red, - priv->color.green, - priv->color.blue, - tmp_alpha); - - cogl_rectangle (0, 0, geom.width, geom.height); + cogl_framebuffer_draw_rectangle (framebuffer, + content_pipeline, + 0, 0, + clutter_actor_box_get_width (&alloc), + clutter_actor_box_get_height (&alloc)); } + + cogl_object_unref (content_pipeline); } static gboolean diff --git a/clutter/clutter/deprecated/clutter-rectangle.h b/clutter/clutter/deprecated/clutter-rectangle.h index ba58bbc8a..0bcda2f14 100644 --- a/clutter/clutter/deprecated/clutter-rectangle.h +++ b/clutter/clutter/deprecated/clutter-rectangle.h @@ -80,35 +80,35 @@ struct _ClutterRectangleClass void (*_clutter_rectangle4) (void); }; -CLUTTER_DEPRECATED_IN_1_10 +CLUTTER_DEPRECATED GType clutter_rectangle_get_type (void) G_GNUC_CONST; -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_new) +CLUTTER_DEPRECATED_FOR(clutter_actor_new) ClutterActor *clutter_rectangle_new (void); -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_new) +CLUTTER_DEPRECATED_FOR(clutter_actor_new) ClutterActor *clutter_rectangle_new_with_color (const ClutterColor *color); -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_get_background_color) +CLUTTER_DEPRECATED_FOR(clutter_actor_get_background_color) void clutter_rectangle_get_color (ClutterRectangle *rectangle, ClutterColor *color); -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_set_background_color) +CLUTTER_DEPRECATED_FOR(clutter_actor_set_background_color) void clutter_rectangle_set_color (ClutterRectangle *rectangle, const ClutterColor *color); -CLUTTER_DEPRECATED_IN_1_10 +CLUTTER_DEPRECATED guint clutter_rectangle_get_border_width (ClutterRectangle *rectangle); -CLUTTER_DEPRECATED_IN_1_10 +CLUTTER_DEPRECATED void clutter_rectangle_set_border_width (ClutterRectangle *rectangle, guint width); -CLUTTER_DEPRECATED_IN_1_10 +CLUTTER_DEPRECATED void clutter_rectangle_get_border_color (ClutterRectangle *rectangle, ClutterColor *color); -CLUTTER_DEPRECATED_IN_1_10 +CLUTTER_DEPRECATED void clutter_rectangle_set_border_color (ClutterRectangle *rectangle, const ClutterColor *color); diff --git a/clutter/clutter/deprecated/clutter-score.c b/clutter/clutter/deprecated/clutter-score.c deleted file mode 100644 index b4e2f1f97..000000000 --- a/clutter/clutter/deprecated/clutter-score.c +++ /dev/null @@ -1,1168 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * Copyright (C) 2007 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -/** - * SECTION:clutter-score - * @short_description: Controller for multiple timelines - * - * #ClutterScore is a base class for sequencing multiple timelines in order. - * Using #ClutterScore it is possible to start multiple timelines at the - * same time or launch multiple timelines when a particular timeline has - * emitted the ClutterTimeline::completed signal. - * - * Each time a #ClutterTimeline is started and completed, a signal will be - * emitted. - * - * For example, this code will start two #ClutterTimelines after - * a third timeline terminates: - * - * |[ - * ClutterTimeline *timeline_1, *timeline_2, *timeline_3; - * ClutterScore *score; - * - * timeline_1 = clutter_timeline_new_for_duration (1000); - * timeline_2 = clutter_timeline_new_for_duration (500); - * timeline_3 = clutter_timeline_new_for_duration (500); - * - * score = clutter_score_new (); - * - * clutter_score_append (score, NULL, timeline_1); - * clutter_score_append (score, timeline_1, timeline_2); - * clutter_score_append (score, timeline_1, timeline_3); - * - * clutter_score_start (score); - * ]| - * - * A #ClutterScore takes a reference on the timelines it manages, - * so timelines can be safely unreferenced after being appended. - * - * New timelines can be appended to the #ClutterScore using - * clutter_score_append() and removed using clutter_score_remove(). - * - * Timelines can also be appended to a specific marker on the - * parent timeline, using clutter_score_append_at_marker(). - * - * The score can be cleared using clutter_score_remove_all(). - * - * The list of timelines can be retrieved using - * clutter_score_list_timelines(). - * - * The score state is controlled using clutter_score_start(), - * clutter_score_pause(), clutter_score_stop() and clutter_score_rewind(). - * The state can be queried using clutter_score_is_playing(). - * - * #ClutterScore is available since Clutter 0.6 - * - * Deprecated: 1.8: Use #ClutterAnimator or #ClutterState to create - * complex animations involving multiple timelines. - */ - -#ifdef HAVE_CONFIG_H -#include "clutter-build-config.h" -#endif - -#define CLUTTER_DISABLE_DEPRECATION_WARNINGS - -#include "clutter-score.h" -#include "clutter-main.h" -#include "clutter-marshal.h" -#include "clutter-private.h" -#include "clutter-debug.h" - -typedef struct _ClutterScoreEntry ClutterScoreEntry; - -struct _ClutterScoreEntry -{ - /* the entry unique id */ - gulong id; - - ClutterTimeline *timeline; - ClutterTimeline *parent; - - /* the optional marker on the parent */ - gchar *marker; - - /* signal handlers id */ - gulong complete_id; - gulong marker_id; - - ClutterScore *score; - - /* pointer back to the tree structure */ - GNode *node; -}; - -struct _ClutterScorePrivate -{ - GNode *root; - - GHashTable *running_timelines; - - gulong last_id; - - guint is_paused : 1; - guint loop : 1; -}; - -enum -{ - PROP_0, - - PROP_LOOP -}; - -enum -{ - TIMELINE_STARTED, - TIMELINE_COMPLETED, - - STARTED, - PAUSED, - COMPLETED, - - LAST_SIGNAL -}; - -static inline void clutter_score_clear (ClutterScore *score); - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterScore, clutter_score, G_TYPE_OBJECT) - -static int score_signals[LAST_SIGNAL] = { 0 }; - -/* Object */ - -static void -clutter_score_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterScorePrivate *priv; - - priv = clutter_score_get_instance_private (CLUTTER_SCORE (gobject)); - - switch (prop_id) - { - case PROP_LOOP: - priv->loop = g_value_get_boolean (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_score_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterScorePrivate *priv; - - priv = clutter_score_get_instance_private (CLUTTER_SCORE (gobject)); - - switch (prop_id) - { - case PROP_LOOP: - g_value_set_boolean (value, priv->loop); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_score_finalize (GObject *object) -{ - ClutterScore *score = CLUTTER_SCORE (object); - - clutter_score_stop (score); - clutter_score_clear (score); - - G_OBJECT_CLASS (clutter_score_parent_class)->finalize (object); -} - -static void -clutter_score_class_init (ClutterScoreClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - gobject_class->set_property = clutter_score_set_property; - gobject_class->get_property = clutter_score_get_property; - gobject_class->finalize = clutter_score_finalize; - - /** - * ClutterScore:loop: - * - * Whether the #ClutterScore should restart once finished. - * - * Since: 0.6 - * Deprecated: 1.8 - */ - g_object_class_install_property (gobject_class, - PROP_LOOP, - g_param_spec_boolean ("loop", - "Loop", - "Whether the score should restart once finished", - FALSE, - CLUTTER_PARAM_READWRITE)); - - /** - * ClutterScore::timeline-started: - * @score: the score which received the signal - * @timeline: the current timeline - * - * The ::timeline-started signal is emitted each time a new timeline - * inside a #ClutterScore starts playing. - * - * Since: 0.6 - * Deprecated: 1.8 - */ - score_signals[TIMELINE_STARTED] = - g_signal_new ("timeline-started", - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterScoreClass, timeline_started), - NULL, NULL, - _clutter_marshal_VOID__OBJECT, - G_TYPE_NONE, - 1, CLUTTER_TYPE_TIMELINE); - /** - * ClutterScore::timeline-completed: - * @score: the score which received the signal - * @timeline: the completed timeline - * - * The ::timeline-completed signal is emitted each time a timeline - * inside a #ClutterScore terminates. - * - * Since: 0.6 - * Deprecated: 1.8 - */ - score_signals[TIMELINE_COMPLETED] = - g_signal_new ("timeline-completed", - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterScoreClass, timeline_completed), - NULL, NULL, - _clutter_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - CLUTTER_TYPE_TIMELINE); - /** - * ClutterScore::completed: - * @score: the score which received the signal - * - * The ::completed signal is emitted each time a #ClutterScore terminates. - * - * Since: 0.6 - * Deprecated: 1.8 - */ - score_signals[COMPLETED] = - g_signal_new ("completed", - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterScoreClass, completed), - NULL, NULL, - _clutter_marshal_VOID__VOID, - G_TYPE_NONE, 0); - /** - * ClutterScore::started: - * @score: the score which received the signal - * - * The ::started signal is emitted each time a #ClutterScore starts playing. - * - * Since: 0.6 - * Deprecated: 1.8 - */ - score_signals[STARTED] = - g_signal_new ("started", - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterScoreClass, started), - NULL, NULL, - _clutter_marshal_VOID__VOID, - G_TYPE_NONE, 0); - /** - * ClutterScore::paused: - * @score: the score which received the signal - * - * The ::paused signal is emitted each time a #ClutterScore - * is paused. - * - * Since: 0.6 - * Deprecated: 1.8 - */ - score_signals[PAUSED] = - g_signal_new ("paused", - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterScoreClass, paused), - NULL, NULL, - _clutter_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - -static void -clutter_score_init (ClutterScore *self) -{ - ClutterScorePrivate *priv; - - self->priv = priv = clutter_score_get_instance_private (self); - - /* sentinel */ - priv->root = g_node_new (NULL); - - priv->running_timelines = NULL; - - priv->is_paused = FALSE; - priv->loop = FALSE; - - priv->last_id = 1; -} - -/** - * clutter_score_new: - * - * Creates a new #ClutterScore. A #ClutterScore is an object that can - * hold multiple #ClutterTimelines in a sequential order. - * - * Return value: the newly created #ClutterScore. Use g_object_unref() - * when done. - * - * Since: 0.6 - * Deprecated: 1.8 - */ -ClutterScore * -clutter_score_new (void) -{ - return g_object_new (CLUTTER_TYPE_SCORE, NULL); -} - -/** - * clutter_score_set_loop: - * @score: a #ClutterScore - * @loop: %TRUE for enable looping - * - * Sets whether @score should loop. A looping #ClutterScore will start - * from its initial state after the ::complete signal has been fired. - * - * Since: 0.6 - * Deprecated: 1.8 - */ -void -clutter_score_set_loop (ClutterScore *score, - gboolean loop) -{ - g_return_if_fail (CLUTTER_IS_SCORE (score)); - - if (score->priv->loop != loop) - { - score->priv->loop = loop; - - g_object_notify (G_OBJECT (score), "loop"); - } -} - -/** - * clutter_score_get_loop: - * @score: a #ClutterScore - * - * Gets whether @score is looping - * - * Return value: %TRUE if the score is looping - * - * Since: 0.6 - * Deprecated: 1.8 - */ -gboolean -clutter_score_get_loop (ClutterScore *score) -{ - g_return_val_if_fail (CLUTTER_IS_SCORE (score), FALSE); - - return score->priv->loop; -} - -/** - * clutter_score_is_playing: - * @score: A #ClutterScore - * - * Query state of a #ClutterScore instance. - * - * Return Value: %TRUE if score is currently playing - * - * Since: 0.6 - * Deprecated: 1.8 - */ -gboolean -clutter_score_is_playing (ClutterScore *score) -{ - g_return_val_if_fail (CLUTTER_IS_SCORE (score), FALSE); - - if (score->priv->is_paused) - return FALSE; - - return score->priv->running_timelines - && g_hash_table_size (score->priv->running_timelines) != 0; -} - -/* destroy_entry: - * @node: a #GNode - * - * Frees the #ClutterScoreEntry attached to @node. - */ -static gboolean -destroy_entry (GNode *node, - G_GNUC_UNUSED gpointer data) -{ - ClutterScoreEntry *entry = node->data; - - if (G_LIKELY (entry != NULL)) - { - if (entry->marker_id) - { - g_signal_handler_disconnect (entry->parent, entry->marker_id); - entry->marker_id = 0; - } - - if (entry->complete_id) - { - g_signal_handler_disconnect (entry->timeline, entry->complete_id); - entry->complete_id = 0; - } - - g_object_unref (entry->timeline); - free (entry->marker); - g_slice_free (ClutterScoreEntry, entry); - - node->data = NULL; - } - - /* continue */ - return FALSE; -} - -typedef enum { - FIND_BY_TIMELINE, - FIND_BY_ID, - REMOVE_BY_ID, - LIST_TIMELINES -} TraverseAction; - -typedef struct { - TraverseAction action; - - ClutterScore *score; - - /* parameters */ - union { - ClutterTimeline *timeline; - gulong id; - ClutterScoreEntry *entry; - } d; - - gpointer result; -} TraverseClosure; - -/* multi-purpose traversal function for the N-ary tree used by the score */ -static gboolean -traverse_children (GNode *node, - gpointer data) -{ - TraverseClosure *closure = data; - ClutterScoreEntry *entry = node->data; - gboolean retval = FALSE; - - /* root */ - if (!entry) - return TRUE; - - switch (closure->action) - { - case FIND_BY_TIMELINE: - if (closure->d.timeline == entry->timeline) - { - closure->result = node; - retval = TRUE; - } - break; - - case FIND_BY_ID: - if (closure->d.id == entry->id) - { - closure->result = node; - retval = TRUE; - } - break; - - case REMOVE_BY_ID: - if (closure->d.id == entry->id) - { - /* Destroy all the child entries of this node */ - g_node_traverse (node, - G_POST_ORDER, - G_TRAVERSE_ALL, - -1, - destroy_entry, NULL); - - /* Keep track of this node so that it will be destroyed - further up */ - closure->result = node; - - retval = TRUE; - } - break; - - case LIST_TIMELINES: - closure->result = g_slist_prepend (closure->result, entry->timeline); - retval = FALSE; - break; - } - - return retval; -} - -static GNode * -find_entry_by_timeline (ClutterScore *score, - ClutterTimeline *timeline) -{ - ClutterScorePrivate *priv = score->priv; - TraverseClosure closure; - - closure.action = FIND_BY_TIMELINE; - closure.score = score; - closure.d.timeline = timeline; - closure.result = NULL; - - g_node_traverse (priv->root, - G_POST_ORDER, - G_TRAVERSE_ALL, - -1, - traverse_children, &closure); - - if (closure.result) - return closure.result; - - return NULL; -} - -static GNode * -find_entry_by_id (ClutterScore *score, - gulong id_) -{ - ClutterScorePrivate *priv = score->priv; - TraverseClosure closure; - - closure.action = FIND_BY_ID; - closure.score = score; - closure.d.id = id_; - closure.result = NULL; - - g_node_traverse (priv->root, - G_POST_ORDER, - G_TRAVERSE_ALL, - -1, - traverse_children, &closure); - - if (closure.result) - return closure.result; - - return NULL; -} - -/* forward declaration */ -static void start_entry (ClutterScoreEntry *entry); - -static void -start_children_entries (GNode *node, - gpointer data) -{ - ClutterScoreEntry *entry = node->data; - - /* If data is NULL, start all entries that have no marker, otherwise - only start entries that have the same marker */ - if (data == NULL - ? entry->marker == NULL - : (entry->marker && !strcmp (data, entry->marker))) - start_entry (entry); -} - -static void -on_timeline_marker (ClutterTimeline *timeline, - const gchar *marker_name, - gint frame_num, - ClutterScoreEntry *entry) -{ - GNode *parent; - CLUTTER_NOTE (SCHEDULER, "timeline [%p] marker ('%s') reached", - entry->timeline, - entry->marker); - - parent = find_entry_by_timeline (entry->score, timeline); - if (!parent) - return; - - /* start every child */ - if (parent->children) - { - g_node_children_foreach (parent, - G_TRAVERSE_ALL, - start_children_entries, - (gpointer) marker_name); - } -} - -static void -on_timeline_completed (ClutterTimeline *timeline, - ClutterScoreEntry *entry) -{ - ClutterScorePrivate *priv = entry->score->priv; - - g_hash_table_remove (priv->running_timelines, - GUINT_TO_POINTER (entry->id)); - - g_signal_handler_disconnect (timeline, entry->complete_id); - entry->complete_id = 0; - - CLUTTER_NOTE (SCHEDULER, "timeline [%p] ('%lu') completed", - entry->timeline, - entry->id); - - g_signal_emit (entry->score, score_signals[TIMELINE_COMPLETED], 0, - entry->timeline); - - /* start every child */ - if (entry->node->children) - { - g_node_children_foreach (entry->node, - G_TRAVERSE_ALL, - start_children_entries, - NULL); - } - - /* score has finished - fire 'completed' signal */ - if (g_hash_table_size (priv->running_timelines) == 0) - { - CLUTTER_NOTE (SCHEDULER, "looks like we finished"); - - g_signal_emit (entry->score, score_signals[COMPLETED], 0); - - clutter_score_stop (entry->score); - - if (priv->loop) - clutter_score_start (entry->score); - } -} - -static void -start_entry (ClutterScoreEntry *entry) -{ - ClutterScorePrivate *priv = entry->score->priv; - - /* timelines attached to a marker might already be playing when we - * end up here from the ::completed handler, so we need to perform - * this check to avoid restarting those timelines - */ - if (clutter_timeline_is_playing (entry->timeline)) - return; - - entry->complete_id = g_signal_connect (entry->timeline, - "completed", - G_CALLBACK (on_timeline_completed), - entry); - - CLUTTER_NOTE (SCHEDULER, "timeline [%p] ('%lu') started", - entry->timeline, - entry->id); - - if (G_UNLIKELY (priv->running_timelines == NULL)) - priv->running_timelines = g_hash_table_new (NULL, NULL); - - g_hash_table_insert (priv->running_timelines, - GUINT_TO_POINTER (entry->id), - entry); - - clutter_timeline_start (entry->timeline); - - g_signal_emit (entry->score, score_signals[TIMELINE_STARTED], 0, - entry->timeline); -} - -enum -{ - ACTION_START, - ACTION_PAUSE, - ACTION_STOP -}; - -static void -foreach_running_timeline (gpointer key, - gpointer value, - gpointer user_data) -{ - ClutterScoreEntry *entry = value; - gint action = GPOINTER_TO_INT (user_data); - - switch (action) - { - case ACTION_START: - clutter_timeline_start (entry->timeline); - break; - - case ACTION_PAUSE: - clutter_timeline_pause (entry->timeline); - break; - - case ACTION_STOP: - if (entry->complete_id) - { - g_signal_handler_disconnect (entry->timeline, entry->complete_id); - entry->complete_id = 0; - } - clutter_timeline_stop (entry->timeline); - break; - } -} - -/** - * clutter_score_start: - * @score: A #ClutterScore - * - * Starts the score. - * - * Since: 0.6 - * Deprecated: 1.8 - */ -void -clutter_score_start (ClutterScore *score) -{ - ClutterScorePrivate *priv; - - g_return_if_fail (CLUTTER_IS_SCORE (score)); - - priv = score->priv; - - if (priv->is_paused) - { - g_hash_table_foreach (priv->running_timelines, - foreach_running_timeline, - GINT_TO_POINTER (ACTION_START)); - priv->is_paused = FALSE; - } - else - { - g_signal_emit (score, score_signals[STARTED], 0); - g_node_children_foreach (priv->root, - G_TRAVERSE_ALL, - start_children_entries, - NULL); - } -} - -/** - * clutter_score_stop: - * @score: A #ClutterScore - * - * Stops and rewinds a playing #ClutterScore instance. - * - * Since: 0.6 - * Deprecated: 1.8 - */ -void -clutter_score_stop (ClutterScore *score) -{ - ClutterScorePrivate *priv; - - g_return_if_fail (CLUTTER_IS_SCORE (score)); - - priv = score->priv; - - if (priv->running_timelines) - { - g_hash_table_foreach (priv->running_timelines, - foreach_running_timeline, - GINT_TO_POINTER (ACTION_STOP)); - g_hash_table_destroy (priv->running_timelines); - priv->running_timelines = NULL; - } -} - -/** - * clutter_score_pause: - * @score: a #ClutterScore - * - * Pauses a playing score @score. - * - * Since: 0.6 - * Deprecated: 1.8 - */ -void -clutter_score_pause (ClutterScore *score) -{ - ClutterScorePrivate *priv; - - g_return_if_fail (CLUTTER_IS_SCORE (score)); - - priv = score->priv; - - if (!clutter_score_is_playing (score)) - return; - - g_hash_table_foreach (priv->running_timelines, - foreach_running_timeline, - GINT_TO_POINTER (ACTION_PAUSE)); - - priv->is_paused = TRUE; - - g_signal_emit (score, score_signals[PAUSED], 0); -} - -/** - * clutter_score_rewind: - * @score: A #ClutterScore - * - * Rewinds a #ClutterScore to its initial state. - * - * Since: 0.6 - * Deprecated: 1.8 - */ -void -clutter_score_rewind (ClutterScore *score) -{ - gboolean was_playing; - - g_return_if_fail (CLUTTER_IS_SCORE (score)); - - was_playing = clutter_score_is_playing (score); - - clutter_score_stop (score); - - if (was_playing) - clutter_score_start (score); -} - -static inline void -clutter_score_clear (ClutterScore *score) -{ - ClutterScorePrivate *priv = score->priv; - - g_node_traverse (priv->root, - G_POST_ORDER, - G_TRAVERSE_ALL, - -1, - destroy_entry, NULL); - g_node_destroy (priv->root); -} - -/** - * clutter_score_append: - * @score: a #ClutterScore - * @parent: (allow-none): a #ClutterTimeline in the score, or %NULL - * @timeline: a #ClutterTimeline - * - * Appends a timeline to another one existing in the score; the newly - * appended timeline will be started when @parent is complete. - * - * If @parent is %NULL, the new #ClutterTimeline will be started when - * clutter_score_start() is called. - * - * #ClutterScore will take a reference on @timeline. - * - * Return value: the id of the #ClutterTimeline inside the score, or - * 0 on failure. The returned id can be used with clutter_score_remove() - * or clutter_score_get_timeline(). - * - * Since: 0.6 - * Deprecated: 1.8 - */ -gulong -clutter_score_append (ClutterScore *score, - ClutterTimeline *parent, - ClutterTimeline *timeline) -{ - ClutterScorePrivate *priv; - ClutterScoreEntry *entry; - - g_return_val_if_fail (CLUTTER_IS_SCORE (score), 0); - g_return_val_if_fail (parent == NULL || CLUTTER_IS_TIMELINE (parent), 0); - g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), 0); - - priv = score->priv; - - if (!parent) - { - entry = g_slice_new (ClutterScoreEntry); - entry->timeline = g_object_ref (timeline); - entry->parent = NULL; - entry->id = priv->last_id; - entry->marker = NULL; - entry->marker_id = 0; - entry->complete_id = 0; - entry->score = score; - - entry->node = g_node_append_data (priv->root, entry); - } - else - { - GNode *node; - - node = find_entry_by_timeline (score, parent); - if (G_UNLIKELY (!node)) - { - g_warning ("Unable to find the parent timeline inside the score."); - return 0; - } - - entry = g_slice_new (ClutterScoreEntry); - entry->timeline = g_object_ref (timeline); - entry->parent = parent; - entry->id = priv->last_id; - entry->marker = NULL; - entry->marker_id = 0; - entry->complete_id = 0; - entry->score = score; - - entry->node = g_node_append_data (node, entry); - } - - priv->last_id += 1; - - return entry->id; -} - -/** - * clutter_score_append_at_marker: - * @score: a #ClutterScore - * @parent: the parent #ClutterTimeline - * @marker_name: the name of the marker to use - * @timeline: the #ClutterTimeline to append - * - * Appends @timeline at the given @marker_name on the @parent - * #ClutterTimeline. - * - * If you want to append @timeline at the end of @parent, use - * clutter_score_append(). - * - * The #ClutterScore will take a reference on @timeline. - * - * Return value: the id of the #ClutterTimeline inside the score, or - * 0 on failure. The returned id can be used with clutter_score_remove() - * or clutter_score_get_timeline(). - * - * Since: 0.8 - * Deprecated: 1.8 - */ -gulong -clutter_score_append_at_marker (ClutterScore *score, - ClutterTimeline *parent, - const gchar *marker_name, - ClutterTimeline *timeline) -{ - ClutterScorePrivate *priv; - GNode *node; - ClutterScoreEntry *entry; - gchar *marker_reached_signal; - - g_return_val_if_fail (CLUTTER_IS_SCORE (score), 0); - g_return_val_if_fail (CLUTTER_IS_TIMELINE (parent), 0); - g_return_val_if_fail (marker_name != NULL, 0); - g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), 0); - - if (!clutter_timeline_has_marker (parent, marker_name)) - { - g_warning ("The parent timeline has no marker '%s'", marker_name); - return 0; - } - - priv = score->priv; - - node = find_entry_by_timeline (score, parent); - if (G_UNLIKELY (!node)) - { - g_warning ("Unable to find the parent timeline inside the score."); - return 0; - } - - entry = g_slice_new (ClutterScoreEntry); - entry->timeline = g_object_ref (timeline); - entry->parent = parent; - entry->marker = g_strdup (marker_name); - entry->id = priv->last_id; - entry->score = score; - entry->complete_id = 0; - - marker_reached_signal = g_strdup_printf ("marker-reached::%s", marker_name); - entry->marker_id = g_signal_connect (entry->parent, - marker_reached_signal, - G_CALLBACK (on_timeline_marker), - entry); - - entry->node = g_node_append_data (node, entry); - - free (marker_reached_signal); - - priv->last_id += 1; - - return entry->id; -} - -/** - * clutter_score_remove: - * @score: a #ClutterScore - * @id_: the id of the timeline to remove - * - * Removes the #ClutterTimeline with the given id inside @score. If - * the timeline has other timelines attached to it, those are removed - * as well. - * - * Since: 0.6 - * Deprecated: 1.8 - */ -void -clutter_score_remove (ClutterScore *score, - gulong id_) -{ - ClutterScorePrivate *priv; - TraverseClosure closure; - - g_return_if_fail (CLUTTER_IS_SCORE (score)); - g_return_if_fail (id_ > 0); - - priv = score->priv; - - closure.action = REMOVE_BY_ID; - closure.score = score; - closure.d.id = id_; - closure.result = NULL; - - g_node_traverse (priv->root, - G_POST_ORDER, - G_TRAVERSE_ALL, - -1, - traverse_children, &closure); - - if (closure.result) - g_node_destroy (closure.result); -} - -/** - * clutter_score_remove_all: - * @score: a #ClutterScore - * - * Removes all the timelines inside @score. - * - * Since: 0.6 - * Deprecated: 1.8 - */ -void -clutter_score_remove_all (ClutterScore *score) -{ - ClutterScorePrivate *priv; - - g_return_if_fail (CLUTTER_IS_SCORE (score)); - - priv = score->priv; - - /* this will take care of the running timelines */ - clutter_score_stop (score); - - /* destroy all the contents of the tree */ - clutter_score_clear (score); - - /* recreate the sentinel */ - priv->root = g_node_new (NULL); -} - -/** - * clutter_score_get_timeline: - * @score: a #ClutterScore - * @id_: the id of the timeline - * - * Retrieves the #ClutterTimeline for @id_ inside @score. - * - * Return value: (transfer none): the requested timeline, or %NULL. This - * function does not increase the reference count on the returned - * #ClutterTimeline - * - * Since: 0.6 - * Deprecated: 1.8 - */ -ClutterTimeline * -clutter_score_get_timeline (ClutterScore *score, - gulong id_) -{ - GNode *node; - ClutterScoreEntry *entry; - - g_return_val_if_fail (CLUTTER_IS_SCORE (score), NULL); - g_return_val_if_fail (id_ > 0, NULL); - - node = find_entry_by_id (score, id_); - if (G_UNLIKELY (!node)) - return NULL; - - entry = node->data; - - return entry->timeline; -} - -/** - * clutter_score_list_timelines: - * @score: a #ClutterScore - * - * Retrieves a list of all the #ClutterTimelines managed by @score. - * - * Return value: (transfer container) (element-type Clutter.Timeline): a - * #GSList containing all the timelines in the score. This function does - * not increase the reference count of the returned timelines. Use - * g_slist_free() on the returned list to deallocate its resources. - * - * Since: 0.6 - * Deprecated: 1.8 - */ -GSList * -clutter_score_list_timelines (ClutterScore *score) -{ - ClutterScorePrivate *priv; - TraverseClosure closure; - GSList *retval; - - g_return_val_if_fail (CLUTTER_IS_SCORE (score), NULL); - - priv = score->priv; - - closure.action = LIST_TIMELINES; - closure.result = NULL; - - g_node_traverse (priv->root, - G_POST_ORDER, - G_TRAVERSE_ALL, - -1, - traverse_children, &closure); - - retval = closure.result; - - return retval; -} diff --git a/clutter/clutter/deprecated/clutter-score.h b/clutter/clutter/deprecated/clutter-score.h deleted file mode 100644 index 301dabd5f..000000000 --- a/clutter/clutter/deprecated/clutter-score.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * Copyright (C) 2006 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __CLUTTER_SCORE_H__ -#define __CLUTTER_SCORE_H__ - -#include - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_SCORE (clutter_score_get_type ()) - -#define CLUTTER_SCORE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_SCORE, ClutterScore)) -#define CLUTTER_SCORE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_SCORE, ClutterScoreClass)) -#define CLUTTER_IS_SCORE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_SCORE)) -#define CLUTTER_IS_SCORE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_SCORE)) -#define CLUTTER_SCORE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_SCORE, ClutterScoreClass)) - -typedef struct _ClutterScore ClutterScore; -typedef struct _ClutterScorePrivate ClutterScorePrivate; -typedef struct _ClutterScoreClass ClutterScoreClass; - -/** - * ClutterScore: - * - * The #ClutterScore structure contains only private data - * and should be accessed using the provided API - * - * Since: 0.6 - */ -struct _ClutterScore -{ - /*< private >*/ - GObject parent; - ClutterScorePrivate *priv; -}; - -/** - * ClutterScoreClass: - * @timeline_started: handler for the #ClutterScore::timeline-started signal - * @timeline_completed: handler for the #ClutterScore::timeline-completed - * signal - * @started: handler for the #ClutterScore::started signal - * @completed: handler for the #ClutterScore::completed signal - * @paused: handler for the #ClutterScore::paused signal - * - * The #ClutterScoreClass structure contains only private data - * - * Since: 0.6 - */ -struct _ClutterScoreClass -{ - /*< private >*/ - GObjectClass parent_class; - - /*< public >*/ - void (* timeline_started) (ClutterScore *score, - ClutterTimeline *timeline); - void (* timeline_completed) (ClutterScore *score, - ClutterTimeline *timeline); - - void (* started) (ClutterScore *score); - void (* completed) (ClutterScore *score); - void (* paused) (ClutterScore *score); - - /*< private >*/ - /* padding for future expansion */ - void (*_clutter_score_1) (void); - void (*_clutter_score_2) (void); - void (*_clutter_score_3) (void); - void (*_clutter_score_4) (void); - void (*_clutter_score_5) (void); -}; - -CLUTTER_DEPRECATED_IN_1_8 -GType clutter_score_get_type (void) G_GNUC_CONST; - -CLUTTER_DEPRECATED_IN_1_8 -ClutterScore * clutter_score_new (void); - -CLUTTER_DEPRECATED_IN_1_8 -void clutter_score_set_loop (ClutterScore *score, - gboolean loop); -CLUTTER_DEPRECATED_IN_1_8 -gboolean clutter_score_get_loop (ClutterScore *score); - -CLUTTER_DEPRECATED_IN_1_8 -gulong clutter_score_append (ClutterScore *score, - ClutterTimeline *parent, - ClutterTimeline *timeline); -CLUTTER_DEPRECATED_IN_1_8 -gulong clutter_score_append_at_marker (ClutterScore *score, - ClutterTimeline *parent, - const gchar *marker_name, - ClutterTimeline *timeline); -CLUTTER_DEPRECATED_IN_1_8 -void clutter_score_remove (ClutterScore *score, - gulong id_); -CLUTTER_DEPRECATED_IN_1_8 -void clutter_score_remove_all (ClutterScore *score); -CLUTTER_DEPRECATED_IN_1_8 -ClutterTimeline *clutter_score_get_timeline (ClutterScore *score, - gulong id_); -CLUTTER_DEPRECATED_IN_1_8 -GSList * clutter_score_list_timelines (ClutterScore *score); - -CLUTTER_DEPRECATED_IN_1_8 -void clutter_score_start (ClutterScore *score); -CLUTTER_DEPRECATED_IN_1_8 -void clutter_score_stop (ClutterScore *score); -CLUTTER_DEPRECATED_IN_1_8 -void clutter_score_pause (ClutterScore *score); -CLUTTER_DEPRECATED_IN_1_8 -void clutter_score_rewind (ClutterScore *score); -CLUTTER_DEPRECATED_IN_1_8 -gboolean clutter_score_is_playing (ClutterScore *score); - -G_END_DECLS - -#endif /* __CLUTTER_SCORE_H__ */ diff --git a/clutter/clutter/deprecated/clutter-shader.c b/clutter/clutter/deprecated/clutter-shader.c deleted file mode 100644 index 4e89b6e78..000000000 --- a/clutter/clutter/deprecated/clutter-shader.c +++ /dev/null @@ -1,933 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By: Matthew Allum - * Øyvind Kolås - * Emmanuele Bassi - * - * Copyright (C) 2007, 2008 OpenedHand - * Copyright (C) 2009 Intel Corp - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -/** - * SECTION:clutter-shader - * @short_description: Programmable pipeline abstraction - * - * #ClutterShader is an object providing an abstraction over the - * OpenGL programmable pipeline. By using #ClutterShaders is - * possible to override the drawing pipeline by using small programs - * also known as "shaders". - * - * #ClutterShader is available since Clutter 0.6. - * - * #ClutterShader is deprecated since Clutter 1.8; use #ClutterShaderEffect - * in newly written code, instead. - */ - -#ifdef HAVE_CONFIG_H -#include "clutter-build-config.h" -#endif - -#include -#include - -#ifdef HAVE_UNISTD_H -#include -#endif - -#define CLUTTER_DISABLE_DEPRECATION_WARNINGS - -#include - -#include - -#include "clutter-shader.h" - -#include "clutter-debug.h" -#include "clutter-private.h" - -/* global list of shaders */ -static GList *clutter_shaders_list = NULL; - -struct _ClutterShaderPrivate -{ - guint compiled : 1; /* Shader is bound to the GL context */ - guint is_enabled : 1; - guint vertex_is_glsl : 1; - guint fragment_is_glsl : 1; - - gchar *vertex_source; /* GLSL source for vertex shader */ - gchar *fragment_source; /* GLSL source for fragment shader */ - - CoglHandle program; - - CoglHandle vertex_shader; - CoglHandle fragment_shader; -}; - -enum -{ - PROP_0, - - PROP_VERTEX_SOURCE, - PROP_FRAGMENT_SOURCE, - PROP_COMPILED, - PROP_ENABLED, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST]; - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterShader, clutter_shader, G_TYPE_OBJECT) - -static inline void -clutter_shader_release_internal (ClutterShader *shader) -{ - ClutterShaderPrivate *priv = shader->priv; - - if (!priv->compiled) - return; - - g_assert (priv->program != COGL_INVALID_HANDLE); - - if (priv->vertex_is_glsl && priv->vertex_shader != COGL_INVALID_HANDLE) - cogl_handle_unref (priv->vertex_shader); - - if (priv->fragment_is_glsl && priv->fragment_shader != COGL_INVALID_HANDLE) - cogl_handle_unref (priv->fragment_shader); - - if (priv->program != COGL_INVALID_HANDLE) - cogl_handle_unref (priv->program); - - priv->vertex_shader = COGL_INVALID_HANDLE; - priv->fragment_shader = COGL_INVALID_HANDLE; - priv->program = COGL_INVALID_HANDLE; - priv->compiled = FALSE; -} - -static void -clutter_shader_finalize (GObject *object) -{ - ClutterShader *shader; - ClutterShaderPrivate *priv; - - shader = CLUTTER_SHADER (object); - priv = shader->priv; - - clutter_shaders_list = g_list_remove (clutter_shaders_list, object); - - free (priv->fragment_source); - free (priv->vertex_source); - - G_OBJECT_CLASS (clutter_shader_parent_class)->finalize (object); -} - -static void -clutter_shader_dispose (GObject *object) -{ - ClutterShader *shader = CLUTTER_SHADER (object); - - clutter_shader_release_internal (shader); - - G_OBJECT_CLASS (clutter_shader_parent_class)->finalize (object); -} - -static void -clutter_shader_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterShader *shader = CLUTTER_SHADER(object); - - switch (prop_id) - { - case PROP_VERTEX_SOURCE: - clutter_shader_set_vertex_source (shader, - g_value_get_string (value), -1); - break; - case PROP_FRAGMENT_SOURCE: - clutter_shader_set_fragment_source (shader, - g_value_get_string (value), -1); - break; - case PROP_ENABLED: - clutter_shader_set_is_enabled (shader, g_value_get_boolean (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -clutter_shader_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterShader *shader; - ClutterShaderPrivate *priv; - - shader = CLUTTER_SHADER(object); - priv = shader->priv; - - switch (prop_id) - { - case PROP_VERTEX_SOURCE: - g_value_set_string (value, priv->vertex_source); - break; - case PROP_FRAGMENT_SOURCE: - g_value_set_string (value, priv->fragment_source); - break; - case PROP_COMPILED: - g_value_set_boolean (value, priv->compiled); - break; - case PROP_ENABLED: - g_value_set_boolean (value, priv->is_enabled); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static GObject * -clutter_shader_constructor (GType type, - guint n_params, - GObjectConstructParam *params) -{ - GObjectClass *parent_class; - GObject *object; - - parent_class = G_OBJECT_CLASS (clutter_shader_parent_class); - object = parent_class->constructor (type, n_params, params); - - /* add this instance to the global list of shaders */ - clutter_shaders_list = g_list_prepend (clutter_shaders_list, object); - - return object; -} - -static void -clutter_shader_class_init (ClutterShaderClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - GParamSpec *pspec = NULL; - - object_class->finalize = clutter_shader_finalize; - object_class->dispose = clutter_shader_dispose; - object_class->set_property = clutter_shader_set_property; - object_class->get_property = clutter_shader_get_property; - object_class->constructor = clutter_shader_constructor; - - /** - * ClutterShader:vertex-source: - * - * GLSL source code for the vertex shader part of the shader - * program, if any - * - * Since: 0.6 - * - * Deprecated: 1.8: Use #ClutterShaderEffect instead. - */ - pspec = g_param_spec_string ("vertex-source", - P_("Vertex Source"), - P_("Source of vertex shader"), - NULL, - CLUTTER_PARAM_READWRITE); - obj_props[PROP_VERTEX_SOURCE] = pspec; - g_object_class_install_property (object_class, PROP_VERTEX_SOURCE, pspec); - - /** - * ClutterShader:fragment-source: - * - * GLSL source code for the fragment shader part of the shader program. - * - * Since: 0.6 - * - * Deprecated: 1.8: Use #ClutterShaderEffect instead. - */ - pspec = g_param_spec_string ("fragment-source", - P_("Fragment Source"), - P_("Source of fragment shader"), - NULL, - CLUTTER_PARAM_READWRITE); - obj_props[PROP_FRAGMENT_SOURCE] = pspec; - g_object_class_install_property (object_class, PROP_FRAGMENT_SOURCE, pspec); - - /** - * ClutterShader:compiled: - * - * Whether the shader is compiled and linked, ready for use - * in the GL context. - * - * Since: 0.8 - * - * Deprecated: 1.8: Use #ClutterShaderEffect instead. - */ - pspec = g_param_spec_boolean ("compiled", - P_("Compiled"), - P_("Whether the shader is compiled and linked"), - FALSE, - CLUTTER_PARAM_READABLE); - obj_props[PROP_COMPILED] = pspec; - g_object_class_install_property (object_class, PROP_COMPILED, pspec); - - /** - * ClutterShader:enabled: - * - * Whether the shader is currently used in the GL rendering pipeline. - * - * Since: 0.6 - * - * Deprecated: 1.8: Use #ClutterShaderEffect instead. - */ - pspec = g_param_spec_boolean ("enabled", - P_("Enabled"), - P_("Whether the shader is enabled"), - FALSE, - CLUTTER_PARAM_READWRITE); - obj_props[PROP_ENABLED] = pspec; - g_object_class_install_property (object_class, PROP_ENABLED, pspec); -} - -static void -clutter_shader_init (ClutterShader *self) -{ - ClutterShaderPrivate *priv; - - priv = self->priv = clutter_shader_get_instance_private (self); - - priv->compiled = FALSE; - - priv->vertex_source = NULL; - priv->fragment_source = NULL; - - priv->program = COGL_INVALID_HANDLE; - priv->vertex_shader = COGL_INVALID_HANDLE; - priv->fragment_shader = COGL_INVALID_HANDLE; -} - -/** - * clutter_shader_new: - * - * Create a new #ClutterShader instance. - * - * Return value: a new #ClutterShader. - * - * Since: 0.6 - * - * Deprecated: 1.8: Use #ClutterShaderEffect instead. - */ -ClutterShader * -clutter_shader_new (void) -{ - return g_object_new (CLUTTER_TYPE_SHADER, NULL); -} - -static inline void -clutter_shader_set_source (ClutterShader *shader, - ClutterShaderType shader_type, - const gchar *data, - gssize length) -{ - ClutterShaderPrivate *priv = shader->priv; - gboolean is_glsl = FALSE; - - if (length < 0) - length = strlen (data); - - g_object_freeze_notify (G_OBJECT (shader)); - - /* release shader if bound when changing the source, the shader will - * automatically be rebound on the next use. - */ - if (clutter_shader_is_compiled (shader)) - clutter_shader_release (shader); - - is_glsl = !g_str_has_prefix (data, "!!ARBfp"); - - CLUTTER_NOTE (SHADER, - "setting %s shader (GLSL:%s, len:%" G_GSSIZE_FORMAT ")", - shader_type == CLUTTER_VERTEX_SHADER ? "vertex" : "fragment", - is_glsl ? "yes" : "no", - length); - - switch (shader_type) - { - case CLUTTER_FRAGMENT_SHADER: - free (priv->fragment_source); - - priv->fragment_source = g_strndup (data, length); - priv->fragment_is_glsl = is_glsl; - g_object_notify_by_pspec (G_OBJECT (shader), obj_props[PROP_FRAGMENT_SOURCE]); - break; - - case CLUTTER_VERTEX_SHADER: - free (priv->vertex_source); - - priv->vertex_source = g_strndup (data, length); - priv->vertex_is_glsl = is_glsl; - g_object_notify_by_pspec (G_OBJECT (shader), obj_props[PROP_VERTEX_SOURCE]); - break; - } - - g_object_thaw_notify (G_OBJECT (shader)); -} - -/** - * clutter_shader_set_fragment_source: - * @shader: a #ClutterShader - * @data: GLSL source code. - * @length: length of source buffer (currently ignored) - * - * Sets the GLSL source code to be used by a #ClutterShader for the fragment - * program. - * - * Since: 0.6 - * - * Deprecated: 1.8: Use #ClutterShaderEffect instead. - */ -void -clutter_shader_set_fragment_source (ClutterShader *shader, - const gchar *data, - gssize length) -{ - g_return_if_fail (CLUTTER_IS_SHADER (shader)); - g_return_if_fail (data != NULL); - - clutter_shader_set_source (shader, CLUTTER_FRAGMENT_SHADER, data, length); -} - -/** - * clutter_shader_set_vertex_source: - * @shader: a #ClutterShader - * @data: GLSL source code. - * @length: length of source buffer (currently ignored) - * - * Sets the GLSL source code to be used by a #ClutterShader for the vertex - * program. - * - * Since: 0.6 - * - * Deprecated: 1.8: Use #ClutterShaderEffect instead. - */ -void -clutter_shader_set_vertex_source (ClutterShader *shader, - const gchar *data, - gssize length) -{ - g_return_if_fail (CLUTTER_IS_SHADER (shader)); - g_return_if_fail (data != NULL); - - clutter_shader_set_source (shader, CLUTTER_VERTEX_SHADER, data, length); -} - -static const gchar * -clutter_shader_get_source (ClutterShader *shader, - ClutterShaderType shader_type) -{ - switch (shader_type) - { - case CLUTTER_FRAGMENT_SHADER: - return shader->priv->fragment_source; - - case CLUTTER_VERTEX_SHADER: - return shader->priv->vertex_source; - } - - return NULL; -} - -static CoglHandle -clutter_shader_get_cogl_shader (ClutterShader *shader, - ClutterShaderType shader_type) -{ - switch (shader_type) - { - case CLUTTER_FRAGMENT_SHADER: - return shader->priv->fragment_shader; - - case CLUTTER_VERTEX_SHADER: - return shader->priv->vertex_shader; - } - - return COGL_INVALID_HANDLE; -} - -static gboolean -clutter_shader_glsl_bind (ClutterShader *self, - ClutterShaderType shader_type, - GError **error) -{ - ClutterShaderPrivate *priv = self->priv; - CoglHandle shader = COGL_INVALID_HANDLE; - - switch (shader_type) - { - case CLUTTER_VERTEX_SHADER: - shader = cogl_create_shader (COGL_SHADER_TYPE_VERTEX); - cogl_shader_source (shader, priv->vertex_source); - - priv->vertex_shader = shader; - break; - - case CLUTTER_FRAGMENT_SHADER: - shader = cogl_create_shader (COGL_SHADER_TYPE_FRAGMENT); - cogl_shader_source (shader, priv->fragment_source); - - priv->fragment_shader = shader; - break; - } - - g_assert (shader != COGL_INVALID_HANDLE); - - cogl_shader_compile (shader); - if (!cogl_shader_is_compiled (shader)) - { - gchar *log_buf; - - log_buf = cogl_shader_get_info_log (shader); - - /* translators: the first %s is the type of the shader, either - * Vertex shader or Fragment shader; the second %s is the actual - * error as reported by COGL - */ - g_set_error (error, CLUTTER_SHADER_ERROR, - CLUTTER_SHADER_ERROR_COMPILE, - _("%s compilation failed: %s"), - shader_type == CLUTTER_VERTEX_SHADER ? _("Vertex shader") - : _("Fragment shader"), - log_buf); - - free (log_buf); - - return FALSE; - } - - cogl_program_attach_shader (priv->program, shader); - - return TRUE; -} - -static gboolean -bind_glsl_shader (ClutterShader *self, - GError **error) -{ - ClutterShaderPrivate *priv = self->priv; - GError *bind_error = NULL; - gboolean res; - - priv->program = cogl_create_program (); - - if (priv->vertex_is_glsl && priv->vertex_source != COGL_INVALID_HANDLE) - { - res = clutter_shader_glsl_bind (self, - CLUTTER_VERTEX_SHADER, - &bind_error); - - if (!res) - { - g_propagate_error (error, bind_error); - return FALSE; - } - } - - if (priv->fragment_is_glsl && priv->fragment_source != COGL_INVALID_HANDLE) - { - res = clutter_shader_glsl_bind (self, - CLUTTER_FRAGMENT_SHADER, - &bind_error); - - if (!res) - { - g_propagate_error (error, bind_error); - return FALSE; - } - } - - cogl_program_link (priv->program); - - return TRUE; -} - -/** - * clutter_shader_compile: - * @shader: a #ClutterShader - * @error: return location for a #GError, or %NULL - * - * Compiles and links GLSL sources set for vertex and fragment shaders for - * a #ClutterShader. If the compilation fails and a #GError return location is - * provided the error will contain the errors from the compiler, if any. - * - * Return value: returns TRUE if the shader was succesfully compiled. - * - * Since: 0.8 - * - * Deprecated: 1.8: Use #ClutterShaderEffect instead. - */ -gboolean -clutter_shader_compile (ClutterShader *shader, - GError **error) -{ - ClutterShaderPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_SHADER (shader), FALSE); - - priv = shader->priv; - - if (priv->compiled) - return priv->compiled; - - if ((priv->vertex_source != COGL_INVALID_HANDLE && !priv->vertex_is_glsl) || - (priv->fragment_source != COGL_INVALID_HANDLE && !priv->fragment_is_glsl)) - { - /* XXX: Could remove this check, since we only advertise support for GLSL - * shaders anyways. */ - g_set_error (error, CLUTTER_SHADER_ERROR, - CLUTTER_SHADER_ERROR_NO_ASM, - "ASM shaders not supported"); - priv->compiled = FALSE; - return priv->compiled; - } - - if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL)) - { - g_set_error (error, CLUTTER_SHADER_ERROR, - CLUTTER_SHADER_ERROR_NO_GLSL, - "GLSL shaders not supported"); - priv->compiled = FALSE; - return priv->compiled; - } - - priv->compiled = bind_glsl_shader (shader, error); - g_object_notify_by_pspec (G_OBJECT (shader), obj_props[PROP_COMPILED]); - - return priv->compiled; -} - -/** - * clutter_shader_release: - * @shader: a #ClutterShader - * - * Frees up any GL context resources held by the shader. - * - * Since: 0.6 - * - * Deprecated: 1.8: Use #ClutterShaderEffect instead. - */ -void -clutter_shader_release (ClutterShader *shader) -{ - g_return_if_fail (CLUTTER_IS_SHADER (shader)); - - clutter_shader_release_internal (shader); - - g_object_notify_by_pspec (G_OBJECT (shader), obj_props[PROP_COMPILED]); -} - -/** - * clutter_shader_is_compiled: - * @shader: a #ClutterShader - * - * Checks whether @shader is is currently compiled, linked and bound - * to the GL context. - * - * Return value: %TRUE if the shader is compiled, linked and ready for use. - * - * Since: 0.8 - * - * Deprecated: 1.8: Use #ClutterShaderEffect instead. - */ -gboolean -clutter_shader_is_compiled (ClutterShader *shader) -{ - g_return_val_if_fail (CLUTTER_IS_SHADER (shader), FALSE); - - return shader->priv->compiled; -} - -/** - * clutter_shader_set_is_enabled: - * @shader: a #ClutterShader - * @enabled: The new state of the shader. - * - * Enables a shader. This function will attempt to compile and link - * the shader, if it isn't already. - * - * When @enabled is %FALSE the default state of the GL pipeline will be - * used instead. - * - * Since: 0.6 - * - * Deprecated: 1.8: Use #ClutterShaderEffect instead. - */ -void -clutter_shader_set_is_enabled (ClutterShader *shader, - gboolean enabled) -{ - ClutterShaderPrivate *priv; - - g_return_if_fail (CLUTTER_IS_SHADER (shader)); - - priv = shader->priv; - - if (priv->is_enabled != enabled) - { - GError *error = NULL; - gboolean res; - - res = clutter_shader_compile (shader, &error); - if (!res) - { - g_warning ("Unable to bind the shader: %s", - error ? error->message : "unknown error"); - if (error) - g_error_free (error); - - return; - } - - priv->is_enabled = enabled; - - if (priv->is_enabled) - cogl_program_use (priv->program); - else - cogl_program_use (COGL_INVALID_HANDLE); - - g_object_notify_by_pspec (G_OBJECT (shader), obj_props[PROP_ENABLED]); - } -} - -/** - * clutter_shader_get_is_enabled: - * @shader: a #ClutterShader - * - * Checks whether @shader is enabled. - * - * Return value: %TRUE if the shader is enabled. - * - * Since: 0.6 - * - * Deprecated: 1.8: Use #ClutterShaderEffect instead. - */ -gboolean -clutter_shader_get_is_enabled (ClutterShader *shader) -{ - g_return_val_if_fail (CLUTTER_IS_SHADER (shader), FALSE); - - return shader->priv->is_enabled; -} - -/** - * clutter_shader_set_uniform: - * @shader: a #ClutterShader. - * @name: name of uniform in GLSL shader program to set. - * @value: a #ClutterShaderFloat, #ClutterShaderInt or #ClutterShaderMatrix - * #GValue. - * - * Sets a user configurable variable in the GLSL shader programs attached to - * a #ClutterShader. - * - * Since: 1.0 - * - * Deprecated: 1.8: Use #ClutterShaderEffect instead. - */ -void -clutter_shader_set_uniform (ClutterShader *shader, - const gchar *name, - const GValue *value) -{ - ClutterShaderPrivate *priv; - int location = 0; - gsize size; - - g_return_if_fail (CLUTTER_IS_SHADER (shader)); - g_return_if_fail (name != NULL); - g_return_if_fail (value != NULL); - g_return_if_fail (CLUTTER_VALUE_HOLDS_SHADER_FLOAT (value) || - CLUTTER_VALUE_HOLDS_SHADER_INT (value) || - CLUTTER_VALUE_HOLDS_SHADER_MATRIX (value) || - G_VALUE_HOLDS_FLOAT (value) || - G_VALUE_HOLDS_INT (value)); - - priv = shader->priv; - g_return_if_fail (priv->program != COGL_INVALID_HANDLE); - - location = cogl_program_get_uniform_location (priv->program, name); - - if (CLUTTER_VALUE_HOLDS_SHADER_FLOAT (value)) - { - const float *floats; - - floats = clutter_value_get_shader_float (value, &size); - cogl_program_set_uniform_float (priv->program, - location, size, 1, floats); - } - else if (CLUTTER_VALUE_HOLDS_SHADER_INT (value)) - { - const int *ints; - - ints = clutter_value_get_shader_int (value, &size); - cogl_program_set_uniform_int (priv->program, - location, size, 1, ints); - } - else if (CLUTTER_VALUE_HOLDS_SHADER_MATRIX (value)) - { - const float *matrix; - - matrix = clutter_value_get_shader_matrix (value, &size); - cogl_program_set_uniform_matrix (priv->program, - location, size, 1, FALSE, matrix); - } - else if (G_VALUE_HOLDS_FLOAT (value)) - { - float float_val = g_value_get_float (value); - - cogl_program_set_uniform_float (priv->program, - location, 1, 1, &float_val); - } - else if (G_VALUE_HOLDS_INT (value)) - { - int int_val = g_value_get_int (value); - - cogl_program_set_uniform_int (priv->program, - location, 1, 1, &int_val); - } - else - g_assert_not_reached (); -} - -/** - * clutter_shader_get_fragment_source: - * @shader: a #ClutterShader - * - * Query the current GLSL fragment source set on @shader. - * - * Return value: the source of the fragment shader for this - * ClutterShader object or %NULL. The returned string is owned by the - * shader object and should never be modified or freed - * - * Since: 0.6 - * - * Deprecated: 1.8: Use #ClutterShaderEffect instead. - */ -const gchar * -clutter_shader_get_fragment_source (ClutterShader *shader) -{ - g_return_val_if_fail (CLUTTER_IS_SHADER (shader), NULL); - - return clutter_shader_get_source (shader, CLUTTER_FRAGMENT_SHADER); -} - -/** - * clutter_shader_get_vertex_source: - * @shader: a #ClutterShader - * - * Query the current GLSL vertex source set on @shader. - * - * Return value: the source of the vertex shader for this - * ClutterShader object or %NULL. The returned string is owned by the - * shader object and should never be modified or freed - * - * Since: 0.6 - * - * Deprecated: 1.8: Use #ClutterShaderEffect instead. - */ -const gchar * -clutter_shader_get_vertex_source (ClutterShader *shader) -{ - g_return_val_if_fail (CLUTTER_IS_SHADER (shader), NULL); - - return clutter_shader_get_source (shader, CLUTTER_VERTEX_SHADER); -} - -/** - * clutter_shader_get_cogl_program: - * @shader: a #ClutterShader - * - * Retrieves the underlying #CoglHandle for the shader program. - * - * Return value: (transfer none): A #CoglHandle for the shader program, - * or %NULL. The handle is owned by the #ClutterShader and it should - * not be unreferenced - * - * Since: 1.0 - * - * Deprecated: 1.8: Use #ClutterShaderEffect instead. - */ -CoglHandle -clutter_shader_get_cogl_program (ClutterShader *shader) -{ - g_return_val_if_fail (CLUTTER_IS_SHADER (shader), NULL); - - return shader->priv->program; -} - -/** - * clutter_shader_get_cogl_fragment_shader: - * @shader: a #ClutterShader - * - * Retrieves the underlying #CoglHandle for the fragment shader. - * - * Return value: (transfer none): A #CoglHandle for the fragment - * shader, or %NULL. The handle is owned by the #ClutterShader - * and it should not be unreferenced - * - * Since: 1.0 - * - * Deprecated: 1.8: Use #ClutterShaderEffect instead. - */ -CoglHandle -clutter_shader_get_cogl_fragment_shader (ClutterShader *shader) -{ - g_return_val_if_fail (CLUTTER_IS_SHADER (shader), NULL); - - return clutter_shader_get_cogl_shader (shader, CLUTTER_FRAGMENT_SHADER); -} - -/** - * clutter_shader_get_cogl_vertex_shader: - * @shader: a #ClutterShader - * - * Retrieves the underlying #CoglHandle for the vertex shader. - * - * Return value: (transfer none): A #CoglHandle for the vertex - * shader, or %NULL. The handle is owned by the #ClutterShader - * and it should not be unreferenced - * - * Since: 1.0 - * - * Deprecated: 1.8: Use #ClutterShaderEffect instead. - */ -CoglHandle -clutter_shader_get_cogl_vertex_shader (ClutterShader *shader) -{ - g_return_val_if_fail (CLUTTER_IS_SHADER (shader), NULL); - - return clutter_shader_get_cogl_shader (shader, CLUTTER_VERTEX_SHADER); -} - -GQuark -clutter_shader_error_quark (void) -{ - return g_quark_from_static_string ("clutter-shader-error"); -} diff --git a/clutter/clutter/deprecated/clutter-shader.h b/clutter/clutter/deprecated/clutter-shader.h deleted file mode 100644 index a04b8dd3c..000000000 --- a/clutter/clutter/deprecated/clutter-shader.h +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * Øyvind Kolås - * - * Copyright (C) 2007 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __CLUTTER_SHADER_H__ -#define __CLUTTER_SHADER_H__ - -#include -#include - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_SHADER (clutter_shader_get_type ()) -#define CLUTTER_SHADER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CLUTTER_TYPE_SHADER, ClutterShader)) -#define CLUTTER_SHADER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CLUTTER_TYPE_SHADER, ClutterShaderClass)) -#define CLUTTER_IS_SHADER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CLUTTER_TYPE_SHADER)) -#define CLUTTER_IS_SHADER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CLUTTER_TYPE_SHADER)) -#define CLUTTER_SHADER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CLUTTER_TYPE_SHADER, ClutterShaderClass)) - -/** - * CLUTTER_SHADER_ERROR: - * - * Error domain for #ClutterShader errors - * - * Since: 0.6 - * - * Deprecated: 1.8 - */ -#define CLUTTER_SHADER_ERROR (clutter_shader_error_quark ()) - -/** - * ClutterShaderError: - * @CLUTTER_SHADER_ERROR_NO_ASM: No ASM shaders support - * @CLUTTER_SHADER_ERROR_NO_GLSL: No GLSL shaders support - * @CLUTTER_SHADER_ERROR_COMPILE: Compilation error - * - * #ClutterShader error enumeration - * - * Since: 0.6 - * - * Deprecated: 1.8 - */ -typedef enum { - CLUTTER_SHADER_ERROR_NO_ASM, - CLUTTER_SHADER_ERROR_NO_GLSL, - CLUTTER_SHADER_ERROR_COMPILE -} ClutterShaderError; - -typedef struct _ClutterShaderPrivate ClutterShaderPrivate; -typedef struct _ClutterShaderClass ClutterShaderClass; - -/** - * ClutterShader: - * - * The #ClutterShader structure contains only private data - * and should be accessed using the provided API - * - * Since: 0.6 - * - * Deprecated: 1.8: Use #ClutterShaderEffect instead - */ -struct _ClutterShader -{ - /*< private >*/ - GObject parent; - ClutterShaderPrivate *priv; -}; - -/** - * ClutterShaderClass: - * - * The #ClutterShaderClass structure contains only private data - * - * Since: 0.6 - * - * Deprecated: 1.8: Use #ClutterShaderEffectClass instead - */ -struct _ClutterShaderClass -{ - /*< private >*/ - GObjectClass parent_class; -}; - -CLUTTER_DEPRECATED_IN_1_8 -GQuark clutter_shader_error_quark (void); - -CLUTTER_DEPRECATED_IN_1_8 -GType clutter_shader_get_type (void) G_GNUC_CONST; - -CLUTTER_DEPRECATED_IN_1_8_FOR(ClutterShaderEffect) -ClutterShader * clutter_shader_new (void); - -CLUTTER_DEPRECATED_IN_1_8_FOR(ClutterShaderEffect) -void clutter_shader_set_is_enabled (ClutterShader *shader, - gboolean enabled); -CLUTTER_DEPRECATED_IN_1_8_FOR(ClutterShaderEffect) -gboolean clutter_shader_get_is_enabled (ClutterShader *shader); - -CLUTTER_DEPRECATED_IN_1_8_FOR(ClutterShaderEffect) -gboolean clutter_shader_compile (ClutterShader *shader, - GError **error); -CLUTTER_DEPRECATED_IN_1_8_FOR(ClutterShaderEffect) -void clutter_shader_release (ClutterShader *shader); -CLUTTER_DEPRECATED_IN_1_8_FOR(ClutterShaderEffect) -gboolean clutter_shader_is_compiled (ClutterShader *shader); - -CLUTTER_DEPRECATED_IN_1_8_FOR(ClutterShaderEffect) -void clutter_shader_set_vertex_source (ClutterShader *shader, - const gchar *data, - gssize length); -CLUTTER_DEPRECATED_IN_1_8_FOR(ClutterShaderEffect) -void clutter_shader_set_fragment_source (ClutterShader *shader, - const gchar *data, - gssize length); -CLUTTER_DEPRECATED_IN_1_8_FOR(ClutterShaderEffect) -const gchar * clutter_shader_get_vertex_source (ClutterShader *shader); -CLUTTER_DEPRECATED_IN_1_8_FOR(ClutterShaderEffect) -const gchar * clutter_shader_get_fragment_source (ClutterShader *shader); - -CLUTTER_DEPRECATED_IN_1_8_FOR(ClutterShaderEffect) -void clutter_shader_set_uniform (ClutterShader *shader, - const gchar *name, - const GValue *value); - -CLUTTER_DEPRECATED_IN_1_8_FOR(ClutterShaderEffect) -CoglHandle clutter_shader_get_cogl_program (ClutterShader *shader); -CLUTTER_DEPRECATED_IN_1_8_FOR(ClutterShaderEffect) -CoglHandle clutter_shader_get_cogl_fragment_shader (ClutterShader *shader); -CLUTTER_DEPRECATED_IN_1_8_FOR(ClutterShaderEffect) -CoglHandle clutter_shader_get_cogl_vertex_shader (ClutterShader *shader); - -/* ClutterActor methods */ - -CLUTTER_DEPRECATED_IN_1_8_FOR(clutter_actor_add_effect) -gboolean clutter_actor_set_shader (ClutterActor *self, - ClutterShader *shader); - -CLUTTER_DEPRECATED_IN_1_8_FOR(clutter_actor_get_effect) -ClutterShader * clutter_actor_get_shader (ClutterActor *self); - -CLUTTER_DEPRECATED_IN_1_8_FOR(clutter_shader_effect_set_uniform_value) -void clutter_actor_set_shader_param (ClutterActor *self, - const gchar *param, - const GValue *value); - -CLUTTER_DEPRECATED_IN_1_8_FOR(clutter_shader_effect_set_uniform) -void clutter_actor_set_shader_param_int (ClutterActor *self, - const gchar *param, - gint value); - -CLUTTER_DEPRECATED_IN_1_8_FOR(clutter_shader_effect_set_uniform) -void clutter_actor_set_shader_param_float (ClutterActor *self, - const gchar *param, - gfloat value); - -G_END_DECLS - -#endif /* __CLUTTER_SHADER_H__ */ diff --git a/clutter/clutter/deprecated/clutter-stage.h b/clutter/clutter/deprecated/clutter-stage.h index fe36a4e57..20b103cf0 100644 --- a/clutter/clutter/deprecated/clutter-stage.h +++ b/clutter/clutter/deprecated/clutter-stage.h @@ -65,39 +65,25 @@ G_BEGIN_DECLS #endif /* CLUTTER_DISABLE_DEPRECATED */ -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_stage_new) +CLUTTER_DEPRECATED_FOR(clutter_stage_new) ClutterActor * clutter_stage_get_default (void); -CLUTTER_DEPRECATED_IN_1_10 +CLUTTER_DEPRECATED gboolean clutter_stage_is_default (ClutterStage *stage); -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_queue_redraw) +CLUTTER_DEPRECATED_FOR(clutter_actor_queue_redraw) void clutter_stage_queue_redraw (ClutterStage *stage); -CLUTTER_DEPRECATED_IN_1_10 -void clutter_stage_set_use_fog (ClutterStage *stage, - gboolean fog); -CLUTTER_DEPRECATED_IN_1_10 -gboolean clutter_stage_get_use_fog (ClutterStage *stage); - -CLUTTER_DEPRECATED_IN_1_10 -void clutter_stage_set_fog (ClutterStage *stage, - ClutterFog *fog); - -CLUTTER_DEPRECATED_IN_1_10 -void clutter_stage_get_fog (ClutterStage *stage, - ClutterFog *fog); - -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_set_background_color) +CLUTTER_DEPRECATED_FOR(clutter_actor_set_background_color) void clutter_stage_set_color (ClutterStage *stage, const ClutterColor *color); -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_actor_get_background_color) +CLUTTER_DEPRECATED_FOR(clutter_actor_get_background_color) void clutter_stage_get_color (ClutterStage *stage, ClutterColor *color); -CLUTTER_DEPRECATED_IN_MUFFIN +CLUTTER_DEPRECATED void clutter_stage_ensure_current (ClutterStage *stage); G_END_DECLS diff --git a/clutter/clutter/deprecated/clutter-state.c b/clutter/clutter/deprecated/clutter-state.c index a2eb7edc2..98b0cbf14 100644 --- a/clutter/clutter/deprecated/clutter-state.c +++ b/clutter/clutter/deprecated/clutter-state.c @@ -131,7 +131,6 @@ * "source" : "source-state", * "target" : "target-state", * "duration" : milliseconds, - * "animator" : "animator-definition" * }, * ... * ] @@ -142,7 +141,7 @@ * as clutter_state_set_key() function arguments. * * The source and target values control the source and target state of the - * transition. The key and animator properties are mutually exclusive. + * transition. * * The pre-delay and post-delay values are optional. * @@ -178,9 +177,7 @@ * ]| */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include #include @@ -191,7 +188,6 @@ #include "clutter-alpha.h" #include "clutter-animatable.h" -#include "clutter-animator.h" #include "clutter-enum-types.h" #include "clutter-interval.h" #include "clutter-marshal.h" @@ -199,20 +195,13 @@ #include "clutter-scriptable.h" #include "clutter-script-private.h" -typedef struct StateAnimator { - const gchar *source_state_name; /* interned string identifying entry */ - ClutterAnimator *animator; /* pointer to animator itself */ -} StateAnimator; - typedef struct State -{ +{ const gchar *name; /* interned string for this state name */ GHashTable *durations; /* durations for transitions from various state names */ GList *keys; /* list of all keys pertaining to transitions from other states to this one */ - GArray *animators; /* list of animators for transitioning from - * specific source states */ ClutterState *clutter_state; /* the ClutterState object this state belongs to */ } State; @@ -229,8 +218,6 @@ struct _ClutterStatePrivate State *source_state; /* current source_state */ const gchar *target_state_name; /* current target state */ State *target_state; /* target state name */ - ClutterAnimator *current_animator; /* !NULL if the current transition is - overriden by an animator */ }; #define SLAVE_TIMELINE_LENGTH 10000 @@ -242,7 +229,7 @@ struct _ClutterStatePrivate * */ typedef struct _ClutterStateKey -{ +{ GObject *object; /* an Gobject */ const gchar *property_name;/* the name of a property */ gulong mode; /* alpha to use */ @@ -498,9 +485,8 @@ state_free (gpointer data) state->keys = g_list_remove (state->keys, state->keys->data)) clutter_state_key_free (state->keys->data); - g_array_free (state->animators, TRUE); g_hash_table_destroy (state->durations); - free (state); + g_free (state); } static State * @@ -512,13 +498,12 @@ state_new (ClutterState *clutter_state, state = g_new0 (State, 1); state->clutter_state = clutter_state; state->name = name; - state->animators = g_array_new (TRUE, TRUE, sizeof (StateAnimator)); state->durations = g_hash_table_new (g_direct_hash, g_direct_equal); return state; } -static void +static void clutter_state_finalize (GObject *object) { ClutterStatePrivate *priv = CLUTTER_STATE (object)->priv; @@ -535,14 +520,6 @@ static void clutter_state_completed (ClutterTimeline *timeline, ClutterState *state) { - ClutterStatePrivate *priv = state->priv; - - if (priv->current_animator) - { - clutter_animator_set_timeline (priv->current_animator, NULL); - priv->current_animator = NULL; - } - g_signal_emit (state, state_signals[COMPLETED], 0); } @@ -558,9 +535,6 @@ clutter_state_new_frame (ClutterTimeline *timeline, GObject *curobj = NULL; gboolean found_specific = FALSE; - if (priv->current_animator) - return; - progress = clutter_timeline_get_progress (timeline); for (k = priv->target_state->keys; k; k = k->next) @@ -580,7 +554,7 @@ clutter_state_new_frame (ClutterTimeline *timeline, { if (key->source_state != NULL && key->source_state->name != NULL && - priv->source_state_name != NULL && + priv->source_state_name != NULL && g_str_equal (priv->source_state_name, key->source_state->name)) { found_specific = TRUE; @@ -651,7 +625,6 @@ clutter_state_change (ClutterState *state, gboolean animate) { ClutterStatePrivate *priv; - ClutterAnimator *animator; State *new_state; guint duration; GList *k; @@ -675,12 +648,6 @@ clutter_state_change (ClutterState *state, clutter_timeline_stop (priv->timeline); clutter_timeline_rewind (priv->timeline); - if (priv->current_animator) - { - clutter_animator_set_timeline (priv->current_animator, NULL); - priv->current_animator = NULL; - } - return NULL; } @@ -696,12 +663,6 @@ clutter_state_change (ClutterState *state, return priv->timeline; } - if (priv->current_animator != NULL) - { - clutter_animator_set_timeline (priv->current_animator, NULL); - priv->current_animator = NULL; - } - priv->source_state_name = priv->target_state_name; priv->target_state_name = target_state_name; @@ -720,55 +681,37 @@ clutter_state_change (ClutterState *state, return NULL; } - animator = clutter_state_get_animator (state, - priv->source_state_name, - priv->target_state_name); - priv->target_state = new_state; - - if (animator == NULL && new_state->keys == NULL) - animator = clutter_state_get_animator (state, NULL, - priv->target_state_name); - - if (animator != NULL) + for (k = new_state->keys; k != NULL; k = k->next) { - /* we've got an animator overriding the tweened animation */ - priv->current_animator = animator; - clutter_animator_set_timeline (animator, priv->timeline); - } - else - { - for (k = new_state->keys; k != NULL; k = k->next) - { - ClutterStateKey *key = k->data; - GValue initial = G_VALUE_INIT; + ClutterStateKey *key = k->data; + GValue initial = G_VALUE_INIT; - /* Reset the pre-pre-delay - this is only used for setting keys - * during transitions. - */ - key->pre_pre_delay = 0; + /* Reset the pre-pre-delay - this is only used for setting keys + * during transitions. + */ + key->pre_pre_delay = 0; - g_value_init (&initial, clutter_interval_get_value_type (key->interval)); + g_value_init (&initial, clutter_interval_get_value_type (key->interval)); - if (key->is_animatable) - { - ClutterAnimatable *animatable; + if (key->is_animatable) + { + ClutterAnimatable *animatable; - animatable = CLUTTER_ANIMATABLE (key->object); - clutter_animatable_get_initial_state (animatable, - key->property_name, - &initial); - } - else - g_object_get_property (key->object, key->property_name, &initial); + animatable = CLUTTER_ANIMATABLE (key->object); + clutter_animatable_get_initial_state (animatable, + key->property_name, + &initial); + } + else + g_object_get_property (key->object, key->property_name, &initial); - if (clutter_alpha_get_mode (key->alpha) != key->mode) - clutter_alpha_set_mode (key->alpha, key->mode); + if (clutter_alpha_get_mode (key->alpha) != key->mode) + clutter_alpha_set_mode (key->alpha, key->mode); - clutter_interval_set_initial_value (key->interval, &initial); - clutter_interval_set_final_value (key->interval, &key->value); + clutter_interval_set_initial_value (key->interval, &initial); + clutter_interval_set_final_value (key->interval, &key->value); - g_value_unset (&initial); - } + g_value_unset (&initial); } if (!animate) @@ -1018,7 +961,7 @@ clutter_state_set (ClutterState *state, if (error != NULL) { g_warning ("%s: %s", G_STRLOC, error); - free (error); + g_free (error); break; } @@ -1274,143 +1217,6 @@ clutter_state_get_states (ClutterState *state) return g_hash_table_get_keys (state->priv->states); } -/** - * clutter_state_get_keys: - * @state: a #ClutterState instance. - * @source_state_name: (allow-none): the source transition name to query, - * or %NULL for all source states - * @target_state_name: (allow-none): the target transition name to query, - * or %NULL for all target states - * @object: (allow-none): the specific object instance to list keys for, - * or %NULL for all managed objects - * @property_name: (allow-none): the property name to search for, or %NULL - * for all properties. - * - * Returns a list of pointers to opaque structures with accessor functions - * that describe the keys added to an animator. - * - * Return value: (transfer container) (element-type Clutter.StateKey): a - * newly allocated #GList of #ClutterStateKeys. The contents of - * the returned list are owned by the #ClutterState and should not be - * modified or freed. Use g_list_free() to free the resources allocated - * by the returned list when done using it - * - * Since: 1.4 - * Deprecated: 1.12: Use #ClutterKeyframeTransition and - * #ClutterTransitionGroup instead - */ -GList * -clutter_state_get_keys (ClutterState *state, - const gchar *source_state_name, - const gchar *target_state_name, - GObject *object, - const gchar *property_name) -{ - GList *s, *state_list; - GList *targets = NULL; - State *source_state = NULL; - - g_return_val_if_fail (CLUTTER_IS_STATE (state), NULL); - - source_state_name = g_intern_string (source_state_name); - target_state_name = g_intern_string (target_state_name); - property_name = g_intern_string (property_name); - - if (target_state_name != NULL) - state_list = g_list_append (NULL, (gpointer) target_state_name); - else - state_list = clutter_state_get_states (state); - - if (source_state_name) - source_state = clutter_state_fetch_state (state, source_state_name, FALSE); - - for (s = state_list; s != NULL; s = s->next) - { - State *target_state; - - target_state = clutter_state_fetch_state (state, s->data, FALSE); - if (target_state != NULL) - { - GList *k; - - for (k = target_state->keys; k; k = k->next) - { - ClutterStateKey *key = k->data; - - if ((object == NULL || (object == key->object)) && - (source_state_name == NULL || - source_state == key->source_state) && - (property_name == NULL || - (property_name == key->property_name))) - { - targets = g_list_prepend (targets, key); - } - } - } - } - - g_list_free (state_list); - - return g_list_reverse (targets); -} - - -/** - * clutter_state_remove_key: - * @state: a #ClutterState instance. - * @source_state_name: (allow-none): the source state name to query, - * or %NULL for all source states - * @target_state_name: (allow-none): the target state name to query, - * or %NULL for all target states - * @object: (allow-none): the specific object instance to list keys for, - * or %NULL for all managed objects - * @property_name: (allow-none): the property name to search for, - * or %NULL for all properties. - * - * Removes all keys matching the search criteria passed in arguments. - * - * Since: 1.4 - * Deprecated: 1.12: Use #ClutterKeyframeTransition and - * #ClutterTransitionGroup instead - */ -void -clutter_state_remove_key (ClutterState *state, - const gchar *source_state_name, - const gchar *target_state_name, - GObject *object, - const gchar *property_name) -{ - g_return_if_fail (CLUTTER_IS_STATE (state)); - - clutter_state_remove_key_internal (state, - source_state_name, target_state_name, - object, property_name, - FALSE); -} - -/** - * clutter_state_get_timeline: - * @state: a #ClutterState - * - * Gets the timeline driving the #ClutterState - * - * Return value: (transfer none): the #ClutterTimeline that drives - * the state change animations. The returned timeline is owned - * by the #ClutterState and it should not be unreferenced directly - * - * Since: 1.4 - * Deprecated: 1.12: Use #ClutterKeyframeTransition and - * #ClutterTransitionGroup instead - */ -ClutterTimeline * -clutter_state_get_timeline (ClutterState *state) -{ - g_return_val_if_fail (CLUTTER_IS_STATE (state), NULL); - - return state->priv->timeline; -} - - static void clutter_state_set_property (GObject *object, guint prop_id, @@ -1480,8 +1286,7 @@ clutter_state_class_init (ClutterStateClass *klass) G_TYPE_FROM_CLASS (gobject_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ClutterStateClass, completed), - NULL, NULL, - _clutter_marshal_VOID__VOID, + NULL, NULL, NULL, G_TYPE_NONE, 0); /** @@ -1551,126 +1356,6 @@ clutter_state_init (ClutterState *self) } -/** - * clutter_state_get_animator: - * @state: a #ClutterState instance. - * @source_state_name: the name of a source state - * @target_state_name: the name of a target state - * - * Retrieves the #ClutterAnimator that is being used for transitioning - * between the two states, if any has been set - * - * Return value: (transfer none): a #ClutterAnimator instance, or %NULL - * - * Since: 1.4 - * Deprecated: 1.12: Use #ClutterKeyframeTransition and - * #ClutterTransitionGroup instead - */ -ClutterAnimator * -clutter_state_get_animator (ClutterState *state, - const gchar *source_state_name, - const gchar *target_state_name) -{ - State *target_state; - guint i; - - g_return_val_if_fail (CLUTTER_IS_STATE (state), NULL); - - source_state_name = g_intern_string (source_state_name); - if (source_state_name == g_intern_static_string ("")) - source_state_name = NULL; - - target_state_name = g_intern_string (target_state_name); - - target_state = clutter_state_fetch_state (state, target_state_name, FALSE); - if (target_state == NULL) - return NULL; - - for (i = 0; i < target_state->animators->len; i++) - { - const StateAnimator *animator; - - animator = &g_array_index (target_state->animators, StateAnimator, i); - if (animator->source_state_name == source_state_name) - return animator->animator; - } - - return NULL; -} - -/** - * clutter_state_set_animator: - * @state: a #ClutterState instance. - * @source_state_name: the name of a source state - * @target_state_name: the name of a target state - * @animator: (allow-none): a #ClutterAnimator instance, or %NULL to - * unset an existing #ClutterAnimator - * - * Specifies a #ClutterAnimator to be used when transitioning between - * the two named states. - * - * The @animator allows specifying a transition between the state that is - * more elaborate than the basic transitions allowed by the tweening of - * properties defined in the #ClutterState keys. - * - * If @animator is %NULL it will unset an existing animator. - * - * #ClutterState will take a reference on the passed @animator, if any - * - * Since: 1.4 - * Deprecated: 1.12: Use #ClutterKeyframeTransition and - * #ClutterTransitionGroup instead - */ -void -clutter_state_set_animator (ClutterState *state, - const gchar *source_state_name, - const gchar *target_state_name, - ClutterAnimator *animator) -{ - State *target_state; - guint i; - - g_return_if_fail (CLUTTER_IS_STATE (state)); - - source_state_name = g_intern_string (source_state_name); - target_state_name = g_intern_string (target_state_name); - - target_state = clutter_state_fetch_state (state, target_state_name, TRUE); - if (target_state == NULL) - return; - - for (i = 0; target_state->animators->len; i++) - { - StateAnimator *a; - - a = &g_array_index (target_state->animators, StateAnimator, i); - if (a->source_state_name == source_state_name) - { - g_object_unref (a->animator); - - if (animator != NULL) - a->animator = g_object_ref (animator); - else - { - /* remove the matched animator if passed NULL */ - g_array_remove_index (target_state->animators, i); - } - - return; - } - } - - if (animator != NULL) - { - StateAnimator state_animator = { - source_state_name, - g_object_ref (animator) - }; - - g_array_append_val (target_state->animators, state_animator); - } -} - static gpointer clutter_state_key_copy (gpointer boxed) { @@ -1688,227 +1373,12 @@ G_DEFINE_BOXED_TYPE (ClutterStateKey, clutter_state_key, clutter_state_key_copy, clutter_state_key_free); -/** - * clutter_state_key_get_pre_delay: - * @state_key: a #ClutterStateKey - * - * Retrieves the pause before transitioning starts as a fraction of - * the total transition time. - * - * Return value: the pre delay used before starting the transition. - * - * Since: 1.4 - * Deprecated: 1.12: Use #ClutterKeyframeTransition and - * #ClutterTransitionGroup instead - */ -gdouble -clutter_state_key_get_pre_delay (const ClutterStateKey *state_key) -{ - g_return_val_if_fail (state_key != NULL, 0.0); - - return state_key->pre_delay; -} - -/** - * clutter_state_key_get_post_delay: - * @state_key: a #ClutterStateKey - * - * Retrieves the duration of the pause after transitioning is complete - * as a fraction of the total transition time. - * - * Return value: the post delay, used after doing the transition. - * - * Since: 1.4 - * Deprecated: 1.12: Use #ClutterKeyframeTransition and - * #ClutterTransitionGroup instead - */ -gdouble -clutter_state_key_get_post_delay (const ClutterStateKey *state_key) -{ - g_return_val_if_fail (state_key != NULL, 0.0); - - return state_key->post_delay; -} - -/** - * clutter_state_key_get_mode: - * @state_key: a #ClutterStateKey - * - * Retrieves the easing mode used for @state_key. - * - * Return value: the mode of a #ClutterStateKey - * - * Since: 1.4 - * Deprecated: 1.12: Use #ClutterKeyframeTransition and - * #ClutterTransitionGroup instead - */ -gulong -clutter_state_key_get_mode (const ClutterStateKey *state_key) -{ - g_return_val_if_fail (state_key != NULL, 0); - - return state_key->mode; -} - -/** - * clutter_state_key_get_value: - * @state_key: a #ClutterStateKey - * @value: a #GValue initialized with the correct type for the @state_key - * - * Retrieves a copy of the value for a #ClutterStateKey. - * - * The #GValue needs to be already initialized for the value type - * of the property or to a type that allow transformation from the value - * type of the key. - * - * Use g_value_unset() when done. - * - * Return value: %TRUE if the value was successfully retrieved, - * and %FALSE otherwise - * - * Since: 1.4 - * Deprecated: 1.12: Use #ClutterKeyframeTransition and - * #ClutterTransitionGroup instead - */ -gboolean -clutter_state_key_get_value (const ClutterStateKey *state_key, - GValue *value) -{ - g_return_val_if_fail (state_key != NULL, FALSE); - g_return_val_if_fail (value != NULL, FALSE); - g_return_val_if_fail (G_VALUE_TYPE (value) != G_TYPE_INVALID, FALSE); - - if (!g_type_is_a (G_VALUE_TYPE (&state_key->value), G_VALUE_TYPE (value))) - { - if (g_value_type_compatible (G_VALUE_TYPE (&state_key->value), - G_VALUE_TYPE (value))) - { - g_value_copy (&state_key->value, value); - return TRUE; - } - - if (g_value_type_transformable (G_VALUE_TYPE (&state_key->value), - G_VALUE_TYPE (value))) - { - if (g_value_transform (&state_key->value, value)) - return TRUE; - } - - g_warning ("%s: Unable to convert from %s to %s for the " - "property '%s' of object %s in the state key", - G_STRLOC, - g_type_name (G_VALUE_TYPE (&state_key->value)), - g_type_name (G_VALUE_TYPE (value)), - state_key->property_name, - G_OBJECT_TYPE_NAME (state_key->object)); - - return FALSE; - } - else - g_value_copy (&state_key->value, value); - - return TRUE; -} - -/** - * clutter_state_key_get_object: - * @state_key: a #ClutterStateKey - * - * Retrieves the object instance this #ClutterStateKey applies to. - * - * Return value: (transfer none): the object this state key applies to. - * - * Since: 1.4 - * Deprecated: 1.12: Use #ClutterKeyframeTransition and - * #ClutterTransitionGroup instead - */ -GObject * -clutter_state_key_get_object (const ClutterStateKey *state_key) -{ - g_return_val_if_fail (state_key, NULL); - - return state_key->object; -} - -/** - * clutter_state_key_get_property_name: - * @state_key: a #ClutterStateKey - * - * Retrieves the name of the property this #ClutterStateKey applies to - * - * Return value: the name of the property. The returned string is owned - * by the #ClutterStateKey and should never be modified or freed - * - * Since: 1.4 - * Deprecated: 1.12: Use #ClutterKeyframeTransition and - * #ClutterTransitionGroup instead - */ -const gchar * -clutter_state_key_get_property_name (const ClutterStateKey *state_key) -{ - g_return_val_if_fail (state_key, NULL); - - return state_key->property_name; -} - -/** - * clutter_state_key_get_source_state_name: - * @state_key: a #ClutterStateKey - * - * Retrieves the name of the source state of the @state_key - * - * Return value: the name of the source state for this key, or %NULL - * if this is the generic state key for the given property when - * transitioning to the target state. The returned string is owned - * by the #ClutterStateKey and should never be modified or freed - * - * Since: 1.4 - * Deprecated: 1.12: Use #ClutterKeyframeTransition and - * #ClutterTransitionGroup instead - */ -const gchar * -clutter_state_key_get_source_state_name (const ClutterStateKey *state_key) -{ - g_return_val_if_fail (state_key, NULL); - - if (state_key->source_state != NULL) - return state_key->source_state->name; - - return NULL; -} - -/** - * clutter_state_key_get_target_state_name: - * @state_key: a #ClutterStateKey - * - * Get the name of the source state this #ClutterStateKey contains, - * or NULL if this is the generic state key for the given property - * when transitioning to the target state. - * - * Return value: the name of the source state for this key, or NULL if - * the key is generic - * - * Since: 1.4 - * Deprecated: 1.12: Use #ClutterKeyframeTransition and - * #ClutterTransitionGroup instead - */ -const gchar * -clutter_state_key_get_target_state_name (const ClutterStateKey *state_key) -{ - g_return_val_if_fail (state_key, NULL); - - return state_key->target_state->name; -} - /** * clutter_state_key_get_property_type: * @key: a #ClutterStateKey * * Retrieves the #GType of the property a key applies to * - * You can use this type to initialize the #GValue to pass to - * clutter_state_key_get_value() - * * Return value: the #GType of the property * * Since: 1.4 @@ -1996,7 +1466,7 @@ clutter_state_set_duration (ClutterState *state, * * The semantics for the query are the same as the semantics used for * setting the duration with clutter_state_set_duration() - * + * * Return value: the duration, in milliseconds * * Since: 1.4 @@ -2056,7 +1526,7 @@ clutter_state_get_duration (ClutterState *state, * * This function is useful when called from handlers of the * #ClutterState::completed signal. - * + * * Return value: a string containing the target state. The returned string * is owned by the #ClutterState and should not be modified or freed * @@ -2109,12 +1579,10 @@ parse_state_transition (JsonArray *array, if (!json_object_has_member (object, "source") || !json_object_has_member (object, "target") || - !(json_object_has_member (object, "keys") || - json_object_has_member (object, "animator"))) + !(json_object_has_member (object, "keys"))) { g_warning ("The transition description at index %d is missing one " - "of the mandatory members: source, target and keys or " - "animator", index_); + "of the mandatory members: source, target and keys", index_); return; } @@ -2133,29 +1601,11 @@ parse_state_transition (JsonArray *array, duration); } - if (json_object_has_member (object, "animator")) - { - const gchar *id_ = json_object_get_string_member (object, "animator"); - GObject *animator; - - animator = clutter_script_get_object (clos->script, id_); - if (animator == NULL) - { - g_warning ("No object with id '%s' has been defined.", id_); - return; - } - - clutter_state_set_animator (clos->state, - source_name, - target_name, - CLUTTER_ANIMATOR (animator)); - } - if (!json_object_has_member (object, "keys")) return; keys = json_object_get_array_member (object, "keys"); - if (keys == NULL && !json_object_has_member (object, "animator")) + if (keys == NULL) { g_warning ("The transition description at index %d has an invalid " "key member of type '%s' when an array was expected.", diff --git a/clutter/clutter/deprecated/clutter-state.h b/clutter/clutter/deprecated/clutter-state.h index e33ae0fec..d452a9d96 100644 --- a/clutter/clutter/deprecated/clutter-state.h +++ b/clutter/clutter/deprecated/clutter-state.h @@ -88,20 +88,20 @@ struct _ClutterStateClass gpointer _padding_dummy[8]; }; -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED GType clutter_state_get_type (void) G_GNUC_CONST; -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED ClutterState *clutter_state_new (void); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED ClutterTimeline * clutter_state_set_state (ClutterState *state, const gchar *target_state_name); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED ClutterTimeline * clutter_state_warp_to_state (ClutterState *state, const gchar *target_state_name); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED ClutterState * clutter_state_set_key (ClutterState *state, const gchar *source_state_name, const gchar *target_state_name, @@ -111,16 +111,16 @@ ClutterState * clutter_state_set_key (ClutterState *state, const GValue *value, gdouble pre_delay, gdouble post_delay); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED void clutter_state_set_duration (ClutterState *state, const gchar *source_state_name, const gchar *target_state_name, guint duration); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED guint clutter_state_get_duration (ClutterState *state, const gchar *source_state_name, const gchar *target_state_name); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED void clutter_state_set (ClutterState *state, const gchar *source_state_name, const gchar *target_state_name, @@ -128,59 +128,19 @@ void clutter_state_set (ClutterState *state, const gchar *first_property_name, gulong first_mode, ...) G_GNUC_NULL_TERMINATED; -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED GList * clutter_state_get_states (ClutterState *state); -CLUTTER_DEPRECATED_IN_1_12 -GList * clutter_state_get_keys (ClutterState *state, - const gchar *source_state_name, - const gchar *target_state_name, - GObject *object, - const gchar *property_name); -CLUTTER_DEPRECATED_IN_1_12 -void clutter_state_remove_key (ClutterState *state, - const gchar *source_state_name, - const gchar *target_state_name, - GObject *object, - const gchar *property_name); -CLUTTER_DEPRECATED_IN_1_12 -ClutterTimeline * clutter_state_get_timeline (ClutterState *state); -CLUTTER_DEPRECATED_IN_1_12 -void clutter_state_set_animator (ClutterState *state, - const gchar *source_state_name, - const gchar *target_state_name, - ClutterAnimator *animator); -CLUTTER_DEPRECATED_IN_1_12 -ClutterAnimator * clutter_state_get_animator (ClutterState *state, - const gchar *source_state_name, - const gchar *target_state_name); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED const gchar * clutter_state_get_state (ClutterState *state); /* * ClutterStateKey */ -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED GType clutter_state_key_get_type (void) G_GNUC_CONST; -CLUTTER_DEPRECATED_IN_1_12 -gdouble clutter_state_key_get_pre_delay (const ClutterStateKey *state_key); -CLUTTER_DEPRECATED_IN_1_12 -gdouble clutter_state_key_get_post_delay (const ClutterStateKey *state_key); -CLUTTER_DEPRECATED_IN_1_12 -gulong clutter_state_key_get_mode (const ClutterStateKey *state_key); -CLUTTER_DEPRECATED_IN_1_12 -gboolean clutter_state_key_get_value (const ClutterStateKey *state_key, - GValue *value); -CLUTTER_DEPRECATED_IN_1_12 +CLUTTER_DEPRECATED GType clutter_state_key_get_property_type (const ClutterStateKey *key); -CLUTTER_DEPRECATED_IN_1_12 -GObject * clutter_state_key_get_object (const ClutterStateKey *state_key); -CLUTTER_DEPRECATED_IN_1_12 -const gchar * clutter_state_key_get_property_name (const ClutterStateKey *state_key); -CLUTTER_DEPRECATED_IN_1_12 -const gchar * clutter_state_key_get_source_state_name (const ClutterStateKey *state_key); -CLUTTER_DEPRECATED_IN_1_12 -const gchar * clutter_state_key_get_target_state_name (const ClutterStateKey *state_key); G_END_DECLS diff --git a/clutter/clutter/deprecated/clutter-table-layout.c b/clutter/clutter/deprecated/clutter-table-layout.c deleted file mode 100644 index f8b1b875d..000000000 --- a/clutter/clutter/deprecated/clutter-table-layout.c +++ /dev/null @@ -1,2611 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Jose Dapena Paz - * - * Based on the MX MxTable actor by: - * Thomas Wood - * and ClutterBoxLayout by: - * Emmanuele Bassi - */ - -/** - * SECTION:clutter-table-layout - * @title: ClutterTableLayout - * @short_description: A layout manager arranging children in rows - * and columns - * - * The #ClutterTableLayout is a #ClutterLayoutManager implementing the - * following layout policy: - * - * - children are arranged in a table - * - each child specifies the specific row and column - * cell to appear; - * - a child can also set a span, and this way, take - * more than one cell both horizontally and vertically; - * - each child will be allocated to its natural - * size or, if set to expand, the available size; - * - if a child is set to fill on either (or both) - * axis, its allocation will match all the available size; the - * fill layout property only makes sense if the expand property is - * also set; - * - if a child is set to expand but not to fill then - * it is possible to control the alignment using the horizontal and - * vertical alignment layout properties. - * - * It is possible to control the spacing between children of a - * #ClutterTableLayout by using clutter_table_layout_set_row_spacing() - * and clutter_table_layout_set_column_spacing(). - * - * In order to set the layout properties when packing an actor inside a - * #ClutterTableLayout you should use the clutter_table_layout_pack() - * function. - * - * A #ClutterTableLayout can use animations to transition between different - * values of the layout management properties; the easing mode and duration - * used for the animations are controlled by the - * #ClutterTableLayout:easing-mode and #ClutterTableLayout:easing-duration - * properties and their accessor functions. - * - * #ClutterTableLayout is available since Clutter 1.4 - * - * Since Clutter 1.18 it's recommended to use #ClutterGridLayout instead - * of #ClutterTableLayout; the former supports right-to-left text direction, - * as well as using the alignment and expansion flags on #ClutterActor. - */ - -#ifdef HAVE_CONFIG_H -#include "clutter-build-config.h" -#endif - -#include - -#define CLUTTER_DISABLE_DEPRECATION_WARNINGS -#include "deprecated/clutter-container.h" -#include "deprecated/clutter-alpha.h" - -#include "clutter-table-layout.h" - -#include "clutter-debug.h" -#include "clutter-enum-types.h" -#include "clutter-layout-meta.h" -#include "clutter-private.h" -#include "clutter-types.h" - -#define CLUTTER_TYPE_TABLE_CHILD (clutter_table_child_get_type ()) -#define CLUTTER_TABLE_CHILD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_TABLE_CHILD, ClutterTableChild)) -#define CLUTTER_IS_TABLE_CHILD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_TABLE_CHILD)) - -typedef struct _ClutterTableChild ClutterTableChild; -typedef struct _ClutterLayoutMetaClass ClutterTableChildClass; - -typedef struct _DimensionData { - gfloat min_size; - gfloat pref_size; - gfloat final_size; - - guint expand : 1; - guint visible : 1; -} DimensionData; - -struct _ClutterTableLayoutPrivate -{ - ClutterContainer *container; - - guint col_spacing; - guint row_spacing; - - gint n_rows; - gint n_cols; - gint active_row; - gint active_col; - gint visible_rows; - gint visible_cols; - - GArray *columns; - GArray *rows; - - gulong easing_mode; - guint easing_duration; - - guint is_animating : 1; - guint use_animations : 1; -}; - -struct _ClutterTableChild -{ - ClutterLayoutMeta parent_instance; - - gint col; - gint row; - - gint col_span; - gint row_span; - - ClutterTableAlignment x_align; - ClutterTableAlignment y_align; - - guint x_expand : 1; - guint y_expand : 1; - guint x_fill : 1; - guint y_fill : 1; -}; - -enum -{ - PROP_CHILD_0, - - PROP_CHILD_ROW, - PROP_CHILD_COLUMN, - PROP_CHILD_ROW_SPAN, - PROP_CHILD_COLUMN_SPAN, - PROP_CHILD_X_ALIGN, - PROP_CHILD_Y_ALIGN, - PROP_CHILD_X_FILL, - PROP_CHILD_Y_FILL, - PROP_CHILD_X_EXPAND, - PROP_CHILD_Y_EXPAND -}; - -enum -{ - PROP_0, - - PROP_ROW_SPACING, - PROP_COLUMN_SPACING, - PROP_USE_ANIMATIONS, - PROP_EASING_MODE, - PROP_EASING_DURATION -}; - -GType clutter_table_child_get_type (void); - -G_DEFINE_TYPE (ClutterTableChild, clutter_table_child, CLUTTER_TYPE_LAYOUT_META) - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterTableLayout, clutter_table_layout, CLUTTER_TYPE_LAYOUT_MANAGER) - -/* - * ClutterBoxChild - */ - -static void -table_child_set_position (ClutterTableChild *self, - gint col, - gint row) -{ - gboolean row_changed = FALSE, col_changed = FALSE; - - if (self->col != col) - { - self->col = col; - - col_changed = TRUE; - } - - if (self->row != row) - { - self->row = row; - - row_changed = TRUE; - } - - if (row_changed || col_changed) - { - ClutterLayoutManager *layout; - - layout = clutter_layout_meta_get_manager (CLUTTER_LAYOUT_META (self)); - clutter_layout_manager_layout_changed (layout); - - g_object_freeze_notify (G_OBJECT (self)); - - if (row_changed) - g_object_notify (G_OBJECT (self), "row"); - - if (col_changed) - g_object_notify (G_OBJECT (self), "column"); - - g_object_thaw_notify (G_OBJECT (self)); - } -} - -static void -table_child_set_span (ClutterTableChild *self, - gint col_span, - gint row_span) -{ - gboolean row_changed = FALSE, col_changed = FALSE; - - if (self->col_span != col_span) - { - self->col_span = col_span; - - col_changed = TRUE; - } - - if (self->row_span != row_span) - { - self->row_span = row_span; - - row_changed = TRUE; - } - - if (row_changed || col_changed) - { - ClutterLayoutManager *layout; - - layout = clutter_layout_meta_get_manager (CLUTTER_LAYOUT_META (self)); - clutter_layout_manager_layout_changed (layout); - - if (row_changed) - g_object_notify (G_OBJECT (self), "row-span"); - - if (col_changed) - g_object_notify (G_OBJECT (self), "column-span"); - } -} - -static void -table_child_set_align (ClutterTableChild *self, - ClutterTableAlignment x_align, - ClutterTableAlignment y_align) -{ - gboolean x_changed = FALSE, y_changed = FALSE; - - if (self->x_align != x_align) - { - self->x_align = x_align; - - x_changed = TRUE; - } - - if (self->y_align != y_align) - { - self->y_align = y_align; - - y_changed = TRUE; - } - - if (x_changed || y_changed) - { - ClutterLayoutManager *layout; - - layout = clutter_layout_meta_get_manager (CLUTTER_LAYOUT_META (self)); - clutter_layout_manager_layout_changed (layout); - - g_object_freeze_notify (G_OBJECT (self)); - - if (x_changed) - g_object_notify (G_OBJECT (self), "x-align"); - - if (y_changed) - g_object_notify (G_OBJECT (self), "y-align"); - - g_object_thaw_notify (G_OBJECT (self)); - } -} - -static void -table_child_set_fill (ClutterTableChild *self, - gboolean x_fill, - gboolean y_fill) -{ - gboolean x_changed = FALSE, y_changed = FALSE; - - x_fill = !!x_fill; - y_fill = !!y_fill; - - if (self->x_fill != x_fill) - { - self->x_fill = x_fill; - - x_changed = TRUE; - } - - if (self->y_fill != y_fill) - { - self->y_fill = y_fill; - - y_changed = TRUE; - } - - if (x_changed || y_changed) - { - ClutterLayoutManager *layout; - - layout = clutter_layout_meta_get_manager (CLUTTER_LAYOUT_META (self)); - clutter_layout_manager_layout_changed (layout); - - g_object_freeze_notify (G_OBJECT (self)); - - if (x_changed) - g_object_notify (G_OBJECT (self), "x-fill"); - - if (y_changed) - g_object_notify (G_OBJECT (self), "y-fill"); - - g_object_thaw_notify (G_OBJECT (self)); - } -} - -static void -table_child_set_expand (ClutterTableChild *self, - gboolean x_expand, - gboolean y_expand) -{ - gboolean x_changed = FALSE, y_changed = FALSE; - - x_expand = !!x_expand; - y_expand = !!y_expand; - - if (self->x_expand != x_expand) - { - self->x_expand = x_expand; - - x_changed = TRUE; - } - - if (self->y_expand != y_expand) - { - self->y_expand = y_expand; - - y_changed = TRUE; - } - - if (x_changed || y_changed) - { - ClutterLayoutManager *layout; - - layout = clutter_layout_meta_get_manager (CLUTTER_LAYOUT_META (self)); - clutter_layout_manager_layout_changed (layout); - - g_object_freeze_notify (G_OBJECT (self)); - - if (x_changed) - g_object_notify (G_OBJECT (self), "x-expand"); - - if (y_changed) - g_object_notify (G_OBJECT (self), "y-expand"); - - g_object_thaw_notify (G_OBJECT (self)); - } -} - -static void -clutter_table_child_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterTableChild *self = CLUTTER_TABLE_CHILD (gobject); - - switch (prop_id) - { - case PROP_CHILD_COLUMN: - table_child_set_position (self, - g_value_get_int (value), - self->row); - break; - - case PROP_CHILD_ROW: - table_child_set_position (self, - self->col, - g_value_get_int (value)); - break; - - case PROP_CHILD_COLUMN_SPAN: - table_child_set_span (self, - g_value_get_int (value), - self->row_span); - break; - - case PROP_CHILD_ROW_SPAN: - table_child_set_span (self, - self->col_span, - g_value_get_int (value)); - break; - - case PROP_CHILD_X_ALIGN: - table_child_set_align (self, - g_value_get_enum (value), - self->y_align); - break; - - case PROP_CHILD_Y_ALIGN: - table_child_set_align (self, - self->x_align, - g_value_get_enum (value)); - break; - - case PROP_CHILD_X_FILL: - table_child_set_fill (self, - g_value_get_boolean (value), - self->y_fill); - break; - - case PROP_CHILD_Y_FILL: - table_child_set_fill (self, - self->x_fill, - g_value_get_boolean (value)); - break; - - case PROP_CHILD_X_EXPAND: - table_child_set_expand (self, - g_value_get_boolean (value), - self->y_expand); - break; - - case PROP_CHILD_Y_EXPAND: - table_child_set_expand (self, - self->x_expand, - g_value_get_boolean (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_table_child_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterTableChild *self = CLUTTER_TABLE_CHILD (gobject); - - switch (prop_id) - { - case PROP_CHILD_ROW: - g_value_set_int (value, self->row); - break; - - case PROP_CHILD_COLUMN: - g_value_set_int (value, self->col); - break; - - case PROP_CHILD_ROW_SPAN: - g_value_set_int (value, self->row_span); - break; - - case PROP_CHILD_COLUMN_SPAN: - g_value_set_int (value, self->col_span); - break; - - case PROP_CHILD_X_ALIGN: - g_value_set_enum (value, self->x_align); - break; - - case PROP_CHILD_Y_ALIGN: - g_value_set_enum (value, self->y_align); - break; - - case PROP_CHILD_X_FILL: - g_value_set_boolean (value, self->x_fill); - break; - - case PROP_CHILD_Y_FILL: - g_value_set_boolean (value, self->y_fill); - break; - - case PROP_CHILD_X_EXPAND: - g_value_set_boolean (value, self->x_expand); - break; - - case PROP_CHILD_Y_EXPAND: - g_value_set_boolean (value, self->y_expand); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_table_child_class_init (ClutterTableChildClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GParamSpec *pspec; - - gobject_class->set_property = clutter_table_child_set_property; - gobject_class->get_property = clutter_table_child_get_property; - - pspec = g_param_spec_int ("column", - P_("Column Number"), - P_("The column the widget resides in"), - 0, G_MAXINT, - 0, - CLUTTER_PARAM_READWRITE); - g_object_class_install_property (gobject_class, PROP_CHILD_COLUMN, pspec); - - pspec = g_param_spec_int ("row", - P_("Row Number"), - P_("The row the widget resides in"), - 0, G_MAXINT, - 0, - CLUTTER_PARAM_READWRITE); - g_object_class_install_property (gobject_class, PROP_CHILD_ROW, pspec); - - pspec = g_param_spec_int ("column-span", - P_("Column Span"), - P_("The number of columns the widget should span"), - 1, G_MAXINT, - 1, - CLUTTER_PARAM_READWRITE); - g_object_class_install_property (gobject_class, PROP_CHILD_COLUMN_SPAN, pspec); - - pspec = g_param_spec_int ("row-span", - P_("Row Span"), - P_("The number of rows the widget should span"), - 1, G_MAXINT, - 1, - CLUTTER_PARAM_READWRITE); - g_object_class_install_property (gobject_class, PROP_CHILD_ROW_SPAN, pspec); - - pspec = g_param_spec_boolean ("x-expand", - P_("Horizontal Expand"), - P_("Allocate extra space for the child in horizontal axis"), - TRUE, - CLUTTER_PARAM_READWRITE); - g_object_class_install_property (gobject_class, PROP_CHILD_X_EXPAND, pspec); - - pspec = g_param_spec_boolean ("y-expand", - P_("Vertical Expand"), - P_("Allocate extra space for the child in vertical axis"), - TRUE, - CLUTTER_PARAM_READWRITE); - g_object_class_install_property (gobject_class, PROP_CHILD_Y_EXPAND, pspec); - - pspec = g_param_spec_boolean ("x-fill", - P_("Horizontal Fill"), - P_("Whether the child should receive priority when the container is allocating spare space on the horizontal axis"), - TRUE, - CLUTTER_PARAM_READWRITE); - g_object_class_install_property (gobject_class, PROP_CHILD_X_FILL, pspec); - - pspec = g_param_spec_boolean ("y-fill", - P_("Vertical Fill"), - P_("Whether the child should receive priority when the container is allocating spare space on the vertical axis"), - TRUE, - CLUTTER_PARAM_READWRITE); - g_object_class_install_property (gobject_class, PROP_CHILD_Y_FILL, pspec); - - /** - * ClutterTableLayout:x-align: - * - * The horizontal alignment of the actor within the cell - * - * Since: 1.4 - */ - pspec = g_param_spec_enum ("x-align", - P_("Horizontal Alignment"), - P_("Horizontal alignment of the actor within the cell"), - CLUTTER_TYPE_TABLE_ALIGNMENT, - CLUTTER_TABLE_ALIGNMENT_CENTER, - CLUTTER_PARAM_READWRITE); - g_object_class_install_property (gobject_class, PROP_CHILD_X_ALIGN, pspec); - - /** - * ClutterTableLayout:y-align: - * - * The vertical alignment of the actor within the cell - * - * Since: 1.4 - */ - pspec = g_param_spec_enum ("y-align", - P_("Vertical Alignment"), - P_("Vertical alignment of the actor within the cell"), - CLUTTER_TYPE_TABLE_ALIGNMENT, - CLUTTER_TABLE_ALIGNMENT_CENTER, - CLUTTER_PARAM_READWRITE); - g_object_class_install_property (gobject_class, PROP_CHILD_Y_ALIGN, pspec); -} - -static void -clutter_table_child_init (ClutterTableChild *self) -{ - self->col_span = 1; - self->row_span = 1; - - self->x_align = CLUTTER_TABLE_ALIGNMENT_CENTER; - self->y_align = CLUTTER_TABLE_ALIGNMENT_CENTER; - - self->x_expand = TRUE; - self->y_expand = TRUE; - - self->x_fill = TRUE; - self->y_fill = TRUE; -} - -static GType -clutter_table_layout_get_child_meta_type (ClutterLayoutManager *manager) -{ - return CLUTTER_TYPE_TABLE_CHILD; -} - -static void -clutter_table_layout_set_container (ClutterLayoutManager *layout, - ClutterContainer *container) -{ - ClutterTableLayoutPrivate *priv = CLUTTER_TABLE_LAYOUT (layout)->priv; - - priv->container = container; -} - - -static void -update_row_col (ClutterTableLayout *layout, - ClutterContainer *container) -{ - ClutterTableLayoutPrivate *priv = layout->priv; - ClutterLayoutManager *manager = CLUTTER_LAYOUT_MANAGER (layout); - ClutterActor *actor, *child; - gint n_cols, n_rows; - - n_cols = n_rows = 0; - - if (container == NULL) - goto out; - - actor = CLUTTER_ACTOR (container); - for (child = clutter_actor_get_first_child (actor); - child != NULL; - child = clutter_actor_get_next_sibling (child)) - { - ClutterTableChild *meta; - - meta = - CLUTTER_TABLE_CHILD (clutter_layout_manager_get_child_meta (manager, - container, - child)); - - n_cols = MAX (n_cols, meta->col + meta->col_span); - n_rows = MAX (n_rows, meta->row + meta->row_span); - } - -out: - priv->n_cols = n_cols; - priv->n_rows = n_rows; - -} - -static void -calculate_col_widths (ClutterTableLayout *self, - ClutterContainer *container, - gint for_width) -{ - ClutterTableLayoutPrivate *priv = self->priv; - ClutterLayoutManager *manager = CLUTTER_LAYOUT_MANAGER (self); - ClutterActor *actor, *child; - gint i; - DimensionData *columns; - ClutterOrientation orientation = CLUTTER_ORIENTATION_HORIZONTAL; - - update_row_col (self, container); - g_array_set_size (priv->columns, 0); - g_array_set_size (priv->columns, priv->n_cols); - columns = (DimensionData *) (void *) priv->columns->data; - - /* reset the visibility of all columns */ - priv->visible_cols = 0; - for (i = 0; i < priv->n_cols; i++) - { - columns[i].expand = FALSE; - columns[i].visible = FALSE; - } - - actor = CLUTTER_ACTOR (container); - - /* STAGE ONE: calculate column widths for non-spanned children */ - for (child = clutter_actor_get_first_child (actor); - child != NULL; - child = clutter_actor_get_next_sibling (child)) - { - ClutterTableChild *meta; - DimensionData *col; - gfloat c_min, c_pref; - - if (!clutter_actor_is_visible (child)) - continue; - - meta = - CLUTTER_TABLE_CHILD (clutter_layout_manager_get_child_meta (manager, - container, - child)); - - if (meta->col_span > 1) - continue; - - col = &columns[meta->col]; - - if (!col->visible) - { - col->visible = TRUE; - priv->visible_cols += 1; - } - - clutter_actor_get_preferred_width (child, -1, &c_min, &c_pref); - - col->min_size = MAX (col->min_size, c_min); - col->pref_size = MAX (col->pref_size, c_pref); - - if (!col->expand) - { - col->expand = clutter_actor_needs_expand (child, orientation) || - meta->x_expand; - } - } - - /* STAGE TWO: take spanning children into account */ - for (child = clutter_actor_get_first_child (actor); - child != NULL; - child = clutter_actor_get_next_sibling (child)) - { - ClutterTableChild *meta; - gfloat c_min, c_pref; - gfloat min_width, pref_width; - gint start_col, end_col; - gint n_expand; - - if (!clutter_actor_is_visible (child)) - continue; - - meta = - CLUTTER_TABLE_CHILD (clutter_layout_manager_get_child_meta (manager, - container, - child)); - - if (meta->col_span < 2) - continue; - - start_col = meta->col; - end_col = meta->col + meta->col_span - 1; - - clutter_actor_get_preferred_width (child, -1, &c_min, &c_pref); - - /* check there is enough room for this actor */ - min_width = 0; - pref_width = 0; - n_expand = 0; - for (i = start_col; i <= end_col; i++) - { - min_width += columns[i].min_size; - pref_width += columns[i].pref_size; - - if (columns[i].expand) - n_expand++; - - if (!columns[i].visible) - { - columns[i].visible = TRUE; - priv->visible_cols += 1; - } - - if (!columns[i].expand) - { - columns[i].expand = clutter_actor_needs_expand (child, - orientation) || - meta->x_expand; - } - } - min_width += priv->col_spacing * (meta->col_span - 1); - pref_width += priv->col_spacing * (meta->col_span - 1); - - /* see calculate_row_heights() for comments */ - /* (1) */ - if (c_min > min_width) - { - - /* (2) */ - /* we can start from preferred width and decrease */ - if (pref_width > c_min) - { - for (i = start_col; i <= end_col; i++) - columns[i].final_size = columns[i].pref_size; - - while (pref_width > c_min) - { - for (i = start_col; i <= end_col; i++) - { - if (columns[i].final_size > columns[i].min_size) - { - columns[i].final_size--; - pref_width--; - } - } - } - - for (i = start_col; i <= end_col; i++) - columns[i].min_size = columns[i].final_size; - } - else - { - /* (3) */ - /* we can expand from preferred size */ - gfloat expand_by; - - expand_by = c_pref - pref_width; - - for (i = start_col; i <= end_col; i++) - { - if (n_expand) - { - if (columns[i].expand) - columns[i].min_size = columns[i].pref_size - + expand_by / n_expand; - } - else - columns[i].min_size = columns[i].pref_size - + expand_by / meta->col_span; - } - } - } - } - - /* calculate final widths */ - if (for_width >= 0) - { - gfloat min_width, pref_width; - gint n_expand; - - min_width = 0; - pref_width = 0; - n_expand = 0; - - for (i = 0; i < self->priv->n_cols; i++) - { - pref_width += columns[i].pref_size; - min_width += columns[i].min_size; - if (columns[i].expand) - n_expand++; - } - - pref_width += priv->col_spacing * MAX (priv->visible_cols - 1, 0); - min_width += priv->col_spacing * MAX (priv->visible_cols - 1, 0); - - if (for_width <= min_width) - { - /* erk, we can't shrink this! */ - for (i = 0; i < priv->n_cols; i++) - columns[i].final_size = columns[i].min_size; - - return; - } - - if (for_width == pref_width) - { - /* perfect! */ - for (i = 0; i < self->priv->n_cols; i++) - columns[i].final_size = columns[i].pref_size; - - return; - } - - /* for_width is between min_width and pref_width */ - if (for_width < pref_width && for_width > min_width) - { - gfloat width; - - /* shrink columns until they reach min_width */ - - /* start with all columns at preferred size */ - for (i = 0; i < self->priv->n_cols; i++) - columns[i].final_size = columns[i].pref_size; - - width = pref_width; - - while (width > for_width) - { - for (i = 0; i < self->priv->n_cols; i++) - { - if (columns[i].final_size > columns[i].min_size) - { - columns[i].final_size--; - width--; - } - } - } - - return; - } - - /* expand columns */ - if (for_width > pref_width) - { - gfloat extra_width = for_width - pref_width; - gint remaining; - - if (n_expand) - remaining = (gint) extra_width % n_expand; - else - remaining = (gint) extra_width % priv->n_cols; - - for (i = 0; i < self->priv->n_cols; i++) - { - if (columns[i].expand) - { - columns[i].final_size = columns[i].pref_size - + (extra_width / n_expand); - } - else - columns[i].final_size = columns[i].pref_size; - } - - /* distribute the remainder among children */ - i = 0; - while (remaining) - { - columns[i].final_size++; - i++; - remaining--; - } - } - } - -} - -static void -calculate_row_heights (ClutterTableLayout *self, - ClutterContainer *container, - gint for_height) -{ - ClutterTableLayoutPrivate *priv = self->priv; - ClutterLayoutManager *manager = CLUTTER_LAYOUT_MANAGER (self); - ClutterActor *actor, *child; - gint i; - DimensionData *rows, *columns; - ClutterOrientation orientation = CLUTTER_ORIENTATION_VERTICAL; - - update_row_col (self, container); - g_array_set_size (priv->rows, 0); - g_array_set_size (priv->rows, self->priv->n_rows); - - rows = (DimensionData *) (void *) priv->rows->data; - columns = (DimensionData *) (void *) priv->columns->data; - - /* reset the visibility of all rows */ - priv->visible_rows = 0; - for (i = 0; i < priv->n_rows; i++) - { - rows[i].expand = FALSE; - rows[i].visible = FALSE; - } - - actor = CLUTTER_ACTOR (container); - - /* STAGE ONE: calculate row heights for non-spanned children */ - for (child = clutter_actor_get_first_child (actor); - child != NULL; - child = clutter_actor_get_next_sibling (child)) - { - ClutterTableChild *meta; - DimensionData *row; - gfloat c_min, c_pref; - - if (!clutter_actor_is_visible (child)) - continue; - - meta = - CLUTTER_TABLE_CHILD (clutter_layout_manager_get_child_meta (manager, - container, - child)); - - if (meta->row_span > 1) - continue; - - row = &rows[meta->row]; - - if (!row->visible) - { - row->visible = TRUE; - priv->visible_rows += 1; - } - - clutter_actor_get_preferred_height (child, columns[meta->col].final_size, - &c_min, &c_pref); - - row->min_size = MAX (row->min_size, c_min); - row->pref_size = MAX (row->pref_size, c_pref); - - if (!row->expand) - { - row->expand = clutter_actor_needs_expand (child, orientation) || - meta->y_expand; - } - } - - /* STAGE TWO: take spanning children into account */ - for (child = clutter_actor_get_first_child (actor); - child != NULL; - child = clutter_actor_get_next_sibling (child)) - { - ClutterTableChild *meta; - gfloat c_min, c_pref; - gfloat min_height, pref_height; - gint start_row, end_row; - gint n_expand; - - if (!clutter_actor_is_visible (child)) - continue; - - meta = - CLUTTER_TABLE_CHILD (clutter_layout_manager_get_child_meta (manager, - container, - child)); - - if (meta->row_span < 2) - continue; - - start_row = meta->row; - end_row = meta->row + meta->row_span - 1; - - clutter_actor_get_preferred_height (child, columns[meta->col].final_size, - &c_min, &c_pref); - - - /* check there is enough room for this actor */ - min_height = 0; - pref_height = 0; - n_expand = 0; - for (i = start_row; i <= end_row; i++) - { - min_height += rows[i].min_size; - pref_height += rows[i].pref_size; - - if (rows[i].expand) - n_expand++; - - if (!rows[i].visible) - { - rows[i].visible = TRUE; - priv->visible_rows += 1; - } - - if (!rows[i].expand) - { - rows[i].expand = clutter_actor_needs_expand (child, orientation) || - meta->y_expand; - } - } - - min_height += priv->row_spacing * (meta->row_span - 1); - pref_height += priv->row_spacing * (meta->row_span - 1); - - /* 1) If the minimum height of the rows spanned is less than the - * minimum height of the child that is spanning them, then we - * must increase the minimum height of the rows spanned. - * - * 2) If the preferred height of the spanned rows is more than - * the minimum height of the spanning child, then we can start - * at this size and decrease each row evenly. - * - * 3) If the preferred height of the rows is more than the minimum - * height of the spanned child, then we can start at the preferred - * height and expand. - */ - - /* (1) */ - if (c_min > min_height) - { - - /* (2) */ - /* we can start from preferred height and decrease */ - if (pref_height > c_min) - { - for (i = start_row; i <= end_row; i++) - rows[i].final_size = rows[i].pref_size; - - while (pref_height > c_min) - { - for (i = start_row; i <= end_row; i++) - { - if (rows[i].final_size > rows[i].min_size) - { - rows[i].final_size--; - pref_height--; - } - } - } - - for (i = start_row; i <= end_row; i++) - rows[i].min_size = rows[i].final_size; - } - else - { - /* (3) */ - /* we can expand from preferred size */ - gfloat expand_by = c_pref - pref_height; - - for (i = start_row; i <= end_row; i++) - { - if (n_expand) - { - if (rows[i].expand) - rows[i].min_size = rows[i].pref_size - + expand_by / n_expand; - } - else - rows[i].min_size = rows[i].pref_size - + expand_by / meta->row_span; - } - } - } - } - - /* calculate final heights */ - if (for_height >= 0) - { - gfloat min_height, pref_height; - gint n_expand; - - min_height = 0; - pref_height = 0; - n_expand = 0; - - for (i = 0; i < self->priv->n_rows; i++) - { - pref_height += rows[i].pref_size; - min_height += rows[i].min_size; - if (rows[i].expand) - n_expand++; - } - - pref_height += priv->row_spacing * MAX (priv->visible_rows - 1, 0); - min_height += priv->row_spacing * MAX (priv->visible_rows - 1, 0); - - if (for_height <= min_height) - { - /* erk, we can't shrink this! */ - for (i = 0; i < self->priv->n_rows; i++) - rows[i].final_size = rows[i].min_size; - - return; - } - - if (for_height == pref_height) - { - /* perfect! */ - for (i = 0; i < self->priv->n_rows; i++) - rows[i].final_size = rows[i].pref_size; - - return; - } - - /* for_height is between min_height and pref_height */ - if (for_height < pref_height && for_height > min_height) - { - gfloat height; - - /* shrink rows until they reach min_height */ - - /* start with all rows at preferred size */ - for (i = 0; i < self->priv->n_rows; i++) - rows[i].final_size = rows[i].pref_size; - - height = pref_height; - - while (height > for_height) - { - for (i = 0; i < priv->n_rows; i++) - { - if (rows[i].final_size > rows[i].min_size) - { - rows[i].final_size--; - height--; - } - } - } - - return; - } - - /* expand rows */ - if (for_height > pref_height) - { - gfloat extra_height = for_height - pref_height; - gint remaining; - - if (n_expand) - remaining = (gint) extra_height % n_expand; - else - remaining = (gint) extra_height % self->priv->n_rows; - - for (i = 0; i < self->priv->n_rows; i++) - { - if (rows[i].expand) - { - rows[i].final_size = rows[i].pref_size - + (extra_height / n_expand); - } - else - rows[i].final_size = rows[i].pref_size; - } - - /* distribute the remainder among children */ - i = 0; - while (remaining) - { - rows[i].final_size++; - i++; - remaining--; - } - } - } - -} - -static void -calculate_table_dimensions (ClutterTableLayout *self, - ClutterContainer *container, - gfloat for_width, - gfloat for_height) -{ - calculate_col_widths (self, container, for_width); - calculate_row_heights (self, container, for_height); -} - -static void -clutter_table_layout_get_preferred_width (ClutterLayoutManager *layout, - ClutterContainer *container, - gfloat for_height, - gfloat *min_width_p, - gfloat *natural_width_p) -{ - ClutterTableLayout *self = CLUTTER_TABLE_LAYOUT (layout); - ClutterTableLayoutPrivate *priv = self->priv; - gfloat total_min_width, total_pref_width; - DimensionData *columns; - gint i; - - update_row_col (self, container); - if (priv->n_cols < 1) - { - *min_width_p = 0; - *natural_width_p = 0; - return; - } - - calculate_table_dimensions (self, container, -1, for_height); - columns = (DimensionData *) (void *) priv->columns->data; - - total_min_width = MAX ((priv->visible_cols - 1) * (float) priv->col_spacing, 0); - total_pref_width = total_min_width; - - for (i = 0; i < priv->n_cols; i++) - { - total_min_width += columns[i].min_size; - total_pref_width += columns[i].pref_size; - } - - if (min_width_p) - *min_width_p = total_min_width; - - if (natural_width_p) - *natural_width_p = total_pref_width; -} - -static void -clutter_table_layout_get_preferred_height (ClutterLayoutManager *layout, - ClutterContainer *container, - gfloat for_width, - gfloat *min_height_p, - gfloat *natural_height_p) -{ - ClutterTableLayout *self = CLUTTER_TABLE_LAYOUT (layout); - ClutterTableLayoutPrivate *priv = self->priv; - gfloat total_min_height, total_pref_height; - DimensionData *rows; - gint i; - - update_row_col (self, container); - if (priv->n_rows < 1) - { - *min_height_p = 0; - *natural_height_p = 0; - return; - } - - calculate_table_dimensions (self, container, for_width, -1); - rows = (DimensionData *) (void *) priv->rows->data; - - total_min_height = MAX ((priv->visible_rows - 1) * (float) priv->row_spacing, 0); - total_pref_height = total_min_height; - - for (i = 0; i < self->priv->n_rows; i++) - { - total_min_height += rows[i].min_size; - total_pref_height += rows[i].pref_size; - } - - if (min_height_p) - *min_height_p = total_min_height; - - if (natural_height_p) - *natural_height_p = total_pref_height; -} - -static gdouble -get_table_alignment_factor (ClutterTableAlignment alignment) -{ - switch (alignment) - { - case CLUTTER_TABLE_ALIGNMENT_START: - return 0.0; - - case CLUTTER_TABLE_ALIGNMENT_CENTER: - return 0.5; - - case CLUTTER_TABLE_ALIGNMENT_END: - return 1.0; - } - - return 0.0; -} - -static void -clutter_table_layout_allocate (ClutterLayoutManager *layout, - ClutterContainer *container, - const ClutterActorBox *box, - ClutterAllocationFlags flags) -{ - ClutterTableLayout *self = CLUTTER_TABLE_LAYOUT (layout); - ClutterTableLayoutPrivate *priv = self->priv; - ClutterActor *actor, *child; - gint row_spacing, col_spacing; - gint i; - DimensionData *rows, *columns; - - update_row_col (self, container); - if (priv->n_cols < 1 || priv->n_rows < 1) - return; - - actor = CLUTTER_ACTOR (container); - - if (clutter_actor_get_n_children (actor) == 0) - return; - - col_spacing = (priv->col_spacing); - row_spacing = (priv->row_spacing); - - calculate_table_dimensions (self, container, - box->x2 - box->x1, - box->y2 - box->y1); - - rows = (DimensionData *) (void *) priv->rows->data; - columns = (DimensionData *) (void *) priv->columns->data; - - for (child = clutter_actor_get_first_child (actor); - child != NULL; - child = clutter_actor_get_next_sibling (child)) - { - gint row, col, row_span, col_span; - gint col_width, row_height; - ClutterTableChild *meta; - ClutterActorBox childbox; - gint child_x, child_y; - gdouble x_align, y_align; - gboolean x_fill, y_fill; - - if (!clutter_actor_is_visible (child)) - continue; - - meta = - CLUTTER_TABLE_CHILD (clutter_layout_manager_get_child_meta (layout, - container, - child)); - - /* get child properties */ - col = meta->col; - row = meta->row; - row_span = meta->row_span; - col_span = meta->col_span; - x_align = get_table_alignment_factor (meta->x_align); - y_align = get_table_alignment_factor (meta->y_align); - x_fill = meta->x_fill; - y_fill = meta->y_fill; - - /* initialise the width and height */ - col_width = columns[col].final_size; - row_height = rows[row].final_size; - - /* Add the widths of the spanned columns: - * - * First check that we have a non-zero span. Then we loop over each of - * the columns that we're spanning but we stop short if we go past the - * number of columns in the table. This is necessary to avoid accessing - * uninitialised memory. We add the spacing in here too since we only - * want to add as much spacing as times we successfully span. - */ - if (col + col_span > priv->n_cols) - g_warning (G_STRLOC ": column-span exceeds number of columns"); - if (row + row_span > priv->n_rows) - g_warning (G_STRLOC ": row-span exceeds number of rows"); - - if (col_span > 1) - { - for (i = col + 1; i < col + col_span && i < priv->n_cols; i++) - { - col_width += columns[i].final_size; - col_width += col_spacing; - } - } - - /* add the height of the spanned rows */ - if (row_span > 1) - { - for (i = row + 1; i < row + row_span && i < priv->n_rows; i++) - { - row_height += rows[i].final_size; - row_height += row_spacing; - } - } - - /* calculate child x */ - child_x = clutter_actor_box_get_x (box); - for (i = 0; i < col; i++) - { - if (columns[i].visible) - { - child_x += columns[i].final_size; - child_x += col_spacing; - } - } - - /* calculate child y */ - child_y = clutter_actor_box_get_y (box); - for (i = 0; i < row; i++) - { - if (rows[i].visible) - { - child_y += rows[i].final_size; - child_y += row_spacing; - } - } - - /* set up childbox */ - childbox.x1 = (float) child_x; - childbox.x2 = (float) MAX (0, child_x + col_width); - - childbox.y1 = (float) child_y; - childbox.y2 = (float) MAX (0, child_y + row_height); - - if (priv->use_animations) - { - clutter_actor_save_easing_state (child); - clutter_actor_set_easing_mode (child, priv->easing_mode); - clutter_actor_set_easing_duration (child, priv->easing_duration); - } - - if (clutter_actor_needs_expand (child, CLUTTER_ORIENTATION_HORIZONTAL) || - clutter_actor_needs_expand (child, CLUTTER_ORIENTATION_VERTICAL)) - clutter_actor_allocate (child, &childbox, flags); - else - clutter_actor_allocate_align_fill (child, &childbox, - x_align, y_align, - x_fill, y_fill, - flags); - - if (priv->use_animations) - clutter_actor_restore_easing_state (child); - } -} - -static void -clutter_table_layout_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterTableLayout *self = CLUTTER_TABLE_LAYOUT (gobject); - - switch (prop_id) - { - case PROP_COLUMN_SPACING: - clutter_table_layout_set_column_spacing (self, g_value_get_uint (value)); - break; - - case PROP_ROW_SPACING: - clutter_table_layout_set_row_spacing (self, g_value_get_uint (value)); - break; - - case PROP_USE_ANIMATIONS: - clutter_table_layout_set_use_animations (self, g_value_get_boolean (value)); - break; - - case PROP_EASING_MODE: - clutter_table_layout_set_easing_mode (self, g_value_get_ulong (value)); - break; - - case PROP_EASING_DURATION: - clutter_table_layout_set_easing_duration (self, g_value_get_uint (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_table_layout_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterTableLayoutPrivate *priv = CLUTTER_TABLE_LAYOUT (gobject)->priv; - - switch (prop_id) - { - case PROP_ROW_SPACING: - g_value_set_uint (value, priv->row_spacing); - break; - - case PROP_COLUMN_SPACING: - g_value_set_uint (value, priv->col_spacing); - break; - - case PROP_USE_ANIMATIONS: - g_value_set_boolean (value, priv->use_animations); - break; - - case PROP_EASING_MODE: - g_value_set_ulong (value, priv->easing_mode); - break; - - case PROP_EASING_DURATION: - g_value_set_uint (value, priv->easing_duration); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_table_layout_finalize (GObject *gobject) -{ - ClutterTableLayoutPrivate *priv = CLUTTER_TABLE_LAYOUT (gobject)->priv; - - g_array_free (priv->columns, TRUE); - g_array_free (priv->rows, TRUE); - - G_OBJECT_CLASS (clutter_table_layout_parent_class)->finalize (gobject); -} - -static void -clutter_table_layout_class_init (ClutterTableLayoutClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterLayoutManagerClass *layout_class; - GParamSpec *pspec; - - layout_class = CLUTTER_LAYOUT_MANAGER_CLASS (klass); - - gobject_class->set_property = clutter_table_layout_set_property; - gobject_class->get_property = clutter_table_layout_get_property; - gobject_class->finalize = clutter_table_layout_finalize; - - layout_class->get_preferred_width = - clutter_table_layout_get_preferred_width; - layout_class->get_preferred_height = - clutter_table_layout_get_preferred_height; - layout_class->allocate = clutter_table_layout_allocate; - layout_class->set_container = clutter_table_layout_set_container; - layout_class->get_child_meta_type = - clutter_table_layout_get_child_meta_type; - - /** - * ClutterTableLayout:column-spacing: - * - * The spacing between columns of the #ClutterTableLayout, in pixels - * - * Since: 1.4 - * - * Deprecated: 1.18: Use #ClutterGridLayout:column-spacing instead - */ - pspec = g_param_spec_uint ("column-spacing", - P_("Column Spacing"), - P_("Spacing between columns"), - 0, G_MAXUINT, 0, - CLUTTER_PARAM_READWRITE); - g_object_class_install_property (gobject_class, PROP_COLUMN_SPACING, pspec); - - /** - * ClutterTableLayout:row-spacing: - * - * The spacing between rows of the #ClutterTableLayout, in pixels - * - * Since: 1.4 - * - * Deprecated: 1.18: Use #ClutterGridLayout:row-spacing instead - */ - pspec = g_param_spec_uint ("row-spacing", - P_("Row Spacing"), - P_("Spacing between rows"), - 0, G_MAXUINT, 0, - CLUTTER_PARAM_READWRITE); - g_object_class_install_property (gobject_class, PROP_ROW_SPACING, pspec); - - /** - * ClutterTableLayout:use-animations: - * - * Whether the #ClutterTableLayout should animate changes in the - * layout properties. - * - * By default, #ClutterTableLayout will honour the easing state of - * the children when allocating them. Setting this property to - * %TRUE will override the easing state with the layout manager's - * #ClutterTableLayout:easing-mode and #ClutterTableLayout:easing-duration - * properties. - * - * Since: 1.4 - * - * Deprecated: 1.12: #ClutterTableLayout will honour the easing state - * of the children when allocating them - */ - pspec = g_param_spec_boolean ("use-animations", - P_("Use Animations"), - P_("Whether layout changes should be animated"), - FALSE, - CLUTTER_PARAM_READWRITE); - g_object_class_install_property (gobject_class, PROP_USE_ANIMATIONS, pspec); - - /** - * ClutterTableLayout:easing-mode: - * - * The easing mode for the animations, in case - * #ClutterTableLayout:use-animations is set to %TRUE. - * - * The easing mode has the same semantics of #ClutterAnimation:mode: it can - * either be a value from the #ClutterAnimationMode enumeration, like - * %CLUTTER_EASE_OUT_CUBIC, or a logical id as returned by - * clutter_alpha_register_func(). - * - * The default value is %CLUTTER_EASE_OUT_CUBIC. - * - * Since: 1.4 - * - * Deprecated: 1.12: #ClutterTableLayout will honour the easing state - * of the children when allocating them - */ - pspec = g_param_spec_ulong ("easing-mode", - P_("Easing Mode"), - P_("The easing mode of the animations"), - 0, G_MAXULONG, - CLUTTER_EASE_OUT_CUBIC, - CLUTTER_PARAM_READWRITE); - g_object_class_install_property (gobject_class, PROP_EASING_MODE, pspec); - - /** - * ClutterTableLayout:easing-duration: - * - * The duration of the animations, in case #ClutterTableLayout:use-animations - * is set to %TRUE. - * - * The duration is expressed in milliseconds. - * - * Since: 1.4 - * - * Deprecated: 1.12: #ClutterTableLayout will honour the easing state - * of the children when allocating them - */ - pspec = g_param_spec_uint ("easing-duration", - P_("Easing Duration"), - P_("The duration of the animations"), - 0, G_MAXUINT, - 500, - CLUTTER_PARAM_READWRITE); - g_object_class_install_property (gobject_class, PROP_EASING_DURATION, pspec); -} - -static void -clutter_table_layout_init (ClutterTableLayout *layout) -{ - ClutterTableLayoutPrivate *priv; - - layout->priv = priv = clutter_table_layout_get_instance_private (layout); - - priv->row_spacing = 0; - priv->col_spacing = 0; - - priv->use_animations = FALSE; - priv->easing_mode = CLUTTER_EASE_OUT_CUBIC; - priv->easing_duration = 500; - - priv->columns = g_array_new (FALSE, TRUE, sizeof (DimensionData)); - priv->rows = g_array_new (FALSE, TRUE, sizeof (DimensionData)); -} - -/** - * clutter_table_layout_new: - * - * Creates a new #ClutterTableLayout layout manager - * - * Return value: the newly created #ClutterTableLayout - * - * Since: 1.4 - * - * Deprecated: 1.18: Use #ClutterGridLayout instead - */ -ClutterLayoutManager * -clutter_table_layout_new (void) -{ - return g_object_new (CLUTTER_TYPE_TABLE_LAYOUT, NULL); -} - -/** - * clutter_table_layout_set_column_spacing: - * @layout: a #ClutterTableLayout - * @spacing: the spacing between columns of the layout, in pixels - * - * Sets the spacing between columns of @layout - * - * Since: 1.4 - * - * Deprecated: 1.18: Use #ClutterGridLayout:column-spacing instead - */ -void -clutter_table_layout_set_column_spacing (ClutterTableLayout *layout, - guint spacing) -{ - ClutterTableLayoutPrivate *priv; - - g_return_if_fail (CLUTTER_IS_TABLE_LAYOUT (layout)); - - priv = layout->priv; - - if (priv->col_spacing != spacing) - { - ClutterLayoutManager *manager; - - priv->col_spacing = spacing; - - manager = CLUTTER_LAYOUT_MANAGER (layout); - clutter_layout_manager_layout_changed (manager); - - g_object_notify (G_OBJECT (layout), "column-spacing"); - } -} - -/** - * clutter_table_layout_get_column_spacing: - * @layout: a #ClutterTableLayout - * - * Retrieves the spacing set using clutter_table_layout_set_column_spacing() - * - * Return value: the spacing between columns of the #ClutterTableLayout - * - * Since: 1.4 - * - * Deprecated: 1.18: Use #ClutterGridLayout:column-spacing - */ -guint -clutter_table_layout_get_column_spacing (ClutterTableLayout *layout) -{ - g_return_val_if_fail (CLUTTER_IS_TABLE_LAYOUT (layout), 0); - - return layout->priv->col_spacing; -} - -/** - * clutter_table_layout_set_row_spacing: - * @layout: a #ClutterTableLayout - * @spacing: the spacing between rows of the layout, in pixels - * - * Sets the spacing between rows of @layout - * - * Since: 1.4 - * - * Deprecated: 1.18: Use #ClutterGridLayout:row-spacing instead - */ -void -clutter_table_layout_set_row_spacing (ClutterTableLayout *layout, - guint spacing) -{ - ClutterTableLayoutPrivate *priv; - - g_return_if_fail (CLUTTER_IS_TABLE_LAYOUT (layout)); - - priv = layout->priv; - - if (priv->row_spacing != spacing) - { - ClutterLayoutManager *manager; - - priv->row_spacing = spacing; - - manager = CLUTTER_LAYOUT_MANAGER (layout); - clutter_layout_manager_layout_changed (manager); - - g_object_notify (G_OBJECT (layout), "row-spacing"); - } -} - -/** - * clutter_table_layout_get_row_spacing: - * @layout: a #ClutterTableLayout - * - * Retrieves the spacing set using clutter_table_layout_set_row_spacing() - * - * Return value: the spacing between rows of the #ClutterTableLayout - * - * Since: 1.4 - * - * Deprecated: 1.18: Use #ClutterGridLayout:row-spacing instead - */ -guint -clutter_table_layout_get_row_spacing (ClutterTableLayout *layout) -{ - g_return_val_if_fail (CLUTTER_IS_TABLE_LAYOUT (layout), 0); - - return layout->priv->row_spacing; -} - -/** - * clutter_table_layout_pack: - * @layout: a #ClutterTableLayout - * @actor: a #ClutterActor - * @column: the column the @actor should be put, or -1 to append - * @row: the row the @actor should be put, or -1 to append - * - * Packs @actor inside the #ClutterContainer associated to @layout - * at the given row and column. - * - * Since: 1.4 - * - * Deprecated: 1.18: Use clutter_grid_layout_attach_child() instead - */ -void -clutter_table_layout_pack (ClutterTableLayout *layout, - ClutterActor *actor, - gint column, - gint row) -{ - ClutterTableLayoutPrivate *priv; - ClutterLayoutManager *manager; - ClutterLayoutMeta *meta; - - g_return_if_fail (CLUTTER_IS_TABLE_LAYOUT (layout)); - g_return_if_fail (CLUTTER_IS_ACTOR (actor)); - - priv = layout->priv; - - if (priv->container == NULL) - { - g_warning ("The layout of type '%s' must be associated to " - "a ClutterContainer before adding children", - G_OBJECT_TYPE_NAME (layout)); - return; - } - - update_row_col (CLUTTER_TABLE_LAYOUT (layout), priv->container); - - clutter_container_add_actor (priv->container, actor); - - manager = CLUTTER_LAYOUT_MANAGER (layout); - meta = clutter_layout_manager_get_child_meta (manager, - priv->container, - actor); - g_assert (CLUTTER_IS_TABLE_CHILD (meta)); - - if (row < 0) - row = priv->n_rows; - - if (column < 0) - column = priv->n_cols; - - table_child_set_position (CLUTTER_TABLE_CHILD (meta), column, row); -} - -/** - * clutter_table_layout_set_span: - * @layout: a #ClutterTableLayout - * @actor: a #ClutterActor child of @layout - * @column_span: Column span for @actor - * @row_span: Row span for @actor - * - * Sets the row and column span for @actor - * inside @layout - * - * Since: 1.4 - * - * Deprecated: 1.18: Use the `width` and `height` layout properties - * of #ClutterGridLayout instead - */ -void -clutter_table_layout_set_span (ClutterTableLayout *layout, - ClutterActor *actor, - gint column_span, - gint row_span) -{ - ClutterTableLayoutPrivate *priv; - ClutterLayoutManager *manager; - ClutterLayoutMeta *meta; - - g_return_if_fail (CLUTTER_IS_TABLE_LAYOUT (layout)); - g_return_if_fail (CLUTTER_IS_ACTOR (actor)); - - priv = layout->priv; - - if (priv->container == NULL) - { - g_warning ("The layout of type '%s' must be associated to " - "a ClutterContainer before querying layout " - "properties", - G_OBJECT_TYPE_NAME (layout)); - return; - } - - manager = CLUTTER_LAYOUT_MANAGER (layout); - meta = clutter_layout_manager_get_child_meta (manager, - priv->container, - actor); - if (meta == NULL) - { - g_warning ("No layout meta found for the child of type '%s' " - "inside the layout manager of type '%s'", - G_OBJECT_TYPE_NAME (actor), - G_OBJECT_TYPE_NAME (manager)); - return; - } - - g_assert (CLUTTER_IS_TABLE_CHILD (meta)); - - table_child_set_span (CLUTTER_TABLE_CHILD (meta), column_span, row_span); -} - -/** - * clutter_table_layout_get_span: - * @layout: a #ClutterTableLayout - * @actor: a #ClutterActor child of @layout - * @column_span: (out): return location for the col span - * @row_span: (out): return location for the row span - * - * Retrieves the row and column span for @actor as set using - * clutter_table_layout_pack() or clutter_table_layout_set_span() - * - * Since: 1.4 - * - * Deprecated: 1.18: Use the `width` and `height` layout properties - * of #ClutterGridLayout instead - */ -void -clutter_table_layout_get_span (ClutterTableLayout *layout, - ClutterActor *actor, - gint *column_span, - gint *row_span) -{ - ClutterTableLayoutPrivate *priv; - ClutterLayoutManager *manager; - ClutterLayoutMeta *meta; - - g_return_if_fail (CLUTTER_IS_TABLE_LAYOUT (layout)); - g_return_if_fail (CLUTTER_IS_ACTOR (actor)); - - priv = layout->priv; - - if (priv->container == NULL) - { - g_warning ("The layout of type '%s' must be associated to " - "a ClutterContainer before querying layout " - "properties", - G_OBJECT_TYPE_NAME (layout)); - return; - } - - manager = CLUTTER_LAYOUT_MANAGER (layout); - meta = clutter_layout_manager_get_child_meta (manager, - priv->container, - actor); - if (meta == NULL) - { - g_warning ("No layout meta found for the child of type '%s' " - "inside the layout manager of type '%s'", - G_OBJECT_TYPE_NAME (actor), - G_OBJECT_TYPE_NAME (manager)); - return; - } - - g_assert (CLUTTER_IS_TABLE_CHILD (meta)); - - if (column_span) - *column_span = CLUTTER_TABLE_CHILD (meta)->col_span; - - if (row_span) - *row_span = CLUTTER_TABLE_CHILD (meta)->row_span; -} - -/** - * clutter_table_layout_set_alignment: - * @layout: a #ClutterTableLayout - * @actor: a #ClutterActor child of @layout - * @x_align: Horizontal alignment policy for @actor - * @y_align: Vertical alignment policy for @actor - * - * Sets the horizontal and vertical alignment policies for @actor - * inside @layout - * - * Since: 1.4 - * - * Deprecated: 1.12: Use clutter_actor_set_x_align() and - * clutter_actor_set_y_align() instead. - */ -void -clutter_table_layout_set_alignment (ClutterTableLayout *layout, - ClutterActor *actor, - ClutterTableAlignment x_align, - ClutterTableAlignment y_align) -{ - ClutterTableLayoutPrivate *priv; - ClutterLayoutManager *manager; - ClutterLayoutMeta *meta; - - g_return_if_fail (CLUTTER_IS_TABLE_LAYOUT (layout)); - g_return_if_fail (CLUTTER_IS_ACTOR (actor)); - - priv = layout->priv; - - if (priv->container == NULL) - { - g_warning ("The layout of type '%s' must be associated to " - "a ClutterContainer before querying layout " - "properties", - G_OBJECT_TYPE_NAME (layout)); - return; - } - - manager = CLUTTER_LAYOUT_MANAGER (layout); - meta = clutter_layout_manager_get_child_meta (manager, - priv->container, - actor); - if (meta == NULL) - { - g_warning ("No layout meta found for the child of type '%s' " - "inside the layout manager of type '%s'", - G_OBJECT_TYPE_NAME (actor), - G_OBJECT_TYPE_NAME (manager)); - return; - } - - g_assert (CLUTTER_IS_TABLE_CHILD (meta)); - - table_child_set_align (CLUTTER_TABLE_CHILD (meta), x_align, y_align); -} - -/** - * clutter_table_layout_get_alignment: - * @layout: a #ClutterTableLayout - * @actor: a #ClutterActor child of @layout - * @x_align: (out): return location for the horizontal alignment policy - * @y_align: (out): return location for the vertical alignment policy - * - * Retrieves the horizontal and vertical alignment policies for @actor - * as set using clutter_table_layout_pack() or - * clutter_table_layout_set_alignment(). - * - * Since: 1.4 - * - * Deprecated: 1.12: Use clutter_actor_get_x_align() and - * clutter_actor_get_y_align() instead. - */ -void -clutter_table_layout_get_alignment (ClutterTableLayout *layout, - ClutterActor *actor, - ClutterTableAlignment *x_align, - ClutterTableAlignment *y_align) -{ - ClutterTableLayoutPrivate *priv; - ClutterLayoutManager *manager; - ClutterLayoutMeta *meta; - - g_return_if_fail (CLUTTER_IS_TABLE_LAYOUT (layout)); - g_return_if_fail (CLUTTER_IS_ACTOR (actor)); - - priv = layout->priv; - - if (priv->container == NULL) - { - g_warning ("The layout of type '%s' must be associated to " - "a ClutterContainer before querying layout " - "properties", - G_OBJECT_TYPE_NAME (layout)); - return; - } - - manager = CLUTTER_LAYOUT_MANAGER (layout); - meta = clutter_layout_manager_get_child_meta (manager, - priv->container, - actor); - if (meta == NULL) - { - g_warning ("No layout meta found for the child of type '%s' " - "inside the layout manager of type '%s'", - G_OBJECT_TYPE_NAME (actor), - G_OBJECT_TYPE_NAME (manager)); - return; - } - - g_assert (CLUTTER_IS_TABLE_CHILD (meta)); - - if (x_align) - *x_align = CLUTTER_TABLE_CHILD (meta)->x_align; - - if (y_align) - *y_align = CLUTTER_TABLE_CHILD (meta)->y_align; -} - -/** - * clutter_table_layout_set_fill: - * @layout: a #ClutterTableLayout - * @actor: a #ClutterActor child of @layout - * @x_fill: whether @actor should fill horizontally the allocated space - * @y_fill: whether @actor should fill vertically the allocated space - * - * Sets the horizontal and vertical fill policies for @actor - * inside @layout - * - * Since: 1.4 - * - * Deprecated: 1.12: Use clutter_actor_set_x_align() and - * clutter_actor_set_y_align() instead. - */ -void -clutter_table_layout_set_fill (ClutterTableLayout *layout, - ClutterActor *actor, - gboolean x_fill, - gboolean y_fill) -{ - ClutterTableLayoutPrivate *priv; - ClutterLayoutManager *manager; - ClutterLayoutMeta *meta; - - g_return_if_fail (CLUTTER_IS_TABLE_LAYOUT (layout)); - g_return_if_fail (CLUTTER_IS_ACTOR (actor)); - - priv = layout->priv; - - if (priv->container == NULL) - { - g_warning ("The layout of type '%s' must be associated to " - "a ClutterContainer before querying layout " - "properties", - G_OBJECT_TYPE_NAME (layout)); - return; - } - - manager = CLUTTER_LAYOUT_MANAGER (layout); - meta = clutter_layout_manager_get_child_meta (manager, - priv->container, - actor); - if (meta == NULL) - { - g_warning ("No layout meta found for the child of type '%s' " - "inside the layout manager of type '%s'", - G_OBJECT_TYPE_NAME (actor), - G_OBJECT_TYPE_NAME (manager)); - return; - } - - g_assert (CLUTTER_IS_TABLE_CHILD (meta)); - - table_child_set_fill (CLUTTER_TABLE_CHILD (meta), x_fill, y_fill); -} - -/** - * clutter_table_layout_get_fill: - * @layout: a #ClutterTableLayout - * @actor: a #ClutterActor child of @layout - * @x_fill: (out): return location for the horizontal fill policy - * @y_fill: (out): return location for the vertical fill policy - * - * Retrieves the horizontal and vertical fill policies for @actor - * as set using clutter_table_layout_pack() or clutter_table_layout_set_fill() - * - * Since: 1.4 - * - * Deprecated: 1.12: Use clutter_actor_get_x_align() and - * clutter_actor_get_y_align() instead. - */ -void -clutter_table_layout_get_fill (ClutterTableLayout *layout, - ClutterActor *actor, - gboolean *x_fill, - gboolean *y_fill) -{ - ClutterTableLayoutPrivate *priv; - ClutterLayoutManager *manager; - ClutterLayoutMeta *meta; - - g_return_if_fail (CLUTTER_IS_TABLE_LAYOUT (layout)); - g_return_if_fail (CLUTTER_IS_ACTOR (actor)); - - priv = layout->priv; - - if (priv->container == NULL) - { - g_warning ("The layout of type '%s' must be associated to " - "a ClutterContainer before querying layout " - "properties", - G_OBJECT_TYPE_NAME (layout)); - return; - } - - manager = CLUTTER_LAYOUT_MANAGER (layout); - meta = clutter_layout_manager_get_child_meta (manager, - priv->container, - actor); - if (meta == NULL) - { - g_warning ("No layout meta found for the child of type '%s' " - "inside the layout manager of type '%s'", - G_OBJECT_TYPE_NAME (actor), - G_OBJECT_TYPE_NAME (manager)); - return; - } - - g_assert (CLUTTER_IS_TABLE_CHILD (meta)); - - if (x_fill) - *x_fill = CLUTTER_TABLE_CHILD (meta)->x_fill; - - if (y_fill) - *y_fill = CLUTTER_TABLE_CHILD (meta)->y_fill; -} - - -/** - * clutter_table_layout_set_expand: - * @layout: a #ClutterTableLayout - * @actor: a #ClutterActor child of @layout - * @x_expand: whether @actor should allocate extra space horizontally - * @y_expand: whether @actor should allocate extra space vertically - * - * Sets the horizontal and vertical expand policies for @actor - * inside @layout - * - * Since: 1.4 - * - * Deprecated: 1.12: Use clutter_actor_set_x_expand() or - * clutter_actor_set_y_expand() instead. - */ -void -clutter_table_layout_set_expand (ClutterTableLayout *layout, - ClutterActor *actor, - gboolean x_expand, - gboolean y_expand) -{ - ClutterTableLayoutPrivate *priv; - ClutterLayoutManager *manager; - ClutterLayoutMeta *meta; - - g_return_if_fail (CLUTTER_IS_TABLE_LAYOUT (layout)); - g_return_if_fail (CLUTTER_IS_ACTOR (actor)); - - priv = layout->priv; - - if (priv->container == NULL) - { - g_warning ("The layout of type '%s' must be associated to " - "a ClutterContainer before querying layout " - "properties", - G_OBJECT_TYPE_NAME (layout)); - return; - } - - manager = CLUTTER_LAYOUT_MANAGER (layout); - meta = clutter_layout_manager_get_child_meta (manager, - priv->container, - actor); - if (meta == NULL) - { - g_warning ("No layout meta found for the child of type '%s' " - "inside the layout manager of type '%s'", - G_OBJECT_TYPE_NAME (actor), - G_OBJECT_TYPE_NAME (manager)); - return; - } - - g_assert (CLUTTER_IS_TABLE_CHILD (meta)); - - table_child_set_expand (CLUTTER_TABLE_CHILD (meta), x_expand, y_expand); -} - -/** - * clutter_table_layout_get_expand: - * @layout: a #ClutterTableLayout - * @actor: a #ClutterActor child of @layout - * @x_expand: (out): return location for the horizontal expand policy - * @y_expand: (out): return location for the vertical expand policy - * - * Retrieves the horizontal and vertical expand policies for @actor - * as set using clutter_table_layout_pack() or clutter_table_layout_set_expand() - * - * Since: 1.4 - * - * Deprecated: 1.12: Use clutter_actor_get_x_expand() and - * clutter_actor_get_y_expand() instead. - */ -void -clutter_table_layout_get_expand (ClutterTableLayout *layout, - ClutterActor *actor, - gboolean *x_expand, - gboolean *y_expand) -{ - ClutterTableLayoutPrivate *priv; - ClutterLayoutManager *manager; - ClutterLayoutMeta *meta; - - g_return_if_fail (CLUTTER_IS_TABLE_LAYOUT (layout)); - g_return_if_fail (CLUTTER_IS_ACTOR (actor)); - - priv = layout->priv; - - if (priv->container == NULL) - { - g_warning ("The layout of type '%s' must be associated to " - "a ClutterContainer before querying layout " - "properties", - G_OBJECT_TYPE_NAME (layout)); - return; - } - - manager = CLUTTER_LAYOUT_MANAGER (layout); - meta = clutter_layout_manager_get_child_meta (manager, - priv->container, - actor); - if (meta == NULL) - { - g_warning ("No layout meta found for the child of type '%s' " - "inside the layout manager of type '%s'", - G_OBJECT_TYPE_NAME (actor), - G_OBJECT_TYPE_NAME (manager)); - return; - } - - g_assert (CLUTTER_IS_TABLE_CHILD (meta)); - - if (x_expand) - *x_expand = CLUTTER_TABLE_CHILD (meta)->x_expand; - - if (y_expand) - *y_expand = CLUTTER_TABLE_CHILD (meta)->y_expand; -} - -/** - * clutter_table_layout_set_use_animations: - * @layout: a #ClutterTableLayout - * @animate: %TRUE if the @layout should use animations - * - * Sets whether @layout should animate changes in the layout properties - * - * The duration of the animations is controlled by - * clutter_table_layout_set_easing_duration(); the easing mode to be used - * by the animations is controlled by clutter_table_layout_set_easing_mode() - * - * Since: 1.4 - * - * Deprecated: 1.12: #ClutterTableLayout will honour the easing state - * of the children when allocating them. See clutter_actor_set_easing_mode() - * and clutter_actor_set_easing_duration(). - */ -void -clutter_table_layout_set_use_animations (ClutterTableLayout *layout, - gboolean animate) -{ - ClutterTableLayoutPrivate *priv; - - g_return_if_fail (CLUTTER_IS_TABLE_LAYOUT (layout)); - - priv = layout->priv; - - animate = !!animate; - if (priv->use_animations != animate) - { - priv->use_animations = animate; - - g_object_notify (G_OBJECT (layout), "use-animations"); - } -} - -/** - * clutter_table_layout_get_use_animations: - * @layout: a #ClutterTableLayout - * - * Retrieves whether @layout should animate changes in the layout properties - * - * Since clutter_table_layout_set_use_animations() - * - * Return value: %TRUE if the animations should be used, %FALSE otherwise - * - * Since: 1.4 - * - * Deprecated: 1.12: #ClutterTableLayout will honour the easing state - * of the children when allocating them. See clutter_actor_set_easing_mode() - * and clutter_actor_set_easing_duration(). - */ -gboolean -clutter_table_layout_get_use_animations (ClutterTableLayout *layout) -{ - g_return_val_if_fail (CLUTTER_IS_TABLE_LAYOUT (layout), FALSE); - - return layout->priv->use_animations; -} - -/** - * clutter_table_layout_set_easing_mode: - * @layout: a #ClutterTableLayout - * @mode: an easing mode, either from #ClutterAnimationMode or a logical id - * from clutter_alpha_register_func() - * - * Sets the easing mode to be used by @layout when animating changes in layout - * properties - * - * Use clutter_table_layout_set_use_animations() to enable and disable the - * animations - * - * Since: 1.4 - * - * Deprecated: 1.12: #ClutterTableLayout will honour the easing state - * of the children when allocating them. See clutter_actor_set_easing_mode() - * and clutter_actor_set_easing_duration(). - */ -void -clutter_table_layout_set_easing_mode (ClutterTableLayout *layout, - gulong mode) -{ - ClutterTableLayoutPrivate *priv; - - g_return_if_fail (CLUTTER_IS_TABLE_LAYOUT (layout)); - - priv = layout->priv; - - if (priv->easing_mode != mode) - { - priv->easing_mode = mode; - - g_object_notify (G_OBJECT (layout), "easing-mode"); - } -} - -/** - * clutter_table_layout_get_easing_mode: - * @layout: a #ClutterTableLayout - * - * Retrieves the easing mode set using clutter_table_layout_set_easing_mode() - * - * Return value: an easing mode - * - * Since: 1.4 - * - * Deprecated: 1.12: #ClutterTableLayout will honour the easing state - * of the children when allocating them. See clutter_actor_set_easing_mode() - * and clutter_actor_set_easing_duration(). - */ -gulong -clutter_table_layout_get_easing_mode (ClutterTableLayout *layout) -{ - g_return_val_if_fail (CLUTTER_IS_TABLE_LAYOUT (layout), - CLUTTER_EASE_OUT_CUBIC); - - return layout->priv->easing_mode; -} - -/** - * clutter_table_layout_set_easing_duration: - * @layout: a #ClutterTableLayout - * @msecs: the duration of the animations, in milliseconds - * - * Sets the duration of the animations used by @layout when animating changes - * in the layout properties - * - * Use clutter_table_layout_set_use_animations() to enable and disable the - * animations - * - * Since: 1.4 - * - * Deprecated: 1.12: #ClutterTableLayout will honour the easing state - * of the children when allocating them. See clutter_actor_set_easing_mode() - * and clutter_actor_set_easing_duration(). - */ -void -clutter_table_layout_set_easing_duration (ClutterTableLayout *layout, - guint msecs) -{ - ClutterTableLayoutPrivate *priv; - - g_return_if_fail (CLUTTER_IS_TABLE_LAYOUT (layout)); - - priv = layout->priv; - - if (priv->easing_duration != msecs) - { - priv->easing_duration = msecs; - - g_object_notify (G_OBJECT (layout), "easing-duration"); - } -} - -/** - * clutter_table_layout_get_easing_duration: - * @layout: a #ClutterTableLayout - * - * Retrieves the duration set using clutter_table_layout_set_easing_duration() - * - * Return value: the duration of the animations, in milliseconds - * - * Since: 1.4 - * - * Deprecated: 1.12: #ClutterTableLayout will honour the easing state - * of the children when allocating them. See clutter_actor_set_easing_mode() - * and clutter_actor_set_easing_duration(). - */ -guint -clutter_table_layout_get_easing_duration (ClutterTableLayout *layout) -{ - g_return_val_if_fail (CLUTTER_IS_TABLE_LAYOUT (layout), 500); - - return layout->priv->easing_duration; -} - - -/** - * clutter_table_layout_get_row_count: - * @layout: A #ClutterTableLayout - * - * Retrieve the current number rows in the @layout - * - * Returns: the number of rows - * - * Since: 1.4 - * - * Deprecated: 1.18: No direct replacement is available - */ -gint -clutter_table_layout_get_row_count (ClutterTableLayout *layout) -{ - g_return_val_if_fail (CLUTTER_IS_TABLE_LAYOUT (layout), -1); - - update_row_col (layout, layout->priv->container); - return CLUTTER_TABLE_LAYOUT (layout)->priv->n_rows; -} - -/** - * clutter_table_layout_get_column_count: - * @layout: A #ClutterTableLayout - * - * Retrieve the current number of columns in @layout - * - * Returns: the number of columns - * - * Since: 1.4 - * - * Deprecated: 1.18: No direct replacement is available - */ -gint -clutter_table_layout_get_column_count (ClutterTableLayout *layout) -{ - g_return_val_if_fail (CLUTTER_IS_TABLE_LAYOUT (layout), -1); - - update_row_col (layout, layout->priv->container); - return CLUTTER_TABLE_LAYOUT (layout)->priv->n_cols; -} diff --git a/clutter/clutter/deprecated/clutter-table-layout.h b/clutter/clutter/deprecated/clutter-table-layout.h deleted file mode 100644 index dffbfb777..000000000 --- a/clutter/clutter/deprecated/clutter-table-layout.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Jose Dapena Paz - * - * Based on the MX MxTable actor by: - * Thomas Wood - */ - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __CLUTTER_TABLE_LAYOUT_H__ -#define __CLUTTER_TABLE_LAYOUT_H__ - -#include - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_TABLE_LAYOUT (clutter_table_layout_get_type ()) -#define CLUTTER_TABLE_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_TABLE_LAYOUT, ClutterTableLayout)) -#define CLUTTER_IS_TABLE_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_TABLE_LAYOUT)) -#define CLUTTER_TABLE_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_TABLE_LAYOUT, ClutterTableLayoutClass)) -#define CLUTTER_IS_TABLE_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_TABLE_LAYOUT)) -#define CLUTTER_TABLE_LAYOUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_TABLE_LAYOUT, ClutterTableLayoutClass)) - -typedef struct _ClutterTableLayout ClutterTableLayout; -typedef struct _ClutterTableLayoutPrivate ClutterTableLayoutPrivate; -typedef struct _ClutterTableLayoutClass ClutterTableLayoutClass; - -/** - * ClutterTableLayout: - * - * The #ClutterTableLayout structure contains only private data - * and should be accessed using the provided API - * - * Since: 1.4 - * - * Deprecated: 1.18: Use #ClutterGridLayout instead - */ -struct _ClutterTableLayout -{ - /*< private >*/ - ClutterLayoutManager parent_instance; - - ClutterTableLayoutPrivate *priv; -}; - -/** - * ClutterTableLayoutClass: - * - * The #ClutterTableLayoutClass structure contains only private - * data and should be accessed using the provided API - * - * Since: 1.4 - * - * Deprecated: 1.18: Use #ClutterGridLayout instead - */ -struct _ClutterTableLayoutClass -{ - /*< private >*/ - ClutterLayoutManagerClass parent_class; -}; - -CLUTTER_DEPRECATED_IN_1_18_FOR (clutter_grid_layout_get_type) -GType clutter_table_layout_get_type (void) G_GNUC_CONST; - -CLUTTER_DEPRECATED_IN_1_18_FOR (clutter_grid_layout_new) -ClutterLayoutManager *clutter_table_layout_new (void); - -CLUTTER_DEPRECATED_IN_1_18_FOR (clutter_grid_layout_attach) -void clutter_table_layout_pack (ClutterTableLayout *layout, - ClutterActor *actor, - gint column, - gint row); - -CLUTTER_DEPRECATED_IN_1_18_FOR (clutter_grid_layout_set_column_spacing) -void clutter_table_layout_set_column_spacing (ClutterTableLayout *layout, - guint spacing); -CLUTTER_DEPRECATED_IN_1_18_FOR (clutter_grid_layout_set_row_spacing) -void clutter_table_layout_set_row_spacing (ClutterTableLayout *layout, - guint spacing); -CLUTTER_DEPRECATED_IN_1_18_FOR (clutter_grid_layout_get_column_spacing) -guint clutter_table_layout_get_column_spacing (ClutterTableLayout *layout); -CLUTTER_DEPRECATED_IN_1_18_FOR (clutter_grid_layout_get_row_spacing) -guint clutter_table_layout_get_row_spacing (ClutterTableLayout *layout); - -CLUTTER_DEPRECATED_IN_1_18 -void clutter_table_layout_set_span (ClutterTableLayout *layout, - ClutterActor *actor, - gint column_span, - gint row_span); -CLUTTER_DEPRECATED_IN_1_18 -void clutter_table_layout_get_span (ClutterTableLayout *layout, - ClutterActor *actor, - gint *column_span, - gint *row_span); - -CLUTTER_DEPRECATED_IN_1_12 -void clutter_table_layout_set_alignment (ClutterTableLayout *layout, - ClutterActor *actor, - ClutterTableAlignment x_align, - ClutterTableAlignment y_align); -CLUTTER_DEPRECATED_IN_1_12 -void clutter_table_layout_get_alignment (ClutterTableLayout *layout, - ClutterActor *actor, - ClutterTableAlignment *x_align, - ClutterTableAlignment *y_align); -CLUTTER_DEPRECATED_IN_1_12 -void clutter_table_layout_set_fill (ClutterTableLayout *layout, - ClutterActor *actor, - gboolean x_fill, - gboolean y_fill); -CLUTTER_DEPRECATED_IN_1_12 -void clutter_table_layout_get_fill (ClutterTableLayout *layout, - ClutterActor *actor, - gboolean *x_fill, - gboolean *y_fill); -CLUTTER_DEPRECATED_IN_1_12 -void clutter_table_layout_set_expand (ClutterTableLayout *layout, - ClutterActor *actor, - gboolean x_expand, - gboolean y_expand); -CLUTTER_DEPRECATED_IN_1_12 -void clutter_table_layout_get_expand (ClutterTableLayout *layout, - ClutterActor *actor, - gboolean *x_expand, - gboolean *y_expand); - -CLUTTER_DEPRECATED_IN_1_18 -gint clutter_table_layout_get_row_count (ClutterTableLayout *layout); -CLUTTER_DEPRECATED_IN_1_18 -gint clutter_table_layout_get_column_count (ClutterTableLayout *layout); - -CLUTTER_DEPRECATED_IN_1_12 -void clutter_table_layout_set_use_animations (ClutterTableLayout *layout, - gboolean animate); -CLUTTER_DEPRECATED_IN_1_12 -gboolean clutter_table_layout_get_use_animations (ClutterTableLayout *layout); -CLUTTER_DEPRECATED_IN_1_12 -void clutter_table_layout_set_easing_mode (ClutterTableLayout *layout, - gulong mode); -CLUTTER_DEPRECATED_IN_1_12 -gulong clutter_table_layout_get_easing_mode (ClutterTableLayout *layout); -CLUTTER_DEPRECATED_IN_1_12 -void clutter_table_layout_set_easing_duration (ClutterTableLayout *layout, - guint msecs); -CLUTTER_DEPRECATED_IN_1_12 -guint clutter_table_layout_get_easing_duration (ClutterTableLayout *layout); - -G_END_DECLS - -#endif /* __CLUTTER_TABLE_LAYOUT_H__ */ diff --git a/clutter/clutter/deprecated/clutter-texture.c b/clutter/clutter/deprecated/clutter-texture.c deleted file mode 100644 index 3456731e8..000000000 --- a/clutter/clutter/deprecated/clutter-texture.c +++ /dev/null @@ -1,3106 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * Copyright (C) 2006 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -/** - * SECTION:clutter-texture - * @short_description: An actor for displaying and manipulating images. - * - * #ClutterTexture is a base class for displaying and manipulating pixel - * buffer type data. - * - * The clutter_texture_set_from_rgb_data() and - * clutter_texture_set_from_file() functions are used to copy image - * data into texture memory and subsequently realize the texture. - * - * Note: a ClutterTexture will scale its contents to fit the bounding - * box requested using clutter_actor_set_size(). To display an area of - * a texture without scaling, you should set the clip area using - * clutter_actor_set_clip(). - * - * The #ClutterTexture API is deprecated since Clutter 1.12. It is strongly - * recommended to use #ClutterImage instead. - */ - -#ifdef HAVE_CONFIG_H -#include "clutter-build-config.h" -#endif - -/* sadly, we are still using ClutterShader internally */ -#define CLUTTER_DISABLE_DEPRECATION_WARNINGS - -#include - -#include "clutter-texture.h" - -#include "clutter-actor-private.h" -#include "clutter-color.h" -#include "clutter-debug.h" -#include "clutter-enum-types.h" -#include "clutter-feature.h" -#include "clutter-main.h" -#include "clutter-marshal.h" -#include "clutter-private.h" -#include "clutter-scriptable.h" -#include "clutter-stage-private.h" -#include "clutter-backend.h" - -#include "deprecated/clutter-shader.h" -#include "deprecated/clutter-texture.h" -#include "deprecated/clutter-util.h" - -typedef struct _ClutterTextureAsyncData ClutterTextureAsyncData; - -struct _ClutterTexturePrivate -{ - gint image_width; - gint image_height; - - CoglPipeline *pipeline; - - ClutterActor *fbo_source; - CoglHandle fbo_handle; - - CoglPipeline *pick_pipeline; - - gchar *filename; - - ClutterTextureAsyncData *async_data; - - guint no_slice : 1; - guint sync_actor_size : 1; - guint repeat_x : 1; - guint repeat_y : 1; - guint keep_aspect_ratio : 1; - guint load_size_async : 1; - guint load_data_async : 1; - guint load_async_set : 1; /* used to make load_async possible */ - guint pick_with_alpha : 1; - guint pick_with_alpha_supported : 1; - guint seen_create_pick_pipeline_warning : 1; -}; - -#define ASYNC_STATE_LOCKED 1 -#define ASYNC_STATE_CANCELLED 2 -#define ASYNC_STATE_QUEUED 3 - -struct _ClutterTextureAsyncData -{ - /* The texture for which the data is being loaded */ - ClutterTexture *texture; - - gchar *load_filename; - CoglHandle load_bitmap; - - guint load_idle; - - GError *load_error; - - gint state; -}; - -static inline void -clutter_texture_async_data_lock (ClutterTextureAsyncData *data) -{ - g_bit_lock (&data->state, 0); -} - -static inline void -clutter_texture_async_data_unlock (ClutterTextureAsyncData *data) -{ - g_bit_unlock (&data->state, 0); -} - -enum -{ - PROP_0, - PROP_NO_SLICE, - PROP_MAX_TILE_WASTE, - PROP_SYNC_SIZE, - PROP_REPEAT_Y, - PROP_REPEAT_X, - PROP_FILTER_QUALITY, - PROP_COGL_TEXTURE, - PROP_COGL_MATERIAL, - PROP_FILENAME, - PROP_KEEP_ASPECT_RATIO, - PROP_LOAD_ASYNC, - PROP_LOAD_DATA_ASYNC, - PROP_PICK_WITH_ALPHA, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST]; - -enum -{ - SIZE_CHANGE, - PIXBUF_CHANGE, - LOAD_SUCCESS, - LOAD_FINISHED, - LAST_SIGNAL -}; - -static int texture_signals[LAST_SIGNAL] = { 0 }; - -static GThreadPool *async_thread_pool = NULL; -static guint repaint_upload_func = 0; -static GList *upload_list = NULL; -static GMutex upload_list_mutex; - -static CoglPipeline *texture_template_pipeline = NULL; - -static void -texture_fbo_free_resources (ClutterTexture *texture); - -static void clutter_scriptable_iface_init (ClutterScriptableIface *iface); - -G_DEFINE_TYPE_WITH_CODE (ClutterTexture, - clutter_texture, - CLUTTER_TYPE_ACTOR, - G_ADD_PRIVATE (ClutterTexture) - G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_SCRIPTABLE, - clutter_scriptable_iface_init)); - - -GQuark -clutter_texture_error_quark (void) -{ - return g_quark_from_static_string ("clutter-texture-error-quark"); -} - -static const struct -{ - gint min_filter; - gint mag_filter; -} -clutter_texture_quality_filters[] = - { - /* CLUTTER_TEXTURE_QUALITY_LOW */ - { COGL_PIPELINE_FILTER_NEAREST, COGL_PIPELINE_FILTER_NEAREST }, - - /* CLUTTER_TEXTURE_QUALITY_MEDIUM */ - { COGL_PIPELINE_FILTER_LINEAR, COGL_PIPELINE_FILTER_LINEAR }, - - /* CLUTTER_TEXTURE_QUALITY_HIGH */ - { COGL_PIPELINE_FILTER_LINEAR_MIPMAP_LINEAR, COGL_PIPELINE_FILTER_LINEAR } - }; - -static inline void -clutter_texture_quality_to_filters (ClutterTextureQuality quality, - gint *min_filter_p, - gint *mag_filter_p) -{ - g_return_if_fail (quality < G_N_ELEMENTS (clutter_texture_quality_filters)); - - if (min_filter_p) - *min_filter_p = clutter_texture_quality_filters[quality].min_filter; - - if (mag_filter_p) - *mag_filter_p = clutter_texture_quality_filters[quality].mag_filter; -} - -static void -texture_free_gl_resources (ClutterTexture *texture) -{ - ClutterTexturePrivate *priv = texture->priv; - - if (priv->pipeline != NULL) - { - /* We want to keep the layer so that the filter settings will - remain but we want to free its resources so we clear the - texture handle */ - cogl_pipeline_set_layer_texture (priv->pipeline, 0, NULL); - } -} - -static void -clutter_texture_unrealize (ClutterActor *actor) -{ - ClutterTexture *texture; - ClutterTexturePrivate *priv; - - texture = CLUTTER_TEXTURE(actor); - priv = texture->priv; - - if (priv->pipeline == NULL) - return; - - if (priv->fbo_source != NULL) - { - /* Free up our fbo handle and texture resources, realize will recreate */ - cogl_object_unref (priv->fbo_handle); - priv->fbo_handle = NULL; - texture_free_gl_resources (texture); - return; - } - - CLUTTER_NOTE (TEXTURE, "Texture unrealized"); -} - -static void -clutter_texture_realize (ClutterActor *actor) -{ - ClutterTexture *texture; - ClutterTexturePrivate *priv; - - texture = CLUTTER_TEXTURE(actor); - priv = texture->priv; - - if (priv->fbo_source) - { - CoglTextureFlags flags = COGL_TEXTURE_NONE; - CoglHandle tex; - - /* Handle FBO's */ - - if (priv->no_slice) - flags |= COGL_TEXTURE_NO_SLICING; - - tex = cogl_texture_new_with_size (priv->image_width, - priv->image_height, - flags, - COGL_PIXEL_FORMAT_RGBA_8888_PRE); - - cogl_pipeline_set_layer_texture (priv->pipeline, 0, tex); - - priv->fbo_handle = cogl_offscreen_new_to_texture (tex); - - /* The pipeline now has a reference to the texture so it will - stick around */ - cogl_object_unref (tex); - - if (priv->fbo_handle == NULL) - { - g_warning ("%s: Offscreen texture creation failed", G_STRLOC); - CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED); - return; - } - - clutter_actor_set_size (actor, priv->image_width, priv->image_height); - - return; - } - - /* If the texture is not a FBO, then realization is a no-op but we - * still want to be in REALIZED state to maintain invariants. - * ClutterTexture doesn't need to be realized to have a Cogl texture - * because Clutter assumes that a GL context is always current so - * there is no need to wait to realization time to create the - * texture. Although this is slightly odd it would be wasteful to - * redundantly store a copy of the texture data in local memory just - * so that we can make a texture during realize. - */ - - CLUTTER_NOTE (TEXTURE, "Texture realized"); -} - -static void -clutter_texture_get_preferred_width (ClutterActor *self, - gfloat for_height, - gfloat *min_width_p, - gfloat *natural_width_p) -{ - ClutterTexture *texture = CLUTTER_TEXTURE (self); - ClutterTexturePrivate *priv = texture->priv; - - /* Min request is always 0 since we can scale down or clip */ - if (min_width_p) - *min_width_p = 0; - - if (priv->sync_actor_size) - { - if (natural_width_p) - { - if (!priv->keep_aspect_ratio || - for_height < 0 || - priv->image_height <= 0) - { - *natural_width_p = priv->image_width; - } - else - { - /* Set the natural width so as to preserve the aspect ratio */ - gfloat ratio = (gfloat) priv->image_width - / (gfloat) priv->image_height; - - *natural_width_p = ratio * for_height; - } - } - } - else - { - if (natural_width_p) - *natural_width_p = 0; - } -} - -static void -clutter_texture_get_preferred_height (ClutterActor *self, - gfloat for_width, - gfloat *min_height_p, - gfloat *natural_height_p) -{ - ClutterTexture *texture = CLUTTER_TEXTURE (self); - ClutterTexturePrivate *priv = texture->priv; - - /* Min request is always 0 since we can scale down or clip */ - if (min_height_p) - *min_height_p = 0; - - if (priv->sync_actor_size) - { - if (natural_height_p) - { - if (!priv->keep_aspect_ratio || - for_width < 0 || - priv->image_width <= 0) - { - *natural_height_p = priv->image_height; - } - else - { - /* Set the natural height so as to preserve the aspect ratio */ - gfloat ratio = (gfloat) priv->image_height - / (gfloat) priv->image_width; - - *natural_height_p = ratio * for_width; - } - } - } - else - { - if (natural_height_p) - *natural_height_p = 0; - } -} - -static void -clutter_texture_allocate (ClutterActor *self, - const ClutterActorBox *box, - ClutterAllocationFlags flags) -{ - ClutterTexturePrivate *priv = CLUTTER_TEXTURE (self)->priv; - - /* chain up to set actor->allocation */ - CLUTTER_ACTOR_CLASS (clutter_texture_parent_class)->allocate (self, - box, - flags); - - /* If we adopted the source fbo then allocate that at its preferred - size */ - if (priv->fbo_source && clutter_actor_get_parent (priv->fbo_source) == self) - clutter_actor_allocate_preferred_size (priv->fbo_source, flags); -} - -static gboolean -clutter_texture_has_overlaps (ClutterActor *self) -{ - /* Textures never need an offscreen redirect because there are never - any overlapping primitives */ - return FALSE; -} - -static void -set_viewport_with_buffer_under_fbo_source (ClutterActor *fbo_source, - int viewport_width, - int viewport_height) -{ - ClutterActorBox box = { 0, }; - float x_offset, y_offset; - - if (clutter_actor_get_paint_box (fbo_source, &box)) - clutter_actor_box_get_origin (&box, &x_offset, &y_offset); - else - { - /* As a fallback when the paint box can't be determined we use - * the transformed allocation to come up with an offset instead. - * - * FIXME: when we don't have a paint box we should instead be - * falling back to a stage sized fbo with an offset of (0,0) - */ - - ClutterVertex verts[4]; - float x_min = G_MAXFLOAT, y_min = G_MAXFLOAT; - int i; - - /* Get the actors allocation transformed into screen coordinates. - * - * XXX: Note: this may not be a bounding box for the actor, since an - * actor with depth may escape the box due to its perspective - * projection. */ - clutter_actor_get_abs_allocation_vertices (fbo_source, verts); - - for (i = 0; i < G_N_ELEMENTS (verts); ++i) - { - if (verts[i].x < x_min) - x_min = verts[i].x; - if (verts[i].y < y_min) - y_min = verts[i].y; - } - - /* XXX: It's not good enough to round by simply truncating the fraction here - * via a cast, as it results in offscreen rendering being offset by 1 pixel - * in many cases... */ -#define ROUND(x) ((x) >= 0 ? (long)((x) + 0.5) : (long)((x) - 0.5)) - - x_offset = ROUND (x_min); - y_offset = ROUND (y_min); - -#undef ROUND - } - - /* translate the viewport so that the source actor lands on the - * sub-region backed by the offscreen framebuffer... */ - cogl_set_viewport (-x_offset, -y_offset, viewport_width, viewport_height); -} - -static void -update_fbo (ClutterActor *self) -{ - ClutterTexture *texture = CLUTTER_TEXTURE (self); - ClutterTexturePrivate *priv = texture->priv; - ClutterActor *head; - ClutterShader *shader = NULL; - ClutterActor *stage = NULL; - CoglMatrix projection; - CoglColor transparent_col; - - head = _clutter_context_peek_shader_stack (); - if (head != NULL) - shader = clutter_actor_get_shader (head); - - /* Temporarily turn off the shader on the top of the context's - * shader stack, to restore the GL pipeline to it's natural state. - */ - if (shader != NULL) - clutter_shader_set_is_enabled (shader, FALSE); - - /* Redirect drawing to the fbo */ - cogl_push_framebuffer (priv->fbo_handle); - - if ((stage = clutter_actor_get_stage (self)) != NULL) - { - gfloat stage_width, stage_height; - ClutterActor *source_parent; - - /* We copy the projection and modelview matrices from the stage to - * the offscreen framebuffer and create a viewport larger than the - * offscreen framebuffer - the same size as the stage. - * - * The fbo source actor gets rendered into this stage size viewport at the - * same position it normally would after applying all it's usual parent - * transforms and it's own scale and rotate transforms etc. - * - * The viewport is offset such that the offscreen buffer will be positioned - * under the actor. - */ - - _clutter_stage_get_projection_matrix (CLUTTER_STAGE (stage), &projection); - - /* Set the projection matrix modelview matrix as it is for the - * stage... */ - cogl_set_projection_matrix (&projection); - - clutter_actor_get_size (stage, &stage_width, &stage_height); - - /* Set a negatively offset the viewport so that the offscreen - * framebuffer is position underneath the fbo_source actor... */ - set_viewport_with_buffer_under_fbo_source (priv->fbo_source, - stage_width, - stage_height); - - /* Apply the source's parent transformations to the modelview */ - if ((source_parent = clutter_actor_get_parent (priv->fbo_source))) - { - CoglMatrix modelview; - cogl_matrix_init_identity (&modelview); - _clutter_actor_apply_relative_transformation_matrix (source_parent, - NULL, - &modelview); - cogl_set_modelview_matrix (&modelview); - } - } - - - /* cogl_clear is called to clear the buffers */ - cogl_color_init_from_4ub (&transparent_col, 0, 0, 0, 0); - cogl_clear (&transparent_col, - COGL_BUFFER_BIT_COLOR | - COGL_BUFFER_BIT_DEPTH); - - /* Render the actor to the fbo */ - clutter_actor_paint (priv->fbo_source); - - /* Restore drawing to the previous framebuffer */ - cogl_pop_framebuffer (); - - /* If there is a shader on top of the shader stack, turn it back on. */ - if (shader != NULL) - clutter_shader_set_is_enabled (shader, TRUE); -} - -static void -gen_texcoords_and_draw_cogl_rectangle (ClutterActor *self) -{ - ClutterTexture *texture = CLUTTER_TEXTURE (self); - ClutterTexturePrivate *priv = texture->priv; - ClutterActorBox box; - float t_w, t_h; - - clutter_actor_get_allocation_box (self, &box); - - if (priv->repeat_x && priv->image_width > 0) - t_w = (box.x2 - box.x1) / (float) priv->image_width; - else - t_w = 1.0; - - if (priv->repeat_y && priv->image_height > 0) - t_h = (box.y2 - box.y1) / (float) priv->image_height; - else - t_h = 1.0; - - cogl_rectangle_with_texture_coords (0, 0, - box.x2 - box.x1, - box.y2 - box.y1, - 0, 0, t_w, t_h); -} - -static CoglPipeline * -create_pick_pipeline (ClutterActor *self) -{ - ClutterTexture *texture = CLUTTER_TEXTURE (self); - ClutterTexturePrivate *priv = texture->priv; - CoglPipeline *pick_pipeline = cogl_pipeline_copy (texture_template_pipeline); - GError *error = NULL; - - if (!cogl_pipeline_set_layer_combine (pick_pipeline, 0, - "RGBA = " - " MODULATE (CONSTANT, TEXTURE[A])", - &error)) - { - if (!priv->seen_create_pick_pipeline_warning) - g_warning ("Error setting up texture combine for shaped " - "texture picking: %s", error->message); - priv->seen_create_pick_pipeline_warning = TRUE; - g_error_free (error); - cogl_object_unref (pick_pipeline); - return NULL; - } - - cogl_pipeline_set_blend (pick_pipeline, - "RGBA = ADD (SRC_COLOR[RGBA], 0)", - NULL); - - cogl_pipeline_set_alpha_test_function (pick_pipeline, - COGL_PIPELINE_ALPHA_FUNC_EQUAL, - 1.0); - - return pick_pipeline; -} - -static void -clutter_texture_pick (ClutterActor *self, - const ClutterColor *color) -{ - ClutterTexture *texture = CLUTTER_TEXTURE (self); - ClutterTexturePrivate *priv = texture->priv; - - if (!clutter_actor_should_pick_paint (self)) - return; - - if (G_LIKELY (priv->pick_with_alpha_supported) && priv->pick_with_alpha) - { - CoglColor pick_color; - - if (priv->pick_pipeline == NULL) - priv->pick_pipeline = create_pick_pipeline (self); - - if (priv->pick_pipeline == NULL) - { - priv->pick_with_alpha_supported = FALSE; - CLUTTER_ACTOR_CLASS (clutter_texture_parent_class)->pick (self, - color); - return; - } - - if (priv->fbo_handle != NULL) - update_fbo (self); - - cogl_color_init_from_4ub (&pick_color, - color->red, - color->green, - color->blue, - 0xff); - cogl_pipeline_set_layer_combine_constant (priv->pick_pipeline, - 0, &pick_color); - cogl_pipeline_set_layer_texture (priv->pick_pipeline, 0, - clutter_texture_get_cogl_texture (texture)); - cogl_set_source (priv->pick_pipeline); - gen_texcoords_and_draw_cogl_rectangle (self); - } - else - CLUTTER_ACTOR_CLASS (clutter_texture_parent_class)->pick (self, color); -} - -static void -clutter_texture_paint (ClutterActor *self) -{ - ClutterTexture *texture = CLUTTER_TEXTURE (self); - ClutterTexturePrivate *priv = texture->priv; - guint8 paint_opacity = clutter_actor_get_paint_opacity (self); - - CLUTTER_NOTE (PAINT, - "painting texture '%s'", - clutter_actor_get_name (self) ? clutter_actor_get_name (self) - : "unknown"); - - if (priv->fbo_handle != NULL) - update_fbo (self); - - cogl_pipeline_set_color4ub (priv->pipeline, - paint_opacity, - paint_opacity, - paint_opacity, - paint_opacity); - cogl_set_source (priv->pipeline); - - gen_texcoords_and_draw_cogl_rectangle (self); -} - -static gboolean -clutter_texture_get_paint_volume (ClutterActor *self, - ClutterPaintVolume *volume) -{ - ClutterTexturePrivate *priv; - - priv = CLUTTER_TEXTURE (self)->priv; - - if (priv->pipeline == NULL) - return FALSE; - - if (priv->image_width == 0 || priv->image_height == 0) - return FALSE; - - return _clutter_actor_set_default_paint_volume (self, - CLUTTER_TYPE_TEXTURE, - volume); -} - -static void -clutter_texture_async_data_free (ClutterTextureAsyncData *data) -{ - /* This function should only be called either from the main thread - once it is known that the load thread has completed or from the - load thread/upload function itself if the abort flag is true (in - which case the main thread has disowned the data) */ - free (data->load_filename); - - if (data->load_bitmap != NULL) - cogl_object_unref (data->load_bitmap); - - if (data->load_error != NULL) - g_error_free (data->load_error); - - g_slice_free (ClutterTextureAsyncData, data); -} - -/* - * clutter_texture_async_load_cancel: - * @texture: a #ClutterTexture - * - * Cancels an asynchronous loading operation, whether done - * with threads enabled or just using the main loop - */ -static void -clutter_texture_async_load_cancel (ClutterTexture *texture) -{ - ClutterTexturePrivate *priv = texture->priv; - - if (priv->async_data != NULL) - { - ClutterTextureAsyncData *async_data = priv->async_data; - - priv->async_data = NULL; - - if (async_data->load_idle != 0) - { - g_source_remove (async_data->load_idle); - async_data->load_idle = 0; - - clutter_texture_async_data_free (async_data); - } - else - { - clutter_texture_async_data_lock (async_data); - - CLUTTER_NOTE (TEXTURE, "[async] cancelling operation for '%s'", - async_data->load_filename); - - async_data->state |= ASYNC_STATE_CANCELLED; - - clutter_texture_async_data_unlock (async_data); - } - } -} - -static void -clutter_texture_dispose (GObject *object) -{ - ClutterTexture *texture = CLUTTER_TEXTURE (object); - ClutterTexturePrivate *priv = texture->priv; - - texture_free_gl_resources (texture); - texture_fbo_free_resources (texture); - - clutter_texture_async_load_cancel (texture); - - if (priv->pipeline != NULL) - { - cogl_object_unref (priv->pipeline); - priv->pipeline = NULL; - } - - if (priv->pick_pipeline != NULL) - { - cogl_object_unref (priv->pick_pipeline); - priv->pick_pipeline = NULL; - } - - G_OBJECT_CLASS (clutter_texture_parent_class)->dispose (object); -} - -static void -clutter_texture_finalize (GObject *object) -{ - ClutterTexturePrivate *priv = CLUTTER_TEXTURE (object)->priv; - - free (priv->filename); - - G_OBJECT_CLASS (clutter_texture_parent_class)->finalize (object); -} - -static void -clutter_texture_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterTexture *texture; - ClutterTexturePrivate *priv; - - texture = CLUTTER_TEXTURE (object); - priv = texture->priv; - - switch (prop_id) - { - case PROP_SYNC_SIZE: - clutter_texture_set_sync_size (texture, g_value_get_boolean (value)); - break; - - case PROP_REPEAT_X: - clutter_texture_set_repeat (texture, - g_value_get_boolean (value), - priv->repeat_y); - break; - - case PROP_REPEAT_Y: - clutter_texture_set_repeat (texture, - priv->repeat_x, - g_value_get_boolean (value)); - break; - - case PROP_FILTER_QUALITY: - clutter_texture_set_filter_quality (texture, - g_value_get_enum (value)); - break; - - case PROP_COGL_TEXTURE: - { - CoglHandle hnd = g_value_get_boxed (value); - - clutter_texture_set_cogl_texture (texture, hnd); - } - break; - - case PROP_COGL_MATERIAL: - { - CoglHandle hnd = g_value_get_boxed (value); - - clutter_texture_set_cogl_material (texture, hnd); - } - break; - - case PROP_FILENAME: - clutter_texture_set_from_file (texture, - g_value_get_string (value), - NULL); - break; - - case PROP_NO_SLICE: - priv->no_slice = g_value_get_boolean (value); - break; - - case PROP_KEEP_ASPECT_RATIO: - clutter_texture_set_keep_aspect_ratio (texture, - g_value_get_boolean (value)); - break; - - case PROP_LOAD_DATA_ASYNC: - clutter_texture_set_load_data_async (texture, - g_value_get_boolean (value)); - break; - - case PROP_LOAD_ASYNC: - clutter_texture_set_load_async (texture, g_value_get_boolean (value)); - break; - - case PROP_PICK_WITH_ALPHA: - clutter_texture_set_pick_with_alpha (texture, - g_value_get_boolean (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -clutter_texture_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterTexture *texture; - ClutterTexturePrivate *priv; - - texture = CLUTTER_TEXTURE(object); - priv = texture->priv; - - switch (prop_id) - { - case PROP_MAX_TILE_WASTE: - g_value_set_int (value, clutter_texture_get_max_tile_waste (texture)); - break; - - case PROP_SYNC_SIZE: - g_value_set_boolean (value, priv->sync_actor_size); - break; - - case PROP_REPEAT_X: - g_value_set_boolean (value, priv->repeat_x); - break; - - case PROP_REPEAT_Y: - g_value_set_boolean (value, priv->repeat_y); - break; - - case PROP_FILTER_QUALITY: - g_value_set_enum (value, clutter_texture_get_filter_quality (texture)); - break; - - case PROP_COGL_TEXTURE: - g_value_set_boxed (value, clutter_texture_get_cogl_texture (texture)); - break; - - case PROP_COGL_MATERIAL: - g_value_set_boxed (value, clutter_texture_get_cogl_material (texture)); - break; - - case PROP_NO_SLICE: - g_value_set_boolean (value, priv->no_slice); - break; - - case PROP_KEEP_ASPECT_RATIO: - g_value_set_boolean (value, priv->keep_aspect_ratio); - break; - - case PROP_PICK_WITH_ALPHA: - g_value_set_boolean (value, priv->pick_with_alpha); - break; - - case PROP_FILENAME: - g_value_set_string (value, priv->filename); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -clutter_texture_class_init (ClutterTextureClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); - GParamSpec *pspec; - - actor_class->paint = clutter_texture_paint; - actor_class->pick = clutter_texture_pick; - actor_class->get_paint_volume = clutter_texture_get_paint_volume; - actor_class->realize = clutter_texture_realize; - actor_class->unrealize = clutter_texture_unrealize; - actor_class->has_overlaps = clutter_texture_has_overlaps; - - actor_class->get_preferred_width = clutter_texture_get_preferred_width; - actor_class->get_preferred_height = clutter_texture_get_preferred_height; - actor_class->allocate = clutter_texture_allocate; - - gobject_class->dispose = clutter_texture_dispose; - gobject_class->finalize = clutter_texture_finalize; - gobject_class->set_property = clutter_texture_set_property; - gobject_class->get_property = clutter_texture_get_property; - - pspec = g_param_spec_boolean ("sync-size", - P_("Sync size of actor"), - P_("Auto sync size of actor to underlying pixbuf dimensions"), - TRUE, - CLUTTER_PARAM_READWRITE); - obj_props[PROP_SYNC_SIZE] = pspec; - g_object_class_install_property (gobject_class, PROP_SYNC_SIZE, pspec); - - pspec = g_param_spec_boolean ("disable-slicing", - P_("Disable Slicing"), - P_("Forces the underlying texture to be singular and not made of smaller space saving " - "individual textures"), - FALSE, - G_PARAM_CONSTRUCT_ONLY | - CLUTTER_PARAM_READWRITE); - obj_props[PROP_NO_SLICE] = pspec; - g_object_class_install_property (gobject_class, PROP_NO_SLICE, pspec); - - pspec = g_param_spec_int ("tile-waste", - P_("Tile Waste"), - P_("Maximum waste area of a sliced texture"), - -1, G_MAXINT, - COGL_TEXTURE_MAX_WASTE, - CLUTTER_PARAM_READABLE); - obj_props[PROP_MAX_TILE_WASTE] = pspec; - g_object_class_install_property (gobject_class, PROP_MAX_TILE_WASTE, pspec); - - pspec = g_param_spec_boolean ("repeat-x", - P_("Horizontal repeat"), - P_("Repeat the contents rather than scaling them horizontally"), - FALSE, - CLUTTER_PARAM_READWRITE); - obj_props[PROP_REPEAT_X] = pspec; - g_object_class_install_property (gobject_class, PROP_REPEAT_X, pspec); - - pspec = g_param_spec_boolean ("repeat-y", - P_("Vertical repeat"), - P_("Repeat the contents rather than scaling them vertically"), - FALSE, - CLUTTER_PARAM_READWRITE); - obj_props[PROP_REPEAT_Y] = pspec; - g_object_class_install_property (gobject_class, PROP_REPEAT_Y, pspec); - - pspec = g_param_spec_enum ("filter-quality", - P_("Filter Quality"), - P_("Rendering quality used when drawing the texture"), - CLUTTER_TYPE_TEXTURE_QUALITY, - CLUTTER_TEXTURE_QUALITY_MEDIUM, - G_PARAM_CONSTRUCT | CLUTTER_PARAM_READWRITE); - obj_props[PROP_FILTER_QUALITY] = pspec; - g_object_class_install_property (gobject_class, PROP_FILTER_QUALITY, pspec); - - pspec = g_param_spec_boxed ("cogl-texture", - P_("Cogl Texture"), - P_("The underlying Cogl texture handle used to draw this actor"), - COGL_TYPE_HANDLE, - CLUTTER_PARAM_READWRITE); - obj_props[PROP_COGL_TEXTURE] = pspec; - g_object_class_install_property (gobject_class, PROP_COGL_TEXTURE, pspec); - - pspec = g_param_spec_boxed ("cogl-material", - P_("Cogl Material"), - P_("The underlying Cogl material handle used to draw this actor"), - COGL_TYPE_HANDLE, - CLUTTER_PARAM_READWRITE); - obj_props[PROP_COGL_MATERIAL] = pspec; - g_object_class_install_property (gobject_class, PROP_COGL_MATERIAL, pspec); - - /** - * ClutterTexture:filename: - * - * The path of the file containing the image data to be displayed by - * the texture. - * - * This property is unset when using the clutter_texture_set_from_*_data() - * family of functions. - * - * Deprecated: 1.12: Use #ClutterImage and platform-specific image loading - * API, like GdkPixbuf - */ - pspec = g_param_spec_string ("filename", - P_("Filename"), - P_("The path of the file containing the image data"), - NULL, - CLUTTER_PARAM_READWRITE); - obj_props[PROP_FILENAME] = pspec; - g_object_class_install_property (gobject_class, PROP_FILENAME, pspec); - - pspec = g_param_spec_boolean ("keep-aspect-ratio", - P_("Keep Aspect Ratio"), - P_("Keep the aspect ratio of the texture when requesting the preferred width or height"), - FALSE, - CLUTTER_PARAM_READWRITE); - obj_props[PROP_KEEP_ASPECT_RATIO] = pspec; - g_object_class_install_property (gobject_class, PROP_KEEP_ASPECT_RATIO, pspec); - - /** - * ClutterTexture:load-async: - * - * Tries to load a texture from a filename by using a local thread to perform - * the read operations. The initially created texture has dimensions 0x0 when - * the true size becomes available the #ClutterTexture::size-change signal is - * emitted and when the image has completed loading the - * #ClutterTexture::load-finished signal is emitted. - * - * Threading is only enabled if g_thread_init() has been called prior to - * clutter_init(), otherwise #ClutterTexture will use the main loop to load - * the image. - * - * The upload of the texture data on the GL pipeline is not asynchronous, as - * it must be performed from within the same thread that called - * clutter_main(). - * - * Since: 1.0 - * - * Deprecated: 1.12: Use platform-specific image loading API, like GdkPixbuf - */ - pspec = g_param_spec_boolean ("load-async", - P_("Load asynchronously"), - P_("Load files inside a thread to avoid blocking when loading images from disk"), - FALSE, - CLUTTER_PARAM_WRITABLE); - obj_props[PROP_LOAD_ASYNC] = pspec; - g_object_class_install_property (gobject_class, PROP_LOAD_ASYNC, pspec); - - - /** - * ClutterTexture:load-data-async: - * - * Like #ClutterTexture:load-async but loads the width and height - * synchronously causing some blocking. - * - * Since: 1.0 - * - * Deprecated: 1.12: Use platform-specific image loading API, like GdkPixbuf - */ - pspec = g_param_spec_boolean ("load-data-async", - P_("Load data asynchronously"), - P_("Decode image data files inside a thread to reduce blocking when loading images from disk"), - FALSE, - CLUTTER_PARAM_WRITABLE); - obj_props[PROP_LOAD_DATA_ASYNC] = pspec; - g_object_class_install_property (gobject_class, PROP_LOAD_DATA_ASYNC, pspec); - - /** - * ClutterTexture::pick-with-alpha: - * - * Determines whether a #ClutterTexture should have it's shape defined - * by its alpha channel when picking. - * - * Be aware that this is a bit more costly than the default picking - * due to the texture lookup, extra test against the alpha value and - * the fact that it will also interrupt the batching of geometry - * done internally. - * - * Also there is currently no control over the threshold used to - * determine what value of alpha is considered pickable, and so - * only fully opaque parts of the texture will react to picking. - * - * Since: 1.4 - * - * Deprecated: 1.12: No replacement is available - */ - pspec = g_param_spec_boolean ("pick-with-alpha", - P_("Pick With Alpha"), - P_("Shape actor with alpha channel when picking"), - FALSE, - CLUTTER_PARAM_READWRITE); - obj_props[PROP_PICK_WITH_ALPHA] = pspec; - g_object_class_install_property (gobject_class, PROP_PICK_WITH_ALPHA, pspec); - - /** - * ClutterTexture::size-change: - * @texture: the texture which received the signal - * @width: the width of the new texture - * @height: the height of the new texture - * - * The ::size-change signal is emitted each time the size of the - * pixbuf used by @texture changes. The new size is given as - * argument to the callback. - * - * Deprecated: 1.12: No replacement is available - */ - texture_signals[SIZE_CHANGE] = - g_signal_new ("size-change", - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterTextureClass, size_change), - NULL, NULL, - _clutter_marshal_VOID__INT_INT, - G_TYPE_NONE, 2, - G_TYPE_INT, - G_TYPE_INT); - /** - * ClutterTexture::pixbuf-change: - * @texture: the texture which received the signal - * - * The ::pixbuf-change signal is emitted each time the pixbuf - * used by @texture changes. - * - * Deprecated: 1.12: No replacement is available - */ - texture_signals[PIXBUF_CHANGE] = - g_signal_new ("pixbuf-change", - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterTextureClass, pixbuf_change), - NULL, NULL, - _clutter_marshal_VOID__VOID, - G_TYPE_NONE, - 0); - /** - * ClutterTexture::load-finished: - * @texture: the texture which received the signal - * @error: A set error, or %NULL - * - * The ::load-finished signal is emitted when a texture load has - * completed. If there was an error during loading, @error will - * be set, otherwise it will be %NULL - * - * Since: 1.0 - * - * Deprecated: 1.12: No replacement is available - */ - texture_signals[LOAD_FINISHED] = - g_signal_new (I_("load-finished"), - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterTextureClass, load_finished), - NULL, NULL, - _clutter_marshal_VOID__BOXED, - G_TYPE_NONE, - 1, - G_TYPE_ERROR); -} - -static ClutterScriptableIface *parent_scriptable_iface = NULL; - -static void -clutter_texture_set_custom_property (ClutterScriptable *scriptable, - ClutterScript *script, - const gchar *name, - const GValue *value) -{ - ClutterTexture *texture = CLUTTER_TEXTURE (scriptable); - - if (strcmp ("filename", name) == 0) - { - const gchar *str = g_value_get_string (value); - gchar *path; - GError *error; - - path = clutter_script_lookup_filename (script, str); - if (G_UNLIKELY (!path)) - { - g_warning ("Unable to find image %s", str); - return; - } - - error = NULL; - clutter_texture_set_from_file (texture, path, &error); - if (error) - { - g_warning ("Unable to open image path at '%s': %s", - path, - error->message); - g_error_free (error); - } - - free (path); - } - else - { - /* chain up */ - if (parent_scriptable_iface->set_custom_property) - parent_scriptable_iface->set_custom_property (scriptable, script, - name, - value); - } -} - -static void -clutter_scriptable_iface_init (ClutterScriptableIface *iface) -{ - parent_scriptable_iface = g_type_interface_peek_parent (iface); - - if (!parent_scriptable_iface) - parent_scriptable_iface = g_type_default_interface_peek - (CLUTTER_TYPE_SCRIPTABLE); - - iface->set_custom_property = clutter_texture_set_custom_property; -} - -static void -clutter_texture_init (ClutterTexture *self) -{ - ClutterTexturePrivate *priv; - - self->priv = priv = clutter_texture_get_instance_private (self); - - priv->repeat_x = FALSE; - priv->repeat_y = FALSE; - priv->sync_actor_size = TRUE; - priv->fbo_handle = NULL; - priv->pick_pipeline = NULL; - priv->keep_aspect_ratio = FALSE; - priv->pick_with_alpha = FALSE; - priv->pick_with_alpha_supported = TRUE; - priv->seen_create_pick_pipeline_warning = FALSE; - - if (G_UNLIKELY (texture_template_pipeline == NULL)) - { - CoglPipeline *pipeline; - CoglContext *ctx = - clutter_backend_get_cogl_context (clutter_get_default_backend ()); - - texture_template_pipeline = cogl_pipeline_new (ctx); - pipeline = COGL_PIPELINE (texture_template_pipeline); - cogl_pipeline_set_layer_null_texture (pipeline, - 0, /* layer_index */ - COGL_TEXTURE_TYPE_2D); - } - - g_assert (texture_template_pipeline != NULL); - priv->pipeline = cogl_pipeline_copy (texture_template_pipeline); -} - -/** - * clutter_texture_get_cogl_material: - * @texture: A #ClutterTexture - * - * Returns a handle to the underlying COGL material used for drawing - * the actor. - * - * Return value: (transfer none): a handle for a #CoglMaterial. The - * material is owned by the #ClutterTexture and it should not be - * unreferenced - * - * Since: 1.0 - * - * Deprecated: 1.12: No replacement is available; it's not advisable - * to modify the Cogl pipeline of an actor. Use a #ClutterContent - * implementation and modify the pipeline during the paint sequence - */ -CoglHandle -clutter_texture_get_cogl_material (ClutterTexture *texture) -{ - g_return_val_if_fail (CLUTTER_IS_TEXTURE (texture), NULL); - - return texture->priv->pipeline; -} - -/** - * clutter_texture_set_cogl_material: - * @texture: A #ClutterTexture - * @cogl_material: A CoglHandle for a material - * - * Replaces the underlying Cogl material drawn by this actor with - * @cogl_material. A reference to the material is taken so if the - * handle is no longer needed it should be deref'd with - * cogl_handle_unref. Texture data is attached to the material so - * calling this function also replaces the Cogl - * texture. #ClutterTexture requires that the material have a texture - * layer so you should set one on the material before calling this - * function. - * - * Since: 0.8 - * - * Deprecated: 1.12: No replacement is available; it's not advisable - * to modify the Cogl pipeline of an actor. Use a #ClutterContent - * implementation and modify the pipeline during the paint sequence - */ -void -clutter_texture_set_cogl_material (ClutterTexture *texture, - CoglHandle cogl_material) -{ - CoglPipeline *cogl_pipeline = cogl_material; - CoglHandle cogl_texture; - - g_return_if_fail (CLUTTER_IS_TEXTURE (texture)); - - cogl_object_ref (cogl_pipeline); - - if (texture->priv->pipeline) - cogl_object_unref (texture->priv->pipeline); - - texture->priv->pipeline = cogl_pipeline; - - /* XXX: We are re-asserting the first layer of the new pipeline to ensure the - * priv state is in sync with the contents of the pipeline. */ - cogl_texture = clutter_texture_get_cogl_texture (texture); - clutter_texture_set_cogl_texture (texture, cogl_texture); - /* XXX: If we add support for more pipeline layers, this will need - * extending */ -} - -typedef struct _GetLayerState -{ - gboolean has_layer; - int first_layer; -} GetLayerState; - -static gboolean -layer_cb (CoglPipeline *pipeline, int layer, void *user_data) -{ - GetLayerState *state = user_data; - - state->has_layer = TRUE; - state->first_layer = layer; - - /* We only care about the first layer. */ - return FALSE; -} - -static gboolean -get_first_layer_index (CoglPipeline *pipeline, int *layer_index) -{ - GetLayerState state = { FALSE }; - cogl_pipeline_foreach_layer (pipeline, - layer_cb, - &state); - if (state.has_layer) - *layer_index = state.first_layer; - - return state.has_layer; -} - -/** - * clutter_texture_get_cogl_texture: - * @texture: A #ClutterTexture - * - * Retrieves the handle to the underlying COGL texture used for drawing - * the actor. No extra reference is taken so if you need to keep the - * handle then you should call cogl_handle_ref() on it. - * - * The texture handle returned is the first layer of the material - * handle used by the #ClutterTexture. If you need to access the other - * layers you should use clutter_texture_get_cogl_material() instead - * and use the #CoglMaterial API. - * - * Return value: (transfer none): a #CoglHandle for the texture. The returned - * handle is owned by the #ClutterTexture and it should not be unreferenced - * - * Since: 0.8 - * - * Deprecated: 1.12: No replacement available; it's not advisable to - * modify the Cogl pipeline of an actor. Use a #ClutterContent - * implementation and set up the pipeline during the paint sequence - * instead. - */ -CoglHandle -clutter_texture_get_cogl_texture (ClutterTexture *texture) -{ - ClutterTexturePrivate *priv; - int layer_index; - - g_return_val_if_fail (CLUTTER_IS_TEXTURE (texture), NULL); - - priv = texture->priv; - - if (get_first_layer_index (priv->pipeline, &layer_index)) - return cogl_pipeline_get_layer_texture (priv->pipeline, layer_index); - else - return NULL; -} - -/** - * clutter_texture_set_cogl_texture: - * @texture: A #ClutterTexture - * @cogl_tex: A CoglHandle for a texture - * - * Replaces the underlying COGL texture drawn by this actor with - * @cogl_tex. A reference to the texture is taken so if the handle is - * no longer needed it should be deref'd with cogl_handle_unref. - * - * Since: 0.8 - * - * Deprecated: 1.12: No replacement available; it's not advisable to - * modify the Cogl pipeline of an actor. Use a #ClutterContent - * implementation and set up the pipeline during the paint sequence - * instead. - */ -void -clutter_texture_set_cogl_texture (ClutterTexture *texture, - CoglHandle cogl_tex) -{ - ClutterTexturePrivate *priv; - gboolean size_changed; - guint width, height; - - g_return_if_fail (CLUTTER_IS_TEXTURE (texture)); - g_return_if_fail (cogl_is_texture (cogl_tex)); - - /* This function can set the texture without the actor being - realized. This is ok because Clutter requires that the GL context - always be current so there is no point in waiting to realization - to set the texture. */ - - priv = texture->priv; - - width = cogl_texture_get_width (cogl_tex); - height = cogl_texture_get_height (cogl_tex); - - /* Reference the new texture now in case it is the same one we are - already using */ - cogl_object_ref (cogl_tex); - - /* Remove FBO if exisiting */ - if (priv->fbo_source) - texture_fbo_free_resources (texture); - - /* Remove old texture */ - texture_free_gl_resources (texture); - - /* Use the new texture */ - if (priv->pipeline == NULL) - priv->pipeline = cogl_pipeline_copy (texture_template_pipeline); - - g_assert (priv->pipeline != NULL); - cogl_pipeline_set_layer_texture (priv->pipeline, 0, cogl_tex); - - /* The pipeline now holds a reference to the texture so we can - safely release the reference we claimed above */ - cogl_object_unref (cogl_tex); - - size_changed = (width != priv->image_width || height != priv->image_height); - priv->image_width = width; - priv->image_height = height; - - CLUTTER_NOTE (TEXTURE, "set size (w:%d, h:%d)", - priv->image_width, - priv->image_height); - - if (size_changed) - { - g_signal_emit (texture, texture_signals[SIZE_CHANGE], 0, - priv->image_width, - priv->image_height); - - if (priv->sync_actor_size) - { - ClutterActor *actor = CLUTTER_ACTOR (texture); - - /* we have been requested to keep the actor size in - * sync with the texture data; if we also want to - * maintain the aspect ratio we want to change the - * requisition mode depending on the orientation of - * the texture, so that the parent container can do - * the right thing - */ - if (priv->keep_aspect_ratio) - { - ClutterRequestMode request; - - if (priv->image_width >= priv->image_height) - request = CLUTTER_REQUEST_HEIGHT_FOR_WIDTH; - else - request = CLUTTER_REQUEST_WIDTH_FOR_HEIGHT; - - clutter_actor_set_request_mode (actor, request); - } - - clutter_actor_queue_relayout (CLUTTER_ACTOR (texture)); - } - } - - /* rename signal */ - g_signal_emit (texture, texture_signals[PIXBUF_CHANGE], 0); - - /* If resized actor may need resizing but paint() will do this */ - clutter_actor_queue_redraw (CLUTTER_ACTOR (texture)); - - g_object_notify_by_pspec (G_OBJECT (texture), obj_props[PROP_COGL_TEXTURE]); -} - -static gboolean -clutter_texture_set_from_data (ClutterTexture *texture, - const guchar *data, - CoglPixelFormat source_format, - gint width, - gint height, - gint rowstride, - gint bpp, - GError **error) -{ - ClutterTexturePrivate *priv = texture->priv; - CoglHandle new_texture = NULL; - CoglTextureFlags flags = COGL_TEXTURE_NONE; - - if (priv->no_slice) - flags |= COGL_TEXTURE_NO_SLICING; - - /* FIXME if we are not realized, we should store the data - * for future use, instead of creating the texture. - */ - new_texture = cogl_texture_new_from_data (width, height, - flags, - source_format, - COGL_PIXEL_FORMAT_ANY, - rowstride, - data); - - if (G_UNLIKELY (new_texture == NULL)) - { - GError *inner_error = NULL; - - g_set_error (&inner_error, CLUTTER_TEXTURE_ERROR, - CLUTTER_TEXTURE_ERROR_BAD_FORMAT, - _("Failed to load the image data")); - - g_signal_emit (texture, texture_signals[LOAD_FINISHED], 0, inner_error); - - if (error != NULL) - g_propagate_error (error, inner_error); - else - g_error_free (inner_error); - - return FALSE; - } - - free (priv->filename); - priv->filename = NULL; - - clutter_texture_set_cogl_texture (texture, new_texture); - - cogl_object_unref (new_texture); - - g_signal_emit (texture, texture_signals[LOAD_FINISHED], 0, NULL); - - return TRUE; -} - -static inline gboolean -get_pixel_format_from_texture_flags (gint bpp, - gboolean has_alpha, - ClutterTextureFlags flags, - CoglPixelFormat *source_format) -{ - /* Convert the flags to a CoglPixelFormat */ - if (has_alpha) - { - if (G_UNLIKELY (bpp != 4)) - { - g_warning ("Unsupported bytes per pixel value '%d': " - "Clutter supports only a value of 4 " - "for RGBA data", - bpp); - return FALSE; - } - - *source_format = COGL_PIXEL_FORMAT_RGBA_8888; - } - else - { - if (G_UNLIKELY (bpp != 3)) - { - g_warning ("Unsupported bytes per pixel value '%d': " - "Clutter supports only a BPP value of 3 " - "for RGB data", - bpp); - return FALSE; - } - - *source_format = COGL_PIXEL_FORMAT_RGB_888; - } - - if ((flags & CLUTTER_TEXTURE_RGB_FLAG_BGR)) - *source_format |= COGL_BGR_BIT; - - if ((flags & CLUTTER_TEXTURE_RGB_FLAG_PREMULT)) - *source_format |= COGL_PREMULT_BIT; - - return TRUE; -} - -/** - * clutter_texture_set_from_rgb_data: - * @texture: a #ClutterTexture - * @data: (array): image data in RGBA type colorspace. - * @has_alpha: set to %TRUE if image data has an alpha channel. - * @width: width in pixels of image data. - * @height: height in pixels of image data - * @rowstride: distance in bytes between row starts. - * @bpp: bytes per pixel (currently only 3 and 4 supported, depending - * on the value of @has_alpha) - * @flags: #ClutterTextureFlags - * @error: return location for a #GError, or %NULL. - * - * Sets #ClutterTexture image data. - * - * Return value: %TRUE on success, %FALSE on failure. - * - * Since: 0.4 - * - * Deprecated: 1.12: Use #ClutterImage and clutter_image_set_data() instead - */ -gboolean -clutter_texture_set_from_rgb_data (ClutterTexture *texture, - const guchar *data, - gboolean has_alpha, - gint width, - gint height, - gint rowstride, - gint bpp, - ClutterTextureFlags flags, - GError **error) -{ - CoglPixelFormat source_format; - - g_return_val_if_fail (CLUTTER_IS_TEXTURE (texture), FALSE); - - if (!get_pixel_format_from_texture_flags (bpp, - has_alpha, - flags, - &source_format)) - { - return FALSE; - } - - return clutter_texture_set_from_data (texture, data, - source_format, - width, height, - rowstride, bpp, - error); -} - -/** - * clutter_texture_set_from_yuv_data: - * @texture: A #ClutterTexture - * @data: (array): Image data in YUV type colorspace. - * @width: Width in pixels of image data. - * @height: Height in pixels of image data - * @flags: #ClutterTextureFlags - * @error: Return location for a #GError, or %NULL. - * - * Sets a #ClutterTexture from YUV image data. If an error occurred, - * %FALSE is returned and @error is set. - * - * The YUV support depends on the driver; the format supported by the - * few drivers exposing this capability are not really useful. - * - * The proper way to convert image data in any YUV colorspace to any - * RGB colorspace is to use a fragment shader associated with the - * #ClutterTexture material. - * - * Return value: %TRUE if the texture was successfully updated - * - * Since: 0.4 - * - * Deprecated: 1.10: Use a custom #ClutterContent implementation and - * set up the Cogl pipeline using a #ClutterPipelineNode with a - * fragment shader instead. - */ -gboolean -clutter_texture_set_from_yuv_data (ClutterTexture *texture, - const guchar *data, - gint width, - gint height, - ClutterTextureFlags flags, - GError **error) -{ - g_return_val_if_fail (CLUTTER_IS_TEXTURE (texture), FALSE); - - if (!clutter_feature_available (CLUTTER_FEATURE_TEXTURE_YUV)) - { - g_set_error (error, CLUTTER_TEXTURE_ERROR, - CLUTTER_TEXTURE_ERROR_NO_YUV, - _("YUV textures are not supported")); - return FALSE; - } - - /* Convert the flags to a CoglPixelFormat */ - if ((flags & CLUTTER_TEXTURE_YUV_FLAG_YUV2)) - { - g_set_error (error, CLUTTER_TEXTURE_ERROR, - CLUTTER_TEXTURE_ERROR_BAD_FORMAT, - _("YUV2 textures are not supported")); - return FALSE; - } - - return clutter_texture_set_from_data (texture, data, - COGL_PIXEL_FORMAT_YUV, - width, height, - width * 3, 3, - error); -} - -/* - * clutter_texture_async_load_complete: - * @self: a #ClutterTexture - * @bitmap: a handle to a CoglBitmap - * @error: load error - * - * If @error is %NULL, loads @bitmap into a #CoglTexture. - * - * This function emits the ::load-finished signal on @self. - */ -static void -clutter_texture_async_load_complete (ClutterTexture *self, - CoglHandle bitmap, - const GError *error) -{ - ClutterTexturePrivate *priv = self->priv; - CoglTextureFlags flags = COGL_TEXTURE_NONE; - CoglHandle handle; - - priv->async_data = NULL; - - if (error == NULL) - { - if (priv->no_slice) - flags |= COGL_TEXTURE_NO_SLICING; - - handle = cogl_texture_new_from_bitmap (bitmap, - flags, - COGL_PIXEL_FORMAT_ANY); - clutter_texture_set_cogl_texture (self, handle); - - if (priv->load_size_async) - { - g_signal_emit (self, texture_signals[SIZE_CHANGE], 0, - cogl_texture_get_width (handle), - cogl_texture_get_height (handle)); - } - - cogl_object_unref (handle); - } - - g_signal_emit (self, texture_signals[LOAD_FINISHED], 0, error); - - clutter_actor_queue_relayout (CLUTTER_ACTOR (self)); -} - -static gboolean -texture_repaint_upload_func (gpointer user_data) -{ - g_mutex_lock (&upload_list_mutex); - - if (upload_list != NULL) - { - gint64 start_time = g_get_monotonic_time (); - - /* continue uploading textures as long as we havent spent more - * then 5ms doing so this stage redraw cycle. - */ - do - { - ClutterTextureAsyncData *async_data = upload_list->data; - - clutter_texture_async_data_lock (async_data); - - if (async_data->state & ASYNC_STATE_QUEUED) - { - CLUTTER_NOTE (TEXTURE, "[async] operation complete for '%s'", - async_data->load_filename); - - clutter_texture_async_load_complete (async_data->texture, - async_data->load_bitmap, - async_data->load_error); - } - else - CLUTTER_NOTE (TEXTURE, "[async] operation cancelled for '%s'", - async_data->load_filename); - - clutter_texture_async_data_unlock (async_data); - - upload_list = g_list_remove (upload_list, async_data); - clutter_texture_async_data_free (async_data); - } - while (upload_list != NULL && - g_get_monotonic_time () < start_time + 5 * 1000L); - } - - if (upload_list != NULL) - { - ClutterMasterClock *master_clock; - - master_clock = _clutter_master_clock_get_default (); - _clutter_master_clock_ensure_next_iteration (master_clock); - } - - g_mutex_unlock (&upload_list_mutex); - - return TRUE; -} - -static void -clutter_texture_thread_load (gpointer user_data, - gpointer pool_data) -{ - ClutterTextureAsyncData *async_data = user_data; - ClutterMasterClock *master_clock = _clutter_master_clock_get_default (); - - clutter_texture_async_data_lock (async_data); - - if (~async_data->state & ASYNC_STATE_CANCELLED) - { - CLUTTER_NOTE (TEXTURE, "[async] loading bitmap from file '%s'", - async_data->load_filename); - - async_data->load_bitmap = - cogl_bitmap_new_from_file (async_data->load_filename, - &async_data->load_error); - - g_mutex_lock (&upload_list_mutex); - - if (repaint_upload_func == 0) - { - repaint_upload_func = - clutter_threads_add_repaint_func (texture_repaint_upload_func, - NULL, NULL); - } - - upload_list = g_list_append (upload_list, async_data); - async_data->state |= ASYNC_STATE_QUEUED; - - CLUTTER_NOTE (TEXTURE, "[async] operation queued"); - - g_mutex_unlock (&upload_list_mutex); - } - else - { - clutter_texture_async_data_unlock (async_data); - clutter_texture_async_data_free (async_data); - - return; - } - - clutter_texture_async_data_unlock (async_data); - - _clutter_master_clock_ensure_next_iteration (master_clock); -} - -static gboolean -clutter_texture_idle_load (gpointer data) -{ - ClutterTextureAsyncData *async_data = data; - - async_data->load_bitmap = - cogl_bitmap_new_from_file (async_data->load_filename, - &async_data->load_error); - - clutter_texture_async_load_complete (async_data->texture, - async_data->load_bitmap, - async_data->load_error); - - clutter_texture_async_data_free (async_data); - - return FALSE; -} - -/* - * clutter_texture_async_load: - * @self: a #ClutterTExture - * @filename: name of the file to load - * @error: return location for a #GError - * - * Starts an asynchronous load of the file name stored inside - * the load_filename member of @data. - * - * If threading is enabled we use a GThread to perform the actual - * I/O; if threading is not enabled, we use an idle GSource. - * - * The I/O is the only bit done in a thread -- uploading the - * texture data to the GL pipeline must be done from within the - * same thread that called clutter_main(). Threaded upload should - * be part of the GL implementation. - * - * This function will block until we get a size from the file - * so that we can effectively get the size the texture actor after - * clutter_texture_set_from_file(). - * - * Return value: %TRUE if the asynchronous loading was successfully - * initiated, %FALSE otherwise - */ -static gboolean -clutter_texture_async_load (ClutterTexture *self, - const gchar *filename, - GError **error) -{ - ClutterTexturePrivate *priv = self->priv; - ClutterTextureAsyncData *data; - gint width, height; - gboolean res; - - /* ask the file for a size; if we cannot get the size then - * there's no point in even continuing the asynchronous - * loading, so we just stop there - */ - - if (priv->load_size_async) - { - res = TRUE; - width = 0; - height = 0; - } - else - res = cogl_bitmap_get_size_from_file (filename, &width, &height); - - if (!res) - { - g_set_error (error, CLUTTER_TEXTURE_ERROR, - CLUTTER_TEXTURE_ERROR_BAD_FORMAT, - _("Failed to load the image data")); - return FALSE; - } - else - { - priv->image_width = width; - priv->image_height = height; - } - - clutter_texture_async_load_cancel (self); - - data = g_slice_new0 (ClutterTextureAsyncData); - - data->texture = self; - data->load_filename = g_strdup (filename); - - priv->async_data = data; - - if (1) - { - if (G_UNLIKELY (async_thread_pool == NULL)) - { - /* This apparently can't fail if exclusive == FALSE */ - async_thread_pool = - g_thread_pool_new (clutter_texture_thread_load, NULL, - 1, - FALSE, - NULL); - } - - g_thread_pool_push (async_thread_pool, data, NULL); - } - else - { - data->load_idle = - clutter_threads_add_idle_full (G_PRIORITY_DEFAULT_IDLE, - clutter_texture_idle_load, - data, - NULL); - } - - return TRUE; -} - -/** - * clutter_texture_set_from_file: - * @texture: A #ClutterTexture - * @filename: The filename of the image in GLib file name encoding - * @error: Return location for a #GError, or %NULL - * - * Sets the #ClutterTexture image data from an image file. In case of - * failure, %FALSE is returned and @error is set. - * - * If #ClutterTexture:load-async is set to %TRUE, this function - * will return as soon as possible, and the actual image loading - * from disk will be performed asynchronously. #ClutterTexture::size-change - * will be emitten when the size of the texture is available and - * #ClutterTexture::load-finished will be emitted when the image has been - * loaded or if an error occurred. - * - * Return value: %TRUE if the image was successfully loaded and set - * - * Since: 0.8 - * - * Deprecated: 1.12: Use #ClutterImage and platform-specific image - * loading API, like GdkPixbuf, instead - */ -gboolean -clutter_texture_set_from_file (ClutterTexture *texture, - const gchar *filename, - GError **error) -{ - ClutterTexturePrivate *priv; - CoglHandle new_texture = NULL; - GError *internal_error = NULL; - CoglTextureFlags flags = COGL_TEXTURE_NONE; - - priv = texture->priv; - - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - if (priv->load_data_async) - return clutter_texture_async_load (texture, filename, error); - - if (priv->no_slice) - flags |= COGL_TEXTURE_NO_SLICING; - - new_texture = cogl_texture_new_from_file (filename, - flags, - COGL_PIXEL_FORMAT_ANY, - &internal_error); - - /* If COGL didn't give an error then make one up */ - if (internal_error == NULL && new_texture == NULL) - { - g_set_error (&internal_error, CLUTTER_TEXTURE_ERROR, - CLUTTER_TEXTURE_ERROR_BAD_FORMAT, - _("Failed to load the image data")); - } - - if (internal_error != NULL) - { - g_signal_emit (texture, texture_signals[LOAD_FINISHED], 0, - internal_error); - - g_propagate_error (error, internal_error); - - return FALSE; - } - - free (priv->filename); - priv->filename = g_strdup (filename); - - clutter_texture_set_cogl_texture (texture, new_texture); - - cogl_object_unref (new_texture); - - g_signal_emit (texture, texture_signals[LOAD_FINISHED], 0, NULL); - - g_object_notify_by_pspec (G_OBJECT (texture), obj_props[PROP_FILENAME]); - - return TRUE; -} - -/** - * clutter_texture_set_filter_quality: - * @texture: a #ClutterTexture - * @filter_quality: new filter quality value - * - * Sets the filter quality when scaling a texture. The quality is an - * enumeration currently the following values are supported: - * %CLUTTER_TEXTURE_QUALITY_LOW which is fast but only uses nearest neighbour - * interpolation. %CLUTTER_TEXTURE_QUALITY_MEDIUM which is computationally a - * bit more expensive (bilinear interpolation), and - * %CLUTTER_TEXTURE_QUALITY_HIGH which uses extra texture memory resources to - * improve scaled down rendering as well (by using mipmaps). The default value - * is %CLUTTER_TEXTURE_QUALITY_MEDIUM. - * - * Since: 0.8 - * - * Deprecated: 1.12: Use #ClutterImage and clutter_actor_set_content_scaling_filters() - * instead - */ -void -clutter_texture_set_filter_quality (ClutterTexture *texture, - ClutterTextureQuality filter_quality) -{ - ClutterTexturePrivate *priv; - ClutterTextureQuality old_quality; - - g_return_if_fail (CLUTTER_IS_TEXTURE (texture)); - - priv = texture->priv; - - old_quality = clutter_texture_get_filter_quality (texture); - - if (filter_quality != old_quality) - { - gint min_filter, mag_filter; - - min_filter = mag_filter = COGL_PIPELINE_FILTER_LINEAR; - clutter_texture_quality_to_filters (filter_quality, - &min_filter, - &mag_filter); - - cogl_pipeline_set_layer_filters (priv->pipeline, 0, - min_filter, mag_filter); - - clutter_actor_queue_redraw (CLUTTER_ACTOR (texture)); - - g_object_notify_by_pspec (G_OBJECT (texture), obj_props[PROP_FILTER_QUALITY]); - } -} - -/** - * clutter_texture_get_filter_quality: - * @texture: A #ClutterTexture - * - * Gets the filter quality used when scaling a texture. - * - * Return value: The filter quality value. - * - * Since: 0.8 - * - * Deprecated: 1.12: Use #ClutterImage and clutter_actor_get_content_scaling_filters() - * instead - */ -ClutterTextureQuality -clutter_texture_get_filter_quality (ClutterTexture *texture) -{ - ClutterTexturePrivate *priv; - int layer_index; - CoglPipelineFilter min_filter, mag_filter; - int i; - - g_return_val_if_fail (CLUTTER_IS_TEXTURE (texture), 0); - - priv = texture->priv; - - if (get_first_layer_index (priv->pipeline, &layer_index)) - { - min_filter = cogl_pipeline_get_layer_min_filter (priv->pipeline, - layer_index); - mag_filter = cogl_pipeline_get_layer_mag_filter (priv->pipeline, - layer_index); - } - else - return CLUTTER_TEXTURE_QUALITY_MEDIUM; - - for (i = 0; i < G_N_ELEMENTS (clutter_texture_quality_filters); i++) - if (clutter_texture_quality_filters[i].min_filter == min_filter - && clutter_texture_quality_filters[i].mag_filter == mag_filter) - return i; - - /* Unknown filter combination */ - return CLUTTER_TEXTURE_QUALITY_LOW; -} - -/** - * clutter_texture_get_max_tile_waste: - * @texture: A #ClutterTexture - * - * Gets the maximum waste that will be used when creating a texture or - * -1 if slicing is disabled. - * - * Return value: The maximum waste or -1 if the texture waste is - * unlimited. - * - * Since: 0.8 - * - * Deprecated: 1.12: No replacement is available - */ -gint -clutter_texture_get_max_tile_waste (ClutterTexture *texture) -{ - ClutterTexturePrivate *priv; - CoglHandle cogl_texture; - - g_return_val_if_fail (CLUTTER_IS_TEXTURE (texture), 0); - - priv = texture->priv; - - cogl_texture = clutter_texture_get_cogl_texture (texture); - - if (cogl_texture == NULL) - return priv->no_slice ? -1 : COGL_TEXTURE_MAX_WASTE; - else - return cogl_texture_get_max_waste (cogl_texture); -} - -/** - * clutter_texture_new_from_file: - * @filename: The name of an image file to load. - * @error: Return locatoin for an error. - * - * Creates a new ClutterTexture actor to display the image contained a - * file. If the image failed to load then NULL is returned and @error - * is set. - * - * Return value: A newly created #ClutterTexture object or NULL on - * error. - * - * Since: 0.8 - * - * Deprecated: 1.12: No direct replacement is available. Use #ClutterImage - * and platform-specific image loading API, like GdkPixbuf, instead - */ -ClutterActor* -clutter_texture_new_from_file (const gchar *filename, - GError **error) -{ - ClutterActor *texture = clutter_texture_new (); - - if (!clutter_texture_set_from_file (CLUTTER_TEXTURE (texture), - filename, error)) - { - g_object_ref_sink (texture); - g_object_unref (texture); - - return NULL; - } - else - return texture; -} - -/** - * clutter_texture_new: - * - * Creates a new empty #ClutterTexture object. - * - * Return value: A newly created #ClutterTexture object. - * - * Deprecated: 1.12: Use #ClutterImage instead - */ -ClutterActor * -clutter_texture_new (void) -{ - return g_object_new (CLUTTER_TYPE_TEXTURE, NULL); -} - -/** - * clutter_texture_get_base_size: - * @texture: a #ClutterTexture - * @width: (out): return location for the width, or %NULL - * @height: (out): return location for the height, or %NULL - * - * Gets the size in pixels of the untransformed underlying image - * - * Deprecated: 1.12: Use #ClutterImage and clutter_content_get_preferred_size() - * instead - */ -void -clutter_texture_get_base_size (ClutterTexture *texture, - gint *width, - gint *height) -{ - g_return_if_fail (CLUTTER_IS_TEXTURE (texture)); - - if (width) - *width = texture->priv->image_width; - - if (height) - *height = texture->priv->image_height; -} - -/** - * clutter_texture_set_area_from_rgb_data: - * @texture: A #ClutterTexture - * @data: (array): Image data in RGB type colorspace. - * @has_alpha: Set to TRUE if image data has an alpha channel. - * @x: X coordinate of upper left corner of region to update. - * @y: Y coordinate of upper left corner of region to update. - * @width: Width in pixels of region to update. - * @height: Height in pixels of region to update. - * @rowstride: Distance in bytes between row starts on source buffer. - * @bpp: bytes per pixel (Currently only 3 and 4 supported, - * depending on @has_alpha) - * @flags: #ClutterTextureFlags - * @error: return location for a #GError, or %NULL - * - * Updates a sub-region of the pixel data in a #ClutterTexture. - * - * Return value: %TRUE on success, %FALSE on failure. - * - * Since: 0.6 - * - * Deprecated: 1.12: Use #ClutterImage and clutter_image_set_area() instead - */ -gboolean -clutter_texture_set_area_from_rgb_data (ClutterTexture *texture, - const guchar *data, - gboolean has_alpha, - gint x, - gint y, - gint width, - gint height, - gint rowstride, - gint bpp, - ClutterTextureFlags flags, - GError **error) -{ - CoglPixelFormat source_format; - CoglHandle cogl_texture; - - if (!get_pixel_format_from_texture_flags (bpp, has_alpha, flags, - &source_format)) - { - return FALSE; - } - - /* attempt to realize ... */ - if (!CLUTTER_ACTOR_IS_REALIZED (texture) && - clutter_actor_get_stage (CLUTTER_ACTOR (texture)) != NULL) - { - clutter_actor_realize (CLUTTER_ACTOR (texture)); - } - - /* due to the fudging of clutter_texture_set_cogl_texture() - * which allows setting a texture pre-realize, we may end - * up having a texture even if we couldn't realize yet. - */ - cogl_texture = clutter_texture_get_cogl_texture (texture); - if (cogl_texture == NULL) - { - g_warning ("Failed to realize actor '%s'", - _clutter_actor_get_debug_name (CLUTTER_ACTOR (texture))); - return FALSE; - } - - if (!cogl_texture_set_region (cogl_texture, - 0, 0, - x, y, width, height, - width, height, - source_format, - rowstride, - data)) - { - g_set_error (error, CLUTTER_TEXTURE_ERROR, - CLUTTER_TEXTURE_ERROR_BAD_FORMAT, - _("Failed to load the image data")); - return FALSE; - } - - free (texture->priv->filename); - texture->priv->filename = NULL; - - /* rename signal */ - g_signal_emit (texture, texture_signals[PIXBUF_CHANGE], 0); - - clutter_actor_queue_redraw (CLUTTER_ACTOR (texture)); - - return TRUE; -} - -static void -on_fbo_source_size_change (GObject *object, - GParamSpec *param_spec, - ClutterTexture *texture) -{ - ClutterTexturePrivate *priv = texture->priv; - gfloat w, h; - ClutterActorBox box; - gboolean status; - - status = clutter_actor_get_paint_box (priv->fbo_source, &box); - if (status) - clutter_actor_box_get_size (&box, &w, &h); - - /* In the end we will size the framebuffer according to the paint - * box, but for code that does: - * tex = clutter_texture_new_from_actor (src); - * clutter_actor_get_size (tex, &width, &height); - * it seems more helpfull to return the src actor size if it has a - * degenerate paint box. The most likely reason it will have a - * degenerate paint box is simply that the src currently has no - * parent. */ - if (status == FALSE || w == 0 || h == 0) - clutter_actor_get_size (priv->fbo_source, &w, &h); - - /* We can't create a texture with a width or height of 0... */ - w = MAX (1, w); - h = MAX (1, h); - - if (w != priv->image_width || h != priv->image_height) - { - CoglTextureFlags flags = COGL_TEXTURE_NONE; - CoglHandle tex; - - /* tear down the FBO */ - if (priv->fbo_handle != NULL) - cogl_object_unref (priv->fbo_handle); - - texture_free_gl_resources (texture); - - priv->image_width = w; - priv->image_height = h; - - flags |= COGL_TEXTURE_NO_SLICING; - - tex = cogl_texture_new_with_size (MAX (priv->image_width, 1), - MAX (priv->image_height, 1), - flags, - COGL_PIXEL_FORMAT_RGBA_8888_PRE); - - cogl_pipeline_set_layer_texture (priv->pipeline, 0, tex); - - priv->fbo_handle = cogl_offscreen_new_to_texture (tex); - - /* The pipeline now has a reference to the texture so it will - stick around */ - cogl_object_unref (tex); - - if (priv->fbo_handle == NULL) - { - g_warning ("%s: Offscreen texture creation failed", G_STRLOC); - return; - } - - clutter_actor_set_size (CLUTTER_ACTOR (texture), w, h); - } -} - -static void -on_fbo_parent_change (ClutterActor *actor, - ClutterActor *old_parent, - ClutterTexture *texture) -{ - ClutterActor *parent = CLUTTER_ACTOR(texture); - - while ((parent = clutter_actor_get_parent (parent)) != NULL) - { - if (parent == actor) - { - g_warning ("Offscreen texture is ancestor of source!"); - /* Desperate but will avoid infinite loops */ - clutter_actor_remove_child (parent, actor); - } - } -} - -static void -fbo_source_queue_redraw_cb (ClutterActor *source, - ClutterActor *origin, - ClutterTexture *texture) -{ - clutter_actor_queue_redraw (CLUTTER_ACTOR (texture)); -} - -static void -fbo_source_queue_relayout_cb (ClutterActor *source, - ClutterTexture *texture) -{ - clutter_actor_queue_relayout (CLUTTER_ACTOR (texture)); -} - -/** - * clutter_texture_new_from_actor: - * @actor: A source #ClutterActor - * - * Creates a new #ClutterTexture object with its source a prexisting - * actor (and associated children). The textures content will contain - * 'live' redirected output of the actors scene. - * - * Note this function is intented as a utility call for uniformly applying - * shaders to groups and other potential visual effects. It requires that - * the %CLUTTER_FEATURE_OFFSCREEN feature is supported by the current backend - * and the target system. - * - * Some tips on usage: - * - * - The source actor must be visible - * - The source actor must have a parent in order for it to be - * allocated a size from the layouting mechanism. If the source - * actor does not have a parent when this function is called then - * the ClutterTexture will adopt it and allocate it at its - * preferred size. Using this you can clone an actor that is - * otherwise not displayed. Because of this feature if you do - * intend to display the source actor then you must make sure that - * the actor is parented before calling - * clutter_texture_new_from_actor() or that you unparent it before - * adding it to a container. - * - When getting the image for the clone texture, Clutter - * will attempt to render the source actor exactly as it would - * appear if it was rendered on screen. The source actor's parent - * transformations are taken into account. Therefore if your - * source actor is rotated along the X or Y axes so that it has - * some depth, the texture will appear differently depending on - * the on-screen location of the source actor. While painting the - * source actor, Clutter will set up a temporary asymmetric - * perspective matrix as the projection matrix so that the source - * actor will be projected as if a small section of the screen was - * being viewed. Before version 0.8.2, an orthogonal identity - * projection was used which meant that the source actor would be - * clipped if any part of it was not on the zero Z-plane. - * - Avoid reparenting the source with the created texture. - * - A group can be padded with a transparent rectangle as to - * provide a border to contents for shader output (blurring text - * for example). - * - The texture will automatically resize to contain a further - * transformed source. However, this involves overhead and can be - * avoided by placing the source actor in a bounding group - * sized large enough to contain any child tranformations. - * - Uploading pixel data to the texture (e.g by using - * clutter_texture_set_from_file()) will destroy the offscreen texture - * data and end redirection. - * - cogl_texture_get_data() with the handle returned by - * clutter_texture_get_cogl_texture() can be used to read the - * offscreen texture pixels into a pixbuf. - * - * Return value: A newly created #ClutterTexture object, or %NULL on failure. - * - * Since: 0.6 - * - * Deprecated: 1.8: Use the #ClutterOffscreenEffect and #ClutterShaderEffect - * directly on the intended #ClutterActor to replace the functionality of - * this function. - */ -ClutterActor * -clutter_texture_new_from_actor (ClutterActor *actor) -{ - ClutterTexture *texture; - ClutterTexturePrivate *priv; - gfloat w, h; - ClutterActorBox box; - gboolean status; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), NULL); - - if (clutter_feature_available (CLUTTER_FEATURE_OFFSCREEN) == FALSE) - return NULL; - - if (!CLUTTER_ACTOR_IS_REALIZED (actor)) - { - clutter_actor_realize (actor); - - if (!CLUTTER_ACTOR_IS_REALIZED (actor)) - return NULL; - } - - status = clutter_actor_get_paint_box (actor, &box); - if (status) - clutter_actor_box_get_size (&box, &w, &h); - - /* In the end we will size the framebuffer according to the paint - * box, but for code that does: - * tex = clutter_texture_new_from_actor (src); - * clutter_actor_get_size (tex, &width, &height); - * it seems more helpfull to return the src actor size if it has a - * degenerate paint box. The most likely reason it will have a - * degenerate paint box is simply that the src currently has no - * parent. */ - if (status == FALSE || w == 0 || h == 0) - clutter_actor_get_size (actor, &w, &h); - - /* We can't create a 0x0 fbo so always bump the size up to at least - * 1 */ - w = MAX (1, w); - h = MAX (1, h); - - /* Hopefully now were good.. */ - texture = g_object_new (CLUTTER_TYPE_TEXTURE, - "disable-slicing", TRUE, - NULL); - - priv = texture->priv; - - priv->fbo_source = g_object_ref_sink (actor); - - /* If the actor doesn't have a parent then claim it so that it will - get a size allocation during layout */ - if (clutter_actor_get_parent (actor) == NULL) - clutter_actor_add_child (CLUTTER_ACTOR (texture), actor); - - /* Connect up any signals which could change our underlying size */ - g_signal_connect (actor, - "notify::width", - G_CALLBACK(on_fbo_source_size_change), - texture); - g_signal_connect (actor, - "notify::height", - G_CALLBACK(on_fbo_source_size_change), - texture); - g_signal_connect (actor, - "notify::scale-x", - G_CALLBACK(on_fbo_source_size_change), - texture); - g_signal_connect (actor, - "notify::scale-y", - G_CALLBACK(on_fbo_source_size_change), - texture); - g_signal_connect (actor, - "notify::rotation-angle-x", - G_CALLBACK(on_fbo_source_size_change), - texture); - g_signal_connect (actor, - "notify::rotation-angle-y", - G_CALLBACK(on_fbo_source_size_change), - texture); - g_signal_connect (actor, - "notify::rotation-angle-z", - G_CALLBACK(on_fbo_source_size_change), - texture); - - g_signal_connect (actor, "queue-relayout", - G_CALLBACK (fbo_source_queue_relayout_cb), texture); - g_signal_connect (actor, "queue-redraw", - G_CALLBACK (fbo_source_queue_redraw_cb), texture); - - /* And a warning if the source becomes a child of the texture */ - g_signal_connect (actor, - "parent-set", - G_CALLBACK(on_fbo_parent_change), - texture); - - priv->image_width = w; - priv->image_height = h; - - clutter_actor_set_size (CLUTTER_ACTOR (texture), - priv->image_width, - priv->image_height); - - return CLUTTER_ACTOR (texture); -} - -static void -texture_fbo_free_resources (ClutterTexture *texture) -{ - ClutterTexturePrivate *priv; - - priv = texture->priv; - - if (priv->fbo_source != NULL) - { - ClutterActor *parent; - - parent = clutter_actor_get_parent (priv->fbo_source); - - /* If we parented the texture then unparent it again so that it - will lose the reference */ - if (parent == CLUTTER_ACTOR (texture)) - clutter_actor_remove_child (parent, priv->fbo_source); - - g_signal_handlers_disconnect_by_func - (priv->fbo_source, - G_CALLBACK(on_fbo_parent_change), - texture); - - g_signal_handlers_disconnect_by_func - (priv->fbo_source, - G_CALLBACK(on_fbo_source_size_change), - texture); - - g_signal_handlers_disconnect_by_func - (priv->fbo_source, - G_CALLBACK(fbo_source_queue_relayout_cb), - texture); - - g_signal_handlers_disconnect_by_func - (priv->fbo_source, - G_CALLBACK(fbo_source_queue_redraw_cb), - texture); - - g_object_unref (priv->fbo_source); - - priv->fbo_source = NULL; - } - - if (priv->fbo_handle != NULL) - { - cogl_object_unref (priv->fbo_handle); - priv->fbo_handle = NULL; - } -} - -/** - * clutter_texture_set_sync_size: - * @texture: a #ClutterTexture - * @sync_size: %TRUE if the texture should have the same size of the - * underlying image data - * - * Sets whether @texture should have the same preferred size as the - * underlying image data. - * - * Since: 1.0 - * - * Deprecated: 1.12: No replacement is available. A #ClutterActor using - * #ClutterImage with a %CLUTTER_REQUEST_CONTENT_SIZE request mode - * will automatically bind the preferred size of the content to the - * preferred size of the actor - */ -void -clutter_texture_set_sync_size (ClutterTexture *texture, - gboolean sync_size) -{ - ClutterTexturePrivate *priv; - - g_return_if_fail (CLUTTER_IS_TEXTURE (texture)); - - priv = texture->priv; - - if (priv->sync_actor_size != sync_size) - { - priv->sync_actor_size = sync_size; - - clutter_actor_queue_relayout (CLUTTER_ACTOR (texture)); - - g_object_notify_by_pspec (G_OBJECT (texture), obj_props[PROP_SYNC_SIZE]); - } -} - -/** - * clutter_texture_get_sync_size: - * @texture: a #ClutterTexture - * - * Retrieves the value set with clutter_texture_set_sync_size() - * - * Return value: %TRUE if the #ClutterTexture should have the same - * preferred size of the underlying image data - * - * Since: 1.0 - * - * Deprecated: 1.12: There is no direct replacement - */ -gboolean -clutter_texture_get_sync_size (ClutterTexture *texture) -{ - g_return_val_if_fail (CLUTTER_IS_TEXTURE (texture), FALSE); - - return texture->priv->sync_actor_size; -} - -/** - * clutter_texture_set_repeat: - * @texture: a #ClutterTexture - * @repeat_x: %TRUE if the texture should repeat horizontally - * @repeat_y: %TRUE if the texture should repeat vertically - * - * Sets whether the @texture should repeat horizontally or - * vertically when the actor size is bigger than the image size - * - * Since: 1.0 - * - * Deprecated: 1.12: Use #ClutterImage and clutter_actor_set_content_repeat() - * instead - */ -void -clutter_texture_set_repeat (ClutterTexture *texture, - gboolean repeat_x, - gboolean repeat_y) -{ - ClutterTexturePrivate *priv; - gboolean changed = FALSE; - - g_return_if_fail (CLUTTER_IS_TEXTURE (texture)); - - priv = texture->priv; - - g_object_freeze_notify (G_OBJECT (texture)); - - if (priv->repeat_x != repeat_x) - { - priv->repeat_x = repeat_x; - - g_object_notify_by_pspec (G_OBJECT (texture), obj_props[PROP_REPEAT_X]); - - changed = TRUE; - } - - if (priv->repeat_y != repeat_y) - { - priv->repeat_y = repeat_y; - - g_object_notify_by_pspec (G_OBJECT (texture), obj_props[PROP_REPEAT_Y]); - - changed = TRUE; - } - - if (changed) - clutter_actor_queue_redraw (CLUTTER_ACTOR (texture)); - - g_object_thaw_notify (G_OBJECT (texture)); -} - -/** - * clutter_texture_get_repeat: - * @texture: a #ClutterTexture - * @repeat_x: (out): return location for the horizontal repeat - * @repeat_y: (out): return location for the vertical repeat - * - * Retrieves the horizontal and vertical repeat values set - * using clutter_texture_set_repeat() - * - * Since: 1.0 - * - * Deprecated: 1.12: Use #ClutterImage and clutter_actor_get_content_repeat() - * instead - */ -void -clutter_texture_get_repeat (ClutterTexture *texture, - gboolean *repeat_x, - gboolean *repeat_y) -{ - g_return_if_fail (CLUTTER_IS_TEXTURE (texture)); - - if (repeat_x != NULL) - *repeat_x = texture->priv->repeat_x; - - if (repeat_y != NULL) - *repeat_y = texture->priv->repeat_y; -} - -/** - * clutter_texture_set_keep_aspect_ratio: - * @texture: a #ClutterTexture - * @keep_aspect: %TRUE to maintain aspect ratio - * - * Sets whether @texture should have a preferred size maintaining - * the aspect ratio of the underlying image - * - * Since: 1.0 - * - * Deprecated: 1.12: Use #ClutterImage and clutter_actor_set_content_gravity() - * with %CLUTTER_CONTENT_GRAVITY_RESIZE_ASPECT instead - */ -void -clutter_texture_set_keep_aspect_ratio (ClutterTexture *texture, - gboolean keep_aspect) -{ - ClutterTexturePrivate *priv; - - g_return_if_fail (CLUTTER_IS_TEXTURE (texture)); - - priv = texture->priv; - - if (priv->keep_aspect_ratio != keep_aspect) - { - priv->keep_aspect_ratio = keep_aspect; - - clutter_actor_queue_relayout (CLUTTER_ACTOR (texture)); - - g_object_notify_by_pspec (G_OBJECT (texture), obj_props[PROP_KEEP_ASPECT_RATIO]); - } -} - -/** - * clutter_texture_get_keep_aspect_ratio: - * @texture: a #ClutterTexture - * - * Retrieves the value set using clutter_texture_set_keep_aspect_ratio() - * - * Return value: %TRUE if the #ClutterTexture should maintain the - * aspect ratio of the underlying image - * - * Since: 1.0 - * - * Deprecated: 1.12: Use #ClutterImage and clutter_actor_get_content_gravity() - * instead - */ -gboolean -clutter_texture_get_keep_aspect_ratio (ClutterTexture *texture) -{ - g_return_val_if_fail (CLUTTER_IS_TEXTURE (texture), FALSE); - - return texture->priv->keep_aspect_ratio; -} - -/** - * clutter_texture_set_load_async: - * @texture: a #ClutterTexture - * @load_async: %TRUE if the texture should asynchronously load data - * from a filename - * - * Sets whether @texture should use a worker thread to load the data - * from disk asynchronously. Setting @load_async to %TRUE will make - * clutter_texture_set_from_file() return immediately. - * - * See the #ClutterTexture:load-async property documentation, and - * clutter_texture_set_load_data_async(). - * - * Since: 1.0 - * - * Deprecated: 1.12: There is no direct replacement for this function. - * Use #ClutterImage and platform-specific API for loading image data - * asynchronously, like GdkPixbuf - */ -void -clutter_texture_set_load_async (ClutterTexture *texture, - gboolean load_async) -{ - ClutterTexturePrivate *priv; - - g_return_if_fail (CLUTTER_IS_TEXTURE (texture)); - - priv = texture->priv; - - load_async = !!load_async; - - if (priv->load_async_set != load_async) - { - priv->load_data_async = load_async; - priv->load_size_async = load_async; - - priv->load_async_set = load_async; - - g_object_notify_by_pspec (G_OBJECT (texture), obj_props[PROP_LOAD_ASYNC]); - g_object_notify_by_pspec (G_OBJECT (texture), obj_props[PROP_LOAD_DATA_ASYNC]); - } -} - -/** - * clutter_texture_get_load_async: - * @texture: a #ClutterTexture - * - * Retrieves the value set using clutter_texture_set_load_async() - * - * Return value: %TRUE if the #ClutterTexture should load the data from - * disk asynchronously - * - * Since: 1.0 - * - * Deprecated: 1.12: There is no direct replacement for this function - */ -gboolean -clutter_texture_get_load_async (ClutterTexture *texture) -{ - g_return_val_if_fail (CLUTTER_IS_TEXTURE (texture), FALSE); - - return texture->priv->load_async_set; -} - -/** - * clutter_texture_set_load_data_async: - * @texture: a #ClutterTexture - * @load_async: %TRUE if the texture should asynchronously load data - * from a filename - * - * Sets whether @texture should use a worker thread to load the data - * from disk asynchronously. Setting @load_async to %TRUE will make - * clutter_texture_set_from_file() block until the #ClutterTexture has - * determined the width and height of the image data. - * - * See the #ClutterTexture:load-async property documentation, and - * clutter_texture_set_load_async(). - * - * Since: 1.0 - * - * Deprecated: 1.12: There is no direct replacement for this function. - * Use #ClutterImage and platform-specific API for loading image data - * asynchronously, like GdkPixbuf - */ -void -clutter_texture_set_load_data_async (ClutterTexture *texture, - gboolean load_async) -{ - ClutterTexturePrivate *priv; - - g_return_if_fail (CLUTTER_IS_TEXTURE (texture)); - - priv = texture->priv; - - if (priv->load_data_async != load_async) - { - /* load-data-async always unsets load-size-async */ - priv->load_data_async = load_async; - priv->load_size_async = FALSE; - - priv->load_async_set = load_async; - - g_object_notify_by_pspec (G_OBJECT (texture), obj_props[PROP_LOAD_ASYNC]); - g_object_notify_by_pspec (G_OBJECT (texture), obj_props[PROP_LOAD_DATA_ASYNC]); - } -} - -/** - * clutter_texture_get_load_data_async: - * @texture: a #ClutterTexture - * - * Retrieves the value set by clutter_texture_set_load_data_async() - * - * Return value: %TRUE if the #ClutterTexture should load the image - * data from a file asynchronously - * - * Since: 1.0 - * - * Deprecated: 1.12: There is no direct replacement for this function - */ -gboolean -clutter_texture_get_load_data_async (ClutterTexture *texture) -{ - g_return_val_if_fail (CLUTTER_IS_TEXTURE (texture), FALSE); - - return texture->priv->load_async_set && - texture->priv->load_data_async; -} - -/** - * clutter_texture_set_pick_with_alpha: - * @texture: a #ClutterTexture - * @pick_with_alpha: %TRUE if the alpha channel should affect the - * picking shape - * - * Sets whether @texture should have it's shape defined by the alpha - * channel when picking. - * - * Be aware that this is a bit more costly than the default picking - * due to the texture lookup, extra test against the alpha value and - * the fact that it will also interrupt the batching of geometry done - * internally. - * - * Also there is currently no control over the threshold used to - * determine what value of alpha is considered pickable, and so only - * fully opaque parts of the texture will react to picking. - * - * Since: 1.4 - * - * Deprecated: 1.12: There is no direct replacement for this function - */ -void -clutter_texture_set_pick_with_alpha (ClutterTexture *texture, - gboolean pick_with_alpha) -{ - ClutterTexturePrivate *priv; - - g_return_if_fail (CLUTTER_IS_TEXTURE (texture)); - - priv = texture->priv; - - if (priv->pick_with_alpha == pick_with_alpha) - return; - - if (!pick_with_alpha && priv->pick_pipeline != NULL) - { - cogl_object_unref (priv->pick_pipeline); - priv->pick_pipeline = NULL; - } - - /* NB: the pick pipeline is created lazily when we first pick */ - priv->pick_with_alpha = pick_with_alpha; - - /* NB: actors are expected to call clutter_actor_queue_redraw when - * ever some state changes that will affect painting *or picking... - */ - clutter_actor_queue_redraw (CLUTTER_ACTOR (texture)); -} - -/** - * clutter_texture_get_pick_with_alpha: - * @texture: a #ClutterTexture - * - * Retrieves the value set by clutter_texture_set_load_data_async() - * - * Return value: %TRUE if the #ClutterTexture should define its shape - * using the alpha channel when picking. - * - * Since: 1.4 - * - * Deprecated: 1.12: There is no direct replacement for this function - */ -gboolean -clutter_texture_get_pick_with_alpha (ClutterTexture *texture) -{ - g_return_val_if_fail (CLUTTER_IS_TEXTURE (texture), FALSE); - - return texture->priv->pick_with_alpha ? TRUE : FALSE; -} - diff --git a/clutter/clutter/deprecated/clutter-texture.h b/clutter/clutter/deprecated/clutter-texture.h deleted file mode 100644 index 6e0494370..000000000 --- a/clutter/clutter/deprecated/clutter-texture.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * Copyright (C) 2006 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __CLUTTER_TEXTURE_DEPRECATED_H__ -#define __CLUTTER_TEXTURE_DEPRECATED_H__ - -#include - -G_BEGIN_DECLS - -CLUTTER_DEPRECATED_IN_1_12_FOR(clutter_image_new) -ClutterActor * clutter_texture_new (void); - -CLUTTER_DEPRECATED_IN_1_12_FOR(ClutterImage and platform-specific image loading) -ClutterActor * clutter_texture_new_from_file (const gchar *filename, - GError **error); - -CLUTTER_DEPRECATED_IN_1_12_FOR(ClutterImage and platform-specific image loading) -gboolean clutter_texture_set_from_file (ClutterTexture *texture, - const gchar *filename, - GError **error); -CLUTTER_DEPRECATED_IN_1_12_FOR(clutter_image_set_data) -gboolean clutter_texture_set_from_rgb_data (ClutterTexture *texture, - const guchar *data, - gboolean has_alpha, - gint width, - gint height, - gint rowstride, - gint bpp, - ClutterTextureFlags flags, - GError **error); -CLUTTER_DEPRECATED_IN_1_12_FOR(clutter_image_set_area) -gboolean clutter_texture_set_area_from_rgb_data (ClutterTexture *texture, - const guchar *data, - gboolean has_alpha, - gint x, - gint y, - gint width, - gint height, - gint rowstride, - gint bpp, - ClutterTextureFlags flags, - GError **error); -CLUTTER_DEPRECATED_IN_1_12_FOR(ClutterImage and clutter_content_get_preferred_size) -void clutter_texture_get_base_size (ClutterTexture *texture, - gint *width, - gint *height); -CLUTTER_DEPRECATED_IN_1_12_FOR(ClutterImage and clutter_actor_set_content_scaling_filters) -void clutter_texture_set_filter_quality (ClutterTexture *texture, - ClutterTextureQuality filter_quality); -CLUTTER_DEPRECATED_IN_1_12_FOR(ClutterImage and clutter_actor_get_content_scaling_filters) -ClutterTextureQuality clutter_texture_get_filter_quality (ClutterTexture *texture); -CLUTTER_DEPRECATED_IN_1_12 -CoglHandle clutter_texture_get_cogl_texture (ClutterTexture *texture); -CLUTTER_DEPRECATED_IN_1_12 -void clutter_texture_set_cogl_texture (ClutterTexture *texture, - CoglHandle cogl_tex); -CLUTTER_DEPRECATED_IN_1_12 -CoglHandle clutter_texture_get_cogl_material (ClutterTexture *texture); -CLUTTER_DEPRECATED_IN_1_12 -void clutter_texture_set_cogl_material (ClutterTexture *texture, - CoglHandle cogl_material); -CLUTTER_DEPRECATED_IN_1_12 -void clutter_texture_set_sync_size (ClutterTexture *texture, - gboolean sync_size); -CLUTTER_DEPRECATED_IN_1_12 -gboolean clutter_texture_get_sync_size (ClutterTexture *texture); -CLUTTER_DEPRECATED_IN_1_12_FOR(ClutterImage and clutter_actor_set_content_repeat) -void clutter_texture_set_repeat (ClutterTexture *texture, - gboolean repeat_x, - gboolean repeat_y); -CLUTTER_DEPRECATED_IN_1_12_FOR(ClutterImage and clutter_actor_get_content_repeat) -void clutter_texture_get_repeat (ClutterTexture *texture, - gboolean *repeat_x, - gboolean *repeat_y); -CLUTTER_DEPRECATED_IN_1_12 -gint clutter_texture_get_max_tile_waste (ClutterTexture *texture); -CLUTTER_DEPRECATED_IN_1_12_FOR(ClutterImage and clutter_actor_set_content_gravity) -void clutter_texture_set_keep_aspect_ratio (ClutterTexture *texture, - gboolean keep_aspect); -CLUTTER_DEPRECATED_IN_1_12_FOR(ClutterImage and clutter_actor_get_content_gravity) -gboolean clutter_texture_get_keep_aspect_ratio (ClutterTexture *texture); -CLUTTER_DEPRECATED_IN_1_12 -void clutter_texture_set_load_async (ClutterTexture *texture, - gboolean load_async); -CLUTTER_DEPRECATED_IN_1_12 -gboolean clutter_texture_get_load_async (ClutterTexture *texture); -CLUTTER_DEPRECATED_IN_1_12 -void clutter_texture_set_load_data_async (ClutterTexture *texture, - gboolean load_async); -CLUTTER_DEPRECATED_IN_1_12 -gboolean clutter_texture_get_load_data_async (ClutterTexture *texture); -CLUTTER_DEPRECATED_IN_1_12 -void clutter_texture_set_pick_with_alpha (ClutterTexture *texture, - gboolean pick_with_alpha); -CLUTTER_DEPRECATED_IN_1_12 -gboolean clutter_texture_get_pick_with_alpha (ClutterTexture *texture); - -CLUTTER_DEPRECATED_IN_1_8_FOR(ClutterOffscreenEffect) -ClutterActor * clutter_texture_new_from_actor (ClutterActor *actor); - -CLUTTER_DEPRECATED_IN_1_10 -gboolean clutter_texture_set_from_yuv_data (ClutterTexture *texture, - const guchar *data, - gint width, - gint height, - ClutterTextureFlags flags, - GError **error); - -G_END_DECLS - -#endif /* __CLUTTER_TEXTURE_DEPRECATED_H__ */ diff --git a/clutter/clutter/deprecated/clutter-timeline.h b/clutter/clutter/deprecated/clutter-timeline.h index e99c7df39..950362e90 100644 --- a/clutter/clutter/deprecated/clutter-timeline.h +++ b/clutter/clutter/deprecated/clutter-timeline.h @@ -26,14 +26,14 @@ G_BEGIN_DECLS -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_timeline_new) +CLUTTER_DEPRECATED_FOR(clutter_timeline_new) ClutterTimeline * clutter_timeline_clone (ClutterTimeline *timeline); -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_timeline_set_repeat_count) +CLUTTER_DEPRECATED_FOR(clutter_timeline_set_repeat_count) void clutter_timeline_set_loop (ClutterTimeline *timeline, gboolean loop); -CLUTTER_DEPRECATED_IN_1_10_FOR(clutter_timeline_get_repeat_count) +CLUTTER_DEPRECATED_FOR(clutter_timeline_get_repeat_count) gboolean clutter_timeline_get_loop (ClutterTimeline *timeline); G_END_DECLS diff --git a/clutter/clutter/deprecated/clutter-timeout-interval.c b/clutter/clutter/deprecated/clutter-timeout-interval.c deleted file mode 100644 index bb9f141cc..000000000 --- a/clutter/clutter/deprecated/clutter-timeout-interval.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Neil Roberts - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#ifdef HAVE_CONFIG_H -#include "clutter-build-config.h" -#endif - -#define CLUTTER_DISABLE_DEPRECATION_WARNINGS - -/* This file contains the common code to check whether an interval has - expired used in clutter-frame-source and clutter-timeout-pool. */ - -#include "clutter-timeout-interval.h" - -void -_clutter_timeout_interval_init (ClutterTimeoutInterval *interval, - guint fps) -{ -#if GLIB_CHECK_VERSION (2, 27, 3) - interval->start_time = g_get_monotonic_time () / 1000; -#else - { - GTimeVal start_time; - g_get_current_time (&start_time); - interval->start_time = start_time.tv_sec * 1000 - + start_time.tv_usec / 1000; - } -#endif - - interval->fps = fps; - interval->frame_count = 0; -} - -static gint64 -_clutter_timeout_interval_get_ticks (gint64 current_time, - ClutterTimeoutInterval *interval) -{ - return MAX (current_time - interval->start_time, 0); -} - -gboolean -_clutter_timeout_interval_prepare (gint64 current_time, - ClutterTimeoutInterval *interval, - gint *delay) -{ - gint elapsed_time, new_frame_num; - - elapsed_time = _clutter_timeout_interval_get_ticks (current_time, interval); - new_frame_num = elapsed_time * interval->fps / 1000; - - /* If time has gone backwards or the time since the last frame is - greater than the two frames worth then reset the time and do a - frame now */ - if (new_frame_num < interval->frame_count || - new_frame_num - interval->frame_count > 2) - { - /* Get the frame time rounded up to the nearest ms */ - guint frame_time = (1000 + interval->fps - 1) / interval->fps; - - /* Reset the start time */ - interval->start_time = current_time; - - /* Move the start time as if one whole frame has elapsed */ - interval->start_time -= frame_time; - - interval->frame_count = 0; - - if (delay) - *delay = 0; - - return TRUE; - } - else if (new_frame_num > interval->frame_count) - { - if (delay) - *delay = 0; - - return TRUE; - } - else - { - if (delay) - *delay = ((interval->frame_count + 1) * 1000 / interval->fps - - elapsed_time); - - return FALSE; - } -} - -gboolean -_clutter_timeout_interval_dispatch (ClutterTimeoutInterval *interval, - GSourceFunc callback, - gpointer user_data) -{ - if ((* callback) (user_data)) - { - interval->frame_count++; - - return TRUE; - } - - return FALSE; -} - -gint -_clutter_timeout_interval_compare_expiration (const ClutterTimeoutInterval *a, - const ClutterTimeoutInterval *b) -{ - guint a_delay = 1000 / a->fps; - guint b_delay = 1000 / b->fps; - gint64 b_difference; - gint comparison; - - b_difference = a->start_time - b->start_time; - - comparison = ((gint) ((a->frame_count + 1) * a_delay) - - (gint) ((b->frame_count + 1) * b_delay + b_difference)); - - return (comparison < 0 ? -1 - : comparison > 0 ? 1 - : 0); -} diff --git a/clutter/clutter/deprecated/clutter-timeout-interval.h b/clutter/clutter/deprecated/clutter-timeout-interval.h deleted file mode 100644 index 57df959a8..000000000 --- a/clutter/clutter/deprecated/clutter-timeout-interval.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Neil Roberts - * - * Copyright (C) 2009 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#ifndef __CLUTTER_TIMEOUT_INTERVAL_H__ -#define __CLUTTER_TIMEOUT_INTERVAL_H__ - -#include - -G_BEGIN_DECLS - -typedef struct _ClutterTimeoutInterval ClutterTimeoutInterval; - -struct _ClutterTimeoutInterval -{ - /* milliseconds */ - gint64 start_time; - - guint frame_count; - guint fps; -}; - -void _clutter_timeout_interval_init (ClutterTimeoutInterval *interval, - guint fps); - -gboolean _clutter_timeout_interval_prepare (gint64 current_time, - ClutterTimeoutInterval *interval, - gint *delay); - -gboolean _clutter_timeout_interval_dispatch (ClutterTimeoutInterval *interval, - GSourceFunc callback, - gpointer user_data); - -gint _clutter_timeout_interval_compare_expiration (const ClutterTimeoutInterval *a, - const ClutterTimeoutInterval *b); - -G_END_DECLS - -#endif /* __CLUTTER_TIMEOUT_INTERVAL_H__ */ diff --git a/clutter/clutter/deprecated/clutter-timeout-pool.c b/clutter/clutter/deprecated/clutter-timeout-pool.c deleted file mode 100644 index 21b3543da..000000000 --- a/clutter/clutter/deprecated/clutter-timeout-pool.c +++ /dev/null @@ -1,500 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * Copyright (C) 2006 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - * - * ClutterTimeoutPool: pool of timeout functions using the same slice of - * the GLib main loop - * - * Author: Emmanuele Bassi - * - * Based on similar code by Tristan van Berkom - */ - -#ifdef HAVE_CONFIG_H -#include "clutter-build-config.h" -#endif - -#define CLUTTER_DISABLE_DEPRECATION_WARNINGS -#include "deprecated/clutter-main.h" - -#include "clutter-timeout-pool.h" - -#include "clutter-debug.h" -#include "clutter-timeout-interval.h" - -typedef struct _ClutterTimeout ClutterTimeout; -typedef enum { - CLUTTER_TIMEOUT_NONE = 0, - CLUTTER_TIMEOUT_READY = 1 << 1 -} ClutterTimeoutFlags; - -struct _ClutterTimeout -{ - guint id; - ClutterTimeoutFlags flags; - gint refcount; - - ClutterTimeoutInterval interval; - - GSourceFunc func; - gpointer data; - GDestroyNotify notify; -}; - -struct _ClutterTimeoutPool -{ - GSource source; - - guint next_id; - - GList *timeouts; - GList *dispatched_timeouts; - - gint ready; - - guint id; -}; - -#define TIMEOUT_READY(timeout) (timeout->flags & CLUTTER_TIMEOUT_READY) - -static gboolean clutter_timeout_pool_prepare (GSource *source, - gint *next_timeout); -static gboolean clutter_timeout_pool_check (GSource *source); -static gboolean clutter_timeout_pool_dispatch (GSource *source, - GSourceFunc callback, - gpointer data); -static void clutter_timeout_pool_finalize (GSource *source); - -static GSourceFuncs clutter_timeout_pool_funcs = -{ - clutter_timeout_pool_prepare, - clutter_timeout_pool_check, - clutter_timeout_pool_dispatch, - clutter_timeout_pool_finalize -}; - -static gint -clutter_timeout_sort (gconstpointer a, - gconstpointer b) -{ - const ClutterTimeout *t_a = a; - const ClutterTimeout *t_b = b; - - /* Keep 'ready' timeouts at the front */ - if (TIMEOUT_READY (t_a)) - return -1; - - if (TIMEOUT_READY (t_b)) - return 1; - - return _clutter_timeout_interval_compare_expiration (&t_a->interval, - &t_b->interval); -} - -static gint -clutter_timeout_find_by_id (gconstpointer a, - gconstpointer b) -{ - const ClutterTimeout *t_a = a; - - return t_a->id == GPOINTER_TO_UINT (b) ? 0 : 1; -} - -static ClutterTimeout * -clutter_timeout_new (guint fps) -{ - ClutterTimeout *timeout; - - timeout = g_slice_new0 (ClutterTimeout); - _clutter_timeout_interval_init (&timeout->interval, fps); - timeout->flags = CLUTTER_TIMEOUT_NONE; - timeout->refcount = 1; - - return timeout; -} - -static gboolean -clutter_timeout_prepare (ClutterTimeoutPool *pool, - ClutterTimeout *timeout, - gint *next_timeout) -{ - GSource *source = (GSource *) pool; - gint64 now; - -#if GLIB_CHECK_VERSION (2, 27, 3) - now = g_source_get_time (source) / 1000; -#else - { - GTimeVal source_time; - g_source_get_current_time (source, &source_time); - now = source_time.tv_sec * 1000 + source_time.tv_usec / 1000; - } -#endif - - return _clutter_timeout_interval_prepare (now, - &timeout->interval, - next_timeout); -} - -/* ref and unref are always called under the main Clutter lock, so there - * is not need for us to use g_atomic_int_* API. - */ - -static ClutterTimeout * -clutter_timeout_ref (ClutterTimeout *timeout) -{ - g_return_val_if_fail (timeout != NULL, timeout); - g_return_val_if_fail (timeout->refcount > 0, timeout); - - timeout->refcount += 1; - - return timeout; -} - -static void -clutter_timeout_unref (ClutterTimeout *timeout) -{ - g_return_if_fail (timeout != NULL); - g_return_if_fail (timeout->refcount > 0); - - timeout->refcount -= 1; - - if (timeout->refcount == 0) - { - if (timeout->notify) - timeout->notify (timeout->data); - - g_slice_free (ClutterTimeout, timeout); - } -} - -static void -clutter_timeout_free (ClutterTimeout *timeout) -{ - if (G_LIKELY (timeout)) - { - if (timeout->notify) - timeout->notify (timeout->data); - - g_slice_free (ClutterTimeout, timeout); - } -} - -static gboolean -clutter_timeout_pool_prepare (GSource *source, - gint *next_timeout) -{ - ClutterTimeoutPool *pool = (ClutterTimeoutPool *) source; - GList *l = pool->timeouts; - - /* the pool is ready if the first timeout is ready */ - if (l && l->data) - { - ClutterTimeout *timeout = l->data; - return clutter_timeout_prepare (pool, timeout, next_timeout); - } - else - { - *next_timeout = -1; - return FALSE; - } -} - -static gboolean -clutter_timeout_pool_check (GSource *source) -{ - ClutterTimeoutPool *pool = (ClutterTimeoutPool *) source; - GList *l; - - clutter_threads_enter (); - - for (l = pool->timeouts; l; l = l->next) - { - ClutterTimeout *timeout = l->data; - - /* since the timeouts are sorted by expiration, as soon - * as we get a check returning FALSE we know that the - * following timeouts are not expiring, so we break as - * soon as possible - */ - if (clutter_timeout_prepare (pool, timeout, NULL)) - { - timeout->flags |= CLUTTER_TIMEOUT_READY; - pool->ready += 1; - } - else - break; - } - - clutter_threads_leave (); - - return (pool->ready > 0); -} - -static gboolean -clutter_timeout_pool_dispatch (GSource *source, - GSourceFunc func, - gpointer data) -{ - ClutterTimeoutPool *pool = (ClutterTimeoutPool *) source; - GList *dispatched_timeouts; - - /* the main loop might have predicted this, so we repeat the - * check for ready timeouts. - */ - if (!pool->ready) - clutter_timeout_pool_check (source); - - clutter_threads_enter (); - - /* Iterate by moving the actual start of the list along so that it - * can cope with adds and removes while a timeout is being dispatched - */ - while (pool->timeouts && pool->timeouts->data && pool->ready-- > 0) - { - ClutterTimeout *timeout = pool->timeouts->data; - GList *l; - - /* One of the ready timeouts may have been removed during dispatch, - * in which case pool->ready will be wrong, but the ready timeouts - * are always kept at the start of the list so we can stop once - * we've reached the first non-ready timeout - */ - if (!(TIMEOUT_READY (timeout))) - break; - - /* Add a reference to the timeout so it can't disappear - * while it's being dispatched - */ - clutter_timeout_ref (timeout); - - timeout->flags &= ~CLUTTER_TIMEOUT_READY; - - /* Move the list node to a list of dispatched timeouts */ - l = pool->timeouts; - if (l->next) - l->next->prev = NULL; - - pool->timeouts = l->next; - - if (pool->dispatched_timeouts) - pool->dispatched_timeouts->prev = l; - - l->prev = NULL; - l->next = pool->dispatched_timeouts; - pool->dispatched_timeouts = l; - - if (!_clutter_timeout_interval_dispatch (&timeout->interval, - timeout->func, timeout->data)) - { - /* The timeout may have already been removed, but nothing - * can be added to the dispatched_timeout list except in this - * function so it will always either be at the head of the - * dispatched list or have been removed - */ - if (pool->dispatched_timeouts && - pool->dispatched_timeouts->data == timeout) - { - pool->dispatched_timeouts = - g_list_delete_link (pool->dispatched_timeouts, - pool->dispatched_timeouts); - - /* Remove the reference that was held by it being in the list */ - clutter_timeout_unref (timeout); - } - } - - clutter_timeout_unref (timeout); - } - - /* Re-insert the dispatched timeouts in sorted order */ - dispatched_timeouts = pool->dispatched_timeouts; - while (dispatched_timeouts) - { - ClutterTimeout *timeout = dispatched_timeouts->data; - GList *next = dispatched_timeouts->next; - - if (timeout) - pool->timeouts = g_list_insert_sorted (pool->timeouts, timeout, - clutter_timeout_sort); - - dispatched_timeouts = next; - } - - g_list_free (pool->dispatched_timeouts); - pool->dispatched_timeouts = NULL; - - pool->ready = 0; - - clutter_threads_leave (); - - return TRUE; -} - -static void -clutter_timeout_pool_finalize (GSource *source) -{ - ClutterTimeoutPool *pool = (ClutterTimeoutPool *) source; - - /* force destruction */ - g_list_foreach (pool->timeouts, (GFunc) clutter_timeout_free, NULL); - g_list_free (pool->timeouts); -} - -/** - * clutter_timeout_pool_new: - * @priority: the priority of the timeout pool. Typically this will - * be #G_PRIORITY_DEFAULT - * - * Creates a new timeout pool source. A timeout pool should be used when - * multiple timeout functions, running at the same priority, are needed and - * the g_timeout_add() API might lead to starvation of the time slice of - * the main loop. A timeout pool allocates a single time slice of the main - * loop and runs every timeout function inside it. The timeout pool is - * always sorted, so that the extraction of the next timeout function is - * a constant time operation. - * - * Return value: the newly created #ClutterTimeoutPool. The created pool - * is owned by the GLib default context and will be automatically - * destroyed when the context is destroyed. It is possible to force - * the destruction of the timeout pool using g_source_destroy() - * - * Since: 0.4 - * - * Deprecated: 1.6: There is no direct replacement for this API - */ -ClutterTimeoutPool * -clutter_timeout_pool_new (gint priority) -{ - ClutterTimeoutPool *pool; - GSource *source; - - source = g_source_new (&clutter_timeout_pool_funcs, - sizeof (ClutterTimeoutPool)); - if (!source) - return NULL; - - g_source_set_name (source, "Clutter timeout pool"); - - if (priority != G_PRIORITY_DEFAULT) - g_source_set_priority (source, priority); - - pool = (ClutterTimeoutPool *) source; - pool->next_id = 1; - pool->id = g_source_attach (source, NULL); - - /* let the default GLib context manage the pool */ - g_source_unref (source); - - return pool; -} - -/** - * clutter_timeout_pool_add: - * @pool: a #ClutterTimeoutPool - * @fps: the time between calls to the function, in frames per second - * @func: function to call - * @data: (closure): data to pass to the function, or %NULL - * @notify: function to call when the timeout is removed, or %NULL - * - * Sets a function to be called at regular intervals, and puts it inside - * the @pool. The function is repeatedly called until it returns %FALSE, - * at which point the timeout is automatically destroyed and the function - * won't be called again. If @notify is not %NULL, the @notify function - * will be called. The first call to @func will be at the end of @interval. - * - * Since Clutter 0.8 this will try to compensate for delays. For - * example, if @func takes half the interval time to execute then the - * function will be called again half the interval time after it - * finished. Before version 0.8 it would not fire until a full - * interval after the function completes so the delay between calls - * would be @interval * 1.5. This function does not however try to - * invoke the function multiple times to catch up missing frames if - * @func takes more than @interval ms to execute. - * - * Return value: the ID (greater than 0) of the timeout inside the pool. - * Use clutter_timeout_pool_remove() to stop the timeout. - * - * Since: 0.4 - * - * Deprecated: 1.6: There is no direct replacement for this API - */ -guint -clutter_timeout_pool_add (ClutterTimeoutPool *pool, - guint fps, - GSourceFunc func, - gpointer data, - GDestroyNotify notify) -{ - ClutterTimeout *timeout; - guint retval = 0; - - timeout = clutter_timeout_new (fps); - - retval = timeout->id = pool->next_id++; - - timeout->func = func; - timeout->data = data; - timeout->notify = notify; - - pool->timeouts = g_list_insert_sorted (pool->timeouts, timeout, - clutter_timeout_sort); - - return retval; -} - -/** - * clutter_timeout_pool_remove: - * @pool: a #ClutterTimeoutPool - * @id_: the id of the timeout to remove - * - * Removes a timeout function with @id_ from the timeout pool. The id - * is the same returned when adding a function to the timeout pool with - * clutter_timeout_pool_add(). - * - * Since: 0.4 - * - * Deprecated: 1.6: There is no direct replacement for this API - */ -void -clutter_timeout_pool_remove (ClutterTimeoutPool *pool, - guint id_) -{ - GList *l; - - if ((l = g_list_find_custom (pool->timeouts, GUINT_TO_POINTER (id_), - clutter_timeout_find_by_id))) - { - clutter_timeout_unref (l->data); - pool->timeouts = g_list_delete_link (pool->timeouts, l); - } - else if ((l = g_list_find_custom (pool->dispatched_timeouts, - GUINT_TO_POINTER (id_), - clutter_timeout_find_by_id))) - { - clutter_timeout_unref (l->data); - - pool->dispatched_timeouts = - g_list_delete_link (pool->dispatched_timeouts, l); - } -} diff --git a/clutter/clutter/deprecated/clutter-timeout-pool.h b/clutter/clutter/deprecated/clutter-timeout-pool.h deleted file mode 100644 index 61780e546..000000000 --- a/clutter/clutter/deprecated/clutter-timeout-pool.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * Copyright (C) 2006 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * ClutterTimeoutPool: pool of timeout functions using the same slice of - * the GLib main loop - * - * Author: Emmanuele Bassi - * - * Based on similar code by Tristan van Berkom - */ - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __CLUTTER_TIMEOUT_POOL_H__ -#define __CLUTTER_TIMEOUT_POOL_H__ - -#include - -G_BEGIN_DECLS - -/** - * ClutterTimeoutPool: (skip) - * - * #ClutterTimeoutPool is an opaque structure - * whose members cannot be directly accessed. - * - * Since: 0.6 - * - * Deprecated: 1.6 - */ -typedef struct _ClutterTimeoutPool ClutterTimeoutPool; - -CLUTTER_DEPRECATED_IN_1_6 -ClutterTimeoutPool *clutter_timeout_pool_new (gint priority); - -CLUTTER_DEPRECATED_IN_1_6 -guint clutter_timeout_pool_add (ClutterTimeoutPool *pool, - guint fps, - GSourceFunc func, - gpointer data, - GDestroyNotify notify); -CLUTTER_DEPRECATED_IN_1_6 -void clutter_timeout_pool_remove (ClutterTimeoutPool *pool, - guint id_); - -G_END_DECLS - -#endif /* __CLUTTER_TIMEOUT_POOL_H__ */ diff --git a/clutter/clutter/egl/clutter-backend-eglnative.c b/clutter/clutter/egl/clutter-backend-eglnative.c index f22246939..8aa959cae 100644 --- a/clutter/clutter/egl/clutter-backend-eglnative.c +++ b/clutter/clutter/egl/clutter-backend-eglnative.c @@ -40,10 +40,6 @@ /* This is a Cogl based backend */ #include "cogl/clutter-stage-cogl.h" -#ifdef HAVE_EVDEV -#include "evdev/clutter-device-manager-evdev.h" -#endif - #include "clutter-debug.h" #include "clutter-private.h" #include "clutter-main.h" @@ -237,7 +233,7 @@ clutter_backend_egl_native_init (ClutterBackendEglNative *backend_egl_native) GSettingsSchemaSource *source = g_settings_schema_source_get_default (); GSettingsSchema *schema = g_settings_schema_source_lookup (source, xsettings_path, - FALSE); + TRUE); if (!schema) { @@ -264,40 +260,6 @@ clutter_backend_egl_native_new (void) return g_object_new (CLUTTER_TYPE_BACKEND_EGL_NATIVE, NULL); } -/** - * clutter_eglx_display: - * - * Retrieves the EGL display used by Clutter. - * - * Return value: the EGL display, or 0 - * - * Since: 0.6 - * - * Deprecated: 1.6: Use clutter_egl_get_egl_display() instead. - */ -EGLDisplay -clutter_eglx_display (void) -{ - return clutter_egl_get_egl_display (); -} - -/** - * clutter_egl_display: - * - * Retrieves the EGL display used by Clutter. - * - * Return value: the EGL display used by Clutter, or 0 - * - * Since: 0.6 - * - * Deprecated: 1.6: Use clutter_egl_get_egl_display() instead. - */ -EGLDisplay -clutter_egl_display (void) -{ - return clutter_egl_get_egl_display (); -} - /** * clutter_egl_get_egl_display: * @@ -327,63 +289,9 @@ clutter_egl_get_egl_display (void) return 0; } -#if COGL_HAS_EGL_SUPPORT +#ifdef COGL_HAS_EGL_SUPPORT return cogl_egl_context_get_egl_display (backend->cogl_context); #else return 0; #endif } - -/** - * clutter_egl_freeze_master_clock: - * - * Freezing the master clock makes Clutter stop processing events, - * redrawing, and advancing timelines. This is necessary when implementing - * a display server, to ensure that Clutter doesn't keep trying to page - * flip when DRM master has been dropped, e.g. when VT switched away. - * - * The master clock starts out running, so if you are VT switched away on - * startup, you need to call this immediately. - * - * If you're also using the evdev backend, make sure to also use - * clutter_evdev_release_devices() to make sure that Clutter doesn't also - * access revoked evdev devices when VT switched away. - * - * To unthaw a frozen master clock, use clutter_egl_thaw_master_clock(). - * - * Since: 1.20 - */ -void -clutter_egl_freeze_master_clock (void) -{ - ClutterMasterClock *master_clock; - - g_return_if_fail (CLUTTER_IS_BACKEND_EGL_NATIVE (clutter_get_default_backend ())); - - master_clock = _clutter_master_clock_get_default (); - _clutter_master_clock_set_paused (master_clock, TRUE); -} - -/** - * clutter_egl_thaw_master_clock: - * - * Thaws a master clock that has previously been frozen with - * clutter_egl_freeze_master_clock(), and start pumping the master clock - * again at the next iteration. Note that if you're switching back to your - * own VT, you should probably also queue a stage redraw with - * clutter_stage_ensure_redraw(). - * - * Since: 1.20 - */ -void -clutter_egl_thaw_master_clock (void) -{ - ClutterMasterClock *master_clock; - - g_return_if_fail (CLUTTER_IS_BACKEND_EGL_NATIVE (clutter_get_default_backend ())); - - master_clock = _clutter_master_clock_get_default (); - _clutter_master_clock_set_paused (master_clock, FALSE); - - _clutter_master_clock_start_running (master_clock); -} diff --git a/clutter/clutter/egl/clutter-backend-eglnative.h b/clutter/clutter/egl/clutter-backend-eglnative.h index 2ccc43d95..cc63f89b3 100644 --- a/clutter/clutter/egl/clutter-backend-eglnative.h +++ b/clutter/clutter/egl/clutter-backend-eglnative.h @@ -27,11 +27,11 @@ #define __CLUTTER_BACKEND_EGL_NATIVE_H__ #include +#include #include #include #include #include -#include #include "clutter-backend-private.h" @@ -53,9 +53,6 @@ struct _ClutterBackendEglNative { ClutterBackend parent_instance; - /* device manager (ie evdev) */ - ClutterDeviceManager *device_manager; - /* event source */ GSource *event_source; @@ -71,7 +68,7 @@ struct _ClutterBackendEglNativeClass ClutterBackendClass parent_class; }; -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT GType clutter_backend_egl_native_get_type (void) G_GNUC_CONST; ClutterBackend *clutter_backend_egl_native_new (void); diff --git a/clutter/clutter/egl/clutter-egl-headers.h b/clutter/clutter/egl/clutter-egl-headers.h index d7b2f3ff9..9ab3d6a54 100644 --- a/clutter/clutter/egl/clutter-egl-headers.h +++ b/clutter/clutter/egl/clutter-egl-headers.h @@ -27,15 +27,6 @@ * header. */ #include - -/* Since Cogl 1.11.2, the EGL headers are no longer included from - * cogl.h when the experimental 2.0 API is requested. Clutter requests - * this in its configure script so we need to switch the header we - * include in that case. COGL_VERSION_CHECK is also new in 1.11.2 */ -#ifdef COGL_VERSION_CHECK -#if COGL_VERSION_CHECK (1, 11, 2) #include -#endif -#endif #endif /* __CLUTTER_EGL_HEADERS_H__ */ diff --git a/clutter/clutter/egl/clutter-egl.h b/clutter/clutter/egl/clutter-egl.h index 83b021343..8258cbec4 100644 --- a/clutter/clutter/egl/clutter-egl.h +++ b/clutter/clutter/egl/clutter-egl.h @@ -37,44 +37,11 @@ #include -#ifdef COGL_HAS_XLIB_SUPPORT -#include -#include -#include -#endif - #include "clutter-egl-headers.h" #include G_BEGIN_DECLS -/** - * clutter_eglx_display: - * - * Retrieves the #EGLDisplay used by Clutter, - * if Clutter has been compiled with EGL and X11 support. - * - * Return value: the EGL display - * - * Since: 0.4 - * - * Deprecated: 1.6: Use clutter_egl_get_egl_display() instead - */ -CLUTTER_DEPRECATED_FOR(clutter_egl_get_egl_display) -EGLDisplay clutter_eglx_display (void); - -/** - * clutter_egl_display: - * - * Retrieves the #EGLDisplay used by Clutter - * - * Return value: the EGL display - * - * Deprecated: 1.6: Use clutter_egl_get_egl_display() instead - */ -CLUTTER_DEPRECATED_FOR(clutter_egl_get_egl_display) -EGLDisplay clutter_egl_display (void); - /** * clutter_egl_get_egl_display: * @@ -84,19 +51,9 @@ EGLDisplay clutter_egl_display (void); * * Since: 1.6 */ -CLUTTER_AVAILABLE_IN_1_6 +CLUTTER_EXPORT EGLDisplay clutter_egl_get_egl_display (void); -#ifdef COGL_HAS_EGL_PLATFORM_KMS_SUPPORT -CLUTTER_AVAILABLE_IN_1_18 -void clutter_egl_set_kms_fd (int fd); -#endif - -CLUTTER_AVAILABLE_IN_1_20 -void clutter_egl_freeze_master_clock (void); -CLUTTER_AVAILABLE_IN_1_20 -void clutter_egl_thaw_master_clock (void); - G_END_DECLS #endif /* __CLUTTER_EGL_H__ */ diff --git a/clutter/clutter/evdev/clutter-device-manager-evdev.c b/clutter/clutter/evdev/clutter-device-manager-evdev.c deleted file mode 100644 index 7daaf3134..000000000 --- a/clutter/clutter/evdev/clutter-device-manager-evdev.c +++ /dev/null @@ -1,2747 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corp. - * Copyright (C) 2014 Jonas Ådahl - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Damien Lespiau - * Author: Jonas Ådahl - */ - -#ifdef HAVE_CONFIG_H -#include "clutter-build-config.h" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "clutter-backend.h" -#include "clutter-debug.h" -#include "clutter-device-manager.h" -#include "clutter-device-manager-private.h" -#include "clutter-event-private.h" -#include "clutter-input-device-evdev.h" -#include "clutter-seat-evdev.h" -#include "clutter-virtual-input-device-evdev.h" -#include "clutter-main.h" -#include "clutter-private.h" -#include "clutter-stage-manager.h" -#include "clutter-xkb-utils.h" -#include "clutter-backend-private.h" -#include "clutter-evdev.h" -#include "clutter-stage-private.h" -#include "clutter-input-device-tool-evdev.h" - -#include "clutter-device-manager-evdev.h" - -/* - * Clutter makes the assumption that two core devices have ID's 2 and 3 (core - * pointer and core keyboard). - * - * Since the two first devices that will ever be created will be the virtual - * pointer and virtual keyboard of the first seat, we fulfill the made - * assumptions by having the first device having ID 2 and following 3. - */ -#define INITIAL_DEVICE_ID 2 - -typedef struct _ClutterEventFilter ClutterEventFilter; - -struct _ClutterEventFilter -{ - ClutterEvdevFilterFunc func; - gpointer data; - GDestroyNotify destroy_notify; -}; - -typedef struct _ClutterEventSource ClutterEventSource; - -struct _ClutterDeviceManagerEvdevPrivate -{ - struct libinput *libinput; - - ClutterStage *stage; - gboolean released; - - ClutterEventSource *event_source; - - GSList *devices; - GSList *seats; - - ClutterSeatEvdev *main_seat; - struct xkb_keymap *keymap; - - ClutterPointerConstrainCallback constrain_callback; - gpointer constrain_data; - GDestroyNotify constrain_data_notify; - - ClutterRelativeMotionFilter relative_motion_filter; - gpointer relative_motion_filter_user_data; - - ClutterStageManager *stage_manager; - guint stage_added_handler; - guint stage_removed_handler; - - GSList *event_filters; - - gint device_id_next; - GList *free_device_ids; -}; - -static void clutter_device_manager_evdev_event_extender_init (ClutterEventExtenderInterface *iface); - -G_DEFINE_TYPE_WITH_CODE (ClutterDeviceManagerEvdev, - clutter_device_manager_evdev, - CLUTTER_TYPE_DEVICE_MANAGER, - G_ADD_PRIVATE (ClutterDeviceManagerEvdev) - G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_EVENT_EXTENDER, - clutter_device_manager_evdev_event_extender_init)) - -static ClutterOpenDeviceCallback device_open_callback; -static ClutterCloseDeviceCallback device_close_callback; -static gpointer device_callback_data; -static gchar * evdev_seat_id; - -#ifdef CLUTTER_ENABLE_DEBUG -static const char *device_type_str[] = { - "pointer", /* CLUTTER_POINTER_DEVICE */ - "keyboard", /* CLUTTER_KEYBOARD_DEVICE */ - "extension", /* CLUTTER_EXTENSION_DEVICE */ - "joystick", /* CLUTTER_JOYSTICK_DEVICE */ - "tablet", /* CLUTTER_TABLET_DEVICE */ - "touchpad", /* CLUTTER_TOUCHPAD_DEVICE */ - "touchscreen", /* CLUTTER_TOUCHSCREEN_DEVICE */ - "pen", /* CLUTTER_PEN_DEVICE */ - "eraser", /* CLUTTER_ERASER_DEVICE */ - "cursor", /* CLUTTER_CURSOR_DEVICE */ - "pad", /* CLUTTER_PAD_DEVICE */ -}; -#endif /* CLUTTER_ENABLE_DEBUG */ - -/* - * ClutterEventSource management - * - * The device manager is responsible for managing the GSource when devices - * appear and disappear from the system. - */ - -static const char *option_xkb_layout = "us"; -static const char *option_xkb_variant = ""; -static const char *option_xkb_options = ""; - -static void -clutter_device_manager_evdev_copy_event_data (ClutterEventExtender *event_extender, - const ClutterEvent *src, - ClutterEvent *dest) -{ - ClutterEventEvdev *event_evdev; - - event_evdev = _clutter_event_get_platform_data (src); - if (event_evdev != NULL) - _clutter_event_set_platform_data (dest, _clutter_event_evdev_copy (event_evdev)); -} - -static void -clutter_device_manager_evdev_free_event_data (ClutterEventExtender *event_extender, - ClutterEvent *event) -{ - ClutterEventEvdev *event_evdev; - - event_evdev = _clutter_event_get_platform_data (event); - if (event_evdev != NULL) - _clutter_event_evdev_free (event_evdev); -} - -static void -clutter_device_manager_evdev_event_extender_init (ClutterEventExtenderInterface *iface) -{ - iface->copy_event_data = clutter_device_manager_evdev_copy_event_data; - iface->free_event_data = clutter_device_manager_evdev_free_event_data; -} - -/* - * ClutterEventSource for reading input devices - */ - -struct _ClutterEventSource -{ - GSource source; - - ClutterDeviceManagerEvdev *manager_evdev; - GPollFD event_poll_fd; -}; - -static void -process_events (ClutterDeviceManagerEvdev *manager_evdev); - -static gboolean -clutter_event_prepare (GSource *source, - gint *timeout) -{ - gboolean retval; - - _clutter_threads_acquire_lock (); - - *timeout = -1; - retval = clutter_events_pending (); - - _clutter_threads_release_lock (); - - return retval; -} - -static gboolean -clutter_event_check (GSource *source) -{ - ClutterEventSource *event_source = (ClutterEventSource *) source; - gboolean retval; - - _clutter_threads_acquire_lock (); - - retval = ((event_source->event_poll_fd.revents & G_IO_IN) || - clutter_events_pending ()); - - _clutter_threads_release_lock (); - - return retval; -} - -static void -queue_event (ClutterEvent *event) -{ - _clutter_event_push (event, FALSE); -} - -void -_clutter_device_manager_evdev_constrain_pointer (ClutterDeviceManagerEvdev *manager_evdev, - ClutterInputDevice *core_pointer, - uint64_t time_us, - float x, - float y, - float *new_x, - float *new_y) -{ - if (manager_evdev->priv->constrain_callback) - { - manager_evdev->priv->constrain_callback (core_pointer, - us2ms (time_us), - x, y, - new_x, new_y, - manager_evdev->priv->constrain_data); - } - else - { - ClutterActor *stage = CLUTTER_ACTOR (manager_evdev->priv->stage); - float stage_width = clutter_actor_get_width (stage); - float stage_height = clutter_actor_get_height (stage); - - x = CLAMP (x, 0.f, stage_width - 1); - y = CLAMP (y, 0.f, stage_height - 1); - } -} - -void -_clutter_device_manager_evdev_filter_relative_motion (ClutterDeviceManagerEvdev *manager_evdev, - ClutterInputDevice *device, - float x, - float y, - float *dx, - float *dy) -{ - ClutterDeviceManagerEvdevPrivate *priv = manager_evdev->priv; - - if (!priv->relative_motion_filter) - return; - - priv->relative_motion_filter (device, x, y, dx, dy, - priv->relative_motion_filter_user_data); -} - -static ClutterEvent * -new_absolute_motion_event (ClutterInputDevice *input_device, - guint64 time_us, - gfloat x, - gfloat y, - gdouble *axes) -{ - gfloat stage_width, stage_height; - ClutterDeviceManagerEvdev *manager_evdev; - ClutterInputDeviceEvdev *device_evdev; - ClutterSeatEvdev *seat; - ClutterStage *stage; - ClutterEvent *event = NULL; - - stage = _clutter_input_device_get_stage (input_device); - device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (input_device); - manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (input_device->device_manager); - seat = _clutter_input_device_evdev_get_seat (device_evdev); - - stage_width = clutter_actor_get_width (CLUTTER_ACTOR (stage)); - stage_height = clutter_actor_get_height (CLUTTER_ACTOR (stage)); - - event = clutter_event_new (CLUTTER_MOTION); - - if (manager_evdev->priv->constrain_callback && - clutter_input_device_get_device_type (input_device) != CLUTTER_TABLET_DEVICE) - { - manager_evdev->priv->constrain_callback (seat->core_pointer, - us2ms (time_us), - seat->pointer_x, - seat->pointer_y, - &x, &y, - manager_evdev->priv->constrain_data); - } - else - { - x = CLAMP (x, 0.f, stage_width - 1); - y = CLAMP (y, 0.f, stage_height - 1); - } - - _clutter_evdev_event_set_time_usec (event, time_us); - event->motion.time = us2ms (time_us); - event->motion.stage = stage; - event->motion.device = seat->core_pointer; - _clutter_xkb_translate_state (event, seat->xkb, seat->button_state); - event->motion.x = x; - event->motion.y = y; - clutter_input_device_evdev_translate_coordinates (input_device, stage, - &event->motion.x, - &event->motion.y); - event->motion.axes = axes; - clutter_event_set_source_device (event, input_device); - - if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE) - { - clutter_event_set_device_tool (event, device_evdev->last_tool); - clutter_event_set_device (event, input_device); - } - else - clutter_event_set_device (event, seat->core_pointer); - - _clutter_input_device_set_stage (seat->core_pointer, stage); - - if (clutter_input_device_get_device_type (input_device) != CLUTTER_TABLET_DEVICE) - { - seat->pointer_x = x; - seat->pointer_y = y; - } - - return event; -} - -static void -notify_absolute_motion (ClutterInputDevice *input_device, - guint64 time_us, - gfloat x, - gfloat y, - gdouble *axes) -{ - ClutterEvent *event; - - event = new_absolute_motion_event (input_device, time_us, x, y, axes); - - queue_event (event); -} - -static void -notify_relative_tool_motion (ClutterInputDevice *input_device, - guint64 time_us, - gfloat dx, - gfloat dy, - gdouble *axes) -{ - ClutterInputDeviceEvdev *device_evdev; - ClutterEvent *event; - ClutterSeatEvdev *seat; - gfloat x, y; - - device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (input_device); - seat = _clutter_input_device_evdev_get_seat (device_evdev); - x = input_device->current_x + dx; - y = input_device->current_y + dy; - - _clutter_device_manager_evdev_filter_relative_motion (seat->manager_evdev, - input_device, - seat->pointer_x, - seat->pointer_y, - &dx, - &dy); - - event = new_absolute_motion_event (input_device, time_us, x, y, axes); - _clutter_evdev_event_set_relative_motion (event, dx, dy, 0, 0); - - queue_event (event); -} - -static void -notify_pinch_gesture_event (ClutterInputDevice *input_device, - ClutterTouchpadGesturePhase phase, - guint64 time_us, - gdouble dx, - gdouble dy, - gdouble angle_delta, - gdouble scale, - guint n_fingers) -{ - ClutterInputDeviceEvdev *device_evdev; - ClutterSeatEvdev *seat; - ClutterStage *stage; - ClutterEvent *event = NULL; - ClutterPoint pos; - - /* We can drop the event on the floor if no stage has been - * associated with the device yet. */ - stage = _clutter_input_device_get_stage (input_device); - if (stage == NULL) - return; - - device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (input_device); - seat = _clutter_input_device_evdev_get_seat (device_evdev); - - event = clutter_event_new (CLUTTER_TOUCHPAD_PINCH); - - clutter_input_device_get_coords (seat->core_pointer, NULL, &pos); - - _clutter_evdev_event_set_time_usec (event, time_us); - event->touchpad_pinch.phase = phase; - event->touchpad_pinch.time = us2ms (time_us); - event->touchpad_pinch.stage = CLUTTER_STAGE (stage); - event->touchpad_pinch.x = pos.x; - event->touchpad_pinch.y = pos.y; - event->touchpad_pinch.dx = dx; - event->touchpad_pinch.dy = dy; - event->touchpad_pinch.angle_delta = angle_delta; - event->touchpad_pinch.scale = scale; - event->touchpad_pinch.n_fingers = n_fingers; - - _clutter_xkb_translate_state (event, seat->xkb, seat->button_state); - - clutter_event_set_device (event, seat->core_pointer); - clutter_event_set_source_device (event, input_device); - - queue_event (event); -} - -static void -notify_swipe_gesture_event (ClutterInputDevice *input_device, - ClutterTouchpadGesturePhase phase, - guint64 time_us, - guint n_fingers, - gdouble dx, - gdouble dy) -{ - ClutterInputDeviceEvdev *device_evdev; - ClutterSeatEvdev *seat; - ClutterStage *stage; - ClutterEvent *event = NULL; - ClutterPoint pos; - - /* We can drop the event on the floor if no stage has been - * associated with the device yet. */ - stage = _clutter_input_device_get_stage (input_device); - if (stage == NULL) - return; - - device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (input_device); - seat = _clutter_input_device_evdev_get_seat (device_evdev); - - event = clutter_event_new (CLUTTER_TOUCHPAD_SWIPE); - - _clutter_evdev_event_set_time_usec (event, time_us); - event->touchpad_swipe.phase = phase; - event->touchpad_swipe.time = us2ms (time_us); - event->touchpad_swipe.stage = CLUTTER_STAGE (stage); - - clutter_input_device_get_coords (seat->core_pointer, NULL, &pos); - event->touchpad_swipe.x = pos.x; - event->touchpad_swipe.y = pos.y; - event->touchpad_swipe.dx = dx; - event->touchpad_swipe.dy = dy; - event->touchpad_swipe.n_fingers = n_fingers; - - _clutter_xkb_translate_state (event, seat->xkb, seat->button_state); - - clutter_event_set_device (event, seat->core_pointer); - clutter_event_set_source_device (event, input_device); - - queue_event (event); -} - -static void -notify_proximity (ClutterInputDevice *input_device, - guint64 time_us, - gboolean in) -{ - ClutterInputDeviceEvdev *device_evdev; - ClutterSeatEvdev *seat; - ClutterStage *stage; - ClutterEvent *event = NULL; - - /* We can drop the event on the floor if no stage has been - * associated with the device yet. */ - stage = _clutter_input_device_get_stage (input_device); - if (stage == NULL) - return; - - device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (input_device); - seat = _clutter_input_device_evdev_get_seat (device_evdev); - - if (in) - event = clutter_event_new (CLUTTER_PROXIMITY_IN); - else - event = clutter_event_new (CLUTTER_PROXIMITY_OUT); - - _clutter_evdev_event_set_time_usec (event, time_us); - - event->proximity.time = us2ms (time_us); - event->proximity.stage = CLUTTER_STAGE (stage); - event->proximity.device = seat->core_pointer; - clutter_event_set_device_tool (event, device_evdev->last_tool); - clutter_event_set_device (event, seat->core_pointer); - clutter_event_set_source_device (event, input_device); - - _clutter_input_device_set_stage (seat->core_pointer, stage); - - queue_event (event); -} - -static void -notify_pad_button (ClutterInputDevice *input_device, - guint64 time_us, - guint32 button, - guint32 mode_group, - guint32 mode, - guint32 pressed) -{ - ClutterInputDeviceEvdev *device_evdev; - ClutterSeatEvdev *seat; - ClutterStage *stage; - ClutterEvent *event; - - /* We can drop the event on the floor if no stage has been - * associated with the device yet. */ - stage = _clutter_input_device_get_stage (input_device); - if (stage == NULL) - return; - - if (pressed) - event = clutter_event_new (CLUTTER_PAD_BUTTON_PRESS); - else - event = clutter_event_new (CLUTTER_PAD_BUTTON_RELEASE); - - device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (input_device); - seat = _clutter_input_device_evdev_get_seat (device_evdev); - - _clutter_evdev_event_set_time_usec (event, time_us); - event->pad_button.stage = stage; - event->pad_button.button = button; - event->pad_button.group = mode_group; - event->pad_button.mode = mode; - clutter_event_set_device (event, input_device); - clutter_event_set_source_device (event, input_device); - clutter_event_set_time (event, us2ms (time_us)); - - _clutter_input_device_set_stage (seat->core_pointer, stage); - - queue_event (event); -} - -static void -notify_pad_strip (ClutterInputDevice *input_device, - guint64 time_us, - guint32 strip_number, - guint32 strip_source, - guint32 mode_group, - guint32 mode, - gdouble value) -{ - ClutterInputDeviceEvdev *device_evdev; - ClutterInputDevicePadSource source; - ClutterSeatEvdev *seat; - ClutterStage *stage; - ClutterEvent *event; - - /* We can drop the event on the floor if no stage has been - * associated with the device yet. */ - stage = _clutter_input_device_get_stage (input_device); - if (stage == NULL) - return; - - if (strip_source == LIBINPUT_TABLET_PAD_STRIP_SOURCE_FINGER) - source = CLUTTER_INPUT_DEVICE_PAD_SOURCE_FINGER; - else - source = CLUTTER_INPUT_DEVICE_PAD_SOURCE_UNKNOWN; - - device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (input_device); - seat = _clutter_input_device_evdev_get_seat (device_evdev); - - event = clutter_event_new (CLUTTER_PAD_STRIP); - _clutter_evdev_event_set_time_usec (event, time_us); - event->pad_strip.strip_source = source; - event->pad_strip.stage = stage; - event->pad_strip.strip_number = strip_number; - event->pad_strip.value = value; - event->pad_strip.group = mode_group; - event->pad_strip.mode = mode; - clutter_event_set_device (event, input_device); - clutter_event_set_source_device (event, input_device); - clutter_event_set_time (event, us2ms (time_us)); - - _clutter_input_device_set_stage (seat->core_pointer, stage); - - queue_event (event); -} - -static void -notify_pad_ring (ClutterInputDevice *input_device, - guint64 time_us, - guint32 ring_number, - guint32 ring_source, - guint32 mode_group, - guint32 mode, - gdouble angle) -{ - ClutterInputDeviceEvdev *device_evdev; - ClutterInputDevicePadSource source; - ClutterSeatEvdev *seat; - ClutterStage *stage; - ClutterEvent *event; - - /* We can drop the event on the floor if no stage has been - * associated with the device yet. */ - stage = _clutter_input_device_get_stage (input_device); - if (stage == NULL) - return; - - if (ring_source == LIBINPUT_TABLET_PAD_RING_SOURCE_FINGER) - source = CLUTTER_INPUT_DEVICE_PAD_SOURCE_FINGER; - else - source = CLUTTER_INPUT_DEVICE_PAD_SOURCE_UNKNOWN; - - device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (input_device); - seat = _clutter_input_device_evdev_get_seat (device_evdev); - - event = clutter_event_new (CLUTTER_PAD_RING); - _clutter_evdev_event_set_time_usec (event, time_us); - event->pad_ring.ring_source = source; - event->pad_ring.stage = stage; - event->pad_ring.ring_number = ring_number; - event->pad_ring.angle = angle; - event->pad_ring.group = mode_group; - event->pad_ring.mode = mode; - clutter_event_set_device (event, input_device); - clutter_event_set_source_device (event, input_device); - clutter_event_set_time (event, us2ms (time_us)); - - _clutter_input_device_set_stage (seat->core_pointer, stage); - - queue_event (event); -} - -static void -dispatch_libinput (ClutterDeviceManagerEvdev *manager_evdev) -{ - ClutterDeviceManagerEvdevPrivate *priv = manager_evdev->priv; - - libinput_dispatch (priv->libinput); - process_events (manager_evdev); -} - -static gboolean -clutter_event_dispatch (GSource *g_source, - GSourceFunc callback, - gpointer user_data) -{ - ClutterEventSource *source = (ClutterEventSource *) g_source; - ClutterDeviceManagerEvdev *manager_evdev; - ClutterEvent *event; - - _clutter_threads_acquire_lock (); - - manager_evdev = source->manager_evdev; - - /* Don't queue more events if we haven't finished handling the previous batch - */ - if (clutter_events_pending ()) - goto queue_event; - - dispatch_libinput (manager_evdev); - - queue_event: - event = clutter_event_get (); - - if (event) - { - ClutterModifierType event_state; - ClutterInputDevice *input_device = - clutter_event_get_source_device (event); - ClutterInputDeviceEvdev *device_evdev = - CLUTTER_INPUT_DEVICE_EVDEV (input_device); - ClutterSeatEvdev *seat = - _clutter_input_device_evdev_get_seat (device_evdev); - - /* Drop events if we don't have any stage to forward them to */ - if (!_clutter_input_device_get_stage (input_device)) - goto out; - - /* forward the event into clutter for emission etc. */ - _clutter_stage_queue_event (event->any.stage, event, FALSE); - - /* update the device states *after* the event */ - event_state = seat->button_state | - xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_EFFECTIVE); - _clutter_input_device_set_state (seat->core_pointer, event_state); - _clutter_input_device_set_state (seat->core_keyboard, event_state); - } - -out: - _clutter_threads_release_lock (); - - return TRUE; -} -static GSourceFuncs event_funcs = { - clutter_event_prepare, - clutter_event_check, - clutter_event_dispatch, - NULL -}; - -static ClutterEventSource * -clutter_event_source_new (ClutterDeviceManagerEvdev *manager_evdev) -{ - ClutterDeviceManagerEvdevPrivate *priv = manager_evdev->priv; - GSource *source; - ClutterEventSource *event_source; - gint fd; - - source = g_source_new (&event_funcs, sizeof (ClutterEventSource)); - event_source = (ClutterEventSource *) source; - - /* setup the source */ - event_source->manager_evdev = manager_evdev; - - fd = libinput_get_fd (priv->libinput); - event_source->event_poll_fd.fd = fd; - event_source->event_poll_fd.events = G_IO_IN; - - /* and finally configure and attach the GSource */ - g_source_set_priority (source, CLUTTER_PRIORITY_EVENTS); - g_source_add_poll (source, &event_source->event_poll_fd); - g_source_set_can_recurse (source, TRUE); - g_source_attach (source, NULL); - - return event_source; -} - -static void -clutter_event_source_free (ClutterEventSource *source) -{ - GSource *g_source = (GSource *) source; - - CLUTTER_NOTE (EVENT, "Removing GSource for evdev device manager"); - - /* ignore the return value of close, it's not like we can do something - * about it */ - close (source->event_poll_fd.fd); - - g_source_destroy (g_source); - g_source_unref (g_source); -} - -static void -evdev_add_device (ClutterDeviceManagerEvdev *manager_evdev, - struct libinput_device *libinput_device) -{ - ClutterDeviceManager *manager = (ClutterDeviceManager *) manager_evdev; - ClutterDeviceManagerEvdevPrivate *priv = manager_evdev->priv; - ClutterInputDeviceType type; - struct libinput_seat *libinput_seat; - ClutterSeatEvdev *seat; - ClutterInputDevice *device; - - libinput_seat = libinput_device_get_seat (libinput_device); - seat = libinput_seat_get_user_data (libinput_seat); - if (seat == NULL) - { - /* Clutter has the notion of global "core" pointers and keyboard devices, - * which are located on the main seat. Make whatever seat comes first the - * main seat. */ - if (priv->main_seat->libinput_seat == NULL) - seat = priv->main_seat; - else - { - seat = clutter_seat_evdev_new (manager_evdev); - priv->seats = g_slist_append (priv->seats, seat); - } - - clutter_seat_evdev_set_libinput_seat (seat, libinput_seat); - } - - device = _clutter_input_device_evdev_new (manager, seat, libinput_device); - _clutter_input_device_set_stage (device, manager_evdev->priv->stage); - - _clutter_device_manager_add_device (manager, device); - - /* Clutter assumes that device types are exclusive in the - * ClutterInputDevice API */ - type = _clutter_input_device_evdev_determine_type (libinput_device); - - if (type == CLUTTER_KEYBOARD_DEVICE) - { - _clutter_input_device_set_associated_device (device, seat->core_keyboard); - _clutter_input_device_add_slave (seat->core_keyboard, device); - } - else if (type == CLUTTER_POINTER_DEVICE) - { - _clutter_input_device_set_associated_device (device, seat->core_pointer); - _clutter_input_device_add_slave (seat->core_pointer, device); - } - - CLUTTER_NOTE (EVENT, "Added physical device '%s', type %s", - clutter_input_device_get_device_name (device), - device_type_str[type]); -} - -static void -evdev_remove_device (ClutterDeviceManagerEvdev *manager_evdev, - ClutterInputDeviceEvdev *device_evdev) -{ - ClutterDeviceManager *manager = CLUTTER_DEVICE_MANAGER (manager_evdev); - ClutterInputDevice *input_device = CLUTTER_INPUT_DEVICE (device_evdev); - - _clutter_device_manager_remove_device (manager, input_device); -} - -/* - * ClutterDeviceManager implementation - */ - -static void -clutter_device_manager_evdev_add_device (ClutterDeviceManager *manager, - ClutterInputDevice *device) -{ - ClutterDeviceManagerEvdev *manager_evdev; - ClutterDeviceManagerEvdevPrivate *priv; - ClutterInputDeviceEvdev *device_evdev; - ClutterSeatEvdev *seat; - - manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (manager); - priv = manager_evdev->priv; - device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (device); - seat = _clutter_input_device_evdev_get_seat (device_evdev); - - seat->devices = g_slist_prepend (seat->devices, device); - priv->devices = g_slist_prepend (priv->devices, device); -} - -static void -clutter_device_manager_evdev_remove_device (ClutterDeviceManager *manager, - ClutterInputDevice *device) -{ - ClutterDeviceManagerEvdev *manager_evdev; - ClutterDeviceManagerEvdevPrivate *priv; - ClutterInputDeviceEvdev *device_evdev; - ClutterSeatEvdev *seat; - - device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (device); - seat = _clutter_input_device_evdev_get_seat (device_evdev); - manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (manager); - priv = manager_evdev->priv; - - /* Remove the device */ - seat->devices = g_slist_remove (seat->devices, device); - priv->devices = g_slist_remove (priv->devices, device); - - if (seat->repeat_timer && seat->repeat_device == device) - clutter_seat_evdev_clear_repeat_timer (seat); - - g_object_unref (device); -} - -static const GSList * -clutter_device_manager_evdev_get_devices (ClutterDeviceManager *manager) -{ - return CLUTTER_DEVICE_MANAGER_EVDEV (manager)->priv->devices; -} - -static ClutterInputDevice * -clutter_device_manager_evdev_get_core_device (ClutterDeviceManager *manager, - ClutterInputDeviceType type) -{ - ClutterDeviceManagerEvdev *manager_evdev; - ClutterDeviceManagerEvdevPrivate *priv; - - manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (manager); - priv = manager_evdev->priv; - - switch (type) - { - case CLUTTER_POINTER_DEVICE: - return priv->main_seat->core_pointer; - - case CLUTTER_KEYBOARD_DEVICE: - return priv->main_seat->core_keyboard; - - case CLUTTER_EXTENSION_DEVICE: - default: - return NULL; - } - - return NULL; -} - -static ClutterInputDevice * -clutter_device_manager_evdev_get_device (ClutterDeviceManager *manager, - gint id) -{ - ClutterDeviceManagerEvdev *manager_evdev; - ClutterDeviceManagerEvdevPrivate *priv; - GSList *l; - - manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (manager); - priv = manager_evdev->priv; - - for (l = priv->seats; l; l = l->next) - { - ClutterSeatEvdev *seat = l->data; - ClutterInputDevice *device = clutter_seat_evdev_get_device (seat, id); - - if (device) - return device; - } - - return NULL; -} - -static void -flush_event_queue (void) -{ - ClutterEvent *event; - - while ((event = clutter_event_get ()) != NULL) - { - _clutter_process_event (event); - clutter_event_free (event); - } -} - -static gboolean -process_base_event (ClutterDeviceManagerEvdev *manager_evdev, - struct libinput_event *event) -{ - ClutterInputDevice *device; - struct libinput_device *libinput_device; - gboolean handled = TRUE; - - switch (libinput_event_get_type (event)) - { - case LIBINPUT_EVENT_DEVICE_ADDED: - libinput_device = libinput_event_get_device (event); - - evdev_add_device (manager_evdev, libinput_device); - break; - - case LIBINPUT_EVENT_DEVICE_REMOVED: - /* Flush all queued events, there - * might be some from this device. - */ - flush_event_queue (); - - libinput_device = libinput_event_get_device (event); - - device = libinput_device_get_user_data (libinput_device); - evdev_remove_device (manager_evdev, - CLUTTER_INPUT_DEVICE_EVDEV (device)); - break; - - default: - handled = FALSE; - } - - return handled; -} - -static ClutterScrollSource -translate_scroll_source (enum libinput_pointer_axis_source source) -{ - switch (source) - { - case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL: - return CLUTTER_SCROLL_SOURCE_WHEEL; - case LIBINPUT_POINTER_AXIS_SOURCE_FINGER: - return CLUTTER_SCROLL_SOURCE_FINGER; - case LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS: - return CLUTTER_SCROLL_SOURCE_CONTINUOUS; - default: - return CLUTTER_SCROLL_SOURCE_UNKNOWN; - } -} - -static ClutterInputDeviceToolType -translate_tool_type (struct libinput_tablet_tool *libinput_tool) -{ - enum libinput_tablet_tool_type tool; - - tool = libinput_tablet_tool_get_type (libinput_tool); - - switch (tool) - { - case LIBINPUT_TABLET_TOOL_TYPE_PEN: - return CLUTTER_INPUT_DEVICE_TOOL_PEN; - case LIBINPUT_TABLET_TOOL_TYPE_ERASER: - return CLUTTER_INPUT_DEVICE_TOOL_ERASER; - case LIBINPUT_TABLET_TOOL_TYPE_BRUSH: - return CLUTTER_INPUT_DEVICE_TOOL_BRUSH; - case LIBINPUT_TABLET_TOOL_TYPE_PENCIL: - return CLUTTER_INPUT_DEVICE_TOOL_PENCIL; - case LIBINPUT_TABLET_TOOL_TYPE_AIRBRUSH: - return CLUTTER_INPUT_DEVICE_TOOL_AIRBRUSH; - case LIBINPUT_TABLET_TOOL_TYPE_MOUSE: - return CLUTTER_INPUT_DEVICE_TOOL_MOUSE; - case LIBINPUT_TABLET_TOOL_TYPE_LENS: - return CLUTTER_INPUT_DEVICE_TOOL_LENS; - default: - return CLUTTER_INPUT_DEVICE_TOOL_NONE; - } -} - -static void -input_device_update_tool (ClutterInputDevice *input_device, - struct libinput_tablet_tool *libinput_tool) -{ - ClutterInputDeviceEvdev *evdev_device = CLUTTER_INPUT_DEVICE_EVDEV (input_device); - ClutterInputDeviceTool *tool = NULL; - ClutterInputDeviceToolType tool_type; - guint64 tool_serial; - - if (libinput_tool) - { - tool_serial = libinput_tablet_tool_get_serial (libinput_tool); - tool_type = translate_tool_type (libinput_tool); - tool = clutter_input_device_lookup_tool (input_device, - tool_serial, tool_type); - - if (!tool) - { - tool = clutter_input_device_tool_evdev_new (libinput_tool, - tool_serial, tool_type); - clutter_input_device_add_tool (input_device, tool); - } - } - - if (evdev_device->last_tool != tool) - { - evdev_device->last_tool = tool; - g_signal_emit_by_name (clutter_device_manager_get_default (), - "tool-changed", input_device, tool); - } -} - -static gdouble * -translate_tablet_axes (struct libinput_event_tablet_tool *tablet_event, - ClutterInputDeviceTool *tool) -{ - GArray *axes = g_array_new (FALSE, FALSE, sizeof (gdouble)); - struct libinput_tablet_tool *libinput_tool; - gdouble value; - - libinput_tool = libinput_event_tablet_tool_get_tool (tablet_event); - - value = libinput_event_tablet_tool_get_x (tablet_event); - g_array_append_val (axes, value); - value = libinput_event_tablet_tool_get_y (tablet_event); - g_array_append_val (axes, value); - - if (libinput_tablet_tool_has_distance (libinput_tool)) - { - value = libinput_event_tablet_tool_get_distance (tablet_event); - g_array_append_val (axes, value); - } - - if (libinput_tablet_tool_has_pressure (libinput_tool)) - { - value = libinput_event_tablet_tool_get_pressure (tablet_event); - value = clutter_input_device_tool_evdev_translate_pressure (tool, value); - g_array_append_val (axes, value); - } - - if (libinput_tablet_tool_has_tilt (libinput_tool)) - { - value = libinput_event_tablet_tool_get_tilt_x (tablet_event); - g_array_append_val (axes, value); - value = libinput_event_tablet_tool_get_tilt_y (tablet_event); - g_array_append_val (axes, value); - } - - if (libinput_tablet_tool_has_rotation (libinput_tool)) - { - value = libinput_event_tablet_tool_get_rotation (tablet_event); - g_array_append_val (axes, value); - } - - if (libinput_tablet_tool_has_slider (libinput_tool)) - { - value = libinput_event_tablet_tool_get_slider_position (tablet_event); - g_array_append_val (axes, value); - } - - if (libinput_tablet_tool_has_wheel (libinput_tool)) - { - value = libinput_event_tablet_tool_get_wheel_delta (tablet_event); - g_array_append_val (axes, value); - } - - if (axes->len == 0) - { - g_array_free (axes, TRUE); - return NULL; - } - else - return (gdouble *) g_array_free (axes, FALSE); -} - -static ClutterSeatEvdev * -seat_from_device (ClutterInputDevice *device) -{ - ClutterInputDeviceEvdev *device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (device); - - return _clutter_input_device_evdev_get_seat (device_evdev); -} - -static void -notify_continuous_axis (ClutterSeatEvdev *seat, - ClutterInputDevice *device, - uint64_t time_us, - ClutterScrollSource scroll_source, - struct libinput_event_pointer *axis_event) -{ - gdouble dx = 0.0, dy = 0.0; - ClutterScrollFinishFlags finish_flags = CLUTTER_SCROLL_FINISHED_NONE; - - if (libinput_event_pointer_has_axis (axis_event, - LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) - { - dx = libinput_event_pointer_get_axis_value ( - axis_event, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL); - - if (fabs (dx) < DBL_EPSILON) - finish_flags |= CLUTTER_SCROLL_FINISHED_HORIZONTAL; - } - if (libinput_event_pointer_has_axis (axis_event, - LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) - { - dy = libinput_event_pointer_get_axis_value ( - axis_event, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); - - if (fabs (dy) < DBL_EPSILON) - finish_flags |= CLUTTER_SCROLL_FINISHED_VERTICAL; - } - - clutter_seat_evdev_notify_scroll_continuous (seat, device, time_us, - dx, dy, - scroll_source, finish_flags); -} - -static void -notify_discrete_axis (ClutterSeatEvdev *seat, - ClutterInputDevice *device, - uint64_t time_us, - ClutterScrollSource scroll_source, - struct libinput_event_pointer *axis_event) -{ - gdouble discrete_dx = 0.0, discrete_dy = 0.0; - - if (libinput_event_pointer_has_axis (axis_event, - LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) - { - discrete_dx = libinput_event_pointer_get_axis_value_discrete ( - axis_event, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL); - } - if (libinput_event_pointer_has_axis (axis_event, - LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) - { - discrete_dy = libinput_event_pointer_get_axis_value_discrete ( - axis_event, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); - } - - clutter_seat_evdev_notify_discrete_scroll (seat, device, - time_us, - discrete_dx, discrete_dy, - scroll_source); -} - -static gboolean -process_device_event (ClutterDeviceManagerEvdev *manager_evdev, - struct libinput_event *event) -{ - gboolean handled = TRUE; - struct libinput_device *libinput_device = libinput_event_get_device(event); - ClutterInputDevice *device; - ClutterInputDeviceEvdev *device_evdev; - - switch (libinput_event_get_type (event)) - { - case LIBINPUT_EVENT_KEYBOARD_KEY: - { - guint32 key, key_state, seat_key_count; - guint64 time_us; - struct libinput_event_keyboard *key_event = - libinput_event_get_keyboard_event (event); - - device = libinput_device_get_user_data (libinput_device); - time_us = libinput_event_keyboard_get_time_usec (key_event); - key = libinput_event_keyboard_get_key (key_event); - key_state = libinput_event_keyboard_get_key_state (key_event) == - LIBINPUT_KEY_STATE_PRESSED; - seat_key_count = - libinput_event_keyboard_get_seat_key_count (key_event); - - /* Ignore key events that are not seat wide state changes. */ - if ((key_state == LIBINPUT_KEY_STATE_PRESSED && - seat_key_count != 1) || - (key_state == LIBINPUT_KEY_STATE_RELEASED && - seat_key_count != 0)) - break; - - clutter_seat_evdev_notify_key (seat_from_device (device), - device, - time_us, key, key_state, TRUE); - - break; - } - - case LIBINPUT_EVENT_POINTER_MOTION: - { - struct libinput_event_pointer *pointer_event = - libinput_event_get_pointer_event (event); - uint64_t time_us; - double dx; - double dy; - double dx_unaccel; - double dy_unaccel; - - device = libinput_device_get_user_data (libinput_device); - time_us = libinput_event_pointer_get_time_usec (pointer_event); - dx = libinput_event_pointer_get_dx (pointer_event); - dy = libinput_event_pointer_get_dy (pointer_event); - dx_unaccel = libinput_event_pointer_get_dx_unaccelerated (pointer_event); - dy_unaccel = libinput_event_pointer_get_dy_unaccelerated (pointer_event); - - clutter_seat_evdev_notify_relative_motion (seat_from_device (device), - device, - time_us, - dx, dy, - dx_unaccel, dy_unaccel); - - break; - } - - case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE: - { - guint64 time_us; - double x, y; - gfloat stage_width, stage_height; - ClutterStage *stage; - struct libinput_event_pointer *motion_event = - libinput_event_get_pointer_event (event); - device = libinput_device_get_user_data (libinput_device); - - stage = _clutter_input_device_get_stage (device); - if (stage == NULL) - break; - - stage_width = clutter_actor_get_width (CLUTTER_ACTOR (stage)); - stage_height = clutter_actor_get_height (CLUTTER_ACTOR (stage)); - - time_us = libinput_event_pointer_get_time_usec (motion_event); - x = libinput_event_pointer_get_absolute_x_transformed (motion_event, - stage_width); - y = libinput_event_pointer_get_absolute_y_transformed (motion_event, - stage_height); - - clutter_seat_evdev_notify_absolute_motion (seat_from_device (device), - device, - time_us, - x, y, - NULL); - - break; - } - - case LIBINPUT_EVENT_POINTER_BUTTON: - { - guint32 button, button_state, seat_button_count; - guint64 time_us; - struct libinput_event_pointer *button_event = - libinput_event_get_pointer_event (event); - device = libinput_device_get_user_data (libinput_device); - - time_us = libinput_event_pointer_get_time_usec (button_event); - button = libinput_event_pointer_get_button (button_event); - button_state = libinput_event_pointer_get_button_state (button_event) == - LIBINPUT_BUTTON_STATE_PRESSED; - seat_button_count = - libinput_event_pointer_get_seat_button_count (button_event); - - /* Ignore button events that are not seat wide state changes. */ - if ((button_state == LIBINPUT_BUTTON_STATE_PRESSED && - seat_button_count != 1) || - (button_state == LIBINPUT_BUTTON_STATE_RELEASED && - seat_button_count != 0)) - break; - - clutter_seat_evdev_notify_button (seat_from_device (device), device, - time_us, button, button_state); - break; - } - - case LIBINPUT_EVENT_POINTER_AXIS: - { - guint64 time_us; - enum libinput_pointer_axis_source source; - struct libinput_event_pointer *axis_event = - libinput_event_get_pointer_event (event); - ClutterSeatEvdev *seat; - ClutterScrollSource scroll_source; - - device = libinput_device_get_user_data (libinput_device); - seat = _clutter_input_device_evdev_get_seat (CLUTTER_INPUT_DEVICE_EVDEV (device)); - - time_us = libinput_event_pointer_get_time_usec (axis_event); - source = libinput_event_pointer_get_axis_source (axis_event); - scroll_source = translate_scroll_source (source); - - /* libinput < 0.8 sent wheel click events with value 10. Since 0.8 - the value is the angle of the click in degrees. To keep - backwards-compat with existing clients, we just send multiples of - the click count. */ - - switch (scroll_source) - { - case CLUTTER_SCROLL_SOURCE_WHEEL: - notify_discrete_axis (seat, device, time_us, scroll_source, - axis_event); - break; - case CLUTTER_SCROLL_SOURCE_FINGER: - case CLUTTER_SCROLL_SOURCE_CONTINUOUS: - case CLUTTER_SCROLL_SOURCE_UNKNOWN: - notify_continuous_axis (seat, device, time_us, scroll_source, - axis_event); - break; - } - break; - } - - case LIBINPUT_EVENT_TOUCH_DOWN: - { - int device_slot; - guint64 time_us; - double x, y; - gfloat stage_width, stage_height; - ClutterSeatEvdev *seat; - ClutterStage *stage; - ClutterTouchState *touch_state; - struct libinput_event_touch *touch_event = - libinput_event_get_touch_event (event); - - device = libinput_device_get_user_data (libinput_device); - device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (device); - seat = _clutter_input_device_evdev_get_seat (device_evdev); - - stage = _clutter_input_device_get_stage (device); - if (stage == NULL) - break; - - stage_width = clutter_actor_get_width (CLUTTER_ACTOR (stage)); - stage_height = clutter_actor_get_height (CLUTTER_ACTOR (stage)); - - device_slot = libinput_event_touch_get_slot (touch_event); - time_us = libinput_event_touch_get_time_usec (touch_event); - x = libinput_event_touch_get_x_transformed (touch_event, - stage_width); - y = libinput_event_touch_get_y_transformed (touch_event, - stage_height); - - touch_state = - clutter_input_device_evdev_acquire_touch_state (device_evdev, - device_slot); - touch_state->coords.x = x; - touch_state->coords.y = y; - - clutter_seat_evdev_notify_touch_event (seat, device, - CLUTTER_TOUCH_BEGIN, - time_us, - touch_state->seat_slot, - touch_state->coords.x, - touch_state->coords.y); - break; - } - - case LIBINPUT_EVENT_TOUCH_UP: - { - int device_slot; - guint64 time_us; - ClutterSeatEvdev *seat; - ClutterTouchState *touch_state; - struct libinput_event_touch *touch_event = - libinput_event_get_touch_event (event); - - device = libinput_device_get_user_data (libinput_device); - device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (device); - seat = _clutter_input_device_evdev_get_seat (device_evdev); - - device_slot = libinput_event_touch_get_slot (touch_event); - time_us = libinput_event_touch_get_time_usec (touch_event); - touch_state = - clutter_input_device_evdev_lookup_touch_state (device_evdev, - device_slot); - if (!touch_state) - break; - - clutter_seat_evdev_notify_touch_event (seat, device, - CLUTTER_TOUCH_END, time_us, - touch_state->seat_slot, - touch_state->coords.x, - touch_state->coords.y); - clutter_input_device_evdev_release_touch_state (device_evdev, - touch_state); - break; - } - - case LIBINPUT_EVENT_TOUCH_MOTION: - { - int device_slot; - guint64 time_us; - double x, y; - gfloat stage_width, stage_height; - ClutterSeatEvdev *seat; - ClutterStage *stage; - ClutterTouchState *touch_state; - struct libinput_event_touch *touch_event = - libinput_event_get_touch_event (event); - - device = libinput_device_get_user_data (libinput_device); - device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (device); - seat = _clutter_input_device_evdev_get_seat (device_evdev); - - stage = _clutter_input_device_get_stage (device); - if (stage == NULL) - break; - - stage_width = clutter_actor_get_width (CLUTTER_ACTOR (stage)); - stage_height = clutter_actor_get_height (CLUTTER_ACTOR (stage)); - - device_slot = libinput_event_touch_get_slot (touch_event); - time_us = libinput_event_touch_get_time_usec (touch_event); - x = libinput_event_touch_get_x_transformed (touch_event, - stage_width); - y = libinput_event_touch_get_y_transformed (touch_event, - stage_height); - - touch_state = - clutter_input_device_evdev_lookup_touch_state (device_evdev, - device_slot); - if (!touch_state) - break; - - touch_state->coords.x = x; - touch_state->coords.y = y; - - clutter_seat_evdev_notify_touch_event (seat, device, - CLUTTER_TOUCH_UPDATE, - time_us, - touch_state->seat_slot, - touch_state->coords.x, - touch_state->coords.y); - break; - } - case LIBINPUT_EVENT_TOUCH_CANCEL: - { - guint64 time_us; - struct libinput_event_touch *touch_event = - libinput_event_get_touch_event (event); - - device = libinput_device_get_user_data (libinput_device); - device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (device); - time_us = libinput_event_touch_get_time_usec (touch_event); - - clutter_input_device_evdev_release_touch_slots (device_evdev, time_us); - - break; - } - case LIBINPUT_EVENT_GESTURE_PINCH_BEGIN: - case LIBINPUT_EVENT_GESTURE_PINCH_END: - { - struct libinput_event_gesture *gesture_event = - libinput_event_get_gesture_event (event); - ClutterTouchpadGesturePhase phase; - guint n_fingers; - guint64 time_us; - - if (libinput_event_get_type (event) == LIBINPUT_EVENT_GESTURE_PINCH_BEGIN) - phase = CLUTTER_TOUCHPAD_GESTURE_PHASE_BEGIN; - else - phase = libinput_event_gesture_get_cancelled (gesture_event) ? - CLUTTER_TOUCHPAD_GESTURE_PHASE_CANCEL : CLUTTER_TOUCHPAD_GESTURE_PHASE_END; - - n_fingers = libinput_event_gesture_get_finger_count (gesture_event); - device = libinput_device_get_user_data (libinput_device); - time_us = libinput_event_gesture_get_time_usec (gesture_event); - notify_pinch_gesture_event (device, phase, time_us, 0, 0, 0, 0, n_fingers); - break; - } - case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE: - { - struct libinput_event_gesture *gesture_event = - libinput_event_get_gesture_event (event); - gdouble angle_delta, scale, dx, dy; - guint n_fingers; - guint64 time_us; - - n_fingers = libinput_event_gesture_get_finger_count (gesture_event); - device = libinput_device_get_user_data (libinput_device); - time_us = libinput_event_gesture_get_time_usec (gesture_event); - angle_delta = libinput_event_gesture_get_angle_delta (gesture_event); - scale = libinput_event_gesture_get_scale (gesture_event); - dx = libinput_event_gesture_get_dx (gesture_event); - dy = libinput_event_gesture_get_dx (gesture_event); - - notify_pinch_gesture_event (device, - CLUTTER_TOUCHPAD_GESTURE_PHASE_UPDATE, - time_us, dx, dy, angle_delta, scale, n_fingers); - break; - } - case LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN: - case LIBINPUT_EVENT_GESTURE_SWIPE_END: - { - struct libinput_event_gesture *gesture_event = - libinput_event_get_gesture_event (event); - ClutterTouchpadGesturePhase phase; - guint32 n_fingers; - guint64 time_us; - - device = libinput_device_get_user_data (libinput_device); - time_us = libinput_event_gesture_get_time_usec (gesture_event); - n_fingers = libinput_event_gesture_get_finger_count (gesture_event); - - if (libinput_event_get_type (event) == LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN) - phase = CLUTTER_TOUCHPAD_GESTURE_PHASE_BEGIN; - else - phase = libinput_event_gesture_get_cancelled (gesture_event) ? - CLUTTER_TOUCHPAD_GESTURE_PHASE_CANCEL : CLUTTER_TOUCHPAD_GESTURE_PHASE_END; - - notify_swipe_gesture_event (device, phase, time_us, n_fingers, 0, 0); - break; - } - case LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE: - { - struct libinput_event_gesture *gesture_event = - libinput_event_get_gesture_event (event); - guint32 n_fingers; - guint64 time_us; - gdouble dx, dy; - - device = libinput_device_get_user_data (libinput_device); - time_us = libinput_event_gesture_get_time_usec (gesture_event); - n_fingers = libinput_event_gesture_get_finger_count (gesture_event); - dx = libinput_event_gesture_get_dx (gesture_event); - dy = libinput_event_gesture_get_dy (gesture_event); - - notify_swipe_gesture_event (device, - CLUTTER_TOUCHPAD_GESTURE_PHASE_UPDATE, - time_us, n_fingers, dx, dy); - break; - } - case LIBINPUT_EVENT_TABLET_TOOL_AXIS: - { - guint64 time; - double x, y, dx, dy, *axes; - gfloat stage_width, stage_height; - ClutterStage *stage; - struct libinput_event_tablet_tool *tablet_event = - libinput_event_get_tablet_tool_event (event); - ClutterInputDeviceEvdev *evdev_device; - - device = libinput_device_get_user_data (libinput_device); - evdev_device = CLUTTER_INPUT_DEVICE_EVDEV (device); - - stage = _clutter_input_device_get_stage (device); - if (!stage) - break; - - axes = translate_tablet_axes (tablet_event, - evdev_device->last_tool); - if (!axes) - break; - - stage_width = clutter_actor_get_width (CLUTTER_ACTOR (stage)); - stage_height = clutter_actor_get_height (CLUTTER_ACTOR (stage)); - - time = libinput_event_tablet_tool_get_time_usec (tablet_event); - - if (clutter_input_device_get_mapping_mode (device) == CLUTTER_INPUT_DEVICE_MAPPING_RELATIVE || - clutter_input_device_tool_get_tool_type (evdev_device->last_tool) == CLUTTER_INPUT_DEVICE_TOOL_MOUSE || - clutter_input_device_tool_get_tool_type (evdev_device->last_tool) == CLUTTER_INPUT_DEVICE_TOOL_LENS) - { - dx = libinput_event_tablet_tool_get_dx (tablet_event); - dy = libinput_event_tablet_tool_get_dy (tablet_event); - notify_relative_tool_motion (device, time, dx, dy, axes); - } - else - { - x = libinput_event_tablet_tool_get_x_transformed (tablet_event, stage_width); - y = libinput_event_tablet_tool_get_y_transformed (tablet_event, stage_height); - notify_absolute_motion (device, time, x, y, axes); - } - - break; - } - case LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY: - { - guint64 time; - struct libinput_event_tablet_tool *tablet_event = - libinput_event_get_tablet_tool_event (event); - struct libinput_tablet_tool *libinput_tool = NULL; - enum libinput_tablet_tool_proximity_state state; - - state = libinput_event_tablet_tool_get_proximity_state (tablet_event); - time = libinput_event_tablet_tool_get_time_usec (tablet_event); - device = libinput_device_get_user_data (libinput_device); - - libinput_tool = libinput_event_tablet_tool_get_tool (tablet_event); - - if (state == LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN) - input_device_update_tool (device, libinput_tool); - notify_proximity (device, time, state == LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN); - if (state == LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT) - input_device_update_tool (device, NULL); - break; - } - case LIBINPUT_EVENT_TABLET_TOOL_BUTTON: - { - guint64 time_us; - guint32 button_state; - struct libinput_event_tablet_tool *tablet_event = - libinput_event_get_tablet_tool_event (event); - guint tablet_button; - - device = libinput_device_get_user_data (libinput_device); - time_us = libinput_event_tablet_tool_get_time_usec (tablet_event); - tablet_button = libinput_event_tablet_tool_get_button (tablet_event); - - button_state = libinput_event_tablet_tool_get_button_state (tablet_event) == - LIBINPUT_BUTTON_STATE_PRESSED; - - clutter_seat_evdev_notify_button (seat_from_device (device), device, - time_us, tablet_button, button_state); - break; - } - case LIBINPUT_EVENT_TABLET_TOOL_TIP: - { - guint64 time_us; - guint32 button_state; - struct libinput_event_tablet_tool *tablet_event = - libinput_event_get_tablet_tool_event (event); - - device = libinput_device_get_user_data (libinput_device); - time_us = libinput_event_tablet_tool_get_time_usec (tablet_event); - - button_state = libinput_event_tablet_tool_get_tip_state (tablet_event) == - LIBINPUT_TABLET_TOOL_TIP_DOWN; - - clutter_seat_evdev_notify_button (seat_from_device (device), device, - time_us, BTN_TOUCH, button_state); - break; - } - case LIBINPUT_EVENT_TABLET_PAD_BUTTON: - { - guint64 time; - guint32 button_state, button, group, mode; - struct libinput_tablet_pad_mode_group *mode_group; - struct libinput_event_tablet_pad *pad_event = - libinput_event_get_tablet_pad_event (event); - - device = libinput_device_get_user_data (libinput_device); - time = libinput_event_tablet_pad_get_time_usec (pad_event); - - mode_group = libinput_event_tablet_pad_get_mode_group (pad_event); - group = libinput_tablet_pad_mode_group_get_index (mode_group); - mode = libinput_event_tablet_pad_get_mode (pad_event); - - button = libinput_event_tablet_pad_get_button_number (pad_event); - button_state = libinput_event_tablet_pad_get_button_state (pad_event) == - LIBINPUT_BUTTON_STATE_PRESSED; - notify_pad_button (device, time, button, group, mode, button_state); - break; - } - case LIBINPUT_EVENT_TABLET_PAD_STRIP: - { - guint64 time; - guint32 number, source, group, mode; - struct libinput_tablet_pad_mode_group *mode_group; - struct libinput_event_tablet_pad *pad_event = - libinput_event_get_tablet_pad_event (event); - gdouble value; - - device = libinput_device_get_user_data (libinput_device); - time = libinput_event_tablet_pad_get_time_usec (pad_event); - number = libinput_event_tablet_pad_get_strip_number (pad_event); - value = libinput_event_tablet_pad_get_strip_position (pad_event); - source = libinput_event_tablet_pad_get_strip_source (pad_event); - - mode_group = libinput_event_tablet_pad_get_mode_group (pad_event); - group = libinput_tablet_pad_mode_group_get_index (mode_group); - mode = libinput_event_tablet_pad_get_mode (pad_event); - - notify_pad_strip (device, time, number, source, group, mode, value); - break; - } - case LIBINPUT_EVENT_TABLET_PAD_RING: - { - guint64 time; - guint32 number, source, group, mode; - struct libinput_tablet_pad_mode_group *mode_group; - struct libinput_event_tablet_pad *pad_event = - libinput_event_get_tablet_pad_event (event); - gdouble angle; - - device = libinput_device_get_user_data (libinput_device); - time = libinput_event_tablet_pad_get_time_usec (pad_event); - number = libinput_event_tablet_pad_get_ring_number (pad_event); - angle = libinput_event_tablet_pad_get_ring_position (pad_event); - source = libinput_event_tablet_pad_get_ring_source (pad_event); - - mode_group = libinput_event_tablet_pad_get_mode_group (pad_event); - group = libinput_tablet_pad_mode_group_get_index (mode_group); - mode = libinput_event_tablet_pad_get_mode (pad_event); - - notify_pad_ring (device, time, number, source, group, mode, angle); - break; - } - default: - handled = FALSE; - } - - return handled; -} - -static gboolean -filter_event (ClutterDeviceManagerEvdev *manager_evdev, - struct libinput_event *event) -{ - gboolean retval = CLUTTER_EVENT_PROPAGATE; - ClutterEventFilter *filter; - GSList *tmp_list; - - tmp_list = manager_evdev->priv->event_filters; - - while (tmp_list) - { - filter = tmp_list->data; - retval = filter->func (event, filter->data); - tmp_list = tmp_list->next; - - if (retval != CLUTTER_EVENT_PROPAGATE) - break; - } - - return retval; -} - -static void -process_event (ClutterDeviceManagerEvdev *manager_evdev, - struct libinput_event *event) -{ - gboolean retval; - - retval = filter_event (manager_evdev, event); - - if (retval != CLUTTER_EVENT_PROPAGATE) - return; - - if (process_base_event (manager_evdev, event)) - return; - if (process_device_event (manager_evdev, event)) - return; -} - -static void -process_events (ClutterDeviceManagerEvdev *manager_evdev) -{ - ClutterDeviceManagerEvdevPrivate *priv = manager_evdev->priv; - struct libinput_event *event; - - while ((event = libinput_get_event (priv->libinput))) - { - process_event(manager_evdev, event); - libinput_event_destroy(event); - } -} - -static int -open_restricted (const char *path, - int flags, - void *user_data) -{ - gint fd; - - if (device_open_callback) - { - GError *error = NULL; - - fd = device_open_callback (path, flags, device_callback_data, &error); - - if (fd < 0) - { - g_warning ("Could not open device %s: %s", path, error->message); - g_error_free (error); - } - } - else - { - fd = open (path, O_RDWR | O_NONBLOCK); - if (fd < 0) - { - g_warning ("Could not open device %s: %s", path, strerror (errno)); - } - } - - return fd; -} - -static void -close_restricted (int fd, - void *user_data) -{ - if (device_close_callback) - device_close_callback (fd, device_callback_data); - else - close (fd); -} - -static const struct libinput_interface libinput_interface = { - open_restricted, - close_restricted -}; - -static ClutterVirtualInputDevice * -clutter_device_manager_evdev_create_virtual_device (ClutterDeviceManager *manager, - ClutterInputDeviceType device_type) -{ - ClutterDeviceManagerEvdev *manager_evdev = - CLUTTER_DEVICE_MANAGER_EVDEV (manager); - ClutterDeviceManagerEvdevPrivate *priv = manager_evdev->priv; - - return g_object_new (CLUTTER_TYPE_VIRTUAL_INPUT_DEVICE_EVDEV, - "device-manager", manager, - "seat", priv->main_seat, - "device-type", device_type, - NULL); -} - -static ClutterVirtualDeviceType -clutter_device_manager_evdev_get_supported_virtual_device_types (ClutterDeviceManager *device_manager) -{ - return (CLUTTER_VIRTUAL_DEVICE_TYPE_KEYBOARD | - CLUTTER_VIRTUAL_DEVICE_TYPE_POINTER | - CLUTTER_VIRTUAL_DEVICE_TYPE_TOUCHSCREEN); -} - -static void -clutter_device_manager_evdev_compress_motion (ClutterDeviceManager *device_manger, - ClutterEvent *event, - const ClutterEvent *to_discard) -{ - double dx, dy; - double dx_unaccel, dy_unaccel; - double dst_dx = 0.0, dst_dy = 0.0; - double dst_dx_unaccel = 0.0, dst_dy_unaccel = 0.0; - - if (!clutter_evdev_event_get_relative_motion (to_discard, - &dx, &dy, - &dx_unaccel, &dy_unaccel)) - return; - - clutter_evdev_event_get_relative_motion (event, - &dst_dx, &dst_dy, - &dst_dx_unaccel, &dst_dy_unaccel); - _clutter_evdev_event_set_relative_motion (event, - dx + dst_dx, - dy + dst_dy, - dx_unaccel + dst_dx_unaccel, - dy_unaccel + dst_dy_unaccel); -} - -static void -clutter_device_manager_evdev_apply_kbd_a11y_settings (ClutterDeviceManager *device_manager, - ClutterKbdA11ySettings *settings) -{ - ClutterInputDevice *device; - - device = clutter_device_manager_evdev_get_core_device (device_manager, CLUTTER_KEYBOARD_DEVICE); - if (device) - clutter_input_device_evdev_apply_kbd_a11y_settings (CLUTTER_INPUT_DEVICE_EVDEV (device), - settings); -} - -/* - * GObject implementation - */ - -static void -clutter_device_manager_evdev_constructed (GObject *gobject) -{ - ClutterDeviceManagerEvdev *manager_evdev; - ClutterDeviceManagerEvdevPrivate *priv; - ClutterEventSource *source; - struct udev *udev; - struct xkb_context *ctx; - struct xkb_rule_names names; - - udev = udev_new (); - if (G_UNLIKELY (udev == NULL)) - { - g_warning ("Failed to create udev object"); - return; - } - - manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (gobject); - priv = manager_evdev->priv; - - priv->libinput = libinput_udev_create_context (&libinput_interface, - manager_evdev, - udev); - if (priv->libinput == NULL) - { - g_critical ("Failed to create the libinput object."); - return; - } - - if (libinput_udev_assign_seat (priv->libinput, - evdev_seat_id ? evdev_seat_id : "seat0") == -1) - { - g_critical ("Failed to assign a seat to the libinput object."); - libinput_unref (priv->libinput); - priv->libinput = NULL; - return; - } - - udev_unref (udev); - - names.rules = "evdev"; - names.model = "pc105"; - names.layout = option_xkb_layout; - names.variant = option_xkb_variant; - names.options = option_xkb_options; - - ctx = xkb_context_new (0); - g_assert (ctx); - priv->keymap = xkb_keymap_new_from_names (ctx, &names, 0); - xkb_context_unref (ctx); - - priv->main_seat = clutter_seat_evdev_new (manager_evdev); - priv->seats = g_slist_append (priv->seats, priv->main_seat); - - dispatch_libinput (manager_evdev); - - source = clutter_event_source_new (manager_evdev); - priv->event_source = source; -} - -static void -clutter_device_manager_evdev_dispose (GObject *object) -{ - ClutterDeviceManagerEvdev *manager_evdev; - ClutterDeviceManagerEvdevPrivate *priv; - - manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (object); - priv = manager_evdev->priv; - - if (priv->stage_added_handler) - { - g_signal_handler_disconnect (priv->stage_manager, - priv->stage_added_handler); - priv->stage_added_handler = 0; - } - - if (priv->stage_removed_handler) - { - g_signal_handler_disconnect (priv->stage_manager, - priv->stage_removed_handler); - priv->stage_removed_handler = 0; - } - - if (priv->stage_manager) - { - g_object_unref (priv->stage_manager); - priv->stage_manager = NULL; - } - - G_OBJECT_CLASS (clutter_device_manager_evdev_parent_class)->dispose (object); -} - -static void -clutter_device_manager_evdev_finalize (GObject *object) -{ - ClutterDeviceManagerEvdev *manager_evdev; - ClutterDeviceManagerEvdevPrivate *priv; - - manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (object); - priv = manager_evdev->priv; - - g_slist_free_full (priv->seats, (GDestroyNotify) clutter_seat_evdev_free); - g_slist_free (priv->devices); - - if (priv->keymap) - xkb_keymap_unref (priv->keymap); - - if (priv->event_source != NULL) - clutter_event_source_free (priv->event_source); - - if (priv->constrain_data_notify != NULL) - priv->constrain_data_notify (priv->constrain_data); - - if (priv->libinput != NULL) - libinput_unref (priv->libinput); - - g_list_free (priv->free_device_ids); - - G_OBJECT_CLASS (clutter_device_manager_evdev_parent_class)->finalize (object); -} - -static void -clutter_device_manager_evdev_class_init (ClutterDeviceManagerEvdevClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterDeviceManagerClass *manager_class; - - gobject_class->constructed = clutter_device_manager_evdev_constructed; - gobject_class->finalize = clutter_device_manager_evdev_finalize; - gobject_class->dispose = clutter_device_manager_evdev_dispose; - - manager_class = CLUTTER_DEVICE_MANAGER_CLASS (klass); - manager_class->add_device = clutter_device_manager_evdev_add_device; - manager_class->remove_device = clutter_device_manager_evdev_remove_device; - manager_class->get_devices = clutter_device_manager_evdev_get_devices; - manager_class->get_core_device = clutter_device_manager_evdev_get_core_device; - manager_class->get_device = clutter_device_manager_evdev_get_device; - manager_class->create_virtual_device = clutter_device_manager_evdev_create_virtual_device; - manager_class->get_supported_virtual_device_types = clutter_device_manager_evdev_get_supported_virtual_device_types; - manager_class->compress_motion = clutter_device_manager_evdev_compress_motion; - manager_class->apply_kbd_a11y_settings = clutter_device_manager_evdev_apply_kbd_a11y_settings; -} - -static void -clutter_device_manager_evdev_stage_added_cb (ClutterStageManager *manager, - ClutterStage *stage, - ClutterDeviceManagerEvdev *self) -{ - ClutterDeviceManagerEvdevPrivate *priv = self->priv; - GSList *l; - - /* NB: Currently we can only associate a single stage with all evdev - * devices. - * - * We save a pointer to the stage so if we release/reclaim input - * devices due to switching virtual terminals then we know what - * stage to re associate the devices with. - */ - priv->stage = stage; - - /* Set the stage of any devices that don't already have a stage */ - for (l = priv->seats; l; l = l->next) - { - ClutterSeatEvdev *seat = l->data; - - clutter_seat_evdev_set_stage (seat, stage); - } - - /* We only want to do this once so we can catch the default - stage. If the application has multiple stages then it will need - to manage the stage of the input devices itself */ - g_signal_handler_disconnect (priv->stage_manager, - priv->stage_added_handler); - priv->stage_added_handler = 0; -} - -static void -clutter_device_manager_evdev_stage_removed_cb (ClutterStageManager *manager, - ClutterStage *stage, - ClutterDeviceManagerEvdev *self) -{ - ClutterDeviceManagerEvdevPrivate *priv = self->priv; - GSList *l; - - /* Remove the stage of any input devices that were pointing to this - stage so we don't send events to invalid stages */ - for (l = priv->seats; l; l = l->next) - { - ClutterSeatEvdev *seat = l->data; - - clutter_seat_evdev_set_stage (seat, NULL); - } -} - -static void -clutter_device_manager_evdev_init (ClutterDeviceManagerEvdev *self) -{ - ClutterDeviceManagerEvdevPrivate *priv; - - priv = self->priv = clutter_device_manager_evdev_get_instance_private (self); - - priv->stage_manager = clutter_stage_manager_get_default (); - g_object_ref (priv->stage_manager); - - /* evdev doesn't have any way to link an event to a particular stage - so we'll have to leave it up to applications to set the - corresponding stage for an input device. However to make it - easier for applications that are only using one fullscreen stage - (which is probably the most frequent use-case for the evdev - backend) we'll associate any input devices that don't have a - stage with the first stage created. */ - priv->stage_added_handler = - g_signal_connect (priv->stage_manager, - "stage-added", - G_CALLBACK (clutter_device_manager_evdev_stage_added_cb), - self); - priv->stage_removed_handler = - g_signal_connect (priv->stage_manager, - "stage-removed", - G_CALLBACK (clutter_device_manager_evdev_stage_removed_cb), - self); - - priv->device_id_next = INITIAL_DEVICE_ID; -} - -void -_clutter_events_evdev_init (ClutterBackend *backend) -{ - CLUTTER_NOTE (EVENT, "Initializing evdev backend"); - - backend->device_manager = g_object_new (CLUTTER_TYPE_DEVICE_MANAGER_EVDEV, - "backend", backend, - NULL); -} - -void -_clutter_events_evdev_uninit (ClutterBackend *backend) -{ - CLUTTER_NOTE (EVENT, "Uninitializing evdev backend"); -} - -gint -_clutter_device_manager_evdev_acquire_device_id (ClutterDeviceManagerEvdev *manager_evdev) -{ - ClutterDeviceManagerEvdevPrivate *priv = manager_evdev->priv; - GList *first; - gint next_id; - - if (priv->free_device_ids == NULL) - { - gint i; - - /* We ran out of free ID's, so append 10 new ones. */ - for (i = 0; i < 10; i++) - priv->free_device_ids = - g_list_append (priv->free_device_ids, - GINT_TO_POINTER (priv->device_id_next++)); - } - - first = g_list_first (priv->free_device_ids); - next_id = GPOINTER_TO_INT (first->data); - priv->free_device_ids = g_list_delete_link (priv->free_device_ids, first); - - return next_id; -} - -void -_clutter_device_manager_evdev_dispatch (ClutterDeviceManagerEvdev *manager_evdev) -{ - dispatch_libinput (manager_evdev); -} - -static int -compare_ids (gconstpointer a, - gconstpointer b) -{ - return GPOINTER_TO_INT (a) - GPOINTER_TO_INT (b); -} - -void -_clutter_device_manager_evdev_release_device_id (ClutterDeviceManagerEvdev *manager_evdev, - ClutterInputDevice *device) -{ - ClutterDeviceManagerEvdevPrivate *priv = manager_evdev->priv; - gint device_id; - - device_id = clutter_input_device_get_device_id (device); - priv->free_device_ids = g_list_insert_sorted (priv->free_device_ids, - GINT_TO_POINTER (device_id), - compare_ids); -} - -struct xkb_keymap * -_clutter_device_manager_evdev_get_keymap (ClutterDeviceManagerEvdev *manager_evdev) -{ - ClutterDeviceManagerEvdevPrivate *priv = manager_evdev->priv; - - return priv->keymap; -} - -ClutterStage * -_clutter_device_manager_evdev_get_stage (ClutterDeviceManagerEvdev *manager_evdev) -{ - ClutterDeviceManagerEvdevPrivate *priv = manager_evdev->priv; - - return priv->stage; -} - -/** - * clutter_evdev_release_devices: - * - * Releases all the evdev devices that Clutter is currently managing. This api - * is typically used when switching away from the Clutter application when - * switching tty. The devices can be reclaimed later with a call to - * clutter_evdev_reclaim_devices(). - * - * This function should only be called after clutter has been initialized. - * - * Since: 1.10 - * Stability: unstable - */ -void -clutter_evdev_release_devices (void) -{ - ClutterDeviceManager *manager = clutter_device_manager_get_default (); - ClutterDeviceManagerEvdev *manager_evdev; - ClutterDeviceManagerEvdevPrivate *priv; - - if (!manager) - { - g_warning ("clutter_evdev_release_devices shouldn't be called " - "before clutter_init()"); - return; - } - - g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER_EVDEV (manager)); - - manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (manager); - priv = manager_evdev->priv; - - if (priv->released) - { - g_warning ("clutter_evdev_release_devices() shouldn't be called " - "multiple times without a corresponding call to " - "clutter_evdev_reclaim_devices() first"); - return; - } - - libinput_suspend (priv->libinput); - process_events (manager_evdev); - - priv->released = TRUE; -} - -static void -clutter_evdev_update_xkb_state (ClutterDeviceManagerEvdev *manager_evdev) -{ - ClutterDeviceManagerEvdevPrivate *priv; - GSList *iter; - ClutterSeatEvdev *seat; - xkb_mod_mask_t latched_mods; - xkb_mod_mask_t locked_mods; - - priv = manager_evdev->priv; - - for (iter = priv->seats; iter; iter = iter->next) - { - seat = iter->data; - - latched_mods = xkb_state_serialize_mods (seat->xkb, - XKB_STATE_MODS_LATCHED); - locked_mods = xkb_state_serialize_mods (seat->xkb, - XKB_STATE_MODS_LOCKED); - xkb_state_unref (seat->xkb); - seat->xkb = xkb_state_new (priv->keymap); - - xkb_state_update_mask (seat->xkb, - 0, /* depressed */ - latched_mods, - locked_mods, - 0, 0, seat->layout_idx); - - seat->caps_lock_led = xkb_keymap_led_get_index (priv->keymap, XKB_LED_NAME_CAPS); - seat->num_lock_led = xkb_keymap_led_get_index (priv->keymap, XKB_LED_NAME_NUM); - seat->scroll_lock_led = xkb_keymap_led_get_index (priv->keymap, XKB_LED_NAME_SCROLL); - - clutter_seat_evdev_sync_leds (seat); - } -} - -/** - * clutter_evdev_reclaim_devices: - * - * This causes Clutter to re-probe for evdev devices. This is must only be - * called after a corresponding call to clutter_evdev_release_devices() - * was previously used to release all evdev devices. This API is typically - * used when a clutter application using evdev has regained focus due to - * switching ttys. - * - * This function should only be called after clutter has been initialized. - * - * Since: 1.10 - * Stability: unstable - */ -void -clutter_evdev_reclaim_devices (void) -{ - ClutterDeviceManager *manager = clutter_device_manager_get_default (); - ClutterDeviceManagerEvdev *manager_evdev = - CLUTTER_DEVICE_MANAGER_EVDEV (manager); - ClutterDeviceManagerEvdevPrivate *priv = manager_evdev->priv; - - if (!priv->released) - { - g_warning ("Spurious call to clutter_evdev_reclaim_devices() without " - "previous call to clutter_evdev_release_devices"); - return; - } - - libinput_resume (priv->libinput); - clutter_evdev_update_xkb_state (manager_evdev); - process_events (manager_evdev); - - priv->released = FALSE; -} - -/** - * clutter_evdev_set_device_callbacks: (skip) - * @open_callback: the user replacement for open() - * @close_callback: the user replacement for close() - * @user_data: user data for @callback - * - * Through this function, the application can set a custom callback - * to invoked when Clutter is about to open an evdev device. It can do - * so if special handling is needed, for example to circumvent permission - * problems. - * - * Setting @callback to %NULL will reset the default behavior. - * - * For reliable effects, this function must be called before clutter_init(). - * - * Since: 1.16 - * Stability: unstable - */ -void -clutter_evdev_set_device_callbacks (ClutterOpenDeviceCallback open_callback, - ClutterCloseDeviceCallback close_callback, - gpointer user_data) -{ - device_open_callback = open_callback; - device_close_callback = close_callback; - device_callback_data = user_data; -} - -/** - * clutter_evdev_set_keyboard_map: (skip) - * @evdev: the #ClutterDeviceManager created by the evdev backend - * @keymap: the new keymap - * - * Instructs @evdev to use the speficied keyboard map. This will cause - * the backend to drop the state and create a new one with the new - * map. To avoid state being lost, callers should ensure that no key - * is pressed when calling this function. - * - * Since: 1.16 - * Stability: unstable - */ -void -clutter_evdev_set_keyboard_map (ClutterDeviceManager *evdev, - struct xkb_keymap *keymap) -{ - ClutterDeviceManagerEvdev *manager_evdev; - ClutterDeviceManagerEvdevPrivate *priv; - - g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER_EVDEV (evdev)); - - manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (evdev); - priv = manager_evdev->priv; - - if (priv->keymap) - xkb_keymap_unref (priv->keymap); - - priv->keymap = xkb_keymap_ref (keymap); - clutter_evdev_update_xkb_state (manager_evdev); -} - -/** - * clutter_evdev_get_keyboard_map: (skip) - * @evdev: the #ClutterDeviceManager created by the evdev backend - * - * Retrieves the #xkb_keymap in use by the evdev backend. - * - * Return value: the #xkb_keymap. - * - * Since: 1.18 - * Stability: unstable - */ -struct xkb_keymap * -clutter_evdev_get_keyboard_map (ClutterDeviceManager *evdev) -{ - ClutterDeviceManagerEvdev *manager_evdev; - - g_return_val_if_fail (CLUTTER_IS_DEVICE_MANAGER_EVDEV (evdev), NULL); - - manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (evdev); - - return xkb_state_get_keymap (manager_evdev->priv->main_seat->xkb); -} - -/** - * clutter_evdev_set_keyboard_layout_index: (skip) - * @evdev: the #ClutterDeviceManager created by the evdev backend - * @idx: the xkb layout index to set - * - * Sets the xkb layout index on the backend's #xkb_state . - * - * Since: 1.20 - * Stability: unstable - */ -void -clutter_evdev_set_keyboard_layout_index (ClutterDeviceManager *evdev, - xkb_layout_index_t idx) -{ - ClutterDeviceManagerEvdev *manager_evdev; - xkb_mod_mask_t depressed_mods; - xkb_mod_mask_t latched_mods; - xkb_mod_mask_t locked_mods; - struct xkb_state *state; - GSList *l; - - g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER_EVDEV (evdev)); - - manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (evdev); - state = manager_evdev->priv->main_seat->xkb; - - depressed_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_DEPRESSED); - latched_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_LATCHED); - locked_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED); - - xkb_state_update_mask (state, depressed_mods, latched_mods, locked_mods, 0, 0, idx); - for (l = manager_evdev->priv->seats; l; l = l->next) - { - ClutterSeatEvdev *seat = l->data; - - seat->layout_idx = idx; - } -} - -/** - * clutter_evdev_get_keyboard_layout_index: (skip) - */ -xkb_layout_index_t -clutter_evdev_get_keyboard_layout_index (ClutterDeviceManager *evdev) -{ - ClutterDeviceManagerEvdev *manager_evdev; - - manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (evdev); - return manager_evdev->priv->main_seat->layout_idx; -} - -/** - * clutter_evdev_set_keyboard_numlock: (skip) - * @evdev: the #ClutterDeviceManager created by the evdev backend - * @numlock_set: TRUE to set NumLock ON, FALSE otherwise. - * - * Sets the NumLock state on the backend's #xkb_state . - * - * Stability: unstable - */ -void -clutter_evdev_set_keyboard_numlock (ClutterDeviceManager *evdev, - gboolean numlock_state) -{ - ClutterDeviceManagerEvdev *manager_evdev; - ClutterDeviceManagerEvdevPrivate *priv; - GSList *iter; - xkb_mod_mask_t numlock; - - g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER_EVDEV (evdev)); - - manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (evdev); - priv = manager_evdev->priv; - numlock = (1 << xkb_keymap_mod_get_index(priv->keymap, "Mod2")); - - for (iter = priv->seats; iter; iter = iter->next) - { - ClutterSeatEvdev *seat = iter->data; - xkb_mod_mask_t depressed_mods; - xkb_mod_mask_t latched_mods; - xkb_mod_mask_t locked_mods; - xkb_mod_mask_t group_mods; - - depressed_mods = xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_DEPRESSED); - latched_mods = xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_LATCHED); - locked_mods = xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_LOCKED); - group_mods = xkb_state_serialize_layout (seat->xkb, XKB_STATE_LAYOUT_EFFECTIVE); - - if (numlock_state) - locked_mods |= numlock; - else - locked_mods &= ~numlock; - - xkb_state_update_mask (seat->xkb, - depressed_mods, - latched_mods, - locked_mods, - 0, 0, - group_mods); - - clutter_seat_evdev_sync_leds (seat); - } -} - - -/** - * clutter_evdev_set_pointer_constrain_callback: - * @evdev: the #ClutterDeviceManager created by the evdev backend - * @callback: the callback - * @user_data: data to pass to the callback - * @user_data_notify: function to be called when removing the callback - * - * Sets a callback to be invoked for every pointer motion. The callback - * can then modify the new pointer coordinates to constrain movement within - * a specific region. - * - * Since: 1.16 - * Stability: unstable - */ -void -clutter_evdev_set_pointer_constrain_callback (ClutterDeviceManager *evdev, - ClutterPointerConstrainCallback callback, - gpointer user_data, - GDestroyNotify user_data_notify) -{ - ClutterDeviceManagerEvdev *manager_evdev; - ClutterDeviceManagerEvdevPrivate *priv; - - g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER_EVDEV (evdev)); - - manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (evdev); - priv = manager_evdev->priv; - - if (priv->constrain_data_notify) - priv->constrain_data_notify (priv->constrain_data); - - priv->constrain_callback = callback; - priv->constrain_data = user_data; - priv->constrain_data_notify = user_data_notify; -} - -void -clutter_evdev_set_relative_motion_filter (ClutterDeviceManager *evdev, - ClutterRelativeMotionFilter filter, - gpointer user_data) -{ - ClutterDeviceManagerEvdev *manager_evdev; - ClutterDeviceManagerEvdevPrivate *priv; - - g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER_EVDEV (evdev)); - - manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (evdev); - priv = manager_evdev->priv; - - priv->relative_motion_filter = filter; - priv->relative_motion_filter_user_data = user_data; -} - -/** - * clutter_evdev_set_keyboard_repeat: - * @evdev: the #ClutterDeviceManager created by the evdev backend - * @repeat: whether to enable or disable keyboard repeat events - * @delay: the delay in ms between the hardware key press event and - * the first synthetic event - * @interval: the period in ms between consecutive synthetic key - * press events - * - * Enables or disables sythetic key press events, allowing for initial - * delay and interval period to be specified. - * - * Since: 1.18 - * Stability: unstable - */ -void -clutter_evdev_set_keyboard_repeat (ClutterDeviceManager *evdev, - gboolean repeat, - guint32 delay, - guint32 interval) -{ - ClutterDeviceManagerEvdev *manager_evdev; - ClutterSeatEvdev *seat; - - g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER_EVDEV (evdev)); - - manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (evdev); - seat = manager_evdev->priv->main_seat; - - seat->repeat = repeat; - seat->repeat_delay = delay; - seat->repeat_interval = interval; -} - -/** - * clutter_evdev_add_filter: (skip) - * @func: (closure data): a filter function - * @data: (allow-none): user data to be passed to the filter function, or %NULL - * @destroy_notify: (allow-none): function to call on @data when the filter is removed, or %NULL - * - * Adds an event filter function. - * - * Since: 1.20 - * Stability: unstable - */ -void -clutter_evdev_add_filter (ClutterEvdevFilterFunc func, - gpointer data, - GDestroyNotify destroy_notify) -{ - ClutterDeviceManagerEvdev *manager_evdev; - ClutterDeviceManager *manager; - ClutterEventFilter *filter; - - g_return_if_fail (func != NULL); - - manager = clutter_device_manager_get_default (); - - if (!CLUTTER_IS_DEVICE_MANAGER_EVDEV (manager)) - { - g_critical ("The Clutter input backend is not a evdev backend"); - return; - } - - manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (manager); - - filter = g_new0 (ClutterEventFilter, 1); - filter->func = func; - filter->data = data; - filter->destroy_notify = destroy_notify; - - manager_evdev->priv->event_filters = - g_slist_append (manager_evdev->priv->event_filters, filter); -} - -/** - * clutter_evdev_remove_filter: (skip) - * @func: a filter function - * @data: (allow-none): user data to be passed to the filter function, or %NULL - * - * Removes the given filter function. - * - * Since: 1.20 - * Stability: unstable - */ -void -clutter_evdev_remove_filter (ClutterEvdevFilterFunc func, - gpointer data) -{ - ClutterDeviceManagerEvdev *manager_evdev; - ClutterDeviceManager *manager; - ClutterEventFilter *filter; - GSList *tmp_list; - - g_return_if_fail (func != NULL); - - manager = clutter_device_manager_get_default (); - - if (!CLUTTER_IS_DEVICE_MANAGER_EVDEV (manager)) - { - g_critical ("The Clutter input backend is not a evdev backend"); - return; - } - - manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (manager); - tmp_list = manager_evdev->priv->event_filters; - - while (tmp_list) - { - filter = tmp_list->data; - - if (filter->func == func && filter->data == data) - { - if (filter->destroy_notify) - filter->destroy_notify (filter->data); - free (filter); - manager_evdev->priv->event_filters = - g_slist_delete_link (manager_evdev->priv->event_filters, tmp_list); - return; - } - - tmp_list = tmp_list->next; - } -} - -/** - * clutter_evdev_warp_pointer: - * @pointer_device: the pointer device to warp - * @time: the timestamp for the warp event - * @x: the new X position of the pointer - * @y: the new Y position of the pointer - * - * Warps the pointer to a new location. Technically, this is - * processed the same way as an absolute motion event from - * libinput: it simply generates an absolute motion event that - * will be processed on the next iteration of the mainloop. - * - * The intended use for this is for display servers that need - * to warp cursor the cursor to a new location. - * - * Since: 1.20 - * Stability: unstable - */ -void -clutter_evdev_warp_pointer (ClutterInputDevice *pointer_device, - guint32 time_, - int x, - int y) -{ - notify_absolute_motion (pointer_device, ms2us(time_), x, y, NULL); -} - -/** - * clutter_evdev_set_seat_id: - * @seat_id: The seat ID - * - * Sets the seat to assign to the libinput context. - * - * For reliable effects, this function must be called before clutter_init(). - */ -void -clutter_evdev_set_seat_id (const gchar *seat_id) -{ - free (evdev_seat_id); - evdev_seat_id = g_strdup (seat_id); -} diff --git a/clutter/clutter/evdev/clutter-device-manager-evdev.h b/clutter/clutter/evdev/clutter-device-manager-evdev.h deleted file mode 100644 index 2b87a444a..000000000 --- a/clutter/clutter/evdev/clutter-device-manager-evdev.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corp. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Damien Lespiau - */ - -#ifndef __CLUTTER_DEVICE_MANAGER_EVDEV_H__ -#define __CLUTTER_DEVICE_MANAGER_EVDEV_H__ - -#include -#include - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_DEVICE_MANAGER_EVDEV (clutter_device_manager_evdev_get_type ()) -#define CLUTTER_DEVICE_MANAGER_EVDEV(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_DEVICE_MANAGER_EVDEV, ClutterDeviceManagerEvdev)) -#define CLUTTER_IS_DEVICE_MANAGER_EVDEV(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_DEVICE_MANAGER_EVDEV)) -#define CLUTTER_DEVICE_MANAGER_EVDEV_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_DEVICE_MANAGER_EVDEV, ClutterDeviceManagerEvdevClass)) -#define CLUTTER_IS_DEVICE_MANAGER_EVDEV_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_DEVICE_MANAGER_EVDEV)) -#define CLUTTER_DEVICE_MANAGER_EVDEV_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_DEVICE_MANAGER_EVDEV, ClutterDeviceManagerEvdevClass)) - -typedef struct _ClutterDeviceManagerEvdev ClutterDeviceManagerEvdev; -typedef struct _ClutterDeviceManagerEvdevClass ClutterDeviceManagerEvdevClass; -typedef struct _ClutterDeviceManagerEvdevPrivate ClutterDeviceManagerEvdevPrivate; - -typedef struct _ClutterSeatEvdev ClutterSeatEvdev; - -struct _ClutterDeviceManagerEvdev -{ - ClutterDeviceManager parent_instance; - - ClutterDeviceManagerEvdevPrivate *priv; -}; - -struct _ClutterDeviceManagerEvdevClass -{ - ClutterDeviceManagerClass parent_class; -}; - -GType clutter_device_manager_evdev_get_type (void) G_GNUC_CONST; - -void _clutter_events_evdev_init (ClutterBackend *backend); -void _clutter_events_evdev_uninit (ClutterBackend *backend); - -gint _clutter_device_manager_evdev_acquire_device_id (ClutterDeviceManagerEvdev *manager_evdev); - -void _clutter_device_manager_evdev_release_device_id (ClutterDeviceManagerEvdev *manager_evdev, - ClutterInputDevice *device); - -struct xkb_keymap * _clutter_device_manager_evdev_get_keymap (ClutterDeviceManagerEvdev *manager_evdev); - -ClutterStage * _clutter_device_manager_evdev_get_stage (ClutterDeviceManagerEvdev *manager_evdev); - -void _clutter_device_manager_evdev_constrain_pointer (ClutterDeviceManagerEvdev *manager_evdev, - ClutterInputDevice *core_pointer, - uint64_t time_us, - float x, - float y, - float *new_x, - float *new_y); - -void _clutter_device_manager_evdev_filter_relative_motion (ClutterDeviceManagerEvdev *manager_evdev, - ClutterInputDevice *device, - float x, - float y, - float *dx, - float *dy); - -void _clutter_device_manager_evdev_dispatch (ClutterDeviceManagerEvdev *manager_evdev); - -static inline guint64 -us (guint64 us) -{ - return us; -} - -static inline guint64 -ms2us (guint64 ms) -{ - return us (ms * 1000); -} - -static inline guint32 -us2ms (guint64 us) -{ - return (guint32) (us / 1000); -} - -G_END_DECLS - -#endif /* __CLUTTER_DEVICE_MANAGER_EVDEV_H__ */ diff --git a/clutter/clutter/evdev/clutter-evdev.h b/clutter/clutter/evdev/clutter-evdev.h deleted file mode 100644 index bd46bc9f2..000000000 --- a/clutter/clutter/evdev/clutter-evdev.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2012 Intel Corp. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __CLUTTER_EVDEV_H__ -#define __CLUTTER_EVDEV_H__ - -#include -#include -#include -#include -#include - -G_BEGIN_DECLS - -#if !defined(CLUTTER_ENABLE_COMPOSITOR_API) && !defined(CLUTTER_COMPILATION) -#error "You need to define CLUTTER_ENABLE_COMPOSITOR_API before including clutter-evdev.h" -#endif - -/** - * ClutterOpenDeviceCallback: - * @path: the device path - * @flags: flags to be passed to open - * - * This callback will be called when Clutter needs to access an input - * device. It should return an open file descriptor for the file at @path, - * or -1 if opening failed. - */ -typedef int (*ClutterOpenDeviceCallback) (const char *path, - int flags, - gpointer user_data, - GError **error); -typedef void (*ClutterCloseDeviceCallback) (int fd, - gpointer user_data); - -CLUTTER_AVAILABLE_IN_1_16 -void clutter_evdev_set_device_callbacks (ClutterOpenDeviceCallback open_callback, - ClutterCloseDeviceCallback close_callback, - gpointer user_data); - -CLUTTER_AVAILABLE_IN_ALL -void clutter_evdev_set_seat_id (const gchar *seat_id); - -CLUTTER_AVAILABLE_IN_1_10 -void clutter_evdev_release_devices (void); -CLUTTER_AVAILABLE_IN_1_10 -void clutter_evdev_reclaim_devices (void); - -/** - * ClutterPointerConstrainCallback: - * @device: the core pointer device - * @time: the event time in milliseconds - * @x: (inout): the new X coordinate - * @y: (inout): the new Y coordinate - * @user_data: user data passed to this function - * - * This callback will be called for all pointer motion events, and should - * update (@x, @y) to constrain the pointer position appropriately. - * The subsequent motion event will use the updated values as the new coordinates. - * Note that the coordinates are not clamped to the stage size, and the callback - * must make sure that this happens before it returns. - * Also note that the event will be emitted even if the pointer is constrained - * to be in the same position. - * - * Since: 1.16 - */ -typedef void (*ClutterPointerConstrainCallback) (ClutterInputDevice *device, - guint32 time, - float prev_x, - float prev_y, - float *x, - float *y, - gpointer user_data); - -CLUTTER_AVAILABLE_IN_1_16 -void clutter_evdev_set_pointer_constrain_callback (ClutterDeviceManager *evdev, - ClutterPointerConstrainCallback callback, - gpointer user_data, - GDestroyNotify user_data_notify); - -typedef void (*ClutterRelativeMotionFilter) (ClutterInputDevice *device, - float x, - float y, - float *dx, - float *dy, - gpointer user_data); - -CLUTTER_AVAILABLE_IN_MUFFIN -void clutter_evdev_set_relative_motion_filter (ClutterDeviceManager *evdev, - ClutterRelativeMotionFilter filter, - gpointer user_data); - -CLUTTER_AVAILABLE_IN_1_16 -void clutter_evdev_set_keyboard_map (ClutterDeviceManager *evdev, - struct xkb_keymap *keymap); - -CLUTTER_AVAILABLE_IN_1_18 -struct xkb_keymap * clutter_evdev_get_keyboard_map (ClutterDeviceManager *evdev); - -CLUTTER_AVAILABLE_IN_1_20 -void clutter_evdev_set_keyboard_layout_index (ClutterDeviceManager *evdev, - xkb_layout_index_t idx); - -CLUTTER_AVAILABLE_IN_MUFFIN -xkb_layout_index_t clutter_evdev_get_keyboard_layout_index (ClutterDeviceManager *evdev); - -CLUTTER_AVAILABLE_IN_1_26 -void clutter_evdev_set_keyboard_numlock (ClutterDeviceManager *evdev, - gboolean numlock_state); - -CLUTTER_AVAILABLE_IN_1_18 -void clutter_evdev_set_keyboard_repeat (ClutterDeviceManager *evdev, - gboolean repeat, - guint32 delay, - guint32 interval); - -typedef gboolean (* ClutterEvdevFilterFunc) (struct libinput_event *event, - gpointer data); - -CLUTTER_AVAILABLE_IN_1_20 -void clutter_evdev_add_filter (ClutterEvdevFilterFunc func, - gpointer data, - GDestroyNotify destroy_notify); -CLUTTER_AVAILABLE_IN_1_20 -void clutter_evdev_remove_filter (ClutterEvdevFilterFunc func, - gpointer data); -CLUTTER_AVAILABLE_IN_1_20 -struct libinput_device * clutter_evdev_input_device_get_libinput_device (ClutterInputDevice *device); - -CLUTTER_AVAILABLE_IN_1_20 -gint32 clutter_evdev_event_sequence_get_slot (const ClutterEventSequence *sequence); - -CLUTTER_AVAILABLE_IN_1_20 -void clutter_evdev_warp_pointer (ClutterInputDevice *pointer_device, - guint32 time_, - int x, - int y); - -CLUTTER_AVAILABLE_IN_1_26 -guint32 clutter_evdev_event_get_event_code (const ClutterEvent *event); - -CLUTTER_AVAILABLE_IN_1_26 -guint64 clutter_evdev_event_get_time_usec (const ClutterEvent *event); - -CLUTTER_AVAILABLE_IN_1_26 -gboolean clutter_evdev_event_get_relative_motion (const ClutterEvent *event, - double *dx, - double *dy, - double *dx_unaccel, - double *dy_unaccel); - -CLUTTER_AVAILABLE_IN_ALL -void clutter_evdev_input_device_tool_set_pressure_curve (ClutterInputDeviceTool *tool, - gdouble curve[4]); -CLUTTER_AVAILABLE_IN_ALL -void clutter_evdev_input_device_tool_set_button_code (ClutterInputDeviceTool *tool, - guint button, - guint evcode); - -G_END_DECLS - -#endif /* __CLUTTER_EVDEV_H__ */ diff --git a/clutter/clutter/evdev/clutter-event-evdev.c b/clutter/clutter/evdev/clutter-event-evdev.c deleted file mode 100644 index 737859dd4..000000000 --- a/clutter/clutter/evdev/clutter-event-evdev.c +++ /dev/null @@ -1,191 +0,0 @@ -/* Clutter. - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2015 Red Hat - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Authored by: - * Carlos Garnacho - */ - -#include "clutter-build-config.h" - -#include "clutter/clutter-device-manager-private.h" -#include "clutter/clutter-event-private.h" -#include "clutter-input-device-evdev.h" -#include "clutter-evdev.h" - -typedef struct _ClutterEventEvdev ClutterEventEvdev; - -struct _ClutterEventEvdev -{ - guint32 evcode; - - guint64 time_usec; - - gboolean has_relative_motion; - double dx; - double dy; - double dx_unaccel; - double dy_unaccel; -}; - -static ClutterEventEvdev * -_clutter_event_evdev_new (void) -{ - return g_slice_new0 (ClutterEventEvdev); -} - -ClutterEventEvdev * -_clutter_event_evdev_copy (ClutterEventEvdev *event_evdev) -{ - if (event_evdev != NULL) - return g_slice_dup (ClutterEventEvdev, event_evdev); - - return NULL; -} - -void -_clutter_event_evdev_free (ClutterEventEvdev *event_evdev) -{ - if (event_evdev != NULL) - g_slice_free (ClutterEventEvdev, event_evdev); -} - -static ClutterEventEvdev * -clutter_evdev_event_ensure_platform_data (ClutterEvent *event) -{ - ClutterEventEvdev *event_evdev = _clutter_event_get_platform_data (event); - - if (!event_evdev) - { - event_evdev = _clutter_event_evdev_new (); - _clutter_event_set_platform_data (event, event_evdev); - } - - return event_evdev; -} - -void -_clutter_evdev_event_set_event_code (ClutterEvent *event, - guint32 evcode) -{ - ClutterEventEvdev *event_evdev; - - event_evdev = clutter_evdev_event_ensure_platform_data (event); - event_evdev->evcode = evcode; -} - -void -_clutter_evdev_event_set_time_usec (ClutterEvent *event, - guint64 time_usec) -{ - ClutterEventEvdev *event_evdev; - - event_evdev = clutter_evdev_event_ensure_platform_data (event); - event_evdev->time_usec = time_usec; -} - -void -_clutter_evdev_event_set_relative_motion (ClutterEvent *event, - double dx, - double dy, - double dx_unaccel, - double dy_unaccel) -{ - ClutterEventEvdev *event_evdev; - - event_evdev = clutter_evdev_event_ensure_platform_data (event); - event_evdev->dx = dx; - event_evdev->dy = dy; - event_evdev->dx_unaccel = dx_unaccel; - event_evdev->dy_unaccel = dy_unaccel; - event_evdev->has_relative_motion = TRUE; -} - -/** - * clutter_evdev_event_get_event_code: - * @event: a #ClutterEvent - * - * Returns the event code of the original event. See linux/input.h for more - * information. - * - * Returns: The event code. - **/ -guint32 -clutter_evdev_event_get_event_code (const ClutterEvent *event) -{ - ClutterEventEvdev *event_evdev = _clutter_event_get_platform_data (event); - - if (event_evdev) - return event_evdev->evcode; - - return 0; -} - -/** - * clutter_evdev_event_get_time_usec: - * @event: a #ClutterEvent - * - * Returns the time in microsecond granularity, or 0 if unavailable. - * - * Returns: The time in microsecond granularity, or 0 if unavailable. - */ -guint64 -clutter_evdev_event_get_time_usec (const ClutterEvent *event) -{ - ClutterEventEvdev *event_evdev = _clutter_event_get_platform_data (event); - - if (event_evdev) - return event_evdev->time_usec; - - return 0; -} - -/** - * clutter_evdev_event_get_pointer_motion - * @event: a #ClutterEvent - * - * If available, the normal and unaccelerated motion deltas are written - * to the dx, dy, dx_unaccel and dy_unaccel and TRUE is returned. - * - * If unavailable, FALSE is returned. - * - * Returns: TRUE on success, otherwise FALSE. - **/ -gboolean -clutter_evdev_event_get_relative_motion (const ClutterEvent *event, - double *dx, - double *dy, - double *dx_unaccel, - double *dy_unaccel) -{ - ClutterEventEvdev *event_evdev = _clutter_event_get_platform_data (event); - - if (event_evdev && event_evdev->has_relative_motion) - { - if (dx) - *dx = event_evdev->dx; - if (dy) - *dy = event_evdev->dy; - if (dx_unaccel) - *dx_unaccel = event_evdev->dx_unaccel; - if (dy_unaccel) - *dy_unaccel = event_evdev->dy_unaccel; - return TRUE; - } - else - return FALSE; -} diff --git a/clutter/clutter/evdev/clutter-input-device-evdev.h b/clutter/clutter/evdev/clutter-input-device-evdev.h deleted file mode 100644 index 90463ee14..000000000 --- a/clutter/clutter/evdev/clutter-input-device-evdev.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corp. - * Copyright (C) 2014 Jonas Ådahl - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Damien Lespiau - * Author: Jonas Ådahl - */ - -#ifndef __CLUTTER_INPUT_DEVICE_EVDEV_H__ -#define __CLUTTER_INPUT_DEVICE_EVDEV_H__ - -#include -#include - -#include "clutter/clutter-device-manager-private.h" -#include "evdev/clutter-seat-evdev.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_INPUT_DEVICE_EVDEV _clutter_input_device_evdev_get_type() - -#define CLUTTER_INPUT_DEVICE_EVDEV(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ - CLUTTER_TYPE_INPUT_DEVICE_EVDEV, ClutterInputDeviceEvdev)) - -#define CLUTTER_INPUT_DEVICE_EVDEV_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), \ - CLUTTER_TYPE_INPUT_DEVICE_EVDEV, ClutterInputDeviceEvdevClass)) - -#define CLUTTER_IS_INPUT_DEVICE_EVDEV(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ - CLUTTER_TYPE_INPUT_DEVICE_EVDEV)) - -#define CLUTTER_IS_INPUT_DEVICE_EVDEV_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), \ - CLUTTER_TYPE_INPUT_DEVICE_EVDEV)) - -#define CLUTTER_INPUT_DEVICE_EVDEV_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), \ - CLUTTER_TYPE_INPUT_DEVICE_EVDEV, ClutterInputDeviceEvdevClass)) - -typedef struct _ClutterInputDeviceEvdev ClutterInputDeviceEvdev; -typedef struct _ClutterEventEvdev ClutterEventEvdev; - -struct _ClutterInputDeviceEvdev -{ - ClutterInputDevice parent; - - struct libinput_device *libinput_device; - ClutterSeatEvdev *seat; - ClutterInputDeviceTool *last_tool; - - cairo_matrix_t device_matrix; - gdouble device_aspect_ratio; /* w:h */ - gdouble output_ratio; /* w:h */ - - GHashTable *touches; - - /* Keyboard a11y */ - ClutterKeyboardA11yFlags a11y_flags; - GList *slow_keys_list; - guint debounce_timer; - guint16 debounce_key; - xkb_mod_mask_t stickykeys_depressed_mask; - xkb_mod_mask_t stickykeys_latched_mask; - xkb_mod_mask_t stickykeys_locked_mask; - guint toggle_slowkeys_timer; - guint16 shift_count; - guint32 last_shift_time; - gint mousekeys_btn; - gboolean mousekeys_btn_states[3]; - guint32 mousekeys_first_motion_time; /* ms */ - guint32 mousekeys_last_motion_time; /* ms */ - guint mousekeys_init_delay; - guint mousekeys_accel_time; - guint mousekeys_max_speed; - gdouble mousekeys_curve_factor; - guint move_mousekeys_timer; - guint16 last_mousekeys_key; - ClutterVirtualInputDevice *mousekeys_virtual_device; -}; - -GType _clutter_input_device_evdev_get_type (void) G_GNUC_CONST; - -ClutterInputDevice * _clutter_input_device_evdev_new (ClutterDeviceManager *manager, - ClutterSeatEvdev *seat, - struct libinput_device *libinput_device); - -ClutterInputDevice * _clutter_input_device_evdev_new_virtual (ClutterDeviceManager *manager, - ClutterSeatEvdev *seat, - ClutterInputDeviceType type, - ClutterInputMode mode); - -ClutterSeatEvdev * _clutter_input_device_evdev_get_seat (ClutterInputDeviceEvdev *device); - -void _clutter_input_device_evdev_update_leds (ClutterInputDeviceEvdev *device, - enum libinput_led leds); - -ClutterInputDeviceType _clutter_input_device_evdev_determine_type (struct libinput_device *libinput_device); - - -ClutterEventEvdev * _clutter_event_evdev_copy (ClutterEventEvdev *event_evdev); -void _clutter_event_evdev_free (ClutterEventEvdev *event_evdev); - -void _clutter_evdev_event_set_event_code (ClutterEvent *event, - guint32 evcode); - -void _clutter_evdev_event_set_time_usec (ClutterEvent *event, - guint64 time_usec); - -void _clutter_evdev_event_set_relative_motion (ClutterEvent *event, - double dx, - double dy, - double dx_unaccel, - double dy_unaccel); - -void clutter_input_device_evdev_translate_coordinates (ClutterInputDevice *device, - ClutterStage *stage, - gfloat *x, - gfloat *y); - -void clutter_input_device_evdev_apply_kbd_a11y_settings (ClutterInputDeviceEvdev *device, - ClutterKbdA11ySettings *settings); - -ClutterTouchState * clutter_input_device_evdev_acquire_touch_state (ClutterInputDeviceEvdev *device, - int device_slot); - -ClutterTouchState * clutter_input_device_evdev_lookup_touch_state (ClutterInputDeviceEvdev *device, - int device_slot); - -void clutter_input_device_evdev_release_touch_state (ClutterInputDeviceEvdev *device, - ClutterTouchState *touch_state); - -void clutter_input_device_evdev_release_touch_slots (ClutterInputDeviceEvdev *device_evdev, - uint64_t time_us); - - -G_END_DECLS - -#endif /* __CLUTTER_INPUT_DEVICE_EVDEV_H__ */ diff --git a/clutter/clutter/evdev/clutter-input-device-tool-evdev.h b/clutter/clutter/evdev/clutter-input-device-tool-evdev.h deleted file mode 100644 index 91eaf8e04..000000000 --- a/clutter/clutter/evdev/clutter-input-device-tool-evdev.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright © 2009, 2010, 2011 Intel Corp. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Carlos Garnacho - */ - -#ifndef __CLUTTER_INPUT_DEVICE_EVDEV_TOOL_H__ -#define __CLUTTER_INPUT_DEVICE_EVDEV_TOOL_H__ - -#include - -#include - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_INPUT_DEVICE_TOOL_EVDEV (clutter_input_device_tool_evdev_get_type ()) - -#define CLUTTER_INPUT_DEVICE_TOOL_EVDEV(o) \ - (G_TYPE_CHECK_INSTANCE_CAST ((o), \ - CLUTTER_TYPE_INPUT_DEVICE_TOOL_EVDEV, ClutterInputDeviceToolEvdev)) - -#define CLUTTER_IS_INPUT_DEVICE_TOOL_EVDEV(o) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((o), \ - CLUTTER_TYPE_INPUT_DEVICE_TOOL_EVDEV)) - -#define CLUTTER_INPUT_DEVICE_TOOL_EVDEV_CLASS(c) \ - (G_TYPE_CHECK_CLASS_CAST ((c), \ - CLUTTER_TYPE_INPUT_DEVICE_TOOL_EVDEV, ClutterInputDeviceToolEvdevClass)) - -#define CLUTTER_IS_INPUT_DEVICE_TOOL_EVDEV_CLASS(c) \ - (G_TYPE_CHECK_CLASS_TYPE ((c), \ - CLUTTER_TYPE_INPUT_DEVICE_TOOL_EVDEV)) - -#define CLUTTER_INPUT_DEVICE_TOOL_EVDEV_GET_CLASS(o) \ - (G_TYPE_INSTANCE_GET_CLASS ((o), \ - CLUTTER_TYPE_INPUT_DEVICE_TOOL_EVDEV, ClutterInputDeviceToolEvdevClass)) - -typedef struct _ClutterInputDeviceToolEvdev ClutterInputDeviceToolEvdev; -typedef struct _ClutterInputDeviceToolEvdevClass ClutterInputDeviceToolEvdevClass; - -struct _ClutterInputDeviceToolEvdev -{ - ClutterInputDeviceTool parent_instance; - struct libinput_tablet_tool *tool; - GHashTable *button_map; - gdouble pressure_curve[4]; -}; - -struct _ClutterInputDeviceToolEvdevClass -{ - ClutterInputDeviceToolClass parent_class; -}; - -GType clutter_input_device_tool_evdev_get_type (void) G_GNUC_CONST; - -ClutterInputDeviceTool * clutter_input_device_tool_evdev_new (struct libinput_tablet_tool *tool, - guint64 serial, - ClutterInputDeviceToolType type); - -gdouble clutter_input_device_tool_evdev_translate_pressure (ClutterInputDeviceTool *tool, - gdouble pressure); -guint clutter_input_device_tool_evdev_get_button_code (ClutterInputDeviceTool *tool, - guint button); - -G_END_DECLS - -#endif /* __CLUTTER_INPUT_DEVICE_EVDEV_TOOL_H__ */ diff --git a/clutter/clutter/evdev/clutter-seat-evdev.c b/clutter/clutter/evdev/clutter-seat-evdev.c deleted file mode 100644 index 276bf3feb..000000000 --- a/clutter/clutter/evdev/clutter-seat-evdev.c +++ /dev/null @@ -1,893 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corp. - * Copyright (C) 2014 Jonas Ådahl - * Copyright (C) 2016 Red Hat Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Damien Lespiau - * Author: Jonas Ådahl - */ - -#include "clutter-build-config.h" - -#include "clutter-seat-evdev.h" - -#include -#include - -#include "clutter-event-private.h" -#include "clutter-input-device-evdev.h" -#include "clutter-input-device-tool-evdev.h" -#include "clutter-main.h" - -/* Try to keep the pointer inside the stage. Hopefully no one is using - * this backend with stages smaller than this. */ -#define INITIAL_POINTER_X 16 -#define INITIAL_POINTER_Y 16 - -#define AUTOREPEAT_VALUE 2 - -#define DISCRETE_SCROLL_STEP 10.0 - -#ifndef BTN_STYLUS3 -#define BTN_STYLUS3 0x149 /* Linux 4.15 */ -#endif - -void -clutter_seat_evdev_set_libinput_seat (ClutterSeatEvdev *seat, - struct libinput_seat *libinput_seat) -{ - g_assert (seat->libinput_seat == NULL); - - libinput_seat_ref (libinput_seat); - libinput_seat_set_user_data (libinput_seat, seat); - seat->libinput_seat = libinput_seat; -} - -void -clutter_seat_evdev_sync_leds (ClutterSeatEvdev *seat) -{ - GSList *iter; - ClutterInputDeviceEvdev *device_evdev; - int caps_lock, num_lock, scroll_lock; - enum libinput_led leds = 0; - - caps_lock = xkb_state_led_index_is_active (seat->xkb, seat->caps_lock_led); - num_lock = xkb_state_led_index_is_active (seat->xkb, seat->num_lock_led); - scroll_lock = xkb_state_led_index_is_active (seat->xkb, seat->scroll_lock_led); - - if (caps_lock) - leds |= LIBINPUT_LED_CAPS_LOCK; - if (num_lock) - leds |= LIBINPUT_LED_NUM_LOCK; - if (scroll_lock) - leds |= LIBINPUT_LED_SCROLL_LOCK; - - for (iter = seat->devices; iter; iter = iter->next) - { - device_evdev = iter->data; - _clutter_input_device_evdev_update_leds (device_evdev, leds); - } -} - -static void -clutter_touch_state_free (ClutterTouchState *touch_state) -{ - g_slice_free (ClutterTouchState, touch_state); -} - -static void -ensure_seat_slot_allocated (ClutterSeatEvdev *seat, - int seat_slot) -{ - if (seat_slot >= seat->n_alloc_touch_states) - { - const int size_increase = 5; - int i; - - seat->n_alloc_touch_states += size_increase; - seat->touch_states = realloc (seat->touch_states, - seat->n_alloc_touch_states * sizeof (ClutterTouchState *)); - for (i = 0; i < size_increase; i++) - seat->touch_states[seat->n_alloc_touch_states - (i + 1)] = NULL; - } -} - -ClutterTouchState * -clutter_seat_evdev_acquire_touch_state (ClutterSeatEvdev *seat, - int device_slot) -{ - ClutterTouchState *touch_state; - int seat_slot; - - for (seat_slot = 0; seat_slot < seat->n_alloc_touch_states; seat_slot++) - { - if (!seat->touch_states[seat_slot]) - break; - } - - ensure_seat_slot_allocated (seat, seat_slot); - - touch_state = g_slice_new0 (ClutterTouchState); - *touch_state = (ClutterTouchState) { - .seat = seat, - .seat_slot = seat_slot, - .device_slot = device_slot, - }; - - seat->touch_states[seat_slot] = touch_state; - - return touch_state; -} - -void -clutter_seat_evdev_release_touch_state (ClutterSeatEvdev *seat, - ClutterTouchState *touch_state) -{ - g_clear_pointer (&seat->touch_states[touch_state->seat_slot], - (GDestroyNotify) clutter_touch_state_free); -} - -ClutterSeatEvdev * -clutter_seat_evdev_new (ClutterDeviceManagerEvdev *manager_evdev) -{ - ClutterDeviceManager *manager = CLUTTER_DEVICE_MANAGER (manager_evdev); - ClutterSeatEvdev *seat; - ClutterInputDevice *device; - ClutterStage *stage; - struct xkb_keymap *keymap; - - seat = g_new0 (ClutterSeatEvdev, 1); - if (!seat) - return NULL; - - seat->manager_evdev = manager_evdev; - device = _clutter_input_device_evdev_new_virtual ( - manager, seat, CLUTTER_POINTER_DEVICE, - CLUTTER_INPUT_MODE_MASTER); - stage = _clutter_device_manager_evdev_get_stage (manager_evdev); - _clutter_input_device_set_stage (device, stage); - seat->pointer_x = INITIAL_POINTER_X; - seat->pointer_y = INITIAL_POINTER_Y; - _clutter_input_device_set_coords (device, NULL, - seat->pointer_x, seat->pointer_y, - NULL); - _clutter_device_manager_add_device (manager, device); - seat->core_pointer = device; - - device = _clutter_input_device_evdev_new_virtual ( - manager, seat, CLUTTER_KEYBOARD_DEVICE, - CLUTTER_INPUT_MODE_MASTER); - _clutter_input_device_set_stage (device, stage); - _clutter_device_manager_add_device (manager, device); - seat->core_keyboard = device; - - seat->repeat = TRUE; - seat->repeat_delay = 250; /* ms */ - seat->repeat_interval = 33; /* ms */ - - keymap = _clutter_device_manager_evdev_get_keymap (manager_evdev); - if (keymap) - { - seat->xkb = xkb_state_new (keymap); - - seat->caps_lock_led = - xkb_keymap_led_get_index (keymap, XKB_LED_NAME_CAPS); - seat->num_lock_led = - xkb_keymap_led_get_index (keymap, XKB_LED_NAME_NUM); - seat->scroll_lock_led = - xkb_keymap_led_get_index (keymap, XKB_LED_NAME_SCROLL); - } - - return seat; -} - -void -clutter_seat_evdev_clear_repeat_timer (ClutterSeatEvdev *seat) -{ - if (seat->repeat_timer) - { - g_source_remove (seat->repeat_timer); - seat->repeat_timer = 0; - g_clear_object (&seat->repeat_device); - } -} - -static gboolean -keyboard_repeat (gpointer data) -{ - ClutterSeatEvdev *seat = data; - GSource *source; - - /* There might be events queued in libinput that could cancel the - repeat timer. */ - _clutter_device_manager_evdev_dispatch (seat->manager_evdev); - if (!seat->repeat_timer) - return G_SOURCE_REMOVE; - - g_return_val_if_fail (seat->repeat_device != NULL, G_SOURCE_REMOVE); - source = g_main_context_find_source_by_id (NULL, seat->repeat_timer); - - clutter_seat_evdev_notify_key (seat, - seat->repeat_device, - g_source_get_time (source), - seat->repeat_key, - AUTOREPEAT_VALUE, - FALSE); - - return G_SOURCE_CONTINUE; -} - -static void -queue_event (ClutterEvent *event) -{ - _clutter_event_push (event, FALSE); -} - -static int -update_button_count (ClutterSeatEvdev *seat, - uint32_t button, - uint32_t state) -{ - if (state) - { - return ++seat->button_count[button]; - } - else - { - /* Handle cases where we newer saw the initial pressed event. */ - if (seat->button_count[button] == 0) - return 0; - - return --seat->button_count[button]; - } -} - -void -clutter_seat_evdev_notify_key (ClutterSeatEvdev *seat, - ClutterInputDevice *device, - uint64_t time_us, - uint32_t key, - uint32_t state, - gboolean update_keys) -{ - ClutterStage *stage; - ClutterEvent *event = NULL; - enum xkb_state_component changed_state; - - if (state != AUTOREPEAT_VALUE) - { - /* Drop any repeated button press (for example from virtual devices. */ - int count = update_button_count (seat, key, state); - if (state && count > 1) - return; - if (!state && count != 0) - return; - } - - /* We can drop the event on the floor if no stage has been - * associated with the device yet. */ - stage = _clutter_input_device_get_stage (device); - if (stage == NULL) - { - clutter_seat_evdev_clear_repeat_timer (seat); - return; - } - - event = _clutter_key_event_new_from_evdev (device, - seat->core_keyboard, - stage, - seat->xkb, - seat->button_state, - us2ms (time_us), key, state); - _clutter_evdev_event_set_event_code (event, key); - - /* We must be careful and not pass multiple releases to xkb, otherwise it gets - confused and locks the modifiers */ - if (state != AUTOREPEAT_VALUE) - { - changed_state = xkb_state_update_key (seat->xkb, - event->key.hardware_keycode, - state ? XKB_KEY_DOWN : XKB_KEY_UP); - } - else - { - changed_state = 0; - clutter_event_set_flags (event, CLUTTER_EVENT_FLAG_SYNTHETIC); - } - - queue_event (event); - - if (update_keys && (changed_state & XKB_STATE_LEDS)) - clutter_seat_evdev_sync_leds (seat); - - if (state == 0 || /* key release */ - !seat->repeat || - !xkb_keymap_key_repeats (xkb_state_get_keymap (seat->xkb), - event->key.hardware_keycode)) - { - clutter_seat_evdev_clear_repeat_timer (seat); - return; - } - - if (state == 1) /* key press */ - seat->repeat_count = 0; - - seat->repeat_count += 1; - seat->repeat_key = key; - - switch (seat->repeat_count) - { - case 1: - case 2: - { - guint32 interval; - - clutter_seat_evdev_clear_repeat_timer (seat); - seat->repeat_device = g_object_ref (device); - - if (seat->repeat_count == 1) - interval = seat->repeat_delay; - else - interval = seat->repeat_interval; - - seat->repeat_timer = - clutter_threads_add_timeout_full (CLUTTER_PRIORITY_EVENTS, - interval, - keyboard_repeat, - seat, - NULL); - return; - } - default: - return; - } -} - -static ClutterEvent * -new_absolute_motion_event (ClutterSeatEvdev *seat, - ClutterInputDevice *input_device, - guint64 time_us, - gfloat x, - gfloat y, - gdouble *axes) -{ - ClutterStage *stage = _clutter_input_device_get_stage (input_device); - ClutterEvent *event; - - event = clutter_event_new (CLUTTER_MOTION); - - if (clutter_input_device_get_device_type (input_device) != CLUTTER_TABLET_DEVICE) - _clutter_device_manager_evdev_constrain_pointer (seat->manager_evdev, - seat->core_pointer, - time_us, - seat->pointer_x, - seat->pointer_y, - &x, &y); - - _clutter_evdev_event_set_time_usec (event, time_us); - event->motion.time = us2ms (time_us); - event->motion.stage = stage; - event->motion.device = seat->core_pointer; - _clutter_xkb_translate_state (event, seat->xkb, seat->button_state); - event->motion.x = x; - event->motion.y = y; - event->motion.axes = axes; - clutter_event_set_device (event, seat->core_pointer); - clutter_event_set_source_device (event, input_device); - - if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE) - { - ClutterInputDeviceEvdev *device_evdev = - CLUTTER_INPUT_DEVICE_EVDEV (input_device); - - clutter_event_set_device_tool (event, device_evdev->last_tool); - clutter_event_set_device (event, input_device); - } - else - { - clutter_event_set_device (event, seat->core_pointer); - } - - _clutter_input_device_set_stage (seat->core_pointer, stage); - - if (clutter_input_device_get_device_type (input_device) != CLUTTER_TABLET_DEVICE) - { - seat->pointer_x = x; - seat->pointer_y = y; - } - - return event; -} - -void -clutter_seat_evdev_notify_relative_motion (ClutterSeatEvdev *seat, - ClutterInputDevice *input_device, - uint64_t time_us, - float dx, - float dy, - float dx_unaccel, - float dy_unaccel) -{ - gfloat new_x, new_y; - ClutterEvent *event; - - /* We can drop the event on the floor if no stage has been - * associated with the device yet. */ - if (!_clutter_input_device_get_stage (input_device)) - return; - - _clutter_device_manager_evdev_filter_relative_motion (seat->manager_evdev, - input_device, - seat->pointer_x, - seat->pointer_y, - &dx, - &dy); - - new_x = seat->pointer_x + dx; - new_y = seat->pointer_y + dy; - event = new_absolute_motion_event (seat, input_device, - time_us, new_x, new_y, NULL); - - _clutter_evdev_event_set_relative_motion (event, - dx, dy, - dx_unaccel, dy_unaccel); - - queue_event (event); -} - -void clutter_seat_evdev_notify_absolute_motion (ClutterSeatEvdev *seat, - ClutterInputDevice *input_device, - uint64_t time_us, - float x, - float y, - double *axes) -{ - ClutterEvent *event; - - event = new_absolute_motion_event (seat, input_device, time_us, x, y, axes); - - queue_event (event); -} - -void -clutter_seat_evdev_notify_button (ClutterSeatEvdev *seat, - ClutterInputDevice *input_device, - uint64_t time_us, - uint32_t button, - uint32_t state) -{ - ClutterInputDeviceEvdev *device_evdev = (ClutterInputDeviceEvdev *) input_device; - ClutterStage *stage; - ClutterEvent *event = NULL; - gint button_nr; - static gint maskmap[8] = - { - CLUTTER_BUTTON1_MASK, CLUTTER_BUTTON3_MASK, CLUTTER_BUTTON2_MASK, - CLUTTER_BUTTON4_MASK, CLUTTER_BUTTON5_MASK, 0, 0, 0 - }; - int button_count; - - /* Drop any repeated button press (for example from virtual devices. */ - button_count = update_button_count (seat, button, state); - if (state && button_count > 1) - return; - if (!state && button_count != 0) - return; - - /* We can drop the event on the floor if no stage has been - * associated with the device yet. */ - stage = _clutter_input_device_get_stage (input_device); - if (stage == NULL) - return; - - /* The evdev button numbers don't map sequentially to clutter button - * numbers (the right and middle mouse buttons are in the opposite - * order) so we'll map them directly with a switch statement */ - switch (button) - { - case BTN_LEFT: - case BTN_TOUCH: - button_nr = CLUTTER_BUTTON_PRIMARY; - break; - - case BTN_RIGHT: - case BTN_STYLUS: - button_nr = CLUTTER_BUTTON_SECONDARY; - break; - - case BTN_MIDDLE: - case BTN_STYLUS2: - button_nr = CLUTTER_BUTTON_MIDDLE; - break; - - case 0x149: /* BTN_STYLUS3 */ - button_nr = 8; - break; - - default: - /* For compatibility reasons, all additional buttons go after the old 4-7 scroll ones */ - if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE) - button_nr = button - BTN_TOOL_PEN + 4; - else - button_nr = button - (BTN_LEFT - 1) + 4; - break; - } - - if (button_nr < 1 || button_nr > 12) - { - g_warning ("Unhandled button event 0x%x", button); - return; - } - - if (state) - event = clutter_event_new (CLUTTER_BUTTON_PRESS); - else - event = clutter_event_new (CLUTTER_BUTTON_RELEASE); - - if (button_nr < G_N_ELEMENTS (maskmap)) - { - /* Update the modifiers */ - if (state) - seat->button_state |= maskmap[button_nr - 1]; - else - seat->button_state &= ~maskmap[button_nr - 1]; - } - - _clutter_evdev_event_set_time_usec (event, time_us); - event->button.time = us2ms (time_us); - event->button.stage = CLUTTER_STAGE (stage); - _clutter_xkb_translate_state (event, seat->xkb, seat->button_state); - event->button.button = button_nr; - - if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE) - { - ClutterPoint point; - - clutter_input_device_get_coords (input_device, NULL, &point); - event->button.x = point.x; - event->button.y = point.y; - } - else - { - event->button.x = seat->pointer_x; - event->button.y = seat->pointer_y; - } - - clutter_event_set_device (event, seat->core_pointer); - clutter_event_set_source_device (event, input_device); - - if (device_evdev->last_tool) - { - /* Apply the button event code as per the tool mapping */ - guint mapped_button; - - mapped_button = clutter_input_device_tool_evdev_get_button_code (device_evdev->last_tool, - button_nr); - if (mapped_button != 0) - button = mapped_button; - } - - _clutter_evdev_event_set_event_code (event, button); - - if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE) - { - clutter_event_set_device_tool (event, device_evdev->last_tool); - clutter_event_set_device (event, input_device); - } - else - { - clutter_event_set_device (event, seat->core_pointer); - } - - _clutter_input_device_set_stage (seat->core_pointer, stage); - - queue_event (event); -} - -static void -notify_scroll (ClutterInputDevice *input_device, - guint64 time_us, - gdouble dx, - gdouble dy, - ClutterScrollSource scroll_source, - ClutterScrollFinishFlags flags, - gboolean emulated) -{ - ClutterInputDeviceEvdev *device_evdev; - ClutterSeatEvdev *seat; - ClutterStage *stage; - ClutterEvent *event = NULL; - gdouble scroll_factor; - - /* We can drop the event on the floor if no stage has been - * associated with the device yet. */ - stage = _clutter_input_device_get_stage (input_device); - if (stage == NULL) - return; - - device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (input_device); - seat = _clutter_input_device_evdev_get_seat (device_evdev); - - event = clutter_event_new (CLUTTER_SCROLL); - - _clutter_evdev_event_set_time_usec (event, time_us); - event->scroll.time = us2ms (time_us); - event->scroll.stage = CLUTTER_STAGE (stage); - event->scroll.device = seat->core_pointer; - _clutter_xkb_translate_state (event, seat->xkb, seat->button_state); - - /* libinput pointer axis events are in pointer motion coordinate space. - * To convert to Xi2 discrete step coordinate space, multiply the factor - * 1/10. */ - event->scroll.direction = CLUTTER_SCROLL_SMOOTH; - scroll_factor = 1.0 / DISCRETE_SCROLL_STEP; - clutter_event_set_scroll_delta (event, - scroll_factor * dx, - scroll_factor * dy); - - event->scroll.x = seat->pointer_x; - event->scroll.y = seat->pointer_y; - clutter_event_set_device (event, seat->core_pointer); - clutter_event_set_source_device (event, input_device); - event->scroll.scroll_source = scroll_source; - event->scroll.finish_flags = flags; - - _clutter_event_set_pointer_emulated (event, emulated); - - queue_event (event); -} - -static void -notify_discrete_scroll (ClutterInputDevice *input_device, - uint64_t time_us, - ClutterScrollDirection direction, - ClutterScrollSource scroll_source, - gboolean emulated) -{ - ClutterInputDeviceEvdev *device_evdev; - ClutterSeatEvdev *seat; - ClutterStage *stage; - ClutterEvent *event = NULL; - - if (direction == CLUTTER_SCROLL_SMOOTH) - return; - - /* We can drop the event on the floor if no stage has been - * associated with the device yet. */ - stage = _clutter_input_device_get_stage (input_device); - if (stage == NULL) - return; - - device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (input_device); - seat = _clutter_input_device_evdev_get_seat (device_evdev); - - event = clutter_event_new (CLUTTER_SCROLL); - - _clutter_evdev_event_set_time_usec (event, time_us); - event->scroll.time = us2ms (time_us); - event->scroll.stage = CLUTTER_STAGE (stage); - event->scroll.device = seat->core_pointer; - _clutter_xkb_translate_state (event, seat->xkb, seat->button_state); - - event->scroll.direction = direction; - - event->scroll.x = seat->pointer_x; - event->scroll.y = seat->pointer_y; - clutter_event_set_device (event, seat->core_pointer); - clutter_event_set_source_device (event, input_device); - event->scroll.scroll_source = scroll_source; - - _clutter_event_set_pointer_emulated (event, emulated); - - queue_event (event); -} - -static void -check_notify_discrete_scroll (ClutterSeatEvdev *seat, - ClutterInputDevice *device, - uint64_t time_us, - ClutterScrollSource scroll_source) -{ - int i, n_xscrolls, n_yscrolls; - - n_xscrolls = floor (fabs (seat->accum_scroll_dx) / DISCRETE_SCROLL_STEP); - n_yscrolls = floor (fabs (seat->accum_scroll_dy) / DISCRETE_SCROLL_STEP); - - for (i = 0; i < n_xscrolls; i++) - { - notify_discrete_scroll (device, time_us, - seat->accum_scroll_dx > 0 ? - CLUTTER_SCROLL_RIGHT : CLUTTER_SCROLL_LEFT, - scroll_source, TRUE); - } - - for (i = 0; i < n_yscrolls; i++) - { - notify_discrete_scroll (device, time_us, - seat->accum_scroll_dy > 0 ? - CLUTTER_SCROLL_DOWN : CLUTTER_SCROLL_UP, - scroll_source, TRUE); - } - - seat->accum_scroll_dx = fmodf (seat->accum_scroll_dx, DISCRETE_SCROLL_STEP); - seat->accum_scroll_dy = fmodf (seat->accum_scroll_dy, DISCRETE_SCROLL_STEP); -} - -void -clutter_seat_evdev_notify_scroll_continuous (ClutterSeatEvdev *seat, - ClutterInputDevice *input_device, - uint64_t time_us, - double dx, - double dy, - ClutterScrollSource scroll_source, - ClutterScrollFinishFlags finish_flags) -{ - if (finish_flags & CLUTTER_SCROLL_FINISHED_HORIZONTAL) - seat->accum_scroll_dx = 0; - else - seat->accum_scroll_dx += dx; - - if (finish_flags & CLUTTER_SCROLL_FINISHED_VERTICAL) - seat->accum_scroll_dy = 0; - else - seat->accum_scroll_dy += dy; - - notify_scroll (input_device, time_us, dx, dy, scroll_source, - finish_flags, FALSE); - check_notify_discrete_scroll (seat, input_device, time_us, scroll_source); -} - -static ClutterScrollDirection -discrete_to_direction (double discrete_dx, - double discrete_dy) -{ - if (discrete_dx > 0) - return CLUTTER_SCROLL_RIGHT; - else if (discrete_dx < 0) - return CLUTTER_SCROLL_LEFT; - else if (discrete_dy > 0) - return CLUTTER_SCROLL_DOWN; - else if (discrete_dy < 0) - return CLUTTER_SCROLL_UP; - else - g_assert_not_reached (); -} - -void -clutter_seat_evdev_notify_discrete_scroll (ClutterSeatEvdev *seat, - ClutterInputDevice *input_device, - uint64_t time_us, - double discrete_dx, - double discrete_dy, - ClutterScrollSource scroll_source) -{ - notify_scroll (input_device, time_us, - discrete_dx * DISCRETE_SCROLL_STEP, - discrete_dy * DISCRETE_SCROLL_STEP, - scroll_source, CLUTTER_SCROLL_FINISHED_NONE, - TRUE); - notify_discrete_scroll (input_device, time_us, - discrete_to_direction (discrete_dx, discrete_dy), - scroll_source, FALSE); - -} - -void -clutter_seat_evdev_notify_touch_event (ClutterSeatEvdev *seat, - ClutterInputDevice *input_device, - ClutterEventType evtype, - uint64_t time_us, - int slot, - double x, - double y) -{ - ClutterStage *stage; - ClutterEvent *event = NULL; - - /* We can drop the event on the floor if no stage has been - * associated with the device yet. */ - stage = _clutter_input_device_get_stage (input_device); - if (stage == NULL) - return; - - event = clutter_event_new (evtype); - - _clutter_evdev_event_set_time_usec (event, time_us); - event->touch.time = us2ms (time_us); - event->touch.stage = CLUTTER_STAGE (stage); - event->touch.device = seat->core_pointer; - event->touch.x = x; - event->touch.y = y; - clutter_input_device_evdev_translate_coordinates (input_device, stage, - &event->touch.x, - &event->touch.y); - - /* "NULL" sequences are special cased in clutter */ - event->touch.sequence = GINT_TO_POINTER (MAX (1, slot + 1)); - _clutter_xkb_translate_state (event, seat->xkb, seat->button_state); - - if (evtype == CLUTTER_TOUCH_BEGIN || - evtype == CLUTTER_TOUCH_UPDATE) - event->touch.modifier_state |= CLUTTER_BUTTON1_MASK; - - clutter_event_set_device (event, seat->core_pointer); - clutter_event_set_source_device (event, input_device); - - queue_event (event); -} - -void -clutter_seat_evdev_free (ClutterSeatEvdev *seat) -{ - GSList *iter; - - for (iter = seat->devices; iter; iter = g_slist_next (iter)) - { - ClutterInputDevice *device = iter->data; - - g_object_unref (device); - } - g_slist_free (seat->devices); - free (seat->touch_states); - - xkb_state_unref (seat->xkb); - - clutter_seat_evdev_clear_repeat_timer (seat); - - if (seat->libinput_seat) - libinput_seat_unref (seat->libinput_seat); - - free (seat); -} - -ClutterInputDevice * -clutter_seat_evdev_get_device (ClutterSeatEvdev *seat, - gint id) -{ - ClutterInputDevice *device; - GSList *l; - - for (l = seat->devices; l; l = l->next) - { - device = l->data; - - if (clutter_input_device_get_device_id (device) == id) - return device; - } - - return NULL; -} - -void -clutter_seat_evdev_set_stage (ClutterSeatEvdev *seat, - ClutterStage *stage) -{ - GSList *l; - - _clutter_input_device_set_stage (seat->core_pointer, stage); - _clutter_input_device_set_stage (seat->core_keyboard, stage); - - for (l = seat->devices; l; l = l->next) - { - ClutterInputDevice *device = l->data; - - _clutter_input_device_set_stage (device, stage); - } -} diff --git a/clutter/clutter/evdev/clutter-seat-evdev.h b/clutter/clutter/evdev/clutter-seat-evdev.h deleted file mode 100644 index 4bb319b3a..000000000 --- a/clutter/clutter/evdev/clutter-seat-evdev.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corp. - * Copyright (C) 2014 Jonas Ådahl - * Copyright (C) 2016 Red Hat Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Damien Lespiau - * Author: Jonas Ådahl - */ - -#ifndef __CLUTTER_SEAT_EVDEV_H__ -#define __CLUTTER_SEAT_EVDEV_H__ - -#include -#include - -#include "clutter-input-device.h" -#include "clutter-device-manager-evdev.h" -#include "clutter-xkb-utils.h" - -typedef struct _ClutterTouchState ClutterTouchState; - -struct _ClutterTouchState -{ - ClutterSeatEvdev *seat; - - int device_slot; - int seat_slot; - ClutterPoint coords; -}; - -struct _ClutterSeatEvdev -{ - struct libinput_seat *libinput_seat; - ClutterDeviceManagerEvdev *manager_evdev; - - GSList *devices; - - ClutterInputDevice *core_pointer; - ClutterInputDevice *core_keyboard; - - ClutterTouchState **touch_states; - int n_alloc_touch_states; - - struct xkb_state *xkb; - xkb_led_index_t caps_lock_led; - xkb_led_index_t num_lock_led; - xkb_led_index_t scroll_lock_led; - xkb_layout_index_t layout_idx; - uint32_t button_state; - int button_count[KEY_CNT]; - - /* keyboard repeat */ - gboolean repeat; - guint32 repeat_delay; - guint32 repeat_interval; - guint32 repeat_key; - guint32 repeat_count; - guint32 repeat_timer; - ClutterInputDevice *repeat_device; - - gfloat pointer_x; - gfloat pointer_y; - - /* Emulation of discrete scroll events out of smooth ones */ - gfloat accum_scroll_dx; - gfloat accum_scroll_dy; -}; - -void clutter_seat_evdev_notify_key (ClutterSeatEvdev *seat, - ClutterInputDevice *device, - uint64_t time_us, - uint32_t key, - uint32_t state, - gboolean update_keys); - -void clutter_seat_evdev_notify_relative_motion (ClutterSeatEvdev *seat_evdev, - ClutterInputDevice *input_device, - uint64_t time_us, - float dx, - float dy, - float dx_unaccel, - float dy_unaccel); - -void clutter_seat_evdev_notify_absolute_motion (ClutterSeatEvdev *seat_evdev, - ClutterInputDevice *input_device, - uint64_t time_us, - float x, - float y, - double *axes); - -void clutter_seat_evdev_notify_button (ClutterSeatEvdev *seat, - ClutterInputDevice *input_device, - uint64_t time_us, - uint32_t button, - uint32_t state); - -void clutter_seat_evdev_notify_scroll_continuous (ClutterSeatEvdev *seat, - ClutterInputDevice *input_device, - uint64_t time_us, - double dx, - double dy, - ClutterScrollSource source, - ClutterScrollFinishFlags flags); - -void clutter_seat_evdev_notify_discrete_scroll (ClutterSeatEvdev *seat, - ClutterInputDevice *input_device, - uint64_t time_us, - double discrete_dx, - double discrete_dy, - ClutterScrollSource source); - -void clutter_seat_evdev_notify_touch_event (ClutterSeatEvdev *seat, - ClutterInputDevice *input_device, - ClutterEventType evtype, - uint64_t time_us, - int slot, - double x, - double y); - -void clutter_seat_evdev_set_libinput_seat (ClutterSeatEvdev *seat, - struct libinput_seat *libinput_seat); - -void clutter_seat_evdev_sync_leds (ClutterSeatEvdev *seat); - -ClutterInputDevice * clutter_seat_evdev_get_device (ClutterSeatEvdev *seat, - gint id); - -ClutterTouchState * clutter_seat_evdev_acquire_touch_state (ClutterSeatEvdev *seat, - int device_slot); - -void clutter_seat_evdev_release_touch_state (ClutterSeatEvdev *seat, - ClutterTouchState *touch_state); - -ClutterTouchState * clutter_seat_evdev_get_touch (ClutterSeatEvdev *seat, - guint32 id); - -void clutter_seat_evdev_set_stage (ClutterSeatEvdev *seat, - ClutterStage *stage); - -void clutter_seat_evdev_clear_repeat_timer (ClutterSeatEvdev *seat); - -ClutterSeatEvdev * clutter_seat_evdev_new (ClutterDeviceManagerEvdev *manager_evdev); - -void clutter_seat_evdev_free (ClutterSeatEvdev *seat); - -#endif /* __CLUTTER_SEAT_EVDEV_H__ */ diff --git a/clutter/clutter/evdev/clutter-virtual-input-device-evdev.c b/clutter/clutter/evdev/clutter-virtual-input-device-evdev.c deleted file mode 100644 index fe628da85..000000000 --- a/clutter/clutter/evdev/clutter-virtual-input-device-evdev.c +++ /dev/null @@ -1,684 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2016 Red Hat Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Jonas Ådahl - */ - -#ifdef HAVE_CONFIG_H -#include "clutter-build-config.h" -#endif - -#include -#include - -#include "clutter-private.h" -#include "clutter-virtual-input-device.h" -#include "evdev/clutter-input-device-evdev.h" -#include "evdev/clutter-seat-evdev.h" -#include "evdev/clutter-virtual-input-device-evdev.h" - -enum -{ - PROP_0, - - PROP_SEAT, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST]; - -struct _ClutterVirtualInputDeviceEvdev -{ - ClutterVirtualInputDevice parent; - - ClutterInputDevice *device; - ClutterSeatEvdev *seat; - int button_count[KEY_CNT]; -}; - -G_DEFINE_TYPE (ClutterVirtualInputDeviceEvdev, - clutter_virtual_input_device_evdev, - CLUTTER_TYPE_VIRTUAL_INPUT_DEVICE) - -typedef enum _EvdevButtonType -{ - EVDEV_BUTTON_TYPE_NONE, - EVDEV_BUTTON_TYPE_KEY, - EVDEV_BUTTON_TYPE_BUTTON, -} EvdevButtonType; - -static int -update_button_count (ClutterVirtualInputDeviceEvdev *virtual_evdev, - uint32_t button, - uint32_t state) -{ - if (state) - return ++virtual_evdev->button_count[button]; - else - return --virtual_evdev->button_count[button]; -} - -static EvdevButtonType -get_button_type (uint16_t code) -{ - switch (code) - { - case BTN_TOOL_PEN: - case BTN_TOOL_RUBBER: - case BTN_TOOL_BRUSH: - case BTN_TOOL_PENCIL: - case BTN_TOOL_AIRBRUSH: - case BTN_TOOL_MOUSE: - case BTN_TOOL_LENS: - case BTN_TOOL_QUINTTAP: - case BTN_TOOL_DOUBLETAP: - case BTN_TOOL_TRIPLETAP: - case BTN_TOOL_QUADTAP: - case BTN_TOOL_FINGER: - case BTN_TOUCH: - return EVDEV_BUTTON_TYPE_NONE; - } - - if (code >= KEY_ESC && code <= KEY_MICMUTE) - return EVDEV_BUTTON_TYPE_KEY; - if (code >= BTN_MISC && code <= BTN_GEAR_UP) - return EVDEV_BUTTON_TYPE_BUTTON; - if (code >= KEY_OK && code <= KEY_LIGHTS_TOGGLE) - return EVDEV_BUTTON_TYPE_KEY; - if (code >= BTN_DPAD_UP && code <= BTN_DPAD_RIGHT) - return EVDEV_BUTTON_TYPE_BUTTON; - if (code >= KEY_ALS_TOGGLE && code <= KEY_KBDINPUTASSIST_CANCEL) - return EVDEV_BUTTON_TYPE_KEY; - if (code >= BTN_TRIGGER_HAPPY && code <= BTN_TRIGGER_HAPPY40) - return EVDEV_BUTTON_TYPE_BUTTON; - return EVDEV_BUTTON_TYPE_NONE; -} - -static void -release_pressed_buttons (ClutterVirtualInputDevice *virtual_device) -{ - ClutterVirtualInputDeviceEvdev *virtual_evdev = - CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device); - int code; - uint64_t time_us; - - time_us = g_get_monotonic_time (); - - for (code = 0; code < G_N_ELEMENTS (virtual_evdev->button_count); code++) - { - if (virtual_evdev->button_count[code] == 0) - continue; - - switch (get_button_type (code)) - { - case EVDEV_BUTTON_TYPE_KEY: - clutter_virtual_input_device_notify_key (virtual_device, - time_us, - code, - CLUTTER_KEY_STATE_RELEASED); - break; - case EVDEV_BUTTON_TYPE_BUTTON: - clutter_virtual_input_device_notify_button (virtual_device, - time_us, - code, - CLUTTER_BUTTON_STATE_RELEASED); - break; - case EVDEV_BUTTON_TYPE_NONE: - g_assert_not_reached (); - } - } -} - -static void -clutter_virtual_input_device_evdev_notify_relative_motion (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - double dx, - double dy) -{ - ClutterVirtualInputDeviceEvdev *virtual_evdev = - CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device); - - if (time_us == CLUTTER_CURRENT_TIME) - time_us = g_get_monotonic_time (); - - clutter_seat_evdev_notify_relative_motion (virtual_evdev->seat, - virtual_evdev->device, - time_us, - dx, dy, - dx, dy); -} - -static void -clutter_virtual_input_device_evdev_notify_absolute_motion (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - double x, - double y) -{ - ClutterVirtualInputDeviceEvdev *virtual_evdev = - CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device); - - if (time_us == CLUTTER_CURRENT_TIME) - time_us = g_get_monotonic_time (); - - clutter_seat_evdev_notify_absolute_motion (virtual_evdev->seat, - virtual_evdev->device, - time_us, - x, y, - NULL); -} - -static void -clutter_virtual_input_device_evdev_notify_button (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - uint32_t button, - ClutterButtonState button_state) -{ - ClutterVirtualInputDeviceEvdev *virtual_evdev = - CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device); - int button_count; - - if (time_us == CLUTTER_CURRENT_TIME) - time_us = g_get_monotonic_time (); - - if (get_button_type (button) != EVDEV_BUTTON_TYPE_BUTTON) - { - g_warning ("Unknown/invalid virtual device button 0x%x pressed", - button); - return; - } - - button_count = update_button_count (virtual_evdev, button, button_state); - if (button_count < 0 || button_count > 1) - { - g_warning ("Received multiple virtual 0x%x button %s (ignoring)", button, - button_state == CLUTTER_BUTTON_STATE_PRESSED ? "presses" : "releases"); - update_button_count (virtual_evdev, button, 1 - button_state); - return; - } - - clutter_seat_evdev_notify_button (virtual_evdev->seat, - virtual_evdev->device, - time_us, - button, - button_state); -} - -static void -clutter_virtual_input_device_evdev_notify_key (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - uint32_t key, - ClutterKeyState key_state) -{ - ClutterVirtualInputDeviceEvdev *virtual_evdev = - CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device); - int key_count; - - if (time_us == CLUTTER_CURRENT_TIME) - time_us = g_get_monotonic_time (); - - if (get_button_type (key) != EVDEV_BUTTON_TYPE_KEY) - { - g_warning ("Unknown/invalid virtual device key 0x%x pressed\n", key); - return; - } - - key_count = update_button_count (virtual_evdev, key, key_state); - if (key_count < 0 || key_count > 1) - { - g_warning ("Received multiple virtual 0x%x key %s (ignoring)", key, - key_state == CLUTTER_KEY_STATE_PRESSED ? "presses" : "releases"); - update_button_count (virtual_evdev, key, 1 - key_state); - return; - } - - clutter_seat_evdev_notify_key (virtual_evdev->seat, - virtual_evdev->device, - time_us, - key, - key_state, - TRUE); -} - -static gboolean -pick_keycode_for_keyval_in_current_group (ClutterVirtualInputDevice *virtual_device, - guint keyval, - guint *keycode_out, - guint *level_out) -{ - ClutterVirtualInputDeviceEvdev *virtual_evdev = - CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device); - ClutterDeviceManager *manager; - struct xkb_keymap *xkb_keymap; - struct xkb_state *state; - guint keycode, layout; - xkb_keycode_t min_keycode, max_keycode; - - manager = clutter_virtual_input_device_get_manager (virtual_device); - xkb_keymap = _clutter_device_manager_evdev_get_keymap (CLUTTER_DEVICE_MANAGER_EVDEV (manager)); - state = virtual_evdev->seat->xkb; - - layout = xkb_state_serialize_layout (state, XKB_STATE_LAYOUT_EFFECTIVE); - min_keycode = xkb_keymap_min_keycode (xkb_keymap); - max_keycode = xkb_keymap_max_keycode (xkb_keymap); - for (keycode = min_keycode; keycode < max_keycode; keycode++) - { - gint num_levels, level; - num_levels = xkb_keymap_num_levels_for_key (xkb_keymap, keycode, layout); - for (level = 0; level < num_levels; level++) - { - const xkb_keysym_t *syms; - gint num_syms, sym; - num_syms = xkb_keymap_key_get_syms_by_level (xkb_keymap, keycode, layout, level, &syms); - for (sym = 0; sym < num_syms; sym++) - { - if (syms[sym] == keyval) - { - *keycode_out = keycode; - if (level_out) - *level_out = level; - return TRUE; - } - } - } - } - - return FALSE; -} - -static void -apply_level_modifiers (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - uint32_t level, - uint32_t key_state) -{ - ClutterVirtualInputDeviceEvdev *virtual_evdev = - CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device); - guint keysym, keycode, evcode; - - if (level == 0) - return; - - if (level == 1) - { - keysym = XKB_KEY_Shift_L; - } - else if (level == 2) - { - keysym = XKB_KEY_ISO_Level3_Shift; - } - else - { - g_warning ("Unhandled level: %d\n", level); - return; - } - - if (!pick_keycode_for_keyval_in_current_group (virtual_device, keysym, - &keycode, NULL)) - return; - - clutter_input_device_keycode_to_evdev (virtual_evdev->device, - keycode, &evcode); - clutter_seat_evdev_notify_key (virtual_evdev->seat, - virtual_evdev->device, - time_us, - evcode, - key_state, - TRUE); -} - -static void -clutter_virtual_input_device_evdev_notify_keyval (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - uint32_t keyval, - ClutterKeyState key_state) -{ - ClutterVirtualInputDeviceEvdev *virtual_evdev = - CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device); - int key_count; - guint keycode = 0, level = 0, evcode = 0; - - if (time_us == CLUTTER_CURRENT_TIME) - time_us = g_get_monotonic_time (); - - if (!pick_keycode_for_keyval_in_current_group (virtual_device, - keyval, &keycode, &level)) - { - g_warning ("No keycode found for keyval %x in current group", keyval); - return; - } - - clutter_input_device_keycode_to_evdev (virtual_evdev->device, - keycode, &evcode); - - if (get_button_type (evcode) != EVDEV_BUTTON_TYPE_KEY) - { - g_warning ("Unknown/invalid virtual device key 0x%x pressed\n", evcode); - return; - } - - key_count = update_button_count (virtual_evdev, evcode, key_state); - if (key_count < 0 || key_count > 1) - { - g_warning ("Received multiple virtual 0x%x key %s (ignoring)", keycode, - key_state == CLUTTER_KEY_STATE_PRESSED ? "presses" : "releases"); - update_button_count (virtual_evdev, evcode, 1 - key_state); - return; - } - - if (key_state) - apply_level_modifiers (virtual_device, time_us, level, key_state); - - clutter_seat_evdev_notify_key (virtual_evdev->seat, - virtual_evdev->device, - time_us, - evcode, - key_state, - TRUE); - - if (!key_state) - apply_level_modifiers (virtual_device, time_us, level, key_state); -} - -static void -direction_to_discrete (ClutterScrollDirection direction, - double *discrete_dx, - double *discrete_dy) -{ - switch (direction) - { - case CLUTTER_SCROLL_UP: - *discrete_dx = 0.0; - *discrete_dy = -1.0; - break; - case CLUTTER_SCROLL_DOWN: - *discrete_dx = 0.0; - *discrete_dy = 1.0; - break; - case CLUTTER_SCROLL_LEFT: - *discrete_dx = -1.0; - *discrete_dy = 0.0; - break; - case CLUTTER_SCROLL_RIGHT: - *discrete_dx = 1.0; - *discrete_dy = 0.0; - break; - case CLUTTER_SCROLL_SMOOTH: - g_assert_not_reached (); - break; - } -} - -static void -clutter_virtual_input_device_evdev_notify_discrete_scroll (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - ClutterScrollDirection direction, - ClutterScrollSource scroll_source) -{ - ClutterVirtualInputDeviceEvdev *virtual_evdev = - CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device); - double discrete_dx = 0.0, discrete_dy = 0.0; - - if (time_us == CLUTTER_CURRENT_TIME) - time_us = g_get_monotonic_time (); - - direction_to_discrete (direction, &discrete_dx, &discrete_dy); - - clutter_seat_evdev_notify_discrete_scroll (virtual_evdev->seat, - virtual_evdev->device, - time_us, - discrete_dx, discrete_dy, - scroll_source); -} - -static void -clutter_virtual_input_device_evdev_notify_scroll_continuous (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - double dx, - double dy, - ClutterScrollSource scroll_source, - ClutterScrollFinishFlags finish_flags) -{ - ClutterVirtualInputDeviceEvdev *virtual_evdev = - CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device); - - if (time_us == CLUTTER_CURRENT_TIME) - time_us = g_get_monotonic_time (); - - clutter_seat_evdev_notify_scroll_continuous (virtual_evdev->seat, - virtual_evdev->device, - time_us, - dx, dy, - scroll_source, - CLUTTER_SCROLL_FINISHED_NONE); -} - -static void -clutter_virtual_input_device_evdev_notify_touch_down (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - int device_slot, - double x, - double y) -{ - ClutterVirtualInputDeviceEvdev *virtual_evdev = - CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device); - ClutterInputDeviceEvdev *device_evdev = - CLUTTER_INPUT_DEVICE_EVDEV (virtual_evdev->device); - ClutterTouchState *touch_state; - - if (time_us == CLUTTER_CURRENT_TIME) - time_us = g_get_monotonic_time (); - - touch_state = clutter_input_device_evdev_acquire_touch_state (device_evdev, - device_slot); - if (!touch_state) - return; - - touch_state->coords.x = x; - touch_state->coords.y = y; - - clutter_seat_evdev_notify_touch_event (virtual_evdev->seat, - virtual_evdev->device, - CLUTTER_TOUCH_BEGIN, - time_us, - touch_state->seat_slot, - touch_state->coords.x, - touch_state->coords.y); -} - -static void -clutter_virtual_input_device_evdev_notify_touch_motion (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - int device_slot, - double x, - double y) -{ - ClutterVirtualInputDeviceEvdev *virtual_evdev = - CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device); - ClutterInputDeviceEvdev *device_evdev = - CLUTTER_INPUT_DEVICE_EVDEV (virtual_evdev->device); - ClutterTouchState *touch_state; - - if (time_us == CLUTTER_CURRENT_TIME) - time_us = g_get_monotonic_time (); - - touch_state = clutter_input_device_evdev_lookup_touch_state (device_evdev, - device_slot); - if (!touch_state) - return; - - touch_state->coords.x = x; - touch_state->coords.y = y; - - clutter_seat_evdev_notify_touch_event (virtual_evdev->seat, - virtual_evdev->device, - CLUTTER_TOUCH_BEGIN, - time_us, - touch_state->seat_slot, - touch_state->coords.x, - touch_state->coords.y); -} - -static void -clutter_virtual_input_device_evdev_notify_touch_up (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - int device_slot) -{ - ClutterVirtualInputDeviceEvdev *virtual_evdev = - CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device); - ClutterInputDeviceEvdev *device_evdev = - CLUTTER_INPUT_DEVICE_EVDEV (virtual_evdev->device); - ClutterTouchState *touch_state; - - if (time_us == CLUTTER_CURRENT_TIME) - time_us = g_get_monotonic_time (); - - touch_state = clutter_input_device_evdev_lookup_touch_state (device_evdev, - device_slot); - if (!touch_state) - return; - - clutter_seat_evdev_notify_touch_event (virtual_evdev->seat, - virtual_evdev->device, - CLUTTER_TOUCH_BEGIN, - time_us, - touch_state->seat_slot, - touch_state->coords.x, - touch_state->coords.y); - - clutter_input_device_evdev_release_touch_state (device_evdev, touch_state); -} - -static void -clutter_virtual_input_device_evdev_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterVirtualInputDeviceEvdev *virtual_evdev = - CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (object); - - switch (prop_id) - { - case PROP_SEAT: - g_value_set_pointer (value, virtual_evdev->seat); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -clutter_virtual_input_device_evdev_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterVirtualInputDeviceEvdev *virtual_evdev = - CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (object); - - switch (prop_id) - { - case PROP_SEAT: - virtual_evdev->seat = g_value_get_pointer (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -clutter_virtual_input_device_evdev_constructed (GObject *object) -{ - ClutterVirtualInputDevice *virtual_device = - CLUTTER_VIRTUAL_INPUT_DEVICE (object); - ClutterVirtualInputDeviceEvdev *virtual_evdev = - CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (object); - ClutterDeviceManager *manager; - ClutterInputDeviceType device_type; - ClutterStage *stage; - - manager = clutter_virtual_input_device_get_manager (virtual_device); - device_type = clutter_virtual_input_device_get_device_type (virtual_device); - - virtual_evdev->device = - _clutter_input_device_evdev_new_virtual (manager, - virtual_evdev->seat, - device_type, - CLUTTER_INPUT_MODE_SLAVE); - - stage = _clutter_device_manager_evdev_get_stage (CLUTTER_DEVICE_MANAGER_EVDEV (manager)); - _clutter_input_device_set_stage (virtual_evdev->device, stage); -} - -static void -clutter_virtual_input_device_evdev_finalize (GObject *object) -{ - ClutterVirtualInputDevice *virtual_device = - CLUTTER_VIRTUAL_INPUT_DEVICE (object); - ClutterVirtualInputDeviceEvdev *virtual_evdev = - CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (object); - GObjectClass *object_class; - - release_pressed_buttons (virtual_device); - g_clear_object (&virtual_evdev->device); - - object_class = - G_OBJECT_CLASS (clutter_virtual_input_device_evdev_parent_class); - object_class->finalize (object); -} - -static void -clutter_virtual_input_device_evdev_init (ClutterVirtualInputDeviceEvdev *virtual_device_evdev) -{ -} - -static void -clutter_virtual_input_device_evdev_class_init (ClutterVirtualInputDeviceEvdevClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - ClutterVirtualInputDeviceClass *virtual_input_device_class = - CLUTTER_VIRTUAL_INPUT_DEVICE_CLASS (klass); - - object_class->get_property = clutter_virtual_input_device_evdev_get_property; - object_class->set_property = clutter_virtual_input_device_evdev_set_property; - object_class->constructed = clutter_virtual_input_device_evdev_constructed; - object_class->finalize = clutter_virtual_input_device_evdev_finalize; - - virtual_input_device_class->notify_relative_motion = clutter_virtual_input_device_evdev_notify_relative_motion; - virtual_input_device_class->notify_absolute_motion = clutter_virtual_input_device_evdev_notify_absolute_motion; - virtual_input_device_class->notify_button = clutter_virtual_input_device_evdev_notify_button; - virtual_input_device_class->notify_key = clutter_virtual_input_device_evdev_notify_key; - virtual_input_device_class->notify_keyval = clutter_virtual_input_device_evdev_notify_keyval; - virtual_input_device_class->notify_discrete_scroll = clutter_virtual_input_device_evdev_notify_discrete_scroll; - virtual_input_device_class->notify_scroll_continuous = clutter_virtual_input_device_evdev_notify_scroll_continuous; - virtual_input_device_class->notify_touch_down = clutter_virtual_input_device_evdev_notify_touch_down; - virtual_input_device_class->notify_touch_motion = clutter_virtual_input_device_evdev_notify_touch_motion; - virtual_input_device_class->notify_touch_up = clutter_virtual_input_device_evdev_notify_touch_up; - - obj_props[PROP_SEAT] = g_param_spec_pointer ("seat", - P_("ClutterSeatEvdev"), - P_("ClutterSeatEvdev"), - CLUTTER_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY); - g_object_class_install_properties (object_class, PROP_LAST, obj_props); -} diff --git a/clutter/clutter/evdev/clutter-xkb-utils.h b/clutter/clutter/evdev/clutter-xkb-utils.h deleted file mode 100644 index ae057dd6f..000000000 --- a/clutter/clutter/evdev/clutter-xkb-utils.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - - * Authors: - * Damien Lespiau - */ - -#ifndef __CLUTTER_XKB_UTILS_H__ -#define __CLUTTER_XKB_UTILS_H__ - -#include - -#include "clutter-stage.h" -#include "clutter-event.h" -#include "clutter-input-device.h" - -ClutterEvent * _clutter_key_event_new_from_evdev (ClutterInputDevice *device, - ClutterInputDevice *core_keyboard, - ClutterStage *stage, - struct xkb_state *xkb_state, - uint32_t button_state, - uint32_t _time, - uint32_t key, - uint32_t state); -void _clutter_xkb_translate_state (ClutterEvent *event, - struct xkb_state *xkb_state, - uint32_t button_state); - -#endif /* __CLUTTER_XKB_UTILS_H__ */ diff --git a/clutter/clutter/meson.build b/clutter/clutter/meson.build new file mode 100644 index 000000000..505bc716e --- /dev/null +++ b/clutter/clutter/meson.build @@ -0,0 +1,561 @@ +clutter_clutter_includesubdir = join_paths(clutter_includesubdir, 'clutter') +clutter_clutter_includedir = join_paths(clutter_includedir, 'clutter') + +clutter_headers = [ + 'clutter.h', + 'clutter-action.h', + 'clutter-actor-meta.h', + 'clutter-actor.h', + 'clutter-align-constraint.h', + 'clutter-animatable.h', + 'clutter-autocleanups.h', + 'clutter-backend.h', + 'clutter-bind-constraint.h', + 'clutter-binding-pool.h', + 'clutter-bin-layout.h', + 'clutter-blur-effect.h', + 'clutter-box-layout.h', + 'clutter-brightness-contrast-effect.h', + 'clutter-cairo.h', + 'clutter-canvas.h', + 'clutter-child-meta.h', + 'clutter-click-action.h', + 'clutter-clone.h', + 'clutter-color-static.h', + 'clutter-color.h', + 'clutter-colorize-effect.h', + 'clutter-constraint.h', + 'clutter-container.h', + 'clutter-content.h', + 'clutter-deform-effect.h', + 'clutter-deprecated.h', + 'clutter-desaturate-effect.h', + 'clutter-drag-action.h', + 'clutter-drop-action.h', + 'clutter-effect.h', + 'clutter-enums.h', + 'clutter-event.h', + 'clutter-feature.h', + 'clutter-fixed-layout.h', + 'clutter-flow-layout.h', + 'clutter-gesture-action.h', + 'clutter-grid-layout.h', + 'clutter-group.h', + 'clutter-image.h', + 'clutter-input-device.h', + 'clutter-input-device-tool.h', + 'clutter-input-focus.h', + 'clutter-input-method.h', + 'clutter-interval.h', + 'clutter-keyframe-transition.h', + 'clutter-keymap.h', + 'clutter-keysyms.h', + 'clutter-layout-manager.h', + 'clutter-layout-meta.h', + 'clutter-macros.h', + 'clutter-main.h', + 'clutter-mutter.h', + 'clutter-offscreen-effect.h', + 'clutter-page-turn-effect.h', + 'clutter-paint-context.h', + 'clutter-paint-nodes.h', + 'clutter-paint-node.h', + 'clutter-pan-action.h', + 'clutter-path-constraint.h', + 'clutter-path.h', + 'clutter-pick-context.h', + 'clutter-property-transition.h', + 'clutter-rotate-action.h', + 'clutter-script.h', + 'clutter-scriptable.h', + 'clutter-scroll-actor.h', + 'clutter-seat.h', + 'clutter-settings.h', + 'clutter-shader-effect.h', + 'clutter-shader-types.h', + 'clutter-swipe-action.h', + 'clutter-snap-constraint.h', + 'clutter-stage.h', + 'clutter-stage-manager.h', + 'clutter-stage-view.h', + 'clutter-tap-action.h', + 'clutter-text.h', + 'clutter-text-buffer.h', + 'clutter-timeline.h', + 'clutter-transition-group.h', + 'clutter-transition.h', + 'clutter-types.h', + 'clutter-units.h', + 'clutter-virtual-input-device.h', + 'clutter-zoom-action.h', +] + +clutter_sources = [ + 'clutter-action.c', + 'clutter-actor-box.c', + 'clutter-actor-meta.c', + 'clutter-actor.c', + 'clutter-align-constraint.c', + 'clutter-animatable.c', + 'clutter-backend.c', + 'clutter-base-types.c', + 'clutter-bezier.c', + 'clutter-bind-constraint.c', + 'clutter-binding-pool.c', + 'clutter-bin-layout.c', + 'clutter-blur-effect.c', + 'clutter-box-layout.c', + 'clutter-brightness-contrast-effect.c', + 'clutter-cairo.c', + 'clutter-canvas.c', + 'clutter-child-meta.c', + 'clutter-click-action.c', + 'clutter-clone.c', + 'clutter-color.c', + 'clutter-colorize-effect.c', + 'clutter-constraint.c', + 'clutter-container.c', + 'clutter-content.c', + 'clutter-deform-effect.c', + 'clutter-desaturate-effect.c', + 'clutter-drag-action.c', + 'clutter-drop-action.c', + 'clutter-effect.c', + 'clutter-event.c', + 'clutter-feature.c', + 'clutter-fixed-layout.c', + 'clutter-flatten-effect.c', + 'clutter-flow-layout.c', + 'clutter-gesture-action.c', + 'clutter-graphene.c', + 'clutter-grid-layout.c', + 'clutter-image.c', + 'clutter-input-device.c', + 'clutter-input-device-tool.c', + 'clutter-input-focus.c', + 'clutter-input-method.c', + 'clutter-input-pointer-a11y.c', + 'clutter-virtual-input-device.c', + 'clutter-interval.c', + 'clutter-keyframe-transition.c', + 'clutter-keymap.c', + 'clutter-keysyms-table.c', + 'clutter-layout-manager.c', + 'clutter-layout-meta.c', + 'clutter-main.c', + 'clutter-master-clock.c', + 'clutter-master-clock-default.c', + 'clutter-offscreen-effect.c', + 'clutter-page-turn-effect.c', + 'clutter-paint-context.c', + 'clutter-paint-nodes.c', + 'clutter-paint-node.c', + 'clutter-pan-action.c', + 'clutter-path-constraint.c', + 'clutter-path.c', + 'clutter-pick-context.c', + 'clutter-property-transition.c', + 'clutter-rotate-action.c', + 'clutter-script.c', + 'clutter-script-parser.c', + 'clutter-scriptable.c', + 'clutter-scroll-actor.c', + 'clutter-seat.c', + 'clutter-settings.c', + 'clutter-shader-effect.c', + 'clutter-shader-types.c', + 'clutter-swipe-action.c', + 'clutter-snap-constraint.c', + 'clutter-stage.c', + 'clutter-stage-manager.c', + 'clutter-stage-view.c', + 'clutter-stage-window.c', + 'clutter-tap-action.c', + 'clutter-text.c', + 'clutter-text-buffer.c', + 'clutter-transition-group.c', + 'clutter-transition.c', + 'clutter-timeline.c', + 'clutter-units.c', + 'clutter-util.c', + 'clutter-paint-volume.c', + 'clutter-zoom-action.c', +] + +clutter_private_headers = [ + 'clutter-actor-meta-private.h', + 'clutter-actor-private.h', + 'clutter-backend-private.h', + 'clutter-bezier.h', + 'clutter-constraint-private.h', + 'clutter-content-private.h', + 'clutter-debug.h', + 'clutter-easing.h', + 'clutter-effect-private.h', + 'clutter-event-private.h', + 'clutter-flatten-effect.h', + 'clutter-graphene.h', + 'clutter-gesture-action-private.h', + 'clutter-id-pool.h', + 'clutter-input-device-private.h', + 'clutter-input-focus-private.h', + 'clutter-input-method-private.h', + 'clutter-input-pointer-a11y-private.h', + 'clutter-master-clock.h', + 'clutter-master-clock-default.h', + 'clutter-offscreen-effect-private.h', + 'clutter-paint-context-private.h', + 'clutter-paint-node-private.h', + 'clutter-paint-volume-private.h', + 'clutter-private.h', + 'clutter-script-private.h', + 'clutter-settings-private.h', + 'clutter-stage-manager-private.h', + 'clutter-stage-private.h', + 'clutter-stage-view-private.h', + 'clutter-stage-window.h', +] + +clutter_nonintrospected_sources = [ + 'clutter-easing.c', + 'clutter-id-pool.c', +] + +clutter_deprecated_headers = [ + 'deprecated/clutter-actor.h', + 'deprecated/clutter-alpha.h', + 'deprecated/clutter-animation.h', + 'deprecated/clutter-box.h', + 'deprecated/clutter-container.h', + 'deprecated/clutter-group.h', + 'deprecated/clutter-rectangle.h', + 'deprecated/clutter-stage.h', + 'deprecated/clutter-state.h', + 'deprecated/clutter-timeline.h', +] + +clutter_deprecated_sources = [ + 'deprecated/clutter-alpha.c', + 'deprecated/clutter-animation.c', + 'deprecated/clutter-box.c', + 'deprecated/clutter-group.c', + 'deprecated/clutter-rectangle.c', + 'deprecated/clutter-state.c', +] + +clutter_backend_sources = [] +clutter_backend_nonintrospected_sources = [ + 'cogl/clutter-stage-cogl.c', +] +clutter_backend_headers = [] +clutter_backend_private_headers = [ + 'cogl/clutter-stage-cogl.h', +] + +if have_x11 + clutter_x11_sources = [ + 'x11/clutter-backend-x11.c', + ] + clutter_backend_sources += clutter_x11_sources + + clutter_x11_headers = [ + 'x11/clutter-x11.h', + ] + clutter_backend_headers += clutter_x11_headers + + clutter_x11_private_headers = [ + 'x11/clutter-backend-x11.h', + 'x11/clutter-settings-x11.h', + ] + clutter_backend_private_headers += clutter_x11_private_headers + + clutter_x11_nonintrospected_sources = [ + 'x11/xsettings/xsettings-client.c', + 'x11/xsettings/xsettings-client.h', + 'x11/xsettings/xsettings-common.c', + 'x11/xsettings/xsettings-common.h', + ] + clutter_backend_nonintrospected_sources += clutter_x11_nonintrospected_sources +endif + +if have_native_backend + clutter_native_nonintrospected_sources = [ + 'egl/clutter-backend-eglnative.c', + ] + clutter_backend_nonintrospected_sources += clutter_native_nonintrospected_sources +endif + +if have_wayland + clutter_wayland_private_headers = [ + 'wayland/clutter-wayland-compositor.h', + ] + clutter_backend_private_headers += clutter_wayland_private_headers +endif + +cally_headers = [ + 'cally/cally-actor.h', + 'cally/cally-clone.h', + 'cally/cally-factory.h', + 'cally/cally-group.h', + 'cally/cally.h', + 'cally/cally-main.h', + 'cally/cally-rectangle.h', + 'cally/cally-root.h', + 'cally/cally-stage.h', + 'cally/cally-text.h', + 'cally/cally-util.h', +] + +cally_sources = [ + 'cally/cally-actor.c', + 'cally/cally.c', + 'cally/cally-clone.c', + 'cally/cally-group.c', + 'cally/cally-rectangle.c', + 'cally/cally-root.c', + 'cally/cally-stage.c', + 'cally/cally-text.c', + 'cally/cally-util.c', +] + +cally_private_headers = [ + 'cally/cally-actor-private.h', +] + +clutter_built_sources = [] +clutter_built_headers = [] +clutter_built_private_headers = [] + +cdata = configuration_data() +cdata.set_quoted('MUTTER_VERSION', meson.project_version()) +cdata.set('CLUTTER_DRIVERS', '"*"') +cdata.set('HAVE_EVDEV', have_native_backend) +cdata.set('HAVE_LIBWACOM', have_libwacom) +cdata.set('HAVE_PANGO_FT2', have_pango_ft2) + +clutter_build_config_h = configure_file( + input: 'clutter-build-config.h.meson', + output: 'clutter-build-config.h', + configuration: cdata, + install: false, +) +clutter_built_private_headers += clutter_build_config_h + +clutter_config_defines = [] +if have_wayland + clutter_config_defines += [ + '#define CLUTTER_HAS_WAYLAND_COMPOSITOR_SUPPORT 1', + ] +endif +if have_x11 + clutter_config_defines += [ + '#define CLUTTER_WINDOWING_X11 "x11"', + '#define CLUTTER_INPUT_X11 "x11"', + '#define CLUTTER_WINDOWING_GLX "glx"', + ] +endif +if have_native_backend + clutter_config_defines += [ + '#define CLUTTER_WINDOWING_EGL "eglnative"', + '#define CLUTTER_INPUT_EVDEV "evdev"', + ] +endif +clutter_config_defines += [ + '#define CLUTTER_INPUT_NULL "null"', +] +clutter_config_defines_string = '' +foreach clutter_config_define : clutter_config_defines + clutter_config_defines_string += clutter_config_define + '\n' +endforeach + +cdata = configuration_data() +cdata.set('CLUTTER_CONFIG_DEFINES', clutter_config_defines_string) + +clutter_config_h = configure_file( + input: 'clutter-config.h.in', + output: 'clutter-config.h', + configuration: cdata, + install: true, + install_dir: clutter_clutter_includedir, +) +clutter_built_headers += clutter_config_h + +clutter_enum_types = gnome.mkenums('clutter-enum-types', + sources: [clutter_headers, clutter_deprecated_headers], + c_template: 'clutter-enum-types.c.in', + h_template: 'clutter-enum-types.h.in', + install_dir: clutter_clutter_includedir, + install_header: true, +) +clutter_built_sources += clutter_enum_types[0] +clutter_built_headers += clutter_enum_types[1] + +clutter_marshal = gnome.genmarshal('clutter-marshal', + prefix: '_clutter_marshal', + sources: 'clutter-marshal.list', + valist_marshallers: true, + extra_args: ['--quiet'], + install_dir: clutter_clutter_includedir, + install_header: true, +) +clutter_built_sources += clutter_marshal[0] +clutter_built_headers += clutter_marshal[1] + +libmutter_clutter_name = 'muffin-clutter-' + libmutter_api_version +libmutter_clutter = shared_library(libmutter_clutter_name, + sources: [ + clutter_sources, + clutter_headers, + clutter_private_headers, + clutter_nonintrospected_sources, + clutter_deprecated_sources, + clutter_deprecated_headers, + clutter_backend_sources, + clutter_backend_nonintrospected_sources, + clutter_backend_headers, + clutter_backend_private_headers, + clutter_built_sources, + clutter_built_headers, + cally_sources, + cally_headers, + cally_private_headers, + ], + version: '0.0.0', + soversion: 0, + c_args: clutter_c_args, + include_directories: clutter_includes, + dependencies: [clutter_deps], + gnu_symbol_visibility: 'hidden', + link_with: [ + libmutter_cogl, + libmutter_cogl_pango, + libmutter_cogl_path, + ], + install_rpath: pkglibdir, + install_dir: pkglibdir, + install: true, +) +libmutter_clutter_dep = declare_dependency( + sources: [clutter_enum_types[1]], + link_with: libmutter_clutter, + dependencies: clutter_deps, +) + +if have_introspection + clutter_introspection_args = introspection_args + [ + '-DCLUTTER_SYSCONFDIR="@0@"'.format(join_paths(prefix, sysconfdir)), + '-DCLUTTER_COMPILATION=1', + '-DCOGL_DISABLE_DEPRECATION_WARNINGS', + '-DG_LOG_DOMAIN="Clutter"' + ] + + libmutter_clutter_gir = gnome.generate_gir(libmutter_clutter, + sources: [ + clutter_built_sources, + clutter_built_headers, + clutter_sources, + clutter_headers, + clutter_deprecated_sources, + clutter_deprecated_headers, + ], + nsversion: libmutter_api_version, + namespace: 'Clutter', + export_packages: [libmutter_clutter_name], + includes: [ + libmutter_cogl_gir[0], + libmutter_cogl_pango_gir[0], + 'GL-1.0', + 'GObject-2.0', + 'cairo-1.0', + 'Atk-1.0', + 'Json-1.0', + ], + dependencies: [cogl_deps], + extra_args: clutter_introspection_args + ['--c-include=clutter/clutter.h'], + install_dir_gir: pkglibdir, + install_dir_typelib: pkglibdir, + install: true, + ) + + libmutter_cally_gir = gnome.generate_gir(libmutter_clutter, + sources: [ + cally_sources, + cally_headers, + ], + nsversion: libmutter_api_version, + namespace: 'Cally', + includes: [ + libmutter_cogl_gir[0], + libmutter_cogl_pango_gir[0], + libmutter_clutter_gir[0], + ], + dependencies: [cogl_deps], + extra_args: clutter_introspection_args, + install_dir_gir: pkglibdir, + install_dir_typelib: pkglibdir, + install: true + ) + + if have_x11 + libmutter_clutter_x11_gir = gnome.generate_gir(libmutter_clutter, + sources: [ + clutter_x11_sources, + clutter_x11_headers, + ], + nsversion: libmutter_api_version, + namespace: 'ClutterX11', + export_packages: ['muffin-clutter-x11-' + libmutter_api_version], + includes: [ + libmutter_cogl_gir[0], + libmutter_cogl_pango_gir[0], + libmutter_clutter_gir[0], + 'xlib-2.0', + ], + dependencies: [], + extra_args: clutter_introspection_args, + install_dir_gir: pkglibdir, + install_dir_typelib: pkglibdir, + install: true + ) + endif +endif + +install_headers(clutter_headers, + subdir: clutter_clutter_includesubdir) + +install_headers(cally_headers, + subdir: join_paths(clutter_includesubdir, 'cally')) + +install_headers(clutter_deprecated_headers, + subdir: join_paths(clutter_clutter_includesubdir, 'deprecated')) + +install_headers(clutter_x11_headers, + subdir: join_paths(clutter_clutter_includesubdir, 'x11')) + +pkg.generate(libmutter_clutter, + name: 'Muffins Clutter', + filebase: libmutter_clutter_name, + description: 'Muffinss Clutter Private Library', + libraries: [m_dep], + subdirs: join_paths(pkgname, 'clutter'), + requires: [clutter_pkg_deps, libmutter_cogl_name], + version: meson.project_version(), + variables: [ + 'apiversion=' + libmutter_api_version, + ], + install_dir: pcdir, +) + +pkg.generate(libmutter_clutter, + name: 'Muffins ClutterX11', + filebase: 'muffin-clutter-x11-' + libmutter_api_version, + description: 'Muffin ClutterX11 Private Library', + libraries: [m_dep], + subdirs: join_paths(pkgname, 'clutter'), + requires: [clutter_pkg_deps, libmutter_cogl_name], + version: meson.project_version(), + variables: [ + 'apiversion=' + libmutter_api_version, + ], + install_dir: pcdir, +) diff --git a/clutter/clutter/muffin-clutter.pc.in b/clutter/clutter/muffin-clutter.pc.in deleted file mode 100644 index 930c5f9a1..000000000 --- a/clutter/clutter/muffin-clutter.pc.in +++ /dev/null @@ -1,24 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@/muffin -includedir=@includedir@/muffin - -apiversion=@MUFFIN_PLUGIN_API_VERSION@ -requires=@CLUTTER_REQUIRES@ muffin-cogl-@MUFFIN_PLUGIN_API_VERSION@ -requires_private=@CLUTTER_REQUIRES_PRIVATE@ -backends=@CLUTTER_BACKENDS@ - -# only kept for backward compatibility -soname_infix=@CLUTTER_SONAME_INFIX@ -winsys=@CLUTTER_WINSYS@ -backend=@CLUTTER_WINSYS@ -cogl=deprecated -cogl_driver=deprecated - -Name: Muffin Clutter -Description: Muffin's Clutter Private Library -Version: @MUFFIN_VERSION@ -Libs: -L${libdir} -lmuffin-clutter-${apiversion} -Cflags: -I${includedir}/clutter-${apiversion} -Requires: ${requires} -Requires.private: ${requires_private} diff --git a/clutter/clutter/mutter-clutter.pc.in b/clutter/clutter/mutter-clutter.pc.in new file mode 100644 index 000000000..6509dfc95 --- /dev/null +++ b/clutter/clutter/mutter-clutter.pc.in @@ -0,0 +1,24 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +apiversion=@LIBMUTTER_API_VERSION@ +libdir=@libdir@/mutter-${apiversion} +includedir=@includedir@/mutter-${apiversion} + +requires=@CLUTTER_REQUIRES@ mutter-cogl-${apiversion} +requires_private=@CLUTTER_REQUIRES_PRIVATE@ +backends=@CLUTTER_BACKENDS@ + +# only kept for backward compatibility +soname_infix=@CLUTTER_SONAME_INFIX@ +winsys=@CLUTTER_WINSYS@ +backend=@CLUTTER_WINSYS@ +cogl=deprecated +cogl_driver=deprecated + +Name: Mutter Clutter +Description: Mutter's Clutter Private Library +Version: @MUTTER_VERSION@ +Libs: -L${libdir} -lmutter-clutter-${apiversion} +Cflags: -I${includedir}/clutter +Requires: ${requires} +Requires.private: ${requires_private} diff --git a/clutter/clutter/wayland/clutter-wayland-compositor.h b/clutter/clutter/wayland/clutter-wayland-compositor.h index 703a7e2f5..cdd4cebcf 100644 --- a/clutter/clutter/wayland/clutter-wayland-compositor.h +++ b/clutter/clutter/wayland/clutter-wayland-compositor.h @@ -37,7 +37,7 @@ G_BEGIN_DECLS -CLUTTER_AVAILABLE_IN_1_10 +CLUTTER_EXPORT void clutter_wayland_set_compositor_display (void *display); G_END_DECLS diff --git a/clutter/clutter/wayland/clutter-wayland-surface.c b/clutter/clutter/wayland/clutter-wayland-surface.c deleted file mode 100644 index 2465a1814..000000000 --- a/clutter/clutter/wayland/clutter-wayland-surface.c +++ /dev/null @@ -1,652 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * Authors: - * Robert Bragg - */ - -/** - * SECTION:clutter-wayland-surface - * @Title: ClutterWaylandSurface - * @short_description: An actor which displays the content of a client surface - * - * #ClutterWaylandSurface is an actor for displaying the contents of a client - * surface. It is intended to support developers implementing Clutter based - * wayland compositors. - */ - -#ifdef HAVE_CONFIG_H -#include "clutter-build-config.h" -#endif - -#define CLUTTER_ENABLE_EXPERIMENTAL_API - -#include "clutter-wayland-surface.h" - -#include "clutter-actor-private.h" -#include "clutter-marshal.h" -#include "clutter-paint-volume-private.h" -#include "clutter-private.h" -#include "clutter-backend.h" - -#include -#include - -enum -{ - PROP_SURFACE = 1, - PROP_SURFACE_WIDTH, - PROP_SURFACE_HEIGHT, - PROP_COGL_TEXTURE, - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST]; - -enum -{ - QUEUE_DAMAGE_REDRAW, - - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0, }; - -struct _ClutterWaylandSurfacePrivate -{ - struct wl_surface *surface; - CoglTexture2D *buffer; - int width, height; - CoglPipeline *pipeline; -}; - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterWaylandSurface, - clutter_wayland_surface, - CLUTTER_TYPE_ACTOR) - -static gboolean -clutter_wayland_surface_get_paint_volume (ClutterActor *self, - ClutterPaintVolume *volume) -{ - return clutter_paint_volume_set_from_allocation (volume, self); -} - -static void -clutter_wayland_surface_queue_damage_redraw (ClutterWaylandSurface *texture, - gint x, - gint y, - gint width, - gint height) -{ - ClutterWaylandSurfacePrivate *priv = texture->priv; - ClutterActor *self = CLUTTER_ACTOR (texture); - ClutterActorBox allocation; - float scale_x; - float scale_y; - cairo_rectangle_int_t clip; - - /* NB: clutter_actor_queue_redraw_with_clip expects a box in the actor's - * coordinate space so we need to convert from surface coordinates to - * actor coordinates... - */ - - /* Calling clutter_actor_get_allocation_box() is enormously expensive - * if the actor has an out-of-date allocation, since it triggers - * a full redraw. clutter_actor_queue_redraw_with_clip() would redraw - * the whole stage anyways in that case, so just go ahead and do - * it here. - */ - if (!clutter_actor_has_allocation (self)) - { - clutter_actor_queue_redraw (self); - return; - } - - if (priv->width == 0 || priv->height == 0) - return; - - clutter_actor_get_allocation_box (self, &allocation); - - scale_x = (allocation.x2 - allocation.x1) / priv->width; - scale_y = (allocation.y2 - allocation.y1) / priv->height; - - clip.x = x * scale_x; - clip.y = y * scale_y; - clip.width = width * scale_x; - clip.height = height * scale_y; - clutter_actor_queue_redraw_with_clip (self, &clip); -} - -static void -free_pipeline (ClutterWaylandSurface *self) -{ - ClutterWaylandSurfacePrivate *priv = self->priv; - - if (priv->pipeline) - { - cogl_object_unref (priv->pipeline); - priv->pipeline = NULL; - } -} - -static void -opacity_change_cb (ClutterWaylandSurface *self) -{ - free_pipeline (self); -} - -static void -clutter_wayland_surface_init (ClutterWaylandSurface *self) -{ - ClutterWaylandSurfacePrivate *priv; - - priv = clutter_wayland_surface_get_instance_private (self); - priv->surface = NULL; - priv->width = 0; - priv->height = 0; - - self->priv = priv; - - g_signal_connect (self, "notify::opacity", G_CALLBACK (opacity_change_cb), NULL); -} - -static void -free_surface_buffers (ClutterWaylandSurface *self) -{ - ClutterWaylandSurfacePrivate *priv = self->priv; - - if (priv->buffer) - { - cogl_object_unref (priv->buffer); - priv->buffer = NULL; - free_pipeline (self); - } -} - -static void -clutter_wayland_surface_dispose (GObject *object) -{ - ClutterWaylandSurface *self = CLUTTER_WAYLAND_SURFACE (object); - ClutterWaylandSurfacePrivate *priv = self->priv; - - free_pipeline (self); - free_surface_buffers (self); - priv->surface = NULL; - - G_OBJECT_CLASS (clutter_wayland_surface_parent_class)->dispose (object); -} - -static void -set_size (ClutterWaylandSurface *self, - int width, - int height) -{ - ClutterWaylandSurfacePrivate *priv = self->priv; - - if (priv->width != width) - { - priv->width = width; - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_SURFACE_WIDTH]); - } - if (priv->height != height) - { - priv->height = height; - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_SURFACE_HEIGHT]); - } - - clutter_actor_set_size (CLUTTER_ACTOR (self), priv->width, priv->height); -} - -/** - * clutter_wayland_surface_get_surface: - * @self: a #ClutterWaylandSurface - * - * Retrieves a point to the Wayland surface used by the actor. - * - * Return value: (transfer none): a wl_surface pointer, or %NULL - * - * Since: 1.10 - */ -struct wl_surface * -clutter_wayland_surface_get_surface (ClutterWaylandSurface *self) -{ - ClutterWaylandSurfacePrivate *priv = self->priv; - return priv->surface; -} - -/** - * clutter_wayland_surface_set_surface: - * @self: a #ClutterWaylandSurface - * @surface: a Wayland wl_surface pointer - * - * Sets the Wayland surface to be used by the actor. - * - * Since: 1.10 - */ -void -clutter_wayland_surface_set_surface (ClutterWaylandSurface *self, - struct wl_surface *surface) -{ - ClutterWaylandSurfacePrivate *priv; - - g_return_if_fail (CLUTTER_WAYLAND_IS_SURFACE (self)); - - priv = self->priv; - - if (priv->surface == surface) - return; - - if (priv->surface) - { - free_pipeline (self); - free_surface_buffers (self); - g_signal_emit (self, signals[QUEUE_DAMAGE_REDRAW], - 0, - 0, 0, priv->width, priv->height); - } - - priv->surface = surface; - - /* XXX: should we freeze/thaw notifications? */ - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_SURFACE]); - - /* We have to wait until the next attach event to find out the surface - * geometry... */ - set_size (self, 0, 0); -} - -static void -clutter_wayland_surface_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterWaylandSurface *self = CLUTTER_WAYLAND_SURFACE (object); - - switch (prop_id) - { - case PROP_SURFACE: - clutter_wayland_surface_set_surface (self, g_value_get_pointer (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -clutter_wayland_surface_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterWaylandSurface *self = CLUTTER_WAYLAND_SURFACE (object); - ClutterWaylandSurfacePrivate *priv = self->priv; - - switch (prop_id) - { - case PROP_SURFACE: - g_value_set_pointer (value, priv->surface); - break; - case PROP_SURFACE_WIDTH: - g_value_set_uint (value, priv->width); - break; - case PROP_SURFACE_HEIGHT: - g_value_set_uint (value, priv->height); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -clutter_wayland_surface_paint (ClutterActor *self) -{ - ClutterWaylandSurfacePrivate *priv; - ClutterActorBox box; - - g_return_if_fail (CLUTTER_WAYLAND_IS_SURFACE (self)); - - priv = CLUTTER_WAYLAND_SURFACE (self)->priv; - - if (G_UNLIKELY (priv->pipeline == NULL)) - { - CoglContext *ctx = - clutter_backend_get_cogl_context (clutter_get_default_backend ()); - guint8 paint_opacity = clutter_actor_get_paint_opacity (self); - - priv->pipeline = cogl_pipeline_new (ctx); - cogl_pipeline_set_color4ub (priv->pipeline, - paint_opacity, - paint_opacity, - paint_opacity, - paint_opacity); - cogl_pipeline_set_layer_texture (priv->pipeline, 0, - COGL_TEXTURE (priv->buffer)); - } - - cogl_set_source (priv->pipeline); - clutter_actor_get_allocation_box (self, &box); - cogl_rectangle (0, 0, box.x2 - box.x1, box.y2 - box.y1); -} - -static void -clutter_wayland_surface_get_preferred_width (ClutterActor *self, - gfloat for_height, - gfloat *min_width_p, - gfloat *natural_width_p) -{ - ClutterWaylandSurfacePrivate *priv; - - g_return_if_fail (CLUTTER_WAYLAND_IS_SURFACE (self)); - - priv = CLUTTER_WAYLAND_SURFACE (self)->priv; - - if (min_width_p) - *min_width_p = 0; - - if (natural_width_p) - *natural_width_p = priv->width; -} - -static void -clutter_wayland_surface_get_preferred_height (ClutterActor *self, - gfloat for_width, - gfloat *min_height_p, - gfloat *natural_height_p) -{ - ClutterWaylandSurfacePrivate *priv; - - g_return_if_fail (CLUTTER_WAYLAND_IS_SURFACE (self)); - - priv = CLUTTER_WAYLAND_SURFACE (self)->priv; - - if (min_height_p) - *min_height_p = 0; - - if (natural_height_p) - *natural_height_p = priv->height; -} - -static gboolean -clutter_wayland_surface_has_overlaps (ClutterActor *self) -{ - /* Rectangles never need an offscreen redirect because there are - never any overlapping primitives */ - return FALSE; -} - -static void -clutter_wayland_surface_class_init (ClutterWaylandSurfaceClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); - GParamSpec *pspec; - - actor_class->get_paint_volume = clutter_wayland_surface_get_paint_volume; - actor_class->paint = clutter_wayland_surface_paint; - actor_class->get_preferred_width = - clutter_wayland_surface_get_preferred_width; - actor_class->get_preferred_height = - clutter_wayland_surface_get_preferred_height; - actor_class->has_overlaps = clutter_wayland_surface_has_overlaps; - - object_class->dispose = clutter_wayland_surface_dispose; - object_class->set_property = clutter_wayland_surface_set_property; - object_class->get_property = clutter_wayland_surface_get_property; - - pspec = g_param_spec_pointer ("surface", - P_("Surface"), - P_("The underlying wayland surface"), - CLUTTER_PARAM_READWRITE| - G_PARAM_CONSTRUCT_ONLY); - obj_props[PROP_SURFACE] = pspec; - g_object_class_install_property (object_class, PROP_SURFACE, pspec); - - pspec = g_param_spec_uint ("surface-width", - P_("Surface width"), - P_("The width of the underlying wayland surface"), - 0, G_MAXUINT, - 0, - G_PARAM_READABLE); - obj_props[PROP_SURFACE_WIDTH] = pspec; - g_object_class_install_property (object_class, PROP_SURFACE_WIDTH, pspec); - - pspec = g_param_spec_uint ("surface-height", - P_("Surface height"), - P_("The height of the underlying wayland surface"), - 0, G_MAXUINT, - 0, - G_PARAM_READABLE); - obj_props[PROP_SURFACE_HEIGHT] = pspec; - g_object_class_install_property (object_class, PROP_SURFACE_HEIGHT, pspec); - - pspec = g_param_spec_boxed ("cogl-texture", - P_("Cogl Texture"), - P_("The underlying Cogl texture handle used to draw this actor"), - COGL_TYPE_HANDLE, - CLUTTER_PARAM_READWRITE); - obj_props[PROP_COGL_TEXTURE] = pspec; - g_object_class_install_property (object_class, PROP_COGL_TEXTURE, pspec); - - /** - * ClutterWaylandSurface::queue-damage-redraw: - * @texture: the object which received the signal - * @x: The top left x position of the damage region - * @y: The top left y position of the damage region - * @width: The width of the damage region - * @height: The height of the damage region - * - * ::queue-damage-redraw is emitted to notify that some sub-region - * of the texture has been changed. This usually means a redraw - * needs to be queued for the actor. - * - * The default handler will queue a clipped redraw in response to - * the damage, using the assumption that the pixmap is being painted - * to a rectangle covering the transformed allocation of the actor. - * If you sub-class and change the paint method so this isn't true - * then you must also provide your own damage signal handler to - * queue a redraw that blocks this default behaviour. - * - * Since: 1.10 - */ - signals[QUEUE_DAMAGE_REDRAW] = - g_signal_new (g_intern_static_string ("queue-damage-redraw"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (ClutterWaylandSurfaceClass, queue_damage_redraw), - NULL, NULL, - _clutter_marshal_VOID__INT_INT_INT_INT, - G_TYPE_NONE, 4, - G_TYPE_INT, - G_TYPE_INT, - G_TYPE_INT, - G_TYPE_INT); - klass->queue_damage_redraw = clutter_wayland_surface_queue_damage_redraw; -} - -/** - * clutter_wayland_surface_new: - * @surface: the Wayland surface this actor should represent - * - * Creates a new #ClutterWaylandSurface for @surface - * - * Return value: A new #ClutterWaylandSurface representing @surface - * - * Since: 1.8 - * Stability: unstable - */ -ClutterActor * -clutter_wayland_surface_new (struct wl_surface *surface) -{ - ClutterActor *actor; - - actor = g_object_new (CLUTTER_WAYLAND_TYPE_SURFACE, - "surface", surface, - NULL); - - return actor; -} - -/** - * clutter_wayland_surface_attach_buffer: - * @self: A #ClutterWaylandSurface actor - * @buffer: A compositor side resource representing a wl_buffer - * @error: A #GError - * - * This associates a client's buffer with the #ClutterWaylandSurface - * actor @self. This will automatically result in @self being re-drawn - * with the new buffer contents. - * - * Since: 1.8 - * Stability: unstable - */ -gboolean -clutter_wayland_surface_attach_buffer (ClutterWaylandSurface *self, - struct wl_resource *buffer, - GError **error) -{ - ClutterWaylandSurfacePrivate *priv; - ClutterBackend *backend = clutter_get_default_backend (); - CoglContext *context = clutter_backend_get_cogl_context (backend); - - g_return_val_if_fail (CLUTTER_WAYLAND_IS_SURFACE (self), TRUE); - - priv = self->priv; - - free_surface_buffers (self); - - priv->buffer = - cogl_wayland_texture_2d_new_from_buffer (context, buffer, error); - - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_COGL_TEXTURE]); - - /* NB: We don't queue a redraw of the actor here because we don't - * know how much of the buffer has changed with respect to the - * previous buffer. We only ever queue a redraw in response to - * surface damage. */ - - if (!priv->buffer) - return FALSE; - - set_size (self, - cogl_texture_get_width (COGL_TEXTURE (priv->buffer)), - cogl_texture_get_height (COGL_TEXTURE (priv->buffer))); - - return TRUE; -} - -/** - * clutter_wayland_surface_damage_buffer: - * @self: A #ClutterWaylandSurface actor - * @buffer: A wayland resource for a buffer - * @x: The x coordinate of the damaged rectangle - * @y: The y coordinate of the damaged rectangle - * @width: The width of the damaged rectangle - * @height: The height of the damaged rectangle - * - * This marks a region of the given @buffer has having been changed by - * the client. This will automatically result in the corresponding damaged - * region of the actor @self being redrawn. - * - * If multiple regions are changed then this should be called multiple - * times with different damage rectangles. - * - * Since: 1.8 - * Stability: unstable - */ -void -clutter_wayland_surface_damage_buffer (ClutterWaylandSurface *self, - struct wl_resource *buffer, - gint32 x, - gint32 y, - gint32 width, - gint32 height) -{ - ClutterWaylandSurfacePrivate *priv; - struct wl_shm_buffer *shm_buffer; - - g_return_if_fail (CLUTTER_WAYLAND_IS_SURFACE (self)); - - priv = self->priv; - - shm_buffer = wl_shm_buffer_get (buffer); - - if (priv->buffer && shm_buffer) - { - CoglPixelFormat format; - - switch (wl_shm_buffer_get_format (shm_buffer)) - { -#if G_BYTE_ORDER == G_BIG_ENDIAN - case WL_SHM_FORMAT_ARGB8888: - format = COGL_PIXEL_FORMAT_ARGB_8888_PRE; - break; - case WL_SHM_FORMAT_XRGB8888: - format = COGL_PIXEL_FORMAT_ARGB_8888; - break; -#elif G_BYTE_ORDER == G_LITTLE_ENDIAN - case WL_SHM_FORMAT_ARGB8888: - format = COGL_PIXEL_FORMAT_BGRA_8888_PRE; - break; - case WL_SHM_FORMAT_XRGB8888: - format = COGL_PIXEL_FORMAT_BGRA_8888; - break; -#endif - default: - g_warn_if_reached (); - format = COGL_PIXEL_FORMAT_ARGB_8888; - } - - cogl_texture_set_region (COGL_TEXTURE (priv->buffer), - x, y, - x, y, - width, height, - width, height, - format, - wl_shm_buffer_get_stride (shm_buffer), - wl_shm_buffer_get_data (shm_buffer)); - } - - g_signal_emit (self, signals[QUEUE_DAMAGE_REDRAW], - 0, - x, y, width, height); -} - -/** - * clutter_wayland_surface_get_cogl_texture: - * @self: a #ClutterWaylandSurface - * - * Retrieves the Cogl texture with the contents of the Wayland surface. - * - * Return value: (transfer none): a Cogl texture, or %NULL - * - * Since: 1.10 - */ -CoglTexture * -clutter_wayland_surface_get_cogl_texture (ClutterWaylandSurface *self) -{ - g_return_val_if_fail (CLUTTER_WAYLAND_IS_SURFACE (self), NULL); - - return COGL_TEXTURE (self->priv->buffer); -} diff --git a/clutter/clutter/wayland/clutter-wayland-surface.h b/clutter/clutter/wayland/clutter-wayland-surface.h deleted file mode 100644 index f674af88a..000000000 --- a/clutter/clutter/wayland/clutter-wayland-surface.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - * Authors: - * Robert Bragg - * - */ - -#ifndef __CLUTTER_WAYLAND_SURFACE_H__ -#define __CLUTTER_WAYLAND_SURFACE_H__ - -#include -#include -#include - -#include - -G_BEGIN_DECLS - -#define CLUTTER_WAYLAND_TYPE_SURFACE (clutter_wayland_surface_get_type ()) -#define CLUTTER_WAYLAND_SURFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_WAYLAND_TYPE_SURFACE, ClutterWaylandSurface)) -#define CLUTTER_WAYLAND_SURFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_WAYLAND_TYPE_SURFACE, ClutterWaylandSurfaceClass)) -#define CLUTTER_WAYLAND_IS_SURFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_WAYLAND_TYPE_SURFACE)) -#define CLUTTER_WAYLAND_IS_SURFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_WAYLAND_TYPE_SURFACE)) -#define CLUTTER_WAYLAND_SURFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_WAYLAND_TYPE_SURFACE, ClutterWaylandSurfaceClass)) - -typedef struct _ClutterWaylandSurface ClutterWaylandSurface; -typedef struct _ClutterWaylandSurfaceClass ClutterWaylandSurfaceClass; -typedef struct _ClutterWaylandSurfacePrivate ClutterWaylandSurfacePrivate; - -/** - * ClutterWaylandSurface: - * - * The #ClutterWaylandSurface structure contains only private data - * - * Since: 1.10 - * Stability: unstable - */ -struct _ClutterWaylandSurface -{ - /*< private >*/ - ClutterActor parent; - - ClutterWaylandSurfacePrivate *priv; -}; - -/** - * ClutterWaylandSurfaceClass: - * @queue_damage_redraw: class handler of the #ClutterWaylandSurface::queue-damage-redraw signal - * - * The #ClutterWaylandSurfaceClass structure contains only private data - * - * Since: 1.10 - * Stability: unstable - */ -struct _ClutterWaylandSurfaceClass -{ - /*< private >*/ - ClutterActorClass parent_class; - - /*< public >*/ - void (*queue_damage_redraw) (ClutterWaylandSurface *texture, - gint x, - gint y, - gint width, - gint height); - - /*< private >*/ - /* padding for future expansion */ - gpointer _padding_dummy[8]; -}; - -CLUTTER_AVAILABLE_IN_1_10 -GType clutter_wayland_surface_get_type (void) G_GNUC_CONST; - -CLUTTER_AVAILABLE_IN_1_8 -ClutterActor *clutter_wayland_surface_new (struct wl_surface *surface); -CLUTTER_AVAILABLE_IN_1_10 -void clutter_wayland_surface_set_surface (ClutterWaylandSurface *self, - struct wl_surface *surface); -CLUTTER_AVAILABLE_IN_1_10 -struct wl_surface *clutter_wayland_surface_get_surface (ClutterWaylandSurface *self); -CLUTTER_AVAILABLE_IN_1_8 -gboolean clutter_wayland_surface_attach_buffer (ClutterWaylandSurface *self, - struct wl_resource *buffer, - GError **error); -CLUTTER_AVAILABLE_IN_1_8 -void clutter_wayland_surface_damage_buffer (ClutterWaylandSurface *self, - struct wl_resource *buffer, - gint32 x, - gint32 y, - gint32 width, - gint32 height); -CLUTTER_AVAILABLE_IN_1_10 -CoglTexture *clutter_wayland_surface_get_cogl_texture (ClutterWaylandSurface *self); - -G_END_DECLS - -#endif diff --git a/clutter/clutter/x11/clutter-backend-x11.c b/clutter/clutter/x11/clutter-backend-x11.c index 5ef9b06e0..c8cb880c8 100644 --- a/clutter/clutter/x11/clutter-backend-x11.c +++ b/clutter/clutter/x11/clutter-backend-x11.c @@ -19,9 +19,7 @@ * */ -#ifdef HAVE_CONFIG_H #include "clutter-build-config.h" -#endif #include @@ -36,28 +34,19 @@ #include #include "clutter-backend-x11.h" -#include "clutter-device-manager-core-x11.h" -#include "clutter-device-manager-xi2.h" #include "clutter-settings-x11.h" -#include "clutter-stage-x11.h" #include "clutter-x11.h" #include "xsettings/xsettings-common.h" -#if HAVE_XCOMPOSITE #include -#endif - -#if HAVE_XINPUT_2 #include -#endif #include #include #include "clutter-backend.h" #include "clutter-debug.h" -#include "clutter-device-manager-private.h" #include "clutter-event-private.h" #include "clutter-main.h" #include "clutter-private.h" @@ -96,7 +85,6 @@ static const gchar *atom_names[] = { "_NET_WM_PID", "_NET_WM_PING", "_NET_WM_STATE", - "_NET_WM_STATE_FULLSCREEN", "_NET_WM_USER_TIME", "WM_PROTOCOLS", "WM_DELETE_WINDOW", @@ -109,7 +97,6 @@ static const gchar *atom_names[] = { #define N_ATOM_NAMES G_N_ELEMENTS (atom_names) /* various flags corresponding to pre init setup calls */ -static gboolean _no_xevent_retrieval = FALSE; static gboolean clutter_enable_xinput = TRUE; static gboolean clutter_enable_argb = FALSE; static gboolean clutter_enable_stereo = FALSE; @@ -237,79 +224,6 @@ clutter_backend_x11_xsettings_notify (const char *name, g_object_thaw_notify (G_OBJECT (settings)); } -static void -clutter_backend_x11_create_device_manager (ClutterBackendX11 *backend_x11) -{ - ClutterEventTranslator *translator; - ClutterBackend *backend; - -#ifdef HAVE_XINPUT_2 - if (clutter_enable_xinput) - { - int event_base, first_event, first_error; - - if (XQueryExtension (backend_x11->xdpy, "XInputExtension", - &event_base, - &first_event, - &first_error)) - { - int major = 2; - int minor = 3; - - if (XIQueryVersion (backend_x11->xdpy, &major, &minor) != BadRequest) - { - CLUTTER_NOTE (BACKEND, "Creating XI2 device manager"); - backend_x11->has_xinput = TRUE; - backend_x11->device_manager = - g_object_new (CLUTTER_TYPE_DEVICE_MANAGER_XI2, - "backend", backend_x11, - "opcode", event_base, - NULL); - - backend_x11->xi_minor = minor; - } - } - } - - if (backend_x11->device_manager == NULL) -#endif /* HAVE_XINPUT_2 */ - { - CLUTTER_NOTE (BACKEND, "Creating Core device manager"); - backend_x11->has_xinput = FALSE; - backend_x11->device_manager = - g_object_new (CLUTTER_TYPE_DEVICE_MANAGER_X11, - "backend", backend_x11, - NULL); - - backend_x11->xi_minor = -1; - } - - backend = CLUTTER_BACKEND (backend_x11); - backend->device_manager = backend_x11->device_manager; - - translator = CLUTTER_EVENT_TRANSLATOR (backend_x11->device_manager); - _clutter_backend_add_event_translator (backend, translator); -} - -static void -clutter_backend_x11_create_keymap (ClutterBackendX11 *backend_x11) -{ - if (backend_x11->keymap == NULL) - { - ClutterEventTranslator *translator; - ClutterBackend *backend; - - backend_x11->keymap = - g_object_new (CLUTTER_TYPE_KEYMAP_X11, - "backend", backend_x11, - NULL); - - backend = CLUTTER_BACKEND (backend_x11); - translator = CLUTTER_EVENT_TRANSLATOR (backend_x11->keymap); - _clutter_backend_add_event_translator (backend, translator); - } -} - static gboolean clutter_backend_x11_pre_parse (ClutterBackend *backend, GError **error) @@ -348,9 +262,7 @@ clutter_backend_x11_post_parse (ClutterBackend *backend, GError **error) { ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend); - ClutterSettings *settings; Atom atoms[N_ATOM_NAMES]; - double dpi; if (_foreign_dpy) backend_x11->xdpy = _foreign_dpy; @@ -390,8 +302,6 @@ clutter_backend_x11_post_parse (ClutterBackend *backend, CLUTTER_NOTE (BACKEND, "Getting the X screen"); - settings = clutter_settings_get_default (); - /* add event filter for Cogl events */ clutter_x11_add_filter (cogl_xlib_filter, backend); @@ -410,11 +320,6 @@ clutter_backend_x11_post_parse (ClutterBackend *backend, backend_x11->display_name = g_strdup (clutter_display_name); - dpi = (((double) DisplayHeight (backend_x11->xdpy, backend_x11->xscreen_num) * 25.4) - / (double) DisplayHeightMM (backend_x11->xdpy, backend_x11->xscreen_num)); - - g_object_set (settings, "font-dpi", (int) dpi * 1024, NULL); - /* create XSETTINGS client */ backend_x11->xsettings = _clutter_xsettings_client_new (backend_x11->xdpy, @@ -436,16 +341,15 @@ clutter_backend_x11_post_parse (ClutterBackend *backend, backend_x11->atom_NET_WM_PID = atoms[0]; backend_x11->atom_NET_WM_PING = atoms[1]; backend_x11->atom_NET_WM_STATE = atoms[2]; - backend_x11->atom_NET_WM_STATE_FULLSCREEN = atoms[3]; - backend_x11->atom_NET_WM_USER_TIME = atoms[4]; - backend_x11->atom_WM_PROTOCOLS = atoms[5]; - backend_x11->atom_WM_DELETE_WINDOW = atoms[6]; - backend_x11->atom_XEMBED = atoms[7]; - backend_x11->atom_XEMBED_INFO = atoms[8]; - backend_x11->atom_NET_WM_NAME = atoms[9]; - backend_x11->atom_UTF8_STRING = atoms[10]; + backend_x11->atom_NET_WM_USER_TIME = atoms[3]; + backend_x11->atom_WM_PROTOCOLS = atoms[4]; + backend_x11->atom_WM_DELETE_WINDOW = atoms[5]; + backend_x11->atom_XEMBED = atoms[6]; + backend_x11->atom_XEMBED_INFO = atoms[7]; + backend_x11->atom_NET_WM_NAME = atoms[8]; + backend_x11->atom_UTF8_STRING = atoms[9]; - free (clutter_display_name); + g_free (clutter_display_name); CLUTTER_NOTE (BACKEND, "X Display '%s'[%p] opened (screen:%d, root:%u, dpi:%f)", @@ -458,48 +362,6 @@ clutter_backend_x11_post_parse (ClutterBackend *backend, return TRUE; } -void -_clutter_backend_x11_events_init (ClutterBackend *backend) -{ - ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend); - - CLUTTER_NOTE (EVENT, "initialising the event loop"); - - /* the event source is optional */ - if (!_no_xevent_retrieval) - { - GSource *source; - - source = _clutter_x11_event_source_new (backend_x11); - - /* default priority for events - * - * XXX - at some point we'll have a common EventSource API that - * is created by the backend, and this code will most likely go - * into the default implementation of ClutterBackend - */ - g_source_set_priority (source, CLUTTER_PRIORITY_EVENTS); - - /* attach the source to the default context, and transfer the - * ownership to the GMainContext itself - */ - g_source_attach (source, NULL); - g_source_unref (source); - - backend_x11->event_source = source; - } - - /* create the device manager; we need this because we can effectively - * choose between core+XI1 and XI2 input events - */ - clutter_backend_x11_create_device_manager (backend_x11); - - /* register keymap; unless we create a generic Keymap object, I'm - * afraid this will have to stay - */ - clutter_backend_x11_create_keymap (backend_x11); -} - static const GOptionEntry entries[] = { { @@ -519,14 +381,12 @@ static const GOptionEntry entries[] = G_OPTION_ARG_NONE, &clutter_synchronise, N_("Make X calls synchronous"), NULL }, -#ifdef HAVE_XINPUT_2 { "disable-xinput", 0, G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &clutter_enable_xinput, N_("Disable XInput support"), NULL }, -#endif /* HAVE_XINPUT_2 */ { NULL } }; @@ -542,7 +402,7 @@ clutter_backend_x11_finalize (GObject *gobject) { ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (gobject); - free (backend_x11->display_name); + g_free (backend_x11->display_name); clutter_x11_remove_filter (cogl_xlib_filter, gobject); @@ -563,8 +423,7 @@ clutter_backend_x11_dispose (GObject *gobject) static ClutterFeatureFlags clutter_backend_x11_get_features (ClutterBackend *backend) { - ClutterFeatureFlags flags = CLUTTER_FEATURE_STAGE_USER_RESIZE - | CLUTTER_FEATURE_STAGE_CURSOR; + ClutterFeatureFlags flags = CLUTTER_FEATURE_STAGE_CURSOR; flags |= CLUTTER_BACKEND_CLASS (clutter_backend_x11_parent_class)->get_features (backend); @@ -622,7 +481,6 @@ clutter_backend_x11_translate_event (ClutterBackend *backend, ClutterEvent *event) { ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend); - ClutterBackendClass *parent_class; XEvent *xevent = native; /* X11 filter functions have a higher priority */ @@ -658,11 +516,7 @@ clutter_backend_x11_translate_event (ClutterBackend *backend, */ update_last_event_time (backend_x11, xevent); - /* chain up to the parent implementation, which will handle - * event translators - */ - parent_class = CLUTTER_BACKEND_CLASS (clutter_backend_x11_parent_class); - return parent_class->translate_event (backend, native, event); + return FALSE; } static CoglRenderer * @@ -689,8 +543,8 @@ static gboolean check_onscreen_template (CoglRenderer *renderer, CoglSwapChain *swap_chain, CoglOnscreenTemplate *onscreen_template, - CoglBool enable_argb, - CoglBool enable_stereo, + gboolean enable_argb, + gboolean enable_stereo, GError **error) { GError *internal_error = NULL; @@ -782,42 +636,6 @@ clutter_backend_x11_get_display (ClutterBackend *backend, return display; } -static ClutterStageWindow * -clutter_backend_x11_create_stage (ClutterBackend *backend, - ClutterStage *wrapper, - GError **error) -{ - ClutterEventTranslator *translator; - ClutterStageWindow *stage; - - stage = g_object_new (CLUTTER_TYPE_STAGE_X11, - "backend", backend, - "wrapper", wrapper, - NULL); - - /* the X11 stage does event translation */ - translator = CLUTTER_EVENT_TRANSLATOR (stage); - _clutter_backend_add_event_translator (backend, translator); - - CLUTTER_NOTE (BACKEND, "X11 stage created (display:%p, screen:%d, root:%u)", - CLUTTER_BACKEND_X11 (backend)->xdpy, - CLUTTER_BACKEND_X11 (backend)->xscreen_num, - (unsigned int) CLUTTER_BACKEND_X11 (backend)->xwin_root); - - return stage; -} - -static PangoDirection -clutter_backend_x11_get_keymap_direction (ClutterBackend *backend) -{ - ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend); - - if (G_UNLIKELY (backend_x11->keymap == NULL)) - return PANGO_DIRECTION_NEUTRAL; - - return _clutter_keymap_x11_get_direction (backend_x11->keymap); -} - static void clutter_backend_x11_class_init (ClutterBackendX11Class *klass) { @@ -827,8 +645,6 @@ clutter_backend_x11_class_init (ClutterBackendX11Class *klass) gobject_class->dispose = clutter_backend_x11_dispose; gobject_class->finalize = clutter_backend_x11_finalize; - backend_class->create_stage = clutter_backend_x11_create_stage; - backend_class->pre_parse = clutter_backend_x11_pre_parse; backend_class->post_parse = clutter_backend_x11_post_parse; backend_class->add_options = clutter_backend_x11_add_options; @@ -838,8 +654,6 @@ clutter_backend_x11_class_init (ClutterBackendX11Class *klass) backend_class->get_renderer = clutter_backend_x11_get_renderer; backend_class->get_display = clutter_backend_x11_get_display; - - backend_class->get_keymap_direction = clutter_backend_x11_get_keymap_direction; } static void @@ -950,82 +764,6 @@ clutter_x11_set_display (Display *xdpy) _foreign_dpy= xdpy; } -/** - * clutter_x11_enable_xinput: - * - * Enables the use of the XInput extension if present on connected - * XServer and support built into Clutter. XInput allows for multiple - * pointing devices to be used. - * - * This function must be called before clutter_init(). - * - * Since XInput might not be supported by the X server, you might - * want to use clutter_x11_has_xinput() to see if support was enabled. - * - * Since: 0.8 - * - * Deprecated: 1.14: This function does not do anything; XInput support - * is enabled by default in Clutter. Use the CLUTTER_DISABLE_XINPUT - * environment variable to disable XInput support and use Xlib core - * events instead. - */ -void -clutter_x11_enable_xinput (void) -{ -} - -/** - * clutter_x11_disable_event_retrieval: - * - * Disables the internal polling of X11 events in the main loop. - * - * Libraries or applications calling this function will be responsible of - * polling all X11 events. - * - * You also must call clutter_x11_handle_event() to let Clutter process - * events and maintain its internal state. - * - * This function can only be called before calling clutter_init(). - * - * Even with event handling disabled, Clutter will still select - * all the events required to maintain its internal state on the stage - * Window; compositors using Clutter and input regions to pass events - * through to application windows should not rely on an empty input - * region, and should instead clear it themselves explicitly using the - * XFixes extension. - * - * This function should not be normally used by applications. - * - * Since: 0.8 - */ -void -clutter_x11_disable_event_retrieval (void) -{ - if (_clutter_context_is_initialized ()) - { - g_warning ("%s() can only be used before calling clutter_init()", - G_STRFUNC); - return; - } - - _no_xevent_retrieval = TRUE; -} - -/** - * clutter_x11_has_event_retrieval: - * - * Queries the X11 backend to check if event collection has been disabled. - * - * Return value: TRUE if event retrival has been disabled. FALSE otherwise. - * - * Since: 0.8 - */ -gboolean -clutter_x11_has_event_retrieval (void) -{ - return !_no_xevent_retrieval; -} - /** * clutter_x11_get_default_screen: * @@ -1175,72 +913,13 @@ clutter_x11_remove_filter (ClutterX11FilterFunc func, g_slist_remove_link (backend_x11->event_filters, this); g_slist_free_1 (this); - free (filter); + g_free (filter); return; } } } -/** - * clutter_x11_get_input_devices: - * - * Retrieves a pointer to the list of input devices - * - * Deprecated: 1.2: Use clutter_device_manager_peek_devices() instead - * - * Since: 0.8 - * - * Return value: (transfer none) (element-type Clutter.InputDevice): a - * pointer to the internal list of input devices; the returned list is - * owned by Clutter and should not be modified or freed - */ -const GSList * -clutter_x11_get_input_devices (void) -{ - ClutterDeviceManager *manager; - - manager = clutter_device_manager_get_default (); - if (manager == NULL) - return NULL; - - return clutter_device_manager_peek_devices (manager); -} - -/** - * clutter_x11_has_xinput: - * - * Gets whether Clutter has XInput support. - * - * Return value: %TRUE if Clutter was compiled with XInput support - * and XInput support is available at run time. - * - * Since: 0.8 - */ -gboolean -clutter_x11_has_xinput (void) -{ -#ifdef HAVE_XINPUT_2 - ClutterBackend *backend = clutter_get_default_backend (); - - if (backend == NULL) - { - g_critical ("The Clutter backend has not been initialised"); - return FALSE; - } - - if (!CLUTTER_IS_BACKEND_X11 (backend)) - { - g_critical ("The Clutter backend is not a X11 backend."); - return FALSE; - } - - return CLUTTER_BACKEND_X11 (backend)->has_xinput; -#else - return FALSE; -#endif -} - /** * clutter_x11_has_composite_extension: * @@ -1252,7 +931,6 @@ clutter_x11_has_xinput (void) gboolean clutter_x11_has_composite_extension (void) { -#if HAVE_XCOMPOSITE static gboolean have_composite = FALSE, done_check = FALSE; int error = 0, event = 0; Display *dpy; @@ -1283,9 +961,6 @@ clutter_x11_has_composite_extension (void) done_check = TRUE; return have_composite; -#else - return FALSE; -#endif /* HAVE_XCOMPOSITE */ } /** @@ -1392,84 +1067,3 @@ clutter_x11_get_use_stereo_stage (void) return clutter_enable_stereo; } -XVisualInfo * -_clutter_backend_x11_get_visual_info (ClutterBackendX11 *backend_x11) -{ - return cogl_clutter_winsys_xlib_get_visual_info (); -} - -/** - * clutter_x11_get_visual_info: (skip) - * - * Retrieves the `XVisualInfo` used by the Clutter X11 backend. - * - * Return value: (transfer full): a `XVisualInfo`, or `None`. - * The returned value should be freed using `XFree()` when done - * - * Since: 1.2 - */ -XVisualInfo * -clutter_x11_get_visual_info (void) -{ - ClutterBackendX11 *backend_x11; - ClutterBackend *backend; - - backend = clutter_get_default_backend (); - if (!CLUTTER_IS_BACKEND_X11 (backend)) - { - g_critical ("The Clutter backend is not a X11 backend."); - return NULL; - } - - backend_x11 = CLUTTER_BACKEND_X11 (backend); - - return _clutter_backend_x11_get_visual_info (backend_x11); -} - -gboolean -_clutter_x11_input_device_translate_screen_coord (ClutterInputDevice *device, - gint stage_root_x, - gint stage_root_y, - guint index_, - gdouble value, - gdouble *axis_value) -{ - ClutterAxisInfo *info; - ClutterBackendX11 *backend_x11; - gdouble width, scale, offset; - - backend_x11 = CLUTTER_BACKEND_X11 (device->backend); - - if (device->axes == NULL || index_ >= device->axes->len) - return FALSE; - - info = &g_array_index (device->axes, ClutterAxisInfo, index_); - if (!(info->axis == CLUTTER_INPUT_AXIS_X || info->axis == CLUTTER_INPUT_AXIS_Y)) - return FALSE; - - width = info->max_value - info->min_value; - - if (info->axis == CLUTTER_INPUT_AXIS_X) - { - if (width > 0) - scale = backend_x11->xscreen_width / width; - else - scale = 1; - - offset = - stage_root_x; - } - else - { - if (width > 0) - scale = backend_x11->xscreen_height / width; - else - scale = 1; - - offset = - stage_root_y; - } - - if (axis_value) - *axis_value = offset + scale * (value - info->min_value); - - return TRUE; -} diff --git a/clutter/clutter/x11/clutter-backend-x11.h b/clutter/clutter/x11/clutter-backend-x11.h index a687b139e..d08c5409d 100644 --- a/clutter/clutter/x11/clutter-backend-x11.h +++ b/clutter/clutter/x11/clutter-backend-x11.h @@ -30,7 +30,6 @@ #include "clutter-x11.h" #include "clutter-backend-private.h" -#include "clutter-keymap-x11.h" #include "xsettings/xsettings-client.h" @@ -45,7 +44,6 @@ G_BEGIN_DECLS typedef struct _ClutterBackendX11 ClutterBackendX11; typedef struct _ClutterBackendX11Class ClutterBackendX11Class; -typedef struct _ClutterEventX11 ClutterEventX11; typedef struct _ClutterX11EventFilter ClutterX11EventFilter; G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBackendX11, g_object_unref) @@ -57,16 +55,6 @@ struct _ClutterX11EventFilter }; -struct _ClutterEventX11 -{ - /* additional fields for Key events */ - gint key_group; - - guint key_is_modifier : 1; - guint num_lock_set : 1; - guint caps_lock_set : 1; -}; - struct _ClutterBackendX11 { ClutterBackend parent_instance; @@ -82,14 +70,12 @@ struct _ClutterBackendX11 Window xwin_root; /* event source */ - GSource *event_source; GSList *event_filters; /* props */ Atom atom_NET_WM_PID; Atom atom_NET_WM_PING; Atom atom_NET_WM_STATE; - Atom atom_NET_WM_STATE_FULLSCREEN; Atom atom_NET_WM_USER_TIME; Atom atom_WM_PROTOCOLS; Atom atom_WM_DELETE_WINDOW; @@ -100,17 +86,8 @@ struct _ClutterBackendX11 Time last_event_time; - ClutterDeviceManager *device_manager; - gboolean has_xinput; - int xi_minor; - XSettingsClient *xsettings; Window xsettings_xwin; - - ClutterKeymapX11 *keymap; - gboolean use_xkb; - gboolean have_xkb_autorepeat; - guint keymap_serial; }; struct _ClutterBackendX11Class @@ -118,31 +95,14 @@ struct _ClutterBackendX11Class ClutterBackendClass parent_class; }; -CLUTTER_AVAILABLE_IN_MUFFIN +CLUTTER_EXPORT GType clutter_backend_x11_get_type (void) G_GNUC_CONST; ClutterBackend *clutter_backend_x11_new (void); -void _clutter_backend_x11_events_init (ClutterBackend *backend); - -GSource * _clutter_x11_event_source_new (ClutterBackendX11 *backend_x11); - /* Private to glx/eglx backends */ -XVisualInfo * _clutter_backend_x11_get_visual_info (ClutterBackendX11 *backend_x11); - void _clutter_x11_select_events (Window xwin); -ClutterEventX11 * _clutter_event_x11_new (void); -ClutterEventX11 * _clutter_event_x11_copy (ClutterEventX11 *event_x11); -void _clutter_event_x11_free (ClutterEventX11 *event_x11); - -gboolean _clutter_x11_input_device_translate_screen_coord (ClutterInputDevice *device, - gint stage_root_x, - gint stage_root_y, - guint index_, - gdouble value, - gdouble *axis_value); - G_END_DECLS #endif /* __CLUTTER_BACKEND_X11_H__ */ diff --git a/clutter/clutter/x11/clutter-device-manager-core-x11.c b/clutter/clutter/x11/clutter-device-manager-core-x11.c deleted file mode 100644 index 34178c1ad..000000000 --- a/clutter/clutter/x11/clutter-device-manager-core-x11.c +++ /dev/null @@ -1,555 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright © 2009, 2010, 2011 Intel Corp. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Emmanuele Bassi - */ - -#include "clutter-build-config.h" - -#include "clutter-device-manager-core-x11.h" - -#include "clutter-backend-x11.h" -#include "clutter-input-device-core-x11.h" -#include "clutter-stage-x11.h" -#include "clutter-virtual-input-device-x11.h" - -#include "clutter-backend.h" -#include "clutter-debug.h" -#include "clutter-device-manager-private.h" -#include "clutter-event-private.h" -#include "clutter-event-translator.h" -#include "clutter-stage-private.h" -#include "clutter-private.h" -#include "clutter-xkb-a11y-x11.h" - -enum -{ - PROP_0, - - PROP_EVENT_BASE, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST] = { NULL, }; - -static void clutter_event_translator_iface_init (ClutterEventTranslatorIface *iface); - -#define clutter_device_manager_x11_get_type _clutter_device_manager_x11_get_type - -G_DEFINE_TYPE_WITH_CODE (ClutterDeviceManagerX11, - clutter_device_manager_x11, - CLUTTER_TYPE_DEVICE_MANAGER, - G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_EVENT_TRANSLATOR, - clutter_event_translator_iface_init)); - -static inline void -translate_key_event (ClutterBackendX11 *backend_x11, - ClutterDeviceManagerX11 *manager_x11, - ClutterEvent *event, - XEvent *xevent) -{ - ClutterEventX11 *event_x11; - char buffer[256 + 1]; - int n; - - event->key.type = xevent->xany.type == KeyPress ? CLUTTER_KEY_PRESS - : CLUTTER_KEY_RELEASE; - event->key.time = xevent->xkey.time; - - clutter_event_set_device (event, manager_x11->core_keyboard); - - /* KeyEvents have platform specific data associated to them */ - event_x11 = _clutter_event_x11_new (); - _clutter_event_set_platform_data (event, event_x11); - - event->key.modifier_state = (ClutterModifierType) xevent->xkey.state; - event->key.hardware_keycode = xevent->xkey.keycode; - - /* keyval is the key ignoring all modifiers ('1' vs. '!') */ - event->key.keyval = - _clutter_keymap_x11_translate_key_state (backend_x11->keymap, - event->key.hardware_keycode, - &event->key.modifier_state, - NULL); - - event_x11->key_group = - _clutter_keymap_x11_get_key_group (backend_x11->keymap, - event->key.modifier_state); - event_x11->key_is_modifier = - _clutter_keymap_x11_get_is_modifier (backend_x11->keymap, - event->key.hardware_keycode); - event_x11->num_lock_set = - _clutter_keymap_x11_get_num_lock_state (backend_x11->keymap); - event_x11->caps_lock_set = - _clutter_keymap_x11_get_caps_lock_state (backend_x11->keymap); - - /* unicode_value is the printable representation */ - n = XLookupString (&xevent->xkey, buffer, sizeof (buffer) - 1, NULL, NULL); - - if (n != NoSymbol) - { - event->key.unicode_value = g_utf8_get_char_validated (buffer, n); - if ((event->key.unicode_value != (gunichar) -1) && - (event->key.unicode_value != (gunichar) -2)) - goto out; - } - else - event->key.unicode_value = (gunichar)'\0'; - -out: - CLUTTER_NOTE (EVENT, - "%s: win:0x%x, key: %12s (%d)", - event->any.type == CLUTTER_KEY_PRESS - ? "key press " - : "key release", - (unsigned int) xevent->xkey.window, - event->key.keyval ? buffer : "(none)", - event->key.keyval); - return; -} - -static ClutterTranslateReturn -clutter_device_manager_x11_translate_event (ClutterEventTranslator *translator, - gpointer native, - ClutterEvent *event) -{ - ClutterDeviceManagerX11 *manager_x11; - ClutterBackendX11 *backend_x11; - ClutterStageX11 *stage_x11; - ClutterTranslateReturn res; - ClutterStage *stage; - XEvent *xevent; - - manager_x11 = CLUTTER_DEVICE_MANAGER_X11 (translator); - backend_x11 = CLUTTER_BACKEND_X11 (clutter_get_default_backend ()); - - xevent = native; - - stage = clutter_x11_get_stage_from_window (xevent->xany.window); - if (stage == NULL) - return CLUTTER_TRANSLATE_CONTINUE; - - if (CLUTTER_ACTOR_IN_DESTRUCTION (stage)) - return CLUTTER_TRANSLATE_CONTINUE; - - stage_x11 = CLUTTER_STAGE_X11 (_clutter_stage_get_window (stage)); - - event->any.stage = stage; - - res = CLUTTER_TRANSLATE_CONTINUE; - - switch (xevent->type) - { - case KeyPress: - translate_key_event (backend_x11, manager_x11, event, xevent); - _clutter_stage_x11_set_user_time (stage_x11, xevent->xkey.time); - res = CLUTTER_TRANSLATE_QUEUE; - break; - - case KeyRelease: - /* old-style X11 terminals require that even modern X11 send - * KeyPress/KeyRelease pairs when auto-repeating. for this - * reason modern(-ish) API like XKB has a way to detect - * auto-repeat and do a single KeyRelease at the end of a - * KeyPress sequence. - * - * this check emulates XKB's detectable auto-repeat; we peek - * the next event and check if it's a KeyPress for the same key - * and timestamp - and then ignore it if it matches the - * KeyRelease - * - * if we have XKB, and autorepeat is enabled, then this becomes - * a no-op - */ - if (!backend_x11->have_xkb_autorepeat && XPending (xevent->xkey.display)) - { - XEvent next_event; - - XPeekEvent (xevent->xkey.display, &next_event); - - if (next_event.type == KeyPress && - next_event.xkey.keycode == xevent->xkey.keycode && - next_event.xkey.time == xevent->xkey.time) - { - res = CLUTTER_TRANSLATE_REMOVE; - break; - } - } - - translate_key_event (backend_x11, manager_x11, event, xevent); - res = CLUTTER_TRANSLATE_QUEUE; - break; - - case ButtonPress: - CLUTTER_NOTE (EVENT, - "button press: win: 0x%x, coords: %d, %d, button: %d", - (unsigned int) stage_x11->xwin, - xevent->xbutton.x, - xevent->xbutton.y, - xevent->xbutton.button); - - switch (xevent->xbutton.button) - { - case 4: /* up */ - case 5: /* down */ - case 6: /* left */ - case 7: /* right */ - event->scroll.type = CLUTTER_SCROLL; - - if (xevent->xbutton.button == 4) - event->scroll.direction = CLUTTER_SCROLL_UP; - else if (xevent->xbutton.button == 5) - event->scroll.direction = CLUTTER_SCROLL_DOWN; - else if (xevent->xbutton.button == 6) - event->scroll.direction = CLUTTER_SCROLL_LEFT; - else - event->scroll.direction = CLUTTER_SCROLL_RIGHT; - - event->scroll.time = xevent->xbutton.time; - event->scroll.x = xevent->xbutton.x; - event->scroll.y = xevent->xbutton.y; - event->scroll.modifier_state = xevent->xbutton.state; - event->scroll.axes = NULL; - break; - - default: - event->button.type = event->type = CLUTTER_BUTTON_PRESS; - event->button.time = xevent->xbutton.time; - event->button.x = xevent->xbutton.x; - event->button.y = xevent->xbutton.y; - event->button.modifier_state = xevent->xbutton.state; - event->button.button = xevent->xbutton.button; - event->button.axes = NULL; - break; - } - - clutter_event_set_device (event, manager_x11->core_pointer); - - _clutter_stage_x11_set_user_time (stage_x11, xevent->xbutton.time); - res = CLUTTER_TRANSLATE_QUEUE; - break; - - case ButtonRelease: - CLUTTER_NOTE (EVENT, - "button press: win: 0x%x, coords: %d, %d, button: %d", - (unsigned int) stage_x11->xwin, - xevent->xbutton.x, - xevent->xbutton.y, - xevent->xbutton.button); - - /* scroll events don't have a corresponding release */ - if (xevent->xbutton.button == 4 || - xevent->xbutton.button == 5 || - xevent->xbutton.button == 6 || - xevent->xbutton.button == 7) - { - res = CLUTTER_TRANSLATE_REMOVE; - break; - } - - event->button.type = event->type = CLUTTER_BUTTON_RELEASE; - event->button.time = xevent->xbutton.time; - event->button.x = xevent->xbutton.x; - event->button.y = xevent->xbutton.y; - event->button.modifier_state = xevent->xbutton.state; - event->button.button = xevent->xbutton.button; - event->button.axes = NULL; - clutter_event_set_device (event, manager_x11->core_pointer); - res = CLUTTER_TRANSLATE_QUEUE; - break; - - case MotionNotify: - CLUTTER_NOTE (EVENT, - "motion: win: 0x%x, coords: %d, %d", - (unsigned int) stage_x11->xwin, - xevent->xmotion.x, - xevent->xmotion.y); - - event->motion.type = event->type = CLUTTER_MOTION; - event->motion.time = xevent->xmotion.time; - event->motion.x = xevent->xmotion.x; - event->motion.y = xevent->xmotion.y; - event->motion.modifier_state = xevent->xmotion.state; - event->motion.axes = NULL; - clutter_event_set_device (event, manager_x11->core_pointer); - res = CLUTTER_TRANSLATE_QUEUE; - break; - - case EnterNotify: - CLUTTER_NOTE (EVENT, "Entering the stage (time:%u)", - (unsigned int) xevent->xcrossing.time); - - event->crossing.type = CLUTTER_ENTER; - event->crossing.time = xevent->xcrossing.time; - event->crossing.x = xevent->xcrossing.x; - event->crossing.y = xevent->xcrossing.y; - event->crossing.source = CLUTTER_ACTOR (stage); - event->crossing.related = NULL; - clutter_event_set_device (event, manager_x11->core_pointer); - - _clutter_input_device_set_stage (manager_x11->core_pointer, stage); - - res = CLUTTER_TRANSLATE_QUEUE; - break; - - case LeaveNotify: - if (manager_x11->core_pointer->stage == NULL) - { - CLUTTER_NOTE (EVENT, "Discarding LeaveNotify for " - "ButtonRelease event off-stage"); - res = CLUTTER_TRANSLATE_REMOVE; - break; - } - - /* we know that we are leaving the stage here */ - CLUTTER_NOTE (EVENT, "Leaving the stage (time:%u)", - (unsigned int) xevent->xcrossing.time); - - event->crossing.type = CLUTTER_LEAVE; - event->crossing.time = xevent->xcrossing.time; - event->crossing.x = xevent->xcrossing.x; - event->crossing.y = xevent->xcrossing.y; - event->crossing.source = CLUTTER_ACTOR (stage); - event->crossing.related = NULL; - clutter_event_set_device (event, manager_x11->core_pointer); - - _clutter_input_device_set_stage (manager_x11->core_pointer, NULL); - - res = CLUTTER_TRANSLATE_QUEUE; - break; - - default: - break; - } - - return res; -} - -static void -clutter_event_translator_iface_init (ClutterEventTranslatorIface *iface) -{ - iface->translate_event = clutter_device_manager_x11_translate_event; -} - -static void -clutter_device_manager_x11_constructed (GObject *gobject) -{ - ClutterDeviceManagerX11 *manager_x11; - ClutterDeviceManager *manager; - ClutterBackendX11 *backend_x11; - - manager_x11 = CLUTTER_DEVICE_MANAGER_X11 (gobject); - manager = CLUTTER_DEVICE_MANAGER (gobject); - - g_object_get (gobject, "backend", &backend_x11, NULL); - g_assert (backend_x11 != NULL); - - manager_x11->core_pointer = - g_object_new (CLUTTER_TYPE_INPUT_DEVICE_X11, - "name", "Core Pointer", - "has-cursor", TRUE, - "device-type", CLUTTER_POINTER_DEVICE, - "device-manager", manager_x11, - "device-mode", CLUTTER_INPUT_MODE_MASTER, - "backend", backend_x11, - "enabled", TRUE, - NULL); - CLUTTER_NOTE (BACKEND, "Added core pointer device"); - - manager_x11->core_keyboard = - g_object_new (CLUTTER_TYPE_INPUT_DEVICE_X11, - "name", "Core Keyboard", - "has-cursor", FALSE, - "device-type", CLUTTER_KEYBOARD_DEVICE, - "device-manager", manager_x11, - "device-mode", CLUTTER_INPUT_MODE_MASTER, - "backend", backend_x11, - "enabled", TRUE, - NULL); - CLUTTER_NOTE (BACKEND, "Added core keyboard device"); - - /* associate core devices */ - _clutter_input_device_set_associated_device (manager_x11->core_pointer, - manager_x11->core_keyboard); - _clutter_input_device_set_associated_device (manager_x11->core_keyboard, - manager_x11->core_pointer); - - clutter_device_manager_x11_a11y_init (manager); - - if (G_OBJECT_CLASS (clutter_device_manager_x11_parent_class)->constructed) - G_OBJECT_CLASS (clutter_device_manager_x11_parent_class)->constructed (gobject); -} - -static void -clutter_device_manager_x11_add_device (ClutterDeviceManager *manager, - ClutterInputDevice *device) -{ - ClutterDeviceManagerX11 *manager_x11 = CLUTTER_DEVICE_MANAGER_X11 (manager); - - manager_x11->devices = g_slist_prepend (manager_x11->devices, device); - g_hash_table_replace (manager_x11->devices_by_id, - GINT_TO_POINTER (device->id), - device); - - /* blow the cache */ - g_slist_free (manager_x11->all_devices); - manager_x11->all_devices = NULL; -} - -static void -clutter_device_manager_x11_remove_device (ClutterDeviceManager *manager, - ClutterInputDevice *device) -{ - ClutterDeviceManagerX11 *manager_x11 = CLUTTER_DEVICE_MANAGER_X11 (manager); - - g_hash_table_remove (manager_x11->devices_by_id, - GINT_TO_POINTER (device->id)); - manager_x11->devices = g_slist_remove (manager_x11->devices, device); - - /* blow the cache */ - g_slist_free (manager_x11->all_devices); - manager_x11->all_devices = NULL; -} - -static const GSList * -clutter_device_manager_x11_get_devices (ClutterDeviceManager *manager) -{ - ClutterDeviceManagerX11 *manager_x11 = CLUTTER_DEVICE_MANAGER_X11 (manager); - - /* cache the devices list so that we can keep the core pointer - * and keyboard outside of the ManagerX11:devices list - */ - if (manager_x11->all_devices == NULL) - { - GSList *all_devices = manager_x11->devices; - - all_devices = g_slist_prepend (all_devices, manager_x11->core_keyboard); - all_devices = g_slist_prepend (all_devices, manager_x11->core_pointer); - - manager_x11->all_devices = all_devices; - } - - return CLUTTER_DEVICE_MANAGER_X11 (manager)->all_devices; -} - -static ClutterInputDevice * -clutter_device_manager_x11_get_core_device (ClutterDeviceManager *manager, - ClutterInputDeviceType type) -{ - ClutterDeviceManagerX11 *manager_x11; - - manager_x11 = CLUTTER_DEVICE_MANAGER_X11 (manager); - - switch (type) - { - case CLUTTER_POINTER_DEVICE: - return manager_x11->core_pointer; - - case CLUTTER_KEYBOARD_DEVICE: - return manager_x11->core_keyboard; - - default: - return NULL; - } - - return NULL; -} - -static ClutterInputDevice * -clutter_device_manager_x11_get_device (ClutterDeviceManager *manager, - gint id) -{ - ClutterDeviceManagerX11 *manager_x11 = CLUTTER_DEVICE_MANAGER_X11 (manager); - - return g_hash_table_lookup (manager_x11->devices_by_id, - GINT_TO_POINTER (id)); -} - -static ClutterVirtualInputDevice * -clutter_device_manager_x11_create_virtual_device (ClutterDeviceManager *device_manager, - ClutterInputDeviceType device_type) -{ - return g_object_new (CLUTTER_TYPE_VIRTUAL_INPUT_DEVICE_X11, NULL); -} - -static ClutterVirtualDeviceType -clutter_device_manager_x11_get_supported_virtual_device_types (ClutterDeviceManager *device_manager) -{ - return (CLUTTER_VIRTUAL_DEVICE_TYPE_KEYBOARD | - CLUTTER_VIRTUAL_DEVICE_TYPE_POINTER); -} - -static void -clutter_device_manager_x11_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterDeviceManagerX11 *manager_x11 = CLUTTER_DEVICE_MANAGER_X11 (gobject); - - switch (prop_id) - { - case PROP_EVENT_BASE: - manager_x11->xi_event_base = g_value_get_int (value); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_device_manager_x11_class_init (ClutterDeviceManagerX11Class *klass) -{ - ClutterDeviceManagerClass *manager_class; - GObjectClass *gobject_class; - - obj_props[PROP_EVENT_BASE] = - g_param_spec_int ("event-base", - "Event Base", - "The first XI event", - -1, G_MAXINT, - -1, - CLUTTER_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY); - - gobject_class = G_OBJECT_CLASS (klass); - gobject_class->constructed = clutter_device_manager_x11_constructed; - gobject_class->set_property = clutter_device_manager_x11_set_property; - - g_object_class_install_properties (gobject_class, PROP_LAST, obj_props); - - manager_class = CLUTTER_DEVICE_MANAGER_CLASS (klass); - manager_class->add_device = clutter_device_manager_x11_add_device; - manager_class->remove_device = clutter_device_manager_x11_remove_device; - manager_class->get_devices = clutter_device_manager_x11_get_devices; - manager_class->get_core_device = clutter_device_manager_x11_get_core_device; - manager_class->get_device = clutter_device_manager_x11_get_device; - manager_class->create_virtual_device = clutter_device_manager_x11_create_virtual_device; - manager_class->get_supported_virtual_device_types = clutter_device_manager_x11_get_supported_virtual_device_types; - manager_class->apply_kbd_a11y_settings = clutter_device_manager_x11_apply_kbd_a11y_settings; -} - -static void -clutter_device_manager_x11_init (ClutterDeviceManagerX11 *self) -{ - self->devices_by_id = g_hash_table_new (NULL, NULL); -} diff --git a/clutter/clutter/x11/clutter-device-manager-core-x11.h b/clutter/clutter/x11/clutter-device-manager-core-x11.h deleted file mode 100644 index f0f28bc17..000000000 --- a/clutter/clutter/x11/clutter-device-manager-core-x11.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright © 2009, 2010, 2011 Intel Corp. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Emmanuele Bassi - */ - -#ifndef __CLUTTER_DEVICE_MANAGER_X11_H__ -#define __CLUTTER_DEVICE_MANAGER_X11_H__ - -#include - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_DEVICE_MANAGER_X11 (_clutter_device_manager_x11_get_type ()) -#define CLUTTER_DEVICE_MANAGER_X11(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_DEVICE_MANAGER_X11, ClutterDeviceManagerX11)) -#define CLUTTER_IS_DEVICE_MANAGER_X11(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_DEVICE_MANAGER_X11)) -#define CLUTTER_DEVICE_MANAGER_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_DEVICE_MANAGER_X11, ClutterDeviceManagerX11Class)) -#define CLUTTER_IS_DEVICE_MANAGER_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_DEVICE_MANAGER_X11)) -#define CLUTTER_DEVICE_MANAGER_X11_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_DEVICE_MANAGER_X11, ClutterDeviceManagerX11Class)) - -typedef struct _ClutterDeviceManagerX11 ClutterDeviceManagerX11; -typedef struct _ClutterDeviceManagerX11Class ClutterDeviceManagerX11Class; - -struct _ClutterDeviceManagerX11 -{ - ClutterDeviceManager parent_instance; - - GHashTable *devices_by_id; - - /* the list of transient devices */ - GSList *devices; - - /* the list of all devices, transient and core; this can be - * NULL-ified when adding or removing devices - */ - GSList *all_devices; - - ClutterInputDevice *core_pointer; - ClutterInputDevice *core_keyboard; - - int xi_event_base; -}; - -struct _ClutterDeviceManagerX11Class -{ - ClutterDeviceManagerClass parent_class; -}; - -GType _clutter_device_manager_x11_get_type (void) G_GNUC_CONST; - -G_END_DECLS - -#endif /* __CLUTTER_DEVICE_MANAGER_X11_H__ */ diff --git a/clutter/clutter/x11/clutter-device-manager-xi2.h b/clutter/clutter/x11/clutter-device-manager-xi2.h deleted file mode 100644 index be2575975..000000000 --- a/clutter/clutter/x11/clutter-device-manager-xi2.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright © 2011 Intel Corp. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Emmanuele Bassi - */ - -#ifndef __CLUTTER_DEVICE_MANAGER_XI2_H__ -#define __CLUTTER_DEVICE_MANAGER_XI2_H__ - -#include - -#ifdef HAVE_LIBWACOM -#include -#endif - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_DEVICE_MANAGER_XI2 (_clutter_device_manager_xi2_get_type ()) -#define CLUTTER_DEVICE_MANAGER_XI2(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_DEVICE_MANAGER_XI2, ClutterDeviceManagerXI2)) -#define CLUTTER_IS_DEVICE_MANAGER_XI2(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_DEVICE_MANAGER_XI2)) -#define CLUTTER_DEVICE_MANAGER_XI2_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_DEVICE_MANAGER_XI2, ClutterDeviceManagerXI2Class)) -#define CLUTTER_IS_DEVICE_MANAGER_XI2_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_DEVICE_MANAGER_XI2)) -#define CLUTTER_DEVICE_MANAGER_XI2_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_DEVICE_MANAGER_XI2, ClutterDeviceManagerXI2Class)) - -typedef struct _ClutterDeviceManagerXI2 ClutterDeviceManagerXI2; -typedef struct _ClutterDeviceManagerXI2Class ClutterDeviceManagerXI2Class; - -struct _ClutterDeviceManagerXI2 -{ - ClutterDeviceManager parent_instance; - - GHashTable *devices_by_id; - GHashTable *tools_by_serial; - - GSList *all_devices; - - GList *master_devices; - GList *slave_devices; - - int opcode; - -#ifdef HAVE_LIBWACOM - WacomDeviceDatabase *wacom_db; -#endif -}; - -struct _ClutterDeviceManagerXI2Class -{ - ClutterDeviceManagerClass parent_class; -}; - -GType _clutter_device_manager_xi2_get_type (void) G_GNUC_CONST; - -G_END_DECLS - -#endif /* __CLUTTER_DEVICE_MANAGER_XI2_H__ */ diff --git a/clutter/clutter/x11/clutter-event-x11.c b/clutter/clutter/x11/clutter-event-x11.c deleted file mode 100644 index 28074a1e3..000000000 --- a/clutter/clutter/x11/clutter-event-x11.c +++ /dev/null @@ -1,394 +0,0 @@ -/* Clutter. - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2006, 2007, 2008 OpenedHand Ltd - * Copyright (C) 2009, 2010 Intel Corp. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - * - * Authored by: - * Matthew Allum - * Emmanuele Bassi - */ - -#include "clutter-build-config.h" - -#include "clutter-backend-x11.h" -#include "clutter-x11.h" - -#include "clutter-backend-private.h" -#include "clutter-debug.h" -#include "clutter-event-private.h" -#include "clutter-main.h" -#include "clutter-private.h" -#include "clutter-stage-private.h" - -#include - -#include - -#if 0 -/* XEMBED protocol support for toolkit embedding */ -#define XEMBED_MAPPED (1 << 0) -#define MAX_SUPPORTED_XEMBED_VERSION 1 - -#define XEMBED_EMBEDDED_NOTIFY 0 -#define XEMBED_WINDOW_ACTIVATE 1 -#define XEMBED_WINDOW_DEACTIVATE 2 -#define XEMBED_REQUEST_FOCUS 3 -#define XEMBED_FOCUS_IN 4 -#define XEMBED_FOCUS_OUT 5 -#define XEMBED_FOCUS_NEXT 6 -#define XEMBED_FOCUS_PREV 7 -/* 8-9 were used for XEMBED_GRAB_KEY/XEMBED_UNGRAB_KEY */ -#define XEMBED_MODALITY_ON 10 -#define XEMBED_MODALITY_OFF 11 -#define XEMBED_REGISTER_ACCELERATOR 12 -#define XEMBED_UNREGISTER_ACCELERATOR 13 -#define XEMBED_ACTIVATE_ACCELERATOR 14 - -static Window ParentEmbedderWin = None; -#endif - -typedef struct _ClutterEventSource ClutterEventSource; - -struct _ClutterEventSource -{ - GSource source; - - ClutterBackendX11 *backend; - - GPollFD event_poll_fd; -}; - -ClutterEventX11 * -_clutter_event_x11_new (void) -{ - return g_slice_new0 (ClutterEventX11); -} - -ClutterEventX11 * -_clutter_event_x11_copy (ClutterEventX11 *event_x11) -{ - if (event_x11 != NULL) - return g_slice_dup (ClutterEventX11, event_x11); - - return NULL; -} - -void -_clutter_event_x11_free (ClutterEventX11 *event_x11) -{ - if (event_x11 != NULL) - g_slice_free (ClutterEventX11, event_x11); -} - -static gboolean clutter_event_prepare (GSource *source, - gint *timeout); -static gboolean clutter_event_check (GSource *source); -static gboolean clutter_event_dispatch (GSource *source, - GSourceFunc callback, - gpointer user_data); - -static GSourceFuncs event_funcs = { - clutter_event_prepare, - clutter_event_check, - clutter_event_dispatch, - NULL -}; - -GSource * -_clutter_x11_event_source_new (ClutterBackendX11 *backend_x11) -{ - ClutterEventSource *event_source; - int connection_number; - GSource *source; - gchar *name; - - connection_number = ConnectionNumber (backend_x11->xdpy); - CLUTTER_NOTE (EVENT, "Connection number: %d", connection_number); - - source = g_source_new (&event_funcs, sizeof (ClutterEventSource)); - event_source = (ClutterEventSource *) source; - - name = g_strdup_printf ("Clutter X11 Event (connection: %d)", - connection_number); - g_source_set_name (source, name); - free (name); - - event_source->backend = backend_x11; - event_source->event_poll_fd.fd = connection_number; - event_source->event_poll_fd.events = G_IO_IN; - - g_source_add_poll (source, &event_source->event_poll_fd); - g_source_set_can_recurse (source, TRUE); - - return source; -} - -/** - * clutter_x11_handle_event: - * @xevent: pointer to XEvent structure - * - * This function processes a single X event; it can be used to hook - * into external X11 event processing (for example, a GDK filter - * function). - * - * If clutter_x11_disable_event_retrieval() has been called, you must - * let this function process events to update Clutter's internal state. - * - * Return value: #ClutterX11FilterReturn. %CLUTTER_X11_FILTER_REMOVE - * indicates that Clutter has internally handled the event and the - * caller should do no further processing. %CLUTTER_X11_FILTER_CONTINUE - * indicates that Clutter is either not interested in the event, - * or has used the event to update internal state without taking - * any exclusive action. %CLUTTER_X11_FILTER_TRANSLATE will not - * occur. - * - * Since: 0.8 - */ -ClutterX11FilterReturn -clutter_x11_handle_event (XEvent *xevent) -{ - ClutterX11FilterReturn result; - ClutterBackend *backend; - ClutterEvent *event; - gint spin = 1; -#ifdef HAVE_XGE - ClutterBackendX11 *backend_x11; - Display *xdisplay; - gboolean allocated_event; -#endif - - /* The return values here are someone approximate; we return - * CLUTTER_X11_FILTER_REMOVE if a clutter event is - * generated for the event. This mostly, but not entirely, - * corresponds to whether other event processing should be - * excluded. As long as the stage window is not shared with another - * toolkit it should be safe, and never return - * %CLUTTER_X11_FILTER_REMOVE when more processing is needed. - */ - - result = CLUTTER_X11_FILTER_CONTINUE; - - _clutter_threads_acquire_lock (); - - backend = clutter_get_default_backend (); - - event = clutter_event_new (CLUTTER_NOTHING); - -#ifdef HAVE_XGE - backend_x11 = CLUTTER_BACKEND_X11 (backend); - xdisplay = backend_x11->xdpy; - - allocated_event = XGetEventData (xdisplay, &xevent->xcookie); -#endif - - if (_clutter_backend_translate_event (backend, xevent, event)) - { - _clutter_event_push (event, FALSE); - - result = CLUTTER_X11_FILTER_REMOVE; - } - else - { - clutter_event_free (event); - goto out; - } - - /* - * Motion events can generate synthetic enter and leave events, so if we - * are processing a motion event, we need to spin the event loop at least - * two extra times to pump the enter/leave events through (otherwise they - * just get pushed down the queue and never processed). - */ - if (event->type == CLUTTER_MOTION) - spin += 2; - - while (spin > 0 && (event = clutter_event_get ())) - { - /* forward the event into clutter for emission etc. */ - _clutter_stage_queue_event (event->any.stage, event, FALSE); - --spin; - } - -out: -#ifdef HAVE_XGE - if (allocated_event) - XFreeEventData (xdisplay, &xevent->xcookie); -#endif - - _clutter_threads_release_lock (); - - return result; -} - -static gboolean -clutter_event_prepare (GSource *source, - gint *timeout) -{ - ClutterBackendX11 *backend = ((ClutterEventSource *) source)->backend; - gboolean retval; - - _clutter_threads_acquire_lock (); - - *timeout = -1; - retval = (clutter_events_pending () || XPending (backend->xdpy)); - - _clutter_threads_release_lock (); - - return retval; -} - -static gboolean -clutter_event_check (GSource *source) -{ - ClutterEventSource *event_source = (ClutterEventSource *) source; - ClutterBackendX11 *backend = event_source->backend; - gboolean retval; - - _clutter_threads_acquire_lock (); - - if (event_source->event_poll_fd.revents & G_IO_IN) - retval = (clutter_events_pending () || XPending (backend->xdpy)); - else - retval = FALSE; - - _clutter_threads_release_lock (); - - return retval; -} - -static void -events_queue (ClutterBackendX11 *backend_x11) -{ - ClutterBackend *backend = CLUTTER_BACKEND (backend_x11); - Display *xdisplay = backend_x11->xdpy; - ClutterEvent *event; - XEvent xevent; - - while (!clutter_events_pending () && XPending (xdisplay)) - { - XNextEvent (xdisplay, &xevent); - - event = clutter_event_new (CLUTTER_NOTHING); - -#ifdef HAVE_XGE - XGetEventData (xdisplay, &xevent.xcookie); -#endif - - if (_clutter_backend_translate_event (backend, &xevent, event)) - _clutter_event_push (event, FALSE); - else - clutter_event_free (event); - -#ifdef HAVE_XGE - XFreeEventData (xdisplay, &xevent.xcookie); -#endif - } -} - -static gboolean -clutter_event_dispatch (GSource *source, - GSourceFunc callback, - gpointer user_data) -{ - ClutterBackendX11 *backend = ((ClutterEventSource *) source)->backend; - ClutterEvent *event; - - _clutter_threads_acquire_lock (); - - /* Grab the event(s), translate and figure out double click. - * The push onto queue (stack) if valid. - */ - events_queue (backend); - - /* Pop an event off the queue if any */ - event = clutter_event_get (); - if (event != NULL) - { - /* forward the event into clutter for emission etc. */ - _clutter_stage_queue_event (event->any.stage, event, FALSE); - } - - _clutter_threads_release_lock (); - - return TRUE; -} - -/** - * clutter_x11_get_current_event_time: (skip) - * - * Retrieves the timestamp of the last X11 event processed by - * Clutter. This might be different from the timestamp returned - * by clutter_get_current_event_time(), as Clutter may synthesize - * or throttle events. - * - * Return value: a timestamp, in milliseconds - * - * Since: 1.0 - */ -Time -clutter_x11_get_current_event_time (void) -{ - ClutterBackend *backend = clutter_get_default_backend (); - - return CLUTTER_BACKEND_X11 (backend)->last_event_time; -} - -/** - * clutter_x11_event_get_key_group: - * @event: a #ClutterEvent of type %CLUTTER_KEY_PRESS or %CLUTTER_KEY_RELEASE - * - * Retrieves the group for the modifiers set in @event - * - * Return value: the group id - * - * Since: 1.4 - */ -gint -clutter_x11_event_get_key_group (const ClutterEvent *event) -{ - ClutterEventX11 *event_x11; - - g_return_val_if_fail (event != NULL, 0); - g_return_val_if_fail (event->type == CLUTTER_KEY_PRESS || - event->type == CLUTTER_KEY_RELEASE, 0); - - event_x11 = _clutter_event_get_platform_data (event); - if (event_x11 == NULL) - return 0; - - return event_x11->key_group; -} - -/** - * clutter_x11_event_sequence_get_touch_detail: - * @sequence: a #ClutterEventSequence - * - * Retrieves the touch detail froma #ClutterEventSequence. - * - * Return value: the touch detail - * - * Since: 1.12 - */ -guint -clutter_x11_event_sequence_get_touch_detail (const ClutterEventSequence *sequence) -{ - g_return_val_if_fail (sequence != NULL, 0); - - return GPOINTER_TO_UINT (sequence); -} diff --git a/clutter/clutter/x11/clutter-glx-texture-pixmap.c b/clutter/clutter/x11/clutter-glx-texture-pixmap.c deleted file mode 100644 index 1fdd9e4c2..000000000 --- a/clutter/clutter/x11/clutter-glx-texture-pixmap.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Johan Bilien - * Matthew Allum - * Robert Bragg - * Neil Roberts - * - * Copyright (C) 2007 OpenedHand - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -/** - * SECTION:clutter-glx-texture-pixmap - * @Title: ClutterGLXTexturePixmap - * @short_description: A texture which displays the content of an X Pixmap - * @Deprecated: 1.4: Use #ClutterX11TexturePixmap instead. - * - * #ClutterGLXTexturePixmap is a class for displaying the content of an - * X Pixmap as a ClutterActor. Used together with the X Composite extension, - * it allows to display the content of X Windows inside Clutter. - * - * This class used to be necessary to use the - * GLX_EXT_texture_from_pixmap extension to get fast texture - * updates. However since Clutter 1.4 the handling of this extension - * has moved down to Cogl. ClutterX11TexturePixmap and - * ClutterGLXTexturePixmap are now equivalent and either one of them - * may use the extension if it is possible. - */ - -#include "clutter-build-config.h" - -#include - -#define CLUTTER_DISABLE_DEPRECATION_WARNINGS -#include "x11/clutter-x11-texture-pixmap.h" - -#include - -#include "clutter-glx-texture-pixmap.h" - -G_DEFINE_TYPE (ClutterGLXTexturePixmap, \ - clutter_glx_texture_pixmap, \ - CLUTTER_X11_TYPE_TEXTURE_PIXMAP); - -static void -clutter_glx_texture_pixmap_init (ClutterGLXTexturePixmap *self) -{ -} - -static void -clutter_glx_texture_pixmap_class_init (ClutterGLXTexturePixmapClass *klass) -{ -} - -/** - * clutter_glx_texture_pixmap_using_extension: - * @texture: A #ClutterGLXTexturePixmap - * - * Checks whether @texture is using the GLX_EXT_texture_from_pixmap - * extension; this extension can be optionally (though it is strongly - * encouraged) implemented as a zero-copy between a GLX pixmap and - * a GL texture. - * - * Return value: %TRUE if the texture is using the - * GLX_EXT_texture_from_pixmap OpenGL extension or falling back to the - * slower software mechanism. - * - * Deprecated: 1.6: Use cogl_texture_pixmap_x11_is_using_tfp_extension() - * on the texture handle instead. - * - * Since: 0.8 - */ -gboolean -clutter_glx_texture_pixmap_using_extension (ClutterGLXTexturePixmap *texture) -{ - CoglHandle cogl_texture; - - g_return_val_if_fail (CLUTTER_GLX_IS_TEXTURE_PIXMAP (texture), FALSE); - - cogl_texture = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (texture)); - - return (cogl_is_texture_pixmap_x11 (cogl_texture) && - cogl_texture_pixmap_x11_is_using_tfp_extension (cogl_texture)); -} - -/** - * clutter_glx_texture_pixmap_new_with_pixmap: - * @pixmap: the X Pixmap to which this texture should be bound - * - * Creates a new #ClutterGLXTexturePixmap for @pixmap - * - * Return value: A new #ClutterGLXTexturePixmap bound to the given X Pixmap - * - * Since: 0.8 - * - * Deprecated: 1.6: Use clutter_x11_texture_pixmap_new_with_pixmap() instead - */ -ClutterActor * -clutter_glx_texture_pixmap_new_with_pixmap (Pixmap pixmap) -{ - return g_object_new (CLUTTER_GLX_TYPE_TEXTURE_PIXMAP, - "pixmap", pixmap, - NULL); -} - -/** - * clutter_glx_texture_pixmap_new_with_window: - * @window: the X window to which this texture should be bound - * - * Creates a new #ClutterGLXTexturePixmap for @window - * - * Return value: A new #ClutterGLXTexturePixmap bound to the given X window - * - * Since: 0.8 - * - * Deprecated: 1.6: Use clutter_x11_texture_pixmap_new_with_window() instead - */ -ClutterActor * -clutter_glx_texture_pixmap_new_with_window (Window window) -{ - return g_object_new (CLUTTER_GLX_TYPE_TEXTURE_PIXMAP, - "window", window, - NULL); -} - -/** - * clutter_glx_texture_pixmap_new: - * - * Creates a new, empty #ClutterGLXTexturePixmap - * - * Return value: A new #ClutterGLXTexturePixmap - * - * Since: 0.8 - * - * Deprecated: 1.6: Use clutter_x11_texture_pixmap_new() instead - */ -ClutterActor * -clutter_glx_texture_pixmap_new (void) -{ - return g_object_new (CLUTTER_GLX_TYPE_TEXTURE_PIXMAP, NULL); -} diff --git a/clutter/clutter/x11/clutter-glx-texture-pixmap.h b/clutter/clutter/x11/clutter-glx-texture-pixmap.h deleted file mode 100644 index ffc967087..000000000 --- a/clutter/clutter/x11/clutter-glx-texture-pixmap.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Johan Bilien - * - * Copyright (C) 2007 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __CLUTTER_GLX_TEXTURE_PIXMAP_H__ -#define __CLUTTER_GLX_TEXTURE_PIXMAP_H__ - -#include - -G_BEGIN_DECLS - -#define CLUTTER_GLX_TYPE_TEXTURE_PIXMAP (clutter_glx_texture_pixmap_get_type ()) -#define CLUTTER_GLX_TEXTURE_PIXMAP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_GLX_TYPE_TEXTURE_PIXMAP, ClutterGLXTexturePixmap)) -#define CLUTTER_GLX_TEXTURE_PIXMAP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_GLX_TYPE_TEXTURE_PIXMAP, ClutterGLXTexturePixmapClass)) -#define CLUTTER_GLX_IS_TEXTURE_PIXMAP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_GLX_TYPE_TEXTURE_PIXMAP)) -#define CLUTTER_GLX_IS_TEXTURE_PIXMAP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_GLX_TYPE_TEXTURE_PIXMAP)) -#define CLUTTER_GLX_TEXTURE_PIXMAP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_GLX_TYPE_TEXTURE_PIXMAP, ClutterGLXTexturePixmapClass)) - -typedef struct _ClutterGLXTexturePixmap ClutterGLXTexturePixmap; -typedef struct _ClutterGLXTexturePixmapClass ClutterGLXTexturePixmapClass; -typedef struct _ClutterGLXTexturePixmapPrivate ClutterGLXTexturePixmapPrivate; - -/** - * ClutterGLXTexturePixmapClass: - * - * The #ClutterGLXTexturePixmapClass structure contains only private data - * - * Since: 0.8 - * - * Deprecated: 1.6: Use #ClutterX11TexturePixmapClass instead - */ -struct _ClutterGLXTexturePixmapClass -{ - /*< private >*/ - ClutterX11TexturePixmapClass parent_class; -}; - -/** - * ClutterGLXTexturePixmap: - * - * The #ClutterGLXTexturePixmap structure contains only private data - * - * Since: 0.8 - * - * Deprecated: 1.6: Use #ClutterX11TexturePixmap instead - */ -struct _ClutterGLXTexturePixmap -{ - /*< private >*/ - ClutterX11TexturePixmap parent; - - ClutterGLXTexturePixmapPrivate *priv; -}; - -CLUTTER_DEPRECATED_FOR(clutter_x11_texture_pixmap_get_type) -GType clutter_glx_texture_pixmap_get_type (void); - -CLUTTER_DEPRECATED_FOR(clutter_x11_texture_pixmap_new) -ClutterActor * clutter_glx_texture_pixmap_new (void); - -CLUTTER_DEPRECATED_FOR(clutter_x11_texture_pixmap_new_with_pixmap) -ClutterActor * clutter_glx_texture_pixmap_new_with_pixmap (Pixmap pixmap); - -CLUTTER_DEPRECATED_FOR(clutter_x11_texture_pixmap_new_with_window) -ClutterActor * clutter_glx_texture_pixmap_new_with_window (Window window); - -CLUTTER_DEPRECATED_FOR(cogl_texture_pixmap_x11_is_using_tfp_extension) -gboolean clutter_glx_texture_pixmap_using_extension (ClutterGLXTexturePixmap *texture); - -G_END_DECLS - -#endif /* __CLUTTER_GLX_TEXTURE_PIXMAP_H__ */ diff --git a/clutter/clutter/x11/clutter-input-device-core-x11.c b/clutter/clutter/x11/clutter-input-device-core-x11.c deleted file mode 100644 index c7543f9bc..000000000 --- a/clutter/clutter/x11/clutter-input-device-core-x11.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright © 2010, 2011 Intel Corp. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Emmanuele Bassi - */ - -#include "clutter-build-config.h" - -#include "clutter-input-device-core-x11.h" - -#include "clutter-debug.h" -#include "clutter-device-manager-private.h" -#include "clutter-private.h" -#include "clutter-stage-private.h" - -#include "clutter-backend-x11.h" -#include "clutter-stage-x11.h" - -typedef struct _ClutterInputDeviceClass ClutterInputDeviceX11Class; - -/* a specific X11 input device */ -struct _ClutterInputDeviceX11 -{ - ClutterInputDevice device; - - int min_keycode; - int max_keycode; -}; - -#define clutter_input_device_x11_get_type _clutter_input_device_x11_get_type - -G_DEFINE_TYPE (ClutterInputDeviceX11, - clutter_input_device_x11, - CLUTTER_TYPE_INPUT_DEVICE); - -static gboolean -clutter_input_device_x11_keycode_to_evdev (ClutterInputDevice *device, - guint hardware_keycode, - guint *evdev_keycode) -{ - /* When using evdev under X11 the hardware keycodes are the evdev - keycodes plus 8. I haven't been able to find any documentation to - know what the +8 is for. FIXME: This should probably verify that - X server is using evdev. */ - *evdev_keycode = hardware_keycode - 8; - - return TRUE; -} - -static void -clutter_input_device_x11_class_init (ClutterInputDeviceX11Class *klass) -{ - ClutterInputDeviceClass *device_class = CLUTTER_INPUT_DEVICE_CLASS (klass); - - device_class->keycode_to_evdev = clutter_input_device_x11_keycode_to_evdev; -} - -static void -clutter_input_device_x11_init (ClutterInputDeviceX11 *self) -{ -} diff --git a/clutter/clutter/x11/clutter-input-device-core-x11.h b/clutter/clutter/x11/clutter-input-device-core-x11.h deleted file mode 100644 index c264051e5..000000000 --- a/clutter/clutter/x11/clutter-input-device-core-x11.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright © 2010, 2011 Intel Corp. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Emmanuele Bassi - */ - -#ifndef __CLUTTER_INPUT_DEVICE_X11_H__ -#define __CLUTTER_INPUT_DEVICE_X11_H__ - -#include -#include - -#include "clutter-stage-x11.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_INPUT_DEVICE_X11 (_clutter_input_device_x11_get_type ()) -#define CLUTTER_INPUT_DEVICE_X11(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_INPUT_DEVICE_X11, ClutterInputDeviceX11)) -#define CLUTTER_IS_INPUT_DEVICE_X11(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_INPUT_DEVICE_X11)) - -typedef struct _ClutterInputDeviceX11 ClutterInputDeviceX11; - -GType _clutter_input_device_x11_get_type (void) G_GNUC_CONST; - -G_END_DECLS - -#endif /* __CLUTTER_INPUT_DEVICE_X11_H__ */ diff --git a/clutter/clutter/x11/clutter-input-device-tool-xi2.h b/clutter/clutter/x11/clutter-input-device-tool-xi2.h deleted file mode 100644 index 97c5e5bf7..000000000 --- a/clutter/clutter/x11/clutter-input-device-tool-xi2.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright © 2016 Red Hat - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Carlos Garnacho - */ - -#ifndef __CLUTTER_INPUT_DEVICE_XI2_TOOL_H__ -#define __CLUTTER_INPUT_DEVICE_XI2_TOOL_H__ - -#include - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_INPUT_DEVICE_TOOL_XI2 (clutter_input_device_tool_xi2_get_type ()) - -#define CLUTTER_INPUT_DEVICE_TOOL_XI2(o) \ - (G_TYPE_CHECK_INSTANCE_CAST ((o), \ - CLUTTER_TYPE_INPUT_DEVICE_TOOL_XI2, ClutterInputDeviceToolXI2)) - -#define CLUTTER_IS_INPUT_DEVICE_TOOL_XI2(o) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((o), \ - CLUTTER_TYPE_INPUT_DEVICE_TOOL_XI2)) - -#define CLUTTER_INPUT_DEVICE_TOOL_XI2_CLASS(c) \ - (G_TYPE_CHECK_CLASS_CAST ((c), \ - CLUTTER_TYPE_INPUT_DEVICE_TOOL_XI2, ClutterInputDeviceToolXI2Class)) - -#define CLUTTER_IS_INPUT_DEVICE_TOOL_XI2_CLASS(c) \ - (G_TYPE_CHECK_CLASS_TYPE ((c), \ - CLUTTER_TYPE_INPUT_DEVICE_TOOL_XI2)) - -#define CLUTTER_INPUT_DEVICE_TOOL_XI2_GET_CLASS(o) \ - (G_TYPE_INSTANCE_GET_CLASS ((o), \ - CLUTTER_TYPE_INPUT_DEVICE_TOOL_XI2, ClutterInputDeviceToolXI2Class)) - -typedef struct _ClutterInputDeviceToolXI2 ClutterInputDeviceToolXI2; -typedef struct _ClutterInputDeviceToolXI2Class ClutterInputDeviceToolXI2Class; - -struct _ClutterInputDeviceToolXI2 -{ - ClutterInputDeviceTool parent_instance; - struct libinput_tablet_tool *tool; -}; - -struct _ClutterInputDeviceToolXI2Class -{ - ClutterInputDeviceToolClass parent_class; -}; - -GType clutter_input_device_tool_xi2_get_type (void) G_GNUC_CONST; - -ClutterInputDeviceTool * clutter_input_device_tool_xi2_new (guint serial, - ClutterInputDeviceToolType type); - -G_END_DECLS - -#endif /* __CLUTTER_INPUT_DEVICE_XI2_TOOL_H__ */ diff --git a/clutter/clutter/x11/clutter-input-device-xi2.c b/clutter/clutter/x11/clutter-input-device-xi2.c deleted file mode 100644 index 1254aca3a..000000000 --- a/clutter/clutter/x11/clutter-input-device-xi2.c +++ /dev/null @@ -1,357 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright © 2011 Intel Corp. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Emmanuele Bassi - */ - -#include "clutter-build-config.h" - -#include "clutter-input-device-xi2.h" - -#include "clutter-debug.h" -#include "clutter-device-manager-private.h" -#include "clutter-event-private.h" -#include "clutter-private.h" -#include "clutter-stage-private.h" - -#include "clutter-backend-x11.h" -#include "clutter-stage-x11.h" - -#include - -typedef struct _ClutterInputDeviceClass ClutterInputDeviceXI2Class; - -/* a specific XI2 input device */ -struct _ClutterInputDeviceXI2 -{ - ClutterInputDevice device; - - gint device_id; - ClutterInputDeviceTool *current_tool; - -#ifdef HAVE_LIBWACOM - WacomDevice *wacom_device; - GArray *group_modes; -#endif -}; - -#define N_BUTTONS 5 - -#define clutter_input_device_xi2_get_type _clutter_input_device_xi2_get_type - -G_DEFINE_TYPE (ClutterInputDeviceXI2, - clutter_input_device_xi2, - CLUTTER_TYPE_INPUT_DEVICE); - -static void -clutter_input_device_xi2_constructed (GObject *gobject) -{ - ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (gobject); - - g_object_get (gobject, "id", &device_xi2->device_id, NULL); - - if (G_OBJECT_CLASS (clutter_input_device_xi2_parent_class)->constructed) - G_OBJECT_CLASS (clutter_input_device_xi2_parent_class)->constructed (gobject); - -#ifdef HAVE_LIBWACOM - if (clutter_input_device_get_device_type (CLUTTER_INPUT_DEVICE (gobject)) == CLUTTER_PAD_DEVICE) - { - device_xi2->group_modes = g_array_new (FALSE, TRUE, sizeof (guint)); - g_array_set_size (device_xi2->group_modes, - clutter_input_device_get_n_mode_groups (CLUTTER_INPUT_DEVICE (gobject))); - } -#endif -} - -static gboolean -clutter_input_device_xi2_keycode_to_evdev (ClutterInputDevice *device, - guint hardware_keycode, - guint *evdev_keycode) -{ - /* When using evdev under X11 the hardware keycodes are the evdev - keycodes plus 8. I haven't been able to find any documentation to - know what the +8 is for. FIXME: This should probably verify that - X server is using evdev. */ - *evdev_keycode = hardware_keycode - 8; - - return TRUE; -} - -static gboolean -clutter_input_device_xi2_is_grouped (ClutterInputDevice *device, - ClutterInputDevice *other_device) -{ - return FALSE; -} - -static void -clutter_input_device_xi2_finalize (GObject *object) -{ -#ifdef HAVE_LIBWACOM - ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (object); - - if (device_xi2->wacom_device) - libwacom_destroy (device_xi2->wacom_device); - - if (device_xi2->group_modes) - g_array_unref (device_xi2->group_modes); -#endif - - G_OBJECT_CLASS (clutter_input_device_xi2_parent_class)->finalize (object); -} - -static gint -clutter_input_device_xi2_get_group_n_modes (ClutterInputDevice *device, - gint group) -{ -#ifdef HAVE_LIBWACOM - ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device); - - if (device_xi2->wacom_device) - { - if (group == 0) - { - if (libwacom_has_ring (device_xi2->wacom_device)) - return libwacom_get_ring_num_modes (device_xi2->wacom_device); - else if (libwacom_get_num_strips (device_xi2->wacom_device) >= 1) - return libwacom_get_strips_num_modes (device_xi2->wacom_device); - } - else if (group == 1) - { - if (libwacom_has_ring2 (device_xi2->wacom_device)) - return libwacom_get_ring2_num_modes (device_xi2->wacom_device); - else if (libwacom_get_num_strips (device_xi2->wacom_device) >= 2) - return libwacom_get_strips_num_modes (device_xi2->wacom_device); - } - } -#endif - - return -1; -} - -#ifdef HAVE_LIBWACOM -static int -clutter_input_device_xi2_get_button_group (ClutterInputDevice *device, - guint button) -{ - ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device); - - if (device_xi2->wacom_device) - { - if (button >= libwacom_get_num_buttons (device_xi2->wacom_device)) - return -1; - - return libwacom_get_button_led_group (device_xi2->wacom_device, - 'A' + button); - } - else - return -1; -} -#endif - -static gboolean -clutter_input_device_xi2_is_mode_switch_button (ClutterInputDevice *device, - guint group, - guint button) -{ - int button_group = -1; - -#ifdef HAVE_LIBWACOM - button_group = clutter_input_device_xi2_get_button_group (device, button); -#endif - - return button_group == (int) group; -} - -static void -clutter_input_device_xi2_class_init (ClutterInputDeviceXI2Class *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterInputDeviceClass *device_class = CLUTTER_INPUT_DEVICE_CLASS (klass); - - gobject_class->constructed = clutter_input_device_xi2_constructed; - gobject_class->finalize = clutter_input_device_xi2_finalize; - - device_class->keycode_to_evdev = clutter_input_device_xi2_keycode_to_evdev; - device_class->is_grouped = clutter_input_device_xi2_is_grouped; - device_class->get_group_n_modes = clutter_input_device_xi2_get_group_n_modes; - device_class->is_mode_switch_button = clutter_input_device_xi2_is_mode_switch_button; -} - -static void -clutter_input_device_xi2_init (ClutterInputDeviceXI2 *self) -{ -} - -static ClutterModifierType -get_modifier_for_button (int i) -{ - switch (i) - { - case 1: - return CLUTTER_BUTTON1_MASK; - case 2: - return CLUTTER_BUTTON2_MASK; - case 3: - return CLUTTER_BUTTON3_MASK; - case 4: - return CLUTTER_BUTTON4_MASK; - case 5: - return CLUTTER_BUTTON5_MASK; - default: - return 0; - } -} - -void -_clutter_input_device_xi2_translate_state (ClutterEvent *event, - XIModifierState *modifiers_state, - XIButtonState *buttons_state, - XIGroupState *group_state) -{ - guint button = 0; - guint base = 0; - guint latched = 0; - guint locked = 0; - guint effective; - - if (modifiers_state) - { - base = (guint) modifiers_state->base; - latched = (guint) modifiers_state->latched; - locked = (guint) modifiers_state->locked; - } - - if (buttons_state) - { - int len, i; - - len = MIN (N_BUTTONS, buttons_state->mask_len * 8); - - for (i = 0; i < len; i++) - { - if (!XIMaskIsSet (buttons_state->mask, i)) - continue; - - button |= get_modifier_for_button (i); - } - } - - /* The XIButtonState sent in the event specifies the - * state of the buttons before the event. In order to - * get the current state of the buttons, we need to - * filter out the current button. - */ - switch (event->type) - { - case CLUTTER_BUTTON_PRESS: - button |= (get_modifier_for_button (event->button.button)); - break; - case CLUTTER_BUTTON_RELEASE: - button &= ~(get_modifier_for_button (event->button.button)); - break; - default: - break; - } - - effective = button | base | latched | locked; - if (group_state) - effective |= (group_state->effective) << 13; - - _clutter_event_set_state_full (event, button, base, latched, locked, effective); -} - -void -clutter_input_device_xi2_update_tool (ClutterInputDevice *device, - ClutterInputDeviceTool *tool) -{ - ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device); - g_set_object (&device_xi2->current_tool, tool); -} - -ClutterInputDeviceTool * -clutter_input_device_xi2_get_current_tool (ClutterInputDevice *device) -{ - ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device); - return device_xi2->current_tool; -} - -#ifdef HAVE_LIBWACOM -void -clutter_input_device_xi2_ensure_wacom_info (ClutterInputDevice *device, - WacomDeviceDatabase *wacom_db) -{ - ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device); - const gchar *node_path; - - node_path = clutter_input_device_get_device_node (device); - device_xi2->wacom_device = libwacom_new_from_path (wacom_db, node_path, - WFALLBACK_NONE, NULL); -} - -guint -clutter_input_device_xi2_get_pad_group_mode (ClutterInputDevice *device, - guint group) -{ - ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device); - - if (group >= device_xi2->group_modes->len) - return 0; - - return g_array_index (device_xi2->group_modes, guint, group); -} - -void -clutter_input_device_xi2_update_pad_state (ClutterInputDevice *device, - guint button, - guint state, - guint *group, - guint *mode) -{ - ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device); - guint button_group, *group_mode; - gboolean is_mode_switch = FALSE; - - button_group = clutter_input_device_xi2_get_button_group (device, button); - is_mode_switch = button_group >= 0; - - /* Assign all non-mode-switch buttons to group 0 so far */ - button_group = MAX (0, button_group); - - if (button_group >= device_xi2->group_modes->len) - return; - - group_mode = &g_array_index (device_xi2->group_modes, guint, button_group); - - if (is_mode_switch && state) - { - guint next, n_modes; - - n_modes = clutter_input_device_get_group_n_modes (device, button_group); - next = (*group_mode + 1) % n_modes; - *group_mode = next; - } - - if (group) - *group = button_group; - if (mode) - *mode = *group_mode; -} -#endif diff --git a/clutter/clutter/x11/clutter-input-device-xi2.h b/clutter/clutter/x11/clutter-input-device-xi2.h deleted file mode 100644 index 2194e1ba2..000000000 --- a/clutter/clutter/x11/clutter-input-device-xi2.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright © 2011 Intel Corp. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Emmanuele Bassi - */ - -#ifndef __CLUTTER_INPUT_DEVICE_XI2_H__ -#define __CLUTTER_INPUT_DEVICE_XI2_H__ - -#include -#include - -#ifdef HAVE_LIBWACOM -#include -#endif - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_INPUT_DEVICE_XI2 (_clutter_input_device_xi2_get_type ()) -#define CLUTTER_INPUT_DEVICE_XI2(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_INPUT_DEVICE_XI2, ClutterInputDeviceXI2)) -#define CLUTTER_IS_INPUT_DEVICE_XI2(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_INPUT_DEVICE_XI2)) - -typedef struct _ClutterInputDeviceXI2 ClutterInputDeviceXI2; - -GType _clutter_input_device_xi2_get_type (void) G_GNUC_CONST; - -void _clutter_input_device_xi2_translate_state (ClutterEvent *event, - XIModifierState *modifiers_state, - XIButtonState *buttons_state, - XIGroupState *group_state); -void clutter_input_device_xi2_update_tool (ClutterInputDevice *device, - ClutterInputDeviceTool *tool); -ClutterInputDeviceTool * clutter_input_device_xi2_get_current_tool (ClutterInputDevice *device); - -#ifdef HAVE_LIBWACOM -void clutter_input_device_xi2_ensure_wacom_info (ClutterInputDevice *device, - WacomDeviceDatabase *wacom_db); - -guint clutter_input_device_xi2_get_pad_group_mode (ClutterInputDevice *device, - guint group); - -void clutter_input_device_xi2_update_pad_state (ClutterInputDevice *device, - guint button, - guint state, - guint *group, - guint *mode); - -#endif - -G_END_DECLS - -#endif /* __CLUTTER_INPUT_DEVICE_XI2_H__ */ diff --git a/clutter/clutter/x11/clutter-keymap-x11.c b/clutter/clutter/x11/clutter-keymap-x11.c deleted file mode 100644 index 914e31434..000000000 --- a/clutter/clutter/x11/clutter-keymap-x11.c +++ /dev/null @@ -1,667 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corp. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Emmanuele Bassi - */ - -#include "clutter-build-config.h" - -#include "clutter-keymap-x11.h" -#include "clutter-backend-x11.h" - -#include "clutter-debug.h" -#include "clutter-event-translator.h" -#include "clutter-private.h" - -#include - -#ifdef HAVE_XKB -#include -#endif - -typedef struct _ClutterKeymapX11Class ClutterKeymapX11Class; -typedef struct _DirectionCacheEntry DirectionCacheEntry; - -struct _DirectionCacheEntry -{ - guint serial; - Atom group_atom; - PangoDirection direction; -}; - -struct _ClutterKeymapX11 -{ - GObject parent_instance; - - ClutterBackend *backend; - - int min_keycode; - int max_keycode; - - ClutterModifierType modmap[8]; - - ClutterModifierType num_lock_mask; - ClutterModifierType scroll_lock_mask; - - PangoDirection current_direction; - -#ifdef HAVE_XKB - XkbDescPtr xkb_desc; - int xkb_event_base; - guint xkb_map_serial; - Atom current_group_atom; - guint current_cache_serial; - DirectionCacheEntry group_direction_cache[4]; -#endif - - guint caps_lock_state : 1; - guint num_lock_state : 1; - guint has_direction : 1; -}; - -struct _ClutterKeymapX11Class -{ - GObjectClass parent_class; -}; - -enum -{ - PROP_0, - - PROP_BACKEND, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST] = { NULL, }; - -static void clutter_event_translator_iface_init (ClutterEventTranslatorIface *iface); - -#define clutter_keymap_x11_get_type _clutter_keymap_x11_get_type - -G_DEFINE_TYPE_WITH_CODE (ClutterKeymapX11, clutter_keymap_x11, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_EVENT_TRANSLATOR, - clutter_event_translator_iface_init)); - -#ifdef HAVE_XKB - -/* code adapted from gdk/x11/gdkkeys-x11.c - update_modmap */ -static void -update_modmap (Display *display, - ClutterKeymapX11 *keymap_x11) -{ - static struct { - const gchar *name; - Atom atom; - ClutterModifierType mask; - } vmods[] = { - { "Meta", 0, CLUTTER_META_MASK }, - { "Super", 0, CLUTTER_SUPER_MASK }, - { "Hyper", 0, CLUTTER_HYPER_MASK }, - { NULL, 0, 0 } - }; - - int i, j, k; - - if (vmods[0].atom == 0) - for (i = 0; vmods[i].name; i++) - vmods[i].atom = XInternAtom (display, vmods[i].name, FALSE); - - for (i = 0; i < 8; i++) - keymap_x11->modmap[i] = 1 << i; - - for (i = 0; i < XkbNumVirtualMods; i++) - { - for (j = 0; vmods[j].atom; j++) - { - if (keymap_x11->xkb_desc->names->vmods[i] == vmods[j].atom) - { - for (k = 0; k < 8; k++) - { - if (keymap_x11->xkb_desc->server->vmods[i] & (1 << k)) - keymap_x11->modmap[k] |= vmods[j].mask; - } - } - } - } -} - -static XkbDescPtr -get_xkb (ClutterKeymapX11 *keymap_x11) -{ - ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (keymap_x11->backend); - - if (keymap_x11->max_keycode == 0) - XDisplayKeycodes (backend_x11->xdpy, - &keymap_x11->min_keycode, - &keymap_x11->max_keycode); - - if (keymap_x11->xkb_desc == NULL) - { - int flags = XkbKeySymsMask - | XkbKeyTypesMask - | XkbModifierMapMask - | XkbVirtualModsMask; - - keymap_x11->xkb_desc = XkbGetMap (backend_x11->xdpy, flags, XkbUseCoreKbd); - if (G_UNLIKELY (keymap_x11->xkb_desc == NULL)) - { - g_error ("Failed to get the keymap from XKB"); - return NULL; - } - - flags = XkbGroupNamesMask | XkbVirtualModNamesMask; - XkbGetNames (backend_x11->xdpy, flags, keymap_x11->xkb_desc); - - update_modmap (backend_x11->xdpy, keymap_x11); - } - else if (keymap_x11->xkb_map_serial != backend_x11->keymap_serial) - { - int flags = XkbKeySymsMask - | XkbKeyTypesMask - | XkbModifierMapMask - | XkbVirtualModsMask; - - CLUTTER_NOTE (BACKEND, "Updating XKB keymap"); - - XkbGetUpdatedMap (backend_x11->xdpy, flags, keymap_x11->xkb_desc); - - flags = XkbGroupNamesMask | XkbVirtualModNamesMask; - XkbGetNames (backend_x11->xdpy, flags, keymap_x11->xkb_desc); - - update_modmap (backend_x11->xdpy, keymap_x11); - - keymap_x11->xkb_map_serial = backend_x11->keymap_serial; - } - - if (keymap_x11->num_lock_mask == 0) - keymap_x11->num_lock_mask = XkbKeysymToModifiers (backend_x11->xdpy, - XK_Num_Lock); - - if (keymap_x11->scroll_lock_mask == 0) - keymap_x11->scroll_lock_mask = XkbKeysymToModifiers (backend_x11->xdpy, - XK_Scroll_Lock); - - return keymap_x11->xkb_desc; -} -#endif /* HAVE_XKB */ - -#ifdef HAVE_XKB -static void -update_locked_mods (ClutterKeymapX11 *keymap_x11, - gint locked_mods) -{ -#if 0 - gboolean old_caps_lock_state, old_num_lock_state; - - old_caps_lock_state = keymap_x11->caps_lock_state; - old_num_lock_state = keymap_x11->num_lock_state; -#endif - - keymap_x11->caps_lock_state = (locked_mods & CLUTTER_LOCK_MASK) != 0; - keymap_x11->num_lock_state = (locked_mods & keymap_x11->num_lock_mask) != 0; - - CLUTTER_NOTE (BACKEND, "Locks state changed - Num: %s, Caps: %s", - keymap_x11->num_lock_state ? "set" : "unset", - keymap_x11->caps_lock_state ? "set" : "unset"); - -#if 0 - /* Add signal to ClutterBackend? */ - if ((keymap_x11->caps_lock_state != old_caps_lock_state) || - (keymap_x11->num_lock_state != old_num_lock_state)) - g_signal_emit_by_name (keymap_x11->backend, "key-lock-changed"); -#endif -} -#endif /* HAVE_XKB */ - -#ifdef HAVE_XKB -/* the code to retrieve the keymap direction and cache it - * is taken from GDK: - * gdk/x11/gdkkeys-x11.c - */ -static PangoDirection -get_direction (XkbDescPtr xkb, - int group) -{ - int rtl_minus_ltr = 0; /* total number of RTL keysyms minus LTR ones */ - int code; - - for (code = xkb->min_key_code; - code <= xkb->max_key_code; - code += 1) - { - int level = 0; - KeySym sym = XkbKeySymEntry (xkb, code, level, group); - PangoDirection dir = pango_unichar_direction (clutter_keysym_to_unicode (sym)); - - switch (dir) - { - case PANGO_DIRECTION_RTL: - rtl_minus_ltr++; - break; - - case PANGO_DIRECTION_LTR: - rtl_minus_ltr--; - break; - - default: - break; - } - } - - if (rtl_minus_ltr > 0) - return PANGO_DIRECTION_RTL; - - return PANGO_DIRECTION_LTR; -} - -static PangoDirection -get_direction_from_cache (ClutterKeymapX11 *keymap_x11, - XkbDescPtr xkb, - int group) -{ - Atom group_atom = xkb->names->groups[group]; - gboolean cache_hit = FALSE; - DirectionCacheEntry *cache = keymap_x11->group_direction_cache; - PangoDirection direction = PANGO_DIRECTION_NEUTRAL; - int i; - - if (keymap_x11->has_direction) - { - /* look up in the cache */ - for (i = 0; i < G_N_ELEMENTS (keymap_x11->group_direction_cache); i++) - { - if (cache[i].group_atom == group_atom) - { - cache_hit = TRUE; - cache[i].serial = keymap_x11->current_cache_serial++; - direction = cache[i].direction; - group_atom = cache[i].group_atom; - break; - } - } - } - else - { - /* initialize the cache */ - for (i = 0; i < G_N_ELEMENTS (keymap_x11->group_direction_cache); i++) - { - cache[i].group_atom = 0; - cache[i].direction = PANGO_DIRECTION_NEUTRAL; - cache[i].serial = keymap_x11->current_cache_serial; - } - - keymap_x11->current_cache_serial += 1; - } - - /* insert the new entry in the cache */ - if (!cache_hit) - { - int oldest = 0; - - direction = get_direction (xkb, group); - - /* replace the oldest entry */ - for (i = 0; i < G_N_ELEMENTS (keymap_x11->group_direction_cache); i++) - { - if (cache[i].serial < cache[oldest].serial) - oldest = i; - } - - cache[oldest].group_atom = group_atom; - cache[oldest].direction = direction; - cache[oldest].serial = keymap_x11->current_cache_serial++; - } - - return direction; -} -#endif /* HAVE_XKB */ - -static void -update_direction (ClutterKeymapX11 *keymap_x11, - int group) -{ -#ifdef HAVE_XKB - XkbDescPtr xkb = get_xkb (keymap_x11); - Atom group_atom; - - group_atom = xkb->names->groups[group]; - - if (!keymap_x11->has_direction || keymap_x11->current_group_atom != group_atom) - { - keymap_x11->current_direction = get_direction_from_cache (keymap_x11, xkb, group); - keymap_x11->current_group_atom = group_atom; - keymap_x11->has_direction = TRUE; - } -#endif /* HAVE_XKB */ -} - -static void -clutter_keymap_x11_constructed (GObject *gobject) -{ - ClutterKeymapX11 *keymap_x11 = CLUTTER_KEYMAP_X11 (gobject); - ClutterBackendX11 *backend_x11; - - g_assert (keymap_x11->backend != NULL); - backend_x11 = CLUTTER_BACKEND_X11 (keymap_x11->backend); - -#ifdef HAVE_XKB - { - gint xkb_major = XkbMajorVersion; - gint xkb_minor = XkbMinorVersion; - - if (XkbLibraryVersion (&xkb_major, &xkb_minor)) - { - xkb_major = XkbMajorVersion; - xkb_minor = XkbMinorVersion; - - if (XkbQueryExtension (backend_x11->xdpy, - NULL, - &keymap_x11->xkb_event_base, - NULL, - &xkb_major, &xkb_minor)) - { - Bool detectable_autorepeat_supported; - - backend_x11->use_xkb = TRUE; - - XkbSelectEvents (backend_x11->xdpy, - XkbUseCoreKbd, - XkbNewKeyboardNotifyMask | XkbMapNotifyMask | XkbStateNotifyMask, - XkbNewKeyboardNotifyMask | XkbMapNotifyMask | XkbStateNotifyMask); - - XkbSelectEventDetails (backend_x11->xdpy, - XkbUseCoreKbd, XkbStateNotify, - XkbAllStateComponentsMask, - XkbGroupLockMask | XkbModifierLockMask); - - /* enable XKB autorepeat */ - XkbSetDetectableAutoRepeat (backend_x11->xdpy, - True, - &detectable_autorepeat_supported); - - backend_x11->have_xkb_autorepeat = detectable_autorepeat_supported; - - CLUTTER_NOTE (BACKEND, "Detectable autorepeat: %s", - backend_x11->have_xkb_autorepeat ? "supported" - : "not supported"); - } - } - } -#endif /* HAVE_XKB */ -} - -static void -clutter_keymap_x11_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterKeymapX11 *keymap = CLUTTER_KEYMAP_X11 (gobject); - - switch (prop_id) - { - case PROP_BACKEND: - keymap->backend = g_value_get_object (value); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_keymap_x11_finalize (GObject *gobject) -{ - ClutterKeymapX11 *keymap; - ClutterEventTranslator *translator; - - keymap = CLUTTER_KEYMAP_X11 (gobject); - translator = CLUTTER_EVENT_TRANSLATOR (keymap); - -#ifdef HAVE_XKB - _clutter_backend_remove_event_translator (keymap->backend, translator); - - if (keymap->xkb_desc != NULL) - XkbFreeKeyboard (keymap->xkb_desc, XkbAllComponentsMask, True); -#endif - - G_OBJECT_CLASS (clutter_keymap_x11_parent_class)->finalize (gobject); -} - -static void -clutter_keymap_x11_class_init (ClutterKeymapX11Class *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - obj_props[PROP_BACKEND] = - g_param_spec_object ("backend", - P_("Backend"), - P_("The Clutter backend"), - CLUTTER_TYPE_BACKEND, - CLUTTER_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY); - - gobject_class->constructed = clutter_keymap_x11_constructed; - gobject_class->set_property = clutter_keymap_x11_set_property; - gobject_class->finalize = clutter_keymap_x11_finalize; - g_object_class_install_properties (gobject_class, PROP_LAST, obj_props); -} - -static void -clutter_keymap_x11_init (ClutterKeymapX11 *keymap) -{ - keymap->current_direction = PANGO_DIRECTION_NEUTRAL; -} - -static ClutterTranslateReturn -clutter_keymap_x11_translate_event (ClutterEventTranslator *translator, - gpointer native, - ClutterEvent *event) -{ - ClutterKeymapX11 *keymap_x11 = CLUTTER_KEYMAP_X11 (translator); - ClutterBackendX11 *backend_x11; - ClutterTranslateReturn retval; - XEvent *xevent; - - backend_x11 = CLUTTER_BACKEND_X11 (keymap_x11->backend); - if (!backend_x11->use_xkb) - return CLUTTER_TRANSLATE_CONTINUE; - - xevent = native; - - retval = CLUTTER_TRANSLATE_CONTINUE; - -#ifdef HAVE_XKB - if (xevent->type == keymap_x11->xkb_event_base) - { - XkbEvent *xkb_event = (XkbEvent *) xevent; - - switch (xkb_event->any.xkb_type) - { - case XkbStateNotify: - CLUTTER_NOTE (EVENT, "Updating keyboard state"); - update_direction (keymap_x11, XkbStateGroup (&xkb_event->state)); - update_locked_mods (keymap_x11, xkb_event->state.locked_mods); - retval = CLUTTER_TRANSLATE_REMOVE; - break; - - case XkbNewKeyboardNotify: - case XkbMapNotify: - CLUTTER_NOTE (EVENT, "Updating keyboard mapping"); - XkbRefreshKeyboardMapping (&xkb_event->map); - backend_x11->keymap_serial += 1; - retval = CLUTTER_TRANSLATE_REMOVE; - break; - - default: - break; - } - } -#endif /* HAVE_XKB */ - - return retval; -} - -static void -clutter_event_translator_iface_init (ClutterEventTranslatorIface *iface) -{ - iface->translate_event = clutter_keymap_x11_translate_event; -} - -gint -_clutter_keymap_x11_get_key_group (ClutterKeymapX11 *keymap, - ClutterModifierType state) -{ -#ifdef HAVE_XKB - return XkbGroupForCoreState (state); -#else - return 0; -#endif /* HAVE_XKB */ -} - -gboolean -_clutter_keymap_x11_get_num_lock_state (ClutterKeymapX11 *keymap) -{ - g_return_val_if_fail (CLUTTER_IS_KEYMAP_X11 (keymap), FALSE); - - return keymap->num_lock_state; -} - -gboolean -_clutter_keymap_x11_get_caps_lock_state (ClutterKeymapX11 *keymap) -{ - g_return_val_if_fail (CLUTTER_IS_KEYMAP_X11 (keymap), FALSE); - - return keymap->caps_lock_state; -} - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - -/* XXX - yes, I know that XKeycodeToKeysym() has been deprecated; hopefully, - * this code will never get run on any decent system that is also able to - * run Clutter. I just don't want to copy the implementation inside GDK for - * a fallback path. - */ -static int -translate_keysym (ClutterKeymapX11 *keymap, - guint hardware_keycode) -{ - ClutterBackendX11 *backend_x11; - gint retval; - - backend_x11 = CLUTTER_BACKEND_X11 (keymap->backend); - - retval = XKeycodeToKeysym (backend_x11->xdpy, hardware_keycode, 0); - - return retval; -} - -G_GNUC_END_IGNORE_DEPRECATIONS - -gint -_clutter_keymap_x11_translate_key_state (ClutterKeymapX11 *keymap, - guint hardware_keycode, - ClutterModifierType *modifier_state_p, - ClutterModifierType *mods_p) -{ - ClutterBackendX11 *backend_x11; - ClutterModifierType unconsumed_modifiers = 0; - ClutterModifierType modifier_state = *modifier_state_p; - gint retval; - - g_return_val_if_fail (CLUTTER_IS_KEYMAP_X11 (keymap), 0); - - backend_x11 = CLUTTER_BACKEND_X11 (keymap->backend); - -#ifdef HAVE_XKB - if (backend_x11->use_xkb) - { - XkbDescRec *xkb = get_xkb (keymap); - KeySym tmp_keysym; - - if (XkbTranslateKeyCode (xkb, hardware_keycode, modifier_state, - &unconsumed_modifiers, - &tmp_keysym)) - { - retval = tmp_keysym; - } - else - retval = 0; - } - else -#endif /* HAVE_XKB */ - retval = translate_keysym (keymap, hardware_keycode); - - if (mods_p) - *mods_p = unconsumed_modifiers; - - *modifier_state_p = modifier_state & ~(keymap->num_lock_mask | - keymap->scroll_lock_mask | - LockMask); - - return retval; -} - -gboolean -_clutter_keymap_x11_get_is_modifier (ClutterKeymapX11 *keymap, - gint keycode) -{ - g_return_val_if_fail (CLUTTER_IS_KEYMAP_X11 (keymap), FALSE); - - if (keycode < keymap->min_keycode || keycode > keymap->max_keycode) - return FALSE; - -#ifdef HAVE_XKB - if (CLUTTER_BACKEND_X11 (keymap->backend)->use_xkb) - { - XkbDescRec *xkb = get_xkb (keymap); - - if (xkb->map->modmap && xkb->map->modmap[keycode] != 0) - return TRUE; - } -#endif /* HAVE_XKB */ - - return FALSE; -} - -PangoDirection -_clutter_keymap_x11_get_direction (ClutterKeymapX11 *keymap) -{ - g_return_val_if_fail (CLUTTER_IS_KEYMAP_X11 (keymap), PANGO_DIRECTION_NEUTRAL); - -#ifdef HAVE_XKB - if (CLUTTER_BACKEND_X11 (keymap->backend)->use_xkb) - { - if (!keymap->has_direction) - { - Display *xdisplay = CLUTTER_BACKEND_X11 (keymap->backend)->xdpy; - XkbStateRec state_rec; - - XkbGetState (xdisplay, XkbUseCoreKbd, &state_rec); - update_direction (keymap, XkbStateGroup (&state_rec)); - } - - return keymap->current_direction; - } - else -#endif - return PANGO_DIRECTION_NEUTRAL; -} diff --git a/clutter/clutter/x11/clutter-keymap-x11.h b/clutter/clutter/x11/clutter-keymap-x11.h deleted file mode 100644 index ad673a2a7..000000000 --- a/clutter/clutter/x11/clutter-keymap-x11.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2009 Intel Corp. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Emmanuele Bassi - */ - -#ifndef __CLUTTER_KEYMAP_X11_H__ -#define __CLUTTER_KEYMAP_X11_H__ - -#include -#include -#include - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_KEYMAP_X11 (_clutter_keymap_x11_get_type ()) -#define CLUTTER_KEYMAP_X11(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_KEYMAP_X11, ClutterKeymapX11)) -#define CLUTTER_IS_KEYMAP_X11(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_KEYMAP_X11)) - -typedef struct _ClutterKeymapX11 ClutterKeymapX11; - -GType _clutter_keymap_x11_get_type (void) G_GNUC_CONST; - -gint _clutter_keymap_x11_get_key_group (ClutterKeymapX11 *keymap, - ClutterModifierType state); -gboolean _clutter_keymap_x11_get_num_lock_state (ClutterKeymapX11 *keymap); -gboolean _clutter_keymap_x11_get_caps_lock_state (ClutterKeymapX11 *keymap); -gint _clutter_keymap_x11_translate_key_state (ClutterKeymapX11 *keymap, - guint hardware_keycode, - ClutterModifierType *modifier_state_p, - ClutterModifierType *mods_p); -gboolean _clutter_keymap_x11_get_is_modifier (ClutterKeymapX11 *keymap, - gint keycode); - -PangoDirection _clutter_keymap_x11_get_direction (ClutterKeymapX11 *keymap); - -G_END_DECLS - -#endif /* __CLUTTER_KEYMAP_X11_H__ */ diff --git a/clutter/clutter/x11/clutter-stage-x11.c b/clutter/clutter/x11/clutter-stage-x11.c deleted file mode 100644 index 30747a59d..000000000 --- a/clutter/clutter/x11/clutter-stage-x11.c +++ /dev/null @@ -1,1604 +0,0 @@ -/* Clutter. - * An OpenGL based 'interactive canvas' library. - * Authored By Matthew Allum - * Copyright (C) 2006-2007 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#include "clutter-build-config.h" - -#include -#include - -#ifdef HAVE_UNISTD_H -#include -#endif - -#include - -#include "clutter-backend-x11.h" -#include "clutter-stage-x11.h" -#include "clutter-x11.h" - -#include "clutter-actor-private.h" -#include "clutter-debug.h" -#include "clutter-device-manager-private.h" -#include "clutter-enum-types.h" -#include "clutter-event-translator.h" -#include "clutter-event-private.h" -#include "clutter-feature.h" -#include "clutter-main.h" -#include "clutter-muffin.h" -#include "clutter-paint-volume-private.h" -#include "clutter-private.h" -#include "clutter-stage-private.h" - -#define STAGE_X11_IS_MAPPED(s) ((((ClutterStageX11 *) (s))->wm_state & STAGE_X11_WITHDRAWN) == 0) - -static ClutterStageWindowIface *clutter_stage_window_parent_iface = NULL; - -static void clutter_stage_window_iface_init (ClutterStageWindowIface *iface); -static void clutter_event_translator_iface_init (ClutterEventTranslatorIface *iface); - -static ClutterStageCogl *clutter_x11_get_stage_window_from_window (Window win); - -static GHashTable *clutter_stages_by_xid = NULL; - -#define clutter_stage_x11_get_type _clutter_stage_x11_get_type - -G_DEFINE_TYPE_WITH_CODE (ClutterStageX11, - clutter_stage_x11, - CLUTTER_TYPE_STAGE_COGL, - G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_STAGE_WINDOW, - clutter_stage_window_iface_init) - G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_EVENT_TRANSLATOR, - clutter_event_translator_iface_init)); - -#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */ -#define _NET_WM_STATE_ADD 1 /* add/set property */ -#define _NET_WM_STATE_TOGGLE 2 /* toggle property */ - -#define CLUTTER_STAGE_X11_EVENT_MASK \ - StructureNotifyMask | \ - FocusChangeMask | \ - ExposureMask | \ - PropertyChangeMask | \ - EnterWindowMask | \ - LeaveWindowMask | \ - KeyPressMask | \ - KeyReleaseMask | \ - ButtonPressMask | \ - ButtonReleaseMask | \ - PointerMotionMask - -static void -send_wmspec_change_state (ClutterBackendX11 *backend_x11, - Window window, - Atom state, - gboolean add) -{ - XClientMessageEvent xclient; - - CLUTTER_NOTE (BACKEND, "%s NET_WM state", add ? "adding" : "removing"); - - memset (&xclient, 0, sizeof (xclient)); - - xclient.type = ClientMessage; - xclient.window = window; - xclient.message_type = backend_x11->atom_NET_WM_STATE; - xclient.format = 32; - - xclient.data.l[0] = add ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; - xclient.data.l[1] = state; - xclient.data.l[2] = 0; - xclient.data.l[3] = 0; - xclient.data.l[4] = 0; - - XSendEvent (backend_x11->xdpy, - DefaultRootWindow (backend_x11->xdpy), - False, - SubstructureRedirectMask | SubstructureNotifyMask, - (XEvent *)&xclient); -} - -static void -update_state (ClutterStageX11 *stage_x11, - ClutterBackendX11 *backend_x11, - Atom *state, - gboolean add) -{ - if (add) - { - /* FIXME: This wont work if we support more states */ - XChangeProperty (backend_x11->xdpy, - stage_x11->xwin, - backend_x11->atom_NET_WM_STATE, XA_ATOM, 32, - PropModeReplace, - (unsigned char *) state, 1); - } - else - { - /* FIXME: This wont work if we support more states */ - XDeleteProperty (backend_x11->xdpy, - stage_x11->xwin, - backend_x11->atom_NET_WM_STATE); - } -} - -static void -clutter_stage_x11_fix_window_size (ClutterStageX11 *stage_x11, - gint new_width, - gint new_height) -{ - ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11); - ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend); - - if (stage_x11->xwin != None && !stage_x11->is_foreign_xwin) - { - guint min_width, min_height; - XSizeHints *size_hints; - gboolean resize; - - resize = clutter_stage_get_user_resizable (stage_cogl->wrapper); - - size_hints = XAllocSizeHints(); - - clutter_stage_get_minimum_size (stage_cogl->wrapper, - &min_width, - &min_height); - - if (new_width <= 0) - new_width = min_width; - - if (new_height <= 0) - new_height = min_height; - - size_hints->flags = 0; - - /* If we are going fullscreen then we don't want any - restrictions on the window size */ - if (!stage_x11->fullscreening) - { - if (resize) - { - size_hints->min_width = min_width; - size_hints->min_height = min_height; - size_hints->flags = PMinSize; - } - else - { - size_hints->min_width = new_width; - size_hints->min_height = new_height; - size_hints->max_width = new_width; - size_hints->max_height = new_height; - size_hints->flags = PMinSize | PMaxSize; - } - } - - XSetWMNormalHints (backend_x11->xdpy, stage_x11->xwin, size_hints); - - XFree(size_hints); - } -} - -static void -clutter_stage_x11_set_wm_protocols (ClutterStageX11 *stage_x11) -{ - ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11); - ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend); - Atom protocols[2]; - int n = 0; - - protocols[n++] = backend_x11->atom_WM_DELETE_WINDOW; - protocols[n++] = backend_x11->atom_NET_WM_PING; - - XSetWMProtocols (backend_x11->xdpy, stage_x11->xwin, protocols, n); -} - -static void -clutter_stage_x11_get_geometry (ClutterStageWindow *stage_window, - cairo_rectangle_int_t *geometry) -{ - ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window); - ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11); - ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend); - - geometry->x = geometry->y = 0; - - /* If we're fullscreen, return the size of the display. - * - * FIXME - this is utterly broken for anything that is not a single - * head set up; the window manager will give us the right size in a - * ConfigureNotify, but between the fullscreen signal emission on the - * stage and the following frame, the size returned by the stage will - * be wrong. - */ - if (_clutter_stage_is_fullscreen (stage_cogl->wrapper) && - stage_x11->fullscreening) - { - geometry->width = DisplayWidth (backend_x11->xdpy, backend_x11->xscreen_num); - geometry->height = DisplayHeight (backend_x11->xdpy, backend_x11->xscreen_num); - - return; - } - - geometry->width = stage_x11->xwin_width; - geometry->height = stage_x11->xwin_height; -} - -static void -clutter_stage_x11_resize (ClutterStageWindow *stage_window, - gint width, - gint height) -{ - ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window); - ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11); - ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend); - - if (stage_x11->is_foreign_xwin) - { - /* If this is a foreign window we won't get a ConfigureNotify, - * so we need to manually set the size and queue a relayout on the - * stage here (as is normally done in response to ConfigureNotify). - */ - stage_x11->xwin_width = width; - stage_x11->xwin_height = height; - clutter_actor_queue_relayout (CLUTTER_ACTOR (stage_cogl->wrapper)); - return; - } - - /* If we're going fullscreen, don't mess with the size */ - if (stage_x11->fullscreening) - return; - - if (width == 0 || height == 0) - { - /* Should not happen, if this turns up we need to debug it and - * determine the cleanest way to fix. - */ - g_warning ("X11 stage not allowed to have 0 width or height"); - width = 1; - height = 1; - } - - CLUTTER_NOTE (BACKEND, "New size received: (%d, %d)", width, height); - - if (stage_x11->xwin != None) - { - clutter_stage_x11_fix_window_size (stage_x11, width, height); - - if (width != stage_x11->xwin_width || - height != stage_x11->xwin_height) - { - CLUTTER_NOTE (BACKEND, "%s: XResizeWindow[%x] (%d, %d)", - G_STRLOC, - (unsigned int) stage_x11->xwin, - width, - height); - - /* XXX: in this case we can rely on a subsequent - * ConfigureNotify that will result in the stage - * being reallocated so we don't actively do anything - * to affect the stage allocation here. */ - XResizeWindow (backend_x11->xdpy, - stage_x11->xwin, - width, - height); - } - } - else - { - /* if the backing window hasn't been created yet, we just - * need to store the new window size - */ - stage_x11->xwin_width = width; - stage_x11->xwin_height = height; - } -} - -static inline void -set_wm_pid (ClutterStageX11 *stage_x11) -{ - ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11); - ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend); - long pid; - - if (stage_x11->xwin == None || stage_x11->is_foreign_xwin) - return; - - /* this will take care of WM_CLIENT_MACHINE and WM_LOCALE_NAME */ - XSetWMProperties (backend_x11->xdpy, stage_x11->xwin, - NULL, - NULL, - NULL, 0, - NULL, NULL, NULL); - - pid = getpid (); - XChangeProperty (backend_x11->xdpy, - stage_x11->xwin, - backend_x11->atom_NET_WM_PID, XA_CARDINAL, 32, - PropModeReplace, - (guchar *) &pid, 1); -} - -static inline void -set_wm_title (ClutterStageX11 *stage_x11) -{ - ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11); - ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend); - - if (stage_x11->xwin == None || stage_x11->is_foreign_xwin) - return; - - if (stage_x11->title == NULL) - { - XDeleteProperty (backend_x11->xdpy, - stage_x11->xwin, - backend_x11->atom_NET_WM_NAME); - } - else - { - XChangeProperty (backend_x11->xdpy, - stage_x11->xwin, - backend_x11->atom_NET_WM_NAME, - backend_x11->atom_UTF8_STRING, - 8, - PropModeReplace, - (unsigned char *) stage_x11->title, - (int) strlen (stage_x11->title)); - } -} - -static inline void -set_cursor_visible (ClutterStageX11 *stage_x11) -{ - ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11); - ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend); - - if (stage_x11->xwin == None) - return; - - CLUTTER_NOTE (BACKEND, "setting cursor state ('%s') over stage window (%u)", - stage_x11->is_cursor_visible ? "visible" : "invisible", - (unsigned int) stage_x11->xwin); - - if (stage_x11->is_cursor_visible) - { - XUndefineCursor (backend_x11->xdpy, stage_x11->xwin); - } - else - { - XColor col; - Pixmap pix; - Cursor curs; - - pix = XCreatePixmap (backend_x11->xdpy, stage_x11->xwin, 1, 1, 1); - memset (&col, 0, sizeof (col)); - curs = XCreatePixmapCursor (backend_x11->xdpy, - pix, pix, - &col, &col, - 1, 1); - XFreePixmap (backend_x11->xdpy, pix); - XDefineCursor (backend_x11->xdpy, stage_x11->xwin, curs); - } -} - -static void -clutter_stage_x11_unrealize (ClutterStageWindow *stage_window) -{ - ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window); - ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window); - - if (clutter_stages_by_xid != NULL) - { - CLUTTER_NOTE (BACKEND, "Removing X11 stage 0x%x [%p]", - (unsigned int) stage_x11->xwin, - stage_x11); - - g_hash_table_remove (clutter_stages_by_xid, - GINT_TO_POINTER (stage_x11->xwin)); - } - - /* Clutter still uses part of the deprecated stateful API of Cogl - * (in particulart cogl_set_framebuffer). It means Cogl can keep an - * internal reference to the onscreen object we rendered to. In the - * case of foreign window, we want to avoid this, as we don't know - * what's going to happen to that window. - * - * The following call sets the current Cogl framebuffer to a dummy - * 1x1 one if we're unrealizing the current one, so Cogl doesn't - * keep any reference to the foreign window. - */ - if (cogl_get_draw_framebuffer () == COGL_FRAMEBUFFER (stage_x11->onscreen)) - _clutter_backend_reset_cogl_framebuffer (stage_cogl->backend); - - if (stage_x11->frame_closure) - { - cogl_onscreen_remove_frame_callback (stage_x11->onscreen, - stage_x11->frame_closure); - stage_x11->frame_closure = NULL; - } - - clutter_stage_window_parent_iface->unrealize (stage_window); - - g_list_free (stage_x11->legacy_views); - g_clear_object (&stage_x11->legacy_view); - g_clear_pointer (&stage_x11->onscreen, cogl_object_unref); -} - -static void -_clutter_stage_x11_update_foreign_event_mask (CoglOnscreen *onscreen, - guint32 event_mask, - void *user_data) -{ - ClutterStageX11 *stage_x11 = user_data; - ClutterStageCogl *stage_cogl = user_data; - ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend); - XSetWindowAttributes attrs; - - attrs.event_mask = event_mask | CLUTTER_STAGE_X11_EVENT_MASK; - - XChangeWindowAttributes (backend_x11->xdpy, - stage_x11->xwin, - CWEventMask, - &attrs); -} - -static void -clutter_stage_x11_set_fullscreen (ClutterStageWindow *stage_window, - gboolean is_fullscreen) -{ - ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window); - ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11); - ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend); - ClutterStage *stage = stage_cogl->wrapper; - gboolean was_fullscreen; - - if (stage == NULL || CLUTTER_ACTOR_IN_DESTRUCTION (stage)) - return; - - was_fullscreen = _clutter_stage_is_fullscreen (stage); - is_fullscreen = !!is_fullscreen; - - if (was_fullscreen == is_fullscreen) - return; - - CLUTTER_NOTE (BACKEND, "%ssetting fullscreen", is_fullscreen ? "" : "un"); - - if (is_fullscreen) - { -#if 0 - int width, height; - - /* FIXME: this will do the wrong thing for dual-headed - displays. This will return the size of the combined display - but Metacity (at least) will fullscreen to only one of the - displays. This will cause the actor to report the wrong size - until the ConfigureNotify for the correct size is received */ - width = DisplayWidth (backend_x11->xdpy, backend_x11->xscreen_num); - height = DisplayHeight (backend_x11->xdpy, backend_x11->xscreen_num); -#endif - - /* Set the fullscreen hint so we can retain the old size of the window. */ - stage_x11->fullscreening = TRUE; - - if (stage_x11->xwin != None) - { - /* if the actor is not mapped we resize the stage window to match - * the size of the screen; this is useful for e.g. EGLX to avoid - * a resize when calling clutter_stage_fullscreen() before showing - * the stage - */ - if (!STAGE_X11_IS_MAPPED (stage_x11)) - { - CLUTTER_NOTE (BACKEND, "Fullscreening unmapped stage"); - - update_state (stage_x11, backend_x11, - &backend_x11->atom_NET_WM_STATE_FULLSCREEN, - TRUE); - } - else - { - CLUTTER_NOTE (BACKEND, "Fullscreening mapped stage"); - - /* We need to fix the window size so that it will remove - the maximum and minimum window hints. Otherwise - metacity will honour the restrictions and not - fullscreen correctly. */ - clutter_stage_x11_fix_window_size (stage_x11, -1, -1); - - send_wmspec_change_state (backend_x11, stage_x11->xwin, - backend_x11->atom_NET_WM_STATE_FULLSCREEN, - TRUE); - } - } - else - stage_x11->fullscreen_on_realize = TRUE; - } - else - { - stage_x11->fullscreening = FALSE; - - if (stage_x11->xwin != None) - { - if (!STAGE_X11_IS_MAPPED (stage_x11)) - { - CLUTTER_NOTE (BACKEND, "Un-fullscreening unmapped stage"); - - update_state (stage_x11, backend_x11, - &backend_x11->atom_NET_WM_STATE_FULLSCREEN, - FALSE); - } - else - { - CLUTTER_NOTE (BACKEND, "Un-fullscreening mapped stage"); - - send_wmspec_change_state (backend_x11, - stage_x11->xwin, - backend_x11->atom_NET_WM_STATE_FULLSCREEN, - FALSE); - - /* Fix the window size to restore the minimum/maximum - restriction */ - clutter_stage_x11_fix_window_size (stage_x11, - stage_x11->xwin_width, - stage_x11->xwin_height); - } - } - else - stage_x11->fullscreen_on_realize = FALSE; - } - - /* XXX: Note we rely on the ConfigureNotify mechanism as the common - * mechanism to handle notifications of new X window sizes from the - * X server so we don't actively change the stage viewport here or - * queue a relayout etc. */ -} - -void -_clutter_stage_x11_events_device_changed (ClutterStageX11 *stage_x11, - ClutterInputDevice *device, - ClutterDeviceManager *device_manager) -{ - ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11); - - if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_FLOATING) - _clutter_device_manager_select_stage_events (device_manager, - stage_cogl->wrapper); -} - -static void -stage_events_device_added (ClutterDeviceManager *device_manager, - ClutterInputDevice *device, - gpointer user_data) -{ - ClutterStageWindow *stage_window = user_data; - ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window); - - if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_FLOATING) - _clutter_device_manager_select_stage_events (device_manager, - stage_cogl->wrapper); -} - -static void -frame_cb (CoglOnscreen *onscreen, - CoglFrameEvent frame_event, - CoglFrameInfo *frame_info, - void *user_data) - -{ - ClutterStageCogl *stage_cogl = user_data; - ClutterFrameInfo clutter_frame_info = { - .frame_counter = cogl_frame_info_get_frame_counter (frame_info), - .presentation_time = cogl_frame_info_get_presentation_time (frame_info), - .refresh_rate = cogl_frame_info_get_refresh_rate (frame_info) - }; - - _clutter_stage_cogl_presented (stage_cogl, frame_event, &clutter_frame_info); -} - -void -clutter_stage_x11_update_sync_state (ClutterStage *stage, - SyncMethod method) -{ - ClutterStageWindow *stage_window; - ClutterStageX11 *stage_x11; - gboolean state; - - g_return_if_fail (stage != NULL); - - stage_window = CLUTTER_STAGE_WINDOW (_clutter_stage_get_window (CLUTTER_STAGE (stage))); - stage_x11 = CLUTTER_STAGE_X11 (stage_window); - - g_return_if_fail (stage_x11->onscreen != NULL); - - state = method != SYNC_NONE; - - _clutter_set_sync_to_vblank (state); - cogl_onscreen_set_swap_throttled (stage_x11->onscreen, state); - clutter_master_clock_set_sync_method (method); -} - -static gboolean -clutter_stage_x11_realize (ClutterStageWindow *stage_window) -{ - ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window); - ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window); - ClutterBackend *backend = CLUTTER_BACKEND (stage_cogl->backend); - ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend); - ClutterDeviceManager *device_manager; - gfloat width, height; - SyncMethod sync_method = _clutter_get_sync_method(); - GError *error = NULL; - - clutter_actor_get_size (CLUTTER_ACTOR (stage_cogl->wrapper), &width, &height); - - CLUTTER_NOTE (BACKEND, "Wrapper size: %.2f x %.2f", width, height); - - CLUTTER_NOTE (BACKEND, "Creating a new Cogl onscreen surface: %.2f x %.2f", - width, height); - - stage_x11->onscreen = cogl_onscreen_new (backend->cogl_context, width, height); - - cogl_onscreen_set_swap_throttled (stage_x11->onscreen, - sync_method != SYNC_NONE); - - stage_x11->frame_closure = - cogl_onscreen_add_frame_callback (stage_x11->onscreen, - frame_cb, - stage_cogl, - NULL); - - if (stage_x11->legacy_view) - g_object_set (G_OBJECT (stage_x11->legacy_view), - "framebuffer", stage_x11->onscreen, - NULL); - - /* We just created a window of the size of the actor. No need to fix - the size of the stage, just update it. */ - stage_x11->xwin_width = width; - stage_x11->xwin_height = height; - - if (stage_x11->xwin != None) - { - cogl_x11_onscreen_set_foreign_window_xid (stage_x11->onscreen, - stage_x11->xwin, - _clutter_stage_x11_update_foreign_event_mask, - stage_x11); - - } - - if (!cogl_framebuffer_allocate (stage_x11->onscreen, &error)) - { - g_warning ("Failed to allocate stage: %s", error->message); - g_error_free (error); - cogl_object_unref (stage_x11->onscreen); - abort(); - } - - if (!(clutter_stage_window_parent_iface->realize (stage_window))) - return FALSE; - - if (stage_x11->xwin == None) - stage_x11->xwin = cogl_x11_onscreen_get_window_xid (stage_x11->onscreen); - - if (clutter_stages_by_xid == NULL) - clutter_stages_by_xid = g_hash_table_new (NULL, NULL); - - g_hash_table_insert (clutter_stages_by_xid, - GINT_TO_POINTER (stage_x11->xwin), - stage_x11); - - set_wm_pid (stage_x11); - set_wm_title (stage_x11); - set_cursor_visible (stage_x11); - - /* we unconditionally select input events even with event retrieval - * disabled because we need to guarantee that the Clutter internal - * state is maintained when calling clutter_x11_handle_event() without - * requiring applications or embedding toolkits to select events - * themselves. if we did that, we'd have to document the events to be - * selected, and also update applications and embedding toolkits each - * time we added a new mask, or a new class of events. - * - * see: http://bugzilla.clutter-project.org/show_bug.cgi?id=998 - * for the rationale of why we did conditional selection. it is now - * clear that a compositor should clear out the input region, since - * it cannot assume a perfectly clean slate coming from us. - * - * see: http://bugzilla.clutter-project.org/show_bug.cgi?id=2228 - * for an example of things that break if we do conditional event - * selection. - */ - XSelectInput (backend_x11->xdpy, stage_x11->xwin, CLUTTER_STAGE_X11_EVENT_MASK); - - /* input events also depent on the actual device, so we need to - * use the device manager to let every device select them, using - * the event mask we passed to XSelectInput as the template - */ - device_manager = clutter_device_manager_get_default (); - if (G_UNLIKELY (device_manager != NULL)) - { - _clutter_device_manager_select_stage_events (device_manager, - stage_cogl->wrapper); - - g_signal_connect (device_manager, "device-added", - G_CALLBACK (stage_events_device_added), - stage_window); - } - - clutter_stage_x11_fix_window_size (stage_x11, - stage_x11->xwin_width, - stage_x11->xwin_height); - clutter_stage_x11_set_wm_protocols (stage_x11); - - if (stage_x11->fullscreen_on_realize) - { - stage_x11->fullscreen_on_realize = FALSE; - - clutter_stage_x11_set_fullscreen (stage_window, TRUE); - } - - CLUTTER_NOTE (BACKEND, "Successfully realized stage"); - - return TRUE; -} - -static void -clutter_stage_x11_set_cursor_visible (ClutterStageWindow *stage_window, - gboolean cursor_visible) -{ - ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window); - - stage_x11->is_cursor_visible = !!cursor_visible; - set_cursor_visible (stage_x11); -} - -static void -clutter_stage_x11_set_title (ClutterStageWindow *stage_window, - const gchar *title) -{ - ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window); - - free (stage_x11->title); - stage_x11->title = g_strdup (title); - set_wm_title (stage_x11); -} - -static void -clutter_stage_x11_set_user_resizable (ClutterStageWindow *stage_window, - gboolean is_resizable) -{ - ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window); - - clutter_stage_x11_fix_window_size (stage_x11, - stage_x11->xwin_width, - stage_x11->xwin_height); -} - -static inline void -update_wm_hints (ClutterStageX11 *stage_x11) -{ - ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11); - ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend); - XWMHints wm_hints; - - if (stage_x11->wm_state & STAGE_X11_WITHDRAWN) - return; - - if (stage_x11->is_foreign_xwin) - return; - - wm_hints.flags = StateHint | InputHint; - wm_hints.initial_state = NormalState; - wm_hints.input = stage_x11->accept_focus ? True : False; - - XSetWMHints (backend_x11->xdpy, stage_x11->xwin, &wm_hints); -} - -static void -clutter_stage_x11_set_accept_focus (ClutterStageWindow *stage_window, - gboolean accept_focus) -{ - ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window); - - stage_x11->accept_focus = !!accept_focus; - update_wm_hints (stage_x11); -} - -static void -set_stage_x11_state (ClutterStageX11 *stage_x11, - ClutterStageX11State unset_flags, - ClutterStageX11State set_flags) -{ - ClutterStageX11State new_stage_state, old_stage_state; - - old_stage_state = stage_x11->wm_state; - - new_stage_state = old_stage_state; - new_stage_state |= set_flags; - new_stage_state &= ~unset_flags; - - if (new_stage_state == old_stage_state) - return; - - stage_x11->wm_state = new_stage_state; -} - -static void -clutter_stage_x11_show (ClutterStageWindow *stage_window, - gboolean do_raise) -{ - ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window); - ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11); - ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend); - - if (stage_x11->xwin != None) - { - if (do_raise && !stage_x11->is_foreign_xwin) - { - CLUTTER_NOTE (BACKEND, "Raising stage[%lu]", - (unsigned long) stage_x11->xwin); - XRaiseWindow (backend_x11->xdpy, stage_x11->xwin); - } - - if (!STAGE_X11_IS_MAPPED (stage_x11)) - { - CLUTTER_NOTE (BACKEND, "Mapping stage[%lu]", - (unsigned long) stage_x11->xwin); - - set_stage_x11_state (stage_x11, STAGE_X11_WITHDRAWN, 0); - - update_wm_hints (stage_x11); - - if (stage_x11->fullscreening) - clutter_stage_x11_set_fullscreen (stage_window, TRUE); - else - clutter_stage_x11_set_fullscreen (stage_window, FALSE); - } - - g_assert (STAGE_X11_IS_MAPPED (stage_x11)); - - clutter_actor_map (CLUTTER_ACTOR (stage_cogl->wrapper)); - - if (!stage_x11->is_foreign_xwin) - XMapWindow (backend_x11->xdpy, stage_x11->xwin); - } -} - -static void -clutter_stage_x11_hide (ClutterStageWindow *stage_window) -{ - ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window); - ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11); - ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend); - - if (stage_x11->xwin != None) - { - if (STAGE_X11_IS_MAPPED (stage_x11)) - set_stage_x11_state (stage_x11, 0, STAGE_X11_WITHDRAWN); - - g_assert (!STAGE_X11_IS_MAPPED (stage_x11)); - - clutter_actor_unmap (CLUTTER_ACTOR (stage_cogl->wrapper)); - - if (!stage_x11->is_foreign_xwin) - XWithdrawWindow (backend_x11->xdpy, stage_x11->xwin, 0); - } -} - -static gboolean -clutter_stage_x11_can_clip_redraws (ClutterStageWindow *stage_window) -{ - ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window); - - /* while resizing a window, clipped redraws are disabled in order to - * avoid artefacts. - */ - return stage_x11->clipped_redraws_cool_off == 0; -} - -static void -ensure_legacy_view (ClutterStageWindow *stage_window) -{ - ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window); - cairo_rectangle_int_t view_layout; - CoglFramebuffer *framebuffer; - - if (stage_x11->legacy_view) - return; - - _clutter_stage_window_get_geometry (stage_window, &view_layout); - framebuffer = COGL_FRAMEBUFFER (stage_x11->onscreen); - stage_x11->legacy_view = g_object_new (CLUTTER_TYPE_STAGE_VIEW_COGL, - "layout", &view_layout, - "framebuffer", framebuffer, - NULL); - stage_x11->legacy_views = g_list_append (stage_x11->legacy_views, - stage_x11->legacy_view); -} - -static GList * -clutter_stage_x11_get_views (ClutterStageWindow *stage_window) -{ - ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window); - - ensure_legacy_view (stage_window); - - return stage_x11->legacy_views; -} - -static int64_t -clutter_stage_x11_get_frame_counter (ClutterStageWindow *stage_window) -{ - ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window); - - return cogl_onscreen_get_frame_counter (stage_x11->onscreen); -} - -static void -clutter_stage_x11_finalize (GObject *gobject) -{ - ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (gobject); - - free (stage_x11->title); - - G_OBJECT_CLASS (clutter_stage_x11_parent_class)->finalize (gobject); -} - -static void -clutter_stage_x11_dispose (GObject *gobject) -{ - ClutterEventTranslator *translator = CLUTTER_EVENT_TRANSLATOR (gobject); - ClutterBackend *backend = CLUTTER_STAGE_COGL (gobject)->backend; - - _clutter_backend_remove_event_translator (backend, translator); - - G_OBJECT_CLASS (clutter_stage_x11_parent_class)->dispose (gobject); -} - -static void -clutter_stage_x11_class_init (ClutterStageX11Class *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - gobject_class->finalize = clutter_stage_x11_finalize; - gobject_class->dispose = clutter_stage_x11_dispose; -} - -static void -clutter_stage_x11_init (ClutterStageX11 *stage) -{ - stage->xwin = None; - stage->xwin_width = 640; - stage->xwin_height = 480; - - stage->wm_state = STAGE_X11_WITHDRAWN; - - stage->is_foreign_xwin = FALSE; - stage->fullscreening = FALSE; - stage->is_cursor_visible = TRUE; - stage->accept_focus = TRUE; - - stage->title = NULL; -} - -static void -clutter_stage_window_iface_init (ClutterStageWindowIface *iface) -{ - clutter_stage_window_parent_iface = g_type_interface_peek_parent (iface); - - iface->set_title = clutter_stage_x11_set_title; - iface->set_fullscreen = clutter_stage_x11_set_fullscreen; - iface->set_cursor_visible = clutter_stage_x11_set_cursor_visible; - iface->set_user_resizable = clutter_stage_x11_set_user_resizable; - iface->set_accept_focus = clutter_stage_x11_set_accept_focus; - iface->show = clutter_stage_x11_show; - iface->hide = clutter_stage_x11_hide; - iface->resize = clutter_stage_x11_resize; - iface->get_geometry = clutter_stage_x11_get_geometry; - iface->realize = clutter_stage_x11_realize; - iface->unrealize = clutter_stage_x11_unrealize; - iface->can_clip_redraws = clutter_stage_x11_can_clip_redraws; - iface->get_views = clutter_stage_x11_get_views; - iface->get_frame_counter = clutter_stage_x11_get_frame_counter; -} - -static inline void -set_user_time (ClutterBackendX11 *backend_x11, - ClutterStageX11 *stage_x11, - long timestamp) -{ - if (timestamp != CLUTTER_CURRENT_TIME) - { - XChangeProperty (backend_x11->xdpy, - stage_x11->xwin, - backend_x11->atom_NET_WM_USER_TIME, - XA_CARDINAL, 32, - PropModeReplace, - (unsigned char *) ×tamp, 1); - } -} - -static gboolean -handle_wm_protocols_event (ClutterBackendX11 *backend_x11, - ClutterStageX11 *stage_x11, - XEvent *xevent) -{ - Atom atom = (Atom) xevent->xclient.data.l[0]; - - if (atom == backend_x11->atom_WM_DELETE_WINDOW && - xevent->xany.window == stage_x11->xwin) - { -#ifdef CLUTTER_ENABLE_DEBUG - ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11); - - /* the WM_DELETE_WINDOW is a request: we do not destroy - * the window right away, as it might contain vital data; - * we relay the event to the application and we let it - * handle the request - */ - CLUTTER_NOTE (EVENT, "Delete stage %s[%p], win:0x%x", - _clutter_actor_get_debug_name (CLUTTER_ACTOR (stage_cogl->wrapper)), - stage_cogl->wrapper, - (unsigned int) stage_x11->xwin); -#endif /* CLUTTER_ENABLE_DEBUG */ - - set_user_time (backend_x11, stage_x11, xevent->xclient.data.l[1]); - - return TRUE; - } - else if (atom == backend_x11->atom_NET_WM_PING && - xevent->xany.window == stage_x11->xwin) - { - XClientMessageEvent xclient = xevent->xclient; - - xclient.window = backend_x11->xwin_root; - XSendEvent (backend_x11->xdpy, xclient.window, - False, - SubstructureRedirectMask | SubstructureNotifyMask, - (XEvent *) &xclient); - return FALSE; - } - - /* do not send any of the WM_PROTOCOLS events to the queue */ - return FALSE; -} - -static gboolean -clipped_redraws_cool_off_cb (void *data) -{ - ClutterStageX11 *stage_x11 = data; - - stage_x11->clipped_redraws_cool_off = 0; - - return G_SOURCE_REMOVE; -} - -static ClutterTranslateReturn -clutter_stage_x11_translate_event (ClutterEventTranslator *translator, - gpointer native, - ClutterEvent *event) -{ - ClutterStageX11 *stage_x11; - ClutterStageCogl *stage_cogl; - ClutterTranslateReturn res = CLUTTER_TRANSLATE_CONTINUE; - ClutterBackendX11 *backend_x11; - Window stage_xwindow; - XEvent *xevent = native; - ClutterStage *stage; - - stage_cogl = clutter_x11_get_stage_window_from_window (xevent->xany.window); - if (stage_cogl == NULL) - return CLUTTER_TRANSLATE_CONTINUE; - - stage = stage_cogl->wrapper; - stage_x11 = CLUTTER_STAGE_X11 (stage_cogl); - backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend); - stage_xwindow = stage_x11->xwin; - - switch (xevent->type) - { - case ConfigureNotify: - if (!stage_x11->is_foreign_xwin) - { - gboolean size_changed = FALSE; - int stage_width; - int stage_height; - - CLUTTER_NOTE (BACKEND, "ConfigureNotify[%x] (%d, %d)", - (unsigned int) stage_x11->xwin, - xevent->xconfigure.width, - xevent->xconfigure.height); - - /* When fullscreen, we'll keep the xwin_width/height - variables to track the old size of the window and we'll - assume all ConfigureNotifies constitute a size change */ - if (_clutter_stage_is_fullscreen (stage)) - size_changed = TRUE; - else if ((stage_x11->xwin_width != xevent->xconfigure.width) || - (stage_x11->xwin_height != xevent->xconfigure.height)) - { - size_changed = TRUE; - stage_x11->xwin_width = xevent->xconfigure.width; - stage_x11->xwin_height = xevent->xconfigure.height; - } - - stage_width = xevent->xconfigure.width; - stage_height = xevent->xconfigure.height; - clutter_actor_set_size (CLUTTER_ACTOR (stage), stage_width, stage_height); - - if (size_changed) - { - /* XXX: This is a workaround for a race condition when - * resizing windows while there are in-flight - * glXCopySubBuffer blits happening. - * - * The problem stems from the fact that rectangles for the - * blits are described relative to the bottom left of the - * window and because we can't guarantee control over the X - * window gravity used when resizing so the gravity is - * typically NorthWest not SouthWest. - * - * This means if you grow a window vertically the server - * will make sure to place the old contents of the window - * at the top-left/north-west of your new larger window, but - * that may happen asynchronous to GLX preparing to do a - * blit specified relative to the bottom-left/south-west of - * the window (based on the old smaller window geometry). - * - * When the GLX issued blit finally happens relative to the - * new bottom of your window, the destination will have - * shifted relative to the top-left where all the pixels you - * care about are so it will result in a nasty artefact - * making resizing look very ugly! - * - * We can't currently fix this completely, in-part because - * the window manager tends to trample any gravity we might - * set. This workaround instead simply disables blits for a - * while if we are notified of any resizes happening so if - * the user is resizing a window via the window manager then - * they may see an artefact for one frame but then we will - * fallback to redrawing the full stage until the cooling - * off period is over. - */ - if (stage_x11->clipped_redraws_cool_off) - g_source_remove (stage_x11->clipped_redraws_cool_off); - - stage_x11->clipped_redraws_cool_off = - clutter_threads_add_timeout (1000, - clipped_redraws_cool_off_cb, - stage_x11); - - /* Queue a relayout - we want glViewport to be called - * with the correct values, and this is done in ClutterStage - * via cogl_onscreen_clutter_backend_set_size (). - * - * We queue a relayout, because if this ConfigureNotify is - * in response to a size we set in the application, the - * set_size() call above is essentially a null-op. - * - * Make sure we do this only when the size has changed, - * otherwise we end up relayouting on window moves. - */ - clutter_actor_queue_relayout (CLUTTER_ACTOR (stage)); - - /* the resize process is complete, so we can ask the stage - * to set up the GL viewport with the new size - */ - clutter_stage_ensure_viewport (stage); - - /* If this was a result of the Xrandr change when running as a - * X11 compositing manager, we need to reset the legacy - * stage view, now that it has a new size. - */ - if (stage_x11->legacy_view) - { - cairo_rectangle_int_t view_layout = { - .width = stage_width, - .height = stage_height - }; - - g_object_set (G_OBJECT (stage_x11->legacy_view), - "layout", &view_layout, - NULL); - } - } - } - break; - - case PropertyNotify: - if (xevent->xproperty.atom == backend_x11->atom_NET_WM_STATE && - xevent->xproperty.window == stage_xwindow && - !stage_x11->is_foreign_xwin) - { - Atom type; - gint format; - gulong n_items, bytes_after; - guchar *data = NULL; - gboolean fullscreen_set = FALSE; - - clutter_x11_trap_x_errors (); - XGetWindowProperty (backend_x11->xdpy, stage_xwindow, - backend_x11->atom_NET_WM_STATE, - 0, G_MAXLONG, - False, XA_ATOM, - &type, &format, &n_items, - &bytes_after, &data); - clutter_x11_untrap_x_errors (); - - if (type != None && data != NULL) - { - gboolean is_fullscreen = FALSE; - Atom *atoms = (Atom *) data; - gulong i; - - for (i = 0; i < n_items; i++) - { - if (atoms[i] == backend_x11->atom_NET_WM_STATE_FULLSCREEN) - fullscreen_set = TRUE; - } - - is_fullscreen = _clutter_stage_is_fullscreen (stage_cogl->wrapper); - - if (fullscreen_set != is_fullscreen) - { - if (fullscreen_set) - _clutter_stage_update_state (stage_cogl->wrapper, - 0, - CLUTTER_STAGE_STATE_FULLSCREEN); - else - _clutter_stage_update_state (stage_cogl->wrapper, - CLUTTER_STAGE_STATE_FULLSCREEN, - 0); - } - - XFree (data); - } - } - break; - - case FocusIn: - if (!_clutter_stage_is_activated (stage_cogl->wrapper)) - { - _clutter_stage_update_state (stage_cogl->wrapper, - 0, - CLUTTER_STAGE_STATE_ACTIVATED); - } - break; - - case FocusOut: - if (_clutter_stage_is_activated (stage_cogl->wrapper)) - { - _clutter_stage_update_state (stage_cogl->wrapper, - CLUTTER_STAGE_STATE_ACTIVATED, - 0); - } - break; - - case Expose: - { - XExposeEvent *expose = (XExposeEvent *) xevent; - cairo_rectangle_int_t clip; - - CLUTTER_NOTE (EVENT, - "expose for stage: %s[%p], win:0x%x - " - "redrawing area (x: %d, y: %d, width: %d, height: %d)", - _clutter_actor_get_debug_name (CLUTTER_ACTOR (stage)), - stage, - (unsigned int) stage_xwindow, - expose->x, - expose->y, - expose->width, - expose->height); - - clip.x = expose->x; - clip.y = expose->y; - clip.width = expose->width; - clip.height = expose->height; - clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stage), &clip); - } - break; - - case DestroyNotify: - CLUTTER_NOTE (EVENT, - "Destroy notification received for stage %s[%p], win:0x%x", - _clutter_actor_get_debug_name (CLUTTER_ACTOR (stage)), - stage, - (unsigned int) stage_xwindow); - event->any.type = CLUTTER_DESTROY_NOTIFY; - event->any.stage = stage; - res = CLUTTER_TRANSLATE_QUEUE; - break; - - case ClientMessage: - CLUTTER_NOTE (EVENT, "Client message for stage %s[%p], win:0x%x", - _clutter_actor_get_debug_name (CLUTTER_ACTOR (stage)), - stage, - (unsigned int) stage_xwindow); - if (handle_wm_protocols_event (backend_x11, stage_x11, xevent)) - { - event->any.type = CLUTTER_DELETE; - event->any.stage = stage; - res = CLUTTER_TRANSLATE_QUEUE; - } - break; - - case MappingNotify: - CLUTTER_NOTE (EVENT, "Refresh keyboard mapping"); - XRefreshKeyboardMapping (&xevent->xmapping); - backend_x11->keymap_serial += 1; - res = CLUTTER_TRANSLATE_REMOVE; - break; - - default: - res = CLUTTER_TRANSLATE_CONTINUE; - break; - } - - return res; -} - -static void -clutter_event_translator_iface_init (ClutterEventTranslatorIface *iface) -{ - iface->translate_event = clutter_stage_x11_translate_event; -} - -/** - * clutter_x11_get_stage_window: (skip) - * @stage: a #ClutterStage - * - * Gets the stages X Window. - * - * Return value: An XID for the stage window. - * - * Since: 0.4 - */ -Window -clutter_x11_get_stage_window (ClutterStage *stage) -{ - ClutterStageWindow *impl; - - g_return_val_if_fail (CLUTTER_IS_STAGE (stage), None); - - impl = _clutter_stage_get_window (stage); - g_assert (CLUTTER_IS_STAGE_X11 (impl)); - - return CLUTTER_STAGE_X11 (impl)->xwin; -} - -static ClutterStageCogl * -clutter_x11_get_stage_window_from_window (Window win) -{ - if (clutter_stages_by_xid == NULL) - return NULL; - - return g_hash_table_lookup (clutter_stages_by_xid, - GINT_TO_POINTER (win)); -} - -/** - * clutter_x11_get_stage_from_window: - * @win: an X Window ID - * - * Gets the stage for a particular X window. - * - * Return value: (transfer none): A #ClutterStage, or% NULL if a stage - * does not exist for the window - * - * Since: 0.8 - */ -ClutterStage * -clutter_x11_get_stage_from_window (Window win) -{ - ClutterStageCogl *stage_cogl; - - stage_cogl = clutter_x11_get_stage_window_from_window (win); - - if (stage_cogl != NULL) - return stage_cogl->wrapper; - - return NULL; -} - -/** - * clutter_x11_get_stage_visual: (skip) - * @stage: a #ClutterStage - * - * Returns an XVisualInfo suitable for creating a foreign window for the given - * stage. NOTE: It doesn't do as the name may suggest, which is return the - * XVisualInfo that was used to create an existing window for the given stage. - * - * XXX: It might be best to deprecate this function and replace with something - * along the lines of clutter_backend_x11_get_foreign_visual () or perhaps - * clutter_stage_x11_get_foreign_visual () - * - * Return value: (transfer full): An XVisualInfo suitable for creating a - * foreign stage. Use XFree() to free the returned value instead - * - * Deprecated: 1.2: Use clutter_x11_get_visual_info() instead - * - * Since: 0.4 - */ -XVisualInfo * -clutter_x11_get_stage_visual (ClutterStage *stage) -{ - ClutterBackend *backend = clutter_get_default_backend (); - ClutterBackendX11 *backend_x11; - - g_return_val_if_fail (CLUTTER_IS_BACKEND_X11 (backend), NULL); - backend_x11 = CLUTTER_BACKEND_X11 (backend); - - return _clutter_backend_x11_get_visual_info (backend_x11); -} - -typedef struct { - ClutterStageX11 *stage_x11; - cairo_rectangle_int_t geom; - Window xwindow; - guint destroy_old_xwindow : 1; -} ForeignWindowData; - -static void -set_foreign_window_callback (ClutterActor *actor, - void *data) -{ - ForeignWindowData *fwd = data; - ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (fwd->stage_x11); - ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend); - - CLUTTER_NOTE (BACKEND, "Setting foreign window (0x%x)", - (unsigned int) fwd->xwindow); - - if (fwd->destroy_old_xwindow && fwd->stage_x11->xwin != None) - { - CLUTTER_NOTE (BACKEND, "Destroying previous window (0x%x)", - (unsigned int) fwd->xwindow); - XDestroyWindow (backend_x11->xdpy, fwd->stage_x11->xwin); - } - - fwd->stage_x11->xwin = fwd->xwindow; - fwd->stage_x11->is_foreign_xwin = TRUE; - - fwd->stage_x11->xwin_width = fwd->geom.width; - fwd->stage_x11->xwin_height = fwd->geom.height; - - clutter_actor_set_size (actor, fwd->geom.width, fwd->geom.height); - - if (clutter_stages_by_xid == NULL) - clutter_stages_by_xid = g_hash_table_new (NULL, NULL); - - g_hash_table_insert (clutter_stages_by_xid, - GINT_TO_POINTER (fwd->stage_x11->xwin), - fwd->stage_x11); -} - -/** - * clutter_x11_set_stage_foreign: - * @stage: a #ClutterStage - * @xwindow: an existing X Window id - * - * Target the #ClutterStage to use an existing external X Window - * - * Return value: %TRUE if foreign window is valid - * - * Since: 0.4 - */ -gboolean -clutter_x11_set_stage_foreign (ClutterStage *stage, - Window xwindow) -{ - ClutterBackendX11 *backend_x11; - ClutterStageX11 *stage_x11; - ClutterStageCogl *stage_cogl; - ClutterStageWindow *impl; - ClutterActor *actor; - gint x, y; - guint width, height, border, depth; - Window root_return; - Status status; - ForeignWindowData fwd; - XVisualInfo *xvisinfo; - - g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE); - g_return_val_if_fail (!CLUTTER_ACTOR_IN_DESTRUCTION (stage), FALSE); - g_return_val_if_fail (xwindow != None, FALSE); - - impl = _clutter_stage_get_window (stage); - stage_x11 = CLUTTER_STAGE_X11 (impl); - stage_cogl = CLUTTER_STAGE_COGL (impl); - backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend); - - xvisinfo = _clutter_backend_x11_get_visual_info (backend_x11); - g_return_val_if_fail (xvisinfo != NULL, FALSE); - - clutter_x11_trap_x_errors (); - - status = XGetGeometry (backend_x11->xdpy, xwindow, - &root_return, - &x, &y, - &width, &height, - &border, - &depth); - - if (clutter_x11_untrap_x_errors () || !status) - { - g_critical ("Unable to retrieve the geometry of the foreign window: " - "XGetGeometry() failed (status code: %d)", status); - return FALSE; - } - - if (width == 0 || height == 0) - { - g_warning ("The size of the foreign window is 0x0"); - return FALSE; - } - - if (depth != xvisinfo->depth) - { - g_warning ("The depth of the visual of the foreign window is %d, but " - "Clutter has been initialized to require a visual depth " - "of %d", - depth, - xvisinfo->depth); - return FALSE; - } - - fwd.stage_x11 = stage_x11; - fwd.xwindow = xwindow; - - /* destroy the old Window, if we have one and it's ours */ - if (stage_x11->xwin != None && !stage_x11->is_foreign_xwin) - fwd.destroy_old_xwindow = TRUE; - else - fwd.destroy_old_xwindow = FALSE; - - fwd.geom.x = x; - fwd.geom.y = y; - fwd.geom.width = width; - fwd.geom.height = height; - - actor = CLUTTER_ACTOR (stage); - - _clutter_actor_rerealize (actor, - set_foreign_window_callback, - &fwd); - - /* Queue a relayout - so the stage will be allocated the new - * window size. - * - * Note also that when the stage gets allocated the new - * window size that will result in the stage's - * priv->viewport being changed, which will in turn result - * in the Cogl viewport changing when _clutter_do_redraw - * calls _clutter_stage_maybe_setup_viewport(). - */ - clutter_actor_queue_relayout (actor); - - return TRUE; -} - -void -_clutter_stage_x11_set_user_time (ClutterStageX11 *stage_x11, - guint32 user_time) -{ - ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11); - ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend); - - set_user_time (backend_x11, stage_x11, user_time); -} diff --git a/clutter/clutter/x11/clutter-stage-x11.h b/clutter/clutter/x11/clutter-stage-x11.h deleted file mode 100644 index b6449f643..000000000 --- a/clutter/clutter/x11/clutter-stage-x11.h +++ /dev/null @@ -1,98 +0,0 @@ -/* Clutter. - * An OpenGL based 'interactive canvas' library. - * Authored By Matthew Allum - * Copyright (C) 2006-2007 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __CLUTTER_STAGE_X11_H__ -#define __CLUTTER_STAGE_X11_H__ - -#include -#include -#include -#include - -#include "clutter-backend-x11.h" -#include "cogl/clutter-stage-cogl.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_STAGE_X11 (_clutter_stage_x11_get_type ()) -#define CLUTTER_STAGE_X11(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_STAGE_X11, ClutterStageX11)) -#define CLUTTER_IS_STAGE_X11(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_STAGE_X11)) -#define CLUTTER_STAGE_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_STAGE_X11, ClutterStageX11Class)) -#define CLUTTER_IS_STAGE_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_STAGE_X11)) -#define CLUTTER_STAGE_X11_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_STAGE_X11, ClutterStageX11Class)) - -typedef struct _ClutterStageX11 ClutterStageX11; -typedef struct _ClutterStageX11Class ClutterStageX11Class; - -G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterStageX11, g_object_unref) - -typedef enum -{ - STAGE_X11_WITHDRAWN = 1 << 1 -} ClutterStageX11State; - -struct _ClutterStageX11 -{ - ClutterStageCogl parent_instance; - - CoglOnscreen *onscreen; - Window xwin; - gint xwin_width; - gint xwin_height; /* FIXME target_width / height */ - - ClutterStageView *legacy_view; - GList *legacy_views; - - CoglFrameClosure *frame_closure; - - gchar *title; - - guint clipped_redraws_cool_off; - - ClutterStageX11State wm_state; - - guint is_foreign_xwin : 1; - guint fullscreening : 1; - guint is_cursor_visible : 1; - guint viewport_initialized : 1; - guint accept_focus : 1; - guint fullscreen_on_realize : 1; -}; - -struct _ClutterStageX11Class -{ - ClutterStageCoglClass parent_class; -}; - -CLUTTER_AVAILABLE_IN_MUFFIN -GType _clutter_stage_x11_get_type (void) G_GNUC_CONST; - -void _clutter_stage_x11_events_device_changed (ClutterStageX11 *stage_x11, - ClutterInputDevice *device, - ClutterDeviceManager *device_manager); - -/* Private to subclasses */ -void _clutter_stage_x11_set_user_time (ClutterStageX11 *stage_x11, - guint32 user_time); - -G_END_DECLS - -#endif /* __CLUTTER_STAGE_H__ */ diff --git a/clutter/clutter/x11/clutter-virtual-input-device-x11.c b/clutter/clutter/x11/clutter-virtual-input-device-x11.c deleted file mode 100644 index 416c944b3..000000000 --- a/clutter/clutter/x11/clutter-virtual-input-device-x11.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2016 Red Hat Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Jonas Ådahl - */ - -#ifdef HAVE_CONFIG_H -#include "clutter-build-config.h" -#endif - -#include - -#include "clutter-x11.h" -#include "X11/extensions/XTest.h" - -#include "clutter-virtual-input-device.h" -#include "x11/clutter-virtual-input-device-x11.h" - -struct _ClutterVirtualInputDeviceX11 -{ - ClutterVirtualInputDevice parent; -}; - -G_DEFINE_TYPE (ClutterVirtualInputDeviceX11, - clutter_virtual_input_device_x11, - CLUTTER_TYPE_VIRTUAL_INPUT_DEVICE) - -static void -clutter_virtual_input_device_x11_notify_relative_motion (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - double dx, - double dy) -{ - XTestFakeRelativeMotionEvent (clutter_x11_get_default_display (), - (int) dx, - (int) dy, - 0); -} - -static void -clutter_virtual_input_device_x11_notify_absolute_motion (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - double x, - double y) -{ - XTestFakeMotionEvent (clutter_x11_get_default_display (), - clutter_x11_get_default_screen (), - (int) x, - (int) y, - 0); -} - -static void -clutter_virtual_input_device_x11_notify_button (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - uint32_t button, - ClutterButtonState button_state) -{ - XTestFakeButtonEvent (clutter_x11_get_default_display (), - button, button_state == CLUTTER_BUTTON_STATE_PRESSED, 0); -} - -static void -clutter_virtual_input_device_x11_notify_discrete_scroll (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - ClutterScrollDirection direction, - ClutterScrollSource scroll_source) -{ - Display *xdisplay = clutter_x11_get_default_display (); - int button; - - switch (direction) - { - case CLUTTER_SCROLL_UP: - button = 4; - break; - case CLUTTER_SCROLL_DOWN: - button = 5; - break; - case CLUTTER_SCROLL_LEFT: - button = 6; - break; - case CLUTTER_SCROLL_RIGHT: - button = 7; - break; - default: - g_warn_if_reached (); - return; - } - - XTestFakeButtonEvent (xdisplay, button, True, 0); - XTestFakeButtonEvent (xdisplay, button, False, 0); -} - -static void -clutter_virtual_input_device_x11_notify_scroll_continuous (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - double dx, - double dy, - ClutterScrollSource scroll_source, - ClutterScrollFinishFlags finish_flags) -{ -} - -static void -clutter_virtual_input_device_x11_notify_key (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - uint32_t key, - ClutterKeyState key_state) -{ - XTestFakeKeyEvent (clutter_x11_get_default_display (), - key, key_state == CLUTTER_KEY_STATE_PRESSED, 0); -} - -static void -clutter_virtual_input_device_x11_notify_keyval (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - uint32_t keyval, - ClutterKeyState key_state) -{ - KeyCode keycode; - - keycode = XKeysymToKeycode (clutter_x11_get_default_display (), keyval); - XTestFakeKeyEvent (clutter_x11_get_default_display (), - keycode, key_state == CLUTTER_KEY_STATE_PRESSED, 0); -} - -static void -clutter_virtual_input_device_x11_notify_touch_down (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - int device_slot, - double x, - double y) -{ - g_warning ("Virtual touch motion not implemented under X11"); -} - -static void -clutter_virtual_input_device_x11_notify_touch_motion (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - int device_slot, - double x, - double y) -{ - g_warning ("Virtual touch motion not implemented under X11"); -} - -static void -clutter_virtual_input_device_x11_notify_touch_up (ClutterVirtualInputDevice *virtual_device, - uint64_t time_us, - int device_slot) -{ - g_warning ("Virtual touch motion not implemented under X11"); -} - -static void -clutter_virtual_input_device_x11_init (ClutterVirtualInputDeviceX11 *virtual_device_x11) -{ -} - -static void -clutter_virtual_input_device_x11_class_init (ClutterVirtualInputDeviceX11Class *klass) -{ - ClutterVirtualInputDeviceClass *virtual_input_device_class = - CLUTTER_VIRTUAL_INPUT_DEVICE_CLASS (klass); - - virtual_input_device_class->notify_relative_motion = clutter_virtual_input_device_x11_notify_relative_motion; - virtual_input_device_class->notify_absolute_motion = clutter_virtual_input_device_x11_notify_absolute_motion; - virtual_input_device_class->notify_button = clutter_virtual_input_device_x11_notify_button; - virtual_input_device_class->notify_discrete_scroll = clutter_virtual_input_device_x11_notify_discrete_scroll; - virtual_input_device_class->notify_scroll_continuous = clutter_virtual_input_device_x11_notify_scroll_continuous; - virtual_input_device_class->notify_key = clutter_virtual_input_device_x11_notify_key; - virtual_input_device_class->notify_keyval = clutter_virtual_input_device_x11_notify_keyval; - virtual_input_device_class->notify_touch_down = clutter_virtual_input_device_x11_notify_touch_down; - virtual_input_device_class->notify_touch_motion = clutter_virtual_input_device_x11_notify_touch_motion; - virtual_input_device_class->notify_touch_up = clutter_virtual_input_device_x11_notify_touch_up; -} diff --git a/clutter/clutter/x11/clutter-x11-texture-pixmap.c b/clutter/clutter/x11/clutter-x11-texture-pixmap.c deleted file mode 100644 index 7c1152f06..000000000 --- a/clutter/clutter/x11/clutter-x11-texture-pixmap.c +++ /dev/null @@ -1,1270 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2007 OpenedHand - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Authors: - * Johan Bilien - * Neil Roberts - */ - -/** - * SECTION:clutter-x11-texture-pixmap - * @Title: ClutterX11TexturePixmap - * @short_description: A texture which displays the content of an X Pixmap. - * - * #ClutterX11TexturePixmap is a class for displaying the content of an - * X Pixmap as a ClutterActor. Used together with the X Composite extension, - * it allows to display the content of X Windows inside Clutter. - * - * The class uses the GLX_EXT_texture_from_pixmap OpenGL extension - * (http://people.freedesktop.org/~davidr/GLX_EXT_texture_from_pixmap.txt) - * if available - */ - -#ifdef HAVE_CONFIG_H -#include "clutter-build-config.h" -#endif - -#define CLUTTER_ENABLE_EXPERIMENTAL_API -#define CLUTTER_DISABLE_DEPRECATION_WARNINGS - -#include "clutter-x11-texture-pixmap.h" -#include "clutter-x11.h" -#include "clutter-backend-x11.h" - -#include "clutter-actor-private.h" -#include "clutter-marshal.h" -#include "clutter-paint-volume-private.h" -#include "clutter-private.h" - -#include - -#include - -#include - -#if HAVE_XCOMPOSITE -#include -#endif - -enum -{ - PROP_PIXMAP = 1, - PROP_PIXMAP_WIDTH, - PROP_PIXMAP_HEIGHT, - PROP_DEPTH, - PROP_AUTO, - PROP_WINDOW, - PROP_WINDOW_REDIRECT_AUTOMATIC, - PROP_WINDOW_MAPPED, - PROP_DESTROYED, - PROP_WINDOW_X, - PROP_WINDOW_Y, - PROP_WINDOW_OVERRIDE_REDIRECT -}; - -enum -{ - UPDATE_AREA, - QUEUE_DAMAGE_REDRAW, - - /* FIXME: Pixmap lost signal? */ - LAST_SIGNAL -}; - -static ClutterX11FilterReturn -on_x_event_filter (XEvent *xev, ClutterEvent *cev, gpointer data); - -static void -clutter_x11_texture_pixmap_update_area_real (ClutterX11TexturePixmap *texture, - gint x, - gint y, - gint width, - gint height); -static void -clutter_x11_texture_pixmap_sync_window_internal (ClutterX11TexturePixmap *texture, - int x, - int y, - int width, - int height, - gboolean override_redirect); -static void -clutter_x11_texture_pixmap_set_mapped (ClutterX11TexturePixmap *texture, gboolean mapped); -static void -clutter_x11_texture_pixmap_destroyed (ClutterX11TexturePixmap *texture); - -static guint signals[LAST_SIGNAL] = { 0, }; - -struct _ClutterX11TexturePixmapPrivate -{ - Window window; - Pixmap pixmap; - guint pixmap_width, pixmap_height; - guint depth; - - Damage damage; - - gint window_x, window_y; - gint window_width, window_height; - - guint window_redirect_automatic : 1; - /* FIXME: this is inconsistently either whether the window is mapped or whether - * it is viewable, and isn't updated correctly. */ - guint window_mapped : 1; - guint destroyed : 1; - guint owns_pixmap : 1; - guint override_redirect : 1; - guint automatic_updates : 1; -}; - -static int _damage_event_base = 0; - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterX11TexturePixmap, - clutter_x11_texture_pixmap, - CLUTTER_TYPE_TEXTURE) - -static gboolean -check_extensions (ClutterX11TexturePixmap *texture) -{ - int damage_error; - Display *dpy; - - if (_damage_event_base) - return TRUE; - - dpy = clutter_x11_get_default_display(); - - if (!XDamageQueryExtension (dpy, &_damage_event_base, &damage_error)) - { - g_warning ("No Damage extension"); - return FALSE; - } - - return TRUE; -} - -static void -process_damage_event (ClutterX11TexturePixmap *texture, - XDamageNotifyEvent *damage_event) -{ - /* Cogl will deal with updating the texture and subtracting from the - damage region so we only need to queue a redraw */ - g_signal_emit (texture, signals[QUEUE_DAMAGE_REDRAW], - 0, - damage_event->area.x, - damage_event->area.y, - damage_event->area.width, - damage_event->area.height); -} - -static ClutterX11FilterReturn -on_x_event_filter (XEvent *xev, ClutterEvent *cev, gpointer data) -{ - ClutterX11TexturePixmap *texture; - ClutterX11TexturePixmapPrivate *priv; - - texture = CLUTTER_X11_TEXTURE_PIXMAP (data); - - g_return_val_if_fail (CLUTTER_X11_IS_TEXTURE_PIXMAP (texture), \ - CLUTTER_X11_FILTER_CONTINUE); - - priv = texture->priv; - - if (xev->type == _damage_event_base + XDamageNotify) - { - XDamageNotifyEvent *dev = (XDamageNotifyEvent*)xev; - - if (dev->damage != priv->damage) - return CLUTTER_X11_FILTER_CONTINUE; - - process_damage_event (texture, dev); - } - - return CLUTTER_X11_FILTER_CONTINUE; -} - -static ClutterX11FilterReturn -on_x_event_filter_too (XEvent *xev, ClutterEvent *cev, gpointer data) -{ - ClutterX11TexturePixmap *texture; - ClutterX11TexturePixmapPrivate *priv; - - texture = CLUTTER_X11_TEXTURE_PIXMAP (data); - - g_return_val_if_fail (CLUTTER_X11_IS_TEXTURE_PIXMAP (texture), \ - CLUTTER_X11_FILTER_CONTINUE); - - priv = texture->priv; - - if (xev->xany.window != priv->window) - return CLUTTER_X11_FILTER_CONTINUE; - - switch (xev->type) { - case MapNotify: - clutter_x11_texture_pixmap_sync_window_internal (texture, - priv->window_x, - priv->window_y, - priv->window_width, - priv->window_height, - priv->override_redirect); - break; - case ConfigureNotify: - clutter_x11_texture_pixmap_sync_window_internal (texture, - xev->xconfigure.x, - xev->xconfigure.y, - xev->xconfigure.width, - xev->xconfigure.height, - xev->xconfigure.override_redirect); - break; - case UnmapNotify: - clutter_x11_texture_pixmap_set_mapped (texture, FALSE); - break; - case DestroyNotify: - clutter_x11_texture_pixmap_destroyed (texture); - break; - default: - break; - } - - return CLUTTER_X11_FILTER_CONTINUE; -} - -static void -update_pixmap_damage_object (ClutterX11TexturePixmap *texture) -{ - ClutterX11TexturePixmapPrivate *priv = texture->priv; - CoglHandle cogl_texture; - - /* If we already have a CoglTexturePixmapX11 then update its - damage object */ - cogl_texture = - clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (texture)); - - if (cogl_texture && cogl_is_texture_pixmap_x11 (cogl_texture)) - { - if (priv->damage) - { - const CoglTexturePixmapX11ReportLevel report_level = - COGL_TEXTURE_PIXMAP_X11_DAMAGE_BOUNDING_BOX; - cogl_texture_pixmap_x11_set_damage_object (cogl_texture, - priv->damage, - report_level); - } - else - cogl_texture_pixmap_x11_set_damage_object (cogl_texture, 0, 0); - } -} - -static void -create_damage_resources (ClutterX11TexturePixmap *texture) -{ - ClutterX11TexturePixmapPrivate *priv; - Display *dpy; - - priv = texture->priv; - dpy = clutter_x11_get_default_display(); - - if (!priv->pixmap) - return; - - clutter_x11_trap_x_errors (); - - priv->damage = XDamageCreate (dpy, - priv->pixmap, - XDamageReportBoundingBox); - - /* Errors here might occur if the window is already destroyed, we - * simply skip processing damage and assume that the texture pixmap - * will be cleaned up by the app when it gets a DestroyNotify. - */ - XSync (dpy, FALSE); - clutter_x11_untrap_x_errors (); - - if (priv->damage) - { - clutter_x11_add_filter (on_x_event_filter, (gpointer)texture); - - update_pixmap_damage_object (texture); - } -} - -static void -free_damage_resources (ClutterX11TexturePixmap *texture) -{ - ClutterX11TexturePixmapPrivate *priv; - Display *dpy; - - priv = texture->priv; - dpy = clutter_x11_get_default_display(); - - if (priv->damage) - { - clutter_x11_trap_x_errors (); - XDamageDestroy (dpy, priv->damage); - XSync (dpy, FALSE); - clutter_x11_untrap_x_errors (); - priv->damage = None; - - clutter_x11_remove_filter (on_x_event_filter, (gpointer)texture); - - update_pixmap_damage_object (texture); - } -} - -static gboolean -clutter_x11_texture_pixmap_get_paint_volume (ClutterActor *self, - ClutterPaintVolume *volume) -{ - return clutter_paint_volume_set_from_allocation (volume, self); -} - -static void -clutter_x11_texture_pixmap_real_queue_damage_redraw ( - ClutterX11TexturePixmap *texture, - gint x, - gint y, - gint width, - gint height) -{ - ClutterX11TexturePixmapPrivate *priv = texture->priv; - ClutterActor *self = CLUTTER_ACTOR (texture); - ClutterActorBox allocation; - float scale_x, scale_y; - cairo_rectangle_int_t clip; - - /* NB: clutter_actor_queue_clipped_redraw expects a box in the actor's - * coordinate space so we need to convert from pixmap coordinates to - * actor coordinates... - */ - - /* Calling clutter_actor_get_allocation_box() is enormously expensive - * if the actor has an out-of-date allocation, since it triggers - * a full redraw. clutter_actor_queue_clipped_redraw() would redraw - * the whole stage anyways in that case, so just go ahead and do - * it here. - */ - if (!clutter_actor_has_allocation (self)) - { - clutter_actor_queue_redraw (self); - return; - } - - if (priv->pixmap_width == 0 || priv->pixmap_height == 0) - return; - - clutter_actor_get_allocation_box (self, &allocation); - - scale_x = (allocation.x2 - allocation.x1) / priv->pixmap_width; - scale_y = (allocation.y2 - allocation.y1) / priv->pixmap_height; - - clip.x = x * scale_x; - clip.y = y * scale_y; - clip.width = width * scale_x; - clip.height = height * scale_y; - clutter_actor_queue_redraw_with_clip (self, &clip); -} - -static void -clutter_x11_texture_pixmap_init (ClutterX11TexturePixmap *self) -{ - self->priv = clutter_x11_texture_pixmap_get_instance_private (self); - - if (!check_extensions (self)) - { - /* FIMXE: means display lacks needed extensions for at least auto. - * - a _can_autoupdate() method ? - */ - } - - self->priv->automatic_updates = FALSE; - self->priv->damage = None; - self->priv->window = None; - self->priv->pixmap = None; - self->priv->pixmap_height = 0; - self->priv->pixmap_width = 0; - self->priv->window_redirect_automatic = TRUE; - self->priv->window_mapped = FALSE; - self->priv->destroyed = FALSE; - self->priv->override_redirect = FALSE; - self->priv->window_x = 0; - self->priv->window_y = 0; -} - -static void -clutter_x11_texture_pixmap_dispose (GObject *object) -{ - ClutterX11TexturePixmap *texture = CLUTTER_X11_TEXTURE_PIXMAP (object); - - free_damage_resources (texture); - - clutter_x11_remove_filter (on_x_event_filter_too, (gpointer)texture); - clutter_x11_texture_pixmap_set_pixmap (texture, None); - - G_OBJECT_CLASS (clutter_x11_texture_pixmap_parent_class)->dispose (object); -} - -static void -clutter_x11_texture_pixmap_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterX11TexturePixmap *texture = CLUTTER_X11_TEXTURE_PIXMAP (object); - ClutterX11TexturePixmapPrivate *priv = texture->priv; - - switch (prop_id) - { - case PROP_PIXMAP: - clutter_x11_texture_pixmap_set_pixmap (texture, - g_value_get_ulong (value)); - break; - case PROP_AUTO: - clutter_x11_texture_pixmap_set_automatic (texture, - g_value_get_boolean (value)); - break; - case PROP_WINDOW: - clutter_x11_texture_pixmap_set_window (texture, - g_value_get_ulong (value), - priv->window_redirect_automatic); - break; - case PROP_WINDOW_REDIRECT_AUTOMATIC: - { - gboolean new; - new = g_value_get_boolean (value); - - /* Change the update mode.. */ - if (new != priv->window_redirect_automatic && priv->window) - clutter_x11_texture_pixmap_set_window (texture, priv->window, new); - - priv->window_redirect_automatic = new; - } - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -clutter_x11_texture_pixmap_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterX11TexturePixmap *texture = CLUTTER_X11_TEXTURE_PIXMAP (object); - ClutterX11TexturePixmapPrivate *priv = texture->priv; - - switch (prop_id) - { - case PROP_PIXMAP: - g_value_set_ulong (value, priv->pixmap); - break; - case PROP_PIXMAP_WIDTH: - g_value_set_uint (value, priv->pixmap_width); - break; - case PROP_PIXMAP_HEIGHT: - g_value_set_uint (value, priv->pixmap_height); - break; - case PROP_DEPTH: - g_value_set_uint (value, priv->depth); - break; - case PROP_AUTO: - g_value_set_boolean (value, priv->automatic_updates); - break; - case PROP_WINDOW: - g_value_set_ulong (value, priv->window); - break; - case PROP_WINDOW_REDIRECT_AUTOMATIC: - g_value_set_boolean (value, priv->window_redirect_automatic); - break; - case PROP_WINDOW_MAPPED: - g_value_set_boolean (value, priv->window_mapped); - break; - case PROP_DESTROYED: - g_value_set_boolean (value, priv->destroyed); - break; - case PROP_WINDOW_X: - g_value_set_int (value, priv->window_x); - break; - case PROP_WINDOW_Y: - g_value_set_int (value, priv->window_y); - break; - case PROP_WINDOW_OVERRIDE_REDIRECT: - g_value_set_boolean (value, priv->override_redirect); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -clutter_x11_texture_pixmap_class_init (ClutterX11TexturePixmapClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); - GParamSpec *pspec; - - actor_class->get_paint_volume = clutter_x11_texture_pixmap_get_paint_volume; - - object_class->dispose = clutter_x11_texture_pixmap_dispose; - object_class->set_property = clutter_x11_texture_pixmap_set_property; - object_class->get_property = clutter_x11_texture_pixmap_get_property; - - klass->update_area = clutter_x11_texture_pixmap_update_area_real; - - pspec = g_param_spec_ulong ("pixmap", - P_("Pixmap"), - P_("The X11 Pixmap to be bound"), - 0, G_MAXULONG, - None, - G_PARAM_READWRITE); - - g_object_class_install_property (object_class, PROP_PIXMAP, pspec); - - pspec = g_param_spec_uint ("pixmap-width", - P_("Pixmap width"), - P_("The width of the pixmap bound to this texture"), - 0, G_MAXUINT, - 0, - G_PARAM_READABLE); - - g_object_class_install_property (object_class, PROP_PIXMAP_WIDTH, pspec); - - pspec = g_param_spec_uint ("pixmap-height", - P_("Pixmap height"), - P_("The height of the pixmap bound to this texture"), - 0, G_MAXUINT, - 0, - G_PARAM_READABLE); - - g_object_class_install_property (object_class, PROP_PIXMAP_HEIGHT, pspec); - - pspec = g_param_spec_uint ("pixmap-depth", - P_("Pixmap Depth"), - P_("The depth (in number of bits) of the pixmap bound to this texture"), - 0, G_MAXUINT, - 0, - G_PARAM_READABLE); - - g_object_class_install_property (object_class, PROP_DEPTH, pspec); - - pspec = g_param_spec_boolean ("automatic-updates", - P_("Automatic Updates"), - P_("If the texture should be kept in " - "sync with any pixmap changes."), - FALSE, - G_PARAM_READWRITE); - - g_object_class_install_property (object_class, PROP_AUTO, pspec); - - pspec = g_param_spec_ulong ("window", - P_("Window"), - P_("The X11 Window to be bound"), - 0, G_MAXULONG, - None, - G_PARAM_READWRITE); - - g_object_class_install_property (object_class, PROP_WINDOW, pspec); - - pspec = g_param_spec_boolean ("window-redirect-automatic", - P_("Window Redirect Automatic"), - P_("If composite window redirects are set to " - "Automatic (or Manual if false)"), - TRUE, - G_PARAM_READWRITE); - - g_object_class_install_property (object_class, - PROP_WINDOW_REDIRECT_AUTOMATIC, pspec); - - - pspec = g_param_spec_boolean ("window-mapped", - P_("Window Mapped"), - P_("If window is mapped"), - FALSE, - G_PARAM_READABLE); - - g_object_class_install_property (object_class, - PROP_WINDOW_MAPPED, pspec); - - - pspec = g_param_spec_boolean ("destroyed", - P_("Destroyed"), - P_("If window has been destroyed"), - FALSE, - G_PARAM_READABLE); - - g_object_class_install_property (object_class, - PROP_DESTROYED, pspec); - - pspec = g_param_spec_int ("window-x", - P_("Window X"), - P_("X position of window on screen according to X11"), - G_MININT, G_MAXINT, 0, G_PARAM_READABLE); - - g_object_class_install_property (object_class, - PROP_WINDOW_X, pspec); - - - pspec = g_param_spec_int ("window-y", - P_("Window Y"), - P_("Y position of window on screen according to X11"), - G_MININT, G_MAXINT, 0, G_PARAM_READABLE); - - g_object_class_install_property (object_class, - PROP_WINDOW_Y, pspec); - - pspec = g_param_spec_boolean ("window-override-redirect", - P_("Window Override Redirect"), - P_("If this is an override-redirect window"), - FALSE, - G_PARAM_READABLE); - - g_object_class_install_property (object_class, - PROP_WINDOW_OVERRIDE_REDIRECT, pspec); - - - /** - * ClutterX11TexturePixmap::update-area: - * @texture: the object which received the signal - * @x: X coordinate of the area to update - * @y: Y coordinate of the area to update - * @width: width of the area to update - * @height: height of the area to update - * - * The ::update-area signal is emitted to ask the texture to update its - * content from its source pixmap. - * - * Since: 0.8 - */ - signals[UPDATE_AREA] = - g_signal_new (g_intern_static_string ("update-area"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (ClutterX11TexturePixmapClass, \ - update_area), - NULL, NULL, - _clutter_marshal_VOID__INT_INT_INT_INT, - G_TYPE_NONE, 4, - G_TYPE_INT, - G_TYPE_INT, - G_TYPE_INT, - G_TYPE_INT); - - /** - * ClutterX11TexturePixmap::queue-damage-redraw: - * @texture: the object which received the signal - * @x: The top left x position of the damage region - * @y: The top left y position of the damage region - * @width: The width of the damage region - * @height: The height of the damage region - * - * ::queue-damage-redraw is emitted to notify that some sub-region - * of the texture has been changed (either by an automatic damage - * update or by an explicit call to - * clutter_x11_texture_pixmap_update_area). This usually means a - * redraw needs to be queued for the actor. - * - * The default handler will queue a clipped redraw in response to - * the damage, using the assumption that the pixmap is being painted - * to a rectangle covering the transformed allocation of the actor. - * If you sub-class and change the paint method so this isn't true - * then you must also provide your own damage signal handler to - * queue a redraw that blocks this default behaviour. - * - * Since: 1.2 - */ - signals[QUEUE_DAMAGE_REDRAW] = - g_signal_new (g_intern_static_string ("queue-damage-redraw"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_FIRST, - 0, - NULL, NULL, - _clutter_marshal_VOID__INT_INT_INT_INT, - G_TYPE_NONE, 4, - G_TYPE_INT, - G_TYPE_INT, - G_TYPE_INT, - G_TYPE_INT); - - g_signal_override_class_handler ("queue-damage-redraw", - CLUTTER_X11_TYPE_TEXTURE_PIXMAP, - G_CALLBACK (clutter_x11_texture_pixmap_real_queue_damage_redraw)); -} - -static void -clutter_x11_texture_pixmap_update_area_real (ClutterX11TexturePixmap *texture, - gint x, - gint y, - gint width, - gint height) -{ - CoglHandle cogl_texture; - - cogl_texture = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (texture)); - - if (cogl_texture) - cogl_texture_pixmap_x11_update_area (cogl_texture, x, y, width, height); -} - -/** - * clutter_x11_texture_pixmap_new: - * - * Creates a new #ClutterX11TexturePixmap which can be used to display the - * contents of an X11 Pixmap inside a Clutter scene graph - * - * Return value: A new #ClutterX11TexturePixmap - * - * Since: 0.8 - */ -ClutterActor * -clutter_x11_texture_pixmap_new (void) -{ - ClutterActor *actor; - - actor = g_object_new (CLUTTER_X11_TYPE_TEXTURE_PIXMAP, NULL); - - return actor; -} - -/** - * clutter_x11_texture_pixmap_new_with_pixmap: - * @pixmap: the X Pixmap to which this texture should be bound - * - * Creates a new #ClutterX11TexturePixmap for @pixmap - * - * Return value: A new #ClutterX11TexturePixmap bound to the given X Pixmap - * - * Since: 0.8 - */ -ClutterActor * -clutter_x11_texture_pixmap_new_with_pixmap (Pixmap pixmap) -{ - ClutterActor *actor; - - actor = g_object_new (CLUTTER_X11_TYPE_TEXTURE_PIXMAP, - "pixmap", pixmap, - NULL); - - return actor; -} - -/** - * clutter_x11_texture_pixmap_new_with_window: - * @window: the X window to which this texture should be bound - * - * Creates a new #ClutterX11TexturePixmap for @window - * - * Return value: A new #ClutterX11TexturePixmap bound to the given X window. - * - * Since: 0.8 - **/ -ClutterActor * -clutter_x11_texture_pixmap_new_with_window (Window window) -{ - ClutterActor *actor; - - actor = g_object_new (CLUTTER_X11_TYPE_TEXTURE_PIXMAP, - "window", window, - NULL); - - return actor; -} - -/** - * clutter_x11_texture_pixmap_set_pixmap: - * @texture: the texture to bind - * @pixmap: the X Pixmap to which the texture should be bound - * - * Sets the X Pixmap to which the texture should be bound. - * - * Since: 0.8 - */ -void -clutter_x11_texture_pixmap_set_pixmap (ClutterX11TexturePixmap *texture, - Pixmap pixmap) -{ - Window root; - int x, y; - unsigned int width, height, border_width, depth; - Status status = 0; - gboolean new_pixmap = FALSE, new_pixmap_width = FALSE; - gboolean new_pixmap_height = FALSE, new_pixmap_depth = FALSE; - CoglPipeline *pipeline; - - ClutterX11TexturePixmapPrivate *priv; - - g_return_if_fail (CLUTTER_X11_IS_TEXTURE_PIXMAP (texture)); - - priv = texture->priv; - - /* Get rid of the existing Cogl texture early because it may try to - use the pixmap which we might destroy */ - pipeline = (CoglPipeline *) - clutter_texture_get_cogl_material (CLUTTER_TEXTURE (texture)); - if (pipeline) - cogl_pipeline_set_layer_texture (pipeline, 0, NULL); - - if (pixmap != None) - { - clutter_x11_trap_x_errors (); - status = XGetGeometry (clutter_x11_get_default_display(), - (Drawable)pixmap, - &root, - &x, - &y, - &width, - &height, - &border_width, - &depth); - - if (clutter_x11_untrap_x_errors () || status == 0) - { - g_warning ("Unable to query pixmap: %lx", pixmap); - pixmap = None; - width = height = depth = 0; - } - } - else - { - width = height = depth = 0; - } - - if (priv->pixmap != pixmap) - { - if (priv->pixmap && priv->owns_pixmap) - XFreePixmap (clutter_x11_get_default_display (), priv->pixmap); - - priv->pixmap = pixmap; - new_pixmap = TRUE; - - /* The damage object is created on the pixmap, so it needs to be - * recreated with a change in pixmap. - */ - if (priv->automatic_updates) - { - free_damage_resources (texture); - create_damage_resources (texture); - } - } - - if (priv->pixmap_width != width) - { - priv->pixmap_width = width; - new_pixmap_width = TRUE; - } - - if (priv->pixmap_height != height) - { - priv->pixmap_height = height; - new_pixmap_height = TRUE; - } - - if (priv->depth != depth) - { - priv->depth = depth; - new_pixmap_depth = TRUE; - } - - /* NB: We defer sending the signals until updating all the - * above members so the values are all available to the - * signal handlers. */ - g_object_ref (texture); - - if (new_pixmap) - g_object_notify (G_OBJECT (texture), "pixmap"); - if (new_pixmap_width) - g_object_notify (G_OBJECT (texture), "pixmap-width"); - if (new_pixmap_height) - g_object_notify (G_OBJECT (texture), "pixmap-height"); - if (new_pixmap_depth) - g_object_notify (G_OBJECT (texture), "pixmap-depth"); - - if (pixmap) - { - CoglContext *ctx = - clutter_backend_get_cogl_context (clutter_get_default_backend ()); - GError *error = NULL; - CoglTexturePixmapX11 *texture_pixmap = - cogl_texture_pixmap_x11_new (ctx, pixmap, FALSE, &error); - if (texture_pixmap) - { - clutter_texture_set_cogl_texture (CLUTTER_TEXTURE (texture), - COGL_TEXTURE (texture_pixmap)); - cogl_object_unref (texture_pixmap); - update_pixmap_damage_object (texture); - } - else - { - g_warning ("Failed to create CoglTexturePixmapX11: %s", - error->message); - g_error_free (error); - } - } - - /* - * Keep ref until here in case a notify causes removal from the scene; can't - * lower the notifies because glx's notify handler needs to run before - * update_area - */ - g_object_unref (texture); -} - -/** - * clutter_x11_texture_pixmap_set_window: - * @texture: the texture to bind - * @window: the X window to which the texture should be bound - * @automatic: %TRUE for automatic window updates, %FALSE for manual. - * - * Sets up a suitable pixmap for the window, using the composite and damage - * extensions if possible, and then calls - * clutter_x11_texture_pixmap_set_pixmap(). - * - * If you want to display a window in a #ClutterTexture, you probably want - * this function, or its older sister, clutter_glx_texture_pixmap_set_window(). - * - * This function has no effect unless the XComposite extension is available. - * - * Since: 0.8 - */ -void -clutter_x11_texture_pixmap_set_window (ClutterX11TexturePixmap *texture, - Window window, - gboolean automatic) -{ - ClutterX11TexturePixmapPrivate *priv; - XWindowAttributes attr; - Display *dpy; - - g_return_if_fail (CLUTTER_X11_IS_TEXTURE_PIXMAP (texture)); - - if (!clutter_x11_has_composite_extension ()) - return; - - dpy = clutter_x11_get_default_display (); - if (dpy == NULL) - return; - -#if HAVE_XCOMPOSITE - priv = texture->priv; - - if (priv->window == window && automatic == priv->window_redirect_automatic) - return; - - if (priv->window) - { - clutter_x11_remove_filter (on_x_event_filter_too, (gpointer)texture); - clutter_x11_trap_x_errors (); - XCompositeUnredirectWindow(clutter_x11_get_default_display (), - priv->window, - priv->window_redirect_automatic ? - CompositeRedirectAutomatic : CompositeRedirectManual); - XSync (clutter_x11_get_default_display (), False); - clutter_x11_untrap_x_errors (); - - clutter_x11_texture_pixmap_set_pixmap (texture, None); - } - - priv->window = window; - priv->window_redirect_automatic = automatic; - priv->window_mapped = FALSE; - priv->destroyed = FALSE; - - if (window == None) - return; - - clutter_x11_trap_x_errors (); - { - if (!XGetWindowAttributes (dpy, window, &attr)) - { - XSync (dpy, False); - clutter_x11_untrap_x_errors (); - g_warning ("bad window 0x%x", (guint32)window); - priv->window = None; - return; - } - - XCompositeRedirectWindow - (dpy, - window, - automatic ? - CompositeRedirectAutomatic : CompositeRedirectManual); - XSync (dpy, False); - } - - clutter_x11_untrap_x_errors (); - - XSelectInput (dpy, priv->window, - attr.your_event_mask | StructureNotifyMask); - clutter_x11_add_filter (on_x_event_filter_too, (gpointer)texture); - - g_object_ref (texture); - g_object_notify (G_OBJECT (texture), "window"); - - clutter_x11_texture_pixmap_set_mapped (texture, - attr.map_state == IsViewable); - - clutter_x11_texture_pixmap_sync_window_internal (texture, - attr.x, attr.y, - attr.width, attr.height, - attr.override_redirect); - g_object_unref (texture); - -#endif /* HAVE_XCOMPOSITE */ -} - -static void -clutter_x11_texture_pixmap_sync_window_internal (ClutterX11TexturePixmap *texture, - int x, - int y, - int width, - int height, - gboolean override_redirect) -{ - ClutterX11TexturePixmapPrivate *priv; - Pixmap pixmap = None; - gboolean mapped = FALSE; - gboolean notify_x = FALSE; - gboolean notify_y = FALSE; - gboolean notify_override_redirect = FALSE; - - priv = texture->priv; - - if (priv->destroyed) - return; - - notify_x = x != priv->window_x; - notify_y = y != priv->window_y; - notify_override_redirect = override_redirect != priv->override_redirect; - priv->window_x = x; - priv->window_y = y; - priv->window_width = width; - priv->window_height = height; - priv->override_redirect = override_redirect; - - if (!clutter_x11_has_composite_extension ()) - { - /* FIXME: this should just be an error, this is unlikely to work worth anything */ - clutter_x11_texture_pixmap_set_pixmap (texture, priv->window); - return; - } - - if (priv->pixmap == None || width != priv->pixmap_width || height != priv->pixmap_height) - { - /* Note that we're checking the size from the event against the size we obtained - * from the last XCompositeNameWindowPixmap/XGetGeometry pair. This will always - * end up right in the end, but we can have a series like: - * - * Window sized to 100x100 - * Window sized to 110x110 - * Window sized to 120x120 - * Configure received for 100x100 - NameWindowPixmap - * Configure received for 110x110 - NameWindowPixmap - * Configure received for 120x120 - last size OK - * - * Where we NameWindowPixmap several times in a row. (Using pixmap_width/pixmap_height - * rather than window_width/window_height saves the last one.) - */ - - Display *dpy = clutter_x11_get_default_display (); - - /* NB: It's only valid to name a pixmap if the window is viewable. - * - * We don't explicitly check this though since there would be a race - * between checking and naming unless we use a server grab which is - * undesireable. - * - * Instead we gracefully handle any error with naming the pixmap. - */ - clutter_x11_trap_x_errors (); - - pixmap = XCompositeNameWindowPixmap (dpy, priv->window); - - /* Possible improvement: combine with the XGetGeometry in - * clutter_x11_texture_pixmap_set_pixmap() */ - XSync(dpy, False); - - if (clutter_x11_untrap_x_errors ()) - pixmap = None; - } - - g_object_ref (texture); /* guard against unparent */ - g_object_freeze_notify (G_OBJECT (texture)); - - /* FIXME: mapped is always FALSE */ - clutter_x11_texture_pixmap_set_mapped (texture, mapped); - - if (pixmap) - { - clutter_x11_texture_pixmap_set_pixmap (texture, pixmap); - priv->owns_pixmap = TRUE; - } - - if (notify_override_redirect) - g_object_notify (G_OBJECT (texture), "window-override-redirect"); - if (notify_x) - g_object_notify (G_OBJECT (texture), "window-x"); - if (notify_y) - g_object_notify (G_OBJECT (texture), "window-y"); - - g_object_thaw_notify (G_OBJECT (texture)); - g_object_unref (texture); -} - -/** - * clutter_x11_texture_pixmap_sync_window: - * @texture: the texture to bind - * - * Resets the texture's pixmap from its window, perhaps in response to the - * pixmap's invalidation as the window changed size. - * - * Since: 0.8 - */ -void -clutter_x11_texture_pixmap_sync_window (ClutterX11TexturePixmap *texture) -{ - ClutterX11TexturePixmapPrivate *priv; - - g_return_if_fail (CLUTTER_X11_IS_TEXTURE_PIXMAP (texture)); - - priv = texture->priv; - - if (priv->destroyed) - return; - - if (priv->window != None) - { - Display *dpy = clutter_x11_get_default_display (); - XWindowAttributes attr; - Status status; - - if (dpy == NULL) - return; - - clutter_x11_trap_x_errors (); - - status = XGetWindowAttributes (dpy, priv->window, &attr); - if (status != 0) - clutter_x11_texture_pixmap_sync_window_internal (texture, - attr.x, attr.y, - attr.width, attr.height, - attr.override_redirect); - - clutter_x11_untrap_x_errors (); - } -} - -static void -clutter_x11_texture_pixmap_set_mapped (ClutterX11TexturePixmap *texture, - gboolean mapped) -{ - ClutterX11TexturePixmapPrivate *priv; - - priv = texture->priv; - - if (mapped != priv->window_mapped) - { - priv->window_mapped = mapped; - g_object_notify (G_OBJECT (texture), "window-mapped"); - } -} - -static void -clutter_x11_texture_pixmap_destroyed (ClutterX11TexturePixmap *texture) -{ - ClutterX11TexturePixmapPrivate *priv; - - priv = texture->priv; - - if (!priv->destroyed) - { - priv->destroyed = TRUE; - g_object_notify (G_OBJECT (texture), "destroyed"); - } - - /* - * Don't set window to None, that would destroy the pixmap, which might still - * be useful e.g. for destroy animations -- app's responsibility. - */ -} - -/** - * clutter_x11_texture_pixmap_update_area: - * @texture: The texture whose content shall be updated. - * @x: the X coordinate of the area to update - * @y: the Y coordinate of the area to update - * @width: the width of the area to update - * @height: the height of the area to update - * - * Performs the actual binding of texture to the current content of - * the pixmap. Can be called to update the texture if the pixmap - * content has changed. - * - * Since: 0.8 - **/ -void -clutter_x11_texture_pixmap_update_area (ClutterX11TexturePixmap *texture, - gint x, - gint y, - gint width, - gint height) -{ - g_return_if_fail (CLUTTER_X11_IS_TEXTURE_PIXMAP (texture)); - - g_signal_emit (texture, signals[UPDATE_AREA], 0, x, y, width, height); - - /* The default handler for the "queue-damage-redraw" signal is - * clutter_x11_texture_pixmap_real_queue_damage_redraw which will queue a - * clipped redraw. */ - g_signal_emit (texture, signals[QUEUE_DAMAGE_REDRAW], - 0, x, y, width, height); -} - -/** - * clutter_x11_texture_pixmap_set_automatic: - * @texture: a #ClutterX11TexturePixmap - * @setting: %TRUE to enable automatic updates - * - * Enables or disables the automatic updates ot @texture in case the backing - * pixmap or window is damaged - * - * Since: 0.8 - */ -void -clutter_x11_texture_pixmap_set_automatic (ClutterX11TexturePixmap *texture, - gboolean setting) -{ - ClutterX11TexturePixmapPrivate *priv; - - g_return_if_fail (CLUTTER_X11_IS_TEXTURE_PIXMAP (texture)); - - priv = texture->priv; - - setting = !!setting; - if (setting == priv->automatic_updates) - return; - - if (setting) - create_damage_resources (texture); - else - free_damage_resources (texture); - - priv->automatic_updates = setting; -} diff --git a/clutter/clutter/x11/clutter-x11-texture-pixmap.h b/clutter/clutter/x11/clutter-x11-texture-pixmap.h deleted file mode 100644 index 8d2dc3338..000000000 --- a/clutter/clutter/x11/clutter-x11-texture-pixmap.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Johan Bilien - * - * Copyright (C) 2007 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __CLUTTER_X11_TEXTURE_PIXMAP_H__ -#define __CLUTTER_X11_TEXTURE_PIXMAP_H__ - -#include -#include -#include - -#include - -G_BEGIN_DECLS - -#define CLUTTER_X11_TYPE_TEXTURE_PIXMAP (clutter_x11_texture_pixmap_get_type ()) -#define CLUTTER_X11_TEXTURE_PIXMAP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_X11_TYPE_TEXTURE_PIXMAP, ClutterX11TexturePixmap)) -#define CLUTTER_X11_TEXTURE_PIXMAP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_X11_TYPE_TEXTURE_PIXMAP, ClutterX11TexturePixmapClass)) -#define CLUTTER_X11_IS_TEXTURE_PIXMAP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_X11_TYPE_TEXTURE_PIXMAP)) -#define CLUTTER_X11_IS_TEXTURE_PIXMAP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_X11_TYPE_TEXTURE_PIXMAP)) -#define CLUTTER_X11_TEXTURE_PIXMAP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_X11_TYPE_TEXTURE_PIXMAP, ClutterX11TexturePixmapClass)) - -typedef struct _ClutterX11TexturePixmap ClutterX11TexturePixmap; -typedef struct _ClutterX11TexturePixmapClass ClutterX11TexturePixmapClass; -typedef struct _ClutterX11TexturePixmapPrivate ClutterX11TexturePixmapPrivate; - -/** - * ClutterX11TexturePixmap: - * - * The #ClutterX11TexturePixmap structure contains only private data - * - * Since: 0.8 - */ -struct _ClutterX11TexturePixmap -{ - /*< private >*/ - ClutterTexture parent; - - ClutterX11TexturePixmapPrivate *priv; -}; - -/** - * ClutterX11TexturePixmapClass: - * @update_area: virtual function for updating the area of the texture - * - * The #ClutterX11TexturePixmapClass structure contains only private data - * - * Since: 0.8 - */ -struct _ClutterX11TexturePixmapClass -{ - /*< private >*/ - ClutterTextureClass parent_class; - - /*< public >*/ - void (* update_area) (ClutterX11TexturePixmap *texture, - gint x, - gint y, - gint width, - gint height); -}; - -CLUTTER_AVAILABLE_IN_ALL -GType clutter_x11_texture_pixmap_get_type (void) G_GNUC_CONST; - -CLUTTER_AVAILABLE_IN_ALL -ClutterActor *clutter_x11_texture_pixmap_new (void); -CLUTTER_AVAILABLE_IN_ALL -ClutterActor *clutter_x11_texture_pixmap_new_with_pixmap (Pixmap pixmap); -CLUTTER_AVAILABLE_IN_ALL -ClutterActor *clutter_x11_texture_pixmap_new_with_window (Window window); - -CLUTTER_AVAILABLE_IN_ALL -void clutter_x11_texture_pixmap_set_automatic (ClutterX11TexturePixmap *texture, - gboolean setting); -CLUTTER_AVAILABLE_IN_ALL -void clutter_x11_texture_pixmap_set_pixmap (ClutterX11TexturePixmap *texture, - Pixmap pixmap); -CLUTTER_AVAILABLE_IN_ALL -void clutter_x11_texture_pixmap_set_window (ClutterX11TexturePixmap *texture, - Window window, - gboolean automatic); - -CLUTTER_AVAILABLE_IN_ALL -void clutter_x11_texture_pixmap_sync_window (ClutterX11TexturePixmap *texture); -CLUTTER_AVAILABLE_IN_ALL -void clutter_x11_texture_pixmap_update_area (ClutterX11TexturePixmap *texture, - gint x, - gint y, - gint width, - gint height); - -G_END_DECLS - -#endif diff --git a/clutter/clutter/x11/clutter-x11.h b/clutter/clutter/x11/clutter-x11.h index e3204f393..bf58e6f56 100644 --- a/clutter/clutter/x11/clutter-x11.h +++ b/clutter/clutter/x11/clutter-x11.h @@ -42,7 +42,6 @@ #include #include #include -#include G_BEGIN_DECLS @@ -58,13 +57,14 @@ G_BEGIN_DECLS * * Since: 0.6 */ -typedef enum { +typedef enum +{ CLUTTER_X11_FILTER_CONTINUE, CLUTTER_X11_FILTER_TRANSLATE, CLUTTER_X11_FILTER_REMOVE } ClutterX11FilterReturn; -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT GType clutter_x11_filter_return_get_type (void) G_GNUC_CONST; /* @@ -88,79 +88,40 @@ typedef ClutterX11FilterReturn (*ClutterX11FilterFunc) (XEvent *xev, ClutterEvent *cev, gpointer data); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_x11_trap_x_errors (void); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gint clutter_x11_untrap_x_errors (void); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT Display *clutter_x11_get_default_display (void); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT int clutter_x11_get_default_screen (void); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT Window clutter_x11_get_root_window (void); -CLUTTER_AVAILABLE_IN_ALL -XVisualInfo *clutter_x11_get_visual_info (void); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_x11_set_display (Display * xdpy); -CLUTTER_DEPRECATED_FOR(clutter_x11_get_visual_info) -XVisualInfo *clutter_x11_get_stage_visual (ClutterStage *stage); - -CLUTTER_AVAILABLE_IN_ALL -Window clutter_x11_get_stage_window (ClutterStage *stage); -CLUTTER_AVAILABLE_IN_ALL -gboolean clutter_x11_set_stage_foreign (ClutterStage *stage, - Window xwindow); - -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_x11_add_filter (ClutterX11FilterFunc func, gpointer data); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_x11_remove_filter (ClutterX11FilterFunc func, gpointer data); -CLUTTER_AVAILABLE_IN_ALL -ClutterX11FilterReturn clutter_x11_handle_event (XEvent *xevent); - -CLUTTER_AVAILABLE_IN_ALL -void clutter_x11_disable_event_retrieval (void); -CLUTTER_AVAILABLE_IN_ALL -gboolean clutter_x11_has_event_retrieval (void); - -CLUTTER_AVAILABLE_IN_ALL -ClutterStage *clutter_x11_get_stage_from_window (Window win); - -CLUTTER_DEPRECATED_FOR(clutter_device_manager_peek_devices) -const GSList* clutter_x11_get_input_devices (void); - -CLUTTER_DEPRECATED_IN_1_14 -void clutter_x11_enable_xinput (void); -CLUTTER_AVAILABLE_IN_ALL -gboolean clutter_x11_has_xinput (void); - -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gboolean clutter_x11_has_composite_extension (void); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT void clutter_x11_set_use_argb_visual (gboolean use_argb); -CLUTTER_AVAILABLE_IN_ALL +CLUTTER_EXPORT gboolean clutter_x11_get_use_argb_visual (void); -CLUTTER_AVAILABLE_IN_1_22 +CLUTTER_EXPORT void clutter_x11_set_use_stereo_stage (gboolean use_stereo); -CLUTTER_AVAILABLE_IN_1_22 +CLUTTER_EXPORT gboolean clutter_x11_get_use_stereo_stage (void); -CLUTTER_AVAILABLE_IN_ALL -Time clutter_x11_get_current_event_time (void); - -CLUTTER_AVAILABLE_IN_ALL -gint clutter_x11_event_get_key_group (const ClutterEvent *event); - -CLUTTER_AVAILABLE_IN_ALL -guint clutter_x11_event_sequence_get_touch_detail (const ClutterEventSequence *sequence); - G_END_DECLS #endif /* __CLUTTER_X11_H__ */ diff --git a/clutter/clutter/x11/xsettings/xsettings-client.c b/clutter/clutter/x11/xsettings/xsettings-client.c index 494d57584..f23149901 100644 --- a/clutter/clutter/x11/xsettings/xsettings-client.c +++ b/clutter/clutter/x11/xsettings/xsettings-client.c @@ -480,7 +480,7 @@ xsettings_client_new_with_grab_funcs (Display *display, { XSettingsClient *client; char buffer[256]; - char *atom_names[3]; + const char *atom_names[3]; Atom atoms[3]; client = malloc (sizeof *client); diff --git a/clutter/configure.ac b/clutter/configure.ac deleted file mode 100644 index 9c0e6cd8c..000000000 --- a/clutter/configure.ac +++ /dev/null @@ -1,880 +0,0 @@ -# clutter package version number, (as distinct from shared library version) -# An odd micro number indicates in-progress development from Git -# An even micro number indicates a released version -# -# Making a point release: -# - increase clutter_micro_version to the next even number -# - increase clutter_interface_age to the next even number -# After the release: -# - increase clutter_micro_version to the next odd number -# - increase clutter_interface_version to the next odd number -m4_define([clutter_major_version], [1]) -m4_define([clutter_minor_version], [26]) -m4_define([clutter_micro_version], [1]) - -# • for stable releases: increase the interface age by 1 for each release; -# if the API changes, set to 0. interface_age and binary_age are used to -# create the soname of the shared object: -# -# ( * 100 + ) - -# -# this allows using the same soname for different micro-releases in case -# no API was added or deprecated. for instance: -# -# clutter 1.2.0 -> 100 * 2 + 0 = 200, interface age = 0 -> 200 -# clutter 1.2.2 -> 100 * 2 + 2 = 202, interface age = 2 -> 200 -# clutter 1.2.4 -> 100 * 2 + 4 = 204, interface age = 4 -> 200 -# [ API addition, deprecation ] -# clutter 1.2.6 -> 100 * 2 + 6 = 206, interface age = 0 -> 206 -# clutter 1.2.8 -> 100 * 2 + 8 = 208, interface age = 2 -> 206 -# clutter 1.2.10 -> 100 * 2 + 10 = 210, interface age = 4 -> 206 -# ... -# -# • for development releases: keep clutter_interface_age to 0 -m4_define([clutter_interface_age], [1]) - -m4_define([clutter_binary_age], [m4_eval(100 * clutter_minor_version + clutter_micro_version)]) - -m4_define([clutter_release_status], - [m4_if(m4_eval(clutter_micro_version % 2), [1], [git], - [m4_if(m4_eval(clutter_minor_version % 2), [1], [snapshot], - [release])])]) - -m4_define([clutter_version], [clutter_major_version.clutter_minor_version.clutter_micro_version]) - -AC_PREREQ([2.63]) - -AC_INIT([clutter], - [clutter_version], - [http://bugzilla.gnome.org/enter_bug.cgi?product=clutter], - [clutter], - [http://www.clutter-project.org]) - -AC_CONFIG_SRCDIR([clutter/clutter.h]) -AC_CONFIG_HEADERS([clutter/clutter-build-config.h]) -AC_CONFIG_AUX_DIR([build]) -AC_CONFIG_MACRO_DIR([build/autotools]) - -AM_INIT_AUTOMAKE([1.11 foreign -Wno-portability no-define no-dist-gzip dist-xz tar-ustar]) -AM_SILENT_RULES([yes]) - -dnl = Check that we are configured by muffin ============================== - -AC_ARG_VAR([MUFFIN_VERSION]) -AC_ARG_VAR([MUFFIN_PLUGIN_API_VERSION]) - -AS_IF([test "x$MUFFIN_VERSION" = "x"], - [AC_MSG_ERROR([Clutter can only be configured by muffin])],) - -AC_SUBST([CLUTTER_MAJOR_VERSION], [clutter_major_version]) -AC_SUBST([CLUTTER_MINOR_VERSION], [clutter_minor_version]) -AC_SUBST([CLUTTER_MICRO_VERSION], [clutter_micro_version]) -AC_SUBST([CLUTTER_VERSION], [clutter_version]) -AC_SUBST([CLUTTER_RELEASE_STATUS], [clutter_release_status]) - -m4_define([lt_current], [m4_eval(100 * clutter_minor_version + clutter_micro_version - clutter_interface_age)]) -m4_define([lt_revision], [clutter_interface_age]) -m4_define([lt_age], [m4_eval(clutter_binary_age - clutter_interface_age)]) -CLUTTER_LT_CURRENT=lt_current -CLUTTER_LT_REV=lt_revision -CLUTTER_LT_AGE=lt_age -CLUTTER_LT_VERSION="$CLUTTER_LT_CURRENT:$CLUTTER_LT_REV:$CLUTTER_LT_AGE" -CLUTTER_LT_LDFLAGS="-avoid-version" -AC_SUBST([CLUTTER_LT_CURRENT], [lt_current]) -AC_SUBST([CLUTTER_LT_REVISION], [lt_revision]) -AC_SUBST([CLUTTER_LT_VERSION], [$CLUTTER_LT_VERSION]) - -AC_PROG_SED - -dnl = Preliminary platform checks ============================================= - -AC_CANONICAL_HOST - -AC_DEFINE([OS_LINUX], [1], [Define to 1 if building for Linux]) - -AC_SUBST(CLUTTER_LT_LDFLAGS) - -AC_CACHE_SAVE - -dnl = Dependencies ========================================================= - -# Checks for programs. -AM_PROG_CC_C_O - -# require libtool >= 2.2 -LT_PREREQ([2.2.6]) -LT_INIT([disable-static]) -LT_LIB_M - -# Checks for header files. -AC_HEADER_STDC - -# required versions for dependencies -m4_define([glib_req_version], [2.50.3]) -m4_define([cogl_req_version], [1.21.2]) -m4_define([json_glib_req_version], [0.12.0]) -m4_define([atk_req_version], [2.5.3]) -m4_define([cairo_req_version], [1.14.0]) -m4_define([pango_req_version], [1.30]) -m4_define([gi_req_version], [1.39.0]) -m4_define([xcomposite_req_version], [0.4]) -m4_define([gdk_req_version], [3.3.18]) -m4_define([libinput_req_version], [1.4.0]) -m4_define([libudev_req_version], [136]) -m4_define([libwacom_req_version], [0.13]) - -AC_SUBST([GLIB_REQ_VERSION], [glib_req_version]) -AC_SUBST([COGL_REQ_VERSION], [cogl_req_version]) -AC_SUBST([JSON_GLIB_REQ_VERSION], [json_glib_req_version]) -AC_SUBST([ATK_REQ_VERSION], [atk_req_version]) -AC_SUBST([CAIRO_REQ_VERSION], [cairo_req_version]) -AC_SUBST([PANGO_REQ_VERSION], [pango_req_version]) -AC_SUBST([GI_REQ_VERSION], [gi_req_version]) -AC_SUBST([XCOMPOSITE_REQ_VERSION], [xcomposite_req_version]) -AC_SUBST([GDK_REQ_VERSION], [gdk_req_version]) -AC_SUBST([LIBINPUT_REQ_VERSION], [libinput_req_version]) -AC_SUBST([LIBUDEV_REQ_VERSION], [libudev_req_version]) -AC_SUBST([LIBWACOM_REQ_VERSION], [libwacom_req_version]) - -# Checks for typedefs, structures, and compiler characteristics. -AM_PATH_GLIB_2_0([glib_req_version], - [], - [AC_MSG_ERROR([glib-2.0 is required])], - [gobject gio gthread gmodule-no-export]) - -# Check for -Bsymbolic-functions to avoid intra-library PLT jumps -AC_ARG_ENABLE([Bsymbolic], - [AS_HELP_STRING([--disable-Bsymbolic], - [Avoid linking with -Bsymbolic])], - [], - [ - saved_LDFLAGS="${LDFLAGS}" - AC_MSG_CHECKING([for -Bsymbolic-functions linker flag]) - LDFLAGS=-Wl,-Bsymbolic-functions - AC_TRY_LINK([], [return 0], - [ - AC_MSG_RESULT([yes]) - enable_Bsymbolic=yes - ], - [ - AC_MSG_RESULT([no]) - enable_Bsymbolic=no - ]) - LDFLAGS="${saved_LDFLAGS}" - ]) - -AS_IF([test "x$enable_Bsymbolic" = "xyes"], [CLUTTER_LINK_FLAGS=-Wl[,]-Bsymbolic-functions]) -AC_SUBST(CLUTTER_LINK_FLAGS) - -# Check for the visibility flags -CLUTTER_HIDDEN_VISIBILITY_CFLAGS="" -dnl on other compilers, check if we can do -fvisibility=hidden -SAVED_CFLAGS="${CFLAGS}" -CFLAGS="-fvisibility=hidden" -AC_MSG_CHECKING([for -fvisibility=hidden compiler flag]) -AC_TRY_COMPILE([], [return 0], - AC_MSG_RESULT(yes) - enable_fvisibility_hidden=yes, - AC_MSG_RESULT(no) - enable_fvisibility_hidden=no) -CFLAGS="${SAVED_CFLAGS}" - -AS_IF([test "${enable_fvisibility_hidden}" = "yes"], [ - AC_DEFINE([_CLUTTER_EXTERN], [__attribute__((visibility("default"))) extern], - [defines how to decorate public symbols while building]) - CLUTTER_HIDDEN_VISIBILITY_CFLAGS="-fvisibility=hidden" -]) -AC_SUBST(CLUTTER_HIDDEN_VISIBILITY_CFLAGS) - -AC_CACHE_SAVE - -dnl ======================================================================== - -FLAVOUR_LIBS="" -FLAVOUR_CFLAGS="" -CLUTTER_BACKENDS="" -CLUTTER_INPUT_BACKENDS="" -CLUTTER_CONFIG_DEFINES= - -# base dependencies for core -CLUTTER_BASE_PC_FILES="cairo-gobject >= $CAIRO_REQ_VERSION gio-2.0 >= glib_req_version atk >= $ATK_REQ_VERSION pangocairo >= $PANGO_REQ_VERSION json-glib-1.0 >= $JSON_GLIB_REQ_VERSION" - -# private base dependencies -CLUTTER_BASE_PC_FILES_PRIVATE="" - -# backend specific pkg-config files -BACKEND_PC_FILES="" - -# private backend specific dependencies -BACKEND_PC_FILES_PRIVATE="" - -dnl === Clutter windowing system backend ====================================== - -CLUTTER_BACKENDS="$CLUTTER_BACKENDS x11" -CLUTTER_INPUT_BACKENDS="$CLUTTER_INPUT_BACKENDS x11" - -SUPPORT_X11=1 -SUPPORT_GLX=1 -SUPPORT_COGL=1 - -# we use fontconfig API and pango-ft2 when the fontconfig -# configuration changes; we don't expose any API for this -# so we add pango-ft2 to the private Requires. -PKG_CHECK_EXISTS([pangoft2], - [ - AC_DEFINE([HAVE_PANGO_FT2], [1], [Supports PangoFt2]) - BACKEND_PC_FILES_PRIVATE="$BACKEND_PC_FILES_PRIVATE pangoft2" - ], - []) - -AC_ARG_ENABLE( - [wayland-egl-server], - [AC_HELP_STRING([--enable-wayland-egl-server=@<:@no/yes@:>@], [Enable server side wayland support @<:@default=no@:>@])], - [], - enable_wayland_egl_server=no -) - -AS_IF([test "x$enable_wayland_egl_server" = "xyes"], - [ - CLUTTER_BACKENDS="$CLUTTER_BACKENDS egl" - SUPPORT_EGL=1 - AC_DEFINE([CLUTTER_EGL_BACKEND_GENERIC], [1], [Use Generic EGL backend]) - - BACKEND_PC_FILES="$BACKEND_PC_FILES wayland-egl wayland-server libdrm gbm" - - SUPPORT_WAYLAND_COMPOSITOR=1 - CLUTTER_CONFIG_DEFINES="$CLUTTER_CONFIG_DEFINES - #define CLUTTER_HAS_WAYLAND_COMPOSITOR_SUPPORT 1" - - CLUTTER_INPUT_BACKENDS="$CLUTTER_INPUT_BACKENDS evdev" - - SUPPORT_EVDEV=1 - BACKEND_PC_FILES_PRIVATE="$BACKEND_PC_FILES_PRIVATE libudev >= $LIBUDEV_REQ_VERSION libinput >= $LIBINPUT_REQ_VERSION xkbcommon" - AC_DEFINE([HAVE_EVDEV], [1], [Have evdev support for input handling]) - ]) - -AM_CONDITIONAL(SUPPORT_WAYLAND, [test "x$enable_wayland_egl_server" = "xyes"]) - -AC_DEFINE_UNQUOTED([CLUTTER_DRIVERS], ["*"], [List of Cogl drivers]) - -dnl strip leading spaces -CLUTTER_BACKENDS=${CLUTTER_BACKENDS#* } -AC_SUBST(CLUTTER_BACKENDS) - -CLUTTER_INPUT_BACKENDS=${CLUTTER_INPUT_BACKENDS#* } -AC_SUBST(CLUTTER_INPUT_BACKENDS) - -AC_CACHE_SAVE - -dnl === Clutter configuration ================================================= - -# windowing systems -AS_IF([test "x$SUPPORT_X11" = "x1"], - [CLUTTER_CONFIG_DEFINES="$CLUTTER_CONFIG_DEFINES -#define CLUTTER_WINDOWING_X11 \"x11\" -#define CLUTTER_INPUT_X11 \"x11\""]) -AS_IF([test "x$SUPPORT_GLX" = "x1"], - [CLUTTER_CONFIG_DEFINES="$CLUTTER_CONFIG_DEFINES -#define CLUTTER_WINDOWING_GLX \"glx\""]) -AS_IF([test "x$SUPPORT_EGL" = "x1"], - [CLUTTER_CONFIG_DEFINES="$CLUTTER_CONFIG_DEFINES -#define CLUTTER_WINDOWING_EGL \"eglnative\""]) -AS_IF([test "x$SUPPORT_EVDEV" = "x1"], - [CLUTTER_CONFIG_DEFINES="$CLUTTER_CONFIG_DEFINES -#define CLUTTER_INPUT_EVDEV \"evdev\""]) - -# the 'null' input backend is special -CLUTTER_CONFIG_DEFINES="$CLUTTER_CONFIG_DEFINES -#define CLUTTER_INPUT_NULL \"null\"" - -AC_SUBST([CLUTTER_CONFIG_DEFINES]) - -dnl === Clutter substitutions kept for backwards compatibility ================ -AC_SUBST([CLUTTER_WINSYS], [deprecated]) -AC_SUBST([CLUTTER_WINSYS_BASE], [deprecated]) -AC_SUBST([CLUTTER_STAGE_TYPE], [deprecated]) -AC_SUBST([CLUTTER_SONAME_INFIX], [deprecated]) -AC_SUBST([CLUTTER_FLAVOUR], [deprecated]) -AC_SUBST([CLUTTER_COGL], [deprecated]) -AC_SUBST([COGL_DRIVER], [deprecated]) - -dnl === X11 checks, only for X11-based backends =============================== -X11_PC_FILES="" -X11_EXTS="" -x11_tests=no - -AS_IF([test "x$SUPPORT_X11" = "x1"], - [ - # base X11 includes and libraries - AC_MSG_CHECKING([for X11]) - - # start with pkg-config - PKG_CHECK_EXISTS([x11], [have_x11=yes], [have_x11=no]) - AS_IF([test "x$have_x11" = "xyes"], - [ - X11_PC_FILES="x11" - - # we actually need to ask for CFLAGS and LIBS - X11_CFLAGS=`$PKG_CONFIG --cflags $X11_PC_FILES` - X11_LIBS=`$PKG_CONFIG --libs $X11_PC_FILES` - - AC_MSG_RESULT([found]) - ], - [ - # no pkg-config, let's go old school - AC_PATH_X - - AS_IF([test "x$no_x" = "xyes"], - [AC_MSG_ERROR([No X11 Libraries found])], - [ - AS_IF([test "x$x_includes" != "xNONE" && test -n "$x_includes"], - [X11_CFLAGS=-I`echo $x_includes | sed -e "s/:/ -I/g"`]) - - AS_IF([test "x$x_libraries" != "xNONE" && test -n "$x_libraries"], - [X11_LIBS=-L`echo $x_libraries | sed -e "s/:/ -L/g"`]) - - AC_MSG_RESULT([found]) - ] - ) - ] - ) - - # XEXT (required) - AC_MSG_CHECKING([for XEXT extension]) - PKG_CHECK_EXISTS([xext], [have_xext=yes], [have_xext=no]) - AS_IF([test "x$have_xext" = "xyes"], - [ - AC_DEFINE(HAVE_XEXT, [1], [Define to 1 if we have the XEXT X extension]) - - X11_LIBS="$X11_LIBS -lXext" - X11_PC_FILES="$X11_PC_FILES xext" - X11_EXTS="$X11_EXTS xext" - - AC_MSG_RESULT([found]) - ], - [AC_MSG_ERROR([Not found])] - ) - - # XDAMAGE (required) - AC_MSG_CHECKING([for XDAMAGE extension]) - PKG_CHECK_EXISTS([xdamage], [have_xdamage=yes], [have_xdamage=no]) - AS_IF([test "x$have_xdamage" = "xyes"], - [ - AC_DEFINE(HAVE_XDAMAGE, [1], [Define to 1 if we have the XDAMAGE X extension]) - - X11_LIBS="$X11_LIBS -lXdamage" - X11_PC_FILES="$X11_PC_FILES xdamage" - X11_EXTS="$X11_EXTS xdamage" - - AC_MSG_RESULT([found]) - ], - [AC_MSG_ERROR([not found])] - ) - - # XCOMPOSITE (optional) - AC_MSG_CHECKING([for XCOMPOSITE extension >= $XCOMPOSITE_REQ_VERSION]) - PKG_CHECK_EXISTS([xcomposite >= $XCOMPOSITE_REQ_VERSION], [have_xcomposite=yes], [have_xcomposite=no]) - AS_IF([test "x$have_xcomposite" = "xyes"], - [ - AC_DEFINE(HAVE_XCOMPOSITE, [1], [Define to 1 if we have the XCOMPOSITE X extension]) - - X11_LIBS="$X11_LIBS -lXcomposite" - X11_PC_FILES="$X11_PC_FILES xcomposite >= $XCOMPOSITE_REQ_VERSION" - X11_EXTS="$X11_EXTS xcomposite" - - AC_MSG_RESULT([found]) - ], - [AC_MSG_ERROR([not found])] - ) - - # XTEST (required) - AC_MSG_CHECKING([for XTest extension]) - PKG_CHECK_EXISTS([xtst], [have_xtest=yes], [have_xtest=no]) - AS_IF([test "x$have_xtest" = "xyes"], - [ - AC_DEFINE(HAVE_XTEST, [1], [Define to 1 if we have the XTest X extension]) - - X11_LIBS="$X11_LIBS -lXtst" - X11_PC_FILES="$X11_PC_FILES xtst" - X11_EXTS="$X11_EXTS xtst" - - AC_MSG_RESULT([found]) - ], - [AC_MSG_ERROR([Not found])] - ) - - # X Generic Extensions (optional) - clutter_save_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $X11_CFLAGS" - - clutter_save_LIBS="$LIBS" - LIBS="$LIBS $X11_LIBS" - - have_xge=no - AC_CHECK_FUNC([XGetEventData], - [ - AC_DEFINE([HAVE_XGE], [1], [Define to 1 if X Generic Extensions is available]) - have_xge=yes - X11_EXTS="$X11_EXTS xge" - ]) - - CPPFLAGS="$clutter_save_CPPFLAGS" - LIBS="$clutter_save_LIBS" - - # XI (optional) - AC_ARG_ENABLE([xinput], - [AS_HELP_STRING([--enable-xinput], [Use the XI X extension])], - [], - [enable_xinput=yes]) - - AS_IF([test "x$enable_xinput" = "xyes"], - [ - PKG_CHECK_EXISTS([xi], [have_xinput=yes], [have_xinput=no]) - ], - [ - have_xinput=no - ]) - - AS_CASE([$have_xinput], - - [yes], - [ - AC_CHECK_HEADERS([X11/extensions/XInput2.h], - [ - have_xinput2=yes - AC_DEFINE([HAVE_XINPUT_2], - [1], - [Define to 1 if XI2 is available]) - ]) - - clutter_save_LIBS="$LIBS" - LIBS="$LIBS -lXi" - - AC_CHECK_FUNC([XIAllowTouchEvents], - [ - AC_CHECK_MEMBER([XIScrollClassInfo.number], - [ - have_xinput_2_2=yes - AC_DEFINE([HAVE_XINPUT_2_2], [1], [Define to 1 if XInput 2.2 is available]) - ], - [have_xinput_2_2=no], - [[#include ]])]) - - LIBS="$clutter_save_LIBS" - - X11_LIBS="$X11_LIBS $XINPUT_LIBS" - X11_PC_FILES="$X11_PC_FILES xi" - - AS_IF([test "x$have_xinput_2_2" = "xyes"], - [X11_EXTS="$X11_EXTS xi2.2"], - [X11_EXTS="$X11_EXTS xi2.0"]) - ], - - [no], - [have_xinput2=no], - - [*], - [AC_MSG_ERROR([Invalid argument for --enable-xinput])] - ) - - # XKB - clutter_save_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $X11_CFLAGS" - - clutter_save_LIBS="$LIBS" - LIBS="$LIBS $X11_LIBS" - - have_xkb=no - AC_CHECK_FUNC([XkbQueryExtension], - [ - AC_DEFINE(HAVE_XKB, 1, [Define to use XKB extension]) - have_xkb=yes - - X11_EXTS="$X11_EXTS xkb" - ]) - - CPPFLAGS="$clutter_save_CPPFLAGS" - LIBS="$clutter_save_LIBS" - - x11_tests=yes - BACKEND_PC_FILES="$BACKEND_PC_FILES $X11_PC_FILES" - FLAVOUR_LIBS="$FLAVOUR_LIBS $X11_LIBS" - FLAVOUR_CFLAGS="$FLAVOUR_CFLAGS $X11_CFLAGS" - ] -) - -AM_CONDITIONAL([BUILD_XI2], [test "x$have_xinput2" = "xyes"]) -AM_CONDITIONAL([X11_TESTS], [test "x$x11_tests" = "xyes"]) - -X11_EXTS=${X11_EXTS#* } - -AC_CACHE_SAVE - -dnl === Libwacom support for X11 =============================================== -AC_ARG_WITH(libwacom, - AC_HELP_STRING([--without-libwacom], - [disable the use of libwacom for advanced tablet management]),, - with_libwacom=auto) - -have_libwacom=no -AC_MSG_CHECKING([libwacom]) -if test x$with_libwacom = xno ; then - AC_MSG_RESULT([disabled]) -else - if $PKG_CONFIG --exists libwacom '>=' $LIBWACOM_REQ_VERSION; then - have_libwacom=yes - AC_MSG_RESULT(yes) - PKG_CHECK_MODULES([LIBWACOM], [libwacom]) - AC_SUBST(LIBWACOM_CFLAGS) - AC_SUBST(LIBWACOM_LIBS) - AC_DEFINE([HAVE_LIBWACOM], 1, [Building with libwacom for advanced tablet management]) - else - AC_MSG_RESULT(no) - if test x$with_libwacom = xyes ; then - AC_MSG_ERROR([libwacom forced but not found]) - fi - fi -fi - -dnl === Enable GDK-Pixbuf in tests ============================================ - -m4_define([pixbuf_default], [yes]) -AC_ARG_ENABLE([gdk-pixbuf], - [AS_HELP_STRING([--enable-gdk-pixbuf=@<:@no/yes@:>@], - [Enable tests using GDK-Pixbuf @<:@default=]pixbuf_default[@:>@])], - [enable_pixbuf=$enable_val], - [enable_pixbuf=pixbuf_default]) - -AS_CASE([$enable_pixbuf], - - [yes], - [ - PKG_CHECK_MODULES([GDK_PIXBUF], [gdk-pixbuf-2.0]) - AC_SUBST(GDK_PIXBUF_CFLAGS) - AC_SUBST(GDK_PIXBUF_LIBS) - pixbuf_tests=yes - ], - - [no], - [ - pixbuf_tests=no - ] -) - -AM_CONDITIONAL([PIXBUF_TESTS], [test "x$pixbuf_tests" = "xyes"]) - -dnl === Enable debug level ==================================================== - -m4_define([debug_default], [m4_if(m4_eval(clutter_minor_version % 2), [1], [yes], [minimum])]) -AC_ARG_ENABLE([debug], - [AS_HELP_STRING([--enable-debug=@<:@no/minimum/yes@:>@], - [Control Clutter debugging level @<:@default=]debug_default[@:>@])], - [], - [enable_debug=debug_default]) - -AS_CASE([$enable_debug], - - [yes], - [ - test "$cflags_set" = set || CFLAGS="$CFLAGS -g" - CLUTTER_DEBUG_CFLAGS="-DCLUTTER_ENABLE_DEBUG" - ], - - [minimum], - [CLUTTER_DEBUG_CFLAGS="-DG_DISABLE_CAST_CHECKS"], - - [no], - [CLUTTER_DEBUG_CFLAGS="-DG_DISABLE_ASSERT -DG_DISABLE_CHECKS -DG_DISABLE_CAST_CHECKS"], - - [AC_MSG_ERROR([Unknown argument for --enable-debug])] -) - -AC_SUBST(CLUTTER_DEBUG_CFLAGS) - -dnl === Enable deprecation guards ================================================== - -m4_define([deprecated_default], - [m4_if(m4_eval(clutter_minor_version % 2), - [1], - [no], - [yes])]) - -AC_ARG_ENABLE([deprecated], - [AS_HELP_STRING([--enable-deprecated=@<:@no/yes@:>@], - [Whether deprecated symbols should be disabled when compiling Clutter @<:@default=]deprecated_default[@:>@])], - [], - [enable_deprecated=deprecated_default]) - -AS_CASE([$enable_deprecated], - - [no], - [ - CLUTTER_DEPRECATED_CFLAGS="-DG_DISABLE_SINGLE_INCLUDES -DCOGL_DISABLE_DEPRECATED" - ], - - [yes], - [ - CLUTTER_DEPRECATED_CFLAGS="-DGLIB_DISABLE_DEPRECATION_WARNINGS" - ], - - [AC_MSG_ERROR([Unknown argument for --enable-deprecated])] -) - -AC_SUBST([CLUTTER_DEPRECATED_CFLAGS]) - -dnl === Enable strict compiler flags ========================================== - -# use strict compiler flags only when building from git; the rules for -# distcheck will take care of turning this on when making a release -m4_define([maintainer_flags_default], [m4_if(m4_eval(clutter_micro_version % 2), [1], [yes], [no])]) -AC_ARG_ENABLE([maintainer-flags], - [AS_HELP_STRING([--enable-maintainer-flags=@<:@no/yes/error@:>@], - [Use strict compiler flags @<:@default=]maintainer_flags_default[@:>@])], - [], - [enable_maintainer_flags=maintainer_flags_default]) - -MAINTAINER_COMPILER_FLAGS="$MAINTAINER_COMPILER_FLAGS - -Wall - -Wcast-align - -Wuninitialized - -Wno-strict-aliasing - -Wshadow" - -AC_ARG_ENABLE([Werror], - [AS_HELP_STRING([--disable-Werror], [Removes -Werror from compiler flags])], - [], - [enable_Werror=yes]) - -AS_IF([test "x$enable_Werror" = xyes], [ - MAINTAINER_COMPILER_FLAGS="$MAINTAINER_COMPILER_FLAGS - -Werror=logical-op - -Werror=pointer-arith - -Werror=missing-declarations - -Werror=redundant-decls - -Werror=empty-body - -Werror=format - -Werror=format-security - -Werror=format-nonliteral - -Werror=init-self - -Werror=declaration-after-statement - -Werror=vla" -]) - -AS_CASE([$enable_maintainer_flags], - [yes], - [ - AS_COMPILER_FLAGS([MAINTAINER_CFLAGS], [$MAINTAINER_COMPILER_FLAGS]) - ], - - [no], - [ - ], - - [error], - [ - MAINTAINER_COMPILER_FLAGS="$MAINTAINER_COMPILER_FLAGS -Werror" - AS_COMPILER_FLAGS([MAINTAINER_CFLAGS], [$MAINTAINER_COMPILER_FLAGS]) - ], - - [*], - [AC_MSG_ERROR([Invalid option for --enable-maintainer-flags])] -) - -# strip leading spaces -MAINTAINER_CFLAGS=${MAINTAINER_CFLAGS#* } -AC_SUBST(MAINTAINER_CFLAGS) - -dnl === Dependencies, compiler flags and linker libraries ===================== -# strip leading space -BACKEND_PC_FILES=${BACKEND_PC_FILES#* } - -# public dependencies, will fill the Requires: field of clutter.pc -CLUTTER_REQUIRES="$CLUTTER_BASE_PC_FILES $BACKEND_PC_FILES" -PKG_CHECK_MODULES(CLUTTER_DEPS, [$CLUTTER_REQUIRES]) - -# private dependencies, will fill the Requires.private: field of clutter.pc -AS_IF([test "x$CLUTTER_BASE_PC_FILES_PRIVATE" = "x" && test "x$BACKEND_PC_FILES_PRIVATE" = "x"], - [ - CLUTTER_REQUIRES_PRIVATE="" - CLUTTER_DEPS_PRIVATE_CFLAGS="" - CLUTTER_DEPS_PRIVATE_LIBS="" - ], - [ - CLUTTER_REQUIRES_PRIVATE="$CLUTTER_BASE_PC_FILES_PRIVATE $BACKEND_PC_FILES_PRIVATE" - PKG_CHECK_MODULES(CLUTTER_DEPS_PRIVATE, [$CLUTTER_REQUIRES_PRIVATE]) - ]) - -AC_SUBST(CLUTTER_REQUIRES) -AC_SUBST(CLUTTER_REQUIRES_PRIVATE) - -CLUTTER_CFLAGS="$FLAVOUR_CFLAGS $CLUTTER_DEPS_CFLAGS $CLUTTER_DEPS_PRIVATE_CFLAGS $GLIB_CFLAGS $LIBWACOM_CFLAGS" -CLUTTER_LIBS="$FLAVOUR_LIBS $CLUTTER_DEPS_LIBS $CLUTTER_DEPS_PRIVATE_LIBS $GLIB_LIBS $LIBWACOM_LIBS" -AC_SUBST(CLUTTER_CFLAGS) -AC_SUBST(CLUTTER_LIBS) - -dnl === Test coverage ========================================================= - -AC_ARG_ENABLE([gcov], - [AS_HELP_STRING([--enable-gcov], [Enable gcov])], - [use_gcov=$enableval], - [use_gcov=no]) - -AS_IF([test "x$use_gcov" = "xyes"], - [ - dnl we need gcc: - AS_IF([test "$GCC" != "yes"], [AC_MSG_ERROR([GCC is required for --enable-gcov])]) - - dnl Check if ccache is being used - AC_CHECK_PROG(SHTOOL, shtool, shtool) - AS_CASE([`$SHTOOL path $CC`], - [*ccache*], [gcc_ccache=yes], - [gcc_ccache=no]) - - if test "$gcc_ccache" = "yes" && (test -z "$CCACHE_DISABLE" || test "$CCACHE_DISABLE" != "1"); then - AC_MSG_ERROR([ccache must be disabled when --enable-gcov option is used. You can disable ccache by setting environment variable CCACHE_DISABLE=1.]) - fi - - ltp_version_list="1.6 1.7 1.8 1.9 1.10" - AC_CHECK_PROG(LTP, lcov, lcov) - AC_CHECK_PROG(LTP_GENHTML, genhtml, genhtml) - - if test "$LTP"; then - AC_CACHE_CHECK([for ltp version], clutter_cv_ltp_version, - [ - clutter_cv_ltp_version=invalid - ltp_version=`$LTP -v 2>/dev/null | $SED -e 's/^.* //'` - for ltp_check_version in $ltp_version_list; do - if test "$ltp_version" = "$ltp_check_version"; then - clutter_cv_ltp_version="$ltp_check_version (ok)" - fi - done - ]) - else - ltp_msg="To enable code coverage reporting you must have one of the following LTP versions installed: $ltp_version_list" - AC_MSG_ERROR([$ltp_msg]) - fi - - case $clutter_cv_ltp_version in - ""|invalid[)] - ltp_msg="You must have one of the following versions of LTP: $ltp_version_list (found: $ltp_version)." - AC_MSG_ERROR([$ltp_msg]) - LTP="exit 0;" - ;; - esac - - if test -z "$LTP_GENHTML"; then - AC_MSG_ERROR([Could not find genhtml from the LTP package]) - fi - - AC_DEFINE(HAVE_GCOV, 1, [Whether you have gcov]) - - dnl Remove all optimization flags from CFLAGS - changequote({,}) - CFLAGS=`echo "$CFLAGS" | $SED -e 's/-O[0-9]*//g'` - CLUTTER_CFLAGS=`echo "$CLUTTER_CFLAGS" | $SED -e 's/-O[0-9]*//g'` - changequote([,]) - - dnl Define the special gcc flags - CLUTTER_GCOV_CFLAGS="-O0 -fprofile-arcs -ftest-coverage" - CLUTTER_GCOV_LDADD="-lgcov" - - AC_SUBST(CLUTTER_GCOV_CFLAGS) - AC_SUBST(CLUTTER_GCOV_LDADD) - - CLUTTER_CFLAGS="$CLUTTER_CFLAGS $CLUTTER_GCOV_CFLAGS" - CLUTTER_LIBS="$CLUTTER_LIBS $CLUTTER_GCOV_LDADD" - ]) - -AM_CONDITIONAL(ENABLE_GCOV, test "x$use_gcov" = "xyes") - -dnl === GObject-Introspection check =========================================== - -GOBJECT_INTROSPECTION_CHECK([gi_req_version]) - -dnl === Conformance test suite ================================================ - -GLIB_TESTS - -AC_ARG_ENABLE([examples], - [AS_HELP_STRING([--enable-examples], [Whether examples should be built])], - [], - [enable_examples=no]) -AM_CONDITIONAL(BUILD_EXAMPLES, [test "x$enable_examples" = "xyes"]) - -dnl =========================================================================== - -AC_CONFIG_FILES([ - Makefile - - build/Makefile - build/autotools/Makefile - - clutter/Makefile - clutter/clutter-config.h - clutter/clutter-version.h - clutter/muffin-clutter-$MUFFIN_PLUGIN_API_VERSION.pc:clutter/muffin-clutter.pc.in - - tests/Makefile - tests/accessibility/Makefile - tests/conform/Makefile - tests/interactive/Makefile - tests/interactive/wrapper.sh - tests/micro-bench/Makefile - tests/performance/Makefile - - examples/Makefile -]) - -AC_OUTPUT - -dnl === Summary =============================================================== - -echo "" -echo "Clutter - $VERSION (${CLUTTER_RELEASE_STATUS})" - -# Global flags -echo "" -echo " • Global:" -echo " Prefix: ${prefix}" -echo " Libdir: ${libdir}" -echo " Sysconfdir: ${sysconfdir}" - -# Compiler/Debug related flags -echo "" -echo " • Compiler options:" -echo " Clutter debug level: ${enable_debug}" -echo " Compiler flags: ${CFLAGS} ${MAINTAINER_CFLAGS}" -echo " Enable coverage tests: ${use_gcov}" -echo " Enable deprecated symbols: ${enable_deprecated}" - -# Miscellaneous -echo "" -echo " • Extra:" -echo " Build introspection data: ${enable_introspection}" -if test "x$x11_tests" = "xyes"; then -echo " Build X11-specific tests: ${x11_tests}" -fi -if test "x$pixbuf_tests" = "xyes"; then -echo " Build tests using GDK-Pixbuf: ${pixbuf_tests}" -fi -echo " Install test suites: ${enable_installed_tests}" -echo " Build examples: ${enable_examples}" - -# Clutter backend related flags -echo "" -echo " • Clutter Backends:" -echo " Windowing systems: ${CLUTTER_BACKENDS}" -echo " Input backends: ${CLUTTER_INPUT_BACKENDS}" - -if test "x$SUPPORT_X11" = "x1"; then -echo "" -echo " - X11 backend options:" -echo " Enabled extensions: ${X11_EXTS}" -fi - -if test "x$SUPPORT_WAYLAND_COMPOSITOR" = "x1"; then -echo "" -echo " - Wayland compositor support enabled" -fi - -echo "" diff --git a/clutter/examples/Makefile.am b/clutter/examples/Makefile.am deleted file mode 100644 index b601629a2..000000000 --- a/clutter/examples/Makefile.am +++ /dev/null @@ -1,36 +0,0 @@ -all_examples = \ - actor-model \ - basic-actor \ - box-layout \ - canvas \ - constraints \ - drag-action \ - drop-action \ - easing-modes \ - flow-layout \ - grid-layout \ - layout-manager \ - pan-action \ - rounded-rectangle \ - scroll-actor \ - threads - -if PIXBUF_TESTS -all_examples += \ - bin-layout \ - image-content -endif - -LDADD = $(top_builddir)/clutter/libmuffin-clutter-@MUFFIN_PLUGIN_API_VERSION@.la $(CLUTTER_LIBS) $(GDK_PIXBUF_LIBS) $(LIBM) -AM_CFLAGS = $(CLUTTER_CFLAGS) $(GDK_PIXBUF_CFLAGS) $(MAINTAINER_CFLAGS) -AM_CPPFLAGS = \ - -DG_DISABLE_SINGLE_INCLUDES \ - -DGLIB_DISABLE_DEPRECATION_WARNINGS \ - -I$(top_srcdir) \ - -I$(top_builddir) \ - -I$(top_srcdir)/clutter \ - -I$(top_builddir)/clutter - -noinst_PROGRAMS = $(all_examples) - -EXTRA_DIST = redhand.png diff --git a/clutter/examples/actor-model.c b/clutter/examples/actor-model.c deleted file mode 100644 index 6fbc465da..000000000 --- a/clutter/examples/actor-model.c +++ /dev/null @@ -1,522 +0,0 @@ -#include -#include -#include - -/* {{{ MenuItemModel */ - -/* This is our "model" of a Menu item; it has a "label" property, and - * a "selected" state property. The user is supposed to operate on the - * model instance, and change its state. - */ - -#define EXAMPLE_TYPE_MENU_ITEM_MODEL (example_menu_item_model_get_type ()) - -G_DECLARE_FINAL_TYPE (ExampleMenuItemModel, example_menu_item_model, EXAMPLE, MENU_ITEM_MODEL, GObject) - -struct _ExampleMenuItemModel -{ - GObject parent_instance; - - char *label; - - gboolean selected; -}; - -struct _ExampleMenuItemModelClass -{ - GObjectClass parent_class; -}; - -enum { - MENU_ITEM_MODEL_PROP_LABEL = 1, - MENU_ITEM_MODEL_PROP_SELECTED, - MENU_ITEM_MODEL_N_PROPS -}; - -static GParamSpec *menu_item_model_props[MENU_ITEM_MODEL_N_PROPS] = { NULL, }; - -G_DEFINE_TYPE (ExampleMenuItemModel, example_menu_item_model, G_TYPE_OBJECT) - -static void -example_menu_item_model_finalize (GObject *gobject) -{ - ExampleMenuItemModel *self = (ExampleMenuItemModel *) gobject; - - free (self->label); - - G_OBJECT_CLASS (example_menu_item_model_parent_class)->finalize (gobject); -} - -static void -example_menu_item_model_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ExampleMenuItemModel *self = (ExampleMenuItemModel *) gobject; - - switch (prop_id) - { - case MENU_ITEM_MODEL_PROP_LABEL: - free (self->label); - self->label = g_value_dup_string (value); - break; - - case MENU_ITEM_MODEL_PROP_SELECTED: - self->selected = g_value_get_boolean (value); - break; - } -} - -static void -example_menu_item_model_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ExampleMenuItemModel *self = (ExampleMenuItemModel *) gobject; - - switch (prop_id) - { - case MENU_ITEM_MODEL_PROP_LABEL: - g_value_set_string (value, self->label); - break; - - case MENU_ITEM_MODEL_PROP_SELECTED: - g_value_set_boolean (value, self->selected); - break; - } -} - -static void -example_menu_item_model_class_init (ExampleMenuItemModelClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - gobject_class->set_property = example_menu_item_model_set_property; - gobject_class->get_property = example_menu_item_model_get_property; - gobject_class->finalize = example_menu_item_model_finalize; - - menu_item_model_props[MENU_ITEM_MODEL_PROP_LABEL] = - g_param_spec_string ("label", NULL, NULL, - NULL, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - menu_item_model_props[MENU_ITEM_MODEL_PROP_SELECTED] = - g_param_spec_boolean ("selected", NULL, NULL, - FALSE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - g_object_class_install_properties (gobject_class, MENU_ITEM_MODEL_N_PROPS, menu_item_model_props); -} - -static void -example_menu_item_model_init (ExampleMenuItemModel *self) -{ -} -/* }}} */ - -/* {{{ MenuItemView */ - -/* This is our "view" of a Menu item; it changes state depending on whether - * the "selected" property is set. The "view" reflects the state of the - * "model" instance, though it has no direct connection to it. - */ -#define EXAMPLE_TYPE_MENU_ITEM_VIEW (example_menu_item_view_get_type ()) - -G_DECLARE_FINAL_TYPE (ExampleMenuItemView, example_menu_item_view, EXAMPLE, MENU_ITEM_VIEW, ClutterText) - -struct _ExampleMenuItemView -{ - ClutterText parent_instance; - - gboolean is_selected; -}; - -struct _ExampleMenuItemViewClass -{ - ClutterTextClass parent_class; -}; - -G_DEFINE_TYPE (ExampleMenuItemView, example_menu_item_view, CLUTTER_TYPE_TEXT) - -enum { - MENU_ITEM_VIEW_PROP_SELECTED = 1, - MENU_ITEM_VIEW_N_PROPS -}; - -static GParamSpec *menu_item_view_props[MENU_ITEM_VIEW_N_PROPS] = { NULL, }; - -static void -example_menu_item_view_set_selected (ExampleMenuItemView *self, - gboolean selected) -{ - selected = !!selected; - if (self->is_selected == selected) - return; - - self->is_selected = selected; - - if (self->is_selected) - clutter_text_set_color (CLUTTER_TEXT (self), CLUTTER_COLOR_LightSkyBlue); - else - clutter_text_set_color (CLUTTER_TEXT (self), CLUTTER_COLOR_White); - - g_object_notify_by_pspec (G_OBJECT (self), menu_item_view_props[MENU_ITEM_VIEW_PROP_SELECTED]); -} - -static void -example_menu_item_view_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (prop_id) - { - case MENU_ITEM_VIEW_PROP_SELECTED: - example_menu_item_view_set_selected (EXAMPLE_MENU_ITEM_VIEW (gobject), - g_value_get_boolean (value)); - break; - } -} - -static void -example_menu_item_view_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - switch (prop_id) - { - case MENU_ITEM_VIEW_PROP_SELECTED: - g_value_set_boolean (value, EXAMPLE_MENU_ITEM_VIEW (gobject)->is_selected); - break; - } -} - -static void -example_menu_item_view_class_init (ExampleMenuItemViewClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - gobject_class->set_property = example_menu_item_view_set_property; - gobject_class->get_property = example_menu_item_view_get_property; - - menu_item_view_props[MENU_ITEM_VIEW_PROP_SELECTED] = - g_param_spec_boolean ("selected", NULL, NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (gobject_class, MENU_ITEM_VIEW_N_PROPS, menu_item_view_props); -} - -static void -example_menu_item_view__transition_stopped (ClutterActor *actor, - const char *transition, - gboolean is_finished) -{ - clutter_actor_set_scale (actor, 1.0, 1.0); - clutter_actor_set_opacity (actor, 255); -} - -static void -example_menu_item_view_init (ExampleMenuItemView *self) -{ - ClutterText *text = CLUTTER_TEXT (self); - ClutterActor *actor = CLUTTER_ACTOR (self); - ClutterTransition *scalex_trans, *scaley_trans, *fade_trans; - ClutterTransition *group; - - clutter_text_set_font_name (text, "Sans Bold 24px"); - clutter_text_set_color (text, CLUTTER_COLOR_White); - - clutter_actor_set_margin_left (actor, 12); - clutter_actor_set_margin_right (actor, 12); - - clutter_actor_set_pivot_point (actor, 0.5, 0.5); - - scalex_trans = clutter_property_transition_new ("scale-x"); - clutter_transition_set_from (scalex_trans, G_TYPE_FLOAT, 1.0); - clutter_transition_set_to (scalex_trans, G_TYPE_FLOAT, 3.0); - - scaley_trans = clutter_property_transition_new ("scale-y"); - clutter_transition_set_from (scaley_trans, G_TYPE_FLOAT, 1.0); - clutter_transition_set_to (scaley_trans, G_TYPE_FLOAT, 3.0); - - fade_trans = clutter_property_transition_new ("opacity"); - clutter_transition_set_to (fade_trans, G_TYPE_UINT, 0); - - group = clutter_transition_group_new (); - clutter_transition_group_add_transition (CLUTTER_TRANSITION_GROUP (group), scalex_trans); - clutter_transition_group_add_transition (CLUTTER_TRANSITION_GROUP (group), scaley_trans); - clutter_transition_group_add_transition (CLUTTER_TRANSITION_GROUP (group), fade_trans); - clutter_timeline_set_duration (CLUTTER_TIMELINE (group), 250); - clutter_timeline_set_progress_mode (CLUTTER_TIMELINE (group), CLUTTER_EASE_OUT); - - clutter_actor_add_transition (actor, "activateTransition", group); - g_object_unref (group); - - clutter_timeline_stop (CLUTTER_TIMELINE (group)); - - g_signal_connect (actor, "transition-stopped", - G_CALLBACK (example_menu_item_view__transition_stopped), - group); -} - -static void -example_menu_item_view_activate (ExampleMenuItemView *self) -{ - ClutterTransition *t; - - t = clutter_actor_get_transition (CLUTTER_ACTOR (self), "activateTransition"); - clutter_timeline_start (CLUTTER_TIMELINE (t)); -} - -/* }}} */ - -/* {{{ Menu */ - -/* This is our container actor, which binds the GListStore with the - * ExampleMenuItemModel instances to the ExampleMenuItemView actors - */ - -#define EXAMPLE_TYPE_MENU (example_menu_get_type ()) - -G_DECLARE_FINAL_TYPE (ExampleMenu, example_menu, EXAMPLE, MENU, ClutterActor) - -struct _ExampleMenu -{ - ClutterActor parent_instance; - - int current_idx; -}; - -struct _ExampleMenuClass -{ - ClutterActorClass parent_class; -}; - -G_DEFINE_TYPE (ExampleMenu, example_menu, CLUTTER_TYPE_ACTOR) - -static void -example_menu_class_init (ExampleMenuClass *klass) -{ -} - -static void -example_menu_init (ExampleMenu *self) -{ - ClutterActor *actor = CLUTTER_ACTOR (self); - ClutterLayoutManager *layout; - - layout = clutter_box_layout_new (); - clutter_box_layout_set_orientation (CLUTTER_BOX_LAYOUT (layout), CLUTTER_ORIENTATION_VERTICAL); - clutter_box_layout_set_spacing (CLUTTER_BOX_LAYOUT (layout), 12); - - clutter_actor_set_layout_manager (actor, layout); - clutter_actor_set_background_color (actor, CLUTTER_COLOR_Black); - - self->current_idx = -1; -} - -static ClutterActor * -example_menu_select_item (ExampleMenu *self, - int idx) -{ - ClutterActor *item; - - /* Any change in the view is reflected into the model */ - - if (idx == self->current_idx) - return clutter_actor_get_child_at_index (CLUTTER_ACTOR (self), self->current_idx); - - item = clutter_actor_get_child_at_index (CLUTTER_ACTOR (self), self->current_idx); - if (item != NULL) - example_menu_item_view_set_selected ((ExampleMenuItemView *) item, FALSE); - - if (idx < 0) - idx = clutter_actor_get_n_children (CLUTTER_ACTOR (self)) - 1; - else if (idx >= clutter_actor_get_n_children (CLUTTER_ACTOR (self))) - idx = 0; - - self->current_idx = idx; - - item = clutter_actor_get_child_at_index (CLUTTER_ACTOR (self), self->current_idx); - if (item != NULL) - example_menu_item_view_set_selected ((ExampleMenuItemView *) item, TRUE); - - return item; -} - -static ClutterActor * -example_menu_select_next (ExampleMenu *self) -{ - return example_menu_select_item (self, self->current_idx + 1); -} - -static ClutterActor * -example_menu_select_prev (ExampleMenu *self) -{ - return example_menu_select_item (self, self->current_idx - 1); -} - -static void -example_menu_activate_item (ExampleMenu *self) -{ - ClutterActor *child; - - child = clutter_actor_get_child_at_index (CLUTTER_ACTOR (self), - self->current_idx); - if (child == NULL) - return; - - example_menu_item_view_activate ((ExampleMenuItemView *) child); -} - -/* }}} */ - -/* {{{ main */ -static gboolean -on_key_press (ClutterActor *stage, - ClutterEvent *event) -{ - ClutterActor *scroll = clutter_actor_get_first_child (stage); - ClutterActor *menu = clutter_actor_get_first_child (scroll); - ClutterActor *item = NULL; - guint key = clutter_event_get_key_symbol (event); - ClutterPoint p; - - switch (key) - { - case CLUTTER_KEY_q: - clutter_main_quit (); - break; - - case CLUTTER_KEY_Up: - item = example_menu_select_prev ((ExampleMenu *) menu); - clutter_actor_get_position (item, &p.x, &p.y); - break; - - case CLUTTER_KEY_Down: - item = example_menu_select_next ((ExampleMenu *) menu); - clutter_actor_get_position (item, &p.x, &p.y); - break; - - case CLUTTER_KEY_Return: - case CLUTTER_KEY_KP_Enter: - example_menu_activate_item ((ExampleMenu *) menu); - break; - } - - if (item != NULL) - clutter_scroll_actor_scroll_to_point (CLUTTER_SCROLL_ACTOR (scroll), &p); - - return CLUTTER_EVENT_PROPAGATE; -} - -static void -on_model_item_selection (GObject *model_item, - GParamSpec *pspec, - gpointer data) -{ - char *label = NULL; - gboolean is_selected = FALSE; - - g_object_get (model_item, "label", &label, "selected", &is_selected, NULL); - - if (is_selected) - g_print ("Item '%s' selected!\n", label); - - free (label); -} - -static ClutterActor * -create_menu_actor (void) -{ - /* Our store of menu item models */ - GListStore *model = g_list_store_new (EXAMPLE_TYPE_MENU_ITEM_MODEL); - ClutterActor *menu = g_object_new (EXAMPLE_TYPE_MENU, NULL); - int i; - - /* Populate the model */ - for (i = 0; i < 12; i++) - { - char *label = g_strdup_printf ("Option %02d", i + 1); - - ExampleMenuItemModel *item = g_object_new (EXAMPLE_TYPE_MENU_ITEM_MODEL, - "label", label, - NULL); - - g_list_store_append (model, item); - - g_signal_connect (item, "notify::selected", - G_CALLBACK (on_model_item_selection), - NULL); - - g_object_unref (item); - free (label); - } - - /* Bind the list of menu item models to the menu actor; this will - * create ClutterActor views of each item in the model, and add them - * to the menu actor - */ - clutter_actor_bind_model_with_properties (menu, G_LIST_MODEL (model), - EXAMPLE_TYPE_MENU_ITEM_VIEW, - "label", "text", G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE, - "selected", "selected", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE, - NULL); - - /* We don't need a pointer to the model any more, so we transfer ownership - * to the menu actor; this means that the model will go away when the menu - * actor is destroyed - */ - g_object_unref (model); - - /* Select the first item in the menu */ - example_menu_select_item ((ExampleMenu *) menu, 0); - - return menu; -} - -/* The scrolling container for the menu */ -static ClutterActor * -create_scroll_actor (void) -{ - ClutterActor *menu = clutter_scroll_actor_new (); - clutter_actor_set_name (menu, "scroll"); - clutter_scroll_actor_set_scroll_mode (CLUTTER_SCROLL_ACTOR (menu), - CLUTTER_SCROLL_VERTICALLY); - clutter_actor_set_easing_duration (menu, 250); - clutter_actor_add_child (menu, create_menu_actor ()); - - return menu; -} - -int -main (int argc, char *argv[]) -{ - ClutterActor *stage, *menu; - - if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) - return 1; - - stage = clutter_stage_new (); - clutter_stage_set_title (CLUTTER_STAGE (stage), "Actor Model"); - clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE); - g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); - g_signal_connect (stage, "key-press-event", G_CALLBACK (on_key_press), NULL); - clutter_actor_show (stage); - -#define PADDING 18.f - - menu = create_scroll_actor (); - clutter_actor_set_position (menu, 0, PADDING); - clutter_actor_add_constraint (menu, clutter_align_constraint_new (stage, CLUTTER_ALIGN_X_AXIS, 0.5)); - clutter_actor_add_constraint (menu, clutter_bind_constraint_new (stage, CLUTTER_BIND_HEIGHT, -PADDING * 2)); - clutter_actor_add_child (stage, menu); - - clutter_main (); - - return 0; -} -/* }}} */ diff --git a/clutter/examples/basic-actor.c b/clutter/examples/basic-actor.c deleted file mode 100644 index e74f33e03..000000000 --- a/clutter/examples/basic-actor.c +++ /dev/null @@ -1,153 +0,0 @@ -#include -#include - -#define SIZE 128 - -static gboolean -animate_color (ClutterActor *actor, - ClutterEvent *event) -{ - static gboolean toggled = TRUE; - const ClutterColor *end_color; - - if (toggled) - end_color = CLUTTER_COLOR_Blue; - else - end_color = CLUTTER_COLOR_Red; - - clutter_actor_save_easing_state (actor); - clutter_actor_set_easing_duration (actor, 500); - clutter_actor_set_easing_mode (actor, CLUTTER_LINEAR); - clutter_actor_set_background_color (actor, end_color); - clutter_actor_restore_easing_state (actor); - - toggled = !toggled; - - return CLUTTER_EVENT_STOP; -} - -static gboolean -on_crossing (ClutterActor *actor, - ClutterEvent *event) -{ - gboolean is_enter = clutter_event_type (event) == CLUTTER_ENTER; - float zpos; - - if (is_enter) - zpos = -250.0; - else - zpos = 0.0; - - clutter_actor_save_easing_state (actor); - clutter_actor_set_easing_duration (actor, 500); - clutter_actor_set_easing_mode (actor, CLUTTER_EASE_OUT_BOUNCE); - clutter_actor_set_z_position (actor, zpos); - clutter_actor_restore_easing_state (actor); - - return CLUTTER_EVENT_STOP; -} - -static void -on_transition_stopped (ClutterActor *actor, - const gchar *transition_name, - gboolean is_finished) -{ - clutter_actor_save_easing_state (actor); - clutter_actor_set_rotation_angle (actor, CLUTTER_Y_AXIS, 0.0f); - clutter_actor_restore_easing_state (actor); - - /* disconnect so we don't get multiple notifications */ - g_signal_handlers_disconnect_by_func (actor, - on_transition_stopped, - NULL); -} - -static gboolean -animate_rotation (ClutterActor *actor, - ClutterEvent *event) -{ - clutter_actor_save_easing_state (actor); - clutter_actor_set_easing_duration (actor, 1000); - - clutter_actor_set_rotation_angle (actor, CLUTTER_Y_AXIS, 360.0); - - clutter_actor_restore_easing_state (actor); - - /* get a notification when the rotation-angle-y transition ends */ - g_signal_connect (actor, - "transition-stopped::rotation-angle-y", - G_CALLBACK (on_transition_stopped), - NULL); - - return CLUTTER_EVENT_STOP; -} - -int -main (int argc, char *argv[]) -{ - ClutterActor *stage, *vase; - ClutterActor *flowers[3]; - - if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) - return EXIT_FAILURE; - - stage = clutter_stage_new (); - g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); - clutter_stage_set_title (CLUTTER_STAGE (stage), "Three Flowers in a Vase"); - clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE); - - /* there are three flowers in a vase */ - vase = clutter_actor_new (); - clutter_actor_set_name (vase, "vase"); - clutter_actor_set_layout_manager (vase, clutter_box_layout_new ()); - clutter_actor_set_background_color (vase, CLUTTER_COLOR_LightSkyBlue); - clutter_actor_add_constraint (vase, clutter_align_constraint_new (stage, CLUTTER_ALIGN_BOTH, 0.5)); - clutter_actor_add_child (stage, vase); - - flowers[0] = clutter_actor_new (); - clutter_actor_set_name (flowers[0], "flower.1"); - clutter_actor_set_size (flowers[0], SIZE, SIZE); - clutter_actor_set_margin_left (flowers[0], 12); - clutter_actor_set_background_color (flowers[0], CLUTTER_COLOR_Red); - clutter_actor_set_reactive (flowers[0], TRUE); - clutter_actor_add_child (vase, flowers[0]); - g_signal_connect (flowers[0], "button-press-event", - G_CALLBACK (animate_color), - NULL); - - flowers[1] = clutter_actor_new (); - clutter_actor_set_name (flowers[1], "flower.2"); - clutter_actor_set_size (flowers[1], SIZE, SIZE); - clutter_actor_set_margin_top (flowers[1], 12); - clutter_actor_set_margin_left (flowers[1], 6); - clutter_actor_set_margin_right (flowers[1], 6); - clutter_actor_set_margin_bottom (flowers[1], 12); - clutter_actor_set_background_color (flowers[1], CLUTTER_COLOR_Yellow); - clutter_actor_set_reactive (flowers[1], TRUE); - clutter_actor_add_child (vase, flowers[1]); - g_signal_connect (flowers[1], "enter-event", - G_CALLBACK (on_crossing), - NULL); - g_signal_connect (flowers[1], "leave-event", - G_CALLBACK (on_crossing), - NULL); - - /* the third one is green */ - flowers[2] = clutter_actor_new (); - clutter_actor_set_name (flowers[2], "flower.3"); - clutter_actor_set_size (flowers[2], SIZE, SIZE); - clutter_actor_set_margin_right (flowers[2], 12); - clutter_actor_set_background_color (flowers[2], CLUTTER_COLOR_Green); - clutter_actor_set_pivot_point (flowers[2], 0.5f, 0.0f); - clutter_actor_set_reactive (flowers[2], TRUE); - clutter_actor_add_child (vase, flowers[2]); - g_signal_connect (flowers[2], "button-press-event", - G_CALLBACK (animate_rotation), - NULL); - - clutter_actor_show (stage); - - clutter_main (); - - return EXIT_SUCCESS; -} diff --git a/clutter/examples/bin-layout.c b/clutter/examples/bin-layout.c deleted file mode 100644 index b6098d6fe..000000000 --- a/clutter/examples/bin-layout.c +++ /dev/null @@ -1,307 +0,0 @@ -#include -#include -#include -#include - -static const ClutterColor bg_color = { 0xcc, 0xcc, 0xcc, 0x99 }; - -static gboolean is_expanded = FALSE; - -static gboolean -on_canvas_draw (ClutterCanvas *canvas, - cairo_t *cr, - gint width, - gint height) -{ - cairo_pattern_t *pat; - gfloat x, y; - - g_print (G_STRLOC ": Painting at %d x %d\n", width, height); - - cairo_save (cr); - cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); - cairo_paint (cr); - cairo_restore (cr); - -#define BG_ROUND_RADIUS 12 - - x = y = 0; - - cairo_move_to (cr, BG_ROUND_RADIUS, y); - cairo_line_to (cr, width - BG_ROUND_RADIUS, y); - cairo_curve_to (cr, width, y, width, y, width, BG_ROUND_RADIUS); - cairo_line_to (cr, width, height - BG_ROUND_RADIUS); - cairo_curve_to (cr, width, height, width, height, width - BG_ROUND_RADIUS, height); - cairo_line_to (cr, BG_ROUND_RADIUS, height); - cairo_curve_to (cr, x, height, x, height, x, height - BG_ROUND_RADIUS); - cairo_line_to (cr, x, BG_ROUND_RADIUS); - cairo_curve_to (cr, x, y, x, y, BG_ROUND_RADIUS, y); - - cairo_close_path (cr); - - clutter_cairo_set_source_color (cr, &bg_color); - cairo_stroke (cr); - - x += 4; - y += 4; - width -= 4; - height -= 4; - - cairo_move_to (cr, BG_ROUND_RADIUS, y); - cairo_line_to (cr, width - BG_ROUND_RADIUS, y); - cairo_curve_to (cr, width, y, width, y, width, BG_ROUND_RADIUS); - cairo_line_to (cr, width, height - BG_ROUND_RADIUS); - cairo_curve_to (cr, width, height, width, height, width - BG_ROUND_RADIUS, height); - cairo_line_to (cr, BG_ROUND_RADIUS, height); - cairo_curve_to (cr, x, height, x, height, x, height - BG_ROUND_RADIUS); - cairo_line_to (cr, x, BG_ROUND_RADIUS); - cairo_curve_to (cr, x, y, x, y, BG_ROUND_RADIUS, y); - - cairo_close_path (cr); - - pat = cairo_pattern_create_linear (0, 0, 0, height); - cairo_pattern_add_color_stop_rgba (pat, 1, .85, .85, .85, 1); - cairo_pattern_add_color_stop_rgba (pat, .95, 1, 1, 1, 1); - cairo_pattern_add_color_stop_rgba (pat, .05, 1, 1, 1, 1); - cairo_pattern_add_color_stop_rgba (pat, 0, .85, .85, .85, 1); - - cairo_set_source (cr, pat); - cairo_fill (cr); - - cairo_pattern_destroy (pat); - -#undef BG_ROUND_RADIUS - - return TRUE; -} - -static gboolean -on_box_enter (ClutterActor *box, - ClutterEvent *event, - ClutterActor *emblem) -{ - /* we ease the opacity linearly */ - clutter_actor_save_easing_state (emblem); - clutter_actor_set_easing_mode (emblem, CLUTTER_LINEAR); - clutter_actor_set_opacity (emblem, 255); - clutter_actor_restore_easing_state (emblem); - - return CLUTTER_EVENT_STOP; -} - -static gboolean -on_box_leave (ClutterActor *box, - ClutterEvent *event, - ClutterActor *emblem) -{ - clutter_actor_save_easing_state (emblem); - clutter_actor_set_easing_mode (emblem, CLUTTER_LINEAR); - clutter_actor_set_opacity (emblem, 0); - clutter_actor_restore_easing_state (emblem); - - return CLUTTER_EVENT_STOP; -} - -static void -on_emblem_clicked (ClutterClickAction *action, - ClutterActor *emblem, - ClutterActor *box) -{ - /* we add a little bounce to the resizing of the box */ - clutter_actor_save_easing_state (box); - clutter_actor_set_easing_mode (box, CLUTTER_EASE_OUT_BOUNCE); - clutter_actor_set_easing_duration (box, 500); - - if (!is_expanded) - clutter_actor_set_size (box, 400, 400); - else - clutter_actor_set_size (box, 200, 200); - - clutter_actor_restore_easing_state (box); - - is_expanded = !is_expanded; -} - -static gboolean -on_emblem_long_press (ClutterClickAction *action, - ClutterActor *emblem, - ClutterLongPressState state, - ClutterActor *box) -{ - switch (state) - { - case CLUTTER_LONG_PRESS_QUERY: - g_print ("*** long press: query ***\n"); - return is_expanded; - - case CLUTTER_LONG_PRESS_CANCEL: - g_print ("*** long press: cancel ***\n"); - break; - - case CLUTTER_LONG_PRESS_ACTIVATE: - g_print ("*** long press: activate ***\n"); - break; - } - - return TRUE; -} - -static void -redraw_canvas (ClutterActor *actor, - ClutterCanvas *canvas) -{ - /* we want to invalidate the canvas and redraw its contents - * only when the size changes at the end of the animation, - * to avoid drawing all the states inbetween - */ - clutter_canvas_set_size (canvas, - clutter_actor_get_width (actor), - clutter_actor_get_height (actor)); -} - -int -main (int argc, char *argv[]) -{ - ClutterActor *stage, *box, *bg, *icon, *emblem, *label; - ClutterLayoutManager *layout; - ClutterContent *canvas, *image; - ClutterColor *color; - ClutterAction *action; - GdkPixbuf *pixbuf; - - if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) - return 1; - - /* prepare the stage */ - stage = clutter_stage_new (); - clutter_stage_set_title (CLUTTER_STAGE (stage), "BinLayout"); - clutter_actor_set_background_color (stage, CLUTTER_COLOR_Aluminium2); - clutter_actor_set_size (stage, 640, 480); - clutter_actor_show (stage); - g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); - - /* this is our BinLayout, with its default alignments */ - layout = clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_CENTER, - CLUTTER_BIN_ALIGNMENT_CENTER); - - /* the main container; this actor will use the BinLayout to lay - * out its children; we use the anchor point to keep it centered - * on the same position even when we change its size - */ - box = clutter_actor_new (); - clutter_actor_set_layout_manager (box, layout); - clutter_actor_add_constraint (box, clutter_align_constraint_new (stage, CLUTTER_ALIGN_BOTH, 0.5)); - clutter_actor_set_position (box, 320, 240); - clutter_actor_set_reactive (box, TRUE); - clutter_actor_set_name (box, "box"); - clutter_actor_add_child (stage, box); - - /* the background is drawn using a canvas content */ - canvas = clutter_canvas_new (); - g_signal_connect (canvas, "draw", G_CALLBACK (on_canvas_draw), NULL); - clutter_canvas_set_size (CLUTTER_CANVAS (canvas), 200, 200); - - /* this is the background actor; we want it to fill the whole - * of the allocation given to it by its parent - */ - bg = clutter_actor_new (); - clutter_actor_set_name (bg, "background"); - clutter_actor_set_size (bg, 200, 200); - clutter_actor_set_content (bg, canvas); - clutter_actor_set_x_expand (bg, TRUE); - clutter_actor_set_y_expand (bg, TRUE); - clutter_actor_set_x_align (bg, CLUTTER_ACTOR_ALIGN_FILL); - clutter_actor_set_y_align (bg, CLUTTER_ACTOR_ALIGN_FILL); - clutter_actor_add_child (box, bg); - /* we use the ::transitions-completed signal to get notification - * of the end of the sizing animation; this allows us to redraw - * the canvas only once the animation has stopped - */ - g_signal_connect (box, "transitions-completed", - G_CALLBACK (redraw_canvas), - canvas); - - /* we use GdkPixbuf to load an image from our data directory */ - pixbuf = gdk_pixbuf_new_from_file ("redhand.png", NULL); - image = clutter_image_new (); - clutter_image_set_data (CLUTTER_IMAGE (image), - gdk_pixbuf_get_pixels (pixbuf), - gdk_pixbuf_get_has_alpha (pixbuf) - ? COGL_PIXEL_FORMAT_RGBA_8888 - : COGL_PIXEL_FORMAT_RGB_888, - gdk_pixbuf_get_width (pixbuf), - gdk_pixbuf_get_height (pixbuf), - gdk_pixbuf_get_rowstride (pixbuf), - NULL); - g_object_unref (pixbuf); - - /* this is the icon; it's going to be centered inside the box actor. - * we use the content gravity to keep the aspect ratio of the image, - * and the scaling filters to get a better result when scaling the - * image down. - */ - icon = clutter_actor_new (); - clutter_actor_set_name (icon, "icon"); - clutter_actor_set_size (icon, 196, 196); - clutter_actor_set_x_expand (icon, TRUE); - clutter_actor_set_y_expand (icon, TRUE); - clutter_actor_set_x_align (icon, CLUTTER_ACTOR_ALIGN_CENTER); - clutter_actor_set_y_align (icon, CLUTTER_ACTOR_ALIGN_CENTER); - clutter_actor_set_content_gravity (icon, CLUTTER_CONTENT_GRAVITY_RESIZE_ASPECT); - clutter_actor_set_content_scaling_filters (icon, - CLUTTER_SCALING_FILTER_TRILINEAR, - CLUTTER_SCALING_FILTER_LINEAR); - clutter_actor_set_content (icon, image); - clutter_actor_add_child (box, icon); - - color = clutter_color_new (g_random_int_range (0, 255), - g_random_int_range (0, 255), - g_random_int_range (0, 255), - 224); - - /* this is the emblem: a small rectangle with a random color, that we - * want to put in the bottom right corner - */ - emblem = clutter_actor_new (); - clutter_actor_set_name (emblem, "emblem"); - clutter_actor_set_size (emblem, 48, 48); - clutter_actor_set_background_color (emblem, color); - clutter_actor_set_x_expand (emblem, TRUE); - clutter_actor_set_y_expand (emblem, TRUE); - clutter_actor_set_x_align (emblem, CLUTTER_ACTOR_ALIGN_END); - clutter_actor_set_y_align (emblem, CLUTTER_ACTOR_ALIGN_END); - clutter_actor_set_reactive (emblem, TRUE); - clutter_actor_set_opacity (emblem, 0); - clutter_actor_add_child (box, emblem); - clutter_color_free (color); - - /* when clicking on the emblem, we want to perform an action */ - action = clutter_click_action_new (); - clutter_actor_add_action (emblem, action); - g_signal_connect (action, "clicked", G_CALLBACK (on_emblem_clicked), box); - g_signal_connect (action, "long-press", G_CALLBACK (on_emblem_long_press), box); - - /* whenever the pointer enters the box, we show the emblem; we hide - * the emblem when the pointer leaves the box - */ - g_signal_connect (box, - "enter-event", G_CALLBACK (on_box_enter), - emblem); - g_signal_connect (box, - "leave-event", G_CALLBACK (on_box_leave), - emblem); - - /* a label, that we want to position at the top and center of the box */ - label = clutter_text_new (); - clutter_actor_set_name (label, "text"); - clutter_text_set_text (CLUTTER_TEXT (label), "A simple test"); - clutter_actor_set_x_expand (label, TRUE); - clutter_actor_set_x_align (label, CLUTTER_ACTOR_ALIGN_CENTER); - clutter_actor_set_y_expand (label, TRUE); - clutter_actor_set_y_align (label, CLUTTER_ACTOR_ALIGN_START); - clutter_actor_add_child (box, label); - - clutter_main (); - - return EXIT_SUCCESS; -} diff --git a/clutter/examples/box-layout.c b/clutter/examples/box-layout.c deleted file mode 100644 index cd5401368..000000000 --- a/clutter/examples/box-layout.c +++ /dev/null @@ -1,314 +0,0 @@ -/* - * Copyright 2009 Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU Lesser General Public License, - * version 2.1, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for - * more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * Boston, MA 02111-1307, USA. - * - */ -#include -#include - -#define INSTRUCTIONS \ - "Press v\t\342\236\236\tSwitch horizontal/vertical\n" \ - "Press h\t\342\236\236\tToggle homogeneous\n" \ - "Press p\t\342\236\236\tToggle pack start/end\n" \ - "Press s\t\342\236\236\tIncrement spacing (up to 12px)\n" \ - "Press +\t\342\236\236\tAdd a new actor\n" \ - "Press a\t\342\236\236\tToggle animations\n" \ - "Press q\t\342\236\236\tQuit" - - -static const gchar * -get_align_name (ClutterActorAlign align) -{ - switch (align) - { - case CLUTTER_ACTOR_ALIGN_FILL: - return "fill"; - - case CLUTTER_ACTOR_ALIGN_START: - return "start"; - - case CLUTTER_ACTOR_ALIGN_CENTER: - return "center"; - - case CLUTTER_ACTOR_ALIGN_END: - return "end"; - - default: - g_assert_not_reached (); - } -} - -static gboolean -button_release_cb (ClutterActor *rect, - ClutterEvent *event, - gpointer user_data) -{ - ClutterActorAlign x_align, y_align; - gboolean x_expand, y_expand; - - g_object_get (rect, - "x-align", &x_align, - "y-align", &y_align, - "x-expand", &x_expand, - "y-expand", &y_expand, - NULL); - - switch (clutter_event_get_button (event)) - { - case CLUTTER_BUTTON_PRIMARY: - if (clutter_event_has_shift_modifier (event)) - { - if (y_align < 3) - y_align += 1; - else - y_align = 0; - break; - } - else - { - if (x_align < 3) - x_align += 1; - else - x_align = 0; - } - break; - - case CLUTTER_BUTTON_SECONDARY: - if (clutter_event_has_shift_modifier (event)) - y_expand = !y_expand; - else - x_expand = !x_expand; - break; - - default: - break; - } - - g_object_set (rect, - "x-align", x_align, - "y-align", y_align, - "x-expand", x_expand, - "y-expand", y_expand, - NULL); - return TRUE; -} - -static void -changed_cb (ClutterActor *actor, - GParamSpec *pspec, - ClutterActor *text) -{ - ClutterActorAlign x_align, y_align; - gboolean x_expand, y_expand; - gchar *label; - - g_object_get (actor, - "x-align", &x_align, - "y-align", &y_align, - "x-expand", &x_expand, - "y-expand", &y_expand, - NULL); - - label = g_strdup_printf ("%d,%d\n" - "%s\n%s", - x_expand, y_expand, - get_align_name (x_align), - get_align_name (y_align)); - clutter_text_set_text (CLUTTER_TEXT (text), label); - free (label); -} - -static void -add_actor (ClutterActor *box, - gint position) -{ - ClutterActor *rect, *text; - ClutterColor color; - ClutterLayoutManager *layout; - - clutter_color_from_hls (&color, - g_random_double_range (0.0, 360.0), - 0.5, - 0.5); - color.alpha = 255; - - layout = clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_CENTER, - CLUTTER_BIN_ALIGNMENT_CENTER); - rect = clutter_actor_new (); - clutter_actor_set_layout_manager (rect, layout); - clutter_actor_set_background_color (rect, &color); - clutter_actor_set_reactive (rect, TRUE); - clutter_actor_set_size (rect, 32, 64); - clutter_actor_set_x_expand (rect, TRUE); - clutter_actor_set_y_expand (rect, TRUE); - clutter_actor_set_x_align (rect, CLUTTER_ACTOR_ALIGN_CENTER); - clutter_actor_set_y_align (rect, CLUTTER_ACTOR_ALIGN_CENTER); - - text = clutter_text_new_with_text ("Sans 8px", NULL); - clutter_text_set_line_alignment (CLUTTER_TEXT (text), - PANGO_ALIGN_CENTER); - clutter_actor_add_child (rect, text); - - g_signal_connect (rect, "button-release-event", - G_CALLBACK (button_release_cb), NULL); - g_signal_connect (rect, "notify::x-expand", - G_CALLBACK (changed_cb), text); - g_signal_connect (rect, "notify::y-expand", - G_CALLBACK (changed_cb), text); - g_signal_connect (rect, "notify::x-align", - G_CALLBACK (changed_cb), text); - g_signal_connect (rect, "notify::y-align", - G_CALLBACK (changed_cb), text); - changed_cb (rect, NULL, text); - - clutter_actor_insert_child_at_index (box, rect, position); -} - -static gboolean -key_release_cb (ClutterActor *stage, - ClutterEvent *event, - ClutterActor *box) -{ - ClutterBoxLayout *layout; - gboolean toggle; - guint spacing; - - layout = CLUTTER_BOX_LAYOUT (clutter_actor_get_layout_manager (box)); - - switch (clutter_event_get_key_symbol (event)) - { - case CLUTTER_KEY_a: - { - ClutterActorIter iter; - ClutterActor *child; - - clutter_actor_iter_init (&iter, box); - while (clutter_actor_iter_next (&iter, &child)) - { - guint duration; - - duration = clutter_actor_get_easing_duration (child); - if (duration != 0) - duration = 0; - else - duration = 250; - - clutter_actor_set_easing_duration (child, duration); - } - } - break; - - case CLUTTER_KEY_v: - { - ClutterOrientation orientation; - - orientation = clutter_box_layout_get_orientation (layout); - - if (orientation == CLUTTER_ORIENTATION_HORIZONTAL) - orientation = CLUTTER_ORIENTATION_VERTICAL; - else - orientation = CLUTTER_ORIENTATION_HORIZONTAL; - - clutter_box_layout_set_orientation (layout, orientation); - } - break; - - case CLUTTER_KEY_h: - toggle = clutter_box_layout_get_homogeneous (layout); - clutter_box_layout_set_homogeneous (layout, !toggle); - break; - - case CLUTTER_KEY_p: - toggle = clutter_box_layout_get_pack_start (layout); - clutter_box_layout_set_pack_start (layout, !toggle); - break; - - case CLUTTER_KEY_s: - spacing = clutter_box_layout_get_spacing (layout); - - if (spacing > 12) - spacing = 0; - else - spacing++; - - clutter_box_layout_set_spacing (layout, spacing); - break; - - case CLUTTER_KEY_plus: - add_actor (box, g_random_int_range (0, clutter_actor_get_n_children (box))); - break; - - case CLUTTER_KEY_q: - clutter_main_quit (); - break; - - default: - return FALSE; - } - - return TRUE; -} - -int -main (int argc, char *argv[]) -{ - ClutterActor *stage, *box, *instructions; - ClutterLayoutManager *layout; - gint i; - - if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) - return EXIT_FAILURE; - - stage = clutter_stage_new (); - clutter_stage_set_title (CLUTTER_STAGE (stage), "Box Layout"); - clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE); - - /* make the stage a vbox */ - layout = clutter_box_layout_new (); - clutter_box_layout_set_orientation (CLUTTER_BOX_LAYOUT (layout), - CLUTTER_ORIENTATION_VERTICAL); - clutter_actor_set_layout_manager (stage, layout); - - box = clutter_actor_new (); - clutter_actor_set_background_color (box, CLUTTER_COLOR_LightGray); - clutter_actor_set_x_expand (box, TRUE); - clutter_actor_set_y_expand (box, TRUE); - layout = clutter_box_layout_new (); - clutter_actor_set_layout_manager (box, layout); - clutter_actor_add_child (stage, box); - - instructions = clutter_text_new_with_text ("Sans 12px", INSTRUCTIONS); - clutter_actor_set_x_expand (instructions, TRUE); - clutter_actor_set_y_expand (instructions, FALSE); - clutter_actor_set_x_align (instructions, CLUTTER_ACTOR_ALIGN_START); - clutter_actor_set_margin_top (instructions, 4); - clutter_actor_set_margin_left (instructions, 4); - clutter_actor_set_margin_bottom (instructions, 4); - clutter_actor_add_child (stage, instructions); - - for (i = 0; i < 5; i++) - add_actor (box, i); - - g_signal_connect (stage, "destroy", - G_CALLBACK (clutter_main_quit), NULL); - g_signal_connect (stage, "key-release-event", - G_CALLBACK (key_release_cb), box); - - clutter_actor_show (stage); - clutter_main (); - - return EXIT_SUCCESS; -} diff --git a/clutter/examples/canvas.c b/clutter/examples/canvas.c deleted file mode 100644 index 2371f96c6..000000000 --- a/clutter/examples/canvas.c +++ /dev/null @@ -1,170 +0,0 @@ -#include -#include -#include -#include - -static gboolean -draw_clock (ClutterCanvas *canvas, - cairo_t *cr, - int width, - int height) -{ - GDateTime *now; - float hours, minutes, seconds; - ClutterColor color; - - /* get the current time and compute the angles */ - now = g_date_time_new_now_local (); - seconds = g_date_time_get_second (now) * G_PI / 30; - minutes = g_date_time_get_minute (now) * G_PI / 30; - hours = g_date_time_get_hour (now) * G_PI / 6; - - cairo_save (cr); - - /* clear the contents of the canvas, to avoid painting - * over the previous frame - */ - cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); - cairo_paint (cr); - - cairo_restore (cr); - - cairo_set_operator (cr, CAIRO_OPERATOR_OVER); - - /* scale the modelview to the size of the surface */ - cairo_scale (cr, width, height); - - cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); - cairo_set_line_width (cr, 0.1); - - /* the black rail that holds the seconds indicator */ - clutter_cairo_set_source_color (cr, CLUTTER_COLOR_Black); - cairo_translate (cr, 0.5, 0.5); - cairo_arc (cr, 0, 0, 0.4, 0, G_PI * 2); - cairo_stroke (cr); - - /* the seconds indicator */ - color = *CLUTTER_COLOR_White; - color.alpha = 128; - clutter_cairo_set_source_color (cr, &color); - cairo_move_to (cr, 0, 0); - cairo_arc (cr, sinf (seconds) * 0.4, - cosf (seconds) * 0.4, 0.05, 0, G_PI * 2); - cairo_fill (cr); - - /* the minutes hand */ - color = *CLUTTER_COLOR_DarkChameleon; - color.alpha = 196; - clutter_cairo_set_source_color (cr, &color); - cairo_move_to (cr, 0, 0); - cairo_line_to (cr, sinf (minutes) * 0.4, -cosf (minutes) * 0.4); - cairo_stroke (cr); - - /* the hours hand */ - cairo_move_to (cr, 0, 0); - cairo_line_to (cr, sinf (hours) * 0.2, -cosf (hours) * 0.2); - cairo_stroke (cr); - - g_date_time_unref (now); - - /* we're done drawing */ - return TRUE; -} - -static gboolean -invalidate_clock (gpointer data_) -{ - /* invalidate the contents of the canvas */ - clutter_content_invalidate (data_); - - /* keep the timeout source */ - return G_SOURCE_CONTINUE; -} - -static guint idle_resize_id; - -static gboolean -idle_resize (gpointer data) -{ - ClutterActor *actor = data; - float width, height; - - /* match the canvas size to the actor's */ - clutter_actor_get_size (actor, &width, &height); - clutter_canvas_set_size (CLUTTER_CANVAS (clutter_actor_get_content (actor)), - ceilf (width), - ceilf (height)); - - /* unset the guard */ - idle_resize_id = 0; - - /* remove the timeout */ - return G_SOURCE_REMOVE; -} - -static void -on_actor_resize (ClutterActor *actor, - const ClutterActorBox *allocation, - ClutterAllocationFlags flags, - gpointer user_data) -{ - /* throttle multiple actor allocations to one canvas resize; we use a guard - * variable to avoid queueing multiple resize operations - */ - if (idle_resize_id == 0) - idle_resize_id = clutter_threads_add_timeout (1000, idle_resize, actor); -} - -int -main (int argc, char *argv[]) -{ - ClutterActor *stage, *actor; - ClutterContent *canvas; - - /* initialize Clutter */ - if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) - return EXIT_FAILURE; - - /* create a resizable stage */ - stage = clutter_stage_new (); - clutter_stage_set_title (CLUTTER_STAGE (stage), "2D Clock"); - clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE); - clutter_actor_set_background_color (stage, CLUTTER_COLOR_LightSkyBlue); - clutter_actor_set_size (stage, 300, 300); - clutter_actor_show (stage); - - /* our 2D canvas, courtesy of Cairo */ - canvas = clutter_canvas_new (); - clutter_canvas_set_size (CLUTTER_CANVAS (canvas), 300, 300); - - actor = clutter_actor_new (); - clutter_actor_set_content (actor, canvas); - clutter_actor_set_content_scaling_filters (actor, - CLUTTER_SCALING_FILTER_TRILINEAR, - CLUTTER_SCALING_FILTER_LINEAR); - clutter_actor_add_child (stage, actor); - - /* the actor now owns the canvas */ - g_object_unref (canvas); - - /* bind the size of the actor to that of the stage */ - clutter_actor_add_constraint (actor, clutter_bind_constraint_new (stage, CLUTTER_BIND_SIZE, 0)); - - /* resize the canvas whenever the actor changes size */ - g_signal_connect (actor, "allocation-changed", G_CALLBACK (on_actor_resize), NULL); - - /* quit on destroy */ - g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); - - /* connect our drawing code */ - g_signal_connect (canvas, "draw", G_CALLBACK (draw_clock), NULL); - - /* invalidate the canvas, so that we can draw before the main loop starts */ - clutter_content_invalidate (canvas); - - /* set up a timer that invalidates the canvas every second */ - clutter_threads_add_timeout (1000, invalidate_clock, canvas); - - clutter_main (); - - return EXIT_SUCCESS; -} diff --git a/clutter/examples/constraints.c b/clutter/examples/constraints.c deleted file mode 100644 index 99af0a4d3..000000000 --- a/clutter/examples/constraints.c +++ /dev/null @@ -1,90 +0,0 @@ -#include -#include - -int -main (int argc, char *argv[]) -{ - ClutterActor *stage, *layer_a, *layer_b, *layer_c; - - if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) - return 1; - - /* the main container */ - stage = clutter_stage_new (); - clutter_actor_set_name (stage, "stage"); - clutter_stage_set_title (CLUTTER_STAGE (stage), "Snap Constraint"); - clutter_actor_set_background_color (stage, CLUTTER_COLOR_Aluminium1); - clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE); - g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); - - /* first layer, with a fixed (100, 25) size */ - layer_a = clutter_actor_new (); - clutter_actor_set_background_color (layer_a, CLUTTER_COLOR_ScarletRed); - clutter_actor_set_name (layer_a, "layerA"); - clutter_actor_set_size (layer_a, 100.0, 25.0); - clutter_actor_add_child (stage, layer_a); - - /* the first layer is anchored to the middle of the stage */ - clutter_actor_add_constraint (layer_a, clutter_align_constraint_new (stage, CLUTTER_ALIGN_BOTH, 0.5)); - - /* second layer, with no implicit size */ - layer_b = clutter_actor_new (); - clutter_actor_set_background_color (layer_b, CLUTTER_COLOR_DarkButter); - clutter_actor_set_name (layer_b, "layerB"); - clutter_actor_add_child (stage, layer_b); - - /* the second layer tracks the X coordinate and the width of - * the first layer - */ - clutter_actor_add_constraint (layer_b, clutter_bind_constraint_new (layer_a, CLUTTER_BIND_X, 0.0)); - clutter_actor_add_constraint (layer_b, clutter_bind_constraint_new (layer_a, CLUTTER_BIND_WIDTH, 0.0)); - - /* the second layer is snapped between the bottom edge of - * the first layer, and the bottom edge of the stage; a - * spacing of 10 pixels in each direction is added for padding - */ - clutter_actor_add_constraint (layer_b, - clutter_snap_constraint_new (layer_a, - CLUTTER_SNAP_EDGE_TOP, - CLUTTER_SNAP_EDGE_BOTTOM, - 10.0)); - - clutter_actor_add_constraint (layer_b, - clutter_snap_constraint_new (stage, - CLUTTER_SNAP_EDGE_BOTTOM, - CLUTTER_SNAP_EDGE_BOTTOM, - -10.0)); - - /* the third layer, with no implicit size */ - layer_c = clutter_actor_new (); - clutter_actor_set_background_color (layer_c, CLUTTER_COLOR_LightChameleon); - clutter_actor_set_name (layer_c, "layerC"); - clutter_actor_add_child (stage, layer_c); - - /* as for the second layer, the third layer tracks the X - * coordinate and width of the first layer - */ - clutter_actor_add_constraint (layer_c, clutter_bind_constraint_new (layer_a, CLUTTER_BIND_X, 0.0)); - clutter_actor_add_constraint (layer_c, clutter_bind_constraint_new (layer_a, CLUTTER_BIND_WIDTH, 0.0)); - - /* the third layer is snapped between the top edge of the stage - * and the top edge of the first layer; again, a spacing of - * 10 pixels in each direction is added for padding - */ - clutter_actor_add_constraint (layer_c, - clutter_snap_constraint_new (layer_a, - CLUTTER_SNAP_EDGE_BOTTOM, - CLUTTER_SNAP_EDGE_TOP, - -10.0)); - clutter_actor_add_constraint (layer_c, - clutter_snap_constraint_new (stage, - CLUTTER_SNAP_EDGE_TOP, - CLUTTER_SNAP_EDGE_TOP, - 10.0)); - - clutter_actor_show (stage); - - clutter_main (); - - return EXIT_SUCCESS; -} diff --git a/clutter/examples/drag-action.c b/clutter/examples/drag-action.c deleted file mode 100644 index d6ed5676a..000000000 --- a/clutter/examples/drag-action.c +++ /dev/null @@ -1,249 +0,0 @@ -#include -#include - -static gboolean -on_enter (ClutterActor *actor, - ClutterEvent *event) -{ - ClutterTransition *t; - - t = clutter_actor_get_transition (actor, "curl"); - if (t == NULL) - { - t = clutter_property_transition_new ("@effects.curl.period"); - clutter_timeline_set_duration (CLUTTER_TIMELINE (t), 250); - clutter_actor_add_transition (actor, "curl", t); - g_object_unref (t); - } - - clutter_transition_set_from (t, G_TYPE_DOUBLE, 0.0); - clutter_transition_set_to (t, G_TYPE_DOUBLE, 0.25); - clutter_timeline_rewind (CLUTTER_TIMELINE (t)); - clutter_timeline_start (CLUTTER_TIMELINE (t)); - - return CLUTTER_EVENT_STOP; -} - -static gboolean -on_leave (ClutterActor *actor, - ClutterEvent *event) -{ - ClutterTransition *t; - - t = clutter_actor_get_transition (actor, "curl"); - if (t == NULL) - { - t = clutter_property_transition_new ("@effects.curl.period"); - clutter_timeline_set_duration (CLUTTER_TIMELINE (t), 250); - clutter_actor_add_transition (actor, "curl", t); - g_object_unref (t); - } - - clutter_transition_set_from (t, G_TYPE_DOUBLE, 0.25); - clutter_transition_set_to (t, G_TYPE_DOUBLE, 0.0); - clutter_timeline_rewind (CLUTTER_TIMELINE (t)); - clutter_timeline_start (CLUTTER_TIMELINE (t)); - - return CLUTTER_EVENT_STOP; -} - -static void -on_drag_begin (ClutterDragAction *action, - ClutterActor *actor, - gfloat event_x, - gfloat event_y, - ClutterModifierType modifiers) -{ - gboolean is_copy = (modifiers & CLUTTER_SHIFT_MASK) ? TRUE : FALSE; - ClutterActor *drag_handle = NULL; - ClutterTransition *t; - - if (is_copy) - { - ClutterActor *stage = clutter_actor_get_stage (actor); - - drag_handle = clutter_actor_new (); - clutter_actor_set_size (drag_handle, 48, 48); - - clutter_actor_set_background_color (drag_handle, CLUTTER_COLOR_DarkSkyBlue); - - clutter_actor_add_child (stage, drag_handle); - clutter_actor_set_position (drag_handle, event_x, event_y); - } - else - drag_handle = actor; - - clutter_drag_action_set_drag_handle (action, drag_handle); - - /* fully desaturate the actor */ - t = clutter_actor_get_transition (actor, "disable"); - if (t == NULL) - { - t = clutter_property_transition_new ("@effects.disable.factor"); - clutter_timeline_set_duration (CLUTTER_TIMELINE (t), 250); - clutter_actor_add_transition (actor, "disable", t); - g_object_unref (t); - } - - clutter_transition_set_from (t, G_TYPE_DOUBLE, 0.0); - clutter_transition_set_to (t, G_TYPE_DOUBLE, 1.0); - clutter_timeline_rewind (CLUTTER_TIMELINE (t)); - clutter_timeline_start (CLUTTER_TIMELINE (t)); -} - -static void -on_drag_end (ClutterDragAction *action, - ClutterActor *actor, - gfloat event_x, - gfloat event_y, - ClutterModifierType modifiers) -{ - ClutterActor *drag_handle; - ClutterTransition *t; - - drag_handle = clutter_drag_action_get_drag_handle (action); - if (actor != drag_handle) - { - gfloat real_x, real_y; - ClutterActor *parent; - - /* if we are dragging a copy we can destroy the copy now - * and animate the real actor to the drop coordinates, - * transformed in the parent's coordinate space - */ - clutter_actor_save_easing_state (drag_handle); - clutter_actor_set_easing_mode (drag_handle, CLUTTER_LINEAR); - clutter_actor_set_opacity (drag_handle, 0); - clutter_actor_restore_easing_state (drag_handle); - g_signal_connect (drag_handle, "transitions-completed", - G_CALLBACK (clutter_actor_destroy), - NULL); - - parent = clutter_actor_get_parent (actor); - clutter_actor_transform_stage_point (parent, event_x, event_y, - &real_x, - &real_y); - - clutter_actor_save_easing_state (actor); - clutter_actor_set_easing_mode (actor, CLUTTER_EASE_OUT_CUBIC); - clutter_actor_set_position (actor, real_x, real_y); - clutter_actor_restore_easing_state (actor); - } - - t = clutter_actor_get_transition (actor, "disable"); - if (t == NULL) - { - t = clutter_property_transition_new ("@effects.disable.factor"); - clutter_timeline_set_duration (CLUTTER_TIMELINE (t), 250); - clutter_actor_add_transition (actor, "disable", t); - g_object_unref (t); - } - - clutter_transition_set_from (t, G_TYPE_DOUBLE, 1.0); - clutter_transition_set_to (t, G_TYPE_DOUBLE, 0.0); - clutter_timeline_rewind (CLUTTER_TIMELINE (t)); - clutter_timeline_start (CLUTTER_TIMELINE (t)); -} - -static ClutterDragAxis -get_drag_axis (const gchar *str) -{ - if (str == NULL || *str == '\0') - return CLUTTER_DRAG_AXIS_NONE; - - if (*str == 'x' || *str == 'X') - return CLUTTER_DRAG_X_AXIS; - - if (*str == 'y' || *str == 'Y') - return CLUTTER_DRAG_Y_AXIS; - - g_warn_if_reached (); - - return CLUTTER_DRAG_AXIS_NONE; -} - -static gchar *drag_axis = NULL; -static gint x_drag_threshold = 0; -static gint y_drag_threshold = 0; - -static GOptionEntry entries[] = { - { - "x-threshold", 'x', - 0, - G_OPTION_ARG_INT, - &x_drag_threshold, - "Set the horizontal drag threshold", "PIXELS" - }, - { - "y-threshold", 'y', - 0, - G_OPTION_ARG_INT, - &y_drag_threshold, - "Set the vertical drag threshold", "PIXELS" - }, - { - "axis", 'a', - 0, - G_OPTION_ARG_STRING, - &drag_axis, - "Set the drag axis", "AXIS" - }, - - { NULL } -}; - -int -main (int argc, char *argv[]) -{ - ClutterActor *stage, *handle; - ClutterAction *action; - GError *error; - - error = NULL; - if (clutter_init_with_args (&argc, &argv, - "test-drag", - entries, - NULL, - &error) != CLUTTER_INIT_SUCCESS) - { - g_print ("Unable to run drag-action: %s\n", error->message); - g_error_free (error); - - return EXIT_FAILURE; - } - - stage = clutter_stage_new (); - clutter_stage_set_title (CLUTTER_STAGE (stage), "Drag Test"); - clutter_actor_set_size (stage, 800, 600); - g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); - - handle = clutter_actor_new (); - clutter_actor_set_background_color (handle, CLUTTER_COLOR_SkyBlue); - clutter_actor_set_size (handle, 128, 128); - clutter_actor_set_position (handle, (800 - 128) / 2, (600 - 128) / 2); - clutter_actor_set_reactive (handle, TRUE); - clutter_actor_add_child (stage, handle); - g_signal_connect (handle, "enter-event", G_CALLBACK (on_enter), NULL); - g_signal_connect (handle, "leave-event", G_CALLBACK (on_leave), NULL); - - action = clutter_drag_action_new (); - clutter_drag_action_set_drag_threshold (CLUTTER_DRAG_ACTION (action), - x_drag_threshold, - y_drag_threshold); - clutter_drag_action_set_drag_axis (CLUTTER_DRAG_ACTION (action), - get_drag_axis (drag_axis)); - - g_signal_connect (action, "drag-begin", G_CALLBACK (on_drag_begin), NULL); - g_signal_connect (action, "drag-end", G_CALLBACK (on_drag_end), NULL); - - clutter_actor_add_action (handle, action); - - clutter_actor_add_effect_with_name (handle, "disable", clutter_desaturate_effect_new (0.0)); - clutter_actor_add_effect_with_name (handle, "curl", clutter_page_turn_effect_new (0.0, 45.0, 12.0)); - - clutter_actor_show (stage); - - clutter_main (); - - return EXIT_SUCCESS; -} diff --git a/clutter/examples/drop-action.c b/clutter/examples/drop-action.c deleted file mode 100644 index 55615e120..000000000 --- a/clutter/examples/drop-action.c +++ /dev/null @@ -1,263 +0,0 @@ -#include -#include - -#define TARGET_SIZE 200 -#define HANDLE_SIZE 128 - -static ClutterActor *stage = NULL; -static ClutterActor *target1 = NULL; -static ClutterActor *target2 = NULL; -static ClutterActor *drag = NULL; - -static gboolean drop_successful = FALSE; - -static void add_drag_object (ClutterActor *target); - -static void -on_drag_end (ClutterDragAction *action, - ClutterActor *actor, - gfloat event_x, - gfloat event_y, - ClutterModifierType modifiers) -{ - ClutterActor *handle = clutter_drag_action_get_drag_handle (action); - - g_print ("Drag ended at: %.0f, %.0f\n", - event_x, event_y); - - clutter_actor_save_easing_state (actor); - clutter_actor_set_easing_mode (actor, CLUTTER_LINEAR); - clutter_actor_set_opacity (actor, 255); - clutter_actor_restore_easing_state (actor); - - clutter_actor_save_easing_state (handle); - - if (!drop_successful) - { - ClutterActor *parent = clutter_actor_get_parent (actor); - gfloat x_pos, y_pos; - - clutter_actor_save_easing_state (parent); - clutter_actor_set_easing_mode (parent, CLUTTER_LINEAR); - clutter_actor_set_opacity (parent, 255); - clutter_actor_restore_easing_state (parent); - - clutter_actor_get_transformed_position (actor, &x_pos, &y_pos); - - clutter_actor_set_easing_mode (handle, CLUTTER_EASE_OUT_BOUNCE); - clutter_actor_set_position (handle, x_pos, y_pos); - clutter_actor_set_opacity (handle, 0); - - } - else - { - clutter_actor_set_easing_mode (handle, CLUTTER_LINEAR); - clutter_actor_set_opacity (handle, 0); - } - - clutter_actor_restore_easing_state (handle); - - g_signal_connect (handle, "transitions-completed", - G_CALLBACK (clutter_actor_destroy), - NULL); -} - -static void -on_drag_begin (ClutterDragAction *action, - ClutterActor *actor, - gfloat event_x, - gfloat event_y, - ClutterModifierType modifiers) -{ - ClutterActor *handle; - gfloat x_pos, y_pos; - - clutter_actor_get_position (actor, &x_pos, &y_pos); - - handle = clutter_actor_new (); - clutter_actor_set_background_color (handle, CLUTTER_COLOR_DarkSkyBlue); - clutter_actor_set_size (handle, 128, 128); - clutter_actor_set_position (handle, event_x - x_pos, event_y - y_pos); - clutter_actor_add_child (stage, handle); - - clutter_drag_action_set_drag_handle (action, handle); - - clutter_actor_save_easing_state (actor); - clutter_actor_set_easing_mode (actor, CLUTTER_LINEAR); - clutter_actor_set_opacity (actor, 128); - clutter_actor_restore_easing_state (actor); - - drop_successful = FALSE; -} - -static void -add_drag_object (ClutterActor *target) -{ - ClutterActor *parent; - - if (drag == NULL) - { - ClutterAction *action; - - drag = clutter_actor_new (); - clutter_actor_set_background_color (drag, CLUTTER_COLOR_LightSkyBlue); - clutter_actor_set_size (drag, HANDLE_SIZE, HANDLE_SIZE); - clutter_actor_set_position (drag, - (TARGET_SIZE - HANDLE_SIZE) / 2.0, - (TARGET_SIZE - HANDLE_SIZE) / 2.0); - clutter_actor_set_reactive (drag, TRUE); - - action = clutter_drag_action_new (); - g_signal_connect (action, "drag-begin", G_CALLBACK (on_drag_begin), NULL); - g_signal_connect (action, "drag-end", G_CALLBACK (on_drag_end), NULL); - - clutter_actor_add_action (drag, action); - } - - parent = clutter_actor_get_parent (drag); - if (parent == target) - { - clutter_actor_save_easing_state (target); - clutter_actor_set_easing_mode (target, CLUTTER_LINEAR); - clutter_actor_set_opacity (target, 255); - clutter_actor_restore_easing_state (target); - return; - } - - g_object_ref (drag); - if (parent != NULL && parent != stage) - { - clutter_actor_remove_child (parent, drag); - - clutter_actor_save_easing_state (parent); - clutter_actor_set_easing_mode (parent, CLUTTER_LINEAR); - clutter_actor_set_opacity (parent, 64); - clutter_actor_restore_easing_state (parent); - } - - clutter_actor_add_child (target, drag); - - clutter_actor_save_easing_state (target); - clutter_actor_set_easing_mode (target, CLUTTER_LINEAR); - clutter_actor_set_opacity (target, 255); - clutter_actor_restore_easing_state (target); - - g_object_unref (drag); -} - -static void -on_target_over (ClutterDropAction *action, - ClutterActor *actor, - gpointer _data) -{ - gboolean is_over = GPOINTER_TO_UINT (_data); - guint8 final_opacity = is_over ? 128 : 64; - ClutterActor *target; - - target = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action)); - - clutter_actor_save_easing_state (target); - clutter_actor_set_easing_mode (target, CLUTTER_LINEAR); - clutter_actor_set_opacity (target, final_opacity); - clutter_actor_restore_easing_state (target); -} - -static void -on_target_drop (ClutterDropAction *action, - ClutterActor *actor, - gfloat event_x, - gfloat event_y) -{ - gfloat actor_x, actor_y; - - actor_x = actor_y = 0.0f; - - clutter_actor_transform_stage_point (actor, event_x, event_y, - &actor_x, - &actor_y); - - g_print ("Dropped at %.0f, %.0f (screen: %.0f, %.0f)\n", - actor_x, actor_y, - event_x, event_y); - - drop_successful = TRUE; - add_drag_object (actor); -} - -int -main (int argc, char *argv[]) -{ - ClutterActor *dummy; - - if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) - return EXIT_FAILURE; - - stage = clutter_stage_new (); - clutter_stage_set_title (CLUTTER_STAGE (stage), "Drop Action"); - g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); - - target1 = clutter_actor_new (); - clutter_actor_set_background_color (target1, CLUTTER_COLOR_LightScarletRed); - clutter_actor_set_size (target1, TARGET_SIZE, TARGET_SIZE); - clutter_actor_set_opacity (target1, 64); - clutter_actor_add_constraint (target1, clutter_align_constraint_new (stage, CLUTTER_ALIGN_Y_AXIS, 0.5)); - clutter_actor_set_x (target1, 10); - clutter_actor_set_reactive (target1, TRUE); - - clutter_actor_add_action_with_name (target1, "drop", clutter_drop_action_new ()); - g_signal_connect (clutter_actor_get_action (target1, "drop"), - "over-in", - G_CALLBACK (on_target_over), - GUINT_TO_POINTER (TRUE)); - g_signal_connect (clutter_actor_get_action (target1, "drop"), - "over-out", - G_CALLBACK (on_target_over), - GUINT_TO_POINTER (FALSE)); - g_signal_connect (clutter_actor_get_action (target1, "drop"), - "drop", - G_CALLBACK (on_target_drop), - NULL); - - dummy = clutter_actor_new (); - clutter_actor_set_background_color (dummy, CLUTTER_COLOR_DarkOrange); - clutter_actor_set_size (dummy, - 640 - (2 * 10) - (2 * (TARGET_SIZE + 10)), - TARGET_SIZE); - clutter_actor_add_constraint (dummy, clutter_align_constraint_new (stage, CLUTTER_ALIGN_X_AXIS, 0.5)); - clutter_actor_add_constraint (dummy, clutter_align_constraint_new (stage, CLUTTER_ALIGN_Y_AXIS, 0.5)); - clutter_actor_set_reactive (dummy, TRUE); - - target2 = clutter_actor_new (); - clutter_actor_set_background_color (target2, CLUTTER_COLOR_LightChameleon); - clutter_actor_set_size (target2, TARGET_SIZE, TARGET_SIZE); - clutter_actor_set_opacity (target2, 64); - clutter_actor_add_constraint (target2, clutter_align_constraint_new (stage, CLUTTER_ALIGN_Y_AXIS, 0.5)); - clutter_actor_set_x (target2, 640 - TARGET_SIZE - 10); - clutter_actor_set_reactive (target2, TRUE); - - clutter_actor_add_action_with_name (target2, "drop", clutter_drop_action_new ()); - g_signal_connect (clutter_actor_get_action (target2, "drop"), - "over-in", - G_CALLBACK (on_target_over), - GUINT_TO_POINTER (TRUE)); - g_signal_connect (clutter_actor_get_action (target2, "drop"), - "over-out", - G_CALLBACK (on_target_over), - GUINT_TO_POINTER (FALSE)); - g_signal_connect (clutter_actor_get_action (target2, "drop"), - "drop", - G_CALLBACK (on_target_drop), - NULL); - - clutter_actor_add_child (stage, target1); - clutter_actor_add_child (stage, dummy); - clutter_actor_add_child (stage, target2); - - add_drag_object (target1); - - clutter_actor_show (stage); - - clutter_main (); - - return EXIT_SUCCESS; -} diff --git a/clutter/examples/easing-modes.c b/clutter/examples/easing-modes.c deleted file mode 100644 index 56c552b0b..000000000 --- a/clutter/examples/easing-modes.c +++ /dev/null @@ -1,241 +0,0 @@ -#include -#include - -/* all the easing modes provided by Clutter */ -static const struct { - const gchar *name; - ClutterAnimationMode mode; -} easing_modes[] = { - { "linear", CLUTTER_LINEAR }, - { "easeInQuad", CLUTTER_EASE_IN_QUAD }, - { "easeOutQuad", CLUTTER_EASE_OUT_QUAD }, - { "easeInOutQuad", CLUTTER_EASE_IN_OUT_QUAD }, - { "easeInCubic", CLUTTER_EASE_IN_CUBIC }, - { "easeOutCubic", CLUTTER_EASE_OUT_CUBIC }, - { "easeInOutCubic", CLUTTER_EASE_IN_OUT_CUBIC }, - { "easeInQuart", CLUTTER_EASE_IN_QUART }, - { "easeOutQuart", CLUTTER_EASE_OUT_QUART }, - { "easeInOutQuart", CLUTTER_EASE_IN_OUT_QUART }, - { "easeInQuint", CLUTTER_EASE_IN_QUINT }, - { "easeOutQuint", CLUTTER_EASE_OUT_QUINT }, - { "easeInOutQuint", CLUTTER_EASE_IN_OUT_QUINT }, - { "easeInSine", CLUTTER_EASE_IN_SINE }, - { "easeOutSine", CLUTTER_EASE_OUT_SINE }, - { "easeInOutSine", CLUTTER_EASE_IN_OUT_SINE }, - { "easeInExpo", CLUTTER_EASE_IN_EXPO }, - { "easeOutExpo", CLUTTER_EASE_OUT_EXPO }, - { "easeInOutExpo", CLUTTER_EASE_IN_OUT_EXPO }, - { "easeInCirc", CLUTTER_EASE_IN_CIRC }, - { "easeOutCirc", CLUTTER_EASE_OUT_CIRC }, - { "easeInOutCirc", CLUTTER_EASE_IN_OUT_CIRC }, - { "easeInElastic", CLUTTER_EASE_IN_ELASTIC }, - { "easeOutElastic", CLUTTER_EASE_OUT_ELASTIC }, - { "easeInOutElastic", CLUTTER_EASE_IN_OUT_ELASTIC }, - { "easeInBack", CLUTTER_EASE_IN_BACK }, - { "easeOutBack", CLUTTER_EASE_OUT_BACK }, - { "easeInOutBack", CLUTTER_EASE_IN_OUT_BACK }, - { "easeInBounce", CLUTTER_EASE_IN_BOUNCE }, - { "easeOutBounce", CLUTTER_EASE_OUT_BOUNCE }, - { "easeInOutBounce", CLUTTER_EASE_IN_OUT_BOUNCE }, - { "stepStart", CLUTTER_STEP_START }, - { "stepEnd", CLUTTER_STEP_END }, - { "ease", CLUTTER_EASE }, - { "easeIn", CLUTTER_EASE_IN }, - { "easeOut", CLUTTER_EASE_OUT }, - { "easeInOut", CLUTTER_EASE_IN_OUT }, -}; - -#define HELP_TEXT "Easing mode: %s (%d of %d)\n" \ - "Left click to tween\n" \ - "Middle click to jump\n" \ - "Right click to change the easing mode" - -static const gint n_easing_modes = G_N_ELEMENTS (easing_modes); -static gint current_mode = 0; - -static gint duration = 1; - -static ClutterActor *main_stage = NULL; -static ClutterActor *easing_mode_label = NULL; - -static gboolean -on_button_press (ClutterActor *actor, - ClutterButtonEvent *event, - ClutterActor *rectangle) -{ - if (event->button == CLUTTER_BUTTON_SECONDARY) - { - gchar *text; - - /* cycle through the various easing modes */ - current_mode = (current_mode + 1 < n_easing_modes) - ? current_mode + 1 - : 0; - - /* update the text of the label */ - text = g_strdup_printf (HELP_TEXT, - easing_modes[current_mode].name, - current_mode + 1, - n_easing_modes); - - clutter_text_set_markup (CLUTTER_TEXT (easing_mode_label), text); - free (text); - } - else if (event->button == CLUTTER_BUTTON_MIDDLE) - { - clutter_actor_set_position (rectangle, event->x, event->y); - } - else if (event->button == CLUTTER_BUTTON_PRIMARY) - { - ClutterAnimationMode cur_mode; - - cur_mode = easing_modes[current_mode].mode; - - clutter_actor_save_easing_state (rectangle); - - /* tween the actor using the current easing mode */ - clutter_actor_set_easing_mode (rectangle, cur_mode); - clutter_actor_set_easing_duration (rectangle, duration * 1000); - - clutter_actor_set_position (rectangle, event->x, event->y); - - clutter_actor_restore_easing_state (rectangle); - } - - return CLUTTER_EVENT_STOP; -} - -static gboolean -draw_bouncer (ClutterCanvas *canvas, - cairo_t *cr, - int width, - int height) -{ - const ClutterColor *bouncer_color; - cairo_pattern_t *pattern; - float radius; - - cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); - cairo_paint (cr); - - cairo_set_operator (cr, CAIRO_OPERATOR_OVER); - - radius = MAX (width, height); - - cairo_arc (cr, radius / 2, radius / 2, radius / 2, 0.0, 2.0 * G_PI); - - bouncer_color = CLUTTER_COLOR_DarkScarletRed; - - pattern = cairo_pattern_create_radial (radius / 2, radius / 2, 0, - radius, radius, radius); - cairo_pattern_add_color_stop_rgba (pattern, - 0, - bouncer_color->red / 255.0, - bouncer_color->green / 255.0, - bouncer_color->blue / 255.0, - bouncer_color->alpha / 255.0); - cairo_pattern_add_color_stop_rgba (pattern, - 0.85, - bouncer_color->red / 255.0, - bouncer_color->green / 255.0, - bouncer_color->blue / 255.0, - 0.25); - - cairo_set_source (cr, pattern); - cairo_fill_preserve (cr); - - cairo_pattern_destroy (pattern); - - return TRUE; -} - -static ClutterActor * -make_bouncer (gfloat width, - gfloat height) -{ - ClutterActor *retval; - ClutterContent *canvas; - - retval = clutter_actor_new (); - - canvas = clutter_canvas_new (); - g_signal_connect (canvas, "draw", G_CALLBACK (draw_bouncer), NULL); - clutter_canvas_set_size (CLUTTER_CANVAS (canvas), width, height); - - clutter_actor_set_name (retval, "bouncer"); - clutter_actor_set_size (retval, width, height); - clutter_actor_set_pivot_point (retval, 0.5f, 0.5f); - clutter_actor_set_translation (retval, width / -2.f, height / -2.f, 0.f); - clutter_actor_set_reactive (retval, TRUE); - clutter_actor_set_content (retval, canvas); - - g_object_unref (canvas); - - return retval; -} - -static GOptionEntry test_easing_entries[] = { - { - "duration", 'd', - 0, - G_OPTION_ARG_INT, &duration, - "Duration of the animation", - "SECONDS" - }, - - { NULL } -}; - -int -main (int argc, char *argv[]) -{ - ClutterActor *stage, *rect, *label; - gchar *text; - gfloat stage_width, stage_height; - GError *error = NULL; - - if (clutter_init_with_args (&argc, &argv, - NULL, - test_easing_entries, - NULL, - &error) != CLUTTER_INIT_SUCCESS) - return 1; - - stage = clutter_stage_new (); - clutter_stage_set_title (CLUTTER_STAGE (stage), "Easing Modes"); - clutter_actor_set_background_color (stage, CLUTTER_COLOR_LightSkyBlue); - g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); - main_stage = stage; - - clutter_actor_get_size (stage, &stage_width, &stage_height); - - /* create the actor that we want to tween */ - rect = make_bouncer (50, 50); - clutter_actor_add_child (stage, rect); - clutter_actor_set_position (rect, stage_width / 2, stage_height / 2); - - text = g_strdup_printf (HELP_TEXT, - easing_modes[current_mode].name, - current_mode + 1, - n_easing_modes); - - label = clutter_text_new (); - clutter_actor_add_child (stage, label); - clutter_text_set_markup (CLUTTER_TEXT (label), text); - clutter_text_set_line_alignment (CLUTTER_TEXT (label), PANGO_ALIGN_RIGHT); - clutter_actor_add_constraint (label, clutter_align_constraint_new (stage, CLUTTER_ALIGN_X_AXIS, 0.95)); - clutter_actor_add_constraint (label, clutter_align_constraint_new (stage, CLUTTER_ALIGN_Y_AXIS, 0.95)); - easing_mode_label = label; - - free (text); - - g_signal_connect (stage, - "button-press-event", G_CALLBACK (on_button_press), - rect); - - clutter_actor_show (stage); - - clutter_main (); - - return EXIT_SUCCESS; -} diff --git a/clutter/examples/flow-layout.c b/clutter/examples/flow-layout.c deleted file mode 100644 index 808993e9f..000000000 --- a/clutter/examples/flow-layout.c +++ /dev/null @@ -1,164 +0,0 @@ -#include -#include -#include -#include - -#define N_RECTS 20 - -static gboolean is_homogeneous = FALSE; -static gboolean vertical = FALSE; -static gboolean random_size = FALSE; -static gboolean fixed_size = FALSE; -static gboolean snap_to_grid = TRUE; - -static gint n_rects = N_RECTS; -static gint x_spacing = 0; -static gint y_spacing = 0; - -static GOptionEntry entries[] = { - { - "random-size", 'r', - 0, - G_OPTION_ARG_NONE, - &random_size, - "Randomly size the rectangles", NULL - }, - { - "num-rects", 'n', - 0, - G_OPTION_ARG_INT, - &n_rects, - "Number of rectangles", "RECTS" - }, - { - "vertical", 'v', - 0, - G_OPTION_ARG_NONE, - &vertical, - "Set vertical orientation", NULL - }, - { - "homogeneous", 'h', - 0, - G_OPTION_ARG_NONE, - &is_homogeneous, - "Whether the layout should be homogeneous", NULL - }, - { - "x-spacing", 0, - 0, - G_OPTION_ARG_INT, - &x_spacing, - "Horizontal spacing between elements", "PX" - }, - { - "y-spacing", 0, - 0, - G_OPTION_ARG_INT, - &y_spacing, - "Vertical spacing between elements", "PX" - }, - { - "fixed-size", 'f', - 0, - G_OPTION_ARG_NONE, - &fixed_size, - "Fix the layout size", NULL - }, - { - "no-snap-to-grid", 's', - G_OPTION_FLAG_REVERSE, - G_OPTION_ARG_NONE, - &snap_to_grid, - "Don't snap elements to grid", NULL - }, - { NULL } -}; - -int -main (int argc, char *argv[]) -{ - ClutterActor *stage, *box; - ClutterLayoutManager *layout; - GError *error; - gint i; - - error = NULL; - if (clutter_init_with_args (&argc, &argv, - NULL, - entries, - NULL, - &error) != CLUTTER_INIT_SUCCESS) - { - g_print ("Unable to run flow-layout: %s", error->message); - g_error_free (error); - - return EXIT_FAILURE; - } - - stage = clutter_stage_new (); - clutter_actor_set_background_color (stage, CLUTTER_COLOR_LightSkyBlue); - clutter_stage_set_title (CLUTTER_STAGE (stage), "Flow Layout"); - clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE); - g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); - - layout = clutter_flow_layout_new (vertical ? CLUTTER_FLOW_VERTICAL - : CLUTTER_FLOW_HORIZONTAL); - clutter_flow_layout_set_homogeneous (CLUTTER_FLOW_LAYOUT (layout), - is_homogeneous); - clutter_flow_layout_set_column_spacing (CLUTTER_FLOW_LAYOUT (layout), - x_spacing); - clutter_flow_layout_set_row_spacing (CLUTTER_FLOW_LAYOUT (layout), - y_spacing); - clutter_flow_layout_set_snap_to_grid (CLUTTER_FLOW_LAYOUT (layout), - snap_to_grid); - - box = clutter_actor_new (); - clutter_actor_set_layout_manager (box, layout); - clutter_actor_set_background_color (box, CLUTTER_COLOR_Aluminium2); - clutter_actor_add_child (stage, box); - - if (!fixed_size) - clutter_actor_add_constraint (box, clutter_bind_constraint_new (stage, CLUTTER_BIND_SIZE, 0.0)); - - clutter_actor_set_position (box, 0, 0); - clutter_actor_set_name (box, "box"); - - for (i = 0; i < n_rects; i++) - { - ClutterColor color = CLUTTER_COLOR_INIT (255, 255, 255, 255); - gfloat width, height; - ClutterActor *rect; - gchar *name; - - name = g_strdup_printf ("rect%02d", i); - - clutter_color_from_hls (&color, - 360.0 / n_rects * i, - 0.5, - 0.8); - rect = clutter_actor_new (); - clutter_actor_set_background_color (rect, &color); - - if (random_size) - { - width = g_random_int_range (50, 100); - height = g_random_int_range (50, 100); - } - else - width = height = 50.f; - - clutter_actor_set_size (rect, width, height); - clutter_actor_set_name (rect, name); - - clutter_actor_add_child (box, rect); - - free (name); - } - - clutter_actor_show (stage); - - clutter_main (); - - return EXIT_SUCCESS; -} diff --git a/clutter/examples/grid-layout.c b/clutter/examples/grid-layout.c deleted file mode 100644 index bb9f2e151..000000000 --- a/clutter/examples/grid-layout.c +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Copyright 2012 Bastian Winkler - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU Lesser General Public License, - * version 2.1, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for - * more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * Boston, MA 02111-1307, USA. - * - */ -#include -#include - -#define INSTRUCTIONS \ - "Press r\t\342\236\236\tSwitch row homogeneous\n" \ - "Press c\t\342\236\236\tSwitch column homogeneous\n" \ - "Press s\t\342\236\236\tIncrement spacing (up to 12px)\n" \ - "Press q\t\342\236\236\tQuit\n\n" \ - "Left/right click\t\t\342\236\236\tChange actor align\n" \ - "Shift left/right click\t\342\236\236\tChange actor expand" - -static gboolean random_size = FALSE; -static gboolean random_align = FALSE; -static gboolean default_expand = TRUE; -static gboolean use_box = FALSE; -static gboolean is_vertical = FALSE; - -static GOptionEntry entries[] = { - { - "random-size", 'r', - 0, - G_OPTION_ARG_NONE, - &random_size, - "Randomly size the rectangles", NULL - }, - { - "random-align", 'f', - 0, - G_OPTION_ARG_NONE, - &random_align, - "Randomly set the align values", NULL - }, - { - "no-expand", 'e', - G_OPTION_FLAG_REVERSE, - G_OPTION_ARG_NONE, - &default_expand, - "Don't expand all actors by default", NULL, - }, - { - "box", 'b', - 0, - G_OPTION_ARG_NONE, - &use_box, - "Use the layout in a ClutterBoxLayout style", NULL - }, - { - "vertical", 'v', - 0, - G_OPTION_ARG_NONE, - &is_vertical, - "Use a vertical orientation when used with --box", NULL - }, - { NULL } -}; - -static gboolean -button_release_cb (ClutterActor *actor, - ClutterEvent *event, - gpointer data) -{ - ClutterActorAlign x_align, y_align; - gboolean x_expand, y_expand; - - g_object_get (actor, - "x-align", &x_align, - "y-align", &y_align, - "x-expand", &x_expand, - "y-expand", &y_expand, - NULL); - - switch (clutter_event_get_button (event)) - { - case CLUTTER_BUTTON_PRIMARY: - if (clutter_event_has_shift_modifier (event)) - x_expand = !x_expand; - else - { - if (x_align < 3) - x_align += 1; - else - x_align = 0; - } - break; - - case CLUTTER_BUTTON_SECONDARY: - if (clutter_event_has_shift_modifier (event)) - y_expand = !y_expand; - else - { - if (y_align < 3) - y_align += 1; - else - y_align = 0; - } - break; - - default: - return FALSE; - } - - g_object_set (actor, - "x-align", x_align, - "y-align", y_align, - "x-expand", x_expand, - "y-expand", y_expand, - NULL); - return TRUE; -} - -static const gchar * -get_align_name (ClutterActorAlign align) -{ - switch (align) - { - case CLUTTER_ACTOR_ALIGN_FILL: - return "fill"; - - case CLUTTER_ACTOR_ALIGN_START: - return "start"; - - case CLUTTER_ACTOR_ALIGN_CENTER: - return "center"; - - case CLUTTER_ACTOR_ALIGN_END: - return "end"; - - default: - g_assert_not_reached (); - } -} -static void -changed_cb (ClutterActor *actor, - GParamSpec *pspec, - ClutterActor *text) -{ - ClutterActorAlign x_align, y_align; - ClutterActor *box; - ClutterLayoutManager *layout; - ClutterLayoutMeta *meta; - gboolean x_expand, y_expand; - gchar *label; - gint left, top, width, height; - - box = clutter_actor_get_parent (actor); - layout = clutter_actor_get_layout_manager (box); - meta = clutter_layout_manager_get_child_meta (layout, - CLUTTER_CONTAINER (box), - actor); - - g_object_get (actor, - "x-align", &x_align, - "y-align", &y_align, - "x-expand", &x_expand, - "y-expand", &y_expand, - NULL); - - g_object_get (meta, - "left-attach", &left, - "top-attach", &top, - "width", &width, - "height", &height, - NULL); - - label = g_strdup_printf ("attach: %d,%d\n" - "span: %d,%d\n" - "expand: %d,%d\n" - "align: %s,%s", - left, top, width, height, - x_expand, y_expand, - get_align_name (x_align), - get_align_name (y_align)); - clutter_text_set_text (CLUTTER_TEXT (text), label); - free (label); -} - -static void -add_actor (ClutterActor *box, - gint left, - gint top, - gint width, - gint height) -{ - ClutterActor *rect, *text; - ClutterColor color; - ClutterLayoutManager *layout; - - clutter_color_from_hls (&color, - g_random_double_range (0.0, 360.0), - 0.5, - 0.5); - color.alpha = 255; - - layout = clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_CENTER, - CLUTTER_BIN_ALIGNMENT_CENTER); - rect = clutter_actor_new (); - clutter_actor_set_layout_manager (rect, layout); - clutter_actor_set_background_color (rect, &color); - clutter_actor_set_reactive (rect, TRUE); - - if (random_size) - clutter_actor_set_size (rect, - g_random_int_range (40, 80), - g_random_int_range (40, 80)); - else - clutter_actor_set_size (rect, 60, 60); - - clutter_actor_set_x_expand (rect, default_expand); - clutter_actor_set_y_expand (rect, default_expand); - - if (!default_expand) - { - clutter_actor_set_x_align (rect, CLUTTER_ACTOR_ALIGN_CENTER); - clutter_actor_set_y_align (rect, CLUTTER_ACTOR_ALIGN_CENTER); - } - - if (random_align) - { - clutter_actor_set_x_align (rect, g_random_int_range (0, 3)); - clutter_actor_set_y_align (rect, g_random_int_range (0, 3)); - } - - text = clutter_text_new_with_text ("Sans 8px", NULL); - clutter_text_set_line_alignment (CLUTTER_TEXT (text), - PANGO_ALIGN_CENTER); - clutter_actor_add_child (rect, text); - - g_signal_connect (rect, "button-release-event", - G_CALLBACK (button_release_cb), NULL); - g_signal_connect (rect, "notify::x-expand", - G_CALLBACK (changed_cb), text); - g_signal_connect (rect, "notify::y-expand", - G_CALLBACK (changed_cb), text); - g_signal_connect (rect, "notify::x-align", - G_CALLBACK (changed_cb), text); - g_signal_connect (rect, "notify::y-align", - G_CALLBACK (changed_cb), text); - - layout = clutter_actor_get_layout_manager (box); - if (use_box) - clutter_actor_add_child (box, rect); - else - clutter_grid_layout_attach (CLUTTER_GRID_LAYOUT (layout), rect, - left, top, width, height); - changed_cb (rect, NULL, text); -} - -static gboolean -key_release_cb (ClutterActor *stage, - ClutterEvent *event, - ClutterActor *box) -{ - ClutterGridLayout *layout; - gboolean toggle; - guint spacing; - - layout = CLUTTER_GRID_LAYOUT (clutter_actor_get_layout_manager (box)); - - switch (clutter_event_get_key_symbol (event)) - { - case CLUTTER_KEY_c: - toggle = clutter_grid_layout_get_column_homogeneous (layout); - clutter_grid_layout_set_column_homogeneous (layout, !toggle); - break; - - case CLUTTER_KEY_r: - toggle = clutter_grid_layout_get_row_homogeneous (layout); - clutter_grid_layout_set_row_homogeneous (layout, !toggle); - break; - - case CLUTTER_KEY_s: - spacing = clutter_grid_layout_get_column_spacing (layout); - if (spacing < 12) - spacing += 1; - else - spacing = 0; - clutter_grid_layout_set_column_spacing (layout, spacing); - clutter_grid_layout_set_row_spacing (layout, spacing); - break; - - case CLUTTER_KEY_q: - clutter_main_quit (); - break; - - default: - return FALSE; - } - - return TRUE; -} -int -main (int argc, char *argv[]) -{ - ClutterActor *stage, *box, *instructions; - ClutterLayoutManager *stage_layout, *grid_layout; - GError *error = NULL; - - if (clutter_init_with_args (&argc, &argv, - NULL, - entries, - NULL, - &error) != CLUTTER_INIT_SUCCESS) - { - g_print ("Unable to run grid-layout: %s", error->message); - g_error_free (error); - - return EXIT_FAILURE; - } - - stage = clutter_stage_new (); - clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE); - stage_layout = clutter_box_layout_new (); - clutter_box_layout_set_orientation (CLUTTER_BOX_LAYOUT (stage_layout), - CLUTTER_ORIENTATION_VERTICAL); - clutter_actor_set_layout_manager (stage, stage_layout); - - grid_layout = clutter_grid_layout_new (); - if (is_vertical) - clutter_grid_layout_set_orientation (CLUTTER_GRID_LAYOUT (grid_layout), - CLUTTER_ORIENTATION_VERTICAL); - box = clutter_actor_new (); - clutter_actor_set_background_color (box, CLUTTER_COLOR_LightGray); - clutter_actor_set_x_expand (box, TRUE); - clutter_actor_set_y_expand (box, TRUE); - clutter_actor_set_layout_manager (box, grid_layout); - clutter_box_layout_pack (CLUTTER_BOX_LAYOUT (stage_layout), box, - TRUE, TRUE, TRUE, - CLUTTER_BOX_ALIGNMENT_CENTER, - CLUTTER_BOX_ALIGNMENT_CENTER); - - add_actor (box, 0, 0, 1, 1); - add_actor (box, 1, 0, 1, 1); - add_actor (box, 2, 0, 1, 1); - add_actor (box, 0, 1, 1, 1); - add_actor (box, 1, 1, 2, 1); - add_actor (box, 0, 2, 3, 1); - add_actor (box, 0, 3, 2, 2); - add_actor (box, 2, 3, 1, 1); - add_actor (box, 2, 4, 1, 1); - - instructions = clutter_text_new_with_text ("Sans 12px", INSTRUCTIONS); - clutter_actor_set_margin_top (instructions, 4); - clutter_actor_set_margin_left (instructions, 4); - clutter_actor_set_margin_bottom (instructions, 4); - clutter_box_layout_pack (CLUTTER_BOX_LAYOUT (stage_layout), instructions, - FALSE, TRUE, FALSE, - CLUTTER_BOX_ALIGNMENT_START, - CLUTTER_BOX_ALIGNMENT_CENTER); - - g_signal_connect (stage, "destroy", - G_CALLBACK (clutter_main_quit), NULL); - g_signal_connect (stage, "key-release-event", - G_CALLBACK (key_release_cb), box); - - clutter_actor_show (stage); - - clutter_main (); - - return 0; -} diff --git a/clutter/examples/image-content.c b/clutter/examples/image-content.c deleted file mode 100644 index 8bcd1c5bf..000000000 --- a/clutter/examples/image-content.c +++ /dev/null @@ -1,110 +0,0 @@ -#include -#include -#include - -static const struct { - ClutterContentGravity gravity; - const char *name; -} gravities[] = { - { CLUTTER_CONTENT_GRAVITY_TOP_LEFT, "Top Left" }, - { CLUTTER_CONTENT_GRAVITY_TOP, "Top" }, - { CLUTTER_CONTENT_GRAVITY_TOP_RIGHT, "Top Right" }, - - { CLUTTER_CONTENT_GRAVITY_LEFT, "Left" }, - { CLUTTER_CONTENT_GRAVITY_CENTER, "Center" }, - { CLUTTER_CONTENT_GRAVITY_RIGHT, "Right" }, - - { CLUTTER_CONTENT_GRAVITY_BOTTOM_LEFT, "Bottom Left" }, - { CLUTTER_CONTENT_GRAVITY_BOTTOM, "Bottom" }, - { CLUTTER_CONTENT_GRAVITY_BOTTOM_RIGHT, "Bottom Right" }, - - { CLUTTER_CONTENT_GRAVITY_RESIZE_FILL, "Resize Fill" }, - { CLUTTER_CONTENT_GRAVITY_RESIZE_ASPECT, "Resize Aspect" }, -}; - -static int n_gravities = G_N_ELEMENTS (gravities); -static int cur_gravity = 0; - -static void -on_tap (ClutterTapAction *action, - ClutterActor *actor, - ClutterText *label) -{ - gchar *str; - - clutter_actor_save_easing_state (actor); - clutter_actor_set_content_gravity (actor, gravities[cur_gravity].gravity); - clutter_actor_restore_easing_state (actor); - - str = g_strconcat ("Content gravity: ", gravities[cur_gravity].name, NULL); - clutter_text_set_text (label, str); - free (str); - - cur_gravity += 1; - - if (cur_gravity >= n_gravities) - cur_gravity = 0; -} - -int -main (int argc, char *argv[]) -{ - ClutterActor *stage, *text; - ClutterContent *image; - ClutterAction *action; - GdkPixbuf *pixbuf; - gchar *str; - - if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) - return EXIT_FAILURE; - - stage = clutter_stage_new (); - clutter_actor_set_name (stage, "Stage"); - clutter_stage_set_title (CLUTTER_STAGE (stage), "Content Box"); - clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE); - g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); - clutter_actor_set_margin_top (stage, 12); - clutter_actor_set_margin_right (stage, 12); - clutter_actor_set_margin_bottom (stage, 12); - clutter_actor_set_margin_left (stage, 12); - clutter_actor_show (stage); - - pixbuf = gdk_pixbuf_new_from_file ("redhand.png", NULL); - image = clutter_image_new (); - clutter_image_set_data (CLUTTER_IMAGE (image), - gdk_pixbuf_get_pixels (pixbuf), - gdk_pixbuf_get_has_alpha (pixbuf) - ? COGL_PIXEL_FORMAT_RGBA_8888 - : COGL_PIXEL_FORMAT_RGB_888, - gdk_pixbuf_get_width (pixbuf), - gdk_pixbuf_get_height (pixbuf), - gdk_pixbuf_get_rowstride (pixbuf), - NULL); - g_object_unref (pixbuf); - - clutter_actor_set_content_scaling_filters (stage, - CLUTTER_SCALING_FILTER_TRILINEAR, - CLUTTER_SCALING_FILTER_LINEAR); - clutter_actor_set_content_gravity (stage, gravities[n_gravities - 1].gravity); - clutter_actor_set_content (stage, image); - g_object_unref (image); - - str = g_strconcat ("Content gravity: ", - gravities[n_gravities - 1].name, - NULL); - - text = clutter_text_new (); - clutter_text_set_text (CLUTTER_TEXT (text), str); - clutter_actor_add_constraint (text, clutter_align_constraint_new (stage, CLUTTER_ALIGN_BOTH, 0.5)); - clutter_actor_add_child (stage, text); - - free (str); - - action = clutter_tap_action_new (); - g_signal_connect (action, "tap", G_CALLBACK (on_tap), text); - clutter_actor_add_action (stage, action); - - clutter_main (); - - return EXIT_SUCCESS; -} diff --git a/clutter/examples/layout-manager.c b/clutter/examples/layout-manager.c deleted file mode 100644 index c5518f2d4..000000000 --- a/clutter/examples/layout-manager.c +++ /dev/null @@ -1,461 +0,0 @@ -#include -#include -#include - -typedef struct _MultiLayout MultiLayout; -typedef struct _MultiLayoutClass MultiLayoutClass; - -typedef enum { - MULTI_LAYOUT_GRID, - MULTI_LAYOUT_CIRCLE -} MultiLayoutState; - -struct _MultiLayout -{ - ClutterLayoutManager parent_instance; - - /* the state of the layout */ - MultiLayoutState state; - - /* spacing between children */ - float spacing; - - /* cell size */ - float cell_width; - float cell_height; -}; - -struct _MultiLayoutClass -{ - ClutterLayoutManagerClass parent_class; -}; - -GType multi_layout_get_type (void); - -ClutterLayoutManager * multi_layout_new (void); -void multi_layout_set_state (MultiLayout *layout, - MultiLayoutState state); -MultiLayoutState multi_layout_get_state (MultiLayout *layout); -void multi_layout_set_spacing (MultiLayout *layout, - float spacing); - -G_DEFINE_TYPE (MultiLayout, multi_layout, CLUTTER_TYPE_LAYOUT_MANAGER) - -static void -multi_layout_get_preferred_width (ClutterLayoutManager *manager, - ClutterContainer *container, - float for_height, - float *min_width_p, - float *nat_width_p) -{ - MultiLayout *self = (MultiLayout *) manager; - float minimum, natural; - float max_natural_width; - ClutterActorIter iter; - ClutterActor *child; - int n_children; - - minimum = natural = 0.f; - max_natural_width = 0.f; - n_children = 0; - - clutter_actor_iter_init (&iter, CLUTTER_ACTOR (container)); - while (clutter_actor_iter_next (&iter, &child)) - { - float child_minimum, child_natural; - - if (!clutter_actor_is_visible (child)) - continue; - - clutter_actor_get_preferred_width (child, -1.f, - &child_minimum, - &child_natural); - - max_natural_width = MAX (max_natural_width, child_natural); - - if (self->state == MULTI_LAYOUT_GRID) - { - minimum += child_minimum; - natural += child_natural; - } - else if (self->state == MULTI_LAYOUT_CIRCLE) - { - minimum = MAX (minimum, child_minimum); - natural = MAX (natural, child_natural); - } - - n_children += 1; - } - - self->cell_width = max_natural_width; - - minimum += (self->spacing * (n_children - 1)); - natural += (self->spacing * (n_children - 1)); - - if (min_width_p != NULL) - *min_width_p = minimum; - - if (nat_width_p != NULL) - *nat_width_p = natural; -} - -static void -multi_layout_get_preferred_height (ClutterLayoutManager *manager, - ClutterContainer *container, - float for_width, - float *min_height_p, - float *nat_height_p) -{ - MultiLayout *self = (MultiLayout *) manager; - float minimum, natural; - ClutterActorIter iter; - ClutterActor *child; - int n_children; - - minimum = natural = self->spacing * 2.f; - n_children = 0; - - clutter_actor_iter_init (&iter, CLUTTER_ACTOR (container)); - while (clutter_actor_iter_next (&iter, &child)) - { - float child_minimum, child_natural; - - if (!clutter_actor_is_visible (child)) - continue; - - clutter_actor_get_preferred_height (child, -1.f, - &child_minimum, - &child_natural); - - minimum = MAX (minimum, child_minimum); - natural = MAX (natural, child_natural); - - n_children += 1; - } - - self->cell_height = natural; - - minimum += (self->spacing * (n_children - 1)); - natural += (self->spacing * (n_children - 1)); - - if (min_height_p != NULL) - *min_height_p = minimum; - - if (nat_height_p != NULL) - *nat_height_p = natural; -} - -static int -get_items_per_row (MultiLayout *self, - float for_width) -{ - int n_columns; - - if (for_width < 0) - return 1; - - if (self->cell_width <= 0) - return 1; - - n_columns = (int) ((for_width + self->spacing) / (self->cell_width + self->spacing)); - - return MAX (n_columns, 1); -} - -static int -get_visible_children (ClutterActor *actor) -{ - ClutterActorIter iter; - ClutterActor *child; - int n_visible_children = 0; - - clutter_actor_iter_init (&iter, actor); - while (clutter_actor_iter_next (&iter, &child)) - { - if (clutter_actor_is_visible (child)) - n_visible_children += 1; - } - - return n_visible_children; -} - -static void -multi_layout_allocate (ClutterLayoutManager *manager, - ClutterContainer *container, - const ClutterActorBox *allocation, - ClutterAllocationFlags flags) -{ - MultiLayout *self = (MultiLayout *) manager; - float avail_width, avail_height; - float x_offset, y_offset; - ClutterActorIter iter; - ClutterActor *child; - float item_x = 0.f, item_y = 0.f; - int n_items, n_items_per_row = 0, item_index; - ClutterPoint center = CLUTTER_POINT_INIT_ZERO; - double radius = 0, theta = 0; - - n_items = get_visible_children (CLUTTER_ACTOR (container)); - if (n_items == 0) - return; - - clutter_actor_box_get_origin (allocation, &x_offset, &y_offset); - clutter_actor_box_get_size (allocation, &avail_width, &avail_height); - - /* ensure we have an updated value of cell_width and cell_height */ - multi_layout_get_preferred_width (manager, container, avail_width, NULL, NULL); - multi_layout_get_preferred_height (manager, container, avail_height, NULL, NULL); - - item_index = 0; - - if (self->state == MULTI_LAYOUT_GRID) - { - n_items_per_row = get_items_per_row (self, avail_width); - item_x = x_offset; - item_y = y_offset; - } - else if (self->state == MULTI_LAYOUT_CIRCLE) - { - center.x = allocation->x2 / 2.f; - center.y = allocation->y2 / 2.f; - radius = MIN ((avail_width - self->cell_width) / 2.0, - (avail_height - self->cell_height) / 2.0); - } - - clutter_actor_iter_init (&iter, CLUTTER_ACTOR (container)); - while (clutter_actor_iter_next (&iter, &child)) - { - ClutterActorBox child_allocation = CLUTTER_ACTOR_BOX_INIT_ZERO; - - if (!clutter_actor_is_visible (child)) - continue; - - if (self->state == MULTI_LAYOUT_GRID) - { - if (item_index == n_items_per_row) - { - item_index = 0; - item_x = x_offset; - item_y += self->cell_height + self->spacing; - } - - child_allocation.x1 = item_x; - child_allocation.y1 = item_y; - child_allocation.x2 = child_allocation.x1 + self->cell_width; - child_allocation.y2 = child_allocation.y1 + self->cell_height; - - item_x += self->cell_width + self->spacing; - } - else if (self->state == MULTI_LAYOUT_CIRCLE) - { - theta = 2.0 * G_PI / n_items * item_index; - child_allocation.x1 = center.x + radius * sinf (theta) - (self->cell_width / 2.f); - child_allocation.y1 = center.y + radius * -cosf (theta) - (self->cell_height / 2.f); - child_allocation.x2 = child_allocation.x1 + self->cell_width; - child_allocation.y2 = child_allocation.y1 + self->cell_height; - } - - clutter_actor_allocate (child, &child_allocation, flags); - - item_index += 1; - } -} - -static void -multi_layout_class_init (MultiLayoutClass *klass) -{ - ClutterLayoutManagerClass *manager_class = CLUTTER_LAYOUT_MANAGER_CLASS (klass); - - manager_class->get_preferred_width = multi_layout_get_preferred_width; - manager_class->get_preferred_height = multi_layout_get_preferred_height; - manager_class->allocate = multi_layout_allocate; -} - -static void -multi_layout_init (MultiLayout *self) -{ - self->state = MULTI_LAYOUT_GRID; - - self->cell_width = -1.f; - self->cell_height = -1.f; - - self->spacing = 0.f; -} - -ClutterLayoutManager * -multi_layout_new (void) -{ - return g_object_new (multi_layout_get_type (), NULL); -} - -void -multi_layout_set_state (MultiLayout *self, - MultiLayoutState state) -{ - if (self->state == state) - return; - - self->state = state; - - clutter_layout_manager_layout_changed (CLUTTER_LAYOUT_MANAGER (self)); -} - -MultiLayoutState -multi_layout_get_state (MultiLayout *self) -{ - return self->state; -} - -void -multi_layout_set_spacing (MultiLayout *self, - float spacing) -{ - self->spacing = spacing; - - clutter_layout_manager_layout_changed (CLUTTER_LAYOUT_MANAGER (self)); -} - -#define N_RECTS 16 -#define RECT_SIZE 64.0 -#define N_ROWS 4 -#define PADDING 12.0 -#define BOX_SIZE (RECT_SIZE * (N_RECTS / N_ROWS) + PADDING * (N_RECTS / N_ROWS - 1)) - -static gboolean -on_enter (ClutterActor *rect, - ClutterEvent *event) -{ - clutter_actor_set_scale (rect, 1.2, 1.2); - - return CLUTTER_EVENT_STOP; -} - -static gboolean -on_leave (ClutterActor *rect, - ClutterEvent *event) -{ - clutter_actor_set_scale (rect, 1.0, 1.0); - - return CLUTTER_EVENT_STOP; -} - -static gboolean -on_key_press (ClutterActor *stage, - ClutterEvent *event, - ClutterActor *box) -{ - guint keysym = clutter_event_get_key_symbol (event); - MultiLayout *layout = (MultiLayout *) clutter_actor_get_layout_manager (box); - - - switch (keysym) - { - case CLUTTER_KEY_q: - clutter_main_quit (); - break; - - case CLUTTER_KEY_t: - { - MultiLayoutState state = multi_layout_get_state (layout); - - if (state == MULTI_LAYOUT_GRID) - multi_layout_set_state (layout, MULTI_LAYOUT_CIRCLE); - - if (state == MULTI_LAYOUT_CIRCLE) - multi_layout_set_state (layout, MULTI_LAYOUT_GRID); - } - break; - - default: - break; - } - - return CLUTTER_EVENT_STOP; -} - -int -main (int argc, char *argv[]) -{ - ClutterActor *stage, *box, *label; - ClutterLayoutManager *manager; - ClutterMargin margin; - ClutterTransition *transition; - int i; - - if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) - return EXIT_FAILURE; - - stage = clutter_stage_new (); - clutter_stage_set_title (CLUTTER_STAGE (stage), "Multi-layout"); - g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); - clutter_actor_show (stage); - - /* the layout manager for the main container */ - manager = multi_layout_new (); - multi_layout_set_spacing ((MultiLayout *) manager, PADDING); - - margin.top = margin.bottom = margin.left = margin.right = PADDING; - - /* our main container, centered on the stage */ - box = clutter_actor_new (); - clutter_actor_set_margin (box, &margin); - clutter_actor_set_layout_manager (box, manager); - clutter_actor_set_size (box, BOX_SIZE, BOX_SIZE); - clutter_actor_add_constraint (box, clutter_align_constraint_new (stage, CLUTTER_ALIGN_BOTH, 0.5)); - clutter_actor_add_child (stage, box); - - for (i = 0; i < N_RECTS; i++) - { - ClutterActor *rect = clutter_actor_new (); - ClutterColor color; - - clutter_color_from_hls (&color, - 360.0 / N_RECTS * i, - 0.5, - 0.8); - - color.alpha = 128 + 128 / N_RECTS * i; - - /* elements on the layout */ - clutter_actor_set_size (rect, RECT_SIZE, RECT_SIZE); - clutter_actor_set_pivot_point (rect, .5f, .5f); - clutter_actor_set_background_color (rect, &color); - clutter_actor_set_opacity (rect, 0); - clutter_actor_set_reactive (rect, TRUE); - - /* explicit transition that fades in the element; the delay on - * the transition staggers the fade depending on the index - */ - transition = clutter_property_transition_new ("opacity"); - clutter_timeline_set_duration (CLUTTER_TIMELINE (transition), 250); - clutter_timeline_set_delay (CLUTTER_TIMELINE (transition), i * 50); - clutter_transition_set_from (transition, G_TYPE_UINT, 0); - clutter_transition_set_to (transition, G_TYPE_UINT, 255); - clutter_actor_add_transition (rect, "fadeIn", transition); - g_object_unref (transition); - - /* we want all state transitions to be animated */ - clutter_actor_set_easing_duration (rect, 250); - clutter_actor_set_easing_mode (rect, CLUTTER_EASE_OUT_CUBIC); - - clutter_actor_add_child (box, rect); - - /* simple hover effect */ - g_signal_connect (rect, "enter-event", G_CALLBACK (on_enter), NULL); - g_signal_connect (rect, "leave-event", G_CALLBACK (on_leave), NULL); - } - - label = clutter_text_new (); - clutter_text_set_text (CLUTTER_TEXT (label), - "Press t\t\342\236\236\tToggle layout\n" - "Press q\t\342\236\236\tQuit"); - clutter_actor_add_constraint (label, clutter_align_constraint_new (stage, CLUTTER_ALIGN_X_AXIS, 0.5)); - clutter_actor_add_constraint (label, clutter_align_constraint_new (stage, CLUTTER_ALIGN_Y_AXIS, 0.95)); - clutter_actor_add_child (stage, label); - - g_signal_connect (stage, "key-press-event", G_CALLBACK (on_key_press), box); - - clutter_main (); - - return EXIT_SUCCESS; -} diff --git a/clutter/examples/pan-action.c b/clutter/examples/pan-action.c deleted file mode 100644 index 4e3f73f25..000000000 --- a/clutter/examples/pan-action.c +++ /dev/null @@ -1,194 +0,0 @@ -#include -#include -#include -#ifdef CLUTTER_WINDOWING_X11 -#include -#endif - -static ClutterActor * -create_content_actor (void) -{ - ClutterActor *content; - ClutterContent *image; - GdkPixbuf *pixbuf; - - content = clutter_actor_new (); - clutter_actor_set_size (content, 720, 720); - - pixbuf = gdk_pixbuf_new_from_file ("redhand.png", NULL); - image = clutter_image_new (); - clutter_image_set_data (CLUTTER_IMAGE (image), - gdk_pixbuf_get_pixels (pixbuf), - gdk_pixbuf_get_has_alpha (pixbuf) - ? COGL_PIXEL_FORMAT_RGBA_8888 - : COGL_PIXEL_FORMAT_RGB_888, - gdk_pixbuf_get_width (pixbuf), - gdk_pixbuf_get_height (pixbuf), - gdk_pixbuf_get_rowstride (pixbuf), - NULL); - g_object_unref (pixbuf); - - clutter_actor_set_content_scaling_filters (content, - CLUTTER_SCALING_FILTER_TRILINEAR, - CLUTTER_SCALING_FILTER_LINEAR); - clutter_actor_set_content_gravity (content, CLUTTER_CONTENT_GRAVITY_RESIZE_ASPECT); - clutter_actor_set_content (content, image); - g_object_unref (image); - - return content; -} - -static gboolean -on_pan (ClutterPanAction *action, - ClutterActor *scroll, - gboolean is_interpolated, - gpointer *user_data) -{ - gfloat delta_x, delta_y; - const ClutterEvent *event = NULL; - - if (is_interpolated) - clutter_pan_action_get_interpolated_delta (action, &delta_x, &delta_y); - else - { - clutter_gesture_action_get_motion_delta (CLUTTER_GESTURE_ACTION (action), 0, &delta_x, &delta_y); - event = clutter_gesture_action_get_last_event (CLUTTER_GESTURE_ACTION (action), 0); - } - - g_print ("[%s] panning dx:%.2f dy:%.2f\n", - event == NULL ? "INTERPOLATED" : - event->type == CLUTTER_MOTION ? "MOTION" : - event->type == CLUTTER_TOUCH_UPDATE ? "TOUCH UPDATE" : - "?", - delta_x, delta_y); - - return TRUE; -} - -static ClutterActor * -create_scroll_actor (ClutterActor *stage) -{ - ClutterActor *scroll; - ClutterAction *pan_action; - - /* our scrollable viewport */ - scroll = clutter_actor_new (); - clutter_actor_set_name (scroll, "scroll"); - - clutter_actor_add_constraint (scroll, clutter_align_constraint_new (stage, CLUTTER_ALIGN_X_AXIS, 0)); - clutter_actor_add_constraint (scroll, clutter_bind_constraint_new (stage, CLUTTER_BIND_SIZE, 0)); - - clutter_actor_add_child (scroll, create_content_actor ()); - - pan_action = clutter_pan_action_new (); - clutter_pan_action_set_interpolate (CLUTTER_PAN_ACTION (pan_action), TRUE); - g_signal_connect (pan_action, "pan", G_CALLBACK (on_pan), NULL); - clutter_actor_add_action_with_name (scroll, "pan", pan_action); - - clutter_actor_set_reactive (scroll, TRUE); - - return scroll; -} - -static gboolean -on_key_press (ClutterActor *stage, - ClutterEvent *event, - gpointer unused) -{ - ClutterActor *scroll; - guint key_symbol; - - scroll = clutter_actor_get_first_child (stage); - - key_symbol = clutter_event_get_key_symbol (event); - - if (key_symbol == CLUTTER_KEY_space) - { - clutter_actor_save_easing_state (scroll); - clutter_actor_set_easing_duration (scroll, 1000); - clutter_actor_set_child_transform (scroll, NULL); - clutter_actor_restore_easing_state (scroll); - } - - return CLUTTER_EVENT_STOP; -} - -static gboolean -label_clicked_cb (ClutterText *label, ClutterEvent *event, ClutterActor *scroll) -{ - ClutterPanAction *action = CLUTTER_PAN_ACTION (clutter_actor_get_action (scroll, "pan")); - const gchar *label_text = clutter_text_get_text (label); - - if (g_str_equal (label_text, "X AXIS")) - clutter_pan_action_set_pan_axis (action, CLUTTER_PAN_X_AXIS); - else if (g_str_equal (label_text, "Y AXIS")) - clutter_pan_action_set_pan_axis (action, CLUTTER_PAN_Y_AXIS); - else if (g_str_equal (label_text, "AUTO")) - clutter_pan_action_set_pan_axis (action, CLUTTER_PAN_AXIS_AUTO); - else - clutter_pan_action_set_pan_axis (action, CLUTTER_PAN_AXIS_NONE); - - return TRUE; -} - -static void -add_label (const gchar *text, ClutterActor *box, ClutterActor *scroll) -{ - ClutterActor *label; - - label = clutter_text_new_with_text (NULL, text); - clutter_actor_set_reactive (label, TRUE); - clutter_actor_set_x_align (label, CLUTTER_ACTOR_ALIGN_START); - clutter_actor_set_x_expand (label, TRUE); - - clutter_actor_add_child (box, label); - - g_signal_connect (label, "button-release-event", - G_CALLBACK (label_clicked_cb), scroll); -} - -int -main (int argc, char *argv[]) -{ - ClutterActor *stage, *scroll, *box, *info; - ClutterLayoutManager *layout; - - if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) - return EXIT_FAILURE; - - /* create a new stage */ - stage = clutter_stage_new (); - clutter_stage_set_title (CLUTTER_STAGE (stage), "Pan Action"); - clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE); - - scroll = create_scroll_actor (stage); - clutter_actor_add_child (stage, scroll); - - box = clutter_actor_new (); - clutter_actor_add_child (stage, box); - clutter_actor_set_position (box, 12, 12); - - layout = clutter_box_layout_new (); - clutter_box_layout_set_orientation (CLUTTER_BOX_LAYOUT (layout), CLUTTER_ORIENTATION_VERTICAL); - clutter_actor_set_layout_manager (box, layout); - - info = clutter_text_new_with_text (NULL, "Press to reset the image position."); - clutter_actor_add_child (box, info); - - info = clutter_text_new_with_text (NULL, "Click labels below to change AXIS pinning."); - clutter_actor_add_child (box, info); - - add_label ("NONE", box, scroll); - add_label ("X AXIS", box, scroll); - add_label ("Y AXIS", box, scroll); - add_label ("AUTO", box, scroll); - - g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); - g_signal_connect (stage, "key-press-event", G_CALLBACK (on_key_press), scroll); - - clutter_actor_show (stage); - - clutter_main (); - - return EXIT_SUCCESS; -} diff --git a/clutter/examples/rounded-rectangle.c b/clutter/examples/rounded-rectangle.c deleted file mode 100644 index 6ffdb4ce0..000000000 --- a/clutter/examples/rounded-rectangle.c +++ /dev/null @@ -1,110 +0,0 @@ -#include -#include -#include -#include - -static gboolean -draw_content (ClutterCanvas *canvas, - cairo_t *cr, - int surface_width, - int surface_height) -{ - /* rounded rectangle taken from: - * - * http://cairographics.org/samples/rounded_rectangle/ - * - * we leave 1 pixel around the edges to avoid jagged edges - * when rotating the actor - */ - double x = 1.0, /* parameters like cairo_rectangle */ - y = 1.0, - width = surface_width - 2.0, - height = surface_height - 2.0, - aspect = 1.0, /* aspect ratio */ - corner_radius = height / 20.0; /* and corner curvature radius */ - - double radius = corner_radius / aspect; - double degrees = M_PI / 180.0; - - cairo_save (cr); - cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); - cairo_paint (cr); - cairo_restore (cr); - - cairo_new_sub_path (cr); - cairo_arc (cr, x + width - radius, y + radius, radius, -90 * degrees, 0 * degrees); - cairo_arc (cr, x + width - radius, y + height - radius, radius, 0 * degrees, 90 * degrees); - cairo_arc (cr, x + radius, y + height - radius, radius, 90 * degrees, 180 * degrees); - cairo_arc (cr, x + radius, y + radius, radius, 180 * degrees, 270 * degrees); - cairo_close_path (cr); - - cairo_set_source_rgba (cr, 0.5, 0.5, 1, 0.95); - cairo_fill (cr); - - /* we're done drawing */ - return TRUE; -} - -int -main (int argc, char *argv[]) -{ - ClutterActor *stage, *actor; - ClutterContent *canvas; - ClutterTransition *transition; - - /* initialize Clutter */ - if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) - return EXIT_FAILURE; - - /* create a stage */ - stage = clutter_stage_new (); - clutter_stage_set_title (CLUTTER_STAGE (stage), "Rectangle with rounded corners"); - clutter_stage_set_use_alpha (CLUTTER_STAGE (stage), TRUE); - clutter_actor_set_background_color (stage, CLUTTER_COLOR_Black); - clutter_actor_set_size (stage, 500, 500); - clutter_actor_set_opacity (stage, 64); - clutter_actor_show (stage); - - /* our 2D canvas, courtesy of Cairo */ - canvas = clutter_canvas_new (); - clutter_canvas_set_size (CLUTTER_CANVAS (canvas), 300, 300); - - /* the actor that will display the contents of the canvas */ - actor = clutter_actor_new (); - clutter_actor_set_content (actor, canvas); - clutter_actor_set_content_gravity (actor, CLUTTER_CONTENT_GRAVITY_CENTER); - clutter_actor_set_content_scaling_filters (actor, - CLUTTER_SCALING_FILTER_TRILINEAR, - CLUTTER_SCALING_FILTER_LINEAR); - clutter_actor_set_pivot_point (actor, 0.5f, 0.5f); - clutter_actor_add_constraint (actor, clutter_align_constraint_new (stage, CLUTTER_ALIGN_BOTH, 0.5)); - clutter_actor_set_request_mode (actor, CLUTTER_REQUEST_CONTENT_SIZE); - clutter_actor_add_child (stage, actor); - - /* the actor now owns the canvas */ - g_object_unref (canvas); - - /* create the continuous animation of the actor spinning around its center */ - transition = clutter_property_transition_new ("rotation-angle-y"); - clutter_transition_set_from (transition, G_TYPE_DOUBLE, 0.0); - clutter_transition_set_to (transition, G_TYPE_DOUBLE, 360.0); - clutter_timeline_set_duration (CLUTTER_TIMELINE (transition), 2000); - clutter_timeline_set_repeat_count (CLUTTER_TIMELINE (transition), -1); - clutter_actor_add_transition (actor, "rotateActor", transition); - - /* the actor now owns the transition */ - g_object_unref (transition); - - /* quit on destroy */ - g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); - - /* connect our drawing code */ - g_signal_connect (canvas, "draw", G_CALLBACK (draw_content), NULL); - - /* invalidate the canvas, so that we can draw before the main loop starts */ - clutter_content_invalidate (canvas); - - clutter_main (); - - return EXIT_SUCCESS; -} diff --git a/clutter/examples/scroll-actor.c b/clutter/examples/scroll-actor.c deleted file mode 100644 index a5ffe3c90..000000000 --- a/clutter/examples/scroll-actor.c +++ /dev/null @@ -1,193 +0,0 @@ -#include -#include -#include - -static const char *menu_items_name[] = { - "Option 1", - "Option 2", - "Option 3", - "Option 4", - "Option 5", - "Option 6", - "Option 7", - "Option 8", - "Option 9", - "Option 10", - "Option 11", -}; - -static const guint menu_items_len = G_N_ELEMENTS (menu_items_name); - -static void -select_item_at_index (ClutterActor *scroll, - int index_) -{ - ClutterPoint point; - ClutterActor *menu, *item; - gpointer old_selected; - - menu = clutter_actor_get_first_child (scroll); - - old_selected = g_object_get_data (G_OBJECT (scroll), "selected-item"); - if (old_selected != NULL) - { - item = clutter_actor_get_child_at_index (menu, GPOINTER_TO_INT (old_selected)); - clutter_text_set_color (CLUTTER_TEXT (item), CLUTTER_COLOR_White); - } - - /* wrap around the index */ - if (index_ < 0) - index_ = clutter_actor_get_n_children (menu) - 1; - else if (index_ >= clutter_actor_get_n_children (menu)) - index_ = 0; - - item = clutter_actor_get_child_at_index (menu, index_); - clutter_actor_get_position (item, &point.x, &point.y); - - /* scroll to the actor's position; the menu actor is always set at (0, 0), - * so it does not contribute any further offset, and we can use the position - * of its children to ask the ScrollActor to scroll the visible region; if - * the menu actor had an offset, or was transformed, we would have needed to - * get their relative transformed position instead. - */ - clutter_actor_save_easing_state (scroll); - clutter_scroll_actor_scroll_to_point (CLUTTER_SCROLL_ACTOR (scroll), &point); - clutter_actor_restore_easing_state (scroll); - - clutter_text_set_color (CLUTTER_TEXT (item), CLUTTER_COLOR_LightSkyBlue); - - /* store the index of the currently selected item, so that we can - * implement select_next_item() and select_prev_item() - */ - g_object_set_data (G_OBJECT (scroll), "selected-item", - GINT_TO_POINTER (index_)); -} - -static void -select_next_item (ClutterActor *scroll) -{ - gpointer selected_ = g_object_get_data (G_OBJECT (scroll), "selected-item"); - - select_item_at_index (scroll, GPOINTER_TO_INT (selected_) + 1); -} - -static void -select_prev_item (ClutterActor *scroll) -{ - gpointer selected_ = g_object_get_data (G_OBJECT (scroll), "selected-item"); - - select_item_at_index (scroll, GPOINTER_TO_INT (selected_) - 1); -} - -static ClutterActor * -create_menu_item (const char *name) -{ - ClutterActor *text; - - text = clutter_text_new (); - clutter_text_set_font_name (CLUTTER_TEXT (text), "Sans Bold 24"); - clutter_text_set_text (CLUTTER_TEXT (text), name); - clutter_text_set_color (CLUTTER_TEXT (text), CLUTTER_COLOR_White); - clutter_actor_set_margin_left (text, 12.f); - clutter_actor_set_margin_right (text, 12.f); - - return text; -} - -static ClutterActor * -create_menu_actor (ClutterActor *scroll) -{ - ClutterActor *menu; - ClutterLayoutManager *layout_manager; - guint i; - - /* this is our menu; it contains items in a vertical layout */ - layout_manager = clutter_box_layout_new (); - clutter_box_layout_set_orientation (CLUTTER_BOX_LAYOUT (layout_manager), - CLUTTER_ORIENTATION_VERTICAL); - clutter_box_layout_set_spacing (CLUTTER_BOX_LAYOUT (layout_manager), 12.f); - - menu = clutter_actor_new (); - clutter_actor_set_layout_manager (menu, layout_manager); - clutter_actor_set_background_color (menu, CLUTTER_COLOR_Black); - - /* these are the items */ - for (i = 0; i < menu_items_len; i++) - clutter_actor_add_child (menu, create_menu_item (menu_items_name[i])); - - return menu; -} - -static ClutterActor * -create_scroll_actor (ClutterActor *stage) -{ - ClutterActor *scroll; - - /* our scrollable viewport */ - scroll = clutter_scroll_actor_new (); - clutter_actor_set_name (scroll, "scroll"); - - /* give a vertical offset, and constrain the viewport so that its size - * is bound to the stage size - */ - clutter_actor_set_position (scroll, 0.f, 18.f); - clutter_actor_add_constraint (scroll, clutter_align_constraint_new (stage, CLUTTER_ALIGN_X_AXIS, 0.5)); - clutter_actor_add_constraint (scroll, clutter_bind_constraint_new (stage, CLUTTER_BIND_HEIGHT, -36.f)); - - /* we only want to scroll the contents vertically, and - * ignore any horizontal component - */ - clutter_scroll_actor_set_scroll_mode (CLUTTER_SCROLL_ACTOR (scroll), - CLUTTER_SCROLL_VERTICALLY); - - clutter_actor_add_child (scroll, create_menu_actor (scroll)); - - /* select the first item */ - select_item_at_index (scroll, 0); - - return scroll; -} - -static gboolean -on_key_press (ClutterActor *stage, - ClutterEvent *event, - gpointer unused) -{ - ClutterActor *scroll; - guint key_symbol; - - scroll = clutter_actor_get_first_child (stage); - - key_symbol = clutter_event_get_key_symbol (event); - - if (key_symbol == CLUTTER_KEY_Up) - select_prev_item (scroll); - else if (key_symbol == CLUTTER_KEY_Down) - select_next_item (scroll); - - return CLUTTER_EVENT_STOP; -} - -int -main (int argc, char *argv[]) -{ - ClutterActor *stage; - - if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) - return EXIT_FAILURE; - - /* create a new stage */ - stage = clutter_stage_new (); - clutter_stage_set_title (CLUTTER_STAGE (stage), "Scroll Actor"); - clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE); - g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); - g_signal_connect (stage, "key-press-event", G_CALLBACK (on_key_press), NULL); - - clutter_actor_add_child (stage, create_scroll_actor (stage)); - - clutter_actor_show (stage); - - clutter_main (); - - return EXIT_SUCCESS; -} diff --git a/clutter/examples/threads.c b/clutter/examples/threads.c deleted file mode 100644 index 61e42e534..000000000 --- a/clutter/examples/threads.c +++ /dev/null @@ -1,292 +0,0 @@ -#include -#include -#include - -/* our thread-specific data */ -typedef struct -{ - ClutterActor *stage; - ClutterActor *label; - ClutterActor *progress; - ClutterActor *rect; - - ClutterTransition *flip; - ClutterTransition *bounce; -} TestThreadData; - -static TestThreadData * -test_thread_data_new (void) -{ - TestThreadData *data; - - data = g_new0 (TestThreadData, 1); - - return data; -} - -static void -test_thread_data_free (gpointer _data) -{ - TestThreadData *data = _data; - - if (data == NULL) - return; - - g_print ("Removing thread data [%p]\n", _data); - - g_clear_object (&data->progress); - g_clear_object (&data->label); - g_clear_object (&data->stage); - g_clear_object (&data->rect); - g_clear_object (&data->flip); - g_clear_object (&data->bounce); - - free (data); -} - -static gboolean -test_thread_done_idle (gpointer user_data) -{ - TestThreadData *data = user_data; - - g_print ("Last update [%p]\n", data); - - clutter_text_set_text (CLUTTER_TEXT (data->label), "Completed"); - - clutter_actor_remove_transition (data->rect, "bounce"); - clutter_actor_remove_transition (data->rect, "flip"); - - return G_SOURCE_REMOVE; -} - -static void -test_thread_data_done (gpointer _data) -{ - if (_data == NULL) - return; - - g_print ("Thread completed\n"); - - /* since the TestThreadData structure references Clutter data structures - * we need to free it from within the same thread that called clutter_main() - * which means using an idle handler in the main loop. - * - * clutter_threads_add_idle() is guaranteed to run the callback passed to - * to it under the Big Clutter Lock. - */ - clutter_threads_add_idle_full (G_PRIORITY_DEFAULT, - test_thread_done_idle, - _data, - test_thread_data_free); -} - -/* thread local storage */ -static GPrivate test_thread_data = G_PRIVATE_INIT (test_thread_data_done); - -typedef struct { - gint count; - TestThreadData *thread_data; -} TestUpdate; - -static gboolean -update_label_idle (gpointer data) -{ - TestUpdate *update = data; - guint width; - gchar *text; - - if (update->thread_data->label == NULL) - return G_SOURCE_REMOVE; - - text = g_strdup_printf ("Count to %d", update->count); - clutter_text_set_text (CLUTTER_TEXT (update->thread_data->label), text); - - clutter_actor_set_width (update->thread_data->label, -1); - - if (update->count == 0) - width = 0; - else if (update->count == 100) - width = 350; - else - width = (guint) (update->count / 100.0 * 350.0); - - clutter_actor_save_easing_state (update->thread_data->progress); - clutter_actor_set_width (update->thread_data->progress, width); - clutter_actor_restore_easing_state (update->thread_data->progress); - - free (text); - free (update); - - return G_SOURCE_REMOVE; -} - -static void -do_something_very_slow (void) -{ - TestThreadData *data; - gint i; - - data = g_private_get (&test_thread_data); - - for (i = 0; i <= 100; i++) - { - gint msecs; - - msecs = 1 + (int) (100.0 * rand () / ((RAND_MAX + 1.0) / 3)); - - /* sleep for a while, to emulate some work being done */ - g_usleep (msecs * 1000); - - if ((i % 10) == 0) - { - TestUpdate *update; - - /* update the UI from within the main loop, making sure that the - * Big Clutter Lock is held; only one thread at a time can call - * Clutter API, and it's mandatory to do this from the same thread - * that called clutter_init()/clutter_main(). - */ - update = g_new (TestUpdate, 1); - update->count = i; - update->thread_data = data; - - clutter_threads_add_idle_full (G_PRIORITY_HIGH, - update_label_idle, - update, NULL); - } - } -} - -static gpointer -test_thread_func (gpointer user_data) -{ - TestThreadData *data = user_data; - - g_private_set (&test_thread_data, data); - - /* this function will block */ - do_something_very_slow (); - - return NULL; -} - -static ClutterActor *count_label = NULL; -static ClutterActor *help_label = NULL; -static ClutterActor *progress_rect = NULL; -static ClutterActor *rect = NULL; -static ClutterTransition *flip = NULL; -static ClutterTransition *bounce = NULL; - -static gboolean -on_key_press_event (ClutterStage *stage, - ClutterEvent *event, - gpointer user_data) -{ - TestThreadData *data; - - switch (clutter_event_get_key_symbol (event)) - { - case CLUTTER_KEY_s: - clutter_text_set_text (CLUTTER_TEXT (help_label), "Press 'q' to quit"); - - /* start the animations */ - clutter_actor_add_transition (rect, "flip", flip); - clutter_actor_add_transition (rect, "bounce", bounce); - - /* the data structure holding all our objects */ - data = test_thread_data_new (); - data->stage = g_object_ref (stage); - data->label = g_object_ref (count_label); - data->progress = g_object_ref (progress_rect); - data->rect = g_object_ref (rect); - data->flip = g_object_ref (flip); - data->bounce = g_object_ref (bounce); - - /* start the thread that updates the counter and the progress bar */ - g_thread_new ("counter", test_thread_func, data); - - return CLUTTER_EVENT_STOP; - - case CLUTTER_KEY_q: - clutter_main_quit (); - - return CLUTTER_EVENT_STOP; - - default: - break; - } - - return CLUTTER_EVENT_PROPAGATE; -} - -int -main (int argc, char *argv[]) -{ - ClutterTransition *transition; - ClutterActor *stage; - ClutterPoint start = CLUTTER_POINT_INIT (75.f, 150.f); - ClutterPoint end = CLUTTER_POINT_INIT (400.f, 150.f); - - if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) - return 1; - - stage = clutter_stage_new (); - clutter_stage_set_title (CLUTTER_STAGE (stage), "Threading"); - clutter_actor_set_background_color (stage, CLUTTER_COLOR_Aluminium3); - clutter_actor_set_size (stage, 600, 300); - g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); - - count_label = clutter_text_new_with_text ("Mono 12", "Counter"); - clutter_actor_set_position (count_label, 350, 50); - clutter_actor_add_child (stage, count_label); - - help_label = clutter_text_new_with_text ("Mono 12", "Press 's' to start"); - clutter_actor_set_position (help_label, 50, 50); - clutter_actor_add_child (stage, help_label); - - /* a progress bar */ - progress_rect = clutter_actor_new (); - clutter_actor_set_background_color (progress_rect, CLUTTER_COLOR_DarkChameleon); - clutter_actor_set_position (progress_rect, 50, 225); - clutter_actor_set_size (progress_rect, 350, 50); - clutter_actor_add_child (stage, progress_rect); - - /* an actor we bounce around */ - rect = clutter_actor_new (); - clutter_actor_set_background_color (rect, CLUTTER_COLOR_LightScarletRed); - clutter_actor_set_position (rect, 75, 150); - clutter_actor_set_size (rect, 50, 50); - clutter_actor_set_pivot_point (rect, .5f, .5f); - clutter_actor_set_opacity (rect, 224); - clutter_actor_add_child (stage, rect); - - /* two transitions we use to bounce rect around */ - transition = clutter_property_transition_new ("rotation-angle-z"); - clutter_transition_set_from (transition, G_TYPE_DOUBLE, 0.0); - clutter_transition_set_to (transition, G_TYPE_DOUBLE, 360.0); - clutter_timeline_set_repeat_count (CLUTTER_TIMELINE (transition), -1); - clutter_timeline_set_auto_reverse (CLUTTER_TIMELINE (transition), TRUE); - clutter_timeline_set_duration (CLUTTER_TIMELINE (transition), 3000); - flip = transition; - - transition = clutter_property_transition_new ("position"); - clutter_transition_set_from (transition, CLUTTER_TYPE_POINT, &start); - clutter_transition_set_to (transition, CLUTTER_TYPE_POINT, &end); - clutter_timeline_set_repeat_count (CLUTTER_TIMELINE (transition), -1); - clutter_timeline_set_auto_reverse (CLUTTER_TIMELINE (transition), TRUE); - clutter_timeline_set_duration (CLUTTER_TIMELINE (transition), 3000); - bounce = transition; - - g_signal_connect (stage, - "button-press-event", G_CALLBACK (clutter_main_quit), - NULL); - g_signal_connect (stage, - "key-press-event", G_CALLBACK (on_key_press_event), - NULL); - - clutter_actor_show (stage); - - clutter_main (); - - return EXIT_SUCCESS; -} diff --git a/clutter/meson.build b/clutter/meson.build new file mode 100644 index 000000000..298d6f177 --- /dev/null +++ b/clutter/meson.build @@ -0,0 +1,88 @@ +clutter_includesubdir = join_paths(pkgname, 'clutter') +clutter_includedir = join_paths(includedir, clutter_includesubdir) + +clutter_includepath = include_directories('.', 'clutter') +clutter_includes = [clutter_includepath, cogl_includepath] + +clutter_c_args = [ + '-DCLUTTER_SYSCONFDIR="@0@"'.format(join_paths(prefix, sysconfdir)), + '-DCLUTTER_COMPILATION=1', + '-DCOGL_DISABLE_DEPRECATION_WARNINGS', + '-DG_LOG_DOMAIN="Clutter"', +] + +clutter_debug_c_args = [] +if get_option('debug') + clutter_debug_c_args += [ + '-DCLUTTER_ENABLE_DEBUG', + '-fno-omit-frame-pointer' + ] +elif buildtype != 'plain' + clutter_debug_c_args += [ + '-DG_DISABLE_ASSERT', + '-DG_DISABLE_CHECKS', + '-DG_DISABLE_CAST_CHECKS', + ] +endif +supported_clutter_debug_c_args = cc.get_supported_arguments(clutter_debug_c_args) +clutter_c_args += clutter_debug_c_args + +clutter_pkg_deps = [ + atk_dep, + cairo_gobject_dep, + glib_dep, + gobject_dep, + gio_dep, + json_glib_dep, + pango_dep, +] + +clutter_pkg_private_deps = [ + fribidi_dep, + gdk_pixbuf_dep, + gthread_dep, + gmodule_no_export_dep, + pangocairo_dep, +] + +if have_pango_ft2 + clutter_pkg_private_deps += [ + pangoft2_dep, + ] +endif + +if have_wayland + clutter_pkg_private_deps += [ + wayland_egl_dep, + wayland_server_dep, + ] +endif + +if have_x11 + clutter_pkg_deps += [ + x11_dep, + ] + clutter_pkg_private_deps += [ + xext_dep, + xdamage_dep, + xcomposite_dep, + xtst_dep, + xi_dep, + ] +endif + +if have_libwacom + clutter_pkg_private_deps += [ + libwacom_dep, + ] +endif + +clutter_deps = [ + clutter_pkg_deps, + clutter_pkg_private_deps, + libmutter_cogl_dep, + m_dep +] + +subdir('clutter') + diff --git a/clutter/tests/Makefile.am b/clutter/tests/Makefile.am deleted file mode 100644 index 65b474a49..000000000 --- a/clutter/tests/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = accessibility conform interactive micro-bench performance - -EXTRA_DIST = README clutter-1.0.suppressions diff --git a/clutter/tests/accessibility/.gitignore b/clutter/tests/accessibility/.gitignore deleted file mode 100644 index 2b1a0b151..000000000 --- a/clutter/tests/accessibility/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -/cally-atkcomponent-example -/cally-atkeditabletext-example -/cally-atkevents-example -/cally-atktext-example -/cally-clone-example diff --git a/clutter/tests/accessibility/Makefile.am b/clutter/tests/accessibility/Makefile.am deleted file mode 100644 index 0c812c97d..000000000 --- a/clutter/tests/accessibility/Makefile.am +++ /dev/null @@ -1,37 +0,0 @@ -common_ldadd = \ - $(top_builddir)/clutter/libmuffin-clutter-@MUFFIN_PLUGIN_API_VERSION@.la - -common_sources = \ - cally-examples-util.c \ - cally-examples-util.h - -AM_CPPFLAGS = \ - -DPREFIXDIR=\"$(libdir)\" \ - -DCLUTTER_DISABLE_DEPRECATION_WARNINGS \ - -DGLIB_DISABLE_DEPRECATION_WARNINGS \ - -I$(top_srcdir)/../cogl \ - -I$(top_builddir)/../cogl \ - -I$(top_builddir)/../cogl/cogl \ - -I$(top_srcdir) \ - -I$(top_builddir) \ - -I$(top_srcdir)/clutter \ - -I$(top_builddir)/clutter \ - -I$(top_srcdir)/tests/accessibility - -AM_CFLAGS = $(CLUTTER_CFLAGS) $(MAINTAINER_CFLAGS) -LDADD = $(common_ldadd) $(CLUTTER_LIBS) - -check_PROGRAMS = \ - cally-atkcomponent-example \ - cally-atkeditabletext-example \ - cally-atkevents-example \ - cally-atktext-example \ - cally-clone-example - -cally_atkcomponent_example_SOURCES = $(common_sources) cally-atkcomponent-example.c -cally_atktext_example_SOURCES = $(common_sources) cally-atktext-example.c -cally_atkevents_example_SOURCES = $(common_sources) cally-atkevents-example.c -cally_atkeditabletext_example_SOURCES = $(common_sources) cally-atkeditabletext-example.c -cally_clone_example_SOURCES = $(common_sources) cally-clone-example.c - -DISTCLEANFILES = diff --git a/clutter/tests/conform/Makefile.am b/clutter/tests/conform/Makefile.am deleted file mode 100644 index 03fe20b47..000000000 --- a/clutter/tests/conform/Makefile.am +++ /dev/null @@ -1,100 +0,0 @@ -installed_test_metadir = $(datadir)/installed-tests/muffin-clutter -installed_testdir = $(libexecdir)/installed-tests/muffin-clutter -include $(top_srcdir)/build/autotools/glib-tap.mk - -AM_CFLAGS = -g $(CLUTTER_CFLAGS) $(MAINTAINER_CFLAGS) -LDADD = $(top_builddir)/../cogl/cogl/libmuffin-cogl-@MUFFIN_PLUGIN_API_VERSION@.la $(top_builddir)/clutter/libmuffin-clutter-@MUFFIN_PLUGIN_API_VERSION@.la $(CLUTTER_LIBS) $(LIBM) -AM_LDFLAGS = -export-dynamic -AM_CPPFLAGS = \ - -DG_LOG_DOMAIN=\"Clutter-Conform\" \ - -I$(top_srcdir)/../cogl \ - -I$(top_builddir)/../cogl \ - -I$(top_builddir)/../cogl/cogl \ - -I$(top_srcdir) \ - -I$(top_builddir) \ - -DCOGL_DISABLE_DEPRECATION_WARNINGS \ - $(CLUTTER_DEPRECATED_CFLAGS) \ - $(CLUTTER_DEBUG_CFLAGS) - -# Basic actor API -actor_tests = \ - actor-anchors \ - actor-destroy \ - actor-graph \ - actor-invariants \ - actor-iter \ - actor-layout \ - actor-meta \ - actor-paint-opacity \ - actor-pick \ - actor-shader-effect \ - actor-size \ - $(NULL) - -# Disabled for offscreen-effect fix -# actor-offscreen-redirect -# actor-offscreen-limit-max-size - -# Actor classes -classes_tests = \ - text \ - $(NULL) - -# General API -general_tests = \ - binding-pool \ - color \ - events-touch \ - interval \ - model \ - script-parser \ - units \ - $(NULL) - -# Test for deprecated functionality -deprecated_tests = \ - animator \ - behaviours \ - group \ - rectangle \ - texture \ - $(NULL) - -test_programs = $(actor_tests) $(general_tests) $(classes_tests) $(deprecated_tests) - -dist_test_data = $(script_ui_files) -script_ui_files = $(addprefix scripts/,$(script_tests)) -script_tests = \ - test-animator-1.json \ - test-animator-2.json \ - test-animator-3.json \ - test-script-animation.json \ - test-script-child.json \ - test-script-implicit-alpha.json \ - test-script-interval.json \ - test-script-layout-property.json \ - test-script-margin.json \ - test-script-model.json \ - test-script-named-object.json \ - test-script-object-property.json \ - test-script-single.json \ - test-script-timeline-markers.json \ - test-state-1.json - -TESTS_ENVIRONMENT += G_ENABLE_DIAGNOSTIC=0 CLUTTER_ENABLE_DIAGNOSTIC=0 CLUTTER_SCALE=1 - -# simple rules for generating a Git ignore file for the conformance test suite -$(srcdir)/.gitignore: Makefile - $(AM_V_GEN)( echo "/*.trs" ; \ - echo "/*.log" ; \ - echo "/*.test" ; \ - echo "/.gitignore" ; \ - for p in $(test_programs); do \ - echo "/$$p" ; \ - done ) > $(@F) - -gitignore: $(srcdir)/.gitignore - -all-am: gitignore - -DISTCLEANFILES += .gitignore diff --git a/clutter/tests/conform/actor-offscreen-limit-max-size.c b/clutter/tests/conform/actor-offscreen-limit-max-size.c deleted file mode 100644 index 943c7d8a7..000000000 --- a/clutter/tests/conform/actor-offscreen-limit-max-size.c +++ /dev/null @@ -1,119 +0,0 @@ -#define CLUTTER_ENABLE_EXPERIMENTAL_API -#include - -#define STAGE_WIDTH (300) -#define STAGE_HEIGHT (300) - -typedef struct -{ - ClutterActor *stage; - - ClutterActor *actor_group1; - ClutterEffect *blur_effect1; - - ClutterActor *actor_group2; - ClutterEffect *blur_effect2; -} Data; - -static void -check_results (ClutterStage *stage, gpointer user_data) -{ - Data *data = user_data; - gfloat width, height; - ClutterRect rect; - - clutter_offscreen_effect_get_target_rect (CLUTTER_OFFSCREEN_EFFECT (data->blur_effect1), - &rect); - - width = clutter_rect_get_width (&rect); - height = clutter_rect_get_height (&rect); - - if (g_test_verbose ()) - g_print ("Checking effect1 size: %.2f x %.2f\n", - clutter_rect_get_width (&rect), - clutter_rect_get_height (&rect)); - - g_assert_cmpint (width, <, STAGE_WIDTH); - g_assert_cmpint (height, <, STAGE_HEIGHT); - - clutter_offscreen_effect_get_target_rect (CLUTTER_OFFSCREEN_EFFECT (data->blur_effect2), - &rect); - - width = clutter_rect_get_width (&rect); - height = clutter_rect_get_height (&rect); - - if (g_test_verbose ()) - g_print ("Checking effect2 size: %.2f x %.2f\n", width, height); - - g_assert_cmpint (width, ==, STAGE_WIDTH); - g_assert_cmpint (height, ==, STAGE_HEIGHT); - - - clutter_main_quit (); -} - -static ClutterActor * -create_actor (gfloat x, gfloat y, - gfloat width, gfloat height, - const ClutterColor *color) -{ - return g_object_new (CLUTTER_TYPE_ACTOR, - "x", x, - "y", y, - "width", width, - "height", height, - "background-color", color, - NULL); -} - -static void -actor_offscreen_limit_max_size (void) -{ - Data data; - - if (!cogl_features_available (COGL_FEATURE_OFFSCREEN)) - return; - - data.stage = clutter_test_get_stage (); - g_signal_connect (data.stage, "after-paint", - G_CALLBACK (check_results), &data); - clutter_actor_set_size (data.stage, STAGE_WIDTH, STAGE_HEIGHT); - - data.actor_group1 = clutter_actor_new (); - clutter_actor_add_child (data.stage, data.actor_group1); - data.blur_effect1 = clutter_blur_effect_new (); - clutter_actor_add_effect (data.actor_group1, data.blur_effect1); - clutter_actor_add_child (data.actor_group1, - create_actor (10, 10, - 100, 100, - CLUTTER_COLOR_Blue)); - clutter_actor_add_child (data.actor_group1, - create_actor (100, 100, - 100, 100, - CLUTTER_COLOR_Gray)); - - data.actor_group2 = clutter_actor_new (); - clutter_actor_add_child (data.stage, data.actor_group2); - data.blur_effect2 = clutter_blur_effect_new (); - clutter_actor_add_effect (data.actor_group2, data.blur_effect2); - clutter_actor_add_child (data.actor_group2, - create_actor (-10, -10, - 100, 100, - CLUTTER_COLOR_Yellow)); - clutter_actor_add_child (data.actor_group2, - create_actor (250, 10, - 100, 100, - CLUTTER_COLOR_ScarletRed)); - clutter_actor_add_child (data.actor_group2, - create_actor (10, 250, - 100, 100, - CLUTTER_COLOR_Yellow)); - - clutter_actor_show (data.stage); - - clutter_main (); -} - -CLUTTER_TEST_SUITE ( - CLUTTER_TEST_UNIT ("/actor/offscreen/limit-max-size", actor_offscreen_limit_max_size) -) diff --git a/clutter/tests/conform/animator.c b/clutter/tests/conform/animator.c deleted file mode 100644 index ec7032d73..000000000 --- a/clutter/tests/conform/animator.c +++ /dev/null @@ -1,199 +0,0 @@ -#define CLUTTER_DISABLE_DEPRECATION_WARNINGS -#include - -static void -animator_multi_properties (void) -{ - ClutterScript *script = clutter_script_new (); - GObject *animator = NULL, *foo = NULL; - GError *error = NULL; - gchar *test_file; - GList *keys; - ClutterAnimatorKey *key; - GValue value = { 0, }; - - test_file = g_test_build_filename (G_TEST_DIST, - "scripts", - "test-animator-3.json", - NULL); - clutter_script_load_from_file (script, test_file, &error); - if (g_test_verbose () && error) - g_print ("Error: %s", error->message); - - g_assert_no_error (error); - - foo = clutter_script_get_object (script, "foo"); - g_assert (G_IS_OBJECT (foo)); - - animator = clutter_script_get_object (script, "animator"); - g_assert (CLUTTER_IS_ANIMATOR (animator)); - - /* get all the keys for foo:x */ - keys = clutter_animator_get_keys (CLUTTER_ANIMATOR (animator), - foo, "x", - -1.0); - g_assert_cmpint (g_list_length (keys), ==, 3); - - key = g_list_nth_data (keys, 1); - g_assert (key != NULL); - - if (g_test_verbose ()) - { - g_print ("(foo, x).keys[1] = \n" - ".object = %s\n" - ".progress = %.2f\n" - ".name = '%s'\n" - ".type = '%s'\n", - clutter_get_script_id (clutter_animator_key_get_object (key)), - clutter_animator_key_get_progress (key), - clutter_animator_key_get_property_name (key), - g_type_name (clutter_animator_key_get_property_type (key))); - } - - g_assert (clutter_animator_key_get_object (key) != NULL); - g_assert_cmpfloat (clutter_animator_key_get_progress (key), ==, 0.2); - g_assert_cmpstr (clutter_animator_key_get_property_name (key), ==, "x"); - - g_assert (clutter_animator_key_get_property_type (key) == G_TYPE_FLOAT); - - g_value_init (&value, G_TYPE_FLOAT); - g_assert (clutter_animator_key_get_value (key, &value)); - g_assert_cmpfloat (g_value_get_float (&value), ==, 150.0); - g_value_unset (&value); - - g_list_free (keys); - - /* get all the keys for foo:y */ - keys = clutter_animator_get_keys (CLUTTER_ANIMATOR (animator), - foo, "y", - -1.0); - g_assert_cmpint (g_list_length (keys), ==, 3); - - key = g_list_nth_data (keys, 2); - g_assert (key != NULL); - - if (g_test_verbose ()) - { - g_print ("(foo, y).keys[2] = \n" - ".object = %s\n" - ".progress = %.2f\n" - ".name = '%s'\n" - ".type = '%s'\n", - clutter_get_script_id (clutter_animator_key_get_object (key)), - clutter_animator_key_get_progress (key), - clutter_animator_key_get_property_name (key), - g_type_name (clutter_animator_key_get_property_type (key))); - } - - g_assert (clutter_animator_key_get_object (key) != NULL); - g_assert_cmpfloat (clutter_animator_key_get_progress (key), ==, 0.8); - g_assert_cmpstr (clutter_animator_key_get_property_name (key), ==, "y"); - - g_assert (clutter_animator_key_get_property_type (key) == G_TYPE_FLOAT); - - g_value_init (&value, G_TYPE_FLOAT); - g_assert (clutter_animator_key_get_value (key, &value)); - g_assert_cmpfloat (g_value_get_float (&value), ==, 200.0); - g_value_unset (&value); - - g_list_free (keys); - - g_object_unref (script); - free (test_file); -} - -static void -animator_properties (void) -{ - ClutterScript *script = clutter_script_new (); - GObject *animator = NULL; - GError *error = NULL; - gchar *test_file; - GList *keys; - ClutterAnimatorKey *key; - GValue value = { 0, }; - - test_file = g_test_build_filename (G_TEST_DIST, - "scripts", - "test-animator-2.json", - NULL); - clutter_script_load_from_file (script, test_file, &error); - if (g_test_verbose () && error) - g_print ("Error: %s", error->message); - - g_assert_no_error (error); - - animator = clutter_script_get_object (script, "animator"); - g_assert (CLUTTER_IS_ANIMATOR (animator)); - - /* get all the keys */ - keys = clutter_animator_get_keys (CLUTTER_ANIMATOR (animator), - NULL, NULL, -1.0); - g_assert_cmpint (g_list_length (keys), ==, 3); - - key = g_list_nth_data (keys, 1); - g_assert (key != NULL); - - if (g_test_verbose ()) - { - g_print ("keys[1] = \n" - ".object = %s\n" - ".progress = %.2f\n" - ".name = '%s'\n" - ".type = '%s'\n", - clutter_get_script_id (clutter_animator_key_get_object (key)), - clutter_animator_key_get_progress (key), - clutter_animator_key_get_property_name (key), - g_type_name (clutter_animator_key_get_property_type (key))); - } - - g_assert (clutter_animator_key_get_object (key) != NULL); - g_assert_cmpfloat (clutter_animator_key_get_progress (key), ==, 0.2); - g_assert_cmpstr (clutter_animator_key_get_property_name (key), ==, "x"); - - g_assert (clutter_animator_key_get_property_type (key) == G_TYPE_FLOAT); - - g_value_init (&value, G_TYPE_FLOAT); - g_assert (clutter_animator_key_get_value (key, &value)); - g_assert_cmpfloat (g_value_get_float (&value), ==, 150.0); - g_value_unset (&value); - - g_list_free (keys); - g_object_unref (script); - free (test_file); -} - -static void -animator_base (void) -{ - ClutterScript *script = clutter_script_new (); - GObject *animator = NULL; - GError *error = NULL; - guint duration = 0; - gchar *test_file; - - test_file = g_test_build_filename (G_TEST_DIST, - "scripts", - "test-animator-1.json", - NULL); - clutter_script_load_from_file (script, test_file, &error); - if (g_test_verbose () && error) - g_print ("Error: %s", error->message); - - g_assert_no_error (error); - - animator = clutter_script_get_object (script, "animator"); - g_assert (CLUTTER_IS_ANIMATOR (animator)); - - duration = clutter_animator_get_duration (CLUTTER_ANIMATOR (animator)); - g_assert_cmpint (duration, ==, 1000); - - g_object_unref (script); - free (test_file); -} - -CLUTTER_TEST_SUITE ( - CLUTTER_TEST_UNIT ("/script/animator/base", animator_base) - CLUTTER_TEST_UNIT ("/script/animator/properties", animator_properties) - CLUTTER_TEST_UNIT ("/script/animator/multi-properties", animator_multi_properties) -) diff --git a/clutter/tests/conform/behaviours.c b/clutter/tests/conform/behaviours.c deleted file mode 100644 index 40fdcfb09..000000000 --- a/clutter/tests/conform/behaviours.c +++ /dev/null @@ -1,80 +0,0 @@ -#define CLUTTER_DISABLE_DEPRECATION_WARNINGS -#include - -static void -behaviour_opacity (void) -{ - ClutterBehaviour *behaviour; - ClutterTimeline *timeline; - ClutterAlpha *alpha; - guint8 start, end; - guint starti; - - timeline = clutter_timeline_new (500); - alpha = clutter_alpha_new_full (timeline, CLUTTER_LINEAR); - behaviour = clutter_behaviour_opacity_new (alpha, 0, 255); - g_assert (CLUTTER_IS_BEHAVIOUR_OPACITY (behaviour)); - g_object_add_weak_pointer (G_OBJECT (behaviour), (gpointer *) &behaviour); - g_object_add_weak_pointer (G_OBJECT (timeline), (gpointer *) &timeline); - - clutter_behaviour_opacity_get_bounds (CLUTTER_BEHAVIOUR_OPACITY (behaviour), - &start, - &end); - - if (g_test_verbose ()) - g_print ("BehaviourOpacity:bounds = %d, %d (expected: 0, 255)\n", - start, - end); - - g_assert_cmpint (start, ==, 0); - g_assert_cmpint (end, ==, 255); - - clutter_behaviour_opacity_set_bounds (CLUTTER_BEHAVIOUR_OPACITY (behaviour), - 255, - 0); - /* XXX: The gobject property is actually a unsigned int not unsigned char - * property so we have to be careful not to corrupt the stack by passing - * a guint8 pointer here... */ - starti = 0; - g_object_get (G_OBJECT (behaviour), "opacity-start", &starti, NULL); - - if (g_test_verbose ()) - g_print ("BehaviourOpacity:start = %d (expected: 255)\n", start); - - g_assert_cmpint (starti, ==, 255); - - g_object_unref (behaviour); - g_object_unref (timeline); - - g_assert_null (behaviour); - g_assert_null (timeline); -} - -static struct -{ - const gchar *path; - GTestFunc func; -} behaviour_tests[] = { - { "opacity", behaviour_opacity }, -}; - -static const int n_behaviour_tests = G_N_ELEMENTS (behaviour_tests); - -int -main (int argc, char *argv[]) -{ - int i; - - clutter_test_init (&argc, &argv); - - for (i = 0; i < n_behaviour_tests; i++) - { - char *path = g_strconcat ("/behaviours/", behaviour_tests[i].path, NULL); - - clutter_test_add (path, behaviour_tests[i].func); - - free (path); - } - - return clutter_test_run (); -} diff --git a/clutter/tests/conform/cairo-texture.c b/clutter/tests/conform/cairo-texture.c deleted file mode 100644 index dd7818063..000000000 --- a/clutter/tests/conform/cairo-texture.c +++ /dev/null @@ -1,198 +0,0 @@ -#include -#include - -#include "test-conform-common.h" - -#define BLOCK_SIZE 16 - -/* Number of pixels at the border of a block to skip when verifying */ -#define TEST_INSET 1 - -static const ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff }; - -typedef enum -{ - /* The first frame is drawn using clutter_cairo_texture_create. The - second frame is an update of the first frame using - clutter_cairo_texture_create_region. The states are stored like - this because the cairo drawing is done on idle and the validation - is done during paint and we need to synchronize the two */ - TEST_BEFORE_DRAW_FIRST_FRAME, - TEST_BEFORE_VALIDATE_FIRST_FRAME, - TEST_BEFORE_DRAW_SECOND_FRAME, - TEST_BEFORE_VALIDATE_SECOND_FRAME, - TEST_DONE -} TestProgress; - -typedef struct _TestState -{ - ClutterActor *stage; - ClutterActor *ct; - guint frame; - TestProgress progress; -} TestState; - -static void -validate_part (int block_x, int block_y, const ClutterColor *color) -{ - guint8 data[BLOCK_SIZE * BLOCK_SIZE * 4]; - int x, y; - - cogl_read_pixels (block_x * BLOCK_SIZE, - block_y * BLOCK_SIZE, - BLOCK_SIZE, BLOCK_SIZE, - COGL_READ_PIXELS_COLOR_BUFFER, - COGL_PIXEL_FORMAT_RGBA_8888_PRE, - data); - - for (x = 0; x < BLOCK_SIZE - TEST_INSET * 2; x++) - for (y = 0; y < BLOCK_SIZE - TEST_INSET * 2; y++) - { - const guint8 *p = data + ((x + TEST_INSET) * 4 + - (y + TEST_INSET) * BLOCK_SIZE * 4); - - g_assert_cmpint (p[0], ==, color->red); - g_assert_cmpint (p[1], ==, color->green); - g_assert_cmpint (p[2], ==, color->blue); - } -} - -static void -paint_cb (ClutterActor *actor, TestState *state) -{ - static const ClutterColor red = { 0xff, 0x00, 0x00, 0xff }; - static const ClutterColor green = { 0x00, 0xff, 0x00, 0xff }; - static const ClutterColor blue = { 0x00, 0x00, 0xff, 0xff }; - - if (state->frame++ < 2) - return; - - switch (state->progress) - { - case TEST_BEFORE_DRAW_FIRST_FRAME: - case TEST_BEFORE_DRAW_SECOND_FRAME: - case TEST_DONE: - /* Handled by the idle callback */ - break; - - case TEST_BEFORE_VALIDATE_FIRST_FRAME: - /* In the first frame there is a red rectangle next to a green - rectangle */ - validate_part (0, 0, &red); - validate_part (1, 0, &green); - - state->progress = TEST_BEFORE_DRAW_SECOND_FRAME; - break; - - case TEST_BEFORE_VALIDATE_SECOND_FRAME: - /* The second frame is the same except the green rectangle is - replaced with a blue one */ - validate_part (0, 0, &red); - validate_part (1, 0, &blue); - - state->progress = TEST_DONE; - break; - } -} - -static gboolean -idle_cb (gpointer data) -{ - TestState *state = data; - cairo_t *cr; - - if (state->frame < 2) - clutter_actor_queue_redraw (CLUTTER_ACTOR (state->stage)); - else - switch (state->progress) - { - case TEST_BEFORE_DRAW_FIRST_FRAME: - /* Draw two different colour rectangles */ - cr = clutter_cairo_texture_create (CLUTTER_CAIRO_TEXTURE (state->ct)); - - cairo_save (cr); - cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); - - cairo_save (cr); - cairo_rectangle (cr, 0, 0, BLOCK_SIZE, BLOCK_SIZE); - cairo_clip (cr); - cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); - cairo_paint (cr); - cairo_restore (cr); - - cairo_rectangle (cr, BLOCK_SIZE, 0, BLOCK_SIZE, BLOCK_SIZE); - cairo_clip (cr); - cairo_set_source_rgb (cr, 0.0, 1.0, 0.0); - cairo_paint (cr); - - cairo_restore (cr); - - cairo_destroy (cr); - - state->progress = TEST_BEFORE_VALIDATE_FIRST_FRAME; - - break; - - case TEST_BEFORE_DRAW_SECOND_FRAME: - /* Replace the second rectangle with a blue one */ - cr = clutter_cairo_texture_create (CLUTTER_CAIRO_TEXTURE (state->ct)); - - cairo_rectangle (cr, BLOCK_SIZE, 0, BLOCK_SIZE, BLOCK_SIZE); - cairo_set_source_rgb (cr, 0.0, 0.0, 1.0); - cairo_fill (cr); - - cairo_destroy (cr); - - state->progress = TEST_BEFORE_VALIDATE_SECOND_FRAME; - - break; - - case TEST_BEFORE_VALIDATE_FIRST_FRAME: - case TEST_BEFORE_VALIDATE_SECOND_FRAME: - /* Handled by the paint callback */ - break; - - case TEST_DONE: - clutter_main_quit (); - break; - } - - return G_SOURCE_CONTINUE; -} - -void -texture_cairo (TestConformSimpleFixture *fixture, - gconstpointer data) -{ - TestState state; - unsigned int idle_source; - unsigned int paint_handler; - - state.frame = 0; - state.stage = clutter_stage_new (); - state.progress = TEST_BEFORE_DRAW_FIRST_FRAME; - - state.ct = clutter_cairo_texture_new (BLOCK_SIZE * 2, BLOCK_SIZE); - clutter_container_add_actor (CLUTTER_CONTAINER (state.stage), state.ct); - - clutter_stage_set_color (CLUTTER_STAGE (state.stage), &stage_color); - - /* We force continuous redrawing of the stage, since we need to skip - * the first few frames, and we wont be doing anything else that - * will trigger redrawing. */ - idle_source = clutter_threads_add_idle (idle_cb, &state); - paint_handler = g_signal_connect_after (state.stage, "paint", - G_CALLBACK (paint_cb), &state); - - clutter_actor_show (state.stage); - clutter_main (); - - g_signal_handler_disconnect (state.stage, paint_handler); - g_source_remove (idle_source); - - if (g_test_verbose ()) - g_print ("OK\n"); - - clutter_actor_destroy (state.stage); -} - diff --git a/clutter/tests/conform/events-touch.c b/clutter/tests/conform/events-touch.c deleted file mode 100644 index 124b821af..000000000 --- a/clutter/tests/conform/events-touch.c +++ /dev/null @@ -1,392 +0,0 @@ -/* - * Copyright (C) 2009 Red Hat, Inc. - * Copyright (C) 2012 Collabora Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for - * more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * Boston, MA 02111-1307, USA. - * - */ - -#include - -#if defined CLUTTER_WINDOWING_X11 && OS_LINUX && HAVE_XINPUT_2_2 - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define ABS_MAX_X 32768 -#define ABS_MAX_Y 32768 - -#define TOUCH_POINTS 10 - -static ClutterPoint gesture_points[] = { - { 100., 100. }, - { 110., 100. }, - { 120., 100. }, - { 130., 100. }, - { 140., 100. }, - { 150., 100. }, - { 160., 100. }, - { 170., 100. }, - { 180., 100. }, - { 190., 100. }, -}; - -typedef struct _State State; - -struct _State -{ - gboolean pass; - ClutterPoint gesture_points_to_check[TOUCH_POINTS]; - int gesture_points; -}; - -static int fd = -1; - -static void send_event(int fd, int type, int code, int value, int sec, int usec) -{ - static int sec_offset = -1; - static long last_time = -1; - long newtime; - struct input_event event; - - event.type = type; - event.code = code; - event.value = value; - - if (sec_offset == -1) - sec_offset = sec; - - sec -= sec_offset; - newtime = sec * 1000000 + usec; - - if (last_time > 0) - usleep(newtime - last_time); - - gettimeofday(&event.time, NULL); - - if (write(fd, &event, sizeof(event)) < sizeof(event)) - perror("Send event failed."); - - last_time = newtime; -} - -static gboolean -event_cb (ClutterActor *actor, ClutterEvent *event, State *state) -{ - int i; - - if (event->type != CLUTTER_TOUCH_BEGIN && - event->type != CLUTTER_TOUCH_UPDATE) - return FALSE; - - state->gesture_points_to_check[state->gesture_points].x = ceil (event->touch.x); - state->gesture_points_to_check[state->gesture_points].y = ceil (event->touch.y); - state->gesture_points++; - - if (state->gesture_points == TOUCH_POINTS) - { - for (i = 0; i < TOUCH_POINTS; i++) - { - if (state->gesture_points_to_check[i].x != gesture_points[i].x || - state->gesture_points_to_check[i].y != gesture_points[i].y) - { - if (g_test_verbose ()) - g_print ("error: expected (%d, %d) but found (%d, %d) at position %d\n", - (int) gesture_points[i].x, (int) gesture_points[i].y, - (int) state->gesture_points_to_check[i].x, - (int) state->gesture_points_to_check[i].y, - i); - state->pass = FALSE; - break; - } - } - - clutter_main_quit (); - } - - return TRUE; -} - -static void -screen_coords_to_device (int screen_x, int screen_y, - int *device_x, int *device_y) -{ - int display_width = DisplayWidth (clutter_x11_get_default_display (), - clutter_x11_get_default_screen ()); - int display_height = DisplayHeight (clutter_x11_get_default_display (), - clutter_x11_get_default_screen ()); - - *device_x = (screen_x * ABS_MAX_X) / display_width; - *device_y = (screen_y * ABS_MAX_Y) / display_height; -} - -static gboolean -perform_gesture (gpointer data) -{ - int i; - - for (i = 0; i < TOUCH_POINTS; i++) - { - int x = gesture_points[i].x; - int y = gesture_points[i].y; - - screen_coords_to_device (x, y, &x, &y); - - send_event(fd, EV_ABS, ABS_MT_SLOT, 0, 1, i * 100); - send_event(fd, EV_ABS, ABS_MT_TRACKING_ID, 1, 1, i * 100 + 10); - - send_event(fd, EV_ABS, ABS_MT_POSITION_X, x, 1, i * 100 + 20); - send_event(fd, EV_ABS, ABS_MT_POSITION_Y, y, 1, i * 100 + 30); - send_event(fd, EV_SYN, SYN_MT_REPORT, 0, 1, i * 100 + 40); - send_event(fd, EV_SYN, SYN_REPORT, 0, 1, i * 100 + 50); - } - - send_event(fd, EV_ABS, ABS_MT_TRACKING_ID, -1, 1, TOUCH_POINTS * 100 + 10); - send_event(fd, EV_SYN, SYN_MT_REPORT, 0, 1, TOUCH_POINTS * 100 + 20); - send_event(fd, EV_SYN, SYN_REPORT, 0, 1, TOUCH_POINTS * 100 + 30); - - return G_SOURCE_REMOVE; -} - -static int -setup (struct uinput_user_dev *dev, int fd) -{ - strcpy (dev->name, "eGalax Touch Screen"); - dev->id.bustype = 0x18; - dev->id.vendor = 0xeef; - dev->id.product = 0x20; - dev->id.version = 0x1; - - if (ioctl (fd, UI_SET_EVBIT, EV_SYN) == -1) - goto error; - - if (ioctl (fd, UI_SET_EVBIT, EV_KEY) == -1) - goto error; - - if (ioctl (fd, UI_SET_KEYBIT, BTN_TOUCH) == -1) - goto error; - - if (ioctl (fd, UI_SET_EVBIT, EV_ABS) == -1) - goto error; - - if (ioctl (fd, UI_SET_ABSBIT, ABS_X) == -1) - goto error; - else - { - int idx = ABS_X; - dev->absmin[idx] = 0; - dev->absmax[idx] = ABS_MAX_X; - dev->absfuzz[idx] = 1; - dev->absflat[idx] = 0; - - if (dev->absmin[idx] == dev->absmax[idx]) - dev->absmax[idx]++; - } - - if (ioctl (fd, UI_SET_ABSBIT, ABS_Y) == -1) - goto error; - else - { - int idx = ABS_Y; - dev->absmin[idx] = 0; - dev->absmax[idx] = ABS_MAX_Y; - dev->absfuzz[idx] = 1; - dev->absflat[idx] = 0; - - if (dev->absmin[idx] == dev->absmax[idx]) - dev->absmax[idx]++; - } - - if (ioctl (fd, UI_SET_ABSBIT, ABS_PRESSURE) == -1) - goto error; - else - { - int idx = ABS_PRESSURE; - dev->absmin[idx] = 0; - dev->absmax[idx] = 0; - dev->absfuzz[idx] = 0; - dev->absflat[idx] = 0; - - if (dev->absmin[idx] == dev->absmax[idx]) - dev->absmax[idx]++; - } - - if (ioctl (fd, UI_SET_ABSBIT, ABS_MT_TOUCH_MAJOR) == -1) - goto error; - else - { - int idx = ABS_MT_TOUCH_MAJOR; - dev->absmin[idx] = 0; - dev->absmax[idx] = 255; - dev->absfuzz[idx] = 1; - dev->absflat[idx] = 0; - - if (dev->absmin[idx] == dev->absmax[idx]) - dev->absmax[idx]++; - } - - if (ioctl (fd, UI_SET_ABSBIT, ABS_MT_WIDTH_MAJOR) == -1) - goto error; - else - { - int idx = ABS_MT_WIDTH_MAJOR; - dev->absmin[idx] = 0; - dev->absmax[idx] = 255; - dev->absfuzz[idx] = 1; - dev->absflat[idx] = 0; - - if (dev->absmin[idx] == dev->absmax[idx]) - dev->absmax[idx]++; - } - - if (ioctl (fd, UI_SET_ABSBIT, ABS_MT_POSITION_X) == -1) - goto error; - else - { - int idx = ABS_MT_POSITION_X; - dev->absmin[idx] = 0; - dev->absmax[idx] = ABS_MAX_X; - dev->absfuzz[idx] = 1; - dev->absflat[idx] = 0; - - if (dev->absmin[idx] == dev->absmax[idx]) - dev->absmax[idx]++; - } - - if (ioctl (fd, UI_SET_ABSBIT, ABS_MT_POSITION_Y) == -1) - goto error; - else - { - int idx = ABS_MT_POSITION_Y; - dev->absmin[idx] = 0; - dev->absmax[idx] = ABS_MAX_Y; - dev->absfuzz[idx] = 1; - dev->absflat[idx] = 0; - - if (dev->absmin[idx] == dev->absmax[idx]) - dev->absmax[idx]++; - } - - if (ioctl (fd, UI_SET_ABSBIT, ABS_MT_TRACKING_ID) == -1) - goto error; - else - { - int idx = ABS_MT_TRACKING_ID; - dev->absmin[idx] = 0; - dev->absmax[idx] = 5; - dev->absfuzz[idx] = 0; - dev->absflat[idx] = 0; - - if (dev->absmin[idx] == dev->absmax[idx]) - dev->absmax[idx]++; - } - - - - return 0; -error: - perror ("ioctl failed."); - return -1; -} - -static int -init_uinput (void) -{ - struct uinput_user_dev dev; - - fd = open ("/dev/uinput", O_RDWR); - if (fd < 0 && errno == ENODEV) - fd = open ("/dev/input/uinput", O_RDWR); - if (fd < 0) - { - if (g_test_verbose ()) - perror ("open"); - - return 0; - }; - - memset (&dev, 0, sizeof (dev)); - setup (&dev, fd); - - if (write (fd, &dev, sizeof (dev)) < sizeof (dev)) - { - if (g_test_verbose ()) - perror ("write"); - - goto error; - } - - if (ioctl (fd, UI_DEV_CREATE, NULL) == -1) - { - if (g_test_verbose ()) - perror ("ioctl"); - - goto error; - } - - return 1; - -error: - if (fd != -1) - close (fd); - - return 0; -} - -#endif /* defined CLUTTER_WINDOWING_X11 && OS_LINUX && HAVE_XINPUT_2_2 */ - -static void -events_touch (void) -{ -#if defined CLUTTER_WINDOWING_X11 && OS_LINUX && HAVE_XINPUT_2_2 - ClutterActor *stage; - State state; - - /* bail out if we could not initialize evdev */ - if (!init_uinput ()) - return; - - state.pass = TRUE; - state.gesture_points = 0; - - stage = clutter_test_get_stage (); - g_signal_connect (stage, "event", G_CALLBACK (event_cb), &state); - clutter_stage_set_fullscreen (CLUTTER_STAGE (stage), TRUE); - clutter_actor_show (stage); - - clutter_threads_add_timeout (500, perform_gesture, &state); - - clutter_main (); - - if (g_test_verbose ()) - g_print ("end result: %s\n", state.pass ? "pass" : "FAIL"); - - g_assert (state.pass); -#endif /* defined CLUTTER_WINDOWING_X11 && OS_LINUX && HAVE_XINPUT_2_2 */ -} - -CLUTTER_TEST_SUITE ( - CLUTTER_TEST_UNIT ("/events/touch", events_touch) -) diff --git a/clutter/tests/conform/model.c b/clutter/tests/conform/model.c deleted file mode 100644 index f911f6ef7..000000000 --- a/clutter/tests/conform/model.c +++ /dev/null @@ -1,528 +0,0 @@ -#include -#include -#define CLUTTER_DISABLE_DEPRECATION_WARNINGS -#include - -typedef struct _ModelData -{ - ClutterModel *model; - - guint n_row; -} ModelData; - -typedef struct _ChangedData -{ - ClutterModel *model; - - ClutterModelIter *iter; - - guint row; - guint n_emissions; - - gint value_check; -} ChangedData; - -enum -{ - COLUMN_FOO, /* G_TYPE_STRING */ - COLUMN_BAR, /* G_TYPE_INT */ - - N_COLUMNS -}; - -static const struct { - const gchar *expected_foo; - gint expected_bar; -} base_model[] = { - { "String 1", 1 }, - { "String 2", 2 }, - { "String 3", 3 }, - { "String 4", 4 }, - { "String 5", 5 }, - { "String 6", 6 }, - { "String 7", 7 }, - { "String 8", 8 }, - { "String 9", 9 }, -}; - -static const struct { - const gchar *expected_foo; - gint expected_bar; -} forward_base[] = { - { "String 1", 1 }, - { "String 2", 2 }, - { "String 3", 3 }, - { "String 4", 4 }, - { "String 5", 5 }, - { "String 6", 6 }, - { "String 7", 7 }, - { "String 8", 8 }, - { "String 9", 9 }, -}; - -static const struct { - const gchar *expected_foo; - gint expected_bar; -} backward_base[] = { - { "String 9", 9 }, - { "String 8", 8 }, - { "String 7", 7 }, - { "String 6", 6 }, - { "String 5", 5 }, - { "String 4", 4 }, - { "String 3", 3 }, - { "String 2", 2 }, - { "String 1", 1 }, -}; - -static const struct { - const gchar *expected_foo; - gint expected_bar; -} filter_odd[] = { - { "String 1", 1 }, - { "String 3", 3 }, - { "String 5", 5 }, - { "String 7", 7 }, - { "String 9", 9 }, -}; - -static const struct { - const gchar *expected_foo; - gint expected_bar; -} filter_even[] = { - { "String 8", 8 }, - { "String 6", 6 }, - { "String 4", 4 }, - { "String 2", 2 }, -}; - -static inline void -compare_iter (ClutterModelIter *iter, - const gint expected_row, - const gchar *expected_foo, - const gint expected_bar) -{ - gchar *foo = NULL; - gint bar = 0; - gint row = 0; - - row = clutter_model_iter_get_row (iter); - clutter_model_iter_get (iter, - COLUMN_FOO, &foo, - COLUMN_BAR, &bar, - -1); - - if (g_test_verbose ()) - g_print ("Row %d => %d: Got [ '%s', '%d' ], expected [ '%s', '%d' ]\n", - row, expected_row, - foo, bar, - expected_foo, expected_bar); - - g_assert_cmpint (row, ==, expected_row); - g_assert_cmpstr (foo, ==, expected_foo); - g_assert_cmpint (bar, ==, expected_bar); - - free (foo); -} - -static void -on_row_added (ClutterModel *model, - ClutterModelIter *iter, - gpointer data) -{ - ModelData *model_data = data; - - compare_iter (iter, - model_data->n_row, - base_model[model_data->n_row].expected_foo, - base_model[model_data->n_row].expected_bar); - - model_data->n_row += 1; -} - -static gboolean -filter_even_rows (ClutterModel *model, - ClutterModelIter *iter, - gpointer dummy G_GNUC_UNUSED) -{ - gint bar_value; - - clutter_model_iter_get (iter, COLUMN_BAR, &bar_value, -1); - - if (bar_value % 2 == 0) - return TRUE; - - return FALSE; -} - -static gboolean -filter_odd_rows (ClutterModel *model, - ClutterModelIter *iter, - gpointer dummy G_GNUC_UNUSED) -{ - gint bar_value; - - clutter_model_iter_get (iter, COLUMN_BAR, &bar_value, -1); - - if (bar_value % 2 != 0) - return TRUE; - - return FALSE; -} - -static void -list_model_filter (void) -{ - ModelData test_data = { NULL, 0 }; - ClutterModelIter *iter; - gint i; - - test_data.model = clutter_list_model_new (N_COLUMNS, - G_TYPE_STRING, "Foo", - G_TYPE_INT, "Bar"); - test_data.n_row = 0; - - for (i = 1; i < 10; i++) - { - gchar *foo = g_strdup_printf ("String %d", i); - - clutter_model_append (test_data.model, - COLUMN_FOO, foo, - COLUMN_BAR, i, - -1); - - free (foo); - } - - if (g_test_verbose ()) - g_print ("Forward iteration (filter odd)...\n"); - - clutter_model_set_filter (test_data.model, filter_odd_rows, NULL, NULL); - - iter = clutter_model_get_first_iter (test_data.model); - g_assert (iter != NULL); - - i = 0; - while (!clutter_model_iter_is_last (iter)) - { - compare_iter (iter, i, - filter_odd[i].expected_foo, - filter_odd[i].expected_bar); - - iter = clutter_model_iter_next (iter); - i += 1; - } - - g_object_unref (iter); - - if (g_test_verbose ()) - g_print ("Backward iteration (filter even)...\n"); - - clutter_model_set_filter (test_data.model, filter_even_rows, NULL, NULL); - - iter = clutter_model_get_last_iter (test_data.model); - g_assert (iter != NULL); - - i = 0; - do - { - compare_iter (iter, G_N_ELEMENTS (filter_even) - i - 1, - filter_even[i].expected_foo, - filter_even[i].expected_bar); - - iter = clutter_model_iter_prev (iter); - i += 1; - } - while (!clutter_model_iter_is_first (iter)); - - g_object_unref (iter); - - if (g_test_verbose ()) - g_print ("get_iter_at_row...\n"); - - clutter_model_set_filter (test_data.model, filter_odd_rows, NULL, NULL); - - for (i = 0; i < 5; i++) - { - iter = clutter_model_get_iter_at_row (test_data.model, i); - compare_iter (iter, i , - filter_odd[i].expected_foo, - filter_odd[i].expected_bar); - g_object_unref (iter); - } - - iter = clutter_model_get_iter_at_row (test_data.model, 5); - g_assert (iter == NULL); - - g_object_unref (test_data.model); -} - -static void -list_model_iterate (void) -{ - ModelData test_data = { NULL, 0 }; - ClutterModelIter *iter; - gint i; - - test_data.model = clutter_list_model_new (N_COLUMNS, - G_TYPE_STRING, "Foo", - G_TYPE_INT, "Bar"); - test_data.n_row = 0; - - g_signal_connect (test_data.model, "row-added", - G_CALLBACK (on_row_added), - &test_data); - - for (i = 1; i < 10; i++) - { - gchar *foo = g_strdup_printf ("String %d", i); - - clutter_model_append (test_data.model, - COLUMN_FOO, foo, - COLUMN_BAR, i, - -1); - - free (foo); - } - - if (g_test_verbose ()) - g_print ("Forward iteration...\n"); - - iter = clutter_model_get_first_iter (test_data.model); - g_assert (iter != NULL); - - i = 0; - while (!clutter_model_iter_is_last (iter)) - { - compare_iter (iter, i, - forward_base[i].expected_foo, - forward_base[i].expected_bar); - - iter = clutter_model_iter_next (iter); - i += 1; - } - - g_object_unref (iter); - - if (g_test_verbose ()) - g_print ("Backward iteration...\n"); - - iter = clutter_model_get_last_iter (test_data.model); - g_assert (iter != NULL); - - i = 0; - do - { - compare_iter (iter, G_N_ELEMENTS (backward_base) - i - 1, - backward_base[i].expected_foo, - backward_base[i].expected_bar); - - iter = clutter_model_iter_prev (iter); - i += 1; - } - while (!clutter_model_iter_is_first (iter)); - - compare_iter (iter, G_N_ELEMENTS (backward_base) - i - 1, - backward_base[i].expected_foo, - backward_base[i].expected_bar); - - g_object_unref (iter); - - g_object_unref (test_data.model); -} - -static void -list_model_populate (void) -{ - ModelData test_data = { NULL, 0 }; - gint i; - - test_data.model = clutter_list_model_new (N_COLUMNS, - G_TYPE_STRING, "Foo", - G_TYPE_INT, "Bar"); - test_data.n_row = 0; - - g_signal_connect (test_data.model, "row-added", - G_CALLBACK (on_row_added), - &test_data); - - for (i = 1; i < 10; i++) - { - gchar *foo = g_strdup_printf ("String %d", i); - - clutter_model_append (test_data.model, - COLUMN_FOO, foo, - COLUMN_BAR, i, - -1); - - free (foo); - } - - g_object_unref (test_data.model); -} - -static void -list_model_from_script (void) -{ - ClutterScript *script = clutter_script_new (); - GObject *model; - GError *error = NULL; - gchar *test_file; - const gchar *name; - GType type; - ClutterModelIter *iter; - GValue value = { 0, }; - - test_file = g_test_build_filename (G_TEST_DIST, "scripts", "test-script-model.json", NULL); - clutter_script_load_from_file (script, test_file, &error); - if (g_test_verbose () && error) - g_print ("Error: %s", error->message); - - g_assert_no_error (error); - - model = clutter_script_get_object (script, "test-model"); - - g_assert (CLUTTER_IS_MODEL (model)); - g_assert (clutter_model_get_n_columns (CLUTTER_MODEL (model)) == 3); - - name = clutter_model_get_column_name (CLUTTER_MODEL (model), 0); - type = clutter_model_get_column_type (CLUTTER_MODEL (model), 0); - - if (g_test_verbose ()) - g_print ("column[0]: %s, type: %s\n", name, g_type_name (type)); - - g_assert (strcmp (name, "text-column") == 0); - g_assert (type == G_TYPE_STRING); - - name = clutter_model_get_column_name (CLUTTER_MODEL (model), 2); - type = clutter_model_get_column_type (CLUTTER_MODEL (model), 2); - - if (g_test_verbose ()) - g_print ("column[2]: %s, type: %s\n", name, g_type_name (type)); - - g_assert (strcmp (name, "actor-column") == 0); - g_assert (g_type_is_a (type, CLUTTER_TYPE_ACTOR)); - - g_assert (clutter_model_get_n_rows (CLUTTER_MODEL (model)) == 3); - - iter = clutter_model_get_iter_at_row (CLUTTER_MODEL (model), 0); - clutter_model_iter_get_value (iter, 0, &value); - g_assert (G_VALUE_HOLDS_STRING (&value)); - g_assert (strcmp (g_value_get_string (&value), "text-row-1") == 0); - g_value_unset (&value); - - clutter_model_iter_get_value (iter, 1, &value); - g_assert (G_VALUE_HOLDS_INT (&value)); - g_assert (g_value_get_int (&value) == 1); - g_value_unset (&value); - - clutter_model_iter_get_value (iter, 2, &value); - g_assert (G_VALUE_HOLDS_OBJECT (&value)); - g_assert (g_value_get_object (&value) == NULL); - g_value_unset (&value); - - iter = clutter_model_iter_next (iter); - clutter_model_iter_get_value (iter, 2, &value); - g_assert (G_VALUE_HOLDS_OBJECT (&value)); - g_assert (CLUTTER_IS_ACTOR (g_value_get_object (&value))); - g_value_unset (&value); - - iter = clutter_model_iter_next (iter); - clutter_model_iter_get_value (iter, 2, &value); - g_assert (G_VALUE_HOLDS_OBJECT (&value)); - g_assert (CLUTTER_IS_ACTOR (g_value_get_object (&value))); - g_assert (strcmp (clutter_actor_get_name (g_value_get_object (&value)), - "actor-row-3") == 0); - g_value_unset (&value); - g_object_unref (iter); -} - -static void -on_row_changed (ClutterModel *model, - ClutterModelIter *iter, - ChangedData *data) -{ - gint value = -1; - - clutter_model_iter_get (iter, COLUMN_BAR, &value, -1); - - if (g_test_verbose ()) - g_print ("row-changed value-check: %d, expected: %d\n", - value, data->value_check); - - g_assert_cmpint (value, ==, data->value_check); - - data->n_emissions += 1; -} - -static void -list_model_row_changed (void) -{ - ChangedData test_data = { NULL, NULL, 0, 0 }; - GValue value = { 0, }; - gint i; - - test_data.model = clutter_list_model_new (N_COLUMNS, - G_TYPE_STRING, "Foo", - G_TYPE_INT, "Bar"); - for (i = 1; i < 10; i++) - { - gchar *foo = g_strdup_printf ("String %d", i); - - clutter_model_append (test_data.model, - COLUMN_FOO, foo, - COLUMN_BAR, i, - -1); - - free (foo); - } - - g_signal_connect (test_data.model, "row-changed", - G_CALLBACK (on_row_changed), - &test_data); - - test_data.row = g_random_int_range (0, 9); - test_data.iter = clutter_model_get_iter_at_row (test_data.model, - test_data.row); - g_assert (CLUTTER_IS_MODEL_ITER (test_data.iter)); - - test_data.value_check = 47; - - g_value_init (&value, G_TYPE_INT); - g_value_set_int (&value, test_data.value_check); - - clutter_model_iter_set_value (test_data.iter, COLUMN_BAR, &value); - - g_value_unset (&value); - - if (g_test_verbose ()) - g_print ("iter.set_value() emissions: %d, expected: 1\n", - test_data.n_emissions); - - g_assert_cmpint (test_data.n_emissions, ==, 1); - - test_data.n_emissions = 0; - test_data.value_check = 42; - - clutter_model_iter_set (test_data.iter, - COLUMN_FOO, "changed", - COLUMN_BAR, test_data.value_check, - -1); - - if (g_test_verbose ()) - g_print ("iter.set() emissions: %d, expected: 1\n", - test_data.n_emissions); - - g_assert_cmpint (test_data.n_emissions, ==, 1); - - g_object_unref (test_data.iter); - g_object_unref (test_data.model); -} - -CLUTTER_TEST_SUITE ( - CLUTTER_TEST_UNIT ("/list-model/populate", list_model_populate) - CLUTTER_TEST_UNIT ("/list-model/iterate", list_model_iterate) - CLUTTER_TEST_UNIT ("/list-model/filter", list_model_filter) - CLUTTER_TEST_UNIT ("/list-model/row-changed", list_model_row_changed) - CLUTTER_TEST_UNIT ("/list-model/from-script", list_model_from_script) -) diff --git a/clutter/tests/conform/score.c b/clutter/tests/conform/score.c deleted file mode 100644 index 2454c57d8..000000000 --- a/clutter/tests/conform/score.c +++ /dev/null @@ -1,121 +0,0 @@ -#include -#include -#include - -#include "test-conform-common.h" - -static guint level = 0; - -static void -on_score_started (ClutterScore *score) -{ - if (g_test_verbose ()) - g_print ("Score started\n"); -} - -static void -on_score_completed (ClutterScore *score) -{ - if (g_test_verbose ()) - g_print ("Score completed\n"); -} - -static void -on_timeline_started (ClutterScore *score, - ClutterTimeline *timeline) -{ - if (g_test_verbose ()) - g_print ("Started timeline: '%s'\n", - (gchar *) g_object_get_data (G_OBJECT (timeline), "timeline-name")); - - level += 1; -} - -static void -on_timeline_completed (ClutterScore *score, - ClutterTimeline *timeline) -{ - if (g_test_verbose ()) - g_print ("Completed timeline: '%s'\n", - (gchar *) g_object_get_data (G_OBJECT (timeline), "timeline-name")); - - level -= 1; -} - -void -score_base (TestConformSimpleFixture *fixture, - gconstpointer data) -{ - ClutterScore *score; - ClutterTimeline *timeline_1; - ClutterTimeline *timeline_2; - ClutterTimeline *timeline_3; - ClutterTimeline *timeline_4; - ClutterTimeline *timeline_5; - GSList *timelines; - - /* FIXME - this is necessary to make the master clock spin */ - ClutterActor *stage = clutter_stage_new (); - - timeline_1 = clutter_timeline_new (100); - g_object_set_data_full (G_OBJECT (timeline_1), - "timeline-name", g_strdup ("Timeline 1"), - free); - - timeline_2 = clutter_timeline_new (100); - clutter_timeline_add_marker_at_time (timeline_2, "foo", 50); - g_object_set_data_full (G_OBJECT (timeline_2), - "timeline-name", g_strdup ("Timeline 2"), - free); - - timeline_3 = clutter_timeline_new (100); - g_object_set_data_full (G_OBJECT (timeline_3), - "timeline-name", g_strdup ("Timeline 3"), - free); - - timeline_4 = clutter_timeline_new (100); - g_object_set_data_full (G_OBJECT (timeline_4), - "timeline-name", g_strdup ("Timeline 4"), - free); - - timeline_5 = clutter_timeline_new (100); - g_object_set_data_full (G_OBJECT (timeline_5), - "timeline-name", g_strdup ("Timeline 5"), - free); - - score = clutter_score_new(); - g_signal_connect (score, "started", - G_CALLBACK (on_score_started), - NULL); - g_signal_connect (score, "timeline-started", - G_CALLBACK (on_timeline_started), - NULL); - g_signal_connect (score, "timeline-completed", - G_CALLBACK (on_timeline_completed), - NULL); - g_signal_connect (score, "completed", - G_CALLBACK (on_score_completed), - NULL); - - clutter_score_append (score, NULL, timeline_1); - clutter_score_append (score, timeline_1, timeline_2); - clutter_score_append (score, timeline_1, timeline_3); - clutter_score_append (score, timeline_3, timeline_4); - - clutter_score_append_at_marker (score, timeline_2, "foo", timeline_5); - - timelines = clutter_score_list_timelines (score); - g_assert (5 == g_slist_length (timelines)); - g_slist_free (timelines); - - clutter_score_start (score); - - clutter_actor_destroy (stage); - - g_object_unref (timeline_1); - g_object_unref (timeline_2); - g_object_unref (timeline_3); - g_object_unref (timeline_4); - g_object_unref (timeline_5); - g_object_unref (score); -} diff --git a/clutter/tests/conform/scripts/test-script-implicit-alpha.json b/clutter/tests/conform/scripts/test-script-implicit-alpha.json deleted file mode 100644 index 5aab70d3d..000000000 --- a/clutter/tests/conform/scripts/test-script-implicit-alpha.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "id" : "test", - "type" : "ClutterBehaviourOpacity", - "alpha" : { - "mode" : "easeOutCirc", - "timeline" : { "duration" : 500 } - } -} diff --git a/clutter/tests/conform/texture.c b/clutter/tests/conform/texture.c deleted file mode 100644 index 2fb127fe7..000000000 --- a/clutter/tests/conform/texture.c +++ /dev/null @@ -1,84 +0,0 @@ -#define CLUTTER_DISABLE_DEPRECATION_WARNINGS -#include -#include - -static CoglHandle -make_texture (void) -{ - guint32 *data = malloc (100 * 100 * 4); - int x; - int y; - - for (y = 0; y < 100; y ++) - for (x = 0; x < 100; x++) - { - if (x < 50 && y < 50) - data[y * 100 + x] = 0xff00ff00; - else - data[y * 100 + x] = 0xff00ffff; - } - return cogl_texture_new_from_data (100, - 100, - COGL_TEXTURE_NONE, - COGL_PIXEL_FORMAT_ARGB_8888, - COGL_PIXEL_FORMAT_ARGB_8888, - 400, - (guchar *)data); -} - -static void -texture_pick_with_alpha (void) -{ - ClutterTexture *tex = CLUTTER_TEXTURE (clutter_texture_new ()); - ClutterStage *stage = CLUTTER_STAGE (clutter_test_get_stage ()); - ClutterActor *actor; - - clutter_texture_set_cogl_texture (tex, make_texture ()); - - clutter_actor_add_child (CLUTTER_ACTOR (stage), CLUTTER_ACTOR (tex)); - - clutter_actor_show (CLUTTER_ACTOR (stage)); - - if (g_test_verbose ()) - { - g_print ("\nstage = %p\n", stage); - g_print ("texture = %p\n\n", tex); - } - - clutter_texture_set_pick_with_alpha (tex, TRUE); - if (g_test_verbose ()) - g_print ("Testing with pick-with-alpha enabled:\n"); - - /* This should fall through and hit the stage: */ - actor = clutter_stage_get_actor_at_pos (stage, CLUTTER_PICK_ALL, 10, 10); - if (g_test_verbose ()) - g_print ("actor @ (10, 10) = %p\n", actor); - g_assert (actor == CLUTTER_ACTOR (stage)); - - /* The rest should hit the texture */ - actor = clutter_stage_get_actor_at_pos (stage, CLUTTER_PICK_ALL, 90, 10); - if (g_test_verbose ()) - g_print ("actor @ (90, 10) = %p\n", actor); - g_assert (actor == CLUTTER_ACTOR (tex)); - actor = clutter_stage_get_actor_at_pos (stage, CLUTTER_PICK_ALL, 90, 90); - if (g_test_verbose ()) - g_print ("actor @ (90, 90) = %p\n", actor); - g_assert (actor == CLUTTER_ACTOR (tex)); - actor = clutter_stage_get_actor_at_pos (stage, CLUTTER_PICK_ALL, 10, 90); - if (g_test_verbose ()) - g_print ("actor @ (10, 90) = %p\n", actor); - g_assert (actor == CLUTTER_ACTOR (tex)); - - clutter_texture_set_pick_with_alpha (tex, FALSE); - if (g_test_verbose ()) - g_print ("Testing with pick-with-alpha disabled:\n"); - - actor = clutter_stage_get_actor_at_pos (stage, CLUTTER_PICK_ALL, 10, 10); - if (g_test_verbose ()) - g_print ("actor @ (10, 10) = %p\n", actor); - g_assert (actor == CLUTTER_ACTOR (tex)); -} - -CLUTTER_TEST_SUITE ( - CLUTTER_TEST_UNIT ("/texture/pick-with-alpha", texture_pick_with_alpha) -) diff --git a/clutter/tests/interactive/Makefile.am b/clutter/tests/interactive/Makefile.am deleted file mode 100644 index 9c051a48f..000000000 --- a/clutter/tests/interactive/Makefile.am +++ /dev/null @@ -1,148 +0,0 @@ -UNIT_TESTS = \ - test-texture-slicing.c \ - test-texture-async.c \ - test-texture-material.c \ - test-events.c \ - test-scale.c \ - test-actors.c \ - test-shader-effects.c \ - test-script.c \ - test-grab.c \ - test-cogl-shader-arbfp.c \ - test-cogl-shader-glsl.c \ - test-animator.c \ - test-state.c \ - test-state-animator.c \ - test-fbo.c \ - test-multistage.c \ - test-cogl-tex-tile.c \ - test-cogl-tex-convert.c \ - test-cogl-tex-foreign.c \ - test-cogl-offscreen.c \ - test-cogl-tex-polygon.c \ - test-cogl-multitexture.c \ - test-stage-read-pixels.c \ - test-paint-wrapper.c \ - test-texture-quality.c \ - test-layout.c \ - test-animation.c \ - test-easing.c \ - test-binding-pool.c \ - test-text.c \ - test-text-field.c \ - test-cairo-clock.c \ - test-cairo-flowers.c \ - test-cogl-vertex-buffer.c \ - test-stage-sizing.c \ - test-scrolling.c \ - test-swipe-action.c \ - test-cogl-point-sprites.c \ - test-table-layout.c \ - test-path-constraint.c \ - test-state-script.c \ - test-devices.c \ - test-content.c \ - test-keyframe-transition.c \ - test-bind-constraint.c \ - test-touch-events.c \ - test-rotate-zoom.c - -if X11_TESTS -UNIT_TESTS += test-pixmap.c -endif - -if PIXBUF_TESTS -UNIT_TESTS += \ - test-image.c -endif - -SHEXT = $(EXEEXT) - -# For convenience, this provides a way to easily run individual unit tests: -wrappers: stamp-test-interactive - @true - -GIT_IGNORE_EXTRA = \ - stamp-test-interactive \ - stamp-test-unit-names \ - test-unit-names.h \ - $(UNIT_TESTS:.c=$(SHEXT)) - -stamp-test-interactive: Makefile - @wrapper=$(abs_builddir)/wrapper.sh ; \ - chmod +x $$wrapper && \ - for i in $(UNIT_TESTS); \ - do \ - test_bin=$${i%*.c} ; \ - echo " GEN $$test_bin" ; \ - ( echo "#!/bin/sh" ; \ - echo "$$wrapper $$test_bin \$$@" \ - ) > $$test_bin$(SHEXT) ; \ - chmod +x $$test_bin$(SHEXT) ; \ - done \ - && echo timestamp > $(@F) - -test-unit-names.h: stamp-test-unit-names - @true - -stamp-test-unit-names: Makefile - @( echo "/* ** This file is autogenerated. Do not edit. ** */" ; \ - echo "" ; \ - echo "const char *test_unit_names[] = {" ) > test-unit-names.h ; \ - for i in $(UNIT_TESTS); \ - do \ - test_bin=$${i%*.c} ; \ - echo " \"$$test_bin\"," >> test-unit-names.h ; \ - done \ - && echo "};" >> test-unit-names.h \ - && echo timestamp > $(@F) - -clean-wrappers: - @for i in $(UNIT_TESTS); \ - do \ - test_bin=$${i%*.c} ; \ - echo " RM $$test_bin"; \ - rm -f $$test_bin$(SHEXT); \ - done \ - && rm -f stamp-test-unit-names \ - && rm -f stamp-test-interactive - -.PHONY: wrappers clean-wrappers - -common_ldadd = \ - $(top_builddir)/clutter/libmuffin-clutter-@MUFFIN_PLUGIN_API_VERSION@.la \ - $(top_builddir)/../cogl/cogl/libmuffin-cogl-@MUFFIN_PLUGIN_API_VERSION@.la - -check_PROGRAMS = test-interactive -check_SCRIPTS = wrappers - -test_interactive_SOURCES = test-main.c $(UNIT_TESTS) -nodist_test_interactive_SOURCES = test-unit-names.h -test_interactive_CFLAGS = $(CLUTTER_CFLAGS) $(GDK_PIXBUF_CFLAGS) -test_interactive_CPPFLAGS = \ - -DTESTS_DATADIR=\""$(abs_srcdir)"\" \ - -DG_DISABLE_SINGLE_INCLUDES \ - -DGLIB_DISABLE_DEPRECATION_WARNINGS \ - -DCOGL_DISABLE_DEPRECATION_WARNINGS \ - -DCLUTTER_DISABLE_DEPRECATION_WARNINGS \ - -I$(top_srcdir)/../cogl \ - -I$(top_builddir)/../cogl \ - -I$(top_builddir)/../cogl/cogl \ - -I$(top_srcdir) \ - -I$(top_builddir) \ - -I$(top_srcdir)/clutter \ - -I$(top_builddir)/clutter -test_interactive_LDFLAGS = -export-dynamic -test_interactive_LDADD = $(CLUTTER_LIBS) $(GDK_PIXBUF_LIBS) $(common_ldadd) $(LIBM) - -EXTRA_DIST = \ - wrapper.sh.in \ - test-script.json \ - test-script-signals.json \ - redhand.png - -DISTCLEANFILES = wrapper.sh .gitignore test-unit-names.h - -BUILT_SOURCES = test-unit-names.h - -clean-local: clean-wrappers diff --git a/clutter/tests/interactive/redhand.png b/clutter/tests/interactive/redhand.png deleted file mode 100644 index c07d8acd33d54996512f6e2b6ca4d17b5ffc4f20..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8250 zcmZ`;Wmr_v)*gE3p#+8+Lb^c&q=pb2x^?Iv#L#Gna z;9~}DGo8|sclaT%M4lM0sJI~^@yle1Nun*Qtas*mx9*&F^7#69TJZ3qQ-xoJo%DX| znaMt;`2V;vDHOLbxeD%3@fWQ(yl9B0{<|x|zEzBir7;y0eIx5!CM!yB=ABC^n0Zqi zULG=FeZ+x^fuZI}U%)~*L0t=1xN;I9lps7>s{tfzeLxhvh7rStBEoj>Xy*5;3&sCx z4C0EZ2}Qzg*pggWz|2@mv*DQiw{83&9ld&Dk*Q5sh^U0i+KJ$MwOg)&9U3ckTWL-! zXP$!k4!uMjM3D|cAY;jf4?$~{rG;QEuO2dZzisK(*sR7Cn5MHmV(flByu^`IbMGv; zTjwp9{^Z`Q&xp2;Sj{%~!fWmZ!zPn6SoFex&gX6qSE0uYcg?1d2*FjLyT9C`I2})u z>!QHLpuxr0fH&8KO(}L!Q8zv<%e?)KfVl5@&G{s4l8)qLcwIf^+|7cy^BVWMztY3d zB`K?*fL|c-f$?4&uWCZX))U9MaGk4Rb?(AO7mYhtx-_HS+~mrKD7E^e#&W9|9}d(> zeP~OvNM8^;O3IZq{AG;GLlhAv#G0eA*#d$()=-BawhU46&!nza-E9-W@$n#h{V4D)ibK`(ZFg>gnw`Nn*^ zuoX2v5ygJ~tPVBLNC{I_O{BYe3%kWAW(9dp0=8@rFtBeB)(tJ9`h zUp^=y;l6W5wV-1A0p=`FM9s~`N;FTy2%GBtg%Ck^m&1)7e#*yhvB-|k<_rcZKSHyEn2l z2na;dnMP8;oXDj*z})umle9{f2;S+dRk8KgVG()1y29)wyo;TEgeE6fSKsXCEJrYX zjd?ogk~aq1t@$?UFvik!t$JtVn#OI(1=m2_g8Xb2Bu#IYu>?cmCO9}442uC2V{UCY zkevs^-j7|E$1e_xrF;-aPrl^k#$OCQK8THN_?czdZ(M`(UMc&tKqm!QA@>Gt3QrUD?r?em>(C;rw6K{*ceA41RYA`F9AMIlP8sFo1Q#Gi)rWmXo zL87$Q;AAk>o2Nv0ve5S2alR1^5uP41sOdv^GMxQYn#@(IB?8dXtPP5@6fEFUD@Nn) z`;*PM9|IH~MUV-VWen$b7(AZ}zR?!*1j+sV@TgxiQS4CXBZ(cmT6`FN2i{pxUu8Di?SJMK@?*1P81RJZ%*8=SOX|B2s)2Zf`IpBw5R zkAD>nK8?Gdww>f1x1b6}Tpm$dWUsD2dlhBOue1n{S@szc;<3c{U zN??MjcHF0I=tq43%kyUP!WPMl@vv?0{<|YpE;PG15gZgLvl(DD#b0t))Eipse(f6_ zY;l1Oo*oZTdg5m?zqm6nkeiyS1fY-UT+77j((J6*R8o=>A9co9cLF$`!6n(Xn>gN0(nM=}@Sa$119Orcg|TqJ{3UvkA3=5>DyxyAgsOnw@Pyc*`HqUKdV= zVM||E!|R9JEQOiSht5f#T*p=;EgK~Sw)&N;^B{^RI;vJLbB1^-s)|EOYR34tEgd9c zbVMIe&3xh4tBPo^Kl$sE>R>!&ekI3;jJ%U_s@EPp$D8UydOFh*J}ZsRRBbgldu!R~ zVDIjTjNI1_!+rbkw;+P5l%S5O)yR?V$u>ut4kQi5N`e`-{Ub9I7K08Vlmk~CyF@bs za9Ig6g*PGHaaIVrs8Bp$!~d+1q4WAL|N8jCaaNYy9o(r0_04#D)w<1iN%}U)81uaj zU?2b40e=0L*Z#FK()S-t@>jutv6fV7Ak0lFVZPz5W@+E4dN3*X7h}7z@Vbni6Y2&^ z7k7fR2y(~d4o*-RX!H>O{5nA{KhSw2P~fY}y?up}Qe+$t7!4QqC+f0-kQBvc{Qtm~ z|Fs$VuS+C=X?e)EyFzs>|MFLP5A7Qr|vfCX#V^e)YAAkCiF<0=5*=t3f{>>`>xJ5HC zJi?WYVk*rHVVr^p(mAC}xG2;nMVP57`$ zNg;3$HU=ub@VPG+&ZGBoK9Ydnj~W?8hJTS7|GkmBv8ps~`X%y;$577ayNiRUo zi34M(cpZ{cJ~9M^&BmU4`SmS$dxEfCNNDupB2wppz36CDtHRnAzF%;#e|R`cwlezO zlZu#%su-cFa9P!nEBX-U(biVL?*TY?)pI9*HXDYLI)RwP(!a}=30$5mfA6v&0uK=r zr(q7oWwsuL_5AomY^F^Xb^f>ablqByUiR;(^@>m=MTos9c>5RL%7{#KszUg5CZ!*1 zjGYk;OJA%)kJm_!j4TrXD4h*_&p#lYNEkyo#b_25#ytBW^}(n57k)do!2{Ibw|l1W-(&uV^*vi0yFNk~xyD#RQqv8V|4rd6*cneWJQL|uZA}Q81?JGdubpjg|>Ed==$Yb zr1Af0@ZpjCa>*Xq`oyoM2{}&-%x2C~$9*h7E6f}ZnQb@J*w`O-=Gmyq+#b`ckC>IF z&(tL}IV25|B*x=0R%Z;n{RZ>JjxFLKH>gyMc)VE6^H_oJ{OHqA#@N;2w`QUP8f^FT zbLEkIwtA>U;`#Re$DNh87XlrM>+1tjxE?k*hxRk%ZFhHmqD+Dzb*qyY+Z*9cm&arx zP6od;tVp!oFDlp>`Ao9U8(j`!<2Kq}wQ5jed#B4VKs7Z@GaqY?iEv5bY9}oO1*y!} zzf07jo)H)Djs&^dlA49q=5OgGk~magkKb>j@{f{ zUuIJ~J&DCNlewee3nyCXi+>CAeRh9V)gD#-jd87wqv2PB30t`lMivPJuz8&c$mgq= za+d;<(4MrbpHUNKIfp0feeS6=J*;fl3kK!xm*^1BPFWd7hRvZhp-7P?BgH)UO`1iQ z2yYD9nU+k*mEI(lrqhg9*{^06$Y10c1LD#4%^Zwyxy|0_9Ac7F8soCA^xVe-{({JZwA9CMNRc9h6LWB9nP7ib+9n>Fhzc8&vk}#r~rG?YOS5 zgOsirL+P(y+CFEz+x!+!&3wg(Qc?uR$3tj|)VEXu1D0n>sRAUuL)@HsG2fh_3>8re zAD!8t#FBw0WN{=61h%3_G(Gaj;=fFOR|g8Mv(|RyCGf-cK+gF_;uH>z`OCx)vQ9}E zbYECmMlBCspkkpo9hGK#;k0mOYg9+UHTLmNDMUhb}m2B(CM zS0X1iHb3q3^2mH7B>K(jZ~+tzvzV&1KmX2Sf7#CpsW+LJn+ci~rMx)^b)I57py{za zf{)&vPE8ob%$iv9o1heKubAJ=2$%IA;?-(JmDY=9zL%m^W_%5PczssF*y^vW#2k}V zQj-oV9g}Ucki}l~LYMY&Ew)m35J6G90_`C+g?)uK6V}$t>*+$`A`ax{S_YXY-^mhVNik6TLV{zNV> zf&d7Xkf&jVPEf2O1j65a&cPVk&yab(PwJu-zgl;?MQvU^;=C2ZY}JWL>AFzrKUVQH z#=U8MQG+RT+S6`p&)wnBGPy8++J!?X34hb>hn)J;@Z8_8m6bX>oD3O5rwJoru=Sh> zO1?Vl`=Ir5Q-^Z~o6@rGnSrDX*YEleKE|MQp2)TySkU3&0T^G~b#!8Ct?S487wkz2 z-UjMVacetnbjE};NTEGekT)JR$r?AQZQfkl$4B&~-JXW!a%R4bmcMb>*o=JaSp90O z6#;*ZN-5ysf&(0tWa?#M-&51O6W!nQ=8qp^pX?5p@lKfW%2P_C-G7%=y(q2n>(}5> z(=a$841Q5%KHsZDXTGxHZum!wa$+m~eCRRBoWqY7Unfp?sCY(ZQ+R>7AcPTT?BNz&om{7<(8IyejeLYbH5r|z@pnX`c9vs

>E{@fRQy3@FN~J}p2Nt@97Uf0{oU|re+3NWF8_n@k&H~DCY}MkY^70m_tQ9( zpI)+pugQ9}0C$Vc(}5rlMPw$`wN42wf?G#7CE8<@z!lpyf^hgE(FF!%Z@ z&7z=RMR_0w&ph{%N6)m67jx?&i{6;e~N(ZJx53FKH?b4n|0*4(>n7YSDE}g1jH6}UBS)c8g_pXLG&_-(Am!}=AHQfLCxxF%1u6-ehk_5-_}0|eRNSS zpn64#*Df=d_ZR-XgJK4TYgd}Gof9v&R3L$Gv)t5T*6Rqu=02Atn!W{NTG|fD7ola4 z%PTpK-vG{&JA#(&l4XXc91(tYGu(w_bWzm_0ZGo-p zE+UhO^`}Xix%-u72M$Z-DQ6;i{}hnHV}5GMBz{Q}hew|I>ruZeO>lIr@*KnQ)zlO_ zq~Aa!JaX5QA6u?aF~*^)+T}mn43@W?{V*|Is! zS+N=N+g*CL_7|=!RnUORDevw^*Xqvz=eSB5kZX3pGphmz#y4zFVAcs zTdiq)pjQ-{fhL{*@F>)-%;3Ovs&b3*={sYKWVyw@*kYOBPlJ6!*wn{Xh!Rrfbpnuf zMjDX!yZe6y4bYKwX9YnI=LH(MfB-D+y%Z>@XYl=Mv6$LIaUO|d$wb#l(|QW6c7#JH zWhXheqtjo_4J`FOSf!%~h4A^HZ|^ktOg%qWmj~yvht;@Oxmr`lh82 zTQG!!NGogP%#aClLH1cy8~ZDtaP26-82g=`@Cp%n;Vj!BwxXxeG2(A z3V8xRdQJYR%vE6Ss{lDxRv7#B>V;+Q`mM3tujW57m&cd(skB$M!ujeMg?}XI-!Bus zz-G3lV`fX!xsoavSNB1t+lBqs`4s)?+NJDF!p!(H37{?_^cu#pd9$Hz5L|7VRLFGw zbzQEJ#w;;nAX_tNXt&?gFin@9BMVj4AM@XXYQ!)S2fk|N5uHkd90@q7SndsE|JKn{ zJUEa`)0C-souRb&cxm}(;=?GWF&{k|Zfzl}A_pGC2#MS8a0|q=?TZ(3V-$YC zTg@Guq}!?wWaQIU=w|P5MUiJDQMU$`kKjMJg_Xb8K?MZZ%1yZj4<`XC<`Hz|oz~`j zWVS`gbnC%_pzUYiMf3LOAr)) zSAMqMp{da(TFL}U7yZ|1Qv8MrFOh=>kFTZs zT=PT4j{(CiXK@0lr5=@+~ZslHXq>#4caPBItw@a2&oZ`sjx-vTcG+WM_NiTwXYFIfvKMHug zD3kaqTi0BA)YJjj(1 zAO+4n00#z%Krj1K@&96A&}63kPXD*MBFtP*8)(GU0Z~fwR>TYy+?8d3MnZ+fz9I6H5Y{aq!~(yLZ}w=8TmAr&I*(*Kq=bPnhSi zusnhtx#xS`NF~+5TU!ud)_Ty8TIvw>T$ey4oTH?~_^jmddYdq}HFtkVEbcc`4U_-#lZFa-+IAI1Z2|KJeQmhP$HT zy-1YeGa`jQKx)ZY1fW!ez+yz5?p!;G!5XaeYd=aHycF90TAN3s#sDbt^{u0 zF*a*$&zqu8E5~z3v;5xjE*1}>e|UYKxBEwXJiq8z(c2fi^vB-Y{0mLzxp7KUATKl9 zKn}iV(%>mc$mi^X(u|ryTz$KdTy8$%iLI^TW_OI!=H_f%EKRRccdg|ye#I~2LTl2G&U$$lO9 zi>afv$I)I&I)@nlt(&(f@^2e;kXh?@AO3GFr|z7{`F!>&kP(PyxW%hU^o&fNw>>FS z+>(&1zzm-`3q-S9?6RzdLj@uSGe5|(@a^YyM8YyTP(<)wZ8K^99bQHt+!r5cJjHq8 zce1Xm_iU&hkbf#g*c!io7UZbnkI;smuHr9=B+_w`b%|XPCw%6_#L_1P_pa>UO+kCF zVpflgl)>-WW>h_F2elCUtf&~Q1F4JBw6Z>Wo^sDMvre64onZNX8c>y&z6ZWFmj7Zv z4uv?pr`f^`BL+*5T<(eZg*?tTCcQNg5Fwbkc0Oz6rwCVpC=w!!`Slib*R>!R!QMAw zk67_C8m9I#TvSu68Juqer~II2N*aol@-LA8 E2il-`3jhEB diff --git a/clutter/tests/interactive/test-animator.c b/clutter/tests/interactive/test-animator.c deleted file mode 100644 index 607668a5e..000000000 --- a/clutter/tests/interactive/test-animator.c +++ /dev/null @@ -1,138 +0,0 @@ -#include -#include -#include -#include - -static ClutterAnimator *animator; - -static ClutterActor *new_rect (gint r, - gint g, - gint b, - gint a) -{ - GError *error = NULL; - ClutterColor *color = clutter_color_new (r, g, b, a); - ClutterActor *rectangle; - - gchar *file = g_build_filename (TESTS_DATADIR, "redhand.png", NULL); - rectangle = clutter_texture_new_from_file (file, &error); - if (rectangle == NULL) - g_error ("image load failed: %s", error->message); - free (file); - - clutter_actor_set_size (rectangle, 128, 128); - clutter_color_free (color); - return rectangle; -} - -static gboolean nuke_one (gpointer actor) -{ - clutter_actor_destroy (actor); - return FALSE; -} - -#define COUNT 4 - -static void reverse_timeline (ClutterTimeline *timeline, - gpointer data) -{ - ClutterTimelineDirection direction = clutter_timeline_get_direction (timeline); - if (direction == CLUTTER_TIMELINE_FORWARD) - clutter_timeline_set_direction (timeline, CLUTTER_TIMELINE_BACKWARD); - else - clutter_timeline_set_direction (timeline, CLUTTER_TIMELINE_FORWARD); - clutter_timeline_start (timeline); -} - - -G_MODULE_EXPORT gint -test_animator_main (gint argc, - gchar **argv) -{ - ClutterActor *stage; - ClutterActor *rects[COUNT]; - gint i; - if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) - return 1; - - stage = clutter_stage_new (); - clutter_stage_set_title (CLUTTER_STAGE (stage), "Animator"); - g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); - - for (i = 0; i < COUNT; i++) - { - rects[i] = new_rect (255 * (i * 1.0 / COUNT), 50, 160, 255); - clutter_container_add_actor (CLUTTER_CONTAINER (stage), rects[i]); - clutter_actor_set_anchor_point (rects[i], 64, 64); - clutter_actor_set_position (rects[i], 320.0, 240.0); - clutter_actor_set_opacity (rects[i], 0x70); - } - - clutter_threads_add_timeout (10000, nuke_one, rects[2]); - - animator = clutter_animator_new (); - - /* Note: when both animations are active for the same actor at the same - * time there is a race, such races should be handled by avoiding - * controlling the same properties from multiple animations. This is - * an intentional design flaw of this test for testing the corner case. - */ - - clutter_animator_set (animator, - rects[0], "x", 1, 0.0, 180.0, - rects[0], "x", CLUTTER_LINEAR, 0.25, 450.0, - rects[0], "x", CLUTTER_LINEAR, 0.5, 450.0, - rects[0], "x", CLUTTER_LINEAR, 0.75, 180.0, - rects[0], "x", CLUTTER_LINEAR, 1.0, 180.0, - - rects[0], "y", -1, 0.0, 100.0, - rects[0], "y", CLUTTER_LINEAR, 0.25, 100.0, - rects[0], "y", CLUTTER_LINEAR, 0.5, 380.0, - rects[0], "y", CLUTTER_LINEAR, 0.75, 380.0, - rects[0], "y", CLUTTER_LINEAR, 1.0, 100.0, - - rects[3], "x", 0, 0.0, 180.0, - rects[3], "x", CLUTTER_LINEAR, 0.25, 180.0, - rects[3], "x", CLUTTER_LINEAR, 0.5, 450.0, - rects[3], "x", CLUTTER_LINEAR, 0.75, 450.0, - rects[3], "x", CLUTTER_LINEAR, 1.0, 180.0, - - rects[3], "y", 0, 0.0, 100.0, - rects[3], "y", CLUTTER_LINEAR, 0.25, 380.0, - rects[3], "y", CLUTTER_LINEAR, 0.5, 380.0, - rects[3], "y", CLUTTER_LINEAR, 0.75, 100.0, - rects[3], "y", CLUTTER_LINEAR, 1.0, 100.0, - - - rects[2], "rotation-angle-y", 0, 0.0, 0.0, - rects[2], "rotation-angle-y", CLUTTER_LINEAR, 1.0, 360.0, - - rects[1], "scale-x", 0, 0.0, 1.0, - rects[1], "scale-x", CLUTTER_LINEAR, 1.0, 2.0, - rects[1], "scale-y", 0, 0.0, 1.0, - rects[1], "scale-y", CLUTTER_LINEAR, 1.0, 2.0, - NULL); - - - clutter_actor_set_scale (rects[0], 1.4, 1.4); - clutter_animator_property_set_ease_in (animator, G_OBJECT (rects[0]), "x", - TRUE); - clutter_animator_property_set_ease_in (animator, G_OBJECT (rects[0]), "y", - TRUE); - clutter_animator_property_set_interpolation (animator, G_OBJECT (rects[0]), - "x", CLUTTER_INTERPOLATION_CUBIC); - clutter_animator_property_set_interpolation (animator, G_OBJECT (rects[0]), - "y", CLUTTER_INTERPOLATION_CUBIC); - - clutter_stage_hide_cursor(CLUTTER_STAGE (stage)); - clutter_actor_show (stage); - clutter_animator_set_duration (animator, 5000); - - g_signal_connect (clutter_animator_start (animator), - "completed", G_CALLBACK (reverse_timeline), NULL); - clutter_main (); - - g_object_unref (animator); - - return EXIT_SUCCESS; -} diff --git a/clutter/tests/interactive/test-cogl-shader-arbfp.c b/clutter/tests/interactive/test-cogl-shader-arbfp.c deleted file mode 100644 index 5daca6845..000000000 --- a/clutter/tests/interactive/test-cogl-shader-arbfp.c +++ /dev/null @@ -1,407 +0,0 @@ -#include - -#include -#include -#include -#include - -typedef struct -{ - char *name; - char *source; -} ShaderSource; - -static ShaderSource shaders[]= - { - /*{"brightness-contrast", - FRAGMENT_SHADER_VARS - "uniform float brightness, contrast;" - FRAGMENT_SHADER_BEGIN - " color.rgb = (color.rgb - vec3(0.5, 0.5, 0.5)) * contrast + " - "vec3 (brightness + 0.5, brightness + 0.5, brightness + 0.5);" - FRAGMENT_SHADER_END - },*/ - {"brightness-contrast", - "!!ARBfp1.0\n" - "PARAM bc = program.local[0];" - "TEMP color;" - "TEMP color2;" - "TEX color.rgba, fragment.texcoord[0], texture[0], 2D;" - "SUB color.rgb, color, 0.5;" - "MUL color2, color, bc.w;" - "ADD color.rgb, color2, bc.z;" - "MOV result.color, color;" - "END" - }, - - /*{"box-blur", - FRAGMENT_SHADER_VARS - - "vec4 get_rgba_rel(sampler2D tex, float dx, float dy)" - "{" - " return texture2D (tex, " TEX_COORD ".st " - " + vec2(dx, dy) * 2.0);" - "}" - - FRAGMENT_SHADER_BEGIN - " float count = 1.0;" - " color += get_rgba_rel (tex, -x_step, -y_step); count++;" - " color += get_rgba_rel (tex, -x_step, 0.0); count++;" - " color += get_rgba_rel (tex, -x_step, y_step); count++;" - " color += get_rgba_rel (tex, 0.0, -y_step); count++;" - " color += get_rgba_rel (tex, 0.0, 0.0); count++;" - " color += get_rgba_rel (tex, 0.0, y_step); count++;" - " color += get_rgba_rel (tex, x_step, -y_step); count++;" - " color += get_rgba_rel (tex, x_step, 0.0); count++;" - " color += get_rgba_rel (tex, x_step, y_step); count++;" - " color = color / count;" - FRAGMENT_SHADER_END - },*/ - {"box-blur", - "!!ARBfp1.0\n" - "PARAM params = program.local[0];" - "TEMP accum;" - "TEMP color;" - "TEMP coord;" - "TEMP step;" - - "MUL step, params, 2.0;" - - "SUB coord, fragment.texcoord[0], step;" - "TEX color.rgba, coord, texture[0], 2D;" - "MOV accum, color;" - - "MOV coord, fragment.texcoord[0];" - "SUB coord.x, coord.x, step.x;" - "TEX color.rgba, coord, texture[0], 2D;" - "ADD accum, accum, color;" - - "MOV coord, fragment.texcoord[0];" - "SUB coord.x, coord.x, step.x;" - "ADD coord.y, coord.y, step.y;" - "TEX color.rgba, coord, texture[0], 2D;" - "ADD accum, accum, color;" - - "MOV coord, fragment.texcoord[0];" - "SUB coord.y, coord.y, step.y;" - "TEX color.rgba, coord, texture[0], 2D;" - "ADD accum, accum, color;" - - "MOV coord, fragment.texcoord[0];" - "TEX color.rgba, coord, texture[0], 2D;" - "ADD accum, accum, color;" - - "MOV coord, fragment.texcoord[0];" - "ADD coord.y, coord.y, step.y;" - "TEX color.rgba, coord, texture[0], 2D;" - "ADD accum, accum, color;" - - "MOV coord, fragment.texcoord[0];" - "ADD coord.x, coord.x, step.x;" - "SUB coord.y, coord.y, step.y;" - "TEX color.rgba, coord, texture[0], 2D;" - "ADD accum, accum, color;" - - "MOV coord, fragment.texcoord[0];" - "ADD coord.x, coord.x, step.x;" - "TEX color.rgba, coord, texture[0], 2D;" - "ADD accum, accum, color;" - - "MOV coord, fragment.texcoord[0];" - "ADD coord.x, coord.x, step.x;" - "ADD coord.y, coord.y, step.y;" - "TEX color.rgba, coord, texture[0], 2D;" - "ADD accum, accum, color;" - - "MUL color, accum, 0.11111111;" - "MOV result.color, color;" - "END" - }, - - /*{"invert", - FRAGMENT_SHADER_VARS - FRAGMENT_SHADER_BEGIN - " color.rgb = vec3(1.0, 1.0, 1.0) - color.rgb;\n" - FRAGMENT_SHADER_END - },*/ - {"invert", - "!!ARBfp1.0\n" - "TEMP color;" - "TEX color.rgba, fragment.texcoord[0], texture[0], 2D;" - "ADD color.rgb, 1.0, -color;" - "MOV result.color, color;" - "END" - }, - - /*{"gray", - FRAGMENT_SHADER_VARS - FRAGMENT_SHADER_BEGIN - " float avg = (color.r + color.g + color.b) / 3.0;" - " color.r = avg;" - " color.g = avg;" - " color.b = avg;" - FRAGMENT_SHADER_END - },*/ - {"gray", - "!!ARBfp1.0\n" - "TEMP color;" - "TEMP grey;" - "TEX color.rgba, fragment.texcoord[0], texture[0], 2D;" - "ADD grey, color.r, color.g;" - "ADD grey, grey, color.b;" - "MUL grey, grey, 0.33333333;" - "MOV color.rgb, grey;" - "MOV result.color, color;" - "END" - }, - -/* {"combined-mirror", - FRAGMENT_SHADER_VARS - FRAGMENT_SHADER_BEGIN - " vec4 colorB = texture2D (tex, vec2(" TEX_COORD ".ts));" - " float avg = (color.r + color.g + color.b) / 3.0;" - " color.r = avg;" - " color.g = avg;" - " color.b = avg;" - " color = (color + colorB)/2.0;" - FRAGMENT_SHADER_END - },*/ - {"combined-mirror", - "!!ARBfp1.0\n" - "TEMP color1;" - "TEMP color2;" - "TEMP coord;" - "MOV coord.x, fragment.texcoord[0].y;" - "MOV coord.y, fragment.texcoord[0].x;" - "TEX color1.rgba, fragment.texcoord[0], texture[0], 2D;" - "TEX color2.rgba, coord, texture[0], 2D;" - "MUL color1, color1, 0.5;" - "MUL color2, color2, 0.5;" - "ADD result.color, color1, color2;" - "END" - }, - -/* {"edge-detect", - FRAGMENT_SHADER_VARS - "float get_avg_rel(sampler2D texB, float dx, float dy)" - "{" - " vec4 colorB = texture2D (texB, " TEX_COORD ".st + vec2(dx, dy));" - " return (colorB.r + colorB.g + colorB.b) / 3.0;" - "}" - FRAGMENT_SHADER_BEGIN - " mat3 sobel_h = mat3( 1.0, 2.0, 1.0," - " 0.0, 0.0, 0.0," - " -1.0, -2.0, -1.0);" - " mat3 sobel_v = mat3( 1.0, 0.0, -1.0," - " 2.0, 0.0, -2.0," - " 1.0, 0.0, -1.0);" - " mat3 map = mat3( get_avg_rel(tex, -x_step, -y_step)," - " get_avg_rel(tex, -x_step, 0.0)," - " get_avg_rel(tex, -x_step, y_step)," - " get_avg_rel(tex, 0.0, -y_step)," - " get_avg_rel(tex, 0.0, 0.0)," - " get_avg_rel(tex, 0.0, y_step)," - " get_avg_rel(tex, x_step, -y_step)," - " get_avg_rel(tex, x_step, 0.0)," - " get_avg_rel(tex, x_step, y_step) );" - " mat3 gh = sobel_h * map;" - " mat3 gv = map * sobel_v;" - " float avgh = (gh[0][0] + gh[0][1] + gh[0][2] +" - " gh[1][0] + gh[1][1] + gh[1][2] +" - " gh[2][0] + gh[2][1] + gh[2][2]) / 18.0 + 0.5;" - " float avgv = (gv[0][0] + gv[0][1] + gv[0][2] +" - " gv[1][0] + gv[1][1] + gv[1][2] +" - " gv[2][0] + gv[2][1] + gv[2][2]) / 18.0 + 0.5;" - " float avg = (avgh + avgv) / 2.0;" - " color.r = avg * color.r;" - " color.g = avg * color.g;" - " color.b = avg * color.b;" - FRAGMENT_SHADER_END - },*/ - - /* Don't really fancy doing this one in assembly :) */ -}; - -static CoglHandle redhand; -static CoglMaterial *material; -static unsigned int timeout_id = 0; -static int shader_no = 0; - -static void -paint_cb (ClutterActor *actor) -{ - int stage_width = clutter_actor_get_width (actor); - int stage_height = clutter_actor_get_height (actor); - int image_width = cogl_texture_get_width (redhand); - int image_height = cogl_texture_get_height (redhand); - - cogl_set_source (material); - cogl_rectangle (stage_width/2.0f - image_width/2.0f, - stage_height/2.0f - image_height/2.0f, - stage_width/2.0f + image_width/2.0f, - stage_height/2.0f + image_height/2.0f); -} - -static void -set_shader_num (int new_no) -{ - CoglHandle shader; - CoglHandle program; - int image_width = cogl_texture_get_width (redhand); - int image_height = cogl_texture_get_height (redhand); - float param0[4]; - int uniform_no; - - g_print ("setting shaders[%i] named '%s'\n", - new_no, - shaders[new_no].name); - - shader = cogl_create_shader (COGL_SHADER_TYPE_FRAGMENT); - cogl_shader_source (shader, shaders[new_no].source); - cogl_shader_compile (shader); - - program = cogl_create_program (); - cogl_program_attach_shader (program, shader); - cogl_handle_unref (shader); - cogl_program_link (program); - - param0[0] = 1.0f/image_width; /* texel x step delta */ - param0[1] = 1.0f/image_height; /* texel y step delta */ - param0[2] = 0.4; /* brightness */ - param0[3] = -1.9; /* contrast */ - - uniform_no = cogl_program_get_uniform_location (program, "program.local[0]"); - cogl_program_set_uniform_float (program, uniform_no, 4, 1, param0); - - cogl_material_set_user_program (material, program); - cogl_handle_unref (program); - - shader_no = new_no; -} - -static gboolean -button_release_cb (ClutterActor *actor, - ClutterEvent *event, - void *data) -{ - int new_no; - - /* Stop the automatic cycling if the user want to manually control - * which shader to display */ - if (timeout_id) - { - g_source_remove (timeout_id); - timeout_id = 0; - } - - if (event->button.button == 1) - { - new_no = shader_no - 1; - if (new_no < 0) - new_no = G_N_ELEMENTS (shaders) - 1; - } - else - { - new_no = shader_no + 1; - if (new_no >= G_N_ELEMENTS (shaders)) - new_no = 0; - } - - set_shader_num (new_no); - - return CLUTTER_EVENT_STOP; -} - -static gboolean -key_release_cb (ClutterActor *actor, - ClutterEvent *event, - gpointer user_data) -{ - guint keysym = clutter_event_get_key_symbol (event); - ClutterModifierType mods = clutter_event_get_state (event); - - if (keysym == CLUTTER_KEY_q || - ((mods & CLUTTER_SHIFT_MASK) && keysym == CLUTTER_KEY_q)) - clutter_main_quit (); - - return CLUTTER_EVENT_STOP; -} - -static gboolean -timeout_cb (gpointer user_data) -{ - shader_no++; - if (shader_no > (G_N_ELEMENTS (shaders) - 1)) - shader_no = 0; - - set_shader_num (shader_no); - - return G_SOURCE_CONTINUE; -} - -static gboolean -idle_cb (gpointer data) -{ - clutter_actor_queue_redraw (data); - - return G_SOURCE_CONTINUE; -} - -static gboolean -destroy_window_cb (ClutterStage *stage, - ClutterEvent *event, - void *user_data) -{ - clutter_main_quit (); - return TRUE; -} - -G_MODULE_EXPORT int -test_cogl_shader_arbfp_main (int argc, char *argv[]) -{ - ClutterActor *stage; - char *file; - GError *error; - ClutterColor stage_color = { 0x61, 0x64, 0x8c, 0xff }; - - if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) - return 1; - - stage = clutter_stage_new (); - - clutter_stage_set_title (CLUTTER_STAGE (stage), "Assembly Shader Test"); - clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color); - - file = g_build_filename (TESTS_DATADIR, "redhand.png", NULL); - error = NULL; - redhand = cogl_texture_new_from_file (file, 0, COGL_PIXEL_FORMAT_ANY, - &error); - if (redhand == COGL_INVALID_HANDLE) - g_error ("image load failed: %s", error->message); - - material = cogl_material_new (); - cogl_material_set_layer (material, 0, redhand); - - set_shader_num (0); - g_signal_connect_after (stage, "paint", G_CALLBACK (paint_cb), NULL); - - clutter_actor_set_reactive (stage, TRUE); - g_signal_connect (stage, "button-release-event", - G_CALLBACK (button_release_cb), NULL); - g_signal_connect (stage, "key-release-event", - G_CALLBACK (key_release_cb), NULL); - - g_signal_connect (stage, "delete-event", - G_CALLBACK (destroy_window_cb), NULL); - - timeout_id = clutter_threads_add_timeout (1000, timeout_cb, NULL); - - clutter_threads_add_idle (idle_cb, stage); - - clutter_actor_show (stage); - - clutter_main (); - - return EXIT_SUCCESS; -} - diff --git a/clutter/tests/interactive/test-cogl-tex-foreign.c b/clutter/tests/interactive/test-cogl-tex-foreign.c deleted file mode 100644 index b499abbbe..000000000 --- a/clutter/tests/interactive/test-cogl-tex-foreign.c +++ /dev/null @@ -1,272 +0,0 @@ -#include -#include -#include -#include -#include - -#ifndef GL_UNPACK_ALIGNMENT -#define GL_UNPACK_ALIGNMENT 0x0CF5 -#endif -#ifndef GL_TEXTURE_BINDING_2D -#define GL_TEXTURE_BINDING_2D 0x8069 -#endif -#ifndef GL_TEXTURE_2D -#define GL_TEXTURE_2D 0x0DE1 -#endif -#ifndef GL_RGB -#define GL_RGB 0x1907 -#endif -#ifndef GL_UNSIGNED_BYTE -#define GL_UNSIGNED_BYTE 0x1401 -#endif -#ifndef GL_TEXTURE_MAG_FILTER -#define GL_TEXTURE_MAG_FILTER 0x2800 -#endif -#ifndef GL_LINEAR -#define GL_LINEAR 0x1208 -#endif -#ifndef GL_TEXTURE_MIN_FILTER -#define GL_TEXTURE_MIN_FILTER 0x2801 -#endif - -/* Coglbox declaration - *--------------------------------------------------*/ - -G_BEGIN_DECLS - -#define TEST_TYPE_COGLBOX test_coglbox_get_type() - -#define TEST_COGLBOX(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ - TEST_TYPE_COGLBOX, TestCoglboxClass)) - -#define TEST_COGLBOX_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), \ - TEST_TYPE_COGLBOX, TestCoglboxClass)) - -#define TEST_IS_COGLBOX(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ - TEST_TYPE_COGLBOX)) - -#define TEST_IS_COGLBOX_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), \ - TEST_TYPE_COGLBOX)) - -#define TEST_COGLBOX_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), \ - TEST_TYPE_COGLBOX, TestCoglboxClass)) - -typedef struct _TestCoglbox TestCoglbox; -typedef struct _TestCoglboxClass TestCoglboxClass; -typedef struct _TestCoglboxPrivate TestCoglboxPrivate; - -struct _TestCoglbox -{ - ClutterActor parent; - - /*< private >*/ - TestCoglboxPrivate *priv; -}; - -struct _TestCoglboxClass -{ - ClutterActorClass parent_class; - - /* padding for future expansion */ - void (*_test_coglbox1) (void); - void (*_test_coglbox2) (void); - void (*_test_coglbox3) (void); - void (*_test_coglbox4) (void); -}; - -static GType test_coglbox_get_type (void) G_GNUC_CONST; - -G_END_DECLS - -/* Coglbox private declaration - *--------------------------------------------------*/ - -G_DEFINE_TYPE (TestCoglbox, test_coglbox, CLUTTER_TYPE_ACTOR); - -#define TEST_COGLBOX_GET_PRIVATE(obj) \ -(G_TYPE_INSTANCE_GET_PRIVATE ((obj), TEST_TYPE_COGLBOX, TestCoglboxPrivate)) - -struct _TestCoglboxPrivate -{ - guint gl_handle; - CoglHandle cogl_handle; - - void - (* glGetIntegerv) (guint pname, int *params); - void - (* glPixelStorei) (guint pname, int param); - void - (* glTexParameteri) (guint target, guint pname, int param); - void - (* glTexImage2D) (guint target, int level, - int internalFormat, - int width, int height, - int border, guint format, guint type, - const void *pixels); - void - (* glGenTextures) (int n, guint *textures); - void - (* glDeleteTextures) (int n, const guint *textures); - void - (* glBindTexture) (guint target, guint texture); -}; - -/* Coglbox implementation - *--------------------------------------------------*/ - -static void -test_coglbox_paint(ClutterActor *self) -{ - TestCoglboxPrivate *priv = TEST_COGLBOX_GET_PRIVATE (self); - gfloat texcoords[4] = { 0.3f, 0.3f, 0.7f, 0.7f }; - - cogl_set_source_color4ub (0x66, 0x66, 0xdd, 0xff); - cogl_rectangle (0,0,400,400); - - cogl_push_matrix (); - - cogl_translate (100,100,0); - cogl_set_source_texture (priv->cogl_handle); - cogl_rectangle_with_texture_coords (0, 0, 200, 200, - texcoords[0], texcoords[1], - texcoords[2], texcoords[3]); - - cogl_pop_matrix(); -} - -static void -test_coglbox_finalize (GObject *object) -{ - G_OBJECT_CLASS (test_coglbox_parent_class)->finalize (object); -} - -static void -test_coglbox_dispose (GObject *object) -{ - TestCoglboxPrivate *priv; - - priv = TEST_COGLBOX_GET_PRIVATE (object); - - cogl_handle_unref (priv->cogl_handle); - priv->glDeleteTextures (1, &priv->gl_handle); - - G_OBJECT_CLASS (test_coglbox_parent_class)->dispose (object); -} - -static void -test_coglbox_init (TestCoglbox *self) -{ - TestCoglboxPrivate *priv; - guchar data[12]; - int prev_unpack_alignment; - int prev_2d_texture_binding; - - self->priv = priv = TEST_COGLBOX_GET_PRIVATE(self); - - /* Prepare a 2x2 pixels texture */ - - data[0] = 255; data[1] = 0; data[2] = 0; - data[3] = 0; data[4] = 255; data[5] = 0; - data[6] = 0; data[7] = 0; data[8] = 255; - data[9] = 0; data[10] = 0; data[11] = 0; - - priv->glGetIntegerv = (void *) cogl_get_proc_address ("glGetIntegerv"); - priv->glPixelStorei = (void *) cogl_get_proc_address ("glPixelStorei"); - priv->glTexParameteri = (void *) cogl_get_proc_address ("glTexParameteri"); - priv->glTexImage2D = (void *) cogl_get_proc_address ("glTexImage2D"); - priv->glGenTextures = (void *) cogl_get_proc_address ("glGenTextures"); - priv->glDeleteTextures = (void *) cogl_get_proc_address ("glDeleteTextures"); - priv->glBindTexture = (void *) cogl_get_proc_address ("glBindTexture"); - - /* We are about to use OpenGL directly to create a TEXTURE_2D - * texture so we need to save the state that we modify so we can - * restore it afterwards and be sure not to interfere with any state - * caching that Cogl may do internally. - */ - priv->glGetIntegerv (GL_UNPACK_ALIGNMENT, &prev_unpack_alignment); - priv->glGetIntegerv (GL_TEXTURE_BINDING_2D, &prev_2d_texture_binding); - - priv->glGenTextures (1, &priv->gl_handle); - priv->glBindTexture (GL_TEXTURE_2D, priv->gl_handle); - - priv->glPixelStorei (GL_UNPACK_ALIGNMENT, 1); - priv->glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, - 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, data); - - /* Now restore the original GL state as Cogl had left it */ - priv->glPixelStorei (GL_UNPACK_ALIGNMENT, prev_unpack_alignment); - priv->glBindTexture (GL_TEXTURE_2D, prev_2d_texture_binding); - - priv->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - priv->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - - /* Create texture from foreign */ - - priv->cogl_handle = - cogl_texture_new_from_foreign (priv->gl_handle, - GL_TEXTURE_2D, - 2, 2, 0, 0, - COGL_PIXEL_FORMAT_RGB_888); - - if (priv->cogl_handle == COGL_INVALID_HANDLE) - { - printf ("Failed creating texture from foreign!\n"); - return; - } -} - -static void -test_coglbox_class_init (TestCoglboxClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); - - gobject_class->finalize = test_coglbox_finalize; - gobject_class->dispose = test_coglbox_dispose; - actor_class->paint = test_coglbox_paint; - - g_type_class_add_private (gobject_class, sizeof (TestCoglboxPrivate)); -} - -static ClutterActor* -test_coglbox_new (void) -{ - return g_object_new (TEST_TYPE_COGLBOX, NULL); -} - -G_MODULE_EXPORT int -test_cogl_tex_foreign_main (int argc, char *argv[]) -{ - ClutterActor *stage; - ClutterActor *coglbox; - - if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) - return 1; - - /* Stage */ - stage = clutter_stage_new (); - clutter_actor_set_size (stage, 400, 400); - clutter_stage_set_title (CLUTTER_STAGE (stage), "Cogl Foreign Textures"); - g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); - - /* Cogl Box */ - coglbox = test_coglbox_new (); - clutter_container_add_actor (CLUTTER_CONTAINER (stage), coglbox); - - clutter_actor_show_all (stage); - - clutter_main (); - - return 0; -} - -G_MODULE_EXPORT const char * -test_cogl_tex_foreign_describe (void) -{ - return "Foreign textures support in Cogl."; -} diff --git a/clutter/tests/interactive/test-cogl-vertex-buffer.c b/clutter/tests/interactive/test-cogl-vertex-buffer.c deleted file mode 100644 index d9bd0a4f5..000000000 --- a/clutter/tests/interactive/test-cogl-vertex-buffer.c +++ /dev/null @@ -1,390 +0,0 @@ -#include -#include -#include -#include -#include -#include - -/* Defines the size and resolution of the quad mesh we morph: - */ -#define MESH_WIDTH 100.0 /* number of quads along x axis */ -#define MESH_HEIGHT 100.0 /* number of quads along y axis */ -#define QUAD_WIDTH 5.0 /* width in pixels of a single quad */ -#define QUAD_HEIGHT 5.0 /* height in pixels of a single quad */ - -/* Defines a sine wave that sweeps across the mesh: - */ -#define WAVE_DEPTH ((MESH_WIDTH * QUAD_WIDTH) / 16.0) /* peak amplitude */ -#define WAVE_PERIODS 4.0 -#define WAVE_SPEED 10.0 - -/* Defines a rippling sine wave emitted from a point: - */ -#define RIPPLE_CENTER_X ((MESH_WIDTH / 2.0) * QUAD_WIDTH) -#define RIPPLE_CENTER_Y ((MESH_HEIGHT / 2.0) * QUAD_HEIGHT) -#define RIPPLE_RADIUS (MESH_WIDTH * QUAD_WIDTH) -#define RIPPLE_DEPTH ((MESH_WIDTH * QUAD_WIDTH) / 16.0) /* peak amplitude */ -#define RIPPLE_PERIODS 4.0 -#define RIPPLE_SPEED -10.0 - -/* Defines the width of the gaussian bell used to fade out the alpha - * towards the edges of the mesh (starting from the ripple center): - */ -#define GAUSSIAN_RADIUS ((MESH_WIDTH * QUAD_WIDTH) / 6.0) - -/* Our hues lie in the range [0, 1], and this defines how we map amplitude - * to hues (before scaling by {WAVE,RIPPLE}_DEPTH) - * As we are interferring two sine waves together; amplitudes lie in the - * range [-2, 2] - */ -#define HSL_OFFSET 0.5 /* the hue that we map an amplitude of 0 too */ -#define HSL_SCALE 0.25 - -typedef struct _TestState -{ - ClutterActor *dummy; - CoglHandle buffer; - float *quad_mesh_verts; - guint8 *quad_mesh_colors; - guint16 *static_indices; - guint n_static_indices; - CoglHandle indices; - ClutterTimeline *timeline; - guint frame_id; -} TestState; - -static void -frame_cb (ClutterTimeline *timeline, - gint elapsed_msecs, - TestState *state) -{ - guint x, y; - float period_progress = clutter_timeline_get_progress (timeline); - float period_progress_sin = sinf (period_progress); - float wave_shift = period_progress * WAVE_SPEED; - float ripple_shift = period_progress * RIPPLE_SPEED; - - for (y = 0; y <= MESH_HEIGHT; y++) - for (x = 0; x <= MESH_WIDTH; x++) - { - guint vert_index = (MESH_WIDTH + 1) * y + x; - float *vert = &state->quad_mesh_verts[3 * vert_index]; - - float real_x = x * QUAD_WIDTH; - float real_y = y * QUAD_HEIGHT; - - float wave_offset = (float)x / (MESH_WIDTH + 1); - float wave_angle = - (WAVE_PERIODS * 2 * G_PI * wave_offset) + wave_shift; - float wave_sin = sinf (wave_angle); - - float a_sqr = (RIPPLE_CENTER_X - real_x) * (RIPPLE_CENTER_X - real_x); - float b_sqr = (RIPPLE_CENTER_Y - real_y) * (RIPPLE_CENTER_Y - real_y); - float ripple_offset = sqrtf (a_sqr + b_sqr) / RIPPLE_RADIUS; - float ripple_angle = - (RIPPLE_PERIODS * 2 * G_PI * ripple_offset) + ripple_shift; - float ripple_sin = sinf (ripple_angle); - - float h, s, l; - guint8 *color; - - vert[2] = (wave_sin * WAVE_DEPTH) + (ripple_sin * RIPPLE_DEPTH); - - /* Burn some CPU time picking a pretty color... */ - h = (HSL_OFFSET - + wave_sin - + ripple_sin - + period_progress_sin) * HSL_SCALE; - s = 0.5; - l = 0.25 + (period_progress_sin + 1.0) / 4.0; - color = &state->quad_mesh_colors[4 * vert_index]; - /* A bit of a sneaky cast, but it seems safe to assume the ClutterColor - * typedef is set in stone... */ - clutter_color_from_hls ((ClutterColor *)color, h * 360.0, l, s); - - color[0] = (color[0] * color[3] + 128) / 255; - color[1] = (color[1] * color[3] + 128) / 255; - color[2] = (color[2] * color[3] + 128) / 255; - } - - cogl_vertex_buffer_add (state->buffer, - "gl_Vertex", - 3, /* n components */ - COGL_ATTRIBUTE_TYPE_FLOAT, - FALSE, /* normalized */ - 0, /* stride */ - state->quad_mesh_verts); - cogl_vertex_buffer_add (state->buffer, - "gl_Color", - 4, /* n components */ - COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE, - FALSE, /* normalized */ - 0, /* stride */ - state->quad_mesh_colors); - - cogl_vertex_buffer_submit (state->buffer); - - clutter_actor_set_rotation (state->dummy, - CLUTTER_Z_AXIS, - 360 * period_progress, - (MESH_WIDTH * QUAD_WIDTH) / 2, - (MESH_HEIGHT * QUAD_HEIGHT) / 2, - 0); - clutter_actor_set_rotation (state->dummy, - CLUTTER_X_AXIS, - 360 * period_progress, - (MESH_WIDTH * QUAD_WIDTH) / 2, - (MESH_HEIGHT * QUAD_HEIGHT) / 2, - 0); -} - -static void -on_paint (ClutterActor *actor, TestState *state) -{ - cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff); - cogl_vertex_buffer_draw_elements (state->buffer, - COGL_VERTICES_MODE_TRIANGLE_STRIP, - state->indices, - 0, /* min index */ - (MESH_WIDTH + 1) * - (MESH_HEIGHT + 1) - 1, /* max index */ - 0, /* indices offset */ - state->n_static_indices); -} - -static void -init_static_index_arrays (TestState *state) -{ - guint n_indices; - int x, y; - guint16 *i; - guint dir; - - /* - Each row takes (2 + 2 * MESH_WIDTH indices) - * - Thats 2 to start the triangle strip then 2 indices to add 2 triangles - * per mesh quad. - * - We have MESH_HEIGHT rows - * - It takes one extra index for linking between rows (MESH_HEIGHT - 1) - * - A 2 x 3 mesh == 20 indices... */ - n_indices = (2 + 2 * MESH_WIDTH) * MESH_HEIGHT + (MESH_HEIGHT - 1); - state->static_indices = malloc (sizeof (guint16) * n_indices); - state->n_static_indices = n_indices; - -#define MESH_INDEX(X, Y) (Y) * (MESH_WIDTH + 1) + (X) - - i = state->static_indices; - - /* NB: front facing == anti-clockwise winding */ - - i[0] = MESH_INDEX (0, 0); - i[1] = MESH_INDEX (0, 1); - i += 2; - -#define LEFT 0 -#define RIGHT 1 - - dir = RIGHT; - - for (y = 0; y < MESH_HEIGHT; y++) - { - for (x = 0; x < MESH_WIDTH; x++) - { - /* Add 2 triangles per mesh quad... */ - if (dir == RIGHT) - { - i[0] = MESH_INDEX (x + 1, y); - i[1] = MESH_INDEX (x + 1, y + 1); - } - else - { - i[0] = MESH_INDEX (MESH_WIDTH - x - 1, y); - i[1] = MESH_INDEX (MESH_WIDTH - x - 1, y + 1); - } - i += 2; - } - - /* Link rows... */ - - if (y == (MESH_HEIGHT - 1)) - break; - - if (dir == RIGHT) - { - i[0] = MESH_INDEX (MESH_WIDTH, y + 1); - i[1] = MESH_INDEX (MESH_WIDTH, y + 1); - i[2] = MESH_INDEX (MESH_WIDTH, y + 2); - } - else - { - i[0] = MESH_INDEX (0, y + 1); - i[1] = MESH_INDEX (0, y + 1); - i[2] = MESH_INDEX (0, y + 2); - } - i += 3; - dir = !dir; - } - -#undef MESH_INDEX - - state->indices = - cogl_vertex_buffer_indices_new (COGL_INDICES_TYPE_UNSIGNED_SHORT, - state->static_indices, - state->n_static_indices); -} - -static float -gaussian (float x, float y) -{ - /* Bell width */ - float c = GAUSSIAN_RADIUS; - - /* Peak amplitude */ - float a = 1.0; - /* float a = 1.0 / (c * sqrtf (2.0 * G_PI)); */ - - /* Center offset */ - float b = 0.0; - - float dist; - x = x - RIPPLE_CENTER_X; - y = y - RIPPLE_CENTER_Y; - dist = sqrtf (x*x + y*y); - - return a * exp ((- ((dist - b) * (dist - b))) / (2.0 * c * c)); -} - -static void -init_quad_mesh (TestState *state) -{ - int x, y; - float *vert; - guint8 *color; - - /* Note: we maintain the minimum number of vertices possible. This minimizes - * the work required when we come to morph the geometry. - * - * We use static indices into our mesh so that we can treat the data like a - * single triangle list and drawing can be done in one operation (Note: We - * are using degenerate triangles at the edges to link to the next row) - */ - state->quad_mesh_verts = - calloc (1, sizeof (float) * 3 * (MESH_WIDTH + 1) * (MESH_HEIGHT + 1)); - - state->quad_mesh_colors = - calloc (1, sizeof (guint8) * 4 * (MESH_WIDTH + 1) * (MESH_HEIGHT + 1)); - - vert = state->quad_mesh_verts; - color = state->quad_mesh_colors; - for (y = 0; y <= MESH_HEIGHT; y++) - for (x = 0; x <= MESH_WIDTH; x++) - { - vert[0] = x * QUAD_WIDTH; - vert[1] = y * QUAD_HEIGHT; - vert += 3; - - color[3] = gaussian (x * QUAD_WIDTH, - y * QUAD_HEIGHT) * 255.0; - color += 4; - } - - state->buffer = cogl_vertex_buffer_new ((MESH_WIDTH + 1)*(MESH_HEIGHT + 1)); - cogl_vertex_buffer_add (state->buffer, - "gl_Vertex", - 3, /* n components */ - COGL_ATTRIBUTE_TYPE_FLOAT, - FALSE, /* normalized */ - 0, /* stride */ - state->quad_mesh_verts); - - cogl_vertex_buffer_add (state->buffer, - "gl_Color", - 4, /* n components */ - COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE, - FALSE, /* normalized */ - 0, /* stride */ - state->quad_mesh_colors); - - cogl_vertex_buffer_submit (state->buffer); - - init_static_index_arrays (state); -} - -/* This creates an actor that has a specific size but that does not result - * in any drawing so we can do our own drawing using Cogl... */ -static ClutterActor * -create_dummy_actor (guint width, guint height) -{ - ClutterActor *group, *rect; - ClutterColor clr = { 0xff, 0xff, 0xff, 0xff}; - - group = clutter_group_new (); - rect = clutter_rectangle_new_with_color (&clr); - clutter_actor_set_size (rect, width, height); - clutter_actor_hide (rect); - clutter_container_add_actor (CLUTTER_CONTAINER (group), rect); - return group; -} - -static void -stop_and_quit (ClutterActor *actor, - TestState *state) -{ - clutter_timeline_stop (state->timeline); - clutter_main_quit (); -} - -G_MODULE_EXPORT int -test_cogl_vertex_buffer_main (int argc, char *argv[]) -{ - TestState state; - ClutterActor *stage; - gfloat stage_w, stage_h; - gint dummy_width, dummy_height; - - if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) - return 1; - - stage = clutter_stage_new (); - - clutter_stage_set_title (CLUTTER_STAGE (stage), "Cogl Vertex Buffers"); - clutter_stage_set_color (CLUTTER_STAGE (stage), CLUTTER_COLOR_Black); - g_signal_connect (stage, "destroy", G_CALLBACK (stop_and_quit), &state); - clutter_actor_get_size (stage, &stage_w, &stage_h); - - dummy_width = MESH_WIDTH * QUAD_WIDTH; - dummy_height = MESH_HEIGHT * QUAD_HEIGHT; - state.dummy = create_dummy_actor (dummy_width, dummy_height); - clutter_container_add_actor (CLUTTER_CONTAINER (stage), state.dummy); - clutter_actor_set_position (state.dummy, - (stage_w / 2.0) - (dummy_width / 2.0), - (stage_h / 2.0) - (dummy_height / 2.0)); - - state.timeline = clutter_timeline_new (1000); - clutter_timeline_set_loop (state.timeline, TRUE); - - state.frame_id = g_signal_connect (state.timeline, - "new-frame", - G_CALLBACK (frame_cb), - &state); - - g_signal_connect (state.dummy, "paint", G_CALLBACK (on_paint), &state); - - init_quad_mesh (&state); - - clutter_actor_show_all (stage); - - clutter_timeline_start (state.timeline); - - clutter_main (); - - cogl_handle_unref (state.buffer); - cogl_handle_unref (state.indices); - - return 0; -} - -G_MODULE_EXPORT const char * -test_cogl_vertex_buffer_describe (void) -{ - return "Vertex buffers support in Cogl."; -} diff --git a/clutter/tests/interactive/test-depth.c b/clutter/tests/interactive/test-depth.c deleted file mode 100644 index ce3eeb91a..000000000 --- a/clutter/tests/interactive/test-depth.c +++ /dev/null @@ -1,211 +0,0 @@ -#include -#include -#include - -/* each time the timeline animating the label completes, swap the direction */ -static void -timeline_completed (ClutterTimeline *timeline, - gpointer user_data) -{ - clutter_timeline_set_direction (timeline, - !clutter_timeline_get_direction (timeline)); - clutter_timeline_start (timeline); -} - -static ClutterActor *raise_actor[2]; -static gboolean raise_no = 0; - -static gboolean -raise_top (gpointer ignored G_GNUC_UNUSED) -{ - ClutterActor *parent = clutter_actor_get_parent (raise_actor[raise_no]); - - clutter_actor_set_child_above_sibling (parent, raise_actor[raise_no], NULL); - raise_no = !raise_no; - - return G_SOURCE_CONTINUE; -} - -static ClutterActor * -clone_box (ClutterActor *original) -{ - gfloat width, height; - ClutterActor *group; - ClutterActor *clone; - - clutter_actor_get_size (original, &width, &height); - - group = clutter_actor_new (); - clone = clutter_clone_new (original); - clutter_actor_add_child (group, clone); - clutter_actor_set_depth (clone, width / 2); - - clone = clutter_clone_new (original); - clutter_actor_add_child (group, clone); - clutter_actor_set_rotation (clone, CLUTTER_Y_AXIS, 180, width / 2, 0, 0); - clutter_actor_set_depth (clone, -width / 2); - - clone = clutter_clone_new (original); - clutter_actor_add_child (group, clone); - clutter_actor_set_rotation (clone, CLUTTER_Y_AXIS, 90, 0, 0, 0); - clutter_actor_set_depth (clone, width / 2); - clutter_actor_set_position (clone, 0, 0); - - clone = clutter_clone_new (original); - clutter_actor_add_child (group, clone); - clutter_actor_set_rotation (clone, CLUTTER_Y_AXIS, 90, 0, 0, 0); - clutter_actor_set_depth (clone, width / 2); - clutter_actor_set_position (clone, width, 0); - - clone = clutter_clone_new (original); - clutter_actor_add_child (group, clone); - clutter_actor_set_rotation (clone, CLUTTER_X_AXIS, 90, 0, 0, 0); - clutter_actor_set_depth (clone, -width / 2); - clutter_actor_set_position (clone, 0, height); - - clone = clutter_clone_new (original); - clutter_actor_add_child (group, clone); - clutter_actor_set_rotation (clone, CLUTTER_X_AXIS, 90, 0, 0, 0); - clutter_actor_set_depth (clone, -width / 2); - clutter_actor_set_position (clone, 0, 0); - - return group; -} - -static ClutterActor * -janus_group (const gchar *front_text, - const gchar *back_text) -{ - ClutterActor *group, *rectangle, *front, *back; - gfloat width, height; - gfloat width2, height2; - - group = clutter_actor_new (); - rectangle = clutter_actor_new (); - clutter_actor_set_background_color (rectangle, CLUTTER_COLOR_White); - front = clutter_text_new_with_text ("Sans 50px", front_text); - back = clutter_text_new_with_text ("Sans 50px", back_text); - clutter_text_set_color (CLUTTER_TEXT (front), CLUTTER_COLOR_Red); - clutter_text_set_color (CLUTTER_TEXT (back), CLUTTER_COLOR_Green); - - clutter_actor_get_size (front, &width, &height); - clutter_actor_get_size (back, &width2, &height2); - - if (width2 > width) - width = width2; - - if (height2 > height) - height = height2; - - clutter_actor_set_size (rectangle, width, height); - clutter_actor_set_rotation (back, CLUTTER_Y_AXIS, 180, width / 2, 0, 0); - - clutter_actor_add_child (group, back); - clutter_actor_add_child (group, rectangle); - clutter_actor_add_child (group, front); - - return group; -} - -G_MODULE_EXPORT gint -test_depth_main (int argc, char *argv[]) -{ - ClutterTimeline *timeline; - ClutterBehaviour *d_behave; - ClutterBehaviour *r_behave; - ClutterActor *stage; - ClutterActor *group, *hand, *label, *rect, *janus, *box; - GError *error; - - if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) - return EXIT_FAILURE; - - stage = clutter_stage_new (); - clutter_stage_set_title (CLUTTER_STAGE (stage), "Depth Test"); - clutter_actor_set_background_color (stage, CLUTTER_COLOR_Aluminium2); - g_signal_connect (stage, - "destroy", G_CALLBACK (clutter_main_quit), - NULL); - g_signal_connect (stage, - "button-press-event", G_CALLBACK (clutter_main_quit), - NULL); - - group = clutter_actor_new (); - clutter_actor_add_child (stage, group); - - label = clutter_text_new_with_text ("Mono 26", "Clutter"); - clutter_actor_set_position (label, 120, 200); - clutter_actor_add_child (stage, label); - - error = NULL; - hand = clutter_texture_new_from_file (TESTS_DATADIR - G_DIR_SEPARATOR_S - "redhand.png", - &error); - if (error) - g_error ("Unable to load redhand.png: %s", error->message); - clutter_actor_set_position (hand, 240, 100); - - rect = clutter_rectangle_new_with_color (CLUTTER_COLOR_Black); - clutter_actor_set_position (rect, 340, 100); - clutter_actor_set_size (rect, 200, 200); - clutter_actor_set_opacity (rect, 128); - - clutter_actor_add_child (group, hand); - clutter_actor_add_child (group, rect); - - timeline = clutter_timeline_new (3000); - g_signal_connect (timeline, - "completed", G_CALLBACK (timeline_completed), - NULL); - - d_behave = - clutter_behaviour_depth_new (clutter_alpha_new_full (timeline, - CLUTTER_LINEAR), - -100, 100); - clutter_behaviour_apply (d_behave, label); - - /* add two faced actor */ - janus = janus_group ("GREEN", "RED"); - clutter_container_add_actor (CLUTTER_CONTAINER (stage), janus); - clutter_actor_set_position (janus, 300, 350); - - r_behave = - clutter_behaviour_rotate_new (clutter_alpha_new_full (timeline, - CLUTTER_LINEAR), - CLUTTER_Y_AXIS, - CLUTTER_ROTATE_CW, - 0, 360); - clutter_behaviour_apply (r_behave, janus); - - /* add hand box */ - box = clone_box (hand); - clutter_actor_add_child (stage, box); - clutter_actor_set_position (box, 200, 250); - clutter_actor_set_scale (box, 0.5, 0.5); - clutter_actor_set_rotation (box, CLUTTER_X_AXIS, 45, 0, 0, 0); - clutter_actor_set_opacity (box, 0x44); - - r_behave = - clutter_behaviour_rotate_new (clutter_alpha_new_full (timeline, - CLUTTER_LINEAR), - CLUTTER_Y_AXIS, - CLUTTER_ROTATE_CW, - 0, 360); - clutter_behaviour_apply (r_behave, box); - - clutter_actor_show (stage); - - clutter_timeline_start (timeline); - - raise_actor[0] = rect; - raise_actor[1] = hand; - clutter_threads_add_timeout (2000, raise_top, NULL); - - clutter_main (); - - g_object_unref (d_behave); - g_object_unref (timeline); - - return EXIT_SUCCESS; -} diff --git a/clutter/tests/interactive/test-fbo.c b/clutter/tests/interactive/test-fbo.c deleted file mode 100644 index f87534876..000000000 --- a/clutter/tests/interactive/test-fbo.c +++ /dev/null @@ -1,105 +0,0 @@ -#include - -#include -#include -#include -#include - -#define STAGE_WIDTH 800 -#define STAGE_HEIGHT 600 - -ClutterActor * -make_source (void) -{ - ClutterActor *source, *actor; - GError *error = NULL; - gchar *file; - - ClutterColor yellow = {0xff, 0xff, 0x00, 0xff}; - - source = clutter_group_new (); - - file = g_build_filename (TESTS_DATADIR, "redhand.png", NULL); - actor = clutter_texture_new_from_file (file, &error); - if (!actor) - g_error("pixbuf load failed: %s", error ? error->message : "Unknown"); - - free (file); - - clutter_container_add_actor (CLUTTER_CONTAINER (source), actor); - - actor = clutter_text_new_with_text ("Sans Bold 50px", "Clutter"); - - clutter_text_set_color (CLUTTER_TEXT (actor), &yellow); - clutter_actor_set_y (actor, clutter_actor_get_height(source) + 5); - clutter_container_add_actor (CLUTTER_CONTAINER (source), actor); - - return source; -} - -G_MODULE_EXPORT int -test_fbo_main (int argc, char *argv[]) -{ - ClutterActor *fbo; - ClutterActor *onscreen_source; - ClutterActor *stage; - ClutterAnimation *animation; - int x_pos = 200; - int y_pos = 100; - - if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) - return 1; - - if (clutter_feature_available (CLUTTER_FEATURE_OFFSCREEN) == FALSE) - g_error("This test requires CLUTTER_FEATURE_OFFSCREEN"); - - stage = clutter_stage_new (); - clutter_actor_set_size (stage, STAGE_WIDTH, STAGE_HEIGHT); - clutter_actor_set_background_color (stage, CLUTTER_COLOR_SkyBlue); - clutter_stage_set_title (CLUTTER_STAGE (stage), "Texture from Actor"); - g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); - - /* Create the first source */ - onscreen_source = make_source(); - clutter_actor_show_all (onscreen_source); - clutter_container_add_actor (CLUTTER_CONTAINER (stage), onscreen_source); - - y_pos = (STAGE_HEIGHT/2.0) - - (clutter_actor_get_height (onscreen_source)/2.0); - clutter_actor_set_position (onscreen_source, x_pos, y_pos); - x_pos += clutter_actor_get_width (onscreen_source); - - animation = clutter_actor_animate (onscreen_source, - CLUTTER_LINEAR, - 5000, /* 1 second duration */ - "rotation-angle-y", 360.0f, - NULL); - clutter_animation_set_loop (animation, TRUE); - - /* Second hand = actor from onscreen_source */ - if ((fbo = clutter_texture_new_from_actor (onscreen_source)) == NULL) - g_error("onscreen fbo creation failed"); - - clutter_actor_set_position (fbo, x_pos, y_pos); - x_pos += clutter_actor_get_width (fbo); - clutter_container_add_actor (CLUTTER_CONTAINER (stage), fbo); - - /* Third hand = actor from Second hand */ - if ((fbo = clutter_texture_new_from_actor (fbo)) == NULL) - g_error("fbo from fbo creation failed"); - - clutter_actor_set_position (fbo, x_pos, y_pos); - x_pos += clutter_actor_get_width (fbo); - clutter_container_add_actor (CLUTTER_CONTAINER (stage), fbo); - - clutter_actor_show_all (stage); - clutter_main (); - - return 0; -} - -G_MODULE_EXPORT const char * -test_fbo_describe (void) -{ - return "Create a texture from an actor."; -} diff --git a/clutter/tests/interactive/test-multistage.c b/clutter/tests/interactive/test-multistage.c deleted file mode 100644 index 5c04b5b5f..000000000 --- a/clutter/tests/interactive/test-multistage.c +++ /dev/null @@ -1,149 +0,0 @@ -#include -#include - -static GList *stages = NULL; -static gint n_stages = 1; - -static gboolean -tex_button_cb (ClutterActor *actor, - ClutterEvent *event, - gpointer data) -{ - clutter_actor_hide (actor); - - return TRUE; -} - -static void -on_destroy (ClutterActor *actor) -{ - stages = g_list_remove (stages, actor); -} - -static gboolean -on_button_press (ClutterActor *actor, - ClutterEvent *event, - gpointer data) -{ - ClutterActor *new_stage; - ClutterActor *label, *tex; - gint width, height; - gchar *stage_label, *stage_name; - ClutterTimeline *timeline; - ClutterAlpha *alpha; - ClutterBehaviour *r_behave; - - new_stage = clutter_stage_new (); - if (new_stage == NULL) - return FALSE; - - stage_name = g_strdup_printf ("Stage [%d]", ++n_stages); - - clutter_stage_set_title (CLUTTER_STAGE (new_stage), stage_name); - clutter_actor_set_background_color (new_stage, - CLUTTER_COLOR_DarkScarletRed); - clutter_actor_set_size (new_stage, 320, 240); - clutter_actor_set_name (new_stage, stage_name); - - g_signal_connect (new_stage, "destroy", G_CALLBACK (on_destroy), NULL); - - tex = clutter_texture_new_from_file (TESTS_DATADIR - G_DIR_SEPARATOR_S - "redhand.png", - NULL); - - if (!tex) - g_error ("pixbuf load failed"); - - clutter_actor_set_reactive (tex, TRUE); - g_signal_connect (tex, "button-press-event", - G_CALLBACK (tex_button_cb), NULL); - - clutter_container_add_actor (CLUTTER_CONTAINER (new_stage), tex); - - stage_label = g_strconcat ("", stage_name, "", NULL); - label = clutter_text_new_with_text ("Mono 12", stage_label); - - clutter_text_set_color (CLUTTER_TEXT (label), CLUTTER_COLOR_White); - clutter_text_set_use_markup (CLUTTER_TEXT (label), TRUE); - width = (clutter_actor_get_width (new_stage) - - clutter_actor_get_width (label)) / 2; - height = (clutter_actor_get_height (new_stage) - - clutter_actor_get_height (label)) / 2; - clutter_actor_set_position (label, width, height); - clutter_container_add_actor (CLUTTER_CONTAINER (new_stage), label); - clutter_actor_show (label); - free (stage_label); - - /* - g_signal_connect (new_stage, "button-press-event", - G_CALLBACK (clutter_actor_destroy), - NULL); - */ - - timeline = clutter_timeline_new (2000); - clutter_timeline_set_repeat_count (timeline, -1); - - alpha = clutter_alpha_new_full (timeline, CLUTTER_LINEAR); - r_behave = clutter_behaviour_rotate_new (alpha, - CLUTTER_Y_AXIS, - CLUTTER_ROTATE_CW, - 0.0, 360.0); - - clutter_behaviour_rotate_set_center (CLUTTER_BEHAVIOUR_ROTATE (r_behave), - clutter_actor_get_width (label)/2, - 0, - 0); - - clutter_behaviour_apply (r_behave, label); - clutter_timeline_start (timeline); - - clutter_actor_show_all (new_stage); - - stages = g_list_prepend (stages, new_stage); - - free (stage_name); - - return TRUE; -} - -G_MODULE_EXPORT int -test_multistage_main (int argc, char *argv[]) -{ - ClutterActor *stage_default; - ClutterActor *label; - gint width, height; - - if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) - return 1; - - stage_default = clutter_stage_new (); - clutter_stage_set_title (CLUTTER_STAGE (stage_default), "Default Stage"); - clutter_actor_set_name (stage_default, "Default Stage"); - g_signal_connect (stage_default, "destroy", - G_CALLBACK (clutter_main_quit), - NULL); - g_signal_connect (stage_default, "button-press-event", - G_CALLBACK (on_button_press), - NULL); - - label = clutter_text_new_with_text ("Mono 16", "Default stage"); - width = (clutter_actor_get_width (stage_default) - - clutter_actor_get_width (label)) - / 2; - height = (clutter_actor_get_height (stage_default) - - clutter_actor_get_height (label)) - / 2; - clutter_actor_set_position (label, width, height); - clutter_container_add_actor (CLUTTER_CONTAINER (stage_default), label); - clutter_actor_show (label); - - clutter_actor_show (stage_default); - - clutter_main (); - - g_list_foreach (stages, (GFunc) clutter_actor_destroy, NULL); - g_list_free (stages); - - return 0; -} diff --git a/clutter/tests/interactive/test-pixmap.c b/clutter/tests/interactive/test-pixmap.c deleted file mode 100644 index 759345721..000000000 --- a/clutter/tests/interactive/test-pixmap.c +++ /dev/null @@ -1,331 +0,0 @@ -#include -#include -#include - -#include - -#ifdef CAIRO_HAS_XLIB_SURFACE -#include -#endif - -#include - -#ifdef CLUTTER_WINDOWING_X11 -#include -#include - -#include -#include -#endif - -#define IMAGE TESTS_DATADIR G_DIR_SEPARATOR_S "redhand.png" - -static gboolean disable_x11 = FALSE; -static gboolean disable_animation = FALSE; - -static GOptionEntry g_options[] = -{ - { "disable-x11", - 0, 0, - G_OPTION_ARG_NONE, - &disable_x11, - "Disable redirection through X11 pixmap", - NULL }, - { "disable-animation", - 0, 0, - G_OPTION_ARG_NONE, - &disable_animation, - "Disable the animations", - NULL }, - - { NULL } -}; - -static void -toggle_texture_quality (ClutterActor *actor) -{ - if (CLUTTER_IS_CONTAINER (actor)) - clutter_container_foreach (CLUTTER_CONTAINER (actor), - (ClutterCallback) toggle_texture_quality, - NULL); - - if (CLUTTER_IS_TEXTURE (actor)) - { - ClutterTextureQuality quality; - - quality = clutter_texture_get_filter_quality (CLUTTER_TEXTURE (actor)); - - if (quality == CLUTTER_TEXTURE_QUALITY_HIGH) - quality = CLUTTER_TEXTURE_QUALITY_MEDIUM; - else - quality = CLUTTER_TEXTURE_QUALITY_HIGH; - - g_print ("switching to quality %s for %p\n", - quality == CLUTTER_TEXTURE_QUALITY_HIGH - ? "high" : "medium", - actor); - - clutter_texture_set_filter_quality (CLUTTER_TEXTURE (actor), quality); - } -} - -static gboolean -stage_key_release_cb (ClutterActor *actor, - ClutterEvent *event, - gpointer data) -{ - switch (clutter_event_get_key_symbol (event)) - { - case CLUTTER_KEY_q: - case CLUTTER_KEY_Q: - clutter_main_quit (); - break; - - case CLUTTER_KEY_m: - toggle_texture_quality (actor); - break; - } - return FALSE; -} - -static gboolean -draw_arc (gpointer data) -{ - Pixmap pixmap = GPOINTER_TO_UINT (data); - Display *dpy = clutter_x11_get_default_display (); - - static GC gc = None; - static int x = 100, y = 100; - - if (gc == None) - { - XGCValues gc_values = { 0 }; - - gc_values.line_width = 12; - /* This is an attempt to get a black pixel will full - opacity. Seemingly the BlackPixel macro and the default GC - value are a fully transparent color */ - gc_values.foreground = 0xff000000; - - gc = XCreateGC (dpy, - pixmap, - GCLineWidth | GCForeground, - &gc_values); - } - - XDrawArc (dpy, pixmap, gc, x, y, 100, 100, 0, 360 * 64); - - x -= 5; - y -= 5; - - return G_SOURCE_CONTINUE; -} - -static gboolean -stage_button_press_cb (ClutterActor *actor, - ClutterEvent *event, - gpointer data) -{ - draw_arc (data); - - return CLUTTER_EVENT_STOP; -} - -Pixmap -create_pixmap (guint *width, guint *height, guint *depth) -{ - Display *dpy = clutter_x11_get_default_display (); - cairo_surface_t *image; - Pixmap pixmap; - XVisualInfo xvisinfo; - XVisualInfo *xvisinfos; - int n; - cairo_surface_t *xlib_surface; - cairo_t *cr; - guint w, h; - - image = cairo_image_surface_create_from_png (IMAGE); - if (cairo_surface_status (image) != CAIRO_STATUS_SUCCESS) - g_error ("Failed to load %s", IMAGE); - - w = cairo_image_surface_get_width (image); - h = cairo_image_surface_get_height (image); - - pixmap = XCreatePixmap (dpy, - DefaultRootWindow (dpy), - w, h, - 32); - - xvisinfo.depth = 32; - xvisinfos = XGetVisualInfo (dpy, VisualDepthMask, &xvisinfo, &n); - if (!xvisinfos) - g_error ("Failed to find a 32bit X Visual"); - - xlib_surface = - cairo_xlib_surface_create (dpy, - pixmap, - xvisinfos->visual, - w, h); - XFree (xvisinfos); - - cr = cairo_create (xlib_surface); - cairo_set_source_surface (cr, image, 0, 0); - cairo_paint (cr); - cairo_surface_destroy (image); - - if (width) - *width = w; - if (height) - *height = h; - if (depth) - *depth = 32; - - return pixmap; -} - -/* each time the timeline animating the label completes, swap the direction */ -static void -timeline_completed (ClutterTimeline *timeline, - gpointer user_data) -{ - clutter_timeline_set_direction (timeline, - !clutter_timeline_get_direction (timeline)); - clutter_timeline_start (timeline); -} - -G_MODULE_EXPORT int -test_pixmap_main (int argc, char **argv) -{ - GOptionContext *context; - Display *xdpy; - int screen; - ClutterActor *group = NULL, *label, *stage, *tex; - Pixmap pixmap; - const ClutterColor gry = { 0x99, 0x99, 0x99, 0xFF }; - Window win_remote; - guint w, h, d; - GC gc; - ClutterTimeline *timeline; - ClutterAlpha *alpha; - ClutterBehaviour *depth_behavior; - int i; - int row_height; - -#ifdef CLUTTER_WINDOWING_X11 - clutter_set_windowing_backend (CLUTTER_WINDOWING_X11); -#endif - - if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) - return 1; - -#ifdef CLUTTER_WINDOWING_X11 - if (!clutter_check_windowing_backend (CLUTTER_WINDOWING_X11)) - g_error ("test-pixmap requires the X11 Clutter backend."); -#endif - - xdpy = clutter_x11_get_default_display (); - XSynchronize (xdpy, True); - - context = g_option_context_new (" - test-pixmap options"); - g_option_context_add_main_entries (context, g_options, NULL); - g_option_context_parse (context, &argc, &argv, NULL); - - pixmap = create_pixmap (&w, &h, &d); - - screen = DefaultScreen(xdpy); - win_remote = XCreateSimpleWindow (xdpy, DefaultRootWindow(xdpy), - 0, 0, 200, 200, - 0, - WhitePixel(xdpy, screen), - WhitePixel(xdpy, screen)); - - XMapWindow (xdpy, win_remote); - - stage = clutter_stage_new (); - clutter_actor_set_position (stage, 0, 150); - clutter_actor_set_background_color (stage, &gry); - clutter_stage_set_title (CLUTTER_STAGE (stage), "X11 Texture from Pixmap"); - g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); - - timeline = clutter_timeline_new (5000); - g_signal_connect (timeline, - "completed", G_CALLBACK (timeline_completed), - NULL); - - alpha = clutter_alpha_new_full (timeline, CLUTTER_LINEAR); - depth_behavior = clutter_behaviour_depth_new (alpha, -2500, 400); - - if (!disable_x11) - { - group = clutter_group_new (); - clutter_container_add_actor (CLUTTER_CONTAINER (stage), group); - label = clutter_text_new_with_text ("fixed", - "ClutterX11Texture (Window)"); - clutter_container_add_actor (CLUTTER_CONTAINER (group), label); - tex = clutter_x11_texture_pixmap_new_with_window (win_remote); - clutter_container_add_actor (CLUTTER_CONTAINER (group), tex); - clutter_actor_set_position (tex, 0, 20); - clutter_x11_texture_pixmap_set_automatic (CLUTTER_X11_TEXTURE_PIXMAP (tex), - TRUE); - clutter_texture_set_filter_quality (CLUTTER_TEXTURE (tex), - CLUTTER_TEXTURE_QUALITY_HIGH); - clutter_actor_set_position (group, 0, 0); - if (!disable_animation) - clutter_behaviour_apply (depth_behavior, group); - } - - if (group) - row_height = clutter_actor_get_height (group); - else - row_height = 0; - - /* NB: We only draw on the window after being redirected, so we dont - * have to worry about handling expose events... */ - gc = XCreateGC (xdpy, win_remote, 0, NULL); - XSetForeground (xdpy, gc, BlackPixel (xdpy, screen)); - XSetLineAttributes(xdpy, gc, 5, LineSolid, CapButt, JoinMiter); - - for (i = 0; i < 10; i++) - XDrawLine (xdpy, win_remote, gc, 0+i*20, 0, 10+i*20+i, 200); - - - group = clutter_group_new (); - clutter_container_add_actor (CLUTTER_CONTAINER (stage), group); - label = clutter_text_new_with_text ("fixed", "ClutterX11Texture (Pixmap)"); - clutter_container_add_actor (CLUTTER_CONTAINER (group), label); - tex = clutter_x11_texture_pixmap_new_with_pixmap (pixmap); - clutter_x11_texture_pixmap_set_automatic (CLUTTER_X11_TEXTURE_PIXMAP (tex), - TRUE); - clutter_container_add_actor (CLUTTER_CONTAINER (group), tex); - clutter_actor_set_position (tex, 0, 20); - clutter_texture_set_filter_quality (CLUTTER_TEXTURE (tex), - CLUTTER_TEXTURE_QUALITY_HIGH); - /* oddly, the actor's size is 0 until it is realized, even though - pixmap-height is set */ - clutter_actor_set_position (group, 0, row_height); - if (!disable_animation) - clutter_behaviour_apply (depth_behavior, group); - - - g_signal_connect (stage, "key-release-event", - G_CALLBACK (stage_key_release_cb), (gpointer)pixmap); - g_signal_connect (stage, "button-press-event", - G_CALLBACK (stage_button_press_cb), (gpointer)pixmap); - - clutter_actor_show (stage); - - if (!disable_animation) - clutter_timeline_start (timeline); - - clutter_threads_add_timeout (1000, draw_arc, GUINT_TO_POINTER (pixmap)); - - clutter_main (); - - return EXIT_SUCCESS; -} - -G_MODULE_EXPORT const char * -test_pixmap_describe (void) -{ - return "GLX Texture from pixmap extension support."; -} diff --git a/clutter/tests/interactive/test-scale.c b/clutter/tests/interactive/test-scale.c deleted file mode 100644 index a21f6d6d5..000000000 --- a/clutter/tests/interactive/test-scale.c +++ /dev/null @@ -1,119 +0,0 @@ -#include -#include -#include - -static const ClutterGravity gravities[] = { - CLUTTER_GRAVITY_NORTH_EAST, - CLUTTER_GRAVITY_NORTH, - CLUTTER_GRAVITY_NORTH_WEST, - CLUTTER_GRAVITY_WEST, - CLUTTER_GRAVITY_SOUTH_WEST, - CLUTTER_GRAVITY_SOUTH, - CLUTTER_GRAVITY_SOUTH_EAST, - CLUTTER_GRAVITY_EAST, - CLUTTER_GRAVITY_CENTER, - CLUTTER_GRAVITY_NONE -}; - -static gint gindex = 0; -static ClutterActor *label; - -static void -set_next_gravity (ClutterActor *actor) -{ - ClutterGravity gravity = gravities[gindex]; - GEnumClass *eclass; - GEnumValue *evalue; - - clutter_actor_move_anchor_point_from_gravity (actor, gravities[gindex]); - - eclass = g_type_class_ref (CLUTTER_TYPE_GRAVITY); - evalue = g_enum_get_value (eclass, gravity); - clutter_text_set_text (CLUTTER_TEXT (label), evalue->value_nick); - g_type_class_unref (eclass); - - if (++gindex >= G_N_ELEMENTS (gravities)) - gindex = 0; -} - -static gdouble -my_ramp_func (ClutterAlpha *alpha, - gpointer unused) -{ - ClutterTimeline *timeline = clutter_alpha_get_timeline (alpha); - - return clutter_timeline_get_progress (timeline); -} - -G_MODULE_EXPORT int -test_scale_main (int argc, char *argv[]) -{ - ClutterActor *stage, *rect; - ClutterColor rect_color = { 0xff, 0xff, 0xff, 0x99 }; - ClutterTimeline *timeline; - ClutterAlpha *alpha; - ClutterBehaviour *behave; - - if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) - return 1; - - stage = clutter_stage_new (); - clutter_stage_set_title (CLUTTER_STAGE (stage), "Scaling"); - clutter_actor_set_background_color (stage, CLUTTER_COLOR_Black); - clutter_actor_set_size (stage, 300, 300); - g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); - - rect = clutter_rectangle_new_with_color (&rect_color); - clutter_actor_set_size (rect, 100, 100); - clutter_actor_set_position (rect, 100, 100); - - clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect); - - label = clutter_text_new_with_text ("Sans 20px", ""); - clutter_text_set_color (CLUTTER_TEXT (label), CLUTTER_COLOR_White); - clutter_actor_set_position (label, - clutter_actor_get_x (rect), - clutter_actor_get_y (rect) - + clutter_actor_get_height (rect)); - - clutter_container_add_actor (CLUTTER_CONTAINER (stage), label); - - rect_color.alpha = 0xff; - rect = clutter_rectangle_new_with_color (&rect_color); - clutter_actor_set_position (rect, 100, 100); - clutter_actor_set_size (rect, 100, 100); - set_next_gravity (rect); - - clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect); - - timeline = clutter_timeline_new (750); - alpha = clutter_alpha_new_with_func (timeline, - my_ramp_func, - NULL, NULL); - - behave = clutter_behaviour_scale_new (alpha, - 0.0, 0.0, /* scale start */ - 1.0, 1.0); /* scale end */ - - clutter_behaviour_apply (behave, rect); - - clutter_timeline_set_repeat_count (timeline, -1); - g_signal_connect_swapped (timeline, "completed", - G_CALLBACK (set_next_gravity), rect); - clutter_timeline_start (timeline); - - clutter_actor_show_all (stage); - - clutter_main(); - - g_object_unref (timeline); - g_object_unref (behave); - - return EXIT_SUCCESS; -} - -G_MODULE_EXPORT const char * -test_scale_describe (void) -{ - return "Scaling animation and scaling center changes"; -} diff --git a/clutter/tests/interactive/test-stage-read-pixels.c b/clutter/tests/interactive/test-stage-read-pixels.c deleted file mode 100644 index eb064e43a..000000000 --- a/clutter/tests/interactive/test-stage-read-pixels.c +++ /dev/null @@ -1,168 +0,0 @@ -#include -#include -#include - -#define DOT_SIZE 2 -#define TEX_SIZE 64 - -typedef struct _CallbackData CallbackData; - -struct _CallbackData -{ - ClutterActor *stage; - ClutterActor *tex; - ClutterActor *box; - ClutterMotionEvent event; - guint idle_source; -}; - -static ClutterActor * -make_label (void) -{ - ClutterActor *label; - gchar *text; - gchar *argv[] = { "ls", "--help", NULL }; - - label = clutter_text_new (); - clutter_text_set_font_name (CLUTTER_TEXT (label), "Sans 10"); - - if (g_spawn_sync (NULL, argv, NULL, - G_SPAWN_STDERR_TO_DEV_NULL | G_SPAWN_SEARCH_PATH, - NULL, NULL, &text, NULL, NULL, NULL)) - { - clutter_text_set_text (CLUTTER_TEXT (label), text); - free (text); - } - - return label; -} - -static ClutterActor * -make_tex (void) -{ - ClutterActor *tex = clutter_texture_new (); - - clutter_actor_set_size (tex, TEX_SIZE * 2, TEX_SIZE * 2); - - return tex; -} - -static ClutterActor * -make_box (void) -{ - ClutterActor *box; - static const ClutterColor blue = { 0x00, 0x00, 0xff, 0xff }; - - box = clutter_rectangle_new_with_color (&blue); - clutter_actor_set_size (box, DOT_SIZE + 2, DOT_SIZE + 2); - clutter_actor_hide (box); - - return box; -} - -static gboolean -on_motion_idle (gpointer user_data) -{ - CallbackData *data = (CallbackData *) user_data; - guchar *pixels, *p; - gfloat stage_width, stage_height; - gint x, y; - - data->idle_source = 0; - - clutter_actor_get_size (data->stage, &stage_width, &stage_height); - - x = CLAMP (data->event.x - TEX_SIZE / 2, 0, stage_width - TEX_SIZE); - y = CLAMP (data->event.y - TEX_SIZE / 2, 0, stage_height - TEX_SIZE); - - clutter_actor_set_position (data->box, - x + TEX_SIZE / 2 - 1, - y + TEX_SIZE / 2 - 1); - clutter_actor_show (data->box); - - /* Redraw so that the layouting will be done and the box will be - drawn in the right position */ - clutter_stage_ensure_redraw (CLUTTER_STAGE (data->stage)); - - pixels = clutter_stage_read_pixels (CLUTTER_STAGE (data->stage), - x, y, - TEX_SIZE, TEX_SIZE); - - /* Make a red dot in the center */ - p = pixels + (TEX_SIZE / 2 - DOT_SIZE / 2) * TEX_SIZE * 4 - + (TEX_SIZE / 2 - DOT_SIZE / 2) * 4; - for (y = 0; y < DOT_SIZE; y++) - { - for (x = 0; x < DOT_SIZE; x++) - { - *(p++) = 255; - memset (p, 0, 3); - p += 3; - } - p += TEX_SIZE * 4 - DOT_SIZE * 4; - } - - /* Set all of the alpa values to full */ - for (p = pixels + TEX_SIZE * TEX_SIZE * 4; p > pixels; p -= 4) - *(p - 1) = 255; - - clutter_texture_set_from_rgb_data (CLUTTER_TEXTURE (data->tex), - pixels, TRUE, - TEX_SIZE, TEX_SIZE, - TEX_SIZE * 4, 4, 0, NULL); - free (pixels); - - return FALSE; -} - -static gboolean -on_motion (ClutterActor *stage, ClutterMotionEvent *event, CallbackData *data) -{ - /* Handle the motion event in an idle handler so that multiple - events will be combined into one */ - if (data->idle_source == 0) - data->idle_source = clutter_threads_add_idle (on_motion_idle, data); - - data->event = *event; - - return FALSE; -} - -G_MODULE_EXPORT int -test_stage_read_pixels_main (int argc, char **argv) -{ - CallbackData data; - - if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) - return 1; - - data.idle_source = 0; - data.stage = clutter_stage_new (); - clutter_stage_set_title (CLUTTER_STAGE (data.stage), "Read Pixels"); - g_signal_connect (data.stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); - - data.tex = make_tex (); - data.box = make_box (); - clutter_actor_set_position (data.tex, - clutter_actor_get_width (data.stage) - - clutter_actor_get_width (data.tex), - clutter_actor_get_height (data.stage) - - clutter_actor_get_height (data.tex)); - - clutter_container_add (CLUTTER_CONTAINER (data.stage), - make_label (), data.tex, data.box, NULL); - - g_signal_connect (data.stage, "motion-event", G_CALLBACK (on_motion), &data); - - clutter_actor_show (data.stage); - - clutter_main (); - - return 0; -} - -G_MODULE_EXPORT const char * -test_stage_read_pixels_describe (void) -{ - return "Read back pixels from a Stage."; -} diff --git a/clutter/tests/interactive/test-state-animator.c b/clutter/tests/interactive/test-state-animator.c deleted file mode 100644 index 3b2ee0520..000000000 --- a/clutter/tests/interactive/test-state-animator.c +++ /dev/null @@ -1,144 +0,0 @@ -#include -#include -#include -#include - -static ClutterState *state; -static ClutterAnimator *animator; - -static gboolean press_event (ClutterActor *actor, - ClutterEvent *event, - gpointer user_data) -{ - clutter_grab_pointer (actor); - clutter_state_set_state (state, "end"); - return TRUE; -} - -static gboolean release_event (ClutterActor *actor, - ClutterEvent *event, - gpointer user_data) -{ - clutter_state_set_state (state, "start"); - clutter_ungrab_pointer (); - return TRUE; -} - - -static ClutterActor *new_rect (gint r, - gint g, - gint b, - gint a) -{ - GError *error = NULL; - ClutterColor *color = clutter_color_new (r, g, b, a); - ClutterActor *rectangle; - - gchar *file = g_build_filename (TESTS_DATADIR, "redhand.png", NULL); - rectangle = clutter_texture_new_from_file (file, &error); - if (rectangle == NULL) - g_error ("image load failed: %s", error->message); - free (file); - - clutter_actor_set_size (rectangle, 128, 128); - clutter_color_free (color); - return rectangle; -} - -G_MODULE_EXPORT gint -test_state_animator_main (gint argc, - gchar **argv) -{ - ClutterActor *stage; - ClutterActor *rects[40]; - gint i; - - if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) - return 1; - - stage = clutter_stage_new (); - clutter_stage_set_title (CLUTTER_STAGE (stage), "State and Animator"); - g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); - - for (i = 0; i < 2; i++) - { - rects[i] = new_rect (255 * (i * 1.0 / 40), 50, 160, 255); - clutter_container_add_actor (CLUTTER_CONTAINER (stage), rects[i]); - clutter_actor_set_anchor_point (rects[i], 64, 64); - clutter_actor_set_position (rects[i], 320.0, 240.0); - clutter_actor_set_opacity (rects[i], 0x70); - - clutter_actor_set_reactive (rects[i], TRUE); - g_signal_connect (rects[i], "button-press-event", G_CALLBACK (press_event), NULL); - g_signal_connect (rects[i], "button-release-event", G_CALLBACK (release_event), NULL); - } - - state = clutter_state_new (); - clutter_state_set (state, NULL, "start", - rects[0], "depth", CLUTTER_LINEAR, 0.0, - rects[0], "x", CLUTTER_LINEAR, 100.0, - rects[0], "y", CLUTTER_LINEAR, 300.0, - rects[1], "opacity", CLUTTER_LINEAR, 0x20, - rects[1], "scale-x", CLUTTER_LINEAR, 1.0, - rects[1], "scale-y", CLUTTER_LINEAR, 1.0, - NULL); - clutter_state_set (state, NULL, "end", - rects[0], "depth", CLUTTER_LINEAR, 200.0, - rects[0], "x", CLUTTER_LINEAR, 320.0, - rects[0], "y", CLUTTER_LINEAR, 240.0, - rects[1], "opacity", CLUTTER_LINEAR, 0xff, - rects[1], "scale-x", CLUTTER_LINEAR, 2.0, - rects[1], "scale-y", CLUTTER_LINEAR, 2.0, - NULL); - - animator = clutter_animator_new (); - clutter_animator_set (animator, - rects[0], "depth", -1, 0.0, 0.0, - rects[0], "depth", CLUTTER_LINEAR, 1.0, 275.0, - rects[0], "x", -1, 0.0, 0.0, - rects[0], "x", CLUTTER_LINEAR, 0.5, 200.0, - rects[0], "x", CLUTTER_LINEAR, 1.0, 320.0, - - rects[0], "y", -1, 0.0, 0.0, - rects[0], "y", CLUTTER_LINEAR, 0.3, 100.0, - rects[0], "y", CLUTTER_LINEAR, 1.0, 240.0, - - rects[1], "opacity", -1, 0.0, 0x20, - rects[1], "opacity", CLUTTER_LINEAR, 1.0, 0xff, - rects[1], "scale-x", -1, 0.0, 1.0, - rects[1], "scale-x", CLUTTER_LINEAR, 0.5, 2.0, - rects[1], "scale-x", CLUTTER_LINEAR, 1.0, 2.0, - rects[1], "scale-y", -1, 0.0, 1.0, - rects[1], "scale-y", CLUTTER_LINEAR, 0.5, 2.0, - rects[1], "scale-y", CLUTTER_LINEAR, 1.0, 2.0, - NULL); - - clutter_animator_property_set_ease_in (animator, G_OBJECT (rects[0]), "depth", TRUE); - clutter_animator_property_set_ease_in (animator, G_OBJECT (rects[0]), "x", TRUE); - clutter_animator_property_set_ease_in (animator, G_OBJECT (rects[0]), "y", TRUE); - clutter_animator_property_set_ease_in (animator, G_OBJECT (rects[1]), "opacity", TRUE); - clutter_animator_property_set_ease_in (animator, G_OBJECT (rects[1]), "scale-x", TRUE); - clutter_animator_property_set_ease_in (animator, G_OBJECT (rects[1]), "scale-y", TRUE); - - clutter_animator_property_set_interpolation (animator, G_OBJECT (rects[0]), "x", - CLUTTER_INTERPOLATION_CUBIC); - clutter_animator_property_set_interpolation (animator, G_OBJECT (rects[0]), "y", - CLUTTER_INTERPOLATION_CUBIC); - - clutter_state_set_animator (state, "start", "end", animator); - g_object_unref (animator); - - clutter_actor_show (stage); - clutter_state_set_state (state, "start"); - - clutter_main (); - g_object_unref (state); - - return EXIT_SUCCESS; -} - -G_MODULE_EXPORT const char * -test_state_animator_describe (void) -{ - return "Animate using the State and Animator classes."; -} diff --git a/clutter/tests/interactive/test-table-layout.c b/clutter/tests/interactive/test-table-layout.c deleted file mode 100644 index c5fd3f85c..000000000 --- a/clutter/tests/interactive/test-table-layout.c +++ /dev/null @@ -1,284 +0,0 @@ -#include -#include - -#include - -#include -#include -#include - -#define FONT "Sans 12" - -static void -set_text (ClutterActor *actor, const gchar *text) -{ - GList *children, *l; - - children = clutter_container_get_children (CLUTTER_CONTAINER (actor)); - for (l = children; l; l = g_list_next (l)) { - if (CLUTTER_IS_TEXT (l->data)) { - clutter_text_set_text (CLUTTER_TEXT (l->data), text); - break; - } - } - g_list_free (children); -} - -static void -toggle_expand (ClutterActor *actor, ClutterEvent *event, ClutterBox *box) -{ - gboolean x_expand; - gchar *label; - ClutterLayoutManager *layout = clutter_box_get_layout_manager (box); - - - clutter_layout_manager_child_get (layout, CLUTTER_CONTAINER (box), actor, - "x-expand", &x_expand, - NULL); - - x_expand = !x_expand; - - clutter_layout_manager_child_set (layout, CLUTTER_CONTAINER (box), actor, - "x-expand", x_expand, - "y-expand", x_expand, - NULL); - - label = g_strdup_printf ("Expand = %d", x_expand); - set_text (actor, label); - - free (label); -} - -static const gchar * -get_alignment_name (ClutterTableAlignment alignment) -{ - switch (alignment) - { - case CLUTTER_TABLE_ALIGNMENT_START: - return "start"; - - case CLUTTER_TABLE_ALIGNMENT_CENTER: - return "center"; - - case CLUTTER_TABLE_ALIGNMENT_END: - return "end"; - } - - return "undefined"; -} - -static void -randomise_align (ClutterActor *actor, ClutterEvent *event, ClutterBox *box) -{ - ClutterTableAlignment x_align, y_align; - gchar *label; - ClutterLayoutManager *layout; - - layout = clutter_box_get_layout_manager (box); - - x_align = (ClutterTableAlignment) g_random_int_range (0, 3); - y_align = (ClutterTableAlignment) g_random_int_range (0, 3); - - clutter_layout_manager_child_set (layout, CLUTTER_CONTAINER (box), actor, - "x-align", x_align, - "y-align", y_align, - NULL); - - label = g_strdup_printf ("Align (%s, %s)", - get_alignment_name (x_align), - get_alignment_name (y_align)); - set_text (actor, label); - free (label); -} - -static void -toggle_visible (ClutterActor *actor, ClutterEvent *event, gpointer userdata) -{ - clutter_actor_hide (actor); -} - -gboolean drag = FALSE; - -static ClutterActor * -create_cell (ClutterActor *actor, const gchar *color_str) -{ - ClutterActor *result; - ClutterActor *rectangle; - ClutterColor color; - - result = - clutter_box_new (clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_FILL, - CLUTTER_BIN_ALIGNMENT_FILL)); - - rectangle = clutter_rectangle_new (); - clutter_color_from_string (&color, color_str); - clutter_rectangle_set_color (CLUTTER_RECTANGLE (rectangle), (const ClutterColor *) &color); - clutter_color_from_string (&color, "#000f"); - clutter_rectangle_set_border_color (CLUTTER_RECTANGLE (rectangle), (const ClutterColor *) &color); - clutter_rectangle_set_border_width (CLUTTER_RECTANGLE (rectangle), 2); - - clutter_actor_show (rectangle); - clutter_actor_set_reactive (result, TRUE); - clutter_container_add_actor (CLUTTER_CONTAINER (result), rectangle); - clutter_box_pack (CLUTTER_BOX (result), actor, - "x-align", CLUTTER_BIN_ALIGNMENT_CENTER, - "y-align", CLUTTER_BIN_ALIGNMENT_CENTER, - NULL); - - return result; -} - -static ClutterActor * -create_text (const gchar *label, const gchar *color) -{ - ClutterActor *text; - ClutterActor *result; - - text = clutter_text_new_with_text (FONT, label); - clutter_actor_show (text); - - result = create_cell (text, color); - clutter_actor_show (result); - - return result; -} - -static ClutterActor * -create_image (const gchar *file, const gchar *color) -{ - ClutterActor *texture; - ClutterActor *result; - - texture = clutter_texture_new_from_file (file, NULL); - g_object_set (G_OBJECT (texture), "keep-aspect-ratio", TRUE, NULL); - clutter_actor_show (texture); - - result = create_cell (texture, color); - clutter_actor_show (result); - - return result; -} - -G_MODULE_EXPORT int -test_table_layout_main (int argc, char *argv[]) -{ - ClutterActor *stage; - ClutterLayoutManager *layout; - ClutterActor *actor1, *actor2, *actor3, *actor4, *actor5, *actor6, *actor7, *actor8, *actor9, *actor10; - ClutterActor *box; - gchar *file; - - if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) - return 1; - - stage = clutter_stage_new (); - clutter_stage_set_title (CLUTTER_STAGE (stage), "Table Layout"); - clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE); - clutter_actor_set_size (stage, 640, 480); - g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); - - layout = clutter_table_layout_new (); - clutter_table_layout_set_column_spacing (CLUTTER_TABLE_LAYOUT (layout), 10); - clutter_table_layout_set_row_spacing (CLUTTER_TABLE_LAYOUT (layout), 10); - clutter_table_layout_set_use_animations (CLUTTER_TABLE_LAYOUT (layout), TRUE); - - box = clutter_box_new (layout); - clutter_container_add_actor (CLUTTER_CONTAINER (stage), box); - clutter_actor_add_constraint (box, clutter_bind_constraint_new (stage, CLUTTER_BIND_WIDTH, -10.0)); - clutter_actor_add_constraint (box, clutter_bind_constraint_new (stage, CLUTTER_BIND_HEIGHT, -10.0)); - - actor1 = create_text ("label 1", "#f66f"); - file = g_build_filename (TESTS_DATADIR, "redhand.png", NULL); - actor2 = create_image (file, "#bbcf"); - free (file); - actor3 = create_text ("label 3", "#6f6f"); - actor4 = create_text ("Expand = 1", "#66ff"); - actor5 = create_text ("label 5", "#f6ff"); - actor6 = create_text ("label 6", "#6fff"); - actor7 = create_text ("Align (center, center)", "#66ff"); - actor8 = create_text ("label 8", "#ffff"); - actor9 = create_text ("label 9", "#666f"); - actor10 = create_text ("label 10", "#aaaf"); - - clutter_table_layout_pack (CLUTTER_TABLE_LAYOUT (layout), actor1, 0, 0); - clutter_table_layout_pack (CLUTTER_TABLE_LAYOUT (layout), actor2, 1, 0); - clutter_table_layout_pack (CLUTTER_TABLE_LAYOUT (layout), actor3, 1, 1); - clutter_table_layout_pack (CLUTTER_TABLE_LAYOUT (layout), actor4, 0, 2); - clutter_table_layout_pack (CLUTTER_TABLE_LAYOUT (layout), actor5, 0, 3); - clutter_table_layout_pack (CLUTTER_TABLE_LAYOUT (layout), actor6, 1, 3); - clutter_table_layout_pack (CLUTTER_TABLE_LAYOUT (layout), actor7, 1, 4); - clutter_table_layout_pack (CLUTTER_TABLE_LAYOUT (layout), actor8, 0, 4); - clutter_table_layout_pack (CLUTTER_TABLE_LAYOUT (layout), actor9, 0, 5); - clutter_table_layout_pack (CLUTTER_TABLE_LAYOUT (layout), actor10, 0, -1); - clutter_table_layout_set_span (CLUTTER_TABLE_LAYOUT (layout), actor1, 1, 2); - clutter_table_layout_set_span (CLUTTER_TABLE_LAYOUT (layout), actor7, 1, 2); - clutter_table_layout_set_span (CLUTTER_TABLE_LAYOUT (layout), actor4, 2, 1); - - clutter_actor_set_size (actor1, 100, 100); - clutter_actor_set_width (actor4, 250); - - clutter_layout_manager_child_set (CLUTTER_LAYOUT_MANAGER (layout), - CLUTTER_CONTAINER (box), - actor1, - "x-expand", FALSE, "y-expand", FALSE, - NULL); - clutter_layout_manager_child_set (CLUTTER_LAYOUT_MANAGER (layout), - CLUTTER_CONTAINER (box), - actor4, - "x-expand", TRUE, "y-expand", TRUE, - "x-fill", TRUE, "y-fill", TRUE, - NULL); - clutter_layout_manager_child_set (CLUTTER_LAYOUT_MANAGER (layout), - CLUTTER_CONTAINER (box), - actor7, - "x-expand", TRUE, "y-expand", TRUE, - "x-fill", FALSE, "y-fill", FALSE, - NULL); - clutter_layout_manager_child_set (CLUTTER_LAYOUT_MANAGER (layout), - CLUTTER_CONTAINER (box), - actor8, - "x-expand", FALSE, "y-expand", FALSE, - NULL); - clutter_layout_manager_child_set (CLUTTER_LAYOUT_MANAGER (layout), - CLUTTER_CONTAINER (box), - actor9, - "x-expand", FALSE, "y-expand", FALSE, - NULL); - - clutter_layout_manager_child_set (CLUTTER_LAYOUT_MANAGER (layout), - CLUTTER_CONTAINER (box), - actor2, - "y-fill", FALSE, - "x-fill", FALSE, - NULL); - - clutter_actor_set_position (box, 5, 5); - - g_signal_connect (actor4, "button-release-event", G_CALLBACK (toggle_expand), box); - g_signal_connect (actor7, "button-release-event", G_CALLBACK (randomise_align), box); - g_signal_connect (actor10, "button-release-event", G_CALLBACK (toggle_visible), NULL); - - /* g_signal_connect (stage, "button-press-event", G_CALLBACK (button_press), */ - /* box); */ - /* g_signal_connect (stage, "motion-event", G_CALLBACK (motion_event), */ - /* box); */ - /* g_signal_connect (stage, "button-release-event", G_CALLBACK (button_release), */ - /* box); */ - - clutter_actor_show (stage); - - g_debug ("table row count = %d", - clutter_table_layout_get_row_count (CLUTTER_TABLE_LAYOUT (layout))); - g_debug ("table column count = %d", - clutter_table_layout_get_column_count (CLUTTER_TABLE_LAYOUT (layout))); - - clutter_main (); - - return EXIT_SUCCESS; -} - -G_MODULE_EXPORT const char * -test_table_layout_describe (void) -{ - return "TableLayout layout manager example."; -} diff --git a/clutter/tests/interactive/test-texture-async.c b/clutter/tests/interactive/test-texture-async.c deleted file mode 100644 index e3525f0c1..000000000 --- a/clutter/tests/interactive/test-texture-async.c +++ /dev/null @@ -1,156 +0,0 @@ -#include -#include -#include - -enum -{ - LOAD_SYNC, - LOAD_DATA_ASYNC, - LOAD_ASYNC -}; - -static ClutterActor *stage = NULL; - -static void -on_load_finished (ClutterTexture *texture, - const GError *error, - gpointer user_data) -{ - gint load_type = GPOINTER_TO_INT (user_data); - const gchar *load_str = NULL; - - switch (load_type) - { - case LOAD_SYNC: - load_str = "synchronous loading"; - break; - - case LOAD_DATA_ASYNC: - load_str = "asynchronous data loading"; - break; - - case LOAD_ASYNC: - load_str = "asynchronous loading"; - break; - } - - if (error != NULL) - g_print ("%s failed: %s\n", load_str, error->message); - else - g_print ("%s successful\n", load_str); -} - -static void -size_change_cb (ClutterTexture *texture, - gint width, - gint height, - gpointer user_data) -{ - clutter_actor_set_size (user_data, width, height); -} - -static -gboolean task (gpointer user_data) -{ - const gchar *path = user_data; - ClutterActor *image[3]; - ClutterActor *clone[3]; - gint i; - - image[0] = g_object_new (CLUTTER_TYPE_TEXTURE, NULL); - g_signal_connect (image[0], "load-finished", - G_CALLBACK (on_load_finished), - GINT_TO_POINTER (LOAD_SYNC)); - - image[1] = g_object_new (CLUTTER_TYPE_TEXTURE, - "load-data-async", TRUE, - NULL); - g_signal_connect (image[1], "load-finished", - G_CALLBACK (on_load_finished), - GINT_TO_POINTER (LOAD_DATA_ASYNC)); - image[2] = g_object_new (CLUTTER_TYPE_TEXTURE, - "load-async", TRUE, - NULL); - g_signal_connect (image[2], "load-finished", - G_CALLBACK (on_load_finished), - GINT_TO_POINTER (LOAD_ASYNC)); - - for (i = 0; i < 3; i++) - { - GError *error = NULL; - - clutter_texture_set_from_file (CLUTTER_TEXTURE (image[i]), path, &error); - if (error != NULL) - g_error ("Unable to load image at '%s': %s", - path != NULL ? path : "", - error->message); - } - - for (i = 0; i < 3; i++) - clutter_container_add_actor (CLUTTER_CONTAINER (stage), image[i]); - - for (i = 0; i < 3; i++) - { - clutter_actor_set_position (image[i], 50 + i * 100, 0 + i * 50); - clutter_actor_set_depth (image[i], -2500); - - clone[i] = clutter_clone_new (image[i]); - g_signal_connect (image[i], "size-change", - G_CALLBACK (size_change_cb), clone[i]); - clutter_container_add_actor (CLUTTER_CONTAINER (stage), clone[i]); - clutter_actor_set_position (clone[i], 50 + i * 100, 150 + i * 50 + 100); - } - - for (i = 0; i < 3; i++) - { - clutter_actor_save_easing_state (image[i]); - clutter_actor_set_easing_duration (image[i], 5000); - clutter_actor_set_depth (image[i], 0); - clutter_actor_restore_easing_state (image[i]); - } - - return FALSE; -} - -static void -cleanup_task (gpointer data) -{ -} - -G_MODULE_EXPORT gint -test_texture_async_main (int argc, char *argv[]) -{ - gchar *path; - - if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) - return 1; - - stage = clutter_stage_new (); - clutter_stage_set_title (CLUTTER_STAGE (stage), "Asynchronous Texture Loading"); - clutter_actor_set_background_color (stage, CLUTTER_COLOR_LightSkyBlue); - g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); - - clutter_actor_show (stage); - - path = (argc > 1) - ? g_strdup (argv[1]) - : g_build_filename (TESTS_DATADIR, "redhand.png", NULL); - - clutter_threads_add_timeout_full (G_PRIORITY_DEFAULT, 500, - task, path, - cleanup_task); - - clutter_threads_enter (); - clutter_main (); - clutter_threads_leave (); - - free (path); - - return EXIT_SUCCESS; -} - -G_MODULE_EXPORT const char * -test_texture_async_describe (void) -{ - return "Texture asynchronous loading using threads"; -} diff --git a/clutter/tests/interactive/test-texture-material.c b/clutter/tests/interactive/test-texture-material.c deleted file mode 100644 index 4886ce03a..000000000 --- a/clutter/tests/interactive/test-texture-material.c +++ /dev/null @@ -1,46 +0,0 @@ -#include -#include -#include -#include - -G_MODULE_EXPORT int -test_texture_material_main (int argc, char *argv[]) -{ - ClutterActor *stage, *box; - ClutterLayoutManager *manager; - int i; - - if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) - return 1; - - stage = clutter_stage_new (); - clutter_stage_set_title (CLUTTER_STAGE (stage), "Texture Material"); - g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); - - manager = clutter_flow_layout_new (CLUTTER_FLOW_HORIZONTAL); - box = clutter_box_new (manager); - clutter_actor_add_constraint (box, clutter_bind_constraint_new (stage, CLUTTER_BIND_WIDTH, -25.0)); - clutter_actor_add_constraint (box, clutter_bind_constraint_new (stage, CLUTTER_BIND_HEIGHT, -25.0)); - clutter_actor_set_position (box, 25.0, 25.0); - clutter_container_add_actor (CLUTTER_CONTAINER (stage), box); - - for (i = 0; i < 48; i++) - { - ClutterActor *texture = clutter_texture_new (); - - clutter_texture_set_load_data_async (CLUTTER_TEXTURE (texture), TRUE); - clutter_texture_set_keep_aspect_ratio (CLUTTER_TEXTURE (texture), TRUE); - clutter_texture_set_from_file (CLUTTER_TEXTURE (texture), - TESTS_DATADIR "/redhand.png", - NULL); - clutter_actor_set_width (texture, 96); - - clutter_container_add_actor (CLUTTER_CONTAINER (box), texture); - } - - clutter_actor_show (stage); - - clutter_main (); - - return EXIT_SUCCESS; -} diff --git a/clutter/tests/interactive/test-texture-quality.c b/clutter/tests/interactive/test-texture-quality.c deleted file mode 100644 index b15b430cf..000000000 --- a/clutter/tests/interactive/test-texture-quality.c +++ /dev/null @@ -1,116 +0,0 @@ -#include -#include -#include - -/* each time the timeline animating the label completes, swap the direction */ -static void -timeline_completed (ClutterTimeline *timeline, - gpointer user_data) -{ - clutter_timeline_set_direction (timeline, - !clutter_timeline_get_direction (timeline)); - clutter_timeline_start (timeline); -} - -static gboolean -change_filter (gpointer actor) -{ - ClutterTextureQuality old_quality; - - old_quality = clutter_texture_get_filter_quality (actor); - switch (old_quality) - { - case CLUTTER_TEXTURE_QUALITY_LOW: - clutter_texture_set_filter_quality (actor, - CLUTTER_TEXTURE_QUALITY_MEDIUM); - g_print ("Setting texture rendering quality to medium\n"); - break; - case CLUTTER_TEXTURE_QUALITY_MEDIUM: - clutter_texture_set_filter_quality (actor, - CLUTTER_TEXTURE_QUALITY_HIGH); - g_print ("Setting texture rendering quality to high\n"); - break; - case CLUTTER_TEXTURE_QUALITY_HIGH: - clutter_texture_set_filter_quality (actor, - CLUTTER_TEXTURE_QUALITY_LOW); - g_print ("Setting texture rendering quality to low\n"); - break; - } - return TRUE; -} - -G_MODULE_EXPORT gint -test_texture_quality_main (int argc, char *argv[]) -{ - ClutterTimeline *timeline; - ClutterAlpha *alpha; - ClutterBehaviour *depth_behavior; - ClutterActor *stage; - ClutterActor *image; - ClutterColor stage_color = { 0x12, 0x34, 0x56, 0xff }; - ClutterFog stage_fog = { 10.0, -50.0 }; - GError *error; - gchar *file; - - if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) - return 1; - - stage = clutter_stage_new (); - clutter_actor_set_background_color (stage, &stage_color); - clutter_stage_set_use_fog (CLUTTER_STAGE (stage), TRUE); - clutter_stage_set_fog (CLUTTER_STAGE (stage), &stage_fog); - g_signal_connect (stage, - "destroy", G_CALLBACK (clutter_main_quit), - NULL); - g_signal_connect (stage, - "button-press-event", G_CALLBACK (clutter_main_quit), - NULL); - - if (argc < 2) - g_print ("Hint: the redhand.png isn't a good test image for this test.\n" - "This test can take any image file as an argument\n"); - - file = (argc > 1) - ? g_strdup (argv[1]) - : g_build_filename (TESTS_DATADIR, "redhand.png", NULL); - - error = NULL; - image = clutter_texture_new_from_file (file, &error); - if (error) - g_error ("Unable to load image: %s", error->message); - - free (file); - - /* center the image */ - clutter_actor_set_position (image, - (clutter_actor_get_width (stage) - clutter_actor_get_width (image))/2, - (clutter_actor_get_height (stage) - clutter_actor_get_height (image))/2); - clutter_container_add (CLUTTER_CONTAINER (stage), image, NULL); - - timeline = clutter_timeline_new (5000); - g_signal_connect (timeline, - "completed", G_CALLBACK (timeline_completed), - NULL); - - alpha = clutter_alpha_new_full (timeline, CLUTTER_LINEAR); - depth_behavior = clutter_behaviour_depth_new (alpha, -2500, 400); - clutter_behaviour_apply (depth_behavior, image); - - clutter_actor_show (stage); - clutter_timeline_start (timeline); - - clutter_threads_add_timeout (10000, change_filter, image); - - clutter_main (); - - g_object_unref (depth_behavior); - g_object_unref (timeline); - - return EXIT_SUCCESS; -} - -G_MODULE_EXPORT const char * -test_texture_quality_describe (void) -{ - return "Change the texture filtering quality."; -} diff --git a/clutter/tests/interactive/test-texture-slicing.c b/clutter/tests/interactive/test-texture-slicing.c deleted file mode 100644 index 579181474..000000000 --- a/clutter/tests/interactive/test-texture-slicing.c +++ /dev/null @@ -1,125 +0,0 @@ -#include -#include - -#include - -guchar* -make_rgba_data (int width, int height, int bpp, int has_alpha, int *rowstride_p) -{ -#define CHECK_SIZE 20 - - gint x,y, rowstride, i = 0; - guchar *pixels; - - g_assert(bpp == 4); - g_assert(has_alpha == TRUE); - - rowstride = width * bpp; - *rowstride_p = rowstride; - - pixels = g_try_malloc (height * rowstride); - if (!pixels) - return NULL; - - for (y = 0; y < height; y++) - { - i = 0; - for (x = 0; x < width; x++) - { - guchar *p; - - p = pixels + y * rowstride + x * bpp; - - p[0] = p[1] = p[2] = 0; p[3] = 0xff; - - if (x && y && y % CHECK_SIZE && x % CHECK_SIZE) - { - if (x % CHECK_SIZE == 1) - { - if (++i > 3) - i = 0; - } - p[i] = 0xff; - } - } - } - - return pixels; -} - -static void -exit_on_destroy (ClutterActor *actor) -{ - exit(EXIT_SUCCESS); -} - -#define SPIN() while (g_main_context_pending (NULL)) \ - g_main_context_iteration (NULL, FALSE); - -G_MODULE_EXPORT int -test_textures_main (int argc, char *argv[]) -{ - ClutterActor *texture; - ClutterActor *stage; - gint i, j; - - if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) - return 1; - - stage = clutter_stage_new (); - clutter_actor_show_all (CLUTTER_ACTOR (stage)); - g_signal_connect (stage, "destroy", G_CALLBACK (exit_on_destroy), NULL); - - SPIN(); - - for (i=100; i<=5000; i += 100) - for (j=0; j<4; j++) - { - const int width = i+j; - const int height = i+j; - const gboolean has_alpha = TRUE; - const int bpp = has_alpha ? 4 : 3; - int rowstride; - guchar *pixels; - - pixels = make_rgba_data (width, height, bpp, has_alpha, &rowstride); - if (!pixels) - g_error("No memory for %ix%i RGBA data failed", width, height); - - printf("o %ix%i texture... ", width, height); - - texture = clutter_texture_new (); - if (!clutter_texture_set_from_rgb_data (CLUTTER_TEXTURE (texture), - pixels, - has_alpha, - width, - height, - rowstride, - bpp, - 0, NULL)) - g_error("texture creation failed"); - free(pixels); - - printf("uploaded to texture...\n"); - - clutter_container_add (CLUTTER_CONTAINER (stage), texture, NULL); - clutter_actor_set_size (texture, 400, 400); - clutter_actor_show (texture); - - /* Hide & show to unreaise then realise the texture */ - clutter_actor_hide (texture); - clutter_actor_show (texture); - - SPIN(); - - clutter_container_remove (CLUTTER_CONTAINER (stage), texture, NULL); - } - - return EXIT_SUCCESS; -} - -G_MODULE_EXPORT const char * -test_texture_slicing_describe (void) -{ - return "Check texture slicing support in CoglTexture"; -} diff --git a/clutter/tests/micro-bench/.gitignore b/clutter/tests/micro-bench/.gitignore deleted file mode 100644 index 13744d47e..000000000 --- a/clutter/tests/micro-bench/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -/test-cogl-perf -/test-picking -/test-random-text -/test-text -/test-text-perf diff --git a/clutter/tests/micro-bench/Makefile.am b/clutter/tests/micro-bench/Makefile.am deleted file mode 100644 index d721218ee..000000000 --- a/clutter/tests/micro-bench/Makefile.am +++ /dev/null @@ -1,35 +0,0 @@ -common_ldadd = \ - $(top_builddir)/clutter/libmuffin-clutter-@MUFFIN_PLUGIN_API_VERSION@.la \ - $(top_builddir)/../cogl/cogl/libmuffin-cogl-@MUFFIN_PLUGIN_API_VERSION@.la - - -check_PROGRAMS = \ - test-text \ - test-picking \ - test-text-perf \ - test-random-text \ - test-cogl-perf - -AM_CFLAGS = $(CLUTTER_CFLAGS) $(MAINTAINER_CFLAGS) - -AM_CPPFLAGS = \ - -DG_DISABLE_SINGLE_INCLUDES \ - -DGLIB_DISABLE_DEPRECATION_WARNINGS \ - -DCOGL_DISABLE_DEPRECATION_WARNINGS \ - -DCLUTTER_DISABLE_DEPRECATION_WARNINGS \ - -DTESTS_DATA_DIR=\""$(top_srcdir)/tests/data/"\" \ - -I$(top_srcdir)/../cogl \ - -I$(top_builddir)/../cogl \ - -I$(top_builddir)/../cogl/cogl \ - -I$(top_srcdir) \ - -I$(top_builddir) \ - -I$(top_srcdir)/clutter \ - -I$(top_builddir)/clutter - -LDADD = $(common_ldadd) $(CLUTTER_LIBS) $(LIBM) - -test_text_SOURCES = test-text.c -test_picking_SOURCES = test-picking.c -test_text_perf_SOURCES = test-text-perf.c -test_random_text_SOURCES = test-random-text.c -test_cogl_perf_SOURCES = test-cogl-perf.c diff --git a/clutter/tests/performance/.gitignore b/clutter/tests/performance/.gitignore deleted file mode 100644 index 0d50b8430..000000000 --- a/clutter/tests/performance/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -/test-picking -/test-state -/test-state-hidden -/test-state-interactive -/test-state-mini -/test-state-pick -/test-text-perf diff --git a/clutter/tests/performance/Makefile-retrospect b/clutter/tests/performance/Makefile-retrospect deleted file mode 100644 index f696d53de..000000000 --- a/clutter/tests/performance/Makefile-retrospect +++ /dev/null @@ -1,66 +0,0 @@ -# A makefile based framework for testing performance commits in retrospect, -# based on work done by pippin@gimp.org done for GEGL, original code placed in the public domain. - -SELF = Makefile-retrospect - -MAKE_FLAGS = -j3 -k -CC = "ccache gcc" # if you do not have ccache replace with just gcc - -PROJECT_PATH = ../../ - -# mute makes echoing of commands -.SILENT: - -# replace sequential with random to build a random subset -all: reset sequential -#all: reset random - -retry: - rm -rf reports/`cat jobs | tail -n1`* - make -f $(SELF) - -prepare: - # uncomment these to make sure cpu is in high performance mode - #sudo sh -c 'echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor || true' - #sudo sh -c 'echo performance > /sys/devices/system/cpu/cpu1/cpufreq/scaling_governor || true' - -reset: - rm -rf jobs jobs - # remove checkout dir to have a full reset on each invokation - rm -rf checkout - # create clone - git clone -s $(PROJECT_PATH) checkout - mkdir reports > /dev/null 2>&1 || true - make -f $(SELF) jobs - make -f $(SELF) prepare - -jobs: joblist - ./makejobs.rb joblist > jobs - -sequential: - for a in `cat jobs`;do make -f $(SELF) reports/$$a;done - -random: - for a in `cat jobs|sort`;do make -f $(SELF) reports/$$a;done - -reports/%: - # check out revision - (cd checkout; git checkout `echo $@|sed s:reports/::`) - # write header for report - git log -1 `echo $@|sed s:reports/::` > $@ || true - # clean previous build - rm -rf install; mkdir install - # build revision - (cd checkout; if [ ! -f Makefile ]; then CC=$(CC) ./autogen.sh --disable-introspection --prefix=`pwd`/../install; fi ; \ - make $(MAKE_FLAGS) ; make -k install ) > $@.log 2>&1 || true - # testing - make -f Makefile-tests clean;\ - make -f Makefile-tests; sync;\ - make -f Makefile-tests check >> $@ || true - # update report.pdf / report.png - ./create-report.rb - echo - -clean: - rm -rf reports jobs report.pdf report.png checkout install - make -f Makefile-tests clean diff --git a/clutter/tests/performance/Makefile-tests b/clutter/tests/performance/Makefile-tests deleted file mode 100644 index 3381a3232..000000000 --- a/clutter/tests/performance/Makefile-tests +++ /dev/null @@ -1,15 +0,0 @@ -CFILES = $(wildcard *.c) -bins = $(subst ,,$(CFILES:.c=)) - -all: $(bins) - -%: %.c - PKG_CONFIG_PATH=install/lib/pkgconfig:$(PKG_CONFIG_PATH) $(CC) -DTESTS_DATA_DIR=\"../data/\" `pkg-config clutter-1.0 --cflags --libs` -Wall -O2 -o $@ $< - -check: $(bins) - for a in $(bins); do \ - LD_LIBRARY_PATH=install/lib:$(LD_LIBRARY_PATH) ./$$a;\ - done - -clean: - rm -f $(bins) diff --git a/clutter/tests/performance/Makefile.am b/clutter/tests/performance/Makefile.am deleted file mode 100644 index 286bb0ddc..000000000 --- a/clutter/tests/performance/Makefile.am +++ /dev/null @@ -1,43 +0,0 @@ -check_PROGRAMS = \ - test-picking \ - test-text-perf \ - test-state \ - test-state-interactive \ - test-state-hidden \ - test-state-mini \ - test-state-pick - -common_ldadd = $(top_builddir)/clutter/libmuffin-clutter-@MUFFIN_PLUGIN_API_VERSION@.la - -LDADD = $(common_ldadd) $(CLUTTER_LIBS) $(LIBM) - -AM_CFLAGS = $(CLUTTER_CFLAGS) - -AM_CPPFLAGS = \ - -DG_DISABLE_SINGLE_INCLUDES \ - -DGLIB_DISABLE_DEPRECATION_WARNINGS \ - -DCOGL_DISABLE_DEPRECATION_WARNINGS \ - -DCLUTTER_DISABLE_DEPRECATION_WARNINGS \ - -DTESTS_DATA_DIR=\""$(top_srcdir)/tests/data/"\" \ - -I$(top_srcdir)/../cogl \ - -I$(top_builddir)/../cogl \ - -I$(top_builddir)/../cogl/cogl \ - -I$(top_srcdir) \ - -I$(top_builddir) \ - -I$(top_srcdir)/clutter \ - -I$(top_builddir)/clutter - -perf-report: check - -check: - for a in $(noinst_PROGRAMS);do ./$$a;done;true - -test_picking_SOURCES = test-picking.c -test_text_perf_SOURCES = test-text-perf.c -test_state_SOURCES = test-state.c -test_state_hidden_SOURCES = test-state-hidden.c -test_state_pick_SOURCES = test-state-pick.c -test_state_interactive_SOURCES = test-state-interactive.c -test_state_mini_SOURCES = test-state-mini.c - -EXTRA_DIST = Makefile-retrospect Makefile-tests create-report.rb test-common.h diff --git a/cogl/.gitignore b/cogl/.gitignore index 1fbcc195d..7f7367087 100644 --- a/cogl/.gitignore +++ b/cogl/.gitignore @@ -40,7 +40,7 @@ cogl-path-enum-types.c cogl-path-enum-types.h cogl-config.h cogl-config.h.in -cogl-muffin-config.h +cogl-mutter-config.h config.log config.lt config.status @@ -66,7 +66,6 @@ TAGS /tests/conform/config.env /tests/conform/.log /tests/unit/.log -/tests/micro-perf/test-journal /tests/config.env /po/POTFILES /po/*.gmo diff --git a/cogl/Makefile.am b/cogl/Makefile.am deleted file mode 100644 index 0fd58eb0d..000000000 --- a/cogl/Makefile.am +++ /dev/null @@ -1,35 +0,0 @@ -SUBDIRS = test-fixtures - -SUBDIRS += cogl - -if BUILD_COGL_PATH -SUBDIRS += cogl-path -endif - -if BUILD_COGL_PANGO -SUBDIRS += cogl-pango -endif - -if BUILD_COGL_GLES2 -SUBDIRS += cogl-gles2 -endif - -SUBDIRS += tests - -ACLOCAL_AMFLAGS = -I build/autotools ${ACLOCAL_FLAGS} - -EXTRA_DIST = \ - config-custom.h - -# .changelog expects these to be initializes -CLEANFILES= -DISTCLEANFILES= - -DISTCHECK_CONFIGURE_FLAGS = \ - --enable-maintainer-flags \ - --enable-profile \ - --enable-gles2 \ - --enable-gl \ - --enable-xlib-egl-platform \ - --enable-glx \ - --enable-cogl-gst diff --git a/cogl/build/autotools/Makefile.am.enums b/cogl/build/autotools/Makefile.am.enums deleted file mode 100644 index 2fd69d5bd..000000000 --- a/cogl/build/autotools/Makefile.am.enums +++ /dev/null @@ -1,52 +0,0 @@ -# Rules for generating enumeration types using glib-mkenums -# -# Define: -# glib_enum_h = header template file -# glib_enum_c = source template file -# glib_enum_headers = list of headers to parse -# -# before including Makefile.am.enums. You will also need to have -# the following targets already defined: -# -# CLEANFILES -# DISTCLEANFILES -# BUILT_SOURCES -# EXTRA_DIST -# -# Author: Emmanuele Bassi - -# Basic sanity checks -$(if $(GLIB_MKENUMS),,$(error Need to define GLIB_MKENUMS)) - -$(if $(or $(glib_enum_h), \ - $(glib_enum_c)),, \ - $(error Need to define glib_enum_h and glib_enum_c)) - -$(if $(glib_enum_headers),,$(error Need to define glib_enum_headers)) - -enum_tmpl_h=$(addprefix $(srcdir)/, $(glib_enum_h:.h=.h.in)) -enum_tmpl_c=$(addprefix $(srcdir)/, $(glib_enum_c:.c=.c.in)) -enum_headers=$(addprefix $(srcdir)/, $(glib_enum_headers)) - -CLEANFILES += stamp-enum-types -DISTCLEANFILES += $(glib_enum_h) $(glib_enum_c) -BUILT_SOURCES += $(glib_enum_h) $(glib_enum_c) -EXTRA_DIST += $(enum_tmpl_h) $(enum_tmpl_c) - -stamp-enum-types: $(enum_headers) $(enum_tmpl_h) - $(AM_V_GEN)$(GLIB_MKENUMS) \ - --template $(enum_tmpl_h) \ - $(enum_headers) > xgen-eh \ - && (cmp -s xgen-eh $(glib_enum_h) || cp -f xgen-eh $(glib_enum_h)) \ - && rm -f xgen-eh \ - && echo timestamp > $(@F) - -$(glib_enum_h): stamp-enum-types - @true - -$(glib_enum_c): $(enum_headers) $(enum_tmpl_h) $(enum_tmpl_c) - $(AM_V_GEN)$(GLIB_MKENUMS) \ - --template $(enum_tmpl_c) \ - $(enum_headers) > xgen-ec \ - && cp -f xgen-ec $(glib_enum_c) \ - && rm -f xgen-ec diff --git a/cogl/build/autotools/as-compiler-flag.m4 b/cogl/build/autotools/as-compiler-flag.m4 deleted file mode 100644 index 0f660cf07..000000000 --- a/cogl/build/autotools/as-compiler-flag.m4 +++ /dev/null @@ -1,62 +0,0 @@ -dnl as-compiler-flag.m4 0.1.0 - -dnl autostars m4 macro for detection of compiler flags - -dnl David Schleef - -dnl $Id: as-compiler-flag.m4,v 1.1 2005/12/15 23:35:19 ds Exp $ - -dnl AS_COMPILER_FLAG(CFLAGS, ACTION-IF-ACCEPTED, [ACTION-IF-NOT-ACCEPTED]) -dnl Tries to compile with the given CFLAGS. -dnl Runs ACTION-IF-ACCEPTED if the compiler can compile with the flags, -dnl and ACTION-IF-NOT-ACCEPTED otherwise. - -AC_DEFUN([AS_COMPILER_FLAG], -[ - AC_MSG_CHECKING([to see if compiler understands $1]) - - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $1" - - AC_TRY_COMPILE([ ], [], [flag_ok=yes], [flag_ok=no]) - CFLAGS="$save_CFLAGS" - - if test "X$flag_ok" = Xyes ; then - m4_ifvaln([$2],[$2]) - true - else - m4_ifvaln([$3],[$3]) - true - fi - AC_MSG_RESULT([$flag_ok]) -]) - -dnl AS_COMPILER_FLAGS(VAR, FLAGS) -dnl Tries to compile with the given CFLAGS. - -AC_DEFUN([AS_COMPILER_FLAGS], -[ - list=$2 - flags_supported="" - flags_unsupported="" - AC_MSG_CHECKING([for supported compiler flags]) - for each in $list - do - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $each" - AC_TRY_COMPILE([ ], [], [flag_ok=yes], [flag_ok=no]) - CFLAGS="$save_CFLAGS" - - if test "X$flag_ok" = Xyes ; then - flags_supported="$flags_supported $each" - else - flags_unsupported="$flags_unsupported $each" - fi - done - AC_MSG_RESULT([$flags_supported]) - if test "X$flags_unsupported" != X ; then - AC_MSG_WARN([unsupported compiler flags: $flags_unsupported]) - fi - $1="$$1 $flags_supported" -]) - diff --git a/cogl/build/autotools/introspection.m4 b/cogl/build/autotools/introspection.m4 deleted file mode 100644 index 589721c5a..000000000 --- a/cogl/build/autotools/introspection.m4 +++ /dev/null @@ -1,94 +0,0 @@ -dnl -*- mode: autoconf -*- -dnl Copyright 2009 Johan Dahlin -dnl -dnl This file is free software; the author(s) gives unlimited -dnl permission to copy and/or distribute it, with or without -dnl modifications, as long as this notice is preserved. -dnl - -# serial 1 - -m4_define([_GOBJECT_INTROSPECTION_CHECK_INTERNAL], -[ - AC_BEFORE([AC_PROG_LIBTOOL],[$0])dnl setup libtool first - AC_BEFORE([AM_PROG_LIBTOOL],[$0])dnl setup libtool first - AC_BEFORE([LT_INIT],[$0])dnl setup libtool first - - dnl enable/disable introspection - m4_if([$2], [require], - [dnl - enable_introspection=yes - ],[dnl - AC_ARG_ENABLE(introspection, - AS_HELP_STRING([--enable-introspection[=@<:@no/auto/yes@:>@]], - [Enable introspection for this build]),, - [enable_introspection=auto]) - ])dnl - - AC_MSG_CHECKING([for gobject-introspection]) - - dnl presence/version checking - AS_CASE([$enable_introspection], - [no], [dnl - found_introspection="no (disabled, use --enable-introspection to enable)" - ],dnl - [yes],[dnl - PKG_CHECK_EXISTS([gobject-introspection-1.0],, - AC_MSG_ERROR([gobject-introspection-1.0 is not installed])) - PKG_CHECK_EXISTS([gobject-introspection-1.0 >= $1], - found_introspection=yes, - AC_MSG_ERROR([You need to have gobject-introspection >= $1 installed to build AC_PACKAGE_NAME])) - ],dnl - [auto],[dnl - PKG_CHECK_EXISTS([gobject-introspection-1.0 >= $1], found_introspection=yes, found_introspection=no) - ],dnl - [dnl - AC_MSG_ERROR([invalid argument passed to --enable-introspection, should be one of @<:@no/auto/yes@:>@]) - ])dnl - - AC_MSG_RESULT([$found_introspection]) - - INTROSPECTION_SCANNER= - INTROSPECTION_COMPILER= - INTROSPECTION_GENERATE= - INTROSPECTION_GIRDIR= - INTROSPECTION_TYPELIBDIR= - if test "x$found_introspection" = "xyes"; then - INTROSPECTION_SCANNER=`$PKG_CONFIG --variable=g_ir_scanner gobject-introspection-1.0` - INTROSPECTION_COMPILER=`$PKG_CONFIG --variable=g_ir_compiler gobject-introspection-1.0` - INTROSPECTION_GENERATE=`$PKG_CONFIG --variable=g_ir_generate gobject-introspection-1.0` - INTROSPECTION_GIRDIR=`$PKG_CONFIG --variable=girdir gobject-introspection-1.0` - INTROSPECTION_TYPELIBDIR="$($PKG_CONFIG --variable=typelibdir gobject-introspection-1.0)" - INTROSPECTION_CFLAGS=`$PKG_CONFIG --cflags gobject-introspection-1.0` - INTROSPECTION_LIBS=`$PKG_CONFIG --libs gobject-introspection-1.0` - INTROSPECTION_MAKEFILE=`$PKG_CONFIG --variable=datadir gobject-introspection-1.0`/gobject-introspection-1.0/Makefile.introspection - fi - AC_SUBST(INTROSPECTION_SCANNER) - AC_SUBST(INTROSPECTION_COMPILER) - AC_SUBST(INTROSPECTION_GENERATE) - AC_SUBST(INTROSPECTION_GIRDIR) - AC_SUBST(INTROSPECTION_TYPELIBDIR) - AC_SUBST(INTROSPECTION_CFLAGS) - AC_SUBST(INTROSPECTION_LIBS) - AC_SUBST(INTROSPECTION_MAKEFILE) - - AM_CONDITIONAL(HAVE_INTROSPECTION, test "x$found_introspection" = "xyes") -]) - - -dnl Usage: -dnl GOBJECT_INTROSPECTION_CHECK([minimum-g-i-version]) - -AC_DEFUN([GOBJECT_INTROSPECTION_CHECK], -[ - _GOBJECT_INTROSPECTION_CHECK_INTERNAL([$1]) -]) - -dnl Usage: -dnl GOBJECT_INTROSPECTION_REQUIRE([minimum-g-i-version]) - - -AC_DEFUN([GOBJECT_INTROSPECTION_REQUIRE], -[ - _GOBJECT_INTROSPECTION_CHECK_INTERNAL([$1], [require]) -]) diff --git a/cogl/cogl-config.h.meson b/cogl/cogl-config.h.meson new file mode 100644 index 000000000..e9e4a0ec6 --- /dev/null +++ b/cogl/cogl-config.h.meson @@ -0,0 +1,16 @@ +/* Have GL for rendering */ +#mesondefine HAVE_COGL_GL + +/* Have GLES 2.0 for rendering */ +#mesondefine HAVE_COGL_GLES2 + +/* Building with Sysprof profiling suport */ +#mesondefine HAVE_TRACING + +/* Enable unit tests */ +#mesondefine ENABLE_UNIT_TESTS + +/* Default COGL driver */ +#mesondefine COGL_DEFAULT_DRIVER + +#define COGL_CONFIG_H_INCLUDED 1 diff --git a/cogl/cogl-gles2/GLES2/gl2.h b/cogl/cogl-gles2/GLES2/gl2.h deleted file mode 100644 index 718fb3b9b..000000000 --- a/cogl/cogl-gles2/GLES2/gl2.h +++ /dev/null @@ -1,169 +0,0 @@ -#ifndef __gl2_h_ -#define __gl2_h_ - -/* $Revision: 16803 $ on $Date:: 2012-02-02 09:49:18 -0800 #$ */ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * This document is licensed under the SGI Free Software B License Version - * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . - */ - -/*------------------------------------------------------------------------- - * GL core functions. - *-----------------------------------------------------------------------*/ - -GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture); -GL_APICALL void GL_APIENTRY glAttachShader (GLuint program, GLuint shader); -GL_APICALL void GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar* name); -GL_APICALL void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer); -GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer); -GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer); -GL_APICALL void GL_APIENTRY glBindTexture (GLenum target, GLuint texture); -GL_APICALL void GL_APIENTRY glBlendColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); -GL_APICALL void GL_APIENTRY glBlendEquation ( GLenum mode ); -GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha); -GL_APICALL void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor); -GL_APICALL void GL_APIENTRY glBlendFuncSeparate (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); -GL_APICALL void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage); -GL_APICALL void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data); -GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target); -GL_APICALL void GL_APIENTRY glClear (GLbitfield mask); -GL_APICALL void GL_APIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); -GL_APICALL void GL_APIENTRY glClearDepthf (GLclampf depth); -GL_APICALL void GL_APIENTRY glClearStencil (GLint s); -GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); -GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader); -GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data); -GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data); -GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -GL_APICALL GLuint GL_APIENTRY glCreateProgram (void); -GL_APICALL GLuint GL_APIENTRY glCreateShader (GLenum type); -GL_APICALL void GL_APIENTRY glCullFace (GLenum mode); -GL_APICALL void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint* buffers); -GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint* framebuffers); -GL_APICALL void GL_APIENTRY glDeleteProgram (GLuint program); -GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint* renderbuffers); -GL_APICALL void GL_APIENTRY glDeleteShader (GLuint shader); -GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint* textures); -GL_APICALL void GL_APIENTRY glDepthFunc (GLenum func); -GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag); -GL_APICALL void GL_APIENTRY glDepthRangef (GLclampf zNear, GLclampf zFar); -GL_APICALL void GL_APIENTRY glDetachShader (GLuint program, GLuint shader); -GL_APICALL void GL_APIENTRY glDisable (GLenum cap); -GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index); -GL_APICALL void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count); -GL_APICALL void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices); -GL_APICALL void GL_APIENTRY glEnable (GLenum cap); -GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index); -GL_APICALL void GL_APIENTRY glFinish (void); -GL_APICALL void GL_APIENTRY glFlush (void); -GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -GL_APICALL void GL_APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -GL_APICALL void GL_APIENTRY glFrontFace (GLenum mode); -GL_APICALL void GL_APIENTRY glGenBuffers (GLsizei n, GLuint* buffers); -GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenum target); -GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint* framebuffers); -GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint* renderbuffers); -GL_APICALL void GL_APIENTRY glGenTextures (GLsizei n, GLuint* textures); -GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name); -GL_APICALL void GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name); -GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders); -GL_APICALL int GL_APIENTRY glGetAttribLocation (GLuint program, const GLchar* name); -GL_APICALL void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean* params); -GL_APICALL void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint* params); -GL_APICALL GLenum GL_APIENTRY glGetError (void); -GL_APICALL void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat* params); -GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint* params); -GL_APICALL void GL_APIENTRY glGetIntegerv (GLenum pname, GLint* params); -GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint* params); -GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog); -GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint* params); -GL_APICALL void GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint* params); -GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog); -GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision); -GL_APICALL void GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source); -GL_APICALL const GLubyte* GL_APIENTRY glGetString (GLenum name); -GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat* params); -GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint* params); -GL_APICALL void GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat* params); -GL_APICALL void GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint* params); -GL_APICALL int GL_APIENTRY glGetUniformLocation (GLuint program, const GLchar* name); -GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat* params); -GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint* params); -GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, GLvoid** pointer); -GL_APICALL void GL_APIENTRY glHint (GLenum target, GLenum mode); -GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLuint buffer); -GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenum cap); -GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLuint framebuffer); -GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLuint program); -GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLuint renderbuffer); -GL_APICALL GLboolean GL_APIENTRY glIsShader (GLuint shader); -GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLuint texture); -GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width); -GL_APICALL void GL_APIENTRY glLinkProgram (GLuint program); -GL_APICALL void GL_APIENTRY glPixelStorei (GLenum pname, GLint param); -GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units); -GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels); -GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void); -GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); -GL_APICALL void GL_APIENTRY glSampleCoverage (GLclampf value, GLboolean invert); -GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); -GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length); -GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length); -GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); -GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask); -GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask); -GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask); -GL_APICALL void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); -GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum fail, GLenum zfail, GLenum zpass); -GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels); -GL_APICALL void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); -GL_APICALL void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat* params); -GL_APICALL void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); -GL_APICALL void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint* params); -GL_APICALL void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels); -GL_APICALL void GL_APIENTRY glUniform1f (GLint location, GLfloat x); -GL_APICALL void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat* v); -GL_APICALL void GL_APIENTRY glUniform1i (GLint location, GLint x); -GL_APICALL void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint* v); -GL_APICALL void GL_APIENTRY glUniform2f (GLint location, GLfloat x, GLfloat y); -GL_APICALL void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat* v); -GL_APICALL void GL_APIENTRY glUniform2i (GLint location, GLint x, GLint y); -GL_APICALL void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint* v); -GL_APICALL void GL_APIENTRY glUniform3f (GLint location, GLfloat x, GLfloat y, GLfloat z); -GL_APICALL void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat* v); -GL_APICALL void GL_APIENTRY glUniform3i (GLint location, GLint x, GLint y, GLint z); -GL_APICALL void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint* v); -GL_APICALL void GL_APIENTRY glUniform4f (GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GL_APICALL void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat* v); -GL_APICALL void GL_APIENTRY glUniform4i (GLint location, GLint x, GLint y, GLint z, GLint w); -GL_APICALL void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint* v); -GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -GL_APICALL void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -GL_APICALL void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -GL_APICALL void GL_APIENTRY glUseProgram (GLuint program); -GL_APICALL void GL_APIENTRY glValidateProgram (GLuint program); -GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint indx, GLfloat x); -GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint indx, const GLfloat* values); -GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint indx, GLfloat x, GLfloat y); -GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint indx, const GLfloat* values); -GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint indx, GLfloat x, GLfloat y, GLfloat z); -GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint indx, const GLfloat* values); -GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint indx, const GLfloat* values); -GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr); -GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); - -#ifdef __cplusplus -} -#endif - -#endif /* __gl2_h_ */ diff --git a/cogl/cogl-gles2/GLES2/gl2ext.h b/cogl/cogl-gles2/GLES2/gl2ext.h deleted file mode 100644 index e4016a5ad..000000000 --- a/cogl/cogl-gles2/GLES2/gl2ext.h +++ /dev/null @@ -1,1498 +0,0 @@ -#ifndef __gl2ext_h_ -#define __gl2ext_h_ - -/* $Revision: 16994 $ on $Date:: 2012-02-29 18:29:34 -0800 #$ */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * This document is licensed under the SGI Free Software B License Version - * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . - */ - -#ifndef GL_APIENTRYP -# define GL_APIENTRYP GL_APIENTRY* -#endif - -/*------------------------------------------------------------------------* - * OES extension tokens - *------------------------------------------------------------------------*/ - -/* GL_OES_compressed_ETC1_RGB8_texture */ -#ifndef GL_OES_compressed_ETC1_RGB8_texture -#define GL_ETC1_RGB8_OES 0x8D64 -#endif - -/* GL_OES_compressed_paletted_texture */ -#ifndef GL_OES_compressed_paletted_texture -#define GL_PALETTE4_RGB8_OES 0x8B90 -#define GL_PALETTE4_RGBA8_OES 0x8B91 -#define GL_PALETTE4_R5_G6_B5_OES 0x8B92 -#define GL_PALETTE4_RGBA4_OES 0x8B93 -#define GL_PALETTE4_RGB5_A1_OES 0x8B94 -#define GL_PALETTE8_RGB8_OES 0x8B95 -#define GL_PALETTE8_RGBA8_OES 0x8B96 -#define GL_PALETTE8_R5_G6_B5_OES 0x8B97 -#define GL_PALETTE8_RGBA4_OES 0x8B98 -#define GL_PALETTE8_RGB5_A1_OES 0x8B99 -#endif - -/* GL_OES_depth24 */ -#ifndef GL_OES_depth24 -#define GL_DEPTH_COMPONENT24_OES 0x81A6 -#endif - -/* GL_OES_depth32 */ -#ifndef GL_OES_depth32 -#define GL_DEPTH_COMPONENT32_OES 0x81A7 -#endif - -/* GL_OES_depth_texture */ -/* No new tokens introduced by this extension. */ - -/* GL_OES_EGL_image */ -#ifndef GL_OES_EGL_image -typedef void* GLeglImageOES; -#endif - -/* GL_OES_EGL_image_external */ -#ifndef GL_OES_EGL_image_external -/* GLeglImageOES defined in GL_OES_EGL_image already. */ -#define GL_TEXTURE_EXTERNAL_OES 0x8D65 -#define GL_SAMPLER_EXTERNAL_OES 0x8D66 -#define GL_TEXTURE_BINDING_EXTERNAL_OES 0x8D67 -#define GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES 0x8D68 -#endif - -/* GL_OES_element_index_uint */ -#ifndef GL_OES_element_index_uint -#define GL_UNSIGNED_INT 0x1405 -#endif - -/* GL_OES_get_program_binary */ -#ifndef GL_OES_get_program_binary -#define GL_PROGRAM_BINARY_LENGTH_OES 0x8741 -#define GL_NUM_PROGRAM_BINARY_FORMATS_OES 0x87FE -#define GL_PROGRAM_BINARY_FORMATS_OES 0x87FF -#endif - -/* GL_OES_mapbuffer */ -#ifndef GL_OES_mapbuffer -#define GL_WRITE_ONLY_OES 0x88B9 -#define GL_BUFFER_ACCESS_OES 0x88BB -#define GL_BUFFER_MAPPED_OES 0x88BC -#define GL_BUFFER_MAP_POINTER_OES 0x88BD -#endif - -/* GL_OES_packed_depth_stencil */ -#ifndef GL_OES_packed_depth_stencil -#define GL_DEPTH_STENCIL_OES 0x84F9 -#define GL_UNSIGNED_INT_24_8_OES 0x84FA -#define GL_DEPTH24_STENCIL8_OES 0x88F0 -#endif - -/* GL_OES_rgb8_rgba8 */ -#ifndef GL_OES_rgb8_rgba8 -#define GL_RGB8_OES 0x8051 -#define GL_RGBA8_OES 0x8058 -#endif - -/* GL_OES_standard_derivatives */ -#ifndef GL_OES_standard_derivatives -#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES 0x8B8B -#endif - -/* GL_OES_stencil1 */ -#ifndef GL_OES_stencil1 -#define GL_STENCIL_INDEX1_OES 0x8D46 -#endif - -/* GL_OES_stencil4 */ -#ifndef GL_OES_stencil4 -#define GL_STENCIL_INDEX4_OES 0x8D47 -#endif - -/* GL_OES_texture_3D */ -#ifndef GL_OES_texture_3D -#define GL_TEXTURE_WRAP_R_OES 0x8072 -#define GL_TEXTURE_3D_OES 0x806F -#define GL_TEXTURE_BINDING_3D_OES 0x806A -#define GL_MAX_3D_TEXTURE_SIZE_OES 0x8073 -#define GL_SAMPLER_3D_OES 0x8B5F -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES 0x8CD4 -#endif - -/* GL_OES_texture_float */ -/* No new tokens introduced by this extension. */ - -/* GL_OES_texture_float_linear */ -/* No new tokens introduced by this extension. */ - -/* GL_OES_texture_half_float */ -#ifndef GL_OES_texture_half_float -#define GL_HALF_FLOAT_OES 0x8D61 -#endif - -/* GL_OES_texture_half_float_linear */ -/* No new tokens introduced by this extension. */ - -/* GL_OES_texture_npot */ -/* No new tokens introduced by this extension. */ - -/* GL_OES_vertex_array_object */ -#ifndef GL_OES_vertex_array_object -#define GL_VERTEX_ARRAY_BINDING_OES 0x85B5 -#endif - -/* GL_OES_vertex_half_float */ -/* GL_HALF_FLOAT_OES defined in GL_OES_texture_half_float already. */ - -/* GL_OES_vertex_type_10_10_10_2 */ -#ifndef GL_OES_vertex_type_10_10_10_2 -#define GL_UNSIGNED_INT_10_10_10_2_OES 0x8DF6 -#define GL_INT_10_10_10_2_OES 0x8DF7 -#endif - -/*------------------------------------------------------------------------* - * AMD extension tokens - *------------------------------------------------------------------------*/ - -/* GL_AMD_compressed_3DC_texture */ -#ifndef GL_AMD_compressed_3DC_texture -#define GL_3DC_X_AMD 0x87F9 -#define GL_3DC_XY_AMD 0x87FA -#endif - -/* GL_AMD_compressed_ATC_texture */ -#ifndef GL_AMD_compressed_ATC_texture -#define GL_ATC_RGB_AMD 0x8C92 -#define GL_ATC_RGBA_EXPLICIT_ALPHA_AMD 0x8C93 -#define GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE -#endif - -/* GL_AMD_performance_monitor */ -#ifndef GL_AMD_performance_monitor -#define GL_COUNTER_TYPE_AMD 0x8BC0 -#define GL_COUNTER_RANGE_AMD 0x8BC1 -#define GL_UNSIGNED_INT64_AMD 0x8BC2 -#define GL_PERCENTAGE_AMD 0x8BC3 -#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4 -#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5 -#define GL_PERFMON_RESULT_AMD 0x8BC6 -#endif - -/* GL_AMD_program_binary_Z400 */ -#ifndef GL_AMD_program_binary_Z400 -#define GL_Z400_BINARY_AMD 0x8740 -#endif - -/*------------------------------------------------------------------------* - * ANGLE extension tokens - *------------------------------------------------------------------------*/ - -/* GL_ANGLE_framebuffer_blit */ -#ifndef GL_ANGLE_framebuffer_blit -#define GL_READ_FRAMEBUFFER_ANGLE 0x8CA8 -#define GL_DRAW_FRAMEBUFFER_ANGLE 0x8CA9 -#define GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 0x8CA6 -#define GL_READ_FRAMEBUFFER_BINDING_ANGLE 0x8CAA -#endif - -/* GL_ANGLE_framebuffer_multisample */ -#ifndef GL_ANGLE_framebuffer_multisample -#define GL_RENDERBUFFER_SAMPLES_ANGLE 0x8CAB -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE 0x8D56 -#define GL_MAX_SAMPLES_ANGLE 0x8D57 -#endif - -/* GL_ANGLE_instanced_arrays */ -#ifndef GL_ANGLE_instanced_arrays -#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 0x88FE -#endif - -/* GL_ANGLE_pack_reverse_row_order */ -#ifndef GL_ANGLE_pack_reverse_row_order -#define GL_PACK_REVERSE_ROW_ORDER_ANGLE 0x93A4 -#endif - -/* GL_ANGLE_texture_compression_dxt3 */ -#ifndef GL_ANGLE_texture_compression_dxt3 -#define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2 -#endif - -/* GL_ANGLE_texture_compression_dxt5 */ -#ifndef GL_ANGLE_texture_compression_dxt5 -#define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE 0x83F3 -#endif - -/* GL_ANGLE_texture_usage */ -#ifndef GL_ANGLE_texture_usage -#define GL_TEXTURE_USAGE_ANGLE 0x93A2 -#define GL_FRAMEBUFFER_ATTACHMENT_ANGLE 0x93A3 -#endif - -/* GL_ANGLE_translated_shader_source */ -#ifndef GL_ANGLE_translated_shader_source -#define GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE 0x93A0 -#endif - -/*------------------------------------------------------------------------* - * APPLE extension tokens - *------------------------------------------------------------------------*/ - -/* GL_APPLE_rgb_422 */ -#ifndef GL_APPLE_rgb_422 -#define GL_RGB_422_APPLE 0x8A1F -#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA -#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB -#endif - -/* GL_APPLE_framebuffer_multisample */ -#ifndef GL_APPLE_framebuffer_multisample -#define GL_RENDERBUFFER_SAMPLES_APPLE 0x8CAB -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE 0x8D56 -#define GL_MAX_SAMPLES_APPLE 0x8D57 -#define GL_READ_FRAMEBUFFER_APPLE 0x8CA8 -#define GL_DRAW_FRAMEBUFFER_APPLE 0x8CA9 -#define GL_DRAW_FRAMEBUFFER_BINDING_APPLE 0x8CA6 -#define GL_READ_FRAMEBUFFER_BINDING_APPLE 0x8CAA -#endif - -/* GL_APPLE_texture_format_BGRA8888 */ -#ifndef GL_APPLE_texture_format_BGRA8888 -#define GL_BGRA_EXT 0x80E1 -#endif - -/* GL_APPLE_texture_max_level */ -#ifndef GL_APPLE_texture_max_level -#define GL_TEXTURE_MAX_LEVEL_APPLE 0x813D -#endif - -/*------------------------------------------------------------------------* - * ARM extension tokens - *------------------------------------------------------------------------*/ - -/* GL_ARM_mali_shader_binary */ -#ifndef GL_ARM_mali_shader_binary -#define GL_MALI_SHADER_BINARY_ARM 0x8F60 -#endif - -/* GL_ARM_rgba8 */ -/* No new tokens introduced by this extension. */ - -/*------------------------------------------------------------------------* - * EXT extension tokens - *------------------------------------------------------------------------*/ - -/* GL_EXT_blend_minmax */ -#ifndef GL_EXT_blend_minmax -#define GL_MIN_EXT 0x8007 -#define GL_MAX_EXT 0x8008 -#endif - -/* GL_EXT_color_buffer_half_float */ -#ifndef GL_EXT_color_buffer_half_float -#define GL_RGBA16F_EXT 0x881A -#define GL_RGB16F_EXT 0x881B -#define GL_RG16F_EXT 0x822F -#define GL_R16F_EXT 0x822D -#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT 0x8211 -#define GL_UNSIGNED_NORMALIZED_EXT 0x8C17 -#endif - -/* GL_EXT_debug_label */ -#ifndef GL_EXT_debug_label -#define GL_PROGRAM_PIPELINE_OBJECT_EXT 0x8A4F -#define GL_PROGRAM_OBJECT_EXT 0x8B40 -#define GL_SHADER_OBJECT_EXT 0x8B48 -#define GL_BUFFER_OBJECT_EXT 0x9151 -#define GL_QUERY_OBJECT_EXT 0x9153 -#define GL_VERTEX_ARRAY_OBJECT_EXT 0x9154 -#endif - -/* GL_EXT_debug_marker */ -/* No new tokens introduced by this extension. */ - -/* GL_EXT_discard_framebuffer */ -#ifndef GL_EXT_discard_framebuffer -#define GL_COLOR_EXT 0x1800 -#define GL_DEPTH_EXT 0x1801 -#define GL_STENCIL_EXT 0x1802 -#endif - -/* GL_EXT_multisampled_render_to_texture */ -#ifndef GL_EXT_multisampled_render_to_texture -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT 0x8D6C -#define GL_RENDERBUFFER_SAMPLES_EXT 0x9133 -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x9134 -#define GL_MAX_SAMPLES_EXT 0x9135 -#endif - -/* GL_EXT_multi_draw_arrays */ -/* No new tokens introduced by this extension. */ - -/* GL_EXT_occlusion_query_boolean */ -#ifndef GL_EXT_occlusion_query_boolean -#define GL_ANY_SAMPLES_PASSED_EXT 0x8C2F -#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT 0x8D6A -#define GL_CURRENT_QUERY_EXT 0x8865 -#define GL_QUERY_RESULT_EXT 0x8866 -#define GL_QUERY_RESULT_AVAILABLE_EXT 0x8867 -#endif - -/* GL_EXT_read_format_bgra */ -#ifndef GL_EXT_read_format_bgra -#define GL_BGRA_EXT 0x80E1 -#define GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT 0x8365 -#define GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT 0x8366 -#endif - -/* GL_EXT_robustness */ -#ifndef GL_EXT_robustness -/* reuse GL_NO_ERROR */ -#define GL_GUILTY_CONTEXT_RESET_EXT 0x8253 -#define GL_INNOCENT_CONTEXT_RESET_EXT 0x8254 -#define GL_UNKNOWN_CONTEXT_RESET_EXT 0x8255 -#define GL_CONTEXT_ROBUST_ACCESS_EXT 0x90F3 -#define GL_RESET_NOTIFICATION_STRATEGY_EXT 0x8256 -#define GL_LOSE_CONTEXT_ON_RESET_EXT 0x8252 -#define GL_NO_RESET_NOTIFICATION_EXT 0x8261 -#endif - -/* GL_EXT_separate_shader_objects */ -#ifndef GL_EXT_separate_shader_objects -#define GL_VERTEX_SHADER_BIT_EXT 0x00000001 -#define GL_FRAGMENT_SHADER_BIT_EXT 0x00000002 -#define GL_ALL_SHADER_BITS_EXT 0xFFFFFFFF -#define GL_PROGRAM_SEPARABLE_EXT 0x8258 -#define GL_ACTIVE_PROGRAM_EXT 0x8259 -#define GL_PROGRAM_PIPELINE_BINDING_EXT 0x825A -#endif - -/* GL_EXT_shader_texture_lod */ -/* No new tokens introduced by this extension. */ - -/* GL_EXT_shadow_samplers */ -#ifndef GL_EXT_shadow_samplers -#define GL_TEXTURE_COMPARE_MODE_EXT 0x884C -#define GL_TEXTURE_COMPARE_FUNC_EXT 0x884D -#define GL_COMPARE_REF_TO_TEXTURE_EXT 0x884E -#define GL_SAMPLER_2D_SHADOW_EXT 0x8B62 -#endif - -/* GL_EXT_sRGB */ -#ifndef GL_EXT_sRGB -#define GL_SRGB_EXT 0x8C40 -#define GL_SRGB_ALPHA_EXT 0x8C42 -#define GL_SRGB8_ALPHA8_EXT 0x8C43 -#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT 0x8210 -#endif - -/* GL_EXT_texture_compression_dxt1 */ -#ifndef GL_EXT_texture_compression_dxt1 -#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 -#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 -#endif - -/* GL_EXT_texture_filter_anisotropic */ -#ifndef GL_EXT_texture_filter_anisotropic -#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE -#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF -#endif - -/* GL_EXT_texture_format_BGRA8888 */ -#ifndef GL_EXT_texture_format_BGRA8888 -#define GL_BGRA_EXT 0x80E1 -#endif - -/* GL_EXT_texture_rg */ -#ifndef GL_EXT_texture_rg -#define GL_RED_EXT 0x1903 -#define GL_RG_EXT 0x8227 -#define GL_R8_EXT 0x8229 -#define GL_RG8_EXT 0x822B -#endif - -/* GL_EXT_texture_storage */ -#ifndef GL_EXT_texture_storage -#define GL_TEXTURE_IMMUTABLE_FORMAT_EXT 0x912F -#define GL_ALPHA8_EXT 0x803C -#define GL_LUMINANCE8_EXT 0x8040 -#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 -#define GL_RGBA32F_EXT 0x8814 -#define GL_RGB32F_EXT 0x8815 -#define GL_ALPHA32F_EXT 0x8816 -#define GL_LUMINANCE32F_EXT 0x8818 -#define GL_LUMINANCE_ALPHA32F_EXT 0x8819 -/* reuse GL_RGBA16F_EXT */ -/* reuse GL_RGB16F_EXT */ -#define GL_ALPHA16F_EXT 0x881C -#define GL_LUMINANCE16F_EXT 0x881E -#define GL_LUMINANCE_ALPHA16F_EXT 0x881F -#define GL_RGB10_A2_EXT 0x8059 -#define GL_RGB10_EXT 0x8052 -#define GL_BGRA8_EXT 0x93A1 -#define GL_R8_EXT 0x8229 -#define GL_RG8_EXT 0x822B -#define GL_R32F_EXT 0x822E -#define GL_RG32F_EXT 0x8230 -#define GL_R16F_EXT 0x822D -#define GL_RG16F_EXT 0x822F -#endif - -/* GL_EXT_texture_type_2_10_10_10_REV */ -#ifndef GL_EXT_texture_type_2_10_10_10_REV -#define GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368 -#endif - -/* GL_EXT_unpack_subimage */ -#ifndef GL_EXT_unpack_subimage -#define GL_UNPACK_ROW_LENGTH 0x0CF2 -#define GL_UNPACK_SKIP_ROWS 0x0CF3 -#define GL_UNPACK_SKIP_PIXELS 0x0CF4 -#endif - -/*------------------------------------------------------------------------* - * DMP extension tokens - *------------------------------------------------------------------------*/ - -/* GL_DMP_shader_binary */ -#ifndef GL_DMP_shader_binary -#define GL_SHADER_BINARY_DMP 0x9250 -#endif - -/*------------------------------------------------------------------------* - * IMG extension tokens - *------------------------------------------------------------------------*/ - -/* GL_IMG_program_binary */ -#ifndef GL_IMG_program_binary -#define GL_SGX_PROGRAM_BINARY_IMG 0x9130 -#endif - -/* GL_IMG_read_format */ -#ifndef GL_IMG_read_format -#define GL_BGRA_IMG 0x80E1 -#define GL_UNSIGNED_SHORT_4_4_4_4_REV_IMG 0x8365 -#endif - -/* GL_IMG_shader_binary */ -#ifndef GL_IMG_shader_binary -#define GL_SGX_BINARY_IMG 0x8C0A -#endif - -/* GL_IMG_texture_compression_pvrtc */ -#ifndef GL_IMG_texture_compression_pvrtc -#define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00 -#define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01 -#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02 -#define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03 -#endif - -/* GL_IMG_multisampled_render_to_texture */ -#ifndef GL_IMG_multisampled_render_to_texture -#define GL_RENDERBUFFER_SAMPLES_IMG 0x9133 -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG 0x9134 -#define GL_MAX_SAMPLES_IMG 0x9135 -#define GL_TEXTURE_SAMPLES_IMG 0x9136 -#endif - -/*------------------------------------------------------------------------* - * NV extension tokens - *------------------------------------------------------------------------*/ - -/* GL_NV_coverage_sample */ -#ifndef GL_NV_coverage_sample -#define GL_COVERAGE_COMPONENT_NV 0x8ED0 -#define GL_COVERAGE_COMPONENT4_NV 0x8ED1 -#define GL_COVERAGE_ATTACHMENT_NV 0x8ED2 -#define GL_COVERAGE_BUFFERS_NV 0x8ED3 -#define GL_COVERAGE_SAMPLES_NV 0x8ED4 -#define GL_COVERAGE_ALL_FRAGMENTS_NV 0x8ED5 -#define GL_COVERAGE_EDGE_FRAGMENTS_NV 0x8ED6 -#define GL_COVERAGE_AUTOMATIC_NV 0x8ED7 -#define GL_COVERAGE_BUFFER_BIT_NV 0x8000 -#endif - -/* GL_NV_depth_nonlinear */ -#ifndef GL_NV_depth_nonlinear -#define GL_DEPTH_COMPONENT16_NONLINEAR_NV 0x8E2C -#endif - -/* GL_NV_draw_buffers */ -#ifndef GL_NV_draw_buffers -#define GL_MAX_DRAW_BUFFERS_NV 0x8824 -#define GL_DRAW_BUFFER0_NV 0x8825 -#define GL_DRAW_BUFFER1_NV 0x8826 -#define GL_DRAW_BUFFER2_NV 0x8827 -#define GL_DRAW_BUFFER3_NV 0x8828 -#define GL_DRAW_BUFFER4_NV 0x8829 -#define GL_DRAW_BUFFER5_NV 0x882A -#define GL_DRAW_BUFFER6_NV 0x882B -#define GL_DRAW_BUFFER7_NV 0x882C -#define GL_DRAW_BUFFER8_NV 0x882D -#define GL_DRAW_BUFFER9_NV 0x882E -#define GL_DRAW_BUFFER10_NV 0x882F -#define GL_DRAW_BUFFER11_NV 0x8830 -#define GL_DRAW_BUFFER12_NV 0x8831 -#define GL_DRAW_BUFFER13_NV 0x8832 -#define GL_DRAW_BUFFER14_NV 0x8833 -#define GL_DRAW_BUFFER15_NV 0x8834 -#define GL_COLOR_ATTACHMENT0_NV 0x8CE0 -#define GL_COLOR_ATTACHMENT1_NV 0x8CE1 -#define GL_COLOR_ATTACHMENT2_NV 0x8CE2 -#define GL_COLOR_ATTACHMENT3_NV 0x8CE3 -#define GL_COLOR_ATTACHMENT4_NV 0x8CE4 -#define GL_COLOR_ATTACHMENT5_NV 0x8CE5 -#define GL_COLOR_ATTACHMENT6_NV 0x8CE6 -#define GL_COLOR_ATTACHMENT7_NV 0x8CE7 -#define GL_COLOR_ATTACHMENT8_NV 0x8CE8 -#define GL_COLOR_ATTACHMENT9_NV 0x8CE9 -#define GL_COLOR_ATTACHMENT10_NV 0x8CEA -#define GL_COLOR_ATTACHMENT11_NV 0x8CEB -#define GL_COLOR_ATTACHMENT12_NV 0x8CEC -#define GL_COLOR_ATTACHMENT13_NV 0x8CED -#define GL_COLOR_ATTACHMENT14_NV 0x8CEE -#define GL_COLOR_ATTACHMENT15_NV 0x8CEF -#endif - -/* GL_NV_fbo_color_attachments */ -#ifndef GL_NV_fbo_color_attachments -#define GL_MAX_COLOR_ATTACHMENTS_NV 0x8CDF -/* GL_COLOR_ATTACHMENT{0-15}_NV defined in GL_NV_draw_buffers already. */ -#endif - -/* GL_NV_fence */ -#ifndef GL_NV_fence -#define GL_ALL_COMPLETED_NV 0x84F2 -#define GL_FENCE_STATUS_NV 0x84F3 -#define GL_FENCE_CONDITION_NV 0x84F4 -#endif - -/* GL_NV_read_buffer */ -#ifndef GL_NV_read_buffer -#define GL_READ_BUFFER_NV 0x0C02 -#endif - -/* GL_NV_read_buffer_front */ -/* No new tokens introduced by this extension. */ - -/* GL_NV_read_depth */ -/* No new tokens introduced by this extension. */ - -/* GL_NV_read_depth_stencil */ -/* No new tokens introduced by this extension. */ - -/* GL_NV_read_stencil */ -/* No new tokens introduced by this extension. */ - -/* GL_NV_texture_compression_s3tc_update */ -/* No new tokens introduced by this extension. */ - -/* GL_NV_texture_npot_2D_mipmap */ -/* No new tokens introduced by this extension. */ - -/*------------------------------------------------------------------------* - * QCOM extension tokens - *------------------------------------------------------------------------*/ - -/* GL_QCOM_alpha_test */ -#ifndef GL_QCOM_alpha_test -#define GL_ALPHA_TEST_QCOM 0x0BC0 -#define GL_ALPHA_TEST_FUNC_QCOM 0x0BC1 -#define GL_ALPHA_TEST_REF_QCOM 0x0BC2 -#endif - -/* GL_QCOM_driver_control */ -/* No new tokens introduced by this extension. */ - -/* GL_QCOM_extended_get */ -#ifndef GL_QCOM_extended_get -#define GL_TEXTURE_WIDTH_QCOM 0x8BD2 -#define GL_TEXTURE_HEIGHT_QCOM 0x8BD3 -#define GL_TEXTURE_DEPTH_QCOM 0x8BD4 -#define GL_TEXTURE_INTERNAL_FORMAT_QCOM 0x8BD5 -#define GL_TEXTURE_FORMAT_QCOM 0x8BD6 -#define GL_TEXTURE_TYPE_QCOM 0x8BD7 -#define GL_TEXTURE_IMAGE_VALID_QCOM 0x8BD8 -#define GL_TEXTURE_NUM_LEVELS_QCOM 0x8BD9 -#define GL_TEXTURE_TARGET_QCOM 0x8BDA -#define GL_TEXTURE_OBJECT_VALID_QCOM 0x8BDB -#define GL_STATE_RESTORE 0x8BDC -#endif - -/* GL_QCOM_extended_get2 */ -/* No new tokens introduced by this extension. */ - -/* GL_QCOM_perfmon_global_mode */ -#ifndef GL_QCOM_perfmon_global_mode -#define GL_PERFMON_GLOBAL_MODE_QCOM 0x8FA0 -#endif - -/* GL_QCOM_writeonly_rendering */ -#ifndef GL_QCOM_writeonly_rendering -#define GL_WRITEONLY_RENDERING_QCOM 0x8823 -#endif - -/* GL_QCOM_tiled_rendering */ -#ifndef GL_QCOM_tiled_rendering -#define GL_COLOR_BUFFER_BIT0_QCOM 0x00000001 -#define GL_COLOR_BUFFER_BIT1_QCOM 0x00000002 -#define GL_COLOR_BUFFER_BIT2_QCOM 0x00000004 -#define GL_COLOR_BUFFER_BIT3_QCOM 0x00000008 -#define GL_COLOR_BUFFER_BIT4_QCOM 0x00000010 -#define GL_COLOR_BUFFER_BIT5_QCOM 0x00000020 -#define GL_COLOR_BUFFER_BIT6_QCOM 0x00000040 -#define GL_COLOR_BUFFER_BIT7_QCOM 0x00000080 -#define GL_DEPTH_BUFFER_BIT0_QCOM 0x00000100 -#define GL_DEPTH_BUFFER_BIT1_QCOM 0x00000200 -#define GL_DEPTH_BUFFER_BIT2_QCOM 0x00000400 -#define GL_DEPTH_BUFFER_BIT3_QCOM 0x00000800 -#define GL_DEPTH_BUFFER_BIT4_QCOM 0x00001000 -#define GL_DEPTH_BUFFER_BIT5_QCOM 0x00002000 -#define GL_DEPTH_BUFFER_BIT6_QCOM 0x00004000 -#define GL_DEPTH_BUFFER_BIT7_QCOM 0x00008000 -#define GL_STENCIL_BUFFER_BIT0_QCOM 0x00010000 -#define GL_STENCIL_BUFFER_BIT1_QCOM 0x00020000 -#define GL_STENCIL_BUFFER_BIT2_QCOM 0x00040000 -#define GL_STENCIL_BUFFER_BIT3_QCOM 0x00080000 -#define GL_STENCIL_BUFFER_BIT4_QCOM 0x00100000 -#define GL_STENCIL_BUFFER_BIT5_QCOM 0x00200000 -#define GL_STENCIL_BUFFER_BIT6_QCOM 0x00400000 -#define GL_STENCIL_BUFFER_BIT7_QCOM 0x00800000 -#define GL_MULTISAMPLE_BUFFER_BIT0_QCOM 0x01000000 -#define GL_MULTISAMPLE_BUFFER_BIT1_QCOM 0x02000000 -#define GL_MULTISAMPLE_BUFFER_BIT2_QCOM 0x04000000 -#define GL_MULTISAMPLE_BUFFER_BIT3_QCOM 0x08000000 -#define GL_MULTISAMPLE_BUFFER_BIT4_QCOM 0x10000000 -#define GL_MULTISAMPLE_BUFFER_BIT5_QCOM 0x20000000 -#define GL_MULTISAMPLE_BUFFER_BIT6_QCOM 0x40000000 -#define GL_MULTISAMPLE_BUFFER_BIT7_QCOM 0x80000000 -#endif - -/*------------------------------------------------------------------------* - * VIV extension tokens - *------------------------------------------------------------------------*/ - -/* GL_VIV_shader_binary */ -#ifndef GL_VIV_shader_binary -#define GL_SHADER_BINARY_VIV 0x8FC4 -#endif - -/*------------------------------------------------------------------------* - * End of extension tokens, start of corresponding extension functions - *------------------------------------------------------------------------*/ - -/*------------------------------------------------------------------------* - * OES extension functions - *------------------------------------------------------------------------*/ - -/* GL_OES_compressed_ETC1_RGB8_texture */ -#ifndef GL_OES_compressed_ETC1_RGB8_texture -#define GL_OES_compressed_ETC1_RGB8_texture 1 -#endif - -/* GL_OES_compressed_paletted_texture */ -#ifndef GL_OES_compressed_paletted_texture -#define GL_OES_compressed_paletted_texture 1 -#endif - -/* GL_OES_depth24 */ -#ifndef GL_OES_depth24 -#define GL_OES_depth24 1 -#endif - -/* GL_OES_depth32 */ -#ifndef GL_OES_depth32 -#define GL_OES_depth32 1 -#endif - -/* GL_OES_depth_texture */ -#ifndef GL_OES_depth_texture -#define GL_OES_depth_texture 1 -#endif - -/* GL_OES_EGL_image */ -#ifndef GL_OES_EGL_image -#define GL_OES_EGL_image 1 -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glEGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image); -GL_APICALL void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image); -#endif -typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image); -typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image); -#endif - -/* GL_OES_EGL_image_external */ -#ifndef GL_OES_EGL_image_external -#define GL_OES_EGL_image_external 1 -/* glEGLImageTargetTexture2DOES defined in GL_OES_EGL_image already. */ -#endif - -/* GL_OES_element_index_uint */ -#ifndef GL_OES_element_index_uint -#define GL_OES_element_index_uint 1 -#endif - -/* GL_OES_fbo_render_mipmap */ -#ifndef GL_OES_fbo_render_mipmap -#define GL_OES_fbo_render_mipmap 1 -#endif - -/* GL_OES_fragment_precision_high */ -#ifndef GL_OES_fragment_precision_high -#define GL_OES_fragment_precision_high 1 -#endif - -/* GL_OES_get_program_binary */ -#ifndef GL_OES_get_program_binary -#define GL_OES_get_program_binary 1 -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glGetProgramBinaryOES (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary); -GL_APICALL void GL_APIENTRY glProgramBinaryOES (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length); -#endif -typedef void (GL_APIENTRYP PFNGLGETPROGRAMBINARYOESPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary); -typedef void (GL_APIENTRYP PFNGLPROGRAMBINARYOESPROC) (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length); -#endif - -/* GL_OES_mapbuffer */ -#ifndef GL_OES_mapbuffer -#define GL_OES_mapbuffer 1 -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void* GL_APIENTRY glMapBufferOES (GLenum target, GLenum access); -GL_APICALL GLboolean GL_APIENTRY glUnmapBufferOES (GLenum target); -GL_APICALL void GL_APIENTRY glGetBufferPointervOES (GLenum target, GLenum pname, GLvoid** params); -#endif -typedef void* (GL_APIENTRYP PFNGLMAPBUFFEROESPROC) (GLenum target, GLenum access); -typedef GLboolean (GL_APIENTRYP PFNGLUNMAPBUFFEROESPROC) (GLenum target); -typedef void (GL_APIENTRYP PFNGLGETBUFFERPOINTERVOESPROC) (GLenum target, GLenum pname, GLvoid** params); -#endif - -/* GL_OES_packed_depth_stencil */ -#ifndef GL_OES_packed_depth_stencil -#define GL_OES_packed_depth_stencil 1 -#endif - -/* GL_OES_rgb8_rgba8 */ -#ifndef GL_OES_rgb8_rgba8 -#define GL_OES_rgb8_rgba8 1 -#endif - -/* GL_OES_standard_derivatives */ -#ifndef GL_OES_standard_derivatives -#define GL_OES_standard_derivatives 1 -#endif - -/* GL_OES_stencil1 */ -#ifndef GL_OES_stencil1 -#define GL_OES_stencil1 1 -#endif - -/* GL_OES_stencil4 */ -#ifndef GL_OES_stencil4 -#define GL_OES_stencil4 1 -#endif - -/* GL_OES_texture_3D */ -#ifndef GL_OES_texture_3D -#define GL_OES_texture_3D 1 -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glTexImage3DOES (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels); -GL_APICALL void GL_APIENTRY glTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels); -GL_APICALL void GL_APIENTRY glCopyTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -GL_APICALL void GL_APIENTRY glCompressedTexImage3DOES (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data); -GL_APICALL void GL_APIENTRY glCompressedTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data); -GL_APICALL void GL_APIENTRY glFramebufferTexture3DOES (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); -#endif -typedef void (GL_APIENTRYP PFNGLTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels); -typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels); -typedef void (GL_APIENTRYP PFNGLCOPYTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data); -typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data); -typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DOES) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); -#endif - -/* GL_OES_texture_float */ -#ifndef GL_OES_texture_float -#define GL_OES_texture_float 1 -#endif - -/* GL_OES_texture_float_linear */ -#ifndef GL_OES_texture_float_linear -#define GL_OES_texture_float_linear 1 -#endif - -/* GL_OES_texture_half_float */ -#ifndef GL_OES_texture_half_float -#define GL_OES_texture_half_float 1 -#endif - -/* GL_OES_texture_half_float_linear */ -#ifndef GL_OES_texture_half_float_linear -#define GL_OES_texture_half_float_linear 1 -#endif - -/* GL_OES_texture_npot */ -#ifndef GL_OES_texture_npot -#define GL_OES_texture_npot 1 -#endif - -/* GL_OES_vertex_array_object */ -#ifndef GL_OES_vertex_array_object -#define GL_OES_vertex_array_object 1 -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glBindVertexArrayOES (GLuint array); -GL_APICALL void GL_APIENTRY glDeleteVertexArraysOES (GLsizei n, const GLuint *arrays); -GL_APICALL void GL_APIENTRY glGenVertexArraysOES (GLsizei n, GLuint *arrays); -GL_APICALL GLboolean GL_APIENTRY glIsVertexArrayOES (GLuint array); -#endif -typedef void (GL_APIENTRYP PFNGLBINDVERTEXARRAYOESPROC) (GLuint array); -typedef void (GL_APIENTRYP PFNGLDELETEVERTEXARRAYSOESPROC) (GLsizei n, const GLuint *arrays); -typedef void (GL_APIENTRYP PFNGLGENVERTEXARRAYSOESPROC) (GLsizei n, GLuint *arrays); -typedef GLboolean (GL_APIENTRYP PFNGLISVERTEXARRAYOESPROC) (GLuint array); -#endif - -/* GL_OES_vertex_half_float */ -#ifndef GL_OES_vertex_half_float -#define GL_OES_vertex_half_float 1 -#endif - -/* GL_OES_vertex_type_10_10_10_2 */ -#ifndef GL_OES_vertex_type_10_10_10_2 -#define GL_OES_vertex_type_10_10_10_2 1 -#endif - -/*------------------------------------------------------------------------* - * AMD extension functions - *------------------------------------------------------------------------*/ - -/* GL_AMD_compressed_3DC_texture */ -#ifndef GL_AMD_compressed_3DC_texture -#define GL_AMD_compressed_3DC_texture 1 -#endif - -/* GL_AMD_compressed_ATC_texture */ -#ifndef GL_AMD_compressed_ATC_texture -#define GL_AMD_compressed_ATC_texture 1 -#endif - -/* AMD_performance_monitor */ -#ifndef GL_AMD_performance_monitor -#define GL_AMD_performance_monitor 1 -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glGetPerfMonitorGroupsAMD (GLint *numGroups, GLsizei groupsSize, GLuint *groups); -GL_APICALL void GL_APIENTRY glGetPerfMonitorCountersAMD (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters); -GL_APICALL void GL_APIENTRY glGetPerfMonitorGroupStringAMD (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString); -GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterStringAMD (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString); -GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterInfoAMD (GLuint group, GLuint counter, GLenum pname, GLvoid *data); -GL_APICALL void GL_APIENTRY glGenPerfMonitorsAMD (GLsizei n, GLuint *monitors); -GL_APICALL void GL_APIENTRY glDeletePerfMonitorsAMD (GLsizei n, GLuint *monitors); -GL_APICALL void GL_APIENTRY glSelectPerfMonitorCountersAMD (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList); -GL_APICALL void GL_APIENTRY glBeginPerfMonitorAMD (GLuint monitor); -GL_APICALL void GL_APIENTRY glEndPerfMonitorAMD (GLuint monitor); -GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterDataAMD (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten); -#endif -typedef void (GL_APIENTRYP PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint *numGroups, GLsizei groupsSize, GLuint *groups); -typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters); -typedef void (GL_APIENTRYP PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString); -typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString); -typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, GLvoid *data); -typedef void (GL_APIENTRYP PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); -typedef void (GL_APIENTRYP PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); -typedef void (GL_APIENTRYP PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList); -typedef void (GL_APIENTRYP PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor); -typedef void (GL_APIENTRYP PFNGLENDPERFMONITORAMDPROC) (GLuint monitor); -typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten); -#endif - -/* GL_AMD_program_binary_Z400 */ -#ifndef GL_AMD_program_binary_Z400 -#define GL_AMD_program_binary_Z400 1 -#endif - -/*------------------------------------------------------------------------* - * ANGLE extension functions - *------------------------------------------------------------------------*/ - -/* GL_ANGLE_framebuffer_blit */ -#ifndef GL_ANGLE_framebuffer_blit -#define GL_ANGLE_framebuffer_blit 1 -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glBlitFramebufferANGLE (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -#endif -typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERANGLEPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -#endif - -/* GL_ANGLE_framebuffer_multisample */ -#ifndef GL_ANGLE_framebuffer_multisample -#define GL_ANGLE_framebuffer_multisample 1 -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleANGLE (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -#endif -typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -#endif - -#ifndef GL_ANGLE_instanced_arrays -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glDrawArraysInstancedANGLE (GLenum mode, GLint first, GLsizei count, GLsizei primcount); -GL_APICALL void GL_APIENTRY glDrawElementsInstancedANGLE (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); -GL_APICALL void GL_APIENTRY glVertexAttribDivisorANGLE (GLuint index, GLuint divisor); -#endif -typedef void (GL_APIENTRYP PFLGLDRAWARRAYSINSTANCEDANGLEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); -typedef void (GL_APIENTRYP PFLGLDRAWELEMENTSINSTANCEDANGLEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); -typedef void (GL_APIENTRYP PFLGLVERTEXATTRIBDIVISORANGLEPROC) (GLuint index, GLuint divisor); -#endif - -/* GL_ANGLE_pack_reverse_row_order */ -#ifndef GL_ANGLE_pack_reverse_row_order -#define GL_ANGLE_pack_reverse_row_order 1 -#endif - -/* GL_ANGLE_texture_compression_dxt3 */ -#ifndef GL_ANGLE_texture_compression_dxt3 -#define GL_ANGLE_texture_compression_dxt3 1 -#endif - -/* GL_ANGLE_texture_compression_dxt5 */ -#ifndef GL_ANGLE_texture_compression_dxt5 -#define GL_ANGLE_texture_compression_dxt5 1 -#endif - -/* GL_ANGLE_texture_usage */ -#ifndef GL_ANGLE_texture_usage -#define GL_ANGLE_texture_usage 1 -#endif - -#ifndef GL_ANGLE_translated_shader_source -#define GL_ANGLE_translated_shader_source 1 -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glGetTranslatedShaderSourceANGLE (GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source); -#endif -typedef void (GL_APIENTRYP PFLGLGETTRANSLATEDSHADERSOURCEANGLEPROC) (GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source); -#endif - -/*------------------------------------------------------------------------* - * APPLE extension functions - *------------------------------------------------------------------------*/ - -/* GL_APPLE_rgb_422 */ -#ifndef GL_APPLE_rgb_422 -#define GL_APPLE_rgb_422 1 -#endif - -/* GL_APPLE_framebuffer_multisample */ -#ifndef GL_APPLE_framebuffer_multisample -#define GL_APPLE_framebuffer_multisample 1 -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleAPPLE (GLenum, GLsizei, GLenum, GLsizei, GLsizei); -GL_APICALL void GL_APIENTRY glResolveMultisampleFramebufferAPPLE (void); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEAPPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (GL_APIENTRYP PFNGLRESOLVEMULTISAMPLEFRAMEBUFFERAPPLEPROC) (void); -#endif - -/* GL_APPLE_texture_format_BGRA8888 */ -#ifndef GL_APPLE_texture_format_BGRA8888 -#define GL_APPLE_texture_format_BGRA8888 1 -#endif - -/* GL_APPLE_texture_max_level */ -#ifndef GL_APPLE_texture_max_level -#define GL_APPLE_texture_max_level 1 -#endif - -/*------------------------------------------------------------------------* - * ARM extension functions - *------------------------------------------------------------------------*/ - -/* GL_ARM_mali_shader_binary */ -#ifndef GL_ARM_mali_shader_binary -#define GL_ARM_mali_shader_binary 1 -#endif - -/* GL_ARM_rgba8 */ -#ifndef GL_ARM_rgba8 -#define GL_ARM_rgba8 1 -#endif - -/*------------------------------------------------------------------------* - * EXT extension functions - *------------------------------------------------------------------------*/ - -/* GL_EXT_blend_minmax */ -#ifndef GL_EXT_blend_minmax -#define GL_EXT_blend_minmax 1 -#endif - -/* GL_EXT_color_buffer_half_float */ -#ifndef GL_EXT_color_buffer_half_float -#define GL_EXT_color_buffer_half_float 1 -#endif - -/* GL_EXT_debug_label */ -#ifndef GL_EXT_debug_label -#define GL_EXT_debug_label 1 -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glLabelObjectEXT (GLenum type, GLuint object, GLsizei length, const GLchar *label); -GL_APICALL void GL_APIENTRY glGetObjectLabelEXT (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label); -#endif -typedef void (GL_APIENTRYP PFNGLLABELOBJECTEXTPROC) (GLenum type, GLuint object, GLsizei length, const GLchar *label); -typedef void (GL_APIENTRYP PFNGLGETOBJECTLABELEXTPROC) (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label); -#endif - -/* GL_EXT_debug_marker */ -#ifndef GL_EXT_debug_marker -#define GL_EXT_debug_marker 1 -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glInsertEventMarkerEXT (GLsizei length, const GLchar *marker); -GL_APICALL void GL_APIENTRY glPushGroupMarkerEXT (GLsizei length, const GLchar *marker); -GL_APICALL void GL_APIENTRY glPopGroupMarkerEXT (void); -#endif -typedef void (GL_APIENTRYP PFNGLINSERTEVENTMARKEREXTPROC) (GLsizei length, const GLchar *marker); -typedef void (GL_APIENTRYP PFNGLPUSHGROUPMARKEREXTPROC) (GLsizei length, const GLchar *marker); -typedef void (GL_APIENTRYP PFNGLPOPGROUPMARKEREXTPROC) (void); -#endif - -/* GL_EXT_discard_framebuffer */ -#ifndef GL_EXT_discard_framebuffer -#define GL_EXT_discard_framebuffer 1 -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glDiscardFramebufferEXT (GLenum target, GLsizei numAttachments, const GLenum *attachments); -#endif -typedef void (GL_APIENTRYP PFNGLDISCARDFRAMEBUFFEREXTPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments); -#endif - -/* GL_EXT_multisampled_render_to_texture */ -#ifndef GL_EXT_multisampled_render_to_texture -#define GL_EXT_multisampled_render_to_texture 1 -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleEXT (GLenum, GLsizei, GLenum, GLsizei, GLsizei); -GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleEXT (GLenum, GLenum, GLenum, GLuint, GLint, GLsizei); -#endif -typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); -#endif - -#ifndef GL_EXT_multi_draw_arrays -#define GL_EXT_multi_draw_arrays 1 -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glMultiDrawArraysEXT (GLenum, GLint *, GLsizei *, GLsizei); -GL_APICALL void GL_APIENTRY glMultiDrawElementsEXT (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (GL_APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount); -typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); -#endif - -/* GL_EXT_occlusion_query_boolean */ -#ifndef GL_EXT_occlusion_query_boolean -#define GL_EXT_occlusion_query_boolean 1 -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glGenQueriesEXT (GLsizei n, GLuint *ids); -GL_APICALL void GL_APIENTRY glDeleteQueriesEXT (GLsizei n, const GLuint *ids); -GL_APICALL GLboolean GL_APIENTRY glIsQueryEXT (GLuint id); -GL_APICALL void GL_APIENTRY glBeginQueryEXT (GLenum target, GLuint id); -GL_APICALL void GL_APIENTRY glEndQueryEXT (GLenum target); -GL_APICALL void GL_APIENTRY glGetQueryivEXT (GLenum target, GLenum pname, GLint *params); -GL_APICALL void GL_APIENTRY glGetQueryObjectuivEXT (GLuint id, GLenum pname, GLuint *params); -#endif -typedef void (GL_APIENTRYP PFNGLGENQUERIESEXTPROC) (GLsizei n, GLuint *ids); -typedef void (GL_APIENTRYP PFNGLDELETEQUERIESEXTPROC) (GLsizei n, const GLuint *ids); -typedef GLboolean (GL_APIENTRYP PFNGLISQUERYEXTPROC) (GLuint id); -typedef void (GL_APIENTRYP PFNGLBEGINQUERYEXTPROC) (GLenum target, GLuint id); -typedef void (GL_APIENTRYP PFNGLENDQUERYEXTPROC) (GLenum target); -typedef void (GL_APIENTRYP PFNGLGETQUERYIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUIVEXTPROC) (GLuint id, GLenum pname, GLuint *params); -#endif - -/* GL_EXT_read_format_bgra */ -#ifndef GL_EXT_read_format_bgra -#define GL_EXT_read_format_bgra 1 -#endif - -/* GL_EXT_robustness */ -#ifndef GL_EXT_robustness -#define GL_EXT_robustness 1 -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL GLenum GL_APIENTRY glGetGraphicsResetStatusEXT (void); -GL_APICALL void GL_APIENTRY glReadnPixelsEXT (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); -GL_APICALL void GL_APIENTRY glGetnUniformfvEXT (GLuint program, GLint location, GLsizei bufSize, float *params); -GL_APICALL void GL_APIENTRY glGetnUniformivEXT (GLuint program, GLint location, GLsizei bufSize, GLint *params); -#endif -typedef GLenum (GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSEXTPROC) (void); -typedef void (GL_APIENTRYP PFNGLREADNPIXELSEXTPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); -typedef void (GL_APIENTRYP PFNGLGETNUNIFORMFVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, float *params); -typedef void (GL_APIENTRYP PFNGLGETNUNIFORMIVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params); -#endif - -/* GL_EXT_separate_shader_objects */ -#ifndef GL_EXT_separate_shader_objects -#define GL_EXT_separate_shader_objects 1 -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glUseProgramStagesEXT (GLuint pipeline, GLbitfield stages, GLuint program); -GL_APICALL void GL_APIENTRY glActiveShaderProgramEXT (GLuint pipeline, GLuint program); -GL_APICALL GLuint GL_APIENTRY glCreateShaderProgramvEXT (GLenum type, GLsizei count, const GLchar **strings); -GL_APICALL void GL_APIENTRY glBindProgramPipelineEXT (GLuint pipeline); -GL_APICALL void GL_APIENTRY glDeleteProgramPipelinesEXT (GLsizei n, const GLuint *pipelines); -GL_APICALL void GL_APIENTRY glGenProgramPipelinesEXT (GLsizei n, GLuint *pipelines); -GL_APICALL GLboolean GL_APIENTRY glIsProgramPipelineEXT (GLuint pipeline); -GL_APICALL void GL_APIENTRY glProgramParameteriEXT (GLuint program, GLenum pname, GLint value); -GL_APICALL void GL_APIENTRY glGetProgramPipelineivEXT (GLuint pipeline, GLenum pname, GLint *params); -GL_APICALL void GL_APIENTRY glProgramUniform1iEXT (GLuint program, GLint location, GLint x); -GL_APICALL void GL_APIENTRY glProgramUniform2iEXT (GLuint program, GLint location, GLint x, GLint y); -GL_APICALL void GL_APIENTRY glProgramUniform3iEXT (GLuint program, GLint location, GLint x, GLint y, GLint z); -GL_APICALL void GL_APIENTRY glProgramUniform4iEXT (GLuint program, GLint location, GLint x, GLint y, GLint z, GLint w); -GL_APICALL void GL_APIENTRY glProgramUniform1fEXT (GLuint program, GLint location, GLfloat x); -GL_APICALL void GL_APIENTRY glProgramUniform2fEXT (GLuint program, GLint location, GLfloat x, GLfloat y); -GL_APICALL void GL_APIENTRY glProgramUniform3fEXT (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z); -GL_APICALL void GL_APIENTRY glProgramUniform4fEXT (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GL_APICALL void GL_APIENTRY glProgramUniform1ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); -GL_APICALL void GL_APIENTRY glProgramUniform2ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); -GL_APICALL void GL_APIENTRY glProgramUniform3ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); -GL_APICALL void GL_APIENTRY glProgramUniform4ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); -GL_APICALL void GL_APIENTRY glProgramUniform1fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); -GL_APICALL void GL_APIENTRY glProgramUniform2fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); -GL_APICALL void GL_APIENTRY glProgramUniform3fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); -GL_APICALL void GL_APIENTRY glProgramUniform4fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); -GL_APICALL void GL_APIENTRY glProgramUniformMatrix2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GL_APICALL void GL_APIENTRY glProgramUniformMatrix3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GL_APICALL void GL_APIENTRY glProgramUniformMatrix4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GL_APICALL void GL_APIENTRY glValidateProgramPipelineEXT (GLuint pipeline); -GL_APICALL void GL_APIENTRY glGetProgramPipelineInfoLogEXT (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); -#endif -typedef void (GL_APIENTRYP PFNGLUSEPROGRAMSTAGESEXTPROC) (GLuint pipeline, GLbitfield stages, GLuint program); -typedef void (GL_APIENTRYP PFNGLACTIVESHADERPROGRAMEXTPROC) (GLuint pipeline, GLuint program); -typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROGRAMVEXTPROC) (GLenum type, GLsizei count, const GLchar **strings); -typedef void (GL_APIENTRYP PFNGLBINDPROGRAMPIPELINEEXTPROC) (GLuint pipeline); -typedef void (GL_APIENTRYP PFNGLDELETEPROGRAMPIPELINESEXTPROC) (GLsizei n, const GLuint *pipelines); -typedef void (GL_APIENTRYP PFNGLGENPROGRAMPIPELINESEXTPROC) (GLsizei n, GLuint *pipelines); -typedef GLboolean (GL_APIENTRYP PFNGLISPROGRAMPIPELINEEXTPROC) (GLuint pipeline); -typedef void (GL_APIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value); -typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEIVEXTPROC) (GLuint pipeline, GLenum pname, GLint *params); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint x); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint x, GLint y); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint x, GLint y, GLint z); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint x, GLint y, GLint z, GLint w); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat x); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat x, GLfloat y); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (GL_APIENTRYP PFNGLVALIDATEPROGRAMPIPELINEEXTPROC) (GLuint pipeline); -typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGEXTPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); -#endif - -/* GL_EXT_shader_texture_lod */ -#ifndef GL_EXT_shader_texture_lod -#define GL_EXT_shader_texture_lod 1 -#endif - -/* GL_EXT_shadow_samplers */ -#ifndef GL_EXT_shadow_samplers -#define GL_EXT_shadow_samplers 1 -#endif - -/* GL_EXT_sRGB */ -#ifndef GL_EXT_sRGB -#define GL_EXT_sRGB 1 -#endif - -/* GL_EXT_texture_compression_dxt1 */ -#ifndef GL_EXT_texture_compression_dxt1 -#define GL_EXT_texture_compression_dxt1 1 -#endif - -/* GL_EXT_texture_filter_anisotropic */ -#ifndef GL_EXT_texture_filter_anisotropic -#define GL_EXT_texture_filter_anisotropic 1 -#endif - -/* GL_EXT_texture_format_BGRA8888 */ -#ifndef GL_EXT_texture_format_BGRA8888 -#define GL_EXT_texture_format_BGRA8888 1 -#endif - -/* GL_EXT_texture_rg */ -#ifndef GL_EXT_texture_rg -#define GL_EXT_texture_rg 1 -#endif - -/* GL_EXT_texture_storage */ -#ifndef GL_EXT_texture_storage -#define GL_EXT_texture_storage 1 -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glTexStorage1DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); -GL_APICALL void GL_APIENTRY glTexStorage2DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); -GL_APICALL void GL_APIENTRY glTexStorage3DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); -GL_APICALL void GL_APIENTRY glTextureStorage1DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); -GL_APICALL void GL_APIENTRY glTextureStorage2DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); -GL_APICALL void GL_APIENTRY glTextureStorage3DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); -#endif -typedef void (GL_APIENTRYP PFNGLTEXSTORAGE1DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); -typedef void (GL_APIENTRYP PFNGLTEXSTORAGE2DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (GL_APIENTRYP PFNGLTEXSTORAGE3DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); -typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE1DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); -typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE2DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE3DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); -#endif - -/* GL_EXT_texture_type_2_10_10_10_REV */ -#ifndef GL_EXT_texture_type_2_10_10_10_REV -#define GL_EXT_texture_type_2_10_10_10_REV 1 -#endif - -/* GL_EXT_unpack_subimage */ -#ifndef GL_EXT_unpack_subimage -#define GL_EXT_unpack_subimage 1 -#endif - -/*------------------------------------------------------------------------* - * DMP extension functions - *------------------------------------------------------------------------*/ - -/* GL_DMP_shader_binary */ -#ifndef GL_DMP_shader_binary -#define GL_DMP_shader_binary 1 -#endif - -/*------------------------------------------------------------------------* - * IMG extension functions - *------------------------------------------------------------------------*/ - -/* GL_IMG_program_binary */ -#ifndef GL_IMG_program_binary -#define GL_IMG_program_binary 1 -#endif - -/* GL_IMG_read_format */ -#ifndef GL_IMG_read_format -#define GL_IMG_read_format 1 -#endif - -/* GL_IMG_shader_binary */ -#ifndef GL_IMG_shader_binary -#define GL_IMG_shader_binary 1 -#endif - -/* GL_IMG_texture_compression_pvrtc */ -#ifndef GL_IMG_texture_compression_pvrtc -#define GL_IMG_texture_compression_pvrtc 1 -#endif - -/* GL_IMG_multisampled_render_to_texture */ -#ifndef GL_IMG_multisampled_render_to_texture -#define GL_IMG_multisampled_render_to_texture 1 -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleIMG (GLenum, GLsizei, GLenum, GLsizei, GLsizei); -GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleIMG (GLenum, GLenum, GLenum, GLuint, GLint, GLsizei); -#endif -typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMG) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMG) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); -#endif - -/*------------------------------------------------------------------------* - * NV extension functions - *------------------------------------------------------------------------*/ - -/* GL_NV_coverage_sample */ -#ifndef GL_NV_coverage_sample -#define GL_NV_coverage_sample 1 -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glCoverageMaskNV (GLboolean mask); -GL_APICALL void GL_APIENTRY glCoverageOperationNV (GLenum operation); -#endif -typedef void (GL_APIENTRYP PFNGLCOVERAGEMASKNVPROC) (GLboolean mask); -typedef void (GL_APIENTRYP PFNGLCOVERAGEOPERATIONNVPROC) (GLenum operation); -#endif - -/* GL_NV_depth_nonlinear */ -#ifndef GL_NV_depth_nonlinear -#define GL_NV_depth_nonlinear 1 -#endif - -/* GL_NV_draw_buffers */ -#ifndef GL_NV_draw_buffers -#define GL_NV_draw_buffers 1 -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glDrawBuffersNV (GLsizei n, const GLenum *bufs); -#endif -typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSNVPROC) (GLsizei n, const GLenum *bufs); -#endif - -/* GL_NV_fbo_color_attachments */ -#ifndef GL_NV_fbo_color_attachments -#define GL_NV_fbo_color_attachments 1 -#endif - -/* GL_NV_fence */ -#ifndef GL_NV_fence -#define GL_NV_fence 1 -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glDeleteFencesNV (GLsizei, const GLuint *); -GL_APICALL void GL_APIENTRY glGenFencesNV (GLsizei, GLuint *); -GL_APICALL GLboolean GL_APIENTRY glIsFenceNV (GLuint); -GL_APICALL GLboolean GL_APIENTRY glTestFenceNV (GLuint); -GL_APICALL void GL_APIENTRY glGetFenceivNV (GLuint, GLenum, GLint *); -GL_APICALL void GL_APIENTRY glFinishFenceNV (GLuint); -GL_APICALL void GL_APIENTRY glSetFenceNV (GLuint, GLenum); -#endif -typedef void (GL_APIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences); -typedef void (GL_APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences); -typedef GLboolean (GL_APIENTRYP PFNGLISFENCENVPROC) (GLuint fence); -typedef GLboolean (GL_APIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence); -typedef void (GL_APIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params); -typedef void (GL_APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence); -typedef void (GL_APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); -#endif - -/* GL_NV_read_buffer */ -#ifndef GL_NV_read_buffer -#define GL_NV_read_buffer 1 -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glReadBufferNV (GLenum mode); -#endif -typedef void (GL_APIENTRYP PFNGLREADBUFFERNVPROC) (GLenum mode); -#endif - -/* GL_NV_read_buffer_front */ -#ifndef GL_NV_read_buffer_front -#define GL_NV_read_buffer_front 1 -#endif - -/* GL_NV_read_depth */ -#ifndef GL_NV_read_depth -#define GL_NV_read_depth 1 -#endif - -/* GL_NV_read_depth_stencil */ -#ifndef GL_NV_read_depth_stencil -#define GL_NV_read_depth_stencil 1 -#endif - -/* GL_NV_read_stencil */ -#ifndef GL_NV_read_stencil -#define GL_NV_read_stencil 1 -#endif - -/* GL_NV_texture_compression_s3tc_update */ -#ifndef GL_NV_texture_compression_s3tc_update -#define GL_NV_texture_compression_s3tc_update 1 -#endif - -/* GL_NV_texture_npot_2D_mipmap */ -#ifndef GL_NV_texture_npot_2D_mipmap -#define GL_NV_texture_npot_2D_mipmap 1 -#endif - -/*------------------------------------------------------------------------* - * QCOM extension functions - *------------------------------------------------------------------------*/ - -/* GL_QCOM_alpha_test */ -#ifndef GL_QCOM_alpha_test -#define GL_QCOM_alpha_test 1 -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glAlphaFuncQCOM (GLenum func, GLclampf ref); -#endif -typedef void (GL_APIENTRYP PFNGLALPHAFUNCQCOMPROC) (GLenum func, GLclampf ref); -#endif - -/* GL_QCOM_driver_control */ -#ifndef GL_QCOM_driver_control -#define GL_QCOM_driver_control 1 -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glGetDriverControlsQCOM (GLint *num, GLsizei size, GLuint *driverControls); -GL_APICALL void GL_APIENTRY glGetDriverControlStringQCOM (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString); -GL_APICALL void GL_APIENTRY glEnableDriverControlQCOM (GLuint driverControl); -GL_APICALL void GL_APIENTRY glDisableDriverControlQCOM (GLuint driverControl); -#endif -typedef void (GL_APIENTRYP PFNGLGETDRIVERCONTROLSQCOMPROC) (GLint *num, GLsizei size, GLuint *driverControls); -typedef void (GL_APIENTRYP PFNGLGETDRIVERCONTROLSTRINGQCOMPROC) (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString); -typedef void (GL_APIENTRYP PFNGLENABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl); -typedef void (GL_APIENTRYP PFNGLDISABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl); -#endif - -/* GL_QCOM_extended_get */ -#ifndef GL_QCOM_extended_get -#define GL_QCOM_extended_get 1 -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glExtGetTexturesQCOM (GLuint *textures, GLint maxTextures, GLint *numTextures); -GL_APICALL void GL_APIENTRY glExtGetBuffersQCOM (GLuint *buffers, GLint maxBuffers, GLint *numBuffers); -GL_APICALL void GL_APIENTRY glExtGetRenderbuffersQCOM (GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers); -GL_APICALL void GL_APIENTRY glExtGetFramebuffersQCOM (GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers); -GL_APICALL void GL_APIENTRY glExtGetTexLevelParameterivQCOM (GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params); -GL_APICALL void GL_APIENTRY glExtTexObjectStateOverrideiQCOM (GLenum target, GLenum pname, GLint param); -GL_APICALL void GL_APIENTRY glExtGetTexSubImageQCOM (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels); -GL_APICALL void GL_APIENTRY glExtGetBufferPointervQCOM (GLenum target, GLvoid **params); -#endif -typedef void (GL_APIENTRYP PFNGLEXTGETTEXTURESQCOMPROC) (GLuint *textures, GLint maxTextures, GLint *numTextures); -typedef void (GL_APIENTRYP PFNGLEXTGETBUFFERSQCOMPROC) (GLuint *buffers, GLint maxBuffers, GLint *numBuffers); -typedef void (GL_APIENTRYP PFNGLEXTGETRENDERBUFFERSQCOMPROC) (GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers); -typedef void (GL_APIENTRYP PFNGLEXTGETFRAMEBUFFERSQCOMPROC) (GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers); -typedef void (GL_APIENTRYP PFNGLEXTGETTEXLEVELPARAMETERIVQCOMPROC) (GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params); -typedef void (GL_APIENTRYP PFNGLEXTTEXOBJECTSTATEOVERRIDEIQCOMPROC) (GLenum target, GLenum pname, GLint param); -typedef void (GL_APIENTRYP PFNGLEXTGETTEXSUBIMAGEQCOMPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels); -typedef void (GL_APIENTRYP PFNGLEXTGETBUFFERPOINTERVQCOMPROC) (GLenum target, GLvoid **params); -#endif - -/* GL_QCOM_extended_get2 */ -#ifndef GL_QCOM_extended_get2 -#define GL_QCOM_extended_get2 1 -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glExtGetShadersQCOM (GLuint *shaders, GLint maxShaders, GLint *numShaders); -GL_APICALL void GL_APIENTRY glExtGetProgramsQCOM (GLuint *programs, GLint maxPrograms, GLint *numPrograms); -GL_APICALL GLboolean GL_APIENTRY glExtIsProgramBinaryQCOM (GLuint program); -GL_APICALL void GL_APIENTRY glExtGetProgramBinarySourceQCOM (GLuint program, GLenum shadertype, GLchar *source, GLint *length); -#endif -typedef void (GL_APIENTRYP PFNGLEXTGETSHADERSQCOMPROC) (GLuint *shaders, GLint maxShaders, GLint *numShaders); -typedef void (GL_APIENTRYP PFNGLEXTGETPROGRAMSQCOMPROC) (GLuint *programs, GLint maxPrograms, GLint *numPrograms); -typedef GLboolean (GL_APIENTRYP PFNGLEXTISPROGRAMBINARYQCOMPROC) (GLuint program); -typedef void (GL_APIENTRYP PFNGLEXTGETPROGRAMBINARYSOURCEQCOMPROC) (GLuint program, GLenum shadertype, GLchar *source, GLint *length); -#endif - -/* GL_QCOM_perfmon_global_mode */ -#ifndef GL_QCOM_perfmon_global_mode -#define GL_QCOM_perfmon_global_mode 1 -#endif - -/* GL_QCOM_writeonly_rendering */ -#ifndef GL_QCOM_writeonly_rendering -#define GL_QCOM_writeonly_rendering 1 -#endif - -/* GL_QCOM_tiled_rendering */ -#ifndef GL_QCOM_tiled_rendering -#define GL_QCOM_tiled_rendering 1 -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glStartTilingQCOM (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask); -GL_APICALL void GL_APIENTRY glEndTilingQCOM (GLbitfield preserveMask); -#endif -typedef void (GL_APIENTRYP PFNGLSTARTTILINGQCOMPROC) (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask); -typedef void (GL_APIENTRYP PFNGLENDTILINGQCOMPROC) (GLbitfield preserveMask); -#endif - -/*------------------------------------------------------------------------* - * VIV extension tokens - *------------------------------------------------------------------------*/ - -/* GL_VIV_shader_binary */ -#ifndef GL_VIV_shader_binary -#define GL_VIV_shader_binary 1 -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* __gl2ext_h_ */ diff --git a/cogl/cogl-gles2/GLES2/gl2platform.h b/cogl/cogl-gles2/GLES2/gl2platform.h deleted file mode 100644 index 8bc44b07e..000000000 --- a/cogl/cogl-gles2/GLES2/gl2platform.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef __gl2platform_h_ -#define __gl2platform_h_ - -/* $Revision: 10602 $ on $Date:: 2010-03-04 22:35:34 -0800 #$ */ - -/* - * This document is licensed under the SGI Free Software B License Version - * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . - */ - -/* Platform-specific types and definitions for OpenGL ES 2.X gl2.h - * - * Adopters may modify khrplatform.h and this file to suit their platform. - * You are encouraged to submit all modifications to the Khronos group so that - * they can be included in future versions of this file. Please submit changes - * by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla) - * by filing a bug against product "OpenGL-ES" component "Registry". - */ - -#ifndef GL_APICALL -#define GL_APICALL -#endif - -#ifndef GL_APIENTRY -#define GL_APIENTRY -#endif - -#endif /* __gl2platform_h_ */ diff --git a/cogl/cogl-gles2/Makefile.am b/cogl/cogl-gles2/Makefile.am deleted file mode 100644 index 193f812fb..000000000 --- a/cogl/cogl-gles2/Makefile.am +++ /dev/null @@ -1,35 +0,0 @@ -# preamble - -NULL = - -DISTCLEANFILES = - -muffinlibdir = $(libdir)/muffin -muffinlib_LTLIBRARIES = libmuffin-cogl-gles2-@MUFFIN_PLUGIN_API_VERSION@.la - -AM_CPPFLAGS = \ - -I$(top_srcdir) \ - -I$(top_builddir) - -AM_CFLAGS = $(COGL_DEP_CFLAGS) $(COGL_EXTRA_CFLAGS) $(MAINTAINER_CFLAGS) - -libmuffin_cogl_gles2_@MUFFIN_PLUGIN_API_VERSION@_la_SOURCES = cogl-gles2-api.c -libmuffin_cogl_gles2_@MUFFIN_PLUGIN_API_VERSION@_la_LDFLAGS = \ - -no-undefined \ - -rpath $(muffinlibdir) \ - -avoid-version \ - -export-dynamic \ - -export-symbols-regex "^gl*" - -coglgles2includedir = $(includedir)/muffin/cogl/cogl-gles2/GLES2 -coglgles2include_HEADERS = \ - GLES2/gl2.h \ - GLES2/gl2ext.h \ - GLES2/gl2platform.h - -pc_files = muffin-cogl-gles2-$(MUFFIN_PLUGIN_API_VERSION).pc - -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = $(pc_files) - -DISTCLEANFILES += $(pc_files) diff --git a/cogl/cogl-gles2/cogl-gles2-api.c b/cogl/cogl-gles2/cogl-gles2-api.c deleted file mode 100644 index 22ab2b716..000000000 --- a/cogl/cogl-gles2/cogl-gles2-api.c +++ /dev/null @@ -1,1048 +0,0 @@ - -#include - -#include - -void -glBindTexture (GLenum target, GLuint texture) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glBindTexture (target, texture); -} - -void -glBlendFunc (GLenum sfactor, GLenum dfactor) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glBlendFunc (sfactor, dfactor); -} - -void -glClear (GLbitfield mask) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glClear (mask); -} - -void -glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glClearColor (red, green, blue, alpha); -} - -void -glClearStencil (GLint s) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glClearStencil (s); -} - -void -glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glColorMask (red, green, blue, alpha); -} - -void -glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, - GLint x, GLint y, GLsizei width, GLsizei height) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glCopyTexSubImage2D (target, level, xoffset, yoffset, x, y, width, - height); -} - -void -glDeleteTextures (GLsizei n, const GLuint * textures) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glDeleteTextures (n, textures); -} - -void -glDepthFunc (GLenum func) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glDepthFunc (func); -} - -void -glDepthMask (GLboolean flag) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glDepthMask (flag); -} - -void -glDisable (GLenum cap) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glDisable (cap); -} - -void -glDrawArrays (GLenum mode, GLint first, GLsizei count) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glDrawArrays (mode, first, count); -} - -void -glDrawElements (GLenum mode, GLsizei count, GLenum type, - const GLvoid * indices) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glDrawElements (mode, count, type, indices); -} - -void -glEnable (GLenum cap) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glEnable (cap); -} - -void -glFinish (void) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glFinish (); -} - -void -glFlush (void) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glFlush (); -} - -void -glFrontFace (GLenum mode) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glFrontFace (mode); -} - -void -glCullFace (GLenum mode) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glCullFace (mode); -} - -void -glGenTextures (GLsizei n, GLuint * textures) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glGenTextures (n, textures); -} - -GLenum -glGetError (void) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - return vtable->glGetError (); -} - -void -glGetIntegerv (GLenum pname, GLint * params) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glGetIntegerv (pname, params); -} - -void -glGetBooleanv (GLenum pname, GLboolean * params) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glGetBooleanv (pname, params); -} - -void -glGetFloatv (GLenum pname, GLfloat * params) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glGetFloatv (pname, params); -} - -const GLubyte * -glGetString (GLenum name) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - return vtable->glGetString (name); -} - -void -glHint (GLenum target, GLenum mode) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glHint (target, mode); -} - -GLboolean -glIsTexture (GLuint texture) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - return vtable->glIsTexture (texture); -} - -void -glPixelStorei (GLenum pname, GLint param) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glPixelStorei (pname, param); -} - -void -glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, - GLenum type, GLvoid * pixels) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glReadPixels (x, y, width, height, format, type, pixels); -} - -void -glScissor (GLint x, GLint y, GLsizei width, GLsizei height) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glScissor (x, y, width, height); -} - -void -glStencilFunc (GLenum func, GLint ref, GLuint mask) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glStencilFunc (func, ref, mask); -} - -void -glStencilMask (GLuint mask) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glStencilMask (mask); -} - -void -glStencilOp (GLenum fail, GLenum zfail, GLenum zpass) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glStencilOp (fail, zfail, zpass); -} - -void -glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, - GLsizei height, GLint border, GLenum format, GLenum type, - const GLvoid * pixels) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glTexImage2D (target, level, internalformat, width, height, border, - format, type, pixels); -} - -void -glTexParameterf (GLenum target, GLenum pname, GLfloat param) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glTexParameterf (target, pname, param); -} - -void -glTexParameterfv (GLenum target, GLenum pname, const GLfloat * params) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glTexParameterfv (target, pname, params); -} - -void -glTexParameteri (GLenum target, GLenum pname, GLint param) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glTexParameteri (target, pname, param); -} - -void -glTexParameteriv (GLenum target, GLenum pname, const GLint * params) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glTexParameteriv (target, pname, params); -} - -void -glGetTexParameterfv (GLenum target, GLenum pname, GLfloat * params) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glGetTexParameterfv (target, pname, params); -} - -void -glGetTexParameteriv (GLenum target, GLenum pname, GLint * params) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glGetTexParameteriv (target, pname, params); -} - -void -glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, GLenum format, GLenum type, - const GLvoid * pixels) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glTexSubImage2D (target, level, xoffset, yoffset, width, height, - format, type, pixels); -} - -void -glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, - GLint y, GLsizei width, GLsizei height, GLint border) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glCopyTexImage2D (target, level, internalformat, - x, y, width, height, border); -} - -void -glViewport (GLint x, GLint y, GLsizei width, GLsizei height) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glViewport (x, y, width, height); -} - -GLboolean -glIsEnabled (GLenum cap) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - return vtable->glIsEnabled (cap); -} - -void -glLineWidth (GLfloat width) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glLineWidth (width); -} - -void -glPolygonOffset (GLfloat factor, GLfloat units) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glPolygonOffset (factor, units); -} - -void -glDepthRangef (GLfloat near_val, GLfloat far_val) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glDepthRangef (near_val, far_val); -} - -void -glClearDepthf (GLclampf depth) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glClearDepthf (depth); -} - -void -glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, - GLsizei width, GLsizei height, GLint border, - GLsizei imageSize, const GLvoid * data) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glCompressedTexImage2D (target, level, internalformat, width, - height, border, imageSize, data); -} - -void -glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, - GLint yoffset, GLsizei width, GLsizei height, - GLenum format, GLsizei imageSize, - const GLvoid * data) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glCompressedTexSubImage2D (target, level, - xoffset, yoffset, width, height, - format, imageSize, data); -} - -void -glSampleCoverage (GLclampf value, GLboolean invert) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glSampleCoverage (value, invert); -} - -void -glGetBufferParameteriv (GLenum target, GLenum pname, GLint * params) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glGetBufferParameteriv (target, pname, params); -} - -void -glGenBuffers (GLsizei n, GLuint * buffers) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glGenBuffers (n, buffers); -} - -void -glBindBuffer (GLenum target, GLuint buffer) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glBindBuffer (target, buffer); -} - -void -glBufferData (GLenum target, GLsizeiptr size, const GLvoid * data, - GLenum usage) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glBufferData (target, size, data, usage); -} - -void -glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, - const GLvoid * data) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glBufferSubData (target, offset, size, data); -} - -void -glDeleteBuffers (GLsizei n, const GLuint * buffers) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glDeleteBuffers (n, buffers); -} - -GLboolean -glIsBuffer (GLuint buffer) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - return vtable->glIsBuffer (buffer); -} - -void -glActiveTexture (GLenum texture) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glActiveTexture (texture); -} - -void -glGenRenderbuffers (GLsizei n, GLuint * renderbuffers) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glGenRenderbuffers (n, renderbuffers); -} - -void -glDeleteRenderbuffers (GLsizei n, const GLuint * renderbuffers) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glDeleteRenderbuffers (n, renderbuffers); -} - -void -glBindRenderbuffer (GLenum target, GLuint renderbuffer) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glBindRenderbuffer (target, renderbuffer); -} - -void -glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, - GLsizei height) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glRenderbufferStorage (target, internalformat, width, height); -} - -void -glGenFramebuffers (GLsizei n, GLuint * framebuffers) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glGenFramebuffers (n, framebuffers); -} - -void -glBindFramebuffer (GLenum target, GLuint framebuffer) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glBindFramebuffer (target, framebuffer); -} - -void -glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, - GLuint texture, GLint level) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glFramebufferTexture2D (target, attachment, - textarget, texture, level); -} - -void -glFramebufferRenderbuffer (GLenum target, GLenum attachment, - GLenum renderbuffertarget, GLuint renderbuffer) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glFramebufferRenderbuffer (target, attachment, - renderbuffertarget, renderbuffer); -} - -GLboolean -glIsRenderbuffer (GLuint renderbuffer) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - return vtable->glIsRenderbuffer (renderbuffer); -} - -GLenum -glCheckFramebufferStatus (GLenum target) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - return vtable->glCheckFramebufferStatus (target); -} - -void -glDeleteFramebuffers (GLsizei n, const GLuint * framebuffers) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glDeleteFramebuffers (n, framebuffers); -} - -void -glGenerateMipmap (GLenum target) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glGenerateMipmap (target); -} - -void -glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, - GLenum pname, GLint * params) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glGetFramebufferAttachmentParameteriv (target, - attachment, pname, params); -} - -void -glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint * params) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glGetRenderbufferParameteriv (target, pname, params); -} - -GLboolean -glIsFramebuffer (GLuint framebuffer) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - return vtable->glIsFramebuffer (framebuffer); -} - -void -glBlendEquation (GLenum mode) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glBlendEquation (mode); -} - -void -glBlendColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glBlendColor (red, green, blue, alpha); -} - -void -glBlendFuncSeparate (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, - GLenum dstAlpha) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glBlendFuncSeparate (srcRGB, dstRGB, srcAlpha, dstAlpha); -} - -void -glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glBlendEquationSeparate (modeRGB, modeAlpha); -} - -void -glReleaseShaderCompiler (void) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glReleaseShaderCompiler (); -} - -void -glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, - GLint * range, GLint * precision) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glGetShaderPrecisionFormat (shadertype, precisiontype, - range, precision); -} - -void -glShaderBinary (GLsizei n, const GLuint * shaders, GLenum binaryformat, - const GLvoid * binary, GLsizei length) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glShaderBinary (n, shaders, binaryformat, binary, length); -} - -void -glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glStencilFuncSeparate (face, func, ref, mask); -} - -void -glStencilMaskSeparate (GLenum face, GLuint mask) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glStencilMaskSeparate (face, mask); -} - -void -glStencilOpSeparate (GLenum face, GLenum fail, GLenum zfail, GLenum zpass) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glStencilOpSeparate (face, fail, zfail, zpass); -} - -GLuint -glCreateProgram (void) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - return vtable->glCreateProgram (); -} - -GLuint -glCreateShader (GLenum shaderType) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - return vtable->glCreateShader (shaderType); -} - -void -glShaderSource (GLuint shader, GLsizei count, - const GLchar * const *string, const GLint * length) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glShaderSource (shader, count, string, length); -} - -void -glCompileShader (GLuint shader) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glCompileShader (shader); -} - -void -glDeleteShader (GLuint shader) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glDeleteShader (shader); -} - -void -glAttachShader (GLuint program, GLuint shader) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glAttachShader (program, shader); -} - -void -glLinkProgram (GLuint program) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glLinkProgram (program); -} - -void -glUseProgram (GLuint program) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glUseProgram (program); -} - -GLint -glGetUniformLocation (GLuint program, const char *name) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - return vtable->glGetUniformLocation (program, name); -} - -void -glDeleteProgram (GLuint program) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glDeleteProgram (program); -} - -void -glGetShaderInfoLog (GLuint shader, GLsizei maxLength, GLsizei * length, - char *infoLog) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glGetShaderInfoLog (shader, maxLength, length, infoLog); -} - -void -glGetShaderiv (GLuint shader, GLenum pname, GLint * params) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glGetShaderiv (shader, pname, params); -} - -void -glVertexAttribPointer (GLuint index, GLint size, GLenum type, - GLboolean normalized, GLsizei stride, - const GLvoid * pointer) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glVertexAttribPointer (index, size, type, normalized, stride, - pointer); -} - -void -glEnableVertexAttribArray (GLuint index) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glEnableVertexAttribArray (index); -} - -void -glDisableVertexAttribArray (GLuint index) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glDisableVertexAttribArray (index); -} - -void -glUniform1f (GLint location, GLfloat v0) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glUniform1f (location, v0); -} - -void -glUniform2f (GLint location, GLfloat v0, GLfloat v1) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glUniform2f (location, v0, v1); -} - -void -glUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glUniform3f (location, v0, v1, v2); -} - -void -glUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glUniform4f (location, v0, v1, v2, v3); -} - -void -glUniform1fv (GLint location, GLsizei count, const GLfloat * value) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glUniform1fv (location, count, value); -} - -void -glUniform2fv (GLint location, GLsizei count, const GLfloat * value) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glUniform2fv (location, count, value); -} - -void -glUniform3fv (GLint location, GLsizei count, const GLfloat * value) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glUniform3fv (location, count, value); -} - -void -glUniform4fv (GLint location, GLsizei count, const GLfloat * value) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glUniform4fv (location, count, value); -} - -void -glUniform1i (GLint location, GLint v0) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glUniform1i (location, v0); -} - -void -glUniform2i (GLint location, GLint v0, GLint v1) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glUniform2i (location, v0, v1); -} - -void -glUniform3i (GLint location, GLint v0, GLint v1, GLint v2) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glUniform3i (location, v0, v1, v2); -} - -void -glUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glUniform4i (location, v0, v1, v2, v3); -} - -void -glUniform1iv (GLint location, GLsizei count, const GLint * value) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glUniform1iv (location, count, value); -} - -void -glUniform2iv (GLint location, GLsizei count, const GLint * value) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glUniform2iv (location, count, value); -} - -void -glUniform3iv (GLint location, GLsizei count, const GLint * value) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glUniform3iv (location, count, value); -} - -void -glUniform4iv (GLint location, GLsizei count, const GLint * value) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glUniform4iv (location, count, value); -} - -void -glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, - const GLfloat * value) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glUniformMatrix2fv (location, count, transpose, value); -} - -void -glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, - const GLfloat * value) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glUniformMatrix3fv (location, count, transpose, value); -} - -void -glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, - const GLfloat * value) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glUniformMatrix4fv (location, count, transpose, value); -} - -void -glGetUniformfv (GLuint program, GLint location, GLfloat * params) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glGetUniformfv (program, location, params); -} - -void -glGetUniformiv (GLuint program, GLint location, GLint * params) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glGetUniformiv (program, location, params); -} - -void -glGetProgramiv (GLuint program, GLenum pname, GLint * params) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glGetProgramiv (program, pname, params); -} - -void -glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei * length, - char *infoLog) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glGetProgramInfoLog (program, bufSize, length, infoLog); -} - -void -glVertexAttrib1f (GLuint indx, GLfloat x) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glVertexAttrib1f (indx, x); -} - -void -glVertexAttrib1fv (GLuint indx, const GLfloat * values) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glVertexAttrib1fv (indx, values); -} - -void -glVertexAttrib2f (GLuint indx, GLfloat x, GLfloat y) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glVertexAttrib2f (indx, x, y); -} - -void -glVertexAttrib2fv (GLuint indx, const GLfloat * values) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glVertexAttrib2fv (indx, values); -} - -void -glVertexAttrib3f (GLuint indx, GLfloat x, GLfloat y, GLfloat z) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glVertexAttrib3f (indx, x, y, z); -} - -void -glVertexAttrib3fv (GLuint indx, const GLfloat * values) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glVertexAttrib3fv (indx, values); -} - -void -glVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glVertexAttrib4f (index, x, y, z, w); -} - -void -glVertexAttrib4fv (GLuint indx, const GLfloat * values) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glVertexAttrib4fv (indx, values); -} - -void -glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat * params) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glGetVertexAttribfv (index, pname, params); -} - -void -glGetVertexAttribiv (GLuint index, GLenum pname, GLint * params) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glGetVertexAttribiv (index, pname, params); -} - -void -glGetVertexAttribPointerv (GLuint index, GLenum pname, GLvoid ** pointer) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glGetVertexAttribPointerv (index, pname, pointer); -} - -GLint -glGetAttribLocation (GLuint program, const char *name) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - return vtable->glGetAttribLocation (program, name); -} - -void -glBindAttribLocation (GLuint program, GLuint index, const GLchar * name) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glBindAttribLocation (program, index, name); -} - -void -glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufsize, - GLsizei * length, GLint * size, GLenum * type, - GLchar * name) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glGetActiveAttrib (program, index, bufsize, length, size, type, - name); -} - -void -glGetActiveUniform (GLuint program, GLuint index, GLsizei bufsize, - GLsizei * length, GLint * size, GLenum * type, - GLchar * name) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glGetActiveUniform (program, index, bufsize, length, size, type, - name); -} - -void -glDetachShader (GLuint program, GLuint shader) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glDetachShader (program, shader); -} - -void -glGetAttachedShaders (GLuint program, GLsizei maxcount, GLsizei * count, - GLuint * shaders) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glGetAttachedShaders (program, maxcount, count, shaders); -} - -void -glGetShaderSource (GLuint shader, GLsizei bufsize, GLsizei * length, - GLchar * source) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glGetShaderSource (shader, bufsize, length, source); -} - -GLboolean -glIsShader (GLuint shader) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - return vtable->glIsShader (shader); -} - -GLboolean -glIsProgram (GLuint program) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - return vtable->glIsProgram (program); -} - -void -glValidateProgram (GLuint program) -{ - CoglGLES2Vtable *vtable = cogl_gles2_get_current_vtable (); - vtable->glValidateProgram (program); -} diff --git a/cogl/cogl-gles2/muffin-cogl-gles2.pc.in b/cogl/cogl-gles2/muffin-cogl-gles2.pc.in deleted file mode 100644 index 788b18ce4..000000000 --- a/cogl/cogl-gles2/muffin-cogl-gles2.pc.in +++ /dev/null @@ -1,13 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@/muffin -includedir=@includedir@/muffin -apiversion=@MUFFIN_PLUGIN_API_VERSION@ -requires=@COGL_PKG_REQUIRES@ muffin-cogl-@MUFFIN_PLUGIN_API_VERSION@ - -Name: Cogl -Description: An object oriented GL/GLES Abstraction/Utility Layer -Version: @MUFFIN_VERSION@ -Libs: -L${libdir} -lmuffin-cogl-gles2-@MUFFIN_PLUGIN_API_VERSION@ -Cflags: -I${includedir}/cogl -Requires: ${requires} diff --git a/cogl/cogl-muffin-config.h.in b/cogl/cogl-muffin-config.h.in deleted file mode 100644 index bc7f146ce..000000000 --- a/cogl/cogl-muffin-config.h.in +++ /dev/null @@ -1,17 +0,0 @@ -/* Have GL for rendering */ -#undef HAVE_COGL_GL - -/* Have GLES 1.1 for rendering */ -#undef HAVE_COGL_GLES - -/* Have GLES 2.0 for rendering */ -#undef HAVE_COGL_GLES2 - -/* Define to 1 if you have the `ffs' function. */ -#undef HAVE_FFS - -/* Define to 1 if you have the `memmem' function. */ -#undef HAVE_MEMMEM - -/* Whether _Static_assert can be used or not */ -#undef HAVE_STATIC_ASSERT diff --git a/cogl/cogl-mutter-config.h.in b/cogl/cogl-mutter-config.h.in new file mode 100644 index 000000000..2c8967811 --- /dev/null +++ b/cogl/cogl-mutter-config.h.in @@ -0,0 +1,7 @@ +/* Have GL for rendering */ +#undef HAVE_COGL_GL + +/* Have GLES 2.0 for rendering */ +#undef HAVE_COGL_GLES2 + +#define COGL_CONFIG_H_INCLUDED 1 diff --git a/cogl/cogl-pango/Makefile.am b/cogl/cogl-pango/Makefile.am deleted file mode 100644 index 468dcb5d2..000000000 --- a/cogl/cogl-pango/Makefile.am +++ /dev/null @@ -1,93 +0,0 @@ -NULL = - -CLEANFILES = -DISTCLEANFILES = - -EXTRA_DIST = - -source_c = \ - cogl-pango-display-list.c \ - cogl-pango-fontmap.c \ - cogl-pango-render.c \ - cogl-pango-glyph-cache.c \ - cogl-pango-pipeline-cache.c \ - $(NULL) - -source_h = cogl-pango.h - -source_h_priv = \ - cogl-pango-display-list.h \ - cogl-pango-private.h \ - cogl-pango-glyph-cache.h \ - cogl-pango-pipeline-cache.h \ - $(NULL) - -muffinlibdir = $(libdir)/muffin -muffinlib_LTLIBRARIES = libmuffin-cogl-pango-@MUFFIN_PLUGIN_API_VERSION@.la - -libmuffin_cogl_pango_@MUFFIN_PLUGIN_API_VERSION@_la_SOURCES = $(source_c) $(source_h) $(source_h_priv) -libmuffin_cogl_pango_@MUFFIN_PLUGIN_API_VERSION@_la_CFLAGS = $(COGL_DEP_CFLAGS) $(COGL_PANGO_DEP_CFLAGS) $(COGL_EXTRA_CFLAGS) $(MAINTAINER_CFLAGS) -libmuffin_cogl_pango_@MUFFIN_PLUGIN_API_VERSION@_la_LIBADD = $(top_builddir)/cogl/libmuffin-cogl-$(MUFFIN_PLUGIN_API_VERSION).la -libmuffin_cogl_pango_@MUFFIN_PLUGIN_API_VERSION@_la_LIBADD += $(COGL_DEP_LIBS) $(COGL_PANGO_DEP_LIBS) $(COGL_EXTRA_LDFLAGS) -libmuffin_cogl_pango_@MUFFIN_PLUGIN_API_VERSION@_la_LDFLAGS = \ - -export-dynamic \ - -rpath $(muffinlibdir) \ - -export-symbols-regex "^cogl_pango_.*" \ - -no-undefined \ - -avoid-version - -AM_CPPFLAGS = \ - -DCOGL_COMPILATION \ - -DG_LOG_DOMAIN=\"CoglPango\" \ - -I$(top_srcdir)/cogl \ - -I$(top_builddir)/cogl \ - -I$(top_srcdir)/cogl/winsys \ - -I$(top_srcdir) \ - -I$(top_builddir) - -cogl_base_includedir = $(includedir)/muffin -cogl_pangoheadersdir = $(cogl_base_includedir)/cogl/cogl-pango -cogl_pangoheaders_HEADERS = $(source_h) - -pc_files = muffin-cogl-pango-$(MUFFIN_PLUGIN_API_VERSION).pc - -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = $(pc_files) - -DISTCLEANFILES += $(pc_files) - -EXTRA_DIST += cogl-pango.symbols - --include $(INTROSPECTION_MAKEFILE) - -INTROSPECTION_GIRS = - -if HAVE_INTROSPECTION -INTROSPECTION_COMPILER_ARGS=--includedir=$(top_builddir)/cogl - -CoglPango-@MUFFIN_PLUGIN_API_VERSION@.gir: libmuffin-cogl-pango-$(MUFFIN_PLUGIN_API_VERSION).la Makefile - -CoglPango_@MUFFIN_PLUGIN_API_VERSION@_gir_NAMESPACE = CoglPango -CoglPango_@MUFFIN_PLUGIN_API_VERSION@_gir_VERSION = @MUFFIN_PLUGIN_API_VERSION@ -CoglPango_@MUFFIN_PLUGIN_API_VERSION@_gir_LIBS = $(top_builddir)/cogl/libmuffin-cogl-$(MUFFIN_PLUGIN_API_VERSION).la libmuffin-cogl-pango-$(MUFFIN_PLUGIN_API_VERSION).la -CoglPango_@MUFFIN_PLUGIN_API_VERSION@_gir_FILES = $(source_h) $(source_c) -CoglPango_@MUFFIN_PLUGIN_API_VERSION@_gir_CFLAGS = $(AM_CPPFLAGS) $(COGL_DEP_CFLAGS) $(COGL_PANGO_DEP_CFLAGS) -CoglPango_@MUFFIN_PLUGIN_API_VERSION@_gir_INCLUDES = Pango-1.0 PangoCairo-1.0 -CoglPango_@MUFFIN_PLUGIN_API_VERSION@_gir_EXPORT_PACKAGES = muffin-cogl-pango-@MUFFIN_PLUGIN_API_VERSION@ -CoglPango_@MUFFIN_PLUGIN_API_VERSION@_gir_SCANNERFLAGS = \ - --warn-all \ - --identifier-prefix=CoglPango \ - --symbol-prefix=cogl_pango \ - --c-include='cogl-pango/cogl-pango.h' \ - --include-uninstalled=$(top_builddir)/cogl/Cogl-@MUFFIN_PLUGIN_API_VERSION@.gir - -INTROSPECTION_GIRS += CoglPango-@MUFFIN_PLUGIN_API_VERSION@.gir - -girdir = $(muffinlibdir) -gir_DATA = $(INTROSPECTION_GIRS) - -typelibdir = $(muffinlibdir) -typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib) - -CLEANFILES += $(gir_DATA) $(typelib_DATA) -endif diff --git a/cogl/cogl-pango/cogl-pango-display-list.c b/cogl/cogl-pango/cogl-pango-display-list.c index 3dc0f421b..caf202d06 100644 --- a/cogl/cogl-pango/cogl-pango-display-list.c +++ b/cogl/cogl-pango/cogl-pango-display-list.c @@ -26,9 +26,7 @@ * SOFTWARE. */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include #include @@ -49,7 +47,7 @@ typedef struct _CoglPangoDisplayListRectangle CoglPangoDisplayListRectangle; struct _CoglPangoDisplayList { - CoglBool color_override; + gboolean color_override; CoglColor color; GSList *nodes; GSList *last_node; @@ -67,7 +65,7 @@ struct _CoglPangoDisplayListNode { CoglPangoDisplayListNodeType type; - CoglBool color_override; + gboolean color_override; CoglColor color; CoglPipeline *pipeline; @@ -83,6 +81,7 @@ struct _CoglPangoDisplayListNode GArray *rectangles; /* A primitive representing those vertices */ CoglPrimitive *primitive; + guint has_color : 1; } texture; struct @@ -275,9 +274,10 @@ emit_vertex_buffer_geometry (CoglFramebuffer *fb, CoglAttributeBuffer *buffer; CoglVertexP2T2 *verts, *v; int n_verts; - CoglBool allocated = FALSE; + gboolean allocated = FALSE; CoglAttribute *attributes[2]; CoglPrimitive *prim; + CoglIndices *indices; int i; n_verts = node->d.texture.rectangles->len * 4; @@ -333,7 +333,7 @@ emit_vertex_buffer_geometry (CoglFramebuffer *fb, 0, /* offset */ verts, sizeof (CoglVertexP2T2) * n_verts); - free (verts); + g_free (verts); } else cogl_buffer_unmap (COGL_BUFFER (buffer)); @@ -356,22 +356,11 @@ emit_vertex_buffer_geometry (CoglFramebuffer *fb, attributes, 2 /* n_attributes */); -#ifdef CLUTTER_COGL_HAS_GL - if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_QUADS)) - cogl_primitive_set_mode (prim, GL_QUADS); - else -#endif - { - /* GLES doesn't support GL_QUADS so instead we use a VBO - with indexed vertices to generate GL_TRIANGLES from the - quads */ + indices = + cogl_get_rectangle_indices (ctx, node->d.texture.rectangles->len); - CoglIndices *indices = - cogl_get_rectangle_indices (ctx, node->d.texture.rectangles->len); - - cogl_primitive_set_indices (prim, indices, - node->d.texture.rectangles->len * 6); - } + cogl_primitive_set_indices (prim, indices, + node->d.texture.rectangles->len * 6); node->d.texture.primitive = prim; @@ -432,7 +421,9 @@ _cogl_pango_display_list_render (CoglFramebuffer *fb, cogl_color_get_red_byte (&node->color), cogl_color_get_green_byte (&node->color), cogl_color_get_blue_byte (&node->color), - cogl_color_get_alpha_byte (color)); + (cogl_color_get_alpha_byte (&node->color) * + cogl_color_get_alpha_byte (color) / + 255)); else draw_color = *color; cogl_color_premultiply (&draw_color); @@ -485,8 +476,8 @@ _cogl_pango_display_list_node_free (CoglPangoDisplayListNode *node) void _cogl_pango_display_list_clear (CoglPangoDisplayList *dl) { - g_slist_foreach (dl->nodes, (GFunc) _cogl_pango_display_list_node_free, NULL); - g_slist_free (dl->nodes); + g_slist_free_full (dl->nodes, (GDestroyNotify) + _cogl_pango_display_list_node_free); dl->nodes = NULL; dl->last_node = NULL; } diff --git a/cogl/cogl-pango/cogl-pango-display-list.h b/cogl/cogl-pango/cogl-pango-display-list.h index 5dbc074e0..03a686ee1 100644 --- a/cogl/cogl-pango/cogl-pango-display-list.h +++ b/cogl/cogl-pango/cogl-pango-display-list.h @@ -32,7 +32,7 @@ #include #include "cogl-pango-pipeline-cache.h" -COGL_BEGIN_DECLS +G_BEGIN_DECLS typedef struct _CoglPangoDisplayList CoglPangoDisplayList; @@ -79,6 +79,6 @@ _cogl_pango_display_list_clear (CoglPangoDisplayList *dl); void _cogl_pango_display_list_free (CoglPangoDisplayList *dl); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_PANGO_DISPLAY_LIST_H__ */ diff --git a/cogl/cogl-pango/cogl-pango-fontmap.c b/cogl/cogl-pango/cogl-pango-fontmap.c index 5c94e3564..714ba6546 100644 --- a/cogl/cogl-pango/cogl-pango-fontmap.c +++ b/cogl/cogl-pango/cogl-pango-fontmap.c @@ -34,9 +34,7 @@ * */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif /* This is needed to get the Pango headers to export stuff needed to subclass */ @@ -69,14 +67,14 @@ free_priv (gpointer data) cogl_object_unref (priv->ctx); cogl_object_unref (priv->renderer); - free (priv); + g_free (priv); } PangoFontMap * cogl_pango_font_map_new (void) { PangoFontMap *fm = pango_cairo_font_map_new (); - CoglPangoFontMapPriv *priv = g_new0 (CoglPangoFontMapPriv, 1); + g_autofree CoglPangoFontMapPriv *priv = g_new0 (CoglPangoFontMapPriv, 1); _COGL_GET_CONTEXT (context, NULL); @@ -87,7 +85,7 @@ cogl_pango_font_map_new (void) * for now. */ g_object_set_qdata_full (G_OBJECT (fm), cogl_pango_font_map_get_priv_key (), - priv, + g_steal_pointer (&priv), free_priv); return fm; @@ -96,7 +94,7 @@ cogl_pango_font_map_new (void) PangoContext * cogl_pango_font_map_create_context (CoglPangoFontMap *fm) { - _COGL_RETURN_VAL_IF_FAIL (COGL_PANGO_IS_FONT_MAP (fm), NULL); + g_return_val_if_fail (COGL_PANGO_IS_FONT_MAP (fm), NULL); #if PANGO_VERSION_CHECK (1, 22, 0) /* We can just directly use the pango context from the Cairo font @@ -140,7 +138,7 @@ void cogl_pango_font_map_set_resolution (CoglPangoFontMap *font_map, double dpi) { - _COGL_RETURN_IF_FAIL (COGL_PANGO_IS_FONT_MAP (font_map)); + g_return_if_fail (COGL_PANGO_IS_FONT_MAP (font_map)); pango_cairo_font_map_set_resolution (PANGO_CAIRO_FONT_MAP (font_map), dpi); } @@ -155,7 +153,7 @@ cogl_pango_font_map_clear_glyph_cache (CoglPangoFontMap *fm) void cogl_pango_font_map_set_use_mipmapping (CoglPangoFontMap *fm, - CoglBool value) + gboolean value) { PangoRenderer *renderer = _cogl_pango_font_map_get_renderer (fm); @@ -163,7 +161,7 @@ cogl_pango_font_map_set_use_mipmapping (CoglPangoFontMap *fm, value); } -CoglBool +gboolean cogl_pango_font_map_get_use_mipmapping (CoglPangoFontMap *fm) { PangoRenderer *renderer = _cogl_pango_font_map_get_renderer (fm); diff --git a/cogl/cogl-pango/cogl-pango-glyph-cache.c b/cogl/cogl-pango/cogl-pango-glyph-cache.c index bf54b5e10..10b73d752 100644 --- a/cogl/cogl-pango/cogl-pango-glyph-cache.c +++ b/cogl/cogl-pango/cogl-pango-glyph-cache.c @@ -26,9 +26,7 @@ * SOFTWARE. */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include @@ -56,16 +54,16 @@ struct _CoglPangoGlyphCache /* TRUE if we've ever stored a texture in the global atlas. This is used to make sure we only register one callback to listen for global atlas reorganizations */ - CoglBool using_global_atlas; + gboolean using_global_atlas; /* True if some of the glyphs are dirty. This is used as an optimization in _cogl_pango_glyph_cache_set_dirty_glyphs to avoid iterating the hash table if we know none of them are dirty */ - CoglBool has_dirty_glyphs; + gboolean has_dirty_glyphs; /* Whether mipmapping is being used for this cache. This only affects whether we decide to put the glyph in the global atlas */ - CoglBool use_mipmapping; + gboolean use_mipmapping; }; struct _CoglPangoGlyphCacheKey @@ -102,7 +100,7 @@ cogl_pango_glyph_cache_hash_func (const void *key) return GPOINTER_TO_UINT (cache_key->font) ^ cache_key->glyph; } -static CoglBool +static gboolean cogl_pango_glyph_cache_equal_func (const void *a, const void *b) { const CoglPangoGlyphCacheKey *key_a @@ -119,11 +117,11 @@ cogl_pango_glyph_cache_equal_func (const void *a, const void *b) CoglPangoGlyphCache * cogl_pango_glyph_cache_new (CoglContext *ctx, - CoglBool use_mipmapping) + gboolean use_mipmapping) { CoglPangoGlyphCache *cache; - cache = malloc (sizeof (CoglPangoGlyphCache)); + cache = g_malloc (sizeof (CoglPangoGlyphCache)); /* Note: as a rule we don't take references to a CoglContext * internally since */ @@ -182,7 +180,7 @@ cogl_pango_glyph_cache_free (CoglPangoGlyphCache *cache) g_hook_list_clear (&cache->reorganize_callbacks); - free (cache); + g_free (cache); } static void @@ -212,14 +210,14 @@ cogl_pango_glyph_cache_update_position_cb (void *user_data, value->dirty = TRUE; } -static CoglBool +static gboolean cogl_pango_glyph_cache_add_to_global_atlas (CoglPangoGlyphCache *cache, PangoFont *font, PangoGlyph glyph, CoglPangoGlyphCacheValue *value) { CoglAtlasTexture *texture; - CoglError *ignore_error = NULL; + GError *ignore_error = NULL; if (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_SHARED_ATLAS)) return FALSE; @@ -234,7 +232,7 @@ cogl_pango_glyph_cache_add_to_global_atlas (CoglPangoGlyphCache *cache, value->draw_height); if (!cogl_texture_allocate (COGL_TEXTURE (texture), &ignore_error)) { - cogl_error_free (ignore_error); + g_error_free (ignore_error); return FALSE; } @@ -261,7 +259,7 @@ cogl_pango_glyph_cache_add_to_global_atlas (CoglPangoGlyphCache *cache, return TRUE; } -static CoglBool +static gboolean cogl_pango_glyph_cache_add_to_local_atlas (CoglPangoGlyphCache *cache, PangoFont *font, PangoGlyph glyph, @@ -311,7 +309,7 @@ cogl_pango_glyph_cache_add_to_local_atlas (CoglPangoGlyphCache *cache, CoglPangoGlyphCacheValue * cogl_pango_glyph_cache_lookup (CoglPangoGlyphCache *cache, - CoglBool create, + gboolean create, PangoFont *font, PangoGlyph glyph) { diff --git a/cogl/cogl-pango/cogl-pango-glyph-cache.h b/cogl/cogl-pango/cogl-pango-glyph-cache.h index ca33203bc..a03330dd2 100644 --- a/cogl/cogl-pango/cogl-pango-glyph-cache.h +++ b/cogl/cogl-pango/cogl-pango-glyph-cache.h @@ -34,7 +34,7 @@ #include "cogl/cogl-texture.h" -COGL_BEGIN_DECLS +G_BEGIN_DECLS typedef struct _CoglPangoGlyphCache CoglPangoGlyphCache; typedef struct _CoglPangoGlyphCacheValue CoglPangoGlyphCacheValue; @@ -58,27 +58,29 @@ struct _CoglPangoGlyphCacheValue /* This will be set to TRUE when the glyph atlas is reorganized which means the glyph will need to be redrawn */ - CoglBool dirty; + guint dirty : 1; + /* Set to TRUE if the glyph has colors (eg. emoji) */ + guint has_color : 1; }; typedef void (* CoglPangoGlyphCacheDirtyFunc) (PangoFont *font, PangoGlyph glyph, CoglPangoGlyphCacheValue *value); -CoglPangoGlyphCache * +COGL_EXPORT CoglPangoGlyphCache * cogl_pango_glyph_cache_new (CoglContext *ctx, - CoglBool use_mipmapping); + gboolean use_mipmapping); -void +COGL_EXPORT void cogl_pango_glyph_cache_free (CoglPangoGlyphCache *cache); -CoglPangoGlyphCacheValue * +COGL_EXPORT CoglPangoGlyphCacheValue * cogl_pango_glyph_cache_lookup (CoglPangoGlyphCache *cache, - CoglBool create, + gboolean create, PangoFont *font, PangoGlyph glyph); -void +COGL_EXPORT void cogl_pango_glyph_cache_clear (CoglPangoGlyphCache *cache); void @@ -95,6 +97,6 @@ void _cogl_pango_glyph_cache_set_dirty_glyphs (CoglPangoGlyphCache *cache, CoglPangoGlyphCacheDirtyFunc func); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_PANGO_GLYPH_CACHE_H__ */ diff --git a/cogl/cogl-pango/cogl-pango-pipeline-cache.c b/cogl/cogl-pango/cogl-pango-pipeline-cache.c index 9224b216a..fdc340908 100644 --- a/cogl/cogl-pango/cogl-pango-pipeline-cache.c +++ b/cogl/cogl-pango/cogl-pango-pipeline-cache.c @@ -31,9 +31,7 @@ * Neil Roberts */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include #include "cogl-pango-pipeline-cache.h" @@ -76,7 +74,7 @@ _cogl_pango_pipeline_cache_value_destroy (void *data) CoglPangoPipelineCache * _cogl_pango_pipeline_cache_new (CoglContext *ctx, - CoglBool use_mipmapping) + gboolean use_mipmapping) { CoglPangoPipelineCache *cache = g_new (CoglPangoPipelineCache, 1); @@ -238,5 +236,5 @@ _cogl_pango_pipeline_cache_free (CoglPangoPipelineCache *cache) cogl_object_unref (cache->ctx); - free (cache); + g_free (cache); } diff --git a/cogl/cogl-pango/cogl-pango-pipeline-cache.h b/cogl/cogl-pango/cogl-pango-pipeline-cache.h index c8abe2c34..2cd887812 100644 --- a/cogl/cogl-pango/cogl-pango-pipeline-cache.h +++ b/cogl/cogl-pango/cogl-pango-pipeline-cache.h @@ -38,7 +38,7 @@ #include "cogl/cogl-context-private.h" -COGL_BEGIN_DECLS +G_BEGIN_DECLS typedef struct _CoglPangoPipelineCache { @@ -49,13 +49,13 @@ typedef struct _CoglPangoPipelineCache CoglPipeline *base_texture_alpha_pipeline; CoglPipeline *base_texture_rgba_pipeline; - CoglBool use_mipmapping; + gboolean use_mipmapping; } CoglPangoPipelineCache; CoglPangoPipelineCache * _cogl_pango_pipeline_cache_new (CoglContext *ctx, - CoglBool use_mipmapping); + gboolean use_mipmapping); /* Returns a pipeline that can be used to render glyphs in the given texture. The pipeline has a new reference so it is up to the caller @@ -67,6 +67,6 @@ _cogl_pango_pipeline_cache_get (CoglPangoPipelineCache *cache, void _cogl_pango_pipeline_cache_free (CoglPangoPipelineCache *cache); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_PANGO_PIPELINE_CACHE_H__ */ diff --git a/cogl/cogl-pango/cogl-pango-private.h b/cogl/cogl-pango/cogl-pango-private.h index e0d1f51fa..c29100a66 100644 --- a/cogl/cogl-pango/cogl-pango-private.h +++ b/cogl/cogl-pango/cogl-pango-private.h @@ -38,7 +38,7 @@ #include "cogl-pango.h" -COGL_BEGIN_DECLS +G_BEGIN_DECLS PangoRenderer * _cogl_pango_renderer_new (CoglContext *context); @@ -48,8 +48,8 @@ _cogl_pango_renderer_clear_glyph_cache (CoglPangoRenderer *renderer); void _cogl_pango_renderer_set_use_mipmapping (CoglPangoRenderer *renderer, - CoglBool value); -CoglBool + gboolean value); +gboolean _cogl_pango_renderer_get_use_mipmapping (CoglPangoRenderer *renderer); @@ -60,6 +60,6 @@ _cogl_pango_font_map_get_cogl_context (CoglPangoFontMap *fm); PangoRenderer * _cogl_pango_font_map_get_renderer (CoglPangoFontMap *fm); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_PANGO_PRIVATE_H__ */ diff --git a/cogl/cogl-pango/cogl-pango-render.c b/cogl/cogl-pango/cogl-pango-render.c index d8cc71306..07ba0ca4b 100644 --- a/cogl/cogl-pango/cogl-pango-render.c +++ b/cogl/cogl-pango/cogl-pango-render.c @@ -33,18 +33,24 @@ * Matthew Allum */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #ifndef PANGO_ENABLE_BACKEND #define PANGO_ENABLE_BACKEND 1 #endif +#ifndef PANGO_UNKNOWN_GLYPH_WIDTH +#define PANGO_UNKNOWN_GLYPH_WIDTH 10 +#endif +#ifndef PANGO_UNKNOWN_GLYPH_HEIGHT +#define PANGO_UNKNOWN_GLYPH_HEIGHT 14 +#endif + #include #include #include #include +#include #include "cogl/cogl-debug.h" #include "cogl/cogl-context-private.h" @@ -78,7 +84,7 @@ struct _CoglPangoRenderer CoglPangoRendererCaches no_mipmap_caches; CoglPangoRendererCaches mipmap_caches; - CoglBool use_mipmapping; + gboolean use_mipmapping; /* The current display list that is being built */ CoglPangoDisplayList *display_list; @@ -104,7 +110,7 @@ struct _CoglPangoLayoutQdata /* Whether mipmapping was previously used to render this layout. We need to regenerate the display list if the mipmapping value is changed because it will be using a different set of textures */ - CoglBool mipmapping_used; + gboolean mipmapping_used; }; static void @@ -155,7 +161,7 @@ cogl_pango_renderer_draw_glyph (CoglPangoRenderer *priv, { CoglPangoRendererSliceCbData data; - _COGL_RETURN_IF_FAIL (priv->display_list != NULL); + g_return_if_fail (priv->display_list != NULL); data.display_list = priv->display_list; data.x1 = x1; @@ -449,34 +455,6 @@ cogl_pango_show_layout (CoglFramebuffer *fb, } } -void -cogl_pango_render_layout_subpixel (PangoLayout *layout, - int x, - int y, - const CoglColor *color, - int flags) -{ - cogl_pango_show_layout (cogl_get_draw_framebuffer (), - layout, - x / (float) PANGO_SCALE, - y / (float) PANGO_SCALE, - color); -} - -void -cogl_pango_render_layout (PangoLayout *layout, - int x, - int y, - const CoglColor *color, - int flags) -{ - cogl_pango_render_layout_subpixel (layout, - x * PANGO_SCALE, - y * PANGO_SCALE, - color, - flags); -} - void cogl_pango_show_layout_line (CoglFramebuffer *fb, PangoLayoutLine *line, @@ -514,19 +492,6 @@ cogl_pango_show_layout_line (CoglFramebuffer *fb, priv->display_list = NULL; } -void -cogl_pango_render_layout_line (PangoLayoutLine *line, - int x, - int y, - const CoglColor *color) -{ - cogl_pango_show_layout_line (cogl_get_draw_framebuffer (), - line, - x / (float) PANGO_SCALE, - y / (float) PANGO_SCALE, - color); -} - void _cogl_pango_renderer_clear_glyph_cache (CoglPangoRenderer *renderer) { @@ -536,12 +501,12 @@ _cogl_pango_renderer_clear_glyph_cache (CoglPangoRenderer *renderer) void _cogl_pango_renderer_set_use_mipmapping (CoglPangoRenderer *renderer, - CoglBool value) + gboolean value) { renderer->use_mipmapping = value; } -CoglBool +gboolean _cogl_pango_renderer_get_use_mipmapping (CoglPangoRenderer *renderer) { return renderer->use_mipmapping; @@ -549,7 +514,7 @@ _cogl_pango_renderer_get_use_mipmapping (CoglPangoRenderer *renderer) static CoglPangoGlyphCacheValue * cogl_pango_renderer_get_cached_glyph (PangoRenderer *renderer, - CoglBool create, + gboolean create, PangoFont *font, PangoGlyph glyph) { @@ -562,6 +527,24 @@ cogl_pango_renderer_get_cached_glyph (PangoRenderer *renderer, create, font, glyph); } +static gboolean +font_has_color_glyphs (const PangoFont *font) +{ + cairo_scaled_font_t *scaled_font; + gboolean has_color = FALSE; + + scaled_font = pango_cairo_font_get_scaled_font ((PangoCairoFont *) font); + + if (cairo_scaled_font_get_type (scaled_font) == CAIRO_FONT_TYPE_FT) + { + FT_Face ft_face = cairo_ft_scaled_font_lock_face (scaled_font); + has_color = (FT_HAS_COLOR (ft_face) != 0); + cairo_ft_scaled_font_unlock_face (scaled_font); + } + + return has_color; +} + static void cogl_pango_renderer_set_dirty_glyph (PangoFont *font, PangoGlyph glyph, @@ -579,7 +562,7 @@ cogl_pango_renderer_set_dirty_glyph (PangoFont *font, /* Glyphs that don't take up any space will end up without a texture. These should never become dirty so they shouldn't end up here */ - _COGL_RETURN_IF_FAIL (value->texture != NULL); + g_return_if_fail (value->texture != NULL); if (_cogl_texture_get_format (value->texture) == COGL_PIXEL_FORMAT_A_8) { @@ -636,6 +619,8 @@ cogl_pango_renderer_set_dirty_glyph (PangoFont *font, cairo_image_surface_get_data (surface)); cairo_surface_destroy (surface); + + value->has_color = font_has_color_glyphs (font); } static void @@ -707,7 +692,7 @@ cogl_pango_ensure_glyph_cache_for_layout (PangoLayout *layout) context = pango_layout_get_context (layout); priv = cogl_pango_get_renderer_from_context (context); - _COGL_RETURN_IF_FAIL (PANGO_IS_LAYOUT (layout)); + g_return_if_fail (PANGO_IS_LAYOUT (layout)); if ((iter = pango_layout_get_iter (layout)) == NULL) return; @@ -734,6 +719,7 @@ cogl_pango_renderer_set_color_for_part (PangoRenderer *renderer, PangoRenderPart part) { PangoColor *pango_color = pango_renderer_get_color (renderer, part); + uint16_t alpha = pango_renderer_get_alpha (renderer, part); CoglPangoRenderer *priv = COGL_PANGO_RENDERER (renderer); if (pango_color) @@ -744,7 +730,7 @@ cogl_pango_renderer_set_color_for_part (PangoRenderer *renderer, pango_color->red >> 8, pango_color->green >> 8, pango_color->blue >> 8, - 0xff); + alpha ? alpha >> 8 : 0xff); _cogl_pango_display_list_set_color_override (priv->display_list, &color); } @@ -761,7 +747,7 @@ cogl_pango_renderer_draw_box (PangoRenderer *renderer, { CoglPangoRenderer *priv = COGL_PANGO_RENDERER (renderer); - _COGL_RETURN_IF_FAIL (priv->display_list != NULL); + g_return_if_fail (priv->display_list != NULL); _cogl_pango_display_list_add_rectangle (priv->display_list, x, @@ -805,7 +791,7 @@ cogl_pango_renderer_draw_rectangle (PangoRenderer *renderer, CoglPangoRenderer *priv = COGL_PANGO_RENDERER (renderer); float x1, x2, y1, y2; - _COGL_RETURN_IF_FAIL (priv->display_list != NULL); + g_return_if_fail (priv->display_list != NULL); cogl_pango_renderer_set_color_for_part (renderer, part); @@ -832,7 +818,7 @@ cogl_pango_renderer_draw_trapezoid (PangoRenderer *renderer, { CoglPangoRenderer *priv = COGL_PANGO_RENDERER (renderer); - _COGL_RETURN_IF_FAIL (priv->display_list != NULL); + g_return_if_fail (priv->display_list != NULL); cogl_pango_renderer_set_color_for_part (renderer, part); @@ -856,14 +842,13 @@ cogl_pango_renderer_draw_glyphs (PangoRenderer *renderer, CoglPangoGlyphCacheValue *cache_value; int i; - cogl_pango_renderer_set_color_for_part (renderer, - PANGO_RENDER_PART_FOREGROUND); - for (i = 0; i < glyphs->num_glyphs; i++) { PangoGlyphInfo *gi = glyphs->glyphs + i; float x, y; + cogl_pango_renderer_set_color_for_part (renderer, + PANGO_RENDER_PART_FOREGROUND); cogl_pango_renderer_get_device_units (renderer, xi + gi->geometry.x_offset, yi + gi->geometry.y_offset, @@ -920,6 +905,19 @@ cogl_pango_renderer_draw_glyphs (PangoRenderer *renderer, x += (float)(cache_value->draw_x); y += (float)(cache_value->draw_y); + /* Do not override color if the glyph/font provide its own */ + if (cache_value->has_color) + { + CoglColor color; + uint16_t alpha; + + alpha = pango_renderer_get_alpha (renderer, + PANGO_RENDER_PART_FOREGROUND); + cogl_color_init_from_4ub (&color, 0xff, 0xff, 0xff, + alpha ? alpha >> 8 : 0xff); + _cogl_pango_display_list_set_color_override (priv->display_list, &color); + } + cogl_pango_renderer_draw_glyph (priv, cache_value, x, y); } } diff --git a/cogl/cogl-pango/cogl-pango.h b/cogl/cogl-pango/cogl-pango.h index 787aaa8af..cd57e6b00 100644 --- a/cogl/cogl-pango/cogl-pango.h +++ b/cogl/cogl-pango/cogl-pango.h @@ -54,7 +54,7 @@ #include "cogl/cogl-macros.h" #endif -COGL_BEGIN_DECLS +G_BEGIN_DECLS /* It's too difficult to actually subclass the pango cairo font * map. Instead we just make a fake set of macros that actually just @@ -75,7 +75,7 @@ typedef PangoCairoFontMap CoglPangoFontMap; * * Since: 1.14 */ -PangoFontMap * +COGL_EXPORT PangoFontMap * cogl_pango_font_map_new (void); /** @@ -86,7 +86,7 @@ cogl_pango_font_map_new (void); * * Returns: (transfer full): the newly created context: free with g_object_unref(). */ -PangoContext * +COGL_EXPORT PangoContext * cogl_pango_font_map_create_context (CoglPangoFontMap *font_map); /** @@ -102,7 +102,7 @@ cogl_pango_font_map_create_context (CoglPangoFontMap *font_map); * * Since: 1.14 */ -void +COGL_EXPORT void cogl_pango_font_map_set_resolution (CoglPangoFontMap *font_map, double dpi); @@ -114,7 +114,7 @@ cogl_pango_font_map_set_resolution (CoglPangoFontMap *font_map, * * Since: 1.0 */ -void +COGL_EXPORT void cogl_pango_font_map_clear_glyph_cache (CoglPangoFontMap *font_map); /** @@ -129,7 +129,7 @@ cogl_pango_font_map_clear_glyph_cache (CoglPangoFontMap *font_map); * * Since: 1.0 */ -void +COGL_EXPORT void cogl_pango_ensure_glyph_cache_for_layout (PangoLayout *layout); /** @@ -142,9 +142,9 @@ cogl_pango_ensure_glyph_cache_for_layout (PangoLayout *layout); * * Since: 1.0 */ -void +COGL_EXPORT void cogl_pango_font_map_set_use_mipmapping (CoglPangoFontMap *font_map, - CoglBool value); + gboolean value); /** * cogl_pango_font_map_get_use_mipmapping: @@ -157,7 +157,7 @@ cogl_pango_font_map_set_use_mipmapping (CoglPangoFontMap *font_map, * * Since: 1.0 */ -CoglBool +COGL_EXPORT gboolean cogl_pango_font_map_get_use_mipmapping (CoglPangoFontMap *font_map); /** @@ -170,7 +170,7 @@ cogl_pango_font_map_get_use_mipmapping (CoglPangoFontMap *font_map); * * Since: 1.0 */ -PangoRenderer * +COGL_EXPORT PangoRenderer * cogl_pango_font_map_get_renderer (CoglPangoFontMap *font_map); /** @@ -187,7 +187,7 @@ cogl_pango_font_map_get_renderer (CoglPangoFontMap *font_map); * * Since: 1.14 */ -void +COGL_EXPORT void cogl_pango_show_layout (CoglFramebuffer *framebuffer, PangoLayout *layout, float x, @@ -208,7 +208,7 @@ cogl_pango_show_layout (CoglFramebuffer *framebuffer, * * Since: 1.14 */ -void +COGL_EXPORT void cogl_pango_show_layout_line (CoglFramebuffer *framebuffer, PangoLayoutLine *line, float x, @@ -227,73 +227,8 @@ cogl_pango_show_layout_line (CoglFramebuffer *framebuffer, typedef struct _CoglPangoRenderer CoglPangoRenderer; typedef struct _CoglPangoRendererClass CoglPangoRendererClass; -GType cogl_pango_renderer_get_type (void) G_GNUC_CONST; +COGL_EXPORT GType cogl_pango_renderer_get_type (void) G_GNUC_CONST; -/** - * cogl_pango_render_layout_subpixel: - * @layout: a #PangoLayout - * @x: X coordinate (in Pango units) to render the layout at - * @y: Y coordinate (in Pango units) to render the layout at - * @color: color to use when rendering the layout - * @flags: - * - * Draws a solidly coloured @layout on the given @framebuffer at (@x, - * @y) within the @framebuffer's current model-view coordinate - * space. - * - * Since: 1.0 - * Deprecated: 1.16: Use cogl_pango_show_layout() instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pango_show_layout) -void -cogl_pango_render_layout_subpixel (PangoLayout *layout, - int x, - int y, - const CoglColor *color, - int flags); - -/** - * cogl_pango_render_layout: - * @layout: a #PangoLayout - * @x: X coordinate to render the layout at - * @y: Y coordinate to render the layout at - * @color: color to use when rendering the layout - * @flags: - * - * Draws a solidly coloured @layout on the given @framebuffer at (@x, - * @y) within the @framebuffer's current model-view coordinate - * space. - * - * Since: 1.0 - * Deprecated: 1.16: Use cogl_pango_show_layout() instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pango_show_layout) -void -cogl_pango_render_layout (PangoLayout *layout, - int x, - int y, - const CoglColor *color, - int flags); - -/** - * cogl_pango_render_layout_line: - * @line: a #PangoLayoutLine - * @x: X coordinate to render the line at - * @y: Y coordinate to render the line at - * @color: color to use when rendering the line - * - * Renders @line at the given coordinates using the given color. - * - * Since: 1.0 - * Deprecated: 1.16: Use cogl_pango_show_layout() instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pango_show_layout_line) -void -cogl_pango_render_layout_line (PangoLayoutLine *line, - int x, - int y, - const CoglColor *color); - -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_PANGO_H__ */ diff --git a/cogl/cogl-pango/cogl-pango.symbols b/cogl/cogl-pango/cogl-pango.symbols index b86c9560e..33258b895 100644 --- a/cogl/cogl-pango/cogl-pango.symbols +++ b/cogl/cogl-pango/cogl-pango.symbols @@ -7,6 +7,3 @@ cogl_pango_font_map_new cogl_pango_font_map_set_resolution cogl_pango_font_map_set_use_mipmapping cogl_pango_renderer_get_type -cogl_pango_render_layout -cogl_pango_render_layout_line -cogl_pango_render_layout_subpixel diff --git a/cogl/cogl-pango/meson.build b/cogl/cogl-pango/meson.build new file mode 100644 index 000000000..a33b6907a --- /dev/null +++ b/cogl/cogl-pango/meson.build @@ -0,0 +1,81 @@ +cogl_pango_sources = [ + 'cogl-pango-display-list.c', + 'cogl-pango-display-list.h', + 'cogl-pango-fontmap.c', + 'cogl-pango-glyph-cache.c', + 'cogl-pango-glyph-cache.h', + 'cogl-pango-pipeline-cache.c', + 'cogl-pango-pipeline-cache.h', + 'cogl-pango-private.h', + 'cogl-pango-render.c', +] + +cogl_pango_public_headers = [ + 'cogl-pango.h', +] + +cogl_pango_deps = [ + pango_dep, + pangocairo_dep, + libmutter_cogl_dep, +] + +libmutter_cogl_pango = shared_library('muffin-cogl-pango-' + libmutter_api_version, + sources: [cogl_pango_sources, cogl_pango_public_headers], + version: '0.0.0', + soversion: 0, + c_args: cogl_c_args, + include_directories: [cogl_includepath, cogl_path_includepath], + gnu_symbol_visibility: 'hidden', + dependencies: [cogl_pango_deps], + install_rpath: pkglibdir, + install_dir: pkglibdir, + install: true, +) + +libmutter_cogl_pango_dep = declare_dependency( + link_with: libmutter_cogl_pango, +) + +if have_introspection + libmutter_cogl_pango_gir = gnome.generate_gir(libmutter_cogl_pango, + sources: cogl_pango_public_headers, + nsversion: libmutter_api_version, + namespace: 'CoglPango', + symbol_prefix: 'cogl_pango', + header: 'cogl-pango.h', + includes: [ + libmutter_cogl_gir[0], + 'Pango-1.0', + 'PangoCairo-1.0' + ], + dependencies: [ + cogl_deps, + pango_dep, + libmutter_cogl_pango_dep, + ], + extra_args: introspection_args + [ + '-UCOGL_COMPILATION', + '-DG_LOG_DOMAIN="CoglPango"', + ], + install_dir_gir: pkglibdir, + install_dir_typelib: pkglibdir, + install: true + ) +endif + +cogl_pango_includesubdir = join_paths(cogl_includesubdir, 'cogl-pango') +install_headers(cogl_pango_public_headers, subdir: cogl_pango_includesubdir) + +pkg.generate(libmutter_cogl_pango, + name: 'CoglPango', + filebase: 'muffin-cogl-pango-' + libmutter_api_version, + description: 'A text rendering for Cogl in mutter', + subdirs: join_paths(pkgname, 'cogl'), + requires: [cogl_pkg_deps, libmutter_cogl_name], + version: meson.project_version(), + variables: [ + 'apiversion=' + libmutter_api_version, + ], + install_dir: pcdir, +) diff --git a/cogl/cogl-pango/muffin-cogl-pango.pc.in b/cogl/cogl-pango/muffin-cogl-pango.pc.in deleted file mode 100644 index 25d2d47c1..000000000 --- a/cogl/cogl-pango/muffin-cogl-pango.pc.in +++ /dev/null @@ -1,13 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@/muffin -includedir=@includedir@/muffin -apiversion=@MUFFIN_PLUGIN_API_VERSION@ -requires=@COGL_PKG_REQUIRES@ muffin-cogl-@MUFFIN_PLUGIN_API_VERSION@ - -Name: Cogl -Description: An object oriented GL/GLES Abstraction/Utility Layer -Version: @MUFFIN_VERSION@ -Libs: -L${libdir} -lmuffin-cogl-pango-@MUFFIN_PLUGIN_API_VERSION@ -Cflags: -I${includedir}/cogl -Requires: ${requires} diff --git a/cogl/cogl-pango/mutter-cogl-pango.pc.in b/cogl/cogl-pango/mutter-cogl-pango.pc.in new file mode 100644 index 000000000..d0ab7c45f --- /dev/null +++ b/cogl/cogl-pango/mutter-cogl-pango.pc.in @@ -0,0 +1,13 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +apiversion=@LIBMUTTER_API_VERSION@ +libdir=@libdir@/mutter-${apiversion} +includedir=@includedir@/mutter-${apiversion} +requires=@COGL_PKG_REQUIRES@ mutter-cogl-${apiversion} + +Name: Cogl +Description: An object oriented GL/GLES Abstraction/Utility Layer +Version: @MUTTER_VERSION@ +Libs: -L${libdir} -lmutter-cogl-pango-${apiversion} +Cflags: -I${includedir}/cogl +Requires: ${requires} diff --git a/cogl/cogl-path/Makefile.am b/cogl/cogl-path/Makefile.am deleted file mode 100644 index 298eb9192..000000000 --- a/cogl/cogl-path/Makefile.am +++ /dev/null @@ -1,102 +0,0 @@ -NULL = - -BUILT_SOURCES = - -CLEANFILES = -DISTCLEANFILES = - -EXTRA_DIST = - -# tesselator sources -cogl_tesselator_sources = \ - tesselator/dict-list.h \ - tesselator/dict.c \ - tesselator/dict.h \ - tesselator/geom.c \ - tesselator/geom.h \ - tesselator/gluos.h \ - tesselator/memalloc.h \ - tesselator/mesh.c \ - tesselator/mesh.h \ - tesselator/normal.c \ - tesselator/normal.h \ - tesselator/priorityq-heap.h \ - tesselator/priorityq-sort.h \ - tesselator/priorityq.c \ - tesselator/priorityq.h \ - tesselator/render.c \ - tesselator/render.h \ - tesselator/sweep.c \ - tesselator/sweep.h \ - tesselator/tess.c \ - tesselator/tess.h \ - tesselator/tesselator.h \ - tesselator/tessmono.c \ - tesselator/tessmono.h \ - tesselator/GL/glu.h \ - $(NULL) - -source_c = \ - $(cogl_tesselator_sources) \ - cogl-path-private.h \ - cogl-path.c \ - $(NULL) - -EXTRA_DIST += \ - tesselator/README \ - tesselator/priorityq-heap.c \ - cogl-path.symbols \ - $(NULL) - -source_1_x_h = \ - cogl-path-types.h \ - $(NULL) - -source_h = \ - cogl-path.h \ - $(source_1_x_h) \ - cogl-path-functions.h \ - $(NULL) - -# glib-mkenums rules -glib_enum_h = cogl-path-enum-types.h -glib_enum_c = cogl-path-enum-types.c -glib_enum_headers = $(source_1_x_h) -include $(top_srcdir)/build/autotools/Makefile.am.enums - -muffinlibdir = $(libdir)/muffin -muffinlib_LTLIBRARIES = libmuffin-cogl-path-@MUFFIN_PLUGIN_API_VERSION@.la - -libmuffin_cogl_path_@MUFFIN_PLUGIN_API_VERSION@_la_SOURCES = $(source_c) $(source_h) -nodist_libmuffin_cogl_path_@MUFFIN_PLUGIN_API_VERSION@_la_SOURCES = $(BUILT_SOURCES) -libmuffin_cogl_path_@MUFFIN_PLUGIN_API_VERSION@_la_CFLAGS = $(COGL_DEP_CFLAGS) $(COGL_EXTRA_CFLAGS) $(MAINTAINER_CFLAGS) -libmuffin_cogl_path_@MUFFIN_PLUGIN_API_VERSION@_la_LIBADD = $(top_builddir)/cogl/libmuffin-cogl-$(MUFFIN_PLUGIN_API_VERSION).la -lm -libmuffin_cogl_path_@MUFFIN_PLUGIN_API_VERSION@_la_LIBADD += $(COGL_DEP_LIBS) $(COGL_EXTRA_LDFLAGS) -libmuffin_cogl_path_@MUFFIN_PLUGIN_API_VERSION@_la_LDFLAGS = \ - -export-dynamic \ - -export-symbols-regex "^(cogl|cogl2)_(framebuffer|path|is|clip|[sg]et)_.*" \ - -no-undefined \ - -avoid-version \ - -rpath $(muffinlibdir) - -AM_CPPFLAGS = \ - -DCOGL_COMPILATION \ - -DG_LOG_DOMAIN=\"CoglPath\" \ - -I$(srcdir)/tesselator \ - -I$(top_srcdir)/cogl \ - -I$(top_builddir)/cogl \ - -I$(top_srcdir)/cogl/winsys \ - -I$(top_srcdir) \ - -I$(top_builddir) - -cogl_base_includedir = $(includedir)/muffin -cogl_pathheadersdir = $(cogl_base_includedir)/cogl/cogl-path -cogl_pathheaders_HEADERS = $(source_h) -nodist_cogl_pathheaders_HEADERS = cogl-path-enum-types.h - -pc_files = muffin-cogl-path-$(MUFFIN_PLUGIN_API_VERSION).pc - -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = $(pc_files) - -DISTCLEANFILES += $(pc_files) diff --git a/cogl/cogl-path/cogl-path-enum-types.c.in b/cogl/cogl-path/cogl-path-enum-types.c.in index 661e81ca2..7209da80a 100644 --- a/cogl/cogl-path/cogl-path-enum-types.c.in +++ b/cogl/cogl-path/cogl-path-enum-types.c.in @@ -1,7 +1,5 @@ /*** BEGIN file-header ***/ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif /* We need to undefine this so that we will be sure to include * cogl-path.h instead of cogl2-path.h when we include the framebuffer diff --git a/cogl/cogl-path/cogl-path-enum-types.h.in b/cogl/cogl-path/cogl-path-enum-types.h.in index 071686acd..2b377ed18 100644 --- a/cogl/cogl-path/cogl-path-enum-types.h.in +++ b/cogl/cogl-path/cogl-path-enum-types.h.in @@ -9,7 +9,7 @@ G_BEGIN_DECLS /*** END file-header ***/ /*** BEGIN file-production ***/ -/* enumerations from "@filename@" */ +/* enumerations from "@basename@" */ /*** END file-production ***/ /*** BEGIN file-tail ***/ diff --git a/cogl/cogl-path/cogl-path-functions.h b/cogl/cogl-path/cogl-path-functions.h index 489b25c29..11e935b6c 100644 --- a/cogl/cogl-path/cogl-path-functions.h +++ b/cogl/cogl-path/cogl-path-functions.h @@ -43,13 +43,14 @@ #endif #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS /** * cogl_path_get_gtype: * * Returns: a #GType that can be used with the GLib type system. */ +COGL_EXPORT GType cogl_path_get_gtype (void); #define cogl_path_new cogl2_path_new @@ -64,7 +65,7 @@ GType cogl_path_get_gtype (void); * * Since: 2.0 */ -CoglPath * +COGL_EXPORT CoglPath * cogl_path_new (void); /** @@ -82,7 +83,7 @@ cogl_path_new (void); * * Since: 2.0 */ -CoglPath * +COGL_EXPORT CoglPath * cogl_path_copy (CoglPath *path); /** @@ -96,7 +97,7 @@ cogl_path_copy (CoglPath *path); * * Since: 2.0 */ -CoglBool +COGL_EXPORT gboolean cogl_is_path (void *object); #define cogl_path_move_to cogl2_path_move_to @@ -110,7 +111,7 @@ cogl_is_path (void *object); * * Since: 2.0 */ -void +COGL_EXPORT void cogl_path_move_to (CoglPath *path, float x, float y); @@ -127,7 +128,7 @@ cogl_path_move_to (CoglPath *path, * * Since: 2.0 */ -void +COGL_EXPORT void cogl_path_rel_move_to (CoglPath *path, float x, float y); @@ -143,7 +144,7 @@ cogl_path_rel_move_to (CoglPath *path, * * Since: 2.0 */ -void +COGL_EXPORT void cogl_path_line_to (CoglPath *path, float x, float y); @@ -159,7 +160,7 @@ cogl_path_line_to (CoglPath *path, * * Since: 2.0 */ -void +COGL_EXPORT void cogl_path_rel_line_to (CoglPath *path, float x, float y); @@ -187,7 +188,7 @@ cogl_path_rel_line_to (CoglPath *path, * * Since: 2.0 */ -void +COGL_EXPORT void cogl_path_arc (CoglPath *path, float center_x, float center_y, @@ -212,7 +213,7 @@ cogl_path_arc (CoglPath *path, * * Since: 2.0 */ -void +COGL_EXPORT void cogl_path_curve_to (CoglPath *path, float x_1, float y_1, @@ -238,7 +239,7 @@ cogl_path_curve_to (CoglPath *path, * * Since: 2.0 */ -void +COGL_EXPORT void cogl_path_rel_curve_to (CoglPath *path, float x_1, float y_1, @@ -256,7 +257,7 @@ cogl_path_rel_curve_to (CoglPath *path, * * Since: 2.0 */ -void +COGL_EXPORT void cogl_path_close (CoglPath *path); #define cogl_path_line cogl2_path_line @@ -273,7 +274,7 @@ cogl_path_close (CoglPath *path); * * Since: 2.0 */ -void +COGL_EXPORT void cogl_path_line (CoglPath *path, float x_1, float y_1, @@ -301,7 +302,7 @@ cogl_path_line (CoglPath *path, * * Since: 2.0 */ -void +COGL_EXPORT void cogl_path_polyline (CoglPath *path, const float *coords, int num_points); @@ -323,7 +324,7 @@ cogl_path_polyline (CoglPath *path, * * Since: 2.0 */ -void +COGL_EXPORT void cogl_path_polygon (CoglPath *path, const float *coords, int num_points); @@ -341,7 +342,7 @@ cogl_path_polygon (CoglPath *path, * * Since: 2.0 */ -void +COGL_EXPORT void cogl_path_rectangle (CoglPath *path, float x_1, float y_1, @@ -361,7 +362,7 @@ cogl_path_rectangle (CoglPath *path, * * Since: 2.0 */ -void +COGL_EXPORT void cogl_path_ellipse (CoglPath *path, float center_x, float center_y, @@ -384,7 +385,7 @@ cogl_path_ellipse (CoglPath *path, * * Since: 2.0 */ -void +COGL_EXPORT void cogl_path_round_rectangle (CoglPath *path, float x_1, float y_1, @@ -406,7 +407,7 @@ cogl_path_round_rectangle (CoglPath *path, * * Since: 2.0 */ -void +COGL_EXPORT void cogl_path_set_fill_rule (CoglPath *path, CoglPathFillRule fill_rule); #define cogl_path_get_fill_rule cogl2_path_get_fill_rule @@ -419,29 +420,9 @@ cogl_path_set_fill_rule (CoglPath *path, CoglPathFillRule fill_rule); * * Since: 2.0 */ -CoglPathFillRule +COGL_EXPORT CoglPathFillRule cogl_path_get_fill_rule (CoglPath *path); -#define cogl_path_fill cogl2_path_fill -/** - * cogl_path_fill: - * - * Fills the interior of the constructed shape using the current - * drawing color. - * - * The interior of the shape is determined using the fill rule of the - * path. See %CoglPathFillRule for details. - * - * The result of referencing sliced textures in your current - * pipeline when filling a path are undefined. You should pass - * the %COGL_TEXTURE_NO_SLICING flag when loading any texture you will - * use while filling a path. - * - * Since: 2.0 - */ -void -cogl_path_fill (CoglPath *path); - /** * cogl_framebuffer_fill_path: * @framebuffer: A #CoglFramebuffer @@ -460,27 +441,12 @@ cogl_path_fill (CoglPath *path); * use while filling a path. * * Stability: unstable - * Deprecated: 1.16: Use cogl_path_fill() instead */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_path_fill) -void +COGL_EXPORT void cogl_framebuffer_fill_path (CoglFramebuffer *framebuffer, CoglPipeline *pipeline, CoglPath *path); -#define cogl_path_stroke cogl2_path_stroke -/** - * cogl_path_stroke: - * - * Strokes the constructed shape using the current drawing color and a - * width of 1 pixel (regardless of the current transformation - * matrix). - * - * Since: 2.0 - */ -void -cogl_path_stroke (CoglPath *path); - /** * cogl_framebuffer_stroke_path: * @framebuffer: A #CoglFramebuffer @@ -492,10 +458,8 @@ cogl_path_stroke (CoglPath *path); * regardless of the current transformation matrix. * * Stability: unstable - * Deprecated: 1.16: Use cogl_path_stroke() instead */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_path_stroke) -void +COGL_EXPORT void cogl_framebuffer_stroke_path (CoglFramebuffer *framebuffer, CoglPipeline *pipeline, CoglPath *path); @@ -513,29 +477,11 @@ cogl_framebuffer_stroke_path (CoglFramebuffer *framebuffer, * Since: 1.0 * Stability: unstable */ -void +COGL_EXPORT void cogl_framebuffer_push_path_clip (CoglFramebuffer *framebuffer, CoglPath *path); -#define cogl_clip_push_from_path cogl2_clip_push_from_path -/** - * cogl_clip_push_from_path: - * @path: The path to clip with. - * - * Sets a new clipping area using the silhouette of the specified, - * filled @path. The clipping area is intersected with the previous - * clipping area. To restore the previous clipping area, call - * call cogl_clip_pop(). - * - * Since: 1.8 - * Stability: Unstable - * Deprecated: 1.16: Use cogl_framebuffer_push_path_clip() instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_framebuffer_push_path_clip) -void -cogl_clip_push_from_path (CoglPath *path); - -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_PATH_FUNCTIONS_H__ */ diff --git a/cogl/cogl-path/cogl-path-private.h b/cogl/cogl-path/cogl-path-private.h index 078e58ffc..25a628b70 100644 --- a/cogl/cogl-path/cogl-path-private.h +++ b/cogl/cogl-path/cogl-path-private.h @@ -105,13 +105,13 @@ struct _CoglPathData case and divert to the journal or a rectangle clip. If it is TRUE then the entire path can be described by calling _cogl_path_get_bounds */ - CoglBool is_rectangle; + gboolean is_rectangle; }; void _cogl_add_path_to_stencil_buffer (CoglPath *path, - CoglBool merge, - CoglBool need_clear); + gboolean merge, + gboolean need_clear); void _cogl_path_get_bounds (CoglPath *path, @@ -120,7 +120,7 @@ _cogl_path_get_bounds (CoglPath *path, float *max_x, float *max_y); -CoglBool +gboolean _cogl_path_is_rectangle (CoglPath *path); #endif /* __COGL_PATH_PRIVATE_H */ diff --git a/cogl/cogl-path/cogl-path-types.h b/cogl/cogl-path/cogl-path-types.h index 53c06ee67..ee8583ad2 100644 --- a/cogl/cogl-path/cogl-path-types.h +++ b/cogl/cogl-path/cogl-path-types.h @@ -37,7 +37,7 @@ #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS typedef struct _CoglPath CoglPath; @@ -75,11 +75,12 @@ typedef struct _CoglPath CoglPath; * * Since: 1.4 */ -typedef enum { +typedef enum +{ COGL_PATH_FILL_RULE_NON_ZERO, COGL_PATH_FILL_RULE_EVEN_ODD } CoglPathFillRule; -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_PATH_TYPES_H__ */ diff --git a/cogl/cogl-path/cogl-path.c b/cogl/cogl-path/cogl-path.c index 3df528dcb..18a9eace9 100644 --- a/cogl/cogl-path/cogl-path.c +++ b/cogl/cogl-path/cogl-path.c @@ -95,7 +95,7 @@ _cogl_path_data_clear_vbos (CoglPathData *data) for (i = 0; i < data->stroke_n_attributes; i++) cogl_object_unref (data->stroke_attributes[i]); - free (data->stroke_attributes); + g_free (data->stroke_attributes); data->stroke_attribute_buffer = NULL; } @@ -149,7 +149,7 @@ void cogl2_path_set_fill_rule (CoglPath *path, CoglPathFillRule fill_rule) { - _COGL_RETURN_IF_FAIL (cogl_is_path (path)); + g_return_if_fail (cogl_is_path (path)); if (path->data->fill_rule != fill_rule) { @@ -162,14 +162,14 @@ cogl2_path_set_fill_rule (CoglPath *path, CoglPathFillRule cogl2_path_get_fill_rule (CoglPath *path) { - _COGL_RETURN_VAL_IF_FAIL (cogl_is_path (path), COGL_PATH_FILL_RULE_NON_ZERO); + g_return_val_if_fail (cogl_is_path (path), COGL_PATH_FILL_RULE_NON_ZERO); return path->data->fill_rule; } static void _cogl_path_add_node (CoglPath *path, - CoglBool new_sub_path, + gboolean new_sub_path, float x, float y) { @@ -225,9 +225,9 @@ _cogl_path_stroke_nodes (CoglPath *path, int path_num = 0; CoglPathNode *node; - _COGL_RETURN_IF_FAIL (cogl_is_path (path)); - _COGL_RETURN_IF_FAIL (cogl_is_framebuffer (framebuffer)); - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); + g_return_if_fail (cogl_is_path (path)); + g_return_if_fail (cogl_is_framebuffer (framebuffer)); + g_return_if_fail (cogl_is_pipeline (pipeline)); data = path->data; @@ -299,7 +299,7 @@ _cogl_path_fill_nodes_with_clipped_rectangle (CoglPath *path, /* We need at least three stencil bits to combine clips */ if (_cogl_framebuffer_get_stencil_bits (framebuffer) >= 3) { - static CoglBool seen_warning = FALSE; + static gboolean seen_warning = FALSE; if (!seen_warning) { @@ -320,10 +320,10 @@ _cogl_path_fill_nodes_with_clipped_rectangle (CoglPath *path, cogl_framebuffer_pop_clip (framebuffer); } -static CoglBool +static gboolean validate_layer_cb (CoglPipelineLayer *layer, void *user_data) { - CoglBool *needs_fallback = user_data; + gboolean *needs_fallback = user_data; CoglTexture *texture = _cogl_pipeline_layer_get_texture (layer); /* If any of the layers of the current pipeline contain sliced @@ -365,7 +365,7 @@ _cogl_path_fill_nodes (CoglPath *path, } else { - CoglBool needs_fallback = FALSE; + gboolean needs_fallback = FALSE; CoglPrimitive *primitive; _cogl_pipeline_foreach_layer_internal (pipeline, @@ -385,38 +385,6 @@ _cogl_path_fill_nodes (CoglPath *path, } } -/* TODO: Update to the protoype used in the Cogl master branch. - * This is experimental API but not in sync with the cogl_path_fill() - * api in Cogl master which takes explicit framebuffer and pipeline - * arguments */ -void -cogl2_path_fill (CoglPath *path) -{ - _COGL_RETURN_IF_FAIL (cogl_is_path (path)); - - _cogl_path_fill_nodes (path, - cogl_get_draw_framebuffer (), - cogl_get_source (), - 0 /* flags */); -} - -/* TODO: Update to the protoype used in the Cogl master branch. - * This is experimental API but not in sync with the cogl_path_fill() - * api in Cogl master which takes explicit framebuffer and pipeline - * arguments */ -void -cogl2_path_stroke (CoglPath *path) -{ - _COGL_RETURN_IF_FAIL (cogl_is_path (path)); - - if (path->data->path_nodes->len == 0) - return; - - _cogl_path_stroke_nodes (path, - cogl_get_draw_framebuffer (), - cogl_get_source ()); -} - void cogl2_path_move_to (CoglPath *path, float x, @@ -424,7 +392,7 @@ cogl2_path_move_to (CoglPath *path, { CoglPathData *data; - _COGL_RETURN_IF_FAIL (cogl_is_path (path)); + g_return_if_fail (cogl_is_path (path)); _cogl_path_add_node (path, TRUE, x, y); @@ -443,7 +411,7 @@ cogl2_path_rel_move_to (CoglPath *path, { CoglPathData *data; - _COGL_RETURN_IF_FAIL (cogl_is_path (path)); + g_return_if_fail (cogl_is_path (path)); data = path->data; @@ -459,7 +427,7 @@ cogl2_path_line_to (CoglPath *path, { CoglPathData *data; - _COGL_RETURN_IF_FAIL (cogl_is_path (path)); + g_return_if_fail (cogl_is_path (path)); _cogl_path_add_node (path, FALSE, x, y); @@ -476,7 +444,7 @@ cogl2_path_rel_line_to (CoglPath *path, { CoglPathData *data; - _COGL_RETURN_IF_FAIL (cogl_is_path (path)); + g_return_if_fail (cogl_is_path (path)); data = path->data; @@ -488,7 +456,7 @@ cogl2_path_rel_line_to (CoglPath *path, void cogl2_path_close (CoglPath *path) { - _COGL_RETURN_IF_FAIL (cogl_is_path (path)); + g_return_if_fail (cogl_is_path (path)); _cogl_path_add_node (path, FALSE, path->data->path_start.x, path->data->path_start.y); @@ -514,7 +482,7 @@ cogl2_path_polyline (CoglPath *path, { int c = 0; - _COGL_RETURN_IF_FAIL (cogl_is_path (path)); + g_return_if_fail (cogl_is_path (path)); cogl2_path_move_to (path, coords[0], coords[1]); @@ -538,7 +506,7 @@ cogl2_path_rectangle (CoglPath *path, float x_2, float y_2) { - CoglBool is_rectangle; + gboolean is_rectangle; /* If the path was previously empty and the rectangle isn't mirrored then we'll record that this is a simple rectangle path so that we @@ -556,7 +524,7 @@ cogl2_path_rectangle (CoglPath *path, path->data->is_rectangle = is_rectangle; } -CoglBool +gboolean _cogl_path_is_rectangle (CoglPath *path) { return path->data->is_rectangle; @@ -639,7 +607,7 @@ cogl2_path_arc (CoglPath *path, { float angle_step = 10; - _COGL_RETURN_IF_FAIL (cogl_is_path (path)); + g_return_if_fail (cogl_is_path (path)); /* it is documented that a move to is needed to create a freestanding * arc @@ -683,7 +651,7 @@ cogl2_path_ellipse (CoglPath *path, { float angle_step = 10; - _COGL_RETURN_IF_FAIL (cogl_is_path (path)); + g_return_if_fail (cogl_is_path (path)); /* FIXME: if shows to be slow might be optimized * by mirroring just a quarter of it */ @@ -709,7 +677,7 @@ cogl2_path_round_rectangle (CoglPath *path, float inner_width = x_2 - x_1 - radius * 2; float inner_height = y_2 - y_1 - radius * 2; - _COGL_RETURN_IF_FAIL (cogl_is_path (path)); + g_return_if_fail (cogl_is_path (path)); cogl2_path_move_to (path, x_1, y_1 + radius); _cogl_path_rel_arc (path, @@ -860,7 +828,7 @@ cogl2_path_curve_to (CoglPath *path, { CoglBezCubic cubic; - _COGL_RETURN_IF_FAIL (cogl_is_path (path)); + g_return_if_fail (cogl_is_path (path)); /* Prepare cubic curve */ cubic.p1 = path->data->path_pen; @@ -890,7 +858,7 @@ cogl2_path_rel_curve_to (CoglPath *path, { CoglPathData *data; - _COGL_RETURN_IF_FAIL (cogl_is_path (path)); + g_return_if_fail (cogl_is_path (path)); data = path->data; @@ -932,7 +900,7 @@ cogl_path_copy (CoglPath *old_path) { CoglPath *new_path; - _COGL_RETURN_VAL_IF_FAIL (cogl_is_path (old_path), NULL); + g_return_val_if_fail (cogl_is_path (old_path), NULL); new_path = g_slice_new (CoglPath); new_path->data = old_path->data; @@ -1053,7 +1021,7 @@ cogl_rel_curve2_to (CoglPath *path, { CoglPathData *data; - _COGL_RETURN_IF_FAIL (cogl_is_path (path)); + g_return_if_fail (cogl_is_path (path)); data = path->data; @@ -1358,13 +1326,13 @@ _cogl_path_build_fill_attribute_buffer (CoglPath *path) gluTessNormal (tess.glu_tess, 0.0, 0.0, 1.0); gluTessCallback (tess.glu_tess, GLU_TESS_BEGIN_DATA, - _cogl_path_tesselator_begin); + (GCallback) _cogl_path_tesselator_begin); gluTessCallback (tess.glu_tess, GLU_TESS_VERTEX_DATA, - _cogl_path_tesselator_vertex); + (GCallback) _cogl_path_tesselator_vertex); gluTessCallback (tess.glu_tess, GLU_TESS_END_DATA, - _cogl_path_tesselator_end); + (GCallback) _cogl_path_tesselator_end); gluTessCallback (tess.glu_tess, GLU_TESS_COMBINE_DATA, - _cogl_path_tesselator_combine); + (GCallback) _cogl_path_tesselator_combine); gluTessBeginPolygon (tess.glu_tess, &tess); @@ -1504,13 +1472,6 @@ cogl_framebuffer_push_path_clip (CoglFramebuffer *framebuffer, COGL_FRAMEBUFFER_STATE_CLIP; } -/* XXX: deprecated */ -void -cogl_clip_push_from_path (CoglPath *path) -{ - cogl_framebuffer_push_path_clip (cogl_get_draw_framebuffer (), path); -} - static void _cogl_path_build_stroke_attribute_buffer (CoglPath *path) { @@ -1575,28 +1536,26 @@ _cogl_path_build_stroke_attribute_buffer (CoglPath *path) data->stroke_n_attributes = n_attributes; } -/* XXX: deprecated */ void cogl_framebuffer_fill_path (CoglFramebuffer *framebuffer, CoglPipeline *pipeline, CoglPath *path) { - _COGL_RETURN_IF_FAIL (cogl_is_framebuffer (framebuffer)); - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); - _COGL_RETURN_IF_FAIL (cogl_is_path (path)); + g_return_if_fail (cogl_is_framebuffer (framebuffer)); + g_return_if_fail (cogl_is_pipeline (pipeline)); + g_return_if_fail (cogl_is_path (path)); _cogl_path_fill_nodes (path, framebuffer, pipeline, 0 /* flags */); } -/* XXX: deprecated */ void cogl_framebuffer_stroke_path (CoglFramebuffer *framebuffer, CoglPipeline *pipeline, CoglPath *path) { - _COGL_RETURN_IF_FAIL (cogl_is_framebuffer (framebuffer)); - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); - _COGL_RETURN_IF_FAIL (cogl_is_path (path)); + g_return_if_fail (cogl_is_framebuffer (framebuffer)); + g_return_if_fail (cogl_is_pipeline (pipeline)); + g_return_if_fail (cogl_is_path (path)); _cogl_path_stroke_nodes (path, framebuffer, pipeline); } diff --git a/cogl/cogl-path/meson.build b/cogl/cogl-path/meson.build new file mode 100644 index 000000000..c75f2259b --- /dev/null +++ b/cogl/cogl-path/meson.build @@ -0,0 +1,87 @@ +cogl_path_includesubdir = join_paths(cogl_includesubdir, 'cogl-path') +cogl_path_includedir = join_paths(cogl_includedir, 'cogl-path') + +cogl_path_public_headers = [ + 'cogl-path.h', + 'cogl-path-functions.h', + 'cogl-path-types.h', +] + +cogl_path_sources = [ + 'cogl-path.c', + 'cogl-path-private.h', + 'tesselator/dict-list.h', + 'tesselator/dict.c', + 'tesselator/dict.h', + 'tesselator/geom.c', + 'tesselator/geom.h', + 'tesselator/gluos.h', + 'tesselator/memalloc.h', + 'tesselator/mesh.c', + 'tesselator/mesh.h', + 'tesselator/normal.c', + 'tesselator/normal.h', + 'tesselator/priorityq-heap.h', + 'tesselator/priorityq-sort.h', + 'tesselator/priorityq.c', + 'tesselator/priorityq.h', + 'tesselator/render.c', + 'tesselator/render.h', + 'tesselator/sweep.c', + 'tesselator/sweep.h', + 'tesselator/tess.c', + 'tesselator/tess.h', + 'tesselator/tesselator.h', + 'tesselator/tessmono.c', + 'tesselator/tessmono.h', +] + +cogl_path_includepath = include_directories('.') + +libmutter_cogl_path_enum_types = gnome.mkenums('cogl-path-enum-types', + sources: 'cogl-path-types.h', + c_template: 'cogl-path-enum-types.c.in', + h_template: 'cogl-path-enum-types.h.in', + install_dir: cogl_path_includedir, + install_header: true, +) +libmutter_cogl_path_enum_types_h = libmutter_cogl_path_enum_types[1] + +cogl_path_sources += libmutter_cogl_path_enum_types + +cogl_path_c_args = [ + cogl_c_args, +] + +libmutter_cogl_path = shared_library('muffin-cogl-path-' + libmutter_api_version, + sources: [cogl_path_sources, cogl_path_public_headers], + version: '0.0.0', + soversion: 0, + c_args: cogl_path_c_args, + include_directories: [cogl_includepath, cogl_path_includepath], + gnu_symbol_visibility: 'hidden', + dependencies: libmutter_cogl_dep, + install_rpath: pkglibdir, + install_dir: pkglibdir, + install: true, +) +libmutter_cogl_path_dep = declare_dependency( + sources: [libmutter_cogl_path_enum_types_h], + link_with: libmutter_cogl_path +) + +install_headers(cogl_path_public_headers, + subdir: cogl_path_includesubdir) + +pkg.generate(libmutter_cogl_path, + name: 'CoglPath', + filebase: 'muffin-cogl-path-' + libmutter_api_version, + description: 'A 2D path drawing library for Cogl in mutter', + subdirs: join_paths(pkgname, 'cogl'), + requires: [cogl_pkg_deps, libmutter_cogl_name], + version: meson.project_version(), + variables: [ + 'apiversion=' + libmutter_api_version, + ], + install_dir: pcdir, +) diff --git a/cogl/cogl-path/muffin-cogl-path.pc.in b/cogl/cogl-path/muffin-cogl-path.pc.in deleted file mode 100644 index 0b061e2dc..000000000 --- a/cogl/cogl-path/muffin-cogl-path.pc.in +++ /dev/null @@ -1,13 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@/muffin -includedir=@includedir@/muffin -apiversion=@MUFFIN_PLUGIN_API_VERSION@ -requires=@COGL_PKG_REQUIRES@ muffin-cogl-@MUFFIN_PLUGIN_API_VERSION@ - -Name: Cogl -Description: A 2D path drawing library for Cogl -Version: @MUFFIN_VERSION@ -Libs: -L${libdir} -lmuffin-cogl-path-@MUFFIN_PLUGIN_API_VERSION@ -Cflags: -I${includedir}/cogl -Requires: ${requires} diff --git a/cogl/cogl-path/mutter-cogl-path.pc.in b/cogl/cogl-path/mutter-cogl-path.pc.in new file mode 100644 index 000000000..5618bba9a --- /dev/null +++ b/cogl/cogl-path/mutter-cogl-path.pc.in @@ -0,0 +1,13 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +apiversion=@LIBMUTTER_API_VERSION@ +libdir=@libdir@/mutter-${apiversion} +includedir=@includedir@/mutter-${apiversion} +requires=@COGL_PKG_REQUIRES@ mutter-cogl-${apiversion} + +Name: Cogl +Description: A 2D path drawing library for Cogl +Version: @MUTTER_VERSION@ +Libs: -L${libdir} -lmutter-cogl-path-${apiversion} +Cflags: -I${includedir}/cogl +Requires: ${requires} diff --git a/cogl/cogl-path/tesselator/GL/glu.h b/cogl/cogl-path/tesselator/GL/glu.h deleted file mode 100644 index 18c4024b7..000000000 --- a/cogl/cogl-path/tesselator/GL/glu.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -/* This is just a wrapper to use our simplified version of glu.h so - that the tesselator code can still #include */ - -#include "../tesselator.h" - -/* These aren't defined on GLES and we don't really want the - tesselator code to use them but we're also trying to avoid - modifying the C files so we just force them to be empty here */ - -#undef GLAPI -#define GLAPI - -#undef GLAPIENTRY -#define GLAPIENTRY - -/* GLES doesn't define a GLdouble type so lets just force it to a - regular double */ -#define GLdouble double diff --git a/cogl/cogl-path/tesselator/memalloc.h b/cogl/cogl-path/tesselator/memalloc.h index 623582828..a094b6cdc 100644 --- a/cogl/cogl-path/tesselator/memalloc.h +++ b/cogl/cogl-path/tesselator/memalloc.h @@ -37,8 +37,8 @@ #include #define memRealloc g_realloc -#define memAlloc malloc -#define memFree free +#define memAlloc g_malloc +#define memFree g_free #define memInit(x) 1 /* tess.c defines TRUE and FALSE itself unconditionally so we need to diff --git a/cogl/cogl-path/tesselator/mesh.c b/cogl/cogl-path/tesselator/mesh.c index 36cb3a7be..39aa61587 100644 --- a/cogl/cogl-path/tesselator/mesh.c +++ b/cogl/cogl-path/tesselator/mesh.c @@ -45,12 +45,12 @@ #define FALSE 0 #endif -static GLUvertex *allocVertex() +static GLUvertex *allocVertex(void) { return (GLUvertex *)memAlloc( sizeof( GLUvertex )); } -static GLUface *allocFace() +static GLUface *allocFace(void) { return (GLUface *)memAlloc( sizeof( GLUface )); } diff --git a/cogl/cogl-path/tesselator/mesh.h b/cogl/cogl-path/tesselator/mesh.h index 690c5f2f6..ede4798a3 100644 --- a/cogl/cogl-path/tesselator/mesh.h +++ b/cogl/cogl-path/tesselator/mesh.h @@ -35,7 +35,7 @@ #ifndef __mesh_h_ #define __mesh_h_ -#include +#include typedef struct GLUmesh GLUmesh; diff --git a/cogl/cogl-path/tesselator/normal.h b/cogl/cogl-path/tesselator/normal.h index c376ca445..b699e087a 100644 --- a/cogl/cogl-path/tesselator/normal.h +++ b/cogl/cogl-path/tesselator/normal.h @@ -36,6 +36,7 @@ #define __normal_h_ #include "tess.h" +#include "tesselator.h" /* __gl_projectPolygon( tess ) determines the polygon normal * and project vertices onto the plane of the polygon. diff --git a/cogl/cogl-path/tesselator/render.h b/cogl/cogl-path/tesselator/render.h index a298c9a94..e0621e84e 100644 --- a/cogl/cogl-path/tesselator/render.h +++ b/cogl/cogl-path/tesselator/render.h @@ -36,6 +36,7 @@ #define __render_h_ #include "mesh.h" +#include "tesselator.h" /* __gl_renderMesh( tess, mesh ) takes a mesh and breaks it into triangle * fans, strips, and separate triangles. A substantial effort is made diff --git a/cogl/cogl-path/tesselator/sweep.h b/cogl/cogl-path/tesselator/sweep.h index feb68b0ff..8b3857796 100644 --- a/cogl/cogl-path/tesselator/sweep.h +++ b/cogl/cogl-path/tesselator/sweep.h @@ -36,6 +36,7 @@ #define __sweep_h_ #include "mesh.h" +#include "tesselator.h" /* __gl_computeInterior( tess ) computes the planar arrangement specified * by the given contours, and further subdivides this arrangement diff --git a/cogl/cogl-path/tesselator/tess.h b/cogl/cogl-path/tesselator/tess.h index 162496088..061dd760c 100644 --- a/cogl/cogl-path/tesselator/tess.h +++ b/cogl/cogl-path/tesselator/tess.h @@ -35,7 +35,6 @@ #ifndef __tess_h_ #define __tess_h_ -#include #include #include "mesh.h" #include "dict.h" diff --git a/cogl/cogl-path/tesselator/tesselator.h b/cogl/cogl-path/tesselator/tesselator.h index 5b651be1d..070873987 100644 --- a/cogl/cogl-path/tesselator/tesselator.h +++ b/cogl/cogl-path/tesselator/tesselator.h @@ -45,7 +45,7 @@ void gluBeginPolygon (GLUtesselator* tess); void gluDeleteTess (GLUtesselator* tess); void gluEndPolygon (GLUtesselator* tess); -typedef void (_GLUfuncptr)(); +typedef void (_GLUfuncptr)(void); void gluGetTessProperty (GLUtesselator* tess, GLenum which, double* data); diff --git a/cogl/cogl/Makefile.am b/cogl/cogl/Makefile.am deleted file mode 100644 index c45f2274f..000000000 --- a/cogl/cogl/Makefile.am +++ /dev/null @@ -1,510 +0,0 @@ -# preamble - -NULL = - -SUBDIRS = - -BUILT_SOURCES = - -EXTRA_DIST = -CLEANFILES = -DISTCLEANFILES = - -AM_CPPFLAGS = \ - -I$(top_srcdir) \ - -I$(top_builddir) \ - -I$(srcdir)/deprecated \ - -I$(srcdir)/winsys \ - -I$(srcdir)/driver/gl \ - -I$(srcdir)/driver/gl/gl \ - -I$(srcdir)/driver/gl/gles \ - $(NULL) - -AM_CPPFLAGS += \ - -DG_LOG_DOMAIN=\"Cogl\" \ - -DCOGL_COMPILATION \ - -DCOGL_GL_LIBNAME=\"$(COGL_GL_LIBNAME)\" \ - -DCOGL_GLES1_LIBNAME=\"$(COGL_GLES1_LIBNAME)\" \ - -DCOGL_GLES2_LIBNAME=\"$(COGL_GLES2_LIBNAME)\" \ - -DCOGL_LOCALEDIR=\""$(localedir)"\" \ - $(NULL) - -if HAVE_COGL_DEFAULT_DRIVER -AM_CPPFLAGS += \ - -DCOGL_DEFAULT_DRIVER=\"$(COGL_DEFAULT_DRIVER)\" -endif - - -AM_CFLAGS = $(COGL_DEP_CFLAGS) $(COGL_EXTRA_CFLAGS) $(MAINTAINER_CFLAGS) - -BUILT_SOURCES += cogl-defines.h cogl-egl-defines.h cogl-gl-header.h -DISTCLEANFILES += cogl-defines.h cogl-egl-defines.h cogl-gl-header.h -EXTRA_DIST += cogl-defines.h.in cogl-egl-defines.h.in cogl-gl-header.h.in - -pc_files = muffin-cogl-$(MUFFIN_PLUGIN_API_VERSION).pc - -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = $(pc_files) - -DISTCLEANFILES += $(pc_files) - -cogl_deprecated_h = \ - deprecated/cogl-material-compat.h \ - deprecated/cogl-vertex-buffer.h \ - deprecated/cogl-shader.h \ - deprecated/cogl-clutter.h \ - deprecated/cogl-type-casts.h \ - deprecated/cogl-auto-texture.h \ - $(NULL) - -cogl_deprecated_nonintrospected_h = \ - deprecated/cogl-framebuffer-deprecated.h \ - $(NULL) - -# public 1.x api headers -cogl_1_public_h = \ - $(cogl_deprecated_h) \ - cogl1-context.h \ - cogl-bitmap.h \ - cogl-color.h \ - cogl-matrix.h \ - cogl-offscreen.h \ - cogl-primitives.h \ - cogl-texture.h \ - cogl-types.h \ - cogl.h \ - $(NULL) - -cogl_nonintrospected_h = \ - cogl-object.h \ - cogl-renderer.h \ - cogl-swap-chain.h \ - cogl-onscreen-template.h \ - cogl-display.h \ - cogl-context.h \ - cogl-pipeline.h \ - cogl-pipeline-state.h \ - cogl-pipeline-layer-state.h \ - cogl-snippet.h \ - cogl-gles2.h \ - cogl-gles2-types.h \ - cogl-index-buffer.h \ - cogl-attribute-buffer.h \ - cogl-indices.h \ - cogl-attribute.h \ - cogl-primitive.h \ - cogl-framebuffer.h \ - cogl-onscreen.h \ - cogl-frame-info.h \ - cogl-vector.h \ - cogl-euler.h \ - cogl-output.h \ - cogl-quaternion.h \ - cogl-matrix-stack.h \ - cogl-poll.h \ - cogl-texture-3d.h \ - cogl-texture-2d.h \ - cogl-texture-2d-gl.h \ - cogl-texture-rectangle.h \ - cogl-texture-2d-sliced.h \ - cogl-sub-texture.h \ - cogl-atlas-texture.h \ - cogl-meta-texture.h \ - cogl-primitive-texture.h \ - cogl-depth-state.h \ - cogl-buffer.h \ - cogl-pixel-buffer.h \ - cogl-macros.h \ - cogl-fence.h \ - cogl-version.h \ - cogl-error.h \ - cogl-bitmap.h \ - cogl-color.h \ - cogl-matrix.h \ - cogl-texture.h \ - cogl-types.h \ - cogl-gtype-private.h \ - cogl-muffin.h \ - $(NULL) - -cogl_nodist_h = \ - $(NULL) - -# nop driver -cogl_driver_sources = \ - driver/nop/cogl-driver-nop.c \ - driver/nop/cogl-framebuffer-nop-private.h \ - driver/nop/cogl-framebuffer-nop.c \ - driver/nop/cogl-attribute-nop-private.h \ - driver/nop/cogl-attribute-nop.c \ - driver/nop/cogl-clip-stack-nop-private.h \ - driver/nop/cogl-clip-stack-nop.c \ - driver/nop/cogl-texture-2d-nop-private.h \ - driver/nop/cogl-texture-2d-nop.c \ - $(NULL) - -# gl driver sources -cogl_gl_prototypes_h = \ - gl-prototypes/cogl-gles2-functions.h \ - gl-prototypes/cogl-core-functions.h \ - gl-prototypes/cogl-in-gles-core-functions.h \ - gl-prototypes/cogl-in-gles2-core-functions.h \ - gl-prototypes/cogl-glsl-functions.h \ - $(NULL) - -cogl_driver_sources += \ - driver/gl/cogl-util-gl-private.h \ - driver/gl/cogl-util-gl.c \ - driver/gl/cogl-framebuffer-gl-private.h \ - driver/gl/cogl-framebuffer-gl.c \ - driver/gl/cogl-texture-gl-private.h \ - driver/gl/cogl-texture-gl.c \ - driver/gl/cogl-texture-2d-gl-private.h \ - driver/gl/cogl-texture-2d-gl.c \ - driver/gl/cogl-attribute-gl-private.h \ - driver/gl/cogl-attribute-gl.c \ - driver/gl/cogl-clip-stack-gl-private.h \ - driver/gl/cogl-clip-stack-gl.c \ - driver/gl/cogl-buffer-gl-private.h \ - driver/gl/cogl-buffer-gl.c \ - driver/gl/cogl-pipeline-opengl.c \ - driver/gl/cogl-pipeline-opengl-private.h \ - driver/gl/cogl-pipeline-fragend-glsl.c \ - driver/gl/cogl-pipeline-fragend-glsl-private.h \ - driver/gl/gl/cogl-pipeline-fragend-arbfp.c \ - driver/gl/gl/cogl-pipeline-fragend-arbfp-private.h \ - driver/gl/gl/cogl-pipeline-progend-fixed-arbfp.c \ - driver/gl/gl/cogl-pipeline-progend-fixed-arbfp-private.h \ - driver/gl/cogl-pipeline-fragend-fixed.c \ - driver/gl/cogl-pipeline-fragend-fixed-private.h \ - driver/gl/cogl-pipeline-vertend-glsl.c \ - driver/gl/cogl-pipeline-vertend-glsl-private.h \ - driver/gl/cogl-pipeline-vertend-fixed.c \ - driver/gl/cogl-pipeline-vertend-fixed-private.h \ - driver/gl/cogl-pipeline-progend-fixed.c \ - driver/gl/cogl-pipeline-progend-fixed-private.h \ - driver/gl/cogl-pipeline-progend-glsl.c \ - driver/gl/cogl-pipeline-progend-glsl-private.h \ - $(NULL) - -if COGL_DRIVER_GL_SUPPORTED -cogl_driver_sources += \ - driver/gl/gl/cogl-driver-gl.c \ - driver/gl/gl/cogl-texture-driver-gl.c \ - $(NULL) -endif - -if COGL_DRIVER_GLES_SUPPORTED -cogl_driver_sources += \ - driver/gl/gles/cogl-driver-gles.c \ - driver/gl/gles/cogl-texture-driver-gles.c \ - $(NULL) -endif - -# winsys sources, common to all backends -cogl_winsys_common_sources = \ - winsys/cogl-winsys-private.h \ - winsys/cogl-winsys.c \ - $(NULL) - -# sources -cogl_sources_c = \ - $(cogl_driver_sources) \ - $(cogl_winsys_common_sources) \ - cogl-private.h \ - cogl-i18n-private.h \ - cogl-debug.h \ - cogl-debug-options.h \ - cogl-gpu-info.c \ - cogl-gpu-info-private.h \ - cogl-context-private.h \ - cogl-context.c \ - cogl-renderer-private.h \ - cogl-renderer.h \ - cogl-renderer.c \ - cogl-swap-chain-private.h \ - cogl-swap-chain.h \ - cogl-swap-chain.c \ - cogl-onscreen-template-private.h \ - cogl-onscreen-template.h \ - cogl-onscreen-template.c \ - cogl-display-private.h \ - cogl-display.h \ - cogl-display.c \ - cogl-driver.h \ - cogl.c \ - cogl-object-private.h \ - cogl-object.h \ - cogl-object.c \ - cogl-util.h \ - cogl-util.c \ - cogl-bitmap-private.h \ - cogl-bitmap.c \ - cogl-bitmap-conversion.c \ - cogl-bitmap-packing.h \ - cogl-primitives-private.h \ - cogl-primitives.h \ - cogl-primitives.c \ - cogl-bitmap-pixbuf.c \ - cogl-clip-stack.h \ - cogl-clip-stack.c \ - cogl-feature-private.h \ - cogl-feature-private.c \ - cogl-color-private.h \ - cogl-color.c \ - cogl-buffer-private.h \ - cogl-buffer.c \ - cogl-pixel-buffer-private.h \ - cogl-pixel-buffer.c \ - cogl-index-buffer-private.h \ - cogl-index-buffer.c \ - cogl-attribute-buffer-private.h \ - cogl-attribute-buffer.c \ - cogl-indices-private.h \ - cogl-indices.c \ - cogl-attribute-private.h \ - cogl-attribute.c \ - cogl-primitive-private.h \ - cogl-primitive.c \ - cogl-matrix.c \ - cogl-vector.c \ - cogl-euler.c \ - cogl-quaternion-private.h \ - cogl-quaternion.c \ - cogl-matrix-private.h \ - cogl-matrix-stack.c \ - cogl-matrix-stack-private.h \ - cogl-depth-state.c \ - cogl-depth-state-private.h \ - cogl-node.c \ - cogl-node-private.h \ - cogl-pipeline.c \ - cogl-pipeline-private.h \ - cogl-pipeline-layer.c \ - cogl-pipeline-layer-private.h \ - cogl-pipeline-state.c \ - cogl-pipeline-layer-state-private.h \ - cogl-pipeline-layer-state.c \ - cogl-pipeline-state-private.h \ - cogl-pipeline-debug.c \ - cogl-glsl-shader.c \ - cogl-glsl-shader-private.h \ - cogl-glsl-shader-boilerplate.h \ - cogl-pipeline-snippet-private.h \ - cogl-pipeline-snippet.c \ - cogl-pipeline-cache.h \ - cogl-pipeline-cache.c \ - cogl-pipeline-hash-table.h \ - cogl-pipeline-hash-table.c \ - cogl-sampler-cache.c \ - cogl-sampler-cache-private.h \ - cogl-blend-string.c \ - cogl-blend-string.h \ - cogl-debug.c \ - cogl-sub-texture-private.h \ - cogl-texture-private.h \ - cogl-texture-2d-private.h \ - cogl-texture-2d-sliced-private.h \ - cogl-texture-3d-private.h \ - cogl-texture-driver.h \ - cogl-sub-texture.c \ - cogl-texture.c \ - cogl-texture-2d.c \ - cogl-texture-2d-sliced.c \ - cogl-texture-3d.c \ - cogl-texture-rectangle-private.h \ - cogl-texture-rectangle.c \ - cogl-rectangle-map.h \ - cogl-rectangle-map.c \ - cogl-atlas.h \ - cogl-atlas.c \ - cogl-atlas-texture-private.h \ - cogl-atlas-texture.c \ - cogl-meta-texture.c \ - cogl-primitive-texture.c \ - cogl-blit.h \ - cogl-blit.c \ - cogl-spans.h \ - cogl-spans.c \ - cogl-journal-private.h \ - cogl-journal.c \ - cogl-frame-info-private.h \ - cogl-frame-info.c \ - cogl-framebuffer-private.h \ - cogl-framebuffer.c \ - cogl-onscreen-private.h \ - cogl-onscreen.c \ - cogl-output-private.h \ - cogl-output.c \ - cogl-profile.h \ - cogl-profile.c \ - cogl-flags.h \ - cogl-bitmask.h \ - cogl-bitmask.c \ - cogl-gtype.c \ - cogl-gtype-private.h \ - cogl-point-in-poly-private.h \ - cogl-point-in-poly.c \ - cogl-list.c \ - cogl-list.h \ - winsys/cogl-winsys-stub-private.h \ - winsys/cogl-winsys-stub.c \ - cogl-config-private.h \ - cogl-config.c \ - cogl-boxed-value.h \ - cogl-boxed-value.c \ - cogl-snippet-private.h \ - cogl-snippet.c \ - cogl-poll-private.h \ - cogl-poll.c \ - gl-prototypes/cogl-all-functions.h \ - gl-prototypes/cogl-gles1-functions.h \ - gl-prototypes/cogl-gles2-functions.h \ - gl-prototypes/cogl-core-functions.h \ - gl-prototypes/cogl-in-gles-core-functions.h \ - gl-prototypes/cogl-in-gles1-core-functions.h \ - gl-prototypes/cogl-in-gles2-core-functions.h \ - gl-prototypes/cogl-fixed-functions.h \ - gl-prototypes/cogl-glsl-functions.h \ - cogl-memory-stack-private.h \ - cogl-memory-stack.c \ - cogl-magazine-private.h \ - cogl-magazine.c \ - cogl-gles2-context-private.h \ - cogl-gles2-context.c \ - cogl-error-private.h \ - cogl-error.c \ - cogl-closure-list-private.h \ - cogl-closure-list.c \ - cogl-fence.c \ - cogl-fence-private.h \ - deprecated/cogl-vertex-buffer-private.h \ - deprecated/cogl-vertex-buffer.c \ - deprecated/cogl-material-compat.c \ - deprecated/cogl-program.c \ - deprecated/cogl-program-private.h \ - deprecated/cogl-auto-texture.c \ - deprecated/cogl-shader-private.h \ - deprecated/cogl-shader.c \ - deprecated/cogl-clutter.c \ - deprecated/cogl-framebuffer-deprecated.c \ - $(NULL) - -cogl_nonintrospected_h += cogl-glib-source.h -cogl_sources_c += cogl-glib-source.c - -if SUPPORT_XLIB -cogl_deprecated_nonintrospected_h += deprecated/cogl-clutter-xlib.h -cogl_1_public_h += cogl-xlib-renderer.h - -cogl_nonintrospected_h += \ - winsys/cogl-texture-pixmap-x11.h \ - cogl-xlib.h - -cogl_sources_c += \ - cogl-x11-renderer-private.h \ - cogl-xlib-renderer-private.h \ - cogl-xlib-renderer.c \ - cogl-xlib.c \ - cogl-xlib-private.h \ - winsys/cogl-texture-pixmap-x11.c \ - winsys/cogl-texture-pixmap-x11-private.h -endif -if SUPPORT_GLX -cogl_nonintrospected_h += cogl-glx.h -cogl_sources_c += \ - cogl-glx-renderer-private.h \ - cogl-glx-display-private.h \ - winsys/cogl-winsys-glx-feature-functions.h \ - winsys/cogl-winsys-glx-private.h \ - winsys/cogl-winsys-glx.c -endif -if SUPPORT_WAYLAND_EGL_SERVER -cogl_nonintrospected_h += cogl-wayland-server.h -endif -if SUPPORT_EGL_PLATFORM_XLIB -cogl_sources_c += \ - winsys/cogl-winsys-egl-x11.c \ - winsys/cogl-winsys-egl-x11-private.h -endif -if SUPPORT_EGL -cogl_nonintrospected_h += cogl-egl.h -cogl_nodist_h += cogl-egl-defines.h - -cogl_sources_c += \ - cogl-egl-private.h \ - winsys/cogl-winsys-egl.c \ - winsys/cogl-winsys-egl-feature-functions.h \ - winsys/cogl-winsys-egl-private.h -endif - -muffinlibdir = $(libdir)/muffin -muffinlib_LTLIBRARIES = libmuffin-cogl-@MUFFIN_PLUGIN_API_VERSION@.la - -libmuffin_cogl_@MUFFIN_PLUGIN_API_VERSION@_la_LIBADD = $(LIBM) $(COGL_DEP_LIBS) $(COGL_EXTRA_LDFLAGS) -if UNIT_TESTS -libmuffin_cogl_@MUFFIN_PLUGIN_API_VERSION@_la_LIBADD += $(top_builddir)/test-fixtures/libtest-fixtures.la -endif -# XXX: The aim is to eventually get rid of all private API exports -# for cogl-pango. -libmuffin_cogl_@MUFFIN_PLUGIN_API_VERSION@_la_LDFLAGS = \ - -no-undefined \ - -avoid-version \ - -export-dynamic \ - -rpath $(muffinlibdir) \ - -export-symbols-regex "^(cogl|_cogl_debug_flags|_cogl_atlas_new|_cogl_atlas_add_reorganize_callback|_cogl_atlas_reserve_space|_cogl_callback|_cogl_util_get_eye_planes_for_screen_poly|_cogl_atlas_texture_remove_reorganize_callback|_cogl_atlas_texture_add_reorganize_callback|_cogl_texture_get_format|_cogl_texture_foreach_sub_texture_in_region|_cogl_texture_set_region|_cogl_profile_trace_message|_cogl_context_get_default|_cogl_framebuffer_get_stencil_bits|_cogl_clip_stack_push_rectangle|_cogl_framebuffer_get_modelview_stack|_cogl_object_default_unref|_cogl_pipeline_foreach_layer_internal|_cogl_clip_stack_push_primitive|_cogl_buffer_unmap_for_fill_or_fallback|_cogl_framebuffer_draw_primitive|_cogl_debug_instances|_cogl_framebuffer_get_projection_stack|_cogl_pipeline_layer_get_texture|_cogl_buffer_map_for_fill_or_fallback|_cogl_texture_can_hardware_repeat|_cogl_pipeline_prune_to_n_layers|_cogl_primitive_draw|test_|unit_test_|_cogl_winsys_glx_get_vtable|_cogl_winsys_egl_xlib_get_vtable|_cogl_winsys_egl_get_vtable|_cogl_closure_disconnect|_cogl_onscreen_notify_complete|_cogl_onscreen_notify_frame_sync|_cogl_winsys_egl_renderer_connect_common|_cogl_winsys_error_quark|_cogl_set_error|_cogl_poll_renderer_add_fd|_cogl_poll_renderer_add_idle|_cogl_framebuffer_winsys_update_size|_cogl_winsys_egl_make_current|_cogl_winsys_egl_ensure_current|_cogl_pixel_format_get_bytes_per_pixel).*" - -libmuffin_cogl_@MUFFIN_PLUGIN_API_VERSION@_la_SOURCES = $(cogl_sources_c) -nodist_libmuffin_cogl_@MUFFIN_PLUGIN_API_VERSION@_la_SOURCES = $(BUILT_SOURCES) - -# Cogl installed headers -cogl_headers = \ - $(cogl_1_public_h) \ - cogl-deprecated.h \ - cogl-pango.h \ - $(NULL) - -cogl_base_includedir = $(includedir)/muffin -cogldeprecatedincludedir = $(cogl_base_includedir)/cogl/cogl/deprecated -cogldeprecatedinclude_HEADERS = $(cogl_deprecated_h) $(cogl_deprecated_nonintrospected_h) - -coglincludedir = $(cogl_base_includedir)/cogl/cogl -coglinclude_HEADERS = $(cogl_headers) $(cogl_nonintrospected_h) -nodist_coglinclude_HEADERS = $(cogl_nodist_h) cogl-defines.h - -cogl_proto_includedir = $(cogl_base_includedir)/cogl/cogl/gl-prototypes -cogl_proto_include_HEADERS = $(cogl_gl_prototypes_h) - -EXTRA_DIST += \ - cogl.symbols - --include $(INTROSPECTION_MAKEFILE) - -INTROSPECTION_GIRS = - -if HAVE_INTROSPECTION -Cogl-@MUFFIN_PLUGIN_API_VERSION@.gir: libmuffin-cogl-$(MUFFIN_PLUGIN_API_VERSION).la Makefile - -Cogl_@MUFFIN_PLUGIN_API_VERSION@_gir_NAMESPACE = Cogl -Cogl_@MUFFIN_PLUGIN_API_VERSION@_gir_VERSION = $(MUFFIN_PLUGIN_API_VERSION) -Cogl_@MUFFIN_PLUGIN_API_VERSION@_gir_LIBS = libmuffin-cogl-$(MUFFIN_PLUGIN_API_VERSION).la -if UNIT_TESTS -Cogl_@MUFFIN_PLUGIN_API_VERSION@_gir_LIBS += $(top_builddir)/test-fixtures/libtest-fixtures.la -endif -Cogl_@MUFFIN_PLUGIN_API_VERSION@_gir_FILES = $(cogl_1_public_h) - -Cogl_@MUFFIN_PLUGIN_API_VERSION@_gir_CFLAGS = $(AM_CPPFLAGS) $(COGL_DEP_CFLAGS) -UCOGL_COMPILATION -D__COGL_H_INSIDE__ -D__COGL_XLIB_H_INSIDE__ -D__COGL_EGL_H_INSIDE__ -D__COGL_GLX_H_INSIDE__ -DCOGL_GIR_SCANNING -Cogl_@MUFFIN_PLUGIN_API_VERSION@_gir_INCLUDES = GL-1.0 GObject-2.0 -Cogl_@MUFFIN_PLUGIN_API_VERSION@_gir_EXPORT_PACKAGES = muffin-cogl-@MUFFIN_PLUGIN_API_VERSION@ -Cogl_@MUFFIN_PLUGIN_API_VERSION@_gir_SCANNERFLAGS = --warn-all --c-include='cogl/cogl.h' - -INTROSPECTION_GIRS += Cogl-@MUFFIN_PLUGIN_API_VERSION@.gir - -girdir = $(muffinlibdir) -gir_DATA = $(INTROSPECTION_GIRS) - -typelibdir = $(muffinlibdir) -typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib) - -CLEANFILES += $(gir_DATA) $(typelib_DATA) -endif diff --git a/cogl/cogl/cogl-atlas-texture-private.h b/cogl/cogl/cogl-atlas-texture-private.h index ba83bf9eb..336bf1cfa 100644 --- a/cogl/cogl/cogl-atlas-texture-private.h +++ b/cogl/cogl/cogl-atlas-texture-private.h @@ -63,19 +63,19 @@ struct _CoglAtlasTexture CoglAtlasTexture * _cogl_atlas_texture_new_from_bitmap (CoglBitmap *bmp, - CoglBool can_convert_in_place); + gboolean can_convert_in_place); -void +COGL_EXPORT void _cogl_atlas_texture_add_reorganize_callback (CoglContext *ctx, GHookFunc callback, void *user_data); -void +COGL_EXPORT void _cogl_atlas_texture_remove_reorganize_callback (CoglContext *ctx, GHookFunc callback, void *user_data); -CoglBool +gboolean _cogl_is_atlas_texture (void *object); #endif /* _COGL_ATLAS_TEXTURE_PRIVATE_H_ */ diff --git a/cogl/cogl/cogl-atlas-texture.c b/cogl/cogl/cogl-atlas-texture.c index d0da4d863..04d888085 100644 --- a/cogl/cogl/cogl-atlas-texture.c +++ b/cogl/cogl/cogl-atlas-texture.c @@ -31,9 +31,7 @@ * Neil Roberts */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-debug.h" #include "cogl-util.h" @@ -46,13 +44,12 @@ #include "cogl-texture-driver.h" #include "cogl-rectangle-map.h" #include "cogl-journal-private.h" -#include "cogl-pipeline-opengl-private.h" #include "cogl-atlas.h" #include "cogl1-context.h" #include "cogl-sub-texture.h" -#include "cogl-error-private.h" -#include "cogl-texture-gl-private.h" #include "cogl-gtype-private.h" +#include "driver/gl/cogl-pipeline-opengl-private.h" +#include "driver/gl/cogl-texture-gl-private.h" #include @@ -184,7 +181,7 @@ _cogl_atlas_texture_post_reorganize_cb (void *user_data) cogl_object_unref (data.textures[i]); } - free (data.textures); + g_free (data.textures); } /* Notify any listeners that an atlas has changed */ @@ -255,16 +252,14 @@ _cogl_atlas_texture_foreach_sub_texture_in_region ( static void _cogl_atlas_texture_gl_flush_legacy_texobj_wrap_modes (CoglTexture *tex, GLenum wrap_mode_s, - GLenum wrap_mode_t, - GLenum wrap_mode_p) + GLenum wrap_mode_t) { CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); /* Forward on to the sub texture */ _cogl_texture_gl_flush_legacy_texobj_wrap_modes (atlas_tex->sub_texture, wrap_mode_s, - wrap_mode_t, - wrap_mode_p); + wrap_mode_t); } static void @@ -301,7 +296,7 @@ _cogl_atlas_texture_get_max_waste (CoglTexture *tex) return cogl_texture_get_max_waste (atlas_tex->sub_texture); } -static CoglBool +static gboolean _cogl_atlas_texture_is_sliced (CoglTexture *tex) { CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); @@ -310,7 +305,7 @@ _cogl_atlas_texture_is_sliced (CoglTexture *tex) return cogl_texture_is_sliced (atlas_tex->sub_texture); } -static CoglBool +static gboolean _cogl_atlas_texture_can_hardware_repeat (CoglTexture *tex) { CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); @@ -341,7 +336,7 @@ _cogl_atlas_texture_transform_quad_coords_to_gl (CoglTexture *tex, coords); } -static CoglBool +static gboolean _cogl_atlas_texture_get_gl_texture (CoglTexture *tex, GLuint *out_gl_handle, GLenum *out_gl_target) @@ -446,7 +441,7 @@ _cogl_atlas_texture_ensure_non_quad_rendering (CoglTexture *tex) _cogl_texture_ensure_non_quad_rendering (atlas_tex->sub_texture); } -static CoglBool +static gboolean _cogl_atlas_texture_set_region_with_border (CoglAtlasTexture *atlas_tex, int src_x, int src_y, @@ -455,7 +450,7 @@ _cogl_atlas_texture_set_region_with_border (CoglAtlasTexture *atlas_tex, int dst_width, int dst_height, CoglBitmap *bmp, - CoglError **error) + GError **error) { CoglAtlas *atlas = atlas_tex->atlas; @@ -525,8 +520,8 @@ static CoglBitmap * _cogl_atlas_texture_convert_bitmap_for_upload (CoglAtlasTexture *atlas_tex, CoglBitmap *bmp, CoglPixelFormat internal_format, - CoglBool can_convert_in_place, - CoglError **error) + gboolean can_convert_in_place, + GError **error) { CoglBitmap *upload_bmp; CoglBitmap *override_bmp; @@ -566,7 +561,7 @@ _cogl_atlas_texture_convert_bitmap_for_upload (CoglAtlasTexture *atlas_tex, return override_bmp; } -static CoglBool +static gboolean _cogl_atlas_texture_set_region (CoglTexture *tex, int src_x, int src_y, @@ -576,7 +571,7 @@ _cogl_atlas_texture_set_region (CoglTexture *tex, int dst_height, int level, CoglBitmap *bmp, - CoglError **error) + GError **error) { CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); @@ -587,7 +582,7 @@ _cogl_atlas_texture_set_region (CoglTexture *tex, pixels to the border */ if (atlas_tex->atlas) { - CoglBool ret; + gboolean ret; CoglBitmap *upload_bmp = _cogl_atlas_texture_convert_bitmap_for_upload (atlas_tex, bmp, @@ -641,7 +636,7 @@ _cogl_atlas_texture_get_gl_format (CoglTexture *tex) return _cogl_texture_gl_get_format (atlas_tex->sub_texture); } -static CoglBool +static gboolean _cogl_atlas_texture_can_use_format (CoglPixelFormat format) { /* We don't care about the ordering or the premult status and we can @@ -696,7 +691,7 @@ cogl_atlas_texture_new_with_size (CoglContext *ctx, /* We can't atlas zero-sized textures because it breaks the atlas * data structure */ - _COGL_RETURN_VAL_IF_FAIL (width > 0 && height > 0, NULL); + g_return_val_if_fail (width > 0 && height > 0, NULL); loader = _cogl_texture_create_loader (); loader->src_type = COGL_TEXTURE_SOURCE_TYPE_SIZED; @@ -708,12 +703,12 @@ cogl_atlas_texture_new_with_size (CoglContext *ctx, loader); } -static CoglBool +static gboolean allocate_space (CoglAtlasTexture *atlas_tex, int width, int height, CoglPixelFormat internal_format, - CoglError **error) + GError **error) { CoglTexture *tex = COGL_TEXTURE (atlas_tex); CoglContext *ctx = tex->context; @@ -725,22 +720,10 @@ allocate_space (CoglAtlasTexture *atlas_tex, { COGL_NOTE (ATLAS, "Texture can not be added because the " "format is unsupported"); - _cogl_set_error (error, - COGL_TEXTURE_ERROR, - COGL_TEXTURE_ERROR_FORMAT, - "Texture format unsuitable for atlasing"); - return FALSE; - } - - /* If we can't use FBOs then it will be too slow to migrate textures - and we shouldn't use the atlas */ - if (!cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN)) - { - _cogl_set_error (error, - COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_UNSUPPORTED, - "Atlasing disabled because migrations " - "would be too slow"); + g_set_error_literal (error, + COGL_TEXTURE_ERROR, + COGL_TEXTURE_ERROR_FORMAT, + "Texture format unsuitable for atlasing"); return FALSE; } @@ -779,10 +762,10 @@ allocate_space (CoglAtlasTexture *atlas_tex, /* Ok, this means we really can't add it to the atlas */ cogl_object_unref (atlas); - _cogl_set_error (error, - COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_NO_MEMORY, - "Not enough memory to atlas texture"); + g_set_error_literal (error, + COGL_SYSTEM_ERROR, + COGL_SYSTEM_ERROR_NO_MEMORY, + "Not enough memory to atlas texture"); return FALSE; } } @@ -794,10 +777,10 @@ allocate_space (CoglAtlasTexture *atlas_tex, return TRUE; } -static CoglBool +static gboolean allocate_with_size (CoglAtlasTexture *atlas_tex, CoglTextureLoader *loader, - CoglError **error) + GError **error) { CoglTexture *tex = COGL_TEXTURE (atlas_tex); CoglPixelFormat internal_format = @@ -819,21 +802,21 @@ allocate_with_size (CoglAtlasTexture *atlas_tex, return FALSE; } -static CoglBool +static gboolean allocate_from_bitmap (CoglAtlasTexture *atlas_tex, CoglTextureLoader *loader, - CoglError **error) + GError **error) { CoglTexture *tex = COGL_TEXTURE (atlas_tex); CoglBitmap *bmp = loader->src.bitmap.bitmap; CoglPixelFormat bmp_format = cogl_bitmap_get_format (bmp); int width = cogl_bitmap_get_width (bmp); int height = cogl_bitmap_get_height (bmp); - CoglBool can_convert_in_place = loader->src.bitmap.can_convert_in_place; + gboolean can_convert_in_place = loader->src.bitmap.can_convert_in_place; CoglPixelFormat internal_format; CoglBitmap *upload_bmp; - _COGL_RETURN_VAL_IF_FAIL (atlas_tex->atlas == NULL, FALSE); + g_return_val_if_fail (atlas_tex->atlas == NULL, FALSE); internal_format = _cogl_texture_determine_internal_format (tex, bmp_format); @@ -880,14 +863,14 @@ allocate_from_bitmap (CoglAtlasTexture *atlas_tex, return TRUE; } -static CoglBool +static gboolean _cogl_atlas_texture_allocate (CoglTexture *tex, - CoglError **error) + GError **error) { CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); CoglTextureLoader *loader = tex->loader; - _COGL_RETURN_VAL_IF_FAIL (loader, FALSE); + g_return_val_if_fail (loader, FALSE); switch (loader->src_type) { @@ -904,11 +887,11 @@ _cogl_atlas_texture_allocate (CoglTexture *tex, CoglAtlasTexture * _cogl_atlas_texture_new_from_bitmap (CoglBitmap *bmp, - CoglBool can_convert_in_place) + gboolean can_convert_in_place) { CoglTextureLoader *loader; - _COGL_RETURN_VAL_IF_FAIL (cogl_is_bitmap (bmp), NULL); + g_return_val_if_fail (cogl_is_bitmap (bmp), NULL); loader = _cogl_texture_create_loader (); loader->src_type = COGL_TEXTURE_SOURCE_TYPE_BITMAP; @@ -935,17 +918,18 @@ cogl_atlas_texture_new_from_data (CoglContext *ctx, CoglPixelFormat format, int rowstride, const uint8_t *data, - CoglError **error) + GError **error) { CoglBitmap *bmp; CoglAtlasTexture *atlas_tex; - _COGL_RETURN_VAL_IF_FAIL (format != COGL_PIXEL_FORMAT_ANY, NULL); - _COGL_RETURN_VAL_IF_FAIL (data != NULL, NULL); + g_return_val_if_fail (format != COGL_PIXEL_FORMAT_ANY, NULL); + g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, NULL); + g_return_val_if_fail (data != NULL, NULL); /* Rowstride from width if not given */ if (rowstride == 0) - rowstride = width * _cogl_pixel_format_get_bytes_per_pixel (format); + rowstride = width * cogl_pixel_format_get_bytes_per_pixel (format, 0); /* Wrap the data into a bitmap */ bmp = cogl_bitmap_new_for_data (ctx, @@ -971,12 +955,12 @@ cogl_atlas_texture_new_from_data (CoglContext *ctx, CoglAtlasTexture * cogl_atlas_texture_new_from_file (CoglContext *ctx, const char *filename, - CoglError **error) + GError **error) { CoglBitmap *bmp; CoglAtlasTexture *atlas_tex = NULL; - _COGL_RETURN_VAL_IF_FAIL (error == NULL || *error == NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); bmp = cogl_bitmap_new_from_file (filename, error); if (bmp == NULL) @@ -1015,18 +999,13 @@ _cogl_atlas_texture_remove_reorganize_callback (CoglContext *ctx, g_hook_destroy_link (&ctx->atlas_reorganize_callbacks, hook); } -static CoglTextureType -_cogl_atlas_texture_get_type (CoglTexture *tex) -{ - return COGL_TEXTURE_TYPE_2D; -} - static const CoglTextureVtable cogl_atlas_texture_vtable = { FALSE, /* not primitive */ _cogl_atlas_texture_allocate, _cogl_atlas_texture_set_region, + NULL, /* is_get_data_supported */ NULL, /* get_data */ _cogl_atlas_texture_foreach_sub_texture_in_region, _cogl_atlas_texture_get_max_waste, @@ -1041,7 +1020,5 @@ cogl_atlas_texture_vtable = _cogl_atlas_texture_gl_flush_legacy_texobj_wrap_modes, _cogl_atlas_texture_get_format, _cogl_atlas_texture_get_gl_format, - _cogl_atlas_texture_get_type, - NULL, /* is_foreign */ NULL /* set_auto_mipmap */ }; diff --git a/cogl/cogl/cogl-atlas-texture.h b/cogl/cogl/cogl-atlas-texture.h index 37b7b8f24..5c6184a42 100644 --- a/cogl/cogl/cogl-atlas-texture.h +++ b/cogl/cogl/cogl-atlas-texture.h @@ -39,7 +39,7 @@ #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS /** * SECTION:cogl-atlas-texture @@ -74,6 +74,7 @@ typedef struct _CoglAtlasTexture CoglAtlasTexture; * * Returns: a #GType that can be used with the GLib type system. */ +COGL_EXPORT GType cogl_atlas_texture_get_gtype (void); /** @@ -108,7 +109,7 @@ GType cogl_atlas_texture_get_gtype (void); * Since: 1.16 * Stability: unstable */ -CoglAtlasTexture * +COGL_EXPORT CoglAtlasTexture * cogl_atlas_texture_new_with_size (CoglContext *ctx, int width, int height); @@ -117,7 +118,7 @@ cogl_atlas_texture_new_with_size (CoglContext *ctx, * cogl_atlas_texture_new_from_file: * @ctx: A #CoglContext * @filename: the file to load - * @error: A #CoglError to catch exceptional errors or %NULL + * @error: A #GError to catch exceptional errors or %NULL * * Creates a #CoglAtlasTexture from an image file. A #CoglAtlasTexture * represents a sub-region within one of Cogl's shared texture @@ -146,10 +147,10 @@ cogl_atlas_texture_new_with_size (CoglContext *ctx, * Since: 1.16 * Stability: unstable */ -CoglAtlasTexture * +COGL_EXPORT CoglAtlasTexture * cogl_atlas_texture_new_from_file (CoglContext *ctx, const char *filename, - CoglError **error); + GError **error); /** * cogl_atlas_texture_new_from_data: @@ -161,7 +162,7 @@ cogl_atlas_texture_new_from_file (CoglContext *ctx, * row in @data. A value of 0 will make Cogl automatically * calculate @rowstride from @width and @format. * @data: pointer to the memory region where the source buffer resides - * @error: A #CoglError to catch exceptional errors or %NULL + * @error: A #GError to catch exceptional errors or %NULL * * Creates a new #CoglAtlasTexture texture based on data residing in * memory. A #CoglAtlasTexture represents a sub-region within one of @@ -191,14 +192,14 @@ cogl_atlas_texture_new_from_file (CoglContext *ctx, * Since: 1.16 * Stability: unstable */ -CoglAtlasTexture * +COGL_EXPORT CoglAtlasTexture * cogl_atlas_texture_new_from_data (CoglContext *ctx, int width, int height, CoglPixelFormat format, int rowstride, const uint8_t *data, - CoglError **error); + GError **error); /** * cogl_atlas_texture_new_from_bitmap: @@ -231,7 +232,7 @@ cogl_atlas_texture_new_from_data (CoglContext *ctx, * Since: 1.16 * Stability: unstable */ -CoglAtlasTexture * +COGL_EXPORT CoglAtlasTexture * cogl_atlas_texture_new_from_bitmap (CoglBitmap *bmp); /** @@ -246,9 +247,9 @@ cogl_atlas_texture_new_from_bitmap (CoglBitmap *bmp); * Since: 1.16 * Stability: Unstable */ -CoglBool +COGL_EXPORT gboolean cogl_is_atlas_texture (void *object); -COGL_END_DECLS +G_END_DECLS #endif /* _COGL_ATLAS_TEXTURE_H_ */ diff --git a/cogl/cogl/cogl-atlas.c b/cogl/cogl/cogl-atlas.c index 34c4e0595..3333f2f94 100644 --- a/cogl/cogl/cogl-atlas.c +++ b/cogl/cogl/cogl-atlas.c @@ -29,9 +29,7 @@ * Neil Roberts */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-atlas.h" #include "cogl-rectangle-map.h" @@ -40,7 +38,6 @@ #include "cogl-texture-2d-private.h" #include "cogl-texture-2d-sliced.h" #include "cogl-texture-driver.h" -#include "cogl-pipeline-opengl-private.h" #include "cogl-debug.h" #include "cogl-framebuffer-private.h" #include "cogl-blit.h" @@ -83,7 +80,7 @@ _cogl_atlas_free (CoglAtlas *atlas) g_hook_list_clear (&atlas->pre_reorganize_callbacks); g_hook_list_clear (&atlas->post_reorganize_callbacks); - free (atlas); + g_free (atlas); } typedef struct _CoglAtlasRepositionData @@ -184,6 +181,8 @@ _cogl_atlas_get_initial_size (CoglPixelFormat format, _COGL_GET_CONTEXT (ctx, NO_RETVAL); + g_return_if_fail (cogl_pixel_format_get_n_planes (format) == 1); + ctx->driver_vtable->pixel_format_to_gl (ctx, format, &gl_intformat, @@ -195,7 +194,7 @@ _cogl_atlas_get_initial_size (CoglPixelFormat format, initial minimum size. If the format is only 1 byte per pixel we can use 1024x1024, otherwise we'll assume it will take 4 bytes per pixel and use 512x512. */ - if (_cogl_pixel_format_get_bytes_per_pixel (format) == 1) + if (cogl_pixel_format_get_bytes_per_pixel (format, 0) == 1) size = 1024; else size = 512; @@ -285,18 +284,23 @@ _cogl_atlas_create_texture (CoglAtlas *atlas, int height) { CoglTexture2D *tex; - CoglError *ignore_error = NULL; + GError *ignore_error = NULL; _COGL_GET_CONTEXT (ctx, NULL); + g_return_val_if_fail ( + cogl_pixel_format_get_n_planes (atlas->texture_format) == 1, + NULL); + if ((atlas->flags & COGL_ATLAS_CLEAR_TEXTURE)) { uint8_t *clear_data; CoglBitmap *clear_bmp; - int bpp = _cogl_pixel_format_get_bytes_per_pixel (atlas->texture_format); + int bpp = cogl_pixel_format_get_bytes_per_pixel (atlas->texture_format, + 0); /* Create a buffer of zeroes to initially clear the texture */ - clear_data = calloc (1, width * height * bpp); + clear_data = g_malloc0 (width * height * bpp); clear_bmp = cogl_bitmap_new_for_data (ctx, width, height, @@ -311,14 +315,14 @@ _cogl_atlas_create_texture (CoglAtlas *atlas, if (!cogl_texture_allocate (COGL_TEXTURE (tex), &ignore_error)) { - cogl_error_free (ignore_error); + g_error_free (ignore_error); cogl_object_unref (tex); tex = NULL; } cogl_object_unref (clear_bmp); - free (clear_data); + g_free (clear_data); } else { @@ -329,7 +333,7 @@ _cogl_atlas_create_texture (CoglAtlas *atlas, if (!cogl_texture_allocate (COGL_TEXTURE (tex), &ignore_error)) { - cogl_error_free (ignore_error); + g_error_free (ignore_error); cogl_object_unref (tex); tex = NULL; } @@ -364,7 +368,7 @@ _cogl_atlas_notify_post_reorganize (CoglAtlas *atlas) g_hook_list_invoke (&atlas->post_reorganize_callbacks, FALSE); } -CoglBool +gboolean _cogl_atlas_reserve_space (CoglAtlas *atlas, unsigned int width, unsigned int height, @@ -374,7 +378,7 @@ _cogl_atlas_reserve_space (CoglAtlas *atlas, CoglRectangleMap *new_map; CoglTexture2D *new_tex; unsigned int map_width = 0, map_height = 0; - CoglBool ret; + gboolean ret; CoglRectangleMapEntry new_position; /* Check if we can fit the rectangle into the existing map */ @@ -409,12 +413,12 @@ _cogl_atlas_reserve_space (CoglAtlas *atlas, /* Get an array of all the textures currently in the atlas. */ data.n_textures = 0; if (atlas->map == NULL) - data.textures = malloc (sizeof (CoglAtlasRepositionData)); + data.textures = g_malloc (sizeof (CoglAtlasRepositionData)); else { unsigned int n_rectangles = _cogl_rectangle_map_get_n_rectangles (atlas->map); - data.textures = malloc (sizeof (CoglAtlasRepositionData) * + data.textures = g_malloc (sizeof (CoglAtlasRepositionData) * (n_rectangles + 1)); _cogl_rectangle_map_foreach (atlas->map, _cogl_atlas_get_rectangles_cb, @@ -528,7 +532,7 @@ _cogl_atlas_reserve_space (CoglAtlas *atlas, ret = TRUE; } - free (data.textures); + g_free (data.textures); _cogl_atlas_notify_post_reorganize (atlas); @@ -562,31 +566,23 @@ create_migration_texture (CoglContext *ctx, CoglPixelFormat internal_format) { CoglTexture *tex; - CoglError *skip_error = NULL; + GError *skip_error = NULL; - if ((_cogl_util_is_pot (width) && _cogl_util_is_pot (height)) || - (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_BASIC) && - cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP))) - { - /* First try creating a fast-path non-sliced texture */ - tex = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx, - width, height)); + /* First try creating a fast-path non-sliced texture */ + tex = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx, width, height)); - _cogl_texture_set_internal_format (tex, internal_format); + _cogl_texture_set_internal_format (tex, internal_format); - /* TODO: instead of allocating storage here it would be better - * if we had some api that let us just check that the size is - * supported by the hardware so storage could be allocated - * lazily when uploading data. */ - if (!cogl_texture_allocate (tex, &skip_error)) - { - cogl_error_free (skip_error); - cogl_object_unref (tex); - tex = NULL; - } + /* TODO: instead of allocating storage here it would be better + * if we had some api that let us just check that the size is + * supported by the hardware so storage could be allocated + * lazily when uploading data. */ + if (!cogl_texture_allocate (tex, &skip_error)) + { + g_error_free (skip_error); + cogl_object_unref (tex); + tex = NULL; } - else - tex = NULL; if (!tex) { @@ -615,7 +611,7 @@ _cogl_atlas_copy_rectangle (CoglAtlas *atlas, { CoglTexture *tex; CoglBlitData blit_data; - CoglError *ignore_error = NULL; + GError *ignore_error = NULL; _COGL_GET_CONTEXT (ctx, NULL); @@ -623,7 +619,7 @@ _cogl_atlas_copy_rectangle (CoglAtlas *atlas, tex = create_migration_texture (ctx, width, height, internal_format); if (!cogl_texture_allocate (tex, &ignore_error)) { - cogl_error_free (ignore_error); + g_error_free (ignore_error); cogl_object_unref (tex); return NULL; } diff --git a/cogl/cogl/cogl-atlas.h b/cogl/cogl/cogl-atlas.h index e9b3fb069..304161046 100644 --- a/cogl/cogl/cogl-atlas.h +++ b/cogl/cogl/cogl-atlas.h @@ -64,12 +64,12 @@ struct _CoglAtlas GHookList post_reorganize_callbacks; }; -CoglAtlas * +COGL_EXPORT CoglAtlas * _cogl_atlas_new (CoglPixelFormat texture_format, CoglAtlasFlags flags, CoglAtlasUpdatePositionCallback update_position_cb); -CoglBool +COGL_EXPORT gboolean _cogl_atlas_reserve_space (CoglAtlas *atlas, unsigned int width, unsigned int height, @@ -87,7 +87,7 @@ _cogl_atlas_copy_rectangle (CoglAtlas *atlas, int height, CoglPixelFormat format); -void +COGL_EXPORT void _cogl_atlas_add_reorganize_callback (CoglAtlas *atlas, GHookFunc pre_callback, GHookFunc post_callback, @@ -99,7 +99,7 @@ _cogl_atlas_remove_reorganize_callback (CoglAtlas *atlas, GHookFunc post_callback, void *user_data); -CoglBool +gboolean _cogl_is_atlas (void *object); #endif /* __COGL_ATLAS_H */ diff --git a/cogl/cogl/cogl-attribute-buffer.c b/cogl/cogl/cogl-attribute-buffer.c index dfc8e89f1..6617de304 100644 --- a/cogl/cogl/cogl-attribute-buffer.c +++ b/cogl/cogl/cogl-attribute-buffer.c @@ -31,9 +31,7 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-object-private.h" #include "cogl-attribute-buffer.h" @@ -73,7 +71,7 @@ cogl_attribute_buffer_new (CoglContext *context, buffer = cogl_attribute_buffer_new_with_size (context, bytes); /* Note: to keep the common cases simple this API doesn't throw - * CoglErrors, so developers can assume this function never returns + * GErrors, so developers can assume this function never returns * NULL and we will simply abort on error. * * Developers wanting to catch errors can use diff --git a/cogl/cogl/cogl-attribute-buffer.h b/cogl/cogl/cogl-attribute-buffer.h index 9c72df49c..9175a8b66 100644 --- a/cogl/cogl/cogl-attribute-buffer.h +++ b/cogl/cogl/cogl-attribute-buffer.h @@ -47,7 +47,7 @@ typedef struct _CoglAttributeBuffer CoglAttributeBuffer; #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS /** * SECTION:cogl-attribute-buffer @@ -64,6 +64,7 @@ COGL_BEGIN_DECLS * * Returns: a #GType that can be used with the GLib type system. */ +COGL_EXPORT GType cogl_attribute_buffer_get_gtype (void); /** @@ -89,7 +90,7 @@ GType cogl_attribute_buffer_get_gtype (void); * * Stability: Unstable */ -CoglAttributeBuffer * +COGL_EXPORT CoglAttributeBuffer * cogl_attribute_buffer_new_with_size (CoglContext *context, size_t bytes); @@ -122,7 +123,7 @@ cogl_attribute_buffer_new_with_size (CoglContext *context, * Since: 1.4 * Stability: Unstable */ -CoglAttributeBuffer * +COGL_EXPORT CoglAttributeBuffer * cogl_attribute_buffer_new (CoglContext *context, size_t bytes, const void *data); @@ -139,10 +140,10 @@ cogl_attribute_buffer_new (CoglContext *context, * Since: 1.4 * Stability: Unstable */ -CoglBool +COGL_EXPORT gboolean cogl_is_attribute_buffer (void *object); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_ATTRIBUTE_BUFFER_H__ */ diff --git a/cogl/cogl/cogl-attribute-private.h b/cogl/cogl/cogl-attribute-private.h index aac4a887d..e97cb7d0f 100644 --- a/cogl/cogl/cogl-attribute-private.h +++ b/cogl/cogl/cogl-attribute-private.h @@ -52,10 +52,10 @@ typedef enum typedef struct _CoglAttributeNameState { - char *name; + const char *name; CoglAttributeNameID name_id; int name_index; - CoglBool normalized_default; + gboolean normalized_default; int layer_number; } CoglAttributeNameState; @@ -64,9 +64,9 @@ struct _CoglAttribute CoglObject _parent; const CoglAttributeNameState *name_state; - CoglBool normalized; + gboolean normalized; - CoglBool is_buffered; + gboolean is_buffered; union { struct { @@ -90,17 +90,16 @@ typedef enum COGL_DRAW_SKIP_JOURNAL_FLUSH = 1 << 0, COGL_DRAW_SKIP_PIPELINE_VALIDATION = 1 << 1, COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH = 1 << 2, - COGL_DRAW_SKIP_LEGACY_STATE = 1 << 3, /* By default the vertex attribute drawing code will assume that if there is a color attribute array enabled then we can't determine if the colors will be opaque so we need to enabling blending. However when drawing from the journal we know what the contents of the color array is so we can override this by passing this flag. */ - COGL_DRAW_COLOR_ATTRIBUTE_IS_OPAQUE = 1 << 4, + COGL_DRAW_COLOR_ATTRIBUTE_IS_OPAQUE = 1 << 3, /* This forcibly disables the debug option to divert all drawing to * wireframes */ - COGL_DRAW_SKIP_DEBUG_WIREFRAME = 1 << 5 + COGL_DRAW_SKIP_DEBUG_WIREFRAME = 1 << 4 } CoglDrawFlags; /* During CoglContext initialization we register the "cogl_color_in" diff --git a/cogl/cogl/cogl-attribute.c b/cogl/cogl/cogl-attribute.c index 88c3179ad..6c1842e17 100644 --- a/cogl/cogl/cogl-attribute.c +++ b/cogl/cogl/cogl-attribute.c @@ -31,9 +31,7 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-util.h" #include "cogl-context-private.h" @@ -43,13 +41,9 @@ #include "cogl-attribute-private.h" #include "cogl-pipeline.h" #include "cogl-pipeline-private.h" -#include "cogl-pipeline-opengl-private.h" #include "cogl-texture-private.h" #include "cogl-framebuffer-private.h" #include "cogl-indices-private.h" -#ifdef COGL_PIPELINE_PROGEND_GLSL -#include "cogl-pipeline-progend-glsl-private.h" -#endif #include "cogl-private.h" #include "cogl-gtype-private.h" @@ -67,11 +61,11 @@ static void _cogl_attribute_free (CoglAttribute *attribute); COGL_OBJECT_DEFINE (Attribute, attribute); COGL_GTYPE_DEFINE_CLASS (Attribute, attribute); -static CoglBool +static gboolean validate_cogl_attribute_name (const char *name, - char **real_attribute_name, + const char **real_attribute_name, CoglAttributeNameID *name_id, - CoglBool *normalized, + gboolean *normalized, int *layer_number) { name = name + 5; /* skip "cogl_" */ @@ -164,45 +158,16 @@ _cogl_attribute_register_attribute_name (CoglContext *context, return name_state; error: - free (name_state); + g_free (name_state); return NULL; } -static CoglBool +static gboolean validate_n_components (const CoglAttributeNameState *name_state, int n_components) { switch (name_state->name_id) { - case COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY: - if (G_UNLIKELY (n_components == 1)) - { - g_critical ("glVertexPointer doesn't allow 1 component vertex " - "positions so we currently only support \"cogl_vertex\" " - "attributes where n_components == 2, 3 or 4"); - return FALSE; - } - break; - case COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY: - if (G_UNLIKELY (n_components != 3 && n_components != 4)) - { - g_critical ("glColorPointer expects 3 or 4 component colors so we " - "currently only support \"cogl_color\" attributes where " - "n_components == 3 or 4"); - return FALSE; - } - break; - case COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY: - break; - case COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY: - if (G_UNLIKELY (n_components != 3)) - { - g_critical ("glNormalPointer expects 3 component normals so we " - "currently only support \"cogl_normal\" attributes " - "where n_components == 3"); - return FALSE; - } - break; case COGL_ATTRIBUTE_NAME_ID_POINT_SIZE_ARRAY: if (G_UNLIKELY (n_components != 1)) { @@ -211,6 +176,10 @@ validate_n_components (const CoglAttributeNameState *name_state, return FALSE; } break; + case COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY: + case COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY: + case COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY: + case COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY: case COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY: return TRUE; } @@ -273,7 +242,7 @@ _cogl_attribute_new_const (CoglContext *context, const char *name, int n_components, int n_columns, - CoglBool transpose, + gboolean transpose, const float *value) { CoglAttribute *attribute = g_slice_new (CoglAttribute); @@ -311,7 +280,7 @@ _cogl_attribute_new_const (CoglContext *context, /* FIXME: Up until GL[ES] 3 only square matrices were supported * and we don't currently expose non-square matrices in Cogl. */ - _COGL_RETURN_VAL_IF_FAIL (n_columns == n_components, NULL); + g_return_val_if_fail (n_columns == n_components, NULL); _cogl_boxed_value_set_matrix (&attribute->d.constant.boxed, n_columns, 1, @@ -430,7 +399,7 @@ CoglAttribute * cogl_attribute_new_const_2x2fv (CoglContext *context, const char *name, const float *matrix2x2, - CoglBool transpose) + gboolean transpose) { return _cogl_attribute_new_const (context, name, @@ -444,7 +413,7 @@ CoglAttribute * cogl_attribute_new_const_3x3fv (CoglContext *context, const char *name, const float *matrix3x3, - CoglBool transpose) + gboolean transpose) { return _cogl_attribute_new_const (context, name, @@ -458,7 +427,7 @@ CoglAttribute * cogl_attribute_new_const_4x4fv (CoglContext *context, const char *name, const float *matrix4x4, - CoglBool transpose) + gboolean transpose) { return _cogl_attribute_new_const (context, name, @@ -468,10 +437,10 @@ cogl_attribute_new_const_4x4fv (CoglContext *context, matrix4x4); } -CoglBool +gboolean cogl_attribute_get_normalized (CoglAttribute *attribute) { - _COGL_RETURN_VAL_IF_FAIL (cogl_is_attribute (attribute), FALSE); + g_return_val_if_fail (cogl_is_attribute (attribute), FALSE); return attribute->normalized; } @@ -479,7 +448,7 @@ cogl_attribute_get_normalized (CoglAttribute *attribute) static void warn_about_midscene_changes (void) { - static CoglBool seen = FALSE; + static gboolean seen = FALSE; if (!seen) { g_warning ("Mid-scene modification of attributes has " @@ -490,9 +459,9 @@ warn_about_midscene_changes (void) void cogl_attribute_set_normalized (CoglAttribute *attribute, - CoglBool normalized) + gboolean normalized) { - _COGL_RETURN_IF_FAIL (cogl_is_attribute (attribute)); + g_return_if_fail (cogl_is_attribute (attribute)); if (G_UNLIKELY (attribute->immutable_ref)) warn_about_midscene_changes (); @@ -503,8 +472,8 @@ cogl_attribute_set_normalized (CoglAttribute *attribute, CoglAttributeBuffer * cogl_attribute_get_buffer (CoglAttribute *attribute) { - _COGL_RETURN_VAL_IF_FAIL (cogl_is_attribute (attribute), NULL); - _COGL_RETURN_VAL_IF_FAIL (attribute->is_buffered, NULL); + g_return_val_if_fail (cogl_is_attribute (attribute), NULL); + g_return_val_if_fail (attribute->is_buffered, NULL); return attribute->d.buffered.attribute_buffer; } @@ -513,8 +482,8 @@ void cogl_attribute_set_buffer (CoglAttribute *attribute, CoglAttributeBuffer *attribute_buffer) { - _COGL_RETURN_IF_FAIL (cogl_is_attribute (attribute)); - _COGL_RETURN_IF_FAIL (attribute->is_buffered); + g_return_if_fail (cogl_is_attribute (attribute)); + g_return_if_fail (attribute->is_buffered); if (G_UNLIKELY (attribute->immutable_ref)) warn_about_midscene_changes (); @@ -530,7 +499,7 @@ _cogl_attribute_immutable_ref (CoglAttribute *attribute) { CoglBuffer *buffer = COGL_BUFFER (attribute->d.buffered.attribute_buffer); - _COGL_RETURN_VAL_IF_FAIL (cogl_is_attribute (attribute), NULL); + g_return_val_if_fail (cogl_is_attribute (attribute), NULL); attribute->immutable_ref++; _cogl_buffer_immutable_ref (buffer); @@ -542,8 +511,8 @@ _cogl_attribute_immutable_unref (CoglAttribute *attribute) { CoglBuffer *buffer = COGL_BUFFER (attribute->d.buffered.attribute_buffer); - _COGL_RETURN_IF_FAIL (cogl_is_attribute (attribute)); - _COGL_RETURN_IF_FAIL (attribute->immutable_ref > 0); + g_return_if_fail (cogl_is_attribute (attribute)); + g_return_if_fail (attribute->immutable_ref > 0); attribute->immutable_ref--; _cogl_buffer_immutable_unref (buffer); @@ -560,7 +529,7 @@ _cogl_attribute_free (CoglAttribute *attribute) g_slice_free (CoglAttribute, attribute); } -static CoglBool +static gboolean validate_layer_cb (CoglPipeline *pipeline, int layer_index, void *user_data) @@ -568,7 +537,7 @@ validate_layer_cb (CoglPipeline *pipeline, CoglTexture *texture = cogl_pipeline_get_layer_texture (pipeline, layer_index); CoglFlushLayerState *state = user_data; - CoglBool status = TRUE; + gboolean status = TRUE; /* invalid textures will be handled correctly in * _cogl_pipeline_flush_layers_gl_state */ @@ -654,18 +623,8 @@ _cogl_flush_attributes_state (CoglFramebuffer *framebuffer, * pixel and the scene is just comprised of simple rectangles still * in the journal. For this optimization to work we need to track * when the framebuffer really does get drawn to. */ - _cogl_framebuffer_mark_mid_scene (framebuffer); _cogl_framebuffer_mark_clear_clip_dirty (framebuffer); - if (G_UNLIKELY (!(flags & COGL_DRAW_SKIP_LEGACY_STATE)) && - G_UNLIKELY (ctx->legacy_state_set) && - _cogl_get_enable_legacy_state ()) - { - copy = cogl_pipeline_copy (pipeline); - pipeline = copy; - _cogl_pipeline_apply_legacy_state (pipeline); - } - ctx->driver_vtable->flush_attributes_state (framebuffer, pipeline, &layers_state, diff --git a/cogl/cogl/cogl-attribute.h b/cogl/cogl/cogl-attribute.h index 801412c46..f35274b56 100644 --- a/cogl/cogl/cogl-attribute.h +++ b/cogl/cogl/cogl-attribute.h @@ -48,7 +48,7 @@ typedef struct _CoglAttribute CoglAttribute; #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS /** * SECTION:cogl-attribute @@ -63,6 +63,7 @@ COGL_BEGIN_DECLS * * Returns: a #GType that can be used with the GLib type system. */ +COGL_EXPORT GType cogl_attribute_get_gtype (void); /** @@ -155,7 +156,7 @@ GType cogl_attribute_get_gtype (void); */ /* XXX: look for a precedent to see if the stride/offset args should * have a different order. */ -CoglAttribute * +COGL_EXPORT CoglAttribute * cogl_attribute_new (CoglAttributeBuffer *attribute_buffer, const char *name, size_t stride, @@ -183,7 +184,7 @@ cogl_attribute_new (CoglAttributeBuffer *attribute_buffer, * Return value: (transfer full): A newly allocated #CoglAttribute * representing the given constant @value. */ -CoglAttribute * +COGL_EXPORT CoglAttribute * cogl_attribute_new_const_1f (CoglContext *context, const char *name, float value); @@ -210,7 +211,7 @@ cogl_attribute_new_const_1f (CoglContext *context, * Return value: (transfer full): A newly allocated #CoglAttribute * representing the given constant vector. */ -CoglAttribute * +COGL_EXPORT CoglAttribute * cogl_attribute_new_const_2f (CoglContext *context, const char *name, float component0, @@ -242,7 +243,7 @@ cogl_attribute_new_const_2f (CoglContext *context, * Return value: (transfer full): A newly allocated #CoglAttribute * representing the given constant vector. */ -CoglAttribute * +COGL_EXPORT CoglAttribute * cogl_attribute_new_const_3f (CoglContext *context, const char *name, float component0, @@ -277,7 +278,7 @@ cogl_attribute_new_const_3f (CoglContext *context, * Return value: (transfer full): A newly allocated #CoglAttribute * representing the given constant vector. */ -CoglAttribute * +COGL_EXPORT CoglAttribute * cogl_attribute_new_const_4f (CoglContext *context, const char *name, float component0, @@ -306,7 +307,7 @@ cogl_attribute_new_const_4f (CoglContext *context, * Return value: (transfer full): A newly allocated #CoglAttribute * representing the given constant vector. */ -CoglAttribute * +COGL_EXPORT CoglAttribute * cogl_attribute_new_const_2fv (CoglContext *context, const char *name, const float *value); @@ -335,7 +336,7 @@ cogl_attribute_new_const_2fv (CoglContext *context, * Return value: (transfer full): A newly allocated #CoglAttribute * representing the given constant vector. */ -CoglAttribute * +COGL_EXPORT CoglAttribute * cogl_attribute_new_const_3fv (CoglContext *context, const char *name, const float *value); @@ -365,7 +366,7 @@ cogl_attribute_new_const_3fv (CoglContext *context, * Return value: (transfer full): A newly allocated #CoglAttribute * representing the given constant vector. */ -CoglAttribute * +COGL_EXPORT CoglAttribute * cogl_attribute_new_const_4fv (CoglContext *context, const char *name, const float *value); @@ -398,11 +399,11 @@ cogl_attribute_new_const_4fv (CoglContext *context, * Return value: (transfer full): A newly allocated #CoglAttribute * representing the given constant matrix. */ -CoglAttribute * +COGL_EXPORT CoglAttribute * cogl_attribute_new_const_2x2fv (CoglContext *context, const char *name, const float *matrix2x2, - CoglBool transpose); + gboolean transpose); /** * cogl_attribute_new_const_3x3fv: @@ -433,11 +434,11 @@ cogl_attribute_new_const_2x2fv (CoglContext *context, * Return value: (transfer full): A newly allocated #CoglAttribute * representing the given constant matrix. */ -CoglAttribute * +COGL_EXPORT CoglAttribute * cogl_attribute_new_const_3x3fv (CoglContext *context, const char *name, const float *matrix3x3, - CoglBool transpose); + gboolean transpose); /** * cogl_attribute_new_const_4x4fv: @@ -468,11 +469,11 @@ cogl_attribute_new_const_3x3fv (CoglContext *context, * Return value: (transfer full): A newly allocated #CoglAttribute * representing the given constant matrix. */ -CoglAttribute * +COGL_EXPORT CoglAttribute * cogl_attribute_new_const_4x4fv (CoglContext *context, const char *name, const float *matrix4x4, - CoglBool transpose); + gboolean transpose); /** * cogl_attribute_set_normalized: @@ -492,9 +493,9 @@ cogl_attribute_new_const_4x4fv (CoglContext *context, * Stability: unstable * Since: 1.10 */ -void +COGL_EXPORT void cogl_attribute_set_normalized (CoglAttribute *attribute, - CoglBool normalized); + gboolean normalized); /** * cogl_attribute_get_normalized: @@ -506,7 +507,7 @@ cogl_attribute_set_normalized (CoglAttribute *attribute, * Stability: unstable * Since: 1.10 */ -CoglBool +COGL_EXPORT gboolean cogl_attribute_get_normalized (CoglAttribute *attribute); /** @@ -519,7 +520,7 @@ cogl_attribute_get_normalized (CoglAttribute *attribute); * Stability: unstable * Since: 1.10 */ -CoglAttributeBuffer * +COGL_EXPORT CoglAttributeBuffer * cogl_attribute_get_buffer (CoglAttribute *attribute); /** @@ -532,7 +533,7 @@ cogl_attribute_get_buffer (CoglAttribute *attribute); * Stability: unstable * Since: 1.10 */ -void +COGL_EXPORT void cogl_attribute_set_buffer (CoglAttribute *attribute, CoglAttributeBuffer *attribute_buffer); @@ -545,10 +546,10 @@ cogl_attribute_set_buffer (CoglAttribute *attribute, * Return value: %TRUE if the @object references a #CoglAttribute, * %FALSE otherwise */ -CoglBool +COGL_EXPORT gboolean cogl_is_attribute (void *object); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_ATTRIBUTE_H__ */ diff --git a/cogl/cogl/cogl-bitmap-conversion.c b/cogl/cogl/cogl-bitmap-conversion.c index 73163bb6a..447db00b3 100644 --- a/cogl/cogl/cogl-bitmap-conversion.c +++ b/cogl/cogl/cogl-bitmap-conversion.c @@ -28,9 +28,7 @@ * */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-private.h" #include "cogl-bitmap-private.h" @@ -291,7 +289,7 @@ _cogl_bitmap_premult_unpacked_span_16 (uint16_t *data, } } -static CoglBool +static gboolean _cogl_bitmap_can_fast_premult (CoglPixelFormat format) { switch (format & ~COGL_PREMULT_BIT) @@ -307,7 +305,7 @@ _cogl_bitmap_can_fast_premult (CoglPixelFormat format) } } -static CoglBool +static gboolean _cogl_bitmap_needs_short_temp_buffer (CoglPixelFormat format) { /* If the format is using more than 8 bits per component then we'll @@ -357,12 +355,13 @@ _cogl_bitmap_needs_short_temp_buffer (CoglPixelFormat format) } g_assert_not_reached (); + return FALSE; } -CoglBool +gboolean _cogl_bitmap_convert_into_bitmap (CoglBitmap *src_bmp, CoglBitmap *dst_bmp, - CoglError **error) + GError **error) { uint8_t *src_data; uint8_t *dst_data; @@ -375,8 +374,8 @@ _cogl_bitmap_convert_into_bitmap (CoglBitmap *src_bmp, int width, height; CoglPixelFormat src_format; CoglPixelFormat dst_format; - CoglBool use_16; - CoglBool need_premult; + gboolean use_16; + gboolean need_premult; src_format = cogl_bitmap_get_format (src_bmp); src_rowstride = cogl_bitmap_get_rowstride (src_bmp); @@ -385,8 +384,8 @@ _cogl_bitmap_convert_into_bitmap (CoglBitmap *src_bmp, width = cogl_bitmap_get_width (src_bmp); height = cogl_bitmap_get_height (src_bmp); - _COGL_RETURN_VAL_IF_FAIL (width == cogl_bitmap_get_width (dst_bmp), FALSE); - _COGL_RETURN_VAL_IF_FAIL (height == cogl_bitmap_get_height (dst_bmp), FALSE); + g_return_val_if_fail (width == cogl_bitmap_get_width (dst_bmp), FALSE); + g_return_val_if_fail (height == cogl_bitmap_get_height (dst_bmp), FALSE); need_premult = ((src_format & COGL_PREMULT_BIT) != (dst_format & COGL_PREMULT_BIT) && @@ -439,7 +438,7 @@ _cogl_bitmap_convert_into_bitmap (CoglBitmap *src_bmp, use_16 = _cogl_bitmap_needs_short_temp_buffer (dst_format); /* Allocate a buffer to hold a temporary RGBA row */ - tmp_row = malloc (width * + tmp_row = g_malloc (width * (use_16 ? sizeof (uint16_t) : sizeof (uint8_t)) * 4); /* FIXME: Optimize */ @@ -481,7 +480,7 @@ _cogl_bitmap_convert_into_bitmap (CoglBitmap *src_bmp, _cogl_bitmap_unmap (src_bmp); _cogl_bitmap_unmap (dst_bmp); - free (tmp_row); + g_free (tmp_row); return TRUE; } @@ -489,7 +488,7 @@ _cogl_bitmap_convert_into_bitmap (CoglBitmap *src_bmp, CoglBitmap * _cogl_bitmap_convert (CoglBitmap *src_bmp, CoglPixelFormat dst_format, - CoglError **error) + GError **error) { CoglBitmap *dst_bmp; int width, height; @@ -515,7 +514,7 @@ _cogl_bitmap_convert (CoglBitmap *src_bmp, return dst_bmp; } -static CoglBool +static gboolean driver_can_convert (CoglContext *ctx, CoglPixelFormat src_format, CoglPixelFormat internal_format) @@ -547,14 +546,14 @@ driver_can_convert (CoglContext *ctx, CoglBitmap * _cogl_bitmap_convert_for_upload (CoglBitmap *src_bmp, CoglPixelFormat internal_format, - CoglBool can_convert_in_place, - CoglError **error) + gboolean can_convert_in_place, + GError **error) { CoglContext *ctx = _cogl_bitmap_get_context (src_bmp); CoglPixelFormat src_format = cogl_bitmap_get_format (src_bmp); CoglBitmap *dst_bmp; - _COGL_RETURN_VAL_IF_FAIL (internal_format != COGL_PIXEL_FORMAT_ANY, NULL); + g_return_val_if_fail (internal_format != COGL_PIXEL_FORMAT_ANY, NULL); /* OpenGL supports specifying a different format for the internal format when uploading texture data. We should use this to convert @@ -615,9 +614,9 @@ _cogl_bitmap_convert_for_upload (CoglBitmap *src_bmp, return dst_bmp; } -CoglBool +gboolean _cogl_bitmap_unpremult (CoglBitmap *bmp, - CoglError **error) + GError **error) { uint8_t *p, *data; uint16_t *tmp_row; @@ -644,7 +643,7 @@ _cogl_bitmap_unpremult (CoglBitmap *bmp, if (_cogl_bitmap_can_fast_premult (format)) tmp_row = NULL; else - tmp_row = malloc (sizeof (uint16_t) * 4 * width); + tmp_row = g_malloc (sizeof (uint16_t) * 4 * width); for (y = 0; y < height; y++) { @@ -674,7 +673,7 @@ _cogl_bitmap_unpremult (CoglBitmap *bmp, } } - free (tmp_row); + g_free (tmp_row); _cogl_bitmap_unmap (bmp); @@ -683,9 +682,9 @@ _cogl_bitmap_unpremult (CoglBitmap *bmp, return TRUE; } -CoglBool +gboolean _cogl_bitmap_premult (CoglBitmap *bmp, - CoglError **error) + GError **error) { uint8_t *p, *data; uint16_t *tmp_row; @@ -711,7 +710,7 @@ _cogl_bitmap_premult (CoglBitmap *bmp, if (_cogl_bitmap_can_fast_premult (format)) tmp_row = NULL; else - tmp_row = malloc (sizeof (uint16_t) * 4 * width); + tmp_row = g_malloc (sizeof (uint16_t) * 4 * width); for (y = 0; y < height; y++) { @@ -738,7 +737,7 @@ _cogl_bitmap_premult (CoglBitmap *bmp, } } - free (tmp_row); + g_free (tmp_row); _cogl_bitmap_unmap (bmp); diff --git a/cogl/cogl/cogl-bitmap-pixbuf.c b/cogl/cogl/cogl-bitmap-pixbuf.c index 21b6fb443..10af4966d 100644 --- a/cogl/cogl/cogl-bitmap-pixbuf.c +++ b/cogl/cogl/cogl-bitmap-pixbuf.c @@ -28,26 +28,23 @@ * */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-util.h" #include "cogl-bitmap-private.h" #include "cogl-context-private.h" #include "cogl-private.h" -#include "cogl-error-private.h" #include #include -CoglBool +gboolean _cogl_bitmap_get_size_from_file (const char *filename, int *width, int *height) { - _COGL_RETURN_VAL_IF_FAIL (filename != NULL, FALSE); + g_return_val_if_fail (filename != NULL, FALSE); if (gdk_pixbuf_get_file_info (filename, width, height) != NULL) return TRUE; @@ -58,11 +55,11 @@ _cogl_bitmap_get_size_from_file (const char *filename, CoglBitmap * _cogl_bitmap_from_file (CoglContext *ctx, const char *filename, - CoglError **error) + GError **error) { static CoglUserDataKey pixbuf_key; GdkPixbuf *pixbuf; - CoglBool has_alpha; + gboolean has_alpha; GdkColorspace color_space; CoglPixelFormat pixel_format; int width; @@ -77,7 +74,7 @@ _cogl_bitmap_from_file (CoglContext *ctx, pixbuf = gdk_pixbuf_new_from_file (filename, &glib_error); if (pixbuf == NULL) { - _cogl_propagate_gerror (error, glib_error); + g_propagate_error (error, glib_error); return FALSE; } diff --git a/cogl/cogl/cogl-bitmap-private.h b/cogl/cogl/cogl-bitmap-private.h index 3bd1e2e83..a92d6af48 100644 --- a/cogl/cogl/cogl-bitmap-private.h +++ b/cogl/cogl/cogl-bitmap-private.h @@ -51,8 +51,8 @@ struct _CoglBitmap uint8_t *data; - CoglBool mapped; - CoglBool bound; + gboolean mapped; + gboolean bound; /* If this is non-null then 'data' is ignored and instead it is fetched from this shared bitmap. */ @@ -70,10 +70,10 @@ struct _CoglBitmap * @width: width of the bitmap in pixels * @height: height of the bitmap in pixels * @format: the format of the pixels the array will store - * @error: A #CoglError for catching exceptional errors or %NULL + * @error: A #GError for catching exceptional errors or %NULL * * This is equivalent to cogl_bitmap_new_with_size() except that it - * allocated the buffer using malloc() instead of creating a + * allocated the buffer using g_malloc() instead of creating a * #CoglPixelBuffer. The buffer will be automatically destroyed when * the bitmap is freed. * @@ -87,7 +87,7 @@ _cogl_bitmap_new_with_malloc_buffer (CoglContext *context, unsigned int width, unsigned int height, CoglPixelFormat format, - CoglError **error); + GError **error); /* The idea of this function is that it will create a bitmap that shares the actual data with another bitmap. This is needed for the @@ -103,55 +103,55 @@ _cogl_bitmap_new_shared (CoglBitmap *shared_bmp, CoglBitmap * _cogl_bitmap_convert (CoglBitmap *bmp, - CoglPixelFormat dst_format, - CoglError **error); + CoglPixelFormat dst_format, + GError **error); CoglBitmap * _cogl_bitmap_convert_for_upload (CoglBitmap *src_bmp, CoglPixelFormat internal_format, - CoglBool can_convert_in_place, - CoglError **error); + gboolean can_convert_in_place, + GError **error); -CoglBool +gboolean _cogl_bitmap_convert_into_bitmap (CoglBitmap *src_bmp, CoglBitmap *dst_bmp, - CoglError **error); + GError **error); CoglBitmap * _cogl_bitmap_from_file (CoglContext *ctx, const char *filename, - CoglError **error); + GError **error); -CoglBool +gboolean _cogl_bitmap_unpremult (CoglBitmap *dst_bmp, - CoglError **error); + GError **error); -CoglBool +gboolean _cogl_bitmap_premult (CoglBitmap *dst_bmp, - CoglError **error); + GError **error); -CoglBool +gboolean _cogl_bitmap_convert_premult_status (CoglBitmap *bmp, CoglPixelFormat dst_format, - CoglError **error); + GError **error); -CoglBool +gboolean _cogl_bitmap_copy_subregion (CoglBitmap *src, - CoglBitmap *dst, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height, - CoglError **error); + CoglBitmap *dst, + int src_x, + int src_y, + int dst_x, + int dst_y, + int width, + int height, + GError **error); /* Creates a deep copy of the source bitmap */ CoglBitmap * _cogl_bitmap_copy (CoglBitmap *src_bmp, - CoglError **error); + GError **error); -CoglBool +gboolean _cogl_bitmap_get_size_from_file (const char *filename, int *width, int *height); @@ -172,29 +172,11 @@ uint8_t * _cogl_bitmap_map (CoglBitmap *bitmap, CoglBufferAccess access, CoglBufferMapHint hints, - CoglError **error); + GError **error); void _cogl_bitmap_unmap (CoglBitmap *bitmap); -/* These two are replacements for map and unmap that should used when - * the pointer is going to be passed to GL for pixel packing or - * unpacking. The address might not be valid for reading if the bitmap - * was created with new_from_buffer but it will however be good to - * pass to glTexImage2D for example. The access should be READ for - * unpacking and WRITE for packing. It can not be both - * - * TODO: split this bind/unbind functions out into a GL specific file - */ -uint8_t * -_cogl_bitmap_gl_bind (CoglBitmap *bitmap, - CoglBufferAccess access, - CoglBufferMapHint hints, - CoglError **error); - -void -_cogl_bitmap_gl_unbind (CoglBitmap *bitmap); - CoglContext * _cogl_bitmap_get_context (CoglBitmap *bitmap); diff --git a/cogl/cogl/cogl-bitmap.c b/cogl/cogl/cogl-bitmap.c index 276cda499..f5577e342 100644 --- a/cogl/cogl/cogl-bitmap.c +++ b/cogl/cogl/cogl-bitmap.c @@ -28,9 +28,7 @@ * */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-util.h" #include "cogl-debug.h" @@ -39,8 +37,6 @@ #include "cogl-buffer-private.h" #include "cogl-pixel-buffer.h" #include "cogl-context-private.h" -#include "cogl-buffer-gl-private.h" -#include "cogl-error-private.h" #include "cogl-gtype-private.h" #include @@ -65,10 +61,10 @@ _cogl_bitmap_free (CoglBitmap *bmp) g_slice_free (CoglBitmap, bmp); } -CoglBool +gboolean _cogl_bitmap_convert_premult_status (CoglBitmap *bmp, CoglPixelFormat dst_format, - CoglError **error) + GError **error) { /* Do we need to unpremultiply? */ if ((bmp->format & COGL_PREMULT_BIT) > 0 && @@ -88,7 +84,7 @@ _cogl_bitmap_convert_premult_status (CoglBitmap *bmp, CoglBitmap * _cogl_bitmap_copy (CoglBitmap *src_bmp, - CoglError **error) + GError **error) { CoglBitmap *dst_bmp; CoglPixelFormat src_format = cogl_bitmap_get_format (src_bmp); @@ -117,7 +113,7 @@ _cogl_bitmap_copy (CoglBitmap *src_bmp, return dst_bmp; } -CoglBool +gboolean _cogl_bitmap_copy_subregion (CoglBitmap *src, CoglBitmap *dst, int src_x, @@ -126,20 +122,22 @@ _cogl_bitmap_copy_subregion (CoglBitmap *src, int dst_y, int width, int height, - CoglError **error) + GError **error) { uint8_t *srcdata; uint8_t *dstdata; int bpp; int line; - CoglBool succeeded = FALSE; + gboolean succeeded = FALSE; /* Intended only for fast copies when format is equal! */ - _COGL_RETURN_VAL_IF_FAIL ((src->format & ~COGL_PREMULT_BIT) == - (dst->format & ~COGL_PREMULT_BIT), - FALSE); + g_return_val_if_fail ((src->format & ~COGL_PREMULT_BIT) == + (dst->format & ~COGL_PREMULT_BIT), + FALSE); + g_return_val_if_fail (cogl_pixel_format_get_n_planes (src->format) == 1, + FALSE); - bpp = _cogl_pixel_format_get_bytes_per_pixel (src->format); + bpp = cogl_pixel_format_get_bytes_per_pixel (src->format, 0); if ((srcdata = _cogl_bitmap_map (src, COGL_BUFFER_ACCESS_READ, 0, error))) { @@ -167,7 +165,7 @@ _cogl_bitmap_copy_subregion (CoglBitmap *src, return succeeded; } -CoglBool +gboolean cogl_bitmap_get_size_from_file (const char *filename, int *width, int *height) @@ -186,10 +184,11 @@ cogl_bitmap_new_for_data (CoglContext *context, CoglBitmap *bmp; g_return_val_if_fail (cogl_is_context (context), NULL); + g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, NULL); /* Rowstride from width if not given */ if (rowstride == 0) - rowstride = width * _cogl_pixel_format_get_bytes_per_pixel (format); + rowstride = width * cogl_pixel_format_get_bytes_per_pixel (format, 0); bmp = g_slice_new (CoglBitmap); bmp->context = context; @@ -211,23 +210,30 @@ _cogl_bitmap_new_with_malloc_buffer (CoglContext *context, unsigned int width, unsigned int height, CoglPixelFormat format, - CoglError **error) + GError **error) { static CoglUserDataKey bitmap_free_key; - int bpp = _cogl_pixel_format_get_bytes_per_pixel (format); - int rowstride = ((width * bpp) + 3) & ~3; - uint8_t *data = g_try_malloc (rowstride * height); + int bpp; + int rowstride; + uint8_t *data; CoglBitmap *bitmap; + g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, NULL); + + /* Try to malloc the data */ + bpp = cogl_pixel_format_get_bytes_per_pixel (format, 0); + rowstride = ((width * bpp) + 3) & ~3; + data = g_try_malloc (rowstride * height); + if (!data) { - _cogl_set_error (error, - COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_NO_MEMORY, - "Failed to allocate memory for bitmap"); + g_set_error_literal (error, COGL_SYSTEM_ERROR, + COGL_SYSTEM_ERROR_NO_MEMORY, + "Failed to allocate memory for bitmap"); return NULL; } + /* Now create the bitmap */ bitmap = cogl_bitmap_new_for_data (context, width, height, format, @@ -236,7 +242,7 @@ _cogl_bitmap_new_with_malloc_buffer (CoglContext *context, cogl_object_set_user_data (COGL_OBJECT (bitmap), &bitmap_free_key, data, - free); + g_free); return bitmap; } @@ -263,12 +269,12 @@ _cogl_bitmap_new_shared (CoglBitmap *shared_bmp, CoglBitmap * cogl_bitmap_new_from_file (const char *filename, - CoglError **error) + GError **error) { _COGL_GET_CONTEXT (ctx, NULL); - _COGL_RETURN_VAL_IF_FAIL (filename != NULL, NULL); - _COGL_RETURN_VAL_IF_FAIL (error == NULL || *error == NULL, NULL); + g_return_val_if_fail (filename != NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); return _cogl_bitmap_from_file (ctx, filename, error); } @@ -283,7 +289,7 @@ cogl_bitmap_new_from_buffer (CoglBuffer *buffer, { CoglBitmap *bmp; - _COGL_RETURN_VAL_IF_FAIL (cogl_is_buffer (buffer), NULL); + g_return_val_if_fail (cogl_is_buffer (buffer), NULL); bmp = cogl_bitmap_new_for_data (buffer->context, width, height, @@ -308,18 +314,19 @@ cogl_bitmap_new_with_size (CoglContext *context, unsigned int rowstride; /* creating a buffer to store "any" format does not make sense */ - _COGL_RETURN_VAL_IF_FAIL (format != COGL_PIXEL_FORMAT_ANY, NULL); + g_return_val_if_fail (format != COGL_PIXEL_FORMAT_ANY, NULL); + g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, NULL); /* for now we fallback to cogl_pixel_buffer_new, later, we could ask * libdrm a tiled buffer for instance */ - rowstride = width * _cogl_pixel_format_get_bytes_per_pixel (format); + rowstride = width * cogl_pixel_format_get_bytes_per_pixel (format, 0); pixel_buffer = cogl_pixel_buffer_new (context, height * rowstride, NULL); /* data */ - _COGL_RETURN_VAL_IF_FAIL (pixel_buffer != NULL, NULL); + g_return_val_if_fail (pixel_buffer != NULL, NULL); bitmap = cogl_bitmap_new_from_buffer (COGL_BUFFER (pixel_buffer), format, @@ -382,7 +389,7 @@ uint8_t * _cogl_bitmap_map (CoglBitmap *bitmap, CoglBufferAccess access, CoglBufferMapHint hints, - CoglError **error) + GError **error) { /* Divert to another bitmap if this data is shared */ if (bitmap->shared_bmp) @@ -435,86 +442,6 @@ _cogl_bitmap_unmap (CoglBitmap *bitmap) cogl_buffer_unmap (bitmap->buffer); } -uint8_t * -_cogl_bitmap_gl_bind (CoglBitmap *bitmap, - CoglBufferAccess access, - CoglBufferMapHint hints, - CoglError **error) -{ - uint8_t *ptr; - CoglError *internal_error = NULL; - - g_return_val_if_fail (access & (COGL_BUFFER_ACCESS_READ | - COGL_BUFFER_ACCESS_WRITE), - NULL); - - /* Divert to another bitmap if this data is shared */ - if (bitmap->shared_bmp) - return _cogl_bitmap_gl_bind (bitmap->shared_bmp, access, hints, error); - - _COGL_RETURN_VAL_IF_FAIL (!bitmap->bound, NULL); - - /* If the bitmap wasn't created from a buffer then the - implementation of bind is the same as map */ - if (bitmap->buffer == NULL) - { - uint8_t *data = _cogl_bitmap_map (bitmap, access, hints, error); - if (data) - bitmap->bound = TRUE; - return data; - } - - if (access == COGL_BUFFER_ACCESS_READ) - ptr = _cogl_buffer_gl_bind (bitmap->buffer, - COGL_BUFFER_BIND_TARGET_PIXEL_UNPACK, - &internal_error); - else if (access == COGL_BUFFER_ACCESS_WRITE) - ptr = _cogl_buffer_gl_bind (bitmap->buffer, - COGL_BUFFER_BIND_TARGET_PIXEL_PACK, - &internal_error); - else - { - ptr = NULL; - g_assert_not_reached (); - return NULL; - } - - /* NB: _cogl_buffer_gl_bind() may return NULL in non-error - * conditions so we have to explicitly check internal_error to see - * if an exception was thrown */ - if (internal_error) - { - _cogl_propagate_error (error, internal_error); - return NULL; - } - - bitmap->bound = TRUE; - - /* The data pointer actually stores the offset */ - return ptr + GPOINTER_TO_INT (bitmap->data); -} - -void -_cogl_bitmap_gl_unbind (CoglBitmap *bitmap) -{ - /* Divert to another bitmap if this data is shared */ - if (bitmap->shared_bmp) - { - _cogl_bitmap_gl_unbind (bitmap->shared_bmp); - return; - } - - g_assert (bitmap->bound); - bitmap->bound = FALSE; - - /* If the bitmap wasn't created from a pixel array then the - implementation of unbind is the same as unmap */ - if (bitmap->buffer) - _cogl_buffer_gl_unbind (bitmap->buffer); - else - _cogl_bitmap_unmap (bitmap); -} - CoglContext * _cogl_bitmap_get_context (CoglBitmap *bitmap) { diff --git a/cogl/cogl/cogl-bitmap.h b/cogl/cogl/cogl-bitmap.h index 723f8d0d0..955fbb59d 100644 --- a/cogl/cogl/cogl-bitmap.h +++ b/cogl/cogl/cogl-bitmap.h @@ -43,16 +43,18 @@ typedef struct _CoglBitmap CoglBitmap; #include #include #include +#include #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS /** * cogl_bitmap_get_gtype: * * Returns: a #GType that can be used with the GLib type system. */ +COGL_EXPORT GType cogl_bitmap_get_gtype (void); /** @@ -69,7 +71,7 @@ GType cogl_bitmap_get_gtype (void); /** * cogl_bitmap_new_from_file: * @filename: the file to load. - * @error: a #CoglError or %NULL. + * @error: a #GError or %NULL. * * Loads an image file from disk. This function can be safely called from * within a thread. @@ -79,9 +81,9 @@ GType cogl_bitmap_get_gtype (void); * * Since: 1.0 */ -CoglBitmap * +COGL_EXPORT CoglBitmap * cogl_bitmap_new_from_file (const char *filename, - CoglError **error); + GError **error); /** * cogl_bitmap_new_from_buffer: (skip) @@ -102,7 +104,7 @@ cogl_bitmap_new_from_file (const char *filename, * Since: 1.8 * Stability: unstable */ -CoglBitmap * +COGL_EXPORT CoglBitmap * cogl_bitmap_new_from_buffer (CoglBuffer *buffer, CoglPixelFormat format, int width, @@ -139,7 +141,7 @@ cogl_bitmap_new_from_buffer (CoglBuffer *buffer, * Since: 1.10 * Stability: Unstable */ -CoglBitmap * +COGL_EXPORT CoglBitmap * cogl_bitmap_new_with_size (CoglContext *context, unsigned int width, unsigned int height, @@ -165,7 +167,7 @@ cogl_bitmap_new_with_size (CoglContext *context, * Since: 1.10 * Stability: unstable */ -CoglBitmap * +COGL_EXPORT CoglBitmap * cogl_bitmap_new_for_data (CoglContext *context, int width, int height, @@ -181,7 +183,7 @@ cogl_bitmap_new_for_data (CoglContext *context, * Since: 1.10 * Stability: unstable */ -CoglPixelFormat +COGL_EXPORT CoglPixelFormat cogl_bitmap_get_format (CoglBitmap *bitmap); /** @@ -192,7 +194,7 @@ cogl_bitmap_get_format (CoglBitmap *bitmap); * Since: 1.10 * Stability: unstable */ -int +COGL_EXPORT int cogl_bitmap_get_width (CoglBitmap *bitmap); /** @@ -203,7 +205,7 @@ cogl_bitmap_get_width (CoglBitmap *bitmap); * Since: 1.10 * Stability: unstable */ -int +COGL_EXPORT int cogl_bitmap_get_height (CoglBitmap *bitmap); /** @@ -216,7 +218,7 @@ cogl_bitmap_get_height (CoglBitmap *bitmap); * Since: 1.10 * Stability: unstable */ -int +COGL_EXPORT int cogl_bitmap_get_rowstride (CoglBitmap *bitmap); /** @@ -230,7 +232,7 @@ cogl_bitmap_get_rowstride (CoglBitmap *bitmap); * Stability: unstable * Since: 1.10 */ -CoglPixelBuffer * +COGL_EXPORT CoglPixelBuffer * cogl_bitmap_get_buffer (CoglBitmap *bitmap); /** @@ -246,7 +248,7 @@ cogl_bitmap_get_buffer (CoglBitmap *bitmap); * * Since: 1.0 */ -CoglBool +COGL_EXPORT gboolean cogl_bitmap_get_size_from_file (const char *filename, int *width, int *height); @@ -262,13 +264,13 @@ cogl_bitmap_get_size_from_file (const char *filename, * * Since: 1.0 */ -CoglBool +COGL_EXPORT gboolean cogl_is_bitmap (void *object); /** * COGL_BITMAP_ERROR: * - * #CoglError domain for bitmap errors. + * #GError domain for bitmap errors. * * Since: 1.4 */ @@ -289,14 +291,16 @@ cogl_is_bitmap (void *object); * * Since: 1.4 */ -typedef enum { +typedef enum +{ COGL_BITMAP_ERROR_FAILED, COGL_BITMAP_ERROR_UNKNOWN_TYPE, COGL_BITMAP_ERROR_CORRUPT_IMAGE } CoglBitmapError; +COGL_EXPORT uint32_t cogl_bitmap_error_quark (void); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_BITMAP_H__ */ diff --git a/cogl/cogl/cogl-bitmask.c b/cogl/cogl/cogl-bitmask.c index 7ec84b596..222cc86ea 100644 --- a/cogl/cogl/cogl-bitmask.c +++ b/cogl/cogl/cogl-bitmask.c @@ -56,7 +56,7 @@ _COGL_STATIC_ASSERT (sizeof (unsigned long) <= sizeof (void *), #define BIT_MASK(bit_num) \ (1UL << BIT_INDEX (bit_num)) -CoglBool +gboolean _cogl_bitmask_get_from_array (const CoglBitmask *bitmask, unsigned int bit_num) { @@ -90,7 +90,7 @@ _cogl_bitmask_convert_to_array (CoglBitmask *bitmask) void _cogl_bitmask_set_in_array (CoglBitmask *bitmask, unsigned int bit_num, - CoglBool value) + gboolean value) { GArray *array; unsigned int array_index; @@ -154,7 +154,7 @@ _cogl_bitmask_set_bits (CoglBitmask *dst, void _cogl_bitmask_set_range_in_array (CoglBitmask *bitmask, unsigned int n_bits, - CoglBool value) + gboolean value) { GArray *array; unsigned int array_index, bit_index; @@ -326,7 +326,7 @@ typedef struct int *bits; } CheckData; -static CoglBool +static gboolean check_bit (int bit_num, void *user_data) { CheckData *data = user_data; diff --git a/cogl/cogl/cogl-bitmask.h b/cogl/cogl/cogl-bitmask.h index c8bbbb0c1..7d73db0db 100644 --- a/cogl/cogl/cogl-bitmask.h +++ b/cogl/cogl/cogl-bitmask.h @@ -35,7 +35,7 @@ #include #include "cogl-util.h" -COGL_BEGIN_DECLS +G_BEGIN_DECLS /* * CoglBitmask implements a growable array of bits. A CoglBitmask can @@ -48,7 +48,7 @@ COGL_BEGIN_DECLS * Internally a CoglBitmask is a pointer. If the least significant bit * of the pointer is 1 then the rest of the bits are directly used as * part of the bitmask, otherwise it is a pointer to a GArray of - * unsigned ints. This relies on the fact the malloc will return a + * unsigned ints. This relies on the fact the g_malloc will return a * pointer aligned to at least two bytes (so that the least * significant bit of the address is always 0). It also assumes that * the size of a pointer is always greater than or equal to the size @@ -90,19 +90,19 @@ typedef struct _CoglBitmaskImaginaryType *CoglBitmask; #define _cogl_bitmask_init(bitmask) \ G_STMT_START { *(bitmask) = _cogl_bitmask_from_bits (0); } G_STMT_END -CoglBool +gboolean _cogl_bitmask_get_from_array (const CoglBitmask *bitmask, unsigned int bit_num); void _cogl_bitmask_set_in_array (CoglBitmask *bitmask, unsigned int bit_num, - CoglBool value); + gboolean value); void _cogl_bitmask_set_range_in_array (CoglBitmask *bitmask, unsigned int n_bits, - CoglBool value); + gboolean value); void _cogl_bitmask_clear_all_in_array (CoglBitmask *bitmask); @@ -143,7 +143,7 @@ _cogl_bitmask_xor_bits (CoglBitmask *dst, const CoglBitmask *src); /* The foreach function can return FALSE to stop iteration */ -typedef CoglBool (* CoglBitmaskForeachFunc) (int bit_num, void *user_data); +typedef gboolean (* CoglBitmaskForeachFunc) (int bit_num, void *user_data); /* * cogl_bitmask_foreach: @@ -165,7 +165,7 @@ _cogl_bitmask_foreach (const CoglBitmask *bitmask, * * Return value: whether bit number @bit_num is set in @bitmask */ -static inline CoglBool +static inline gboolean _cogl_bitmask_get (const CoglBitmask *bitmask, unsigned int bit_num) { if (_cogl_bitmask_has_array (bitmask)) @@ -185,7 +185,7 @@ _cogl_bitmask_get (const CoglBitmask *bitmask, unsigned int bit_num) * Sets or resets a bit number @bit_num in @bitmask according to @value. */ static inline void -_cogl_bitmask_set (CoglBitmask *bitmask, unsigned int bit_num, CoglBool value) +_cogl_bitmask_set (CoglBitmask *bitmask, unsigned int bit_num, gboolean value) { if (_cogl_bitmask_has_array (bitmask) || bit_num >= COGL_BITMASK_MAX_DIRECT_BITS) @@ -209,7 +209,7 @@ _cogl_bitmask_set (CoglBitmask *bitmask, unsigned int bit_num, CoglBool value) static inline void _cogl_bitmask_set_range (CoglBitmask *bitmask, unsigned int n_bits, - CoglBool value) + gboolean value) { if (_cogl_bitmask_has_array (bitmask) || n_bits > COGL_BITMASK_MAX_DIRECT_BITS) @@ -307,6 +307,6 @@ _cogl_bitmask_popcount_upto (const CoglBitmask *bitmask, ((1UL << upto) - 1)); } -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_BITMASK_H */ diff --git a/cogl/cogl/cogl-blend-string.c b/cogl/cogl/cogl-blend-string.c index 659152d21..ba8eb8e96 100644 --- a/cogl/cogl/cogl-blend-string.c +++ b/cogl/cogl/cogl-blend-string.c @@ -31,9 +31,7 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include #include @@ -43,7 +41,6 @@ #include "cogl-context-private.h" #include "cogl-debug.h" #include "cogl-blend-string.h" -#include "cogl-error-private.h" typedef enum _ParserState { @@ -165,10 +162,10 @@ _cogl_blend_string_split_rgba_statement (CoglBlendStringStatement *statement, } } -static CoglBool +static gboolean validate_tex_combine_statements (CoglBlendStringStatement *statements, int n_statements, - CoglError **error) + GError **error) { int i, j; const char *error_string; @@ -197,11 +194,8 @@ validate_tex_combine_statements (CoglBlendStringStatement *statements, return TRUE; error: - _cogl_set_error (error, - COGL_BLEND_STRING_ERROR, - detail, - "Invalid texture combine string: %s", - error_string); + g_set_error (error, COGL_BLEND_STRING_ERROR, detail, + "Invalid texture combine string: %s", error_string); if (COGL_DEBUG_ENABLED (COGL_DEBUG_BLEND_STRINGS)) { @@ -211,10 +205,10 @@ validate_tex_combine_statements (CoglBlendStringStatement *statements, return FALSE; } -static CoglBool +static gboolean validate_blend_statements (CoglBlendStringStatement *statements, int n_statements, - CoglError **error) + GError **error) { int i, j; const char *error_string; @@ -222,16 +216,6 @@ validate_blend_statements (CoglBlendStringStatement *statements, _COGL_GET_CONTEXT (ctx, 0); - if (n_statements == 2 && - !ctx->glBlendEquationSeparate && - statements[0].function->type != statements[1].function->type) - { - error_string = "Separate blend functions for the RGB an A " - "channels isn't supported by the driver"; - detail = COGL_BLEND_STRING_ERROR_GPU_UNSUPPORTED_ERROR; - goto error; - } - for (i = 0; i < n_statements; i++) for (j = 0; j < statements[i].function->argc; j++) { @@ -251,35 +235,21 @@ validate_blend_statements (CoglBlendStringStatement *statements, "for arg0 and DST_COLOR for arg1"; goto error; } - - if (!_cogl_has_private_feature (ctx, - COGL_PRIVATE_FEATURE_BLEND_CONSTANT) && - arg->factor.is_color && - (arg->factor.source.info->type == - COGL_BLEND_STRING_COLOR_SOURCE_CONSTANT)) - { - error_string = "Driver doesn't support constant blend factors"; - detail = COGL_BLEND_STRING_ERROR_GPU_UNSUPPORTED_ERROR; - goto error; - } } return TRUE; error: - _cogl_set_error (error, - COGL_BLEND_STRING_ERROR, - detail, - "Invalid blend string: %s", - error_string); + g_set_error (error, COGL_BLEND_STRING_ERROR, detail, + "Invalid blend string: %s", error_string); return FALSE; } -static CoglBool +static gboolean validate_statements_for_context (CoglBlendStringStatement *statements, int n_statements, CoglBlendStringContext context, - CoglError **error) + GError **error) { const char *error_string; @@ -305,13 +275,12 @@ validate_statements_for_context (CoglBlendStringStatement *statements, return validate_tex_combine_statements (statements, n_statements, error); error: - _cogl_set_error (error, - COGL_BLEND_STRING_ERROR, - COGL_BLEND_STRING_ERROR_INVALID_ERROR, - "Invalid %s string: %s", - context == COGL_BLEND_STRING_CONTEXT_BLENDING ? - "blend" : "texture combine", - error_string); + g_set_error (error, COGL_BLEND_STRING_ERROR, + COGL_BLEND_STRING_ERROR_INVALID_ERROR, + "Invalid %s string: %s", + context == COGL_BLEND_STRING_CONTEXT_BLENDING ? + "blend" : "texture combine", + error_string); if (COGL_DEBUG_ENABLED (COGL_DEBUG_BLEND_STRINGS)) { @@ -447,33 +416,33 @@ get_color_src_info (const char *mark, return NULL; } -static CoglBool +static gboolean is_symbol_char (const char c) { return (g_ascii_isalpha (c) || c == '_') ? TRUE : FALSE; } -static CoglBool +static gboolean is_alphanum_char (const char c) { return (g_ascii_isalnum (c) || c == '_') ? TRUE : FALSE; } -static CoglBool +static gboolean parse_argument (const char *string, /* original user string */ const char **ret_p, /* start of argument IN:OUT */ const CoglBlendStringStatement *statement, int current_arg, CoglBlendStringArgument *arg, /* OUT */ CoglBlendStringContext context, - CoglError **error) + GError **error) { const char *p = *ret_p; const char *mark = NULL; const char *error_string = NULL; ParserArgState state = PARSER_ARG_STATE_START; - CoglBool parsing_factor = FALSE; - CoglBool implicit_factor_brace = FALSE; + gboolean parsing_factor = FALSE; + gboolean implicit_factor_brace = FALSE; arg->source.is_zero = FALSE; arg->source.info = NULL; @@ -540,7 +509,7 @@ parse_argument (const char *string, /* original user string */ if (parsing_factor) arg->factor.is_color = TRUE; - /* fall through */ + G_GNUC_FALLTHROUGH; case PARSER_ARG_STATE_SCRAPING_COLOR_SRC_NAME: if (!is_symbol_char (*p)) { @@ -571,7 +540,7 @@ parse_argument (const char *string, /* original user string */ else continue; - /* fall through */ + G_GNUC_FALLTHROUGH; case PARSER_ARG_STATE_MAYBE_COLOR_MASK: if (*p != '[') { @@ -585,7 +554,7 @@ parse_argument (const char *string, /* original user string */ state = PARSER_ARG_STATE_SCRAPING_MASK; mark = p; - /* fall through */ + G_GNUC_FALLTHROUGH; case PARSER_ARG_STATE_SCRAPING_MASK: if (*p == ']') { @@ -718,7 +687,7 @@ parse_argument (const char *string, /* original user string */ arg->factor.is_one = TRUE; state = PARSER_ARG_STATE_EXPECT_END; - /* fall through */ + G_GNUC_FALLTHROUGH; case PARSER_ARG_STATE_EXPECT_END: if (*p != ',' && *p != ')') { @@ -735,13 +704,13 @@ parse_argument (const char *string, /* original user string */ error: { int offset = p - string; - _cogl_set_error (error, - COGL_BLEND_STRING_ERROR, - COGL_BLEND_STRING_ERROR_ARGUMENT_PARSE_ERROR, - "Syntax error for argument %d at offset %d: %s", - current_arg, - offset, - error_string); + g_set_error (error, + COGL_BLEND_STRING_ERROR, + COGL_BLEND_STRING_ERROR_ARGUMENT_PARSE_ERROR, + "Syntax error for argument %d at offset %d: %s", + current_arg, + offset, + error_string); if (COGL_DEBUG_ENABLED (COGL_DEBUG_BLEND_STRINGS)) { @@ -756,7 +725,7 @@ int _cogl_blend_string_compile (const char *string, CoglBlendStringContext context, CoglBlendStringStatement *statements, - CoglError **error) + GError **error) { const char *p = string; const char *mark = NULL; @@ -818,7 +787,7 @@ _cogl_blend_string_compile (const char *string, mark = p; state = PARSER_STATE_SCRAPING_DEST_CHANNELS; - /* fall through */ + G_GNUC_FALLTHROUGH; case PARSER_STATE_SCRAPING_DEST_CHANNELS: if (*p != '=') continue; @@ -841,7 +810,7 @@ _cogl_blend_string_compile (const char *string, mark = p; state = PARSER_STATE_SCRAPING_FUNCTION_NAME; - /* fall through */ + G_GNUC_FALLTHROUGH; case PARSER_STATE_SCRAPING_FUNCTION_NAME: if (*p != '(') { @@ -863,7 +832,7 @@ _cogl_blend_string_compile (const char *string, current_arg = 0; state = PARSER_STATE_EXPECT_ARG_START; - /* fall through */ + G_GNUC_FALLTHROUGH; case PARSER_STATE_EXPECT_ARG_START: if (*p != '(' && *p != ',') continue; @@ -916,12 +885,12 @@ _cogl_blend_string_compile (const char *string, error: { int offset = p - string; - _cogl_set_error (error, - COGL_BLEND_STRING_ERROR, - COGL_BLEND_STRING_ERROR_PARSE_ERROR, - "Syntax error at offset %d: %s", - offset, - error_string); + g_set_error (error, + COGL_BLEND_STRING_ERROR, + COGL_BLEND_STRING_ERROR_PARSE_ERROR, + "Syntax error at offset %d: %s", + offset, + error_string); if (COGL_DEBUG_ENABLED (COGL_DEBUG_BLEND_STRINGS)) { @@ -973,7 +942,7 @@ _cogl_blend_string_test (void) }; int i; - CoglError *error = NULL; + GError *error = NULL; for (i = 0; strings[i].string; i++) { CoglBlendStringStatement statements[2]; @@ -986,7 +955,7 @@ _cogl_blend_string_test (void) g_print ("Failed to parse string:\n%s\n%s\n", strings[i].string, error->message); - cogl_error_free (error); + g_error_free (error); error = NULL; continue; } diff --git a/cogl/cogl/cogl-blend-string.h b/cogl/cogl/cogl-blend-string.h index 355338c61..8333abad4 100644 --- a/cogl/cogl/cogl-blend-string.h +++ b/cogl/cogl/cogl-blend-string.h @@ -77,18 +77,18 @@ typedef struct _CoglBlendStringColorSourceInfo typedef struct _CoglBlendStringColorSource { - CoglBool is_zero; + gboolean is_zero; const CoglBlendStringColorSourceInfo *info; int texture; /* for the TEXTURE_N color source */ - CoglBool one_minus; + gboolean one_minus; CoglBlendStringChannelMask mask; } CoglBlendStringColorSource; typedef struct _CoglBlendStringFactor { - CoglBool is_one; - CoglBool is_src_alpha_saturate; - CoglBool is_color; + gboolean is_one; + gboolean is_src_alpha_saturate; + gboolean is_color; CoglBlendStringColorSource source; } CoglBlendStringFactor; @@ -129,11 +129,11 @@ typedef struct _CoglBlendStringStatement } CoglBlendStringStatement; -CoglBool +gboolean _cogl_blend_string_compile (const char *string, CoglBlendStringContext context, CoglBlendStringStatement *statements, - CoglError **error); + GError **error); void _cogl_blend_string_split_rgba_statement (CoglBlendStringStatement *statement, diff --git a/cogl/cogl/cogl-blit.c b/cogl/cogl/cogl-blit.c index a9b6306e0..0946f26d0 100644 --- a/cogl/cogl/cogl-blit.c +++ b/cogl/cogl/cogl-blit.c @@ -4,6 +4,7 @@ * A Low Level GPU Graphics and Utilities API * * Copyright (C) 2011 Intel Corporation. + * Copyright (C) 2019 DisplayLink (UK) Ltd. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -29,9 +30,7 @@ * Neil Roberts */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include @@ -46,7 +45,7 @@ static const CoglBlitMode *_cogl_blit_default_mode = NULL; -static CoglBool +static gboolean _cogl_blit_texture_render_begin (CoglBlitData *data) { CoglContext *ctx = data->src_tex->context; @@ -54,7 +53,7 @@ _cogl_blit_texture_render_begin (CoglBlitData *data) CoglFramebuffer *fb; CoglPipeline *pipeline; unsigned int dst_width, dst_height; - CoglError *ignore_error = NULL; + GError *ignore_error = NULL; offscreen = _cogl_offscreen_new_with_texture_full (data->dst_tex, COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL, 0 /* level */); @@ -62,7 +61,7 @@ _cogl_blit_texture_render_begin (CoglBlitData *data) fb = COGL_FRAMEBUFFER (offscreen); if (!cogl_framebuffer_allocate (fb, &ignore_error)) { - cogl_error_free (ignore_error); + g_error_free (ignore_error); cogl_object_unref (fb); return FALSE; } @@ -146,19 +145,20 @@ _cogl_blit_texture_render_end (CoglBlitData *data) cogl_object_unref (data->dest_fb); } -static CoglBool +static gboolean _cogl_blit_framebuffer_begin (CoglBlitData *data) { CoglContext *ctx = data->src_tex->context; CoglOffscreen *dst_offscreen = NULL, *src_offscreen = NULL; CoglFramebuffer *dst_fb, *src_fb; - CoglError *ignore_error = NULL; - - /* We can only blit between FBOs if both textures are the same - format and the blit framebuffer extension is supported */ - if ((_cogl_texture_get_format (data->src_tex) & ~COGL_A_BIT) != - (_cogl_texture_get_format (data->dst_tex) & ~COGL_A_BIT) || - !_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT)) + GError *ignore_error = NULL; + + /* We can only blit between FBOs if both textures have the same + premult convention and the blit framebuffer extension is + supported. */ + if ((_cogl_texture_get_format (data->src_tex) & COGL_PREMULT_BIT) != + (_cogl_texture_get_format (data->dst_tex) & COGL_PREMULT_BIT) || + !_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER)) return FALSE; dst_offscreen = _cogl_offscreen_new_with_texture_full @@ -167,7 +167,7 @@ _cogl_blit_framebuffer_begin (CoglBlitData *data) dst_fb = COGL_FRAMEBUFFER (dst_offscreen); if (!cogl_framebuffer_allocate (dst_fb, &ignore_error)) { - cogl_error_free (ignore_error); + g_error_free (ignore_error); goto error; } @@ -179,7 +179,7 @@ _cogl_blit_framebuffer_begin (CoglBlitData *data) src_fb = COGL_FRAMEBUFFER (src_offscreen); if (!cogl_framebuffer_allocate (src_fb, &ignore_error)) { - cogl_error_free (ignore_error); + g_error_free (ignore_error); goto error; } @@ -207,11 +207,12 @@ _cogl_blit_framebuffer_blit (CoglBlitData *data, int width, int height) { - _cogl_blit_framebuffer (data->src_fb, - data->dest_fb, - src_x, src_y, - dst_x, dst_y, - width, height); + cogl_blit_framebuffer (data->src_fb, + data->dest_fb, + src_x, src_y, + dst_x, dst_y, + width, height, + NULL); } static void @@ -221,12 +222,12 @@ _cogl_blit_framebuffer_end (CoglBlitData *data) cogl_object_unref (data->dest_fb); } -static CoglBool +static gboolean _cogl_blit_copy_tex_sub_image_begin (CoglBlitData *data) { CoglOffscreen *offscreen; CoglFramebuffer *fb; - CoglError *ignore_error = NULL; + GError *ignore_error = NULL; /* This will only work if the target texture is a CoglTexture2D */ if (!cogl_is_texture_2d (data->dst_tex)) @@ -238,7 +239,7 @@ _cogl_blit_copy_tex_sub_image_begin (CoglBlitData *data) fb = COGL_FRAMEBUFFER (offscreen); if (!cogl_framebuffer_allocate (fb, &ignore_error)) { - cogl_error_free (ignore_error); + g_error_free (ignore_error); cogl_object_unref (fb); return FALSE; } @@ -271,13 +272,17 @@ _cogl_blit_copy_tex_sub_image_end (CoglBlitData *data) cogl_object_unref (data->src_fb); } -static CoglBool +static gboolean _cogl_blit_get_tex_data_begin (CoglBlitData *data) { data->format = _cogl_texture_get_format (data->src_tex); - data->bpp = _cogl_pixel_format_get_bytes_per_pixel (data->format); - data->image_data = malloc (data->bpp * data->src_width * + g_return_val_if_fail (cogl_pixel_format_get_n_planes (data->format) == 1, + FALSE); + + data->bpp = cogl_pixel_format_get_bytes_per_pixel (data->format, 0); + + data->image_data = g_malloc (data->bpp * data->src_width * data->src_height); cogl_texture_get_data (data->src_tex, data->format, data->src_width * data->bpp, data->image_data); @@ -294,7 +299,7 @@ _cogl_blit_get_tex_data_blit (CoglBlitData *data, int width, int height) { - CoglError *ignore = NULL; + GError *ignore = NULL; int rowstride = data->src_width * data->bpp; int offset = rowstride * src_y + src_x * data->bpp; @@ -312,7 +317,7 @@ _cogl_blit_get_tex_data_blit (CoglBlitData *data, static void _cogl_blit_get_tex_data_end (CoglBlitData *data) { - free (data->image_data); + g_free (data->image_data); } /* These should be specified in order of preference */ @@ -411,7 +416,7 @@ _cogl_blit_begin (CoglBlitData *data, _cogl_blit_modes[i].name); /* The last blit mode can't fail so this should never happen */ - _COGL_RETURN_IF_FAIL (i < G_N_ELEMENTS (_cogl_blit_modes)); + g_return_if_fail (i < G_N_ELEMENTS (_cogl_blit_modes)); } data->blit_mode = _cogl_blit_default_mode; diff --git a/cogl/cogl/cogl-blit.h b/cogl/cogl/cogl-blit.h index d7776524b..d3e0da233 100644 --- a/cogl/cogl/cogl-blit.h +++ b/cogl/cogl/cogl-blit.h @@ -41,7 +41,7 @@ typedef struct _CoglBlitData CoglBlitData; -typedef CoglBool (* CoglBlitBeginFunc) (CoglBlitData *data); +typedef gboolean (* CoglBlitBeginFunc) (CoglBlitData *data); typedef void (* CoglBlitEndFunc) (CoglBlitData *data); typedef void (* CoglBlitFunc) (CoglBlitData *data, @@ -69,7 +69,7 @@ struct _CoglBlitData const CoglBlitMode *blit_mode; - /* If we're not using an FBO then we malloc a buffer and copy the + /* If we're not using an FBO then we g_malloc a buffer and copy the complete texture data in */ unsigned char *image_data; CoglPixelFormat format; diff --git a/cogl/cogl/cogl-boxed-value.c b/cogl/cogl/cogl-boxed-value.c index a0d826363..7d55231c0 100644 --- a/cogl/cogl/cogl-boxed-value.c +++ b/cogl/cogl/cogl-boxed-value.c @@ -28,17 +28,15 @@ * */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include #include "cogl-boxed-value.h" #include "cogl-context-private.h" -#include "cogl-util-gl-private.h" +#include "driver/gl/cogl-util-gl-private.h" -CoglBool +gboolean _cogl_boxed_value_equal (const CoglBoxedValue *bva, const CoglBoxedValue *bvb) { @@ -136,12 +134,12 @@ _cogl_boxed_value_set_x (CoglBoxedValue *bv, CoglBoxedType type, size_t value_size, const void *value, - CoglBool transpose) + gboolean transpose) { if (count == 1) { if (bv->count > 1) - free (bv->v.array); + g_free (bv->v.array); if (transpose) _cogl_boxed_value_tranpose (bv->v.float_value, @@ -158,12 +156,12 @@ _cogl_boxed_value_set_x (CoglBoxedValue *bv, bv->size != size || bv->type != type) { - free (bv->v.array); - bv->v.array = malloc (count * value_size); + g_free (bv->v.array); + bv->v.array = g_malloc (count * value_size); } } else - bv->v.array = malloc (count * value_size); + bv->v.array = g_malloc (count * value_size); if (transpose) { @@ -231,7 +229,7 @@ void _cogl_boxed_value_set_matrix (CoglBoxedValue *bv, int dimensions, int count, - CoglBool transpose, + gboolean transpose, const float *value) { _cogl_boxed_value_set_x (bv, @@ -280,7 +278,7 @@ void _cogl_boxed_value_destroy (CoglBoxedValue *bv) { if (bv->count > 1) - free (bv->v.array); + g_free (bv->v.array); } void diff --git a/cogl/cogl/cogl-boxed-value.h b/cogl/cogl/cogl-boxed-value.h index c8eda44dd..962c13387 100644 --- a/cogl/cogl/cogl-boxed-value.h +++ b/cogl/cogl/cogl-boxed-value.h @@ -35,7 +35,8 @@ #include "cogl-context.h" -typedef enum { +typedef enum +{ COGL_BOXED_NONE, COGL_BOXED_INT, COGL_BOXED_FLOAT, @@ -64,7 +65,7 @@ typedef struct _CoglBoxedValue _bv->count = 1; \ } G_STMT_END -CoglBool +gboolean _cogl_boxed_value_equal (const CoglBoxedValue *bva, const CoglBoxedValue *bvb); @@ -92,7 +93,7 @@ void _cogl_boxed_value_set_matrix (CoglBoxedValue *bv, int dimensions, int count, - CoglBool transpose, + gboolean transpose, const float *value); /* diff --git a/cogl/cogl/cogl-buffer-private.h b/cogl/cogl/cogl-buffer-private.h index eab81fda4..1e8113838 100644 --- a/cogl/cogl/cogl-buffer-private.h +++ b/cogl/cogl/cogl-buffer-private.h @@ -42,7 +42,7 @@ #include "cogl-context.h" #include "cogl-gl-header.h" -COGL_BEGIN_DECLS +G_BEGIN_DECLS typedef struct _CoglBufferVtable CoglBufferVtable; @@ -53,15 +53,15 @@ struct _CoglBufferVtable size_t size, CoglBufferAccess access, CoglBufferMapHint hints, - CoglError **error); + GError **error); void (* unmap) (CoglBuffer *buffer); - CoglBool (* set_data) (CoglBuffer *buffer, + gboolean (* set_data) (CoglBuffer *buffer, unsigned int offset, const void *data, unsigned int size, - CoglError **error); + GError **error); }; typedef enum _CoglBufferFlags @@ -72,13 +72,15 @@ typedef enum _CoglBufferFlags COGL_BUFFER_FLAG_MAPPED_FALLBACK = 1UL << 2 } CoglBufferFlags; -typedef enum { +typedef enum +{ COGL_BUFFER_USAGE_HINT_TEXTURE, COGL_BUFFER_USAGE_HINT_ATTRIBUTE_BUFFER, COGL_BUFFER_USAGE_HINT_INDEX_BUFFER } CoglBufferUsageHint; -typedef enum { +typedef enum +{ COGL_BUFFER_BIND_TARGET_PIXEL_PACK, COGL_BUFFER_BIND_TARGET_PIXEL_UNPACK, COGL_BUFFER_BIND_TARGET_ATTRIBUTE_BUFFER, @@ -137,27 +139,24 @@ _cogl_buffer_fini (CoglBuffer *buffer); CoglBufferUsageHint _cogl_buffer_get_usage_hint (CoglBuffer *buffer); -GLenum -_cogl_buffer_access_to_gl_enum (CoglBufferAccess access); - CoglBuffer * _cogl_buffer_immutable_ref (CoglBuffer *buffer); void _cogl_buffer_immutable_unref (CoglBuffer *buffer); -CoglBool +gboolean _cogl_buffer_set_data (CoglBuffer *buffer, size_t offset, const void *data, size_t size, - CoglError **error); + GError **error); void * _cogl_buffer_map (CoglBuffer *buffer, CoglBufferAccess access, CoglBufferMapHint hints, - CoglError **error); + GError **error); /* This is a wrapper around cogl_buffer_map_range for internal use when we want to map the buffer for write only to replace the entire @@ -169,12 +168,12 @@ void * _cogl_buffer_map_range_for_fill_or_fallback (CoglBuffer *buffer, size_t offset, size_t size); -void * +COGL_EXPORT void * _cogl_buffer_map_for_fill_or_fallback (CoglBuffer *buffer); -void +COGL_EXPORT void _cogl_buffer_unmap_for_fill_or_fallback (CoglBuffer *buffer); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_BUFFER_PRIVATE_H__ */ diff --git a/cogl/cogl/cogl-buffer.c b/cogl/cogl/cogl-buffer.c index 4bae88f93..dd7d8cb18 100644 --- a/cogl/cogl/cogl-buffer.c +++ b/cogl/cogl/cogl-buffer.c @@ -37,9 +37,7 @@ * Pixel Buffers API. */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include #include @@ -64,7 +62,7 @@ _cogl_buffer_register_buffer_type (const CoglObjectClass *klass) _cogl_buffer_types = g_slist_prepend (_cogl_buffer_types, (void *) klass); } -CoglBool +gboolean cogl_is_buffer (void *object) { const CoglObject *obj = object; @@ -90,7 +88,7 @@ malloc_map_range (CoglBuffer *buffer, size_t size, CoglBufferAccess access, CoglBufferMapHint hints, - CoglError **error) + GError **error) { buffer->flags |= COGL_BUFFER_FLAG_MAPPED; return buffer->data + offset; @@ -102,12 +100,12 @@ malloc_unmap (CoglBuffer *buffer) buffer->flags &= ~COGL_BUFFER_FLAG_MAPPED; } -static CoglBool +static gboolean malloc_set_data (CoglBuffer *buffer, unsigned int offset, const void *data, unsigned int size, - CoglError **error) + GError **error) { memcpy (buffer->data + offset, data, size); return TRUE; @@ -121,7 +119,7 @@ _cogl_buffer_initialize (CoglBuffer *buffer, CoglBufferUsageHint usage_hint, CoglBufferUpdateHint update_hint) { - CoglBool use_malloc = FALSE; + gboolean use_malloc = FALSE; buffer->context = ctx; buffer->flags = COGL_BUFFER_FLAG_NONE; @@ -139,12 +137,6 @@ _cogl_buffer_initialize (CoglBuffer *buffer, if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_PBOS)) use_malloc = TRUE; } - else if (default_target == COGL_BUFFER_BIND_TARGET_ATTRIBUTE_BUFFER || - default_target == COGL_BUFFER_BIND_TARGET_INDEX_BUFFER) - { - if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_VBOS)) - use_malloc = TRUE; - } if (use_malloc) { @@ -152,7 +144,7 @@ _cogl_buffer_initialize (CoglBuffer *buffer, buffer->vtable.unmap = malloc_unmap; buffer->vtable.set_data = malloc_set_data; - buffer->data = malloc (size); + buffer->data = g_malloc (size); } else { @@ -169,13 +161,13 @@ _cogl_buffer_initialize (CoglBuffer *buffer, void _cogl_buffer_fini (CoglBuffer *buffer) { - _COGL_RETURN_IF_FAIL (!(buffer->flags & COGL_BUFFER_FLAG_MAPPED)); - _COGL_RETURN_IF_FAIL (buffer->immutable_ref == 0); + g_return_if_fail (!(buffer->flags & COGL_BUFFER_FLAG_MAPPED)); + g_return_if_fail (buffer->immutable_ref == 0); if (buffer->flags & COGL_BUFFER_FLAG_BUFFER_OBJECT) buffer->context->driver_vtable->buffer_destroy (buffer); else - free (buffer->data); + g_free (buffer->data); } unsigned int @@ -212,7 +204,7 @@ cogl_buffer_get_update_hint (CoglBuffer *buffer) static void warn_about_midscene_changes (void) { - static CoglBool seen = FALSE; + static gboolean seen = FALSE; if (!seen) { g_warning ("Mid-scene modification of buffers has " @@ -225,9 +217,9 @@ void * _cogl_buffer_map (CoglBuffer *buffer, CoglBufferAccess access, CoglBufferMapHint hints, - CoglError **error) + GError **error) { - _COGL_RETURN_VAL_IF_FAIL (cogl_is_buffer (buffer), NULL); + g_return_val_if_fail (cogl_is_buffer (buffer), NULL); return cogl_buffer_map_range (buffer, 0, buffer->size, access, hints, error); } @@ -237,12 +229,11 @@ cogl_buffer_map (CoglBuffer *buffer, CoglBufferAccess access, CoglBufferMapHint hints) { - CoglError *ignore_error = NULL; + GError *ignore_error = NULL; void *ptr = cogl_buffer_map_range (buffer, 0, buffer->size, access, hints, &ignore_error); - if (!ptr) - cogl_error_free (ignore_error); + g_clear_error (&ignore_error); return ptr; } @@ -252,10 +243,10 @@ cogl_buffer_map_range (CoglBuffer *buffer, size_t size, CoglBufferAccess access, CoglBufferMapHint hints, - CoglError **error) + GError **error) { - _COGL_RETURN_VAL_IF_FAIL (cogl_is_buffer (buffer), NULL); - _COGL_RETURN_VAL_IF_FAIL (!(buffer->flags & COGL_BUFFER_FLAG_MAPPED), NULL); + g_return_val_if_fail (cogl_is_buffer (buffer), NULL); + g_return_val_if_fail (!(buffer->flags & COGL_BUFFER_FLAG_MAPPED), NULL); if (G_UNLIKELY (buffer->immutable_ref)) warn_about_midscene_changes (); @@ -295,9 +286,9 @@ _cogl_buffer_map_range_for_fill_or_fallback (CoglBuffer *buffer, { CoglContext *ctx = buffer->context; void *ret; - CoglError *ignore_error = NULL; + GError *ignore_error = NULL; - _COGL_RETURN_VAL_IF_FAIL (!ctx->buffer_map_fallback_in_use, NULL); + g_return_val_if_fail (!ctx->buffer_map_fallback_in_use, NULL); ctx->buffer_map_fallback_in_use = TRUE; @@ -311,7 +302,7 @@ _cogl_buffer_map_range_for_fill_or_fallback (CoglBuffer *buffer, if (ret) return ret; - cogl_error_free (ignore_error); + g_error_free (ignore_error); /* If the map fails then we'll use a temporary buffer to fill the data and then upload it using cogl_buffer_set_data when @@ -330,7 +321,7 @@ _cogl_buffer_unmap_for_fill_or_fallback (CoglBuffer *buffer) { CoglContext *ctx = buffer->context; - _COGL_RETURN_IF_FAIL (ctx->buffer_map_fallback_in_use); + g_return_if_fail (ctx->buffer_map_fallback_in_use); ctx->buffer_map_fallback_in_use = FALSE; @@ -361,15 +352,15 @@ _cogl_buffer_unmap_for_fill_or_fallback (CoglBuffer *buffer) cogl_buffer_unmap (buffer); } -CoglBool +gboolean _cogl_buffer_set_data (CoglBuffer *buffer, size_t offset, const void *data, size_t size, - CoglError **error) + GError **error) { - _COGL_RETURN_VAL_IF_FAIL (cogl_is_buffer (buffer), FALSE); - _COGL_RETURN_VAL_IF_FAIL ((offset + size) <= buffer->size, FALSE); + g_return_val_if_fail (cogl_is_buffer (buffer), FALSE); + g_return_val_if_fail ((offset + size) <= buffer->size, FALSE); if (G_UNLIKELY (buffer->immutable_ref)) warn_about_midscene_changes (); @@ -377,24 +368,23 @@ _cogl_buffer_set_data (CoglBuffer *buffer, return buffer->vtable.set_data (buffer, offset, data, size, error); } -CoglBool +gboolean cogl_buffer_set_data (CoglBuffer *buffer, size_t offset, const void *data, size_t size) { - CoglError *ignore_error = NULL; - CoglBool status = + GError *ignore_error = NULL; + gboolean status = _cogl_buffer_set_data (buffer, offset, data, size, &ignore_error); - if (!status) - cogl_error_free (ignore_error); + g_clear_error (&ignore_error); return status; } CoglBuffer * _cogl_buffer_immutable_ref (CoglBuffer *buffer) { - _COGL_RETURN_VAL_IF_FAIL (cogl_is_buffer (buffer), NULL); + g_return_val_if_fail (cogl_is_buffer (buffer), NULL); buffer->immutable_ref++; return buffer; @@ -403,8 +393,8 @@ _cogl_buffer_immutable_ref (CoglBuffer *buffer) void _cogl_buffer_immutable_unref (CoglBuffer *buffer) { - _COGL_RETURN_IF_FAIL (cogl_is_buffer (buffer)); - _COGL_RETURN_IF_FAIL (buffer->immutable_ref > 0); + g_return_if_fail (cogl_is_buffer (buffer)); + g_return_if_fail (buffer->immutable_ref > 0); buffer->immutable_ref--; } diff --git a/cogl/cogl/cogl-buffer.h b/cogl/cogl/cogl-buffer.h index 428b5b30a..4dc1f5744 100644 --- a/cogl/cogl/cogl-buffer.h +++ b/cogl/cogl/cogl-buffer.h @@ -40,9 +40,8 @@ #define __COGL_BUFFER_H__ #include -#include -COGL_BEGIN_DECLS +G_BEGIN_DECLS /** * SECTION:cogl-buffer @@ -66,7 +65,7 @@ COGL_BEGIN_DECLS * without blocking other Cogl operations. */ -#if defined(__COGL_H_INSIDE__) && !defined(COGL_ENABLE_MUFFIN_API) && \ +#if defined(__COGL_H_INSIDE__) && !defined(COGL_ENABLE_MUTTER_API) && \ !defined(COGL_GIR_SCANNING) /* For the public C api we typedef interface types as void to avoid needing * lots of casting in code and instead we will rely on runtime type checking @@ -89,7 +88,8 @@ typedef struct _CoglBuffer CoglBuffer; * * Stability: unstable */ -typedef enum { /*< prefix=COGL_BUFFER_ERROR >*/ +typedef enum /*< prefix=COGL_BUFFER_ERROR >*/ +{ COGL_BUFFER_ERROR_MAP } CoglBufferError; @@ -107,7 +107,7 @@ _cogl_buffer_error_domain (void); * Since: 1.2 * Stability: unstable */ -CoglBool +COGL_EXPORT gboolean cogl_is_buffer (void *object); /** @@ -121,7 +121,7 @@ cogl_is_buffer (void *object); * Since: 1.2 * Stability: unstable */ -unsigned int +COGL_EXPORT unsigned int cogl_buffer_get_size (CoglBuffer *buffer); /** @@ -137,7 +137,8 @@ cogl_buffer_get_size (CoglBuffer *buffer); * Since: 1.2 * Stability: unstable */ -typedef enum { /*< prefix=COGL_BUFFER_UPDATE_HINT >*/ +typedef enum /*< prefix=COGL_BUFFER_UPDATE_HINT >*/ +{ COGL_BUFFER_UPDATE_HINT_STATIC, COGL_BUFFER_UPDATE_HINT_DYNAMIC, COGL_BUFFER_UPDATE_HINT_STREAM @@ -154,7 +155,7 @@ typedef enum { /*< prefix=COGL_BUFFER_UPDATE_HINT >*/ * Since: 1.2 * Stability: unstable */ -void +COGL_EXPORT void cogl_buffer_set_update_hint (CoglBuffer *buffer, CoglBufferUpdateHint hint); @@ -169,7 +170,7 @@ cogl_buffer_set_update_hint (CoglBuffer *buffer, * Since: 1.2 * Stability: unstable */ -CoglBufferUpdateHint +COGL_EXPORT CoglBufferUpdateHint cogl_buffer_get_update_hint (CoglBuffer *buffer); /** @@ -184,7 +185,8 @@ cogl_buffer_get_update_hint (CoglBuffer *buffer); * Since: 1.2 * Stability: unstable */ -typedef enum { /*< prefix=COGL_BUFFER_ACCESS >*/ +typedef enum /*< prefix=COGL_BUFFER_ACCESS >*/ +{ COGL_BUFFER_ACCESS_READ = 1 << 0, COGL_BUFFER_ACCESS_WRITE = 1 << 1, COGL_BUFFER_ACCESS_READ_WRITE = COGL_BUFFER_ACCESS_READ | COGL_BUFFER_ACCESS_WRITE @@ -208,7 +210,8 @@ typedef enum { /*< prefix=COGL_BUFFER_ACCESS >*/ * Since: 1.4 * Stability: unstable */ -typedef enum { /*< prefix=COGL_BUFFER_MAP_HINT >*/ +typedef enum /*< prefix=COGL_BUFFER_MAP_HINT >*/ +{ COGL_BUFFER_MAP_HINT_DISCARD = 1 << 0, COGL_BUFFER_MAP_HINT_DISCARD_RANGE = 1 << 1 } CoglBufferMapHint; @@ -241,7 +244,7 @@ typedef enum { /*< prefix=COGL_BUFFER_MAP_HINT >*/ * Since: 1.2 * Stability: unstable */ -void * +COGL_EXPORT void * cogl_buffer_map (CoglBuffer *buffer, CoglBufferAccess access, CoglBufferMapHint hints); @@ -254,7 +257,7 @@ cogl_buffer_map (CoglBuffer *buffer, * @access: how the mapped buffer will be used by the application * @hints: A mask of #CoglBufferMapHints that tell Cogl how * the data will be modified once mapped. - * @error: A #CoglError for catching exceptional errors + * @error: A #GError for catching exceptional errors * * Maps a sub-region of the buffer into the application's address space * for direct access. @@ -278,13 +281,13 @@ cogl_buffer_map (CoglBuffer *buffer, * Since: 2.0 * Stability: unstable */ -void * +COGL_EXPORT void * cogl_buffer_map_range (CoglBuffer *buffer, size_t offset, size_t size, CoglBufferAccess access, CoglBufferMapHint hints, - CoglError **error); + GError **error); /** * cogl_buffer_unmap: @@ -295,7 +298,7 @@ cogl_buffer_map_range (CoglBuffer *buffer, * Since: 1.2 * Stability: unstable */ -void +COGL_EXPORT void cogl_buffer_unmap (CoglBuffer *buffer); /** @@ -314,12 +317,12 @@ cogl_buffer_unmap (CoglBuffer *buffer); * Since: 1.2 * Stability: unstable */ -CoglBool +COGL_EXPORT gboolean cogl_buffer_set_data (CoglBuffer *buffer, size_t offset, const void *data, size_t size); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_BUFFER_H__ */ diff --git a/cogl/cogl/cogl-clip-stack.c b/cogl/cogl/cogl-clip-stack.c index 128b1bc85..aa3172e2e 100644 --- a/cogl/cogl/cogl-clip-stack.c +++ b/cogl/cogl/cogl-clip-stack.c @@ -28,9 +28,7 @@ * */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include #include @@ -38,7 +36,6 @@ #include #include "cogl-clip-stack.h" -#include "cogl-primitives.h" #include "cogl-context-private.h" #include "cogl-framebuffer-private.h" #include "cogl-journal-private.h" @@ -46,15 +43,12 @@ #include "cogl-matrix-private.h" #include "cogl-primitives-private.h" #include "cogl-private.h" -#include "cogl-pipeline-opengl-private.h" #include "cogl-attribute-private.h" #include "cogl-primitive-private.h" #include "cogl1-context.h" #include "cogl-offscreen.h" #include "cogl-matrix-stack.h" - - static void * _cogl_clip_stack_push_entry (CoglClipStack *clip_stack, size_t size, @@ -300,6 +294,30 @@ _cogl_clip_stack_push_primitive (CoglClipStack *stack, return (CoglClipStack *) entry; } +CoglClipStack * +cogl_clip_stack_push_region (CoglClipStack *stack, + cairo_region_t *region) +{ + CoglClipStack *entry; + CoglClipStackRegion *entry_region; + cairo_rectangle_int_t bounds; + + entry_region = _cogl_clip_stack_push_entry (stack, + sizeof (CoglClipStackRegion), + COGL_CLIP_STACK_REGION); + entry = (CoglClipStack *) entry_region; + + cairo_region_get_extents (region, &bounds); + entry->bounds_x0 = bounds.x; + entry->bounds_x1 = bounds.x + bounds.width; + entry->bounds_y0 = bounds.y; + entry->bounds_y1 = bounds.y + bounds.height; + + entry_region->region = cairo_region_reference (region); + + return entry; +} + CoglClipStack * _cogl_clip_stack_ref (CoglClipStack *entry) { @@ -341,6 +359,13 @@ _cogl_clip_stack_unref (CoglClipStack *entry) g_slice_free1 (sizeof (CoglClipStackPrimitive), entry); break; } + case COGL_CLIP_STACK_REGION: + { + CoglClipStackRegion *region = (CoglClipStackRegion *) entry; + cairo_region_destroy (region->region); + g_slice_free1 (sizeof (CoglClipStackRegion), entry); + break; + } default: g_assert_not_reached (); } @@ -354,7 +379,7 @@ _cogl_clip_stack_pop (CoglClipStack *stack) { CoglClipStack *new_top; - _COGL_RETURN_VAL_IF_FAIL (stack != NULL, NULL); + g_return_val_if_fail (stack != NULL, NULL); /* To pop we are moving the top of the stack to the old top's parent node. The stack always needs to have a reference to the top entry diff --git a/cogl/cogl/cogl-clip-stack.h b/cogl/cogl/cogl-clip-stack.h index 56bc3f805..62d65bcd3 100644 --- a/cogl/cogl/cogl-clip-stack.h +++ b/cogl/cogl/cogl-clip-stack.h @@ -48,12 +48,14 @@ typedef struct _CoglClipStack CoglClipStack; typedef struct _CoglClipStackRect CoglClipStackRect; typedef struct _CoglClipStackWindowRect CoglClipStackWindowRect; typedef struct _CoglClipStackPrimitive CoglClipStackPrimitive; +typedef struct _CoglClipStackRegion CoglClipStackRegion; typedef enum { COGL_CLIP_STACK_RECT, COGL_CLIP_STACK_WINDOW_RECT, - COGL_CLIP_STACK_PRIMITIVE + COGL_CLIP_STACK_PRIMITIVE, + COGL_CLIP_STACK_REGION, } CoglClipStackType; /* A clip stack consists a list of entries. Each entry has a reference @@ -136,7 +138,7 @@ struct _CoglClipStackRect modelview matrix is that same as when a rectangle is added to the journal. In that case we can use the original clip coordinates and modify the rectangle instead. */ - CoglBool can_be_scissor; + gboolean can_be_scissor; }; struct _CoglClipStackWindowRect @@ -162,6 +164,13 @@ struct _CoglClipStackPrimitive float bounds_y2; }; +struct _CoglClipStackRegion +{ + CoglClipStack _parent_data; + + cairo_region_t *region; +}; + CoglClipStack * _cogl_clip_stack_push_window_rectangle (CoglClipStack *stack, int x_offset, @@ -169,7 +178,7 @@ _cogl_clip_stack_push_window_rectangle (CoglClipStack *stack, int width, int height); -CoglClipStack * +COGL_EXPORT CoglClipStack * _cogl_clip_stack_push_rectangle (CoglClipStack *stack, float x_1, float y_1, @@ -179,7 +188,7 @@ _cogl_clip_stack_push_rectangle (CoglClipStack *stack, CoglMatrixEntry *projection_entry, const float *viewport); -CoglClipStack * +COGL_EXPORT CoglClipStack * _cogl_clip_stack_push_primitive (CoglClipStack *stack, CoglPrimitive *primitive, float bounds_x1, @@ -189,6 +198,9 @@ _cogl_clip_stack_push_primitive (CoglClipStack *stack, CoglMatrixEntry *modelview_entry, CoglMatrixEntry *projection_entry, const float *viewport); +CoglClipStack * +cogl_clip_stack_push_region (CoglClipStack *stack, + cairo_region_t *region); CoglClipStack * _cogl_clip_stack_pop (CoglClipStack *stack); diff --git a/cogl/cogl/cogl-closure-list-private.h b/cogl/cogl/cogl-closure-list-private.h index 5446cb207..f4b829ba7 100644 --- a/cogl/cogl/cogl-closure-list-private.h +++ b/cogl/cogl/cogl-closure-list-private.h @@ -65,7 +65,7 @@ typedef struct _CoglClosure * Removes the given closure from the callback list it is connected to * and destroys it. If the closure was created with a destroy function * then it will be invoked. */ -void +COGL_EXPORT void _cogl_closure_disconnect (CoglClosure *closure); void diff --git a/cogl/cogl/cogl-color.c b/cogl/cogl/cogl-color.c index 631ec4a9a..75cf829bd 100644 --- a/cogl/cogl/cogl-color.c +++ b/cogl/cogl/cogl-color.c @@ -28,9 +28,7 @@ * */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include @@ -70,7 +68,7 @@ cogl_color_init_from_4ub (CoglColor *color, uint8_t blue, uint8_t alpha) { - _COGL_RETURN_IF_FAIL (color != NULL); + g_return_if_fail (color != NULL); color->red = red; color->green = green; @@ -78,17 +76,6 @@ cogl_color_init_from_4ub (CoglColor *color, color->alpha = alpha; } -/* XXX: deprecated, use cogl_color_init_from_4ub */ -void -cogl_color_set_from_4ub (CoglColor *dest, - uint8_t red, - uint8_t green, - uint8_t blue, - uint8_t alpha) -{ - cogl_color_init_from_4ub (dest, red, green, blue, alpha); -} - void cogl_color_init_from_4f (CoglColor *color, float red, @@ -96,7 +83,7 @@ cogl_color_init_from_4f (CoglColor *color, float blue, float alpha) { - _COGL_RETURN_IF_FAIL (color != NULL); + g_return_if_fail (color != NULL); color->red = (red * 255); color->green = (green * 255); @@ -104,22 +91,11 @@ cogl_color_init_from_4f (CoglColor *color, color->alpha = (alpha * 255); } -/* XXX: deprecated, use cogl_color_init_from_4f */ -void -cogl_color_set_from_4f (CoglColor *color, - float red, - float green, - float blue, - float alpha) -{ - cogl_color_init_from_4f (color, red, green, blue, alpha); -} - void cogl_color_init_from_4fv (CoglColor *color, const float *color_array) { - _COGL_RETURN_IF_FAIL (color != NULL); + g_return_if_fail (color != NULL); color->red = (color_array[0] * 255); color->green = (color_array[1] * 255); @@ -302,13 +278,13 @@ cogl_color_unpremultiply (CoglColor *color) } } -CoglBool +gboolean cogl_color_equal (const void *v1, const void *v2) { const uint32_t *c1 = v1, *c2 = v2; - _COGL_RETURN_VAL_IF_FAIL (v1 != NULL, FALSE); - _COGL_RETURN_VAL_IF_FAIL (v2 != NULL, FALSE); + g_return_val_if_fail (v1 != NULL, FALSE); + g_return_val_if_fail (v2 != NULL, FALSE); /* XXX: We don't compare the padding */ return *c1 == *c2 ? TRUE : FALSE; diff --git a/cogl/cogl/cogl-color.h b/cogl/cogl/cogl-color.h index 42fe52546..0defb733c 100644 --- a/cogl/cogl/cogl-color.h +++ b/cogl/cogl/cogl-color.h @@ -50,13 +50,14 @@ #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS /** * cogl_color_get_gtype: * * Returns: a #GType that can be used with the GLib type system. */ +COGL_EXPORT GType cogl_color_get_gtype (void); /** @@ -69,7 +70,7 @@ GType cogl_color_get_gtype (void); * * Since: 1.0 */ -CoglColor * +COGL_EXPORT CoglColor * cogl_color_new (void); /** @@ -83,7 +84,7 @@ cogl_color_new (void); * * Since: 1.0 */ -CoglColor * +COGL_EXPORT CoglColor * cogl_color_copy (const CoglColor *color); /** @@ -94,7 +95,7 @@ cogl_color_copy (const CoglColor *color); * * Since: 1.0 */ -void +COGL_EXPORT void cogl_color_free (CoglColor *color); /** @@ -109,34 +110,13 @@ cogl_color_free (CoglColor *color); * * Since: 1.4 */ -void +COGL_EXPORT void cogl_color_init_from_4ub (CoglColor *color, uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha); -/** - * cogl_color_set_from_4ub: - * @color: A pointer to a #CoglColor to initialize - * @red: value of the red channel, between 0 and 255 - * @green: value of the green channel, between 0 and 255 - * @blue: value of the blue channel, between 0 and 255 - * @alpha: value of the alpha channel, between 0 and 255 - * - * Sets the values of the passed channels into a #CoglColor. - * - * Since: 1.0 - * Deprecated: 1.4: Use cogl_color_init_from_4ub instead. - */ -COGL_DEPRECATED_IN_1_4_FOR (cogl_color_init_from_4ub) -void -cogl_color_set_from_4ub (CoglColor *color, - uint8_t red, - uint8_t green, - uint8_t blue, - uint8_t alpha); - /** * cogl_color_init_from_4f: * @color: A pointer to a #CoglColor to initialize @@ -149,34 +129,13 @@ cogl_color_set_from_4ub (CoglColor *color, * * Since: 1.4 */ -void +COGL_EXPORT void cogl_color_init_from_4f (CoglColor *color, float red, float green, float blue, float alpha); -/** - * cogl_color_set_from_4f: - * @color: A pointer to a #CoglColor to initialize - * @red: value of the red channel, between 0 and %1.0 - * @green: value of the green channel, between 0 and %1.0 - * @blue: value of the blue channel, between 0 and %1.0 - * @alpha: value of the alpha channel, between 0 and %1.0 - * - * Sets the values of the passed channels into a #CoglColor - * - * Since: 1.0 - * Deprecated: 1.4: Use cogl_color_init_from_4f instead. - */ -COGL_DEPRECATED_IN_1_4_FOR (cogl_color_init_from_4f) -void -cogl_color_set_from_4f (CoglColor *color, - float red, - float green, - float blue, - float alpha); - /** * cogl_color_init_from_4fv: * @color: A pointer to a #CoglColor to initialize @@ -186,7 +145,7 @@ cogl_color_set_from_4f (CoglColor *color, * * Since: 1.4 */ -void +COGL_EXPORT void cogl_color_init_from_4fv (CoglColor *color, const float *color_array); @@ -201,7 +160,7 @@ cogl_color_init_from_4fv (CoglColor *color, * * Since: 1.0 */ -unsigned char +COGL_EXPORT unsigned char cogl_color_get_red_byte (const CoglColor *color); /** @@ -215,7 +174,7 @@ cogl_color_get_red_byte (const CoglColor *color); * * Since: 1.0 */ -unsigned char +COGL_EXPORT unsigned char cogl_color_get_green_byte (const CoglColor *color); /** @@ -229,7 +188,7 @@ cogl_color_get_green_byte (const CoglColor *color); * * Since: 1.0 */ -unsigned char +COGL_EXPORT unsigned char cogl_color_get_blue_byte (const CoglColor *color); /** @@ -243,7 +202,7 @@ cogl_color_get_blue_byte (const CoglColor *color); * * Since: 1.0 */ -unsigned char +COGL_EXPORT unsigned char cogl_color_get_alpha_byte (const CoglColor *color); /** @@ -257,7 +216,7 @@ cogl_color_get_alpha_byte (const CoglColor *color); * * Since: 1.0 */ -float +COGL_EXPORT float cogl_color_get_red_float (const CoglColor *color); /** @@ -271,7 +230,7 @@ cogl_color_get_red_float (const CoglColor *color); * * Since: 1.0 */ -float +COGL_EXPORT float cogl_color_get_green_float (const CoglColor *color); /** @@ -285,7 +244,7 @@ cogl_color_get_green_float (const CoglColor *color); * * Since: 1.0 */ -float +COGL_EXPORT float cogl_color_get_blue_float (const CoglColor *color); /** @@ -299,7 +258,7 @@ cogl_color_get_blue_float (const CoglColor *color); * * Since: 1.0 */ -float +COGL_EXPORT float cogl_color_get_alpha_float (const CoglColor *color); /** @@ -313,7 +272,7 @@ cogl_color_get_alpha_float (const CoglColor *color); * * Since: 1.0 */ -float +COGL_EXPORT float cogl_color_get_red (const CoglColor *color); /** @@ -327,7 +286,7 @@ cogl_color_get_red (const CoglColor *color); * * Since: 1.0 */ -float +COGL_EXPORT float cogl_color_get_green (const CoglColor *color); /** @@ -341,7 +300,7 @@ cogl_color_get_green (const CoglColor *color); * * Since: 1.0 */ -float +COGL_EXPORT float cogl_color_get_blue (const CoglColor *color); /** @@ -355,7 +314,7 @@ cogl_color_get_blue (const CoglColor *color); * * Since: 1.0 */ -float +COGL_EXPORT float cogl_color_get_alpha (const CoglColor *color); /** @@ -367,7 +326,7 @@ cogl_color_get_alpha (const CoglColor *color); * * Since: 1.4 */ -void +COGL_EXPORT void cogl_color_set_red_byte (CoglColor *color, unsigned char red); @@ -380,7 +339,7 @@ cogl_color_set_red_byte (CoglColor *color, * * Since: 1.4 */ -void +COGL_EXPORT void cogl_color_set_green_byte (CoglColor *color, unsigned char green); @@ -393,7 +352,7 @@ cogl_color_set_green_byte (CoglColor *color, * * Since: 1.4 */ -void +COGL_EXPORT void cogl_color_set_blue_byte (CoglColor *color, unsigned char blue); @@ -406,7 +365,7 @@ cogl_color_set_blue_byte (CoglColor *color, * * Since: 1.4 */ -void +COGL_EXPORT void cogl_color_set_alpha_byte (CoglColor *color, unsigned char alpha); @@ -419,7 +378,7 @@ cogl_color_set_alpha_byte (CoglColor *color, * * since: 1.4 */ -void +COGL_EXPORT void cogl_color_set_red_float (CoglColor *color, float red); @@ -432,7 +391,7 @@ cogl_color_set_red_float (CoglColor *color, * * since: 1.4 */ -void +COGL_EXPORT void cogl_color_set_green_float (CoglColor *color, float green); @@ -445,7 +404,7 @@ cogl_color_set_green_float (CoglColor *color, * * since: 1.4 */ -void +COGL_EXPORT void cogl_color_set_blue_float (CoglColor *color, float blue); @@ -458,7 +417,7 @@ cogl_color_set_blue_float (CoglColor *color, * * since: 1.4 */ -void +COGL_EXPORT void cogl_color_set_alpha_float (CoglColor *color, float alpha); @@ -471,7 +430,7 @@ cogl_color_set_alpha_float (CoglColor *color, * * Since: 1.4 */ -void +COGL_EXPORT void cogl_color_set_red (CoglColor *color, float red); @@ -484,7 +443,7 @@ cogl_color_set_red (CoglColor *color, * * Since: 1.4 */ -void +COGL_EXPORT void cogl_color_set_green (CoglColor *color, float green); @@ -497,7 +456,7 @@ cogl_color_set_green (CoglColor *color, * * Since: 1.4 */ -void +COGL_EXPORT void cogl_color_set_blue (CoglColor *color, float blue); @@ -510,7 +469,7 @@ cogl_color_set_blue (CoglColor *color, * * Since: 1.4 */ -void +COGL_EXPORT void cogl_color_set_alpha (CoglColor *color, float alpha); @@ -524,7 +483,7 @@ cogl_color_set_alpha (CoglColor *color, * * Since: 1.0 */ -void +COGL_EXPORT void cogl_color_premultiply (CoglColor *color); /** @@ -537,7 +496,7 @@ cogl_color_premultiply (CoglColor *color); * * Since: 1.4 */ -void +COGL_EXPORT void cogl_color_unpremultiply (CoglColor *color); /** @@ -554,7 +513,7 @@ cogl_color_unpremultiply (CoglColor *color); * * Since: 1.0 */ -CoglBool +COGL_EXPORT gboolean cogl_color_equal (const void *v1, const void *v2); /** @@ -571,7 +530,7 @@ cogl_color_equal (const void *v1, const void *v2); * * Since: 1.16 */ -void +COGL_EXPORT void cogl_color_to_hsl (const CoglColor *color, float *hue, float *saturation, @@ -589,12 +548,12 @@ cogl_color_to_hsl (const CoglColor *color, * * Since: 1.16 */ -void +COGL_EXPORT void cogl_color_init_from_hsl (CoglColor *color, float hue, float saturation, float luminance); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_COLOR_H__ */ diff --git a/cogl/cogl/cogl-config.c b/cogl/cogl/cogl-config.c deleted file mode 100644 index 6535d0797..000000000 --- a/cogl/cogl/cogl-config.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Robert Bragg - */ - -#ifdef HAVE_CONFIG_H -#include "cogl-config.h" -#endif - -#include "cogl-debug.h" -#include "cogl-config-private.h" - -#include - -char *_cogl_config_driver; -char *_cogl_config_renderer; -char *_cogl_config_disable_gl_extensions; -char *_cogl_config_override_gl_version; - -/* Array of config options that just set a global string */ -static const struct -{ - const char *conf_name; - char **variable; -} cogl_config_string_options[] = - { - { "COGL_DRIVER", &_cogl_config_driver }, - { "COGL_RENDERER", &_cogl_config_renderer }, - { "COGL_DISABLE_GL_EXTENSIONS", &_cogl_config_disable_gl_extensions }, - { "COGL_OVERRIDE_GL_VERSION", &_cogl_config_override_gl_version } - }; - -static void -_cogl_config_process (GKeyFile *key_file) -{ - char *value; - int i; - - value = g_key_file_get_string (key_file, "global", "COGL_DEBUG", NULL); - if (value) - { - _cogl_parse_debug_string (value, - TRUE /* enable the flags */, - TRUE /* ignore help option */); - free (value); - } - - value = g_key_file_get_string (key_file, "global", "COGL_NO_DEBUG", NULL); - if (value) - { - _cogl_parse_debug_string (value, - FALSE /* disable the flags */, - TRUE /* ignore help option */); - free (value); - } - - for (i = 0; i < G_N_ELEMENTS (cogl_config_string_options); i++) - { - const char *conf_name = cogl_config_string_options[i].conf_name; - char **variable = cogl_config_string_options[i].variable; - - value = g_key_file_get_string (key_file, "global", conf_name, NULL); - if (value) - { - free (*variable); - *variable = value; - } - } -} - -void -_cogl_config_read (void) -{ - GKeyFile *key_file = g_key_file_new (); - const char * const *system_dirs = g_get_system_config_dirs (); - char *filename; - CoglBool status = FALSE; - int i; - - for (i = 0; system_dirs[i]; i++) - { - filename = g_build_filename (system_dirs[i], "cogl", "cogl.conf", NULL); - status = g_key_file_load_from_file (key_file, - filename, - 0, - NULL); - free (filename); - if (status) - { - _cogl_config_process (key_file); - g_key_file_free (key_file); - key_file = g_key_file_new (); - break; - } - } - - filename = g_build_filename (g_get_user_config_dir (), "cogl", "cogl.conf", NULL); - status = g_key_file_load_from_file (key_file, - filename, - 0, - NULL); - free (filename); - - if (status) - _cogl_config_process (key_file); - - g_key_file_free (key_file); -} diff --git a/cogl/cogl/cogl-context-private.h b/cogl/cogl/cogl-context-private.h index 9e6620733..1880dbc90 100644 --- a/cogl/cogl/cogl-context-private.h +++ b/cogl/cogl/cogl-context-private.h @@ -32,15 +32,9 @@ #define __COGL_CONTEXT_PRIVATE_H #include "cogl-context.h" -#include "cogl-winsys-private.h" #include "cogl-flags.h" -#ifdef COGL_HAS_XLIB_SUPPORT -#include "cogl-xlib-private.h" -#endif - #include "cogl-display-private.h" -#include "cogl-primitives.h" #include "cogl-clip-stack.h" #include "cogl-matrix-stack.h" #include "cogl-pipeline-private.h" @@ -51,8 +45,6 @@ #include "cogl-texture-driver.h" #include "cogl-pipeline-cache.h" #include "cogl-texture-2d.h" -#include "cogl-texture-3d.h" -#include "cogl-texture-rectangle.h" #include "cogl-sampler-cache-private.h" #include "cogl-gpu-info-private.h" #include "cogl-gl-header.h" @@ -62,6 +54,7 @@ #include "cogl-poll-private.h" #include "cogl-path/cogl-path-types.h" #include "cogl-private.h" +#include "winsys/cogl-winsys-private.h" typedef struct { @@ -99,13 +92,9 @@ struct _CoglContext /* Features cache */ unsigned long features[COGL_FLAGS_N_LONGS_FOR_SIZE (_COGL_N_FEATURE_IDS)]; - CoglFeatureFlags feature_flags; /* legacy/deprecated feature flags */ unsigned long private_features [COGL_FLAGS_N_LONGS_FOR_SIZE (COGL_N_PRIVATE_FEATURES)]; - CoglBool needs_viewport_scissor_workaround; - CoglFramebuffer *viewport_scissor_workaround_framebuffer; - CoglPipeline *default_pipeline; CoglPipelineLayer *default_layer_0; CoglPipelineLayer *default_layer_n; @@ -115,28 +104,20 @@ struct _CoglContext GArray *attribute_name_index_map; int n_attribute_names; - CoglBitmask enabled_builtin_attributes; - CoglBitmask enabled_texcoord_attributes; CoglBitmask enabled_custom_attributes; /* These are temporary bitmasks that are used when disabling - * builtin,texcoord and custom attribute arrays. They are here just + * builtin and custom attribute arrays. They are here just * to avoid allocating new ones each time */ - CoglBitmask enable_builtin_attributes_tmp; - CoglBitmask enable_texcoord_attributes_tmp; CoglBitmask enable_custom_attributes_tmp; CoglBitmask changed_bits_tmp; - CoglBool legacy_backface_culling_enabled; + gboolean legacy_backface_culling_enabled; /* A few handy matrix constants */ CoglMatrix identity_matrix; CoglMatrix y_flip_matrix; - /* Value that was last used when calling glMatrixMode to avoid - calling it multiple times */ - CoglMatrixMode flushed_matrix_mode; - /* The matrix stack entries that should be flushed during the next * pipeline state flush */ CoglMatrixEntry *current_projection_entry; @@ -152,25 +133,17 @@ struct _CoglContext GArray *texture_units; int active_texture_unit; - CoglPipelineFogState legacy_fog_state; + /* Only used for comparing other pipelines when reading pixels. */ + CoglPipeline *opaque_color_pipeline; - /* Pipelines */ - CoglPipeline *opaque_color_pipeline; /* used for set_source_color */ - CoglPipeline *blended_color_pipeline; /* used for set_source_color */ - CoglPipeline *texture_pipeline; /* used for set_source_texture */ GString *codegen_header_buffer; GString *codegen_source_buffer; GString *codegen_boilerplate_buffer; - GList *source_stack; - - int legacy_state_set; CoglPipelineCache *pipeline_cache; /* Textures */ CoglTexture2D *default_gl_texture_2d_tex; - CoglTexture3D *default_gl_texture_3d_tex; - CoglTextureRectangle *default_gl_texture_rect_tex; /* Central list of all framebuffers so all journals can be flushed * at any time. */ @@ -185,25 +158,23 @@ struct _CoglContext /* Some simple caching, to minimize state changes... */ CoglPipeline *current_pipeline; unsigned long current_pipeline_changes_since_flush; - CoglBool current_pipeline_with_color_attrib; - CoglBool current_pipeline_unknown_color_alpha; + gboolean current_pipeline_with_color_attrib; + gboolean current_pipeline_unknown_color_alpha; unsigned long current_pipeline_age; - CoglBool gl_blend_enable_cache; + gboolean gl_blend_enable_cache; - CoglBool depth_test_enabled_cache; + gboolean depth_test_enabled_cache; CoglDepthTestFunction depth_test_function_cache; - CoglBool depth_writing_enabled_cache; + gboolean depth_writing_enabled_cache; float depth_range_near_cache; float depth_range_far_cache; - CoglBool legacy_depth_test_enabled; + gboolean legacy_depth_test_enabled; CoglBuffer *current_buffer[COGL_BUFFER_BIND_TARGET_COUNT]; /* Framebuffers */ - GSList *framebuffer_stack; - CoglFramebuffer *window_buffer; unsigned long current_draw_buffer_state_flushed; unsigned long current_draw_buffer_changes; CoglFramebuffer *current_draw_buffer; @@ -219,13 +190,10 @@ struct _CoglContext CoglList onscreen_dirty_queue; CoglClosure *onscreen_dispatch_idle; - CoglGLES2Context *current_gles2_context; - GQueue gles2_context_stack; - /* This becomes TRUE the first time the context is bound to an * onscreen buffer. This is used by cogl-framebuffer-gl to determine * when to initialise the glDrawBuffer state */ - CoglBool was_bound_to_onscreen; + gboolean was_bound_to_onscreen; /* Primitives */ CoglPath *current_path; @@ -241,8 +209,6 @@ struct _CoglContext CoglIndices *rectangle_short_indices; int rectangle_short_indices_len; - CoglBool in_begin_gl_block; - CoglPipeline *texture_download_pipeline; CoglPipeline *blit_texture_pipeline; @@ -262,14 +228,9 @@ struct _CoglContext GLint max_activateable_texture_units; /* Fragment processing programs */ - CoglHandle current_program; - - CoglPipelineProgramType current_fragment_program_type; - CoglPipelineProgramType current_vertex_program_type; GLuint current_gl_program; - CoglBool current_gl_dither_enabled; - CoglColorMask current_gl_color_mask; + gboolean current_gl_dither_enabled; GLenum current_gl_draw_buffer; /* Clipping */ @@ -280,7 +241,7 @@ struct _CoglContext doesn't need to be a valid pointer. We can't just use NULL in current_clip_stack to mark a dirty state because NULL is a valid stack (meaning no clipping) */ - CoglBool current_clip_stack_valid; + gboolean current_clip_stack_valid; /* The clip state that was flushed. This isn't intended to be used as a stack to push and pop new entries. Instead the current stack that the user wants is part of the framebuffer state. This is @@ -288,36 +249,16 @@ struct _CoglContext same state multiple times. When the clip state is flushed this will hold a reference */ CoglClipStack *current_clip_stack; - /* Whether the stencil buffer was used as part of the current clip - state. If TRUE then any further use of the stencil buffer (such - as for drawing paths) would need to be merged with the existing - stencil buffer */ - CoglBool current_clip_stack_uses_stencil; /* This is used as a temporary buffer to fill a CoglBuffer when cogl_buffer_map fails and we only want to map to fill it with new data */ GByteArray *buffer_map_fallback_array; - CoglBool buffer_map_fallback_in_use; + gboolean buffer_map_fallback_in_use; size_t buffer_map_fallback_offset; - CoglWinsysRectangleState rectangle_state; - CoglSamplerCache *sampler_cache; - /* FIXME: remove these when we remove the last xlib based clutter - * backend. they should be tracked as part of the renderer but e.g. - * the eglx backend doesn't yet have a corresponding Cogl winsys - * and so we wont have a renderer in that case. */ -#ifdef COGL_HAS_XLIB_SUPPORT - int damage_base; - /* List of callback functions that will be given every Xlib event */ - GSList *event_filters; - /* Current top of the XError trap state stack. The actual memory for - these is expected to be allocated on the stack by the caller */ - CoglXlibTrapState *trap_state; -#endif - unsigned long winsys_features [COGL_FLAGS_N_LONGS_FOR_SIZE (COGL_WINSYS_FEATURE_N_FEATURES)]; void *winsys; @@ -359,8 +300,8 @@ struct _CoglContext #undef COGL_EXT_END }; -CoglContext * -_cogl_context_get_default (); +COGL_EXPORT CoglContext * +_cogl_context_get_default (void); const CoglWinsysVtable * _cogl_context_get_winsys (CoglContext *context); @@ -371,9 +312,9 @@ _cogl_context_get_winsys (CoglContext *context); * to know when to re-query the GL extensions. The backend should also * check whether the GL context is supported by Cogl. If not it should * return FALSE and set @error */ -CoglBool +gboolean _cogl_context_update_features (CoglContext *context, - CoglError **error); + GError **error); /* Obtains the context and returns retval if NULL */ #define _COGL_GET_CONTEXT(ctxvar, retval) \ diff --git a/cogl/cogl/cogl-context.c b/cogl/cogl/cogl-context.c index 7c50fb02c..688c3b37d 100644 --- a/cogl/cogl/cogl-context.c +++ b/cogl/cogl/cogl-context.c @@ -28,45 +28,30 @@ * */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-object.h" #include "cogl-private.h" -#include "cogl-winsys-private.h" -#include "winsys/cogl-winsys-stub-private.h" #include "cogl-profile.h" #include "cogl-util.h" #include "cogl-context-private.h" -#include "cogl-util-gl-private.h" #include "cogl-display-private.h" #include "cogl-renderer-private.h" #include "cogl-journal-private.h" #include "cogl-texture-private.h" #include "cogl-texture-2d-private.h" -#include "cogl-texture-3d-private.h" -#include "cogl-texture-rectangle-private.h" #include "cogl-pipeline-private.h" -#include "cogl-pipeline-opengl-private.h" #include "cogl-framebuffer-private.h" #include "cogl-onscreen-private.h" #include "cogl-attribute-private.h" #include "cogl1-context.h" #include "cogl-gpu-info-private.h" -#include "cogl-config-private.h" -#include "cogl-error-private.h" #include "cogl-gtype-private.h" - -#include "cogl/deprecated/cogl-framebuffer-deprecated.h" +#include "winsys/cogl-winsys-private.h" #include #include -#ifdef HAVE_COGL_GL -#include "cogl-pipeline-fragend-arbfp-private.h" -#endif - /* These aren't defined in the GLES headers */ #ifndef GL_POINT_SPRITE #define GL_POINT_SPRITE 0x8861 @@ -107,41 +92,8 @@ static CoglContext *_cogl_context = NULL; static void _cogl_init_feature_overrides (CoglContext *ctx) { - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_VBOS))) - COGL_FLAGS_SET (ctx->private_features, COGL_PRIVATE_FEATURE_VBOS, FALSE); - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_PBOS))) COGL_FLAGS_SET (ctx->private_features, COGL_PRIVATE_FEATURE_PBOS, FALSE); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_ARBFP))) - { - ctx->feature_flags &= ~COGL_FEATURE_SHADERS_ARBFP; - COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_ARBFP, FALSE); - } - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_GLSL))) - { - ctx->feature_flags &= ~COGL_FEATURE_SHADERS_GLSL; - COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_GLSL, FALSE); - COGL_FLAGS_SET (ctx->features, - COGL_FEATURE_ID_PER_VERTEX_POINT_SIZE, - FALSE); - } - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_NPOT_TEXTURES))) - { - ctx->feature_flags &= ~(COGL_FEATURE_TEXTURE_NPOT | - COGL_FEATURE_TEXTURE_NPOT_BASIC | - COGL_FEATURE_TEXTURE_NPOT_MIPMAP | - COGL_FEATURE_TEXTURE_NPOT_REPEAT); - COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_TEXTURE_NPOT, FALSE); - COGL_FLAGS_SET (ctx->features, - COGL_FEATURE_ID_TEXTURE_NPOT_BASIC, FALSE); - COGL_FLAGS_SET (ctx->features, - COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP, FALSE); - COGL_FLAGS_SET (ctx->features, - COGL_FEATURE_ID_TEXTURE_NPOT_REPEAT, FALSE); - } } const CoglWinsysVtable * @@ -150,6 +102,12 @@ _cogl_context_get_winsys (CoglContext *context) return context->display->renderer->winsys_vtable; } +static const CoglDriverVtable * +_cogl_context_get_driver (CoglContext *context) +{ + return context->driver_vtable; +} + /* For reference: There was some deliberation over whether to have a * constructor that could throw an exception but looking at standard * practices with several high level OO languages including python, C++, @@ -161,14 +119,12 @@ _cogl_context_get_winsys (CoglContext *context) */ CoglContext * cogl_context_new (CoglDisplay *display, - CoglError **error) + GError **error) { CoglContext *context; uint8_t white_pixel[] = { 0xff, 0xff, 0xff, 0xff }; - CoglBitmap *white_pixel_bitmap; const CoglWinsysVtable *winsys; int i; - CoglError *internal_error = NULL; _cogl_init (); @@ -189,7 +145,7 @@ cogl_context_new (CoglDisplay *display, #endif /* Allocate context memory */ - context = calloc (1, sizeof (CoglContext)); + context = g_malloc0 (sizeof (CoglContext)); /* Convert the context into an object immediately in case any of the code below wants to verify that the context pointer is a valid @@ -207,11 +163,7 @@ cogl_context_new (CoglDisplay *display, /* Init default values */ memset (context->features, 0, sizeof (context->features)); - context->feature_flags = 0; memset (context->private_features, 0, sizeof (context->private_features)); - - context->rectangle_state = COGL_WINSYS_RECTANGLE_STATE_UNKNOWN; - memset (context->winsys_features, 0, sizeof (context->winsys_features)); if (!display) @@ -219,7 +171,7 @@ cogl_context_new (CoglDisplay *display, CoglRenderer *renderer = cogl_renderer_new (); if (!cogl_renderer_connect (renderer, error)) { - free (context); + g_free (context); return NULL; } @@ -232,7 +184,7 @@ cogl_context_new (CoglDisplay *display, if (!cogl_display_setup (display, error)) { cogl_object_unref (display); - free (context); + g_free (context); return NULL; } @@ -255,12 +207,19 @@ cogl_context_new (CoglDisplay *display, if (!winsys->context_init (context, error)) { cogl_object_unref (display); - free (context); + g_free (context); + return NULL; + } + + if (!context->driver_vtable->context_init (context)) + { + cogl_object_unref (display); + g_free (context); return NULL; } context->attribute_name_states_hash = - g_hash_table_new_full (g_str_hash, g_str_equal, free, free); + g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); context->attribute_name_index_map = NULL; context->n_attribute_names = 0; @@ -270,29 +229,13 @@ cogl_context_new (CoglDisplay *display, context->uniform_names = - g_ptr_array_new_with_free_func ((GDestroyNotify) free); + g_ptr_array_new_with_free_func ((GDestroyNotify) g_free); context->uniform_name_hash = g_hash_table_new (g_str_hash, g_str_equal); context->n_uniform_names = 0; /* Initialise the driver specific state */ _cogl_init_feature_overrides (context); - /* XXX: ONGOING BUG: Intel viewport scissor - * - * Intel gen6 drivers don't currently correctly handle offset - * viewports, since primitives aren't clipped within the bounds of - * the viewport. To workaround this we push our own clip for the - * viewport that will use scissoring to ensure we clip as expected. - * - * TODO: file a bug upstream! - */ - if (context->gpu.driver_package == COGL_GPU_INFO_DRIVER_PACKAGE_MESA && - context->gpu.architecture == COGL_GPU_INFO_ARCHITECTURE_SANDYBRIDGE && - !getenv ("COGL_DISABLE_INTEL_VIEWPORT_SCISSORT_WORKAROUND")) - context->needs_viewport_scissor_workaround = TRUE; - else - context->needs_viewport_scissor_workaround = FALSE; - context->sampler_cache = _cogl_sampler_cache_new (context); _cogl_pipeline_init_default_pipeline (); @@ -309,34 +252,13 @@ cogl_context_new (CoglDisplay *display, cogl_matrix_init_identity (&context->y_flip_matrix); cogl_matrix_scale (&context->y_flip_matrix, 1, -1, 1); - context->flushed_matrix_mode = COGL_MATRIX_MODELVIEW; - - context->texture_units = - g_array_new (FALSE, FALSE, sizeof (CoglTextureUnit)); - - if (_cogl_has_private_feature (context, COGL_PRIVATE_FEATURE_ANY_GL)) - { - /* See cogl-pipeline.c for more details about why we leave texture unit 1 - * active by default... */ - context->active_texture_unit = 1; - GE (context, glActiveTexture (GL_TEXTURE1)); - } - - context->legacy_fog_state.enabled = FALSE; - context->opaque_color_pipeline = cogl_pipeline_new (context); - context->blended_color_pipeline = cogl_pipeline_new (context); - context->texture_pipeline = cogl_pipeline_new (context); + context->codegen_header_buffer = g_string_new (""); context->codegen_source_buffer = g_string_new (""); context->codegen_boilerplate_buffer = g_string_new (""); - context->source_stack = NULL; - - context->legacy_state_set = 0; context->default_gl_texture_2d_tex = NULL; - context->default_gl_texture_3d_tex = NULL; - context->default_gl_texture_rect_tex = NULL; context->framebuffers = NULL; context->current_draw_buffer = NULL; @@ -350,8 +272,6 @@ cogl_context_new (CoglDisplay *display, _cogl_list_init (&context->onscreen_events_queue); _cogl_list_init (&context->onscreen_dirty_queue); - g_queue_init (&context->gles2_context_stack); - context->journal_flush_attributes_array = g_array_new (TRUE, FALSE, sizeof (CoglAttribute *)); context->journal_clip_bounds = NULL; @@ -362,10 +282,6 @@ cogl_context_new (CoglDisplay *display, context->current_pipeline_changes_since_flush = 0; context->current_pipeline_with_color_attrib = FALSE; - _cogl_bitmask_init (&context->enabled_builtin_attributes); - _cogl_bitmask_init (&context->enable_builtin_attributes_tmp); - _cogl_bitmask_init (&context->enabled_texcoord_attributes); - _cogl_bitmask_init (&context->enable_texcoord_attributes_tmp); _cogl_bitmask_init (&context->enabled_custom_attributes); _cogl_bitmask_init (&context->enable_custom_attributes_tmp); _cogl_bitmask_init (&context->changed_bits_tmp); @@ -373,12 +289,9 @@ cogl_context_new (CoglDisplay *display, context->max_texture_units = -1; context->max_activateable_texture_units = -1; - context->current_fragment_program_type = COGL_PIPELINE_PROGRAM_TYPE_FIXED; - context->current_vertex_program_type = COGL_PIPELINE_PROGRAM_TYPE_FIXED; context->current_gl_program = 0; context->current_gl_dither_enabled = TRUE; - context->current_gl_color_mask = COGL_COLOR_MASK_ALL; context->gl_blend_enable_cache = FALSE; @@ -395,25 +308,9 @@ cogl_context_new (CoglDisplay *display, for (i = 0; i < COGL_BUFFER_BIND_TARGET_COUNT; i++) context->current_buffer[i] = NULL; - context->window_buffer = NULL; - context->framebuffer_stack = _cogl_create_framebuffer_stack (); - - /* XXX: In this case the Clutter backend is still responsible for - * the OpenGL binding API and for creating onscreen framebuffers and - * so we have to add a dummy framebuffer to represent the backend - * owned window... */ - if (_cogl_context_get_winsys (context) == _cogl_winsys_stub_get_vtable ()) - { - CoglOnscreen *window = _cogl_onscreen_new (); - cogl_set_framebuffer (COGL_FRAMEBUFFER (window)); - cogl_object_unref (COGL_FRAMEBUFFER (window)); - } - context->current_path = NULL; context->stencil_pipeline = cogl_pipeline_new (context); - context->in_begin_gl_block = FALSE; - context->quad_buffer_indices_byte = NULL; context->quad_buffer_indices = NULL; context->quad_buffer_indices_len = 0; @@ -425,33 +322,6 @@ cogl_context_new (CoglDisplay *display, context->texture_download_pipeline = NULL; context->blit_texture_pipeline = NULL; -#if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES) - if (_cogl_has_private_feature (context, COGL_PRIVATE_FEATURE_ALPHA_TEST)) - /* The default for GL_ALPHA_TEST is to always pass which is equivalent to - * the test being disabled therefore we assume that for all drivers there - * will be no performance impact if we always leave the test enabled which - * makes things a bit simpler for us. Under GLES2 the alpha test is - * implemented in the fragment shader so there is no enable for it - */ - GE (context, glEnable (GL_ALPHA_TEST)); -#endif - -#if defined (HAVE_COGL_GL) - if ((context->driver == COGL_DRIVER_GL3)) - { - GLuint vertex_array; - - /* In a forward compatible context, GL 3 doesn't support rendering - * using the default vertex array object. Cogl doesn't use vertex - * array objects yet so for now we just create a dummy array - * object that we will use as our own default object. Eventually - * it could be good to attach the vertex array objects to - * CoglPrimitives */ - context->glGenVertexArrays (1, &vertex_array); - context->glBindVertexArray (vertex_array); - } -#endif - context->current_modelview_entry = NULL; context->current_projection_entry = NULL; _cogl_matrix_entry_identity_init (&context->identity_entry); @@ -467,60 +337,12 @@ cogl_context_new (CoglDisplay *display, white_pixel, NULL); /* abort on error */ - /* If 3D or rectangle textures aren't supported then these will - * return errors that we can simply ignore. */ - internal_error = NULL; - context->default_gl_texture_3d_tex = - cogl_texture_3d_new_from_data (context, - 1, 1, 1, /* width, height, depth */ - COGL_PIXEL_FORMAT_RGBA_8888_PRE, - 0, /* rowstride */ - 0, /* image stride */ - white_pixel, - &internal_error); - if (internal_error) - cogl_error_free (internal_error); - - /* TODO: add cogl_texture_rectangle_new_from_data() */ - white_pixel_bitmap = - cogl_bitmap_new_for_data (context, - 1, 1, /* width/height */ - COGL_PIXEL_FORMAT_RGBA_8888_PRE, - 4, /* rowstride */ - white_pixel); - - internal_error = NULL; - context->default_gl_texture_rect_tex = - cogl_texture_rectangle_new_from_bitmap (white_pixel_bitmap); - - /* XXX: we need to allocate the texture now because the white_pixel - * data is on the stack */ - cogl_texture_allocate (COGL_TEXTURE (context->default_gl_texture_rect_tex), - &internal_error); - if (internal_error) - cogl_error_free (internal_error); - - cogl_object_unref (white_pixel_bitmap); - - cogl_push_source (context->opaque_color_pipeline); - context->atlases = NULL; g_hook_list_init (&context->atlas_reorganize_callbacks, sizeof (GHook)); context->buffer_map_fallback_array = g_byte_array_new (); context->buffer_map_fallback_in_use = FALSE; - /* As far as I can tell, GL_POINT_SPRITE doesn't have any effect - unless GL_COORD_REPLACE is enabled for an individual layer. - Therefore it seems like it should be ok to just leave it enabled - all the time instead of having to have a set property on each - pipeline to track whether any layers have point sprite coords - enabled. We don't need to do this for GL3 or GLES2 because point - sprites are handled using a builtin varying in the shader. */ - if (_cogl_has_private_feature (context, COGL_PRIVATE_FEATURE_GL_FIXED) && - cogl_has_feature (context, COGL_FEATURE_ID_POINT_SPRITE)) - GE (context, glEnable (GL_POINT_SPRITE)); - _cogl_list_init (&context->fences); return context; @@ -530,27 +352,18 @@ static void _cogl_context_free (CoglContext *context) { const CoglWinsysVtable *winsys = _cogl_context_get_winsys (context); + const CoglDriverVtable *driver = _cogl_context_get_driver (context); winsys->context_deinit (context); - _cogl_free_framebuffer_stack (context->framebuffer_stack); - if (context->current_path) - cogl_handle_unref (context->current_path); + cogl_object_unref (context->current_path); if (context->default_gl_texture_2d_tex) cogl_object_unref (context->default_gl_texture_2d_tex); - if (context->default_gl_texture_3d_tex) - cogl_object_unref (context->default_gl_texture_3d_tex); - if (context->default_gl_texture_rect_tex) - cogl_object_unref (context->default_gl_texture_rect_tex); if (context->opaque_color_pipeline) cogl_object_unref (context->opaque_color_pipeline); - if (context->blended_color_pipeline) - cogl_object_unref (context->blended_color_pipeline); - if (context->texture_pipeline) - cogl_object_unref (context->texture_pipeline); if (context->blit_texture_pipeline) cogl_object_unref (context->blit_texture_pipeline); @@ -558,8 +371,6 @@ _cogl_context_free (CoglContext *context) if (context->swap_callback_closures) g_hash_table_destroy (context->swap_callback_closures); - g_warn_if_fail (context->gles2_context_stack.length == 0); - if (context->journal_flush_attributes_array) g_array_free (context->journal_flush_attributes_array, TRUE); if (context->journal_clip_bounds) @@ -594,10 +405,6 @@ _cogl_context_free (CoglContext *context) g_slist_free (context->atlases); g_hook_list_clear (&context->atlas_reorganize_callbacks); - _cogl_bitmask_destroy (&context->enabled_builtin_attributes); - _cogl_bitmask_destroy (&context->enable_builtin_attributes_tmp); - _cogl_bitmask_destroy (&context->enabled_texcoord_attributes); - _cogl_bitmask_destroy (&context->enable_texcoord_attributes_tmp); _cogl_bitmask_destroy (&context->enabled_custom_attributes); _cogl_bitmask_destroy (&context->enable_custom_attributes_tmp); _cogl_bitmask_destroy (&context->changed_bits_tmp); @@ -613,8 +420,6 @@ _cogl_context_free (CoglContext *context) _cogl_sampler_cache_free (context->sampler_cache); - _cogl_destroy_texture_units (); - g_ptr_array_free (context->uniform_names, TRUE); g_hash_table_destroy (context->uniform_name_hash); @@ -623,15 +428,17 @@ _cogl_context_free (CoglContext *context) g_byte_array_free (context->buffer_map_fallback_array, TRUE); + driver->context_deinit (context); + cogl_object_unref (context->display); - free (context); + g_free (context); } CoglContext * _cogl_context_get_default (void) { - CoglError *error = NULL; + GError *error = NULL; /* Create if doesn't exist yet */ if (_cogl_context == NULL) { @@ -640,7 +447,7 @@ _cogl_context_get_default (void) { g_warning ("Failed to create default context: %s", error->message); - cogl_error_free (error); + g_error_free (error); } } @@ -659,9 +466,9 @@ cogl_context_get_renderer (CoglContext *context) return context->display->renderer; } -CoglBool +gboolean _cogl_context_update_features (CoglContext *context, - CoglError **error) + GError **error) { return context->driver_vtable->update_features (context, error); } @@ -701,7 +508,7 @@ _cogl_context_get_gl_extensions (CoglContext *context) context->glGetIntegerv (GL_NUM_EXTENSIONS, &num_extensions); - ret = malloc (sizeof (char *) * (num_extensions + 1)); + ret = g_malloc (sizeof (char *) * (num_extensions + 1)); for (i = 0; i < num_extensions; i++) { @@ -721,11 +528,9 @@ _cogl_context_get_gl_extensions (CoglContext *context) ret = g_strsplit (all_extensions, " ", 0 /* max tokens */); } - if ((env_disabled_extensions = g_getenv ("COGL_DISABLE_GL_EXTENSIONS")) - || _cogl_config_disable_gl_extensions) + if ((env_disabled_extensions = g_getenv ("COGL_DISABLE_GL_EXTENSIONS"))) { char **split_env_disabled_extensions; - char **split_conf_disabled_extensions; char **src, **dst; if (env_disabled_extensions) @@ -736,14 +541,6 @@ _cogl_context_get_gl_extensions (CoglContext *context) else split_env_disabled_extensions = NULL; - if (_cogl_config_disable_gl_extensions) - split_conf_disabled_extensions = - g_strsplit (_cogl_config_disable_gl_extensions, - ",", - 0 /* no max tokens */); - else - split_conf_disabled_extensions = NULL; - for (dst = ret, src = ret; *src; src++) @@ -754,16 +551,12 @@ _cogl_context_get_gl_extensions (CoglContext *context) for (d = split_env_disabled_extensions; *d; d++) if (!strcmp (*src, *d)) goto disabled; - if (split_conf_disabled_extensions) - for (d = split_conf_disabled_extensions; *d; d++) - if (!strcmp (*src, *d)) - goto disabled; *(dst++) = *src; continue; disabled: - free (*src); + g_free (*src); continue; } @@ -771,8 +564,6 @@ _cogl_context_get_gl_extensions (CoglContext *context) if (split_env_disabled_extensions) g_strfreev (split_env_disabled_extensions); - if (split_conf_disabled_extensions) - g_strfreev (split_conf_disabled_extensions); } return ret; @@ -785,8 +576,6 @@ _cogl_context_get_gl_version (CoglContext *context) if ((version_override = g_getenv ("COGL_OVERRIDE_GL_VERSION"))) return version_override; - else if (_cogl_config_override_gl_version) - return _cogl_config_override_gl_version; else return (const char *) context->glGetString (GL_VERSION); diff --git a/cogl/cogl/cogl-context.h b/cogl/cogl/cogl-context.h index add575b49..ed0923d0f 100644 --- a/cogl/cogl/cogl-context.h +++ b/cogl/cogl/cogl-context.h @@ -48,7 +48,7 @@ typedef struct _CoglContext CoglContext; #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS /** * SECTION:cogl-context @@ -99,12 +99,13 @@ COGL_BEGIN_DECLS * * Returns: a #GType that can be used with the GLib type system. */ +COGL_EXPORT GType cogl_context_get_gtype (void); /** - * cogl_context_new: (constructor) + * cogl_context_new: (constructor) (skip) * @display: (allow-none): A #CoglDisplay pointer - * @error: A CoglError return location. + * @error: A GError return location. * * Creates a new #CoglContext which acts as an application sandbox * for any state objects that are allocated. @@ -113,12 +114,12 @@ GType cogl_context_get_gtype (void); * Since: 1.8 * Stability: unstable */ -CoglContext * +COGL_EXPORT CoglContext * cogl_context_new (CoglDisplay *display, - CoglError **error); + GError **error); /** - * cogl_context_get_display: + * cogl_context_get_display: (skip) * @context: A #CoglContext pointer * * Retrieves the #CoglDisplay that is internally associated with the @@ -132,11 +133,11 @@ cogl_context_new (CoglDisplay *display, * Since: 1.8 * Stability: unstable */ -CoglDisplay * +COGL_EXPORT CoglDisplay * cogl_context_get_display (CoglContext *context); /** - * cogl_context_get_renderer: + * cogl_context_get_renderer: (skip) * @context: A #CoglContext pointer * * Retrieves the #CoglRenderer that is internally associated with the @@ -151,7 +152,7 @@ cogl_context_get_display (CoglContext *context); * Since: 1.16 * Stability: unstable */ -CoglRenderer * +COGL_EXPORT CoglRenderer * cogl_context_get_renderer (CoglContext *context); /** @@ -166,7 +167,7 @@ cogl_context_get_renderer (CoglContext *context); * Since: 1.10 * Stability: Unstable */ -CoglBool +COGL_EXPORT gboolean cogl_is_context (void *object); /* XXX: not guarded by the EXPERIMENTAL_API defines to avoid @@ -174,58 +175,22 @@ cogl_is_context (void *object); * experimental since it's only useable with experimental API... */ /** * CoglFeatureID: - * @COGL_FEATURE_ID_TEXTURE_NPOT_BASIC: The hardware supports non power - * of two textures, but you also need to check the - * %COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP and %COGL_FEATURE_ID_TEXTURE_NPOT_REPEAT - * features to know if the hardware supports npot texture mipmaps - * or repeat modes other than - * %COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE respectively. - * @COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP: Mipmapping is supported in - * conjuntion with non power of two textures. - * @COGL_FEATURE_ID_TEXTURE_NPOT_REPEAT: Repeat modes other than - * %COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE are supported by the - * hardware. - * @COGL_FEATURE_ID_TEXTURE_NPOT: Non power of two textures are supported - * by the hardware. This is a equivalent to the - * %COGL_FEATURE_ID_TEXTURE_NPOT_BASIC, %COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP - * and %COGL_FEATURE_ID_TEXTURE_NPOT_REPEAT features combined. - * @COGL_FEATURE_ID_TEXTURE_RECTANGLE: Support for rectangular - * textures with non-normalized texture coordinates. * @COGL_FEATURE_ID_TEXTURE_RG: Support for * %COGL_TEXTURE_COMPONENTS_RG as the internal components of a * texture. - * @COGL_FEATURE_ID_TEXTURE_3D: 3D texture support - * @COGL_FEATURE_ID_OFFSCREEN: Offscreen rendering support - * @COGL_FEATURE_ID_OFFSCREEN_MULTISAMPLE: Multisample support for - * offscreen framebuffers - * @COGL_FEATURE_ID_ONSCREEN_MULTIPLE: Multiple onscreen framebuffers - * supported. - * @COGL_FEATURE_ID_GLSL: GLSL support - * @COGL_FEATURE_ID_ARBFP: ARBFP support * @COGL_FEATURE_ID_UNSIGNED_INT_INDICES: Set if * %COGL_INDICES_TYPE_UNSIGNED_INT is supported in * cogl_indices_new(). - * @COGL_FEATURE_ID_DEPTH_RANGE: cogl_pipeline_set_depth_range() support - * @COGL_FEATURE_ID_POINT_SPRITE: Whether - * cogl_pipeline_set_layer_point_sprite_coords_enabled() is supported. - * @COGL_FEATURE_ID_PER_VERTEX_POINT_SIZE: Whether cogl_point_size_in - * can be used as an attribute to set a per-vertex point size. * @COGL_FEATURE_ID_MAP_BUFFER_FOR_READ: Whether cogl_buffer_map() is * supported with CoglBufferAccess including read support. * @COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE: Whether cogl_buffer_map() is * supported with CoglBufferAccess including write support. - * @COGL_FEATURE_ID_MIRRORED_REPEAT: Whether - * %COGL_PIPELINE_WRAP_MODE_MIRRORED_REPEAT is supported. * @COGL_FEATURE_ID_SWAP_BUFFERS_EVENT: * Available if the window system supports reporting an event * for swap buffer completions. * @COGL_FEATURE_ID_BUFFER_AGE: Available if the age of #CoglOnscreen back * buffers are tracked and so cogl_onscreen_get_buffer_age() can be * expected to return age values other than 0. - * @COGL_FEATURE_ID_GLES2_CONTEXT: Whether creating new GLES2 contexts is - * suported. - * @COGL_FEATURE_ID_DEPTH_TEXTURE: Whether #CoglFramebuffer support rendering - * the depth buffer to a texture. * @COGL_FEATURE_ID_PRESENTATION_TIME: Whether frame presentation * time stamps will be recorded in #CoglFrameInfo objects. * @@ -237,29 +202,12 @@ cogl_is_context (void *object); */ typedef enum _CoglFeatureID { - COGL_FEATURE_ID_TEXTURE_NPOT_BASIC = 1, - COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP, - COGL_FEATURE_ID_TEXTURE_NPOT_REPEAT, - COGL_FEATURE_ID_TEXTURE_NPOT, - COGL_FEATURE_ID_TEXTURE_RECTANGLE, - COGL_FEATURE_ID_TEXTURE_3D, - COGL_FEATURE_ID_GLSL, - COGL_FEATURE_ID_ARBFP, - COGL_FEATURE_ID_OFFSCREEN, - COGL_FEATURE_ID_OFFSCREEN_MULTISAMPLE, - COGL_FEATURE_ID_ONSCREEN_MULTIPLE, COGL_FEATURE_ID_UNSIGNED_INT_INDICES, - COGL_FEATURE_ID_DEPTH_RANGE, - COGL_FEATURE_ID_POINT_SPRITE, COGL_FEATURE_ID_MAP_BUFFER_FOR_READ, COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE, - COGL_FEATURE_ID_MIRRORED_REPEAT, COGL_FEATURE_ID_SWAP_BUFFERS_EVENT, - COGL_FEATURE_ID_GLES2_CONTEXT, - COGL_FEATURE_ID_DEPTH_TEXTURE, COGL_FEATURE_ID_PRESENTATION_TIME, COGL_FEATURE_ID_FENCE, - COGL_FEATURE_ID_PER_VERTEX_POINT_SIZE, COGL_FEATURE_ID_TEXTURE_RG, COGL_FEATURE_ID_BUFFER_AGE, COGL_FEATURE_ID_TEXTURE_EGL_IMAGE_EXTERNAL, @@ -287,7 +235,7 @@ typedef enum _CoglFeatureID * Since: 1.10 * Stability: unstable */ -CoglBool +COGL_EXPORT gboolean cogl_has_feature (CoglContext *context, CoglFeatureID feature); /** @@ -307,7 +255,7 @@ cogl_has_feature (CoglContext *context, CoglFeatureID feature); * Since: 1.10 * Stability: unstable */ -CoglBool +COGL_EXPORT gboolean cogl_has_features (CoglContext *context, ...); /** @@ -336,7 +284,7 @@ typedef void (*CoglFeatureCallback) (CoglFeatureID feature, void *user_data); * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_foreach_feature (CoglContext *context, CoglFeatureCallback callback, void *user_data); @@ -361,7 +309,7 @@ cogl_foreach_feature (CoglContext *context, * Since: 1.14 * Stability: unstable */ -int64_t +COGL_EXPORT int64_t cogl_get_clock_time (CoglContext *context); /** @@ -403,10 +351,10 @@ typedef enum _CoglGraphicsResetStatus * * Return value: a #CoglGraphicsResetStatus */ -CoglGraphicsResetStatus +COGL_EXPORT CoglGraphicsResetStatus cogl_get_graphics_reset_status (CoglContext *context); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_CONTEXT_H__ */ diff --git a/cogl/cogl/cogl-debug-options.h b/cogl/cogl/cogl-debug-options.h index 0f3b30731..25c70d766 100644 --- a/cogl/cogl/cogl-debug-options.h +++ b/cogl/cogl/cogl-debug-options.h @@ -94,11 +94,6 @@ OPT (DISABLE_BATCHING, "disable-batching", N_("Disable Journal batching"), N_("Disable batching of geometry in the Cogl Journal.")) -OPT (DISABLE_VBOS, - N_("Root Cause"), - "disable-vbos", - N_("Disable GL Vertex Buffers"), - N_("Disable use of OpenGL vertex buffer objects")) OPT (DISABLE_PBOS, N_("Root Cause"), "disable-pbos", @@ -130,32 +125,11 @@ OPT (DISABLE_TEXTURING, "disable-texturing", N_("Disable texturing"), N_("Disable texturing any primitives")) -OPT (DISABLE_ARBFP, - N_("Root Cause"), - "disable-arbfp", - N_("Disable arbfp"), - N_("Disable use of ARB fragment programs")) -OPT (DISABLE_FIXED, - N_("Root Cause"), - "disable-fixed", - N_("Disable fixed"), - N_("Disable use of the fixed function pipeline backend")) -OPT (DISABLE_GLSL, - N_("Root Cause"), - "disable-glsl", - N_("Disable GLSL"), - N_("Disable use of GLSL")) OPT (DISABLE_BLENDING, N_("Root Cause"), "disable-blending", N_("Disable blending"), N_("Disable use of blending")) -OPT (DISABLE_NPOT_TEXTURES, - N_("Root Cause"), - "disable-npot-textures", - N_("Disable non-power-of-two textures"), - N_("Makes Cogl think that the GL driver doesn't support NPOT textures " - "so that it will create sliced textures or textures with waste instead.")) OPT (DISABLE_SOFTWARE_CLIP, N_("Root Cause"), "disable-software-clip", @@ -165,7 +139,7 @@ OPT (SHOW_SOURCE, N_("Cogl Tracing"), "show-source", N_("Show source"), - N_("Show generated ARBfp/GLSL source code")) + N_("Show generated GLSL source code")) OPT (OPENGL, N_("Cogl Tracing"), "opengl", @@ -180,7 +154,7 @@ OPT (DISABLE_BLENDING, N_("Root Cause"), "disable-program-caches", N_("Disable program caches"), - N_("Disable fallback caches for arbfp and glsl programs")) + N_("Disable fallback caches for glsl programs")) OPT (DISABLE_FAST_READ_PIXEL, N_("Root Cause"), "disable-fast-read-pixel", diff --git a/cogl/cogl/cogl-debug.c b/cogl/cogl/cogl-debug.c index 1ef2fd037..3898ee125 100644 --- a/cogl/cogl/cogl-debug.c +++ b/cogl/cogl/cogl-debug.c @@ -28,9 +28,7 @@ * */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include @@ -72,18 +70,13 @@ static const int n_cogl_log_debug_keys = static const GDebugKey cogl_behavioural_debug_keys[] = { { "rectangles", COGL_DEBUG_RECTANGLES }, { "disable-batching", COGL_DEBUG_DISABLE_BATCHING }, - { "disable-vbos", COGL_DEBUG_DISABLE_VBOS }, { "disable-pbos", COGL_DEBUG_DISABLE_PBOS }, { "disable-software-transform", COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM }, { "dump-atlas-image", COGL_DEBUG_DUMP_ATLAS_IMAGE }, { "disable-atlas", COGL_DEBUG_DISABLE_ATLAS }, { "disable-shared-atlas", COGL_DEBUG_DISABLE_SHARED_ATLAS }, { "disable-texturing", COGL_DEBUG_DISABLE_TEXTURING}, - { "disable-arbfp", COGL_DEBUG_DISABLE_ARBFP}, - { "disable-fixed", COGL_DEBUG_DISABLE_FIXED}, - { "disable-glsl", COGL_DEBUG_DISABLE_GLSL}, { "disable-blending", COGL_DEBUG_DISABLE_BLENDING}, - { "disable-npot-textures", COGL_DEBUG_DISABLE_NPOT_TEXTURES}, { "wireframe", COGL_DEBUG_WIREFRAME}, { "disable-software-clip", COGL_DEBUG_DISABLE_SOFTWARE_CLIP}, { "disable-program-caches", COGL_DEBUG_DISABLE_PROGRAM_CACHES}, @@ -97,7 +90,7 @@ GHashTable *_cogl_debug_instances; static void _cogl_parse_debug_string_for_keys (const char *value, - CoglBool enable, + gboolean enable, const GDebugKey *keys, unsigned int nkeys) { @@ -155,8 +148,8 @@ _cogl_parse_debug_string_for_keys (const char *value, void _cogl_parse_debug_string (const char *value, - CoglBool enable, - CoglBool ignore_help) + gboolean enable, + gboolean ignore_help) { if (ignore_help && strcmp (value, "help") == 0) return; @@ -214,7 +207,7 @@ _cogl_parse_debug_string (const char *value, } #ifdef COGL_ENABLE_DEBUG -static CoglBool +static gboolean cogl_arg_debug_cb (const char *key, const char *value, void *user_data) @@ -225,7 +218,7 @@ cogl_arg_debug_cb (const char *key, return TRUE; } -static CoglBool +static gboolean cogl_arg_no_debug_cb (const char *key, const char *value, void *user_data) @@ -271,7 +264,7 @@ _cogl_debug_check_environment (void) } } -static CoglBool +static gboolean pre_parse_hook (GOptionContext *context, GOptionGroup *group, void *data, diff --git a/cogl/cogl/cogl-debug.h b/cogl/cogl/cogl-debug.h index 4eaad0917..bcbce9791 100644 --- a/cogl/cogl/cogl-debug.h +++ b/cogl/cogl/cogl-debug.h @@ -37,9 +37,10 @@ #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS -typedef enum { +typedef enum +{ COGL_DEBUG_SLICING, COGL_DEBUG_OFFSCREEN, COGL_DEBUG_DRAW, @@ -48,7 +49,6 @@ typedef enum { COGL_DEBUG_OBJECT, COGL_DEBUG_BLEND_STRINGS, COGL_DEBUG_DISABLE_BATCHING, - COGL_DEBUG_DISABLE_VBOS, COGL_DEBUG_DISABLE_PBOS, COGL_DEBUG_JOURNAL, COGL_DEBUG_BATCHING, @@ -60,14 +60,10 @@ typedef enum { COGL_DEBUG_DISABLE_SHARED_ATLAS, COGL_DEBUG_OPENGL, COGL_DEBUG_DISABLE_TEXTURING, - COGL_DEBUG_DISABLE_ARBFP, - COGL_DEBUG_DISABLE_FIXED, - COGL_DEBUG_DISABLE_GLSL, COGL_DEBUG_SHOW_SOURCE, COGL_DEBUG_DISABLE_BLENDING, COGL_DEBUG_TEXTURE_PIXMAP, COGL_DEBUG_BITMAP, - COGL_DEBUG_DISABLE_NPOT_TEXTURES, COGL_DEBUG_WIREFRAME, COGL_DEBUG_DISABLE_SOFTWARE_CLIP, COGL_DEBUG_DISABLE_PROGRAM_CACHES, @@ -79,10 +75,12 @@ typedef enum { COGL_DEBUG_N_FLAGS } CoglDebugFlags; -extern GHashTable *_cogl_debug_instances; +COGL_EXPORT +GHashTable *_cogl_debug_instances; #define COGL_DEBUG_N_LONGS COGL_FLAGS_N_LONGS_FOR_SIZE (COGL_DEBUG_N_FLAGS) -extern unsigned long _cogl_debug_flags[COGL_DEBUG_N_LONGS]; +COGL_EXPORT +unsigned long _cogl_debug_flags[COGL_DEBUG_N_LONGS]; #define COGL_DEBUG_ENABLED(flag) \ COGL_FLAGS_GET (_cogl_debug_flags, flag) @@ -104,7 +102,7 @@ extern unsigned long _cogl_debug_flags[COGL_DEBUG_N_LONGS]; if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_##type))) { \ char *_fmt = g_strdup_printf (__VA_ARGS__); \ _cogl_profile_trace_message ("[" #type "] " G_STRLOC " & %s", _fmt);\ - free (_fmt); \ + g_free (_fmt); \ } } G_STMT_END #endif /* __GNUC__ */ @@ -114,10 +112,10 @@ _cogl_debug_check_environment (void); void _cogl_parse_debug_string (const char *value, - CoglBool enable, - CoglBool ignore_help); + gboolean enable, + gboolean ignore_help); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_DEBUG_H__ */ diff --git a/cogl/cogl/cogl-defines.h.in b/cogl/cogl/cogl-defines.h.in index eb3ad9268..a438a9622 100644 --- a/cogl/cogl/cogl-defines.h.in +++ b/cogl/cogl/cogl-defines.h.in @@ -37,9 +37,4 @@ @COGL_DEFINES@ -#define COGL_VERSION_MAJOR_INTERNAL 1 -#define COGL_VERSION_MINOR_INTERNAL @COGL_1_MINOR_VERSION@ -#define COGL_VERSION_MICRO_INTERNAL @COGL_1_MICRO_VERSION@ -#define COGL_VERSION_STRING_INTERNAL "@COGL_1_VERSION@" - #endif diff --git a/cogl/cogl/driver/gl/cogl-pipeline-fragend-fixed-private.h b/cogl/cogl/cogl-defines.h.meson similarity index 63% rename from cogl/cogl/driver/gl/cogl-pipeline-fragend-fixed-private.h rename to cogl/cogl/cogl-defines.h.meson index 6f259f998..4c9535239 100644 --- a/cogl/cogl/driver/gl/cogl-pipeline-fragend-fixed-private.h +++ b/cogl/cogl/cogl-defines.h.meson @@ -3,7 +3,7 @@ * * A Low Level GPU Graphics and Utilities API * - * Copyright (C) 2010 Intel Corporation. + * Copyright (C) 2007,2008,2009,2010 Intel Corporation. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -25,18 +25,26 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * - * - * - * Authors: - * Robert Bragg */ -#ifndef __COGL_PIPELINE_FRAGEND_FIXED_PRIVATE_H -#define __COGL_PIPELINE_FRAGEND_FIXED_PRIVATE_H - -#include "cogl-pipeline-private.h" +#include -extern const CoglPipelineFragend _cogl_pipeline_fixed_fragend; +#define COGL_SYSDEF_POLLIN POLLIN +#define COGL_SYSDEF_POLLPRI POLLPRI +#define COGL_SYSDEF_POLLOUT POLLOUT +#define COGL_SYSDEF_POLLERR POLLERR +#define COGL_SYSDEF_POLLHUP POLLHUP +#define COGL_SYSDEF_POLLNVAL POLLNVAL -#endif /* __COGL_PIPELINE_FRAGEND_FIXED_PRIVATE_H */ +#mesondefine COGL_HAS_GL +#mesondefine CLUTTER_COGL_HAS_GL +#mesondefine COGL_HAS_GLX_SUPPORT +#mesondefine COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT +#mesondefine COGL_HAS_EGL_PLATFORM_XLIB_SUPPORT +#mesondefine COGL_HAS_EGL_SUPPORT +#mesondefine COGL_HAS_X11 +#mesondefine COGL_HAS_X11_SUPPORT +#mesondefine COGL_HAS_XLIB +#mesondefine COGL_HAS_XLIB_SUPPORT +#mesondefine COGL_HAS_TRACING diff --git a/cogl/cogl/cogl-deprecated.h b/cogl/cogl/cogl-deprecated.h deleted file mode 100644 index ca56fa18a..000000000 --- a/cogl/cogl/cogl-deprecated.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef COGL_DEPRECATED_H - -#define cogl_color cogl_color_REPLACED_BY_cogl_set_source_color -#define cogl_enable_depth_test cogl_enable_depth_test_RENAMED_TO_cogl_set_depth_test_enabled -#define cogl_enable_backface_culling cogl_enable_backface_culling_RENAMED_TO_cogl_set_backface_culling_enabled - -#define cogl_texture_rectangle cogl_texture_rectangle_REPLACE_BY_cogl_set_source_texture_AND_cogl_rectangle_with_texture_coords - -#define cogl_texture_multiple_rectangles cogl_texture_multiple_rectangles_REPLACED_BY_cogl_set_source_texture_AND_cogl_rectangles_with_texture_coords - -#define cogl_texture_polygon cogl_texture_polygon_REPLACED_BY_cogl_set_source_texture_AND_cogl_polygon - -#endif diff --git a/cogl/cogl/cogl-depth-state.c b/cogl/cogl/cogl-depth-state.c index 8346d4c6c..a8b141d49 100644 --- a/cogl/cogl/cogl-depth-state.c +++ b/cogl/cogl/cogl-depth-state.c @@ -29,9 +29,7 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-util.h" #include "cogl-depth-state-private.h" @@ -52,31 +50,31 @@ cogl_depth_state_init (CoglDepthState *state) void cogl_depth_state_set_test_enabled (CoglDepthState *state, - CoglBool enabled) + gboolean enabled) { - _COGL_RETURN_IF_FAIL (state->magic == COGL_DEPTH_STATE_MAGIC); + g_return_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC); state->test_enabled = enabled; } -CoglBool +gboolean cogl_depth_state_get_test_enabled (CoglDepthState *state) { - _COGL_RETURN_VAL_IF_FAIL (state->magic == COGL_DEPTH_STATE_MAGIC, FALSE); + g_return_val_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC, FALSE); return state->test_enabled; } void cogl_depth_state_set_write_enabled (CoglDepthState *state, - CoglBool enabled) + gboolean enabled) { - _COGL_RETURN_IF_FAIL (state->magic == COGL_DEPTH_STATE_MAGIC); + g_return_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC); state->write_enabled = enabled; } -CoglBool +gboolean cogl_depth_state_get_write_enabled (CoglDepthState *state) { - _COGL_RETURN_VAL_IF_FAIL (state->magic == COGL_DEPTH_STATE_MAGIC, FALSE); + g_return_val_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC, FALSE); return state->write_enabled; } @@ -84,14 +82,14 @@ void cogl_depth_state_set_test_function (CoglDepthState *state, CoglDepthTestFunction function) { - _COGL_RETURN_IF_FAIL (state->magic == COGL_DEPTH_STATE_MAGIC); + g_return_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC); state->test_function = function; } CoglDepthTestFunction cogl_depth_state_get_test_function (CoglDepthState *state) { - _COGL_RETURN_VAL_IF_FAIL (state->magic == COGL_DEPTH_STATE_MAGIC, FALSE); + g_return_val_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC, FALSE); return state->test_function; } @@ -100,7 +98,7 @@ cogl_depth_state_set_range (CoglDepthState *state, float near, float far) { - _COGL_RETURN_IF_FAIL (state->magic == COGL_DEPTH_STATE_MAGIC); + g_return_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC); state->range_near = near; state->range_far = far; } @@ -110,7 +108,7 @@ cogl_depth_state_get_range (CoglDepthState *state, float *near_out, float *far_out) { - _COGL_RETURN_IF_FAIL (state->magic == COGL_DEPTH_STATE_MAGIC); + g_return_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC); *near_out = state->range_near; *far_out = state->range_far; } diff --git a/cogl/cogl/cogl-depth-state.h b/cogl/cogl/cogl-depth-state.h index 581b96110..b3b240526 100644 --- a/cogl/cogl/cogl-depth-state.h +++ b/cogl/cogl/cogl-depth-state.h @@ -37,7 +37,7 @@ #ifndef __COGL_DEPTH_STATE_H__ #define __COGL_DEPTH_STATE_H__ -COGL_BEGIN_DECLS +G_BEGIN_DECLS /** * SECTION:cogl-depth-state @@ -54,9 +54,9 @@ typedef struct { /*< private >*/ uint32_t COGL_PRIVATE (magic); - CoglBool COGL_PRIVATE (test_enabled); + gboolean COGL_PRIVATE (test_enabled); CoglDepthTestFunction COGL_PRIVATE (test_function); - CoglBool COGL_PRIVATE (write_enabled); + gboolean COGL_PRIVATE (write_enabled); float COGL_PRIVATE (range_near); float COGL_PRIVATE (range_far); @@ -84,7 +84,7 @@ typedef struct { * Since: 2.0 * Stability: Unstable */ -void +COGL_EXPORT void cogl_depth_state_init (CoglDepthState *state); /** @@ -112,9 +112,9 @@ cogl_depth_state_init (CoglDepthState *state); * Since: 2.0 * Stability: Unstable */ -void +COGL_EXPORT void cogl_depth_state_set_test_enabled (CoglDepthState *state, - CoglBool enable); + gboolean enable); /** * cogl_depth_state_get_test_enabled: @@ -127,7 +127,7 @@ cogl_depth_state_set_test_enabled (CoglDepthState *state, * Since: 2.0 * Stability: Unstable */ -CoglBool +COGL_EXPORT gboolean cogl_depth_state_get_test_enabled (CoglDepthState *state); /** @@ -150,9 +150,9 @@ cogl_depth_state_get_test_enabled (CoglDepthState *state); * Since: 2.0 * Stability: Unstable */ -void +COGL_EXPORT void cogl_depth_state_set_write_enabled (CoglDepthState *state, - CoglBool enable); + gboolean enable); /** * cogl_depth_state_get_write_enabled: @@ -165,7 +165,7 @@ cogl_depth_state_set_write_enabled (CoglDepthState *state, * Since: 2.0 * Stability: Unstable */ -CoglBool +COGL_EXPORT gboolean cogl_depth_state_get_write_enabled (CoglDepthState *state); /** @@ -186,7 +186,7 @@ cogl_depth_state_get_write_enabled (CoglDepthState *state); * Since: 2.0 * Stability: Unstable */ -void +COGL_EXPORT void cogl_depth_state_set_test_function (CoglDepthState *state, CoglDepthTestFunction function); @@ -201,7 +201,7 @@ cogl_depth_state_set_test_function (CoglDepthState *state, * Since: 2.0 * Stability: Unstable */ -CoglDepthTestFunction +COGL_EXPORT CoglDepthTestFunction cogl_depth_state_get_test_function (CoglDepthState *state); /** @@ -225,13 +225,6 @@ cogl_depth_state_get_test_function (CoglDepthState *state); * mapped too although the range must still lye within the range [0, * 1]. * - * If your driver does not support this feature (for example you are - * using GLES 1 drivers) then if you don't use the default range - * values you will get an error reported when calling - * cogl_pipeline_set_depth_state (). You can check ahead of time for - * the %COGL_FEATURE_ID_DEPTH_RANGE feature with - * cogl_has_feature() to know if this function will succeed. - * * By default normalized device coordinate depth values are mapped to * the full range of depth buffer values, [0, 1]. * @@ -242,7 +235,7 @@ cogl_depth_state_get_test_function (CoglDepthState *state); * Since: 2.0 * Stability: Unstable */ -void +COGL_EXPORT void cogl_depth_state_set_range (CoglDepthState *state, float near_val, float far_val); @@ -260,11 +253,11 @@ cogl_depth_state_set_range (CoglDepthState *state, * Since: 2.0 * Stability: Unstable */ -void +COGL_EXPORT void cogl_depth_state_get_range (CoglDepthState *state, float *near_val, float *far_val); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_DEPTH_STATE_H__ */ diff --git a/cogl/cogl/cogl-display-private.h b/cogl/cogl/cogl-display-private.h index 9788435bb..74dfb8e59 100644 --- a/cogl/cogl/cogl-display-private.h +++ b/cogl/cogl/cogl-display-private.h @@ -40,7 +40,7 @@ struct _CoglDisplay { CoglObject _parent; - CoglBool setup; + gboolean setup; CoglRenderer *renderer; CoglOnscreenTemplate *onscreen_template; diff --git a/cogl/cogl/cogl-display.c b/cogl/cogl/cogl-display.c index 81d3d8458..5394dbf85 100644 --- a/cogl/cogl/cogl-display.c +++ b/cogl/cogl/cogl-display.c @@ -29,9 +29,7 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include @@ -40,11 +38,11 @@ #include "cogl-display-private.h" #include "cogl-renderer-private.h" -#include "cogl-winsys-private.h" #ifdef COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT #include "cogl-wayland-server.h" #endif #include "cogl-gtype-private.h" +#include "winsys/cogl-winsys-private.h" static void _cogl_display_free (CoglDisplay *display); @@ -89,7 +87,7 @@ cogl_display_new (CoglRenderer *renderer, CoglOnscreenTemplate *onscreen_template) { CoglDisplay *display = g_slice_new0 (CoglDisplay); - CoglError *error = NULL; + GError *error = NULL; _cogl_init (); @@ -121,7 +119,7 @@ void cogl_display_set_onscreen_template (CoglDisplay *display, CoglOnscreenTemplate *onscreen_template) { - _COGL_RETURN_IF_FAIL (display->setup == FALSE); + g_return_if_fail (display->setup == FALSE); if (onscreen_template) cogl_object_ref (onscreen_template); @@ -137,9 +135,9 @@ cogl_display_set_onscreen_template (CoglDisplay *display, display->onscreen_template = cogl_onscreen_template_new (NULL); } -CoglBool +gboolean cogl_display_setup (CoglDisplay *display, - CoglError **error) + GError **error) { const CoglWinsysVtable *winsys; @@ -160,7 +158,7 @@ void cogl_wayland_display_set_compositor_display (CoglDisplay *display, struct wl_display *wayland_display) { - _COGL_RETURN_IF_FAIL (display->setup == FALSE); + g_return_if_fail (display->setup == FALSE); display->wayland_compositor_display = wayland_display; } diff --git a/cogl/cogl/cogl-display.h b/cogl/cogl/cogl-display.h index 4c15dcc6f..098e436ae 100644 --- a/cogl/cogl/cogl-display.h +++ b/cogl/cogl/cogl-display.h @@ -42,7 +42,7 @@ #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS /** * SECTION:cogl-display @@ -75,6 +75,7 @@ typedef struct _CoglDisplay CoglDisplay; * * Returns: a #GType that can be used with the GLib type system. */ +COGL_EXPORT GType cogl_display_get_gtype (void); /** @@ -117,7 +118,7 @@ GType cogl_display_get_gtype (void); * Since: 1.10 * Stability: unstable */ -CoglDisplay * +COGL_EXPORT CoglDisplay * cogl_display_new (CoglRenderer *renderer, CoglOnscreenTemplate *onscreen_template); @@ -132,7 +133,7 @@ cogl_display_new (CoglRenderer *renderer, * Since: 1.10 * Stability: unstable */ -CoglRenderer * +COGL_EXPORT CoglRenderer * cogl_display_get_renderer (CoglDisplay *display); /** @@ -151,14 +152,14 @@ cogl_display_get_renderer (CoglDisplay *display); * Since: 1.16 * Stability: unstable */ -void +COGL_EXPORT void cogl_display_set_onscreen_template (CoglDisplay *display, CoglOnscreenTemplate *onscreen_template); /** * cogl_display_setup: * @display: a #CoglDisplay - * @error: return location for a #CoglError + * @error: return location for a #GError * * Explicitly sets up the given @display object. Use of this api is * optional since Cogl will internally setup the display if not done @@ -186,9 +187,9 @@ cogl_display_set_onscreen_template (CoglDisplay *display, * Since: 1.10 * Stability: unstable */ -CoglBool +COGL_EXPORT gboolean cogl_display_setup (CoglDisplay *display, - CoglError **error); + GError **error); /** * cogl_is_display: @@ -201,10 +202,10 @@ cogl_display_setup (CoglDisplay *display, * Since: 1.10 * Stability: unstable */ -CoglBool +COGL_EXPORT gboolean cogl_is_display (void *object); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_DISPLAY_H__ */ diff --git a/cogl/cogl/cogl-dma-buf-handle.c b/cogl/cogl/cogl-dma-buf-handle.c new file mode 100644 index 000000000..4a8f709f2 --- /dev/null +++ b/cogl/cogl/cogl-dma-buf-handle.c @@ -0,0 +1,94 @@ +/* + * Cogl + * + * A Low Level GPU Graphics and Utilities API + * + * Copyright (C) 2020 Endless, Inc. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Authors: + * Georges Basile Stavracas Neto + */ + +#include "cogl-config.h" + +#include "cogl-dma-buf-handle.h" +#include "cogl-object.h" + +#include + +struct _CoglDmaBufHandle +{ + CoglFramebuffer *framebuffer; + int dmabuf_fd; + gpointer user_data; + GDestroyNotify destroy_func; +}; + +CoglDmaBufHandle * +cogl_dma_buf_handle_new (CoglFramebuffer *framebuffer, + int dmabuf_fd, + gpointer user_data, + GDestroyNotify destroy_func) +{ + CoglDmaBufHandle *dmabuf_handle; + + g_assert (framebuffer); + g_assert (dmabuf_fd != -1); + + dmabuf_handle = g_new0 (CoglDmaBufHandle, 1); + dmabuf_handle->framebuffer = cogl_object_ref (framebuffer); + dmabuf_handle->dmabuf_fd = dmabuf_fd; + dmabuf_handle->user_data = user_data; + dmabuf_handle->destroy_func = destroy_func; + + return dmabuf_handle; +} + +void +cogl_dma_buf_handle_free (CoglDmaBufHandle *dmabuf_handle) +{ + g_return_if_fail (dmabuf_handle != NULL); + + g_clear_pointer (&dmabuf_handle->framebuffer, cogl_object_unref); + + if (dmabuf_handle->destroy_func) + g_clear_pointer (&dmabuf_handle->user_data, dmabuf_handle->destroy_func); + + if (dmabuf_handle->dmabuf_fd != -1) + close (dmabuf_handle->dmabuf_fd); + + g_free (dmabuf_handle); +} + +CoglFramebuffer * +cogl_dma_buf_handle_get_framebuffer (CoglDmaBufHandle *dmabuf_handle) +{ + return dmabuf_handle->framebuffer; +} + +int +cogl_dma_buf_handle_get_fd (CoglDmaBufHandle *dmabuf_handle) +{ + return dmabuf_handle->dmabuf_fd; +} + diff --git a/cogl/cogl/cogl-dma-buf-handle.h b/cogl/cogl/cogl-dma-buf-handle.h new file mode 100644 index 000000000..87a2ce2f1 --- /dev/null +++ b/cogl/cogl/cogl-dma-buf-handle.h @@ -0,0 +1,83 @@ +/* + * Cogl + * + * A Low Level GPU Graphics and Utilities API + * + * Copyright (C) 2020 Endless, Inc. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Authors: + * Georges Basile Stavracas Neto + */ + + +#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __COGL_DMA_BUF_HANDLE_H__ +#define __COGL_DMA_BUF_HANDLE_H__ + +#include +#include + +/** + * cogl_dma_buf_handle_new: (skip) + */ +COGL_EXPORT CoglDmaBufHandle * +cogl_dma_buf_handle_new (CoglFramebuffer *framebuffer, + int dmabuf_fd, + gpointer data, + GDestroyNotify destroy_func); + +/** + * cogl_dma_buf_handle_free: (skip) + * + * Releases @dmabuf_handle; it is a programming error to release + * an already released handle. + */ +COGL_EXPORT void +cogl_dma_buf_handle_free (CoglDmaBufHandle *dmabuf_handle); + +/** + * cogl_dma_buf_handle_get_framebuffer: (skip) + * + * Retrieves the #CoglFramebuffer, backed by an exported DMABuf buffer, + * of @dmabuf_handle. + * + * Returns: (transfer none): a #CoglFramebuffer + */ +COGL_EXPORT CoglFramebuffer * +cogl_dma_buf_handle_get_framebuffer (CoglDmaBufHandle *dmabuf_handle); + +/** + * cogl_dma_buf_handle_get_fd: (skip) + * + * Retrieves the file descriptor of @dmabuf_handle. + * + * Returns: a valid file descriptor + */ +COGL_EXPORT int +cogl_dma_buf_handle_get_fd (CoglDmaBufHandle *dmabuf_handle); + + +#endif /* __COGL_DMA_BUF_HANDLE_H__ */ diff --git a/cogl/cogl/cogl-driver.h b/cogl/cogl/cogl-driver.h index 85aa0d870..5dcecf862 100644 --- a/cogl/cogl/cogl-driver.h +++ b/cogl/cogl/cogl-driver.h @@ -40,9 +40,15 @@ typedef struct _CoglDriverVtable CoglDriverVtable; struct _CoglDriverVtable { + gboolean + (* context_init) (CoglContext *context); + + void + (* context_deinit) (CoglContext *context); + /* TODO: factor this out since this is OpenGL specific and * so can be ignored by non-OpenGL drivers. */ - CoglBool + gboolean (* pixel_format_from_gl_internal) (CoglContext *context, GLenum gl_int_format, CoglPixelFormat *out_format); @@ -55,21 +61,14 @@ struct _CoglDriverVtable GLenum *out_glintformat, GLenum *out_glformat, GLenum *out_gltype); - CoglPixelFormat - (* pixel_format_to_gl_with_target) (CoglContext *context, - CoglPixelFormat format, - CoglPixelFormat target_format, - GLenum *out_glintformat, - GLenum *out_glformat, - GLenum *out_gltype); - - CoglBool + + gboolean (* update_features) (CoglContext *context, - CoglError **error); + GError **error); - CoglBool + gboolean (* offscreen_allocate) (CoglOffscreen *offscreen, - CoglError **error); + GError **error); void (* offscreen_free) (CoglOffscreen *offscreen); @@ -94,6 +93,9 @@ struct _CoglDriverVtable void (* framebuffer_finish) (CoglFramebuffer *framebuffer); + void + (* framebuffer_flush) (CoglFramebuffer *framebuffer); + void (* framebuffer_discard_buffers) (CoglFramebuffer *framebuffer, unsigned long buffers); @@ -119,13 +121,13 @@ struct _CoglDriverVtable int n_attributes, CoglDrawFlags flags); - CoglBool + gboolean (* framebuffer_read_pixels_into_bitmap) (CoglFramebuffer *framebuffer, int x, int y, CoglReadPixelsFlags source, CoglBitmap *bitmap, - CoglError **error); + GError **error); /* Destroys any driver specific resources associated with the given * 2D texture. */ @@ -135,7 +137,7 @@ struct _CoglDriverVtable /* Returns TRUE if the driver can support creating a 2D texture with * the given geometry and specified internal format. */ - CoglBool + gboolean (* texture_2d_can_create) (CoglContext *ctx, int width, int height, @@ -151,9 +153,9 @@ struct _CoglDriverVtable /* Allocates (uninitialized) storage for the given texture according * to the configured size and format of the texture */ - CoglBool + gboolean (* texture_2d_allocate) (CoglTexture *tex, - CoglError **error); + GError **error); /* Initialize the specified region of storage of the given texture * with the contents of the specified framebuffer region @@ -187,7 +189,7 @@ struct _CoglDriverVtable * Since this may need to create the underlying storage first * it may throw a NO_MEMORY error. */ - CoglBool + gboolean (* texture_2d_copy_from_bitmap) (CoglTexture2D *tex_2d, int src_x, int src_y, @@ -197,7 +199,10 @@ struct _CoglDriverVtable int dst_x, int dst_y, int level, - CoglError **error); + GError **error); + + gboolean + (* texture_2d_is_get_data_supported) (CoglTexture2D *tex_2d); /* Reads back the full contents of the given texture and write it to * @data in the given @format and with the given @rowstride. @@ -243,7 +248,7 @@ struct _CoglDriverVtable size_t size, CoglBufferAccess access, CoglBufferMapHint hints, - CoglError **error); + GError **error); /* Unmaps a buffer */ void @@ -251,17 +256,18 @@ struct _CoglDriverVtable /* Uploads data to the buffer without needing to map it necessarily */ - CoglBool + gboolean (* buffer_set_data) (CoglBuffer *buffer, unsigned int offset, const void *data, unsigned int size, - CoglError **error); + GError **error); }; #define COGL_DRIVER_ERROR (_cogl_driver_error_quark ()) -typedef enum { /*< prefix=COGL_DRIVER_ERROR >*/ +typedef enum /*< prefix=COGL_DRIVER_ERROR >*/ +{ COGL_DRIVER_ERROR_UNKNOWN_VERSION, COGL_DRIVER_ERROR_INVALID_VERSION, COGL_DRIVER_ERROR_NO_SUITABLE_DRIVER_FOUND, diff --git a/cogl/cogl/cogl-egl.h b/cogl/cogl/cogl-egl.h index 787feabf3..07dac799b 100644 --- a/cogl/cogl/cogl-egl.h +++ b/cogl/cogl/cogl-egl.h @@ -58,7 +58,7 @@ #include #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS /** * cogl_egl_context_get_egl_display: @@ -76,30 +76,10 @@ COGL_BEGIN_DECLS * Since: 1.8 * Stability: unstable */ -EGLDisplay +COGL_EXPORT EGLDisplay cogl_egl_context_get_egl_display (CoglContext *context); -/** - * cogl_egl_context_get_egl_context: - * @context: A #CoglContext pointer - * - * If you have done a runtime check to determine that Cogl is using - * EGL internally then this API can be used to retrieve the EGLContext - * handle that was setup internally. The result is undefined if Cogl - * is not using EGL. - * - * Note: The current window system backend can be checked using - * cogl_renderer_get_winsys_id(). - * - * Return value: The internally setup EGLDisplay handle. - * Since: 1.18 - * Stability: unstable - */ -EGLContext -cogl_egl_context_get_egl_context (CoglContext *context); - - -COGL_END_DECLS +G_END_DECLS /* The gobject introspection scanner seems to parse public headers in * isolation which means we need to be extra careful about how we diff --git a/cogl/cogl/cogl-error-private.h b/cogl/cogl/cogl-error-private.h deleted file mode 100644 index 382fc449f..000000000 --- a/cogl/cogl/cogl-error-private.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef __COGL_ERROR_PRIVATE_H__ -#define __COGL_ERROR_PRIVATE_H__ - -#include "cogl-error.h" - -void -_cogl_set_error (CoglError **error, - uint32_t domain, - int code, - const char *format, - ...) G_GNUC_PRINTF (4, 5); - -void -_cogl_set_error_literal (CoglError **error, - uint32_t domain, - int code, - const char *message); - -void -_cogl_propagate_error (CoglError **dest, - CoglError *src); - -void -_cogl_propagate_gerror (CoglError **dest, - GError *src); - -#define _cogl_clear_error(X) g_clear_error ((GError **)X) - -#endif /* __COGL_ERROR_PRIVATE_H__ */ diff --git a/cogl/cogl/cogl-error.c b/cogl/cogl/cogl-error.c deleted file mode 100644 index 623ab1b86..000000000 --- a/cogl/cogl/cogl-error.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg - */ - -#ifdef HAVE_CONFIG_H -#include "cogl-config.h" -#endif - -#include "cogl-types.h" -#include "cogl-util.h" -#include "cogl-error-private.h" - -#include - -void -cogl_error_free (CoglError *error) -{ - g_error_free ((GError *)error); -} - -CoglError * -cogl_error_copy (CoglError *error) -{ - return (CoglError *)g_error_copy ((GError *)error); -} - -CoglBool -cogl_error_matches (CoglError *error, - uint32_t domain, - int code) -{ - return g_error_matches ((GError *)error, domain, code); -} - -#define ERROR_OVERWRITTEN_WARNING \ - "CoglError set over the top of a previous CoglError or " \ - "uninitialized memory.\nThis indicates a bug in someone's " \ - "code. You must ensure an error is NULL before it's set.\n" \ - "The overwriting error message was: %s" - -void -_cogl_set_error (CoglError **error, - uint32_t domain, - int code, - const char *format, - ...) -{ - GError *new; - - va_list args; - - va_start (args, format); - - if (error == NULL) - { - g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, format, args); - va_end (args); - return; - } - - new = g_error_new_valist (domain, code, format, args); - va_end (args); - - if (*error == NULL) - *error = (CoglError *)new; - else - g_warning (ERROR_OVERWRITTEN_WARNING, new->message); -} - -void -_cogl_set_error_literal (CoglError **error, - uint32_t domain, - int code, - const char *message) -{ - _cogl_set_error (error, domain, code, "%s", message); -} - -void -_cogl_propagate_error (CoglError **dest, - CoglError *src) -{ - _COGL_RETURN_IF_FAIL (src != NULL); - - if (dest == NULL) - { - g_log (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "%s", src->message); - cogl_error_free (src); - } - else if (*dest) - g_warning (ERROR_OVERWRITTEN_WARNING, src->message); - else - *dest = src; -} - -void -_cogl_propagate_gerror (CoglError **dest, - GError *src) -{ - _cogl_propagate_error (dest, (CoglError *) src); -} diff --git a/cogl/cogl/cogl-error.h b/cogl/cogl/cogl-error.h deleted file mode 100644 index eddec357f..000000000 --- a/cogl/cogl/cogl-error.h +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL_ERROR_H__ -#define __COGL_ERROR_H__ - -#include "cogl-types.h" - -COGL_BEGIN_DECLS - -/** - * SECTION:cogl-error - * @short_description: A way for Cogl to throw exceptions - * - * As a general rule Cogl shields non-recoverable errors from - * developers, such as most heap allocation failures (unless for - * exceptionally large resources which we might reasonably expect to - * fail) and this reduces the burden on developers. - * - * There are some Cogl apis though that can fail for exceptional - * reasons that can also potentially be recovered from at runtime - * and for these apis we use a standard convention for reporting - * runtime recoverable errors. - * - * As an example if we look at the cogl_context_new() api which - * takes an error argument: - * |[ - * CoglContext * - * cogl_context_new (CoglDisplay *display, CoglError **error); - * ]| - * - * A caller interested in catching any runtime error when creating a - * new #CoglContext would pass the address of a #CoglError pointer - * that has first been initialized to %NULL as follows: - * - * |[ - * CoglError *error = NULL; - * CoglContext *context; - * - * context = cogl_context_new (NULL, &error); - * ]| - * - * The return status should usually be enough to determine if there - * was an error set (in this example we can check if context == %NULL) - * but if it's not possible to tell from the function's return status - * you can instead look directly at the error pointer which you - * initialized to %NULL. In this example we now check the error, - * report any error to the user, free the error and then simply - * abort without attempting to recover. - * - * |[ - * if (context == NULL) - * { - * fprintf (stderr, "Failed to create a Cogl context: %s\n", - * error->message); - * cogl_error_free (error); - * abort (); - * } - * ]| - * - * All Cogl APIs that accept an error argument can also be passed a - * %NULL pointer. In this case if an exceptional error condition is hit - * then Cogl will simply log the error message and abort the - * application. This can be compared to language execeptions where the - * developer has not attempted to catch the exception. This means the - * above example is essentially redundant because it's what Cogl would - * have done automatically and so, similarly, if your application has - * no way to recover from a particular error you might just as well - * pass a %NULL #CoglError pointer to save a bit of typing. - * - * If you are used to using the GLib API you will probably - * recognize that #CoglError is just like a #GError. In fact if Cogl - * has been built with --enable-glib then it is safe to cast a - * #CoglError to a #GError. - * - * An important detail to be aware of if you are used to using - * GLib's GError API is that Cogl deviates from the GLib GError - * conventions in one noteable way which is that a %NULL error pointer - * does not mean you want to ignore the details of an error, it means - * you are not trying to catch any exceptional errors the function might - * throw which will result in the program aborting with a log message - * if an error is thrown. - */ - -#define CoglError GError - -/** - * cogl_error_free: - * @error: A #CoglError thrown by the Cogl api - * - * Frees a #CoglError and associated resources. - */ -void -cogl_error_free (CoglError *error); - -/** - * cogl_error_copy: - * @error: A #CoglError thrown by the Cogl api - * - * Makes a copy of @error which can later be freed using - * cogl_error_free(). - * - * Return value: A newly allocated #CoglError initialized to match the - * contents of @error. - */ -CoglError * -cogl_error_copy (CoglError *error); - -/** - * cogl_error_matches: - * @error: A #CoglError thrown by the Cogl api or %NULL - * @domain: The error domain - * @code: The error code - * - * Returns %TRUE if error matches @domain and @code, %FALSE otherwise. - * In particular, when error is %NULL, FALSE will be returned. - * - * Return value: whether the @error corresponds to the given @domain - * and @code. - */ -CoglBool -cogl_error_matches (CoglError *error, - uint32_t domain, - int code); - -/** - * COGL_GLIB_ERROR: - * @COGL_ERROR: A #CoglError thrown by the Cogl api or %NULL - * - * Simply casts a #CoglError to a #CoglError - * - * If Cogl is built with GLib support then it can safely be assumed - * that a CoglError is a GError and can be used directly with the - * GError api. - */ -#define COGL_GLIB_ERROR(COGL_ERROR) ((CoglError *)COGL_ERROR) - -COGL_END_DECLS - -#endif /* __COGL_ERROR_H__ */ diff --git a/cogl/cogl/cogl-euler.c b/cogl/cogl/cogl-euler.c deleted file mode 100644 index 7af6ea057..000000000 --- a/cogl/cogl/cogl-euler.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg - */ - -#ifdef HAVE_CONFIG_H -#include "cogl-config.h" -#endif - -#include -#include -#include -#include "cogl-gtype-private.h" - -#include -#include - -COGL_GTYPE_DEFINE_BOXED (Euler, euler, - cogl_euler_copy, - cogl_euler_free); - -void -cogl_euler_init (CoglEuler *euler, - float heading, - float pitch, - float roll) -{ - euler->heading = heading; - euler->pitch = pitch; - euler->roll = roll; -} - -void -cogl_euler_init_from_matrix (CoglEuler *euler, - const CoglMatrix *matrix) -{ - /* - * Extracting a canonical Euler angle from a matrix: - * (where it is assumed the matrix contains no scaling, mirroring or - * skewing) - * - * A Euler angle is a combination of three rotations around mutually - * perpendicular axis. For this algorithm they are: - * - * Heading: A rotation about the Y axis by an angle H: - * | cosH 0 sinH| - * | 0 1 0| - * |-sinH 0 cosH| - * - * Pitch: A rotation around the X axis by an angle P: - * |1 0 0| - * |0 cosP -sinP| - * |0 sinP cosP| - * - * Roll: A rotation about the Z axis by an angle R: - * |cosR -sinR 0| - * |sinR cosR 0| - * | 0 0 1| - * - * When multiplied as matrices this gives: - * | cosHcosR+sinHsinPsinR sinRcosP -sinHcosR+cosHsinPsinR| - * M = |-cosHsinR+sinHsinPcosR cosRcosP sinRsinH+cosHsinPcosB| - * | sinHcosP -sinP cosHcosP | - * - * Given that there are an infinite number of ways to represent - * a given orientation, the "canonical" Euler angle is any such that: - * -180 < H < 180, - * -180 < R < 180 and - * -90 < P < 90 - * - * M[3][2] = -sinP lets us immediately solve for P = asin(-M[3][2]) - * (Note: asin has a range of +-90) - * This gives cosP - * This means we can use M[3][1] to calculate sinH: - * sinH = M[3][1]/cosP - * And use M[3][3] to calculate cosH: - * cosH = M[3][3]/cosP - * This lets us calculate H = atan2(sinH,cosH), but we optimise this: - * 1st note: atan2(x, y) does: atan(x/y) and uses the sign of x and y to - * determine the quadrant of the final angle. - * 2nd note: we know cosP is > 0 (ignoring cosP == 0) - * Therefore H = atan2((M[3][1]/cosP) / (M[3][3]/cosP)) can be simplified - * by skipping the division by cosP since it won't change the x/y ratio - * nor will it change their sign. This gives: - * H = atan2(M[3][1], M[3][3]) - * R is computed in the same way as H from M[1][2] and M[2][2] so: - * R = atan2(M[1][2], M[2][2]) - * Note: If cosP were == 0 then H and R could not be calculated as above - * because all the necessary matrix values would == 0. In other words we are - * pitched vertically and so H and R would now effectively rotate around the - * same axis - known as "Gimbal lock". In this situation we will set all the - * rotation on H and set R = 0. - * So with P = R = 0 we have cosP = 0, sinR = 0 and cosR = 1 - * We can substitute those into the above equation for M giving: - * | cosH 0 -sinH| - * |sinHsinP 0 cosHsinP| - * | 0 -sinP 0| - * And calculate H as atan2 (-M[3][2], M[1][1]) - */ - - float sinP; - float H; /* heading */ - float P; /* pitch */ - float R; /* roll */ - - /* NB: CoglMatrix provides struct members named according to the - * [row][column] indexed. So matrix->zx is row 3 column 1. */ - sinP = -matrix->zy; - - /* Determine the Pitch, avoiding domain errors with asin () which - * might occur due to previous imprecision in manipulating the - * matrix. */ - if (sinP <= -1.0f) - P = -G_PI_2; - else if (sinP >= 1.0f) - P = G_PI_2; - else - P = asinf (sinP); - - /* If P is too close to 0 then we have hit Gimbal lock */ - if (sinP > 0.999f) - { - H = atan2f (-matrix->zy, matrix->xx); - R = 0; - } - else - { - H = atan2f (matrix->zx, matrix->zz); - R = atan2f (matrix->xy, matrix->yy); - } - - euler->heading = H; - euler->pitch = P; - euler->roll = R; -} - -CoglBool -cogl_euler_equal (const void *v1, const void *v2) -{ - const CoglEuler *a = v1; - const CoglEuler *b = v2; - - _COGL_RETURN_VAL_IF_FAIL (v1 != NULL, FALSE); - _COGL_RETURN_VAL_IF_FAIL (v2 != NULL, FALSE); - - if (v1 == v2) - return TRUE; - - return (a->heading == b->heading && - a->pitch == b->pitch && - a->roll == b->roll); -} - -CoglEuler * -cogl_euler_copy (const CoglEuler *src) -{ - if (G_LIKELY (src)) - { - CoglEuler *new = g_slice_new (CoglEuler); - memcpy (new, src, sizeof (float) * 3); - return new; - } - else - return NULL; -} - -void -cogl_euler_free (CoglEuler *euler) -{ - g_slice_free (CoglEuler, euler); -} - diff --git a/cogl/cogl/cogl-euler.h b/cogl/cogl/cogl-euler.h deleted file mode 100644 index 39b06decc..000000000 --- a/cogl/cogl/cogl-euler.h +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL_EULER_H -#define __COGL_EULER_H - -#include - -#include - -COGL_BEGIN_DECLS - -/** - * SECTION:cogl-euler - * @short_description: Functions for initializing and manipulating - * euler angles. - * - * Euler angles are a simple representation of a 3 dimensional - * rotation; comprised of 3 ordered heading, pitch and roll rotations. - * An important thing to understand is that the axis of rotation - * belong to the object being rotated and so they also rotate as each - * of the heading, pitch and roll rotations are applied. - * - * One way to consider euler angles is to imagine controlling an - * aeroplane, where you first choose a heading (Such as flying south - * east), then you set the pitch (such as 30 degrees to take off) and - * then you might set a roll, by dipping the left, wing as you prepare - * to turn. - * - * They have some advantages and limitations that it helps to be - * aware of: - * - * Advantages: - * - * - * Easy to understand and use, compared to quaternions and matrices, - * so may be a good choice for a user interface. - * - * - * Efficient storage, needing only 3 components any rotation can be - * represented. - * Actually the #CoglEuler type isn't optimized for size because - * we may cache the equivalent #CoglQuaternion along with a euler - * rotation, but it would be trivial for an application to track the - * components of euler rotations in a packed float array if optimizing - * for size was important. The values could be passed to Cogl only when - * manipulation is necessary. - * - * - * - * Disadvantages: - * - * - * Aliasing: it's possible to represent some rotations with multiple - * different heading, pitch and roll rotations. - * - * - * They can suffer from a problem called Gimbal Lock. A good - * explanation of this can be seen on wikipedia here: - * http://en.wikipedia.org/wiki/Gimbal_lock but basically two - * of the axis of rotation may become aligned and so you loose a - * degree of freedom. For example a pitch of +-90° would mean that - * heading and bank rotate around the same axis. - * - * - * If you use euler angles to orient something in 3D space and try to - * transition between orientations by interpolating the component - * angles you probably wont get the transitions you expect as they may - * not follow the shortest path between the two orientations. - * - * - * There's no standard to what order the component axis rotations are - * applied. The most common convention seems to be what we do in Cogl - * with heading (y-axis), pitch (x-axis) and then roll (z-axis), but - * other software might apply x-axis, y-axis then z-axis or any other - * order so you need to consider this if you are accepting euler - * rotations from some other software. Other software may also use - * slightly different aeronautical terms, such as "yaw" instead of - * "heading" or "bank" instead of "roll". - * - * - * - * To minimize the aliasing issue we may refer to "Canonical Euler" - * angles where heading and roll are restricted to +- 180° and pitch is - * restricted to +- 90°. If pitch is +- 90° bank is set to 0°. - * - * Quaternions don't suffer from Gimbal Lock and they can be nicely - * interpolated between, their disadvantage is that they don't have an - * intuitive representation. - * - * A common practice is to accept angles in the intuitive Euler form - * and convert them to quaternions internally to avoid Gimbal Lock and - * handle interpolations. See cogl_quaternion_init_from_euler(). - */ - -/** - * CoglEuler: - * @heading: Angle to rotate around an object's y axis - * @pitch: Angle to rotate around an object's x axis - * @roll: Angle to rotate around an object's z axis - * - * Represents an ordered rotation first of @heading degrees around an - * object's y axis, then @pitch degrees around an object's x axis and - * finally @roll degrees around an object's z axis. - * - * It's important to understand the that axis are associated - * with the object being rotated, so the axis also rotate in sequence - * with the rotations being applied. - * - * The members of a #CoglEuler can be initialized, for example, with - * cogl_euler_init() and cogl_euler_init_from_quaternion (). - * - * You may also want to look at cogl_quaternion_init_from_euler() if - * you want to do interpolation between 3d rotations. - * - * Since: 2.0 - */ -struct _CoglEuler -{ - /*< public > */ - float heading; - float pitch; - float roll; - - /*< private > */ - /* May cached a quaternion here in the future */ - float padding0; - float padding1; - float padding2; - float padding3; - float padding4; -}; -COGL_STRUCT_SIZE_ASSERT (CoglEuler, 32); - -/** - * cogl_euler_get_gtype: - * - * Returns: a #GType that can be used with the GLib type system. - */ -GType cogl_euler_get_gtype (void); - -/** - * cogl_euler_init: - * @euler: The #CoglEuler angle to initialize - * @heading: Angle to rotate around an object's y axis - * @pitch: Angle to rotate around an object's x axis - * @roll: Angle to rotate around an object's z axis - * - * Initializes @euler to represent a rotation of @x_angle degrees - * around the x axis, then @y_angle degrees around the y_axis and - * @z_angle degrees around the z axis. - * - * Since: 2.0 - */ -void -cogl_euler_init (CoglEuler *euler, - float heading, - float pitch, - float roll); - -/** - * cogl_euler_init_from_matrix: - * @euler: The #CoglEuler angle to initialize - * @matrix: A #CoglMatrix containing a rotation, but no scaling, - * mirroring or skewing. - * - * Extracts a euler rotation from the given @matrix and - * initializses @euler with the component x, y and z rotation angles. - */ -void -cogl_euler_init_from_matrix (CoglEuler *euler, - const CoglMatrix *matrix); - -/** - * cogl_euler_init_from_quaternion: - * @euler: The #CoglEuler angle to initialize - * @quaternion: A #CoglEuler with the rotation to initialize with - * - * Initializes a @euler rotation with the equivalent rotation - * represented by the given @quaternion. - */ -void -cogl_euler_init_from_quaternion (CoglEuler *euler, - const CoglQuaternion *quaternion); - -/** - * cogl_euler_equal: - * @v1: The first euler angle to compare - * @v2: The second euler angle to compare - * - * Compares the two given euler angles @v1 and @v1 and it they are - * equal returns %TRUE else %FALSE. - * - * This function only checks that all three components rotations - * are numerically equal, it does not consider that some rotations - * can be represented with different component rotations - * - * Returns: %TRUE if @v1 and @v2 are equal else %FALSE. - * Since: 2.0 - */ -CoglBool -cogl_euler_equal (const void *v1, const void *v2); - -/** - * cogl_euler_copy: - * @src: A #CoglEuler to copy - * - * Allocates a new #CoglEuler and initilizes it with the component - * angles of @src. The newly allocated euler should be freed using - * cogl_euler_free(). - * - * Returns: A newly allocated #CoglEuler - * Since: 2.0 - */ -CoglEuler * -cogl_euler_copy (const CoglEuler *src); - -/** - * cogl_euler_free: - * @euler: A #CoglEuler allocated via cogl_euler_copy() - * - * Frees a #CoglEuler that was previously allocated using - * cogl_euler_copy(). - * - * Since: 2.0 - */ -void -cogl_euler_free (CoglEuler *euler); - -COGL_END_DECLS - -#endif /* __COGL_EULER_H */ - diff --git a/cogl/cogl/cogl-feature-private.c b/cogl/cogl/cogl-feature-private.c index 7680df4f3..3b2a9be98 100644 --- a/cogl/cogl/cogl-feature-private.c +++ b/cogl/cogl/cogl-feature-private.c @@ -28,9 +28,7 @@ * */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include @@ -40,7 +38,7 @@ #include "cogl-renderer-private.h" #include "cogl-private.h" -CoglBool +gboolean _cogl_feature_check (CoglRenderer *renderer, const char *driver_prefix, const CoglFeatureData *data, @@ -54,13 +52,10 @@ _cogl_feature_check (CoglRenderer *renderer, const char *suffix = NULL; int func_num; CoglExtGlesAvailability gles_availability = 0; - CoglBool in_core; + gboolean in_core; switch (driver) { - case COGL_DRIVER_GLES1: - gles_availability = COGL_EXT_IN_GLES; - break; case COGL_DRIVER_GLES2: gles_availability = COGL_EXT_IN_GLES2; @@ -69,9 +64,6 @@ _cogl_feature_check (CoglRenderer *renderer, break; case COGL_DRIVER_ANY: g_assert_not_reached (); - case COGL_DRIVER_WEBGL: - /* FIXME: WebGL should probably have its own COGL_EXT_IN_WEBGL flag */ - break; case COGL_DRIVER_NOP: case COGL_DRIVER_GL: case COGL_DRIVER_GL3: @@ -160,7 +152,7 @@ _cogl_feature_check (CoglRenderer *renderer, func = _cogl_renderer_get_proc_address (renderer, full_function_name, in_core); - free (full_function_name); + g_free (full_function_name); if (func == NULL) goto error; @@ -204,7 +196,7 @@ _cogl_feature_check (CoglRenderer *renderer, gles_availability, \ namespaces, extension_names) \ { min_gl_major, min_gl_minor, gles_availability, namespaces, \ - extension_names, 0, 0, 0, \ + extension_names, 0, 0, \ cogl_ext_ ## name ## _funcs }, #undef COGL_EXT_FUNCTION #define COGL_EXT_FUNCTION(ret, name, args) diff --git a/cogl/cogl/cogl-feature-private.h b/cogl/cogl/cogl-feature-private.h index a342d2333..35ec08953 100644 --- a/cogl/cogl/cogl-feature-private.h +++ b/cogl/cogl/cogl-feature-private.h @@ -33,6 +33,8 @@ #include +#include "cogl-context.h" +#include "cogl-renderer.h" #define COGL_CHECK_GL_VERSION(driver_major, driver_minor, \ target_major, target_minor) \ @@ -41,7 +43,7 @@ typedef enum { - COGL_EXT_IN_GLES = (1 << 0), + COGL_EXT_IN_GL = (1 << 0), COGL_EXT_IN_GLES2 = (1 << 1), COGL_EXT_IN_GLES3 = (1 << 2) } CoglExtGlesAvailability; @@ -75,8 +77,6 @@ struct _CoglFeatureData extension is different from the namespace, you can specify it with a ':' after the namespace */ const char *extension_names; - /* A set of feature flags to enable if the extension is available */ - CoglFeatureFlags feature_flags; /* A set of private feature flags to enable if the extension is * available */ int feature_flags_private; @@ -87,7 +87,7 @@ struct _CoglFeatureData const CoglFeatureFunction *functions; }; -CoglBool +gboolean _cogl_feature_check (CoglRenderer *renderer, const char *driver_prefix, const CoglFeatureData *data, diff --git a/cogl/cogl/cogl-fence-private.h b/cogl/cogl/cogl-fence-private.h index abbf51ffb..d2fe839f3 100644 --- a/cogl/cogl/cogl-fence-private.h +++ b/cogl/cogl/cogl-fence-private.h @@ -33,7 +33,7 @@ #include "cogl-fence.h" #include "cogl-list.h" -#include "cogl-winsys-private.h" +#include "winsys/cogl-winsys-private.h" typedef enum { diff --git a/cogl/cogl/cogl-fence.c b/cogl/cogl/cogl-fence.c index f1209be36..eb40978b1 100644 --- a/cogl/cogl/cogl-fence.c +++ b/cogl/cogl/cogl-fence.c @@ -27,14 +27,12 @@ * */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-fence.h" #include "cogl-fence-private.h" #include "cogl-context-private.h" -#include "cogl-winsys-private.h" +#include "winsys/cogl-winsys-private.h" #define FENCE_CHECK_TIMEOUT 5000 /* microseconds */ @@ -52,7 +50,7 @@ _cogl_fence_check (CoglFenceClosure *fence) if (fence->type == FENCE_TYPE_WINSYS) { const CoglWinsysVtable *winsys = _cogl_context_get_winsys (context); - CoglBool ret; + gboolean ret; ret = winsys->fence_is_complete (context, fence->fence_obj); if (!ret) diff --git a/cogl/cogl/cogl-fence.h b/cogl/cogl/cogl-fence.h index e268f8f5f..22cb88e1f 100644 --- a/cogl/cogl/cogl-fence.h +++ b/cogl/cogl/cogl-fence.h @@ -97,7 +97,7 @@ typedef struct _CoglFenceClosure CoglFenceClosure; * Since: 2.0 * Stability: Unstable */ -void * +COGL_EXPORT void * cogl_fence_closure_get_user_data (CoglFenceClosure *closure); /** @@ -118,7 +118,7 @@ cogl_fence_closure_get_user_data (CoglFenceClosure *closure); * Since: 2.0 * Stability: Unstable */ -CoglFenceClosure * +COGL_EXPORT CoglFenceClosure * cogl_framebuffer_add_fence_callback (CoglFramebuffer *framebuffer, CoglFenceCallback callback, void *user_data); @@ -136,7 +136,7 @@ cogl_framebuffer_add_fence_callback (CoglFramebuffer *framebuffer, * Since: 2.0 * Stability: Unstable */ -void +COGL_EXPORT void cogl_framebuffer_cancel_fence_callback (CoglFramebuffer *framebuffer, CoglFenceClosure *closure); diff --git a/cogl/cogl/cogl-flags.h b/cogl/cogl/cogl-flags.h index 33633f0d8..773818dcb 100644 --- a/cogl/cogl/cogl-flags.h +++ b/cogl/cogl/cogl-flags.h @@ -36,7 +36,7 @@ #include "cogl-util.h" -COGL_BEGIN_DECLS +G_BEGIN_DECLS /* These are macros used to implement a fixed-size array of bits. This should be used instead of CoglBitmask when the maximum bit number @@ -124,7 +124,7 @@ COGL_BEGIN_DECLS #define COGL_FLAGS_FOREACH_END \ } } } G_STMT_END -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_FLAGS_H */ diff --git a/cogl/cogl/cogl-frame-info.c b/cogl/cogl/cogl-frame-info.c index 4e7ac3aee..0455db1c1 100644 --- a/cogl/cogl/cogl-frame-info.c +++ b/cogl/cogl/cogl-frame-info.c @@ -28,9 +28,7 @@ * */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-frame-info-private.h" #include "cogl-gtype-private.h" diff --git a/cogl/cogl/cogl-frame-info.h b/cogl/cogl/cogl-frame-info.h index a87f7e13b..e35336b00 100644 --- a/cogl/cogl/cogl-frame-info.h +++ b/cogl/cogl/cogl-frame-info.h @@ -53,6 +53,7 @@ typedef struct _CoglFrameInfo CoglFrameInfo; * * Returns: a #GType that can be used with the GLib type system. */ +COGL_EXPORT GType cogl_frame_info_get_gtype (void); /** @@ -66,7 +67,7 @@ GType cogl_frame_info_get_gtype (void); * Since: 2.0 * Stability: unstable */ -CoglBool +COGL_EXPORT gboolean cogl_is_frame_info (void *object); /** @@ -80,6 +81,7 @@ cogl_is_frame_info (void *object); * Since: 1.14 * Stability: unstable */ +COGL_EXPORT int64_t cogl_frame_info_get_frame_counter (CoglFrameInfo *info); /** @@ -89,11 +91,8 @@ int64_t cogl_frame_info_get_frame_counter (CoglFrameInfo *info); * Gets the presentation time for the frame. This is the time at which * the frame became visible to the user. * - * The presentation time measured in nanoseconds is based on a - * monotonic time source. The time source is not necessarily - * correlated with system/wall clock time and may represent the time - * elapsed since some undefined system event such as when the system - * last booted. + * The presentation time measured in nanoseconds, is based on + * cogl_get_clock_time(). * * Linux kernel version less that 3.8 can result in * non-monotonic timestamps being reported when using a drm based @@ -104,6 +103,7 @@ int64_t cogl_frame_info_get_frame_counter (CoglFrameInfo *info); * Since: 1.14 * Stability: unstable */ +COGL_EXPORT int64_t cogl_frame_info_get_presentation_time (CoglFrameInfo *info); /** @@ -123,6 +123,7 @@ int64_t cogl_frame_info_get_presentation_time (CoglFrameInfo *info); * Since: 1.14 * Stability: unstable */ +COGL_EXPORT float cogl_frame_info_get_refresh_rate (CoglFrameInfo *info); /** @@ -136,12 +137,13 @@ float cogl_frame_info_get_refresh_rate (CoglFrameInfo *info); * Since: 1.14 * Stability: unstable */ -CoglOutput * +COGL_EXPORT CoglOutput * cogl_frame_info_get_output (CoglFrameInfo *info); /** * cogl_frame_info_get_global_frame_counter: (skip) */ +COGL_EXPORT int64_t cogl_frame_info_get_global_frame_counter (CoglFrameInfo *info); G_END_DECLS diff --git a/cogl/cogl/cogl-framebuffer-private.h b/cogl/cogl/cogl-framebuffer-private.h index 99ac2fba9..2cbfc7342 100644 --- a/cogl/cogl/cogl-framebuffer-private.h +++ b/cogl/cogl/cogl-framebuffer-private.h @@ -4,6 +4,7 @@ * A Low Level GPU Graphics and Utilities API * * Copyright (C) 2007,2008,2009 Intel Corporation. + * Copyright (C) 2019 DisplayLink (UK) Ltd. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -34,21 +35,12 @@ #include "cogl-object-private.h" #include "cogl-matrix-stack-private.h" #include "cogl-journal-private.h" -#include "cogl-winsys-private.h" +#include "winsys/cogl-winsys-private.h" #include "cogl-attribute-private.h" #include "cogl-offscreen.h" #include "cogl-gl-header.h" #include "cogl-clip-stack.h" -#ifdef COGL_HAS_XLIB_SUPPORT -#include -#endif - -#ifdef COGL_HAS_GLX_SUPPORT -#include -#include -#endif - typedef enum _CoglFramebufferType { COGL_FRAMEBUFFER_TYPE_ONSCREEN, COGL_FRAMEBUFFER_TYPE_OFFSCREEN @@ -57,11 +49,9 @@ typedef enum _CoglFramebufferType { typedef struct { CoglSwapChain *swap_chain; - CoglBool need_stencil; + gboolean need_stencil; int samples_per_pixel; - CoglBool swap_throttled; - CoglBool depth_texture_enabled; - CoglBool stereo_enabled; + gboolean stereo_enabled; } CoglFramebufferConfig; /* Flags to pass to _cogl_offscreen_new_with_texture_full */ @@ -84,11 +74,10 @@ typedef enum _CoglFramebufferStateIndex COGL_FRAMEBUFFER_STATE_INDEX_DITHER = 3, COGL_FRAMEBUFFER_STATE_INDEX_MODELVIEW = 4, COGL_FRAMEBUFFER_STATE_INDEX_PROJECTION = 5, - COGL_FRAMEBUFFER_STATE_INDEX_COLOR_MASK = 6, - COGL_FRAMEBUFFER_STATE_INDEX_FRONT_FACE_WINDING = 7, - COGL_FRAMEBUFFER_STATE_INDEX_DEPTH_WRITE = 8, - COGL_FRAMEBUFFER_STATE_INDEX_STEREO_MODE = 9, - COGL_FRAMEBUFFER_STATE_INDEX_MAX = 10 + COGL_FRAMEBUFFER_STATE_INDEX_FRONT_FACE_WINDING = 6, + COGL_FRAMEBUFFER_STATE_INDEX_DEPTH_WRITE = 7, + COGL_FRAMEBUFFER_STATE_INDEX_STEREO_MODE = 8, + COGL_FRAMEBUFFER_STATE_INDEX_MAX = 9 } CoglFramebufferStateIndex; typedef enum _CoglFramebufferState @@ -99,10 +88,9 @@ typedef enum _CoglFramebufferState COGL_FRAMEBUFFER_STATE_DITHER = 1<<3, COGL_FRAMEBUFFER_STATE_MODELVIEW = 1<<4, COGL_FRAMEBUFFER_STATE_PROJECTION = 1<<5, - COGL_FRAMEBUFFER_STATE_COLOR_MASK = 1<<6, - COGL_FRAMEBUFFER_STATE_FRONT_FACE_WINDING = 1<<7, - COGL_FRAMEBUFFER_STATE_DEPTH_WRITE = 1<<8, - COGL_FRAMEBUFFER_STATE_STEREO_MODE = 1<<9 + COGL_FRAMEBUFFER_STATE_FRONT_FACE_WINDING = 1<<6, + COGL_FRAMEBUFFER_STATE_DEPTH_WRITE = 1<<7, + COGL_FRAMEBUFFER_STATE_STEREO_MODE = 1<<8 } CoglFramebufferState; #define COGL_FRAMEBUFFER_STATE_ALL ((1<last_entry; } -CoglBool +gboolean _cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer, int x, int y, CoglReadPixelsFlags source, CoglBitmap *bitmap, - CoglError **error); + GError **error); /* * _cogl_framebuffer_get_stencil_bits: @@ -508,7 +393,7 @@ _cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer, * Since: 2.0 * Stability: unstable */ -int +COGL_EXPORT int _cogl_framebuffer_get_stencil_bits (CoglFramebuffer *framebuffer); #endif /* __COGL_FRAMEBUFFER_PRIVATE_H */ diff --git a/cogl/cogl/cogl-framebuffer.c b/cogl/cogl/cogl-framebuffer.c index 359b4f8ce..6edb7f042 100644 --- a/cogl/cogl/cogl-framebuffer.c +++ b/cogl/cogl/cogl-framebuffer.c @@ -4,6 +4,7 @@ * A Low Level GPU Graphics and Utilities API * * Copyright (C) 2007,2008,2009,2012 Intel Corporation. + * Copyright (C) 2019 DisplayLink (UK) Ltd. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -28,9 +29,7 @@ * */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include @@ -45,7 +44,6 @@ #include "cogl-onscreen-template-private.h" #include "cogl-clip-stack.h" #include "cogl-journal-private.h" -#include "cogl-winsys-private.h" #include "cogl-pipeline-state-private.h" #include "cogl-matrix-private.h" #include "cogl-primitive-private.h" @@ -53,9 +51,8 @@ #include "cogl1-context.h" #include "cogl-private.h" #include "cogl-primitives-private.h" -#include "cogl-error-private.h" -#include "cogl-texture-gl-private.h" #include "cogl-gtype-private.h" +#include "winsys/cogl-winsys-private.h" extern CoglObjectClass _cogl_onscreen_class; @@ -68,8 +65,8 @@ static void _cogl_offscreen_free (CoglOffscreen *offscreen); COGL_OBJECT_DEFINE_WITH_CODE_GTYPE (Offscreen, offscreen, _cogl_offscreen_class.virt_unref = _cogl_framebuffer_unref); -COGL_GTYPE_DEFINE_CLASS (Offscreen, offscreen); -COGL_OBJECT_DEFINE_DEPRECATED_REF_COUNTING (offscreen); +COGL_GTYPE_DEFINE_CLASS (Offscreen, offscreen, + COGL_GTYPE_IMPLEMENT_INTERFACE (framebuffer)); COGL_GTYPE_DEFINE_INTERFACE (Framebuffer, framebuffer); /* XXX: @@ -84,7 +81,7 @@ cogl_framebuffer_error_quark (void) return g_quark_from_static_string ("cogl-framebuffer-error-quark"); } -CoglBool +gboolean cogl_is_framebuffer (void *object) { CoglObject *obj = object; @@ -117,14 +114,13 @@ _cogl_framebuffer_init (CoglFramebuffer *framebuffer, framebuffer->viewport_age_for_scissor_workaround = -1; framebuffer->dither_enabled = TRUE; framebuffer->depth_writing_enabled = TRUE; + framebuffer->depth_buffer_clear_needed = TRUE; framebuffer->modelview_stack = cogl_matrix_stack_new (ctx); framebuffer->projection_stack = cogl_matrix_stack_new (ctx); framebuffer->dirty_bitmasks = TRUE; - framebuffer->color_mask = COGL_COLOR_MASK_ALL; - framebuffer->samples_per_pixel = 0; framebuffer->clip_stack = NULL; @@ -191,9 +187,6 @@ _cogl_framebuffer_free (CoglFramebuffer *framebuffer) cogl_object_unref (framebuffer->journal); - if (ctx->viewport_scissor_workaround_framebuffer == framebuffer) - ctx->viewport_scissor_workaround_framebuffer = NULL; - ctx->framebuffers = g_list_remove (ctx->framebuffers, framebuffer); if (ctx->current_draw_buffer == framebuffer) @@ -224,7 +217,7 @@ _cogl_framebuffer_clear_without_flush4f (CoglFramebuffer *framebuffer, if (!buffers) { - static CoglBool shown = FALSE; + static gboolean shown = FALSE; if (!shown) { @@ -246,12 +239,6 @@ _cogl_framebuffer_mark_clear_clip_dirty (CoglFramebuffer *framebuffer) framebuffer->clear_clip_dirty = TRUE; } -void -_cogl_framebuffer_mark_mid_scene (CoglFramebuffer *framebuffer) -{ - framebuffer->mid_scene = TRUE; -} - void cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer, unsigned long buffers, @@ -260,13 +247,23 @@ cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer, float blue, float alpha) { - CoglContext *ctx = framebuffer->context; CoglClipStack *clip_stack = _cogl_framebuffer_get_clip_stack (framebuffer); + gboolean had_depth_and_color_buffer_bits; int scissor_x0; int scissor_y0; int scissor_x1; int scissor_y1; - CoglBool saved_viewport_scissor_workaround; + + had_depth_and_color_buffer_bits = + (buffers & COGL_BUFFER_BIT_DEPTH) && + (buffers & COGL_BUFFER_BIT_COLOR); + + if (!framebuffer->depth_buffer_clear_needed && + (buffers & COGL_BUFFER_BIT_DEPTH)) + buffers &= ~(COGL_BUFFER_BIT_DEPTH); + + if (buffers == 0) + return; _cogl_clip_stack_get_bounds (clip_stack, &scissor_x0, &scissor_y0, @@ -306,8 +303,7 @@ cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer, * Note: Comparing without an epsilon is considered * appropriate here. */ - if (buffers & COGL_BUFFER_BIT_COLOR && - buffers & COGL_BUFFER_BIT_DEPTH && + if (had_depth_and_color_buffer_bits && !framebuffer->clear_clip_dirty && framebuffer->clear_color_red == red && framebuffer->clear_color_green == green && @@ -354,31 +350,6 @@ cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer, _cogl_framebuffer_flush_journal (framebuffer); - /* XXX: ONGOING BUG: Intel viewport scissor - * - * The semantics of cogl_framebuffer_clear() are that it should not - * be affected by the current viewport and so if we are currently - * applying a workaround for viewport scissoring we need to - * temporarily disable the workaround before clearing so any - * special scissoring for the workaround will be removed first. - * - * Note: we only need to disable the workaround if the current - * viewport doesn't match the framebuffer's size since otherwise - * the workaround wont affect clearing anyway. - */ - if (ctx->needs_viewport_scissor_workaround && - (framebuffer->viewport_x != 0 || - framebuffer->viewport_y != 0 || - framebuffer->viewport_width != framebuffer->width || - framebuffer->viewport_height != framebuffer->height)) - { - saved_viewport_scissor_workaround = TRUE; - ctx->needs_viewport_scissor_workaround = FALSE; - ctx->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_CLIP; - } - else - saved_viewport_scissor_workaround = FALSE; - /* NB: _cogl_framebuffer_flush_state may disrupt various state (such * as the pipeline state) when flushing the clip stack, so should * always be done first when preparing to draw. */ @@ -388,16 +359,6 @@ cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer, _cogl_framebuffer_clear_without_flush4f (framebuffer, buffers, red, green, blue, alpha); - /* XXX: ONGOING BUG: Intel viewport scissor - * - * See comment about temporarily disabling this workaround above - */ - if (saved_viewport_scissor_workaround) - { - ctx->needs_viewport_scissor_workaround = TRUE; - ctx->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_CLIP; - } - /* This is a debugging variable used to visually display the quad * batches from the journal. It is reset here to increase the * chances of getting the same colours for each frame during an @@ -412,10 +373,12 @@ cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer, cleared: - _cogl_framebuffer_mark_mid_scene (framebuffer); _cogl_framebuffer_mark_clear_clip_dirty (framebuffer); - if (buffers & COGL_BUFFER_BIT_COLOR && buffers & COGL_BUFFER_BIT_DEPTH) + if (buffers & COGL_BUFFER_BIT_DEPTH) + framebuffer->depth_buffer_clear_needed = FALSE; + + if (had_depth_and_color_buffer_bits) { /* For our fast-path for reading back a single pixel of simple * scenes where the whole frame is in the journal we need to @@ -429,18 +392,11 @@ cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer, /* NB: A clear may be scissored so we need to track the extents * that the clear is applicable too... */ - if (clip_stack) - { - _cogl_clip_stack_get_bounds (clip_stack, - &framebuffer->clear_clip_x0, - &framebuffer->clear_clip_y0, - &framebuffer->clear_clip_x1, - &framebuffer->clear_clip_y1); - } - else - { - /* FIXME: set degenerate clip */ - } + _cogl_clip_stack_get_bounds (clip_stack, + &framebuffer->clear_clip_x0, + &framebuffer->clear_clip_y0, + &framebuffer->clear_clip_x1, + &framebuffer->clear_clip_y1); } } @@ -477,11 +433,11 @@ ensure_size_initialized (CoglFramebuffer *framebuffer) { /* Currently we assume the size is always initialized for * onscreen framebuffers. */ - _COGL_RETURN_IF_FAIL (cogl_is_offscreen (framebuffer)); + g_return_if_fail (cogl_is_offscreen (framebuffer)); /* We also assume the size would have been initialized if the * framebuffer were allocated. */ - _COGL_RETURN_IF_FAIL (!framebuffer->allocated); + g_return_if_fail (!framebuffer->allocated); cogl_framebuffer_allocate (framebuffer, NULL); } @@ -508,12 +464,20 @@ _cogl_framebuffer_get_clip_stack (CoglFramebuffer *framebuffer) } void -_cogl_framebuffer_set_clip_stack (CoglFramebuffer *framebuffer, - CoglClipStack *stack) +cogl_framebuffer_set_viewport4fv (CoglFramebuffer *framebuffer, + float *viewport) { - _cogl_clip_stack_ref (stack); - _cogl_clip_stack_unref (framebuffer->clip_stack); - framebuffer->clip_stack = stack; + if (framebuffer->viewport_x == viewport[0] && + framebuffer->viewport_y == viewport[1] && + framebuffer->viewport_width == viewport[2] && + framebuffer->viewport_height == viewport[3]) + return; + + framebuffer->viewport_x = viewport[0]; + framebuffer->viewport_y = viewport[1]; + framebuffer->viewport_width = viewport[2]; + framebuffer->viewport_height = viewport[3]; + framebuffer->viewport_age++; } void @@ -523,9 +487,7 @@ cogl_framebuffer_set_viewport (CoglFramebuffer *framebuffer, float width, float height) { - CoglContext *context = framebuffer->context; - - _COGL_RETURN_IF_FAIL (width > 0 && height > 0); + g_return_if_fail (width > 0 && height > 0); if (framebuffer->viewport_x == x && framebuffer->viewport_y == y && @@ -533,21 +495,10 @@ cogl_framebuffer_set_viewport (CoglFramebuffer *framebuffer, framebuffer->viewport_height == height) return; - _cogl_framebuffer_flush_journal (framebuffer); - framebuffer->viewport_x = x; framebuffer->viewport_y = y; framebuffer->viewport_width = width; framebuffer->viewport_height = height; - framebuffer->viewport_age++; - - if (context->current_draw_buffer == framebuffer) - { - context->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_VIEWPORT; - - if (context->needs_viewport_scissor_workaround) - context->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_CLIP; - } } float @@ -620,16 +571,6 @@ _cogl_framebuffer_add_dependency (CoglFramebuffer *framebuffer, g_list_prepend (framebuffer->deps, cogl_object_ref (dependency)); } -void -_cogl_framebuffer_remove_all_dependencies (CoglFramebuffer *framebuffer) -{ - GList *l; - for (l = framebuffer->deps; l; l = l->next) - cogl_object_unref (l->data); - g_list_free (framebuffer->deps); - framebuffer->deps = NULL; -} - void _cogl_framebuffer_flush_journal (CoglFramebuffer *framebuffer) { @@ -642,7 +583,10 @@ _cogl_framebuffer_flush_dependency_journals (CoglFramebuffer *framebuffer) GList *l; for (l = framebuffer->deps; l; l = l->next) _cogl_framebuffer_flush_journal (l->data); - _cogl_framebuffer_remove_all_dependencies (framebuffer); + for (l = framebuffer->deps; l; l = l->next) + cogl_object_unref (l->data); + g_list_free (framebuffer->deps); + framebuffer->deps = NULL; } CoglOffscreen * @@ -655,7 +599,7 @@ _cogl_offscreen_new_with_texture_full (CoglTexture *texture, CoglFramebuffer *fb; CoglOffscreen *ret; - _COGL_RETURN_VAL_IF_FAIL (cogl_is_texture (texture), NULL); + g_return_val_if_fail (cogl_is_texture (texture), NULL); offscreen = g_new0 (CoglOffscreen, 1); offscreen->texture = cogl_object_ref (texture); @@ -687,12 +631,12 @@ CoglOffscreen * cogl_offscreen_new_to_texture (CoglTexture *texture) { CoglOffscreen *ret = _cogl_offscreen_new_with_texture_full (texture, 0, 0); - CoglError *error = NULL; + GError *error = NULL; if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (ret), &error)) { cogl_object_unref (ret); - cogl_error_free (error); + g_error_free (error); ret = NULL; } @@ -728,12 +672,12 @@ _cogl_offscreen_free (CoglOffscreen *offscreen) if (offscreen->depth_texture != NULL) cogl_object_unref (offscreen->depth_texture); - free (offscreen); + g_free (offscreen); } -CoglBool +gboolean cogl_framebuffer_allocate (CoglFramebuffer *framebuffer, - CoglError **error) + GError **error) { CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer); const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer); @@ -744,15 +688,6 @@ cogl_framebuffer_allocate (CoglFramebuffer *framebuffer, if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN) { - if (framebuffer->config.depth_texture_enabled) - { - _cogl_set_error (error, COGL_FRAMEBUFFER_ERROR, - COGL_FRAMEBUFFER_ERROR_ALLOCATE, - "Can't allocate onscreen framebuffer with a " - "texture based depth buffer"); - return FALSE; - } - if (!winsys->onscreen_init (onscreen, error)) return FALSE; @@ -767,14 +702,6 @@ cogl_framebuffer_allocate (CoglFramebuffer *framebuffer, { CoglOffscreen *offscreen = COGL_OFFSCREEN (framebuffer); - if (!cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN)) - { - _cogl_set_error (error, COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_UNSUPPORTED, - "Offscreen framebuffers not supported by system"); - return FALSE; - } - if (!cogl_texture_allocate (offscreen->texture, error)) return FALSE; @@ -782,10 +709,9 @@ cogl_framebuffer_allocate (CoglFramebuffer *framebuffer, * determine whether a texture needs slicing... */ if (cogl_texture_is_sliced (offscreen->texture)) { - _cogl_set_error (error, COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_UNSUPPORTED, - "Can't create offscreen framebuffer from " - "sliced texture"); + g_set_error (error, COGL_SYSTEM_ERROR, COGL_SYSTEM_ERROR_UNSUPPORTED, + "Can't create offscreen framebuffer from " + "sliced texture"); return FALSE; } @@ -821,27 +747,7 @@ _cogl_framebuffer_compare_viewport_state (CoglFramebuffer *a, /* NB: we render upside down to offscreen framebuffers and that * can affect how we setup the GL viewport... */ a->type != b->type) - { - unsigned long differences = COGL_FRAMEBUFFER_STATE_VIEWPORT; - CoglContext *context = a->context; - - /* XXX: ONGOING BUG: Intel viewport scissor - * - * Intel gen6 drivers don't currently correctly handle offset - * viewports, since primitives aren't clipped within the bounds of - * the viewport. To workaround this we push our own clip for the - * viewport that will use scissoring to ensure we clip as expected. - * - * This workaround implies that a change in viewport state is - * effectively also a change in the clipping state. - * - * TODO: file a bug upstream! - */ - if (G_UNLIKELY (context->needs_viewport_scissor_workaround)) - differences |= COGL_FRAMEBUFFER_STATE_CLIP; - - return differences; - } + return COGL_FRAMEBUFFER_STATE_VIEWPORT; else return 0; } @@ -884,17 +790,6 @@ _cogl_framebuffer_compare_projection_state (CoglFramebuffer *a, return COGL_FRAMEBUFFER_STATE_PROJECTION; } -static unsigned long -_cogl_framebuffer_compare_color_mask_state (CoglFramebuffer *a, - CoglFramebuffer *b) -{ - if (cogl_framebuffer_get_color_mask (a) != - cogl_framebuffer_get_color_mask (b)) - return COGL_FRAMEBUFFER_STATE_COLOR_MASK; - else - return 0; -} - static unsigned long _cogl_framebuffer_compare_front_face_winding_state (CoglFramebuffer *a, CoglFramebuffer *b) @@ -961,10 +856,6 @@ _cogl_framebuffer_compare (CoglFramebuffer *a, differences |= _cogl_framebuffer_compare_projection_state (a, b); break; - case COGL_FRAMEBUFFER_STATE_INDEX_COLOR_MASK: - differences |= - _cogl_framebuffer_compare_color_mask_state (a, b); - break; case COGL_FRAMEBUFFER_STATE_INDEX_FRONT_FACE_WINDING: differences |= _cogl_framebuffer_compare_front_face_winding_state (a, b); @@ -1070,29 +961,6 @@ cogl_framebuffer_get_is_stereo (CoglFramebuffer *framebuffer) return framebuffer->config.stereo_enabled; } -CoglColorMask -cogl_framebuffer_get_color_mask (CoglFramebuffer *framebuffer) -{ - return framebuffer->color_mask; -} - -void -cogl_framebuffer_set_color_mask (CoglFramebuffer *framebuffer, - CoglColorMask color_mask) -{ - if (framebuffer->color_mask == color_mask) - return; - - /* XXX: Currently color mask changes don't go through the journal */ - _cogl_framebuffer_flush_journal (framebuffer); - - framebuffer->color_mask = color_mask; - - if (framebuffer->context->current_draw_buffer == framebuffer) - framebuffer->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_COLOR_MASK; -} - CoglStereoMode cogl_framebuffer_get_stereo_mode (CoglFramebuffer *framebuffer) { @@ -1116,7 +984,7 @@ cogl_framebuffer_set_stereo_mode (CoglFramebuffer *framebuffer, COGL_FRAMEBUFFER_STATE_STEREO_MODE; } -CoglBool +gboolean cogl_framebuffer_get_depth_write_enabled (CoglFramebuffer *framebuffer) { return framebuffer->depth_writing_enabled; @@ -1124,7 +992,7 @@ cogl_framebuffer_get_depth_write_enabled (CoglFramebuffer *framebuffer) void cogl_framebuffer_set_depth_write_enabled (CoglFramebuffer *framebuffer, - CoglBool depth_write_enabled) + gboolean depth_write_enabled) { if (framebuffer->depth_writing_enabled == depth_write_enabled) return; @@ -1139,7 +1007,7 @@ cogl_framebuffer_set_depth_write_enabled (CoglFramebuffer *framebuffer, COGL_FRAMEBUFFER_STATE_DEPTH_WRITE; } -CoglBool +gboolean cogl_framebuffer_get_dither_enabled (CoglFramebuffer *framebuffer) { return framebuffer->dither_enabled; @@ -1147,43 +1015,12 @@ cogl_framebuffer_get_dither_enabled (CoglFramebuffer *framebuffer) void cogl_framebuffer_set_dither_enabled (CoglFramebuffer *framebuffer, - CoglBool dither_enabled) + gboolean dither_enabled) { if (framebuffer->dither_enabled == dither_enabled) return; - cogl_flush (); /* Currently dithering changes aren't tracked in the journal */ framebuffer->dither_enabled = dither_enabled; - - if (framebuffer->context->current_draw_buffer == framebuffer) - framebuffer->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_DITHER; -} - -void -cogl_framebuffer_set_depth_texture_enabled (CoglFramebuffer *framebuffer, - CoglBool enabled) -{ - _COGL_RETURN_IF_FAIL (!framebuffer->allocated); - - framebuffer->config.depth_texture_enabled = enabled; -} - -CoglBool -cogl_framebuffer_get_depth_texture_enabled (CoglFramebuffer *framebuffer) -{ - return framebuffer->config.depth_texture_enabled; -} - -CoglTexture * -cogl_framebuffer_get_depth_texture (CoglFramebuffer *framebuffer) -{ - /* lazily allocate the framebuffer... */ - if (!cogl_framebuffer_allocate (framebuffer, NULL)) - return NULL; - - _COGL_RETURN_VAL_IF_FAIL (cogl_is_offscreen (framebuffer), NULL); - return COGL_OFFSCREEN(framebuffer)->depth_texture; } int @@ -1199,7 +1036,7 @@ void cogl_framebuffer_set_samples_per_pixel (CoglFramebuffer *framebuffer, int samples_per_pixel) { - _COGL_RETURN_IF_FAIL (!framebuffer->allocated); + g_return_if_fail (!framebuffer->allocated); framebuffer->config.samples_per_pixel = samples_per_pixel; } @@ -1253,19 +1090,19 @@ cogl_framebuffer_resolve_samples_region (CoglFramebuffer *framebuffer, CoglContext * cogl_framebuffer_get_context (CoglFramebuffer *framebuffer) { - _COGL_RETURN_VAL_IF_FAIL (framebuffer != NULL, NULL); + g_return_val_if_fail (framebuffer != NULL, NULL); return framebuffer->context; } -static CoglBool +static gboolean _cogl_framebuffer_try_fast_read_pixel (CoglFramebuffer *framebuffer, int x, int y, CoglReadPixelsFlags source, CoglBitmap *bitmap) { - CoglBool found_intersection; + gboolean found_intersection; CoglPixelFormat format; if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_FAST_READ_PIXEL))) @@ -1307,7 +1144,7 @@ _cogl_framebuffer_try_fast_read_pixel (CoglFramebuffer *framebuffer, y < framebuffer->clear_clip_y1) { uint8_t *pixel; - CoglError *ignore_error = NULL; + GError *ignore_error = NULL; /* we currently only care about cases where the premultiplied or * unpremultipled colors are equivalent... */ @@ -1320,7 +1157,7 @@ _cogl_framebuffer_try_fast_read_pixel (CoglFramebuffer *framebuffer, &ignore_error); if (pixel == NULL) { - cogl_error_free (ignore_error); + g_error_free (ignore_error); return FALSE; } @@ -1337,20 +1174,20 @@ _cogl_framebuffer_try_fast_read_pixel (CoglFramebuffer *framebuffer, return FALSE; } -CoglBool +gboolean _cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer, int x, int y, CoglReadPixelsFlags source, CoglBitmap *bitmap, - CoglError **error) + GError **error) { CoglContext *ctx; int width; int height; - _COGL_RETURN_VAL_IF_FAIL (source & COGL_READ_PIXELS_COLOR_BUFFER, FALSE); - _COGL_RETURN_VAL_IF_FAIL (cogl_is_framebuffer (framebuffer), FALSE); + g_return_val_if_fail (source & COGL_READ_PIXELS_COLOR_BUFFER, FALSE); + g_return_val_if_fail (cogl_is_framebuffer (framebuffer), FALSE); if (!cogl_framebuffer_allocate (framebuffer, error)) return FALSE; @@ -1387,24 +1224,23 @@ _cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer, error); } -CoglBool +gboolean cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer, int x, int y, CoglReadPixelsFlags source, CoglBitmap *bitmap) { - CoglError *ignore_error = NULL; - CoglBool status = + GError *ignore_error = NULL; + gboolean status = _cogl_framebuffer_read_pixels_into_bitmap (framebuffer, x, y, source, bitmap, &ignore_error); - if (!status) - cogl_error_free (ignore_error); + g_clear_error (&ignore_error); return status; } -CoglBool +gboolean cogl_framebuffer_read_pixels (CoglFramebuffer *framebuffer, int x, int y, @@ -1413,10 +1249,13 @@ cogl_framebuffer_read_pixels (CoglFramebuffer *framebuffer, CoglPixelFormat format, uint8_t *pixels) { - int bpp = _cogl_pixel_format_get_bytes_per_pixel (format); + int bpp; CoglBitmap *bitmap; - CoglBool ret; + gboolean ret; + + g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, FALSE); + bpp = cogl_pixel_format_get_bytes_per_pixel (format, 0); bitmap = cogl_bitmap_new_for_data (framebuffer->context, width, height, format, @@ -1438,28 +1277,43 @@ cogl_framebuffer_read_pixels (CoglFramebuffer *framebuffer, return ret; } -void -_cogl_blit_framebuffer (CoglFramebuffer *src, - CoglFramebuffer *dest, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height) +gboolean +cogl_blit_framebuffer (CoglFramebuffer *src, + CoglFramebuffer *dest, + int src_x, + int src_y, + int dst_x, + int dst_y, + int width, + int height, + GError **error) { CoglContext *ctx = src->context; + int src_x1, src_y1, src_x2, src_y2; + int dst_x1, dst_y1, dst_x2, dst_y2; - _COGL_RETURN_IF_FAIL (_cogl_has_private_feature - (ctx, COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT)); + if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER)) + { + g_set_error_literal (error, COGL_SYSTEM_ERROR, + COGL_SYSTEM_ERROR_UNSUPPORTED, + "Cogl BLIT_FRAMEBUFFER is not supported by the system."); + return FALSE; + } - /* We can only support blitting between offscreen buffers because - otherwise we would need to mirror the image and GLES2.0 doesn't - support this */ - _COGL_RETURN_IF_FAIL (cogl_is_offscreen (src)); - _COGL_RETURN_IF_FAIL (cogl_is_offscreen (dest)); - /* The buffers must be the same format */ - _COGL_RETURN_IF_FAIL (src->internal_format == dest->internal_format); + /* The buffers must use the same premult convention */ + if ((src->internal_format & COGL_PREMULT_BIT) != + (dest->internal_format & COGL_PREMULT_BIT)) + { + g_set_error_literal (error, COGL_SYSTEM_ERROR, + COGL_SYSTEM_ERROR_UNSUPPORTED, + "cogl_blit_framebuffer premult mismatch."); + return FALSE; + } + + /* Make sure any batched primitives get submitted to the driver + * before blitting + */ + _cogl_framebuffer_flush_journal (src); /* Make sure the current framebuffers are bound. We explicitly avoid flushing the clip state so we can bind our own empty state */ @@ -1480,12 +1334,45 @@ _cogl_blit_framebuffer (CoglFramebuffer *src, * as changed */ ctx->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_CLIP; - ctx->glBlitFramebuffer (src_x, src_y, - src_x + width, src_y + height, - dst_x, dst_y, - dst_x + width, dst_y + height, + /* Offscreens we do the normal way, onscreens need an y-flip. Even if + * we consider offscreens to be rendered upside-down, the offscreen + * orientation is in this function's API. */ + if (cogl_is_offscreen (src)) + { + src_x1 = src_x; + src_y1 = src_y; + src_x2 = src_x + width; + src_y2 = src_y + height; + } + else + { + src_x1 = src_x; + src_y1 = cogl_framebuffer_get_height (src) - src_y; + src_x2 = src_x + width; + src_y2 = src_y1 - height; + } + + if (cogl_is_offscreen (dest)) + { + dst_x1 = dst_x; + dst_y1 = dst_y; + dst_x2 = dst_x + width; + dst_y2 = dst_y + height; + } + else + { + dst_x1 = dst_x; + dst_y1 = cogl_framebuffer_get_height (dest) - dst_y; + dst_x2 = dst_x + width; + dst_y2 = dst_y1 - height; + } + + ctx->glBlitFramebuffer (src_x1, src_y1, src_x2, src_y2, + dst_x1, dst_y1, dst_x2, dst_y2, GL_COLOR_BUFFER_BIT, GL_NEAREST); + + return TRUE; } void @@ -1494,7 +1381,7 @@ cogl_framebuffer_discard_buffers (CoglFramebuffer *framebuffer, { CoglContext *ctx = framebuffer->context; - _COGL_RETURN_IF_FAIL (buffers & COGL_BUFFER_BIT_COLOR); + g_return_if_fail (buffers & COGL_BUFFER_BIT_COLOR); ctx->driver_vtable->framebuffer_discard_buffers (framebuffer, buffers); } @@ -1509,6 +1396,17 @@ cogl_framebuffer_finish (CoglFramebuffer *framebuffer) ctx->driver_vtable->framebuffer_finish (framebuffer); } +void +cogl_framebuffer_flush (CoglFramebuffer *framebuffer) +{ + + CoglContext *ctx = framebuffer->context; + + _cogl_framebuffer_flush_journal (framebuffer); + + ctx->driver_vtable->framebuffer_flush (framebuffer); +} + void cogl_framebuffer_push_matrix (CoglFramebuffer *framebuffer) { @@ -1591,22 +1489,9 @@ cogl_framebuffer_rotate (CoglFramebuffer *framebuffer, COGL_FRAMEBUFFER_STATE_MODELVIEW; } -void -cogl_framebuffer_rotate_quaternion (CoglFramebuffer *framebuffer, - const CoglQuaternion *quaternion) -{ - CoglMatrixStack *modelview_stack = - _cogl_framebuffer_get_modelview_stack (framebuffer); - cogl_matrix_stack_rotate_quaternion (modelview_stack, quaternion); - - if (framebuffer->context->current_draw_buffer == framebuffer) - framebuffer->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_MODELVIEW; -} - void cogl_framebuffer_rotate_euler (CoglFramebuffer *framebuffer, - const CoglEuler *euler) + const graphene_euler_t *euler) { CoglMatrixStack *modelview_stack = _cogl_framebuffer_get_modelview_stack (framebuffer); @@ -1709,30 +1594,6 @@ cogl_framebuffer_orthographic (CoglFramebuffer *framebuffer, COGL_FRAMEBUFFER_STATE_PROJECTION; } -void -_cogl_framebuffer_push_projection (CoglFramebuffer *framebuffer) -{ - CoglMatrixStack *projection_stack = - _cogl_framebuffer_get_projection_stack (framebuffer); - cogl_matrix_stack_push (projection_stack); - - if (framebuffer->context->current_draw_buffer == framebuffer) - framebuffer->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_PROJECTION; -} - -void -_cogl_framebuffer_pop_projection (CoglFramebuffer *framebuffer) -{ - CoglMatrixStack *projection_stack = - _cogl_framebuffer_get_projection_stack (framebuffer); - cogl_matrix_stack_pop (projection_stack); - - if (framebuffer->context->current_draw_buffer == framebuffer) - framebuffer->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_PROJECTION; -} - void cogl_framebuffer_get_modelview_matrix (CoglFramebuffer *framebuffer, CoglMatrix *matrix) @@ -1871,6 +1732,19 @@ cogl_framebuffer_push_primitive_clip (CoglFramebuffer *framebuffer, COGL_FRAMEBUFFER_STATE_CLIP; } +void +cogl_framebuffer_push_region_clip (CoglFramebuffer *framebuffer, + cairo_region_t *region) +{ + framebuffer->clip_stack = + cogl_clip_stack_push_region (framebuffer->clip_stack, + region); + + if (framebuffer->context->current_draw_buffer == framebuffer) + framebuffer->context->current_draw_buffer_changes |= + COGL_FRAMEBUFFER_STATE_CLIP; +} + void cogl_framebuffer_pop_clip (CoglFramebuffer *framebuffer) { @@ -2013,7 +1887,7 @@ get_wire_line_indices (CoglContext *ctx, n_lines = get_line_count (mode, n_vertices_in); /* Note: we are using COGL_INDICES_TYPE_UNSIGNED_INT so 4 bytes per index. */ - line_indices = malloc (4 * n_lines * 2); + line_indices = g_malloc (4 * n_lines * 2); pos = 0; @@ -2082,20 +1956,11 @@ get_wire_line_indices (CoglContext *ctx, line_indices, *n_indices); - free (line_indices); + g_free (line_indices); return ret; } -static CoglBool -remove_layer_cb (CoglPipeline *pipeline, - int layer_index, - void *user_data) -{ - cogl_pipeline_remove_layer (pipeline, layer_index); - return TRUE; -} - static void pipeline_destroyed_cb (CoglPipeline *weak_pipeline, void *user_data) { @@ -2147,6 +2012,8 @@ draw_wireframe (CoglContext *ctx, if (!wire_pipeline) { + static CoglSnippet *snippet = NULL; + wire_pipeline = _cogl_pipeline_weak_copy (pipeline, pipeline_destroyed_cb, NULL); @@ -2158,29 +2025,20 @@ draw_wireframe (CoglContext *ctx, * vertex program and since we'd like to see the results of the * vertex program in the wireframe we just add a final clobber * of the wire color leaving the rest of the state untouched. */ - if (cogl_has_feature (framebuffer->context, COGL_FEATURE_ID_GLSL)) - { - static CoglSnippet *snippet = NULL; - /* The snippet is cached so that it will reuse the program - * from the pipeline cache if possible */ - if (snippet == NULL) - { - snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, - NULL, - NULL); - cogl_snippet_set_replace (snippet, - "cogl_color_out = " - "vec4 (0.0, 1.0, 0.0, 1.0);\n"); - } - - cogl_pipeline_add_snippet (wire_pipeline, snippet); - } - else + /* The snippet is cached so that it will reuse the program + * from the pipeline cache if possible */ + if (snippet == NULL) { - cogl_pipeline_foreach_layer (wire_pipeline, remove_layer_cb, NULL); - cogl_pipeline_set_color4f (wire_pipeline, 0, 1, 0, 1); + snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, + NULL, + NULL); + cogl_snippet_set_replace (snippet, + "cogl_color_out = " + "vec4 (0.0, 1.0, 0.0, 1.0);\n"); } + + cogl_pipeline_add_snippet (wire_pipeline, snippet); } /* temporarily disable the wireframe to avoid recursion! */ @@ -2241,59 +2099,6 @@ _cogl_framebuffer_draw_attributes (CoglFramebuffer *framebuffer, } } -/* XXX: deprecated */ -void -cogl_framebuffer_draw_attributes (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglAttribute **attributes, - int n_attributes) -{ - _cogl_framebuffer_draw_attributes (framebuffer, - pipeline, - mode, - first_vertex, - n_vertices, - attributes, n_attributes, - COGL_DRAW_SKIP_LEGACY_STATE); -} - -/* XXX: deprecated */ -void -cogl_framebuffer_vdraw_attributes (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - ...) -{ - va_list ap; - int n_attributes; - CoglAttribute *attribute; - CoglAttribute **attributes; - int i; - - va_start (ap, n_vertices); - for (n_attributes = 0; va_arg (ap, CoglAttribute *); n_attributes++) - ; - va_end (ap); - - attributes = g_alloca (sizeof (CoglAttribute *) * n_attributes); - - va_start (ap, n_vertices); - for (i = 0; (attribute = va_arg (ap, CoglAttribute *)); i++) - attributes[i] = attribute; - va_end (ap); - - _cogl_framebuffer_draw_attributes (framebuffer, - pipeline, - mode, first_vertex, n_vertices, - attributes, n_attributes, - COGL_DRAW_SKIP_LEGACY_STATE); -} - void _cogl_framebuffer_draw_indexed_attributes (CoglFramebuffer *framebuffer, CoglPipeline *pipeline, @@ -2333,72 +2138,12 @@ _cogl_framebuffer_draw_indexed_attributes (CoglFramebuffer *framebuffer, } } -/* XXX: deprecated */ -void -cogl_framebuffer_draw_indexed_attributes (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglIndices *indices, - CoglAttribute **attributes, - int n_attributes) -{ - _cogl_framebuffer_draw_indexed_attributes (framebuffer, - pipeline, - mode, first_vertex, - n_vertices, indices, - attributes, n_attributes, - COGL_DRAW_SKIP_LEGACY_STATE); -} - -/* XXX: deprecated */ -void -cogl_framebuffer_vdraw_indexed_attributes (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglIndices *indices, - ...) - -{ - va_list ap; - int n_attributes; - CoglAttribute **attributes; - int i; - CoglAttribute *attribute; - - va_start (ap, indices); - for (n_attributes = 0; va_arg (ap, CoglAttribute *); n_attributes++) - ; - va_end (ap); - - attributes = g_alloca (sizeof (CoglAttribute *) * n_attributes); - - va_start (ap, indices); - for (i = 0; (attribute = va_arg (ap, CoglAttribute *)); i++) - attributes[i] = attribute; - va_end (ap); - - _cogl_framebuffer_draw_indexed_attributes (framebuffer, - pipeline, - mode, - first_vertex, - n_vertices, - indices, - attributes, - n_attributes, - COGL_DRAW_SKIP_LEGACY_STATE); -} - void cogl_framebuffer_draw_primitive (CoglFramebuffer *framebuffer, CoglPipeline *pipeline, CoglPrimitive *primitive) { - _cogl_primitive_draw (primitive, framebuffer, pipeline, - COGL_DRAW_SKIP_LEGACY_STATE); + _cogl_primitive_draw (primitive, framebuffer, pipeline, 0); } void @@ -2424,8 +2169,7 @@ cogl_framebuffer_draw_rectangle (CoglFramebuffer *framebuffer, _cogl_framebuffer_draw_multitextured_rectangles (framebuffer, pipeline, &rect, - 1, - TRUE); + 1); } void @@ -2456,8 +2200,7 @@ cogl_framebuffer_draw_textured_rectangle (CoglFramebuffer *framebuffer, _cogl_framebuffer_draw_multitextured_rectangles (framebuffer, pipeline, &rect, - 1, - TRUE); + 1); } void @@ -2485,8 +2228,7 @@ cogl_framebuffer_draw_multitextured_rectangle (CoglFramebuffer *framebuffer, _cogl_framebuffer_draw_multitextured_rectangles (framebuffer, pipeline, &rect, - 1, - TRUE); + 1); } void @@ -2515,8 +2257,7 @@ cogl_framebuffer_draw_rectangles (CoglFramebuffer *framebuffer, _cogl_framebuffer_draw_multitextured_rectangles (framebuffer, pipeline, rects, - n_rectangles, - TRUE); + n_rectangles); } void @@ -2545,6 +2286,5 @@ cogl_framebuffer_draw_textured_rectangles (CoglFramebuffer *framebuffer, _cogl_framebuffer_draw_multitextured_rectangles (framebuffer, pipeline, rects, - n_rectangles, - TRUE); + n_rectangles); } diff --git a/cogl/cogl/cogl-framebuffer.h b/cogl/cogl/cogl-framebuffer.h index 6dc2eca39..a4bbcf7e4 100644 --- a/cogl/cogl/cogl-framebuffer.h +++ b/cogl/cogl/cogl-framebuffer.h @@ -3,7 +3,8 @@ * * A Low Level GPU Graphics and Utilities API * - * Copyright (C) 2011 Intel Corporation. + * Copyright (C) 2007,2008,2009,2011 Intel Corporation. + * Copyright (C) 2019 DisplayLink (UK) Ltd. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -37,7 +38,7 @@ /* We forward declare the CoglFramebuffer type here to avoid some circular * dependency issues with the following headers. */ -#if defined(__COGL_H_INSIDE__) && !defined(COGL_ENABLE_MUFFIN_API) && \ +#if defined(__COGL_H_INSIDE__) && !defined(COGL_ENABLE_MUTTER_API) && \ !defined(COGL_GIR_SCANNING) /* For the public C api we typedef interface types as void to avoid needing * lots of casting in code and instead we will rely on runtime type checking @@ -51,12 +52,13 @@ typedef struct _CoglFramebuffer CoglFramebuffer; #include #include #include -#include -#include #include #include +#include -COGL_BEGIN_DECLS +#include + +G_BEGIN_DECLS /** * SECTION:cogl-framebuffer @@ -101,12 +103,13 @@ COGL_BEGIN_DECLS * * Returns: a #GType that can be used with the GLib type system. */ +COGL_EXPORT GType cogl_framebuffer_get_gtype (void); /** * cogl_framebuffer_allocate: * @framebuffer: A #CoglFramebuffer - * @error: A pointer to a #CoglError for returning exceptions. + * @error: A pointer to a #GError for returning exceptions. * * Explicitly allocates a configured #CoglFramebuffer allowing developers to * check and handle any errors that might arise from an unsupported @@ -123,9 +126,9 @@ GType cogl_framebuffer_get_gtype (void); * Since: 1.8 * Stability: unstable */ -CoglBool +COGL_EXPORT gboolean cogl_framebuffer_allocate (CoglFramebuffer *framebuffer, - CoglError **error); + GError **error); /** * cogl_framebuffer_get_width: @@ -137,7 +140,7 @@ cogl_framebuffer_allocate (CoglFramebuffer *framebuffer, * Since: 1.8 * Stability: unstable */ -int +COGL_EXPORT int cogl_framebuffer_get_width (CoglFramebuffer *framebuffer); /** @@ -150,7 +153,7 @@ cogl_framebuffer_get_width (CoglFramebuffer *framebuffer); * Since: 1.8 * Stability: unstable */ -int +COGL_EXPORT int cogl_framebuffer_get_height (CoglFramebuffer *framebuffer); /** @@ -182,7 +185,7 @@ cogl_framebuffer_get_height (CoglFramebuffer *framebuffer); * Since: 1.8 * Stability: unstable */ -void +COGL_EXPORT void cogl_framebuffer_set_viewport (CoglFramebuffer *framebuffer, float x, float y, @@ -200,7 +203,7 @@ cogl_framebuffer_set_viewport (CoglFramebuffer *framebuffer, * Since: 1.8 * Stability: unstable */ -float +COGL_EXPORT float cogl_framebuffer_get_viewport_x (CoglFramebuffer *framebuffer); /** @@ -214,7 +217,7 @@ cogl_framebuffer_get_viewport_x (CoglFramebuffer *framebuffer); * Since: 1.8 * Stability: unstable */ -float +COGL_EXPORT float cogl_framebuffer_get_viewport_y (CoglFramebuffer *framebuffer); /** @@ -228,7 +231,7 @@ cogl_framebuffer_get_viewport_y (CoglFramebuffer *framebuffer); * Since: 1.8 * Stability: unstable */ -float +COGL_EXPORT float cogl_framebuffer_get_viewport_width (CoglFramebuffer *framebuffer); /** @@ -242,7 +245,7 @@ cogl_framebuffer_get_viewport_width (CoglFramebuffer *framebuffer); * Since: 1.8 * Stability: unstable */ -float +COGL_EXPORT float cogl_framebuffer_get_viewport_height (CoglFramebuffer *framebuffer); /** @@ -260,7 +263,7 @@ cogl_framebuffer_get_viewport_height (CoglFramebuffer *framebuffer); * Since: 1.8 * Stability: unstable */ -void +COGL_EXPORT void cogl_framebuffer_get_viewport4fv (CoglFramebuffer *framebuffer, float *viewport); @@ -273,7 +276,7 @@ cogl_framebuffer_get_viewport4fv (CoglFramebuffer *framebuffer, * * Since: 1.10 */ -void +COGL_EXPORT void cogl_framebuffer_push_matrix (CoglFramebuffer *framebuffer); /** @@ -284,7 +287,7 @@ cogl_framebuffer_push_matrix (CoglFramebuffer *framebuffer); * * Since: 1.10 */ -void +COGL_EXPORT void cogl_framebuffer_pop_matrix (CoglFramebuffer *framebuffer); /** @@ -296,7 +299,7 @@ cogl_framebuffer_pop_matrix (CoglFramebuffer *framebuffer); * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_framebuffer_identity_matrix (CoglFramebuffer *framebuffer); /** @@ -312,7 +315,7 @@ cogl_framebuffer_identity_matrix (CoglFramebuffer *framebuffer); * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_framebuffer_scale (CoglFramebuffer *framebuffer, float x, float y, @@ -331,7 +334,7 @@ cogl_framebuffer_scale (CoglFramebuffer *framebuffer, * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_framebuffer_translate (CoglFramebuffer *framebuffer, float x, float y, @@ -354,32 +357,17 @@ cogl_framebuffer_translate (CoglFramebuffer *framebuffer, * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_framebuffer_rotate (CoglFramebuffer *framebuffer, float angle, float x, float y, float z); -/** - * cogl_framebuffer_rotate_quaternion: - * @framebuffer: A #CoglFramebuffer pointer - * @quaternion: A #CoglQuaternion - * - * Multiplies the current model-view matrix by one that rotates - * according to the rotation described by @quaternion. - * - * Since: 2.0 - * Stability: unstable - */ -void -cogl_framebuffer_rotate_quaternion (CoglFramebuffer *framebuffer, - const CoglQuaternion *quaternion); - /** * cogl_framebuffer_rotate_euler: * @framebuffer: A #CoglFramebuffer pointer - * @euler: A #CoglEuler + * @euler: A #graphene_euler_t * * Multiplies the current model-view matrix by one that rotates * according to the rotation described by @euler. @@ -387,9 +375,9 @@ cogl_framebuffer_rotate_quaternion (CoglFramebuffer *framebuffer, * Since: 2.0 * Stability: unstable */ -void +COGL_EXPORT void cogl_framebuffer_rotate_euler (CoglFramebuffer *framebuffer, - const CoglEuler *euler); + const graphene_euler_t *euler); /** * cogl_framebuffer_transform: @@ -401,7 +389,7 @@ cogl_framebuffer_rotate_euler (CoglFramebuffer *framebuffer, * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_framebuffer_transform (CoglFramebuffer *framebuffer, const CoglMatrix *matrix); @@ -415,7 +403,7 @@ cogl_framebuffer_transform (CoglFramebuffer *framebuffer, * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_framebuffer_get_modelview_matrix (CoglFramebuffer *framebuffer, CoglMatrix *matrix); @@ -429,7 +417,7 @@ cogl_framebuffer_get_modelview_matrix (CoglFramebuffer *framebuffer, * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_framebuffer_set_modelview_matrix (CoglFramebuffer *framebuffer, const CoglMatrix *matrix); @@ -453,7 +441,7 @@ cogl_framebuffer_set_modelview_matrix (CoglFramebuffer *framebuffer, * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_framebuffer_perspective (CoglFramebuffer *framebuffer, float fov_y, float aspect, @@ -481,7 +469,7 @@ cogl_framebuffer_perspective (CoglFramebuffer *framebuffer, * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_framebuffer_frustum (CoglFramebuffer *framebuffer, float left, float right, @@ -510,7 +498,7 @@ cogl_framebuffer_frustum (CoglFramebuffer *framebuffer, * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_framebuffer_orthographic (CoglFramebuffer *framebuffer, float x_1, float y_1, @@ -529,7 +517,7 @@ cogl_framebuffer_orthographic (CoglFramebuffer *framebuffer, * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_framebuffer_get_projection_matrix (CoglFramebuffer *framebuffer, CoglMatrix *matrix); @@ -543,7 +531,7 @@ cogl_framebuffer_get_projection_matrix (CoglFramebuffer *framebuffer, * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_framebuffer_set_projection_matrix (CoglFramebuffer *framebuffer, const CoglMatrix *matrix); @@ -567,7 +555,7 @@ cogl_framebuffer_set_projection_matrix (CoglFramebuffer *framebuffer, * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_framebuffer_push_scissor_clip (CoglFramebuffer *framebuffer, int x, int y, @@ -594,7 +582,7 @@ cogl_framebuffer_push_scissor_clip (CoglFramebuffer *framebuffer, * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_framebuffer_push_rectangle_clip (CoglFramebuffer *framebuffer, float x_1, float y_1, @@ -602,7 +590,7 @@ cogl_framebuffer_push_rectangle_clip (CoglFramebuffer *framebuffer, float y_2); /** - * cogl_framebuffer_push_primitive_clip: + * cogl_framebuffer_push_primitive_clip: (skip) * @framebuffer: A #CoglFramebuffer pointer * @primitive: A #CoglPrimitive describing a flat 2D shape * @bounds_x1: x coordinate for the top-left corner of the primitives @@ -630,7 +618,7 @@ cogl_framebuffer_push_rectangle_clip (CoglFramebuffer *framebuffer, * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_framebuffer_push_primitive_clip (CoglFramebuffer *framebuffer, CoglPrimitive *primitive, float bounds_x1, @@ -638,6 +626,10 @@ cogl_framebuffer_push_primitive_clip (CoglFramebuffer *framebuffer, float bounds_x2, float bounds_y2); +COGL_EXPORT void +cogl_framebuffer_push_region_clip (CoglFramebuffer *framebuffer, + cairo_region_t *region); + /** * cogl_framebuffer_pop_clip: * @framebuffer: A #CoglFramebuffer pointer @@ -649,7 +641,7 @@ cogl_framebuffer_push_primitive_clip (CoglFramebuffer *framebuffer, * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_framebuffer_pop_clip (CoglFramebuffer *framebuffer); /** @@ -663,7 +655,7 @@ cogl_framebuffer_pop_clip (CoglFramebuffer *framebuffer); * Since: 1.8 * Stability: unstable */ -int +COGL_EXPORT int cogl_framebuffer_get_red_bits (CoglFramebuffer *framebuffer); /** @@ -677,7 +669,7 @@ cogl_framebuffer_get_red_bits (CoglFramebuffer *framebuffer); * Since: 1.8 * Stability: unstable */ -int +COGL_EXPORT int cogl_framebuffer_get_green_bits (CoglFramebuffer *framebuffer); /** @@ -691,7 +683,7 @@ cogl_framebuffer_get_green_bits (CoglFramebuffer *framebuffer); * Since: 1.8 * Stability: unstable */ -int +COGL_EXPORT int cogl_framebuffer_get_blue_bits (CoglFramebuffer *framebuffer); /** @@ -705,7 +697,7 @@ cogl_framebuffer_get_blue_bits (CoglFramebuffer *framebuffer); * Since: 1.8 * Stability: unstable */ -int +COGL_EXPORT int cogl_framebuffer_get_alpha_bits (CoglFramebuffer *framebuffer); /** @@ -719,7 +711,7 @@ cogl_framebuffer_get_alpha_bits (CoglFramebuffer *framebuffer); * Since: 2.0 * Stability: unstable */ -int +COGL_EXPORT int cogl_framebuffer_get_depth_bits (CoglFramebuffer *framebuffer); /* @@ -736,7 +728,7 @@ cogl_framebuffer_get_depth_bits (CoglFramebuffer *framebuffer); * Since: 1.20 * Stability: unstable */ -CoglBool +COGL_EXPORT gboolean cogl_framebuffer_get_is_stereo (CoglFramebuffer *framebuffer); /** @@ -754,7 +746,7 @@ cogl_framebuffer_get_is_stereo (CoglFramebuffer *framebuffer); * Since: 1.8 * Stability: unstable */ -CoglBool +COGL_EXPORT gboolean cogl_framebuffer_get_dither_enabled (CoglFramebuffer *framebuffer); /** @@ -779,9 +771,9 @@ cogl_framebuffer_get_dither_enabled (CoglFramebuffer *framebuffer); * Since: 1.8 * Stability: unstable */ -void +COGL_EXPORT void cogl_framebuffer_set_dither_enabled (CoglFramebuffer *framebuffer, - CoglBool dither_enabled); + gboolean dither_enabled); /** * cogl_framebuffer_get_depth_write_enabled: @@ -794,7 +786,7 @@ cogl_framebuffer_set_dither_enabled (CoglFramebuffer *framebuffer, * Since: 1.18 * Stability: unstable */ -CoglBool +COGL_EXPORT gboolean cogl_framebuffer_get_depth_write_enabled (CoglFramebuffer *framebuffer); /** @@ -812,41 +804,9 @@ cogl_framebuffer_get_depth_write_enabled (CoglFramebuffer *framebuffer); * Since: 1.18 * Stability: unstable */ -void +COGL_EXPORT void cogl_framebuffer_set_depth_write_enabled (CoglFramebuffer *framebuffer, - CoglBool depth_write_enabled); - -/** - * cogl_framebuffer_get_color_mask: - * @framebuffer: a pointer to a #CoglFramebuffer - * - * Gets the current #CoglColorMask of which channels would be written to the - * current framebuffer. Each bit set in the mask means that the - * corresponding color would be written. - * - * Returns: A #CoglColorMask - * Since: 1.8 - * Stability: unstable - */ -CoglColorMask -cogl_framebuffer_get_color_mask (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_set_color_mask: - * @framebuffer: a pointer to a #CoglFramebuffer - * @color_mask: A #CoglColorMask of which color channels to write to - * the current framebuffer. - * - * Defines a bit mask of which color channels should be written to the - * given @framebuffer. If a bit is set in @color_mask that means that - * color will be written. - * - * Since: 1.8 - * Stability: unstable - */ -void -cogl_framebuffer_set_color_mask (CoglFramebuffer *framebuffer, - CoglColorMask color_mask); + gboolean depth_write_enabled); /** * cogl_framebuffer_get_stereo_mode: @@ -859,7 +819,7 @@ cogl_framebuffer_set_color_mask (CoglFramebuffer *framebuffer, * Since: 1.20 * Stability: unstable */ -CoglStereoMode +COGL_EXPORT CoglStereoMode cogl_framebuffer_get_stereo_mode (CoglFramebuffer *framebuffer); /** @@ -879,69 +839,10 @@ cogl_framebuffer_get_stereo_mode (CoglFramebuffer *framebuffer); * Since: 1.20 * Stability: unstable */ -void +COGL_EXPORT void cogl_framebuffer_set_stereo_mode (CoglFramebuffer *framebuffer, CoglStereoMode stereo_mode); -/** - * cogl_framebuffer_set_depth_texture_enabled: - * @framebuffer: A #CoglFramebuffer - * @enabled: TRUE or FALSE - * - * If @enabled is #TRUE, the depth buffer used when rendering to @framebuffer - * is available as a texture. You can retrieve the texture with - * cogl_framebuffer_get_depth_texture(). - * - * It's possible that your GPU does not support depth textures. You - * should check the %COGL_FEATURE_ID_DEPTH_TEXTURE feature before using this - * function. - * It's not valid to call this function after the framebuffer has been - * allocated as the creation of the depth texture is done at allocation time. - * - * - * Since: 1.14 - * Stability: unstable - */ -void -cogl_framebuffer_set_depth_texture_enabled (CoglFramebuffer *framebuffer, - CoglBool enabled); - -/** - * cogl_framebuffer_get_depth_texture_enabled: - * @framebuffer: A #CoglFramebuffer - * - * Queries whether texture based depth buffer has been enabled via - * cogl_framebuffer_set_depth_texture_enabled(). - * - * Return value: %TRUE if a depth texture has been enabled, else - * %FALSE. - * - * Since: 1.14 - * Stability: unstable - */ -CoglBool -cogl_framebuffer_get_depth_texture_enabled (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_get_depth_texture: - * @framebuffer: A #CoglFramebuffer - * - * Retrieves the depth buffer of @framebuffer as a #CoglTexture. You need to - * call cogl_framebuffer_get_depth_texture(fb, TRUE); before using this - * function. - * - * Calling this function implicitely allocates the framebuffer. - * The texture returned stays valid as long as the framebuffer stays - * valid. - * - * Returns: (transfer none): the depth texture - * - * Since: 1.14 - * Stability: unstable - */ -CoglTexture * -cogl_framebuffer_get_depth_texture (CoglFramebuffer *framebuffer); - /** * cogl_framebuffer_set_samples_per_pixel: * @framebuffer: A #CoglFramebuffer framebuffer @@ -983,7 +884,7 @@ cogl_framebuffer_get_depth_texture (CoglFramebuffer *framebuffer); * Since: 1.8 * Stability: unstable */ -void +COGL_EXPORT void cogl_framebuffer_set_samples_per_pixel (CoglFramebuffer *framebuffer, int samples_per_pixel); @@ -1011,7 +912,7 @@ cogl_framebuffer_set_samples_per_pixel (CoglFramebuffer *framebuffer, * Since: 1.10 * Stability: unstable */ -int +COGL_EXPORT int cogl_framebuffer_get_samples_per_pixel (CoglFramebuffer *framebuffer); @@ -1043,7 +944,7 @@ cogl_framebuffer_get_samples_per_pixel (CoglFramebuffer *framebuffer); * Since: 1.8 * Stability: unstable */ -void +COGL_EXPORT void cogl_framebuffer_resolve_samples (CoglFramebuffer *framebuffer); /** @@ -1079,7 +980,7 @@ cogl_framebuffer_resolve_samples (CoglFramebuffer *framebuffer); * Since: 1.8 * Stability: unstable */ -void +COGL_EXPORT void cogl_framebuffer_resolve_samples_region (CoglFramebuffer *framebuffer, int x, int y, @@ -1099,7 +1000,7 @@ cogl_framebuffer_resolve_samples_region (CoglFramebuffer *framebuffer, * Since: 1.8 * Stability: unstable */ -CoglContext * +COGL_EXPORT CoglContext * cogl_framebuffer_get_context (CoglFramebuffer *framebuffer); /** @@ -1116,7 +1017,7 @@ cogl_framebuffer_get_context (CoglFramebuffer *framebuffer); * Since: 1.8 * Stability: unstable */ -void +COGL_EXPORT void cogl_framebuffer_clear (CoglFramebuffer *framebuffer, unsigned long buffers, const CoglColor *color); @@ -1141,7 +1042,7 @@ cogl_framebuffer_clear (CoglFramebuffer *framebuffer, * Since: 1.8 * Stability: unstable */ -void +COGL_EXPORT void cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer, unsigned long buffers, float red, @@ -1150,7 +1051,7 @@ cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer, float alpha); /** - * cogl_framebuffer_draw_primitive: + * cogl_framebuffer_draw_primitive: (skip) * @framebuffer: A destination #CoglFramebuffer * @pipeline: A #CoglPipeline state object * @primitive: A #CoglPrimitive geometry object @@ -1161,248 +1062,24 @@ cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer, * This drawing api doesn't support high-level meta texture types such * as #CoglTexture2DSliced so it is the user's responsibility to * ensure that only low-level textures that can be directly sampled by - * a GPU such as #CoglTexture2D, #CoglTextureRectangle or #CoglTexture3D - * are associated with layers of the given @pipeline. + * a GPU such as #CoglTexture2D are associated with layers of the given + * @pipeline. * * This api doesn't support any of the legacy global state options such - * as cogl_set_depth_test_enabled(), cogl_set_backface_culling_enabled() or - * cogl_program_use() + * as cogl_set_depth_test_enabled() or + * cogl_set_backface_culling_enabled(). * * Stability: unstable * Since: 1.10 * Deprecated: 1.16: Use #CoglPrimitives and * cogl_primitive_draw() instead */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_primitive_draw) -void +COGL_DEPRECATED_FOR (cogl_primitive_draw) +COGL_EXPORT void cogl_framebuffer_draw_primitive (CoglFramebuffer *framebuffer, CoglPipeline *pipeline, CoglPrimitive *primitive); -/** - * cogl_framebuffer_vdraw_attributes: - * @framebuffer: A destination #CoglFramebuffer - * @pipeline: A #CoglPipeline state object - * @mode: The #CoglVerticesMode defining the topology of vertices - * @first_vertex: The vertex offset within the given attributes to draw from - * @n_vertices: The number of vertices to draw from the given attributes - * @...: A set of vertex #CoglAttributes defining vertex geometry - * - * First defines a geometry primitive by grouping a set of vertex attributes; - * specifying a @first_vertex; a number of vertices (@n_vertices) and - * specifying what kind of topology the vertices have via @mode. - * - * Then the function draws the given @primitive geometry to the specified - * destination @framebuffer using the graphics processing pipeline described by - * @pipeline. - * - * The list of #CoglAttributes define the attributes of the vertices to - * be drawn, such as positions, colors and normals and should be %NULL - * terminated. - * - * This drawing api doesn't support high-level meta texture types such - * as #CoglTexture2DSliced so it is the user's responsibility to - * ensure that only low-level textures that can be directly sampled by - * a GPU such as #CoglTexture2D, #CoglTextureRectangle or #CoglTexture3D - * are associated with layers of the given @pipeline. - * - * Stability: unstable - * Since: 1.10 - * Deprecated: 1.16: Use #CoglPrimitives and - * cogl_primitive_draw() instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_primitive_draw) -void -cogl_framebuffer_vdraw_attributes (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - ...) COGL_GNUC_NULL_TERMINATED; - -/** - * cogl_framebuffer_draw_attributes: - * @framebuffer: A destination #CoglFramebuffer - * @pipeline: A #CoglPipeline state object - * @mode: The #CoglVerticesMode defining the topology of vertices - * @first_vertex: The vertex offset within the given attributes to draw from - * @n_vertices: The number of vertices to draw from the given attributes - * @attributes: An array of pointers to #CoglAttribute<-- -->s defining vertex - * geometry - * @n_attributes: The number of attributes in the @attributes array. - * - * First defines a geometry primitive by grouping a set of vertex @attributes; - * specifying a @first_vertex; a number of vertices (@n_vertices) and - * specifying what kind of topology the vertices have via @mode. - * - * Then the function draws the given @primitive geometry to the specified - * destination @framebuffer using the graphics processing pipeline described by - * @pipeline. - * - * The list of #CoglAttributes define the attributes of the vertices to - * be drawn, such as positions, colors and normals and the number of attributes - * is given as @n_attributes. - * - * This drawing api doesn't support high-level meta texture types such - * as #CoglTexture2DSliced so it is the user's responsibility to - * ensure that only low-level textures that can be directly sampled by - * a GPU such as #CoglTexture2D, #CoglTextureRectangle or #CoglTexture3D - * are associated with layers of the given @pipeline. - * - * This api doesn't support any of the legacy global state options such - * as cogl_set_depth_test_enabled(), cogl_set_backface_culling_enabled() or - * cogl_program_use() - * - * Stability: unstable - * Since: 1.10 - * Deprecated: 1.16: Use #CoglPrimitives and - * cogl_primitive_draw() instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_primitive_draw) -void -cogl_framebuffer_draw_attributes (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglAttribute **attributes, - int n_attributes); - -/** - * cogl_framebuffer_vdraw_indexed_attributes: - * @framebuffer: A destination #CoglFramebuffer - * @pipeline: A #CoglPipeline state object - * @mode: The #CoglVerticesMode defining the topology of vertices - * @first_vertex: The vertex offset within the given attributes to draw from - * @n_vertices: The number of vertices to draw from the given attributes - * @indices: The array of indices used by the GPU to lookup attribute - * data for each vertex. - * @...: A set of vertex #CoglAttributes defining vertex geometry - * - * Behaves the same as cogl_framebuffer_vdraw_attributes() except that - * instead of reading vertex data sequentially from the specified - * attributes the @indices provide an indirection for how the data - * should be indexed allowing a random access order to be - * specified. - * - * For example an indices array of [0, 1, 2, 0, 2, 3] could be used - * used to draw two triangles (@mode = %COGL_VERTICES_MODE_TRIANGLES + - * @n_vertices = 6) but only provide attribute data for the 4 corners - * of a rectangle. When the GPU needs to read in each of the 6 - * vertices it will read the @indices array for each vertex in - * sequence and use the index to look up the vertex attribute data. So - * here you can see that first and fourth vertex will point to the - * same data and third and fifth vertex will also point to shared - * data. - * - * Drawing with indices can be a good way of minimizing the size of a - * mesh by allowing you to avoid data for duplicate vertices because - * multiple entries in the index array can refer back to a single - * shared vertex. - * - * The @indices array must be at least as long as @first_vertex - * + @n_vertices otherwise the GPU will overrun the indices array when - * looking up vertex data. - * - * Since it's very common to want to draw a run of rectangles using - * indices to avoid duplicating vertex data you can use - * cogl_get_rectangle_indices() to get a set of indices that can be - * shared. - * - * This drawing api doesn't support high-level meta texture types such - * as #CoglTexture2DSliced so it is the user's responsibility to - * ensure that only low-level textures that can be directly sampled by - * a GPU such as #CoglTexture2D, #CoglTextureRectangle or - * #CoglTexture3D are associated with layers of the given @pipeline. - * - * This api doesn't support any of the legacy global state - * options such as cogl_set_depth_test_enabled(), - * cogl_set_backface_culling_enabled() or cogl_program_use() - * - * Stability: unstable - * Since: 1.10 - * Deprecated: 1.16: Use #CoglPrimitives and - * cogl_primitive_draw() instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_primitive_draw) -void -cogl_framebuffer_vdraw_indexed_attributes (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglIndices *indices, - ...) COGL_GNUC_NULL_TERMINATED; - -/** - * cogl_framebuffer_draw_indexed_attributes: - * @framebuffer: A destination #CoglFramebuffer - * @pipeline: A #CoglPipeline state object - * @mode: The #CoglVerticesMode defining the topology of vertices - * @first_vertex: The vertex offset within the given attributes to draw from - * @n_vertices: The number of vertices to draw from the given attributes - * @indices: The array of indices used by the GPU to lookup attribute - * data for each vertex. - * @attributes: An array of pointers to #CoglAttribute<-- -->s defining vertex - * geometry - * @n_attributes: The number of attributes in the @attributes array. - * - * Behaves the same as cogl_framebuffer_draw_attributes() except that - * instead of reading vertex data sequentially from the specified - * @attributes the @indices provide an indirection for how the data - * should be indexed allowing a random access order to be - * specified. - * - * For example an indices array of [0, 1, 2, 0, 2, 3] could be used - * used to draw two triangles (@mode = %COGL_VERTICES_MODE_TRIANGLES + - * @n_vertices = 6) but only provide attribute data for the 4 corners - * of a rectangle. When the GPU needs to read in each of the 6 - * vertices it will read the @indices array for each vertex in - * sequence and use the index to look up the vertex attribute data. So - * here you can see that first and fourth vertex will point to the - * same data and third and fifth vertex will also point to shared - * data. - * - * Drawing with indices can be a good way of minimizing the size of a - * mesh by allowing you to avoid data for duplicate vertices because - * multiple entries in the index array can refer back to a single - * shared vertex. - * - * The @indices array must be at least as long as @first_vertex - * + @n_vertices otherwise the GPU will overrun the indices array when - * looking up vertex data. - * - * Since it's very common to want to draw a run of rectangles using - * indices to avoid duplicating vertex data you can use - * cogl_get_rectangle_indices() to get a set of indices that can be - * shared. - * - * This drawing api doesn't support high-level meta texture types such - * as #CoglTexture2DSliced so it is the user's responsibility to - * ensure that only low-level textures that can be directly sampled by - * a GPU such as #CoglTexture2D, #CoglTextureRectangle or - * #CoglTexture3D are associated with layers of the given @pipeline. - * - * This api doesn't support any of the legacy global state - * options such as cogl_set_depth_test_enabled(), - * cogl_set_backface_culling_enabled() or cogl_program_use() - * - * Stability: unstable - * Since: 1.10 - * Deprecated: 1.16: Use #CoglPrimitives and - * cogl_primitive_draw() instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_primitive_draw) -void -cogl_framebuffer_draw_indexed_attributes (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglIndices *indices, - CoglAttribute **attributes, - int n_attributes); - /** * cogl_framebuffer_draw_rectangle: * @framebuffer: A destination #CoglFramebuffer @@ -1427,7 +1104,7 @@ cogl_framebuffer_draw_indexed_attributes (CoglFramebuffer *framebuffer, * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_framebuffer_draw_rectangle (CoglFramebuffer *framebuffer, CoglPipeline *pipeline, float x_1, @@ -1475,15 +1152,10 @@ cogl_framebuffer_draw_rectangle (CoglFramebuffer *framebuffer, * bottom right. To map an entire texture across the rectangle pass * in @s_1=0, @t_1=0, @s_2=1, @t_2=1. * - * Even if you have associated a #CoglTextureRectangle texture - * with one of your @pipeline layers which normally implies working - * with non-normalized texture coordinates this api should still be - * passed normalized texture coordinates. - * * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_framebuffer_draw_textured_rectangle (CoglFramebuffer *framebuffer, CoglPipeline *pipeline, float x_1, @@ -1532,9 +1204,7 @@ cogl_framebuffer_draw_textured_rectangle (CoglFramebuffer *framebuffer, * This api can not currently handle multiple high-level meta * texture layers. The first layer may be a high level meta texture * such as #CoglTexture2DSliced but all other layers much be low - * level textures such as #CoglTexture2D and additionally they - * should be textures that can be sampled using normalized coordinates - * (so not #CoglTextureRectangle textures). + * level textures such as #CoglTexture2D. * * The top left texture coordinate for layer 0 of any pipeline will be * (tex_coords[0], tex_coords[1]) and the bottom right coordinate will @@ -1548,11 +1218,6 @@ cogl_framebuffer_draw_textured_rectangle (CoglFramebuffer *framebuffer, * in tex_coords[0]=0, tex_coords[1]=0, tex_coords[2]=1, * tex_coords[3]=1. * - * Even if you have associated a #CoglTextureRectangle texture - * which normally implies working with non-normalized texture - * coordinates this api should still be passed normalized texture - * coordinates. - * * The first pair of coordinates are for the first layer (with the * smallest layer index) and if you supply less texture coordinates * than there are layers in the current source material then default @@ -1561,7 +1226,7 @@ cogl_framebuffer_draw_textured_rectangle (CoglFramebuffer *framebuffer, * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_framebuffer_draw_multitextured_rectangle (CoglFramebuffer *framebuffer, CoglPipeline *pipeline, float x_1, @@ -1605,7 +1270,7 @@ cogl_framebuffer_draw_multitextured_rectangle (CoglFramebuffer *framebuffer, * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_framebuffer_draw_rectangles (CoglFramebuffer *framebuffer, CoglPipeline *pipeline, const float *coordinates, @@ -1656,15 +1321,10 @@ cogl_framebuffer_draw_rectangles (CoglFramebuffer *framebuffer, * in tex_coords[0]=0, tex_coords[1]=0, tex_coords[2]=1, * tex_coords[3]=1. * - * Even if you have associated a #CoglTextureRectangle texture - * which normally implies working with non-normalized texture - * coordinates this api should still be passed normalized texture - * coordinates. - * * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_framebuffer_draw_textured_rectangles (CoglFramebuffer *framebuffer, CoglPipeline *pipeline, const float *coordinates, @@ -1699,7 +1359,7 @@ cogl_framebuffer_draw_textured_rectangles (CoglFramebuffer *framebuffer, * Since: 1.8 * Stability: unstable */ -void +COGL_EXPORT void cogl_framebuffer_discard_buffers (CoglFramebuffer *framebuffer, unsigned long buffers); @@ -1720,7 +1380,7 @@ cogl_framebuffer_discard_buffers (CoglFramebuffer *framebuffer, * Stability: unstable * Since: 1.10 */ -void +COGL_EXPORT void cogl_framebuffer_finish (CoglFramebuffer *framebuffer); /** @@ -1749,7 +1409,7 @@ cogl_framebuffer_finish (CoglFramebuffer *framebuffer); * Since: 1.10 * Stability: unstable */ -CoglBool +COGL_EXPORT gboolean cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer, int x, int y, @@ -1795,7 +1455,7 @@ cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer, * Since: 1.10 * Stability: unstable */ -CoglBool +COGL_EXPORT gboolean cogl_framebuffer_read_pixels (CoglFramebuffer *framebuffer, int x, int y, @@ -1804,20 +1464,7 @@ cogl_framebuffer_read_pixels (CoglFramebuffer *framebuffer, CoglPixelFormat format, uint8_t *pixels); -/** - * cogl_get_draw_framebuffer: - * - * Gets the current #CoglFramebuffer as set using - * cogl_push_framebuffer() - * - * Return value: (transfer none): The current #CoglFramebuffer - * Stability: unstable - * Since: 1.8 - */ -CoglFramebuffer * -cogl_get_draw_framebuffer (void); - -uint32_t +COGL_EXPORT uint32_t cogl_framebuffer_error_quark (void); /** @@ -1827,7 +1474,8 @@ cogl_framebuffer_error_quark (void); */ #define COGL_FRAMEBUFFER_ERROR (cogl_framebuffer_error_quark ()) -typedef enum { /*< prefix=COGL_FRAMEBUFFER_ERROR >*/ +typedef enum /*< prefix=COGL_FRAMEBUFFER_ERROR >*/ +{ COGL_FRAMEBUFFER_ERROR_ALLOCATE } CoglFramebufferError; @@ -1842,9 +1490,84 @@ typedef enum { /*< prefix=COGL_FRAMEBUFFER_ERROR >*/ * Since: 1.10 * Stability: unstable */ -CoglBool +COGL_EXPORT gboolean cogl_is_framebuffer (void *object); -COGL_END_DECLS +/** + * cogl_blit_framebuffer: + * @src: The source #CoglFramebuffer + * @dest: The destination #CoglFramebuffer + * @src_x: Source x position + * @src_y: Source y position + * @dst_x: Destination x position + * @dst_y: Destination y position + * @width: Width of region to copy + * @height: Height of region to copy + * @error: optional error object + * + * @return FALSE for an immediately detected error, TRUE otherwise. + * + * This blits a region of the color buffer of the source buffer + * to the destination buffer. This function should only be + * called if the COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER feature is + * advertised. + * + * The source and destination rectangles are defined in offscreen + * framebuffer orientation. When copying between an offscreen and + * onscreen framebuffers, the image is y-flipped accordingly. + * + * The two buffers must have the same value types (e.g. floating-point, + * unsigned int, signed int, or fixed-point), but color formats do not + * need to match. This limitation comes from OpenGL ES 3.0 definition + * of glBlitFramebuffer. + * + * Note that this function differs a lot from the glBlitFramebuffer + * function provided by the GL_EXT_framebuffer_blit extension. Notably + * it doesn't support having different sizes for the source and + * destination rectangle. This doesn't seem + * like a particularly useful feature. If the application wanted to + * scale the results it may make more sense to draw a primitive + * instead. + * + * The GL function is documented to be affected by the scissor. This + * function therefore ensure that an empty clip stack is flushed + * before performing the blit which means the scissor is effectively + * ignored. + * + * The function also doesn't support specifying the buffers to copy + * and instead only the color buffer is copied. When copying the depth + * or stencil buffers the extension on GLES2.0 only supports copying + * the full buffer which would be awkward to document with this + * API. If we wanted to support that feature it may be better to have + * a separate function to copy the entire buffer for a given mask. + * + * The @c error argument is optional, it can be NULL. If it is not NULL + * and this function returns FALSE, an error object with a code from + * COGL_SYSTEM_ERROR will be created. + */ +COGL_EXPORT gboolean +cogl_blit_framebuffer (CoglFramebuffer *src, + CoglFramebuffer *dest, + int src_x, + int src_y, + int dst_x, + int dst_y, + int width, + int height, + GError **error); + +/** + * cogl_framebuffer_flush: + * @framebuffer: A #CoglFramebuffer pointer + * + * Flushes @framebuffer to ensure the current batch of commands is + * submitted to the GPU. + * + * Unlike cogl_framebuffer_finish(), this does not block the CPU. + */ +void +cogl_framebuffer_flush (CoglFramebuffer *framebuffer); + +G_END_DECLS #endif /* __COGL_FRAMEBUFFER_H */ diff --git a/cogl/cogl/cogl-gl-header.h.in b/cogl/cogl/cogl-gl-header.h.in index 8b0f2fe2c..a6659e92f 100644 --- a/cogl/cogl/cogl-gl-header.h.in +++ b/cogl/cogl/cogl-gl-header.h.in @@ -28,7 +28,7 @@ * */ -#if !defined(COGL_COMPILATION) && !defined(COGL_ENABLE_MUFFIN_API) +#if !defined(COGL_COMPILATION) && !defined(COGL_ENABLE_MUTTER_API) #error "cogl-gl-header.h should only be included when compiling Cogl" #endif diff --git a/cogl/cogl/cogl-gles2-context-private.h b/cogl/cogl/cogl-gles2-context-private.h deleted file mode 100644 index 805b06468..000000000 --- a/cogl/cogl/cogl-gles2-context-private.h +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Collabora Ltd. - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Tomeu Vizoso - * Robert Bragg - * - */ - -#ifndef __COGL_GLES2_CONTEXT_PRIVATE_H -#define __COGL_GLES2_CONTEXT_PRIVATE_H - -#include - -#include "cogl-object-private.h" -#include "cogl-framebuffer-private.h" -#include "cogl-list.h" - -typedef struct _CoglGLES2Offscreen -{ - CoglList link; - CoglOffscreen *original_offscreen; - CoglGLFramebuffer gl_framebuffer; -} CoglGLES2Offscreen; - -typedef struct -{ - /* GL's ID for the shader */ - GLuint object_id; - /* Shader type */ - GLenum type; - - /* Number of references to this shader. The shader will have one - * reference when it is created. This reference will be removed when - * glDeleteShader is called. An additional reference will be taken - * whenever the shader is attached to a program. This is necessary - * to correctly detect when a shader is destroyed because - * glDeleteShader doesn't actually delete the object if it is - * attached to a program */ - int ref_count; - - /* Set once this object has had glDeleteShader called on it. We need - * to keep track of this so we don't deref the data twice if the - * application calls glDeleteShader multiple times */ - CoglBool deleted; -} CoglGLES2ShaderData; - -typedef enum -{ - COGL_GLES2_FLIP_STATE_UNKNOWN, - COGL_GLES2_FLIP_STATE_NORMAL, - COGL_GLES2_FLIP_STATE_FLIPPED -} CoglGLES2FlipState; - -typedef struct -{ - /* GL's ID for the program */ - GLuint object_id; - - /* List of shaders attached to this program */ - GList *attached_shaders; - - /* Reference count. There can be up to two references. One of these - * will exist between glCreateProgram and glDeleteShader, the other - * will exist while the program is made current. This is necessary - * to correctly detect when the program is deleted because - * glDeleteShader will delay the deletion if the program is - * current */ - int ref_count; - - /* Set once this object has had glDeleteProgram called on it. We need - * to keep track of this so we don't deref the data twice if the - * application calls glDeleteProgram multiple times */ - CoglBool deleted; - - GLuint flip_vector_location; - - /* A cache of what value we've put in the flip vector uniform so - * that we don't flush unless it's changed */ - CoglGLES2FlipState flip_vector_state; - - CoglGLES2Context *context; -} CoglGLES2ProgramData; - -/* State tracked for each texture unit */ -typedef struct -{ - /* The currently bound texture for the GL_TEXTURE_2D */ - GLuint current_texture_2d; -} CoglGLES2TextureUnitData; - -/* State tracked for each texture object */ -typedef struct -{ - /* GL's ID for this object */ - GLuint object_id; - - GLenum target; - - /* The details for texture when it has a 2D target */ - int width, height; - GLenum format; -} CoglGLES2TextureObjectData; - -struct _CoglGLES2Context -{ - CoglObject _parent; - - CoglContext *context; - - /* This is set to FALSE until the first time the GLES2 context is - * bound to something. We need to keep track of this so we can set - * the viewport and scissor the first time it is bound. */ - CoglBool has_been_bound; - - CoglFramebuffer *read_buffer; - CoglGLES2Offscreen *gles2_read_buffer; - CoglFramebuffer *write_buffer; - CoglGLES2Offscreen *gles2_write_buffer; - - GLuint current_fbo_handle; - - CoglList foreign_offscreens; - - CoglGLES2Vtable *vtable; - - /* Hash table mapping GL's IDs for shaders and objects to ShaderData - * and ProgramData so that we can maintain extra data for these - * objects. Although technically the IDs will end up global across - * all GLES2 contexts because they will all be in the same share - * list, we don't really want to expose this outside of the Cogl API - * so we will assume it is undefined behaviour if an application - * relies on this. */ - GHashTable *shader_map; - GHashTable *program_map; - - /* Currently in use program. We need to keep track of this so that - * we can keep a reference to the data for the program while it is - * current */ - CoglGLES2ProgramData *current_program; - - /* Whether the currently bound framebuffer needs flipping. This is - * used to check for changes so that we can dirty the following - * state flags */ - CoglGLES2FlipState current_flip_state; - - /* The following state is tracked separately from the GL context - * because we need to modify it depending on whether we are flipping - * the geometry. */ - CoglBool viewport_dirty; - int viewport[4]; - CoglBool scissor_dirty; - int scissor[4]; - CoglBool front_face_dirty; - GLenum front_face; - - /* We need to keep track of the pack alignment so we can flip the - * results of glReadPixels read from a CoglOffscreen */ - int pack_alignment; - - /* A hash table of CoglGLES2TextureObjects indexed by the texture - * object ID so that we can track some state */ - GHashTable *texture_object_map; - - /* Array of CoglGLES2TextureUnits to keep track of state for each - * texture unit */ - GArray *texture_units; - - /* The currently active texture unit indexed from 0 (not from - * GL_TEXTURE0) */ - int current_texture_unit; - - void *winsys; -}; - -#endif /* __COGL_GLES2_CONTEXT_PRIVATE_H */ diff --git a/cogl/cogl/cogl-gles2-context.c b/cogl/cogl/cogl-gles2-context.c deleted file mode 100644 index 379348d74..000000000 --- a/cogl/cogl/cogl-gles2-context.c +++ /dev/null @@ -1,1966 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Collabora Ltd. - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Tomeu Vizoso - * Robert Bragg - * Neil Roberts - * - */ - -#ifdef HAVE_CONFIG_H -#include "cogl-config.h" -#endif - -#include - -#include "cogl-gles2.h" -#include "cogl-gles2-context-private.h" - -#include "cogl-context-private.h" -#include "cogl-display-private.h" -#include "cogl-framebuffer-private.h" -#include "cogl-framebuffer-gl-private.h" -#include "cogl-onscreen-template-private.h" -#include "cogl-renderer-private.h" -#include "cogl-swap-chain-private.h" -#include "cogl-texture-2d-gl.h" -#include "cogl-texture-2d-private.h" -#include "cogl-pipeline-opengl-private.h" -#include "cogl-error-private.h" -#include "cogl-gtype-private.h" - -static void _cogl_gles2_context_free (CoglGLES2Context *gles2_context); - -COGL_OBJECT_DEFINE (GLES2Context, gles2_context); -COGL_GTYPE_DEFINE_CLASS (GLES2Context, gles2_context); - -static CoglGLES2Context *current_gles2_context; - -static CoglUserDataKey offscreen_wrapper_key; - -/* The application's main function is renamed to this so that we can - * provide an alternative main function */ -#define MAIN_WRAPPER_REPLACEMENT_NAME "_c31" -/* This uniform is used to flip the rendering or not depending on - * whether we are rendering to an offscreen buffer or not */ -#define MAIN_WRAPPER_FLIP_UNIFORM "_cogl_flip_vector" -/* These comments are used to delimit the added wrapper snippet so - * that we can remove it again when the shader source is requested via - * glGetShaderSource */ -#define MAIN_WRAPPER_BEGIN "/*_COGL_WRAPPER_BEGIN*/" -#define MAIN_WRAPPER_END "/*_COGL_WRAPPER_END*/" - -/* This wrapper function around 'main' is appended to every vertex shader - * so that we can add some extra code to flip the rendering when - * rendering to an offscreen buffer */ -static const char -main_wrapper_function[] = - MAIN_WRAPPER_BEGIN "\n" - "uniform vec4 " MAIN_WRAPPER_FLIP_UNIFORM ";\n" - "\n" - "void\n" - "main ()\n" - "{\n" - " " MAIN_WRAPPER_REPLACEMENT_NAME " ();\n" - " gl_Position *= " MAIN_WRAPPER_FLIP_UNIFORM ";\n" - "}\n" - MAIN_WRAPPER_END; - -enum { - RESTORE_FB_NONE, - RESTORE_FB_FROM_OFFSCREEN, - RESTORE_FB_FROM_ONSCREEN, -}; - -uint32_t -_cogl_gles2_context_error_quark (void) -{ - return g_quark_from_static_string ("cogl-gles2-context-error-quark"); -} - -static void -shader_data_unref (CoglGLES2Context *context, - CoglGLES2ShaderData *shader_data) -{ - if (--shader_data->ref_count < 1) - /* Removing the hash table entry should also destroy the data */ - g_hash_table_remove (context->shader_map, - GINT_TO_POINTER (shader_data->object_id)); -} - -static void -program_data_unref (CoglGLES2ProgramData *program_data) -{ - if (--program_data->ref_count < 1) - /* Removing the hash table entry should also destroy the data */ - g_hash_table_remove (program_data->context->program_map, - GINT_TO_POINTER (program_data->object_id)); -} - -static void -detach_shader (CoglGLES2ProgramData *program_data, - CoglGLES2ShaderData *shader_data) -{ - GList *l; - - for (l = program_data->attached_shaders; l; l = l->next) - { - if (l->data == shader_data) - { - shader_data_unref (program_data->context, shader_data); - program_data->attached_shaders = - g_list_delete_link (program_data->attached_shaders, l); - break; - } - } -} - -static CoglBool -is_symbol_character (char ch) -{ - return g_ascii_isalnum (ch) || ch == '_'; -} - -static void -replace_token (char *string, - const char *token, - const char *replacement, - int length) -{ - char *token_pos; - char *last_pos = string; - char *end = string + length; - int token_length = strlen (token); - - /* NOTE: this assumes token and replacement are the same length */ - - while ((token_pos = _cogl_util_memmem (last_pos, - end - last_pos, - token, - token_length))) - { - /* Make sure this isn't in the middle of some longer token */ - if ((token_pos <= string || - !is_symbol_character (token_pos[-1])) && - (token_pos + token_length == end || - !is_symbol_character (token_pos[token_length]))) - memcpy (token_pos, replacement, token_length); - - last_pos = token_pos + token_length; - } -} - -static void -update_current_flip_state (CoglGLES2Context *gles2_ctx) -{ - CoglGLES2FlipState new_flip_state; - - if (gles2_ctx->current_fbo_handle == 0 && - cogl_is_offscreen (gles2_ctx->write_buffer)) - new_flip_state = COGL_GLES2_FLIP_STATE_FLIPPED; - else - new_flip_state = COGL_GLES2_FLIP_STATE_NORMAL; - - /* If the flip state has changed then we need to reflush all of the - * dependent state */ - if (new_flip_state != gles2_ctx->current_flip_state) - { - gles2_ctx->viewport_dirty = TRUE; - gles2_ctx->scissor_dirty = TRUE; - gles2_ctx->front_face_dirty = TRUE; - gles2_ctx->current_flip_state = new_flip_state; - } -} - -static GLuint -get_current_texture_2d_object (CoglGLES2Context *gles2_ctx) -{ - return g_array_index (gles2_ctx->texture_units, - CoglGLES2TextureUnitData, - gles2_ctx->current_texture_unit).current_texture_2d; -} - -static void -set_texture_object_data (CoglGLES2Context *gles2_ctx, - GLenum target, - GLint level, - GLenum internal_format, - GLsizei width, - GLsizei height) -{ - GLuint texture_id = get_current_texture_2d_object (gles2_ctx); - CoglGLES2TextureObjectData *texture_object; - - /* We want to keep track of all texture objects where the data is - * created by this context so that we can delete them later */ - texture_object = g_hash_table_lookup (gles2_ctx->texture_object_map, - GUINT_TO_POINTER (texture_id)); - if (texture_object == NULL) - { - texture_object = g_slice_new0 (CoglGLES2TextureObjectData); - texture_object->object_id = texture_id; - - g_hash_table_insert (gles2_ctx->texture_object_map, - GUINT_TO_POINTER (texture_id), - texture_object); - } - - switch (target) - { - case GL_TEXTURE_2D: - texture_object->target = GL_TEXTURE_2D; - - /* We want to keep track of the dimensions of any texture object - * setting the GL_TEXTURE_2D target */ - if (level == 0) - { - texture_object->width = width; - texture_object->height = height; - texture_object->format = internal_format; - } - break; - - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - texture_object->target = GL_TEXTURE_CUBE_MAP; - break; - } -} - -static void -copy_flipped_texture (CoglGLES2Context *gles2_ctx, - int level, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height) -{ - GLuint tex_id = get_current_texture_2d_object (gles2_ctx); - CoglGLES2TextureObjectData *tex_object_data; - CoglContext *ctx; - const CoglWinsysVtable *winsys; - CoglTexture2D *dst_texture; - CoglPixelFormat internal_format; - - tex_object_data = g_hash_table_lookup (gles2_ctx->texture_object_map, - GUINT_TO_POINTER (tex_id)); - - /* We can't do anything if the application hasn't set a level 0 - * image on this texture object */ - if (tex_object_data == NULL || - tex_object_data->target != GL_TEXTURE_2D || - tex_object_data->width <= 0 || - tex_object_data->height <= 0) - return; - - switch (tex_object_data->format) - { - case GL_RGB: - internal_format = COGL_PIXEL_FORMAT_RGB_888; - break; - - case GL_RGBA: - internal_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE; - break; - - case GL_ALPHA: - internal_format = COGL_PIXEL_FORMAT_A_8; - break; - - case GL_LUMINANCE: - internal_format = COGL_PIXEL_FORMAT_G_8; - break; - - default: - /* We can't handle this format so just give up */ - return; - } - - ctx = gles2_ctx->context; - winsys = ctx->display->renderer->winsys_vtable; - - /* We need to make sure the rendering on the GLES2 context is - * complete before the blit will be ready in the GLES2 context */ - ctx->glFinish (); - /* We need to force Cogl to rebind the texture because according to - * the GL spec a shared texture isn't guaranteed to be updated until - * is rebound */ - _cogl_get_texture_unit (0)->dirty_gl_texture = TRUE; - - /* Temporarily switch back to the Cogl context */ - winsys->restore_context (ctx); - - dst_texture = - cogl_gles2_texture_2d_new_from_handle (gles2_ctx->context, - gles2_ctx, - tex_id, - tex_object_data->width, - tex_object_data->height, - internal_format); - - if (dst_texture) - { - CoglTexture *src_texture = - COGL_OFFSCREEN (gles2_ctx->read_buffer)->texture; - CoglPipeline *pipeline = cogl_pipeline_new (ctx); - const CoglOffscreenFlags flags = COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL; - CoglOffscreen *offscreen = - _cogl_offscreen_new_with_texture_full (COGL_TEXTURE (dst_texture), - flags, level); - int src_width = cogl_texture_get_width (src_texture); - int src_height = cogl_texture_get_height (src_texture); - /* The framebuffer size might be different from the texture size - * if a level > 0 is used */ - int dst_width = - cogl_framebuffer_get_width (COGL_FRAMEBUFFER (offscreen)); - int dst_height = - cogl_framebuffer_get_height (COGL_FRAMEBUFFER (offscreen)); - float x_1, y_1, x_2, y_2, s_1, t_1, s_2, t_2; - - cogl_pipeline_set_layer_texture (pipeline, 0, src_texture); - cogl_pipeline_set_blend (pipeline, - "RGBA = ADD(SRC_COLOR, 0)", - NULL); - cogl_pipeline_set_layer_filters (pipeline, - 0, /* layer_num */ - COGL_PIPELINE_FILTER_NEAREST, - COGL_PIPELINE_FILTER_NEAREST); - - x_1 = dst_x * 2.0f / dst_width - 1.0f; - y_1 = dst_y * 2.0f / dst_height - 1.0f; - x_2 = x_1 + width * 2.0f / dst_width; - y_2 = y_1 + height * 2.0f / dst_height; - - s_1 = src_x / (float) src_width; - t_1 = 1.0f - src_y / (float) src_height; - s_2 = (src_x + width) / (float) src_width; - t_2 = 1.0f - (src_y + height) / (float) src_height; - - cogl_framebuffer_draw_textured_rectangle (COGL_FRAMEBUFFER (offscreen), - pipeline, - x_1, y_1, - x_2, y_2, - s_1, t_1, - s_2, t_2); - - _cogl_framebuffer_flush_journal (COGL_FRAMEBUFFER (offscreen)); - - /* We need to make sure the rendering is complete before the - * blit will be ready in the GLES2 context */ - ctx->glFinish (); - - cogl_object_unref (pipeline); - cogl_object_unref (dst_texture); - cogl_object_unref (offscreen); - } - - winsys->set_gles2_context (gles2_ctx, NULL); - - /* From what I understand of the GL spec, changes to a shared object - * are not guaranteed to be propagated to another context until that - * object is rebound in that context so we can just rebind it - * here */ - gles2_ctx->vtable->glBindTexture (GL_TEXTURE_2D, tex_id); -} - -/* We wrap glBindFramebuffer so that when framebuffer 0 is bound - * we can instead bind the write_framebuffer passed to - * cogl_push_gles2_context(). - */ -static void -gl_bind_framebuffer_wrapper (GLenum target, GLuint framebuffer) -{ - CoglGLES2Context *gles2_ctx = current_gles2_context; - - gles2_ctx->current_fbo_handle = framebuffer; - - if (framebuffer == 0 && cogl_is_offscreen (gles2_ctx->write_buffer)) - { - CoglGLES2Offscreen *write = gles2_ctx->gles2_write_buffer; - framebuffer = write->gl_framebuffer.fbo_handle; - } - - gles2_ctx->context->glBindFramebuffer (target, framebuffer); - - update_current_flip_state (gles2_ctx); -} - -static int -transient_bind_read_buffer (CoglGLES2Context *gles2_ctx) -{ - if (gles2_ctx->current_fbo_handle == 0) - { - if (cogl_is_offscreen (gles2_ctx->read_buffer)) - { - CoglGLES2Offscreen *read = gles2_ctx->gles2_read_buffer; - GLuint read_fbo_handle = read->gl_framebuffer.fbo_handle; - - gles2_ctx->context->glBindFramebuffer (GL_FRAMEBUFFER, - read_fbo_handle); - - return RESTORE_FB_FROM_OFFSCREEN; - } - else - { - _cogl_framebuffer_gl_bind (gles2_ctx->read_buffer, - 0 /* target ignored */); - - return RESTORE_FB_FROM_ONSCREEN; - } - } - else - return RESTORE_FB_NONE; -} - -static void -restore_write_buffer (CoglGLES2Context *gles2_ctx, - int restore_mode) -{ - switch (restore_mode) - { - case RESTORE_FB_FROM_OFFSCREEN: - - gl_bind_framebuffer_wrapper (GL_FRAMEBUFFER, 0); - - break; - case RESTORE_FB_FROM_ONSCREEN: - - /* Note: we can't restore the original write buffer using - * _cogl_framebuffer_gl_bind() if it's an offscreen - * framebuffer because _cogl_framebuffer_gl_bind() doesn't - * know about the fbo handle owned by the gles2 context. - */ - if (cogl_is_offscreen (gles2_ctx->write_buffer)) - gl_bind_framebuffer_wrapper (GL_FRAMEBUFFER, 0); - else - _cogl_framebuffer_gl_bind (gles2_ctx->write_buffer, GL_FRAMEBUFFER); - - break; - case RESTORE_FB_NONE: - break; - } -} - -/* We wrap glReadPixels so when framebuffer 0 is bound then we can - * read from the read_framebuffer passed to cogl_push_gles2_context(). - */ -static void -gl_read_pixels_wrapper (GLint x, - GLint y, - GLsizei width, - GLsizei height, - GLenum format, - GLenum type, - GLvoid *pixels) -{ - CoglGLES2Context *gles2_ctx = current_gles2_context; - int restore_mode = transient_bind_read_buffer (gles2_ctx); - - gles2_ctx->context->glReadPixels (x, y, width, height, format, type, pixels); - - restore_write_buffer (gles2_ctx, restore_mode); - - /* If the read buffer is a CoglOffscreen then the data will be - * upside down compared to what GL expects so we need to flip it */ - if (gles2_ctx->current_fbo_handle == 0 && - cogl_is_offscreen (gles2_ctx->read_buffer)) - { - int bpp, bytes_per_row, stride, y; - uint8_t *bytes = pixels; - uint8_t *temprow; - - /* Try to determine the bytes per pixel for the given - * format/type combination. If there's a format which doesn't - * make sense then we'll just give up because GL will probably - * have just thrown an error */ - switch (format) - { - case GL_RGB: - switch (type) - { - case GL_UNSIGNED_BYTE: - bpp = 3; - break; - - case GL_UNSIGNED_SHORT_5_6_5: - bpp = 2; - break; - - default: - return; - } - break; - - case GL_RGBA: - switch (type) - { - case GL_UNSIGNED_BYTE: - bpp = 4; - break; - - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_5_5_5_1: - bpp = 2; - break; - - default: - return; - } - break; - - case GL_ALPHA: - switch (type) - { - case GL_UNSIGNED_BYTE: - bpp = 1; - break; - - default: - return; - } - break; - - default: - return; - } - - bytes_per_row = bpp * width; - stride = ((bytes_per_row + gles2_ctx->pack_alignment - 1) & - ~(gles2_ctx->pack_alignment - 1)); - temprow = g_alloca (bytes_per_row); - - /* vertically flip the buffer in-place */ - for (y = 0; y < height / 2; y++) - { - if (y != height - y - 1) /* skip center row */ - { - memcpy (temprow, - bytes + y * stride, - bytes_per_row); - memcpy (bytes + y * stride, - bytes + (height - y - 1) * stride, - bytes_per_row); - memcpy (bytes + (height - y - 1) * stride, - temprow, - bytes_per_row); - } - } - } -} - -static void -gl_copy_tex_image_2d_wrapper (GLenum target, - GLint level, - GLenum internal_format, - GLint x, - GLint y, - GLsizei width, - GLsizei height, - GLint border) -{ - CoglGLES2Context *gles2_ctx = current_gles2_context; - - /* If we are reading from a CoglOffscreen buffer then the image will - * be upside down with respect to what GL expects so we can't use - * glCopyTexImage2D. Instead we we'll try to use the Cogl API to - * flip it */ - if (gles2_ctx->current_fbo_handle == 0 && - cogl_is_offscreen (gles2_ctx->read_buffer)) - { - /* This will only work with the GL_TEXTURE_2D target. FIXME: - * GLES2 also supports setting cube map textures with - * glTexImage2D so we need to handle that too */ - if (target != GL_TEXTURE_2D) - return; - - /* Create an empty texture to hold the data */ - gles2_ctx->vtable->glTexImage2D (target, - level, - internal_format, - width, height, - border, - internal_format, /* format */ - GL_UNSIGNED_BYTE, /* type */ - NULL /* data */); - - copy_flipped_texture (gles2_ctx, - level, - x, y, /* src_x/src_y */ - 0, 0, /* dst_x/dst_y */ - width, height); - } - else - { - int restore_mode = transient_bind_read_buffer (gles2_ctx); - - gles2_ctx->context->glCopyTexImage2D (target, level, internal_format, - x, y, width, height, border); - - restore_write_buffer (gles2_ctx, restore_mode); - - set_texture_object_data (gles2_ctx, - target, - level, - internal_format, - width, height); - } -} - -static void -gl_copy_tex_sub_image_2d_wrapper (GLenum target, - GLint level, - GLint xoffset, - GLint yoffset, - GLint x, - GLint y, - GLsizei width, - GLsizei height) -{ - CoglGLES2Context *gles2_ctx = current_gles2_context; - - /* If we are reading from a CoglOffscreen buffer then the image will - * be upside down with respect to what GL expects so we can't use - * glCopyTexSubImage2D. Instead we we'll try to use the Cogl API to - * flip it */ - if (gles2_ctx->current_fbo_handle == 0 && - cogl_is_offscreen (gles2_ctx->read_buffer)) - { - /* This will only work with the GL_TEXTURE_2D target. FIXME: - * GLES2 also supports setting cube map textures with - * glTexImage2D so we need to handle that too */ - if (target != GL_TEXTURE_2D) - return; - - copy_flipped_texture (gles2_ctx, - level, - x, y, /* src_x/src_y */ - xoffset, yoffset, /* dst_x/dst_y */ - width, height); - } - else - { - int restore_mode = transient_bind_read_buffer (gles2_ctx); - - gles2_ctx->context->glCopyTexSubImage2D (target, level, - xoffset, yoffset, - x, y, width, height); - - restore_write_buffer (gles2_ctx, restore_mode); - } -} - -static GLuint -gl_create_shader_wrapper (GLenum type) -{ - CoglGLES2Context *gles2_ctx = current_gles2_context; - GLuint id; - - id = gles2_ctx->context->glCreateShader (type); - - if (id != 0) - { - CoglGLES2ShaderData *data = g_slice_new (CoglGLES2ShaderData); - - data->object_id = id; - data->type = type; - data->ref_count = 1; - data->deleted = FALSE; - - g_hash_table_insert (gles2_ctx->shader_map, - GINT_TO_POINTER (id), - data); - } - - return id; -} - -static void -gl_delete_shader_wrapper (GLuint shader) -{ - CoglGLES2Context *gles2_ctx = current_gles2_context; - CoglGLES2ShaderData *shader_data; - - if ((shader_data = g_hash_table_lookup (gles2_ctx->shader_map, - GINT_TO_POINTER (shader))) && - !shader_data->deleted) - { - shader_data->deleted = TRUE; - shader_data_unref (gles2_ctx, shader_data); - } - - gles2_ctx->context->glDeleteShader (shader); -} - -static GLuint -gl_create_program_wrapper (void) -{ - CoglGLES2Context *gles2_ctx = current_gles2_context; - GLuint id; - - id = gles2_ctx->context->glCreateProgram (); - - if (id != 0) - { - CoglGLES2ProgramData *data = g_slice_new (CoglGLES2ProgramData); - - data->object_id = id; - data->attached_shaders = NULL; - data->ref_count = 1; - data->deleted = FALSE; - data->context = gles2_ctx; - data->flip_vector_location = 0; - data->flip_vector_state = COGL_GLES2_FLIP_STATE_UNKNOWN; - - g_hash_table_insert (gles2_ctx->program_map, - GINT_TO_POINTER (id), - data); - } - - return id; -} - -static void -gl_delete_program_wrapper (GLuint program) -{ - CoglGLES2Context *gles2_ctx = current_gles2_context; - CoglGLES2ProgramData *program_data; - - if ((program_data = g_hash_table_lookup (gles2_ctx->program_map, - GINT_TO_POINTER (program))) && - !program_data->deleted) - { - program_data->deleted = TRUE; - program_data_unref (program_data); - } - - gles2_ctx->context->glDeleteProgram (program); -} - -static void -gl_use_program_wrapper (GLuint program) -{ - CoglGLES2Context *gles2_ctx = current_gles2_context; - CoglGLES2ProgramData *program_data; - - program_data = g_hash_table_lookup (gles2_ctx->program_map, - GINT_TO_POINTER (program)); - - if (program_data) - program_data->ref_count++; - if (gles2_ctx->current_program) - program_data_unref (gles2_ctx->current_program); - - gles2_ctx->current_program = program_data; - - gles2_ctx->context->glUseProgram (program); -} - -static void -gl_attach_shader_wrapper (GLuint program, - GLuint shader) -{ - CoglGLES2Context *gles2_ctx = current_gles2_context; - CoglGLES2ProgramData *program_data; - CoglGLES2ShaderData *shader_data; - - if ((program_data = g_hash_table_lookup (gles2_ctx->program_map, - GINT_TO_POINTER (program))) && - (shader_data = g_hash_table_lookup (gles2_ctx->shader_map, - GINT_TO_POINTER (shader))) && - /* Ignore attempts to attach a shader that is already attached */ - g_list_find (program_data->attached_shaders, shader_data) == NULL) - { - shader_data->ref_count++; - program_data->attached_shaders = - g_list_prepend (program_data->attached_shaders, shader_data); - } - - gles2_ctx->context->glAttachShader (program, shader); -} - -static void -gl_detach_shader_wrapper (GLuint program, - GLuint shader) -{ - CoglGLES2Context *gles2_ctx = current_gles2_context; - CoglGLES2ProgramData *program_data; - CoglGLES2ShaderData *shader_data; - - if ((program_data = g_hash_table_lookup (gles2_ctx->program_map, - GINT_TO_POINTER (program))) && - (shader_data = g_hash_table_lookup (gles2_ctx->shader_map, - GINT_TO_POINTER (shader)))) - detach_shader (program_data, shader_data); - - gles2_ctx->context->glDetachShader (program, shader); -} - -static void -gl_shader_source_wrapper (GLuint shader, - GLsizei count, - const char *const *string, - const GLint *length) -{ - CoglGLES2Context *gles2_ctx = current_gles2_context; - CoglGLES2ShaderData *shader_data; - - if ((shader_data = g_hash_table_lookup (gles2_ctx->shader_map, - GINT_TO_POINTER (shader))) && - shader_data->type == GL_VERTEX_SHADER) - { - char **string_copy = g_alloca ((count + 1) * sizeof (char *)); - int *length_copy = g_alloca ((count + 1) * sizeof (int)); - int i; - - /* Replace any occurences of the symbol 'main' with a different - * symbol so that we can provide our own wrapper main - * function */ - - for (i = 0; i < count; i++) - { - int string_length; - - if (length == NULL || length[i] < 0) - string_length = strlen (string[i]); - else - string_length = length[i]; - - string_copy[i] = g_memdup (string[i], string_length); - - replace_token (string_copy[i], - "main", - MAIN_WRAPPER_REPLACEMENT_NAME, - string_length); - - length_copy[i] = string_length; - } - - string_copy[count] = (char *) main_wrapper_function; - length_copy[count] = sizeof (main_wrapper_function) - 1; - - gles2_ctx->context->glShaderSource (shader, - count + 1, - (const char *const *) string_copy, - length_copy); - - /* Note: we don't need to free the last entry in string_copy[] - * because it is our static wrapper string... */ - for (i = 0; i < count; i++) - free (string_copy[i]); - } - else - gles2_ctx->context->glShaderSource (shader, count, string, length); -} - -static void -gl_get_shader_source_wrapper (GLuint shader, - GLsizei buf_size, - GLsizei *length_out, - GLchar *source) -{ - CoglGLES2Context *gles2_ctx = current_gles2_context; - CoglGLES2ShaderData *shader_data; - GLsizei length; - - gles2_ctx->context->glGetShaderSource (shader, - buf_size, - &length, - source); - - if ((shader_data = g_hash_table_lookup (gles2_ctx->shader_map, - GINT_TO_POINTER (shader))) && - shader_data->type == GL_VERTEX_SHADER) - { - GLsizei copy_length = MIN (length, buf_size - 1); - static const char wrapper_marker[] = MAIN_WRAPPER_BEGIN; - char *wrapper_start; - - /* Strip out the wrapper snippet we added when the source was - * specified */ - wrapper_start = _cogl_util_memmem (source, - copy_length, - wrapper_marker, - sizeof (wrapper_marker) - 1); - if (wrapper_start) - { - length = wrapper_start - source; - copy_length = length; - *wrapper_start = '\0'; - } - - /* Correct the name of the main function back to its original */ - replace_token (source, - MAIN_WRAPPER_REPLACEMENT_NAME, - "main", - copy_length); - } - - if (length_out) - *length_out = length; -} - -static void -gl_link_program_wrapper (GLuint program) -{ - CoglGLES2Context *gles2_ctx = current_gles2_context; - CoglGLES2ProgramData *program_data; - - gles2_ctx->context->glLinkProgram (program); - - program_data = g_hash_table_lookup (gles2_ctx->program_map, - GINT_TO_POINTER (program)); - - if (program_data) - { - GLint status; - - gles2_ctx->context->glGetProgramiv (program, GL_LINK_STATUS, &status); - - if (status) - program_data->flip_vector_location = - gles2_ctx->context->glGetUniformLocation (program, - MAIN_WRAPPER_FLIP_UNIFORM); - } -} - -static void -gl_get_program_iv_wrapper (GLuint program, - GLenum pname, - GLint *params) -{ - CoglGLES2Context *gles2_ctx = current_gles2_context; - - gles2_ctx->context->glGetProgramiv (program, pname, params); - - switch (pname) - { - case GL_ATTACHED_SHADERS: - /* Decrease the number of shaders to try and hide the shader - * wrapper we added */ - if (*params > 1) - (*params)--; - break; - } -} - -static void -flush_viewport_state (CoglGLES2Context *gles2_ctx) -{ - if (gles2_ctx->viewport_dirty) - { - int y; - - if (gles2_ctx->current_flip_state == COGL_GLES2_FLIP_STATE_FLIPPED) - { - /* We need to know the height of the current framebuffer in - * order to flip the viewport. Fortunately we don't need to - * track the height of the FBOs created within the GLES2 - * context because we would never be flipping if they are - * bound so we can just assume Cogl's framebuffer is bound - * when we are flipping */ - int fb_height = cogl_framebuffer_get_height (gles2_ctx->write_buffer); - y = fb_height - (gles2_ctx->viewport[1] + gles2_ctx->viewport[3]); - } - else - y = gles2_ctx->viewport[1]; - - gles2_ctx->context->glViewport (gles2_ctx->viewport[0], - y, - gles2_ctx->viewport[2], - gles2_ctx->viewport[3]); - - gles2_ctx->viewport_dirty = FALSE; - } -} - -static void -flush_scissor_state (CoglGLES2Context *gles2_ctx) -{ - if (gles2_ctx->scissor_dirty) - { - int y; - - if (gles2_ctx->current_flip_state == COGL_GLES2_FLIP_STATE_FLIPPED) - { - /* See comment above about the viewport flipping */ - int fb_height = cogl_framebuffer_get_height (gles2_ctx->write_buffer); - y = fb_height - (gles2_ctx->scissor[1] + gles2_ctx->scissor[3]); - } - else - y = gles2_ctx->scissor[1]; - - gles2_ctx->context->glScissor (gles2_ctx->scissor[0], - y, - gles2_ctx->scissor[2], - gles2_ctx->scissor[3]); - - gles2_ctx->scissor_dirty = FALSE; - } -} - -static void -flush_front_face_state (CoglGLES2Context *gles2_ctx) -{ - if (gles2_ctx->front_face_dirty) - { - GLenum front_face; - - if (gles2_ctx->current_flip_state == COGL_GLES2_FLIP_STATE_FLIPPED) - { - if (gles2_ctx->front_face == GL_CW) - front_face = GL_CCW; - else - front_face = GL_CW; - } - else - front_face = gles2_ctx->front_face; - - gles2_ctx->context->glFrontFace (front_face); - - gles2_ctx->front_face_dirty = FALSE; - } -} - -static void -pre_draw_wrapper (CoglGLES2Context *gles2_ctx) -{ - /* If there's no current program then we'll just let GL report an - * error */ - if (gles2_ctx->current_program == NULL) - return; - - flush_viewport_state (gles2_ctx); - flush_scissor_state (gles2_ctx); - flush_front_face_state (gles2_ctx); - - /* We want to flip rendering when the application is rendering to a - * Cogl offscreen buffer in order to maintain the flipped texture - * coordinate origin */ - if (gles2_ctx->current_flip_state != - gles2_ctx->current_program->flip_vector_state) - { - GLuint location = - gles2_ctx->current_program->flip_vector_location; - float value[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; - - if (gles2_ctx->current_flip_state == COGL_GLES2_FLIP_STATE_FLIPPED) - value[1] = -1.0f; - - gles2_ctx->context->glUniform4fv (location, 1, value); - - gles2_ctx->current_program->flip_vector_state = - gles2_ctx->current_flip_state; - } -} - -static void -gl_clear_wrapper (GLbitfield mask) -{ - CoglGLES2Context *gles2_ctx = current_gles2_context; - - /* Clearing is affected by the scissor state so we need to ensure - * that's flushed */ - flush_scissor_state (gles2_ctx); - - gles2_ctx->context->glClear (mask); -} - -static void -gl_draw_elements_wrapper (GLenum mode, - GLsizei count, - GLenum type, - const GLvoid *indices) -{ - CoglGLES2Context *gles2_ctx = current_gles2_context; - - pre_draw_wrapper (gles2_ctx); - - gles2_ctx->context->glDrawElements (mode, count, type, indices); -} - -static void -gl_draw_arrays_wrapper (GLenum mode, - GLint first, - GLsizei count) -{ - CoglGLES2Context *gles2_ctx = current_gles2_context; - - pre_draw_wrapper (gles2_ctx); - - gles2_ctx->context->glDrawArrays (mode, first, count); -} - -static void -gl_get_program_info_log_wrapper (GLuint program, - GLsizei buf_size, - GLsizei *length_out, - GLchar *info_log) -{ - CoglGLES2Context *gles2_ctx = current_gles2_context; - GLsizei length; - - gles2_ctx->context->glGetProgramInfoLog (program, - buf_size, - &length, - info_log); - - replace_token (info_log, - MAIN_WRAPPER_REPLACEMENT_NAME, - "main", - MIN (length, buf_size)); - - if (length_out) - *length_out = length; -} - -static void -gl_get_shader_info_log_wrapper (GLuint shader, - GLsizei buf_size, - GLsizei *length_out, - GLchar *info_log) -{ - CoglGLES2Context *gles2_ctx = current_gles2_context; - GLsizei length; - - gles2_ctx->context->glGetShaderInfoLog (shader, - buf_size, - &length, - info_log); - - replace_token (info_log, - MAIN_WRAPPER_REPLACEMENT_NAME, - "main", - MIN (length, buf_size)); - - if (length_out) - *length_out = length; -} - -static void -gl_front_face_wrapper (GLenum mode) -{ - CoglGLES2Context *gles2_ctx = current_gles2_context; - - /* If the mode doesn't make any sense then we'll just let the - * context deal with it directly so that it will throw an error */ - if (mode != GL_CW && mode != GL_CCW) - gles2_ctx->context->glFrontFace (mode); - else - { - gles2_ctx->front_face = mode; - gles2_ctx->front_face_dirty = TRUE; - } -} - -static void -gl_viewport_wrapper (GLint x, - GLint y, - GLsizei width, - GLsizei height) -{ - CoglGLES2Context *gles2_ctx = current_gles2_context; - - /* If the viewport is invalid then we'll just let the context deal - * with it directly so that it will throw an error */ - if (width < 0 || height < 0) - gles2_ctx->context->glViewport (x, y, width, height); - else - { - gles2_ctx->viewport[0] = x; - gles2_ctx->viewport[1] = y; - gles2_ctx->viewport[2] = width; - gles2_ctx->viewport[3] = height; - gles2_ctx->viewport_dirty = TRUE; - } -} - -static void -gl_scissor_wrapper (GLint x, - GLint y, - GLsizei width, - GLsizei height) -{ - CoglGLES2Context *gles2_ctx = current_gles2_context; - - /* If the scissor is invalid then we'll just let the context deal - * with it directly so that it will throw an error */ - if (width < 0 || height < 0) - gles2_ctx->context->glScissor (x, y, width, height); - else - { - gles2_ctx->scissor[0] = x; - gles2_ctx->scissor[1] = y; - gles2_ctx->scissor[2] = width; - gles2_ctx->scissor[3] = height; - gles2_ctx->scissor_dirty = TRUE; - } -} - -static void -gl_get_boolean_v_wrapper (GLenum pname, - GLboolean *params) -{ - CoglGLES2Context *gles2_ctx = current_gles2_context; - - switch (pname) - { - case GL_VIEWPORT: - { - int i; - - for (i = 0; i < 4; i++) - params[i] = !!gles2_ctx->viewport[i]; - } - break; - - case GL_SCISSOR_BOX: - { - int i; - - for (i = 0; i < 4; i++) - params[i] = !!gles2_ctx->scissor[i]; - } - break; - - default: - gles2_ctx->context->glGetBooleanv (pname, params); - } -} - -static void -gl_get_integer_v_wrapper (GLenum pname, - GLint *params) -{ - CoglGLES2Context *gles2_ctx = current_gles2_context; - - switch (pname) - { - case GL_VIEWPORT: - { - int i; - - for (i = 0; i < 4; i++) - params[i] = gles2_ctx->viewport[i]; - } - break; - - case GL_SCISSOR_BOX: - { - int i; - - for (i = 0; i < 4; i++) - params[i] = gles2_ctx->scissor[i]; - } - break; - - case GL_FRONT_FACE: - params[0] = gles2_ctx->front_face; - break; - - default: - gles2_ctx->context->glGetIntegerv (pname, params); - } -} - -static void -gl_get_float_v_wrapper (GLenum pname, - GLfloat *params) -{ - CoglGLES2Context *gles2_ctx = current_gles2_context; - - switch (pname) - { - case GL_VIEWPORT: - { - int i; - - for (i = 0; i < 4; i++) - params[i] = gles2_ctx->viewport[i]; - } - break; - - case GL_SCISSOR_BOX: - { - int i; - - for (i = 0; i < 4; i++) - params[i] = gles2_ctx->scissor[i]; - } - break; - - case GL_FRONT_FACE: - params[0] = gles2_ctx->front_face; - break; - - default: - gles2_ctx->context->glGetFloatv (pname, params); - } -} - -static void -gl_pixel_store_i_wrapper (GLenum pname, GLint param) -{ - CoglGLES2Context *gles2_ctx = current_gles2_context; - - gles2_ctx->context->glPixelStorei (pname, param); - - if (pname == GL_PACK_ALIGNMENT && - (param == 1 || param == 2 || param == 4 || param == 8)) - gles2_ctx->pack_alignment = param; -} - -static void -gl_active_texture_wrapper (GLenum texture) -{ - CoglGLES2Context *gles2_ctx = current_gles2_context; - int texture_unit; - - gles2_ctx->context->glActiveTexture (texture); - - texture_unit = texture - GL_TEXTURE0; - - /* If the application is binding some odd looking texture unit - * numbers then we'll just ignore it and hope that GL has generated - * an error */ - if (texture_unit >= 0 && texture_unit < 512) - { - gles2_ctx->current_texture_unit = texture_unit; - g_array_set_size (gles2_ctx->texture_units, - MAX (texture_unit, gles2_ctx->texture_units->len)); - } -} - -static void -gl_delete_textures_wrapper (GLsizei n, - const GLuint *textures) -{ - CoglGLES2Context *gles2_ctx = current_gles2_context; - int texture_index; - int texture_unit; - - gles2_ctx->context->glDeleteTextures (n, textures); - - for (texture_index = 0; texture_index < n; texture_index++) - { - /* Reset any texture units that have any of these textures bound */ - for (texture_unit = 0; - texture_unit < gles2_ctx->texture_units->len; - texture_unit++) - { - CoglGLES2TextureUnitData *unit = - &g_array_index (gles2_ctx->texture_units, - CoglGLES2TextureUnitData, - texture_unit); - - if (unit->current_texture_2d == textures[texture_index]) - unit->current_texture_2d = 0; - } - - /* Remove the binding. We can do this immediately because unlike - * shader objects the deletion isn't delayed until the object is - * unbound */ - g_hash_table_remove (gles2_ctx->texture_object_map, - GUINT_TO_POINTER (textures[texture_index])); - } -} - -static void -gl_bind_texture_wrapper (GLenum target, - GLuint texture) -{ - CoglGLES2Context *gles2_ctx = current_gles2_context; - - gles2_ctx->context->glBindTexture (target, texture); - - if (target == GL_TEXTURE_2D) - { - CoglGLES2TextureUnitData *unit = - &g_array_index (gles2_ctx->texture_units, - CoglGLES2TextureUnitData, - gles2_ctx->current_texture_unit); - unit->current_texture_2d = texture; - } -} - -static void -gl_tex_image_2d_wrapper (GLenum target, - GLint level, - GLint internal_format, - GLsizei width, - GLsizei height, - GLint border, - GLenum format, - GLenum type, - const GLvoid *pixels) -{ - CoglGLES2Context *gles2_ctx = current_gles2_context; - - gles2_ctx->context->glTexImage2D (target, - level, - internal_format, - width, height, - border, - format, - type, - pixels); - - set_texture_object_data (gles2_ctx, - target, - level, - internal_format, - width, height); -} - -static void -_cogl_gles2_offscreen_free (CoglGLES2Offscreen *gles2_offscreen) -{ - _cogl_list_remove (&gles2_offscreen->link); - g_slice_free (CoglGLES2Offscreen, gles2_offscreen); -} - -static void -force_delete_program_object (CoglGLES2Context *context, - CoglGLES2ProgramData *program_data) -{ - if (!program_data->deleted) - { - context->context->glDeleteProgram (program_data->object_id); - program_data->deleted = TRUE; - program_data_unref (program_data); - } -} - -static void -force_delete_shader_object (CoglGLES2Context *context, - CoglGLES2ShaderData *shader_data) -{ - if (!shader_data->deleted) - { - context->context->glDeleteShader (shader_data->object_id); - shader_data->deleted = TRUE; - shader_data_unref (context, shader_data); - } -} - -static void -force_delete_texture_object (CoglGLES2Context *context, - CoglGLES2TextureObjectData *texture_data) -{ - context->context->glDeleteTextures (1, &texture_data->object_id); -} - -static void -_cogl_gles2_context_free (CoglGLES2Context *gles2_context) -{ - CoglContext *ctx = gles2_context->context; - const CoglWinsysVtable *winsys; - GList *objects, *l; - - if (gles2_context->current_program) - program_data_unref (gles2_context->current_program); - - /* Try to forcibly delete any shaders, programs and textures so that - * they won't get leaked. Because all GLES2 contexts are in the same - * share list as Cogl's context these won't get deleted by default. - * FIXME: we should do this for all of the other resources too, like - * textures */ - objects = g_hash_table_get_values (gles2_context->program_map); - for (l = objects; l; l = l->next) - force_delete_program_object (gles2_context, l->data); - g_list_free (objects); - objects = g_hash_table_get_values (gles2_context->shader_map); - for (l = objects; l; l = l->next) - force_delete_shader_object (gles2_context, l->data); - g_list_free (objects); - objects = g_hash_table_get_values (gles2_context->texture_object_map); - for (l = objects; l; l = l->next) - force_delete_texture_object (gles2_context, l->data); - g_list_free (objects); - - /* All of the program and shader objects should now be destroyed */ - if (g_hash_table_size (gles2_context->program_map) > 0) - g_warning ("Program objects have been leaked from a CoglGLES2Context"); - if (g_hash_table_size (gles2_context->shader_map) > 0) - g_warning ("Shader objects have been leaked from a CoglGLES2Context"); - - g_hash_table_destroy (gles2_context->program_map); - g_hash_table_destroy (gles2_context->shader_map); - - g_hash_table_destroy (gles2_context->texture_object_map); - g_array_free (gles2_context->texture_units, TRUE); - - winsys = ctx->display->renderer->winsys_vtable; - winsys->destroy_gles2_context (gles2_context); - - while (!_cogl_list_empty (&gles2_context->foreign_offscreens)) - { - CoglGLES2Offscreen *gles2_offscreen = - _cogl_container_of (gles2_context->foreign_offscreens.next, - CoglGLES2Offscreen, - link); - - /* Note: this will also indirectly free the gles2_offscreen by - * calling the destroy notify for the _user_data */ - cogl_object_set_user_data (COGL_OBJECT (gles2_offscreen->original_offscreen), - &offscreen_wrapper_key, - NULL, - NULL); - } - - free (gles2_context->vtable); - - free (gles2_context); -} - -static void -free_shader_data (CoglGLES2ShaderData *data) -{ - g_slice_free (CoglGLES2ShaderData, data); -} - -static void -free_program_data (CoglGLES2ProgramData *data) -{ - while (data->attached_shaders) - detach_shader (data, - data->attached_shaders->data); - - g_slice_free (CoglGLES2ProgramData, data); -} - -static void -free_texture_object_data (CoglGLES2TextureObjectData *data) -{ - g_slice_free (CoglGLES2TextureObjectData, data); -} - -CoglGLES2Context * -cogl_gles2_context_new (CoglContext *ctx, CoglError **error) -{ - CoglGLES2Context *gles2_ctx; - const CoglWinsysVtable *winsys; - - if (!cogl_has_feature (ctx, COGL_FEATURE_ID_GLES2_CONTEXT)) - { - _cogl_set_error (error, COGL_GLES2_CONTEXT_ERROR, - COGL_GLES2_CONTEXT_ERROR_UNSUPPORTED, - "Backend doesn't support creating GLES2 contexts"); - - return NULL; - } - - gles2_ctx = calloc (1, sizeof (CoglGLES2Context)); - - gles2_ctx->context = ctx; - - _cogl_list_init (&gles2_ctx->foreign_offscreens); - - winsys = ctx->display->renderer->winsys_vtable; - gles2_ctx->winsys = winsys->context_create_gles2_context (ctx, error); - if (gles2_ctx->winsys == NULL) - { - free (gles2_ctx); - return NULL; - } - - gles2_ctx->current_flip_state = COGL_GLES2_FLIP_STATE_UNKNOWN; - gles2_ctx->viewport_dirty = TRUE; - gles2_ctx->scissor_dirty = TRUE; - gles2_ctx->front_face_dirty = TRUE; - gles2_ctx->front_face = GL_CCW; - gles2_ctx->pack_alignment = 4; - - gles2_ctx->vtable = calloc (1, sizeof (CoglGLES2Vtable)); -#define COGL_EXT_BEGIN(name, \ - min_gl_major, min_gl_minor, \ - gles_availability, \ - extension_suffixes, extension_names) - -#define COGL_EXT_FUNCTION(ret, name, args) \ - gles2_ctx->vtable->name = (void *) ctx->name; - -#define COGL_EXT_END() - -#include "gl-prototypes/cogl-gles2-functions.h" - -#undef COGL_EXT_BEGIN -#undef COGL_EXT_FUNCTION -#undef COGL_EXT_END - - gles2_ctx->vtable->glBindFramebuffer = - (void *) gl_bind_framebuffer_wrapper; - gles2_ctx->vtable->glReadPixels = - (void *) gl_read_pixels_wrapper; - gles2_ctx->vtable->glCopyTexImage2D = - (void *) gl_copy_tex_image_2d_wrapper; - gles2_ctx->vtable->glCopyTexSubImage2D = - (void *) gl_copy_tex_sub_image_2d_wrapper; - - gles2_ctx->vtable->glCreateShader = gl_create_shader_wrapper; - gles2_ctx->vtable->glDeleteShader = gl_delete_shader_wrapper; - gles2_ctx->vtable->glCreateProgram = gl_create_program_wrapper; - gles2_ctx->vtable->glDeleteProgram = gl_delete_program_wrapper; - gles2_ctx->vtable->glUseProgram = gl_use_program_wrapper; - gles2_ctx->vtable->glAttachShader = gl_attach_shader_wrapper; - gles2_ctx->vtable->glDetachShader = gl_detach_shader_wrapper; - gles2_ctx->vtable->glShaderSource = gl_shader_source_wrapper; - gles2_ctx->vtable->glGetShaderSource = gl_get_shader_source_wrapper; - gles2_ctx->vtable->glLinkProgram = gl_link_program_wrapper; - gles2_ctx->vtable->glGetProgramiv = gl_get_program_iv_wrapper; - gles2_ctx->vtable->glGetProgramInfoLog = gl_get_program_info_log_wrapper; - gles2_ctx->vtable->glGetShaderInfoLog = gl_get_shader_info_log_wrapper; - gles2_ctx->vtable->glClear = gl_clear_wrapper; - gles2_ctx->vtable->glDrawElements = gl_draw_elements_wrapper; - gles2_ctx->vtable->glDrawArrays = gl_draw_arrays_wrapper; - gles2_ctx->vtable->glFrontFace = gl_front_face_wrapper; - gles2_ctx->vtable->glViewport = gl_viewport_wrapper; - gles2_ctx->vtable->glScissor = gl_scissor_wrapper; - gles2_ctx->vtable->glGetBooleanv = gl_get_boolean_v_wrapper; - gles2_ctx->vtable->glGetIntegerv = gl_get_integer_v_wrapper; - gles2_ctx->vtable->glGetFloatv = gl_get_float_v_wrapper; - gles2_ctx->vtable->glPixelStorei = gl_pixel_store_i_wrapper; - gles2_ctx->vtable->glActiveTexture = gl_active_texture_wrapper; - gles2_ctx->vtable->glDeleteTextures = gl_delete_textures_wrapper; - gles2_ctx->vtable->glBindTexture = gl_bind_texture_wrapper; - gles2_ctx->vtable->glTexImage2D = gl_tex_image_2d_wrapper; - - gles2_ctx->shader_map = - g_hash_table_new_full (g_direct_hash, - g_direct_equal, - NULL, /* key_destroy */ - (GDestroyNotify) free_shader_data); - gles2_ctx->program_map = - g_hash_table_new_full (g_direct_hash, - g_direct_equal, - NULL, /* key_destroy */ - (GDestroyNotify) free_program_data); - - gles2_ctx->texture_object_map = - g_hash_table_new_full (g_direct_hash, - g_direct_equal, - NULL, /* key_destroy */ - (GDestroyNotify) free_texture_object_data); - - gles2_ctx->texture_units = g_array_new (FALSE, /* not zero terminated */ - TRUE, /* clear */ - sizeof (CoglGLES2TextureUnitData)); - gles2_ctx->current_texture_unit = 0; - g_array_set_size (gles2_ctx->texture_units, 1); - - return _cogl_gles2_context_object_new (gles2_ctx); -} - -const CoglGLES2Vtable * -cogl_gles2_context_get_vtable (CoglGLES2Context *gles2_ctx) -{ - return gles2_ctx->vtable; -} - -/* When drawing to a CoglFramebuffer from a separate context we have - * to be able to allocate ancillary buffers for that context... - */ -static CoglGLES2Offscreen * -_cogl_gles2_offscreen_allocate (CoglOffscreen *offscreen, - CoglGLES2Context *gles2_context, - CoglError **error) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (offscreen); - const CoglWinsysVtable *winsys; - CoglError *internal_error = NULL; - CoglGLES2Offscreen *gles2_offscreen; - int level_width; - int level_height; - - if (!framebuffer->allocated && - !cogl_framebuffer_allocate (framebuffer, error)) - { - return NULL; - } - - _cogl_list_for_each (gles2_offscreen, - &gles2_context->foreign_offscreens, - link) - { - if (gles2_offscreen->original_offscreen == offscreen) - return gles2_offscreen; - } - - winsys = _cogl_framebuffer_get_winsys (framebuffer); - winsys->save_context (framebuffer->context); - if (!winsys->set_gles2_context (gles2_context, &internal_error)) - { - winsys->restore_context (framebuffer->context); - - cogl_error_free (internal_error); - _cogl_set_error (error, COGL_FRAMEBUFFER_ERROR, - COGL_FRAMEBUFFER_ERROR_ALLOCATE, - "Failed to bind gles2 context to create framebuffer"); - return NULL; - } - - gles2_offscreen = g_slice_new0 (CoglGLES2Offscreen); - - _cogl_texture_get_level_size (offscreen->texture, - offscreen->texture_level, - &level_width, - &level_height, - NULL); - - if (!_cogl_framebuffer_try_creating_gl_fbo (gles2_context->context, - offscreen->texture, - offscreen->texture_level, - level_width, - level_height, - offscreen->depth_texture, - &COGL_FRAMEBUFFER (offscreen)->config, - offscreen->allocation_flags, - &gles2_offscreen->gl_framebuffer)) - { - winsys->restore_context (framebuffer->context); - - g_slice_free (CoglGLES2Offscreen, gles2_offscreen); - - _cogl_set_error (error, COGL_FRAMEBUFFER_ERROR, - COGL_FRAMEBUFFER_ERROR_ALLOCATE, - "Failed to create an OpenGL framebuffer object"); - return NULL; - } - - winsys->restore_context (framebuffer->context); - - gles2_offscreen->original_offscreen = offscreen; - - _cogl_list_insert (&gles2_context->foreign_offscreens, - &gles2_offscreen->link); - - /* So we avoid building up an ever growing collection of ancillary - * buffers for wrapped framebuffers, we make sure that the wrappers - * get freed when the original offscreen framebuffer is freed. */ - cogl_object_set_user_data (COGL_OBJECT (framebuffer), - &offscreen_wrapper_key, - gles2_offscreen, - (CoglUserDataDestroyCallback) - _cogl_gles2_offscreen_free); - - return gles2_offscreen; -} - -CoglBool -cogl_push_gles2_context (CoglContext *ctx, - CoglGLES2Context *gles2_ctx, - CoglFramebuffer *read_buffer, - CoglFramebuffer *write_buffer, - CoglError **error) -{ - const CoglWinsysVtable *winsys = ctx->display->renderer->winsys_vtable; - CoglError *internal_error = NULL; - - _COGL_RETURN_VAL_IF_FAIL (gles2_ctx != NULL, FALSE); - - /* The read/write buffers are properties of the gles2 context and we - * don't currently track the read/write buffers as part of the stack - * entries so we explicitly don't allow the same context to be - * pushed multiple times. */ - if (g_queue_find (&ctx->gles2_context_stack, gles2_ctx)) - { - g_critical ("Pushing the same GLES2 context multiple times isn't " - "supported"); - return FALSE; - } - - if (ctx->gles2_context_stack.length == 0) - { - _cogl_journal_flush (read_buffer->journal); - if (write_buffer != read_buffer) - _cogl_journal_flush (write_buffer->journal); - winsys->save_context (ctx); - } - else - gles2_ctx->vtable->glFlush (); - - if (gles2_ctx->read_buffer != read_buffer) - { - if (cogl_is_offscreen (read_buffer)) - { - gles2_ctx->gles2_read_buffer = - _cogl_gles2_offscreen_allocate (COGL_OFFSCREEN (read_buffer), - gles2_ctx, - error); - /* XXX: what consistency guarantees should this api have? - * - * It should be safe to return at this point but we provide - * no guarantee to the caller whether their given buffers - * may be referenced and old buffers unreferenced even - * if the _push fails. */ - if (!gles2_ctx->gles2_read_buffer) - return FALSE; - } - else - gles2_ctx->gles2_read_buffer = NULL; - if (gles2_ctx->read_buffer) - cogl_object_unref (gles2_ctx->read_buffer); - gles2_ctx->read_buffer = cogl_object_ref (read_buffer); - } - - if (gles2_ctx->write_buffer != write_buffer) - { - if (cogl_is_offscreen (write_buffer)) - { - gles2_ctx->gles2_write_buffer = - _cogl_gles2_offscreen_allocate (COGL_OFFSCREEN (write_buffer), - gles2_ctx, - error); - /* XXX: what consistency guarantees should this api have? - * - * It should be safe to return at this point but we provide - * no guarantee to the caller whether their given buffers - * may be referenced and old buffers unreferenced even - * if the _push fails. */ - if (!gles2_ctx->gles2_write_buffer) - return FALSE; - } - else - gles2_ctx->gles2_write_buffer = NULL; - if (gles2_ctx->write_buffer) - cogl_object_unref (gles2_ctx->write_buffer); - gles2_ctx->write_buffer = cogl_object_ref (write_buffer); - - update_current_flip_state (gles2_ctx); - } - - if (!winsys->set_gles2_context (gles2_ctx, &internal_error)) - { - winsys->restore_context (ctx); - - cogl_error_free (internal_error); - _cogl_set_error (error, COGL_GLES2_CONTEXT_ERROR, - COGL_GLES2_CONTEXT_ERROR_DRIVER, - "Driver failed to make GLES2 context current"); - return FALSE; - } - - g_queue_push_tail (&ctx->gles2_context_stack, gles2_ctx); - - /* The last time this context was pushed may have been with a - * different offscreen draw framebuffer and so if GL framebuffer 0 - * is bound for this GLES2 context we may need to bind a new, - * corresponding, window system framebuffer... */ - if (gles2_ctx->current_fbo_handle == 0) - { - if (cogl_is_offscreen (gles2_ctx->write_buffer)) - { - CoglGLES2Offscreen *write = gles2_ctx->gles2_write_buffer; - GLuint handle = write->gl_framebuffer.fbo_handle; - gles2_ctx->context->glBindFramebuffer (GL_FRAMEBUFFER, handle); - } - } - - current_gles2_context = gles2_ctx; - - /* If this is the first time this gles2 context has been used then - * we'll force the viewport and scissor to the right size. GL has - * the semantics that the viewport and scissor default to the size - * of the first surface the context is used with. If the first - * CoglFramebuffer that this context is used with is an offscreen, - * then the surface from GL's point of view will be the 1x1 dummy - * surface so the viewport will be wrong. Therefore we just override - * the default viewport and scissor here */ - if (!gles2_ctx->has_been_bound) - { - int fb_width = cogl_framebuffer_get_width (write_buffer); - int fb_height = cogl_framebuffer_get_height (write_buffer); - - gles2_ctx->vtable->glViewport (0, 0, /* x/y */ - fb_width, fb_height); - gles2_ctx->vtable->glScissor (0, 0, /* x/y */ - fb_width, fb_height); - gles2_ctx->has_been_bound = TRUE; - } - - return TRUE; -} - -CoglGLES2Vtable * -cogl_gles2_get_current_vtable (void) -{ - return current_gles2_context ? current_gles2_context->vtable : NULL; -} - -void -cogl_pop_gles2_context (CoglContext *ctx) -{ - CoglGLES2Context *gles2_ctx; - const CoglWinsysVtable *winsys = ctx->display->renderer->winsys_vtable; - - _COGL_RETURN_IF_FAIL (ctx->gles2_context_stack.length > 0); - - g_queue_pop_tail (&ctx->gles2_context_stack); - - gles2_ctx = g_queue_peek_tail (&ctx->gles2_context_stack); - - if (gles2_ctx) - { - winsys->set_gles2_context (gles2_ctx, NULL); - current_gles2_context = gles2_ctx; - } - else - { - winsys->restore_context (ctx); - current_gles2_context = NULL; - } -} - -CoglTexture2D * -cogl_gles2_texture_2d_new_from_handle (CoglContext *ctx, - CoglGLES2Context *gles2_ctx, - unsigned int handle, - int width, - int height, - CoglPixelFormat format) -{ - return cogl_texture_2d_gl_new_from_foreign (ctx, - handle, - width, - height, - format); -} - -CoglBool -cogl_gles2_texture_get_handle (CoglTexture *texture, - unsigned int *handle, - unsigned int *target) -{ - return cogl_texture_get_gl_texture (texture, handle, target); -} diff --git a/cogl/cogl/cogl-gles2-types.h b/cogl/cogl/cogl-gles2-types.h deleted file mode 100644 index d07b1552f..000000000 --- a/cogl/cogl/cogl-gles2-types.h +++ /dev/null @@ -1,475 +0,0 @@ -#ifndef __COGL_GLES2_TYPES_H_ -#define __COGL_GLES2_TYPES_H_ - -/* $Revision: 16803 $ on $Date:: 2012-02-02 09:49:18 -0800 #$ */ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * This document is licensed under the SGI Free Software B License Version - * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . - */ - -/*------------------------------------------------------------------------- - * Data type definitions - *-----------------------------------------------------------------------*/ - -typedef void GLvoid; -typedef char GLchar; -typedef unsigned int GLenum; -typedef unsigned char GLboolean; -typedef unsigned int GLbitfield; -typedef int8_t GLbyte; -typedef short GLshort; -typedef int GLint; -typedef int GLsizei; -typedef uint8_t GLubyte; -typedef unsigned short GLushort; -typedef unsigned int GLuint; -typedef float GLfloat; -typedef float GLclampf; -typedef int32_t GLfixed; - -/* GL types for handling large vertex buffer objects */ -typedef signed long int GLintptr; -typedef long GLsizeiptr; - -/* OpenGL ES core versions */ -#define GL_ES_VERSION_2_0 1 - -/* ClearBufferMask */ -#define GL_DEPTH_BUFFER_BIT 0x00000100 -#define GL_STENCIL_BUFFER_BIT 0x00000400 -#define GL_COLOR_BUFFER_BIT 0x00004000 - -/* Boolean */ -#define GL_FALSE 0 -#define GL_TRUE 1 - -/* BeginMode */ -#define GL_POINTS 0x0000 -#define GL_LINES 0x0001 -#define GL_LINE_LOOP 0x0002 -#define GL_LINE_STRIP 0x0003 -#define GL_TRIANGLES 0x0004 -#define GL_TRIANGLE_STRIP 0x0005 -#define GL_TRIANGLE_FAN 0x0006 - -/* AlphaFunction (not supported in ES20) */ -/* GL_NEVER */ -/* GL_LESS */ -/* GL_EQUAL */ -/* GL_LEQUAL */ -/* GL_GREATER */ -/* GL_NOTEQUAL */ -/* GL_GEQUAL */ -/* GL_ALWAYS */ - -/* BlendingFactorDest */ -#define GL_ZERO 0 -#define GL_ONE 1 -#define GL_SRC_COLOR 0x0300 -#define GL_ONE_MINUS_SRC_COLOR 0x0301 -#define GL_SRC_ALPHA 0x0302 -#define GL_ONE_MINUS_SRC_ALPHA 0x0303 -#define GL_DST_ALPHA 0x0304 -#define GL_ONE_MINUS_DST_ALPHA 0x0305 - -/* BlendingFactorSrc */ -/* GL_ZERO */ -/* GL_ONE */ -#define GL_DST_COLOR 0x0306 -#define GL_ONE_MINUS_DST_COLOR 0x0307 -#define GL_SRC_ALPHA_SATURATE 0x0308 -/* GL_SRC_ALPHA */ -/* GL_ONE_MINUS_SRC_ALPHA */ -/* GL_DST_ALPHA */ -/* GL_ONE_MINUS_DST_ALPHA */ - -/* BlendEquationSeparate */ -#define GL_FUNC_ADD 0x8006 -#define GL_BLEND_EQUATION 0x8009 -#define GL_BLEND_EQUATION_RGB 0x8009 /* same as BLEND_EQUATION */ -#define GL_BLEND_EQUATION_ALPHA 0x883D - -/* BlendSubtract */ -#define GL_FUNC_SUBTRACT 0x800A -#define GL_FUNC_REVERSE_SUBTRACT 0x800B - -/* Separate Blend Functions */ -#define GL_BLEND_DST_RGB 0x80C8 -#define GL_BLEND_SRC_RGB 0x80C9 -#define GL_BLEND_DST_ALPHA 0x80CA -#define GL_BLEND_SRC_ALPHA 0x80CB -#define GL_CONSTANT_COLOR 0x8001 -#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 -#define GL_CONSTANT_ALPHA 0x8003 -#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 -#define GL_BLEND_COLOR 0x8005 - -/* Buffer Objects */ -#define GL_ARRAY_BUFFER 0x8892 -#define GL_ELEMENT_ARRAY_BUFFER 0x8893 -#define GL_ARRAY_BUFFER_BINDING 0x8894 -#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 - -#define GL_STREAM_DRAW 0x88E0 -#define GL_STATIC_DRAW 0x88E4 -#define GL_DYNAMIC_DRAW 0x88E8 - -#define GL_BUFFER_SIZE 0x8764 -#define GL_BUFFER_USAGE 0x8765 - -#define GL_CURRENT_VERTEX_ATTRIB 0x8626 - -/* CullFaceMode */ -#define GL_FRONT 0x0404 -#define GL_BACK 0x0405 -#define GL_FRONT_AND_BACK 0x0408 - -/* DepthFunction */ -/* GL_NEVER */ -/* GL_LESS */ -/* GL_EQUAL */ -/* GL_LEQUAL */ -/* GL_GREATER */ -/* GL_NOTEQUAL */ -/* GL_GEQUAL */ -/* GL_ALWAYS */ - -/* EnableCap */ -#define GL_TEXTURE_2D 0x0DE1 -#define GL_CULL_FACE 0x0B44 -#define GL_BLEND 0x0BE2 -#define GL_DITHER 0x0BD0 -#define GL_STENCIL_TEST 0x0B90 -#define GL_DEPTH_TEST 0x0B71 -#define GL_SCISSOR_TEST 0x0C11 -#define GL_POLYGON_OFFSET_FILL 0x8037 -#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E -#define GL_SAMPLE_COVERAGE 0x80A0 -#define GL_TEXTURE_EXTERNAL_OES 0x8D65 - -/* ErrorCode */ -#define GL_NO_ERROR 0 -#define GL_INVALID_ENUM 0x0500 -#define GL_INVALID_VALUE 0x0501 -#define GL_INVALID_OPERATION 0x0502 -#define GL_OUT_OF_MEMORY 0x0505 - -/* FrontFaceDirection */ -#define GL_CW 0x0900 -#define GL_CCW 0x0901 - -/* GetPName */ -#define GL_LINE_WIDTH 0x0B21 -#define GL_ALIASED_POINT_SIZE_RANGE 0x846D -#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E -#define GL_CULL_FACE_MODE 0x0B45 -#define GL_FRONT_FACE 0x0B46 -#define GL_DEPTH_RANGE 0x0B70 -#define GL_DEPTH_WRITEMASK 0x0B72 -#define GL_DEPTH_CLEAR_VALUE 0x0B73 -#define GL_DEPTH_FUNC 0x0B74 -#define GL_STENCIL_CLEAR_VALUE 0x0B91 -#define GL_STENCIL_FUNC 0x0B92 -#define GL_STENCIL_FAIL 0x0B94 -#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 -#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 -#define GL_STENCIL_REF 0x0B97 -#define GL_STENCIL_VALUE_MASK 0x0B93 -#define GL_STENCIL_WRITEMASK 0x0B98 -#define GL_STENCIL_BACK_FUNC 0x8800 -#define GL_STENCIL_BACK_FAIL 0x8801 -#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 -#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 -#define GL_STENCIL_BACK_REF 0x8CA3 -#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 -#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 -#define GL_VIEWPORT 0x0BA2 -#define GL_SCISSOR_BOX 0x0C10 -/* GL_SCISSOR_TEST */ -#define GL_COLOR_CLEAR_VALUE 0x0C22 -#define GL_COLOR_WRITEMASK 0x0C23 -#define GL_UNPACK_ALIGNMENT 0x0CF5 -#define GL_PACK_ALIGNMENT 0x0D05 -#define GL_MAX_TEXTURE_SIZE 0x0D33 -#define GL_MAX_VIEWPORT_DIMS 0x0D3A -#define GL_SUBPIXEL_BITS 0x0D50 -#define GL_RED_BITS 0x0D52 -#define GL_GREEN_BITS 0x0D53 -#define GL_BLUE_BITS 0x0D54 -#define GL_ALPHA_BITS 0x0D55 -#define GL_DEPTH_BITS 0x0D56 -#define GL_STENCIL_BITS 0x0D57 -#define GL_POLYGON_OFFSET_UNITS 0x2A00 -/* GL_POLYGON_OFFSET_FILL */ -#define GL_POLYGON_OFFSET_FACTOR 0x8038 -#define GL_TEXTURE_BINDING_2D 0x8069 -#define GL_SAMPLE_BUFFERS 0x80A8 -#define GL_SAMPLES 0x80A9 -#define GL_SAMPLE_COVERAGE_VALUE 0x80AA -#define GL_SAMPLE_COVERAGE_INVERT 0x80AB - -/* GetTextureParameter */ -/* GL_TEXTURE_MAG_FILTER */ -/* GL_TEXTURE_MIN_FILTER */ -/* GL_TEXTURE_WRAP_S */ -/* GL_TEXTURE_WRAP_T */ - -#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 -#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 - -/* HintMode */ -#define GL_DONT_CARE 0x1100 -#define GL_FASTEST 0x1101 -#define GL_NICEST 0x1102 - -/* HintTarget */ -#define GL_GENERATE_MIPMAP_HINT 0x8192 - -/* DataType */ -#define GL_BYTE 0x1400 -#define GL_UNSIGNED_BYTE 0x1401 -#define GL_SHORT 0x1402 -#define GL_UNSIGNED_SHORT 0x1403 -#define GL_INT 0x1404 -#define GL_UNSIGNED_INT 0x1405 -#define GL_FLOAT 0x1406 -#define GL_FIXED 0x140C - -/* PixelFormat */ -#define GL_DEPTH_COMPONENT 0x1902 -#define GL_ALPHA 0x1906 -#define GL_RGB 0x1907 -#define GL_RGBA 0x1908 -#define GL_LUMINANCE 0x1909 -#define GL_LUMINANCE_ALPHA 0x190A - -/* PixelType */ -/* GL_UNSIGNED_BYTE */ -#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 -#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 -#define GL_UNSIGNED_SHORT_5_6_5 0x8363 - -/* Shaders */ -#define GL_FRAGMENT_SHADER 0x8B30 -#define GL_VERTEX_SHADER 0x8B31 -#define GL_MAX_VERTEX_ATTRIBS 0x8869 -#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB -#define GL_MAX_VARYING_VECTORS 0x8DFC -#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D -#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C -#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 -#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD -#define GL_SHADER_TYPE 0x8B4F -#define GL_DELETE_STATUS 0x8B80 -#define GL_LINK_STATUS 0x8B82 -#define GL_VALIDATE_STATUS 0x8B83 -#define GL_ATTACHED_SHADERS 0x8B85 -#define GL_ACTIVE_UNIFORMS 0x8B86 -#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 -#define GL_ACTIVE_ATTRIBUTES 0x8B89 -#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A -#define GL_SHADING_LANGUAGE_VERSION 0x8B8C -#define GL_CURRENT_PROGRAM 0x8B8D - -/* StencilFunction */ -#define GL_NEVER 0x0200 -#define GL_LESS 0x0201 -#define GL_EQUAL 0x0202 -#define GL_LEQUAL 0x0203 -#define GL_GREATER 0x0204 -#define GL_NOTEQUAL 0x0205 -#define GL_GEQUAL 0x0206 -#define GL_ALWAYS 0x0207 - -/* StencilOp */ -/* GL_ZERO */ -#define GL_KEEP 0x1E00 -#define GL_REPLACE 0x1E01 -#define GL_INCR 0x1E02 -#define GL_DECR 0x1E03 -#define GL_INVERT 0x150A -#define GL_INCR_WRAP 0x8507 -#define GL_DECR_WRAP 0x8508 - -/* StringName */ -#define GL_VENDOR 0x1F00 -#define GL_RENDERER 0x1F01 -#define GL_VERSION 0x1F02 -#define GL_EXTENSIONS 0x1F03 - -/* TextureMagFilter */ -#define GL_NEAREST 0x2600 -#define GL_LINEAR 0x2601 - -/* TextureMinFilter */ -/* GL_NEAREST */ -/* GL_LINEAR */ -#define GL_NEAREST_MIPMAP_NEAREST 0x2700 -#define GL_LINEAR_MIPMAP_NEAREST 0x2701 -#define GL_NEAREST_MIPMAP_LINEAR 0x2702 -#define GL_LINEAR_MIPMAP_LINEAR 0x2703 - -/* TextureParameterName */ -#define GL_TEXTURE_MAG_FILTER 0x2800 -#define GL_TEXTURE_MIN_FILTER 0x2801 -#define GL_TEXTURE_WRAP_S 0x2802 -#define GL_TEXTURE_WRAP_T 0x2803 - -/* TextureTarget */ -/* GL_TEXTURE_2D */ -#define GL_TEXTURE 0x1702 - -#define GL_TEXTURE_CUBE_MAP 0x8513 -#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C - -/* TextureUnit */ -#define GL_TEXTURE0 0x84C0 -#define GL_TEXTURE1 0x84C1 -#define GL_TEXTURE2 0x84C2 -#define GL_TEXTURE3 0x84C3 -#define GL_TEXTURE4 0x84C4 -#define GL_TEXTURE5 0x84C5 -#define GL_TEXTURE6 0x84C6 -#define GL_TEXTURE7 0x84C7 -#define GL_TEXTURE8 0x84C8 -#define GL_TEXTURE9 0x84C9 -#define GL_TEXTURE10 0x84CA -#define GL_TEXTURE11 0x84CB -#define GL_TEXTURE12 0x84CC -#define GL_TEXTURE13 0x84CD -#define GL_TEXTURE14 0x84CE -#define GL_TEXTURE15 0x84CF -#define GL_TEXTURE16 0x84D0 -#define GL_TEXTURE17 0x84D1 -#define GL_TEXTURE18 0x84D2 -#define GL_TEXTURE19 0x84D3 -#define GL_TEXTURE20 0x84D4 -#define GL_TEXTURE21 0x84D5 -#define GL_TEXTURE22 0x84D6 -#define GL_TEXTURE23 0x84D7 -#define GL_TEXTURE24 0x84D8 -#define GL_TEXTURE25 0x84D9 -#define GL_TEXTURE26 0x84DA -#define GL_TEXTURE27 0x84DB -#define GL_TEXTURE28 0x84DC -#define GL_TEXTURE29 0x84DD -#define GL_TEXTURE30 0x84DE -#define GL_TEXTURE31 0x84DF -#define GL_ACTIVE_TEXTURE 0x84E0 - -/* TextureWrapMode */ -#define GL_REPEAT 0x2901 -#define GL_CLAMP_TO_EDGE 0x812F -#define GL_MIRRORED_REPEAT 0x8370 - -/* Uniform Types */ -#define GL_FLOAT_VEC2 0x8B50 -#define GL_FLOAT_VEC3 0x8B51 -#define GL_FLOAT_VEC4 0x8B52 -#define GL_INT_VEC2 0x8B53 -#define GL_INT_VEC3 0x8B54 -#define GL_INT_VEC4 0x8B55 -#define GL_BOOL 0x8B56 -#define GL_BOOL_VEC2 0x8B57 -#define GL_BOOL_VEC3 0x8B58 -#define GL_BOOL_VEC4 0x8B59 -#define GL_FLOAT_MAT2 0x8B5A -#define GL_FLOAT_MAT3 0x8B5B -#define GL_FLOAT_MAT4 0x8B5C -#define GL_SAMPLER_2D 0x8B5E -#define GL_SAMPLER_CUBE 0x8B60 - -/* Vertex Arrays */ -#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 -#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 -#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 -#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 -#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A -#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 -#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F - -/* Read Format */ -#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A -#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B - -/* Shader Source */ -#define GL_COMPILE_STATUS 0x8B81 -#define GL_INFO_LOG_LENGTH 0x8B84 -#define GL_SHADER_SOURCE_LENGTH 0x8B88 -#define GL_SHADER_COMPILER 0x8DFA - -/* Shader Binary */ -#define GL_SHADER_BINARY_FORMATS 0x8DF8 -#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 - -/* Shader Precision-Specified Types */ -#define GL_LOW_FLOAT 0x8DF0 -#define GL_MEDIUM_FLOAT 0x8DF1 -#define GL_HIGH_FLOAT 0x8DF2 -#define GL_LOW_INT 0x8DF3 -#define GL_MEDIUM_INT 0x8DF4 -#define GL_HIGH_INT 0x8DF5 - -/* Framebuffer Object. */ -#define GL_FRAMEBUFFER 0x8D40 -#define GL_RENDERBUFFER 0x8D41 - -#define GL_RGBA4 0x8056 -#define GL_RGB5_A1 0x8057 -#define GL_RGB565 0x8D62 -#define GL_DEPTH_COMPONENT16 0x81A5 -#define GL_STENCIL_INDEX8 0x8D48 - -#define GL_RENDERBUFFER_WIDTH 0x8D42 -#define GL_RENDERBUFFER_HEIGHT 0x8D43 -#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 -#define GL_RENDERBUFFER_RED_SIZE 0x8D50 -#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 -#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 -#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 -#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 -#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 - -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 - -#define GL_COLOR_ATTACHMENT0 0x8CE0 -#define GL_DEPTH_ATTACHMENT 0x8D00 -#define GL_STENCIL_ATTACHMENT 0x8D20 - -#define GL_NONE 0 - -#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 -#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 -#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 -#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 -#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD - -#define GL_FRAMEBUFFER_BINDING 0x8CA6 -#define GL_RENDERBUFFER_BINDING 0x8CA7 -#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 - -#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 - - -#ifdef __cplusplus -} -#endif - -#endif /* __COGL_GLES2_TYPES_H_ */ diff --git a/cogl/cogl/cogl-gles2.h b/cogl/cogl/cogl-gles2.h deleted file mode 100644 index ea6af28dd..000000000 --- a/cogl/cogl/cogl-gles2.h +++ /dev/null @@ -1,416 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Collabora Ltd. - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Tomeu Vizoso - * Robert Bragg - * - */ - -#ifndef __COGL_GLES2_H__ -#define __COGL_GLES2_H__ - -/* NB: cogl-gles2.h is a top-level header that can be included directly - * but we want to be careful not to define __COGL_H_INSIDE__ when this - * is included internally while building Cogl itself since - * __COGL_H_INSIDE__ is used in headers to guard public vs private - * api definitions - */ -#ifndef COGL_COMPILATION - -/* Note: When building Cogl .gir we explicitly define - * __COGL_H_INSIDE__ */ -#ifndef __COGL_H_INSIDE__ -#define __COGL_H_INSIDE__ -#define __COGL_MUST_UNDEF_COGL_H_INSIDE_COGL_GLES2__ -#endif - -#endif /* COGL_COMPILATION */ - -#include -#include -#include -#include -#include - -/* CoglGLES2Vtable depends on GLES 2.0 typedefs being available but we - * want to be careful that the public api doesn't expose arbitrary - * system GL headers as part of the Cogl API so although when building - * internally we consistently refer to the system headers to avoid - * conflicts we only expose the minimal set of GLES 2.0 types and enums - * publicly. - */ -#if defined(COGL_COMPILATION) || defined(COGL_ENABLE_MUFFIN_API) -#include "cogl-gl-header.h" -#else -#include -#endif - -COGL_BEGIN_DECLS - -/** - * SECTION:cogl-gles2 - * @short_description: A portable api to access OpenGLES 2.0 - * - * Cogl provides portable access to the OpenGLES api through a single - * library that is able to smooth over inconsistencies between the - * different vendor drivers for OpenGLES in a single place. - * - * The api is designed to allow Cogl to transparently implement the - * api on top of other drivers, such as OpenGL, D3D or on Cogl's own - * drawing api so even if your platform doesn't come with an - * OpenGLES 2.0 api Cogl may still be able to expose the api to your - * application. - * - * Since Cogl is a library and not an api specification it is possible - * to add OpenGLES 2.0 api features to Cogl which can immidiately - * benefit developers regardless of what platform they are running on. - * - * With this api it's possible to re-use existing OpenGLES 2.0 code - * within applications that are rendering with the Cogl API and also - * it's possible for applications that render using OpenGLES 2.0 to - * incorporate content rendered with Cogl. - * - * Applications can check for OpenGLES 2.0 api support by checking for - * %COGL_FEATURE_ID_GLES2_CONTEXT support with cogl_has_feature(). - * - * Since: 1.12 - * Stability: unstable - */ - -/** - * CoglGLES2Context: - * - * Represents an OpenGLES 2.0 api context used as a sandbox for - * OpenGLES 2.0 state. This is comparable to an EGLContext for those - * who have used OpenGLES 2.0 with EGL before. - * - * Since: 1.12 - * Stability: unstable - */ -typedef struct _CoglGLES2Context CoglGLES2Context; - -/** - * CoglGLES2Vtable: - * - * Provides function pointers for the full OpenGLES 2.0 api. The - * api must be accessed this way and not by directly calling - * symbols of any system OpenGLES 2.0 api. - * - * Since: 1.12 - * Stability: unstable - */ -typedef struct _CoglGLES2Vtable CoglGLES2Vtable; - -struct _CoglGLES2Vtable -{ - /*< private >*/ -#define COGL_EXT_BEGIN(name, \ - min_gl_major, min_gl_minor, \ - gles_availability, \ - extension_suffixes, extension_names) - -#define COGL_EXT_FUNCTION(ret, name, args) \ - ret (* name) args; - -#define COGL_EXT_END() - -#include - -#include - -#undef COGL_EXT_BEGIN -#undef COGL_EXT_FUNCTION -#undef COGL_EXT_END -}; - -/** - * cogl_gles2_context_get_gtype: - * - * Returns: a #GType that can be used with the GLib type system. - */ -GType cogl_gles2_context_get_gtype (void); - -uint32_t -_cogl_gles2_context_error_quark (void); - -/** - * COGL_GLES2_CONTEXT_ERROR: - * - * An error domain for runtime exceptions relating to the - * cogl_gles2_context api. - * - * Since: 2.0 - * Stability: unstable - */ -#define COGL_GLES2_CONTEXT_ERROR (_cogl_gles2_context_error_quark ()) - -/** - * CoglGLES2ContextError: - * @COGL_GLES2_CONTEXT_ERROR_UNSUPPORTED: Creating GLES2 contexts - * isn't supported. Applications should use cogl_has_feature() to - * check for the %COGL_FEATURE_ID_GLES2_CONTEXT. - * @COGL_GLES2_CONTEXT_ERROR_DRIVER: An underlying driver error - * occured. - * - * Error codes that relate to the cogl_gles2_context api. - */ -typedef enum { /*< prefix=COGL_GLES2_CONTEXT_ERROR >*/ - COGL_GLES2_CONTEXT_ERROR_UNSUPPORTED, - COGL_GLES2_CONTEXT_ERROR_DRIVER -} CoglGLES2ContextError; - -/** - * cogl_gles2_context_new: - * @ctx: A #CoglContext - * @error: A pointer to a #CoglError for returning exceptions - * - * Allocates a new OpenGLES 2.0 context that can be used to render to - * #CoglOffscreen framebuffers (Rendering to #CoglOnscreen - * framebuffers is not currently supported). - * - * To actually access the OpenGLES 2.0 api itself you need to use - * cogl_gles2_context_get_vtable(). You should not try to directly link - * to and use the symbols provided by the a system OpenGLES 2.0 - * driver. - * - * Once you have allocated an OpenGLES 2.0 context you can make it - * current using cogl_push_gles2_context(). For those familiar with - * using the EGL api, this serves a similar purpose to eglMakeCurrent. - * - * Before using this api applications can check for OpenGLES 2.0 - * api support by checking for %COGL_FEATURE_ID_GLES2_CONTEXT support - * with cogl_has_feature(). This function will return %FALSE and - * return an %COGL_GLES2_CONTEXT_ERROR_UNSUPPORTED error if the - * feature isn't available. - * - * Since: 2.0 - * Return value: A newly allocated #CoglGLES2Context or %NULL if there - * was an error and @error will be updated in that case. - * Stability: unstable - */ -CoglGLES2Context * -cogl_gles2_context_new (CoglContext *ctx, CoglError **error); - -/** - * cogl_gles2_context_get_vtable: - * @gles2_ctx: A #CoglGLES2Context allocated with - * cogl_gles2_context_new() - * - * Queries the OpenGLES 2.0 api function pointers that should be - * used for rendering with the given @gles2_ctx. - * - * You should not try to directly link to and use the symbols - * provided by any system OpenGLES 2.0 driver. - * - * Since: 2.0 - * Return value: A pointer to a #CoglGLES2Vtable providing pointers - * to functions for the full OpenGLES 2.0 api. - * Stability: unstable - */ -const CoglGLES2Vtable * -cogl_gles2_context_get_vtable (CoglGLES2Context *gles2_ctx); - -/** - * cogl_push_gles2_context: - * @ctx: A #CoglContext - * @gles2_ctx: A #CoglGLES2Context allocated with - * cogl_gles2_context_new() - * @read_buffer: A #CoglFramebuffer to access to read operations - * such as glReadPixels. (must be a #CoglOffscreen - * framebuffer currently) - * @write_buffer: A #CoglFramebuffer to access for drawing operations - * such as glDrawArrays. (must be a #CoglOffscreen - * framebuffer currently) - * @error: A pointer to a #CoglError for returning exceptions - * - * Pushes the given @gles2_ctx onto a stack associated with @ctx so - * that the OpenGLES 2.0 api can be used instead of the Cogl - * rendering apis to read and write to the specified framebuffers. - * - * Usage of the api available through a #CoglGLES2Vtable is only - * allowed between cogl_push_gles2_context() and - * cogl_pop_gles2_context() calls. - * - * If there is a runtime problem with switching over to the given - * @gles2_ctx then this function will return %FALSE and return - * an error through @error. - * - * Since: 2.0 - * Return value: %TRUE if operation was successfull or %FALSE - * otherwise and @error will be updated. - * Stability: unstable - */ -CoglBool -cogl_push_gles2_context (CoglContext *ctx, - CoglGLES2Context *gles2_ctx, - CoglFramebuffer *read_buffer, - CoglFramebuffer *write_buffer, - CoglError **error); - -/** - * cogl_pop_gles2_context: - * @ctx: A #CoglContext - * - * Restores the previously active #CoglGLES2Context if there - * were nested calls to cogl_push_gles2_context() or otherwise - * restores the ability to render with the Cogl api instead - * of OpenGLES 2.0. - * - * The behaviour is undefined if calls to cogl_pop_gles2_context() - * are not balenced with the number of corresponding calls to - * cogl_push_gles2_context(). - * - * Since: 2.0 - * Stability: unstable - */ -void -cogl_pop_gles2_context (CoglContext *ctx); - -/** - * cogl_gles2_get_current_vtable: - * - * Returns the OpenGL ES 2.0 api vtable for the currently pushed - * #CoglGLES2Context (last pushed with cogl_push_gles2_context()) or - * %NULL if no #CoglGLES2Context has been pushed. - * - * Return value: The #CoglGLES2Vtable for the currently pushed - * #CoglGLES2Context or %NULL if none has been pushed. - * Since: 2.0 - * Stability: unstable - */ -CoglGLES2Vtable * -cogl_gles2_get_current_vtable (void); - -/** - * cogl_gles2_texture_2d_new_from_handle: - * @ctx: A #CoglContext - * @gles2_ctx: A #CoglGLES2Context allocated with - * cogl_gles2_context_new() - * @handle: An OpenGL ES 2.0 texture handle created with - * glGenTextures() - * @width: Width of the texture to allocate - * @height: Height of the texture to allocate - * @format: The format of the texture - * - * Creates a #CoglTexture2D from an OpenGL ES 2.0 texture handle that - * was created within the given @gles2_ctx via glGenTextures(). The - * texture needs to have been associated with the GL_TEXTURE_2D target. - * - * This interface is only intended for sharing textures to read - * from. The behaviour is undefined if the texture is modified using - * the Cogl api. - * - * Applications should only pass this function handles that were - * created via a #CoglGLES2Vtable or via libcogl-gles2 and not pass - * handles created directly using the system's native libGLESv2 - * api. - * - * Since: 2.0 - * Stability: unstable - */ -CoglTexture2D * -cogl_gles2_texture_2d_new_from_handle (CoglContext *ctx, - CoglGLES2Context *gles2_ctx, - unsigned int handle, - int width, - int height, - CoglPixelFormat format); - -/** - * cogl_gles2_texture_get_handle: - * @texture: A #CoglTexture - * @handle: A return location for an OpenGL ES 2.0 texture handle - * @target: A return location for an OpenGL ES 2.0 texture target - * - * Gets an OpenGL ES 2.0 texture handle for a #CoglTexture that can - * then be referenced by a #CoglGLES2Context. As well as returning - * a texture handle the texture's target (such as GL_TEXTURE_2D) is - * also returned. - * - * If the #CoglTexture can not be shared with a #CoglGLES2Context then - * this function will return %FALSE. - * - * This api does not affect the lifetime of the CoglTexture and you - * must take care not to reference the returned handle after the - * original texture has been freed. - * - * This interface is only intended for sharing textures to read - * from. The behaviour is undefined if the texture is modified by a - * GLES2 context. - * - * This function will only return %TRUE for low-level - * #CoglTextures such as #CoglTexture2D or #CoglTexture3D but - * not for high level meta textures such as - * #CoglTexture2DSliced - * - * The handle returned should not be passed directly to a system - * OpenGL ES 2.0 library, the handle is only intended to be used via - * a #CoglGLES2Vtable or via libcogl-gles2. - * - * Return value: %TRUE if a handle and target could be returned - * otherwise %FALSE is returned. - * Since: 2.0 - * Stability: unstable - */ -CoglBool -cogl_gles2_texture_get_handle (CoglTexture *texture, - unsigned int *handle, - unsigned int *target); - -/** - * cogl_is_gles2_context: - * @object: A #CoglObject pointer - * - * Gets whether the given object references a #CoglGLES2Context. - * - * Return value: %TRUE if the object references a #CoglGLES2Context - * and %FALSE otherwise. - * Since: 2.0 - * Stability: unstable - */ -CoglBool -cogl_is_gles2_context (void *object); - -COGL_END_DECLS - -/* The gobject introspection scanner seems to parse public headers in - * isolation which means we need to be extra careful about how we - * define and undefine __COGL_H_INSIDE__ used to detect when internal - * headers are incorrectly included by developers. In the gobject - * introspection case we have to manually define __COGL_H_INSIDE__ as - * a commandline argument for the scanner which means we must be - * careful not to undefine it in a header... - */ -#ifdef __COGL_MUST_UNDEF_COGL_H_INSIDE_COGL_GLES2__ -#undef __COGL_H_INSIDE__ -#undef __COGL_MUST_UNDEF_COGL_H_INSIDE_COGL_GLES2__ -#endif - -#endif /* __COGL_GLES2_H__ */ - diff --git a/cogl/cogl/cogl-glib-source.c b/cogl/cogl/cogl-glib-source.c index b0b0ac566..aa86c828d 100644 --- a/cogl/cogl/cogl-glib-source.c +++ b/cogl/cogl/cogl-glib-source.c @@ -28,9 +28,7 @@ * */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-glib-source.h" #include "cogl-poll.h" @@ -47,7 +45,7 @@ typedef struct _CoglGLibSource int64_t expiration_time; } CoglGLibSource; -static CoglBool +static gboolean cogl_glib_source_prepare (GSource *source, int *timeout) { CoglGLibSource *cogl_source = (CoglGLibSource *) source; @@ -111,7 +109,7 @@ cogl_glib_source_prepare (GSource *source, int *timeout) return *timeout == 0; } -static CoglBool +static gboolean cogl_glib_source_check (GSource *source) { CoglGLibSource *cogl_source = (CoglGLibSource *) source; @@ -131,7 +129,7 @@ cogl_glib_source_check (GSource *source) return FALSE; } -static CoglBool +static gboolean cogl_glib_source_dispatch (GSource *source, GSourceFunc callback, void *user_data) diff --git a/cogl/cogl/cogl-glib-source.h b/cogl/cogl/cogl-glib-source.h index ddb7f9957..cf192e3d7 100644 --- a/cogl/cogl/cogl-glib-source.h +++ b/cogl/cogl/cogl-glib-source.h @@ -67,7 +67,7 @@ G_BEGIN_DECLS * Stability: unstable * Since: 1.10 */ -GSource * +COGL_EXPORT GSource * cogl_glib_source_new (CoglContext *context, int priority); @@ -88,7 +88,7 @@ cogl_glib_source_new (CoglContext *context, * Stability: unstable * Since: 1.16 */ -GSource * +COGL_EXPORT GSource * cogl_glib_renderer_source_new (CoglRenderer *renderer, int priority); diff --git a/cogl/cogl/cogl-glsl-shader.c b/cogl/cogl/cogl-glsl-shader.c index 6599ec28d..fda923c34 100644 --- a/cogl/cogl/cogl-glsl-shader.c +++ b/cogl/cogl/cogl-glsl-shader.c @@ -32,20 +32,18 @@ * Neil Roberts */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-context-private.h" -#include "cogl-util-gl-private.h" #include "cogl-glsl-shader-private.h" #include "cogl-glsl-shader-boilerplate.h" +#include "driver/gl/cogl-util-gl-private.h" #include #include -static CoglBool +static gboolean add_layer_vertex_boilerplate_cb (CoglPipelineLayer *layer, void *user_data) { @@ -63,7 +61,7 @@ add_layer_vertex_boilerplate_cb (CoglPipelineLayer *layer, return TRUE; } -static CoglBool +static gboolean add_layer_fragment_boilerplate_cb (CoglPipelineLayer *layer, void *user_data) { @@ -102,21 +100,12 @@ _cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx, strings[count] = version_string; lengths[count++] = -1; - if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_EMBEDDED) && - cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_3D)) - { - static const char texture_3d_extension[] = - "#extension GL_OES_texture_3D : enable\n"; - strings[count] = texture_3d_extension; - lengths[count++] = sizeof (texture_3d_extension) - 1; - } - if (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_EGL_IMAGE_EXTERNAL)) { - static const char texture_3d_extension[] = + static const char image_external_extension[] = "#extension GL_OES_EGL_image_external : require\n"; - strings[count] = texture_3d_extension; - lengths[count++] = sizeof (texture_3d_extension) - 1; + strings[count] = image_external_extension; + lengths[count++] = sizeof (image_external_extension) - 1; } if (shader_gl_type == GL_VERTEX_SHADER) @@ -196,5 +185,5 @@ _cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx, GE( ctx, glShaderSource (shader_gl_handle, count, (const char **) strings, lengths) ); - free (version_string); + g_free (version_string); } diff --git a/cogl/cogl/cogl-gpu-info-private.h b/cogl/cogl/cogl-gpu-info-private.h index e532cdd5c..7ab4950f8 100644 --- a/cogl/cogl/cogl-gpu-info-private.h +++ b/cogl/cogl/cogl-gpu-info-private.h @@ -74,12 +74,7 @@ typedef enum typedef enum { - /* If this bug is present then it is faster to read pixels into a - * PBO and then memcpy out of the PBO into system memory rather than - * directly read into system memory. - * https://bugs.freedesktop.org/show_bug.cgi?id=46631 - */ - COGL_GPU_INFO_DRIVER_BUG_MESA_46631_SLOW_READ_PIXELS = 1 << 0 + COGL_GPU_INFO_DRIVER_STUB } CoglGpuInfoDriverBug; typedef struct _CoglGpuInfoVersion CoglGpuInfoVersion; diff --git a/cogl/cogl/cogl-gpu-info.c b/cogl/cogl/cogl-gpu-info.c index 23a846616..f44319e96 100644 --- a/cogl/cogl/cogl-gpu-info.c +++ b/cogl/cogl/cogl-gpu-info.c @@ -28,9 +28,7 @@ * */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include #include @@ -53,7 +51,7 @@ typedef struct CoglGpuInfoArchitectureDescription CoglGpuInfoArchitecture architecture; const char *name; CoglGpuInfoArchitectureFlag flags; - CoglBool (* check_function) (const CoglGpuInfoStrings *strings); + gboolean (* check_function) (const CoglGpuInfoStrings *strings); } CoglGpuInfoArchitectureDescription; @@ -61,7 +59,7 @@ typedef struct { CoglGpuInfoVendor vendor; const char *name; - CoglBool (* check_function) (const CoglGpuInfoStrings *strings); + gboolean (* check_function) (const CoglGpuInfoStrings *strings); const CoglGpuInfoArchitectureDescription *architectures; } CoglGpuInfoVendorDescription; @@ -70,11 +68,11 @@ typedef struct { CoglGpuInfoDriverPackage driver_package; const char *name; - CoglBool (* check_function) (const CoglGpuInfoStrings *strings, + gboolean (* check_function) (const CoglGpuInfoStrings *strings, int *version_out); } CoglGpuInfoDriverPackageDescription; -static CoglBool +static gboolean _cogl_gpu_info_parse_version_string (const char *version_string, int n_components, const char **tail, @@ -113,7 +111,7 @@ _cogl_gpu_info_parse_version_string (const char *version_string, return TRUE; } -static CoglBool +static gboolean match_phrase (const char *string, const char *phrase) { const char *part = strstr (string, phrase); @@ -136,13 +134,13 @@ match_phrase (const char *string, const char *phrase) return TRUE; } -static CoglBool +static gboolean check_intel_vendor (const CoglGpuInfoStrings *strings) { return match_phrase (strings->renderer_string, "Intel(R)"); } -static CoglBool +static gboolean check_imagination_technologies_vendor (const CoglGpuInfoStrings *strings) { if (strcmp (strings->vendor_string, "Imagination Technologies") != 0) @@ -150,7 +148,7 @@ check_imagination_technologies_vendor (const CoglGpuInfoStrings *strings) return TRUE; } -static CoglBool +static gboolean check_arm_vendor (const CoglGpuInfoStrings *strings) { if (strcmp (strings->vendor_string, "ARM") != 0) @@ -158,7 +156,7 @@ check_arm_vendor (const CoglGpuInfoStrings *strings) return TRUE; } -static CoglBool +static gboolean check_qualcomm_vendor (const CoglGpuInfoStrings *strings) { if (strcmp (strings->vendor_string, "Qualcomm") != 0) @@ -166,7 +164,7 @@ check_qualcomm_vendor (const CoglGpuInfoStrings *strings) return TRUE; } -static CoglBool +static gboolean check_nvidia_vendor (const CoglGpuInfoStrings *strings) { if (strcmp (strings->vendor_string, "NVIDIA") != 0 && @@ -176,7 +174,7 @@ check_nvidia_vendor (const CoglGpuInfoStrings *strings) return TRUE; } -static CoglBool +static gboolean check_ati_vendor (const CoglGpuInfoStrings *strings) { if (strcmp (strings->vendor_string, "ATI") != 0) @@ -185,7 +183,7 @@ check_ati_vendor (const CoglGpuInfoStrings *strings) return TRUE; } -static CoglBool +static gboolean check_mesa_vendor (const CoglGpuInfoStrings *strings) { if (strcmp (strings->vendor_string, "Tungsten Graphics, Inc") == 0) @@ -198,39 +196,39 @@ check_mesa_vendor (const CoglGpuInfoStrings *strings) return FALSE; } -static CoglBool +static gboolean check_true (const CoglGpuInfoStrings *strings) { /* This is a last resort so it always matches */ return TRUE; } -static CoglBool +static gboolean check_sandybridge_architecture (const CoglGpuInfoStrings *strings) { return match_phrase (strings->renderer_string, "Sandybridge"); } -static CoglBool +static gboolean check_llvmpipe_architecture (const CoglGpuInfoStrings *strings) { return match_phrase (strings->renderer_string, "llvmpipe"); } -static CoglBool +static gboolean check_softpipe_architecture (const CoglGpuInfoStrings *strings) { return match_phrase (strings->renderer_string, "softpipe"); } -static CoglBool +static gboolean check_swrast_architecture (const CoglGpuInfoStrings *strings) { return match_phrase (strings->renderer_string, "software rasterizer") || match_phrase (strings->renderer_string, "Software Rasterizer"); } -static CoglBool +static gboolean check_sgx_architecture (const CoglGpuInfoStrings *strings) { if (strncmp (strings->renderer_string, "PowerVR SGX", 12) != 0) @@ -239,7 +237,7 @@ check_sgx_architecture (const CoglGpuInfoStrings *strings) return TRUE; } -static CoglBool +static gboolean check_mali_architecture (const CoglGpuInfoStrings *strings) { if (strncmp (strings->renderer_string, "Mali-", 5) != 0) @@ -410,7 +408,7 @@ _cogl_gpu_info_vendors[] = } }; -static CoglBool +static gboolean check_mesa_driver_package (const CoglGpuInfoStrings *strings, int *version_ret) { @@ -482,7 +480,7 @@ UNIT_TEST (check_mesa_driver_package_parser, } } -static CoglBool +static gboolean check_unknown_driver_package (const CoglGpuInfoStrings *strings, int *version_out) { @@ -570,13 +568,5 @@ _cogl_gpu_info_init (CoglContext *ctx, gpu->architecture_name); /* Determine the driver bugs */ - - /* In Mesa the glReadPixels implementation is really slow - when using the Intel driver. The Intel - driver has a fast blit path when reading into a PBO. Reading into - a temporary PBO and then memcpying back out to the application's - memory is faster than a regular glReadPixels in this case */ - if (gpu->vendor == COGL_GPU_INFO_VENDOR_INTEL && - gpu->driver_package == COGL_GPU_INFO_DRIVER_PACKAGE_MESA) - gpu->driver_bugs |= COGL_GPU_INFO_DRIVER_BUG_MESA_46631_SLOW_READ_PIXELS; + gpu->driver_bugs = 0; } diff --git a/cogl/cogl/cogl-gtype-private.h b/cogl/cogl/cogl-gtype-private.h index e7505264f..7ba270651 100644 --- a/cogl/cogl/cogl-gtype-private.h +++ b/cogl/cogl/cogl-gtype-private.h @@ -269,8 +269,10 @@ void _cogl_gtype_object_class_base_finalize (CoglObjectClass *klass); void _cogl_gtype_object_class_init (CoglObjectClass *klass); void _cogl_gtype_object_init (CoglObject *object); +COGL_EXPORT void cogl_object_value_set_object (GValue *value, gpointer object); +COGL_EXPORT gpointer cogl_object_value_get_object (const GValue *value); void _cogl_gtype_dummy_iface_init (gpointer iface); diff --git a/cogl/cogl/cogl-index-buffer.c b/cogl/cogl/cogl-index-buffer.c index 1f9b59d8d..9333a2fef 100644 --- a/cogl/cogl/cogl-index-buffer.c +++ b/cogl/cogl/cogl-index-buffer.c @@ -31,9 +31,7 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-object-private.h" #include "cogl-indices.h" diff --git a/cogl/cogl/cogl-index-buffer.h b/cogl/cogl/cogl-index-buffer.h index 94d2c8d8b..bf9bf1e99 100644 --- a/cogl/cogl/cogl-index-buffer.h +++ b/cogl/cogl/cogl-index-buffer.h @@ -42,7 +42,7 @@ #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS /** * SECTION:cogl-index-buffer @@ -61,7 +61,7 @@ typedef struct _CoglIndexBuffer CoglIndexBuffer; * * Returns: a #GType that can be used with the GLib type system. */ -GType cogl_index_buffer_get_gtype (void); +COGL_EXPORT GType cogl_index_buffer_get_gtype (void); /** * cogl_index_buffer_new: @@ -78,7 +78,7 @@ GType cogl_index_buffer_get_gtype (void); * Since: 1.4 * Stability: Unstable */ -CoglIndexBuffer * +COGL_EXPORT CoglIndexBuffer * cogl_index_buffer_new (CoglContext *context, size_t bytes); @@ -94,10 +94,10 @@ cogl_index_buffer_new (CoglContext *context, * Since: 1.4 * Stability: Unstable */ -CoglBool +COGL_EXPORT gboolean cogl_is_index_buffer (void *object); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_INDEX_BUFFER_H__ */ diff --git a/cogl/cogl/cogl-indices.c b/cogl/cogl/cogl-indices.c index a049cf622..5fac91a2e 100644 --- a/cogl/cogl/cogl-indices.c +++ b/cogl/cogl/cogl-indices.c @@ -32,9 +32,7 @@ * Neil Roberts */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-util.h" #include "cogl-object-private.h" @@ -93,7 +91,7 @@ cogl_indices_new (CoglContext *context, CoglIndexBuffer *index_buffer = cogl_index_buffer_new (context, buffer_bytes); CoglBuffer *buffer = COGL_BUFFER (index_buffer); CoglIndices *indices; - CoglError *ignore_error = NULL; + GError *ignore_error = NULL; _cogl_buffer_set_data (buffer, 0, @@ -102,7 +100,7 @@ cogl_indices_new (CoglContext *context, &ignore_error); if (ignore_error) { - cogl_error_free (ignore_error); + g_error_free (ignore_error); cogl_object_unref (index_buffer); return NULL; } @@ -122,15 +120,15 @@ cogl_indices_get_buffer (CoglIndices *indices) CoglIndicesType cogl_indices_get_type (CoglIndices *indices) { - _COGL_RETURN_VAL_IF_FAIL (cogl_is_indices (indices), - COGL_INDICES_TYPE_UNSIGNED_BYTE); + g_return_val_if_fail (cogl_is_indices (indices), + COGL_INDICES_TYPE_UNSIGNED_BYTE); return indices->type; } size_t cogl_indices_get_offset (CoglIndices *indices) { - _COGL_RETURN_VAL_IF_FAIL (cogl_is_indices (indices), 0); + g_return_val_if_fail (cogl_is_indices (indices), 0); return indices->offset; } @@ -138,7 +136,7 @@ cogl_indices_get_offset (CoglIndices *indices) static void warn_about_midscene_changes (void) { - static CoglBool seen = FALSE; + static gboolean seen = FALSE; if (!seen) { g_warning ("Mid-scene modification of indices has " @@ -151,7 +149,7 @@ void cogl_indices_set_offset (CoglIndices *indices, size_t offset) { - _COGL_RETURN_IF_FAIL (cogl_is_indices (indices)); + g_return_if_fail (cogl_is_indices (indices)); if (G_UNLIKELY (indices->immutable_ref)) warn_about_midscene_changes (); @@ -169,7 +167,7 @@ _cogl_indices_free (CoglIndices *indices) CoglIndices * _cogl_indices_immutable_ref (CoglIndices *indices) { - _COGL_RETURN_VAL_IF_FAIL (cogl_is_indices (indices), NULL); + g_return_val_if_fail (cogl_is_indices (indices), NULL); indices->immutable_ref++; _cogl_buffer_immutable_ref (COGL_BUFFER (indices->buffer)); @@ -179,8 +177,8 @@ _cogl_indices_immutable_ref (CoglIndices *indices) void _cogl_indices_immutable_unref (CoglIndices *indices) { - _COGL_RETURN_IF_FAIL (cogl_is_indices (indices)); - _COGL_RETURN_IF_FAIL (indices->immutable_ref > 0); + g_return_if_fail (cogl_is_indices (indices)); + g_return_if_fail (indices->immutable_ref > 0); indices->immutable_ref--; _cogl_buffer_immutable_unref (COGL_BUFFER (indices->buffer)); @@ -197,7 +195,7 @@ cogl_get_rectangle_indices (CoglContext *ctx, int n_rectangles) /* Generate the byte array if we haven't already */ if (ctx->rectangle_byte_indices == NULL) { - uint8_t *byte_array = malloc (256 / 4 * 6 * sizeof (uint8_t)); + uint8_t *byte_array = g_malloc (256 / 4 * 6 * sizeof (uint8_t)); uint8_t *p = byte_array; int i, vert_num = 0; @@ -218,7 +216,7 @@ cogl_get_rectangle_indices (CoglContext *ctx, int n_rectangles) byte_array, 256 / 4 * 6); - free (byte_array); + g_free (byte_array); } return ctx->rectangle_byte_indices; @@ -240,7 +238,7 @@ cogl_get_rectangle_indices (CoglContext *ctx, int n_rectangles) ctx->rectangle_short_indices_len *= 2; /* Over-allocate to generate a whole number of quads */ - p = short_array = malloc ((ctx->rectangle_short_indices_len + p = short_array = g_malloc ((ctx->rectangle_short_indices_len + 5) / 6 * 6 * sizeof (uint16_t)); @@ -262,7 +260,7 @@ cogl_get_rectangle_indices (CoglContext *ctx, int n_rectangles) short_array, ctx->rectangle_short_indices_len); - free (short_array); + g_free (short_array); } return ctx->rectangle_short_indices; diff --git a/cogl/cogl/cogl-indices.h b/cogl/cogl/cogl-indices.h index 9247f400d..09631df9c 100644 --- a/cogl/cogl/cogl-indices.h +++ b/cogl/cogl/cogl-indices.h @@ -47,7 +47,7 @@ typedef struct _CoglIndices CoglIndices; #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS /** * SECTION:cogl-indices @@ -76,7 +76,7 @@ COGL_BEGIN_DECLS * vertices multiple times. * * |[ - * CoglVertex2f quad_vertices[] = { + * CoglVertexP2 quad_vertices[] = { * {x0, y0}, //0 = top left * {x1, y1}, //1 = bottom left * {x2, y2}, //2 = bottom right @@ -112,33 +112,34 @@ COGL_BEGIN_DECLS * * Returns: a #GType that can be used with the GLib type system. */ +COGL_EXPORT GType cogl_indices_get_gtype (void); -CoglIndices * +COGL_EXPORT CoglIndices * cogl_indices_new (CoglContext *context, CoglIndicesType type, const void *indices_data, int n_indices); -CoglIndices * +COGL_EXPORT CoglIndices * cogl_indices_new_for_buffer (CoglIndicesType type, CoglIndexBuffer *buffer, size_t offset); -CoglIndexBuffer * +COGL_EXPORT CoglIndexBuffer * cogl_indices_get_buffer (CoglIndices *indices); -CoglIndicesType +COGL_EXPORT CoglIndicesType cogl_indices_get_type (CoglIndices *indices); -size_t +COGL_EXPORT size_t cogl_indices_get_offset (CoglIndices *indices); -void +COGL_EXPORT void cogl_indices_set_offset (CoglIndices *indices, size_t offset); -CoglIndices * +COGL_EXPORT CoglIndices * cogl_get_rectangle_indices (CoglContext *context, int n_rectangles); /** @@ -152,10 +153,10 @@ cogl_get_rectangle_indices (CoglContext *context, int n_rectangles); * Since: 1.10 * Stability: unstable */ -CoglBool +COGL_EXPORT gboolean cogl_is_indices (void *object); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_INDICES_H__ */ diff --git a/cogl/cogl/cogl-journal-private.h b/cogl/cogl/cogl-journal-private.h index 8211359fa..d38c3df1a 100644 --- a/cogl/cogl/cogl-journal-private.h +++ b/cogl/cogl/cogl-journal-private.h @@ -78,6 +78,8 @@ typedef struct _CoglJournalEntry CoglPipeline *pipeline; CoglMatrixEntry *modelview_entry; CoglClipStack *clip_stack; + float viewport[4]; + gboolean dither_enabled; /* Offset into ctx->logged_vertices */ size_t array_offset; int n_layers; @@ -101,21 +103,21 @@ _cogl_journal_flush (CoglJournal *journal); void _cogl_journal_discard (CoglJournal *journal); -CoglBool +gboolean _cogl_journal_all_entries_within_bounds (CoglJournal *journal, float clip_x0, float clip_y0, float clip_x1, float clip_y1); -CoglBool +gboolean _cogl_journal_try_read_pixel (CoglJournal *journal, int x, int y, CoglBitmap *bitmap, - CoglBool *found_intersection); + gboolean *found_intersection); -CoglBool +gboolean _cogl_is_journal (void *object); #endif /* __COGL_JOURNAL_PRIVATE_H */ diff --git a/cogl/cogl/cogl-journal.c b/cogl/cogl/cogl-journal.c index a8d4f934e..b7eb3c709 100644 --- a/cogl/cogl/cogl-journal.c +++ b/cogl/cogl/cogl-journal.c @@ -28,17 +28,13 @@ * */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-debug.h" #include "cogl-context-private.h" #include "cogl-journal-private.h" #include "cogl-texture-private.h" #include "cogl-pipeline-private.h" -#include "cogl-pipeline-opengl-private.h" -#include "cogl-vertex-buffer-private.h" #include "cogl-framebuffer-private.h" #include "cogl-profile.h" #include "cogl-attribute-private.h" @@ -121,7 +117,7 @@ typedef struct _CoglJournalFlushState typedef void (*CoglJournalBatchCallback) (CoglJournalEntry *start, int n_entries, void *data); -typedef CoglBool (*CoglJournalBatchTest) (CoglJournalEntry *entry0, +typedef gboolean (*CoglJournalBatchTest) (CoglJournalEntry *entry0, CoglJournalEntry *entry1); static void _cogl_journal_free (CoglJournal *journal); @@ -284,8 +280,7 @@ _cogl_journal_flush_modelview_and_entries (CoglJournalEntry *batch_start, CoglAttribute **attributes; CoglDrawFlags draw_flags = (COGL_DRAW_SKIP_JOURNAL_FLUSH | COGL_DRAW_SKIP_PIPELINE_VALIDATION | - COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH | - COGL_DRAW_SKIP_LEGACY_STATE); + COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH); COGL_STATIC_TIMER (time_flush_modelview_and_entries, "flush: pipeline+entries", /* parent */ @@ -307,46 +302,30 @@ _cogl_journal_flush_modelview_and_entries (CoglJournalEntry *batch_start, if (!_cogl_pipeline_get_real_blend_enabled (state->pipeline)) draw_flags |= COGL_DRAW_COLOR_ATTRIBUTE_IS_OPAQUE; -#ifdef HAVE_COGL_GL - if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_QUADS)) + if (batch_len > 1) + { + CoglVerticesMode mode = COGL_VERTICES_MODE_TRIANGLES; + int first_vertex = state->current_vertex * 6 / 4; + _cogl_framebuffer_draw_indexed_attributes (framebuffer, + state->pipeline, + mode, + first_vertex, + batch_len * 6, + state->indices, + attributes, + state->attributes->len, + draw_flags); + } + else { - /* XXX: it's rather evil that we sneak in the GL_QUADS enum here... */ _cogl_framebuffer_draw_attributes (framebuffer, state->pipeline, - GL_QUADS, - state->current_vertex, batch_len * 4, + COGL_VERTICES_MODE_TRIANGLE_FAN, + state->current_vertex, 4, attributes, state->attributes->len, draw_flags); } - else -#endif /* HAVE_COGL_GL */ - { - if (batch_len > 1) - { - CoglVerticesMode mode = COGL_VERTICES_MODE_TRIANGLES; - int first_vertex = state->current_vertex * 6 / 4; - _cogl_framebuffer_draw_indexed_attributes (framebuffer, - state->pipeline, - mode, - first_vertex, - batch_len * 6, - state->indices, - attributes, - state->attributes->len, - draw_flags); - } - else - { - _cogl_framebuffer_draw_attributes (framebuffer, - state->pipeline, - COGL_VERTICES_MODE_TRIANGLE_FAN, - state->current_vertex, 4, - attributes, - state->attributes->len, - draw_flags); - } - } /* DEBUGGING CODE XXX: This path will cause all rectangles to be * drawn with a coloured outline. Each batch will be rendered with @@ -405,7 +384,7 @@ _cogl_journal_flush_modelview_and_entries (CoglJournalEntry *batch_start, COGL_TIMER_STOP (_cogl_uprof_context, time_flush_modelview_and_entries); } -static CoglBool +static gboolean compare_entry_modelviews (CoglJournalEntry *entry0, CoglJournalEntry *entry1) { @@ -450,7 +429,7 @@ _cogl_journal_flush_pipeline_and_entries (CoglJournalEntry *batch_start, COGL_TIMER_STOP (_cogl_uprof_context, time_flush_pipeline_entries); } -static CoglBool +static gboolean compare_entry_pipelines (CoglJournalEntry *entry0, CoglJournalEntry *entry1) { /* batch rectangles using compatible pipelines */ @@ -472,7 +451,7 @@ typedef struct _CreateAttributeState CoglJournalFlushState *flush_state; } CreateAttributeState; -static CoglBool +static gboolean create_attribute_cb (CoglPipeline *pipeline, int layer_number, void *user_data) @@ -520,7 +499,7 @@ create_attribute_cb (CoglPipeline *pipeline, COGL_ATTRIBUTE_TYPE_FLOAT); if (layer_number >= 8) - free (name); + g_free (name); state->current++; @@ -570,7 +549,7 @@ _cogl_journal_flush_texcoord_vbo_offsets_and_entries ( COGL_TIMER_STOP (_cogl_uprof_context, time_flush_texcoord_pipeline_entries); } -static CoglBool +static gboolean compare_entry_layer_numbers (CoglJournalEntry *entry0, CoglJournalEntry *entry1) { if (_cogl_pipeline_layer_numbers_equal (entry0->pipeline, entry1->pipeline)) @@ -639,8 +618,7 @@ _cogl_journal_flush_vbo_offsets_and_entries (CoglJournalEntry *batch_start, 4, COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE); - if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_QUADS)) - state->indices = cogl_get_rectangle_indices (ctx, batch_len); + state->indices = cogl_get_rectangle_indices (ctx, batch_len); /* We only create new Attributes when the stride within the * AttributeBuffer changes. (due to a change in the number of pipeline @@ -685,7 +663,7 @@ _cogl_journal_flush_vbo_offsets_and_entries (CoglJournalEntry *batch_start, time_flush_vbo_texcoord_pipeline_entries); } -static CoglBool +static gboolean compare_entry_strides (CoglJournalEntry *entry0, CoglJournalEntry *entry1) { /* Currently the only thing that affects the stride for our vertex arrays @@ -765,7 +743,7 @@ typedef struct float x_2, y_2; } ClipBounds; -static CoglBool +static gboolean can_software_clip_entry (CoglJournalEntry *journal_entry, CoglJournalEntry *prev_journal_entry, CoglClipStack *clip_stack, @@ -1040,12 +1018,104 @@ _cogl_journal_maybe_software_clip_entries (CoglJournalEntry *batch_start, time_check_software_clip); } -static CoglBool +static gboolean compare_entry_clip_stacks (CoglJournalEntry *entry0, CoglJournalEntry *entry1) { return entry0->clip_stack == entry1->clip_stack; } +static void +_cogl_journal_flush_dither_and_entries (CoglJournalEntry *batch_start, + int batch_len, + void *data) +{ + CoglJournalFlushState *state = data; + CoglFramebuffer *framebuffer = state->journal->framebuffer; + CoglContext *ctx = framebuffer->context; + + COGL_STATIC_TIMER (time_flush_dither_and_entries, + "Journal Flush", /* parent */ + "flush: viewport+dither+clip+vbo+texcoords+pipeline+entries", + "The time spent flushing viewport + dither + clip + vbo + " + "texcoord offsets + pipeline + entries", + 0 /* no application private data */); + + COGL_TIMER_START (_cogl_uprof_context, time_flush_dither_and_entries); + + if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_BATCHING))) + g_print ("BATCHING: dither batch len = %d\n", batch_len); + + cogl_framebuffer_set_dither_enabled (framebuffer, batch_start->dither_enabled); + ctx->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_DITHER; + + _cogl_framebuffer_flush_state (framebuffer, + framebuffer, + COGL_FRAMEBUFFER_STATE_DITHER); + + batch_and_call (batch_start, + batch_len, + compare_entry_clip_stacks, + _cogl_journal_flush_clip_stacks_and_entries, + state); + + COGL_TIMER_STOP (_cogl_uprof_context, time_flush_dither_and_entries); +} + +static gboolean +compare_entry_dither_states (CoglJournalEntry *entry0, CoglJournalEntry *entry1) +{ + return entry0->dither_enabled == entry1->dither_enabled; +} + +static void +_cogl_journal_flush_viewport_and_entries (CoglJournalEntry *batch_start, + int batch_len, + void *data) +{ + CoglJournalFlushState *state = data; + CoglFramebuffer *framebuffer = state->journal->framebuffer; + CoglContext *ctx = framebuffer->context; + float current_viewport[4]; + + COGL_STATIC_TIMER (time_flush_viewport_and_entries, + "Journal Flush", /* parent */ + "flush: viewport+clip+vbo+texcoords+pipeline+entries", + "The time spent flushing viewport + clip + vbo + texcoord offsets + " + "pipeline + entries", + 0 /* no application private data */); + + COGL_TIMER_START (_cogl_uprof_context, time_flush_viewport_and_entries); + + if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_BATCHING))) + g_print ("BATCHING: viewport batch len = %d\n", batch_len); + + ctx->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_VIEWPORT; + + cogl_framebuffer_get_viewport4fv (framebuffer, current_viewport); + cogl_framebuffer_set_viewport4fv (framebuffer, batch_start->viewport); + + _cogl_framebuffer_flush_state (framebuffer, + framebuffer, + COGL_FRAMEBUFFER_STATE_VIEWPORT); + + batch_and_call (batch_start, + batch_len, + compare_entry_dither_states, + _cogl_journal_flush_dither_and_entries, + state); + + if (memcmp (batch_start->viewport, current_viewport, sizeof (float) * 4) != 0) + cogl_framebuffer_set_viewport4fv (framebuffer, current_viewport); + + COGL_TIMER_STOP (_cogl_uprof_context, time_flush_viewport_and_entries); +} + +static gboolean +compare_entry_viewports (CoglJournalEntry *entry0, CoglJournalEntry *entry1) +{ + return memcmp (entry0->viewport, entry1->viewport, sizeof (float) * 4) == 0; +} + /* Gets a new vertex array from the pool. A reference is taken on the array so it can be treated as if it was just newly allocated */ static CoglAttributeBuffer * @@ -1055,12 +1125,6 @@ create_attribute_buffer (CoglJournal *journal, CoglAttributeBuffer *vbo; CoglContext *ctx = journal->framebuffer->context; - /* If CoglBuffers are being emulated with malloc then there's not - really any point in using the pool so we'll just allocate the - buffer directly */ - if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_VBOS)) - return cogl_attribute_buffer_new_with_size (ctx, n_bytes); - vbo = journal->vbo_pool[journal->next_vbo_in_pool]; if (vbo == NULL) @@ -1211,7 +1275,7 @@ _cogl_journal_discard (CoglJournal *journal) /* Note: A return value of FALSE doesn't mean 'no' it means * 'unknown' */ -CoglBool +gboolean _cogl_journal_all_entries_within_bounds (CoglJournal *journal, float clip_x0, float clip_y0, @@ -1256,7 +1320,7 @@ _cogl_journal_all_entries_within_bounds (CoglJournal *journal, */ for (i = 1; i < journal->entries->len; i++) { - CoglBool found_reference = FALSE; + gboolean found_reference = FALSE; entry = &g_array_index (journal->entries, CoglJournalEntry, i); for (clip_entry = entry->clip_stack; @@ -1333,12 +1397,14 @@ _cogl_journal_flush (CoglJournal *journal) if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_BATCHING))) g_print ("BATCHING: journal len = %d\n", journal->entries->len); - /* NB: the journal deals with flushing the modelview stack and clip - state manually */ + /* NB: the journal deals with flushing the viewport, the modelview + * stack and clip state manually */ _cogl_framebuffer_flush_state (framebuffer, framebuffer, COGL_FRAMEBUFFER_STATE_ALL & - ~(COGL_FRAMEBUFFER_STATE_MODELVIEW | + ~(COGL_FRAMEBUFFER_STATE_DITHER | + COGL_FRAMEBUFFER_STATE_VIEWPORT | + COGL_FRAMEBUFFER_STATE_MODELVIEW | COGL_FRAMEBUFFER_STATE_CLIP)); /* We need to mark the current modelview state of the framebuffer as @@ -1387,9 +1453,7 @@ _cogl_journal_flush (CoglJournal *journal) * is the number of pipeline layers. * 3) We split the entries explicitly by the number of pipeline layers: * We pad our vertex data when the number of layers is < 2 so that we - * can minimize changes in stride. Each time the number of layers - * changes we need to call glTexCoordPointer to inform GL of new VBO - * offsets. + * can minimize changes in stride. * 4) We then split according to compatible Cogl pipelines: * This is where we flush pipeline state * 5) Finally we split according to modelview matrix changes: @@ -1397,11 +1461,11 @@ _cogl_journal_flush (CoglJournal *journal) * Note: Splitting by modelview changes is skipped when are doing the * vertex transformation in software at log time. */ - batch_and_call ((CoglJournalEntry *)journal->entries->data, /* first entry */ - journal->entries->len, /* max number of entries to consider */ - compare_entry_clip_stacks, - _cogl_journal_flush_clip_stacks_and_entries, /* callback */ - &state); /* data */ + batch_and_call ((CoglJournalEntry *)journal->entries->data, + journal->entries->len, + compare_entry_viewports, + _cogl_journal_flush_viewport_and_entries, + &state); for (i = 0; i < state.attributes->len; i++) cogl_object_unref (g_array_index (state.attributes, CoglAttribute *, i)); @@ -1418,7 +1482,7 @@ _cogl_journal_flush (CoglJournal *journal) COGL_TIMER_STOP (_cogl_uprof_context, flush_timer); } -static CoglBool +static gboolean add_framebuffer_deps_cb (CoglPipelineLayer *layer, void *user_data) { CoglFramebuffer *framebuffer = user_data; @@ -1463,12 +1527,6 @@ _cogl_journal_log_quad (CoglJournal *journal, COGL_TIMER_START (_cogl_uprof_context, log_timer); - /* Adding something to the journal should mean that we are in the - * middle of the scene. Although this will also end up being set - * when the journal is actually flushed, we set it here explicitly - * so that we will know sooner */ - _cogl_framebuffer_mark_mid_scene (framebuffer); - /* If the framebuffer was previously empty then we'll take a reference to the current framebuffer. This reference will be removed when the journal is flushed */ @@ -1554,6 +1612,9 @@ _cogl_journal_log_quad (CoglJournal *journal, clip_stack = _cogl_framebuffer_get_clip_stack (framebuffer); entry->clip_stack = _cogl_clip_stack_ref (clip_stack); + entry->dither_enabled = cogl_framebuffer_get_dither_enabled (framebuffer); + + cogl_framebuffer_get_viewport4fv (framebuffer, entry->viewport); if (G_UNLIKELY (final_pipeline != pipeline)) cogl_object_unref (final_pipeline); @@ -1584,7 +1645,7 @@ entry_to_screen_polygon (CoglFramebuffer *framebuffer, CoglMatrix projection; CoglMatrix modelview; int i; - float viewport[4]; + const float *viewport = entry->viewport; poly[0] = vertices[0]; poly[1] = vertices[1]; @@ -1633,8 +1694,6 @@ entry_to_screen_polygon (CoglFramebuffer *framebuffer, poly, /* points_out */ 4 /* n_points */); - cogl_framebuffer_get_viewport4fv (framebuffer, viewport); - /* Scale from OpenGL normalized device coordinates (ranging from -1 to 1) * to Cogl window/framebuffer coordinates (ranging from 0 to buffer-size) with * (0,0) being top left. */ @@ -1666,16 +1725,16 @@ entry_to_screen_polygon (CoglFramebuffer *framebuffer, #undef VIEWPORT_TRANSFORM_Y } -static CoglBool +static gboolean try_checking_point_hits_entry_after_clipping (CoglFramebuffer *framebuffer, CoglJournalEntry *entry, float *vertices, float x, float y, - CoglBool *hit) + gboolean *hit) { - CoglBool can_software_clip = TRUE; - CoglBool needs_software_clip = FALSE; + gboolean can_software_clip = TRUE; + gboolean needs_software_clip = FALSE; CoglClipStack *clip_entry; *hit = TRUE; @@ -1739,12 +1798,12 @@ try_checking_point_hits_entry_after_clipping (CoglFramebuffer *framebuffer, return TRUE; } -CoglBool +gboolean _cogl_journal_try_read_pixel (CoglJournal *journal, int x, int y, CoglBitmap *bitmap, - CoglBool *found_intersection) + gboolean *found_intersection) { CoglContext *ctx; CoglPixelFormat format; @@ -1788,7 +1847,7 @@ _cogl_journal_try_read_pixel (CoglJournal *journal, float poly[16]; CoglFramebuffer *framebuffer = journal->framebuffer; uint8_t *pixel; - CoglError *ignore_error; + GError *ignore_error; entry_to_screen_polygon (framebuffer, entry, vertices, poly); @@ -1797,7 +1856,7 @@ _cogl_journal_try_read_pixel (CoglJournal *journal, if (entry->clip_stack) { - CoglBool hit; + gboolean hit; if (!try_checking_point_hits_entry_after_clipping (framebuffer, entry, @@ -1833,7 +1892,7 @@ _cogl_journal_try_read_pixel (CoglJournal *journal, &ignore_error); if (pixel == NULL) { - cogl_error_free (ignore_error); + g_error_free (ignore_error); return FALSE; } diff --git a/cogl/cogl/cogl-list.c b/cogl/cogl/cogl-list.c index 08e6a2402..9e855e5f9 100644 --- a/cogl/cogl/cogl-list.c +++ b/cogl/cogl/cogl-list.c @@ -23,9 +23,7 @@ /* This list implementation is based on the Wayland source code */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include #include diff --git a/cogl/cogl/cogl-macros.h b/cogl/cogl/cogl-macros.h index 96c06591f..8172354d1 100644 --- a/cogl/cogl/cogl-macros.h +++ b/cogl/cogl/cogl-macros.h @@ -75,213 +75,6 @@ #endif /* COGL_DISABLE_DEPRECATION_WARNINGS */ -/** - * COGL_VERSION_MIN_REQUIRED: - * - * A macro that should be defined by the user prior to including the - * cogl.h header. - * - * The definition should be one of the predefined Cogl version macros, - * such as: %COGL_VERSION_1_8, %COGL_VERSION_1_10, ... - * - * This macro defines the lower bound for the Cogl API to be used. - * - * If a function has been deprecated in a newer version of Cogl, it - * is possible to use this symbol to avoid the compiler warnings without - * disabling warnings for every deprecated function. - * - * Since: 1.16 - */ -#ifndef COGL_VERSION_MIN_REQUIRED -# define COGL_VERSION_MIN_REQUIRED (COGL_VERSION_CURRENT_STABLE) -#endif - -/** - * COGL_VERSION_MAX_ALLOWED: - * - * A macro that should be define by the user prior to including the - * cogl.h header. - * - * The definition should be one of the predefined Cogl version macros, - * such as: %COGL_VERSION_1_0, %COGL_VERSION_1_2, ... - * - * This macro defines the upper bound for the Cogl API to be used. - * - * If a function has been introduced in a newer version of Cogl, it - * is possible to use this symbol to get compiler warnings when trying - * to use that function. - * - * Since: 1.16 - */ -#ifndef COGL_VERSION_MAX_ALLOWED -# if COGL_VERSION_MIN_REQUIRED > COGL_VERSION_PREVIOUS_STABLE -# define COGL_VERSION_MAX_ALLOWED COGL_VERSION_MIN_REQUIRED -# else -# define COGL_VERSION_MAX_ALLOWED COGL_VERSION_CURRENT_STABLE -# endif -#endif - -/* sanity checks */ -#if COGL_VERSION_MAX_ALLOWED < COGL_VERSION_MIN_REQUIRED -# error "COGL_VERSION_MAX_ALLOWED must be >= COGL_VERSION_MIN_REQUIRED" -#endif -#if COGL_VERSION_MIN_REQUIRED < COGL_VERSION_1_0 -# error "COGL_VERSION_MIN_REQUIRED must be >= COGL_VERSION_1_0" -#endif - -/* XXX: Every new stable minor release should add a set of macros here */ -#if COGL_VERSION_MIN_REQUIRED >= COGL_VERSION_1_0 -# define COGL_DEPRECATED_IN_1_0 COGL_DEPRECATED -# define COGL_DEPRECATED_IN_1_0_FOR(f) COGL_DEPRECATED_FOR(f) -#else -# define COGL_DEPRECATED_IN_1_0 -# define COGL_DEPRECATED_IN_1_0_FOR(f) -#endif - -#if COGL_VERSION_MAX_ALLOWED < COGL_VERSION_1_0 -# define COGL_AVAILABLE_IN_1_0 COGL_UNAVAILABLE(1, 0) -#else -# define COGL_AVAILABLE_IN_1_0 -#endif - -#if COGL_VERSION_MIN_REQUIRED >= COGL_VERSION_1_2 -# define COGL_DEPRECATED_IN_1_2 COGL_DEPRECATED -# define COGL_DEPRECATED_IN_1_2_FOR(f) COGL_DEPRECATED_FOR(f) -#else -# define COGL_DEPRECATED_IN_1_2 -# define COGL_DEPRECATED_IN_1_2_FOR(f) -#endif - -#if COGL_VERSION_MAX_ALLOWED < COGL_VERSION_1_2 -# define COGL_AVAILABLE_IN_1_2 COGL_UNAVAILABLE(1, 2) -#else -# define COGL_AVAILABLE_IN_1_2 -#endif - -#if COGL_VERSION_MIN_REQUIRED >= COGL_VERSION_1_4 -# define COGL_DEPRECATED_IN_1_4 COGL_DEPRECATED -# define COGL_DEPRECATED_IN_1_4_FOR(f) COGL_DEPRECATED_FOR(f) -#else -# define COGL_DEPRECATED_IN_1_4 -# define COGL_DEPRECATED_IN_1_4_FOR(f) -#endif - -#if COGL_VERSION_MAX_ALLOWED < COGL_VERSION_1_4 -# define COGL_AVAILABLE_IN_1_4 COGL_UNAVAILABLE(1, 4) -#else -# define COGL_AVAILABLE_IN_1_4 -#endif - -#if COGL_VERSION_MIN_REQUIRED >= COGL_VERSION_1_6 -# define COGL_DEPRECATED_IN_1_6 COGL_DEPRECATED -# define COGL_DEPRECATED_IN_1_6_FOR(f) COGL_DEPRECATED_FOR(f) -#else -# define COGL_DEPRECATED_IN_1_6 -# define COGL_DEPRECATED_IN_1_6_FOR(f) -#endif - -#if COGL_VERSION_MAX_ALLOWED < COGL_VERSION_1_6 -# define COGL_AVAILABLE_IN_1_6 COGL_UNAVAILABLE(1, 6) -#else -# define COGL_AVAILABLE_IN_1_6 -#endif - -#if COGL_VERSION_MIN_REQUIRED >= COGL_VERSION_1_8 -# define COGL_DEPRECATED_IN_1_8 COGL_DEPRECATED -# define COGL_DEPRECATED_IN_1_8_FOR(f) COGL_DEPRECATED_FOR(f) -#else -# define COGL_DEPRECATED_IN_1_8 -# define COGL_DEPRECATED_IN_1_8_FOR(f) -#endif - -#if COGL_VERSION_MAX_ALLOWED < COGL_VERSION_1_8 -# define COGL_AVAILABLE_IN_1_8 COGL_UNAVAILABLE(1, 8) -#else -# define COGL_AVAILABLE_IN_1_8 -#endif - -#if COGL_VERSION_MIN_REQUIRED >= COGL_VERSION_1_10 -# define COGL_DEPRECATED_IN_1_10 COGL_DEPRECATED -# define COGL_DEPRECATED_IN_1_10_FOR(f) COGL_DEPRECATED_FOR(f) -#else -# define COGL_DEPRECATED_IN_1_10 -# define COGL_DEPRECATED_IN_1_10_FOR(f) -#endif - -#if COGL_VERSION_MAX_ALLOWED < COGL_VERSION_1_10 -# define COGL_AVAILABLE_IN_1_10 COGL_UNAVAILABLE(1, 10) -#else -# define COGL_AVAILABLE_IN_1_10 -#endif - -#if COGL_VERSION_MIN_REQUIRED >= COGL_VERSION_1_12 -# define COGL_DEPRECATED_IN_1_12 COGL_DEPRECATED -# define COGL_DEPRECATED_IN_1_12_FOR(f) COGL_DEPRECATED_FOR(f) -#else -# define COGL_DEPRECATED_IN_1_12 -# define COGL_DEPRECATED_IN_1_12_FOR(f) -#endif - -#if COGL_VERSION_MAX_ALLOWED < COGL_VERSION_1_12 -# define COGL_AVAILABLE_IN_1_12 COGL_UNAVAILABLE(1, 12) -#else -# define COGL_AVAILABLE_IN_1_12 -#endif - -#if COGL_VERSION_MIN_REQUIRED >= COGL_VERSION_1_14 -# define COGL_DEPRECATED_IN_1_14 COGL_DEPRECATED -# define COGL_DEPRECATED_IN_1_14_FOR(f) COGL_DEPRECATED_FOR(f) -#else -# define COGL_DEPRECATED_IN_1_14 -# define COGL_DEPRECATED_IN_1_14_FOR(f) -#endif - -#if COGL_VERSION_MAX_ALLOWED < COGL_VERSION_1_14 -# define COGL_AVAILABLE_IN_1_14 COGL_UNAVAILABLE(1, 14) -#else -# define COGL_AVAILABLE_IN_1_14 -#endif - -#if COGL_VERSION_MIN_REQUIRED >= COGL_VERSION_1_16 -# define COGL_DEPRECATED_IN_1_16 COGL_DEPRECATED -# define COGL_DEPRECATED_IN_1_16_FOR(f) COGL_DEPRECATED_FOR(f) -#else -# define COGL_DEPRECATED_IN_1_16 -# define COGL_DEPRECATED_IN_1_16_FOR(f) -#endif - -#if COGL_VERSION_MAX_ALLOWED < COGL_VERSION_1_16 -# define COGL_AVAILABLE_IN_1_16 COGL_UNAVAILABLE(1, 16) -#else -# define COGL_AVAILABLE_IN_1_16 -#endif - -#if COGL_VERSION_MIN_REQUIRED >= COGL_VERSION_1_18 -# define COGL_DEPRECATED_IN_1_18 COGL_DEPRECATED -# define COGL_DEPRECATED_IN_1_18_FOR(f) COGL_DEPRECATED_FOR(f) -#else -# define COGL_DEPRECATED_IN_1_18 -# define COGL_DEPRECATED_IN_1_18_FOR(f) -#endif - -#if COGL_VERSION_MAX_ALLOWED < COGL_VERSION_1_18 -# define COGL_AVAILABLE_IN_1_18 COGL_UNAVAILABLE(1, 18) -#else -# define COGL_AVAILABLE_IN_1_18 -#endif - -#if COGL_VERSION_MIN_REQUIRED >= COGL_VERSION_1_20 -# define COGL_DEPRECATED_IN_1_20 COGL_DEPRECATED -# define COGL_DEPRECATED_IN_1_20_FOR(f) COGL_DEPRECATED_FOR(f) -#else -# define COGL_DEPRECATED_IN_1_20 -# define COGL_DEPRECATED_IN_1_20_FOR(f) -#endif - -#if COGL_VERSION_MAX_ALLOWED < COGL_VERSION_1_20 -# define COGL_AVAILABLE_IN_1_20 COGL_UNAVAILABLE(1, 18) -#else -# define COGL_AVAILABLE_IN_1_20 -#endif +#define COGL_EXPORT __attribute__((visibility("default"))) extern #endif /* __COGL_MACROS_H__ */ diff --git a/cogl/cogl/cogl-magazine.c b/cogl/cogl/cogl-magazine.c index 9c9aa4eb9..be5669d81 100644 --- a/cogl/cogl/cogl-magazine.c +++ b/cogl/cogl/cogl-magazine.c @@ -51,9 +51,7 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-memory-stack-private.h" #include "cogl-magazine-private.h" @@ -80,5 +78,5 @@ void _cogl_magazine_free (CoglMagazine *magazine) { _cogl_memory_stack_free (magazine->stack); - free (magazine); + g_free (magazine); } diff --git a/cogl/cogl/cogl-matrix-private.h b/cogl/cogl/cogl-matrix-private.h index d9fc98eab..0add3e4c2 100644 --- a/cogl/cogl/cogl-matrix-private.h +++ b/cogl/cogl/cogl-matrix-private.h @@ -36,7 +36,7 @@ #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS #define _COGL_MATRIX_DEBUG_PRINT(MATRIX) \ if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_MATRICES))) \ @@ -52,7 +52,7 @@ void _cogl_matrix_init_from_matrix_without_inverse (CoglMatrix *matrix, const CoglMatrix *src); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_MATRIX_PRIVATE_H */ diff --git a/cogl/cogl/cogl-matrix-stack-private.h b/cogl/cogl/cogl-matrix-stack-private.h index 0d5caf8b9..7a6e8b587 100644 --- a/cogl/cogl/cogl-matrix-stack-private.h +++ b/cogl/cogl/cogl-matrix-stack-private.h @@ -45,7 +45,6 @@ typedef enum _CoglMatrixOp COGL_MATRIX_OP_LOAD_IDENTITY, COGL_MATRIX_OP_TRANSLATE, COGL_MATRIX_OP_ROTATE, - COGL_MATRIX_OP_ROTATE_QUATERNION, COGL_MATRIX_OP_ROTATE_EULER, COGL_MATRIX_OP_SCALE, COGL_MATRIX_OP_MULTIPLY, @@ -69,9 +68,7 @@ typedef struct _CoglMatrixEntryTranslate { CoglMatrixEntry _parent_data; - float x; - float y; - float z; + graphene_point3d_t translate; } CoglMatrixEntryTranslate; @@ -80,9 +77,7 @@ typedef struct _CoglMatrixEntryRotate CoglMatrixEntry _parent_data; float angle; - float x; - float y; - float z; + graphene_vec3_t axis; } CoglMatrixEntryRotate; @@ -90,22 +85,9 @@ typedef struct _CoglMatrixEntryRotateEuler { CoglMatrixEntry _parent_data; - /* This doesn't store an actual CoglEuler in order to avoid the - * padding */ - float heading; - float pitch; - float roll; + graphene_euler_t euler; } CoglMatrixEntryRotateEuler; -typedef struct _CoglMatrixEntryRotateQuaternion -{ - CoglMatrixEntry _parent_data; - - /* This doesn't store an actual CoglQuaternion in order to avoid the - * padding */ - float values[4]; -} CoglMatrixEntryRotateQuaternion; - typedef struct _CoglMatrixEntryScale { CoglMatrixEntry _parent_data; @@ -137,7 +119,7 @@ typedef struct _CoglMatrixEntrySave CoglMatrixEntry _parent_data; CoglMatrix *cache; - CoglBool cache_valid; + gboolean cache_valid; } CoglMatrixEntrySave; @@ -147,7 +129,6 @@ typedef union _CoglMatrixEntryFull CoglMatrixEntryTranslate translate; CoglMatrixEntryRotate rotate; CoglMatrixEntryRotateEuler rotate_euler; - CoglMatrixEntryRotateQuaternion rotate_quaternion; CoglMatrixEntryScale scale; CoglMatrixEntryMultiply multiply; CoglMatrixEntryLoad load; @@ -166,33 +147,20 @@ struct _CoglMatrixStack typedef struct _CoglMatrixEntryCache { CoglMatrixEntry *entry; - CoglBool flushed_identity; - CoglBool flipped; + gboolean flushed_identity; + gboolean flipped; } CoglMatrixEntryCache; void _cogl_matrix_entry_identity_init (CoglMatrixEntry *entry); -typedef enum { - COGL_MATRIX_MODELVIEW, - COGL_MATRIX_PROJECTION, - COGL_MATRIX_TEXTURE -} CoglMatrixMode; - -void -_cogl_matrix_entry_flush_to_gl_builtins (CoglContext *ctx, - CoglMatrixEntry *entry, - CoglMatrixMode mode, - CoglFramebuffer *framebuffer, - CoglBool disable_flip); - void _cogl_matrix_entry_cache_init (CoglMatrixEntryCache *cache); -CoglBool +gboolean _cogl_matrix_entry_cache_maybe_update (CoglMatrixEntryCache *cache, CoglMatrixEntry *entry, - CoglBool flip); + gboolean flip); void _cogl_matrix_entry_cache_destroy (CoglMatrixEntryCache *cache); diff --git a/cogl/cogl/cogl-matrix-stack.c b/cogl/cogl/cogl-matrix-stack.c index d426e1fa3..2e5150afa 100644 --- a/cogl/cogl/cogl-matrix-stack.c +++ b/cogl/cogl/cogl-matrix-stack.c @@ -31,12 +31,9 @@ * Neil Roberts */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-context-private.h" -#include "cogl-util-gl-private.h" #include "cogl-matrix-stack.h" #include "cogl-framebuffer-private.h" #include "cogl-object-private.h" @@ -44,6 +41,7 @@ #include "cogl-matrix-private.h" #include "cogl-magazine-private.h" #include "cogl-gtype-private.h" +#include "driver/gl/cogl-util-gl-private.h" static void _cogl_matrix_stack_free (CoglMatrixStack *stack); @@ -160,9 +158,7 @@ cogl_matrix_stack_translate (CoglMatrixStack *stack, entry = _cogl_matrix_stack_push_operation (stack, COGL_MATRIX_OP_TRANSLATE); - entry->x = x; - entry->y = y; - entry->z = z; + graphene_point3d_init (&entry->translate, x, y, z); } void @@ -177,38 +173,18 @@ cogl_matrix_stack_rotate (CoglMatrixStack *stack, entry = _cogl_matrix_stack_push_operation (stack, COGL_MATRIX_OP_ROTATE); entry->angle = angle; - entry->x = x; - entry->y = y; - entry->z = z; -} - -void -cogl_matrix_stack_rotate_quaternion (CoglMatrixStack *stack, - const CoglQuaternion *quaternion) -{ - CoglMatrixEntryRotateQuaternion *entry; - - entry = _cogl_matrix_stack_push_operation (stack, - COGL_MATRIX_OP_ROTATE_QUATERNION); - - entry->values[0] = quaternion->w; - entry->values[1] = quaternion->x; - entry->values[2] = quaternion->y; - entry->values[3] = quaternion->z; + graphene_vec3_init (&entry->axis, x, y, z); } void -cogl_matrix_stack_rotate_euler (CoglMatrixStack *stack, - const CoglEuler *euler) +cogl_matrix_stack_rotate_euler (CoglMatrixStack *stack, + const graphene_euler_t *euler) { CoglMatrixEntryRotateEuler *entry; entry = _cogl_matrix_stack_push_operation (stack, COGL_MATRIX_OP_ROTATE_EULER); - - entry->heading = euler->heading; - entry->pitch = euler->pitch; - entry->roll = euler->roll; + graphene_euler_init_from_euler (&entry->euler, euler); } void @@ -359,7 +335,6 @@ cogl_matrix_entry_unref (CoglMatrixEntry *entry) case COGL_MATRIX_OP_LOAD_IDENTITY: case COGL_MATRIX_OP_TRANSLATE: case COGL_MATRIX_OP_ROTATE: - case COGL_MATRIX_OP_ROTATE_QUATERNION: case COGL_MATRIX_OP_ROTATE_EULER: case COGL_MATRIX_OP_SCALE: break; @@ -398,10 +373,10 @@ cogl_matrix_stack_pop (CoglMatrixStack *stack) CoglMatrixEntry *old_top; CoglMatrixEntry *new_top; - _COGL_RETURN_IF_FAIL (stack != NULL); + g_return_if_fail (stack != NULL); old_top = stack->last_entry; - _COGL_RETURN_IF_FAIL (old_top != NULL); + g_return_if_fail (old_top != NULL); /* To pop we are moving the top of the stack to the old top's parent * node. The stack always needs to have a reference to the top entry @@ -429,7 +404,7 @@ cogl_matrix_stack_pop (CoglMatrixStack *stack) stack->last_entry = new_top; } -CoglBool +gboolean cogl_matrix_stack_get_inverse (CoglMatrixStack *stack, CoglMatrix *inverse) { @@ -500,7 +475,6 @@ cogl_matrix_entry_get (CoglMatrixEntry *entry, case COGL_MATRIX_OP_LOAD_IDENTITY: case COGL_MATRIX_OP_TRANSLATE: case COGL_MATRIX_OP_ROTATE: - case COGL_MATRIX_OP_ROTATE_QUATERNION: case COGL_MATRIX_OP_ROTATE_EULER: case COGL_MATRIX_OP_SCALE: case COGL_MATRIX_OP_MULTIPLY: @@ -562,9 +536,9 @@ cogl_matrix_entry_get (CoglMatrixEntry *entry, CoglMatrixEntryTranslate *translate = (CoglMatrixEntryTranslate *)children[i]; cogl_matrix_translate (matrix, - translate->x, - translate->y, - translate->z); + translate->translate.x, + translate->translate.y, + translate->translate.z); continue; } case COGL_MATRIX_OP_ROTATE: @@ -573,31 +547,17 @@ cogl_matrix_entry_get (CoglMatrixEntry *entry, (CoglMatrixEntryRotate *)children[i]; cogl_matrix_rotate (matrix, rotate->angle, - rotate->x, - rotate->y, - rotate->z); + graphene_vec3_get_x (&rotate->axis), + graphene_vec3_get_y (&rotate->axis), + graphene_vec3_get_z (&rotate->axis)); continue; } case COGL_MATRIX_OP_ROTATE_EULER: { CoglMatrixEntryRotateEuler *rotate = (CoglMatrixEntryRotateEuler *)children[i]; - CoglEuler euler; - cogl_euler_init (&euler, - rotate->heading, - rotate->pitch, - rotate->roll); cogl_matrix_rotate_euler (matrix, - &euler); - continue; - } - case COGL_MATRIX_OP_ROTATE_QUATERNION: - { - CoglMatrixEntryRotateQuaternion *rotate = - (CoglMatrixEntryRotateQuaternion *)children[i]; - CoglQuaternion quaternion; - cogl_quaternion_init_from_array (&quaternion, rotate->values); - cogl_matrix_rotate_quaternion (matrix, &quaternion); + &rotate->euler); continue; } case COGL_MATRIX_OP_SCALE: @@ -688,7 +648,7 @@ _cogl_matrix_entry_skip_saves (CoglMatrixEntry *entry) return entry; } -CoglBool +gboolean cogl_matrix_entry_calculate_translation (CoglMatrixEntry *entry0, CoglMatrixEntry *entry1, float *x, @@ -792,9 +752,9 @@ cogl_matrix_entry_calculate_translation (CoglMatrixEntry *entry0, translate = (CoglMatrixEntryTranslate *)node0; - *x = *x - translate->x; - *y = *y - translate->y; - *z = *z - translate->z; + *x = *x - translate->translate.x; + *y = *y - translate->translate.y; + *z = *z - translate->translate.z; } for (head1 = common_ancestor1->next; head1; head1 = head1->next) { @@ -807,142 +767,21 @@ cogl_matrix_entry_calculate_translation (CoglMatrixEntry *entry0, translate = (CoglMatrixEntryTranslate *)node1; - *x = *x + translate->x; - *y = *y + translate->y; - *z = *z + translate->z; + *x = *x + translate->translate.x; + *y = *y + translate->translate.y; + *z = *z + translate->translate.z; } return TRUE; } -CoglBool +gboolean cogl_matrix_entry_is_identity (CoglMatrixEntry *entry) { return entry ? entry->op == COGL_MATRIX_OP_LOAD_IDENTITY : FALSE; } -static void -_cogl_matrix_flush_to_gl_builtin (CoglContext *ctx, - CoglBool is_identity, - CoglMatrix *matrix, - CoglMatrixMode mode) -{ - g_assert (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_FIXED)); - -#if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES) - if (ctx->flushed_matrix_mode != mode) - { - GLenum gl_mode = 0; - - switch (mode) - { - case COGL_MATRIX_MODELVIEW: - gl_mode = GL_MODELVIEW; - break; - - case COGL_MATRIX_PROJECTION: - gl_mode = GL_PROJECTION; - break; - - case COGL_MATRIX_TEXTURE: - gl_mode = GL_TEXTURE; - break; - } - - GE (ctx, glMatrixMode (gl_mode)); - ctx->flushed_matrix_mode = mode; - } - - if (is_identity) - GE (ctx, glLoadIdentity ()); - else - GE (ctx, glLoadMatrixf (cogl_matrix_get_array (matrix))); -#endif -} - -void -_cogl_matrix_entry_flush_to_gl_builtins (CoglContext *ctx, - CoglMatrixEntry *entry, - CoglMatrixMode mode, - CoglFramebuffer *framebuffer, - CoglBool disable_flip) -{ - g_assert (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_FIXED)); - -#if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES) - { - CoglBool needs_flip; - CoglMatrixEntryCache *cache; - - if (mode == COGL_MATRIX_PROJECTION) - { - /* Because Cogl defines texture coordinates to have a top left - * origin and because offscreen framebuffers may be used for - * rendering to textures we always render upside down to - * offscreen buffers. Also for some backends we need to render - * onscreen buffers upside-down too. - */ - if (disable_flip) - needs_flip = FALSE; - else - needs_flip = cogl_is_offscreen (framebuffer); - - cache = &ctx->builtin_flushed_projection; - } - else - { - needs_flip = FALSE; - - if (mode == COGL_MATRIX_MODELVIEW) - cache = &ctx->builtin_flushed_modelview; - else - cache = NULL; - } - - /* We don't need to do anything if the state is the same */ - if (!cache || - _cogl_matrix_entry_cache_maybe_update (cache, entry, needs_flip)) - { - CoglBool is_identity; - CoglMatrix matrix; - - if (entry->op == COGL_MATRIX_OP_LOAD_IDENTITY) - is_identity = TRUE; - else - { - is_identity = FALSE; - cogl_matrix_entry_get (entry, &matrix); - } - - if (needs_flip) - { - CoglMatrix flipped_matrix; - - cogl_matrix_multiply (&flipped_matrix, - &ctx->y_flip_matrix, - is_identity ? - &ctx->identity_matrix : - &matrix); - - _cogl_matrix_flush_to_gl_builtin (ctx, - /* not identity */ - FALSE, - &flipped_matrix, - mode); - } - else - { - _cogl_matrix_flush_to_gl_builtin (ctx, - is_identity, - &matrix, - mode); - } - } - } -#endif -} - -CoglBool +gboolean cogl_matrix_entry_equal (CoglMatrixEntry *entry0, CoglMatrixEntry *entry1) { @@ -972,9 +811,8 @@ cogl_matrix_entry_equal (CoglMatrixEntry *entry0, /* We could perhaps use an epsilon to compare here? * I expect the false negatives are probaly never going to * be a problem and this is a bit cheaper. */ - if (translate0->x != translate1->x || - translate0->y != translate1->y || - translate0->z != translate1->z) + if (!graphene_point3d_equal (&translate0->translate, + &translate1->translate)) return FALSE; } break; @@ -985,24 +823,10 @@ cogl_matrix_entry_equal (CoglMatrixEntry *entry0, CoglMatrixEntryRotate *rotate1 = (CoglMatrixEntryRotate *)entry1; if (rotate0->angle != rotate1->angle || - rotate0->x != rotate1->x || - rotate0->y != rotate1->y || - rotate0->z != rotate1->z) + !graphene_vec3_equal (&rotate0->axis, &rotate1->axis)) return FALSE; } break; - case COGL_MATRIX_OP_ROTATE_QUATERNION: - { - CoglMatrixEntryRotateQuaternion *rotate0 = - (CoglMatrixEntryRotateQuaternion *)entry0; - CoglMatrixEntryRotateQuaternion *rotate1 = - (CoglMatrixEntryRotateQuaternion *)entry1; - int i; - for (i = 0; i < 4; i++) - if (rotate0->values[i] != rotate1->values[i]) - return FALSE; - } - break; case COGL_MATRIX_OP_ROTATE_EULER: { CoglMatrixEntryRotateEuler *rotate0 = @@ -1010,9 +834,7 @@ cogl_matrix_entry_equal (CoglMatrixEntry *entry0, CoglMatrixEntryRotateEuler *rotate1 = (CoglMatrixEntryRotateEuler *)entry1; - if (rotate0->heading != rotate1->heading || - rotate0->pitch != rotate1->pitch || - rotate0->roll != rotate1->roll) + if (!graphene_euler_equal (&rotate0->euler, &rotate1->euler)) return FALSE; } break; @@ -1088,9 +910,9 @@ cogl_debug_matrix_entry_print (CoglMatrixEntry *entry) CoglMatrixEntryTranslate *translate = (CoglMatrixEntryTranslate *)entry; g_print (" TRANSLATE X=%f Y=%f Z=%f\n", - translate->x, - translate->y, - translate->z); + translate->translate.x, + translate->translate.y, + translate->translate.z); continue; } case COGL_MATRIX_OP_ROTATE: @@ -1099,20 +921,9 @@ cogl_debug_matrix_entry_print (CoglMatrixEntry *entry) (CoglMatrixEntryRotate *)entry; g_print (" ROTATE ANGLE=%f X=%f Y=%f Z=%f\n", rotate->angle, - rotate->x, - rotate->y, - rotate->z); - continue; - } - case COGL_MATRIX_OP_ROTATE_QUATERNION: - { - CoglMatrixEntryRotateQuaternion *rotate = - (CoglMatrixEntryRotateQuaternion *)entry; - g_print (" ROTATE QUATERNION w=%f x=%f y=%f z=%f\n", - rotate->values[0], - rotate->values[1], - rotate->values[2], - rotate->values[3]); + graphene_vec3_get_x (&rotate->axis), + graphene_vec3_get_y (&rotate->axis), + graphene_vec3_get_z (&rotate->axis)); continue; } case COGL_MATRIX_OP_ROTATE_EULER: @@ -1120,9 +931,9 @@ cogl_debug_matrix_entry_print (CoglMatrixEntry *entry) CoglMatrixEntryRotateEuler *rotate = (CoglMatrixEntryRotateEuler *)entry; g_print (" ROTATE EULER heading=%f pitch=%f roll=%f\n", - rotate->heading, - rotate->pitch, - rotate->roll); + graphene_euler_get_y (&rotate->euler), + graphene_euler_get_x (&rotate->euler), + graphene_euler_get_z (&rotate->euler)); continue; } case COGL_MATRIX_OP_SCALE: @@ -1164,13 +975,13 @@ _cogl_matrix_entry_cache_init (CoglMatrixEntryCache *cache) /* NB: This function can report false negatives since it never does a * deep comparison of the stack matrices. */ -CoglBool +gboolean _cogl_matrix_entry_cache_maybe_update (CoglMatrixEntryCache *cache, CoglMatrixEntry *entry, - CoglBool flip) + gboolean flip) { - CoglBool is_identity; - CoglBool updated = FALSE; + gboolean is_identity; + gboolean updated = FALSE; if (cache->flipped != flip) { diff --git a/cogl/cogl/cogl-matrix-stack.h b/cogl/cogl/cogl-matrix-stack.h index 8d936b218..d8262d3c3 100644 --- a/cogl/cogl/cogl-matrix-stack.h +++ b/cogl/cogl/cogl-matrix-stack.h @@ -42,6 +42,7 @@ #include "cogl-matrix.h" #include "cogl-context.h" +#include /** * SECTION:cogl-matrix-stack @@ -139,6 +140,7 @@ typedef struct _CoglMatrixStack CoglMatrixStack; * * Returns: a #GType that can be used with the GLib type system. */ +COGL_EXPORT GType cogl_matrix_stack_get_gtype (void); /** @@ -182,6 +184,7 @@ typedef struct _CoglMatrixEntry CoglMatrixEntry; * * Returns: a #GType that can be used with the GLib type system. */ +COGL_EXPORT GType cogl_matrix_entry_get_gtype (void); @@ -213,7 +216,7 @@ GType cogl_matrix_entry_get_gtype (void); * * Return value: (transfer full): A newly allocated #CoglMatrixStack */ -CoglMatrixStack * +COGL_EXPORT CoglMatrixStack * cogl_matrix_stack_new (CoglContext *ctx); /** @@ -228,7 +231,7 @@ cogl_matrix_stack_new (CoglContext *ctx); * called when going back up one layer to restore the previous * transform of an ancestor. */ -void +COGL_EXPORT void cogl_matrix_stack_push (CoglMatrixStack *stack); /** @@ -241,7 +244,7 @@ cogl_matrix_stack_push (CoglMatrixStack *stack); * This is usually called while traversing a scenegraph whenever you * return up one level in the graph towards the root node. */ -void +COGL_EXPORT void cogl_matrix_stack_pop (CoglMatrixStack *stack); /** @@ -250,7 +253,7 @@ cogl_matrix_stack_pop (CoglMatrixStack *stack); * * Resets the current matrix to the identity matrix. */ -void +COGL_EXPORT void cogl_matrix_stack_load_identity (CoglMatrixStack *stack); /** @@ -263,7 +266,7 @@ cogl_matrix_stack_load_identity (CoglMatrixStack *stack); * Multiplies the current matrix by one that scales the x, y and z * axes by the given values. */ -void +COGL_EXPORT void cogl_matrix_stack_scale (CoglMatrixStack *stack, float x, float y, @@ -279,7 +282,7 @@ cogl_matrix_stack_scale (CoglMatrixStack *stack, * Multiplies the current matrix by one that translates along all * three axes according to the given values. */ -void +COGL_EXPORT void cogl_matrix_stack_translate (CoglMatrixStack *stack, float x, float y, @@ -299,36 +302,24 @@ cogl_matrix_stack_translate (CoglMatrixStack *stack, * the axis-vector (0, 0, 1) causes a small counter-clockwise * rotation. */ -void +COGL_EXPORT void cogl_matrix_stack_rotate (CoglMatrixStack *stack, float angle, float x, float y, float z); -/** - * cogl_matrix_stack_rotate_quaternion: - * @stack: A #CoglMatrixStack - * @quaternion: A #CoglQuaternion - * - * Multiplies the current matrix by one that rotates according to the - * rotation described by @quaternion. - */ -void -cogl_matrix_stack_rotate_quaternion (CoglMatrixStack *stack, - const CoglQuaternion *quaternion); - /** * cogl_matrix_stack_rotate_euler: * @stack: A #CoglMatrixStack - * @euler: A #CoglEuler + * @euler: A #graphene_euler_t * * Multiplies the current matrix by one that rotates according to the * rotation described by @euler. */ -void +COGL_EXPORT void cogl_matrix_stack_rotate_euler (CoglMatrixStack *stack, - const CoglEuler *euler); + const graphene_euler_t *euler); /** * cogl_matrix_stack_multiply: @@ -337,7 +328,7 @@ cogl_matrix_stack_rotate_euler (CoglMatrixStack *stack, * * Multiplies the current matrix by the given matrix. */ -void +COGL_EXPORT void cogl_matrix_stack_multiply (CoglMatrixStack *stack, const CoglMatrix *matrix); @@ -359,7 +350,7 @@ cogl_matrix_stack_multiply (CoglMatrixStack *stack, * viewing frustum defined by 4 side clip planes that all cross * through the origin and 2 near and far clip planes. */ -void +COGL_EXPORT void cogl_matrix_stack_frustum (CoglMatrixStack *stack, float left, float right, @@ -385,7 +376,7 @@ cogl_matrix_stack_frustum (CoglMatrixStack *stack, * since there wont be enough precision to identify the depth of * objects near to each other. */ -void +COGL_EXPORT void cogl_matrix_stack_perspective (CoglMatrixStack *stack, float fov_y, float aspect, @@ -408,7 +399,7 @@ cogl_matrix_stack_perspective (CoglMatrixStack *stack, * * Replaces the current matrix with an orthographic projection matrix. */ -void +COGL_EXPORT void cogl_matrix_stack_orthographic (CoglMatrixStack *stack, float x_1, float y_1, @@ -429,7 +420,7 @@ cogl_matrix_stack_orthographic (CoglMatrixStack *stack, * for degenerate transformations that can't be inverted (in this case the * @inverse matrix will simply be initialized with the identity matrix) */ -CoglBool +COGL_EXPORT gboolean cogl_matrix_stack_get_inverse (CoglMatrixStack *stack, CoglMatrix *inverse); @@ -451,7 +442,7 @@ cogl_matrix_stack_get_inverse (CoglMatrixStack *stack, * Return value: (transfer none): A pointer to the #CoglMatrixEntry * representing the current matrix stack transform. */ -CoglMatrixEntry * +COGL_EXPORT CoglMatrixEntry * cogl_matrix_stack_get_entry (CoglMatrixStack *stack); /** @@ -480,7 +471,7 @@ cogl_matrix_stack_get_entry (CoglMatrixStack *stack); * and in that case @matrix will be initialized with * the value of the current transform. */ -CoglMatrix * +COGL_EXPORT CoglMatrix * cogl_matrix_stack_get (CoglMatrixStack *stack, CoglMatrix *matrix); @@ -511,7 +502,7 @@ cogl_matrix_stack_get (CoglMatrixStack *stack, * and in that case @matrix will be initialized with * the effective transform represented by @entry. */ -CoglMatrix * +COGL_EXPORT CoglMatrix * cogl_matrix_entry_get (CoglMatrixEntry *entry, CoglMatrix *matrix); @@ -525,7 +516,7 @@ cogl_matrix_entry_get (CoglMatrixEntry *entry, * since the last time cogl_matrix_stack_push() was called or since * the stack was initialized. */ -void +COGL_EXPORT void cogl_matrix_stack_set (CoglMatrixStack *stack, const CoglMatrix *matrix); @@ -538,7 +529,7 @@ cogl_matrix_stack_set (CoglMatrixStack *stack, * Return value: %TRUE if @object is a #CoglMatrixStack, otherwise * %FALSE. */ -CoglBool +COGL_EXPORT gboolean cogl_is_matrix_stack (void *object); /** @@ -560,7 +551,7 @@ cogl_is_matrix_stack (void *object); * @entry0 and the transform of @entry1 is a translation, * otherwise %FALSE. */ -CoglBool +COGL_EXPORT gboolean cogl_matrix_entry_calculate_translation (CoglMatrixEntry *entry0, CoglMatrixEntry *entry1, float *x, @@ -581,7 +572,7 @@ cogl_matrix_entry_calculate_translation (CoglMatrixEntry *entry0, * Return value: %TRUE if @entry is definitely an identity transform, * otherwise %FALSE. */ -CoglBool +COGL_EXPORT gboolean cogl_matrix_entry_is_identity (CoglMatrixEntry *entry); /** @@ -599,7 +590,7 @@ cogl_matrix_entry_is_identity (CoglMatrixEntry *entry); * Return value: %TRUE if @entry0 represents the same transform as * @entry1, otherwise %FALSE. */ -CoglBool +COGL_EXPORT gboolean cogl_matrix_entry_equal (CoglMatrixEntry *entry0, CoglMatrixEntry *entry1); @@ -610,7 +601,7 @@ cogl_matrix_entry_equal (CoglMatrixEntry *entry0, * Allows visualizing the operations that build up the given @entry * for debugging purposes by printing to stdout. */ -void +COGL_EXPORT void cogl_debug_matrix_entry_print (CoglMatrixEntry *entry); /** @@ -624,7 +615,7 @@ cogl_debug_matrix_entry_print (CoglMatrixEntry *entry); * It is an error to pass an @entry pointer to cogl_object_ref() and * cogl_object_unref() */ -CoglMatrixEntry * +COGL_EXPORT CoglMatrixEntry * cogl_matrix_entry_ref (CoglMatrixEntry *entry); /** @@ -635,7 +626,7 @@ cogl_matrix_entry_ref (CoglMatrixEntry *entry); * cogl_matrix_entry_unref() or to release the reference given when * calling cogl_matrix_stack_get_entry(). */ -void +COGL_EXPORT void cogl_matrix_entry_unref (CoglMatrixEntry *entry); #endif /* _COGL_MATRIX_STACK_H_ */ diff --git a/cogl/cogl/cogl-matrix.c b/cogl/cogl/cogl-matrix.c index 7c01a0bd8..06cded0f8 100644 --- a/cogl/cogl/cogl-matrix.c +++ b/cogl/cogl/cogl-matrix.c @@ -69,17 +69,12 @@ * the inverse of the identity matrix) */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include #include -#include -#include #include #include -#include #include #include @@ -378,7 +373,7 @@ _cogl_matrix_prefix_print (const char *prefix, const CoglMatrix *matrix) { if (!(matrix->flags & MAT_DIRTY_TYPE)) { - _COGL_RETURN_IF_FAIL (matrix->type < COGL_MATRIX_N_TYPES); + g_return_if_fail (matrix->type < COGL_MATRIX_N_TYPES); g_print ("%sMatrix type: %s, flags: %x\n", prefix, types[matrix->type], (int)matrix->flags); } @@ -444,7 +439,7 @@ cogl_debug_matrix_print (const CoglMatrix *matrix) * with partial pivoting followed by back/substitution with the loops manually * unrolled. */ -static CoglBool +static gboolean invert_matrix_general (CoglMatrix *matrix) { const float *m = (float *)matrix; @@ -583,7 +578,7 @@ invert_matrix_general (CoglMatrix *matrix) * element. Finally deals with the translation part by transforming the * original translation vector using by the calculated submatrix inverse. */ -static CoglBool +static gboolean invert_matrix_3d_general (CoglMatrix *matrix) { const float *in = (float *)matrix; @@ -665,7 +660,7 @@ invert_matrix_3d_general (CoglMatrix *matrix) * the inverse matrix analyzing and inverting each of the scaling, rotation and * translation parts. */ -static CoglBool +static gboolean invert_matrix_3d (CoglMatrix *matrix) { const float *in = (float *)matrix; @@ -750,7 +745,7 @@ invert_matrix_3d (CoglMatrix *matrix) * * Simply copies identity into CoglMatrix::inv. */ -static CoglBool +static gboolean invert_matrix_identity (CoglMatrix *matrix) { memcpy (matrix->inv, identity, 16 * sizeof (float)); @@ -767,7 +762,7 @@ invert_matrix_identity (CoglMatrix *matrix) * * Calculates the */ -static CoglBool +static gboolean invert_matrix_3d_no_rotation (CoglMatrix *matrix) { const float *in = (float *)matrix; @@ -802,7 +797,7 @@ invert_matrix_3d_no_rotation (CoglMatrix *matrix) * Calculates the inverse matrix by applying the inverse scaling and * translation to the identity matrix. */ -static CoglBool +static gboolean invert_matrix_2d_no_rotation (CoglMatrix *matrix) { const float *in = (float *)matrix; @@ -826,7 +821,7 @@ invert_matrix_2d_no_rotation (CoglMatrix *matrix) #if 0 /* broken */ -static CoglBool +static gboolean invert_matrix_perspective (CoglMatrix *matrix) { const float *in = matrix; @@ -856,7 +851,7 @@ invert_matrix_perspective (CoglMatrix *matrix) /* * Matrix inversion function pointer type. */ -typedef CoglBool (*inv_mat_func)(CoglMatrix *matrix); +typedef gboolean (*inv_mat_func)(CoglMatrix *matrix); /* * Table of the matrix inversion functions according to the matrix type. @@ -1114,7 +1109,7 @@ _cogl_matrix_update_type_and_flags (CoglMatrix *matrix) * given matrix type. In case of failure, updates the MAT_FLAG_SINGULAR flag, * and copies the identity matrix into CoglMatrix::inv. */ -static CoglBool +static gboolean _cogl_matrix_update_inverse (CoglMatrix *matrix) { if (matrix->flags & MAT_DIRTY_FLAGS || @@ -1139,7 +1134,7 @@ _cogl_matrix_update_inverse (CoglMatrix *matrix) return TRUE; } -CoglBool +gboolean cogl_matrix_get_inverse (const CoglMatrix *matrix, CoglMatrix *inverse) { if (_cogl_matrix_update_inverse ((CoglMatrix *)matrix)) @@ -1171,7 +1166,7 @@ _cogl_matrix_rotate (CoglMatrix *matrix, { float xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c, s, c; float m[16]; - CoglBool optimized; + gboolean optimized; s = sinf (angle * DEG2RAD); c = cosf (angle * DEG2RAD); @@ -1360,19 +1355,9 @@ cogl_matrix_rotate (CoglMatrix *matrix, _COGL_MATRIX_DEBUG_PRINT (matrix); } -void -cogl_matrix_rotate_quaternion (CoglMatrix *matrix, - const CoglQuaternion *quaternion) -{ - CoglMatrix rotation_transform; - - cogl_matrix_init_from_quaternion (&rotation_transform, quaternion); - cogl_matrix_multiply (matrix, matrix, &rotation_transform); -} - void cogl_matrix_rotate_euler (CoglMatrix *matrix, - const CoglEuler *euler) + const graphene_euler_t *euler) { CoglMatrix rotation_transform; @@ -1491,19 +1476,6 @@ _cogl_matrix_orthographic (CoglMatrix *matrix, MAT_FLAG_TRANSLATION)); } -void -cogl_matrix_ortho (CoglMatrix *matrix, - float left, - float right, - float bottom, - float top, - float near, - float far) -{ - _cogl_matrix_orthographic (matrix, left, top, right, bottom, near, far); - _COGL_MATRIX_DEBUG_PRINT (matrix); -} - void cogl_matrix_orthographic (CoglMatrix *matrix, float x_1, @@ -1669,7 +1641,7 @@ cogl_matrix_init_translation (CoglMatrix *matrix, /* * Test if the given matrix preserves vector lengths. */ -static CoglBool +static gboolean _cogl_matrix_is_length_preserving (const CoglMatrix *m) { return TEST_MAT_FLAGS (m, MAT_FLAGS_LENGTH_PRESERVING); @@ -1679,7 +1651,7 @@ _cogl_matrix_is_length_preserving (const CoglMatrix *m) * Test if the given matrix does any rotation. * (or perhaps if the upper-left 3x3 is non-identity) */ -static CoglBool +static gboolean _cogl_matrix_has_rotation (const CoglMatrix *matrix) { if (matrix->flags & (MAT_FLAG_GENERAL | @@ -1691,13 +1663,13 @@ _cogl_matrix_has_rotation (const CoglMatrix *matrix) return FALSE; } -static CoglBool +static gboolean _cogl_matrix_is_general_scale (const CoglMatrix *matrix) { return (matrix->flags & MAT_FLAG_GENERAL_SCALE) ? TRUE : FALSE; } -static CoglBool +static gboolean _cogl_matrix_is_dirty (const CoglMatrix *matrix) { return (matrix->flags & MAT_DIRTY_ALL) ? TRUE : FALSE; @@ -1737,56 +1709,14 @@ _cogl_matrix_init_from_matrix_without_inverse (CoglMatrix *matrix, matrix->flags = src->flags | MAT_DIRTY_INVERSE; } -static void -_cogl_matrix_init_from_quaternion (CoglMatrix *matrix, - const CoglQuaternion *quaternion) -{ - float qnorm = _COGL_QUATERNION_NORM (quaternion); - float s = (qnorm > 0.0f) ? (2.0f / qnorm) : 0.0f; - float xs = quaternion->x * s; - float ys = quaternion->y * s; - float zs = quaternion->z * s; - float wx = quaternion->w * xs; - float wy = quaternion->w * ys; - float wz = quaternion->w * zs; - float xx = quaternion->x * xs; - float xy = quaternion->x * ys; - float xz = quaternion->x * zs; - float yy = quaternion->y * ys; - float yz = quaternion->y * zs; - float zz = quaternion->z * zs; - - matrix->xx = 1.0f - (yy + zz); - matrix->yx = xy + wz; - matrix->zx = xz - wy; - matrix->xy = xy - wz; - matrix->yy = 1.0f - (xx + zz); - matrix->zy = yz + wx; - matrix->xz = xz + wy; - matrix->yz = yz - wx; - matrix->zz = 1.0f - (xx + yy); - matrix->xw = matrix->yw = matrix->zw = 0.0f; - matrix->wx = matrix->wy = matrix->wz = 0.0f; - matrix->ww = 1.0f; - - matrix->flags = (MAT_FLAG_GENERAL | MAT_DIRTY_ALL); -} - -void -cogl_matrix_init_from_quaternion (CoglMatrix *matrix, - const CoglQuaternion *quaternion) -{ - _cogl_matrix_init_from_quaternion (matrix, quaternion); -} - void cogl_matrix_init_from_euler (CoglMatrix *matrix, - const CoglEuler *euler) + const graphene_euler_t *euler) { /* Convert angles to radians */ - float heading_rad = euler->heading / 180.0f * G_PI; - float pitch_rad = euler->pitch / 180.0f * G_PI; - float roll_rad = euler->roll / 180.0f * G_PI; + float heading_rad = graphene_euler_get_y (euler) / 180.0f * G_PI; + float pitch_rad = graphene_euler_get_x (euler) / 180.0f * G_PI; + float roll_rad = graphene_euler_get_z (euler) / 180.0f * G_PI; /* Pre-calculate the sin and cos */ float sin_heading = sinf (heading_rad); float cos_heading = cosf (heading_rad); @@ -1938,14 +1868,14 @@ cogl_matrix_view_2d_in_perspective (CoglMatrix *matrix, height_2d); } -CoglBool +gboolean cogl_matrix_equal (const void *v1, const void *v2) { const CoglMatrix *a = v1; const CoglMatrix *b = v2; - _COGL_RETURN_VAL_IF_FAIL (v1 != NULL, FALSE); - _COGL_RETURN_VAL_IF_FAIL (v2 != NULL, FALSE); + g_return_val_if_fail (v1 != NULL, FALSE); + g_return_val_if_fail (v2 != NULL, FALSE); /* We want to avoid having a fuzzy _equal() function (e.g. that uses * an arbitrary epsilon value) since this function noteably conforms @@ -2169,7 +2099,7 @@ cogl_matrix_transform_points (const CoglMatrix *matrix, int n_points) { /* The results of transforming always have three components... */ - _COGL_RETURN_IF_FAIL (stride_out >= sizeof (Point3f)); + g_return_if_fail (stride_out >= sizeof (Point3f)); if (n_components == 2) _cogl_matrix_transform_points_f2 (matrix, @@ -2178,7 +2108,7 @@ cogl_matrix_transform_points (const CoglMatrix *matrix, n_points); else { - _COGL_RETURN_IF_FAIL (n_components == 3); + g_return_if_fail (n_components == 3); _cogl_matrix_transform_points_f3 (matrix, stride_in, points_in, @@ -2208,7 +2138,7 @@ cogl_matrix_project_points (const CoglMatrix *matrix, n_points); else { - _COGL_RETURN_IF_FAIL (n_components == 4); + g_return_if_fail (n_components == 4); _cogl_matrix_project_points_f4 (matrix, stride_in, points_in, @@ -2217,7 +2147,7 @@ cogl_matrix_project_points (const CoglMatrix *matrix, } } -CoglBool +gboolean cogl_matrix_is_identity (const CoglMatrix *matrix) { if (!(matrix->flags & MAT_DIRTY_TYPE) && @@ -2240,41 +2170,41 @@ cogl_matrix_look_at (CoglMatrix *matrix, float world_up_z) { CoglMatrix tmp; - float forward[3]; - float side[3]; - float up[3]; + graphene_vec3_t forward; + graphene_vec3_t side; + graphene_vec3_t up; /* Get a unit viewing direction vector */ - cogl_vector3_init (forward, - object_x - eye_position_x, - object_y - eye_position_y, - object_z - eye_position_z); - cogl_vector3_normalize (forward); + graphene_vec3_init (&forward, + object_x - eye_position_x, + object_y - eye_position_y, + object_z - eye_position_z); + graphene_vec3_normalize (&forward, &forward); - cogl_vector3_init (up, world_up_x, world_up_y, world_up_z); + graphene_vec3_init (&up, world_up_x, world_up_y, world_up_z); /* Take the sideways direction as being perpendicular to the viewing * direction and the word up vector. */ - cogl_vector3_cross_product (side, forward, up); - cogl_vector3_normalize (side); + graphene_vec3_cross (&forward, &up, &side); + graphene_vec3_normalize (&side, &side); /* Now we have unit sideways and forward-direction vectors calculate * a new mutually perpendicular up vector. */ - cogl_vector3_cross_product (up, side, forward); + graphene_vec3_cross (&side, &forward, &up); - tmp.xx = side[0]; - tmp.yx = side[1]; - tmp.zx = side[2]; + tmp.xx = graphene_vec3_get_x (&side); + tmp.yx = graphene_vec3_get_y (&side); + tmp.zx = graphene_vec3_get_z (&side); tmp.wx = 0; - tmp.xy = up[0]; - tmp.yy = up[1]; - tmp.zy = up[2]; + tmp.xy = graphene_vec3_get_x (&up); + tmp.yy = graphene_vec3_get_y (&up); + tmp.zy = graphene_vec3_get_z (&up); tmp.wy = 0; - tmp.xz = -forward[0]; - tmp.yz = -forward[1]; - tmp.zz = -forward[2]; + tmp.xz = -graphene_vec3_get_x (&forward); + tmp.yz = -graphene_vec3_get_y (&forward); + tmp.zz = -graphene_vec3_get_z (&forward); tmp.wz = 0; tmp.xw = 0; diff --git a/cogl/cogl/cogl-matrix.h b/cogl/cogl/cogl-matrix.h index 43adfd979..c14bb3565 100644 --- a/cogl/cogl/cogl-matrix.h +++ b/cogl/cogl/cogl-matrix.h @@ -41,10 +41,11 @@ #include #include -#include #include -COGL_BEGIN_DECLS +#include + +G_BEGIN_DECLS /** * SECTION:cogl-matrix @@ -134,7 +135,7 @@ COGL_STRUCT_SIZE_ASSERT (CoglMatrix, 128 + sizeof (unsigned long) * 3); * .wx=0; .wy=0; .wz=0; .ww=1; * ]| */ -void +COGL_EXPORT void cogl_matrix_init_identity (CoglMatrix *matrix); /** @@ -155,7 +156,7 @@ cogl_matrix_init_identity (CoglMatrix *matrix); * * Since: 2.0 */ -void +COGL_EXPORT void cogl_matrix_init_translation (CoglMatrix *matrix, float tx, float ty, @@ -173,7 +174,7 @@ cogl_matrix_init_translation (CoglMatrix *matrix, * It is possible to multiply the @a matrix in-place, so * @result can be equal to @a but can't be equal to @b. */ -void +COGL_EXPORT void cogl_matrix_multiply (CoglMatrix *result, const CoglMatrix *a, const CoglMatrix *b); @@ -189,40 +190,26 @@ cogl_matrix_multiply (CoglMatrix *result, * Multiplies @matrix with a rotation matrix that applies a rotation * of @angle degrees around the specified 3D vector. */ -void +COGL_EXPORT void cogl_matrix_rotate (CoglMatrix *matrix, float angle, float x, float y, float z); -/** - * cogl_matrix_rotate_quaternion: - * @matrix: A 4x4 transformation matrix - * @quaternion: A quaternion describing a rotation - * - * Multiplies @matrix with a rotation transformation described by the - * given #CoglQuaternion. - * - * Since: 2.0 - */ -void -cogl_matrix_rotate_quaternion (CoglMatrix *matrix, - const CoglQuaternion *quaternion); - /** * cogl_matrix_rotate_euler: * @matrix: A 4x4 transformation matrix * @euler: A euler describing a rotation * * Multiplies @matrix with a rotation transformation described by the - * given #CoglEuler. + * given #graphene_euler_t. * * Since: 2.0 */ -void +COGL_EXPORT void cogl_matrix_rotate_euler (CoglMatrix *matrix, - const CoglEuler *euler); + const graphene_euler_t *euler); /** * cogl_matrix_translate: @@ -234,7 +221,7 @@ cogl_matrix_rotate_euler (CoglMatrix *matrix, * Multiplies @matrix with a transform matrix that translates along * the X, Y and Z axis. */ -void +COGL_EXPORT void cogl_matrix_translate (CoglMatrix *matrix, float x, float y, @@ -250,7 +237,7 @@ cogl_matrix_translate (CoglMatrix *matrix, * Multiplies @matrix with a transform matrix that scales along the X, * Y and Z axis. */ -void +COGL_EXPORT void cogl_matrix_scale (CoglMatrix *matrix, float sx, float sy, @@ -299,7 +286,7 @@ cogl_matrix_scale (CoglMatrix *matrix, * Since: 1.8 * Stability: unstable */ -void +COGL_EXPORT void cogl_matrix_look_at (CoglMatrix *matrix, float eye_position_x, float eye_position_y, @@ -327,7 +314,7 @@ cogl_matrix_look_at (CoglMatrix *matrix, * * Multiplies @matrix by the given frustum perspective matrix. */ -void +COGL_EXPORT void cogl_matrix_frustum (CoglMatrix *matrix, float left, float right, @@ -352,7 +339,7 @@ cogl_matrix_frustum (CoglMatrix *matrix, * since there wont be enough precision to identify the depth of * objects near to each other. */ -void +COGL_EXPORT void cogl_matrix_perspective (CoglMatrix *matrix, float fov_y, float aspect, @@ -378,7 +365,7 @@ cogl_matrix_perspective (CoglMatrix *matrix, * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_matrix_orthographic (CoglMatrix *matrix, float x_1, float y_1, @@ -387,34 +374,6 @@ cogl_matrix_orthographic (CoglMatrix *matrix, float near, float far); -/** - * cogl_matrix_ortho: - * @matrix: A 4x4 transformation matrix - * @left: The coordinate for the left clipping plane - * @right: The coordinate for the right clipping plane - * @bottom: The coordinate for the bottom clipping plane - * @top: The coordinate for the top clipping plane - * @near: The distance to the near clipping - * plane (will be negative if the plane is - * behind the viewer) - * @far: The distance to the far clipping - * plane (will be negative if the plane is - * behind the viewer) - * - * Multiplies @matrix by a parallel projection matrix. - * - * Deprecated: 1.10: Use cogl_matrix_orthographic() - */ -COGL_DEPRECATED_IN_1_10_FOR (cogl_matrix_orthographic) -void -cogl_matrix_ortho (CoglMatrix *matrix, - float left, - float right, - float bottom, - float top, - float near, - float far); - /** * cogl_matrix_view_2d_in_frustum: * @matrix: A 4x4 transformation matrix @@ -445,7 +404,7 @@ cogl_matrix_ortho (CoglMatrix *matrix, * Since: 1.8 * Stability: unstable */ -void +COGL_EXPORT void cogl_matrix_view_2d_in_frustum (CoglMatrix *matrix, float left, float right, @@ -484,7 +443,7 @@ cogl_matrix_view_2d_in_frustum (CoglMatrix *matrix, * Since: 1.8 * Stability: unstable */ -void +COGL_EXPORT void cogl_matrix_view_2d_in_perspective (CoglMatrix *matrix, float fov_y, float aspect, @@ -500,7 +459,7 @@ cogl_matrix_view_2d_in_perspective (CoglMatrix *matrix, * * Initializes @matrix with the contents of @array */ -void +COGL_EXPORT void cogl_matrix_init_from_array (CoglMatrix *matrix, const float *array); @@ -512,30 +471,19 @@ cogl_matrix_init_from_array (CoglMatrix *matrix, * * Return value: a pointer to the float array */ -const float * +COGL_EXPORT const float * cogl_matrix_get_array (const CoglMatrix *matrix); -/** - * cogl_matrix_init_from_quaternion: - * @matrix: A 4x4 transformation matrix - * @quaternion: A #CoglQuaternion - * - * Initializes @matrix from a #CoglQuaternion rotation. - */ -void -cogl_matrix_init_from_quaternion (CoglMatrix *matrix, - const CoglQuaternion *quaternion); - /** * cogl_matrix_init_from_euler: * @matrix: A 4x4 transformation matrix - * @euler: A #CoglEuler + * @euler: A #graphene_euler_t * - * Initializes @matrix from a #CoglEuler rotation. + * Initializes @matrix from a #graphene_euler_t rotation. */ -void +COGL_EXPORT void cogl_matrix_init_from_euler (CoglMatrix *matrix, - const CoglEuler *euler); + const graphene_euler_t *euler); /** * cogl_matrix_equal: @@ -549,7 +497,7 @@ cogl_matrix_init_from_euler (CoglMatrix *matrix, * * Since: 1.4 */ -CoglBool +COGL_EXPORT gboolean cogl_matrix_equal (const void *v1, const void *v2); /** @@ -564,7 +512,7 @@ cogl_matrix_equal (const void *v1, const void *v2); * * Since: 1.6 */ -CoglMatrix * +COGL_EXPORT CoglMatrix * cogl_matrix_copy (const CoglMatrix *matrix); /** @@ -576,7 +524,7 @@ cogl_matrix_copy (const CoglMatrix *matrix); * * Since: 1.6 */ -void +COGL_EXPORT void cogl_matrix_free (CoglMatrix *matrix); /** @@ -599,7 +547,7 @@ cogl_matrix_free (CoglMatrix *matrix); * * Since: 1.2 */ -CoglBool +COGL_EXPORT gboolean cogl_matrix_get_inverse (const CoglMatrix *matrix, CoglMatrix *inverse); @@ -618,7 +566,7 @@ cogl_matrix_get_inverse (const CoglMatrix *matrix, * Transforms a point whos position is given and returned as four float * components. */ -void +COGL_EXPORT void cogl_matrix_transform_point (const CoglMatrix *matrix, float *x, float *y, @@ -674,7 +622,7 @@ cogl_matrix_transform_point (const CoglMatrix *matrix, * * Stability: unstable */ -void +COGL_EXPORT void cogl_matrix_transform_points (const CoglMatrix *matrix, int n_components, size_t stride_in, @@ -729,7 +677,7 @@ cogl_matrix_transform_points (const CoglMatrix *matrix, * * Stability: unstable */ -void +COGL_EXPORT void cogl_matrix_project_points (const CoglMatrix *matrix, int n_components, size_t stride_in, @@ -747,7 +695,7 @@ cogl_matrix_project_points (const CoglMatrix *matrix, * Returns: %TRUE if @matrix is an identity matrix else %FALSE * Since: 1.8 */ -CoglBool +COGL_EXPORT gboolean cogl_matrix_is_identity (const CoglMatrix *matrix); /** @@ -759,7 +707,7 @@ cogl_matrix_is_identity (const CoglMatrix *matrix); * * Since: 1.10 */ -void +COGL_EXPORT void cogl_matrix_transpose (CoglMatrix *matrix); /** @@ -770,7 +718,7 @@ cogl_matrix_transpose (CoglMatrix *matrix); * * Since: 2.0 */ -void +COGL_EXPORT void cogl_debug_matrix_print (const CoglMatrix *matrix); #define COGL_GTYPE_TYPE_MATRIX (cogl_matrix_get_gtype ()) @@ -780,6 +728,7 @@ cogl_debug_matrix_print (const CoglMatrix *matrix); * * Returns: a #GType that can be used with the GLib type system. */ +COGL_EXPORT GType cogl_matrix_get_gtype (void); /** @@ -791,9 +740,9 @@ GType cogl_matrix_get_gtype (void); * * Deprecated: 1.18: Use cogl_matrix_get_gtype() instead. */ -GType +COGL_EXPORT GType cogl_gtype_matrix_get_type (void); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_MATRIX_H */ diff --git a/cogl/cogl/cogl-memory-stack.c b/cogl/cogl/cogl-memory-stack.c index 12a26cb18..b44e3bac4 100644 --- a/cogl/cogl/cogl-memory-stack.c +++ b/cogl/cogl/cogl-memory-stack.c @@ -54,9 +54,7 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-memory-stack-private.h" #include "cogl-list.h" @@ -85,7 +83,7 @@ _cogl_memory_sub_stack_alloc (size_t bytes) { CoglMemorySubStack *sub_stack = g_slice_new (CoglMemorySubStack); sub_stack->bytes = bytes; - sub_stack->data = malloc (bytes); + sub_stack->data = g_malloc (bytes); return sub_stack; } @@ -176,7 +174,7 @@ _cogl_memory_stack_rewind (CoglMemoryStack *stack) static void _cogl_memory_sub_stack_free (CoglMemorySubStack *sub_stack) { - free (sub_stack->data); + g_free (sub_stack->data); g_slice_free (CoglMemorySubStack, sub_stack); } diff --git a/cogl/cogl/cogl-meta-texture.c b/cogl/cogl/cogl-meta-texture.c index ed1226924..adee5ce04 100644 --- a/cogl/cogl/cogl-meta-texture.c +++ b/cogl/cogl/cogl-meta-texture.c @@ -30,15 +30,13 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-texture.h" #include "cogl-matrix.h" #include "cogl-spans.h" #include "cogl-meta-texture.h" -#include "cogl-texture-rectangle-private.h" +#include "cogl-texture-private.h" #include #include @@ -229,8 +227,8 @@ typedef struct _ClampData { float start; float end; - CoglBool s_flipped; - CoglBool t_flipped; + gboolean s_flipped; + gboolean t_flipped; CoglMetaTextureCallback callback; void *user_data; } ClampData; @@ -279,7 +277,7 @@ clamp_t_cb (CoglTexture *sub_texture, clamp_data->user_data); } -static CoglBool +static gboolean foreach_clamped_region (CoglMetaTexture *meta_texture, float *tx_1, float *ty_1, @@ -318,16 +316,9 @@ foreach_clamped_region (CoglMetaTexture *meta_texture, if (wrap_s == COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE) { - float max_s_coord; + float max_s_coord = 1.0; float half_texel_width; - /* Consider that rectangle textures have non-normalized - * coordinates... */ - if (cogl_is_texture_rectangle (meta_texture)) - max_s_coord = width; - else - max_s_coord = 1.0; - half_texel_width = max_s_coord / (width * 2); /* Handle any left clamped region */ @@ -377,16 +368,9 @@ foreach_clamped_region (CoglMetaTexture *meta_texture, if (wrap_t == COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE) { float height = cogl_texture_get_height (COGL_TEXTURE (meta_texture)); - float max_t_coord; + float max_t_coord = 1.0; float half_texel_height; - /* Consider that rectangle textures have non-normalized - * coordinates... */ - if (cogl_is_texture_rectangle (meta_texture)) - max_t_coord = height; - else - max_t_coord = 1.0; - half_texel_height = max_t_coord / (height * 2); /* Handle any top clamped region */ @@ -468,33 +452,6 @@ normalize_meta_coords_cb (CoglTexture *slice_texture, data->user_data); } -typedef struct _UnNormalizeData -{ - CoglMetaTextureCallback callback; - void *user_data; - float width; - float height; -} UnNormalizeData; - -static void -un_normalize_slice_coords_cb (CoglTexture *slice_texture, - const float *slice_coords, - const float *meta_coords, - void *user_data) -{ - UnNormalizeData *data = user_data; - float un_normalized_slice_coords[4] = { - slice_coords[0] * data->width, - slice_coords[1] * data->height, - slice_coords[2] * data->width, - slice_coords[3] * data->height - }; - - data->callback (slice_texture, - un_normalized_slice_coords, meta_coords, - data->user_data); -} - void cogl_meta_texture_foreach_in_region (CoglMetaTexture *meta_texture, float tx_1, @@ -519,7 +476,7 @@ cogl_meta_texture_foreach_in_region (CoglMetaTexture *meta_texture, if (wrap_s == COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE || wrap_t == COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE) { - CoglBool finished = foreach_clamped_region (meta_texture, + gboolean finished = foreach_clamped_region (meta_texture, &tx_1, &ty_1, &tx_2, &ty_2, wrap_s, wrap_t, callback, @@ -541,19 +498,16 @@ cogl_meta_texture_foreach_in_region (CoglMetaTexture *meta_texture, * coordinates beyond this point and only re-normalize just before * calling the user's callback... */ - if (!cogl_is_texture_rectangle (COGL_TEXTURE (meta_texture))) - { - normalize_data.callback = callback; - normalize_data.user_data = user_data; - normalize_data.s_normalize_factor = 1.0f / width; - normalize_data.t_normalize_factor = 1.0f / height; - callback = normalize_meta_coords_cb; - user_data = &normalize_data; - tx_1 *= width; - ty_1 *= height; - tx_2 *= width; - ty_2 *= height; - } + normalize_data.callback = callback; + normalize_data.user_data = user_data; + normalize_data.s_normalize_factor = 1.0f / width; + normalize_data.t_normalize_factor = 1.0f / height; + callback = normalize_meta_coords_cb; + user_data = &normalize_data; + tx_1 *= width; + ty_1 *= height; + tx_2 *= width; + ty_2 *= height; /* XXX: at some point this wont be routed through the CoglTexture * vtable, instead there will be a separate CoglMetaTexture @@ -611,21 +565,6 @@ cogl_meta_texture_foreach_in_region (CoglMetaTexture *meta_texture, CoglSpan x_span = { 0, width, 0 }; CoglSpan y_span = { 0, height, 0 }; float meta_region_coords[4] = { tx_1, ty_1, tx_2, ty_2 }; - UnNormalizeData un_normalize_data; - - /* If we are dealing with a CoglTextureRectangle then we need a shim - * callback that un_normalizes the slice coordinates we get from - * _cogl_texture_spans_foreach_in_region before passing them to - * the user's callback. */ - if (cogl_is_texture_rectangle (meta_texture)) - { - un_normalize_data.callback = callback; - un_normalize_data.user_data = user_data; - un_normalize_data.width = width; - un_normalize_data.height = height; - callback = un_normalize_slice_coords_cb; - user_data = &un_normalize_data; - } _cogl_texture_spans_foreach_in_region (&x_span, 1, &y_span, 1, diff --git a/cogl/cogl/cogl-meta-texture.h b/cogl/cogl/cogl-meta-texture.h index 42c61702c..9f7784d7d 100644 --- a/cogl/cogl/cogl-meta-texture.h +++ b/cogl/cogl/cogl-meta-texture.h @@ -37,13 +37,12 @@ #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS /** * SECTION:cogl-meta-texture * @short_description: Interface for high-level textures built from - * low-level textures like #CoglTexture2D and - * #CoglTexture3D. + * low-level textures like #CoglTexture2D. * * Cogl helps to make it easy to deal with high level textures such * as #CoglAtlasTextures, #CoglSubTextures, @@ -52,12 +51,11 @@ COGL_BEGIN_DECLS * * A #CoglMetaTexture is a texture that might internally be * represented by one or more low-level #CoglTextures - * such as #CoglTexture2D or #CoglTexture3D. These low-level textures - * are the only ones that a GPU really understands but because - * applications often want more high-level texture abstractions - * (such as storing multiple textures inside one larger "atlas" - * texture) it's desirable to be able to deal with these - * using a common interface. + * such as #CoglTexture2D. These low-level textures are the only ones + * that a GPU really understands but because applications often want + * more high-level texture abstractions (such as storing multiple + * textures inside one larger "atlas" texture) it's desirable to be + * able to deal with these using a common interface. * * For example the GPU is not able to automatically handle repeating a * texture that is part of a larger atlas texture but if you use @@ -92,7 +90,7 @@ COGL_BEGIN_DECLS * meta-textures. */ -#if defined(__COGL_H_INSIDE__) && !defined(COGL_ENABLE_MUFFIN_API) && \ +#if defined(__COGL_H_INSIDE__) && !defined(COGL_ENABLE_MUTTER_API) && \ !defined(COGL_GIR_SCANNING) /* For the public C api we typedef interface types as void to avoid needing * lots of casting in code and instead we will rely on runtime type checking @@ -179,7 +177,7 @@ typedef void (*CoglMetaTextureCallback) (CoglTexture *sub_texture, * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_meta_texture_foreach_in_region (CoglMetaTexture *meta_texture, float tx_1, float ty_1, @@ -190,6 +188,6 @@ cogl_meta_texture_foreach_in_region (CoglMetaTexture *meta_texture, CoglMetaTextureCallback callback, void *user_data); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_META_TEXTURE_H__ */ diff --git a/cogl/cogl/cogl-muffin.h b/cogl/cogl/cogl-mutter.h similarity index 91% rename from cogl/cogl/cogl-muffin.h rename to cogl/cogl/cogl-mutter.h index baac164ea..2d48ce040 100644 --- a/cogl/cogl/cogl-muffin.h +++ b/cogl/cogl/cogl-mutter.h @@ -28,22 +28,24 @@ * */ -#ifndef __COGL_MUFFIN_H___ -#define __COGL_MUFFIN_H___ +#ifndef __COGL_MUTTER_H___ +#define __COGL_MUTTER_H___ -#include "cogl-muffin-config.h" +#include "cogl-config.h" #include "cogl-defines.h" #include #include -#include #include #include +#if defined (COGL_HAS_EGL_SUPPORT) #include +#endif #include +COGL_EXPORT void cogl_renderer_set_custom_winsys (CoglRenderer *renderer, CoglCustomWinsysVtableGetter winsys_vtable_getter, void *user_data); -#endif /* __COGL_MUFFIN_H___ */ +#endif /* __COGL_MUTTER_H___ */ diff --git a/cogl/cogl/cogl-node-private.h b/cogl/cogl/cogl-node-private.h index 8fe24775d..37981c4ab 100644 --- a/cogl/cogl/cogl-node-private.h +++ b/cogl/cogl/cogl-node-private.h @@ -60,7 +60,7 @@ struct _CoglNode /* TRUE if the node took a strong reference on its parent. Weak * pipelines for instance don't take a reference on their parent. */ - CoglBool has_parent_reference; + gboolean has_parent_reference; }; #define COGL_NODE(X) ((CoglNode *)(X)) @@ -74,12 +74,12 @@ void _cogl_pipeline_node_set_parent_real (CoglNode *node, CoglNode *parent, CoglNodeUnparentVFunc unparent, - CoglBool take_strong_reference); + gboolean take_strong_reference); void _cogl_pipeline_node_unparent_real (CoglNode *node); -typedef CoglBool (*CoglNodeChildCallback) (CoglNode *child, void *user_data); +typedef gboolean (*CoglNodeChildCallback) (CoglNode *child, void *user_data); void _cogl_pipeline_node_foreach_child (CoglNode *node, diff --git a/cogl/cogl/cogl-node.c b/cogl/cogl/cogl-node.c index dcec3cca7..07b524f94 100644 --- a/cogl/cogl/cogl-node.c +++ b/cogl/cogl/cogl-node.c @@ -31,9 +31,7 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-util.h" #include "cogl-node-private.h" @@ -49,7 +47,7 @@ void _cogl_pipeline_node_set_parent_real (CoglNode *node, CoglNode *parent, CoglNodeUnparentVFunc unparent, - CoglBool take_strong_reference) + gboolean take_strong_reference) { /* NB: the old parent may indirectly be keeping the new parent alive * so we have to ref the new parent before unrefing the old. @@ -86,7 +84,7 @@ _cogl_pipeline_node_unparent_real (CoglNode *node) if (parent == NULL) return; - _COGL_RETURN_IF_FAIL (!_cogl_list_empty (&parent->children)); + g_return_if_fail (!_cogl_list_empty (&parent->children)); _cogl_list_remove (&node->link); diff --git a/cogl/cogl/cogl-object-private.h b/cogl/cogl/cogl-object-private.h index c63e3231d..27c19e5d4 100644 --- a/cogl/cogl/cogl-object-private.h +++ b/cogl/cogl/cogl-object-private.h @@ -202,7 +202,7 @@ COGL_OBJECT_COMMON_DEFINE_WITH_CODE(TypeName, \ do { code; } while (0); \ _COGL_GTYPE_INIT_CLASS (type_name)) \ \ -CoglBool \ +gboolean \ cogl_is_##type_name (void *object) \ { \ CoglObject *obj = object; \ @@ -217,7 +217,7 @@ cogl_is_##type_name (void *object) \ \ COGL_OBJECT_COMMON_DEFINE_WITH_CODE(TypeName, type_name, code) \ \ -CoglBool \ +gboolean \ cogl_is_##type_name (void *object) \ { \ CoglObject *obj = object; \ @@ -232,7 +232,7 @@ cogl_is_##type_name (void *object) \ \ COGL_OBJECT_COMMON_DEFINE_WITH_CODE(TypeName, type_name, code) \ \ -CoglBool \ +gboolean \ _cogl_is_##type_name (void *object) \ { \ CoglObject *obj = object; \ @@ -243,37 +243,6 @@ _cogl_is_##type_name (void *object) \ return obj->klass == &_cogl_##type_name##_class; \ } -#define COGL_OBJECT_DEFINE_DEPRECATED_REF_COUNTING(type_name) \ - \ -void * G_GNUC_DEPRECATED \ -cogl_##type_name##_ref (void *object) \ -{ \ - if (!cogl_is_##type_name (object)) \ - return NULL; \ - \ - _COGL_OBJECT_DEBUG_REF (TypeName, object); \ - \ - cogl_handle_ref (object); \ - \ - return object; \ -} \ - \ -void G_GNUC_DEPRECATED \ -cogl_##type_name##_unref (void *object) \ -{ \ - if (!cogl_is_##type_name (object)) \ - { \ - g_warning (G_STRINGIFY (cogl_##type_name##_unref) \ - ": Ignoring unref of Cogl handle " \ - "due to type mismatch"); \ - return; \ - } \ - \ - _COGL_OBJECT_DEBUG_UNREF (TypeName, object); \ - \ - cogl_handle_unref (object); \ -} - #define COGL_OBJECT_DEFINE(TypeName, type_name) \ COGL_OBJECT_DEFINE_WITH_CODE_GTYPE (TypeName, type_name, (void) 0) @@ -310,7 +279,7 @@ _cogl_object_set_user_data (CoglObject *object, void *user_data, CoglUserDataDestroyInternalCallback destroy); -void +COGL_EXPORT void _cogl_object_default_unref (void *obj); #endif /* __COGL_OBJECT_PRIVATE_H */ diff --git a/cogl/cogl/cogl-object.c b/cogl/cogl/cogl-object.c index e159c6c3a..b96f19817 100644 --- a/cogl/cogl/cogl-object.c +++ b/cogl/cogl/cogl-object.c @@ -29,9 +29,7 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include #include @@ -48,25 +46,19 @@ cogl_object_ref (void *object) { CoglObject *obj = object; - _COGL_RETURN_VAL_IF_FAIL (object != NULL, NULL); + g_return_val_if_fail (object != NULL, NULL); obj->ref_count++; return object; } -CoglHandle -cogl_handle_ref (CoglHandle handle) -{ - return cogl_object_ref (handle); -} - void _cogl_object_default_unref (void *object) { CoglObject *obj = object; - _COGL_RETURN_IF_FAIL (object != NULL); - _COGL_RETURN_IF_FAIL (obj->ref_count > 0); + g_return_if_fail (object != NULL); + g_return_if_fail (obj->ref_count > 0); if (--obj->ref_count < 1) { @@ -111,18 +103,12 @@ cogl_object_unref (void *obj) { void (* unref_func) (void *); - _COGL_RETURN_IF_FAIL (obj != NULL); + g_return_if_fail (obj != NULL); unref_func = ((CoglObject *) obj)->klass->virt_unref; unref_func (obj); } -void -cogl_handle_unref (CoglHandle handle) -{ - cogl_object_unref (handle); -} - GType cogl_handle_get_type (void) { diff --git a/cogl/cogl/cogl-object.h b/cogl/cogl/cogl-object.h index 6093f2a5d..3d67eb080 100644 --- a/cogl/cogl/cogl-object.h +++ b/cogl/cogl/cogl-object.h @@ -35,7 +35,7 @@ #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS typedef struct _CoglObject CoglObject; @@ -52,6 +52,7 @@ typedef struct _CoglObject CoglObject; * * Returns: a #GType that can be used with the GLib type system. */ +COGL_EXPORT GType cogl_object_get_gtype (void); /** @@ -62,7 +63,7 @@ GType cogl_object_get_gtype (void); * * Returns: the @object, with its reference count increased */ -void * +COGL_EXPORT void * cogl_object_ref (void *object); /** @@ -72,9 +73,23 @@ cogl_object_ref (void *object); * Drecreases the reference count of @object by 1; if the reference * count reaches 0, the resources allocated by @object will be freed */ -void +COGL_EXPORT void cogl_object_unref (void *object); +/** + * cogl_clear_object: (skip) + * @object_ptr: a pointer to a #CoglObject reference + * + * Clears a reference to a #CoglObject. + * + * @object_ptr must not be %NULL. + * + * If the reference is %NULL then this function does nothing. + * Otherwise, the reference count of the object is decreased using + * cogl_object_unref() and the pointer is set to %NULL. + */ +#define cogl_clear_object(object_ptr) g_clear_pointer ((object_ptr), cogl_object_unref) + /** * CoglUserDataKey: * @unused: ignored. @@ -93,7 +108,7 @@ cogl_object_unref (void *object); * static void * destroy_path_private_cb (void *data) * { - * free (data); + * g_free (data); * } * * static void @@ -173,7 +188,7 @@ typedef void * * Since: 1.4 */ -void +COGL_EXPORT void cogl_object_set_user_data (CoglObject *object, CoglUserDataKey *key, void *user_data, @@ -195,7 +210,7 @@ cogl_object_set_user_data (CoglObject *object, * * Since: 1.4 */ -void * +COGL_EXPORT void * cogl_object_get_user_data (CoglObject *object, CoglUserDataKey *key); @@ -212,7 +227,7 @@ cogl_object_get_user_data (CoglObject *object, * Since: 1.8 * Stability: unstable */ -void +COGL_EXPORT void cogl_debug_object_foreach_type (CoglDebugObjectForeachTypeCallback func, void *user_data); @@ -227,10 +242,10 @@ cogl_debug_object_foreach_type (CoglDebugObjectForeachTypeCallback func, * Since: 1.8 * Stability: unstable */ -void +COGL_EXPORT void cogl_debug_object_print_instances (void); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_OBJECT_H */ diff --git a/cogl/cogl/cogl-offscreen.h b/cogl/cogl/cogl-offscreen.h index 5c26370af..07289db54 100644 --- a/cogl/cogl/cogl-offscreen.h +++ b/cogl/cogl/cogl-offscreen.h @@ -40,7 +40,7 @@ #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS /** * SECTION:cogl-offscreen @@ -59,6 +59,7 @@ typedef struct _CoglOffscreen CoglOffscreen; * * Returns: a #GType that can be used with the GLib type system. */ +COGL_EXPORT GType cogl_offscreen_get_gtype (void); /* Offscreen api */ @@ -75,8 +76,8 @@ GType cogl_offscreen_get_gtype (void); * destroy the offscreen buffer before you can use the @texture again. * * This api only works with low-level #CoglTexture types such as - * #CoglTexture2D, #CoglTexture3D and #CoglTextureRectangle, and not - * with meta-texture types such as #CoglTexture2DSliced. + * #CoglTexture2D and not with meta-texture types such as + * #CoglTexture2DSliced. * * The storage for the framebuffer is actually allocated lazily * so this function will never return %NULL to indicate a runtime @@ -90,12 +91,12 @@ GType cogl_offscreen_get_gtype (void); * message. If you need to be able to catch such exceptions at runtime * then you can explicitly allocate your framebuffer when you have * finished configuring it by calling cogl_framebuffer_allocate() and - * passing in a #CoglError argument to catch any exceptions. + * passing in a #GError argument to catch any exceptions. * * Return value: (transfer full): a newly instantiated #CoglOffscreen * framebuffer. */ -CoglOffscreen * +COGL_EXPORT CoglOffscreen * cogl_offscreen_new_with_texture (CoglTexture *texture); /** @@ -110,16 +111,16 @@ cogl_offscreen_new_with_texture (CoglTexture *texture); * you can use the @texture again. * * This only works with low-level #CoglTexture types such as - * #CoglTexture2D, #CoglTexture3D and #CoglTextureRectangle, and not - * with meta-texture types such as #CoglTexture2DSliced. + * #CoglTexture2D and not with meta-texture types such as + * #CoglTexture2DSliced. * * Return value: (transfer full): a newly instantiated #CoglOffscreen * framebuffer or %NULL if it wasn't possible to create the * buffer. * Deprecated: 1.16: Use cogl_offscreen_new_with_texture instead. */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_offscreen_new_with_texture) -CoglOffscreen * +COGL_DEPRECATED_FOR (cogl_offscreen_new_with_texture) +COGL_EXPORT CoglOffscreen * cogl_offscreen_new_to_texture (CoglTexture *texture); /** @@ -132,43 +133,15 @@ cogl_offscreen_new_to_texture (CoglTexture *texture); * Returns: %TRUE if @object is a #CoglOffscreen framebuffer, * %FALSE otherwise */ -CoglBool +COGL_EXPORT gboolean cogl_is_offscreen (void *object); -/** - * cogl_offscreen_ref: - * @offscreen: A pointer to a #CoglOffscreen framebuffer - * - * Increments the reference count on the @offscreen framebuffer. - * - * Return value: (transfer none): For convenience it returns the - * given @offscreen - * - * Deprecated: 1.2: cogl_object_ref() should be used in new code. - */ -COGL_DEPRECATED_FOR (cogl_object_ref) -void * -cogl_offscreen_ref (void *offscreen); - -/** - * cogl_offscreen_unref: - * @offscreen: A pointer to a #CoglOffscreen framebuffer - * - * Decreases the reference count for the @offscreen buffer and frees it when - * the count reaches 0. - * - * Deprecated: 1.2: cogl_object_unref() should be used in new code. - */ -COGL_DEPRECATED_FOR (cogl_object_unref) -void -cogl_offscreen_unref (void *offscreen); - /** * cogl_offscreen_get_texture: (skip) */ -CoglTexture * +COGL_EXPORT CoglTexture * cogl_offscreen_get_texture (CoglOffscreen *offscreen); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_OFFSCREEN_H__ */ diff --git a/cogl/cogl/cogl-onscreen-private.h b/cogl/cogl/cogl-onscreen-private.h index 0a67832ac..480ca5076 100644 --- a/cogl/cogl/cogl-onscreen-private.h +++ b/cogl/cogl/cogl-onscreen-private.h @@ -59,17 +59,9 @@ struct _CoglOnscreen { CoglFramebuffer _parent; -#ifdef COGL_HAS_X11_SUPPORT - uint32_t foreign_xid; - CoglOnscreenX11MaskCallback foreign_update_mask_callback; - void *foreign_update_mask_data; -#endif - - CoglBool swap_throttled; - CoglList frame_closures; - CoglBool resizable; + gboolean resizable; CoglList resize_closures; CoglList dirty_closures; @@ -86,7 +78,7 @@ struct _CoglOnscreen CoglOnscreen * _cogl_onscreen_new (void); -void +COGL_EXPORT void _cogl_framebuffer_winsys_update_size (CoglFramebuffer *framebuffer, int width, int height); @@ -95,10 +87,10 @@ _cogl_onscreen_queue_event (CoglOnscreen *onscreen, CoglFrameEvent type, CoglFrameInfo *info); -void +COGL_EXPORT void _cogl_onscreen_notify_frame_sync (CoglOnscreen *onscreen, CoglFrameInfo *info); -void +COGL_EXPORT void _cogl_onscreen_notify_complete (CoglOnscreen *onscreen, CoglFrameInfo *info); void diff --git a/cogl/cogl/cogl-onscreen-template.c b/cogl/cogl/cogl-onscreen-template.c index 1adbf4128..244470739 100644 --- a/cogl/cogl/cogl-onscreen-template.c +++ b/cogl/cogl/cogl-onscreen-template.c @@ -29,9 +29,7 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-object.h" @@ -64,7 +62,6 @@ cogl_onscreen_template_new (CoglSwapChain *swap_chain) else onscreen_template->config.swap_chain = cogl_swap_chain_new (); - onscreen_template->config.swap_throttled = TRUE; onscreen_template->config.need_stencil = TRUE; onscreen_template->config.samples_per_pixel = 0; @@ -88,18 +85,10 @@ cogl_onscreen_template_set_samples_per_pixel ( onscreen_template->config.samples_per_pixel = samples_per_pixel; } -void -cogl_onscreen_template_set_swap_throttled ( - CoglOnscreenTemplate *onscreen_template, - CoglBool throttled) -{ - onscreen_template->config.swap_throttled = throttled; -} - void cogl_onscreen_template_set_stereo_enabled ( CoglOnscreenTemplate *onscreen_template, - CoglBool enabled) + gboolean enabled) { onscreen_template->config.stereo_enabled = enabled; } diff --git a/cogl/cogl/cogl-onscreen-template.h b/cogl/cogl/cogl-onscreen-template.h index 2dd737bef..9881e1c48 100644 --- a/cogl/cogl/cogl-onscreen-template.h +++ b/cogl/cogl/cogl-onscreen-template.h @@ -41,7 +41,7 @@ #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS typedef struct _CoglOnscreenTemplate CoglOnscreenTemplate; @@ -52,9 +52,10 @@ typedef struct _CoglOnscreenTemplate CoglOnscreenTemplate; * * Returns: a #GType that can be used with the GLib type system. */ +COGL_EXPORT GType cogl_onscreen_template_get_gtype (void); -CoglOnscreenTemplate * +COGL_EXPORT CoglOnscreenTemplate * cogl_onscreen_template_new (CoglSwapChain *swap_chain); /** @@ -80,28 +81,11 @@ cogl_onscreen_template_new (CoglSwapChain *swap_chain); * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_onscreen_template_set_samples_per_pixel ( CoglOnscreenTemplate *onscreen_template, int n); -/** - * cogl_onscreen_template_set_swap_throttled: - * @onscreen_template: A #CoglOnscreenTemplate template framebuffer - * @throttled: Whether throttling should be enabled - * - * Requests that any future #CoglOnscreen framebuffers derived from this - * template should enable or disable swap throttling according to the given - * @throttled argument. - * - * Since: 1.10 - * Stability: unstable - */ -void -cogl_onscreen_template_set_swap_throttled ( - CoglOnscreenTemplate *onscreen_template, - CoglBool throttled); - /** * cogl_onscreen_template_set_stereo_enabled: * @onscreen_template: A #CoglOnscreenTemplate template framebuffer @@ -116,10 +100,10 @@ cogl_onscreen_template_set_swap_throttled ( * Since: 1.20 * Stability: unstable */ -void +COGL_EXPORT void cogl_onscreen_template_set_stereo_enabled ( CoglOnscreenTemplate *onscreen_template, - CoglBool enabled); + gboolean enabled); /** * cogl_is_onscreen_template: * @object: A #CoglObject pointer @@ -131,9 +115,9 @@ cogl_onscreen_template_set_stereo_enabled ( * Since: 1.10 * Stability: unstable */ -CoglBool +COGL_EXPORT gboolean cogl_is_onscreen_template (void *object); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_ONSCREEN_TEMPLATE_H__ */ diff --git a/cogl/cogl/cogl-onscreen.c b/cogl/cogl/cogl-onscreen.c index c656474c6..704e1c44b 100644 --- a/cogl/cogl/cogl-onscreen.c +++ b/cogl/cogl/cogl-onscreen.c @@ -28,9 +28,7 @@ * */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-util.h" #include "cogl-onscreen-private.h" @@ -44,10 +42,6 @@ #include "cogl-poll-private.h" #include "cogl-gtype-private.h" -#ifdef COGL_HAS_X11_SUPPORT -#include "cogl-xlib-renderer.h" -#endif - static void _cogl_onscreen_free (CoglOnscreen *onscreen); COGL_OBJECT_DEFINE_WITH_CODE_GTYPE (Onscreen, onscreen, @@ -99,10 +93,12 @@ _cogl_onscreen_init_from_template (CoglOnscreen *onscreen, CoglOnscreen * _cogl_onscreen_new (void) { - CoglOnscreen *onscreen = g_new0 (CoglOnscreen, 1); + g_autofree CoglOnscreen *onscreen_ptr = g_new0 (CoglOnscreen, 1); + CoglOnscreen *onscreen; _COGL_GET_CONTEXT (ctx, NULL); + onscreen = g_steal_pointer (&onscreen_ptr); _cogl_framebuffer_init (COGL_FRAMEBUFFER (onscreen), ctx, COGL_FRAMEBUFFER_TYPE_ONSCREEN, @@ -163,16 +159,13 @@ _cogl_onscreen_free (CoglOnscreen *onscreen) cogl_object_unref (frame_info); g_queue_clear (&onscreen->pending_frame_infos); - if (framebuffer->context->window_buffer == COGL_FRAMEBUFFER (onscreen)) - framebuffer->context->window_buffer = NULL; - winsys->onscreen_deinit (onscreen); - _COGL_RETURN_IF_FAIL (onscreen->winsys == NULL); + g_return_if_fail (onscreen->winsys == NULL); /* Chain up to parent */ _cogl_framebuffer_free (framebuffer); - free (onscreen); + g_free (onscreen); } static void @@ -306,7 +299,7 @@ cogl_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen, const CoglWinsysVtable *winsys; CoglFrameInfo *info; - _COGL_RETURN_IF_FAIL (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN); + g_return_if_fail (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN); info = _cogl_frame_info_new (); info->frame_counter = onscreen->frame_counter; @@ -338,7 +331,6 @@ cogl_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen, } onscreen->frame_counter++; - framebuffer->mid_scene = FALSE; } void @@ -356,7 +348,7 @@ cogl_onscreen_swap_region (CoglOnscreen *onscreen, const CoglWinsysVtable *winsys; CoglFrameInfo *info; - _COGL_RETURN_IF_FAIL (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN); + g_return_if_fail (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN); info = _cogl_frame_info_new (); info->frame_counter = onscreen->frame_counter; @@ -369,7 +361,7 @@ cogl_onscreen_swap_region (CoglOnscreen *onscreen, /* This should only be called if the winsys advertises COGL_WINSYS_FEATURE_SWAP_REGION */ - _COGL_RETURN_IF_FAIL (winsys->onscreen_swap_region != NULL); + g_return_if_fail (winsys->onscreen_swap_region != NULL); winsys->onscreen_swap_region (COGL_ONSCREEN (framebuffer), rectangles, @@ -395,7 +387,6 @@ cogl_onscreen_swap_region (CoglOnscreen *onscreen, } onscreen->frame_counter++; - framebuffer->mid_scene = FALSE; } int @@ -404,7 +395,7 @@ cogl_onscreen_get_buffer_age (CoglOnscreen *onscreen) CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); const CoglWinsysVtable *winsys; - _COGL_RETURN_VAL_IF_FAIL (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN, 0); + g_return_val_if_fail (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN, 0); winsys = _cogl_framebuffer_get_winsys (framebuffer); @@ -415,54 +406,16 @@ cogl_onscreen_get_buffer_age (CoglOnscreen *onscreen) } #ifdef COGL_HAS_X11_SUPPORT -void -cogl_x11_onscreen_set_foreign_window_xid (CoglOnscreen *onscreen, - uint32_t xid, - CoglOnscreenX11MaskCallback update, - void *user_data) -{ - /* We don't wan't applications to get away with being lazy here and not - * passing an update callback... */ - _COGL_RETURN_IF_FAIL (update); - - onscreen->foreign_xid = xid; - onscreen->foreign_update_mask_callback = update; - onscreen->foreign_update_mask_data = user_data; -} - uint32_t cogl_x11_onscreen_get_window_xid (CoglOnscreen *onscreen) { CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); + const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer); - if (onscreen->foreign_xid) - return onscreen->foreign_xid; - else - { - const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer); - - /* This should only be called for x11 onscreens */ - _COGL_RETURN_VAL_IF_FAIL (winsys->onscreen_x11_get_window_xid != NULL, 0); - - return winsys->onscreen_x11_get_window_xid (onscreen); - } -} - -uint32_t -cogl_x11_onscreen_get_visual_xid (CoglOnscreen *onscreen) -{ - CoglContext *ctx = COGL_FRAMEBUFFER (onscreen)->context; - XVisualInfo *visinfo; - uint32_t id; - - /* This should only be called for xlib based onscreens */ - visinfo = cogl_xlib_renderer_get_visual_info (ctx->display->renderer); - if (visinfo == NULL) - return 0; - - id = (uint32_t)visinfo->visualid; + /* This should only be called for x11 onscreens */ + g_return_val_if_fail (winsys->onscreen_x11_get_window_xid != NULL, 0); - return id; + return winsys->onscreen_x11_get_window_xid (onscreen); } #endif /* COGL_HAS_X11_SUPPORT */ @@ -482,97 +435,11 @@ void cogl_onscreen_remove_frame_callback (CoglOnscreen *onscreen, CoglFrameClosure *closure) { - _COGL_RETURN_IF_FAIL (closure); + g_return_if_fail (closure); _cogl_closure_disconnect (closure); } -typedef struct _SwapBufferCallbackState -{ - CoglSwapBuffersNotify callback; - void *user_data; -} SwapBufferCallbackState; - -static void -destroy_swap_buffers_callback_state (void *user_data) -{ - g_slice_free (SwapBufferCallbackState, user_data); -} - -static void -shim_swap_buffers_callback (CoglOnscreen *onscreen, - CoglFrameEvent event, - CoglFrameInfo *info, - void *user_data) -{ - SwapBufferCallbackState *state = user_data; - - /* XXX: Note that technically it is a change in semantics for this - * interface to forward _SYNC events here and also makes the api - * name somewhat missleading. - * - * In practice though this interface is currently used by - * applications for throttling, not because they are strictly - * interested in knowing when a frame has been presented and so - * forwarding _SYNC events should serve them better. - */ - if (event == COGL_FRAME_EVENT_SYNC) - state->callback (COGL_FRAMEBUFFER (onscreen), state->user_data); -} - -unsigned int -cogl_onscreen_add_swap_buffers_callback (CoglOnscreen *onscreen, - CoglSwapBuffersNotify callback, - void *user_data) -{ - CoglContext *ctx = COGL_FRAMEBUFFER (onscreen)->context; - SwapBufferCallbackState *state = g_slice_new (SwapBufferCallbackState); - CoglFrameClosure *closure; - unsigned int id = ctx->next_swap_callback_id++; - - state->callback = callback; - state->user_data = user_data; - - closure = - cogl_onscreen_add_frame_callback (onscreen, - shim_swap_buffers_callback, - state, - destroy_swap_buffers_callback_state); - - g_hash_table_insert (ctx->swap_callback_closures, - GINT_TO_POINTER (id), - closure); - - return id; -} - -void -cogl_onscreen_remove_swap_buffers_callback (CoglOnscreen *onscreen, - unsigned int id) -{ - CoglContext *ctx = COGL_FRAMEBUFFER (onscreen)->context; - CoglFrameClosure *closure = g_hash_table_lookup (ctx->swap_callback_closures, - GINT_TO_POINTER (id)); - - _COGL_RETURN_IF_FAIL (closure); - - cogl_onscreen_remove_frame_callback (onscreen, closure); -} - -void -cogl_onscreen_set_swap_throttled (CoglOnscreen *onscreen, - CoglBool throttled) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - framebuffer->config.swap_throttled = throttled; - if (framebuffer->allocated) - { - const CoglWinsysVtable *winsys = - _cogl_framebuffer_get_winsys (framebuffer); - winsys->onscreen_update_swap_throttled (onscreen); - } -} - void cogl_onscreen_show (CoglOnscreen *onscreen) { @@ -647,7 +514,7 @@ _cogl_framebuffer_winsys_update_size (CoglFramebuffer *framebuffer, void cogl_onscreen_set_resizable (CoglOnscreen *onscreen, - CoglBool resizable) + gboolean resizable) { CoglFramebuffer *framebuffer; const CoglWinsysVtable *winsys; @@ -667,7 +534,7 @@ cogl_onscreen_set_resizable (CoglOnscreen *onscreen, } } -CoglBool +gboolean cogl_onscreen_get_resizable (CoglOnscreen *onscreen) { return onscreen->resizable; @@ -708,7 +575,7 @@ void cogl_onscreen_remove_dirty_callback (CoglOnscreen *onscreen, CoglOnscreenDirtyClosure *closure) { - _COGL_RETURN_IF_FAIL (closure); + g_return_if_fail (closure); _cogl_closure_disconnect (closure); } diff --git a/cogl/cogl/cogl-onscreen.h b/cogl/cogl/cogl-onscreen.h index bf36bfb51..40bd6780b 100644 --- a/cogl/cogl/cogl-onscreen.h +++ b/cogl/cogl/cogl-onscreen.h @@ -45,7 +45,7 @@ #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS typedef struct _CoglOnscreen CoglOnscreen; #define COGL_ONSCREEN(X) ((CoglOnscreen *)(X)) @@ -55,10 +55,11 @@ typedef struct _CoglOnscreen CoglOnscreen; * * Returns: a #GType that can be used with the GLib type system. */ +COGL_EXPORT GType cogl_onscreen_get_gtype (void); /** - * cogl_onscreen_new: (constructor) + * cogl_onscreen_new: (constructor) (skip) * @context: A #CoglContext * @width: The desired framebuffer width * @height: The desired framebuffer height @@ -71,71 +72,10 @@ GType cogl_onscreen_get_gtype (void); * Since: 1.8 * Stability: unstable */ -CoglOnscreen * +COGL_EXPORT CoglOnscreen * cogl_onscreen_new (CoglContext *context, int width, int height); #ifdef COGL_HAS_X11 -typedef void (*CoglOnscreenX11MaskCallback) (CoglOnscreen *onscreen, - uint32_t event_mask, - void *user_data); - -/** - * cogl_x11_onscreen_set_foreign_window_xid: - * @onscreen: The unallocated framebuffer to associated with an X - * window. - * @xid: The XID of an existing X window - * @update: A callback that notifies of updates to what Cogl requires - * to be in the core X protocol event mask. - * @user_data: user data passed to @update - * - * Ideally we would recommend that you let Cogl be responsible for - * creating any X window required to back an onscreen framebuffer but - * if you really need to target a window created manually this - * function can be called before @onscreen has been allocated to set a - * foreign XID for your existing X window. - * - * Since Cogl needs, for example, to track changes to the size of an X - * window it requires that certain events be selected for via the core - * X protocol. This requirement may also be changed asynchronously so - * you must pass in an @update callback to inform you of Cogl's - * required event mask. - * - * For example if you are using Xlib you could use this API roughly - * as follows: - * [{ - * static void - * my_update_cogl_x11_event_mask (CoglOnscreen *onscreen, - * uint32_t event_mask, - * void *user_data) - * { - * XSetWindowAttributes attrs; - * MyData *data = user_data; - * attrs.event_mask = event_mask | data->my_event_mask; - * XChangeWindowAttributes (data->xdpy, - * data->xwin, - * CWEventMask, - * &attrs); - * } - * - * { - * *snip* - * cogl_x11_onscreen_set_foreign_window_xid (onscreen, - * data->xwin, - * my_update_cogl_x11_event_mask, - * data); - * *snip* - * } - * }] - * - * Since: 2.0 - * Stability: Unstable - */ -void -cogl_x11_onscreen_set_foreign_window_xid (CoglOnscreen *onscreen, - uint32_t xid, - CoglOnscreenX11MaskCallback update, - void *user_data); - /** * cogl_x11_onscreen_get_window_xid: * @onscreen: A #CoglOnscreen framebuffer @@ -153,32 +93,11 @@ cogl_x11_onscreen_set_foreign_window_xid (CoglOnscreen *onscreen, * Since: 1.10 * Stability: unstable */ -uint32_t +COGL_EXPORT uint32_t cogl_x11_onscreen_get_window_xid (CoglOnscreen *onscreen); -/* XXX: we should maybe remove this, since nothing currently uses - * it and the current implementation looks dubious. */ -uint32_t -cogl_x11_onscreen_get_visual_xid (CoglOnscreen *onscreen); #endif /* COGL_HAS_X11 */ -/** - * cogl_onscreen_set_swap_throttled: - * @onscreen: A #CoglOnscreen framebuffer - * @throttled: Whether swap throttling is wanted or not. - * - * Requests that the given @onscreen framebuffer should have swap buffer - * requests (made using cogl_onscreen_swap_buffers()) throttled either by a - * displays vblank period or perhaps some other mechanism in a composited - * environment. - * - * Since: 1.8 - * Stability: unstable - */ -void -cogl_onscreen_set_swap_throttled (CoglOnscreen *onscreen, - CoglBool throttled); - /** * cogl_onscreen_show: * @onscreen: The onscreen framebuffer to make visible @@ -207,7 +126,7 @@ cogl_onscreen_set_swap_throttled (CoglOnscreen *onscreen, * Since: 2.0 * Stability: Unstable */ -void +COGL_EXPORT void cogl_onscreen_show (CoglOnscreen *onscreen); /** @@ -232,7 +151,7 @@ cogl_onscreen_show (CoglOnscreen *onscreen); * Since: 2.0 * Stability: Unstable */ -void +COGL_EXPORT void cogl_onscreen_hide (CoglOnscreen *onscreen); /** @@ -256,7 +175,7 @@ cogl_onscreen_hide (CoglOnscreen *onscreen); * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_onscreen_swap_buffers (CoglOnscreen *onscreen); @@ -309,7 +228,7 @@ cogl_onscreen_swap_buffers (CoglOnscreen *onscreen); * Since: 1.14 * Stability: stable */ -int +COGL_EXPORT int cogl_onscreen_get_buffer_age (CoglOnscreen *onscreen); /** @@ -360,7 +279,7 @@ cogl_onscreen_get_buffer_age (CoglOnscreen *onscreen); * Since: 1.16 * Stability: unstable */ -void +COGL_EXPORT void cogl_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen, const int *rectangles, int n_rectangles); @@ -385,7 +304,7 @@ cogl_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen, * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_onscreen_swap_region (CoglOnscreen *onscreen, const int *rectangles, int n_rectangles); @@ -470,6 +389,7 @@ typedef struct _CoglClosure CoglFrameClosure; * * Returns: a #GType that can be used with the GLib type system. */ +COGL_EXPORT GType cogl_frame_closure_get_gtype (void); /** @@ -509,7 +429,7 @@ GType cogl_frame_closure_get_gtype (void); * Since: 1.14 * Stability: unstable */ -CoglFrameClosure * +COGL_EXPORT CoglFrameClosure * cogl_onscreen_add_frame_callback (CoglOnscreen *onscreen, CoglFrameCallback callback, void *user_data, @@ -531,63 +451,10 @@ cogl_onscreen_add_frame_callback (CoglOnscreen *onscreen, * Since: 1.14 * Stability: unstable */ -void +COGL_EXPORT void cogl_onscreen_remove_frame_callback (CoglOnscreen *onscreen, CoglFrameClosure *closure); -typedef void (*CoglSwapBuffersNotify) (CoglFramebuffer *framebuffer, - void *user_data); - -/** - * cogl_onscreen_add_swap_buffers_callback: - * @onscreen: A #CoglOnscreen framebuffer - * @callback: (scope notified): A callback function to call when a swap - * has completed - * @user_data: (closure): A private pointer to be passed to @callback - * - * Installs a @callback function that should be called whenever a swap buffers - * request (made using cogl_onscreen_swap_buffers()) for the given - * @onscreen completes. - * - * Applications should check for the %COGL_FEATURE_ID_SWAP_BUFFERS_EVENT - * feature before using this API. It's currently undefined when and if - * registered callbacks will be called if this feature is not supported. - * - * We recommend using this mechanism when available to manually throttle your - * applications (in conjunction with cogl_onscreen_set_swap_throttled()) so - * your application will be able to avoid long blocks in the driver caused by - * throttling when you request to swap buffers too quickly. - * - * Return value: a unique identifier that can be used to remove to remove - * the callback later. - * Since: 1.10 - * Stability: unstable - * Deprecated: 1.14: Use cogl_onscreen_add_frame_callback() instead - */ -COGL_DEPRECATED_IN_1_14_FOR (cogl_onscreen_add_frame_callback) -unsigned int -cogl_onscreen_add_swap_buffers_callback (CoglOnscreen *onscreen, - CoglSwapBuffersNotify callback, - void *user_data); - -/** - * cogl_onscreen_remove_swap_buffers_callback: - * @onscreen: A #CoglOnscreen framebuffer - * @id: An identifier returned from cogl_onscreen_add_swap_buffers_callback() - * - * Removes a callback that was previously registered - * using cogl_onscreen_add_swap_buffers_callback(). - * - * Since: 1.10 - * Stability: unstable - * Deprecated: 1.14: Use cogl_onscreen_remove_frame_callback() instead - */ - -COGL_DEPRECATED_IN_1_14_FOR (cogl_onscreen_remove_frame_callback) -void -cogl_onscreen_remove_swap_buffers_callback (CoglOnscreen *onscreen, - unsigned int id); - /** * cogl_onscreen_set_resizable: * @onscreen: A #CoglOnscreen framebuffer @@ -617,9 +484,9 @@ cogl_onscreen_remove_swap_buffers_callback (CoglOnscreen *onscreen, * * Since: 2.0 */ -void +COGL_EXPORT void cogl_onscreen_set_resizable (CoglOnscreen *onscreen, - CoglBool resizable); + gboolean resizable); /** * cogl_onscreen_get_resizable: @@ -644,7 +511,7 @@ cogl_onscreen_set_resizable (CoglOnscreen *onscreen, * resizable or not. * Since: 2.0 */ -CoglBool +COGL_EXPORT gboolean cogl_onscreen_get_resizable (CoglOnscreen *onscreen); /** @@ -695,6 +562,7 @@ typedef struct _CoglClosure CoglOnscreenResizeClosure; * * Returns: a #GType that can be used with the GLib type system. */ +COGL_EXPORT GType cogl_onscreen_resize_closure_get_gtype (void); /** @@ -729,7 +597,7 @@ GType cogl_onscreen_resize_closure_get_gtype (void); * remove the callback and associated @user_data later. * Since: 2.0 */ -CoglOnscreenResizeClosure * +COGL_EXPORT CoglOnscreenResizeClosure * cogl_onscreen_add_resize_callback (CoglOnscreen *onscreen, CoglOnscreenResizeCallback callback, void *user_data, @@ -745,7 +613,7 @@ cogl_onscreen_add_resize_callback (CoglOnscreen *onscreen, * * Since: 2.0 */ -void +COGL_EXPORT void cogl_onscreen_remove_resize_callback (CoglOnscreen *onscreen, CoglOnscreenResizeClosure *closure); @@ -809,6 +677,7 @@ typedef struct _CoglClosure CoglOnscreenDirtyClosure; * * Returns: a #GType that can be used with the GLib type system. */ +COGL_EXPORT GType cogl_onscreen_dirty_closure_get_gtype (void); /** @@ -841,7 +710,7 @@ GType cogl_onscreen_dirty_closure_get_gtype (void); * Since: 1.16 * Stability: unstable */ -CoglOnscreenDirtyClosure * +COGL_EXPORT CoglOnscreenDirtyClosure * cogl_onscreen_add_dirty_callback (CoglOnscreen *onscreen, CoglOnscreenDirtyCallback callback, void *user_data, @@ -863,7 +732,7 @@ cogl_onscreen_add_dirty_callback (CoglOnscreen *onscreen, * Since: 1.16 * Stability: unstable */ -void +COGL_EXPORT void cogl_onscreen_remove_dirty_callback (CoglOnscreen *onscreen, CoglOnscreenDirtyClosure *closure); @@ -878,7 +747,7 @@ cogl_onscreen_remove_dirty_callback (CoglOnscreen *onscreen, * Since: 1.10 * Stability: unstable */ -CoglBool +COGL_EXPORT gboolean cogl_is_onscreen (void *object); /** @@ -893,9 +762,9 @@ cogl_is_onscreen (void *object); * Since: 1.14 * Stability: unstable */ -int64_t +COGL_EXPORT int64_t cogl_onscreen_get_frame_counter (CoglOnscreen *onscreen); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_ONSCREEN_H */ diff --git a/cogl/cogl/cogl-output-private.h b/cogl/cogl/cogl-output-private.h index d264d482b..4f8b60ed5 100644 --- a/cogl/cogl/cogl-output-private.h +++ b/cogl/cogl/cogl-output-private.h @@ -51,7 +51,7 @@ struct _CoglOutput }; CoglOutput *_cogl_output_new (const char *name); -CoglBool _cogl_output_values_equal (CoglOutput *output, +gboolean _cogl_output_values_equal (CoglOutput *output, CoglOutput *other); #endif /* __COGL_OUTPUT_PRIVATE_H */ diff --git a/cogl/cogl/cogl-output.c b/cogl/cogl/cogl-output.c index 89ac8d72e..e2c005076 100644 --- a/cogl/cogl/cogl-output.c +++ b/cogl/cogl/cogl-output.c @@ -28,9 +28,7 @@ * */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-output-private.h" #include "cogl-gtype-private.h" @@ -56,7 +54,7 @@ _cogl_output_new (const char *name) static void _cogl_output_free (CoglOutput *output) { - free (output->name); + g_free (output->name); g_slice_free (CoglOutput, output); } diff --git a/cogl/cogl/cogl-output.h b/cogl/cogl/cogl-output.h index 15df92c33..6ea135cff 100644 --- a/cogl/cogl/cogl-output.h +++ b/cogl/cogl/cogl-output.h @@ -41,7 +41,7 @@ #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS /** * SECTION:cogl-output @@ -73,6 +73,7 @@ typedef struct _CoglOutput CoglOutput; * * Returns: a #GType that can be used with the GLib type system. */ +COGL_EXPORT GType cogl_output_get_gtype (void); /** @@ -106,7 +107,8 @@ GType cogl_output_get_gtype (void); * Since: 1.14 * Stability: unstable */ -typedef enum { +typedef enum +{ COGL_SUBPIXEL_ORDER_UNKNOWN, COGL_SUBPIXEL_ORDER_NONE, COGL_SUBPIXEL_ORDER_HORIZONTAL_RGB, @@ -126,7 +128,7 @@ typedef enum { * Since: 1.14 * Stability: unstable */ -CoglBool +COGL_EXPORT gboolean cogl_is_output (void *object); /** @@ -141,7 +143,7 @@ cogl_is_output (void *object); * Since: 1.14 * Stability: unstable */ -int +COGL_EXPORT int cogl_output_get_x (CoglOutput *output); /** @@ -156,7 +158,7 @@ cogl_output_get_x (CoglOutput *output); * Since: 1.14 * Stability: unstable */ -int +COGL_EXPORT int cogl_output_get_y (CoglOutput *output); /** @@ -169,7 +171,7 @@ cogl_output_get_y (CoglOutput *output); * Since: 1.14 * Stability: unstable */ -int +COGL_EXPORT int cogl_output_get_width (CoglOutput *output); /** @@ -182,7 +184,7 @@ cogl_output_get_width (CoglOutput *output); * Since: 1.14 * Stability: unstable */ -int +COGL_EXPORT int cogl_output_get_height (CoglOutput *output); /** @@ -199,7 +201,7 @@ cogl_output_get_height (CoglOutput *output); * Since: 1.14 * Stability: unstable */ -int +COGL_EXPORT int cogl_output_get_mm_width (CoglOutput *output); /** @@ -216,7 +218,7 @@ cogl_output_get_mm_width (CoglOutput *output); * Since: 1.14 * Stability: unstable */ -int +COGL_EXPORT int cogl_output_get_mm_height (CoglOutput *output); /** @@ -231,7 +233,7 @@ cogl_output_get_mm_height (CoglOutput *output); * Since: 1.14 * Stability: unstable */ -CoglSubpixelOrder +COGL_EXPORT CoglSubpixelOrder cogl_output_get_subpixel_order (CoglOutput *output); /** @@ -246,10 +248,10 @@ cogl_output_get_subpixel_order (CoglOutput *output); * Since: 1.14 * Stability: unstable */ -float +COGL_EXPORT float cogl_output_get_refresh_rate (CoglOutput *output); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_OUTPUT_H */ diff --git a/cogl/cogl/cogl-pango.h b/cogl/cogl/cogl-pango.h deleted file mode 100644 index 8082c5657..000000000 --- a/cogl/cogl/cogl-pango.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ -#ifndef __COGL_PANGO_H_COMPAT__ -#define __COGL_PANGO_H_COMPAT__ - -#warning "#include is deprecated; please #include " -#include - -#endif /* __COGL_PANGO_H_COMPAT__ */ diff --git a/cogl/cogl/cogl-pipeline-cache.c b/cogl/cogl/cogl-pipeline-cache.c index 5c6929a5c..6bfc37732 100644 --- a/cogl/cogl/cogl-pipeline-cache.c +++ b/cogl/cogl/cogl-pipeline-cache.c @@ -31,9 +31,7 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include @@ -52,7 +50,7 @@ struct _CoglPipelineCache CoglPipelineCache * _cogl_pipeline_cache_new (void) { - CoglPipelineCache *cache = g_new (CoglPipelineCache, 1); + g_autofree CoglPipelineCache *cache = g_new (CoglPipelineCache, 1); unsigned long vertex_state; unsigned long layer_vertex_state; unsigned int fragment_state; @@ -82,7 +80,7 @@ _cogl_pipeline_cache_new (void) layer_vertex_state | layer_fragment_state, "programs"); - return cache; + return g_steal_pointer (&cache); } void @@ -91,7 +89,7 @@ _cogl_pipeline_cache_free (CoglPipelineCache *cache) _cogl_pipeline_hash_table_destroy (&cache->fragment_hash); _cogl_pipeline_hash_table_destroy (&cache->vertex_hash); _cogl_pipeline_hash_table_destroy (&cache->combined_hash); - free (cache); + g_free (cache); } CoglPipelineCacheEntry * @@ -136,7 +134,7 @@ create_pipelines (CoglPipeline **pipelines, NULL, /* declarations */ source); - free (source); + g_free (source); pipelines[i] = cogl_pipeline_new (test_ctx); cogl_pipeline_add_snippet (pipelines[i], snippet); diff --git a/cogl/cogl/cogl-pipeline-debug.c b/cogl/cogl/cogl-pipeline-debug.c index 0e4f6cd42..7555257d0 100644 --- a/cogl/cogl/cogl-pipeline-debug.c +++ b/cogl/cogl/cogl-pipeline-debug.c @@ -31,9 +31,7 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-context-private.h" #include "cogl-pipeline-private.h" @@ -50,7 +48,7 @@ typedef struct int indent; } PrintDebugState; -static CoglBool +static gboolean dump_layer_cb (CoglNode *node, void *user_data) { CoglPipelineLayer *layer = COGL_PIPELINE_LAYER (node); @@ -58,7 +56,7 @@ dump_layer_cb (CoglNode *node, void *user_data) int layer_id = *state->node_id_ptr; PrintDebugState state_out; GString *changes_label; - CoglBool changes = FALSE; + gboolean changes = FALSE; if (state->parent_id >= 0) g_string_append_printf (state->graph, "%*slayer%p -> layer%p;\n", @@ -123,7 +121,7 @@ dump_layer_cb (CoglNode *node, void *user_data) return TRUE; } -static CoglBool +static gboolean dump_layer_ref_cb (CoglPipelineLayer *layer, void *data) { PrintDebugState *state = data; @@ -138,7 +136,7 @@ dump_layer_ref_cb (CoglPipelineLayer *layer, void *data) return TRUE; } -static CoglBool +static gboolean dump_pipeline_cb (CoglNode *node, void *user_data) { CoglPipeline *pipeline = COGL_PIPELINE (node); @@ -146,8 +144,8 @@ dump_pipeline_cb (CoglNode *node, void *user_data) int pipeline_id = *state->node_id_ptr; PrintDebugState state_out; GString *changes_label; - CoglBool changes = FALSE; - CoglBool layers = FALSE; + gboolean changes = FALSE; + gboolean layers = FALSE; if (state->parent_id >= 0) g_string_append_printf (state->graph, "%*spipeline%d -> pipeline%d;\n", @@ -195,27 +193,9 @@ dump_pipeline_cb (CoglNode *node, void *user_data) if (pipeline->differences & COGL_PIPELINE_STATE_BLEND) { - const char *blend_enable_name; - changes = TRUE; - - switch (pipeline->blend_enable) - { - case COGL_PIPELINE_BLEND_ENABLE_AUTOMATIC: - blend_enable_name = "AUTO"; - break; - case COGL_PIPELINE_BLEND_ENABLE_ENABLED: - blend_enable_name = "ENABLED"; - break; - case COGL_PIPELINE_BLEND_ENABLE_DISABLED: - blend_enable_name = "DISABLED"; - break; - default: - blend_enable_name = "UNKNOWN"; - } g_string_append_printf (changes_label, - "\\lblend=%s\\n", - blend_enable_name); + "\\lblend\\n"); } if (pipeline->differences & COGL_PIPELINE_STATE_LAYERS) diff --git a/cogl/cogl/cogl-pipeline-hash-table.c b/cogl/cogl/cogl-pipeline-hash-table.c index 8f961b030..1e4bc1784 100644 --- a/cogl/cogl/cogl-pipeline-hash-table.c +++ b/cogl/cogl/cogl-pipeline-hash-table.c @@ -31,9 +31,7 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-context-private.h" #include "cogl-pipeline-private.h" @@ -79,7 +77,7 @@ entry_hash (const void *data) return entry->hash_value; } -static CoglBool +static gboolean entry_equal (const void *a, const void *b) { diff --git a/cogl/cogl/cogl-pipeline-layer-private.h b/cogl/cogl/cogl-pipeline-layer-private.h index 38cd3b5eb..901489d2b 100644 --- a/cogl/cogl/cogl-pipeline-layer-private.h +++ b/cogl/cogl/cogl-pipeline-layer-private.h @@ -55,7 +55,6 @@ typedef enum { /* sparse state */ COGL_PIPELINE_LAYER_STATE_UNIT_INDEX, - COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE_INDEX, COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX, COGL_PIPELINE_LAYER_STATE_SAMPLER_INDEX, COGL_PIPELINE_LAYER_STATE_COMBINE_INDEX, @@ -82,8 +81,6 @@ typedef enum { COGL_PIPELINE_LAYER_STATE_UNIT = 1L< */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-context-private.h" #include "cogl-pipeline-private.h" @@ -43,7 +41,6 @@ #include "cogl-snippet-private.h" #include "cogl-texture-private.h" #include "cogl-pipeline-layer-state-private.h" -#include "cogl-error-private.h" #include "string.h" #if 0 @@ -138,87 +135,6 @@ cogl_pipeline_get_layer_texture (CoglPipeline *pipeline, return _cogl_pipeline_layer_get_texture (layer); } -CoglTextureType -_cogl_pipeline_layer_get_texture_type (CoglPipelineLayer *layer) -{ - CoglPipelineLayer *authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE); - - return authority->texture_type; -} - -static void -_cogl_pipeline_set_layer_texture_type (CoglPipeline *pipeline, - int layer_index, - CoglTextureType texture_type) -{ - CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE; - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - CoglPipelineLayer *new; - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, change); - - if (texture_type == authority->texture_type) - return; - - new = _cogl_pipeline_layer_pre_change_notify (pipeline, layer, change); - if (new != layer) - layer = new; - else - { - /* If the original layer we found is currently the authority on - * the state we are changing see if we can revert to one of our - * ancestors being the authority. */ - if (layer == authority && - _cogl_pipeline_layer_get_parent (authority) != NULL) - { - CoglPipelineLayer *parent = - _cogl_pipeline_layer_get_parent (authority); - CoglPipelineLayer *old_authority = - _cogl_pipeline_layer_get_authority (parent, change); - - if (old_authority->texture_type == texture_type) - { - layer->differences &= ~change; - - g_assert (layer->owner == pipeline); - if (layer->differences == 0) - _cogl_pipeline_prune_empty_layer_difference (pipeline, - layer); - goto changed; - } - } - } - - layer->texture_type = texture_type; - - /* If we weren't previously the authority on this state then we need - * to extended our differences mask and so it's possible that some - * of our ancestry will now become redundant, so we aim to reparent - * ourselves if that's true... */ - if (layer != authority) - { - layer->differences |= change; - _cogl_pipeline_layer_prune_redundant_ancestry (layer); - } - -changed: - - pipeline->dirty_real_blend_enable = TRUE; -} - static void _cogl_pipeline_set_layer_texture_data (CoglPipeline *pipeline, int layer_index, @@ -303,69 +219,13 @@ cogl_pipeline_set_layer_texture (CoglPipeline *pipeline, int layer_index, CoglTexture *texture) { - /* For the convenience of fragend code we separate texture state - * into the "type" and the "data", and setting a layer texture - * updates both of these properties. - * - * One example for why this is helpful is that the fragends may - * cache programs they generate and want to re-use those programs - * with all pipelines having equivalent fragment processing state. - * For the sake of determining if pipelines have equivalent fragment - * processing state we don't need to compare that the same - * underlying texture objects are referenced by the pipelines but we - * do need to see if they use the same texture types. Making this - * distinction is much simpler if they are in different state - * groups. - * - * Note: if a NULL texture is set then we leave the type unchanged - * so we can avoid needlessly invalidating any associated fragment - * program. - */ - if (texture) - { - CoglTextureType texture_type = - _cogl_texture_get_type (texture); - _cogl_pipeline_set_layer_texture_type (pipeline, - layer_index, - texture_type); - } _cogl_pipeline_set_layer_texture_data (pipeline, layer_index, texture); } void cogl_pipeline_set_layer_null_texture (CoglPipeline *pipeline, - int layer_index, - CoglTextureType texture_type) + int layer_index) { - CoglContext *ctx = _cogl_context_get_default (); - - /* Disallow setting texture types that aren't supported */ - switch (texture_type) - { - case COGL_TEXTURE_TYPE_2D: - break; - - case COGL_TEXTURE_TYPE_3D: - if (ctx->default_gl_texture_3d_tex == NULL) - { - g_warning ("The default 3D texture was set on a pipeline but " - "3D textures are not supported"); - texture_type = COGL_TEXTURE_TYPE_2D; - return; - } - break; - - case COGL_TEXTURE_TYPE_RECTANGLE: - if (ctx->default_gl_texture_rect_tex == NULL) - { - g_warning ("The default rectangle texture was set on a pipeline but " - "rectangle textures are not supported"); - texture_type = COGL_TEXTURE_TYPE_2D; - } - break; - } - - _cogl_pipeline_set_layer_texture_type (pipeline, layer_index, texture_type); _cogl_pipeline_set_layer_texture_data (pipeline, layer_index, NULL); } @@ -432,7 +292,7 @@ public_to_internal_wrap_mode (CoglPipelineWrapMode mode) static CoglPipelineWrapMode internal_to_public_wrap_mode (CoglSamplerCacheWrapMode internal_mode) { - _COGL_RETURN_VAL_IF_FAIL (internal_mode != + g_return_val_if_fail (internal_mode != COGL_SAMPLER_CACHE_WRAP_MODE_CLAMP_TO_BORDER, COGL_PIPELINE_WRAP_MODE_AUTOMATIC); return (CoglPipelineWrapMode)internal_mode; @@ -452,7 +312,7 @@ cogl_pipeline_set_layer_wrap_mode_s (CoglPipeline *pipeline, _COGL_GET_CONTEXT (ctx, NO_RETVAL); - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); + g_return_if_fail (cogl_is_pipeline (pipeline)); /* Note: this will ensure that the layer exists, creating one if it * doesn't already. @@ -471,9 +331,7 @@ cogl_pipeline_set_layer_wrap_mode_s (CoglPipeline *pipeline, authority->sampler_cache_entry, internal_mode, authority->sampler_cache_entry-> - wrap_mode_t, - authority->sampler_cache_entry-> - wrap_mode_p); + wrap_mode_t); _cogl_pipeline_set_layer_sampler_state (pipeline, layer, authority, @@ -494,7 +352,7 @@ cogl_pipeline_set_layer_wrap_mode_t (CoglPipeline *pipeline, _COGL_GET_CONTEXT (ctx, NO_RETVAL); - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); + g_return_if_fail (cogl_is_pipeline (pipeline)); /* Note: this will ensure that the layer exists, creating one if it * doesn't already. @@ -513,62 +371,6 @@ cogl_pipeline_set_layer_wrap_mode_t (CoglPipeline *pipeline, authority->sampler_cache_entry, authority->sampler_cache_entry-> wrap_mode_s, - internal_mode, - authority->sampler_cache_entry-> - wrap_mode_p); - _cogl_pipeline_set_layer_sampler_state (pipeline, - layer, - authority, - sampler_state); -} - -/* The rationale for naming the third texture coordinate 'p' instead - of OpenGL's usual 'r' is that 'r' conflicts with the usual naming - of the 'red' component when treating a vector as a color. Under - GLSL this is awkward because the texture swizzling for a vector - uses a single letter for each component and the names for colors, - textures and positions are synonymous. GLSL works around this by - naming the components of the texture s, t, p and q. Cogl already - effectively already exposes this naming because it exposes GLSL so - it makes sense to use that naming consistently. Another alternative - could be u, v and w. This is what Blender and Direct3D use. However - the w component conflicts with the w component of a position - vertex. */ -void -cogl_pipeline_set_layer_wrap_mode_p (CoglPipeline *pipeline, - int layer_index, - CoglPipelineWrapMode mode) -{ - CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_SAMPLER; - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - CoglSamplerCacheWrapMode internal_mode = - public_to_internal_wrap_mode (mode); - const CoglSamplerCacheEntry *sampler_state; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, change); - - sampler_state = - _cogl_sampler_cache_update_wrap_modes (ctx->sampler_cache, - authority->sampler_cache_entry, - authority->sampler_cache_entry-> - wrap_mode_s, - authority->sampler_cache_entry-> - wrap_mode_t, internal_mode); _cogl_pipeline_set_layer_sampler_state (pipeline, layer, @@ -590,7 +392,7 @@ cogl_pipeline_set_layer_wrap_mode (CoglPipeline *pipeline, _COGL_GET_CONTEXT (ctx, NO_RETVAL); - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); + g_return_if_fail (cogl_is_pipeline (pipeline)); /* Note: this will ensure that the layer exists, creating one if it * doesn't already. @@ -608,14 +410,11 @@ cogl_pipeline_set_layer_wrap_mode (CoglPipeline *pipeline, _cogl_sampler_cache_update_wrap_modes (ctx->sampler_cache, authority->sampler_cache_entry, internal_mode, - internal_mode, internal_mode); _cogl_pipeline_set_layer_sampler_state (pipeline, layer, authority, sampler_state); - /* XXX: I wonder if we should really be duplicating the mode into - * the 'p' wrap mode too? */ } /* FIXME: deprecate this API */ @@ -626,7 +425,7 @@ _cogl_pipeline_layer_get_wrap_mode_s (CoglPipelineLayer *layer) CoglPipelineLayer *authority; const CoglSamplerCacheEntry *sampler_state; - _COGL_RETURN_VAL_IF_FAIL (_cogl_is_pipeline_layer (layer), FALSE); + g_return_val_if_fail (_cogl_is_pipeline_layer (layer), FALSE); /* Now find the ancestor of the layer that is the authority for the * state we want to change */ @@ -641,7 +440,7 @@ cogl_pipeline_get_layer_wrap_mode_s (CoglPipeline *pipeline, int layer_index) { CoglPipelineLayer *layer; - _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), FALSE); + g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); /* Note: this will ensure that the layer exists, creating one if it * doesn't already. @@ -663,7 +462,7 @@ _cogl_pipeline_layer_get_wrap_mode_t (CoglPipelineLayer *layer) CoglPipelineLayer *authority; const CoglSamplerCacheEntry *sampler_state; - _COGL_RETURN_VAL_IF_FAIL (_cogl_is_pipeline_layer (layer), FALSE); + g_return_val_if_fail (_cogl_is_pipeline_layer (layer), FALSE); /* Now find the ancestor of the layer that is the authority for the * state we want to change */ @@ -678,7 +477,7 @@ cogl_pipeline_get_layer_wrap_mode_t (CoglPipeline *pipeline, int layer_index) { CoglPipelineLayer *layer; - _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), FALSE); + g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); /* Note: this will ensure that the layer exists, creating one if it * doesn't already. @@ -692,41 +491,10 @@ cogl_pipeline_get_layer_wrap_mode_t (CoglPipeline *pipeline, int layer_index) return _cogl_pipeline_layer_get_wrap_mode_t (layer); } -CoglPipelineWrapMode -_cogl_pipeline_layer_get_wrap_mode_p (CoglPipelineLayer *layer) -{ - CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_SAMPLER; - CoglPipelineLayer *authority = - _cogl_pipeline_layer_get_authority (layer, change); - const CoglSamplerCacheEntry *sampler_state; - - sampler_state = authority->sampler_cache_entry; - return internal_to_public_wrap_mode (sampler_state->wrap_mode_p); -} - -CoglPipelineWrapMode -cogl_pipeline_get_layer_wrap_mode_p (CoglPipeline *pipeline, int layer_index) -{ - CoglPipelineLayer *layer; - - _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), FALSE); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - return _cogl_pipeline_layer_get_wrap_mode_p (layer); -} - void _cogl_pipeline_layer_get_wrap_modes (CoglPipelineLayer *layer, CoglSamplerCacheWrapMode *wrap_mode_s, - CoglSamplerCacheWrapMode *wrap_mode_t, - CoglSamplerCacheWrapMode *wrap_mode_p) + CoglSamplerCacheWrapMode *wrap_mode_t) { CoglPipelineLayer *authority = _cogl_pipeline_layer_get_authority (layer, @@ -734,14 +502,13 @@ _cogl_pipeline_layer_get_wrap_modes (CoglPipelineLayer *layer, *wrap_mode_s = authority->sampler_cache_entry->wrap_mode_s; *wrap_mode_t = authority->sampler_cache_entry->wrap_mode_t; - *wrap_mode_p = authority->sampler_cache_entry->wrap_mode_p; } -CoglBool +gboolean cogl_pipeline_set_layer_point_sprite_coords_enabled (CoglPipeline *pipeline, int layer_index, - CoglBool enable, - CoglError **error) + gboolean enable, + GError **error) { CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS; @@ -751,31 +518,7 @@ cogl_pipeline_set_layer_point_sprite_coords_enabled (CoglPipeline *pipeline, _COGL_GET_CONTEXT (ctx, FALSE); - _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), FALSE); - - /* Don't allow point sprite coordinates to be enabled if the driver - doesn't support it */ - if (enable && !cogl_has_feature (ctx, COGL_FEATURE_ID_POINT_SPRITE)) - { - if (error) - { - _cogl_set_error (error, - COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_UNSUPPORTED, - "Point sprite texture coordinates are enabled for " - "a layer but the GL driver does not support it."); - } - else - { - static CoglBool warning_seen = FALSE; - if (!warning_seen) - g_warning ("Point sprite texture coordinates are enabled " - "for a layer but the GL driver does not support it."); - warning_seen = TRUE; - } - - return FALSE; - } + g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); /* Note: this will ensure that the layer exists, creating one if it * doesn't already. @@ -836,7 +579,7 @@ cogl_pipeline_set_layer_point_sprite_coords_enabled (CoglPipeline *pipeline, return TRUE; } -CoglBool +gboolean cogl_pipeline_get_layer_point_sprite_coords_enabled (CoglPipeline *pipeline, int layer_index) { @@ -845,7 +588,7 @@ cogl_pipeline_get_layer_point_sprite_coords_enabled (CoglPipeline *pipeline, CoglPipelineLayer *layer; CoglPipelineLayer *authority; - _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), FALSE); + g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); /* Note: this will ensure that the layer exists, creating one if it * doesn't already. @@ -938,9 +681,9 @@ cogl_pipeline_add_layer_snippet (CoglPipeline *pipeline, int layer_index, CoglSnippet *snippet) { - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); - _COGL_RETURN_IF_FAIL (cogl_is_snippet (snippet)); - _COGL_RETURN_IF_FAIL (snippet->hook >= COGL_SNIPPET_FIRST_LAYER_HOOK); + g_return_if_fail (cogl_is_pipeline (pipeline)); + g_return_if_fail (cogl_is_snippet (snippet)); + g_return_if_fail (snippet->hook >= COGL_SNIPPET_FIRST_LAYER_HOOK); if (snippet->hook < COGL_SNIPPET_FIRST_LAYER_FRAGMENT_HOOK) _cogl_pipeline_layer_add_vertex_snippet (pipeline, @@ -952,15 +695,7 @@ cogl_pipeline_add_layer_snippet (CoglPipeline *pipeline, snippet); } -CoglBool -_cogl_pipeline_layer_texture_type_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1, - CoglPipelineEvalFlags flags) -{ - return authority0->texture_type == authority1->texture_type; -} - -CoglBool +gboolean _cogl_pipeline_layer_texture_data_equal (CoglPipelineLayer *authority0, CoglPipelineLayer *authority1, CoglPipelineEvalFlags flags) @@ -968,8 +703,7 @@ _cogl_pipeline_layer_texture_data_equal (CoglPipelineLayer *authority0, if (authority0->texture == NULL) { if (authority1->texture == NULL) - return (_cogl_pipeline_layer_get_texture_type (authority0) == - _cogl_pipeline_layer_get_texture_type (authority1)); + return TRUE; else return FALSE; } @@ -986,7 +720,7 @@ _cogl_pipeline_layer_texture_data_equal (CoglPipelineLayer *authority0, } } -CoglBool +gboolean _cogl_pipeline_layer_combine_state_equal (CoglPipelineLayer *authority0, CoglPipelineLayer *authority1) { @@ -1028,7 +762,7 @@ _cogl_pipeline_layer_combine_state_equal (CoglPipelineLayer *authority0, return TRUE; } -CoglBool +gboolean _cogl_pipeline_layer_combine_constant_equal (CoglPipelineLayer *authority0, CoglPipelineLayer *authority1) { @@ -1037,7 +771,7 @@ _cogl_pipeline_layer_combine_constant_equal (CoglPipelineLayer *authority0, sizeof (float) * 4) == 0 ? TRUE : FALSE; } -CoglBool +gboolean _cogl_pipeline_layer_sampler_equal (CoglPipelineLayer *authority0, CoglPipelineLayer *authority1) { @@ -1048,7 +782,7 @@ _cogl_pipeline_layer_sampler_equal (CoglPipelineLayer *authority0, authority1->sampler_cache_entry->sampler_object); } -CoglBool +gboolean _cogl_pipeline_layer_user_matrix_equal (CoglPipelineLayer *authority0, CoglPipelineLayer *authority1) { @@ -1061,7 +795,7 @@ _cogl_pipeline_layer_user_matrix_equal (CoglPipelineLayer *authority0, return TRUE; } -CoglBool +gboolean _cogl_pipeline_layer_point_sprite_coords_equal (CoglPipelineLayer *authority0, CoglPipelineLayer *authority1) { @@ -1071,7 +805,7 @@ _cogl_pipeline_layer_point_sprite_coords_equal (CoglPipelineLayer *authority0, return big_state0->point_sprite_coords == big_state1->point_sprite_coords; } -CoglBool +gboolean _cogl_pipeline_layer_vertex_snippets_equal (CoglPipelineLayer *authority0, CoglPipelineLayer *authority1) { @@ -1081,7 +815,7 @@ _cogl_pipeline_layer_vertex_snippets_equal (CoglPipelineLayer *authority0, vertex_snippets); } -CoglBool +gboolean _cogl_pipeline_layer_fragment_snippets_equal (CoglPipelineLayer *authority0, CoglPipelineLayer *authority1) { @@ -1173,11 +907,11 @@ setup_texture_combine_state (CoglBlendStringStatement *statement, } } -CoglBool +gboolean cogl_pipeline_set_layer_combine (CoglPipeline *pipeline, int layer_index, const char *combine_description, - CoglError **error) + GError **error) { CoglPipelineLayerState state = COGL_PIPELINE_LAYER_STATE_COMBINE; CoglPipelineLayer *authority; @@ -1188,7 +922,7 @@ cogl_pipeline_set_layer_combine (CoglPipeline *pipeline, CoglBlendStringStatement *a; int count; - _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), FALSE); + g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); /* Note: this will ensure that the layer exists, creating one if it * doesn't already. @@ -1288,7 +1022,7 @@ cogl_pipeline_set_layer_combine_constant (CoglPipeline *pipeline, CoglPipelineLayer *new; float color_as_floats[4]; - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); + g_return_if_fail (cogl_is_pipeline (pipeline)); /* Note: this will ensure that the layer exists, creating one if it * doesn't already. @@ -1371,7 +1105,7 @@ _cogl_pipeline_get_layer_combine_constant (CoglPipeline *pipeline, CoglPipelineLayer *layer; CoglPipelineLayer *authority; - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); + g_return_if_fail (cogl_is_pipeline (pipeline)); /* Note: this will ensure that the layer exists, creating one if it * doesn't already. @@ -1398,7 +1132,7 @@ _cogl_pipeline_get_layer_matrix (CoglPipeline *pipeline, int layer_index) CoglPipelineLayer *layer; CoglPipelineLayer *authority; - _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), NULL); + g_return_val_if_fail (cogl_is_pipeline (pipeline), NULL); layer = _cogl_pipeline_get_layer (pipeline, layer_index); @@ -1416,7 +1150,7 @@ cogl_pipeline_set_layer_matrix (CoglPipeline *pipeline, CoglPipelineLayer *authority; CoglPipelineLayer *new; - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); + g_return_if_fail (cogl_is_pipeline (pipeline)); /* Note: this will ensure that the layer exists, creating one if it * doesn't already. @@ -1478,12 +1212,12 @@ cogl_pipeline_set_layer_matrix (CoglPipeline *pipeline, CoglTexture * _cogl_pipeline_layer_get_texture (CoglPipelineLayer *layer) { - _COGL_RETURN_VAL_IF_FAIL (_cogl_is_pipeline_layer (layer), NULL); + g_return_val_if_fail (_cogl_is_pipeline_layer (layer), NULL); return _cogl_pipeline_layer_get_texture_real (layer); } -CoglBool +gboolean _cogl_pipeline_layer_has_user_matrix (CoglPipeline *pipeline, int layer_index) { @@ -1522,7 +1256,7 @@ _cogl_pipeline_get_layer_filters (CoglPipeline *pipeline, CoglPipelineLayer *layer; CoglPipelineLayer *authority; - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); + g_return_if_fail (cogl_is_pipeline (pipeline)); layer = _cogl_pipeline_get_layer (pipeline, layer_index); @@ -1563,7 +1297,7 @@ _cogl_pipeline_layer_get_min_filter (CoglPipelineLayer *layer) { CoglPipelineLayer *authority; - _COGL_RETURN_VAL_IF_FAIL (_cogl_is_pipeline_layer (layer), 0); + g_return_val_if_fail (_cogl_is_pipeline_layer (layer), 0); authority = _cogl_pipeline_layer_get_authority (layer, @@ -1577,7 +1311,7 @@ _cogl_pipeline_layer_get_mag_filter (CoglPipelineLayer *layer) { CoglPipelineLayer *authority; - _COGL_RETURN_VAL_IF_FAIL (_cogl_is_pipeline_layer (layer), 0); + g_return_val_if_fail (_cogl_is_pipeline_layer (layer), 0); authority = _cogl_pipeline_layer_get_authority (layer, @@ -1599,10 +1333,10 @@ cogl_pipeline_set_layer_filters (CoglPipeline *pipeline, _COGL_GET_CONTEXT (ctx, NO_RETVAL); - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); + g_return_if_fail (cogl_is_pipeline (pipeline)); - _COGL_RETURN_IF_FAIL (mag_filter == COGL_PIPELINE_FILTER_NEAREST || - mag_filter == COGL_PIPELINE_FILTER_LINEAR); + g_return_if_fail (mag_filter == COGL_PIPELINE_FILTER_NEAREST || + mag_filter == COGL_PIPELINE_FILTER_LINEAR); /* Note: this will ensure that the layer exists, creating one if it * doesn't already. @@ -1627,6 +1361,17 @@ cogl_pipeline_set_layer_filters (CoglPipeline *pipeline, sampler_state); } +void +cogl_pipeline_set_layer_max_mipmap_level (CoglPipeline *pipeline, + int layer, + int max_level) +{ + CoglTexture *texture = cogl_pipeline_get_layer_texture (pipeline, layer); + + if (texture != NULL) + cogl_texture_set_max_level (texture, max_level); +} + const CoglSamplerCacheEntry * _cogl_pipeline_layer_get_sampler_state (CoglPipelineLayer *layer) { @@ -1649,18 +1394,6 @@ _cogl_pipeline_layer_hash_unit_state (CoglPipelineLayer *authority, _cogl_util_one_at_a_time_hash (state->hash, &unit, sizeof (unit)); } -void -_cogl_pipeline_layer_hash_texture_type_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state) -{ - CoglTextureType texture_type = authority->texture_type; - - state->hash = _cogl_util_one_at_a_time_hash (state->hash, - &texture_type, - sizeof (texture_type)); -} - void _cogl_pipeline_layer_hash_texture_data_state (CoglPipelineLayer *authority, CoglPipelineLayer **authorities, @@ -1730,7 +1463,7 @@ _cogl_pipeline_layer_hash_combine_constant_state (CoglPipelineLayer *authority, CoglPipelineHashState *state) { CoglPipelineLayerBigState *b = authority->big_state; - CoglBool need_hash = FALSE; + gboolean need_hash = FALSE; int n_args; int i; diff --git a/cogl/cogl/cogl-pipeline-layer-state.h b/cogl/cogl/cogl-pipeline-layer-state.h index 96ae1b405..947b37b14 100644 --- a/cogl/cogl/cogl-pipeline-layer-state.h +++ b/cogl/cogl/cogl-pipeline-layer-state.h @@ -40,7 +40,7 @@ #include #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS /** * CoglPipelineFilter: @@ -69,7 +69,8 @@ COGL_BEGIN_DECLS * possibly referring to multiple neighbouring texels and taking a weighted * average or simply using the nearest texel. */ -typedef enum { +typedef enum +{ COGL_PIPELINE_FILTER_NEAREST = 0x2600, COGL_PIPELINE_FILTER_LINEAR = 0x2601, COGL_PIPELINE_FILTER_NEAREST_MIPMAP_NEAREST = 0x2700, @@ -113,7 +114,8 @@ typedef enum { * XXX: keep the values in sync with the CoglPipelineWrapModeInternal * enum so no conversion is actually needed. */ -typedef enum { +typedef enum +{ COGL_PIPELINE_WRAP_MODE_REPEAT = 0x2901, COGL_PIPELINE_WRAP_MODE_MIRRORED_REPEAT = 0x8370, COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE = 0x812F, @@ -148,7 +150,7 @@ typedef enum { * Since: 2.0 * Stability: unstable */ -void +COGL_EXPORT void cogl_pipeline_set_layer_texture (CoglPipeline *pipeline, int layer_index, CoglTexture *texture); @@ -157,13 +159,9 @@ cogl_pipeline_set_layer_texture (CoglPipeline *pipeline, * cogl_pipeline_set_layer_null_texture: * @pipeline: A #CoglPipeline * @layer_index: The layer number to modify - * @texture_type: The type of the default texture to use * * Sets the texture for this layer to be the default texture for the - * given type. This is equivalent to calling - * cogl_pipeline_set_layer_texture() with %NULL for the texture - * argument except that you can also specify the type of default - * texture to use. The default texture is a 1x1 pixel white texture. + * given type. The default texture is a 1x1 pixel white texture. * * This function is mostly useful if you want to create a base * pipeline that you want to create multiple copies from using @@ -174,10 +172,9 @@ cogl_pipeline_set_layer_texture (CoglPipeline *pipeline, * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_pipeline_set_layer_null_texture (CoglPipeline *pipeline, - int layer_index, - CoglTextureType texture_type); + int layer_index); /** * cogl_pipeline_get_layer_texture: @@ -189,7 +186,7 @@ cogl_pipeline_set_layer_null_texture (CoglPipeline *pipeline, * Stability: unstable * Since: 1.10 */ -CoglTexture * +COGL_EXPORT CoglTexture * cogl_pipeline_get_layer_texture (CoglPipeline *pipeline, int layer_index); @@ -202,7 +199,7 @@ cogl_pipeline_get_layer_texture (CoglPipeline *pipeline, * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_pipeline_remove_layer (CoglPipeline *pipeline, int layer_index); @@ -212,7 +209,7 @@ cogl_pipeline_remove_layer (CoglPipeline *pipeline, * @layer_index: Specifies the layer you want define a combine function for * @blend_string: A Cogl blend string * describing the desired texture combine function. - * @error: A #CoglError that may report parse errors or lack of GPU/driver + * @error: A #GError that may report parse errors or lack of GPU/driver * support. May be %NULL, in which case a warning will be printed out if an * error is encountered. * @@ -300,11 +297,11 @@ cogl_pipeline_remove_layer (CoglPipeline *pipeline, * Since: 2.0 * Stability: unstable */ -CoglBool +COGL_EXPORT gboolean cogl_pipeline_set_layer_combine (CoglPipeline *pipeline, int layer_index, const char *blend_string, - CoglError **error); + GError **error); /** * cogl_pipeline_set_layer_combine_constant: @@ -319,7 +316,7 @@ cogl_pipeline_set_layer_combine (CoglPipeline *pipeline, * Since: 2.0 * Stability: unstable */ -void +COGL_EXPORT void cogl_pipeline_set_layer_combine_constant (CoglPipeline *pipeline, int layer_index, const CoglColor *constant); @@ -336,7 +333,7 @@ cogl_pipeline_set_layer_combine_constant (CoglPipeline *pipeline, * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_pipeline_set_layer_matrix (CoglPipeline *pipeline, int layer_index, const CoglMatrix *matrix); @@ -352,7 +349,7 @@ cogl_pipeline_set_layer_matrix (CoglPipeline *pipeline, * Since: 2.0 * Stability: unstable */ -int +COGL_EXPORT int cogl_pipeline_get_n_layers (CoglPipeline *pipeline); /** @@ -373,7 +370,7 @@ cogl_pipeline_get_n_layers (CoglPipeline *pipeline); * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_pipeline_set_layer_filters (CoglPipeline *pipeline, int layer_index, CoglPipelineFilter min_filter, @@ -396,7 +393,7 @@ cogl_pipeline_set_layer_filters (CoglPipeline *pipeline, * Since: 1.10 * Stability: unstable */ -CoglPipelineFilter +COGL_EXPORT CoglPipelineFilter cogl_pipeline_get_layer_min_filter (CoglPipeline *pipeline, int layer_index); @@ -417,7 +414,7 @@ cogl_pipeline_get_layer_min_filter (CoglPipeline *pipeline, * Since: 1.10 * Stability: unstable */ -CoglPipelineFilter +COGL_EXPORT CoglPipelineFilter cogl_pipeline_get_layer_mag_filter (CoglPipeline *pipeline, int layer_index); @@ -426,7 +423,7 @@ cogl_pipeline_get_layer_mag_filter (CoglPipeline *pipeline, * @pipeline: A #CoglPipeline object * @layer_index: the layer number to change. * @enable: whether to enable point sprite coord generation. - * @error: A return location for a CoglError, or NULL to ignore errors. + * @error: A return location for a #GError, or NULL to ignore errors. * * When rendering points, if @enable is %TRUE then the texture * coordinates for this layer will be replaced with coordinates that @@ -435,19 +432,15 @@ cogl_pipeline_get_layer_mag_filter (CoglPipeline *pipeline, * have 1.0,1.0. If @enable is %FALSE then the coordinates will be * fixed for the entire point. * - * This function will only work if %COGL_FEATURE_ID_POINT_SPRITE is - * available. If the feature is not available then the function will - * return %FALSE and set @error. - * * Return value: %TRUE if the function succeeds, %FALSE otherwise. * Since: 2.0 * Stability: unstable */ -CoglBool +COGL_EXPORT gboolean cogl_pipeline_set_layer_point_sprite_coords_enabled (CoglPipeline *pipeline, int layer_index, - CoglBool enable, - CoglError **error); + gboolean enable, + GError **error); /** * cogl_pipeline_get_layer_point_sprite_coords_enabled: @@ -463,7 +456,7 @@ cogl_pipeline_set_layer_point_sprite_coords_enabled (CoglPipeline *pipeline, * Since: 2.0 * Stability: unstable */ -CoglBool +COGL_EXPORT gboolean cogl_pipeline_get_layer_point_sprite_coords_enabled (CoglPipeline *pipeline, int layer_index); @@ -481,7 +474,7 @@ cogl_pipeline_get_layer_point_sprite_coords_enabled (CoglPipeline *pipeline, * Since: 1.6 * Stability: unstable */ -CoglPipelineWrapMode +COGL_EXPORT CoglPipelineWrapMode cogl_pipeline_get_layer_wrap_mode_s (CoglPipeline *pipeline, int layer_index); @@ -496,7 +489,7 @@ cogl_pipeline_get_layer_wrap_mode_s (CoglPipeline *pipeline, * Since: 2.0 * Stability: unstable */ -void +COGL_EXPORT void cogl_pipeline_set_layer_wrap_mode_s (CoglPipeline *pipeline, int layer_index, CoglPipelineWrapMode mode); @@ -515,7 +508,7 @@ cogl_pipeline_set_layer_wrap_mode_s (CoglPipeline *pipeline, * Since: 1.6 * Stability: unstable */ -CoglPipelineWrapMode +COGL_EXPORT CoglPipelineWrapMode cogl_pipeline_get_layer_wrap_mode_t (CoglPipeline *pipeline, int layer_index); @@ -531,46 +524,11 @@ cogl_pipeline_get_layer_wrap_mode_t (CoglPipeline *pipeline, * Since: 2.0 * Stability: unstable */ -void +COGL_EXPORT void cogl_pipeline_set_layer_wrap_mode_t (CoglPipeline *pipeline, int layer_index, CoglPipelineWrapMode mode); -/** - * cogl_pipeline_get_layer_wrap_mode_p: - * @pipeline: A #CoglPipeline object - * @layer_index: the layer number to change. - * - * Returns the wrap mode for the 'p' coordinate of texture lookups on this - * layer. - * - * Return value: the wrap mode for the 'p' coordinate of texture lookups on - * this layer. - * - * Since: 1.6 - * Stability: unstable - */ -CoglPipelineWrapMode -cogl_pipeline_get_layer_wrap_mode_p (CoglPipeline *pipeline, - int layer_index); - -/** - * cogl_pipeline_set_layer_wrap_mode_p: - * @pipeline: A #CoglPipeline object - * @layer_index: the layer number to change. - * @mode: the new wrap mode - * - * Sets the wrap mode for the 'p' coordinate of texture lookups on - * this layer. 'p' is the third coordinate. - * - * Since: 2.0 - * Stability: unstable - */ -void -cogl_pipeline_set_layer_wrap_mode_p (CoglPipeline *pipeline, - int layer_index, - CoglPipelineWrapMode mode); - /** * cogl_pipeline_set_layer_wrap_mode: * @pipeline: A #CoglPipeline object @@ -579,20 +537,19 @@ cogl_pipeline_set_layer_wrap_mode_p (CoglPipeline *pipeline, * * Sets the wrap mode for all three coordinates of texture lookups on * this layer. This is equivalent to calling - * cogl_pipeline_set_layer_wrap_mode_s(), - * cogl_pipeline_set_layer_wrap_mode_t() and - * cogl_pipeline_set_layer_wrap_mode_p() separately. + * cogl_pipeline_set_layer_wrap_mode_s() and + * cogl_pipeline_set_layer_wrap_mode_t() separately. * * Since: 2.0 * Stability: unstable */ -void +COGL_EXPORT void cogl_pipeline_set_layer_wrap_mode (CoglPipeline *pipeline, int layer_index, CoglPipelineWrapMode mode); /** - * cogl_pipeline_add_layer_snippet: + * cogl_pipeline_add_layer_snippet: (skip) * @pipeline: A #CoglPipeline * @layer: The layer to hook the snippet to * @snippet: A #CoglSnippet @@ -606,11 +563,16 @@ cogl_pipeline_set_layer_wrap_mode (CoglPipeline *pipeline, * Since: 1.10 * Stability: Unstable */ -void +COGL_EXPORT void cogl_pipeline_add_layer_snippet (CoglPipeline *pipeline, int layer, CoglSnippet *snippet); -COGL_END_DECLS +COGL_EXPORT void +cogl_pipeline_set_layer_max_mipmap_level (CoglPipeline *pipeline, + int layer, + int max_level); + +G_END_DECLS #endif /* __COGL_PIPELINE_LAYER_STATE_H__ */ diff --git a/cogl/cogl/cogl-pipeline-layer.c b/cogl/cogl/cogl-pipeline-layer.c index c7a3d5ec5..c6f13696a 100644 --- a/cogl/cogl/cogl-pipeline-layer.c +++ b/cogl/cogl/cogl-pipeline-layer.c @@ -31,9 +31,7 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-util.h" #include "cogl-context-private.h" @@ -44,9 +42,9 @@ #include "cogl-pipeline-layer-state-private.h" #include "cogl-pipeline-layer-state.h" #include "cogl-node-private.h" -#include "cogl-pipeline-opengl-private.h" #include "cogl-context-private.h" #include "cogl-texture-private.h" +#include "driver/gl/cogl-pipeline-opengl-private.h" #include @@ -78,7 +76,7 @@ _cogl_pipeline_layer_get_unit_index (CoglPipelineLayer *layer) return authority->unit_index; } -CoglBool +gboolean _cogl_pipeline_layer_has_alpha (CoglPipelineLayer *layer) { CoglPipelineLayer *combine_authority = @@ -175,7 +173,7 @@ _cogl_pipeline_layer_copy_differences (CoglPipelineLayer *dest, while (differences) { - int index = _cogl_util_ffs (differences) - 1; + int index = ffs (differences) - 1; differences &= ~(1 << index); @@ -189,10 +187,6 @@ _cogl_pipeline_layer_copy_differences (CoglPipelineLayer *dest, g_warn_if_reached (); break; - case COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE_INDEX: - dest->texture_type = src->texture_type; - break; - case COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX: dest->texture = src->texture; if (dest->texture) @@ -274,7 +268,6 @@ _cogl_pipeline_layer_init_multi_property_sparse_state ( /* XXX: avoid using a default: label so we get a warning if we * don't explicitly handle a newly defined state-group here. */ case COGL_PIPELINE_LAYER_STATE_UNIT: - case COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE: case COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA: case COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS: case COGL_PIPELINE_LAYER_STATE_USER_MATRIX: @@ -358,7 +351,7 @@ _cogl_pipeline_layer_pre_change_notify (CoglPipeline *required_owner, goto init_layer_state; /* We only allow a NULL required_owner for new layers */ - _COGL_RETURN_VAL_IF_FAIL (required_owner != NULL, layer); + g_return_val_if_fail (required_owner != NULL, layer); /* Chain up: * A modification of a layer is indirectly also a modification of @@ -397,14 +390,10 @@ _cogl_pipeline_layer_pre_change_notify (CoglPipeline *required_owner, * have a single owner and can only be associated with a single * backend that needs to be notified of the layer change... */ - if (required_owner->progend != COGL_PIPELINE_PROGEND_UNDEFINED) { - const CoglPipelineProgend *progend = - _cogl_pipeline_progends[required_owner->progend]; - const CoglPipelineFragend *fragend = - _cogl_pipeline_fragends[progend->fragend]; - const CoglPipelineVertend *vertend = - _cogl_pipeline_vertends[progend->vertend]; + const CoglPipelineProgend *progend = _cogl_pipeline_progend; + const CoglPipelineFragend *fragend = _cogl_pipeline_fragend; + const CoglPipelineVertend *vertend = _cogl_pipeline_vertend; if (fragend->layer_pre_change_notify) fragend->layer_pre_change_notify (required_owner, layer, change); @@ -594,7 +583,7 @@ _cogl_pipeline_layer_compare_differences (CoglPipelineLayer *layer0, return layers_difference; } -static CoglBool +static gboolean layer_state_equal (CoglPipelineLayerStateIndex state_index, CoglPipelineLayer **authorities0, CoglPipelineLayer **authorities1, @@ -638,7 +627,7 @@ _cogl_pipeline_layer_resolve_authorities (CoglPipelineLayer *layer, g_assert (remaining == 0); } -CoglBool +gboolean _cogl_pipeline_layer_equal (CoglPipelineLayer *layer0, CoglPipelineLayer *layer1, unsigned long differences_mask, @@ -664,16 +653,6 @@ _cogl_pipeline_layer_equal (CoglPipelineLayer *layer0, layers_difference, authorities1); - if (layers_difference & COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE) - { - CoglPipelineLayerStateIndex state_index = - COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE_INDEX; - if (!_cogl_pipeline_layer_texture_type_equal (authorities0[state_index], - authorities1[state_index], - flags)) - return FALSE; - } - if (layers_difference & COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA) { CoglPipelineLayerStateIndex state_index = @@ -769,7 +748,6 @@ _cogl_pipeline_init_default_layers (void) layer->unit_index = 0; layer->texture = NULL; - layer->texture_type = COGL_TEXTURE_TYPE_2D; layer->sampler_cache_entry = _cogl_sampler_cache_get_default_entry (ctx->sampler_cache); @@ -869,7 +847,7 @@ _cogl_pipeline_layer_pre_paint (CoglPipelineLayer *layer) * separately or is the same function used for both channel masks and * with the same arguments... */ -CoglBool +gboolean _cogl_pipeline_layer_needs_combine_separate (CoglPipelineLayer *combine_authority) { diff --git a/cogl/cogl/cogl-pipeline-private.h b/cogl/cogl/cogl-pipeline-private.h index 845fdd866..1e719a068 100644 --- a/cogl/cogl/cogl-pipeline-private.h +++ b/cogl/cogl/cogl-pipeline-private.h @@ -49,63 +49,11 @@ #include -#ifdef HAVE_COGL_GL - -#define COGL_PIPELINE_PROGEND_FIXED_ARBFP 0 -#define COGL_PIPELINE_PROGEND_FIXED 1 -#define COGL_PIPELINE_PROGEND_GLSL 2 -#define COGL_PIPELINE_N_PROGENDS 3 - -#define COGL_PIPELINE_VERTEND_FIXED 0 -#define COGL_PIPELINE_VERTEND_GLSL 1 -#define COGL_PIPELINE_N_VERTENDS 2 - -#define COGL_PIPELINE_FRAGEND_ARBFP 0 -#define COGL_PIPELINE_FRAGEND_FIXED 1 -#define COGL_PIPELINE_FRAGEND_GLSL 2 -#define COGL_PIPELINE_N_FRAGENDS 3 - -#else /* HAVE_COGL_GL */ - -#ifdef HAVE_COGL_GLES2 - -#define COGL_PIPELINE_PROGEND_GLSL 0 -#define COGL_PIPELINE_VERTEND_GLSL 0 -#define COGL_PIPELINE_FRAGEND_GLSL 0 - -#ifdef HAVE_COGL_GLES -#define COGL_PIPELINE_PROGEND_FIXED 1 -#define COGL_PIPELINE_VERTEND_FIXED 1 -#define COGL_PIPELINE_FRAGEND_FIXED 1 - -#define COGL_PIPELINE_N_PROGENDS 2 -#define COGL_PIPELINE_N_VERTENDS 2 -#define COGL_PIPELINE_N_FRAGENDS 2 -#else -#define COGL_PIPELINE_N_PROGENDS 1 -#define COGL_PIPELINE_N_VERTENDS 1 -#define COGL_PIPELINE_N_FRAGENDS 1 -#endif - -#else /* HAVE_COGL_GLES2 */ +#if !(defined(HAVE_COGL_GL) || defined(HAVE_COGL_GLES2)) -#ifdef HAVE_COGL_GLES -#define COGL_PIPELINE_PROGEND_FIXED 0 -#define COGL_PIPELINE_VERTEND_FIXED 0 -#define COGL_PIPELINE_FRAGEND_FIXED 0 -#define COGL_PIPELINE_N_PROGENDS 1 -#define COGL_PIPELINE_N_VERTENDS 1 -#define COGL_PIPELINE_N_FRAGENDS 1 -#else #error No drivers defined -#endif -#endif /* HAVE_COGL_GLES2 */ - -#endif /* HAVE_COGL_GL */ - -#define COGL_PIPELINE_PROGEND_DEFAULT 0 -#define COGL_PIPELINE_PROGEND_UNDEFINED 3 +#endif /* defined(HAVE_COGL_GL) || defined(HAVE_COGL_GLES2) */ /* XXX: should I rename these as * COGL_PIPELINE_STATE_INDEX_XYZ... ? @@ -114,19 +62,15 @@ typedef enum { /* sparse state */ COGL_PIPELINE_STATE_COLOR_INDEX, - COGL_PIPELINE_STATE_BLEND_ENABLE_INDEX, COGL_PIPELINE_STATE_LAYERS_INDEX, - COGL_PIPELINE_STATE_LIGHTING_INDEX, COGL_PIPELINE_STATE_ALPHA_FUNC_INDEX, COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE_INDEX, COGL_PIPELINE_STATE_BLEND_INDEX, COGL_PIPELINE_STATE_USER_SHADER_INDEX, COGL_PIPELINE_STATE_DEPTH_INDEX, - COGL_PIPELINE_STATE_FOG_INDEX, COGL_PIPELINE_STATE_NON_ZERO_POINT_SIZE_INDEX, COGL_PIPELINE_STATE_POINT_SIZE_INDEX, COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE_INDEX, - COGL_PIPELINE_STATE_LOGIC_OPS_INDEX, COGL_PIPELINE_STATE_CULL_FACE_INDEX, COGL_PIPELINE_STATE_UNIFORMS_INDEX, COGL_PIPELINE_STATE_VERTEX_SNIPPETS_INDEX, @@ -154,13 +98,9 @@ typedef enum _CoglPipelineState { COGL_PIPELINE_STATE_COLOR = 1L<big_state is valid */ unsigned int has_big_state:1; - /* By default blending is enabled automatically depending on the - * unlit color, the lighting colors or the texture format. The user - * can override this to explicitly enable or disable blending. - * - * This is a sparse property */ - unsigned int blend_enable:3; - /* There are many factors that can determine if we need to enable * blending, this holds our final decision */ unsigned int real_blend_enable:1; @@ -497,7 +368,6 @@ struct _CoglPipeline unsigned int unknown_color_alpha:1; unsigned int layers_cache_dirty:1; - unsigned int deprecated_get_layers_list_dirty:1; #ifdef COGL_DEBUG_ENABLED /* For debugging purposes it's possible to associate a static const @@ -505,12 +375,6 @@ struct _CoglPipeline * where the pipeline originates from */ unsigned int has_static_breadcrumb:1; #endif - - /* There are multiple fragment and vertex processing backends for - * CoglPipeline, glsl, arbfp and fixed that are bundled under a - * "progend". This identifies the backend being used for the - * pipeline. */ - unsigned int progend:3; }; typedef struct _CoglPipelineFragend @@ -518,17 +382,15 @@ typedef struct _CoglPipelineFragend void (*start) (CoglPipeline *pipeline, int n_layers, unsigned long pipelines_difference); - CoglBool (*add_layer) (CoglPipeline *pipeline, + gboolean (*add_layer) (CoglPipeline *pipeline, CoglPipelineLayer *layer, unsigned long layers_difference); - CoglBool (*passthrough) (CoglPipeline *pipeline); - CoglBool (*end) (CoglPipeline *pipeline, + gboolean (*end) (CoglPipeline *pipeline, unsigned long pipelines_difference); void (*pipeline_pre_change_notify) (CoglPipeline *pipeline, CoglPipelineState change, const CoglColor *new_color); - void (*pipeline_set_parent_notify) (CoglPipeline *pipeline); void (*layer_pre_change_notify) (CoglPipeline *owner, CoglPipelineLayer *layer, CoglPipelineLayerState change); @@ -539,11 +401,11 @@ typedef struct _CoglPipelineVertend void (*start) (CoglPipeline *pipeline, int n_layers, unsigned long pipelines_difference); - CoglBool (*add_layer) (CoglPipeline *pipeline, + gboolean (*add_layer) (CoglPipeline *pipeline, CoglPipelineLayer *layer, unsigned long layers_difference, CoglFramebuffer *framebuffer); - CoglBool (*end) (CoglPipeline *pipeline, + gboolean (*end) (CoglPipeline *pipeline, unsigned long pipelines_difference); void (*pipeline_pre_change_notify) (CoglPipeline *pipeline, @@ -556,9 +418,7 @@ typedef struct _CoglPipelineVertend typedef struct { - int vertend; - int fragend; - CoglBool (*start) (CoglPipeline *pipeline); + gboolean (*start) (CoglPipeline *pipeline); void (*end) (CoglPipeline *pipeline, unsigned long pipelines_difference); void (*pipeline_pre_change_notify) (CoglPipeline *pipeline, @@ -573,19 +433,9 @@ typedef struct void (* pre_paint) (CoglPipeline *pipeline, CoglFramebuffer *framebuffer); } CoglPipelineProgend; -typedef enum -{ - COGL_PIPELINE_PROGRAM_TYPE_GLSL = 1, - COGL_PIPELINE_PROGRAM_TYPE_ARBFP, - COGL_PIPELINE_PROGRAM_TYPE_FIXED -} CoglPipelineProgramType; - -extern const CoglPipelineFragend * -_cogl_pipeline_fragends[COGL_PIPELINE_N_FRAGENDS]; -extern const CoglPipelineVertend * -_cogl_pipeline_vertends[COGL_PIPELINE_N_VERTENDS]; -extern const CoglPipelineProgend * -_cogl_pipeline_progends[]; +extern const CoglPipelineFragend *_cogl_pipeline_fragend; +extern const CoglPipelineVertend *_cogl_pipeline_vertend; +extern const CoglPipelineProgend *_cogl_pipeline_progend; void _cogl_pipeline_init_default_pipeline (void); @@ -607,7 +457,7 @@ _cogl_pipeline_get_authority (CoglPipeline *pipeline, return authority; } -typedef CoglBool (*CoglPipelineStateComparitor) (CoglPipeline *authority0, +typedef gboolean (*CoglPipelineStateComparitor) (CoglPipeline *authority0, CoglPipeline *authority1); void @@ -620,14 +470,14 @@ void _cogl_pipeline_pre_change_notify (CoglPipeline *pipeline, CoglPipelineState change, const CoglColor *new_color, - CoglBool from_layer_change); + gboolean from_layer_change); void _cogl_pipeline_prune_redundant_ancestry (CoglPipeline *pipeline); void _cogl_pipeline_update_real_blend_enable (CoglPipeline *pipeline, - CoglBool unknown_color_alpha); + gboolean unknown_color_alpha); typedef enum { @@ -642,7 +492,7 @@ _cogl_pipeline_get_layer_with_flags (CoglPipeline *pipeline, #define _cogl_pipeline_get_layer(p, l) \ _cogl_pipeline_get_layer_with_flags (p, l, 0) -CoglBool +gboolean _cogl_is_pipeline_layer (void *object); void @@ -660,7 +510,7 @@ _cogl_pipeline_prune_empty_layer_difference (CoglPipeline *layers_authority, * able to fill your geometry according to a given Cogl pipeline. */ -CoglBool +gboolean _cogl_pipeline_get_real_blend_enabled (CoglPipeline *pipeline); /* @@ -711,12 +561,6 @@ typedef struct _CoglPipelineFlushOptions CoglTexture *layer0_override_texture; } CoglPipelineFlushOptions; -void -_cogl_use_fragment_program (GLuint gl_program, CoglPipelineProgramType type); - -void -_cogl_use_vertex_program (GLuint gl_program, CoglPipelineProgramType type); - unsigned int _cogl_get_n_args_for_combine_func (CoglPipelineCombineFunc func); @@ -846,9 +690,6 @@ _cogl_pipeline_weak_copy (CoglPipeline *pipeline, void _cogl_pipeline_set_progend (CoglPipeline *pipeline, int progend); -CoglPipeline * -_cogl_pipeline_get_parent (CoglPipeline *pipeline); - void _cogl_pipeline_get_colorubv (CoglPipeline *pipeline, uint8_t *color); @@ -861,7 +702,7 @@ unsigned long _cogl_pipeline_compare_differences (CoglPipeline *pipeline0, CoglPipeline *pipeline1); -CoglBool +gboolean _cogl_pipeline_equal (CoglPipeline *pipeline0, CoglPipeline *pipeline1, unsigned int differences, @@ -905,16 +746,6 @@ void _cogl_pipeline_apply_overrides (CoglPipeline *pipeline, CoglPipelineFlushOptions *options); -CoglPipelineBlendEnable -_cogl_pipeline_get_blend_enabled (CoglPipeline *pipeline); - -void -_cogl_pipeline_set_blend_enabled (CoglPipeline *pipeline, - CoglPipelineBlendEnable enable); - -CoglBool -_cogl_pipeline_get_fog_enabled (CoglPipeline *pipeline); - #ifdef COGL_DEBUG_ENABLED void _cogl_pipeline_set_static_breadcrumb (CoglPipeline *pipeline, @@ -924,19 +755,15 @@ _cogl_pipeline_set_static_breadcrumb (CoglPipeline *pipeline, unsigned long _cogl_pipeline_get_age (CoglPipeline *pipeline); -CoglPipeline * -_cogl_pipeline_get_authority (CoglPipeline *pipeline, - unsigned long difference); - void _cogl_pipeline_add_layer_difference (CoglPipeline *pipeline, CoglPipelineLayer *layer, - CoglBool inc_n_layers); + gboolean inc_n_layers); void _cogl_pipeline_remove_layer_difference (CoglPipeline *pipeline, CoglPipelineLayer *layer, - CoglBool dec_n_layers); + gboolean dec_n_layers); CoglPipeline * _cogl_pipeline_find_equivalent_parent (CoglPipeline *pipeline, @@ -948,7 +775,7 @@ _cogl_pipeline_get_layer_combine_constant (CoglPipeline *pipeline, int layer_index, float *constant); -void +COGL_EXPORT void _cogl_pipeline_prune_to_n_layers (CoglPipeline *pipeline, int n); @@ -956,26 +783,23 @@ _cogl_pipeline_prune_to_n_layers (CoglPipeline *pipeline, int n); * API to support the deprecate cogl_pipeline_layer_xyz functions... */ -const GList * -_cogl_pipeline_get_layers (CoglPipeline *pipeline); - -typedef CoglBool (*CoglPipelineInternalLayerCallback) (CoglPipelineLayer *layer, +typedef gboolean (*CoglPipelineInternalLayerCallback) (CoglPipelineLayer *layer, void *user_data); -void +COGL_EXPORT void _cogl_pipeline_foreach_layer_internal (CoglPipeline *pipeline, CoglPipelineInternalLayerCallback callback, void *user_data); -CoglBool +gboolean _cogl_pipeline_layer_numbers_equal (CoglPipeline *pipeline0, CoglPipeline *pipeline1); -CoglBool +gboolean _cogl_pipeline_layer_and_unit_numbers_equal (CoglPipeline *pipeline0, CoglPipeline *pipeline1); -CoglBool +gboolean _cogl_pipeline_need_texture_combine_separate (CoglPipelineLayer *combine_authority); diff --git a/cogl/cogl/cogl-pipeline-snippet-private.h b/cogl/cogl/cogl-pipeline-snippet-private.h index 7a9d233c8..9207f2036 100644 --- a/cogl/cogl/cogl-pipeline-snippet-private.h +++ b/cogl/cogl/cogl-pipeline-snippet-private.h @@ -73,7 +73,7 @@ typedef struct the return value. Instead it is expected that the snippet will modify one of the argument variables directly and that will be returned */ - CoglBool return_variable_is_argument; + gboolean return_variable_is_argument; /* The argument names or NULL if there are none */ const char *arguments; @@ -108,7 +108,7 @@ void _cogl_pipeline_snippet_list_hash (CoglPipelineSnippetList *list, unsigned int *hash); -CoglBool +gboolean _cogl_pipeline_snippet_list_equal (CoglPipelineSnippetList *list0, CoglPipelineSnippetList *list1); diff --git a/cogl/cogl/cogl-pipeline-snippet.c b/cogl/cogl/cogl-pipeline-snippet.c index 18aefc790..ae83bc398 100644 --- a/cogl/cogl/cogl-pipeline-snippet.c +++ b/cogl/cogl/cogl-pipeline-snippet.c @@ -31,9 +31,7 @@ * Neil Roberts */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include @@ -270,7 +268,7 @@ _cogl_pipeline_snippet_list_hash (CoglPipelineSnippetList *list, } } -CoglBool +gboolean _cogl_pipeline_snippet_list_equal (CoglPipelineSnippetList *list0, CoglPipelineSnippetList *list1) { diff --git a/cogl/cogl/cogl-pipeline-state-private.h b/cogl/cogl/cogl-pipeline-state-private.h index 366683ec4..e49fe8a45 100644 --- a/cogl/cogl/cogl-pipeline-state-private.h +++ b/cogl/cogl/cogl-pipeline-state-private.h @@ -37,82 +37,70 @@ CoglPipeline * _cogl_pipeline_get_user_program (CoglPipeline *pipeline); -CoglBool +gboolean _cogl_pipeline_has_vertex_snippets (CoglPipeline *pipeline); -CoglBool +gboolean _cogl_pipeline_has_fragment_snippets (CoglPipeline *pipeline); -CoglBool +gboolean _cogl_pipeline_has_non_layer_vertex_snippets (CoglPipeline *pipeline); -CoglBool +gboolean _cogl_pipeline_has_non_layer_fragment_snippets (CoglPipeline *pipeline); -void -_cogl_pipeline_set_fog_state (CoglPipeline *pipeline, - const CoglPipelineFogState *fog_state); - -CoglBool +gboolean _cogl_pipeline_color_equal (CoglPipeline *authority0, CoglPipeline *authority1); -CoglBool -_cogl_pipeline_lighting_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1); - -CoglBool +gboolean _cogl_pipeline_alpha_func_state_equal (CoglPipeline *authority0, CoglPipeline *authority1); -CoglBool +gboolean _cogl_pipeline_alpha_func_reference_state_equal (CoglPipeline *authority0, CoglPipeline *authority1); -CoglBool +gboolean _cogl_pipeline_blend_state_equal (CoglPipeline *authority0, CoglPipeline *authority1); -CoglBool +gboolean _cogl_pipeline_depth_state_equal (CoglPipeline *authority0, CoglPipeline *authority1); -CoglBool -_cogl_pipeline_fog_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1); - -CoglBool +gboolean _cogl_pipeline_non_zero_point_size_equal (CoglPipeline *authority0, CoglPipeline *authority1); -CoglBool +gboolean _cogl_pipeline_point_size_equal (CoglPipeline *authority0, CoglPipeline *authority1); -CoglBool +gboolean _cogl_pipeline_per_vertex_point_size_equal (CoglPipeline *authority0, CoglPipeline *authority1); -CoglBool +gboolean _cogl_pipeline_logic_ops_state_equal (CoglPipeline *authority0, CoglPipeline *authority1); -CoglBool +gboolean _cogl_pipeline_user_shader_equal (CoglPipeline *authority0, CoglPipeline *authority1); -CoglBool +gboolean _cogl_pipeline_cull_face_state_equal (CoglPipeline *authority0, CoglPipeline *authority1); -CoglBool +gboolean _cogl_pipeline_uniforms_state_equal (CoglPipeline *authority0, CoglPipeline *authority1); -CoglBool +gboolean _cogl_pipeline_vertex_snippets_state_equal (CoglPipeline *authority0, CoglPipeline *authority1); -CoglBool +gboolean _cogl_pipeline_fragment_snippets_state_equal (CoglPipeline *authority0, CoglPipeline *authority1); @@ -120,18 +108,10 @@ void _cogl_pipeline_hash_color_state (CoglPipeline *authority, CoglPipelineHashState *state); -void -_cogl_pipeline_hash_blend_enable_state (CoglPipeline *authority, - CoglPipelineHashState *state); - void _cogl_pipeline_hash_layers_state (CoglPipeline *authority, CoglPipelineHashState *state); -void -_cogl_pipeline_hash_lighting_state (CoglPipeline *authority, - CoglPipelineHashState *state); - void _cogl_pipeline_hash_alpha_func_state (CoglPipeline *authority, CoglPipelineHashState *state); @@ -152,10 +132,6 @@ void _cogl_pipeline_hash_depth_state (CoglPipeline *authority, CoglPipelineHashState *state); -void -_cogl_pipeline_hash_fog_state (CoglPipeline *authority, - CoglPipelineHashState *state); - void _cogl_pipeline_hash_non_zero_point_size_state (CoglPipeline *authority, CoglPipelineHashState *state); diff --git a/cogl/cogl/cogl-pipeline-state.c b/cogl/cogl/cogl-pipeline-state.c index bda42d8ed..ecfc4cd3b 100644 --- a/cogl/cogl/cogl-pipeline-state.c +++ b/cogl/cogl/cogl-pipeline-state.c @@ -31,9 +31,7 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-context-private.h" #include "cogl-color-private.h" @@ -42,7 +40,6 @@ #include "cogl-depth-state-private.h" #include "cogl-pipeline-state-private.h" #include "cogl-snippet-private.h" -#include "cogl-error-private.h" #include @@ -57,7 +54,7 @@ _cogl_pipeline_get_user_program (CoglPipeline *pipeline) { CoglPipeline *authority; - _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), NULL); + g_return_val_if_fail (cogl_is_pipeline (pipeline), NULL); authority = _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_USER_SHADER); @@ -65,35 +62,14 @@ _cogl_pipeline_get_user_program (CoglPipeline *pipeline) return authority->big_state->user_program; } -CoglBool +gboolean _cogl_pipeline_color_equal (CoglPipeline *authority0, CoglPipeline *authority1) { return cogl_color_equal (&authority0->color, &authority1->color); } -CoglBool -_cogl_pipeline_lighting_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - CoglPipelineLightingState *state0 = &authority0->big_state->lighting_state; - CoglPipelineLightingState *state1 = &authority1->big_state->lighting_state; - - if (memcmp (state0->ambient, state1->ambient, sizeof (float) * 4) != 0) - return FALSE; - if (memcmp (state0->diffuse, state1->diffuse, sizeof (float) * 4) != 0) - return FALSE; - if (memcmp (state0->specular, state1->specular, sizeof (float) * 4) != 0) - return FALSE; - if (memcmp (state0->emission, state1->emission, sizeof (float) * 4) != 0) - return FALSE; - if (state0->shininess != state1->shininess) - return FALSE; - - return TRUE; -} - -CoglBool +gboolean _cogl_pipeline_alpha_func_state_equal (CoglPipeline *authority0, CoglPipeline *authority1) { @@ -105,7 +81,7 @@ _cogl_pipeline_alpha_func_state_equal (CoglPipeline *authority0, return alpha_state0->alpha_func == alpha_state1->alpha_func; } -CoglBool +gboolean _cogl_pipeline_alpha_func_reference_state_equal (CoglPipeline *authority0, CoglPipeline *authority1) { @@ -118,7 +94,7 @@ _cogl_pipeline_alpha_func_reference_state_equal (CoglPipeline *authority0, alpha_state1->alpha_func_reference); } -CoglBool +gboolean _cogl_pipeline_blend_state_equal (CoglPipeline *authority0, CoglPipeline *authority1) { @@ -160,7 +136,7 @@ _cogl_pipeline_blend_state_equal (CoglPipeline *authority0, return TRUE; } -CoglBool +gboolean _cogl_pipeline_depth_state_equal (CoglPipeline *authority0, CoglPipeline *authority1) { @@ -179,25 +155,7 @@ _cogl_pipeline_depth_state_equal (CoglPipeline *authority0, } } -CoglBool -_cogl_pipeline_fog_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - CoglPipelineFogState *fog_state0 = &authority0->big_state->fog_state; - CoglPipelineFogState *fog_state1 = &authority1->big_state->fog_state; - - if (fog_state0->enabled == fog_state1->enabled && - cogl_color_equal (&fog_state0->color, &fog_state1->color) && - fog_state0->mode == fog_state1->mode && - fog_state0->density == fog_state1->density && - fog_state0->z_near == fog_state1->z_near && - fog_state0->z_far == fog_state1->z_far) - return TRUE; - else - return FALSE; -} - -CoglBool +gboolean _cogl_pipeline_non_zero_point_size_equal (CoglPipeline *authority0, CoglPipeline *authority1) { @@ -205,14 +163,14 @@ _cogl_pipeline_non_zero_point_size_equal (CoglPipeline *authority0, authority1->big_state->non_zero_point_size); } -CoglBool +gboolean _cogl_pipeline_point_size_equal (CoglPipeline *authority0, CoglPipeline *authority1) { return authority0->big_state->point_size == authority1->big_state->point_size; } -CoglBool +gboolean _cogl_pipeline_per_vertex_point_size_equal (CoglPipeline *authority0, CoglPipeline *authority1) { @@ -220,17 +178,7 @@ _cogl_pipeline_per_vertex_point_size_equal (CoglPipeline *authority0, authority1->big_state->per_vertex_point_size); } -CoglBool -_cogl_pipeline_logic_ops_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - CoglPipelineLogicOpsState *logic_ops_state0 = &authority0->big_state->logic_ops_state; - CoglPipelineLogicOpsState *logic_ops_state1 = &authority1->big_state->logic_ops_state; - - return logic_ops_state0->color_mask == logic_ops_state1->color_mask; -} - -CoglBool +gboolean _cogl_pipeline_cull_face_state_equal (CoglPipeline *authority0, CoglPipeline *authority1) { @@ -251,7 +199,7 @@ _cogl_pipeline_cull_face_state_equal (CoglPipeline *authority0, cull_face_state0->front_winding == cull_face_state1->front_winding); } -CoglBool +gboolean _cogl_pipeline_user_shader_equal (CoglPipeline *authority0, CoglPipeline *authority1) { @@ -266,7 +214,7 @@ typedef struct int override_count; } GetUniformsClosure; -static CoglBool +static gboolean get_uniforms_cb (int uniform_num, void *user_data) { GetUniformsClosure *data = user_data; @@ -311,7 +259,7 @@ _cogl_pipeline_get_all_uniform_values (CoglPipeline *pipeline, while (pipeline); } -CoglBool +gboolean _cogl_pipeline_uniforms_state_equal (CoglPipeline *authority0, CoglPipeline *authority1) { @@ -361,7 +309,7 @@ _cogl_pipeline_uniforms_state_equal (CoglPipeline *authority0, return TRUE; } -CoglBool +gboolean _cogl_pipeline_vertex_snippets_state_equal (CoglPipeline *authority0, CoglPipeline *authority1) { @@ -371,7 +319,7 @@ _cogl_pipeline_vertex_snippets_state_equal (CoglPipeline *authority0, vertex_snippets); } -CoglBool +gboolean _cogl_pipeline_fragment_snippets_state_equal (CoglPipeline *authority0, CoglPipeline *authority1) { @@ -387,7 +335,7 @@ cogl_pipeline_get_color (CoglPipeline *pipeline, { CoglPipeline *authority; - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); + g_return_if_fail (cogl_is_pipeline (pipeline)); authority = _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_COLOR); @@ -413,7 +361,7 @@ cogl_pipeline_set_color (CoglPipeline *pipeline, CoglPipelineState state = COGL_PIPELINE_STATE_COLOR; CoglPipeline *authority; - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); + g_return_if_fail (cogl_is_pipeline (pipeline)); authority = _cogl_pipeline_get_authority (pipeline, state); @@ -459,314 +407,6 @@ cogl_pipeline_set_color4f (CoglPipeline *pipeline, cogl_pipeline_set_color (pipeline, &color); } -CoglPipelineBlendEnable -_cogl_pipeline_get_blend_enabled (CoglPipeline *pipeline) -{ - CoglPipeline *authority; - - _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), FALSE); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_BLEND_ENABLE); - return authority->blend_enable; -} - -static CoglBool -_cogl_pipeline_blend_enable_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - return authority0->blend_enable == authority1->blend_enable ? TRUE : FALSE; -} - -void -_cogl_pipeline_set_blend_enabled (CoglPipeline *pipeline, - CoglPipelineBlendEnable enable) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_BLEND_ENABLE; - CoglPipeline *authority; - - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); - _COGL_RETURN_IF_FAIL (enable > 1 && - "don't pass TRUE or FALSE to _set_blend_enabled!"); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - if (authority->blend_enable == enable) - return; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - pipeline->blend_enable = enable; - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_blend_enable_equal); - - pipeline->dirty_real_blend_enable = TRUE; -} - -void -cogl_pipeline_get_ambient (CoglPipeline *pipeline, - CoglColor *ambient) -{ - CoglPipeline *authority; - - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LIGHTING); - - cogl_color_init_from_4fv (ambient, - authority->big_state->lighting_state.ambient); -} - -void -cogl_pipeline_set_ambient (CoglPipeline *pipeline, - const CoglColor *ambient) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_LIGHTING; - CoglPipeline *authority; - CoglPipelineLightingState *lighting_state; - - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - lighting_state = &authority->big_state->lighting_state; - if (cogl_color_equal (ambient, &lighting_state->ambient)) - return; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - lighting_state = &pipeline->big_state->lighting_state; - lighting_state->ambient[0] = cogl_color_get_red_float (ambient); - lighting_state->ambient[1] = cogl_color_get_green_float (ambient); - lighting_state->ambient[2] = cogl_color_get_blue_float (ambient); - lighting_state->ambient[3] = cogl_color_get_alpha_float (ambient); - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_lighting_state_equal); - - pipeline->dirty_real_blend_enable = TRUE; -} - -void -cogl_pipeline_get_diffuse (CoglPipeline *pipeline, - CoglColor *diffuse) -{ - CoglPipeline *authority; - - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LIGHTING); - - cogl_color_init_from_4fv (diffuse, - authority->big_state->lighting_state.diffuse); -} - -void -cogl_pipeline_set_diffuse (CoglPipeline *pipeline, - const CoglColor *diffuse) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_LIGHTING; - CoglPipeline *authority; - CoglPipelineLightingState *lighting_state; - - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - lighting_state = &authority->big_state->lighting_state; - if (cogl_color_equal (diffuse, &lighting_state->diffuse)) - return; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - lighting_state = &pipeline->big_state->lighting_state; - lighting_state->diffuse[0] = cogl_color_get_red_float (diffuse); - lighting_state->diffuse[1] = cogl_color_get_green_float (diffuse); - lighting_state->diffuse[2] = cogl_color_get_blue_float (diffuse); - lighting_state->diffuse[3] = cogl_color_get_alpha_float (diffuse); - - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_lighting_state_equal); - - pipeline->dirty_real_blend_enable = TRUE; -} - -void -cogl_pipeline_set_ambient_and_diffuse (CoglPipeline *pipeline, - const CoglColor *color) -{ - cogl_pipeline_set_ambient (pipeline, color); - cogl_pipeline_set_diffuse (pipeline, color); -} - -void -cogl_pipeline_get_specular (CoglPipeline *pipeline, - CoglColor *specular) -{ - CoglPipeline *authority; - - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LIGHTING); - - cogl_color_init_from_4fv (specular, - authority->big_state->lighting_state.specular); -} - -void -cogl_pipeline_set_specular (CoglPipeline *pipeline, const CoglColor *specular) -{ - CoglPipeline *authority; - CoglPipelineState state = COGL_PIPELINE_STATE_LIGHTING; - CoglPipelineLightingState *lighting_state; - - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - lighting_state = &authority->big_state->lighting_state; - if (cogl_color_equal (specular, &lighting_state->specular)) - return; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - lighting_state = &pipeline->big_state->lighting_state; - lighting_state->specular[0] = cogl_color_get_red_float (specular); - lighting_state->specular[1] = cogl_color_get_green_float (specular); - lighting_state->specular[2] = cogl_color_get_blue_float (specular); - lighting_state->specular[3] = cogl_color_get_alpha_float (specular); - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_lighting_state_equal); - - pipeline->dirty_real_blend_enable = TRUE; -} - -float -cogl_pipeline_get_shininess (CoglPipeline *pipeline) -{ - CoglPipeline *authority; - - _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), 0); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LIGHTING); - - return authority->big_state->lighting_state.shininess; -} - -void -cogl_pipeline_set_shininess (CoglPipeline *pipeline, - float shininess) -{ - CoglPipeline *authority; - CoglPipelineState state = COGL_PIPELINE_STATE_LIGHTING; - CoglPipelineLightingState *lighting_state; - - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); - - if (shininess < 0.0) - { - g_warning ("Out of range shininess %f supplied for pipeline\n", - shininess); - return; - } - - authority = _cogl_pipeline_get_authority (pipeline, state); - - lighting_state = &authority->big_state->lighting_state; - - if (lighting_state->shininess == shininess) - return; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - lighting_state = &pipeline->big_state->lighting_state; - lighting_state->shininess = shininess; - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_lighting_state_equal); -} - -void -cogl_pipeline_get_emission (CoglPipeline *pipeline, - CoglColor *emission) -{ - CoglPipeline *authority; - - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LIGHTING); - - cogl_color_init_from_4fv (emission, - authority->big_state->lighting_state.emission); -} - -void -cogl_pipeline_set_emission (CoglPipeline *pipeline, const CoglColor *emission) -{ - CoglPipeline *authority; - CoglPipelineState state = COGL_PIPELINE_STATE_LIGHTING; - CoglPipelineLightingState *lighting_state; - - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - lighting_state = &authority->big_state->lighting_state; - if (cogl_color_equal (emission, &lighting_state->emission)) - return; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - lighting_state = &pipeline->big_state->lighting_state; - lighting_state->emission[0] = cogl_color_get_red_float (emission); - lighting_state->emission[1] = cogl_color_get_green_float (emission); - lighting_state->emission[2] = cogl_color_get_blue_float (emission); - lighting_state->emission[3] = cogl_color_get_alpha_float (emission); - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_lighting_state_equal); - - pipeline->dirty_real_blend_enable = TRUE; -} - static void _cogl_pipeline_set_alpha_test_function (CoglPipeline *pipeline, CoglPipelineAlphaFunc alpha_func) @@ -775,7 +415,7 @@ _cogl_pipeline_set_alpha_test_function (CoglPipeline *pipeline, CoglPipeline *authority; CoglPipelineAlphaFuncState *alpha_state; - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); + g_return_if_fail (cogl_is_pipeline (pipeline)); authority = _cogl_pipeline_get_authority (pipeline, state); @@ -805,7 +445,7 @@ _cogl_pipeline_set_alpha_test_function_reference (CoglPipeline *pipeline, CoglPipeline *authority; CoglPipelineAlphaFuncState *alpha_state; - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); + g_return_if_fail (cogl_is_pipeline (pipeline)); authority = _cogl_pipeline_get_authority (pipeline, state); @@ -842,7 +482,7 @@ cogl_pipeline_get_alpha_test_function (CoglPipeline *pipeline) { CoglPipeline *authority; - _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), 0); + g_return_val_if_fail (cogl_is_pipeline (pipeline), 0); authority = _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_ALPHA_FUNC); @@ -855,7 +495,7 @@ cogl_pipeline_get_alpha_test_reference (CoglPipeline *pipeline) { CoglPipeline *authority; - _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), 0.0f); + g_return_val_if_fail (cogl_is_pipeline (pipeline), 0.0f); authority = _cogl_pipeline_get_authority (pipeline, @@ -955,10 +595,10 @@ setup_blend_state (CoglBlendStringStatement *statement, *blend_dst_factor = arg_to_gl_blend_factor (&statement->args[1]); } -CoglBool +gboolean cogl_pipeline_set_blend (CoglPipeline *pipeline, const char *blend_description, - CoglError **error) + GError **error) { CoglPipelineState state = COGL_PIPELINE_STATE_BLEND; CoglPipeline *authority; @@ -970,7 +610,7 @@ cogl_pipeline_set_blend (CoglPipeline *pipeline, _COGL_GET_CONTEXT (ctx, FALSE); - _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), FALSE); + g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); count = _cogl_blend_string_compile (blend_description, @@ -1043,10 +683,7 @@ cogl_pipeline_set_blend_constant (CoglPipeline *pipeline, { _COGL_GET_CONTEXT (ctx, NO_RETVAL); - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); - - if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_BLEND_CONSTANT)) - return; + g_return_if_fail (cogl_is_pipeline (pipeline)); #if defined(HAVE_COGL_GLES2) || defined(HAVE_COGL_GL) { @@ -1083,7 +720,7 @@ cogl_pipeline_get_user_program (CoglPipeline *pipeline) { CoglPipeline *authority; - _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), COGL_INVALID_HANDLE); + g_return_val_if_fail (cogl_is_pipeline (pipeline), NULL); authority = _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_USER_SHADER); @@ -1104,7 +741,7 @@ cogl_pipeline_set_user_program (CoglPipeline *pipeline, CoglPipelineState state = COGL_PIPELINE_STATE_USER_SHADER; CoglPipeline *authority; - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); + g_return_if_fail (cogl_is_pipeline (pipeline)); authority = _cogl_pipeline_get_authority (pipeline, state); @@ -1118,9 +755,6 @@ cogl_pipeline_set_user_program (CoglPipeline *pipeline, */ _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - if (program != COGL_INVALID_HANDLE) - _cogl_pipeline_set_progend (pipeline, COGL_PIPELINE_PROGEND_UNDEFINED); - /* If we are the current authority see if we can revert to one of our * ancestors being the authority */ if (pipeline == authority && @@ -1143,20 +777,20 @@ cogl_pipeline_set_user_program (CoglPipeline *pipeline, _cogl_pipeline_prune_redundant_ancestry (pipeline); } - if (program != COGL_INVALID_HANDLE) - cogl_handle_ref (program); + if (program != NULL) + cogl_object_ref (program); if (authority == pipeline && - pipeline->big_state->user_program != COGL_INVALID_HANDLE) - cogl_handle_unref (pipeline->big_state->user_program); + pipeline->big_state->user_program != NULL) + cogl_object_unref (pipeline->big_state->user_program); pipeline->big_state->user_program = program; pipeline->dirty_real_blend_enable = TRUE; } -CoglBool +gboolean cogl_pipeline_set_depth_state (CoglPipeline *pipeline, const CoglDepthState *depth_state, - CoglError **error) + GError **error) { CoglPipelineState state = COGL_PIPELINE_STATE_DEPTH; CoglPipeline *authority; @@ -1164,8 +798,8 @@ cogl_pipeline_set_depth_state (CoglPipeline *pipeline, _COGL_GET_CONTEXT (ctx, FALSE); - _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), FALSE); - _COGL_RETURN_VAL_IF_FAIL (depth_state->magic == COGL_DEPTH_STATE_MAGIC, FALSE); + g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); + g_return_val_if_fail (depth_state->magic == COGL_DEPTH_STATE_MAGIC, FALSE); authority = _cogl_pipeline_get_authority (pipeline, state); @@ -1177,17 +811,6 @@ cogl_pipeline_set_depth_state (CoglPipeline *pipeline, orig_state->range_far == depth_state->range_far) return TRUE; - if (ctx->driver == COGL_DRIVER_GLES1 && - (depth_state->range_near != 0 || - depth_state->range_far != 1)) - { - _cogl_set_error (error, - COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_UNSUPPORTED, - "glDepthRange not available on GLES 1"); - return FALSE; - } - /* - Flush journal primitives referencing the current state. * - Make sure the pipeline has no dependants so it may be modified. * - If the pipeline isn't currently an authority for the state being @@ -1209,91 +832,13 @@ cogl_pipeline_get_depth_state (CoglPipeline *pipeline, { CoglPipeline *authority; - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); + g_return_if_fail (cogl_is_pipeline (pipeline)); authority = _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_DEPTH); *state = authority->big_state->depth_state; } -CoglColorMask -cogl_pipeline_get_color_mask (CoglPipeline *pipeline) -{ - CoglPipeline *authority; - - _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), 0); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LOGIC_OPS); - - return authority->big_state->logic_ops_state.color_mask; -} - -void -cogl_pipeline_set_color_mask (CoglPipeline *pipeline, - CoglColorMask color_mask) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_LOGIC_OPS; - CoglPipeline *authority; - CoglPipelineLogicOpsState *logic_ops_state; - - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - logic_ops_state = &authority->big_state->logic_ops_state; - if (logic_ops_state->color_mask == color_mask) - return; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - logic_ops_state = &pipeline->big_state->logic_ops_state; - logic_ops_state->color_mask = color_mask; - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_logic_ops_state_equal); -} - -void -_cogl_pipeline_set_fog_state (CoglPipeline *pipeline, - const CoglPipelineFogState *fog_state) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_FOG; - CoglPipeline *authority; - CoglPipelineFogState *current_fog_state; - - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - current_fog_state = &authority->big_state->fog_state; - - if (current_fog_state->enabled == fog_state->enabled && - cogl_color_equal (¤t_fog_state->color, &fog_state->color) && - current_fog_state->mode == fog_state->mode && - current_fog_state->density == fog_state->density && - current_fog_state->z_near == fog_state->z_near && - current_fog_state->z_far == fog_state->z_far) - return; - - /* - Flush journal primitives referencing the current state. - * - Make sure the pipeline has no dependants so it may be modified. - * - If the pipeline isn't currently an authority for the state being - * changed, then initialize that state from the current authority. - */ - _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); - - pipeline->big_state->fog_state = *fog_state; - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_fog_state_equal); -} - void cogl_pipeline_set_cull_face_mode (CoglPipeline *pipeline, CoglPipelineCullFaceMode cull_face_mode) @@ -1302,7 +847,7 @@ cogl_pipeline_set_cull_face_mode (CoglPipeline *pipeline, CoglPipeline *authority; CoglPipelineCullFaceState *cull_face_state; - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); + g_return_if_fail (cogl_is_pipeline (pipeline)); authority = _cogl_pipeline_get_authority (pipeline, state); @@ -1332,7 +877,7 @@ cogl_pipeline_set_front_face_winding (CoglPipeline *pipeline, CoglPipeline *authority; CoglPipelineCullFaceState *cull_face_state; - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); + g_return_if_fail (cogl_is_pipeline (pipeline)); authority = _cogl_pipeline_get_authority (pipeline, state); @@ -1360,8 +905,8 @@ cogl_pipeline_get_cull_face_mode (CoglPipeline *pipeline) CoglPipelineState state = COGL_PIPELINE_STATE_CULL_FACE; CoglPipeline *authority; - _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), - COGL_PIPELINE_CULL_FACE_MODE_NONE); + g_return_val_if_fail (cogl_is_pipeline (pipeline), + COGL_PIPELINE_CULL_FACE_MODE_NONE); authority = _cogl_pipeline_get_authority (pipeline, state); @@ -1374,8 +919,8 @@ cogl_pipeline_get_front_face_winding (CoglPipeline *pipeline) CoglPipelineState state = COGL_PIPELINE_STATE_CULL_FACE; CoglPipeline *authority; - _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), - COGL_PIPELINE_CULL_FACE_MODE_NONE); + g_return_val_if_fail (cogl_is_pipeline (pipeline), + COGL_WINDING_CLOCKWISE); authority = _cogl_pipeline_get_authority (pipeline, state); @@ -1387,7 +932,7 @@ cogl_pipeline_get_point_size (CoglPipeline *pipeline) { CoglPipeline *authority; - _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), FALSE); + g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); authority = _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_POINT_SIZE); @@ -1397,12 +942,12 @@ cogl_pipeline_get_point_size (CoglPipeline *pipeline) static void _cogl_pipeline_set_non_zero_point_size (CoglPipeline *pipeline, - CoglBool value) + gboolean value) { CoglPipelineState state = COGL_PIPELINE_STATE_NON_ZERO_POINT_SIZE; CoglPipeline *authority; - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); + g_return_if_fail (cogl_is_pipeline (pipeline)); authority = _cogl_pipeline_get_authority (pipeline, state); @@ -1426,7 +971,7 @@ cogl_pipeline_set_point_size (CoglPipeline *pipeline, CoglPipelineState state = COGL_PIPELINE_STATE_POINT_SIZE; CoglPipeline *authority; - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); + g_return_if_fail (cogl_is_pipeline (pipeline)); authority = _cogl_pipeline_get_authority (pipeline, state); @@ -1452,16 +997,16 @@ cogl_pipeline_set_point_size (CoglPipeline *pipeline, _cogl_pipeline_point_size_equal); } -CoglBool +gboolean cogl_pipeline_set_per_vertex_point_size (CoglPipeline *pipeline, - CoglBool enable, - CoglError **error) + gboolean enable, + GError **error) { CoglPipelineState state = COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE; CoglPipeline *authority; _COGL_GET_CONTEXT (ctx, FALSE); - _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), FALSE); + g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); authority = _cogl_pipeline_get_authority (pipeline, state); @@ -1470,16 +1015,6 @@ cogl_pipeline_set_per_vertex_point_size (CoglPipeline *pipeline, if (authority->big_state->per_vertex_point_size == enable) return TRUE; - if (enable && !cogl_has_feature (ctx, COGL_FEATURE_ID_PER_VERTEX_POINT_SIZE)) - { - _cogl_set_error (error, - COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_UNSUPPORTED, - "Per-vertex point size is not supported"); - - return FALSE; - } - /* - Flush journal primitives referencing the current state. * - Make sure the pipeline has no dependants so it may be modified. * - If the pipeline isn't currently an authority for the state being @@ -1495,12 +1030,12 @@ cogl_pipeline_set_per_vertex_point_size (CoglPipeline *pipeline, return TRUE; } -CoglBool +gboolean cogl_pipeline_get_per_vertex_point_size (CoglPipeline *pipeline) { CoglPipeline *authority; - _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), FALSE); + g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); authority = _cogl_pipeline_get_authority (pipeline, @@ -1571,7 +1106,7 @@ _cogl_pipeline_override_uniform (CoglPipeline *pipeline, old_values + override_index, sizeof (CoglBoxedValue) * (old_size - override_index)); - free (old_values); + g_free (old_values); } _cogl_boxed_value_init (uniforms_state->override_values + override_index); @@ -1638,7 +1173,7 @@ cogl_pipeline_set_uniform_matrix (CoglPipeline *pipeline, int uniform_location, int dimensions, int count, - CoglBool transpose, + gboolean transpose, const float *value) { CoglBoxedValue *boxed_value; @@ -1700,7 +1235,7 @@ cogl_pipeline_add_snippet (CoglPipeline *pipeline, _cogl_pipeline_add_fragment_snippet (pipeline, snippet); } -CoglBool +gboolean _cogl_pipeline_has_non_layer_vertex_snippets (CoglPipeline *pipeline) { CoglPipeline *authority = @@ -1710,14 +1245,14 @@ _cogl_pipeline_has_non_layer_vertex_snippets (CoglPipeline *pipeline) return authority->big_state->vertex_snippets.entries != NULL; } -static CoglBool +static gboolean check_layer_has_vertex_snippet (CoglPipelineLayer *layer, void *user_data) { unsigned long state = COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS; CoglPipelineLayer *authority = _cogl_pipeline_layer_get_authority (layer, state); - CoglBool *found_vertex_snippet = user_data; + gboolean *found_vertex_snippet = user_data; if (authority->big_state->vertex_snippets.entries) { @@ -1728,10 +1263,10 @@ check_layer_has_vertex_snippet (CoglPipelineLayer *layer, return TRUE; } -CoglBool +gboolean _cogl_pipeline_has_vertex_snippets (CoglPipeline *pipeline) { - CoglBool found_vertex_snippet = FALSE; + gboolean found_vertex_snippet = FALSE; if (_cogl_pipeline_has_non_layer_vertex_snippets (pipeline)) return TRUE; @@ -1743,7 +1278,7 @@ _cogl_pipeline_has_vertex_snippets (CoglPipeline *pipeline) return found_vertex_snippet; } -CoglBool +gboolean _cogl_pipeline_has_non_layer_fragment_snippets (CoglPipeline *pipeline) { CoglPipeline *authority = @@ -1753,14 +1288,14 @@ _cogl_pipeline_has_non_layer_fragment_snippets (CoglPipeline *pipeline) return authority->big_state->fragment_snippets.entries != NULL; } -static CoglBool +static gboolean check_layer_has_fragment_snippet (CoglPipelineLayer *layer, void *user_data) { unsigned long state = COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS; CoglPipelineLayer *authority = _cogl_pipeline_layer_get_authority (layer, state); - CoglBool *found_fragment_snippet = user_data; + gboolean *found_fragment_snippet = user_data; if (authority->big_state->fragment_snippets.entries) { @@ -1771,10 +1306,10 @@ check_layer_has_fragment_snippet (CoglPipelineLayer *layer, return TRUE; } -CoglBool +gboolean _cogl_pipeline_has_fragment_snippets (CoglPipeline *pipeline) { - CoglBool found_fragment_snippet = FALSE; + gboolean found_fragment_snippet = FALSE; if (_cogl_pipeline_has_non_layer_fragment_snippets (pipeline)) return TRUE; @@ -1794,25 +1329,6 @@ _cogl_pipeline_hash_color_state (CoglPipeline *authority, _COGL_COLOR_DATA_SIZE); } -void -_cogl_pipeline_hash_blend_enable_state (CoglPipeline *authority, - CoglPipelineHashState *state) -{ - uint8_t blend_enable = authority->blend_enable; - state->hash = _cogl_util_one_at_a_time_hash (state->hash, &blend_enable, 1); -} - -void -_cogl_pipeline_hash_lighting_state (CoglPipeline *authority, - CoglPipelineHashState *state) -{ - CoglPipelineLightingState *lighting_state = - &authority->big_state->lighting_state; - state->hash = - _cogl_util_one_at_a_time_hash (state->hash, lighting_state, - sizeof (CoglPipelineLightingState)); -} - void _cogl_pipeline_hash_alpha_func_state (CoglPipeline *authority, CoglPipelineHashState *state) @@ -1917,28 +1433,11 @@ _cogl_pipeline_hash_depth_state (CoglPipeline *authority, state->hash = hash; } -void -_cogl_pipeline_hash_fog_state (CoglPipeline *authority, - CoglPipelineHashState *state) -{ - CoglPipelineFogState *fog_state = &authority->big_state->fog_state; - unsigned long hash = state->hash; - - if (!fog_state->enabled) - hash = _cogl_util_one_at_a_time_hash (hash, &fog_state->enabled, - sizeof (fog_state->enabled)); - else - hash = _cogl_util_one_at_a_time_hash (hash, &fog_state, - sizeof (CoglPipelineFogState)); - - state->hash = hash; -} - void _cogl_pipeline_hash_non_zero_point_size_state (CoglPipeline *authority, CoglPipelineHashState *state) { - CoglBool non_zero_point_size = authority->big_state->non_zero_point_size; + gboolean non_zero_point_size = authority->big_state->non_zero_point_size; state->hash = _cogl_util_one_at_a_time_hash (state->hash, &non_zero_point_size, @@ -1958,21 +1457,12 @@ void _cogl_pipeline_hash_per_vertex_point_size_state (CoglPipeline *authority, CoglPipelineHashState *state) { - CoglBool per_vertex_point_size = authority->big_state->per_vertex_point_size; + gboolean per_vertex_point_size = authority->big_state->per_vertex_point_size; state->hash = _cogl_util_one_at_a_time_hash (state->hash, &per_vertex_point_size, sizeof (per_vertex_point_size)); } -void -_cogl_pipeline_hash_logic_ops_state (CoglPipeline *authority, - CoglPipelineHashState *state) -{ - CoglPipelineLogicOpsState *logic_ops_state = &authority->big_state->logic_ops_state; - state->hash = _cogl_util_one_at_a_time_hash (state->hash, &logic_ops_state->color_mask, - sizeof (CoglColorMask)); -} - void _cogl_pipeline_hash_cull_face_state (CoglPipeline *authority, CoglPipelineHashState *state) diff --git a/cogl/cogl/cogl-pipeline-state.h b/cogl/cogl/cogl-pipeline-state.h index 67e6ef814..286f673c1 100644 --- a/cogl/cogl/cogl-pipeline-state.h +++ b/cogl/cogl/cogl-pipeline-state.h @@ -39,7 +39,7 @@ #include #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS /** * cogl_pipeline_set_color: @@ -58,7 +58,7 @@ COGL_BEGIN_DECLS * Since: 2.0 * Stability: Unstable */ -void +COGL_EXPORT void cogl_pipeline_set_color (CoglPipeline *pipeline, const CoglColor *color); @@ -77,7 +77,7 @@ cogl_pipeline_set_color (CoglPipeline *pipeline, * Since: 2.0 * Stability: Unstable */ -void +COGL_EXPORT void cogl_pipeline_set_color4ub (CoglPipeline *pipeline, uint8_t red, uint8_t green, @@ -99,7 +99,7 @@ cogl_pipeline_set_color4ub (CoglPipeline *pipeline, * Since: 2.0 * Stability: Unstable */ -void +COGL_EXPORT void cogl_pipeline_set_color4f (CoglPipeline *pipeline, float red, float green, @@ -116,193 +116,10 @@ cogl_pipeline_set_color4f (CoglPipeline *pipeline, * Since: 2.0 * Stability: Unstable */ -void +COGL_EXPORT void cogl_pipeline_get_color (CoglPipeline *pipeline, CoglColor *color); -/** - * cogl_pipeline_set_ambient: - * @pipeline: A #CoglPipeline object - * @ambient: The components of the desired ambient color - * - * Sets the pipeline's ambient color, in the standard OpenGL lighting - * model. The ambient color affects the overall color of the object. - * - * Since the diffuse color will be intense when the light hits the surface - * directly, the ambient will be most apparent where the light hits at a - * slant. - * - * The default value is (0.2, 0.2, 0.2, 1.0) - * - * Since: 2.0 - * Stability: Unstable - */ -void -cogl_pipeline_set_ambient (CoglPipeline *pipeline, - const CoglColor *ambient); - -/** - * cogl_pipeline_get_ambient: - * @pipeline: A #CoglPipeline object - * @ambient: The location to store the ambient color - * - * Retrieves the current ambient color for @pipeline - * - * Since: 2.0 - * Stability: Unstable - */ -void -cogl_pipeline_get_ambient (CoglPipeline *pipeline, - CoglColor *ambient); - -/** - * cogl_pipeline_set_diffuse: - * @pipeline: A #CoglPipeline object - * @diffuse: The components of the desired diffuse color - * - * Sets the pipeline's diffuse color, in the standard OpenGL lighting - * model. The diffuse color is most intense where the light hits the - * surface directly - perpendicular to the surface. - * - * The default value is (0.8, 0.8, 0.8, 1.0) - * - * Since: 2.0 - * Stability: Unstable - */ -void -cogl_pipeline_set_diffuse (CoglPipeline *pipeline, - const CoglColor *diffuse); - -/** - * cogl_pipeline_get_diffuse: - * @pipeline: A #CoglPipeline object - * @diffuse: The location to store the diffuse color - * - * Retrieves the current diffuse color for @pipeline - * - * Since: 2.0 - * Stability: Unstable - */ -void -cogl_pipeline_get_diffuse (CoglPipeline *pipeline, - CoglColor *diffuse); - -/** - * cogl_pipeline_set_ambient_and_diffuse: - * @pipeline: A #CoglPipeline object - * @color: The components of the desired ambient and diffuse colors - * - * Conveniently sets the diffuse and ambient color of @pipeline at the same - * time. See cogl_pipeline_set_ambient() and cogl_pipeline_set_diffuse(). - * - * The default ambient color is (0.2, 0.2, 0.2, 1.0) - * - * The default diffuse color is (0.8, 0.8, 0.8, 1.0) - * - * Since: 2.0 - * Stability: Unstable - */ -void -cogl_pipeline_set_ambient_and_diffuse (CoglPipeline *pipeline, - const CoglColor *color); - -/** - * cogl_pipeline_set_specular: - * @pipeline: A #CoglPipeline object - * @specular: The components of the desired specular color - * - * Sets the pipeline's specular color, in the standard OpenGL lighting - * model. The intensity of the specular color depends on the viewport - * position, and is brightest along the lines of reflection. - * - * The default value is (0.0, 0.0, 0.0, 1.0) - * - * Since: 2.0 - * Stability: Unstable - */ -void -cogl_pipeline_set_specular (CoglPipeline *pipeline, - const CoglColor *specular); - -/** - * cogl_pipeline_get_specular: - * @pipeline: A #CoglPipeline object - * @specular: The location to store the specular color - * - * Retrieves the pipelines current specular color. - * - * Since: 2.0 - * Stability: Unstable - */ -void -cogl_pipeline_get_specular (CoglPipeline *pipeline, - CoglColor *specular); - -/** - * cogl_pipeline_set_shininess: - * @pipeline: A #CoglPipeline object - * @shininess: The desired shininess; must be >= 0.0 - * - * Sets the shininess of the pipeline, in the standard OpenGL lighting - * model, which determines the size of the specular highlights. A - * higher @shininess will produce smaller highlights which makes the - * object appear more shiny. - * - * The default value is 0.0 - * - * Since: 2.0 - * Stability: Unstable - */ -void -cogl_pipeline_set_shininess (CoglPipeline *pipeline, - float shininess); - -/** - * cogl_pipeline_get_shininess: - * @pipeline: A #CoglPipeline object - * - * Retrieves the pipelines current emission color. - * - * Return value: The pipelines current shininess value - * - * Since: 2.0 - * Stability: Unstable - */ -float -cogl_pipeline_get_shininess (CoglPipeline *pipeline); - -/** - * cogl_pipeline_set_emission: - * @pipeline: A #CoglPipeline object - * @emission: The components of the desired emissive color - * - * Sets the pipeline's emissive color, in the standard OpenGL lighting - * model. It will look like the surface is a light source emitting this - * color. - * - * The default value is (0.0, 0.0, 0.0, 1.0) - * - * Since: 2.0 - * Stability: Unstable - */ -void -cogl_pipeline_set_emission (CoglPipeline *pipeline, - const CoglColor *emission); - -/** - * cogl_pipeline_get_emission: - * @pipeline: A #CoglPipeline object - * @emission: The location to store the emission color - * - * Retrieves the pipelines current emission color. - * - * Since: 2.0 - * Stability: Unstable - */ -void -cogl_pipeline_get_emission (CoglPipeline *pipeline, - CoglColor *emission); - /** * CoglPipelineAlphaFunc: * @COGL_PIPELINE_ALPHA_FUNC_NEVER: Never let the fragment through. @@ -325,7 +142,8 @@ cogl_pipeline_get_emission (CoglPipeline *pipeline, * incoming alpha value and a reference alpha value. The #CoglPipelineAlphaFunc * determines how the comparison is done. */ -typedef enum { +typedef enum +{ COGL_PIPELINE_ALPHA_FUNC_NEVER = 0x0200, COGL_PIPELINE_ALPHA_FUNC_LESS = 0x0201, COGL_PIPELINE_ALPHA_FUNC_EQUAL = 0x0202, @@ -355,7 +173,7 @@ typedef enum { * Since: 2.0 * Stability: Unstable */ -void +COGL_EXPORT void cogl_pipeline_set_alpha_test_function (CoglPipeline *pipeline, CoglPipelineAlphaFunc alpha_func, float alpha_reference); @@ -369,7 +187,7 @@ cogl_pipeline_set_alpha_test_function (CoglPipeline *pipeline, * Since: 2.0 * Stability: Unstable */ -CoglPipelineAlphaFunc +COGL_EXPORT CoglPipelineAlphaFunc cogl_pipeline_get_alpha_test_function (CoglPipeline *pipeline); /** @@ -381,7 +199,7 @@ cogl_pipeline_get_alpha_test_function (CoglPipeline *pipeline); * Since: 2.0 * Stability: Unstable */ -float +COGL_EXPORT float cogl_pipeline_get_alpha_test_reference (CoglPipeline *pipeline); /** @@ -389,7 +207,7 @@ cogl_pipeline_get_alpha_test_reference (CoglPipeline *pipeline); * @pipeline: A #CoglPipeline object * @blend_string: A Cogl blend string * describing the desired blend function. - * @error: return location for a #CoglError that may report lack of driver + * @error: return location for a #GError that may report lack of driver * support if you give separate blend string statements for the alpha * channel and RGB channels since some drivers, or backends such as * GLES 1.1, don't support this feature. May be %NULL, in which case a @@ -466,10 +284,10 @@ cogl_pipeline_get_alpha_test_reference (CoglPipeline *pipeline); * Since: 2.0 * Stability: Unstable */ -CoglBool +COGL_EXPORT gboolean cogl_pipeline_set_blend (CoglPipeline *pipeline, const char *blend_string, - CoglError **error); + GError **error); /** * cogl_pipeline_set_blend_constant: @@ -482,7 +300,7 @@ cogl_pipeline_set_blend (CoglPipeline *pipeline, * Since: 2.0 * Stability: Unstable */ -void +COGL_EXPORT void cogl_pipeline_set_blend_constant (CoglPipeline *pipeline, const CoglColor *constant_color); @@ -507,7 +325,7 @@ cogl_pipeline_set_blend_constant (CoglPipeline *pipeline, * Since: 2.0 * Stability: Unstable */ -void +COGL_EXPORT void cogl_pipeline_set_point_size (CoglPipeline *pipeline, float point_size); @@ -523,14 +341,14 @@ cogl_pipeline_set_point_size (CoglPipeline *pipeline, * Since: 2.0 * Stability: Unstable */ -float +COGL_EXPORT float cogl_pipeline_get_point_size (CoglPipeline *pipeline); /** * cogl_pipeline_set_per_vertex_point_size: * @pipeline: a #CoglPipeline pointer * @enable: whether to enable per-vertex point size - * @error: a location to store a #CoglError if the change failed + * @error: a location to store a #GError if the change failed * * Sets whether to use a per-vertex point size or to use the value set * by cogl_pipeline_set_point_size(). If per-vertex point size is @@ -543,19 +361,14 @@ cogl_pipeline_get_point_size (CoglPipeline *pipeline); * and cogl_point_size_out is not written to then the results are * undefined. * - * Note that enabling this will only work if the - * %COGL_FEATURE_ID_PER_VERTEX_POINT_SIZE feature is available. If - * this is not available then the function will return %FALSE and set - * a #CoglError. - * * Since: 2.0 * Stability: Unstable * Return value: %TRUE if the change suceeded or %FALSE otherwise */ -CoglBool +COGL_EXPORT gboolean cogl_pipeline_set_per_vertex_point_size (CoglPipeline *pipeline, - CoglBool enable, - CoglError **error); + gboolean enable, + GError **error); /** * cogl_pipeline_get_per_vertex_point_size: @@ -567,41 +380,9 @@ cogl_pipeline_set_per_vertex_point_size (CoglPipeline *pipeline, * enabled or %FALSE otherwise. The per-vertex point size can be * enabled with cogl_pipeline_set_per_vertex_point_size(). */ -CoglBool +COGL_EXPORT gboolean cogl_pipeline_get_per_vertex_point_size (CoglPipeline *pipeline); -/** - * cogl_pipeline_get_color_mask: - * @pipeline: a #CoglPipeline object. - * - * Gets the current #CoglColorMask of which channels would be written to the - * current framebuffer. Each bit set in the mask means that the - * corresponding color would be written. - * - * Returns: A #CoglColorMask - * Since: 1.8 - * Stability: unstable - */ -CoglColorMask -cogl_pipeline_get_color_mask (CoglPipeline *pipeline); - -/** - * cogl_pipeline_set_color_mask: - * @pipeline: a #CoglPipeline object. - * @color_mask: A #CoglColorMask of which color channels to write to - * the current framebuffer. - * - * Defines a bit mask of which color channels should be written to the - * current framebuffer. If a bit is set in @color_mask that means that - * color will be written. - * - * Since: 1.8 - * Stability: unstable - */ -void -cogl_pipeline_set_color_mask (CoglPipeline *pipeline, - CoglColorMask color_mask); - /** * cogl_pipeline_get_user_program: * @pipeline: a #CoglPipeline object. @@ -609,12 +390,12 @@ cogl_pipeline_set_color_mask (CoglPipeline *pipeline, * Queries what user program has been associated with the given * @pipeline using cogl_pipeline_set_user_program(). * - * Return value: (transfer none): The current user program or %COGL_INVALID_HANDLE. + * Return value: (transfer none): The current user program or %NULL. * * Since: 2.0 * Stability: Unstable */ -CoglHandle +COGL_EXPORT CoglHandle cogl_pipeline_get_user_program (CoglPipeline *pipeline); /** @@ -637,7 +418,6 @@ cogl_pipeline_get_user_program (CoglPipeline *pipeline); * "!!ARBfp1.0\n" * "MOV result.color,fragment.color;\n" * "END\n"); - * cogl_shader_compile (shader); * * program = cogl_create_program (); * cogl_program_attach_shader (program, shader); @@ -657,22 +437,18 @@ cogl_pipeline_get_user_program (CoglPipeline *pipeline); * meantime we hope this will handle most practical GLSL and ARBfp * requirements. * - * Also remember you need to check for either the - * %COGL_FEATURE_SHADERS_GLSL or %COGL_FEATURE_SHADERS_ARBFP before - * using the cogl_program or cogl_shader API. - * * Since: 2.0 * Stability: Unstable */ -void +COGL_EXPORT void cogl_pipeline_set_user_program (CoglPipeline *pipeline, CoglHandle program); /** - * cogl_pipeline_set_depth_state: + * cogl_pipeline_set_depth_state: (skip) * @pipeline: A #CoglPipeline object * @state: A #CoglDepthState struct - * @error: A #CoglError to report failures to setup the given @state. + * @error: A #GError to report failures to setup the given @state. * * This commits all the depth state configured in @state struct to the * given @pipeline. The configuration values are copied into the @@ -688,13 +464,13 @@ cogl_pipeline_set_user_program (CoglPipeline *pipeline, * Since: 2.0 * Stability: Unstable */ -CoglBool +COGL_EXPORT gboolean cogl_pipeline_set_depth_state (CoglPipeline *pipeline, const CoglDepthState *state, - CoglError **error); + GError **error); /** - * cogl_pipeline_get_depth_state: + * cogl_pipeline_get_depth_state: (skip) * @pipeline: A #CoglPipeline object * @state_out: (out): A destination #CoglDepthState struct * @@ -704,7 +480,7 @@ cogl_pipeline_set_depth_state (CoglPipeline *pipeline, * Since: 2.0 * Stability: Unstable */ -void +COGL_EXPORT void cogl_pipeline_get_depth_state (CoglPipeline *pipeline, CoglDepthState *state_out); @@ -748,7 +524,7 @@ typedef enum * Status: Unstable * Since: 2.0 */ -void +COGL_EXPORT void cogl_pipeline_set_cull_face_mode (CoglPipeline *pipeline, CoglPipelineCullFaceMode cull_face_mode); @@ -761,7 +537,7 @@ cogl_pipeline_set_cull_face_mode (CoglPipeline *pipeline, * Status: Unstable * Since: 2.0 */ -CoglPipelineCullFaceMode +COGL_EXPORT CoglPipelineCullFaceMode cogl_pipeline_get_cull_face_mode (CoglPipeline *pipeline); /** @@ -780,7 +556,7 @@ cogl_pipeline_get_cull_face_mode (CoglPipeline *pipeline); * Status: Unstable * Since: 2.0 */ -void +COGL_EXPORT void cogl_pipeline_set_front_face_winding (CoglPipeline *pipeline, CoglWinding front_winding); @@ -801,7 +577,7 @@ cogl_pipeline_set_front_face_winding (CoglPipeline *pipeline, * Status: Unstable * Since: 2.0 */ -CoglWinding +COGL_EXPORT CoglWinding cogl_pipeline_get_front_face_winding (CoglPipeline *pipeline); /** @@ -824,7 +600,7 @@ cogl_pipeline_get_front_face_winding (CoglPipeline *pipeline); * Since: 2.0 * Stability: Unstable */ -void +COGL_EXPORT void cogl_pipeline_set_uniform_1f (CoglPipeline *pipeline, int uniform_location, float value); @@ -849,7 +625,7 @@ cogl_pipeline_set_uniform_1f (CoglPipeline *pipeline, * Since: 2.0 * Stability: Unstable */ -void +COGL_EXPORT void cogl_pipeline_set_uniform_1i (CoglPipeline *pipeline, int uniform_location, int value); @@ -878,7 +654,7 @@ cogl_pipeline_set_uniform_1i (CoglPipeline *pipeline, * Since: 2.0 * Stability: Unstable */ -void +COGL_EXPORT void cogl_pipeline_set_uniform_float (CoglPipeline *pipeline, int uniform_location, int n_components, @@ -909,7 +685,7 @@ cogl_pipeline_set_uniform_float (CoglPipeline *pipeline, * Since: 2.0 * Stability: Unstable */ -void +COGL_EXPORT void cogl_pipeline_set_uniform_int (CoglPipeline *pipeline, int uniform_location, int n_components, @@ -946,16 +722,16 @@ cogl_pipeline_set_uniform_int (CoglPipeline *pipeline, * Since: 2.0 * Stability: Unstable */ -void +COGL_EXPORT void cogl_pipeline_set_uniform_matrix (CoglPipeline *pipeline, int uniform_location, int dimensions, int count, - CoglBool transpose, + gboolean transpose, const float *value); /** - * cogl_pipeline_add_snippet: + * cogl_pipeline_add_snippet: (skip) * @pipeline: A #CoglPipeline * @snippet: The #CoglSnippet to add to the vertex processing hook * @@ -967,10 +743,10 @@ cogl_pipeline_set_uniform_matrix (CoglPipeline *pipeline, * Since: 1.10 * Stability: Unstable */ -void +COGL_EXPORT void cogl_pipeline_add_snippet (CoglPipeline *pipeline, CoglSnippet *snippet); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_PIPELINE_STATE_H__ */ diff --git a/cogl/cogl/cogl-pipeline.c b/cogl/cogl/cogl-pipeline.c index 5bc286607..3b911b83f 100644 --- a/cogl/cogl/cogl-pipeline.c +++ b/cogl/cogl/cogl-pipeline.c @@ -31,16 +31,13 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-debug.h" #include "cogl-context-private.h" #include "cogl-object.h" #include "cogl-pipeline-private.h" -#include "cogl-pipeline-opengl-private.h" #include "cogl-pipeline-state-private.h" #include "cogl-pipeline-layer-state-private.h" #include "cogl-texture-private.h" @@ -59,41 +56,15 @@ static void _cogl_pipeline_free (CoglPipeline *tex); static void recursively_free_layer_caches (CoglPipeline *pipeline); -static CoglBool _cogl_pipeline_is_weak (CoglPipeline *pipeline); - -const CoglPipelineFragend *_cogl_pipeline_fragends[COGL_PIPELINE_N_FRAGENDS]; -const CoglPipelineVertend *_cogl_pipeline_vertends[COGL_PIPELINE_N_VERTENDS]; -/* The 'MAX' here is so that we don't define an empty array when there - are no progends */ -const CoglPipelineProgend * -_cogl_pipeline_progends[MAX (COGL_PIPELINE_N_PROGENDS, 1)]; +static gboolean _cogl_pipeline_is_weak (CoglPipeline *pipeline); -#ifdef COGL_PIPELINE_FRAGEND_GLSL -#include "cogl-pipeline-fragend-glsl-private.h" -#endif -#ifdef COGL_PIPELINE_FRAGEND_ARBFP -#include "cogl-pipeline-fragend-arbfp-private.h" -#endif -#ifdef COGL_PIPELINE_FRAGEND_FIXED -#include "cogl-pipeline-fragend-fixed-private.h" -#endif +const CoglPipelineFragend *_cogl_pipeline_fragend; +const CoglPipelineVertend *_cogl_pipeline_vertend; +const CoglPipelineProgend *_cogl_pipeline_progend; -#ifdef COGL_PIPELINE_VERTEND_GLSL -#include "cogl-pipeline-vertend-glsl-private.h" -#endif -#ifdef COGL_PIPELINE_VERTEND_FIXED -#include "cogl-pipeline-vertend-fixed-private.h" -#endif - -#ifdef COGL_PIPELINE_PROGEND_FIXED_ARBFP -#include "cogl-pipeline-progend-fixed-arbfp-private.h" -#endif -#ifdef COGL_PIPELINE_PROGEND_FIXED -#include "cogl-pipeline-progend-fixed-private.h" -#endif -#ifdef COGL_PIPELINE_PROGEND_GLSL -#include "cogl-pipeline-progend-glsl-private.h" -#endif +#include "driver/gl/cogl-pipeline-fragend-glsl-private.h" +#include "driver/gl/cogl-pipeline-vertend-glsl-private.h" +#include "driver/gl/cogl-pipeline-progend-glsl-private.h" COGL_OBJECT_DEFINE (Pipeline, pipeline); COGL_GTYPE_DEFINE_CLASS (Pipeline, pipeline); @@ -113,60 +84,26 @@ _cogl_pipeline_init_default_pipeline (void) /* XXX: NB: It's important that we zero this to avoid polluting * pipeline hash values with un-initialized data */ CoglPipelineBigState *big_state = g_slice_new0 (CoglPipelineBigState); - CoglPipelineLightingState *lighting_state = &big_state->lighting_state; CoglPipelineAlphaFuncState *alpha_state = &big_state->alpha_state; CoglPipelineBlendState *blend_state = &big_state->blend_state; - CoglPipelineLogicOpsState *logic_ops_state = &big_state->logic_ops_state; CoglPipelineCullFaceState *cull_face_state = &big_state->cull_face_state; CoglPipelineUniformsState *uniforms_state = &big_state->uniforms_state; _COGL_GET_CONTEXT (ctx, NO_RETVAL); /* Take this opportunity to setup the backends... */ -#ifdef COGL_PIPELINE_FRAGEND_GLSL - _cogl_pipeline_fragends[COGL_PIPELINE_FRAGEND_GLSL] = - &_cogl_pipeline_glsl_fragend; -#endif -#ifdef COGL_PIPELINE_FRAGEND_ARBFP - _cogl_pipeline_fragends[COGL_PIPELINE_FRAGEND_ARBFP] = - &_cogl_pipeline_arbfp_fragend; -#endif -#ifdef COGL_PIPELINE_FRAGEND_FIXED - _cogl_pipeline_fragends[COGL_PIPELINE_FRAGEND_FIXED] = - &_cogl_pipeline_fixed_fragend; -#endif -#ifdef COGL_PIPELINE_PROGEND_FIXED - _cogl_pipeline_progends[COGL_PIPELINE_PROGEND_FIXED_ARBFP] = - &_cogl_pipeline_fixed_arbfp_progend; -#endif -#ifdef COGL_PIPELINE_PROGEND_FIXED - _cogl_pipeline_progends[COGL_PIPELINE_PROGEND_FIXED] = - &_cogl_pipeline_fixed_progend; -#endif -#ifdef COGL_PIPELINE_PROGEND_GLSL - _cogl_pipeline_progends[COGL_PIPELINE_PROGEND_GLSL] = - &_cogl_pipeline_glsl_progend; -#endif - -#ifdef COGL_PIPELINE_VERTEND_GLSL - _cogl_pipeline_vertends[COGL_PIPELINE_VERTEND_GLSL] = - &_cogl_pipeline_glsl_vertend; -#endif -#ifdef COGL_PIPELINE_VERTEND_FIXED - _cogl_pipeline_vertends[COGL_PIPELINE_VERTEND_FIXED] = - &_cogl_pipeline_fixed_vertend; -#endif + _cogl_pipeline_fragend = &_cogl_pipeline_glsl_fragend; + _cogl_pipeline_progend = &_cogl_pipeline_glsl_progend; + _cogl_pipeline_vertend = &_cogl_pipeline_glsl_vertend; _cogl_pipeline_node_init (COGL_NODE (pipeline)); pipeline->is_weak = FALSE; pipeline->journal_ref_count = 0; - pipeline->progend = COGL_PIPELINE_PROGEND_UNDEFINED; pipeline->differences = COGL_PIPELINE_STATE_ALL_SPARSE; pipeline->real_blend_enable = FALSE; - pipeline->blend_enable = COGL_PIPELINE_BLEND_ENABLE_AUTOMATIC; pipeline->layer_differences = NULL; pipeline->n_layers = 0; @@ -181,29 +118,6 @@ _cogl_pipeline_init_default_pipeline (void) /* Use the same defaults as the GL spec... */ cogl_color_init_from_4ub (&pipeline->color, 0xff, 0xff, 0xff, 0xff); - /* Use the same defaults as the GL spec... */ - lighting_state->ambient[0] = 0.2; - lighting_state->ambient[1] = 0.2; - lighting_state->ambient[2] = 0.2; - lighting_state->ambient[3] = 1.0; - - lighting_state->diffuse[0] = 0.8; - lighting_state->diffuse[1] = 0.8; - lighting_state->diffuse[2] = 0.8; - lighting_state->diffuse[3] = 1.0; - - lighting_state->specular[0] = 0; - lighting_state->specular[1] = 0; - lighting_state->specular[2] = 0; - lighting_state->specular[3] = 1.0; - - lighting_state->emission[0] = 0; - lighting_state->emission[1] = 0; - lighting_state->emission[2] = 0; - lighting_state->emission[3] = 1.0; - - lighting_state->shininess = 0.0f; - /* Use the same defaults as the GL spec... */ alpha_state->alpha_func = COGL_PIPELINE_ALPHA_FUNC_ALWAYS; alpha_state->alpha_func_reference = 0.0; @@ -220,14 +134,12 @@ _cogl_pipeline_init_default_pipeline (void) blend_state->blend_src_factor_rgb = GL_ONE; blend_state->blend_dst_factor_rgb = GL_ONE_MINUS_SRC_ALPHA; - big_state->user_program = COGL_INVALID_HANDLE; + big_state->user_program = NULL; cogl_depth_state_init (&big_state->depth_state); big_state->point_size = 0.0f; - logic_ops_state->color_mask = COGL_COLOR_MASK_ALL; - cull_face_state->mode = COGL_PIPELINE_CULL_FACE_MODE_NONE; cull_face_state->front_winding = COGL_WINDING_COUNTER_CLOCKWISE; @@ -245,7 +157,7 @@ _cogl_pipeline_unparent (CoglNode *pipeline) _cogl_pipeline_node_unparent_real (pipeline); } -static CoglBool +static gboolean recursively_free_layer_caches_cb (CoglNode *node, void *user_data) { @@ -280,7 +192,7 @@ recursively_free_layer_caches (CoglPipeline *pipeline) static void _cogl_pipeline_set_parent (CoglPipeline *pipeline, CoglPipeline *parent, - CoglBool take_strong_reference) + gboolean take_strong_reference) { /* Chain up */ _cogl_pipeline_node_set_parent_real (COGL_NODE (pipeline), @@ -292,23 +204,6 @@ _cogl_pipeline_set_parent (CoglPipeline *pipeline, * layers could now be invalid so free it... */ if (pipeline->differences & COGL_PIPELINE_STATE_LAYERS) recursively_free_layer_caches (pipeline); - - /* If the backends are also caching state along with the pipeline - * that depends on the pipeline's ancestry then it may be notified - * here... - */ - if (pipeline->progend != COGL_PIPELINE_PROGEND_UNDEFINED) - { - const CoglPipelineProgend *progend = - _cogl_pipeline_progends[pipeline->progend]; - const CoglPipelineFragend *fragend = - _cogl_pipeline_fragends[progend->fragend]; - - /* Currently only the fragends ever care about reparenting of - * pipelines... */ - if (fragend->pipeline_set_parent_notify) - fragend->pipeline_set_parent_notify (pipeline); - } } static void @@ -316,7 +211,7 @@ _cogl_pipeline_promote_weak_ancestors (CoglPipeline *strong) { CoglNode *n; - _COGL_RETURN_IF_FAIL (!strong->is_weak); + g_return_if_fail (!strong->is_weak); /* If the parent of strong is weak, then we want to promote it by taking a reference on strong's grandparent. We don't need to take @@ -338,7 +233,7 @@ _cogl_pipeline_revert_weak_ancestors (CoglPipeline *strong) { CoglNode *n; - _COGL_RETURN_IF_FAIL (!strong->is_weak); + g_return_if_fail (!strong->is_weak); /* This reverts the effect of calling _cogl_pipeline_promote_weak_ancestors */ @@ -357,7 +252,7 @@ _cogl_pipeline_revert_weak_ancestors (CoglPipeline *strong) /* XXX: Always have an eye out for opportunities to lower the cost of * cogl_pipeline_copy. */ static CoglPipeline * -_cogl_pipeline_copy (CoglPipeline *src, CoglBool is_weak) +_cogl_pipeline_copy (CoglPipeline *src, gboolean is_weak) { CoglPipeline *pipeline = g_slice_new (CoglPipeline); @@ -385,10 +280,6 @@ _cogl_pipeline_copy (CoglPipeline *src, CoglBool is_weak) */ pipeline->layers_cache_dirty = TRUE; - pipeline->deprecated_get_layers_list = NULL; - pipeline->deprecated_get_layers_list_dirty = TRUE; - - pipeline->progend = src->progend; pipeline->has_static_breadcrumb = FALSE; @@ -439,7 +330,7 @@ cogl_pipeline_new (CoglContext *context) return new; } -static CoglBool +static gboolean destroy_weak_children_cb (CoglNode *node, void *user_data) { @@ -475,7 +366,7 @@ _cogl_pipeline_free (CoglPipeline *pipeline) if (pipeline->differences & COGL_PIPELINE_STATE_USER_SHADER && pipeline->big_state->user_program) - cogl_handle_unref (pipeline->big_state->user_program); + cogl_object_unref (pipeline->big_state->user_program); if (pipeline->differences & COGL_PIPELINE_STATE_UNIFORMS) { @@ -486,21 +377,14 @@ _cogl_pipeline_free (CoglPipeline *pipeline) for (i = 0; i < n_overrides; i++) _cogl_boxed_value_destroy (uniforms_state->override_values + i); - free (uniforms_state->override_values); + g_free (uniforms_state->override_values); _cogl_bitmask_destroy (&uniforms_state->override_mask); _cogl_bitmask_destroy (&uniforms_state->changed_mask); } - if (pipeline->differences & COGL_PIPELINE_STATE_NEEDS_BIG_STATE) - g_slice_free (CoglPipelineBigState, pipeline->big_state); - if (pipeline->differences & COGL_PIPELINE_STATE_LAYERS) - { - g_list_foreach (pipeline->layer_differences, - (GFunc)cogl_object_unref, NULL); - g_list_free (pipeline->layer_differences); - } + g_list_free_full (pipeline->layer_differences, cogl_object_unref); if (pipeline->differences & COGL_PIPELINE_STATE_VERTEX_SNIPPETS) _cogl_pipeline_snippet_list_free (&pipeline->big_state->vertex_snippets); @@ -508,17 +392,18 @@ _cogl_pipeline_free (CoglPipeline *pipeline) if (pipeline->differences & COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS) _cogl_pipeline_snippet_list_free (&pipeline->big_state->fragment_snippets); - g_list_free (pipeline->deprecated_get_layers_list); + if (pipeline->differences & COGL_PIPELINE_STATE_NEEDS_BIG_STATE) + g_slice_free (CoglPipelineBigState, pipeline->big_state); recursively_free_layer_caches (pipeline); g_slice_free (CoglPipeline, pipeline); } -CoglBool +gboolean _cogl_pipeline_get_real_blend_enabled (CoglPipeline *pipeline) { - _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), FALSE); + g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); return pipeline->real_blend_enable; } @@ -613,7 +498,7 @@ _cogl_pipeline_foreach_layer_internal (CoglPipeline *pipeline, _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LAYERS); int n_layers; int i; - CoglBool cont; + gboolean cont; n_layers = authority->n_layers; if (n_layers == 0) @@ -623,12 +508,12 @@ _cogl_pipeline_foreach_layer_internal (CoglPipeline *pipeline, for (i = 0, cont = TRUE; i < n_layers && cont == TRUE; i++) { - _COGL_RETURN_IF_FAIL (authority->layers_cache_dirty == FALSE); + g_return_if_fail (authority->layers_cache_dirty == FALSE); cont = callback (authority->layers_cache[i], user_data); } } -CoglBool +gboolean _cogl_pipeline_layer_numbers_equal (CoglPipeline *pipeline0, CoglPipeline *pipeline1) { @@ -657,7 +542,7 @@ _cogl_pipeline_layer_numbers_equal (CoglPipeline *pipeline0, return TRUE; } -CoglBool +gboolean _cogl_pipeline_layer_and_unit_numbers_equal (CoglPipeline *pipeline0, CoglPipeline *pipeline1) { @@ -698,7 +583,7 @@ typedef struct int *indices; } AppendLayerIndexState; -static CoglBool +static gboolean append_layer_index_cb (CoglPipelineLayer *layer, void *user_data) { @@ -715,7 +600,7 @@ cogl_pipeline_foreach_layer (CoglPipeline *pipeline, CoglPipeline *authority = _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LAYERS); AppendLayerIndexState state; - CoglBool cont; + gboolean cont; int i; /* XXX: We don't know what the user is going to want to do to the layers @@ -735,10 +620,10 @@ cogl_pipeline_foreach_layer (CoglPipeline *pipeline, cont = callback (pipeline, state.indices[i], user_data); } -static CoglBool +static gboolean layer_has_alpha_cb (CoglPipelineLayer *layer, void *data) { - CoglBool *has_alpha = data; + gboolean *has_alpha = data; *has_alpha = _cogl_pipeline_layer_has_alpha (layer); /* return FALSE to stop iterating layers if we find any layer @@ -760,11 +645,11 @@ layer_has_alpha_cb (CoglPipelineLayer *layer, void *data) * this returns FALSE for a set of changes then you can follow * up */ -static CoglBool +static gboolean _cogl_pipeline_change_implies_transparency (CoglPipeline *pipeline, unsigned int changes, const CoglColor *override_color, - CoglBool unknown_color_alpha) + gboolean unknown_color_alpha) { /* In the case of a layer state change we need to check everything * else first since they contribute to the has_alpha status of the @@ -793,7 +678,7 @@ _cogl_pipeline_change_implies_transparency (CoglPipeline *pipeline, * * TODO: check that it isn't just a vertex shader! */ - if (_cogl_pipeline_get_user_program (pipeline) != COGL_INVALID_HANDLE) + if (_cogl_pipeline_get_user_program (pipeline) != NULL) return TRUE; } @@ -809,38 +694,12 @@ _cogl_pipeline_change_implies_transparency (CoglPipeline *pipeline, return TRUE; } - /* XXX: we should only need to look at these if lighting is enabled - */ - if (changes & COGL_PIPELINE_STATE_LIGHTING) - { - /* XXX: This stuff is showing up in sysprof reports which is - * silly because lighting isn't currently actually supported - * by Cogl except for these token properties. When we actually - * expose lighting support we can avoid these checks when - * lighting is disabled. */ -#if 0 - CoglColor tmp; - cogl_pipeline_get_ambient (pipeline, &tmp); - if (cogl_color_get_alpha_byte (&tmp) != 0xff) - return TRUE; - cogl_pipeline_get_diffuse (pipeline, &tmp); - if (cogl_color_get_alpha_byte (&tmp) != 0xff) - return TRUE; - cogl_pipeline_get_specular (pipeline, &tmp); - if (cogl_color_get_alpha_byte (&tmp) != 0xff) - return TRUE; - cogl_pipeline_get_emission (pipeline, &tmp); - if (cogl_color_get_alpha_byte (&tmp) != 0xff) - return TRUE; -#endif - } - if (changes & COGL_PIPELINE_STATE_LAYERS) { /* has_alpha tracks the alpha status of the GL_PREVIOUS layer. * To start with that's defined by the pipeline color which * must be fully opaque if we got this far. */ - CoglBool has_alpha = FALSE; + gboolean has_alpha = FALSE; _cogl_pipeline_foreach_layer_internal (pipeline, layer_has_alpha_cb, &has_alpha); @@ -851,30 +710,18 @@ _cogl_pipeline_change_implies_transparency (CoglPipeline *pipeline, return FALSE; } -static CoglBool +static gboolean _cogl_pipeline_needs_blending_enabled (CoglPipeline *pipeline, unsigned int changes, const CoglColor *override_color, - CoglBool unknown_color_alpha) + gboolean unknown_color_alpha) { - CoglPipeline *enable_authority; CoglPipeline *blend_authority; CoglPipelineBlendState *blend_state; - CoglPipelineBlendEnable enabled; if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_BLENDING))) return FALSE; - /* We unconditionally check the _BLEND_ENABLE state first because - * all the other changes are irrelevent if blend_enable != _AUTOMATIC - */ - enable_authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_BLEND_ENABLE); - - enabled = enable_authority->blend_enable; - if (enabled != COGL_PIPELINE_BLEND_ENABLE_AUTOMATIC) - return enabled == COGL_PIPELINE_BLEND_ENABLE_ENABLED ? TRUE : FALSE; - blend_authority = _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_BLEND); @@ -952,12 +799,6 @@ _cogl_pipeline_needs_blending_enabled (CoglPipeline *pipeline, return FALSE; } -void -_cogl_pipeline_set_progend (CoglPipeline *pipeline, int progend) -{ - pipeline->progend = progend; -} - static void _cogl_pipeline_copy_differences (CoglPipeline *dest, CoglPipeline *src, @@ -968,21 +809,13 @@ _cogl_pipeline_copy_differences (CoglPipeline *dest, if (differences & COGL_PIPELINE_STATE_COLOR) dest->color = src->color; - if (differences & COGL_PIPELINE_STATE_BLEND_ENABLE) - dest->blend_enable = src->blend_enable; - if (differences & COGL_PIPELINE_STATE_LAYERS) { GList *l; if (dest->differences & COGL_PIPELINE_STATE_LAYERS && dest->layer_differences) - { - g_list_foreach (dest->layer_differences, - (GFunc)cogl_object_unref, - NULL); - g_list_free (dest->layer_differences); - } + g_list_free_full (dest->layer_differences, cogl_object_unref); for (l = src->layer_differences; l; l = l->next) { @@ -1013,13 +846,6 @@ _cogl_pipeline_copy_differences (CoglPipeline *dest, else goto check_for_blending_change; - if (differences & COGL_PIPELINE_STATE_LIGHTING) - { - memcpy (&big_state->lighting_state, - &src->big_state->lighting_state, - sizeof (CoglPipelineLightingState)); - } - if (differences & COGL_PIPELINE_STATE_ALPHA_FUNC) big_state->alpha_state.alpha_func = src->big_state->alpha_state.alpha_func; @@ -1039,9 +865,9 @@ _cogl_pipeline_copy_differences (CoglPipeline *dest, { if (src->big_state->user_program) big_state->user_program = - cogl_handle_ref (src->big_state->user_program); + cogl_object_ref (src->big_state->user_program); else - big_state->user_program = COGL_INVALID_HANDLE; + big_state->user_program = NULL; } if (differences & COGL_PIPELINE_STATE_DEPTH) @@ -1051,13 +877,6 @@ _cogl_pipeline_copy_differences (CoglPipeline *dest, sizeof (CoglDepthState)); } - if (differences & COGL_PIPELINE_STATE_FOG) - { - memcpy (&big_state->fog_state, - &src->big_state->fog_state, - sizeof (CoglPipelineFogState)); - } - if (differences & COGL_PIPELINE_STATE_NON_ZERO_POINT_SIZE) big_state->non_zero_point_size = src->big_state->non_zero_point_size; @@ -1067,13 +886,6 @@ _cogl_pipeline_copy_differences (CoglPipeline *dest, if (differences & COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE) big_state->per_vertex_point_size = src->big_state->per_vertex_point_size; - if (differences & COGL_PIPELINE_STATE_LOGIC_OPS) - { - memcpy (&big_state->logic_ops_state, - &src->big_state->logic_ops_state, - sizeof (CoglPipelineLogicOpsState)); - } - if (differences & COGL_PIPELINE_STATE_CULL_FACE) { memcpy (&big_state->cull_face_state, @@ -1088,7 +900,7 @@ _cogl_pipeline_copy_differences (CoglPipeline *dest, int i; big_state->uniforms_state.override_values = - malloc (n_overrides * sizeof (CoglBoxedValue)); + g_malloc (n_overrides * sizeof (CoglBoxedValue)); for (i = 0; i < n_overrides; i++) { @@ -1133,7 +945,7 @@ _cogl_pipeline_init_multi_property_sparse_state (CoglPipeline *pipeline, { CoglPipeline *authority; - _COGL_RETURN_IF_FAIL (change & COGL_PIPELINE_STATE_ALL_SPARSE); + g_return_if_fail (change & COGL_PIPELINE_STATE_ALL_SPARSE); if (!(change & COGL_PIPELINE_STATE_MULTI_PROPERTY)) return; @@ -1145,7 +957,6 @@ _cogl_pipeline_init_multi_property_sparse_state (CoglPipeline *pipeline, /* XXX: avoid using a default: label so we get a warning if we * don't explicitly handle a newly defined state-group here. */ case COGL_PIPELINE_STATE_COLOR: - case COGL_PIPELINE_STATE_BLEND_ENABLE: case COGL_PIPELINE_STATE_ALPHA_FUNC: case COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE: case COGL_PIPELINE_STATE_NON_ZERO_POINT_SIZE: @@ -1159,13 +970,6 @@ _cogl_pipeline_init_multi_property_sparse_state (CoglPipeline *pipeline, pipeline->n_layers = authority->n_layers; pipeline->layer_differences = NULL; break; - case COGL_PIPELINE_STATE_LIGHTING: - { - memcpy (&pipeline->big_state->lighting_state, - &authority->big_state->lighting_state, - sizeof (CoglPipelineLightingState)); - break; - } case COGL_PIPELINE_STATE_BLEND: { memcpy (&pipeline->big_state->blend_state, @@ -1180,20 +984,6 @@ _cogl_pipeline_init_multi_property_sparse_state (CoglPipeline *pipeline, sizeof (CoglDepthState)); break; } - case COGL_PIPELINE_STATE_FOG: - { - memcpy (&pipeline->big_state->fog_state, - &authority->big_state->fog_state, - sizeof (CoglPipelineFogState)); - break; - } - case COGL_PIPELINE_STATE_LOGIC_OPS: - { - memcpy (&pipeline->big_state->logic_ops_state, - &authority->big_state->logic_ops_state, - sizeof (CoglPipelineLogicOpsState)); - break; - } case COGL_PIPELINE_STATE_CULL_FACE: { memcpy (&pipeline->big_state->cull_face_state, @@ -1223,11 +1013,11 @@ _cogl_pipeline_init_multi_property_sparse_state (CoglPipeline *pipeline, } } -static CoglBool +static gboolean check_if_strong_cb (CoglNode *node, void *user_data) { CoglPipeline *pipeline = COGL_PIPELINE (node); - CoglBool *has_strong_child = user_data; + gboolean *has_strong_child = user_data; if (!_cogl_pipeline_is_weak (pipeline)) { @@ -1238,17 +1028,17 @@ check_if_strong_cb (CoglNode *node, void *user_data) return TRUE; } -static CoglBool +static gboolean has_strong_children (CoglPipeline *pipeline) { - CoglBool has_strong_child = FALSE; + gboolean has_strong_child = FALSE; _cogl_pipeline_node_foreach_child (COGL_NODE (pipeline), check_if_strong_cb, &has_strong_child); return has_strong_child; } -static CoglBool +static gboolean _cogl_pipeline_is_weak (CoglPipeline *pipeline) { if (pipeline->is_weak && !has_strong_children (pipeline)) @@ -1257,7 +1047,7 @@ _cogl_pipeline_is_weak (CoglPipeline *pipeline) return FALSE; } -static CoglBool +static gboolean reparent_children_cb (CoglNode *node, void *user_data) { @@ -1273,7 +1063,7 @@ void _cogl_pipeline_pre_change_notify (CoglPipeline *pipeline, CoglPipelineState change, const CoglColor *new_color, - CoglBool from_layer_change) + gboolean from_layer_change) { _COGL_GET_CONTEXT (ctx, NO_RETVAL); @@ -1282,7 +1072,7 @@ _cogl_pipeline_pre_change_notify (CoglPipeline *pipeline, * before we can modify it... */ if (pipeline->journal_ref_count) { - CoglBool skip_journal_flush = FALSE; + gboolean skip_journal_flush = FALSE; /* XXX: We don't usually need to flush the journal just due to * color changes since pipeline colors are logged in the @@ -1290,12 +1080,12 @@ _cogl_pipeline_pre_change_notify (CoglPipeline *pipeline, * color enables or disables the need for blending. */ if (change == COGL_PIPELINE_STATE_COLOR) { - CoglBool will_need_blending = + gboolean will_need_blending = _cogl_pipeline_needs_blending_enabled (pipeline, change, new_color, FALSE); - CoglBool blend_enable = pipeline->real_blend_enable ? TRUE : FALSE; + gboolean blend_enable = pipeline->real_blend_enable ? TRUE : FALSE; if (will_need_blending == blend_enable) skip_journal_flush = TRUE; @@ -1338,28 +1128,21 @@ _cogl_pipeline_pre_change_notify (CoglPipeline *pipeline, */ if (!from_layer_change) { - int i; - - for (i = 0; i < COGL_PIPELINE_N_PROGENDS; i++) - { - const CoglPipelineProgend *progend = _cogl_pipeline_progends[i]; - const CoglPipelineVertend *vertend = - _cogl_pipeline_vertends[progend->vertend]; - const CoglPipelineFragend *fragend = - _cogl_pipeline_fragends[progend->fragend]; + const CoglPipelineProgend *progend = _cogl_pipeline_progend; + const CoglPipelineVertend *vertend = _cogl_pipeline_vertend; + const CoglPipelineFragend *fragend = _cogl_pipeline_fragend; - if (vertend->pipeline_pre_change_notify) - vertend->pipeline_pre_change_notify (pipeline, change, new_color); + if (vertend->pipeline_pre_change_notify) + vertend->pipeline_pre_change_notify (pipeline, change, new_color); - /* TODO: make the vertend and fragend implementation details - * of the progend */ + /* TODO: make the vertend and fragend implementation details + * of the progend */ - if (fragend->pipeline_pre_change_notify) - fragend->pipeline_pre_change_notify (pipeline, change, new_color); + if (fragend->pipeline_pre_change_notify) + fragend->pipeline_pre_change_notify (pipeline, change, new_color); - if (progend->pipeline_pre_change_notify) - progend->pipeline_pre_change_notify (pipeline, change, new_color); - } + if (progend->pipeline_pre_change_notify) + progend->pipeline_pre_change_notify (pipeline, change, new_color); } /* There may be an arbitrary tree of descendants of this pipeline; @@ -1481,9 +1264,9 @@ _cogl_pipeline_pre_change_notify (CoglPipeline *pipeline, void _cogl_pipeline_add_layer_difference (CoglPipeline *pipeline, CoglPipelineLayer *layer, - CoglBool inc_n_layers) + gboolean inc_n_layers) { - _COGL_RETURN_IF_FAIL (layer->owner == NULL); + g_return_if_fail (layer->owner == NULL); layer->owner = pipeline; cogl_object_ref (layer); @@ -1520,7 +1303,7 @@ _cogl_pipeline_add_layer_difference (CoglPipeline *pipeline, void _cogl_pipeline_remove_layer_difference (CoglPipeline *pipeline, CoglPipelineLayer *layer, - CoglBool dec_n_layers) + gboolean dec_n_layers) { /* - Flush journal primitives referencing the current state. * - Make sure the pipeline has no dependants so it may be modified. @@ -1583,7 +1366,7 @@ _cogl_pipeline_try_reverting_layers_authority (CoglPipeline *authority, void _cogl_pipeline_update_real_blend_enable (CoglPipeline *pipeline, - CoglBool unknown_color_alpha) + gboolean unknown_color_alpha) { CoglPipeline *parent; unsigned int differences; @@ -1635,7 +1418,7 @@ typedef struct int first_index_to_prune; } CoglPipelinePruneLayersInfo; -static CoglBool +static gboolean update_prune_layers_info_cb (CoglPipelineLayer *layer, void *user_data) { CoglPipelinePruneLayersInfo *state = user_data; @@ -1716,12 +1499,12 @@ typedef struct /* When adding a layer we don't need a complete list of * layers_to_shift if we find a layer already corresponding to the * layer_index. */ - CoglBool ignore_shift_layers_if_found; + gboolean ignore_shift_layers_if_found; } CoglPipelineLayerInfo; /* Returns TRUE once we know there is nothing more to update */ -static CoglBool +static gboolean update_layer_info (CoglPipelineLayer *layer, CoglPipelineLayerInfo *layer_info) { @@ -1744,7 +1527,7 @@ update_layer_info (CoglPipelineLayer *layer, } /* Returns FALSE to break out of a _foreach_layer () iteration */ -static CoglBool +static gboolean update_layer_info_cb (CoglPipelineLayer *layer, void *user_data) { @@ -1879,7 +1662,7 @@ _cogl_pipeline_prune_empty_layer_difference (CoglPipeline *layers_authority, CoglPipelineLayerInfo layer_info; CoglPipeline *old_layers_authority; - _COGL_RETURN_IF_FAIL (link != NULL); + g_return_if_fail (link != NULL); /* If the layer's parent doesn't have an owner then we can simply * take ownership ourselves and drop our reference on the empty @@ -1953,12 +1736,11 @@ typedef struct unsigned long fallback_layers; } CoglPipelineFallbackState; -static CoglBool +static gboolean fallback_layer_cb (CoglPipelineLayer *layer, void *user_data) { CoglPipelineFallbackState *state = user_data; CoglPipeline *pipeline = state->pipeline; - CoglTextureType texture_type = _cogl_pipeline_layer_get_texture_type (layer); CoglTexture *texture = NULL; COGL_STATIC_COUNTER (layer_fallback_counter, "layer fallback counter", @@ -1973,20 +1755,7 @@ fallback_layer_cb (CoglPipelineLayer *layer, void *user_data) COGL_COUNTER_INC (_cogl_uprof_context, layer_fallback_counter); - switch (texture_type) - { - case COGL_TEXTURE_TYPE_2D: - texture = COGL_TEXTURE (ctx->default_gl_texture_2d_tex); - break; - - case COGL_TEXTURE_TYPE_3D: - texture = COGL_TEXTURE (ctx->default_gl_texture_3d_tex); - break; - - case COGL_TEXTURE_TYPE_RECTANGLE: - texture = COGL_TEXTURE (ctx->default_gl_texture_rect_tex); - break; - } + texture = COGL_TEXTURE (ctx->default_gl_texture_2d_tex); if (texture == NULL) { @@ -2010,7 +1779,7 @@ typedef struct CoglTexture *texture; } CoglPipelineOverrideLayerState; -static CoglBool +static gboolean override_layer_texture_cb (CoglPipelineLayer *layer, void *user_data) { CoglPipelineOverrideLayerState *state = user_data; @@ -2077,7 +1846,7 @@ _cogl_pipeline_apply_overrides (CoglPipeline *pipeline, } } -static CoglBool +static gboolean _cogl_pipeline_layers_equal (CoglPipeline *authority0, CoglPipeline *authority1, unsigned long differences, @@ -2238,7 +2007,7 @@ _cogl_pipeline_resolve_authorities (CoglPipeline *pipeline, * COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE because once they get to the * journal stage they act exactly the same. */ -CoglBool +gboolean _cogl_pipeline_equal (CoglPipeline *pipeline0, CoglPipeline *pipeline1, unsigned int differences, @@ -2249,7 +2018,7 @@ _cogl_pipeline_equal (CoglPipeline *pipeline0, CoglPipeline *authorities0[COGL_PIPELINE_STATE_SPARSE_COUNT]; CoglPipeline *authorities1[COGL_PIPELINE_STATE_SPARSE_COUNT]; int bit; - CoglBool ret; + gboolean ret; COGL_STATIC_TIMER (pipeline_equal_timer, "Mainloop", /* parent */ @@ -2304,11 +2073,6 @@ _cogl_pipeline_equal (CoglPipeline *pipeline0, &authorities1[bit]->color)) goto done; break; - case COGL_PIPELINE_STATE_LIGHTING_INDEX: - if (!_cogl_pipeline_lighting_state_equal (authorities0[bit], - authorities1[bit])) - goto done; - break; case COGL_PIPELINE_STATE_ALPHA_FUNC_INDEX: if (!_cogl_pipeline_alpha_func_state_equal (authorities0[bit], authorities1[bit])) @@ -2335,11 +2099,6 @@ _cogl_pipeline_equal (CoglPipeline *pipeline0, authorities1[bit])) goto done; break; - case COGL_PIPELINE_STATE_FOG_INDEX: - if (!_cogl_pipeline_fog_state_equal (authorities0[bit], - authorities1[bit])) - goto done; - break; case COGL_PIPELINE_STATE_CULL_FACE_INDEX: if (!_cogl_pipeline_cull_face_state_equal (authorities0[bit], authorities1[bit])) @@ -2360,11 +2119,6 @@ _cogl_pipeline_equal (CoglPipeline *pipeline0, authorities1[bit])) goto done; break; - case COGL_PIPELINE_STATE_LOGIC_OPS_INDEX: - if (!_cogl_pipeline_logic_ops_state_equal (authorities0[bit], - authorities1[bit])) - goto done; - break; case COGL_PIPELINE_STATE_USER_SHADER_INDEX: if (!_cogl_pipeline_user_shader_equal (authorities0[bit], authorities1[bit])) @@ -2395,7 +2149,6 @@ _cogl_pipeline_equal (CoglPipeline *pipeline0, break; } - case COGL_PIPELINE_STATE_BLEND_ENABLE_INDEX: case COGL_PIPELINE_STATE_REAL_BLEND_ENABLE_INDEX: case COGL_PIPELINE_STATE_COUNT: g_warn_if_reached (); @@ -2444,7 +2197,7 @@ _cogl_pipeline_prune_redundant_ancestry (CoglPipeline *pipeline) if (new_parent != _cogl_pipeline_get_parent (pipeline)) { - CoglBool is_weak = _cogl_pipeline_is_weak (pipeline); + gboolean is_weak = _cogl_pipeline_is_weak (pipeline); _cogl_pipeline_set_parent (pipeline, new_parent, is_weak ? FALSE : TRUE); } } @@ -2478,22 +2231,10 @@ _cogl_pipeline_update_authority (CoglPipeline *pipeline, } } -CoglBool -_cogl_pipeline_get_fog_enabled (CoglPipeline *pipeline) -{ - CoglPipeline *authority; - - _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), FALSE); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_FOG); - return authority->big_state->fog_state.enabled; -} - unsigned long _cogl_pipeline_get_age (CoglPipeline *pipeline) { - _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), 0); + g_return_val_if_fail (cogl_is_pipeline (pipeline), 0); return pipeline->age; } @@ -2505,7 +2246,7 @@ cogl_pipeline_remove_layer (CoglPipeline *pipeline, int layer_index) CoglPipelineLayerInfo layer_info; int i; - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); + g_return_if_fail (cogl_is_pipeline (pipeline)); authority = _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LAYERS); @@ -2550,48 +2291,12 @@ cogl_pipeline_remove_layer (CoglPipeline *pipeline, int layer_index) pipeline->dirty_real_blend_enable = TRUE; } -static CoglBool -prepend_layer_to_list_cb (CoglPipelineLayer *layer, - void *user_data) -{ - GList **layers = user_data; - - *layers = g_list_prepend (*layers, layer); - return TRUE; -} - -/* TODO: deprecate this API and replace it with - * cogl_pipeline_foreach_layer - * TODO: update the docs to note that if the user modifies any layers - * then the list may become invalid. - */ -const GList * -_cogl_pipeline_get_layers (CoglPipeline *pipeline) -{ - _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), NULL); - - if (!pipeline->deprecated_get_layers_list_dirty) - g_list_free (pipeline->deprecated_get_layers_list); - - pipeline->deprecated_get_layers_list = NULL; - - _cogl_pipeline_foreach_layer_internal (pipeline, - prepend_layer_to_list_cb, - &pipeline->deprecated_get_layers_list); - pipeline->deprecated_get_layers_list = - g_list_reverse (pipeline->deprecated_get_layers_list); - - pipeline->deprecated_get_layers_list_dirty = 0; - - return pipeline->deprecated_get_layers_list; -} - int cogl_pipeline_get_n_layers (CoglPipeline *pipeline) { CoglPipeline *authority; - _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), 0); + g_return_val_if_fail (cogl_is_pipeline (pipeline), 0); authority = _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LAYERS); @@ -2625,40 +2330,6 @@ _cogl_pipeline_journal_unref (CoglPipeline *pipeline) } #ifdef COGL_DEBUG_ENABLED -void -_cogl_pipeline_apply_legacy_state (CoglPipeline *pipeline) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* It was a mistake that we ever copied the OpenGL style API for - * associating these things directly with the context when we - * originally wrote Cogl. Until the corresponding deprecated APIs - * can be removed though we now shoehorn the state changes through - * the cogl_pipeline API instead. - */ - - /* A program explicitly set on the pipeline has higher precedence than - * one associated with the context using cogl_program_use() */ - if (ctx->current_program && - cogl_pipeline_get_user_program (pipeline) == COGL_INVALID_HANDLE) - cogl_pipeline_set_user_program (pipeline, ctx->current_program); - - if (ctx->legacy_depth_test_enabled) - { - CoglDepthState depth_state; - cogl_depth_state_init (&depth_state); - cogl_depth_state_set_test_enabled (&depth_state, TRUE); - cogl_pipeline_set_depth_state (pipeline, &depth_state, NULL); - } - - if (ctx->legacy_fog_state.enabled) - _cogl_pipeline_set_fog_state (pipeline, &ctx->legacy_fog_state); - - if (ctx->legacy_backface_culling_enabled) - cogl_pipeline_set_cull_face_mode (pipeline, - COGL_PIPELINE_CULL_FACE_MODE_BACK); -} - void _cogl_pipeline_set_static_breadcrumb (CoglPipeline *pipeline, const char *breadcrumb) @@ -2684,8 +2355,6 @@ _cogl_pipeline_init_layer_state_hash_functions (void) CoglPipelineLayerStateIndex _index; layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_UNIT_INDEX] = _cogl_pipeline_layer_hash_unit_state; - layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE_INDEX] = - _cogl_pipeline_layer_hash_texture_type_state; layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX] = _cogl_pipeline_layer_hash_texture_data_state; layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_SAMPLER_INDEX] = @@ -2708,14 +2377,14 @@ _cogl_pipeline_init_layer_state_hash_functions (void) { /* So we get a big error if we forget to update this code! */ - _COGL_STATIC_ASSERT (COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT == 10, + _COGL_STATIC_ASSERT (COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT == 9, "Don't forget to install a hash function for new " "pipeline state and update assert at end of " "_cogl_pipeline_init_state_hash_functions"); } } -static CoglBool +static gboolean _cogl_pipeline_hash_layer_cb (CoglPipelineLayer *layer, void *user_data) { @@ -2787,12 +2456,8 @@ _cogl_pipeline_init_state_hash_functions (void) { state_hash_functions[COGL_PIPELINE_STATE_COLOR_INDEX] = _cogl_pipeline_hash_color_state; - state_hash_functions[COGL_PIPELINE_STATE_BLEND_ENABLE_INDEX] = - _cogl_pipeline_hash_blend_enable_state; state_hash_functions[COGL_PIPELINE_STATE_LAYERS_INDEX] = _cogl_pipeline_hash_layers_state; - state_hash_functions[COGL_PIPELINE_STATE_LIGHTING_INDEX] = - _cogl_pipeline_hash_lighting_state; state_hash_functions[COGL_PIPELINE_STATE_ALPHA_FUNC_INDEX] = _cogl_pipeline_hash_alpha_func_state; state_hash_functions[COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE_INDEX] = @@ -2803,8 +2468,6 @@ _cogl_pipeline_init_state_hash_functions (void) _cogl_pipeline_hash_user_shader_state; state_hash_functions[COGL_PIPELINE_STATE_DEPTH_INDEX] = _cogl_pipeline_hash_depth_state; - state_hash_functions[COGL_PIPELINE_STATE_FOG_INDEX] = - _cogl_pipeline_hash_fog_state; state_hash_functions[COGL_PIPELINE_STATE_CULL_FACE_INDEX] = _cogl_pipeline_hash_cull_face_state; state_hash_functions[COGL_PIPELINE_STATE_NON_ZERO_POINT_SIZE_INDEX] = @@ -2813,8 +2476,6 @@ _cogl_pipeline_init_state_hash_functions (void) _cogl_pipeline_hash_point_size_state; state_hash_functions[COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE_INDEX] = _cogl_pipeline_hash_per_vertex_point_size_state; - state_hash_functions[COGL_PIPELINE_STATE_LOGIC_OPS_INDEX] = - _cogl_pipeline_hash_logic_ops_state; state_hash_functions[COGL_PIPELINE_STATE_UNIFORMS_INDEX] = _cogl_pipeline_hash_uniforms_state; state_hash_functions[COGL_PIPELINE_STATE_VERTEX_SNIPPETS_INDEX] = @@ -2824,7 +2485,7 @@ _cogl_pipeline_init_state_hash_functions (void) { /* So we get a big error if we forget to update this code! */ - _COGL_STATIC_ASSERT (COGL_PIPELINE_STATE_SPARSE_COUNT == 18, + _COGL_STATIC_ASSERT (COGL_PIPELINE_STATE_SPARSE_COUNT == 14, "Make sure to install a hash function for " "newly added pipeline state and update assert " "in _cogl_pipeline_init_state_hash_functions"); @@ -2853,7 +2514,7 @@ _cogl_pipeline_hash (CoglPipeline *pipeline, if (differences & COGL_PIPELINE_STATE_REAL_BLEND_ENABLE) { - CoglBool enable = pipeline->real_blend_enable; + gboolean enable = pipeline->real_blend_enable; state.hash = _cogl_util_one_at_a_time_hash (state.hash, &enable, sizeof (enable)); } @@ -2894,7 +2555,7 @@ typedef struct unsigned int layer_differences; } DeepCopyData; -static CoglBool +static gboolean deep_copy_layer_cb (CoglPipelineLayer *src_layer, void *user_data) { @@ -2928,7 +2589,7 @@ _cogl_pipeline_deep_copy (CoglPipeline *pipeline, unsigned long layer_differences) { CoglPipeline *new, *authority; - CoglBool copy_layer_state; + gboolean copy_layer_state; _COGL_GET_CONTEXT (ctx, NULL); @@ -2983,7 +2644,7 @@ typedef struct CoglPipelineLayer **layers; } AddLayersToArrayState; -static CoglBool +static gboolean add_layer_to_array_cb (CoglPipelineLayer *layer, void *user_data) { @@ -3098,14 +2759,7 @@ _cogl_pipeline_get_state_for_vertex_codegen (CoglContext *context) COGL_PIPELINE_STATE_USER_SHADER | COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE | COGL_PIPELINE_STATE_VERTEX_SNIPPETS); - - /* If we don't have the builtin point size uniform then we'll add - * one in the GLSL but we'll only do this if the point size is - * non-zero. Whether or not the point size is zero is represented by - * COGL_PIPELINE_STATE_NON_ZERO_POINT_SIZE */ - if (!_cogl_has_private_feature - (context, COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM)) - state |= COGL_PIPELINE_STATE_NON_ZERO_POINT_SIZE; + state |= COGL_PIPELINE_STATE_NON_ZERO_POINT_SIZE; return state; } @@ -3115,15 +2769,13 @@ _cogl_pipeline_get_layer_state_for_fragment_codegen (CoglContext *context) { CoglPipelineLayerState state = (COGL_PIPELINE_LAYER_STATE_COMBINE | - COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE | COGL_PIPELINE_LAYER_STATE_UNIT | COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS); - /* If the driver supports GLSL then we might be using gl_PointCoord + /* Since the driver supports GLSL then we might be using gl_PointCoord * to implement the sprite coords. In that case the generated code * depends on the point sprite state */ - if (cogl_has_feature (context, COGL_FEATURE_ID_GLSL)) - state |= COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS; + state |= COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS; return state; } @@ -3133,10 +2785,8 @@ _cogl_pipeline_get_state_for_fragment_codegen (CoglContext *context) { CoglPipelineState state = (COGL_PIPELINE_STATE_LAYERS | COGL_PIPELINE_STATE_USER_SHADER | - COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS); - - if (!_cogl_has_private_feature (context, COGL_PRIVATE_FEATURE_ALPHA_TEST)) - state |= COGL_PIPELINE_STATE_ALPHA_FUNC; + COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS | + COGL_PIPELINE_STATE_ALPHA_FUNC); return state; } diff --git a/cogl/cogl/cogl-pipeline.h b/cogl/cogl/cogl-pipeline.h index 65587353e..16acc772d 100644 --- a/cogl/cogl/cogl-pipeline.h +++ b/cogl/cogl/cogl-pipeline.h @@ -46,7 +46,7 @@ typedef struct _CoglPipeline CoglPipeline; #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS /** * SECTION:cogl-pipeline @@ -69,10 +69,11 @@ COGL_BEGIN_DECLS * * Returns: a #GType that can be used with the GLib type system. */ +COGL_EXPORT GType cogl_pipeline_get_gtype (void); /** - * cogl_pipeline_new: + * cogl_pipeline_new: (constructor) * @context: a #CoglContext * * Allocates and initializes a default simple pipeline that will color @@ -83,7 +84,7 @@ GType cogl_pipeline_get_gtype (void); * Since: 2.0 * Stability: Unstable */ -CoglPipeline * +COGL_EXPORT CoglPipeline * cogl_pipeline_new (CoglContext *context); /** @@ -104,7 +105,7 @@ cogl_pipeline_new (CoglContext *context); * Since: 2.0 * Stability: Unstable */ -CoglPipeline * +COGL_EXPORT CoglPipeline * cogl_pipeline_copy (CoglPipeline *source); /** @@ -119,7 +120,7 @@ cogl_pipeline_copy (CoglPipeline *source); * Since: 2.0 * Stability: Unstable */ -CoglBool +COGL_EXPORT gboolean cogl_is_pipeline (void *object); /** @@ -134,7 +135,7 @@ cogl_is_pipeline (void *object); * Since: 2.0 * Stability: Unstable */ -typedef CoglBool (*CoglPipelineLayerCallback) (CoglPipeline *pipeline, +typedef gboolean (*CoglPipelineLayerCallback) (CoglPipeline *pipeline, int layer_index, void *user_data); @@ -151,7 +152,7 @@ typedef CoglBool (*CoglPipelineLayerCallback) (CoglPipeline *pipeline, * Since: 2.0 * Stability: Unstable */ -void +COGL_EXPORT void cogl_pipeline_foreach_layer (CoglPipeline *pipeline, CoglPipelineLayerCallback callback, void *user_data); @@ -176,10 +177,10 @@ cogl_pipeline_foreach_layer (CoglPipeline *pipeline, * Since: 2.0 * Stability: Unstable */ -int +COGL_EXPORT int cogl_pipeline_get_uniform_location (CoglPipeline *pipeline, const char *uniform_name); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_PIPELINE_H__ */ diff --git a/cogl/cogl/cogl-pixel-buffer-private.h b/cogl/cogl/cogl-pixel-buffer-private.h index 2735277e0..3e5100336 100644 --- a/cogl/cogl/cogl-pixel-buffer-private.h +++ b/cogl/cogl/cogl-pixel-buffer-private.h @@ -40,13 +40,13 @@ #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS struct _CoglPixelBuffer { CoglBuffer _parent; }; -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_PIXEL_BUFFER_PRIVATE_H__ */ diff --git a/cogl/cogl/cogl-pixel-buffer.c b/cogl/cogl/cogl-pixel-buffer.c index 348f74a21..7abebaccc 100644 --- a/cogl/cogl/cogl-pixel-buffer.c +++ b/cogl/cogl/cogl-pixel-buffer.c @@ -37,9 +37,7 @@ * Pixel Buffers API. */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include #include @@ -79,7 +77,7 @@ static CoglPixelBuffer * _cogl_pixel_buffer_new (CoglContext *context, size_t size, const void *data, - CoglError **error) + GError **error) { CoglPixelBuffer *pixel_buffer = g_slice_new0 (CoglPixelBuffer); CoglBuffer *buffer = COGL_BUFFER (pixel_buffer); @@ -115,11 +113,11 @@ cogl_pixel_buffer_new (CoglContext *context, size_t size, const void *data) { - CoglError *ignore_error = NULL; + GError *ignore_error = NULL; CoglPixelBuffer *buffer = _cogl_pixel_buffer_new (context, size, data, &ignore_error); - if (!buffer) - cogl_error_free (ignore_error); + + g_clear_error (&ignore_error); return buffer; } diff --git a/cogl/cogl/cogl-pixel-buffer.h b/cogl/cogl/cogl-pixel-buffer.h index 473b5ed82..79d03c83c 100644 --- a/cogl/cogl/cogl-pixel-buffer.h +++ b/cogl/cogl/cogl-pixel-buffer.h @@ -48,7 +48,7 @@ typedef struct _CoglPixelBuffer CoglPixelBuffer; #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS #define COGL_PIXEL_BUFFER(buffer) ((CoglPixelBuffer *)(buffer)) @@ -61,6 +61,7 @@ COGL_BEGIN_DECLS * * Returns: a #GType that can be used with the GLib type system. */ +COGL_EXPORT GType cogl_pixel_buffer_get_gtype (void); /** @@ -82,7 +83,7 @@ GType cogl_pixel_buffer_get_gtype (void); * Since: 1.10 * Stability: unstable */ -CoglPixelBuffer * +COGL_EXPORT CoglPixelBuffer * cogl_pixel_buffer_new (CoglContext *context, size_t size, const void *data); @@ -99,40 +100,9 @@ cogl_pixel_buffer_new (CoglContext *context, * Since: 1.2 * Stability: Unstable */ -CoglBool +COGL_EXPORT gboolean cogl_is_pixel_buffer (void *object); -#if 0 -/* - * cogl_pixel_buffer_set_region: - * @buffer: A #CoglPixelBuffer object - * @data: pixel data to upload to @array - * @src_width: width in pixels of the region to update - * @src_height: height in pixels of the region to update - * @src_rowstride: row stride in bytes of the source array - * @dst_x: upper left destination horizontal coordinate - * @dst_y: upper left destination vertical coordinate - * - * Uploads new data into a pixel array. The source data pointed by @data can - * have a different stride than @array in which case the function will do the - * right thing for you. For performance reasons, it is recommended for the - * source data to have the same stride than @array. - * - * Return value: %TRUE if the upload succeeded, %FALSE otherwise - * - * Since: 1.2 - * Stability: Unstable - */ -CoglBool -cogl_pixel_buffer_set_region (CoglPixelBuffer *buffer, - uint8_t *data, - unsigned int src_width, - unsigned int src_height, - unsigned int src_rowstride, - unsigned int dst_x, - unsigned int dst_y); -#endif - -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_PIXEL_BUFFER_H__ */ diff --git a/cogl/cogl/cogl-pixel-format.c b/cogl/cogl/cogl-pixel-format.c new file mode 100644 index 000000000..bfe6e13ad --- /dev/null +++ b/cogl/cogl/cogl-pixel-format.c @@ -0,0 +1,343 @@ +/* + * Cogl + * + * A Low Level GPU Graphics and Utilities API + * + * Copyright (C) 2007,2008,2009,2010 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * + */ + +#include "cogl-config.h" + +#include +#include +#include + +#include "cogl-pixel-format.h" + +/* An entry to map CoglPixelFormats to their respective properties */ +typedef struct _CoglPixelFormatInfo +{ + CoglPixelFormat cogl_format; + const char *format_str; + int aligned; /* Aligned components? (-1 if n/a) */ + uint8_t n_planes; + + /* Per-plane information */ + uint8_t bpp[COGL_PIXEL_FORMAT_MAX_PLANES]; /* Bytes per pixel */ +} CoglPixelFormatInfo; + +static const CoglPixelFormatInfo format_info_table[] = { + { + .cogl_format = COGL_PIXEL_FORMAT_ANY, + .format_str = "ANY", + .n_planes = 0, + .aligned = -1, + .bpp = { 0 }, + }, + { + .cogl_format = COGL_PIXEL_FORMAT_A_8, + .format_str = "A_8", + .n_planes = 1, + .aligned = 1, + .bpp = { 1 }, + }, + { + .cogl_format = COGL_PIXEL_FORMAT_RGB_565, + .format_str = "RGB_565", + .n_planes = 1, + .aligned = 0, + .bpp = { 2 }, + }, + { + .cogl_format = COGL_PIXEL_FORMAT_RGBA_4444, + .format_str = "RGBA_4444", + .n_planes = 1, + .aligned = 0, + .bpp = { 2 }, + }, + { + .cogl_format = COGL_PIXEL_FORMAT_RGBA_5551, + .format_str = "RGBA_5551", + .n_planes = 1, + .aligned = 0, + .bpp = { 2 }, + }, + { + .cogl_format = COGL_PIXEL_FORMAT_YUV, + .format_str = "YUV", + .n_planes = 1, + .aligned = -1, + .bpp = { 0 }, + }, + { + .cogl_format = COGL_PIXEL_FORMAT_G_8, + .format_str = "G_8", + .n_planes = 1, + .aligned = 1, + .bpp = { 1 }, + }, + { + .cogl_format = COGL_PIXEL_FORMAT_RG_88, + .format_str = "RG_88", + .n_planes = 1, + .aligned = 1, + .bpp = { 2 }, + }, + { + .cogl_format = COGL_PIXEL_FORMAT_RGB_888, + .format_str = "RGB_888", + .n_planes = 1, + .aligned = 1, + .bpp = { 3 }, + }, + { + .cogl_format = COGL_PIXEL_FORMAT_BGR_888, + .format_str = "BGR_888", + .n_planes = 1, + .aligned = 1, + .bpp = { 3 }, + }, + { + .cogl_format = COGL_PIXEL_FORMAT_RGBA_8888, + .format_str = "RGBA_8888", + .n_planes = 1, + .aligned = 1, + .bpp = { 4 }, + }, + { + .cogl_format = COGL_PIXEL_FORMAT_BGRA_8888, + .format_str = "BGRA_8888", + .n_planes = 1, + .aligned = 1, + .bpp = { 4 }, + }, + { + .cogl_format = COGL_PIXEL_FORMAT_ARGB_8888, + .format_str = "ARGB_8888", + .n_planes = 1, + .aligned = 1, + .bpp = { 4 }, + }, + { + .cogl_format = COGL_PIXEL_FORMAT_ABGR_8888, + .format_str = "ABGR_8888", + .n_planes = 1, + .aligned = 1, + .bpp = { 4 }, + }, + { + .cogl_format = COGL_PIXEL_FORMAT_RGBA_1010102, + .format_str = "RGBA_1010102", + .n_planes = 1, + .aligned = 0, + .bpp = { 4 }, + }, + { + .cogl_format = COGL_PIXEL_FORMAT_BGRA_1010102, + .format_str = "BGRA_1010102", + .n_planes = 1, + .aligned = 0, + .bpp = { 4 }, + }, + { + .cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010, + .format_str = "ARGB_2101010", + .n_planes = 1, + .aligned = 0, + .bpp = { 4 }, + }, + { + .cogl_format = COGL_PIXEL_FORMAT_ABGR_2101010, + .format_str = "ABGR_2101010", + .n_planes = 1, + .aligned = 0, + .bpp = { 4 }, + }, + { + .cogl_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE, + .format_str = "RGBA_8888_PRE", + .n_planes = 1, + .aligned = 1, + .bpp = { 4 }, + }, + { + .cogl_format = COGL_PIXEL_FORMAT_BGRA_8888_PRE, + .format_str = "BGRA_8888_PRE", + .n_planes = 1, + .aligned = 1, + .bpp = { 4 }, + }, + { + .cogl_format = COGL_PIXEL_FORMAT_ARGB_8888_PRE, + .format_str = "ARGB_8888_PRE", + .n_planes = 1, + .aligned = 1, + .bpp = { 4 }, + }, + { + .cogl_format = COGL_PIXEL_FORMAT_ABGR_8888_PRE, + .format_str = "ABGR_8888_PRE", + .n_planes = 1, + .aligned = 1, + .bpp = { 4 }, + }, + { + .cogl_format = COGL_PIXEL_FORMAT_RGBA_4444_PRE, + .format_str = "RGBA_4444_PRE", + .n_planes = 1, + .aligned = 0, + .bpp = { 2 }, + }, + { + .cogl_format = COGL_PIXEL_FORMAT_RGBA_5551_PRE, + .format_str = "RGBA_5551_PRE", + .n_planes = 1, + .aligned = 0, + .bpp = { 2 }, + }, + { + .cogl_format = COGL_PIXEL_FORMAT_RGBA_1010102_PRE, + .format_str = "RGBA_1010102_PRE", + .n_planes = 1, + .aligned = 0, + .bpp = { 4 }, + }, + { + .cogl_format = COGL_PIXEL_FORMAT_BGRA_1010102_PRE, + .format_str = "BGRA_1010102_PRE", + .n_planes = 1, + .aligned = 0, + .bpp = { 4 }, + }, + { + .cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010_PRE, + .format_str = "ARGB_2101010_PRE", + .n_planes = 1, + .aligned = 0, + .bpp = { 4 }, + }, + { + .cogl_format = COGL_PIXEL_FORMAT_ABGR_2101010_PRE, + .format_str = "ABGR_2101010_PRE", + .n_planes = 1, + .aligned = 0, + .bpp = { 4 }, + }, + { + .cogl_format = COGL_PIXEL_FORMAT_DEPTH_16, + .format_str = "DEPTH_16", + .n_planes = 1, + .aligned = 1, + .bpp = { 2 }, + }, + { + .cogl_format = COGL_PIXEL_FORMAT_DEPTH_32, + .format_str = "DEPTH_32", + .n_planes = 1, + .aligned = 1, + .bpp = { 4 }, + }, + { + .cogl_format = COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8, + .format_str = "DEPTH_24_STENCIL_8", + .n_planes = 1, + .aligned = 1, + .bpp = { 4 }, + }, +}; + +int +cogl_pixel_format_get_bytes_per_pixel (CoglPixelFormat format, + int plane) +{ + size_t i; + + for (i = 0; i < G_N_ELEMENTS (format_info_table); i++) + { + if (format_info_table[i].cogl_format == format) + { + g_return_val_if_fail (plane < format_info_table[i].n_planes, 0); + + return format_info_table[i].bpp[plane]; + } + } + + g_assert_not_reached (); +} + +/* Note: this also refers to the mapping defined above for + * cogl_pixel_format_get_bytes_per_pixel() */ +gboolean +_cogl_pixel_format_is_endian_dependant (CoglPixelFormat format) +{ + int aligned = -1; + size_t i; + + /* NB: currently checking whether the format components are aligned + * or not determines whether the format is endian dependent or not. + * In the future though we might consider adding formats with + * aligned components that are also endian independant. */ + + for (i = 0; i < G_N_ELEMENTS (format_info_table); i++) + { + if (format_info_table[i].cogl_format == format) + { + aligned = format_info_table[i].aligned; + break; + } + } + + g_return_val_if_fail (aligned != -1, FALSE); + + return aligned; +} + +int +cogl_pixel_format_get_n_planes (CoglPixelFormat format) +{ + size_t i; + + for (i = 0; i < G_N_ELEMENTS (format_info_table); i++) + { + if (format_info_table[i].cogl_format == format) + return format_info_table[i].n_planes; + } + + g_assert_not_reached (); +} + +const char * +cogl_pixel_format_to_string (CoglPixelFormat format) +{ + size_t i; + + for (i = 0; i < G_N_ELEMENTS (format_info_table); i++) + { + if (format_info_table[i].cogl_format == format) + return format_info_table[i].format_str; + } + + g_assert_not_reached (); +} diff --git a/cogl/cogl/cogl-pixel-format.h b/cogl/cogl/cogl-pixel-format.h new file mode 100644 index 000000000..e2f898c97 --- /dev/null +++ b/cogl/cogl/cogl-pixel-format.h @@ -0,0 +1,322 @@ +/* + * Cogl + * + * A Low Level GPU Graphics and Utilities API + * + * Copyright (C) 2008,2009 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * + */ + +#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __COGL_PIXEL_FORMAT_H__ +#define __COGL_PIXEL_FORMAT_H__ + +#include +#include + +#include +#include + +#include +#include + +G_BEGIN_DECLS + +/** + * SECTION:cogl-pixel-format + * @short_description: Pixel formats supported by Cogl + * + * The pixel format of an image descrbes how the bits of each pixel are + * represented in memory. For example: an image can be laid out as one long + * sequence of pixels, where each pixel is a sequence of 8 bits of Red, Green + * and Blue. The amount of bits that are used can be different for each pixel + * format, as well as the components (for example an Alpha layer to include + * transparency, or non_RGBA). + * + * Other examples of factors that can influence the layout in memory are the + * system's endianness. + */ + +#define COGL_A_BIT (1 << 4) +#define COGL_BGR_BIT (1 << 5) +#define COGL_AFIRST_BIT (1 << 6) +#define COGL_PREMULT_BIT (1 << 7) +#define COGL_DEPTH_BIT (1 << 8) +#define COGL_STENCIL_BIT (1 << 9) + +/* XXX: Notes to those adding new formats here... + * + * First this diagram outlines how we allocate the 32bits of a + * CoglPixelFormat currently... + * + * 6 bits for flags + * |-----| + * enum unused 4 bits for the bytes-per-pixel + * and component alignment info + * |------| |-------------| |--| + * 00000000 xxxxxxxx xxxxxxSD PFBA0000 + * ^ stencil + * ^ depth + * ^ premult + * ^ alpha first + * ^ bgr order + * ^ has alpha + * + * The most awkward part about the formats is how we use the last 4 + * bits to encode the bytes per pixel and component alignment + * information. Ideally we should have had 3 bits for the bpp and a + * flag for alignment but we didn't plan for that in advance so we + * instead use a small lookup table to query the bpp and whether the + * components are byte aligned or not. + * + * The mapping is the following (see discussion on bug #660188): + * + * 0 = undefined + * 1, 8 = 1 bpp (e.g. A_8, G_8) + * 2 = 3 bpp, aligned (e.g. 888) + * 3 = 4 bpp, aligned (e.g. 8888) + * 4-6 = 2 bpp, not aligned (e.g. 565, 4444, 5551) + * 7 = YUV: undefined bpp, undefined alignment + * 9 = 2 bpp, aligned + * 10 = depth, aligned (8, 16, 24, 32, 32f) + * 11 = undefined + * 12 = 3 bpp, not aligned + * 13 = 4 bpp, not aligned (e.g. 2101010) + * 14-15 = undefined + * + * Note: the gap at 10-11 is just because we wanted to maintain that + * all non-aligned formats have the third bit set in case that's + * useful later. + * + * Since we don't want to waste bits adding more and more flags, we'd + * like to see most new pixel formats that can't be represented + * uniquely with the existing flags in the least significant byte + * simply be enumerated with sequential values in the most significant + * enum byte. + * + * Note: Cogl avoids exposing any padded XRGB or RGBX formats and + * instead we leave it up to applications to decided whether they + * consider the A component as padding or valid data. We shouldn't + * change this policy without good reasoning. + * + * So to add a new format: + * 1) Use the mapping table above to figure out what to but in + * the lowest nibble. + * 2) OR in the COGL_PREMULT_BIT, COGL_AFIRST_BIT, COGL_A_BIT and + * COGL_BGR_BIT flags as appropriate. + * 3) If the result is not yet unique then also combine with an + * increment of the last sequence number in the most significant + * byte. + * + * The last sequence number used was 0 (i.e. no formats currently need + * a sequence number) + * Update this note whenever a new sequence number is used. + */ +/** + * CoglPixelFormat: + * @COGL_PIXEL_FORMAT_ANY: Any format + * @COGL_PIXEL_FORMAT_A_8: 8 bits alpha mask + * @COGL_PIXEL_FORMAT_RG_88: RG, 16 bits. Note that red-green textures + * are only available if %COGL_FEATURE_ID_TEXTURE_RG is advertised. + * See cogl_texture_set_components() for details. + * @COGL_PIXEL_FORMAT_RGB_565: RGB, 16 bits + * @COGL_PIXEL_FORMAT_RGBA_4444: RGBA, 16 bits + * @COGL_PIXEL_FORMAT_RGBA_5551: RGBA, 16 bits + * @COGL_PIXEL_FORMAT_YUV: Not currently supported + * @COGL_PIXEL_FORMAT_G_8: Single luminance component + * @COGL_PIXEL_FORMAT_RGB_888: RGB, 24 bits + * @COGL_PIXEL_FORMAT_BGR_888: BGR, 24 bits + * @COGL_PIXEL_FORMAT_RGBA_8888: RGBA, 32 bits + * @COGL_PIXEL_FORMAT_BGRA_8888: BGRA, 32 bits + * @COGL_PIXEL_FORMAT_ARGB_8888: ARGB, 32 bits + * @COGL_PIXEL_FORMAT_ABGR_8888: ABGR, 32 bits + * @COGL_PIXEL_FORMAT_RGBA_1010102 : RGBA, 32 bits, 10 bpc + * @COGL_PIXEL_FORMAT_BGRA_1010102 : BGRA, 32 bits, 10 bpc + * @COGL_PIXEL_FORMAT_ARGB_2101010 : ARGB, 32 bits, 10 bpc + * @COGL_PIXEL_FORMAT_ABGR_2101010 : ABGR, 32 bits, 10 bpc + * @COGL_PIXEL_FORMAT_RGBA_8888_PRE: Premultiplied RGBA, 32 bits + * @COGL_PIXEL_FORMAT_BGRA_8888_PRE: Premultiplied BGRA, 32 bits + * @COGL_PIXEL_FORMAT_ARGB_8888_PRE: Premultiplied ARGB, 32 bits + * @COGL_PIXEL_FORMAT_ABGR_8888_PRE: Premultiplied ABGR, 32 bits + * @COGL_PIXEL_FORMAT_RGBA_4444_PRE: Premultiplied RGBA, 16 bits + * @COGL_PIXEL_FORMAT_RGBA_5551_PRE: Premultiplied RGBA, 16 bits + * @COGL_PIXEL_FORMAT_RGBA_1010102_PRE: Premultiplied RGBA, 32 bits, 10 bpc + * @COGL_PIXEL_FORMAT_BGRA_1010102_PRE: Premultiplied BGRA, 32 bits, 10 bpc + * @COGL_PIXEL_FORMAT_ARGB_2101010_PRE: Premultiplied ARGB, 32 bits, 10 bpc + * @COGL_PIXEL_FORMAT_ABGR_2101010_PRE: Premultiplied ABGR, 32 bits, 10 bpc + * + * Pixel formats used by Cogl. For the formats with a byte per + * component, the order of the components specify the order in + * increasing memory addresses. So for example + * %COGL_PIXEL_FORMAT_RGB_888 would have the red component in the + * lowest address, green in the next address and blue after that + * regardless of the endianness of the system. + * + * For the formats with non byte aligned components the component + * order specifies the order within a 16-bit or 32-bit number from + * most significant bit to least significant. So for + * %COGL_PIXEL_FORMAT_RGB_565, the red component would be in bits + * 11-15, the green component would be in 6-11 and the blue component + * would be in 1-5. Therefore the order in memory depends on the + * endianness of the system. + * + * When uploading a texture %COGL_PIXEL_FORMAT_ANY can be used as the + * internal format. Cogl will try to pick the best format to use + * internally and convert the texture data if necessary. + * + * Since: 0.8 + */ +typedef enum /*< prefix=COGL_PIXEL_FORMAT >*/ +{ + COGL_PIXEL_FORMAT_ANY = 0, + COGL_PIXEL_FORMAT_A_8 = 1 | COGL_A_BIT, + + COGL_PIXEL_FORMAT_RGB_565 = 4, + COGL_PIXEL_FORMAT_RGBA_4444 = 5 | COGL_A_BIT, + COGL_PIXEL_FORMAT_RGBA_5551 = 6 | COGL_A_BIT, + COGL_PIXEL_FORMAT_YUV = 7, + COGL_PIXEL_FORMAT_G_8 = 8, + + COGL_PIXEL_FORMAT_RG_88 = 9, + + COGL_PIXEL_FORMAT_RGB_888 = 2, + COGL_PIXEL_FORMAT_BGR_888 = (2 | COGL_BGR_BIT), + + COGL_PIXEL_FORMAT_RGBA_8888 = (3 | COGL_A_BIT), + COGL_PIXEL_FORMAT_BGRA_8888 = (3 | COGL_A_BIT | COGL_BGR_BIT), + COGL_PIXEL_FORMAT_ARGB_8888 = (3 | COGL_A_BIT | COGL_AFIRST_BIT), + COGL_PIXEL_FORMAT_ABGR_8888 = (3 | COGL_A_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT), + + COGL_PIXEL_FORMAT_RGBA_1010102 = (13 | COGL_A_BIT), + COGL_PIXEL_FORMAT_BGRA_1010102 = (13 | COGL_A_BIT | COGL_BGR_BIT), + COGL_PIXEL_FORMAT_ARGB_2101010 = (13 | COGL_A_BIT | COGL_AFIRST_BIT), + COGL_PIXEL_FORMAT_ABGR_2101010 = (13 | COGL_A_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT), + + COGL_PIXEL_FORMAT_RGBA_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT), + COGL_PIXEL_FORMAT_BGRA_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_BGR_BIT), + COGL_PIXEL_FORMAT_ARGB_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_AFIRST_BIT), + COGL_PIXEL_FORMAT_ABGR_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT), + COGL_PIXEL_FORMAT_RGBA_4444_PRE = (COGL_PIXEL_FORMAT_RGBA_4444 | COGL_A_BIT | COGL_PREMULT_BIT), + COGL_PIXEL_FORMAT_RGBA_5551_PRE = (COGL_PIXEL_FORMAT_RGBA_5551 | COGL_A_BIT | COGL_PREMULT_BIT), + + COGL_PIXEL_FORMAT_RGBA_1010102_PRE = (COGL_PIXEL_FORMAT_RGBA_1010102 | COGL_PREMULT_BIT), + COGL_PIXEL_FORMAT_BGRA_1010102_PRE = (COGL_PIXEL_FORMAT_BGRA_1010102 | COGL_PREMULT_BIT), + COGL_PIXEL_FORMAT_ARGB_2101010_PRE = (COGL_PIXEL_FORMAT_ARGB_2101010 | COGL_PREMULT_BIT), + COGL_PIXEL_FORMAT_ABGR_2101010_PRE = (COGL_PIXEL_FORMAT_ABGR_2101010 | COGL_PREMULT_BIT), + + COGL_PIXEL_FORMAT_DEPTH_16 = (9 | COGL_DEPTH_BIT), + COGL_PIXEL_FORMAT_DEPTH_32 = (3 | COGL_DEPTH_BIT), + + COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8 = (3 | COGL_DEPTH_BIT | COGL_STENCIL_BIT) +} CoglPixelFormat; + +/** + * COGL_PIXEL_FORMAT_MAX_PLANES: + * + * The maximum number of planes of a pixel format (see also + * cogl_pixel_format_get_planes()). + */ +#define COGL_PIXEL_FORMAT_MAX_PLANES (4) + +/** + * cogl_pixel_format_get_bytes_per_pixel: + * @format: The pixel format + * @plane: The index of the plane (should not be more than the number of planes + * in the given format). + * + * Queries the number of bytes per pixel for a given format in the given plane. + * + * Returns: The number of bytes per pixel in the given format's given plane. + */ +COGL_EXPORT int +cogl_pixel_format_get_bytes_per_pixel (CoglPixelFormat format, + int plane); + +/* + * _cogl_pixel_format_has_aligned_components: + * @format: a #CoglPixelFormat + * + * Queries whether the ordering of the components for the given + * @format depend on the endianness of the host CPU or if the + * components can be accessed using bit shifting and bitmasking by + * loading a whole pixel into a word. + * + * XXX: If we ever consider making something like this public we + * should really try to think of a better name and come up with + * much clearer documentation since it really depends on what + * point of view you consider this from whether a format like + * COGL_PIXEL_FORMAT_RGBA_8888 is endian dependent. E.g. If you + * read an RGBA_8888 pixel into a uint32 + * it's endian dependent how you mask out the different channels. + * But If you already have separate color components and you want + * to write them to an RGBA_8888 pixel then the bytes can be + * written sequentially regardless of the endianness. + * + * Return value: %TRUE if you need to consider the host CPU + * endianness when dealing with the given @format + * else %FALSE. + */ +gboolean +_cogl_pixel_format_is_endian_dependant (CoglPixelFormat format); + +/* + * COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT(format): + * @format: a #CoglPixelFormat + * + * Returns TRUE if the pixel format can take a premult bit. This is + * currently true for all formats that have an alpha channel except + * COGL_PIXEL_FORMAT_A_8 (because that doesn't have any other + * components to multiply by the alpha). + */ +#define COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT(format) \ + (((format) & COGL_A_BIT) && (format) != COGL_PIXEL_FORMAT_A_8) + +/** + * cogl_pixel_format_get_n_planes: + * @format: The format for which to get the number of planes + * + * Returns the number of planes the given CoglPixelFormat specifies. + * + * Returns: The no. of planes of @format (at most %COGL_PIXEL_FORMAT_MAX_PLANES) + */ +COGL_EXPORT int +cogl_pixel_format_get_n_planes (CoglPixelFormat format); + +/** + * cogl_pixel_format_to_string: + * @format: a #CoglPixelFormat + * + * Returns a string representation of @format, useful for debugging purposes. + * + * Returns: (transfer none): A string representation of @format. + */ +COGL_EXPORT const char * +cogl_pixel_format_to_string (CoglPixelFormat format); + +G_END_DECLS + +#endif /* __COGL_PIXEL_FORMAT_H__ */ diff --git a/cogl/cogl/cogl-point-in-poly-private.h b/cogl/cogl/cogl-point-in-poly-private.h index 1f3f7014c..9b6b21953 100644 --- a/cogl/cogl/cogl-point-in-poly-private.h +++ b/cogl/cogl/cogl-point-in-poly-private.h @@ -31,7 +31,7 @@ #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS int _cogl_util_point_in_screen_poly (float point_x, @@ -40,7 +40,7 @@ _cogl_util_point_in_screen_poly (float point_x, size_t stride, int n_vertices); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_POINT_INT_POLYGON_PRIVATE_H */ diff --git a/cogl/cogl/cogl-point-in-poly.c b/cogl/cogl/cogl-point-in-poly.c index 64bbd30b5..c80fcbaca 100644 --- a/cogl/cogl/cogl-point-in-poly.c +++ b/cogl/cogl/cogl-point-in-poly.c @@ -34,9 +34,7 @@ * http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-util.h" #include "cogl-point-in-poly-private.h" diff --git a/cogl/cogl/cogl-poll-private.h b/cogl/cogl/cogl-poll-private.h index bdc9e6d80..55021926e 100644 --- a/cogl/cogl/cogl-poll-private.h +++ b/cogl/cogl/cogl-poll-private.h @@ -41,7 +41,7 @@ _cogl_poll_renderer_remove_fd (CoglRenderer *renderer, int fd); typedef int64_t (*CoglPollPrepareCallback) (void *user_data); typedef void (*CoglPollDispatchCallback) (void *user_data, int revents); -void +COGL_EXPORT void _cogl_poll_renderer_add_fd (CoglRenderer *renderer, int fd, CoglPollFDEvent events, @@ -68,7 +68,7 @@ _cogl_poll_renderer_remove_source (CoglRenderer *renderer, typedef void (*CoglIdleCallback) (void *user_data); -CoglClosure * +COGL_EXPORT CoglClosure * _cogl_poll_renderer_add_idle (CoglRenderer *renderer, CoglIdleCallback idle_cb, void *user_data, diff --git a/cogl/cogl/cogl-poll.c b/cogl/cogl/cogl-poll.c index d0926e3d8..c736e48b3 100644 --- a/cogl/cogl/cogl-poll.c +++ b/cogl/cogl/cogl-poll.c @@ -30,14 +30,12 @@ * Neil Roberts */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-poll.h" #include "cogl-poll-private.h" -#include "cogl-winsys-private.h" #include "cogl-renderer-private.h" +#include "winsys/cogl-winsys-private.h" struct _CoglPollSource { @@ -55,10 +53,10 @@ cogl_poll_renderer_get_info (CoglRenderer *renderer, { GList *l, *next; - _COGL_RETURN_VAL_IF_FAIL (cogl_is_renderer (renderer), 0); - _COGL_RETURN_VAL_IF_FAIL (poll_fds != NULL, 0); - _COGL_RETURN_VAL_IF_FAIL (n_poll_fds != NULL, 0); - _COGL_RETURN_VAL_IF_FAIL (timeout != NULL, 0); + g_return_val_if_fail (cogl_is_renderer (renderer), 0); + g_return_val_if_fail (poll_fds != NULL, 0); + g_return_val_if_fail (n_poll_fds != NULL, 0); + g_return_val_if_fail (timeout != NULL, 0); *timeout = -1; @@ -97,7 +95,7 @@ cogl_poll_renderer_dispatch (CoglRenderer *renderer, { GList *l, *next; - _COGL_RETURN_IF_FAIL (cogl_is_renderer (renderer)); + g_return_if_fail (cogl_is_renderer (renderer)); _cogl_closure_list_invoke_no_args (&renderer->idle_closures); diff --git a/cogl/cogl/cogl-poll.h b/cogl/cogl/cogl-poll.h index 849e95c92..5afed9089 100644 --- a/cogl/cogl/cogl-poll.h +++ b/cogl/cogl/cogl-poll.h @@ -40,7 +40,7 @@ #include #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS /** * SECTION:cogl-poll @@ -157,7 +157,7 @@ typedef struct { * Stability: unstable * Since: 1.16 */ -int +COGL_EXPORT int cogl_poll_renderer_get_info (CoglRenderer *renderer, CoglPollFD **poll_fds, int *n_poll_fds, @@ -185,11 +185,11 @@ cogl_poll_renderer_get_info (CoglRenderer *renderer, * Stability: unstable * Since: 1.16 */ -void +COGL_EXPORT void cogl_poll_renderer_dispatch (CoglRenderer *renderer, const CoglPollFD *poll_fds, int n_poll_fds); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_POLL_H__ */ diff --git a/cogl/cogl/cogl-primitive-private.h b/cogl/cogl/cogl-primitive-private.h index 78627295a..072812148 100644 --- a/cogl/cogl/cogl-primitive-private.h +++ b/cogl/cogl/cogl-primitive-private.h @@ -63,7 +63,7 @@ _cogl_primitive_immutable_ref (CoglPrimitive *primitive); void _cogl_primitive_immutable_unref (CoglPrimitive *primitive); -void +COGL_EXPORT void _cogl_primitive_draw (CoglPrimitive *primitive, CoglFramebuffer *framebuffer, CoglPipeline *pipeline, diff --git a/cogl/cogl/cogl-primitive-texture.c b/cogl/cogl/cogl-primitive-texture.c index ae913d1c9..f7f0aabd8 100644 --- a/cogl/cogl/cogl-primitive-texture.c +++ b/cogl/cogl/cogl-primitive-texture.c @@ -30,14 +30,12 @@ * Neil Roberts */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-primitive-texture.h" #include "cogl-texture-private.h" -CoglBool +gboolean cogl_is_primitive_texture (void *object) { return (cogl_is_texture (object) && @@ -46,11 +44,11 @@ cogl_is_primitive_texture (void *object) void cogl_primitive_texture_set_auto_mipmap (CoglPrimitiveTexture *primitive_texture, - CoglBool value) + gboolean value) { CoglTexture *texture; - _COGL_RETURN_IF_FAIL (cogl_is_primitive_texture (primitive_texture)); + g_return_if_fail (cogl_is_primitive_texture (primitive_texture)); texture = COGL_TEXTURE (primitive_texture); diff --git a/cogl/cogl/cogl-primitive-texture.h b/cogl/cogl/cogl-primitive-texture.h index 4e239af94..8d6efe9dc 100644 --- a/cogl/cogl/cogl-primitive-texture.h +++ b/cogl/cogl/cogl-primitive-texture.h @@ -37,19 +37,18 @@ #include "cogl-types.h" -COGL_BEGIN_DECLS +G_BEGIN_DECLS /** * SECTION:cogl-primitive-texture * @short_description: Interface for low-level textures like - * #CoglTexture2D and #CoglTexture3D. + * #CoglTexture2D. * * A #CoglPrimitiveTexture is a texture that is directly represented - * by a single texture on the GPU. For example these could be a - * #CoglTexture2D, #CoglTexture3D or #CoglTextureRectangle. This is - * opposed to high level meta textures which may be composed of - * multiple primitive textures or a sub-region of another texture such - * as #CoglAtlasTexture and #CoglTexture2DSliced. + * by a single texture on the GPU. For example this could be a + * #CoglTexture2D. This is opposed to high level meta textures which + * may be composed of multiple primitive textures or a sub-region of + * another texture such as #CoglAtlasTexture and #CoglTexture2DSliced. * * A texture that implements this interface can be directly used with * the low level cogl_primitive_draw() API. Other types of textures @@ -63,7 +62,7 @@ COGL_BEGIN_DECLS * primitive textures. */ -#if defined(__COGL_H_INSIDE__) && !defined(COGL_ENABLE_MUFFIN_API) && \ +#if defined(__COGL_H_INSIDE__) && !defined(COGL_ENABLE_MUTTER_API) && \ !defined(COGL_GIR_SCANNING) /* For the public C api we typedef interface types as void to avoid needing * lots of casting in code and instead we will rely on runtime type checking @@ -85,7 +84,7 @@ typedef struct _CoglPrimitiveTexture CoglPrimitiveTexture; * Since: 2.0 * Stability: unstable */ -CoglBool +gboolean cogl_is_primitive_texture (void *object); /** @@ -103,10 +102,10 @@ cogl_is_primitive_texture (void *object); * Since: 2.0 * Stability: unstable */ -void +COGL_EXPORT void cogl_primitive_texture_set_auto_mipmap (CoglPrimitiveTexture *primitive_texture, - CoglBool value); + gboolean value); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_PRIMITIVE_TEXTURE_H__ */ diff --git a/cogl/cogl/cogl-primitive.c b/cogl/cogl/cogl-primitive.c index 728d94f5e..ff547387f 100644 --- a/cogl/cogl/cogl-primitive.c +++ b/cogl/cogl/cogl-primitive.c @@ -31,9 +31,7 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-util.h" #include "cogl-object-private.h" @@ -76,7 +74,7 @@ cogl_primitive_new_with_attributes (CoglVerticesMode mode, CoglAttribute *attribute = attributes[i]; cogl_object_ref (attribute); - _COGL_RETURN_VAL_IF_FAIL (cogl_is_attribute (attribute), NULL); + g_return_val_if_fail (cogl_is_attribute (attribute), NULL); primitive->attributes[i] = attribute; } @@ -400,7 +398,7 @@ _cogl_primitive_free (CoglPrimitive *primitive) static void warn_about_midscene_changes (void) { - static CoglBool seen = FALSE; + static gboolean seen = FALSE; if (!seen) { g_warning ("Mid-scene modification of primitives has " @@ -416,7 +414,7 @@ cogl_primitive_set_attributes (CoglPrimitive *primitive, { int i; - _COGL_RETURN_IF_FAIL (cogl_is_primitive (primitive)); + g_return_if_fail (cogl_is_primitive (primitive)); if (G_UNLIKELY (primitive->immutable_ref)) { @@ -429,7 +427,7 @@ cogl_primitive_set_attributes (CoglPrimitive *primitive, * attribute thats actually in the new list too. */ for (i = 0; i < n_attributes; i++) { - _COGL_RETURN_IF_FAIL (cogl_is_attribute (attributes[i])); + g_return_if_fail (cogl_is_attribute (attributes[i])); cogl_object_ref (attributes[i]); } @@ -465,7 +463,7 @@ cogl_primitive_set_attributes (CoglPrimitive *primitive, int cogl_primitive_get_first_vertex (CoglPrimitive *primitive) { - _COGL_RETURN_VAL_IF_FAIL (cogl_is_primitive (primitive), 0); + g_return_val_if_fail (cogl_is_primitive (primitive), 0); return primitive->first_vertex; } @@ -474,7 +472,7 @@ void cogl_primitive_set_first_vertex (CoglPrimitive *primitive, int first_vertex) { - _COGL_RETURN_IF_FAIL (cogl_is_primitive (primitive)); + g_return_if_fail (cogl_is_primitive (primitive)); if (G_UNLIKELY (primitive->immutable_ref)) { @@ -488,7 +486,7 @@ cogl_primitive_set_first_vertex (CoglPrimitive *primitive, int cogl_primitive_get_n_vertices (CoglPrimitive *primitive) { - _COGL_RETURN_VAL_IF_FAIL (cogl_is_primitive (primitive), 0); + g_return_val_if_fail (cogl_is_primitive (primitive), 0); return primitive->n_vertices; } @@ -497,7 +495,7 @@ void cogl_primitive_set_n_vertices (CoglPrimitive *primitive, int n_vertices) { - _COGL_RETURN_IF_FAIL (cogl_is_primitive (primitive)); + g_return_if_fail (cogl_is_primitive (primitive)); primitive->n_vertices = n_vertices; } @@ -505,7 +503,7 @@ cogl_primitive_set_n_vertices (CoglPrimitive *primitive, CoglVerticesMode cogl_primitive_get_mode (CoglPrimitive *primitive) { - _COGL_RETURN_VAL_IF_FAIL (cogl_is_primitive (primitive), 0); + g_return_val_if_fail (cogl_is_primitive (primitive), 0); return primitive->mode; } @@ -514,7 +512,7 @@ void cogl_primitive_set_mode (CoglPrimitive *primitive, CoglVerticesMode mode) { - _COGL_RETURN_IF_FAIL (cogl_is_primitive (primitive)); + g_return_if_fail (cogl_is_primitive (primitive)); if (G_UNLIKELY (primitive->immutable_ref)) { @@ -530,7 +528,7 @@ cogl_primitive_set_indices (CoglPrimitive *primitive, CoglIndices *indices, int n_indices) { - _COGL_RETURN_IF_FAIL (cogl_is_primitive (primitive)); + g_return_if_fail (cogl_is_primitive (primitive)); if (G_UNLIKELY (primitive->immutable_ref)) { @@ -573,7 +571,7 @@ _cogl_primitive_immutable_ref (CoglPrimitive *primitive) { int i; - _COGL_RETURN_VAL_IF_FAIL (cogl_is_primitive (primitive), NULL); + g_return_val_if_fail (cogl_is_primitive (primitive), NULL); primitive->immutable_ref++; @@ -588,8 +586,8 @@ _cogl_primitive_immutable_unref (CoglPrimitive *primitive) { int i; - _COGL_RETURN_IF_FAIL (cogl_is_primitive (primitive)); - _COGL_RETURN_IF_FAIL (primitive->immutable_ref > 0); + g_return_if_fail (cogl_is_primitive (primitive)); + g_return_if_fail (primitive->immutable_ref > 0); primitive->immutable_ref--; diff --git a/cogl/cogl/cogl-primitive.h b/cogl/cogl/cogl-primitive.h index e1c5d4002..5b3a70c88 100644 --- a/cogl/cogl/cogl-primitive.h +++ b/cogl/cogl/cogl-primitive.h @@ -49,7 +49,7 @@ typedef struct _CoglPrimitive CoglPrimitive; #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS /** * SECTION:cogl-primitive @@ -70,6 +70,7 @@ COGL_BEGIN_DECLS * * Returns: a #GType that can be used with the GLib type system. */ +COGL_EXPORT GType cogl_primitive_get_gtype (void); /** @@ -249,7 +250,7 @@ typedef struct { * Since: 1.6 * Stability: Unstable */ -CoglPrimitive * +COGL_EXPORT CoglPrimitive * cogl_primitive_new (CoglVerticesMode mode, int n_vertices, ...); @@ -275,7 +276,7 @@ cogl_primitive_new (CoglVerticesMode mode, * Since: 1.6 * Stability: Unstable */ -CoglPrimitive * +COGL_EXPORT CoglPrimitive * cogl_primitive_new_with_attributes (CoglVerticesMode mode, int n_vertices, CoglAttribute **attributes, @@ -329,7 +330,7 @@ cogl_primitive_new_with_attributes (CoglVerticesMode mode, * Since: 1.6 * Stability: Unstable */ -CoglPrimitive * +COGL_EXPORT CoglPrimitive * cogl_primitive_new_p2 (CoglContext *context, CoglVerticesMode mode, int n_vertices, @@ -383,7 +384,7 @@ cogl_primitive_new_p2 (CoglContext *context, * Since: 1.6 * Stability: Unstable */ -CoglPrimitive * +COGL_EXPORT CoglPrimitive * cogl_primitive_new_p3 (CoglContext *context, CoglVerticesMode mode, int n_vertices, @@ -439,7 +440,7 @@ cogl_primitive_new_p3 (CoglContext *context, * Since: 1.6 * Stability: Unstable */ -CoglPrimitive * +COGL_EXPORT CoglPrimitive * cogl_primitive_new_p2c4 (CoglContext *context, CoglVerticesMode mode, int n_vertices, @@ -495,7 +496,7 @@ cogl_primitive_new_p2c4 (CoglContext *context, * Since: 1.6 * Stability: Unstable */ -CoglPrimitive * +COGL_EXPORT CoglPrimitive * cogl_primitive_new_p3c4 (CoglContext *context, CoglVerticesMode mode, int n_vertices, @@ -551,7 +552,7 @@ cogl_primitive_new_p3c4 (CoglContext *context, * Since: 1.6 * Stability: Unstable */ -CoglPrimitive * +COGL_EXPORT CoglPrimitive * cogl_primitive_new_p2t2 (CoglContext *context, CoglVerticesMode mode, int n_vertices, @@ -607,7 +608,7 @@ cogl_primitive_new_p2t2 (CoglContext *context, * Since: 1.6 * Stability: Unstable */ -CoglPrimitive * +COGL_EXPORT CoglPrimitive * cogl_primitive_new_p3t2 (CoglContext *context, CoglVerticesMode mode, int n_vertices, @@ -663,7 +664,7 @@ cogl_primitive_new_p3t2 (CoglContext *context, * Since: 1.6 * Stability: Unstable */ -CoglPrimitive * +COGL_EXPORT CoglPrimitive * cogl_primitive_new_p2t2c4 (CoglContext *context, CoglVerticesMode mode, int n_vertices, @@ -719,15 +720,15 @@ cogl_primitive_new_p2t2c4 (CoglContext *context, * Since: 1.6 * Stability: Unstable */ -CoglPrimitive * +COGL_EXPORT CoglPrimitive * cogl_primitive_new_p3t2c4 (CoglContext *context, CoglVerticesMode mode, int n_vertices, const CoglVertexP3T2C4 *data); -int +COGL_EXPORT int cogl_primitive_get_first_vertex (CoglPrimitive *primitive); -void +COGL_EXPORT void cogl_primitive_set_first_vertex (CoglPrimitive *primitive, int first_vertex); @@ -753,7 +754,7 @@ cogl_primitive_set_first_vertex (CoglPrimitive *primitive, * Since: 1.8 * Stability: unstable */ -int +COGL_EXPORT int cogl_primitive_get_n_vertices (CoglPrimitive *primitive); /** @@ -774,14 +775,14 @@ cogl_primitive_get_n_vertices (CoglPrimitive *primitive); * Since: 1.8 * Stability: unstable */ -void +COGL_EXPORT void cogl_primitive_set_n_vertices (CoglPrimitive *primitive, int n_vertices); -CoglVerticesMode +COGL_EXPORT CoglVerticesMode cogl_primitive_get_mode (CoglPrimitive *primitive); -void +COGL_EXPORT void cogl_primitive_set_mode (CoglPrimitive *primitive, CoglVerticesMode mode); @@ -796,7 +797,7 @@ cogl_primitive_set_mode (CoglPrimitive *primitive, * Since: 1.6 * Stability: Unstable */ -void +COGL_EXPORT void cogl_primitive_set_attributes (CoglPrimitive *primitive, CoglAttribute **attributes, int n_attributes); @@ -829,7 +830,7 @@ cogl_primitive_set_attributes (CoglPrimitive *primitive, * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_primitive_set_indices (CoglPrimitive *primitive, CoglIndices *indices, int n_indices); @@ -844,7 +845,7 @@ cogl_primitive_set_indices (CoglPrimitive *primitive, * Since: 1.10 * Stability: unstable */ -CoglIndices * +COGL_EXPORT CoglIndices * cogl_primitive_get_indices (CoglPrimitive *primitive); /** @@ -859,7 +860,7 @@ cogl_primitive_get_indices (CoglPrimitive *primitive); * Since: 1.10 * Stability: unstable */ -CoglPrimitive * +COGL_EXPORT CoglPrimitive * cogl_primitive_copy (CoglPrimitive *primitive); /** @@ -874,7 +875,7 @@ cogl_primitive_copy (CoglPrimitive *primitive); * Since: 1.6 * Stability: Unstable */ -CoglBool +COGL_EXPORT gboolean cogl_is_primitive (void *object); /** @@ -892,7 +893,7 @@ cogl_is_primitive (void *object); * Since: 1.10 * Stability: Unstable */ -typedef CoglBool (* CoglPrimitiveAttributeCallback) (CoglPrimitive *primitive, +typedef gboolean (* CoglPrimitiveAttributeCallback) (CoglPrimitive *primitive, CoglAttribute *attribute, void *user_data); @@ -909,7 +910,7 @@ typedef CoglBool (* CoglPrimitiveAttributeCallback) (CoglPrimitive *primitive, * Since: 1.10 * Stability: Unstable */ -void +COGL_EXPORT void cogl_primitive_foreach_attribute (CoglPrimitive *primitive, CoglPrimitiveAttributeCallback callback, void *user_data); @@ -926,19 +927,19 @@ cogl_primitive_foreach_attribute (CoglPrimitive *primitive, * This drawing api doesn't support high-level meta texture types such * as #CoglTexture2DSliced so it is the user's responsibility to * ensure that only low-level textures that can be directly sampled by - * a GPU such as #CoglTexture2D, #CoglTextureRectangle or #CoglTexture3D - * are associated with layers of the given @pipeline. + * a GPU such as #CoglTexture2D are associated with layers of the given + * @pipeline. * * Stability: unstable * Since: 1.16 */ -void +COGL_EXPORT void cogl_primitive_draw (CoglPrimitive *primitive, CoglFramebuffer *framebuffer, CoglPipeline *pipeline); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_PRIMITIVE_H__ */ diff --git a/cogl/cogl/cogl-primitives-private.h b/cogl/cogl/cogl-primitives-private.h index 10db86905..637c33eba 100644 --- a/cogl/cogl/cogl-primitives-private.h +++ b/cogl/cogl/cogl-primitives-private.h @@ -33,7 +33,7 @@ #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS /* Draws a rectangle without going through the journal so that it will be flushed immediately. This should only be used in situations @@ -47,6 +47,13 @@ _cogl_rectangle_immediate (CoglFramebuffer *framebuffer, float x_2, float y_2); +void +cogl_2d_primitives_immediate (CoglFramebuffer *framebuffer, + CoglPipeline *pipeline, + CoglVerticesMode mode, + const CoglVertexP2 *vertices, + unsigned int n_vertices); + typedef struct _CoglMultiTexturedRect { const float *position; /* x0,y0,x1,y1 */ @@ -59,9 +66,8 @@ _cogl_framebuffer_draw_multitextured_rectangles ( CoglFramebuffer *framebuffer, CoglPipeline *pipeline, CoglMultiTexturedRect *rects, - int n_rects, - CoglBool disable_legacy_state); + int n_rects); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_PRIMITIVES_PRIVATE_H */ diff --git a/cogl/cogl/cogl-primitives.c b/cogl/cogl/cogl-primitives.c index 04d1262d1..7d5141d4d 100644 --- a/cogl/cogl/cogl-primitives.c +++ b/cogl/cogl/cogl-primitives.c @@ -28,17 +28,13 @@ * */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-debug.h" #include "cogl-context-private.h" #include "cogl-journal-private.h" #include "cogl-texture-private.h" #include "cogl-pipeline-private.h" -#include "cogl-pipeline-opengl-private.h" -#include "cogl-vertex-buffer-private.h" #include "cogl-framebuffer-private.h" #include "cogl-attribute-private.h" #include "cogl-private.h" @@ -65,8 +61,8 @@ typedef struct _TextureSlicedQuadState float v_to_q_scale_y; float quad_len_x; float quad_len_y; - CoglBool flipped_x; - CoglBool flipped_y; + gboolean flipped_x; + gboolean flipped_y; } TextureSlicedQuadState; typedef struct _TextureSlicedPolygonState @@ -141,7 +137,7 @@ typedef struct _ValidateFirstLayerState CoglPipeline *override_pipeline; } ValidateFirstLayerState; -static CoglBool +static gboolean validate_first_layer_cb (CoglPipeline *pipeline, int layer_index, void *user_data) @@ -189,8 +185,6 @@ validate_first_layer_cb (CoglPipeline *pipeline, * texture coordinates require repeating, * - CoglTexture2DAtlas: if the users given texture coordinates require * repeating, - * - CoglTextureRectangle: if the users given texture coordinates require - * repeating, * - CoglTexturePixmap: if the users given texture coordinates require * repeating */ @@ -207,10 +201,10 @@ _cogl_texture_quad_multiple_primitives (CoglFramebuffer *framebuffer, float ty_2) { TextureSlicedQuadState state; - CoglBool tex_virtual_flipped_x; - CoglBool tex_virtual_flipped_y; - CoglBool quad_flipped_x; - CoglBool quad_flipped_y; + gboolean tex_virtual_flipped_x; + gboolean tex_virtual_flipped_y; + gboolean quad_flipped_x; + gboolean quad_flipped_y; ValidateFirstLayerState validate_first_layer_state; CoglPipelineWrapMode wrap_s, wrap_t; @@ -297,13 +291,13 @@ typedef struct _ValidateTexCoordsState int user_tex_coords_len; float *final_tex_coords; CoglPipeline *override_pipeline; - CoglBool needs_multiple_primitives; + gboolean needs_multiple_primitives; } ValidateTexCoordsState; /* * Validate the texture coordinates for this rectangle. */ -static CoglBool +static gboolean validate_tex_coords_cb (CoglPipeline *pipeline, int layer_index, void *user_data) @@ -357,7 +351,7 @@ validate_tex_coords_cb (CoglPipeline *pipeline, { if (state->n_layers > 1) { - static CoglBool warning_seen = FALSE; + static gboolean warning_seen = FALSE; if (!warning_seen) g_warning ("Skipping layers 1..n of your material since " "the first layer doesn't support hardware " @@ -376,7 +370,7 @@ validate_tex_coords_cb (CoglPipeline *pipeline, } else { - static CoglBool warning_seen = FALSE; + static gboolean warning_seen = FALSE; if (!warning_seen) g_warning ("Skipping layer %d of your material " "since you have supplied texture coords " @@ -429,15 +423,13 @@ validate_tex_coords_cb (CoglPipeline *pipeline, * - CoglTexture2DSliced: if only comprised of a single slice with optional * waste, assuming the users given texture coordinates don't require * repeating. - * - CoglTexture{1D,2D,3D}: always. + * - CoglTexture{1D,2D}: always. * - CoglTexture2DAtlas: assuming the users given texture coordinates don't * require repeating. - * - CoglTextureRectangle: assuming the users given texture coordinates don't - * require repeating. * - CoglTexturePixmap: assuming the users given texture coordinates don't * require repeating. */ -static CoglBool +static gboolean _cogl_multitexture_quad_single_primitive (CoglFramebuffer *framebuffer, CoglPipeline *pipeline, const float *position, @@ -486,10 +478,10 @@ typedef struct _ValidateLayerState int i; int first_layer; CoglPipeline *override_source; - CoglBool all_use_sliced_quad_fallback; + gboolean all_use_sliced_quad_fallback; } ValidateLayerState; -static CoglBool +static gboolean _cogl_rectangles_validate_layer_cb (CoglPipeline *pipeline, int layer_index, void *user_data) @@ -566,7 +558,7 @@ _cogl_rectangles_validate_layer_cb (CoglPipeline *pipeline, { if (cogl_pipeline_get_n_layers (pipeline) > 1) { - static CoglBool warning_seen = FALSE; + static gboolean warning_seen = FALSE; if (!state->override_source) state->override_source = cogl_pipeline_copy (pipeline); @@ -587,7 +579,7 @@ _cogl_rectangles_validate_layer_cb (CoglPipeline *pipeline, } else { - static CoglBool warning_seen = FALSE; + static gboolean warning_seen = FALSE; CoglTexture2D *tex_2d; if (!warning_seen) @@ -618,7 +610,7 @@ _cogl_rectangles_validate_layer_cb (CoglPipeline *pipeline, if (!_cogl_texture_can_hardware_repeat (texture) && _cogl_pipeline_layer_has_user_matrix (pipeline, layer_index)) { - static CoglBool warning_seen = FALSE; + static gboolean warning_seen = FALSE; if (!warning_seen) g_warning ("layer %d of your pipeline uses a custom " "texture matrix but because the texture doesn't " @@ -637,8 +629,7 @@ _cogl_framebuffer_draw_multitextured_rectangles ( CoglFramebuffer *framebuffer, CoglPipeline *pipeline, CoglMultiTexturedRect *rects, - int n_rects, - CoglBool disable_legacy_state) + int n_rects) { CoglContext *ctx = framebuffer->context; CoglPipeline *original_pipeline; @@ -662,18 +653,6 @@ _cogl_framebuffer_draw_multitextured_rectangles ( if (state.override_source) pipeline = state.override_source; - if (!disable_legacy_state) - { - if (G_UNLIKELY (ctx->legacy_state_set) && - _cogl_get_enable_legacy_state ()) - { - /* If we haven't already made a pipeline copy */ - if (pipeline == original_pipeline) - pipeline = cogl_pipeline_copy (pipeline); - _cogl_pipeline_apply_legacy_state (pipeline); - } - } - /* * Emit geometry for each of the rectangles... */ @@ -686,7 +665,7 @@ _cogl_framebuffer_draw_multitextured_rectangles ( if (!state.all_use_sliced_quad_fallback) { - CoglBool success = + gboolean success = _cogl_multitexture_quad_single_primitive (framebuffer, pipeline, rects[i].position, @@ -728,421 +707,62 @@ _cogl_framebuffer_draw_multitextured_rectangles ( cogl_object_unref (pipeline); } -static void -_cogl_rectangles_with_multitexture_coords ( - CoglMultiTexturedRect *rects, - int n_rects) -{ - _cogl_framebuffer_draw_multitextured_rectangles (cogl_get_draw_framebuffer (), - cogl_get_source (), - rects, - n_rects, - FALSE); -} - -void -cogl_rectangles (const float *verts, - unsigned int n_rects) -{ - CoglMultiTexturedRect *rects; - int i; - - /* XXX: All the cogl_rectangle* APIs normalize their input into an array of - * CoglMultiTexturedRect rectangles and pass these on to our work horse; - * _cogl_rectangles_with_multitexture_coords. - */ - - rects = g_alloca (n_rects * sizeof (CoglMultiTexturedRect)); - - for (i = 0; i < n_rects; i++) - { - rects[i].position = &verts[i * 4]; - rects[i].tex_coords = NULL; - rects[i].tex_coords_len = 0; - } - - _cogl_rectangles_with_multitexture_coords (rects, n_rects); -} - -void -cogl_rectangles_with_texture_coords (const float *verts, - unsigned int n_rects) -{ - CoglMultiTexturedRect *rects; - int i; - - /* XXX: All the cogl_rectangle* APIs normalize their input into an array of - * CoglMultiTexturedRect rectangles and pass these on to our work horse; - * _cogl_rectangles_with_multitexture_coords. - */ - - rects = g_alloca (n_rects * sizeof (CoglMultiTexturedRect)); - - for (i = 0; i < n_rects; i++) - { - rects[i].position = &verts[i * 8]; - rects[i].tex_coords = &verts[i * 8 + 4]; - rects[i].tex_coords_len = 4; - } - - _cogl_rectangles_with_multitexture_coords (rects, n_rects); -} - -void -cogl_rectangle_with_texture_coords (float x_1, - float y_1, - float x_2, - float y_2, - float tx_1, - float ty_1, - float tx_2, - float ty_2) -{ - const float position[4] = {x_1, y_1, x_2, y_2}; - const float tex_coords[4] = {tx_1, ty_1, tx_2, ty_2}; - CoglMultiTexturedRect rect; - - /* XXX: All the cogl_rectangle* APIs normalize their input into an array of - * CoglMultiTexturedRect rectangles and pass these on to our work horse; - * _cogl_rectangles_with_multitexture_coords. - */ - - rect.position = position; - rect.tex_coords = tex_coords; - rect.tex_coords_len = 4; - - _cogl_rectangles_with_multitexture_coords (&rect, 1); -} - void -cogl_rectangle_with_multitexture_coords (float x_1, - float y_1, - float x_2, - float y_2, - const float *user_tex_coords, - int user_tex_coords_len) +cogl_2d_primitives_immediate (CoglFramebuffer *framebuffer, + CoglPipeline *pipeline, + CoglVerticesMode mode, + const CoglVertexP2 *vertices, + unsigned int n_vertices) { - const float position[4] = {x_1, y_1, x_2, y_2}; - CoglMultiTexturedRect rect; - - /* XXX: All the cogl_rectangle* APIs normalize their input into an array of - * CoglMultiTexturedRect rectangles and pass these on to our work horse; - * _cogl_rectangles_with_multitexture_coords. - */ - - rect.position = position; - rect.tex_coords = user_tex_coords; - rect.tex_coords_len = user_tex_coords_len; - - _cogl_rectangles_with_multitexture_coords (&rect, 1); -} - -void -cogl_rectangle (float x_1, - float y_1, - float x_2, - float y_2) -{ - const float position[4] = {x_1, y_1, x_2, y_2}; - CoglMultiTexturedRect rect; - - /* XXX: All the cogl_rectangle* APIs normalize their input into an array of - * CoglMultiTexturedRect rectangles and pass these on to our work horse; - * _cogl_rectangles_with_multitexture_coords. - */ - - rect.position = position; - rect.tex_coords = NULL; - rect.tex_coords_len = 0; - - _cogl_rectangles_with_multitexture_coords (&rect, 1); -} - -void -_cogl_rectangle_immediate (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - float x_1, - float y_1, - float x_2, - float y_2) -{ - /* Draw a rectangle using the vertex array API to avoid going - through the journal. This should only be used in cases where the - code might be called while the journal is already being flushed - such as when flushing the clip state */ CoglContext *ctx = framebuffer->context; - float vertices[8] = - { - x_1, y_1, - x_1, y_2, - x_2, y_1, - x_2, y_2 - }; CoglAttributeBuffer *attribute_buffer; CoglAttribute *attributes[1]; + size_t vertices_size = sizeof (CoglVertexP2) * n_vertices; attribute_buffer = - cogl_attribute_buffer_new (ctx, sizeof (vertices), vertices); + cogl_attribute_buffer_new (ctx, vertices_size, vertices); attributes[0] = cogl_attribute_new (attribute_buffer, "cogl_position_in", - sizeof (float) * 2, /* stride */ + sizeof (CoglVertexP2), /* stride */ 0, /* offset */ 2, /* n_components */ COGL_ATTRIBUTE_TYPE_FLOAT); _cogl_framebuffer_draw_attributes (framebuffer, pipeline, - COGL_VERTICES_MODE_TRIANGLE_STRIP, + mode, 0, /* first_index */ - 4, /* n_vertices */ + n_vertices, attributes, 1, COGL_DRAW_SKIP_JOURNAL_FLUSH | COGL_DRAW_SKIP_PIPELINE_VALIDATION | - COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH | - COGL_DRAW_SKIP_LEGACY_STATE); + COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH); cogl_object_unref (attributes[0]); cogl_object_unref (attribute_buffer); } -typedef struct _AppendTexCoordsState -{ - const CoglTextureVertex *vertices_in; - int vertex; - int layer; - float *vertices_out; -} AppendTexCoordsState; - -static CoglBool -append_tex_coord_attributes_cb (CoglPipeline *pipeline, - int layer_index, - void *user_data) -{ - AppendTexCoordsState *state = user_data; - CoglTexture *texture; - float tx, ty; - float *t; - - tx = state->vertices_in[state->vertex].tx; - ty = state->vertices_in[state->vertex].ty; - - /* NULL textures will be handled in - * _cogl_pipeline_flush_layers_gl_state but there is no need to worry - * about scaling texture coordinates in this case */ - texture = cogl_pipeline_get_layer_texture (pipeline, layer_index); - if (texture != NULL) - _cogl_texture_transform_coords_to_gl (texture, &tx, &ty); - - /* NB: [X,Y,Z,TX,TY...,R,G,B,A,...] */ - t = state->vertices_out + 3 + 2 * state->layer; - t[0] = tx; - t[1] = ty; - - state->layer++; - - return TRUE; -} - -typedef struct _ValidateState -{ - CoglPipeline *original_pipeline; - CoglPipeline *pipeline; -} ValidateState; - -static CoglBool -_cogl_polygon_validate_layer_cb (CoglPipeline *pipeline, - int layer_index, - void *user_data) -{ - ValidateState *state = user_data; - - /* By default COGL_PIPELINE_WRAP_MODE_AUTOMATIC becomes - * GL_CLAMP_TO_EDGE but we want the polygon API to use GL_REPEAT to - * maintain compatibility with previous releases - */ - - if (cogl_pipeline_get_layer_wrap_mode_s (pipeline, layer_index) == - COGL_PIPELINE_WRAP_MODE_AUTOMATIC) - { - if (state->original_pipeline == state->pipeline) - state->pipeline = cogl_pipeline_copy (pipeline); - - cogl_pipeline_set_layer_wrap_mode_s (state->pipeline, layer_index, - COGL_PIPELINE_WRAP_MODE_REPEAT); - } - - if (cogl_pipeline_get_layer_wrap_mode_t (pipeline, layer_index) == - COGL_PIPELINE_WRAP_MODE_AUTOMATIC) - { - if (state->original_pipeline == state->pipeline) - state->pipeline = cogl_pipeline_copy (pipeline); - - cogl_pipeline_set_layer_wrap_mode_t (state->pipeline, layer_index, - COGL_PIPELINE_WRAP_MODE_REPEAT); - } - - return TRUE; -} - void -cogl_polygon (const CoglTextureVertex *vertices, - unsigned int n_vertices, - CoglBool use_color) +_cogl_rectangle_immediate (CoglFramebuffer *framebuffer, + CoglPipeline *pipeline, + float x_1, + float y_1, + float x_2, + float y_2) { - CoglPipeline *pipeline; - ValidateState validate_state; - int n_layers; - int n_attributes; - CoglAttribute **attributes; - int i; - unsigned int stride; - size_t stride_bytes; - CoglAttributeBuffer *attribute_buffer; - float *v; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - pipeline = cogl_get_source (); - - validate_state.original_pipeline = pipeline; - validate_state.pipeline = pipeline; - cogl_pipeline_foreach_layer (pipeline, - _cogl_polygon_validate_layer_cb, - &validate_state); - pipeline = validate_state.pipeline; - - n_layers = cogl_pipeline_get_n_layers (pipeline); - - n_attributes = 1 + n_layers + (use_color ? 1 : 0); - attributes = g_alloca (sizeof (CoglAttribute *) * n_attributes); - - /* Our data is arranged like: - * [X, Y, Z, TX0, TY0, TX1, TY1..., R, G, B, A,...] */ - stride = 3 + (2 * n_layers) + (use_color ? 1 : 0); - stride_bytes = stride * sizeof (float); - - /* Make sure there is enough space in the global vertex array. This - * is used so we can render the polygon with a single call to OpenGL - * but still support any number of vertices */ - g_array_set_size (ctx->polygon_vertices, n_vertices * stride); - - attribute_buffer = - cogl_attribute_buffer_new (ctx, n_vertices * stride_bytes, NULL); - - attributes[0] = cogl_attribute_new (attribute_buffer, - "cogl_position_in", - stride_bytes, - 0, - 3, - COGL_ATTRIBUTE_TYPE_FLOAT); - - for (i = 0; i < n_layers; i++) - { - static const char *names[] = { - "cogl_tex_coord0_in", - "cogl_tex_coord1_in", - "cogl_tex_coord2_in", - "cogl_tex_coord3_in", - "cogl_tex_coord4_in", - "cogl_tex_coord5_in", - "cogl_tex_coord6_in", - "cogl_tex_coord7_in" - }; - char *allocated_name = NULL; - const char *name; - - if (i < 8) - name = names[i]; - else - name = allocated_name = g_strdup_printf ("cogl_tex_coord%d_in", i); - - attributes[i + 1] = cogl_attribute_new (attribute_buffer, - name, - stride_bytes, - /* NB: [X,Y,Z,TX,TY...,R,G,B,A,...] */ - 12 + 8 * i, - 2, - COGL_ATTRIBUTE_TYPE_FLOAT); - - free (allocated_name); - } - - if (use_color) + CoglVertexP2 vertices[4] = { - attributes[n_attributes - 1] = - cogl_attribute_new (attribute_buffer, - "cogl_color_in", - stride_bytes, - /* NB: [X,Y,Z,TX,TY...,R,G,B,A,...] */ - 12 + 8 * n_layers, - 4, - COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE); - } - - /* Convert the vertices into an array of float vertex attributes */ - v = (float *)ctx->polygon_vertices->data; - for (i = 0; i < n_vertices; i++) - { - AppendTexCoordsState append_tex_coords_state; - uint8_t *c; - - /* NB: [X,Y,Z,TX,TY...,R,G,B,A,...] */ - v[0] = vertices[i].x; - v[1] = vertices[i].y; - v[2] = vertices[i].z; - - append_tex_coords_state.vertices_in = vertices; - append_tex_coords_state.vertex = i; - append_tex_coords_state.layer = 0; - append_tex_coords_state.vertices_out = v; - cogl_pipeline_foreach_layer (pipeline, - append_tex_coord_attributes_cb, - &append_tex_coords_state); - - if (use_color) - { - /* NB: [X,Y,Z,TX,TY...,R,G,B,A,...] */ - c = (uint8_t *) (v + 3 + 2 * n_layers); - c[0] = cogl_color_get_red_byte (&vertices[i].color); - c[1] = cogl_color_get_green_byte (&vertices[i].color); - c[2] = cogl_color_get_blue_byte (&vertices[i].color); - c[3] = cogl_color_get_alpha_byte (&vertices[i].color); - } - - v += stride; - } - - v = (float *)ctx->polygon_vertices->data; - cogl_buffer_set_data (COGL_BUFFER (attribute_buffer), - 0, - v, - ctx->polygon_vertices->len * sizeof (float)); - - /* XXX: although this may seem redundant, we need to do this since - * cogl_polygon() can be used with legacy state and its the source stack - * which track whether legacy state is enabled. - * - * (We only have a CoglDrawFlag to disable legacy state not one - * to enable it) */ - cogl_push_source (pipeline); - - _cogl_framebuffer_draw_attributes (cogl_get_draw_framebuffer (), - pipeline, - COGL_VERTICES_MODE_TRIANGLE_FAN, - 0, n_vertices, - attributes, - n_attributes, - 0 /* no draw flags */); - - cogl_pop_source (); - - if (pipeline != validate_state.original_pipeline) - cogl_object_unref (pipeline); - - cogl_object_unref (attribute_buffer); + {x_1, y_1}, + {x_1, y_2}, + {x_2, y_1}, + {x_2, y_2} + }; - for (i = 0; i < n_attributes; i++) - cogl_object_unref (attributes[i]); + cogl_2d_primitives_immediate (framebuffer, + pipeline, + COGL_VERTICES_MODE_TRIANGLE_STRIP, + vertices, + 4); } diff --git a/cogl/cogl/cogl-primitives.h b/cogl/cogl/cogl-primitives.h deleted file mode 100644 index 0c9211eee..000000000 --- a/cogl/cogl/cogl-primitives.h +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_PRIMITIVES_H -#define __COGL_PRIMITIVES_H - -#include - -COGL_BEGIN_DECLS - -/** - * SECTION:cogl-primitives - * @short_description: Functions that draw various primitive 3D shapes - * - * The primitives API provides utilities for drawing some - * common 3D shapes in a more convenient way than the CoglVertexBuffer - * API provides. - */ - -/** - * cogl_rectangle: - * @x_1: X coordinate of the top-left corner - * @y_1: Y coordinate of the top-left corner - * @x_2: X coordinate of the bottom-right corner - * @y_2: Y coordinate of the bottom-right corner - * - * Fills a rectangle at the given coordinates with the current source material - **/ -void -cogl_rectangle (float x_1, - float y_1, - float x_2, - float y_2); - -/** - * cogl_rectangle_with_texture_coords: - * @x1: x coordinate upper left on screen. - * @y1: y coordinate upper left on screen. - * @x2: x coordinate lower right on screen. - * @y2: y coordinate lower right on screen. - * @tx1: x part of texture coordinate to use for upper left pixel - * @ty1: y part of texture coordinate to use for upper left pixel - * @tx2: x part of texture coordinate to use for lower right pixel - * @ty2: y part of texture coordinate to use for left pixel - * - * Draw a rectangle using the current material and supply texture coordinates - * to be used for the first texture layer of the material. To draw the entire - * texture pass in @tx1=0.0 @ty1=0.0 @tx2=1.0 @ty2=1.0. - * - * Since: 1.0 - */ -void -cogl_rectangle_with_texture_coords (float x1, - float y1, - float x2, - float y2, - float tx1, - float ty1, - float tx2, - float ty2); - -/** - * cogl_rectangle_with_multitexture_coords: - * @x1: x coordinate upper left on screen. - * @y1: y coordinate upper left on screen. - * @x2: x coordinate lower right on screen. - * @y2: y coordinate lower right on screen. - * @tex_coords: (in) (array) (transfer none): An array containing groups of - * 4 float values: [tx1, ty1, tx2, ty2] that are interpreted as two texture - * coordinates; one for the upper left texel, and one for the lower right - * texel. Each value should be between 0.0 and 1.0, where the coordinate - * (0.0, 0.0) represents the top left of the texture, and (1.0, 1.0) the - * bottom right. - * @tex_coords_len: The length of the tex_coords array. (e.g. for one layer - * and one group of texture coordinates, this would be 4) - * - * This function draws a rectangle using the current source material to - * texture or fill with. As a material may contain multiple texture layers - * this interface lets you supply texture coordinates for each layer of the - * material. - * - * The first pair of coordinates are for the first layer (with the smallest - * layer index) and if you supply less texture coordinates than there are - * layers in the current source material then default texture coordinates - * (0.0, 0.0, 1.0, 1.0) are generated. - * - * Since: 1.0 - */ -void -cogl_rectangle_with_multitexture_coords (float x1, - float y1, - float x2, - float y2, - const float *tex_coords, - int tex_coords_len); - -/** - * cogl_rectangles_with_texture_coords: - * @verts: (in) (array) (transfer none): an array of vertices - * @n_rects: number of rectangles to draw - * - * Draws a series of rectangles in the same way that - * cogl_rectangle_with_texture_coords() does. In some situations it can give a - * significant performance boost to use this function rather than - * calling cogl_rectangle_with_texture_coords() separately for each rectangle. - * - * @verts should point to an array of #floats with - * @n_rects * 8 elements. Each group of 8 values corresponds to the - * parameters x1, y1, x2, y2, tx1, ty1, tx2 and ty2 and have the same - * meaning as in cogl_rectangle_with_texture_coords(). - * - * Since: 0.8.6 - */ -void -cogl_rectangles_with_texture_coords (const float *verts, - unsigned int n_rects); - -/** - * cogl_rectangles: - * @verts: (in) (array) (transfer none): an array of vertices - * @n_rects: number of rectangles to draw - * - * Draws a series of rectangles in the same way that - * cogl_rectangle() does. In some situations it can give a - * significant performance boost to use this function rather than - * calling cogl_rectangle() separately for each rectangle. - * - * @verts should point to an array of #floats with - * @n_rects * 4 elements. Each group of 4 values corresponds to the - * parameters x1, y1, x2, and y2, and have the same - * meaning as in cogl_rectangle(). - * - * Since: 1.0 - */ -void -cogl_rectangles (const float *verts, - unsigned int n_rects); - -/** - * cogl_polygon: - * @vertices: An array of #CoglTextureVertex structs - * @n_vertices: The length of the vertices array - * @use_color: %TRUE if the color member of #CoglTextureVertex should be used - * - * Draws a convex polygon using the current source material to fill / texture - * with according to the texture coordinates passed. - * - * If @use_color is %TRUE then the color will be changed for each vertex using - * the value specified in the color member of #CoglTextureVertex. This can be - * used for example to make the texture fade out by setting the alpha value of - * the color. - * - * All of the texture coordinates must be in the range [0,1] and repeating the - * texture is not supported. - * - * Because of the way this function is implemented it will currently - * only work if either the texture is not sliced or the backend is not - * OpenGL ES and the minifying and magnifying functions are both set - * to COGL_MATERIAL_FILTER_NEAREST. - * - * Since: 1.0 - */ -void -cogl_polygon (const CoglTextureVertex *vertices, - unsigned int n_vertices, - CoglBool use_color); - -COGL_END_DECLS - -#endif /* __COGL_PRIMITIVES_H */ diff --git a/cogl/cogl/cogl-private.h b/cogl/cogl/cogl-private.h index e5dc9feda..76829d454 100644 --- a/cogl/cogl/cogl-private.h +++ b/cogl/cogl/cogl-private.h @@ -36,50 +36,35 @@ #include "cogl-context.h" #include "cogl-flags.h" -COGL_BEGIN_DECLS +G_BEGIN_DECLS typedef enum { COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE, COGL_PRIVATE_FEATURE_MESA_PACK_INVERT, - COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT, - COGL_PRIVATE_FEATURE_FOUR_CLIP_PLANES, + COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER, COGL_PRIVATE_FEATURE_PBOS, - COGL_PRIVATE_FEATURE_VBOS, COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL, COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL, COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_BGRA8888, COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE, COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS, COGL_PRIVATE_FEATURE_READ_PIXELS_ANY_FORMAT, - COGL_PRIVATE_FEATURE_ALPHA_TEST, COGL_PRIVATE_FEATURE_FORMAT_CONVERSION, - COGL_PRIVATE_FEATURE_QUADS, - COGL_PRIVATE_FEATURE_BLEND_CONSTANT, COGL_PRIVATE_FEATURE_QUERY_FRAMEBUFFER_BITS, - COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM, COGL_PRIVATE_FEATURE_QUERY_TEXTURE_PARAMETERS, COGL_PRIVATE_FEATURE_ALPHA_TEXTURES, COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE, COGL_PRIVATE_FEATURE_TEXTURE_MAX_LEVEL, - COGL_PRIVATE_FEATURE_ARBFP, COGL_PRIVATE_FEATURE_OES_EGL_SYNC, /* If this is set then the winsys is responsible for queueing dirty * events. Otherwise a dirty event will be queued when the onscreen * is first allocated or when it is shown or resized */ COGL_PRIVATE_FEATURE_DIRTY_EVENTS, - COGL_PRIVATE_FEATURE_ENABLE_PROGRAM_POINT_SIZE, - /* These features let us avoid conditioning code based on the exact - * driver being used and instead check for broad opengl feature - * sets that can be shared by several GL apis */ + /* This feature allows for explicitly selecting a GL-based backend, + * as opposed to nop or (in the future) Vulkan. + */ COGL_PRIVATE_FEATURE_ANY_GL, - COGL_PRIVATE_FEATURE_GL_FIXED, - COGL_PRIVATE_FEATURE_GL_PROGRAMMABLE, - COGL_PRIVATE_FEATURE_GL_EMBEDDED, - COGL_PRIVATE_FEATURE_GL_WEB, - /* This is currently only implemented for GLX, but isn't actually - * that winsys dependent */ - COGL_PRIVATE_FEATURE_THREADED_SWAP_WAIT, COGL_N_PRIVATE_FEATURES } CoglPrivateFeature; @@ -99,75 +84,15 @@ _cogl_transform_point (const CoglMatrix *matrix_mv, float *x, float *y); -CoglBool +gboolean _cogl_check_extension (const char *name, char * const *ext); -void -_cogl_clear (const CoglColor *color, unsigned long buffers); - void _cogl_init (void); -void -_cogl_push_source (CoglPipeline *pipeline, CoglBool enable_legacy); - -CoglBool -_cogl_get_enable_legacy_state (void); - #define _cogl_has_private_feature(ctx, feature) \ COGL_FLAGS_GET ((ctx)->private_features, (feature)) -/* - * _cogl_pixel_format_get_bytes_per_pixel: - * @format: a #CoglPixelFormat - * - * Queries how many bytes a pixel of the given @format takes. - * - * Return value: The number of bytes taken for a pixel of the given - * @format. - */ -int -_cogl_pixel_format_get_bytes_per_pixel (CoglPixelFormat format); - -/* - * _cogl_pixel_format_has_aligned_components: - * @format: a #CoglPixelFormat - * - * Queries whether the ordering of the components for the given - * @format depend on the endianness of the host CPU or if the - * components can be accessed using bit shifting and bitmasking by - * loading a whole pixel into a word. - * - * XXX: If we ever consider making something like this public we - * should really try to think of a better name and come up with - * much clearer documentation since it really depends on what - * point of view you consider this from whether a format like - * COGL_PIXEL_FORMAT_RGBA_8888 is endian dependent. E.g. If you - * read an RGBA_8888 pixel into a uint32 - * it's endian dependent how you mask out the different channels. - * But If you already have separate color components and you want - * to write them to an RGBA_8888 pixel then the bytes can be - * written sequentially regardless of the endianness. - * - * Return value: %TRUE if you need to consider the host CPU - * endianness when dealing with the given @format - * else %FALSE. - */ -CoglBool -_cogl_pixel_format_is_endian_dependant (CoglPixelFormat format); - -/* - * COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT(format): - * @format: a #CoglPixelFormat - * - * Returns TRUE if the pixel format can take a premult bit. This is - * currently true for all formats that have an alpha channel except - * COGL_PIXEL_FORMAT_A_8 (because that doesn't have any other - * components to multiply by the alpha). - */ -#define COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT(format) \ - (((format) & COGL_A_BIT) && (format) != COGL_PIXEL_FORMAT_A_8) - -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_PRIVATE_H__ */ diff --git a/cogl/cogl/cogl-profile.c b/cogl/cogl/cogl-profile.c index d5bca6a20..c7ee7dca1 100644 --- a/cogl/cogl/cogl-profile.c +++ b/cogl/cogl/cogl-profile.c @@ -1,6 +1,4 @@ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #ifdef COGL_ENABLE_PROFILE @@ -12,7 +10,7 @@ UProfContext *_cogl_uprof_context; -static CoglBool +static gboolean debug_option_getter (void *user_data) { unsigned int shift = GPOINTER_TO_UINT (user_data); @@ -20,7 +18,7 @@ debug_option_getter (void *user_data) } static void -debug_option_setter (CoglBool value, void *user_data) +debug_option_setter (gboolean value, void *user_data) { unsigned int shift = GPOINTER_TO_UINT (user_data); diff --git a/cogl/cogl/cogl-profile.h b/cogl/cogl/cogl-profile.h index db95647e9..ad32a3f16 100644 --- a/cogl/cogl/cogl-profile.h +++ b/cogl/cogl/cogl-profile.h @@ -48,13 +48,13 @@ extern UProfContext *_cogl_uprof_context; void _cogl_uprof_init (void); -void +COGL_EXPORT void _cogl_profile_trace_message (const char *format, ...); #else -#define COGL_STATIC_TIMER(A,B,C,D,E) extern void _cogl_dummy_decl (void) -#define COGL_STATIC_COUNTER(A,B,C,D) extern void _cogl_dummy_decl (void) +#define COGL_STATIC_TIMER(A,B,C,D,E) G_STMT_START{ (void)0; }G_STMT_END +#define COGL_STATIC_COUNTER(A,B,C,D) G_STMT_START{ (void)0; }G_STMT_END #define COGL_COUNTER_INC(A,B) G_STMT_START{ (void)0; }G_STMT_END #define COGL_COUNTER_DEC(A,B) G_STMT_START{ (void)0; }G_STMT_END #define COGL_TIMER_START(A,B) G_STMT_START{ (void)0; }G_STMT_END diff --git a/cogl/cogl/cogl-quaternion-private.h b/cogl/cogl/cogl-quaternion-private.h deleted file mode 100644 index eda672ea8..000000000 --- a/cogl/cogl/cogl-quaternion-private.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg - */ - -#ifndef __COGL_QUATERNION_PRIVATE_H__ -#define __COGL_QUATERNION_PRIVATE_H__ - -#include - -/* squared length */ -#define _COGL_QUATERNION_NORM(Q) \ - ((Q)->x*(Q)->x + (Q)->y*(Q)->y + (Q)->z*(Q)->z + (Q)->w*(Q)->w) - -#define _COGL_QUATERNION_DEGREES_TO_RADIANS (G_PI / 180.0f) -#define _COGL_QUATERNION_RADIANS_TO_DEGREES (180.0f / G_PI) - -#endif /* __COGL_QUATERNION_PRIVATE_H__ */ diff --git a/cogl/cogl/cogl-quaternion.c b/cogl/cogl/cogl-quaternion.c deleted file mode 100644 index d380cec84..000000000 --- a/cogl/cogl/cogl-quaternion.c +++ /dev/null @@ -1,673 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg - * - * Various references relating to quaternions: - * - * http://www.cs.caltech.edu/courses/cs171/quatut.pdf - * http://mathworld.wolfram.com/Quaternion.html - * http://www.gamedev.net/reference/articles/article1095.asp - * http://www.cprogramming.com/tutorial/3d/quaternions.html - * http://www.isner.com/tutorials/quatSpells/quaternion_spells_12.htm - * http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q56 - * 3D Maths Primer for Graphics and Game Development ISBN-10: 1556229119 - */ - -#ifdef HAVE_CONFIG_H -#include "cogl-config.h" -#endif - -#include -#include -#include -#include -#include -#include -#include "cogl-gtype-private.h" - -#include -#include - -#define FLOAT_EPSILON 1e-03 - -COGL_GTYPE_DEFINE_BOXED (Quaternion, quaternion, - cogl_quaternion_copy, - cogl_quaternion_free); - -static CoglQuaternion zero_quaternion = -{ - 0.0, 0.0, 0.0, 0.0, -}; - -static CoglQuaternion identity_quaternion = -{ - 1.0, 0.0, 0.0, 0.0, -}; - -/* This function is just here to be called from GDB so we don't really - want to put a declaration in a header and we just add it here to - avoid a warning */ -void -_cogl_quaternion_print (CoglQuaternion *quarternion); - -void -_cogl_quaternion_print (CoglQuaternion *quaternion) -{ - g_print ("[ %6.4f (%6.4f, %6.4f, %6.4f)]\n", - quaternion->w, - quaternion->x, - quaternion->y, - quaternion->z); -} - -void -cogl_quaternion_init (CoglQuaternion *quaternion, - float angle, - float x, - float y, - float z) -{ - float axis[3] = { x, y, z}; - cogl_quaternion_init_from_angle_vector (quaternion, angle, axis); -} - -void -cogl_quaternion_init_from_angle_vector (CoglQuaternion *quaternion, - float angle, - const float *axis3f_in) -{ - /* NB: We are using quaternions to represent an axis (a), angle (𝜃) pair - * in this form: - * [w=cos(𝜃/2) ( x=sin(𝜃/2)*a.x, y=sin(𝜃/2)*a.y, z=sin(𝜃/2)*a.x )] - */ - float axis[3]; - float half_angle; - float sin_half_angle; - - /* XXX: Should we make cogl_vector3_normalize have separate in and - * out args? */ - axis[0] = axis3f_in[0]; - axis[1] = axis3f_in[1]; - axis[2] = axis3f_in[2]; - cogl_vector3_normalize (axis); - - half_angle = angle * _COGL_QUATERNION_DEGREES_TO_RADIANS * 0.5f; - sin_half_angle = sinf (half_angle); - - quaternion->w = cosf (half_angle); - - quaternion->x = axis[0] * sin_half_angle; - quaternion->y = axis[1] * sin_half_angle; - quaternion->z = axis[2] * sin_half_angle; - - cogl_quaternion_normalize (quaternion); -} - -void -cogl_quaternion_init_identity (CoglQuaternion *quaternion) -{ - quaternion->w = 1.0; - - quaternion->x = 0.0; - quaternion->y = 0.0; - quaternion->z = 0.0; -} - -void -cogl_quaternion_init_from_array (CoglQuaternion *quaternion, - const float *array) -{ - quaternion->w = array[0]; - quaternion->x = array[1]; - quaternion->y = array[2]; - quaternion->z = array[3]; -} - -void -cogl_quaternion_init_from_x_rotation (CoglQuaternion *quaternion, - float angle) -{ - /* NB: We are using quaternions to represent an axis (a), angle (𝜃) pair - * in this form: - * [w=cos(𝜃/2) ( x=sin(𝜃/2)*a.x, y=sin(𝜃/2)*a.y, z=sin(𝜃/2)*a.x )] - */ - float half_angle = angle * _COGL_QUATERNION_DEGREES_TO_RADIANS * 0.5f; - - quaternion->w = cosf (half_angle); - - quaternion->x = sinf (half_angle); - quaternion->y = 0.0f; - quaternion->z = 0.0f; -} - -void -cogl_quaternion_init_from_y_rotation (CoglQuaternion *quaternion, - float angle) -{ - /* NB: We are using quaternions to represent an axis (a), angle (𝜃) pair - * in this form: - * [w=cos(𝜃/2) ( x=sin(𝜃/2)*a.x, y=sin(𝜃/2)*a.y, z=sin(𝜃/2)*a.x )] - */ - float half_angle = angle * _COGL_QUATERNION_DEGREES_TO_RADIANS * 0.5f; - - quaternion->w = cosf (half_angle); - - quaternion->x = 0.0f; - quaternion->y = sinf (half_angle); - quaternion->z = 0.0f; -} - -void -cogl_quaternion_init_from_z_rotation (CoglQuaternion *quaternion, - float angle) -{ - /* NB: We are using quaternions to represent an axis (a), angle (𝜃) pair - * in this form: - * [w=cos(𝜃/2) ( x=sin(𝜃/2)*a.x, y=sin(𝜃/2)*a.y, z=sin(𝜃/2)*a.x )] - */ - float half_angle = angle * _COGL_QUATERNION_DEGREES_TO_RADIANS * 0.5f; - - quaternion->w = cosf (half_angle); - - quaternion->x = 0.0f; - quaternion->y = 0.0f; - quaternion->z = sinf (half_angle); -} - -void -cogl_quaternion_init_from_euler (CoglQuaternion *quaternion, - const CoglEuler *euler) -{ - /* NB: We are using quaternions to represent an axis (a), angle (𝜃) pair - * in this form: - * [w=cos(𝜃/2) ( x=sin(𝜃/2)*a.x, y=sin(𝜃/2)*a.y, z=sin(𝜃/2)*a.x )] - */ - float sin_heading = - sinf (euler->heading * _COGL_QUATERNION_DEGREES_TO_RADIANS * 0.5f); - float sin_pitch = - sinf (euler->pitch * _COGL_QUATERNION_DEGREES_TO_RADIANS * 0.5f); - float sin_roll = - sinf (euler->roll * _COGL_QUATERNION_DEGREES_TO_RADIANS * 0.5f); - float cos_heading = - cosf (euler->heading * _COGL_QUATERNION_DEGREES_TO_RADIANS * 0.5f); - float cos_pitch = - cosf (euler->pitch * _COGL_QUATERNION_DEGREES_TO_RADIANS * 0.5f); - float cos_roll = - cosf (euler->roll * _COGL_QUATERNION_DEGREES_TO_RADIANS * 0.5f); - - quaternion->w = - cos_heading * cos_pitch * cos_roll + - sin_heading * sin_pitch * sin_roll; - - quaternion->x = - cos_heading * sin_pitch * cos_roll + - sin_heading * cos_pitch * sin_roll; - quaternion->y = - sin_heading * cos_pitch * cos_roll - - cos_heading * sin_pitch * sin_roll; - quaternion->z = - cos_heading * cos_pitch * sin_roll - - sin_heading * sin_pitch * cos_roll; -} - -void -cogl_quaternion_init_from_quaternion (CoglQuaternion *quaternion, - CoglQuaternion *src) -{ - memcpy (quaternion, src, sizeof (float) * 4); -} - -/* XXX: it could be nice to make something like this public... */ -/* - * COGL_MATRIX_READ: - * @MATRIX: A 4x4 transformation matrix - * @ROW: The row of the value you want to read - * @COLUMN: The column of the value you want to read - * - * Reads a value from the given matrix using integers to index - * into the matrix. - */ -#define COGL_MATRIX_READ(MATRIX, ROW, COLUMN) \ - (((const float *)matrix)[COLUMN * 4 + ROW]) - -void -cogl_quaternion_init_from_matrix (CoglQuaternion *quaternion, - const CoglMatrix *matrix) -{ - /* Algorithm devised by Ken Shoemake, Ref: - * http://campar.in.tum.de/twiki/pub/Chair/DwarfTutorial/quatut.pdf - */ - - /* 3D maths literature refers to the diagonal of a matrix as the - * "trace" of a matrix... */ - float trace = matrix->xx + matrix->yy + matrix->zz; - float root; - - if (trace > 0.0f) - { - root = sqrtf (trace + 1); - quaternion->w = root * 0.5f; - root = 0.5f / root; - quaternion->x = (matrix->zy - matrix->yz) * root; - quaternion->y = (matrix->xz - matrix->zx) * root; - quaternion->z = (matrix->yx - matrix->xy) * root; - } - else - { -#define X 0 -#define Y 1 -#define Z 2 -#define W 3 - int h = X; - if (matrix->yy > matrix->xx) - h = Y; - if (matrix->zz > COGL_MATRIX_READ (matrix, h, h)) - h = Z; - switch (h) - { -#define CASE_MACRO(i, j, k, I, J, K) \ - case I: \ - root = sqrtf ((COGL_MATRIX_READ (matrix, I, I) - \ - (COGL_MATRIX_READ (matrix, J, J) + \ - COGL_MATRIX_READ (matrix, K, K))) + \ - COGL_MATRIX_READ (matrix, W, W)); \ - quaternion->i = root * 0.5f;\ - root = 0.5f / root;\ - quaternion->j = (COGL_MATRIX_READ (matrix, I, J) + \ - COGL_MATRIX_READ (matrix, J, I)) * root; \ - quaternion->k = (COGL_MATRIX_READ (matrix, K, I) + \ - COGL_MATRIX_READ (matrix, I, K)) * root; \ - quaternion->w = (COGL_MATRIX_READ (matrix, K, J) - \ - COGL_MATRIX_READ (matrix, J, K)) * root;\ - break - CASE_MACRO (x, y, z, X, Y, Z); - CASE_MACRO (y, z, x, Y, Z, X); - CASE_MACRO (z, x, y, Z, X, Y); -#undef CASE_MACRO -#undef X -#undef Y -#undef Z - } - } - - if (matrix->ww != 1.0f) - { - float s = 1.0 / sqrtf (matrix->ww); - quaternion->w *= s; - quaternion->x *= s; - quaternion->y *= s; - quaternion->z *= s; - } -} - -CoglBool -cogl_quaternion_equal (const void *v1, const void *v2) -{ - const CoglQuaternion *a = v1; - const CoglQuaternion *b = v2; - - _COGL_RETURN_VAL_IF_FAIL (v1 != NULL, FALSE); - _COGL_RETURN_VAL_IF_FAIL (v2 != NULL, FALSE); - - if (v1 == v2) - return TRUE; - - return (a->w == b->w && - a->x == b->x && - a->y == b->y && - a->z == b->z); -} - -CoglQuaternion * -cogl_quaternion_copy (const CoglQuaternion *src) -{ - if (G_LIKELY (src)) - { - CoglQuaternion *new = g_slice_new (CoglQuaternion); - memcpy (new, src, sizeof (float) * 4); - return new; - } - else - return NULL; -} - -void -cogl_quaternion_free (CoglQuaternion *quaternion) -{ - g_slice_free (CoglQuaternion, quaternion); -} - -float -cogl_quaternion_get_rotation_angle (const CoglQuaternion *quaternion) -{ - /* NB: We are using quaternions to represent an axis (a), angle (𝜃) pair - * in this form: - * [w=cos(𝜃/2) ( x=sin(𝜃/2)*a.x, y=sin(𝜃/2)*a.y, z=sin(𝜃/2)*a.x )] - */ - - /* FIXME: clamp [-1, 1] */ - return 2.0f * acosf (quaternion->w) * _COGL_QUATERNION_RADIANS_TO_DEGREES; -} - -void -cogl_quaternion_get_rotation_axis (const CoglQuaternion *quaternion, - float *vector3) -{ - float sin_half_angle_sqr; - float one_over_sin_angle_over_2; - - /* NB: We are using quaternions to represent an axis (a), angle (𝜃) pair - * in this form: - * [w=cos(𝜃/2) ( x=sin(𝜃/2)*a.x, y=sin(𝜃/2)*a.y, z=sin(𝜃/2)*a.x )] - */ - - /* NB: sin²(𝜃) + cos²(𝜃) = 1 */ - - sin_half_angle_sqr = 1.0f - quaternion->w * quaternion->w; - - if (sin_half_angle_sqr <= 0.0f) - { - /* Either an identity quaternion or numerical imprecision. - * Either way we return an arbitrary vector. */ - vector3[0] = 1; - vector3[1] = 0; - vector3[2] = 0; - return; - } - - /* Calculate 1 / sin(𝜃/2) */ - one_over_sin_angle_over_2 = 1.0f / sqrtf (sin_half_angle_sqr); - - vector3[0] = quaternion->x * one_over_sin_angle_over_2; - vector3[1] = quaternion->y * one_over_sin_angle_over_2; - vector3[2] = quaternion->z * one_over_sin_angle_over_2; -} - -void -cogl_quaternion_normalize (CoglQuaternion *quaternion) -{ - float slen = _COGL_QUATERNION_NORM (quaternion); - float factor = 1.0f / sqrtf (slen); - - quaternion->x *= factor; - quaternion->y *= factor; - quaternion->z *= factor; - - quaternion->w *= factor; - - return; -} - -float -cogl_quaternion_dot_product (const CoglQuaternion *a, - const CoglQuaternion *b) -{ - return a->w * b->w + a->x * b->x + a->y * b->y + a->z * b->z; -} - -void -cogl_quaternion_invert (CoglQuaternion *quaternion) -{ - quaternion->x = -quaternion->x; - quaternion->y = -quaternion->y; - quaternion->z = -quaternion->z; -} - -void -cogl_quaternion_multiply (CoglQuaternion *result, - const CoglQuaternion *a, - const CoglQuaternion *b) -{ - float w = a->w; - float x = a->x; - float y = a->y; - float z = a->z; - - _COGL_RETURN_IF_FAIL (b != result); - - result->w = w * b->w - x * b->x - y * b->y - z * b->z; - - result->x = w * b->x + x * b->w + y * b->z - z * b->y; - result->y = w * b->y + y * b->w + z * b->x - x * b->z; - result->z = w * b->z + z * b->w + x * b->y - y * b->x; -} - -void -cogl_quaternion_pow (CoglQuaternion *quaternion, float exponent) -{ - float half_angle; - float new_half_angle; - float factor; - - /* Try and identify and nop identity quaternions to avoid - * dividing by zero */ - if (fabs (quaternion->w) > 0.9999f) - return; - - /* NB: We are using quaternions to represent an axis (a), angle (𝜃) pair - * in this form: - * [w=cos(𝜃/2) ( x=sin(𝜃/2)*a.x, y=sin(𝜃/2)*a.y, z=sin(𝜃/2)*a.x )] - */ - - /* FIXME: clamp [-1, 1] */ - /* Extract 𝜃/2 from w */ - half_angle = acosf (quaternion->w); - - /* Compute the new 𝜃/2 */ - new_half_angle = half_angle * exponent; - - /* Compute the new w value */ - quaternion->w = cosf (new_half_angle); - - /* And new xyz values */ - factor = sinf (new_half_angle) / sinf (half_angle); - quaternion->x *= factor; - quaternion->y *= factor; - quaternion->z *= factor; -} - -void -cogl_quaternion_slerp (CoglQuaternion *result, - const CoglQuaternion *a, - const CoglQuaternion *b, - float t) -{ - float cos_difference; - float qb_w; - float qb_x; - float qb_y; - float qb_z; - float fa; - float fb; - - _COGL_RETURN_IF_FAIL (t >=0 && t <= 1.0f); - - if (t == 0) - { - *result = *a; - return; - } - else if (t == 1) - { - *result = *b; - return; - } - - /* compute the cosine of the angle between the two given quaternions */ - cos_difference = cogl_quaternion_dot_product (a, b); - - /* If negative, use -b. Two quaternions q and -q represent the same angle but - * may produce a different slerp. We choose b or -b to rotate using the acute - * angle. - */ - if (cos_difference < 0.0f) - { - qb_w = -b->w; - qb_x = -b->x; - qb_y = -b->y; - qb_z = -b->z; - cos_difference = -cos_difference; - } - else - { - qb_w = b->w; - qb_x = b->x; - qb_y = b->y; - qb_z = b->z; - } - - /* If we have two unit quaternions the dot should be <= 1.0 */ - g_assert (cos_difference < 1.1f); - - - /* Determine the interpolation factors for each quaternion, simply using - * linear interpolation for quaternions that are nearly exactly the same. - * (this will avoid divisions by zero) - */ - - if (cos_difference > 0.9999f) - { - fa = 1.0f - t; - fb = t; - - /* XXX: should we also normalize() at the end in this case? */ - } - else - { - /* Calculate the sin of the angle between the two quaternions using the - * trig identity: sin²(𝜃) + cos²(𝜃) = 1 - */ - float sin_difference = sqrtf (1.0f - cos_difference * cos_difference); - - float difference = atan2f (sin_difference, cos_difference); - float one_over_sin_difference = 1.0f / sin_difference; - fa = sinf ((1.0f - t) * difference) * one_over_sin_difference; - fb = sinf (t * difference) * one_over_sin_difference; - } - - /* Finally interpolate the two quaternions */ - - result->x = fa * a->x + fb * qb_x; - result->y = fa * a->y + fb * qb_y; - result->z = fa * a->z + fb * qb_z; - result->w = fa * a->w + fb * qb_w; -} - -void -cogl_quaternion_nlerp (CoglQuaternion *result, - const CoglQuaternion *a, - const CoglQuaternion *b, - float t) -{ - float cos_difference; - float qb_w; - float qb_x; - float qb_y; - float qb_z; - float fa; - float fb; - - _COGL_RETURN_IF_FAIL (t >=0 && t <= 1.0f); - - if (t == 0) - { - *result = *a; - return; - } - else if (t == 1) - { - *result = *b; - return; - } - - /* compute the cosine of the angle between the two given quaternions */ - cos_difference = cogl_quaternion_dot_product (a, b); - - /* If negative, use -b. Two quaternions q and -q represent the same angle but - * may produce a different slerp. We choose b or -b to rotate using the acute - * angle. - */ - if (cos_difference < 0.0f) - { - qb_w = -b->w; - qb_x = -b->x; - qb_y = -b->y; - qb_z = -b->z; - cos_difference = -cos_difference; - } - else - { - qb_w = b->w; - qb_x = b->x; - qb_y = b->y; - qb_z = b->z; - } - - /* If we have two unit quaternions the dot should be <= 1.0 */ - g_assert (cos_difference < 1.1f); - - fa = 1.0f - t; - fb = t; - - result->x = fa * a->x + fb * qb_x; - result->y = fa * a->y + fb * qb_y; - result->z = fa * a->z + fb * qb_z; - result->w = fa * a->w + fb * qb_w; - - cogl_quaternion_normalize (result); -} - -void -cogl_quaternion_squad (CoglQuaternion *result, - const CoglQuaternion *prev, - const CoglQuaternion *a, - const CoglQuaternion *b, - const CoglQuaternion *next, - float t) -{ - CoglQuaternion slerp0; - CoglQuaternion slerp1; - - cogl_quaternion_slerp (&slerp0, a, b, t); - cogl_quaternion_slerp (&slerp1, prev, next, t); - cogl_quaternion_slerp (result, &slerp0, &slerp1, 2.0f * t * (1.0f - t)); -} - -const CoglQuaternion * -cogl_get_static_identity_quaternion (void) -{ - return &identity_quaternion; -} - -const CoglQuaternion * -cogl_get_static_zero_quaternion (void) -{ - return &zero_quaternion; -} - diff --git a/cogl/cogl/cogl-quaternion.h b/cogl/cogl/cogl-quaternion.h deleted file mode 100644 index 0660f7e51..000000000 --- a/cogl/cogl/cogl-quaternion.h +++ /dev/null @@ -1,560 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL_QUATERNION_H__ -#define __COGL_QUATERNION_H__ - -#include -#include - -COGL_BEGIN_DECLS - -/** - * SECTION:cogl-quaternion - * @short_description: Functions for initializing and manipulating - * quaternions. - * - * Quaternions have become a standard form for representing 3D - * rotations and have some nice properties when compared with other - * representation such as (roll,pitch,yaw) Euler angles. They can be - * used to interpolate between different rotations and they don't - * suffer from a problem called - * "Gimbal lock" - * where two of the axis of rotation may become aligned and you loose a - * degree of freedom. - * . - */ -#include -#include - -#include - -/** - * CoglQuaternion: - * @w: based on the angle of rotation it is cos(𝜃/2) - * @x: based on the angle of rotation and x component of the axis of - * rotation it is sin(𝜃/2)*axis.x - * @y: based on the angle of rotation and y component of the axis of - * rotation it is sin(𝜃/2)*axis.y - * @z: based on the angle of rotation and z component of the axis of - * rotation it is sin(𝜃/2)*axis.z - * - * A quaternion is comprised of a scalar component and a 3D vector - * component. The scalar component is normally referred to as w and the - * vector might either be referred to as v or a (for axis) or expanded - * with the individual components: (x, y, z) A full quaternion would - * then be written as [w (x, y, z)]. - * - * Quaternions can be considered to represent an axis and angle - * pair although sadly these numbers are buried somewhat under some - * maths... - * - * For the curious you can see here that a given axis (a) and angle (𝜃) - * pair are represented in a quaternion as follows: - * |[ - * [w=cos(𝜃/2) ( x=sin(𝜃/2)*a.x, y=sin(𝜃/2)*a.y, z=sin(𝜃/2)*a.x )] - * ]| - * - * Unit Quaternions: - * When using Quaternions to represent spatial orientations for 3D - * graphics it's always assumed you have a unit quaternion. The - * magnitude of a quaternion is defined as: - * |[ - * sqrt (w² + x² + y² + z²) - * ]| - * and a unit quaternion satisfies this equation: - * |[ - * w² + x² + y² + z² = 1 - * ]| - * - * Thankfully most of the time we don't actually have to worry about - * the maths that goes on behind the scenes but if you are curious to - * learn more here are some external references: - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * 3D Maths Primer for Graphics and Game Development ISBN-10: 1556229119 - * - * - * - * - * - * - * - * - * - */ -struct _CoglQuaternion -{ - /*< public >*/ - float w; - - float x; - float y; - float z; - - /*< private >*/ - float padding0; - float padding1; - float padding2; - float padding3; -}; -COGL_STRUCT_SIZE_ASSERT (CoglQuaternion, 32); - -/** - * cogl_quaternion_get_gtype: - * - * Returns: a #GType that can be used with the GLib type system. - */ -GType cogl_quaternion_get_gtype (void); - -/** - * cogl_quaternion_init: - * @quaternion: An uninitialized #CoglQuaternion - * @angle: The angle you want to rotate around the given axis - * @x: The x component of your axis vector about which you want to - * rotate. - * @y: The y component of your axis vector about which you want to - * rotate. - * @z: The z component of your axis vector about which you want to - * rotate. - * - * Initializes a quaternion that rotates @angle degrees around the - * axis vector (@x, @y, @z). The axis vector does not need to be - * normalized. - * - * Returns: A normalized, unit quaternion representing an orientation - * rotated @angle degrees around the axis vector (@x, @y, @z) - * - * Since: 2.0 - */ -void -cogl_quaternion_init (CoglQuaternion *quaternion, - float angle, - float x, - float y, - float z); - -/** - * cogl_quaternion_init_from_angle_vector: - * @quaternion: An uninitialized #CoglQuaternion - * @angle: The angle to rotate around @axis3f - * @axis3f: your 3 component axis vector about which you want to rotate. - * - * Initializes a quaternion that rotates @angle degrees around the - * given @axis vector. The axis vector does not need to be - * normalized. - * - * Returns: A normalized, unit quaternion representing an orientation - * rotated @angle degrees around the given @axis vector. - * - * Since: 2.0 - */ -void -cogl_quaternion_init_from_angle_vector (CoglQuaternion *quaternion, - float angle, - const float *axis3f); - -/** - * cogl_quaternion_init_identity: - * @quaternion: An uninitialized #CoglQuaternion - * - * Initializes the quaternion with the canonical quaternion identity - * [1 (0, 0, 0)] which represents no rotation. Multiplying a - * quaternion with this identity leaves the quaternion unchanged. - * - * You might also want to consider using - * cogl_get_static_identity_quaternion(). - * - * Since: 2.0 - */ -void -cogl_quaternion_init_identity (CoglQuaternion *quaternion); - -/** - * cogl_quaternion_init_from_array: - * @quaternion: A #CoglQuaternion - * @array: An array of 4 floats w,(x,y,z) - * - * Initializes a [w (x, y,z)] quaternion directly from an array of 4 - * floats: [w,x,y,z]. - * - * Since: 2.0 - */ -void -cogl_quaternion_init_from_array (CoglQuaternion *quaternion, - const float *array); - -/** - * cogl_quaternion_init_from_x_rotation: - * @quaternion: An uninitialized #CoglQuaternion - * @angle: The angle to rotate around the x axis - * - * XXX: check which direction this rotates - * - * Since: 2.0 - */ -void -cogl_quaternion_init_from_x_rotation (CoglQuaternion *quaternion, - float angle); - -/** - * cogl_quaternion_init_from_y_rotation: - * @quaternion: An uninitialized #CoglQuaternion - * @angle: The angle to rotate around the y axis - * - * - * Since: 2.0 - */ -void -cogl_quaternion_init_from_y_rotation (CoglQuaternion *quaternion, - float angle); - -/** - * cogl_quaternion_init_from_z_rotation: - * @quaternion: An uninitialized #CoglQuaternion - * @angle: The angle to rotate around the z axis - * - * - * Since: 2.0 - */ -void -cogl_quaternion_init_from_z_rotation (CoglQuaternion *quaternion, - float angle); - -/** - * cogl_quaternion_init_from_euler: - * @quaternion: A #CoglQuaternion - * @euler: A #CoglEuler with which to initialize the quaternion - * - * Since: 2.0 - */ -void -cogl_quaternion_init_from_euler (CoglQuaternion *quaternion, - const CoglEuler *euler); - -/** - * cogl_quaternion_init_from_quaternion: - * @quaternion: A #CoglQuaternion - * @src: A #CoglQuaternion with which to initialize @quaternion - * - * Since: 2.0 - */ -void -cogl_quaternion_init_from_quaternion (CoglQuaternion *quaternion, - CoglQuaternion *src); - -/** - * cogl_quaternion_init_from_matrix: - * @quaternion: A Cogl Quaternion - * @matrix: A rotation matrix with which to initialize the quaternion - * - * Initializes a quaternion from a rotation matrix. - * - * Since: 1.10 - * Stability: unstable - */ -void -cogl_quaternion_init_from_matrix (CoglQuaternion *quaternion, - const CoglMatrix *matrix); - -/** - * cogl_quaternion_equal: - * @v1: A #CoglQuaternion - * @v2: A #CoglQuaternion - * - * Compares that all the components of quaternions @a and @b are - * equal. - * - * An epsilon value is not used to compare the float components, but - * the == operator is at least used so that 0 and -0 are considered - * equal. - * - * Returns: %TRUE if the quaternions are equal else %FALSE. - * - * Since: 2.0 - */ -CoglBool -cogl_quaternion_equal (const void *v1, const void *v2); - -/** - * cogl_quaternion_copy: - * @src: A #CoglQuaternion - * - * Allocates a new #CoglQuaternion on the stack and initializes it with - * the same values as @src. - * - * Returns: A newly allocated #CoglQuaternion which should be freed - * using cogl_quaternion_free() - * - * Since: 2.0 - */ -CoglQuaternion * -cogl_quaternion_copy (const CoglQuaternion *src); - -/** - * cogl_quaternion_free: - * @quaternion: A #CoglQuaternion - * - * Frees a #CoglQuaternion that was previously allocated via - * cogl_quaternion_copy(). - * - * Since: 2.0 - */ -void -cogl_quaternion_free (CoglQuaternion *quaternion); - -/** - * cogl_quaternion_get_rotation_angle: - * @quaternion: A #CoglQuaternion - * - * - * Since: 2.0 - */ -float -cogl_quaternion_get_rotation_angle (const CoglQuaternion *quaternion); - -/** - * cogl_quaternion_get_rotation_axis: - * @quaternion: A #CoglQuaternion - * @vector3: (out): an allocated 3-float array - * - * Since: 2.0 - */ -void -cogl_quaternion_get_rotation_axis (const CoglQuaternion *quaternion, - float *vector3); - -/** - * cogl_quaternion_normalize: - * @quaternion: A #CoglQuaternion - * - * - * Since: 2.0 - */ -void -cogl_quaternion_normalize (CoglQuaternion *quaternion); - -/** - * cogl_quaternion_dot_product: - * @a: A #CoglQuaternion - * @b: A #CoglQuaternion - * - * Since: 2.0 - */ -float -cogl_quaternion_dot_product (const CoglQuaternion *a, - const CoglQuaternion *b); - -/** - * cogl_quaternion_invert: - * @quaternion: A #CoglQuaternion - * - * - * Since: 2.0 - */ -void -cogl_quaternion_invert (CoglQuaternion *quaternion); - -/** - * cogl_quaternion_multiply: - * @result: The destination #CoglQuaternion - * @left: The second #CoglQuaternion rotation to apply - * @right: The first #CoglQuaternion rotation to apply - * - * This combines the rotations of two quaternions into @result. The - * operation is not commutative so the order is important because AxB - * != BxA. Cogl follows the standard convention for quaternions here - * so the rotations are applied @right to @left. This is similar to the - * combining of matrices. - * - * It is possible to multiply the @a quaternion in-place, so - * @result can be equal to @a but can't be equal to @b. - * - * Since: 2.0 - */ -void -cogl_quaternion_multiply (CoglQuaternion *result, - const CoglQuaternion *left, - const CoglQuaternion *right); - -/** - * cogl_quaternion_pow: - * @quaternion: A #CoglQuaternion - * @exponent: the exponent - * - * - * Since: 2.0 - */ -void -cogl_quaternion_pow (CoglQuaternion *quaternion, float exponent); - -/** - * cogl_quaternion_slerp: - * @result: The destination #CoglQuaternion - * @a: The first #CoglQuaternion - * @b: The second #CoglQuaternion - * @t: The factor in the range [0,1] used to interpolate between - * quaternion @a and @b. - * - * Performs a spherical linear interpolation between two quaternions. - * - * Noteable properties: - * - * - * commutative: No - * - * - * constant velocity: Yes - * - * - * torque minimal (travels along the surface of the 4-sphere): Yes - * - * - * more expensive than cogl_quaternion_nlerp() - * - * - */ -void -cogl_quaternion_slerp (CoglQuaternion *result, - const CoglQuaternion *a, - const CoglQuaternion *b, - float t); - -/** - * cogl_quaternion_nlerp: - * @result: The destination #CoglQuaternion - * @a: The first #CoglQuaternion - * @b: The second #CoglQuaternion - * @t: The factor in the range [0,1] used to interpolate between - * quaterion @a and @b. - * - * Performs a normalized linear interpolation between two quaternions. - * That is it does a linear interpolation of the quaternion components - * and then normalizes the result. This will follow the shortest arc - * between the two orientations (just like the slerp() function) but - * will not progress at a constant speed. Unlike slerp() nlerp is - * commutative which is useful if you are blending animations - * together. (I.e. nlerp (tmp, a, b) followed by nlerp (result, tmp, - * d) is the same as nlerp (tmp, a, d) followed by nlerp (result, tmp, - * b)). Finally nlerp is cheaper than slerp so it can be a good choice - * if you don't need the constant speed property of the slerp() function. - * - * Notable properties: - * - * - * commutative: Yes - * - * - * constant velocity: No - * - * - * torque minimal (travels along the surface of the 4-sphere): Yes - * - * - * faster than cogl_quaternion_slerp() - * - * - */ -void -cogl_quaternion_nlerp (CoglQuaternion *result, - const CoglQuaternion *a, - const CoglQuaternion *b, - float t); -/** - * cogl_quaternion_squad: - * @result: The destination #CoglQuaternion - * @prev: A #CoglQuaternion used before @a - * @a: The first #CoglQuaternion - * @b: The second #CoglQuaternion - * @next: A #CoglQuaternion that will be used after @b - * @t: The factor in the range [0,1] used to interpolate between - * quaternion @a and @b. - * - * - * Since: 2.0 - */ -void -cogl_quaternion_squad (CoglQuaternion *result, - const CoglQuaternion *prev, - const CoglQuaternion *a, - const CoglQuaternion *b, - const CoglQuaternion *next, - float t); - -/** - * cogl_get_static_identity_quaternion: - * - * Returns a pointer to a singleton quaternion constant describing the - * canonical identity [1 (0, 0, 0)] which represents no rotation. - * - * If you multiply a quaternion with the identity quaternion you will - * get back the same value as the original quaternion. - * - * Returns: A pointer to an identity quaternion - * - * Since: 2.0 - */ -const CoglQuaternion * -cogl_get_static_identity_quaternion (void); - -/** - * cogl_get_static_zero_quaternion: - * - * Returns: a pointer to a singleton quaternion constant describing a - * rotation of 180 degrees around a degenerate axis: - * [0 (0, 0, 0)] - * - * Since: 2.0 - */ -const CoglQuaternion * -cogl_get_static_zero_quaternion (void); - -COGL_END_DECLS - -#endif /* __COGL_QUATERNION_H__ */ - diff --git a/cogl/cogl/cogl-rectangle-map.c b/cogl/cogl/cogl-rectangle-map.c index ae64016c5..b966d802e 100644 --- a/cogl/cogl/cogl-rectangle-map.c +++ b/cogl/cogl/cogl-rectangle-map.c @@ -31,9 +31,7 @@ * Neil Roberts */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include @@ -48,7 +46,7 @@ http://www.blackpawn.com/texts/lightmaps/default.html */ -#if defined (COGL_ENABLE_DEBUG) && defined (HAVE_CAIRO) +#ifdef COGL_ENABLE_DEBUG /* The cairo header is only used for debugging to generate an image of the atlas */ @@ -56,7 +54,7 @@ static void _cogl_rectangle_map_dump_image (CoglRectangleMap *map); -#endif /* COGL_ENABLE_DEBUG && HAVE_CAIRO */ +#endif /* COGL_ENABLE_DEBUG */ typedef struct _CoglRectangleMapNode CoglRectangleMapNode; typedef struct _CoglRectangleMapStackEntry CoglRectangleMapStackEntry; @@ -117,7 +115,7 @@ struct _CoglRectangleMapStackEntry CoglRectangleMapNode *node; /* Index of next branch of this node to explore. Basically either 0 to go left or 1 to go right */ - CoglBool next_index; + gboolean next_index; }; static CoglRectangleMapNode * @@ -161,7 +159,7 @@ _cogl_rectangle_map_new (unsigned int width, static void _cogl_rectangle_map_stack_push (GArray *stack, CoglRectangleMapNode *node, - CoglBool next_index) + gboolean next_index) { CoglRectangleMapStackEntry *new_entry; @@ -348,7 +346,7 @@ _cogl_rectangle_map_verify (CoglRectangleMap *map) #endif /* COGL_ENABLE_DEBUG */ -CoglBool +gboolean _cogl_rectangle_map_add (CoglRectangleMap *map, unsigned int width, unsigned int height, @@ -362,7 +360,7 @@ _cogl_rectangle_map_add (CoglRectangleMap *map, /* Zero-sized rectangles break the algorithm for removing rectangles so we'll disallow them */ - _COGL_RETURN_VAL_IF_FAIL (width > 0 && height > 0, FALSE); + g_return_val_if_fail (width > 0 && height > 0, FALSE); /* Start with the root node */ g_array_set_size (stack, 0); @@ -464,9 +462,7 @@ _cogl_rectangle_map_add (CoglRectangleMap *map, #ifdef COGL_ENABLE_DEBUG if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DUMP_ATLAS_IMAGE))) { -#ifdef HAVE_CAIRO _cogl_rectangle_map_dump_image (map); -#endif /* Dumping the rectangle map is really slow so we might as well verify the space remaining here as it is also quite slow */ _cogl_rectangle_map_verify (map); @@ -557,9 +553,7 @@ _cogl_rectangle_map_remove (CoglRectangleMap *map, #ifdef COGL_ENABLE_DEBUG if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DUMP_ATLAS_IMAGE))) { -#ifdef HAVE_CAIRO _cogl_rectangle_map_dump_image (map); -#endif /* Dumping the rectangle map is really slow so we might as well verify the space remaining here as it is also quite slow */ _cogl_rectangle_map_verify (map); @@ -703,10 +697,10 @@ _cogl_rectangle_map_free (CoglRectangleMap *map) g_array_free (map->stack, TRUE); - free (map); + g_free (map); } -#if defined (COGL_ENABLE_DEBUG) && defined (HAVE_CAIRO) +#ifdef COGL_ENABLE_DEBUG static void _cogl_rectangle_map_dump_image_cb (CoglRectangleMapNode *node, void *data) @@ -761,4 +755,4 @@ _cogl_rectangle_map_dump_image (CoglRectangleMap *map) cairo_surface_destroy (surface); } -#endif /* COGL_ENABLE_DEBUG && HAVE_CAIRO */ +#endif /* COGL_ENABLE_DEBUG */ diff --git a/cogl/cogl/cogl-rectangle-map.h b/cogl/cogl/cogl-rectangle-map.h index 1dd50fdbe..613965d68 100644 --- a/cogl/cogl/cogl-rectangle-map.h +++ b/cogl/cogl/cogl-rectangle-map.h @@ -50,7 +50,7 @@ _cogl_rectangle_map_new (unsigned int width, unsigned int height, GDestroyNotify value_destroy_func); -CoglBool +gboolean _cogl_rectangle_map_add (CoglRectangleMap *map, unsigned int width, unsigned int height, diff --git a/cogl/cogl/cogl-renderer-private.h b/cogl/cogl/cogl-renderer-private.h index 03b0c3014..66634c075 100644 --- a/cogl/cogl/cogl-renderer-private.h +++ b/cogl/cogl/cogl-renderer-private.h @@ -34,22 +34,18 @@ #include #include "cogl-object-private.h" -#include "cogl-winsys-private.h" #include "cogl-driver.h" #include "cogl-texture-driver.h" #include "cogl-context.h" #include "cogl-closure-list-private.h" - -#ifdef COGL_HAS_XLIB_SUPPORT -#include -#endif +#include "winsys/cogl-winsys-private.h" typedef const CoglWinsysVtable *(*CoglCustomWinsysVtableGetter) (CoglRenderer *renderer); struct _CoglRenderer { CoglObject _parent; - CoglBool connected; + gboolean connected; CoglDriver driver_override; const CoglDriverVtable *driver_vtable; const CoglTextureDriver *texture_driver; @@ -69,9 +65,8 @@ struct _CoglRenderer #ifdef COGL_HAS_XLIB_SUPPORT Display *foreign_xdpy; - CoglBool xlib_enable_event_retrieval; - CoglBool xlib_want_reset_on_video_memory_purge; - CoglBool xlib_enable_threaded_swap_wait; + gboolean xlib_enable_event_retrieval; + gboolean xlib_want_reset_on_video_memory_purge; #endif CoglDriver driver; @@ -84,11 +79,6 @@ struct _CoglRenderer void *winsys; }; -/* Mask of constraints that effect driver selection. All of the other - * constraints effect only the winsys selection */ -#define COGL_RENDERER_DRIVER_CONSTRAINTS \ - COGL_RENDERER_CONSTRAINT_SUPPORTS_COGL_GLES2 - typedef CoglFilterReturn (* CoglNativeFilterFunc) (void *native_event, void *data); @@ -109,6 +99,6 @@ _cogl_renderer_remove_native_filter (CoglRenderer *renderer, void * _cogl_renderer_get_proc_address (CoglRenderer *renderer, const char *name, - CoglBool in_core); + gboolean in_core); #endif /* __COGL_RENDERER_PRIVATE_H */ diff --git a/cogl/cogl/cogl-renderer.c b/cogl/cogl/cogl-renderer.c index 69e34c3a2..3dc22c190 100644 --- a/cogl/cogl/cogl-renderer.c +++ b/cogl/cogl/cogl-renderer.c @@ -29,9 +29,7 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include #include @@ -40,23 +38,20 @@ #include "cogl-private.h" #include "cogl-object.h" #include "cogl-context-private.h" -#include "cogl-util-gl-private.h" -#include "cogl-muffin.h" +#include "cogl-mutter.h" #include "cogl-renderer.h" #include "cogl-renderer-private.h" #include "cogl-display-private.h" -#include "cogl-winsys-private.h" -#include "cogl-winsys-stub-private.h" -#include "cogl-config-private.h" -#include "cogl-error-private.h" #include "cogl-gtype-private.h" +#include "winsys/cogl-winsys-private.h" + #ifdef COGL_HAS_EGL_PLATFORM_XLIB_SUPPORT -#include "cogl-winsys-egl-x11-private.h" +#include "winsys/cogl-winsys-egl-x11-private.h" #endif #ifdef COGL_HAS_GLX_SUPPORT -#include "cogl-winsys-glx-private.h" +#include "winsys/cogl-winsys-glx-private.h" #endif #ifdef COGL_HAS_XLIB_SUPPORT @@ -67,7 +62,7 @@ extern const CoglTextureDriver _cogl_texture_driver_gl; extern const CoglDriverVtable _cogl_driver_gl; #endif -#if defined (HAVE_COGL_GLES) || defined (HAVE_COGL_GLES2) +#if defined (HAVE_COGL_GLES2) extern const CoglTextureDriver _cogl_texture_driver_gles; extern const CoglDriverVtable _cogl_driver_gles; #endif @@ -78,7 +73,6 @@ typedef struct _CoglDriverDescription { CoglDriver id; const char *name; - CoglRendererConstraint constraints; /* It would be nice to make this a pointer and then use a compound * literal from C99 to initialise it but we probably can't get away * with using C99 here. Instead we'll just use a fixed-size array. @@ -96,10 +90,7 @@ static CoglDriverDescription _cogl_drivers[] = { COGL_DRIVER_GL, "gl", - 0, { COGL_PRIVATE_FEATURE_ANY_GL, - COGL_PRIVATE_FEATURE_GL_FIXED, - COGL_PRIVATE_FEATURE_GL_PROGRAMMABLE, -1 }, &_cogl_driver_gl, &_cogl_texture_driver_gl, @@ -108,9 +99,7 @@ static CoglDriverDescription _cogl_drivers[] = { COGL_DRIVER_GL3, "gl3", - 0, { COGL_PRIVATE_FEATURE_ANY_GL, - COGL_PRIVATE_FEATURE_GL_PROGRAMMABLE, -1 }, &_cogl_driver_gl, &_cogl_texture_driver_gl, @@ -121,34 +110,16 @@ static CoglDriverDescription _cogl_drivers[] = { COGL_DRIVER_GLES2, "gles2", - COGL_RENDERER_CONSTRAINT_SUPPORTS_COGL_GLES2, { COGL_PRIVATE_FEATURE_ANY_GL, - COGL_PRIVATE_FEATURE_GL_EMBEDDED, - COGL_PRIVATE_FEATURE_GL_PROGRAMMABLE, -1 }, &_cogl_driver_gles, &_cogl_texture_driver_gles, COGL_GLES2_LIBNAME, }, -#endif -#ifdef HAVE_COGL_GLES - { - COGL_DRIVER_GLES1, - "gles1", - 0, - { COGL_PRIVATE_FEATURE_ANY_GL, - COGL_PRIVATE_FEATURE_GL_EMBEDDED, - COGL_PRIVATE_FEATURE_GL_FIXED, - -1 }, - &_cogl_driver_gles, - &_cogl_texture_driver_gles, - COGL_GLES1_LIBNAME, - }, #endif { COGL_DRIVER_NOP, "nop", - 0, /* constraints satisfied */ { -1 }, &_cogl_driver_nop, NULL, /* texture driver */ @@ -164,7 +135,6 @@ static CoglWinsysVtableGetter _cogl_winsys_vtable_getters[] = #ifdef COGL_HAS_EGL_PLATFORM_XLIB_SUPPORT _cogl_winsys_egl_xlib_get_vtable, #endif - _cogl_winsys_stub_get_vtable, }; static void _cogl_renderer_free (CoglRenderer *renderer); @@ -209,14 +179,12 @@ _cogl_renderer_free (CoglRenderer *renderer) if (renderer->libgl_module) g_module_close (renderer->libgl_module); - g_slist_foreach (renderer->event_filters, - (GFunc) native_filter_closure_free, - NULL); - g_slist_free (renderer->event_filters); + g_slist_free_full (renderer->event_filters, + (GDestroyNotify) native_filter_closure_free); g_array_free (renderer->poll_fds, TRUE); - free (renderer); + g_free (renderer); } CoglRenderer * @@ -245,63 +213,41 @@ void cogl_xlib_renderer_set_foreign_display (CoglRenderer *renderer, Display *xdisplay) { - _COGL_RETURN_IF_FAIL (cogl_is_renderer (renderer)); + g_return_if_fail (cogl_is_renderer (renderer)); /* NB: Renderers are considered immutable once connected */ - _COGL_RETURN_IF_FAIL (!renderer->connected); + g_return_if_fail (!renderer->connected); renderer->foreign_xdpy = xdisplay; /* If the application is using a foreign display then we can assume it will also do its own event retrieval */ - cogl_xlib_renderer_set_event_retrieval_enabled (renderer, FALSE); + renderer->xlib_enable_event_retrieval = FALSE; } Display * cogl_xlib_renderer_get_foreign_display (CoglRenderer *renderer) { - _COGL_RETURN_VAL_IF_FAIL (cogl_is_renderer (renderer), NULL); + g_return_val_if_fail (cogl_is_renderer (renderer), NULL); return renderer->foreign_xdpy; } -void -cogl_xlib_renderer_set_event_retrieval_enabled (CoglRenderer *renderer, - CoglBool enable) -{ - _COGL_RETURN_IF_FAIL (cogl_is_renderer (renderer)); - /* NB: Renderers are considered immutable once connected */ - _COGL_RETURN_IF_FAIL (!renderer->connected); - - renderer->xlib_enable_event_retrieval = enable; -} - void cogl_xlib_renderer_request_reset_on_video_memory_purge (CoglRenderer *renderer, - CoglBool enable) + gboolean enable) { - _COGL_RETURN_IF_FAIL (cogl_is_renderer (renderer)); - _COGL_RETURN_IF_FAIL (!renderer->connected); + g_return_if_fail (cogl_is_renderer (renderer)); + g_return_if_fail (!renderer->connected); renderer->xlib_want_reset_on_video_memory_purge = enable; } - -void -cogl_xlib_renderer_set_threaded_swap_wait_enabled (CoglRenderer *renderer, - CoglBool enable) -{ - _COGL_RETURN_IF_FAIL (cogl_is_renderer (renderer)); - /* NB: Renderers are considered immutable once connected */ - _COGL_RETURN_IF_FAIL (!renderer->connected); - - renderer->xlib_enable_threaded_swap_wait = enable; -} #endif /* COGL_HAS_XLIB_SUPPORT */ -CoglBool +gboolean cogl_renderer_check_onscreen_template (CoglRenderer *renderer, CoglOnscreenTemplate *onscreen_template, - CoglError **error) + GError **error) { CoglDisplay *display; @@ -320,7 +266,7 @@ cogl_renderer_check_onscreen_template (CoglRenderer *renderer, return TRUE; } -typedef CoglBool (*CoglDriverCallback) (CoglDriverDescription *description, +typedef gboolean (*CoglDriverCallback) (CoglDriverDescription *description, void *user_data); static void @@ -401,12 +347,8 @@ driver_id_to_name (CoglDriver id) return "gl"; case COGL_DRIVER_GL3: return "gl3"; - case COGL_DRIVER_GLES1: - return "gles1"; case COGL_DRIVER_GLES2: return "gles2"; - case COGL_DRIVER_WEBGL: - return "webgl"; case COGL_DRIVER_NOP: return "nop"; case COGL_DRIVER_ANY: @@ -420,40 +362,24 @@ driver_id_to_name (CoglDriver id) typedef struct _SatisfyConstraintsState { - GList *constraints; const CoglDriverDescription *driver_description; } SatisfyConstraintsState; -static CoglBool +/* XXX this is still uglier than it needs to be */ +static gboolean satisfy_constraints (CoglDriverDescription *description, void *user_data) { SatisfyConstraintsState *state = user_data; - GList *l; - - for (l = state->constraints; l; l = l->next) - { - CoglRendererConstraint constraint = GPOINTER_TO_UINT (l->data); - - /* Most of the constraints only affect the winsys selection so - * we'll filter them out */ - if (!(constraint & COGL_RENDERER_DRIVER_CONSTRAINTS)) - continue; - - /* If the driver doesn't satisfy any constraint then continue - * to the next driver description */ - if (!(constraint & description->constraints)) - return TRUE; - } state->driver_description = description; return FALSE; } -static CoglBool +static gboolean _cogl_renderer_choose_driver (CoglRenderer *renderer, - CoglError **error) + GError **error) { const char *driver_name = g_getenv ("COGL_DRIVER"); CoglDriver driver_override = COGL_DRIVER_ANY; @@ -463,9 +389,6 @@ _cogl_renderer_choose_driver (CoglRenderer *renderer, const CoglDriverDescription *desc; int i; - if (!driver_name) - driver_name = _cogl_config_driver; - if (driver_name) { driver_override = driver_name_to_id (driver_name); @@ -478,11 +401,10 @@ _cogl_renderer_choose_driver (CoglRenderer *renderer, if (driver_override != COGL_DRIVER_ANY && renderer->driver_override != driver_override) { - _cogl_set_error (error, - COGL_RENDERER_ERROR, - COGL_RENDERER_ERROR_BAD_CONSTRAINT, - "Application driver selection conflicts with driver " - "specified in configuration"); + g_set_error (error, COGL_RENDERER_ERROR, + COGL_RENDERER_ERROR_BAD_CONSTRAINT, + "Application driver selection conflicts with driver " + "specified in configuration"); return FALSE; } @@ -491,7 +413,7 @@ _cogl_renderer_choose_driver (CoglRenderer *renderer, if (driver_override != COGL_DRIVER_ANY) { - CoglBool found = FALSE; + gboolean found = FALSE; int i; for (i = 0; i < G_N_ELEMENTS (_cogl_drivers); i++) @@ -508,16 +430,14 @@ _cogl_renderer_choose_driver (CoglRenderer *renderer, if (invalid_override) { - _cogl_set_error (error, - COGL_RENDERER_ERROR, - COGL_RENDERER_ERROR_BAD_CONSTRAINT, - "Driver \"%s\" is not available", - invalid_override); + g_set_error (error, COGL_RENDERER_ERROR, + COGL_RENDERER_ERROR_BAD_CONSTRAINT, + "Driver \"%s\" is not available", + invalid_override); return FALSE; } state.driver_description = NULL; - state.constraints = renderer->constraints; foreach_driver_description (driver_override, satisfy_constraints, @@ -525,10 +445,9 @@ _cogl_renderer_choose_driver (CoglRenderer *renderer, if (!state.driver_description) { - _cogl_set_error (error, - COGL_RENDERER_ERROR, - COGL_RENDERER_ERROR_BAD_CONSTRAINT, - "No suitable driver found"); + g_set_error (error, COGL_RENDERER_ERROR, + COGL_RENDERER_ERROR_BAD_CONSTRAINT, + "No suitable driver found"); return FALSE; } @@ -551,7 +470,7 @@ _cogl_renderer_choose_driver (CoglRenderer *renderer, if (renderer->libgl_module == NULL) { - _cogl_set_error (error, COGL_DRIVER_ERROR, + g_set_error (error, COGL_DRIVER_ERROR, COGL_DRIVER_ERROR_FAILED_TO_LOAD_LIBRARY, "Failed to dynamically open the GL library \"%s\"", libgl_name); @@ -573,12 +492,12 @@ cogl_renderer_set_custom_winsys (CoglRenderer *renderer, renderer->custom_winsys_vtable_getter = winsys_vtable_getter; } -static CoglBool +static gboolean connect_custom_winsys (CoglRenderer *renderer, - CoglError **error) + GError **error) { const CoglWinsysVtable *winsys; - CoglError *tmp_error = NULL; + GError *tmp_error = NULL; GString *error_message; winsys = renderer->custom_winsys_vtable_getter (renderer); @@ -589,7 +508,7 @@ connect_custom_winsys (CoglRenderer *renderer, { g_string_append_c (error_message, '\n'); g_string_append (error_message, tmp_error->message); - cogl_error_free (tmp_error); + g_error_free (tmp_error); } else { @@ -599,20 +518,18 @@ connect_custom_winsys (CoglRenderer *renderer, } renderer->winsys_vtable = NULL; - _cogl_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_INIT, - "Failed to connected to any renderer: %s", - error_message->str); + g_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_INIT, + "Failed to connected to any renderer: %s", error_message->str); g_string_free (error_message, TRUE); return FALSE; } -CoglBool -cogl_renderer_connect (CoglRenderer *renderer, CoglError **error) +gboolean +cogl_renderer_connect (CoglRenderer *renderer, GError **error) { int i; GString *error_message; - CoglBool constraints_failed = FALSE; + gboolean constraints_failed = FALSE; if (renderer->connected) return TRUE; @@ -630,9 +547,9 @@ cogl_renderer_connect (CoglRenderer *renderer, CoglError **error) for (i = 0; i < G_N_ELEMENTS (_cogl_winsys_vtable_getters); i++) { const CoglWinsysVtable *winsys = _cogl_winsys_vtable_getters[i](); - CoglError *tmp_error = NULL; + GError *tmp_error = NULL; GList *l; - CoglBool skip_due_to_constraints = FALSE; + gboolean skip_due_to_constraints = FALSE; if (renderer->winsys_id_override != COGL_WINSYS_ID_ANY) { @@ -642,8 +559,6 @@ cogl_renderer_connect (CoglRenderer *renderer, CoglError **error) else { char *user_choice = getenv ("COGL_RENDERER"); - if (!user_choice) - user_choice = _cogl_config_renderer; if (user_choice && g_ascii_strcasecmp (winsys->name, user_choice) != 0) continue; @@ -673,7 +588,7 @@ cogl_renderer_connect (CoglRenderer *renderer, CoglError **error) { g_string_append_c (error_message, '\n'); g_string_append (error_message, tmp_error->message); - cogl_error_free (tmp_error); + g_error_free (tmp_error); } else { @@ -687,15 +602,14 @@ cogl_renderer_connect (CoglRenderer *renderer, CoglError **error) { if (constraints_failed) { - _cogl_set_error (error, COGL_RENDERER_ERROR, + g_set_error (error, COGL_RENDERER_ERROR, COGL_RENDERER_ERROR_BAD_CONSTRAINT, "Failed to connected to any renderer due to constraints"); return FALSE; } renderer->winsys_vtable = NULL; - _cogl_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_INIT, + g_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_INIT, "Failed to connected to any renderer: %s", error_message->str); g_string_free (error_message, TRUE); @@ -772,7 +686,7 @@ void cogl_renderer_set_winsys_id (CoglRenderer *renderer, CoglWinsysID winsys_id) { - _COGL_RETURN_IF_FAIL (!renderer->connected); + g_return_if_fail (!renderer->connected); renderer->winsys_id_override = winsys_id; } @@ -780,7 +694,7 @@ cogl_renderer_set_winsys_id (CoglRenderer *renderer, CoglWinsysID cogl_renderer_get_winsys_id (CoglRenderer *renderer) { - _COGL_RETURN_VAL_IF_FAIL (renderer->connected, 0); + g_return_val_if_fail (renderer->connected, 0); return renderer->winsys_vtable->id; } @@ -788,29 +702,13 @@ cogl_renderer_get_winsys_id (CoglRenderer *renderer) void * _cogl_renderer_get_proc_address (CoglRenderer *renderer, const char *name, - CoglBool in_core) + gboolean in_core) { const CoglWinsysVtable *winsys = _cogl_renderer_get_winsys (renderer); return winsys->renderer_get_proc_address (renderer, name, in_core); } -int -cogl_renderer_get_n_fragment_texture_units (CoglRenderer *renderer) -{ - int n = 0; - - _COGL_GET_CONTEXT (ctx, 0); - -#if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES2) - if (cogl_has_feature (ctx, COGL_FEATURE_ID_GLSL) || - cogl_has_feature (ctx, COGL_FEATURE_ID_ARBFP)) - GE (ctx, glGetIntegerv (GL_MAX_TEXTURE_IMAGE_UNITS, &n)); -#endif - - return n; -} - void cogl_renderer_add_constraint (CoglRenderer *renderer, CoglRendererConstraint constraint) @@ -833,14 +731,14 @@ void cogl_renderer_set_driver (CoglRenderer *renderer, CoglDriver driver) { - _COGL_RETURN_IF_FAIL (!renderer->connected); + g_return_if_fail (!renderer->connected); renderer->driver_override = driver; } CoglDriver cogl_renderer_get_driver (CoglRenderer *renderer) { - _COGL_RETURN_VAL_IF_FAIL (renderer->connected, 0); + g_return_val_if_fail (renderer->connected, 0); return renderer->driver; } @@ -852,9 +750,23 @@ cogl_renderer_foreach_output (CoglRenderer *renderer, { GList *l; - _COGL_RETURN_IF_FAIL (renderer->connected); - _COGL_RETURN_IF_FAIL (callback != NULL); + g_return_if_fail (renderer->connected); + g_return_if_fail (callback != NULL); for (l = renderer->outputs; l; l = l->next) callback (l->data, user_data); } + +CoglDmaBufHandle * +cogl_renderer_create_dma_buf (CoglRenderer *renderer, + int width, + int height, + GError **error) +{ + const CoglWinsysVtable *winsys = _cogl_renderer_get_winsys (renderer); + + if (winsys->renderer_create_dma_buf) + return winsys->renderer_create_dma_buf (renderer, width, height, error); + + return NULL; +} diff --git a/cogl/cogl/cogl-renderer.h b/cogl/cogl/cogl-renderer.h index 8dbf199c8..b8eb6e545 100644 --- a/cogl/cogl/cogl-renderer.h +++ b/cogl/cogl/cogl-renderer.h @@ -35,12 +35,11 @@ #include #include -#include #include #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS /** * SECTION:cogl-renderer @@ -81,7 +80,7 @@ COGL_BEGIN_DECLS */ #define COGL_RENDERER_ERROR cogl_renderer_error_quark () -uint32_t +COGL_EXPORT uint32_t cogl_renderer_error_quark (void); typedef struct _CoglRenderer CoglRenderer; @@ -91,6 +90,7 @@ typedef struct _CoglRenderer CoglRenderer; * * Returns: a #GType that can be used with the GLib type system. */ +COGL_EXPORT GType cogl_renderer_get_gtype (void); /** @@ -103,7 +103,7 @@ GType cogl_renderer_get_gtype (void); * Since: 1.10 * Stability: unstable */ -CoglBool +COGL_EXPORT gboolean cogl_is_renderer (void *object); /** @@ -146,7 +146,7 @@ cogl_is_renderer (void *object); * Since: 1.10 * Stability: unstable */ -CoglRenderer * +COGL_EXPORT CoglRenderer * cogl_renderer_new (void); /* optional configuration APIs */ @@ -185,7 +185,7 @@ typedef enum * * This may only be called on an un-connected #CoglRenderer. */ -void +COGL_EXPORT void cogl_renderer_set_winsys_id (CoglRenderer *renderer, CoglWinsysID winsys_id); @@ -200,28 +200,14 @@ cogl_renderer_set_winsys_id (CoglRenderer *renderer, * Returns: The #CoglWinsysID corresponding to the chosen window * system backend. */ -CoglWinsysID +COGL_EXPORT CoglWinsysID cogl_renderer_get_winsys_id (CoglRenderer *renderer); -/** - * cogl_renderer_get_n_fragment_texture_units: - * @renderer: A #CoglRenderer - * - * Queries how many texture units can be used from fragment programs - * - * Returns: the number of texture image units. - * - * Since: 1.8 - * Stability: Unstable - */ -int -cogl_renderer_get_n_fragment_texture_units (CoglRenderer *renderer); - /** * cogl_renderer_check_onscreen_template: (skip) * @renderer: A #CoglRenderer * @onscreen_template: A #CoglOnscreenTemplate - * @error: A pointer to a #CoglError for reporting exceptions + * @error: A pointer to a #GError for reporting exceptions * * Tests if a given @onscreen_template can be supported with the given * @renderer. @@ -231,17 +217,17 @@ cogl_renderer_get_n_fragment_texture_units (CoglRenderer *renderer); * Since: 1.10 * Stability: unstable */ -CoglBool +COGL_EXPORT gboolean cogl_renderer_check_onscreen_template (CoglRenderer *renderer, CoglOnscreenTemplate *onscreen_template, - CoglError **error); + GError **error); /* Final connection API */ /** * cogl_renderer_connect: * @renderer: An unconnected #CoglRenderer - * @error: a pointer to a #CoglError for reporting exceptions + * @error: a pointer to a #GError for reporting exceptions * * Connects the configured @renderer. Renderer connection isn't a * very active process, it basically just means validating that @@ -253,8 +239,8 @@ cogl_renderer_check_onscreen_template (CoglRenderer *renderer, * Since: 1.10 * Stability: unstable */ -CoglBool -cogl_renderer_connect (CoglRenderer *renderer, CoglError **error); +COGL_EXPORT gboolean +cogl_renderer_connect (CoglRenderer *renderer, GError **error); /** * CoglRendererConstraint: @@ -262,10 +248,6 @@ cogl_renderer_connect (CoglRenderer *renderer, CoglError **error); * @COGL_RENDERER_CONSTRAINT_USES_XLIB: Require the renderer to be X11 * based and use Xlib * @COGL_RENDERER_CONSTRAINT_USES_EGL: Require the renderer to be EGL based - * @COGL_RENDERER_CONSTRAINT_SUPPORTS_COGL_GLES2: Require that the - * renderer supports creating a #CoglGLES2Context via - * cogl_gles2_context_new(). This can be used to integrate GLES 2.0 - * code into Cogl based applications. * * These constraint flags are hard-coded features of the different renderer * backends. Sometimes a platform may support multiple rendering options which @@ -287,7 +269,6 @@ typedef enum COGL_RENDERER_CONSTRAINT_USES_X11 = (1 << 0), COGL_RENDERER_CONSTRAINT_USES_XLIB = (1 << 1), COGL_RENDERER_CONSTRAINT_USES_EGL = (1 << 2), - COGL_RENDERER_CONSTRAINT_SUPPORTS_COGL_GLES2 = (1 << 3) } CoglRendererConstraint; @@ -304,7 +285,7 @@ typedef enum * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_renderer_add_constraint (CoglRenderer *renderer, CoglRendererConstraint constraint); @@ -321,7 +302,7 @@ cogl_renderer_add_constraint (CoglRenderer *renderer, * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_renderer_remove_constraint (CoglRenderer *renderer, CoglRendererConstraint constraint); @@ -331,9 +312,7 @@ cogl_renderer_remove_constraint (CoglRenderer *renderer, * @COGL_DRIVER_NOP: A No-Op driver. * @COGL_DRIVER_GL: An OpenGL driver. * @COGL_DRIVER_GL3: An OpenGL driver using the core GL 3.1 profile - * @COGL_DRIVER_GLES1: An OpenGL ES 1.1 driver. * @COGL_DRIVER_GLES2: An OpenGL ES 2.0 driver. - * @COGL_DRIVER_WEBGL: A WebGL driver. * * Identifiers for underlying hardware drivers that may be used by * Cogl for rendering. @@ -347,9 +326,7 @@ typedef enum COGL_DRIVER_NOP, COGL_DRIVER_GL, COGL_DRIVER_GL3, - COGL_DRIVER_GLES1, COGL_DRIVER_GLES2, - COGL_DRIVER_WEBGL } CoglDriver; /** @@ -369,7 +346,7 @@ typedef enum * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_renderer_set_driver (CoglRenderer *renderer, CoglDriver driver); @@ -384,7 +361,7 @@ cogl_renderer_set_driver (CoglRenderer *renderer, * Since: 1.10 * Stability: unstable */ -CoglDriver +COGL_EXPORT CoglDriver cogl_renderer_get_driver (CoglRenderer *renderer); /** @@ -416,12 +393,33 @@ typedef void (*CoglOutputCallback) (CoglOutput *output, void *user_data); * Since: 1.14 * Stability: Unstable */ -void +COGL_EXPORT void cogl_renderer_foreach_output (CoglRenderer *renderer, CoglOutputCallback callback, void *user_data); -COGL_END_DECLS +/** + * cogl_renderer_create_dma_buf: (skip) + * @renderer: A #CoglRenderer + * @width: width of the new + * @height: height of the new + * @error: (nullable): return location for a #GError + * + * Creates a new #CoglFramebuffer with @width x @height, and format + * hardcoded to XRGB, and exports the new framebuffer's DMA buffer + * handle. + * + * Returns: (nullable)(transfer full): a #CoglDmaBufHandle. The + * return result must be released with cogl_dma_buf_handle_free() + * after use. + */ +COGL_EXPORT CoglDmaBufHandle * +cogl_renderer_create_dma_buf (CoglRenderer *renderer, + int width, + int height, + GError **error); + +G_END_DECLS #endif /* __COGL_RENDERER_H__ */ diff --git a/cogl/cogl/cogl-sampler-cache-private.h b/cogl/cogl/cogl-sampler-cache-private.h index 5688effb9..bfddc12a3 100644 --- a/cogl/cogl/cogl-sampler-cache-private.h +++ b/cogl/cogl/cogl-sampler-cache-private.h @@ -68,7 +68,6 @@ typedef struct _CoglSamplerCacheEntry CoglSamplerCacheWrapMode wrap_mode_s; CoglSamplerCacheWrapMode wrap_mode_t; - CoglSamplerCacheWrapMode wrap_mode_p; } CoglSamplerCacheEntry; CoglSamplerCache * @@ -81,8 +80,7 @@ const CoglSamplerCacheEntry * _cogl_sampler_cache_update_wrap_modes (CoglSamplerCache *cache, const CoglSamplerCacheEntry *old_entry, CoglSamplerCacheWrapMode wrap_mode_s, - CoglSamplerCacheWrapMode wrap_mode_t, - CoglSamplerCacheWrapMode wrap_mode_p); + CoglSamplerCacheWrapMode wrap_mode_t); const CoglSamplerCacheEntry * _cogl_sampler_cache_update_filters (CoglSamplerCache *cache, diff --git a/cogl/cogl/cogl-sampler-cache.c b/cogl/cogl/cogl-sampler-cache.c index 1b9e3abf4..f2dbaeb63 100644 --- a/cogl/cogl/cogl-sampler-cache.c +++ b/cogl/cogl/cogl-sampler-cache.c @@ -30,13 +30,11 @@ * Neil Roberts */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-sampler-cache-private.h" #include "cogl-context-private.h" -#include "cogl-util-gl-private.h" +#include "driver/gl/cogl-util-gl-private.h" #ifndef GL_TEXTURE_WRAP_R #define GL_TEXTURE_WRAP_R 0x8072 @@ -79,10 +77,9 @@ canonicalize_key (CoglSamplerCacheEntry *key) sampler object for the state */ key->wrap_mode_s = get_real_wrap_mode (key->wrap_mode_s); key->wrap_mode_t = get_real_wrap_mode (key->wrap_mode_t); - key->wrap_mode_p = get_real_wrap_mode (key->wrap_mode_p); } -static CoglBool +static gboolean wrap_mode_equal_gl (CoglSamplerCacheWrapMode wrap_mode0, CoglSamplerCacheWrapMode wrap_mode1) { @@ -92,7 +89,7 @@ wrap_mode_equal_gl (CoglSamplerCacheWrapMode wrap_mode0, return get_real_wrap_mode (wrap_mode0) == get_real_wrap_mode (wrap_mode1); } -static CoglBool +static gboolean sampler_state_equal_gl (const void *value0, const void *value1) { @@ -102,8 +99,7 @@ sampler_state_equal_gl (const void *value0, return (state0->mag_filter == state1->mag_filter && state0->min_filter == state1->min_filter && wrap_mode_equal_gl (state0->wrap_mode_s, state1->wrap_mode_s) && - wrap_mode_equal_gl (state0->wrap_mode_t, state1->wrap_mode_t) && - wrap_mode_equal_gl (state0->wrap_mode_p, state1->wrap_mode_p)); + wrap_mode_equal_gl (state0->wrap_mode_t, state1->wrap_mode_t)); } static unsigned int @@ -132,12 +128,11 @@ hash_sampler_state_gl (const void *key) sizeof (entry->min_filter)); hash = hash_wrap_mode_gl (hash, entry->wrap_mode_s); hash = hash_wrap_mode_gl (hash, entry->wrap_mode_t); - hash = hash_wrap_mode_gl (hash, entry->wrap_mode_p); return _cogl_util_one_at_a_time_mix (hash); } -static CoglBool +static gboolean sampler_state_equal_cogl (const void *value0, const void *value1) { @@ -147,8 +142,7 @@ sampler_state_equal_cogl (const void *value0, return (state0->mag_filter == state1->mag_filter && state0->min_filter == state1->min_filter && state0->wrap_mode_s == state1->wrap_mode_s && - state0->wrap_mode_t == state1->wrap_mode_t && - state0->wrap_mode_p == state1->wrap_mode_p); + state0->wrap_mode_t == state1->wrap_mode_t); } static unsigned int @@ -165,8 +159,6 @@ hash_sampler_state_cogl (const void *key) sizeof (entry->wrap_mode_s)); hash = _cogl_util_one_at_a_time_hash (hash, &entry->wrap_mode_t, sizeof (entry->wrap_mode_t)); - hash = _cogl_util_one_at_a_time_hash (hash, &entry->wrap_mode_p, - sizeof (entry->wrap_mode_p)); return _cogl_util_one_at_a_time_mix (hash); } @@ -234,10 +226,6 @@ _cogl_sampler_cache_get_entry_gl (CoglSamplerCache *cache, entry->sampler_object, GL_TEXTURE_WRAP_T, entry->wrap_mode_t); - set_wrap_mode (context, - entry->sampler_object, - GL_TEXTURE_WRAP_R, - entry->wrap_mode_p); } else { @@ -289,7 +277,6 @@ _cogl_sampler_cache_get_default_entry (CoglSamplerCache *cache) key.wrap_mode_s = COGL_SAMPLER_CACHE_WRAP_MODE_AUTOMATIC; key.wrap_mode_t = COGL_SAMPLER_CACHE_WRAP_MODE_AUTOMATIC; - key.wrap_mode_p = COGL_SAMPLER_CACHE_WRAP_MODE_AUTOMATIC; key.min_filter = GL_LINEAR; key.mag_filter = GL_LINEAR; @@ -301,14 +288,12 @@ const CoglSamplerCacheEntry * _cogl_sampler_cache_update_wrap_modes (CoglSamplerCache *cache, const CoglSamplerCacheEntry *old_entry, CoglSamplerCacheWrapMode wrap_mode_s, - CoglSamplerCacheWrapMode wrap_mode_t, - CoglSamplerCacheWrapMode wrap_mode_p) + CoglSamplerCacheWrapMode wrap_mode_t) { CoglSamplerCacheEntry key = *old_entry; key.wrap_mode_s = wrap_mode_s; key.wrap_mode_t = wrap_mode_t; - key.wrap_mode_p = wrap_mode_p; return _cogl_sampler_cache_get_entry_cogl (cache, &key); } @@ -367,5 +352,5 @@ _cogl_sampler_cache_free (CoglSamplerCache *cache) g_hash_table_destroy (cache->hash_table_cogl); - free (cache); + g_free (cache); } diff --git a/cogl/cogl/cogl-snippet-private.h b/cogl/cogl/cogl-snippet-private.h index e3269f20d..323117b77 100644 --- a/cogl/cogl/cogl-snippet-private.h +++ b/cogl/cogl/cogl-snippet-private.h @@ -62,7 +62,7 @@ struct _CoglSnippet /* This is set to TRUE the first time the snippet is attached to the pipeline. After that any attempts to modify the snippet will be ignored. */ - CoglBool immutable; + gboolean immutable; char *declarations; char *pre; diff --git a/cogl/cogl/cogl-snippet.c b/cogl/cogl/cogl-snippet.c index 6c18a2dbe..9b5ed7c23 100644 --- a/cogl/cogl/cogl-snippet.c +++ b/cogl/cogl/cogl-snippet.c @@ -31,9 +31,7 @@ * Neil Roberts */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-types.h" #include "cogl-snippet-private.h" @@ -66,12 +64,12 @@ cogl_snippet_new (CoglSnippetHook hook, CoglSnippetHook cogl_snippet_get_hook (CoglSnippet *snippet) { - _COGL_RETURN_VAL_IF_FAIL (cogl_is_snippet (snippet), 0); + g_return_val_if_fail (cogl_is_snippet (snippet), 0); return snippet->hook; } -static CoglBool +static gboolean _cogl_snippet_modify (CoglSnippet *snippet) { if (snippet->immutable) @@ -90,19 +88,19 @@ void cogl_snippet_set_declarations (CoglSnippet *snippet, const char *declarations) { - _COGL_RETURN_IF_FAIL (cogl_is_snippet (snippet)); + g_return_if_fail (cogl_is_snippet (snippet)); if (!_cogl_snippet_modify (snippet)) return; - free (snippet->declarations); + g_free (snippet->declarations); snippet->declarations = declarations ? g_strdup (declarations) : NULL; } const char * cogl_snippet_get_declarations (CoglSnippet *snippet) { - _COGL_RETURN_VAL_IF_FAIL (cogl_is_snippet (snippet), NULL); + g_return_val_if_fail (cogl_is_snippet (snippet), NULL); return snippet->declarations; } @@ -111,19 +109,19 @@ void cogl_snippet_set_pre (CoglSnippet *snippet, const char *pre) { - _COGL_RETURN_IF_FAIL (cogl_is_snippet (snippet)); + g_return_if_fail (cogl_is_snippet (snippet)); if (!_cogl_snippet_modify (snippet)) return; - free (snippet->pre); + g_free (snippet->pre); snippet->pre = pre ? g_strdup (pre) : NULL; } const char * cogl_snippet_get_pre (CoglSnippet *snippet) { - _COGL_RETURN_VAL_IF_FAIL (cogl_is_snippet (snippet), NULL); + g_return_val_if_fail (cogl_is_snippet (snippet), NULL); return snippet->pre; } @@ -132,19 +130,19 @@ void cogl_snippet_set_replace (CoglSnippet *snippet, const char *replace) { - _COGL_RETURN_IF_FAIL (cogl_is_snippet (snippet)); + g_return_if_fail (cogl_is_snippet (snippet)); if (!_cogl_snippet_modify (snippet)) return; - free (snippet->replace); + g_free (snippet->replace); snippet->replace = replace ? g_strdup (replace) : NULL; } const char * cogl_snippet_get_replace (CoglSnippet *snippet) { - _COGL_RETURN_VAL_IF_FAIL (cogl_is_snippet (snippet), NULL); + g_return_val_if_fail (cogl_is_snippet (snippet), NULL); return snippet->replace; } @@ -153,19 +151,19 @@ void cogl_snippet_set_post (CoglSnippet *snippet, const char *post) { - _COGL_RETURN_IF_FAIL (cogl_is_snippet (snippet)); + g_return_if_fail (cogl_is_snippet (snippet)); if (!_cogl_snippet_modify (snippet)) return; - free (snippet->post); + g_free (snippet->post); snippet->post = post ? g_strdup (post) : NULL; } const char * cogl_snippet_get_post (CoglSnippet *snippet) { - _COGL_RETURN_VAL_IF_FAIL (cogl_is_snippet (snippet), NULL); + g_return_val_if_fail (cogl_is_snippet (snippet), NULL); return snippet->post; } @@ -179,9 +177,9 @@ _cogl_snippet_make_immutable (CoglSnippet *snippet) static void _cogl_snippet_free (CoglSnippet *snippet) { - free (snippet->declarations); - free (snippet->pre); - free (snippet->replace); - free (snippet->post); + g_free (snippet->declarations); + g_free (snippet->pre); + g_free (snippet->replace); + g_free (snippet->post); g_slice_free (CoglSnippet, snippet); } diff --git a/cogl/cogl/cogl-snippet.h b/cogl/cogl/cogl-snippet.h index a4a77ed46..aec502173 100644 --- a/cogl/cogl/cogl-snippet.h +++ b/cogl/cogl/cogl-snippet.h @@ -38,7 +38,7 @@ #ifndef __COGL_SNIPPET_H__ #define __COGL_SNIPPET_H__ -COGL_BEGIN_DECLS +G_BEGIN_DECLS /** * SECTION:cogl-snippet @@ -294,8 +294,7 @@ COGL_BEGIN_DECLS * will be the bottom right. Note that there is currently a bug in * Cogl where when rendering to an offscreen buffer these * coordinates will be upside-down. The value is undefined when not - * rendering points. This builtin can only be used if the - * %COGL_FEATURE_ID_POINT_SPRITE feature is available. + * rendering points. * * * @@ -346,6 +345,7 @@ typedef struct _CoglSnippet CoglSnippet; * * Returns: a #GType that can be used with the GLib type system. */ +COGL_EXPORT GType cogl_snippet_get_gtype (void); /* Enumeration of all the hook points that a snippet can be attached @@ -655,7 +655,8 @@ GType cogl_snippet_get_gtype (void); * Since: 1.10 * Stability: Unstable */ -typedef enum { +typedef enum +{ /* Per pipeline vertex hooks */ COGL_SNIPPET_HOOK_VERTEX = 0, COGL_SNIPPET_HOOK_VERTEX_TRANSFORM, @@ -690,7 +691,7 @@ typedef enum { * Since: 1.10 * Stability: Unstable */ -CoglSnippet * +COGL_EXPORT CoglSnippet * cogl_snippet_new (CoglSnippetHook hook, const char *declarations, const char *post); @@ -704,7 +705,7 @@ cogl_snippet_new (CoglSnippetHook hook, * Since: 1.10 * Stability: Unstable */ -CoglSnippetHook +COGL_EXPORT CoglSnippetHook cogl_snippet_get_hook (CoglSnippet *snippet); /** @@ -719,7 +720,7 @@ cogl_snippet_get_hook (CoglSnippet *snippet); * Since: 1.10 * Stability: Unstable */ -CoglBool +COGL_EXPORT gboolean cogl_is_snippet (void *object); /** @@ -740,7 +741,7 @@ cogl_is_snippet (void *object); * Since: 1.10 * Stability: Unstable */ -void +COGL_EXPORT void cogl_snippet_set_declarations (CoglSnippet *snippet, const char *declarations); @@ -754,7 +755,7 @@ cogl_snippet_set_declarations (CoglSnippet *snippet, * Since: 1.10 * Stability: Unstable */ -const char * +COGL_EXPORT const char * cogl_snippet_get_declarations (CoglSnippet *snippet); /** @@ -774,7 +775,7 @@ cogl_snippet_get_declarations (CoglSnippet *snippet); * Since: 1.10 * Stability: Unstable */ -void +COGL_EXPORT void cogl_snippet_set_pre (CoglSnippet *snippet, const char *pre); @@ -788,7 +789,7 @@ cogl_snippet_set_pre (CoglSnippet *snippet, * Since: 1.10 * Stability: Unstable */ -const char * +COGL_EXPORT const char * cogl_snippet_get_pre (CoglSnippet *snippet); /** @@ -808,7 +809,7 @@ cogl_snippet_get_pre (CoglSnippet *snippet); * Since: 1.10 * Stability: Unstable */ -void +COGL_EXPORT void cogl_snippet_set_replace (CoglSnippet *snippet, const char *replace); @@ -822,7 +823,7 @@ cogl_snippet_set_replace (CoglSnippet *snippet, * Since: 1.10 * Stability: Unstable */ -const char * +COGL_EXPORT const char * cogl_snippet_get_replace (CoglSnippet *snippet); /** @@ -842,7 +843,7 @@ cogl_snippet_get_replace (CoglSnippet *snippet); * Since: 1.10 * Stability: Unstable */ -void +COGL_EXPORT void cogl_snippet_set_post (CoglSnippet *snippet, const char *post); @@ -856,9 +857,9 @@ cogl_snippet_set_post (CoglSnippet *snippet, * Since: 1.10 * Stability: Unstable */ -const char * +COGL_EXPORT const char * cogl_snippet_get_post (CoglSnippet *snippet); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_SNIPPET_H__ */ diff --git a/cogl/cogl/cogl-spans.c b/cogl/cogl/cogl-spans.c index 85f8e01eb..8f7eaf4e3 100644 --- a/cogl/cogl/cogl-spans.c +++ b/cogl/cogl/cogl-spans.c @@ -28,9 +28,7 @@ * */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "math.h" @@ -81,8 +79,8 @@ _cogl_span_iter_begin (CoglSpanIter *iter, { /* XXX: If CLAMP_TO_EDGE needs to be emulated then it needs to be * done at a higher level than here... */ - _COGL_RETURN_IF_FAIL (wrap_mode == COGL_PIPELINE_WRAP_MODE_REPEAT || - wrap_mode == COGL_PIPELINE_WRAP_MODE_MIRRORED_REPEAT); + g_return_if_fail (wrap_mode == COGL_PIPELINE_WRAP_MODE_REPEAT || + wrap_mode == COGL_PIPELINE_WRAP_MODE_MIRRORED_REPEAT); iter->span = NULL; @@ -173,7 +171,7 @@ _cogl_span_iter_next (CoglSpanIter *iter) _cogl_span_iter_update (iter); } -CoglBool +gboolean _cogl_span_iter_end (CoglSpanIter *iter) { /* End reached when whole area covered */ diff --git a/cogl/cogl/cogl-spans.h b/cogl/cogl/cogl-spans.h index a236784c4..d93c39688 100644 --- a/cogl/cogl/cogl-spans.h +++ b/cogl/cogl/cogl-spans.h @@ -54,8 +54,8 @@ typedef struct _CoglSpanIter float cover_end; float intersect_start; float intersect_end; - CoglBool intersects; - CoglBool flipped; + gboolean intersects; + gboolean flipped; CoglPipelineWrapMode wrap_mode; int mirror_direction; } CoglSpanIter; @@ -75,7 +75,7 @@ _cogl_span_iter_begin (CoglSpanIter *iter, void _cogl_span_iter_next (CoglSpanIter *iter); -CoglBool +gboolean _cogl_span_iter_end (CoglSpanIter *iter); #endif /* __COGL_SPANS_PRIVATE_H */ diff --git a/cogl/cogl/cogl-sub-texture.c b/cogl/cogl/cogl-sub-texture.c index 9d7abea90..8e5d372f2 100644 --- a/cogl/cogl/cogl-sub-texture.c +++ b/cogl/cogl/cogl-sub-texture.c @@ -31,9 +31,7 @@ * Neil Roberts */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-util.h" #include "cogl-texture-private.h" @@ -42,10 +40,9 @@ #include "cogl-context-private.h" #include "cogl-object.h" #include "cogl-texture-driver.h" -#include "cogl-texture-rectangle-private.h" #include "cogl-texture-2d.h" -#include "cogl-texture-gl-private.h" #include "cogl-gtype-private.h" +#include "driver/gl/cogl-texture-gl-private.h" #include #include @@ -62,30 +59,13 @@ _cogl_sub_texture_unmap_quad (CoglSubTexture *sub_tex, float *coords) { CoglTexture *tex = COGL_TEXTURE (sub_tex); + float width = cogl_texture_get_width (sub_tex->full_texture); + float height = cogl_texture_get_height (sub_tex->full_texture); - /* NB: coords[] come in as non-normalized if sub_tex->full_texture - * is a CoglTextureRectangle otherwhise they are normalized. The - * coordinates we write out though must always be normalized. - * - * NB: sub_tex->sub_x/y/width/height are in non-normalized - * coordinates. - */ - if (cogl_is_texture_rectangle (sub_tex->full_texture)) - { - coords[0] = (coords[0] - sub_tex->sub_x) / tex->width; - coords[1] = (coords[1] - sub_tex->sub_y) / tex->height; - coords[2] = (coords[2] - sub_tex->sub_x) / tex->width; - coords[3] = (coords[3] - sub_tex->sub_y) / tex->height; - } - else - { - float width = cogl_texture_get_width (sub_tex->full_texture); - float height = cogl_texture_get_height (sub_tex->full_texture); - coords[0] = (coords[0] * width - sub_tex->sub_x) / tex->width; - coords[1] = (coords[1] * height - sub_tex->sub_y) / tex->height; - coords[2] = (coords[2] * width - sub_tex->sub_x) / tex->width; - coords[3] = (coords[3] * height - sub_tex->sub_y) / tex->height; - } + coords[0] = (coords[0] * width - sub_tex->sub_x) / tex->width; + coords[1] = (coords[1] * height - sub_tex->sub_y) / tex->height; + coords[2] = (coords[2] * width - sub_tex->sub_x) / tex->width; + coords[3] = (coords[3] * height - sub_tex->sub_y) / tex->height; } static void @@ -93,31 +73,13 @@ _cogl_sub_texture_map_quad (CoglSubTexture *sub_tex, float *coords) { CoglTexture *tex = COGL_TEXTURE (sub_tex); + float width = cogl_texture_get_width (sub_tex->full_texture); + float height = cogl_texture_get_height (sub_tex->full_texture); - /* NB: coords[] always come in as normalized coordinates but may go - * out as non-normalized if sub_tex->full_texture is a - * CoglTextureRectangle. - * - * NB: sub_tex->sub_x/y/width/height are in non-normalized - * coordinates. - */ - - if (cogl_is_texture_rectangle (sub_tex->full_texture)) - { - coords[0] = coords[0] * tex->width + sub_tex->sub_x; - coords[1] = coords[1] * tex->height + sub_tex->sub_y; - coords[2] = coords[2] * tex->width + sub_tex->sub_x; - coords[3] = coords[3] * tex->height + sub_tex->sub_y; - } - else - { - float width = cogl_texture_get_width (sub_tex->full_texture); - float height = cogl_texture_get_height (sub_tex->full_texture); - coords[0] = (coords[0] * tex->width + sub_tex->sub_x) / width; - coords[1] = (coords[1] * tex->height + sub_tex->sub_y) / height; - coords[2] = (coords[2] * tex->width + sub_tex->sub_x) / width; - coords[3] = (coords[3] * tex->height + sub_tex->sub_y) / height; - } + coords[0] = (coords[0] * tex->width + sub_tex->sub_x) / width; + coords[1] = (coords[1] * tex->height + sub_tex->sub_y) / height; + coords[2] = (coords[2] * tex->width + sub_tex->sub_x) / width; + coords[3] = (coords[3] * tex->height + sub_tex->sub_y) / height; } typedef struct _CoglSubTextureForeachData @@ -167,8 +129,7 @@ _cogl_sub_texture_foreach_sub_texture_in_region ( _cogl_sub_texture_map_quad (sub_tex, mapped_coords); /* TODO: Add something like cogl_is_low_level_texture() */ - if (cogl_is_texture_2d (full_texture) || - cogl_is_texture_rectangle (full_texture)) + if (cogl_is_texture_2d (full_texture)) { callback (sub_tex->full_texture, mapped_coords, @@ -198,15 +159,13 @@ _cogl_sub_texture_foreach_sub_texture_in_region ( static void _cogl_sub_texture_gl_flush_legacy_texobj_wrap_modes (CoglTexture *tex, GLenum wrap_mode_s, - GLenum wrap_mode_t, - GLenum wrap_mode_p) + GLenum wrap_mode_t) { CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); _cogl_texture_gl_flush_legacy_texobj_wrap_modes (sub_tex->full_texture, wrap_mode_s, - wrap_mode_t, - wrap_mode_p); + wrap_mode_t); } static void @@ -234,10 +193,10 @@ cogl_sub_texture_new (CoglContext *ctx, next_height = cogl_texture_get_height (next_texture); /* The region must specify a non-zero subset of the full texture */ - _COGL_RETURN_VAL_IF_FAIL (sub_x >= 0 && sub_y >= 0, NULL); - _COGL_RETURN_VAL_IF_FAIL (sub_width > 0 && sub_height > 0, NULL); - _COGL_RETURN_VAL_IF_FAIL (sub_x + sub_width <= next_width, NULL); - _COGL_RETURN_VAL_IF_FAIL (sub_y + sub_height <= next_height, NULL); + g_return_val_if_fail (sub_x >= 0 && sub_y >= 0, NULL); + g_return_val_if_fail (sub_width > 0 && sub_height > 0, NULL); + g_return_val_if_fail (sub_x + sub_width <= next_width, NULL); + g_return_val_if_fail (sub_y + sub_height <= next_height, NULL); sub_tex = g_new (CoglSubTexture, 1); @@ -270,12 +229,12 @@ cogl_sub_texture_new (CoglContext *ctx, return _cogl_sub_texture_object_new (sub_tex); } -static CoglBool +static gboolean _cogl_sub_texture_allocate (CoglTexture *tex, - CoglError **error) + GError **error) { CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - CoglBool status = cogl_texture_allocate (sub_tex->full_texture, error); + gboolean status = cogl_texture_allocate (sub_tex->full_texture, error); _cogl_texture_set_allocated (tex, _cogl_texture_get_format (sub_tex->full_texture), @@ -298,7 +257,7 @@ _cogl_sub_texture_get_max_waste (CoglTexture *tex) return cogl_texture_get_max_waste (sub_tex->full_texture); } -static CoglBool +static gboolean _cogl_sub_texture_is_sliced (CoglTexture *tex) { CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); @@ -306,7 +265,7 @@ _cogl_sub_texture_is_sliced (CoglTexture *tex) return cogl_texture_is_sliced (sub_tex->full_texture); } -static CoglBool +static gboolean _cogl_sub_texture_can_hardware_repeat (CoglTexture *tex) { CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); @@ -356,7 +315,7 @@ _cogl_sub_texture_transform_quad_coords_to_gl (CoglTexture *tex, coords); } -static CoglBool +static gboolean _cogl_sub_texture_get_gl_texture (CoglTexture *tex, GLuint *out_gl_handle, GLenum *out_gl_target) @@ -393,7 +352,7 @@ _cogl_sub_texture_ensure_non_quad_rendering (CoglTexture *tex) { } -static CoglBool +static gboolean _cogl_sub_texture_set_region (CoglTexture *tex, int src_x, int src_y, @@ -403,7 +362,7 @@ _cogl_sub_texture_set_region (CoglTexture *tex, int dst_height, int level, CoglBitmap *bmp, - CoglError **error) + GError **error) { CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); @@ -412,12 +371,12 @@ _cogl_sub_texture_set_region (CoglTexture *tex, int full_width = cogl_texture_get_width (sub_tex->full_texture); int full_height = cogl_texture_get_width (sub_tex->full_texture); - _COGL_RETURN_VAL_IF_FAIL (sub_tex->sub_x == 0 && - cogl_texture_get_width (tex) == full_width, - FALSE); - _COGL_RETURN_VAL_IF_FAIL (sub_tex->sub_y == 0 && - cogl_texture_get_height (tex) == full_height, - FALSE); + g_return_val_if_fail (sub_tex->sub_x == 0 && + cogl_texture_get_width (tex) == full_width, + FALSE); + g_return_val_if_fail (sub_tex->sub_y == 0 && + cogl_texture_get_height (tex) == full_height, + FALSE); } return _cogl_texture_set_region_from_bitmap (sub_tex->full_texture, @@ -430,6 +389,14 @@ _cogl_sub_texture_set_region (CoglTexture *tex, error); } +static gboolean +_cogl_sub_texture_is_get_data_supported (CoglTexture *tex) +{ + CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); + + return cogl_texture_is_get_data_supported (sub_tex->full_texture); +} + static CoglPixelFormat _cogl_sub_texture_get_format (CoglTexture *tex) { @@ -446,20 +413,13 @@ _cogl_sub_texture_get_gl_format (CoglTexture *tex) return _cogl_texture_gl_get_format (sub_tex->full_texture); } -static CoglTextureType -_cogl_sub_texture_get_type (CoglTexture *tex) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - return _cogl_texture_get_type (sub_tex->full_texture); -} - static const CoglTextureVtable cogl_sub_texture_vtable = { FALSE, /* not primitive */ _cogl_sub_texture_allocate, _cogl_sub_texture_set_region, + _cogl_sub_texture_is_get_data_supported, NULL, /* get_data */ _cogl_sub_texture_foreach_sub_texture_in_region, _cogl_sub_texture_get_max_waste, @@ -474,7 +434,5 @@ cogl_sub_texture_vtable = _cogl_sub_texture_gl_flush_legacy_texobj_wrap_modes, _cogl_sub_texture_get_format, _cogl_sub_texture_get_gl_format, - _cogl_sub_texture_get_type, - NULL, /* is_foreign */ NULL /* set_auto_mipmap */ }; diff --git a/cogl/cogl/cogl-sub-texture.h b/cogl/cogl/cogl-sub-texture.h index 7b89bb72c..97874e763 100644 --- a/cogl/cogl/cogl-sub-texture.h +++ b/cogl/cogl/cogl-sub-texture.h @@ -36,7 +36,7 @@ #ifndef __COGL_SUB_TEXTURE_H #define __COGL_SUB_TEXTURE_H -COGL_BEGIN_DECLS +G_BEGIN_DECLS /** * SECTION:cogl-sub-texture @@ -90,7 +90,7 @@ GType cogl_sub_texture_get_gtype (void); * Since: 1.10 * Stability: unstable */ -CoglSubTexture * +COGL_EXPORT CoglSubTexture * cogl_sub_texture_new (CoglContext *ctx, CoglTexture *parent_texture, int sub_x, @@ -111,7 +111,7 @@ cogl_sub_texture_new (CoglContext *ctx, * Since: 1.10 * Stability: unstable */ -CoglTexture * +COGL_EXPORT CoglTexture * cogl_sub_texture_get_parent (CoglSubTexture *sub_texture); /** @@ -126,9 +126,9 @@ cogl_sub_texture_get_parent (CoglSubTexture *sub_texture); * Since: 1.10 * Stability: unstable */ -CoglBool +COGL_EXPORT gboolean cogl_is_sub_texture (void *object); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_SUB_TEXTURE_H */ diff --git a/cogl/cogl/cogl-swap-chain-private.h b/cogl/cogl/cogl-swap-chain-private.h index c67e6f08b..34c2e2120 100644 --- a/cogl/cogl/cogl-swap-chain-private.h +++ b/cogl/cogl/cogl-swap-chain-private.h @@ -37,7 +37,7 @@ struct _CoglSwapChain { CoglObject _parent; - CoglBool has_alpha; + gboolean has_alpha; int length; }; diff --git a/cogl/cogl/cogl-swap-chain.c b/cogl/cogl/cogl-swap-chain.c index 558dad230..89bab0049 100644 --- a/cogl/cogl/cogl-swap-chain.c +++ b/cogl/cogl/cogl-swap-chain.c @@ -29,9 +29,7 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-object.h" @@ -63,7 +61,7 @@ cogl_swap_chain_new (void) void cogl_swap_chain_set_has_alpha (CoglSwapChain *swap_chain, - CoglBool has_alpha) + gboolean has_alpha) { swap_chain->has_alpha = has_alpha; } diff --git a/cogl/cogl/cogl-swap-chain.h b/cogl/cogl/cogl-swap-chain.h index dd854bcc9..6e965ee9a 100644 --- a/cogl/cogl/cogl-swap-chain.h +++ b/cogl/cogl/cogl-swap-chain.h @@ -37,7 +37,7 @@ #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS typedef struct _CoglSwapChain CoglSwapChain; @@ -46,22 +46,23 @@ typedef struct _CoglSwapChain CoglSwapChain; * * Returns: a #GType that can be used with the GLib type system. */ +COGL_EXPORT GType cogl_swap_chain_get_gtype (void); -CoglSwapChain * +COGL_EXPORT CoglSwapChain * cogl_swap_chain_new (void); -void +COGL_EXPORT void cogl_swap_chain_set_has_alpha (CoglSwapChain *swap_chain, - CoglBool has_alpha); + gboolean has_alpha); -void +COGL_EXPORT void cogl_swap_chain_set_length (CoglSwapChain *swap_chain, int length); -CoglBool +COGL_EXPORT gboolean cogl_is_swap_chain (void *object); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_SWAP_CHAIN_H__ */ diff --git a/cogl/cogl/cogl-texture-2d-gl.h b/cogl/cogl/cogl-texture-2d-gl.h deleted file mode 100644 index e7b22df91..000000000 --- a/cogl/cogl/cogl-texture-2d-gl.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Robert Bragg - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef _COGL_TEXTURE_2D_GL_H_ -#define _COGL_TEXTURE_2D_GL_H_ - -#include "cogl-context.h" -#include "cogl-texture-2d.h" - -COGL_BEGIN_DECLS - -/** - * cogl_texture_2d_gl_new_from_foreign: - * @ctx: A #CoglContext - * @gl_handle: A GL handle for a GL_TEXTURE_2D texture object - * @width: Width of the foreign GL texture - * @height: Height of the foreign GL texture - * @format: The format of the texture - * - * Wraps an existing GL_TEXTURE_2D texture object as a #CoglTexture2D. - * This can be used for integrating Cogl with software using OpenGL - * directly. - * - * The texture is still configurable until it has been allocated so - * for example you can declare whether the texture is premultiplied - * with cogl_texture_set_premultiplied(). - * - * The results are undefined for passing an invalid @gl_handle - * or if @width or @height don't have the correct texture - * geometry. - * - * Returns: (transfer full): A newly allocated #CoglTexture2D - * - * Since: 2.0 - */ -CoglTexture2D * -cogl_texture_2d_gl_new_from_foreign (CoglContext *ctx, - unsigned int gl_handle, - int width, - int height, - CoglPixelFormat format); - -COGL_END_DECLS - -#endif /* _COGL_TEXTURE_2D_GL_H_ */ diff --git a/cogl/cogl/cogl-texture-2d-private.h b/cogl/cogl/cogl-texture-2d-private.h index feda782c1..4f41dadf5 100644 --- a/cogl/cogl/cogl-texture-2d-private.h +++ b/cogl/cogl/cogl-texture-2d-private.h @@ -44,9 +44,9 @@ struct _CoglTexture2D CoglPixelFormat */ CoglPixelFormat internal_format; - CoglBool auto_mipmap; - CoglBool mipmaps_dirty; - CoglBool is_foreign; + gboolean auto_mipmap; + gboolean mipmaps_dirty; + gboolean is_get_data_supported; /* TODO: factor out these OpenGL specific members into some form * of driver private state. */ @@ -70,7 +70,7 @@ struct _CoglTexture2D CoglTexture2D * _cogl_texture_2d_new_from_bitmap (CoglBitmap *bmp, - CoglBool can_convert_in_place); + gboolean can_convert_in_place); CoglTexture2D * _cogl_texture_2d_create_base (CoglContext *ctx, @@ -81,7 +81,7 @@ _cogl_texture_2d_create_base (CoglContext *ctx, void _cogl_texture_2d_set_auto_mipmap (CoglTexture *tex, - CoglBool value); + gboolean value); /* * _cogl_texture_2d_externally_modified: diff --git a/cogl/cogl/cogl-texture-2d-sliced-private.h b/cogl/cogl/cogl-texture-2d-sliced-private.h index e827923c0..5ca4cbf32 100644 --- a/cogl/cogl/cogl-texture-2d-sliced-private.h +++ b/cogl/cogl/cogl-texture-2d-sliced-private.h @@ -49,19 +49,9 @@ struct _CoglTexture2DSliced CoglPixelFormat internal_format; }; -CoglTexture2DSliced * -_cogl_texture_2d_sliced_new_from_foreign (CoglContext *context, - unsigned int gl_handle, - unsigned int gl_target, - int width, - int height, - int x_pot_waste, - int y_pot_waste, - CoglPixelFormat format); - CoglTexture2DSliced * _cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp, int max_waste, - CoglBool can_convert_in_place); + gboolean can_convert_in_place); #endif /* __COGL_TEXTURE_2D_SLICED_PRIVATE_H */ diff --git a/cogl/cogl/cogl-texture-2d-sliced.c b/cogl/cogl/cogl-texture-2d-sliced.c index 454cdadfa..2d903e83b 100644 --- a/cogl/cogl/cogl-texture-2d-sliced.c +++ b/cogl/cogl/cogl-texture-2d-sliced.c @@ -33,9 +33,7 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-debug.h" #include "cogl-private.h" @@ -43,20 +41,16 @@ #include "cogl-bitmap.h" #include "cogl-bitmap-private.h" #include "cogl-texture-private.h" -#include "cogl-texture-2d-gl.h" #include "cogl-texture-2d-private.h" #include "cogl-texture-2d-sliced-private.h" -#include "cogl-texture-gl-private.h" #include "cogl-texture-driver.h" #include "cogl-context-private.h" #include "cogl-object-private.h" #include "cogl-spans.h" #include "cogl-journal-private.h" -#include "cogl-pipeline-opengl-private.h" #include "cogl-primitive-texture.h" -#include "cogl-error-private.h" -#include "cogl-texture-gl-private.h" #include "cogl-gtype-private.h" +#include "driver/gl/cogl-texture-gl-private.h" #include #include @@ -158,6 +152,9 @@ _cogl_texture_2d_sliced_allocate_waste_buffer (CoglTexture2DSliced *tex_2ds, CoglSpan *last_y_span; uint8_t *waste_buf = NULL; + g_return_val_if_fail (format != COGL_PIXEL_FORMAT_ANY, NULL); + g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, NULL); + /* If the texture has any waste then allocate a buffer big enough to fill the gaps */ last_x_span = &g_array_index (tex_2ds->slice_x_spans, CoglSpan, @@ -166,7 +163,7 @@ _cogl_texture_2d_sliced_allocate_waste_buffer (CoglTexture2DSliced *tex_2ds, tex_2ds->slice_y_spans->len - 1); if (last_x_span->waste > 0 || last_y_span->waste > 0) { - int bpp = _cogl_pixel_format_get_bytes_per_pixel (format); + int bpp = cogl_pixel_format_get_bytes_per_pixel (format, 0); CoglSpan *first_x_span = &g_array_index (tex_2ds->slice_x_spans, CoglSpan, 0); CoglSpan *first_y_span @@ -174,13 +171,13 @@ _cogl_texture_2d_sliced_allocate_waste_buffer (CoglTexture2DSliced *tex_2ds, unsigned int right_size = first_y_span->size * last_x_span->waste; unsigned int bottom_size = first_x_span->size * last_y_span->waste; - waste_buf = malloc (MAX (right_size, bottom_size) * bpp); + waste_buf = g_malloc (MAX (right_size, bottom_size) * bpp); } return waste_buf; } -static CoglBool +static gboolean _cogl_texture_2d_sliced_set_waste (CoglTexture2DSliced *tex_2ds, CoglBitmap *source_bmp, CoglTexture2D *slice_tex, @@ -193,9 +190,9 @@ _cogl_texture_2d_sliced_set_waste (CoglTexture2DSliced *tex_2ds, int src_y, int dst_x, int dst_y, - CoglError **error) + GError **error) { - CoglBool need_x, need_y; + gboolean need_x, need_y; CoglContext *ctx = COGL_TEXTURE (tex_2ds)->context; /* If the x_span is sliced and the upload touches the @@ -212,17 +209,23 @@ _cogl_texture_2d_sliced_set_waste (CoglTexture2DSliced *tex_2ds, { int bmp_rowstride = cogl_bitmap_get_rowstride (source_bmp); CoglPixelFormat source_format = cogl_bitmap_get_format (source_bmp); - int bpp = _cogl_pixel_format_get_bytes_per_pixel (source_format); + int bpp; uint8_t *bmp_data; const uint8_t *src; uint8_t *dst; unsigned int wy, wx; CoglBitmap *waste_bmp; + /* We only support single plane formats here */ + if (cogl_pixel_format_get_n_planes (source_format) == 1) + return FALSE; + bmp_data = _cogl_bitmap_map (source_bmp, COGL_BUFFER_ACCESS_READ, 0, error); if (bmp_data == NULL) return FALSE; + bpp = cogl_pixel_format_get_bytes_per_pixel (source_format, 0); + if (need_x) { src = (bmp_data + ((src_y + (int) y_iter->intersect_start - dst_y) * @@ -341,10 +344,10 @@ _cogl_texture_2d_sliced_set_waste (CoglTexture2DSliced *tex_2ds, return TRUE; } -static CoglBool +static gboolean _cogl_texture_2d_sliced_upload_bitmap (CoglTexture2DSliced *tex_2ds, CoglBitmap *bmp, - CoglError **error) + GError **error) { CoglSpan *x_span; CoglSpan *y_span; @@ -389,7 +392,7 @@ _cogl_texture_2d_sliced_upload_bitmap (CoglTexture2DSliced *tex_2ds, error)) { if (waste_buf) - free (waste_buf); + g_free (waste_buf); return FALSE; } @@ -419,19 +422,19 @@ _cogl_texture_2d_sliced_upload_bitmap (CoglTexture2DSliced *tex_2ds, error)) /* dst_y */ { if (waste_buf) - free (waste_buf); + g_free (waste_buf); return FALSE; } } } if (waste_buf) - free (waste_buf); + g_free (waste_buf); return TRUE; } -static CoglBool +static gboolean _cogl_texture_2d_sliced_upload_subregion (CoglTexture2DSliced *tex_2ds, int src_x, int src_y, @@ -440,7 +443,7 @@ _cogl_texture_2d_sliced_upload_subregion (CoglTexture2DSliced *tex_2ds, int width, int height, CoglBitmap *source_bmp, - CoglError **error) + GError **error) { CoglTexture *tex = COGL_TEXTURE (tex_2ds); CoglSpan *x_span; @@ -523,7 +526,7 @@ _cogl_texture_2d_sliced_upload_subregion (CoglTexture2DSliced *tex_2ds, error)) { if (waste_buf) - free (waste_buf); + g_free (waste_buf); return FALSE; } @@ -538,14 +541,14 @@ _cogl_texture_2d_sliced_upload_subregion (CoglTexture2DSliced *tex_2ds, error)) { if (waste_buf) - free (waste_buf); + g_free (waste_buf); return FALSE; } } } if (waste_buf) - free (waste_buf); + g_free (waste_buf); return TRUE; } @@ -587,70 +590,10 @@ _cogl_rect_slices_for_size (int size_to_fill, return n_spans; } -static int -_cogl_pot_slices_for_size (int size_to_fill, - int max_span_size, - int max_waste, - GArray *out_spans) -{ - int n_spans = 0; - CoglSpan span; - - /* Init first slice span */ - span.start = 0; - span.size = max_span_size; - span.waste = 0; - - /* Fix invalid max_waste */ - if (max_waste < 0) - max_waste = 0; - - while (TRUE) - { - /* Is the whole area covered? */ - if (size_to_fill > span.size) - { - /* Not yet - add a span of this size */ - if (out_spans) - g_array_append_val (out_spans, span); - - span.start += span.size; - size_to_fill -= span.size; - n_spans++; - } - else if (span.size - size_to_fill <= max_waste) - { - /* Yes and waste is small enough */ - /* Pick the next power of two up from size_to_fill. This can - sometimes be less than the span.size that would be chosen - otherwise */ - span.size = _cogl_util_next_p2 (size_to_fill); - span.waste = span.size - size_to_fill; - if (out_spans) - g_array_append_val (out_spans, span); - - return ++n_spans; - } - else - { - /* Yes but waste is too large */ - while (span.size - size_to_fill > max_waste) - { - span.size /= 2; - g_assert (span.size > 0); - } - } - } - - /* Can't get here */ - return 0; -} - static void _cogl_texture_2d_sliced_gl_flush_legacy_texobj_wrap_modes (CoglTexture *tex, GLenum wrap_mode_s, - GLenum wrap_mode_t, - GLenum wrap_mode_p) + GLenum wrap_mode_t) { CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); int i; @@ -664,8 +607,7 @@ _cogl_texture_2d_sliced_gl_flush_legacy_texobj_wrap_modes (CoglTexture *tex, _cogl_texture_gl_flush_legacy_texobj_wrap_modes (COGL_TEXTURE (slice_tex), wrap_mode_s, - wrap_mode_t, - wrap_mode_p); + wrap_mode_t); } } @@ -685,14 +627,14 @@ free_spans (CoglTexture2DSliced *tex_2ds) } } -static CoglBool +static gboolean setup_spans (CoglContext *ctx, CoglTexture2DSliced *tex_2ds, int width, int height, int max_waste, CoglPixelFormat internal_format, - CoglError **error) + GError **error) { int max_width; int max_height; @@ -702,18 +644,9 @@ setup_spans (CoglContext *ctx, int (*slices_for_size) (int, int, int, GArray*); /* Initialize size of largest slice according to supported features */ - if (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT)) - { - max_width = width; - max_height = height; - slices_for_size = _cogl_rect_slices_for_size; - } - else - { - max_width = _cogl_util_next_p2 (width); - max_height = _cogl_util_next_p2 (height); - slices_for_size = _cogl_pot_slices_for_size; - } + max_width = width; + max_height = height; + slices_for_size = _cogl_rect_slices_for_size; /* Negative number means no slicing forced by the user */ if (max_waste <= -1) @@ -726,13 +659,11 @@ setup_spans (CoglContext *ctx, max_height, internal_format)) { - _cogl_set_error (error, - COGL_TEXTURE_ERROR, - COGL_TEXTURE_ERROR_SIZE, - "Sliced texture size of %d x %d not possible " - "with max waste set to -1", - width, - height); + g_set_error (error, COGL_TEXTURE_ERROR, COGL_TEXTURE_ERROR_SIZE, + "Sliced texture size of %d x %d not possible " + "with max waste set to -1", + width, + height); return FALSE; } @@ -776,10 +707,8 @@ setup_spans (CoglContext *ctx, { /* Maybe it would be ok to just g_warn_if_reached() for this * codepath */ - _cogl_set_error (error, - COGL_TEXTURE_ERROR, - COGL_TEXTURE_ERROR_SIZE, - "No suitable slice geometry found"); + g_set_error (error, COGL_TEXTURE_ERROR, COGL_TEXTURE_ERROR_SIZE, + "No suitable slice geometry found"); free_spans (tex_2ds); return FALSE; } @@ -836,13 +765,13 @@ free_slices (CoglTexture2DSliced *tex_2ds) free_spans (tex_2ds); } -static CoglBool +static gboolean allocate_slices (CoglTexture2DSliced *tex_2ds, int width, int height, int max_waste, CoglPixelFormat internal_format, - CoglError **error) + GError **error) { CoglTexture *tex = COGL_TEXTURE (tex_2ds); CoglContext *ctx = tex->context; @@ -957,11 +886,11 @@ cogl_texture_2d_sliced_new_with_size (CoglContext *ctx, CoglTexture2DSliced * _cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp, int max_waste, - CoglBool can_convert_in_place) + gboolean can_convert_in_place) { CoglTextureLoader *loader; - _COGL_RETURN_VAL_IF_FAIL (cogl_is_bitmap (bmp), NULL); + g_return_val_if_fail (cogl_is_bitmap (bmp), NULL); loader = _cogl_texture_create_loader (); loader->src_type = COGL_TEXTURE_SOURCE_TYPE_BITMAP; @@ -985,52 +914,6 @@ cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp, FALSE); } -CoglTexture2DSliced * -_cogl_texture_2d_sliced_new_from_foreign (CoglContext *ctx, - unsigned int gl_handle, - unsigned int gl_target, - int width, - int height, - int x_pot_waste, - int y_pot_waste, - CoglPixelFormat format) -{ - CoglTextureLoader *loader; - - /* NOTE: width, height and internal format are not queriable - * in GLES, hence such a function prototype. - */ - - /* This should only be called when the texture target is 2D. If a - rectangle texture is used then _cogl_texture_new_from_foreign - will create a cogl_texture_rectangle instead */ - _COGL_RETURN_VAL_IF_FAIL (gl_target == GL_TEXTURE_2D, NULL); - - /* Assert it is a valid GL texture object */ - _COGL_RETURN_VAL_IF_FAIL (ctx->glIsTexture (gl_handle), FALSE); - - /* Validate width and height */ - _COGL_RETURN_VAL_IF_FAIL (width > 0 && height > 0, NULL); - - /* Validate pot waste */ - _COGL_RETURN_VAL_IF_FAIL (x_pot_waste >= 0 && x_pot_waste < width && - y_pot_waste >= 0 && y_pot_waste < height, - NULL); - - loader = _cogl_texture_create_loader (); - loader->src_type = COGL_TEXTURE_SOURCE_TYPE_GL_FOREIGN; - loader->src.gl_foreign.gl_handle = gl_handle; - loader->src.gl_foreign.width = width + x_pot_waste; - loader->src.gl_foreign.height = height + y_pot_waste; - loader->src.gl_foreign.format = format; - - return _cogl_texture_2d_sliced_create_base (ctx, - width, - height, - 0, /* max waste */ - format, loader); -} - CoglTexture2DSliced * cogl_texture_2d_sliced_new_from_data (CoglContext *ctx, int width, @@ -1039,17 +922,18 @@ cogl_texture_2d_sliced_new_from_data (CoglContext *ctx, CoglPixelFormat format, int rowstride, const uint8_t *data, - CoglError **error) + GError **error) { CoglBitmap *bmp; CoglTexture2DSliced *tex_2ds; - _COGL_RETURN_VAL_IF_FAIL (format != COGL_PIXEL_FORMAT_ANY, NULL); - _COGL_RETURN_VAL_IF_FAIL (data != NULL, NULL); + g_return_val_if_fail (format != COGL_PIXEL_FORMAT_ANY, NULL); + g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, NULL); + g_return_val_if_fail (data != NULL, NULL); /* Rowstride from width if not given */ if (rowstride == 0) - rowstride = width * _cogl_pixel_format_get_bytes_per_pixel (format); + rowstride = width * cogl_pixel_format_get_bytes_per_pixel (format, 0); /* Wrap the data into a bitmap */ bmp = cogl_bitmap_new_for_data (ctx, @@ -1076,12 +960,12 @@ CoglTexture2DSliced * cogl_texture_2d_sliced_new_from_file (CoglContext *ctx, const char *filename, int max_waste, - CoglError **error) + GError **error) { CoglBitmap *bmp; CoglTexture2DSliced *tex_2ds = NULL; - _COGL_RETURN_VAL_IF_FAIL (error == NULL || *error == NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); bmp = _cogl_bitmap_from_file (ctx, filename, error); if (bmp == NULL) @@ -1096,10 +980,10 @@ cogl_texture_2d_sliced_new_from_file (CoglContext *ctx, return tex_2ds; } -static CoglBool +static gboolean allocate_with_size (CoglTexture2DSliced *tex_2ds, CoglTextureLoader *loader, - CoglError **error) + GError **error) { CoglTexture *tex = COGL_TEXTURE (tex_2ds); CoglPixelFormat internal_format = @@ -1122,20 +1006,20 @@ allocate_with_size (CoglTexture2DSliced *tex_2ds, return FALSE; } -static CoglBool +static gboolean allocate_from_bitmap (CoglTexture2DSliced *tex_2ds, CoglTextureLoader *loader, - CoglError **error) + GError **error) { CoglTexture *tex = COGL_TEXTURE (tex_2ds); CoglBitmap *bmp = loader->src.bitmap.bitmap; int width = cogl_bitmap_get_width (bmp); int height = cogl_bitmap_get_height (bmp); - CoglBool can_convert_in_place = loader->src.bitmap.can_convert_in_place; + gboolean can_convert_in_place = loader->src.bitmap.can_convert_in_place; CoglPixelFormat internal_format; CoglBitmap *upload_bmp; - _COGL_RETURN_VAL_IF_FAIL (tex_2ds->slice_textures == NULL, FALSE); + g_return_val_if_fail (tex_2ds->slice_textures == NULL, FALSE); internal_format = _cogl_texture_determine_internal_format (tex, @@ -1175,79 +1059,14 @@ allocate_from_bitmap (CoglTexture2DSliced *tex_2ds, return TRUE; } -static CoglBool -allocate_from_gl_foreign (CoglTexture2DSliced *tex_2ds, - CoglTextureLoader *loader, - CoglError **error) -{ - CoglTexture *tex = COGL_TEXTURE (tex_2ds); - CoglContext *ctx = tex->context; - CoglPixelFormat format = loader->src.gl_foreign.format; - int gl_width = loader->src.gl_foreign.width; - int gl_height = loader->src.gl_foreign.height; - int x_pot_waste = gl_width - tex->width; - int y_pot_waste = gl_height - tex->height; - CoglSpan x_span; - CoglSpan y_span; - CoglTexture2D *tex_2d = - cogl_texture_2d_gl_new_from_foreign (ctx, - loader->src.gl_foreign.gl_handle, - gl_width, - gl_height, - format); - - if (!cogl_texture_allocate (COGL_TEXTURE (tex_2d), error)) - { - cogl_object_unref (tex_2d); - return FALSE; - } - - /* The texture 2d backend may use a different pixel format if it - queries the actual texture so we'll refetch the format it - actually used */ - format = _cogl_texture_get_format (tex); - - tex_2ds->internal_format = format; - - /* Create slice arrays */ - tex_2ds->slice_x_spans = - g_array_sized_new (FALSE, FALSE, sizeof (CoglSpan), 1); - - tex_2ds->slice_y_spans = - g_array_sized_new (FALSE, FALSE, sizeof (CoglSpan), 1); - - tex_2ds->slice_textures = - g_array_sized_new (FALSE, FALSE, sizeof (CoglTexture2D *), 1); - - /* Store info for a single slice */ - x_span.start = 0; - x_span.size = gl_width; - x_span.waste = x_pot_waste; - g_array_append_val (tex_2ds->slice_x_spans, x_span); - - y_span.start = 0; - y_span.size = gl_height; - y_span.waste = y_pot_waste; - g_array_append_val (tex_2ds->slice_y_spans, y_span); - - g_array_append_val (tex_2ds->slice_textures, tex_2d); - - _cogl_texture_set_allocated (tex, - format, - tex->width, - tex->height); - - return TRUE; -} - -static CoglBool +static gboolean _cogl_texture_2d_sliced_allocate (CoglTexture *tex, - CoglError **error) + GError **error) { CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); CoglTextureLoader *loader = tex->loader; - _COGL_RETURN_VAL_IF_FAIL (loader, FALSE); + g_return_val_if_fail (loader, FALSE); switch (loader->src_type) { @@ -1255,8 +1074,6 @@ _cogl_texture_2d_sliced_allocate (CoglTexture *tex, return allocate_with_size (tex_2ds, loader, error); case COGL_TEXTURE_SOURCE_TYPE_BITMAP: return allocate_from_bitmap (tex_2ds, loader, error); - case COGL_TEXTURE_SOURCE_TYPE_GL_FOREIGN: - return allocate_from_gl_foreign (tex_2ds, loader, error); default: break; } @@ -1264,21 +1081,6 @@ _cogl_texture_2d_sliced_allocate (CoglTexture *tex, g_return_val_if_reached (FALSE); } -static CoglBool -_cogl_texture_2d_sliced_is_foreign (CoglTexture *tex) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - CoglTexture2D *slice_tex; - - /* Make sure slices were created */ - if (tex_2ds->slice_textures == NULL) - return FALSE; - - /* Pass the call on to the first slice */ - slice_tex = g_array_index (tex_2ds->slice_textures, CoglTexture2D *, 0); - return _cogl_texture_is_foreign (COGL_TEXTURE (slice_tex)); -} - static int _cogl_texture_2d_sliced_get_max_waste (CoglTexture *tex) { @@ -1287,7 +1089,7 @@ _cogl_texture_2d_sliced_get_max_waste (CoglTexture *tex) return tex_2ds->max_waste; } -static CoglBool +static gboolean _cogl_texture_2d_sliced_is_sliced (CoglTexture *tex) { CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); @@ -1304,7 +1106,7 @@ _cogl_texture_2d_sliced_is_sliced (CoglTexture *tex) return FALSE; } -static CoglBool +static gboolean _cogl_texture_2d_sliced_can_hardware_repeat (CoglTexture *tex) { CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); @@ -1355,7 +1157,7 @@ static CoglTransformResult _cogl_texture_2d_sliced_transform_quad_coords_to_gl (CoglTexture *tex, float *coords) { - CoglBool need_repeat = FALSE; + gboolean need_repeat = FALSE; int i; /* This is a bit lazy - in the case where the quad lies entirely @@ -1380,7 +1182,7 @@ _cogl_texture_2d_sliced_transform_quad_coords_to_gl (CoglTexture *tex, ? COGL_TRANSFORM_HARDWARE_REPEAT : COGL_TRANSFORM_NO_REPEAT); } -static CoglBool +static gboolean _cogl_texture_2d_sliced_get_gl_texture (CoglTexture *tex, GLuint *out_gl_handle, GLenum *out_gl_target) @@ -1409,7 +1211,7 @@ _cogl_texture_2d_sliced_gl_flush_legacy_texobj_filters (CoglTexture *tex, CoglTexture2D *slice_tex; int i; - _COGL_RETURN_IF_FAIL (tex_2ds->slice_textures != NULL); + g_return_if_fail (tex_2ds->slice_textures != NULL); /* Apply new filters to every slice. The slice texture itself should cache the value and avoid resubmitting the same filter value to @@ -1429,7 +1231,7 @@ _cogl_texture_2d_sliced_pre_paint (CoglTexture *tex, CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); int i; - _COGL_RETURN_IF_FAIL (tex_2ds->slice_textures != NULL); + g_return_if_fail (tex_2ds->slice_textures != NULL); /* Pass the pre-paint on to every slice */ for (i = 0; i < tex_2ds->slice_textures->len; i++) @@ -1446,7 +1248,7 @@ _cogl_texture_2d_sliced_ensure_non_quad_rendering (CoglTexture *tex) CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); int i; - _COGL_RETURN_IF_FAIL (tex_2ds->slice_textures != NULL); + g_return_if_fail (tex_2ds->slice_textures != NULL); /* Pass the call on to every slice */ for (i = 0; i < tex_2ds->slice_textures->len; i++) @@ -1457,7 +1259,7 @@ _cogl_texture_2d_sliced_ensure_non_quad_rendering (CoglTexture *tex) } } -static CoglBool +static gboolean _cogl_texture_2d_sliced_set_region (CoglTexture *tex, int src_x, int src_y, @@ -1467,11 +1269,11 @@ _cogl_texture_2d_sliced_set_region (CoglTexture *tex, int dst_height, int level, CoglBitmap *bmp, - CoglError **error) + GError **error) { CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); CoglBitmap *upload_bmp; - CoglBool status; + gboolean status; upload_bmp = _cogl_bitmap_convert_for_upload (bmp, _cogl_texture_get_format (tex), @@ -1514,18 +1316,13 @@ _cogl_texture_2d_sliced_get_gl_format (CoglTexture *tex) return _cogl_texture_gl_get_format (COGL_TEXTURE (slice_tex)); } -static CoglTextureType -_cogl_texture_2d_sliced_get_type (CoglTexture *tex) -{ - return COGL_TEXTURE_TYPE_2D; -} - static const CoglTextureVtable cogl_texture_2d_sliced_vtable = { FALSE, /* not primitive */ _cogl_texture_2d_sliced_allocate, _cogl_texture_2d_sliced_set_region, + NULL, /* is_get_data_supported */ NULL, /* get_data */ _cogl_texture_2d_sliced_foreach_sub_texture_in_region, _cogl_texture_2d_sliced_get_max_waste, @@ -1540,7 +1337,5 @@ cogl_texture_2d_sliced_vtable = _cogl_texture_2d_sliced_gl_flush_legacy_texobj_wrap_modes, _cogl_texture_2d_sliced_get_format, _cogl_texture_2d_sliced_get_gl_format, - _cogl_texture_2d_sliced_get_type, - _cogl_texture_2d_sliced_is_foreign, NULL /* set_auto_mipmap */ }; diff --git a/cogl/cogl/cogl-texture-2d-sliced.h b/cogl/cogl/cogl-texture-2d-sliced.h index 7208ef41e..29a25a570 100644 --- a/cogl/cogl/cogl-texture-2d-sliced.h +++ b/cogl/cogl/cogl-texture-2d-sliced.h @@ -75,10 +75,11 @@ typedef struct _CoglTexture2DSliced CoglTexture2DSliced; * * Returns: a #GType that can be used with the GLib type system. */ +COGL_EXPORT GType cogl_texture_2d_sliced_get_gtype (void); /** - * cogl_texture_2d_sliced_new_with_size: + * cogl_texture_2d_sliced_new_with_size: (skip) * @ctx: A #CoglContext * @width: The virtual width of your sliced texture. * @height: The virtual height of your sliced texture. @@ -118,21 +119,21 @@ GType cogl_texture_2d_sliced_get_gtype (void); * Since: 1.10 * Stability: unstable */ -CoglTexture2DSliced * +COGL_EXPORT CoglTexture2DSliced * cogl_texture_2d_sliced_new_with_size (CoglContext *ctx, int width, int height, int max_waste); /** - * cogl_texture_2d_sliced_new_from_file: + * cogl_texture_2d_sliced_new_from_file: (skip) * @ctx: A #CoglContext * @filename: the file to load * @max_waste: The threshold of how wide a strip of wasted texels * are allowed along the right and bottom textures before * they must be sliced to reduce the amount of waste. A * negative can be passed to disable slicing. - * @error: A #CoglError to catch exceptional errors or %NULL + * @error: A #GError to catch exceptional errors or %NULL * * Creates a #CoglTexture2DSliced from an image file. * @@ -166,14 +167,14 @@ cogl_texture_2d_sliced_new_with_size (CoglContext *ctx, * * Since: 1.16 */ -CoglTexture2DSliced * +COGL_EXPORT CoglTexture2DSliced * cogl_texture_2d_sliced_new_from_file (CoglContext *ctx, const char *filename, int max_waste, - CoglError **error); + GError **error); /** - * cogl_texture_2d_sliced_new_from_data: + * cogl_texture_2d_sliced_new_from_data: (skip) * @ctx: A #CoglContext * @width: width of texture in pixels * @height: height of texture in pixels @@ -186,7 +187,7 @@ cogl_texture_2d_sliced_new_from_file (CoglContext *ctx, * row in @data. A value of 0 will make Cogl automatically * calculate @rowstride from @width and @format. * @data: pointer the memory region where the source buffer resides - * @error: A #CoglError to catch exceptional errors or %NULL + * @error: A #GError to catch exceptional errors or %NULL * * Creates a new #CoglTexture2DSliced texture based on data residing * in memory. @@ -227,7 +228,7 @@ cogl_texture_2d_sliced_new_from_file (CoglContext *ctx, * * Since: 1.16 */ -CoglTexture2DSliced * +COGL_EXPORT CoglTexture2DSliced * cogl_texture_2d_sliced_new_from_data (CoglContext *ctx, int width, int height, @@ -235,7 +236,7 @@ cogl_texture_2d_sliced_new_from_data (CoglContext *ctx, CoglPixelFormat format, int rowstride, const uint8_t *data, - CoglError **error); + GError **error); /** * cogl_texture_2d_sliced_new_from_bitmap: @@ -278,7 +279,7 @@ cogl_texture_2d_sliced_new_from_data (CoglContext *ctx, * * Since: 1.16 */ -CoglTexture2DSliced * +COGL_EXPORT CoglTexture2DSliced * cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp, int max_waste); @@ -293,7 +294,7 @@ cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp, * Since: 1.10 * Stability: unstable */ -CoglBool +COGL_EXPORT gboolean cogl_is_texture_2d_sliced (void *object); #endif /* __COGL_TEXURE_2D_SLICED_H */ diff --git a/cogl/cogl/cogl-texture-2d.c b/cogl/cogl/cogl-texture-2d.c index 663125890..bababf749 100644 --- a/cogl/cogl/cogl-texture-2d.c +++ b/cogl/cogl/cogl-texture-2d.c @@ -31,26 +31,22 @@ * Neil Roberts */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-private.h" #include "cogl-util.h" #include "cogl-texture-private.h" #include "cogl-texture-2d-private.h" -#include "cogl-texture-2d-gl-private.h" #include "cogl-texture-driver.h" #include "cogl-context-private.h" #include "cogl-object-private.h" #include "cogl-journal-private.h" -#include "cogl-pipeline-opengl-private.h" #include "cogl-framebuffer-private.h" -#include "cogl-error-private.h" +#include "cogl-gtype-private.h" +#include "driver/gl/cogl-texture-2d-gl-private.h" #ifdef COGL_HAS_EGL_SUPPORT -#include "cogl-winsys-egl-private.h" +#include "winsys/cogl-winsys-egl-private.h" #endif -#include "cogl-gtype-private.h" #include #include @@ -87,7 +83,7 @@ _cogl_texture_2d_free (CoglTexture2D *tex_2d) void _cogl_texture_2d_set_auto_mipmap (CoglTexture *tex, - CoglBool value) + gboolean value) { CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex); @@ -109,11 +105,10 @@ _cogl_texture_2d_create_base (CoglContext *ctx, tex_2d->mipmaps_dirty = TRUE; tex_2d->auto_mipmap = TRUE; + tex_2d->is_get_data_supported = TRUE; tex_2d->gl_target = GL_TEXTURE_2D; - tex_2d->is_foreign = FALSE; - ctx->driver_vtable->texture_2d_init (tex_2d); return _cogl_texture_2d_object_new (tex_2d); @@ -126,6 +121,9 @@ cogl_texture_2d_new_with_size (CoglContext *ctx, { CoglTextureLoader *loader; + g_return_val_if_fail (width >= 1, NULL); + g_return_val_if_fail (height >= 1, NULL); + loader = _cogl_texture_create_loader (); loader->src_type = COGL_TEXTURE_SOURCE_TYPE_SIZED; loader->src.sized.width = width; @@ -135,9 +133,9 @@ cogl_texture_2d_new_with_size (CoglContext *ctx, COGL_PIXEL_FORMAT_RGBA_8888_PRE, loader); } -static CoglBool +static gboolean _cogl_texture_2d_allocate (CoglTexture *tex, - CoglError **error) + GError **error) { CoglContext *ctx = tex->context; @@ -146,11 +144,11 @@ _cogl_texture_2d_allocate (CoglTexture *tex, CoglTexture2D * _cogl_texture_2d_new_from_bitmap (CoglBitmap *bmp, - CoglBool can_convert_in_place) + gboolean can_convert_in_place) { CoglTextureLoader *loader; - _COGL_RETURN_VAL_IF_FAIL (bmp != NULL, NULL); + g_return_val_if_fail (bmp != NULL, NULL); loader = _cogl_texture_create_loader (); loader->src_type = COGL_TEXTURE_SOURCE_TYPE_BITMAP; @@ -174,12 +172,12 @@ cogl_texture_2d_new_from_bitmap (CoglBitmap *bmp) CoglTexture2D * cogl_texture_2d_new_from_file (CoglContext *ctx, const char *filename, - CoglError **error) + GError **error) { CoglBitmap *bmp; CoglTexture2D *tex_2d = NULL; - _COGL_RETURN_VAL_IF_FAIL (error == NULL || *error == NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); bmp = _cogl_bitmap_from_file (ctx, filename, error); if (bmp == NULL) @@ -200,17 +198,18 @@ cogl_texture_2d_new_from_data (CoglContext *ctx, CoglPixelFormat format, int rowstride, const uint8_t *data, - CoglError **error) + GError **error) { CoglBitmap *bmp; CoglTexture2D *tex_2d; - _COGL_RETURN_VAL_IF_FAIL (format != COGL_PIXEL_FORMAT_ANY, NULL); - _COGL_RETURN_VAL_IF_FAIL (data != NULL, NULL); + g_return_val_if_fail (format != COGL_PIXEL_FORMAT_ANY, NULL); + g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, NULL); + g_return_val_if_fail (data != NULL, NULL); /* Rowstride from width if not given */ if (rowstride == 0) - rowstride = width * _cogl_pixel_format_get_bytes_per_pixel (format); + rowstride = width * cogl_pixel_format_get_bytes_per_pixel (format, 0); /* Wrap the data into a bitmap */ bmp = cogl_bitmap_new_for_data (ctx, @@ -243,19 +242,20 @@ cogl_egl_texture_2d_new_from_image (CoglContext *ctx, int height, CoglPixelFormat format, EGLImageKHR image, - CoglError **error) + CoglEglImageFlags flags, + GError **error) { CoglTextureLoader *loader; CoglTexture2D *tex; - _COGL_RETURN_VAL_IF_FAIL (_cogl_context_get_winsys (ctx)->constraints & - COGL_RENDERER_CONSTRAINT_USES_EGL, - NULL); + g_return_val_if_fail (_cogl_context_get_winsys (ctx)->constraints & + COGL_RENDERER_CONSTRAINT_USES_EGL, + NULL); - _COGL_RETURN_VAL_IF_FAIL (_cogl_has_private_feature - (ctx, - COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE), - NULL); + g_return_val_if_fail (_cogl_has_private_feature + (ctx, + COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE), + NULL); loader = _cogl_texture_create_loader (); loader->src_type = COGL_TEXTURE_SOURCE_TYPE_EGL_IMAGE; @@ -263,6 +263,7 @@ cogl_egl_texture_2d_new_from_image (CoglContext *ctx, loader->src.egl_image.width = width; loader->src.egl_image.height = height; loader->src.egl_image.format = format; + loader->src.egl_image.flags = flags; tex = _cogl_texture_2d_create_base (ctx, width, height, format, loader); @@ -276,181 +277,6 @@ cogl_egl_texture_2d_new_from_image (CoglContext *ctx, } #endif /* defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base) */ -#ifdef COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT -static void -shm_buffer_get_cogl_pixel_format (struct wl_shm_buffer *shm_buffer, - CoglPixelFormat *format_out, - CoglTextureComponents *components_out) -{ - CoglPixelFormat format; - CoglTextureComponents components = COGL_TEXTURE_COMPONENTS_RGBA; - - switch (wl_shm_buffer_get_format (shm_buffer)) - { -#if G_BYTE_ORDER == G_BIG_ENDIAN - case WL_SHM_FORMAT_ARGB8888: - format = COGL_PIXEL_FORMAT_ARGB_8888_PRE; - break; - case WL_SHM_FORMAT_XRGB8888: - format = COGL_PIXEL_FORMAT_ARGB_8888; - components = COGL_TEXTURE_COMPONENTS_RGB; - break; -#elif G_BYTE_ORDER == G_LITTLE_ENDIAN - case WL_SHM_FORMAT_ARGB8888: - format = COGL_PIXEL_FORMAT_BGRA_8888_PRE; - break; - case WL_SHM_FORMAT_XRGB8888: - format = COGL_PIXEL_FORMAT_BGRA_8888; - components = COGL_TEXTURE_COMPONENTS_RGB; - break; -#endif - default: - g_warn_if_reached (); - format = COGL_PIXEL_FORMAT_ARGB_8888; - } - - if (format_out) - *format_out = format; - if (components_out) - *components_out = components; -} - -CoglBool -cogl_wayland_texture_set_region_from_shm_buffer (CoglTexture *texture, - int src_x, - int src_y, - int width, - int height, - struct wl_shm_buffer * - shm_buffer, - int dst_x, - int dst_y, - int level, - CoglError **error) -{ - const uint8_t *data = wl_shm_buffer_get_data (shm_buffer); - int32_t stride = wl_shm_buffer_get_stride (shm_buffer); - CoglPixelFormat format; - int bpp; - - shm_buffer_get_cogl_pixel_format (shm_buffer, &format, NULL); - bpp = _cogl_pixel_format_get_bytes_per_pixel (format); - - return _cogl_texture_set_region (COGL_TEXTURE (texture), - width, height, - format, - stride, - data + src_x * bpp + src_y * stride, - dst_x, dst_y, - level, - error); -} - -CoglTexture2D * -cogl_wayland_texture_2d_new_from_buffer (CoglContext *ctx, - struct wl_resource *buffer, - CoglError **error) -{ - struct wl_shm_buffer *shm_buffer; - CoglTexture2D *tex = NULL; - - shm_buffer = wl_shm_buffer_get (buffer); - - if (shm_buffer) - { - int stride = wl_shm_buffer_get_stride (shm_buffer); - int width = wl_shm_buffer_get_width (shm_buffer); - int height = wl_shm_buffer_get_height (shm_buffer); - CoglPixelFormat format; - CoglTextureComponents components; - CoglBitmap *bmp; - - shm_buffer_get_cogl_pixel_format (shm_buffer, &format, &components); - - bmp = cogl_bitmap_new_for_data (ctx, - width, height, - format, - stride, - wl_shm_buffer_get_data (shm_buffer)); - - tex = cogl_texture_2d_new_from_bitmap (bmp); - - cogl_texture_set_components (COGL_TEXTURE (tex), components); - - cogl_object_unref (bmp); - - if (!cogl_texture_allocate (COGL_TEXTURE (tex), error)) - { - cogl_object_unref (tex); - return NULL; - } - else - return tex; - } - else - { - int format, width, height; - - if (_cogl_egl_query_wayland_buffer (ctx, - buffer, - EGL_TEXTURE_FORMAT, - &format) && - _cogl_egl_query_wayland_buffer (ctx, - buffer, - EGL_WIDTH, - &width) && - _cogl_egl_query_wayland_buffer (ctx, - buffer, - EGL_HEIGHT, - &height)) - { - EGLImageKHR image; - CoglPixelFormat internal_format; - - _COGL_RETURN_VAL_IF_FAIL (_cogl_context_get_winsys (ctx)->constraints & - COGL_RENDERER_CONSTRAINT_USES_EGL, - NULL); - - switch (format) - { - case EGL_TEXTURE_RGB: - internal_format = COGL_PIXEL_FORMAT_RGB_888; - break; - case EGL_TEXTURE_RGBA: - internal_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE; - break; - default: - _cogl_set_error (error, - COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_UNSUPPORTED, - "Can't create texture from unknown " - "wayland buffer format %d\n", format); - return NULL; - } - - image = _cogl_egl_create_image (ctx, - EGL_WAYLAND_BUFFER_WL, - buffer, - NULL); - tex = cogl_egl_texture_2d_new_from_image (ctx, - width, height, - internal_format, - image, - error); - _cogl_egl_destroy_image (ctx, image); - return tex; - } - } - - _cogl_set_error (error, - COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_UNSUPPORTED, - "Can't create texture from unknown " - "wayland buffer type\n"); - return NULL; -} -#endif /* COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT */ - void _cogl_texture_2d_externally_modified (CoglTexture *texture) { @@ -496,23 +322,16 @@ _cogl_texture_2d_get_max_waste (CoglTexture *tex) return -1; } -static CoglBool +static gboolean _cogl_texture_2d_is_sliced (CoglTexture *tex) { return FALSE; } -static CoglBool +static gboolean _cogl_texture_2d_can_hardware_repeat (CoglTexture *tex) { - CoglContext *ctx = tex->context; - - if (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_REPEAT) || - (_cogl_util_is_pot (tex->width) && - _cogl_util_is_pot (tex->height))) - return TRUE; - else - return FALSE; + return TRUE; } static void @@ -546,7 +365,7 @@ _cogl_texture_2d_transform_quad_coords_to_gl (CoglTexture *tex, return COGL_TRANSFORM_NO_REPEAT; } -static CoglBool +static gboolean _cogl_texture_2d_get_gl_texture (CoglTexture *tex, GLuint *out_gl_handle, GLenum *out_gl_target) @@ -583,6 +402,11 @@ _cogl_texture_2d_pre_paint (CoglTexture *tex, CoglTexturePrePaintFlags flags) { CoglContext *ctx = tex->context; + /* Since we are about to ask the GPU to generate mipmaps of tex, we + * better make sure tex is up-to-date. + */ + _cogl_texture_flush_journal_rendering (tex); + ctx->driver_vtable->texture_2d_generate_mipmap (tex_2d); tex_2d->mipmaps_dirty = FALSE; @@ -595,7 +419,7 @@ _cogl_texture_2d_ensure_non_quad_rendering (CoglTexture *tex) /* Nothing needs to be done */ } -static CoglBool +static gboolean _cogl_texture_2d_set_region (CoglTexture *tex, int src_x, int src_y, @@ -605,7 +429,7 @@ _cogl_texture_2d_set_region (CoglTexture *tex, int height, int level, CoglBitmap *bmp, - CoglError **error) + GError **error) { CoglContext *ctx = tex->context; CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex); @@ -629,7 +453,16 @@ _cogl_texture_2d_set_region (CoglTexture *tex, return TRUE; } -static CoglBool +static gboolean +_cogl_texture_2d_is_get_data_supported (CoglTexture *tex) +{ + CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex); + CoglContext *ctx = tex->context; + + return ctx->driver_vtable->texture_2d_is_get_data_supported (tex_2d); +} + +static gboolean _cogl_texture_2d_get_data (CoglTexture *tex, CoglPixelFormat format, int rowstride, @@ -659,24 +492,13 @@ _cogl_texture_2d_get_gl_format (CoglTexture *tex) return COGL_TEXTURE_2D (tex)->gl_internal_format; } -static CoglBool -_cogl_texture_2d_is_foreign (CoglTexture *tex) -{ - return COGL_TEXTURE_2D (tex)->is_foreign; -} - -static CoglTextureType -_cogl_texture_2d_get_type (CoglTexture *tex) -{ - return COGL_TEXTURE_TYPE_2D; -} - static const CoglTextureVtable cogl_texture_2d_vtable = { TRUE, /* primitive */ _cogl_texture_2d_allocate, _cogl_texture_2d_set_region, + _cogl_texture_2d_is_get_data_supported, _cogl_texture_2d_get_data, NULL, /* foreach_sub_texture_in_region */ _cogl_texture_2d_get_max_waste, @@ -691,7 +513,5 @@ cogl_texture_2d_vtable = _cogl_texture_2d_gl_flush_legacy_texobj_wrap_modes, _cogl_texture_2d_get_format, _cogl_texture_2d_get_gl_format, - _cogl_texture_2d_get_type, - _cogl_texture_2d_is_foreign, _cogl_texture_2d_set_auto_mipmap }; diff --git a/cogl/cogl/cogl-texture-2d.h b/cogl/cogl/cogl-texture-2d.h index 405fb5f6a..9bee64692 100644 --- a/cogl/cogl/cogl-texture-2d.h +++ b/cogl/cogl/cogl-texture-2d.h @@ -44,7 +44,7 @@ #include "cogl-egl-defines.h" #endif -COGL_BEGIN_DECLS +G_BEGIN_DECLS /** * SECTION:cogl-texture-2d @@ -55,21 +55,23 @@ COGL_BEGIN_DECLS * made up of multiple 2D textures, or atlas textures where Cogl must * internally modify user texture coordinates before they can be used * by the GPU. - * - * You should be aware that many GPUs only support power of two sizes - * for #CoglTexture2D textures. You can check support for non power of - * two textures by checking for the %COGL_FEATURE_ID_TEXTURE_NPOT feature - * via cogl_has_feature(). */ typedef struct _CoglTexture2D CoglTexture2D; #define COGL_TEXTURE_2D(X) ((CoglTexture2D *)X) +typedef enum _CoglEglImageFlags +{ + COGL_EGL_IMAGE_FLAG_NONE = 0, + COGL_EGL_IMAGE_FLAG_NO_GET_DATA = 1 << 0, +} CoglEglImageFlags; + /** * cogl_texture_2d_get_gtype: * * Returns: a #GType that can be used with the GLib type system. */ +COGL_EXPORT GType cogl_texture_2d_get_gtype (void); /** @@ -82,11 +84,11 @@ GType cogl_texture_2d_get_gtype (void); * Return value: %TRUE if the object references a #CoglTexture2D, * %FALSE otherwise */ -CoglBool +COGL_EXPORT gboolean cogl_is_texture_2d (void *object); /** - * cogl_texture_2d_new_with_size: + * cogl_texture_2d_new_with_size: (skip) * @ctx: A #CoglContext * @width: Width of the texture to allocate * @height: Height of the texture to allocate @@ -105,25 +107,20 @@ cogl_is_texture_2d (void *object); * using cogl_texture_set_components() and * cogl_texture_set_premultiplied(). * - * Many GPUs only support power of two sizes for #CoglTexture2D - * textures. You can check support for non power of two textures by - * checking for the %COGL_FEATURE_ID_TEXTURE_NPOT feature via - * cogl_has_feature(). - * * Returns: (transfer full): A new #CoglTexture2D object with no storage yet allocated. * * Since: 2.0 */ -CoglTexture2D * +COGL_EXPORT CoglTexture2D * cogl_texture_2d_new_with_size (CoglContext *ctx, int width, int height); /** - * cogl_texture_2d_new_from_file: + * cogl_texture_2d_new_from_file: (skip) * @ctx: A #CoglContext * @filename: the file to load - * @error: A #CoglError to catch exceptional errors or %NULL + * @error: A #GError to catch exceptional errors or %NULL * * Creates a low-level #CoglTexture2D texture from an image file. * @@ -138,23 +135,18 @@ cogl_texture_2d_new_with_size (CoglContext *ctx, * using cogl_texture_set_components() and * cogl_texture_set_premultiplied(). * - * Many GPUs only support power of two sizes for #CoglTexture2D - * textures. You can check support for non power of two textures by - * checking for the %COGL_FEATURE_ID_TEXTURE_NPOT feature via - * cogl_has_feature(). - * * Return value: (transfer full): A newly created #CoglTexture2D or %NULL on failure * and @error will be updated. * * Since: 1.16 */ -CoglTexture2D * +COGL_EXPORT CoglTexture2D * cogl_texture_2d_new_from_file (CoglContext *ctx, const char *filename, - CoglError **error); + GError **error); /** - * cogl_texture_2d_new_from_data: + * cogl_texture_2d_new_from_data: (skip) * @ctx: A #CoglContext * @width: width of texture in pixels * @height: height of texture in pixels @@ -163,7 +155,7 @@ cogl_texture_2d_new_from_file (CoglContext *ctx, * scanlines in @data. A value of 0 will make Cogl automatically * calculate @rowstride from @width and @format. * @data: pointer the memory region where the source buffer resides - * @error: A #CoglError for exceptions + * @error: A #GError for exceptions * * Creates a low-level #CoglTexture2D texture based on data residing * in memory. @@ -179,11 +171,6 @@ cogl_texture_2d_new_from_file (CoglContext *ctx, * cogl_texture_2d_new_with_size() and then upload data using * cogl_texture_set_data() * - * Many GPUs only support power of two sizes for #CoglTexture2D - * textures. You can check support for non power of two textures by - * checking for the %COGL_FEATURE_ID_TEXTURE_NPOT feature via - * cogl_has_feature(). - * * Returns: (transfer full): A newly allocated #CoglTexture2D, or if * the size is not supported (because it is too large or a * non-power-of-two size that the hardware doesn't support) @@ -191,14 +178,14 @@ cogl_texture_2d_new_from_file (CoglContext *ctx, * * Since: 2.0 */ -CoglTexture2D * +COGL_EXPORT CoglTexture2D * cogl_texture_2d_new_from_data (CoglContext *ctx, int width, int height, CoglPixelFormat format, int rowstride, const uint8_t *data, - CoglError **error); + GError **error); /** * cogl_texture_2d_new_from_bitmap: @@ -218,53 +205,55 @@ cogl_texture_2d_new_from_data (CoglContext *ctx, * using cogl_texture_set_components() and * cogl_texture_set_premultiplied(). * - * Many GPUs only support power of two sizes for #CoglTexture2D - * textures. You can check support for non power of two textures by - * checking for the %COGL_FEATURE_ID_TEXTURE_NPOT feature via - * cogl_has_feature(). - * * Returns: (transfer full): A newly allocated #CoglTexture2D * * Since: 2.0 * Stability: unstable */ -CoglTexture2D * +COGL_EXPORT CoglTexture2D * cogl_texture_2d_new_from_bitmap (CoglBitmap *bitmap); +/** + * cogl_egl_texture_2d_new_from_image: (skip) + */ #if defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base) /* NB: The reason we require the width, height and format to be passed * even though they may seem redundant is because GLES 1/2 don't * provide a way to query these properties. */ -CoglTexture2D * +COGL_EXPORT CoglTexture2D * cogl_egl_texture_2d_new_from_image (CoglContext *ctx, int width, int height, CoglPixelFormat format, EGLImageKHR image, - CoglError **error); + CoglEglImageFlags flags, + GError **error); typedef gboolean (*CoglTexture2DEGLImageExternalAlloc) (CoglTexture2D *tex_2d, gpointer user_data, GError **error); -CoglTexture2D * +/** + * cogl_texture_2d_new_from_egl_image_external: (skip) + */ +COGL_EXPORT CoglTexture2D * cogl_texture_2d_new_from_egl_image_external (CoglContext *ctx, int width, int height, CoglTexture2DEGLImageExternalAlloc alloc, gpointer user_data, GDestroyNotify destroy, - CoglError **error); + GError **error); -void +COGL_EXPORT void cogl_texture_2d_egl_image_external_bind (CoglTexture2D *tex_2d); -void +COGL_EXPORT void cogl_texture_2d_egl_image_external_alloc_finish (CoglTexture2D *tex_2d, void *user_data, GDestroyNotify destroy); #endif -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_TEXTURE_2D_H */ diff --git a/cogl/cogl/cogl-texture-3d-private.h b/cogl/cogl/cogl-texture-3d-private.h deleted file mode 100644 index b6e0066d3..000000000 --- a/cogl/cogl/cogl-texture-3d-private.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Neil Roberts - */ - -#ifndef __COGL_TEXTURE_3D_PRIVATE_H -#define __COGL_TEXTURE_3D_PRIVATE_H - -#include "cogl-object-private.h" -#include "cogl-pipeline-private.h" -#include "cogl-texture-private.h" -#include "cogl-texture-3d.h" - -struct _CoglTexture3D -{ - CoglTexture _parent; - - /* The internal format of the texture represented as a - CoglPixelFormat */ - CoglPixelFormat internal_format; - int depth; - CoglBool auto_mipmap; - CoglBool mipmaps_dirty; - - /* TODO: factor out these OpenGL specific members into some form - * of driver private state. */ - - /* The internal format of the GL texture represented as a GL enum */ - GLenum gl_format; - /* The texture object number */ - GLuint gl_texture; - GLenum gl_legacy_texobj_min_filter; - GLenum gl_legacy_texobj_mag_filter; - GLint gl_legacy_texobj_wrap_mode_s; - GLint gl_legacy_texobj_wrap_mode_t; - GLint gl_legacy_texobj_wrap_mode_p; - CoglTexturePixel first_pixel; -}; - -#endif /* __COGL_TEXTURE_3D_PRIVATE_H */ diff --git a/cogl/cogl/cogl-texture-3d.c b/cogl/cogl/cogl-texture-3d.c deleted file mode 100644 index 5644119d7..000000000 --- a/cogl/cogl/cogl-texture-3d.c +++ /dev/null @@ -1,759 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Neil Roberts - */ - -#ifdef HAVE_CONFIG_H -#include "cogl-config.h" -#endif - -#include "cogl-private.h" -#include "cogl-util.h" -#include "cogl-texture-private.h" -#include "cogl-texture-3d-private.h" -#include "cogl-texture-3d.h" -#include "cogl-texture-gl-private.h" -#include "cogl-texture-driver.h" -#include "cogl-context-private.h" -#include "cogl-object-private.h" -#include "cogl-journal-private.h" -#include "cogl-pipeline-private.h" -#include "cogl-pipeline-opengl-private.h" -#include "cogl-error-private.h" -#include "cogl-util-gl-private.h" -#include "cogl-gtype-private.h" - -#include -#include - -/* These might not be defined on GLES */ -#ifndef GL_TEXTURE_3D -#define GL_TEXTURE_3D 0x806F -#endif -#ifndef GL_TEXTURE_WRAP_R -#define GL_TEXTURE_WRAP_R 0x8072 -#endif - -static void _cogl_texture_3d_free (CoglTexture3D *tex_3d); - -COGL_TEXTURE_DEFINE (Texture3D, texture_3d); -COGL_GTYPE_DEFINE_CLASS (Texture3D, texture_3d, - COGL_GTYPE_IMPLEMENT_INTERFACE (texture)); - -static const CoglTextureVtable cogl_texture_3d_vtable; - -static void -_cogl_texture_3d_gl_flush_legacy_texobj_wrap_modes (CoglTexture *tex, - GLenum wrap_mode_s, - GLenum wrap_mode_t, - GLenum wrap_mode_p) -{ - CoglTexture3D *tex_3d = COGL_TEXTURE_3D (tex); - CoglContext *ctx = tex->context; - - /* Only set the wrap mode if it's different from the current value - to avoid too many GL calls. */ - if (tex_3d->gl_legacy_texobj_wrap_mode_s != wrap_mode_s || - tex_3d->gl_legacy_texobj_wrap_mode_t != wrap_mode_t || - tex_3d->gl_legacy_texobj_wrap_mode_p != wrap_mode_p) - { - _cogl_bind_gl_texture_transient (GL_TEXTURE_3D, - tex_3d->gl_texture, - FALSE); - GE( ctx, glTexParameteri (GL_TEXTURE_3D, - GL_TEXTURE_WRAP_S, - wrap_mode_s) ); - GE( ctx, glTexParameteri (GL_TEXTURE_3D, - GL_TEXTURE_WRAP_T, - wrap_mode_t) ); - GE( ctx, glTexParameteri (GL_TEXTURE_3D, - GL_TEXTURE_WRAP_R, - wrap_mode_p) ); - - tex_3d->gl_legacy_texobj_wrap_mode_s = wrap_mode_s; - tex_3d->gl_legacy_texobj_wrap_mode_t = wrap_mode_t; - tex_3d->gl_legacy_texobj_wrap_mode_p = wrap_mode_p; - } -} - -static void -_cogl_texture_3d_free (CoglTexture3D *tex_3d) -{ - if (tex_3d->gl_texture) - _cogl_delete_gl_texture (tex_3d->gl_texture); - - /* Chain up */ - _cogl_texture_free (COGL_TEXTURE (tex_3d)); -} - -static void -_cogl_texture_3d_set_auto_mipmap (CoglTexture *tex, - CoglBool value) -{ - CoglTexture3D *tex_3d = COGL_TEXTURE_3D (tex); - - tex_3d->auto_mipmap = value; -} - -static CoglTexture3D * -_cogl_texture_3d_create_base (CoglContext *ctx, - int width, - int height, - int depth, - CoglPixelFormat internal_format, - CoglTextureLoader *loader) -{ - CoglTexture3D *tex_3d = g_new (CoglTexture3D, 1); - CoglTexture *tex = COGL_TEXTURE (tex_3d); - - _cogl_texture_init (tex, ctx, width, height, - internal_format, loader, &cogl_texture_3d_vtable); - - tex_3d->gl_texture = 0; - - tex_3d->depth = depth; - tex_3d->mipmaps_dirty = TRUE; - tex_3d->auto_mipmap = TRUE; - - /* We default to GL_LINEAR for both filters */ - tex_3d->gl_legacy_texobj_min_filter = GL_LINEAR; - tex_3d->gl_legacy_texobj_mag_filter = GL_LINEAR; - - /* Wrap mode not yet set */ - tex_3d->gl_legacy_texobj_wrap_mode_s = GL_FALSE; - tex_3d->gl_legacy_texobj_wrap_mode_t = GL_FALSE; - tex_3d->gl_legacy_texobj_wrap_mode_p = GL_FALSE; - - return _cogl_texture_3d_object_new (tex_3d); -} - -CoglTexture3D * -cogl_texture_3d_new_with_size (CoglContext *ctx, - int width, - int height, - int depth) -{ - CoglTextureLoader *loader = _cogl_texture_create_loader (); - loader->src_type = COGL_TEXTURE_SOURCE_TYPE_SIZED; - loader->src.sized.width = width; - loader->src.sized.height = height; - loader->src.sized.depth = depth; - - return _cogl_texture_3d_create_base (ctx, width, height, depth, - COGL_PIXEL_FORMAT_RGBA_8888_PRE, - loader); -} - -CoglTexture3D * -cogl_texture_3d_new_from_bitmap (CoglBitmap *bmp, - int height, - int depth) -{ - CoglTextureLoader *loader; - - _COGL_RETURN_VAL_IF_FAIL (bmp, NULL); - - loader = _cogl_texture_create_loader (); - loader->src_type = COGL_TEXTURE_SOURCE_TYPE_BITMAP; - loader->src.bitmap.bitmap = cogl_object_ref (bmp); - loader->src.bitmap.height = height; - loader->src.bitmap.depth = depth; - loader->src.bitmap.can_convert_in_place = FALSE; /* TODO add api for this */ - - return _cogl_texture_3d_create_base (_cogl_bitmap_get_context (bmp), - cogl_bitmap_get_width (bmp), - height, - depth, - cogl_bitmap_get_format (bmp), - loader); -} - -CoglTexture3D * -cogl_texture_3d_new_from_data (CoglContext *context, - int width, - int height, - int depth, - CoglPixelFormat format, - int rowstride, - int image_stride, - const uint8_t *data, - CoglError **error) -{ - CoglBitmap *bitmap; - CoglTexture3D *ret; - - _COGL_RETURN_VAL_IF_FAIL (data, NULL); - _COGL_RETURN_VAL_IF_FAIL (format != COGL_PIXEL_FORMAT_ANY, NULL); - - /* Rowstride from width if not given */ - if (rowstride == 0) - rowstride = width * _cogl_pixel_format_get_bytes_per_pixel (format); - /* Image stride from height and rowstride if not given */ - if (image_stride == 0) - image_stride = height * rowstride; - - if (image_stride < rowstride * height) - return NULL; - - /* GL doesn't support uploading when the image_stride isn't a - multiple of the rowstride. If this happens we'll just pack the - image into a new bitmap. The documentation for this function - recommends avoiding this situation. */ - if (image_stride % rowstride != 0) - { - uint8_t *bmp_data; - int bmp_rowstride; - int z, y; - - bitmap = _cogl_bitmap_new_with_malloc_buffer (context, - width, - depth * height, - format, - error); - if (!bitmap) - return NULL; - - bmp_data = _cogl_bitmap_map (bitmap, - COGL_BUFFER_ACCESS_WRITE, - COGL_BUFFER_MAP_HINT_DISCARD, - error); - - if (bmp_data == NULL) - { - cogl_object_unref (bitmap); - return NULL; - } - - bmp_rowstride = cogl_bitmap_get_rowstride (bitmap); - - /* Copy all of the images in */ - for (z = 0; z < depth; z++) - for (y = 0; y < height; y++) - memcpy (bmp_data + (z * bmp_rowstride * height + - bmp_rowstride * y), - data + z * image_stride + rowstride * y, - bmp_rowstride); - - _cogl_bitmap_unmap (bitmap); - } - else - bitmap = cogl_bitmap_new_for_data (context, - width, - image_stride / rowstride * depth, - format, - rowstride, - (uint8_t *) data); - - ret = cogl_texture_3d_new_from_bitmap (bitmap, - height, - depth); - - cogl_object_unref (bitmap); - - if (ret && - !cogl_texture_allocate (COGL_TEXTURE (ret), error)) - { - cogl_object_unref (ret); - return NULL; - } - - return ret; -} - -static CoglBool -_cogl_texture_3d_can_create (CoglContext *ctx, - int width, - int height, - int depth, - CoglPixelFormat internal_format, - CoglError **error) -{ - GLenum gl_intformat; - GLenum gl_type; - - /* This should only happen on GLES */ - if (!cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_3D)) - { - _cogl_set_error (error, - COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_UNSUPPORTED, - "3D textures are not supported by the GPU"); - return FALSE; - } - - /* If NPOT textures aren't supported then the size must be a power - of two */ - if (!cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT) && - (!_cogl_util_is_pot (width) || - !_cogl_util_is_pot (height) || - !_cogl_util_is_pot (depth))) - { - _cogl_set_error (error, - COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_UNSUPPORTED, - "A non-power-of-two size was requested but this is not " - "supported by the GPU"); - return FALSE; - } - - ctx->driver_vtable->pixel_format_to_gl (ctx, - internal_format, - &gl_intformat, - NULL, - &gl_type); - - /* Check that the driver can create a texture with that size */ - if (!ctx->texture_driver->size_supported_3d (ctx, - GL_TEXTURE_3D, - gl_intformat, - gl_type, - width, - height, - depth)) - { - _cogl_set_error (error, - COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_UNSUPPORTED, - "The requested dimensions are not supported by the GPU"); - return FALSE; - } - - return TRUE; -} - -static CoglBool -allocate_with_size (CoglTexture3D *tex_3d, - CoglTextureLoader *loader, - CoglError **error) -{ - CoglTexture *tex = COGL_TEXTURE (tex_3d); - CoglContext *ctx = tex->context; - CoglPixelFormat internal_format; - int width = loader->src.sized.width; - int height = loader->src.sized.height; - int depth = loader->src.sized.depth; - GLenum gl_intformat; - GLenum gl_format; - GLenum gl_type; - GLenum gl_texture; - - internal_format = - _cogl_texture_determine_internal_format (tex, COGL_PIXEL_FORMAT_ANY); - - if (!_cogl_texture_3d_can_create (ctx, - width, - height, - depth, - internal_format, - error)) - return FALSE; - - ctx->driver_vtable->pixel_format_to_gl (ctx, - internal_format, - &gl_intformat, - &gl_format, - &gl_type); - - gl_texture = - ctx->texture_driver->gen (ctx, GL_TEXTURE_3D, internal_format); - _cogl_bind_gl_texture_transient (GL_TEXTURE_3D, - gl_texture, - FALSE); - /* Clear any GL errors */ - _cogl_gl_util_clear_gl_errors (ctx); - - ctx->glTexImage3D (GL_TEXTURE_3D, 0, gl_intformat, - width, height, depth, - 0, gl_format, gl_type, NULL); - - if (_cogl_gl_util_catch_out_of_memory (ctx, error)) - { - GE( ctx, glDeleteTextures (1, &gl_texture) ); - return FALSE; - } - - tex_3d->gl_texture = gl_texture; - tex_3d->gl_format = gl_intformat; - - tex_3d->depth = depth; - - tex_3d->internal_format = internal_format; - - _cogl_texture_set_allocated (tex, internal_format, width, height); - - return TRUE; -} - -static CoglBool -allocate_from_bitmap (CoglTexture3D *tex_3d, - CoglTextureLoader *loader, - CoglError **error) -{ - CoglTexture *tex = COGL_TEXTURE (tex_3d); - CoglContext *ctx = tex->context; - CoglPixelFormat internal_format; - CoglBitmap *bmp = loader->src.bitmap.bitmap; - int bmp_width = cogl_bitmap_get_width (bmp); - int height = loader->src.bitmap.height; - int depth = loader->src.bitmap.depth; - CoglPixelFormat bmp_format = cogl_bitmap_get_format (bmp); - CoglBool can_convert_in_place = loader->src.bitmap.can_convert_in_place; - CoglBitmap *upload_bmp; - CoglPixelFormat upload_format; - GLenum gl_intformat; - GLenum gl_format; - GLenum gl_type; - - internal_format = _cogl_texture_determine_internal_format (tex, bmp_format); - - if (!_cogl_texture_3d_can_create (ctx, - bmp_width, height, depth, - internal_format, - error)) - return FALSE; - - upload_bmp = _cogl_bitmap_convert_for_upload (bmp, - internal_format, - can_convert_in_place, - error); - if (upload_bmp == NULL) - return FALSE; - - upload_format = cogl_bitmap_get_format (upload_bmp); - - ctx->driver_vtable->pixel_format_to_gl (ctx, - upload_format, - NULL, /* internal format */ - &gl_format, - &gl_type); - ctx->driver_vtable->pixel_format_to_gl (ctx, - internal_format, - &gl_intformat, - NULL, - NULL); - - /* Keep a copy of the first pixel so that if glGenerateMipmap isn't - supported we can fallback to using GL_GENERATE_MIPMAP */ - if (!cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN)) - { - CoglError *ignore = NULL; - uint8_t *data = _cogl_bitmap_map (upload_bmp, - COGL_BUFFER_ACCESS_READ, 0, - &ignore); - - tex_3d->first_pixel.gl_format = gl_format; - tex_3d->first_pixel.gl_type = gl_type; - - if (data) - { - memcpy (tex_3d->first_pixel.data, data, - _cogl_pixel_format_get_bytes_per_pixel (upload_format)); - _cogl_bitmap_unmap (upload_bmp); - } - else - { - g_warning ("Failed to read first pixel of bitmap for " - "glGenerateMipmap fallback"); - cogl_error_free (ignore); - memset (tex_3d->first_pixel.data, 0, - _cogl_pixel_format_get_bytes_per_pixel (upload_format)); - } - } - - tex_3d->gl_texture = - ctx->texture_driver->gen (ctx, GL_TEXTURE_3D, internal_format); - - if (!ctx->texture_driver->upload_to_gl_3d (ctx, - GL_TEXTURE_3D, - tex_3d->gl_texture, - FALSE, /* is_foreign */ - height, - depth, - upload_bmp, - gl_intformat, - gl_format, - gl_type, - error)) - { - cogl_object_unref (upload_bmp); - return FALSE; - } - - tex_3d->gl_format = gl_intformat; - - cogl_object_unref (upload_bmp); - - tex_3d->depth = loader->src.bitmap.depth; - - tex_3d->internal_format = internal_format; - - _cogl_texture_set_allocated (tex, internal_format, - bmp_width, loader->src.bitmap.height); - - return TRUE; -} - -static CoglBool -_cogl_texture_3d_allocate (CoglTexture *tex, - CoglError **error) -{ - CoglTexture3D *tex_3d = COGL_TEXTURE_3D (tex); - CoglTextureLoader *loader = tex->loader; - - _COGL_RETURN_VAL_IF_FAIL (loader, FALSE); - - switch (loader->src_type) - { - case COGL_TEXTURE_SOURCE_TYPE_SIZED: - return allocate_with_size (tex_3d, loader, error); - case COGL_TEXTURE_SOURCE_TYPE_BITMAP: - return allocate_from_bitmap (tex_3d, loader, error); - default: - break; - } - - g_return_val_if_reached (FALSE); -} - -static int -_cogl_texture_3d_get_max_waste (CoglTexture *tex) -{ - return -1; -} - -static CoglBool -_cogl_texture_3d_is_sliced (CoglTexture *tex) -{ - return FALSE; -} - -static CoglBool -_cogl_texture_3d_can_hardware_repeat (CoglTexture *tex) -{ - return TRUE; -} - -static void -_cogl_texture_3d_transform_coords_to_gl (CoglTexture *tex, - float *s, - float *t) -{ - /* The texture coordinates map directly so we don't need to do - anything */ -} - -static CoglTransformResult -_cogl_texture_3d_transform_quad_coords_to_gl (CoglTexture *tex, - float *coords) -{ - /* The texture coordinates map directly so we don't need to do - anything other than check for repeats */ - - CoglBool need_repeat = FALSE; - int i; - - for (i = 0; i < 4; i++) - if (coords[i] < 0.0f || coords[i] > 1.0f) - need_repeat = TRUE; - - return (need_repeat ? COGL_TRANSFORM_HARDWARE_REPEAT - : COGL_TRANSFORM_NO_REPEAT); -} - -static CoglBool -_cogl_texture_3d_get_gl_texture (CoglTexture *tex, - GLuint *out_gl_handle, - GLenum *out_gl_target) -{ - CoglTexture3D *tex_3d = COGL_TEXTURE_3D (tex); - - if (out_gl_handle) - *out_gl_handle = tex_3d->gl_texture; - - if (out_gl_target) - *out_gl_target = GL_TEXTURE_3D; - - return TRUE; -} - -static void -_cogl_texture_3d_gl_flush_legacy_texobj_filters (CoglTexture *tex, - GLenum min_filter, - GLenum mag_filter) -{ - CoglTexture3D *tex_3d = COGL_TEXTURE_3D (tex); - CoglContext *ctx = tex->context; - - if (min_filter == tex_3d->gl_legacy_texobj_min_filter - && mag_filter == tex_3d->gl_legacy_texobj_mag_filter) - return; - - /* Store new values */ - tex_3d->gl_legacy_texobj_min_filter = min_filter; - tex_3d->gl_legacy_texobj_mag_filter = mag_filter; - - /* Apply new filters to the texture */ - _cogl_bind_gl_texture_transient (GL_TEXTURE_3D, - tex_3d->gl_texture, - FALSE); - GE( ctx, glTexParameteri (GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, mag_filter) ); - GE( ctx, glTexParameteri (GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, min_filter) ); -} - -static void -_cogl_texture_3d_pre_paint (CoglTexture *tex, CoglTexturePrePaintFlags flags) -{ - CoglTexture3D *tex_3d = COGL_TEXTURE_3D (tex); - CoglContext *ctx = tex->context; - - /* Only update if the mipmaps are dirty */ - if ((flags & COGL_TEXTURE_NEEDS_MIPMAP) && - tex_3d->auto_mipmap && tex_3d->mipmaps_dirty) - { - /* glGenerateMipmap is defined in the FBO extension. If it's not - available we'll fallback to temporarily enabling - GL_GENERATE_MIPMAP and reuploading the first pixel */ - if (cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN)) - _cogl_texture_gl_generate_mipmaps (tex); -#if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES) - else if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_FIXED)) - { - _cogl_bind_gl_texture_transient (GL_TEXTURE_3D, - tex_3d->gl_texture, - FALSE); - - GE( ctx, glTexParameteri (GL_TEXTURE_3D, - GL_GENERATE_MIPMAP, - GL_TRUE) ); - GE( ctx, glTexSubImage3D (GL_TEXTURE_3D, - 0, /* level */ - 0, /* xoffset */ - 0, /* yoffset */ - 0, /* zoffset */ - 1, /* width */ - 1, /* height */ - 1, /* depth */ - tex_3d->first_pixel.gl_format, - tex_3d->first_pixel.gl_type, - tex_3d->first_pixel.data) ); - GE( ctx, glTexParameteri (GL_TEXTURE_3D, - GL_GENERATE_MIPMAP, - GL_FALSE) ); - } -#endif - - tex_3d->mipmaps_dirty = FALSE; - } -} - -static void -_cogl_texture_3d_ensure_non_quad_rendering (CoglTexture *tex) -{ - /* Nothing needs to be done */ -} - -static CoglBool -_cogl_texture_3d_set_region (CoglTexture *tex, - int src_x, - int src_y, - int dst_x, - int dst_y, - int dst_width, - int dst_height, - int level, - CoglBitmap *bmp, - CoglError **error) -{ - /* This function doesn't really make sense for 3D textures because - it can't specify which image to upload to */ - _cogl_set_error (error, - COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_UNSUPPORTED, - "Setting a 2D region on a 3D texture isn't " - "currently supported"); - - return FALSE; -} - -static int -_cogl_texture_3d_get_data (CoglTexture *tex, - CoglPixelFormat format, - int rowstride, - uint8_t *data) -{ - /* FIXME: we could probably implement this by assuming the data is - big enough to hold all of the images and that there is no stride - between the images. However it would be better to have an API - that can provide an image stride and this function probably isn't - particularly useful anyway so for now it just reports failure */ - return 0; -} - -static CoglPixelFormat -_cogl_texture_3d_get_format (CoglTexture *tex) -{ - return COGL_TEXTURE_3D (tex)->internal_format; -} - -static GLenum -_cogl_texture_3d_get_gl_format (CoglTexture *tex) -{ - return COGL_TEXTURE_3D (tex)->gl_format; -} - -static CoglTextureType -_cogl_texture_3d_get_type (CoglTexture *tex) -{ - return COGL_TEXTURE_TYPE_3D; -} - -static const CoglTextureVtable -cogl_texture_3d_vtable = - { - TRUE, /* primitive */ - _cogl_texture_3d_allocate, - _cogl_texture_3d_set_region, - _cogl_texture_3d_get_data, - NULL, /* foreach_sub_texture_in_region */ - _cogl_texture_3d_get_max_waste, - _cogl_texture_3d_is_sliced, - _cogl_texture_3d_can_hardware_repeat, - _cogl_texture_3d_transform_coords_to_gl, - _cogl_texture_3d_transform_quad_coords_to_gl, - _cogl_texture_3d_get_gl_texture, - _cogl_texture_3d_gl_flush_legacy_texobj_filters, - _cogl_texture_3d_pre_paint, - _cogl_texture_3d_ensure_non_quad_rendering, - _cogl_texture_3d_gl_flush_legacy_texobj_wrap_modes, - _cogl_texture_3d_get_format, - _cogl_texture_3d_get_gl_format, - _cogl_texture_3d_get_type, - NULL, /* is_foreign */ - _cogl_texture_3d_set_auto_mipmap - }; diff --git a/cogl/cogl/cogl-texture-3d.h b/cogl/cogl/cogl-texture-3d.h deleted file mode 100644 index 238adfe24..000000000 --- a/cogl/cogl/cogl-texture-3d.h +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Neil Roberts - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL_TEXTURE_3D_H -#define __COGL_TEXTURE_3D_H - -COGL_BEGIN_DECLS - -/** - * SECTION:cogl-texture-3d - * @short_description: Functions for creating and manipulating 3D textures - * - * These functions allow 3D textures to be used. 3D textures can be - * thought of as layers of 2D images arranged into a cuboid - * shape. When choosing a texel from the texture, Cogl will take into - * account the 'r' texture coordinate to select one of the images. - */ - -typedef struct _CoglTexture3D CoglTexture3D; - -#define COGL_TEXTURE_3D(X) ((CoglTexture3D *)X) - -/** - * cogl_texture_3d_get_gtype: - * - * Returns: a #GType that can be used with the GLib type system. - */ -GType cogl_texture_3d_get_gtype (void); - -/** - * cogl_texture_3d_new_with_size: - * @context: a #CoglContext - * @width: width of the texture in pixels. - * @height: height of the texture in pixels. - * @depth: depth of the texture in pixels. - * - * Creates a low-level #CoglTexture3D texture with the specified - * dimensions and pixel format. - * - * The storage for the texture is not allocated before this function - * returns. You can call cogl_texture_allocate() to explicitly - * allocate the underlying storage or preferably let Cogl - * automatically allocate storage lazily when it may know more about - * how the texture is going to be used and can optimize how it is - * allocated. - * - * The texture is still configurable until it has been allocated so - * for example you can influence the internal format of the texture - * using cogl_texture_set_components() and - * cogl_texture_set_premultiplied(). - * - * This texture will fail to allocate later if - * %COGL_FEATURE_ID_TEXTURE_3D is not advertised. Allocation can also - * fail if the requested dimensions are not supported by the - * GPU. - * - * Returns: (transfer full): A new #CoglTexture3D object with no storage yet allocated. - * Since: 1.10 - * Stability: Unstable - */ -CoglTexture3D * -cogl_texture_3d_new_with_size (CoglContext *context, - int width, - int height, - int depth); - -/** - * cogl_texture_3d_new_from_data: - * @context: a #CoglContext - * @width: width of the texture in pixels. - * @height: height of the texture in pixels. - * @depth: depth of the texture in pixels. - * @format: the #CoglPixelFormat the buffer is stored in in RAM - * @rowstride: the memory offset in bytes between the starts of - * scanlines in @data or 0 to infer it from the width and format - * @image_stride: the number of bytes from one image to the next. This - * can be used to add padding between the images in a similar way - * that the rowstride can be used to add padding between - * rows. Alternatively 0 can be passed to infer the @image_stride - * from the @height. - * @data: pointer the memory region where the source buffer resides - * @error: A CoglError return location. - * - * Creates a low-level 3D texture and initializes it with @data. The - * data is assumed to be packed array of @depth images. There can be - * padding between the images using @image_stride. - * - * This api will always immediately allocate GPU memory for the - * texture and upload the given data so that the @data pointer does - * not need to remain valid once this function returns. This means it - * is not possible to configure the texture before it is allocated. If - * you do need to configure the texture before allocation (to specify - * constraints on the internal format for example) then you can - * instead create a #CoglBitmap for your data and use - * cogl_texture_3d_new_from_bitmap(). - * - * Return value: (transfer full): the newly created #CoglTexture3D or - * %NULL if there was an error and an exception will be - * returned through @error. - * Since: 1.10 - * Stability: Unstable - */ -CoglTexture3D * -cogl_texture_3d_new_from_data (CoglContext *context, - int width, - int height, - int depth, - CoglPixelFormat format, - int rowstride, - int image_stride, - const uint8_t *data, - CoglError **error); - -/** - * cogl_texture_3d_new_from_bitmap: - * @bitmap: A #CoglBitmap object. - * @height: height of the texture in pixels. - * @depth: depth of the texture in pixels. - * - * Creates a low-level 3D texture and initializes it with the images - * in @bitmap. The images are assumed to be packed together after one - * another in the increasing y axis. The height of individual image is - * given as @height and the number of images is given in @depth. The - * actual height of the bitmap can be larger than @height × @depth. In - * this case it assumes there is padding between the images. - * - * The storage for the texture is not allocated before this function - * returns. You can call cogl_texture_allocate() to explicitly - * allocate the underlying storage or preferably let Cogl - * automatically allocate storage lazily when it may know more about - * how the texture is going to be used and can optimize how it is - * allocated. - * - * The texture is still configurable until it has been allocated so - * for example you can influence the internal format of the texture - * using cogl_texture_set_components() and - * cogl_texture_set_premultiplied(). - * - * This texture will fail to allocate later if - * %COGL_FEATURE_ID_TEXTURE_3D is not advertised. Allocation can also - * fail if the requested dimensions are not supported by the - * GPU. - * - * Return value: (transfer full): a newly created #CoglTexture3D - * Since: 2.0 - * Stability: unstable - */ -CoglTexture3D * -cogl_texture_3d_new_from_bitmap (CoglBitmap *bitmap, - int height, - int depth); - -/** - * cogl_is_texture_3d: - * @object: a #CoglObject - * - * Checks whether the given object references a #CoglTexture3D - * - * Return value: %TRUE if the passed object represents a 3D texture - * and %FALSE otherwise - * - * Since: 1.4 - * Stability: Unstable - */ -CoglBool -cogl_is_texture_3d (void *object); - -COGL_END_DECLS - -#endif /* __COGL_TEXTURE_3D_H */ diff --git a/cogl/cogl/cogl-texture-driver.h b/cogl/cogl/cogl-texture-driver.h index e548605db..240635f49 100644 --- a/cogl/cogl/cogl-texture-driver.h +++ b/cogl/cogl/cogl-texture-driver.h @@ -45,18 +45,6 @@ struct _CoglTextureDriver GLenum gl_target, CoglPixelFormat internal_format); - /* - * This sets up the glPixelStore state for an upload to a destination with - * the same size, and with no offset. - */ - /* NB: GLES can't upload a sub region of pixel data from a larger source - * buffer which is why this interface is limited. The GL driver has a more - * flexible version of this function that is uses internally */ - void - (* prep_gl_for_pixels_upload) (CoglContext *ctx, - int pixels_rowstride, - int pixels_bpp); - /* * This uploads a sub-region from source_bmp to a single GL texture * handle (i.e a single CoglTexture slice) @@ -70,10 +58,9 @@ struct _CoglTextureDriver * * XXX: sorry for the ridiculous number of arguments :-( */ - CoglBool + gboolean (* upload_subregion_to_gl) (CoglContext *ctx, CoglTexture *texture, - CoglBool is_foreign, int src_x, int src_y, int dst_x, @@ -84,7 +71,7 @@ struct _CoglTextureDriver CoglBitmap *source_bmp, GLuint source_gl_format, GLuint source_gl_type, - CoglError **error); + GError **error); /* * Replaces the contents of the GL texture with the entire bitmap. On @@ -92,36 +79,15 @@ struct _CoglTextureDriver * to copy the bitmap if the rowstride is not a multiple of a possible * alignment value because there is no GL_UNPACK_ROW_LENGTH */ - CoglBool + gboolean (* upload_to_gl) (CoglContext *ctx, GLenum gl_target, GLuint gl_handle, - CoglBool is_foreign, CoglBitmap *source_bmp, GLint internal_gl_format, GLuint source_gl_format, GLuint source_gl_type, - CoglError **error); - - /* - * Replaces the contents of the GL texture with the entire bitmap. The - * width of the texture is inferred from the bitmap. The height and - * depth of the texture is given directly. The 'image_height' (which - * is the number of rows between images) is inferred by dividing the - * height of the bitmap by the depth. - */ - CoglBool - (* upload_to_gl_3d) (CoglContext *ctx, - GLenum gl_target, - GLuint gl_handle, - CoglBool is_foreign, - GLint height, - GLint depth, - CoglBitmap *source_bmp, - GLint internal_gl_format, - GLuint source_gl_format, - GLuint source_gl_type, - CoglError **error); + GError **error); /* * This sets up the glPixelStore state for an download to a destination with @@ -143,7 +109,7 @@ struct _CoglTextureDriver * renders the texture and reads it back from the framebuffer. (See * _cogl_texture_draw_and_read () ) */ - CoglBool + gboolean (* gl_get_tex_image) (CoglContext *ctx, GLenum gl_target, GLenum dest_gl_format, @@ -153,7 +119,7 @@ struct _CoglTextureDriver /* * It may depend on the driver as to what texture sizes are supported... */ - CoglBool + gboolean (* size_supported) (CoglContext *ctx, GLenum gl_target, GLenum gl_intformat, @@ -162,33 +128,6 @@ struct _CoglTextureDriver int width, int height); - CoglBool - (* size_supported_3d) (CoglContext *ctx, - GLenum gl_target, - GLenum gl_format, - GLenum gl_type, - int width, - int height, - int depth); - - /* - * This driver abstraction is needed because GLES doesn't support setting - * a texture border color. - */ - void - (* try_setting_gl_border_color) (CoglContext *ctx, - GLuint gl_target, - const GLfloat *transparent_color); - - /* - * It may depend on the driver as to what texture targets may be used when - * creating a foreign texture. E.g. OpenGL supports ARB_texture_rectangle - * but GLES doesn't - */ - CoglBool - (* allows_foreign_gl_target) (CoglContext *ctx, - GLenum gl_target); - /* * The driver may impose constraints on what formats can be used to store * texture data read from textures. For example GLES currently only supports @@ -198,7 +137,6 @@ struct _CoglTextureDriver CoglPixelFormat (* find_best_gl_get_data_format) (CoglContext *context, CoglPixelFormat format, - CoglPixelFormat target_format, GLenum *closest_gl_format, GLenum *closest_gl_type); }; diff --git a/cogl/cogl/cogl-texture-private.h b/cogl/cogl/cogl-texture-private.h index 742983e2d..d20de6bce 100644 --- a/cogl/cogl/cogl-texture-private.h +++ b/cogl/cogl/cogl-texture-private.h @@ -46,7 +46,8 @@ typedef struct _CoglTextureVtable CoglTextureVtable; /* Encodes three possibiloities result of transforming a quad */ -typedef enum { +typedef enum +{ /* quad doesn't cross the boundaries of a texture */ COGL_TRANSFORM_NO_REPEAT, /* quad crosses boundaries, hardware wrap mode can handle */ @@ -58,7 +59,8 @@ typedef enum { } CoglTransformResult; /* Flags given to the pre_paint method */ -typedef enum { +typedef enum +{ /* The texture is going to be used with filters that require mipmapping. This gives the texture the opportunity to automatically update the mipmap tree */ @@ -70,17 +72,17 @@ struct _CoglTextureVtable /* Virtual functions that must be implemented for a texture backend */ - CoglBool is_primitive; + gboolean is_primitive; - CoglBool (* allocate) (CoglTexture *tex, - CoglError **error); + gboolean (* allocate) (CoglTexture *tex, + GError **error); /* This should update the specified sub region of the texture with a sub region of the given bitmap. The bitmap is not converted before being set so the caller is expected to have called _cogl_bitmap_convert_for_upload with a suitable internal_format before passing here */ - CoglBool (* set_region) (CoglTexture *tex, + gboolean (* set_region) (CoglTexture *tex, int src_x, int src_y, int dst_x, @@ -89,14 +91,16 @@ struct _CoglTextureVtable int dst_height, int level, CoglBitmap *bitmap, - CoglError **error); + GError **error); + + gboolean (* is_get_data_supported) (CoglTexture *texture); /* This should copy the image data of the texture into @data. The requested format will have been first passed through ctx->texture_driver->find_best_gl_get_data_format so it should always be a format that is valid for GL (ie, no conversion should be necessary). */ - CoglBool (* get_data) (CoglTexture *tex, + gboolean (* get_data) (CoglTexture *tex, CoglPixelFormat format, int rowstride, uint8_t *data); @@ -111,9 +115,9 @@ struct _CoglTextureVtable int (* get_max_waste) (CoglTexture *tex); - CoglBool (* is_sliced) (CoglTexture *tex); + gboolean (* is_sliced) (CoglTexture *tex); - CoglBool (* can_hardware_repeat) (CoglTexture *tex); + gboolean (* can_hardware_repeat) (CoglTexture *tex); void (* transform_coords_to_gl) (CoglTexture *tex, float *s, @@ -121,7 +125,7 @@ struct _CoglTextureVtable CoglTransformResult (* transform_quad_coords_to_gl) (CoglTexture *tex, float *coords); - CoglBool (* get_gl_texture) (CoglTexture *tex, + gboolean (* get_gl_texture) (CoglTexture *tex, GLuint *out_gl_handle, GLenum *out_gl_target); @@ -136,26 +140,20 @@ struct _CoglTextureVtable /* OpenGL driver specific virtual function */ void (* gl_flush_legacy_texobj_wrap_modes) (CoglTexture *tex, GLenum wrap_mode_s, - GLenum wrap_mode_t, - GLenum wrap_mode_p); + GLenum wrap_mode_t); CoglPixelFormat (* get_format) (CoglTexture *tex); GLenum (* get_gl_format) (CoglTexture *tex); - CoglTextureType (* get_type) (CoglTexture *tex); - - CoglBool (* is_foreign) (CoglTexture *tex); - /* Only needs to be implemented if is_primitive == TRUE */ void (* set_auto_mipmap) (CoglTexture *texture, - CoglBool value); + gboolean value); }; typedef enum _CoglTextureSoureType { COGL_TEXTURE_SOURCE_TYPE_SIZED = 1, COGL_TEXTURE_SOURCE_TYPE_BITMAP, COGL_TEXTURE_SOURCE_TYPE_EGL_IMAGE, - COGL_TEXTURE_SOURCE_TYPE_GL_FOREIGN, COGL_TEXTURE_SOURCE_TYPE_EGL_IMAGE_EXTERNAL } CoglTextureSourceType; @@ -172,7 +170,7 @@ typedef struct _CoglTextureLoader CoglBitmap *bitmap; int height; /* for 3d textures */ int depth; /* for 3d textures */ - CoglBool can_convert_in_place; + gboolean can_convert_in_place; } bitmap; #if defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base) struct { @@ -180,6 +178,7 @@ typedef struct _CoglTextureLoader int width; int height; CoglPixelFormat format; + CoglEglImageFlags flags; } egl_image; #endif #if defined (COGL_HAS_EGL_SUPPORT) @@ -205,10 +204,11 @@ struct _CoglTexture CoglContext *context; CoglTextureLoader *loader; GList *framebuffers; - int max_level; + int max_level_set; + int max_level_requested; int width; int height; - CoglBool allocated; + gboolean allocated; /* * Internal format @@ -273,7 +273,7 @@ _cogl_texture_register_texture_type (const CoglObjectClass *klass); (TypeName, type_name, \ _cogl_texture_register_texture_type (&_cogl_##type_name##_class)) -CoglBool +COGL_EXPORT gboolean _cogl_texture_can_hardware_repeat (CoglTexture *texture); void @@ -323,9 +323,6 @@ void _cogl_texture_set_internal_format (CoglTexture *texture, CoglPixelFormat internal_format); -CoglBool -_cogl_texture_is_foreign (CoglTexture *texture); - void _cogl_texture_associate_framebuffer (CoglTexture *texture, CoglFramebuffer *framebuffer); @@ -350,19 +347,7 @@ _cogl_texture_spans_foreach_in_region (CoglSpan *x_spans, CoglMetaTextureCallback callback, void *user_data); -/* - * _cogl_texture_get_type: - * @texture: a #CoglTexture pointer - * - * Retrieves the texture type of the underlying hardware texture that - * this #CoglTexture will use. - * - * Return value: The type of the hardware texture. - */ -CoglTextureType -_cogl_texture_get_type (CoglTexture *texture); - -CoglBool +COGL_EXPORT gboolean _cogl_texture_set_region (CoglTexture *texture, int width, int height, @@ -372,9 +357,9 @@ _cogl_texture_set_region (CoglTexture *texture, int dst_x, int dst_y, int level, - CoglError **error); + GError **error); -CoglBool +gboolean _cogl_texture_set_region_from_bitmap (CoglTexture *texture, int src_x, int src_y, @@ -384,15 +369,19 @@ _cogl_texture_set_region_from_bitmap (CoglTexture *texture, int dst_x, int dst_y, int level, - CoglError **error); + GError **error); -CoglBool +gboolean _cogl_texture_needs_premult_conversion (CoglPixelFormat src_format, CoglPixelFormat dst_format); int _cogl_texture_get_n_levels (CoglTexture *texture); +void +cogl_texture_set_max_level (CoglTexture *texture, + int max_level); + void _cogl_texture_get_level_size (CoglTexture *texture, int level, @@ -406,7 +395,7 @@ _cogl_texture_set_allocated (CoglTexture *texture, int width, int height); -CoglPixelFormat +COGL_EXPORT CoglPixelFormat _cogl_texture_get_format (CoglTexture *texture); CoglTextureLoader * diff --git a/cogl/cogl/cogl-texture-rectangle-private.h b/cogl/cogl/cogl-texture-rectangle-private.h deleted file mode 100644 index 75029e76e..000000000 --- a/cogl/cogl/cogl-texture-rectangle-private.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_TEXTURE_RECTANGLE_H -#define __COGL_TEXTURE_RECTANGLE_H - -#include "cogl-pipeline-private.h" -#include "cogl-texture-private.h" -#include "cogl-texture-rectangle.h" - -struct _CoglTextureRectangle -{ - CoglTexture _parent; - - /* The internal format of the texture represented as a - CoglPixelFormat */ - CoglPixelFormat internal_format; - - /* TODO: factor out these OpenGL specific members into some form - * of driver private state. */ - - /* The internal format of the GL texture represented as a GL enum */ - GLenum gl_format; - /* The texture object number */ - GLuint gl_texture; - GLenum gl_legacy_texobj_min_filter; - GLenum gl_legacy_texobj_mag_filter; - GLint gl_legacy_texobj_wrap_mode_s; - GLint gl_legacy_texobj_wrap_mode_t; - CoglBool is_foreign; -}; - -CoglTextureRectangle * -_cogl_texture_rectangle_new_from_foreign (GLuint gl_handle, - GLuint width, - GLuint height, - CoglPixelFormat format); - -#endif /* __COGL_TEXTURE_RECTANGLE_H */ diff --git a/cogl/cogl/cogl-texture-rectangle.c b/cogl/cogl/cogl-texture-rectangle.c deleted file mode 100644 index cc2e642d3..000000000 --- a/cogl/cogl/cogl-texture-rectangle.c +++ /dev/null @@ -1,777 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts - */ - -#ifdef HAVE_CONFIG_H -#include "cogl-config.h" -#endif - -#include "cogl-private.h" -#include "cogl-util.h" -#include "cogl-texture-private.h" -#include "cogl-texture-rectangle-private.h" -#include "cogl-texture-driver.h" -#include "cogl-context-private.h" -#include "cogl-object-private.h" -#include "cogl-journal-private.h" -#include "cogl-pipeline-opengl-private.h" -#include "cogl-error-private.h" -#include "cogl-util-gl-private.h" -#include "cogl-gtype-private.h" - -#include -#include - -/* These aren't defined under GLES */ -#ifndef GL_TEXTURE_RECTANGLE_ARB -#define GL_TEXTURE_RECTANGLE_ARB 0x84F5 -#endif -#ifndef GL_CLAMP -#define GL_CLAMP 0x2900 -#endif -#ifndef GL_CLAMP_TO_BORDER -#define GL_CLAMP_TO_BORDER 0x812D -#endif - -static void _cogl_texture_rectangle_free (CoglTextureRectangle *tex_rect); - -COGL_TEXTURE_DEFINE (TextureRectangle, texture_rectangle); -COGL_GTYPE_DEFINE_CLASS (TextureRectangle, texture_rectangle, - COGL_GTYPE_IMPLEMENT_INTERFACE (texture)); - -static const CoglTextureVtable cogl_texture_rectangle_vtable; - -static CoglBool -can_use_wrap_mode (GLenum wrap_mode) -{ - return (wrap_mode == GL_CLAMP || - wrap_mode == GL_CLAMP_TO_EDGE || - wrap_mode == GL_CLAMP_TO_BORDER); -} - -static void -_cogl_texture_rectangle_gl_flush_legacy_texobj_wrap_modes (CoglTexture *tex, - GLenum wrap_mode_s, - GLenum wrap_mode_t, - GLenum wrap_mode_p) -{ - CoglTextureRectangle *tex_rect = COGL_TEXTURE_RECTANGLE (tex); - CoglContext *ctx = tex->context; - - /* Only set the wrap mode if it's different from the current value - to avoid too many GL calls. Texture rectangle doesn't make use of - the r coordinate so we can ignore its wrap mode */ - if (tex_rect->gl_legacy_texobj_wrap_mode_s != wrap_mode_s || - tex_rect->gl_legacy_texobj_wrap_mode_t != wrap_mode_t) - { - g_assert (can_use_wrap_mode (wrap_mode_s)); - g_assert (can_use_wrap_mode (wrap_mode_t)); - - _cogl_bind_gl_texture_transient (GL_TEXTURE_RECTANGLE_ARB, - tex_rect->gl_texture, - tex_rect->is_foreign); - GE( ctx, glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, - GL_TEXTURE_WRAP_S, wrap_mode_s) ); - GE( ctx, glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, - GL_TEXTURE_WRAP_T, wrap_mode_t) ); - - tex_rect->gl_legacy_texobj_wrap_mode_s = wrap_mode_s; - tex_rect->gl_legacy_texobj_wrap_mode_t = wrap_mode_t; - } -} - -static void -_cogl_texture_rectangle_free (CoglTextureRectangle *tex_rect) -{ - if (!tex_rect->is_foreign && tex_rect->gl_texture) - _cogl_delete_gl_texture (tex_rect->gl_texture); - - /* Chain up */ - _cogl_texture_free (COGL_TEXTURE (tex_rect)); -} - -static CoglBool -_cogl_texture_rectangle_can_create (CoglContext *ctx, - unsigned int width, - unsigned int height, - CoglPixelFormat internal_format, - CoglError **error) -{ - GLenum gl_intformat; - GLenum gl_format; - GLenum gl_type; - - if (!cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_RECTANGLE)) - { - _cogl_set_error (error, - COGL_TEXTURE_ERROR, - COGL_TEXTURE_ERROR_TYPE, - "The CoglTextureRectangle feature isn't available"); - return FALSE; - } - - ctx->driver_vtable->pixel_format_to_gl (ctx, - internal_format, - &gl_intformat, - &gl_format, - &gl_type); - - /* Check that the driver can create a texture with that size */ - if (!ctx->texture_driver->size_supported (ctx, - GL_TEXTURE_RECTANGLE_ARB, - gl_intformat, - gl_format, - gl_type, - width, - height)) - { - _cogl_set_error (error, - COGL_TEXTURE_ERROR, - COGL_TEXTURE_ERROR_SIZE, - "The requested texture size + format is unsupported"); - return FALSE; - } - - return TRUE; -} - -static void -_cogl_texture_rectangle_set_auto_mipmap (CoglTexture *tex, - CoglBool value) -{ - /* Rectangle textures currently never support mipmapping so there's - no point in doing anything here */ -} - -static CoglTextureRectangle * -_cogl_texture_rectangle_create_base (CoglContext *ctx, - int width, - int height, - CoglPixelFormat internal_format, - CoglTextureLoader *loader) -{ - CoglTextureRectangle *tex_rect = g_new (CoglTextureRectangle, 1); - CoglTexture *tex = COGL_TEXTURE (tex_rect); - - _cogl_texture_init (tex, ctx, width, height, - internal_format, loader, - &cogl_texture_rectangle_vtable); - - tex_rect->gl_texture = 0; - tex_rect->is_foreign = FALSE; - - /* We default to GL_LINEAR for both filters */ - tex_rect->gl_legacy_texobj_min_filter = GL_LINEAR; - tex_rect->gl_legacy_texobj_mag_filter = GL_LINEAR; - - /* Wrap mode not yet set */ - tex_rect->gl_legacy_texobj_wrap_mode_s = GL_FALSE; - tex_rect->gl_legacy_texobj_wrap_mode_t = GL_FALSE; - - return _cogl_texture_rectangle_object_new (tex_rect); -} - -CoglTextureRectangle * -cogl_texture_rectangle_new_with_size (CoglContext *ctx, - int width, - int height) -{ - CoglTextureLoader *loader = _cogl_texture_create_loader (); - loader->src_type = COGL_TEXTURE_SOURCE_TYPE_SIZED; - loader->src.sized.width = width; - loader->src.sized.height = height; - - return _cogl_texture_rectangle_create_base (ctx, width, height, - COGL_PIXEL_FORMAT_RGBA_8888_PRE, - loader); -} - -static CoglBool -allocate_with_size (CoglTextureRectangle *tex_rect, - CoglTextureLoader *loader, - CoglError **error) -{ - CoglTexture *tex = COGL_TEXTURE (tex_rect); - CoglContext *ctx = tex->context; - CoglPixelFormat internal_format; - int width = loader->src.sized.width; - int height = loader->src.sized.height; - GLenum gl_intformat; - GLenum gl_format; - GLenum gl_type; - GLenum gl_texture; - - internal_format = - _cogl_texture_determine_internal_format (tex, COGL_PIXEL_FORMAT_ANY); - - if (!_cogl_texture_rectangle_can_create (ctx, - width, - height, - internal_format, - error)) - return FALSE; - - ctx->driver_vtable->pixel_format_to_gl (ctx, - internal_format, - &gl_intformat, - &gl_format, - &gl_type); - - gl_texture = - ctx->texture_driver->gen (ctx, - GL_TEXTURE_RECTANGLE_ARB, - internal_format); - _cogl_bind_gl_texture_transient (GL_TEXTURE_RECTANGLE_ARB, - gl_texture, - tex_rect->is_foreign); - - /* Clear any GL errors */ - _cogl_gl_util_clear_gl_errors (ctx); - - ctx->glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, gl_intformat, - width, height, 0, gl_format, gl_type, NULL); - - if (_cogl_gl_util_catch_out_of_memory (ctx, error)) - { - GE( ctx, glDeleteTextures (1, &gl_texture) ); - return FALSE; - } - - tex_rect->internal_format = internal_format; - - tex_rect->gl_texture = gl_texture; - tex_rect->gl_format = gl_intformat; - - _cogl_texture_set_allocated (COGL_TEXTURE (tex_rect), - internal_format, width, height); - - return TRUE; -} - -static CoglBool -allocate_from_bitmap (CoglTextureRectangle *tex_rect, - CoglTextureLoader *loader, - CoglError **error) -{ - CoglTexture *tex = COGL_TEXTURE (tex_rect); - CoglContext *ctx = tex->context; - CoglPixelFormat internal_format; - CoglBitmap *bmp = loader->src.bitmap.bitmap; - int width = cogl_bitmap_get_width (bmp); - int height = cogl_bitmap_get_height (bmp); - CoglBool can_convert_in_place = loader->src.bitmap.can_convert_in_place; - CoglBitmap *upload_bmp; - GLenum gl_intformat; - GLenum gl_format; - GLenum gl_type; - - internal_format = - _cogl_texture_determine_internal_format (tex, cogl_bitmap_get_format (bmp)); - - if (!_cogl_texture_rectangle_can_create (ctx, - width, - height, - internal_format, - error)) - return FALSE; - - upload_bmp = _cogl_bitmap_convert_for_upload (bmp, - internal_format, - can_convert_in_place, - error); - if (upload_bmp == NULL) - return FALSE; - - ctx->driver_vtable->pixel_format_to_gl (ctx, - cogl_bitmap_get_format (upload_bmp), - NULL, /* internal format */ - &gl_format, - &gl_type); - ctx->driver_vtable->pixel_format_to_gl (ctx, - internal_format, - &gl_intformat, - NULL, - NULL); - - tex_rect->gl_texture = - ctx->texture_driver->gen (ctx, - GL_TEXTURE_RECTANGLE_ARB, - internal_format); - if (!ctx->texture_driver->upload_to_gl (ctx, - GL_TEXTURE_RECTANGLE_ARB, - tex_rect->gl_texture, - FALSE, - upload_bmp, - gl_intformat, - gl_format, - gl_type, - error)) - { - cogl_object_unref (upload_bmp); - return FALSE; - } - - tex_rect->gl_format = gl_intformat; - tex_rect->internal_format = internal_format; - - cogl_object_unref (upload_bmp); - - _cogl_texture_set_allocated (COGL_TEXTURE (tex_rect), - internal_format, width, height); - - return TRUE; -} - -static CoglBool -allocate_from_gl_foreign (CoglTextureRectangle *tex_rect, - CoglTextureLoader *loader, - CoglError **error) -{ - CoglTexture *tex = COGL_TEXTURE (tex_rect); - CoglContext *ctx = tex->context; - CoglPixelFormat format = loader->src.gl_foreign.format; - GLint gl_compressed = GL_FALSE; - GLenum gl_int_format = 0; - - if (!ctx->texture_driver->allows_foreign_gl_target (ctx, - GL_TEXTURE_RECTANGLE_ARB)) - { - _cogl_set_error (error, - COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_UNSUPPORTED, - "Foreign GL_TEXTURE_RECTANGLE textures are not " - "supported by your system"); - return FALSE; - } - - /* Make sure binding succeeds */ - _cogl_gl_util_clear_gl_errors (ctx); - - _cogl_bind_gl_texture_transient (GL_TEXTURE_RECTANGLE_ARB, - loader->src.gl_foreign.gl_handle, TRUE); - if (_cogl_gl_util_get_error (ctx) != GL_NO_ERROR) - { - _cogl_set_error (error, - COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_UNSUPPORTED, - "Failed to bind foreign GL_TEXTURE_RECTANGLE texture"); - return FALSE; - } - - /* Obtain texture parameters */ - -#ifdef HAVE_COGL_GL - if (_cogl_has_private_feature - (ctx, COGL_PRIVATE_FEATURE_QUERY_TEXTURE_PARAMETERS)) - { - GLint val; - - GE( ctx, glGetTexLevelParameteriv (GL_TEXTURE_RECTANGLE_ARB, 0, - GL_TEXTURE_COMPRESSED, - &gl_compressed) ); - - GE( ctx, glGetTexLevelParameteriv (GL_TEXTURE_RECTANGLE_ARB, 0, - GL_TEXTURE_INTERNAL_FORMAT, - &val) ); - - gl_int_format = val; - - /* If we can query GL for the actual pixel format then we'll ignore - the passed in format and use that. */ - if (!ctx->driver_vtable->pixel_format_from_gl_internal (ctx, - gl_int_format, - &format)) - { - _cogl_set_error (error, - COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_UNSUPPORTED, - "Unsupported internal format for foreign texture"); - return FALSE; - } - } - else -#endif - { - /* Otherwise we'll assume we can derive the GL format from the - passed in format */ - ctx->driver_vtable->pixel_format_to_gl (ctx, - format, - &gl_int_format, - NULL, - NULL); - } - - /* Compressed texture images not supported */ - if (gl_compressed == GL_TRUE) - { - _cogl_set_error (error, - COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_UNSUPPORTED, - "Compressed foreign textures aren't currently supported"); - return FALSE; - } - - /* Setup bitmap info */ - tex_rect->is_foreign = TRUE; - - tex_rect->gl_texture = loader->src.gl_foreign.gl_handle; - tex_rect->gl_format = gl_int_format; - - /* Unknown filter */ - tex_rect->gl_legacy_texobj_min_filter = GL_FALSE; - tex_rect->gl_legacy_texobj_mag_filter = GL_FALSE; - - tex_rect->internal_format = format; - - _cogl_texture_set_allocated (COGL_TEXTURE (tex_rect), - format, - loader->src.gl_foreign.width, - loader->src.gl_foreign.height); - - return TRUE; -} - -static CoglBool -_cogl_texture_rectangle_allocate (CoglTexture *tex, - CoglError **error) -{ - CoglTextureRectangle *tex_rect = COGL_TEXTURE_RECTANGLE (tex); - CoglTextureLoader *loader = tex->loader; - - _COGL_RETURN_VAL_IF_FAIL (loader, FALSE); - - switch (loader->src_type) - { - case COGL_TEXTURE_SOURCE_TYPE_SIZED: - return allocate_with_size (tex_rect, loader, error); - case COGL_TEXTURE_SOURCE_TYPE_BITMAP: - return allocate_from_bitmap (tex_rect, loader, error); - case COGL_TEXTURE_SOURCE_TYPE_GL_FOREIGN: - return allocate_from_gl_foreign (tex_rect, loader, error); - default: - break; - } - - g_return_val_if_reached (FALSE); -} - -CoglTextureRectangle * -cogl_texture_rectangle_new_from_bitmap (CoglBitmap *bmp) -{ - CoglTextureLoader *loader; - - _COGL_RETURN_VAL_IF_FAIL (cogl_is_bitmap (bmp), NULL); - - loader = _cogl_texture_create_loader (); - loader->src_type = COGL_TEXTURE_SOURCE_TYPE_BITMAP; - loader->src.bitmap.bitmap = cogl_object_ref (bmp); - loader->src.bitmap.can_convert_in_place = FALSE; /* TODO add api for this */ - - return _cogl_texture_rectangle_create_base (_cogl_bitmap_get_context (bmp), - cogl_bitmap_get_width (bmp), - cogl_bitmap_get_height (bmp), - cogl_bitmap_get_format (bmp), - loader); -} - -CoglTextureRectangle * -cogl_texture_rectangle_new_from_foreign (CoglContext *ctx, - unsigned int gl_handle, - int width, - int height, - CoglPixelFormat format) -{ - CoglTextureLoader *loader; - - /* NOTE: width, height and internal format are not queriable in - * GLES, hence such a function prototype. Also in the case of full - * opengl the user may be creating a Cogl texture for a - * texture_from_pixmap object where glTexImage2D may not have been - * called and the texture_from_pixmap spec doesn't clarify that it - * is reliable to query back the size from OpenGL. - */ - - /* Assert that it is a valid GL texture object */ - _COGL_RETURN_VAL_IF_FAIL (ctx->glIsTexture (gl_handle), NULL); - - /* Validate width and height */ - _COGL_RETURN_VAL_IF_FAIL (width > 0 && height > 0, NULL); - - loader = _cogl_texture_create_loader (); - loader->src_type = COGL_TEXTURE_SOURCE_TYPE_GL_FOREIGN; - loader->src.gl_foreign.gl_handle = gl_handle; - loader->src.gl_foreign.width = width; - loader->src.gl_foreign.height = height; - loader->src.gl_foreign.format = format; - - return _cogl_texture_rectangle_create_base (ctx, width, height, - format, loader); -} - -static int -_cogl_texture_rectangle_get_max_waste (CoglTexture *tex) -{ - return -1; -} - -static CoglBool -_cogl_texture_rectangle_is_sliced (CoglTexture *tex) -{ - return FALSE; -} - -static CoglBool -_cogl_texture_rectangle_can_hardware_repeat (CoglTexture *tex) -{ - return FALSE; -} - -static void -_cogl_texture_rectangle_transform_coords_to_gl (CoglTexture *tex, - float *s, - float *t) -{ - *s *= tex->width; - *t *= tex->height; -} - -static CoglTransformResult -_cogl_texture_rectangle_transform_quad_coords_to_gl (CoglTexture *tex, - float *coords) -{ - CoglBool need_repeat = FALSE; - int i; - - for (i = 0; i < 4; i++) - { - if (coords[i] < 0.0f || coords[i] > 1.0f) - need_repeat = TRUE; - coords[i] *= (i & 1) ? tex->height : tex->width; - } - - return (need_repeat ? COGL_TRANSFORM_SOFTWARE_REPEAT - : COGL_TRANSFORM_NO_REPEAT); -} - -static CoglBool -_cogl_texture_rectangle_get_gl_texture (CoglTexture *tex, - GLuint *out_gl_handle, - GLenum *out_gl_target) -{ - CoglTextureRectangle *tex_rect = COGL_TEXTURE_RECTANGLE (tex); - - if (out_gl_handle) - *out_gl_handle = tex_rect->gl_texture; - - if (out_gl_target) - *out_gl_target = GL_TEXTURE_RECTANGLE_ARB; - - return TRUE; -} - -static void -_cogl_texture_rectangle_gl_flush_legacy_texobj_filters (CoglTexture *tex, - GLenum min_filter, - GLenum mag_filter) -{ - CoglTextureRectangle *tex_rect = COGL_TEXTURE_RECTANGLE (tex); - CoglContext *ctx = tex->context; - - if (min_filter == tex_rect->gl_legacy_texobj_min_filter - && mag_filter == tex_rect->gl_legacy_texobj_mag_filter) - return; - - /* Rectangle textures don't support mipmapping */ - g_assert (min_filter == GL_LINEAR || min_filter == GL_NEAREST); - - /* Store new values */ - tex_rect->gl_legacy_texobj_min_filter = min_filter; - tex_rect->gl_legacy_texobj_mag_filter = mag_filter; - - /* Apply new filters to the texture */ - _cogl_bind_gl_texture_transient (GL_TEXTURE_RECTANGLE_ARB, - tex_rect->gl_texture, - tex_rect->is_foreign); - GE( ctx, glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, - mag_filter) ); - GE( ctx, glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, - min_filter) ); -} - -static void -_cogl_texture_rectangle_pre_paint (CoglTexture *tex, - CoglTexturePrePaintFlags flags) -{ - /* Rectangle textures don't support mipmaps */ - g_assert ((flags & COGL_TEXTURE_NEEDS_MIPMAP) == 0); -} - -static void -_cogl_texture_rectangle_ensure_non_quad_rendering (CoglTexture *tex) -{ - /* Nothing needs to be done */ -} - -static CoglBool -_cogl_texture_rectangle_set_region (CoglTexture *tex, - int src_x, - int src_y, - int dst_x, - int dst_y, - int dst_width, - int dst_height, - int level, - CoglBitmap *bmp, - CoglError **error) -{ - CoglBitmap *upload_bmp; - GLenum gl_format; - GLenum gl_type; - CoglContext *ctx = tex->context; - CoglBool status; - - upload_bmp = - _cogl_bitmap_convert_for_upload (bmp, - _cogl_texture_get_format (tex), - FALSE, /* can't convert in place */ - error); - if (upload_bmp == NULL) - return FALSE; - - ctx->driver_vtable->pixel_format_to_gl (ctx, - cogl_bitmap_get_format (upload_bmp), - NULL, /* internal format */ - &gl_format, - &gl_type); - - /* Send data to GL */ - status = - ctx->texture_driver->upload_subregion_to_gl (ctx, - tex, - FALSE, - src_x, src_y, - dst_x, dst_y, - dst_width, dst_height, - level, - upload_bmp, - gl_format, - gl_type, - error); - - cogl_object_unref (upload_bmp); - - return status; -} - -static CoglBool -_cogl_texture_rectangle_get_data (CoglTexture *tex, - CoglPixelFormat format, - int rowstride, - uint8_t *data) -{ - CoglTextureRectangle *tex_rect = COGL_TEXTURE_RECTANGLE (tex); - CoglContext *ctx = tex->context; - int bpp; - GLenum gl_format; - GLenum gl_type; - - bpp = _cogl_pixel_format_get_bytes_per_pixel (format); - - ctx->driver_vtable->pixel_format_to_gl (ctx, - format, - NULL, /* internal format */ - &gl_format, - &gl_type); - - ctx->texture_driver->prep_gl_for_pixels_download (ctx, - rowstride, - tex->width, - bpp); - - _cogl_bind_gl_texture_transient (GL_TEXTURE_RECTANGLE_ARB, - tex_rect->gl_texture, - tex_rect->is_foreign); - return ctx->texture_driver->gl_get_tex_image (ctx, - GL_TEXTURE_RECTANGLE_ARB, - gl_format, - gl_type, - data); -} - -static CoglPixelFormat -_cogl_texture_rectangle_get_format (CoglTexture *tex) -{ - return COGL_TEXTURE_RECTANGLE (tex)->internal_format; -} - -static GLenum -_cogl_texture_rectangle_get_gl_format (CoglTexture *tex) -{ - return COGL_TEXTURE_RECTANGLE (tex)->gl_format; -} - -static CoglBool -_cogl_texture_rectangle_is_foreign (CoglTexture *tex) -{ - return COGL_TEXTURE_RECTANGLE (tex)->is_foreign; -} - -static CoglTextureType -_cogl_texture_rectangle_get_type (CoglTexture *tex) -{ - return COGL_TEXTURE_TYPE_RECTANGLE; -} - -static const CoglTextureVtable -cogl_texture_rectangle_vtable = - { - TRUE, /* primitive */ - _cogl_texture_rectangle_allocate, - _cogl_texture_rectangle_set_region, - _cogl_texture_rectangle_get_data, - NULL, /* foreach_sub_texture_in_region */ - _cogl_texture_rectangle_get_max_waste, - _cogl_texture_rectangle_is_sliced, - _cogl_texture_rectangle_can_hardware_repeat, - _cogl_texture_rectangle_transform_coords_to_gl, - _cogl_texture_rectangle_transform_quad_coords_to_gl, - _cogl_texture_rectangle_get_gl_texture, - _cogl_texture_rectangle_gl_flush_legacy_texobj_filters, - _cogl_texture_rectangle_pre_paint, - _cogl_texture_rectangle_ensure_non_quad_rendering, - _cogl_texture_rectangle_gl_flush_legacy_texobj_wrap_modes, - _cogl_texture_rectangle_get_format, - _cogl_texture_rectangle_get_gl_format, - _cogl_texture_rectangle_get_type, - _cogl_texture_rectangle_is_foreign, - _cogl_texture_rectangle_set_auto_mipmap - }; diff --git a/cogl/cogl/cogl-texture-rectangle.h b/cogl/cogl/cogl-texture-rectangle.h deleted file mode 100644 index c71f0f84e..000000000 --- a/cogl/cogl/cogl-texture-rectangle.h +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Robert Bragg - */ - -#ifndef __COGL_TEXURE_RECTANGLE_H -#define __COGL_TEXURE_RECTANGLE_H - -#include "cogl-context.h" - -COGL_BEGIN_DECLS - -/** - * SECTION:cogl-texture-rectangle - * @short_description: Functions for creating and manipulating rectangle - * textures for use with non-normalized coordinates. - * - * These functions allow low-level "rectangle" textures to be allocated. - * These textures are never constrained to power-of-two sizes but they - * also don't support having a mipmap and can only be wrapped with - * %COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE. - * - * The most notable difference between rectangle textures and 2D - * textures is that rectangle textures are sampled using un-normalized - * texture coordinates, so instead of using coordinates (0,0) and - * (1,1) to map to the top-left and bottom right corners of the - * texture you would instead use (0,0) and (width,height). - * - * The use of non-normalized coordinates can be particularly - * convenient when writing glsl shaders that use a texture as a lookup - * table since you don't need to upload separate uniforms to map - * normalized coordinates to texels. - * - * If you want to sample from a rectangle texture from GLSL you should - * use the sampler2DRect sampler type. - * - * Applications wanting to use #CoglTextureRectangle should first check - * for the %COGL_FEATURE_ID_TEXTURE_RECTANGLE feature using - * cogl_has_feature(). - */ - -typedef struct _CoglTextureRectangle CoglTextureRectangle; -#define COGL_TEXTURE_RECTANGLE(X) ((CoglTextureRectangle *)X) - -/** - * cogl_texture_rectangle_get_gtype: - * - * Returns: a #GType that can be used with the GLib type system. - */ -GType cogl_texture_rectangle_get_gtype (void); - -/** - * cogl_is_texture_rectangle: - * @object: A #CoglObject - * - * Gets whether the given object references an existing - * #CoglTextureRectangle object. - * - * Return value: %TRUE if the object references a - * #CoglTextureRectangle, %FALSE otherwise. - */ -CoglBool -cogl_is_texture_rectangle (void *object); - -/** - * cogl_texture_rectangle_new_with_size: - * @ctx: A #CoglContext pointer - * @width: The texture width to allocate - * @height: The texture height to allocate - * - * Creates a new #CoglTextureRectangle texture with a given @width, - * and @height. This texture is a low-level texture that the GPU can - * sample from directly unlike high-level textures such as - * #CoglTexture2DSliced and #CoglAtlasTexture. - * - * Unlike for #CoglTexture2D textures, coordinates for - * #CoglTextureRectangle textures should not be normalized. So instead - * of using the coordinate (1, 1) to sample the bottom right corner of - * a rectangle texture you would use (@width, @height) where @width - * and @height are the width and height of the texture. - * - * If you want to sample from a rectangle texture from GLSL you - * should use the sampler2DRect sampler type. - * - * Applications wanting to use #CoglTextureRectangle should - * first check for the %COGL_FEATURE_ID_TEXTURE_RECTANGLE feature - * using cogl_has_feature(). - * - * The storage for the texture is not allocated before this function - * returns. You can call cogl_texture_allocate() to explicitly - * allocate the underlying storage or preferably let Cogl - * automatically allocate storage lazily when it may know more about - * how the texture is going to be used and can optimize how it is - * allocated. - * - * Returns value: (transfer full): A pointer to a new #CoglTextureRectangle - * object with no storage allocated yet. - * - * Since: 1.10 - * Stability: unstable - */ -CoglTextureRectangle * -cogl_texture_rectangle_new_with_size (CoglContext *ctx, - int width, - int height); - -/** - * cogl_texture_rectangle_new_from_bitmap: - * @bitmap: A #CoglBitmap - * - * Allocates a new #CoglTextureRectangle texture which will be - * initialized with the pixel data from @bitmap. This texture is a - * low-level texture that the GPU can sample from directly unlike - * high-level textures such as #CoglTexture2DSliced and - * #CoglAtlasTexture. - * - * Unlike for #CoglTexture2D textures, coordinates for - * #CoglTextureRectangle textures should not be normalized. So instead - * of using the coordinate (1, 1) to sample the bottom right corner of - * a rectangle texture you would use (@width, @height) where @width - * and @height are the width and height of the texture. - * - * If you want to sample from a rectangle texture from GLSL you - * should use the sampler2DRect sampler type. - * - * Applications wanting to use #CoglTextureRectangle should - * first check for the %COGL_FEATURE_ID_TEXTURE_RECTANGLE feature - * using cogl_has_feature(). - * - * The storage for the texture is not allocated before this function - * returns. You can call cogl_texture_allocate() to explicitly - * allocate the underlying storage or preferably let Cogl - * automatically allocate storage lazily when it may know more about - * how the texture is going to be used and can optimize how it is - * allocated. - * - * Return value: (transfer full): A pointer to a new - * #CoglTextureRectangle texture. - * Since: 2.0 - * Stability: unstable - */ -CoglTextureRectangle * -cogl_texture_rectangle_new_from_bitmap (CoglBitmap *bitmap); - -/** - * cogl_texture_rectangle_new_from_foreign: - * @ctx: A #CoglContext - * @gl_handle: A GL handle for a GL_TEXTURE_RECTANGLE texture object - * @width: Width of the foreign GL texture - * @height: Height of the foreign GL texture - * @format: The format of the texture - * - * Wraps an existing GL_TEXTURE_RECTANGLE texture object as a - * #CoglTextureRectangle. This can be used for integrating Cogl with - * software using OpenGL directly. - * - * Unlike for #CoglTexture2D textures, coordinates for - * #CoglTextureRectangle textures should not be normalized. So instead - * of using the coordinate (1, 1) to sample the bottom right corner of - * a rectangle texture you would use (@width, @height) where @width - * and @height are the width and height of the texture. - * - * The results are undefined for passing an invalid @gl_handle - * or if @width or @height don't have the correct texture - * geometry. - * - * If you want to sample from a rectangle texture from GLSL you - * should use the sampler2DRect sampler type. - * - * Applications wanting to use #CoglTextureRectangle should - * first check for the %COGL_FEATURE_ID_TEXTURE_RECTANGLE feature - * using cogl_has_feature(). - * - * The texture is still configurable until it has been allocated so - * for example you can declare whether the texture is premultiplied - * with cogl_texture_set_premultiplied(). - * - * Return value: (transfer full): A new #CoglTextureRectangle texture - */ -CoglTextureRectangle * -cogl_texture_rectangle_new_from_foreign (CoglContext *ctx, - unsigned int gl_handle, - int width, - int height, - CoglPixelFormat format); - -COGL_END_DECLS - -#endif /* __COGL_TEXURE_RECTANGLE_H */ diff --git a/cogl/cogl/cogl-texture.c b/cogl/cogl/cogl-texture.c index 4c882ebce..c82481156 100644 --- a/cogl/cogl/cogl-texture.c +++ b/cogl/cogl/cogl-texture.c @@ -34,9 +34,7 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-util.h" #include "cogl-bitmap.h" @@ -48,21 +46,16 @@ #include "cogl-texture-driver.h" #include "cogl-texture-2d-sliced-private.h" #include "cogl-texture-2d-private.h" -#include "cogl-texture-2d-gl.h" -#include "cogl-texture-3d-private.h" -#include "cogl-texture-rectangle-private.h" #include "cogl-sub-texture-private.h" #include "cogl-atlas-texture-private.h" #include "cogl-pipeline.h" #include "cogl-context-private.h" #include "cogl-object-private.h" #include "cogl-object-private.h" -#include "cogl-primitives.h" #include "cogl-framebuffer-private.h" #include "cogl1-context.h" #include "cogl-sub-texture.h" #include "cogl-primitive-texture.h" -#include "cogl-error-private.h" #include "cogl-gtype-private.h" #include @@ -96,7 +89,7 @@ _cogl_texture_register_texture_type (const CoglObjectClass *klass) _cogl_texture_types = g_slist_prepend (_cogl_texture_types, (void *) klass); } -CoglBool +gboolean cogl_is_texture (void *object) { CoglObject *obj = (CoglObject *)object; @@ -122,7 +115,8 @@ _cogl_texture_init (CoglTexture *texture, const CoglTextureVtable *vtable) { texture->context = context; - texture->max_level = 0; + texture->max_level_set = 0; + texture->max_level_requested = 1000; /* OpenGL default GL_TEXTURE_MAX_LEVEL */ texture->width = width; texture->height = height; texture->allocated = FALSE; @@ -159,7 +153,6 @@ _cogl_texture_free_loader (CoglTexture *texture) { case COGL_TEXTURE_SOURCE_TYPE_SIZED: case COGL_TEXTURE_SOURCE_TYPE_EGL_IMAGE: - case COGL_TEXTURE_SOURCE_TYPE_GL_FOREIGN: case COGL_TEXTURE_SOURCE_TYPE_EGL_IMAGE_EXTERNAL: break; case COGL_TEXTURE_SOURCE_TYPE_BITMAP: @@ -182,10 +175,10 @@ _cogl_texture_free (CoglTexture *texture) { _cogl_texture_free_loader (texture); - free (texture); + g_free (texture); } -CoglBool +gboolean _cogl_texture_needs_premult_conversion (CoglPixelFormat src_format, CoglPixelFormat dst_format) { @@ -196,13 +189,13 @@ _cogl_texture_needs_premult_conversion (CoglPixelFormat src_format, (dst_format & COGL_PREMULT_BIT)); } -CoglBool -_cogl_texture_is_foreign (CoglTexture *texture) +gboolean +cogl_texture_is_get_data_supported (CoglTexture *texture) { - if (texture->vtable->is_foreign) - return texture->vtable->is_foreign (texture); + if (texture->vtable->is_get_data_supported) + return texture->vtable->is_get_data_supported (texture); else - return FALSE; + return TRUE; } unsigned int @@ -237,14 +230,16 @@ _cogl_texture_get_n_levels (CoglTexture *texture) int width = cogl_texture_get_width (texture); int height = cogl_texture_get_height (texture); int max_dimension = MAX (width, height); + int n_levels = _cogl_util_fls (max_dimension); - if (cogl_is_texture_3d (texture)) - { - CoglTexture3D *tex_3d = COGL_TEXTURE_3D (texture); - max_dimension = MAX (max_dimension, tex_3d->depth); - } + return MIN (n_levels, texture->max_level_requested + 1); +} - return _cogl_util_fls (max_dimension); +void +cogl_texture_set_max_level (CoglTexture *texture, + int max_level) +{ + texture->max_level_requested = max_level; } void @@ -256,17 +251,9 @@ _cogl_texture_get_level_size (CoglTexture *texture, { int current_width = cogl_texture_get_width (texture); int current_height = cogl_texture_get_height (texture); - int current_depth; + int current_depth = 0; int i; - if (cogl_is_texture_3d (texture)) - { - CoglTexture3D *tex_3d = COGL_TEXTURE_3D (texture); - current_depth = tex_3d->depth; - } - else - current_depth = 0; - /* NB: The OpenGL spec (like D3D) uses a floor() convention to * round down the size of a mipmap level when dividing the size * of the previous level results in a fraction... @@ -286,7 +273,7 @@ _cogl_texture_get_level_size (CoglTexture *texture, *depth = current_depth; } -CoglBool +gboolean cogl_texture_is_sliced (CoglTexture *texture) { if (!texture->allocated) @@ -298,7 +285,7 @@ cogl_texture_is_sliced (CoglTexture *texture) * will be needed to iterate over multiple sub textures for regions whos * texture coordinates extend out of the range [0,1] */ -CoglBool +gboolean _cogl_texture_can_hardware_repeat (CoglTexture *texture) { if (!texture->allocated) @@ -324,7 +311,7 @@ _cogl_texture_transform_quad_coords_to_gl (CoglTexture *texture, return texture->vtable->transform_quad_coords_to_gl (texture, coords); } -CoglBool +gboolean cogl_texture_get_gl_texture (CoglTexture *texture, GLuint *out_gl_handle, GLenum *out_gl_target) @@ -336,12 +323,6 @@ cogl_texture_get_gl_texture (CoglTexture *texture, out_gl_handle, out_gl_target); } -CoglTextureType -_cogl_texture_get_type (CoglTexture *texture) -{ - return texture->vtable->get_type (texture); -} - void _cogl_texture_pre_paint (CoglTexture *texture, CoglTexturePrePaintFlags flags) { @@ -368,7 +349,7 @@ _cogl_texture_ensure_non_quad_rendering (CoglTexture *texture) texture->vtable->ensure_non_quad_rendering (texture); } -CoglBool +gboolean _cogl_texture_set_region_from_bitmap (CoglTexture *texture, int src_x, int src_y, @@ -378,14 +359,12 @@ _cogl_texture_set_region_from_bitmap (CoglTexture *texture, int dst_x, int dst_y, int level, - CoglError **error) + GError **error) { - _COGL_RETURN_VAL_IF_FAIL ((cogl_bitmap_get_width (bmp) - src_x) - >= width, FALSE); - _COGL_RETURN_VAL_IF_FAIL ((cogl_bitmap_get_height (bmp) - src_y) - >= height, FALSE); - _COGL_RETURN_VAL_IF_FAIL (width > 0, FALSE); - _COGL_RETURN_VAL_IF_FAIL (height > 0, FALSE); + g_return_val_if_fail (cogl_bitmap_get_width (bmp) - src_x >= width, FALSE); + g_return_val_if_fail (cogl_bitmap_get_height (bmp) - src_y >= height, FALSE); + g_return_val_if_fail (width > 0, FALSE); + g_return_val_if_fail (height > 0, FALSE); /* Assert that the storage for this texture has been allocated */ if (!cogl_texture_allocate (texture, error)) @@ -407,7 +386,7 @@ _cogl_texture_set_region_from_bitmap (CoglTexture *texture, error); } -CoglBool +gboolean cogl_texture_set_region_from_bitmap (CoglTexture *texture, int src_x, int src_y, @@ -417,8 +396,8 @@ cogl_texture_set_region_from_bitmap (CoglTexture *texture, unsigned int dst_height, CoglBitmap *bitmap) { - CoglError *ignore_error = NULL; - CoglBool status = + GError *ignore_error = NULL; + gboolean status = _cogl_texture_set_region_from_bitmap (texture, src_x, src_y, dst_width, dst_height, @@ -427,12 +406,11 @@ cogl_texture_set_region_from_bitmap (CoglTexture *texture, 0, /* level */ &ignore_error); - if (!status) - cogl_error_free (ignore_error); + g_clear_error (&ignore_error); return status; } -CoglBool +gboolean _cogl_texture_set_region (CoglTexture *texture, int width, int height, @@ -442,17 +420,18 @@ _cogl_texture_set_region (CoglTexture *texture, int dst_x, int dst_y, int level, - CoglError **error) + GError **error) { CoglContext *ctx = texture->context; CoglBitmap *source_bmp; - CoglBool ret; + gboolean ret; - _COGL_RETURN_VAL_IF_FAIL (format != COGL_PIXEL_FORMAT_ANY, FALSE); + g_return_val_if_fail (format != COGL_PIXEL_FORMAT_ANY, FALSE); + g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, FALSE); /* Rowstride from width if none specified */ if (rowstride == 0) - rowstride = _cogl_pixel_format_get_bytes_per_pixel (format) * width; + rowstride = cogl_pixel_format_get_bytes_per_pixel (format, 0) * width; /* Init source bitmap */ source_bmp = cogl_bitmap_new_for_data (ctx, @@ -474,7 +453,7 @@ _cogl_texture_set_region (CoglTexture *texture, return ret; } -CoglBool +gboolean cogl_texture_set_region (CoglTexture *texture, int src_x, int src_y, @@ -488,12 +467,16 @@ cogl_texture_set_region (CoglTexture *texture, unsigned int rowstride, const uint8_t *data) { - CoglError *ignore_error = NULL; + GError *ignore_error = NULL; const uint8_t *first_pixel; - int bytes_per_pixel = _cogl_pixel_format_get_bytes_per_pixel (format); - CoglBool status; + int bytes_per_pixel; + gboolean status; + + g_return_val_if_fail (format != COGL_PIXEL_FORMAT_ANY, FALSE); + g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, FALSE); /* Rowstride from width if none specified */ + bytes_per_pixel = cogl_pixel_format_get_bytes_per_pixel (format, 0); if (rowstride == 0) rowstride = bytes_per_pixel * width; @@ -509,18 +492,17 @@ cogl_texture_set_region (CoglTexture *texture, dst_y, 0, &ignore_error); - if (!status) - cogl_error_free (ignore_error); + g_clear_error (&ignore_error); return status; } -CoglBool +gboolean cogl_texture_set_data (CoglTexture *texture, CoglPixelFormat format, int rowstride, const uint8_t *data, int level, - CoglError **error) + GError **error) { int level_width; int level_height; @@ -542,7 +524,7 @@ cogl_texture_set_data (CoglTexture *texture, error); } -static CoglBool +static gboolean get_texture_bits_via_offscreen (CoglTexture *meta_texture, CoglTexture *sub_texture, int x, @@ -557,13 +539,10 @@ get_texture_bits_via_offscreen (CoglTexture *meta_texture, CoglOffscreen *offscreen; CoglFramebuffer *framebuffer; CoglBitmap *bitmap; - CoglBool ret; - CoglError *ignore_error = NULL; + gboolean ret; + GError *ignore_error = NULL; CoglPixelFormat real_format; - if (!cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN)) - return FALSE; - offscreen = _cogl_offscreen_new_with_texture_full (sub_texture, COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL, @@ -572,7 +551,7 @@ get_texture_bits_via_offscreen (CoglTexture *meta_texture, framebuffer = COGL_FRAMEBUFFER (offscreen); if (!cogl_framebuffer_allocate (framebuffer, &ignore_error)) { - cogl_error_free (ignore_error); + g_error_free (ignore_error); return FALSE; } @@ -601,8 +580,7 @@ get_texture_bits_via_offscreen (CoglTexture *meta_texture, bitmap, &ignore_error); - if (!ret) - cogl_error_free (ignore_error); + g_clear_error (&ignore_error); cogl_object_unref (bitmap); @@ -611,7 +589,7 @@ get_texture_bits_via_offscreen (CoglTexture *meta_texture, return ret; } -static CoglBool +static gboolean get_texture_bits_via_copy (CoglTexture *texture, int x, int y, @@ -623,17 +601,20 @@ get_texture_bits_via_copy (CoglTexture *texture, { unsigned int full_rowstride; uint8_t *full_bits; - CoglBool ret = TRUE; + gboolean ret = TRUE; int bpp; int full_tex_width, full_tex_height; + g_return_val_if_fail (dst_format != COGL_PIXEL_FORMAT_ANY, FALSE); + g_return_val_if_fail (cogl_pixel_format_get_n_planes (dst_format) == 1, FALSE); + full_tex_width = cogl_texture_get_width (texture); full_tex_height = cogl_texture_get_height (texture); - bpp = _cogl_pixel_format_get_bytes_per_pixel (dst_format); + bpp = cogl_pixel_format_get_bytes_per_pixel (dst_format, 0); full_rowstride = bpp * full_tex_width; - full_bits = malloc (full_rowstride * full_tex_height); + full_bits = g_malloc (full_rowstride * full_tex_height); if (texture->vtable->get_data (texture, dst_format, @@ -654,7 +635,7 @@ get_texture_bits_via_copy (CoglTexture *texture, else ret = FALSE; - free (full_bits); + g_free (full_bits); return ret; } @@ -666,8 +647,8 @@ typedef struct int orig_height; CoglBitmap *target_bmp; uint8_t *target_bits; - CoglBool success; - CoglError *error; + gboolean success; + GError *error; } CoglTextureGetData; static void @@ -679,7 +660,8 @@ texture_get_cb (CoglTexture *subtexture, CoglTextureGetData *tg_data = user_data; CoglTexture *meta_texture = tg_data->meta_texture; CoglPixelFormat closest_format = cogl_bitmap_get_format (tg_data->target_bmp); - int bpp = _cogl_pixel_format_get_bytes_per_pixel (closest_format); + /* We already asserted that we have a single plane format */ + int bpp = cogl_pixel_format_get_bytes_per_pixel (closest_format, 0); unsigned int rowstride = cogl_bitmap_get_rowstride (tg_data->target_bmp); int subtexture_width = cogl_texture_get_width (subtexture); int subtexture_height = cogl_texture_get_height (subtexture); @@ -755,7 +737,7 @@ cogl_texture_get_data (CoglTexture *texture, int tex_width; int tex_height; CoglPixelFormat texture_format; - CoglError *ignore_error = NULL; + GError *ignore_error = NULL; CoglTextureGetData tg_data; @@ -765,11 +747,14 @@ cogl_texture_get_data (CoglTexture *texture, if (format == COGL_PIXEL_FORMAT_ANY) format = texture_format; + /* We only support single plane formats */ + g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, 0); + tex_width = cogl_texture_get_width (texture); tex_height = cogl_texture_get_height (texture); /* Rowstride from texture width if none specified */ - bpp = _cogl_pixel_format_get_bytes_per_pixel (format); + bpp = cogl_pixel_format_get_bytes_per_pixel (format, 0); if (rowstride == 0) rowstride = tex_width * bpp; @@ -780,7 +765,6 @@ cogl_texture_get_data (CoglTexture *texture, closest_format = ctx->texture_driver->find_best_gl_get_data_format (ctx, - texture_format, format, &closest_gl_format, &closest_gl_type); @@ -836,7 +820,7 @@ cogl_texture_get_data (CoglTexture *texture, &ignore_error); if (!target_bmp) { - cogl_error_free (ignore_error); + g_error_free (ignore_error); return 0; } } @@ -873,7 +857,7 @@ cogl_texture_get_data (CoglTexture *texture, } else { - cogl_error_free (ignore_error); + g_error_free (ignore_error); tg_data.success = FALSE; } @@ -890,8 +874,8 @@ cogl_texture_get_data (CoglTexture *texture, if (closest_format != format) { CoglBitmap *new_bmp; - CoglBool result; - CoglError *error = NULL; + gboolean result; + GError *error = NULL; /* Convert to requested format directly into the user's buffer */ new_bmp = cogl_bitmap_new_for_data (ctx, @@ -903,7 +887,7 @@ cogl_texture_get_data (CoglTexture *texture, if (!result) { - cogl_error_free (error); + g_error_free (error); /* Return failure after cleaning up */ byte_size = 0; } @@ -1091,20 +1075,20 @@ _cogl_texture_set_allocated (CoglTexture *texture, _cogl_texture_free_loader (texture); } -CoglBool +gboolean cogl_texture_allocate (CoglTexture *texture, - CoglError **error) + GError **error) { if (texture->allocated) return TRUE; if (texture->components == COGL_TEXTURE_COMPONENTS_RG && !cogl_has_feature (texture->context, COGL_FEATURE_ID_TEXTURE_RG)) - _cogl_set_error (error, - COGL_TEXTURE_ERROR, - COGL_TEXTURE_ERROR_FORMAT, - "A red-green texture was requested but the driver " - "does not support them"); + g_set_error (error, + COGL_TEXTURE_ERROR, + COGL_TEXTURE_ERROR_FORMAT, + "A red-green texture was requested but the driver " + "does not support them"); texture->allocated = texture->vtable->allocate (texture, error); @@ -1208,7 +1192,7 @@ void cogl_texture_set_components (CoglTexture *texture, CoglTextureComponents components) { - _COGL_RETURN_IF_FAIL (!texture->allocated); + g_return_if_fail (!texture->allocated); if (texture->components == components) return; @@ -1224,9 +1208,9 @@ cogl_texture_get_components (CoglTexture *texture) void cogl_texture_set_premultiplied (CoglTexture *texture, - CoglBool premultiplied) + gboolean premultiplied) { - _COGL_RETURN_IF_FAIL (!texture->allocated); + g_return_if_fail (!texture->allocated); premultiplied = !!premultiplied; @@ -1236,7 +1220,7 @@ cogl_texture_set_premultiplied (CoglTexture *texture, texture->premultiplied = premultiplied; } -CoglBool +gboolean cogl_texture_get_premultiplied (CoglTexture *texture) { return texture->premultiplied; diff --git a/cogl/cogl/cogl-texture.h b/cogl/cogl/cogl-texture.h index 61ee52be8..c86b4e3a5 100644 --- a/cogl/cogl/cogl-texture.h +++ b/cogl/cogl/cogl-texture.h @@ -38,7 +38,7 @@ /* We forward declare the CoglTexture type here to avoid some circular * dependency issues with the following headers. */ -#if defined(__COGL_H_INSIDE__) && !defined(COGL_ENABLE_MUFFIN_API) && \ +#if defined(__COGL_H_INSIDE__) && !defined(COGL_ENABLE_MUTTER_API) && \ !defined(COGL_GIR_SCANNING) /* For the public C api we typedef interface types as void to avoid needing * lots of casting in code and instead we will rely on runtime type checking @@ -53,11 +53,12 @@ typedef struct _CoglTexture CoglTexture; #include #include #include +#include #include #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS /** * SECTION:cogl-texture @@ -75,12 +76,13 @@ COGL_BEGIN_DECLS * * Returns: a #GType that can be used with the GLib type system. */ +COGL_EXPORT GType cogl_texture_get_gtype (void); /** * COGL_TEXTURE_ERROR: * - * #CoglError domain for texture errors. + * #GError domain for texture errors. * * Since: 1.8 * Stability: Unstable @@ -99,31 +101,15 @@ GType cogl_texture_get_gtype (void); * Since: 1.8 * Stability: Unstable */ -typedef enum { +typedef enum +{ COGL_TEXTURE_ERROR_SIZE, COGL_TEXTURE_ERROR_FORMAT, COGL_TEXTURE_ERROR_BAD_PARAMETER, COGL_TEXTURE_ERROR_TYPE } CoglTextureError; -/** - * CoglTextureType: - * @COGL_TEXTURE_TYPE_2D: A #CoglTexture2D - * @COGL_TEXTURE_TYPE_3D: A #CoglTexture3D - * @COGL_TEXTURE_TYPE_RECTANGLE: A #CoglTextureRectangle - * - * Constants representing the underlying hardware texture type of a - * #CoglTexture. - * - * Stability: unstable - * Since: 1.10 - */ -typedef enum { - COGL_TEXTURE_TYPE_2D, - COGL_TEXTURE_TYPE_3D, - COGL_TEXTURE_TYPE_RECTANGLE -} CoglTextureType; - +COGL_EXPORT uint32_t cogl_texture_error_quark (void); /** @@ -135,7 +121,7 @@ uint32_t cogl_texture_error_quark (void); * Return value: %TRUE if the @object references a texture, and * %FALSE otherwise */ -CoglBool +COGL_EXPORT gboolean cogl_is_texture (void *object); /** @@ -187,7 +173,7 @@ typedef enum _CoglTextureComponents * * Since: 1.18 */ -void +COGL_EXPORT void cogl_texture_set_components (CoglTexture *texture, CoglTextureComponents components); @@ -205,7 +191,7 @@ cogl_texture_set_components (CoglTexture *texture, * * Since: 1.18 */ -CoglTextureComponents +COGL_EXPORT CoglTextureComponents cogl_texture_get_components (CoglTexture *texture); /** @@ -239,9 +225,9 @@ cogl_texture_get_components (CoglTexture *texture); * * Since: 1.18 */ -void +COGL_EXPORT void cogl_texture_set_premultiplied (CoglTexture *texture, - CoglBool premultiplied); + gboolean premultiplied); /** * cogl_texture_get_premultiplied: @@ -258,7 +244,7 @@ cogl_texture_set_premultiplied (CoglTexture *texture, * value or %FALSE if not. * Since: 1.18 */ -CoglBool +COGL_EXPORT gboolean cogl_texture_get_premultiplied (CoglTexture *texture); /** @@ -269,7 +255,7 @@ cogl_texture_get_premultiplied (CoglTexture *texture); * * Return value: the width of the GPU side texture in pixels */ -unsigned int +COGL_EXPORT unsigned int cogl_texture_get_width (CoglTexture *texture); /** @@ -280,7 +266,7 @@ cogl_texture_get_width (CoglTexture *texture); * * Return value: the height of the GPU side texture in pixels */ -unsigned int +COGL_EXPORT unsigned int cogl_texture_get_height (CoglTexture *texture); /** @@ -292,7 +278,7 @@ cogl_texture_get_height (CoglTexture *texture); * * Return value: the maximum waste */ -int +COGL_EXPORT int cogl_texture_get_max_waste (CoglTexture *texture); /** @@ -305,7 +291,7 @@ cogl_texture_get_max_waste (CoglTexture *texture); * Return value: %TRUE if the texture is sliced, %FALSE if the texture * is stored as a single GPU texture */ -CoglBool +COGL_EXPORT gboolean cogl_texture_is_sliced (CoglTexture *texture); /** @@ -324,7 +310,7 @@ cogl_texture_is_sliced (CoglTexture *texture); * Return value: %TRUE if the handle was successfully retrieved, %FALSE * if the handle was invalid */ -CoglBool +COGL_EXPORT gboolean cogl_texture_get_gl_texture (CoglTexture *texture, unsigned int *out_gl_handle, unsigned int *out_gl_target); @@ -336,8 +322,8 @@ cogl_texture_get_gl_texture (CoglTexture *texture, * @rowstride: the rowstride of @data in bytes or pass 0 to calculate * from the bytes-per-pixel of @format multiplied by the * @texture width. - * @data: memory location to write the @texture's contents, or %NULL - * to only query the data size through the return value. + * @data: (array) (nullable): memory location to write the @texture's contents, + * or %NULL to only query the data size through the return value. * * Copies the pixel data from a cogl texture to system memory. * @@ -348,7 +334,7 @@ cogl_texture_get_gl_texture (CoglTexture *texture, * * Return value: the size of the texture data in bytes */ -int +COGL_EXPORT int cogl_texture_get_data (CoglTexture *texture, CoglPixelFormat format, unsigned int rowstride, @@ -370,7 +356,7 @@ cogl_texture_get_data (CoglTexture *texture, * @format: the #CoglPixelFormat used in the source buffer. * @rowstride: rowstride of source buffer (computed from width if none * specified) - * @data: the actual pixel data. + * @data: (array): the actual pixel data. * * Sets the pixels in a rectangular subregion of @texture from an in-memory * buffer containing pixel data. @@ -380,7 +366,7 @@ cogl_texture_get_data (CoglTexture *texture, * Return value: %TRUE if the subregion upload was successful, and * %FALSE otherwise */ -CoglBool +COGL_EXPORT gboolean cogl_texture_set_region (CoglTexture *texture, int src_x, int src_y, @@ -400,10 +386,10 @@ cogl_texture_set_region (CoglTexture *texture, * @format: the #CoglPixelFormat used in the source @data buffer. * @rowstride: rowstride of the source @data buffer (computed from * the texture width and @format if it equals 0) - * @data: the source data, pointing to the first top-left pixel to set + * @data: (array): the source data, pointing to the first top-left pixel to set * @level: The mipmap level to update (Normally 0 for the largest, * base texture) - * @error: A #CoglError to return exceptional errors + * @error: A #GError to return exceptional errors * * Sets all the pixels for a given mipmap @level by copying the pixel * data pointed to by the @data argument into the given @texture. @@ -446,13 +432,13 @@ cogl_texture_set_region (CoglTexture *texture, * Return value: %TRUE if the data upload was successful, and * %FALSE otherwise */ -CoglBool +COGL_EXPORT gboolean cogl_texture_set_data (CoglTexture *texture, CoglPixelFormat format, int rowstride, const uint8_t *data, int level, - CoglError **error); + GError **error); /** * cogl_texture_set_region_from_bitmap: @@ -479,7 +465,7 @@ cogl_texture_set_data (CoglTexture *texture, * Since: 1.8 * Stability: unstable */ -CoglBool +COGL_EXPORT gboolean cogl_texture_set_region_from_bitmap (CoglTexture *texture, int src_x, int src_y, @@ -492,7 +478,7 @@ cogl_texture_set_region_from_bitmap (CoglTexture *texture, /** * cogl_texture_allocate: * @texture: A #CoglTexture - * @error: A #CoglError to return exceptional errors or %NULL + * @error: A #GError to return exceptional errors or %NULL * * Explicitly allocates the storage for the given @texture which * allows you to be sure that there is enough memory for the @@ -507,10 +493,16 @@ cogl_texture_set_region_from_bitmap (CoglTexture *texture, * otherwise %FALSE and @error will be updated if it * wasn't %NULL. */ -CoglBool +COGL_EXPORT gboolean cogl_texture_allocate (CoglTexture *texture, - CoglError **error); + GError **error); + +/** + * cogl_texture_is_get_data_supported: (skip) + */ +COGL_EXPORT gboolean +cogl_texture_is_get_data_supported (CoglTexture *texture); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_TEXTURE_H__ */ diff --git a/cogl/cogl/cogl-trace.c b/cogl/cogl/cogl-trace.c new file mode 100644 index 000000000..ffe42edeb --- /dev/null +++ b/cogl/cogl/cogl-trace.c @@ -0,0 +1,303 @@ +/* + * Copyright 2018 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#include "cogl-config.h" + +#include "cogl/cogl-trace.h" + +#ifdef HAVE_TRACING + +#include +#include +#include +#include +#include +#include + +#define COGL_TRACE_OUTPUT_FILE "cogl-trace-sp-capture.syscap" +#define BUFFER_LENGTH (4096 * 4) + +struct _CoglTraceContext +{ + SysprofCaptureWriter *writer; +}; + +typedef struct _CoglTraceThreadContext +{ + int cpu_id; + GPid pid; + char *group; +} CoglTraceThreadContext; + +typedef struct +{ + int fd; + char *filename; + char *group; +} TraceData; + +static void +trace_data_free (gpointer user_data) +{ + TraceData *data = user_data; + + data->fd = -1; + g_clear_pointer (&data->group, g_free); + g_clear_pointer (&data->filename, g_free); + g_free (data); +} + +static void cogl_trace_thread_context_free (gpointer data); + +GPrivate cogl_trace_thread_data = G_PRIVATE_INIT (cogl_trace_thread_context_free); +CoglTraceContext *cogl_trace_context; +GMutex cogl_trace_mutex; + +static CoglTraceContext * +cogl_trace_context_new (int fd, + const char *filename) +{ + CoglTraceContext *context; + SysprofCaptureWriter *writer; + + if (fd != -1) + { + g_debug ("Initializing trace context with fd=%d", fd); + writer = sysprof_capture_writer_new_from_fd (fd, BUFFER_LENGTH); + } + else if (filename != NULL) + { + g_debug ("Initializing trace context with filename='%s'", filename); + writer = sysprof_capture_writer_new (filename, BUFFER_LENGTH); + } + else + { + g_debug ("Initializing trace context with default filename"); + writer = sysprof_capture_writer_new (COGL_TRACE_OUTPUT_FILE, BUFFER_LENGTH); + } + + context = g_new0 (CoglTraceContext, 1); + context->writer = writer; + return context; +} + +static void +cogl_trace_context_free (CoglTraceContext *trace_context) +{ + g_clear_pointer (&trace_context->writer, sysprof_capture_writer_unref); + g_free (trace_context); +} + +static void +ensure_trace_context (TraceData *data) +{ + g_mutex_lock (&cogl_trace_mutex); + if (!cogl_trace_context) + cogl_trace_context = cogl_trace_context_new (data->fd, data->filename); + g_mutex_unlock (&cogl_trace_mutex); +} + +static CoglTraceThreadContext * +cogl_trace_thread_context_new (const char *group) +{ + CoglTraceThreadContext *thread_context; + pid_t tid; + + tid = (pid_t) syscall (SYS_gettid); + + thread_context = g_new0 (CoglTraceThreadContext, 1); + thread_context->cpu_id = -1; + thread_context->pid = getpid (); + thread_context->group = + group ? g_strdup (group) : g_strdup_printf ("t:%d", tid); + + return thread_context; +} + +static gboolean +enable_tracing_idle_callback (gpointer user_data) +{ + CoglTraceThreadContext *thread_context = + g_private_get (&cogl_trace_thread_data); + TraceData *data = user_data; + + ensure_trace_context (data); + + if (thread_context) + { + g_warning ("Tracing already enabled"); + return G_SOURCE_REMOVE; + } + + thread_context = cogl_trace_thread_context_new (data->group); + g_private_set (&cogl_trace_thread_data, thread_context); + + return G_SOURCE_REMOVE; +} + +static void +cogl_trace_thread_context_free (gpointer data) +{ + CoglTraceThreadContext *thread_context = data; + + if (!thread_context) + return; + + g_free (thread_context->group); + g_free (thread_context); +} + +static gboolean +disable_tracing_idle_callback (gpointer user_data) +{ + CoglTraceThreadContext *thread_context = + g_private_get (&cogl_trace_thread_data); + CoglTraceContext *trace_context; + + if (!thread_context) + { + g_warning ("Tracing not enabled"); + return G_SOURCE_REMOVE; + } + + g_private_replace (&cogl_trace_thread_data, NULL); + + g_mutex_lock (&cogl_trace_mutex); + trace_context = cogl_trace_context; + sysprof_capture_writer_flush (trace_context->writer); + + g_clear_pointer (&cogl_trace_context, cogl_trace_context_free); + + g_mutex_unlock (&cogl_trace_mutex); + + return G_SOURCE_REMOVE; +} + +static void +set_tracing_enabled_on_thread (GMainContext *main_context, + const char *group, + int fd, + const char *filename) +{ + TraceData *data; + GSource *source; + + data = g_new0 (TraceData, 1); + data->fd = fd; + data->group = group ? strdup (group) : NULL; + data->filename = filename ? strdup (filename) : NULL; + + source = g_idle_source_new (); + + g_source_set_callback (source, + enable_tracing_idle_callback, + data, + trace_data_free); + + g_source_attach (source, main_context); + g_source_unref (source); +} + +void +cogl_set_tracing_enabled_on_thread_with_fd (GMainContext *main_context, + const char *group, + int fd) +{ + set_tracing_enabled_on_thread (main_context, group, fd, NULL); +} + +void +cogl_set_tracing_enabled_on_thread (GMainContext *main_context, + const char *group, + const char *filename) +{ + set_tracing_enabled_on_thread (main_context, group, -1, filename); +} + +void +cogl_set_tracing_disabled_on_thread (GMainContext *main_context) +{ + GSource *source; + + source = g_idle_source_new (); + + g_source_set_callback (source, disable_tracing_idle_callback, NULL, NULL); + + g_source_attach (source, main_context); + g_source_unref (source); +} + +void +cogl_trace_end (CoglTraceHead *head) +{ + SysprofTimeStamp end_time; + CoglTraceContext *trace_context; + CoglTraceThreadContext *trace_thread_context; + + end_time = g_get_monotonic_time () * 1000; + trace_context = cogl_trace_context; + trace_thread_context = g_private_get (&cogl_trace_thread_data); + + g_mutex_lock (&cogl_trace_mutex); + if (!sysprof_capture_writer_add_mark (trace_context->writer, + head->begin_time, + trace_thread_context->cpu_id, + trace_thread_context->pid, + (uint64_t) end_time - head->begin_time, + trace_thread_context->group, + head->name, + NULL)) + { + /* XXX: g_main_context_get_thread_default() might be wrong, it probably + * needs to store the GMainContext in CoglTraceThreadContext when creating + * and use it here. + */ + if (errno == EPIPE) + cogl_set_tracing_disabled_on_thread (g_main_context_get_thread_default ()); + } + g_mutex_unlock (&cogl_trace_mutex); +} + +#else + +#include +#include + +void +cogl_set_tracing_enabled_on_thread_with_fd (void *data, + const char *group, + int fd) +{ + fprintf (stderr, "Tracing not enabled"); +} + +void +cogl_set_tracing_enabled_on_thread (void *data, + const char *group, + const char *filename) +{ + fprintf (stderr, "Tracing not enabled"); +} + +void +cogl_set_tracing_disabled_on_thread (void *data) +{ + fprintf (stderr, "Tracing not enabled"); +} + +#endif /* HAVE_TRACING */ diff --git a/cogl/cogl/cogl-trace.h b/cogl/cogl/cogl-trace.h new file mode 100644 index 000000000..1f0a5ec34 --- /dev/null +++ b/cogl/cogl/cogl-trace.h @@ -0,0 +1,117 @@ +/* + * Copyright 2018 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#ifndef COGL_TRACE_H +#define COGL_TRACE_H + +#include +#include +#include + +#include "cogl/cogl-defines.h" +#include "cogl/cogl-macros.h" + +#ifdef COGL_HAS_TRACING + +typedef struct _CoglTraceContext CoglTraceContext; + +typedef struct _CoglTraceHead +{ + uint64_t begin_time; + const char *name; +} CoglTraceHead; + +COGL_EXPORT +GPrivate cogl_trace_thread_data; +COGL_EXPORT +CoglTraceContext *cogl_trace_context; +COGL_EXPORT +GMutex cogl_trace_mutex; + +COGL_EXPORT void +cogl_set_tracing_enabled_on_thread_with_fd (GMainContext *main_context, + const char *group, + int fd); + +COGL_EXPORT void +cogl_set_tracing_enabled_on_thread (GMainContext *main_context, + const char *group, + const char *filename); + +COGL_EXPORT void +cogl_set_tracing_disabled_on_thread (GMainContext *main_context); + +static inline void +cogl_trace_begin (CoglTraceHead *head, + const char *name) +{ + head->begin_time = g_get_monotonic_time () * 1000; + head->name = name; +} + +COGL_EXPORT void +cogl_trace_end (CoglTraceHead *head); + +static inline void +cogl_auto_trace_end_helper (CoglTraceHead **head) +{ + if (*head) + cogl_trace_end (*head); +} + +#define COGL_TRACE_BEGIN(Name, description) \ + CoglTraceHead CoglTrace##Name = { 0 }; \ + if (g_private_get (&cogl_trace_thread_data)) \ + cogl_trace_begin (&CoglTrace##Name, description); \ + +#define COGL_TRACE_END(Name)\ + if (g_private_get (&cogl_trace_thread_data)) \ + cogl_trace_end (&CoglTrace##Name); + +#define COGL_TRACE_BEGIN_SCOPED(Name, description) \ + CoglTraceHead CoglTrace##Name = { 0 }; \ + __attribute__((cleanup (cogl_auto_trace_end_helper))) \ + CoglTraceHead *ScopedCoglTrace##Name = NULL; \ + if (g_private_get (&cogl_trace_thread_data)) \ + { \ + cogl_trace_begin (&CoglTrace##Name, description); \ + ScopedCoglTrace##Name = &CoglTrace##Name; \ + } + +#else /* COGL_HAS_TRACING */ + +#include + +#define COGL_TRACE_BEGIN(Name, description) (void) 0 +#define COGL_TRACE_END(Name) (void) 0 +#define COGL_TRACE_BEGIN_SCOPED(Name, description) (void) 0 + +COGL_EXPORT void +cogl_set_tracing_enabled_on_thread_with_fd (void *data, + const char *group, + int fd); +COGL_EXPORT void +cogl_set_tracing_enabled_on_thread (void *data, + const char *group, + const char *filename); +COGL_EXPORT void +cogl_set_tracing_disabled_on_thread (void *data); + +#endif /* COGL_HAS_TRACING */ + +#endif /* COGL_TRACE_H */ diff --git a/cogl/cogl/cogl-types.h b/cogl/cogl/cogl-types.h index f67895dd9..495070e9d 100644 --- a/cogl/cogl/cogl-types.h +++ b/cogl/cogl/cogl-types.h @@ -39,20 +39,12 @@ #include #include +#include #include #include -/* Guard C code in headers, while including them from C++ */ -#ifdef __cplusplus -#define COGL_BEGIN_DECLS extern "C" { -#define COGL_END_DECLS } -#else -#define COGL_BEGIN_DECLS -#define COGL_END_DECLS -#endif - -COGL_BEGIN_DECLS +G_BEGIN_DECLS /** * SECTION:cogl-types @@ -61,32 +53,6 @@ COGL_BEGIN_DECLS * General types used by various Cogl functions. */ -/** - * CoglBool: - * - * A boolean data type used throughout the Cogl C api. This should be - * used in conjunction with the %TRUE and %FALSE macro defines for - * setting and testing boolean values. - * - * Since: 2.0 - * Stability: stable - */ -typedef int CoglBool; - -#if __GNUC__ >= 4 -#define COGL_GNUC_NULL_TERMINATED __attribute__((__sentinel__)) -#else -#define COGL_GNUC_NULL_TERMINATED -#endif - -#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) && \ - !defined (COGL_COMPILATION) -#define COGL_GNUC_DEPRECATED \ - __attribute__((__deprecated__)) -#else -#define COGL_GNUC_DEPRECATED -#endif /* __GNUC__ */ - /* Some structures are meant to be opaque but they have public definitions because we want the size to be public so they can be allocated on the stack. This macro is used to ensure that users @@ -115,60 +81,14 @@ typedef struct { \ */ typedef void * CoglHandle; -/** - * COGL_INVALID_HANDLE: - * - * A COGL handle that is not valid, used for unitialized handles as well as - * error conditions. - */ -#define COGL_INVALID_HANDLE NULL - #define COGL_TYPE_HANDLE (cogl_handle_get_type ()) -GType +COGL_EXPORT GType cogl_handle_get_type (void) G_GNUC_CONST; -/** - * cogl_handle_ref: - * @handle: a #CoglHandle - * - * Increases the reference count of @handle by 1 - * - * Return value: (transfer none): the handle, with its reference count increased - */ -CoglHandle -cogl_handle_ref (CoglHandle handle); - -/** - * cogl_handle_unref: - * @handle: a #CoglHandle - * - * Drecreases the reference count of @handle by 1; if the reference - * count reaches 0, the resources allocated by @handle will be freed - */ -void -cogl_handle_unref (CoglHandle handle); - -/** - * CoglFuncPtr: - * - * The type used by cogl for function pointers, note that this type - * is used as a generic catch-all cast for function pointers and the - * actual arguments and return type may be different. - */ -typedef void (* CoglFuncPtr) (void); - /* We forward declare this in cogl-types to avoid circular dependencies - * between cogl-matrix.h, cogl-euler.h and cogl-quaterion.h */ + * between cogl-matrix.h and cogl-quaterion.h */ typedef struct _CoglMatrix CoglMatrix; -/* Same as above we forward declared CoglQuaternion to avoid - * circular dependencies. */ -typedef struct _CoglQuaternion CoglQuaternion; - -/* Same as above we forward declared CoglEuler to avoid - * circular dependencies. */ -typedef struct _CoglEuler CoglEuler; - /** * CoglAngle: * @@ -182,6 +102,14 @@ typedef int32_t CoglAngle; typedef struct _CoglColor CoglColor; typedef struct _CoglTextureVertex CoglTextureVertex; +/** + * CoglDmaBufHandle: (skip) + * + * An opaque type that tracks the lifetime of a DMA buffer fd. Release + * with cogl_dma_buf_handle_free(). + */ +typedef struct _CoglDmaBufHandle CoglDmaBufHandle; + /* Enum declarations */ #define COGL_A_BIT (1 << 4) @@ -191,246 +119,6 @@ typedef struct _CoglTextureVertex CoglTextureVertex; #define COGL_DEPTH_BIT (1 << 8) #define COGL_STENCIL_BIT (1 << 9) -/* XXX: Notes to those adding new formats here... - * - * First this diagram outlines how we allocate the 32bits of a - * CoglPixelFormat currently... - * - * 6 bits for flags - * |-----| - * enum unused 4 bits for the bytes-per-pixel - * and component alignment info - * |------| |-------------| |--| - * 00000000 xxxxxxxx xxxxxxSD PFBA0000 - * ^ stencil - * ^ depth - * ^ premult - * ^ alpha first - * ^ bgr order - * ^ has alpha - * - * The most awkward part about the formats is how we use the last 4 - * bits to encode the bytes per pixel and component alignment - * information. Ideally we should have had 3 bits for the bpp and a - * flag for alignment but we didn't plan for that in advance so we - * instead use a small lookup table to query the bpp and whether the - * components are byte aligned or not. - * - * The mapping is the following (see discussion on bug #660188): - * - * 0 = undefined - * 1, 8 = 1 bpp (e.g. A_8, G_8) - * 2 = 3 bpp, aligned (e.g. 888) - * 3 = 4 bpp, aligned (e.g. 8888) - * 4-6 = 2 bpp, not aligned (e.g. 565, 4444, 5551) - * 7 = YUV: undefined bpp, undefined alignment - * 9 = 2 bpp, aligned - * 10 = depth, aligned (8, 16, 24, 32, 32f) - * 11 = undefined - * 12 = 3 bpp, not aligned - * 13 = 4 bpp, not aligned (e.g. 2101010) - * 14-15 = undefined - * - * Note: the gap at 10-11 is just because we wanted to maintain that - * all non-aligned formats have the third bit set in case that's - * useful later. - * - * Since we don't want to waste bits adding more and more flags, we'd - * like to see most new pixel formats that can't be represented - * uniquely with the existing flags in the least significant byte - * simply be enumerated with sequential values in the most significant - * enum byte. - * - * Note: Cogl avoids exposing any padded XRGB or RGBX formats and - * instead we leave it up to applications to decided whether they - * consider the A component as padding or valid data. We shouldn't - * change this policy without good reasoning. - * - * So to add a new format: - * 1) Use the mapping table above to figure out what to but in - * the lowest nibble. - * 2) OR in the COGL_PREMULT_BIT, COGL_AFIRST_BIT, COGL_A_BIT and - * COGL_BGR_BIT flags as appropriate. - * 3) If the result is not yet unique then also combine with an - * increment of the last sequence number in the most significant - * byte. - * - * The last sequence number used was 0 (i.e. no formats currently need - * a sequence number) - * Update this note whenever a new sequence number is used. - */ -/** - * CoglPixelFormat: - * @COGL_PIXEL_FORMAT_ANY: Any format - * @COGL_PIXEL_FORMAT_A_8: 8 bits alpha mask - * @COGL_PIXEL_FORMAT_RG_88: RG, 16 bits. Note that red-green textures - * are only available if %COGL_FEATURE_ID_TEXTURE_RG is advertised. - * See cogl_texture_set_components() for details. - * @COGL_PIXEL_FORMAT_RGB_565: RGB, 16 bits - * @COGL_PIXEL_FORMAT_RGBA_4444: RGBA, 16 bits - * @COGL_PIXEL_FORMAT_RGBA_5551: RGBA, 16 bits - * @COGL_PIXEL_FORMAT_YUV: Not currently supported - * @COGL_PIXEL_FORMAT_G_8: Single luminance component - * @COGL_PIXEL_FORMAT_RGB_888: RGB, 24 bits - * @COGL_PIXEL_FORMAT_BGR_888: BGR, 24 bits - * @COGL_PIXEL_FORMAT_RGBA_8888: RGBA, 32 bits - * @COGL_PIXEL_FORMAT_BGRA_8888: BGRA, 32 bits - * @COGL_PIXEL_FORMAT_ARGB_8888: ARGB, 32 bits - * @COGL_PIXEL_FORMAT_ABGR_8888: ABGR, 32 bits - * @COGL_PIXEL_FORMAT_RGBA_1010102 : RGBA, 32 bits, 10 bpc - * @COGL_PIXEL_FORMAT_BGRA_1010102 : BGRA, 32 bits, 10 bpc - * @COGL_PIXEL_FORMAT_ARGB_2101010 : ARGB, 32 bits, 10 bpc - * @COGL_PIXEL_FORMAT_ABGR_2101010 : ABGR, 32 bits, 10 bpc - * @COGL_PIXEL_FORMAT_RGBA_8888_PRE: Premultiplied RGBA, 32 bits - * @COGL_PIXEL_FORMAT_BGRA_8888_PRE: Premultiplied BGRA, 32 bits - * @COGL_PIXEL_FORMAT_ARGB_8888_PRE: Premultiplied ARGB, 32 bits - * @COGL_PIXEL_FORMAT_ABGR_8888_PRE: Premultiplied ABGR, 32 bits - * @COGL_PIXEL_FORMAT_RGBA_4444_PRE: Premultiplied RGBA, 16 bits - * @COGL_PIXEL_FORMAT_RGBA_5551_PRE: Premultiplied RGBA, 16 bits - * @COGL_PIXEL_FORMAT_RGBA_1010102_PRE: Premultiplied RGBA, 32 bits, 10 bpc - * @COGL_PIXEL_FORMAT_BGRA_1010102_PRE: Premultiplied BGRA, 32 bits, 10 bpc - * @COGL_PIXEL_FORMAT_ARGB_2101010_PRE: Premultiplied ARGB, 32 bits, 10 bpc - * @COGL_PIXEL_FORMAT_ABGR_2101010_PRE: Premultiplied ABGR, 32 bits, 10 bpc - * - * Pixel formats used by Cogl. For the formats with a byte per - * component, the order of the components specify the order in - * increasing memory addresses. So for example - * %COGL_PIXEL_FORMAT_RGB_888 would have the red component in the - * lowest address, green in the next address and blue after that - * regardless of the endianness of the system. - * - * For the formats with non byte aligned components the component - * order specifies the order within a 16-bit or 32-bit number from - * most significant bit to least significant. So for - * %COGL_PIXEL_FORMAT_RGB_565, the red component would be in bits - * 11-15, the green component would be in 6-11 and the blue component - * would be in 1-5. Therefore the order in memory depends on the - * endianness of the system. - * - * When uploading a texture %COGL_PIXEL_FORMAT_ANY can be used as the - * internal format. Cogl will try to pick the best format to use - * internally and convert the texture data if necessary. - * - * Since: 0.8 - */ -typedef enum { /*< prefix=COGL_PIXEL_FORMAT >*/ - COGL_PIXEL_FORMAT_ANY = 0, - COGL_PIXEL_FORMAT_A_8 = 1 | COGL_A_BIT, - - COGL_PIXEL_FORMAT_RGB_565 = 4, - COGL_PIXEL_FORMAT_RGBA_4444 = 5 | COGL_A_BIT, - COGL_PIXEL_FORMAT_RGBA_5551 = 6 | COGL_A_BIT, - COGL_PIXEL_FORMAT_YUV = 7, - COGL_PIXEL_FORMAT_G_8 = 8, - - COGL_PIXEL_FORMAT_RG_88 = 9, - - COGL_PIXEL_FORMAT_RGB_888 = 2, - COGL_PIXEL_FORMAT_BGR_888 = (2 | COGL_BGR_BIT), - - COGL_PIXEL_FORMAT_RGBA_8888 = (3 | COGL_A_BIT), - COGL_PIXEL_FORMAT_BGRA_8888 = (3 | COGL_A_BIT | COGL_BGR_BIT), - COGL_PIXEL_FORMAT_ARGB_8888 = (3 | COGL_A_BIT | COGL_AFIRST_BIT), - COGL_PIXEL_FORMAT_ABGR_8888 = (3 | COGL_A_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT), - - COGL_PIXEL_FORMAT_RGBA_1010102 = (13 | COGL_A_BIT), - COGL_PIXEL_FORMAT_BGRA_1010102 = (13 | COGL_A_BIT | COGL_BGR_BIT), - COGL_PIXEL_FORMAT_ARGB_2101010 = (13 | COGL_A_BIT | COGL_AFIRST_BIT), - COGL_PIXEL_FORMAT_ABGR_2101010 = (13 | COGL_A_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT), - - COGL_PIXEL_FORMAT_RGBA_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT), - COGL_PIXEL_FORMAT_BGRA_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_BGR_BIT), - COGL_PIXEL_FORMAT_ARGB_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_AFIRST_BIT), - COGL_PIXEL_FORMAT_ABGR_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT), - COGL_PIXEL_FORMAT_RGBA_4444_PRE = (COGL_PIXEL_FORMAT_RGBA_4444 | COGL_A_BIT | COGL_PREMULT_BIT), - COGL_PIXEL_FORMAT_RGBA_5551_PRE = (COGL_PIXEL_FORMAT_RGBA_5551 | COGL_A_BIT | COGL_PREMULT_BIT), - - COGL_PIXEL_FORMAT_RGBA_1010102_PRE = (COGL_PIXEL_FORMAT_RGBA_1010102 | COGL_PREMULT_BIT), - COGL_PIXEL_FORMAT_BGRA_1010102_PRE = (COGL_PIXEL_FORMAT_BGRA_1010102 | COGL_PREMULT_BIT), - COGL_PIXEL_FORMAT_ARGB_2101010_PRE = (COGL_PIXEL_FORMAT_ARGB_2101010 | COGL_PREMULT_BIT), - COGL_PIXEL_FORMAT_ABGR_2101010_PRE = (COGL_PIXEL_FORMAT_ABGR_2101010 | COGL_PREMULT_BIT), - - COGL_PIXEL_FORMAT_DEPTH_16 = (9 | COGL_DEPTH_BIT), - COGL_PIXEL_FORMAT_DEPTH_32 = (3 | COGL_DEPTH_BIT), - - COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8 = (3 | COGL_DEPTH_BIT | COGL_STENCIL_BIT) -} CoglPixelFormat; - -/** - * CoglFeatureFlags: - * @COGL_FEATURE_TEXTURE_RECTANGLE: ARB_texture_rectangle support - * @COGL_FEATURE_TEXTURE_NPOT: Non power of two textures are supported - * by the hardware. This is a equivalent to the - * %COGL_FEATURE_TEXTURE_NPOT_BASIC, %COGL_FEATURE_TEXTURE_NPOT_MIPMAP - * and %COGL_FEATURE_TEXTURE_NPOT_REPEAT features combined. - * @COGL_FEATURE_TEXTURE_YUV: ycbcr conversion support - * @COGL_FEATURE_TEXTURE_READ_PIXELS: glReadPixels() support - * @COGL_FEATURE_SHADERS_GLSL: GLSL support - * @COGL_FEATURE_SHADERS_ARBFP: ARBFP support - * @COGL_FEATURE_OFFSCREEN: FBO support - * @COGL_FEATURE_OFFSCREEN_MULTISAMPLE: Multisample support on FBOs - * @COGL_FEATURE_OFFSCREEN_BLIT: Blit support on FBOs - * @COGL_FEATURE_FOUR_CLIP_PLANES: At least 4 clip planes available - * @COGL_FEATURE_STENCIL_BUFFER: Stencil buffer support - * @COGL_FEATURE_VBOS: VBO support - * @COGL_FEATURE_PBOS: PBO support - * @COGL_FEATURE_UNSIGNED_INT_INDICES: Set if - * %COGL_INDICES_TYPE_UNSIGNED_INT is supported in - * cogl_vertex_buffer_indices_new(). - * @COGL_FEATURE_DEPTH_RANGE: cogl_material_set_depth_range() support - * @COGL_FEATURE_TEXTURE_NPOT_BASIC: The hardware supports non power - * of two textures, but you also need to check the - * %COGL_FEATURE_TEXTURE_NPOT_MIPMAP and %COGL_FEATURE_TEXTURE_NPOT_REPEAT - * features to know if the hardware supports npot texture mipmaps - * or repeat modes other than - * %COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE respectively. - * @COGL_FEATURE_TEXTURE_NPOT_MIPMAP: Mipmapping is supported in - * conjuntion with non power of two textures. - * @COGL_FEATURE_TEXTURE_NPOT_REPEAT: Repeat modes other than - * %COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE are supported by the - * hardware. - * @COGL_FEATURE_POINT_SPRITE: Whether - * cogl_material_set_layer_point_sprite_coords_enabled() is supported. - * @COGL_FEATURE_TEXTURE_3D: 3D texture support - * @COGL_FEATURE_MAP_BUFFER_FOR_READ: Whether cogl_buffer_map() is - * supported with CoglBufferAccess including read support. - * @COGL_FEATURE_MAP_BUFFER_FOR_WRITE: Whether cogl_buffer_map() is - * supported with CoglBufferAccess including write support. - * @COGL_FEATURE_DEPTH_TEXTURE: Whether #CoglFramebuffer support rendering the - * depth buffer to a texture. - * - * Flags for the supported features. - * - * Since: 0.8 - */ -typedef enum -{ - COGL_FEATURE_TEXTURE_RECTANGLE = (1 << 1), - COGL_FEATURE_TEXTURE_NPOT = (1 << 2), - COGL_FEATURE_TEXTURE_YUV = (1 << 3), - COGL_FEATURE_TEXTURE_READ_PIXELS = (1 << 4), - COGL_FEATURE_SHADERS_GLSL = (1 << 5), - COGL_FEATURE_OFFSCREEN = (1 << 6), - COGL_FEATURE_OFFSCREEN_MULTISAMPLE = (1 << 7), - COGL_FEATURE_OFFSCREEN_BLIT = (1 << 8), - COGL_FEATURE_FOUR_CLIP_PLANES = (1 << 9), - COGL_FEATURE_STENCIL_BUFFER = (1 << 10), - COGL_FEATURE_VBOS = (1 << 11), - COGL_FEATURE_PBOS = (1 << 12), - COGL_FEATURE_UNSIGNED_INT_INDICES = (1 << 13), - COGL_FEATURE_DEPTH_RANGE = (1 << 14), - COGL_FEATURE_TEXTURE_NPOT_BASIC = (1 << 15), - COGL_FEATURE_TEXTURE_NPOT_MIPMAP = (1 << 16), - COGL_FEATURE_TEXTURE_NPOT_REPEAT = (1 << 17), - COGL_FEATURE_POINT_SPRITE = (1 << 18), - COGL_FEATURE_TEXTURE_3D = (1 << 19), - COGL_FEATURE_SHADERS_ARBFP = (1 << 20), - COGL_FEATURE_MAP_BUFFER_FOR_READ = (1 << 21), - COGL_FEATURE_MAP_BUFFER_FOR_WRITE = (1 << 22), - COGL_FEATURE_ONSCREEN_MULTIPLE = (1 << 23), - COGL_FEATURE_DEPTH_TEXTURE = (1 << 24) -} CoglFeatureFlags; - /** * CoglBufferTarget: * @COGL_WINDOW_BUFFER: FIXME @@ -513,51 +201,18 @@ COGL_STRUCT_SIZE_ASSERT (CoglTextureVertex, 36); * * Since: 1.0 */ -typedef enum { +typedef enum +{ COGL_TEXTURE_NONE = 0, COGL_TEXTURE_NO_AUTO_MIPMAP = 1 << 0, COGL_TEXTURE_NO_SLICING = 1 << 1, COGL_TEXTURE_NO_ATLAS = 1 << 2 } CoglTextureFlags; -/** - * CoglFogMode: - * @COGL_FOG_MODE_LINEAR: Calculates the fog blend factor as: - * |[ - * f = end - eye_distance / end - start - * ]| - * @COGL_FOG_MODE_EXPONENTIAL: Calculates the fog blend factor as: - * |[ - * f = e ^ -(density * eye_distance) - * ]| - * @COGL_FOG_MODE_EXPONENTIAL_SQUARED: Calculates the fog blend factor as: - * |[ - * f = e ^ -(density * eye_distance)^2 - * ]| - * - * The fog mode determines the equation used to calculate the fogging blend - * factor while fogging is enabled. The simplest %COGL_FOG_MODE_LINEAR mode - * determines f as: - * - * |[ - * f = end - eye_distance / end - start - * ]| - * - * Where eye_distance is the distance of the current fragment in eye - * coordinates from the origin. - * - * Since: 1.0 - */ -typedef enum { - COGL_FOG_MODE_LINEAR, - COGL_FOG_MODE_EXPONENTIAL, - COGL_FOG_MODE_EXPONENTIAL_SQUARED -} CoglFogMode; - /** * COGL_BLEND_STRING_ERROR: * - * #CoglError domain for blend string parser errors + * #GError domain for blend string parser errors * * Since: 1.0 */ @@ -575,7 +230,8 @@ typedef enum { * * Since: 1.0 */ -typedef enum { /*< prefix=COGL_BLEND_STRING_ERROR >*/ +typedef enum /*< prefix=COGL_BLEND_STRING_ERROR >*/ +{ COGL_BLEND_STRING_ERROR_PARSE_ERROR, COGL_BLEND_STRING_ERROR_ARGUMENT_PARSE_ERROR, COGL_BLEND_STRING_ERROR_INVALID_ERROR, @@ -601,9 +257,7 @@ cogl_blend_string_error_quark (void); * * * You've tried to use a feature that is not - * advertised by cogl_has_feature(). This could happen if you create - * a 2d texture with a non-power-of-two size when - * %COGL_FEATURE_ID_TEXTURE_NPOT is not advertised. + * advertised by cogl_has_feature(). * The GPU can not handle the configuration you have * requested. An example might be if you try to use too many texture * layers in a single #CoglPipeline @@ -617,12 +271,13 @@ cogl_blend_string_error_quark (void); * Since: 1.4 * Stability: unstable */ -typedef enum { /*< prefix=COGL_ERROR >*/ +typedef enum /*< prefix=COGL_ERROR >*/ +{ COGL_SYSTEM_ERROR_UNSUPPORTED, COGL_SYSTEM_ERROR_NO_MEMORY } CoglSystemError; -uint32_t +COGL_EXPORT uint32_t _cogl_system_error_quark (void); /** @@ -639,7 +294,8 @@ _cogl_system_error_quark (void); * * Since: 1.0 */ -typedef enum { +typedef enum +{ COGL_ATTRIBUTE_TYPE_BYTE = 0x1400, COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE = 0x1401, COGL_ATTRIBUTE_TYPE_SHORT = 0x1402, @@ -663,7 +319,8 @@ typedef enum { * be available if the GL_OES_element_index_uint extension is * advertized. */ -typedef enum { +typedef enum +{ COGL_INDICES_TYPE_UNSIGNED_BYTE, COGL_INDICES_TYPE_UNSIGNED_SHORT, COGL_INDICES_TYPE_UNSIGNED_INT @@ -688,7 +345,8 @@ typedef enum { * * Since: 1.0 */ -typedef enum { +typedef enum +{ COGL_VERTICES_MODE_POINTS = 0x0000, COGL_VERTICES_MODE_LINES = 0x0001, COGL_VERTICES_MODE_LINE_LOOP = 0x0002, @@ -730,7 +388,8 @@ typedef enum { * The test is only done when depth testing is explicitly enabled. (See * cogl_depth_state_set_test_enabled()) */ -typedef enum { +typedef enum +{ COGL_DEPTH_TEST_FUNCTION_NEVER = 0x0200, COGL_DEPTH_TEST_FUNCTION_LESS = 0x0201, COGL_DEPTH_TEST_FUNCTION_EQUAL = 0x0202, @@ -742,7 +401,8 @@ typedef enum { } CoglDepthTestFunction; /* NB: The above definitions are taken from gl.h equivalents */ -typedef enum { /*< prefix=COGL_RENDERER_ERROR >*/ +typedef enum /*< prefix=COGL_RENDERER_ERROR >*/ +{ COGL_RENDERER_ERROR_XLIB_DISPLAY_OPEN, COGL_RENDERER_ERROR_BAD_CONSTRAINT } CoglRendererError; @@ -809,32 +469,6 @@ typedef enum _CoglWinsysFeature COGL_WINSYS_FEATURE_N_FEATURES } CoglWinsysFeature; -/** - * CoglColorMask: - * @COGL_COLOR_MASK_NONE: None of the color channels are masked - * @COGL_COLOR_MASK_RED: Masks the red color channel - * @COGL_COLOR_MASK_GREEN: Masks the green color channel - * @COGL_COLOR_MASK_BLUE: Masks the blue color channel - * @COGL_COLOR_MASK_ALPHA: Masks the alpha color channel - * @COGL_COLOR_MASK_ALL: All of the color channels are masked - * - * Defines a bit mask of color channels. This can be used with - * cogl_pipeline_set_color_mask() for example to define which color - * channels should be written to the current framebuffer when - * drawing something. - */ -typedef enum -{ - COGL_COLOR_MASK_NONE = 0, - COGL_COLOR_MASK_RED = 1L<<0, - COGL_COLOR_MASK_GREEN = 1L<<1, - COGL_COLOR_MASK_BLUE = 1L<<2, - COGL_COLOR_MASK_ALPHA = 1L<<3, - /* XXX: glib-mkenums is a perl script that can't cope if we split - * this onto multiple lines! *sigh* */ - COGL_COLOR_MASK_ALL = (COGL_COLOR_MASK_RED | COGL_COLOR_MASK_GREEN | COGL_COLOR_MASK_BLUE | COGL_COLOR_MASK_ALPHA) -} CoglColorMask; - /** * CoglWinding: * @COGL_WINDING_CLOCKWISE: Vertices are in a clockwise order @@ -860,7 +494,8 @@ typedef enum * * Since: 1.0 */ -typedef enum { +typedef enum +{ COGL_BUFFER_BIT_COLOR = 1L<<0, COGL_BUFFER_BIT_DEPTH = 1L<<1, COGL_BUFFER_BIT_STENCIL = 1L<<2 @@ -874,7 +509,8 @@ typedef enum { * * Since: 1.0 */ -typedef enum { /*< prefix=COGL_READ_PIXELS >*/ +typedef enum /*< prefix=COGL_READ_PIXELS >*/ +{ COGL_READ_PIXELS_COLOR_BUFFER = 1L << 0 } CoglReadPixelsFlags; @@ -887,12 +523,13 @@ typedef enum { /*< prefix=COGL_READ_PIXELS >*/ * Represents how draw should affect the two buffers * of a stereo framebuffer. See cogl_framebuffer_set_stereo_mode(). */ -typedef enum { +typedef enum +{ COGL_STEREO_BOTH, COGL_STEREO_LEFT, COGL_STEREO_RIGHT } CoglStereoMode; -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_TYPES_H__ */ diff --git a/cogl/cogl/cogl-util.c b/cogl/cogl/cogl-util.c index f26c8961a..84a8c5c30 100644 --- a/cogl/cogl/cogl-util.c +++ b/cogl/cogl/cogl-util.c @@ -28,9 +28,7 @@ * */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include @@ -46,7 +44,7 @@ * Return value: @a if @a is already a power of two, otherwise returns * the next nearest power of two. */ -int +COGL_EXPORT int _cogl_util_next_p2 (int a) { int rval = 1; @@ -67,70 +65,6 @@ _cogl_util_one_at_a_time_mix (unsigned int hash) return hash; } -/* The 'ffs' function is part of C99 so it isn't always available */ -#ifndef HAVE_FFS - -int -_cogl_util_ffs (int num) -{ - int i = 1; - - if (num == 0) - return 0; - - while ((num & 1) == 0) - { - num >>= 1; - i++; - } - - return i; -} -#endif /* HAVE_FFS */ - -/* The 'ffsl' is non-standard but when building with GCC we'll use its - builtin instead */ -#ifndef COGL_UTIL_HAVE_BUILTIN_FFSL - -int -_cogl_util_ffsl_wrapper (long int num) -{ - int i = 1; - - if (num == 0) - return 0; - - while ((num & 1) == 0) - { - num >>= 1; - i++; - } - - return i; -} - -#endif /* COGL_UTIL_HAVE_BUILTIN_FFSL */ - -#ifndef COGL_UTIL_HAVE_BUILTIN_POPCOUNTL - -const unsigned char -_cogl_util_popcount_table[256] = - { - 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, - 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, - 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, - 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, - 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, - 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 - }; - -#endif /* COGL_UTIL_HAVE_BUILTIN_POPCOUNTL */ - /* tests/conform/test-bitmask.c tests some cogl internals and includes this * file directly but since these functions depend on other internal Cogl * symbols we hide them from test-bitmask.c @@ -160,8 +94,8 @@ _cogl_util_pixel_format_from_masks_real (unsigned long r_mask, unsigned long g_mask, unsigned long b_mask, int depth, int bpp, - CoglBool check_bgr, - CoglBool check_afirst, + gboolean check_bgr, + gboolean check_afirst, int recursion_depth) { CoglPixelFormat image_format; @@ -229,7 +163,7 @@ _cogl_util_pixel_format_from_masks (unsigned long r_mask, unsigned long g_mask, unsigned long b_mask, int depth, int bpp, - CoglBool byte_order_is_lsb_first) + gboolean byte_order_is_lsb_first) { CoglPixelFormat image_format = _cogl_util_pixel_format_from_masks_real (r_mask, g_mask, b_mask, @@ -261,26 +195,4 @@ _cogl_util_pixel_format_from_masks (unsigned long r_mask, return image_format; } -#ifndef HAVE_MEMMEM - -char * -_cogl_util_memmem (const void *haystack, - size_t haystack_len, - const void *needle, - size_t needle_len) -{ - size_t i; - - if (needle_len > haystack_len) - return NULL; - - for (i = 0; i <= haystack_len - needle_len; i++) - if (!memcmp ((const char *) haystack + i, needle, needle_len)) - return (char *) haystack + i; - - return NULL; -} - -#endif /* HAVE_MEMMEM */ - #endif /* _COGL_IN_TEST_BITMASK */ diff --git a/cogl/cogl/cogl-util.h b/cogl/cogl/cogl-util.h index 85652965e..8ebf01bb9 100644 --- a/cogl/cogl/cogl-util.h +++ b/cogl/cogl/cogl-util.h @@ -35,14 +35,13 @@ #include #include +#include #include "cogl-types.h" #include /* Double check that config.h has been included */ -#if (!defined (PACKAGE_NAME) && \ - !defined (_COGL_IN_TEST_BITMASK) && \ - !defined(COGL_ENABLE_MUFFIN_API)) +#ifndef COGL_CONFIG_H_INCLUDED #error "cogl-config.h must be included before including cogl-util.h" #endif @@ -60,7 +59,7 @@ _cogl_util_next_p2 (int a); It xors the integer reinterpretations of -1.0f and 1.0f. In theory they should only differ by the signbit so that gives a mask for the sign which we can just test against the value */ -static inline CoglBool +static inline gboolean cogl_util_float_signbit (float x) { static const union { float f; uint32_t i; } negative_one = { -1.0f }; @@ -80,7 +79,7 @@ cogl_util_float_signbit (float x) #define COGL_UTIL_NEARBYINT(x) ((int) ((x) < 0.0f ? (x) - 0.5f : (x) + 0.5f)) /* Returns whether the given integer is a power of two */ -static inline CoglBool +static inline gboolean _cogl_util_is_pot (unsigned int num) { /* Make sure there is only one bit set */ @@ -114,78 +113,16 @@ _cogl_util_one_at_a_time_hash (unsigned int hash, unsigned int _cogl_util_one_at_a_time_mix (unsigned int hash); -/* These two builtins are available since GCC 3.4 */ -#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) -#define COGL_UTIL_HAVE_BUILTIN_FFSL -#define COGL_UTIL_HAVE_BUILTIN_POPCOUNTL -#define COGL_UTIL_HAVE_BUILTIN_CLZ -#endif -/* The 'ffs' function is part of C99 so it isn't always available */ -#ifdef HAVE_FFS -#define _cogl_util_ffs ffs -#else -int -_cogl_util_ffs (int num); -#endif - -/* The 'ffsl' function is non-standard but GCC has a builtin for it - since 3.4 which we can use */ -#ifdef COGL_UTIL_HAVE_BUILTIN_FFSL #define _cogl_util_ffsl __builtin_ffsl -#else -/* If ints and longs are the same size we can just use ffs. Hopefully - the compiler will optimise away this conditional */ -#define _cogl_util_ffsl(x) \ - (sizeof (long int) == sizeof (int) ? _cogl_util_ffs ((int) x) : \ - _cogl_util_ffsl_wrapper (x)) -int -_cogl_util_ffsl_wrapper (long int num); -#endif /* COGL_UTIL_HAVE_BUILTIN_FFSL */ static inline unsigned int _cogl_util_fls (unsigned int n) { -#ifdef COGL_UTIL_HAVE_BUILTIN_CLZ return n == 0 ? 0 : sizeof (unsigned int) * 8 - __builtin_clz (n); -#else - unsigned int v = 1; - - if (n == 0) - return 0; - - while (n >>= 1) - v++; - - return v; -#endif } -#ifdef COGL_UTIL_HAVE_BUILTIN_POPCOUNTL #define _cogl_util_popcountl __builtin_popcountl -#else -extern const unsigned char _cogl_util_popcount_table[256]; - -/* There are many ways of doing popcount but doing a table lookup - seems to be the most robust against different sizes for long. Some - pages seem to claim it's the fastest method anyway. */ -static inline int -_cogl_util_popcountl (unsigned long num) -{ - int i; - int sum = 0; - - /* Let's hope GCC will unroll this loop.. */ - for (i = 0; i < sizeof (num); i++) - sum += _cogl_util_popcount_table[(num >> (i * 8)) & 0xff]; - - return sum; -} - -#endif /* COGL_UTIL_HAVE_BUILTIN_POPCOUNTL */ - -#define _COGL_RETURN_IF_FAIL(EXPR) g_return_if_fail(EXPR) -#define _COGL_RETURN_VAL_IF_FAIL(EXPR, VAL) g_return_val_if_fail(EXPR, VAL) /* Match a CoglPixelFormat according to channel masks, color depth, * bits per pixel and byte order. These information are provided by @@ -201,14 +138,6 @@ _cogl_util_pixel_format_from_masks (unsigned long r_mask, int depth, int bpp, int byte_order); -/* Since we can't rely on _Static_assert always being available for - * all compilers we have limited static assert that can be used in - * C code but not in headers. - */ -#define _COGL_TYPEDEF_ASSERT(EXPRESSION) \ - typedef struct { char Compile_Time_Assertion[(EXPRESSION) ? 1 : -1]; } \ - G_PASTE (_GStaticAssert_, __LINE__) - /* _COGL_STATIC_ASSERT: * @expression: An expression to assert evaluates to true at compile * time. @@ -218,26 +147,9 @@ _cogl_util_pixel_format_from_masks (unsigned long r_mask, * Allows you to assert that an expression evaluates to true at * compile time and aborts compilation if not. If possible message * will also be printed if the assertion fails. - * - * Note: Only Gcc >= 4.6 supports the c11 _Static_assert which lets us - * print a nice message if the compile time assertion fails. */ -#ifdef HAVE_STATIC_ASSERT #define _COGL_STATIC_ASSERT(EXPRESSION, MESSAGE) \ _Static_assert (EXPRESSION, MESSAGE); -#else -#define _COGL_STATIC_ASSERT(EXPRESSION, MESSAGE) -#endif - -#ifdef HAVE_MEMMEM -#define _cogl_util_memmem memmem -#else -char * -_cogl_util_memmem (const void *haystack, - size_t haystack_len, - const void *needle, - size_t needle_len); -#endif static inline void _cogl_util_scissor_intersect (int rect_x0, diff --git a/cogl/cogl/cogl-vector.c b/cogl/cogl/cogl-vector.c deleted file mode 100644 index e98d01b96..000000000 --- a/cogl/cogl/cogl-vector.c +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg - */ - -#ifdef HAVE_CONFIG_H -#include "cogl-config.h" -#endif - -#include -#include - -#include -#include -#include - -#define X 0 -#define Y 1 -#define Z 2 -#define W 3 - -void -cogl_vector3_init (float *vector, float x, float y, float z) -{ - vector[X] = x; - vector[Y] = y; - vector[Z] = z; -} - -void -cogl_vector3_init_zero (float *vector) -{ - memset (vector, 0, sizeof (float) * 3); -} - -CoglBool -cogl_vector3_equal (const void *v1, const void *v2) -{ - float *vector0 = (float *)v1; - float *vector1 = (float *)v2; - - _COGL_RETURN_VAL_IF_FAIL (v1 != NULL, FALSE); - _COGL_RETURN_VAL_IF_FAIL (v2 != NULL, FALSE); - - /* There's no point picking an arbitrary epsilon that's appropriate - * for comparing the components so we just use == that will at least - * consider -0 and 0 to be equal. */ - return - vector0[X] == vector1[X] && - vector0[Y] == vector1[Y] && - vector0[Z] == vector1[Z]; -} - -CoglBool -cogl_vector3_equal_with_epsilon (const float *vector0, - const float *vector1, - float epsilon) -{ - _COGL_RETURN_VAL_IF_FAIL (vector0 != NULL, FALSE); - _COGL_RETURN_VAL_IF_FAIL (vector1 != NULL, FALSE); - - if (fabsf (vector0[X] - vector1[X]) < epsilon && - fabsf (vector0[Y] - vector1[Y]) < epsilon && - fabsf (vector0[Z] - vector1[Z]) < epsilon) - return TRUE; - else - return FALSE; -} - -float * -cogl_vector3_copy (const float *vector) -{ - if (vector) - return g_slice_copy (sizeof (float) * 3, vector); - return NULL; -} - -void -cogl_vector3_free (float *vector) -{ - g_slice_free1 (sizeof (float) * 3, vector); -} - -void -cogl_vector3_invert (float *vector) -{ - vector[X] = -vector[X]; - vector[Y] = -vector[Y]; - vector[Z] = -vector[Z]; -} - -void -cogl_vector3_add (float *result, - const float *a, - const float *b) -{ - result[X] = a[X] + b[X]; - result[Y] = a[Y] + b[Y]; - result[Z] = a[Z] + b[Z]; -} - -void -cogl_vector3_subtract (float *result, - const float *a, - const float *b) -{ - result[X] = a[X] - b[X]; - result[Y] = a[Y] - b[Y]; - result[Z] = a[Z] - b[Z]; -} - -void -cogl_vector3_multiply_scalar (float *vector, - float scalar) -{ - vector[X] *= scalar; - vector[Y] *= scalar; - vector[Z] *= scalar; -} - -void -cogl_vector3_divide_scalar (float *vector, - float scalar) -{ - float one_over_scalar = 1.0f / scalar; - vector[X] *= one_over_scalar; - vector[Y] *= one_over_scalar; - vector[Z] *= one_over_scalar; -} - -void -cogl_vector3_normalize (float *vector) -{ - float mag_squared = - vector[X] * vector[X] + - vector[Y] * vector[Y] + - vector[Z] * vector[Z]; - - if (mag_squared > 0.0f) - { - float one_over_mag = 1.0f / sqrtf (mag_squared); - vector[X] *= one_over_mag; - vector[Y] *= one_over_mag; - vector[Z] *= one_over_mag; - } -} - -float -cogl_vector3_magnitude (const float *vector) -{ - return sqrtf (vector[X] * vector[X] + - vector[Y] * vector[Y] + - vector[Z] * vector[Z]); -} - -void -cogl_vector3_cross_product (float *result, - const float *a, - const float *b) -{ - float tmp[3]; - - tmp[X] = a[Y] * b[Z] - a[Z] * b[Y]; - tmp[Y] = a[Z] * b[X] - a[X] * b[Z]; - tmp[Z] = a[X] * b[Y] - a[Y] * b[X]; - result[X] = tmp[X]; - result[Y] = tmp[Y]; - result[Z] = tmp[Z]; -} - -float -cogl_vector3_dot_product (const float *a, const float *b) -{ - return a[X] * b[X] + a[Y] * b[Y] + a[Z] * b[Z]; -} - -float -cogl_vector3_distance (const float *a, const float *b) -{ - float dx = b[X] - a[X]; - float dy = b[Y] - a[Y]; - float dz = b[Z] - a[Z]; - - return sqrtf (dx * dx + dy * dy + dz * dz); -} - -#if 0 -void -cogl_vector4_init (float *vector, float x, float y, float z) -{ - vector[X] = x; - vector[Y] = y; - vector[Z] = z; - vector[W] = w; -} - -void -cogl_vector4_init_zero (float *vector) -{ - memset (vector, 0, sizeof (CoglVector4)); -} - -void -cogl_vector4_init_from_vector4 (float *vector, float *src) -{ - *vector4 = *src; -} - -CoglBool -cogl_vector4_equal (const void *v0, const void *v1) -{ - _COGL_RETURN_VAL_IF_FAIL (v1 != NULL, FALSE); - _COGL_RETURN_VAL_IF_FAIL (v2 != NULL, FALSE); - - return memcmp (v1, v2, sizeof (float) * 4) == 0 ? TRUE : FALSE; -} - -float * -cogl_vector4_copy (float *vector) -{ - if (vector) - return g_slice_dup (CoglVector4, vector); - return NULL; -} - -void -cogl_vector4_free (float *vector) -{ - g_slice_free (CoglVector4, vector); -} - -void -cogl_vector4_invert (float *vector) -{ - vector.x = -vector.x; - vector.y = -vector.y; - vector.z = -vector.z; - vector.w = -vector.w; -} - -void -cogl_vector4_add (float *result, - float *a, - float *b) -{ - result.x = a.x + b.x; - result.y = a.y + b.y; - result.z = a.z + b.z; - result.w = a.w + b.w; -} - -void -cogl_vector4_subtract (float *result, - float *a, - float *b) -{ - result.x = a.x - b.x; - result.y = a.y - b.y; - result.z = a.z - b.z; - result.w = a.w - b.w; -} - -void -cogl_vector4_divide (float *vector, - float scalar) -{ - float one_over_scalar = 1.0f / scalar; - result.x *= one_over_scalar; - result.y *= one_over_scalar; - result.z *= one_over_scalar; - result.w *= one_over_scalar; -} - -#endif diff --git a/cogl/cogl/cogl-vector.h b/cogl/cogl/cogl-vector.h deleted file mode 100644 index 08cf017f8..000000000 --- a/cogl/cogl/cogl-vector.h +++ /dev/null @@ -1,356 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL_VECTOR_H -#define __COGL_VECTOR_H - -COGL_BEGIN_DECLS - -/** - * SECTION:cogl-vector - * @short_description: Functions for handling single precision float - * vectors. - * - * This exposes a utility API that can be used for basic manipulation of 3 - * component float vectors. - */ - -/** - * cogl_vector3_init: - * @vector: The 3 component vector you want to initialize - * @x: The x component - * @y: The y component - * @z: The z component - * - * Initializes a 3 component, single precision float vector which can - * then be manipulated with the cogl_vector convenience APIs. Vectors - * can also be used in places where a "point" is often desired. - * - * Since: 1.4 - * Stability: Unstable - */ -void -cogl_vector3_init (float *vector, float x, float y, float z); - -/** - * cogl_vector3_init_zero: - * @vector: The 3 component vector you want to initialize - * - * Initializes a 3 component, single precision float vector with zero - * for each component. - * - * Since: 1.4 - * Stability: Unstable - */ -void -cogl_vector3_init_zero (float *vector); - -/** - * cogl_vector3_equal: - * @v1: The first 3 component vector you want to compare - * @v2: The second 3 component vector you want to compare - * - * Compares the components of two vectors and returns TRUE if they are - * the same. - * - * The comparison of the components is done with the '==' operator - * such that -0 is considered equal to 0, but otherwise there is no - * fuzziness such as an epsilon to consider vectors that are - * essentially identical except for some minor precision error - * differences due to the way they have been manipulated. - * - * Returns: TRUE if the vectors are equal else FALSE. - * - * Since: 1.4 - * Stability: Unstable - */ -CoglBool -cogl_vector3_equal (const void *v1, const void *v2); - -/** - * cogl_vector3_equal_with_epsilon: - * @vector0: The first 3 component vector you want to compare - * @vector1: The second 3 component vector you want to compare - * @epsilon: The allowable difference between components to still be - * considered equal - * - * Compares the components of two vectors using the given epsilon and - * returns TRUE if they are the same, using an internal epsilon for - * comparing the floats. - * - * Each component is compared against the epsilon value in this way: - * |[ - * if (fabsf (vector0->x - vector1->x) < epsilon) - * ]| - * - * Returns: TRUE if the vectors are equal else FALSE. - * - * Since: 1.4 - * Stability: Unstable - */ -CoglBool -cogl_vector3_equal_with_epsilon (const float *vector0, - const float *vector1, - float epsilon); - -/** - * cogl_vector3_copy: - * @vector: The 3 component vector you want to copy - * - * Allocates a new 3 component float vector on the heap initializing - * the components from the given @vector and returns a pointer to the - * newly allocated vector. You should free the memory using - * cogl_vector3_free() - * - * Returns: A newly allocated 3 component float vector - * - * Since: 1.4 - * Stability: Unstable - */ -float * -cogl_vector3_copy (const float *vector); - -/** - * cogl_vector3_free: - * @vector: The 3 component you want to free - * - * Frees a 3 component vector that was previously allocated with - * cogl_vector3_copy() - * - * Since: 1.4 - * Stability: Unstable - */ -void -cogl_vector3_free (float *vector); - -/** - * cogl_vector3_invert: - * @vector: The 3 component vector you want to manipulate - * - * Inverts/negates all the components of the given @vector. - * - * Since: 1.4 - * Stability: Unstable - */ -void -cogl_vector3_invert (float *vector); - -/** - * cogl_vector3_add: - * @result: Where you want the result written - * @a: The first vector operand - * @b: The second vector operand - * - * Adds each of the corresponding components in vectors @a and @b - * storing the results in @result. - * - * Since: 1.4 - * Stability: Unstable - */ -void -cogl_vector3_add (float *result, - const float *a, - const float *b); - -/** - * cogl_vector3_subtract: - * @result: Where you want the result written - * @a: The first vector operand - * @b: The second vector operand - * - * Subtracts each of the corresponding components in vector @b from - * @a storing the results in @result. - * - * Since: 1.4 - * Stability: Unstable - */ -void -cogl_vector3_subtract (float *result, - const float *a, - const float *b); - -/** - * cogl_vector3_multiply_scalar: - * @vector: The 3 component vector you want to manipulate - * @scalar: The scalar you want to multiply the vector components by - * - * Multiplies each of the @vector components by the given scalar. - * - * Since: 1.4 - * Stability: Unstable - */ -void -cogl_vector3_multiply_scalar (float *vector, - float scalar); - -/** - * cogl_vector3_divide_scalar: - * @vector: The 3 component vector you want to manipulate - * @scalar: The scalar you want to divide the vector components by - * - * Divides each of the @vector components by the given scalar. - * - * Since: 1.4 - * Stability: Unstable - */ -void -cogl_vector3_divide_scalar (float *vector, - float scalar); - -/** - * cogl_vector3_normalize: - * @vector: The 3 component vector you want to manipulate - * - * Updates the vector so it is a "unit vector" such that the - * @vectors magnitude or length is equal to 1. - * - * It's safe to use this function with the [0, 0, 0] vector, it will not - * try to divide components by 0 (its norm) and will leave the vector - * untouched. - * - * Since: 1.4 - * Stability: Unstable - */ -void -cogl_vector3_normalize (float *vector); - -/** - * cogl_vector3_magnitude: - * @vector: The 3 component vector you want the magnitude for - * - * Calculates the scalar magnitude or length of @vector. - * - * Returns: The magnitude of @vector. - * - * Since: 1.4 - * Stability: Unstable - */ -float -cogl_vector3_magnitude (const float *vector); - -/** - * cogl_vector3_cross_product: - * @result: Where you want the result written - * @u: Your first 3 component vector - * @v: Your second 3 component vector - * - * Calculates the cross product between the two vectors @u and @v. - * - * The cross product is a vector perpendicular to both @u and @v. This - * can be useful for calculating the normal of a polygon by creating - * two vectors in its plane using the polygons vertices and taking - * their cross product. - * - * If the two vectors are parallel then the cross product is 0. - * - * You can use a right hand rule to determine which direction the - * perpendicular vector will point: If you place the two vectors tail, - * to tail and imagine grabbing the perpendicular line that extends - * through the common tail with your right hand such that you fingers - * rotate in the direction from @u to @v then the resulting vector - * points along your extended thumb. - * - * Returns: The cross product between two vectors @u and @v. - * - * Since: 1.4 - * Stability: Unstable - */ -void -cogl_vector3_cross_product (float *result, - const float *u, - const float *v); - -/** - * cogl_vector3_dot_product: - * @a: Your first 3 component vector - * @b: Your second 3 component vector - * - * Calculates the dot product of the two 3 component vectors. This - * can be used to determine the magnitude of one vector projected onto - * another. (for example a surface normal) - * - * For example if you have a polygon with a given normal vector and - * some other point for which you want to calculate its distance from - * the polygon, you can create a vector between one of the polygon - * vertices and that point and use the dot product to calculate the - * magnitude for that vector but projected onto the normal of the - * polygon. This way you don't just get the distance from the point to - * the edge of the polygon you get the distance from the point to the - * nearest part of the polygon. - * - * If you don't use a unit length normal in the above example - * then you would then also have to divide the result by the magnitude - * of the normal - * - * The dot product is calculated as: - * |[ - * (a->x * b->x + a->y * b->y + a->z * b->z) - * ]| - * - * For reference, the dot product can also be calculated from the - * angle between two vectors as: - * |[ - * |a||b|cos𝜃 - * ]| - * - * Returns: The dot product of two vectors. - * - * Since: 1.4 - * Stability: Unstable - */ -float -cogl_vector3_dot_product (const float *a, const float *b); - -/** - * cogl_vector3_distance: - * @a: The first point - * @b: The second point - * - * If you consider the two given vectors as (x,y,z) points instead - * then this will compute the distance between those two points. - * - * Returns: The distance between two points given as 3 component - * vectors. - * - * Since: 1.4 - * Stability: Unstable - */ -float -cogl_vector3_distance (const float *a, const float *b); - -COGL_END_DECLS - -#endif /* __COGL_VECTOR_H */ - diff --git a/cogl/cogl/cogl-version.h b/cogl/cogl/cogl-version.h index bc82437ba..089c4998a 100644 --- a/cogl/cogl/cogl-version.h +++ b/cogl/cogl/cogl-version.h @@ -33,84 +33,6 @@ #include -/** - * SECTION:cogl-version - * @short_description: Macros for determining the version of Cogl being used - * - * Cogl offers a set of macros for checking the version of the library - * at compile time. - * - * Cogl adds version information to both API deprecations and additions; - * by definining the macros %COGL_VERSION_MIN_REQUIRED and - * %COGL_VERSION_MAX_ALLOWED, you can specify the range of Cogl versions - * whose API you want to use. Functions that were deprecated before, or - * introduced after, this range will trigger compiler warnings. For instance, - * if we define the following symbols: - * - * |[ - * COGL_VERSION_MIN_REQUIRED = COGL_VERSION_1_6 - * COGL_VERSION_MAX_ALLOWED = COGL_VERSION_1_8 - * ]| - * - * and we have the following functions annotated in the Cogl headers: - * - * |[ - * COGL_DEPRECATED_IN_1_4 void cogl_function_A (void); - * COGL_DEPRECATED_IN_1_6 void cogl_function_B (void); - * COGL_AVAILABLE_IN_1_8 void cogl_function_C (void); - * COGL_AVAILABLE_IN_1_10 void cogl_function_D (void); - * ]| - * - * then any application code using the functions above will get the output: - * - * |[ - * cogl_function_A: deprecation warning - * cogl_function_B: no warning - * cogl_function_C: no warning - * cogl_function_D: symbol not available warning - * ]| - * - * It is possible to disable the compiler warnings by defining the macro - * %COGL_DISABLE_DEPRECATION_WARNINGS before including the cogl.h - * header. - */ - -/** - * COGL_VERSION_MAJOR: - * - * The major version of the Cogl library (1, if %COGL_VERSION is 1.2.3) - * - * Since: 1.12.0 - */ -#define COGL_VERSION_MAJOR COGL_VERSION_MAJOR_INTERNAL - -/** - * COGL_VERSION_MINOR: - * - * The minor version of the Cogl library (2, if %COGL_VERSION is 1.2.3) - * - * Since: 1.12.0 - */ -#define COGL_VERSION_MINOR COGL_VERSION_MINOR_INTERNAL - -/** - * COGL_VERSION_MICRO: - * - * The micro version of the Cogl library (3, if %COGL_VERSION is 1.2.3) - * - * Since: 1.12.0 - */ -#define COGL_VERSION_MICRO COGL_VERSION_MICRO_INTERNAL - -/** - * COGL_VERSION_STRING: - * - * The full version of the Cogl library, in string form (suited for - * string concatenation) - * - * Since: 1.12.0 - */ -#define COGL_VERSION_STRING COGL_VERSION_STRING_INTERNAL /* Macros to handle compacting a 3-component version number into an * int for quick comparison. This assumes all of the components are <= @@ -119,20 +41,6 @@ #define COGL_VERSION_MAX_COMPONENT_VALUE \ ((1 << COGL_VERSION_COMPONENT_BITS) - 1) -/** - * COGL_VERSION: - * - * The Cogl version encoded into a single integer using the - * COGL_VERSION_ENCODE() macro. This can be used for quick comparisons - * with particular versions. - * - * Since: 1.12.0 - */ -#define COGL_VERSION \ - COGL_VERSION_ENCODE (COGL_VERSION_MAJOR, \ - COGL_VERSION_MINOR, \ - COGL_VERSION_MICRO) - /** * COGL_VERSION_ENCODE: * @major: The major part of a version number @@ -221,138 +129,4 @@ #define COGL_VERSION_CHECK(major, minor, micro) \ (COGL_VERSION >= COGL_VERSION_ENCODE (major, minor, micro)) -/** - * COGL_VERSION_1_0: - * - * A macro that evaluates to the 1.0 version of Cogl, in a format - * that can be used by the C pre-processor. - * - * Since: 1.16 - */ -#define COGL_VERSION_1_0 (COGL_VERSION_ENCODE (1, 0, 0)) - -/** - * COGL_VERSION_1_2: - * - * A macro that evaluates to the 1.2 version of Cogl, in a format - * that can be used by the C pre-processor. - * - * Since: 1.16 - */ -#define COGL_VERSION_1_2 (COGL_VERSION_ENCODE (1, 2, 0)) - -/** - * COGL_VERSION_1_4: - * - * A macro that evaluates to the 1.4 version of Cogl, in a format - * that can be used by the C pre-processor. - * - * Since: 1.16 - */ -#define COGL_VERSION_1_4 (COGL_VERSION_ENCODE (1, 4, 0)) - -/** - * COGL_VERSION_1_6: - * - * A macro that evaluates to the 1.6 version of Cogl, in a format - * that can be used by the C pre-processor. - * - * Since: 1.16 - */ -#define COGL_VERSION_1_6 (COGL_VERSION_ENCODE (1, 6, 0)) - -/** - * COGL_VERSION_1_8: - * - * A macro that evaluates to the 1.8 version of Cogl, in a format - * that can be used by the C pre-processor. - * - * Since: 1.16 - */ -#define COGL_VERSION_1_8 (COGL_VERSION_ENCODE (1, 8, 0)) - -/** - * COGL_VERSION_1_10: - * - * A macro that evaluates to the 1.10 version of Cogl, in a format - * that can be used by the C pre-processor. - * - * Since: 1.16 - */ -#define COGL_VERSION_1_10 (COGL_VERSION_ENCODE (1, 10, 0)) - -/** - * COGL_VERSION_1_12: - * - * A macro that evaluates to the 1.12 version of Cogl, in a format - * that can be used by the C pre-processor. - * - * Since: 1.16 - */ -#define COGL_VERSION_1_12 (COGL_VERSION_ENCODE (1, 12, 0)) - -/** - * COGL_VERSION_1_14: - * - * A macro that evaluates to the 1.14 version of Cogl, in a format - * that can be used by the C pre-processor. - * - * Since: 1.16 - */ -#define COGL_VERSION_1_14 (COGL_VERSION_ENCODE (1, 14, 0)) - -/** - * COGL_VERSION_1_16: - * - * A macro that evaluates to the 1.16 version of Cogl, in a format - * that can be used by the C pre-processor. - * - * Since: 1.16 - */ -#define COGL_VERSION_1_16 (COGL_VERSION_ENCODE (1, 16, 0)) - -/** - * COGL_VERSION_1_18: - * - * A macro that evaluates to the 1.18 version of Cogl, in a format - * that can be used by the C pre-processor. - * - * Since: 1.18 - */ -#define COGL_VERSION_1_18 (COGL_VERSION_ENCODE (1, 18, 0)) - -/** - * COGL_VERSION_1_20: - * - * A macro that evaluates to the 1.20 version of Cogl, in a format - * that can be used by the C pre-processor. - * - * Since: 1.20 - */ -#define COGL_VERSION_1_20 (COGL_VERSION_ENCODE (1, 20, 0)) - -/* evaluates to the current stable version; for development cycles, - * this means the next stable target - */ -#if (COGL_VERSION_MINOR_INTERNAL % 2) -#define COGL_VERSION_CURRENT_STABLE \ - (COGL_VERSION_ENCODE (COGL_VERSION_MAJOR_INTERNAL, \ - COGL_VERSION_MINOR_INTERNAL + 1, 0)) -#else -#define COGL_VERSION_CURRENT_STABLE \ - (COGL_VERSION_ENCODE (COGL_VERSION_MAJOR_INTERNAL, \ - COGL_VERSION_MINOR_INTERNAL, 0)) -#endif - -/* evaluates to the previous stable version */ -#if (COGL_VERSION_MINOR_INTERNAL % 2) -#define COGL_VERSION_PREVIOUS_STABLE \ - (COGL_VERSION_ENCODE (COGL_VERSION_MAJOR_INTERNAL, \ - COGL_VERSION_MINOR_INTERNAL - 1, 0)) -#else -#define COGL_VERSION_PREVIOUS_STABLE \ - (COGL_VERSION_ENCODE (COGL_VERSION_MAJOR_INTERNAL, \ - COGL_VERSION_MINOR_INTERNAL - 2, 0)) -#endif - #endif /* __COGL_VERSION_H__ */ diff --git a/cogl/cogl/cogl-wayland-server.h b/cogl/cogl/cogl-wayland-server.h index 271260191..f4d83bc24 100644 --- a/cogl/cogl/cogl-wayland-server.h +++ b/cogl/cogl/cogl-wayland-server.h @@ -52,7 +52,7 @@ #include #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS /** * cogl_wayland_display_set_compositor_display: @@ -66,86 +66,11 @@ COGL_BEGIN_DECLS * Since: 1.10 * Stability: unstable */ -void +COGL_EXPORT void cogl_wayland_display_set_compositor_display (CoglDisplay *display, struct wl_display *wayland_display); -/** - * cogl_wayland_texture_2d_new_from_buffer: - * @ctx: A #CoglContext - * @buffer: A Wayland resource for a buffer - * @error: A #CoglError for exceptions - * - * Uploads the @buffer referenced by the given Wayland resource to a - * #CoglTexture2D. The buffer resource may refer to a wl_buffer or a - * wl_shm_buffer. - * - * The results are undefined for passing an invalid @buffer - * pointer - * It is undefined if future updates to @buffer outside the - * control of Cogl will affect the allocated #CoglTexture2D. In some - * cases the contents of the buffer are copied (such as shm buffers), - * and in other cases the underlying storage is re-used directly (such - * as drm buffers) - * - * Returns: A newly allocated #CoglTexture2D, or if Cogl could not - * validate the @buffer in some way (perhaps because of - * an unsupported format) it will return %NULL and set - * @error. - * - * Since: 1.10 - * Stability: unstable - */ -CoglTexture2D * -cogl_wayland_texture_2d_new_from_buffer (CoglContext *ctx, - struct wl_resource *buffer, - CoglError **error); - -/** - * cogl_wayland_texture_set_region_from_shm_buffer: - * @texture: a #CoglTexture - * @width: The width of the region to copy - * @height: The height of the region to copy - * @shm_buffer: The source buffer - * @src_x: The X offset within the source bufer to copy from - * @src_y: The Y offset within the source bufer to copy from - * @dst_x: The X offset within the texture to copy to - * @dst_y: The Y offset within the texture to copy to - * @level: The mipmap level of the texture to copy to - * @error: A #CoglError to return exceptional errors - * - * Sets the pixels in a rectangular subregion of @texture from a - * Wayland SHM buffer. Generally this would be used in response to - * wl_surface.damage event in a compositor in order to update the - * texture with the damaged region. This is just a convenience wrapper - * around getting the SHM buffer pointer and calling - * cogl_texture_set_region(). See that function for a description of - * the level parameter. - * - * Since the storage for a #CoglTexture is allocated lazily then - * if the given @texture has not previously been allocated then this - * api can return %FALSE and throw an exceptional @error if there is - * not enough memory to allocate storage for @texture. - * - * Return value: %TRUE if the subregion upload was successful, and - * %FALSE otherwise - * Since: 1.18 - * Stability: unstable - */ -CoglBool -cogl_wayland_texture_set_region_from_shm_buffer (CoglTexture *texture, - int src_x, - int src_y, - int width, - int height, - struct wl_shm_buffer * - shm_buffer, - int dst_x, - int dst_y, - int level, - CoglError **error); - -COGL_END_DECLS +G_END_DECLS /* The gobject introspection scanner seems to parse public headers in * isolation which means we need to be extra careful about how we diff --git a/cogl/cogl/cogl-xlib-private.h b/cogl/cogl/cogl-xlib-private.h index 992a32099..317163fb2 100644 --- a/cogl/cogl/cogl-xlib-private.h +++ b/cogl/cogl/cogl-xlib-private.h @@ -45,10 +45,4 @@ struct _CoglXlibTrapState CoglXlibTrapState *old_state; }; -void -_cogl_xlib_query_damage_extension (void); - -int -_cogl_xlib_get_damage_base (void); - #endif /* __COGL_XLIB_PRIVATE_H */ diff --git a/cogl/cogl/cogl-xlib-renderer-private.h b/cogl/cogl/cogl-xlib-renderer-private.h index ea0ee906f..edfa189b7 100644 --- a/cogl/cogl/cogl-xlib-renderer-private.h +++ b/cogl/cogl/cogl-xlib-renderer-private.h @@ -31,6 +31,8 @@ #ifndef __COGL_RENDERER_XLIB_PRIVATE_H #define __COGL_RENDERER_XLIB_PRIVATE_H +#include + #include "cogl-object-private.h" #include "cogl-xlib-private.h" #include "cogl-x11-renderer-private.h" @@ -52,8 +54,8 @@ typedef struct _CoglXlibRenderer XVisualInfo *xvisinfo; } CoglXlibRenderer; -CoglBool -_cogl_xlib_renderer_connect (CoglRenderer *renderer, CoglError **error); +gboolean +_cogl_xlib_renderer_connect (CoglRenderer *renderer, GError **error); void _cogl_xlib_renderer_disconnect (CoglRenderer *renderer); @@ -90,9 +92,6 @@ _cogl_xlib_renderer_untrap_errors (CoglRenderer *renderer, CoglXlibRenderer * _cogl_xlib_renderer_get_data (CoglRenderer *renderer); -int64_t -_cogl_xlib_renderer_get_dispatch_timeout (CoglRenderer *renderer); - CoglOutput * _cogl_xlib_renderer_output_for_rectangle (CoglRenderer *renderer, int x, diff --git a/cogl/cogl/cogl-xlib-renderer.c b/cogl/cogl/cogl-xlib-renderer.c index 66fe0e595..9ee9d6a47 100644 --- a/cogl/cogl/cogl-xlib-renderer.c +++ b/cogl/cogl/cogl-xlib-renderer.c @@ -29,9 +29,7 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-xlib-renderer.h" #include "cogl-util.h" @@ -41,9 +39,8 @@ #include "cogl-renderer-private.h" #include "cogl-xlib-renderer-private.h" #include "cogl-x11-renderer-private.h" -#include "cogl-winsys-private.h" -#include "cogl-error-private.h" #include "cogl-poll-private.h" +#include "winsys/cogl-winsys-private.h" #include #include @@ -56,41 +53,27 @@ static char *_cogl_x11_display_name = NULL; static GList *_cogl_xlib_renderers = NULL; static void -destroy_xlib_renderer_data (void *user_data) +_xlib_renderer_data_free (CoglXlibRenderer *data) { - CoglXlibRenderer *data = user_data; - if (data->xvisinfo) XFree (data->xvisinfo); - g_slice_free (CoglXlibRenderer, user_data); + g_slice_free (CoglXlibRenderer, data); } CoglXlibRenderer * _cogl_xlib_renderer_get_data (CoglRenderer *renderer) { - static CoglUserDataKey key; - CoglXlibRenderer *data; - /* Constructs a CoglXlibRenderer struct on demand and attaches it to the object using user data. It's done this way instead of using a subclassing hierarchy in the winsys data because all EGL winsys's need the EGL winsys data but only one of them wants the Xlib data. */ - data = cogl_object_get_user_data (COGL_OBJECT (renderer), &key); - - if (data == NULL) - { - data = g_slice_new0 (CoglXlibRenderer); - - cogl_object_set_user_data (COGL_OBJECT (renderer), - &key, - data, - destroy_xlib_renderer_data); - } + if (!renderer->custom_winsys_user_data) + renderer->custom_winsys_user_data = g_slice_new0 (CoglXlibRenderer); - return data; + return renderer->custom_winsys_user_data; } static void @@ -178,7 +161,7 @@ _cogl_xlib_renderer_untrap_errors (CoglRenderer *renderer, } static Display * -assert_xlib_display (CoglRenderer *renderer, CoglError **error) +assert_xlib_display (CoglRenderer *renderer, GError **error) { Display *xdpy = cogl_xlib_renderer_get_foreign_display (renderer); CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (renderer); @@ -193,7 +176,7 @@ assert_xlib_display (CoglRenderer *renderer, CoglError **error) xdpy = XOpenDisplay (_cogl_x11_display_name); if (xdpy == NULL) { - _cogl_set_error (error, + g_set_error (error, COGL_RENDERER_ERROR, COGL_RENDERER_ERROR_XLIB_DISPLAY_OPEN, "Failed to open X Display %s", _cogl_x11_display_name); @@ -230,16 +213,16 @@ static CoglSubpixelOrder subpixel_map[6][6] = { static void update_outputs (CoglRenderer *renderer, - CoglBool notify) + gboolean notify) { CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (renderer); XRRScreenResources *resources; CoglXlibTrapState state; - CoglBool error = FALSE; + gboolean error = FALSE; GList *new_outputs = NULL; GList *l, *m; - CoglBool changed = FALSE; + gboolean changed = FALSE; int i; xlib_renderer->outputs_update_serial = XNextRequest (xlib_renderer->xdpy); @@ -504,8 +487,8 @@ dispatch_xlib_events (void *user_data, int revents) } } -CoglBool -_cogl_xlib_renderer_connect (CoglRenderer *renderer, CoglError **error) +gboolean +_cogl_xlib_renderer_connect (CoglRenderer *renderer, GError **error) { CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (renderer); @@ -572,6 +555,8 @@ _cogl_xlib_renderer_disconnect (CoglRenderer *renderer) if (!renderer->foreign_xdpy && xlib_renderer->xdpy) XCloseDisplay (xlib_renderer->xdpy); + g_clear_pointer (&renderer->custom_winsys_user_data, _xlib_renderer_data_free); + unregister_xlib_renderer (renderer); } @@ -580,7 +565,7 @@ cogl_xlib_renderer_get_display (CoglRenderer *renderer) { CoglXlibRenderer *xlib_renderer; - _COGL_RETURN_VAL_IF_FAIL (cogl_is_renderer (renderer), NULL); + g_return_val_if_fail (cogl_is_renderer (renderer), NULL); xlib_renderer = _cogl_xlib_renderer_get_data (renderer); @@ -612,22 +597,6 @@ cogl_xlib_renderer_remove_filter (CoglRenderer *renderer, (CoglNativeFilterFunc)func, data); } -int64_t -_cogl_xlib_renderer_get_dispatch_timeout (CoglRenderer *renderer) -{ - CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (renderer); - - if (renderer->xlib_enable_event_retrieval) - { - if (XPending (xlib_renderer->xdpy)) - return 0; - else - return -1; - } - else - return -1; -} - CoglOutput * _cogl_xlib_renderer_output_for_rectangle (CoglRenderer *renderer, int x, @@ -663,15 +632,3 @@ _cogl_xlib_renderer_output_for_rectangle (CoglRenderer *renderer, return max_overlapped; } - -XVisualInfo * -cogl_xlib_renderer_get_visual_info (CoglRenderer *renderer) -{ - CoglXlibRenderer *xlib_renderer; - - _COGL_RETURN_VAL_IF_FAIL (cogl_is_renderer (renderer), NULL); - - xlib_renderer = _cogl_xlib_renderer_get_data (renderer); - - return xlib_renderer->xvisinfo; -} diff --git a/cogl/cogl/cogl-xlib-renderer.h b/cogl/cogl/cogl-xlib-renderer.h index 2a4f5d6ea..3afdabb27 100644 --- a/cogl/cogl/cogl-xlib-renderer.h +++ b/cogl/cogl/cogl-xlib-renderer.h @@ -55,7 +55,7 @@ #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS /** * cogl_xlib_renderer_handle_event: (skip) @@ -72,7 +72,7 @@ COGL_BEGIN_DECLS * either not interested in the event, or has used the event to update * internal state without taking any exclusive action. */ -CoglFilterReturn +COGL_EXPORT CoglFilterReturn cogl_xlib_renderer_handle_event (CoglRenderer *renderer, XEvent *event); @@ -99,7 +99,7 @@ typedef CoglFilterReturn (* CoglXlibFilterFunc) (XEvent *event, * function can stop further processing of the event by return * %COGL_FILTER_REMOVE. */ -void +COGL_EXPORT void cogl_xlib_renderer_add_filter (CoglRenderer *renderer, CoglXlibFilterFunc func, void *data); @@ -113,7 +113,7 @@ cogl_xlib_renderer_add_filter (CoglRenderer *renderer, * Removes a callback that was previously added with * cogl_xlib_renderer_add_filter(). */ -void +COGL_EXPORT void cogl_xlib_renderer_remove_filter (CoglRenderer *renderer, CoglXlibFilterFunc func, void *data); @@ -126,7 +126,7 @@ cogl_xlib_renderer_remove_filter (CoglRenderer *renderer, * winsys backend. The display needs to be set with * cogl_xlib_renderer_set_foreign_display() before this function is called. */ -Display * +COGL_EXPORT Display * cogl_xlib_renderer_get_foreign_display (CoglRenderer *renderer); /** @@ -136,79 +136,21 @@ cogl_xlib_renderer_get_foreign_display (CoglRenderer *renderer); * Sets a foreign Xlib display that Cogl will use for and Xlib based winsys * backend. * - * Note that calling this function will automatically call - * cogl_xlib_renderer_set_event_retrieval_enabled() to disable Cogl's + * Note that calling this function will automatically disable Cogl's * event retrieval. Cogl still needs to see all of the X events so the * application should also use cogl_xlib_renderer_handle_event() if it * uses this function. */ -void +COGL_EXPORT void cogl_xlib_renderer_set_foreign_display (CoglRenderer *renderer, Display *display); -/** - * cogl_xlib_renderer_set_event_retrieval_enabled: (skip) - * @renderer: a #CoglRenderer - * @enable: The new value - * - * Sets whether Cogl should automatically retrieve events from the X - * display. This defaults to %TRUE unless - * cogl_xlib_renderer_set_foreign_display() is called. It can be set - * to %FALSE if the application wants to handle its own event - * retrieval. Note that Cogl still needs to see all of the X events to - * function properly so the application should call - * cogl_xlib_renderer_handle_event() for each event if it disables - * automatic event retrieval. - * - * Since: 1.10 - * Stability: unstable - */ -void -cogl_xlib_renderer_set_event_retrieval_enabled (CoglRenderer *renderer, - CoglBool enable); - -/** - * cogl_xlib_renderer_set_threaded_swap_wait_enabled: (skip) - * @renderer: a #CoglRenderer - * @enable: The new value - * - * Sets whether Cogl is allowed to use a separate threaded to wait for the - * completion of glXSwapBuffers() and call the frame callback for the - * corresponding #CoglOnscreen. This is a way of emulating the - * INTEL_swap_event extension, and will only ever be used if - * INTEL_swap_event is not present; it will also only be used for - * specific white-listed drivers that are known to work correctly with - * multiple contexts sharing state between threads. - * - * The advantage of enabling this is that it will allow your main loop - * to do other work while waiting for the system to be ready to draw - * the next frame, instead of blocking in glXSwapBuffers(). A disadvantage - * is that the driver will be prevented from buffering up multiple frames - * even if it thinks that it would be advantageous. In general, this - * will work best for something like a system compositor that is doing - * simple drawing but handling lots of other complex tasks. - * - * If you enable this, you must call XInitThreads() before any other - * X11 calls in your program. (See the documentation for XInitThreads()) - * - * Stability: unstable - */ -void -cogl_xlib_renderer_set_threaded_swap_wait_enabled (CoglRenderer *renderer, - CoglBool enable); - /** * cogl_xlib_renderer_get_display: (skip) */ -Display * +COGL_EXPORT Display * cogl_xlib_renderer_get_display (CoglRenderer *renderer); -/** - * cogl_xlib_renderer_get_visual_info: (skip) - */ -XVisualInfo * -cogl_xlib_renderer_get_visual_info (CoglRenderer *renderer); - /** * cogl_xlib_renderer_request_reset_on_video_memory_purge: (skip) * @renderer: a #CoglRenderer @@ -247,10 +189,10 @@ cogl_xlib_renderer_get_visual_info (CoglRenderer *renderer); * This defaults to %FALSE and is effective only if called before * cogl_display_setup() . */ -void +COGL_EXPORT void cogl_xlib_renderer_request_reset_on_video_memory_purge (CoglRenderer *renderer, - CoglBool enable); -COGL_END_DECLS + gboolean enable); +G_END_DECLS /* The gobject introspection scanner seems to parse public headers in * isolation which means we need to be extra careful about how we diff --git a/cogl/cogl/cogl-xlib.c b/cogl/cogl/cogl-xlib.c deleted file mode 100644 index c381035b6..000000000 --- a/cogl/cogl/cogl-xlib.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010,2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg - * - */ - -#ifdef HAVE_CONFIG_H -#include "cogl-config.h" -#endif - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "cogl-xlib.h" - -/* FIXME: when we remove the last X11 based Clutter backend then we - * will get rid of these functions and instead rely on the equivalent - * _cogl_xlib_renderer API - */ - -/* This can't be in the Cogl context because it can be set before - context is created */ -static Display *_cogl_xlib_display = NULL; - -Display * -cogl_xlib_get_display (void) -{ - _COGL_GET_CONTEXT (ctx, NULL); - - return cogl_xlib_renderer_get_display (ctx->display->renderer); -} - -void -cogl_xlib_set_display (Display *display) -{ - /* This can only be called once before the Cogl context is created */ - g_assert (_cogl_xlib_display == NULL); - - _cogl_xlib_display = display; -} - -/* These three functions are wrappers around the equivalent renderer - functions. They can be removed once all xlib-based backends in - Clutter know about the renderer */ -CoglFilterReturn -cogl_xlib_handle_event (XEvent *xevent) -{ - _COGL_GET_CONTEXT (ctx, COGL_FILTER_CONTINUE); - - /* Pass the event on to the renderer */ - return cogl_xlib_renderer_handle_event (ctx->display->renderer, xevent); -} - -void -_cogl_xlib_query_damage_extension (void) -{ - int damage_error; - Display *display; - - _COGL_GET_CONTEXT (ctxt, NO_RETVAL); - - /* Check whether damage events are supported on this display */ - display = cogl_xlib_renderer_get_display (ctxt->display->renderer); - if (!XDamageQueryExtension (display, &ctxt->damage_base, &damage_error)) - ctxt->damage_base = -1; -} - -int -_cogl_xlib_get_damage_base (void) -{ - CoglX11Renderer *x11_renderer; - _COGL_GET_CONTEXT (ctxt, -1); - - x11_renderer = - (CoglX11Renderer *) _cogl_xlib_renderer_get_data (ctxt->display->renderer); - return x11_renderer->damage_base; -} diff --git a/cogl/cogl/cogl-xlib.h b/cogl/cogl/cogl-xlib.h index ac4a14004..4fd803b88 100644 --- a/cogl/cogl/cogl-xlib.h +++ b/cogl/cogl/cogl-xlib.h @@ -55,66 +55,9 @@ #endif /* COGL_COMPILATION */ #include -#include #include #include -COGL_BEGIN_DECLS - -/* - * cogl_xlib_get_display: - * - * Return value: the Xlib display that will be used by the Xlib winsys - * backend. The display needs to be set with _cogl_xlib_set_display() - * before this function is called. - * - * Stability: Unstable - * Deprecated: 1.16: Use cogl_xlib_renderer_get_display() instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_xlib_renderer_get_display) -Display * -cogl_xlib_get_display (void); - -/* - * cogl_xlib_set_display: - * - * Sets the Xlib display that Cogl will use for the Xlib winsys - * backend. This function should eventually go away when Cogl gains a - * more complete winsys abstraction. - * - * Stability: Unstable - * Deprecated: 1.16: Use cogl_xlib_renderer_set_foreign_display() - * instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_xlib_renderer_set_foreign_display) -void -cogl_xlib_set_display (Display *display); - -/* - * cogl_xlib_handle_event: - * @xevent: pointer to XEvent structure - * - * This function processes a single X event; it can be used to hook - * into external X event retrieval (for example that done by Clutter - * or GDK). - * - * Return value: #CoglXlibFilterReturn. %COGL_XLIB_FILTER_REMOVE - * indicates that Cogl has internally handled the event and the - * caller should do no further processing. %COGL_XLIB_FILTER_CONTINUE - * indicates that Cogl is either not interested in the event, - * or has used the event to update internal state without taking - * any exclusive action. - * - * Stability: Unstable - * Deprecated: 1.16: Use cogl_xlib_renderer_handle_event() instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_xlib_renderer_handle_event) -CoglFilterReturn -cogl_xlib_handle_event (XEvent *xevent); - -COGL_END_DECLS - - /* The gobject introspection scanner seems to parse public headers in * isolation which means we need to be extra careful about how we * define and undefine __COGL_H_INSIDE__ used to detect when internal diff --git a/cogl/cogl/cogl.c b/cogl/cogl/cogl.c index a9ca3fe95..2cf0dbe21 100644 --- a/cogl/cogl/cogl.c +++ b/cogl/cogl/cogl.c @@ -34,15 +34,11 @@ #include #include -#define COGL_VERSION_MIN_REQUIRED COGL_VERSION_1_4 - #include "cogl-i18n-private.h" #include "cogl-debug.h" #include "cogl-util.h" #include "cogl-context-private.h" #include "cogl-pipeline-private.h" -#include "cogl-pipeline-opengl-private.h" -#include "cogl-winsys-private.h" #include "cogl-framebuffer-private.h" #include "cogl-matrix-private.h" #include "cogl-journal-private.h" @@ -52,16 +48,12 @@ #include "cogl-attribute-private.h" #include "cogl-framebuffer-private.h" #include "cogl-renderer-private.h" -#include "cogl-config-private.h" #include "cogl-private.h" #include "cogl1-context.h" #include "cogl-offscreen.h" -#include "cogl-attribute-gl-private.h" -#include "cogl-clutter.h" - -#include "deprecated/cogl-framebuffer-deprecated.h" +#include "winsys/cogl-winsys-private.h" -CoglFuncPtr +GCallback cogl_get_proc_address (const char* name) { _COGL_GET_CONTEXT (ctx, NULL); @@ -69,7 +61,7 @@ cogl_get_proc_address (const char* name) return _cogl_renderer_get_proc_address (ctx->display->renderer, name, FALSE); } -CoglBool +gboolean _cogl_check_extension (const char *name, char * const *ext) { while (*ext) @@ -81,24 +73,9 @@ _cogl_check_extension (const char *name, char * const *ext) return FALSE; } -/* XXX: This has been deprecated as public API */ -CoglBool -cogl_check_extension (const char *name, const char *ext) -{ - return cogl_clutter_check_extension (name, ext); -} - -/* XXX: it's expected that we'll deprecated this with - * cogl_framebuffer_clear at some point. */ -void -cogl_clear (const CoglColor *color, unsigned long buffers) -{ - cogl_framebuffer_clear (cogl_get_draw_framebuffer (), buffers, color); -} - /* XXX: This API has been deprecated */ void -cogl_set_depth_test_enabled (CoglBool setting) +cogl_set_depth_test_enabled (gboolean setting) { _COGL_GET_CONTEXT (ctx, NO_RETVAL); @@ -106,14 +83,10 @@ cogl_set_depth_test_enabled (CoglBool setting) return; ctx->legacy_depth_test_enabled = setting; - if (ctx->legacy_depth_test_enabled) - ctx->legacy_state_set++; - else - ctx->legacy_state_set--; } /* XXX: This API has been deprecated */ -CoglBool +gboolean cogl_get_depth_test_enabled (void) { _COGL_GET_CONTEXT (ctx, FALSE); @@ -121,7 +94,7 @@ cogl_get_depth_test_enabled (void) } void -cogl_set_backface_culling_enabled (CoglBool setting) +cogl_set_backface_culling_enabled (gboolean setting) { _COGL_GET_CONTEXT (ctx, NO_RETVAL); @@ -129,14 +102,9 @@ cogl_set_backface_culling_enabled (CoglBool setting) return; ctx->legacy_backface_culling_enabled = setting; - - if (ctx->legacy_backface_culling_enabled) - ctx->legacy_state_set++; - else - ctx->legacy_state_set--; } -CoglBool +gboolean cogl_get_backface_culling_enabled (void) { _COGL_GET_CONTEXT (ctx, FALSE); @@ -144,80 +112,13 @@ cogl_get_backface_culling_enabled (void) return ctx->legacy_backface_culling_enabled; } -void -cogl_set_source_color (const CoglColor *color) -{ - CoglPipeline *pipeline; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (cogl_color_get_alpha_byte (color) == 0xff) - { - cogl_pipeline_set_color (ctx->opaque_color_pipeline, color); - pipeline = ctx->opaque_color_pipeline; - } - else - { - CoglColor premultiplied = *color; - cogl_color_premultiply (&premultiplied); - cogl_pipeline_set_color (ctx->blended_color_pipeline, &premultiplied); - pipeline = ctx->blended_color_pipeline; - } - - cogl_set_source (pipeline); -} - -void -cogl_set_viewport (int x, - int y, - int width, - int height) -{ - CoglFramebuffer *framebuffer; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - framebuffer = cogl_get_draw_framebuffer (); - - cogl_framebuffer_set_viewport (framebuffer, - x, - y, - width, - height); -} - -/* XXX: This should be deprecated, and we should expose a way to also - * specify an x and y viewport offset */ -void -cogl_viewport (unsigned int width, - unsigned int height) -{ - cogl_set_viewport (0, 0, width, height); -} - -CoglFeatureFlags -cogl_get_features (void) -{ - _COGL_GET_CONTEXT (ctx, 0); - - return ctx->feature_flags; -} - -CoglBool -cogl_features_available (CoglFeatureFlags features) -{ - _COGL_GET_CONTEXT (ctx, 0); - - return (ctx->feature_flags & features) == features; -} - -CoglBool +gboolean cogl_has_feature (CoglContext *ctx, CoglFeatureID feature) { return COGL_FLAGS_GET (ctx->features, feature); } -CoglBool +gboolean cogl_has_features (CoglContext *ctx, ...) { va_list args; @@ -243,75 +144,6 @@ cogl_foreach_feature (CoglContext *ctx, callback (i, user_data); } -/* XXX: This function should either be replaced with one returning - * integers, or removed/deprecated and make the - * _cogl_framebuffer_get_viewport* functions public. - */ -void -cogl_get_viewport (float viewport[4]) -{ - CoglFramebuffer *framebuffer; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - framebuffer = cogl_get_draw_framebuffer (); - cogl_framebuffer_get_viewport4fv (framebuffer, viewport); -} - -void -cogl_get_bitmasks (int *red, - int *green, - int *blue, - int *alpha) -{ - CoglFramebuffer *framebuffer; - - framebuffer = cogl_get_draw_framebuffer (); - - if (red) - *red = cogl_framebuffer_get_red_bits (framebuffer); - - if (green) - *green = cogl_framebuffer_get_green_bits (framebuffer); - - if (blue) - *blue = cogl_framebuffer_get_blue_bits (framebuffer); - - if (alpha) - *alpha = cogl_framebuffer_get_alpha_bits (framebuffer); -} - -void -cogl_set_fog (const CoglColor *fog_color, - CoglFogMode mode, - float density, - float z_near, - float z_far) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (ctx->legacy_fog_state.enabled == FALSE) - ctx->legacy_state_set++; - - ctx->legacy_fog_state.enabled = TRUE; - ctx->legacy_fog_state.color = *fog_color; - ctx->legacy_fog_state.mode = mode; - ctx->legacy_fog_state.density = density; - ctx->legacy_fog_state.z_near = z_near; - ctx->legacy_fog_state.z_far = z_far; -} - -void -cogl_disable_fog (void) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (ctx->legacy_fog_state.enabled == TRUE) - ctx->legacy_state_set--; - - ctx->legacy_fog_state.enabled = FALSE; -} - void cogl_flush (void) { @@ -323,387 +155,12 @@ cogl_flush (void) _cogl_framebuffer_flush_journal (l->data); } -void -cogl_read_pixels (int x, - int y, - int width, - int height, - CoglReadPixelsFlags source, - CoglPixelFormat format, - uint8_t *pixels) -{ - int bpp = _cogl_pixel_format_get_bytes_per_pixel (format); - CoglBitmap *bitmap; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - bitmap = cogl_bitmap_new_for_data (ctx, - width, height, - format, - bpp * width, /* rowstride */ - pixels); - cogl_framebuffer_read_pixels_into_bitmap (_cogl_get_read_framebuffer (), - x, y, - source, - bitmap); - cogl_object_unref (bitmap); -} - -void -cogl_begin_gl (void) -{ - CoglPipeline *pipeline; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (ctx->in_begin_gl_block) - { - static CoglBool shown = FALSE; - if (!shown) - g_warning ("You should not nest cogl_begin_gl/cogl_end_gl blocks"); - shown = TRUE; - return; - } - ctx->in_begin_gl_block = TRUE; - - /* Flush all batched primitives */ - cogl_flush (); - - /* Flush framebuffer state, including clip state, modelview and - * projection matrix state - * - * NB: _cogl_framebuffer_flush_state may disrupt various state (such - * as the pipeline state) when flushing the clip stack, so should - * always be done first when preparing to draw. */ - _cogl_framebuffer_flush_state (cogl_get_draw_framebuffer (), - _cogl_get_read_framebuffer (), - COGL_FRAMEBUFFER_STATE_ALL); - - /* Setup the state for the current pipeline */ - - /* We considered flushing a specific, minimal pipeline here to try and - * simplify the GL state, but decided to avoid special cases and second - * guessing what would be actually helpful. - * - * A user should instead call cogl_set_source_color4ub() before - * cogl_begin_gl() to simplify the state flushed. - * - * XXX: note defining n_tex_coord_attribs using - * cogl_pipeline_get_n_layers is a hack, but the problem is that - * n_tex_coord_attribs is usually defined when drawing a primitive - * which isn't happening here. - * - * Maybe it would be more useful if this code did flush the - * opaque_color_pipeline and then call into cogl-pipeline-opengl.c to then - * restore all state for the material's backend back to default OpenGL - * values. - */ - pipeline = cogl_get_source (); - _cogl_pipeline_flush_gl_state (ctx, - pipeline, - cogl_get_draw_framebuffer (), - FALSE, - FALSE); - - /* Disable any cached vertex arrays */ - _cogl_gl_disable_all_attributes (ctx); -} - -void -cogl_end_gl (void) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (!ctx->in_begin_gl_block) - { - static CoglBool shown = FALSE; - if (!shown) - g_warning ("cogl_end_gl is being called before cogl_begin_gl"); - shown = TRUE; - return; - } - ctx->in_begin_gl_block = FALSE; -} - -void -cogl_push_matrix (void) -{ - cogl_framebuffer_push_matrix (cogl_get_draw_framebuffer ()); -} - -void -cogl_pop_matrix (void) -{ - cogl_framebuffer_pop_matrix (cogl_get_draw_framebuffer ()); -} - -void -cogl_scale (float x, float y, float z) -{ - cogl_framebuffer_scale (cogl_get_draw_framebuffer (), x, y, z); -} - -void -cogl_translate (float x, float y, float z) -{ - cogl_framebuffer_translate (cogl_get_draw_framebuffer (), x, y, z); -} - -void -cogl_rotate (float angle, float x, float y, float z) -{ - cogl_framebuffer_rotate (cogl_get_draw_framebuffer (), angle, x, y, z); -} - -void -cogl_transform (const CoglMatrix *matrix) -{ - cogl_framebuffer_transform (cogl_get_draw_framebuffer (), matrix); -} - -void -cogl_perspective (float fov_y, - float aspect, - float z_near, - float z_far) -{ - cogl_framebuffer_perspective (cogl_get_draw_framebuffer (), - fov_y, aspect, z_near, z_far); -} - -void -cogl_frustum (float left, - float right, - float bottom, - float top, - float z_near, - float z_far) -{ - cogl_framebuffer_frustum (cogl_get_draw_framebuffer (), - left, right, bottom, top, z_near, z_far); -} - -void -cogl_ortho (float left, - float right, - float bottom, - float top, - float near, - float far) -{ - cogl_framebuffer_orthographic (cogl_get_draw_framebuffer (), - left, top, right, bottom, near, far); -} - -void -cogl_get_modelview_matrix (CoglMatrix *matrix) -{ - cogl_framebuffer_get_modelview_matrix (cogl_get_draw_framebuffer (), matrix); -} - -void -cogl_set_modelview_matrix (CoglMatrix *matrix) -{ - cogl_framebuffer_set_modelview_matrix (cogl_get_draw_framebuffer (), matrix); -} - -void -cogl_get_projection_matrix (CoglMatrix *matrix) -{ - cogl_framebuffer_get_projection_matrix (cogl_get_draw_framebuffer (), matrix); -} - -void -cogl_set_projection_matrix (CoglMatrix *matrix) -{ - cogl_framebuffer_set_projection_matrix (cogl_get_draw_framebuffer (), matrix); -} - uint32_t _cogl_driver_error_quark (void) { return g_quark_from_static_string ("cogl-driver-error-quark"); } -typedef struct _CoglSourceState -{ - CoglPipeline *pipeline; - int push_count; - /* If this is TRUE then the pipeline will be copied and the legacy - state will be applied whenever the pipeline is used. This is - necessary because some internal Cogl code expects to be able to - push a temporary pipeline to put GL into a known state. For that - to work it also needs to prevent applying the legacy state */ - CoglBool enable_legacy; -} CoglSourceState; - -static void -_push_source_real (CoglPipeline *pipeline, CoglBool enable_legacy) -{ - CoglSourceState *top = g_slice_new (CoglSourceState); - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - top->pipeline = cogl_object_ref (pipeline); - top->enable_legacy = enable_legacy; - top->push_count = 1; - - ctx->source_stack = g_list_prepend (ctx->source_stack, top); -} - -/* FIXME: This should take a context pointer for Cogl 2.0 Technically - * we could make it so we can retrieve a context reference from the - * pipeline, but this would not by symmetric with cogl_pop_source. */ -void -cogl_push_source (void *material_or_pipeline) -{ - CoglPipeline *pipeline = COGL_PIPELINE (material_or_pipeline); - - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); - - _cogl_push_source (pipeline, TRUE); -} - -/* This internal version of cogl_push_source is the same except it - never applies the legacy state. Some parts of Cogl use this - internally to set a temporary pipeline with a known state */ -void -_cogl_push_source (CoglPipeline *pipeline, CoglBool enable_legacy) -{ - CoglSourceState *top; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); - - if (ctx->source_stack) - { - top = ctx->source_stack->data; - if (top->pipeline == pipeline && top->enable_legacy == enable_legacy) - { - top->push_count++; - return; - } - else - _push_source_real (pipeline, enable_legacy); - } - else - _push_source_real (pipeline, enable_legacy); -} - -/* FIXME: This needs to take a context pointer for Cogl 2.0 */ -void -cogl_pop_source (void) -{ - CoglSourceState *top; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - _COGL_RETURN_IF_FAIL (ctx->source_stack); - - top = ctx->source_stack->data; - top->push_count--; - if (top->push_count == 0) - { - cogl_object_unref (top->pipeline); - g_slice_free (CoglSourceState, top); - ctx->source_stack = g_list_delete_link (ctx->source_stack, - ctx->source_stack); - } -} - -/* FIXME: This needs to take a context pointer for Cogl 2.0 */ -void * -cogl_get_source (void) -{ - CoglSourceState *top; - - _COGL_GET_CONTEXT (ctx, NULL); - - _COGL_RETURN_VAL_IF_FAIL (ctx->source_stack, NULL); - - top = ctx->source_stack->data; - return top->pipeline; -} - -CoglBool -_cogl_get_enable_legacy_state (void) -{ - CoglSourceState *top; - - _COGL_GET_CONTEXT (ctx, FALSE); - - _COGL_RETURN_VAL_IF_FAIL (ctx->source_stack, FALSE); - - top = ctx->source_stack->data; - return top->enable_legacy; -} - -void -cogl_set_source (void *material_or_pipeline) -{ - CoglSourceState *top; - CoglPipeline *pipeline = COGL_PIPELINE (material_or_pipeline); - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline)); - _COGL_RETURN_IF_FAIL (ctx->source_stack); - - top = ctx->source_stack->data; - if (top->pipeline == pipeline && top->enable_legacy) - return; - - if (top->push_count == 1) - { - /* NB: top->pipeline may be only thing keeping pipeline - * alive currently so ref pipeline first... */ - cogl_object_ref (pipeline); - cogl_object_unref (top->pipeline); - top->pipeline = pipeline; - top->enable_legacy = TRUE; - } - else - { - top->push_count--; - cogl_push_source (pipeline); - } -} - -void -cogl_set_source_texture (CoglTexture *texture) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - _COGL_RETURN_IF_FAIL (texture != NULL); - - cogl_pipeline_set_layer_texture (ctx->texture_pipeline, 0, texture); - cogl_set_source (ctx->texture_pipeline); -} - -void -cogl_set_source_color4ub (uint8_t red, - uint8_t green, - uint8_t blue, - uint8_t alpha) -{ - CoglColor c = { 0, }; - - cogl_color_init_from_4ub (&c, red, green, blue, alpha); - cogl_set_source_color (&c); -} - -void -cogl_set_source_color4f (float red, - float green, - float blue, - float alpha) -{ - CoglColor c = { 0, }; - - cogl_color_init_from_4f (&c, red, green, blue, alpha); - cogl_set_source_color (&c); -} - /* Scale from OpenGL normalized device coordinates (ranging from -1 to 1) * to Cogl window/framebuffer coordinates (ranging from 0 to buffer-size) with * (0,0) being top left. */ @@ -753,7 +210,7 @@ _cogl_system_error_quark (void) void _cogl_init (void) { - static CoglBool initialized = FALSE; + static gboolean initialized = FALSE; if (initialized == FALSE) { @@ -761,60 +218,7 @@ _cogl_init (void) g_type_init (); #endif - _cogl_config_read (); _cogl_debug_check_environment (); initialized = TRUE; } } - -/* - * Returns the number of bytes-per-pixel of a given format. The bpp - * can be extracted from the least significant nibble of the pixel - * format (see CoglPixelFormat). - * - * The mapping is the following (see discussion on bug #660188): - * - * 0 = undefined - * 1, 8 = 1 bpp (e.g. A_8, G_8) - * 2 = 3 bpp, aligned (e.g. 888) - * 3 = 4 bpp, aligned (e.g. 8888) - * 4-6 = 2 bpp, not aligned (e.g. 565, 4444, 5551) - * 7 = undefined yuv - * 9 = 2 bpp, aligned - * 10 = undefined - * 11 = undefined - * 12 = 3 bpp, not aligned - * 13 = 4 bpp, not aligned (e.g. 2101010) - * 14-15 = undefined - */ -int -_cogl_pixel_format_get_bytes_per_pixel (CoglPixelFormat format) -{ - int bpp_lut[] = { 0, 1, 3, 4, - 2, 2, 2, 0, - 1, 2, 0, 0, - 3, 4, 0, 0 }; - - return bpp_lut [format & 0xf]; -} - -/* Note: this also refers to the mapping defined above for - * _cogl_pixel_format_get_bytes_per_pixel() */ -CoglBool -_cogl_pixel_format_is_endian_dependant (CoglPixelFormat format) -{ - int aligned_lut[] = { -1, 1, 1, 1, - 0, 0, 0, -1, - 1, 1, -1, -1, - 0, 0, -1, -1}; - int aligned = aligned_lut[format & 0xf]; - - _COGL_RETURN_VAL_IF_FAIL (aligned != -1, FALSE); - - /* NB: currently checking whether the format components are aligned - * or not determines whether the format is endian dependent or not. - * In the future though we might consider adding formats with - * aligned components that are also endian independant. */ - - return aligned; -} diff --git a/cogl/cogl/cogl.h b/cogl/cogl/cogl.h index cdf739415..64ba6d25b 100644 --- a/cogl/cogl/cogl.h +++ b/cogl/cogl/cogl.h @@ -42,6 +42,8 @@ #define __COGL_MUST_UNDEF_COGL_H_INSIDE__ #endif +#include + /* We currently keep gtype integration delimited in case we eventually * want to split it out into a separate utility library when Cogl * becomes a standalone project. (like cairo-gobject.so) @@ -55,16 +57,15 @@ #include #include -#include - #include #include #include #include +#include #include #include #include -#include +#include #include #include #include @@ -83,14 +84,12 @@ * they enable the experimental api... */ #include -#include #include #include #include -#include -#ifdef COGL_ENABLE_MUFFIN_API -#include +#ifdef COGL_ENABLE_MUTTER_API +#include #endif #include @@ -100,13 +99,7 @@ #include #include #include -#include -#include -#include #include -#include -#include -#include #include #include #include @@ -128,15 +121,11 @@ #include #include #include +#include /* XXX: This will definitly go away once all the Clutter winsys * code has been migrated down into Cogl! */ #include -/* - * API deprecations - */ -#include - /* * Cogl Path api compatability * @@ -148,8 +137,7 @@ * cogl-path now gets built after cogl and some cogl-path headers are * only generated at build time... */ -#if defined (COGL_HAS_COGL_PATH_SUPPORT) && \ - !defined (COGL_COMPILATION) && \ +#if !defined (COGL_COMPILATION) && \ !defined (COGL_GIR_SCANNING) #include #endif diff --git a/cogl/cogl/cogl.symbols b/cogl/cogl/cogl.symbols deleted file mode 100644 index c1cd50e07..000000000 --- a/cogl/cogl/cogl.symbols +++ /dev/null @@ -1,1087 +0,0 @@ - - -#ifdef COGL_HAS_EGL_PLATFORM_ANDROID_SUPPORT -cogl_android_set_native_window -#endif - -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_atlas_texture_get_gtype -#endif -cogl_atlas_texture_new_with_size -cogl_atlas_texture_new_from_file -cogl_atlas_texture_new_from_data -cogl_atlas_texture_new_from_bitmap - -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_attribute_buffer_get_gtype -#endif -cogl_attribute_buffer_new_with_size - -cogl_attribute_buffer_new -cogl_attribute_get_buffer -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_attribute_get_gtype -#endif -cogl_attribute_get_normalized -cogl_attribute_new -cogl_attribute_new_const_1f -cogl_attribute_new_const_2f -cogl_attribute_new_const_2fv -cogl_attribute_new_const_2x2fv -cogl_attribute_new_const_3f -cogl_attribute_new_const_3fv -cogl_attribute_new_const_3x3fv -cogl_attribute_new_const_4f -cogl_attribute_new_const_4fv -cogl_attribute_new_const_4x4fv -cogl_attribute_set_buffer -cogl_attribute_set_normalized -cogl_attribute_type_get_type - -cogl_begin_gl - -cogl_bitmap_error_get_type -cogl_bitmap_get_buffer -cogl_bitmap_get_format -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_bitmap_get_gtype -#endif -cogl_bitmap_get_height -cogl_bitmap_get_rowstride -cogl_bitmap_get_size_from_file -cogl_bitmap_get_width -cogl_bitmap_new_for_data -cogl_bitmap_new_from_file -cogl_bitmap_new_from_buffer -cogl_bitmap_new_with_size -cogl_blend_string_error_get_type - -cogl_buffer_bit_get_type -cogl_buffer_get_size -cogl_buffer_get_update_hint -#if 0 -/* not implemented! */ -cogl_buffer_get_usage_hint -#endif -cogl_buffer_map -cogl_buffer_map_range -cogl_buffer_set_data -cogl_buffer_set_update_hint -#if 0 -/* not implemented! */ -cogl_buffer_set_usage_hint -#endif -cogl_buffer_target_get_type -cogl_buffer_unmap - -#ifndef COGL_DISABLE_DEPRECATED -cogl_check_extension -#endif - -cogl_clear - -#ifndef COGL_DISABLE_DEPRECATED -cogl_clip_ensure -#endif - -cogl_clip_pop - -#ifndef COGL_DISABLE_DEPRECATED -cogl_clip_push -#endif - -cogl_clip_push_rectangle - -cogl_clip_push_window_rect - -cogl_clip_push_primitive - -#ifndef COGL_DISABLE_DEPRECATED -cogl_clip_push_window_rectangle -cogl_clip_stack_restore -cogl_clip_stack_save -#endif - -#ifndef COGL_WINSYS_INTEGRATED -cogl_clutter_check_extension_CLUTTER -cogl_clutter_winsys_has_feature_CLUTTER -#ifdef COGL_HAS_XLIB -cogl_clutter_winsys_xlib_get_visual_info_CLUTTER -#endif -#endif - -cogl_color_copy -cogl_color_equal -cogl_color_free -cogl_color_get_alpha -cogl_color_get_alpha_byte -cogl_color_get_alpha_float -cogl_color_get_blue -cogl_color_get_blue_byte -cogl_color_get_blue_float -cogl_color_get_green -cogl_color_get_green_byte -cogl_color_get_green_float -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_color_get_gtype -#endif -cogl_color_get_red -cogl_color_get_red_byte -cogl_color_get_red_float -cogl_color_init_from_hsl -cogl_color_init_from_4f -cogl_color_init_from_4fv -cogl_color_init_from_4ub -cogl_color_mask_get_type -cogl_color_new -cogl_color_premultiply -cogl_color_set_alpha -cogl_color_set_alpha_byte -cogl_color_set_alpha_float -cogl_color_set_blue -cogl_color_set_blue_byte -cogl_color_set_blue_float -cogl_color_set_from_4f -cogl_color_set_from_4ub -cogl_color_set_green -cogl_color_set_green_byte -cogl_color_set_green_float -cogl_color_set_red -cogl_color_set_red_byte -cogl_color_set_red_float -cogl_color_to_hsl -cogl_color_unpremultiply - - -#ifdef COGL_HAS_EGL_SUPPORT -cogl_egl_context_get_egl_display -cogl_egl_context_get_egl_context -#endif - -#ifdef COGL_HAS_GLX_SUPPORT -cogl_glx_context_get_glx_context -#endif - -cogl_context_get_display -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_context_get_gtype -#endif -cogl_context_get_renderer -cogl_context_new - -cogl_create_program -cogl_create_shader - -cogl_debug_matrix_entry_print -cogl_debug_matrix_print -cogl_debug_object_foreach_type -cogl_debug_object_print_instances -cogl_depth_state_get_range -cogl_depth_state_get_test_enabled -cogl_depth_state_get_test_function -cogl_depth_state_get_write_enabled -cogl_depth_state_init -cogl_depth_state_set_test_enabled -cogl_depth_state_set_test_function -cogl_depth_state_set_range -cogl_depth_state_set_write_enabled -cogl_depth_test_function_get_type - -cogl_disable_fog - -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_display_get_gtype -#endif -cogl_display_get_renderer -cogl_display_new -cogl_display_setup -cogl_display_set_onscreen_template - -cogl_double_to_fixed - -cogl_end_gl - -cogl_error_copy -cogl_error_free -cogl_error_matches - -cogl_euler_copy -cogl_euler_equal -cogl_euler_free -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_euler_get_gtype -#endif -cogl_euler_init -cogl_euler_init_from_matrix -#if 0 -/* not yet implemented */ -cogl_euler_init_from_quaternion -#endif - -cogl_features_available -cogl_feature_flags_get_type -cogl_fence_closure_get_user_data -cogl_fixed_atan -cogl_fixed_atan2 -cogl_fixed_cos -cogl_fixed_get_type -cogl_fixed_log2 -cogl_fixed_pow -cogl_fixed_pow2 -cogl_fixed_sin -cogl_fixed_sqrt -cogl_fixed_tan - -cogl_fog_mode_get_type - -cogl_foreach_feature - -cogl_flush - -cogl_framebuffer_add_fence_callback -cogl_framebuffer_allocate -cogl_framebuffer_cancel_fence_callback -cogl_framebuffer_clear4f -cogl_framebuffer_clear -cogl_framebuffer_discard_buffers -cogl_framebuffer_draw_primitive -cogl_framebuffer_draw_rectangle -cogl_framebuffer_draw_rectangles -cogl_framebuffer_draw_textured_rectangle -cogl_framebuffer_draw_textured_rectangles -cogl_framebuffer_finish -cogl_framebuffer_frustum -cogl_framebuffer_get_alpha_bits -cogl_framebuffer_get_blue_bits -cogl_framebuffer_get_color_format -cogl_framebuffer_get_color_mask -cogl_framebuffer_get_context -cogl_framebuffer_get_depth_bits -cogl_framebuffer_get_depth_texture -cogl_framebuffer_get_depth_texture_enabled -cogl_framebuffer_get_depth_write_enabled -cogl_framebuffer_get_dither_enabled -cogl_framebuffer_get_green_bits -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_framebuffer_get_gtype -#endif -cogl_framebuffer_get_height -cogl_framebuffer_get_modelview_matrix -cogl_framebuffer_get_projection_matrix -cogl_framebuffer_get_red_bits -cogl_framebuffer_get_samples_per_pixel -cogl_framebuffer_get_viewport4fv -cogl_framebuffer_get_viewport_height -cogl_framebuffer_get_viewport_width -cogl_framebuffer_get_viewport_x -cogl_framebuffer_get_viewport_y -cogl_framebuffer_get_width -cogl_framebuffer_identity_matrix -cogl_framebuffer_orthographic -cogl_framebuffer_perspective -cogl_framebuffer_pop_clip -cogl_framebuffer_pop_matrix -cogl_framebuffer_push_matrix -cogl_framebuffer_push_primitive_clip -cogl_framebuffer_push_rectangle_clip -cogl_framebuffer_push_scissor_clip -cogl_framebuffer_read_pixels -cogl_framebuffer_read_pixels_into_bitmap -cogl_framebuffer_resolve_samples -cogl_framebuffer_resolve_samples_region -cogl_framebuffer_rotate - -#ifdef COGL_ENABLE_EXPERIMENTAL_API -cogl_framebuffer_rotate_euler -cogl_framebuffer_rotate_quaternion -#endif - -cogl_framebuffer_scale -cogl_framebuffer_set_color_mask -cogl_framebuffer_set_depth_texture_enabled -cogl_framebuffer_set_depth_write_enabled -cogl_framebuffer_set_dither_enabled -cogl_framebuffer_set_modelview_matrix -cogl_framebuffer_set_projection_matrix -cogl_framebuffer_set_samples_per_pixel -cogl_framebuffer_set_viewport -cogl_framebuffer_transform -cogl_framebuffer_translate -cogl_framebuffer_vdraw_attributes -/* cogl_framebuffer_vdraw_indexed_attributes */ /* Not Implemented! */ - -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_frame_closure_get_gtype -#endif -cogl_frame_info_get_frame_counter - -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_frame_info_get_gtype -#endif -cogl_frame_info_get_output -cogl_frame_info_get_presentation_time -cogl_frame_info_get_refresh_rate - -cogl_frustum - -cogl_get_backface_culling_enabled -cogl_get_bitmasks -cogl_get_clock_time -cogl_get_depth_test_enabled -cogl_get_draw_framebuffer -cogl_get_features -cogl_get_graphics_reset_status -cogl_get_modelview_matrix -cogl_get_option_group -cogl_get_proc_address -cogl_get_projection_matrix -cogl_get_rectangle_indices -cogl_get_source -cogl_get_static_identity_quaternion -cogl_get_static_zero_quaternion -cogl_get_viewport - -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_gles2_context_get_gtype -#endif -cogl_gles2_context_get_vtable -cogl_gles2_context_new -cogl_gles2_get_current_vtable -cogl_gles2_texture_get_handle -cogl_gles2_texture_2d_new_from_handle - -#ifdef COGL_HAS_GLIB_SUPPORT -cogl_glib_renderer_source_new -cogl_glib_source_new -#endif - -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_gtype_matrix_get_type -#endif - -cogl_handle_get_type -cogl_handle_ref -cogl_handle_unref - -cogl_has_feature -cogl_has_features - -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_index_buffer_get_gtype -#endif -cogl_index_buffer_new -cogl_indices_get_buffer -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_indices_get_gtype -#endif -cogl_indices_get_offset -cogl_indices_get_type -cogl_indices_new -cogl_indices_new_for_buffer -cogl_indices_set_offset -cogl_indices_type_get_type - -cogl_is_atlas_texture -cogl_is_attribute -cogl_is_attribute_buffer -cogl_is_bitmap -cogl_is_buffer -cogl_is_context -cogl_is_frame_info -cogl_is_gles2_context -cogl_is_index_buffer -#if 0 -/* not implemented! */ -cogl_is_indices_array -#endif -cogl_is_material -cogl_is_matrix_stack -cogl_is_offscreen -cogl_is_output -cogl_is_pipeline -cogl_is_pixel_buffer -cogl_is_primitive -cogl_is_primitive_texture -cogl_is_program -cogl_is_renderer -cogl_is_shader -cogl_is_snippet -cogl_is_sub_texture -cogl_is_texture -#ifdef COGL_HAS_X11 -cogl_is_texture_pixmap_x11 -#endif -cogl_is_texture_rectangle -cogl_is_texture_2d -cogl_is_texture_3d - -#ifdef COGL_HAS_EGL_PLATFORM_KMS_SUPPORT -cogl_kms_display_queue_modes_reset -cogl_kms_display_set_layout -cogl_kms_renderer_get_kms_fd -#endif - -cogl_material_alpha_func_get_type -cogl_material_copy -cogl_material_filter_get_type -cogl_material_foreach_layer -cogl_material_get_ambient -cogl_material_get_color -cogl_material_get_depth_state -cogl_material_get_diffuse -cogl_material_get_emission -cogl_material_get_layers -cogl_material_get_layer_point_sprite_coords_enabled -cogl_material_get_layer_wrap_mode_p -cogl_material_get_layer_wrap_mode_s -cogl_material_get_layer_wrap_mode_t -cogl_material_get_n_layers -cogl_material_get_point_size -cogl_material_get_shininess -cogl_material_get_specular -cogl_material_get_user_program -cogl_material_layer_get_mag_filter -cogl_material_layer_get_min_filter -cogl_material_layer_get_texture -cogl_material_layer_get_type -cogl_material_layer_get_wrap_mode_p -cogl_material_layer_get_wrap_mode_s -cogl_material_layer_get_wrap_mode_t -cogl_material_layer_type_get_type -cogl_material_new -cogl_material_remove_layer -#ifndef COGL_DISABLE_DEPRECATED -cogl_material_ref -#endif -cogl_material_set_alpha_test_function -cogl_material_set_ambient -cogl_material_set_ambient_and_diffuse -cogl_material_set_blend -cogl_material_set_blend_constant -cogl_material_set_color -cogl_material_set_color4f -cogl_material_set_color4ub -cogl_material_set_depth_state -cogl_material_set_diffuse -cogl_material_set_emission -cogl_material_set_layer -cogl_material_set_layer_combine -cogl_material_set_layer_combine_constant -cogl_material_set_layer_filters -cogl_material_set_layer_matrix -cogl_material_set_layer_point_sprite_coords_enabled -cogl_material_set_layer_wrap_mode -cogl_material_set_layer_wrap_mode_p -cogl_material_set_layer_wrap_mode_s -cogl_material_set_layer_wrap_mode_t -cogl_material_set_point_size -cogl_material_set_shininess -cogl_material_set_specular -cogl_material_set_user_program -#ifndef COGL_DISABLE_DEPRECATED -cogl_material_unref -#endif -cogl_material_wrap_mode_get_type - -cogl_matrix_copy -cogl_matrix_entry_calculate_translation -cogl_matrix_entry_equal -cogl_matrix_entry_get -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_matrix_entry_get_gtype -#endif -cogl_matrix_entry_is_identity -cogl_matrix_entry_ref -cogl_matrix_entry_unref -cogl_matrix_equal -cogl_matrix_free -cogl_matrix_frustum -cogl_matrix_get_array -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_matrix_get_gtype -#endif -cogl_matrix_get_inverse -cogl_matrix_init_from_array -cogl_matrix_init_translation -cogl_matrix_is_identity -cogl_matrix_init_from_euler -cogl_matrix_init_from_quaternion -cogl_matrix_init_identity -cogl_matrix_look_at -cogl_matrix_multiply -#ifndef COGL_DISABLE_DEPRECATED -cogl_matrix_ortho -#endif -cogl_matrix_orthographic -cogl_matrix_perspective -cogl_matrix_project_points -cogl_matrix_rotate - -#ifdef COGL_ENABLE_EXPERIMENTAL_API -cogl_matrix_rotate_euler -cogl_matrix_rotate_quaternion -#endif - -cogl_matrix_scale -cogl_matrix_stack_frustum -cogl_matrix_stack_get -cogl_matrix_stack_get_entry -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_matrix_stack_get_gtype -#endif -cogl_matrix_stack_get_inverse -cogl_matrix_stack_load_identity -cogl_matrix_stack_multiply -cogl_matrix_stack_new -cogl_matrix_stack_orthographic -cogl_matrix_stack_perspective -cogl_matrix_stack_pop -cogl_matrix_stack_push -cogl_matrix_stack_rotate -cogl_matrix_stack_rotate_euler -cogl_matrix_stack_rotate_quaternion -cogl_matrix_stack_scale -cogl_matrix_stack_set -cogl_matrix_stack_translate -cogl_matrix_transform_point -cogl_matrix_transform_points -cogl_matrix_translate -cogl_matrix_transpose -cogl_matrix_view_2d_in_frustum -cogl_matrix_view_2d_in_perspective - -cogl_meta_texture_foreach_in_region - -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_object_get_gtype -#endif -cogl_object_get_user_data -cogl_object_ref -cogl_object_set_user_data -cogl_object_unref - -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_offscreen_get_gtype -#endif -cogl_offscreen_new_to_texture -cogl_offscreen_new_with_texture - -cogl_onscreen_add_dirty_callback -cogl_onscreen_add_frame_callback -cogl_onscreen_add_resize_callback -cogl_onscreen_add_swap_buffers_callback -#ifndef COGL_WINSYS_INTEGRATED -cogl_onscreen_clutter_backend_set_size_CLUTTER -#endif -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_onscreen_dirty_closure_get_gtype -#endif -cogl_onscreen_get_buffer_age -cogl_onscreen_get_frame_counter -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_onscreen_get_gtype -#endif -cogl_onscreen_get_resizable -cogl_onscreen_hide -cogl_onscreen_new -cogl_onscreen_set_swap_throttled -cogl_onscreen_remove_dirty_callback -cogl_onscreen_remove_frame_callback -cogl_onscreen_remove_resize_callback -cogl_onscreen_remove_swap_buffers_callback -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_onscreen_resize_closure_get_gtype -#endif -cogl_onscreen_set_resizable -cogl_onscreen_set_swap_throttled -cogl_onscreen_show -cogl_onscreen_swap_buffers -cogl_onscreen_swap_buffers_with_damage -cogl_onscreen_swap_region -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_onscreen_template_get_gtype -#endif -cogl_onscreen_template_new -cogl_onscreen_template_set_samples_per_pixel -cogl_onscreen_template_set_swap_throttled - -cogl_ortho - -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_output_get_gtype -#endif -cogl_output_get_height -cogl_output_get_mm_height -cogl_output_get_mm_width -cogl_output_get_refresh_rate -cogl_output_get_subpixel_order -cogl_output_get_width -cogl_output_get_x -cogl_output_get_y - -cogl_perspective - -cogl_pipeline_add_layer_snippet -cogl_pipeline_add_snippet -cogl_pipeline_copy -cogl_pipeline_foreach_layer -cogl_pipeline_get_alpha_test_function -cogl_pipeline_get_alpha_test_reference -cogl_pipeline_get_ambient -cogl_pipeline_get_color -cogl_pipeline_get_color_mask -cogl_pipeline_get_cull_face_mode -cogl_pipeline_get_depth_state -cogl_pipeline_get_diffuse -cogl_pipeline_get_emission -cogl_pipeline_get_front_face_winding -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_pipeline_get_gtype -#endif -cogl_pipeline_get_layer_mag_filter -cogl_pipeline_get_layer_min_filter -cogl_pipeline_get_layer_point_sprite_coords_enabled -cogl_pipeline_get_layer_texture -cogl_pipeline_get_layer_wrap_mode_p -cogl_pipeline_get_layer_wrap_mode_s -cogl_pipeline_get_layer_wrap_mode_t -cogl_pipeline_get_n_layers -cogl_pipeline_get_per_vertex_point_size -cogl_pipeline_get_point_size -cogl_pipeline_get_shininess -cogl_pipeline_get_specular -cogl_pipeline_get_uniform_location -cogl_pipeline_get_user_program -cogl_pipeline_new -cogl_pipeline_set_alpha_test_function -cogl_pipeline_set_ambient -cogl_pipeline_set_ambient_and_diffuse -cogl_pipeline_set_blend -cogl_pipeline_set_blend_constant -cogl_pipeline_set_color -cogl_pipeline_set_color_mask -cogl_pipeline_set_color4f -cogl_pipeline_set_color4ub -cogl_pipeline_set_cull_face_mode -cogl_pipeline_set_depth_state -cogl_pipeline_set_diffuse -cogl_pipeline_set_emission -cogl_pipeline_set_front_face_winding -cogl_pipeline_set_layer_combine -cogl_pipeline_set_layer_combine_constant -cogl_pipeline_set_layer_filters -cogl_pipeline_set_layer_matrix -cogl_pipeline_set_layer_null_texture -cogl_pipeline_set_layer_point_sprite_coords_enabled -cogl_pipeline_set_layer_texture -cogl_pipeline_set_layer_wrap_mode -cogl_pipeline_set_layer_wrap_mode_p -cogl_pipeline_set_layer_wrap_mode_s -cogl_pipeline_set_layer_wrap_mode_t -cogl_pipeline_set_per_vertex_point_size -cogl_pipeline_set_point_size -cogl_pipeline_remove_layer -cogl_pipeline_set_shininess -cogl_pipeline_set_specular -cogl_pipeline_set_uniform_float -cogl_pipeline_set_uniform_int -cogl_pipeline_set_uniform_matrix -cogl_pipeline_set_uniform_1f -cogl_pipeline_set_uniform_1i -cogl_pipeline_set_user_program - -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_pixel_buffer_get_gtype -#endif -cogl_pixel_buffer_new -#if 0 -/* not exported in the main APIs for now */ -cogl_pixel_buffer_set_region -#endif -cogl_pixel_format_get_type - -cogl_poll_renderer_dispatch -cogl_poll_renderer_get_info - -cogl_polygon - -#ifndef COGL_DISABLE_DEPRECATED -cogl_pop_draw_buffer -#endif -cogl_pop_framebuffer -cogl_pop_gles2_context -cogl_pop_matrix -cogl_pop_source - -cogl_primitive_copy -cogl_primitive_foreach_attribute -cogl_primitive_get_first_vertex -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_primitive_get_gtype -#endif -cogl_primitive_get_indices -cogl_primitive_get_mode -cogl_primitive_get_n_vertices -cogl_primitive_new -cogl_primitive_new_p2 -cogl_primitive_new_p2c4 -cogl_primitive_new_p2t2 -cogl_primitive_new_p2t2c4 -cogl_primitive_new_p3 -cogl_primitive_new_p3c4 -cogl_primitive_new_p3t2 -cogl_primitive_new_p3t2c4 -cogl_primitive_new_with_attributes -cogl_primitive_set_attributes -cogl_primitive_set_first_vertex -cogl_primitive_set_indices -cogl_primitive_set_mode -cogl_primitive_set_n_vertices -cogl_primitive_draw - -cogl_primitive_texture_set_auto_mipmap - -cogl_program_attach_shader -cogl_program_get_uniform_location -cogl_program_link - -#ifndef COGL_DISABLE_DEPRECATED -cogl_program_ref -#endif - -cogl_program_set_uniform_float -cogl_program_set_uniform_int -cogl_program_set_uniform_matrix -cogl_program_set_uniform_1f -cogl_program_set_uniform_1i - -#ifndef COGL_DISABLE_DEPRECATED -cogl_program_uniform_float -cogl_program_uniform_int -cogl_program_uniform_matrix -cogl_program_uniform_1f -cogl_program_uniform_1i -cogl_program_unref -#endif - -cogl_program_use - -#ifndef COGL_DISABLE_DEPRECATED -cogl_push_draw_buffer -#endif - -cogl_push_framebuffer -cogl_push_gles2_context -cogl_push_matrix -cogl_push_source - -cogl_quaternion_copy -cogl_quaternion_dot_product -cogl_quaternion_equal -cogl_quaternion_free -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_quaternion_get_gtype -#endif -cogl_quaternion_get_rotation_angle -cogl_quaternion_get_rotation_axis -cogl_quaternion_init -cogl_quaternion_init_from_angle_vector -cogl_quaternion_init_from_array -cogl_quaternion_init_from_euler -cogl_quaternion_init_from_x_rotation -cogl_quaternion_init_from_y_rotation -cogl_quaternion_init_from_z_rotation -cogl_quaternion_init_identity -cogl_quaternion_invert -cogl_quaternion_multiply -cogl_quaternion_nlerp -cogl_quaternion_normalize -cogl_quaternion_pow -cogl_quaternion_slerp -cogl_quaternion_squad - -cogl_read_pixels -cogl_read_pixels_flags_get_type - -cogl_rectangle -cogl_rectangles -cogl_rectangles_with_texture_coords -cogl_rectangle_with_multitexture_coords -cogl_rectangle_with_texture_coords - -cogl_renderer_add_constraint -cogl_renderer_check_onscreen_template -cogl_renderer_connect -cogl_renderer_foreach_output -cogl_renderer_get_driver -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_renderer_get_gtype -#endif -cogl_renderer_get_n_fragment_texture_units -cogl_renderer_error_get_type -cogl_renderer_get_winsys_id -cogl_renderer_new -cogl_renderer_remove_constraint -cogl_renderer_set_driver -cogl_renderer_set_winsys_id - -cogl_rotate - -cogl_scale - -cogl_set_backface_culling_enabled -cogl_set_depth_test_enabled -#ifndef COGL_DISABLE_DEPRECATED -cogl_set_draw_buffer -#endif -cogl_set_fog -#ifdef COGL_HAS_SDL_SUPPORT -cogl_sdl_context_new -cogl_sdl_handle_event -cogl_sdl_idle -#if SDL_MAJOR_VERSION >= 2 -cogl_sdl_onscreen_get_window -#endif -cogl_sdl_renderer_get_event_type -cogl_sdl_renderer_set_event_type -#endif - -cogl_set_framebuffer -cogl_set_modelview_matrix -cogl_set_projection_matrix -cogl_set_source -cogl_set_source_color -cogl_set_source_color4f -cogl_set_source_color4ub -cogl_set_source_texture -cogl_set_viewport - -cogl_shader_compile -cogl_shader_get_info_log -cogl_shader_get_type -cogl_shader_is_compiled - -#ifndef COGL_DISABLE_DEPRECATED -cogl_shader_ref -#endif - -cogl_shader_source -cogl_shader_type_get_type - -#ifndef COGL_DISABLE_DEPRECATED -cogl_shader_unref -#endif - -cogl_snippet_get_declarations -cogl_snippet_get_hook -cogl_snippet_get_post -cogl_snippet_get_pre -cogl_snippet_get_replace -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_snippet_get_gtype -#endif -cogl_snippet_new -cogl_snippet_set_declarations -cogl_snippet_set_post -cogl_snippet_set_pre -cogl_snippet_set_replace - -cogl_sqrti - -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_sub_texture_get_gtype -#endif -cogl_sub_texture_get_parent -cogl_sub_texture_new - -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_swap_chain_get_gtype -#endif -cogl_swap_chain_new -cogl_swap_chain_set_has_alpha -cogl_swap_chain_set_length - -cogl_system_error_get_type - -cogl_texture_allocate -cogl_texture_components_get_type -cogl_texture_error_get_type -cogl_texture_flags_get_type -cogl_texture_get_components -cogl_texture_get_data -cogl_texture_get_format -cogl_texture_get_gl_texture -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_texture_get_gtype -#endif -cogl_texture_get_height -cogl_texture_get_max_waste -cogl_texture_get_premultiplied -cogl_texture_get_rowstride -cogl_texture_get_width -cogl_texture_is_sliced -cogl_texture_new_from_bitmap -cogl_texture_new_from_data -cogl_texture_new_from_file -cogl_texture_new_from_foreign -cogl_texture_new_from_sub_texture -cogl_texture_new_with_size -#ifdef COGL_HAS_X11 -cogl_texture_pixmap_x11_error_domain -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_texture_pixmap_x11_get_gtype -#endif -cogl_texture_pixmap_x11_is_using_tfp_extension -cogl_texture_pixmap_x11_new -cogl_texture_pixmap_x11_set_damage_object -cogl_texture_pixmap_x11_update_area -#endif -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_texture_rectangle_get_gtype -#endif -cogl_texture_rectangle_new_from_bitmap -cogl_texture_rectangle_new_from_foreign -cogl_texture_rectangle_new_with_size -#ifndef COGL_DISABLE_DEPRECATED -cogl_texture_ref -#endif -cogl_texture_set_components -cogl_texture_set_data -cogl_texture_set_premultiplied -cogl_texture_set_region -cogl_texture_set_region_from_bitmap -cogl_texture_type_get_type -#ifndef COGL_DISABLE_DEPRECATED -cogl_texture_unref -#endif -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_texture_2d_get_gtype -#endif -cogl_texture_2d_new_from_bitmap -cogl_texture_2d_new_from_data -cogl_texture_2d_new_from_file -cogl_texture_2d_new_with_size -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_texture_2d_sliced_get_gtype -#endif -cogl_texture_2d_sliced_new_from_bitmap -cogl_texture_2d_sliced_new_from_data -cogl_texture_2d_sliced_new_from_file -cogl_texture_2d_sliced_new_with_size -#ifdef COGL_HAS_GTYPE_SUPPORT -cogl_texture_3d_get_gtype -#endif -cogl_texture_3d_new_from_bitmap -cogl_texture_3d_new_from_data -cogl_texture_3d_new_with_size - -cogl_transform -cogl_translate - -cogl_vector3_add -cogl_vector3_copy -cogl_vector3_cross_product -cogl_vector3_distance -cogl_vector3_divide_scalar -cogl_vector3_dot_product -cogl_vector3_equal -cogl_vector3_equal_with_epsilon -cogl_vector3_free -cogl_vector3_init -cogl_vector3_init_zero -cogl_vector3_invert -cogl_vector3_magnitude -cogl_vector3_multiply_scalar -cogl_vector3_normalize -cogl_vector3_subtract - -cogl_vertex_buffer_add -cogl_vertex_buffer_delete -cogl_vertex_buffer_disable -cogl_vertex_buffer_draw -cogl_vertex_buffer_draw_elements -cogl_vertex_buffer_enable -cogl_vertex_buffer_get_n_vertices -cogl_vertex_buffer_indices_get_for_quads -cogl_vertex_buffer_indices_get_type -cogl_vertex_buffer_indices_new -cogl_vertex_buffer_new -#ifndef COGL_DISABLE_DEPRECATED -cogl_vertex_buffer_ref -#endif -cogl_vertex_buffer_submit -#ifndef COGL_DISABLE_DEPRECATED -cogl_vertex_buffer_unref -#endif - -cogl_vertices_mode_get_type - -#ifdef COGL_DISABLE_DEPRECATED -cogl_viewport -#endif - -cogl_winsys_feature_get_type - -#ifdef COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT -cogl_wayland_display_set_compositor_display -cogl_wayland_onscreen_resize -cogl_wayland_renderer_get_display -cogl_wayland_renderer_set_event_dispatch_enabled -cogl_wayland_renderer_set_foreign_display -cogl_wayland_texture_set_region_from_shm_buffer -cogl_wayland_texture_2d_new_from_buffer -#endif - -cogl_winding_get_type - -#ifdef COGL_HAS_XLIB -cogl_xlib_get_display -cogl_xlib_handle_event -cogl_xlib_renderer_add_filter -cogl_xlib_renderer_get_display -cogl_xlib_renderer_get_foreign_display -cogl_xlib_renderer_get_visual_info -cogl_xlib_renderer_handle_event -cogl_xlib_renderer_remove_filter -cogl_xlib_renderer_request_reset_on_video_memory_purge -cogl_xlib_renderer_set_event_retrieval_enabled -cogl_xlib_renderer_set_foreign_display -cogl_xlib_set_display -#endif - -#ifdef COGL_HAS_X11 -cogl_x11_onscreen_get_visual_xid -cogl_x11_onscreen_set_foreign_window_xid -#endif - -#ifndef COGL_NO_EXPORT_UNDERSCORE -/* probably these should not be exported at all, but anyways, for now... */ -/* eventually, this section should disappear (or cogl, cogl-pango, clutter et al */ -/* will link without the following) */ -_cogl_atlas_add_reorganize_callback -_cogl_atlas_new -_cogl_atlas_reserve_space -_cogl_atlas_texture_add_reorganize_callback -_cogl_atlas_texture_remove_reorganize_callback -_cogl_buffer_map_for_fill_or_fallback -_cogl_buffer_unmap_for_fill_or_fallback -_cogl_clip_stack_push_rectangle -_cogl_clip_stack_push_primitive -_cogl_context_get_default -_cogl_debug_instances -_cogl_framebuffer_get_modelview_stack -_cogl_framebuffer_get_projection_stack -_cogl_framebuffer_get_stencil_bits -_cogl_object_default_unref -_cogl_pipeline_foreach_layer_internal -_cogl_pipeline_layer_get_texture -_cogl_pipeline_prune_to_n_layers -_cogl_primitive_draw -_cogl_system_error_quark -_cogl_texture_can_hardware_repeat -_cogl_texture_get_format -#endif - -cogl_fence_closure_get_user_data -cogl_framebuffer_add_fence_callback -cogl_framebuffer_cancel_fence_callback diff --git a/cogl/cogl/cogl1-context.h b/cogl/cogl/cogl1-context.h index 0f43c198a..755a48452 100644 --- a/cogl/cogl/cogl1-context.h +++ b/cogl/cogl/cogl1-context.h @@ -42,7 +42,7 @@ #include #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS /** * cogl_get_option_group: @@ -56,41 +56,11 @@ COGL_BEGIN_DECLS * Since: 1.0 * Deprecated: 1.16: Not replaced */ -COGL_DEPRECATED_IN_1_16 -GOptionGroup * +COGL_DEPRECATED +COGL_EXPORT GOptionGroup * cogl_get_option_group (void); /* Misc */ -/** - * cogl_get_features: - * - * Returns all of the features supported by COGL. - * - * Return value: A logical OR of all the supported COGL features. - * - * Since: 0.8 - * Deprecated: 1.10: Use cogl_foreach_feature() instead - */ -COGL_DEPRECATED_IN_1_10_FOR (cogl_foreach_feature) -CoglFeatureFlags -cogl_get_features (void); - -/** - * cogl_features_available: - * @features: A bitmask of features to check for - * - * Checks whether the given COGL features are available. Multiple - * features can be checked for by or-ing them together with the '|' - * operator. %TRUE is only returned if all of the requested features - * are available. - * - * Return value: %TRUE if the features are available, %FALSE otherwise. - * Deprecated: 1.10: Use cogl_has_feature() instead - */ -COGL_DEPRECATED_IN_1_10_FOR (cogl_has_feature) -CoglBool -cogl_features_available (CoglFeatureFlags features); - /** * cogl_get_proc_address: (skip) * @name: the name of the function. @@ -106,337 +76,9 @@ cogl_features_available (CoglFeatureFlags features); * Return value: a pointer to the requested function or %NULL if the * function is not available. */ -CoglFuncPtr +COGL_EXPORT GCallback cogl_get_proc_address (const char *name); -/** - * cogl_check_extension: - * @name: extension to check for - * @ext: list of extensions - * - * Check whether @name occurs in list of extensions in @ext. - * - * Return value: %TRUE if the extension occurs in the list, %FALSE otherwise. - * - * Deprecated: 1.2: OpenGL is an implementation detail for Cogl and so it's - * not appropriate to expose OpenGL extensions through the Cogl API. This - * function can be replaced by the following equivalent code: - * |[ - * CoglBool retval = (strstr (ext, name) != NULL) ? TRUE : FALSE; - * ]| - */ -COGL_DEPRECATED -CoglBool -cogl_check_extension (const char *name, - const char *ext); - -/** - * cogl_get_bitmasks: - * @red: (out): Return location for the number of red bits or %NULL - * @green: (out): Return location for the number of green bits or %NULL - * @blue: (out): Return location for the number of blue bits or %NULL - * @alpha: (out): Return location for the number of alpha bits or %NULL - * - * Gets the number of bitplanes used for each of the color components - * in the color buffer. Pass %NULL for any of the arguments if the - * value is not required. - * - * Deprecated: 1.8: Use cogl_framebuffer_get_red/green/blue/alpha_bits() - * instead - */ -COGL_DEPRECATED_IN_1_8_FOR (cogl_framebuffer_get_red_OR_green_OR_blue_OR_alpha_bits) -void -cogl_get_bitmasks (int *red, - int *green, - int *blue, - int *alpha); - -/** - * cogl_perspective: - * @fovy: Vertical field of view angle in degrees. - * @aspect: The (width over height) aspect ratio for display - * @z_near: The distance to the near clipping plane (Must be positive) - * @z_far: The distance to the far clipping plane (Must be positive) - * - * Replaces the current projection matrix with a perspective matrix - * based on the provided values. - * - * You should be careful not to have to great a @z_far / @z_near - * ratio since that will reduce the effectiveness of depth testing - * since there wont be enough precision to identify the depth of - * objects near to each other. - * - * Deprecated: 1.10: Use cogl_framebuffer_perspective() instead - */ -COGL_DEPRECATED_IN_1_10_FOR (cogl_framebuffer_perspective) -void -cogl_perspective (float fovy, - float aspect, - float z_near, - float z_far); - -/** - * cogl_frustum: - * @left: X position of the left clipping plane where it - * intersects the near clipping plane - * @right: X position of the right clipping plane where it - * intersects the near clipping plane - * @bottom: Y position of the bottom clipping plane where it - * intersects the near clipping plane - * @top: Y position of the top clipping plane where it intersects - * the near clipping plane - * @z_near: The distance to the near clipping plane (Must be positive) - * @z_far: The distance to the far clipping plane (Must be positive) - * - * Replaces the current projection matrix with a perspective matrix - * for a given viewing frustum defined by 4 side clip planes that - * all cross through the origin and 2 near and far clip planes. - * - * Since: 0.8.2 - * Deprecated: 1.10: Use cogl_framebuffer_frustum() instead - */ -COGL_DEPRECATED_IN_1_10_FOR (cogl_framebuffer_frustum) -void -cogl_frustum (float left, - float right, - float bottom, - float top, - float z_near, - float z_far); - -/** - * cogl_ortho: - * @left: The coordinate for the left clipping plane - * @right: The coordinate for the right clipping plane - * @bottom: The coordinate for the bottom clipping plane - * @top: The coordinate for the top clipping plane - * @near: The distance to the near clipping - * plane (negative if the plane is behind the viewer) - * @far: The distance for the far clipping - * plane (negative if the plane is behind the viewer) - * - * Replaces the current projection matrix with an orthographic projection - * matrix. See to see how the matrix is - * calculated. - * - *

- * - * - *
- * - * This function copies the arguments from OpenGL's glOrtho() even - * though they are unnecessarily confusing due to the z near and z far - * arguments actually being a "distance" from the origin, where - * negative values are behind the viewer, instead of coordinates for - * the z clipping planes which would have been consistent with the - * left, right bottom and top arguments. - * - * Since: 1.0 - * Deprecated: 1.10: Use cogl_framebuffer_orthographic() instead - */ -COGL_DEPRECATED_IN_1_10_FOR (cogl_framebuffer_orthographic) -void -cogl_ortho (float left, - float right, - float bottom, - float top, - float near, - float far); - -/** - * cogl_viewport: - * @width: Width of the viewport - * @height: Height of the viewport - * - * Replace the current viewport with the given values. - * - * Since: 0.8.2 - * Deprecated: 1.8: Use cogl_framebuffer_set_viewport instead - */ -COGL_DEPRECATED_IN_1_8_FOR (cogl_framebuffer_set_viewport) -void -cogl_viewport (unsigned int width, - unsigned int height); - -/** - * cogl_set_viewport: - * @x: X offset of the viewport - * @y: Y offset of the viewport - * @width: Width of the viewport - * @height: Height of the viewport - * - * Replaces the current viewport with the given values. - * - * Since: 1.2 - * Deprecated: 1.8: Use cogl_framebuffer_set_viewport() instead - */ -COGL_DEPRECATED_IN_1_8_FOR (cogl_framebuffer_set_viewport) -void -cogl_set_viewport (int x, - int y, - int width, - int height); - -/** - * cogl_push_matrix: - * - * Stores the current model-view matrix on the matrix stack. The matrix - * can later be restored with cogl_pop_matrix(). - * - * Deprecated: 1.10: Use cogl_framebuffer_push_matrix() instead - */ -COGL_DEPRECATED_IN_1_10_FOR (cogl_framebuffer_push_matrix) -void -cogl_push_matrix (void); - -/** - * cogl_pop_matrix: - * - * Restores the current model-view matrix from the matrix stack. - * - * Deprecated: 1.10: Use cogl_framebuffer_pop_matrix() instead - */ -COGL_DEPRECATED_IN_1_10_FOR (cogl_framebuffer_push_matrix) -void -cogl_pop_matrix (void); - -/** - * cogl_scale: - * @x: Amount to scale along the x-axis - * @y: Amount to scale along the y-axis - * @z: Amount to scale along the z-axis - * - * Multiplies the current model-view matrix by one that scales the x, - * y and z axes by the given values. - * - * Deprecated: 1.10: Use cogl_framebuffer_pop_matrix() instead - */ -COGL_DEPRECATED_IN_1_10_FOR (cogl_framebuffer_scale) -void -cogl_scale (float x, - float y, - float z); - -/** - * cogl_translate: - * @x: Distance to translate along the x-axis - * @y: Distance to translate along the y-axis - * @z: Distance to translate along the z-axis - * - * Multiplies the current model-view matrix by one that translates the - * model along all three axes according to the given values. - * - * Deprecated: 1.10: Use cogl_framebuffer_translate() instead - */ -COGL_DEPRECATED_IN_1_10_FOR (cogl_framebuffer_translate) -void -cogl_translate (float x, - float y, - float z); - -/** - * cogl_rotate: - * @angle: Angle in degrees to rotate. - * @x: X-component of vertex to rotate around. - * @y: Y-component of vertex to rotate around. - * @z: Z-component of vertex to rotate around. - * - * Multiplies the current model-view matrix by one that rotates the - * model around the vertex specified by @x, @y and @z. The rotation - * follows the right-hand thumb rule so for example rotating by 10 - * degrees about the vertex (0, 0, 1) causes a small counter-clockwise - * rotation. - * - * Deprecated: 1.10: Use cogl_framebuffer_rotate() instead - */ -COGL_DEPRECATED_IN_1_10_FOR (cogl_framebuffer_rotate) -void -cogl_rotate (float angle, - float x, - float y, - float z); - -/** - * cogl_transform: - * @matrix: the matrix to multiply with the current model-view - * - * Multiplies the current model-view matrix by the given matrix. - * - * Since: 1.4 - * Deprecated: 1.10: Use cogl_framebuffer_transform() instead - */ -COGL_DEPRECATED_IN_1_10_FOR (cogl_framebuffer_transform) -void -cogl_transform (const CoglMatrix *matrix); - -/** - * cogl_get_modelview_matrix: - * @matrix: (out): return location for the model-view matrix - * - * Stores the current model-view matrix in @matrix. - * - * Deprecated: 1.10: Use cogl_framebuffer_get_modelview_matrix() - * instead - */ -COGL_DEPRECATED_IN_1_10_FOR (cogl_framebuffer_get_modelview_matrix) -void -cogl_get_modelview_matrix (CoglMatrix *matrix); - -/** - * cogl_set_modelview_matrix: - * @matrix: the new model-view matrix - * - * Loads @matrix as the new model-view matrix. - * - * Deprecated: 1.10: Use cogl_framebuffer_set_modelview_matrix() - * instead - */ -COGL_DEPRECATED_IN_1_10_FOR (cogl_framebuffer_set_modelview_matrix) -void -cogl_set_modelview_matrix (CoglMatrix *matrix); - -/** - * cogl_get_projection_matrix: - * @matrix: (out): return location for the projection matrix - * - * Stores the current projection matrix in @matrix. - * - * Deprecated: 1.10: Use cogl_framebuffer_get_projection_matrix() - * instead - */ -COGL_DEPRECATED_IN_1_10_FOR (cogl_framebuffer_get_projection_matrix) -void -cogl_get_projection_matrix (CoglMatrix *matrix); - -/** - * cogl_set_projection_matrix: - * @matrix: the new projection matrix - * - * Loads matrix as the new projection matrix. - * - * Deprecated: 1.10: Use cogl_framebuffer_set_projection_matrix() - * instead - */ -COGL_DEPRECATED_IN_1_10_FOR (cogl_framebuffer_set_projection_matrix) -void -cogl_set_projection_matrix (CoglMatrix *matrix); - -/** - * cogl_get_viewport: - * @v: (out) (array fixed-size=4): pointer to a 4 element array - * of #floats to receive the viewport dimensions. - * - * Stores the current viewport in @v. @v[0] and @v[1] get the x and y - * position of the viewport and @v[2] and @v[3] get the width and - * height. - * - * Deprecated: 1.10: Use cogl_framebuffer_get_viewport4fv() - * instead - */ -COGL_DEPRECATED_IN_1_10_FOR (cogl_framebuffer_get_viewport4fv) -void -cogl_get_viewport (float v[4]); - /** * cogl_set_depth_test_enabled: * @setting: %TRUE to enable depth testing or %FALSE to disable. @@ -449,9 +91,9 @@ cogl_get_viewport (float v[4]); * * Deprecated: 1.16: Use cogl_pipeline_set_depth_state() instead */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_set_depth_state) -void -cogl_set_depth_test_enabled (CoglBool setting); +COGL_DEPRECATED_FOR (cogl_pipeline_set_depth_state) +COGL_EXPORT void +cogl_set_depth_test_enabled (gboolean setting); /** * cogl_get_depth_test_enabled: @@ -462,8 +104,8 @@ cogl_set_depth_test_enabled (CoglBool setting); * * Deprecated: 1.16: Use cogl_pipeline_set_depth_state() instead */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_set_depth_state) -CoglBool +COGL_DEPRECATED_FOR (cogl_pipeline_set_depth_state) +COGL_EXPORT gboolean cogl_get_depth_test_enabled (void); /** @@ -478,9 +120,9 @@ cogl_get_depth_test_enabled (void); * * Deprecated: 1.16: Use cogl_pipeline_set_cull_face_mode() instead */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_set_cull_face_mode) -void -cogl_set_backface_culling_enabled (CoglBool setting); +COGL_DEPRECATED_FOR (cogl_pipeline_set_cull_face_mode) +COGL_EXPORT void +cogl_set_backface_culling_enabled (gboolean setting); /** * cogl_get_backface_culling_enabled: @@ -492,251 +134,10 @@ cogl_set_backface_culling_enabled (CoglBool setting); * * Deprecated: 1.16: Use cogl_pipeline_get_cull_face_mode() instead */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_get_cull_face_mode) -CoglBool +COGL_DEPRECATED_FOR (cogl_pipeline_get_cull_face_mode) +COGL_EXPORT gboolean cogl_get_backface_culling_enabled (void); -/** - * cogl_set_fog: - * @fog_color: The color of the fog - * @mode: A #CoglFogMode that determines the equation used to calculate the - * fogging blend factor. - * @density: Used by %COGL_FOG_MODE_EXPONENTIAL and by - * %COGL_FOG_MODE_EXPONENTIAL_SQUARED equations. - * @z_near: Position along Z axis where no fogging should be applied - * @z_far: Position along Z axis where full fogging should be applied - * - * Enables fogging. Fogging causes vertices that are further away from the eye - * to be rendered with a different color. The color is determined according to - * the chosen fog mode; at it's simplest the color is linearly interpolated so - * that vertices at @z_near are drawn fully with their original color and - * vertices at @z_far are drawn fully with @fog_color. Fogging will remain - * enabled until you call cogl_disable_fog(). - * - * The fogging functions only work correctly when primitives use - * unmultiplied alpha colors. By default Cogl will premultiply textures - * and cogl_set_source_color() will premultiply colors, so unless you - * explicitly load your textures requesting an unmultiplied internal format - * and use cogl_material_set_color() you can only use fogging with fully - * opaque primitives. This might improve in the future when we can depend - * on fragment shaders. - * - * Deprecated: 1.16: Use #CoglSnippet shader api for fog - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_API) -void -cogl_set_fog (const CoglColor *fog_color, - CoglFogMode mode, - float density, - float z_near, - float z_far); - -/** - * cogl_disable_fog: - * - * This function disables fogging, so primitives drawn afterwards will not be - * blended with any previously set fog color. - * - * Deprecated: 1.16: Use #CoglSnippet shader api for fog - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_API) -void -cogl_disable_fog (void); - -/** - * cogl_clear: - * @color: Background color to clear to - * @buffers: A mask of #CoglBufferBit's identifying which auxiliary - * buffers to clear - * - * Clears all the auxiliary buffers identified in the @buffers mask, and if - * that includes the color buffer then the specified @color is used. - * - * Deprecated: 1.16: Use cogl_framebuffer_clear() api instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_framebuffer_clear) -void -cogl_clear (const CoglColor *color, - unsigned long buffers); - -/** - * cogl_set_source: - * @material: A #CoglMaterial - * - * This function changes the material at the top of the source stack. - * The material at the top of this stack defines the GPU state used to - * process subsequent primitives, such as rectangles drawn with - * cogl_rectangle() or vertices drawn using cogl_vertex_buffer_draw(). - * - * Since: 1.0 - * Deprecated: 1.16: Latest drawing apis all take an explicit - * #CoglPipeline argument so this stack of - * #CoglMaterials shouldn't be used. - */ -COGL_DEPRECATED_IN_1_16 -void -cogl_set_source (void *material); - -/** - * cogl_get_source: - * - * Returns the current source material as previously set using - * cogl_set_source(). - * - * You should typically consider the returned material immutable - * and not try to change any of its properties unless you own a - * reference to that material. At times you may be able to get a - * reference to an internally managed materials and the result of - * modifying such materials is undefined. - * - * Return value: The current source material. - * - * Since: 1.6 - * Deprecated: 1.16: Latest drawing apis all take an explicit - * #CoglPipeline argument so this stack of - * #CoglMaterials shouldn't be used. - */ -COGL_DEPRECATED_IN_1_16 -void * -cogl_get_source (void); - -/** - * cogl_push_source: - * @material: A #CoglMaterial - * - * Pushes the given @material to the top of the source stack. The - * material at the top of this stack defines the GPU state used to - * process later primitives as defined by cogl_set_source(). - * - * Since: 1.6 - * Deprecated: 1.16: Latest drawing apis all take an explicit - * #CoglPipeline argument so this stack of - * #CoglMaterials shouldn't be used. - */ -COGL_DEPRECATED_IN_1_16 -void -cogl_push_source (void *material); - -/** - * cogl_pop_source: - * - * Removes the material at the top of the source stack. The material - * at the top of this stack defines the GPU state used to process - * later primitives as defined by cogl_set_source(). - * - * Since: 1.6 - * Deprecated: 1.16: Latest drawing apis all take an explicit - * #CoglPipeline argument so this stack of - * #CoglMaterials shouldn't be used. - */ -COGL_DEPRECATED_IN_1_16 -void -cogl_pop_source (void); - -/** - * cogl_set_source_color: - * @color: a #CoglColor - * - * This is a convenience function for creating a solid fill source material - * from the given color. This color will be used for any subsequent drawing - * operation. - * - * The color will be premultiplied by Cogl, so the color should be - * non-premultiplied. For example: use (1.0, 0.0, 0.0, 0.5) for - * semi-transparent red. - * - * See also cogl_set_source_color4ub() and cogl_set_source_color4f() - * if you already have the color components. - * - * Since: 1.0 - * Deprecated: 1.16: Latest drawing apis all take an explicit - * #CoglPipeline argument so this stack of - * #CoglMaterials shouldn't be used. - */ -COGL_DEPRECATED_IN_1_16 -void -cogl_set_source_color (const CoglColor *color); - -/** - * cogl_set_source_color4ub: - * @red: value of the red channel, between 0 and 255 - * @green: value of the green channel, between 0 and 255 - * @blue: value of the blue channel, between 0 and 255 - * @alpha: value of the alpha channel, between 0 and 255 - * - * This is a convenience function for creating a solid fill source material - * from the given color using unsigned bytes for each component. This - * color will be used for any subsequent drawing operation. - * - * The value for each component is an unsigned byte in the range - * between 0 and 255. - * - * Since: 1.0 - * Deprecated: 1.16: Latest drawing apis all take an explicit - * #CoglPipeline argument so this stack of - * #CoglMaterials shouldn't be used. - */ -COGL_DEPRECATED_IN_1_16 -void -cogl_set_source_color4ub (uint8_t red, - uint8_t green, - uint8_t blue, - uint8_t alpha); - -/** - * cogl_set_source_color4f: - * @red: value of the red channel, between 0 and %1.0 - * @green: value of the green channel, between 0 and %1.0 - * @blue: value of the blue channel, between 0 and %1.0 - * @alpha: value of the alpha channel, between 0 and %1.0 - * - * This is a convenience function for creating a solid fill source material - * from the given color using normalized values for each component. This color - * will be used for any subsequent drawing operation. - * - * The value for each component is a fixed point number in the range - * between 0 and %1.0. If the values passed in are outside that - * range, they will be clamped. - * - * Since: 1.0 - * Deprecated: 1.16: Latest drawing apis all take an explicit - * #CoglPipeline argument so this stack of - * #CoglMaterials shouldn't be used. - */ -COGL_DEPRECATED_IN_1_16 -void -cogl_set_source_color4f (float red, - float green, - float blue, - float alpha); - -/** - * cogl_set_source_texture: - * @texture: The #CoglTexture you want as your source - * - * This is a convenience function for creating a material with the first - * layer set to @texture and setting that material as the source with - * cogl_set_source. - * - * Note: There is no interaction between calls to cogl_set_source_color - * and cogl_set_source_texture. If you need to blend a texture with a color then - * you can create a simple material like this: - * - * material = cogl_material_new (); - * cogl_material_set_color4ub (material, 0xff, 0x00, 0x00, 0x80); - * cogl_material_set_layer (material, 0, tex_handle); - * cogl_set_source (material); - * - * - * Since: 1.0 - * Deprecated: 1.16: Latest drawing apis all take an explicit - * #CoglPipeline argument so this stack of - * #CoglMaterials shouldn't be used. - */ -COGL_DEPRECATED_IN_1_16 -void -cogl_set_source_texture (CoglTexture *texture); - /** * cogl_flush: * @@ -763,100 +164,9 @@ cogl_set_source_texture (CoglTexture *texture); * * Since: 1.0 */ -void +COGL_EXPORT void cogl_flush (void); -/** - * cogl_begin_gl: - * - * We do not advise nor reliably support the interleaving of raw GL drawing and - * Cogl drawing functions, but if you insist, cogl_begin_gl() and cogl_end_gl() - * provide a simple mechanism that may at least give you a fighting chance of - * succeeding. - * - * Note: this doesn't help you modify the behaviour of Cogl drawing functions - * through the modification of GL state; that will never be reliably supported, - * but if you are trying to do something like: - * - * |[ - * { - * - setup some OpenGL state. - * - draw using OpenGL (e.g. glDrawArrays() ) - * - reset modified OpenGL state. - * - continue using Cogl to draw - * } - * ]| - * - * You should surround blocks of drawing using raw GL with cogl_begin_gl() - * and cogl_end_gl(): - * - * |[ - * { - * cogl_begin_gl (); - * - setup some OpenGL state. - * - draw using OpenGL (e.g. glDrawArrays() ) - * - reset modified OpenGL state. - * cogl_end_gl (); - * - continue using Cogl to draw - * } - * ]| - * - * Don't ever try and do: - * - * |[ - * { - * - setup some OpenGL state. - * - use Cogl to draw - * - reset modified OpenGL state. - * } - * ]| - * - * When the internals of Cogl evolves, this is very liable to break. - * - * This function will flush all batched primitives, and subsequently flush - * all internal Cogl state to OpenGL as if it were going to draw something - * itself. - * - * The result is that the OpenGL modelview matrix will be setup; the state - * corresponding to the current source material will be set up and other world - * state such as backface culling, depth and fogging enabledness will be sent - * to OpenGL. - * - * No special material state is flushed, so if you want Cogl to setup a - * simplified material state it is your responsibility to set a simple source - * material before calling cogl_begin_gl(). E.g. by calling - * cogl_set_source_color4ub(). - * - * It is your responsibility to restore any OpenGL state that you modify - * to how it was after calling cogl_begin_gl() if you don't do this then the - * result of further Cogl calls is undefined. - * - * You can not nest begin/end blocks. - * - * Again we would like to stress, we do not advise the use of this API and if - * possible we would prefer to improve Cogl than have developers require raw - * OpenGL. - * - * Since: 1.0 - * Deprecated: 1.16: Use the #CoglGLES2Context api instead - */ -COGL_DEPRECATED_IN_1_16_FOR (CoglGLES2Context_API) -void -cogl_begin_gl (void); - -/** - * cogl_end_gl: - * - * This is the counterpart to cogl_begin_gl() used to delimit blocks of drawing - * code using raw OpenGL. Please refer to cogl_begin_gl() for full details. - * - * Since: 1.0 - * Deprecated: 1.16: Use the #CoglGLES2Context api instead - */ -COGL_DEPRECATED_IN_1_16_FOR (CoglGLES2Context_API) -void -cogl_end_gl (void); - -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_1_CONTEXT_H__ */ diff --git a/cogl/cogl/deprecated/cogl-auto-texture.c b/cogl/cogl/deprecated/cogl-auto-texture.c index fe52e1575..ca009ee9a 100644 --- a/cogl/cogl/deprecated/cogl-auto-texture.c +++ b/cogl/cogl/deprecated/cogl-auto-texture.c @@ -47,10 +47,7 @@ #include "cogl-object.h" #include "cogl-bitmap-private.h" #include "cogl-atlas-texture-private.h" -#include "cogl-error-private.h" -#include "cogl-texture-rectangle.h" #include "cogl-sub-texture.h" -#include "cogl-texture-2d-gl.h" #include "deprecated/cogl-auto-texture.h" @@ -58,8 +55,8 @@ static CoglTexture * _cogl_texture_new_from_bitmap (CoglBitmap *bitmap, CoglTextureFlags flags, CoglPixelFormat internal_format, - CoglBool can_convert_in_place, - CoglError **error); + gboolean can_convert_in_place, + GError **error); static void set_auto_mipmap_cb (CoglTexture *sub_texture, @@ -78,29 +75,22 @@ cogl_texture_new_with_size (unsigned int width, CoglPixelFormat internal_format) { CoglTexture *tex; - CoglError *skip_error = NULL; + GError *skip_error = NULL; _COGL_GET_CONTEXT (ctx, NULL); - if ((_cogl_util_is_pot (width) && _cogl_util_is_pot (height)) || - (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_BASIC) && - cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP))) - { - /* First try creating a fast-path non-sliced texture */ - tex = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx, width, height)); + /* First try creating a fast-path non-sliced texture */ + tex = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx, width, height)); - _cogl_texture_set_internal_format (tex, internal_format); + _cogl_texture_set_internal_format (tex, internal_format); - if (!cogl_texture_allocate (tex, &skip_error)) - { - cogl_error_free (skip_error); - skip_error = NULL; - cogl_object_unref (tex); - tex = NULL; - } + if (!cogl_texture_allocate (tex, &skip_error)) + { + g_error_free (skip_error); + skip_error = NULL; + cogl_object_unref (tex); + tex = NULL; } - else - tex = NULL; if (!tex) { @@ -119,7 +109,7 @@ cogl_texture_new_with_size (unsigned int width, * semantics and return NULL if allocation fails... */ if (!cogl_texture_allocate (tex, &skip_error)) { - cogl_error_free (skip_error); + g_error_free (skip_error); cogl_object_unref (tex); return NULL; } @@ -147,17 +137,18 @@ _cogl_texture_new_from_data (CoglContext *ctx, CoglPixelFormat internal_format, int rowstride, const uint8_t *data, - CoglError **error) + GError **error) { CoglBitmap *bmp; CoglTexture *tex; - _COGL_RETURN_VAL_IF_FAIL (format != COGL_PIXEL_FORMAT_ANY, NULL); - _COGL_RETURN_VAL_IF_FAIL (data != NULL, NULL); + g_return_val_if_fail (format != COGL_PIXEL_FORMAT_ANY, NULL); + g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, NULL); + g_return_val_if_fail (data != NULL, NULL); /* Rowstride from width if not given */ if (rowstride == 0) - rowstride = width * _cogl_pixel_format_get_bytes_per_pixel (format); + rowstride = width * cogl_pixel_format_get_bytes_per_pixel (format, 0); /* Wrap the data into a bitmap */ bmp = cogl_bitmap_new_for_data (ctx, @@ -186,7 +177,7 @@ cogl_texture_new_from_data (int width, int rowstride, const uint8_t *data) { - CoglError *ignore_error = NULL; + GError *ignore_error = NULL; CoglTexture *tex; _COGL_GET_CONTEXT (ctx, NULL); @@ -199,7 +190,7 @@ cogl_texture_new_from_data (int width, data, &ignore_error); if (!tex) - cogl_error_free (ignore_error); + g_error_free (ignore_error); return tex; } @@ -207,12 +198,11 @@ static CoglTexture * _cogl_texture_new_from_bitmap (CoglBitmap *bitmap, CoglTextureFlags flags, CoglPixelFormat internal_format, - CoglBool can_convert_in_place, - CoglError **error) + gboolean can_convert_in_place, + GError **error) { - CoglContext *ctx = _cogl_bitmap_get_context (bitmap); CoglTexture *tex; - CoglError *internal_error = NULL; + GError *internal_error = NULL; if (!flags && !COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_ATLAS)) @@ -228,32 +218,24 @@ _cogl_texture_new_from_bitmap (CoglBitmap *bitmap, if (cogl_texture_allocate (COGL_TEXTURE (atlas_tex), &internal_error)) return COGL_TEXTURE (atlas_tex); - cogl_error_free (internal_error); + g_error_free (internal_error); internal_error = NULL; cogl_object_unref (atlas_tex); } /* If that doesn't work try a fast path 2D texture */ - if ((_cogl_util_is_pot (bitmap->width) && - _cogl_util_is_pot (bitmap->height)) || - (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_BASIC) && - cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP))) - { - tex = COGL_TEXTURE (_cogl_texture_2d_new_from_bitmap (bitmap, - can_convert_in_place)); + tex = COGL_TEXTURE (_cogl_texture_2d_new_from_bitmap (bitmap, + can_convert_in_place)); - _cogl_texture_set_internal_format (tex, internal_format); + _cogl_texture_set_internal_format (tex, internal_format); - if (!cogl_texture_allocate (tex, &internal_error)) - { - cogl_error_free (internal_error); - internal_error = NULL; - cogl_object_unref (tex); - tex = NULL; - } + if (!cogl_texture_allocate (tex, &internal_error)) + { + g_error_free (internal_error); + internal_error = NULL; + cogl_object_unref (tex); + tex = NULL; } - else - tex = NULL; if (!tex) { @@ -291,7 +273,7 @@ cogl_texture_new_from_bitmap (CoglBitmap *bitmap, CoglTextureFlags flags, CoglPixelFormat internal_format) { - CoglError *ignore_error = NULL; + GError *ignore_error = NULL; CoglTexture *tex = _cogl_texture_new_from_bitmap (bitmap, flags, @@ -299,7 +281,7 @@ cogl_texture_new_from_bitmap (CoglBitmap *bitmap, FALSE, /* can't convert in-place */ &ignore_error); if (!tex) - cogl_error_free (ignore_error); + g_error_free (ignore_error); return tex; } @@ -307,14 +289,14 @@ CoglTexture * cogl_texture_new_from_file (const char *filename, CoglTextureFlags flags, CoglPixelFormat internal_format, - CoglError **error) + GError **error) { CoglBitmap *bmp; CoglTexture *texture = NULL; _COGL_GET_CONTEXT (ctx, NULL); - _COGL_RETURN_VAL_IF_FAIL (error == NULL || *error == NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); bmp = cogl_bitmap_new_from_file (filename, error); if (bmp == NULL) @@ -330,82 +312,6 @@ cogl_texture_new_from_file (const char *filename, return texture; } -CoglTexture * -cogl_texture_new_from_foreign (GLuint gl_handle, - GLenum gl_target, - GLuint width, - GLuint height, - GLuint x_pot_waste, - GLuint y_pot_waste, - CoglPixelFormat format) -{ - _COGL_GET_CONTEXT (ctx, NULL); - -#ifdef HAVE_COGL_GL - if (gl_target == GL_TEXTURE_RECTANGLE_ARB) - { - CoglTextureRectangle *texture_rectangle; - CoglSubTexture *sub_texture; - - if (x_pot_waste != 0 || y_pot_waste != 0) - { - /* It shouldn't be necessary to have waste in this case since - * the texture isn't limited to power of two sizes. */ - g_warning ("You can't create a foreign GL_TEXTURE_RECTANGLE cogl " - "texture with waste\n"); - return NULL; - } - - texture_rectangle = cogl_texture_rectangle_new_from_foreign (ctx, - gl_handle, - width, - height, - format); - _cogl_texture_set_internal_format (COGL_TEXTURE (texture_rectangle), - format); - - /* CoglTextureRectangle textures work with non-normalized - * coordinates, but the semantics for this function that people - * depend on are that all returned texture works with normalized - * coordinates so we wrap with a CoglSubTexture... */ - sub_texture = cogl_sub_texture_new (ctx, - COGL_TEXTURE (texture_rectangle), - 0, 0, width, height); - return COGL_TEXTURE (sub_texture); - } -#endif - - if (x_pot_waste != 0 || y_pot_waste != 0) - { - CoglTexture *tex = - COGL_TEXTURE (_cogl_texture_2d_sliced_new_from_foreign (ctx, - gl_handle, - gl_target, - width, - height, - x_pot_waste, - y_pot_waste, - format)); - _cogl_texture_set_internal_format (tex, format); - - cogl_texture_allocate (tex, NULL); - return tex; - } - else - { - CoglTexture *tex = - COGL_TEXTURE (cogl_texture_2d_gl_new_from_foreign (ctx, - gl_handle, - width, - height, - format)); - _cogl_texture_set_internal_format (tex, format); - - cogl_texture_allocate (tex, NULL); - return tex; - } -} - CoglTexture * cogl_texture_new_from_sub_texture (CoglTexture *full_texture, int sub_x, diff --git a/cogl/cogl/deprecated/cogl-auto-texture.h b/cogl/cogl/deprecated/cogl-auto-texture.h index 44e868d88..61ac84ed2 100644 --- a/cogl/cogl/deprecated/cogl-auto-texture.h +++ b/cogl/cogl/deprecated/cogl-auto-texture.h @@ -31,7 +31,7 @@ #ifndef __COGL_AUTO_TEXTURE_H__ #define __COGL_AUTO_TEXTURE_H__ -COGL_BEGIN_DECLS +G_BEGIN_DECLS #include @@ -51,8 +51,8 @@ COGL_BEGIN_DECLS * Deprecated: 1.18: Use specific constructors such as * cogl_texture_2d_new_with_size() */ -COGL_DEPRECATED_IN_1_18_FOR(cogl_texture_2d_new_with_size__OR__cogl_texture_2d_sliced_new_with_size) -CoglTexture * +COGL_DEPRECATED_FOR (cogl_texture_2d_new_with_size__OR__cogl_texture_2d_sliced_new_with_size) +COGL_EXPORT CoglTexture * cogl_texture_new_with_size (unsigned int width, unsigned int height, CoglTextureFlags flags, @@ -70,7 +70,7 @@ cogl_texture_new_with_size (unsigned int width, * have non-premultiplied source data and are going to adjust the blend * mode (see cogl_material_set_blend()) or use the data for something * other than straight blending. - * @error: return location for a #CoglError or %NULL + * @error: return location for a #GError or %NULL * * Creates a #CoglTexture from an image file. * @@ -81,12 +81,12 @@ cogl_texture_new_with_size (unsigned int width, * Deprecated: 1.18: Use specific constructors such as * cogl_texture_2d_new_from_file() */ -COGL_DEPRECATED_IN_1_18_FOR(cogl_texture_2d_new_from_file__OR__cogl_texture_2d_sliced_new_from_file) -CoglTexture * +COGL_DEPRECATED_FOR (cogl_texture_2d_new_from_file__OR__cogl_texture_2d_sliced_new_from_file) +COGL_EXPORT CoglTexture * cogl_texture_new_from_file (const char *filename, CoglTextureFlags flags, CoglPixelFormat internal_format, - CoglError **error); + GError **error); /** * cogl_texture_new_from_data: @@ -104,7 +104,7 @@ cogl_texture_new_from_file (const char *filename, * something other than straight blending. * @rowstride: the memory offset in bytes between the starts of * scanlines in @data - * @data: pointer the memory region where the source buffer resides + * @data: (array): pointer the memory region where the source buffer resides * * Creates a new #CoglTexture based on data residing in memory. * @@ -115,8 +115,8 @@ cogl_texture_new_from_file (const char *filename, * Deprecated: 1.18: Use specific constructors such as * cogl_texture_2d_new_from_data() */ -COGL_DEPRECATED_IN_1_18_FOR(cogl_texture_2d_new_from_data__OR__cogl_texture_2d_sliced_new_from_data) -CoglTexture * +COGL_DEPRECATED_FOR (cogl_texture_2d_new_from_data__OR__cogl_texture_2d_sliced_new_from_data) +COGL_EXPORT CoglTexture * cogl_texture_new_from_data (int width, int height, CoglTextureFlags flags, @@ -125,44 +125,6 @@ cogl_texture_new_from_data (int width, int rowstride, const uint8_t *data); -/** - * cogl_texture_new_from_foreign: - * @gl_handle: opengl handle of foreign texture. - * @gl_target: opengl target type of foreign texture - * @width: width of foreign texture - * @height: height of foreign texture. - * @x_pot_waste: horizontal waste on the right hand edge of the texture. - * @y_pot_waste: vertical waste on the bottom edge of the texture. - * @format: format of the foreign texture. - * - * Creates a #CoglTexture based on an existing OpenGL texture; the - * width, height and format are passed along since it is not always - * possible to query these from OpenGL. - * - * The waste arguments allow you to create a Cogl texture that maps to - * a region smaller than the real OpenGL texture. For instance if your - * hardware only supports power-of-two textures you may load a - * non-power-of-two image into a larger power-of-two texture and use - * the waste arguments to tell Cogl which region should be mapped to - * the texture coordinate range [0:1]. - * - * Return value: (transfer full): A newly created #CoglTexture or - * %NULL on failure - * - * Since: 0.8 - * Deprecated: 1.18: Use specific constructors such as - * cogl_texture_2d_new_from_foreign() - */ -COGL_DEPRECATED_IN_1_18_FOR(cogl_texture_2d_new_from_foreign) -CoglTexture * -cogl_texture_new_from_foreign (unsigned int gl_handle, - unsigned int gl_target, - unsigned int width, - unsigned int height, - unsigned int x_pot_waste, - unsigned int y_pot_waste, - CoglPixelFormat format); - /** * cogl_texture_new_from_bitmap: * @bitmap: A #CoglBitmap pointer @@ -179,8 +141,8 @@ cogl_texture_new_from_foreign (unsigned int gl_handle, * Deprecated: 1.18: Use specific constructors such as * cogl_texture_2d_new_from_bitmap() */ -COGL_DEPRECATED_IN_1_18_FOR(cogl_texture_2d_new_from_bitmap__OR__cogl_texture_2d_sliced_new_from_bitmap) -CoglTexture * +COGL_DEPRECATED_FOR (cogl_texture_2d_new_from_bitmap__OR__cogl_texture_2d_sliced_new_from_bitmap) +COGL_EXPORT CoglTexture * cogl_texture_new_from_bitmap (CoglBitmap *bitmap, CoglTextureFlags flags, CoglPixelFormat internal_format); @@ -198,8 +160,7 @@ cogl_texture_new_from_bitmap (CoglBitmap *bitmap, * data is actually allocated. * * Sub textures have undefined behaviour texture coordinates outside - * of the range [0,1] are used. They also do not work with - * CoglVertexBuffers. + * of the range [0,1] are used. * * The sub texture will keep a reference to the full texture so you do * not need to keep one separately if you only want to use the sub @@ -210,14 +171,14 @@ cogl_texture_new_from_bitmap (CoglBitmap *bitmap, * Since: 1.2 * Deprecated: 1.18: Use cogl_sub_texture_new() */ -COGL_DEPRECATED_IN_1_18_FOR(cogl_sub_texture_new) -CoglTexture * +COGL_DEPRECATED_FOR (cogl_sub_texture_new) +COGL_EXPORT CoglTexture * cogl_texture_new_from_sub_texture (CoglTexture *full_texture, int sub_x, int sub_y, int sub_width, int sub_height); -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_AUTO_TEXTURE_H__ */ diff --git a/cogl/cogl/deprecated/cogl-clutter-xlib.h b/cogl/cogl/deprecated/cogl-clutter-xlib.h deleted file mode 100644 index dc7300a8b..000000000 --- a/cogl/cogl/deprecated/cogl-clutter-xlib.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#if !defined(__COGL_XLIB_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL_CLUTTER_XLIB_H__ -#define __COGL_CLUTTER_XLIB_H__ - -#include - -COGL_BEGIN_DECLS - -#define cogl_clutter_winsys_xlib_get_visual_info cogl_clutter_winsys_xlib_get_visual_info_CLUTTER - -/** - * cogl_clutter_winsys_xlib_get_visual_info_CLUTTER: (skip) - */ -XVisualInfo * -cogl_clutter_winsys_xlib_get_visual_info (void); - -COGL_END_DECLS - -#endif /* __COGL_CLUTTER_XLIB_H__ */ diff --git a/cogl/cogl/deprecated/cogl-clutter.c b/cogl/cogl/deprecated/cogl-clutter.c index 6c972f2bd..a2528c8be 100644 --- a/cogl/cogl/deprecated/cogl-clutter.c +++ b/cogl/cogl/deprecated/cogl-clutter.c @@ -29,9 +29,7 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include #include @@ -40,75 +38,16 @@ #include "cogl-types.h" #include "cogl-private.h" #include "cogl-context-private.h" -#include "cogl-winsys-private.h" -#include "cogl-winsys-stub-private.h" #include "cogl-framebuffer-private.h" #include "cogl-onscreen-private.h" #ifdef COGL_HAS_XLIB_SUPPORT -#include "cogl-clutter-xlib.h" #include "cogl-xlib-renderer.h" #endif -#include "cogl-clutter.h" - -CoglBool -cogl_clutter_check_extension (const char *name, const char *ext) -{ - char *end; - int name_len, n; - - if (name == NULL || ext == NULL) - return FALSE; - - end = (char*)(ext + strlen(ext)); - - name_len = strlen(name); - - while (ext < end) - { - n = strcspn(ext, " "); +#include "winsys/cogl-winsys-private.h" +#include "deprecated/cogl-clutter.h" - if ((name_len == n) && (!strncmp(name, ext, n))) - return TRUE; - ext += (n + 1); - } - - return FALSE; -} - -CoglBool +gboolean cogl_clutter_winsys_has_feature (CoglWinsysFeature feature) { return _cogl_winsys_has_feature (feature); } - -void -cogl_onscreen_clutter_backend_set_size (int width, int height) -{ - CoglFramebuffer *framebuffer; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (_cogl_context_get_winsys (ctx) != _cogl_winsys_stub_get_vtable ()) - return; - - framebuffer = COGL_FRAMEBUFFER (ctx->window_buffer); - - _cogl_framebuffer_winsys_update_size (framebuffer, width, height); -} - -#ifdef COGL_HAS_XLIB_SUPPORT -XVisualInfo * -cogl_clutter_winsys_xlib_get_visual_info (void) -{ - CoglRenderer *renderer; - - _COGL_GET_CONTEXT (ctx, NULL); - - _COGL_RETURN_VAL_IF_FAIL (ctx->display != NULL, NULL); - - renderer = cogl_display_get_renderer (ctx->display); - _COGL_RETURN_VAL_IF_FAIL (renderer != NULL, NULL); - - return cogl_xlib_renderer_get_visual_info (renderer); -} -#endif diff --git a/cogl/cogl/deprecated/cogl-clutter.h b/cogl/cogl/deprecated/cogl-clutter.h index cc6c44644..3cf624d20 100644 --- a/cogl/cogl/deprecated/cogl-clutter.h +++ b/cogl/cogl/deprecated/cogl-clutter.h @@ -33,22 +33,13 @@ #ifndef __COGL_CLUTTER_H__ #define __COGL_CLUTTER_H__ -COGL_BEGIN_DECLS - -#define cogl_clutter_check_extension cogl_clutter_check_extension_CLUTTER -COGL_DEPRECATED_IN_1_16 -CoglBool -cogl_clutter_check_extension (const char *name, const char *ext); +G_BEGIN_DECLS #define cogl_clutter_winsys_has_feature cogl_clutter_winsys_has_feature_CLUTTER COGL_DEPRECATED_FOR (cogl_has_feature) -CoglBool +COGL_EXPORT gboolean cogl_clutter_winsys_has_feature (CoglWinsysFeature feature); -#define cogl_onscreen_clutter_backend_set_size cogl_onscreen_clutter_backend_set_size_CLUTTER -void -cogl_onscreen_clutter_backend_set_size (int width, int height); - -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_CLUTTER_H__ */ diff --git a/cogl/cogl/deprecated/cogl-framebuffer-deprecated.c b/cogl/cogl/deprecated/cogl-framebuffer-deprecated.c deleted file mode 100644 index c1fb5608a..000000000 --- a/cogl/cogl/deprecated/cogl-framebuffer-deprecated.c +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2014 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "cogl-config.h" - -#include "cogl-types.h" -#include "cogl-context-private.h" -#include "cogl-framebuffer-private.h" -#include "cogl-framebuffer-deprecated.h" - -typedef struct _CoglFramebufferStackEntry -{ - CoglFramebuffer *draw_buffer; - CoglFramebuffer *read_buffer; -} CoglFramebufferStackEntry; - - -static CoglFramebufferStackEntry * -create_stack_entry (CoglFramebuffer *draw_buffer, - CoglFramebuffer *read_buffer) -{ - CoglFramebufferStackEntry *entry = g_slice_new (CoglFramebufferStackEntry); - - entry->draw_buffer = draw_buffer; - entry->read_buffer = read_buffer; - - return entry; -} - -GSList * -_cogl_create_framebuffer_stack (void) -{ - CoglFramebufferStackEntry *entry; - GSList *stack = NULL; - - entry = create_stack_entry (NULL, NULL); - - return g_slist_prepend (stack, entry); -} - -void -_cogl_free_framebuffer_stack (GSList *stack) -{ - GSList *l; - - for (l = stack; l != NULL; l = l->next) - { - CoglFramebufferStackEntry *entry = l->data; - - if (entry->draw_buffer) - cogl_object_unref (entry->draw_buffer); - - if (entry->read_buffer) - cogl_object_unref (entry->read_buffer); - - g_slice_free (CoglFramebufferStackEntry, entry); - } - g_slist_free (stack); -} - -static void -notify_buffers_changed (CoglFramebuffer *old_draw_buffer, - CoglFramebuffer *new_draw_buffer, - CoglFramebuffer *old_read_buffer, - CoglFramebuffer *new_read_buffer) -{ - /* XXX: To support the deprecated cogl_set_draw_buffer API we keep - * track of the last onscreen framebuffer that was set so that it - * can be restored if the COGL_WINDOW_BUFFER enum is used. A - * reference isn't taken to the framebuffer because otherwise we - * would have a circular reference between the context and the - * framebuffer. Instead the pointer is set to NULL in - * _cogl_onscreen_free as a kind of a cheap weak reference */ - if (new_draw_buffer && - new_draw_buffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN) - new_draw_buffer->context->window_buffer = new_draw_buffer; -} - -/* Set the current framebuffer without checking if it's already the - * current framebuffer. This is used by cogl_pop_framebuffer while - * the top of the stack is currently not up to date. */ -static void -_cogl_set_framebuffers_real (CoglFramebuffer *draw_buffer, - CoglFramebuffer *read_buffer) -{ - CoglFramebufferStackEntry *entry; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - _COGL_RETURN_IF_FAIL (ctx != NULL); - _COGL_RETURN_IF_FAIL (draw_buffer && read_buffer ? - draw_buffer->context == read_buffer->context : TRUE); - - entry = ctx->framebuffer_stack->data; - - notify_buffers_changed (entry->draw_buffer, - draw_buffer, - entry->read_buffer, - read_buffer); - - if (draw_buffer) - cogl_object_ref (draw_buffer); - if (entry->draw_buffer) - cogl_object_unref (entry->draw_buffer); - - if (read_buffer) - cogl_object_ref (read_buffer); - if (entry->read_buffer) - cogl_object_unref (entry->read_buffer); - - entry->draw_buffer = draw_buffer; - entry->read_buffer = read_buffer; -} - -static void -_cogl_set_framebuffers (CoglFramebuffer *draw_buffer, - CoglFramebuffer *read_buffer) -{ - CoglFramebuffer *current_draw_buffer; - CoglFramebuffer *current_read_buffer; - - _COGL_RETURN_IF_FAIL (cogl_is_framebuffer (draw_buffer)); - _COGL_RETURN_IF_FAIL (cogl_is_framebuffer (read_buffer)); - - current_draw_buffer = cogl_get_draw_framebuffer (); - current_read_buffer = _cogl_get_read_framebuffer (); - - if (current_draw_buffer != draw_buffer || - current_read_buffer != read_buffer) - _cogl_set_framebuffers_real (draw_buffer, read_buffer); -} - -void -cogl_set_framebuffer (CoglFramebuffer *framebuffer) -{ - _cogl_set_framebuffers (framebuffer, framebuffer); -} - -/* XXX: deprecated API */ -void -cogl_set_draw_buffer (CoglBufferTarget target, CoglHandle handle) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (target == COGL_WINDOW_BUFFER) - handle = ctx->window_buffer; - - /* This is deprecated public API. The public API doesn't currently - really expose the concept of separate draw and read buffers so - for the time being this actually just sets both buffers */ - cogl_set_framebuffer (handle); -} - -CoglFramebuffer * -cogl_get_draw_framebuffer (void) -{ - CoglFramebufferStackEntry *entry; - - _COGL_GET_CONTEXT (ctx, NULL); - - g_assert (ctx->framebuffer_stack); - - entry = ctx->framebuffer_stack->data; - - return entry->draw_buffer; -} - -CoglFramebuffer * -_cogl_get_read_framebuffer (void) -{ - CoglFramebufferStackEntry *entry; - - _COGL_GET_CONTEXT (ctx, NULL); - - g_assert (ctx->framebuffer_stack); - - entry = ctx->framebuffer_stack->data; - - return entry->read_buffer; -} - -void -_cogl_push_framebuffers (CoglFramebuffer *draw_buffer, - CoglFramebuffer *read_buffer) -{ - CoglContext *ctx; - CoglFramebuffer *old_draw_buffer, *old_read_buffer; - - _COGL_RETURN_IF_FAIL (cogl_is_framebuffer (draw_buffer)); - _COGL_RETURN_IF_FAIL (cogl_is_framebuffer (read_buffer)); - - ctx = draw_buffer->context; - _COGL_RETURN_IF_FAIL (ctx != NULL); - _COGL_RETURN_IF_FAIL (draw_buffer->context == read_buffer->context); - - _COGL_RETURN_IF_FAIL (ctx->framebuffer_stack != NULL); - - /* Copy the top of the stack so that when we call cogl_set_framebuffer - it will still know what the old framebuffer was */ - old_draw_buffer = cogl_get_draw_framebuffer (); - if (old_draw_buffer) - cogl_object_ref (old_draw_buffer); - old_read_buffer = _cogl_get_read_framebuffer (); - if (old_read_buffer) - cogl_object_ref (old_read_buffer); - ctx->framebuffer_stack = - g_slist_prepend (ctx->framebuffer_stack, - create_stack_entry (old_draw_buffer, - old_read_buffer)); - - _cogl_set_framebuffers (draw_buffer, read_buffer); -} - -void -cogl_push_framebuffer (CoglFramebuffer *buffer) -{ - _cogl_push_framebuffers (buffer, buffer); -} - -/* XXX: deprecated API */ -void -cogl_push_draw_buffer (void) -{ - cogl_push_framebuffer (cogl_get_draw_framebuffer ()); -} - -void -cogl_pop_framebuffer (void) -{ - CoglFramebufferStackEntry *to_pop; - CoglFramebufferStackEntry *to_restore; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - g_assert (ctx->framebuffer_stack != NULL); - g_assert (ctx->framebuffer_stack->next != NULL); - - to_pop = ctx->framebuffer_stack->data; - to_restore = ctx->framebuffer_stack->next->data; - - if (to_pop->draw_buffer != to_restore->draw_buffer || - to_pop->read_buffer != to_restore->read_buffer) - notify_buffers_changed (to_pop->draw_buffer, - to_restore->draw_buffer, - to_pop->read_buffer, - to_restore->read_buffer); - - cogl_object_unref (to_pop->draw_buffer); - cogl_object_unref (to_pop->read_buffer); - g_slice_free (CoglFramebufferStackEntry, to_pop); - - ctx->framebuffer_stack = - g_slist_delete_link (ctx->framebuffer_stack, - ctx->framebuffer_stack); -} - -/* XXX: deprecated API */ -void -cogl_pop_draw_buffer (void) -{ - cogl_pop_framebuffer (); -} - -CoglPixelFormat -cogl_framebuffer_get_color_format (CoglFramebuffer *framebuffer) -{ - return framebuffer->internal_format; -} diff --git a/cogl/cogl/deprecated/cogl-framebuffer-deprecated.h b/cogl/cogl/deprecated/cogl-framebuffer-deprecated.h index 64c3413d2..200dcee03 100644 --- a/cogl/cogl/deprecated/cogl-framebuffer-deprecated.h +++ b/cogl/cogl/deprecated/cogl-framebuffer-deprecated.h @@ -34,7 +34,7 @@ #include #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS /** * cogl_set_framebuffer: (skip) @@ -49,7 +49,7 @@ COGL_BEGIN_DECLS * #CoglFramebuffer arguments so this stack of * framebuffers shouldn't be used anymore. */ -COGL_DEPRECATED_IN_1_16 +COGL_DEPRECATED void cogl_set_framebuffer (CoglFramebuffer *buffer); @@ -134,7 +134,7 @@ cogl_set_framebuffer (CoglFramebuffer *buffer); * #CoglFramebuffer arguments so this stack of * framebuffers shouldn't be used anymore. */ -COGL_DEPRECATED_IN_1_16 +COGL_DEPRECATED void cogl_push_framebuffer (CoglFramebuffer *buffer); @@ -149,117 +149,10 @@ cogl_push_framebuffer (CoglFramebuffer *buffer); * #CoglFramebuffer arguments so this stack of * framebuffers shouldn't be used anymore. */ -COGL_DEPRECATED_IN_1_16 +COGL_DEPRECATED void cogl_pop_framebuffer (void); -/** - * cogl_set_draw_buffer: - * @target: A #CoglBufferTarget that specifies what kind of framebuffer you - * are setting as the render target. - * @offscreen: If you are setting a framebuffer of type COGL_OFFSCREEN_BUFFER - * then this is a CoglHandle for the offscreen buffer. - * - * Redirects all subsequent drawing to the specified framebuffer. This - * can either be an offscreen buffer created with - * cogl_offscreen_new_to_texture () or you can revert to your original - * on screen window buffer. - * - * Deprecated: 1.16: The latest drawing apis take explicit - * #CoglFramebuffer arguments so this stack of - * framebuffers shouldn't be used anymore. - */ -COGL_DEPRECATED_IN_1_16 -void -cogl_set_draw_buffer (CoglBufferTarget target, - CoglHandle offscreen); - -/** - * cogl_push_draw_buffer: - * - * Save cogl_set_draw_buffer() state. - * - * Deprecated: 1.16: The latest drawing apis take explicit - * #CoglFramebuffer arguments so this stack of - * framebuffers shouldn't be used anymore. - */ -COGL_DEPRECATED_IN_1_16 -void -cogl_push_draw_buffer (void); - -/** - * cogl_pop_draw_buffer: - * - * Restore cogl_set_draw_buffer() state. - * - * Deprecated: 1.16: The latest drawing apis take explicit - * #CoglFramebuffer arguments so this stack of - * framebuffers shouldn't be used anymore. - */ -COGL_DEPRECATED_IN_1_16 -void -cogl_pop_draw_buffer (void); - -/** - * cogl_read_pixels: - * @x: The window x position to start reading from - * @y: The window y position to start reading from - * @width: The width of the rectangle you want to read - * @height: The height of the rectangle you want to read - * @source: Identifies which auxillary buffer you want to read - * (only COGL_READ_PIXELS_COLOR_BUFFER supported currently) - * @format: The pixel format you want the result in - * (only COGL_PIXEL_FORMAT_RGBA_8888 supported currently) - * @pixels: The location to write the pixel data. - * - * This reads a rectangle of pixels from the current framebuffer where - * position (0, 0) is the top left. The pixel at (x, y) is the first - * read, and the data is returned with a rowstride of (width * 4). - * - * Currently Cogl assumes that the framebuffer is in a premultiplied - * format so if @format is non-premultiplied it will convert it. To - * read the pixel values without any conversion you should either - * specify a format that doesn't use an alpha channel or use one of - * the formats ending in PRE. - * - * Deprecated: 1.16: Use cogl_framebuffer_read_pixels() instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_framebuffer_read_pixels) -void -cogl_read_pixels (int x, - int y, - int width, - int height, - CoglReadPixelsFlags source, - CoglPixelFormat format, - uint8_t *pixels); - - -/* XXX: Since this api was marked unstable, maybe we can just - * remove this api if we can't find anyone is using it. */ -/** - * cogl_framebuffer_get_color_format: (skip) - * @framebuffer: A #CoglFramebuffer framebuffer - * - * Queries the common #CoglPixelFormat of all color buffers attached - * to this framebuffer. For an offscreen framebuffer created with - * cogl_offscreen_new_with_texture() this will correspond to the format - * of the texture. - * - * This API is deprecated because it is missleading to report a - * #CoglPixelFormat for the internal format of the @framebuffer since - * #CoglPixelFormat is such a precise format description and it's - * only the set of components and the premultiplied alpha status - * that is really known. - * - * Since: 1.8 - * Stability: unstable - * Deprecated 1.18: Removed since it is misleading - */ -COGL_DEPRECATED_IN_1_18 -CoglPixelFormat -cogl_framebuffer_get_color_format (CoglFramebuffer *framebuffer); - -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_FRAMEBUFFER_DEPRECATED_H__ */ diff --git a/cogl/cogl/deprecated/cogl-material-compat.c b/cogl/cogl/deprecated/cogl-material-compat.c index 3084225c1..23c03ea0a 100644 --- a/cogl/cogl/deprecated/cogl-material-compat.c +++ b/cogl/cogl/deprecated/cogl-material-compat.c @@ -29,16 +29,14 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif -#include #include #include #include #include #include +#include G_DEFINE_BOXED_TYPE (CoglMaterial, cogl_material, cogl_object_ref, cogl_object_unref) @@ -50,30 +48,6 @@ cogl_material_new (void) return COGL_MATERIAL (cogl_pipeline_new (ctx)); } -CoglMaterial * -cogl_material_copy (CoglMaterial *source) -{ - return COGL_MATERIAL (cogl_pipeline_copy (COGL_PIPELINE (source))); -} - -CoglHandle -cogl_material_ref (CoglHandle handle) -{ - return cogl_object_ref (handle); -} - -void -cogl_material_unref (CoglHandle handle) -{ - cogl_object_unref (handle); -} - -CoglBool -cogl_is_material (CoglHandle handle) -{ - return cogl_is_pipeline (handle); -} - void cogl_material_set_color (CoglMaterial *material, const CoglColor *color) @@ -92,117 +66,10 @@ cogl_material_set_color4ub (CoglMaterial *material, red, green, blue, alpha); } -void -cogl_material_set_color4f (CoglMaterial *material, - float red, - float green, - float blue, - float alpha) -{ - cogl_pipeline_set_color4f (COGL_PIPELINE (material), - red, green, blue, alpha); -} - -void -cogl_material_get_color (CoglMaterial *material, - CoglColor *color) -{ - cogl_pipeline_get_color (COGL_PIPELINE (material), color); -} - -void -cogl_material_set_ambient (CoglMaterial *material, - const CoglColor *ambient) -{ - cogl_pipeline_set_ambient (COGL_PIPELINE (material), ambient); -} - -void -cogl_material_get_ambient (CoglMaterial *material, - CoglColor *ambient) -{ - cogl_pipeline_get_ambient (COGL_PIPELINE (material), ambient); -} - -void -cogl_material_set_diffuse (CoglMaterial *material, - const CoglColor *diffuse) -{ - cogl_pipeline_set_diffuse (COGL_PIPELINE (material), diffuse); -} - -void -cogl_material_get_diffuse (CoglMaterial *material, - CoglColor *diffuse) -{ - cogl_pipeline_get_diffuse (COGL_PIPELINE (material), diffuse); -} - -void -cogl_material_set_ambient_and_diffuse (CoglMaterial *material, - const CoglColor *color) -{ - cogl_pipeline_set_ambient_and_diffuse (COGL_PIPELINE (material), color); - -} - -void -cogl_material_set_specular (CoglMaterial *material, - const CoglColor *specular) -{ - cogl_pipeline_set_specular (COGL_PIPELINE (material), specular); -} - -void -cogl_material_get_specular (CoglMaterial *material, - CoglColor *specular) -{ - cogl_pipeline_get_specular (COGL_PIPELINE (material), specular); -} - -void -cogl_material_set_shininess (CoglMaterial *material, - float shininess) -{ - cogl_pipeline_set_shininess (COGL_PIPELINE (material), shininess); -} - -float -cogl_material_get_shininess (CoglMaterial *material) -{ - return cogl_pipeline_get_shininess (COGL_PIPELINE (material)); -} - -void -cogl_material_set_emission (CoglMaterial *material, - const CoglColor *emission) -{ - cogl_pipeline_set_emission (COGL_PIPELINE (material), emission); - -} - -void -cogl_material_get_emission (CoglMaterial *material, - CoglColor *emission) -{ - cogl_pipeline_get_emission (COGL_PIPELINE (material), emission); - -} - -void -cogl_material_set_alpha_test_function (CoglMaterial *material, - CoglMaterialAlphaFunc alpha_func, - float alpha_reference) -{ - cogl_pipeline_set_alpha_test_function (COGL_PIPELINE (material), - alpha_func, - alpha_reference); -} - -CoglBool +gboolean cogl_material_set_blend (CoglMaterial *material, const char *blend_string, - CoglError **error) + GError **error) { return cogl_pipeline_set_blend (COGL_PIPELINE (material), blend_string, @@ -223,18 +90,6 @@ cogl_material_set_point_size (CoglMaterial *material, cogl_pipeline_set_point_size (COGL_PIPELINE (material), point_size); } -float -cogl_material_get_point_size (CoglMaterial *material) -{ - return cogl_pipeline_get_point_size (COGL_PIPELINE (material)); -} - -CoglHandle -cogl_material_get_user_program (CoglMaterial *material) -{ - return cogl_pipeline_get_user_program (COGL_PIPELINE (material)); -} - void cogl_material_set_user_program (CoglMaterial *material, CoglHandle program) @@ -251,18 +106,11 @@ cogl_material_set_layer (CoglMaterial *material, layer_index, texture); } -void -cogl_material_remove_layer (CoglMaterial *material, - int layer_index) -{ - cogl_pipeline_remove_layer (COGL_PIPELINE (material), layer_index); -} - -CoglBool +gboolean cogl_material_set_layer_combine (CoglMaterial *material, int layer_index, const char *blend_string, - CoglError **error) + GError **error) { return cogl_pipeline_set_layer_combine (COGL_PIPELINE (material), layer_index, @@ -289,42 +137,6 @@ cogl_material_set_layer_matrix (CoglMaterial *material, layer_index, matrix); } -const GList * -cogl_material_get_layers (CoglMaterial *material) -{ - return _cogl_pipeline_get_layers (COGL_PIPELINE (material)); -} - -int -cogl_material_get_n_layers (CoglMaterial *material) -{ - return cogl_pipeline_get_n_layers (COGL_PIPELINE (material)); -} - -CoglMaterialLayerType -cogl_material_layer_get_type (CoglMaterialLayer *layer) -{ - return COGL_MATERIAL_LAYER_TYPE_TEXTURE; -} - -CoglHandle -cogl_material_layer_get_texture (CoglMaterialLayer *layer) -{ - return _cogl_pipeline_layer_get_texture (COGL_PIPELINE_LAYER (layer)); -} - -CoglMaterialFilter -cogl_material_layer_get_min_filter (CoglMaterialLayer *layer) -{ - return _cogl_pipeline_layer_get_min_filter (COGL_PIPELINE_LAYER (layer)); -} - -CoglMaterialFilter -cogl_material_layer_get_mag_filter (CoglMaterialLayer *layer) -{ - return _cogl_pipeline_layer_get_mag_filter (COGL_PIPELINE_LAYER (layer)); -} - void cogl_material_set_layer_filters (CoglMaterial *material, int layer_index, @@ -337,11 +149,11 @@ cogl_material_set_layer_filters (CoglMaterial *material, mag_filter); } -CoglBool +gboolean cogl_material_set_layer_point_sprite_coords_enabled (CoglMaterial *material, int layer_index, - CoglBool enable, - CoglError **error) + gboolean enable, + GError **error) { CoglPipeline *pipeline = COGL_PIPELINE (material); return cogl_pipeline_set_layer_point_sprite_coords_enabled (pipeline, @@ -349,116 +161,3 @@ cogl_material_set_layer_point_sprite_coords_enabled (CoglMaterial *material, enable, error); } - -CoglBool -cogl_material_get_layer_point_sprite_coords_enabled (CoglMaterial *material, - int layer_index) -{ - CoglPipeline *pipeline = COGL_PIPELINE (material); - return cogl_pipeline_get_layer_point_sprite_coords_enabled (pipeline, - layer_index); -} - -CoglMaterialWrapMode -cogl_material_get_layer_wrap_mode_s (CoglMaterial *material, - int layer_index) -{ - return cogl_pipeline_get_layer_wrap_mode_s (COGL_PIPELINE (material), - layer_index); -} - -void -cogl_material_set_layer_wrap_mode_s (CoglMaterial *material, - int layer_index, - CoglMaterialWrapMode mode) -{ - cogl_pipeline_set_layer_wrap_mode_s (COGL_PIPELINE (material), layer_index, - mode); -} - -CoglMaterialWrapMode -cogl_material_get_layer_wrap_mode_t (CoglMaterial *material, - int layer_index) -{ - return cogl_pipeline_get_layer_wrap_mode_t (COGL_PIPELINE (material), - layer_index); -} - -void -cogl_material_set_layer_wrap_mode_t (CoglMaterial *material, - int layer_index, - CoglMaterialWrapMode mode) -{ - cogl_pipeline_set_layer_wrap_mode_t (COGL_PIPELINE (material), layer_index, - mode); -} - -CoglMaterialWrapMode -cogl_material_get_layer_wrap_mode_p (CoglMaterial *material, - int layer_index) -{ - return cogl_pipeline_get_layer_wrap_mode_p (COGL_PIPELINE (material), - layer_index); -} - -void -cogl_material_set_layer_wrap_mode_p (CoglMaterial *material, - int layer_index, - CoglMaterialWrapMode mode) -{ - cogl_pipeline_set_layer_wrap_mode_p (COGL_PIPELINE (material), layer_index, - mode); -} - -void -cogl_material_set_layer_wrap_mode (CoglMaterial *material, - int layer_index, - CoglMaterialWrapMode mode) -{ - cogl_pipeline_set_layer_wrap_mode (COGL_PIPELINE (material), layer_index, - mode); -} - -CoglMaterialWrapMode -cogl_material_layer_get_wrap_mode_s (CoglMaterialLayer *layer) -{ - return _cogl_pipeline_layer_get_wrap_mode_s (COGL_PIPELINE_LAYER (layer)); -} - -CoglMaterialWrapMode -cogl_material_layer_get_wrap_mode_t (CoglMaterialLayer *layer) -{ - return _cogl_pipeline_layer_get_wrap_mode_t (COGL_PIPELINE_LAYER (layer)); -} - -CoglMaterialWrapMode -cogl_material_layer_get_wrap_mode_p (CoglMaterialLayer *layer) -{ - return _cogl_pipeline_layer_get_wrap_mode_p (COGL_PIPELINE_LAYER (layer)); -} - -void -cogl_material_foreach_layer (CoglMaterial *material, - CoglMaterialLayerCallback callback, - void *user_data) -{ - cogl_pipeline_foreach_layer (COGL_PIPELINE (material), - (CoglPipelineLayerCallback)callback, user_data); -} - -CoglBool -cogl_material_set_depth_state (CoglMaterial *material, - const CoglDepthState *state, - CoglError **error) -{ - return cogl_pipeline_set_depth_state (COGL_PIPELINE (material), - state, error); -} - -void -cogl_material_get_depth_state (CoglMaterial *material, - CoglDepthState *state_out) -{ - cogl_pipeline_get_depth_state (COGL_PIPELINE (material), state_out); -} - diff --git a/cogl/cogl/deprecated/cogl-material-compat.h b/cogl/cogl/deprecated/cogl-material-compat.h index 97f3e9c6a..740322e56 100644 --- a/cogl/cogl/deprecated/cogl-material-compat.h +++ b/cogl/cogl/deprecated/cogl-material-compat.h @@ -38,7 +38,6 @@ #include #include #include -#include #include #include @@ -58,6 +57,7 @@ typedef struct _CoglMaterial CoglMaterial; typedef struct _CoglMaterialLayer CoglMaterialLayer; #define COGL_TYPE_MATERIAL (cogl_material_get_type ()) +COGL_EXPORT GType cogl_material_get_type (void); #define COGL_MATERIAL(OBJECT) ((CoglMaterial *)OBJECT) @@ -89,7 +89,8 @@ GType cogl_material_get_type (void); * possibly referring to multiple neighbouring texels and taking a weighted * average or simply using the nearest texel. */ -typedef enum { +typedef enum +{ COGL_MATERIAL_FILTER_NEAREST = 0x2600, COGL_MATERIAL_FILTER_LINEAR = 0x2601, COGL_MATERIAL_FILTER_NEAREST_MIPMAP_NEAREST = 0x2700, @@ -133,7 +134,8 @@ typedef enum { * XXX: keep the values in sync with the CoglMaterialWrapModeInternal * enum so no conversion is actually needed. */ -typedef enum { +typedef enum +{ COGL_MATERIAL_WRAP_MODE_REPEAT = 0x2901, COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE = 0x812F, COGL_MATERIAL_WRAP_MODE_AUTOMATIC = 0x0207 @@ -148,76 +150,10 @@ typedef enum { * Return value: a pointer to a new #CoglMaterial * Deprecated: 1.16: Use cogl_pipeline_new() instead */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_new) -CoglMaterial * +COGL_DEPRECATED_FOR (cogl_pipeline_new) +COGL_EXPORT CoglMaterial * cogl_material_new (void); -/** - * cogl_material_copy: - * @source: a #CoglMaterial object to copy - * - * Creates a new material with the configuration copied from the - * source material. - * - * We would strongly advise developers to always aim to use - * cogl_material_copy() instead of cogl_material_new() whenever there will - * be any similarity between two materials. Copying a material helps Cogl - * keep track of a materials ancestry which we may use to help minimize GPU - * state changes. - * - * Returns: a pointer to the newly allocated #CoglMaterial - * - * Since: 1.2 - * Deprecated: 1.16: Use cogl_pipeline_copy() instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_copy) -CoglMaterial * -cogl_material_copy (CoglMaterial *source); - -/** - * cogl_material_ref: - * @material: a #CoglMaterial object. - * - * Increment the reference count for a #CoglMaterial. - * - * Return value: the @material. - * - * Since: 1.0 - * - * Deprecated: 1.2: Use cogl_object_ref() instead - */ -COGL_DEPRECATED -CoglHandle -cogl_material_ref (CoglHandle material); - -/** - * cogl_material_unref: - * @material: a #CoglMaterial object. - * - * Decrement the reference count for a #CoglMaterial. - * - * Since: 1.0 - * - * Deprecated: 1.2: Use cogl_object_unref() instead - */ -COGL_DEPRECATED -void -cogl_material_unref (CoglHandle material); - -/** - * cogl_is_material: - * @handle: A CoglHandle - * - * Gets whether the given handle references an existing material object. - * - * Return value: %TRUE if the handle references a #CoglMaterial, - * %FALSE otherwise - * Deprecated: 1.16: Use cogl_is_pipeline() instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_is_pipeline) -CoglBool -cogl_is_material (CoglHandle handle); - /** * cogl_material_set_color: * @material: A #CoglMaterial object @@ -235,8 +171,8 @@ cogl_is_material (CoglHandle handle); * Since: 1.0 * Deprecated: 1.16: Use cogl_pipeline_set_color() instead */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_set_color) -void +COGL_DEPRECATED_FOR (cogl_pipeline_set_color) +COGL_EXPORT void cogl_material_set_color (CoglMaterial *material, const CoglColor *color); @@ -255,246 +191,14 @@ cogl_material_set_color (CoglMaterial *material, * Since: 1.0 * Deprecated: 1.16: Use cogl_pipeline_set_color4ub() instead */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_set_color4ub) -void +COGL_DEPRECATED_FOR (cogl_pipeline_set_color4ub) +COGL_EXPORT void cogl_material_set_color4ub (CoglMaterial *material, uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha); -/** - * cogl_material_set_color4f: - * @material: A #CoglMaterial object - * @red: The red component - * @green: The green component - * @blue: The blue component - * @alpha: The alpha component - * - * Sets the basic color of the material, used when no lighting is enabled. - * - * The default value is (1.0, 1.0, 1.0, 1.0) - * - * Since: 1.0 - * Deprecated: 1.16: Use cogl_pipeline_set_color4f() instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_set_color4f) -void -cogl_material_set_color4f (CoglMaterial *material, - float red, - float green, - float blue, - float alpha); - -/** - * cogl_material_get_color: - * @material: A #CoglMaterial object - * @color: (out): The location to store the color - * - * Retrieves the current material color. - * - * Since: 1.0 - * Deprecated: 1.16: Use cogl_pipeline_get_color() instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_get_color) -void -cogl_material_get_color (CoglMaterial *material, - CoglColor *color); - -/** - * cogl_material_set_ambient: - * @material: A #CoglMaterial object - * @ambient: The components of the desired ambient color - * - * Sets the material's ambient color, in the standard OpenGL lighting - * model. The ambient color affects the overall color of the object. - * - * Since the diffuse color will be intense when the light hits the surface - * directly, the ambient will be most apparent where the light hits at a - * slant. - * - * The default value is (0.2, 0.2, 0.2, 1.0) - * - * Since: 1.0 - * Deprecated: 1.16: Use the #CoglSnippet shader api for lighting - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -void -cogl_material_set_ambient (CoglMaterial *material, - const CoglColor *ambient); - -/** - * cogl_material_get_ambient: - * @material: A #CoglMaterial object - * @ambient: The location to store the ambient color - * - * Retrieves the current ambient color for @material - * - * Since: 1.0 - * Deprecated: 1.16: Use the #CoglSnippet shader api for lighting - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -void -cogl_material_get_ambient (CoglMaterial *material, - CoglColor *ambient); - -/** - * cogl_material_set_diffuse: - * @material: A #CoglMaterial object - * @diffuse: The components of the desired diffuse color - * - * Sets the material's diffuse color, in the standard OpenGL lighting - * model. The diffuse color is most intense where the light hits the - * surface directly - perpendicular to the surface. - * - * The default value is (0.8, 0.8, 0.8, 1.0) - * - * Since: 1.0 - * Deprecated: 1.16: Use the #CoglSnippet shader api for lighting - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -void -cogl_material_set_diffuse (CoglMaterial *material, - const CoglColor *diffuse); - -/** - * cogl_material_get_diffuse: - * @material: A #CoglMaterial object - * @diffuse: The location to store the diffuse color - * - * Retrieves the current diffuse color for @material - * - * Since: 1.0 - * Deprecated: 1.16: Use the #CoglSnippet shader api for lighting - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -void -cogl_material_get_diffuse (CoglMaterial *material, - CoglColor *diffuse); - -/** - * cogl_material_set_ambient_and_diffuse: - * @material: A #CoglMaterial object - * @color: The components of the desired ambient and diffuse colors - * - * Conveniently sets the diffuse and ambient color of @material at the same - * time. See cogl_material_set_ambient() and cogl_material_set_diffuse(). - * - * The default ambient color is (0.2, 0.2, 0.2, 1.0) - * - * The default diffuse color is (0.8, 0.8, 0.8, 1.0) - * - * Since: 1.0 - * Deprecated: 1.16: Use the #CoglSnippet shader api for lighting - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -void -cogl_material_set_ambient_and_diffuse (CoglMaterial *material, - const CoglColor *color); - -/** - * cogl_material_set_specular: - * @material: A #CoglMaterial object - * @specular: The components of the desired specular color - * - * Sets the material's specular color, in the standard OpenGL lighting - * model. The intensity of the specular color depends on the viewport - * position, and is brightest along the lines of reflection. - * - * The default value is (0.0, 0.0, 0.0, 1.0) - * - * Since: 1.0 - * Deprecated: 1.16: Use the #CoglSnippet shader api for lighting - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -void -cogl_material_set_specular (CoglMaterial *material, - const CoglColor *specular); - -/** - * cogl_material_get_specular: - * @material: A #CoglMaterial object - * @specular: The location to store the specular color - * - * Retrieves the materials current specular color. - * - * Since: 1.0 - * Deprecated: 1.16: Use the #CoglSnippet shader api for lighting - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -void -cogl_material_get_specular (CoglMaterial *material, - CoglColor *specular); - -/** - * cogl_material_set_shininess: - * @material: A #CoglMaterial object - * @shininess: The desired shininess; must be >= 0.0 - * - * Sets the shininess of the material, in the standard OpenGL lighting - * model, which determines the size of the specular highlights. A - * higher @shininess will produce smaller highlights which makes the - * object appear more shiny. - * - * The default value is 0.0 - * - * Since: 1.0 - * Deprecated: 1.16: Use the #CoglSnippet shader api for lighting - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -void -cogl_material_set_shininess (CoglMaterial *material, - float shininess); - -/** - * cogl_material_get_shininess: - * @material: A #CoglMaterial object - * - * Retrieves the materials current emission color. - * - * Return value: The materials current shininess value - * - * Since: 1.0 - * Deprecated: 1.16: Use the #CoglSnippet shader api for lighting - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -float -cogl_material_get_shininess (CoglMaterial *material); - -/** - * cogl_material_set_emission: - * @material: A #CoglMaterial object - * @emission: The components of the desired emissive color - * - * Sets the material's emissive color, in the standard OpenGL lighting - * model. It will look like the surface is a light source emitting this - * color. - * - * The default value is (0.0, 0.0, 0.0, 1.0) - * - * Since: 1.0 - * Deprecated: 1.16: Use the #CoglSnippet shader api for lighting - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -void -cogl_material_set_emission (CoglMaterial *material, - const CoglColor *emission); - -/** - * cogl_material_get_emission: - * @material: A #CoglMaterial object - * @emission: The location to store the emission color - * - * Retrieves the materials current emission color. - * - * Since: 1.0 - * Deprecated: 1.16: Use the #CoglSnippet shader api for lighting - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -void -cogl_material_get_emission (CoglMaterial *material, - CoglColor *emission); - /** * CoglMaterialAlphaFunc: * @COGL_MATERIAL_ALPHA_FUNC_NEVER: Never let the fragment through. @@ -517,7 +221,8 @@ cogl_material_get_emission (CoglMaterial *material, * incoming alpha value and a reference alpha value. The #CoglMaterialAlphaFunc * determines how the comparison is done. */ -typedef enum { +typedef enum +{ COGL_MATERIAL_ALPHA_FUNC_NEVER = 0x0200, COGL_MATERIAL_ALPHA_FUNC_LESS = 0x0201, COGL_MATERIAL_ALPHA_FUNC_EQUAL = 0x0202, @@ -546,8 +251,8 @@ typedef enum { * Since: 1.0 * Deprecated: 1.16: Use cogl_pipeline_set_alpha_test_function() instead */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_set_alpha_test_function) -void +COGL_DEPRECATED_FOR (cogl_pipeline_set_alpha_test_function) +COGL_EXPORT void cogl_material_set_alpha_test_function (CoglMaterial *material, CoglMaterialAlphaFunc alpha_func, float alpha_reference); @@ -557,7 +262,7 @@ cogl_material_set_alpha_test_function (CoglMaterial *material, * @material: A #CoglMaterial object * @blend_string: A Cogl blend string * describing the desired blend function. - * @error: return location for a #CoglError that may report lack of driver + * @error: return location for a #GError that may report lack of driver * support if you give separate blend string statements for the alpha * channel and RGB channels since some drivers, or backends such as * GLES 1.1, don't support this feature. May be %NULL, in which case a @@ -637,11 +342,11 @@ cogl_material_set_alpha_test_function (CoglMaterial *material, * Since: 1.0 * Deprecated: 1.16: Use cogl_pipeline_set_blend() instead */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_set_blend) -CoglBool +COGL_DEPRECATED_FOR (cogl_pipeline_set_blend) +COGL_EXPORT gboolean cogl_material_set_blend (CoglMaterial *material, const char *blend_string, - CoglError **error); + GError **error); /** * cogl_material_set_blend_constant: @@ -654,8 +359,8 @@ cogl_material_set_blend (CoglMaterial *material, * Since: 1.0 * Deprecated: 1.16: Use cogl_pipeline_set_blend_constant() instead */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_set_blend_constant) -void +COGL_DEPRECATED_FOR (cogl_pipeline_set_blend_constant) +COGL_EXPORT void cogl_material_set_blend_constant (CoglMaterial *material, const CoglColor *constant_color); @@ -675,44 +380,11 @@ cogl_material_set_blend_constant (CoglMaterial *material, * Since: 1.4 * Deprecated: 1.16: Use cogl_pipeline_set_point_size() instead */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_set_point_size) -void +COGL_DEPRECATED_FOR (cogl_pipeline_set_point_size) +COGL_EXPORT void cogl_material_set_point_size (CoglMaterial *material, float point_size); -/** - * cogl_material_get_point_size: - * @material: a #CoglHandle to a material. - * - * Get the size of points drawn when %COGL_VERTICES_MODE_POINTS is - * used with the vertex buffer API. - * - * Return value: the point size of the material. - * - * Since: 1.4 - * Deprecated: 1.16: Use cogl_pipeline_get_point_size() instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_get_point_size) -float -cogl_material_get_point_size (CoglMaterial *material); - -/** - * cogl_material_get_user_program: - * @material: a #CoglMaterial object. - * - * Queries what user program has been associated with the given - * @material using cogl_material_set_user_program(). - * - * Return value: (transfer none): The current user program - * or %COGL_INVALID_HANDLE. - * - * Since: 1.4 - * Deprecated: 1.16: Use #CoglSnippet api instead instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -CoglHandle -cogl_material_get_user_program (CoglMaterial *material); - /** * cogl_material_set_user_program: * @material: a #CoglMaterial object. @@ -733,7 +405,6 @@ cogl_material_get_user_program (CoglMaterial *material); * "!!ARBfp1.0\n" * "MOV result.color,fragment.color;\n" * "END\n"); - * cogl_shader_compile (shader); * * program = cogl_create_program (); * cogl_program_attach_shader (program, shader); @@ -753,15 +424,11 @@ cogl_material_get_user_program (CoglMaterial *material); * meantime we hope this will handle most practical GLSL and ARBfp * requirements. * - * Also remember you need to check for either the - * %COGL_FEATURE_SHADERS_GLSL or %COGL_FEATURE_SHADERS_ARBFP before - * using the cogl_program or cogl_shader API. - * * Since: 1.4 * Deprecated: 1.16: Use #CoglSnippet api instead instead */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -void +COGL_DEPRECATED_FOR (cogl_snippet_) +COGL_EXPORT void cogl_material_set_user_program (CoglMaterial *material, CoglHandle program); @@ -785,33 +452,19 @@ cogl_material_set_user_program (CoglMaterial *material, * Since: 1.0 * Deprecated: 1.16: Use cogl_pipeline_set_layer() instead */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_set_layer) -void +COGL_DEPRECATED_FOR (cogl_pipeline_set_layer) +COGL_EXPORT void cogl_material_set_layer (CoglMaterial *material, int layer_index, CoglHandle texture); -/** - * cogl_material_remove_layer: - * @material: A #CoglMaterial object - * @layer_index: Specifies the layer you want to remove - * - * This function removes a layer from your material - * Deprecated: 1.16: Use cogl_pipeline_remove_layer() instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_remove_layer) -void -cogl_material_remove_layer (CoglMaterial *material, - int layer_index); - - /** * cogl_material_set_layer_combine: * @material: A #CoglMaterial object * @layer_index: Specifies the layer you want define a combine function for * @blend_string: A Cogl blend string * describing the desired texture combine function. - * @error: A #CoglError that may report parse errors or lack of GPU/driver + * @error: A #GError that may report parse errors or lack of GPU/driver * support. May be %NULL, in which case a warning will be printed out if an * error is encountered. * @@ -898,12 +551,12 @@ cogl_material_remove_layer (CoglMaterial *material, * Since: 1.0 * Deprecated: 1.16: Use cogl_pipeline_set_layer_combine() instead */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_set_layer_combine) -CoglBool +COGL_DEPRECATED_FOR (cogl_pipeline_set_layer_combine) +COGL_EXPORT gboolean cogl_material_set_layer_combine (CoglMaterial *material, int layer_index, const char *blend_string, - CoglError **error); + GError **error); /** * cogl_material_set_layer_combine_constant: @@ -919,8 +572,8 @@ cogl_material_set_layer_combine (CoglMaterial *material, * Deprecated: 1.16: Use cogl_pipeline_set_layer_combine_constant() * instead */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_set_layer_combine_constant) -void +COGL_DEPRECATED_FOR (cogl_pipeline_set_layer_combine_constant) +COGL_EXPORT void cogl_material_set_layer_combine_constant (CoglMaterial *material, int layer_index, const CoglColor *constant); @@ -935,131 +588,12 @@ cogl_material_set_layer_combine_constant (CoglMaterial *material, * and rotate a single layer of a material used to fill your geometry. * Deprecated: 1.16: Use cogl_pipeline_set_layer_matrix() instead */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_set_layer_matrix) -void +COGL_DEPRECATED_FOR (cogl_pipeline_set_layer_matrix) +COGL_EXPORT void cogl_material_set_layer_matrix (CoglMaterial *material, int layer_index, const CoglMatrix *matrix); -/** - * cogl_material_get_layers: - * @material: A #CoglMaterial object - * - * This function lets you access a material's internal list of layers - * for iteration. - * - * You should avoid using this API if possible since it was only - * made public by mistake and will be deprecated when we have - * suitable alternative. - * - * It's important to understand that the list returned may not - * remain valid if you modify the material or any of the layers in any - * way and so you would have to re-get the list in that - * situation. - * - * Return value: (element-type CoglMaterialLayer) (transfer none): A - * list of #CoglMaterialLayer's that can be passed to the - * cogl_material_layer_* functions. The list is owned by Cogl and it - * should not be modified or freed - * Deprecated: 1.16: Use cogl_pipeline_get_layers() instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_get_layers) -const GList * -cogl_material_get_layers (CoglMaterial *material); - -/** - * cogl_material_get_n_layers: - * @material: A #CoglMaterial object - * - * Retrieves the number of layers defined for the given @material - * - * Return value: the number of layers - * - * Since: 1.0 - * Deprecated: 1.16: Use cogl_pipeline_get_n_layers() instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_get_n_layers) -int -cogl_material_get_n_layers (CoglMaterial *material); - -/** - * CoglMaterialLayerType: - * @COGL_MATERIAL_LAYER_TYPE_TEXTURE: The layer represents a - * texture - * - * Available types of layers for a #CoglMaterial. This enumeration - * might be expanded in later versions. - * - * Since: 1.0 - */ -typedef enum { - COGL_MATERIAL_LAYER_TYPE_TEXTURE -} CoglMaterialLayerType; - - -/** - * cogl_material_layer_get_type: - * @layer: A #CoglMaterialLayer object - * - * Retrieves the type of the layer - * - * Currently there is only one type of layer defined: - * %COGL_MATERIAL_LAYER_TYPE_TEXTURE, but considering we may add purely GLSL - * based layers in the future, you should write code that checks the type - * first. - * - * Return value: the type of the layer - * Deprecated: 1.16: No replacement - */ -COGL_DEPRECATED_IN_1_16 -CoglMaterialLayerType -cogl_material_layer_get_type (CoglMaterialLayer *layer); - -/** - * cogl_material_layer_get_texture: - * @layer: A #CoglMaterialLayer object - * - * Extracts a texture handle for a specific layer. - * - * In the future Cogl may support purely GLSL based layers; for those - * layers this function which will likely return %COGL_INVALID_HANDLE if you - * try to get the texture handle from them. Considering this scenario, you - * should call cogl_material_layer_get_type() first in order check it is of - * type %COGL_MATERIAL_LAYER_TYPE_TEXTURE before calling this function. - * - * Return value: (transfer none): a #CoglHandle for the texture inside the layer - * Deprecated: 1.16: No replacement - */ -COGL_DEPRECATED_IN_1_16 -CoglHandle -cogl_material_layer_get_texture (CoglMaterialLayer *layer); - -/** - * cogl_material_layer_get_min_filter: - * @layer: a #CoglHandle for a material layer - * - * Queries the currently set downscaling filter for a material layer - * - * Return value: the current downscaling filter - * Deprecated: 1.16: No replacement - */ -COGL_DEPRECATED_IN_1_16 -CoglMaterialFilter -cogl_material_layer_get_min_filter (CoglMaterialLayer *layer); - -/** - * cogl_material_layer_get_mag_filter: - * @layer: A #CoglMaterialLayer object - * - * Queries the currently set downscaling filter for a material later - * - * Return value: the current downscaling filter - * Deprecated: 1.16: No replacement - */ -COGL_DEPRECATED_IN_1_16 -CoglMaterialFilter -cogl_material_layer_get_mag_filter (CoglMaterialLayer *layer); - /** * cogl_material_set_layer_filters: * @material: A #CoglMaterial object @@ -1071,8 +605,8 @@ cogl_material_layer_get_mag_filter (CoglMaterialLayer *layer); * drawn at other scales than 100%. * Deprecated: 1.16: Use cogl_pipeline_set_layer_filters() instead */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_set_layer_filters) -void +COGL_DEPRECATED_FOR (cogl_pipeline_set_layer_filters) +COGL_EXPORT void cogl_material_set_layer_filters (CoglMaterial *material, int layer_index, CoglMaterialFilter min_filter, @@ -1083,7 +617,7 @@ cogl_material_set_layer_filters (CoglMaterial *material, * @material: a #CoglHandle to a material. * @layer_index: the layer number to change. * @enable: whether to enable point sprite coord generation. - * @error: A return location for a CoglError, or NULL to ignore errors. + * @error: A return location for a GError, or NULL to ignore errors. * * When rendering points, if @enable is %TRUE then the texture * coordinates for this layer will be replaced with coordinates that @@ -1092,299 +626,17 @@ cogl_material_set_layer_filters (CoglMaterial *material, * have 1.0,1.0. If @enable is %FALSE then the coordinates will be * fixed for the entire point. * - * This function will only work if %COGL_FEATURE_POINT_SPRITE is - * available. If the feature is not available then the function will - * return %FALSE and set @error. - * * Return value: %TRUE if the function succeeds, %FALSE otherwise. * Since: 1.4 * Deprecated: 1.16: Use cogl_pipeline_set_layer_point_sprite_coords_enabled() * instead */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_set_layer_point_sprite_coords_enabled) -CoglBool +COGL_DEPRECATED_FOR (cogl_pipeline_set_layer_point_sprite_coords_enabled) +COGL_EXPORT gboolean cogl_material_set_layer_point_sprite_coords_enabled (CoglMaterial *material, int layer_index, - CoglBool enable, - CoglError **error); - -/** - * cogl_material_get_layer_point_sprite_coords_enabled: - * @material: a #CoglHandle to a material. - * @layer_index: the layer number to check. - * - * Gets whether point sprite coordinate generation is enabled for this - * texture layer. - * - * Return value: whether the texture coordinates will be replaced with - * point sprite coordinates. - * - * Since: 1.4 - * Deprecated: 1.16: Use cogl_pipeline_get_layer_point_sprite_coords_enabled() - * instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_get_layer_point_sprite_coords_enabled) -CoglBool -cogl_material_get_layer_point_sprite_coords_enabled (CoglMaterial *material, - int layer_index); - -/** - * cogl_material_get_layer_wrap_mode_s: - * @material: A #CoglMaterial object - * @layer_index: the layer number to change. - * - * Returns the wrap mode for the 's' coordinate of texture lookups on this - * layer. - * - * Return value: the wrap mode for the 's' coordinate of texture lookups on - * this layer. - * - * Since: 1.6 - * Deprecated: 1.16: Use cogl_pipeline_get_layer_wrap_mode_s() instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_get_layer_wrap_mode_s) -CoglMaterialWrapMode -cogl_material_get_layer_wrap_mode_s (CoglMaterial *material, - int layer_index); - -/** - * cogl_material_set_layer_wrap_mode_s: - * @material: A #CoglMaterial object - * @layer_index: the layer number to change. - * @mode: the new wrap mode - * - * Sets the wrap mode for the 's' coordinate of texture lookups on this layer. - * - * Since: 1.4 - * Deprecated: 1.16: Use cogl_pipeline_set_layer_wrap_mode_s() instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_set_layer_wrap_mode_s) -void -cogl_material_set_layer_wrap_mode_s (CoglMaterial *material, - int layer_index, - CoglMaterialWrapMode mode); - -/** - * cogl_material_get_layer_wrap_mode_t: - * @material: A #CoglMaterial object - * @layer_index: the layer number to change. - * - * Returns the wrap mode for the 't' coordinate of texture lookups on this - * layer. - * - * Return value: the wrap mode for the 't' coordinate of texture lookups on - * this layer. - * - * Since: 1.6 - * Deprecated: 1.16: Use cogl_pipeline_get_layer_wrap_mode_t() instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_get_layer_wrap_mode_t) -CoglMaterialWrapMode -cogl_material_get_layer_wrap_mode_t (CoglMaterial *material, - int layer_index); - - -/** - * cogl_material_set_layer_wrap_mode_t: - * @material: A #CoglMaterial object - * @layer_index: the layer number to change. - * @mode: the new wrap mode - * - * Sets the wrap mode for the 't' coordinate of texture lookups on this layer. - * - * Since: 1.4 - * Deprecated: 1.16: Use cogl_pipeline_set_layer_wrap_mode_t() instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_set_layer_wrap_mode_t) -void -cogl_material_set_layer_wrap_mode_t (CoglMaterial *material, - int layer_index, - CoglMaterialWrapMode mode); - -/** - * cogl_material_get_layer_wrap_mode_p: - * @material: A #CoglMaterial object - * @layer_index: the layer number to change. - * - * Returns the wrap mode for the 'p' coordinate of texture lookups on this - * layer. - * - * Return value: the wrap mode for the 'p' coordinate of texture lookups on - * this layer. - * - * Since: 1.6 - * Deprecated: 1.16: Use cogl_pipeline_get_layer_wrap_mode_p() instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_get_layer_wrap_mode_p) -CoglMaterialWrapMode -cogl_material_get_layer_wrap_mode_p (CoglMaterial *material, - int layer_index); - -/** - * cogl_material_set_layer_wrap_mode_p: - * @material: A #CoglMaterial object - * @layer_index: the layer number to change. - * @mode: the new wrap mode - * - * Sets the wrap mode for the 'p' coordinate of texture lookups on - * this layer. 'p' is the third coordinate. - * - * Since: 1.4 - * Deprecated: 1.16: Use cogl_pipeline_set_layer_wrap_mode_p() instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_set_layer_wrap_mode_p) -void -cogl_material_set_layer_wrap_mode_p (CoglMaterial *material, - int layer_index, - CoglMaterialWrapMode mode); - -/** - * cogl_material_set_layer_wrap_mode: - * @material: A #CoglMaterial object - * @layer_index: the layer number to change. - * @mode: the new wrap mode - * - * Sets the wrap mode for all three coordinates of texture lookups on - * this layer. This is equivalent to calling - * cogl_material_set_layer_wrap_mode_s(), - * cogl_material_set_layer_wrap_mode_t() and - * cogl_material_set_layer_wrap_mode_p() separately. - * - * Since: 1.4 - * Deprecated: 1.16: Use cogl_pipeline_set_layer_wrap_mode() instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_set_layer_wrap_mode) -void -cogl_material_set_layer_wrap_mode (CoglMaterial *material, - int layer_index, - CoglMaterialWrapMode mode); - -/** - * cogl_material_layer_get_wrap_mode_s: - * @layer: A #CoglMaterialLayer object - * - * Gets the wrap mode for the 's' coordinate of texture lookups on this layer. - * - * Return value: the wrap mode value for the s coordinate. - * - * Since: 1.4 - * Deprecated: 1.16: Use cogl_pipeline_layer_get_wrap_mode_s() instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_layer_get_wrap_mode_s) -CoglMaterialWrapMode -cogl_material_layer_get_wrap_mode_s (CoglMaterialLayer *layer); - -/** - * cogl_material_layer_get_wrap_mode_t: - * @layer: A #CoglMaterialLayer object - * - * Gets the wrap mode for the 't' coordinate of texture lookups on this layer. - * - * Return value: the wrap mode value for the t coordinate. - * - * Since: 1.4 - * Deprecated: 1.16: Use cogl_pipeline_layer_get_wrap_mode_t() instead - */ - -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_layer_get_wrap_mode_t) -CoglMaterialWrapMode -cogl_material_layer_get_wrap_mode_t (CoglMaterialLayer *layer); - -/** - * cogl_material_layer_get_wrap_mode_p: - * @layer: A #CoglMaterialLayer object - * - * Gets the wrap mode for the 'p' coordinate of texture lookups on - * this layer. 'p' is the third coordinate. - * - * Return value: the wrap mode value for the p coordinate. - * - * Since: 1.4 - * Deprecated: 1.16: Use cogl_pipeline_layer_get_wrap_mode_p() instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_layer_get_wrap_mode_p) -CoglMaterialWrapMode -cogl_material_layer_get_wrap_mode_p (CoglMaterialLayer *layer); - -/** - * cogl_material_set_depth_state: (skip) - * @material: A #CoglMaterial object - * @state: A #CoglDepthState struct - * @error: A #CoglError to report failures to setup the given @state. - * - * This commits all the depth state configured in @state struct to the - * given @material. The configuration values are copied into the - * material so there is no requirement to keep the #CoglDepthState - * struct around if you don't need it any more. - * - * Note: Since some platforms do not support the depth range feature - * it is possible for this function to fail and report an @error. - * - * Returns: TRUE if the GPU supports all the given @state else %FALSE - * and returns an @error. - * - * Since: 1.8 - * Stability: Unstable - * Deprecated: 1.16: Use cogl_pipeline_set_depth_state() instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_set_depth_state) -CoglBool -cogl_material_set_depth_state (CoglMaterial *material, - const CoglDepthState *state, - CoglError **error); - -/** - * cogl_material_get_depth_state: (skip) - * @material: A #CoglMaterial object - * @state_out: A destination #CoglDepthState struct - * - * Retrieves the current depth state configuration for the given - * @pipeline as previously set using cogl_pipeline_set_depth_state(). - * - * Since: 2.0 - * Stability: Unstable - * Deprecated: 1.16: Use cogl_pipeline_get_depth_state() instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_pipeline_get_depth_state) -void -cogl_material_get_depth_state (CoglMaterial *material, - CoglDepthState *state_out); - -/** - * CoglMaterialLayerCallback: - * @material: The #CoglMaterial whos layers are being iterated - * @layer_index: The current layer index - * @user_data: The private data passed to cogl_material_foreach_layer() - * - * The callback prototype used with cogl_material_foreach_layer() for - * iterating all the layers of a @material. - * - * Since: 1.4 - * Stability: Unstable - * Deprecated: 1.16 - */ -typedef CoglBool (*CoglMaterialLayerCallback) (CoglMaterial *material, - int layer_index, - void *user_data); - -/** - * cogl_material_foreach_layer: - * @material: A #CoglMaterial object - * @callback: (scope call): A #CoglMaterialLayerCallback to be called for each - * layer index - * @user_data: Private data that will be passed to the callback - * - * Iterates all the layer indices of the given @material. - * - * Since: 1.4 - * Stability: Unstable - * Deprecated: 1.16: No replacement - */ -COGL_DEPRECATED_IN_1_16 -void -cogl_material_foreach_layer (CoglMaterial *material, - CoglMaterialLayerCallback callback, - void *user_data); + gboolean enable, + GError **error); G_END_DECLS diff --git a/cogl/cogl/deprecated/cogl-program-private.h b/cogl/cogl/deprecated/cogl-program-private.h index 64ed72c6e..38b5f59d8 100644 --- a/cogl/cogl/deprecated/cogl-program-private.h +++ b/cogl/cogl/deprecated/cogl-program-private.h @@ -74,15 +74,12 @@ struct _CoglProgramUniform void _cogl_program_flush_uniforms (CoglProgram *program, GLuint gl_program, - CoglBool gl_program_changed); + gboolean gl_program_changed); -CoglShaderLanguage -_cogl_program_get_language (CoglHandle handle); - -CoglBool +gboolean _cogl_program_has_fragment_shader (CoglHandle handle); -CoglBool +gboolean _cogl_program_has_vertex_shader (CoglHandle handle); #endif /* __COGL_PROGRAM_H */ diff --git a/cogl/cogl/deprecated/cogl-program.c b/cogl/cogl/deprecated/cogl-program.c index 6960b1e98..adf5543d2 100644 --- a/cogl/cogl/deprecated/cogl-program.c +++ b/cogl/cogl/deprecated/cogl-program.c @@ -28,25 +28,21 @@ * */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif - #include "cogl-util.h" -#include "cogl-util-gl-private.h" +#include "driver/gl/cogl-util-gl-private.h" #include "cogl-context-private.h" #include "cogl-object-private.h" -#include "cogl-shader-private.h" -#include "cogl-program-private.h" +#include "deprecated/cogl-shader-private.h" +#include "deprecated/cogl-program-private.h" #include static void _cogl_program_free (CoglProgram *program); COGL_HANDLE_DEFINE (Program, program); -COGL_OBJECT_DEFINE_DEPRECATED_REF_COUNTING (program); /* A CoglProgram is effectively just a list of shaders that will be used together and a set of values for the custom uniforms. No @@ -62,20 +58,18 @@ _cogl_program_free (CoglProgram *program) _COGL_GET_CONTEXT (ctx, NO_RETVAL); - /* Unref all of the attached shaders */ - g_slist_foreach (program->attached_shaders, (GFunc) cogl_handle_unref, NULL); - /* Destroy the list */ - g_slist_free (program->attached_shaders); + /* Unref all of the attached shaders and destroy the list */ + g_slist_free_full (program->attached_shaders, cogl_object_unref); for (i = 0; i < program->custom_uniforms->len; i++) { CoglProgramUniform *uniform = &g_array_index (program->custom_uniforms, CoglProgramUniform, i); - free (uniform->name); + g_free (uniform->name); if (uniform->value.count > 1) - free (uniform->value.v.array); + g_free (uniform->value.v.array); } g_array_free (program->custom_uniforms, TRUE); @@ -102,7 +96,6 @@ cogl_program_attach_shader (CoglHandle program_handle, CoglHandle shader_handle) { CoglProgram *program; - CoglShader *shader; _COGL_GET_CONTEXT (ctx, NO_RETVAL); @@ -110,18 +103,10 @@ cogl_program_attach_shader (CoglHandle program_handle, return; program = program_handle; - shader = shader_handle; - - /* Only one shader is allowed if the type is ARBfp */ - if (shader->language == COGL_SHADER_LANGUAGE_ARBFP) - _COGL_RETURN_IF_FAIL (program->attached_shaders == NULL); - else if (shader->language == COGL_SHADER_LANGUAGE_GLSL) - _COGL_RETURN_IF_FAIL (_cogl_program_get_language (program) == - COGL_SHADER_LANGUAGE_GLSL); program->attached_shaders = g_slist_prepend (program->attached_shaders, - cogl_handle_ref (shader_handle)); + cogl_object_ref (shader_handle)); program->age++; } @@ -134,26 +119,6 @@ cogl_program_link (CoglHandle handle) whenever the settings change */ } -void -cogl_program_use (CoglHandle handle) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - _COGL_RETURN_IF_FAIL (handle == COGL_INVALID_HANDLE || - cogl_is_program (handle)); - - if (ctx->current_program == 0 && handle != 0) - ctx->legacy_state_set++; - else if (handle == 0 && ctx->current_program != 0) - ctx->legacy_state_set--; - - if (handle != COGL_INVALID_HANDLE) - cogl_handle_ref (handle); - if (ctx->current_program != COGL_INVALID_HANDLE) - cogl_handle_unref (ctx->current_program); - ctx->current_program = handle; -} - int cogl_program_get_uniform_location (CoglHandle handle, const char *uniform_name) @@ -201,10 +166,10 @@ cogl_program_modify_uniform (CoglProgram *program, { CoglProgramUniform *uniform; - _COGL_RETURN_VAL_IF_FAIL (cogl_is_program (program), NULL); - _COGL_RETURN_VAL_IF_FAIL (uniform_no >= 0 && - uniform_no < program->custom_uniforms->len, - NULL); + g_return_val_if_fail (cogl_is_program (program), NULL); + g_return_val_if_fail (uniform_no >= 0 && + uniform_no < program->custom_uniforms->len, + NULL); uniform = &g_array_index (program->custom_uniforms, CoglProgramUniform, uniform_no); @@ -213,18 +178,6 @@ cogl_program_modify_uniform (CoglProgram *program, return uniform; } -void -cogl_program_uniform_1f (int uniform_no, - float value) -{ - CoglProgramUniform *uniform; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - uniform = cogl_program_modify_uniform (ctx->current_program, uniform_no); - _cogl_boxed_value_set_1f (&uniform->value, value); -} - void cogl_program_set_uniform_1f (CoglHandle handle, int uniform_location, @@ -236,18 +189,6 @@ cogl_program_set_uniform_1f (CoglHandle handle, _cogl_boxed_value_set_1f (&uniform->value, value); } -void -cogl_program_uniform_1i (int uniform_no, - int value) -{ - CoglProgramUniform *uniform; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - uniform = cogl_program_modify_uniform (ctx->current_program, uniform_no); - _cogl_boxed_value_set_1i (&uniform->value, value); -} - void cogl_program_set_uniform_1i (CoglHandle handle, int uniform_location, @@ -259,20 +200,6 @@ cogl_program_set_uniform_1i (CoglHandle handle, _cogl_boxed_value_set_1i (&uniform->value, value); } -void -cogl_program_uniform_float (int uniform_no, - int size, - int count, - const float *value) -{ - CoglProgramUniform *uniform; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - uniform = cogl_program_modify_uniform (ctx->current_program, uniform_no); - _cogl_boxed_value_set_float (&uniform->value, size, count, value); -} - void cogl_program_set_uniform_float (CoglHandle handle, int uniform_location, @@ -286,20 +213,6 @@ cogl_program_set_uniform_float (CoglHandle handle, _cogl_boxed_value_set_float (&uniform->value, n_components, count, value); } -void -cogl_program_uniform_int (int uniform_no, - int size, - int count, - const int *value) -{ - CoglProgramUniform *uniform; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - uniform = cogl_program_modify_uniform (ctx->current_program, uniform_no); - _cogl_boxed_value_set_int (&uniform->value, size, count, value); -} - void cogl_program_set_uniform_int (CoglHandle handle, int uniform_location, @@ -318,7 +231,7 @@ cogl_program_set_uniform_matrix (CoglHandle handle, int uniform_location, int dimensions, int count, - CoglBool transpose, + gboolean transpose, const float *value) { CoglProgramUniform *uniform; @@ -331,86 +244,16 @@ cogl_program_set_uniform_matrix (CoglHandle handle, value); } -void -cogl_program_uniform_matrix (int uniform_no, - int size, - int count, - CoglBool transpose, - const float *value) -{ - CoglProgramUniform *uniform; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - uniform = cogl_program_modify_uniform (ctx->current_program, uniform_no); - _cogl_boxed_value_set_matrix (&uniform->value, size, count, transpose, value); -} - -/* ARBfp local parameters can be referenced like: - * - * "program.local[5]" - * ^14char offset (after whitespace is stripped) - */ -static int -get_local_param_index (const char *uniform_name) -{ - char *input = g_strdup (uniform_name); - int i; - char *p = input; - char *endptr; - int _index; - - for (i = 0; input[i] != '\0'; i++) - if (input[i] != '_' && input[i] != '\t') - *p++ = input[i]; - input[i] = '\0'; - - _COGL_RETURN_VAL_IF_FAIL (strncmp ("program.local[", input, 14) == 0, -1); - - _index = g_ascii_strtoull (input + 14, &endptr, 10); - _COGL_RETURN_VAL_IF_FAIL (endptr != input + 14, -1); - _COGL_RETURN_VAL_IF_FAIL (*endptr == ']', -1); - - _COGL_RETURN_VAL_IF_FAIL (_index >= 0, -1); - - free (input); - - return _index; -} - -#ifdef HAVE_COGL_GL - -static void -_cogl_program_flush_uniform_arbfp (GLint location, - CoglBoxedValue *value) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (value->type != COGL_BOXED_NONE) - { - _COGL_RETURN_IF_FAIL (value->type == COGL_BOXED_FLOAT); - _COGL_RETURN_IF_FAIL (value->size == 4); - _COGL_RETURN_IF_FAIL (value->count == 1); - - GE( ctx, glProgramLocalParameter4fv (GL_FRAGMENT_PROGRAM_ARB, location, - value->v.float_value) ); - } -} - -#endif /* HAVE_COGL_GL */ - void _cogl_program_flush_uniforms (CoglProgram *program, GLuint gl_program, - CoglBool gl_program_changed) + gboolean gl_program_changed) { CoglProgramUniform *uniform; int i; _COGL_GET_CONTEXT (ctx, NO_RETVAL); - _COGL_RETURN_IF_FAIL (ctx->driver != COGL_DRIVER_GLES1); - for (i = 0; i < program->custom_uniforms->len; i++) { uniform = &g_array_index (program->custom_uniforms, @@ -420,36 +263,19 @@ _cogl_program_flush_uniforms (CoglProgram *program, { if (gl_program_changed || !uniform->location_valid) { - if (_cogl_program_get_language (program) == - COGL_SHADER_LANGUAGE_GLSL) - uniform->location = - ctx->glGetUniformLocation (gl_program, uniform->name); - else - uniform->location = - get_local_param_index (uniform->name); - - uniform->location_valid = TRUE; + uniform->location = + ctx->glGetUniformLocation (gl_program, uniform->name); + + uniform->location_valid = TRUE; } /* If the uniform isn't really in the program then there's no need to actually set it */ if (uniform->location != -1) { - switch (_cogl_program_get_language (program)) - { - case COGL_SHADER_LANGUAGE_GLSL: - _cogl_boxed_value_set_uniform (ctx, - uniform->location, - &uniform->value); - break; - - case COGL_SHADER_LANGUAGE_ARBFP: -#ifdef HAVE_COGL_GL - _cogl_program_flush_uniform_arbfp (uniform->location, - &uniform->value); -#endif - break; - } + _cogl_boxed_value_set_uniform (ctx, + uniform->location, + &uniform->value); } uniform->dirty = FALSE; @@ -457,23 +283,7 @@ _cogl_program_flush_uniforms (CoglProgram *program, } } -CoglShaderLanguage -_cogl_program_get_language (CoglHandle handle) -{ - CoglProgram *program = handle; - - /* Use the language of the first shader */ - - if (program->attached_shaders) - { - CoglShader *shader = program->attached_shaders->data; - return shader->language; - } - else - return COGL_SHADER_LANGUAGE_GLSL; -} - -static CoglBool +static gboolean _cogl_program_has_shader_type (CoglProgram *program, CoglShaderType type) { @@ -490,13 +300,13 @@ _cogl_program_has_shader_type (CoglProgram *program, return FALSE; } -CoglBool +gboolean _cogl_program_has_fragment_shader (CoglHandle handle) { return _cogl_program_has_shader_type (handle, COGL_SHADER_TYPE_FRAGMENT); } -CoglBool +gboolean _cogl_program_has_vertex_shader (CoglHandle handle) { return _cogl_program_has_shader_type (handle, COGL_SHADER_TYPE_VERTEX); diff --git a/cogl/cogl/deprecated/cogl-shader-private.h b/cogl/cogl/deprecated/cogl-shader-private.h index dcc16b924..f19aaa22c 100644 --- a/cogl/cogl/deprecated/cogl-shader-private.h +++ b/cogl/cogl/deprecated/cogl-shader-private.h @@ -38,19 +38,12 @@ typedef struct _CoglShader CoglShader; -typedef enum -{ - COGL_SHADER_LANGUAGE_GLSL, - COGL_SHADER_LANGUAGE_ARBFP -} CoglShaderLanguage; - struct _CoglShader { CoglHandleObject _parent; GLuint gl_handle; CoglPipeline *compilation_pipeline; CoglShaderType type; - CoglShaderLanguage language; char *source; }; @@ -58,9 +51,6 @@ void _cogl_shader_compile_real (CoglHandle handle, CoglPipeline *pipeline); -CoglShaderLanguage -_cogl_program_get_language (CoglHandle handle); - void _cogl_shader_set_source_with_boilerplate (GLuint shader_gl_handle, GLenum shader_gl_type, diff --git a/cogl/cogl/deprecated/cogl-shader.c b/cogl/cogl/deprecated/cogl-shader.c index 4a2af043c..701545477 100644 --- a/cogl/cogl/deprecated/cogl-shader.c +++ b/cogl/cogl/deprecated/cogl-shader.c @@ -28,16 +28,14 @@ * */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif -#include "cogl-shader-private.h" -#include "cogl-util-gl-private.h" #include "cogl-context-private.h" #include "cogl-object-private.h" #include "cogl-glsl-shader-private.h" #include "cogl-glsl-shader-boilerplate.h" +#include "driver/gl/cogl-util-gl-private.h" +#include "deprecated/cogl-shader-private.h" #include @@ -46,7 +44,6 @@ static void _cogl_shader_free (CoglShader *shader); COGL_HANDLE_DEFINE (Shader, shader); -COGL_OBJECT_DEFINE_DEPRECATED_REF_COUNTING (shader); #ifndef GL_FRAGMENT_SHADER #define GL_FRAGMENT_SHADER 0x8B30 @@ -62,14 +59,6 @@ _cogl_shader_free (CoglShader *shader) released! Do that separately before this! */ _COGL_GET_CONTEXT (ctx, NO_RETVAL); -#ifdef HAVE_COGL_GL - if (shader->language == COGL_SHADER_LANGUAGE_ARBFP) - { - if (shader->gl_handle) - GE (ctx, glDeletePrograms (1, &shader->gl_handle)); - } - else -#endif if (shader->gl_handle) GE (ctx, glDeleteShader (shader->gl_handle)); @@ -81,7 +70,7 @@ cogl_create_shader (CoglShaderType type) { CoglShader *shader; - _COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE); + _COGL_GET_CONTEXT (ctx, NULL); switch (type) { @@ -91,11 +80,10 @@ cogl_create_shader (CoglShaderType type) default: g_warning ("Unexpected shader type (0x%08lX) given to " "cogl_create_shader", (unsigned long) type); - return COGL_INVALID_HANDLE; + return NULL; } shader = g_slice_new (CoglShader); - shader->language = COGL_SHADER_LANGUAGE_GLSL; shader->gl_handle = 0; shader->compilation_pipeline = NULL; shader->type = type; @@ -108,18 +96,8 @@ delete_shader (CoglShader *shader) { _COGL_GET_CONTEXT (ctx, NO_RETVAL); -#ifdef HAVE_COGL_GL - if (shader->language == COGL_SHADER_LANGUAGE_ARBFP) - { - if (shader->gl_handle) - GE (ctx, glDeletePrograms (1, &shader->gl_handle)); - } - else -#endif - { - if (shader->gl_handle) - GE (ctx, glDeleteShader (shader->gl_handle)); - } + if (shader->gl_handle) + GE (ctx, glDeleteShader (shader->gl_handle)); shader->gl_handle = 0; @@ -135,7 +113,6 @@ cogl_shader_source (CoglHandle handle, const char *source) { CoglShader *shader; - CoglShaderLanguage language; _COGL_GET_CONTEXT (ctx, NO_RETVAL); @@ -144,47 +121,7 @@ cogl_shader_source (CoglHandle handle, shader = handle; -#ifdef HAVE_COGL_GL - if (strncmp (source, "!!ARBfp1.0", 10) == 0) - language = COGL_SHADER_LANGUAGE_ARBFP; - else -#endif - language = COGL_SHADER_LANGUAGE_GLSL; - - /* Delete the old object if the language is changing... */ - if (G_UNLIKELY (language != shader->language) && - shader->gl_handle) - delete_shader (shader); - shader->source = g_strdup (source); - - shader->language = language; -} - -void -cogl_shader_compile (CoglHandle handle) -{ - CoglShader *shader; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (!cogl_is_shader (handle)) - return; - -#ifdef HAVE_COGL_GL - shader = handle; - if (shader->language == COGL_SHADER_LANGUAGE_ARBFP) - _cogl_shader_compile_real (handle, NULL); -#endif - - /* XXX: For GLSL we don't actually compile anything until the shader - * gets used so we have an opportunity to add some boilerplate to - * the shader. - * - * At the end of the day this is obviously a badly designed API - * given that we are having to lie to the user. It was a mistake to - * so thinly wrap the OpenGL shader API and the current plan is to - * replace it with a pipeline snippets API. */ } void @@ -192,138 +129,70 @@ _cogl_shader_compile_real (CoglHandle handle, CoglPipeline *pipeline) { CoglShader *shader = handle; + GLenum gl_type; + GLint status; _COGL_GET_CONTEXT (ctx, NO_RETVAL); -#ifdef HAVE_COGL_GL - if (shader->language == COGL_SHADER_LANGUAGE_ARBFP) + if (shader->gl_handle) { -#ifdef COGL_GL_DEBUG - GLenum gl_error; -#endif - - if (shader->gl_handle) + CoglPipeline *prev = shader->compilation_pipeline; + + /* XXX: currently the only things that will affect the + * boilerplate for user shaders, apart from driver features, + * are the pipeline layer-indices and texture-unit-indices + */ + if (pipeline == prev || + _cogl_pipeline_layer_and_unit_numbers_equal (prev, pipeline)) return; + } - GE (ctx, glGenPrograms (1, &shader->gl_handle)); + if (shader->gl_handle) + delete_shader (shader); - GE (ctx, glBindProgram (GL_FRAGMENT_PROGRAM_ARB, shader->gl_handle)); + switch (shader->type) + { + case COGL_SHADER_TYPE_VERTEX: + gl_type = GL_VERTEX_SHADER; + break; + case COGL_SHADER_TYPE_FRAGMENT: + gl_type = GL_FRAGMENT_SHADER; + break; + default: + g_assert_not_reached (); + break; + } - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_SHOW_SOURCE))) - g_message ("user ARBfp program:\n%s", shader->source); + shader->gl_handle = ctx->glCreateShader (gl_type); -#ifdef COGL_GL_DEBUG - _cogl_gl_util_clear_gl_errors (ctx); -#endif - ctx->glProgramString (GL_FRAGMENT_PROGRAM_ARB, - GL_PROGRAM_FORMAT_ASCII_ARB, - strlen (shader->source), - shader->source); -#ifdef COGL_GL_DEBUG - gl_error = _cogl_gl_util_get_error (ctx); - if (gl_error != GL_NO_ERROR) - { - g_warning ("%s: GL error (%d): Failed to compile ARBfp:\n%s\n%s", - G_STRLOC, - gl_error, - shader->source, - ctx->glGetString (GL_PROGRAM_ERROR_STRING_ARB)); - } -#endif - } - else -#endif + _cogl_glsl_shader_set_source_with_boilerplate (ctx, + shader->gl_handle, + gl_type, + pipeline, + 1, + (const char **) + &shader->source, + NULL); + + GE (ctx, glCompileShader (shader->gl_handle)); + + shader->compilation_pipeline = cogl_object_ref (pipeline); + + GE (ctx, glGetShaderiv (shader->gl_handle, GL_COMPILE_STATUS, &status)); + if (!status) { - GLenum gl_type; - GLint status; - - if (shader->gl_handle) - { - CoglPipeline *prev = shader->compilation_pipeline; - - /* XXX: currently the only things that will affect the - * boilerplate for user shaders, apart from driver features, - * are the pipeline layer-indices and texture-unit-indices - */ - if (pipeline == prev || - _cogl_pipeline_layer_and_unit_numbers_equal (prev, pipeline)) - return; - } - - if (shader->gl_handle) - delete_shader (shader); - - switch (shader->type) - { - case COGL_SHADER_TYPE_VERTEX: - gl_type = GL_VERTEX_SHADER; - break; - case COGL_SHADER_TYPE_FRAGMENT: - gl_type = GL_FRAGMENT_SHADER; - break; - default: - g_assert_not_reached (); - break; - } - - shader->gl_handle = ctx->glCreateShader (gl_type); - - _cogl_glsl_shader_set_source_with_boilerplate (ctx, - shader->gl_handle, - gl_type, - pipeline, - 1, - (const char **) - &shader->source, - NULL); - - GE (ctx, glCompileShader (shader->gl_handle)); - - shader->compilation_pipeline = cogl_object_ref (pipeline); - - GE (ctx, glGetShaderiv (shader->gl_handle, GL_COMPILE_STATUS, &status)); - if (!status) - { - char buffer[512]; - int len = 0; - - ctx->glGetShaderInfoLog (shader->gl_handle, 511, &len, buffer); - buffer[len] = '\0'; - - g_warning ("Failed to compile GLSL program:\n" - "src:\n%s\n" - "error:\n%s\n", - shader->source, - buffer); - } - } -} + char buffer[512]; + int len = 0; -char * -cogl_shader_get_info_log (CoglHandle handle) -{ - if (!cogl_is_shader (handle)) - return NULL; - - /* XXX: This API doesn't really do anything! - * - * This API is purely for compatibility - * - * The reason we don't do anything is because a shader needs to - * be associated with a CoglPipeline for Cogl to be able to - * compile and link anything. - * - * The way this API was originally designed as a very thin wrapper - * over the GL api was a mistake and it's now very difficult to - * make the API work in a meaningful way given how the rest of Cogl - * has evolved. - * - * The CoglShader API is mostly deprecated by CoglSnippets and so - * these days we do the bare minimum to support the existing users - * of it until they are able to migrate to the snippets api. - */ - - return g_strdup (""); + ctx->glGetShaderInfoLog (shader->gl_handle, 511, &len, buffer); + buffer[len] = '\0'; + + g_warning ("Failed to compile GLSL program:\n" + "src:\n%s\n" + "error:\n%s\n", + shader->source, + buffer); + } } CoglShaderType @@ -342,35 +211,3 @@ cogl_shader_get_type (CoglHandle handle) shader = handle; return shader->type; } - -CoglBool -cogl_shader_is_compiled (CoglHandle handle) -{ -#if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES2) - if (!cogl_is_shader (handle)) - return FALSE; - - /* XXX: This API doesn't really do anything! - * - * This API is purely for compatibility and blatantly lies to the - * user about whether their shader has been compiled. - * - * I suppose we could say we're stretching the definition of - * "compile" and are deferring any related errors to be "linker" - * errors. - * - * The reason we don't do anything is because a shader needs to - * be associated with a CoglPipeline for Cogl to be able to - * compile and link anything. - * - * The CoglShader API is mostly deprecated by CoglSnippets and so - * these days we do the bare minimum to support the existing users - * of it until they are able to migrate to the snippets api. - */ - - return TRUE; - -#else - return FALSE; -#endif -} diff --git a/cogl/cogl/deprecated/cogl-shader.h b/cogl/cogl/deprecated/cogl-shader.h index d664746d9..a7676fa42 100644 --- a/cogl/cogl/deprecated/cogl-shader.h +++ b/cogl/cogl/deprecated/cogl-shader.h @@ -39,7 +39,7 @@ #include #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS /** * SECTION:cogl-shaders @@ -48,11 +48,6 @@ COGL_BEGIN_DECLS * Cogl allows accessing the GL programmable pipeline in order to create * vertex and fragment shaders. * - * The shader source code can either be GLSL or ARBfp. If the source - * code is ARBfp, it must begin with the string “!!ARBfp1.0”. The - * application should check for the %COGL_FEATURE_SHADERS_GLSL or - * %COGL_FEATURE_SHADERS_ARBFP features before using shaders. - * * When using GLSL Cogl provides replacement names for most of the * builtin varyings and uniforms. It is recommended to use these names * wherever possible to increase portability between OpenGL 2.0 and @@ -234,7 +229,8 @@ COGL_BEGIN_DECLS * * Since: 1.0 */ -typedef enum { +typedef enum +{ COGL_SHADER_TYPE_VERTEX, COGL_SHADER_TYPE_FRAGMENT } CoglShaderType; @@ -249,36 +245,10 @@ typedef enum { * Returns: a new shader handle. * Deprecated: 1.16: Use #CoglSnippet api */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -CoglHandle +COGL_DEPRECATED_FOR (cogl_snippet_) +COGL_EXPORT CoglHandle cogl_create_shader (CoglShaderType shader_type); -/** - * cogl_shader_ref: - * @handle: A #CoglHandle to a shader. - * - * Add an extra reference to a shader. - * - * Returns: @handle - * Deprecated: 1.16: Use #CoglSnippet api - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -CoglHandle -cogl_shader_ref (CoglHandle handle); - -/** - * cogl_shader_unref: - * @handle: A #CoglHandle to a shader. - * - * Removes a reference to a shader. If it was the last reference the - * shader object will be destroyed. - * - * Deprecated: 1.16: Use #CoglSnippet api - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -void -cogl_shader_unref (CoglHandle handle); - /** * cogl_is_shader: * @handle: A CoglHandle @@ -289,8 +259,8 @@ cogl_shader_unref (CoglHandle handle); * %FALSE otherwise * Deprecated: 1.16: Use #CoglSnippet api */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -CoglBool +COGL_DEPRECATED_FOR (cogl_snippet_) +COGL_EXPORT gboolean cogl_is_shader (CoglHandle handle); /** @@ -306,42 +276,11 @@ cogl_is_shader (CoglHandle handle); * for a description of the recommended format for the shader code. * Deprecated: 1.16: Use #CoglSnippet api */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -void +COGL_DEPRECATED_FOR (cogl_snippet_) +COGL_EXPORT void cogl_shader_source (CoglHandle shader, const char *source); -/** - * cogl_shader_compile: - * @handle: #CoglHandle for a shader. - * - * Compiles the shader, no return value, but the shader is now ready - * for linking into a program. Note that calling this function is - * optional. If it is not called then the shader will be automatically - * compiled when it is linked. - * Deprecated: 1.16: Use #CoglSnippet api - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -void -cogl_shader_compile (CoglHandle handle); - -/** - * cogl_shader_get_info_log: - * @handle: #CoglHandle for a shader. - * - * Retrieves the information log for a coglobject, can be used in conjunction - * with cogl_shader_get_parameteriv() to retrieve the compiler warnings/error - * messages that caused a shader to not compile correctly, mainly useful for - * debugging purposes. - * - * Return value: a newly allocated string containing the info log. Use - * free() to free it - * Deprecated: 1.16: Use #CoglSnippet api - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -char * -cogl_shader_get_info_log (CoglHandle handle); - /** * cogl_shader_get_type: * @handle: #CoglHandle for a shader. @@ -352,23 +291,10 @@ cogl_shader_get_info_log (CoglHandle handle); * or %COGL_SHADER_TYPE_FRAGMENT if the shader is a frament processor * Deprecated: 1.16: Use #CoglSnippet api */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -CoglShaderType +COGL_DEPRECATED_FOR (cogl_snippet_) +COGL_EXPORT CoglShaderType cogl_shader_get_type (CoglHandle handle); -/** - * cogl_shader_is_compiled: - * @handle: #CoglHandle for a shader. - * - * Retrieves whether a shader #CoglHandle has been compiled - * - * Return value: %TRUE if the shader object has sucessfully be compiled - * Deprecated: 1.16: Use #CoglSnippet api - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -CoglBool -cogl_shader_is_compiled (CoglHandle handle); - /** * cogl_create_program: * @@ -378,37 +304,10 @@ cogl_shader_is_compiled (CoglHandle handle); * Returns: a new cogl program. * Deprecated: 1.16: Use #CoglSnippet api */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -CoglHandle +COGL_DEPRECATED_FOR (cogl_snippet_) +COGL_EXPORT CoglHandle cogl_create_program (void); -/** - * cogl_program_ref: - * @handle: A #CoglHandle to a program. - * - * Add an extra reference to a program. - * - * Deprecated: 1.0: Please use cogl_object_ref() instead. - * - * Returns: @handle - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -CoglHandle -cogl_program_ref (CoglHandle handle); - -/** - * cogl_program_unref: - * @handle: A #CoglHandle to a program. - * - * Removes a reference to a program. If it was the last reference the - * program object will be destroyed. - * - * Deprecated: 1.0: Please use cogl_object_unref() instead. - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -void -cogl_program_unref (CoglHandle handle); - /** * cogl_is_program: * @handle: A CoglHandle @@ -420,8 +319,8 @@ cogl_program_unref (CoglHandle handle); * * Deprecated: 1.16: Use #CoglSnippet api */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -CoglBool +COGL_DEPRECATED_FOR (cogl_snippet_) +COGL_EXPORT gboolean cogl_is_program (CoglHandle handle); /** @@ -436,8 +335,8 @@ cogl_is_program (CoglHandle handle); * * Deprecated: 1.16: Use #CoglSnippet api */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -void +COGL_DEPRECATED_FOR (cogl_snippet_) +COGL_EXPORT void cogl_program_attach_shader (CoglHandle program_handle, CoglHandle shader_handle); @@ -451,29 +350,10 @@ cogl_program_attach_shader (CoglHandle program_handle, * * Deprecated: 1.16: Use #CoglSnippet api */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -void +COGL_DEPRECATED_FOR (cogl_snippet_) +COGL_EXPORT void cogl_program_link (CoglHandle handle); -/** - * cogl_program_use: - * @handle: a #CoglHandle for a shader program or %COGL_INVALID_HANDLE. - * - * Activate a specific shader program replacing that part of the GL - * rendering pipeline, if passed in %COGL_INVALID_HANDLE the default - * behavior of GL is reinstated. - * - * This function affects the global state of the current Cogl - * context. It is much more efficient to attach the shader to a - * specific material used for rendering instead by calling - * cogl_material_set_user_program(). - * - * Deprecated: 1.16: Use #CoglSnippet api - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -void -cogl_program_use (CoglHandle handle); - /** * cogl_program_get_uniform_location: * @handle: a #CoglHandle for a shader program. @@ -484,12 +364,10 @@ cogl_program_use (CoglHandle handle); * shader object and is possible to modify as an external parameter. * * Return value: the offset of a uniform in a specified program. - * This uniform can be set using cogl_program_uniform_1f() when the - * program is in use. * Deprecated: 1.16: Use #CoglSnippet api instead */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -int +COGL_DEPRECATED_FOR (cogl_snippet_) +COGL_EXPORT int cogl_program_get_uniform_location (CoglHandle handle, const char *uniform_name); @@ -506,8 +384,8 @@ cogl_program_get_uniform_location (CoglHandle handle, * Since: 1.4 * Deprecated: 1.16: Use #CoglSnippet api instead */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -void +COGL_DEPRECATED_FOR (cogl_snippet_) +COGL_EXPORT void cogl_program_set_uniform_1f (CoglHandle program, int uniform_location, float value); @@ -525,8 +403,8 @@ cogl_program_set_uniform_1f (CoglHandle program, * Since: 1.4 * Deprecated: 1.16: Use #CoglSnippet api instead */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -void +COGL_DEPRECATED_FOR (cogl_snippet_) +COGL_EXPORT void cogl_program_set_uniform_1i (CoglHandle program, int uniform_location, int value); @@ -548,8 +426,8 @@ cogl_program_set_uniform_1i (CoglHandle program, * Since: 1.4 * Deprecated: 1.16: Use #CoglSnippet api instead */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -void +COGL_DEPRECATED_FOR (cogl_snippet_) +COGL_EXPORT void cogl_program_set_uniform_float (CoglHandle program, int uniform_location, int n_components, @@ -573,8 +451,8 @@ cogl_program_set_uniform_float (CoglHandle program, * Since: 1.4 * Deprecated: 1.16: Use #CoglSnippet api instead */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -void +COGL_DEPRECATED_FOR (cogl_snippet_) +COGL_EXPORT void cogl_program_set_uniform_int (CoglHandle program, int uniform_location, int n_components, @@ -599,105 +477,15 @@ cogl_program_set_uniform_int (CoglHandle program, * Since: 1.4 * Deprecated: 1.16: Use #CoglSnippet api instead */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -void +COGL_DEPRECATED_FOR (cogl_snippet_) +COGL_EXPORT void cogl_program_set_uniform_matrix (CoglHandle program, int uniform_location, int dimensions, int count, - CoglBool transpose, + gboolean transpose, const float *value); -/** - * cogl_program_uniform_1f: - * @uniform_no: the uniform to set. - * @value: the new value of the uniform. - * - * Changes the value of a floating point uniform in the currently - * used (see cogl_program_use()) shader program. - * - * Deprecated: 1.16: Use #CoglSnippet api - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -void -cogl_program_uniform_1f (int uniform_no, - float value); - -/** - * cogl_program_uniform_1i: - * @uniform_no: the uniform to set. - * @value: the new value of the uniform. - * - * Changes the value of an integer uniform in the currently - * used (see cogl_program_use()) shader program. - * - * Deprecated: 1.16: Use #CoglSnippet api - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -void -cogl_program_uniform_1i (int uniform_no, - int value); - -/** - * cogl_program_uniform_float: - * @uniform_no: the uniform to set. - * @size: Size of float vector. - * @count: Size of array of uniforms. - * @value: (array length=count): the new value of the uniform. - * - * Changes the value of a float vector uniform, or uniform array in the - * currently used (see cogl_program_use()) shader program. - * - * Deprecated: 1.16: Use #CoglSnippet api - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -void -cogl_program_uniform_float (int uniform_no, - int size, - int count, - const float *value); - -/** - * cogl_program_uniform_int: - * @uniform_no: the uniform to set. - * @size: Size of int vector. - * @count: Size of array of uniforms. - * @value: (array length=count): the new value of the uniform. - * - * Changes the value of a int vector uniform, or uniform array in the - * currently used (see cogl_program_use()) shader program. - * - * Deprecated: 1.16: Use #CoglSnippet api - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -void -cogl_program_uniform_int (int uniform_no, - int size, - int count, - const int *value); - -/** - * cogl_program_uniform_matrix: - * @uniform_no: the uniform to set. - * @size: Size of matrix. - * @count: Size of array of uniforms. - * @transpose: Whether to transpose the matrix when setting the uniform. - * @value: (array length=count): the new value of the uniform. - * - * Changes the value of a matrix uniform, or uniform array in the - * currently used (see cogl_program_use()) shader program. The @size - * parameter is used to determine the square size of the matrix. - * - * Deprecated: 1.16: Use #CoglSnippet api - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_snippet_) -void -cogl_program_uniform_matrix (int uniform_no, - int size, - int count, - CoglBool transpose, - const float *value); - -COGL_END_DECLS +G_END_DECLS #endif /* __COGL_SHADER_H__ */ diff --git a/cogl/cogl/deprecated/cogl-type-casts.h b/cogl/cogl/deprecated/cogl-type-casts.h index 00bead869..c35ea056b 100644 --- a/cogl/cogl/deprecated/cogl-type-casts.h +++ b/cogl/cogl/deprecated/cogl-type-casts.h @@ -44,7 +44,7 @@ * so these macros are only kept for compatibility... */ -#if !defined(COGL_ENABLE_MUFFIN_API) && !defined(COGL_GIR_SCANNING) +#if !defined(COGL_ENABLE_MUTTER_API) && !defined(COGL_GIR_SCANNING) #define COGL_FRAMEBUFFER(X) (X) #define COGL_BUFFER(X) (X) #define COGL_TEXTURE(X) (X) diff --git a/cogl/cogl/deprecated/cogl-vertex-buffer-private.h b/cogl/cogl/deprecated/cogl-vertex-buffer-private.h deleted file mode 100644 index f803bbba6..000000000 --- a/cogl/cogl/deprecated/cogl-vertex-buffer-private.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#ifndef __COGL_VERTEX_BUFFER_H -#define __COGL_VERTEX_BUFFER_H - -#include "cogl-object-private.h" - -#include "cogl-primitive.h" - -#include - -/* Note we put quite a bit into the flags here to help keep - * the down size of the CoglVertexBufferAttrib struct below. */ -typedef enum _CoglVertexBufferAttribFlags -{ - /* Types */ - /* NB: update the _TYPE_MASK below if these are changed */ - COGL_VERTEX_BUFFER_ATTRIB_FLAG_COLOR_ARRAY = 1<<0, - COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMAL_ARRAY = 1<<1, - COGL_VERTEX_BUFFER_ATTRIB_FLAG_TEXTURE_COORD_ARRAY = 1<<2, - COGL_VERTEX_BUFFER_ATTRIB_FLAG_VERTEX_ARRAY = 1<<3, - COGL_VERTEX_BUFFER_ATTRIB_FLAG_CUSTOM_ARRAY = 1<<4, - COGL_VERTEX_BUFFER_ATTRIB_FLAG_INVALID = 1<<5, - - COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMALIZED = 1<<6, - COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED = 1<<7, - - /* Usage hints */ - /* FIXME - flatten into one flag, since its used as a boolean */ - COGL_VERTEX_BUFFER_ATTRIB_FLAG_INFREQUENT_RESUBMIT = 1<<8, - COGL_VERTEX_BUFFER_ATTRIB_FLAG_FREQUENT_RESUBMIT = 1<<9, - - /* GL Data types */ - /* NB: Update the _GL_TYPE_MASK below if these are changed */ - COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_BYTE = 1<<10, - COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_BYTE = 1<<11, - COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_SHORT = 1<<12, - COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_SHORT = 1<<13, - COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_INT = 1<<14, - COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_UNSIGNED_INT = 1<<15, - COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_FLOAT = 1<<16, - COGL_VERTEX_BUFFER_ATTRIB_FLAG_GL_TYPE_DOUBLE = 1<<17, - - COGL_VERTEX_BUFFER_ATTRIB_FLAG_SUBMITTED = 1<<18, - COGL_VERTEX_BUFFER_ATTRIB_FLAG_UNUSED = 1<<19 - - /* XXX NB: If we need > 24 bits then look at changing the layout - * of struct _CoglVertexBufferAttrib below */ -} CoglVertexBufferAttribFlags; - -#define COGL_VERTEX_BUFFER_ATTRIB_FLAG_TYPE_MASK \ - (COGL_VERTEX_BUFFER_ATTRIB_FLAG_COLOR_ARRAY \ - | COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMAL_ARRAY \ - | COGL_VERTEX_BUFFER_ATTRIB_FLAG_TEXTURE_COORD_ARRAY \ - | COGL_VERTEX_BUFFER_ATTRIB_FLAG_VERTEX_ARRAY \ - | COGL_VERTEX_BUFFER_ATTRIB_FLAG_CUSTOM_ARRAY \ - | COGL_VERTEX_BUFFER_ATTRIB_FLAG_INVALID) - -typedef struct _CoglVertexBufferAttrib -{ - /* TODO: look at breaking up the flags into seperate - * bitfields and seperate enums */ - CoglVertexBufferAttribFlags flags:24; - uint8_t id; - GQuark name; - char *name_without_detail; - union _u - { - const void *pointer; - size_t vbo_offset; - } u; - CoglAttributeType type; - size_t span_bytes; - uint16_t stride; - uint8_t n_components; - uint8_t texture_unit; - - int attribute_first; - CoglAttribute *attribute; - -} CoglVertexBufferAttrib; - -typedef enum _CoglVertexBufferVBOFlags -{ - COGL_VERTEX_BUFFER_VBO_FLAG_STRIDED = 1<<0, - COGL_VERTEX_BUFFER_VBO_FLAG_MULTIPACK = 1<<1, - - /* FIXME - flatten into one flag, since its used as a boolean */ - COGL_VERTEX_BUFFER_VBO_FLAG_INFREQUENT_RESUBMIT = 1<<3, - COGL_VERTEX_BUFFER_VBO_FLAG_FREQUENT_RESUBMIT = 1<<4, - - COGL_VERTEX_BUFFER_VBO_FLAG_SUBMITTED = 1<<5 -} CoglVertexBufferVBOFlags; - -/* - * A CoglVertexBufferVBO represents one or more attributes in a single - * buffer object - */ -typedef struct _CoglVertexBufferVBO -{ - CoglVertexBufferVBOFlags flags; - - CoglAttributeBuffer *attribute_buffer; - size_t buffer_bytes; - - GList *attributes; -} CoglVertexBufferVBO; - -typedef struct _CoglVertexBufferIndices -{ - CoglHandleObject _parent; - - CoglIndices *indices; -} CoglVertexBufferIndices; - -typedef struct _CoglVertexBuffer -{ - CoglHandleObject _parent; - - int n_vertices; /*!< The number of vertices in the buffer */ - GList *submitted_vbos; /* The VBOs currently submitted to the GPU */ - - /* Note: new_attributes is normally NULL and only valid while - * modifying a buffer. */ - GList *new_attributes; /*!< attributes pending submission */ - - CoglBool dirty_attributes; - - CoglPrimitive *primitive; - -} CoglVertexBuffer; - -#endif /* __COGL_VERTEX_BUFFER_H */ - diff --git a/cogl/cogl/deprecated/cogl-vertex-buffer.c b/cogl/cogl/deprecated/cogl-vertex-buffer.c deleted file mode 100644 index affd3101d..000000000 --- a/cogl/cogl/deprecated/cogl-vertex-buffer.c +++ /dev/null @@ -1,1795 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -/* XXX: For an overview of the functionality implemented here, please - * see cogl-vertex-buffer.h, which contains the gtk-doc section overview - * for the Vertex Buffers API. - */ - -/* - * TODO: We need to do a better job of minimizing when we call glVertexPointer - * and pals in enable_state_for_drawing_buffer - * - * We should have an internal 2-tuple cache of (VBO, offset) for each of them - * so we can avoid some GL calls. We could have cogl wrappers for the - * gl*Pointer funcs that look like this: - * - * cogl_vertex_pointer (n_components, gl_type, stride, vbo, offset); - * cogl_color_pointer (n_components, gl_type, stride, vbo, offset); - * - * They would also accept NULL for the VBO handle to support old style vertex - * arrays. - * - * TODO: - * Actually hook this up to the cogl shaders infrastructure. The vertex - * buffer API has been designed to allow adding of arbitrary attributes for use - * with shaders, but this has yet to be actually plumbed together and tested. - * The bits we are missing: - * - cogl_program_use doesn't currently record within ctx-> which program - * is currently in use so a.t.m only Clutter knows the current shader. - * - We don't query the current shader program for the generic vertex indices - * (using glGetAttribLocation) so that we can call glEnableVertexAttribArray - * with those indices. - * (currently we just make up consecutive indices) - * - some dirty flag mechanims to know when the shader program has changed - * so we don't need to re-query it each time we draw a buffer. - * - * TODO - * Expose API that lets developers get back a buffer handle for a particular - * polygon so they may add custom attributes to them. - * - It should be possible to query/modify attributes efficiently, in place, - * avoiding copies. It would not be acceptable to simply require that - * developers must query back the n_vertices of a buffer and then the - * n_components, type and stride etc of each attribute since there - * would be too many combinations to realistically handle. - * - * - In practice, some cases might be best solved with a higher level - * EditableMesh API, (see futher below) but for many cases I think an - * API like this might be appropriate: - * - * cogl_vertex_buffer_foreach_vertex (buffer_handle, - * (AttributesBufferIteratorFunc)callback, - * "gl_Vertex", "gl_Color", NULL); - * static void callback (CoglVertexBufferVertex *vert) - * { - * GLfloat *pos = vert->attrib[0]; - * GLubyte *color = vert->attrib[1]; - * GLfloat *new_attrib = buf[vert->index]; - * - * new_attrib = pos*color; - * } - * - * TODO - * Think about a higher level Mesh API for building/modifying attribute buffers - * - E.g. look at Blender for inspiration here. They can build a mesh from - * "MVert", "MFace" and "MEdge" primitives. - */ - -#ifdef HAVE_CONFIG_H -#include "cogl-config.h" -#endif - -#include -#include -#include - -#include "cogl-util.h" -#include "cogl-context-private.h" -#include "cogl-object-private.h" -#include "cogl-vertex-buffer-private.h" -#include "cogl-texture-private.h" -#include "cogl-pipeline.h" -#include "cogl-pipeline-private.h" -#include "cogl-primitives.h" -#include "cogl-framebuffer-private.h" -#include "cogl-primitive-private.h" -#include "cogl-journal-private.h" -#include "cogl1-context.h" -#include "cogl-vertex-buffer.h" - -#define PAD_FOR_ALIGNMENT(VAR, TYPE_SIZE) \ - (VAR = TYPE_SIZE + ((VAR - 1) & ~(TYPE_SIZE - 1))) - -static void _cogl_vertex_buffer_free (CoglVertexBuffer *buffer); -static void _cogl_vertex_buffer_indices_free (CoglVertexBufferIndices *buffer_indices); -static CoglUserDataKey _cogl_vertex_buffer_pipeline_priv_key; - -COGL_HANDLE_DEFINE (VertexBuffer, vertex_buffer); -COGL_OBJECT_DEFINE_DEPRECATED_REF_COUNTING (vertex_buffer); -COGL_HANDLE_DEFINE (VertexBufferIndices, vertex_buffer_indices); - -CoglHandle -cogl_vertex_buffer_new (unsigned int n_vertices) -{ - CoglVertexBuffer *buffer = g_slice_alloc (sizeof (CoglVertexBuffer)); - - buffer->n_vertices = n_vertices; - - buffer->submitted_vbos = NULL; - buffer->new_attributes = NULL; - buffer->primitive = cogl_primitive_new (COGL_VERTICES_MODE_TRIANGLES, - n_vertices, NULL); - - /* return COGL_INVALID_HANDLE; */ - return _cogl_vertex_buffer_handle_new (buffer); -} - -unsigned int -cogl_vertex_buffer_get_n_vertices (CoglHandle handle) -{ - CoglVertexBuffer *buffer; - - if (!cogl_is_vertex_buffer (handle)) - return 0; - - buffer = handle; - - return buffer->n_vertices; -} - -/* There are a number of standard OpenGL attributes that we deal with - * specially. These attributes are all namespaced with a "gl_" prefix - * so we should catch any typos instead of silently adding a custom - * attribute. - */ -static CoglVertexBufferAttribFlags -validate_gl_attribute (const char *gl_attribute, - uint8_t n_components, - uint8_t *texture_unit) -{ - CoglVertexBufferAttribFlags type; - char *detail_seperator = NULL; - int name_len; - - detail_seperator = strstr (gl_attribute, "::"); - if (detail_seperator) - name_len = detail_seperator - gl_attribute; - else - name_len = strlen (gl_attribute); - - if (strncmp (gl_attribute, "Vertex", name_len) == 0) - { - if (G_UNLIKELY (n_components == 1)) - g_critical ("glVertexPointer doesn't allow 1 component vertex " - "positions so we currently only support \"gl_Vertex\" " - "attributes where n_components == 2, 3 or 4"); - type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_VERTEX_ARRAY; - } - else if (strncmp (gl_attribute, "Color", name_len) == 0) - { - if (G_UNLIKELY (n_components != 3 && n_components != 4)) - g_critical ("glColorPointer expects 3 or 4 component colors so we " - "currently only support \"gl_Color\" attributes where " - "n_components == 3 or 4"); - type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_COLOR_ARRAY; - } - else if (strncmp (gl_attribute, - "MultiTexCoord", - strlen ("MultiTexCoord")) == 0) - { - unsigned int unit; - - if (sscanf (gl_attribute, "MultiTexCoord%u", &unit) != 1) - { - g_warning ("gl_MultiTexCoord attributes should include a\n" - "texture unit number, E.g. gl_MultiTexCoord0\n"); - unit = 0; - } - /* FIXME: validate any '::' delimiter for this case */ - *texture_unit = unit; - type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_TEXTURE_COORD_ARRAY; - } - else if (strncmp (gl_attribute, "Normal", name_len) == 0) - { - if (G_UNLIKELY (n_components != 3)) - g_critical ("glNormalPointer expects 3 component normals so we " - "currently only support \"gl_Normal\" attributes where " - "n_components == 3"); - type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMAL_ARRAY; - } - else - { - g_warning ("Unknown gl_* attribute name gl_%s\n", gl_attribute); - type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_INVALID; - } - - return type; -} - -/* There are a number of standard OpenGL attributes that we deal with - * specially. These attributes are all namespaced with a "gl_" prefix - * so we should catch any typos instead of silently adding a custom - * attribute. - */ -static CoglVertexBufferAttribFlags -validate_cogl_attribute (const char *cogl_attribute, - uint8_t n_components, - uint8_t *texture_unit) -{ - CoglVertexBufferAttribFlags type; - char *detail_seperator = NULL; - int name_len; - - detail_seperator = strstr (cogl_attribute, "::"); - if (detail_seperator) - name_len = detail_seperator - cogl_attribute; - else - name_len = strlen (cogl_attribute); - - if (strncmp (cogl_attribute, "position_in", name_len) == 0) - { - if (G_UNLIKELY (n_components == 1)) - g_critical ("glVertexPointer doesn't allow 1 component vertex " - "positions so we currently only support " - "\"cogl_position_in\" attributes where " - "n_components == 2, 3 or 4"); - type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_VERTEX_ARRAY; - } - else if (strncmp (cogl_attribute, "color_in", name_len) == 0) - { - if (G_UNLIKELY (n_components != 3 && n_components != 4)) - g_critical ("glColorPointer expects 3 or 4 component colors so we " - "currently only support \"cogl_color_in\" attributes " - "where n_components == 3 or 4"); - type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_COLOR_ARRAY; - } - else if (strncmp (cogl_attribute, - "cogl_tex_coord", - strlen ("cogl_tex_coord")) == 0) - { - unsigned int unit; - - if (strcmp (cogl_attribute, "cogl_tex_coord_in") == 0) - unit = 0; - else if (sscanf (cogl_attribute, "cogl_tex_coord%u_in", &unit) != 1) - { - g_warning ("texture coordinate attributes should either be " - "referenced as \"cogl_tex_coord_in\" or with a" - "texture unit number like \"cogl_tex_coord1_in\""); - unit = 0; - } - /* FIXME: validate any '::' delimiter for this case */ - *texture_unit = unit; - type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_TEXTURE_COORD_ARRAY; - } - else if (strncmp (cogl_attribute, "normal_in", name_len) == 0) - { - if (G_UNLIKELY (n_components != 3)) - g_critical ("glNormalPointer expects 3 component normals so we " - "currently only support \"cogl_normal_in\" attributes " - "where n_components == 3"); - type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMAL_ARRAY; - } - else - { - g_warning ("Unknown cogl_* attribute name cogl_%s\n", cogl_attribute); - type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_INVALID; - } - - return type; -} - -/* This validates that a custom attribute name is a valid GLSL variable name - * - * NB: attribute names may have a detail component delimited using '::' E.g. - * custom_attrib::foo or custom_attrib::bar - * - * maybe I should hang a compiled regex somewhere to handle this - */ -static CoglBool -validate_custom_attribute_name (const char *attribute_name) -{ - char *detail_seperator = NULL; - int name_len; - int i; - - detail_seperator = strstr (attribute_name, "::"); - if (detail_seperator) - name_len = detail_seperator - attribute_name; - else - name_len = strlen (attribute_name); - - if (name_len == 0 - || !g_ascii_isalpha (attribute_name[0]) - || attribute_name[0] != '_') - return FALSE; - - for (i = 1; i < name_len; i++) - if (!g_ascii_isalnum (attribute_name[i]) || attribute_name[i] != '_') - return FALSE; - - return TRUE; -} - -/* Iterates the CoglVertexBufferVBOs of a buffer and creates a flat list - * of all the submitted attributes - * - * Note: The CoglVertexBufferAttrib structs are deep copied, except the - * internal CoglAttribute pointer is set to NULL. - */ -static GList * -copy_submitted_attributes_list (CoglVertexBuffer *buffer) -{ - GList *tmp; - GList *submitted_attributes = NULL; - - for (tmp = buffer->submitted_vbos; tmp != NULL; tmp = tmp->next) - { - CoglVertexBufferVBO *cogl_vbo = tmp->data; - GList *tmp2; - - for (tmp2 = cogl_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) - { - CoglVertexBufferAttrib *attribute = tmp2->data; - CoglVertexBufferAttrib *copy = - g_slice_alloc (sizeof (CoglVertexBufferAttrib)); - *copy = *attribute; - copy->name_without_detail = - g_strdup (attribute->name_without_detail); - copy->attribute = NULL; - submitted_attributes = g_list_prepend (submitted_attributes, copy); - } - } - return submitted_attributes; -} - -static size_t -sizeof_attribute_type (CoglAttributeType type) -{ - switch (type) - { - case COGL_ATTRIBUTE_TYPE_BYTE: - return 1; - case COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE: - return 1; - case COGL_ATTRIBUTE_TYPE_SHORT: - return 2; - case COGL_ATTRIBUTE_TYPE_UNSIGNED_SHORT: - return 2; - case COGL_ATTRIBUTE_TYPE_FLOAT: - return 4; - } - g_return_val_if_reached (0); -} - -static size_t -strideof (CoglAttributeType type, int n_components) -{ - return sizeof_attribute_type (type) * n_components; -} - -static char * -canonize_attribute_name (const char *attribute_name) -{ - char *detail_seperator = NULL; - int name_len; - - if (strncmp (attribute_name, "gl_", 3) != 0) - return g_strdup (attribute_name); - - /* skip past the "gl_" */ - attribute_name += 3; - - detail_seperator = strstr (attribute_name, "::"); - if (detail_seperator) - name_len = detail_seperator - attribute_name; - else - { - name_len = strlen (attribute_name); - detail_seperator = ""; - } - - if (strncmp (attribute_name, "Vertex", name_len) == 0) - return g_strconcat ("cogl_position_in", detail_seperator, NULL); - else if (strncmp (attribute_name, "Color", name_len) == 0) - return g_strconcat ("cogl_color_in", detail_seperator, NULL); - else if (strncmp (attribute_name, - "MultiTexCoord", - strlen ("MultiTexCoord")) == 0) - { - unsigned int unit; - - if (sscanf (attribute_name, "MultiTexCoord%u", &unit) != 1) - { - g_warning ("gl_MultiTexCoord attributes should include a\n" - "texture unit number, E.g. gl_MultiTexCoord0\n"); - unit = 0; - } - return g_strdup_printf ("cogl_tex_coord%u_in%s", - unit, detail_seperator); - } - else if (strncmp (attribute_name, "Normal", name_len) == 0) - return g_strconcat ("cogl_normal_in", detail_seperator, NULL); - else - { - g_warning ("Unknown gl_* attribute name gl_%s\n", attribute_name); - return g_strdup (attribute_name); - } -} - -void -cogl_vertex_buffer_add (CoglHandle handle, - const char *attribute_name, - uint8_t n_components, - CoglAttributeType type, - CoglBool normalized, - uint16_t stride, - const void *pointer) -{ - CoglVertexBuffer *buffer; - char *cogl_attribute_name; - GQuark name_quark; - CoglBool modifying_an_attrib = FALSE; - CoglVertexBufferAttrib *attribute; - CoglVertexBufferAttribFlags flags = 0; - uint8_t texture_unit = 0; - GList *tmp; - char *detail; - - if (!cogl_is_vertex_buffer (handle)) - return; - - buffer = handle; - buffer->dirty_attributes = TRUE; - - cogl_attribute_name = canonize_attribute_name (attribute_name); - name_quark = g_quark_from_string (cogl_attribute_name); - - /* The submit function works by diffing between submitted_attributes - * and new_attributes to minimize the upload bandwidth + cost of - * allocating new VBOs, so if there isn't already a list of new_attributes - * we create one: */ - if (!buffer->new_attributes) - buffer->new_attributes = copy_submitted_attributes_list (buffer); - - /* Note: we first look for an existing attribute that we are modifying - * so we may skip needing to validate the name */ - for (tmp = buffer->new_attributes; tmp != NULL; tmp = tmp->next) - { - CoglVertexBufferAttrib *submitted_attribute = tmp->data; - if (submitted_attribute->name == name_quark) - { - modifying_an_attrib = TRUE; - - attribute = submitted_attribute; - - /* since we will skip validate_gl/cogl_attribute in this case, we - * need to pluck out the attribute type before overwriting the - * flags: */ - flags |= - attribute->flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_TYPE_MASK; - break; - } - } - - if (!modifying_an_attrib) - { - /* Validate the attribute name, is suitable as a variable name */ - if (strncmp (attribute_name, "gl_", 3) == 0) - { - /* Note: we pass the original attribute name here so that - * any warning messages correspond to the users original - * attribute name... */ - flags |= validate_gl_attribute (attribute_name + 3, - n_components, - &texture_unit); - if (flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_INVALID) - return; - } - else if (strncmp (attribute_name, "cogl_", 5) == 0) - { - flags |= validate_cogl_attribute (attribute_name + 5, - n_components, - &texture_unit); - if (flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_INVALID) - return; - } - else - { - flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_CUSTOM_ARRAY; - if (validate_custom_attribute_name (attribute_name)) - return; - } - - attribute = g_slice_alloc0 (sizeof (CoglVertexBufferAttrib)); - } - - attribute->name = name_quark; - detail = strstr (cogl_attribute_name, "::"); - if (detail) - attribute->name_without_detail = g_strndup (cogl_attribute_name, - detail - cogl_attribute_name); - else - attribute->name_without_detail = g_strdup (cogl_attribute_name); - attribute->type = type; - attribute->n_components = n_components; - if (stride == 0) - stride = strideof (type, n_components); - attribute->stride = stride; - attribute->u.pointer = pointer; - attribute->texture_unit = texture_unit; - attribute->attribute = NULL; - - flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED; - - /* Note: We currently just assume, if an attribute is *ever* updated - * then it should be taged as frequently changing. */ - if (modifying_an_attrib) - flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_FREQUENT_RESUBMIT; - else - flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_INFREQUENT_RESUBMIT; - - if (normalized) - flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMALIZED; - attribute->flags = flags; - - attribute->span_bytes = buffer->n_vertices * attribute->stride; - - if (!modifying_an_attrib) - buffer->new_attributes = - g_list_prepend (buffer->new_attributes, attribute); - - free (cogl_attribute_name); -} - -static void -_cogl_vertex_buffer_attrib_free (CoglVertexBufferAttrib *attribute) -{ - if (attribute->attribute) - cogl_object_unref (attribute->attribute); - free (attribute->name_without_detail); - g_slice_free (CoglVertexBufferAttrib, attribute); -} - -void -cogl_vertex_buffer_delete (CoglHandle handle, - const char *attribute_name) -{ - CoglVertexBuffer *buffer; - char *cogl_attribute_name = canonize_attribute_name (attribute_name); - GQuark name = g_quark_from_string (cogl_attribute_name); - GList *tmp; - - free (cogl_attribute_name); - - if (!cogl_is_vertex_buffer (handle)) - return; - - buffer = handle; - buffer->dirty_attributes = TRUE; - - /* The submit function works by diffing between submitted_attributes - * and new_attributes to minimize the upload bandwidth + cost of - * allocating new VBOs, so if there isn't already a list of new_attributes - * we create one: */ - if (!buffer->new_attributes) - buffer->new_attributes = copy_submitted_attributes_list (buffer); - - for (tmp = buffer->new_attributes; tmp != NULL; tmp = tmp->next) - { - CoglVertexBufferAttrib *submitted_attribute = tmp->data; - if (submitted_attribute->name == name) - { - buffer->new_attributes = - g_list_delete_link (buffer->new_attributes, tmp); - _cogl_vertex_buffer_attrib_free (submitted_attribute); - return; - } - } - - g_warning ("Failed to find an attribute named %s to delete\n", - attribute_name); -} - -static void -set_attribute_enable (CoglHandle handle, - const char *attribute_name, - CoglBool state) -{ - CoglVertexBuffer *buffer; - char *cogl_attribute_name = canonize_attribute_name (attribute_name); - GQuark name_quark = g_quark_from_string (cogl_attribute_name); - GList *tmp; - - free (cogl_attribute_name); - - if (!cogl_is_vertex_buffer (handle)) - return; - - buffer = handle; - buffer->dirty_attributes = TRUE; - - /* NB: If a buffer is currently being edited, then there can be two seperate - * lists of attributes; those that are currently submitted and a new list yet - * to be submitted, we need to modify both. */ - - for (tmp = buffer->new_attributes; tmp != NULL; tmp = tmp->next) - { - CoglVertexBufferAttrib *attribute = tmp->data; - if (attribute->name == name_quark) - { - if (state) - attribute->flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED; - else - attribute->flags &= ~COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED; - break; - } - } - - for (tmp = buffer->submitted_vbos; tmp != NULL; tmp = tmp->next) - { - CoglVertexBufferVBO *cogl_vbo = tmp->data; - GList *tmp2; - - for (tmp2 = cogl_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) - { - CoglVertexBufferAttrib *attribute = tmp2->data; - if (attribute->name == name_quark) - { - if (state) - attribute->flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED; - else - attribute->flags &= ~COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED; - return; - } - } - } - - g_warning ("Failed to %s attribute named %s/%s\n", - state == TRUE ? "enable" : "disable", - attribute_name, cogl_attribute_name); -} - -void -cogl_vertex_buffer_enable (CoglHandle handle, - const char *attribute_name) -{ - set_attribute_enable (handle, attribute_name, TRUE); -} - -void -cogl_vertex_buffer_disable (CoglHandle handle, - const char *attribute_name) -{ - set_attribute_enable (handle, attribute_name, FALSE); -} - -/* Given an attribute that we know has already been submitted before, this - * function looks for the existing VBO that contains it. - * - * Note: It will free redundant attribute struct once the corresponding - * VBO has been found. - */ -static void -filter_already_submitted_attribute (CoglVertexBufferAttrib *attribute, - GList **reuse_vbos, - GList **submitted_vbos) -{ - GList *tmp; - - /* First check the cogl_vbos we already know are being reused since we - * are more likley to get a match here */ - for (tmp = *reuse_vbos; tmp != NULL; tmp = tmp->next) - { - CoglVertexBufferVBO *cogl_vbo = tmp->data; - GList *tmp2; - - for (tmp2 = cogl_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) - { - CoglVertexBufferAttrib *vbo_attribute = tmp2->data; - - if (vbo_attribute->name == attribute->name) - { - vbo_attribute->flags &= - ~COGL_VERTEX_BUFFER_ATTRIB_FLAG_UNUSED; - /* Note: we don't free the redundant attribute here, since it - * will be freed after all filtering in - * cogl_vertex_buffer_submit */ - return; - } - } - } - - for (tmp = *submitted_vbos; tmp != NULL; tmp = tmp->next) - { - CoglVertexBufferVBO *cogl_vbo = tmp->data; - CoglVertexBufferAttrib *reuse_attribute = NULL; - GList *tmp2; - - for (tmp2 = cogl_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) - { - CoglVertexBufferAttrib *vbo_attribute = tmp2->data; - if (vbo_attribute->name == attribute->name) - { - reuse_attribute = vbo_attribute; - /* Note: we don't free the redundant attribute here, since it - * will be freed after all filtering in - * cogl_vertex_buffer_submit */ - - *submitted_vbos = g_list_remove_link (*submitted_vbos, tmp); - tmp->next = *reuse_vbos; - *reuse_vbos = tmp; - break; - } - } - - if (!reuse_attribute) - continue; - - /* Mark all but the matched attribute as UNUSED, so that when we - * finish filtering all our attributes any attrributes still - * marked as UNUSED can be removed from their cogl_vbo */ - for (tmp2 = cogl_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) - { - CoglVertexBufferAttrib *vbo_attribute = tmp2->data; - if (vbo_attribute != reuse_attribute) - vbo_attribute->flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_UNUSED; - } - - return; - } - - g_critical ("Failed to find the cogl vbo that corresponds to an\n" - "attribute that had apparently already been submitted!"); -} - -/* When we first mark a CoglVertexBufferVBO to be reused, we mark the - * attributes as unsed, so that when filtering of attributes into VBOs is done - * we can then prune the now unsed attributes. */ -static void -remove_unused_attributes (CoglVertexBufferVBO *cogl_vbo) -{ - GList *tmp; - GList *next; - - for (tmp = cogl_vbo->attributes; tmp != NULL; tmp = next) - { - CoglVertexBufferAttrib *attribute = tmp->data; - next = tmp->next; - - if (attribute->flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_UNUSED) - { - cogl_vbo->attributes = - g_list_delete_link (cogl_vbo->attributes, tmp); - g_slice_free (CoglVertexBufferAttrib, attribute); - } - } -} - -/* Give a newly added, strided, attribute, this function looks for a - * CoglVertexBufferVBO that the attribute is interleved with. If it can't - * find one then a new CoglVertexBufferVBO is allocated and added to the - * list of new_strided_vbos. - */ -static void -filter_strided_attribute (CoglVertexBufferAttrib *attribute, - GList **new_vbos) -{ - GList *tmp; - CoglVertexBufferVBO *new_cogl_vbo; - - for (tmp = *new_vbos; tmp != NULL; tmp = tmp->next) - { - CoglVertexBufferVBO *cogl_vbo = tmp->data; - GList *tmp2; - - if (!(cogl_vbo->flags & COGL_VERTEX_BUFFER_VBO_FLAG_STRIDED)) - continue; - - for (tmp2 = cogl_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) - { - CoglVertexBufferAttrib *vbo_attribute = tmp2->data; - const char *attribute_start = attribute->u.pointer; - const char *vbo_attribute_start = vbo_attribute->u.pointer; - - /* NB: All attributes have buffer->n_vertices values which - * simplifies determining which attributes are interleved - * since we assume they will start no farther than +- a - * stride away from each other: - */ - if (attribute_start <= (vbo_attribute_start - vbo_attribute->stride) - || attribute_start - >= (vbo_attribute_start + vbo_attribute->stride)) - continue; /* Not interleved */ - - cogl_vbo->attributes = - g_list_prepend (cogl_vbo->attributes, attribute); - - if (attribute->flags & - COGL_VERTEX_BUFFER_ATTRIB_FLAG_FREQUENT_RESUBMIT) - { - cogl_vbo->flags &= - ~COGL_VERTEX_BUFFER_VBO_FLAG_INFREQUENT_RESUBMIT; - cogl_vbo->flags |= - COGL_VERTEX_BUFFER_VBO_FLAG_FREQUENT_RESUBMIT; - } - return; - } - } - new_cogl_vbo = g_slice_alloc (sizeof (CoglVertexBufferVBO)); - new_cogl_vbo->attributes = NULL; - new_cogl_vbo->attributes = - g_list_prepend (new_cogl_vbo->attributes, attribute); - /* Any one of the interleved attributes will have the same span_bytes */ - new_cogl_vbo->attribute_buffer = NULL; - new_cogl_vbo->buffer_bytes = attribute->span_bytes; - new_cogl_vbo->flags = COGL_VERTEX_BUFFER_VBO_FLAG_STRIDED; - - if (attribute->flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_INFREQUENT_RESUBMIT) - new_cogl_vbo->flags |= COGL_VERTEX_BUFFER_VBO_FLAG_INFREQUENT_RESUBMIT; - else - new_cogl_vbo->flags |= COGL_VERTEX_BUFFER_VBO_FLAG_FREQUENT_RESUBMIT; - - *new_vbos = g_list_prepend (*new_vbos, new_cogl_vbo); - return; -} - -/* This iterates through the list of submitted VBOs looking for one that - * contains attribute. If found the list *link* is removed and returned */ -static GList * -unlink_submitted_vbo_containing_attribute (GList **submitted_vbos, - CoglVertexBufferAttrib *attribute) -{ - GList *tmp; - GList *next = NULL; - - for (tmp = *submitted_vbos; tmp != NULL; tmp = next) - { - CoglVertexBufferVBO *submitted_vbo = tmp->data; - GList *tmp2; - - next = tmp->next; - - for (tmp2 = submitted_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) - { - CoglVertexBufferAttrib *submitted_attribute = tmp2->data; - - if (submitted_attribute->name == attribute->name) - { - *submitted_vbos = g_list_remove_link (*submitted_vbos, tmp); - return tmp; - } - } - } - - return NULL; -} - -/* Unlinks all the submitted VBOs that conflict with the new cogl_vbo and - * returns them as a list. */ -static GList * -get_submitted_vbo_conflicts (GList **submitted_vbos, - CoglVertexBufferVBO *cogl_vbo) -{ - GList *tmp; - GList *conflicts = NULL; - - for (tmp = cogl_vbo->attributes; tmp != NULL; tmp = tmp->next) - { - GList *link = - unlink_submitted_vbo_containing_attribute (submitted_vbos, - tmp->data); - if (link) - { - /* prepend the link to the list of conflicts: */ - link->next = conflicts; - conflicts = link; - } - } - return conflicts; -} - -/* Any attributes in cogl_vbo gets removed from conflict_vbo */ -static void -disassociate_conflicting_attributes (CoglVertexBufferVBO *conflict_vbo, - CoglVertexBufferVBO *cogl_vbo) -{ - GList *tmp; - - /* NB: The attributes list in conflict_vbo will be shrinking so - * we iterate those in the inner loop. */ - - for (tmp = cogl_vbo->attributes; tmp != NULL; tmp = tmp->next) - { - CoglVertexBufferAttrib *attribute = tmp->data; - GList *tmp2; - for (tmp2 = conflict_vbo->attributes; tmp2 != NULL; tmp2 = tmp2->next) - { - CoglVertexBufferAttrib *conflict_attribute = tmp2->data; - - if (conflict_attribute->name == attribute->name) - { - _cogl_vertex_buffer_attrib_free (conflict_attribute); - conflict_vbo->attributes = - g_list_delete_link (conflict_vbo->attributes, tmp2); - break; - } - } - } -} - -static void -cogl_vertex_buffer_vbo_free (CoglVertexBufferVBO *cogl_vbo) -{ - GList *tmp; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - for (tmp = cogl_vbo->attributes; tmp != NULL; tmp = tmp->next) - _cogl_vertex_buffer_attrib_free (tmp->data); - g_list_free (cogl_vbo->attributes); - - if (cogl_vbo->flags & COGL_VERTEX_BUFFER_VBO_FLAG_SUBMITTED) - cogl_object_unref (cogl_vbo->attribute_buffer); - - g_slice_free (CoglVertexBufferVBO, cogl_vbo); -} - -/* This figures out the lowest attribute client pointer. (This pointer is used - * to upload all the interleved attributes). - * - * In the process it also replaces the client pointer with the attributes - * offset, and marks the attribute as submitted. - */ -static const void * -prep_strided_vbo_for_upload (CoglVertexBufferVBO *cogl_vbo) -{ - GList *tmp; - const char *lowest_pointer = NULL; - - for (tmp = cogl_vbo->attributes; tmp != NULL; tmp = tmp->next) - { - CoglVertexBufferAttrib *attribute = tmp->data; - const char *client_pointer = attribute->u.pointer; - - if (!lowest_pointer || client_pointer < lowest_pointer) - lowest_pointer = client_pointer; - } - - for (tmp = cogl_vbo->attributes; tmp != NULL; tmp = tmp->next) - { - CoglVertexBufferAttrib *attribute = tmp->data; - const char *client_pointer = attribute->u.pointer; - attribute->u.vbo_offset = client_pointer - lowest_pointer; - attribute->flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_SUBMITTED; - } - - return lowest_pointer; -} - -static CoglBool -upload_multipack_vbo_via_map_buffer (CoglVertexBufferVBO *cogl_vbo) -{ - GList *tmp; - unsigned int offset = 0; - uint8_t *buf; - - _COGL_GET_CONTEXT (ctx, FALSE); - - buf = cogl_buffer_map (COGL_BUFFER (cogl_vbo->attribute_buffer), - COGL_BUFFER_ACCESS_WRITE, - COGL_BUFFER_MAP_HINT_DISCARD); - if (!buf) - return FALSE; - - for (tmp = cogl_vbo->attributes; tmp != NULL; tmp = tmp->next) - { - CoglVertexBufferAttrib *attribute = tmp->data; - gsize attribute_size = attribute->span_bytes; - gsize type_size = sizeof_attribute_type (attribute->type); - - PAD_FOR_ALIGNMENT (offset, type_size); - - memcpy (buf + offset, attribute->u.pointer, attribute_size); - - attribute->u.vbo_offset = offset; - attribute->flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_SUBMITTED; - offset += attribute_size; - } - - cogl_buffer_unmap (COGL_BUFFER (cogl_vbo->attribute_buffer)); - - return TRUE; -} - -static void -upload_multipack_vbo_via_buffer_sub_data (CoglVertexBufferVBO *cogl_vbo) -{ - GList *l; - unsigned int offset = 0; - - for (l = cogl_vbo->attributes; l != NULL; l = l->next) - { - CoglVertexBufferAttrib *attribute = l->data; - gsize attribute_size = attribute->span_bytes; - gsize type_size = sizeof_attribute_type (attribute->type); - - PAD_FOR_ALIGNMENT (offset, type_size); - - cogl_buffer_set_data (COGL_BUFFER (cogl_vbo->attribute_buffer), - offset, - attribute->u.pointer, - attribute_size); - - attribute->u.vbo_offset = offset; - attribute->flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_SUBMITTED; - offset += attribute_size; - } -} - -static void -upload_attributes (CoglVertexBufferVBO *cogl_vbo) -{ - CoglBufferUpdateHint usage; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (cogl_vbo->flags & COGL_VERTEX_BUFFER_VBO_FLAG_FREQUENT_RESUBMIT) - usage = COGL_BUFFER_UPDATE_HINT_DYNAMIC; - else - usage = COGL_BUFFER_UPDATE_HINT_STATIC; - cogl_buffer_set_update_hint (COGL_BUFFER (cogl_vbo->attribute_buffer), usage); - - if (cogl_vbo->flags & COGL_VERTEX_BUFFER_VBO_FLAG_STRIDED) - { - const void *pointer = prep_strided_vbo_for_upload (cogl_vbo); - cogl_buffer_set_data (COGL_BUFFER (cogl_vbo->attribute_buffer), - 0, /* offset */ - pointer, - cogl_vbo->buffer_bytes); - } - else /* MULTIPACK */ - { - /* I think it might depend on the specific driver/HW whether its better - * to use glMapBuffer here or glBufferSubData here. There is even a good - * thread about this topic here: - * http://www.mail-archive.com/dri-devel@lists.sourceforge.net/msg35004.html - * For now I have gone with glMapBuffer, but the jury is still out. - */ - - if (!upload_multipack_vbo_via_map_buffer (cogl_vbo)) - upload_multipack_vbo_via_buffer_sub_data (cogl_vbo); - } - - cogl_vbo->flags |= COGL_VERTEX_BUFFER_VBO_FLAG_SUBMITTED; -} - -/* Note: although there ends up being quite a few inner loops involved with - * resolving buffers, the number of attributes will be low so I don't expect - * them to cause a problem. */ -static void -cogl_vertex_buffer_vbo_resolve (CoglVertexBuffer *buffer, - CoglVertexBufferVBO *new_cogl_vbo, - GList **final_vbos) -{ - GList *conflicts; - GList *tmp; - GList *next; - CoglBool found_target_vbo = FALSE; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - conflicts = - get_submitted_vbo_conflicts (&buffer->submitted_vbos, new_cogl_vbo); - - for (tmp = conflicts; tmp != NULL; tmp = next) - { - CoglVertexBufferVBO *conflict_vbo = tmp->data; - - next = tmp->next; - - disassociate_conflicting_attributes (conflict_vbo, new_cogl_vbo); - - if (!conflict_vbo->attributes) - { - /* See if we can re-use this now empty VBO: */ - - if (!found_target_vbo - && conflict_vbo->buffer_bytes == new_cogl_vbo->buffer_bytes) - { - found_target_vbo = TRUE; - new_cogl_vbo->attribute_buffer = - cogl_object_ref (conflict_vbo->attribute_buffer); - cogl_vertex_buffer_vbo_free (conflict_vbo); - - upload_attributes (new_cogl_vbo); - - *final_vbos = g_list_prepend (*final_vbos, new_cogl_vbo); - } - else - cogl_vertex_buffer_vbo_free (conflict_vbo); - } - else - { - /* Relink the VBO back into buffer->submitted_vbos since it may - * be involved in other conflicts later */ - tmp->next = buffer->submitted_vbos; - tmp->prev = NULL; - buffer->submitted_vbos = tmp; - } - } - - if (!found_target_vbo) - { - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - new_cogl_vbo->attribute_buffer = - cogl_attribute_buffer_new (ctx, new_cogl_vbo->buffer_bytes, NULL); - - upload_attributes (new_cogl_vbo); - *final_vbos = g_list_prepend (*final_vbos, new_cogl_vbo); - } -} - -static void -update_primitive_attributes (CoglVertexBuffer *buffer) -{ - GList *l; - int n_attributes = 0; - CoglAttribute **attributes; - int i; - - if (!buffer->dirty_attributes) - return; - - buffer->dirty_attributes = FALSE; - - for (l = buffer->submitted_vbos; l; l = l->next) - { - CoglVertexBufferVBO *cogl_vbo = l->data; - GList *l2; - - for (l2 = cogl_vbo->attributes; l2; l2 = l2->next, n_attributes++) - ; - } - - _COGL_RETURN_IF_FAIL (n_attributes > 0); - - attributes = g_alloca (sizeof (CoglAttribute *) * n_attributes); - - i = 0; - for (l = buffer->submitted_vbos; l; l = l->next) - { - CoglVertexBufferVBO *cogl_vbo = l->data; - GList *l2; - - for (l2 = cogl_vbo->attributes; l2; l2 = l2->next) - { - CoglVertexBufferAttrib *attribute = l2->data; - if (G_LIKELY (attribute->flags & - COGL_VERTEX_BUFFER_ATTRIB_FLAG_ENABLED)) - { - if (G_UNLIKELY (!attribute->attribute)) - { - attribute->attribute = - cogl_attribute_new (cogl_vbo->attribute_buffer, - attribute->name_without_detail, - attribute->stride, - attribute->u.vbo_offset, - attribute->n_components, - attribute->type); - } - - attributes[i++] = attribute->attribute; - } - } - } - - cogl_primitive_set_attributes (buffer->primitive, attributes, i); -} - -static void -cogl_vertex_buffer_submit_real (CoglVertexBuffer *buffer) -{ - GList *tmp; - CoglVertexBufferVBO *new_multipack_vbo; - GList *new_multipack_vbo_link; - GList *new_vbos = NULL; - GList *reuse_vbos = NULL; - GList *final_vbos = NULL; - - if (!buffer->new_attributes) - goto done; - - /* The objective now is to copy the attribute data supplied by the client - * into buffer objects, but it's important to minimize the number of - * redundant data uploads. - * - * We obviously aim to group together the attributes that are interleved so - * that they can be delivered in one go to the driver. - * All BOs for interleved data are created as STATIC_DRAW_ARB. - * - * Non interleved attributes tagged as INFREQUENT_RESUBMIT will be grouped - * together back to back in a single BO created as STATIC_DRAW_ARB - * - * Non interleved attributes tagged as FREQUENT_RESUBMIT will be copied into - * individual buffer objects, and the BO itself created DYNAMIC_DRAW_ARB - * - * If we are modifying a previously submitted CoglVertexBuffer then we are - * carefull not to needlesly delete OpenGL buffer objects and replace with - * new ones, instead we upload new data to the existing buffers. - */ - - /* NB: We must forget attribute->pointer after submitting since the user - * is free to re-use that memory for other purposes now. */ - - /* Pseudo code: - * - * Broadly speaking we start with a list of unsorted attributes, and filter - * those into 'new' and 're-use' CoglVertexBufferVBO (CBO) lists. We then - * take the list of new CBO structs and compare with the CBOs that have - * already been submitted to the GPU (but ignoring those we already know will - * be re-used) to determine what other CBOs can be re-used, due to being - * superseded, and what new GL VBOs need to be created. - * - * We have two kinds of CBOs: - * - Multi Pack CBOs - * These contain multiple attributes tightly packed back to back) - * - Strided CBOs - * These typically contain multiple interleved sets of attributes, - * though they can contain just one attribute with a stride - * - * First create a new-CBOs entry "new-multipack-CBO" - * Tag "new-multipack-CBO" as MULTIPACK + INFREQUENT_RESUBMIT - * For each unsorted attrib: - * if already marked as submitted: - * iterate reuse-CBOs: - * if we find one that contains this attribute: - * free redundant unsorted attrib struct - * remove the UNUSED flag from the attrib found in the reuse-CBO - * continue to next unsorted attrib - * iterate submitted VBOs: - * if we find one that contains this attribute: - * free redundant unsorted attrib struct - * unlink the vbo and move it to the list of reuse-CBOs - * mark all attributes except the one just matched as UNUSED - * assert (found) - * continue to next unsorted attrib - * if strided: - * iterate the new, strided, CBOs, to see if the attribute is - * interleved with one of them, if found: - * add to the matched CBO - * else if not found: - * create a new-CBOs entry tagged STRIDED + INFREQUENT_RESUBMIT - * else if unstrided && tagged with FREQUENT_RESUBMIT: - * create a new-CBOs entry tagged MULTIPACK + FREQUENT_RESUBMIT - * else - * add to the new-multipack-CBO - * free list of unsorted-attribs - * - * Next compare the new list of CBOs with the submitted set and try to - * minimize the memory bandwidth required to upload the attributes and the - * overhead of creating new GL-BOs. - * - * We deal with four sets of CBOs: - * - The "new" CBOs - * (as determined above during filtering) - * - The "re-use" CBOs - * (as determined above during filtering) - * - The "submitted" CBOs - * (I.e. ones currently submitted to the GPU) - * - The "final" CBOs - * (The result of resolving the differences between the above sets) - * - * The re-use CBOs are dealt with first, and we simply delete any remaining - * attributes in these that are still marked as UNUSED, and move them - * to the list of final CBOs. - * - * Next we iterate through the "new" CBOs, searching for conflicts - * with the "submitted" CBOs and commit our decision to the "final" CBOs - * - * When searching for submitted entries we always unlink items from the - * submitted list once we make matches (before we make descisions - * based on the matches). If the CBO node is superseded it is freed, - * if it is modified but may be needed for more descisions later it is - * relinked back into the submitted list and if it's identical to a new - * CBO it will be linked into the final list. - * - * At the end the list of submitted CBOs represents the attributes that were - * deleted from the buffer. - * - * Iterate re-use-CBOs: - * Iterate attribs for each: - * if attrib UNUSED: - * remove the attrib from the CBO + free - * |Note: we could potentially mark this as a re-useable gap - * |if needs be later. - * add re-use CBO to the final-CBOs - * Iterate new-CBOs: - * List submitted CBOs conflicting with the this CBO (Unlinked items) - * found-target-BO=FALSE - * Iterate conflicting CBOs: - * Disassociate conflicting attribs from conflicting CBO struct - * If no attribs remain: - * If found-target-BO!=TRUE - * _AND_ If the total size of the conflicting CBO is compatible: - * |Note: We don't currently consider re-using oversized buffers - * found-target-BO=TRUE - * upload replacement data - * free submitted CBO struct - * add new CBO struct to final-CBOs - * else: - * delete conflict GL-BO - * delete conflict CBO struct - * else: - * relink CBO back into submitted-CBOs - * - * if found-target-BO == FALSE: - * create a new GL-BO - * upload data - * add new CBO struct to final-BOs - * - * Iterate through the remaining "submitted" CBOs: - * delete the submitted GL-BO - * free the submitted CBO struct - */ - - new_multipack_vbo = g_slice_alloc (sizeof (CoglVertexBufferVBO)); - new_multipack_vbo->attribute_buffer = NULL; - new_multipack_vbo->buffer_bytes = 0; - new_multipack_vbo->flags = - COGL_VERTEX_BUFFER_VBO_FLAG_MULTIPACK - | COGL_VERTEX_BUFFER_VBO_FLAG_INFREQUENT_RESUBMIT; - new_multipack_vbo->attributes = NULL; - new_vbos = g_list_prepend (new_vbos, new_multipack_vbo); - /* We save the link pointer here, just so we can do a fast removal later if - * no attributes get added to this vbo. */ - new_multipack_vbo_link = new_vbos; - - /* Start with a list of unsorted attributes, and filter those into - * potential new Cogl BO structs - */ - for (tmp = buffer->new_attributes; tmp != NULL; tmp = tmp->next) - { - CoglVertexBufferAttrib *attribute = tmp->data; - - if (attribute->flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_SUBMITTED) - { - /* If the attribute is already marked as submitted, then we need - * to find the existing VBO that contains it so we dont delete it. - * - * NB: this also frees the attribute struct since it's implicitly - * redundant in this case. - */ - filter_already_submitted_attribute (attribute, - &reuse_vbos, - &buffer->submitted_vbos); - } - else if (attribute->stride) - { - /* look for a CoglVertexBufferVBO that the attribute is - * interleved with. If one can't be found then a new - * CoglVertexBufferVBO is allocated and added to the list of - * new_vbos: */ - filter_strided_attribute (attribute, &new_vbos); - } - else if (attribute->flags & - COGL_VERTEX_BUFFER_ATTRIB_FLAG_FREQUENT_RESUBMIT) - { - CoglVertexBufferVBO *cogl_vbo = - g_slice_alloc (sizeof (CoglVertexBufferVBO)); - - /* attributes we expect will be frequently resubmitted are placed - * in their own VBO so that updates don't impact other attributes - */ - - cogl_vbo->flags = - COGL_VERTEX_BUFFER_VBO_FLAG_MULTIPACK - | COGL_VERTEX_BUFFER_VBO_FLAG_FREQUENT_RESUBMIT; - cogl_vbo->attributes = NULL; - cogl_vbo->attributes = g_list_prepend (cogl_vbo->attributes, - attribute); - cogl_vbo->attribute_buffer = NULL; - cogl_vbo->buffer_bytes = attribute->span_bytes; - new_vbos = g_list_prepend (new_vbos, cogl_vbo); - } - else - { - gsize type_size = sizeof_attribute_type (attribute->flags); - - /* Infrequently updated attributes just get packed back to back - * in a single VBO: */ - new_multipack_vbo->attributes = - g_list_prepend (new_multipack_vbo->attributes, - attribute); - - /* Note: we have to ensure that each run of attributes is - * naturally aligned according to its data type, which may - * require some padding bytes: */ - - /* XXX: We also have to be sure that the attributes aren't - * reorderd before being uploaded because the alignment padding - * is based on the adjacent attribute. - */ - - PAD_FOR_ALIGNMENT (new_multipack_vbo->buffer_bytes, type_size); - - new_multipack_vbo->buffer_bytes += attribute->span_bytes; - } - } - - /* At this point all buffer->new_attributes have been filtered into - * CoglVertexBufferVBOs... */ - g_list_free (buffer->new_attributes); - buffer->new_attributes = NULL; - - /* If the multipack vbo wasn't needed: */ - if (new_multipack_vbo->attributes == NULL) - { - new_vbos = g_list_delete_link (new_vbos, new_multipack_vbo_link); - g_slice_free (CoglVertexBufferVBO, new_multipack_vbo); - } - - for (tmp = reuse_vbos; tmp != NULL; tmp = tmp->next) - remove_unused_attributes (tmp->data); - final_vbos = g_list_concat (final_vbos, reuse_vbos); - - for (tmp = new_vbos; tmp != NULL; tmp = tmp->next) - cogl_vertex_buffer_vbo_resolve (buffer, tmp->data, &final_vbos); - - /* Anything left corresponds to deleted attributes: */ - for (tmp = buffer->submitted_vbos; tmp != NULL; tmp = tmp->next) - cogl_vertex_buffer_vbo_free (tmp->data); - g_list_free (buffer->submitted_vbos); - g_list_free (new_vbos); - - buffer->submitted_vbos = final_vbos; - -done: - update_primitive_attributes (buffer); -} - -void -cogl_vertex_buffer_submit (CoglHandle handle) -{ - CoglVertexBuffer *buffer; - - if (!cogl_is_vertex_buffer (handle)) - return; - - buffer = handle; - - cogl_vertex_buffer_submit_real (buffer); -} - -typedef struct -{ - /* We have a ref-count on this private structure because we need to - refer to it both from the private data on a pipeline and any weak - pipelines that we create from it. If we didn't have the ref count - then we would depend on the order of destruction of a - CoglPipeline and the weak materials to avoid a crash */ - unsigned int ref_count; - - CoglPipeline *real_source; -} VertexBufferMaterialPrivate; - -static void -unref_pipeline_priv (VertexBufferMaterialPrivate *priv) -{ - if (--priv->ref_count < 1) - g_slice_free (VertexBufferMaterialPrivate, priv); -} - -static void -weak_override_source_destroyed_cb (CoglPipeline *pipeline, - void *user_data) -{ - VertexBufferMaterialPrivate *pipeline_priv = user_data; - /* Unref the weak pipeline copy since it is no longer valid - probably because - * one of its ancestors has been changed. */ - cogl_object_unref (pipeline_priv->real_source); - pipeline_priv->real_source = NULL; - /* A reference was added when we copied the weak material so we need - to unref it here */ - unref_pipeline_priv (pipeline_priv); -} - -static CoglBool -validate_layer_cb (CoglPipeline *pipeline, - int layer_index, - void *user_data) -{ - VertexBufferMaterialPrivate *pipeline_priv = user_data; - CoglPipeline *source = pipeline_priv->real_source; - - if (!cogl_pipeline_get_layer_point_sprite_coords_enabled (source, - layer_index)) - { - CoglPipelineWrapMode wrap_s; - CoglPipelineWrapMode wrap_t; - CoglPipelineWrapMode wrap_p; - CoglBool need_override_source = FALSE; - - /* By default COGL_PIPELINE_WRAP_MODE_AUTOMATIC becomes - * GL_CLAMP_TO_EDGE but we want GL_REPEAT to maintain - * compatibility with older versions of Cogl so we'll override - * it. We don't want to do this for point sprites because in - * that case the whole texture is drawn so you would usually - * want clamp-to-edge. - */ - wrap_s = cogl_pipeline_get_layer_wrap_mode_s (source, layer_index); - if (wrap_s == COGL_PIPELINE_WRAP_MODE_AUTOMATIC) - { - need_override_source = TRUE; - wrap_s = COGL_PIPELINE_WRAP_MODE_REPEAT; - } - wrap_t = cogl_pipeline_get_layer_wrap_mode_t (source, layer_index); - if (wrap_t == COGL_PIPELINE_WRAP_MODE_AUTOMATIC) - { - need_override_source = TRUE; - wrap_t = COGL_PIPELINE_WRAP_MODE_REPEAT; - } - wrap_p = cogl_pipeline_get_layer_wrap_mode_p (source, layer_index); - if (wrap_p == COGL_PIPELINE_WRAP_MODE_AUTOMATIC) - { - need_override_source = TRUE; - wrap_p = COGL_PIPELINE_WRAP_MODE_REPEAT; - } - - if (need_override_source) - { - if (pipeline_priv->real_source == pipeline) - { - pipeline_priv->ref_count++; - pipeline_priv->real_source = source = - _cogl_pipeline_weak_copy (pipeline, - weak_override_source_destroyed_cb, - pipeline_priv); - } - - cogl_pipeline_set_layer_wrap_mode_s (source, layer_index, wrap_s); - cogl_pipeline_set_layer_wrap_mode_t (source, layer_index, wrap_t); - cogl_pipeline_set_layer_wrap_mode_p (source, layer_index, wrap_p); - } - } - - return TRUE; -} - -static void -destroy_pipeline_priv_cb (void *user_data) -{ - unref_pipeline_priv (user_data); -} - -static void -update_primitive_and_draw (CoglVertexBuffer *buffer, - CoglVerticesMode mode, - int first, - int count, - CoglVertexBufferIndices *buffer_indices) -{ - VertexBufferMaterialPrivate *pipeline_priv; - CoglPipeline *users_source; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - cogl_primitive_set_mode (buffer->primitive, mode); - cogl_primitive_set_first_vertex (buffer->primitive, first); - cogl_primitive_set_n_vertices (buffer->primitive, count); - - if (buffer_indices) - cogl_primitive_set_indices (buffer->primitive, buffer_indices->indices, count); - else - cogl_primitive_set_indices (buffer->primitive, NULL, count); - - cogl_vertex_buffer_submit_real (buffer); - - users_source = cogl_get_source (); - pipeline_priv = - cogl_object_get_user_data (COGL_OBJECT (users_source), - &_cogl_vertex_buffer_pipeline_priv_key); - if (G_UNLIKELY (!pipeline_priv)) - { - pipeline_priv = g_slice_new0 (VertexBufferMaterialPrivate); - pipeline_priv->ref_count = 1; - cogl_object_set_user_data (COGL_OBJECT (users_source), - &_cogl_vertex_buffer_pipeline_priv_key, - pipeline_priv, - destroy_pipeline_priv_cb); - } - - if (G_UNLIKELY (!pipeline_priv->real_source)) - { - pipeline_priv->real_source = users_source; - cogl_pipeline_foreach_layer (pipeline_priv->real_source, - validate_layer_cb, - pipeline_priv); - } - - /* XXX: although this may seem redundant, we need to do this since - * CoglVertexBuffers can be used with legacy state and its the source stack - * which track whether legacy state is enabled. - * - * (We only have a CoglDrawFlag to disable legacy state not one - * to enable it) */ - cogl_push_source (pipeline_priv->real_source); - - _cogl_primitive_draw (buffer->primitive, - cogl_get_draw_framebuffer (), - pipeline_priv->real_source, - 0 /* no draw flags */); - - cogl_pop_source (); -} - -void -cogl_vertex_buffer_draw (CoglHandle handle, - CoglVerticesMode mode, - int first, - int count) -{ - CoglVertexBuffer *buffer; - - if (!cogl_is_vertex_buffer (handle)) - return; - - buffer = handle; - - update_primitive_and_draw (buffer, mode, first, count, NULL); -} - -static CoglHandle -_cogl_vertex_buffer_indices_new_real (CoglIndices *indices) -{ - CoglVertexBufferIndices *buffer_indices = - g_slice_alloc (sizeof (CoglVertexBufferIndices)); - buffer_indices->indices = indices; - - return _cogl_vertex_buffer_indices_handle_new (buffer_indices); -} - -CoglHandle -cogl_vertex_buffer_indices_new (CoglIndicesType indices_type, - const void *indices_array, - int indices_len) -{ - CoglIndices *indices; - - _COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE); - - indices = cogl_indices_new (ctx, indices_type, indices_array, indices_len); - return _cogl_vertex_buffer_indices_new_real (indices); -} - -CoglIndicesType -cogl_vertex_buffer_indices_get_type (CoglHandle indices_handle) -{ - CoglVertexBufferIndices *buffer_indices = NULL; - - if (!cogl_is_vertex_buffer_indices (indices_handle)) - return COGL_INDICES_TYPE_UNSIGNED_SHORT; - - buffer_indices = indices_handle; - - return cogl_indices_get_type (buffer_indices->indices); -} - -void -_cogl_vertex_buffer_indices_free (CoglVertexBufferIndices *buffer_indices) -{ - cogl_object_unref (buffer_indices->indices); - g_slice_free (CoglVertexBufferIndices, buffer_indices); -} - -void -cogl_vertex_buffer_draw_elements (CoglHandle handle, - CoglVerticesMode mode, - CoglHandle indices_handle, - int min_index, - int max_index, - int indices_offset, - int count) -{ - CoglVertexBuffer *buffer; - CoglVertexBufferIndices *buffer_indices; - - if (!cogl_is_vertex_buffer (handle)) - return; - - buffer = handle; - - if (!cogl_is_vertex_buffer_indices (indices_handle)) - return; - - buffer_indices = indices_handle; - - update_primitive_and_draw (buffer, mode, indices_offset, count, - buffer_indices); -} - -static void -_cogl_vertex_buffer_free (CoglVertexBuffer *buffer) -{ - GList *tmp; - - for (tmp = buffer->submitted_vbos; tmp != NULL; tmp = tmp->next) - cogl_vertex_buffer_vbo_free (tmp->data); - g_list_free (buffer->submitted_vbos); - - for (tmp = buffer->new_attributes; tmp != NULL; tmp = tmp->next) - _cogl_vertex_buffer_attrib_free (tmp->data); - g_list_free (buffer->new_attributes); - - if (buffer->primitive) - cogl_object_unref (buffer->primitive); - - g_slice_free (CoglVertexBuffer, buffer); -} - -CoglHandle -cogl_vertex_buffer_indices_get_for_quads (unsigned int n_indices) -{ - _COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE); - - if (n_indices <= 256 / 4 * 6) - { - if (ctx->quad_buffer_indices_byte == COGL_INVALID_HANDLE) - { - /* NB: cogl_get_quad_indices takes n_quads not n_indices... */ - CoglIndices *indices = cogl_get_rectangle_indices (ctx, 256 / 4); - cogl_object_ref (indices); - ctx->quad_buffer_indices_byte = - _cogl_vertex_buffer_indices_new_real (indices); - } - - return ctx->quad_buffer_indices_byte; - } - else - { - if (ctx->quad_buffer_indices && - ctx->quad_buffer_indices_len < n_indices) - { - cogl_handle_unref (ctx->quad_buffer_indices); - ctx->quad_buffer_indices = COGL_INVALID_HANDLE; - } - - if (ctx->quad_buffer_indices == COGL_INVALID_HANDLE) - { - /* NB: cogl_get_quad_indices takes n_quads not n_indices... */ - CoglIndices *indices = - cogl_get_rectangle_indices (ctx, n_indices / 6); - cogl_object_ref (indices); - ctx->quad_buffer_indices = - _cogl_vertex_buffer_indices_new_real (indices); - } - - ctx->quad_buffer_indices_len = n_indices; - - return ctx->quad_buffer_indices; - } - - g_return_val_if_reached (NULL); -} - diff --git a/cogl/cogl/deprecated/cogl-vertex-buffer.h b/cogl/cogl/deprecated/cogl-vertex-buffer.h deleted file mode 100644 index 8b780224e..000000000 --- a/cogl/cogl/deprecated/cogl-vertex-buffer.h +++ /dev/null @@ -1,451 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __COGL_VERTEX_BUFFER_H__ -#define __COGL_VERTEX_BUFFER_H__ - -#include -#include -#include -#include - -COGL_BEGIN_DECLS - -/** - * SECTION:cogl-vertex-buffer - * @short_description: An API for submitting extensible arrays of vertex - * attributes to be mapped into the GPU for fast drawing. - * - * For example to describe a textured triangle, you could create a new cogl - * vertex buffer with 3 vertices, and then you might add 2 attributes for each - * vertex: - * - * - * a "gl_Position" describing the (x,y,z) position for each vertex. - * - * - * a "gl_MultiTexCoord0" describing the (tx,ty) texture coordinates for each - * vertex. - * - * - * - * The Vertex Buffer API is designed to be a fairly raw mechanism for - * developers to be able to submit geometry to Cogl in a format that can be - * directly consumed by an OpenGL driver and mapped into your GPU for fast - * re-use. It is designed to avoid repeated validation of the attributes by the - * driver; to minimize transport costs (e.g. considering indirect GLX - * use-cases) and to potentially avoid repeated format conversions when - * attributes are supplied in a format that is not natively supported by the - * GPU. - * - * Although this API does allow you to modify attributes after they have been - * submitted to the GPU you should be aware that modification is not that - * cheap, since it implies validating the new data and potentially the - * OpenGL driver will need to reformat it for the GPU. - * - * If at all possible think of tricks that let you re-use static attributes, - * and if you do need to repeatedly update attributes (e.g. for some kind of - * morphing geometry) then only update and re-submit the specific attributes - * that have changed. - */ - -/** - * cogl_vertex_buffer_new: - * @n_vertices: The number of vertices that your attributes will correspond to. - * - * Creates a new vertex buffer that you can use to add attributes. - * - * Return value: a new #CoglHandle - * Deprecated: 1.16: Use the #CoglPrimitive api instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_primitive_API) -CoglHandle -cogl_vertex_buffer_new (unsigned int n_vertices); - -/** - * cogl_vertex_buffer_get_n_vertices: - * @handle: A vertex buffer handle - * - * Retrieves the number of vertices that @handle represents - * - * Return value: the number of vertices - * Deprecated: 1.16: Use the #CoglPrimitive api instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_primitive_API) -unsigned int -cogl_vertex_buffer_get_n_vertices (CoglHandle handle); - -/** - * cogl_vertex_buffer_add: - * @handle: A vertex buffer handle - * @attribute_name: The name of your attribute. It should be a valid GLSL - * variable name and standard attribute types must use one of following - * built-in names: (Note: they correspond to the built-in names of GLSL) - * - * "gl_Color" - * "gl_Normal" - * "gl_MultiTexCoord0, gl_MultiTexCoord1, ..." - * "gl_Vertex" - * - * To support adding multiple variations of the same attribute the name - * can have a detail component, E.g. "gl_Color::active" or - * "gl_Color::inactive" - * @n_components: The number of components per attribute and must be 1, 2, - * 3 or 4 - * @type: a #CoglAttributeType specifying the data type of each component. - * @normalized: If %TRUE, this specifies that values stored in an integer - * format should be mapped into the range [-1.0, 1.0] or [0.0, 1.0] - * for unsigned values. If %FALSE they are converted to floats - * directly. - * @stride: This specifies the number of bytes from the start of one attribute - * value to the start of the next value (for the same attribute). So, for - * example, with a position interleved with color like this: - * XYRGBAXYRGBAXYRGBA, then if each letter represents a byte, the - * stride for both attributes is 6. The special value 0 means the - * values are stored sequentially in memory. - * @pointer: This addresses the first attribute in the vertex array. This - * must remain valid until you either call cogl_vertex_buffer_submit() or - * issue a draw call. - * - * Adds an attribute to a buffer, or replaces a previously added - * attribute with the same name. - * - * You either can use one of the built-in names such as "gl_Vertex", or - * "gl_MultiTexCoord0" to add standard attributes, like positions, colors - * and normals, or you can add custom attributes for use in shaders. - * - * The number of vertices declared when calling cogl_vertex_buffer_new() - * determines how many attribute values will be read from the supplied - * @pointer. - * - * The data for your attribute isn't copied anywhere until you call - * cogl_vertex_buffer_submit(), or issue a draw call which automatically - * submits pending attribute changes. so the supplied pointer must remain - * valid until then. If you are updating an existing attribute (done by - * re-adding it) then you still need to re-call cogl_vertex_buffer_submit() - * to commit the changes to the GPU. Be carefull to minimize the number - * of calls to cogl_vertex_buffer_submit(), though. - * - * If you are interleving attributes it is assumed that each interleaved - * attribute starts no farther than +- stride bytes from the other attributes - * it is interleved with. I.e. this is ok: - * - * |-0-0-0-0-0-0-0-0-0-0| - * - * This is not ok: - * - * |- - - - -0-0-0-0-0-0 0 0 0 0| - * - * (Though you can have multiple groups of interleved attributes) - * - * Deprecated: 1.16: Use the #CoglPrimitive api instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_primitive_API) -void -cogl_vertex_buffer_add (CoglHandle handle, - const char *attribute_name, - uint8_t n_components, - CoglAttributeType type, - CoglBool normalized, - uint16_t stride, - const void *pointer); - -/** - * cogl_vertex_buffer_delete: - * @handle: A vertex buffer handle - * @attribute_name: The name of a previously added attribute - * - * Deletes an attribute from a buffer. You will need to call - * cogl_vertex_buffer_submit() or issue a draw call to commit this - * change to the GPU. - * - * Deprecated: 1.16: Use the #CoglPrimitive api instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_primitive_API) -void -cogl_vertex_buffer_delete (CoglHandle handle, - const char *attribute_name); - -/** - * cogl_vertex_buffer_submit: - * @handle: A vertex buffer handle - * - * Submits all the user added attributes to the GPU; once submitted, the - * attributes can be used for drawing. - * - * You should aim to minimize calls to this function since it implies - * validating your data; it potentially incurs a transport cost (especially if - * you are using GLX indirect rendering) and potentially a format conversion - * cost if the GPU doesn't natively support any of the given attribute formats. - * - * Deprecated: 1.16: Use the #CoglPrimitive api instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_primitive_API) -void -cogl_vertex_buffer_submit (CoglHandle handle); - -/** - * cogl_vertex_buffer_disable: - * @handle: A vertex buffer handle - * @attribute_name: The name of the attribute you want to disable - * - * Disables a previosuly added attribute. - * - * Since it can be costly to add and remove new attributes to buffers; to make - * individual buffers more reuseable it is possible to enable and disable - * attributes before using a buffer for drawing. - * - * You don't need to call cogl_vertex_buffer_submit() after using this - * function. - * - * Deprecated: 1.16: Use the #CoglPrimitive api instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_primitive_API) -void -cogl_vertex_buffer_disable (CoglHandle handle, - const char *attribute_name); - -/** - * cogl_vertex_buffer_enable: - * @handle: A vertex buffer handle - * @attribute_name: The name of the attribute you want to enable - * - * Enables a previosuly disabled attribute. - * - * Since it can be costly to add and remove new attributes to buffers; to make - * individual buffers more reuseable it is possible to enable and disable - * attributes before using a buffer for drawing. - * - * You don't need to call cogl_vertex_buffer_submit() after using this function - * - * Deprecated: 1.16: Use the #CoglPrimitive api instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_primitive_API) -void -cogl_vertex_buffer_enable (CoglHandle handle, - const char *attribute_name); - -/** - * cogl_vertex_buffer_draw: - * @handle: A vertex buffer handle - * @mode: A #CoglVerticesMode specifying how the vertices should be - * interpreted. - * @first: Specifies the index of the first vertex you want to draw with - * @count: Specifies the number of vertices you want to draw. - * - * Allows you to draw geometry using all or a subset of the - * vertices in a vertex buffer. - * - * Any un-submitted attribute changes are automatically submitted before - * drawing. - * - * Deprecated: 1.16: Use the #CoglPrimitive api instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_primitive_API) -void -cogl_vertex_buffer_draw (CoglHandle handle, - CoglVerticesMode mode, - int first, - int count); - -/** - * cogl_vertex_buffer_indices_new: (skip) - * @indices_type: a #CoglIndicesType specifying the data type used for - * the indices. - * @indices_array: (array length=indices_len): Specifies the address of - * your array of indices - * @indices_len: The number of indices in indices_array - * - * Depending on how much geometry you are submitting it can be worthwhile - * optimizing the number of redundant vertices you submit. Using an index - * array allows you to reference vertices multiple times, for example - * during triangle strips. - * - * Return value: A CoglHandle for the indices which you can pass to - * cogl_vertex_buffer_draw_elements(). - * - * Deprecated: 1.16: Use the #CoglPrimitive api instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_primitive_API) -CoglHandle -cogl_vertex_buffer_indices_new (CoglIndicesType indices_type, - const void *indices_array, - int indices_len); - -/** - * cogl_vertex_buffer_indices_get_type: - * @indices: An indices handle - * - * Queries back the data type used for the given indices - * - * Returns: The CoglIndicesType used - * - * Deprecated: 1.16: Use the #CoglPrimitive api instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_primitive_API) -CoglIndicesType -cogl_vertex_buffer_indices_get_type (CoglHandle indices); - -/** - * cogl_vertex_buffer_draw_elements: - * @handle: A vertex buffer handle - * @mode: A #CoglVerticesMode specifying how the vertices should be - * interpreted. - * @indices: A CoglHandle for a set of indices allocated via - * cogl_vertex_buffer_indices_new () - * @min_index: Specifies the minimum vertex index contained in indices - * @max_index: Specifies the maximum vertex index contained in indices - * @indices_offset: An offset into named indices. The offset marks the first - * index to use for drawing. - * @count: Specifies the number of vertices you want to draw. - * - * This function lets you use an array of indices to specify the vertices - * within your vertex buffer that you want to draw. The indices themselves - * are created by calling cogl_vertex_buffer_indices_new () - * - * Any un-submitted attribute changes are automatically submitted before - * drawing. - * Deprecated: 1.16: Use the #CoglPrimitive api instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_primitive_API) -void -cogl_vertex_buffer_draw_elements (CoglHandle handle, - CoglVerticesMode mode, - CoglHandle indices, - int min_index, - int max_index, - int indices_offset, - int count); - -/** - * cogl_vertex_buffer_ref: - * @handle: a @CoglHandle. - * - * Increment the reference count for a vertex buffer - * - * Return value: the @handle. - * - * Deprecated: 1.2: Use cogl_object_ref() instead - */ -COGL_DEPRECATED_FOR (cogl_object_ref) -CoglHandle -cogl_vertex_buffer_ref (CoglHandle handle); - -/** - * cogl_vertex_buffer_unref: - * @handle: a @CoglHandle. - * - * Decrement the reference count for a vertex buffer - * - * Deprecated: 1.2: Use cogl_object_unref() instead - */ -COGL_DEPRECATED_FOR (cogl_object_unref) -void -cogl_vertex_buffer_unref (CoglHandle handle); - -/** - * cogl_vertex_buffer_indices_get_for_quads: - * @n_indices: the number of indices in the vertex buffer. - * - * Creates a vertex buffer containing the indices needed to draw pairs - * of triangles from a list of vertices grouped as quads. There will - * be at least @n_indices entries in the buffer (but there may be - * more). - * - * The indices will follow this pattern: - * - * 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7 ... etc - * - * For example, if you submit vertices for a quad like like that shown - * in then you can request 6 - * indices to render two triangles like those shown in . - * - *
- * Example of vertices submitted to form a quad - * - *
- * - *
- * Illustration of the triangle indices that will be generated - * - *
- * - * Returns: A %CoglHandle containing the indices. The handled is - * owned by Cogl and should not be modified or unref'd. - * - * Deprecated: 1.16: Use the #CoglPrimitive api instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_primitive_API) -CoglHandle -cogl_vertex_buffer_indices_get_for_quads (unsigned int n_indices); - -/** - * cogl_is_vertex_buffer: - * @handle: a #CoglHandle for a vertex buffer object - * - * Checks whether @handle is a Vertex Buffer Object - * - * Return value: %TRUE if the handle is a VBO, and %FALSE - * otherwise - * - * Since: 1.0 - * Deprecated: 1.16: Use the #CoglPrimitive api instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_primitive_API) -CoglBool -cogl_is_vertex_buffer (CoglHandle handle); - -/** - * cogl_is_vertex_buffer_indices: - * @handle: a #CoglHandle - * - * Checks whether @handle is a handle to the indices for a vertex - * buffer object - * - * Return value: %TRUE if the handle is indices, and %FALSE - * otherwise - * - * Since: 1.4 - * Deprecated: 1.16: Use the #CoglPrimitive api instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_primitive_API) -CoglBool -cogl_is_vertex_buffer_indices (CoglHandle handle); -COGL_END_DECLS - -#endif /* __COGL_VERTEX_BUFFER_H__ */ diff --git a/cogl/cogl/driver/gl/cogl-attribute-gl-private.h b/cogl/cogl/driver/gl/cogl-attribute-gl-private.h index efb3c0ea2..8370621e3 100644 --- a/cogl/cogl/driver/gl/cogl-attribute-gl-private.h +++ b/cogl/cogl/driver/gl/cogl-attribute-gl-private.h @@ -47,7 +47,4 @@ _cogl_gl_flush_attributes_state (CoglFramebuffer *framebuffer, CoglAttribute **attributes, int n_attributes); -void -_cogl_gl_disable_all_attributes (CoglContext *ctx); - #endif /* _COGL_ATTRIBUTE_GL_PRIVATE_H_ */ diff --git a/cogl/cogl/driver/gl/cogl-attribute-gl.c b/cogl/cogl/driver/gl/cogl-attribute-gl.c index 0599049f0..620992dfb 100644 --- a/cogl/cogl/driver/gl/cogl-attribute-gl.c +++ b/cogl/cogl/driver/gl/cogl-attribute-gl.c @@ -32,22 +32,19 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include #include "cogl-private.h" -#include "cogl-util-gl-private.h" -#include "cogl-pipeline-opengl-private.h" -#include "cogl-error-private.h" #include "cogl-context-private.h" #include "cogl-attribute.h" #include "cogl-attribute-private.h" -#include "cogl-attribute-gl-private.h" -#include "cogl-pipeline-progend-glsl-private.h" -#include "cogl-buffer-gl-private.h" +#include "driver/gl/cogl-attribute-gl-private.h" +#include "driver/gl/cogl-buffer-gl-private.h" +#include "driver/gl/cogl-pipeline-opengl-private.h" +#include "driver/gl/cogl-pipeline-progend-glsl-private.h" +#include "driver/gl/cogl-util-gl-private.h" typedef struct _ForeachChangedBitState { @@ -56,76 +53,11 @@ typedef struct _ForeachChangedBitState CoglPipeline *pipeline; } ForeachChangedBitState; -static CoglBool -toggle_builtin_attribute_enabled_cb (int bit_num, void *user_data) -{ - ForeachChangedBitState *state = user_data; - CoglContext *context = state->context; - - _COGL_RETURN_VAL_IF_FAIL (_cogl_has_private_feature - (context, COGL_PRIVATE_FEATURE_GL_FIXED), - FALSE); - -#if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES) - { - CoglBool enabled = _cogl_bitmask_get (state->new_bits, bit_num); - GLenum cap; - - switch (bit_num) - { - case COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY: - cap = GL_COLOR_ARRAY; - break; - case COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY: - cap = GL_VERTEX_ARRAY; - break; - case COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY: - cap = GL_NORMAL_ARRAY; - break; - default: - g_assert_not_reached (); - } - if (enabled) - GE (context, glEnableClientState (cap)); - else - GE (context, glDisableClientState (cap)); - } -#endif - - return TRUE; -} - -static CoglBool -toggle_texcood_attribute_enabled_cb (int bit_num, void *user_data) -{ - ForeachChangedBitState *state = user_data; - CoglContext *context = state->context; - - _COGL_RETURN_VAL_IF_FAIL (_cogl_has_private_feature - (context, COGL_PRIVATE_FEATURE_GL_FIXED), - FALSE); - -#if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES) - { - CoglBool enabled = _cogl_bitmask_get (state->new_bits, bit_num); - - GE( context, glClientActiveTexture (GL_TEXTURE0 + bit_num) ); - - if (enabled) - GE( context, glEnableClientState (GL_TEXTURE_COORD_ARRAY) ); - else - GE( context, glDisableClientState (GL_TEXTURE_COORD_ARRAY) ); - } -#endif - - return TRUE; -} - -static CoglBool +static gboolean toggle_custom_attribute_enabled_cb (int bit_num, void *user_data) { ForeachChangedBitState *state = user_data; - CoglBool enabled = _cogl_bitmask_get (state->new_bits, bit_num); + gboolean enabled = _cogl_bitmask_get (state->new_bits, bit_num); CoglContext *context = state->context; if (enabled) @@ -159,8 +91,6 @@ foreach_changed_bit_and_save (CoglContext *context, _cogl_bitmask_set_bits (current_bits, new_bits); } -#ifdef COGL_PIPELINE_PROGEND_GLSL - static void setup_generic_buffered_attribute (CoglContext *context, CoglPipeline *pipeline, @@ -232,136 +162,6 @@ setup_generic_const_attribute (CoglContext *context, } } -#endif /* COGL_PIPELINE_PROGEND_GLSL */ - -static void -setup_legacy_buffered_attribute (CoglContext *ctx, - CoglPipeline *pipeline, - CoglAttribute *attribute, - uint8_t *base) -{ - switch (attribute->name_state->name_id) - { - case COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY: - _cogl_bitmask_set (&ctx->enable_builtin_attributes_tmp, - COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY, TRUE); - GE (ctx, glColorPointer (attribute->d.buffered.n_components, - attribute->d.buffered.type, - attribute->d.buffered.stride, - base + attribute->d.buffered.offset)); - break; - case COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY: - _cogl_bitmask_set (&ctx->enable_builtin_attributes_tmp, - COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY, TRUE); - GE (ctx, glNormalPointer (attribute->d.buffered.type, - attribute->d.buffered.stride, - base + attribute->d.buffered.offset)); - break; - case COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY: - { - int layer_number = attribute->name_state->layer_number; - const CoglPipelineGetLayerFlags flags = - COGL_PIPELINE_GET_LAYER_NO_CREATE; - CoglPipelineLayer *layer = - _cogl_pipeline_get_layer_with_flags (pipeline, layer_number, flags); - - if (layer) - { - int unit = _cogl_pipeline_layer_get_unit_index (layer); - - _cogl_bitmask_set (&ctx->enable_texcoord_attributes_tmp, - unit, - TRUE); - - GE (ctx, glClientActiveTexture (GL_TEXTURE0 + unit)); - GE (ctx, glTexCoordPointer (attribute->d.buffered.n_components, - attribute->d.buffered.type, - attribute->d.buffered.stride, - base + attribute->d.buffered.offset)); - } - break; - } - case COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY: - _cogl_bitmask_set (&ctx->enable_builtin_attributes_tmp, - COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY, TRUE); - GE (ctx, glVertexPointer (attribute->d.buffered.n_components, - attribute->d.buffered.type, - attribute->d.buffered.stride, - base + attribute->d.buffered.offset)); - break; - case COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY: -#ifdef COGL_PIPELINE_PROGEND_GLSL - if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_PROGRAMMABLE)) - setup_generic_buffered_attribute (ctx, pipeline, attribute, base); -#endif - break; - default: - g_warn_if_reached (); - } -} - -static void -setup_legacy_const_attribute (CoglContext *ctx, - CoglPipeline *pipeline, - CoglAttribute *attribute) -{ -#ifdef COGL_PIPELINE_PROGEND_GLSL - if (attribute->name_state->name_id == COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY) - { - if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_PROGRAMMABLE)) - setup_generic_const_attribute (ctx, pipeline, attribute); - } - else -#endif - { - float vector[4] = { 0, 0, 0, 1 }; - float *boxed = attribute->d.constant.boxed.v.float_value; - int n_components = attribute->d.constant.boxed.size; - int i; - - for (i = 0; i < n_components; i++) - vector[i] = boxed[i]; - - switch (attribute->name_state->name_id) - { - case COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY: - GE (ctx, glColor4f (vector[0], vector[1], vector[2], vector[3])); - break; - case COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY: - GE (ctx, glNormal3f (vector[0], vector[1], vector[2])); - break; - case COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY: - { - int layer_number = attribute->name_state->layer_number; - const CoglPipelineGetLayerFlags flags = - COGL_PIPELINE_GET_LAYER_NO_CREATE; - CoglPipelineLayer *layer = - _cogl_pipeline_get_layer_with_flags (pipeline, - layer_number, - flags); - - if (layer) - { - int unit = _cogl_pipeline_layer_get_unit_index (layer); - - GE (ctx, glClientActiveTexture (GL_TEXTURE0 + unit)); - - GE (ctx, glMultiTexCoord4f (vector[0], - vector[1], - vector[2], - vector[3])); - } - break; - } - case COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY: - GE (ctx, glVertex4f (vector[0], vector[1], vector[2], vector[3])); - break; - default: - g_warn_if_reached (); - } - } -} - static void apply_attribute_enable_updates (CoglContext *context, CoglPipeline *pipeline) @@ -369,22 +169,7 @@ apply_attribute_enable_updates (CoglContext *context, ForeachChangedBitState changed_bits_state; changed_bits_state.context = context; - changed_bits_state.new_bits = &context->enable_builtin_attributes_tmp; changed_bits_state.pipeline = pipeline; - - foreach_changed_bit_and_save (context, - &context->enabled_builtin_attributes, - &context->enable_builtin_attributes_tmp, - toggle_builtin_attribute_enabled_cb, - &changed_bits_state); - - changed_bits_state.new_bits = &context->enable_texcoord_attributes_tmp; - foreach_changed_bit_and_save (context, - &context->enabled_texcoord_attributes, - &context->enable_texcoord_attributes_tmp, - toggle_texcood_attribute_enabled_cb, - &changed_bits_state); - changed_bits_state.new_bits = &context->enable_custom_attributes_tmp; foreach_changed_bit_and_save (context, &context->enabled_custom_attributes, @@ -403,8 +188,8 @@ _cogl_gl_flush_attributes_state (CoglFramebuffer *framebuffer, { CoglContext *ctx = framebuffer->context; int i; - CoglBool with_color_attrib = FALSE; - CoglBool unknown_color_alpha = FALSE; + gboolean with_color_attrib = FALSE; + gboolean unknown_color_alpha = FALSE; CoglPipeline *copy = NULL; /* Iterate the attributes to see if we have a color attribute which @@ -442,7 +227,6 @@ _cogl_gl_flush_attributes_state (CoglFramebuffer *framebuffer, * { * age = cogl_pipeline_get_age (pipeline); * XXX: actually we also need to check for legacy_state - * and blending overrides for use of glColorPointer... * if (overrides->ags != age || * memcmp (&overrides->options, &options, * sizeof (options) != 0) @@ -475,8 +259,6 @@ _cogl_gl_flush_attributes_state (CoglFramebuffer *framebuffer, with_color_attrib, unknown_color_alpha); - _cogl_bitmask_clear_all (&ctx->enable_builtin_attributes_tmp); - _cogl_bitmask_clear_all (&ctx->enable_texcoord_attributes_tmp); _cogl_bitmask_clear_all (&ctx->enable_custom_attributes_tmp); /* Bind the attribute pointers. We need to do this after the @@ -505,19 +287,13 @@ _cogl_gl_flush_attributes_state (CoglFramebuffer *framebuffer, COGL_BUFFER_BIND_TARGET_ATTRIBUTE_BUFFER, NULL); - if (pipeline->progend == COGL_PIPELINE_PROGEND_GLSL) - setup_generic_buffered_attribute (ctx, pipeline, attribute, base); - else - setup_legacy_buffered_attribute (ctx, pipeline, attribute, base); + setup_generic_buffered_attribute (ctx, pipeline, attribute, base); _cogl_buffer_gl_unbind (buffer); } else { - if (pipeline->progend == COGL_PIPELINE_PROGEND_GLSL) - setup_generic_const_attribute (ctx, pipeline, attribute); - else - setup_legacy_const_attribute (ctx, pipeline, attribute); + setup_generic_const_attribute (ctx, pipeline, attribute); } } @@ -526,16 +302,3 @@ _cogl_gl_flush_attributes_state (CoglFramebuffer *framebuffer, if (copy) cogl_object_unref (copy); } - -void -_cogl_gl_disable_all_attributes (CoglContext *ctx) -{ - _cogl_bitmask_clear_all (&ctx->enable_builtin_attributes_tmp); - _cogl_bitmask_clear_all (&ctx->enable_texcoord_attributes_tmp); - _cogl_bitmask_clear_all (&ctx->enable_custom_attributes_tmp); - - /* XXX: we can pass a NULL source pipeline here because we know a - * source pipeline only needs to be referenced when enabling - * attributes. */ - apply_attribute_enable_updates (ctx, NULL); -} diff --git a/cogl/cogl/cogl-config-private.h b/cogl/cogl/driver/gl/cogl-bitmap-gl-private.h similarity index 59% rename from cogl/cogl/cogl-config-private.h rename to cogl/cogl/driver/gl/cogl-bitmap-gl-private.h index 93ff943b2..b2726c421 100644 --- a/cogl/cogl/cogl-config-private.h +++ b/cogl/cogl/driver/gl/cogl-bitmap-gl-private.h @@ -3,7 +3,7 @@ * * A Low Level GPU Graphics and Utilities API * - * Copyright (C) 2011 Intel Corporation. + * Copyright (C) 2007 OpenedHand * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -26,20 +26,27 @@ * SOFTWARE. * * - * - * Authors: - * Robert Bragg */ -#ifndef __COGL_CONFIG_PRIVATE_H -#define __COGL_CONFIG_PRIVATE_H +#ifndef __COGL_BITMAP_GL_PRIVATE_H +#define __COGL_BITMAP_GL_PRIVATE_H -void -_cogl_config_read (void); +#include "cogl-bitmap-private.h" -extern char *_cogl_config_driver; -extern char *_cogl_config_renderer; -extern char *_cogl_config_disable_gl_extensions; -extern char *_cogl_config_override_gl_version; +/* These two are replacements for map and unmap that should used when + * the pointer is going to be passed to GL for pixel packing or + * unpacking. The address might not be valid for reading if the bitmap + * was created with new_from_buffer but it will however be good to + * pass to glTexImage2D for example. The access should be READ for + * unpacking and WRITE for packing. It can not be both + */ +uint8_t * +_cogl_bitmap_gl_bind (CoglBitmap *bitmap, + CoglBufferAccess access, + CoglBufferMapHint hints, + GError **error); + +void +_cogl_bitmap_gl_unbind (CoglBitmap *bitmap); -#endif /* __COGL_CONFIG_PRIVATE_H */ +#endif /* __COGL_BITMAP_GL_PRIVATE_H */ diff --git a/cogl/cogl/driver/gl/cogl-bitmap-gl.c b/cogl/cogl/driver/gl/cogl-bitmap-gl.c new file mode 100644 index 000000000..8011d7fc8 --- /dev/null +++ b/cogl/cogl/driver/gl/cogl-bitmap-gl.c @@ -0,0 +1,122 @@ +/* + * Cogl + * + * A Low Level GPU Graphics and Utilities API + * + * Copyright (C) 2007,2008,2009 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * + */ + +#include "cogl-config.h" + +#include "cogl-util.h" +#include "cogl-debug.h" +#include "cogl-private.h" +#include "cogl-bitmap-private.h" +#include "cogl-buffer-private.h" +#include "cogl-pixel-buffer.h" +#include "cogl-context-private.h" +#include "cogl-gtype-private.h" +#include "cogl-buffer-gl-private.h" +#include "cogl-bitmap-gl-private.h" + +uint8_t * +_cogl_bitmap_gl_bind (CoglBitmap *bitmap, + CoglBufferAccess access, + CoglBufferMapHint hints, + GError **error) +{ + uint8_t *ptr; + GError *internal_error = NULL; + + g_return_val_if_fail (access & (COGL_BUFFER_ACCESS_READ | + COGL_BUFFER_ACCESS_WRITE), + NULL); + + /* Divert to another bitmap if this data is shared */ + if (bitmap->shared_bmp) + return _cogl_bitmap_gl_bind (bitmap->shared_bmp, access, hints, error); + + g_return_val_if_fail (!bitmap->bound, NULL); + + /* If the bitmap wasn't created from a buffer then the + implementation of bind is the same as map */ + if (bitmap->buffer == NULL) + { + uint8_t *data = _cogl_bitmap_map (bitmap, access, hints, error); + if (data) + bitmap->bound = TRUE; + return data; + } + + if (access == COGL_BUFFER_ACCESS_READ) + ptr = _cogl_buffer_gl_bind (bitmap->buffer, + COGL_BUFFER_BIND_TARGET_PIXEL_UNPACK, + &internal_error); + else if (access == COGL_BUFFER_ACCESS_WRITE) + ptr = _cogl_buffer_gl_bind (bitmap->buffer, + COGL_BUFFER_BIND_TARGET_PIXEL_PACK, + &internal_error); + else + { + ptr = NULL; + g_assert_not_reached (); + return NULL; + } + + /* NB: _cogl_buffer_gl_bind() may return NULL in non-error + * conditions so we have to explicitly check internal_error to see + * if an exception was thrown */ + if (internal_error) + { + g_propagate_error (error, internal_error); + return NULL; + } + + bitmap->bound = TRUE; + + /* The data pointer actually stores the offset */ + return ptr + GPOINTER_TO_INT (bitmap->data); +} + +void +_cogl_bitmap_gl_unbind (CoglBitmap *bitmap) +{ + /* Divert to another bitmap if this data is shared */ + if (bitmap->shared_bmp) + { + _cogl_bitmap_gl_unbind (bitmap->shared_bmp); + return; + } + + g_assert (bitmap->bound); + bitmap->bound = FALSE; + + /* If the bitmap wasn't created from a pixel array then the + implementation of unbind is the same as unmap */ + if (bitmap->buffer) + _cogl_buffer_gl_unbind (bitmap->buffer); + else + _cogl_bitmap_unmap (bitmap); +} diff --git a/cogl/cogl/driver/gl/cogl-buffer-gl-private.h b/cogl/cogl/driver/gl/cogl-buffer-gl-private.h index b8f0435b3..61807f17e 100644 --- a/cogl/cogl/driver/gl/cogl-buffer-gl-private.h +++ b/cogl/cogl/driver/gl/cogl-buffer-gl-private.h @@ -51,22 +51,22 @@ _cogl_buffer_gl_map_range (CoglBuffer *buffer, size_t size, CoglBufferAccess access, CoglBufferMapHint hints, - CoglError **error); + GError **error); void _cogl_buffer_gl_unmap (CoglBuffer *buffer); -CoglBool +gboolean _cogl_buffer_gl_set_data (CoglBuffer *buffer, unsigned int offset, const void *data, unsigned int size, - CoglError **error); + GError **error); void * _cogl_buffer_gl_bind (CoglBuffer *buffer, CoglBufferBindTarget target, - CoglError **error); + GError **error); void _cogl_buffer_gl_unbind (CoglBuffer *buffer); diff --git a/cogl/cogl/driver/gl/cogl-buffer-gl.c b/cogl/cogl/driver/gl/cogl-buffer-gl.c index f3c134a9c..7fce18a56 100644 --- a/cogl/cogl/driver/gl/cogl-buffer-gl.c +++ b/cogl/cogl/driver/gl/cogl-buffer-gl.c @@ -32,14 +32,11 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-context-private.h" -#include "cogl-buffer-gl-private.h" -#include "cogl-error-private.h" -#include "cogl-util-gl-private.h" +#include "driver/gl/cogl-buffer-gl-private.h" +#include "driver/gl/cogl-util-gl-private.h" /* * GL/GLES compatibility defines for the buffer API: @@ -107,14 +104,14 @@ update_hints_to_gl_enum (CoglBuffer *buffer) case COGL_BUFFER_UPDATE_HINT_STREAM: /* OpenGL ES 1.1 only knows about STATIC_DRAW and DYNAMIC_DRAW */ #if defined(HAVE_COGL_GL) || defined(HAVE_COGL_GLES2) - if (buffer->context->driver != COGL_DRIVER_GLES1) - return GL_STREAM_DRAW; + return GL_STREAM_DRAW; #else return GL_DYNAMIC_DRAW; #endif } g_assert_not_reached (); + return 0; } static GLenum @@ -135,9 +132,9 @@ convert_bind_target_to_gl_target (CoglBufferBindTarget target) } } -static CoglBool +static gboolean recreate_store (CoglBuffer *buffer, - CoglError **error) + GError **error) { CoglContext *ctx = buffer->context; GLenum gl_target; @@ -163,7 +160,7 @@ recreate_store (CoglBuffer *buffer, return TRUE; } -GLenum +static GLenum _cogl_buffer_access_to_gl_enum (CoglBufferAccess access) { if ((access & COGL_BUFFER_ACCESS_READ_WRITE) == COGL_BUFFER_ACCESS_READ_WRITE) @@ -180,14 +177,14 @@ _cogl_buffer_bind_no_create (CoglBuffer *buffer, { CoglContext *ctx = buffer->context; - _COGL_RETURN_VAL_IF_FAIL (buffer != NULL, NULL); + g_return_val_if_fail (buffer != NULL, NULL); /* Don't allow binding the buffer to multiple targets at the same time */ - _COGL_RETURN_VAL_IF_FAIL (ctx->current_buffer[buffer->last_target] != buffer, - NULL); + g_return_val_if_fail (ctx->current_buffer[buffer->last_target] != buffer, + NULL); /* Don't allow nesting binds to the same target */ - _COGL_RETURN_VAL_IF_FAIL (ctx->current_buffer[target] == NULL, NULL); + g_return_val_if_fail (ctx->current_buffer[target] == NULL, NULL); buffer->last_target = target; ctx->current_buffer[target] = buffer; @@ -208,7 +205,7 @@ _cogl_buffer_gl_map_range (CoglBuffer *buffer, size_t size, CoglBufferAccess access, CoglBufferMapHint hints, - CoglError **error) + GError **error) { uint8_t *data; CoglBufferBindTarget target; @@ -220,10 +217,10 @@ _cogl_buffer_gl_map_range (CoglBuffer *buffer, ((access & COGL_BUFFER_ACCESS_WRITE) && !cogl_has_feature (ctx, COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE))) { - _cogl_set_error (error, - COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_UNSUPPORTED, - "Tried to map a buffer with unsupported access mode"); + g_set_error_literal (error, + COGL_SYSTEM_ERROR, + COGL_SYSTEM_ERROR_UNSUPPORTED, + "Tried to map a buffer with unsupported access mode"); return NULL; } @@ -243,7 +240,7 @@ _cogl_buffer_gl_map_range (CoglBuffer *buffer, if (ctx->glMapBufferRange) { GLbitfield gl_access = 0; - CoglBool should_recreate_store = !buffer->store_created; + gboolean should_recreate_store = !buffer->store_created; if ((access & COGL_BUFFER_ACCESS_READ)) gl_access |= GL_MAP_READ_BIT; @@ -292,7 +289,7 @@ _cogl_buffer_gl_map_range (CoglBuffer *buffer, return NULL; } - _COGL_RETURN_VAL_IF_FAIL (data != NULL, NULL); + g_return_val_if_fail (data != NULL, NULL); } else { @@ -321,7 +318,7 @@ _cogl_buffer_gl_map_range (CoglBuffer *buffer, return NULL; } - _COGL_RETURN_VAL_IF_FAIL (data != NULL, NULL); + g_return_val_if_fail (data != NULL, NULL); data += offset; } @@ -348,18 +345,18 @@ _cogl_buffer_gl_unmap (CoglBuffer *buffer) _cogl_buffer_gl_unbind (buffer); } -CoglBool +gboolean _cogl_buffer_gl_set_data (CoglBuffer *buffer, unsigned int offset, const void *data, unsigned int size, - CoglError **error) + GError **error) { CoglBufferBindTarget target; GLenum gl_target; CoglContext *ctx = buffer->context; - CoglBool status = TRUE; - CoglError *internal_error = NULL; + gboolean status = TRUE; + GError *internal_error = NULL; target = buffer->last_target; @@ -371,7 +368,7 @@ _cogl_buffer_gl_set_data (CoglBuffer *buffer, */ if (internal_error) { - _cogl_propagate_error (error, internal_error); + g_propagate_error (error, internal_error); return FALSE; } @@ -393,7 +390,7 @@ _cogl_buffer_gl_set_data (CoglBuffer *buffer, void * _cogl_buffer_gl_bind (CoglBuffer *buffer, CoglBufferBindTarget target, - CoglError **error) + GError **error) { void *ret; @@ -420,10 +417,10 @@ _cogl_buffer_gl_unbind (CoglBuffer *buffer) { CoglContext *ctx = buffer->context; - _COGL_RETURN_IF_FAIL (buffer != NULL); + g_return_if_fail (buffer != NULL); /* the unbind should pair up with a previous bind */ - _COGL_RETURN_IF_FAIL (ctx->current_buffer[buffer->last_target] == buffer); + g_return_if_fail (ctx->current_buffer[buffer->last_target] == buffer); if (buffer->flags & COGL_BUFFER_FLAG_BUFFER_OBJECT) { diff --git a/cogl/cogl/driver/gl/cogl-clip-stack-gl.c b/cogl/cogl/driver/gl/cogl-clip-stack-gl.c index 5c77e07b6..24a714f6c 100644 --- a/cogl/cogl/driver/gl/cogl-clip-stack-gl.c +++ b/cogl/cogl/driver/gl/cogl-clip-stack-gl.c @@ -32,16 +32,14 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-context-private.h" -#include "cogl-util-gl-private.h" #include "cogl-primitives-private.h" -#include "cogl-pipeline-opengl-private.h" -#include "cogl-clip-stack-gl-private.h" #include "cogl-primitive-private.h" +#include "driver/gl/cogl-util-gl-private.h" +#include "driver/gl/cogl-pipeline-opengl-private.h" +#include "driver/gl/cogl-clip-stack-gl-private.h" #ifndef GL_CLIP_PLANE0 #define GL_CLIP_PLANE0 0x3000 @@ -52,155 +50,6 @@ #define GL_CLIP_PLANE5 0x3005 #endif -static void -project_vertex (const CoglMatrix *modelview_projection, - float *vertex) -{ - int i; - - cogl_matrix_transform_point (modelview_projection, - &vertex[0], &vertex[1], - &vertex[2], &vertex[3]); - - /* Convert from homogenized coordinates */ - for (i = 0; i < 4; i++) - vertex[i] /= vertex[3]; -} - -static void -set_clip_plane (CoglFramebuffer *framebuffer, - int plane_num, - const float *vertex_a, - const float *vertex_b) -{ - CoglContext *ctx = framebuffer->context; - float planef[4]; - double planed[4]; - float angle; - CoglMatrixStack *modelview_stack = - _cogl_framebuffer_get_modelview_stack (framebuffer); - CoglMatrixStack *projection_stack = - _cogl_framebuffer_get_projection_stack (framebuffer); - CoglMatrix inverse_projection; - - cogl_matrix_stack_get_inverse (projection_stack, &inverse_projection); - - /* Calculate the angle between the axes and the line crossing the - two points */ - angle = atan2f (vertex_b[1] - vertex_a[1], - vertex_b[0] - vertex_a[0]) * (180.0/G_PI); - - cogl_matrix_stack_push (modelview_stack); - - /* Load the inverse of the projection matrix so we can specify the plane - * in screen coordinates */ - cogl_matrix_stack_set (modelview_stack, &inverse_projection); - - /* Rotate about point a */ - cogl_matrix_stack_translate (modelview_stack, - vertex_a[0], vertex_a[1], vertex_a[2]); - /* Rotate the plane by the calculated angle so that it will connect - the two points */ - cogl_matrix_stack_rotate (modelview_stack, angle, 0.0f, 0.0f, 1.0f); - cogl_matrix_stack_translate (modelview_stack, - -vertex_a[0], -vertex_a[1], -vertex_a[2]); - - /* Clip planes can only be used when a fixed function backend is in - use so we know we can directly push this matrix to the builtin - state */ - _cogl_matrix_entry_flush_to_gl_builtins (ctx, - modelview_stack->last_entry, - COGL_MATRIX_MODELVIEW, - framebuffer, - FALSE /* don't disable flip */); - - planef[0] = 0; - planef[1] = -1.0; - planef[2] = 0; - planef[3] = vertex_a[1]; - - switch (ctx->driver) - { - default: - g_assert_not_reached (); - break; - - case COGL_DRIVER_GLES1: - GE( ctx, glClipPlanef (plane_num, planef) ); - break; - - case COGL_DRIVER_GL: - case COGL_DRIVER_GL3: - planed[0] = planef[0]; - planed[1] = planef[1]; - planed[2] = planef[2]; - planed[3] = planef[3]; - GE( ctx, glClipPlane (plane_num, planed) ); - break; - } - - cogl_matrix_stack_pop (modelview_stack); -} - -static void -set_clip_planes (CoglFramebuffer *framebuffer, - CoglMatrixEntry *modelview_entry, - float x_1, - float y_1, - float x_2, - float y_2) -{ - CoglMatrix modelview_matrix; - CoglMatrixStack *projection_stack = - _cogl_framebuffer_get_projection_stack (framebuffer); - CoglMatrix projection_matrix; - CoglMatrix modelview_projection; - float signed_area; - - float vertex_tl[4] = { x_1, y_1, 0, 1.0 }; - float vertex_tr[4] = { x_2, y_1, 0, 1.0 }; - float vertex_bl[4] = { x_1, y_2, 0, 1.0 }; - float vertex_br[4] = { x_2, y_2, 0, 1.0 }; - - cogl_matrix_stack_get (projection_stack, &projection_matrix); - cogl_matrix_entry_get (modelview_entry, &modelview_matrix); - - cogl_matrix_multiply (&modelview_projection, - &projection_matrix, - &modelview_matrix); - - project_vertex (&modelview_projection, vertex_tl); - project_vertex (&modelview_projection, vertex_tr); - project_vertex (&modelview_projection, vertex_bl); - project_vertex (&modelview_projection, vertex_br); - - /* Calculate the signed area of the polygon formed by the four - vertices so that we can know its orientation */ - signed_area = (vertex_tl[0] * (vertex_tr[1] - vertex_bl[1]) - + vertex_tr[0] * (vertex_br[1] - vertex_tl[1]) - + vertex_br[0] * (vertex_bl[1] - vertex_tr[1]) - + vertex_bl[0] * (vertex_tl[1] - vertex_br[1])); - - /* Set the clip planes to form lines between all of the vertices - using the same orientation as we calculated */ - if (signed_area > 0.0f) - { - /* counter-clockwise */ - set_clip_plane (framebuffer, GL_CLIP_PLANE0, vertex_tl, vertex_bl); - set_clip_plane (framebuffer, GL_CLIP_PLANE1, vertex_bl, vertex_br); - set_clip_plane (framebuffer, GL_CLIP_PLANE2, vertex_br, vertex_tr); - set_clip_plane (framebuffer, GL_CLIP_PLANE3, vertex_tr, vertex_tl); - } - else - { - /* clockwise */ - set_clip_plane (framebuffer, GL_CLIP_PLANE0, vertex_tl, vertex_tr); - set_clip_plane (framebuffer, GL_CLIP_PLANE1, vertex_tr, vertex_br); - set_clip_plane (framebuffer, GL_CLIP_PLANE2, vertex_br, vertex_bl); - set_clip_plane (framebuffer, GL_CLIP_PLANE3, vertex_bl, vertex_tl); - } -} - static void add_stencil_clip_rectangle (CoglFramebuffer *framebuffer, CoglMatrixEntry *modelview_entry, @@ -208,60 +57,194 @@ add_stencil_clip_rectangle (CoglFramebuffer *framebuffer, float y_1, float x_2, float y_2, - CoglBool first) + gboolean merge) { CoglMatrixStack *projection_stack = _cogl_framebuffer_get_projection_stack (framebuffer); CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); + CoglMatrixEntry *old_projection_entry, *old_modelview_entry; /* NB: This can be called while flushing the journal so we need * to be very conservative with what state we change. */ + old_projection_entry = g_steal_pointer (&ctx->current_projection_entry); + old_modelview_entry = g_steal_pointer (&ctx->current_modelview_entry); - _cogl_context_set_current_projection_entry (ctx, - projection_stack->last_entry); - _cogl_context_set_current_modelview_entry (ctx, modelview_entry); + ctx->current_projection_entry = projection_stack->last_entry; + ctx->current_modelview_entry = modelview_entry; - if (first) + GE( ctx, glColorMask (FALSE, FALSE, FALSE, FALSE) ); + GE( ctx, glDepthMask (FALSE) ); + + if (merge) + { + /* Add one to every pixel of the stencil buffer in the + rectangle */ + GE( ctx, glStencilFunc (GL_NEVER, 0x1, 0x3) ); + GE( ctx, glStencilOp (GL_INCR, GL_INCR, GL_INCR) ); + _cogl_rectangle_immediate (framebuffer, + ctx->stencil_pipeline, + x_1, y_1, x_2, y_2); + + /* Subtract one from all pixels in the stencil buffer so that + only pixels where both the original stencil buffer and the + rectangle are set will be valid */ + GE( ctx, glStencilOp (GL_DECR, GL_DECR, GL_DECR) ); + + ctx->current_projection_entry = &ctx->identity_entry; + ctx->current_modelview_entry = &ctx->identity_entry; + + _cogl_rectangle_immediate (framebuffer, + ctx->stencil_pipeline, + -1.0, -1.0, 1.0, 1.0); + } + else { GE( ctx, glEnable (GL_STENCIL_TEST) ); + GE( ctx, glStencilMask (0x1) ); /* Initially disallow everything */ GE( ctx, glClearStencil (0) ); GE( ctx, glClear (GL_STENCIL_BUFFER_BIT) ); /* Punch out a hole to allow the rectangle */ - GE( ctx, glStencilFunc (GL_NEVER, 0x1, 0x1) ); - GE( ctx, glStencilOp (GL_REPLACE, GL_REPLACE, GL_REPLACE) ); - + GE( ctx, glStencilFunc (GL_ALWAYS, 0x1, 0x1) ); + GE( ctx, glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE) ); _cogl_rectangle_immediate (framebuffer, ctx->stencil_pipeline, x_1, y_1, x_2, y_2); } + + ctx->current_projection_entry = old_projection_entry; + ctx->current_modelview_entry = old_modelview_entry; + + /* Restore the stencil mode */ + GE( ctx, glDepthMask (TRUE) ); + GE( ctx, glColorMask (TRUE, TRUE, TRUE, TRUE) ); + GE( ctx, glStencilFunc (GL_EQUAL, 0x1, 0x1) ); + GE( ctx, glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP) ); +} + +static void +add_stencil_clip_region (CoglFramebuffer *framebuffer, + cairo_region_t *region, + gboolean merge) +{ + CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); + CoglMatrixEntry *old_projection_entry, *old_modelview_entry; + CoglMatrix matrix; + int num_rectangles = cairo_region_num_rectangles (region); + int i; + CoglVertexP2 *vertices; + + /* NB: This can be called while flushing the journal so we need + * to be very conservative with what state we change. + */ + old_projection_entry = g_steal_pointer (&ctx->current_projection_entry); + old_modelview_entry = g_steal_pointer (&ctx->current_modelview_entry); + + ctx->current_projection_entry = &ctx->identity_entry; + ctx->current_modelview_entry = &ctx->identity_entry; + + /* The coordinates in the region are meant to be window coordinates, + * make a matrix that translates those across the viewport, and into + * the default [-1, -1, 1, 1] range. + */ + cogl_matrix_init_identity (&matrix); + cogl_matrix_translate (&matrix, -1, 1, 0); + cogl_matrix_scale (&matrix, + 2.0 / framebuffer->viewport_width, + - 2.0 / framebuffer->viewport_height, + 1); + cogl_matrix_translate (&matrix, + - framebuffer->viewport_x, + - framebuffer->viewport_y, + 0); + + GE( ctx, glColorMask (FALSE, FALSE, FALSE, FALSE) ); + GE( ctx, glDepthMask (FALSE) ); + + if (merge) + { + GE( ctx, glStencilFunc (GL_ALWAYS, 0x1, 0x3) ); + GE( ctx, glStencilOp (GL_KEEP, GL_KEEP, GL_INCR) ); + } else { - /* Add one to every pixel of the stencil buffer in the - rectangle */ - GE( ctx, glStencilFunc (GL_NEVER, 0x1, 0x3) ); - GE( ctx, glStencilOp (GL_INCR, GL_INCR, GL_INCR) ); - _cogl_rectangle_immediate (framebuffer, - ctx->stencil_pipeline, - x_1, y_1, x_2, y_2); + GE( ctx, glEnable (GL_STENCIL_TEST) ); + GE( ctx, glStencilMask (0x1) ); - /* Subtract one from all pixels in the stencil buffer so that - only pixels where both the original stencil buffer and the - rectangle are set will be valid */ - GE( ctx, glStencilOp (GL_DECR, GL_DECR, GL_DECR) ); + /* Initially disallow everything */ + GE( ctx, glClearStencil (0) ); + GE( ctx, glClear (GL_STENCIL_BUFFER_BIT) ); - _cogl_context_set_current_projection_entry (ctx, &ctx->identity_entry); - _cogl_context_set_current_modelview_entry (ctx, &ctx->identity_entry); + /* Punch out holes to allow the rectangles */ + GE( ctx, glStencilFunc (GL_ALWAYS, 0x1, 0x1) ); + GE( ctx, glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE) ); + } + + vertices = g_alloca (sizeof (CoglVertexP2) * num_rectangles * 6); + for (i = 0; i < num_rectangles; i++) + { + cairo_rectangle_int_t rect; + float x1, y1, z1, w1; + float x2, y2, z2, w2; + CoglVertexP2 *v = vertices + i * 6; + + cairo_region_get_rectangle (region, i, &rect); + + x1 = rect.x; + y1 = rect.y; + z1 = 0.f; + w1 = 1.f; + + x2 = rect.x + rect.width; + y2 = rect.y + rect.height; + z2 = 0.f; + w2 = 1.f; + + cogl_matrix_transform_point (&matrix, &x1, &y1, &z1, &w1); + cogl_matrix_transform_point (&matrix, &x2, &y2, &z2, &w2); + + v[0].x = x1; + v[0].y = y1; + v[1].x = x1; + v[1].y = y2; + v[2].x = x2; + v[2].y = y1; + v[3].x = x1; + v[3].y = y2; + v[4].x = x2; + v[4].y = y2; + v[5].x = x2; + v[5].y = y1; + } + + cogl_2d_primitives_immediate (framebuffer, + ctx->stencil_pipeline, + COGL_VERTICES_MODE_TRIANGLES, + vertices, + 6 * num_rectangles); + + if (merge) + { + /* Subtract one from all pixels in the stencil buffer so that + * only pixels where both the original stencil buffer and the + * region are set will be valid + */ + GE( ctx, glStencilOp (GL_KEEP, GL_KEEP, GL_DECR) ); _cogl_rectangle_immediate (framebuffer, ctx->stencil_pipeline, -1.0, -1.0, 1.0, 1.0); } + ctx->current_projection_entry = old_projection_entry; + ctx->current_modelview_entry = old_modelview_entry; + /* Restore the stencil mode */ + GE (ctx, glDepthMask (TRUE)); + GE (ctx, glColorMask (TRUE, TRUE, TRUE, TRUE)); GE( ctx, glStencilFunc (GL_EQUAL, 0x1, 0x1) ); GE( ctx, glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP) ); } @@ -278,21 +261,23 @@ add_stencil_clip_silhouette (CoglFramebuffer *framebuffer, float bounds_y1, float bounds_x2, float bounds_y2, - CoglBool merge, - CoglBool need_clear, + gboolean merge, + gboolean need_clear, void *user_data) { CoglMatrixStack *projection_stack = _cogl_framebuffer_get_projection_stack (framebuffer); CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); + CoglMatrixEntry *old_projection_entry, *old_modelview_entry; /* NB: This can be called while flushing the journal so we need * to be very conservative with what state we change. */ + old_projection_entry = g_steal_pointer (&ctx->current_projection_entry); + old_modelview_entry = g_steal_pointer (&ctx->current_modelview_entry); - _cogl_context_set_current_projection_entry (ctx, - projection_stack->last_entry); - _cogl_context_set_current_modelview_entry (ctx, modelview_entry); + ctx->current_projection_entry = projection_stack->last_entry; + ctx->current_modelview_entry = modelview_entry; _cogl_pipeline_flush_gl_state (ctx, ctx->stencil_pipeline, framebuffer, FALSE, FALSE); @@ -350,8 +335,8 @@ add_stencil_clip_silhouette (CoglFramebuffer *framebuffer, /* Decrement all of the bits twice so that only pixels where the value is 3 will remain */ - _cogl_context_set_current_projection_entry (ctx, &ctx->identity_entry); - _cogl_context_set_current_modelview_entry (ctx, &ctx->identity_entry); + ctx->current_projection_entry = &ctx->identity_entry; + ctx->current_modelview_entry = &ctx->identity_entry; _cogl_rectangle_immediate (framebuffer, ctx->stencil_pipeline, -1.0, -1.0, 1.0, 1.0); @@ -359,6 +344,9 @@ add_stencil_clip_silhouette (CoglFramebuffer *framebuffer, -1.0, -1.0, 1.0, 1.0); } + ctx->current_projection_entry = old_projection_entry; + ctx->current_modelview_entry = old_modelview_entry; + GE (ctx, glStencilMask (~(GLuint) 0)); GE (ctx, glDepthMask (TRUE)); GE (ctx, glColorMask (TRUE, TRUE, TRUE, TRUE)); @@ -377,8 +365,7 @@ paint_primitive_silhouette (CoglFramebuffer *framebuffer, pipeline, COGL_DRAW_SKIP_JOURNAL_FLUSH | COGL_DRAW_SKIP_PIPELINE_VALIDATION | - COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH | - COGL_DRAW_SKIP_LEGACY_STATE); + COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH); } static void @@ -389,8 +376,8 @@ add_stencil_clip_primitive (CoglFramebuffer *framebuffer, float bounds_y1, float bounds_x2, float bounds_y2, - CoglBool merge, - CoglBool need_clear) + gboolean merge, + gboolean need_clear) { add_stencil_clip_silhouette (framebuffer, paint_primitive_silhouette, @@ -404,32 +391,12 @@ add_stencil_clip_primitive (CoglFramebuffer *framebuffer, primitive); } -static void -enable_clip_planes (CoglContext *ctx) -{ - GE( ctx, glEnable (GL_CLIP_PLANE0) ); - GE( ctx, glEnable (GL_CLIP_PLANE1) ); - GE( ctx, glEnable (GL_CLIP_PLANE2) ); - GE( ctx, glEnable (GL_CLIP_PLANE3) ); -} - -static void -disable_clip_planes (CoglContext *ctx) -{ - GE( ctx, glDisable (GL_CLIP_PLANE3) ); - GE( ctx, glDisable (GL_CLIP_PLANE2) ); - GE( ctx, glDisable (GL_CLIP_PLANE1) ); - GE( ctx, glDisable (GL_CLIP_PLANE0) ); -} - void _cogl_clip_stack_gl_flush (CoglClipStack *stack, CoglFramebuffer *framebuffer) { CoglContext *ctx = framebuffer->context; - int has_clip_planes; - CoglBool using_clip_planes = FALSE; - CoglBool using_stencil_buffer = FALSE; + gboolean using_stencil_buffer = FALSE; int scissor_x0; int scissor_y0; int scissor_x1; @@ -441,12 +408,7 @@ _cogl_clip_stack_gl_flush (CoglClipStack *stack, anything */ if (ctx->current_clip_stack_valid) { - if (ctx->current_clip_stack == stack && - (ctx->needs_viewport_scissor_workaround == FALSE || - (framebuffer->viewport_age == - framebuffer->viewport_age_for_scissor_workaround && - ctx->viewport_scissor_workaround_framebuffer == - framebuffer))) + if (ctx->current_clip_stack == stack) return; _cogl_clip_stack_unref (ctx->current_clip_stack); @@ -455,22 +417,14 @@ _cogl_clip_stack_gl_flush (CoglClipStack *stack, ctx->current_clip_stack_valid = TRUE; ctx->current_clip_stack = _cogl_clip_stack_ref (stack); - has_clip_planes = - _cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_FOUR_CLIP_PLANES); - - if (has_clip_planes) - disable_clip_planes (ctx); GE( ctx, glDisable (GL_STENCIL_TEST) ); /* If the stack is empty then there's nothing else to do - * - * See comment below about ctx->needs_viewport_scissor_workaround */ - if (stack == NULL && !ctx->needs_viewport_scissor_workaround) + if (stack == NULL) { COGL_NOTE (CLIPPING, "Flushed empty clip stack"); - ctx->current_clip_stack_uses_stencil = FALSE; GE (ctx, glDisable (GL_SCISSOR_TEST)); return; } @@ -483,31 +437,6 @@ _cogl_clip_stack_gl_flush (CoglClipStack *stack, &scissor_x0, &scissor_y0, &scissor_x1, &scissor_y1); - /* XXX: ONGOING BUG: Intel viewport scissor - * - * Intel gen6 drivers don't correctly handle offset viewports, since - * primitives aren't clipped within the bounds of the viewport. To - * workaround this we push our own clip for the viewport that will - * use scissoring to ensure we clip as expected. - * - * TODO: file a bug upstream! - */ - if (ctx->needs_viewport_scissor_workaround) - { - _cogl_util_scissor_intersect (framebuffer->viewport_x, - framebuffer->viewport_y, - framebuffer->viewport_x + - framebuffer->viewport_width, - framebuffer->viewport_y + - framebuffer->viewport_height, - &scissor_x0, &scissor_y0, - &scissor_x1, &scissor_y1); - framebuffer->viewport_age_for_scissor_workaround = - framebuffer->viewport_age; - ctx->viewport_scissor_workaround_framebuffer = - framebuffer; - } - /* Enable scissoring as soon as possible */ if (scissor_x0 >= scissor_x1 || scissor_y0 >= scissor_y1) scissor_x0 = scissor_y0 = scissor_x1 = scissor_y1 = scissor_y_start = 0; @@ -577,36 +506,33 @@ _cogl_clip_stack_gl_flush (CoglClipStack *stack, rectangle was entirely described by its scissor bounds */ if (!rect->can_be_scissor) { - /* If we support clip planes and we haven't already used - them then use that instead */ - if (has_clip_planes) - { - COGL_NOTE (CLIPPING, - "Adding clip planes clip for rectangle"); - - set_clip_planes (framebuffer, - rect->matrix_entry, - rect->x0, - rect->y0, - rect->x1, - rect->y1); - using_clip_planes = TRUE; - /* We can't use clip planes a second time */ - has_clip_planes = FALSE; - } - else - { - COGL_NOTE (CLIPPING, "Adding stencil clip for rectangle"); - - add_stencil_clip_rectangle (framebuffer, - rect->matrix_entry, - rect->x0, - rect->y0, - rect->x1, - rect->y1, - !using_stencil_buffer); - using_stencil_buffer = TRUE; - } + COGL_NOTE (CLIPPING, "Adding stencil clip for rectangle"); + + add_stencil_clip_rectangle (framebuffer, + rect->matrix_entry, + rect->x0, + rect->y0, + rect->x1, + rect->y1, + using_stencil_buffer); + using_stencil_buffer = TRUE; + } + break; + } + case COGL_CLIP_STACK_REGION: + { + CoglClipStackRegion *region = (CoglClipStackRegion *) entry; + + /* If nrectangles <= 1, it can be fully represented with the + * scissor clip. + */ + if (cairo_region_num_rectangles (region->region) > 1) + { + COGL_NOTE (CLIPPING, "Adding stencil clip for region"); + + add_stencil_clip_region (framebuffer, region->region, + using_stencil_buffer); + using_stencil_buffer = TRUE; } break; } @@ -617,11 +543,4 @@ _cogl_clip_stack_gl_flush (CoglClipStack *stack, * box */ } } - - /* Enabling clip planes is delayed to now so that they won't affect - setting up the stencil buffer */ - if (using_clip_planes) - enable_clip_planes (ctx); - - ctx->current_clip_stack_uses_stencil = using_stencil_buffer; } diff --git a/cogl/cogl/driver/gl/cogl-framebuffer-gl-private.h b/cogl/cogl/driver/gl/cogl-framebuffer-gl-private.h index 47a1c1c96..3e9333a24 100644 --- a/cogl/cogl/driver/gl/cogl-framebuffer-gl-private.h +++ b/cogl/cogl/driver/gl/cogl-framebuffer-gl-private.h @@ -34,9 +34,9 @@ #ifndef __COGL_FRAMEBUFFER_GL_PRIVATE_H__ #define __COGL_FRAMEBUFFER_GL_PRIVATE_H__ -CoglBool +gboolean _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen, - CoglError **error); + GError **error); void _cogl_offscreen_gl_free (CoglOffscreen *offscreen); @@ -61,6 +61,9 @@ _cogl_framebuffer_gl_query_bits (CoglFramebuffer *framebuffer, void _cogl_framebuffer_gl_finish (CoglFramebuffer *framebuffer); +void +_cogl_framebuffer_gl_flush (CoglFramebuffer *framebuffer); + void _cogl_framebuffer_gl_discard_buffers (CoglFramebuffer *framebuffer, unsigned long buffers); @@ -89,13 +92,13 @@ _cogl_framebuffer_gl_draw_indexed_attributes (CoglFramebuffer *framebuffer, int n_attributes, CoglDrawFlags flags); -CoglBool +gboolean _cogl_framebuffer_gl_read_pixels_into_bitmap (CoglFramebuffer *framebuffer, int x, int y, CoglReadPixelsFlags source, CoglBitmap *bitmap, - CoglError **error); + GError **error); #endif /* __COGL_FRAMEBUFFER_GL_PRIVATE_H__ */ diff --git a/cogl/cogl/driver/gl/cogl-framebuffer-gl.c b/cogl/cogl/driver/gl/cogl-framebuffer-gl.c index abff84ee0..e4d215ea2 100644 --- a/cogl/cogl/driver/gl/cogl-framebuffer-gl.c +++ b/cogl/cogl/driver/gl/cogl-framebuffer-gl.c @@ -4,6 +4,7 @@ * A Low Level GPU Graphics and Utilities API * * Copyright (C) 2007,2008,2009,2012 Intel Corporation. + * Copyright (C) 2018 DisplayLink (UK) Ltd. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -28,18 +29,16 @@ * */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-context-private.h" -#include "cogl-util-gl-private.h" #include "cogl-framebuffer-private.h" -#include "cogl-framebuffer-gl-private.h" -#include "cogl-buffer-gl-private.h" -#include "cogl-error-private.h" -#include "cogl-texture-gl-private.h" #include "cogl-texture-private.h" +#include "driver/gl/cogl-util-gl-private.h" +#include "driver/gl/cogl-framebuffer-gl-private.h" +#include "driver/gl/cogl-bitmap-gl-private.h" +#include "driver/gl/cogl-buffer-gl-private.h" +#include "driver/gl/cogl-texture-gl-private.h" #include #include @@ -107,6 +106,9 @@ #ifndef GL_PACK_INVERT_MESA #define GL_PACK_INVERT_MESA 0x8758 #endif +#ifndef GL_PACK_REVERSE_ROW_ORDER_ANGLE +#define GL_PACK_REVERSE_ROW_ORDER_ANGLE 0x93A4 +#endif #ifndef GL_BACK_LEFT #define GL_BACK_LEFT 0x0402 #endif @@ -130,8 +132,8 @@ _cogl_framebuffer_gl_flush_viewport_state (CoglFramebuffer *framebuffer) { float gl_viewport_y; - g_assert (framebuffer->viewport_width >=0 && - framebuffer->viewport_height >=0); + g_return_if_fail (framebuffer->viewport_width >= 0); + g_return_if_fail (framebuffer->viewport_height >= 0); /* Convert the Cogl viewport y offset to an OpenGL viewport y offset * NB: OpenGL defines its window and viewport origins to be bottom @@ -196,20 +198,6 @@ _cogl_framebuffer_gl_flush_projection_state (CoglFramebuffer *framebuffer) projection_entry); } -static void -_cogl_framebuffer_gl_flush_color_mask_state (CoglFramebuffer *framebuffer) -{ - CoglContext *context = framebuffer->context; - - /* The color mask state is really owned by a CoglPipeline so to - * ensure the color mask is updated the next time we draw something - * we need to make sure the logic ops for the pipeline are - * re-flushed... */ - context->current_pipeline_changes_since_flush |= - COGL_PIPELINE_STATE_LOGIC_OPS; - context->current_pipeline_age--; -} - static void _cogl_framebuffer_gl_flush_front_face_winding_state (CoglFramebuffer *framebuffer) { @@ -294,9 +282,7 @@ _cogl_framebuffer_gl_bind (CoglFramebuffer *framebuffer, GLenum target) const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer); winsys->onscreen_bind (COGL_ONSCREEN (framebuffer)); - /* glBindFramebuffer is an an extension with OpenGL ES 1.1 */ - if (cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN)) - GE (ctx, glBindFramebuffer (target, 0)); + GE (ctx, glBindFramebuffer (target, 0)); /* Initialise the glDrawBuffer state the first time the context * is bound to the default framebuffer. If the winsys is using a @@ -401,12 +387,9 @@ _cogl_framebuffer_gl_flush_state (CoglFramebuffer *draw_buffer, else { /* NB: Currently we only take advantage of binding separate - * read/write buffers for offscreen framebuffer blit - * purposes. */ - _COGL_RETURN_IF_FAIL (_cogl_has_private_feature - (ctx, COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT)); - _COGL_RETURN_IF_FAIL (draw_buffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN); - _COGL_RETURN_IF_FAIL (read_buffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN); + * read/write buffers for framebuffer blit purposes. */ + g_return_if_fail (_cogl_has_private_feature + (ctx, COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER)); _cogl_framebuffer_gl_bind (draw_buffer, GL_DRAW_FRAMEBUFFER); _cogl_framebuffer_gl_bind (read_buffer, GL_READ_FRAMEBUFFER); @@ -438,9 +421,6 @@ _cogl_framebuffer_gl_flush_state (CoglFramebuffer *draw_buffer, case COGL_FRAMEBUFFER_STATE_INDEX_PROJECTION: _cogl_framebuffer_gl_flush_projection_state (draw_buffer); break; - case COGL_FRAMEBUFFER_STATE_INDEX_COLOR_MASK: - _cogl_framebuffer_gl_flush_color_mask_state (draw_buffer); - break; case COGL_FRAMEBUFFER_STATE_INDEX_FRONT_FACE_WINDING: _cogl_framebuffer_gl_flush_front_face_winding_state (draw_buffer); break; @@ -461,20 +441,6 @@ _cogl_framebuffer_gl_flush_state (CoglFramebuffer *draw_buffer, ctx->current_draw_buffer_changes &= ~state; } -static CoglTexture * -create_depth_texture (CoglContext *ctx, - int width, - int height) -{ - CoglTexture2D *depth_texture = - cogl_texture_2d_new_with_size (ctx, width, height); - - cogl_texture_set_components (COGL_TEXTURE (depth_texture), - COGL_TEXTURE_COMPONENTS_DEPTH); - - return COGL_TEXTURE (depth_texture); -} - static CoglTexture * attach_depth_texture (CoglContext *ctx, CoglTexture *depth_texture, @@ -537,9 +503,6 @@ try_creating_renderbuffers (CoglContext *ctx, /* WebGL adds a GL_DEPTH_STENCIL_ATTACHMENT and requires that we * use the GL_DEPTH_STENCIL format. */ -#ifdef HAVE_COGL_WEBGL - format = GL_DEPTH_STENCIL; -#else /* Although GL_OES_packed_depth_stencil is mostly equivalent to * GL_EXT_packed_depth_stencil, one notable difference is that * GL_OES_packed_depth_stencil doesn't allow GL_DEPTH_STENCIL to @@ -550,13 +513,12 @@ try_creating_renderbuffers (CoglContext *ctx, format = GL_DEPTH_STENCIL; else { - _COGL_RETURN_VAL_IF_FAIL ( + g_return_val_if_fail ( _cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL), NULL); format = GL_DEPTH24_STENCIL8; } -#endif /* Create a renderbuffer for depth and stenciling */ GE (ctx, glGenRenderbuffers (1, &gl_depth_stencil_handle)); @@ -572,12 +534,6 @@ try_creating_renderbuffers (CoglContext *ctx, GE (ctx, glBindRenderbuffer (GL_RENDERBUFFER, 0)); -#ifdef HAVE_COGL_WEBGL - GE (ctx, glFramebufferRenderbuffer (GL_FRAMEBUFFER, - GL_DEPTH_STENCIL_ATTACHMENT, - GL_RENDERBUFFER, - gl_depth_stencil_handle)); -#else GE (ctx, glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, @@ -586,7 +542,6 @@ try_creating_renderbuffers (CoglContext *ctx, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, gl_depth_stencil_handle)); -#endif renderbuffers = g_list_prepend (renderbuffers, GUINT_TO_POINTER (gl_depth_stencil_handle)); @@ -661,7 +616,7 @@ delete_renderbuffers (CoglContext *ctx, GList *renderbuffers) * CoglTexture as the given CoglOffscreen. This function shouldn't * modify anything in */ -static CoglBool +static gboolean try_creating_fbo (CoglContext *ctx, CoglTexture *texture, int texture_level, @@ -775,31 +730,9 @@ try_creating_fbo (CoglContext *ctx, return TRUE; } -CoglBool -_cogl_framebuffer_try_creating_gl_fbo (CoglContext *ctx, - CoglTexture *texture, - int texture_level, - int texture_level_width, - int texture_level_height, - CoglTexture *depth_texture, - CoglFramebufferConfig *config, - CoglOffscreenAllocateFlags flags, - CoglGLFramebuffer *gl_framebuffer) -{ - return try_creating_fbo (ctx, - texture, - texture_level, - texture_level_width, - texture_level_height, - depth_texture, - config, - flags, - gl_framebuffer); -} - -CoglBool +gboolean _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen, - CoglError **error) + GError **error) { CoglFramebuffer *fb = COGL_FRAMEBUFFER (offscreen); CoglContext *ctx = fb->context; @@ -808,9 +741,9 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen, int level_width; int level_height; - _COGL_RETURN_VAL_IF_FAIL (offscreen->texture_level < - _cogl_texture_get_n_levels (offscreen->texture), - FALSE); + g_return_val_if_fail (offscreen->texture_level < + _cogl_texture_get_n_levels (offscreen->texture), + FALSE); _cogl_texture_get_level_size (offscreen->texture, offscreen->texture_level, @@ -818,24 +751,6 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen, &level_height, NULL); - if (fb->config.depth_texture_enabled && - offscreen->depth_texture == NULL) - { - offscreen->depth_texture = - create_depth_texture (ctx, - level_width, - level_height); - - if (!cogl_texture_allocate (offscreen->depth_texture, error)) - { - cogl_object_unref (offscreen->depth_texture); - offscreen->depth_texture = NULL; - return FALSE; - } - - _cogl_texture_associate_framebuffer (offscreen->depth_texture, fb); - } - /* XXX: The framebuffer_object spec isn't clear in defining whether attaching * a texture as a renderbuffer with mipmap filtering enabled while the * mipmaps have not been uploaded should result in an incomplete framebuffer @@ -874,12 +789,10 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen, ( /* NB: WebGL introduces a DEPTH_STENCIL_ATTACHMENT and doesn't * need an extension to handle _FLAG_DEPTH_STENCIL */ -#ifndef HAVE_COGL_WEBGL (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL) || _cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL)) && -#endif try_creating_fbo (ctx, offscreen->texture, offscreen->texture_level, @@ -933,7 +846,7 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen, { fb->samples_per_pixel = gl_framebuffer->samples_per_pixel; - if (!offscreen->create_flags & COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL) + if (!(offscreen->create_flags & COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL)) { /* Record that the last set of flags succeeded so that we can try that set first next time */ @@ -950,9 +863,9 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen, } else { - _cogl_set_error (error, COGL_FRAMEBUFFER_ERROR, - COGL_FRAMEBUFFER_ERROR_ALLOCATE, - "Failed to create an OpenGL framebuffer object"); + g_set_error (error, COGL_FRAMEBUFFER_ERROR, + COGL_FRAMEBUFFER_ERROR_ALLOCATE, + "Failed to create an OpenGL framebuffer object"); return FALSE; } } @@ -982,20 +895,6 @@ _cogl_framebuffer_gl_clear (CoglFramebuffer *framebuffer, { GE( ctx, glClearColor (red, green, blue, alpha) ); gl_buffers |= GL_COLOR_BUFFER_BIT; - - if (ctx->current_gl_color_mask != framebuffer->color_mask) - { - CoglColorMask color_mask = framebuffer->color_mask; - GE( ctx, glColorMask (!!(color_mask & COGL_COLOR_MASK_RED), - !!(color_mask & COGL_COLOR_MASK_GREEN), - !!(color_mask & COGL_COLOR_MASK_BLUE), - !!(color_mask & COGL_COLOR_MASK_ALPHA))); - ctx->current_gl_color_mask = color_mask; - /* Make sure the ColorMask is updated when the next primitive is drawn */ - ctx->current_pipeline_changes_since_flush |= - COGL_PIPELINE_STATE_LOGIC_OPS; - ctx->current_pipeline_age--; - } } if (buffers & COGL_BUFFER_BIT_DEPTH) @@ -1132,6 +1031,12 @@ _cogl_framebuffer_gl_finish (CoglFramebuffer *framebuffer) GE (framebuffer->context, glFinish ()); } +void +_cogl_framebuffer_gl_flush (CoglFramebuffer *framebuffer) +{ + GE (framebuffer->context, glFlush ()); +} + void _cogl_framebuffer_gl_discard_buffers (CoglFramebuffer *framebuffer, unsigned long buffers) @@ -1255,103 +1160,13 @@ _cogl_framebuffer_gl_draw_indexed_attributes (CoglFramebuffer *framebuffer, _cogl_buffer_gl_unbind (buffer); } -static CoglBool -mesa_46631_slow_read_pixels_workaround (CoglFramebuffer *framebuffer, - int x, - int y, - CoglReadPixelsFlags source, - CoglBitmap *bitmap, - CoglError **error) -{ - CoglContext *ctx; - CoglPixelFormat format; - CoglBitmap *pbo; - int width; - int height; - CoglBool res; - uint8_t *dst; - const uint8_t *src; - - ctx = cogl_framebuffer_get_context (framebuffer); - - width = cogl_bitmap_get_width (bitmap); - height = cogl_bitmap_get_height (bitmap); - format = cogl_bitmap_get_format (bitmap); - - pbo = cogl_bitmap_new_with_size (ctx, width, height, format); - - /* Read into the pbo. We need to disable the flipping because the - blit fast path in the driver does not work with - GL_PACK_INVERT_MESA is set */ - res = _cogl_framebuffer_read_pixels_into_bitmap (framebuffer, - x, y, - source | - COGL_READ_PIXELS_NO_FLIP, - pbo, - error); - if (!res) - { - cogl_object_unref (pbo); - return FALSE; - } - - /* Copy the pixels back into application's buffer */ - dst = _cogl_bitmap_map (bitmap, - COGL_BUFFER_ACCESS_WRITE, - COGL_BUFFER_MAP_HINT_DISCARD, - error); - if (!dst) - { - cogl_object_unref (pbo); - return FALSE; - } - - src = _cogl_bitmap_map (pbo, - COGL_BUFFER_ACCESS_READ, - 0, /* hints */ - error); - if (src) - { - int src_rowstride = cogl_bitmap_get_rowstride (pbo); - int dst_rowstride = cogl_bitmap_get_rowstride (bitmap); - int to_copy = - _cogl_pixel_format_get_bytes_per_pixel (format) * width; - int y; - - /* If the framebuffer is onscreen we need to flip the - data while copying */ - if (!cogl_is_offscreen (framebuffer)) - { - src += src_rowstride * (height - 1); - src_rowstride = -src_rowstride; - } - - for (y = 0; y < height; y++) - { - memcpy (dst, src, to_copy); - dst += dst_rowstride; - src += src_rowstride; - } - - _cogl_bitmap_unmap (pbo); - } - else - res = FALSE; - - _cogl_bitmap_unmap (bitmap); - - cogl_object_unref (pbo); - - return res; -} - -CoglBool +gboolean _cogl_framebuffer_gl_read_pixels_into_bitmap (CoglFramebuffer *framebuffer, int x, int y, CoglReadPixelsFlags source, CoglBitmap *bitmap, - CoglError **error) + GError **error) { CoglContext *ctx = framebuffer->context; int framebuffer_height = cogl_framebuffer_get_height (framebuffer); @@ -1362,42 +1177,11 @@ _cogl_framebuffer_gl_read_pixels_into_bitmap (CoglFramebuffer *framebuffer, GLenum gl_intformat; GLenum gl_format; GLenum gl_type; - CoglBool pack_invert_set; + GLenum gl_pack_enum = GL_FALSE; + gboolean pack_invert_set; int status = FALSE; - /* Workaround for cases where its faster to read into a temporary - * PBO. This is only worth doing if: - * - * • The GPU is an Intel GPU. In that case there is a known - * fast-path when reading into a PBO that will use the blitter - * instead of the Mesa fallback code. The driver bug will only be - * set if this is the case. - * • We're not already reading into a PBO. - * • The target format is BGRA. The fast-path blit does not get hit - * otherwise. - * • The size of the data is not trivially small. This isn't a - * requirement to hit the fast-path blit but intuitively it feels - * like if the amount of data is too small then the cost of - * allocating a PBO will outweigh the cost of temporarily - * converting the data to floats. - */ - if ((ctx->gpu.driver_bugs & - COGL_GPU_INFO_DRIVER_BUG_MESA_46631_SLOW_READ_PIXELS) && - (width > 8 || height > 8) && - (format & ~COGL_PREMULT_BIT) == COGL_PIXEL_FORMAT_BGRA_8888 && - cogl_bitmap_get_buffer (bitmap) == NULL) - { - CoglError *ignore_error = NULL; - - if (mesa_46631_slow_read_pixels_workaround (framebuffer, - x, y, - source, - bitmap, - &ignore_error)) - return TRUE; - else - cogl_error_free (ignore_error); - } + g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, FALSE); _cogl_framebuffer_flush_state (framebuffer, framebuffer, @@ -1412,12 +1196,11 @@ _cogl_framebuffer_gl_read_pixels_into_bitmap (CoglFramebuffer *framebuffer, if (!cogl_is_offscreen (framebuffer)) y = framebuffer_height - y - height; - required_format = ctx->driver_vtable->pixel_format_to_gl_with_target (ctx, - framebuffer->internal_format, - format, - &gl_intformat, - &gl_format, - &gl_type); + required_format = ctx->driver_vtable->pixel_format_to_gl (ctx, + format, + &gl_intformat, + &gl_format, + &gl_type); /* NB: All offscreen rendering is done upside down so there is no need * to flip in this case... */ @@ -1425,7 +1208,12 @@ _cogl_framebuffer_gl_read_pixels_into_bitmap (CoglFramebuffer *framebuffer, (source & COGL_READ_PIXELS_NO_FLIP) == 0 && !cogl_is_offscreen (framebuffer)) { - GE (ctx, glPixelStorei (GL_PACK_INVERT_MESA, TRUE)); + if (ctx->driver == COGL_DRIVER_GLES2) + gl_pack_enum = GL_PACK_REVERSE_ROW_ORDER_ANGLE; + else + gl_pack_enum = GL_PACK_INVERT_MESA; + + GE (ctx, glPixelStorei (gl_pack_enum, TRUE)); pack_invert_set = TRUE; } else @@ -1451,7 +1239,7 @@ _cogl_framebuffer_gl_read_pixels_into_bitmap (CoglFramebuffer *framebuffer, CoglPixelFormat read_format; int bpp, rowstride; uint8_t *tmp_data; - CoglBool succeeded; + gboolean succeeded; if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_READ_PIXELS_ANY_FORMAT)) @@ -1474,7 +1262,7 @@ _cogl_framebuffer_gl_read_pixels_into_bitmap (CoglFramebuffer *framebuffer, if (!tmp_bmp) goto EXIT; - bpp = _cogl_pixel_format_get_bytes_per_pixel (read_format); + bpp = cogl_pixel_format_get_bytes_per_pixel (read_format, 0); rowstride = cogl_bitmap_get_rowstride (tmp_bmp); ctx->texture_driver->prep_gl_for_pixels_download (ctx, @@ -1508,9 +1296,9 @@ _cogl_framebuffer_gl_read_pixels_into_bitmap (CoglFramebuffer *framebuffer, CoglBitmap *shared_bmp; CoglPixelFormat bmp_format; int bpp, rowstride; - CoglBool succeeded = FALSE; + gboolean succeeded = FALSE; uint8_t *pixels; - CoglError *internal_error = NULL; + GError *internal_error = NULL; rowstride = cogl_bitmap_get_rowstride (bitmap); @@ -1531,7 +1319,7 @@ _cogl_framebuffer_gl_read_pixels_into_bitmap (CoglFramebuffer *framebuffer, else shared_bmp = cogl_object_ref (bitmap); - bpp = _cogl_pixel_format_get_bytes_per_pixel (bmp_format); + bpp = cogl_pixel_format_get_bytes_per_pixel (bmp_format, 0); ctx->texture_driver->prep_gl_for_pixels_download (ctx, rowstride, @@ -1548,7 +1336,7 @@ _cogl_framebuffer_gl_read_pixels_into_bitmap (CoglFramebuffer *framebuffer, if (internal_error) { cogl_object_unref (shared_bmp); - _cogl_propagate_error (error, internal_error); + g_propagate_error (error, internal_error); goto EXIT; } @@ -1619,7 +1407,7 @@ _cogl_framebuffer_gl_read_pixels_into_bitmap (CoglFramebuffer *framebuffer, * to interfere with other Cogl components so all other code can assume that * we leave the pack_invert state off. */ if (pack_invert_set) - GE (ctx, glPixelStorei (GL_PACK_INVERT_MESA, FALSE)); + GE (ctx, glPixelStorei (gl_pack_enum, FALSE)); return status; } diff --git a/cogl/cogl/driver/gl/cogl-pipeline-fragend-fixed.c b/cogl/cogl/driver/gl/cogl-pipeline-fragend-fixed.c deleted file mode 100644 index b529122e4..000000000 --- a/cogl/cogl/driver/gl/cogl-pipeline-fragend-fixed.c +++ /dev/null @@ -1,435 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#ifdef HAVE_CONFIG_H -#include "cogl-config.h" -#endif - -#include "cogl-context-private.h" -#include "cogl-util-gl-private.h" -#include "cogl-pipeline-private.h" -#include "cogl-pipeline-state-private.h" -#include "cogl-pipeline-opengl-private.h" - -#ifdef COGL_PIPELINE_FRAGEND_FIXED - -#include "cogl-context-private.h" -#include "cogl-object-private.h" - -#include "cogl-texture-private.h" -#include "cogl-blend-string.h" -#include "cogl-profile.h" -#include "cogl-program-private.h" - -#include -#include -#include - -#ifndef GL_TEXTURE_RECTANGLE_ARB -#define GL_TEXTURE_RECTANGLE_ARB 0x84F5 -#endif - -const CoglPipelineFragend _cogl_pipeline_fixed_fragend; - -static void -_cogl_disable_texture_unit (int unit_index) -{ - CoglTextureUnit *unit; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - unit = &g_array_index (ctx->texture_units, CoglTextureUnit, unit_index); - - if (unit->enabled_gl_target) - { - _cogl_set_active_texture_unit (unit_index); - GE (ctx, glDisable (unit->enabled_gl_target)); - unit->enabled_gl_target = 0; - } -} - -static int -get_max_texture_units (void) -{ - _COGL_GET_CONTEXT (ctx, 0); - - /* This function is called quite often so we cache the value to - avoid too many GL calls */ - if (ctx->max_texture_units == -1) - { - ctx->max_texture_units = 1; - GE (ctx, glGetIntegerv (GL_MAX_TEXTURE_UNITS, - &ctx->max_texture_units)); - } - - return ctx->max_texture_units; -} - -static void -_cogl_pipeline_fragend_fixed_start (CoglPipeline *pipeline, - int n_layers, - unsigned long pipelines_difference) -{ - _cogl_use_fragment_program (0, COGL_PIPELINE_PROGRAM_TYPE_FIXED); -} - -static void -translate_sources (CoglPipeline *pipeline, - int n_sources, - CoglPipelineCombineSource *source_in, - GLenum *source_out) -{ - int i; - - /* The texture source numbers specified in the layer combine are the - layer numbers so we need to map these to unit indices */ - - for (i = 0; i < n_sources; i++) - switch (source_in[i]) - { - case COGL_PIPELINE_COMBINE_SOURCE_TEXTURE: - source_out[i] = GL_TEXTURE; - break; - - case COGL_PIPELINE_COMBINE_SOURCE_CONSTANT: - source_out[i] = GL_CONSTANT; - break; - - case COGL_PIPELINE_COMBINE_SOURCE_PRIMARY_COLOR: - source_out[i] = GL_PRIMARY_COLOR; - break; - - case COGL_PIPELINE_COMBINE_SOURCE_PREVIOUS: - source_out[i] = GL_PREVIOUS; - break; - - default: - { - int layer_num = source_in[i] - COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0; - CoglPipelineGetLayerFlags flags = COGL_PIPELINE_GET_LAYER_NO_CREATE; - CoglPipelineLayer *layer = - _cogl_pipeline_get_layer_with_flags (pipeline, layer_num, flags); - - if (layer == NULL) - { - static CoglBool warning_seen = FALSE; - if (!warning_seen) - { - g_warning ("The application is trying to use a texture " - "combine with a layer number that does not exist"); - warning_seen = TRUE; - } - source_out[i] = GL_PREVIOUS; - } - else - source_out[i] = (_cogl_pipeline_layer_get_unit_index (layer) + - GL_TEXTURE0); - } - } -} - -static CoglBool -_cogl_pipeline_fragend_fixed_add_layer (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - unsigned long layers_difference) -{ - CoglTextureUnit *unit = - _cogl_get_texture_unit (_cogl_pipeline_layer_get_unit_index (layer)); - int unit_index = unit->index; - int n_rgb_func_args; - int n_alpha_func_args; - - _COGL_GET_CONTEXT (ctx, FALSE); - - /* XXX: Beware that since we are changing the active texture unit we - * must make sure we don't call into other Cogl components that may - * temporarily bind texture objects to query/modify parameters since - * they will end up binding texture unit 1. See - * _cogl_bind_gl_texture_transient for more details. - */ - _cogl_set_active_texture_unit (unit_index); - - if (G_UNLIKELY (unit_index >= get_max_texture_units ())) - { - _cogl_disable_texture_unit (unit_index); - /* TODO: although this isn't considered an error that - * warrants falling back to a different backend we - * should print a warning here. */ - return TRUE; - } - - /* Handle enabling or disabling the right texture type */ - if (layers_difference & COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE) - { - CoglTextureType texture_type = - _cogl_pipeline_layer_get_texture_type (layer); - GLenum gl_target; - - switch (texture_type) - { - case COGL_TEXTURE_TYPE_2D: - gl_target = GL_TEXTURE_2D; - break; - - case COGL_TEXTURE_TYPE_3D: - gl_target = GL_TEXTURE_3D; - break; - - case COGL_TEXTURE_TYPE_RECTANGLE: - gl_target = GL_TEXTURE_RECTANGLE_ARB; - break; - - default: - g_assert_not_reached (); - } - - _cogl_set_active_texture_unit (unit_index); - - /* The common GL code handles binding the right texture so we - just need to handle enabling and disabling it */ - - if (unit->enabled_gl_target != gl_target) - { - /* Disable the previous target if it's still enabled */ - if (unit->enabled_gl_target) - GE (ctx, glDisable (unit->enabled_gl_target)); - - /* Enable the new target */ - if (!G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_TEXTURING))) - { - GE (ctx, glEnable (gl_target)); - unit->enabled_gl_target = gl_target; - } - } - } - else - { - /* Even though there may be no difference between the last flushed - * texture state and the current layers texture state it may be that the - * texture unit has been disabled for some time so we need to assert that - * it's enabled now. - */ - if (!G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_TEXTURING)) && - unit->enabled_gl_target == 0) - { - _cogl_set_active_texture_unit (unit_index); - GE (ctx, glEnable (unit->gl_target)); - unit->enabled_gl_target = unit->gl_target; - } - } - - if (layers_difference & COGL_PIPELINE_LAYER_STATE_COMBINE) - { - CoglPipelineLayer *authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_COMBINE); - CoglPipelineLayerBigState *big_state = authority->big_state; - GLenum sources[3]; - - GE (ctx, glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE)); - - /* Set the combiner functions... */ - GE (ctx, glTexEnvi (GL_TEXTURE_ENV, - GL_COMBINE_RGB, - big_state->texture_combine_rgb_func)); - GE (ctx, glTexEnvi (GL_TEXTURE_ENV, - GL_COMBINE_ALPHA, - big_state->texture_combine_alpha_func)); - - /* - * Setup the function arguments... - */ - - /* For the RGB components... */ - n_rgb_func_args = - _cogl_get_n_args_for_combine_func (big_state->texture_combine_rgb_func); - - translate_sources (pipeline, - n_rgb_func_args, - big_state->texture_combine_rgb_src, - sources); - - GE (ctx, glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_RGB, - sources[0])); - GE (ctx, glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB, - big_state->texture_combine_rgb_op[0])); - if (n_rgb_func_args > 1) - { - GE (ctx, glTexEnvi (GL_TEXTURE_ENV, GL_SRC1_RGB, - sources[1])); - GE (ctx, glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_RGB, - big_state->texture_combine_rgb_op[1])); - } - if (n_rgb_func_args > 2) - { - GE (ctx, glTexEnvi (GL_TEXTURE_ENV, GL_SRC2_RGB, - sources[2])); - GE (ctx, glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND2_RGB, - big_state->texture_combine_rgb_op[2])); - } - - /* For the Alpha component */ - n_alpha_func_args = - _cogl_get_n_args_for_combine_func (big_state->texture_combine_alpha_func); - - translate_sources (pipeline, - n_alpha_func_args, - big_state->texture_combine_alpha_src, - sources); - - GE (ctx, glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_ALPHA, - sources[0])); - GE (ctx, glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, - big_state->texture_combine_alpha_op[0])); - if (n_alpha_func_args > 1) - { - GE (ctx, glTexEnvi (GL_TEXTURE_ENV, GL_SRC1_ALPHA, - sources[1])); - GE (ctx, glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, - big_state->texture_combine_alpha_op[1])); - } - if (n_alpha_func_args > 2) - { - GE (ctx, glTexEnvi (GL_TEXTURE_ENV, GL_SRC2_ALPHA, - sources[2])); - GE (ctx, glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, - big_state->texture_combine_alpha_op[2])); - } - } - - if (layers_difference & COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT) - { - CoglPipelineLayer *authority = - _cogl_pipeline_layer_get_authority - (layer, COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT); - CoglPipelineLayerBigState *big_state = authority->big_state; - - GE (ctx, glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, - big_state->texture_combine_constant)); - } - - return TRUE; -} - -static CoglBool -get_highest_unit_index_cb (CoglPipelineLayer *layer, - void *user_data) -{ - int unit_index = _cogl_pipeline_layer_get_unit_index (layer); - int *highest_index = user_data; - - *highest_index = unit_index; - - return TRUE; -} - -static CoglBool -_cogl_pipeline_fragend_fixed_end (CoglPipeline *pipeline, - unsigned long pipelines_difference) -{ - int highest_unit_index = -1; - int i; - - _COGL_GET_CONTEXT (ctx, FALSE); - - _cogl_pipeline_foreach_layer_internal (pipeline, - get_highest_unit_index_cb, - &highest_unit_index); - - /* Disable additional texture units that may have previously been in use.. */ - for (i = highest_unit_index + 1; i < ctx->texture_units->len; i++) - _cogl_disable_texture_unit (i); - - if (pipelines_difference & COGL_PIPELINE_STATE_FOG) - { - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_FOG); - CoglPipelineFogState *fog_state = &authority->big_state->fog_state; - - if (fog_state->enabled) - { - GLfloat fogColor[4]; - GLenum gl_mode = GL_LINEAR; - - fogColor[0] = cogl_color_get_red_float (&fog_state->color); - fogColor[1] = cogl_color_get_green_float (&fog_state->color); - fogColor[2] = cogl_color_get_blue_float (&fog_state->color); - fogColor[3] = cogl_color_get_alpha_float (&fog_state->color); - - GE (ctx, glEnable (GL_FOG)); - - GE (ctx, glFogfv (GL_FOG_COLOR, fogColor)); - - if (ctx->driver == COGL_DRIVER_GLES1) - switch (fog_state->mode) - { - case COGL_FOG_MODE_LINEAR: - gl_mode = GL_LINEAR; - break; - case COGL_FOG_MODE_EXPONENTIAL: - gl_mode = GL_EXP; - break; - case COGL_FOG_MODE_EXPONENTIAL_SQUARED: - gl_mode = GL_EXP2; - break; - } - /* TODO: support other modes for GLES2 */ - - /* NB: GLES doesn't have glFogi */ - GE (ctx, glFogf (GL_FOG_MODE, gl_mode)); - GE (ctx, glHint (GL_FOG_HINT, GL_NICEST)); - - GE (ctx, glFogf (GL_FOG_DENSITY, fog_state->density)); - GE (ctx, glFogf (GL_FOG_START, fog_state->z_near)); - GE (ctx, glFogf (GL_FOG_END, fog_state->z_far)); - } - else - GE (ctx, glDisable (GL_FOG)); - } - - return TRUE; -} - -const CoglPipelineFragend _cogl_pipeline_fixed_fragend = -{ - _cogl_pipeline_fragend_fixed_start, - _cogl_pipeline_fragend_fixed_add_layer, - NULL, /* passthrough */ - _cogl_pipeline_fragend_fixed_end, - NULL, /* pipeline_change_notify */ - NULL, /* pipeline_set_parent_notify */ - NULL, /* layer_change_notify */ -}; - -#endif /* COGL_PIPELINE_FRAGEND_FIXED */ - diff --git a/cogl/cogl/driver/gl/cogl-pipeline-fragend-glsl.c b/cogl/cogl/driver/gl/cogl-pipeline-fragend-glsl.c index b9451dc84..0e95fb390 100644 --- a/cogl/cogl/driver/gl/cogl-pipeline-fragend-glsl.c +++ b/cogl/cogl/driver/gl/cogl-pipeline-fragend-glsl.c @@ -32,29 +32,25 @@ * Neil Roberts */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include #include "cogl-context-private.h" -#include "cogl-util-gl-private.h" #include "cogl-pipeline-private.h" #include "cogl-pipeline-layer-private.h" #include "cogl-blend-string.h" #include "cogl-snippet-private.h" #include "cogl-list.h" - -#ifdef COGL_PIPELINE_FRAGEND_GLSL +#include "driver/gl/cogl-util-gl-private.h" #include "cogl-context-private.h" #include "cogl-object-private.h" -#include "cogl-shader-private.h" -#include "cogl-program-private.h" #include "cogl-pipeline-cache.h" -#include "cogl-pipeline-fragend-glsl-private.h" #include "cogl-glsl-shader-private.h" +#include "driver/gl/cogl-pipeline-fragend-glsl-private.h" +#include "deprecated/cogl-shader-private.h" +#include "deprecated/cogl-program-private.h" #include @@ -148,7 +144,7 @@ destroy_shader_state (void *user_data, if (shader_state->gl_shader) GE( ctx, glDeleteShader (shader_state->gl_shader) ); - free (shader_state->unit_state); + g_free (shader_state->unit_state); g_slice_free (CoglPipelineShaderState, shader_state); } @@ -213,7 +209,7 @@ get_layer_fragment_snippets (CoglPipelineLayer *layer) return &layer->big_state->fragment_snippets; } -static CoglBool +static gboolean has_replace_hook (CoglPipelineLayer *layer, CoglSnippetHook hook) { @@ -230,20 +226,14 @@ has_replace_hook (CoglPipelineLayer *layer, return FALSE; } -static CoglBool +static gboolean add_layer_declaration_cb (CoglPipelineLayer *layer, void *user_data) { CoglPipelineShaderState *shader_state = user_data; - CoglTextureType texture_type = - _cogl_pipeline_layer_get_texture_type (layer); - const char *target_string; - - _cogl_gl_util_get_texture_target_string (texture_type, &target_string, NULL); g_string_append_printf (shader_state->header, - "uniform sampler%s cogl_sampler%i;\n", - target_string, + "uniform sampler2D cogl_sampler%i;\n", layer->index); return TRUE; @@ -413,20 +403,12 @@ ensure_texture_lookup_generated (CoglPipelineShaderState *shader_state, { int unit_index = _cogl_pipeline_layer_get_unit_index (layer); CoglPipelineSnippetData snippet_data; - CoglTextureType texture_type; - const char *target_string, *tex_coord_swizzle; _COGL_GET_CONTEXT (ctx, NO_RETVAL); if (shader_state->unit_state[unit_index].sampled) return; - texture_type = - _cogl_pipeline_layer_get_texture_type (layer); - _cogl_gl_util_get_texture_target_string (texture_type, - &target_string, - &tex_coord_swizzle); - shader_state->unit_state[unit_index].sampled = TRUE; g_string_append_printf (shader_state->header, @@ -457,20 +439,18 @@ ensure_texture_lookup_generated (CoglPipelineShaderState *shader_state, { g_string_append_printf (shader_state->header, "vec4\n" - "cogl_real_texture_lookup%i (sampler%s tex,\n" + "cogl_real_texture_lookup%i (sampler2D tex,\n" " vec4 coords)\n" "{\n" " return ", - layer->index, - target_string); + layer->index); if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_TEXTURING))) g_string_append (shader_state->header, "vec4 (1.0, 1.0, 1.0, 1.0);\n"); else - g_string_append_printf (shader_state->header, - "texture%s (tex, coords.%s);\n", - target_string, tex_coord_swizzle); + g_string_append (shader_state->header, + "texture2D (tex, coords.st);\n"); g_string_append (shader_state->header, "}\n"); } @@ -489,16 +469,15 @@ ensure_texture_lookup_generated (CoglPipelineShaderState *shader_state, snippet_data.return_variable = "cogl_texel"; snippet_data.arguments = "cogl_sampler, cogl_tex_coord"; snippet_data.argument_declarations = - g_strdup_printf ("sampler%s cogl_sampler, vec4 cogl_tex_coord", - target_string); + g_strdup ("sampler2D cogl_sampler, vec4 cogl_tex_coord"); snippet_data.source_buf = shader_state->header; _cogl_pipeline_snippet_generate_code (&snippet_data); - free ((char *) snippet_data.chain_function); - free ((char *) snippet_data.final_name); - free ((char *) snippet_data.function_prefix); - free ((char *) snippet_data.argument_declarations); + g_free ((char *) snippet_data.chain_function); + g_free ((char *) snippet_data.final_name); + g_free ((char *) snippet_data.function_prefix); + g_free ((char *) snippet_data.argument_declarations); } static void @@ -569,7 +548,7 @@ add_arg (CoglPipelineShaderState *shader_state, if (other_layer == NULL) { - static CoglBool warning_seen = FALSE; + static gboolean warning_seen = FALSE; if (!warning_seen) { g_warning ("The application is trying to use a texture " @@ -881,9 +860,9 @@ ensure_layer_generated (CoglPipeline *pipeline, _cogl_pipeline_snippet_generate_code (&snippet_data); - free ((char *) snippet_data.chain_function); - free ((char *) snippet_data.final_name); - free ((char *) snippet_data.function_prefix); + g_free ((char *) snippet_data.chain_function); + g_free ((char *) snippet_data.final_name); + g_free ((char *) snippet_data.function_prefix); g_string_append_printf (shader_state->source, " cogl_layer%i = cogl_generate_layer%i ();\n", @@ -893,7 +872,7 @@ ensure_layer_generated (CoglPipeline *pipeline, g_slice_free (LayerData, layer_data); } -static CoglBool +static gboolean _cogl_pipeline_fragend_glsl_add_layer (CoglPipeline *pipeline, CoglPipelineLayer *layer, unsigned long layers_difference) @@ -991,7 +970,7 @@ add_alpha_test_snippet (CoglPipeline *pipeline, #endif /* HAVE_COGL_GLES2 */ -static CoglBool +static gboolean _cogl_pipeline_fragend_glsl_end (CoglPipeline *pipeline, unsigned long pipelines_difference) { @@ -1043,10 +1022,7 @@ _cogl_pipeline_fragend_glsl_end (CoglPipeline *pipeline, g_string_append (shader_state->source, " cogl_color_out = cogl_color_in;\n"); -#if defined(HAVE_COGL_GLES2) || defined (HAVE_COGL_GL) - if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_ALPHA_TEST)) - add_alpha_test_snippet (pipeline, shader_state); -#endif + add_alpha_test_snippet (pipeline, shader_state); /* Close the function surrounding the generated fragment processing */ g_string_append (shader_state->source, "}\n"); @@ -1138,12 +1114,7 @@ const CoglPipelineFragend _cogl_pipeline_glsl_fragend = { _cogl_pipeline_fragend_glsl_start, _cogl_pipeline_fragend_glsl_add_layer, - NULL, /* passthrough */ _cogl_pipeline_fragend_glsl_end, _cogl_pipeline_fragend_glsl_pre_change_notify, - NULL, /* pipeline_set_parent_notify */ _cogl_pipeline_fragend_glsl_layer_pre_change_notify }; - -#endif /* COGL_PIPELINE_FRAGEND_GLSL */ - diff --git a/cogl/cogl/driver/gl/cogl-pipeline-opengl-private.h b/cogl/cogl/driver/gl/cogl-pipeline-opengl-private.h index 0a374be49..afcb4460e 100644 --- a/cogl/cogl/driver/gl/cogl-pipeline-opengl-private.h +++ b/cogl/cogl/driver/gl/cogl-pipeline-opengl-private.h @@ -71,13 +71,6 @@ typedef struct _CoglTextureUnit * dirty_gl_texture == TRUE */ GLenum gl_target; - /* Foreign textures are those not created or deleted by Cogl. If we ever - * call glBindTexture for a foreign texture then the next time we are - * asked to glBindTexture we can't try and optimize a redundant state - * change because we don't know if the original texture name was deleted - * and now we are being asked to bind a recycled name. */ - CoglBool is_foreign; - /* We have many components in Cogl that need to temporarily bind arbitrary * textures e.g. to query texture object parameters and since we don't * want that to result in too much redundant reflushing of layer state @@ -89,7 +82,7 @@ typedef struct _CoglTextureUnit * of always using texture unit 1 for these transient bindings so we * can assume this is only ever TRUE for unit 1. */ - CoglBool dirty_gl_texture; + gboolean dirty_gl_texture; /* A matrix stack giving us the means to associate a texture * transform matrix with the texture unit. */ @@ -126,7 +119,7 @@ typedef struct _CoglTextureUnit * too. When we later come to flush some pipeline state then we will * always check this to potentially force an update of the texture * state even if the pipeline hasn't changed. */ - CoglBool texture_storage_changed; + gboolean texture_storage_changed; } CoglTextureUnit; @@ -134,15 +127,14 @@ CoglTextureUnit * _cogl_get_texture_unit (int index_); void -_cogl_destroy_texture_units (void); +_cogl_destroy_texture_units (CoglContext *ctx); void _cogl_set_active_texture_unit (int unit_index); void _cogl_bind_gl_texture_transient (GLenum gl_target, - GLuint gl_texture, - CoglBool is_foreign); + GLuint gl_texture); void _cogl_delete_gl_texture (GLuint gl_texture); @@ -151,8 +143,8 @@ void _cogl_pipeline_flush_gl_state (CoglContext *context, CoglPipeline *pipeline, CoglFramebuffer *framebuffer, - CoglBool skip_gl_state, - CoglBool unknown_color_alpha); + gboolean skip_gl_state, + gboolean unknown_color_alpha); #endif /* __COGL_PIPELINE_OPENGL_PRIVATE_H */ diff --git a/cogl/cogl/driver/gl/cogl-pipeline-opengl.c b/cogl/cogl/driver/gl/cogl-pipeline-opengl.c index 178269646..44a968a2c 100644 --- a/cogl/cogl/driver/gl/cogl-pipeline-opengl.c +++ b/cogl/cogl/driver/gl/cogl-pipeline-opengl.c @@ -34,16 +34,16 @@ #include "cogl-config.h" #include "cogl-debug.h" -#include "cogl-util-gl-private.h" -#include "cogl-pipeline-opengl-private.h" #include "cogl-pipeline-private.h" #include "cogl-context-private.h" #include "cogl-texture-private.h" #include "cogl-framebuffer-private.h" #include "cogl-offscreen.h" -#include "cogl-texture-gl-private.h" +#include "driver/gl/cogl-util-gl-private.h" +#include "driver/gl/cogl-pipeline-opengl-private.h" +#include "driver/gl/cogl-texture-gl-private.h" -#include "cogl-pipeline-progend-glsl-private.h" +#include "driver/gl/cogl-pipeline-progend-glsl-private.h" #include @@ -64,9 +64,6 @@ #ifndef GL_CLAMP_TO_BORDER #define GL_CLAMP_TO_BORDER 0x812d #endif -#ifndef GL_PROGRAM_POINT_SIZE -#define GL_PROGRAM_POINT_SIZE 0x8642 -#endif static void texture_unit_init (CoglContext *ctx, @@ -77,7 +74,6 @@ texture_unit_init (CoglContext *ctx, unit->enabled_gl_target = 0; unit->gl_texture = 0; unit->gl_target = 0; - unit->is_foreign = FALSE; unit->dirty_gl_texture = FALSE; unit->matrix_stack = cogl_matrix_stack_new (ctx); @@ -117,12 +113,10 @@ _cogl_get_texture_unit (int index_) } void -_cogl_destroy_texture_units (void) +_cogl_destroy_texture_units (CoglContext *ctx) { int i; - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - for (i = 0; i < ctx->texture_units->len; i++) { CoglTextureUnit *unit = @@ -166,8 +160,7 @@ _cogl_set_active_texture_unit (int unit_index) */ void _cogl_bind_gl_texture_transient (GLenum gl_target, - GLuint gl_texture, - CoglBool is_foreign) + GLuint gl_texture) { CoglTextureUnit *unit; @@ -183,18 +176,12 @@ _cogl_bind_gl_texture_transient (GLenum gl_target, _cogl_set_active_texture_unit (1); unit = _cogl_get_texture_unit (1); - /* NB: If we have previously bound a foreign texture to this texture - * unit we don't know if that texture has since been deleted and we - * are seeing the texture name recycled */ - if (unit->gl_texture == gl_texture && - !unit->dirty_gl_texture && - !unit->is_foreign) + if (unit->gl_texture == gl_texture && !unit->dirty_gl_texture) return; GE (ctx, glBindTexture (gl_target, gl_texture)); unit->dirty_gl_texture = TRUE; - unit->is_foreign = is_foreign; } void @@ -246,156 +233,9 @@ _cogl_pipeline_texture_storage_change_notify (CoglTexture *texture) } } -static void -set_glsl_program (GLuint gl_program) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (ctx->current_gl_program != gl_program) - { - _cogl_gl_util_clear_gl_errors (ctx); - ctx->glUseProgram (gl_program); - if (_cogl_gl_util_get_error (ctx) == GL_NO_ERROR) - ctx->current_gl_program = gl_program; - else - { - GE( ctx, glUseProgram (0) ); - ctx->current_gl_program = 0; - } - } -} - -void -_cogl_use_fragment_program (GLuint gl_program, CoglPipelineProgramType type) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* If we're changing program type... */ - if (type != ctx->current_fragment_program_type) - { - /* ... disable the old type */ - switch (ctx->current_fragment_program_type) - { - case COGL_PIPELINE_PROGRAM_TYPE_GLSL: - /* If the program contains a vertex shader then we shouldn't - disable it */ - if (ctx->current_vertex_program_type != - COGL_PIPELINE_PROGRAM_TYPE_GLSL) - set_glsl_program (0); - break; - - case COGL_PIPELINE_PROGRAM_TYPE_ARBFP: -#ifdef HAVE_COGL_GL - GE( ctx, glDisable (GL_FRAGMENT_PROGRAM_ARB) ); -#endif - break; - - case COGL_PIPELINE_PROGRAM_TYPE_FIXED: - /* don't need to to anything */ - break; - } - - /* ... and enable the new type */ - switch (type) - { - case COGL_PIPELINE_PROGRAM_TYPE_ARBFP: -#ifdef HAVE_COGL_GL - GE( ctx, glEnable (GL_FRAGMENT_PROGRAM_ARB) ); -#endif - break; - - case COGL_PIPELINE_PROGRAM_TYPE_GLSL: - case COGL_PIPELINE_PROGRAM_TYPE_FIXED: - /* don't need to to anything */ - break; - } - } - - if (type == COGL_PIPELINE_PROGRAM_TYPE_GLSL) - { -#ifdef COGL_PIPELINE_FRAGEND_GLSL - set_glsl_program (gl_program); - -#else - - g_warning ("Unexpected use of GLSL fragend!"); - -#endif /* COGL_PIPELINE_FRAGEND_GLSL */ - } -#ifndef COGL_PIPELINE_FRAGEND_ARBFP - else if (type == COGL_PIPELINE_PROGRAM_TYPE_ARBFP) - g_warning ("Unexpected use of ARBFP fragend!"); -#endif /* COGL_PIPELINE_FRAGEND_ARBFP */ - - ctx->current_fragment_program_type = type; -} - -void -_cogl_use_vertex_program (GLuint gl_program, CoglPipelineProgramType type) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* If we're changing program type... */ - if (type != ctx->current_vertex_program_type) - { - /* ... disable the old type */ - switch (ctx->current_vertex_program_type) - { - case COGL_PIPELINE_PROGRAM_TYPE_GLSL: - /* If the program contains a fragment shader then we shouldn't - disable it */ - if (ctx->current_fragment_program_type != - COGL_PIPELINE_PROGRAM_TYPE_GLSL) - set_glsl_program (0); - break; - - case COGL_PIPELINE_PROGRAM_TYPE_ARBFP: - /* It doesn't make sense to enable ARBfp for the vertex program */ - g_assert_not_reached (); - break; - - case COGL_PIPELINE_PROGRAM_TYPE_FIXED: - /* don't need to to anything */ - break; - } - - /* ... and enable the new type */ - switch (type) - { - case COGL_PIPELINE_PROGRAM_TYPE_ARBFP: - /* It doesn't make sense to enable ARBfp for the vertex program */ - g_assert_not_reached (); - break; - - case COGL_PIPELINE_PROGRAM_TYPE_GLSL: - case COGL_PIPELINE_PROGRAM_TYPE_FIXED: - /* don't need to to anything */ - break; - } - } - - if (type == COGL_PIPELINE_PROGRAM_TYPE_GLSL) - { -#ifdef COGL_PIPELINE_VERTEND_GLSL - set_glsl_program (gl_program); - -#else - - g_warning ("Unexpected use of GLSL vertend!"); - -#endif /* COGL_PIPELINE_VERTEND_GLSL */ - } -#ifndef COGL_PIPELINE_VERTEND_ARBFP - else if (type == COGL_PIPELINE_PROGRAM_TYPE_ARBFP) - g_warning ("Unexpected use of ARBFP vertend!"); -#endif /* COGL_PIPELINE_VERTEND_ARBFP */ - - ctx->current_vertex_program_type = type; -} - #if defined(HAVE_COGL_GLES2) || defined(HAVE_COGL_GL) -static CoglBool +static gboolean blend_factor_uses_constant (GLenum blend_factor) { return (blend_factor == GL_CONSTANT_COLOR || @@ -410,7 +250,7 @@ static void flush_depth_state (CoglContext *ctx, CoglDepthState *depth_state) { - CoglBool depth_writing_enabled = depth_state->write_enabled; + gboolean depth_writing_enabled = depth_state->write_enabled; if (ctx->current_draw_buffer) depth_writing_enabled &= ctx->current_draw_buffer->depth_writing_enabled; @@ -418,7 +258,11 @@ flush_depth_state (CoglContext *ctx, if (ctx->depth_test_enabled_cache != depth_state->test_enabled) { if (depth_state->test_enabled == TRUE) - GE (ctx, glEnable (GL_DEPTH_TEST)); + { + GE (ctx, glEnable (GL_DEPTH_TEST)); + if (ctx->current_draw_buffer) + ctx->current_draw_buffer->depth_buffer_clear_needed = TRUE; + } else GE (ctx, glDisable (GL_DEPTH_TEST)); ctx->depth_test_enabled_cache = depth_state->test_enabled; @@ -438,11 +282,10 @@ flush_depth_state (CoglContext *ctx, ctx->depth_writing_enabled_cache = depth_writing_enabled; } - if (ctx->driver != COGL_DRIVER_GLES1 && - (ctx->depth_range_near_cache != depth_state->range_near || + if ((ctx->depth_range_near_cache != depth_state->range_near || ctx->depth_range_far_cache != depth_state->range_far)) { - if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_EMBEDDED)) + if (ctx->driver == COGL_DRIVER_GLES2) GE (ctx, glDepthRangef (depth_state->range_near, depth_state->range_far)); else @@ -490,28 +333,10 @@ static void _cogl_pipeline_flush_color_blend_alpha_depth_state ( CoglPipeline *pipeline, unsigned long pipelines_difference, - CoglBool with_color_attrib) + gboolean with_color_attrib) { _COGL_GET_CONTEXT (ctx, NO_RETVAL); - /* On GLES2 we'll flush the color later */ - if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_FIXED) && - !with_color_attrib) - { - if ((pipelines_difference & COGL_PIPELINE_STATE_COLOR) || - /* Assume if we were previously told to skip the color, then - * the current color needs updating... */ - ctx->current_pipeline_with_color_attrib) - { - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_COLOR); - GE (ctx, glColor4ub (cogl_color_get_red_byte (&authority->color), - cogl_color_get_green_byte (&authority->color), - cogl_color_get_blue_byte (&authority->color), - cogl_color_get_alpha_byte (&authority->color))); - } - } - if (pipelines_difference & COGL_PIPELINE_STATE_BLEND) { CoglPipeline *authority = @@ -519,102 +344,34 @@ _cogl_pipeline_flush_color_blend_alpha_depth_state ( CoglPipelineBlendState *blend_state = &authority->big_state->blend_state; - /* GLES 1 only has glBlendFunc */ - if (ctx->driver == COGL_DRIVER_GLES1) - { - GE (ctx, glBlendFunc (blend_state->blend_src_factor_rgb, - blend_state->blend_dst_factor_rgb)); - } #if defined(HAVE_COGL_GLES2) || defined(HAVE_COGL_GL) - else + if (blend_factor_uses_constant (blend_state->blend_src_factor_rgb) || + blend_factor_uses_constant (blend_state + ->blend_src_factor_alpha) || + blend_factor_uses_constant (blend_state->blend_dst_factor_rgb) || + blend_factor_uses_constant (blend_state->blend_dst_factor_alpha)) { - if (blend_factor_uses_constant (blend_state->blend_src_factor_rgb) || - blend_factor_uses_constant (blend_state - ->blend_src_factor_alpha) || - blend_factor_uses_constant (blend_state->blend_dst_factor_rgb) || - blend_factor_uses_constant (blend_state->blend_dst_factor_alpha)) - { - float red = - cogl_color_get_red_float (&blend_state->blend_constant); - float green = - cogl_color_get_green_float (&blend_state->blend_constant); - float blue = - cogl_color_get_blue_float (&blend_state->blend_constant); - float alpha = - cogl_color_get_alpha_float (&blend_state->blend_constant); + float red = + cogl_color_get_red_float (&blend_state->blend_constant); + float green = + cogl_color_get_green_float (&blend_state->blend_constant); + float blue = + cogl_color_get_blue_float (&blend_state->blend_constant); + float alpha = + cogl_color_get_alpha_float (&blend_state->blend_constant); - GE (ctx, glBlendColor (red, green, blue, alpha)); - } - - if (ctx->glBlendEquationSeparate && - blend_state->blend_equation_rgb != - blend_state->blend_equation_alpha) - GE (ctx, - glBlendEquationSeparate (blend_state->blend_equation_rgb, - blend_state->blend_equation_alpha)); - else - GE (ctx, glBlendEquation (blend_state->blend_equation_rgb)); - - if (ctx->glBlendFuncSeparate && - (blend_state->blend_src_factor_rgb != - blend_state->blend_src_factor_alpha || - (blend_state->blend_dst_factor_rgb != - blend_state->blend_dst_factor_alpha))) - GE (ctx, glBlendFuncSeparate (blend_state->blend_src_factor_rgb, - blend_state->blend_dst_factor_rgb, - blend_state->blend_src_factor_alpha, - blend_state->blend_dst_factor_alpha)); - else - GE (ctx, glBlendFunc (blend_state->blend_src_factor_rgb, - blend_state->blend_dst_factor_rgb)); + GE (ctx, glBlendColor (red, green, blue, alpha)); } -#endif - } - -#if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES) - if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_ALPHA_TEST)) - { - /* Under GLES2 the alpha function is implemented as part of the - fragment shader */ - if (pipelines_difference & (COGL_PIPELINE_STATE_ALPHA_FUNC | - COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE)) - { - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, - COGL_PIPELINE_STATE_ALPHA_FUNC); - CoglPipelineAlphaFuncState *alpha_state = - &authority->big_state->alpha_state; - - /* NB: Currently the Cogl defines are compatible with the GL ones: */ - GE (ctx, glAlphaFunc (alpha_state->alpha_func, - alpha_state->alpha_func_reference)); - } + GE (ctx, glBlendEquationSeparate (blend_state->blend_equation_rgb, + blend_state->blend_equation_alpha)); - /* Under GLES2 the lighting parameters are implemented as uniforms - in the progend */ - if (pipelines_difference & COGL_PIPELINE_STATE_LIGHTING) - { - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, - COGL_PIPELINE_STATE_LIGHTING); - CoglPipelineLightingState *lighting_state = - &authority->big_state->lighting_state; - - GE (ctx, glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, - lighting_state->ambient)); - GE (ctx, glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, - lighting_state->diffuse)); - GE (ctx, glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, - lighting_state->specular)); - GE (ctx, glMaterialfv (GL_FRONT_AND_BACK, GL_EMISSION, - lighting_state->emission)); - GE (ctx, glMaterialfv (GL_FRONT_AND_BACK, GL_SHININESS, - &lighting_state->shininess)); - } + GE (ctx, glBlendFuncSeparate (blend_state->blend_src_factor_rgb, + blend_state->blend_dst_factor_rgb, + blend_state->blend_src_factor_alpha, + blend_state->blend_dst_factor_alpha)); } - #endif if (pipelines_difference & COGL_PIPELINE_STATE_DEPTH) @@ -626,23 +383,6 @@ _cogl_pipeline_flush_color_blend_alpha_depth_state ( flush_depth_state (ctx, depth_state); } - if (pipelines_difference & COGL_PIPELINE_STATE_LOGIC_OPS) - { - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LOGIC_OPS); - CoglPipelineLogicOpsState *logic_ops_state = &authority->big_state->logic_ops_state; - CoglColorMask color_mask = logic_ops_state->color_mask; - - if (ctx->current_draw_buffer) - color_mask &= ctx->current_draw_buffer->color_mask; - - GE (ctx, glColorMask (!!(color_mask & COGL_COLOR_MASK_RED), - !!(color_mask & COGL_COLOR_MASK_GREEN), - !!(color_mask & COGL_COLOR_MASK_BLUE), - !!(color_mask & COGL_COLOR_MASK_ALPHA))); - ctx->current_gl_color_mask = color_mask; - } - if (pipelines_difference & COGL_PIPELINE_STATE_CULL_FACE) { CoglPipeline *authority = @@ -654,7 +394,7 @@ _cogl_pipeline_flush_color_blend_alpha_depth_state ( GE( ctx, glDisable (GL_CULL_FACE) ); else { - CoglBool invert_winding; + gboolean invert_winding; GE( ctx, glEnable (GL_CULL_FACE) ); @@ -694,21 +434,6 @@ _cogl_pipeline_flush_color_blend_alpha_depth_state ( } } -#ifdef HAVE_COGL_GL - if (_cogl_has_private_feature - (ctx, COGL_PRIVATE_FEATURE_ENABLE_PROGRAM_POINT_SIZE) && - (pipelines_difference & COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE)) - { - unsigned long state = COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE; - CoglPipeline *authority = _cogl_pipeline_get_authority (pipeline, state); - - if (authority->big_state->per_vertex_point_size) - GE( ctx, glEnable (GL_PROGRAM_POINT_SIZE) ); - else - GE( ctx, glDisable (GL_PROGRAM_POINT_SIZE) ); - } -#endif - if (pipeline->real_blend_enable != ctx->gl_blend_enable_cache) { if (pipeline->real_blend_enable) @@ -733,31 +458,20 @@ get_max_activateable_texture_units (void) int i; #ifdef HAVE_COGL_GL - if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_EMBEDDED)) + if (ctx->driver != COGL_DRIVER_GLES2) { - /* GL_MAX_TEXTURE_COORDS is provided for both GLSL and ARBfp. It - defines the number of texture coordinates that can be - uploaded (but doesn't necessarily relate to how many texture - images can be sampled) */ - if (cogl_has_feature (ctx, COGL_FEATURE_ID_GLSL) || - cogl_has_feature (ctx, COGL_FEATURE_ID_ARBFP)) - /* Previously this code subtracted the value by one but there - was no explanation for why it did this and it doesn't seem - to make sense so it has been removed */ - GE (ctx, glGetIntegerv (GL_MAX_TEXTURE_COORDS, - values + n_values++)); - - /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS is defined for GLSL but - not ARBfp */ - if (cogl_has_feature (ctx, COGL_FEATURE_ID_GLSL)) - GE (ctx, glGetIntegerv (GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, - values + n_values++)); + /* GL_MAX_TEXTURE_COORDS defines the number of texture coordinates + * that can be uploaded (but doesn't necessarily relate to how many + * texture images can be sampled) */ + GE (ctx, glGetIntegerv (GL_MAX_TEXTURE_COORDS, values + n_values++)); + + GE (ctx, glGetIntegerv (GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, + values + n_values++)); } #endif /* HAVE_COGL_GL */ #ifdef HAVE_COGL_GLES2 - if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_EMBEDDED) && - _cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_PROGRAMMABLE)) + if (ctx->driver == COGL_DRIVER_GLES2) { GE (ctx, glGetIntegerv (GL_MAX_VERTEX_ATTRIBS, values + n_values)); /* Two of the vertex attribs need to be used for the position @@ -769,8 +483,8 @@ get_max_activateable_texture_units (void) } #endif -#if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES) - if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_FIXED)) +#ifdef HAVE_COGL_GL + if (ctx->driver == COGL_DRIVER_GL) { /* GL_MAX_TEXTURE_UNITS defines the number of units that are usable from the fixed function pipeline, therefore it isn't @@ -802,7 +516,7 @@ typedef struct unsigned long *layer_differences; } CoglPipelineFlushLayerState; -static CoglBool +static gboolean flush_layers_common_gl_state_cb (CoglPipelineLayer *layer, void *user_data) { CoglPipelineFlushLayerState *flush_state = user_data; @@ -818,7 +532,7 @@ flush_layers_common_gl_state_cb (CoglPipelineLayer *layer, void *user_data) */ if (G_UNLIKELY (unit_index >= get_max_activateable_texture_units ())) { - static CoglBool shown_warning = FALSE; + static gboolean shown_warning = FALSE; if (!shown_warning) { @@ -836,18 +550,7 @@ flush_layers_common_gl_state_cb (CoglPipelineLayer *layer, void *user_data) GLenum gl_target; if (texture == NULL) - switch (_cogl_pipeline_layer_get_texture_type (layer)) - { - case COGL_TEXTURE_TYPE_2D: - texture = COGL_TEXTURE (ctx->default_gl_texture_2d_tex); - break; - case COGL_TEXTURE_TYPE_3D: - texture = COGL_TEXTURE (ctx->default_gl_texture_3d_tex); - break; - case COGL_TEXTURE_TYPE_RECTANGLE: - texture = COGL_TEXTURE (ctx->default_gl_texture_rect_tex); - break; - } + texture = COGL_TEXTURE (ctx->default_gl_texture_2d_tex); cogl_texture_get_gl_texture (texture, &gl_texture, @@ -880,7 +583,7 @@ flush_layers_common_gl_state_cb (CoglPipelineLayer *layer, void *user_data) * associated with the texture unit then we can't assume that we * aren't seeing a recycled texture name so we have to bind. */ - if (unit->gl_texture != gl_texture || unit->is_foreign) + if (unit->gl_texture != gl_texture) { if (unit_index == 1) unit->dirty_gl_texture = TRUE; @@ -890,8 +593,6 @@ flush_layers_common_gl_state_cb (CoglPipelineLayer *layer, void *user_data) unit->gl_target = gl_target; } - unit->is_foreign = _cogl_texture_is_foreign (texture); - /* The texture_storage_changed boolean indicates if the * CoglTexture's underlying GL texture storage has changed since * it was flushed to the texture unit. We've just flushed the @@ -909,27 +610,6 @@ flush_layers_common_gl_state_cb (CoglPipelineLayer *layer, void *user_data) GE( ctx, glBindSampler (unit_index, sampler_state->sampler_object) ); } - /* FIXME: If using GLSL the progend we will use gl_PointCoord - * instead of us needing to replace the texture coordinates but at - * this point we can't currently tell if we are using the fixed or - * glsl progend. - */ -#if defined (HAVE_COGL_GLES) || defined (HAVE_COGL_GL) - if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_FIXED) && - (layers_difference & COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS)) - { - CoglPipelineState change = COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS; - CoglPipelineLayer *authority = - _cogl_pipeline_layer_get_authority (layer, change); - CoglPipelineLayerBigState *big_state = authority->big_state; - - _cogl_set_active_texture_unit (unit_index); - - GE (ctx, glTexEnvi (GL_POINT_SPRITE, GL_COORD_REPLACE, - big_state->point_sprite_coords)); - } -#endif - cogl_object_ref (layer); if (unit->layer != NULL) cogl_object_unref (unit->layer); @@ -946,7 +626,7 @@ static void _cogl_pipeline_flush_common_gl_state (CoglPipeline *pipeline, unsigned long pipelines_difference, unsigned long *layer_differences, - CoglBool with_color_attrib) + gboolean with_color_attrib) { CoglPipelineFlushLayerState state; @@ -972,16 +652,15 @@ static void _cogl_pipeline_layer_forward_wrap_modes (CoglPipelineLayer *layer, CoglTexture *texture) { - CoglSamplerCacheWrapMode wrap_mode_s, wrap_mode_t, wrap_mode_p; - GLenum gl_wrap_mode_s, gl_wrap_mode_t, gl_wrap_mode_p; + CoglSamplerCacheWrapMode wrap_mode_s, wrap_mode_t; + GLenum gl_wrap_mode_s, gl_wrap_mode_t; if (texture == NULL) return; _cogl_pipeline_layer_get_wrap_modes (layer, &wrap_mode_s, - &wrap_mode_t, - &wrap_mode_p); + &wrap_mode_t); /* Update the wrap mode on the texture object. The texture backend should cache the value so that it will be a no-op if the object @@ -1004,15 +683,9 @@ _cogl_pipeline_layer_forward_wrap_modes (CoglPipelineLayer *layer, else gl_wrap_mode_t = wrap_mode_t; - if (wrap_mode_p == COGL_SAMPLER_CACHE_WRAP_MODE_AUTOMATIC) - gl_wrap_mode_p = GL_CLAMP_TO_EDGE; - else - gl_wrap_mode_p = wrap_mode_p; - _cogl_texture_gl_flush_legacy_texobj_wrap_modes (texture, gl_wrap_mode_s, - gl_wrap_mode_t, - gl_wrap_mode_p); + gl_wrap_mode_t); } /* OpenGL associates the min/mag filters and repeat modes with the @@ -1061,7 +734,7 @@ typedef struct unsigned long *layer_differences; } CoglPipelineCompareLayersState; -static CoglBool +static gboolean compare_layer_differences_cb (CoglPipelineLayer *layer, void *user_data) { CoglPipelineCompareLayersState *state = user_data; @@ -1102,11 +775,11 @@ typedef struct const CoglPipelineFragend *fragend; CoglPipeline *pipeline; unsigned long *layer_differences; - CoglBool error_adding_layer; - CoglBool added_layer; + gboolean error_adding_layer; + gboolean added_layer; } CoglPipelineAddLayerState; -static CoglBool +static gboolean vertend_add_layer_cb (CoglPipelineLayer *layer, void *user_data) { @@ -1131,7 +804,7 @@ vertend_add_layer_cb (CoglPipelineLayer *layer, return TRUE; } -static CoglBool +static gboolean fragend_add_layer_cb (CoglPipelineLayer *layer, void *user_data) { @@ -1203,20 +876,19 @@ fragend_add_layer_cb (CoglPipelineLayer *layer, * * Currently for textured rectangles we manually calculate the texture * coords for each slice based on the users given coords, but this solution - * isn't ideal, and can't be used with CoglVertexBuffers. + * isn't ideal. */ void _cogl_pipeline_flush_gl_state (CoglContext *ctx, CoglPipeline *pipeline, CoglFramebuffer *framebuffer, - CoglBool with_color_attrib, - CoglBool unknown_color_alpha) + gboolean with_color_attrib, + gboolean unknown_color_alpha) { CoglPipeline *current_pipeline = ctx->current_pipeline; unsigned long pipelines_difference; int n_layers; unsigned long *layer_differences; - int i; CoglTextureUnit *unit1; const CoglPipelineProgend *progend; @@ -1253,7 +925,7 @@ _cogl_pipeline_flush_gl_state (CoglContext *ctx, if (pipelines_difference & COGL_PIPELINE_STATE_AFFECTS_BLENDING || pipeline->unknown_color_alpha != unknown_color_alpha) { - CoglBool save_real_blend_enable = pipeline->real_blend_enable; + gboolean save_real_blend_enable = pipeline->real_blend_enable; _cogl_pipeline_update_real_blend_enable (pipeline, unknown_color_alpha); @@ -1331,23 +1003,19 @@ _cogl_pipeline_flush_gl_state (CoglContext *ctx, * with the given progend so we will simply use that to avoid * fallback code paths. */ - if (pipeline->progend == COGL_PIPELINE_PROGEND_UNDEFINED) - _cogl_pipeline_set_progend (pipeline, COGL_PIPELINE_PROGEND_DEFAULT); - for (i = pipeline->progend; - i < COGL_PIPELINE_N_PROGENDS; - i++, _cogl_pipeline_set_progend (pipeline, i)) + do { const CoglPipelineVertend *vertend; const CoglPipelineFragend *fragend; CoglPipelineAddLayerState state; - progend = _cogl_pipeline_progends[i]; + progend = _cogl_pipeline_progend; if (G_UNLIKELY (!progend->start (pipeline))) continue; - vertend = _cogl_pipeline_vertends[progend->vertend]; + vertend = _cogl_pipeline_vertend; vertend->start (pipeline, n_layers, @@ -1377,7 +1045,7 @@ _cogl_pipeline_flush_gl_state (CoglContext *ctx, * ctx->codegen_source_buffer as a scratch buffer. */ - fragend = _cogl_pipeline_fragends[progend->fragend]; + fragend = _cogl_pipeline_fragend; state.fragend = fragend; fragend->start (pipeline, @@ -1391,13 +1059,6 @@ _cogl_pipeline_flush_gl_state (CoglContext *ctx, if (G_UNLIKELY (state.error_adding_layer)) continue; - if (!state.added_layer) - { - if (fragend->passthrough && - G_UNLIKELY (!fragend->passthrough (pipeline))) - continue; - } - if (G_UNLIKELY (!fragend->end (pipeline, pipelines_difference))) continue; @@ -1405,6 +1066,7 @@ _cogl_pipeline_flush_gl_state (CoglContext *ctx, progend->end (pipeline, pipelines_difference); break; } + while (0); /* FIXME: This reference is actually resulting in lots of * copy-on-write reparenting because one-shot pipelines end up @@ -1425,13 +1087,13 @@ _cogl_pipeline_flush_gl_state (CoglContext *ctx, done: - progend = _cogl_pipeline_progends[pipeline->progend]; + progend = _cogl_pipeline_progend; /* We can't assume the color will be retained between flushes when * using the glsl progend because the generic attribute values are * not stored as part of the program object so they could be * overridden by any attribute changes in another program */ - if (pipeline->progend == COGL_PIPELINE_PROGEND_GLSL && !with_color_attrib) + if (!with_color_attrib) { int attribute; CoglPipeline *authority = diff --git a/cogl/cogl/driver/gl/cogl-pipeline-progend-fixed-private.h b/cogl/cogl/driver/gl/cogl-pipeline-progend-fixed-private.h deleted file mode 100644 index f97e16a99..000000000 --- a/cogl/cogl/driver/gl/cogl-pipeline-progend-fixed-private.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts - */ - -#ifndef __COGL_PIPELINE_PROGEND_FIXED_PRIVATE_H -#define __COGL_PIPELINE_PROGEND_FIXED_PRIVATE_H - -#include "cogl-pipeline-private.h" - -extern const CoglPipelineProgend _cogl_pipeline_fixed_progend; - -#endif /* __COGL_PIPELINE_PROGEND_FIXED_PRIVATE_H */ - diff --git a/cogl/cogl/driver/gl/cogl-pipeline-progend-fixed.c b/cogl/cogl/driver/gl/cogl-pipeline-progend-fixed.c deleted file mode 100644 index 4eb4191f0..000000000 --- a/cogl/cogl/driver/gl/cogl-pipeline-progend-fixed.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts - */ - -#ifdef HAVE_CONFIG_H -#include "cogl-config.h" -#endif - -#include - -#include "cogl-pipeline-private.h" -#include "cogl-pipeline-state-private.h" - -#ifdef COGL_PIPELINE_PROGEND_FIXED - -#include "cogl-context.h" -#include "cogl-context-private.h" -#include "cogl-framebuffer-private.h" - -static CoglBool -_cogl_pipeline_progend_fixed_start (CoglPipeline *pipeline) -{ - _COGL_GET_CONTEXT (ctx, FALSE); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_FIXED))) - return FALSE; - - if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_FIXED)) - return FALSE; - - /* Vertex snippets are only supported in the GLSL fragend */ - if (_cogl_pipeline_has_vertex_snippets (pipeline)) - return FALSE; - - /* Fragment snippets are only supported in the GLSL fragend */ - if (_cogl_pipeline_has_fragment_snippets (pipeline)) - return FALSE; - - /* If there is a user program then the appropriate backend for that - * language should handle it. */ - if (cogl_pipeline_get_user_program (pipeline)) - return FALSE; - - /* The fixed progend can't handle the per-vertex point size - * attribute */ - if (cogl_pipeline_get_per_vertex_point_size (pipeline)) - return FALSE; - - return TRUE; -} - -static void -_cogl_pipeline_progend_fixed_pre_paint (CoglPipeline *pipeline, - CoglFramebuffer *framebuffer) -{ - CoglContext *ctx = framebuffer->context; - - if (ctx->current_projection_entry) - _cogl_matrix_entry_flush_to_gl_builtins (ctx, - ctx->current_projection_entry, - COGL_MATRIX_PROJECTION, - framebuffer, - FALSE /* enable flip */); - if (ctx->current_modelview_entry) - _cogl_matrix_entry_flush_to_gl_builtins (ctx, - ctx->current_modelview_entry, - COGL_MATRIX_MODELVIEW, - framebuffer, - FALSE /* enable flip */); -} - -const CoglPipelineProgend _cogl_pipeline_fixed_progend = - { - COGL_PIPELINE_VERTEND_FIXED, - COGL_PIPELINE_FRAGEND_FIXED, - _cogl_pipeline_progend_fixed_start, - NULL, /* end */ - NULL, /* pre_change_notify */ - NULL, /* layer_pre_change_notify */ - _cogl_pipeline_progend_fixed_pre_paint - }; - -#endif /* COGL_PIPELINE_PROGEND_FIXED */ diff --git a/cogl/cogl/driver/gl/cogl-pipeline-progend-glsl.c b/cogl/cogl/driver/gl/cogl-pipeline-progend-glsl.c index ee0cc2722..3a049a70b 100644 --- a/cogl/cogl/driver/gl/cogl-pipeline-progend-glsl.c +++ b/cogl/cogl/driver/gl/cogl-pipeline-progend-glsl.c @@ -31,31 +31,27 @@ * Neil Roberts */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include #include "cogl-util.h" #include "cogl-context-private.h" -#include "cogl-util-gl-private.h" #include "cogl-pipeline-private.h" -#include "cogl-pipeline-opengl-private.h" #include "cogl-offscreen.h" - -#ifdef COGL_PIPELINE_PROGEND_GLSL +#include "driver/gl/cogl-util-gl-private.h" +#include "driver/gl/cogl-pipeline-opengl-private.h" #include "cogl-context-private.h" #include "cogl-object-private.h" -#include "cogl-program-private.h" -#include "cogl-pipeline-fragend-glsl-private.h" -#include "cogl-pipeline-vertend-glsl-private.h" #include "cogl-pipeline-cache.h" #include "cogl-pipeline-state-private.h" #include "cogl-attribute-private.h" #include "cogl-framebuffer-private.h" -#include "cogl-pipeline-progend-glsl-private.h" +#include "driver/gl/cogl-pipeline-fragend-glsl-private.h" +#include "driver/gl/cogl-pipeline-vertend-glsl-private.h" +#include "driver/gl/cogl-pipeline-progend-glsl-private.h" +#include "deprecated/cogl-program-private.h" /* These are used to generalise updating some uniforms that are required when building for drivers missing some fixed function @@ -75,22 +71,16 @@ typedef struct void *getter_func; UpdateUniformFunc update_func; CoglPipelineState change; - - /* This builtin is only necessary if the following private feature - * is not implemented in the driver */ - CoglPrivateFeature feature_replacement; } BuiltinUniformData; static BuiltinUniformData builtin_uniforms[] = { { "cogl_point_size_in", cogl_pipeline_get_point_size, update_float_uniform, - COGL_PIPELINE_STATE_POINT_SIZE, - COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM }, + COGL_PIPELINE_STATE_POINT_SIZE }, { "_cogl_alpha_test_ref", cogl_pipeline_get_alpha_test_reference, update_float_uniform, - COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE, - COGL_PRIVATE_FEATURE_ALPHA_TEST } + COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE }, }; const CoglPipelineProgend _cogl_pipeline_glsl_progend; @@ -182,8 +172,8 @@ _cogl_pipeline_progend_glsl_get_attrib_location (CoglPipeline *pipeline, _COGL_GET_CONTEXT (ctx, -1); - _COGL_RETURN_VAL_IF_FAIL (program_state != NULL, -1); - _COGL_RETURN_VAL_IF_FAIL (program_state->program != 0, -1); + g_return_val_if_fail (program_state != NULL, -1); + g_return_val_if_fail (program_state->program != 0, -1); if (G_UNLIKELY (program_state->attribute_locations == NULL)) program_state->attribute_locations = @@ -206,7 +196,7 @@ _cogl_pipeline_progend_glsl_get_attrib_location (CoglPipeline *pipeline, g_array_index (ctx->attribute_name_index_map, CoglAttributeNameState *, name_index); - _COGL_RETURN_VAL_IF_FAIL (name_state != NULL, 0); + g_return_val_if_fail (name_state != NULL, 0); GE_RET( locations[name_index], ctx, glGetAttribLocation (program_state->program, @@ -283,7 +273,7 @@ destroy_program_state (void *user_data, if (program_state->program) GE( ctx, glDeleteProgram (program_state->program) ); - free (program_state->unit_state); + g_free (program_state->unit_state); if (program_state->uniform_locations) g_array_free (program_state->uniform_locations, TRUE); @@ -341,7 +331,7 @@ link_program (GLint gl_program) GE( ctx, glGetProgramiv (gl_program, GL_INFO_LOG_LENGTH, &log_length) ); - log = malloc (log_length); + log = g_malloc (log_length); GE( ctx, glGetProgramInfoLog (gl_program, log_length, &out_log_length, log) ); @@ -349,7 +339,7 @@ link_program (GLint gl_program) g_warning ("Failed to link GLSL program:\n%.*s\n", log_length, log); - free (log); + g_free (log); } } @@ -357,11 +347,11 @@ typedef struct { int unit; GLuint gl_program; - CoglBool update_all; + gboolean update_all; CoglPipelineProgramState *program_state; } UpdateUniformsState; -static CoglBool +static gboolean get_uniform_cb (CoglPipeline *pipeline, int layer_index, void *user_data) @@ -415,7 +405,7 @@ get_uniform_cb (CoglPipeline *pipeline, return TRUE; } -static CoglBool +static gboolean update_constants_cb (CoglPipeline *pipeline, int layer_index, void *user_data) @@ -466,9 +456,7 @@ update_builtin_uniforms (CoglContext *context, return; for (i = 0; i < G_N_ELEMENTS (builtin_uniforms); i++) - if (!_cogl_has_private_feature (context, - builtin_uniforms[i].feature_replacement) && - (program_state->dirty_builtin_uniforms & (1 << i)) && + if ((program_state->dirty_builtin_uniforms & (1 << i)) && program_state->builtin_uniform_locations[i] != -1) builtin_uniforms[i].update_func (pipeline, program_state @@ -488,7 +476,7 @@ typedef struct int value_index; } FlushUniformsClosure; -static CoglBool +static gboolean flush_uniform_cb (int uniform_num, void *user_data) { FlushUniformsClosure *data = user_data; @@ -551,7 +539,7 @@ _cogl_pipeline_progend_glsl_flush_uniforms (CoglPipeline *pipeline, CoglPipelineProgramState * program_state, GLuint gl_program, - CoglBool program_changed) + gboolean program_changed) { CoglPipelineUniformsState *uniforms_state; FlushUniformsClosure data; @@ -639,21 +627,9 @@ _cogl_pipeline_progend_glsl_flush_uniforms (CoglPipeline *pipeline, _cogl_bitmask_clear_all (&uniforms_state->changed_mask); } -static CoglBool +static gboolean _cogl_pipeline_progend_glsl_start (CoglPipeline *pipeline) { - CoglHandle user_program; - - _COGL_GET_CONTEXT (ctx, FALSE); - - if (!cogl_has_feature (ctx, COGL_FEATURE_ID_GLSL)) - return FALSE; - - user_program = cogl_pipeline_get_user_program (pipeline); - if (user_program && - _cogl_program_get_language (user_program) != COGL_SHADER_LANGUAGE_GLSL) - return FALSE; - return TRUE; } @@ -663,7 +639,7 @@ _cogl_pipeline_progend_glsl_end (CoglPipeline *pipeline, { CoglPipelineProgramState *program_state; GLuint gl_program; - CoglBool program_changed = FALSE; + gboolean program_changed = FALSE; UpdateUniformsState state; CoglProgram *user_program; CoglPipelineCacheEntry *cache_entry = NULL; @@ -749,8 +725,6 @@ _cogl_pipeline_progend_glsl_end (CoglPipeline *pipeline, _cogl_shader_compile_real (shader, pipeline); - g_assert (shader->language == COGL_SHADER_LANGUAGE_GLSL); - GE( ctx, glAttachShader (program_state->program, shader->gl_handle) ); } @@ -778,8 +752,18 @@ _cogl_pipeline_progend_glsl_end (CoglPipeline *pipeline, gl_program = program_state->program; - _cogl_use_fragment_program (gl_program, COGL_PIPELINE_PROGRAM_TYPE_GLSL); - _cogl_use_vertex_program (gl_program, COGL_PIPELINE_PROGRAM_TYPE_GLSL); + if (ctx->current_gl_program != gl_program) + { + _cogl_gl_util_clear_gl_errors (ctx); + ctx->glUseProgram (gl_program); + if (_cogl_gl_util_get_error (ctx) == GL_NO_ERROR) + ctx->current_gl_program = gl_program; + else + { + GE( ctx, glUseProgram (0) ); + ctx->current_gl_program = 0; + } + } state.unit = 0; state.gl_program = gl_program; @@ -812,11 +796,9 @@ _cogl_pipeline_progend_glsl_end (CoglPipeline *pipeline, clear_flushed_matrix_stacks (program_state); for (i = 0; i < G_N_ELEMENTS (builtin_uniforms); i++) - if (!_cogl_has_private_feature - (ctx, builtin_uniforms[i].feature_replacement)) - GE_RET( program_state->builtin_uniform_locations[i], ctx, - glGetUniformLocation (gl_program, - builtin_uniforms[i].uniform_name) ); + GE_RET( program_state->builtin_uniform_locations[i], ctx, + glGetUniformLocation (gl_program, + builtin_uniforms[i].uniform_name) ); GE_RET( program_state->modelview_uniform, ctx, glGetUniformLocation (gl_program, @@ -869,9 +851,7 @@ _cogl_pipeline_progend_glsl_pre_change_notify (CoglPipeline *pipeline, int i; for (i = 0; i < G_N_ELEMENTS (builtin_uniforms); i++) - if (!_cogl_has_private_feature - (ctx, builtin_uniforms[i].feature_replacement) && - (change & builtin_uniforms[i].change)) + if (change & builtin_uniforms[i].change) { CoglPipelineProgramState *program_state = get_program_state (pipeline); @@ -927,14 +907,14 @@ static void _cogl_pipeline_progend_glsl_pre_paint (CoglPipeline *pipeline, CoglFramebuffer *framebuffer) { - CoglBool needs_flip; + gboolean needs_flip; CoglMatrixEntry *projection_entry; CoglMatrixEntry *modelview_entry; CoglPipelineProgramState *program_state; - CoglBool modelview_changed; - CoglBool projection_changed; - CoglBool need_modelview; - CoglBool need_projection; + gboolean modelview_changed; + gboolean projection_changed; + gboolean need_modelview; + gboolean need_projection; CoglMatrix modelview, projection; _COGL_GET_CONTEXT (ctx, NO_RETVAL); @@ -1062,13 +1042,9 @@ update_float_uniform (CoglPipeline *pipeline, const CoglPipelineProgend _cogl_pipeline_glsl_progend = { - COGL_PIPELINE_VERTEND_GLSL, - COGL_PIPELINE_FRAGEND_GLSL, _cogl_pipeline_progend_glsl_start, _cogl_pipeline_progend_glsl_end, _cogl_pipeline_progend_glsl_pre_change_notify, _cogl_pipeline_progend_glsl_layer_pre_change_notify, _cogl_pipeline_progend_glsl_pre_paint }; - -#endif /* COGL_PIPELINE_PROGEND_GLSL */ diff --git a/cogl/cogl/driver/gl/cogl-pipeline-vertend-fixed-private.h b/cogl/cogl/driver/gl/cogl-pipeline-vertend-fixed-private.h deleted file mode 100644 index 97dee5479..000000000 --- a/cogl/cogl/driver/gl/cogl-pipeline-vertend-fixed-private.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts - */ - -#ifndef __COGL_PIPELINE_VERTEND_FIXED_PRIVATE_H -#define __COGL_PIPELINE_VERTEND_FIXED_PRIVATE_H - -#include "cogl-pipeline-private.h" - -extern const CoglPipelineVertend _cogl_pipeline_fixed_vertend; - -#endif /* __COGL_PIPELINE_VERTEND_FIXED_PRIVATE_H */ - diff --git a/cogl/cogl/driver/gl/cogl-pipeline-vertend-fixed.c b/cogl/cogl/driver/gl/cogl-pipeline-vertend-fixed.c deleted file mode 100644 index eec60d303..000000000 --- a/cogl/cogl/driver/gl/cogl-pipeline-vertend-fixed.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts - */ - -#ifdef HAVE_CONFIG_H -#include "cogl-config.h" -#endif - -#include "cogl-context-private.h" -#include "cogl-util-gl-private.h" -#include "cogl-pipeline-private.h" -#include "cogl-pipeline-state-private.h" -#include "cogl-pipeline-opengl-private.h" -#include "cogl-framebuffer-private.h" - -#ifdef COGL_PIPELINE_VERTEND_FIXED - -#include "cogl-context-private.h" -#include "cogl-object-private.h" -#include "cogl-program-private.h" - -const CoglPipelineVertend _cogl_pipeline_fixed_vertend; - -static void -_cogl_pipeline_vertend_fixed_start (CoglPipeline *pipeline, - int n_layers, - unsigned long pipelines_difference) -{ - _cogl_use_vertex_program (0, COGL_PIPELINE_PROGRAM_TYPE_FIXED); -} - -static CoglBool -_cogl_pipeline_vertend_fixed_add_layer (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - unsigned long layers_difference, - CoglFramebuffer *framebuffer) -{ - CoglContext *ctx = framebuffer->context; - int unit_index = _cogl_pipeline_layer_get_unit_index (layer); - CoglTextureUnit *unit = _cogl_get_texture_unit (unit_index); - - if (layers_difference & COGL_PIPELINE_LAYER_STATE_USER_MATRIX) - { - CoglPipelineLayerState state = COGL_PIPELINE_LAYER_STATE_USER_MATRIX; - CoglPipelineLayer *authority = - _cogl_pipeline_layer_get_authority (layer, state); - CoglMatrixEntry *matrix_entry; - - cogl_matrix_stack_set (unit->matrix_stack, - &authority->big_state->matrix); - - _cogl_set_active_texture_unit (unit_index); - - matrix_entry = unit->matrix_stack->last_entry; - _cogl_matrix_entry_flush_to_gl_builtins (ctx, matrix_entry, - COGL_MATRIX_TEXTURE, - framebuffer, - FALSE /* enable flip */); - } - - return TRUE; -} - -static CoglBool -_cogl_pipeline_vertend_fixed_end (CoglPipeline *pipeline, - unsigned long pipelines_difference) -{ - _COGL_GET_CONTEXT (ctx, FALSE); - - if (pipelines_difference & COGL_PIPELINE_STATE_POINT_SIZE) - { - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_POINT_SIZE); - - if (authority->big_state->point_size > 0.0f) - GE( ctx, glPointSize (authority->big_state->point_size) ); - } - - return TRUE; -} - -const CoglPipelineVertend _cogl_pipeline_fixed_vertend = -{ - _cogl_pipeline_vertend_fixed_start, - _cogl_pipeline_vertend_fixed_add_layer, - _cogl_pipeline_vertend_fixed_end, - NULL, /* pipeline_change_notify */ - NULL /* layer_change_notify */ -}; - -#endif /* COGL_PIPELINE_VERTEND_FIXED */ - diff --git a/cogl/cogl/driver/gl/cogl-pipeline-vertend-glsl.c b/cogl/cogl/driver/gl/cogl-pipeline-vertend-glsl.c index 7dfe40635..c69f50ae8 100644 --- a/cogl/cogl/driver/gl/cogl-pipeline-vertend-glsl.c +++ b/cogl/cogl/driver/gl/cogl-pipeline-vertend-glsl.c @@ -31,27 +31,23 @@ * Neil Roberts */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include #include #include "cogl-context-private.h" -#include "cogl-util-gl-private.h" #include "cogl-pipeline-private.h" -#include "cogl-pipeline-opengl-private.h" - -#ifdef COGL_PIPELINE_VERTEND_GLSL +#include "driver/gl/cogl-util-gl-private.h" +#include "driver/gl/cogl-pipeline-opengl-private.h" #include "cogl-context-private.h" #include "cogl-object-private.h" -#include "cogl-program-private.h" -#include "cogl-pipeline-vertend-glsl-private.h" #include "cogl-pipeline-state-private.h" #include "cogl-glsl-shader-private.h" +#include "driver/gl/cogl-pipeline-vertend-glsl-private.h" +#include "deprecated/cogl-program-private.h" const CoglPipelineVertend _cogl_pipeline_glsl_vertend; @@ -166,20 +162,14 @@ get_layer_vertex_snippets (CoglPipelineLayer *layer) return &layer->big_state->vertex_snippets; } -static CoglBool +static gboolean add_layer_declaration_cb (CoglPipelineLayer *layer, void *user_data) { CoglPipelineShaderState *shader_state = user_data; - CoglTextureType texture_type = - _cogl_pipeline_layer_get_texture_type (layer); - const char *target_string; - - _cogl_gl_util_get_texture_target_string (texture_type, &target_string, NULL); g_string_append_printf (shader_state->header, - "uniform sampler%s cogl_sampler%i;\n", - target_string, + "uniform sampler2D cogl_sampler%i;\n", layer->index); return TRUE; @@ -315,8 +305,7 @@ _cogl_pipeline_vertend_glsl_start (CoglPipeline *pipeline, if (cogl_pipeline_get_per_vertex_point_size (pipeline)) g_string_append (shader_state->header, "attribute float cogl_point_size_in;\n"); - else if (!_cogl_has_private_feature - (ctx, COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM)) + else { /* There is no builtin uniform for the point size on GLES2 so we need to copy it from the custom uniform in the vertex shader @@ -334,7 +323,7 @@ _cogl_pipeline_vertend_glsl_start (CoglPipeline *pipeline, } } -static CoglBool +static gboolean _cogl_pipeline_vertend_glsl_add_layer (CoglPipeline *pipeline, CoglPipelineLayer *layer, unsigned long layers_difference, @@ -390,9 +379,9 @@ _cogl_pipeline_vertend_glsl_add_layer (CoglPipeline *pipeline, _cogl_pipeline_snippet_generate_code (&snippet_data); - free ((char *) snippet_data.chain_function); - free ((char *) snippet_data.final_name); - free ((char *) snippet_data.function_prefix); + g_free ((char *) snippet_data.chain_function); + g_free ((char *) snippet_data.final_name); + g_free ((char *) snippet_data.function_prefix); g_string_append_printf (shader_state->source, " cogl_tex_coord%i_out = " @@ -407,7 +396,7 @@ _cogl_pipeline_vertend_glsl_add_layer (CoglPipeline *pipeline, return TRUE; } -static CoglBool +static gboolean _cogl_pipeline_vertend_glsl_end (CoglPipeline *pipeline, unsigned long pipelines_difference) { @@ -425,7 +414,7 @@ _cogl_pipeline_vertend_glsl_end (CoglPipeline *pipeline, GLuint shader; CoglPipelineSnippetData snippet_data; CoglPipelineSnippetList *vertex_snippets; - CoglBool has_per_vertex_point_size = + gboolean has_per_vertex_point_size = cogl_pipeline_get_per_vertex_point_size (pipeline); COGL_STATIC_COUNTER (vertend_glsl_compile_counter, @@ -551,19 +540,6 @@ _cogl_pipeline_vertend_glsl_end (CoglPipeline *pipeline, shader_state->gl_shader = shader; } -#ifdef HAVE_COGL_GL - if (_cogl_has_private_feature - (ctx, COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM) && - (pipelines_difference & COGL_PIPELINE_STATE_POINT_SIZE)) - { - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_POINT_SIZE); - - if (authority->big_state->point_size > 0.0f) - GE( ctx, glPointSize (authority->big_state->point_size) ); - } -#endif /* HAVE_COGL_GL */ - return TRUE; } @@ -661,11 +637,7 @@ UNIT_TEST (check_point_size_shader, * size */ if (shader_states[0]) { - if (_cogl_has_private_feature - (test_ctx, COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM)) - g_assert (shader_states[0] == shader_states[1]); - else - g_assert (shader_states[0] != shader_states[1]); + g_assert (shader_states[0] != shader_states[1]); } /* The second and third pipelines should always have the same shader @@ -676,5 +648,3 @@ UNIT_TEST (check_point_size_shader, /* The fourth pipeline should be exactly the same as the first */ g_assert (shader_states[0] == shader_states[3]); } - -#endif /* COGL_PIPELINE_VERTEND_GLSL */ diff --git a/cogl/cogl/driver/gl/cogl-texture-2d-gl-private.h b/cogl/cogl/driver/gl/cogl-texture-2d-gl-private.h index e5c658534..c10637627 100644 --- a/cogl/cogl/driver/gl/cogl-texture-2d-gl-private.h +++ b/cogl/cogl/driver/gl/cogl-texture-2d-gl-private.h @@ -41,7 +41,7 @@ void _cogl_texture_2d_gl_free (CoglTexture2D *tex_2d); -CoglBool +gboolean _cogl_texture_2d_gl_can_create (CoglContext *ctx, int width, int height, @@ -50,15 +50,15 @@ _cogl_texture_2d_gl_can_create (CoglContext *ctx, void _cogl_texture_2d_gl_init (CoglTexture2D *tex_2d); -CoglBool +gboolean _cogl_texture_2d_gl_allocate (CoglTexture *tex, - CoglError **error); + GError **error); CoglTexture2D * _cogl_texture_2d_gl_new_from_bitmap (CoglBitmap *bmp, CoglPixelFormat internal_format, - CoglBool can_convert_in_place, - CoglError **error); + gboolean can_convert_in_place, + GError **error); #if defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base) CoglTexture2D * @@ -67,7 +67,7 @@ _cogl_egl_texture_2d_gl_new_from_image (CoglContext *ctx, int height, CoglPixelFormat format, EGLImageKHR image, - CoglError **error); + GError **error); #endif void @@ -78,8 +78,7 @@ _cogl_texture_2d_gl_flush_legacy_texobj_filters (CoglTexture *tex, void _cogl_texture_2d_gl_flush_legacy_texobj_wrap_modes (CoglTexture *tex, GLenum wrap_mode_s, - GLenum wrap_mode_t, - GLenum wrap_mode_p); + GLenum wrap_mode_t); void _cogl_texture_2d_gl_copy_from_framebuffer (CoglTexture2D *tex_2d, @@ -98,7 +97,7 @@ _cogl_texture_2d_gl_get_gl_handle (CoglTexture2D *tex_2d); void _cogl_texture_2d_gl_generate_mipmap (CoglTexture2D *tex_2d); -CoglBool +gboolean _cogl_texture_2d_gl_copy_from_bitmap (CoglTexture2D *tex_2d, int src_x, int src_y, @@ -108,7 +107,10 @@ _cogl_texture_2d_gl_copy_from_bitmap (CoglTexture2D *tex_2d, int dst_x, int dst_y, int level, - CoglError **error); + GError **error); + +gboolean +_cogl_texture_2d_gl_is_get_data_supported (CoglTexture2D *tex_2d); void _cogl_texture_2d_gl_get_data (CoglTexture2D *tex_2d, diff --git a/cogl/cogl/driver/gl/cogl-texture-2d-gl.c b/cogl/cogl/driver/gl/cogl-texture-2d-gl.c index d1eff4507..d602de2c8 100644 --- a/cogl/cogl/driver/gl/cogl-texture-2d-gl.c +++ b/cogl/cogl/driver/gl/cogl-texture-2d-gl.c @@ -38,13 +38,11 @@ #include "cogl-private.h" #include "cogl-texture-private.h" -#include "cogl-texture-2d-gl.h" -#include "cogl-texture-2d-gl-private.h" #include "cogl-texture-2d-private.h" -#include "cogl-texture-gl-private.h" -#include "cogl-pipeline-opengl-private.h" -#include "cogl-error-private.h" -#include "cogl-util-gl-private.h" +#include "driver/gl/cogl-texture-2d-gl-private.h" +#include "driver/gl/cogl-texture-gl-private.h" +#include "driver/gl/cogl-pipeline-opengl-private.h" +#include "driver/gl/cogl-util-gl-private.h" #if defined (COGL_HAS_EGL_SUPPORT) @@ -64,7 +62,7 @@ void _cogl_texture_2d_gl_free (CoglTexture2D *tex_2d) { - if (!tex_2d->is_foreign && tex_2d->gl_texture) + if (tex_2d->gl_texture) _cogl_delete_gl_texture (tex_2d->gl_texture); #if defined (COGL_HAS_EGL_SUPPORT) @@ -73,7 +71,7 @@ _cogl_texture_2d_gl_free (CoglTexture2D *tex_2d) #endif } -CoglBool +gboolean _cogl_texture_2d_gl_can_create (CoglContext *ctx, int width, int height, @@ -83,11 +81,8 @@ _cogl_texture_2d_gl_can_create (CoglContext *ctx, GLenum gl_format; GLenum gl_type; - /* If NPOT textures aren't supported then the size must be a power - of two */ - if (!cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_BASIC) && - (!_cogl_util_is_pot (width) || - !_cogl_util_is_pot (height))) + /* We only support single plane formats for now */ + if (cogl_pixel_format_get_n_planes (internal_format) != 1) return FALSE; ctx->driver_vtable->pixel_format_to_gl (ctx, @@ -126,10 +121,10 @@ _cogl_texture_2d_gl_init (CoglTexture2D *tex_2d) tex_2d->egl_image_external.destroy = NULL; } -static CoglBool +static gboolean allocate_with_size (CoglTexture2D *tex_2d, CoglTextureLoader *loader, - CoglError **error) + GError **error) { CoglTexture *tex = COGL_TEXTURE (tex_2d); CoglPixelFormat internal_format; @@ -149,10 +144,10 @@ allocate_with_size (CoglTexture2D *tex_2d, height, internal_format)) { - _cogl_set_error (error, COGL_TEXTURE_ERROR, - COGL_TEXTURE_ERROR_SIZE, - "Failed to create texture 2d due to size/format" - " constraints"); + g_set_error_literal (error, COGL_TEXTURE_ERROR, + COGL_TEXTURE_ERROR_SIZE, + "Failed to create texture 2d due to size/format" + " constraints"); return FALSE; } @@ -167,8 +162,7 @@ allocate_with_size (CoglTexture2D *tex_2d, tex_2d->gl_internal_format = gl_intformat; _cogl_bind_gl_texture_transient (GL_TEXTURE_2D, - gl_texture, - tex_2d->is_foreign); + gl_texture); /* Clear any GL errors */ _cogl_gl_util_clear_gl_errors (ctx); @@ -192,10 +186,10 @@ allocate_with_size (CoglTexture2D *tex_2d, return TRUE; } -static CoglBool +static gboolean allocate_from_bitmap (CoglTexture2D *tex_2d, CoglTextureLoader *loader, - CoglError **error) + GError **error) { CoglTexture *tex = COGL_TEXTURE (tex_2d); CoglBitmap *bmp = loader->src.bitmap.bitmap; @@ -203,7 +197,7 @@ allocate_from_bitmap (CoglTexture2D *tex_2d, CoglPixelFormat internal_format; int width = cogl_bitmap_get_width (bmp); int height = cogl_bitmap_get_height (bmp); - CoglBool can_convert_in_place = loader->src.bitmap.can_convert_in_place; + gboolean can_convert_in_place = loader->src.bitmap.can_convert_in_place; CoglBitmap *upload_bmp; GLenum gl_intformat; GLenum gl_format; @@ -217,10 +211,10 @@ allocate_from_bitmap (CoglTexture2D *tex_2d, height, internal_format)) { - _cogl_set_error (error, COGL_TEXTURE_ERROR, - COGL_TEXTURE_ERROR_SIZE, - "Failed to create texture 2d due to size/format" - " constraints"); + g_set_error_literal (error, COGL_TEXTURE_ERROR, + COGL_TEXTURE_ERROR_SIZE, + "Failed to create texture 2d due to size/format" + " constraints"); return FALSE; } @@ -242,41 +236,11 @@ allocate_from_bitmap (CoglTexture2D *tex_2d, NULL, NULL); - /* Keep a copy of the first pixel so that if glGenerateMipmap isn't - supported we can fallback to using GL_GENERATE_MIPMAP */ - if (!cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN)) - { - CoglError *ignore = NULL; - uint8_t *data = _cogl_bitmap_map (upload_bmp, - COGL_BUFFER_ACCESS_READ, 0, - &ignore); - CoglPixelFormat format = cogl_bitmap_get_format (upload_bmp); - - tex_2d->first_pixel.gl_format = gl_format; - tex_2d->first_pixel.gl_type = gl_type; - - if (data) - { - memcpy (tex_2d->first_pixel.data, data, - _cogl_pixel_format_get_bytes_per_pixel (format)); - _cogl_bitmap_unmap (upload_bmp); - } - else - { - g_warning ("Failed to read first pixel of bitmap for " - "glGenerateMipmap fallback"); - cogl_error_free (ignore); - memset (tex_2d->first_pixel.data, 0, - _cogl_pixel_format_get_bytes_per_pixel (format)); - } - } - tex_2d->gl_texture = ctx->texture_driver->gen (ctx, GL_TEXTURE_2D, internal_format); if (!ctx->texture_driver->upload_to_gl (ctx, GL_TEXTURE_2D, tex_2d->gl_texture, - FALSE, upload_bmp, gl_intformat, gl_format, @@ -299,10 +263,10 @@ allocate_from_bitmap (CoglTexture2D *tex_2d, } #if defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base) -static CoglBool +static gboolean allocate_from_egl_image (CoglTexture2D *tex_2d, CoglTextureLoader *loader, - CoglError **error) + GError **error) { CoglTexture *tex = COGL_TEXTURE (tex_2d); CoglContext *ctx = tex->context; @@ -311,23 +275,24 @@ allocate_from_egl_image (CoglTexture2D *tex_2d, tex_2d->gl_texture = ctx->texture_driver->gen (ctx, GL_TEXTURE_2D, internal_format); _cogl_bind_gl_texture_transient (GL_TEXTURE_2D, - tex_2d->gl_texture, - FALSE); + tex_2d->gl_texture); _cogl_gl_util_clear_gl_errors (ctx); ctx->glEGLImageTargetTexture2D (GL_TEXTURE_2D, loader->src.egl_image.image); if (_cogl_gl_util_get_error (ctx) != GL_NO_ERROR) { - _cogl_set_error (error, - COGL_TEXTURE_ERROR, - COGL_TEXTURE_ERROR_BAD_PARAMETER, - "Could not create a CoglTexture2D from a given " - "EGLImage"); + g_set_error_literal (error, + COGL_TEXTURE_ERROR, + COGL_TEXTURE_ERROR_BAD_PARAMETER, + "Could not create a CoglTexture2D from a given " + "EGLImage"); GE( ctx, glDeleteTextures (1, &tex_2d->gl_texture) ); return FALSE; } tex_2d->internal_format = internal_format; + tex_2d->is_get_data_supported = + !(loader->src.egl_image.flags & COGL_EGL_IMAGE_FLAG_NO_GET_DATA); _cogl_texture_set_allocated (tex, internal_format, @@ -338,139 +303,20 @@ allocate_from_egl_image (CoglTexture2D *tex_2d, } #endif -static CoglBool -allocate_from_gl_foreign (CoglTexture2D *tex_2d, - CoglTextureLoader *loader, - CoglError **error) -{ - CoglTexture *tex = COGL_TEXTURE (tex_2d); - CoglContext *ctx = tex->context; - CoglPixelFormat format = loader->src.gl_foreign.format; - GLint gl_compressed = GL_FALSE; - GLenum gl_int_format = 0; - - if (!ctx->texture_driver->allows_foreign_gl_target (ctx, GL_TEXTURE_2D)) - { - _cogl_set_error (error, - COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_UNSUPPORTED, - "Foreign GL_TEXTURE_2D textures are not " - "supported by your system"); - return FALSE; - } - - /* Make sure binding succeeds */ - _cogl_gl_util_clear_gl_errors (ctx); - - _cogl_bind_gl_texture_transient (GL_TEXTURE_2D, - loader->src.gl_foreign.gl_handle, TRUE); - if (_cogl_gl_util_get_error (ctx) != GL_NO_ERROR) - { - _cogl_set_error (error, - COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_UNSUPPORTED, - "Failed to bind foreign GL_TEXTURE_2D texture"); - return FALSE; - } - - /* Obtain texture parameters - (only level 0 we are interested in) */ - -#ifdef HAVE_COGL_GL - if (_cogl_has_private_feature - (ctx, COGL_PRIVATE_FEATURE_QUERY_TEXTURE_PARAMETERS)) - { - GE( ctx, glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, - GL_TEXTURE_COMPRESSED, - &gl_compressed) ); - - { - GLint val; - - GE( ctx, glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, - GL_TEXTURE_INTERNAL_FORMAT, - &val) ); - - gl_int_format = val; - } - - /* If we can query GL for the actual pixel format then we'll ignore - the passed in format and use that. */ - if (!ctx->driver_vtable->pixel_format_from_gl_internal (ctx, - gl_int_format, - &format)) - { - _cogl_set_error (error, - COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_UNSUPPORTED, - "Unsupported internal format for foreign texture"); - return FALSE; - } - } - else -#endif - { - /* Otherwise we'll assume we can derive the GL format from the - passed in format */ - ctx->driver_vtable->pixel_format_to_gl (ctx, - format, - &gl_int_format, - NULL, - NULL); - } - - /* Compressed texture images not supported */ - if (gl_compressed == GL_TRUE) - { - _cogl_set_error (error, - COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_UNSUPPORTED, - "Compressed foreign textures aren't currently supported"); - return FALSE; - } - - /* Note: previously this code would query the texture object for - whether it has GL_GENERATE_MIPMAP enabled to determine whether to - auto-generate the mipmap. This doesn't make much sense any more - since Cogl switch to using glGenerateMipmap. Ideally I think - cogl_texture_2d_gl_new_from_foreign should take a flags parameter so - that the application can decide whether it wants - auto-mipmapping. To be compatible with existing code, Cogl now - disables its own auto-mipmapping but leaves the value of - GL_GENERATE_MIPMAP alone so that it would still work but without - the dirtiness tracking that Cogl would do. */ - - _cogl_texture_2d_set_auto_mipmap (COGL_TEXTURE (tex_2d), FALSE); - - /* Setup bitmap info */ - tex_2d->is_foreign = TRUE; - tex_2d->mipmaps_dirty = TRUE; - - tex_2d->gl_texture = loader->src.gl_foreign.gl_handle; - tex_2d->gl_internal_format = gl_int_format; - - /* Unknown filter */ - tex_2d->gl_legacy_texobj_min_filter = GL_FALSE; - tex_2d->gl_legacy_texobj_mag_filter = GL_FALSE; - - tex_2d->internal_format = format; - - _cogl_texture_set_allocated (tex, - format, - loader->src.gl_foreign.width, - loader->src.gl_foreign.height); - return TRUE; -} - #if defined (COGL_HAS_EGL_SUPPORT) -static CoglBool +static gboolean allocate_custom_egl_image_external (CoglTexture2D *tex_2d, CoglTextureLoader *loader, - CoglError **error) + GError **error) { CoglTexture *tex = COGL_TEXTURE (tex_2d); CoglContext *ctx = tex->context; - CoglPixelFormat internal_format = loader->src.egl_image_external.format; + CoglPixelFormat external_format; + CoglPixelFormat internal_format; + + external_format = loader->src.egl_image_external.format; + internal_format = _cogl_texture_determine_internal_format (tex, + external_format); _cogl_gl_util_clear_gl_errors (ctx); @@ -482,11 +328,11 @@ allocate_custom_egl_image_external (CoglTexture2D *tex_2d, if (_cogl_gl_util_get_error (ctx) != GL_NO_ERROR) { - _cogl_set_error (error, - COGL_TEXTURE_ERROR, - COGL_TEXTURE_ERROR_BAD_PARAMETER, - "Could not create a CoglTexture2D from a given " - "EGLImage"); + g_set_error_literal (error, + COGL_TEXTURE_ERROR, + COGL_TEXTURE_ERROR_BAD_PARAMETER, + "Could not create a CoglTexture2D from a given " + "EGLImage"); GE( ctx, glDeleteTextures (1, &tex_2d->gl_texture) ); return FALSE; } @@ -509,6 +355,7 @@ allocate_custom_egl_image_external (CoglTexture2D *tex_2d, tex_2d->internal_format = internal_format; tex_2d->gl_target = GL_TEXTURE_EXTERNAL_OES; + tex_2d->is_get_data_supported = FALSE; return TRUE; } @@ -520,19 +367,19 @@ cogl_texture_2d_new_from_egl_image_external (CoglContext *ctx, CoglTexture2DEGLImageExternalAlloc alloc, gpointer user_data, GDestroyNotify destroy, - CoglError **error) + GError **error) { CoglTextureLoader *loader; CoglTexture2D *tex_2d; CoglPixelFormat internal_format = COGL_PIXEL_FORMAT_ANY; - _COGL_RETURN_VAL_IF_FAIL (_cogl_context_get_winsys (ctx)->constraints & - COGL_RENDERER_CONSTRAINT_USES_EGL, - NULL); + g_return_val_if_fail (_cogl_context_get_winsys (ctx)->constraints & + COGL_RENDERER_CONSTRAINT_USES_EGL, + NULL); - _COGL_RETURN_VAL_IF_FAIL (cogl_has_feature (ctx, - COGL_FEATURE_ID_TEXTURE_EGL_IMAGE_EXTERNAL), - NULL); + g_return_val_if_fail (cogl_has_feature (ctx, + COGL_FEATURE_ID_TEXTURE_EGL_IMAGE_EXTERNAL), + NULL); loader = _cogl_texture_create_loader (); loader->src_type = COGL_TEXTURE_SOURCE_TYPE_EGL_IMAGE_EXTERNAL; @@ -552,14 +399,14 @@ cogl_texture_2d_new_from_egl_image_external (CoglContext *ctx, } #endif /* defined (COGL_HAS_EGL_SUPPORT) */ -CoglBool +gboolean _cogl_texture_2d_gl_allocate (CoglTexture *tex, - CoglError **error) + GError **error) { CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex); CoglTextureLoader *loader = tex->loader; - _COGL_RETURN_VAL_IF_FAIL (loader, FALSE); + g_return_val_if_fail (loader, FALSE); switch (loader->src_type) { @@ -573,10 +420,12 @@ _cogl_texture_2d_gl_allocate (CoglTexture *tex, #else g_return_val_if_reached (FALSE); #endif - case COGL_TEXTURE_SOURCE_TYPE_GL_FOREIGN: - return allocate_from_gl_foreign (tex_2d, loader, error); case COGL_TEXTURE_SOURCE_TYPE_EGL_IMAGE_EXTERNAL: +#if defined (COGL_HAS_EGL_SUPPORT) return allocate_custom_egl_image_external (tex_2d, loader, error); +#else + g_return_val_if_reached (FALSE); +#endif } g_return_val_if_reached (FALSE); @@ -600,8 +449,7 @@ _cogl_texture_2d_gl_flush_legacy_texobj_filters (CoglTexture *tex, /* Apply new filters to the texture */ _cogl_bind_gl_texture_transient (GL_TEXTURE_2D, - tex_2d->gl_texture, - tex_2d->is_foreign); + tex_2d->gl_texture); GE( ctx, glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter) ); GE( ctx, glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter) ); } @@ -609,8 +457,7 @@ _cogl_texture_2d_gl_flush_legacy_texobj_filters (CoglTexture *tex, void _cogl_texture_2d_gl_flush_legacy_texobj_wrap_modes (CoglTexture *tex, GLenum wrap_mode_s, - GLenum wrap_mode_t, - GLenum wrap_mode_p) + GLenum wrap_mode_t) { CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex); CoglContext *ctx = tex->context; @@ -622,8 +469,7 @@ _cogl_texture_2d_gl_flush_legacy_texobj_wrap_modes (CoglTexture *tex, tex_2d->gl_legacy_texobj_wrap_mode_t != wrap_mode_t) { _cogl_bind_gl_texture_transient (GL_TEXTURE_2D, - tex_2d->gl_texture, - tex_2d->is_foreign); + tex_2d->gl_texture); GE( ctx, glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_mode_s) ); @@ -636,42 +482,6 @@ _cogl_texture_2d_gl_flush_legacy_texobj_wrap_modes (CoglTexture *tex, } } -CoglTexture2D * -cogl_texture_2d_gl_new_from_foreign (CoglContext *ctx, - unsigned int gl_handle, - int width, - int height, - CoglPixelFormat format) -{ - CoglTextureLoader *loader; - - /* NOTE: width, height and internal format are not queriable - * in GLES, hence such a function prototype. - */ - - /* Note: We always trust the given width and height without querying - * the texture object because the user may be creating a Cogl - * texture for a texture_from_pixmap object where glTexImage2D may - * not have been called and the texture_from_pixmap spec doesn't - * clarify that it is reliable to query back the size from OpenGL. - */ - - /* Assert it is a valid GL texture object */ - _COGL_RETURN_VAL_IF_FAIL (ctx->glIsTexture (gl_handle), FALSE); - - /* Validate width and height */ - _COGL_RETURN_VAL_IF_FAIL (width > 0 && height > 0, NULL); - - loader = _cogl_texture_create_loader (); - loader->src_type = COGL_TEXTURE_SOURCE_TYPE_GL_FOREIGN; - loader->src.gl_foreign.gl_handle = gl_handle; - loader->src.gl_foreign.width = width; - loader->src.gl_foreign.height = height; - loader->src.gl_foreign.format = format; - - return _cogl_texture_2d_create_base (ctx, width, height, format, loader); -} - void _cogl_texture_2d_gl_copy_from_framebuffer (CoglTexture2D *tex_2d, int src_x, @@ -695,8 +505,7 @@ _cogl_texture_2d_gl_copy_from_framebuffer (CoglTexture2D *tex_2d, ~COGL_FRAMEBUFFER_STATE_CLIP); _cogl_bind_gl_texture_transient (GL_TEXTURE_2D, - tex_2d->gl_texture, - tex_2d->is_foreign); + tex_2d->gl_texture); ctx->glCopyTexSubImage2D (GL_TEXTURE_2D, 0, /* level */ @@ -714,35 +523,10 @@ _cogl_texture_2d_gl_get_gl_handle (CoglTexture2D *tex_2d) void _cogl_texture_2d_gl_generate_mipmap (CoglTexture2D *tex_2d) { - CoglContext *ctx = COGL_TEXTURE (tex_2d)->context; - - /* glGenerateMipmap is defined in the FBO extension. If it's not - available we'll fallback to temporarily enabling - GL_GENERATE_MIPMAP and reuploading the first pixel */ - if (cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN)) - _cogl_texture_gl_generate_mipmaps (COGL_TEXTURE (tex_2d)); -#if defined(HAVE_COGL_GLES) || defined(HAVE_COGL_GL) - else - { - _cogl_bind_gl_texture_transient (GL_TEXTURE_2D, - tex_2d->gl_texture, - tex_2d->is_foreign); - - GE( ctx, glTexParameteri (GL_TEXTURE_2D, - GL_GENERATE_MIPMAP, - GL_TRUE) ); - GE( ctx, glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, 1, 1, - tex_2d->first_pixel.gl_format, - tex_2d->first_pixel.gl_type, - tex_2d->first_pixel.data) ); - GE( ctx, glTexParameteri (GL_TEXTURE_2D, - GL_GENERATE_MIPMAP, - GL_FALSE) ); - } -#endif + _cogl_texture_gl_generate_mipmaps (COGL_TEXTURE (tex_2d)); } -CoglBool +gboolean _cogl_texture_2d_gl_copy_from_bitmap (CoglTexture2D *tex_2d, int src_x, int src_y, @@ -752,7 +536,7 @@ _cogl_texture_2d_gl_copy_from_bitmap (CoglTexture2D *tex_2d, int dst_x, int dst_y, int level, - CoglError **error) + GError **error) { CoglTexture *tex = COGL_TEXTURE (tex_2d); CoglContext *ctx = tex->context; @@ -760,7 +544,7 @@ _cogl_texture_2d_gl_copy_from_bitmap (CoglTexture2D *tex_2d, CoglPixelFormat upload_format; GLenum gl_format; GLenum gl_type; - CoglBool status = TRUE; + gboolean status = TRUE; upload_bmp = _cogl_bitmap_convert_for_upload (bmp, @@ -772,47 +556,22 @@ _cogl_texture_2d_gl_copy_from_bitmap (CoglTexture2D *tex_2d, upload_format = cogl_bitmap_get_format (upload_bmp); - ctx->driver_vtable->pixel_format_to_gl_with_target (ctx, - upload_format, - _cogl_texture_get_format (tex), - NULL, /* internal gl format */ - &gl_format, - &gl_type); + /* Only support single plane formats */ + if (upload_format == COGL_PIXEL_FORMAT_ANY || + cogl_pixel_format_get_n_planes (upload_format) != 1) + return FALSE; - /* If this touches the first pixel then we'll update our copy */ - if (dst_x == 0 && dst_y == 0 && - !cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN)) - { - CoglError *ignore = NULL; - uint8_t *data = - _cogl_bitmap_map (upload_bmp, COGL_BUFFER_ACCESS_READ, 0, &ignore); - CoglPixelFormat bpp = - _cogl_pixel_format_get_bytes_per_pixel (upload_format); - - tex_2d->first_pixel.gl_format = gl_format; - tex_2d->first_pixel.gl_type = gl_type; - - if (data) - { - memcpy (tex_2d->first_pixel.data, - (data + - cogl_bitmap_get_rowstride (upload_bmp) * src_y + - bpp * src_x), - bpp); - _cogl_bitmap_unmap (bmp); - } - else - { - g_warning ("Failed to read first bitmap pixel for " - "glGenerateMipmap fallback"); - cogl_error_free (ignore); - memset (tex_2d->first_pixel.data, 0, bpp); - } - } + ctx->driver_vtable->pixel_format_to_gl (ctx, + upload_format, + NULL, /* internal gl format */ + &gl_format, + &gl_type); + + if (tex->max_level_set < level) + cogl_texture_gl_set_max_level (tex, level); status = ctx->texture_driver->upload_subregion_to_gl (ctx, tex, - FALSE, src_x, src_y, dst_x, dst_y, width, height, @@ -824,11 +583,15 @@ _cogl_texture_2d_gl_copy_from_bitmap (CoglTexture2D *tex_2d, cogl_object_unref (upload_bmp); - _cogl_texture_gl_maybe_update_max_level (tex, level); - return status; } +gboolean +_cogl_texture_2d_gl_is_get_data_supported (CoglTexture2D *tex_2d) +{ + return tex_2d->is_get_data_supported; +} + void _cogl_texture_2d_gl_get_data (CoglTexture2D *tex_2d, CoglPixelFormat format, @@ -836,12 +599,15 @@ _cogl_texture_2d_gl_get_data (CoglTexture2D *tex_2d, uint8_t *data) { CoglContext *ctx = COGL_TEXTURE (tex_2d)->context; - int bpp; + uint8_t bpp; int width = COGL_TEXTURE (tex_2d)->width; GLenum gl_format; GLenum gl_type; - bpp = _cogl_pixel_format_get_bytes_per_pixel (format); + g_return_if_fail (format != COGL_PIXEL_FORMAT_ANY); + g_return_if_fail (cogl_pixel_format_get_n_planes (format) == 1); + + bpp = cogl_pixel_format_get_bytes_per_pixel (format, 0); ctx->driver_vtable->pixel_format_to_gl (ctx, format, @@ -854,12 +620,11 @@ _cogl_texture_2d_gl_get_data (CoglTexture2D *tex_2d, width, bpp); - _cogl_bind_gl_texture_transient (GL_TEXTURE_2D, - tex_2d->gl_texture, - tex_2d->is_foreign); + _cogl_bind_gl_texture_transient (tex_2d->gl_target, + tex_2d->gl_texture); ctx->texture_driver->gl_get_tex_image (ctx, - GL_TEXTURE_2D, + tex_2d->gl_target, gl_format, gl_type, data); diff --git a/cogl/cogl/driver/gl/cogl-texture-gl-private.h b/cogl/cogl/driver/gl/cogl-texture-gl-private.h index b5baac7bf..a8fbd2866 100644 --- a/cogl/cogl/driver/gl/cogl-texture-gl-private.h +++ b/cogl/cogl/driver/gl/cogl-texture-gl-private.h @@ -45,8 +45,7 @@ _cogl_texture_gl_prep_alignment_for_pixels_download (CoglContext *ctx, void _cogl_texture_gl_flush_legacy_texobj_wrap_modes (CoglTexture *texture, unsigned int wrap_mode_s, - unsigned int wrap_mode_t, - unsigned int wrap_mode_p); + unsigned int wrap_mode_t); void _cogl_texture_gl_flush_legacy_texobj_filters (CoglTexture *texture, @@ -54,8 +53,8 @@ _cogl_texture_gl_flush_legacy_texobj_filters (CoglTexture *texture, unsigned int mag_filter); void -_cogl_texture_gl_maybe_update_max_level (CoglTexture *texture, - int max_level); +cogl_texture_gl_set_max_level (CoglTexture *texture, + int max_level); void _cogl_texture_gl_generate_mipmaps (CoglTexture *texture); diff --git a/cogl/cogl/driver/gl/cogl-texture-gl.c b/cogl/cogl/driver/gl/cogl-texture-gl.c index 02253415b..f1367b0db 100644 --- a/cogl/cogl/driver/gl/cogl-texture-gl.c +++ b/cogl/cogl/driver/gl/cogl-texture-gl.c @@ -27,25 +27,20 @@ * */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif -#ifdef HAVE_STRINGS_H #include -#endif #include "cogl-context-private.h" -#include "cogl-util-gl-private.h" -#include "cogl-texture-gl-private.h" -#include "cogl-texture-3d-private.h" #include "cogl-util.h" -#include "cogl-pipeline-opengl-private.h" +#include "driver/gl/cogl-util-gl-private.h" +#include "driver/gl/cogl-texture-gl-private.h" +#include "driver/gl/cogl-pipeline-opengl-private.h" static inline int calculate_alignment (int rowstride) { - int alignment = 1 << (_cogl_util_ffs (rowstride) - 1); + int alignment = 1 << (ffs (rowstride) - 1); return MIN (alignment, 8); } @@ -86,13 +81,11 @@ _cogl_texture_gl_prep_alignment_for_pixels_download (CoglContext *ctx, void _cogl_texture_gl_flush_legacy_texobj_wrap_modes (CoglTexture *texture, unsigned int wrap_mode_s, - unsigned int wrap_mode_t, - unsigned int wrap_mode_p) + unsigned int wrap_mode_t) { texture->vtable->gl_flush_legacy_texobj_wrap_modes (texture, wrap_mode_s, - wrap_mode_t, - wrap_mode_p); + wrap_mode_t); } void @@ -104,33 +97,36 @@ _cogl_texture_gl_flush_legacy_texobj_filters (CoglTexture *texture, min_filter, mag_filter); } +/* GL and GLES3 have this by default, but GLES2 does not except via extension. + * So really it's probably always available. Even if we used it and it wasn't + * available in some driver then there are no adverse consequences to the + * command simply being ignored... + */ +#ifndef GL_TEXTURE_MAX_LEVEL +#define GL_TEXTURE_MAX_LEVEL 0x813D +#endif + void -_cogl_texture_gl_maybe_update_max_level (CoglTexture *texture, - int max_level) +cogl_texture_gl_set_max_level (CoglTexture *texture, + int max_level) { - /* This isn't supported on GLES */ -#ifdef HAVE_COGL_GL CoglContext *ctx = texture->context; - if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_TEXTURE_MAX_LEVEL) && - texture->max_level < max_level) + if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_TEXTURE_MAX_LEVEL)) { - CoglContext *ctx = texture->context; GLuint gl_handle; GLenum gl_target; cogl_texture_get_gl_texture (texture, &gl_handle, &gl_target); - texture->max_level = max_level; + texture->max_level_set = max_level; _cogl_bind_gl_texture_transient (gl_target, - gl_handle, - _cogl_texture_is_foreign (texture)); + gl_handle); GE( ctx, glTexParameteri (gl_target, - GL_TEXTURE_MAX_LEVEL, texture->max_level)); + GL_TEXTURE_MAX_LEVEL, texture->max_level_set)); } -#endif /* HAVE_COGL_GL */ } void @@ -141,13 +137,13 @@ _cogl_texture_gl_generate_mipmaps (CoglTexture *texture) GLuint gl_handle; GLenum gl_target; - _cogl_texture_gl_maybe_update_max_level (texture, n_levels - 1); + if (texture->max_level_set != n_levels - 1) + cogl_texture_gl_set_max_level (texture, n_levels - 1); cogl_texture_get_gl_texture (texture, &gl_handle, &gl_target); _cogl_bind_gl_texture_transient (gl_target, - gl_handle, - _cogl_texture_is_foreign (texture)); + gl_handle); GE( ctx, glGenerateMipmap (gl_target) ); } diff --git a/cogl/cogl/driver/gl/cogl-util-gl-private.h b/cogl/cogl/driver/gl/cogl-util-gl-private.h index 74db6ee05..52279be67 100644 --- a/cogl/cogl/driver/gl/cogl-util-gl-private.h +++ b/cogl/cogl/driver/gl/cogl-util-gl-private.h @@ -76,19 +76,20 @@ _cogl_gl_error_to_string (GLenum error_code); #endif /* COGL_GL_DEBUG */ +gboolean +_cogl_driver_gl_context_init (CoglContext *context); + +void +_cogl_driver_gl_context_deinit (CoglContext *context); + GLenum _cogl_gl_util_get_error (CoglContext *ctx); void _cogl_gl_util_clear_gl_errors (CoglContext *ctx); -CoglBool -_cogl_gl_util_catch_out_of_memory (CoglContext *ctx, CoglError **error); - -void -_cogl_gl_util_get_texture_target_string (CoglTextureType texture_type, - const char **target_string_out, - const char **swizzle_out); +gboolean +_cogl_gl_util_catch_out_of_memory (CoglContext *ctx, GError **error); /* Parses a GL version number stored in a string. @version_string must * point to the beginning of the version number (ie, it can't point to @@ -96,7 +97,7 @@ _cogl_gl_util_get_texture_target_string (CoglTextureType texture_type, * by the end of the string, a space or a full stop. Anything else * will be treated as invalid. Returns TRUE and sets major_out and * minor_out if it is succesfully parsed or FALSE otherwise. */ -CoglBool +gboolean _cogl_gl_util_parse_gl_version (const char *version_string, int *major_out, int *minor_out); diff --git a/cogl/cogl/driver/gl/cogl-util-gl.c b/cogl/cogl/driver/gl/cogl-util-gl.c index 25e490318..34488c7d8 100644 --- a/cogl/cogl/driver/gl/cogl-util-gl.c +++ b/cogl/cogl/driver/gl/cogl-util-gl.c @@ -30,14 +30,12 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-types.h" #include "cogl-context-private.h" -#include "cogl-error-private.h" -#include "cogl-util-gl-private.h" +#include "driver/gl/cogl-pipeline-opengl-private.h" +#include "driver/gl/cogl-util-gl-private.h" #ifdef COGL_GL_DEBUG /* GL error to string conversion */ @@ -77,6 +75,26 @@ _cogl_gl_error_to_string (GLenum error_code) } #endif /* COGL_GL_DEBUG */ +gboolean +_cogl_driver_gl_context_init (CoglContext *context) +{ + context->texture_units = + g_array_new (FALSE, FALSE, sizeof (CoglTextureUnit)); + + /* See cogl-pipeline.c for more details about why we leave texture unit 1 + * active by default... */ + context->active_texture_unit = 1; + GE (context, glActiveTexture (GL_TEXTURE1)); + + return TRUE; +} + +void +_cogl_driver_gl_context_deinit (CoglContext *context) +{ + _cogl_destroy_texture_units (context); +} + GLenum _cogl_gl_util_get_error (CoglContext *ctx) { @@ -97,11 +115,11 @@ _cogl_gl_util_clear_gl_errors (CoglContext *ctx) ; } -CoglBool -_cogl_gl_util_catch_out_of_memory (CoglContext *ctx, CoglError **error) +gboolean +_cogl_gl_util_catch_out_of_memory (CoglContext *ctx, GError **error) { GLenum gl_error; - CoglBool out_of_memory = FALSE; + gboolean out_of_memory = FALSE; while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR && gl_error != GL_CONTEXT_LOST) { @@ -120,59 +138,16 @@ _cogl_gl_util_catch_out_of_memory (CoglContext *ctx, CoglError **error) if (out_of_memory) { - _cogl_set_error (error, COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_NO_MEMORY, - "Out of memory"); + g_set_error_literal (error, COGL_SYSTEM_ERROR, + COGL_SYSTEM_ERROR_NO_MEMORY, + "Out of memory"); return TRUE; } return FALSE; } -void -_cogl_gl_util_get_texture_target_string (CoglTextureType texture_type, - const char **target_string_out, - const char **swizzle_out) -{ - const char *target_string, *tex_coord_swizzle; - - switch (texture_type) - { -#if 0 /* TODO */ - case COGL_TEXTURE_TYPE_1D: - target_string = "1D"; - tex_coord_swizzle = "s"; - break; -#endif - - case COGL_TEXTURE_TYPE_2D: - target_string = "2D"; - tex_coord_swizzle = "st"; - break; - - case COGL_TEXTURE_TYPE_3D: - target_string = "3D"; - tex_coord_swizzle = "stp"; - break; - - case COGL_TEXTURE_TYPE_RECTANGLE: - target_string = "2DRect"; - tex_coord_swizzle = "st"; - break; - - default: - target_string = "Unknown"; - tex_coord_swizzle = NULL; - g_assert_not_reached (); - } - - if (target_string_out) - *target_string_out = target_string; - if (swizzle_out) - *swizzle_out = tex_coord_swizzle; -} - -CoglBool +gboolean _cogl_gl_util_parse_gl_version (const char *version_string, int *major_out, int *minor_out) diff --git a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c index 99b3c7cf0..bb780cec5 100644 --- a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c +++ b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c @@ -28,25 +28,60 @@ * */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include #include "cogl-private.h" #include "cogl-context-private.h" -#include "cogl-util-gl-private.h" #include "cogl-feature-private.h" #include "cogl-renderer-private.h" -#include "cogl-error-private.h" -#include "cogl-framebuffer-gl-private.h" -#include "cogl-texture-2d-gl-private.h" -#include "cogl-attribute-gl-private.h" -#include "cogl-clip-stack-gl-private.h" -#include "cogl-buffer-gl-private.h" - -static CoglBool +#include "driver/gl/cogl-util-gl-private.h" +#include "driver/gl/cogl-framebuffer-gl-private.h" +#include "driver/gl/cogl-texture-2d-gl-private.h" +#include "driver/gl/cogl-attribute-gl-private.h" +#include "driver/gl/cogl-clip-stack-gl-private.h" +#include "driver/gl/cogl-buffer-gl-private.h" + +static gboolean +_cogl_driver_gl_real_context_init (CoglContext *context) +{ + + _cogl_driver_gl_context_init (context); + + if ((context->driver == COGL_DRIVER_GL3)) + { + GLuint vertex_array; + + /* In a forward compatible context, GL 3 doesn't support rendering + * using the default vertex array object. Cogl doesn't use vertex + * array objects yet so for now we just create a dummy array + * object that we will use as our own default object. Eventually + * it could be good to attach the vertex array objects to + * CoglPrimitives */ + context->glGenVertexArrays (1, &vertex_array); + context->glBindVertexArray (vertex_array); + } + + /* As far as I can tell, GL_POINT_SPRITE doesn't have any effect + unless GL_COORD_REPLACE is enabled for an individual layer. + Therefore it seems like it should be ok to just leave it enabled + all the time instead of having to have a set property on each + pipeline to track whether any layers have point sprite coords + enabled. We don't need to do this for GL3 or GLES2 because point + sprites are handled using a builtin varying in the shader. */ + if (context->driver == COGL_DRIVER_GL) + GE (context, glEnable (GL_POINT_SPRITE)); + + /* There's no enable for this in GLES2, it's always on */ + if (context->driver == COGL_DRIVER_GL || + context->driver == COGL_DRIVER_GL3) + GE (context, glEnable (GL_PROGRAM_POINT_SIZE) ); + + return TRUE; +} + +static gboolean _cogl_driver_pixel_format_from_gl_internal (CoglContext *context, GLenum gl_int_format, CoglPixelFormat *out_format) @@ -96,12 +131,11 @@ _cogl_driver_pixel_format_from_gl_internal (CoglContext *context, } static CoglPixelFormat -_cogl_driver_pixel_format_to_gl_with_target (CoglContext *context, - CoglPixelFormat format, - CoglPixelFormat target_format, - GLenum *out_glintformat, - GLenum *out_glformat, - GLenum *out_gltype) +_cogl_driver_pixel_format_to_gl (CoglContext *context, + CoglPixelFormat format, + GLenum *out_glintformat, + GLenum *out_glformat, + GLenum *out_gltype) { CoglPixelFormat required_format; GLenum glintformat = 0; @@ -175,16 +209,7 @@ _cogl_driver_pixel_format_to_gl_with_target (CoglContext *context, case COGL_PIXEL_FORMAT_BGRA_8888: case COGL_PIXEL_FORMAT_BGRA_8888_PRE: glintformat = GL_RGBA; - /* If the driver has texture_swizzle, pretend internal - * and buffer format are the same here, the pixels - * will be flipped through this extension. - */ - if (target_format == format && - _cogl_has_private_feature - (context, COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE)) - glformat = GL_RGBA; - else - glformat = GL_BGRA; + glformat = GL_BGRA; gltype = GL_UNSIGNED_BYTE; break; @@ -299,21 +324,7 @@ _cogl_driver_pixel_format_to_gl_with_target (CoglContext *context, return required_format; } -static CoglPixelFormat -_cogl_driver_pixel_format_to_gl (CoglContext *context, - CoglPixelFormat format, - GLenum *out_glintformat, - GLenum *out_glformat, - GLenum *out_gltype) -{ - return _cogl_driver_pixel_format_to_gl_with_target (context, - format, format, - out_glintformat, - out_glformat, - out_gltype); -} - -static CoglBool +static gboolean _cogl_get_gl_version (CoglContext *ctx, int *major_out, int *minor_out) @@ -327,61 +338,43 @@ _cogl_get_gl_version (CoglContext *ctx, return _cogl_gl_util_parse_gl_version (version_string, major_out, minor_out); } -static CoglBool +static gboolean check_gl_version (CoglContext *ctx, char **gl_extensions, - CoglError **error) + GError **error) { int major, minor; if (!_cogl_get_gl_version (ctx, &major, &minor)) { - _cogl_set_error (error, + g_set_error (error, COGL_DRIVER_ERROR, COGL_DRIVER_ERROR_UNKNOWN_VERSION, "The OpenGL version could not be determined"); return FALSE; } - /* GL 1.3 supports all of the required functionality in core */ - if (COGL_CHECK_GL_VERSION (major, minor, 1, 3)) - return TRUE; - - /* OpenGL 1.2 is only supported if we have the multitexturing - extension */ - if (!_cogl_check_extension ("GL_ARB_multitexture", gl_extensions)) - { - _cogl_set_error (error, - COGL_DRIVER_ERROR, - COGL_DRIVER_ERROR_INVALID_VERSION, - "The OpenGL driver is missing " - "the GL_ARB_multitexture extension"); - return FALSE; - } - - /* OpenGL 1.2 is required */ - if (!COGL_CHECK_GL_VERSION (major, minor, 1, 2)) + /* We require GLSL 1.20, which is implied by OpenGL 2.1. */ + if (!COGL_CHECK_GL_VERSION (major, minor, 2, 1)) { - _cogl_set_error (error, + g_set_error (error, COGL_DRIVER_ERROR, COGL_DRIVER_ERROR_INVALID_VERSION, - "The OpenGL version of your driver (%i.%i) " - "is not compatible with Cogl", - major, minor); + "OpenGL 2.1 or better is required"); return FALSE; } return TRUE; } -static CoglBool +static gboolean _cogl_driver_update_features (CoglContext *ctx, - CoglError **error) + GError **error) { - CoglFeatureFlags flags = 0; unsigned long private_features [COGL_FLAGS_N_LONGS_FOR_SIZE (COGL_N_PRIVATE_FEATURES)] = { 0 }; char **gl_extensions; + const char *glsl_version; int gl_major = 0, gl_minor = 0; int i; @@ -421,7 +414,7 @@ _cogl_driver_update_features (CoglContext *ctx, _cogl_context_get_gl_version (ctx), all_extensions); - free (all_extensions); + g_free (all_extensions); } _cogl_get_gl_version (ctx, &gl_major, &gl_minor); @@ -429,174 +422,46 @@ _cogl_driver_update_features (CoglContext *ctx, _cogl_gpu_info_init (ctx, &ctx->gpu); ctx->glsl_major = 1; - ctx->glsl_minor = 1; - - if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 0)) - { - const char *glsl_version = - (char *)ctx->glGetString (GL_SHADING_LANGUAGE_VERSION); - _cogl_gl_util_parse_gl_version (glsl_version, - &ctx->glsl_major, - &ctx->glsl_minor); - } + ctx->glsl_minor = 2; + ctx->glsl_version_to_use = 120; - if (COGL_CHECK_GL_VERSION (ctx->glsl_major, ctx->glsl_minor, 1, 2)) - /* We want to use version 120 if it is available so that the - * gl_PointCoord can be used. */ - ctx->glsl_version_to_use = 120; - else - ctx->glsl_version_to_use = 110; + glsl_version = (char *)ctx->glGetString (GL_SHADING_LANGUAGE_VERSION); + _cogl_gl_util_parse_gl_version (glsl_version, + &ctx->glsl_major, + &ctx->glsl_minor); - flags = (COGL_FEATURE_TEXTURE_READ_PIXELS - | COGL_FEATURE_UNSIGNED_INT_INDICES - | COGL_FEATURE_DEPTH_RANGE); COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_UNSIGNED_INT_INDICES, TRUE); - COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_DEPTH_RANGE, TRUE); - - if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 1, 4)) - COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_MIRRORED_REPEAT, TRUE); _cogl_feature_check_ext_functions (ctx, gl_major, gl_minor, gl_extensions); - if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 0) || - _cogl_check_extension ("GL_ARB_texture_non_power_of_two", gl_extensions)) - { - flags |= COGL_FEATURE_TEXTURE_NPOT - | COGL_FEATURE_TEXTURE_NPOT_BASIC - | COGL_FEATURE_TEXTURE_NPOT_MIPMAP - | COGL_FEATURE_TEXTURE_NPOT_REPEAT; - COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_TEXTURE_NPOT, TRUE); - COGL_FLAGS_SET (ctx->features, - COGL_FEATURE_ID_TEXTURE_NPOT_BASIC, TRUE); - COGL_FLAGS_SET (ctx->features, - COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP, TRUE); - COGL_FLAGS_SET (ctx->features, - COGL_FEATURE_ID_TEXTURE_NPOT_REPEAT, TRUE); - } - if (_cogl_check_extension ("GL_MESA_pack_invert", gl_extensions)) COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_MESA_PACK_INVERT, TRUE); - if (ctx->glGenRenderbuffers) + if (!ctx->glGenRenderbuffers) { - flags |= COGL_FEATURE_OFFSCREEN; - COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_OFFSCREEN, TRUE); - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_QUERY_FRAMEBUFFER_BITS, - TRUE); + g_set_error (error, + COGL_DRIVER_ERROR, + COGL_DRIVER_ERROR_NO_SUITABLE_DRIVER_FOUND, + "Framebuffer objects are required to use the GL driver"); + return FALSE; } + COGL_FLAGS_SET (private_features, + COGL_PRIVATE_FEATURE_QUERY_FRAMEBUFFER_BITS, + TRUE); if (ctx->glBlitFramebuffer) COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT, TRUE); - - if (ctx->glRenderbufferStorageMultisampleIMG) - { - flags |= COGL_FEATURE_OFFSCREEN_MULTISAMPLE; - COGL_FLAGS_SET (ctx->features, - COGL_FEATURE_ID_OFFSCREEN_MULTISAMPLE, TRUE); - } - - if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 3, 0) || - _cogl_check_extension ("GL_ARB_depth_texture", gl_extensions)) - { - flags |= COGL_FEATURE_DEPTH_TEXTURE; - COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_DEPTH_TEXTURE, TRUE); - } - - if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 1) || - _cogl_check_extension ("GL_EXT_pixel_buffer_object", gl_extensions)) - COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_PBOS, TRUE); - - if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 1, 4) || - _cogl_check_extension ("GL_EXT_blend_color", gl_extensions)) - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_BLEND_CONSTANT, TRUE); - - if (ctx->glGenPrograms) - { - flags |= COGL_FEATURE_SHADERS_ARBFP; - COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_ARBFP, TRUE); - } - - if (ctx->glCreateProgram) - { - flags |= COGL_FEATURE_SHADERS_GLSL; - COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_GLSL, TRUE); - } - else - { - /* If all of the old GLSL extensions are available then we can fake - * the GL 2.0 GLSL support by diverting to the old function names */ - if (ctx->glCreateProgramObject && /* GL_ARB_shader_objects */ - ctx->glVertexAttribPointer && /* GL_ARB_vertex_shader */ - _cogl_check_extension ("GL_ARB_fragment_shader", gl_extensions)) - { - ctx->glCreateShader = ctx->glCreateShaderObject; - ctx->glCreateProgram = ctx->glCreateProgramObject; - ctx->glDeleteShader = ctx->glDeleteObject; - ctx->glDeleteProgram = ctx->glDeleteObject; - ctx->glAttachShader = ctx->glAttachObject; - ctx->glUseProgram = ctx->glUseProgramObject; - ctx->glGetProgramInfoLog = ctx->glGetInfoLog; - ctx->glGetShaderInfoLog = ctx->glGetInfoLog; - ctx->glGetShaderiv = ctx->glGetObjectParameteriv; - ctx->glGetProgramiv = ctx->glGetObjectParameteriv; - ctx->glDetachShader = ctx->glDetachObject; - ctx->glGetAttachedShaders = ctx->glGetAttachedObjects; - /* FIXME: there doesn't seem to be an equivalent for glIsShader - * and glIsProgram. This doesn't matter for now because Cogl - * doesn't use these but if we add support for simulating a - * GLES2 context on top of regular GL then we'll need to do - * something here */ - - flags |= COGL_FEATURE_SHADERS_GLSL; - COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_GLSL, TRUE); - } - } + COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER, TRUE); - if ((COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 0) || - _cogl_check_extension ("GL_ARB_point_sprite", gl_extensions)) && + COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_PBOS, TRUE); - /* If GLSL is supported then we only enable point sprite support - * too if we have glsl >= 1.2 otherwise we don't have the - * gl_PointCoord builtin which we depend on in the glsl backend. - */ - (!COGL_FLAGS_GET (ctx->features, COGL_FEATURE_ID_GLSL) || - COGL_CHECK_GL_VERSION (ctx->glsl_major, ctx->glsl_minor, 1, 2))) - { - flags |= COGL_FEATURE_POINT_SPRITE; - COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_POINT_SPRITE, TRUE); - } - - if (ctx->glGenBuffers) - { - COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_VBOS, TRUE); - flags |= (COGL_FEATURE_MAP_BUFFER_FOR_READ | - COGL_FEATURE_MAP_BUFFER_FOR_WRITE); - COGL_FLAGS_SET (ctx->features, - COGL_FEATURE_ID_MAP_BUFFER_FOR_READ, TRUE); - COGL_FLAGS_SET (ctx->features, - COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE, TRUE); - } - - if (_cogl_check_extension ("GL_ARB_texture_rectangle", gl_extensions)) - { - flags |= COGL_FEATURE_TEXTURE_RECTANGLE; - COGL_FLAGS_SET (ctx->features, - COGL_FEATURE_ID_TEXTURE_RECTANGLE, TRUE); - } - - if (ctx->glTexImage3D) - { - flags |= COGL_FEATURE_TEXTURE_3D; - COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_TEXTURE_3D, TRUE); - } + COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_MAP_BUFFER_FOR_READ, TRUE); + COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE, TRUE); if (ctx->glEGLImageTargetTexture2D) COGL_FLAGS_SET (private_features, @@ -616,33 +481,11 @@ _cogl_driver_update_features (CoglContext *ctx, COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE, TRUE); - /* The per-vertex point size is only available via GLSL with the - * gl_PointSize builtin. This is only available in GL 2.0 (not the - * GLSL extensions) */ - if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 0)) - { - COGL_FLAGS_SET (ctx->features, - COGL_FEATURE_ID_PER_VERTEX_POINT_SIZE, - TRUE); - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_ENABLE_PROGRAM_POINT_SIZE, TRUE); - } - if (ctx->driver == COGL_DRIVER_GL) { - int max_clip_planes = 0; - /* Features which are not available in GL 3 */ - COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_GL_FIXED, TRUE); - COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_ALPHA_TEST, TRUE); - COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_QUADS, TRUE); COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_ALPHA_TEXTURES, TRUE); - - GE( ctx, glGetIntegerv (GL_MAX_CLIP_PLANES, &max_clip_planes) ); - if (max_clip_planes >= 4) - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_FOUR_CLIP_PLANES, TRUE); } COGL_FLAGS_SET (private_features, @@ -650,9 +493,6 @@ _cogl_driver_update_features (CoglContext *ctx, COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_ANY_GL, TRUE); COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_FORMAT_CONVERSION, TRUE); - COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_BLEND_CONSTANT, TRUE); - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM, TRUE); COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_QUERY_TEXTURE_PARAMETERS, TRUE); COGL_FLAGS_SET (private_features, @@ -670,18 +510,17 @@ _cogl_driver_update_features (CoglContext *ctx, /* Cache features */ for (i = 0; i < G_N_ELEMENTS (private_features); i++) ctx->private_features[i] |= private_features[i]; - ctx->feature_flags |= flags; g_strfreev (gl_extensions); if (!COGL_FLAGS_GET (private_features, COGL_PRIVATE_FEATURE_ALPHA_TEXTURES) && !COGL_FLAGS_GET (private_features, COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE)) { - _cogl_set_error (error, - COGL_DRIVER_ERROR, - COGL_DRIVER_ERROR_NO_SUITABLE_DRIVER_FOUND, - "The GL_ARB_texture_swizzle extension is required " - "to use the GL3 driver"); + g_set_error (error, + COGL_DRIVER_ERROR, + COGL_DRIVER_ERROR_NO_SUITABLE_DRIVER_FOUND, + "The GL_ARB_texture_swizzle extension is required " + "to use the GL3 driver"); return FALSE; } @@ -691,9 +530,10 @@ _cogl_driver_update_features (CoglContext *ctx, const CoglDriverVtable _cogl_driver_gl = { + _cogl_driver_gl_real_context_init, + _cogl_driver_gl_context_deinit, _cogl_driver_pixel_format_from_gl_internal, _cogl_driver_pixel_format_to_gl, - _cogl_driver_pixel_format_to_gl_with_target, _cogl_driver_update_features, _cogl_offscreen_gl_allocate, _cogl_offscreen_gl_free, @@ -701,6 +541,7 @@ _cogl_driver_gl = _cogl_framebuffer_gl_clear, _cogl_framebuffer_gl_query_bits, _cogl_framebuffer_gl_finish, + _cogl_framebuffer_gl_flush, _cogl_framebuffer_gl_discard_buffers, _cogl_framebuffer_gl_draw_attributes, _cogl_framebuffer_gl_draw_indexed_attributes, @@ -713,6 +554,7 @@ _cogl_driver_gl = _cogl_texture_2d_gl_get_gl_handle, _cogl_texture_2d_gl_generate_mipmap, _cogl_texture_2d_gl_copy_from_bitmap, + _cogl_texture_2d_gl_is_get_data_supported, _cogl_texture_2d_gl_get_data, _cogl_gl_flush_attributes_state, _cogl_clip_stack_gl_flush, diff --git a/cogl/cogl/driver/gl/gl/cogl-pipeline-fragend-arbfp-private.h b/cogl/cogl/driver/gl/gl/cogl-pipeline-fragend-arbfp-private.h deleted file mode 100644 index f054aada2..000000000 --- a/cogl/cogl/driver/gl/gl/cogl-pipeline-fragend-arbfp-private.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#ifndef __COGL_PIPELINE_FRAGEND_ARBFP_PRIVATE_H -#define __COGL_PIPELINE_FRAGEND_ARBFP_PRIVATE_H - -#include "cogl-pipeline-private.h" - -extern const CoglPipelineFragend _cogl_pipeline_arbfp_fragend; - -#endif /* __COGL_PIPELINE_ARBFP_PRIVATE_H */ - diff --git a/cogl/cogl/driver/gl/gl/cogl-pipeline-fragend-arbfp.c b/cogl/cogl/driver/gl/gl/cogl-pipeline-fragend-arbfp.c deleted file mode 100644 index 33ac988e9..000000000 --- a/cogl/cogl/driver/gl/gl/cogl-pipeline-fragend-arbfp.c +++ /dev/null @@ -1,988 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#ifdef HAVE_CONFIG_H -#include "cogl-config.h" -#endif - -#include "cogl-debug.h" -#include "cogl-context-private.h" -#include "cogl-util-gl-private.h" -#include "cogl-pipeline-private.h" -#include "cogl-pipeline-state-private.h" -#include "cogl-pipeline-layer-private.h" - -#ifdef COGL_PIPELINE_FRAGEND_ARBFP - -#include "cogl-context-private.h" -#include "cogl-object-private.h" - -#include "cogl-texture-private.h" -#include "cogl-blend-string.h" -#include "cogl-journal-private.h" -#include "cogl-color-private.h" -#include "cogl-profile.h" -#include "cogl-program-private.h" - -#include -#include -#include - -/* This might not be defined on GLES */ -#ifndef GL_TEXTURE_3D -#define GL_TEXTURE_3D 0x806F -#endif - -const CoglPipelineFragend _cogl_pipeline_arbfp_fragend; - -typedef struct _UnitState -{ - int constant_id; /* The program.local[] index */ - unsigned int dirty_combine_constant:1; - unsigned int has_combine_constant:1; - - unsigned int sampled:1; -} UnitState; - -typedef struct -{ - int ref_count; - - CoglHandle user_program; - /* XXX: only valid during codegen */ - GString *source; - GLuint gl_program; - UnitState *unit_state; - int next_constant_id; - - /* Age of the program the last time the uniforms were flushed. This - is used to detect when we need to flush all of the uniforms */ - unsigned int user_program_age; - - /* We need to track the last pipeline that an ARBfp program was used - * with so know if we need to update any program.local parameters. */ - CoglPipeline *last_used_for_pipeline; - - CoglPipelineCacheEntry *cache_entry; -} CoglPipelineShaderState; - -static CoglUserDataKey shader_state_key; - -static CoglPipelineShaderState * -shader_state_new (int n_layers, - CoglPipelineCacheEntry *cache_entry) -{ - CoglPipelineShaderState *shader_state; - - shader_state = g_slice_new0 (CoglPipelineShaderState); - shader_state->ref_count = 1; - shader_state->unit_state = g_new0 (UnitState, n_layers); - shader_state->cache_entry = cache_entry; - - return shader_state; -} - -static CoglPipelineShaderState * -get_shader_state (CoglPipeline *pipeline) -{ - return cogl_object_get_user_data (COGL_OBJECT (pipeline), &shader_state_key); -} - -static void -destroy_shader_state (void *user_data, - void *instance) -{ - CoglPipelineShaderState *shader_state = user_data; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* If the shader state was last used for this pipeline then clear it - so that if same address gets used again for a new pipeline then - we won't think it's the same pipeline and avoid updating the - constants */ - if (shader_state->last_used_for_pipeline == instance) - shader_state->last_used_for_pipeline = NULL; - - if (shader_state->cache_entry && - shader_state->cache_entry->pipeline != instance) - shader_state->cache_entry->usage_count--; - - if (--shader_state->ref_count == 0) - { - if (shader_state->gl_program) - { - GE (ctx, glDeletePrograms (1, &shader_state->gl_program)); - shader_state->gl_program = 0; - } - - free (shader_state->unit_state); - - g_slice_free (CoglPipelineShaderState, shader_state); - } -} - -static void -set_shader_state (CoglPipeline *pipeline, CoglPipelineShaderState *shader_state) -{ - if (shader_state) - { - shader_state->ref_count++; - - /* If we're not setting the state on the template pipeline then - * mark it as a usage of the pipeline cache entry */ - if (shader_state->cache_entry && - shader_state->cache_entry->pipeline != pipeline) - shader_state->cache_entry->usage_count++; - } - - _cogl_object_set_user_data (COGL_OBJECT (pipeline), - &shader_state_key, - shader_state, - destroy_shader_state); -} - -static void -dirty_shader_state (CoglPipeline *pipeline) -{ - cogl_object_set_user_data (COGL_OBJECT (pipeline), - &shader_state_key, - NULL, - NULL); -} - -static void -_cogl_pipeline_fragend_arbfp_start (CoglPipeline *pipeline, - int n_layers, - unsigned long pipelines_difference) -{ - CoglPipelineShaderState *shader_state; - CoglPipeline *authority; - CoglPipelineCacheEntry *cache_entry = NULL; - CoglProgram *user_program = cogl_pipeline_get_user_program (pipeline); - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* Now lookup our ARBfp backend private state */ - shader_state = get_shader_state (pipeline); - - /* If we have a valid shader_state then we are all set and don't - * need to generate a new program. */ - if (shader_state) - return; - - /* If we don't have an associated arbfp program yet then find the - * arbfp-authority (the oldest ancestor whose state will result in - * the same program being generated as for this pipeline). - * - * We always make sure to associate new programs with the - * arbfp-authority to maximize the chance that other pipelines can - * share it. - */ - authority = _cogl_pipeline_find_equivalent_parent - (pipeline, - _cogl_pipeline_get_state_for_fragment_codegen (ctx) & - ~COGL_PIPELINE_STATE_LAYERS, - _cogl_pipeline_get_layer_state_for_fragment_codegen (ctx)); - shader_state = get_shader_state (authority); - if (shader_state) - { - /* If we are going to share our program state with an arbfp-authority - * then add a reference to the program state associated with that - * arbfp-authority... */ - set_shader_state (pipeline, shader_state); - return; - } - - /* If we haven't yet found an existing program then before we resort to - * generating a new arbfp program we see if we can find a suitable - * program in the pipeline_cache. */ - if (G_LIKELY (!(COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_PROGRAM_CACHES)))) - { - cache_entry = - _cogl_pipeline_cache_get_fragment_template (ctx->pipeline_cache, - authority); - - shader_state = get_shader_state (cache_entry->pipeline); - - if (shader_state) - shader_state->ref_count++; - } - - /* If we still haven't got a shader state then we'll have to create - a new one */ - if (shader_state == NULL) - { - shader_state = shader_state_new (n_layers, cache_entry); - - shader_state->user_program = user_program; - if (user_program == COGL_INVALID_HANDLE) - { - /* We reuse a single grow-only GString for code-gen */ - g_string_set_size (ctx->codegen_source_buffer, 0); - shader_state->source = ctx->codegen_source_buffer; - g_string_append (shader_state->source, - "!!ARBfp1.0\n" - "TEMP output;\n" - "TEMP tmp0, tmp1, tmp2, tmp3, tmp4;\n" - "PARAM half = {.5, .5, .5, .5};\n" - "PARAM one = {1, 1, 1, 1};\n" - "PARAM two = {2, 2, 2, 2};\n" - "PARAM minus_one = {-1, -1, -1, -1};\n"); - } - } - - set_shader_state (pipeline, shader_state); - - shader_state->ref_count--; - - /* Since we have already resolved the arbfp-authority at this point - * we might as well also associate any program we find from the cache - * with the authority too... */ - if (authority != pipeline) - set_shader_state (authority, shader_state); - - /* If we found a template then we'll attach it to that too so that - next time a similar pipeline is used it can use the same state */ - if (cache_entry) - set_shader_state (cache_entry->pipeline, shader_state); -} - -static const char * -texture_type_to_arbfp_string (CoglTextureType texture_type) -{ - switch (texture_type) - { -#if 0 /* TODO */ - case COGL_TEXTURE_TYPE_1D: - return "1D"; -#endif - case COGL_TEXTURE_TYPE_2D: - return "2D"; - case COGL_TEXTURE_TYPE_3D: - return "3D"; - case COGL_TEXTURE_TYPE_RECTANGLE: - return "RECT"; - } - - g_warn_if_reached (); - - return "2D"; -} - -static void -setup_texture_source (CoglPipelineShaderState *shader_state, - int unit_index, - CoglTextureType texture_type) -{ - if (!shader_state->unit_state[unit_index].sampled) - { - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_TEXTURING))) - g_string_append_printf (shader_state->source, - "TEMP texel%d;\n" - "MOV texel%d, one;\n", - unit_index, - unit_index); - else - g_string_append_printf (shader_state->source, - "TEMP texel%d;\n" - "TEX texel%d,fragment.texcoord[%d]," - "texture[%d],%s;\n", - unit_index, - unit_index, - unit_index, - unit_index, - texture_type_to_arbfp_string (texture_type)); - shader_state->unit_state[unit_index].sampled = TRUE; - } -} - -typedef enum _CoglPipelineFragendARBfpArgType -{ - COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_SIMPLE, - COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_CONSTANT, - COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_TEXTURE -} CoglPipelineFragendARBfpArgType; - -typedef struct _CoglPipelineFragendARBfpArg -{ - const char *name; - - CoglPipelineFragendARBfpArgType type; - - /* for type = TEXTURE */ - int texture_unit; - CoglTextureType texture_type; - - /* for type = CONSTANT */ - int constant_id; - - const char *swizzle; - -} CoglPipelineFragendARBfpArg; - -static void -append_arg (GString *source, const CoglPipelineFragendARBfpArg *arg) -{ - switch (arg->type) - { - case COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_TEXTURE: - g_string_append_printf (source, "texel%d%s", - arg->texture_unit, arg->swizzle); - break; - case COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_CONSTANT: - g_string_append_printf (source, "program.local[%d]%s", - arg->constant_id, arg->swizzle); - break; - case COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_SIMPLE: - g_string_append_printf (source, "%s%s", - arg->name, arg->swizzle); - break; - } -} - -/* Note: we are trying to avoid duplicating strings during codegen - * which is why we have the slightly awkward - * CoglPipelineFragendARBfpArg mechanism. */ -static void -setup_arg (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - CoglBlendStringChannelMask mask, - int arg_index, - CoglPipelineCombineSource src, - GLint op, - CoglPipelineFragendARBfpArg *arg) -{ - CoglPipelineShaderState *shader_state = get_shader_state (pipeline); - static const char *tmp_name[3] = { "tmp0", "tmp1", "tmp2" }; - - switch (src) - { - case COGL_PIPELINE_COMBINE_SOURCE_TEXTURE: - arg->type = COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_TEXTURE; - arg->name = "texel%d"; - arg->texture_unit = _cogl_pipeline_layer_get_unit_index (layer); - setup_texture_source (shader_state, - arg->texture_unit, - _cogl_pipeline_layer_get_texture_type (layer)); - break; - case COGL_PIPELINE_COMBINE_SOURCE_CONSTANT: - { - int unit_index = _cogl_pipeline_layer_get_unit_index (layer); - UnitState *unit_state = &shader_state->unit_state[unit_index]; - - unit_state->constant_id = shader_state->next_constant_id++; - unit_state->has_combine_constant = TRUE; - unit_state->dirty_combine_constant = TRUE; - - arg->type = COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_CONSTANT; - arg->name = "program.local[%d]"; - arg->constant_id = unit_state->constant_id; - break; - } - case COGL_PIPELINE_COMBINE_SOURCE_PRIMARY_COLOR: - arg->type = COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_SIMPLE; - arg->name = "fragment.color.primary"; - break; - case COGL_PIPELINE_COMBINE_SOURCE_PREVIOUS: - arg->type = COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_SIMPLE; - if (_cogl_pipeline_layer_get_unit_index (layer) == 0) - arg->name = "fragment.color.primary"; - else - arg->name = "output"; - break; - default: /* Sample the texture attached to a specific layer */ - { - int layer_num = src - COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0; - CoglPipelineGetLayerFlags flags = COGL_PIPELINE_GET_LAYER_NO_CREATE; - CoglPipelineLayer *other_layer = - _cogl_pipeline_get_layer_with_flags (pipeline, layer_num, flags); - - if (other_layer == NULL) - { - static CoglBool warning_seen = FALSE; - if (!warning_seen) - { - g_warning ("The application is trying to use a texture " - "combine with a layer number that does not exist"); - warning_seen = TRUE; - } - arg->type = COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_SIMPLE; - arg->name = "output"; - } - else - { - CoglTextureType texture_type; - - arg->type = COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_TEXTURE; - arg->name = "texture[%d]"; - arg->texture_unit = - _cogl_pipeline_layer_get_unit_index (other_layer); - texture_type = _cogl_pipeline_layer_get_texture_type (other_layer); - setup_texture_source (shader_state, - arg->texture_unit, - texture_type); - } - } - break; - } - - arg->swizzle = ""; - - switch (op) - { - case COGL_PIPELINE_COMBINE_OP_SRC_COLOR: - break; - case COGL_PIPELINE_COMBINE_OP_ONE_MINUS_SRC_COLOR: - g_string_append_printf (shader_state->source, - "SUB tmp%d, one, ", - arg_index); - append_arg (shader_state->source, arg); - g_string_append_printf (shader_state->source, ";\n"); - arg->type = COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_SIMPLE; - arg->name = tmp_name[arg_index]; - arg->swizzle = ""; - break; - case COGL_PIPELINE_COMBINE_OP_SRC_ALPHA: - /* avoid a swizzle if we know RGB are going to be masked - * in the end anyway */ - if (mask != COGL_BLEND_STRING_CHANNEL_MASK_ALPHA) - arg->swizzle = ".a"; - break; - case COGL_PIPELINE_COMBINE_OP_ONE_MINUS_SRC_ALPHA: - g_string_append_printf (shader_state->source, - "SUB tmp%d, one, ", - arg_index); - append_arg (shader_state->source, arg); - /* avoid a swizzle if we know RGB are going to be masked - * in the end anyway */ - if (mask != COGL_BLEND_STRING_CHANNEL_MASK_ALPHA) - g_string_append_printf (shader_state->source, ".a;\n"); - else - g_string_append_printf (shader_state->source, ";\n"); - arg->type = COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_SIMPLE; - arg->name = tmp_name[arg_index]; - break; - default: - g_error ("Unknown texture combine operator %d", op); - break; - } -} - -static CoglBool -fragend_arbfp_args_equal (CoglPipelineFragendARBfpArg *arg0, - CoglPipelineFragendARBfpArg *arg1) -{ - if (arg0->type != arg1->type) - return FALSE; - - if (arg0->name != arg1->name && - strcmp (arg0->name, arg1->name) != 0) - return FALSE; - - if (arg0->type == COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_TEXTURE && - arg0->texture_unit != arg1->texture_unit) - return FALSE; - /* Note we don't have to check the target; a texture unit can only - * have one target enabled at a time. */ - - if (arg0->type == COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_CONSTANT && - arg0->constant_id != arg1->constant_id) - return FALSE; - - if (arg0->swizzle != arg1->swizzle && - strcmp (arg0->swizzle, arg1->swizzle) != 0) - return FALSE; - - return TRUE; -} - -static void -append_function (CoglPipeline *pipeline, - CoglBlendStringChannelMask mask, - GLint function, - CoglPipelineFragendARBfpArg *args, - int n_args) -{ - CoglPipelineShaderState *shader_state = get_shader_state (pipeline); - const char *mask_name; - - switch (mask) - { - case COGL_BLEND_STRING_CHANNEL_MASK_RGB: - mask_name = ".rgb"; - break; - case COGL_BLEND_STRING_CHANNEL_MASK_ALPHA: - mask_name = ".a"; - break; - case COGL_BLEND_STRING_CHANNEL_MASK_RGBA: - mask_name = ""; - break; - default: - g_error ("Unknown channel mask %d", mask); - mask_name = ""; - } - - switch (function) - { - case COGL_PIPELINE_COMBINE_FUNC_ADD: - g_string_append_printf (shader_state->source, - "ADD_SAT output%s, ", - mask_name); - break; - case COGL_PIPELINE_COMBINE_FUNC_MODULATE: - /* Note: no need to saturate since we can assume operands - * have values in the range [0,1] */ - g_string_append_printf (shader_state->source, "MUL output%s, ", - mask_name); - break; - case COGL_PIPELINE_COMBINE_FUNC_REPLACE: - /* Note: no need to saturate since we can assume operand - * has a value in the range [0,1] */ - g_string_append_printf (shader_state->source, "MOV output%s, ", - mask_name); - break; - case COGL_PIPELINE_COMBINE_FUNC_SUBTRACT: - g_string_append_printf (shader_state->source, - "SUB_SAT output%s, ", - mask_name); - break; - case COGL_PIPELINE_COMBINE_FUNC_ADD_SIGNED: - g_string_append_printf (shader_state->source, "ADD tmp3%s, ", - mask_name); - append_arg (shader_state->source, &args[0]); - g_string_append (shader_state->source, ", "); - append_arg (shader_state->source, &args[1]); - g_string_append (shader_state->source, ";\n"); - g_string_append_printf (shader_state->source, - "SUB_SAT output%s, tmp3, half", - mask_name); - n_args = 0; - break; - case COGL_PIPELINE_COMBINE_FUNC_DOT3_RGB: - /* These functions are the same except that GL_DOT3_RGB never - * updates the alpha channel. - * - * NB: GL_DOT3_RGBA is a bit special because it effectively forces - * an RGBA mask and we end up ignoring any separate alpha channel - * function. - */ - case COGL_PIPELINE_COMBINE_FUNC_DOT3_RGBA: - { - const char *tmp4 = "tmp4"; - - /* The maths for this was taken from Mesa; - * apparently: - * - * tmp3 = 2*src0 - 1 - * tmp4 = 2*src1 - 1 - * output = DP3 (tmp3, tmp4) - * - * is the same as: - * - * output = 4 * DP3 (src0 - 0.5, src1 - 0.5) - */ - - g_string_append (shader_state->source, "MAD tmp3, two, "); - append_arg (shader_state->source, &args[0]); - g_string_append (shader_state->source, ", minus_one;\n"); - - if (!fragend_arbfp_args_equal (&args[0], &args[1])) - { - g_string_append (shader_state->source, "MAD tmp4, two, "); - append_arg (shader_state->source, &args[1]); - g_string_append (shader_state->source, ", minus_one;\n"); - } - else - tmp4 = "tmp3"; - - g_string_append_printf (shader_state->source, - "DP3_SAT output%s, tmp3, %s", - mask_name, tmp4); - n_args = 0; - } - break; - case COGL_PIPELINE_COMBINE_FUNC_INTERPOLATE: - /* Note: no need to saturate since we can assume operands - * have values in the range [0,1] */ - - /* NB: GL_INTERPOLATE = arg0*arg2 + arg1*(1-arg2) - * but LRP dst, a, b, c = b*a + c*(1-a) */ - g_string_append_printf (shader_state->source, "LRP output%s, ", - mask_name); - append_arg (shader_state->source, &args[2]); - g_string_append (shader_state->source, ", "); - append_arg (shader_state->source, &args[0]); - g_string_append (shader_state->source, ", "); - append_arg (shader_state->source, &args[1]); - n_args = 0; - break; - default: - g_error ("Unknown texture combine function %d", function); - g_string_append_printf (shader_state->source, "MUL_SAT output%s, ", - mask_name); - n_args = 2; - break; - } - - if (n_args > 0) - append_arg (shader_state->source, &args[0]); - if (n_args > 1) - { - g_string_append (shader_state->source, ", "); - append_arg (shader_state->source, &args[1]); - } - g_string_append (shader_state->source, ";\n"); -} - -static void -append_masked_combine (CoglPipeline *arbfp_authority, - CoglPipelineLayer *layer, - CoglBlendStringChannelMask mask, - CoglPipelineCombineFunc function, - CoglPipelineCombineSource *src, - CoglPipelineCombineOp *op) -{ - int i; - int n_args; - CoglPipelineFragendARBfpArg args[3]; - - n_args = _cogl_get_n_args_for_combine_func (function); - - for (i = 0; i < n_args; i++) - { - setup_arg (arbfp_authority, - layer, - mask, - i, - src[i], - op[i], - &args[i]); - } - - append_function (arbfp_authority, - mask, - function, - args, - n_args); -} - -static CoglBool -_cogl_pipeline_fragend_arbfp_add_layer (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - unsigned long layers_difference) -{ - CoglPipelineShaderState *shader_state = get_shader_state (pipeline); - CoglPipelineLayer *combine_authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_COMBINE); - CoglPipelineLayerBigState *big_state = combine_authority->big_state; - - /* Notes... - * - * We are ignoring the issue of texture indirection limits until - * someone complains (Ref Section 3.11.6 in the ARB_fragment_program - * spec) - * - * There always five TEMPs named tmp0, tmp1 and tmp2, tmp3 and tmp4 - * available and these constants: 'one' = {1, 1, 1, 1}, 'half' - * {.5, .5, .5, .5}, 'two' = {2, 2, 2, 2}, 'minus_one' = {-1, -1, - * -1, -1} - * - * tmp0-2 are intended for dealing with some of the texture combine - * operands (e.g. GL_ONE_MINUS_SRC_COLOR) tmp3/4 are for dealing - * with the GL_ADD_SIGNED texture combine and the GL_DOT3_RGB[A] - * functions. - * - * Each layer outputs to the TEMP called "output", and reads from - * output if it needs to refer to GL_PREVIOUS. (we detect if we are - * layer0 so we will read fragment.color for GL_PREVIOUS in that - * case) - * - * We aim to do all the channels together if the same function is - * used for RGB as for A. - * - * We aim to avoid string duplication / allocations during codegen. - * - * We are careful to only saturate when writing to output. - */ - - if (!shader_state->source) - return TRUE; - - if (!_cogl_pipeline_layer_needs_combine_separate (combine_authority)) - { - append_masked_combine (pipeline, - layer, - COGL_BLEND_STRING_CHANNEL_MASK_RGBA, - big_state->texture_combine_rgb_func, - big_state->texture_combine_rgb_src, - big_state->texture_combine_rgb_op); - } - else if (big_state->texture_combine_rgb_func == - COGL_PIPELINE_COMBINE_FUNC_DOT3_RGBA) - { - /* GL_DOT3_RGBA Is a bit weird as a GL_COMBINE_RGB function - * since if you use it, it overrides your ALPHA function... - */ - append_masked_combine (pipeline, - layer, - COGL_BLEND_STRING_CHANNEL_MASK_RGBA, - big_state->texture_combine_rgb_func, - big_state->texture_combine_rgb_src, - big_state->texture_combine_rgb_op); - } - else - { - append_masked_combine (pipeline, - layer, - COGL_BLEND_STRING_CHANNEL_MASK_RGB, - big_state->texture_combine_rgb_func, - big_state->texture_combine_rgb_src, - big_state->texture_combine_rgb_op); - append_masked_combine (pipeline, - layer, - COGL_BLEND_STRING_CHANNEL_MASK_ALPHA, - big_state->texture_combine_alpha_func, - big_state->texture_combine_alpha_src, - big_state->texture_combine_alpha_op); - } - - return TRUE; -} - -static CoglBool -_cogl_pipeline_fragend_arbfp_passthrough (CoglPipeline *pipeline) -{ - CoglPipelineShaderState *shader_state = get_shader_state (pipeline); - - if (!shader_state->source) - return TRUE; - - g_string_append (shader_state->source, - "MOV output, fragment.color.primary;\n"); - return TRUE; -} - -typedef struct _UpdateConstantsState -{ - int unit; - CoglBool update_all; - CoglPipelineShaderState *shader_state; -} UpdateConstantsState; - -static CoglBool -update_constants_cb (CoglPipeline *pipeline, - int layer_index, - void *user_data) -{ - UpdateConstantsState *state = user_data; - CoglPipelineShaderState *shader_state = state->shader_state; - UnitState *unit_state = &shader_state->unit_state[state->unit++]; - - _COGL_GET_CONTEXT (ctx, FALSE); - - if (unit_state->has_combine_constant && - (state->update_all || unit_state->dirty_combine_constant)) - { - float constant[4]; - _cogl_pipeline_get_layer_combine_constant (pipeline, - layer_index, - constant); - GE (ctx, glProgramLocalParameter4fv (GL_FRAGMENT_PROGRAM_ARB, - unit_state->constant_id, - constant)); - unit_state->dirty_combine_constant = FALSE; - } - return TRUE; -} - -static CoglBool -_cogl_pipeline_fragend_arbfp_end (CoglPipeline *pipeline, - unsigned long pipelines_difference) -{ - CoglPipelineShaderState *shader_state = get_shader_state (pipeline); - GLuint gl_program; - - _COGL_GET_CONTEXT (ctx, FALSE); - - if (shader_state->source) - { - COGL_STATIC_COUNTER (fragend_arbfp_compile_counter, - "arbfp compile counter", - "Increments each time a new ARBfp " - "program is compiled", - 0 /* no application private data */); - - COGL_COUNTER_INC (_cogl_uprof_context, fragend_arbfp_compile_counter); - - g_string_append (shader_state->source, - "MOV result.color,output;\n"); - g_string_append (shader_state->source, "END\n"); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_SHOW_SOURCE))) - g_message ("pipeline program:\n%s", shader_state->source->str); - - GE (ctx, glGenPrograms (1, &shader_state->gl_program)); - - GE (ctx, glBindProgram (GL_FRAGMENT_PROGRAM_ARB, - shader_state->gl_program)); - _cogl_gl_util_clear_gl_errors (ctx); - - ctx->glProgramString (GL_FRAGMENT_PROGRAM_ARB, - GL_PROGRAM_FORMAT_ASCII_ARB, - shader_state->source->len, - shader_state->source->str); - if (_cogl_gl_util_get_error (ctx) != GL_NO_ERROR) - { - g_warning ("\n%s\n%s", - shader_state->source->str, - ctx->glGetString (GL_PROGRAM_ERROR_STRING_ARB)); - } - - shader_state->source = NULL; - } - - if (shader_state->user_program != COGL_INVALID_HANDLE) - { - /* An arbfp program should contain exactly one shader which we - can use directly */ - CoglProgram *program = shader_state->user_program; - CoglShader *shader = program->attached_shaders->data; - - gl_program = shader->gl_handle; - } - else - gl_program = shader_state->gl_program; - - GE (ctx, glBindProgram (GL_FRAGMENT_PROGRAM_ARB, gl_program)); - _cogl_use_fragment_program (0, COGL_PIPELINE_PROGRAM_TYPE_ARBFP); - - if (shader_state->user_program == COGL_INVALID_HANDLE) - { - UpdateConstantsState state; - state.unit = 0; - state.shader_state = shader_state; - /* If this arbfp program was last used with a different pipeline - * then we need to ensure we update all program.local params */ - state.update_all = - pipeline != shader_state->last_used_for_pipeline; - cogl_pipeline_foreach_layer (pipeline, - update_constants_cb, - &state); - } - else - { - CoglProgram *program = shader_state->user_program; - CoglBool program_changed; - - /* If the shader has changed since it was last flushed then we - need to update all uniforms */ - program_changed = program->age != shader_state->user_program_age; - - _cogl_program_flush_uniforms (program, gl_program, program_changed); - - shader_state->user_program_age = program->age; - } - - /* We need to track what pipeline used this arbfp program last since - * we will need to update program.local params when switching - * between different pipelines. */ - shader_state->last_used_for_pipeline = pipeline; - - return TRUE; -} - -static void -_cogl_pipeline_fragend_arbfp_pipeline_pre_change_notify ( - CoglPipeline *pipeline, - CoglPipelineState change, - const CoglColor *new_color) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if ((change & _cogl_pipeline_get_state_for_fragment_codegen (ctx))) - dirty_shader_state (pipeline); -} - -/* NB: layers are considered immutable once they have any dependants - * so although multiple pipelines can end up depending on a single - * static layer, we can guarantee that if a layer is being *changed* - * then it can only have one pipeline depending on it. - * - * XXX: Don't forget this is *pre* change, we can't read the new value - * yet! - */ -static void -_cogl_pipeline_fragend_arbfp_layer_pre_change_notify ( - CoglPipeline *owner, - CoglPipelineLayer *layer, - CoglPipelineLayerState change) -{ - CoglPipelineShaderState *shader_state = get_shader_state (owner); - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (!shader_state) - return; - - if ((change & _cogl_pipeline_get_layer_state_for_fragment_codegen (ctx))) - { - dirty_shader_state (owner); - return; - } - - if (change & COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT) - { - int unit_index = _cogl_pipeline_layer_get_unit_index (layer); - shader_state->unit_state[unit_index].dirty_combine_constant = TRUE; - } - - /* TODO: we could be saving snippets of texture combine code along - * with each layer and then when a layer changes we would just free - * the snippet. */ - return; -} - -const CoglPipelineFragend _cogl_pipeline_arbfp_fragend = -{ - _cogl_pipeline_fragend_arbfp_start, - _cogl_pipeline_fragend_arbfp_add_layer, - _cogl_pipeline_fragend_arbfp_passthrough, - _cogl_pipeline_fragend_arbfp_end, - _cogl_pipeline_fragend_arbfp_pipeline_pre_change_notify, - NULL, - _cogl_pipeline_fragend_arbfp_layer_pre_change_notify -}; - -#endif /* COGL_PIPELINE_FRAGEND_ARBFP */ - diff --git a/cogl/cogl/driver/gl/gl/cogl-pipeline-progend-fixed-arbfp-private.h b/cogl/cogl/driver/gl/gl/cogl-pipeline-progend-fixed-arbfp-private.h deleted file mode 100644 index ba0c713cd..000000000 --- a/cogl/cogl/driver/gl/gl/cogl-pipeline-progend-fixed-arbfp-private.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts - */ - -#ifndef __COGL_PIPELINE_PROGEND_FIXED_ARBFP_PRIVATE_H -#define __COGL_PIPELINE_PROGEND_FIXED_ARBFP_PRIVATE_H - -#include "cogl-pipeline-private.h" - -extern const CoglPipelineProgend _cogl_pipeline_fixed_arbfp_progend; - -#endif /* __COGL_PIPELINE_PROGEND_FIXED_ARBFP_PRIVATE_H */ - diff --git a/cogl/cogl/driver/gl/gl/cogl-pipeline-progend-fixed-arbfp.c b/cogl/cogl/driver/gl/gl/cogl-pipeline-progend-fixed-arbfp.c deleted file mode 100644 index ac7950084..000000000 --- a/cogl/cogl/driver/gl/gl/cogl-pipeline-progend-fixed-arbfp.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - */ - -#ifdef HAVE_CONFIG_H -#include "cogl-config.h" -#endif - -#include - -#include "cogl-pipeline-private.h" -#include "cogl-pipeline-state-private.h" - -#ifdef COGL_PIPELINE_PROGEND_FIXED_ARBFP - -#include "cogl-context.h" -#include "cogl-context-private.h" -#include "cogl-framebuffer-private.h" -#include "cogl-program-private.h" - -static CoglBool -_cogl_pipeline_progend_fixed_arbfp_start (CoglPipeline *pipeline) -{ - CoglHandle user_program; - - _COGL_GET_CONTEXT (ctx, FALSE); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_FIXED))) - return FALSE; - - if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_FIXED)) - return FALSE; - - /* Vertex snippets are only supported in the GLSL fragend */ - if (_cogl_pipeline_has_vertex_snippets (pipeline)) - return FALSE; - - /* Validate that we can handle the fragment state using ARBfp - */ - - if (!cogl_has_feature (ctx, COGL_FEATURE_ID_ARBFP)) - return FALSE; - - /* Fragment snippets are only supported in the GLSL fragend */ - if (_cogl_pipeline_has_fragment_snippets (pipeline)) - return FALSE; - - user_program = cogl_pipeline_get_user_program (pipeline); - if (user_program && - _cogl_program_get_language (user_program) != COGL_SHADER_LANGUAGE_ARBFP) - return FALSE; - - /* The ARBfp progend can't handle the per-vertex point size - * attribute */ - if (cogl_pipeline_get_per_vertex_point_size (pipeline)) - return FALSE; - - return TRUE; -} - -static void -_cogl_pipeline_progend_fixed_arbfp_pre_paint (CoglPipeline *pipeline, - CoglFramebuffer *framebuffer) -{ - CoglContext *ctx = framebuffer->context; - - if (ctx->current_projection_entry) - _cogl_matrix_entry_flush_to_gl_builtins (ctx, - ctx->current_projection_entry, - COGL_MATRIX_PROJECTION, - framebuffer, - FALSE /* enable flip */); - if (ctx->current_modelview_entry) - _cogl_matrix_entry_flush_to_gl_builtins (ctx, - ctx->current_modelview_entry, - COGL_MATRIX_MODELVIEW, - framebuffer, - FALSE /* enable flip */); -} - -const CoglPipelineProgend _cogl_pipeline_fixed_arbfp_progend = - { - COGL_PIPELINE_VERTEND_FIXED, - COGL_PIPELINE_FRAGEND_ARBFP, - _cogl_pipeline_progend_fixed_arbfp_start, - NULL, /* end */ - NULL, /* pre_change_notify */ - NULL, /* layer_pre_change_notify */ - _cogl_pipeline_progend_fixed_arbfp_pre_paint - }; - -#endif /* COGL_PIPELINE_PROGEND_FIXED_ARBFP */ diff --git a/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c b/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c index 036b04c3d..35c10c2d6 100644 --- a/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c +++ b/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c @@ -33,9 +33,7 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-private.h" #include "cogl-util.h" @@ -45,11 +43,10 @@ #include "cogl-pipeline.h" #include "cogl-context-private.h" #include "cogl-object-private.h" -#include "cogl-primitives.h" -#include "cogl-pipeline-opengl-private.h" -#include "cogl-util-gl-private.h" -#include "cogl-error-private.h" -#include "cogl-texture-gl-private.h" +#include "driver/gl/cogl-pipeline-opengl-private.h" +#include "driver/gl/cogl-util-gl-private.h" +#include "driver/gl/cogl-texture-gl-private.h" +#include "driver/gl/cogl-bitmap-gl-private.h" #include #include @@ -68,12 +65,11 @@ _cogl_texture_driver_gen (CoglContext *ctx, GE (ctx, glGenTextures (1, &tex)); - _cogl_bind_gl_texture_transient (gl_target, tex, FALSE); + _cogl_bind_gl_texture_transient (gl_target, tex); switch (gl_target) { case GL_TEXTURE_2D: - case GL_TEXTURE_3D: /* In case automatic mipmap generation gets disabled for this * texture but a minification filter depending on mipmap * interpolation is selected then we initialize the max mipmap @@ -114,18 +110,6 @@ _cogl_texture_driver_gen (CoglContext *ctx, red_swizzle) ); } - /* If swizzle extension is available, prefer it to flip bgra buffers to rgba */ - if ((internal_format == COGL_PIXEL_FORMAT_BGRA_8888 || - internal_format == COGL_PIXEL_FORMAT_BGRA_8888_PRE) && - _cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE)) - { - static const GLint bgra_swizzle[] = { GL_BLUE, GL_GREEN, GL_RED, GL_ALPHA }; - - GE( ctx, glTexParameteriv (gl_target, - GL_TEXTURE_SWIZZLE_RGBA, - bgra_swizzle) ); - } - return tex; } @@ -145,20 +129,9 @@ prep_gl_for_pixels_upload_full (CoglContext *ctx, GE( ctx, glPixelStorei (GL_UNPACK_SKIP_PIXELS, pixels_src_x) ); GE( ctx, glPixelStorei (GL_UNPACK_SKIP_ROWS, pixels_src_y) ); - if (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_3D)) - GE( ctx, glPixelStorei (GL_UNPACK_IMAGE_HEIGHT, image_height) ); - _cogl_texture_gl_prep_alignment_for_pixels_upload (ctx, pixels_rowstride); } -static void -_cogl_texture_driver_prep_gl_for_pixels_upload (CoglContext *ctx, - int pixels_rowstride, - int pixels_bpp) -{ - prep_gl_for_pixels_upload_full (ctx, pixels_rowstride, 0, 0, 0, pixels_bpp); -} - /* OpenGL - unlike GLES - can download pixel data into a sub region of * a larger destination buffer */ static void @@ -175,9 +148,6 @@ prep_gl_for_pixels_download_full (CoglContext *ctx, GE( ctx, glPixelStorei (GL_PACK_SKIP_PIXELS, pixels_src_x) ); GE( ctx, glPixelStorei (GL_PACK_SKIP_ROWS, pixels_src_y) ); - if (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_3D)) - GE( ctx, glPixelStorei (GL_PACK_IMAGE_HEIGHT, image_height) ); - _cogl_texture_gl_prep_alignment_for_pixels_download (ctx, pixels_bpp, image_width, @@ -198,10 +168,9 @@ _cogl_texture_driver_prep_gl_for_pixels_download (CoglContext *ctx, pixels_bpp); } -static CoglBool +static gboolean _cogl_texture_driver_upload_subregion_to_gl (CoglContext *ctx, CoglTexture *texture, - CoglBool is_foreign, int src_x, int src_y, int dst_x, @@ -212,18 +181,23 @@ _cogl_texture_driver_upload_subregion_to_gl (CoglContext *ctx, CoglBitmap *source_bmp, GLuint source_gl_format, GLuint source_gl_type, - CoglError **error) + GError **error) { GLenum gl_target; GLuint gl_handle; uint8_t *data; CoglPixelFormat source_format = cogl_bitmap_get_format (source_bmp); - int bpp = _cogl_pixel_format_get_bytes_per_pixel (source_format); - CoglBool status = TRUE; - CoglError *internal_error = NULL; + int bpp; + gboolean status = TRUE; + GError *internal_error = NULL; int level_width; int level_height; + g_return_val_if_fail (source_format != COGL_PIXEL_FORMAT_ANY, FALSE); + g_return_val_if_fail (cogl_pixel_format_get_n_planes (source_format) == 1, + FALSE); + + bpp = cogl_pixel_format_get_bytes_per_pixel (source_format, 0); cogl_texture_get_gl_texture (texture, &gl_handle, &gl_target); data = _cogl_bitmap_gl_bind (source_bmp, COGL_BUFFER_ACCESS_READ, 0, &internal_error); @@ -233,7 +207,7 @@ _cogl_texture_driver_upload_subregion_to_gl (CoglContext *ctx, * problems... */ if (internal_error) { - _cogl_propagate_error (error, internal_error); + g_propagate_error (error, internal_error); return FALSE; } @@ -245,7 +219,7 @@ _cogl_texture_driver_upload_subregion_to_gl (CoglContext *ctx, src_y, bpp); - _cogl_bind_gl_texture_transient (gl_target, gl_handle, is_foreign); + _cogl_bind_gl_texture_transient (gl_target, gl_handle); /* Clear any GL errors */ _cogl_gl_util_clear_gl_errors (ctx); @@ -281,7 +255,7 @@ _cogl_texture_driver_upload_subregion_to_gl (CoglContext *ctx, * glTexImage2D first to assert that the storage for this * level exists. */ - if (texture->max_level < level) + if (texture->max_level_set < level) { ctx->glTexImage2D (gl_target, level, @@ -311,22 +285,27 @@ _cogl_texture_driver_upload_subregion_to_gl (CoglContext *ctx, return status; } -static CoglBool +static gboolean _cogl_texture_driver_upload_to_gl (CoglContext *ctx, GLenum gl_target, GLuint gl_handle, - CoglBool is_foreign, CoglBitmap *source_bmp, GLint internal_gl_format, GLuint source_gl_format, GLuint source_gl_type, - CoglError **error) + GError **error) { uint8_t *data; CoglPixelFormat source_format = cogl_bitmap_get_format (source_bmp); - int bpp = _cogl_pixel_format_get_bytes_per_pixel (source_format); - CoglBool status = TRUE; - CoglError *internal_error = NULL; + int bpp; + gboolean status = TRUE; + GError *internal_error = NULL; + + g_return_val_if_fail (source_format != COGL_PIXEL_FORMAT_ANY, FALSE); + g_return_val_if_fail (cogl_pixel_format_get_n_planes (source_format) == 1, + FALSE); + + bpp = cogl_pixel_format_get_bytes_per_pixel (source_format, 0); data = _cogl_bitmap_gl_bind (source_bmp, COGL_BUFFER_ACCESS_READ, @@ -338,7 +317,7 @@ _cogl_texture_driver_upload_to_gl (CoglContext *ctx, * problems... */ if (internal_error) { - _cogl_propagate_error (error, internal_error); + g_propagate_error (error, internal_error); return FALSE; } @@ -347,7 +326,7 @@ _cogl_texture_driver_upload_to_gl (CoglContext *ctx, cogl_bitmap_get_rowstride (source_bmp), 0, 0, 0, bpp); - _cogl_bind_gl_texture_transient (gl_target, gl_handle, is_foreign); + _cogl_bind_gl_texture_transient (gl_target, gl_handle); /* Clear any GL errors */ _cogl_gl_util_clear_gl_errors (ctx); @@ -369,60 +348,7 @@ _cogl_texture_driver_upload_to_gl (CoglContext *ctx, return status; } -static CoglBool -_cogl_texture_driver_upload_to_gl_3d (CoglContext *ctx, - GLenum gl_target, - GLuint gl_handle, - CoglBool is_foreign, - GLint height, - GLint depth, - CoglBitmap *source_bmp, - GLint internal_gl_format, - GLuint source_gl_format, - GLuint source_gl_type, - CoglError **error) -{ - uint8_t *data; - CoglPixelFormat source_format = cogl_bitmap_get_format (source_bmp); - int bpp = _cogl_pixel_format_get_bytes_per_pixel (source_format); - CoglBool status = TRUE; - - data = _cogl_bitmap_gl_bind (source_bmp, COGL_BUFFER_ACCESS_READ, 0, error); - if (!data) - return FALSE; - - /* Setup gl alignment to match rowstride and top-left corner */ - prep_gl_for_pixels_upload_full (ctx, - cogl_bitmap_get_rowstride (source_bmp), - (cogl_bitmap_get_height (source_bmp) / - depth), - 0, 0, bpp); - - _cogl_bind_gl_texture_transient (gl_target, gl_handle, is_foreign); - - /* Clear any GL errors */ - _cogl_gl_util_clear_gl_errors (ctx); - - ctx->glTexImage3D (gl_target, - 0, /* level */ - internal_gl_format, - cogl_bitmap_get_width (source_bmp), - height, - depth, - 0, - source_gl_format, - source_gl_type, - data); - - if (_cogl_gl_util_catch_out_of_memory (ctx, error)) - status = FALSE; - - _cogl_bitmap_gl_unbind (source_bmp); - - return status; -} - -static CoglBool +static gboolean _cogl_texture_driver_gl_get_tex_image (CoglContext *ctx, GLenum gl_target, GLenum dest_gl_format, @@ -437,36 +363,7 @@ _cogl_texture_driver_gl_get_tex_image (CoglContext *ctx, return TRUE; } -static CoglBool -_cogl_texture_driver_size_supported_3d (CoglContext *ctx, - GLenum gl_target, - GLenum gl_format, - GLenum gl_type, - int width, - int height, - int depth) -{ - GLenum proxy_target; - GLint new_width = 0; - - if (gl_target == GL_TEXTURE_3D) - proxy_target = GL_PROXY_TEXTURE_3D; - else - /* Unknown target, assume it's not supported */ - return FALSE; - - /* Proxy texture allows for a quick check for supported size */ - GE( ctx, glTexImage3D (proxy_target, 0, GL_RGBA, - width, height, depth, 0 /* border */, - gl_format, gl_type, NULL) ); - - GE( ctx, glGetTexLevelParameteriv (proxy_target, 0, - GL_TEXTURE_WIDTH, &new_width) ); - - return new_width != 0; -} - -static CoglBool +static gboolean _cogl_texture_driver_size_supported (CoglContext *ctx, GLenum gl_target, GLenum gl_intformat, @@ -480,7 +377,7 @@ _cogl_texture_driver_size_supported (CoglContext *ctx, if (gl_target == GL_TEXTURE_2D) proxy_target = GL_PROXY_TEXTURE_2D; -#if HAVE_COGL_GL +#ifdef HAVE_COGL_GL else if (gl_target == GL_TEXTURE_RECTANGLE_ARB) proxy_target = GL_PROXY_TEXTURE_RECTANGLE_ARB; #endif @@ -499,65 +396,28 @@ _cogl_texture_driver_size_supported (CoglContext *ctx, return new_width != 0; } -static void -_cogl_texture_driver_try_setting_gl_border_color - (CoglContext *ctx, - GLuint gl_target, - const GLfloat *transparent_color) -{ - /* Use a transparent border color so that we can leave the - color buffer alone when using texture co-ordinates - outside of the texture */ - GE( ctx, glTexParameterfv (gl_target, GL_TEXTURE_BORDER_COLOR, - transparent_color) ); -} - -static CoglBool -_cogl_texture_driver_allows_foreign_gl_target (CoglContext *ctx, - GLenum gl_target) -{ - /* GL_ARB_texture_rectangle textures are supported if they are - created from foreign because some chipsets have trouble with - GL_ARB_texture_non_power_of_two. There is no Cogl call to create - them directly to emphasize the fact that they don't work fully - (for example, no mipmapping and complicated shader support) */ - - /* Allow 2-dimensional or rectangle textures only */ - if (gl_target != GL_TEXTURE_2D && gl_target != GL_TEXTURE_RECTANGLE_ARB) - return FALSE; - - return TRUE; -} - static CoglPixelFormat _cogl_texture_driver_find_best_gl_get_data_format (CoglContext *context, CoglPixelFormat format, - CoglPixelFormat target_format, GLenum *closest_gl_format, GLenum *closest_gl_type) { - return context->driver_vtable->pixel_format_to_gl_with_target (context, - format, - target_format, - NULL, /* don't need */ - closest_gl_format, - closest_gl_type); + return context->driver_vtable->pixel_format_to_gl (context, + format, + NULL, /* don't need */ + closest_gl_format, + closest_gl_type); } const CoglTextureDriver _cogl_texture_driver_gl = { _cogl_texture_driver_gen, - _cogl_texture_driver_prep_gl_for_pixels_upload, _cogl_texture_driver_upload_subregion_to_gl, _cogl_texture_driver_upload_to_gl, - _cogl_texture_driver_upload_to_gl_3d, _cogl_texture_driver_prep_gl_for_pixels_download, _cogl_texture_driver_gl_get_tex_image, _cogl_texture_driver_size_supported, - _cogl_texture_driver_size_supported_3d, - _cogl_texture_driver_try_setting_gl_border_color, - _cogl_texture_driver_allows_foreign_gl_target, _cogl_texture_driver_find_best_gl_get_data_format }; diff --git a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c index 86fbd0101..ca98823e8 100644 --- a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c +++ b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c @@ -28,22 +28,20 @@ * */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include #include "cogl-context-private.h" -#include "cogl-util-gl-private.h" #include "cogl-feature-private.h" #include "cogl-renderer-private.h" #include "cogl-private.h" -#include "cogl-framebuffer-gl-private.h" -#include "cogl-texture-2d-gl-private.h" -#include "cogl-attribute-gl-private.h" -#include "cogl-clip-stack-gl-private.h" -#include "cogl-buffer-gl-private.h" +#include "driver/gl/cogl-util-gl-private.h" +#include "driver/gl/cogl-framebuffer-gl-private.h" +#include "driver/gl/cogl-texture-2d-gl-private.h" +#include "driver/gl/cogl-attribute-gl-private.h" +#include "driver/gl/cogl-clip-stack-gl-private.h" +#include "driver/gl/cogl-buffer-gl-private.h" #ifndef GL_UNSIGNED_INT_24_8 #define GL_UNSIGNED_INT_24_8 0x84FA @@ -58,7 +56,7 @@ #define GL_RG8 0x822B #endif -static CoglBool +static gboolean _cogl_driver_pixel_format_from_gl_internal (CoglContext *context, GLenum gl_int_format, CoglPixelFormat *out_format) @@ -67,12 +65,11 @@ _cogl_driver_pixel_format_from_gl_internal (CoglContext *context, } static CoglPixelFormat -_cogl_driver_pixel_format_to_gl_with_target (CoglContext *context, - CoglPixelFormat format, - CoglPixelFormat target_format, - GLenum *out_glintformat, - GLenum *out_glformat, - GLenum *out_gltype) +_cogl_driver_pixel_format_to_gl (CoglContext *context, + CoglPixelFormat format, + GLenum *out_glintformat, + GLenum *out_glformat, + GLenum *out_gltype) { CoglPixelFormat required_format; GLenum glintformat; @@ -220,21 +217,7 @@ _cogl_driver_pixel_format_to_gl_with_target (CoglContext *context, return required_format; } -static CoglPixelFormat -_cogl_driver_pixel_format_to_gl (CoglContext *context, - CoglPixelFormat format, - GLenum *out_glintformat, - GLenum *out_glformat, - GLenum *out_gltype) -{ - return _cogl_driver_pixel_format_to_gl_with_target (context, - format, format, - out_glintformat, - out_glformat, - out_gltype); -} - -static CoglBool +static gboolean _cogl_get_gl_version (CoglContext *ctx, int *major_out, int *minor_out) @@ -253,13 +236,12 @@ _cogl_get_gl_version (CoglContext *ctx, minor_out); } -static CoglBool +static gboolean _cogl_driver_update_features (CoglContext *context, - CoglError **error) + GError **error) { unsigned long private_features [COGL_FLAGS_N_LONGS_FOR_SIZE (COGL_N_PRIVATE_FEATURES)] = { 0 }; - CoglFeatureFlags flags = 0; char **gl_extensions; int gl_major, gl_minor; int i; @@ -271,6 +253,10 @@ _cogl_driver_update_features (CoglContext *context, (void *) _cogl_renderer_get_proc_address (context->display->renderer, "glGetString", TRUE); + context->glGetStringi = + (void *) _cogl_renderer_get_proc_address (context->display->renderer, + "glGetStringi", + TRUE); gl_extensions = _cogl_context_get_gl_extensions (context); @@ -289,7 +275,7 @@ _cogl_driver_update_features (CoglContext *context, _cogl_context_get_gl_version (context), all_extensions); - free (all_extensions); + g_free (all_extensions); } context->glsl_major = 1; @@ -304,117 +290,47 @@ _cogl_driver_update_features (CoglContext *context, gl_minor = 1; } + if (!COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 0)) + { + g_set_error (error, + COGL_DRIVER_ERROR, + COGL_DRIVER_ERROR_INVALID_VERSION, + "OpenGL ES 2.0 or better is required"); + return FALSE; + } + _cogl_feature_check_ext_functions (context, gl_major, gl_minor, gl_extensions); -#ifdef HAVE_COGL_GLES - if (context->driver == COGL_DRIVER_GLES1) - { - int max_clip_planes; - GE( context, glGetIntegerv (GL_MAX_CLIP_PLANES, &max_clip_planes) ); - if (max_clip_planes >= 4) - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_FOUR_CLIP_PLANES, TRUE); - } -#endif - - if (context->driver == COGL_DRIVER_GLES2) - { - flags |= COGL_FEATURE_SHADERS_GLSL | COGL_FEATURE_OFFSCREEN; - /* Note GLES 2 core doesn't support mipmaps for npot textures or - * repeat modes other than CLAMP_TO_EDGE. */ - flags |= COGL_FEATURE_TEXTURE_NPOT_BASIC; - flags |= COGL_FEATURE_DEPTH_RANGE; - COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_GLSL, TRUE); - COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_OFFSCREEN, TRUE); - COGL_FLAGS_SET (context->features, - COGL_FEATURE_ID_TEXTURE_NPOT_BASIC, TRUE); - COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_DEPTH_RANGE, TRUE); - COGL_FLAGS_SET (context->features, - COGL_FEATURE_ID_MIRRORED_REPEAT, TRUE); - COGL_FLAGS_SET (context->features, - COGL_FEATURE_ID_PER_VERTEX_POINT_SIZE, TRUE); + if (_cogl_check_extension ("GL_ANGLE_pack_reverse_row_order", gl_extensions)) + COGL_FLAGS_SET (private_features, + COGL_PRIVATE_FEATURE_MESA_PACK_INVERT, TRUE); - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_BLEND_CONSTANT, TRUE); - } - else if (context->driver == COGL_DRIVER_GLES1) - { - COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_GL_FIXED, TRUE); - COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_ALPHA_TEST, TRUE); - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM, TRUE); - } + /* Note GLES 2 core doesn't support mipmaps for npot textures or + * repeat modes other than CLAMP_TO_EDGE. */ - COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_VBOS, TRUE); COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_ANY_GL, TRUE); COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_ALPHA_TEXTURES, TRUE); - /* Both GLES 1.1 and GLES 2.0 support point sprites in core */ - flags |= COGL_FEATURE_POINT_SPRITE; - COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_POINT_SPRITE, TRUE); - - if (context->glGenRenderbuffers) - { - flags |= COGL_FEATURE_OFFSCREEN; - COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_OFFSCREEN, TRUE); - } + if (context->glGenSamplers) + COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS, TRUE); if (context->glBlitFramebuffer) COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT, TRUE); + COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER, TRUE); if (_cogl_check_extension ("GL_OES_element_index_uint", gl_extensions)) { - flags |= COGL_FEATURE_UNSIGNED_INT_INDICES; COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_UNSIGNED_INT_INDICES, TRUE); } - if (_cogl_check_extension ("GL_OES_depth_texture", gl_extensions)) - { - flags |= COGL_FEATURE_DEPTH_TEXTURE; - COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_DEPTH_TEXTURE, TRUE); - } - - if (_cogl_check_extension ("GL_OES_texture_npot", gl_extensions)) - { - flags |= (COGL_FEATURE_TEXTURE_NPOT | - COGL_FEATURE_TEXTURE_NPOT_BASIC | - COGL_FEATURE_TEXTURE_NPOT_MIPMAP | - COGL_FEATURE_TEXTURE_NPOT_REPEAT); - COGL_FLAGS_SET (context->features, - COGL_FEATURE_ID_TEXTURE_NPOT, TRUE); - COGL_FLAGS_SET (context->features, - COGL_FEATURE_ID_TEXTURE_NPOT_BASIC, TRUE); - COGL_FLAGS_SET (context->features, - COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP, TRUE); - COGL_FLAGS_SET (context->features, - COGL_FEATURE_ID_TEXTURE_NPOT_REPEAT, TRUE); - } - else if (_cogl_check_extension ("GL_IMG_texture_npot", gl_extensions)) - { - flags |= (COGL_FEATURE_TEXTURE_NPOT_BASIC | - COGL_FEATURE_TEXTURE_NPOT_MIPMAP); - COGL_FLAGS_SET (context->features, - COGL_FEATURE_ID_TEXTURE_NPOT_BASIC, TRUE); - COGL_FLAGS_SET (context->features, - COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP, TRUE); - } - - if (context->glTexImage3D) - { - flags |= COGL_FEATURE_TEXTURE_3D; - COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_TEXTURE_3D, TRUE); - } - if (context->glMapBuffer) { /* The GL_OES_mapbuffer extension doesn't support mapping for read */ - flags |= COGL_FEATURE_MAP_BUFFER_FOR_WRITE; COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE, TRUE); } @@ -422,8 +338,6 @@ _cogl_driver_update_features (CoglContext *context, if (context->glMapBufferRange) { /* MapBufferRange in ES3+ does support mapping for read */ - flags |= (COGL_FEATURE_MAP_BUFFER_FOR_WRITE | - COGL_FEATURE_MAP_BUFFER_FOR_READ); COGL_FLAGS_SET(context->features, COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE, TRUE); COGL_FLAGS_SET(context->features, @@ -452,6 +366,11 @@ _cogl_driver_update_features (CoglContext *context, _cogl_check_extension ("GL_OES_egl_sync", gl_extensions)) COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_OES_EGL_SYNC, TRUE); +#ifdef GL_ARB_sync + if (context->glFenceSync) + COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_FENCE, TRUE); +#endif + if (_cogl_check_extension ("GL_EXT_texture_rg", gl_extensions)) COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_TEXTURE_RG, @@ -460,19 +379,25 @@ _cogl_driver_update_features (CoglContext *context, /* Cache features */ for (i = 0; i < G_N_ELEMENTS (private_features); i++) context->private_features[i] |= private_features[i]; - context->feature_flags |= flags; g_strfreev (gl_extensions); return TRUE; } +static gboolean +_cogl_driver_texture_2d_is_get_data_supported (CoglTexture2D *tex_2d) +{ + return FALSE; +} + const CoglDriverVtable _cogl_driver_gles = { + _cogl_driver_gl_context_init, + _cogl_driver_gl_context_deinit, _cogl_driver_pixel_format_from_gl_internal, _cogl_driver_pixel_format_to_gl, - _cogl_driver_pixel_format_to_gl_with_target, _cogl_driver_update_features, _cogl_offscreen_gl_allocate, _cogl_offscreen_gl_free, @@ -480,6 +405,7 @@ _cogl_driver_gles = _cogl_framebuffer_gl_clear, _cogl_framebuffer_gl_query_bits, _cogl_framebuffer_gl_finish, + _cogl_framebuffer_gl_flush, _cogl_framebuffer_gl_discard_buffers, _cogl_framebuffer_gl_draw_attributes, _cogl_framebuffer_gl_draw_indexed_attributes, @@ -492,6 +418,7 @@ _cogl_driver_gles = _cogl_texture_2d_gl_get_gl_handle, _cogl_texture_2d_gl_generate_mipmap, _cogl_texture_2d_gl_copy_from_bitmap, + _cogl_driver_texture_2d_is_get_data_supported, NULL, /* texture_2d_get_data */ _cogl_gl_flush_attributes_state, _cogl_clip_stack_gl_flush, diff --git a/cogl/cogl/driver/gl/gles/cogl-texture-driver-gles.c b/cogl/cogl/driver/gl/gles/cogl-texture-driver-gles.c index 1f62ade67..f3cf3831e 100644 --- a/cogl/cogl/driver/gl/gles/cogl-texture-driver-gles.c +++ b/cogl/cogl/driver/gl/gles/cogl-texture-driver-gles.c @@ -33,9 +33,7 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-private.h" #include "cogl-util.h" @@ -43,13 +41,12 @@ #include "cogl-bitmap-private.h" #include "cogl-texture-private.h" #include "cogl-pipeline.h" -#include "cogl-pipeline-opengl-private.h" #include "cogl-context-private.h" #include "cogl-object-private.h" -#include "cogl-primitives.h" -#include "cogl-util-gl-private.h" -#include "cogl-error-private.h" -#include "cogl-texture-gl-private.h" +#include "driver/gl/cogl-pipeline-opengl-private.h" +#include "driver/gl/cogl-util-gl-private.h" +#include "driver/gl/cogl-texture-gl-private.h" +#include "driver/gl/cogl-bitmap-gl-private.h" #include #include @@ -83,7 +80,7 @@ _cogl_texture_driver_gen (CoglContext *ctx, GE (ctx, glGenTextures (1, &tex)); - _cogl_bind_gl_texture_transient (gl_target, tex, FALSE); + _cogl_bind_gl_texture_transient (gl_target, tex); switch (gl_target) { @@ -152,20 +149,25 @@ _cogl_texture_driver_prep_gl_for_pixels_download (CoglContext *ctx, static CoglBitmap * prepare_bitmap_alignment_for_upload (CoglContext *ctx, CoglBitmap *src_bmp, - CoglError **error) + GError **error) { CoglPixelFormat format = cogl_bitmap_get_format (src_bmp); - int bpp = _cogl_pixel_format_get_bytes_per_pixel (format); + int bpp; int src_rowstride = cogl_bitmap_get_rowstride (src_bmp); int width = cogl_bitmap_get_width (src_bmp); int alignment = 1; + g_return_val_if_fail (format != COGL_PIXEL_FORMAT_ANY, FALSE); + g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, FALSE); + + bpp = cogl_pixel_format_get_bytes_per_pixel (format, 0); + if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE) || src_rowstride == 0) return cogl_object_ref (src_bmp); /* Work out the alignment of the source rowstride */ - alignment = 1 << (_cogl_util_ffs (src_rowstride) - 1); + alignment = 1 << (ffs (src_rowstride) - 1); alignment = MIN (alignment, 8); /* If the aligned data equals the rowstride then we can upload from @@ -178,10 +180,9 @@ prepare_bitmap_alignment_for_upload (CoglContext *ctx, return _cogl_bitmap_copy (src_bmp, error); } -static CoglBool +static gboolean _cogl_texture_driver_upload_subregion_to_gl (CoglContext *ctx, CoglTexture *texture, - CoglBool is_foreign, int src_x, int src_y, int dst_x, @@ -192,20 +193,26 @@ _cogl_texture_driver_upload_subregion_to_gl (CoglContext *ctx, CoglBitmap *source_bmp, GLuint source_gl_format, GLuint source_gl_type, - CoglError **error) + GError **error) { GLenum gl_target; GLuint gl_handle; uint8_t *data; CoglPixelFormat source_format = cogl_bitmap_get_format (source_bmp); - int bpp = _cogl_pixel_format_get_bytes_per_pixel (source_format); + int bpp; CoglBitmap *slice_bmp; int rowstride; - CoglBool status = TRUE; - CoglError *internal_error = NULL; + gboolean status = TRUE; + GError *internal_error = NULL; int level_width; int level_height; + g_return_val_if_fail (source_format != COGL_PIXEL_FORMAT_ANY, FALSE); + g_return_val_if_fail (cogl_pixel_format_get_n_planes (source_format) == 1, + FALSE); + + bpp = cogl_pixel_format_get_bytes_per_pixel (source_format, 0); + cogl_texture_get_gl_texture (texture, &gl_handle, &gl_target); /* If we have the GL_EXT_unpack_subimage extension then we can @@ -256,12 +263,12 @@ _cogl_texture_driver_upload_subregion_to_gl (CoglContext *ctx, * problems... */ if (internal_error) { - _cogl_propagate_error (error, internal_error); + g_propagate_error (error, internal_error); cogl_object_unref (slice_bmp); return FALSE; } - _cogl_bind_gl_texture_transient (gl_target, gl_handle, is_foreign); + _cogl_bind_gl_texture_transient (gl_target, gl_handle); /* Clear any GL errors */ _cogl_gl_util_clear_gl_errors (ctx); @@ -296,7 +303,7 @@ _cogl_texture_driver_upload_subregion_to_gl (CoglContext *ctx, * glTexImage2D first to assert that the storage for this * level exists. */ - if (texture->max_level < level) + if (texture->max_level_set < level) { ctx->glTexImage2D (gl_target, level, @@ -328,26 +335,31 @@ _cogl_texture_driver_upload_subregion_to_gl (CoglContext *ctx, return status; } -static CoglBool +static gboolean _cogl_texture_driver_upload_to_gl (CoglContext *ctx, GLenum gl_target, GLuint gl_handle, - CoglBool is_foreign, CoglBitmap *source_bmp, GLint internal_gl_format, GLuint source_gl_format, GLuint source_gl_type, - CoglError **error) + GError **error) { CoglPixelFormat source_format = cogl_bitmap_get_format (source_bmp); - int bpp = _cogl_pixel_format_get_bytes_per_pixel (source_format); + int bpp; int rowstride; int bmp_width = cogl_bitmap_get_width (source_bmp); int bmp_height = cogl_bitmap_get_height (source_bmp); CoglBitmap *bmp; uint8_t *data; - CoglError *internal_error = NULL; - CoglBool status = TRUE; + GError *internal_error = NULL; + gboolean status = TRUE; + + g_return_val_if_fail (source_format != COGL_PIXEL_FORMAT_ANY, FALSE); + g_return_val_if_fail (cogl_pixel_format_get_n_planes (source_format) == 1, + FALSE); + + bpp = cogl_pixel_format_get_bytes_per_pixel (source_format, 0); bmp = prepare_bitmap_alignment_for_upload (ctx, source_bmp, error); if (!bmp) @@ -358,7 +370,7 @@ _cogl_texture_driver_upload_to_gl (CoglContext *ctx, /* Setup gl alignment to match rowstride and top-left corner */ _cogl_texture_driver_prep_gl_for_pixels_upload (ctx, rowstride, bpp); - _cogl_bind_gl_texture_transient (gl_target, gl_handle, is_foreign); + _cogl_bind_gl_texture_transient (gl_target, gl_handle); data = _cogl_bitmap_gl_bind (bmp, COGL_BUFFER_ACCESS_READ, @@ -371,7 +383,7 @@ _cogl_texture_driver_upload_to_gl (CoglContext *ctx, if (internal_error) { cogl_object_unref (bmp); - _cogl_propagate_error (error, internal_error); + g_propagate_error (error, internal_error); return FALSE; } @@ -396,156 +408,10 @@ _cogl_texture_driver_upload_to_gl (CoglContext *ctx, return status; } -static CoglBool -_cogl_texture_driver_upload_to_gl_3d (CoglContext *ctx, - GLenum gl_target, - GLuint gl_handle, - CoglBool is_foreign, - GLint height, - GLint depth, - CoglBitmap *source_bmp, - GLint internal_gl_format, - GLuint source_gl_format, - GLuint source_gl_type, - CoglError **error) -{ - CoglPixelFormat source_format = cogl_bitmap_get_format (source_bmp); - int bpp = _cogl_pixel_format_get_bytes_per_pixel (source_format); - int rowstride = cogl_bitmap_get_rowstride (source_bmp); - int bmp_width = cogl_bitmap_get_width (source_bmp); - int bmp_height = cogl_bitmap_get_height (source_bmp); - uint8_t *data; - - _cogl_bind_gl_texture_transient (gl_target, gl_handle, is_foreign); - - /* If the rowstride or image height can't be specified with just - GL_ALIGNMENT alone then we need to copy the bitmap because there - is no GL_ROW_LENGTH */ - if (rowstride / bpp != bmp_width || - height != bmp_height / depth) - { - CoglBitmap *bmp; - int image_height = bmp_height / depth; - CoglPixelFormat source_bmp_format = cogl_bitmap_get_format (source_bmp); - int i; - - _cogl_texture_driver_prep_gl_for_pixels_upload (ctx, bmp_width * bpp, bpp); - - /* Initialize the texture with empty data and then upload each - image with a sub-region update */ - - /* Clear any GL errors */ - _cogl_gl_util_clear_gl_errors (ctx); - - ctx->glTexImage3D (gl_target, - 0, /* level */ - internal_gl_format, - bmp_width, - height, - depth, - 0, - source_gl_format, - source_gl_type, - NULL); - - if (_cogl_gl_util_catch_out_of_memory (ctx, error)) - return FALSE; - - bmp = _cogl_bitmap_new_with_malloc_buffer (ctx, - bmp_width, - height, - source_bmp_format, - error); - if (!bmp) - return FALSE; - - for (i = 0; i < depth; i++) - { - if (!_cogl_bitmap_copy_subregion (source_bmp, - bmp, - 0, image_height * i, - 0, 0, - bmp_width, - height, - error)) - { - cogl_object_unref (bmp); - return FALSE; - } - - data = _cogl_bitmap_gl_bind (bmp, - COGL_BUFFER_ACCESS_READ, 0, error); - if (!data) - { - cogl_object_unref (bmp); - return FALSE; - } - - /* Clear any GL errors */ - _cogl_gl_util_clear_gl_errors (ctx); - - ctx->glTexSubImage3D (gl_target, - 0, /* level */ - 0, /* xoffset */ - 0, /* yoffset */ - i, /* zoffset */ - bmp_width, /* width */ - height, /* height */ - 1, /* depth */ - source_gl_format, - source_gl_type, - data); - - if (_cogl_gl_util_catch_out_of_memory (ctx, error)) - { - cogl_object_unref (bmp); - _cogl_bitmap_gl_unbind (bmp); - return FALSE; - } - - _cogl_bitmap_gl_unbind (bmp); - } - - cogl_object_unref (bmp); - } - else - { - data = _cogl_bitmap_gl_bind (source_bmp, COGL_BUFFER_ACCESS_READ, 0, error); - if (!data) - return FALSE; - - _cogl_texture_driver_prep_gl_for_pixels_upload (ctx, rowstride, bpp); - - /* Clear any GL errors */ - _cogl_gl_util_clear_gl_errors (ctx); - - ctx->glTexImage3D (gl_target, - 0, /* level */ - internal_gl_format, - bmp_width, - height, - depth, - 0, - source_gl_format, - source_gl_type, - data); - - if (_cogl_gl_util_catch_out_of_memory (ctx, error)) - { - _cogl_bitmap_gl_unbind (source_bmp); - return FALSE; - } - - _cogl_bitmap_gl_unbind (source_bmp); - } - - return TRUE; -} - /* NB: GLES doesn't support glGetTexImage2D, so cogl-texture will instead * fallback to a generic render + readpixels approach to downloading * texture data. (See _cogl_texture_draw_and_read() ) */ -static CoglBool +static gboolean _cogl_texture_driver_gl_get_tex_image (CoglContext *ctx, GLenum gl_target, GLenum dest_gl_format, @@ -555,26 +421,7 @@ _cogl_texture_driver_gl_get_tex_image (CoglContext *ctx, return FALSE; } -static CoglBool -_cogl_texture_driver_size_supported_3d (CoglContext *ctx, - GLenum gl_target, - GLenum gl_format, - GLenum gl_type, - int width, - int height, - int depth) -{ - GLint max_size; - - /* GLES doesn't support a proxy texture target so let's at least - check whether the size is greater than - GL_MAX_3D_TEXTURE_SIZE_OES */ - GE( ctx, glGetIntegerv (GL_MAX_3D_TEXTURE_SIZE_OES, &max_size) ); - - return width <= max_size && height <= max_size && depth <= max_size; -} - -static CoglBool +static gboolean _cogl_texture_driver_size_supported (CoglContext *ctx, GLenum gl_target, GLenum gl_intformat, @@ -592,30 +439,10 @@ _cogl_texture_driver_size_supported (CoglContext *ctx, return width <= max_size && height <= max_size; } -static void -_cogl_texture_driver_try_setting_gl_border_color - (CoglContext *ctx, - GLuint gl_target, - const GLfloat *transparent_color) -{ - /* FAIL! */ -} - -static CoglBool -_cogl_texture_driver_allows_foreign_gl_target (CoglContext *ctx, - GLenum gl_target) -{ - /* Allow 2-dimensional textures only */ - if (gl_target != GL_TEXTURE_2D) - return FALSE; - return TRUE; -} - static CoglPixelFormat _cogl_texture_driver_find_best_gl_get_data_format (CoglContext *context, CoglPixelFormat format, - CoglPixelFormat target_format, GLenum *closest_gl_format, GLenum *closest_gl_type) { @@ -631,15 +458,10 @@ const CoglTextureDriver _cogl_texture_driver_gles = { _cogl_texture_driver_gen, - _cogl_texture_driver_prep_gl_for_pixels_upload, _cogl_texture_driver_upload_subregion_to_gl, _cogl_texture_driver_upload_to_gl, - _cogl_texture_driver_upload_to_gl_3d, _cogl_texture_driver_prep_gl_for_pixels_download, _cogl_texture_driver_gl_get_tex_image, _cogl_texture_driver_size_supported, - _cogl_texture_driver_size_supported_3d, - _cogl_texture_driver_try_setting_gl_border_color, - _cogl_texture_driver_allows_foreign_gl_target, _cogl_texture_driver_find_best_gl_get_data_format }; diff --git a/cogl/cogl/driver/nop/cogl-attribute-nop.c b/cogl/cogl/driver/nop/cogl-attribute-nop.c index dcb689120..40b6d5e7c 100644 --- a/cogl/cogl/driver/nop/cogl-attribute-nop.c +++ b/cogl/cogl/driver/nop/cogl-attribute-nop.c @@ -28,9 +28,7 @@ * */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-types.h" #include "cogl-framebuffer.h" diff --git a/cogl/cogl/driver/nop/cogl-clip-stack-nop.c b/cogl/cogl/driver/nop/cogl-clip-stack-nop.c index 441dd6e1d..3469965fb 100644 --- a/cogl/cogl/driver/nop/cogl-clip-stack-nop.c +++ b/cogl/cogl/driver/nop/cogl-clip-stack-nop.c @@ -28,9 +28,7 @@ * */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-clip-stack.h" #include "cogl-clip-stack-nop-private.h" diff --git a/cogl/cogl/driver/nop/cogl-driver-nop.c b/cogl/cogl/driver/nop/cogl-driver-nop.c index 6e04e7164..3594a966b 100644 --- a/cogl/cogl/driver/nop/cogl-driver-nop.c +++ b/cogl/cogl/driver/nop/cogl-driver-nop.c @@ -28,9 +28,7 @@ * */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include @@ -38,30 +36,40 @@ #include "cogl-context-private.h" #include "cogl-feature-private.h" #include "cogl-renderer-private.h" -#include "cogl-error-private.h" #include "cogl-framebuffer-nop-private.h" #include "cogl-texture-2d-nop-private.h" #include "cogl-attribute-nop-private.h" #include "cogl-clip-stack-nop-private.h" -static CoglBool +static gboolean _cogl_driver_update_features (CoglContext *ctx, - CoglError **error) + GError **error) { /* _cogl_gpu_info_init (ctx, &ctx->gpu); */ memset (ctx->private_features, 0, sizeof (ctx->private_features)); - ctx->feature_flags = 0; return TRUE; } +static gboolean +_cogl_driver_nop_context_init (CoglContext *context) +{ + return TRUE; +} + +static void +_cogl_driver_nop_context_deinit (CoglContext *context) +{ +} + const CoglDriverVtable _cogl_driver_nop = { + _cogl_driver_nop_context_init, + _cogl_driver_nop_context_deinit, NULL, /* pixel_format_from_gl_internal */ NULL, /* pixel_format_to_gl */ - NULL, /* pixel_format_to_gl_with_target */ _cogl_driver_update_features, _cogl_offscreen_nop_allocate, _cogl_offscreen_nop_free, @@ -69,6 +77,7 @@ _cogl_driver_nop = _cogl_framebuffer_nop_clear, _cogl_framebuffer_nop_query_bits, _cogl_framebuffer_nop_finish, + _cogl_framebuffer_nop_flush, _cogl_framebuffer_nop_discard_buffers, _cogl_framebuffer_nop_draw_attributes, _cogl_framebuffer_nop_draw_indexed_attributes, @@ -81,6 +90,7 @@ _cogl_driver_nop = _cogl_texture_2d_nop_get_gl_handle, _cogl_texture_2d_nop_generate_mipmap, _cogl_texture_2d_nop_copy_from_bitmap, + NULL, /* texture_2d_is_get_data_supported */ NULL, /* texture_2d_get_data */ _cogl_nop_flush_attributes_state, _cogl_clip_stack_nop_flush, diff --git a/cogl/cogl/driver/nop/cogl-framebuffer-nop-private.h b/cogl/cogl/driver/nop/cogl-framebuffer-nop-private.h index 1e9630feb..95b636517 100644 --- a/cogl/cogl/driver/nop/cogl-framebuffer-nop-private.h +++ b/cogl/cogl/driver/nop/cogl-framebuffer-nop-private.h @@ -37,9 +37,9 @@ #include "cogl-types.h" #include "cogl-context-private.h" -CoglBool +gboolean _cogl_offscreen_nop_allocate (CoglOffscreen *offscreen, - CoglError **error); + GError **error); void _cogl_offscreen_nop_free (CoglOffscreen *offscreen); @@ -64,6 +64,9 @@ _cogl_framebuffer_nop_query_bits (CoglFramebuffer *framebuffer, void _cogl_framebuffer_nop_finish (CoglFramebuffer *framebuffer); +void +_cogl_framebuffer_nop_flush (CoglFramebuffer *framebuffer); + void _cogl_framebuffer_nop_discard_buffers (CoglFramebuffer *framebuffer, unsigned long buffers); @@ -89,12 +92,12 @@ _cogl_framebuffer_nop_draw_indexed_attributes (CoglFramebuffer *framebuffer, int n_attributes, CoglDrawFlags flags); -CoglBool +gboolean _cogl_framebuffer_nop_read_pixels_into_bitmap (CoglFramebuffer *framebuffer, int x, int y, CoglReadPixelsFlags source, CoglBitmap *bitmap, - CoglError **error); + GError **error); #endif /* _COGL_FRAMEBUFFER_NOP_PRIVATE_H_ */ diff --git a/cogl/cogl/driver/nop/cogl-framebuffer-nop.c b/cogl/cogl/driver/nop/cogl-framebuffer-nop.c index 2e730e418..f9db69c91 100644 --- a/cogl/cogl/driver/nop/cogl-framebuffer-nop.c +++ b/cogl/cogl/driver/nop/cogl-framebuffer-nop.c @@ -28,9 +28,7 @@ * */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-framebuffer-nop-private.h" @@ -44,9 +42,9 @@ _cogl_framebuffer_nop_flush_state (CoglFramebuffer *draw_buffer, { } -CoglBool +gboolean _cogl_offscreen_nop_allocate (CoglOffscreen *offscreen, - CoglError **error) + GError **error) { return TRUE; } @@ -78,6 +76,11 @@ _cogl_framebuffer_nop_finish (CoglFramebuffer *framebuffer) { } +void +_cogl_framebuffer_nop_flush (CoglFramebuffer *framebuffer) +{ +} + void _cogl_framebuffer_nop_discard_buffers (CoglFramebuffer *framebuffer, unsigned long buffers) @@ -109,13 +112,13 @@ _cogl_framebuffer_nop_draw_indexed_attributes (CoglFramebuffer *framebuffer, { } -CoglBool +gboolean _cogl_framebuffer_nop_read_pixels_into_bitmap (CoglFramebuffer *framebuffer, int x, int y, CoglReadPixelsFlags source, CoglBitmap *bitmap, - CoglError **error) + GError **error) { return TRUE; } diff --git a/cogl/cogl/driver/nop/cogl-texture-2d-nop-private.h b/cogl/cogl/driver/nop/cogl-texture-2d-nop-private.h index 51de1e3c1..dce8b689d 100644 --- a/cogl/cogl/driver/nop/cogl-texture-2d-nop-private.h +++ b/cogl/cogl/driver/nop/cogl-texture-2d-nop-private.h @@ -41,7 +41,7 @@ void _cogl_texture_2d_nop_free (CoglTexture2D *tex_2d); -CoglBool +gboolean _cogl_texture_2d_nop_can_create (CoglContext *ctx, int width, int height, @@ -50,9 +50,9 @@ _cogl_texture_2d_nop_can_create (CoglContext *ctx, void _cogl_texture_2d_nop_init (CoglTexture2D *tex_2d); -CoglBool +gboolean _cogl_texture_2d_nop_allocate (CoglTexture *tex, - CoglError **error); + GError **error); void _cogl_texture_2d_nop_flush_legacy_texobj_filters (CoglTexture *tex, @@ -62,8 +62,7 @@ _cogl_texture_2d_nop_flush_legacy_texobj_filters (CoglTexture *tex, void _cogl_texture_2d_nop_flush_legacy_texobj_wrap_modes (CoglTexture *tex, GLenum wrap_mode_s, - GLenum wrap_mode_t, - GLenum wrap_mode_p); + GLenum wrap_mode_t); void _cogl_texture_2d_nop_copy_from_framebuffer (CoglTexture2D *tex_2d, @@ -82,7 +81,7 @@ _cogl_texture_2d_nop_get_gl_handle (CoglTexture2D *tex_2d); void _cogl_texture_2d_nop_generate_mipmap (CoglTexture2D *tex_2d); -CoglBool +gboolean _cogl_texture_2d_nop_copy_from_bitmap (CoglTexture2D *tex_2d, int src_x, int src_y, @@ -92,7 +91,7 @@ _cogl_texture_2d_nop_copy_from_bitmap (CoglTexture2D *tex_2d, int dst_x, int dst_y, int level, - CoglError **error); + GError **error); void _cogl_texture_2d_nop_get_data (CoglTexture2D *tex_2d, diff --git a/cogl/cogl/driver/nop/cogl-texture-2d-nop.c b/cogl/cogl/driver/nop/cogl-texture-2d-nop.c index 539048a7c..4a9989553 100644 --- a/cogl/cogl/driver/nop/cogl-texture-2d-nop.c +++ b/cogl/cogl/driver/nop/cogl-texture-2d-nop.c @@ -32,23 +32,20 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include #include "cogl-private.h" #include "cogl-texture-2d-nop-private.h" #include "cogl-texture-2d-private.h" -#include "cogl-error-private.h" void _cogl_texture_2d_nop_free (CoglTexture2D *tex_2d) { } -CoglBool +gboolean _cogl_texture_2d_nop_can_create (CoglContext *ctx, int width, int height, @@ -62,9 +59,9 @@ _cogl_texture_2d_nop_init (CoglTexture2D *tex_2d) { } -CoglBool +gboolean _cogl_texture_2d_nop_allocate (CoglTexture *tex, - CoglError **error) + GError **error) { return TRUE; } @@ -79,8 +76,7 @@ _cogl_texture_2d_nop_flush_legacy_texobj_filters (CoglTexture *tex, void _cogl_texture_2d_nop_flush_legacy_texobj_wrap_modes (CoglTexture *tex, GLenum wrap_mode_s, - GLenum wrap_mode_t, - GLenum wrap_mode_p) + GLenum wrap_mode_t) { } @@ -108,7 +104,7 @@ _cogl_texture_2d_nop_generate_mipmap (CoglTexture2D *tex_2d) { } -CoglBool +gboolean _cogl_texture_2d_nop_copy_from_bitmap (CoglTexture2D *tex_2d, int src_x, int src_y, @@ -118,7 +114,7 @@ _cogl_texture_2d_nop_copy_from_bitmap (CoglTexture2D *tex_2d, int dst_x, int dst_y, int level, - CoglError **error) + GError **error) { return TRUE; } diff --git a/cogl/cogl/gl-prototypes/cogl-all-functions.h b/cogl/cogl/gl-prototypes/cogl-all-functions.h index 0c80fbcd2..a0c6395af 100644 --- a/cogl/cogl/gl-prototypes/cogl-all-functions.h +++ b/cogl/cogl/gl-prototypes/cogl-all-functions.h @@ -4,6 +4,7 @@ * A Low Level GPU Graphics and Utilities API * * Copyright (C) 2009, 2011 Intel Corporation. + * Copyright (C) 2019 DisplayLink (UK) Ltd. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -59,10 +60,6 @@ /* The functions in this file are part of the core GL,GLES1 and GLES2 apis */ #include "cogl-core-functions.h" -/* The functions in this file are core to GLES1 only but may also be - * extensions available for GLES2 and GL */ -#include "cogl-in-gles1-core-functions.h" - /* The functions in this file are core to GLES2 only but * may be extensions for GLES1 and GL */ #include "cogl-in-gles2-core-functions.h" @@ -71,9 +68,6 @@ * to GL but they may be extensions available for GL */ #include "cogl-in-gles-core-functions.h" -/* These are fixed-function APIs core to GL and GLES1 */ -#include "cogl-fixed-functions.h" - /* These are GLSL shader APIs core to GL 2.0 and GLES2 */ #include "cogl-glsl-functions.h" @@ -91,8 +85,6 @@ COGL_EXT_FUNCTION (void, glGetTexImage, (GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels)) -COGL_EXT_FUNCTION (void, glClipPlane, - (GLenum plane, const double *equation)) COGL_EXT_FUNCTION (void, glDepthRange, (double near_val, double far_val)) COGL_EXT_FUNCTION (void, glDrawBuffer, @@ -113,31 +105,10 @@ COGL_EXT_FUNCTION (GLboolean, glUnmapBuffer, (GLenum target)) COGL_EXT_END () -COGL_EXT_BEGIN (texture_3d, 1, 2, - 0, /* not in either GLES */ - "OES\0", - "texture_3D\0") -COGL_EXT_FUNCTION (void, glTexImage3D, - (GLenum target, GLint level, - GLint internalFormat, - GLsizei width, GLsizei height, - GLsizei depth, GLint border, - GLenum format, GLenum type, - const GLvoid *pixels)) -COGL_EXT_FUNCTION (void, glTexSubImage3D, - (GLenum target, GLint level, - GLint xoffset, GLint yoffset, - GLint zoffset, GLsizei width, - GLsizei height, GLsizei depth, - GLenum format, - GLenum type, const GLvoid *pixels)) -COGL_EXT_END () - - COGL_EXT_BEGIN (offscreen_blit, 3, 0, - 0, /* not in either GLES */ - "EXT\0ANGLE\0", + COGL_EXT_IN_GLES3, + "EXT\0NV\0", "framebuffer_blit\0") COGL_EXT_FUNCTION (void, glBlitFramebuffer, (GLint srcX0, @@ -152,31 +123,6 @@ COGL_EXT_FUNCTION (void, glBlitFramebuffer, GLenum filter)) COGL_EXT_END () -/* ARB_fragment_program */ -COGL_EXT_BEGIN (arbfp, 255, 255, - 0, /* not in either GLES */ - "ARB\0", - "fragment_program\0") -COGL_EXT_FUNCTION (void, glGenPrograms, - (GLsizei n, - GLuint *programs)) -COGL_EXT_FUNCTION (void, glDeletePrograms, - (GLsizei n, - GLuint *programs)) -COGL_EXT_FUNCTION (void, glBindProgram, - (GLenum target, - GLuint program)) -COGL_EXT_FUNCTION (void, glProgramString, - (GLenum target, - GLenum format, - GLsizei len, - const void *program)) -COGL_EXT_FUNCTION (void, glProgramLocalParameter4fv, - (GLenum target, - GLuint index, - GLfloat *params)) -COGL_EXT_END () - COGL_EXT_BEGIN (EGL_image, 255, 255, 0, /* not in either GLES */ "OES\0", @@ -184,9 +130,6 @@ COGL_EXT_BEGIN (EGL_image, 255, 255, COGL_EXT_FUNCTION (void, glEGLImageTargetTexture2D, (GLenum target, GLeglImageOES image)) -COGL_EXT_FUNCTION (void, glEGLImageTargetRenderbufferStorage, - (GLenum target, - GLeglImageOES image)) COGL_EXT_END () COGL_EXT_BEGIN (framebuffer_discard, 255, 255, @@ -219,7 +162,7 @@ COGL_EXT_FUNCTION (void, glFramebufferTexture2DMultisampleIMG, COGL_EXT_END () COGL_EXT_BEGIN (ARB_sampler_objects, 3, 3, - 0, /* not in either GLES */ + COGL_EXT_IN_GLES3, "ARB:\0", "sampler_objects\0") COGL_EXT_FUNCTION (void, glGenSamplers, @@ -237,43 +180,8 @@ COGL_EXT_FUNCTION (void, glSamplerParameteri, GLint param)) COGL_EXT_END () -/* These only list functions that come from the old GLSL extensions. - * Functions that are common to the extensions and GLSL 2.0 should - * instead be listed in cogl-glsl-functions.h */ -COGL_EXT_BEGIN (shader_objects, 255, 255, - 0, /* not in either GLES */ - "ARB\0", - "shader_objects\0") -COGL_EXT_FUNCTION (GLuint, glCreateProgramObject, - (void)) -COGL_EXT_FUNCTION (GLuint, glCreateShaderObject, - (GLenum shaderType)) -COGL_EXT_FUNCTION (void, glDeleteObject, - (GLuint obj)) -COGL_EXT_FUNCTION (void, glAttachObject, - (GLuint container, GLuint obj)) -COGL_EXT_FUNCTION (void, glUseProgramObject, - (GLuint programObj)) -COGL_EXT_FUNCTION (void, glGetInfoLog, - (GLuint obj, - GLsizei maxLength, - GLsizei *length, - char *infoLog)) -COGL_EXT_FUNCTION (void, glGetObjectParameteriv, - (GLuint obj, - GLenum pname, - GLint *params)) -COGL_EXT_FUNCTION (void, glDetachObject, - (GLuint container, GLuint obj)) -COGL_EXT_FUNCTION (void, glGetAttachedObjects, - (GLuint program, - GLsizei maxcount, - GLsizei* count, - GLuint* shaders)) -COGL_EXT_END () - COGL_EXT_BEGIN (only_gl3, 3, 0, - 0, /* not in either GLES */ + COGL_EXT_IN_GLES3, "\0", "\0") COGL_EXT_FUNCTION (const GLubyte *, glGetStringi, @@ -281,14 +189,11 @@ COGL_EXT_FUNCTION (const GLubyte *, glGetStringi, COGL_EXT_END () COGL_EXT_BEGIN (vertex_array_object, 3, 0, - 0, /* not in either GLES */ + COGL_EXT_IN_GLES3, "ARB\0OES\0", "vertex_array_object\0") COGL_EXT_FUNCTION (void, glBindVertexArray, (GLuint array)) -COGL_EXT_FUNCTION (void, glDeleteVertexArrays, - (GLsizei n, - const GLuint *arrays)) COGL_EXT_FUNCTION (void, glGenVertexArrays, (GLsizei n, GLuint *arrays)) @@ -307,7 +212,7 @@ COGL_EXT_END () #ifdef GL_ARB_sync COGL_EXT_BEGIN (sync, 3, 2, - 0, /* not in either GLES */ + COGL_EXT_IN_GLES3, "ARB:\0", "sync\0") COGL_EXT_FUNCTION (GLsync, glFenceSync, @@ -334,3 +239,11 @@ COGL_EXT_BEGIN (robustness, 255, 255, COGL_EXT_FUNCTION (GLenum, glGetGraphicsResetStatus, (void)) COGL_EXT_END () + +COGL_EXT_BEGIN (multitexture_part1, 1, 3, + 0, + "ARB\0", + "multitexture\0") +COGL_EXT_FUNCTION (void, glClientActiveTexture, + (GLenum texture)) +COGL_EXT_END () diff --git a/cogl/cogl/gl-prototypes/cogl-core-functions.h b/cogl/cogl/gl-prototypes/cogl-core-functions.h index f37041b7b..e04b443ae 100644 --- a/cogl/cogl/gl-prototypes/cogl-core-functions.h +++ b/cogl/cogl/gl-prototypes/cogl-core-functions.h @@ -60,13 +60,26 @@ available */ COGL_EXT_BEGIN (core, 0, 0, - COGL_EXT_IN_GLES | COGL_EXT_IN_GLES2, + COGL_EXT_IN_GLES2, "\0", "\0") +COGL_EXT_FUNCTION (void, glActiveTexture, + (GLenum texture)) +COGL_EXT_FUNCTION (void, glBindBuffer, + (GLenum target, + GLuint buffer)) COGL_EXT_FUNCTION (void, glBindTexture, (GLenum target, GLuint texture)) -COGL_EXT_FUNCTION (void, glBlendFunc, - (GLenum sfactor, GLenum dfactor)) +COGL_EXT_FUNCTION (void, glBufferData, + (GLenum target, + GLsizeiptr size, + const GLvoid *data, + GLenum usage)) +COGL_EXT_FUNCTION (void, glBufferSubData, + (GLenum target, + GLintptr offset, + GLsizeiptr size, + const GLvoid *data)) COGL_EXT_FUNCTION (void, glClear, (GLbitfield mask)) COGL_EXT_FUNCTION (void, glClearColor, @@ -90,6 +103,9 @@ COGL_EXT_FUNCTION (void, glCopyTexSubImage2D, GLint y, GLsizei width, GLsizei height)) +COGL_EXT_FUNCTION (void, glDeleteBuffers, + (GLsizei n, + const GLuint *buffers)) COGL_EXT_FUNCTION (void, glDeleteTextures, (GLsizei n, const GLuint* textures)) COGL_EXT_FUNCTION (void, glDepthFunc, @@ -115,20 +131,17 @@ COGL_EXT_FUNCTION (void, glFrontFace, (GLenum mode)) COGL_EXT_FUNCTION (void, glCullFace, (GLenum mode)) +COGL_EXT_FUNCTION (void, glGenBuffers, + (GLsizei n, + GLuint *buffers)) COGL_EXT_FUNCTION (void, glGenTextures, (GLsizei n, GLuint* textures)) COGL_EXT_FUNCTION (GLenum, glGetError, (void)) COGL_EXT_FUNCTION (void, glGetIntegerv, (GLenum pname, GLint* params)) -COGL_EXT_FUNCTION (void, glGetBooleanv, - (GLenum pname, GLboolean* params)) -COGL_EXT_FUNCTION (void, glGetFloatv, - (GLenum pname, GLfloat* params)) COGL_EXT_FUNCTION (const GLubyte*, glGetString, (GLenum name)) -COGL_EXT_FUNCTION (void, glHint, - (GLenum target, GLenum mode)) COGL_EXT_FUNCTION (GLboolean, glIsTexture, (GLuint texture)) COGL_EXT_FUNCTION (void, glPixelStorei, @@ -159,18 +172,10 @@ COGL_EXT_FUNCTION (void, glTexImage2D, GLenum format, GLenum type, const GLvoid* pixels)) -COGL_EXT_FUNCTION (void, glTexParameterf, - (GLenum target, GLenum pname, GLfloat param)) -COGL_EXT_FUNCTION (void, glTexParameterfv, - (GLenum target, GLenum pname, const GLfloat* params)) COGL_EXT_FUNCTION (void, glTexParameteri, (GLenum target, GLenum pname, GLint param)) COGL_EXT_FUNCTION (void, glTexParameteriv, (GLenum target, GLenum pname, const GLint* params)) -COGL_EXT_FUNCTION (void, glGetTexParameterfv, - (GLenum target, GLenum pname, GLfloat* params)) -COGL_EXT_FUNCTION (void, glGetTexParameteriv, - (GLenum target, GLenum pname, GLint* params)) COGL_EXT_FUNCTION (void, glTexSubImage2D, (GLenum target, GLint level, @@ -181,18 +186,6 @@ COGL_EXT_FUNCTION (void, glTexSubImage2D, GLenum format, GLenum type, const GLvoid* pixels)) -COGL_EXT_FUNCTION (void, glCopyTexImage2D, - (GLenum target, - GLint level, - GLenum internalformat, - GLint x, - GLint y, - GLsizei width, - GLsizei height, - GLint border)) COGL_EXT_FUNCTION (void, glViewport, (GLint x, GLint y, GLsizei width, GLsizei height)) -COGL_EXT_FUNCTION (GLboolean, glIsEnabled, (GLenum cap)) -COGL_EXT_FUNCTION (void, glLineWidth, (GLfloat width)) -COGL_EXT_FUNCTION (void, glPolygonOffset, (GLfloat factor, GLfloat units)) COGL_EXT_END () diff --git a/cogl/cogl/gl-prototypes/cogl-fixed-functions.h b/cogl/cogl/gl-prototypes/cogl-fixed-functions.h deleted file mode 100644 index ce7b4e0de..000000000 --- a/cogl/cogl/gl-prototypes/cogl-fixed-functions.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009, 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -/* This is included multiple times with different definitions for - * these macros. The macros are given the following arguments: - * - * COGL_EXT_BEGIN: - * - * @name: a unique symbol name for this feature - * - * @min_gl_major: the major part of the minimum GL version where these - * functions are available in core, or 255 if it isn't available in - * any version. - * @min_gl_minor: the minor part of the minimum GL version where these - * functions are available in core, or 255 if it isn't available in - * any version. - * - * @gles_availability: flags to specify which versions of GLES the - * functions are available in. Should be a combination of - * COGL_EXT_IN_GLES and COGL_EXT_IN_GLES2. - * - * @extension_suffixes: A zero-separated list of suffixes in a - * string. These are appended to the extension name to get a complete - * extension name to try. The suffix is also appended to all of the - * function names. The suffix can optionally include a ':' to specify - * an alternate suffix for the function names. - * - * @extension_names: A list of extension names to try. If any of these - * extensions match then it will be used. - */ - -/* These are the core GL functions which are available when the API - supports fixed-function (ie, GL and GLES1.1) */ -COGL_EXT_BEGIN (fixed_function_core, - 0, 0, - COGL_EXT_IN_GLES, - "\0", - "\0") -COGL_EXT_FUNCTION (void, glAlphaFunc, - (GLenum func, GLclampf ref)) -COGL_EXT_FUNCTION (void, glFogf, - (GLenum pname, GLfloat param)) -COGL_EXT_FUNCTION (void, glFogfv, - (GLenum pname, const GLfloat *params)) -COGL_EXT_FUNCTION (void, glLoadMatrixf, - (const GLfloat *m)) -COGL_EXT_FUNCTION (void, glMaterialfv, - (GLenum face, GLenum pname, const GLfloat *params)) -COGL_EXT_FUNCTION (void, glPointSize, - (GLfloat size)) -COGL_EXT_FUNCTION (void, glTexEnvfv, - (GLenum target, GLenum pname, const GLfloat *params)) -COGL_EXT_FUNCTION (void, glColor4ub, - (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)) -COGL_EXT_FUNCTION (void, glColor4f, - (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)) -COGL_EXT_FUNCTION (void, glColorPointer, - (GLint size, - GLenum type, - GLsizei stride, - const GLvoid *pointer)) -COGL_EXT_FUNCTION (void, glDisableClientState, - (GLenum array)) -COGL_EXT_FUNCTION (void, glEnableClientState, - (GLenum array)) -COGL_EXT_FUNCTION (void, glLoadIdentity, - (void)) -COGL_EXT_FUNCTION (void, glMatrixMode, - (GLenum mode)) -COGL_EXT_FUNCTION (void, glNormal3f, - (GLfloat x, GLfloat y, GLfloat z)) -COGL_EXT_FUNCTION (void, glNormalPointer, - (GLenum type, GLsizei stride, const GLvoid *pointer)) -COGL_EXT_FUNCTION (void, glMultiTexCoord4f, - (GLfloat s, GLfloat t, GLfloat r, GLfloat q)) -COGL_EXT_FUNCTION (void, glTexCoordPointer, - (GLint size, - GLenum type, - GLsizei stride, - const GLvoid *pointer)) -COGL_EXT_FUNCTION (void, glTexEnvi, - (GLenum target, - GLenum pname, - GLint param)) -COGL_EXT_FUNCTION (void, glVertex4f, - (GLfloat x, GLfloat y, GLfloat z, GLfloat w)) -COGL_EXT_FUNCTION (void, glVertexPointer, - (GLint size, - GLenum type, - GLsizei stride, - const GLvoid *pointer)) -COGL_EXT_END () diff --git a/cogl/cogl/gl-prototypes/cogl-gles1-functions.h b/cogl/cogl/gl-prototypes/cogl-gles1-functions.h deleted file mode 100644 index 774b9b33b..000000000 --- a/cogl/cogl/gl-prototypes/cogl-gles1-functions.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009, 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -/* The functions in this file are part of the core GL,GLES1 and GLES2 apis */ -#include "cogl-core-functions.h" - -/* The functions in this file are core to GLES1 and GLES2 but not core - * to GL but they may be extensions available for GL */ -#include "cogl-in-gles-core-functions.h" - -/* The functions in this file are core to GLES1 only but - * may be extensions for GLES2 and GL */ -#include "cogl-in-gles1-core-functions.h" - -/* These are fixed-function APIs core to GL and GLES1 */ -#include "cogl-fixed-functions.h" diff --git a/cogl/cogl/gl-prototypes/cogl-glsl-functions.h b/cogl/cogl/gl-prototypes/cogl-glsl-functions.h index 980f8adf0..a918ad866 100644 --- a/cogl/cogl/gl-prototypes/cogl-glsl-functions.h +++ b/cogl/cogl/gl-prototypes/cogl-glsl-functions.h @@ -93,17 +93,6 @@ COGL_EXT_FUNCTION (void, glGetProgramiv, (GLuint program, GLenum pname, GLint *params)) -COGL_EXT_FUNCTION (void, glDetachShader, - (GLuint program, GLuint shader)) -COGL_EXT_FUNCTION (void, glGetAttachedShaders, - (GLuint program, - GLsizei maxcount, - GLsizei* count, - GLuint* shaders)) -COGL_EXT_FUNCTION (GLboolean, glIsShader, - (GLuint shader)) -COGL_EXT_FUNCTION (GLboolean, glIsProgram, - (GLuint program)) COGL_EXT_END () /* These functions are provided by GL_ARB_shader_objects or are in GL @@ -127,21 +116,6 @@ COGL_EXT_FUNCTION (GLint, glGetUniformLocation, COGL_EXT_FUNCTION (void, glUniform1f, (GLint location, GLfloat v0)) -COGL_EXT_FUNCTION (void, glUniform2f, - (GLint location, - GLfloat v0, - GLfloat v1)) -COGL_EXT_FUNCTION (void, glUniform3f, - (GLint location, - GLfloat v0, - GLfloat v1, - GLfloat v2)) -COGL_EXT_FUNCTION (void, glUniform4f, - (GLint location, - GLfloat v0, - GLfloat v1, - GLfloat v2, - GLfloat v3)) COGL_EXT_FUNCTION (void, glUniform1fv, (GLint location, GLsizei count, @@ -161,21 +135,6 @@ COGL_EXT_FUNCTION (void, glUniform4fv, COGL_EXT_FUNCTION (void, glUniform1i, (GLint location, GLint v0)) -COGL_EXT_FUNCTION (void, glUniform2i, - (GLint location, - GLint v0, - GLint v1)) -COGL_EXT_FUNCTION (void, glUniform3i, - (GLint location, - GLint v0, - GLint v1, - GLint v2)) -COGL_EXT_FUNCTION (void, glUniform4i, - (GLint location, - GLint v0, - GLint v1, - GLint v2, - GLint v3)) COGL_EXT_FUNCTION (void, glUniform1iv, (GLint location, GLsizei count, @@ -207,29 +166,6 @@ COGL_EXT_FUNCTION (void, glUniformMatrix4fv, GLsizei count, GLboolean transpose, const GLfloat *value)) - -COGL_EXT_FUNCTION (void, glGetUniformfv, - (GLuint program, - GLint location, - GLfloat *params)) -COGL_EXT_FUNCTION (void, glGetUniformiv, - (GLuint program, - GLint location, - GLint *params)) -COGL_EXT_FUNCTION (void, glGetActiveUniform, - (GLuint program, - GLuint index, - GLsizei bufsize, - GLsizei* length, - GLint* size, - GLenum* type, - GLchar* name)) -COGL_EXT_FUNCTION (void, glGetShaderSource, - (GLuint shader, - GLsizei bufsize, - GLsizei* length, - GLchar* source)) -COGL_EXT_FUNCTION (void, glValidateProgram, (GLuint program)) COGL_EXT_END () /* These functions are provided by GL_ARB_vertex_shader or are in GL @@ -249,38 +185,20 @@ COGL_EXT_FUNCTION (void, glEnableVertexAttribArray, (GLuint index)) COGL_EXT_FUNCTION (void, glDisableVertexAttribArray, (GLuint index)) -COGL_EXT_FUNCTION (void, glVertexAttrib1f, (GLuint indx, GLfloat x)) COGL_EXT_FUNCTION (void, glVertexAttrib1fv, (GLuint indx, const GLfloat* values)) -COGL_EXT_FUNCTION (void, glVertexAttrib2f, (GLuint indx, GLfloat x, GLfloat y)) COGL_EXT_FUNCTION (void, glVertexAttrib2fv, (GLuint indx, const GLfloat* values)) -COGL_EXT_FUNCTION (void, glVertexAttrib3f, - (GLuint indx, GLfloat x, GLfloat y, GLfloat z)) COGL_EXT_FUNCTION (void, glVertexAttrib3fv, (GLuint indx, const GLfloat* values)) COGL_EXT_FUNCTION (void, glVertexAttrib4f, (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)) COGL_EXT_FUNCTION (void, glVertexAttrib4fv, (GLuint indx, const GLfloat* values)) -COGL_EXT_FUNCTION (void, glGetVertexAttribfv, - (GLuint index, GLenum pname, GLfloat* params)) -COGL_EXT_FUNCTION (void, glGetVertexAttribiv, - (GLuint index, GLenum pname, GLint* params)) -COGL_EXT_FUNCTION (void, glGetVertexAttribPointerv, - (GLuint index, GLenum pname, GLvoid** pointer)) COGL_EXT_FUNCTION (GLint, glGetAttribLocation, (GLuint program, const char *name)) COGL_EXT_FUNCTION (void, glBindAttribLocation, (GLuint program, GLuint index, const GLchar* name)) -COGL_EXT_FUNCTION (void, glGetActiveAttrib, - (GLuint program, - GLuint index, - GLsizei bufsize, - GLsizei* length, - GLint* size, - GLenum* type, - GLchar* name)) COGL_EXT_END () diff --git a/cogl/cogl/gl-prototypes/cogl-in-gles-core-functions.h b/cogl/cogl/gl-prototypes/cogl-in-gles-core-functions.h index 5679e7221..b298bceb8 100644 --- a/cogl/cogl/gl-prototypes/cogl-in-gles-core-functions.h +++ b/cogl/cogl/gl-prototypes/cogl-in-gles-core-functions.h @@ -58,91 +58,9 @@ COGL_EXT_BEGIN (only_in_both_gles, 4, 1, - COGL_EXT_IN_GLES | COGL_EXT_IN_GLES2, "ARB\0", "ES2_compatibility\0") COGL_EXT_FUNCTION (void, glDepthRangef, (GLfloat near_val, GLfloat far_val)) -COGL_EXT_FUNCTION (void, glClearDepthf, - (GLclampf depth)) COGL_EXT_END () - -COGL_EXT_BEGIN (only_in_both_gles_and_gl_1_3, - 1, 3, - COGL_EXT_IN_GLES | - COGL_EXT_IN_GLES2, - "\0", - "\0") -COGL_EXT_FUNCTION (void, glCompressedTexImage2D, - (GLenum target, - GLint level, - GLenum internalformat, - GLsizei width, - GLsizei height, - GLint border, - GLsizei imageSize, - const GLvoid* data)) -COGL_EXT_FUNCTION (void, glCompressedTexSubImage2D, - (GLenum target, - GLint level, - GLint xoffset, - GLint yoffset, - GLsizei width, - GLsizei height, - GLenum format, - GLsizei imageSize, - const GLvoid* data)) -COGL_EXT_FUNCTION (void, glSampleCoverage, - (GLclampf value, GLboolean invert)) -COGL_EXT_END () - -COGL_EXT_BEGIN (only_in_both_gles_and_gl_1_5, - 1, 5, - COGL_EXT_IN_GLES | - COGL_EXT_IN_GLES2, - "\0", - "\0") -COGL_EXT_FUNCTION (void, glGetBufferParameteriv, - (GLenum target, GLenum pname, GLint* params)) -COGL_EXT_END () - -COGL_EXT_BEGIN (vbos, 1, 5, - COGL_EXT_IN_GLES | - COGL_EXT_IN_GLES2, - "ARB\0", - "vertex_buffer_object\0") -COGL_EXT_FUNCTION (void, glGenBuffers, - (GLsizei n, - GLuint *buffers)) -COGL_EXT_FUNCTION (void, glBindBuffer, - (GLenum target, - GLuint buffer)) -COGL_EXT_FUNCTION (void, glBufferData, - (GLenum target, - GLsizeiptr size, - const GLvoid *data, - GLenum usage)) -COGL_EXT_FUNCTION (void, glBufferSubData, - (GLenum target, - GLintptr offset, - GLsizeiptr size, - const GLvoid *data)) -COGL_EXT_FUNCTION (void, glDeleteBuffers, - (GLsizei n, - const GLuint *buffers)) -COGL_EXT_FUNCTION (GLboolean, glIsBuffer, - (GLuint buffer)) -COGL_EXT_END () - -/* Available in GL 1.3, the multitexture extension or GLES. These are - required */ -COGL_EXT_BEGIN (multitexture_part0, 1, 3, - COGL_EXT_IN_GLES | - COGL_EXT_IN_GLES2, - "ARB\0", - "multitexture\0") -COGL_EXT_FUNCTION (void, glActiveTexture, - (GLenum texture)) -COGL_EXT_END () - diff --git a/cogl/cogl/gl-prototypes/cogl-in-gles1-core-functions.h b/cogl/cogl/gl-prototypes/cogl-in-gles1-core-functions.h deleted file mode 100644 index 20dc1a81f..000000000 --- a/cogl/cogl/gl-prototypes/cogl-in-gles1-core-functions.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009, 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -/* This is included multiple times with different definitions for - * these macros. The macros are given the following arguments: - * - * COGL_EXT_BEGIN: - * - * @name: a unique symbol name for this feature - * - * @min_gl_major: the major part of the minimum GL version where these - * functions are available in core, or 255 if it isn't available in - * any version. - * @min_gl_minor: the minor part of the minimum GL version where these - * functions are available in core, or 255 if it isn't available in - * any version. - * - * @gles_availability: flags to specify which versions of GLES the - * functions are available in. Should be a combination of - * COGL_EXT_IN_GLES and COGL_EXT_IN_GLES2. - * - * @extension_suffixes: A zero-separated list of suffixes in a - * string. These are appended to the extension name to get a complete - * extension name to try. The suffix is also appended to all of the - * function names. The suffix can optionally include a ':' to specify - * an alternate suffix for the function names. - * - * @extension_names: A list of extension names to try. If any of these - * extensions match then it will be used. - */ - -/* These functions are only available in GLES and are used as - replacements for some GL equivalents that only accept double - arguments */ -COGL_EXT_BEGIN (only_in_gles1, - 255, 255, - COGL_EXT_IN_GLES, - "\0", - "\0") -COGL_EXT_FUNCTION (void, glClipPlanef, - (GLenum plane, const GLfloat *equation)) -COGL_EXT_END () - -COGL_EXT_BEGIN (multitexture_part1, 1, 3, - COGL_EXT_IN_GLES, - "ARB\0", - "multitexture\0") -COGL_EXT_FUNCTION (void, glClientActiveTexture, - (GLenum texture)) -COGL_EXT_END () - diff --git a/cogl/cogl/gl-prototypes/cogl-in-gles2-core-functions.h b/cogl/cogl/gl-prototypes/cogl-in-gles2-core-functions.h index 1e2f79ea4..113b99b86 100644 --- a/cogl/cogl/gl-prototypes/cogl-in-gles2-core-functions.h +++ b/cogl/cogl/gl-prototypes/cogl-in-gles2-core-functions.h @@ -95,8 +95,6 @@ COGL_EXT_FUNCTION (void, glFramebufferRenderbuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)) -COGL_EXT_FUNCTION (GLboolean, glIsRenderbuffer, - (GLuint renderbuffer)) COGL_EXT_FUNCTION (GLenum, glCheckFramebufferStatus, (GLenum target)) COGL_EXT_FUNCTION (void, glDeleteFramebuffers, @@ -109,20 +107,12 @@ COGL_EXT_FUNCTION (void, glGetFramebufferAttachmentParameteriv, GLenum attachment, GLenum pname, GLint *params)) -COGL_EXT_FUNCTION (void, glGetRenderbufferParameteriv, - (GLenum target, - GLenum pname, - GLint *params)) -COGL_EXT_FUNCTION (GLboolean, glIsFramebuffer, - (GLuint framebuffer)) COGL_EXT_END () COGL_EXT_BEGIN (blending, 1, 2, COGL_EXT_IN_GLES2, "\0", "\0") -COGL_EXT_FUNCTION (void, glBlendEquation, - (GLenum mode)) COGL_EXT_FUNCTION (void, glBlendColor, (GLclampf red, GLclampf green, @@ -151,36 +141,3 @@ COGL_EXT_FUNCTION (void, glBlendEquationSeparate, (GLenum modeRGB, GLenum modeAlpha)) COGL_EXT_END () - -COGL_EXT_BEGIN (gles2_only_api, - 4, 1, - COGL_EXT_IN_GLES2, - "ARB:\0", - "ES2_compatibility\0") -COGL_EXT_FUNCTION (void, glReleaseShaderCompiler, (void)) -COGL_EXT_FUNCTION (void, glGetShaderPrecisionFormat, - (GLenum shadertype, - GLenum precisiontype, - GLint* range, - GLint* precision)) -COGL_EXT_FUNCTION (void, glShaderBinary, - (GLsizei n, - const GLuint* shaders, - GLenum binaryformat, - const GLvoid* binary, - GLsizei length)) -COGL_EXT_END () - -/* GL and GLES 2.0 apis */ -COGL_EXT_BEGIN (two_point_zero_api, - 2, 0, - COGL_EXT_IN_GLES2, - "\0", - "\0") -COGL_EXT_FUNCTION (void, glStencilFuncSeparate, - (GLenum face, GLenum func, GLint ref, GLuint mask)) -COGL_EXT_FUNCTION (void, glStencilMaskSeparate, - (GLenum face, GLuint mask)) -COGL_EXT_FUNCTION (void, glStencilOpSeparate, - (GLenum face, GLenum fail, GLenum zfail, GLenum zpass)) -COGL_EXT_END () diff --git a/cogl/cogl/meson.build b/cogl/cogl/meson.build new file mode 100644 index 000000000..90f1b4dfe --- /dev/null +++ b/cogl/cogl/meson.build @@ -0,0 +1,501 @@ +cogl_cogl_includesubdir = join_paths(cogl_includesubdir, 'cogl') +cogl_cogl_includedir = join_paths(cogl_includedir, 'cogl') + +cdata = configuration_data() +cdata.set('COGL_HAS_GL', have_gl) +cdata.set('CLUTTER_COGL_HAS_GL', have_gl) +cdata.set('COGL_HAS_GLX_SUPPORT', have_glx) +cdata.set('COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT', have_wayland) +cdata.set('COGL_HAS_EGL_PLATFORM_XLIB_SUPPORT', have_egl_xlib) +cdata.set('COGL_HAS_EGL_SUPPORT', have_egl) +cdata.set('COGL_HAS_X11', have_x11) +cdata.set('COGL_HAS_X11_SUPPORT', have_x11) +cdata.set('COGL_HAS_XLIB', have_x11) +cdata.set('COGL_HAS_XLIB_SUPPORT', have_x11) +cdata.set('COGL_HAS_TRACING', have_profiler) + +cogl_defines_h = configure_file( + input: 'cogl-defines.h.meson', + output: 'cogl-defines.h', + configuration: cdata, + install_dir: cogl_cogl_includedir, + install: true, +) + +if have_gl + cogl_gl_header_includes = ['GL/gl.h'] +elif have_gles2 + cogl_gl_header_includes = ['GLES2/gl2.h', 'GLES2/gl2ext.h'] +else + error('Neither GLES2 or OpenGL was enabled') +endif + +cogl_gl_header_includes_string = '' +foreach gl_header : cogl_gl_header_includes + cogl_gl_header_includes_string += '#include <@0@>\n'.format(gl_header) +endforeach + +built_headers = [] + +cdata = configuration_data() +cdata.set('COGL_GL_HEADER_INCLUDES', cogl_gl_header_includes_string) + +cogl_gl_header_h = configure_file( + input: 'cogl-gl-header.h.in', + output: 'cogl-gl-header.h', + configuration: cdata, + install: false, +) +built_headers += [cogl_gl_header_h] + +if have_egl + cogl_egl_includes_string = '#include \n#include \n#include ' +else + cogl_egl_includes_string = '' +endif + +cdata = configuration_data() +cdata.set('COGL_EGL_INCLUDES', cogl_egl_includes_string) +cogl_egl_defines_h = configure_file( + input: 'cogl-egl-defines.h.in', + output: 'cogl-egl-defines.h', + configuration: cdata, + install: false, +) +built_headers += [cogl_gl_header_h] + +cogl_deprecated_headers = [ + 'deprecated/cogl-material-compat.h', + 'deprecated/cogl-shader.h', + 'deprecated/cogl-clutter.h', + 'deprecated/cogl-type-casts.h', + 'deprecated/cogl-auto-texture.h', +] + +cogl_headers = [ + 'cogl1-context.h', + 'cogl-bitmap.h', + 'cogl-color.h', + 'cogl-context.h', + 'cogl-framebuffer.h', + 'cogl-matrix.h', + 'cogl-object.h', + 'cogl-offscreen.h', + 'cogl-onscreen.h', + 'cogl-pipeline.h', + 'cogl-pipeline-state.h', + 'cogl-pipeline-layer-state.h', + 'cogl-pixel-format.h', + 'cogl-texture.h', + 'cogl-texture-2d.h', + 'cogl-texture-2d-sliced.h', + 'cogl-types.h', + 'cogl-trace.h', + 'cogl.h', +] + +cogl_nonintrospected_headers = [ + 'cogl-renderer.h', + 'cogl-swap-chain.h', + 'cogl-onscreen-template.h', + 'cogl-dma-buf-handle.h', + 'cogl-display.h', + 'cogl-snippet.h', + 'cogl-index-buffer.h', + 'cogl-attribute-buffer.h', + 'cogl-indices.h', + 'cogl-attribute.h', + 'cogl-primitive.h', + 'cogl-frame-info.h', + 'cogl-output.h', + 'cogl-matrix-stack.h', + 'cogl-poll.h', + 'cogl-sub-texture.h', + 'cogl-atlas-texture.h', + 'cogl-meta-texture.h', + 'cogl-primitive-texture.h', + 'cogl-depth-state.h', + 'cogl-buffer.h', + 'cogl-pixel-buffer.h', + 'cogl-macros.h', + 'cogl-fence.h', + 'cogl-version.h', + 'cogl-gtype-private.h', + 'cogl-glib-source.h', +] + +cogl_nodist_headers = [ +] + +cogl_noop_driver_sources = [ + 'driver/nop/cogl-driver-nop.c', + 'driver/nop/cogl-framebuffer-nop-private.h', + 'driver/nop/cogl-framebuffer-nop.c', + 'driver/nop/cogl-attribute-nop-private.h', + 'driver/nop/cogl-attribute-nop.c', + 'driver/nop/cogl-clip-stack-nop-private.h', + 'driver/nop/cogl-clip-stack-nop.c', + 'driver/nop/cogl-texture-2d-nop-private.h', + 'driver/nop/cogl-texture-2d-nop.c', +] + +cogl_gl_prototype_headers = [ + 'gl-prototypes/cogl-gles2-functions.h', + 'gl-prototypes/cogl-core-functions.h', + 'gl-prototypes/cogl-in-gles-core-functions.h', + 'gl-prototypes/cogl-in-gles2-core-functions.h', + 'gl-prototypes/cogl-glsl-functions.h', +] + +cogl_common_driver_sources = [ + 'driver/gl/cogl-util-gl-private.h', + 'driver/gl/cogl-util-gl.c', + 'driver/gl/cogl-framebuffer-gl-private.h', + 'driver/gl/cogl-framebuffer-gl.c', + 'driver/gl/cogl-texture-gl-private.h', + 'driver/gl/cogl-texture-gl.c', + 'driver/gl/cogl-texture-2d-gl-private.h', + 'driver/gl/cogl-texture-2d-gl.c', + 'driver/gl/cogl-attribute-gl-private.h', + 'driver/gl/cogl-attribute-gl.c', + 'driver/gl/cogl-clip-stack-gl-private.h', + 'driver/gl/cogl-clip-stack-gl.c', + 'driver/gl/cogl-buffer-gl-private.h', + 'driver/gl/cogl-buffer-gl.c', + 'driver/gl/cogl-bitmap-gl-private.h', + 'driver/gl/cogl-bitmap-gl.c', + 'driver/gl/cogl-pipeline-opengl.c', + 'driver/gl/cogl-pipeline-opengl-private.h', + 'driver/gl/cogl-pipeline-fragend-glsl.c', + 'driver/gl/cogl-pipeline-fragend-glsl-private.h', + 'driver/gl/cogl-pipeline-vertend-glsl.c', + 'driver/gl/cogl-pipeline-vertend-glsl-private.h', + 'driver/gl/cogl-pipeline-progend-glsl.c', + 'driver/gl/cogl-pipeline-progend-glsl-private.h', +] + +gl_driver_sources = [ + 'driver/gl/gl/cogl-driver-gl.c', + 'driver/gl/gl/cogl-texture-driver-gl.c', +] + +gles_driver_sources = [ + 'driver/gl/gles/cogl-driver-gles.c', + 'driver/gl/gles/cogl-texture-driver-gles.c', +] + +cogl_driver_sources = [ + cogl_noop_driver_sources, + cogl_common_driver_sources, +] + +if have_gl + cogl_driver_sources += gl_driver_sources +endif + +if have_gles2 + cogl_driver_sources += gles_driver_sources +endif + +cogl_sources = [ + cogl_driver_sources, + + 'winsys/cogl-winsys-private.h', + 'winsys/cogl-winsys.c', + 'cogl-private.h', + 'cogl-i18n-private.h', + 'cogl-debug.h', + 'cogl-debug-options.h', + 'cogl-dma-buf-handle.c', + 'cogl-gpu-info.c', + 'cogl-gpu-info-private.h', + 'cogl-context-private.h', + 'cogl-context.c', + 'cogl-renderer-private.h', + 'cogl-renderer.h', + 'cogl-renderer.c', + 'cogl-swap-chain-private.h', + 'cogl-swap-chain.h', + 'cogl-swap-chain.c', + 'cogl-onscreen-template-private.h', + 'cogl-onscreen-template.h', + 'cogl-onscreen-template.c', + 'cogl-display-private.h', + 'cogl-display.h', + 'cogl-display.c', + 'cogl-driver.h', + 'cogl.c', + 'cogl-pixel-format.c', + 'cogl-object-private.h', + 'cogl-object.h', + 'cogl-object.c', + 'cogl-util.h', + 'cogl-util.c', + 'cogl-bitmap-private.h', + 'cogl-bitmap.c', + 'cogl-bitmap-conversion.c', + 'cogl-bitmap-packing.h', + 'cogl-primitives-private.h', + 'cogl-primitives.c', + 'cogl-bitmap-pixbuf.c', + 'cogl-clip-stack.h', + 'cogl-clip-stack.c', + 'cogl-feature-private.h', + 'cogl-feature-private.c', + 'cogl-color-private.h', + 'cogl-color.c', + 'cogl-buffer-private.h', + 'cogl-buffer.c', + 'cogl-pixel-buffer-private.h', + 'cogl-pixel-buffer.c', + 'cogl-index-buffer-private.h', + 'cogl-index-buffer.c', + 'cogl-attribute-buffer-private.h', + 'cogl-attribute-buffer.c', + 'cogl-indices-private.h', + 'cogl-indices.c', + 'cogl-attribute-private.h', + 'cogl-attribute.c', + 'cogl-primitive-private.h', + 'cogl-primitive.c', + 'cogl-matrix.c', + 'cogl-matrix-private.h', + 'cogl-matrix-stack.c', + 'cogl-matrix-stack-private.h', + 'cogl-depth-state.c', + 'cogl-depth-state-private.h', + 'cogl-node.c', + 'cogl-node-private.h', + 'cogl-pipeline.c', + 'cogl-pipeline-private.h', + 'cogl-pipeline-layer.c', + 'cogl-pipeline-layer-private.h', + 'cogl-pipeline-state.c', + 'cogl-pipeline-layer-state-private.h', + 'cogl-pipeline-layer-state.c', + 'cogl-pipeline-state-private.h', + 'cogl-pipeline-debug.c', + 'cogl-glsl-shader.c', + 'cogl-glsl-shader-private.h', + 'cogl-glsl-shader-boilerplate.h', + 'cogl-pipeline-snippet-private.h', + 'cogl-pipeline-snippet.c', + 'cogl-pipeline-cache.h', + 'cogl-pipeline-cache.c', + 'cogl-pipeline-hash-table.h', + 'cogl-pipeline-hash-table.c', + 'cogl-sampler-cache.c', + 'cogl-sampler-cache-private.h', + 'cogl-blend-string.c', + 'cogl-blend-string.h', + 'cogl-debug.c', + 'cogl-trace.c', + 'cogl-sub-texture-private.h', + 'cogl-texture-private.h', + 'cogl-texture-2d-private.h', + 'cogl-texture-2d-sliced-private.h', + 'cogl-texture-driver.h', + 'cogl-sub-texture.c', + 'cogl-texture.c', + 'cogl-texture-2d.c', + 'cogl-texture-2d-sliced.c', + 'cogl-rectangle-map.h', + 'cogl-rectangle-map.c', + 'cogl-atlas.h', + 'cogl-atlas.c', + 'cogl-atlas-texture-private.h', + 'cogl-atlas-texture.c', + 'cogl-meta-texture.c', + 'cogl-primitive-texture.c', + 'cogl-blit.h', + 'cogl-blit.c', + 'cogl-spans.h', + 'cogl-spans.c', + 'cogl-journal-private.h', + 'cogl-journal.c', + 'cogl-frame-info-private.h', + 'cogl-frame-info.c', + 'cogl-framebuffer-private.h', + 'cogl-framebuffer.c', + 'cogl-onscreen-private.h', + 'cogl-onscreen.c', + 'cogl-output-private.h', + 'cogl-output.c', + 'cogl-profile.h', + 'cogl-profile.c', + 'cogl-flags.h', + 'cogl-bitmask.h', + 'cogl-bitmask.c', + 'cogl-gtype.c', + 'cogl-gtype-private.h', + 'cogl-point-in-poly-private.h', + 'cogl-point-in-poly.c', + 'cogl-list.c', + 'cogl-list.h', + 'cogl-boxed-value.h', + 'cogl-boxed-value.c', + 'cogl-snippet-private.h', + 'cogl-snippet.c', + 'cogl-poll-private.h', + 'cogl-poll.c', + 'gl-prototypes/cogl-all-functions.h', + 'cogl-memory-stack-private.h', + 'cogl-memory-stack.c', + 'cogl-magazine-private.h', + 'cogl-magazine.c', + 'cogl-closure-list-private.h', + 'cogl-closure-list.c', + 'cogl-fence.c', + 'cogl-fence-private.h', + 'deprecated/cogl-material-compat.c', + 'deprecated/cogl-program.c', + 'deprecated/cogl-program-private.h', + 'deprecated/cogl-auto-texture.c', + 'deprecated/cogl-shader-private.h', + 'deprecated/cogl-shader.c', + 'deprecated/cogl-clutter.c', + 'cogl-glib-source.c', + 'cogl-mutter.h', +] + +if have_x11 + cogl_nonintrospected_headers += [ + 'winsys/cogl-texture-pixmap-x11.h', + 'cogl-xlib.h', + ] + cogl_sources += [ + 'cogl-x11-renderer-private.h', + 'cogl-xlib-private.h', + 'cogl-xlib-renderer-private.h', + 'cogl-xlib-renderer.c', + 'winsys/cogl-texture-pixmap-x11-private.h', + 'winsys/cogl-texture-pixmap-x11.c', + ] + cogl_headers += [ + 'cogl-xlib-renderer.h' + ] +endif + +if have_glx + cogl_nonintrospected_headers += [ + 'winsys/cogl-glx.h', + ] + cogl_sources += [ + 'winsys/cogl-glx-display-private.h', + 'winsys/cogl-glx-renderer-private.h', + 'winsys/cogl-winsys-glx-feature-functions.h', + 'winsys/cogl-winsys-glx-private.h', + 'winsys/cogl-winsys-glx.c', + ] +endif + +if have_wayland + cogl_nonintrospected_headers += [ + 'cogl-wayland-server.h', + ] +endif + +if have_egl + cogl_nonintrospected_headers += [ + 'cogl-egl.h', + cogl_egl_defines_h, + ] + cogl_sources += [ + 'cogl-egl-private.h', + 'winsys/cogl-winsys-egl.c', + 'winsys/cogl-winsys-egl-feature-functions.h', + 'winsys/cogl-winsys-egl-private.h', + ] +endif + +if have_egl_xlib + cogl_sources += [ + 'winsys/cogl-winsys-egl-x11.c', + 'winsys/cogl-winsys-egl-x11-private.h', + ] +endif + +cogl_introspected_headers = [ + cogl_headers, + cogl_deprecated_headers, +] + +cogl_headers_all = [ + cogl_introspected_headers, + cogl_nonintrospected_headers, + cogl_deprecated_headers, +] + +cogl_test_deps = [] + +if have_cogl_tests + cogl_test_deps += [libmutter_cogl_test_fixtures_dep] +endif + +libmutter_cogl_name = 'muffin-cogl-' + libmutter_api_version +libmutter_cogl = shared_library(libmutter_cogl_name, + sources: [cogl_sources, cogl_headers_all], + version: '0.0.0', + soversion: 0, + c_args: cogl_c_args, + include_directories: cogl_includepath, + dependencies: [cogl_deps, cogl_test_deps], + gnu_symbol_visibility: 'hidden', + install_rpath: pkglibdir, + install_dir: pkglibdir, + install: true, +) +libmutter_cogl_dep = declare_dependency( + dependencies: [cogl_deps], + link_with: libmutter_cogl, +) + +if have_introspection + libmutter_cogl_gir = gnome.generate_gir(libmutter_cogl, + sources: cogl_introspected_headers, + nsversion: libmutter_api_version, + namespace: 'Cogl', + includes: ['cairo-1.0', 'GL-1.0', 'GObject-2.0', 'Graphene-1.0'], + dependencies: [cogl_deps], + extra_args: introspection_args + [ + '-UCOGL_COMPILATION', + '-D__COGL_H_INSIDE__', + '-D__COGL_XLIB_H_INSIDE__', + '-D__COGL_EGL_H_INSIDE__', + '-D__COGL_GLX_H_INSIDE__', + '-DCOGL_GIR_SCANNING', + ], + header: 'cogl/cogl.h', + install_dir_gir: pkglibdir, + install_dir_typelib: pkglibdir, + install: true + ) +endif + +install_headers([ + cogl_headers, + cogl_nonintrospected_headers, + ], + subdir: cogl_cogl_includesubdir) + +install_headers([ + cogl_deprecated_headers, + ], + subdir: join_paths(cogl_cogl_includesubdir, 'deprecated')) + +install_headers(cogl_gl_prototype_headers, + subdir: join_paths(cogl_cogl_includesubdir, 'gl-prototypes')) + +pkg.generate(libmutter_cogl, + name: 'Cogl', + filebase: libmutter_cogl_name, + description: 'An object oriented GL/GLES Abstraction/Utility Layer in mutter', + libraries: [m_dep], + subdirs: join_paths(pkgname, 'cogl'), + requires: [cogl_pkg_deps], + version: meson.project_version(), + variables: [ + 'apiversion=' + libmutter_api_version, + ], + install_dir: pcdir, +) diff --git a/cogl/cogl/muffin-cogl.pc.in b/cogl/cogl/mutter-cogl.pc.in similarity index 51% rename from cogl/cogl/muffin-cogl.pc.in rename to cogl/cogl/mutter-cogl.pc.in index 13dcf5e11..797eef3d2 100644 --- a/cogl/cogl/muffin-cogl.pc.in +++ b/cogl/cogl/mutter-cogl.pc.in @@ -1,13 +1,13 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ -libdir=@libdir@/muffin -includedir=@includedir@/muffin -apiversion=@MUFFIN_PLUGIN_API_VERSION@ +apiversion=@LIBMUTTER_API_VERSION@ +libdir=@libdir@/mutter-${apiversion} +includedir=@includedir@/mutter-${apiversion} requires=@COGL_PKG_REQUIRES@ Name: Cogl Description: An object oriented GL/GLES Abstraction/Utility Layer -Version: @MUFFIN_VERSION@ -Libs: -L${libdir} -lmuffin-cogl-@MUFFIN_PLUGIN_API_VERSION@ +Version: @MUTTER_VERSION@ +Libs: -L${libdir} -lmutter-cogl-${apiversion} Cflags: -I${includedir}/cogl Requires: ${requires} diff --git a/cogl/cogl/cogl-glx-display-private.h b/cogl/cogl/winsys/cogl-glx-display-private.h similarity index 89% rename from cogl/cogl/cogl-glx-display-private.h rename to cogl/cogl/winsys/cogl-glx-display-private.h index 1d1afc0cf..265868c40 100644 --- a/cogl/cogl/cogl-glx-display-private.h +++ b/cogl/cogl/winsys/cogl-glx-display-private.h @@ -37,10 +37,10 @@ typedef struct _CoglGLXCachedConfig { /* This will be -1 if there is no cached config in this slot */ int depth; - CoglBool found; + gboolean found; GLXFBConfig fb_config; - CoglBool stereo; - CoglBool can_mipmap; + gboolean stereo; + gboolean can_mipmap; } CoglGLXCachedConfig; #define COGL_GLX_N_CACHED_CONFIGS 6 @@ -49,11 +49,11 @@ typedef struct _CoglGLXDisplay { CoglGLXCachedConfig glx_cached_configs[COGL_GLX_N_CACHED_CONFIGS]; - CoglBool found_fbconfig; - CoglBool fbconfig_has_rgba_visual; - CoglBool is_direct; - CoglBool have_vblank_counter; - CoglBool can_vblank_wait; + gboolean found_fbconfig; + gboolean fbconfig_has_rgba_visual; + gboolean is_direct; + gboolean have_vblank_counter; + gboolean can_vblank_wait; GLXFBConfig fbconfig; /* Single context for all wins */ diff --git a/cogl/cogl/cogl-glx-renderer-private.h b/cogl/cogl/winsys/cogl-glx-renderer-private.h similarity index 97% rename from cogl/cogl/cogl-glx-renderer-private.h rename to cogl/cogl/winsys/cogl-glx-renderer-private.h index 061f2ccb5..64ccf7c90 100644 --- a/cogl/cogl/cogl-glx-renderer-private.h +++ b/cogl/cogl/winsys/cogl-glx-renderer-private.h @@ -48,7 +48,8 @@ typedef struct _CoglGLXRenderer /* enumeration with relatioship between OML_sync_control * UST (unadjusted-system-time) and the system clock */ - enum { + enum +{ COGL_GLX_UST_IS_UNKNOWN, COGL_GLX_UST_IS_GETTIMEOFDAY, COGL_GLX_UST_IS_MONOTONIC_TIME, @@ -68,8 +69,6 @@ typedef struct _CoglGLXRenderer unsigned long base_winsys_features [COGL_FLAGS_N_LONGS_FOR_SIZE (COGL_WINSYS_FEATURE_N_FEATURES)]; - CoglFeatureFlags legacy_feature_flags; - /* Function pointers for core GLX functionality. We can't just link against these directly because we need to conditionally load libGL when we are using GLX so that it won't conflict with a GLES @@ -96,7 +95,7 @@ typedef struct _CoglGLXRenderer #define COGL_WINSYS_FEATURE_END() -#include "cogl-winsys-glx-feature-functions.h" +#include "winsys/cogl-winsys-glx-feature-functions.h" #undef COGL_WINSYS_FEATURE_BEGIN #undef COGL_WINSYS_FEATURE_FUNCTION diff --git a/cogl/cogl/cogl-glx.h b/cogl/cogl/winsys/cogl-glx.h similarity index 83% rename from cogl/cogl/cogl-glx.h rename to cogl/cogl/winsys/cogl-glx.h index 69963d7c2..b04656981 100644 --- a/cogl/cogl/cogl-glx.h +++ b/cogl/cogl/winsys/cogl-glx.h @@ -58,26 +58,6 @@ #include #include -COGL_BEGIN_DECLS - -/** - * cogl_glx_context_get_glx_context: - * @context: A #CoglContext pointer - * - * If you have done a runtime check to determine that Cogl is using - * GLX internally then this API can be used to retrieve the GLXContext - * handle that was setup internally. The result is undefined if Cogl - * is not using GLX. - * - * Return value: The internally setup GLXContext handle. - * Since: 1.18 - * Stability: unstable - */ -GLXContext -cogl_glx_context_get_glx_context (CoglContext *context); - -COGL_END_DECLS - /* The gobject introspection scanner seems to parse public headers in * isolation which means we need to be extra careful about how we * define and undefine __COGL_H_INSIDE__ used to detect when internal diff --git a/cogl/cogl/winsys/cogl-texture-pixmap-x11-private.h b/cogl/cogl/winsys/cogl-texture-pixmap-x11-private.h index 5da998f89..c1d6d9361 100644 --- a/cogl/cogl/winsys/cogl-texture-pixmap-x11-private.h +++ b/cogl/cogl/winsys/cogl-texture-pixmap-x11-private.h @@ -88,7 +88,7 @@ struct _CoglTexturePixmapX11 Damage damage; CoglTexturePixmapX11ReportLevel damage_report_level; - CoglBool damage_owned; + gboolean damage_owned; CoglDamageRectangle damage_rect; void *winsys; @@ -96,7 +96,7 @@ struct _CoglTexturePixmapX11 /* During the pre_paint method, this will be set to TRUE if we should use the winsys texture, otherwise we will use the regular texture */ - CoglBool use_winsys_texture; + gboolean use_winsys_texture; }; diff --git a/cogl/cogl/winsys/cogl-texture-pixmap-x11.c b/cogl/cogl/winsys/cogl-texture-pixmap-x11.c index e32225ba0..05c6439dd 100644 --- a/cogl/cogl/winsys/cogl-texture-pixmap-x11.c +++ b/cogl/cogl/winsys/cogl-texture-pixmap-x11.c @@ -33,9 +33,7 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-debug.h" #include "cogl-util.h" @@ -46,18 +44,17 @@ #include "cogl-texture-driver.h" #include "cogl-texture-2d-private.h" #include "cogl-texture-2d-sliced.h" -#include "cogl-texture-rectangle-private.h" #include "cogl-context-private.h" #include "cogl-display-private.h" #include "cogl-renderer-private.h" #include "cogl-object-private.h" -#include "cogl-winsys-private.h" -#include "cogl-pipeline-opengl-private.h" #include "cogl-xlib.h" -#include "cogl-error-private.h" -#include "cogl-texture-gl-private.h" +#include "cogl-xlib-renderer-private.h" +#include "cogl-x11-renderer-private.h" #include "cogl-private.h" #include "cogl-gtype-private.h" +#include "driver/gl/cogl-texture-gl-private.h" +#include "winsys/cogl-winsys-private.h" #include #include @@ -112,7 +109,7 @@ cogl_damage_rectangle_union (CoglDamageRectangle *damage_rect, } } -static CoglBool +static gboolean cogl_damage_rectangle_is_whole (const CoglDamageRectangle *damage_rect, unsigned int width, unsigned int height) @@ -137,7 +134,8 @@ process_damage_event (CoglTexturePixmapX11 *tex_pixmap, { CoglTexture *tex = COGL_TEXTURE (tex_pixmap); Display *display; - enum { DO_NOTHING, NEEDS_SUBTRACT, NEED_BOUNDING_BOX } handle_mode; + enum +{ DO_NOTHING, NEEDS_SUBTRACT, NEED_BOUNDING_BOX } handle_mode; const CoglWinsysVtable *winsys; _COGL_GET_CONTEXT (ctxt, NO_RETVAL); @@ -234,6 +232,17 @@ process_damage_event (CoglTexturePixmapX11 *tex_pixmap, } } +static int +_cogl_xlib_get_damage_base (void) +{ + CoglX11Renderer *x11_renderer; + _COGL_GET_CONTEXT (ctxt, -1); + + x11_renderer = + (CoglX11Renderer *) _cogl_xlib_renderer_get_data (ctxt->display->renderer); + return x11_renderer->damage_base; +} + static CoglFilterReturn _cogl_texture_pixmap_x11_filter (XEvent *event, void *data) { @@ -287,9 +296,9 @@ set_damage_object_internal (CoglContext *ctx, static CoglTexturePixmapX11 * _cogl_texture_pixmap_x11_new (CoglContext *ctxt, uint32_t pixmap, - CoglBool automatic_updates, + gboolean automatic_updates, CoglTexturePixmapStereoMode stereo_mode, - CoglError **error) + GError **error) { CoglTexturePixmapX11 *tex_pixmap = g_new (CoglTexturePixmapX11, 1); Display *display = cogl_xlib_renderer_get_display (ctxt->display->renderer); @@ -308,11 +317,11 @@ _cogl_texture_pixmap_x11_new (CoglContext *ctxt, &pixmap_width, &pixmap_height, &pixmap_border_width, &tex_pixmap->depth)) { - free (tex_pixmap); - _cogl_set_error (error, - COGL_TEXTURE_PIXMAP_X11_ERROR, - COGL_TEXTURE_PIXMAP_X11_ERROR_X11, - "Unable to query pixmap size"); + g_free (tex_pixmap); + g_set_error_literal (error, + COGL_TEXTURE_PIXMAP_X11_ERROR, + COGL_TEXTURE_PIXMAP_X11_ERROR_X11, + "Unable to query pixmap size"); return NULL; } @@ -340,11 +349,11 @@ _cogl_texture_pixmap_x11_new (CoglContext *ctxt, it from the pixmap's root window */ if (!XGetWindowAttributes (display, pixmap_root_window, &window_attributes)) { - free (tex_pixmap); - _cogl_set_error (error, - COGL_TEXTURE_PIXMAP_X11_ERROR, - COGL_TEXTURE_PIXMAP_X11_ERROR_X11, - "Unable to query root window attributes"); + g_free (tex_pixmap); + g_set_error_literal (error, + COGL_TEXTURE_PIXMAP_X11_ERROR, + COGL_TEXTURE_PIXMAP_X11_ERROR_X11, + "Unable to query root window attributes"); return NULL; } @@ -393,8 +402,8 @@ _cogl_texture_pixmap_x11_new (CoglContext *ctxt, CoglTexturePixmapX11 * cogl_texture_pixmap_x11_new (CoglContext *ctxt, uint32_t pixmap, - CoglBool automatic_updates, - CoglError **error) + gboolean automatic_updates, + GError **error) { return _cogl_texture_pixmap_x11_new (ctxt, pixmap, @@ -405,8 +414,8 @@ cogl_texture_pixmap_x11_new (CoglContext *ctxt, CoglTexturePixmapX11 * cogl_texture_pixmap_x11_new_left (CoglContext *ctxt, uint32_t pixmap, - CoglBool automatic_updates, - CoglError **error) + gboolean automatic_updates, + GError **error) { return _cogl_texture_pixmap_x11_new (ctxt, pixmap, automatic_updates, COGL_TEXTURE_PIXMAP_LEFT, @@ -443,9 +452,9 @@ cogl_texture_pixmap_x11_new_right (CoglTexturePixmapX11 *tfp_left) return _cogl_texture_pixmap_x11_object_new (tfp_right); } -static CoglBool +static gboolean _cogl_texture_pixmap_x11_allocate (CoglTexture *tex, - CoglError **error) + GError **error) { return TRUE; } @@ -548,7 +557,7 @@ cogl_texture_pixmap_x11_update_area (CoglTexturePixmapX11 *tex_pixmap, x, y, width, height); } -CoglBool +gboolean cogl_texture_pixmap_x11_is_using_tfp_extension (CoglTexturePixmapX11 *tex_pixmap) { if (tex_pixmap->stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT) @@ -557,23 +566,6 @@ cogl_texture_pixmap_x11_is_using_tfp_extension (CoglTexturePixmapX11 *tex_pixmap return !!tex_pixmap->winsys; } -void -cogl_texture_pixmap_x11_set_damage_object (CoglTexturePixmapX11 *tex_pixmap, - uint32_t damage, - CoglTexturePixmapX11ReportLevel - report_level) -{ - int damage_base; - - _COGL_GET_CONTEXT (ctxt, NO_RETVAL); - - g_return_if_fail (tex_pixmap->stereo_mode != COGL_TEXTURE_PIXMAP_RIGHT); - - damage_base = _cogl_xlib_get_damage_base (); - if (damage_base >= 0) - set_damage_object_internal (ctxt, tex_pixmap, damage, report_level); -} - static CoglTexture * create_fallback_texture (CoglContext *ctx, int width, @@ -581,31 +573,23 @@ create_fallback_texture (CoglContext *ctx, CoglPixelFormat internal_format) { CoglTexture *tex; - CoglError *skip_error = NULL; + GError *skip_error = NULL; - if ((_cogl_util_is_pot (width) && _cogl_util_is_pot (height)) || - (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_BASIC) && - cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP))) - { - /* First try creating a fast-path non-sliced texture */ - tex = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx, - width, height)); + /* First try creating a fast-path non-sliced texture */ + tex = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx, width, height)); - _cogl_texture_set_internal_format (tex, internal_format); + _cogl_texture_set_internal_format (tex, internal_format); - /* TODO: instead of allocating storage here it would be better - * if we had some api that let us just check that the size is - * supported by the hardware so storage could be allocated - * lazily when uploading data. */ - if (!cogl_texture_allocate (tex, &skip_error)) - { - cogl_error_free (skip_error); - cogl_object_unref (tex); - tex = NULL; - } + /* TODO: instead of allocating storage here it would be better + * if we had some api that let us just check that the size is + * supported by the hardware so storage could be allocated + * lazily when uploading data. */ + if (!cogl_texture_allocate (tex, &skip_error)) + { + g_error_free (skip_error); + cogl_object_unref (tex); + tex = NULL; } - else - tex = NULL; if (!tex) { @@ -634,7 +618,7 @@ _cogl_texture_pixmap_x11_update_image_texture (CoglTexturePixmapX11 *tex_pixmap) int x, y, width, height; int bpp; int offset; - CoglError *ignore = NULL; + GError *ignore = NULL; _COGL_GET_CONTEXT (ctx, NO_RETVAL); @@ -740,8 +724,9 @@ _cogl_texture_pixmap_x11_update_image_texture (CoglTexturePixmapX11 *tex_pixmap) image->depth, image->bits_per_pixel, image->byte_order == LSBFirst); + g_return_if_fail (cogl_pixel_format_get_n_planes (image_format) == 1); - bpp = _cogl_pixel_format_get_bytes_per_pixel (image_format); + bpp = cogl_pixel_format_get_bytes_per_pixel (image_format, 0); offset = image->bytes_per_line * src_y + bpp * src_x; _cogl_texture_set_region (tex_pixmap->tex, @@ -764,7 +749,7 @@ _cogl_texture_pixmap_x11_update_image_texture (CoglTexturePixmapX11 *tex_pixmap) static void _cogl_texture_pixmap_x11_set_use_winsys_texture (CoglTexturePixmapX11 *tex_pixmap, - CoglBool new_value) + gboolean new_value) { if (tex_pixmap->use_winsys_texture != new_value) { @@ -779,7 +764,7 @@ _cogl_texture_pixmap_x11_set_use_winsys_texture (CoglTexturePixmapX11 *tex_pixma static void _cogl_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap, - CoglBool needs_mipmap) + gboolean needs_mipmap) { CoglTexturePixmapStereoMode stereo_mode = tex_pixmap->stereo_mode; if (stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT) @@ -846,7 +831,7 @@ _cogl_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap) return NULL; } -static CoglBool +static gboolean _cogl_texture_pixmap_x11_set_region (CoglTexture *tex, int src_x, int src_y, @@ -856,18 +841,19 @@ _cogl_texture_pixmap_x11_set_region (CoglTexture *tex, int dst_height, int level, CoglBitmap *bmp, - CoglError **error) + GError **error) { /* This doesn't make much sense for texture from pixmap so it's not supported */ - _cogl_set_error (error, - COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_UNSUPPORTED, - "Explicitly setting a region of a TFP texture unsupported"); + g_set_error_literal (error, + COGL_SYSTEM_ERROR, + COGL_SYSTEM_ERROR_UNSUPPORTED, + "Explicitly setting a region of a TFP texture " + "unsupported"); return FALSE; } -static CoglBool +static gboolean _cogl_texture_pixmap_x11_get_data (CoglTexture *tex, CoglPixelFormat format, int rowstride, @@ -880,33 +866,6 @@ _cogl_texture_pixmap_x11_get_data (CoglTexture *tex, return cogl_texture_get_data (child_tex, format, rowstride, data); } -typedef struct _NormalizeCoordsWrapperData -{ - int width; - int height; - CoglMetaTextureCallback callback; - void *user_data; -} NormalizeCoordsWrapperData; - -static void -normalize_coords_wrapper_cb (CoglTexture *child_texture, - const float *child_texture_coords, - const float *meta_coords, - void *user_data) -{ - NormalizeCoordsWrapperData *data = user_data; - float normalized_coords[4]; - - normalized_coords[0] = meta_coords[0] / data->width; - normalized_coords[1] = meta_coords[1] / data->height; - normalized_coords[2] = meta_coords[2] / data->width; - normalized_coords[3] = meta_coords[3] / data->height; - - data->callback (child_texture, - child_texture_coords, normalized_coords, - data->user_data); -} - static void _cogl_texture_pixmap_x11_foreach_sub_texture_in_region (CoglTexture *tex, @@ -921,47 +880,15 @@ _cogl_texture_pixmap_x11_foreach_sub_texture_in_region CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); /* Forward on to the child texture */ - - /* tfp textures may be implemented in terms of a - * CoglTextureRectangle texture which uses un-normalized texture - * coordinates but we want to consistently deal with normalized - * texture coordinates with CoglTexturePixmapX11... */ - if (cogl_is_texture_rectangle (child_tex)) - { - NormalizeCoordsWrapperData data; - int width = tex->width; - int height = tex->height; - - virtual_tx_1 *= width; - virtual_ty_1 *= height; - virtual_tx_2 *= width; - virtual_ty_2 *= height; - - data.width = width; - data.height = height; - data.callback = callback; - data.user_data = user_data; - - cogl_meta_texture_foreach_in_region (COGL_META_TEXTURE (child_tex), - virtual_tx_1, - virtual_ty_1, - virtual_tx_2, - virtual_ty_2, - COGL_PIPELINE_WRAP_MODE_REPEAT, - COGL_PIPELINE_WRAP_MODE_REPEAT, - normalize_coords_wrapper_cb, - &data); - } - else - cogl_meta_texture_foreach_in_region (COGL_META_TEXTURE (child_tex), - virtual_tx_1, - virtual_ty_1, - virtual_tx_2, - virtual_ty_2, - COGL_PIPELINE_WRAP_MODE_REPEAT, - COGL_PIPELINE_WRAP_MODE_REPEAT, - callback, - user_data); + cogl_meta_texture_foreach_in_region (COGL_META_TEXTURE (child_tex), + virtual_tx_1, + virtual_ty_1, + virtual_tx_2, + virtual_ty_2, + COGL_PIPELINE_WRAP_MODE_REPEAT, + COGL_PIPELINE_WRAP_MODE_REPEAT, + callback, + user_data); } static int @@ -973,7 +900,7 @@ _cogl_texture_pixmap_x11_get_max_waste (CoglTexture *tex) return cogl_texture_get_max_waste (child_tex); } -static CoglBool +static gboolean _cogl_texture_pixmap_x11_is_sliced (CoglTexture *tex) { CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); @@ -982,7 +909,7 @@ _cogl_texture_pixmap_x11_is_sliced (CoglTexture *tex) return cogl_texture_is_sliced (child_tex); } -static CoglBool +static gboolean _cogl_texture_pixmap_x11_can_hardware_repeat (CoglTexture *tex) { CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); @@ -1014,7 +941,7 @@ _cogl_texture_pixmap_x11_transform_quad_coords_to_gl (CoglTexture *tex, return _cogl_texture_transform_quad_coords_to_gl (child_tex, coords); } -static CoglBool +static gboolean _cogl_texture_pixmap_x11_get_gl_texture (CoglTexture *tex, GLuint *out_gl_handle, GLenum *out_gl_target) @@ -1069,8 +996,7 @@ _cogl_texture_pixmap_x11_ensure_non_quad_rendering (CoglTexture *tex) static void _cogl_texture_pixmap_x11_gl_flush_legacy_texobj_wrap_modes (CoglTexture *tex, GLenum wrap_mode_s, - GLenum wrap_mode_t, - GLenum wrap_mode_p) + GLenum wrap_mode_t) { CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); @@ -1078,8 +1004,7 @@ _cogl_texture_pixmap_x11_gl_flush_legacy_texobj_wrap_modes (CoglTexture *tex, /* Forward on to the child texture */ _cogl_texture_gl_flush_legacy_texobj_wrap_modes (child_tex, wrap_mode_s, - wrap_mode_t, - wrap_mode_p); + wrap_mode_t); } static CoglPixelFormat @@ -1101,18 +1026,6 @@ _cogl_texture_pixmap_x11_get_gl_format (CoglTexture *tex) return _cogl_texture_gl_get_format (child_tex); } -static CoglTextureType -_cogl_texture_pixmap_x11_get_type (CoglTexture *tex) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex; - - child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - return _cogl_texture_get_type (child_tex); -} - static void _cogl_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap) { @@ -1164,6 +1077,7 @@ cogl_texture_pixmap_x11_vtable = FALSE, /* not primitive */ _cogl_texture_pixmap_x11_allocate, _cogl_texture_pixmap_x11_set_region, + NULL, /* is_get_data_supported */ _cogl_texture_pixmap_x11_get_data, _cogl_texture_pixmap_x11_foreach_sub_texture_in_region, _cogl_texture_pixmap_x11_get_max_waste, @@ -1178,7 +1092,5 @@ cogl_texture_pixmap_x11_vtable = _cogl_texture_pixmap_x11_gl_flush_legacy_texobj_wrap_modes, _cogl_texture_pixmap_x11_get_format, _cogl_texture_pixmap_x11_get_gl_format, - _cogl_texture_pixmap_x11_get_type, - NULL, /* is_foreign */ NULL /* set_auto_mipmap */ }; diff --git a/cogl/cogl/winsys/cogl-texture-pixmap-x11.h b/cogl/cogl/winsys/cogl-texture-pixmap-x11.h index 4c86c6858..8103cf379 100644 --- a/cogl/cogl/winsys/cogl-texture-pixmap-x11.h +++ b/cogl/cogl/winsys/cogl-texture-pixmap-x11.h @@ -52,7 +52,7 @@ #include -COGL_BEGIN_DECLS +G_BEGIN_DECLS /** * SECTION:cogl-texture-pixmap-x11 @@ -73,6 +73,7 @@ typedef struct _CoglTexturePixmapX11 CoglTexturePixmapX11; * * Returns: a #GType that can be used with the GLib type system. */ +COGL_EXPORT GType cogl_texture_pixmap_x11_get_gtype (void); typedef enum @@ -86,7 +87,7 @@ typedef enum /** * COGL_TEXTURE_PIXMAP_X11_ERROR: * - * #CoglError domain for texture-pixmap-x11 errors. + * #GError domain for texture-pixmap-x11 errors. * * Since: 1.10 */ @@ -101,10 +102,12 @@ typedef enum * * Since: 1.10 */ -typedef enum { +typedef enum +{ COGL_TEXTURE_PIXMAP_X11_ERROR_X11, } CoglTexturePixmapX11Error; +COGL_EXPORT uint32_t cogl_texture_pixmap_x11_error_quark (void); /** @@ -113,7 +116,7 @@ uint32_t cogl_texture_pixmap_x11_error_quark (void); * @pixmap: A X11 pixmap ID * @automatic_updates: Whether to automatically copy the contents of * the pixmap to the texture. - * @error: A #CoglError for exceptions + * @error: A #GError for exceptions * * Creates a texture that contains the contents of @pixmap. If * @automatic_updates is %TRUE then Cogl will attempt to listen for @@ -125,11 +128,11 @@ uint32_t cogl_texture_pixmap_x11_error_quark (void); * Since: 1.10 * Stability: Unstable */ -CoglTexturePixmapX11 * +COGL_EXPORT CoglTexturePixmapX11 * cogl_texture_pixmap_x11_new (CoglContext *context, uint32_t pixmap, - CoglBool automatic_updates, - CoglError **error); + gboolean automatic_updates, + GError **error); /** * cogl_texture_pixmap_x11_new_left: @@ -137,7 +140,7 @@ cogl_texture_pixmap_x11_new (CoglContext *context, * @pixmap: A X11 pixmap ID * @automatic_updates: Whether to automatically copy the contents of * the pixmap to the texture. - * @error: A #CoglError for exceptions + * @error: A #GError for exceptions * * Creates one of a pair of textures to contain the contents of @pixmap, * which has stereo content. (Different images for the right and left eyes.) @@ -164,11 +167,11 @@ cogl_texture_pixmap_x11_new (CoglContext *context, * Since: 1.20 * Stability: Unstable */ -CoglTexturePixmapX11 * +COGL_EXPORT CoglTexturePixmapX11 * cogl_texture_pixmap_x11_new_left (CoglContext *context, uint32_t pixmap, - CoglBool automatic_updates, - CoglError **error); + gboolean automatic_updates, + GError **error); /** * cogl_texture_pixmap_x11_new_right: @@ -184,7 +187,7 @@ cogl_texture_pixmap_x11_new_left (CoglContext *context, * Since: 1.20 * Stability: Unstable */ -CoglTexturePixmapX11 * +COGL_EXPORT CoglTexturePixmapX11 * cogl_texture_pixmap_x11_new_right (CoglTexturePixmapX11 *left_texture); /** @@ -202,7 +205,7 @@ cogl_texture_pixmap_x11_new_right (CoglTexturePixmapX11 *left_texture); * Since: 1.4 * Stability: Unstable */ -void +COGL_EXPORT void cogl_texture_pixmap_x11_update_area (CoglTexturePixmapX11 *texture, int x, int y, @@ -225,34 +228,9 @@ cogl_texture_pixmap_x11_update_area (CoglTexturePixmapX11 *texture, * Since: 1.4 * Stability: Unstable */ -CoglBool +COGL_EXPORT gboolean cogl_texture_pixmap_x11_is_using_tfp_extension (CoglTexturePixmapX11 *texture); -/** - * cogl_texture_pixmap_x11_set_damage_object: - * @texture: A #CoglTexturePixmapX11 instance - * @damage: A X11 Damage object or 0 - * @report_level: The report level which describes how to interpret - * the damage events. This should match the level that the damage - * object was created with. - * - * Sets the damage object that will be used to track automatic updates - * to the @texture. Damage tracking can be disabled by passing 0 for - * @damage. Otherwise this damage will replace the one used if %TRUE - * was passed for automatic_updates to cogl_texture_pixmap_x11_new(). - * - * Note that Cogl will subtract from the damage region as it processes - * damage events. - * - * Since: 1.4 - * Stability: Unstable - */ -void -cogl_texture_pixmap_x11_set_damage_object (CoglTexturePixmapX11 *texture, - uint32_t damage, - CoglTexturePixmapX11ReportLevel - report_level); - /** * cogl_is_texture_pixmap_x11: * @object: A pointer to a #CoglObject @@ -265,10 +243,10 @@ cogl_texture_pixmap_x11_set_damage_object (CoglTexturePixmapX11 *texture, * Since: 1.4 * Stability: Unstable */ -CoglBool +COGL_EXPORT gboolean cogl_is_texture_pixmap_x11 (void *object); -COGL_END_DECLS +G_END_DECLS /* The gobject introspection scanner seems to parse public headers in * isolation which means we need to be extra careful about how we diff --git a/cogl/cogl/winsys/cogl-winsys-egl-feature-functions.h b/cogl/cogl/winsys/cogl-winsys-egl-feature-functions.h index 17a99f269..bbe4912bc 100644 --- a/cogl/cogl/winsys/cogl-winsys-egl-feature-functions.h +++ b/cogl/cogl/winsys/cogl-winsys-egl-feature-functions.h @@ -147,3 +147,9 @@ COGL_WINSYS_FEATURE_BEGIN (surfaceless_context, "surfaceless_context\0", COGL_EGL_WINSYS_FEATURE_SURFACELESS_CONTEXT) COGL_WINSYS_FEATURE_END () + +COGL_WINSYS_FEATURE_BEGIN (context_priority, + "IMG\0", + "context_priority\0", + COGL_EGL_WINSYS_FEATURE_CONTEXT_PRIORITY) +COGL_WINSYS_FEATURE_END () diff --git a/cogl/cogl/winsys/cogl-winsys-egl-private.h b/cogl/cogl/winsys/cogl-winsys-egl-private.h index 1db2cd481..8aea7c92b 100644 --- a/cogl/cogl/winsys/cogl-winsys-egl-private.h +++ b/cogl/cogl/winsys/cogl-winsys-egl-private.h @@ -32,10 +32,10 @@ #define __COGL_WINSYS_EGL_PRIVATE_H #include "cogl-defines.h" -#include "cogl-winsys-private.h" #include "cogl-context.h" #include "cogl-context-private.h" #include "cogl-framebuffer-private.h" +#include "winsys/cogl-winsys-private.h" /* XXX: depending on what version of Mesa you have then * eglQueryWaylandBuffer may take a wl_buffer or wl_resource argument @@ -60,29 +60,29 @@ struct wl_resource; typedef struct _CoglWinsysEGLVtable { - CoglBool + gboolean (* display_setup) (CoglDisplay *display, - CoglError **error); + GError **error); void (* display_destroy) (CoglDisplay *display); - CoglBool + gboolean (* context_created) (CoglDisplay *display, - CoglError **error); + GError **error); void (* cleanup_context) (CoglDisplay *display); - CoglBool - (* context_init) (CoglContext *context, CoglError **error); + gboolean + (* context_init) (CoglContext *context, GError **error); void (* context_deinit) (CoglContext *context); - CoglBool + gboolean (* onscreen_init) (CoglOnscreen *onscreen, EGLConfig config, - CoglError **error); + GError **error); void (* onscreen_deinit) (CoglOnscreen *onscreen); @@ -90,11 +90,11 @@ typedef struct _CoglWinsysEGLVtable (* add_config_attributes) (CoglDisplay *display, CoglFramebufferConfig *config, EGLint *attributes); - CoglBool + gboolean (* choose_config) (CoglDisplay *display, EGLint *attributes, EGLConfig *out_config, - CoglError **error); + GError **error); } CoglWinsysEGLVtable; typedef enum _CoglEGLWinsysFeature @@ -105,7 +105,8 @@ typedef enum _CoglEGLWinsysFeature COGL_EGL_WINSYS_FEATURE_CREATE_CONTEXT =1L<<3, COGL_EGL_WINSYS_FEATURE_BUFFER_AGE =1L<<4, COGL_EGL_WINSYS_FEATURE_FENCE_SYNC =1L<<5, - COGL_EGL_WINSYS_FEATURE_SURFACELESS_CONTEXT =1L<<6 + COGL_EGL_WINSYS_FEATURE_SURFACELESS_CONTEXT =1L<<6, + COGL_EGL_WINSYS_FEATURE_CONTEXT_PRIORITY =1L<<7, } CoglEGLWinsysFeature; typedef struct _CoglRendererEGL @@ -132,7 +133,7 @@ typedef struct _CoglRendererEGL #define COGL_WINSYS_FEATURE_END() -#include "cogl-winsys-egl-feature-functions.h" +#include "winsys/cogl-winsys-egl-feature-functions.h" #undef COGL_WINSYS_FEATURE_BEGIN #undef COGL_WINSYS_FEATURE_FUNCTION @@ -146,7 +147,7 @@ typedef struct _CoglDisplayEGL EGLSurface egl_surface; EGLConfig egl_config; - CoglBool found_egl_config; + gboolean found_egl_config; EGLSurface current_read_surface; EGLSurface current_draw_surface; @@ -166,22 +167,22 @@ typedef struct _CoglOnscreenEGL { EGLSurface egl_surface; - CoglBool pending_resize_notify; + gboolean pending_resize_notify; /* Platform specific data */ void *platform; } CoglOnscreenEGL; -const CoglWinsysVtable * +COGL_EXPORT const CoglWinsysVtable * _cogl_winsys_egl_get_vtable (void); -EGLBoolean +COGL_EXPORT EGLBoolean _cogl_winsys_egl_make_current (CoglDisplay *display, EGLSurface draw, EGLSurface read, EGLContext context); -EGLBoolean +COGL_EXPORT EGLBoolean _cogl_winsys_egl_ensure_current (CoglDisplay *display); #ifdef EGL_KHR_image_base @@ -197,15 +198,15 @@ _cogl_egl_destroy_image (CoglContext *ctx, #endif #ifdef EGL_WL_bind_wayland_display -CoglBool +gboolean _cogl_egl_query_wayland_buffer (CoglContext *ctx, struct wl_resource *buffer, int attribute, int *value); #endif -CoglBool +COGL_EXPORT gboolean _cogl_winsys_egl_renderer_connect_common (CoglRenderer *renderer, - CoglError **error); + GError **error); #endif /* __COGL_WINSYS_EGL_PRIVATE_H */ diff --git a/cogl/cogl/winsys/cogl-winsys-egl-x11-private.h b/cogl/cogl/winsys/cogl-winsys-egl-x11-private.h index 206d4850d..5b84941f6 100644 --- a/cogl/cogl/winsys/cogl-winsys-egl-x11-private.h +++ b/cogl/cogl/winsys/cogl-winsys-egl-x11-private.h @@ -31,9 +31,9 @@ #ifndef __COGL_WINSYS_EGL_X11_PRIVATE_H #define __COGL_WINSYS_EGL_X11_PRIVATE_H -#include "cogl-winsys-private.h" +#include "winsys/cogl-winsys-private.h" -const CoglWinsysVtable * +COGL_EXPORT const CoglWinsysVtable * _cogl_winsys_egl_xlib_get_vtable (void); #endif /* __COGL_WINSYS_EGL_X11_PRIVATE_H */ diff --git a/cogl/cogl/winsys/cogl-winsys-egl-x11.c b/cogl/cogl/winsys/cogl-winsys-egl-x11.c index bdf9b263a..aad6a12ca 100644 --- a/cogl/cogl/winsys/cogl-winsys-egl-x11.c +++ b/cogl/cogl/winsys/cogl-winsys-egl-x11.c @@ -31,26 +31,22 @@ * Neil Roberts */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include -#include "cogl-winsys-egl-x11-private.h" -#include "cogl-winsys-egl-private.h" #include "cogl-xlib-renderer-private.h" #include "cogl-xlib-renderer.h" #include "cogl-framebuffer-private.h" #include "cogl-onscreen-private.h" #include "cogl-display-private.h" #include "cogl-renderer-private.h" - #include "cogl-texture-pixmap-x11-private.h" #include "cogl-texture-2d-private.h" #include "cogl-texture-2d.h" -#include "cogl-error-private.h" #include "cogl-poll-private.h" +#include "winsys/cogl-winsys-egl-x11-private.h" +#include "winsys/cogl-winsys-egl-private.h" #define COGL_ONSCREEN_X11_EVENT_MASK (StructureNotifyMask | ExposureMask) @@ -64,7 +60,6 @@ typedef struct _CoglDisplayXlib typedef struct _CoglOnscreenXlib { Window xwin; - CoglBool is_foreign_xwin; } CoglOnscreenXlib; #ifdef EGL_KHR_image_pixmap @@ -86,7 +81,7 @@ find_onscreen_for_xid (CoglContext *context, uint32_t xid) CoglOnscreenEGL *egl_onscreen; CoglOnscreenXlib *xlib_onscreen; - if (!framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN) + if (framebuffer->type != COGL_FRAMEBUFFER_TYPE_ONSCREEN) continue; egl_onscreen = COGL_ONSCREEN (framebuffer)->winsys; @@ -295,9 +290,9 @@ _cogl_winsys_egl_get_display (void *native) return eglGetDisplay ((EGLNativeDisplayType) native); } -static CoglBool +static gboolean _cogl_winsys_renderer_connect (CoglRenderer *renderer, - CoglError **error) + GError **error) { CoglRendererEGL *egl_renderer; CoglXlibRenderer *xlib_renderer; @@ -336,11 +331,11 @@ _cogl_winsys_egl_add_config_attributes (CoglDisplay *display, return i; } -static CoglBool +static gboolean _cogl_winsys_egl_choose_config (CoglDisplay *display, EGLint *attributes, EGLConfig *out_config, - CoglError **error) + GError **error) { CoglRenderer *renderer = display->renderer; CoglRendererEGL *egl_renderer = renderer->winsys; @@ -353,18 +348,18 @@ _cogl_winsys_egl_choose_config (CoglDisplay *display, &config_count); if (status != EGL_TRUE || config_count == 0) { - _cogl_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "No compatible EGL configs found"); + g_set_error (error, COGL_WINSYS_ERROR, + COGL_WINSYS_ERROR_CREATE_CONTEXT, + "No compatible EGL configs found"); return FALSE; } return TRUE; } -static CoglBool +static gboolean _cogl_winsys_egl_display_setup (CoglDisplay *display, - CoglError **error) + GError **error) { CoglDisplayEGL *egl_display = display->winsys; CoglDisplayXlib *xlib_display; @@ -383,17 +378,14 @@ _cogl_winsys_egl_display_destroy (CoglDisplay *display) g_slice_free (CoglDisplayXlib, egl_display->platform); } -static CoglBool +static gboolean _cogl_winsys_egl_context_init (CoglContext *context, - CoglError **error) + GError **error) { cogl_xlib_renderer_add_filter (context->display->renderer, event_filter_cb, context); - context->feature_flags |= COGL_FEATURE_ONSCREEN_MULTIPLE; - COGL_FLAGS_SET (context->features, - COGL_FEATURE_ID_ONSCREEN_MULTIPLE, TRUE); COGL_FLAGS_SET (context->winsys_features, COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN, TRUE); @@ -415,10 +407,10 @@ _cogl_winsys_egl_context_deinit (CoglContext *context) context); } -static CoglBool +static gboolean _cogl_winsys_egl_onscreen_init (CoglOnscreen *onscreen, EGLConfig egl_config, - CoglError **error) + GError **error) { CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); CoglContext *context = framebuffer->context; @@ -432,51 +424,10 @@ _cogl_winsys_egl_onscreen_init (CoglOnscreen *onscreen, Window xwin; /* FIXME: We need to explicitly Select for ConfigureNotify events. - * For foreign windows we need to be careful not to mess up any - * existing event mask. * We need to document that for windows we create then toolkits * must be careful not to clear event mask bits that we select. */ - /* XXX: Note we ignore the user's original width/height when - * given a foreign X window. */ - if (onscreen->foreign_xid) - { - Status status; - CoglXlibTrapState state; - XWindowAttributes attr; - int xerror; - - xwin = onscreen->foreign_xid; - - _cogl_xlib_renderer_trap_errors (display->renderer, &state); - - status = XGetWindowAttributes (xlib_renderer->xdpy, xwin, &attr); - xerror = _cogl_xlib_renderer_untrap_errors (display->renderer, - &state); - if (status == 0 || xerror) - { - char message[1000]; - XGetErrorText (xlib_renderer->xdpy, xerror, - message, sizeof (message)); - _cogl_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_ONSCREEN, - "Unable to query geometry of foreign " - "xid 0x%08lX: %s", - xwin, message); - return FALSE; - } - - _cogl_framebuffer_winsys_update_size (framebuffer, - attr.width, attr.height); - - /* Make sure the app selects for the events we require... */ - onscreen->foreign_update_mask_callback (onscreen, - COGL_ONSCREEN_X11_EVENT_MASK, - onscreen-> - foreign_update_mask_data); - } - else { int width; int height; @@ -494,7 +445,7 @@ _cogl_winsys_egl_onscreen_init (CoglOnscreen *onscreen, xvisinfo = get_visual_info (display, egl_config); if (xvisinfo == NULL) { - _cogl_set_error (error, COGL_WINSYS_ERROR, + g_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_ONSCREEN, "Unable to retrieve the X11 visual of context's " "fbconfig"); @@ -536,7 +487,7 @@ _cogl_winsys_egl_onscreen_init (CoglOnscreen *onscreen, char message[1000]; XGetErrorText (xlib_renderer->xdpy, xerror, message, sizeof (message)); - _cogl_set_error (error, COGL_WINSYS_ERROR, + g_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_ONSCREEN, "X error while creating Window for CoglOnscreen: %s", message); @@ -548,7 +499,6 @@ _cogl_winsys_egl_onscreen_init (CoglOnscreen *onscreen, egl_onscreen->platform = xlib_onscreen; xlib_onscreen->xwin = xwin; - xlib_onscreen->is_foreign_xwin = onscreen->foreign_xid ? TRUE : FALSE; egl_onscreen->egl_surface = eglCreateWindowSurface (egl_renderer->edpy, @@ -573,7 +523,7 @@ _cogl_winsys_egl_onscreen_deinit (CoglOnscreen *onscreen) _cogl_xlib_renderer_trap_errors (renderer, &old_state); - if (!xlib_onscreen->is_foreign_xwin && xlib_onscreen->xwin != None) + if (xlib_onscreen->xwin != None) { XDestroyWindow (xlib_renderer->xdpy, xlib_onscreen->xwin); xlib_onscreen->xwin = None; @@ -592,7 +542,7 @@ _cogl_winsys_egl_onscreen_deinit (CoglOnscreen *onscreen) static void _cogl_winsys_onscreen_set_visibility (CoglOnscreen *onscreen, - CoglBool visibility) + gboolean visibility) { CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context; CoglRenderer *renderer = context->display->renderer; @@ -609,7 +559,7 @@ _cogl_winsys_onscreen_set_visibility (CoglOnscreen *onscreen, static void _cogl_winsys_onscreen_set_resizable (CoglOnscreen *onscreen, - CoglBool resizable) + gboolean resizable) { CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); CoglContext *context = framebuffer->context; @@ -655,9 +605,9 @@ _cogl_winsys_onscreen_x11_get_window_xid (CoglOnscreen *onscreen) return xlib_onscreen->xwin; } -static CoglBool +static gboolean _cogl_winsys_egl_context_created (CoglDisplay *display, - CoglError **error) + GError **error) { CoglRenderer *renderer = display->renderer; CoglDisplayEGL *egl_display = display->winsys; @@ -730,7 +680,7 @@ _cogl_winsys_egl_context_created (CoglDisplay *display, return TRUE; fail: - _cogl_set_error (error, COGL_WINSYS_ERROR, + g_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_CONTEXT, "%s", error_message); return FALSE; @@ -761,7 +711,7 @@ _cogl_winsys_egl_cleanup_context (CoglDisplay *display) #ifdef EGL_KHR_image_pixmap -static CoglBool +static gboolean _cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap) { CoglTexture *tex = COGL_TEXTURE (tex_pixmap); @@ -791,7 +741,7 @@ _cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap) attribs); if (egl_tex_pixmap->image == EGL_NO_IMAGE_KHR) { - free (egl_tex_pixmap); + g_free (egl_tex_pixmap); return FALSE; } @@ -805,6 +755,7 @@ _cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap) tex->height, texture_format, egl_tex_pixmap->image, + COGL_EGL_IMAGE_FLAG_NONE, NULL)); tex_pixmap->winsys = egl_tex_pixmap; @@ -833,13 +784,13 @@ _cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap) _cogl_egl_destroy_image (ctx, egl_tex_pixmap->image); tex_pixmap->winsys = NULL; - free (egl_tex_pixmap); + g_free (egl_tex_pixmap); } -static CoglBool +static gboolean _cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap, CoglTexturePixmapStereoMode stereo_mode, - CoglBool needs_mipmap) + gboolean needs_mipmap) { if (needs_mipmap) return FALSE; @@ -878,10 +829,10 @@ _cogl_winsys_egl_vtable = .onscreen_deinit = _cogl_winsys_egl_onscreen_deinit }; -const CoglWinsysVtable * +COGL_EXPORT const CoglWinsysVtable * _cogl_winsys_egl_xlib_get_vtable (void) { - static CoglBool vtable_inited = FALSE; + static gboolean vtable_inited = FALSE; static CoglWinsysVtable vtable; if (!vtable_inited) diff --git a/cogl/cogl/winsys/cogl-winsys-egl.c b/cogl/cogl/winsys/cogl-winsys-egl.c index a5d8de6dd..5dd106d1b 100644 --- a/cogl/cogl/winsys/cogl-winsys-egl.c +++ b/cogl/cogl/winsys/cogl-winsys-egl.c @@ -30,14 +30,10 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-i18n-private.h" #include "cogl-util.h" -#include "cogl-winsys-egl-private.h" -#include "cogl-winsys-private.h" #include "cogl-feature-private.h" #include "cogl-context-private.h" #include "cogl-framebuffer.h" @@ -45,11 +41,11 @@ #include "cogl-swap-chain-private.h" #include "cogl-renderer-private.h" #include "cogl-onscreen-template-private.h" -#include "cogl-gles2-context-private.h" -#include "cogl-error-private.h" #include "cogl-egl.h" - #include "cogl-private.h" +#include "cogl-trace.h" +#include "winsys/cogl-winsys-egl-private.h" +#include "winsys/cogl-winsys-private.h" #include #include @@ -74,6 +70,12 @@ #define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002 #endif +#ifndef EGL_IMG_context_priority +#define EGL_CONTEXT_PRIORITY_LEVEL_IMG 0x3100 +#define EGL_CONTEXT_PRIORITY_HIGH_IMG 0x3101 +#define EGL_CONTEXT_PRIORITY_MEDIUM_IMG 0x3102 +#define EGL_CONTEXT_PRIORITY_LOW_IMG 0x3103 +#endif #define MAX_EGL_CONFIG_ATTRIBS 30 @@ -88,14 +90,14 @@ #define COGL_WINSYS_FEATURE_END() \ { NULL, 0 }, \ }; -#include "cogl-winsys-egl-feature-functions.h" +#include "winsys/cogl-winsys-egl-feature-functions.h" /* Define an array of features */ #undef COGL_WINSYS_FEATURE_BEGIN #define COGL_WINSYS_FEATURE_BEGIN(name, namespaces, extension_names, \ egl_private_flags) \ { 255, 255, 0, namespaces, extension_names, \ - 0, egl_private_flags, \ + egl_private_flags, \ 0, \ cogl_egl_feature_ ## name ## _funcs }, #undef COGL_WINSYS_FEATURE_FUNCTION @@ -105,46 +107,13 @@ static const CoglFeatureData winsys_feature_data[] = { -#include "cogl-winsys-egl-feature-functions.h" +#include "winsys/cogl-winsys-egl-feature-functions.h" }; -static const char * -get_error_string (void) -{ - switch (eglGetError()){ - case EGL_BAD_DISPLAY: - return "Invalid display"; - case EGL_NOT_INITIALIZED: - return "Display not initialized"; - case EGL_BAD_ALLOC: - return "Not enough resources to allocate context"; - case EGL_BAD_ATTRIBUTE: - return "Invalid attribute"; - case EGL_BAD_CONFIG: - return "Invalid config"; - case EGL_BAD_CONTEXT: - return "Invalid context"; - case EGL_BAD_CURRENT_SURFACE: - return "Invalid current surface"; - case EGL_BAD_MATCH: - return "Bad match"; - case EGL_BAD_NATIVE_PIXMAP: - return "Invalid native pixmap"; - case EGL_BAD_NATIVE_WINDOW: - return "Invalid native window"; - case EGL_BAD_PARAMETER: - return "Invalid parameter"; - case EGL_BAD_SURFACE: - return "Invalid surface"; - default: - g_assert_not_reached (); - } -} - -static CoglFuncPtr +static GCallback _cogl_winsys_renderer_get_proc_address (CoglRenderer *renderer, const char *name, - CoglBool in_core) + gboolean in_core) { void *ptr = NULL; @@ -195,9 +164,9 @@ check_egl_extensions (CoglRenderer *renderer) g_strfreev (split_extensions); } -CoglBool +gboolean _cogl_winsys_egl_renderer_connect_common (CoglRenderer *renderer, - CoglError **error) + GError **error) { CoglRendererEGL *egl_renderer = renderer->winsys; @@ -205,7 +174,7 @@ _cogl_winsys_egl_renderer_connect_common (CoglRenderer *renderer, &egl_renderer->egl_version_major, &egl_renderer->egl_version_minor)) { - _cogl_set_error (error, COGL_WINSYS_ERROR, + g_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_INIT, "Couldn't initialize EGL"); return FALSE; @@ -216,12 +185,13 @@ _cogl_winsys_egl_renderer_connect_common (CoglRenderer *renderer, return TRUE; } -static CoglBool +static gboolean _cogl_winsys_renderer_connect (CoglRenderer *renderer, - CoglError **error) + GError **error) { /* This function must be overridden by a platform winsys */ g_assert_not_reached (); + return FALSE; } static void @@ -265,8 +235,6 @@ egl_attributes_from_framebuffer_config (CoglDisplay *display, attributes[i++] = ((renderer->driver == COGL_DRIVER_GL || renderer->driver == COGL_DRIVER_GL3) ? EGL_OPENGL_BIT : - renderer->driver == COGL_DRIVER_GLES1 ? - EGL_OPENGL_ES_BIT : EGL_OPENGL_ES2_BIT); if (config->samples_per_pixel) @@ -341,25 +309,28 @@ cleanup_context (CoglDisplay *display) egl_renderer->platform_vtable->cleanup_context (display); } -static CoglBool +static gboolean try_create_context (CoglDisplay *display, - CoglError **error) + GError **error) { CoglRenderer *renderer = display->renderer; CoglDisplayEGL *egl_display = display->winsys; CoglRendererEGL *egl_renderer = renderer->winsys; EGLDisplay edpy; EGLConfig config; - EGLint attribs[9]; + EGLint attribs[11]; EGLint cfg_attribs[MAX_EGL_CONFIG_ATTRIBS]; GError *config_error = NULL; const char *error_message; + int i = 0; - _COGL_RETURN_VAL_IF_FAIL (egl_display->egl_context == NULL, TRUE); + g_return_val_if_fail (egl_display->egl_context == NULL, TRUE); if (renderer->driver == COGL_DRIVER_GL || renderer->driver == COGL_DRIVER_GL3) eglBindAPI (EGL_OPENGL_API); + else if (renderer->driver == COGL_DRIVER_GLES2) + eglBindAPI (EGL_OPENGL_ES_API); egl_attributes_from_framebuffer_config (display, &display->onscreen_template->config, @@ -372,9 +343,9 @@ try_create_context (CoglDisplay *display, &config, &config_error)) { - _cogl_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Couldn't choose config: %s", config_error->message); + g_set_error (error, COGL_WINSYS_ERROR, + COGL_WINSYS_ERROR_CREATE_CONTEXT, + "Couldn't choose config: %s", config_error->message); g_error_free (config_error); goto err; } @@ -391,24 +362,29 @@ try_create_context (CoglDisplay *display, } /* Try to get a core profile 3.1 context with no deprecated features */ - attribs[0] = EGL_CONTEXT_MAJOR_VERSION_KHR; - attribs[1] = 3; - attribs[2] = EGL_CONTEXT_MINOR_VERSION_KHR; - attribs[3] = 1; - attribs[4] = EGL_CONTEXT_FLAGS_KHR; - attribs[5] = EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR; - attribs[6] = EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR; - attribs[7] = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR; - attribs[8] = EGL_NONE; + attribs[i++] = EGL_CONTEXT_MAJOR_VERSION_KHR; + attribs[i++] = 3; + attribs[i++] = EGL_CONTEXT_MINOR_VERSION_KHR; + attribs[i++] = 1; + attribs[i++] = EGL_CONTEXT_FLAGS_KHR; + attribs[i++] = EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR; + attribs[i++] = EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR; + attribs[i++] = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR; } else if (display->renderer->driver == COGL_DRIVER_GLES2) { - attribs[0] = EGL_CONTEXT_CLIENT_VERSION; - attribs[1] = 2; - attribs[2] = EGL_NONE; + attribs[i++] = EGL_CONTEXT_CLIENT_VERSION; + attribs[i++] = 2; + } + + if (egl_renderer->private_features & + COGL_EGL_WINSYS_FEATURE_CONTEXT_PRIORITY) + { + attribs[i++] = EGL_CONTEXT_PRIORITY_LEVEL_IMG; + attribs[i++] = EGL_CONTEXT_PRIORITY_HIGH_IMG; } - else - attribs[0] = EGL_NONE; + + attribs[i++] = EGL_NONE; egl_display->egl_context = eglCreateContext (edpy, config, @@ -421,6 +397,20 @@ try_create_context (CoglDisplay *display, goto fail; } + if (egl_renderer->private_features & + COGL_EGL_WINSYS_FEATURE_CONTEXT_PRIORITY) + { + EGLint value = EGL_CONTEXT_PRIORITY_MEDIUM_IMG; + + eglQueryContext (egl_renderer->edpy, + egl_display->egl_context, + EGL_CONTEXT_PRIORITY_LEVEL_IMG, + &value); + + if (value != EGL_CONTEXT_PRIORITY_HIGH_IMG) + g_message ("Failed to obtain high priority context"); + } + if (egl_renderer->platform_vtable->context_created && !egl_renderer->platform_vtable->context_created (display, error)) return FALSE; @@ -428,7 +418,7 @@ try_create_context (CoglDisplay *display, return TRUE; fail: - _cogl_set_error (error, COGL_WINSYS_ERROR, + g_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_CONTEXT, "%s", error_message); @@ -444,7 +434,7 @@ _cogl_winsys_display_destroy (CoglDisplay *display) CoglRendererEGL *egl_renderer = display->renderer->winsys; CoglDisplayEGL *egl_display = display->winsys; - _COGL_RETURN_IF_FAIL (egl_display != NULL); + g_return_if_fail (egl_display != NULL); cleanup_context (display); @@ -455,15 +445,15 @@ _cogl_winsys_display_destroy (CoglDisplay *display) display->winsys = NULL; } -static CoglBool +static gboolean _cogl_winsys_display_setup (CoglDisplay *display, - CoglError **error) + GError **error) { CoglDisplayEGL *egl_display; CoglRenderer *renderer = display->renderer; CoglRendererEGL *egl_renderer = renderer->winsys; - _COGL_RETURN_VAL_IF_FAIL (display->winsys == NULL, FALSE); + g_return_val_if_fail (display->winsys == NULL, FALSE); egl_display = g_slice_new0 (CoglDisplayEGL); display->winsys = egl_display; @@ -496,8 +486,8 @@ _cogl_winsys_display_setup (CoglDisplay *display, return FALSE; } -static CoglBool -_cogl_winsys_context_init (CoglContext *context, CoglError **error) +static gboolean +_cogl_winsys_context_init (CoglContext *context, GError **error) { CoglRenderer *renderer = context->display->renderer; CoglDisplayEGL *egl_display = context->display->winsys; @@ -505,7 +495,7 @@ _cogl_winsys_context_init (CoglContext *context, CoglError **error) context->winsys = g_new0 (CoglContextEGL, 1); - _COGL_RETURN_VAL_IF_FAIL (egl_display->egl_context, FALSE); + g_return_val_if_fail (egl_display->egl_context, FALSE); memset (context->winsys_features, 0, sizeof (context->winsys_features)); @@ -534,14 +524,6 @@ _cogl_winsys_context_init (CoglContext *context, CoglError **error) COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_BUFFER_AGE, TRUE); } - /* NB: We currently only support creating standalone GLES2 contexts - * for offscreen rendering and so we need a dummy (non-visible) - * surface to be able to bind those contexts */ - if (egl_display->dummy_surface != EGL_NO_SURFACE && - context->driver == COGL_DRIVER_GLES2) - COGL_FLAGS_SET (context->features, - COGL_FEATURE_ID_GLES2_CONTEXT, TRUE); - if (egl_renderer->platform_vtable->context_init && !egl_renderer->platform_vtable->context_init (context, error)) return FALSE; @@ -558,60 +540,12 @@ _cogl_winsys_context_deinit (CoglContext *context) if (egl_renderer->platform_vtable->context_deinit) egl_renderer->platform_vtable->context_deinit (context); - free (context->winsys); + g_free (context->winsys); } -typedef struct _CoglGLES2ContextEGL -{ - EGLContext egl_context; - EGLSurface dummy_surface; -} CoglGLES2ContextEGL; - -static void * -_cogl_winsys_context_create_gles2_context (CoglContext *ctx, CoglError **error) -{ - CoglRendererEGL *egl_renderer = ctx->display->renderer->winsys; - CoglDisplayEGL *egl_display = ctx->display->winsys; - EGLint attribs[3]; - EGLContext egl_context; - - attribs[0] = EGL_CONTEXT_CLIENT_VERSION; - attribs[1] = 2; - attribs[2] = EGL_NONE; - - egl_context = eglCreateContext (egl_renderer->edpy, - egl_display->egl_config, - egl_display->egl_context, - attribs); - if (egl_context == EGL_NO_CONTEXT) - { - _cogl_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_GLES2_CONTEXT, - "%s", get_error_string ()); - return NULL; - } - - return (void *)egl_context; -} - -static void -_cogl_winsys_destroy_gles2_context (CoglGLES2Context *gles2_ctx) -{ - CoglContext *context = gles2_ctx->context; - CoglDisplay *display = context->display; - CoglDisplayEGL *egl_display = display->winsys; - CoglRenderer *renderer = display->renderer; - CoglRendererEGL *egl_renderer = renderer->winsys; - EGLContext egl_context = gles2_ctx->winsys; - - _COGL_RETURN_IF_FAIL (egl_display->current_context != egl_context); - - eglDestroyContext (egl_renderer->edpy, egl_context); -} - -static CoglBool +static gboolean _cogl_winsys_onscreen_init (CoglOnscreen *onscreen, - CoglError **error) + GError **error) { CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); CoglContext *context = framebuffer->context; @@ -624,7 +558,7 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen, EGLint config_count = 0; EGLBoolean status; - _COGL_RETURN_VAL_IF_FAIL (egl_display->egl_context, FALSE); + g_return_val_if_fail (egl_display->egl_context, FALSE); egl_attributes_from_framebuffer_config (display, &framebuffer->config, @@ -636,7 +570,7 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen, &config_count); if (status != EGL_TRUE || config_count == 0) { - _cogl_set_error (error, COGL_WINSYS_ERROR, + g_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_ONSCREEN, "Failed to find a suitable EGL configuration"); return FALSE; @@ -712,7 +646,7 @@ _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen) onscreen->winsys = NULL; } -static CoglBool +static gboolean bind_onscreen_with_context (CoglOnscreen *onscreen, EGLContext egl_context) { @@ -720,7 +654,7 @@ bind_onscreen_with_context (CoglOnscreen *onscreen, CoglContext *context = fb->context; CoglOnscreenEGL *egl_onscreen = onscreen->winsys; - CoglBool status = _cogl_winsys_egl_make_current (context->display, + gboolean status = _cogl_winsys_egl_make_current (context->display, egl_onscreen->egl_surface, egl_onscreen->egl_surface, egl_context); @@ -729,16 +663,13 @@ bind_onscreen_with_context (CoglOnscreen *onscreen, CoglRenderer *renderer = context->display->renderer; CoglRendererEGL *egl_renderer = renderer->winsys; - if (fb->config.swap_throttled) - eglSwapInterval (egl_renderer->edpy, 1); - else - eglSwapInterval (egl_renderer->edpy, 0); + eglSwapInterval (egl_renderer->edpy, 1); } return status; } -static CoglBool +static gboolean bind_onscreen (CoglOnscreen *onscreen) { CoglFramebuffer *fb = COGL_FRAMEBUFFER (onscreen); @@ -765,13 +696,29 @@ _cogl_winsys_onscreen_get_buffer_age (CoglOnscreen *onscreen) CoglRenderer *renderer = context->display->renderer; CoglRendererEGL *egl_renderer = renderer->winsys; CoglOnscreenEGL *egl_onscreen = onscreen->winsys; + CoglDisplayEGL *egl_display = context->display->winsys; EGLSurface surface = egl_onscreen->egl_surface; - int age; + static gboolean warned = FALSE; + int age = 0; if (!(egl_renderer->private_features & COGL_EGL_WINSYS_FEATURE_BUFFER_AGE)) return 0; - eglQuerySurface (egl_renderer->edpy, surface, EGL_BUFFER_AGE_EXT, &age); + if (!_cogl_winsys_egl_make_current (context->display, + surface, surface, + egl_display->egl_context)) + return 0; + + if (!eglQuerySurface (egl_renderer->edpy, surface, EGL_BUFFER_AGE_EXT, &age)) + { + if (!warned) + g_critical ("Failed to query buffer age, got error %x", eglGetError ()); + warned = TRUE; + } + else + { + warned = FALSE; + } return age; } @@ -825,6 +772,9 @@ _cogl_winsys_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen, CoglRendererEGL *egl_renderer = renderer->winsys; CoglOnscreenEGL *egl_onscreen = onscreen->winsys; + COGL_TRACE_BEGIN_SCOPED (CoglOnscreenEGLSwapBuffersWithDamage, + "Onscreen (eglSwapBuffers)"); + /* The specification for EGL (at least in 1.4) says that the surface needs to be bound to the current context for the swap to work although it may change in future. Mesa explicitly checks for this @@ -859,73 +809,6 @@ _cogl_winsys_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen, eglSwapBuffers (egl_renderer->edpy, egl_onscreen->egl_surface); } -static void -_cogl_winsys_onscreen_update_swap_throttled (CoglOnscreen *onscreen) -{ - CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context; - CoglDisplayEGL *egl_display = context->display->winsys; - CoglOnscreenEGL *egl_onscreen = onscreen->winsys; - - if (egl_display->current_draw_surface != egl_onscreen->egl_surface) - return; - - egl_display->current_draw_surface = EGL_NO_SURFACE; - - _cogl_winsys_onscreen_bind (onscreen); -} - -static void -_cogl_winsys_save_context (CoglContext *ctx) -{ - CoglContextEGL *egl_context = ctx->winsys; - CoglDisplayEGL *egl_display = ctx->display->winsys; - - egl_context->saved_draw_surface = egl_display->current_draw_surface; - egl_context->saved_read_surface = egl_display->current_read_surface; -} - -static CoglBool -_cogl_winsys_set_gles2_context (CoglGLES2Context *gles2_ctx, CoglError **error) -{ - CoglContext *ctx = gles2_ctx->context; - CoglDisplayEGL *egl_display = ctx->display->winsys; - CoglBool status; - - if (gles2_ctx->write_buffer && - cogl_is_onscreen (gles2_ctx->write_buffer)) - status = - bind_onscreen_with_context (COGL_ONSCREEN (gles2_ctx->write_buffer), - gles2_ctx->winsys); - else - status = _cogl_winsys_egl_make_current (ctx->display, - egl_display->dummy_surface, - egl_display->dummy_surface, - gles2_ctx->winsys); - - if (!status) - { - _cogl_set_error (error, - COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_MAKE_CURRENT, - "Failed to make gles2 context current"); - return FALSE; - } - - return TRUE; -} - -static void -_cogl_winsys_restore_context (CoglContext *ctx) -{ - CoglContextEGL *egl_context = ctx->winsys; - CoglDisplayEGL *egl_display = ctx->display->winsys; - - _cogl_winsys_egl_make_current (ctx->display, - egl_context->saved_draw_surface, - egl_context->saved_read_surface, - egl_display->egl_context); -} - #if defined(EGL_KHR_fence_sync) || defined(EGL_KHR_reusable_sync) static void * _cogl_winsys_fence_add (CoglContext *context) @@ -943,7 +826,7 @@ _cogl_winsys_fence_add (CoglContext *context) return ret; } -static CoglBool +static gboolean _cogl_winsys_fence_is_complete (CoglContext *context, void *fence) { CoglRendererEGL *renderer = context->display->renderer->winsys; @@ -967,8 +850,7 @@ _cogl_winsys_fence_destroy (CoglContext *context, void *fence) static CoglWinsysVtable _cogl_winsys_vtable = { - .constraints = COGL_RENDERER_CONSTRAINT_USES_EGL | - COGL_RENDERER_CONSTRAINT_SUPPORTS_COGL_GLES2, + .constraints = COGL_RENDERER_CONSTRAINT_USES_EGL, /* This winsys is only used as a base for the EGL-platform winsys's so it does not have an ID or a name */ @@ -980,9 +862,6 @@ static CoglWinsysVtable _cogl_winsys_vtable = .display_destroy = _cogl_winsys_display_destroy, .context_init = _cogl_winsys_context_init, .context_deinit = _cogl_winsys_context_deinit, - .context_create_gles2_context = - _cogl_winsys_context_create_gles2_context, - .destroy_gles2_context = _cogl_winsys_destroy_gles2_context, .onscreen_init = _cogl_winsys_onscreen_init, .onscreen_deinit = _cogl_winsys_onscreen_deinit, .onscreen_bind = _cogl_winsys_onscreen_bind, @@ -990,13 +869,6 @@ static CoglWinsysVtable _cogl_winsys_vtable = _cogl_winsys_onscreen_swap_buffers_with_damage, .onscreen_swap_region = _cogl_winsys_onscreen_swap_region, .onscreen_get_buffer_age = _cogl_winsys_onscreen_get_buffer_age, - .onscreen_update_swap_throttled = - _cogl_winsys_onscreen_update_swap_throttled, - - /* CoglGLES2Context related methods */ - .save_context = _cogl_winsys_save_context, - .set_gles2_context = _cogl_winsys_set_gles2_context, - .restore_context = _cogl_winsys_restore_context, #if defined(EGL_KHR_fence_sync) || defined(EGL_KHR_reusable_sync) .fence_add = _cogl_winsys_fence_add, @@ -1031,7 +903,7 @@ _cogl_egl_create_image (CoglContext *ctx, CoglRendererEGL *egl_renderer = ctx->display->renderer->winsys; EGLContext egl_ctx; - _COGL_RETURN_VAL_IF_FAIL (egl_renderer->pf_eglCreateImage, EGL_NO_IMAGE_KHR); + g_return_val_if_fail (egl_renderer->pf_eglCreateImage, EGL_NO_IMAGE_KHR); /* The EGL_KHR_image_pixmap spec explicitly states that EGL_NO_CONTEXT must * always be used in conjunction with the EGL_NATIVE_PIXMAP_KHR target */ @@ -1062,14 +934,14 @@ _cogl_egl_destroy_image (CoglContext *ctx, { CoglRendererEGL *egl_renderer = ctx->display->renderer->winsys; - _COGL_RETURN_IF_FAIL (egl_renderer->pf_eglDestroyImage); + g_return_if_fail (egl_renderer->pf_eglDestroyImage); egl_renderer->pf_eglDestroyImage (egl_renderer->edpy, image); } #endif #ifdef EGL_WL_bind_wayland_display -CoglBool +gboolean _cogl_egl_query_wayland_buffer (CoglContext *ctx, struct wl_resource *buffer, int attribute, @@ -1077,7 +949,7 @@ _cogl_egl_query_wayland_buffer (CoglContext *ctx, { CoglRendererEGL *egl_renderer = ctx->display->renderer->winsys; - _COGL_RETURN_VAL_IF_FAIL (egl_renderer->pf_eglQueryWaylandBuffer, FALSE); + g_return_val_if_fail (egl_renderer->pf_eglQueryWaylandBuffer, FALSE); return egl_renderer->pf_eglQueryWaylandBuffer (egl_renderer->edpy, buffer, @@ -1093,11 +965,3 @@ cogl_egl_context_get_egl_display (CoglContext *context) return egl_renderer->edpy; } - -EGLContext -cogl_egl_context_get_egl_context (CoglContext *context) -{ - CoglDisplayEGL *egl_display = context->display->winsys; - - return egl_display->egl_context; -} diff --git a/cogl/cogl/winsys/cogl-winsys-glx-private.h b/cogl/cogl/winsys/cogl-winsys-glx-private.h index 9fb386ff7..15e7f988d 100644 --- a/cogl/cogl/winsys/cogl-winsys-glx-private.h +++ b/cogl/cogl/winsys/cogl-winsys-glx-private.h @@ -31,7 +31,7 @@ #ifndef __COGL_WINSYS_GLX_PRIVATE_H #define __COGL_WINSYS_GLX_PRIVATE_H -const CoglWinsysVtable * +COGL_EXPORT const CoglWinsysVtable * _cogl_winsys_glx_get_vtable (void); #endif /* __COGL_WINSYS_GLX_PRIVATE_H */ diff --git a/cogl/cogl/winsys/cogl-winsys-glx.c b/cogl/cogl/winsys/cogl-winsys-glx.c index 1522e52a9..c2deaeb8b 100644 --- a/cogl/cogl/winsys/cogl-winsys-glx.c +++ b/cogl/cogl/winsys/cogl-winsys-glx.c @@ -30,13 +30,10 @@ * Robert Bragg */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-i18n-private.h" #include "cogl-util.h" -#include "cogl-winsys-private.h" #include "cogl-feature-private.h" #include "cogl-context-private.h" #include "cogl-framebuffer.h" @@ -47,19 +44,18 @@ #include "cogl-glx-display-private.h" #include "cogl-private.h" #include "cogl-texture-2d-private.h" -#include "cogl-texture-rectangle-private.h" -#include "cogl-pipeline-opengl-private.h" #include "cogl-frame-info-private.h" #include "cogl-framebuffer-private.h" #include "cogl-onscreen-private.h" #include "cogl-swap-chain-private.h" #include "cogl-xlib-renderer.h" #include "cogl-util.h" -#include "cogl-winsys-glx-private.h" -#include "cogl-error-private.h" #include "cogl-poll-private.h" #include "cogl-version.h" #include "cogl-glx.h" +#include "driver/gl/cogl-pipeline-opengl-private.h" +#include "winsys/cogl-winsys-private.h" +#include "winsys/cogl-winsys-glx-private.h" #include #include @@ -92,7 +88,6 @@ typedef struct _CoglOnscreenXlib { Window xwin; int x, y; - CoglBool is_foreign_xwin; CoglOutput *output; } CoglOnscreenXlib; @@ -104,28 +99,20 @@ typedef struct _CoglOnscreenGLX uint32_t pending_sync_notify; uint32_t pending_complete_notify; uint32_t pending_resize_notify; - - GThread *swap_wait_thread; - GQueue *swap_wait_queue; - GCond swap_wait_cond; - GMutex swap_wait_mutex; - int swap_wait_pipe[2]; - GLXContext swap_wait_context; - CoglBool closing_down; } CoglOnscreenGLX; typedef struct _CoglPixmapTextureEyeGLX { CoglTexture *glx_tex; - CoglBool bind_tex_image_queued; - CoglBool pixmap_bound; + gboolean bind_tex_image_queued; + gboolean pixmap_bound; } CoglPixmapTextureEyeGLX; typedef struct _CoglTexturePixmapGLX { GLXPixmap glx_pixmap; - CoglBool has_mipmap_space; - CoglBool can_mipmap; + gboolean has_mipmap_space; + gboolean can_mipmap; CoglPixmapTextureEyeGLX left; CoglPixmapTextureEyeGLX right; @@ -144,7 +131,7 @@ typedef struct _CoglTexturePixmapGLX #define COGL_WINSYS_FEATURE_END() \ { NULL, 0 }, \ }; -#include "cogl-winsys-glx-feature-functions.h" +#include "winsys/cogl-winsys-glx-feature-functions.h" /* Define an array of features */ #undef COGL_WINSYS_FEATURE_BEGIN @@ -154,7 +141,6 @@ typedef struct _CoglTexturePixmapGLX winsys_feature) \ { major_version, minor_version, \ 0, namespaces, extension_names, \ - feature_flags, \ 0, \ winsys_feature, \ cogl_glx_feature_ ## name ## _funcs }, @@ -165,13 +151,13 @@ typedef struct _CoglTexturePixmapGLX static const CoglFeatureData winsys_feature_data[] = { -#include "cogl-winsys-glx-feature-functions.h" +#include "winsys/cogl-winsys-glx-feature-functions.h" }; -static CoglFuncPtr +static GCallback _cogl_winsys_renderer_get_proc_address (CoglRenderer *renderer, const char *name, - CoglBool in_core) + gboolean in_core) { CoglGLXRenderer *glx_renderer = renderer->winsys; @@ -537,7 +523,6 @@ notify_resize (CoglContext *context, glx_onscreen->pending_resize_notify++; - if (!xlib_onscreen->is_foreign_xwin) { int x, y; @@ -629,7 +614,7 @@ _cogl_winsys_renderer_disconnect (CoglRenderer *renderer) g_slice_free (CoglGLXRenderer, renderer->winsys); } -static CoglBool +static gboolean update_all_outputs (CoglRenderer *renderer) { GList *l; @@ -661,9 +646,9 @@ _cogl_winsys_renderer_outputs_changed (CoglRenderer *renderer) update_all_outputs (renderer); } -static CoglBool +static gboolean resolve_core_glx_functions (CoglRenderer *renderer, - CoglError **error) + GError **error) { CoglGLXRenderer *glx_renderer; @@ -682,9 +667,9 @@ resolve_core_glx_functions (CoglRenderer *renderer, !g_module_symbol (glx_renderer->libgl_module, "glXQueryDrawable", (void **) &glx_renderer->glXQueryDrawable)) { - _cogl_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_INIT, - "Failed to resolve required GLX symbol"); + g_set_error_literal (error, COGL_WINSYS_ERROR, + COGL_WINSYS_ERROR_INIT, + "Failed to resolve required GLX symbol"); return FALSE; } @@ -720,8 +705,6 @@ update_base_winsys_features (CoglRenderer *renderer) split_extensions, glx_renderer)) { - glx_renderer->legacy_feature_flags |= - winsys_feature_data[i].feature_flags; if (winsys_feature_data[i].winsys_feature) COGL_FLAGS_SET (glx_renderer->base_winsys_features, winsys_feature_data[i].winsys_feature, @@ -754,9 +737,9 @@ update_base_winsys_features (CoglRenderer *renderer) TRUE); } -static CoglBool +static gboolean _cogl_winsys_renderer_connect (CoglRenderer *renderer, - CoglError **error) + GError **error) { CoglGLXRenderer *glx_renderer; CoglXlibRenderer *xlib_renderer; @@ -772,9 +755,9 @@ _cogl_winsys_renderer_connect (CoglRenderer *renderer, if (renderer->driver != COGL_DRIVER_GL && renderer->driver != COGL_DRIVER_GL3) { - _cogl_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_INIT, - "GLX Backend can only be used in conjunction with OpenGL"); + g_set_error_literal (error, COGL_WINSYS_ERROR, + COGL_WINSYS_ERROR_INIT, + "GLX Backend can only be used in conjunction with OpenGL"); goto error; } @@ -783,9 +766,9 @@ _cogl_winsys_renderer_connect (CoglRenderer *renderer, if (glx_renderer->libgl_module == NULL) { - _cogl_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_INIT, - "Failed to dynamically open the OpenGL library"); + g_set_error_literal (error, COGL_WINSYS_ERROR, + COGL_WINSYS_ERROR_INIT, + "Failed to dynamically open the OpenGL library"); goto error; } @@ -796,9 +779,9 @@ _cogl_winsys_renderer_connect (CoglRenderer *renderer, &glx_renderer->glx_error_base, &glx_renderer->glx_event_base)) { - _cogl_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_INIT, - "XServer appears to lack required GLX support"); + g_set_error_literal (error, COGL_WINSYS_ERROR, + COGL_WINSYS_ERROR_INIT, + "XServer appears to lack required GLX support"); goto error; } @@ -810,9 +793,9 @@ _cogl_winsys_renderer_connect (CoglRenderer *renderer, &glx_renderer->glx_minor) || !(glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 2)) { - _cogl_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_INIT, - "XServer appears to lack required GLX 1.2 support"); + g_set_error_literal (error, COGL_WINSYS_ERROR, + COGL_WINSYS_ERROR_INIT, + "XServer appears to lack required GLX 1.2 support"); goto error; } @@ -827,13 +810,13 @@ _cogl_winsys_renderer_connect (CoglRenderer *renderer, return FALSE; } -static CoglBool -update_winsys_features (CoglContext *context, CoglError **error) +static gboolean +update_winsys_features (CoglContext *context, GError **error) { CoglGLXDisplay *glx_display = context->display->winsys; CoglGLXRenderer *glx_renderer = context->display->renderer->winsys; - _COGL_RETURN_VAL_IF_FAIL (glx_display->glx_context, FALSE); + g_return_val_if_fail (glx_display->glx_context, FALSE); if (!_cogl_context_update_features (context, error)) return FALSE; @@ -842,40 +825,8 @@ update_winsys_features (CoglContext *context, CoglError **error) glx_renderer->base_winsys_features, sizeof (context->winsys_features)); - context->feature_flags |= glx_renderer->legacy_feature_flags; - - context->feature_flags |= COGL_FEATURE_ONSCREEN_MULTIPLE; - COGL_FLAGS_SET (context->features, - COGL_FEATURE_ID_ONSCREEN_MULTIPLE, TRUE); - if (glx_renderer->glXCopySubBuffer || context->glBlitFramebuffer) - { - CoglGpuInfo *info = &context->gpu; - CoglGpuInfoArchitecture arch = info->architecture; - - COGL_FLAGS_SET (context->winsys_features, COGL_WINSYS_FEATURE_SWAP_REGION, TRUE); - - /* - * "The "drisw" binding in Mesa for loading sofware renderers is - * broken, and neither glBlitFramebuffer nor glXCopySubBuffer - * work correctly." - * - ajax - * - https://bugzilla.gnome.org/show_bug.cgi?id=674208 - * - * This is broken in software Mesa at least as of 7.10 and got - * fixed in Mesa 10.1 - */ - - if (info->driver_package == COGL_GPU_INFO_DRIVER_PACKAGE_MESA && - info->driver_package_version < COGL_VERSION_ENCODE (10, 1, 0) && - (arch == COGL_GPU_INFO_ARCHITECTURE_LLVMPIPE || - arch == COGL_GPU_INFO_ARCHITECTURE_SOFTPIPE || - arch == COGL_GPU_INFO_ARCHITECTURE_SWRAST)) - { - COGL_FLAGS_SET (context->winsys_features, - COGL_WINSYS_FEATURE_SWAP_REGION, FALSE); - } - } + COGL_FLAGS_SET (context->winsys_features, COGL_WINSYS_FEATURE_SWAP_REGION, TRUE); /* Note: glXCopySubBuffer and glBlitFramebuffer won't be throttled * by the SwapInterval so we have to throttle swap_region requests @@ -897,29 +848,6 @@ update_winsys_features (CoglContext *context, CoglError **error) COGL_FEATURE_ID_PRESENTATION_TIME, TRUE); } - else - { - CoglGpuInfo *info = &context->gpu; - if (glx_display->have_vblank_counter && - context->display->renderer->xlib_enable_threaded_swap_wait && - info->vendor == COGL_GPU_INFO_VENDOR_NVIDIA) - { - COGL_FLAGS_SET (context->winsys_features, - COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT, TRUE); - COGL_FLAGS_SET (context->winsys_features, - COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT, TRUE); - /* TODO: remove this deprecated feature */ - COGL_FLAGS_SET (context->features, - COGL_FEATURE_ID_SWAP_BUFFERS_EVENT, - TRUE); - COGL_FLAGS_SET (context->features, - COGL_FEATURE_ID_PRESENTATION_TIME, - TRUE); - COGL_FLAGS_SET (context->private_features, - COGL_PRIVATE_FEATURE_THREADED_SWAP_WAIT, - TRUE); - } - } /* We'll manually handle queueing dirty events in response to * Expose events from X */ @@ -985,11 +913,11 @@ glx_attributes_from_framebuffer_config (CoglDisplay *display, /* It seems the GLX spec never defined an invalid GLXFBConfig that * we could overload as an indication of error, so we have to return * an explicit boolean status. */ -static CoglBool +static gboolean find_fbconfig (CoglDisplay *display, CoglFramebufferConfig *config, GLXFBConfig *config_ret, - CoglError **error) + GError **error) { CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (display->renderer); @@ -997,7 +925,7 @@ find_fbconfig (CoglDisplay *display, GLXFBConfig *configs = NULL; int n_configs; static int attributes[MAX_GLX_CONFIG_ATTRIBS]; - CoglBool ret = TRUE; + gboolean ret = TRUE; int xscreen_num = DefaultScreen (xlib_renderer->xdpy); glx_attributes_from_framebuffer_config (display, config, attributes); @@ -1009,9 +937,9 @@ find_fbconfig (CoglDisplay *display, if (!configs || n_configs == 0) { - _cogl_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Failed to find any compatible fbconfigs"); + g_set_error_literal (error, COGL_WINSYS_ERROR, + COGL_WINSYS_ERROR_CREATE_CONTEXT, + "Failed to find any compatible fbconfigs"); ret = FALSE; goto done; } @@ -1039,9 +967,9 @@ find_fbconfig (CoglDisplay *display, } } - _cogl_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Unable to find fbconfig with rgba visual"); + g_set_error_literal (error, COGL_WINSYS_ERROR, + COGL_WINSYS_ERROR_CREATE_CONTEXT, + "Unable to find fbconfig with rgba visual"); ret = FALSE; goto done; } @@ -1124,34 +1052,34 @@ create_gl3_context (CoglDisplay *display, attrib_list); } -static CoglBool -create_context (CoglDisplay *display, CoglError **error) +static gboolean +create_context (CoglDisplay *display, GError **error) { CoglGLXDisplay *glx_display = display->winsys; CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (display->renderer); CoglGLXRenderer *glx_renderer = display->renderer->winsys; - CoglBool support_transparent_windows = + gboolean support_transparent_windows = display->onscreen_template->config.swap_chain->has_alpha; GLXFBConfig config; - CoglError *fbconfig_error = NULL; + GError *fbconfig_error = NULL; XSetWindowAttributes attrs; XVisualInfo *xvisinfo; GLXDrawable dummy_drawable; CoglXlibTrapState old_state; - _COGL_RETURN_VAL_IF_FAIL (glx_display->glx_context == NULL, TRUE); + g_return_val_if_fail (glx_display->glx_context == NULL, TRUE); glx_display->found_fbconfig = find_fbconfig (display, &display->onscreen_template->config, &config, &fbconfig_error); if (!glx_display->found_fbconfig) { - _cogl_set_error (error, COGL_WINSYS_ERROR, + g_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_CONTEXT, "Unable to find suitable fbconfig for the GLX context: %s", fbconfig_error->message); - cogl_error_free (fbconfig_error); + g_error_free (fbconfig_error); return FALSE; } @@ -1176,9 +1104,9 @@ create_context (CoglDisplay *display, CoglError **error) if (_cogl_xlib_renderer_untrap_errors (display->renderer, &old_state) || glx_display->glx_context == NULL) { - _cogl_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Unable to create suitable GL context"); + g_set_error_literal (error, COGL_WINSYS_ERROR, + COGL_WINSYS_ERROR_CREATE_CONTEXT, + "Unable to create suitable GL context"); return FALSE; } @@ -1199,9 +1127,9 @@ create_context (CoglDisplay *display, CoglError **error) config); if (xvisinfo == NULL) { - _cogl_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Unable to retrieve the X11 visual"); + g_set_error_literal (error, COGL_WINSYS_ERROR, + COGL_WINSYS_ERROR_CREATE_CONTEXT, + "Unable to retrieve the X11 visual"); return FALSE; } @@ -1254,9 +1182,9 @@ create_context (CoglDisplay *display, CoglError **error) if (_cogl_xlib_renderer_untrap_errors (display->renderer, &old_state)) { - _cogl_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Unable to select the newly created GLX context"); + g_set_error_literal (error, COGL_WINSYS_ERROR, + COGL_WINSYS_ERROR_CREATE_CONTEXT, + "Unable to select the newly created GLX context"); return FALSE; } @@ -1271,7 +1199,7 @@ _cogl_winsys_display_destroy (CoglDisplay *display) _cogl_xlib_renderer_get_data (display->renderer); CoglGLXRenderer *glx_renderer = display->renderer->winsys; - _COGL_RETURN_IF_FAIL (glx_display != NULL); + g_return_if_fail (glx_display != NULL); if (glx_display->glx_context) { @@ -1299,14 +1227,14 @@ _cogl_winsys_display_destroy (CoglDisplay *display) display->winsys = NULL; } -static CoglBool +static gboolean _cogl_winsys_display_setup (CoglDisplay *display, - CoglError **error) + GError **error) { CoglGLXDisplay *glx_display; int i; - _COGL_RETURN_VAL_IF_FAIL (display->winsys == NULL, FALSE); + g_return_val_if_fail (display->winsys == NULL, FALSE); glx_display = g_slice_new0 (CoglGLXDisplay); display->winsys = glx_display; @@ -1324,8 +1252,8 @@ _cogl_winsys_display_setup (CoglDisplay *display, return FALSE; } -static CoglBool -_cogl_winsys_context_init (CoglContext *context, CoglError **error) +static gboolean +_cogl_winsys_context_init (CoglContext *context, GError **error) { context->winsys = g_new0 (CoglContextGLX, 1); @@ -1341,12 +1269,12 @@ _cogl_winsys_context_deinit (CoglContext *context) cogl_xlib_renderer_remove_filter (context->display->renderer, glx_event_filter_cb, context); - free (context->winsys); + g_free (context->winsys); } -static CoglBool +static gboolean _cogl_winsys_onscreen_init (CoglOnscreen *onscreen, - CoglError **error) + GError **error) { CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); CoglContext *context = framebuffer->context; @@ -1359,19 +1287,19 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen, CoglOnscreenXlib *xlib_onscreen; CoglOnscreenGLX *glx_onscreen; GLXFBConfig fbconfig; - CoglError *fbconfig_error = NULL; + GError *fbconfig_error = NULL; - _COGL_RETURN_VAL_IF_FAIL (glx_display->glx_context, FALSE); + g_return_val_if_fail (glx_display->glx_context, FALSE); if (!find_fbconfig (display, &framebuffer->config, &fbconfig, &fbconfig_error)) { - _cogl_set_error (error, COGL_WINSYS_ERROR, + g_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_CONTEXT, "Unable to find suitable fbconfig for the GLX context: %s", fbconfig_error->message); - cogl_error_free (fbconfig_error); + g_error_free (fbconfig_error); return FALSE; } @@ -1389,48 +1317,9 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen, } /* FIXME: We need to explicitly Select for ConfigureNotify events. - * For foreign windows we need to be careful not to mess up any - * existing event mask. * We need to document that for windows we create then toolkits * must be careful not to clear event mask bits that we select. */ - - /* XXX: Note we ignore the user's original width/height when - * given a foreign X window. */ - if (onscreen->foreign_xid) - { - Status status; - CoglXlibTrapState state; - XWindowAttributes attr; - int xerror; - - xwin = onscreen->foreign_xid; - - _cogl_xlib_renderer_trap_errors (display->renderer, &state); - - status = XGetWindowAttributes (xlib_renderer->xdpy, xwin, &attr); - XSync (xlib_renderer->xdpy, False); - xerror = _cogl_xlib_renderer_untrap_errors (display->renderer, &state); - if (status == 0 || xerror) - { - char message[1000]; - XGetErrorText (xlib_renderer->xdpy, xerror, message, sizeof(message)); - _cogl_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_ONSCREEN, - "Unable to query geometry of foreign xid 0x%08lX: %s", - xwin, message); - return FALSE; - } - - _cogl_framebuffer_winsys_update_size (framebuffer, - attr.width, attr.height); - - /* Make sure the app selects for the events we require... */ - onscreen->foreign_update_mask_callback (onscreen, - COGL_ONSCREEN_X11_EVENT_MASK, - onscreen->foreign_update_mask_data); - } - else { int width; int height; @@ -1449,10 +1338,10 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen, fbconfig); if (xvisinfo == NULL) { - _cogl_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_ONSCREEN, - "Unable to retrieve the X11 visual of context's " - "fbconfig"); + g_set_error_literal (error, COGL_WINSYS_ERROR, + COGL_WINSYS_ERROR_CREATE_ONSCREEN, + "Unable to retrieve the X11 visual of context's " + "fbconfig"); return FALSE; } @@ -1488,7 +1377,7 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen, char message[1000]; XGetErrorText (xlib_renderer->xdpy, xerror, message, sizeof (message)); - _cogl_set_error (error, COGL_WINSYS_ERROR, + g_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_ONSCREEN, "X error while creating Window for CoglOnscreen: %s", message); @@ -1501,7 +1390,6 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen, glx_onscreen = onscreen->winsys; xlib_onscreen->xwin = xwin; - xlib_onscreen->is_foreign_xwin = onscreen->foreign_xid ? TRUE : FALSE; /* Try and create a GLXWindow to use with extensions dependent on * GLX versions >= 1.3 that don't accept regular X Windows as GLX @@ -1516,8 +1404,7 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen, } #ifdef GLX_INTEL_swap_event - if (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT) && - !_cogl_has_private_feature (context, COGL_PRIVATE_FEATURE_THREADED_SWAP_WAIT)) + if (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT)) { GLXDrawable drawable = glx_onscreen->glxwin ? glx_onscreen->glxwin : xlib_onscreen->xwin; @@ -1560,31 +1447,6 @@ _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen) xlib_onscreen->output = NULL; } - if (glx_onscreen->swap_wait_thread) - { - g_mutex_lock (&glx_onscreen->swap_wait_mutex); - glx_onscreen->closing_down = TRUE; - g_cond_signal (&glx_onscreen->swap_wait_cond); - g_mutex_unlock (&glx_onscreen->swap_wait_mutex); - g_thread_join (glx_onscreen->swap_wait_thread); - glx_onscreen->swap_wait_thread = NULL; - - g_cond_clear (&glx_onscreen->swap_wait_cond); - g_mutex_clear (&glx_onscreen->swap_wait_mutex); - - g_queue_free (glx_onscreen->swap_wait_queue); - glx_onscreen->swap_wait_queue = NULL; - - _cogl_poll_renderer_remove_fd (context->display->renderer, - glx_onscreen->swap_wait_pipe[0]); - - close (glx_onscreen->swap_wait_pipe[0]); - close (glx_onscreen->swap_wait_pipe[1]); - - glx_renderer->glXDestroyContext (xlib_renderer->xdpy, - glx_onscreen->swap_wait_context); - } - _cogl_xlib_renderer_trap_errors (context->display->renderer, &old_state); drawable = @@ -1616,7 +1478,7 @@ _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen) glx_onscreen->glxwin = None; } - if (!xlib_onscreen->is_foreign_xwin && xlib_onscreen->xwin != None) + if (xlib_onscreen->xwin != None) { XDestroyWindow (xlib_renderer->xdpy, xlib_onscreen->xwin); xlib_onscreen->xwin = None; @@ -1655,10 +1517,9 @@ _cogl_winsys_onscreen_bind (CoglOnscreen *onscreen) _cogl_xlib_renderer_trap_errors (context->display->renderer, &old_state); COGL_NOTE (WINSYS, - "MakeContextCurrent dpy: %p, window: 0x%x (%s), context: %p", + "MakeContextCurrent dpy: %p, window: 0x%x, context: %p", xlib_renderer->xdpy, (unsigned int) drawable, - xlib_onscreen->is_foreign_xwin ? "foreign" : "native", glx_display->glx_context); glx_renderer->glXMakeContextCurrent (xlib_renderer->xdpy, @@ -1687,18 +1548,11 @@ _cogl_winsys_onscreen_bind (CoglOnscreen *onscreen) * exclusive. */ if (glx_renderer->glXSwapInterval) - { - CoglFramebuffer *fb = COGL_FRAMEBUFFER (onscreen); - if (fb->config.swap_throttled) - glx_renderer->glXSwapInterval (1); - else - glx_renderer->glXSwapInterval (0); - } + glx_renderer->glXSwapInterval (1); XSync (xlib_renderer->xdpy, False); - /* FIXME: We should be reporting a CoglError here - */ + /* FIXME: We should be reporting a GError here */ if (_cogl_xlib_renderer_untrap_errors (context->display->renderer, &old_state)) { @@ -1818,199 +1672,6 @@ set_frame_info_output (CoglOnscreen *onscreen, } } -static gpointer -threaded_swap_wait (gpointer data) -{ - CoglOnscreen *onscreen = data; - - CoglOnscreenGLX *glx_onscreen = onscreen->winsys; - - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = framebuffer->context; - CoglDisplay *display = context->display; - CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (display->renderer); - CoglGLXDisplay *glx_display = display->winsys; - CoglGLXRenderer *glx_renderer = display->renderer->winsys; - GLXDrawable dummy_drawable; - - if (glx_display->dummy_glxwin) - dummy_drawable = glx_display->dummy_glxwin; - else - dummy_drawable = glx_display->dummy_xwin; - - glx_renderer->glXMakeContextCurrent (xlib_renderer->xdpy, - dummy_drawable, - dummy_drawable, - glx_onscreen->swap_wait_context); - - g_mutex_lock (&glx_onscreen->swap_wait_mutex); - - while (TRUE) - { - gpointer queue_element; - uint32_t vblank_counter; - - while (!glx_onscreen->closing_down && glx_onscreen->swap_wait_queue->length == 0) - g_cond_wait (&glx_onscreen->swap_wait_cond, &glx_onscreen->swap_wait_mutex); - - if (glx_onscreen->closing_down) - break; - - queue_element = g_queue_pop_tail (glx_onscreen->swap_wait_queue); - vblank_counter = GPOINTER_TO_UINT(queue_element); - - g_mutex_unlock (&glx_onscreen->swap_wait_mutex); - glx_renderer->glXWaitVideoSync (2, - (vblank_counter + 1) % 2, - &vblank_counter); - g_mutex_lock (&glx_onscreen->swap_wait_mutex); - - if (!glx_onscreen->closing_down) - { - int bytes_written = 0; - - union { - char bytes[8]; - int64_t presentation_time; - } u; - - u.presentation_time = get_monotonic_time_ns (); - - while (bytes_written < 8) - { - int res = write (glx_onscreen->swap_wait_pipe[1], u.bytes + bytes_written, 8 - bytes_written); - if (res == -1) - { - if (errno != EINTR) - g_error ("Error writing to swap notification pipe: %s\n", - g_strerror (errno)); - } - else - { - bytes_written += res; - } - } - } - } - - g_mutex_unlock (&glx_onscreen->swap_wait_mutex); - - glx_renderer->glXMakeContextCurrent (xlib_renderer->xdpy, - None, - None, - NULL); - - return NULL; -} - -static int64_t -threaded_swap_wait_pipe_prepare (void *user_data) -{ - return -1; -} - -static void -threaded_swap_wait_pipe_dispatch (void *user_data, int revents) -{ - CoglOnscreen *onscreen = user_data; - CoglOnscreenGLX *glx_onscreen = onscreen->winsys; - - CoglFrameInfo *info; - - if ((revents & COGL_POLL_FD_EVENT_IN)) - { - int bytes_read = 0; - - union { - char bytes[8]; - int64_t presentation_time; - } u; - - while (bytes_read < 8) - { - int res = read (glx_onscreen->swap_wait_pipe[0], u.bytes + bytes_read, 8 - bytes_read); - if (res == -1) - { - if (errno != EINTR) - g_error ("Error reading from swap notification pipe: %s\n", - g_strerror (errno)); - } - else - { - bytes_read += res; - } - } - - set_sync_pending (onscreen); - set_complete_pending (onscreen); - - info = g_queue_peek_head (&onscreen->pending_frame_infos); - info->presentation_time = u.presentation_time; - } -} - -static void -start_threaded_swap_wait (CoglOnscreen *onscreen, - uint32_t vblank_counter) -{ - CoglOnscreenGLX *glx_onscreen = onscreen->winsys; - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = framebuffer->context; - - if (glx_onscreen->swap_wait_thread == NULL) - { - CoglDisplay *display = context->display; - CoglGLXRenderer *glx_renderer = display->renderer->winsys; - CoglGLXDisplay *glx_display = display->winsys; - CoglOnscreenXlib *xlib_onscreen = onscreen->winsys; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (display->renderer); - - GLXDrawable drawable = - glx_onscreen->glxwin ? glx_onscreen->glxwin : xlib_onscreen->xwin; - int i; - - ensure_ust_type (display->renderer, drawable); - - if ((pipe (glx_onscreen->swap_wait_pipe) == -1)) - g_error ("Couldn't create pipe for swap notification: %s\n", - g_strerror (errno)); - - for (i = 0; i < 2; i++) - { - if (fcntl(glx_onscreen->swap_wait_pipe[i], F_SETFD, - fcntl(glx_onscreen->swap_wait_pipe[i], F_GETFD, 0) | FD_CLOEXEC) == -1) - g_error ("Couldn't set swap notification pipe CLOEXEC: %s\n", - g_strerror (errno)); - } - - _cogl_poll_renderer_add_fd (display->renderer, - glx_onscreen->swap_wait_pipe[0], - COGL_POLL_FD_EVENT_IN, - threaded_swap_wait_pipe_prepare, - threaded_swap_wait_pipe_dispatch, - onscreen); - - glx_onscreen->swap_wait_queue = g_queue_new (); - g_mutex_init (&glx_onscreen->swap_wait_mutex); - g_cond_init (&glx_onscreen->swap_wait_cond); - glx_onscreen->swap_wait_context = - glx_renderer->glXCreateNewContext (xlib_renderer->xdpy, - glx_display->fbconfig, - GLX_RGBA_TYPE, - glx_display->glx_context, - True); - glx_onscreen->swap_wait_thread = g_thread_new ("cogl_glx_swap_wait", - threaded_swap_wait, - onscreen); - } - - g_mutex_lock (&glx_onscreen->swap_wait_mutex); - g_queue_push_head (glx_onscreen->swap_wait_queue, GUINT_TO_POINTER(vblank_counter)); - g_cond_signal (&glx_onscreen->swap_wait_cond); - g_mutex_unlock (&glx_onscreen->swap_wait_mutex); -} - static void _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen, const int *user_rectangles, @@ -2027,8 +1688,8 @@ _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen, GLXDrawable drawable = glx_onscreen->glxwin ? glx_onscreen->glxwin : xlib_onscreen->xwin; uint32_t end_frame_vsync_counter = 0; - CoglBool have_counter; - CoglBool can_wait; + gboolean have_counter; + gboolean can_wait; int x_min = 0, x_max = 0, y_min = 0, y_max = 0; /* @@ -2037,7 +1698,7 @@ _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen, * case then we still want to use the vblank sync menchanism but * we only need it to throttle redraws. */ - CoglBool blit_sub_buffer_is_synchronized = + gboolean blit_sub_buffer_is_synchronized = _cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_REGION_SYNCHRONIZED); int framebuffer_width = cogl_framebuffer_get_width (framebuffer); @@ -2076,16 +1737,8 @@ _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen, framebuffer, COGL_FRAMEBUFFER_STATE_BIND); - if (framebuffer->config.swap_throttled) - { - have_counter = glx_display->have_vblank_counter; - can_wait = glx_display->can_vblank_wait; - } - else - { - have_counter = FALSE; - can_wait = FALSE; - } + have_counter = glx_display->have_vblank_counter; + can_wait = glx_display->can_vblank_wait; /* We need to ensure that all the rendering is done, otherwise * redraw operations that are slower than the framerate can @@ -2195,24 +1848,23 @@ _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen, if (have_counter) glx_onscreen->last_swap_vsync_counter = end_frame_vsync_counter; - if (!xlib_onscreen->is_foreign_xwin) - { - CoglOutput *output; + { + CoglOutput *output; - x_min = CLAMP (x_min, 0, framebuffer_width); - x_max = CLAMP (x_max, 0, framebuffer_width); - y_min = CLAMP (y_min, 0, framebuffer_width); - y_max = CLAMP (y_max, 0, framebuffer_height); + x_min = CLAMP (x_min, 0, framebuffer_width); + x_max = CLAMP (x_max, 0, framebuffer_width); + y_min = CLAMP (y_min, 0, framebuffer_width); + y_max = CLAMP (y_max, 0, framebuffer_height); - output = - _cogl_xlib_renderer_output_for_rectangle (context->display->renderer, - xlib_onscreen->x + x_min, - xlib_onscreen->y + y_min, - x_max - x_min, - y_max - y_min); + output = + _cogl_xlib_renderer_output_for_rectangle (context->display->renderer, + xlib_onscreen->x + x_min, + xlib_onscreen->y + y_min, + x_max - x_min, + y_max - y_min); - set_frame_info_output (onscreen, output); - } + set_frame_info_output (onscreen, output); + } /* XXX: we don't get SwapComplete events based on how we implement * the _swap_region() API but if cogl-onscreen.c knows we are @@ -2239,7 +1891,7 @@ _cogl_winsys_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen, CoglGLXDisplay *glx_display = context->display->winsys; CoglOnscreenXlib *xlib_onscreen = onscreen->winsys; CoglOnscreenGLX *glx_onscreen = onscreen->winsys; - CoglBool have_counter; + gboolean have_counter; GLXDrawable drawable; /* XXX: theoretically this shouldn't be necessary but at least with @@ -2252,71 +1904,47 @@ _cogl_winsys_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen, drawable = glx_onscreen->glxwin ? glx_onscreen->glxwin : xlib_onscreen->xwin; - if (framebuffer->config.swap_throttled) + have_counter = glx_display->have_vblank_counter; + + if (!glx_renderer->glXSwapInterval) { - have_counter = glx_display->have_vblank_counter; + gboolean can_wait = have_counter || glx_display->can_vblank_wait; - if (glx_renderer->glXSwapInterval) - { - if (_cogl_has_private_feature (context, COGL_PRIVATE_FEATURE_THREADED_SWAP_WAIT)) - { - /* If we didn't wait for the GPU here, then it's easy to get the case - * where there is a VBlank between the point where we get the vsync counter - * and the point where the GPU is ready to actually perform the glXSwapBuffers(), - * and the swap wait terminates at the first VBlank rather than the one - * where the swap buffers happens. Calling glFinish() here makes this a - * rare race since the GPU is already ready to swap when we call glXSwapBuffers(). - * The glFinish() also prevents any serious damage if the rare race happens, - * since it will wait for the preceding glXSwapBuffers() and prevent us from - * getting premanently ahead. (For NVIDIA drivers, glFinish() after glXSwapBuffers() - * waits for the buffer swap to happen.) - */ - _cogl_winsys_wait_for_gpu (onscreen); - start_threaded_swap_wait (onscreen, _cogl_winsys_get_vsync_counter (context)); - } - } - else + uint32_t end_frame_vsync_counter = 0; + + /* If the swap_region API is also being used then we need to track + * the vsync counter for each swap request so we can manually + * throttle swap_region requests. */ + if (have_counter) + end_frame_vsync_counter = _cogl_winsys_get_vsync_counter (context); + + /* If we are going to wait for VBLANK manually, we not only + * need to flush out pending drawing to the GPU before we + * sleep, we need to wait for it to finish. Otherwise, we + * may end up with the situation: + * + * - We finish drawing - GPU drawing continues + * - We go to sleep - GPU drawing continues + * VBLANK - We call glXSwapBuffers - GPU drawing continues + * - GPU drawing continues + * - Swap buffers happens + * + * Producing a tear. Calling glFinish() first will cause us + * to properly wait for the next VBLANK before we swap. This + * obviously does not happen when we use _GLX_SWAP and let + * the driver do the right thing + */ + _cogl_winsys_wait_for_gpu (onscreen); + + if (have_counter && can_wait) { - CoglBool can_wait = have_counter || glx_display->can_vblank_wait; - - uint32_t end_frame_vsync_counter = 0; - - /* If the swap_region API is also being used then we need to track - * the vsync counter for each swap request so we can manually - * throttle swap_region requests. */ - if (have_counter) - end_frame_vsync_counter = _cogl_winsys_get_vsync_counter (context); - - /* If we are going to wait for VBLANK manually, we not only - * need to flush out pending drawing to the GPU before we - * sleep, we need to wait for it to finish. Otherwise, we - * may end up with the situation: - * - * - We finish drawing - GPU drawing continues - * - We go to sleep - GPU drawing continues - * VBLANK - We call glXSwapBuffers - GPU drawing continues - * - GPU drawing continues - * - Swap buffers happens - * - * Producing a tear. Calling glFinish() first will cause us - * to properly wait for the next VBLANK before we swap. This - * obviously does not happen when we use _GLX_SWAP and let - * the driver do the right thing - */ - _cogl_winsys_wait_for_gpu (onscreen); - - if (have_counter && can_wait) - { - if (glx_onscreen->last_swap_vsync_counter == - end_frame_vsync_counter) - _cogl_winsys_wait_for_vblank (onscreen); - } - else if (can_wait) + if (glx_onscreen->last_swap_vsync_counter == + end_frame_vsync_counter) _cogl_winsys_wait_for_vblank (onscreen); } + else if (can_wait) + _cogl_winsys_wait_for_vblank (onscreen); } - else - have_counter = FALSE; glx_renderer->glXSwapBuffers (xlib_renderer->xdpy, drawable); @@ -2334,26 +1962,9 @@ _cogl_winsys_onscreen_x11_get_window_xid (CoglOnscreen *onscreen) return xlib_onscreen->xwin; } -static void -_cogl_winsys_onscreen_update_swap_throttled (CoglOnscreen *onscreen) -{ - CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context; - CoglContextGLX *glx_context = context->winsys; - CoglOnscreenGLX *glx_onscreen = onscreen->winsys; - CoglOnscreenXlib *xlib_onscreen = onscreen->winsys; - GLXDrawable drawable = - glx_onscreen->glxwin ? glx_onscreen->glxwin : xlib_onscreen->xwin; - - if (glx_context->current_drawable != drawable) - return; - - glx_context->current_drawable = 0; - _cogl_winsys_onscreen_bind (onscreen); -} - static void _cogl_winsys_onscreen_set_visibility (CoglOnscreen *onscreen, - CoglBool visibility) + gboolean visibility) { CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context; CoglXlibRenderer *xlib_renderer = @@ -2368,7 +1979,7 @@ _cogl_winsys_onscreen_set_visibility (CoglOnscreen *onscreen, static void _cogl_winsys_onscreen_set_resizable (CoglOnscreen *onscreen, - CoglBool resizable) + gboolean resizable) { CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); CoglContext *context = framebuffer->context; @@ -2404,12 +2015,12 @@ _cogl_winsys_onscreen_set_resizable (CoglOnscreen *onscreen, XFree (size_hints); } -static CoglBool +static gboolean get_fbconfig_for_depth (CoglContext *context, unsigned int depth, - CoglBool stereo, + gboolean stereo, GLXFBConfig *fbconfig_ret, - CoglBool *can_mipmap_ret) + gboolean *can_mipmap_ret) { CoglXlibRenderer *xlib_renderer; CoglGLXRenderer *glx_renderer; @@ -2419,7 +2030,7 @@ get_fbconfig_for_depth (CoglContext *context, int n_elements, i; int db, stencil, alpha, mipmap, rgba, value; int spare_cache_slot = 0; - CoglBool found = FALSE; + gboolean found = FALSE; xlib_renderer = _cogl_xlib_renderer_get_data (context->display->renderer); glx_renderer = context->display->renderer->winsys; @@ -2533,19 +2144,15 @@ get_fbconfig_for_depth (CoglContext *context, stencil = value; - /* glGenerateMipmap is defined in the offscreen extension */ - if (cogl_has_feature (context, COGL_FEATURE_ID_OFFSCREEN)) - { - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_BIND_TO_MIPMAP_TEXTURE_EXT, - &value); + glx_renderer->glXGetFBConfigAttrib (dpy, + fbconfigs[i], + GLX_BIND_TO_MIPMAP_TEXTURE_EXT, + &value); - if (value < mipmap) - continue; + if (value < mipmap) + continue; - mipmap = value; - } + mipmap = value; *fbconfig_ret = fbconfigs[i]; *can_mipmap_ret = mipmap; @@ -2563,58 +2170,10 @@ get_fbconfig_for_depth (CoglContext *context, return found; } -static CoglBool -should_use_rectangle (CoglContext *context) -{ - - if (context->rectangle_state == COGL_WINSYS_RECTANGLE_STATE_UNKNOWN) - { - if (cogl_has_feature (context, COGL_FEATURE_ID_TEXTURE_RECTANGLE)) - { - const char *rect_env; - - /* Use the rectangle only if it is available and either: - - the COGL_PIXMAP_TEXTURE_RECTANGLE environment variable is - set to 'force' - - *or* - - the env var is set to 'allow' or not set and NPOTs textures - are not available */ - - context->rectangle_state = - cogl_has_feature (context, COGL_FEATURE_ID_TEXTURE_NPOT) ? - COGL_WINSYS_RECTANGLE_STATE_DISABLE : - COGL_WINSYS_RECTANGLE_STATE_ENABLE; - - if ((rect_env = g_getenv ("COGL_PIXMAP_TEXTURE_RECTANGLE")) || - /* For compatibility, we'll also look at the old Clutter - environment variable */ - (rect_env = g_getenv ("CLUTTER_PIXMAP_TEXTURE_RECTANGLE"))) - { - if (g_ascii_strcasecmp (rect_env, "force") == 0) - context->rectangle_state = - COGL_WINSYS_RECTANGLE_STATE_ENABLE; - else if (g_ascii_strcasecmp (rect_env, "disable") == 0) - context->rectangle_state = - COGL_WINSYS_RECTANGLE_STATE_DISABLE; - else if (g_ascii_strcasecmp (rect_env, "allow")) - g_warning ("Unknown value for COGL_PIXMAP_TEXTURE_RECTANGLE, " - "should be 'force' or 'disable'"); - } - } - else - context->rectangle_state = COGL_WINSYS_RECTANGLE_STATE_DISABLE; - } - - return context->rectangle_state == COGL_WINSYS_RECTANGLE_STATE_ENABLE; -} - -static CoglBool +static gboolean try_create_glx_pixmap (CoglContext *context, CoglTexturePixmapX11 *tex_pixmap, - CoglBool mipmap) + gboolean mipmap) { CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys; CoglRenderer *renderer; @@ -2627,7 +2186,6 @@ try_create_glx_pixmap (CoglContext *context, GLXFBConfig fb_config = (GLXFBConfig)0; int attribs[7]; int i = 0; - GLenum target; CoglXlibTrapState trap_state; unsigned int depth = tex_pixmap->depth; @@ -2648,14 +2206,6 @@ try_create_glx_pixmap (CoglContext *context, return FALSE; } - if (should_use_rectangle (context)) - { - target = GLX_TEXTURE_RECTANGLE_EXT; - glx_tex_pixmap->can_mipmap = FALSE; - } - else - target = GLX_TEXTURE_2D_EXT; - if (!glx_tex_pixmap->can_mipmap) mipmap = FALSE; @@ -2676,7 +2226,7 @@ try_create_glx_pixmap (CoglContext *context, attribs[i++] = mipmap; attribs[i++] = GLX_TEXTURE_TARGET_EXT; - attribs[i++] = target; + attribs[i++] = GLX_TEXTURE_2D_EXT; attribs[i++] = None; @@ -2711,7 +2261,7 @@ try_create_glx_pixmap (CoglContext *context, return TRUE; } -static CoglBool +static gboolean _cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap) { CoglTexturePixmapGLX *glx_tex_pixmap; @@ -2742,7 +2292,7 @@ _cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap) if (!try_create_glx_pixmap (ctx, tex_pixmap, FALSE)) { tex_pixmap->winsys = NULL; - free (glx_tex_pixmap); + g_free (glx_tex_pixmap); return FALSE; } @@ -2817,13 +2367,13 @@ _cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap) cogl_object_unref (glx_tex_pixmap->right.glx_tex); tex_pixmap->winsys = NULL; - free (glx_tex_pixmap); + g_free (glx_tex_pixmap); } -static CoglBool +static gboolean _cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap, CoglTexturePixmapStereoMode stereo_mode, - CoglBool needs_mipmap) + gboolean needs_mipmap) { CoglTexture *tex = COGL_TEXTURE (tex_pixmap); CoglContext *ctx = COGL_TEXTURE (tex_pixmap)->context; @@ -2853,55 +2403,27 @@ _cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap, if (texture_info->glx_tex == NULL) { CoglPixelFormat texture_format; - CoglError *error = NULL; + GError *error = NULL; texture_format = (tex_pixmap->depth >= 32 ? COGL_PIXEL_FORMAT_RGBA_8888_PRE : COGL_PIXEL_FORMAT_RGB_888); - if (should_use_rectangle (ctx)) - { - texture_info->glx_tex = COGL_TEXTURE ( - cogl_texture_rectangle_new_with_size (ctx, - tex->width, - tex->height)); + texture_info->glx_tex = COGL_TEXTURE ( + cogl_texture_2d_new_with_size (ctx, tex->width, tex->height)); - _cogl_texture_set_internal_format (tex, texture_format); + _cogl_texture_set_internal_format (tex, texture_format); - if (cogl_texture_allocate (texture_info->glx_tex, &error)) - COGL_NOTE (TEXTURE_PIXMAP, "Created a texture rectangle for %p", - tex_pixmap); - else - { - COGL_NOTE (TEXTURE_PIXMAP, "Falling back for %p because a " - "texture rectangle could not be created: %s", - tex_pixmap, error->message); - cogl_error_free (error); - free_glx_pixmap (ctx, glx_tex_pixmap); - return FALSE; - } - } + if (cogl_texture_allocate (texture_info->glx_tex, &error)) + COGL_NOTE (TEXTURE_PIXMAP, "Created a texture 2d for %p", tex_pixmap); else { - texture_info->glx_tex = COGL_TEXTURE ( - cogl_texture_2d_new_with_size (ctx, - tex->width, - tex->height)); - - _cogl_texture_set_internal_format (tex, texture_format); - - if (cogl_texture_allocate (texture_info->glx_tex, &error)) - COGL_NOTE (TEXTURE_PIXMAP, "Created a texture 2d for %p", - tex_pixmap); - else - { - COGL_NOTE (TEXTURE_PIXMAP, "Falling back for %p because a " - "texture 2d could not be created: %s", - tex_pixmap, error->message); - cogl_error_free (error); - free_glx_pixmap (ctx, glx_tex_pixmap); - return FALSE; - } + COGL_NOTE (TEXTURE_PIXMAP, "Falling back for %p because a " + "texture 2d could not be created: %s", + tex_pixmap, error->message); + g_error_free (error); + free_glx_pixmap (ctx, glx_tex_pixmap); + return FALSE; } } @@ -2949,7 +2471,7 @@ _cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap, COGL_NOTE (TEXTURE_PIXMAP, "Rebinding GLXPixmap for %p", tex_pixmap); - _cogl_bind_gl_texture_transient (gl_target, gl_handle, FALSE); + _cogl_bind_gl_texture_transient (gl_target, gl_handle); if (texture_info->pixmap_bound) glx_renderer->glXReleaseTexImage (xlib_renderer->xdpy, @@ -3024,8 +2546,6 @@ static CoglWinsysVtable _cogl_winsys_vtable = _cogl_winsys_onscreen_swap_buffers_with_damage, .onscreen_swap_region = _cogl_winsys_onscreen_swap_region, .onscreen_get_buffer_age = _cogl_winsys_onscreen_get_buffer_age, - .onscreen_update_swap_throttled = - _cogl_winsys_onscreen_update_swap_throttled, .onscreen_x11_get_window_xid = _cogl_winsys_onscreen_x11_get_window_xid, .onscreen_set_visibility = _cogl_winsys_onscreen_set_visibility, @@ -3056,16 +2576,8 @@ static CoglWinsysVtable _cogl_winsys_vtable = * c99 initializers for insane platforms they can initialize * the members by name in a function. */ -const CoglWinsysVtable * +COGL_EXPORT const CoglWinsysVtable * _cogl_winsys_glx_get_vtable (void) { return &_cogl_winsys_vtable; } - -GLXContext -cogl_glx_context_get_glx_context (CoglContext *context) -{ - CoglGLXDisplay *glx_display = context->display->winsys; - - return glx_display->glx_context; -} diff --git a/cogl/cogl/winsys/cogl-winsys-private.h b/cogl/cogl/winsys/cogl-winsys-private.h index a8e07a509..d849ef705 100644 --- a/cogl/cogl/winsys/cogl-winsys-private.h +++ b/cogl/cogl/winsys/cogl-winsys-private.h @@ -33,7 +33,6 @@ #include "cogl-renderer.h" #include "cogl-onscreen.h" -#include "cogl-gles2.h" #ifdef COGL_HAS_XLIB_SUPPORT #include "cogl-texture-pixmap-x11-private.h" @@ -50,26 +49,19 @@ #include "cogl-poll.h" -uint32_t +COGL_EXPORT uint32_t _cogl_winsys_error_quark (void); #define COGL_WINSYS_ERROR (_cogl_winsys_error_quark ()) -typedef enum { /*< prefix=COGL_WINSYS_ERROR >*/ +typedef enum /*< prefix=COGL_WINSYS_ERROR >*/ +{ COGL_WINSYS_ERROR_INIT, COGL_WINSYS_ERROR_CREATE_CONTEXT, COGL_WINSYS_ERROR_CREATE_ONSCREEN, COGL_WINSYS_ERROR_MAKE_CURRENT, - COGL_WINSYS_ERROR_CREATE_GLES2_CONTEXT, } CoglWinsysError; -typedef enum -{ - COGL_WINSYS_RECTANGLE_STATE_UNKNOWN, - COGL_WINSYS_RECTANGLE_STATE_DISABLE, - COGL_WINSYS_RECTANGLE_STATE_ENABLE -} CoglWinsysRectangleState; - typedef struct _CoglWinsysVtable { CoglWinsysID id; @@ -79,13 +71,13 @@ typedef struct _CoglWinsysVtable /* Required functions */ - CoglFuncPtr + GCallback (*renderer_get_proc_address) (CoglRenderer *renderer, const char *name, - CoglBool in_core); + gboolean in_core); - CoglBool - (*renderer_connect) (CoglRenderer *renderer, CoglError **error); + gboolean + (*renderer_connect) (CoglRenderer *renderer, GError **error); void (*renderer_disconnect) (CoglRenderer *renderer); @@ -93,23 +85,26 @@ typedef struct _CoglWinsysVtable void (*renderer_outputs_changed) (CoglRenderer *renderer); - CoglBool - (*display_setup) (CoglDisplay *display, CoglError **error); + gboolean + (*display_setup) (CoglDisplay *display, GError **error); void (*display_destroy) (CoglDisplay *display); - CoglBool - (*context_init) (CoglContext *context, CoglError **error); + CoglDmaBufHandle * + (*renderer_create_dma_buf) (CoglRenderer *renderer, + int width, + int height, + GError **error); + + gboolean + (*context_init) (CoglContext *context, GError **error); void (*context_deinit) (CoglContext *context); - void * - (*context_create_gles2_context) (CoglContext *ctx, CoglError **error); - - CoglBool - (*onscreen_init) (CoglOnscreen *onscreen, CoglError **error); + gboolean + (*onscreen_init) (CoglOnscreen *onscreen, GError **error); void (*onscreen_deinit) (CoglOnscreen *onscreen); @@ -122,12 +117,9 @@ typedef struct _CoglWinsysVtable const int *rectangles, int n_rectangles); - void - (*onscreen_update_swap_throttled) (CoglOnscreen *onscreen); - void (*onscreen_set_visibility) (CoglOnscreen *onscreen, - CoglBool visibility); + gboolean visibility); /* Optional functions */ @@ -140,7 +132,7 @@ typedef struct _CoglWinsysVtable int n_rectangles); void - (*onscreen_set_resizable) (CoglOnscreen *onscreen, CoglBool resizable); + (*onscreen_set_resizable) (CoglOnscreen *onscreen, gboolean resizable); int (*onscreen_get_buffer_age) (CoglOnscreen *onscreen); @@ -149,15 +141,15 @@ typedef struct _CoglWinsysVtable (*onscreen_x11_get_window_xid) (CoglOnscreen *onscreen); #ifdef COGL_HAS_XLIB_SUPPORT - CoglBool + gboolean (*texture_pixmap_x11_create) (CoglTexturePixmapX11 *tex_pixmap); void (*texture_pixmap_x11_free) (CoglTexturePixmapX11 *tex_pixmap); - CoglBool + gboolean (*texture_pixmap_x11_update) (CoglTexturePixmapX11 *tex_pixmap, CoglTexturePixmapStereoMode stereo_mode, - CoglBool needs_mipmap); + gboolean needs_mipmap); void (*texture_pixmap_x11_damage_notify) (CoglTexturePixmapX11 *tex_pixmap); @@ -167,22 +159,10 @@ typedef struct _CoglWinsysVtable CoglTexturePixmapStereoMode stereo_mode); #endif - void - (*save_context) (CoglContext *ctx); - - CoglBool - (*set_gles2_context) (CoglGLES2Context *gles2_ctx, CoglError **error); - - void - (*restore_context) (CoglContext *ctx); - - void - (*destroy_gles2_context) (CoglGLES2Context *gles2_ctx); - void * (*fence_add) (CoglContext *ctx); - CoglBool + gboolean (*fence_is_complete) (CoglContext *ctx, void *fence); void @@ -192,7 +172,7 @@ typedef struct _CoglWinsysVtable typedef const CoglWinsysVtable *(*CoglWinsysVtableGetter) (void); -CoglBool +gboolean _cogl_winsys_has_feature (CoglWinsysFeature feature); #endif /* __COGL_WINSYS_PRIVATE_H */ diff --git a/cogl/cogl/winsys/cogl-winsys-stub-private.h b/cogl/cogl/winsys/cogl-winsys-stub-private.h deleted file mode 100644 index 4aaf798a3..000000000 --- a/cogl/cogl/winsys/cogl-winsys-stub-private.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_WINSYS_STUB_PRIVATE_H -#define __COGL_WINSYS_STUB_PRIVATE_H - -const CoglWinsysVtable * -_cogl_winsys_stub_get_vtable (void); - -#endif /* __COGL_WINSYS_STUB_PRIVATE_H */ diff --git a/cogl/cogl/winsys/cogl-winsys-stub.c b/cogl/cogl/winsys/cogl-winsys-stub.c deleted file mode 100644 index ba49a9419..000000000 --- a/cogl/cogl/winsys/cogl-winsys-stub.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Robert Bragg - * - */ - -#ifdef HAVE_CONFIG_H -#include "cogl-config.h" -#endif - -#include "cogl-renderer-private.h" -#include "cogl-display-private.h" -#include "cogl-context-private.h" -#include "cogl-framebuffer-private.h" -#include "cogl-private.h" -#include "cogl-winsys-stub-private.h" - -#include - -static int _cogl_winsys_stub_dummy_ptr; - -/* This provides a NOP winsys. This can be useful for debugging or for - * integrating with toolkits that already have window system - * integration code. - */ - -static CoglFuncPtr -_cogl_winsys_renderer_get_proc_address (CoglRenderer *renderer, - const char *name, - CoglBool in_core) -{ - static GModule *module = NULL; - - /* this should find the right function if the program is linked against a - * library providing it */ - if (G_UNLIKELY (module == NULL)) - module = g_module_open (NULL, 0); - - if (module) - { - void *symbol; - - if (g_module_symbol (module, name, &symbol)) - return symbol; - } - - return NULL; -} - -static void -_cogl_winsys_renderer_disconnect (CoglRenderer *renderer) -{ - renderer->winsys = NULL; -} - -static CoglBool -_cogl_winsys_renderer_connect (CoglRenderer *renderer, - CoglError **error) -{ - renderer->winsys = &_cogl_winsys_stub_dummy_ptr; - return TRUE; -} - -static void -_cogl_winsys_display_destroy (CoglDisplay *display) -{ - display->winsys = NULL; -} - -static CoglBool -_cogl_winsys_display_setup (CoglDisplay *display, - CoglError **error) -{ - display->winsys = &_cogl_winsys_stub_dummy_ptr; - return TRUE; -} - -static CoglBool -_cogl_winsys_context_init (CoglContext *context, CoglError **error) -{ - context->winsys = &_cogl_winsys_stub_dummy_ptr; - - if (!_cogl_context_update_features (context, error)) - return FALSE; - - memset (context->winsys_features, 0, sizeof (context->winsys_features)); - - return TRUE; -} - -static void -_cogl_winsys_context_deinit (CoglContext *context) -{ - context->winsys = NULL; -} - -static CoglBool -_cogl_winsys_onscreen_init (CoglOnscreen *onscreen, - CoglError **error) -{ - return TRUE; -} - -static void -_cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen) -{ -} - -static void -_cogl_winsys_onscreen_bind (CoglOnscreen *onscreen) -{ -} - -static void -_cogl_winsys_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen, - const int *rectangles, - int n_rectangles) -{ -} - -static void -_cogl_winsys_onscreen_update_swap_throttled (CoglOnscreen *onscreen) -{ -} - -static void -_cogl_winsys_onscreen_set_visibility (CoglOnscreen *onscreen, - CoglBool visibility) -{ -} - -const CoglWinsysVtable * -_cogl_winsys_stub_get_vtable (void) -{ - static CoglBool vtable_inited = FALSE; - static CoglWinsysVtable vtable; - - /* It would be nice if we could use C99 struct initializers here - like the GLX backend does. However this code is more likely to be - compiled using Visual Studio which (still!) doesn't support them - so we initialize it in code instead */ - - if (!vtable_inited) - { - memset (&vtable, 0, sizeof (vtable)); - - vtable.id = COGL_WINSYS_ID_STUB; - vtable.name = "STUB"; - vtable.renderer_get_proc_address = _cogl_winsys_renderer_get_proc_address; - vtable.renderer_connect = _cogl_winsys_renderer_connect; - vtable.renderer_disconnect = _cogl_winsys_renderer_disconnect; - vtable.display_setup = _cogl_winsys_display_setup; - vtable.display_destroy = _cogl_winsys_display_destroy; - vtable.context_init = _cogl_winsys_context_init; - vtable.context_deinit = _cogl_winsys_context_deinit; - - vtable.onscreen_init = _cogl_winsys_onscreen_init; - vtable.onscreen_deinit = _cogl_winsys_onscreen_deinit; - vtable.onscreen_bind = _cogl_winsys_onscreen_bind; - vtable.onscreen_swap_buffers_with_damage = - _cogl_winsys_onscreen_swap_buffers_with_damage; - vtable.onscreen_update_swap_throttled = - _cogl_winsys_onscreen_update_swap_throttled; - vtable.onscreen_set_visibility = _cogl_winsys_onscreen_set_visibility; - - vtable_inited = TRUE; - } - - return &vtable; -} diff --git a/cogl/cogl/winsys/cogl-winsys.c b/cogl/cogl/winsys/cogl-winsys.c index b0a7b68ca..9eacd81c0 100644 --- a/cogl/cogl/winsys/cogl-winsys.c +++ b/cogl/cogl/winsys/cogl-winsys.c @@ -28,9 +28,7 @@ * */ -#ifdef HAVE_CONFIG_H #include "cogl-config.h" -#endif #include "cogl-context-private.h" @@ -43,7 +41,7 @@ _cogl_winsys_error_quark (void) } /* FIXME: we should distinguish renderer and context features */ -CoglBool +gboolean _cogl_winsys_has_feature (CoglWinsysFeature feature) { _COGL_GET_CONTEXT (ctx, FALSE); diff --git a/cogl/config-custom.h b/cogl/config-custom.h index d31afeff5..08fb9a40c 100644 --- a/cogl/config-custom.h +++ b/cogl/config-custom.h @@ -30,4 +30,3 @@ intended for extra configuration that needs to be included by all Cogl source files. */ -#include diff --git a/cogl/configure.ac b/cogl/configure.ac deleted file mode 100644 index 023afb645..000000000 --- a/cogl/configure.ac +++ /dev/null @@ -1,1024 +0,0 @@ -AC_PREREQ(2.59) - -dnl ================================================================ -dnl XXX: If you are making a release then you need to check these -dnl sections: -dnl » API versions (Only the 1.x version needs to change) -dnl (the pretty numbers that the users see) -dnl -dnl » Interface version details for libtool -dnl (the shared library versioning information) -dnl -dnl » Source code release status -dnl (mark the source code as being part of a "release" or from "git") -dnl ================================================================ - -dnl ================================================================ -dnl API versions (i.e. the pretty numbers that users see) -dnl ================================================================ -m4_define([cogl_major_version], [2]) -m4_define([cogl_minor_version], [0]) -m4_define([cogl_micro_version], [0]) -m4_define([cogl_version], - [cogl_major_version.cogl_minor_version.cogl_micro_version]) - -dnl Since the core Cogl library has to also maintain support for the -dnl Cogl 1.x API for Clutter then we track the 1.x version separately. -m4_define([cogl_1_minor_version], [22]) -m4_define([cogl_1_micro_version], [1]) -m4_define([cogl_1_version], [1.cogl_1_minor_version.cogl_1_micro_version]) - -dnl ================================================================ -dnl Interface version details for libtool -dnl ================================================================ -# Note: we don't automatically deduce the libtool version info from -# the pretty version number that users sees. This is because we want -# to update the pretty version number before making a release since it -# can affect the name of our pkg-config file and the naming or -# location of other installed files which we want to be able to verify -# as correct well before making a release. -# -# For reference on how the various numbers should be updated at -# release time these rules are adapted from the libtool info pages: -# -# 1. Update the version information only immediately before a public -# release. -# -# 2. If the library source code has changed at all since the last -# update, then increment REVISION (`C:R:A' becomes `C:r+1:A'). -# -# 3. If any interfaces have been added, removed, or changed since the -# last update, increment CURRENT, and set REVISION to 0. -# -# 4. If any interfaces have been added since the last public release, -# then increment AGE. -# -# 5. If any interfaces have been removed since the last public release, -# then set AGE to 0. -m4_define([cogl_lt_current], 24) -m4_define([cogl_lt_revision], 1) -m4_define([cogl_lt_age], 4) -# We do also tell libtool the pretty version: -m4_define([cogl_lt_release], [cogl_version]) - - -dnl ================================================================ -dnl Source code release status -dnl ================================================================ -# Finally we explicitly track when we are building development source -# from Git vs building source corresponding to a release. As with the -# libtool version info we don't automatically derive this from the -# pretty version number because we want to test the results of -# updating the version number in advance of a release. -# -# Possible status values are: git, snapshot or release -# -m4_define([cogl_release_status], [git]) - -AC_INIT(cogl, [cogl_1_version]) -AC_CONFIG_SRCDIR(cogl/cogl.h) -AC_CONFIG_AUX_DIR([build]) -AC_CONFIG_MACRO_DIR([build/autotools]) -AC_CONFIG_HEADERS(cogl-config.h) -AC_CONFIG_HEADERS(cogl-muffin-config.h) -AC_GNU_SOURCE - -dnl ================================================================ -dnl Check that we are configured by muffin -dnl ================================================================ - -AC_ARG_VAR([MUFFIN_VERSION]) -AC_ARG_VAR([MUFFIN_PLUGIN_API_VERSION]) - -AS_IF([test "x$MUFFIN_VERSION" = "x"], - [AC_MSG_ERROR([Clutter can only be configured by muffin])],) - -dnl ================================================================ -dnl Required versions for dependencies -dnl ================================================================ -m4_define([glib_req_version], [2.32.0]) -m4_define([pangocairo_req_version], [1.20]) -m4_define([gi_req_version], [0.9.5]) -m4_define([gdk_pixbuf_req_version], [2.0]) -m4_define([uprof_req_version], [0.3]) -m4_define([xfixes_req_version], [3]) -m4_define([xcomposite_req_version], [0.4]) -m4_define([xrandr_req_version], [1.2]) -m4_define([cairo_req_version], [1.10]) -m4_define([wayland_server_req_version], [1.1.90]) -m4_define([mirclient_req_version], [0.9.0]) - -dnl These variables get copied into the generated README -AC_SUBST([GLIB_REQ_VERSION], [glib_req_version]) -AC_SUBST([GDK_PIXBUF_REQ_VERSION], [gdk_pixbuf_req_version]) -AC_SUBST([CAIRO_REQ_VERSION], [cairo_req_version]) -AC_SUBST([PANGOCAIRO_REQ_VERSION], [pangocairo_req_version]) -AC_SUBST([XCOMPOSITE_REQ_VERSION], [xcomposite_req_version]) -AC_SUBST([XFIXES_REQ_VERSION], [xfixes_req_version]) -AC_SUBST([GI_REQ_VERSION], [gi_req_version]) -AC_SUBST([UPROF_REQ_VERSION], [uprof_req_version]) -AC_SUBST([WAYLAND_SERVER_REQ_VERSION], [wayland_server_req_version]) - -# Save this value here, since automake will set cflags later and we -# want to know if the user specified custom cflags or not. -cflags_set=${CFLAGS+set} - -AM_INIT_AUTOMAKE([1.14 foreign -Wno-portability no-define no-dist-gzip dist-xz tar-ustar subdir-objects]) -AM_SILENT_RULES([yes]) - -AH_BOTTOM([#include "config-custom.h"]) - -dnl ================================================================ -dnl Export the API versioning -dnl ================================================================ -AC_SUBST([COGL_MAJOR_VERSION],[cogl_major_version]) -AC_SUBST([COGL_MINOR_VERSION],[cogl_minor_version]) -AC_SUBST([COGL_MICRO_VERSION],[cogl_micro_version]) -AC_SUBST([COGL_VERSION],[cogl_version]) -AC_SUBST([COGL_API_VERSION],[cogl_major_version.0]) -AC_SUBST([COGL_API_VERSION_AM],[$COGL_MAJOR_VERSION\_0]) - -AC_SUBST([COGL_1_MINOR_VERSION],[cogl_1_minor_version]) -AC_SUBST([COGL_1_MICRO_VERSION],[cogl_1_micro_version]) -AC_SUBST([COGL_1_VERSION],[cogl_1_version]) - - -dnl ================================================================ -dnl Export the libtool versioning -dnl ================================================================ -AC_SUBST([COGL_LT_CURRENT], [cogl_lt_current]) -AC_SUBST([COGL_LT_REVISION], [cogl_lt_revision]) -AC_SUBST([COGL_LT_AGE], [cogl_lt_age]) -AC_SUBST([COGL_LT_RELEASE], [cogl_lt_release]) - - -dnl ================================================================ -dnl Export the source code release status -dnl ================================================================ -AC_SUBST([COGL_RELEASE_STATUS], [cogl_release_status]) - -dnl ================================================================ -dnl Compiler stuff. -dnl ================================================================ -AC_PROG_CC -AC_PROG_CPP -AC_PROG_CXX -AM_PROG_CC_C_O -AC_ISC_POSIX -AC_C_CONST - -dnl ============================================================ -dnl Compiler features -dnl ============================================================ -AC_MSG_CHECKING([for _Static_assert]) -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([_Static_assert (1, "");], - [(void) 0])], - [AC_DEFINE([HAVE_STATIC_ASSERT], [1], - [Whether _Static_assert can be used or not]) - AC_MSG_RESULT([yes])], - [AC_MSG_RESULT([no])]) - -dnl ================================================================ -dnl Libtool stuff. -dnl ================================================================ -dnl AC_PROG_LIBTOOL -dnl LIBTOOL="$LIBTOOL --preserve-dup-deps" -LT_PREREQ([2.2.6]) -LT_INIT([disable-static]) -dnl when using libtool 2.x create libtool early, because it's used in the -dnl internal glib configure (as-glibconfig.m4) -m4_ifdef([LT_OUTPUT], [LT_OUTPUT]) - -dnl ================================================================ -dnl Find an appropriate libm, for sin() etc. -dnl ================================================================ -LT_LIB_M -AC_SUBST(LIBM) - -dnl ================================================================ -dnl See what platform we are building for -dnl ================================================================ -AC_CANONICAL_HOST - -dnl ============================================================ -dnl Installed tests -dnl ============================================================ - -AC_ARG_ENABLE(installed_tests, - AS_HELP_STRING([--enable-installed-tests], - [Install test programs (default: no)]),, - [enable_installed_tests=no]) -AM_CONDITIONAL(ENABLE_INSTALLED_TESTS, test x$enable_installed_tests = xyes) - -dnl ============================================================ -dnl Enable debugging -dnl ============================================================ -m4_define([debug_default], [m4_if(cogl_release_status, [git], [yes], [no])]) -AC_ARG_ENABLE( - [debug], - [AC_HELP_STRING([--enable-debug=@<:@no/yes@:>@], [Control Cogl debugging level @<:@default=]debug_default[@:>@])], - [], - enable_debug=debug_default -) -AS_CASE( - [$enable_debug], - [yes], - [ - test "$cflags_set" = set || CFLAGS="$CFLAGS -g -O0" - COGL_EXTRA_CFLAGS="$COGL_EXTRA_CFLAGS -DCOGL_GL_DEBUG -DCOGL_OBJECT_DEBUG -DCOGL_ENABLE_DEBUG" - ], - [no], - [ - COGL_EXTRA_CFLAGS="$COGL_EXTRA_CFLAGS -DG_DISABLE_CHECKS -DG_DISABLE_CAST_CHECKS" - ], - [AC_MSG_ERROR([Unknown argument for --enable-debug])] -) - -AC_SUBST(COGL_DEBUG_CFLAGS) - -AC_ARG_ENABLE( - [unit-tests], - [AC_HELP_STRING([--enable-unit-tests=@<:@no/yes@:>@], [Build Cogl unit tests @<:@default=yes@:>@])], - [], - enable_unit_tests=yes -) -AS_IF([test "x$enable_unit_tests" = "xyes"], - [ - AC_DEFINE([ENABLE_UNIT_TESTS], [1], [Whether to enable building unit tests]) - ] -) -AM_CONDITIONAL(UNIT_TESTS, test "x$enable_unit_tests" = "xyes") - -dnl ============================================================ -dnl Enable cairo usage for debugging -dnl (debugging code can use cairo to dump the atlas) -dnl ============================================================ - -PKG_CHECK_EXISTS([CAIRO], [cairo >= cairo_req_version], [have_cairo=yes]) -AC_ARG_ENABLE( - [cairo], - [AC_HELP_STRING([--enable-cairo=@<:@no/yes@:>@], [Control Cairo usage in Cogl debugging code @<:@default=auto@:>@])], - [], - [ - AS_IF([test "x$enable_debug" = "xyes"], - [enable_cairo=$have_cairo], - [enable_cairo=no]) - ] -) -AS_IF([test "x$enable_cairo" = "xyes" && test "x$enable_debug" = "xyes"], - [ - AS_IF([test "x$have_cairo" != "xyes"], - [AC_MSG_ERROR([Could not find Cairo])]) - - COGL_PKG_REQUIRES="$COGL_PKG_REQUIRES cairo >= cairo_req_version" - AC_DEFINE([HAVE_CAIRO], [1], [Whether we have cairo or not]) - ]) - - -dnl ============================================================ -dnl Enable profiling -dnl ============================================================ -AC_ARG_ENABLE(profile, - [AC_HELP_STRING([--enable-profile=@<:@no/yes@:>@], - [Turn on uprof profiling support. yes; All UProf profiling probe points are compiled in and may be runtime enabled. no; No profiling support will built into cogl. @<:@default=no@:>@])], - [], - [enable_profile=no]) -AS_IF([test "x$enable_profile" = "xyes"], - [ - AS_IF([test "x$GCC" = "xyes"], - [ - COGL_PKG_REQUIRES="$COGL_PKG_REQUIRES uprof-0.3" - COGL_EXTRA_CFLAGS="$COGL_EXTRA_CFLAGS -DCOGL_ENABLE_PROFILE" - AS_IF([test "x$enable_debug" = "xyes"], [COGL_EXTRA_CFLAGS="$COGL_EXTRA_CFLAGS -DUPROF_DEBUG"]) - ], - [ - AC_MSG_ERROR([--enable-profile is currently only supported if using GCC]) - ]) - ]) -AM_CONDITIONAL(PROFILE, test "x$enable_profile" != "xno") - - -dnl ============================================================ -dnl Enable strict compiler flags -dnl ============================================================ - -# use strict compiler flags only when building from git; the rules for -# distcheck will take care of turning this on when making a release -m4_define([maintainer_default], [m4_if(cogl_release_status, [git], [yes], [no])]) -AC_ARG_ENABLE( - [maintainer-flags], - [AC_HELP_STRING([--enable-maintainer-flags=@<:@no/yes/error@:>@], [Use strict compiler flags @<:@default=]maintainer_default[@:>@])], - [], - enable_maintainer_flags=maintainer_default -) - -MAINTAINER_COMPILER_FLAGS="-Wall -Wcast-align -Wformat -Wformat-security - -Werror=uninitialized -Werror=no-strict-aliasing - -Werror=empty-body -Werror=init-self -Werror=undef - -Werror=declaration-after-statement -Werror=vla - -Werror=pointer-arith -Werror=missing-declarations - -Werror=maybe-uninitialized" - -AS_CASE( - [$enable_maintainer_flags], - [yes], - [ - AS_COMPILER_FLAGS([MAINTAINER_CFLAGS], [$MAINTAINER_COMPILER_FLAGS]) - ], - [no], - [ - ], - [error], - [ - MAINTAINER_COMPILER_FLAGS="$MAINTAINER_COMPILER_FLAGS -Werror" - AS_COMPILER_FLAGS([MAINTAINER_CFLAGS], [$MAINTAINER_COMPILER_FLAGS]) - ], - [*], - [AC_MSG_ERROR([Invalid option for --enable-maintainer-flags])] -) - -# strip leading spaces -COGL_EXTRA_CFLAGS="$COGL_EXTRA_CFLAGS ${MAINTAINER_CFLAGS#* }" -COGL_EXTRA_CFLAGS="$COGL_EXTRA_CFLAGS -Wno-error=sign-compare" - - -dnl ============================================================ -dnl Enable deprecation guards -dnl ============================================================ - -# disable deprecated options from Glib only when building from git; -# the rules for distcheck will take care of turning this on when -# making a release -m4_define([deprecated_default], - [m4_if(cogl_release_status, [git], [no], [yes])]) - -AC_ARG_ENABLE([deprecated], - [AS_HELP_STRING([--enable-deprecated=@<:@no/yes@:>@], - [Whether deprecated symbols should be disabled when compiling Cogl @<:@default=]deprecated_default[@:>@])], - [], - [enable_deprecated=deprecated_default]) - -AS_CASE([$enable_deprecated], - - [no], - [ - DEPRECATED_CFLAGS="-DG_DISABLE_DEPRECATED -DG_DISABLE_SINGLE_INCLUDES" - ], - - [yes], - [ - DEPRECATED_CFLAGS="" - ], - - [AC_MSG_ERROR([Unknown argument for --enable-deprecated])] -) - -# strip leading spaces -COGL_EXTRA_CFLAGS="$COGL_EXTRA_CFLAGS ${DEPRECATED_CFLAGS#* }" - -dnl ================================================================ -dnl Check for dependency packages. -dnl ================================================================ - -AM_PATH_GLIB_2_0([glib_req_version], - [], - [AC_MSG_ERROR([glib-2.0 is required])], - [gobject gthread gmodule-no-export]) - -COGL_PKG_REQUIRES="$COGL_PKG_REQUIRES gobject-2.0 gmodule-no-export-2.0" - -dnl ============================================================ -dnl Should cogl-pango be built? -dnl ============================================================ - -AC_ARG_ENABLE( - [cogl-pango], - [AC_HELP_STRING([--enable-cogl-pango=@<:@no/yes@:>@], [Enable pango support @<:@default=yes@:>@])], - [], - enable_cogl_pango=yes -) -AS_IF([test "x$enable_cogl_pango" = "xyes"], - [ - COGL_PANGO_PKG_REQUIRES="$COGL_PANGO_PKG_REQUIRES pangocairo >= pangocairo_req_version" - ] -) - -dnl ============================================================ -dnl Should cogl-path be built? -dnl ============================================================ - -AC_ARG_ENABLE( - [cogl-path], - [AC_HELP_STRING([--enable-cogl-path=@<:@no/yes@:>@], [Enable 2D path support @<:@default=yes@:>@])], - [], - enable_cogl_path=yes -) -AS_IF([test "x$enable_cogl_path" = "xyes"], - [ - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_COGL_PATH_SUPPORT" - ] -) - -dnl ============================================================ -dnl Choose image loading backend -dnl ============================================================ -COGL_PKG_REQUIRES="$COGL_PKG_REQUIRES gdk-pixbuf-2.0 >= gdk_pixbuf_req_version" -COGL_IMAGE_BACKEND="gdk-pixbuf" - -dnl ============================================================ -dnl Determine which drivers and window systems we can support -dnl ============================================================ - -dnl ======================================================== -dnl Drivers first... -dnl ======================================================== -EGL_CHECKED=no - -enabled_drivers="" - -HAVE_GLES1=0 -AC_ARG_ENABLE( - [gles1], - [AC_HELP_STRING([--enable-gles1=@<:@no/yes@:>@], [Enable support for OpenGL-ES 1.1 @<:@default=no@:>@])], - [], - enable_gles1=no -) -AS_IF([test "x$enable_gles1" = "xyes"], - [ - enabled_drivers="$enabled_drivers gles1" - - cogl_gl_headers="GLES/gl.h GLES/glext.h" - - AC_DEFINE([HAVE_COGL_GLES], 1, [Have GLES 1.1 for rendering]) - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_GLES CLUTTER_COGL_HAS_GLES" - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_GLES1" - HAVE_GLES1=1 - - PKG_CHECK_EXISTS([glesv1_cm], - [COGL_PKG_REQUIRES_GL="$COGL_PKG_REQUIRES_GL glesv1_cm" - COGL_GLES1_LIBNAME="libGLESv1_CM.so" - ], - [ - # We have to check the two headers independently as GLES/glext.h - # needs to include GLES/gl.h to have the GL types defined (eg. - # GLenum). - AC_CHECK_HEADER([GLES/gl.h], - [], - [AC_MSG_ERROR([Unable to locate GLES/gl.h])]) - AC_CHECK_HEADER([GLES/glext.h], - [], - [AC_MSG_ERROR([Unable to locate GLES/glext.h])], - [#include ]) - - # Early implementations provided only a GLES/egl.h while Khronos's - # implementer guide now states EGL/egl.h is the One. Some - # implementations keep a GLES/egl.h wrapper around EGL/egl.h for - # backward compatibility while others provide EGL/egl.h only. - AC_CHECK_HEADERS([GLES/egl.h EGL/egl.h]) - - AS_IF([test "x$ac_cv_header_GLES_egl_h" = "xyes"], - [COGL_EGL_INCLUDES="#include "], - [test "x$ac_cv_header_EGL_egl_h" = "xyes"], - [ - COGL_EGL_INCLUDES="#include " - ], - [AC_MSG_ERROR([Unable to locate EGL header])]) - AC_SUBST([COGL_EGL_INCLUDES]) - - AC_CHECK_HEADERS([EGL/eglext.h], - [COGL_EGL_INCLUDES="$COGL_EGL_INCLUDE -#include "], - [], - [$COGL_EGL_INCLUDES]) - - # Check for a GLES 1.x Common Profile library with/without EGL. - # - # Note: historically GLES 1 libraries shipped with the - # EGL and GLES symbols all bundled in one library. Now - # the Khronos Implementers Guide defines two naming - # schemes: -lGLES_CM should be used for a library that - # bundles the GLES and EGL API together and -lGLESv1_CM - # would be used for a standalone GLES API. - AC_CHECK_LIB(GLES_CM, [eglInitialize], - [COGL_GLES1_LIBNAME="libGLES_CM.so"], - [ - AC_CHECK_LIB(GLESv1_CM, [glFlush], - [COGL_GLES1_LIBNAME="libGLESv1_CM.so" - NEED_SEPARATE_EGL=yes - ], - [AC_MSG_ERROR([Unable to locate required GLES 1.x Common Profile library])]) - ]) - - EGL_CHECKED=yes - ]) - ]) - -HAVE_GLES2=0 -AC_ARG_ENABLE( - [gles2], - [AC_HELP_STRING([--enable-gles2=@<:@no/yes@:>@], [Enable support for OpenGL-ES 2.0 @<:@default=no@:>@])], - [], - enable_gles2=no -) -AS_IF([test "x$enable_gles2" = "xyes"], - [ - enabled_drivers="$enabled_drivers gles2" - - cogl_gl_headers="GLES2/gl2.h GLES2/gl2ext.h" - AC_DEFINE([HAVE_COGL_GLES2], 1, [Have GLES 2.0 for rendering]) - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_GLES CLUTTER_COGL_HAS_GLES" - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_GLES2" - HAVE_GLES2=1 - - PKG_CHECK_EXISTS([glesv2], - [COGL_PKG_REQUIRES_GL="$COGL_PKG_REQUIRES_GL glesv2" - COGL_GLES2_LIBNAME="libGLESv2.so" - ], - [ - # We have to check the two headers independently as GLES2/gl2ext.h - # needs to include GLES2/gl2.h to have the GL types defined (eg. - # GLenum). - AC_CHECK_HEADER([GLES2/gl2.h], - [], - [AC_MSG_ERROR([Unable to locate GLES2/gl2.h])]) - AC_CHECK_HEADER([GLES2/gl2ext.h], - [], - [AC_MSG_ERROR([Unable to locate GLES2/gl2ext.h])], - [#include ]) - - COGL_GLES2_LIBNAME="libGLESv2.so" - ]) - ]) - -HAVE_GL=0 -AC_ARG_ENABLE( - [gl], - [AC_HELP_STRING([--enable-gl=@<:@no/yes@:>@], [Enable support for OpenGL @<:@default=yes@:>@])], - [], - [enable_gl=yes] -) -AS_IF([test "x$enable_gl" = "xyes"], - [ - enabled_drivers="$enabled_drivers gl" - - PKG_CHECK_EXISTS([x11], [ALLOW_GLX=yes]) - - cogl_gl_headers="GL/gl.h" - - PKG_CHECK_EXISTS([gl], - dnl We don't want to use COGL_PKG_REQUIRES here because we don't want to - dnl directly link against libGL - [COGL_PKG_REQUIRES_GL="$COGL_PKG_REQUIRES_GL gl"], - [AC_CHECK_LIB(GL, [glGetString], - , - [AC_MSG_ERROR([Unable to locate required GL library])]) - ]) - COGL_GL_LIBNAME="libGL.so.1" - - AC_DEFINE([HAVE_COGL_GL], [1], [Have GL for rendering]) - - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_GL" - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS CLUTTER_COGL_HAS_GL" - HAVE_GL=1 - ]) - -AM_CONDITIONAL([COGL_DRIVER_GL_SUPPORTED], [test "x$enable_gl" = "xyes"]) -AM_CONDITIONAL([COGL_DRIVER_GLES_SUPPORTED], - [test "x$enable_gles1" = "xyes" || test "x$enable_gles2" = "xyes"]) - -dnl Allow the GL library names and default driver to be overridden with configure options -AC_ARG_WITH([gl-libname], - [AS_HELP_STRING([--with-gl-libname], - override the name of the GL library to dlopen)], - [COGL_GL_LIBNAME="$withval"]) -AC_ARG_WITH([gles1-libname], - [AS_HELP_STRING([--with-gles1-libname], - override the name of the GLESv1 library to dlopen)], - [COGL_GLES1_LIBNAME="$withval"]) -AC_ARG_WITH([gles2-libname], - [AS_HELP_STRING([--with-gles2-libname], - override the name of the GLESv2 library to dlopen)], - [COGL_GLES2_LIBNAME="$withval"]) -AC_ARG_WITH([default-driver], - [AS_HELP_STRING([--with-default-driver], - specify a default cogl driver)], - [COGL_DEFAULT_DRIVER="${withval}"], - [COGL_DEFAULT_DRIVER="" ]) - -AM_CONDITIONAL(HAVE_COGL_DEFAULT_DRIVER, - [ test "x$COGL_DEFAULT_DRIVER" != "x" ]) - - -AC_SUBST([COGL_GL_LIBNAME]) -AC_SUBST([HAVE_GL]) -AC_SUBST([COGL_GLES1_LIBNAME]) -AC_SUBST([HAVE_GLES1]) -AC_SUBST([COGL_GLES2_LIBNAME]) -AC_SUBST([HAVE_GLES2]) -AC_SUBST([COGL_DEFAULT_DRIVER]) - -AC_ARG_ENABLE( - [cogl-gles2], - [AC_HELP_STRING([--enable-cogl-gles2=@<:@no/yes@:>@], - [Enable libcogl-gles2 frontend api for OpenGL-ES 2.0 @<:@default=auto@:>@])], - [], - [ - AS_IF([test "x$HAVE_GLES2" = "x1"], - [enable_cogl_gles2=yes], - [enable_cogl_gles2=no]) - ] -) -AS_IF([test "x$enable_cogl_gles2" = "xyes"], - [ - AS_IF([test "x$HAVE_GLES2" != "x1"], - [ - AC_MSG_ERROR([libcogl-gles2 is currently only supported on systems with a native GLES 2.0 library]) - ]) - ]) -AM_CONDITIONAL([BUILD_COGL_GLES2], [test "x$enable_cogl_gles2" = "xyes"]) - - -dnl ======================================================== -dnl Check window system integration libraries... -dnl ======================================================== - -AC_ARG_ENABLE( - [glx], - [AC_HELP_STRING([--enable-glx=@<:@no/yes@:>@], [Enable support GLX @<:@default=auto@:>@])], - [], - [AS_IF([test "x$ALLOW_GLX" = "xyes"], [enable_glx=yes], [enable_glx=no])] -) -AS_IF([test "x$enable_glx" = "xyes"], - [ - AS_IF([test "x$ALLOW_GLX" != "xyes"], - [AC_MSG_ERROR([GLX not supported with this configuration])]) - - NEED_XLIB=yes - SUPPORT_GLX=yes - GL_WINSYS_APIS="$GL_WINSYS_APIS glx" - - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_GLX_SUPPORT" - ]) -AM_CONDITIONAL(SUPPORT_GLX, [test "x$SUPPORT_GLX" = "xyes"]) - -EGL_PLATFORM_COUNT=0 - -AC_ARG_ENABLE( - [kms-egl-platform], - [AC_HELP_STRING([--enable-kms-egl-platform=@<:@no/yes@:>@], [Enable support for the KMS egl platform @<:@default=no@:>@])], - [], - enable_kms_egl_platform=no -) -AS_IF([test "x$enable_kms_egl_platform" = "xyes"], - [ - EGL_PLATFORM_COUNT=$((EGL_PLATFORM_COUNT+1)) - NEED_EGL=yes - EGL_PLATFORMS="$EGL_PLATFORMS kms" - - PKG_CHECK_EXISTS([gbm], - [ - COGL_PKG_REQUIRES="$COGL_PKG_REQUIRES gbm" - COGL_PKG_REQUIRES="$COGL_PKG_REQUIRES libdrm" - ], - [AC_MSG_ERROR([Unable to locate required libgbm library for the KMS egl platform])]) - - GBM_VERSION=`$PKG_CONFIG --modversion gbm` - GBM_MAJOR=`echo $GBM_VERSION | cut -d'.' -f1` - GBM_MINOR=`echo $GBM_VERSION | cut -d'.' -f2` - GBM_MICRO=`echo $GBM_VERSION | cut -d'.' -f3 | sed 's/-.*//'` - - AC_DEFINE_UNQUOTED([COGL_GBM_MAJOR], [$GBM_MAJOR], [The major version for libgbm]) - AC_DEFINE_UNQUOTED([COGL_GBM_MINOR], [$GBM_MINOR], [The minor version for libgbm]) - AC_DEFINE_UNQUOTED([COGL_GBM_MICRO], [$GBM_MICRO], [The micro version for libgbm]) - - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_EGL_PLATFORM_KMS_SUPPORT" - ]) -AM_CONDITIONAL(SUPPORT_EGL_PLATFORM_KMS, - [test "x$enable_kms_egl_platform" = "xyes"]) - -AC_ARG_ENABLE( - [wayland-egl-server], - [AC_HELP_STRING([--enable-wayland-egl-server=@<:@no/yes@:>@], [Enable server side wayland support @<:@default=no@:>@])], - [], - enable_wayland_egl_server=no -) -AS_IF([test "x$enable_wayland_egl_server" = "xyes"], - [ - NEED_EGL=yes - - PKG_CHECK_MODULES(WAYLAND_SERVER, - [wayland-server >= wayland_server_req_version]) - COGL_PKG_REQUIRES="$COGL_PKG_REQUIRES wayland-server >= wayland_server_req_version" - - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT" - ]) -AM_CONDITIONAL(SUPPORT_WAYLAND_EGL_SERVER, - [test "x$enable_wayland_egl_server" = "xyes"]) - -dnl This should go last, since it's the default fallback and we need -dnl to check the value of $EGL_PLATFORM_COUNT here. -AC_ARG_ENABLE( - [xlib-egl-platform], - [AC_HELP_STRING([--enable-xlib-egl-platform=@<:@no/yes@:>@], [Enable support for the Xlib egl platform @<:@default=auto@:>@])], - [], - enable_xlib_egl_platform=yes -) -AS_IF([test "x$enable_xlib_egl_platform" = "xyes"], - [ - EGL_PLATFORM_COUNT=$((EGL_PLATFORM_COUNT+1)) - NEED_EGL=yes - NEED_XLIB=yes - EGL_PLATFORMS="$EGL_PLATFORMS xlib" - - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_EGL_PLATFORM_XLIB_SUPPORT" - ]) -AM_CONDITIONAL(SUPPORT_EGL_PLATFORM_XLIB, - [test "x$enable_xlib_egl_platform" = "xyes"]) - -AS_IF([test "x$NEED_EGL" = "xyes" && test "x$EGL_CHECKED" != "xyes"], - [ - PKG_CHECK_EXISTS([egl], - [COGL_PKG_REQUIRES="$COGL_PKG_REQUIRES egl"], - [ - AC_CHECK_HEADERS( - [EGL/egl.h], - [], - [AC_MSG_ERROR([Unable to locate required EGL headers])]) - AC_CHECK_HEADERS( - [EGL/eglext.h], - [], - [AC_MSG_ERROR([Unable to locate required EGL headers])], - [#include ]) - - AC_CHECK_LIB(EGL, [eglInitialize], - [COGL_EXTRA_LDFLAGS="$COGL_EXTRA_LDFLAGS -lEGL"], - [AC_MSG_ERROR([Unable to locate required EGL library])]) - - COGL_EXTRA_LDFLAGS="$COGL_EXTRA_LDFLAGS -lEGL" - ] - ) - - COGL_EGL_INCLUDES="#include -#include " - AC_SUBST([COGL_EGL_INCLUDES]) - ]) - -AS_IF([test "x$NEED_EGL" = "xyes"], - [ - SUPPORT_EGL=yes - GL_WINSYS_APIS="$GL_WINSYS_APIS egl" - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_EGL_SUPPORT" - ]) - -AM_CONDITIONAL(SUPPORT_EGL, [test "x$SUPPORT_EGL" = "xyes"]) - -dnl ======================================================== -dnl Check X11 dependencies if required -dnl ======================================================== -AS_IF([test "x$NEED_XLIB" = "xyes"], - [ - X11_MODULES="x11 xext xfixes >= xfixes_req_version xdamage xcomposite >= xcomposite_req_version xrandr >= xrandr_req_version" - PKG_CHECK_MODULES(DUMMY, [$X11_MODULES], - [COGL_PKG_REQUIRES="$COGL_PKG_REQUIRES $X11_MODULES"]) - SUPPORT_X11=yes - SUPPORT_XLIB=yes - - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_X11" - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_X11_SUPPORT" - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_XLIB" - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_XLIB_SUPPORT" - ]) - -AM_CONDITIONAL(X11_TESTS, [test "x$SUPPORT_X11" = "xyes"]) -AM_CONDITIONAL(SUPPORT_X11, [test "x$SUPPORT_X11" = "xyes"]) -AM_CONDITIONAL(SUPPORT_XLIB, [test "x$SUPPORT_XLIB" = "xyes"]) - -dnl ================================================================ -dnl Documentation stuff. -dnl ================================================================ -GLIB_PREFIX="`$PKG_CONFIG --variable=prefix glib-2.0`" -GDKPIXBUF_PREFIX="`$PKG_CONFIG --variable=prefix gdk-pixbuf-2.0`" -AC_SUBST(GLIB_PREFIX) -AC_SUBST(GDKPIXBUF_PREFIX) - - -AC_SUBST(COGL_PKG_REQUIRES) -if test -n "$COGL_PKG_REQUIRES"; then - PKG_CHECK_MODULES(COGL_DEP, [$COGL_PKG_REQUIRES]) - - if test -n "$COGL_PKG_REQUIRES_GL"; then - PKG_CHECK_MODULES(COGL_DEP_GL, [$COGL_PKG_REQUIRES_GL]) - - dnl Strip out the GL libraries from the GL pkg-config files so we can - dnl dynamically load them instead - gl_libs="" - for x in $COGL_DEP_GL_LIBS; do - AS_CASE([$x], - [-lGL], [], - [-lGLESv2], [], - [-lGLESv1_CM], [], - [*], [gl_libs="$gl_libs $x"]) - done - COGL_DEP_CFLAGS="$COGL_DEP_CFLAGS $COGL_DEP_CFLAGS_GL" - COGL_DEP_LIBS="$COGL_DEP_LIBS $gl_libs" - fi -fi -AC_SUBST(COGL_PANGO_PKG_REQUIRES) - -AS_IF([test "x$enable_cogl_pango" = "xyes"], - [PKG_CHECK_MODULES(COGL_PANGO_DEP, [$COGL_PANGO_PKG_REQUIRES])] -) -AM_CONDITIONAL([BUILD_COGL_PANGO], [test "x$enable_cogl_pango" = "xyes"]) - -AM_CONDITIONAL([BUILD_COGL_PATH], [test "x$enable_cogl_path" = "xyes"]) - -dnl ================================================================ -dnl Misc program dependencies. -dnl ================================================================ -AC_PROG_INSTALL - -dnl ================================================================ -dnl GObject-Introspection check -dnl ================================================================ -GOBJECT_INTROSPECTION_CHECK([gi_req_version]) - -dnl ================================================================ -dnl Checks for header files. -dnl ================================================================ -AC_PATH_X -AC_HEADER_STDC -AC_CHECK_HEADERS(fcntl.h limits.h unistd.h) -AC_CHECK_HEADER([endian.h], - [AC_CHECK_DECL([__FLOAT_WORD_ORDER], - AC_DEFINE([HAVE_FLOAT_WORD_ORDER], [1], - [Has the __FLOAT_WORD_ORDER macro]))]) - -dnl ================================================================ -dnl Checks for library functions. -dnl ================================================================ - -dnl The 'ffs' function is part of C99 so it isn't always -dnl available. Cogl has a fallback if needed. -AC_CHECK_FUNCS([ffs]) - -dnl 'memmem' is a GNU extension but we have a simple fallback -AC_CHECK_FUNCS([memmem]) - -dnl This is used in the cogl-gles2-gears example but it is a GNU extension -save_libs="$LIBS" -LIBS="$LIBS $LIBM" -AC_CHECK_FUNCS([sincos]) -LIBS="$save_libs" - -dnl ================================================================ -dnl Platform values -dnl ================================================================ - -dnl These are values from system headers that we want to copy into the -dnl public Cogl headers without having to include the system header -have_poll_h=no -AC_CHECK_HEADER(poll.h, - [ - AC_COMPUTE_INT(COGL_SYSDEF_POLLIN, POLLIN, [#include ], - AC_MSG_ERROR([Unable to get value of POLLIN])) - AC_COMPUTE_INT(COGL_SYSDEF_POLLPRI, POLLPRI, [#include ], - AC_MSG_ERROR([Unable to get value of POLLPRI])) - AC_COMPUTE_INT(COGL_SYSDEF_POLLOUT, POLLOUT, [#include ], - AC_MSG_ERROR([Unable to get value of POLLOUT])) - AC_COMPUTE_INT(COGL_SYSDEF_POLLERR, POLLERR, [#include ], - AC_MSG_ERROR([Unable to get value of POLLERR])) - AC_COMPUTE_INT(COGL_SYSDEF_POLLHUP, POLLHUP, [#include ], - AC_MSG_ERROR([Unable to get value of POLLHUP])) - AC_COMPUTE_INT(COGL_SYSDEF_POLLNVAL, POLLNVAL, [#include ], - AC_MSG_ERROR([Unable to get value of POLLNVAL])) - COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_POLL_SUPPORT" - have_poll_h=yes - ]) - -AS_IF([test "x$have_poll_h" = "xno"], - [ - COGL_SYSDEF_POLLIN=1 - COGL_SYSDEF_POLLPRI=2 - COGL_SYSDEF_POLLOUT=4 - COGL_SYSDEF_POLLERR=8 - COGL_SYSDEF_POLLHUP=16 - COGL_SYSDEF_POLLNVAL=32 - ]) - -COGL_DEFINES_EXTRA="$COGL_DEFINES_EXTRA -#define COGL_SYSDEF_POLLIN $COGL_SYSDEF_POLLIN -#define COGL_SYSDEF_POLLPRI $COGL_SYSDEF_POLLPRI -#define COGL_SYSDEF_POLLOUT $COGL_SYSDEF_POLLOUT -#define COGL_SYSDEF_POLLERR $COGL_SYSDEF_POLLERR -#define COGL_SYSDEF_POLLHUP $COGL_SYSDEF_POLLHUP -#define COGL_SYSDEF_POLLNVAL $COGL_SYSDEF_POLLNVAL -" - -dnl ================================================================ -dnl What needs to be substituted in other files -dnl ================================================================ -COGL_DEFINES="$COGL_DEFINES_EXTRA" -for x in $COGL_DEFINES_SYMBOLS; do - COGL_DEFINES="$COGL_DEFINES -#define $x 1" -done; -AC_SUBST(COGL_DEFINES) -AM_SUBST_NOTMAKE(COGL_DEFINES) - -AS_IF([test "x$cogl_gl_headers" = "x"], - [AC_MSG_ERROR([Internal error: no GL header set])]) -dnl cogl_gl_headers is a space separate list of headers to -dnl include. We'll now convert them to a single variable with a -dnl #include line for each header -COGL_GL_HEADER_INCLUDES="" -for x in $cogl_gl_headers; do - COGL_GL_HEADER_INCLUDES="$COGL_GL_HEADER_INCLUDES -#include <$x>" -done; -AC_SUBST(COGL_GL_HEADER_INCLUDES) -AM_SUBST_NOTMAKE(COGL_GL_HEADER_INCLUDES) - -AC_SUBST(COGL_DEP_CFLAGS) -AC_SUBST(COGL_DEP_LIBS) -AC_SUBST(COGL_PANGO_DEP_CFLAGS) -AC_SUBST(COGL_PANGO_DEP_LIBS) -AC_SUBST(COGL_GST_DEP_CFLAGS) -AC_SUBST(COGL_GST_DEP_LIBS) -AC_SUBST(COGL_EXTRA_CFLAGS) -AC_SUBST(COGL_EXTRA_LDFLAGS) - -# just for compatability with the clutter build... -MAINTAINER_CFLAGS= -AC_SUBST(MAINTAINER_CFLAGS) - -AC_OUTPUT( -Makefile -test-fixtures/Makefile -cogl/Makefile -cogl/muffin-cogl-$MUFFIN_PLUGIN_API_VERSION.pc:cogl/muffin-cogl.pc.in -cogl/cogl-defines.h -cogl/cogl-gl-header.h -cogl/cogl-egl-defines.h -cogl-pango/Makefile -cogl-pango/muffin-cogl-pango-$MUFFIN_PLUGIN_API_VERSION.pc:cogl-pango/muffin-cogl-pango.pc.in -cogl-path/Makefile -cogl-path/muffin-cogl-path-$MUFFIN_PLUGIN_API_VERSION.pc:cogl-path/muffin-cogl-path.pc.in -cogl-gles2/Makefile -cogl-gles2/muffin-cogl-gles2-$MUFFIN_PLUGIN_API_VERSION.pc:cogl-gles2/muffin-cogl-gles2.pc.in -tests/Makefile -tests/config.env -tests/conform/Makefile -tests/unit/Makefile -tests/micro-perf/Makefile -tests/data/Makefile -) - -dnl ================================================================ -dnl Dah Da! -dnl ================================================================ -echo "" -echo "Cogl - $COGL_1_VERSION/$COGL_VERSION (${COGL_RELEASE_STATUS})" - -# Global flags -echo "" -echo " • Global:" -echo " Prefix: ${prefix}" -if test "x$COGL_DEFAULT_DRIVER" != "x"; then -echo " Default driver: ${COGL_DEFAULT_DRIVER}" -fi - -echo "" -# Features -echo " • Features:" -echo " Drivers: ${enabled_drivers}" -for driver in $enabled_drivers; do - driver=`echo $driver | tr "[gles]" "[GLES]"` - libname=`eval echo \\$COGL_${driver}_LIBNAME` - echo " Library name for $driver: $libname" -done -echo " GL Window System APIs:${GL_WINSYS_APIS}" -if test "x$SUPPORT_EGL" = "xyes"; then -echo " EGL Platforms:${EGL_PLATFORMS}" -echo " Wayland compositor support: ${enable_wayland_egl_server}" -fi -echo " Build libcogl-gles2 GLES 2.0 frontend api: ${enable_cogl_gles2}" -echo " Image backend: ${COGL_IMAGE_BACKEND}" -echo " Cogl Pango: ${enable_cogl_pango}" -echo " Cogl Path: ${enable_cogl_path}" - -# Compiler/Debug related flags -echo "" -echo " • Build options:" -echo " Debugging: ${enable_debug}" -echo " Profiling: ${enable_profile}" -echo " Enable deprecated symbols: ${enable_deprecated}" -echo " Compiler flags: ${CFLAGS} ${COGL_EXTRA_CFLAGS}" -echo " Linker flags: ${LDFLAGS} ${COGL_EXTRA_LDFLAGS}" - -# Miscellaneous -echo "" -echo " • Extra:" -echo " Build introspection data: ${enable_introspection}" -echo " Build unit tests: ${enable_unit_tests}" - -echo "" diff --git a/cogl/meson.build b/cogl/meson.build new file mode 100644 index 000000000..3d4c2d3c3 --- /dev/null +++ b/cogl/meson.build @@ -0,0 +1,127 @@ +cogl_includesubdir = join_paths(pkgname, 'cogl') +cogl_includedir = join_paths(includedir, cogl_includesubdir) +cogl_srcdir = meson.current_source_dir() + +cogl_includepath = include_directories('.', 'cogl') + +cdata = configuration_data() +cdata.set('HAVE_COGL_GL', have_gl) +cdata.set('HAVE_COGL_GLES2', have_gles2) +cdata.set('HAVE_TRACING', have_profiler) +cdata.set('ENABLE_UNIT_TESTS', have_cogl_tests) + +if default_driver != 'auto' + cdata.set_quoted('COGL_DEFAULT_DRIVER', default_driver) +endif + +cogl_config_h = configure_file( + input: 'cogl-config.h.meson', + output: 'cogl-config.h', + configuration: cdata) + +cogl_pkg_deps = [ + glib_dep, + gobject_dep, + graphene_dep, +] + +cogl_pkg_private_deps = [ + cairo_dep, + gmodule_no_export_dep, + gdk_pixbuf_dep, + #uprof_dep, +] + +if have_profiler + cogl_pkg_private_deps += [ + sysprof_dep, + ] +endif + +if have_wayland + cogl_pkg_deps += [ + wayland_server_dep, + ] +endif + +if have_egl + cogl_pkg_deps += [ + egl_dep, + ] +endif + +if have_x11 + cogl_pkg_deps += [ + x11_dep, + ] + cogl_pkg_private_deps += [ + xext_dep, + xfixes_dep, + xdamage_dep, + xcomposite_dep, + xrandr_dep, + ] +endif + +if have_gl + cogl_pkg_deps += [ + gl_dep, + ] +endif + +if have_gles2 + cogl_pkg_deps += [ + gles2_dep, + ] +endif + +cogl_deps = [ + cogl_pkg_deps, + cogl_pkg_private_deps, + m_dep, +] + +cogl_c_args = [ + '-DCOGL_LOCALEDIR="@0@"'.format(localedir), + '-DCOGL_COMPILATION', +] + +if have_gl + cogl_c_args += [ + '-DCOGL_GL_LIBNAME="@0@"'.format(gl_libname) + ] +endif + +if have_gles2 + cogl_c_args += [ + '-DCOGL_GLES2_LIBNAME="@0@"'.format(gles2_libname) + ] +endif + +cogl_debug_c_args = [] +buildtype = get_option('buildtype') +if get_option('debug') + cogl_debug_c_args += [ + '-DCOGL_GL_DEBUG', + '-DCOGL_OBJECT_DEBUG', + '-DCOGL_ENABLE_DEBUG', + '-fno-omit-frame-pointer' + ] +elif buildtype != 'plain' + cogl_debug_c_args += [ + '-DG_DISABLE_CHECKS', + '-DG_DISABLE_CAST_CHECKS' + ] +endif +supported_cogl_debug_c_args = cc.get_supported_arguments(cogl_debug_c_args) +cogl_c_args += cogl_debug_c_args + +if have_cogl_tests + subdir('test-fixtures') +endif +subdir('cogl') +subdir('cogl-path') +subdir('cogl-pango') +if have_cogl_tests + subdir('tests') +endif diff --git a/cogl/test-fixtures/Makefile.am b/cogl/test-fixtures/Makefile.am deleted file mode 100644 index a5d312e54..000000000 --- a/cogl/test-fixtures/Makefile.am +++ /dev/null @@ -1,21 +0,0 @@ - -noinst_LTLIBRARIES = libtest-fixtures.la - -libtest_fixtures_la_CPPFLAGS = \ - -I$(top_srcdir) \ - -I$(top_builddir)/cogl \ - -Wall \ - $(NULL) - -libtest_fixtures_la_CPPFLAGS += \ - -DCOGL_DISABLE_DEPRECATED \ - -DTESTS_DATADIR=\""$(top_srcdir)/tests/data"\" \ - -DCOGL_COMPILATION - -libtest_fixtures_la_CFLAGS = -g3 -O0 $(COGL_DEP_CFLAGS) $(COGL_EXTRA_CFLAGS) -Wno-error=maybe-uninitialized -Wno-error=nested-externs -Wno-error=missing-prototypes - -libtest_fixtures_la_SOURCES = \ - test-unit.h \ - test-utils.h \ - test-utils.c - diff --git a/cogl/test-fixtures/meson.build b/cogl/test-fixtures/meson.build new file mode 100644 index 000000000..d4bb2f911 --- /dev/null +++ b/cogl/test-fixtures/meson.build @@ -0,0 +1,22 @@ +cogl_test_fixtures_includepath = [include_directories('.')] + +cogl_test_fixtures_sources = [ + 'test-unit.h', + 'test-utils.h', + 'test-utils.c', +] + +test_datadir = join_paths(cogl_srcdir, 'tests', 'data') + +libmutter_cogl_test_fixtures = static_library('mutter-cogl-test-fixtures', + sources: cogl_test_fixtures_sources, + c_args: [cogl_c_args, '-DTEST_DATADIR=@0@'.format(test_datadir)], + link_args: ['-Wl,--no-undefined', '-Wl,--unresolved-symbols=ignore-in-object-files'], + include_directories: cogl_includepath, + dependencies: [cogl_deps], + install: false, +) + +libmutter_cogl_test_fixtures_dep = declare_dependency( + link_with: libmutter_cogl_test_fixtures +) diff --git a/cogl/test-fixtures/test-unit.h b/cogl/test-fixtures/test-unit.h index 270a94134..c96587f95 100644 --- a/cogl/test-fixtures/test-unit.h +++ b/cogl/test-fixtures/test-unit.h @@ -16,6 +16,8 @@ typedef struct _CoglUnitTest #define UNIT_TEST(NAME, REQUIREMENT_FLAGS, KNOWN_FAILURE_FLAGS) \ static void NAME (void); \ \ + COGL_EXPORT \ + const CoglUnitTest unit_test_##NAME; \ const CoglUnitTest unit_test_##NAME = \ { #NAME, REQUIREMENT_FLAGS, KNOWN_FAILURE_FLAGS, NAME }; \ \ diff --git a/cogl/test-fixtures/test-utils.c b/cogl/test-fixtures/test-utils.c index c61a42783..6834f9fac 100644 --- a/cogl/test-fixtures/test-utils.c +++ b/cogl/test-fixtures/test-utils.c @@ -8,12 +8,12 @@ #define FB_WIDTH 512 #define FB_HEIGHT 512 -static CoglBool cogl_test_is_verbose; +static gboolean cogl_test_is_verbose; CoglContext *test_ctx; CoglFramebuffer *test_fb; -static CoglBool +static gboolean check_flags (TestFlags flags, CoglRenderer *renderer) { @@ -24,66 +24,18 @@ check_flags (TestFlags flags, return FALSE; } - if (flags & TEST_REQUIREMENT_NPOT && - !cogl_has_feature (test_ctx, COGL_FEATURE_ID_TEXTURE_NPOT)) - { - return FALSE; - } - - if (flags & TEST_REQUIREMENT_TEXTURE_3D && - !cogl_has_feature (test_ctx, COGL_FEATURE_ID_TEXTURE_3D)) - { - return FALSE; - } - - if (flags & TEST_REQUIREMENT_TEXTURE_RECTANGLE && - !cogl_has_feature (test_ctx, COGL_FEATURE_ID_TEXTURE_RECTANGLE)) - { - return FALSE; - } - if (flags & TEST_REQUIREMENT_TEXTURE_RG && !cogl_has_feature (test_ctx, COGL_FEATURE_ID_TEXTURE_RG)) { return FALSE; } - if (flags & TEST_REQUIREMENT_POINT_SPRITE && - !cogl_has_feature (test_ctx, COGL_FEATURE_ID_POINT_SPRITE)) - { - return FALSE; - } - - if (flags & TEST_REQUIREMENT_PER_VERTEX_POINT_SIZE && - !cogl_has_feature (test_ctx, COGL_FEATURE_ID_PER_VERTEX_POINT_SIZE)) - { - return FALSE; - } - - if (flags & TEST_REQUIREMENT_GLES2_CONTEXT && - !cogl_has_feature (test_ctx, COGL_FEATURE_ID_GLES2_CONTEXT)) - { - return FALSE; - } - if (flags & TEST_REQUIREMENT_MAP_WRITE && !cogl_has_feature (test_ctx, COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE)) { return FALSE; } - if (flags & TEST_REQUIREMENT_GLSL && - !cogl_has_feature (test_ctx, COGL_FEATURE_ID_GLSL)) - { - return FALSE; - } - - if (flags & TEST_REQUIREMENT_OFFSCREEN && - !cogl_has_feature (test_ctx, COGL_FEATURE_ID_OFFSCREEN)) - { - return FALSE; - } - if (flags & TEST_REQUIREMENT_FENCE && !cogl_has_feature (test_ctx, COGL_FEATURE_ID_FENCE)) { @@ -98,11 +50,11 @@ check_flags (TestFlags flags, return TRUE; } -CoglBool +static gboolean is_boolean_env_set (const char *variable) { char *val = getenv (variable); - CoglBool ret; + gboolean ret; if (!val) return FALSE; @@ -130,12 +82,12 @@ test_utils_init (TestFlags requirement_flags, TestFlags known_failure_flags) { static int counter = 0; - CoglError *error = NULL; + GError *error = NULL; CoglOnscreen *onscreen = NULL; CoglDisplay *display; CoglRenderer *renderer; - CoglBool missing_requirement; - CoglBool known_failure; + gboolean missing_requirement; + gboolean known_failure; if (counter != 0) g_critical ("We don't support running more than one test at a time\n" @@ -157,7 +109,7 @@ test_utils_init (TestFlags requirement_flags, { char *debug = g_strconcat (g_getenv ("G_DEBUG"), ",fatal-warnings", NULL); g_setenv ("G_DEBUG", debug, TRUE); - free (debug); + g_free (debug); } else g_setenv ("G_DEBUG", "fatal-warnings", TRUE); @@ -216,7 +168,7 @@ test_utils_fini (void) cogl_object_unref (test_ctx); } -static CoglBool +static gboolean compare_component (int a, int b) { return ABS (a - b) <= 1; @@ -240,8 +192,8 @@ test_utils_compare_pixel_and_alpha (const uint8_t *screen_pixel, g_assert_cmpstr (screen_pixel_string, ==, expected_pixel_string); - free (screen_pixel_string); - free (expected_pixel_string); + g_free (screen_pixel_string); + g_free (expected_pixel_string); } } @@ -261,8 +213,8 @@ test_utils_compare_pixel (const uint8_t *screen_pixel, uint32_t expected_pixel) g_assert_cmpstr (screen_pixel_string, ==, expected_pixel_string); - free (screen_pixel_string); - free (expected_pixel_string); + g_free (screen_pixel_string); + g_free (expected_pixel_string); } } @@ -309,7 +261,7 @@ test_utils_check_region (CoglFramebuffer *test_fb, { uint8_t *pixels, *p; - pixels = p = malloc (width * height * 4); + pixels = p = g_malloc (width * height * 4); cogl_framebuffer_read_pixels (test_fb, x, y, @@ -326,7 +278,7 @@ test_utils_check_region (CoglFramebuffer *test_fb, p += 4; } - free (pixels); + g_free (pixels); } CoglTexture * @@ -347,7 +299,7 @@ test_utils_create_color_texture (CoglContext *context, return COGL_TEXTURE (tex_2d); } -CoglBool +gboolean cogl_test_verbose (void) { return cogl_test_is_verbose; @@ -371,27 +323,19 @@ test_utils_texture_new_with_size (CoglContext *ctx, CoglTextureComponents components) { CoglTexture *tex; - CoglError *skip_error = NULL; + GError *skip_error = NULL; - if ((test_utils_is_pot (width) && test_utils_is_pot (height)) || - (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_BASIC) && - cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP))) - { - /* First try creating a fast-path non-sliced texture */ - tex = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx, - width, height)); + /* First try creating a fast-path non-sliced texture */ + tex = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx, width, height)); - cogl_texture_set_components (tex, components); + cogl_texture_set_components (tex, components); - if (!cogl_texture_allocate (tex, &skip_error)) - { - cogl_error_free (skip_error); - cogl_object_unref (tex); - tex = NULL; - } + if (!cogl_texture_allocate (tex, &skip_error)) + { + g_error_free (skip_error); + cogl_object_unref (tex); + tex = NULL; } - else - tex = NULL; if (!tex) { @@ -430,11 +374,11 @@ test_utils_texture_new_with_size (CoglContext *ctx, CoglTexture * test_utils_texture_new_from_bitmap (CoglBitmap *bitmap, TestUtilsTextureFlags flags, - CoglBool premultiplied) + gboolean premultiplied) { CoglAtlasTexture *atlas_tex; CoglTexture *tex; - CoglError *internal_error = NULL; + GError *internal_error = NULL; if (!flags) { @@ -446,37 +390,25 @@ test_utils_texture_new_from_bitmap (CoglBitmap *bitmap, if (cogl_texture_allocate (COGL_TEXTURE (atlas_tex), &internal_error)) return COGL_TEXTURE (atlas_tex); - cogl_error_free (internal_error); cogl_object_unref (atlas_tex); - internal_error = NULL; } + g_clear_error (&internal_error); + /* If that doesn't work try a fast path 2D texture */ - if ((test_utils_is_pot (cogl_bitmap_get_width (bitmap)) && - test_utils_is_pot (cogl_bitmap_get_height (bitmap))) || - (cogl_has_feature (test_ctx, COGL_FEATURE_ID_TEXTURE_NPOT_BASIC) && - cogl_has_feature (test_ctx, COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP))) - { - tex = COGL_TEXTURE (cogl_texture_2d_new_from_bitmap (bitmap)); + tex = COGL_TEXTURE (cogl_texture_2d_new_from_bitmap (bitmap)); - cogl_texture_set_premultiplied (tex, premultiplied); + cogl_texture_set_premultiplied (tex, premultiplied); - if (cogl_error_matches (internal_error, - COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_NO_MEMORY)) - { - g_assert_not_reached (); - return NULL; - } - - if (!tex) - { - cogl_error_free (internal_error); - internal_error = NULL; - } + if (g_error_matches (internal_error, + COGL_SYSTEM_ERROR, + COGL_SYSTEM_ERROR_NO_MEMORY)) + { + g_assert_not_reached (); + return NULL; } - else - tex = NULL; + + g_clear_error (&internal_error); if (!tex) { diff --git a/cogl/test-fixtures/test-utils.h b/cogl/test-fixtures/test-utils.h index 9c3ced9b3..fe76a53e3 100644 --- a/cogl/test-fixtures/test-utils.h +++ b/cogl/test-fixtures/test-utils.h @@ -33,11 +33,9 @@ typedef enum _TestFlags TEST_KNOWN_FAILURE = 1<<0, TEST_REQUIREMENT_GL = 1<<1, TEST_REQUIREMENT_NPOT = 1<<2, - TEST_REQUIREMENT_TEXTURE_3D = 1<<3, TEST_REQUIREMENT_TEXTURE_RECTANGLE = 1<<4, TEST_REQUIREMENT_TEXTURE_RG = 1<<5, TEST_REQUIREMENT_POINT_SPRITE = 1<<6, - TEST_REQUIREMENT_GLES2_CONTEXT = 1<<7, TEST_REQUIREMENT_MAP_WRITE = 1<<8, TEST_REQUIREMENT_GLSL = 1<<9, TEST_REQUIREMENT_OFFSCREEN = 1<<10, @@ -59,7 +57,8 @@ typedef enum _TestFlags * * Flags to pass to the test_utils_texture_new_* family of functions. */ -typedef enum { +typedef enum +{ TEST_UTILS_TEXTURE_NONE = 0, TEST_UTILS_TEXTURE_NO_AUTO_MIPMAP = 1 << 0, TEST_UTILS_TEXTURE_NO_SLICING = 1 << 1, @@ -112,7 +111,7 @@ test_utils_texture_new_with_size (CoglContext *ctx, * @rowstride: the memory offset in bytes between the starts of * scanlines in @data * @data: pointer the memory region where the source buffer resides - * @error: A #CoglError to catch exceptional errors or %NULL + * @error: A #GError to catch exceptional errors or %NULL * * Creates a new #CoglTexture based on data residing in memory. * @@ -152,7 +151,7 @@ test_utils_texture_new_from_data (CoglContext *ctx, CoglTexture * test_utils_texture_new_from_bitmap (CoglBitmap *bitmap, TestUtilsTextureFlags flags, - CoglBool premultiplied); + gboolean premultiplied); /* * test_utils_check_pixel: @@ -269,7 +268,7 @@ test_utils_create_color_texture (CoglContext *context, * * Queries if the user asked for verbose output or not. */ -CoglBool +gboolean cogl_test_verbose (void); /* test_util_is_pot: @@ -277,7 +276,7 @@ cogl_test_verbose (void); * * Returns whether the given integer is a power of two */ -static inline CoglBool +static inline gboolean test_utils_is_pot (unsigned int number) { /* Make sure there is only one bit set */ diff --git a/cogl/tests/Makefile.am b/cogl/tests/Makefile.am deleted file mode 100644 index f5d50f56b..000000000 --- a/cogl/tests/Makefile.am +++ /dev/null @@ -1,31 +0,0 @@ -SUBDIRS = conform - -if UNIT_TESTS -SUBDIRS += unit -endif - -SUBDIRS += micro-perf data - -DIST_SUBDIRS = conform unit micro-perf data - -EXTRA_DIST = README test-launcher.sh run-tests.sh - -if UNIT_TESTS -test conform: - ( cd ./conform && $(MAKE) $(AM_MAKEFLAGS) $@ ) || exit $$? - ( cd ./unit && $(MAKE) $(AM_MAKEFLAGS) $@ ) || exit $$? -else -test conform: - ( cd ./conform && $(MAKE) $(AM_MAKEFLAGS) $@ ) || exit $$? -endif - -.PHONY: test conform - -# run make test as part of make check -check-local: test - -if ENABLE_INSTALLED_TESTS -insttestdir = $(libexecdir)/installed-tests/muffin-cogl -insttest_SCRIPTS = run-tests.sh -insttest_DATA = config.env -endif diff --git a/cogl/tests/config.env.in b/cogl/tests/config.env.in index d3777565d..341dd35cf 100644 --- a/cogl/tests/config.env.in +++ b/cogl/tests/config.env.in @@ -1,3 +1,2 @@ HAVE_GL=@HAVE_GL@ -HAVE_GLES1=@HAVE_GLES1@ HAVE_GLES2=@HAVE_GLES2@ diff --git a/cogl/tests/conform/Makefile.am b/cogl/tests/conform/Makefile.am deleted file mode 100644 index 04be38266..000000000 --- a/cogl/tests/conform/Makefile.am +++ /dev/null @@ -1,177 +0,0 @@ -NULL = - -noinst_PROGRAMS = test-conformance - -common_sources = \ - test-conform-main.c \ - $(NULL) - -unported_test_sources = \ - test-fixed.c \ - test-materials.c \ - test-viewport.c \ - test-multitexture.c \ - test-npot-texture.c \ - test-object.c \ - test-readpixels.c \ - test-texture-mipmaps.c \ - test-texture-pixmap-x11.c \ - test-texture-rectangle.c \ - test-vertex-buffer-contiguous.c \ - test-vertex-buffer-interleved.c \ - test-vertex-buffer-mutability.c \ - $(NULL) - -test_sources = \ - test-atlas-migration.c \ - test-blend-strings.c \ - test-blend.c \ - test-depth-test.c \ - test-color-hsl.c \ - test-color-mask.c \ - test-backface-culling.c \ - test-just-vertex-shader.c \ - test-pipeline-user-matrix.c \ - test-pipeline-uniforms.c \ - test-pixel-buffer.c \ - test-premult.c \ - test-snippets.c \ - test-wrap-modes.c \ - test-sub-texture.c \ - test-custom-attributes.c \ - test-offscreen.c \ - test-primitive.c \ - test-texture-3d.c \ - test-sparse-pipeline.c \ - test-read-texture-formats.c \ - test-write-texture-formats.c \ - test-point-size.c \ - test-point-size-attribute.c \ - test-point-sprite.c \ - test-no-gl-header.c \ - test-version.c \ - test-gles2-context.c \ - test-euler-quaternion.c \ - test-layer-remove.c \ - test-alpha-test.c \ - test-map-buffer-range.c \ - test-npot-texture.c \ - test-alpha-textures.c \ - test-wrap-rectangle-textures.c \ - test-texture-get-set-data.c \ - test-framebuffer-get-bits.c \ - test-primitive-and-journal.c \ - test-copy-replace-texture.c \ - test-pipeline-cache-unrefs-texture.c \ - test-texture-no-allocate.c \ - test-pipeline-shader-state.c \ - test-texture-rg.c \ - test-fence.c \ - $(NULL) - -if BUILD_COGL_PATH -test_sources += \ - test-path.c \ - test-path-clip.c -endif - -test_conformance_SOURCES = $(common_sources) $(test_sources) - -SHEXT = $(EXEEXT) - -# For convenience, this provides a way to easily run individual unit tests: -.PHONY: wrappers clean-wrappers - -wrappers: stamp-test-conformance - @true -stamp-test-conformance: Makefile $(srcdir)/test-conform-main.c - @mkdir -p wrappers - @sed -n -e 's/^ \{1,\}ADD_TEST *( *\([a-zA-Z0-9_]\{1,\}\).*/\1/p' $(srcdir)/test-conform-main.c > unit-tests - @chmod +x $(top_srcdir)/tests/test-launcher.sh - @( echo "/stamp-test-conformance" ; \ - echo "/test-conformance$(EXEEXT)" ; \ - echo "*.o" ; \ - echo ".gitignore" ; \ - echo "unit-tests" ; ) > .gitignore - @for i in `cat unit-tests`; \ - do \ - unit=`basename $$i | sed -e s/_/-/g`; \ - echo " GEN $$unit"; \ - ( echo "#!/bin/sh" ; echo "$(top_srcdir)/tests/test-launcher.sh $(abs_builddir)/test-conformance$(EXEEXT) '' '$$i' \"\$$@\"" ) > $$unit$(SHEXT) ; \ - chmod +x $$unit$(SHEXT); \ - echo "/$$unit$(SHEXT)" >> .gitignore; \ - done \ - && echo timestamp > $(@F) - -clean-wrappers: - @for i in `cat unit-tests`; \ - do \ - unit=`basename $$i | sed -e s/_/-/g`; \ - echo " RM $$unit"; \ - rm -f $$unit$(SHEXT) ; \ - done \ - && rm -f unit-tests \ - && rm -f stamp-test-conformance - -# NB: BUILT_SOURCES here a misnomer. We aren't building source, just inserting -# a phony rule that will generate symlink scripts for running individual tests -BUILT_SOURCES = wrappers - -AM_CPPFLAGS = \ - -I$(top_srcdir) \ - -I$(top_builddir)/cogl \ - -I$(top_srcdir)/test-fixtures - -AM_CPPFLAGS += \ - -DCOGL_ENABLE_EXPERIMENTAL_API \ - -DCOGL_DISABLE_DEPRECATED \ - -DCOGL_DISABLE_DEPRECATION_WARNINGS \ - -DTESTS_DATADIR=\""$(top_srcdir)/tests/data"\" - -test_conformance_CFLAGS = -g3 -O0 $(COGL_DEP_CFLAGS) $(COGL_EXTRA_CFLAGS) -Wno-error=maybe-uninitialized -Wno-error=nested-externs -Wno-error=missing-prototypes -test_conformance_LDADD = \ - $(COGL_DEP_LIBS) \ - $(top_builddir)/cogl/libmuffin-cogl-$(MUFFIN_PLUGIN_API_VERSION).la \ - $(LIBM) -if BUILD_COGL_PATH -test_conformance_LDADD += $(top_builddir)/cogl-path/libmuffin-cogl-path-$(MUFFIN_PLUGIN_API_VERSION).la -endif -test_conformance_LDFLAGS = -export-dynamic - -# XXX: uncomment when tests get fixed -#test: wrappers -# @$(top_srcdir)/tests/run-tests.sh $(abs_builddir)/../config.env $(abs_builddir)/test-conformance$(EXEEXT) - -# XXX: we could prevent the conformance test suite from running -# by simply defining this variable conditionally -TEST_PROGS = test-conformance - -.PHONY: test - -DISTCLEANFILES = .gitignore - -# we override the clean-generic target to clean up the wrappers so -# we cannot use CLEANFILES -clean-generic: clean-wrappers - $(QUIET_RM)rm -f .log - - -if ENABLE_INSTALLED_TESTS - -insttestdir = $(libexecdir)/installed-tests/muffin-cogl/conform -insttest_PROGRAMS = test-conformance -insttest_DATA = unit-tests - -testmetadir = $(datadir)/installed-tests/muffin-cogl -testmeta_DATA = conform.test - -conform.test: - echo " GEN $@"; \ - echo "[Test]" > $@.tmp; \ - echo "Type=session" >> $@.tmp; \ - echo "Exec=sh -c \"cd $(libexecdir)/installed-tests/muffin-cogl/conform; ../run-tests.sh ../config.env ./test-conformance\"" >> $@.tmp; \ - mv $@.tmp $@ - -CLEANFILES = conform.test - -endif diff --git a/cogl/tests/conform/meson.build b/cogl/tests/conform/meson.build new file mode 100644 index 000000000..3e1bc1596 --- /dev/null +++ b/cogl/tests/conform/meson.build @@ -0,0 +1,129 @@ +cogl_test_conformance_sources = [ + 'test-conform-main.c', + 'test-atlas-migration.c', + 'test-blend-strings.c', + 'test-blend.c', + 'test-depth-test.c', + 'test-color-hsl.c', + 'test-backface-culling.c', + 'test-just-vertex-shader.c', + 'test-pipeline-user-matrix.c', + 'test-pipeline-uniforms.c', + 'test-pixel-buffer.c', + 'test-premult.c', + 'test-snippets.c', + 'test-wrap-modes.c', + 'test-sub-texture.c', + 'test-custom-attributes.c', + 'test-offscreen.c', + 'test-primitive.c', + 'test-sparse-pipeline.c', + 'test-read-texture-formats.c', + 'test-write-texture-formats.c', + 'test-point-size.c', + 'test-point-size-attribute.c', + 'test-point-sprite.c', + 'test-no-gl-header.c', + 'test-version.c', + 'test-euler.c', + 'test-layer-remove.c', + 'test-alpha-test.c', + 'test-map-buffer-range.c', + 'test-npot-texture.c', + 'test-alpha-textures.c', + 'test-texture-get-set-data.c', + 'test-framebuffer-get-bits.c', + 'test-primitive-and-journal.c', + 'test-copy-replace-texture.c', + 'test-pipeline-cache-unrefs-texture.c', + 'test-texture-no-allocate.c', + 'test-pipeline-shader-state.c', + 'test-texture-rg.c', + 'test-fence.c', + 'test-path.c', + 'test-path-clip.c', +] + +#unported = [ +# "test-viewport.c", +# "test-multitexture.c", +# "test-npot-texture.c", +# "test-object.c", +# "test-readpixels.c", +# "test-texture-mipmaps.c", +# "test-texture-pixmap-x11.c",", +#] + +cogl_test_conformance_includes = [ + cogl_includepath, + cogl_test_fixtures_includepath, +] + +if have_installed_tests + cogl_installed_tests_cdata = configuration_data() + cogl_installed_tests_cdata.set('libexecdir', libexecdir) + cogl_installed_tests_cdata.set('apiversion', libmutter_api_version) + + configure_file( + input: 'mutter-cogl.test.in', + output: 'mutter-cogl.test', + configuration: cogl_installed_tests_cdata, + install: true, + install_dir: mutter_installed_tests_datadir, + ) +endif + +libmutter_cogl_test_conformance = executable('test-conformance', + sources: cogl_test_conformance_sources, + c_args: cogl_debug_c_args + [ + '-DCOGL_ENABLE_EXPERIMENTAL_API', + '-DCOGL_DISABLE_DEPRECATED', + '-DCOGL_DISABLE_DEPRECATION_WARNINGS', + '-DTESTS_DATADIR="@0@/tests/data"'.format(cogl_srcdir), + ], + include_directories: cogl_test_conformance_includes, + dependencies: [ + libmutter_cogl_dep, + libmutter_cogl_path_dep, + libmutter_cogl_test_fixtures_dep, + ], + install: have_installed_tests, + install_dir: cogl_installed_tests_libexecdir, + install_rpath: pkglibdir, +) + +find_unit_tests = find_program('meson/find-conform-unit-tests.sh') +test_conform_main = files(join_paths(meson.current_source_dir(), 'test-conform-main.c')) +cogl_conform_unit_tests = custom_target('cogl-tests-conform-unit-tests', + output: 'unit-tests', + input: test_conform_main, + command: [find_unit_tests, '@INPUT@', '@OUTPUT@'], + install: have_installed_tests, + install_dir: cogl_installed_tests_libexecdir, +) + +cogl_conformance_tests = run_command( + find_unit_tests, test_conform_main, '/dev/stdout', + check: true, +).stdout().strip().split('\n') + +foreach test_target: cogl_conformance_tests + name_parts = [] + foreach part: test_target.split('_') + if part != 'test' + name_parts += [part] + endif + endforeach + + test_name = '-'.join(name_parts) + test(test_name, cogl_run_tests, + suite: ['cogl', 'cogl/conform'], + env: ['RUN_TESTS_QUIET=1'], + args: [ + cogl_config_env, + libmutter_cogl_test_conformance, + test_target + ], + is_parallel: false, + ) +endforeach diff --git a/cogl/tests/conform/meson/find-conform-unit-tests.sh b/cogl/tests/conform/meson/find-conform-unit-tests.sh new file mode 100755 index 000000000..3c42b0a89 --- /dev/null +++ b/cogl/tests/conform/meson/find-conform-unit-tests.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +inputfile="$1" +outputfile="$2" + +sed -n -e 's/^ \{1,\}ADD_TEST *( *\([a-zA-Z0-9_]\{1,\}\).*/\1/p' "$inputfile" | while read -r test; do + echo "$test" >> "$outputfile" +done diff --git a/cogl/tests/conform/mutter-cogl.test.in b/cogl/tests/conform/mutter-cogl.test.in new file mode 100644 index 000000000..d7c85ede2 --- /dev/null +++ b/cogl/tests/conform/mutter-cogl.test.in @@ -0,0 +1,4 @@ +[Test] +Type=session +TestEnvironment=COGL_TEST_VERBOSE=1 +Exec=sh -c "cd @libexecdir@/installed-tests/mutter-@apiversion@/cogl/conform; ./run-tests.sh ./config.env ./test-conformance ./unit-tests" diff --git a/cogl/tests/conform/test-alpha-test.c b/cogl/tests/conform/test-alpha-test.c index e74f6d8e0..c46f7c218 100644 --- a/cogl/tests/conform/test-alpha-test.c +++ b/cogl/tests/conform/test-alpha-test.c @@ -1,6 +1,7 @@ #include #include +#include "test-declarations.h" #include "test-utils.h" static CoglTexture2D * diff --git a/cogl/tests/conform/test-alpha-textures.c b/cogl/tests/conform/test-alpha-textures.c index dccd30e11..05a2a8a37 100644 --- a/cogl/tests/conform/test-alpha-textures.c +++ b/cogl/tests/conform/test-alpha-textures.c @@ -2,6 +2,7 @@ #include +#include "test-declarations.h" #include "test-utils.h" static void diff --git a/cogl/tests/conform/test-atlas-migration.c b/cogl/tests/conform/test-atlas-migration.c index 628a3d558..b5d04c3d3 100644 --- a/cogl/tests/conform/test-atlas-migration.c +++ b/cogl/tests/conform/test-atlas-migration.c @@ -1,5 +1,6 @@ #include +#include "test-declarations.h" #include "test-utils.h" #define N_TEXTURES 128 @@ -31,7 +32,7 @@ create_texture (int size) /* Create a red, green or blue texture depending on the size */ color = COLOR_FOR_SIZE (size); - p = data = malloc (size * size * 4); + p = data = g_malloc (size * size * 4); /* Fill the data with the color but fade the opacity out with increasing y coordinates so that we can see the blending it the @@ -63,7 +64,7 @@ create_texture (int size) size * 4, data); - free (data); + g_free (data); return texture; } @@ -77,7 +78,7 @@ verify_texture (CoglTexture *texture, int size) color = COLOR_FOR_SIZE (size); - p = data = malloc (size * size * 4); + p = data = g_malloc (size * size * 4); cogl_texture_get_data (texture, COGL_PIXEL_FORMAT_RGBA_8888_PRE, @@ -108,7 +109,7 @@ verify_texture (CoglTexture *texture, int size) } } - free (data); + g_free (data); } void diff --git a/cogl/tests/conform/test-backface-culling.c b/cogl/tests/conform/test-backface-culling.c index 13357035b..24cce4b94 100644 --- a/cogl/tests/conform/test-backface-culling.c +++ b/cogl/tests/conform/test-backface-culling.c @@ -4,6 +4,7 @@ #include +#include "test-declarations.h" #include "test-utils.h" /* Size the texture so that it is just off a power of two to encourage @@ -27,7 +28,7 @@ typedef struct _TestState static void validate_part (CoglFramebuffer *framebuffer, - int xnum, int ynum, CoglBool shown) + int xnum, int ynum, gboolean shown) { test_utils_check_region (framebuffer, xnum * TEXTURE_RENDER_SIZE + TEST_INSET, @@ -37,13 +38,12 @@ validate_part (CoglFramebuffer *framebuffer, shown ? 0xff0000ff : 0x000000ff); } -/* We draw everything 16 times. The draw number is used as a bitmask - to test all of the combinations of enabling legacy state, both - winding orders and all four culling modes */ +/* We draw everything 8 times. The draw number is used as a bitmask + to test all of the combinations of enabling both winding orders and all four + culling modes */ -#define USE_LEGACY_STATE(draw_num) (((draw_num) & 0x01) >> 0) -#define FRONT_WINDING(draw_num) (((draw_num) & 0x02) >> 1) -#define CULL_FACE_MODE(draw_num) (((draw_num) & 0x0c) >> 2) +#define FRONT_WINDING(draw_num) (((draw_num) & 0x01) >> 1) +#define CULL_FACE_MODE(draw_num) (((draw_num) & 0x06) >> 2) static void paint_test_backface_culling (TestState *state, @@ -69,46 +69,47 @@ paint_test_backface_culling (TestState *state, COGL_PIPELINE_FILTER_NEAREST, COGL_PIPELINE_FILTER_NEAREST); - cogl_push_framebuffer (framebuffer); - /* Render the scene sixteen times to test all of the combinations of cull face mode, legacy state and winding orders */ - for (draw_num = 0; draw_num < 16; draw_num++) + for (draw_num = 0; draw_num < 8; draw_num++) { float x1 = 0, x2, y1 = 0, y2 = (float)(TEXTURE_RENDER_SIZE); - CoglTextureVertex verts[4]; + CoglVertexP3T2 verts[4]; + CoglPrimitive *primitive; CoglPipeline *pipeline; - cogl_push_matrix (); - cogl_translate (0, TEXTURE_RENDER_SIZE * draw_num, 0); + cogl_framebuffer_push_matrix (framebuffer); + cogl_framebuffer_translate (framebuffer, + 0, + TEXTURE_RENDER_SIZE * draw_num, + 0); pipeline = cogl_pipeline_copy (base_pipeline); - cogl_set_backface_culling_enabled (USE_LEGACY_STATE (draw_num)); cogl_pipeline_set_front_face_winding (pipeline, FRONT_WINDING (draw_num)); cogl_pipeline_set_cull_face_mode (pipeline, CULL_FACE_MODE (draw_num)); - cogl_push_source (pipeline); - memset (verts, 0, sizeof (verts)); x2 = x1 + (float)(TEXTURE_RENDER_SIZE); /* Draw a front-facing texture */ - cogl_rectangle (x1, y1, x2, y2); + cogl_framebuffer_draw_rectangle (framebuffer, pipeline, x1, y1, x2, y2); x1 = x2; x2 = x1 + (float)(TEXTURE_RENDER_SIZE); /* Draw a front-facing texture with flipped texcoords */ - cogl_rectangle_with_texture_coords (x1, y1, x2, y2, - 1.0, 0.0, 0.0, 1.0); + cogl_framebuffer_draw_textured_rectangle (framebuffer, pipeline, + x1, y1, x2, y2, + 1.0, 0.0, 0.0, 1.0); x1 = x2; x2 = x1 + (float)(TEXTURE_RENDER_SIZE); /* Draw a back-facing texture */ - cogl_rectangle (x2, y1, x1, y2); + cogl_framebuffer_draw_rectangle (framebuffer, pipeline, + x2, y1, x1, y2); x1 = x2; x2 = x1 + (float)(TEXTURE_RENDER_SIZE); @@ -116,18 +117,24 @@ paint_test_backface_culling (TestState *state, /* If the texture is sliced then cogl_polygon doesn't work so we'll just use a solid color instead */ if (cogl_texture_is_sliced (state->texture)) - cogl_set_source_color4ub (255, 0, 0, 255); + cogl_pipeline_set_color4ub (pipeline, 255, 0, 0, 255); /* Draw a front-facing polygon */ verts[0].x = x1; verts[0].y = y2; verts[1].x = x2; verts[1].y = y2; verts[2].x = x2; verts[2].y = y1; verts[3].x = x1; verts[3].y = y1; - verts[0].tx = 0; verts[0].ty = 0; - verts[1].tx = 1.0; verts[1].ty = 0; - verts[2].tx = 1.0; verts[2].ty = 1.0; - verts[3].tx = 0; verts[3].ty = 1.0; - cogl_polygon (verts, 4, FALSE); + verts[0].s = 0; verts[0].t = 0; + verts[1].s = 1.0; verts[1].t = 0; + verts[2].s = 1.0; verts[2].t = 1.0; + verts[3].s = 0; verts[3].t = 1.0; + + primitive = cogl_primitive_new_p3t2 (test_ctx, + COGL_VERTICES_MODE_TRIANGLE_FAN, + 4, + verts); + cogl_primitive_draw (primitive, framebuffer, pipeline); + cogl_object_unref (primitive); x1 = x2; x2 = x1 + (float)(TEXTURE_RENDER_SIZE); @@ -137,23 +144,26 @@ paint_test_backface_culling (TestState *state, verts[1].x = x2; verts[1].y = y1; verts[2].x = x2; verts[2].y = y2; verts[3].x = x1; verts[3].y = y2; - verts[0].tx = 0; verts[0].ty = 0; - verts[1].tx = 1.0; verts[1].ty = 0; - verts[2].tx = 1.0; verts[2].ty = 1.0; - verts[3].tx = 0; verts[3].ty = 1.0; - cogl_polygon (verts, 4, FALSE); + verts[0].s = 0; verts[0].t = 0; + verts[1].s = 1.0; verts[1].t = 0; + verts[2].s = 1.0; verts[2].t = 1.0; + verts[3].s = 0; verts[3].t = 1.0; + + primitive = cogl_primitive_new_p3t2 (test_ctx, + COGL_VERTICES_MODE_TRIANGLE_FAN, + 4, + verts); + cogl_primitive_draw (primitive, framebuffer, pipeline); + cogl_object_unref (primitive); x1 = x2; x2 = x1 + (float)(TEXTURE_RENDER_SIZE); - cogl_pop_matrix (); + cogl_framebuffer_pop_matrix (framebuffer); - cogl_pop_source (); cogl_object_unref (pipeline); } - cogl_pop_framebuffer (); - cogl_object_unref (base_pipeline); } @@ -162,15 +172,12 @@ validate_result (CoglFramebuffer *framebuffer, int y_offset) { int draw_num; - for (draw_num = 0; draw_num < 16; draw_num++) + for (draw_num = 0; draw_num < 8; draw_num++) { - CoglBool cull_front, cull_back; + gboolean cull_front, cull_back; CoglPipelineCullFaceMode cull_mode; - if (USE_LEGACY_STATE (draw_num)) - cull_mode = COGL_PIPELINE_CULL_FACE_MODE_BACK; - else - cull_mode = CULL_FACE_MODE (draw_num); + cull_mode = CULL_FACE_MODE (draw_num); switch (cull_mode) { @@ -197,7 +204,7 @@ validate_result (CoglFramebuffer *framebuffer, int y_offset) if (FRONT_WINDING (draw_num) == COGL_WINDING_CLOCKWISE) { - CoglBool tmp = cull_front; + gboolean tmp = cull_front; cull_front = cull_back; cull_back = tmp; } @@ -241,13 +248,13 @@ paint (TestState *state) cogl_pipeline_set_layer_texture (pipeline, 0, state->offscreen_tex); cogl_framebuffer_draw_rectangle (test_fb, pipeline, - 0, TEXTURE_RENDER_SIZE * 16, + 0, TEXTURE_RENDER_SIZE * 8, state->width, - state->height + TEXTURE_RENDER_SIZE * 16); + state->height + TEXTURE_RENDER_SIZE * 8); cogl_object_unref (pipeline); validate_result (test_fb, 0); - validate_result (test_fb, 16); + validate_result (test_fb, 8); } static CoglTexture * @@ -256,7 +263,7 @@ make_texture (void) guchar *tex_data, *p; CoglTexture *tex; - tex_data = malloc (TEXTURE_SIZE * TEXTURE_SIZE * 4); + tex_data = g_malloc (TEXTURE_SIZE * TEXTURE_SIZE * 4); for (p = tex_data + TEXTURE_SIZE * TEXTURE_SIZE * 4; p > tex_data;) { @@ -274,7 +281,7 @@ make_texture (void) TEXTURE_SIZE * 4, tex_data); - free (tex_data); + g_free (tex_data); return tex; } diff --git a/cogl/tests/conform/test-blend-strings.c b/cogl/tests/conform/test-blend-strings.c index d58c66c65..d440a5eaf 100644 --- a/cogl/tests/conform/test-blend-strings.c +++ b/cogl/tests/conform/test-blend-strings.c @@ -2,6 +2,7 @@ #include +#include "test-declarations.h" #include "test-utils.h" #define QUAD_WIDTH 20 @@ -26,14 +27,14 @@ typedef struct _TestState static void -test_blend (TestState *state, - int x, - int y, - uint32_t src_color, - uint32_t dst_color, - const char *blend_string, - uint32_t blend_constant, - uint32_t expected_result) +test_blend_paint (TestState *state, + int x, + int y, + uint32_t src_color, + uint32_t dst_color, + const char *blend_string, + uint32_t blend_constant, + uint32_t expected_result) { /* src color */ uint8_t Sr = MASK_RED (src_color); @@ -52,10 +53,9 @@ test_blend (TestState *state, uint8_t Ba = MASK_ALPHA (blend_constant); CoglColor blend_const_color; - CoglHandle material; CoglPipeline *pipeline; - CoglBool status; - CoglError *error = NULL; + gboolean status; + GError *error = NULL; int y_off; int x_off; @@ -63,11 +63,12 @@ test_blend (TestState *state, pipeline = cogl_pipeline_new (test_ctx); cogl_pipeline_set_color4ub (pipeline, Dr, Dg, Db, Da); cogl_pipeline_set_blend (pipeline, "RGBA = ADD (SRC_COLOR, 0)", NULL); - cogl_set_source (pipeline); - cogl_rectangle (x * QUAD_WIDTH, - y * QUAD_WIDTH, - x * QUAD_WIDTH + QUAD_WIDTH, - y * QUAD_WIDTH + QUAD_WIDTH); + cogl_framebuffer_draw_rectangle (test_fb, + pipeline, + x * QUAD_WIDTH, + y * QUAD_WIDTH, + x * QUAD_WIDTH + QUAD_WIDTH, + y * QUAD_WIDTH + QUAD_WIDTH); cogl_object_unref (pipeline); /* @@ -94,11 +95,12 @@ test_blend (TestState *state, cogl_color_init_from_4ub (&blend_const_color, Br, Bg, Bb, Ba); cogl_pipeline_set_blend_constant (pipeline, &blend_const_color); - cogl_set_source (pipeline); - cogl_rectangle (x * QUAD_WIDTH, - y * QUAD_WIDTH, - x * QUAD_WIDTH + QUAD_WIDTH, - y * QUAD_WIDTH + QUAD_WIDTH); + cogl_framebuffer_draw_rectangle (test_fb, + pipeline, + x * QUAD_WIDTH, + y * QUAD_WIDTH, + x * QUAD_WIDTH + QUAD_WIDTH, + y * QUAD_WIDTH + QUAD_WIDTH); cogl_object_unref (pipeline); /* See what we got... */ @@ -119,59 +121,6 @@ test_blend (TestState *state, } test_utils_check_pixel (test_fb, x_off, y_off, expected_result); - - - /* - * Test with legacy API - */ - - /* Clear previous work */ - cogl_set_source_color4ub (0, 0, 0, 0xff); - cogl_rectangle (x * QUAD_WIDTH, - y * QUAD_WIDTH, - x * QUAD_WIDTH + QUAD_WIDTH, - y * QUAD_WIDTH + QUAD_WIDTH); - - /* First write out the destination color without any blending... */ - material = cogl_material_new (); - cogl_material_set_color4ub (material, Dr, Dg, Db, Da); - cogl_material_set_blend (material, "RGBA = ADD (SRC_COLOR, 0)", NULL); - cogl_set_source (material); - cogl_rectangle (x * QUAD_WIDTH, - y * QUAD_WIDTH, - x * QUAD_WIDTH + QUAD_WIDTH, - y * QUAD_WIDTH + QUAD_WIDTH); - cogl_handle_unref (material); - - /* - * Now blend a rectangle over our well defined destination: - */ - - material = cogl_material_new (); - cogl_material_set_color4ub (material, Sr, Sg, Sb, Sa); - - status = cogl_material_set_blend (material, blend_string, &error); - if (!status) - { - /* This is a failure as it must be equivalent to the new API */ - g_warning ("Error setting blend string %s: %s", - blend_string, error->message); - g_assert_not_reached (); - } - - cogl_color_init_from_4ub (&blend_const_color, Br, Bg, Bb, Ba); - cogl_material_set_blend_constant (material, &blend_const_color); - - cogl_set_source (material); - cogl_rectangle (x * QUAD_WIDTH, - y * QUAD_WIDTH, - x * QUAD_WIDTH + QUAD_WIDTH, - y * QUAD_WIDTH + QUAD_WIDTH); - cogl_handle_unref (material); - - /* See what we got... */ - - test_utils_check_pixel (test_fb, x_off, y_off, expected_result); } static CoglTexture * @@ -184,7 +133,7 @@ make_texture (uint32_t color) uint8_t a = MASK_ALPHA (color); CoglTexture *tex; - tex_data = malloc (QUAD_WIDTH * QUAD_WIDTH * 4); + tex_data = g_malloc (QUAD_WIDTH * QUAD_WIDTH * 4); for (p = tex_data + QUAD_WIDTH * QUAD_WIDTH * 4; p > tex_data;) { @@ -204,7 +153,7 @@ make_texture (uint32_t color) QUAD_WIDTH * 4, tex_data); - free (tex_data); + g_free (tex_data); return tex; } @@ -228,9 +177,9 @@ test_tex_combine (TestState *state, uint8_t Ca = MASK_ALPHA (combine_constant); CoglColor combine_const_color; - CoglHandle material; - CoglBool status; - CoglError *error = NULL; + CoglPipeline *pipeline; + gboolean status; + GError *error = NULL; int y_off; int x_off; @@ -238,17 +187,17 @@ test_tex_combine (TestState *state, tex0 = make_texture (tex0_color); tex1 = make_texture (tex1_color); - material = cogl_material_new (); + pipeline = cogl_pipeline_new (test_ctx); - cogl_material_set_color4ub (material, 0x80, 0x80, 0x80, 0x80); - cogl_material_set_blend (material, "RGBA = ADD (SRC_COLOR, 0)", NULL); + cogl_pipeline_set_color4ub (pipeline, 0x80, 0x80, 0x80, 0x80); + cogl_pipeline_set_blend (pipeline, "RGBA = ADD (SRC_COLOR, 0)", NULL); - cogl_material_set_layer (material, 0, tex0); - cogl_material_set_layer_combine (material, 0, + cogl_pipeline_set_layer_texture (pipeline, 0, tex0); + cogl_pipeline_set_layer_combine (pipeline, 0, "RGBA = REPLACE (TEXTURE)", NULL); - cogl_material_set_layer (material, 1, tex1); - status = cogl_material_set_layer_combine (material, 1, + cogl_pipeline_set_layer_texture (pipeline, 1, tex1); + status = cogl_pipeline_set_layer_combine (pipeline, 1, combine_string, &error); if (!status) { @@ -259,15 +208,16 @@ test_tex_combine (TestState *state, } cogl_color_init_from_4ub (&combine_const_color, Cr, Cg, Cb, Ca); - cogl_material_set_layer_combine_constant (material, 1, &combine_const_color); + cogl_pipeline_set_layer_combine_constant (pipeline, 1, &combine_const_color); - cogl_set_source (material); - cogl_rectangle (x * QUAD_WIDTH, - y * QUAD_WIDTH, - x * QUAD_WIDTH + QUAD_WIDTH, - y * QUAD_WIDTH + QUAD_WIDTH); + cogl_framebuffer_draw_rectangle (test_fb, + pipeline, + x * QUAD_WIDTH, + y * QUAD_WIDTH, + x * QUAD_WIDTH + QUAD_WIDTH, + y * QUAD_WIDTH + QUAD_WIDTH); - cogl_handle_unref (material); + cogl_object_unref (pipeline); cogl_object_unref (tex0); cogl_object_unref (tex1); @@ -294,34 +244,34 @@ test_tex_combine (TestState *state, static void paint (TestState *state) { - test_blend (state, 0, 0, /* position */ - 0xff0000ff, /* src */ - 0xffffffff, /* dst */ - "RGBA = ADD (SRC_COLOR, 0)", - BLEND_CONSTANT_UNUSED, - 0xff0000ff); /* expected */ - - test_blend (state, 1, 0, /* position */ - 0x11223344, /* src */ - 0x11223344, /* dst */ - "RGBA = ADD (SRC_COLOR, DST_COLOR)", - BLEND_CONSTANT_UNUSED, - 0x22446688); /* expected */ - - test_blend (state, 2, 0, /* position */ - 0x80808080, /* src */ - 0xffffffff, /* dst */ - "RGBA = ADD (SRC_COLOR * (CONSTANT), 0)", - 0x80808080, /* constant (RGBA all = 0.5 when normalized) */ - 0x40404040); /* expected */ - - test_blend (state, 3, 0, /* position */ - 0x80000080, /* src (alpha = 0.5 when normalized) */ - 0x40000000, /* dst */ - "RGBA = ADD (SRC_COLOR * (SRC_COLOR[A])," - " DST_COLOR * (1-SRC_COLOR[A]))", - BLEND_CONSTANT_UNUSED, - 0x60000040); /* expected */ + test_blend_paint (state, 0, 0, /* position */ + 0xff0000ff, /* src */ + 0xffffffff, /* dst */ + "RGBA = ADD (SRC_COLOR, 0)", + BLEND_CONSTANT_UNUSED, + 0xff0000ff); /* expected */ + + test_blend_paint (state, 1, 0, /* position */ + 0x11223344, /* src */ + 0x11223344, /* dst */ + "RGBA = ADD (SRC_COLOR, DST_COLOR)", + BLEND_CONSTANT_UNUSED, + 0x22446688); /* expected */ + + test_blend_paint (state, 2, 0, /* position */ + 0x80808080, /* src */ + 0xffffffff, /* dst */ + "RGBA = ADD (SRC_COLOR * (CONSTANT), 0)", + 0x80808080, /* constant (RGBA all = 0.5 when normalized) */ + 0x40404040); /* expected */ + + test_blend_paint (state, 3, 0, /* position */ + 0x80000080, /* src (alpha = 0.5 when normalized) */ + 0x40000000, /* dst */ + "RGBA = ADD (SRC_COLOR * (SRC_COLOR[A])," + " DST_COLOR * (1-SRC_COLOR[A]))", + BLEND_CONSTANT_UNUSED, + 0x60000040); /* expected */ /* XXX: * For all texture combine tests tex0 will use a combine mode of @@ -350,7 +300,7 @@ paint (TestState *state) "A = MODULATE (PREVIOUS, TEXTURE)", /* tex combine */ 0xffffff20); /* expected */ - /* XXX: we are assuming test_tex_combine creates a material with + /* XXX: we are assuming test_tex_combine creates a pipeline with * a color of 0x80808080 (i.e. the "PRIMARY" color) */ test_tex_combine (state, 7, 0, /* position */ 0xffffff80, /* texture 0 color (alpha = 0.5) */ @@ -418,11 +368,7 @@ test_blend_strings (void) -1, 100); - /* XXX: we have to push/pop a framebuffer since this test currently - * uses the legacy cogl_rectangle() api. */ - cogl_push_framebuffer (test_fb); paint (&state); - cogl_pop_framebuffer (); if (cogl_test_verbose ()) g_print ("OK\n"); diff --git a/cogl/tests/conform/test-blend.c b/cogl/tests/conform/test-blend.c index 3c6235b5f..720fcc02c 100644 --- a/cogl/tests/conform/test-blend.c +++ b/cogl/tests/conform/test-blend.c @@ -2,6 +2,7 @@ #include +#include "test-declarations.h" #include "test-utils.h" static void diff --git a/cogl/tests/conform/test-color-hsl.c b/cogl/tests/conform/test-color-hsl.c index 651ce5208..15f2fe84b 100644 --- a/cogl/tests/conform/test-color-hsl.c +++ b/cogl/tests/conform/test-color-hsl.c @@ -3,6 +3,7 @@ #include +#include "test-declarations.h" #include "test-utils.h" #define cogl_assert_float(a, b) \ diff --git a/cogl/tests/conform/test-color-mask.c b/cogl/tests/conform/test-color-mask.c deleted file mode 100644 index e80f46dae..000000000 --- a/cogl/tests/conform/test-color-mask.c +++ /dev/null @@ -1,110 +0,0 @@ -#include - -#include "test-utils.h" - -#define TEX_SIZE 128 - -#define NUM_FBOS 3 - -typedef struct _TestState -{ - int width; - int height; - - CoglTexture *tex[NUM_FBOS]; - CoglFramebuffer *fbo[NUM_FBOS]; -} TestState; - -static void -paint (TestState *state) -{ - CoglColor bg; - int i; - - cogl_set_source_color4ub (255, 255, 255, 255); - - /* We push the third framebuffer first so that later we can switch - back to it by popping to test that that works */ - cogl_push_framebuffer (state->fbo[2]); - - cogl_push_framebuffer (state->fbo[0]); - cogl_rectangle (-1.0, -1.0, 1.0, 1.0); - cogl_pop_framebuffer (); - - cogl_push_framebuffer (state->fbo[1]); - cogl_rectangle (-1.0, -1.0, 1.0, 1.0); - cogl_pop_framebuffer (); - - /* We should now be back on the third framebuffer */ - cogl_rectangle (-1.0, -1.0, 1.0, 1.0); - cogl_pop_framebuffer (); - - cogl_color_init_from_4ub (&bg, 128, 128, 128, 255); - cogl_clear (&bg, COGL_BUFFER_BIT_COLOR | COGL_BUFFER_BIT_DEPTH); - - /* Render all of the textures to the screen */ - for (i = 0; i < NUM_FBOS; i++) - { - CoglPipeline *pipeline = cogl_pipeline_new (test_ctx); - cogl_pipeline_set_layer_texture (pipeline, 0, state->tex[i]); - cogl_framebuffer_draw_rectangle (test_fb, pipeline, - 2.0f / NUM_FBOS * i - 1.0f, -1.0f, - 2.0f / NUM_FBOS * (i + 1) - 1.0f, 1.0f); - cogl_object_unref (pipeline); - } - - /* Verify all of the fbos drew the right color */ - for (i = 0; i < NUM_FBOS; i++) - { - uint8_t expected_colors[NUM_FBOS][4] = - { { 0xff, 0x00, 0x00, 0xff }, - { 0x00, 0xff, 0x00, 0xff }, - { 0x00, 0x00, 0xff, 0xff } }; - - test_utils_check_pixel_rgb (test_fb, - state->width * (i + 0.5f) / NUM_FBOS, - state->height / 2, - expected_colors[i][0], - expected_colors[i][1], - expected_colors[i][2]); - } -} - -void -test_color_mask (void) -{ - TestState state; - int i; - - state.width = cogl_framebuffer_get_width (test_fb); - state.height = cogl_framebuffer_get_height (test_fb); - - for (i = 0; i < NUM_FBOS; i++) - { - state.tex[i] = test_utils_texture_new_with_size (test_ctx, 128, 128, - TEST_UTILS_TEXTURE_NO_ATLAS, - COGL_TEXTURE_COMPONENTS_RGB); - - - state.fbo[i] = cogl_offscreen_new_with_texture (state.tex[i]); - - /* Clear the texture color bits */ - cogl_framebuffer_clear4f (state.fbo[i], - COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1); - - cogl_framebuffer_set_color_mask (state.fbo[i], - i == 0 ? COGL_COLOR_MASK_RED : - i == 1 ? COGL_COLOR_MASK_GREEN : - COGL_COLOR_MASK_BLUE); - } - - /* XXX: we have to push/pop a framebuffer since this test currently - * uses the legacy cogl_rectangle() api. */ - cogl_push_framebuffer (test_fb); - paint (&state); - cogl_pop_framebuffer (); - - if (cogl_test_verbose ()) - g_print ("OK\n"); -} - diff --git a/cogl/tests/conform/test-conform-main.c b/cogl/tests/conform/test-conform-main.c index 64fdfba01..a01026d43 100644 --- a/cogl/tests/conform/test-conform-main.c +++ b/cogl/tests/conform/test-conform-main.c @@ -7,12 +7,12 @@ #include #include +#include "test-declarations.h" #include "test-utils.h" /* A bit of sugar for adding new conformance tests */ #define ADD_TEST(FUNC, REQUIREMENTS, KNOWN_FAIL_REQUIREMENTS) \ G_STMT_START { \ - extern void FUNC (void); \ if (strcmp (#FUNC, argv[1]) == 0) \ { \ test_utils_init (REQUIREMENTS, KNOWN_FAIL_REQUIREMENTS); \ @@ -57,12 +57,9 @@ main (int argc, char **argv) ADD_TEST (test_blend, 0, 0); ADD_TEST (test_premult, 0, TEST_KNOWN_FAILURE); UNPORTED_TEST (test_readpixels); -#ifdef COGL_HAS_COGL_PATH_SUPPORT ADD_TEST (test_path, 0, 0); ADD_TEST (test_path_clip, 0, 0); -#endif ADD_TEST (test_depth_test, 0, 0); - ADD_TEST (test_color_mask, 0, 0); ADD_TEST (test_backface_culling, 0, TEST_REQUIREMENT_NPOT); ADD_TEST (test_layer_remove, 0, 0); @@ -76,7 +73,6 @@ main (int argc, char **argv) ADD_TEST (test_pixel_buffer_set_data, 0, 0); ADD_TEST (test_pixel_buffer_sub_region, 0, 0); UNPORTED_TEST (test_texture_rectangle); - ADD_TEST (test_texture_3d, TEST_REQUIREMENT_TEXTURE_3D, 0); ADD_TEST (test_wrap_modes, 0, 0); UNPORTED_TEST (test_texture_pixmap_x11); ADD_TEST (test_texture_get_set_data, 0, 0); @@ -84,9 +80,6 @@ main (int argc, char **argv) ADD_TEST (test_read_texture_formats, 0, TEST_KNOWN_FAILURE); ADD_TEST (test_write_texture_formats, 0, 0); ADD_TEST (test_alpha_textures, 0, 0); - ADD_TEST (test_wrap_rectangle_textures, - TEST_REQUIREMENT_TEXTURE_RECTANGLE, - TEST_KNOWN_FAILURE); UNPORTED_TEST (test_vertex_buffer_contiguous); UNPORTED_TEST (test_vertex_buffer_interleved); @@ -121,8 +114,6 @@ main (int argc, char **argv) TEST_REQUIREMENT_GLSL, 0); - ADD_TEST (test_version, 0, 0); - ADD_TEST (test_alpha_test, 0, 0); ADD_TEST (test_map_buffer_range, TEST_REQUIREMENT_MAP_WRITE, 0); @@ -136,13 +127,7 @@ main (int argc, char **argv) UNPORTED_TEST (test_viewport); - ADD_TEST (test_gles2_context, TEST_REQUIREMENT_GLES2_CONTEXT, 0); - ADD_TEST (test_gles2_context_fbo, TEST_REQUIREMENT_GLES2_CONTEXT, 0); - ADD_TEST (test_gles2_context_copy_tex_image, - TEST_REQUIREMENT_GLES2_CONTEXT, - 0); - - ADD_TEST (test_euler_quaternion, 0, 0); + ADD_TEST (test_euler, 0, 0); ADD_TEST (test_color_hsl, 0, 0); ADD_TEST (test_fence, TEST_REQUIREMENT_FENCE, 0); diff --git a/cogl/tests/conform/test-copy-replace-texture.c b/cogl/tests/conform/test-copy-replace-texture.c index f11070ee8..7f0f319d6 100644 --- a/cogl/tests/conform/test-copy-replace-texture.c +++ b/cogl/tests/conform/test-copy-replace-texture.c @@ -1,6 +1,7 @@ #include #include +#include "test-declarations.h" #include "test-utils.h" /* Keep track of the number of textures that we've created and are diff --git a/cogl/tests/conform/test-custom-attributes.c b/cogl/tests/conform/test-custom-attributes.c index 633dc2ad8..dfb7cbdb2 100644 --- a/cogl/tests/conform/test-custom-attributes.c +++ b/cogl/tests/conform/test-custom-attributes.c @@ -2,6 +2,7 @@ #include +#include "test-declarations.h" #include "test-utils.h" typedef struct _TestState diff --git a/cogl/tests/conform/test-declarations.h b/cogl/tests/conform/test-declarations.h new file mode 100644 index 000000000..850d59f0f --- /dev/null +++ b/cogl/tests/conform/test-declarations.h @@ -0,0 +1,53 @@ +#ifndef COGL_TEST_DECLARATIONS_H +#define COGL_TEST_DECLARATIONS_H + +void test_pipeline_user_matrix (void); +void test_blend_strings (void); +void test_blend (void); +void test_premult (void); +void test_path (void); +void test_path_clip (void); +void test_depth_test (void); +void test_backface_culling (void); +void test_layer_remove (void); +void test_sparse_pipeline (void); +void test_npot_texture (void); +void test_sub_texture (void); +void test_pixel_buffer_map (void); +void test_pixel_buffer_set_data (void); +void test_pixel_buffer_sub_region (void); +void test_wrap_modes (void); +void test_texture_get_set_data (void); +void test_atlas_migration (void); +void test_read_texture_formats (void); +void test_write_texture_formats (void); +void test_alpha_textures (void); +void test_primitive (void); +void test_just_vertex_shader (void); +void test_pipeline_uniforms (void); +void test_snippets (void); +void test_custom_attributes (void); +void test_offscreen (void); +void test_framebuffer_get_bits (void); +void test_point_size (void); +void test_point_size_attribute (void); +void test_point_size_attribute_snippet (void); +void test_point_sprite (void); +void test_point_sprite_orientation (void); +void test_point_sprite_glsl (void); +void test_alpha_test (void); +void test_map_buffer_range (void); +void test_primitive_and_journal (void); +void test_copy_replace_texture (void); +void test_pipeline_cache_unrefs_texture (void); +void test_pipeline_shader_state (void); +void test_gles2_context (void); +void test_gles2_context_fbo (void); +void test_gles2_context_copy_tex_image (void); +void test_euler (void); +void test_color_hsl (void); +void test_fence (void); +void test_texture_no_allocate (void); +void test_texture_rg (void); + +#endif /* COGL_TEST_DECLARATIONS_H */ diff --git a/cogl/tests/conform/test-depth-test.c b/cogl/tests/conform/test-depth-test.c index bfa9d0e1f..b6ed98d9d 100644 --- a/cogl/tests/conform/test-depth-test.c +++ b/cogl/tests/conform/test-depth-test.c @@ -4,6 +4,7 @@ #include +#include "test-declarations.h" #include "test-utils.h" #define QUAD_WIDTH 20 @@ -27,20 +28,20 @@ typedef struct { uint32_t color; float depth; - CoglBool test_enable; + gboolean test_enable; CoglDepthTestFunction test_function; - CoglBool write_enable; - CoglBool fb_write_enable; + gboolean write_enable; + gboolean fb_write_enable; float range_near; float range_far; } TestDepthState; -static CoglBool +static gboolean draw_rectangle (TestState *state, int x, int y, TestDepthState *rect_state, - CoglBool legacy_mode) + gboolean legacy_mode) { uint8_t Cr = MASK_RED (rect_state->color); uint8_t Cg = MASK_GREEN (rect_state->color); @@ -82,16 +83,22 @@ draw_rectangle (TestState *state, } else { - cogl_push_framebuffer (test_fb); - cogl_push_matrix (); - cogl_set_source_color4ub (Cr, Cg, Cb, Ca); - cogl_translate (0, 0, rect_state->depth); - cogl_rectangle (x * QUAD_WIDTH, - y * QUAD_WIDTH, - x * QUAD_WIDTH + QUAD_WIDTH, - y * QUAD_WIDTH + QUAD_WIDTH); - cogl_pop_matrix (); - cogl_pop_framebuffer (); + CoglPipeline *legacy_pipeline; + + legacy_pipeline = cogl_pipeline_new (test_ctx); + + cogl_framebuffer_push_matrix (test_fb); + cogl_pipeline_set_color4ub (pipeline, Cr, Cg, Cb, Ca); + cogl_framebuffer_translate (test_fb, 0, 0, rect_state->depth); + cogl_framebuffer_draw_rectangle (test_fb, + pipeline, + x * QUAD_WIDTH, + y * QUAD_WIDTH, + x * QUAD_WIDTH + QUAD_WIDTH, + y * QUAD_WIDTH + QUAD_WIDTH); + cogl_framebuffer_pop_matrix (test_fb); + + cogl_object_unref (legacy_pipeline); } cogl_object_unref (pipeline); @@ -106,10 +113,10 @@ test_depth (TestState *state, TestDepthState *rect0_state, TestDepthState *rect1_state, TestDepthState *rect2_state, - CoglBool legacy_mode, + gboolean legacy_mode, uint32_t expected_result) { - CoglBool missing_feature = FALSE; + gboolean missing_feature = FALSE; if (rect0_state) missing_feature |= !draw_rectangle (state, x, y, rect0_state, legacy_mode); @@ -243,43 +250,6 @@ paint (TestState *state) FALSE, /* legacy mode */ 0xff0000ff); /* expected */ } - - /* Test that the legacy cogl_set_depth_test_enabled() API still - * works... */ - - { - /* Nearest */ - TestDepthState rect0_state = { - 0xff0000ff, /* rgba color */ - -10, /* depth */ - FALSE, /* depth test enable */ - COGL_DEPTH_TEST_FUNCTION_LESS, - TRUE, /* depth write enable */ - TRUE, /* FB depth write enable */ - 0, 1 /* depth range */ - }; - /* Furthest */ - TestDepthState rect1_state = { - 0x00ff00ff, /* rgba color */ - -70, /* depth */ - FALSE, /* depth test enable */ - COGL_DEPTH_TEST_FUNCTION_LESS, - TRUE, /* depth write enable */ - TRUE, /* FB depth write enable */ - 0, 1 /* depth range */ - }; - - cogl_set_depth_test_enabled (TRUE); - test_depth (state, 0, 2, /* position */ - &rect0_state, &rect1_state, NULL, - TRUE, /* legacy mode */ - 0xff0000ff); /* expected */ - cogl_set_depth_test_enabled (FALSE); - test_depth (state, 1, 2, /* position */ - &rect0_state, &rect1_state, NULL, - TRUE, /* legacy mode */ - 0x00ff00ff); /* expected */ - } } void diff --git a/cogl/tests/conform/test-euler-quaternion.c b/cogl/tests/conform/test-euler.c similarity index 76% rename from cogl/tests/conform/test-euler-quaternion.c rename to cogl/tests/conform/test-euler.c index c250bec0b..c911a1a13 100644 --- a/cogl/tests/conform/test-euler-quaternion.c +++ b/cogl/tests/conform/test-euler.c @@ -2,6 +2,7 @@ #include #include +#include "test-declarations.h" #include "test-utils.h" /* Macros are used here instead of functions so that the @@ -35,10 +36,9 @@ } while (0) void -test_euler_quaternion (void) +test_euler (void) { - CoglEuler euler; - CoglQuaternion quaternion; + graphene_euler_t euler; CoglMatrix matrix_a, matrix_b; /* Try doing the rotation with three separate rotations */ @@ -48,18 +48,12 @@ test_euler_quaternion (void) cogl_matrix_rotate (&matrix_a, 50.0f, 0.0f, 0.0f, 1.0f); /* And try the same rotation with a euler */ - cogl_euler_init (&euler, -30, 40, 50); + graphene_euler_init_with_order (&euler, 40, -30, 50, GRAPHENE_EULER_ORDER_RYXZ); cogl_matrix_init_from_euler (&matrix_b, &euler); /* Verify that the matrices are approximately the same */ COMPARE_MATRICES (&matrix_a, &matrix_b); - /* Try converting the euler to a matrix via a quaternion */ - cogl_quaternion_init_from_euler (&quaternion, &euler); - memset (&matrix_b, 0, sizeof (matrix_b)); - cogl_matrix_init_from_quaternion (&matrix_b, &quaternion); - COMPARE_MATRICES (&matrix_a, &matrix_b); - /* Try applying the rotation from a euler to a framebuffer */ cogl_framebuffer_identity_matrix (test_fb); cogl_framebuffer_rotate_euler (test_fb, &euler); @@ -67,13 +61,6 @@ test_euler_quaternion (void) cogl_framebuffer_get_modelview_matrix (test_fb, &matrix_b); COMPARE_MATRICES (&matrix_a, &matrix_b); - /* And again with a quaternion */ - cogl_framebuffer_identity_matrix (test_fb); - cogl_framebuffer_rotate_quaternion (test_fb, &quaternion); - memset (&matrix_b, 0, sizeof (matrix_b)); - cogl_framebuffer_get_modelview_matrix (test_fb, &matrix_b); - COMPARE_MATRICES (&matrix_a, &matrix_b); - /* FIXME: This needs a lot more tests! */ if (cogl_test_verbose ()) diff --git a/cogl/tests/conform/test-fence.c b/cogl/tests/conform/test-fence.c index 1386bceca..6c429c1d7 100644 --- a/cogl/tests/conform/test-fence.c +++ b/cogl/tests/conform/test-fence.c @@ -1,5 +1,6 @@ #include +#include "test-declarations.h" #include "test-utils.h" #include "cogl-config.h" @@ -8,7 +9,7 @@ static GMainLoop *loop; -gboolean +static gboolean timeout (void *user_data) { g_assert (!"timeout not reached"); @@ -16,7 +17,7 @@ timeout (void *user_data) return FALSE; } -void +static void callback (CoglFence *fence, void *user_data) { diff --git a/cogl/tests/conform/test-fixed.c b/cogl/tests/conform/test-fixed.c deleted file mode 100644 index 175b2d195..000000000 --- a/cogl/tests/conform/test-fixed.c +++ /dev/null @@ -1,18 +0,0 @@ -#include -#include - -#include "test-conform-common.h" - -void -test_fixed (TestUtilsGTestFixture *fixture, - void *data) -{ - g_assert_cmpint (COGL_FIXED_1, ==, COGL_FIXED_FROM_FLOAT (1.0)); - g_assert_cmpint (COGL_FIXED_1, ==, COGL_FIXED_FROM_INT (1)); - - g_assert_cmpint (COGL_FIXED_0_5, ==, COGL_FIXED_FROM_FLOAT (0.5)); - - g_assert_cmpfloat (COGL_FIXED_TO_FLOAT (COGL_FIXED_1), ==, 1.0); - g_assert_cmpfloat (COGL_FIXED_TO_FLOAT (COGL_FIXED_0_5), ==, 0.5); -} - diff --git a/cogl/tests/conform/test-framebuffer-get-bits.c b/cogl/tests/conform/test-framebuffer-get-bits.c index 31c220d78..d03f91b99 100644 --- a/cogl/tests/conform/test-framebuffer-get-bits.c +++ b/cogl/tests/conform/test-framebuffer-get-bits.c @@ -1,5 +1,6 @@ #include +#include "test-declarations.h" #include "test-utils.h" void diff --git a/cogl/tests/conform/test-gles2-context.c b/cogl/tests/conform/test-gles2-context.c deleted file mode 100644 index d291be271..000000000 --- a/cogl/tests/conform/test-gles2-context.c +++ /dev/null @@ -1,962 +0,0 @@ - -#include -#include -#include - -#include "test-utils.h" - -typedef struct _TestState -{ - CoglTexture *offscreen_texture; - CoglOffscreen *offscreen; - CoglGLES2Context *gles2_ctx; - const CoglGLES2Vtable *gles2; -} TestState; - -static void -test_push_pop_single_context (void) -{ - CoglTexture *offscreen_texture; - CoglOffscreen *offscreen; - CoglPipeline *pipeline; - CoglGLES2Context *gles2_ctx; - const CoglGLES2Vtable *gles2; - CoglError *error = NULL; - - offscreen_texture = - cogl_texture_2d_new_with_size (test_ctx, - cogl_framebuffer_get_width (test_fb), - cogl_framebuffer_get_height (test_fb)); - offscreen = cogl_offscreen_new_with_texture (offscreen_texture); - - pipeline = cogl_pipeline_new (test_ctx); - cogl_pipeline_set_layer_texture (pipeline, 0, offscreen_texture); - - gles2_ctx = cogl_gles2_context_new (test_ctx, &error); - if (!gles2_ctx) - g_error ("Failed to create GLES2 context: %s\n", error->message); - - gles2 = cogl_gles2_context_get_vtable (gles2_ctx); - - /* Clear onscreen to 0xffff00 using GLES2 */ - - if (!cogl_push_gles2_context (test_ctx, - gles2_ctx, - test_fb, - test_fb, - &error)) - { - g_error ("Failed to push gles2 context: %s\n", error->message); - } - - gles2->glClearColor (1, 1, 0, 1); - gles2->glClear (GL_COLOR_BUFFER_BIT); - - cogl_pop_gles2_context (test_ctx); - - test_utils_check_pixel (test_fb, 0, 0, 0xffff00ff); - - /* Clear offscreen to 0xff0000 using GLES2 and then copy the result - * onscreen. - * - * If we fail to bind the new context here then we'd probably end up - * clearing onscreen to 0xff0000 and copying 0xffff00 to onscreen - * instead. - */ - - if (!cogl_push_gles2_context (test_ctx, - gles2_ctx, - offscreen, - offscreen, - &error)) - { - g_error ("Failed to push gles2 context: %s\n", error->message); - } - - gles2->glClearColor (1, 0, 0, 1); - gles2->glClear (GL_COLOR_BUFFER_BIT); - - cogl_pop_gles2_context (test_ctx); - - cogl_framebuffer_draw_rectangle (test_fb, - pipeline, - -1, 1, 1, -1); - /* NB: Cogl doesn't automatically support mid-scene modifications - * of textures and so we explicitly flush the drawn rectangle to the - * framebuffer now otherwise it may be batched until after the - * offscreen texture has been modified again. */ - cogl_flush (); - - /* Clear the offscreen framebuffer to blue using GLES2 before - * reading back from the onscreen framebuffer in case we mistakenly - * read from the offscreen framebuffer and get a false positive - */ - if (!cogl_push_gles2_context (test_ctx, - gles2_ctx, - offscreen, - offscreen, - &error)) - { - g_error ("Failed to push gles2 context: %s\n", error->message); - } - - gles2->glClearColor (0, 0, 1, 1); - gles2->glClear (GL_COLOR_BUFFER_BIT); - - cogl_pop_gles2_context (test_ctx); - - test_utils_check_pixel (test_fb, 0, 0, 0xff0000ff); - - /* Now copy the offscreen blue clear to the onscreen framebufer and - * check that too */ - cogl_framebuffer_draw_rectangle (test_fb, - pipeline, - -1, 1, 1, -1); - - test_utils_check_pixel (test_fb, 0, 0, 0x0000ffff); - - if (!cogl_push_gles2_context (test_ctx, - gles2_ctx, - test_fb, - test_fb, - &error)) - { - g_error ("Failed to push gles2 context: %s\n", error->message); - } - - gles2->glClearColor (1, 0, 1, 1); - gles2->glClear (GL_COLOR_BUFFER_BIT); - - cogl_pop_gles2_context (test_ctx); - - test_utils_check_pixel (test_fb, 0, 0, 0xff00ffff); - - - cogl_object_unref (gles2_ctx); - - cogl_object_unref (pipeline); -} - -static void -create_gles2_context (CoglTexture **offscreen_texture, - CoglOffscreen **offscreen, - CoglPipeline **pipeline, - CoglGLES2Context **gles2_ctx, - const CoglGLES2Vtable **gles2) -{ - CoglError *error = NULL; - - *offscreen_texture = - cogl_texture_2d_new_with_size (test_ctx, - cogl_framebuffer_get_width (test_fb), - cogl_framebuffer_get_height (test_fb)); - *offscreen = cogl_offscreen_new_with_texture (*offscreen_texture); - - *pipeline = cogl_pipeline_new (test_ctx); - cogl_pipeline_set_layer_texture (*pipeline, 0, *offscreen_texture); - - *gles2_ctx = cogl_gles2_context_new (test_ctx, &error); - if (!*gles2_ctx) - g_error ("Failed to create GLES2 context: %s\n", error->message); - - *gles2 = cogl_gles2_context_get_vtable (*gles2_ctx); -} - -static void -test_push_pop_multi_context (void) -{ - CoglTexture *offscreen_texture0; - CoglOffscreen *offscreen0; - CoglPipeline *pipeline0; - CoglGLES2Context *gles2_ctx0; - const CoglGLES2Vtable *gles20; - CoglTexture *offscreen_texture1; - CoglOffscreen *offscreen1; - CoglPipeline *pipeline1; - CoglGLES2Context *gles2_ctx1; - const CoglGLES2Vtable *gles21; - CoglError *error = NULL; - - create_gles2_context (&offscreen_texture0, - &offscreen0, - &pipeline0, - &gles2_ctx0, - &gles20); - - create_gles2_context (&offscreen_texture1, - &offscreen1, - &pipeline1, - &gles2_ctx1, - &gles21); - - cogl_framebuffer_clear4f (test_fb, COGL_BUFFER_BIT_COLOR, 1, 1, 1, 1); - - if (!cogl_push_gles2_context (test_ctx, - gles2_ctx0, - offscreen0, - offscreen0, - &error)) - { - g_error ("Failed to push gles2 context 0: %s\n", error->message); - } - - gles20->glClearColor (1, 0, 0, 1); - gles20->glClear (GL_COLOR_BUFFER_BIT); - - if (!cogl_push_gles2_context (test_ctx, - gles2_ctx1, - offscreen1, - offscreen1, - &error)) - { - g_error ("Failed to push gles2 context 1: %s\n", error->message); - } - - gles21->glClearColor (0, 1, 0, 1); - gles21->glClear (GL_COLOR_BUFFER_BIT); - - cogl_pop_gles2_context (test_ctx); - cogl_pop_gles2_context (test_ctx); - - test_utils_check_pixel (test_fb, 0, 0, 0xffffffff); - - cogl_framebuffer_draw_rectangle (test_fb, - pipeline0, - -1, 1, 1, -1); - - test_utils_check_pixel (test_fb, 0, 0, 0xff0000ff); - - cogl_framebuffer_draw_rectangle (test_fb, - pipeline1, - -1, 1, 1, -1); - - test_utils_check_pixel (test_fb, 0, 0, 0x00ff00ff); -} - -static GLuint -create_gles2_framebuffer (const CoglGLES2Vtable *gles2, - int width, - int height) -{ - GLuint texture_handle; - GLuint fbo_handle; - GLenum status; - - gles2->glGenTextures (1, &texture_handle); - gles2->glGenFramebuffers (1, &fbo_handle); - - gles2->glBindTexture (GL_TEXTURE_2D, texture_handle); - gles2->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - gles2->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - gles2->glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, - GL_UNSIGNED_BYTE, NULL); - gles2->glBindTexture (GL_TEXTURE_2D, 0); - - gles2->glBindFramebuffer (GL_FRAMEBUFFER, fbo_handle); - gles2->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, texture_handle, 0); - - status = gles2->glCheckFramebufferStatus (GL_FRAMEBUFFER); - if (cogl_test_verbose ()) - g_print ("status for gles2 framebuffer = 0x%x %s\n", - status, status == GL_FRAMEBUFFER_COMPLETE ? "(complete)" : "(?)"); - - gles2->glBindFramebuffer (GL_FRAMEBUFFER, 0); - - return fbo_handle; -} - -static void -test_gles2_read_pixels (void) -{ - CoglTexture *offscreen_texture; - CoglOffscreen *offscreen; - CoglPipeline *pipeline; - CoglGLES2Context *gles2_ctx; - const CoglGLES2Vtable *gles2; - CoglError *error = NULL; - GLubyte pixel[4]; - GLuint fbo_handle; - - create_gles2_context (&offscreen_texture, - &offscreen, - &pipeline, - &gles2_ctx, - &gles2); - - cogl_framebuffer_clear4f (test_fb, COGL_BUFFER_BIT_COLOR, 1, 1, 1, 1); - - if (!cogl_push_gles2_context (test_ctx, - gles2_ctx, - offscreen, - offscreen, - &error)) - { - g_error ("Failed to push gles2 context: %s\n", error->message); - } - - gles2->glClearColor (1, 0, 0, 1); - gles2->glClear (GL_COLOR_BUFFER_BIT); - gles2->glReadPixels (0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel); - - test_utils_compare_pixel (pixel, 0xff0000ff); - - fbo_handle = create_gles2_framebuffer (gles2, 256, 256); - - gles2->glBindFramebuffer (GL_FRAMEBUFFER, fbo_handle); - - gles2->glClearColor (0, 1, 0, 1); - gles2->glClear (GL_COLOR_BUFFER_BIT); - gles2->glReadPixels (0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel); - - test_utils_compare_pixel (pixel, 0x00ff00ff); - - gles2->glBindFramebuffer (GL_FRAMEBUFFER, 0); - - gles2->glClearColor (0, 1, 1, 1); - gles2->glClear (GL_COLOR_BUFFER_BIT); - gles2->glReadPixels (0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel); - - test_utils_compare_pixel (pixel, 0x00ffffff); - - cogl_pop_gles2_context (test_ctx); - - test_utils_check_pixel (test_fb, 0, 0, 0xffffffff); - - /* Bind different read and write buffers */ - if (!cogl_push_gles2_context (test_ctx, - gles2_ctx, - offscreen, - test_fb, - &error)) - { - g_error ("Failed to push gles2 context: %s\n", error->message); - } - - gles2->glReadPixels (0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel); - - test_utils_compare_pixel (pixel, 0x00ffffff); - - cogl_pop_gles2_context (test_ctx); - - test_utils_check_pixel (test_fb, 0, 0, 0xffffffff); - - /* Bind different read and write buffers (the other way around from - * before so when we test with COGL_TEST_ONSCREEN=1 we will read - * from an onscreen framebuffer) */ - if (!cogl_push_gles2_context (test_ctx, - gles2_ctx, - test_fb, - offscreen, - &error)) - { - g_error ("Failed to push gles2 context: %s\n", error->message); - } - - gles2->glReadPixels (0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel); - - test_utils_compare_pixel (pixel, 0xffffffff); - - cogl_pop_gles2_context (test_ctx); -} - -void -test_gles2_context (void) -{ - test_push_pop_single_context (); - test_push_pop_multi_context (); - test_gles2_read_pixels (); - - if (cogl_test_verbose ()) - g_print ("OK\n"); -} - -static GLuint -create_shader (const CoglGLES2Vtable *gles2, - GLenum type, - const char *source) -{ - GLuint shader; - GLint status; - int length = strlen (source); - - shader = gles2->glCreateShader (type); - gles2->glShaderSource (shader, 1, &source, &length); - gles2->glCompileShader (shader); - gles2->glGetShaderiv (shader, GL_COMPILE_STATUS, &status); - - if (!status) - { - char buf[512]; - - gles2->glGetShaderInfoLog (shader, sizeof (buf), NULL, buf); - - g_error ("Shader compilation failed:\n%s", buf); - } - - return shader; -} - -static GLuint -create_program (const CoglGLES2Vtable *gles2, - const char *vertex_shader_source, - const char *fragment_shader_source) -{ - GLuint fragment_shader, vertex_shader, program; - GLint status; - - vertex_shader = - create_shader (gles2, GL_VERTEX_SHADER, vertex_shader_source); - fragment_shader = - create_shader (gles2, GL_FRAGMENT_SHADER, fragment_shader_source); - - program = gles2->glCreateProgram (); - gles2->glAttachShader (program, vertex_shader); - gles2->glAttachShader (program, fragment_shader); - gles2->glLinkProgram (program); - - gles2->glGetProgramiv (program, GL_LINK_STATUS, &status); - - if (!status) - { - char buf[512]; - - gles2->glGetProgramInfoLog (program, sizeof (buf), NULL, buf); - - g_error ("Program linking failed:\n%s", buf); - } - - return program; -} - -typedef struct -{ - const CoglGLES2Vtable *gles2; - GLint color_location; - GLint pos_location; - int fb_width, fb_height; -} PaintData; - -typedef void (* PaintMethod) (PaintData *data); - -/* Top vertices are counter-clockwise */ -static const float top_vertices[] = - { - -1.0f, 0.0f, - 1.0f, 0.0f, - -1.0f, 1.0f, - 1.0f, 1.0f - }; -/* Bottom vertices are clockwise */ -static const float bottom_vertices[] = - { - 1.0f, 0.0f, - 1.0f, -1.0f, - -1.0f, 0.0f, - -1.0f, -1.0f - }; - -static void -paint_quads (PaintData *data) -{ - const CoglGLES2Vtable *gles2 = data->gles2; - - gles2->glEnableVertexAttribArray (data->pos_location); - - /* Paint the top half in red */ - gles2->glUniform4f (data->color_location, - 1.0f, 0.0f, 0.0f, 1.0f); - gles2->glVertexAttribPointer (data->pos_location, - 2, /* size */ - GL_FLOAT, - GL_FALSE, /* not normalized */ - sizeof (float) * 2, - top_vertices); - gles2->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4); - - /* Paint the bottom half in blue */ - gles2->glUniform4f (data->color_location, - 0.0f, 0.0f, 1.0f, 1.0f); - gles2->glVertexAttribPointer (data->pos_location, - 2, /* size */ - GL_FLOAT, - GL_FALSE, /* not normalized */ - sizeof (float) * 2, - bottom_vertices); - gles2->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4); -} - -static void -paint_viewport (PaintData *data) -{ - const CoglGLES2Vtable *gles2 = data->gles2; - int viewport[4]; - - /* Vertices to fill the entire framebuffer */ - static const float vertices[] = - { - -1.0f, -1.0f, - 1.0f, -1.0f, - -1.0f, 1.0f, - 1.0f, 1.0f - }; - - gles2->glEnableVertexAttribArray (data->pos_location); - gles2->glVertexAttribPointer (data->pos_location, - 2, /* size */ - GL_FLOAT, - GL_FALSE, /* not normalized */ - sizeof (float) * 2, - vertices); - - /* Paint the top half in red */ - gles2->glViewport (0, data->fb_height / 2, - data->fb_width, data->fb_height / 2); - gles2->glUniform4f (data->color_location, - 1.0f, 0.0f, 0.0f, 1.0f); - gles2->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4); - - /* Paint the bottom half in blue */ - gles2->glViewport (0, 0, data->fb_width, data->fb_height / 2); - gles2->glUniform4f (data->color_location, - 0.0f, 0.0f, 1.0f, 1.0f); - gles2->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4); - - gles2->glGetIntegerv (GL_VIEWPORT, viewport); - g_assert_cmpint (viewport[0], ==, 0.0f); - g_assert_cmpint (viewport[1], ==, 0.0f); - g_assert_cmpint (viewport[2], ==, data->fb_width); - g_assert_cmpint (viewport[3], ==, data->fb_height / 2); -} - -static void -paint_scissor (PaintData *data) -{ - const CoglGLES2Vtable *gles2 = data->gles2; - float scissor[4]; - - gles2->glEnable (GL_SCISSOR_TEST); - - /* Paint the top half in red */ - gles2->glScissor (0, data->fb_height / 2, - data->fb_width, data->fb_height / 2); - gles2->glClearColor (1.0, 0.0, 0.0, 1.0); - gles2->glClear (GL_COLOR_BUFFER_BIT); - - /* Paint the bottom half in blue */ - gles2->glScissor (0, 0, data->fb_width, data->fb_height / 2); - gles2->glClearColor (0.0, 0.0, 1.0, 1.0); - gles2->glClear (GL_COLOR_BUFFER_BIT); - - gles2->glGetFloatv (GL_SCISSOR_BOX, scissor); - g_assert_cmpfloat (scissor[0], ==, 0.0f); - g_assert_cmpfloat (scissor[1], ==, 0.0f); - g_assert_cmpfloat (scissor[2], ==, data->fb_width); - g_assert_cmpfloat (scissor[3], ==, data->fb_height / 2); -} - -static void -paint_cull (PaintData *data) -{ - const CoglGLES2Vtable *gles2 = data->gles2; - GLint front_face; - int i; - - gles2->glEnableVertexAttribArray (data->pos_location); - gles2->glEnable (GL_CULL_FACE); - - /* First time round we'll use GL_CCW as the front face so that the - * bottom quad will be culled */ - gles2->glFrontFace (GL_CCW); - gles2->glUniform4f (data->color_location, - 1.0f, 0.0f, 0.0f, 1.0f); - - gles2->glGetIntegerv (GL_FRONT_FACE, &front_face); - g_assert_cmpint (front_face, ==, GL_CCW); - - for (i = 0; i < 2; i++) - { - /* Paint both quads in the same color. One of these will be - * culled */ - gles2->glVertexAttribPointer (data->pos_location, - 2, /* size */ - GL_FLOAT, - GL_FALSE, /* not normalized */ - sizeof (float) * 2, - top_vertices); - gles2->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4); - - gles2->glVertexAttribPointer (data->pos_location, - 2, /* size */ - GL_FLOAT, - GL_FALSE, /* not normalized */ - sizeof (float) * 2, - bottom_vertices); - gles2->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4); - - /* Second time round we'll use GL_CW as the front face so that the - * top quad will be culled */ - gles2->glFrontFace (GL_CW); - gles2->glUniform4f (data->color_location, - 0.0f, 0.0f, 1.0f, 1.0f); - - gles2->glGetIntegerv (GL_FRONT_FACE, &front_face); - g_assert_cmpint (front_face, ==, GL_CW); - } -} - -static void -verify_read_pixels (const PaintData *data) -{ - int stride = data->fb_width * 4; - uint8_t *buf = malloc (data->fb_height * stride); - - data->gles2->glReadPixels (0, 0, /* x/y */ - data->fb_width, data->fb_height, - GL_RGBA, - GL_UNSIGNED_BYTE, - buf); - - /* In GL, the lines earlier in the buffer are the bottom */ - /* Bottom should be blue */ - test_utils_compare_pixel (buf + data->fb_width / 2 * 4 + - data->fb_height / 4 * stride, - 0x0000ffff); - /* Top should be red */ - test_utils_compare_pixel (buf + data->fb_width / 2 * 4 + - data->fb_height * 3 / 4 * stride, - 0xff0000ff); - - free (buf); -} - -void -test_gles2_context_fbo (void) -{ - static const char vertex_shader_source[] = - "attribute vec2 pos;\n" - "\n" - "void\n" - "main ()\n" - "{\n" - " gl_Position = vec4 (pos, 0.0, 1.0);\n" - "}\n"; - static const char fragment_shader_source[] = - "precision mediump float;\n" - "uniform vec4 color;\n" - "\n" - "void\n" - "main ()\n" - "{\n" - " gl_FragColor = color;\n" - "}\n"; - static const PaintMethod paint_methods[] = - { - paint_quads, - paint_viewport, - paint_scissor, - paint_cull - }; - int i; - PaintData data; - - data.fb_width = cogl_framebuffer_get_width (test_fb); - data.fb_height = cogl_framebuffer_get_height (test_fb); - - for (i = 0; i < G_N_ELEMENTS (paint_methods); i++) - { - CoglTexture *offscreen_texture; - CoglOffscreen *offscreen; - CoglPipeline *pipeline; - CoglGLES2Context *gles2_ctx; - GLuint program; - CoglError *error = NULL; - - create_gles2_context (&offscreen_texture, - &offscreen, - &pipeline, - &gles2_ctx, - &data.gles2); - - if (!cogl_push_gles2_context (test_ctx, - gles2_ctx, - offscreen, - offscreen, - &error)) - g_error ("Failed to push gles2 context: %s\n", error->message); - - program = create_program (data.gles2, - vertex_shader_source, - fragment_shader_source); - - data.gles2->glClearColor (1.0, 1.0, 0.0, 1.0); - data.gles2->glClear (GL_COLOR_BUFFER_BIT); - - data.gles2->glUseProgram (program); - - data.color_location = data.gles2->glGetUniformLocation (program, "color"); - if (data.color_location == -1) - g_error ("Couldn't find ‘color’ uniform"); - - data.pos_location = data.gles2->glGetAttribLocation (program, "pos"); - if (data.pos_location == -1) - g_error ("Couldn't find ‘pos’ attribute"); - - paint_methods[i] (&data); - - verify_read_pixels (&data); - - cogl_pop_gles2_context (test_ctx); - - cogl_object_unref (offscreen); - cogl_object_unref (gles2_ctx); - - cogl_framebuffer_draw_rectangle (test_fb, - pipeline, - -1.0f, 1.0f, - 1.0f, -1.0f); - - cogl_object_unref (pipeline); - cogl_object_unref (offscreen_texture); - - /* Top half of the framebuffer should be red */ - test_utils_check_pixel (test_fb, - data.fb_width / 2, data.fb_height / 4, - 0xff0000ff); - /* Bottom half should be blue */ - test_utils_check_pixel (test_fb, - data.fb_width / 2, data.fb_height * 3 / 4, - 0x0000ffff); - } -} - -/* Position to draw a rectangle in. The top half of this rectangle - * will be red, and the bottom will be blue */ -#define RECTANGLE_DRAW_X 10 -#define RECTANGLE_DRAW_Y 15 - -/* Position to copy the rectangle to in the destination texture */ -#define RECTANGLE_COPY_X 110 -#define RECTANGLE_COPY_Y 115 - -#define RECTANGLE_WIDTH 30 -#define RECTANGLE_HEIGHT 40 - -static void -verify_region (const CoglGLES2Vtable *gles2, - int x, - int y, - int width, - int height, - uint32_t expected_pixel) -{ - uint8_t *buf, *p; - - buf = malloc (width * height * 4); - - gles2->glReadPixels (x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buf); - - for (p = buf + width * height * 4; p > buf; p -= 4) - test_utils_compare_pixel (p - 4, expected_pixel); - - free (buf); -} - -void -test_gles2_context_copy_tex_image (void) -{ - static const char vertex_shader_source[] = - "attribute vec2 pos;\n" - "attribute vec2 tex_coord_attrib;\n" - "varying vec2 tex_coord_varying;\n" - "\n" - "void\n" - "main ()\n" - "{\n" - " gl_Position = vec4 (pos, 0.0, 1.0);\n" - " tex_coord_varying = tex_coord_attrib;\n" - "}\n"; - static const char fragment_shader_source[] = - "precision mediump float;\n" - "varying vec2 tex_coord_varying;\n" - "uniform sampler2D tex;\n" - "\n" - "void\n" - "main ()\n" - "{\n" - " gl_FragColor = texture2D (tex, tex_coord_varying);\n" - "}\n"; - static const float verts[] = - { - -1.0f, -1.0f, 0.0f, 0.0f, - 1.0f, -1.0f, 1.0f, 0.0f, - -1.0f, 1.0f, 0.0f, 1.0f, - 1.0f, 1.0f, 1.0f, 1.0f - }; - int fb_width = cogl_framebuffer_get_width (test_fb); - int fb_height = cogl_framebuffer_get_height (test_fb); - CoglTexture *offscreen_texture; - CoglOffscreen *offscreen; - CoglPipeline *pipeline; - CoglGLES2Context *gles2_ctx; - const CoglGLES2Vtable *gles2; - CoglError *error = NULL; - GLuint tex; - GLint tex_uniform_location; - GLint pos_location; - GLint tex_coord_location; - GLuint program; - - create_gles2_context (&offscreen_texture, - &offscreen, - &pipeline, - &gles2_ctx, - &gles2); - - if (!cogl_push_gles2_context (test_ctx, - gles2_ctx, - offscreen, - offscreen, - &error)) - g_error ("Failed to push gles2 context: %s\n", error->message); - - gles2->glClearColor (1.0, 1.0, 0.0, 1.0); - gles2->glClear (GL_COLOR_BUFFER_BIT); - - /* Draw a rectangle using clear and the scissor so that we don't - * have to create a shader */ - gles2->glEnable (GL_SCISSOR_TEST); - - /* Top half red */ - gles2->glScissor (RECTANGLE_DRAW_X, - RECTANGLE_DRAW_Y + RECTANGLE_HEIGHT / 2, - RECTANGLE_WIDTH, - RECTANGLE_HEIGHT / 2); - gles2->glClearColor (1.0, 0.0, 0.0, 1.0); - gles2->glClear (GL_COLOR_BUFFER_BIT); - /* Bottom half blue */ - gles2->glScissor (RECTANGLE_DRAW_X, - RECTANGLE_DRAW_Y, - RECTANGLE_WIDTH, - RECTANGLE_HEIGHT / 2); - gles2->glClearColor (0.0, 0.0, 1.0, 1.0); - gles2->glClear (GL_COLOR_BUFFER_BIT); - - /* Draw where the rectangle would be if the coordinates were flipped - * in white to make it obvious that that is the problem if the - * assertion fails */ - gles2->glScissor (RECTANGLE_DRAW_X, - fb_width - (RECTANGLE_DRAW_Y + RECTANGLE_HEIGHT), - RECTANGLE_WIDTH, - RECTANGLE_HEIGHT); - gles2->glClearColor (1.0, 1.0, 1.0, 1.0); - gles2->glClear (GL_COLOR_BUFFER_BIT); - - gles2->glDisable (GL_SCISSOR_TEST); - - /* Create a texture */ - gles2->glGenTextures (1, &tex); - gles2->glBindTexture (GL_TEXTURE_2D, tex); - gles2->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - gles2->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - /* Copy the entire framebuffer into the texture */ - gles2->glCopyTexImage2D (GL_TEXTURE_2D, - 0, /* level */ - GL_RGBA, - 0, 0, /* x/y */ - fb_width, fb_height, - 0 /* border */); - - /* Copy the rectangle into another part of the texture */ - gles2->glCopyTexSubImage2D (GL_TEXTURE_2D, - 0, /* level */ - RECTANGLE_COPY_X, - RECTANGLE_COPY_Y, - RECTANGLE_DRAW_X, - RECTANGLE_DRAW_Y, - RECTANGLE_WIDTH, - RECTANGLE_HEIGHT); - - /* Clear the framebuffer to make the test more thorough */ - gles2->glClearColor (1.0, 1.0, 0.0, 1.0); - gles2->glClear (GL_COLOR_BUFFER_BIT); - - /* Create a program to render the texture */ - program = create_program (gles2, - vertex_shader_source, - fragment_shader_source); - - pos_location = - gles2->glGetAttribLocation (program, "pos"); - if (pos_location == -1) - g_error ("Couldn't find ‘pos’ attribute"); - - tex_coord_location = - gles2->glGetAttribLocation (program, "tex_coord_attrib"); - if (tex_coord_location == -1) - g_error ("Couldn't find ‘tex_coord_attrib’ attribute"); - - tex_uniform_location = - gles2->glGetUniformLocation (program, "tex"); - if (tex_uniform_location == -1) - g_error ("Couldn't find ‘tex’ uniform"); - - gles2->glUseProgram (program); - - gles2->glUniform1i (tex_uniform_location, 0); - - /* Render the texture to fill the framebuffer */ - gles2->glEnableVertexAttribArray (pos_location); - gles2->glVertexAttribPointer (pos_location, - 2, /* n_components */ - GL_FLOAT, - FALSE, /* normalized */ - sizeof (float) * 4, - verts); - gles2->glEnableVertexAttribArray (tex_coord_location); - gles2->glVertexAttribPointer (tex_coord_location, - 2, /* n_components */ - GL_FLOAT, - FALSE, /* normalized */ - sizeof (float) * 4, - verts + 2); - - gles2->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4); - - /* Verify top of drawn rectangle is red */ - verify_region (gles2, - RECTANGLE_DRAW_X, - RECTANGLE_DRAW_Y + RECTANGLE_HEIGHT / 2, - RECTANGLE_WIDTH, - RECTANGLE_HEIGHT / 2, - 0xff0000ff); - /* Verify bottom of drawn rectangle is blue */ - verify_region (gles2, - RECTANGLE_DRAW_X, - RECTANGLE_DRAW_Y, - RECTANGLE_WIDTH, - RECTANGLE_HEIGHT / 2, - 0x0000ffff); - /* Verify top of copied rectangle is red */ - verify_region (gles2, - RECTANGLE_COPY_X, - RECTANGLE_COPY_Y + RECTANGLE_HEIGHT / 2, - RECTANGLE_WIDTH, - RECTANGLE_HEIGHT / 2, - 0xff0000ff); - /* Verify bottom of copied rectangle is blue */ - verify_region (gles2, - RECTANGLE_COPY_X, - RECTANGLE_COPY_Y, - RECTANGLE_WIDTH, - RECTANGLE_HEIGHT / 2, - 0x0000ffff); - - cogl_pop_gles2_context (test_ctx); - - cogl_object_unref (offscreen); - cogl_object_unref (gles2_ctx); - cogl_object_unref (pipeline); - cogl_object_unref (offscreen_texture); -} diff --git a/cogl/tests/conform/test-just-vertex-shader.c b/cogl/tests/conform/test-just-vertex-shader.c index 376a21556..2e9cab0e8 100644 --- a/cogl/tests/conform/test-just-vertex-shader.c +++ b/cogl/tests/conform/test-just-vertex-shader.c @@ -4,6 +4,7 @@ #include +#include "test-declarations.h" #include "test-utils.h" typedef struct _TestState @@ -26,90 +27,20 @@ create_dummy_texture (void) data); } -static void -paint_legacy (TestState *state) -{ - CoglHandle material = cogl_material_new (); - CoglTexture *tex; - CoglColor color; - CoglError *error = NULL; - CoglHandle shader, program; - - cogl_color_init_from_4ub (&color, 0, 0, 0, 255); - cogl_clear (&color, COGL_BUFFER_BIT_COLOR); - - /* Set the primary vertex color as red */ - cogl_color_set_from_4ub (&color, 0xff, 0x00, 0x00, 0xff); - cogl_material_set_color (material, &color); - - /* Override the vertex color in the texture environment with a - constant green color provided by a texture */ - tex = create_dummy_texture (); - cogl_material_set_layer (material, 0, tex); - cogl_object_unref (tex); - if (!cogl_material_set_layer_combine (material, 0, - "RGBA=REPLACE(TEXTURE)", - &error)) - { - g_warning ("Error setting layer combine: %s", error->message); - g_assert_not_reached (); - } - - /* Set up a dummy vertex shader that does nothing but the usual - fixed function transform */ - shader = cogl_create_shader (COGL_SHADER_TYPE_VERTEX); - cogl_shader_source (shader, - "void\n" - "main ()\n" - "{\n" - " cogl_position_out = " - "cogl_modelview_projection_matrix * " - "cogl_position_in;\n" - " cogl_color_out = cogl_color_in;\n" - " cogl_tex_coord_out[0] = cogl_tex_coord_in;\n" - "}\n"); - cogl_shader_compile (shader); - if (!cogl_shader_is_compiled (shader)) - { - char *log = cogl_shader_get_info_log (shader); - g_warning ("Shader compilation failed:\n%s", log); - free (log); - g_assert_not_reached (); - } - - program = cogl_create_program (); - cogl_program_attach_shader (program, shader); - cogl_program_link (program); - - cogl_handle_unref (shader); - - /* Draw something using the material */ - cogl_set_source (material); - cogl_rectangle (0, 0, 50, 50); - - /* Draw it again using the program. It should look exactly the same */ - cogl_program_use (program); - cogl_rectangle (50, 0, 100, 50); - cogl_program_use (COGL_INVALID_HANDLE); - - cogl_handle_unref (material); - cogl_handle_unref (program); -} - static void paint (TestState *state) { CoglPipeline *pipeline = cogl_pipeline_new (test_ctx); CoglTexture *tex; CoglColor color; - CoglError *error = NULL; + GError *error = NULL; CoglHandle shader, program; cogl_color_init_from_4ub (&color, 0, 0, 0, 255); - cogl_clear (&color, COGL_BUFFER_BIT_COLOR); + cogl_framebuffer_clear (test_fb, COGL_BUFFER_BIT_COLOR, &color); /* Set the primary vertex color as red */ - cogl_color_set_from_4ub (&color, 0xff, 0x00, 0x00, 0xff); + cogl_color_init_from_4ub (&color, 0xff, 0x00, 0x00, 0xff); cogl_pipeline_set_color (pipeline, &color); /* Override the vertex color in the texture environment with a @@ -138,31 +69,24 @@ paint (TestState *state) " cogl_color_out = cogl_color_in;\n" " cogl_tex_coord_out[0] = cogl_tex_coord_in;\n" "}\n"); - cogl_shader_compile (shader); - if (!cogl_shader_is_compiled (shader)) - { - char *log = cogl_shader_get_info_log (shader); - g_warning ("Shader compilation failed:\n%s", log); - free (log); - g_assert_not_reached (); - } program = cogl_create_program (); cogl_program_attach_shader (program, shader); cogl_program_link (program); - cogl_handle_unref (shader); + cogl_object_unref (shader); /* Draw something without the program */ - cogl_set_source (pipeline); - cogl_rectangle (0, 0, 50, 50); + cogl_framebuffer_draw_rectangle (test_fb, pipeline, + 0, 0, 50, 50); /* Draw it again using the program. It should look exactly the same */ cogl_pipeline_set_user_program (pipeline, program); - cogl_handle_unref (program); + cogl_object_unref (program); - cogl_rectangle (50, 0, 100, 50); - cogl_pipeline_set_user_program (pipeline, COGL_INVALID_HANDLE); + cogl_framebuffer_draw_rectangle (test_fb, pipeline, + 50, 0, 100, 50); + cogl_pipeline_set_user_program (pipeline, NULL); cogl_object_unref (pipeline); } @@ -188,18 +112,9 @@ test_just_vertex_shader (void) -1, 100); - /* XXX: we have to push/pop a framebuffer since this test currently - * uses the legacy cogl_rectangle() api. */ - cogl_push_framebuffer (test_fb); - - paint_legacy (&state); - validate_result (test_fb); - paint (&state); validate_result (test_fb); - cogl_pop_framebuffer (); - if (cogl_test_verbose ()) g_print ("OK\n"); } diff --git a/cogl/tests/conform/test-layer-remove.c b/cogl/tests/conform/test-layer-remove.c index de1efeccd..fbfdd6473 100644 --- a/cogl/tests/conform/test-layer-remove.c +++ b/cogl/tests/conform/test-layer-remove.c @@ -1,5 +1,6 @@ #include +#include "test-declarations.h" #include "test-utils.h" #define TEST_SQUARE_SIZE 10 diff --git a/cogl/tests/conform/test-map-buffer-range.c b/cogl/tests/conform/test-map-buffer-range.c index e9792405f..c4d28aaac 100644 --- a/cogl/tests/conform/test-map-buffer-range.c +++ b/cogl/tests/conform/test-map-buffer-range.c @@ -2,6 +2,7 @@ #include +#include "test-declarations.h" #include "test-utils.h" static uint8_t diff --git a/cogl/tests/conform/test-materials.c b/cogl/tests/conform/test-materials.c deleted file mode 100644 index e260683cb..000000000 --- a/cogl/tests/conform/test-materials.c +++ /dev/null @@ -1,253 +0,0 @@ -#include "cogl-config.h" - -#include -#include -#include - -#include "test-conform-common.h" - -static const ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff }; - -#define QUAD_WIDTH 20 - -#define RED 0 -#define GREEN 1 -#define BLUE 2 -#define ALPHA 3 - -#define MASK_RED(COLOR) ((COLOR & 0xff000000) >> 24) -#define MASK_GREEN(COLOR) ((COLOR & 0xff0000) >> 16) -#define MASK_BLUE(COLOR) ((COLOR & 0xff00) >> 8) -#define MASK_ALPHA(COLOR) (COLOR & 0xff) - -typedef struct _TestState -{ - ClutterGeometry stage_geom; -} TestState; - -static void -check_quad (int quad_x, int quad_y, uint32_t color) -{ - test_utils_check_pixel (x * QUAD_WIDTH + (QUAD_WIDTH / 2), - y * QUAD_WIDTH + (QUAD_WIDTH / 2), - color); -} - -static void -test_material_with_primitives (TestState *state, - int x, int y, - uint32_t color) -{ - CoglTextureVertex verts[4] = { - { .x = 0, .y = 0, .z = 0 }, - { .x = 0, .y = QUAD_WIDTH, .z = 0 }, - { .x = QUAD_WIDTH, .y = QUAD_WIDTH, .z = 0 }, - { .x = QUAD_WIDTH, .y = 0, .z = 0 }, - }; - CoglHandle vbo; - - cogl_push_matrix (); - - cogl_translate (x * QUAD_WIDTH, y * QUAD_WIDTH, 0); - - cogl_rectangle (0, 0, QUAD_WIDTH, QUAD_WIDTH); - - cogl_translate (0, QUAD_WIDTH, 0); - cogl_polygon (verts, 4, FALSE); - - cogl_translate (0, QUAD_WIDTH, 0); - vbo = cogl_vertex_buffer_new (4); - cogl_vertex_buffer_add (vbo, - "gl_Vertex", - 2, /* n components */ - COGL_ATTRIBUTE_TYPE_FLOAT, - FALSE, /* normalized */ - sizeof (CoglTextureVertex), /* stride */ - verts); - cogl_vertex_buffer_draw (vbo, - COGL_VERTICES_MODE_TRIANGLE_FAN, - 0, /* first */ - 4); /* count */ - cogl_handle_unref (vbo); - - cogl_pop_matrix (); - - check_quad (x, y, color); - check_quad (x, y+1, color); - check_quad (x, y+2, color); -} - -static void -test_invalid_texture_layers (TestState *state, int x, int y) -{ - CoglHandle material = cogl_material_new (); - - /* explicitly create a layer with an invalid handle. This may be desireable - * if the user also sets a texture combine string that e.g. refers to a - * constant color. */ - cogl_material_set_layer (material, 0, NULL); - - cogl_set_source (material); - - cogl_handle_unref (material); - - /* We expect a white fallback material to be used */ - test_material_with_primitives (state, x, y, 0xffffffff); -} - -static void -test_using_all_layers (TestState *state, int x, int y) -{ - CoglHandle material = cogl_material_new (); - uint8_t white_pixel[] = { 0xff, 0xff, 0xff, 0xff }; - uint8_t red_pixel[] = { 0xff, 0x00, 0x00, 0xff }; - CoglHandle white_texture; - CoglHandle red_texture; - GLint n_layers; - int i; - - /* Create a material that uses the maximum number of layers. All but - the last layer will use a solid white texture. The last layer - will use a red texture. The layers will all be modulated together - so the final fragment should be red. */ - - white_texture = test_utils_texture_new_from_data (1, 1, TEST_UTILS_TEXTURE_NONE, - COGL_PIXEL_FORMAT_RGBA_8888_PRE, - COGL_PIXEL_FORMAT_ANY, - 4, white_pixel); - red_texture = test_utils_texture_new_from_data (1, 1, TEST_UTILS_TEXTURE_NONE, - COGL_PIXEL_FORMAT_RGBA_8888_PRE, - COGL_PIXEL_FORMAT_ANY, - 4, red_pixel); - - /* FIXME: Cogl doesn't provide a way to query the maximum number of - texture layers so for now we'll just ask GL directly. */ -#ifdef HAVE_COGL_GLES2 - { - GLint n_image_units, n_attribs; - /* GLES 2 doesn't have GL_MAX_TEXTURE_UNITS and it uses - GL_MAX_TEXTURE_IMAGE_UNITS instead */ - glGetIntegerv (GL_MAX_TEXTURE_IMAGE_UNITS, &n_image_units); - /* Cogl needs a vertex attrib for each layer to upload the texture - coordinates */ - glGetIntegerv (GL_MAX_VERTEX_ATTRIBS, &n_attribs); - /* We can't use two of the attribs because they are used by the - position and color */ - n_attribs -= 2; - n_layers = MIN (n_attribs, n_image_units); - } -#else - glGetIntegerv (GL_MAX_TEXTURE_UNITS, &n_layers); -#endif - /* FIXME: is this still true? */ - /* Cogl currently can't cope with more than 32 layers so we'll also - limit the maximum to that. */ - if (n_layers > 32) - n_layers = 32; - - for (i = 0; i < n_layers; i++) - { - cogl_material_set_layer_filters (material, i, - COGL_MATERIAL_FILTER_NEAREST, - COGL_MATERIAL_FILTER_NEAREST); - cogl_material_set_layer (material, i, - i == n_layers - 1 ? red_texture : white_texture); - } - - cogl_set_source (material); - - cogl_handle_unref (material); - cogl_handle_unref (white_texture); - cogl_handle_unref (red_texture); - - /* We expect the final fragment to be red */ - test_material_with_primitives (state, x, y, 0xff0000ff); -} - -static void -test_invalid_texture_layers_with_constant_colors (TestState *state, - int x, int y) -{ - CoglHandle material = cogl_material_new (); - CoglColor constant_color; - - /* explicitly create a layer with an invalid handle */ - cogl_material_set_layer (material, 0, NULL); - - /* ignore the fallback texture on the layer and use a constant color - instead */ - cogl_color_init_from_4ub (&constant_color, 0, 0, 255, 255); - cogl_material_set_layer_combine (material, 0, - "RGBA=REPLACE(CONSTANT)", - NULL); - cogl_material_set_layer_combine_constant (material, 0, &constant_color); - - cogl_set_source (material); - - cogl_handle_unref (material); - - /* We expect the final fragments to be green */ - test_material_with_primitives (state, x, y, 0x0000ffff); -} - -static void -on_paint (ClutterActor *actor, TestState *state) -{ - test_invalid_texture_layers (state, - 0, 0 /* position */ - ); - test_invalid_texture_layers_with_constant_colors (state, - 1, 0 /* position */ - ); - test_using_all_layers (state, - 2, 0 /* position */ - ); - - /* Comment this out if you want visual feedback for what this test paints */ -#if 1 - clutter_main_quit (); -#endif -} - -static CoglBool -queue_redraw (void *stage) -{ - clutter_actor_queue_redraw (CLUTTER_ACTOR (stage)); - - return TRUE; -} - -void -test_materials (TestUtilsGTestFixture *fixture, - void *data) -{ - TestState state; - ClutterActor *stage; - ClutterActor *group; - unsigned int idle_source; - - stage = clutter_stage_get_default (); - - clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color); - clutter_actor_get_geometry (stage, &state.stage_geom); - - group = clutter_group_new (); - clutter_container_add_actor (CLUTTER_CONTAINER (stage), group); - - /* We force continuous redrawing of the stage, since we need to skip - * the first few frames, and we wont be doing anything else that - * will trigger redrawing. */ - idle_source = g_idle_add (queue_redraw, stage); - - g_signal_connect (group, "paint", G_CALLBACK (on_paint), &state); - - clutter_actor_show_all (stage); - - clutter_main (); - - g_source_remove (idle_source); - - if (cogl_test_verbose ()) - g_print ("OK\n"); -} - diff --git a/cogl/tests/conform/test-multitexture.c b/cogl/tests/conform/test-multitexture.c index 6ae949ebd..5a7a4eca2 100644 --- a/cogl/tests/conform/test-multitexture.c +++ b/cogl/tests/conform/test-multitexture.c @@ -28,7 +28,7 @@ assert_region_color (int x, uint8_t blue, uint8_t alpha) { - uint8_t *data = calloc (1, width * height * 4); + uint8_t *data = g_malloc0 (width * height * 4); cogl_read_pixels (x, y, width, height, COGL_READ_PIXELS_COLOR_BUFFER, COGL_PIXEL_FORMAT_RGBA_8888_PRE, @@ -43,7 +43,7 @@ assert_region_color (int x, pixel[BLUE] == blue); #endif } - free (data); + g_free (data); } /* Creates a texture divided into 4 quads with colors arranged as follows: @@ -68,7 +68,7 @@ make_texture (guchar ref) CoglHandle tex; guchar val; - tex_data = malloc (QUAD_WIDTH * QUAD_WIDTH * 16); + tex_data = g_malloc (QUAD_WIDTH * QUAD_WIDTH * 16); for (y = 0; y < QUAD_WIDTH * 2; y++) for (x = 0; x < QUAD_WIDTH * 2; x++) @@ -93,18 +93,20 @@ make_texture (guchar ref) QUAD_WIDTH * 8, tex_data); - free (tex_data); + g_free (tex_data); return tex; } static void -on_paint (ClutterActor *actor, TestState *state) +on_paint (ClutterActor *actor, + ClutterPaintContext *paint_context, + TestState *state) { CoglHandle tex0, tex1; CoglHandle material; - CoglBool status; - CoglError *error = NULL; + gboolean status; + GError *error = NULL; float tex_coords[] = { 0, 0, 0.5, 0.5, /* tex0 */ 0.5, 0.5, 1, 1 /* tex1 */ @@ -149,9 +151,9 @@ on_paint (ClutterActor *actor, TestState *state) cogl_rectangle_with_multitexture_coords (0, 0, QUAD_WIDTH, QUAD_WIDTH, tex_coords, 8); - cogl_handle_unref (material); - cogl_handle_unref (tex0); - cogl_handle_unref (tex1); + cogl_object_unref (material); + cogl_object_unref (tex0); + cogl_object_unref (tex1); /* See what we got... */ @@ -164,7 +166,7 @@ on_paint (ClutterActor *actor, TestState *state) #endif } -static CoglBool +static gboolean queue_redraw (void *stage) { clutter_actor_queue_redraw (CLUTTER_ACTOR (stage)); @@ -199,7 +201,7 @@ test_multitexture (TestUtilsGTestFixture *fixture, clutter_main (); - g_source_remove (idle_source); + g_clear_handle_id (&idle_source, g_source_remove); if (cogl_test_verbose ()) g_print ("OK\n"); diff --git a/cogl/tests/conform/test-npot-texture.c b/cogl/tests/conform/test-npot-texture.c index d2d01c555..551f72b7b 100644 --- a/cogl/tests/conform/test-npot-texture.c +++ b/cogl/tests/conform/test-npot-texture.c @@ -2,6 +2,7 @@ #include +#include "test-declarations.h" #include "test-utils.h" /* Non-power-of-two sized texture that should cause slicing */ @@ -60,7 +61,7 @@ make_texture (void) CoglTexture *tex; int partx, party, width, height; - p = tex_data = malloc (TEXTURE_SIZE * TEXTURE_SIZE * 4); + p = tex_data = g_malloc (TEXTURE_SIZE * TEXTURE_SIZE * 4); /* Make a texture with a different color for each part */ for (party = 0; party < PARTS; party++) @@ -95,7 +96,7 @@ make_texture (void) TEXTURE_SIZE * 4, tex_data); - free (tex_data); + g_free (tex_data); if (cogl_test_verbose ()) { @@ -105,10 +106,8 @@ make_texture (void) g_print ("Texture is not sliced\n"); } - /* The texture should be sliced unless NPOTs are supported */ - g_assert (cogl_has_feature (test_ctx, COGL_FEATURE_ID_TEXTURE_NPOT) - ? !cogl_texture_is_sliced (tex) - : cogl_texture_is_sliced (tex)); + /* The texture should be sliced unless NPOTs are supported, which they are */ + g_assert (!cogl_texture_is_sliced (tex)); return tex; } @@ -146,14 +145,6 @@ paint (void) void test_npot_texture (void) { - if (cogl_test_verbose ()) - { - if (cogl_has_feature (test_ctx, COGL_FEATURE_ID_TEXTURE_NPOT)) - g_print ("NPOT textures are supported\n"); - else - g_print ("NPOT textures are not supported\n"); - } - cogl_framebuffer_orthographic (test_fb, 0, 0, cogl_framebuffer_get_width (test_fb), diff --git a/cogl/tests/conform/test-offscreen.c b/cogl/tests/conform/test-offscreen.c index 9bc14b7da..d5f779947 100644 --- a/cogl/tests/conform/test-offscreen.c +++ b/cogl/tests/conform/test-offscreen.c @@ -2,6 +2,7 @@ #include +#include "test-declarations.h" #include "test-utils.h" #define RED 0 @@ -43,6 +44,8 @@ test_paint (TestState *state) CoglTexture2D *tex_2d; CoglTexture *tex; CoglOffscreen *offscreen; + CoglPipeline *opaque_pipeline; + CoglPipeline *texture_pipeline; tex_2d = cogl_texture_2d_new_with_size (test_ctx, state->fb_width, @@ -61,41 +64,41 @@ test_paint (TestState *state) * quarter of the window size and slide it to the top right of the * window. */ - cogl_push_matrix (); - cogl_translate (0.5, 0.5, 0); - cogl_scale (-0.5, 0.5, 1); - - cogl_push_framebuffer (offscreen); - - /* Cogl should release the last reference when we call cogl_pop_framebuffer() - */ - cogl_object_unref (offscreen); + cogl_framebuffer_push_matrix (test_fb); + cogl_framebuffer_translate (test_fb, 0.5, 0.5, 0); + cogl_framebuffer_scale (test_fb, -0.5, 0.5, 1); /* Setup something other than the identity matrix for the modelview so we can * verify it gets restored when we call cogl_pop_framebuffer () */ - cogl_scale (2, 2, 1); + cogl_framebuffer_scale (test_fb, 2, 2, 1); + opaque_pipeline = cogl_pipeline_new (test_ctx); /* red, top left */ - cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff); - cogl_rectangle (-0.5, 0.5, 0, 0); + cogl_pipeline_set_color4ub (opaque_pipeline, 0xff, 0x00, 0x00, 0xff); + cogl_framebuffer_draw_rectangle (offscreen, opaque_pipeline, -0.5, 0.5, 0, 0); /* green, top right */ - cogl_set_source_color4ub (0x00, 0xff, 0x00, 0xff); - cogl_rectangle (0, 0.5, 0.5, 0); + cogl_pipeline_set_color4ub (opaque_pipeline, 0x00, 0xff, 0x00, 0xff); + cogl_framebuffer_draw_rectangle (offscreen, opaque_pipeline, 0, 0.5, 0.5, 0); /* blue, bottom left */ - cogl_set_source_color4ub (0x00, 0x00, 0xff, 0xff); - cogl_rectangle (-0.5, 0, 0, -0.5); + cogl_pipeline_set_color4ub (opaque_pipeline, 0x00, 0x00, 0xff, 0xff); + cogl_framebuffer_draw_rectangle (offscreen, opaque_pipeline, -0.5, 0, 0, -0.5); /* white, bottom right */ - cogl_set_source_color4ub (0xff, 0xff, 0xff, 0xff); - cogl_rectangle (0, 0, 0.5, -0.5); + cogl_pipeline_set_color4ub (opaque_pipeline, 0xff, 0xff, 0xff, 0xff); + cogl_framebuffer_draw_rectangle (offscreen, opaque_pipeline, 0, 0, 0.5, -0.5); - cogl_pop_framebuffer (); + /* Cogl should release the last reference when we call cogl_pop_framebuffer() + */ + cogl_object_unref (offscreen); - cogl_set_source_texture (tex); - cogl_rectangle (-1, 1, 1, -1); + texture_pipeline = cogl_pipeline_new (test_ctx); + cogl_pipeline_set_layer_texture (texture_pipeline, 0, tex); + cogl_framebuffer_draw_rectangle (test_fb, texture_pipeline, -1, 1, 1, -1); + cogl_object_unref (opaque_pipeline); + cogl_object_unref (texture_pipeline); cogl_object_unref (tex_2d); - cogl_pop_matrix (); + cogl_framebuffer_pop_matrix (test_fb); /* NB: The texture is drawn flipped horizontally and scaled to fit in the * top right corner of the window. */ @@ -113,12 +116,16 @@ test_paint (TestState *state) static void test_flush (TestState *state) { + CoglPipeline *pipeline; CoglTexture2D *tex_2d; CoglTexture *tex; CoglOffscreen *offscreen; CoglColor clear_color; int i; + pipeline = cogl_pipeline_new (test_ctx); + cogl_pipeline_set_color4ub (pipeline, 255, 0, 0, 255); + for (i = 0; i < 3; i++) { /* This tests that rendering to a framebuffer and then reading back @@ -131,13 +138,10 @@ test_flush (TestState *state) offscreen = cogl_offscreen_new_with_texture (tex); - cogl_push_framebuffer (offscreen); - cogl_color_init_from_4ub (&clear_color, 0, 0, 0, 255); - cogl_clear (&clear_color, COGL_BUFFER_BIT_COLOR); + cogl_framebuffer_clear (offscreen, COGL_BUFFER_BIT_COLOR, &clear_color); - cogl_set_source_color4ub (255, 0, 0, 255); - cogl_rectangle (-1, -1, 1, 1); + cogl_framebuffer_draw_rectangle (offscreen, pipeline, -1, -1, 1, 1); if (i == 0) /* First time check using read pixels on the offscreen */ @@ -160,13 +164,11 @@ test_flush (TestState *state) 0xff0000ff); } - cogl_pop_framebuffer (); - if (i == 2) { /* Third time try drawing the texture to the screen */ - cogl_set_source_texture (tex); - cogl_rectangle (-1, -1, 1, 1); + cogl_framebuffer_draw_rectangle (test_fb, pipeline, + -1, -1, 1, 1); test_utils_check_region (test_fb, 2, 2, /* x/y */ state->fb_width - 4, @@ -177,6 +179,8 @@ test_flush (TestState *state) cogl_object_unref (tex_2d); cogl_object_unref (offscreen); } + + cogl_object_unref (pipeline); } void @@ -187,12 +191,8 @@ test_offscreen (void) state.fb_width = cogl_framebuffer_get_width (test_fb); state.fb_height = cogl_framebuffer_get_height (test_fb); - /* XXX: we have to push/pop a framebuffer since this test currently - * uses the legacy cogl_rectangle() api. */ - cogl_push_framebuffer (test_fb); test_paint (&state); test_flush (&state); - cogl_pop_framebuffer (); if (cogl_test_verbose ()) g_print ("OK\n"); diff --git a/cogl/tests/conform/test-path-clip.c b/cogl/tests/conform/test-path-clip.c index ec2106129..7fcb299a1 100644 --- a/cogl/tests/conform/test-path-clip.c +++ b/cogl/tests/conform/test-path-clip.c @@ -3,6 +3,7 @@ #include +#include "test-declarations.h" #include "test-utils.h" void diff --git a/cogl/tests/conform/test-path.c b/cogl/tests/conform/test-path.c index fd0b59032..f9287d4b4 100644 --- a/cogl/tests/conform/test-path.c +++ b/cogl/tests/conform/test-path.c @@ -3,6 +3,7 @@ #include +#include "test-declarations.h" #include "test-utils.h" #define BLOCK_SIZE 16 @@ -21,9 +22,7 @@ draw_path_at (CoglPath *path, CoglPipeline *pipeline, int x, int y) cogl_framebuffer_push_matrix (test_fb); cogl_framebuffer_translate (test_fb, x * BLOCK_SIZE, y * BLOCK_SIZE, 0.0f); - cogl_set_framebuffer (test_fb); - cogl_set_source (pipeline); - cogl_path_fill (path); + cogl_framebuffer_fill_path (test_fb, pipeline, path); cogl_framebuffer_pop_matrix (test_fb); } @@ -61,7 +60,7 @@ check_block (int block_x, int block_y, int block_mask) (y + TEST_INSET) * BLOCK_SIZE); char *screen_pixel = g_strdup_printf ("#%06x", GUINT32_FROM_BE (*p) >> 8); g_assert_cmpstr (screen_pixel, ==, intended_pixel); - free (screen_pixel); + g_free (screen_pixel); } } } @@ -177,7 +176,7 @@ paint (TestState *state) } static void -validate_result () +validate_result (void) { check_block (0, 0, 0x8 /* bottom right */); check_block (1, 0, 0xf /* all of them */); diff --git a/cogl/tests/conform/test-pipeline-cache-unrefs-texture.c b/cogl/tests/conform/test-pipeline-cache-unrefs-texture.c index 5d278dcd0..81abe99e1 100644 --- a/cogl/tests/conform/test-pipeline-cache-unrefs-texture.c +++ b/cogl/tests/conform/test-pipeline-cache-unrefs-texture.c @@ -1,5 +1,6 @@ #include +#include "test-declarations.h" #include "test-utils.h" /* Keep track of the number of textures that we've created and are diff --git a/cogl/tests/conform/test-pipeline-shader-state.c b/cogl/tests/conform/test-pipeline-shader-state.c index 4d1e5f2b7..7bf0e72e6 100644 --- a/cogl/tests/conform/test-pipeline-shader-state.c +++ b/cogl/tests/conform/test-pipeline-shader-state.c @@ -2,6 +2,7 @@ #include +#include "test-declarations.h" #include "test-utils.h" void diff --git a/cogl/tests/conform/test-pipeline-uniforms.c b/cogl/tests/conform/test-pipeline-uniforms.c index 4d660dc09..d2b5e8f4d 100644 --- a/cogl/tests/conform/test-pipeline-uniforms.c +++ b/cogl/tests/conform/test-pipeline-uniforms.c @@ -2,6 +2,7 @@ #include +#include "test-declarations.h" #include "test-utils.h" #define LONG_ARRAY_SIZE 128 @@ -100,8 +101,8 @@ create_pipeline_for_shader (TestState *state, const char *shader_source) cogl_pipeline_set_user_program (pipeline, program); - cogl_handle_unref (shader); - cogl_handle_unref (program); + cogl_object_unref (shader); + cogl_object_unref (program); return pipeline; } @@ -156,7 +157,7 @@ init_long_pipeline_state (TestState *state) state->long_uniform_locations[i] = cogl_pipeline_get_uniform_location (state->long_pipeline, uniform_name); - free (uniform_name); + g_free (uniform_name); } } diff --git a/cogl/tests/conform/test-pipeline-user-matrix.c b/cogl/tests/conform/test-pipeline-user-matrix.c index 024bbfc26..37304688a 100644 --- a/cogl/tests/conform/test-pipeline-user-matrix.c +++ b/cogl/tests/conform/test-pipeline-user-matrix.c @@ -2,6 +2,7 @@ #include +#include "test-declarations.h" #include "test-utils.h" typedef struct _TestState @@ -20,7 +21,7 @@ validate_result (TestState *state) /* The textures are setup so that when added together with the correct matrices then all of the pixels should be white. We can verify this by reading back the entire stage */ - pixels = malloc (state->width * state->height * 4); + pixels = g_malloc (state->width * state->height * 4); cogl_framebuffer_read_pixels (test_fb, 0, 0, state->width, state->height, COGL_PIXEL_FORMAT_RGBA_8888_PRE, @@ -30,7 +31,7 @@ validate_result (TestState *state) { screen_pixel = g_strdup_printf ("#%06x", GUINT32_FROM_BE (*p) >> 8); g_assert_cmpstr (screen_pixel, ==, intended_pixel); - free (screen_pixel); + g_free (screen_pixel); } } @@ -54,7 +55,7 @@ paint (TestState *state) CoglTexture *tex0, *tex1; CoglPipeline *pipeline; CoglMatrix matrix; - CoglError *error = NULL; + GError *error = NULL; cogl_framebuffer_orthographic (test_fb, 0, 0, diff --git a/cogl/tests/conform/test-pixel-buffer.c b/cogl/tests/conform/test-pixel-buffer.c index 89d3a5751..fab66cab3 100644 --- a/cogl/tests/conform/test-pixel-buffer.c +++ b/cogl/tests/conform/test-pixel-buffer.c @@ -1,6 +1,7 @@ #include #include +#include "test-declarations.h" #include "test-utils.h" #define BITMAP_SIZE 256 @@ -174,7 +175,7 @@ test_pixel_buffer_set_data (void) stride = cogl_bitmap_get_rowstride (bitmap); - data = malloc (stride * BITMAP_SIZE); + data = g_malloc (stride * BITMAP_SIZE); generate_bitmap_data (data, stride); @@ -184,7 +185,7 @@ test_pixel_buffer_set_data (void) stride * (BITMAP_SIZE - 1) + BITMAP_SIZE * 4); - free (data); + g_free (data); texture = create_texture_from_bitmap (bitmap); pipeline = create_pipeline_from_texture (texture); @@ -211,7 +212,7 @@ static CoglTexture * create_white_texture (void) { CoglTexture2D *texture; - uint8_t *data = malloc (BITMAP_SIZE * BITMAP_SIZE * 4); + uint8_t *data = g_malloc (BITMAP_SIZE * BITMAP_SIZE * 4); memset (data, 255, BITMAP_SIZE * BITMAP_SIZE * 4); @@ -223,7 +224,7 @@ create_white_texture (void) data, NULL); /* don't catch errors */ - free (data); + g_free (data); return texture; } diff --git a/cogl/tests/conform/test-point-size-attribute.c b/cogl/tests/conform/test-point-size-attribute.c index a08d1daa9..b5aeec69b 100644 --- a/cogl/tests/conform/test-point-size-attribute.c +++ b/cogl/tests/conform/test-point-size-attribute.c @@ -1,5 +1,6 @@ #include +#include "test-declarations.h" #include "test-utils.h" /* This test assumes the GL driver supports point sizes up to 16 @@ -29,6 +30,7 @@ calc_coord_offset (int pos, int pos_index, int point_size) } g_assert_not_reached (); + return 0; } static void @@ -42,7 +44,7 @@ verify_point_size (CoglFramebuffer *test_fb, for (y = 0; y < 4; y++) for (x = 0; x < 4; x++) { - CoglBool in_point = x >= 1 && x <= 2 && y >= 1 && y <= 2; + gboolean in_point = x >= 1 && x <= 2 && y >= 1 && y <= 2; uint32_t expected_pixel = in_point ? 0x00ff00ff : 0xff0000ff; test_utils_check_pixel (test_fb, diff --git a/cogl/tests/conform/test-point-size.c b/cogl/tests/conform/test-point-size.c index 49d083325..92148a0e6 100644 --- a/cogl/tests/conform/test-point-size.c +++ b/cogl/tests/conform/test-point-size.c @@ -1,5 +1,6 @@ #include +#include "test-declarations.h" #include "test-utils.h" /* This test assumes the GL driver supports point sizes up to 16 @@ -21,6 +22,7 @@ calc_coord_offset (int pos, int pos_index, int point_size) } g_assert_not_reached (); + return 0; } static void @@ -34,7 +36,7 @@ verify_point_size (CoglFramebuffer *test_fb, for (y = 0; y < 4; y++) for (x = 0; x < 4; x++) { - CoglBool in_point = x >= 1 && x <= 2 && y >= 1 && y <= 2; + gboolean in_point = x >= 1 && x <= 2 && y >= 1 && y <= 2; uint32_t expected_pixel = in_point ? 0x00ff00ff : 0xff0000ff; test_utils_check_pixel (test_fb, diff --git a/cogl/tests/conform/test-point-sprite.c b/cogl/tests/conform/test-point-sprite.c index 65ce9a859..ab4391ceb 100644 --- a/cogl/tests/conform/test-point-sprite.c +++ b/cogl/tests/conform/test-point-sprite.c @@ -1,5 +1,6 @@ #include +#include "test-declarations.h" #include "test-utils.h" #define POINT_SIZE 8 @@ -19,13 +20,13 @@ tex_data[3 * 2 * 2] = }; static void -do_test (CoglBool check_orientation, - CoglBool use_glsl) +do_test (gboolean check_orientation, + gboolean use_glsl) { int fb_width = cogl_framebuffer_get_width (test_fb); int fb_height = cogl_framebuffer_get_height (test_fb); CoglPrimitive *prim; - CoglError *error = NULL; + GError *error = NULL; CoglTexture2D *tex_2d; CoglPipeline *pipeline, *solid_pipeline; int tex_height; @@ -91,7 +92,7 @@ do_test (CoglBool check_orientation, } else { - CoglBool res = + gboolean res = cogl_pipeline_set_layer_point_sprite_coords_enabled (pipeline, /* layer_index */ 0, diff --git a/cogl/tests/conform/test-premult.c b/cogl/tests/conform/test-premult.c index 3f13233fa..70a67318a 100644 --- a/cogl/tests/conform/test-premult.c +++ b/cogl/tests/conform/test-premult.c @@ -2,6 +2,7 @@ #include +#include "test-declarations.h" #include "test-utils.h" #define QUAD_WIDTH 32 @@ -31,7 +32,7 @@ gen_tex_data (uint32_t color) uint8_t b = MASK_BLUE (color); uint8_t a = MASK_ALPHA (color); - tex_data = malloc (QUAD_WIDTH * QUAD_WIDTH * 4); + tex_data = g_malloc (QUAD_WIDTH * QUAD_WIDTH * 4); for (p = tex_data + QUAD_WIDTH * QUAD_WIDTH * 4; p > tex_data;) { @@ -66,7 +67,7 @@ make_texture (uint32_t color, cogl_texture_set_premultiplied (tex_2d, FALSE); cogl_object_unref (bmp); - free (tex_data); + g_free (tex_data); return tex_2d; } @@ -90,23 +91,11 @@ set_region (CoglTexture *tex, static void check_texture (CoglPipeline *pipeline, - CoglHandle material, int x, int y, CoglTexture *tex, uint32_t expected_result) { - /* Legacy */ - cogl_push_framebuffer (test_fb); - cogl_material_set_layer (material, 0, tex); - cogl_set_source (material); - cogl_rectangle (x * QUAD_WIDTH, - y * QUAD_WIDTH, - x * QUAD_WIDTH + QUAD_WIDTH, - y * QUAD_WIDTH + QUAD_WIDTH); - test_utils_check_pixel (test_fb, x * QUAD_WIDTH + QUAD_WIDTH / 2, y * QUAD_WIDTH + QUAD_WIDTH / 2, expected_result); - cogl_pop_framebuffer (); - /* New API */ cogl_pipeline_set_layer_texture (pipeline, 0, tex); cogl_framebuffer_draw_rectangle (test_fb, pipeline, @@ -121,7 +110,6 @@ void test_premult (void) { CoglPipeline *pipeline; - CoglHandle material; CoglTexture *tex; cogl_framebuffer_orthographic (test_fb, 0, 0, @@ -134,13 +122,6 @@ test_premult (void) COGL_BUFFER_BIT_COLOR, 1.0f, 1.0f, 1.0f, 1.0f); - /* Legacy */ - material = cogl_material_new (); - cogl_material_set_blend (material, - "RGBA = ADD (SRC_COLOR, 0)", NULL); - cogl_material_set_layer_combine (material, 0, - "RGBA = REPLACE (TEXTURE)", NULL); - /* New API */ pipeline = cogl_pipeline_new (test_ctx); cogl_pipeline_set_blend (pipeline, @@ -156,7 +137,7 @@ test_premult (void) tex = make_texture (0xff00ff80, COGL_PIXEL_FORMAT_RGBA_8888, /* src format */ TEXTURE_FLAG_SET_UNPREMULTIPLIED); - check_texture (pipeline, material, 0, 0, /* position */ + check_texture (pipeline, 0, 0, /* position */ tex, 0xff00ff80); /* expected */ @@ -169,7 +150,7 @@ test_premult (void) tex = make_texture (0xff00ff80, COGL_PIXEL_FORMAT_RGBA_8888, /* src format */ TEXTURE_FLAG_SET_PREMULTIPLIED); - check_texture (pipeline, material, 1, 0, /* position */ + check_texture (pipeline, 1, 0, /* position */ tex, 0x80008080); /* expected */ @@ -183,7 +164,7 @@ test_premult (void) tex = make_texture (0xff00ff80, COGL_PIXEL_FORMAT_RGBA_8888, /* src format */ 0); /* default premultiplied status */ - check_texture (pipeline, material, 2, 0, /* position */ + check_texture (pipeline, 2, 0, /* position */ tex, 0x80008080); /* expected */ @@ -197,7 +178,7 @@ test_premult (void) tex = make_texture (0x80008080, COGL_PIXEL_FORMAT_RGBA_8888_PRE, /* src format */ TEXTURE_FLAG_SET_PREMULTIPLIED); - check_texture (pipeline, material, 3, 0, /* position */ + check_texture (pipeline, 3, 0, /* position */ tex, 0x80008080); /* expected */ @@ -210,7 +191,7 @@ test_premult (void) tex = make_texture (0x80008080, COGL_PIXEL_FORMAT_RGBA_8888_PRE, /* src format */ TEXTURE_FLAG_SET_UNPREMULTIPLIED); - check_texture (pipeline, material, 4, 0, /* position */ + check_texture (pipeline, 4, 0, /* position */ tex, 0xff00ff80); /* expected */ @@ -224,7 +205,7 @@ test_premult (void) tex = make_texture (0x80008080, COGL_PIXEL_FORMAT_RGBA_8888_PRE, /* src format */ 0); /* default premultiplied status */ - check_texture (pipeline, material, 5, 0, /* position */ + check_texture (pipeline, 5, 0, /* position */ tex, 0x80008080); /* expected */ @@ -241,7 +222,7 @@ test_premult (void) if (cogl_test_verbose ()) g_print ("set_region (0xff00ff80, RGBA_8888)\n"); set_region (tex, 0xff00ff80, COGL_PIXEL_FORMAT_RGBA_8888); - check_texture (pipeline, material, 6, 0, /* position */ + check_texture (pipeline, 6, 0, /* position */ tex, 0xff00ff80); /* expected */ @@ -257,7 +238,7 @@ test_premult (void) if (cogl_test_verbose ()) g_print ("set_region (0x80008080, RGBA_8888_PRE)\n"); set_region (tex, 0x80008080, COGL_PIXEL_FORMAT_RGBA_8888_PRE); - check_texture (pipeline, material, 7, 0, /* position */ + check_texture (pipeline, 7, 0, /* position */ tex, 0xff00ff80); /* expected */ @@ -272,7 +253,7 @@ test_premult (void) if (cogl_test_verbose ()) g_print ("set_region (0x80008080, RGBA_8888_PRE)\n"); set_region (tex, 0x80008080, COGL_PIXEL_FORMAT_RGBA_8888_PRE); - check_texture (pipeline, material, 8, 0, /* position */ + check_texture (pipeline, 8, 0, /* position */ tex, 0x80008080); /* expected */ @@ -290,7 +271,7 @@ test_premult (void) if (cogl_test_verbose ()) g_print ("set_region (0xff00ff80, RGBA_8888)\n"); set_region (tex, 0xff00ff80, COGL_PIXEL_FORMAT_RGBA_8888); - check_texture (pipeline, material, 9, 0, /* position */ + check_texture (pipeline, 9, 0, /* position */ tex, 0x80008080); /* expected */ diff --git a/cogl/tests/conform/test-primitive-and-journal.c b/cogl/tests/conform/test-primitive-and-journal.c index f978cd5ee..c6c943605 100644 --- a/cogl/tests/conform/test-primitive-and-journal.c +++ b/cogl/tests/conform/test-primitive-and-journal.c @@ -1,5 +1,6 @@ #include +#include "test-declarations.h" #include "test-utils.h" typedef CoglVertexP2C4 Vertex; diff --git a/cogl/tests/conform/test-primitive.c b/cogl/tests/conform/test-primitive.c index 4151a4041..d013da310 100644 --- a/cogl/tests/conform/test-primitive.c +++ b/cogl/tests/conform/test-primitive.c @@ -2,6 +2,7 @@ #include #include +#include "test-declarations.h" #include "test-utils.h" typedef struct _TestState @@ -205,7 +206,7 @@ test_paint (TestState *state) cogl_object_unref (pipeline); } -static CoglBool +static gboolean get_attributes_cb (CoglPrimitive *prim, CoglAttribute *attrib, void *user_data) @@ -251,7 +252,7 @@ test_copy (TestState *state) 16, /* offset */ 2, /* components */ COGL_ATTRIBUTE_TYPE_FLOAT); - free (name); + g_free (name); } prim_a = cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_TRIANGLES, diff --git a/cogl/tests/conform/test-read-texture-formats.c b/cogl/tests/conform/test-read-texture-formats.c index f7940d3cd..9add8127d 100644 --- a/cogl/tests/conform/test-read-texture-formats.c +++ b/cogl/tests/conform/test-read-texture-formats.c @@ -1,6 +1,7 @@ #include #include +#include "test-declarations.h" #include "test-utils.h" /* @@ -60,8 +61,8 @@ test_read_short (CoglTexture2D *tex_2d, received_value_str = g_strdup_printf ("0x%04x", received_value); expected_value_str = g_strdup_printf ("0x%04x", expected_value); g_assert_cmpstr (received_value_str, ==, expected_value_str); - free (received_value_str); - free (expected_value_str); + g_free (received_value_str); + g_free (expected_value_str); } static void @@ -115,8 +116,8 @@ test_read_8888 (CoglTexture2D *tex_2d, received_value_str = g_strdup_printf ("0x%08x", received_pixel); expected_value_str = g_strdup_printf ("0x%08x", expected_pixel); g_assert_cmpstr (received_value_str, ==, expected_value_str); - free (received_value_str); - free (expected_value_str); + g_free (received_value_str); + g_free (expected_value_str); } static void @@ -154,8 +155,8 @@ test_read_int (CoglTexture2D *tex_2d, received_value_str = g_strdup_printf ("0x%08x", received_value); expected_value_str = g_strdup_printf ("0x%08x", expected_value); g_assert_cmpstr (received_value_str, ==, expected_value_str); - free (received_value_str); - free (expected_value_str); + g_free (received_value_str); + g_free (expected_value_str); } void diff --git a/cogl/tests/conform/test-readpixels.c b/cogl/tests/conform/test-readpixels.c index 2c5ea675b..4e861afc4 100644 --- a/cogl/tests/conform/test-readpixels.c +++ b/cogl/tests/conform/test-readpixels.c @@ -15,7 +15,9 @@ static const ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff }; static void -on_paint (ClutterActor *actor, void *state) +on_paint (ClutterActor *actor, + ClutterPaintContext *paint_context, + void *state) { float saved_viewport[4]; CoglMatrix saved_projection; @@ -43,14 +45,14 @@ on_paint (ClutterActor *actor, void *state) * verify is reading back grid of colors from a CoglOffscreen framebuffer */ - data = malloc (FRAMEBUFFER_WIDTH * 4 * FRAMEBUFFER_HEIGHT); + data = g_malloc (FRAMEBUFFER_WIDTH * 4 * FRAMEBUFFER_HEIGHT); tex = test_utils_texture_new_from_data (FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT, TEST_UTILS_TEXTURE_NO_SLICING, COGL_PIXEL_FORMAT_RGBA_8888, /* data fmt */ COGL_PIXEL_FORMAT_ANY, /* internal fmt */ FRAMEBUFFER_WIDTH * 4, /* rowstride */ data); - free (data); + g_free (data); offscreen = cogl_offscreen_new_with_texture (tex); cogl_push_framebuffer (offscreen); @@ -68,7 +70,7 @@ on_paint (ClutterActor *actor, void *state) cogl_set_source_color4ub (0xff, 0xff, 0xff, 0xff); cogl_rectangle (0, 0, 1, -1); - pixels = calloc (1, FRAMEBUFFER_WIDTH * 4 * FRAMEBUFFER_HEIGHT); + pixels = g_malloc0 (FRAMEBUFFER_WIDTH * 4 * FRAMEBUFFER_HEIGHT); cogl_read_pixels (0, 0, FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT, COGL_READ_PIXELS_COLOR_BUFFER, COGL_PIXEL_FORMAT_RGBA_8888_PRE, @@ -78,10 +80,10 @@ on_paint (ClutterActor *actor, void *state) g_assert_cmpint (pixels[FRAMEBUFFER_WIDTH - 1], ==, 0xff00ff00); g_assert_cmpint (pixels[(FRAMEBUFFER_HEIGHT - 1) * FRAMEBUFFER_WIDTH], ==, 0xffff0000); g_assert_cmpint (pixels[(FRAMEBUFFER_HEIGHT - 1) * FRAMEBUFFER_WIDTH + FRAMEBUFFER_WIDTH - 1], ==, 0xffffffff); - free (pixels); + g_free (pixels); cogl_pop_framebuffer (); - cogl_handle_unref (offscreen); + cogl_object_unref (offscreen); /* Now verify reading back from an onscreen framebuffer... */ @@ -89,7 +91,7 @@ on_paint (ClutterActor *actor, void *state) cogl_set_source_texture (tex); cogl_rectangle (-1, 1, 1, -1); - pixels = calloc (1, FRAMEBUFFER_WIDTH * 4 * FRAMEBUFFER_HEIGHT); + pixels = g_malloc0 (FRAMEBUFFER_WIDTH * 4 * FRAMEBUFFER_HEIGHT); cogl_read_pixels (0, 0, FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT, COGL_READ_PIXELS_COLOR_BUFFER, COGL_PIXEL_FORMAT_RGBA_8888_PRE, @@ -99,14 +101,14 @@ on_paint (ClutterActor *actor, void *state) g_assert_cmpint (pixels[FRAMEBUFFER_WIDTH - 1], ==, 0xff00ff00); g_assert_cmpint (pixels[(FRAMEBUFFER_HEIGHT - 1) * FRAMEBUFFER_WIDTH], ==, 0xffff0000); g_assert_cmpint (pixels[(FRAMEBUFFER_HEIGHT - 1) * FRAMEBUFFER_WIDTH + FRAMEBUFFER_WIDTH - 1], ==, 0xffffffff); - free (pixels); + g_free (pixels); /* Verify using BGR format */ cogl_set_source_texture (tex); cogl_rectangle (-1, 1, 1, -1); - pixelsc = calloc (1, FRAMEBUFFER_WIDTH * 3 * FRAMEBUFFER_HEIGHT); + pixelsc = g_malloc0 (FRAMEBUFFER_WIDTH * 3 * FRAMEBUFFER_HEIGHT); cogl_read_pixels (0, 0, FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT, COGL_READ_PIXELS_COLOR_BUFFER, COGL_PIXEL_FORMAT_BGR_888, @@ -120,9 +122,9 @@ on_paint (ClutterActor *actor, void *state) g_assert_cmpint (pixelsc[(FRAMEBUFFER_WIDTH - 1) * 3 + 1], ==, 0xff); g_assert_cmpint (pixelsc[(FRAMEBUFFER_WIDTH - 1) * 3 + 2], ==, 0x00); - free (pixelsc); + g_free (pixelsc); - cogl_handle_unref (tex); + cogl_object_unref (tex); /* Restore the viewport and matrices state */ cogl_set_viewport (saved_viewport[0], @@ -138,7 +140,7 @@ on_paint (ClutterActor *actor, void *state) clutter_main_quit (); } -static CoglBool +static gboolean queue_redraw (void *stage) { clutter_actor_queue_redraw (CLUTTER_ACTOR (stage)); @@ -165,12 +167,10 @@ test_readpixels (TestUtilsGTestFixture *fixture, clutter_actor_show (stage); clutter_main (); - g_source_remove (idle_source); + g_clear_handle_id (&idle_source, g_source_remove); /* Remove all of the actors from the stage */ - clutter_container_foreach (CLUTTER_CONTAINER (stage), - (ClutterCallback) clutter_actor_destroy, - NULL); + clutter_actor_remove_all_children (stage); if (cogl_test_verbose ()) g_print ("OK\n"); diff --git a/cogl/tests/conform/test-snippets.c b/cogl/tests/conform/test-snippets.c index 396f61a9f..9b19b221b 100644 --- a/cogl/tests/conform/test-snippets.c +++ b/cogl/tests/conform/test-snippets.c @@ -2,6 +2,7 @@ #include +#include "test-declarations.h" #include "test-utils.h" typedef struct _TestState @@ -158,9 +159,9 @@ lots_snippets (TestState *state) cogl_pipeline_add_snippet (pipeline, snippet); cogl_object_unref (snippet); - free (code); - free (uniform_name); - free (declarations); + g_free (code); + g_free (uniform_name); + g_free (declarations); } cogl_framebuffer_draw_rectangle (test_fb, pipeline, 30, 0, 40, 10); diff --git a/cogl/tests/conform/test-sparse-pipeline.c b/cogl/tests/conform/test-sparse-pipeline.c index 2b618dc50..5e694d83c 100644 --- a/cogl/tests/conform/test-sparse-pipeline.c +++ b/cogl/tests/conform/test-sparse-pipeline.c @@ -1,6 +1,7 @@ #include #include +#include "test-declarations.h" #include "test-utils.h" typedef struct _TestState diff --git a/cogl/tests/conform/test-sub-texture.c b/cogl/tests/conform/test-sub-texture.c index 728815bde..9e8d1164c 100644 --- a/cogl/tests/conform/test-sub-texture.c +++ b/cogl/tests/conform/test-sub-texture.c @@ -1,6 +1,7 @@ #include #include +#include "test-declarations.h" #include "test-utils.h" #define SOURCE_SIZE 32 @@ -29,7 +30,7 @@ static CoglTexture2D * create_source (TestState *state) { int dx, dy; - uint8_t *data = malloc (SOURCE_SIZE * SOURCE_SIZE * 4); + uint8_t *data = g_malloc (SOURCE_SIZE * SOURCE_SIZE * 4); CoglTexture2D *tex; /* Create a texture with a different coloured rectangle at each @@ -67,7 +68,7 @@ static CoglTexture2D * create_test_texture (TestState *state) { CoglTexture2D *tex; - uint8_t *data = malloc (256 * 256 * 4), *p = data; + uint8_t *data = g_malloc (256 * 256 * 4), *p = data; int x, y; /* Create a texture that is 256x256 where the red component ranges @@ -89,7 +90,7 @@ create_test_texture (TestState *state) 256 * 4, data, NULL); - free (data); + g_free (data); return tex; } @@ -169,7 +170,7 @@ validate_part (int xpos, int ypos, static uint8_t * create_update_data (void) { - uint8_t *data = malloc (256 * 256 * 4), *p = data; + uint8_t *data = g_malloc (256 * 256 * 4), *p = data; int x, y; /* Create some image data that is 256x256 where the blue component @@ -212,7 +213,7 @@ validate_result (TestState *state) corner_colors[division_num]); /* Sub sub texture */ - p = texture_data = malloc (10 * 10 * 4); + p = texture_data = g_malloc (10 * 10 * 4); cogl_flush (); cogl_framebuffer_read_pixels (test_fb, 0, SOURCE_SIZE * 2, 10, 10, @@ -225,7 +226,7 @@ validate_result (TestState *state) g_assert (*(p++) == y + 20); p += 2; } - free (texture_data); + g_free (texture_data); /* Try reading back the texture data */ sub_texture = cogl_sub_texture_new (test_ctx, @@ -236,7 +237,7 @@ validate_result (TestState *state) SOURCE_SIZE / 2); tex_width = cogl_texture_get_width (sub_texture); tex_height = cogl_texture_get_height (sub_texture); - p = texture_data = malloc (tex_width * tex_height * 4); + p = texture_data = g_malloc (tex_width * tex_height * 4); cogl_texture_get_data (sub_texture, COGL_PIXEL_FORMAT_RGBA_8888, tex_width * 4, @@ -253,7 +254,7 @@ validate_result (TestState *state) g_assert (color == reference); p += 4; } - free (texture_data); + g_free (texture_data); cogl_object_unref (sub_texture); /* Create a 256x256 test texture */ @@ -268,10 +269,10 @@ validate_result (TestState *state) 0, 0, 32, 32, 64, 64, 256, 256, COGL_PIXEL_FORMAT_RGBA_8888_PRE, 256 * 4, texture_data); - free (texture_data); + g_free (texture_data); cogl_object_unref (sub_texture); /* Get the texture data */ - p = texture_data = malloc (256 * 256 * 4); + p = texture_data = g_malloc (256 * 256 * 4); cogl_texture_get_data (test_tex, COGL_PIXEL_FORMAT_RGBA_8888_PRE, 256 * 4, texture_data); @@ -296,7 +297,7 @@ validate_result (TestState *state) g_assert ((*p++) == 255); } } - free (texture_data); + g_free (texture_data); cogl_object_unref (test_tex); } diff --git a/cogl/tests/conform/test-texture-3d.c b/cogl/tests/conform/test-texture-3d.c deleted file mode 100644 index ac5ab27f7..000000000 --- a/cogl/tests/conform/test-texture-3d.c +++ /dev/null @@ -1,274 +0,0 @@ -#include -#include - -#include "test-utils.h" - -#define TEX_WIDTH 4 -#define TEX_HEIGHT 8 -#define TEX_DEPTH 16 -/* Leave four bytes of padding between each row */ -#define TEX_ROWSTRIDE (TEX_WIDTH * 4 + 4) -/* Leave four rows of padding between each image */ -#define TEX_IMAGE_STRIDE ((TEX_HEIGHT + 4) * TEX_ROWSTRIDE) - -typedef struct _TestState -{ - int fb_width; - int fb_height; -} TestState; - -static CoglTexture3D * -create_texture_3d (CoglContext *context) -{ - int x, y, z; - uint8_t *data = malloc (TEX_IMAGE_STRIDE * TEX_DEPTH); - uint8_t *p = data; - CoglTexture3D *tex; - CoglError *error = NULL; - - for (z = 0; z < TEX_DEPTH; z++) - { - for (y = 0; y < TEX_HEIGHT; y++) - { - for (x = 0; x < TEX_WIDTH; x++) - { - /* Set red, green, blue to values based on x, y, z */ - *(p++) = 255 - x * 8; - *(p++) = y * 8; - *(p++) = 255 - z * 8; - /* Fully opaque */ - *(p++) = 0xff; - } - - /* Set the padding between rows to 0xde */ - memset (p, 0xde, TEX_ROWSTRIDE - (TEX_WIDTH * 4)); - p += TEX_ROWSTRIDE - (TEX_WIDTH * 4); - } - /* Set the padding between images to 0xad */ - memset (p, 0xba, TEX_IMAGE_STRIDE - (TEX_HEIGHT * TEX_ROWSTRIDE)); - p += TEX_IMAGE_STRIDE - (TEX_HEIGHT * TEX_ROWSTRIDE); - } - - tex = cogl_texture_3d_new_from_data (context, - TEX_WIDTH, TEX_HEIGHT, TEX_DEPTH, - COGL_PIXEL_FORMAT_RGBA_8888, - TEX_ROWSTRIDE, - TEX_IMAGE_STRIDE, - data, - &error); - - if (tex == NULL) - { - g_assert (error != NULL); - g_warning ("Failed to create 3D texture: %s", error->message); - g_assert_not_reached (); - } - - free (data); - - return tex; -} - -static void -draw_frame (TestState *state) -{ - CoglTexture *tex = create_texture_3d (test_ctx); - CoglPipeline *pipeline = cogl_pipeline_new (test_ctx); - typedef struct { float x, y, s, t, r; } Vert; - CoglPrimitive *primitive; - CoglAttributeBuffer *attribute_buffer; - CoglAttribute *attributes[2]; - Vert *verts, *v; - int i; - - cogl_pipeline_set_layer_texture (pipeline, 0, tex); - cogl_object_unref (tex); - cogl_pipeline_set_layer_filters (pipeline, 0, - COGL_PIPELINE_FILTER_NEAREST, - COGL_PIPELINE_FILTER_NEAREST); - - /* Render the texture repeated horizontally twice using a regular - cogl rectangle. This should end up with the r texture coordinates - as zero */ - cogl_framebuffer_draw_textured_rectangle (test_fb, pipeline, - 0.0f, 0.0f, TEX_WIDTH * 2, TEX_HEIGHT, - 0.0f, 0.0f, 2.0f, 1.0f); - - /* Render all of the images in the texture using coordinates from a - CoglPrimitive */ - v = verts = g_new (Vert, 4 * TEX_DEPTH); - for (i = 0; i < TEX_DEPTH; i++) - { - float r = (i + 0.5f) / TEX_DEPTH; - - v->x = i * TEX_WIDTH; - v->y = TEX_HEIGHT; - v->s = 0; - v->t = 0; - v->r = r; - v++; - - v->x = i * TEX_WIDTH; - v->y = TEX_HEIGHT * 2; - v->s = 0; - v->t = 1; - v->r = r; - v++; - - v->x = i * TEX_WIDTH + TEX_WIDTH; - v->y = TEX_HEIGHT * 2; - v->s = 1; - v->t = 1; - v->r = r; - v++; - - v->x = i * TEX_WIDTH + TEX_WIDTH; - v->y = TEX_HEIGHT; - v->s = 1; - v->t = 0; - v->r = r; - v++; - } - - attribute_buffer = cogl_attribute_buffer_new (test_ctx, - 4 * TEX_DEPTH * sizeof (Vert), - verts); - attributes[0] = cogl_attribute_new (attribute_buffer, - "cogl_position_in", - sizeof (Vert), - G_STRUCT_OFFSET (Vert, x), - 2, /* n_components */ - COGL_ATTRIBUTE_TYPE_FLOAT); - attributes[1] = cogl_attribute_new (attribute_buffer, - "cogl_tex_coord_in", - sizeof (Vert), - G_STRUCT_OFFSET (Vert, s), - 3, /* n_components */ - COGL_ATTRIBUTE_TYPE_FLOAT); - primitive = cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_TRIANGLES, - 6 * TEX_DEPTH, - attributes, - 2 /* n_attributes */); - - cogl_primitive_set_indices (primitive, - cogl_get_rectangle_indices (test_ctx, - TEX_DEPTH), - 6 * TEX_DEPTH); - - cogl_primitive_draw (primitive, test_fb, pipeline); - - free (verts); - - cogl_object_unref (primitive); - cogl_object_unref (attributes[0]); - cogl_object_unref (attributes[1]); - cogl_object_unref (attribute_buffer); - cogl_object_unref (pipeline); -} - -static void -validate_block (int block_x, int block_y, int z) -{ - int x, y; - - for (y = 0; y < TEX_HEIGHT; y++) - for (x = 0; x < TEX_WIDTH; x++) - test_utils_check_pixel_rgb (test_fb, - block_x * TEX_WIDTH + x, - block_y * TEX_HEIGHT + y, - 255 - x * 8, - y * 8, - 255 - z * 8); -} - -static void -validate_result (void) -{ - int i; - - validate_block (0, 0, 0); - - for (i = 0; i < TEX_DEPTH; i++) - validate_block (i, 1, i); -} - -static void -test_multi_texture (TestState *state) -{ - CoglPipeline *pipeline; - CoglTexture3D *tex_3d; - CoglTexture2D *tex_2d; - uint8_t tex_data[4]; - - cogl_framebuffer_clear4f (test_fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1); - - /* Tests a pipeline that is using multi-texturing to combine a 3D - texture with a 2D texture. The texture from another layer is - sampled with TEXTURE_? just to pick up a specific bug that was - happening with the ARBfp fragend */ - - pipeline = cogl_pipeline_new (test_ctx); - - tex_data[0] = 0xff; - tex_data[1] = 0x00; - tex_data[2] = 0x00; - tex_data[3] = 0xff; - tex_2d = cogl_texture_2d_new_from_data (test_ctx, - 1, 1, /* width/height */ - COGL_PIXEL_FORMAT_RGBA_8888_PRE, - 4, /* rowstride */ - tex_data, - NULL); - cogl_pipeline_set_layer_texture (pipeline, 0, tex_2d); - - tex_data[0] = 0x00; - tex_data[1] = 0xff; - tex_data[2] = 0x00; - tex_data[3] = 0xff; - tex_3d = cogl_texture_3d_new_from_data (test_ctx, - 1, 1, 1, /* width/height/depth */ - COGL_PIXEL_FORMAT_RGBA_8888_PRE, - 4, /* rowstride */ - 4, /* image_stride */ - tex_data, - NULL); - cogl_pipeline_set_layer_texture (pipeline, 1, tex_3d); - - cogl_pipeline_set_layer_combine (pipeline, 0, - "RGBA = REPLACE(PREVIOUS)", - NULL); - cogl_pipeline_set_layer_combine (pipeline, 1, - "RGBA = ADD(TEXTURE_0, TEXTURE_1)", - NULL); - - cogl_framebuffer_draw_rectangle (test_fb, pipeline, 0, 0, 10, 10); - - test_utils_check_pixel (test_fb, 5, 5, 0xffff00ff); - - cogl_object_unref (tex_2d); - cogl_object_unref (tex_3d); - cogl_object_unref (pipeline); -} - -void -test_texture_3d (void) -{ - TestState state; - - state.fb_width = cogl_framebuffer_get_width (test_fb); - state.fb_height = cogl_framebuffer_get_height (test_fb); - - cogl_framebuffer_orthographic (test_fb, - 0, 0, /* x_1, y_1 */ - state.fb_width, /* x_2 */ - state.fb_height /* y_2 */, - -1, 100 /* near/far */); - - draw_frame (&state); - validate_result (); - - test_multi_texture (&state); - - if (cogl_test_verbose ()) - g_print ("OK\n"); -} diff --git a/cogl/tests/conform/test-texture-get-set-data.c b/cogl/tests/conform/test-texture-get-set-data.c index b8f0b3182..6bc68b387 100644 --- a/cogl/tests/conform/test-texture-get-set-data.c +++ b/cogl/tests/conform/test-texture-get-set-data.c @@ -2,6 +2,7 @@ #include +#include "test-declarations.h" #include "test-utils.h" static void @@ -13,7 +14,7 @@ check_texture (int width, int height, TestUtilsTextureFlags flags) int rowstride; CoglBitmap *bmp; - p = data = malloc (width * height * 4); + p = data = g_malloc (width * height * 4); for (y = 0; y < height; y++) for (x = 0; x < width; x++) { @@ -125,7 +126,7 @@ check_texture (int width, int height, TestUtilsTextureFlags flags) } cogl_object_unref (tex); - free (data); + g_free (data); } void diff --git a/cogl/tests/conform/test-texture-mipmaps.c b/cogl/tests/conform/test-texture-mipmaps.c index 4f2964fbd..8db876315 100644 --- a/cogl/tests/conform/test-texture-mipmaps.c +++ b/cogl/tests/conform/test-texture-mipmaps.c @@ -18,7 +18,7 @@ typedef struct _TestState static CoglHandle make_texture (void) { - guchar *tex_data = malloc (TEX_SIZE * TEX_SIZE * 3), *p = tex_data; + guchar *tex_data = g_malloc (TEX_SIZE * TEX_SIZE * 3), *p = tex_data; CoglHandle tex; int x, y; @@ -39,13 +39,15 @@ make_texture (void) TEX_SIZE * 3, tex_data); - free (tex_data); + g_free (tex_data); return tex; } static void -on_paint (ClutterActor *actor, TestState *state) +on_paint (ClutterActor *actor, + ClutterPaintContext *paint_context, + TestState *state) { CoglHandle tex; CoglHandle material; @@ -54,7 +56,7 @@ on_paint (ClutterActor *actor, TestState *state) tex = make_texture (); material = cogl_material_new (); cogl_material_set_layer (material, 0, tex); - cogl_handle_unref (tex); + cogl_object_unref (tex); /* Render a 1x1 pixel quad without mipmaps */ cogl_set_source (material); @@ -68,7 +70,7 @@ on_paint (ClutterActor *actor, TestState *state) COGL_MATERIAL_FILTER_NEAREST); cogl_rectangle (1, 0, 2, 1); - cogl_handle_unref (material); + cogl_object_unref (material); /* Read back the two pixels we rendered */ cogl_read_pixels (0, 0, 2, 1, @@ -94,7 +96,7 @@ on_paint (ClutterActor *actor, TestState *state) #endif } -static CoglBool +static gboolean queue_redraw (void *stage) { clutter_actor_queue_redraw (CLUTTER_ACTOR (stage)); @@ -129,7 +131,7 @@ test_texture_mipmaps (TestUtilsGTestFixture *fixture, clutter_main (); - g_source_remove (idle_source); + g_clear_handle_id (&idle_source, g_source_remove); if (cogl_test_verbose ()) g_print ("OK\n"); diff --git a/cogl/tests/conform/test-texture-no-allocate.c b/cogl/tests/conform/test-texture-no-allocate.c index db5187f6e..de2f6e0e3 100644 --- a/cogl/tests/conform/test-texture-no-allocate.c +++ b/cogl/tests/conform/test-texture-no-allocate.c @@ -1,5 +1,6 @@ #include +#include "test-declarations.h" #include "test-utils.h" /* Tests that the various texture types can be freed without being @@ -18,7 +19,7 @@ test_texture_no_allocate (void) CoglTexture2D *texture_2d; GError *error = NULL; - tex_data = malloc (BIG_TEX_WIDTH * BIG_TEX_HEIGHT * 4); + tex_data = g_malloc (BIG_TEX_WIDTH * BIG_TEX_HEIGHT * 4); /* NB: if we make the atlas and sliced texture APIs public then this * could changed to explicitly use that instead of the magic texture @@ -37,13 +38,13 @@ test_texture_no_allocate (void) tex_data, &error); - free (tex_data); + g_free (tex_data); /* It's ok if this causes an error, we just don't want it to * crash */ if (texture == NULL) - cogl_error_free (error); + g_error_free (error); else cogl_object_unref (texture); @@ -59,22 +60,4 @@ test_texture_no_allocate (void) texture_2d = cogl_texture_2d_new_with_size (test_ctx, 64, 64); cogl_object_unref (texture_2d); - - /* 3D texture */ - if (cogl_has_feature (test_ctx, COGL_FEATURE_ID_TEXTURE_3D)) - { - CoglTexture3D *texture_3d = - cogl_texture_3d_new_with_size (test_ctx, - 64, 64, 64); - cogl_object_unref (texture_3d); - } - - /* Rectangle texture */ - if (cogl_has_feature (test_ctx, COGL_FEATURE_ID_TEXTURE_RECTANGLE)) - { - CoglTextureRectangle *texture_rect = - cogl_texture_rectangle_new_with_size (test_ctx, - 64, 64); - cogl_object_unref (texture_rect); - } } diff --git a/cogl/tests/conform/test-texture-pixmap-x11.c b/cogl/tests/conform/test-texture-pixmap-x11.c index 7f7e33203..d2b9d7ae5 100644 --- a/cogl/tests/conform/test-texture-pixmap-x11.c +++ b/cogl/tests/conform/test-texture-pixmap-x11.c @@ -83,12 +83,12 @@ update_pixmap (TestState *state) XFreeGC (state->display, black_gc); } -static CoglBool +static gboolean check_paint (TestState *state, int x, int y, int scale) { uint8_t *data, *p, update_value = 0; - p = data = malloc (PIXMAP_WIDTH * PIXMAP_HEIGHT * 4); + p = data = g_malloc (PIXMAP_WIDTH * PIXMAP_HEIGHT * 4); cogl_read_pixels (x, y, PIXMAP_WIDTH / scale, PIXMAP_HEIGHT / scale, COGL_READ_PIXELS_COLOR_BUFFER, @@ -125,7 +125,7 @@ check_paint (TestState *state, int x, int y, int scale) } } - free (data); + g_free (data); return update_value == 0x00; } @@ -140,7 +140,9 @@ check_paint (TestState *state, int x, int y, int scale) #define FRAME_COUNT_UPDATED 8 static void -on_paint (ClutterActor *actor, TestState *state) +on_paint (ClutterActor *actor, + ClutterPaintContext *paint_context, + TestState *state) { CoglHandle material; @@ -167,7 +169,7 @@ on_paint (ClutterActor *actor, TestState *state) if (state->frame_count >= 5) { - CoglBool big_updated, small_updated; + gboolean big_updated, small_updated; big_updated = check_paint (state, 0, 0, 1); small_updated = check_paint (state, 0, PIXMAP_HEIGHT, 4); @@ -187,7 +189,7 @@ on_paint (ClutterActor *actor, TestState *state) state->frame_count++; } -static CoglBool +static gboolean queue_redraw (void *stage) { clutter_actor_queue_redraw (CLUTTER_ACTOR (stage)); @@ -205,7 +207,7 @@ test_texture_pixmap_x11 (TestUtilsGTestFixture *fixture, TestState state; unsigned int idle_handler; - unsigned int paint_handler; + unsigned long paint_handler; state.frame_count = 0; state.stage = clutter_stage_get_default (); @@ -226,9 +228,9 @@ test_texture_pixmap_x11 (TestUtilsGTestFixture *fixture, clutter_main (); - g_signal_handler_disconnect (state.stage, paint_handler); + g_clear_signal_handler (&paint_handler, state.stage); - g_source_remove (idle_handler); + g_clear_handle_id (&idle_handler, g_source_remove); XFreePixmap (state.display, state.pixmap); diff --git a/cogl/tests/conform/test-texture-rectangle.c b/cogl/tests/conform/test-texture-rectangle.c deleted file mode 100644 index 39d366e29..000000000 --- a/cogl/tests/conform/test-texture-rectangle.c +++ /dev/null @@ -1,276 +0,0 @@ -#include -#include - -#include "test-conform-common.h" - -static const ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff }; - -typedef struct _TestState -{ - ClutterActor *stage; -} TestState; - -static CoglHandle -create_source_rect (void) -{ -#ifdef GL_TEXTURE_RECTANGLE_ARB - - int x, y; - GLint prev_unpack_row_length; - GLint prev_unpack_alignment; - GLint prev_unpack_skip_rows; - GLint prev_unpack_skip_pixles; - GLint prev_rectangle_binding; - uint8_t *data = malloc (256 * 256 * 4), *p = data; - CoglHandle tex; - GLuint gl_tex; - - for (y = 0; y < 256; y++) - for (x = 0; x < 256; x++) - { - *(p++) = x; - *(p++) = y; - *(p++) = 0; - *(p++) = 255; - } - - /* We are about to use OpenGL directly to create a TEXTURE_RECTANGLE - * texture so we need to save the state that we modify so we can - * restore it afterwards and be sure not to interfere with any state - * caching that Cogl may do internally. - */ - glGetIntegerv (GL_UNPACK_ROW_LENGTH, &prev_unpack_row_length); - glGetIntegerv (GL_UNPACK_ALIGNMENT, &prev_unpack_alignment); - glGetIntegerv (GL_UNPACK_SKIP_ROWS, &prev_unpack_skip_rows); - glGetIntegerv (GL_UNPACK_SKIP_PIXELS, &prev_unpack_skip_pixles); - glGetIntegerv (GL_TEXTURE_BINDING_RECTANGLE_ARB, &prev_rectangle_binding); - - glPixelStorei (GL_UNPACK_ROW_LENGTH, 256); - glPixelStorei (GL_UNPACK_ALIGNMENT, 8); - glPixelStorei (GL_UNPACK_SKIP_ROWS, 0); - glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0); - - glGenTextures (1, &gl_tex); - glBindTexture (GL_TEXTURE_RECTANGLE_ARB, gl_tex); - glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, - GL_RGBA, 256, 256, 0, - GL_RGBA, - GL_UNSIGNED_BYTE, - data); - - /* Now restore the original GL state as Cogl had left it */ - glPixelStorei (GL_UNPACK_ROW_LENGTH, prev_unpack_row_length); - glPixelStorei (GL_UNPACK_ALIGNMENT, prev_unpack_alignment); - glPixelStorei (GL_UNPACK_SKIP_ROWS, prev_unpack_skip_rows); - glPixelStorei (GL_UNPACK_SKIP_PIXELS, prev_unpack_skip_pixles); - glBindTexture (GL_TEXTURE_RECTANGLE_ARB, prev_rectangle_binding); - - g_assert (glGetError () == GL_NO_ERROR); - - free (data); - - tex = test_utils_texture_new_from_foreign (gl_tex, - GL_TEXTURE_RECTANGLE_ARB, - 256, 256, 0, 0, - COGL_PIXEL_FORMAT_RGBA_8888); - - return tex; - -#else /* GL_TEXTURE_RECTANGLE_ARB */ - - return NULL; - -#endif /* GL_TEXTURE_RECTANGLE_ARB */ -} - -static CoglHandle -create_source_2d (void) -{ - int x, y; - uint8_t *data = malloc (256 * 256 * 4), *p = data; - CoglHandle tex; - - for (y = 0; y < 256; y++) - for (x = 0; x < 256; x++) - { - *(p++) = 0; - *(p++) = x; - *(p++) = y; - *(p++) = 255; - } - - tex = test_utils_texture_new_from_data (256, 256, TEST_UTILS_TEXTURE_NONE, - COGL_PIXEL_FORMAT_RGBA_8888_PRE, - COGL_PIXEL_FORMAT_ANY, - 256 * 4, - data); - - free (data); - - return tex; -} - -static void -draw_frame (TestState *state) -{ - GLuint gl_tex; - CoglHandle tex_rect = create_source_rect (); - CoglHandle material_rect = cogl_material_new (); - CoglHandle tex_2d = create_source_2d (); - CoglHandle material_2d = cogl_material_new (); - - g_assert (tex_rect != NULL); - - cogl_material_set_layer (material_rect, 0, tex_rect); - cogl_material_set_layer_filters (material_rect, 0, - COGL_MATERIAL_FILTER_NEAREST, - COGL_MATERIAL_FILTER_NEAREST); - - cogl_material_set_layer (material_2d, 0, tex_2d); - cogl_material_set_layer_filters (material_2d, 0, - COGL_MATERIAL_FILTER_NEAREST, - COGL_MATERIAL_FILTER_NEAREST); - - cogl_set_source (material_rect); - - /* Render the texture repeated horizontally twice */ - cogl_rectangle_with_texture_coords (0.0f, 0.0f, 512.0f, 256.0f, - 0.0f, 0.0f, 2.0f, 1.0f); - /* Render the top half of the texture to test without repeating */ - cogl_rectangle_with_texture_coords (0.0f, 256.0f, 256.0f, 384.0f, - 0.0f, 0.0f, 1.0f, 0.5f); - - cogl_set_source (material_2d); - - /* Render the top half of a regular 2D texture */ - cogl_rectangle_with_texture_coords (256.0f, 256.0f, 512.0f, 384.0f, - 0.0f, 0.0f, 1.0f, 0.5f); - - /* Flush the rendering now so we can safely delete the texture */ - cogl_flush (); - - cogl_handle_unref (material_rect); - - /* Cogl doesn't destroy foreign textures so we have to do it manually */ - cogl_texture_get_gl_texture (tex_rect, &gl_tex, NULL); - glDeleteTextures (1, &gl_tex); - cogl_handle_unref (tex_rect); -} - -static void -validate_result (TestState *state) -{ - uint8_t *data, *p; - int x, y; - - p = data = malloc (512 * 384 * 4); - - cogl_read_pixels (0, 0, 512, 384, - COGL_READ_PIXELS_COLOR_BUFFER, - COGL_PIXEL_FORMAT_RGBA_8888, - data); - - for (y = 0; y < 384; y++) - for (x = 0; x < 512; x++) - { - if (x >= 256 && y >= 256) - { - g_assert_cmpint (p[0], ==, 0); - g_assert_cmpint (p[1], ==, x & 0xff); - g_assert_cmpint (p[2], ==, y & 0xff); - } - else - { - g_assert_cmpint (p[0], ==, x & 0xff); - g_assert_cmpint (p[1], ==, y & 0xff); - g_assert_cmpint (p[2], ==, 0); - } - p += 4; - } - - free (data); - - /* Comment this out to see what the test paints */ - clutter_main_quit (); -} - -static void -on_paint (ClutterActor *actor, TestState *state) -{ - draw_frame (state); - - validate_result (state); -} - -static CoglBool -queue_redraw (void *stage) -{ - clutter_actor_queue_redraw (CLUTTER_ACTOR (stage)); - - return TRUE; -} - -static CoglBool -check_rectangle_extension (void) -{ - static const char rect_extension[] = "GL_ARB_texture_rectangle"; - const char *extensions = (const char *) glGetString (GL_EXTENSIONS); - const char *extensions_end; - - extensions_end = extensions + strlen (extensions); - - while (extensions < extensions_end) - { - const char *end = strchr (extensions, ' '); - - if (end == NULL) - end = extensions_end; - - if (end - extensions == sizeof (rect_extension) - 1 && - !memcmp (extensions, rect_extension, sizeof (rect_extension) - 1)) - return TRUE; - - extensions = end + 1; - } - - return FALSE; -} - -void -test_texture_rectangle (TestUtilsGTestFixture *fixture, - void *data) -{ - TestState state; - unsigned int idle_source; - unsigned int paint_handler; - - state.stage = clutter_stage_get_default (); - - /* Check whether GL supports the rectangle extension. If not we'll - just assume the test passes */ - if (check_rectangle_extension ()) - { - clutter_stage_set_color (CLUTTER_STAGE (state.stage), &stage_color); - - /* We force continuous redrawing of the stage, since we need to skip - * the first few frames, and we wont be doing anything else that - * will trigger redrawing. */ - idle_source = g_idle_add (queue_redraw, state.stage); - - paint_handler = g_signal_connect_after (state.stage, "paint", - G_CALLBACK (on_paint), &state); - - clutter_actor_show_all (state.stage); - - clutter_main (); - - g_source_remove (idle_source); - g_signal_handler_disconnect (state.stage, paint_handler); - - if (cogl_test_verbose ()) - g_print ("OK\n"); - } - else if (cogl_test_verbose ()) - g_print ("Skipping\n"); -} - diff --git a/cogl/tests/conform/test-texture-rg.c b/cogl/tests/conform/test-texture-rg.c index 72a5ae930..e3ed2b529 100644 --- a/cogl/tests/conform/test-texture-rg.c +++ b/cogl/tests/conform/test-texture-rg.c @@ -2,6 +2,7 @@ #include +#include "test-declarations.h" #include "test-utils.h" #define TEX_WIDTH 8 diff --git a/cogl/tests/conform/test-version.c b/cogl/tests/conform/test-version.c index c316de203..afc87914a 100644 --- a/cogl/tests/conform/test-version.c +++ b/cogl/tests/conform/test-version.c @@ -1,5 +1,6 @@ #include +#include "test-declarations.h" #include "test-utils.h" #include "cogl-config.h" @@ -12,13 +13,6 @@ #include #undef __COGL_H_INSIDE__ -_COGL_STATIC_ASSERT (COGL_VERSION_ENCODE (COGL_VERSION_MAJOR, - COGL_VERSION_MINOR, - COGL_VERSION_MICRO) == - COGL_VERSION, - "The pre-encoded Cogl version does not match the version " - "encoding macro"); - _COGL_STATIC_ASSERT (COGL_VERSION_GET_MAJOR (COGL_VERSION_ENCODE (100, 200, 300)) == @@ -37,45 +31,3 @@ _COGL_STATIC_ASSERT (COGL_VERSION_GET_MICRO (COGL_VERSION_ENCODE (100, 300, "Getting the micro component out of a encoded version " "does not work"); - -_COGL_STATIC_ASSERT (COGL_VERSION_CHECK (COGL_VERSION_MAJOR, - COGL_VERSION_MINOR, - COGL_VERSION_MICRO), - "Checking the Cogl version against the current version " - "does not pass"); -_COGL_STATIC_ASSERT (!COGL_VERSION_CHECK (COGL_VERSION_MAJOR, - COGL_VERSION_MINOR, - COGL_VERSION_MICRO + 1), - "Checking the Cogl version against a later micro version " - "should not pass"); -_COGL_STATIC_ASSERT (!COGL_VERSION_CHECK (COGL_VERSION_MAJOR, - COGL_VERSION_MINOR + 1, - COGL_VERSION_MICRO), - "Checking the Cogl version against a later minor version " - "should not pass"); -_COGL_STATIC_ASSERT (!COGL_VERSION_CHECK (COGL_VERSION_MAJOR + 1, - COGL_VERSION_MINOR, - COGL_VERSION_MICRO), - "Checking the Cogl version against a later major version " - "should not pass"); - -_COGL_STATIC_ASSERT (COGL_VERSION_CHECK (COGL_VERSION_MAJOR - 1, - COGL_VERSION_MINOR, - COGL_VERSION_MICRO), - "Checking the Cogl version against a older major version " - "should pass"); - -void -test_version (void) -{ - const char *version = g_strdup_printf ("version = %i.%i.%i", - COGL_VERSION_MAJOR, - COGL_VERSION_MINOR, - COGL_VERSION_MICRO); - - g_assert_cmpstr (version, ==, "version = " COGL_VERSION_STRING); - - if (cogl_test_verbose ()) - g_print ("OK\n"); -} - diff --git a/cogl/tests/conform/test-vertex-buffer-contiguous.c b/cogl/tests/conform/test-vertex-buffer-contiguous.c deleted file mode 100644 index 1cd7b456b..000000000 --- a/cogl/tests/conform/test-vertex-buffer-contiguous.c +++ /dev/null @@ -1,257 +0,0 @@ - -#include -#include - -#include "test-conform-common.h" - -/* This test verifies that the simplest usage of the vertex buffer API, - * where we add contiguous (x,y) GLfloat vertices, and RGBA GLubyte color - * attributes to a buffer, submit, and draw. - * - * It also tries to verify that the enable/disable attribute APIs are working - * too. - * - * If you want visual feedback of what this test paints for debugging purposes, - * then remove the call to clutter_main_quit() in validate_result. - */ - -typedef struct _TestState -{ - CoglHandle buffer; - CoglHandle texture; - CoglHandle material; - ClutterGeometry stage_geom; -} TestState; - -static void -validate_result (TestState *state) -{ - GLubyte pixel[4]; - GLint y_off = 90; - - if (cogl_test_verbose ()) - g_print ("y_off = %d\n", y_off); - - /* NB: We ignore the alpha, since we don't know if our render target is - * RGB or RGBA */ - -#define RED 0 -#define GREEN 1 -#define BLUE 2 - - /* Should see a blue pixel */ - cogl_read_pixels (10, y_off, 1, 1, - COGL_READ_PIXELS_COLOR_BUFFER, - COGL_PIXEL_FORMAT_RGBA_8888_PRE, - pixel); - if (cogl_test_verbose ()) - g_print ("pixel 0 = %x, %x, %x\n", pixel[RED], pixel[GREEN], pixel[BLUE]); - g_assert (pixel[RED] == 0 && pixel[GREEN] == 0 && pixel[BLUE] != 0); - - /* Should see a red pixel */ - cogl_read_pixels (110, y_off, 1, 1, - COGL_READ_PIXELS_COLOR_BUFFER, - COGL_PIXEL_FORMAT_RGBA_8888_PRE, - pixel); - if (cogl_test_verbose ()) - g_print ("pixel 1 = %x, %x, %x\n", pixel[RED], pixel[GREEN], pixel[BLUE]); - g_assert (pixel[RED] != 0 && pixel[GREEN] == 0 && pixel[BLUE] == 0); - - /* Should see a blue pixel */ - cogl_read_pixels (210, y_off, 1, 1, - COGL_READ_PIXELS_COLOR_BUFFER, - COGL_PIXEL_FORMAT_RGBA_8888_PRE, - pixel); - if (cogl_test_verbose ()) - g_print ("pixel 2 = %x, %x, %x\n", pixel[RED], pixel[GREEN], pixel[BLUE]); - g_assert (pixel[RED] == 0 && pixel[GREEN] == 0 && pixel[BLUE] != 0); - - /* Should see a green pixel, at bottom of 4th triangle */ - cogl_read_pixels (310, y_off, 1, 1, - COGL_READ_PIXELS_COLOR_BUFFER, - COGL_PIXEL_FORMAT_RGBA_8888_PRE, - pixel); - if (cogl_test_verbose ()) - g_print ("pixel 3 = %x, %x, %x\n", pixel[RED], pixel[GREEN], pixel[BLUE]); - g_assert (pixel[GREEN] > pixel[RED] && pixel[GREEN] > pixel[BLUE]); - - /* Should see a red pixel, at top of 4th triangle */ - cogl_read_pixels (310, y_off - 70, 1, 1, - COGL_READ_PIXELS_COLOR_BUFFER, - COGL_PIXEL_FORMAT_RGBA_8888_PRE, - pixel); - if (cogl_test_verbose ()) - g_print ("pixel 4 = %x, %x, %x\n", pixel[RED], pixel[GREEN], pixel[BLUE]); - g_assert (pixel[RED] > pixel[GREEN] && pixel[RED] > pixel[BLUE]); - - -#undef RED -#undef GREEN -#undef BLUE - - /* Comment this out if you want visual feedback of what this test - * paints. - */ - clutter_main_quit (); -} - -static void -on_paint (ClutterActor *actor, TestState *state) -{ - /* Draw a faded blue triangle */ - cogl_vertex_buffer_enable (state->buffer, "gl_Color::blue"); - cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff); - cogl_vertex_buffer_draw (state->buffer, - GL_TRIANGLE_STRIP, /* mode */ - 0, /* first */ - 3); /* count */ - - /* Draw a red triangle */ - /* Here we are testing that the disable attribute works; if it doesn't - * the triangle will remain faded blue */ - cogl_translate (100, 0, 0); - cogl_vertex_buffer_disable (state->buffer, "gl_Color::blue"); - cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff); - cogl_vertex_buffer_draw (state->buffer, - GL_TRIANGLE_STRIP, /* mode */ - 0, /* first */ - 3); /* count */ - - /* Draw a faded blue triangle */ - /* Here we are testing that the re-enable works; if it doesn't - * the triangle will remain red */ - cogl_translate (100, 0, 0); - cogl_vertex_buffer_enable (state->buffer, "gl_Color::blue"); - cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff); - cogl_vertex_buffer_draw (state->buffer, - GL_TRIANGLE_STRIP, /* mode */ - 0, /* first */ - 3); /* count */ - - /* Draw a textured triangle */ - cogl_translate (100, 0, 0); - cogl_vertex_buffer_disable (state->buffer, "gl_Color::blue"); - cogl_set_source (state->material); - cogl_material_set_color4ub (state->material, 0xff, 0xff, 0xff, 0xff); - cogl_vertex_buffer_draw (state->buffer, - GL_TRIANGLE_STRIP, /* mode */ - 0, /* first */ - 3); /* count */ - - validate_result (state); -} - -static CoglBool -queue_redraw (gpointer stage) -{ - clutter_actor_queue_redraw (CLUTTER_ACTOR (stage)); - - return TRUE; -} - - - -void -test_vertex_buffer_contiguous (TestUtilsGTestFixture *fixture, - void *data) -{ - TestState state; - ClutterActor *stage; - ClutterColor stage_clr = {0x0, 0x0, 0x0, 0xff}; - ClutterActor *group; - unsigned int idle_source; - guchar tex_data[] = { - 0xff, 0x00, 0x00, 0xff, - 0xff, 0x00, 0x00, 0xff, - 0x00, 0xff, 0x00, 0xff, - 0x00, 0xff, 0x00, 0xff - }; - - stage = clutter_stage_get_default (); - - clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_clr); - clutter_actor_get_geometry (stage, &state.stage_geom); - - group = clutter_group_new (); - clutter_actor_set_size (group, - state.stage_geom.width, - state.stage_geom.height); - clutter_container_add_actor (CLUTTER_CONTAINER (stage), group); - - /* We force continuous redrawing incase someone comments out the - * clutter_main_quit and wants visual feedback for the test since we - * wont be doing anything else that will trigger redrawing. */ - idle_source = g_idle_add (queue_redraw, stage); - - g_signal_connect (group, "paint", G_CALLBACK (on_paint), &state); - - state.texture = cogl_texture_new_from_data (2, 2, - COGL_TEXTURE_NO_SLICING, - COGL_PIXEL_FORMAT_RGBA_8888, - COGL_PIXEL_FORMAT_ANY, - 0, /* auto calc row stride */ - tex_data); - - state.material = cogl_material_new (); - cogl_material_set_color4ub (state.material, 0x00, 0xff, 0x00, 0xff); - cogl_material_set_layer (state.material, 0, state.texture); - - { - GLfloat triangle_verts[3][2] = - { - {0.0, 0.0}, - {100.0, 100.0}, - {0.0, 100.0} - }; - GLbyte triangle_colors[3][4] = - { - {0x00, 0x00, 0xff, 0xff}, /* blue */ - {0x00, 0x00, 0xff, 0x00}, /* transparent blue */ - {0x00, 0x00, 0xff, 0x00} /* transparent blue */ - }; - GLfloat triangle_tex_coords[3][2] = - { - {0.0, 0.0}, - {1.0, 1.0}, - {0.0, 1.0} - }; - state.buffer = cogl_vertex_buffer_new (3 /* n vertices */); - cogl_vertex_buffer_add (state.buffer, - "gl_Vertex", - 2, /* n components */ - GL_FLOAT, - FALSE, /* normalized */ - 0, /* stride */ - triangle_verts); - cogl_vertex_buffer_add (state.buffer, - "gl_Color::blue", - 4, /* n components */ - GL_UNSIGNED_BYTE, - FALSE, /* normalized */ - 0, /* stride */ - triangle_colors); - cogl_vertex_buffer_add (state.buffer, - "gl_MultiTexCoord0", - 2, /* n components */ - GL_FLOAT, - FALSE, /* normalized */ - 0, /* stride */ - triangle_tex_coords); - - cogl_vertex_buffer_submit (state.buffer); - } - - clutter_actor_show_all (stage); - - clutter_main (); - - cogl_handle_unref (state.buffer); - cogl_handle_unref (state.material); - cogl_handle_unref (state.texture); - - g_source_remove (idle_source); - - if (cogl_test_verbose ()) - g_print ("OK\n"); -} - diff --git a/cogl/tests/conform/test-vertex-buffer-interleved.c b/cogl/tests/conform/test-vertex-buffer-interleved.c deleted file mode 100644 index 2d31e364a..000000000 --- a/cogl/tests/conform/test-vertex-buffer-interleved.c +++ /dev/null @@ -1,162 +0,0 @@ - -#include -#include - -#include "test-conform-common.h" - -/* This test verifies that interleved attributes work with the vertex buffer - * API. We add (x,y) GLfloat vertices, interleved with RGBA GLubyte color - * attributes to a buffer, submit and draw. - * - * If you want visual feedback of what this test paints for debugging purposes, - * then remove the call to clutter_main_quit() in validate_result. - */ - -typedef struct _TestState -{ - CoglHandle buffer; - ClutterGeometry stage_geom; -} TestState; - -typedef struct _InterlevedVertex -{ - GLfloat x; - GLfloat y; - - GLubyte r; - GLubyte g; - GLubyte b; - GLubyte a; -} InterlevedVertex; - - -static void -validate_result (TestState *state) -{ - GLubyte pixel[4]; - GLint y_off = 90; - - /* NB: We ignore the alpha, since we don't know if our render target is - * RGB or RGBA */ - -#define RED 0 -#define GREEN 1 -#define BLUE 2 - - /* Should see a blue pixel */ - cogl_read_pixels (10, y_off, 1, 1, - COGL_READ_PIXELS_COLOR_BUFFER, - COGL_PIXEL_FORMAT_RGBA_8888_PRE, - pixel); - if (cogl_test_verbose ()) - g_print ("pixel 0 = %x, %x, %x\n", pixel[RED], pixel[GREEN], pixel[BLUE]); - g_assert (pixel[RED] == 0 && pixel[GREEN] == 0 && pixel[BLUE] != 0); - -#undef RED -#undef GREEN -#undef BLUE - - /* Comment this out if you want visual feedback of what this test - * paints. - */ - clutter_main_quit (); -} - -static void -on_paint (ClutterActor *actor, TestState *state) -{ - /* Draw a faded blue triangle */ - cogl_vertex_buffer_draw (state->buffer, - GL_TRIANGLE_STRIP, /* mode */ - 0, /* first */ - 3); /* count */ - - validate_result (state); -} - -static CoglBool -queue_redraw (gpointer stage) -{ - clutter_actor_queue_redraw (CLUTTER_ACTOR (stage)); - - return TRUE; -} - -void -test_vertex_buffer_interleved (TestUtilsGTestFixture *fixture, - void *data) -{ - TestState state; - ClutterActor *stage; - ClutterColor stage_clr = {0x0, 0x0, 0x0, 0xff}; - ClutterActor *group; - unsigned int idle_source; - - stage = clutter_stage_get_default (); - - clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_clr); - clutter_actor_get_geometry (stage, &state.stage_geom); - - group = clutter_group_new (); - clutter_actor_set_size (group, - state.stage_geom.width, - state.stage_geom.height); - clutter_container_add_actor (CLUTTER_CONTAINER (stage), group); - - /* We force continuous redrawing incase someone comments out the - * clutter_main_quit and wants visual feedback for the test since we - * wont be doing anything else that will trigger redrawing. */ - idle_source = g_idle_add (queue_redraw, stage); - - g_signal_connect (group, "paint", G_CALLBACK (on_paint), &state); - - { - InterlevedVertex verts[3] = - { - { /* .x = */ 0.0, /* .y = */ 0.0, - /* blue */ - /* .r = */ 0x00, /* .g = */ 0x00, /* .b = */ 0xff, /* .a = */ 0xff }, - - { /* .x = */ 100.0, /* .y = */ 100.0, - /* transparent blue */ - /* .r = */ 0x00, /* .g = */ 0x00, /* .b = */ 0xff, /* .a = */ 0x00 }, - - { /* .x = */ 0.0, /* .y = */ 100.0, - /* transparent blue */ - /* .r = */ 0x00, /* .g = */ 0x00, /* .b = */ 0xff, /* .a = */ 0x00 }, - }; - - /* We assume the compiler is doing no funny struct padding for this test: - */ - g_assert (sizeof (InterlevedVertex) == 12); - - state.buffer = cogl_vertex_buffer_new (3 /* n vertices */); - cogl_vertex_buffer_add (state.buffer, - "gl_Vertex", - 2, /* n components */ - GL_FLOAT, - FALSE, /* normalized */ - 12, /* stride */ - &verts[0].x); - cogl_vertex_buffer_add (state.buffer, - "gl_Color", - 4, /* n components */ - GL_UNSIGNED_BYTE, - FALSE, /* normalized */ - 12, /* stride */ - &verts[0].r); - cogl_vertex_buffer_submit (state.buffer); - } - - clutter_actor_show_all (stage); - - clutter_main (); - - cogl_handle_unref (state.buffer); - - g_source_remove (idle_source); - - if (cogl_test_verbose ()) - g_print ("OK\n"); -} - diff --git a/cogl/tests/conform/test-vertex-buffer-mutability.c b/cogl/tests/conform/test-vertex-buffer-mutability.c deleted file mode 100644 index 9c8d5da8c..000000000 --- a/cogl/tests/conform/test-vertex-buffer-mutability.c +++ /dev/null @@ -1,198 +0,0 @@ - -#include -#include - -#include "test-conform-common.h" - -/* This test verifies that modifying a vertex buffer works, by updating - * vertex positions, and deleting and re-adding different color attributes. - * - * If you want visual feedback of what this test paints for debugging purposes, - * then remove the call to clutter_main_quit() in validate_result. - */ - -typedef struct _TestState -{ - CoglHandle buffer; - ClutterGeometry stage_geom; -} TestState; - -static void -validate_result (TestState *state) -{ - GLubyte pixel[4]; - GLint y_off = 90; - - /* NB: We ignore the alpha, since we don't know if our render target is - * RGB or RGBA */ - -#define RED 0 -#define GREEN 1 -#define BLUE 2 - - /* Should see a red pixel */ - cogl_read_pixels (110, y_off, 1, 1, - COGL_READ_PIXELS_COLOR_BUFFER, - COGL_PIXEL_FORMAT_RGBA_8888_PRE, - pixel); - if (cogl_test_verbose ()) - g_print ("pixel 0 = %x, %x, %x\n", pixel[RED], pixel[GREEN], pixel[BLUE]); - g_assert (pixel[RED] != 0 && pixel[GREEN] == 0 && pixel[BLUE] == 0); - - /* Should see a green pixel */ - cogl_read_pixels (210, y_off, 1, 1, - COGL_READ_PIXELS_COLOR_BUFFER, - COGL_PIXEL_FORMAT_RGBA_8888_PRE, - pixel); - if (cogl_test_verbose ()) - g_print ("pixel 1 = %x, %x, %x\n", pixel[RED], pixel[GREEN], pixel[BLUE]); - g_assert (pixel[RED] == 0 && pixel[GREEN] != 0 && pixel[BLUE] == 0); - -#undef RED -#undef GREEN -#undef BLUE - - /* Comment this out if you want visual feedback of what this test - * paints. - */ - clutter_main_quit (); -} - -static void -on_paint (ClutterActor *actor, TestState *state) -{ - GLfloat triangle_verts[3][2] = - { - {100.0, 0.0}, - {200.0, 100.0}, - {100.0, 100.0} - }; - GLbyte triangle_colors[3][4] = - { - {0x00, 0xff, 0x00, 0xff}, /* blue */ - {0x00, 0xff, 0x00, 0x00}, /* transparent blue */ - {0x00, 0xff, 0x00, 0x00} /* transparent blue */ - }; - - /* - * Draw a red triangle - */ - - cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff); - - cogl_vertex_buffer_add (state->buffer, - "gl_Vertex", - 2, /* n components */ - GL_FLOAT, - FALSE, /* normalized */ - 0, /* stride */ - triangle_verts); - cogl_vertex_buffer_delete (state->buffer, "gl_Color"); - cogl_vertex_buffer_submit (state->buffer); - - cogl_vertex_buffer_draw (state->buffer, - GL_TRIANGLE_STRIP, /* mode */ - 0, /* first */ - 3); /* count */ - - /* - * Draw a faded green triangle - */ - - cogl_vertex_buffer_add (state->buffer, - "gl_Color", - 4, /* n components */ - GL_UNSIGNED_BYTE, - FALSE, /* normalized */ - 0, /* stride */ - triangle_colors); - cogl_vertex_buffer_submit (state->buffer); - - cogl_translate (100, 0, 0); - cogl_vertex_buffer_draw (state->buffer, - GL_TRIANGLE_STRIP, /* mode */ - 0, /* first */ - 3); /* count */ - - validate_result (state); -} - -static CoglBool -queue_redraw (gpointer stage) -{ - clutter_actor_queue_redraw (CLUTTER_ACTOR (stage)); - - return TRUE; -} - -void -test_vertex_buffer_mutability (TestUtilsGTestFixture *fixture, - void *data) -{ - TestState state; - ClutterActor *stage; - ClutterColor stage_clr = {0x0, 0x0, 0x0, 0xff}; - ClutterActor *group; - unsigned int idle_source; - - stage = clutter_stage_get_default (); - - clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_clr); - clutter_actor_get_geometry (stage, &state.stage_geom); - - group = clutter_group_new (); - clutter_actor_set_size (group, - state.stage_geom.width, - state.stage_geom.height); - clutter_container_add_actor (CLUTTER_CONTAINER (stage), group); - - /* We force continuous redrawing incase someone comments out the - * clutter_main_quit and wants visual feedback for the test since we - * wont be doing anything else that will trigger redrawing. */ - idle_source = g_idle_add (queue_redraw, stage); - - g_signal_connect (group, "paint", G_CALLBACK (on_paint), &state); - - { - GLfloat triangle_verts[3][2] = - { - {0.0, 0.0}, - {100.0, 100.0}, - {0.0, 100.0} - }; - GLbyte triangle_colors[3][4] = - { - {0x00, 0x00, 0xff, 0xff}, /* blue */ - {0x00, 0x00, 0xff, 0x00}, /* transparent blue */ - {0x00, 0x00, 0xff, 0x00} /* transparent blue */ - }; - state.buffer = cogl_vertex_buffer_new (3 /* n vertices */); - cogl_vertex_buffer_add (state.buffer, - "gl_Vertex", - 2, /* n components */ - GL_FLOAT, - FALSE, /* normalized */ - 0, /* stride */ - triangle_verts); - cogl_vertex_buffer_add (state.buffer, - "gl_Color", - 4, /* n components */ - GL_UNSIGNED_BYTE, - FALSE, /* normalized */ - 0, /* stride */ - triangle_colors); - cogl_vertex_buffer_submit (state.buffer); - } - - clutter_actor_show_all (stage); - - clutter_main (); - - cogl_handle_unref (state.buffer); - - g_source_remove (idle_source); - - if (cogl_test_verbose ()) - g_print ("OK\n"); -} - diff --git a/cogl/tests/conform/test-viewport.c b/cogl/tests/conform/test-viewport.c index 310fd49ea..1b2582954 100644 --- a/cogl/tests/conform/test-viewport.c +++ b/cogl/tests/conform/test-viewport.c @@ -24,7 +24,7 @@ assert_region_color (int x, uint8_t blue, uint8_t alpha) { - uint8_t *data = calloc (1, width * height * 4); + uint8_t *data = g_malloc0 (width * height * 4); cogl_read_pixels (x, y, width, height, COGL_READ_PIXELS_COLOR_BUFFER, COGL_PIXEL_FORMAT_RGBA_8888_PRE, @@ -40,7 +40,7 @@ assert_region_color (int x, pixel[ALPHA] == alpha); #endif } - free (data); + g_free (data); } static void @@ -66,7 +66,9 @@ assert_rectangle_color_and_black_border (int x, static void -on_paint (ClutterActor *actor, void *state) +on_paint (ClutterActor *actor, + ClutterPaintContext *paint_context, + void *state) { float saved_viewport[4]; CoglMatrix saved_projection; @@ -209,14 +211,14 @@ on_paint (ClutterActor *actor, void *state) /* * Next test offscreen drawing... */ - data = malloc (FRAMEBUFFER_WIDTH * 4 * FRAMEBUFFER_HEIGHT); + data = g_malloc (FRAMEBUFFER_WIDTH * 4 * FRAMEBUFFER_HEIGHT); tex = test_utils_texture_new_from_data (FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT, TEST_UTILS_TEXTURE_NO_SLICING, COGL_PIXEL_FORMAT_RGBA_8888, /* data fmt */ COGL_PIXEL_FORMAT_ANY, /* internal fmt */ FRAMEBUFFER_WIDTH * 4, /* rowstride */ data); - free (data); + g_free (data); offscreen = cogl_offscreen_new_with_texture (tex); cogl_push_framebuffer (offscreen); @@ -335,7 +337,7 @@ on_paint (ClutterActor *actor, void *state) cogl_set_viewport (0, 0, 10, 10); cogl_pop_framebuffer (); - cogl_handle_unref (offscreen); + cogl_object_unref (offscreen); /* * Verify that the previous onscreen framebuffer's viewport was restored @@ -361,7 +363,7 @@ on_paint (ClutterActor *actor, void *state) cogl_rectangle (-1, 1, 1, -1); #endif - cogl_handle_unref (tex); + cogl_object_unref (tex); /* Finally restore the stage's original state... */ cogl_pop_matrix (); @@ -376,7 +378,7 @@ on_paint (ClutterActor *actor, void *state) clutter_main_quit (); } -static CoglBool +static gboolean queue_redraw (void *stage) { clutter_actor_queue_redraw (CLUTTER_ACTOR (stage)); @@ -403,12 +405,10 @@ test_viewport (TestUtilsGTestFixture *fixture, clutter_actor_show (stage); clutter_main (); - g_source_remove (idle_source); + g_clear_handle_id (&idle_source, g_source_remove); /* Remove all of the actors from the stage */ - clutter_container_foreach (CLUTTER_CONTAINER (stage), - (ClutterCallback) clutter_actor_destroy, - NULL); + clutter_actor_remove_all_children (stage); if (cogl_test_verbose ()) g_print ("OK\n"); diff --git a/cogl/tests/conform/test-wrap-modes.c b/cogl/tests/conform/test-wrap-modes.c index baf32fcb5..9bd525ebc 100644 --- a/cogl/tests/conform/test-wrap-modes.c +++ b/cogl/tests/conform/test-wrap-modes.c @@ -3,6 +3,7 @@ #include #include +#include "test-declarations.h" #include "test-utils.h" #define TEX_SIZE 4 @@ -17,7 +18,7 @@ typedef struct _TestState static CoglTexture * create_texture (TestUtilsTextureFlags flags) { - uint8_t *data = malloc (TEX_SIZE * TEX_SIZE * 4), *p = data; + uint8_t *data = g_malloc (TEX_SIZE * TEX_SIZE * 4), *p = data; CoglTexture *tex; int x, y; @@ -35,7 +36,7 @@ create_texture (TestUtilsTextureFlags flags) COGL_PIXEL_FORMAT_RGBA_8888_PRE, TEX_SIZE * 4, data); - free (data); + g_free (data); return tex; } @@ -72,12 +73,6 @@ wrap_modes[] = COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE, COGL_PIPELINE_WRAP_MODE_REPEAT, - - COGL_PIPELINE_WRAP_MODE_AUTOMATIC, - COGL_PIPELINE_WRAP_MODE_AUTOMATIC, - - COGL_PIPELINE_WRAP_MODE_AUTOMATIC, - COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE }; static void @@ -107,12 +102,12 @@ draw_tests (TestState *state) } } -static const CoglTextureVertex vertices[4] = +static const CoglVertexP3T2 vertices[4] = { - { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, TEX_SIZE * 2, 0.0f, 0.0f, 2.0f }, - { TEX_SIZE * 2, TEX_SIZE * 2, 0.0f, 2.0f, 2.0f }, - { TEX_SIZE * 2, 0.0f, 0.0f, 2.0f, 0.0f } + { .x = 0.0f, .y = 0.0f, .z = 0.0f, .s = 0.0f, .t = 0.0f }, + { .x = 0.0f, .y = TEX_SIZE * 2, .z = 0.0f, .s = 0.0f, .t = 2.0f }, + { .x = TEX_SIZE * 2, .y = TEX_SIZE * 2, .z = 0.0f, .s = 2.0f, .t = 2.0f }, + { .x = TEX_SIZE * 2, .y = 0.0f, .z = 0.0f, .s = 2.0f, .t = 0.0f } }; static void @@ -123,56 +118,24 @@ draw_tests_polygon (TestState *state) for (i = 0; i < G_N_ELEMENTS (wrap_modes); i += 2) { CoglPipelineWrapMode wrap_mode_s, wrap_mode_t; + CoglPrimitive *primitive; CoglPipeline *pipeline; wrap_mode_s = wrap_modes[i]; wrap_mode_t = wrap_modes[i + 1]; pipeline = create_pipeline (state, wrap_mode_s, wrap_mode_t); - cogl_set_source (pipeline); - cogl_object_unref (pipeline); - cogl_push_matrix (); - cogl_translate (TEX_SIZE * i, 0.0f, 0.0f); + cogl_framebuffer_push_matrix (test_fb); + cogl_framebuffer_translate (test_fb, TEX_SIZE * i, 0.0f, 0.0f); /* Render the pipeline at four times the size of the texture */ - cogl_polygon (vertices, G_N_ELEMENTS (vertices), FALSE); - cogl_pop_matrix (); - } -} - -static void -draw_tests_vbo (TestState *state) -{ - CoglHandle vbo; - int i; - - vbo = cogl_vertex_buffer_new (4); - cogl_vertex_buffer_add (vbo, "gl_Vertex", 3, - COGL_ATTRIBUTE_TYPE_FLOAT, FALSE, - sizeof (vertices[0]), - &vertices[0].x); - cogl_vertex_buffer_add (vbo, "gl_MultiTexCoord0", 2, - COGL_ATTRIBUTE_TYPE_FLOAT, FALSE, - sizeof (vertices[0]), - &vertices[0].tx); - cogl_vertex_buffer_submit (vbo); - - for (i = 0; i < G_N_ELEMENTS (wrap_modes); i += 2) - { - CoglPipelineWrapMode wrap_mode_s, wrap_mode_t; - CoglPipeline *pipeline; - - wrap_mode_s = wrap_modes[i]; - wrap_mode_t = wrap_modes[i + 1]; - pipeline = create_pipeline (state, wrap_mode_s, wrap_mode_t); - cogl_set_source (pipeline); + primitive = cogl_primitive_new_p3t2 (test_ctx, + COGL_VERTICES_MODE_TRIANGLE_FAN, + G_N_ELEMENTS (vertices), + vertices); + cogl_primitive_draw (primitive, test_fb, pipeline); + cogl_object_unref (primitive); cogl_object_unref (pipeline); - cogl_push_matrix (); - cogl_translate (TEX_SIZE * i, 0.0f, 0.0f); - /* Render the pipeline at four times the size of the texture */ - cogl_vertex_buffer_draw (vbo, COGL_VERTICES_MODE_TRIANGLE_FAN, 0, 4); - cogl_pop_matrix (); + cogl_framebuffer_pop_matrix (test_fb); } - - cogl_handle_unref (vbo); } static void @@ -230,8 +193,7 @@ validate_result (TestState *state) #if 0 /* this doesn't currently work */ validate_set (state, 1); /* atlased rectangle */ #endif - validate_set (state, 2); /* cogl_polygon */ - validate_set (state, 3); /* vertex buffer */ + validate_set (state, 2); /* CoglPrimitive */ } static void @@ -248,23 +210,16 @@ paint (TestState *state) cogl_framebuffer_push_matrix (test_fb); cogl_framebuffer_translate (test_fb, 0.0f, TEX_SIZE * 2.0f, 0.0f); draw_tests (state); - cogl_pop_matrix (); + cogl_framebuffer_pop_matrix (test_fb); cogl_object_unref (state->texture); - /* Draw the tests using cogl_polygon */ - state->texture = create_texture (COGL_TEXTURE_NO_ATLAS); - cogl_push_matrix (); - cogl_translate (0.0f, TEX_SIZE * 4.0f, 0.0f); + /* Draw the tests using CoglPrimitive */ + state->texture = create_texture (TEST_UTILS_TEXTURE_NO_ATLAS); + cogl_framebuffer_push_matrix (test_fb); + cogl_framebuffer_translate (test_fb, + 0.0f, TEX_SIZE * 4.0f, 0.0f); draw_tests_polygon (state); - cogl_pop_matrix (); - cogl_object_unref (state->texture); - - /* Draw the tests using a vertex buffer */ - state->texture = create_texture (COGL_TEXTURE_NO_ATLAS); - cogl_push_matrix (); - cogl_translate (0.0f, TEX_SIZE * 6.0f, 0.0f); - draw_tests_vbo (state); - cogl_pop_matrix (); + cogl_framebuffer_pop_matrix (test_fb); cogl_object_unref (state->texture); validate_result (state); @@ -285,11 +240,7 @@ test_wrap_modes (void) -1, 100); - /* XXX: we have to push/pop a framebuffer since this test currently - * uses the legacy cogl_vertex_buffer_draw() api. */ - cogl_push_framebuffer (test_fb); paint (&state); - cogl_pop_framebuffer (); if (cogl_test_verbose ()) g_print ("OK\n"); diff --git a/cogl/tests/conform/test-wrap-rectangle-textures.c b/cogl/tests/conform/test-wrap-rectangle-textures.c deleted file mode 100644 index 73b357536..000000000 --- a/cogl/tests/conform/test-wrap-rectangle-textures.c +++ /dev/null @@ -1,175 +0,0 @@ -#include - -#include - -#include "test-utils.h" - -#define DRAW_SIZE 64 - -static CoglPipeline * -create_base_pipeline (void) -{ - CoglBitmap *bmp; - CoglTextureRectangle *tex; - CoglPipeline *pipeline; - uint8_t tex_data[] = - { - 0x44, 0x44, 0x44, 0x88, 0x88, 0x88, - 0xcc, 0xcc, 0xcc, 0xff, 0xff, 0xff - }; - - bmp = cogl_bitmap_new_for_data (test_ctx, - 2, 2, /* width/height */ - COGL_PIXEL_FORMAT_RGB_888, - 2 * 3, /* rowstride */ - tex_data); - - tex = cogl_texture_rectangle_new_from_bitmap (bmp); - - cogl_object_unref (bmp); - - pipeline = cogl_pipeline_new (test_ctx); - - cogl_pipeline_set_layer_filters (pipeline, - 0, /* layer */ - COGL_PIPELINE_FILTER_NEAREST, - COGL_PIPELINE_FILTER_NEAREST); - - cogl_pipeline_set_layer_texture (pipeline, - 0, /* layer */ - tex); - - cogl_object_unref (tex); - - return pipeline; -} - -static void -check_colors (int x_offset, - int y_offset, - const uint8_t expected_colors[9]) -{ - int x, y; - - for (y = 0; y < 4; y++) - for (x = 0; x < 4; x++) - { - uint32_t color = expected_colors[x + y * 4]; - test_utils_check_region (test_fb, - x * DRAW_SIZE / 4 + 1 + x_offset, - y * DRAW_SIZE / 4 + 1 + y_offset, - DRAW_SIZE / 4 - 2, - DRAW_SIZE / 4 - 2, - 0xff | - (color << 8) | - (color << 16) | - (color << 24)); - } -} - -static void -test_pipeline (CoglPipeline *pipeline, - int x_offset, - int y_offset, - const uint8_t expected_colors[9]) -{ - float x1 = x_offset; - float y1 = y_offset; - float x2 = x1 + DRAW_SIZE; - float y2 = y1 + DRAW_SIZE; - int y, x; - - cogl_framebuffer_draw_textured_rectangle (test_fb, - pipeline, - x1, y1, - x2, y2, - -0.5f, /* s1 */ - -0.5f, /* t1 */ - 1.5f, /* s2 */ - 1.5f /* t2 */); - - check_colors (x_offset, y_offset, expected_colors); - - /* Also try drawing each quadrant of the rectangle with a small - * rectangle */ - - for (y = -1; y < 3; y++) - for (x = -1; x < 3; x++) - { - x1 = x_offset + (x + 1) * DRAW_SIZE / 4 + DRAW_SIZE; - y1 = y_offset + (y + 1) * DRAW_SIZE / 4; - x2 = x1 + DRAW_SIZE / 4; - y2 = y1 + DRAW_SIZE / 4; - - cogl_framebuffer_draw_textured_rectangle (test_fb, - pipeline, - x1, y1, - x2, y2, - x / 2.0f, /* s1 */ - y / 2.0f, /* t1 */ - (x + 1) / 2.0f, /* s2 */ - (y + 1) / 2.0f /* t2 */); - } - - check_colors (x_offset + DRAW_SIZE, y_offset, expected_colors); -} - -void -test_wrap_rectangle_textures (void) -{ - float fb_width = cogl_framebuffer_get_width (test_fb); - float fb_height = cogl_framebuffer_get_height (test_fb); - CoglPipeline *base_pipeline; - CoglPipeline *clamp_pipeline; - CoglPipeline *repeat_pipeline; - /* The textures are drawn with the texture coordinates from - * -0.5→1.5. That means we get one complete copy of the texture and - * an extra half of the texture surrounding it. The drawing is - * tested against a 4x4 grid of colors. The center 2x2 colours - * specify the normal texture colors and the other colours specify - * what the wrap mode should generate */ - static const uint8_t clamp_colors[] = - { - 0x44, 0x44, 0x88, 0x88, - 0x44, 0x44, 0x88, 0x88, - 0xcc, 0xcc, 0xff, 0xff, - 0xcc, 0xcc, 0xff, 0xff - }; - static const uint8_t repeat_colors[] = - { - 0xff, 0xcc, 0xff, 0xcc, - 0x88, 0x44, 0x88, 0x44, - 0xff, 0xcc, 0xff, 0xcc, - 0x88, 0x44, 0x88, 0x44 - }; - - cogl_framebuffer_orthographic (test_fb, - 0, 0, /* x_1, y_1 */ - fb_width, /* x_2 */ - fb_height /* y_2 */, - -1, 100 /* near/far */); - - base_pipeline = create_base_pipeline (); - - clamp_pipeline = cogl_pipeline_copy (base_pipeline); - cogl_pipeline_set_layer_wrap_mode (clamp_pipeline, - 0, /* layer */ - COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE); - - repeat_pipeline = cogl_pipeline_copy (base_pipeline); - cogl_pipeline_set_layer_wrap_mode (repeat_pipeline, - 0, /* layer */ - COGL_PIPELINE_WRAP_MODE_REPEAT); - - test_pipeline (clamp_pipeline, - 0, 0, /* x/y offset */ - clamp_colors); - - test_pipeline (repeat_pipeline, - 0, DRAW_SIZE * 2, /* x/y offset */ - repeat_colors); - - cogl_object_unref (repeat_pipeline); - cogl_object_unref (clamp_pipeline); - cogl_object_unref (base_pipeline); -} diff --git a/cogl/tests/conform/test-write-texture-formats.c b/cogl/tests/conform/test-write-texture-formats.c index 76c434826..ca8015771 100644 --- a/cogl/tests/conform/test-write-texture-formats.c +++ b/cogl/tests/conform/test-write-texture-formats.c @@ -1,6 +1,7 @@ #include #include +#include "test-declarations.h" #include "test-utils.h" /* diff --git a/cogl/tests/data/Makefile.am b/cogl/tests/data/Makefile.am deleted file mode 100644 index 3a2030a77..000000000 --- a/cogl/tests/data/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -NULL = - -EXTRA_DIST = valgrind.suppressions diff --git a/cogl/tests/data/valgrind.suppressions b/cogl/tests/data/valgrind.suppressions index f47498d16..b7f82ab30 100644 --- a/cogl/tests/data/valgrind.suppressions +++ b/cogl/tests/data/valgrind.suppressions @@ -66,14 +66,6 @@ fun:g_get_charset } -{ - cogl_features - Memcheck:Leak - fun:*alloc - ... - fun:cogl_get_features -} - { glx_query_version Memcheck:Leak diff --git a/cogl/tests/meson.build b/cogl/tests/meson.build new file mode 100644 index 000000000..0d76c8bc9 --- /dev/null +++ b/cogl/tests/meson.build @@ -0,0 +1,22 @@ +cogl_run_tests = find_program('run-tests.sh') + +cdata = configuration_data() +cdata.set('HAVE_GL', have_gl.to_int()) +cdata.set('HAVE_GLES2', have_gles2.to_int()) + +cogl_installed_tests_libexecdir = join_paths( + mutter_installed_tests_libexecdir, 'cogl', 'conform') +if have_installed_tests + install_data('run-tests.sh', install_dir: cogl_installed_tests_libexecdir) +endif + +cogl_config_env = configure_file( + input: 'config.env.in', + output: 'config.env', + configuration: cdata, + install: have_installed_tests, + install_dir: cogl_installed_tests_libexecdir, +) + +subdir('conform') +subdir('unit') diff --git a/cogl/tests/micro-perf/Makefile.am b/cogl/tests/micro-perf/Makefile.am deleted file mode 100644 index 6ef09f8e1..000000000 --- a/cogl/tests/micro-perf/Makefile.am +++ /dev/null @@ -1,24 +0,0 @@ -NULL = - -AM_CPPFLAGS = \ - -I$(top_srcdir) \ - -I$(top_builddir)/cogl \ - -DCOGL_DISABLE_DEPRECATED - -test_conformance_CPPFLAGS = \ - -DTESTS_DATADIR=\""$(top_srcdir)/tests/data"\" - - -noinst_PROGRAMS = - -noinst_PROGRAMS += test-journal - -AM_CFLAGS = $(COGL_DEP_CFLAGS) $(COGL_EXTRA_CFLAGS) - -common_ldadd = \ - $(COGL_DEP_LIBS) \ - $(top_builddir)/cogl/libmuffin-cogl-$(MUFFIN_PLUGIN_API_VERSION).la \ - $(LIBM) - -test_journal_SOURCES = test-journal.c -test_journal_LDADD = $(common_ldadd) diff --git a/cogl/tests/micro-perf/test-journal.c b/cogl/tests/micro-perf/test-journal.c deleted file mode 100644 index 7bfdcf790..000000000 --- a/cogl/tests/micro-perf/test-journal.c +++ /dev/null @@ -1,190 +0,0 @@ -#include -#include -#include - -#include "cogl/cogl-profile.h" - -#define FRAMEBUFFER_WIDTH 800 -#define FRAMEBUFFER_HEIGHT 600 - -CoglBool run_all = FALSE; - -typedef struct _Data -{ - CoglContext *ctx; - CoglFramebuffer *fb; - CoglPipeline *pipeline; - CoglPipeline *alpha_pipeline; - GTimer *timer; - int frame; -} Data; - -static void -test_rectangles (Data *data) -{ -#define RECT_WIDTH 5 -#define RECT_HEIGHT 5 - int x; - int y; - - cogl_framebuffer_clear4f (data->fb, COGL_BUFFER_BIT_COLOR, 1, 1, 1, 1); - - cogl_framebuffer_push_rectangle_clip (data->fb, - 10, - 10, - FRAMEBUFFER_WIDTH - 10, - FRAMEBUFFER_HEIGHT - 10); - - /* Should the rectangles be randomly positioned/colored/rotated? - * - * It could be good to develop equivalent GL and Cairo tests so we can - * have a sanity check for our Cogl performance. - * - * The color should vary to check that we correctly batch color changes - * The use of alpha should vary so we have a variation of which rectangles - * require blending. - * Should this be a random variation? - * It could be good to experiment with focibly enabling blending for - * rectangles that don't technically need it for the sake of extending - * batching. E.g. if you a long run of interleved rectangles with every - * other rectangle needing blending then it may be worth enabling blending - * for all the rectangles to avoid the state changes. - * The modelview should change between rectangles to check the software - * transform codepath. - * Should we group some rectangles under the same modelview? Potentially - * we could avoid software transform for long runs of rectangles with the - * same modelview. - * - */ - for (y = 0; y < FRAMEBUFFER_HEIGHT; y += RECT_HEIGHT) - { - for (x = 0; x < FRAMEBUFFER_WIDTH; x += RECT_WIDTH) - { - cogl_framebuffer_push_matrix (data->fb); - cogl_framebuffer_translate (data->fb, x, y, 0); - cogl_framebuffer_rotate (data->fb, 45, 0, 0, 1); - - cogl_pipeline_set_color4f (data->pipeline, - 1, - (1.0f/FRAMEBUFFER_WIDTH)*y, - (1.0f/FRAMEBUFFER_HEIGHT)*x, - 1); - cogl_framebuffer_draw_rectangle (data->fb, - data->pipeline, - 0, 0, RECT_WIDTH, RECT_HEIGHT); - - cogl_framebuffer_pop_matrix (data->fb); - } - } - - for (y = 0; y < FRAMEBUFFER_HEIGHT; y += RECT_HEIGHT) - { - for (x = 0; x < FRAMEBUFFER_WIDTH; x += RECT_WIDTH) - { - cogl_framebuffer_push_matrix (data->fb); - cogl_framebuffer_translate (data->fb, x, y, 0); - - cogl_pipeline_set_color4f (data->alpha_pipeline, - 1, - (1.0f/FRAMEBUFFER_WIDTH)*x, - (1.0f/FRAMEBUFFER_HEIGHT)*y, - (1.0f/FRAMEBUFFER_WIDTH)*x); - cogl_framebuffer_draw_rectangle (data->fb, - data->alpha_pipeline, - 0, 0, RECT_WIDTH, RECT_HEIGHT); - - cogl_framebuffer_pop_matrix (data->fb); - } - } - - cogl_framebuffer_pop_clip (data->fb); -} - -static CoglBool -paint_cb (void *user_data) -{ - Data *data = user_data; - double elapsed; - - data->frame++; - - test_rectangles (data); - - cogl_onscreen_swap_buffers (COGL_ONSCREEN (data->fb)); - - elapsed = g_timer_elapsed (data->timer, NULL); - if (elapsed > 1.0) - { - g_print ("fps = %f\n", data->frame / elapsed); - g_timer_start (data->timer); - data->frame = 0; - } - - return FALSE; /* remove the callback */ -} - -static void -frame_event_cb (CoglOnscreen *onscreen, - CoglFrameEvent event, - CoglFrameInfo *info, - void *user_data) -{ - if (event == COGL_FRAME_EVENT_SYNC) - paint_cb (user_data); -} - -int -main (int argc, char **argv) -{ - Data data; - CoglOnscreen *onscreen; - GSource *cogl_source; - GMainLoop *loop; - COGL_STATIC_TIMER (mainloop_timer, - NULL, //no parent - "Mainloop", - "The time spent in the glib mainloop", - 0); // no application private data - - data.ctx = cogl_context_new (NULL, NULL); - - onscreen = cogl_onscreen_new (data.ctx, - FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT); - cogl_onscreen_set_swap_throttled (onscreen, FALSE); - cogl_onscreen_show (onscreen); - - data.fb = onscreen; - cogl_framebuffer_orthographic (data.fb, - 0, 0, - FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT, - -1, - 100); - - data.pipeline = cogl_pipeline_new (data.ctx); - cogl_pipeline_set_color4f (data.pipeline, 1, 1, 1, 1); - data.alpha_pipeline = cogl_pipeline_new (data.ctx); - cogl_pipeline_set_color4f (data.alpha_pipeline, 1, 1, 1, 0.5); - - cogl_source = cogl_glib_source_new (data.ctx, G_PRIORITY_DEFAULT); - - g_source_attach (cogl_source, NULL); - - cogl_onscreen_add_frame_callback (COGL_ONSCREEN (data.fb), - frame_event_cb, - &data, - NULL); /* destroy notify */ - - g_idle_add (paint_cb, &data); - - data.frame = 0; - data.timer = g_timer_new (); - g_timer_start (data.timer); - - loop = g_main_loop_new (NULL, TRUE); - COGL_TIMER_START (uprof_get_mainloop_context (), mainloop_timer); - g_main_loop_run (loop); - COGL_TIMER_STOP (uprof_get_mainloop_context (), mainloop_timer); - - return 0; -} - diff --git a/cogl/tests/run-tests.sh b/cogl/tests/run-tests.sh index 7e62bf0f6..825dd1251 100755 --- a/cogl/tests/run-tests.sh +++ b/cogl/tests/run-tests.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash if test -z "$G_DEBUG"; then G_DEBUG=fatal-warnings @@ -14,10 +14,15 @@ shift TEST_BINARY=$1 shift -. $ENVIRONMENT_CONFIG +UNIT_TESTS=$1 +shift + +. "$ENVIRONMENT_CONFIG" set +m +LOG=$(mktemp) + trap "" ERR trap "" SIGABRT trap "" SIGFPE @@ -27,13 +32,15 @@ EXIT=0 MISSING_FEATURE="WARNING: Missing required feature"; KNOWN_FAILURE="WARNING: Test is known to fail"; -echo "Key:" -echo "ok = Test passed" -echo "n/a = Driver is missing a feature required for the test" -echo "FAIL = Unexpected failure" -echo "FIXME = Test failed, but it was an expected failure" -echo "PASS! = Unexpected pass" -echo "" +if [ -z "$RUN_TESTS_QUIET" ]; then + echo "Key:" + echo "ok = Test passed" + echo "n/a = Driver is missing a feature required for the test" + echo "FAIL = Unexpected failure" + echo "FIXME = Test failed, but it was an expected failure" + echo "PASS! = Unexpected pass" + echo "" +fi get_status() { @@ -62,96 +69,94 @@ get_status() run_test() { - $($TEST_BINARY $1 &>.log) + $("$TEST_BINARY" "$1" &> "$LOG") TMP=$? var_name=$2_result - eval $var_name=$TMP - if grep -q "$MISSING_FEATURE" .log; then - if test $TMP -ne 0; then - eval $var_name=500 + eval "$var_name=$TMP" + if grep -q "$MISSING_FEATURE" "$LOG"; then + if test "$TMP" -ne 0; then + eval "$var_name=500" else - eval $var_name=400 + eval "$var_name=400" fi - elif grep -q "$KNOWN_FAILURE" .log; then + elif grep -q "$KNOWN_FAILURE" "$LOG"; then if test $TMP -ne 0; then - eval $var_name=300 + eval "$var_name=300" else - eval $var_name=400 + eval "$var_name=400" fi else - if test $TMP -ne 0; then EXIT=$TMP; fi + if test "$TMP" -ne 0; then EXIT=$TMP; fi fi } +if [ -z "$UNIT_TESTS" ]; then + echo Missing unit-tests file or names + exit 1 +fi + TITLE_FORMAT="%35s" -printf $TITLE_FORMAT "Test" +printf "$TITLE_FORMAT" "Test" -if test $HAVE_GL -eq 1; then - GL_FORMAT=" %6s %8s %7s %6s %6s" - printf "$GL_FORMAT" "GL+FF" "GL+ARBFP" "GL+GLSL" "GL-NPT" "GL3" +if test "$HAVE_GL" -eq 1; then + GL_FORMAT=" %6s %8s %7s %6s" + printf "$GL_FORMAT" "GL+GLSL" "GL3" fi -if test $HAVE_GLES2 -eq 1; then - GLES2_FORMAT=" %6s %7s" - printf "$GLES2_FORMAT" "ES2" "ES2-NPT" +if test "$HAVE_GLES2" -eq 1; then + GLES2_FORMAT=" %6s" + printf "$GLES2_FORMAT" "ES2" fi echo "" -echo "" -for test in `cat unit-tests` +if [ -f "$UNIT_TESTS" ]; then + UNIT_TESTS="$(cat $UNIT_TESTS)" +fi + +if [ -z "$RUN_TESTS_QUIET" ] || [ "$(echo "$UNIT_TESTS" | wc -w )" -gt 1 ]; then + echo "" +fi + +for test in $UNIT_TESTS do + printf $TITLE_FORMAT "$test:" export COGL_DEBUG= - if test $HAVE_GL -eq 1; then - export COGL_DRIVER=gl - export COGL_DEBUG=disable-glsl,disable-arbfp - run_test $test gl_ff - + if test "$HAVE_GL" -eq 1; then export COGL_DRIVER=gl # NB: we can't explicitly disable fixed + glsl in this case since # the arbfp code only supports fragment processing so we need either # the fixed or glsl vertends export COGL_DEBUG= - run_test $test gl_arbfp + run_test "$test" gl_arbfp export COGL_DRIVER=gl export COGL_DEBUG=disable-fixed,disable-arbfp - run_test $test gl_glsl - - export COGL_DRIVER=gl - export COGL_DEBUG=disable-npot-textures - run_test $test gl_npot + run_test "$test" gl_glsl export COGL_DRIVER=gl3 export COGL_DEBUG= - run_test $test gl3 + run_test "$test" gl3 fi - if test $HAVE_GLES2 -eq 1; then + if test "$HAVE_GLES2" -eq 1; then export COGL_DRIVER=gles2 export COGL_DEBUG= - run_test $test gles2 - - export COGL_DRIVER=gles2 - export COGL_DEBUG=disable-npot-textures - run_test $test gles2_npot + run_test "$test" gles2 fi - printf $TITLE_FORMAT "$test:" - if test $HAVE_GL -eq 1; then + if test "$HAVE_GL" -eq 1; then printf "$GL_FORMAT" \ - "`get_status $gl_ff_result`" \ - "`get_status $gl_arbfp_result`" \ - "`get_status $gl_glsl_result`" \ - "`get_status $gl_npot_result`" \ - "`get_status $gl3_result`" + "$(get_status "$gl_glsl_result")" \ + "$(get_status "$gl3_result")" fi - if test $HAVE_GLES2 -eq 1; then + if test "$HAVE_GLES2" -eq 1; then printf "$GLES2_FORMAT" \ - "`get_status $gles2_result`" \ - "`get_status $gles2_npot_result`" + "$(get_status "$gles2_result")" fi echo "" done -exit $EXIT +rm "$LOG" + +exit "$EXIT" diff --git a/cogl/tests/test-launcher.sh b/cogl/tests/test-launcher.sh index e159e2e49..c3cb345db 100755 --- a/cogl/tests/test-launcher.sh +++ b/cogl/tests/test-launcher.sh @@ -9,20 +9,20 @@ shift UNIT_TEST=$1 shift -test -z ${UNIT_TEST} && { +test -z "${UNIT_TEST}" && { echo "Usage: $0 UNIT_TEST" exit 1 } -BINARY_NAME=`basename $TEST_BINARY` -UNIT_TEST=`echo $UNIT_TEST|sed 's/-/_/g'` +BINARY_NAME=$(basename "$TEST_BINARY") +UNIT_TEST=$(echo "$UNIT_TEST"|sed 's/-/_/g') -echo "Running: ./$BINARY_NAME ${UNIT_TEST} $@" +echo "Running: ./$BINARY_NAME ${UNIT_TEST} $*" echo "" -COGL_TEST_VERBOSE=1 $TEST_BINARY ${UNIT_TEST} "$@" +COGL_TEST_VERBOSE=1 "$TEST_BINARY" "${UNIT_TEST}" "$@" exit_val=$? -if test $exit_val -eq 0; then +if test "$exit_val" -eq 0; then echo "OK" fi @@ -36,4 +36,4 @@ echo "$ env G_SLICE=always-malloc \\" echo " libtool --mode=execute \\" echo " valgrind ./$BINARY_NAME ${UNIT_TEST}" -exit $exit_val +exit "$exit_val" diff --git a/cogl/tests/unit/Makefile.am b/cogl/tests/unit/Makefile.am deleted file mode 100644 index 723bec66a..000000000 --- a/cogl/tests/unit/Makefile.am +++ /dev/null @@ -1,84 +0,0 @@ -NULL = - -noinst_PROGRAMS = test-unit - -test_unit_SOURCES = test-unit-main.c - -SHEXT = $(EXEEXT) - -# For convenience, this provides a way to easily run individual unit tests: -.PHONY: wrappers clean-wrappers - -wrappers: stamp-test-unit - @true -stamp-test-unit: Makefile test-unit$(EXEEXT) - @mkdir -p wrappers - . $(top_builddir)/cogl/libmuffin-cogl-$(MUFFIN_PLUGIN_API_VERSION).la ; \ - $(NM) $(top_builddir)/cogl/.libs/"$$dlname"| \ - grep '[DR] _\?unit_test_'|sed 's/.\+ [DR] _\?//' > unit-tests - @chmod +x $(top_srcdir)/tests/test-launcher.sh - @( echo "/stamp-test-unit" ; \ - echo "/test-unit$(EXEEXT)" ; \ - echo "*.o" ; \ - echo ".gitignore" ; \ - echo "unit-tests" ; ) > .gitignore - @for i in `cat unit-tests`; \ - do \ - unit=`echo $$i | sed -e s/_/-/g | sed s/unit-test-//`; \ - echo " GEN $$unit"; \ - ( echo "#!/bin/sh" ; echo "$(top_srcdir)/tests/test-launcher.sh $(abs_builddir)/test-unit$(EXEEXT) 'unit_test_' '$$i' \"\$$@\"" ) > $$unit$(SHEXT) ; \ - chmod +x $$unit$(SHEXT); \ - echo "/$$unit$(SHEXT)" >> .gitignore; \ - done \ - && echo timestamp > $(@F) - -clean-wrappers: - @for i in `cat unit-tests`; \ - do \ - unit=`echo $$i | sed -e s/_/-/g | sed s/unit-test-//`; \ - echo " RM $$unit"; \ - rm -f $$unit$(SHEXT) ; \ - done \ - && rm -f unit-tests \ - && rm -f stamp-test-unit - -# NB: BUILT_SOURCES here a misnomer. We aren't building source, just inserting -# a phony rule that will generate symlink scripts for running individual tests -BUILT_SOURCES = wrappers - -# The include of the $(buildir)/cogl directory here is to make it so -# that tests that directly include Cogl source code for whitebox -# testing (such as test-bitmask) will still compile -AM_CPPFLAGS = \ - -I$(top_srcdir) \ - -I$(top_srcdir)/test-fixtures \ - -I$(top_builddir)/cogl - -AM_CPPFLAGS += \ - -DCOGL_DISABLE_DEPRECATED \ - -DTESTS_DATADIR=\""$(top_srcdir)/tests/data"\" \ - -DCOGL_COMPILATION - -test_unit_CFLAGS = -g3 -O0 $(COGL_DEP_CFLAGS) $(COGL_EXTRA_CFLAGS) -test_unit_LDADD = \ - $(COGL_DEP_LIBS) \ - $(top_builddir)/cogl/libmuffin-cogl-$(MUFFIN_PLUGIN_API_VERSION).la \ - $(LIBM) -test_unit_LDFLAGS = -export-dynamic - -# XXX: uncomment when tests get fixed -#test: wrappers -# @$(top_srcdir)/tests/run-tests.sh $(abs_builddir)/../config.env $(abs_builddir)/test-unit$(EXEEXT) - -# XXX: we could prevent the unit test suite from running -# by simply defining this variable conditionally -TEST_PROGS = test-unit - -.PHONY: test - -DISTCLEANFILES = .gitignore - -# we override the clean-generic target to clean up the wrappers so -# we cannot use CLEANFILES -clean-generic: clean-wrappers - $(QUIET_RM)rm -f .log diff --git a/cogl/tests/unit/meson.build b/cogl/tests/unit/meson.build new file mode 100644 index 000000000..289245e29 --- /dev/null +++ b/cogl/tests/unit/meson.build @@ -0,0 +1,43 @@ +cogl_test_unit_sources = [ + 'test-unit-main.c', +] + +cogl_test_unit_includes = [ + cogl_includepath, + cogl_test_fixtures_includepath, +] + +libmutter_cogl_test_unit = executable('test-unit', + sources: cogl_test_unit_sources, + c_args: cogl_debug_c_args + [ + '-DCOGL_DISABLE_DEPRECATED', + '-DCOGL_COMPILATION', + '-DTESTS_DATADIR="@0@/tests/data"'.format(cogl_srcdir), + ], + include_directories: cogl_test_unit_includes, + dependencies: [ + libmutter_cogl_dep, + libmutter_cogl_path_dep, + libmutter_cogl_test_fixtures_dep, + ], + install: false, +) + +cogl_unit_tests = run_command( + find_program('meson/find-unit-tests.sh'), cogl_srcdir, '/dev/stdout', + check: true, +).stdout().strip().split('\n') + +foreach test_target: cogl_unit_tests + test_name = '-'.join(test_target.split('_')) + test(test_name, cogl_run_tests, + suite: ['cogl', 'cogl/unit'], + env: ['RUN_TESTS_QUIET=1'], + args: [ + cogl_config_env, + libmutter_cogl_test_unit, + 'unit_test_' + test_target + ], + is_parallel: false, + ) +endforeach diff --git a/cogl/tests/unit/meson/find-unit-tests.sh b/cogl/tests/unit/meson/find-unit-tests.sh new file mode 100755 index 000000000..dc8ceb2bc --- /dev/null +++ b/cogl/tests/unit/meson/find-unit-tests.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +inputdir="$1" +outputfile="$2" + +echo > "$outputfile" + +grep -h -r --include \*.c UNIT_TEST "$inputdir" | \ + sed -n -e 's/^UNIT_TEST *( *\([a-zA-Z0-9_]\{1,\}\).*/\1/p' > "$outputfile" diff --git a/config.h.meson b/config.h.meson new file mode 100644 index 000000000..0edff4d57 --- /dev/null +++ b/config.h.meson @@ -0,0 +1,72 @@ +/* The prefix for our gettext translation domains. */ +#mesondefine GETTEXT_PACKAGE + +/* Version number of package */ +#mesondefine VERSION + +/* Version number of package */ +#mesondefine PACKAGE_VERSION + +/* Search path for plugins */ +#mesondefine MUTTER_PLUGIN_DIR + +/* */ +#mesondefine MUTTER_LOCALEDIR + +/* */ +#mesondefine MUTTER_LIBEXECDIR + +/* */ +#mesondefine MUTTER_PKGDATADIR + +/* Defined if EGL support is enabled */ +#mesondefine HAVE_EGL + +/* Defined if EGLDevice support is enabled */ +#mesondefine HAVE_EGL_DEVICE + +/* Defined if EGLStream support is enabled */ +#mesondefine HAVE_WAYLAND_EGLSTREAM + +/* Building with gudev for device type detection */ +#mesondefine HAVE_LIBGUDEV + +/* Building with libwacom for advanced tablet management */ +#mesondefine HAVE_LIBWACOM + +/* Define if you want to enable the native (KMS) backend based on systemd */ +#mesondefine HAVE_NATIVE_BACKEND + +/* Define if you want to enable Wayland support */ +#mesondefine HAVE_WAYLAND + +/* Defined if screen cast and remote desktop support is enabled */ +#mesondefine HAVE_REMOTE_DESKTOP + +/* Building with SM support */ +#mesondefine HAVE_SM + +/* Building with startup notification support */ +#mesondefine HAVE_STARTUP_NOTIFICATION + +/* Building with Sysprof profiling suport */ +#mesondefine HAVE_PROFILER + +/* Path to Xwayland executable */ +#mesondefine XWAYLAND_PATH + +/* Xwayland applications allowed to issue keyboard grabs */ +#mesondefine XWAYLAND_GRAB_DEFAULT_ACCESS_RULES + +/* XKB base prefix */ +#mesondefine XKB_BASE + +/* Whether exists and it defines prctl() */ +#mesondefine HAVE_SYS_PRCTL + +/* Either or */ +#mesondefine HAVE_SYS_RANDOM +#mesondefine HAVE_LINUX_RANDOM + +/* Whether Xwayland has -initfd option */ +#mesondefine HAVE_XWAYLAND_INITFD diff --git a/configure.ac b/configure.ac deleted file mode 100644 index 1ec02d7f9..000000000 --- a/configure.ac +++ /dev/null @@ -1,543 +0,0 @@ -AC_PREREQ(2.50) - -m4_define([muffin_major_version], [5]) -m4_define([muffin_minor_version], [2]) -m4_define([muffin_micro_version], [1]) - -m4_define([muffin_version], - [muffin_major_version.muffin_minor_version.muffin_micro_version]) - -m4_define([muffin_plugin_api_version], [0]) - -AC_INIT([muffin], [muffin_version], - [https://github.com/linuxmint/muffin/issues]) - -m4_ifdef([AX_IS_RELEASE], [AX_IS_RELEASE([always])]) - -AC_CONFIG_SRCDIR(src/core/display.c) -AC_CONFIG_HEADERS(config.h) -AC_CONFIG_SUBDIRS([cogl clutter]) - -AC_CONFIG_MACRO_DIR(m4) -AM_INIT_AUTOMAKE([1.11 no-dist-gzip dist-xz tar-ustar subdir-objects]) -m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])],) -AM_MAINTAINER_MODE([enable]) - -AC_GNU_SOURCE - -MUFFIN_MAJOR_VERSION=muffin_major_version -MUFFIN_MINOR_VERSION=muffin_minor_version -MUFFIN_MICRO_VERSION=muffin_micro_version -MUFFIN_VERSION=muffin_version -MUFFIN_PLUGIN_API_VERSION=muffin_plugin_api_version -AC_SUBST(MUFFIN_MAJOR_VERSION) -AC_SUBST(MUFFIN_MINOR_VERSION) -AC_SUBST(MUFFIN_MICRO_VERSION) -AC_SUBST(MUFFIN_VERSION) -AC_SUBST(MUFFIN_PLUGIN_API_VERSION) - -# Make the muffin versions visible to the cogl and clutter subdirs -export MUFFIN_PLUGIN_API_VERSION MUFFIN_VERSION - -MUFFIN_PLUGIN_DIR="$libdir/$PACKAGE/plugins" -AC_SUBST(MUFFIN_PLUGIN_DIR) - -# Honor aclocal flags - dnl ensure that when the Automake generated makefile calls aclocal, - dnl it honours the $ACLOCAL_FLAGS environment variable - ACLOCAL_AMFLAGS="\${ACLOCAL_FLAGS}" - if test -n "$ac_macro_dir"; then - ACLOCAL_AMFLAGS="-I $ac_macro_dir $ACLOCAL_AMFLAGS" - fi - AC_SUBST([ACLOCAL_AMFLAGS]) - -GETTEXT_PACKAGE=muffin -AC_SUBST(GETTEXT_PACKAGE) -AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE",[Name of default gettext domain]) - -LT_PREREQ([2.2.6]) -LT_INIT([disable-static]) - -# Debian / Ubuntu set this flag to 'no' in libtool, causing linking errors -# (i.e when linking against muffin-clutter). Not to explicitly redefine such -# deps, we enable this flag for everybody. -link_all_deplibs=yes -link_all_deplibs_CXX=yes - -IT_PROG_INTLTOOL([0.34.90]) -AC_PROG_CC -AM_PROG_CC_C_O -AC_ISC_POSIX -AC_PROG_INSTALL -AC_PROG_SED -AC_HEADER_STDC -AC_LIBTOOL_WIN32_DLL -AM_PROG_LIBTOOL -PKG_PROG_PKG_CONFIG([0.21]) - -# Sets GLIB_GENMARSHAL and GLIB_MKENUMS -AM_PATH_GLIB_2_0([2.50.3]) - -#### Integer sizes - -AC_CHECK_SIZEOF(char) -AC_CHECK_SIZEOF(short) -AC_CHECK_SIZEOF(long) -AC_CHECK_SIZEOF(int) -AC_CHECK_SIZEOF(void *) -AC_CHECK_SIZEOF(long long) -AC_CHECK_SIZEOF(__int64) - -## byte order -AC_C_BIGENDIAN - -#### Usability of visibility attributes -gl_VISIBILITY -AC_DEFINE(LOCAL_SYMBOL, [], [attribute of the non-exported symbols]) -AC_DEFINE(API_EXPORTED, [], [attribute of the symbols exported in the API]) -if test $HAVE_VISIBILITY = 1; then - AC_DEFINE(LOCAL_SYMBOL, [__attribute__ ((visibility ("hidden")))]) - AC_DEFINE(API_EXPORTED, [__attribute__ ((visibility ("default")))]) -fi - - -CANBERRA_GTK=libcanberra-gtk3 -CANBERRA_GTK_VERSION=0.26 - -MUFFIN_PC_MODULES=" - gtk+-3.0 >= 3.9.12 - gio-unix-2.0 >= 2.35.1 - glib-2.0 - pango >= 1.14.0 - cairo >= 1.10.0 - json-glib-1.0 - cinnamon-desktop >= 2.4.0 - xcomposite >= 0.3 - xcursor - xdamage - xext - xfixes - xi >= 1.6.0 - xkbfile - xkeyboard-config - xkbcommon >= 0.4.3 - xkbcommon-x11 - xrender - x11-xcb - xcb-randr - xcb-res - gl - egl -" - -GLIB_GSETTINGS - -AC_ARG_ENABLE(verbose-mode, - AC_HELP_STRING([--disable-verbose-mode], - [disable muffin's ability to do verbose logging, for embedded/size-sensitive custom builds]),, - enable_verbose_mode=yes) -dnl ' - -if test x$enable_verbose_mode = xyes; then - AC_DEFINE(WITH_VERBOSE_MODE,1,[Build with verbose mode support]) -fi - -AC_ARG_ENABLE([gtk-doc], - AC_HELP_STRING([--enable-gtk-doc], - [use gtk-doc to build documentation [[default=yes]]]),, - enable_gtk_doc=yes) - -# prefixes for fixing gtk-doc references -CAIRO_PREFIX="`$PKG_CONFIG --variable=prefix cairo`" -GLIB_PREFIX="`$PKG_CONFIG --variable=prefix glib-2.0`" -PANGO_PREFIX="/usr" -ATK_PREFIX="`$PKG_CONFIG --variable=prefix atk`" -GDKPIXBUF_PREFIX="`$PKG_CONFIG --variable=prefix gdk-pixbuf-2.0`" -AC_SUBST(CAIRO_PREFIX) -AC_SUBST(GLIB_PREFIX) -AC_SUBST(PANGO_PREFIX) -AC_SUBST(ATK_PREFIX) -AC_SUBST(GDKPIXBUF_PREFIX) - -AC_ARG_ENABLE(sm, - AC_HELP_STRING([--disable-sm], - [disable muffin's session management support, for embedded/size-sensitive custom non-GNOME builds]),, - enable_sm=auto) -dnl ' - - -AC_ARG_ENABLE(startup-notification, - AC_HELP_STRING([--disable-startup-notification], - [disable muffin's startup notification support, for embedded/size-sensitive custom non-GNOME builds]),, - enable_startup_notification=auto) -dnl ' - -AC_ARG_WITH(libcanberra, - AC_HELP_STRING([--without-libcanberra], - [disable the use of libcanberra for playing sounds]),, - with_libcanberra=auto) - -AC_ARG_ENABLE(xsync, - AC_HELP_STRING([--disable-xsync], - [disable muffin's use of the XSync extension]),, - enable_xsync=auto) -dnl ' - -AC_ARG_ENABLE(shape, - AC_HELP_STRING([--disable-shape], - [disable muffin's use of the shaped window extension]),, - enable_shape=auto) -dnl ' - -## try definining HAVE_BACKTRACE -AC_CHECK_HEADERS(execinfo.h, [AC_CHECK_FUNCS(backtrace)]) - -AM_GLIB_GNU_GETTEXT - -## here we get the flags we'll actually use -PKG_CHECK_MODULES(ALL, glib-2.0 >= 2.37.3) -PKG_CHECK_MODULES(MUFFIN_MESSAGE, gtk+-3.0) -PKG_CHECK_MODULES(MUFFIN_WINDOW_DEMO, gtk+-3.0) - -# Unconditionally use this dir to avoid a circular dep with gnomecc -GNOME_KEYBINDINGS_KEYSDIR="${datadir}/gnome-control-center/keybindings" -AC_SUBST(GNOME_KEYBINDINGS_KEYSDIR) - -STARTUP_NOTIFICATION_VERSION=0.7 -AC_MSG_CHECKING([Startup notification library >= $STARTUP_NOTIFICATION_VERSION]) -if $PKG_CONFIG --atleast-version $STARTUP_NOTIFICATION_VERSION libstartup-notification-1.0; then - have_startup_notification=yes -else - have_startup_notification=no -fi -AC_MSG_RESULT($have_startup_notification) - -if test x$enable_startup_notification = xyes; then - have_startup_notification=yes - echo "startup-notification support forced on" -elif test x$enable_startup_notification = xauto; then - true -else - have_startup_notification=no -fi - -if test x$have_startup_notification = xyes; then - echo "Building with libstartup-notification" - MUFFIN_PC_MODULES="$MUFFIN_PC_MODULES libstartup-notification-1.0 >= $STARTUP_NOTIFICATION_VERSION" - AC_DEFINE(HAVE_STARTUP_NOTIFICATION, , [Building with startup notification support]) -else - echo "Building without libstartup-notification" -fi - -have_libcanberra=no -AC_MSG_CHECKING([libcanberra-gtk]) -if test x$with_libcanberra = xno ; then - AC_MSG_RESULT([disabled]) -else - if $PKG_CONFIG --exists $CANBERRA_GTK '>=' $CANBERRA_GTK_VERSION; then - have_libcanberra=yes - AC_MSG_RESULT(yes) - MUFFIN_PC_MODULES="$MUFFIN_PC_MODULES $CANBERRA_GTK" - AC_DEFINE([HAVE_LIBCANBERRA], 1, [Building with libcanberra for playing sounds]) - else - AC_MSG_RESULT(no) - if test x$with_libcanberra = xyes ; then - AC_MSG_ERROR([libcanberra forced and libcanberra-gtk was not found]) - fi - fi -fi - -INTROSPECTION_VERSION=0.9.2 -GOBJECT_INTROSPECTION_CHECK([$INTROSPECTION_VERSION]) - -if test x$found_introspection != xno; then - AC_DEFINE(HAVE_INTROSPECTION, 1, [Define if GObject introspection is available]) - MUFFIN_PC_MODULES="$MUFFIN_PC_MODULES gobject-introspection-1.0" - # Since we don't make any guarantees about stability and we don't support - # parallel install, there's no real reason to change directories, filenames, - # etc. as we change the Muffin tarball version. Note that this must match - # api_version in src/Makefile.am - - # This is set to a magic number which is different from the API which - # Mutter uses. Otherwise there will be dependency conflicts in RPM - # based distributions that automatically resolve typelib file dependencies. - META_GIR=Meta_Muffin_0_gir - # META_GIR=[Meta_]muffin_major_version[_]muffin_minor_version[_gir] - AC_SUBST(META_GIR) -fi - -AC_MSG_CHECKING([Xcursor]) -if $PKG_CONFIG xcursor; then - have_xcursor=yes - else - have_xcursor=no - fi - AC_MSG_RESULT($have_xcursor) - -if test x$have_xcursor = xyes; then - echo "Building with Xcursor" - MUFFIN_PC_MODULES="$MUFFIN_PC_MODULES xcursor" - AC_DEFINE(HAVE_XCURSOR, , [Building with Xcursor support]) -fi - -PKG_CHECK_MODULES(MUFFIN, $MUFFIN_PC_MODULES) - -AC_PATH_XTRA - -ALL_X_LIBS="$X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS" - -# Check for Xinerama extension (Solaris impl or Xfree impl) -muffin_save_cppflags="$CPPFLAGS" -CPPFLAGS="$CPPFLAGS $X_CFLAGS" - -AC_ARG_ENABLE(xinerama, - AC_HELP_STRING([--disable-xinerama], - [disable muffin's use of the Xinerama extension]), - try_xinerama=$enable_xinerama,try_xinerama=yes) -dnl ' - -use_solaris_xinerama=no -use_xfree_xinerama=no -if test "${try_xinerama}" != no; then - case "$host" in - *-*-solaris*) - # Check for solaris - use_solaris_xinerama=yes - AC_CHECK_LIB(Xext, XineramaGetInfo, - use_solaris_xinerama=yes, use_solaris_xinerama=no, - $ALL_X_LIBS) - if test "x$use_solaris_xinerama" = "xyes"; then - AC_CHECK_HEADER(X11/extensions/xinerama.h, - if test -z "`echo $ALL_X_LIBS | grep "\-lXext" 2> /dev/null`"; then - X_EXTRA_LIBS="-lXext $X_EXTRA_LIBS" - fi - AC_DEFINE(HAVE_SOLARIS_XINERAMA, , [Have Solaris-style Xinerama]) - AC_DEFINE(HAVE_XINERAMA, , [Have some version of Xinerama]), - use_solaris_xinerama=no, - [#include ]) - fi - AC_MSG_CHECKING(for Xinerama support on Solaris) - AC_MSG_RESULT($use_solaris_xinerama); - ;; - *) - # Check for XFree - use_xfree_xinerama=yes - AC_CHECK_LIB(Xinerama, XineramaQueryExtension, - [AC_CHECK_HEADER(X11/extensions/Xinerama.h, - X_EXTRA_LIBS="-lXinerama $X_EXTRA_LIBS" - if test -z "`echo $ALL_X_LIBS | grep "\-lXext" 2> /dev/null`"; then - X_EXTRA_LIBS="-lXext $X_EXTRA_LIBS" - fi - AC_DEFINE(HAVE_XFREE_XINERAMA, , [Have XFree86-style Xinerama]) - AC_DEFINE(HAVE_XINERAMA,, [Have some version of Xinerama]), - use_xfree_xinerama=no, - [#include ])], - use_xfree_xinerama=no, -lXext $ALL_X_LIBS) - AC_MSG_CHECKING(for Xinerama support on XFree86) - AC_MSG_RESULT($use_xfree_xinerama); - ;; - esac -fi - -CPPFLAGS="$muffin_save_cppflags" - -SHAPE_LIBS= -found_shape=no -AC_CHECK_LIB(Xext, XShapeQueryExtension, - [AC_CHECK_HEADER(X11/extensions/shape.h, - SHAPE_LIBS=-lXext found_shape=yes)], - , $ALL_X_LIBS) - -if test x$enable_shape = xno; then - found_shape=no -fi - -if test x$enable_shape = xyes; then - if test "$found_shape" = "no"; then - AC_MSG_ERROR([--enable-shape forced and Shape not found]) - exit 1 - fi -fi - -if test "x$found_shape" = "xyes"; then - AC_DEFINE(HAVE_SHAPE, , [Have the shape extension library]) -fi - -found_xkb=no -AC_CHECK_LIB(X11, XkbQueryExtension, - [AC_CHECK_HEADER(X11/XKBlib.h, - found_xkb=yes)], - , $ALL_X_LIBS) - -if test "x$found_xkb" = "xyes"; then - AC_DEFINE(HAVE_XKB, , [Have keyboard extension library]) -fi - - -RANDR_LIBS= -found_randr=no -AC_CHECK_LIB(Xrandr, XRRUpdateConfiguration, - [AC_CHECK_HEADER(X11/extensions/Xrandr.h, - RANDR_LIBS=-lXrandr found_randr=yes,, - [#include ])], - , -lXrender -lXext $ALL_X_LIBS) - -if test "x$found_randr" = "xyes"; then - AC_DEFINE(HAVE_RANDR, , [Have the Xrandr extension library]) -fi - -XSYNC_LIBS= -found_xsync=no -AC_CHECK_LIB(Xext, XSyncQueryExtension, - [AC_CHECK_HEADER(X11/extensions/sync.h, - found_xsync=yes,, - [#include ])], - , $ALL_X_LIBS) - -if test x$enable_xsync = xno; then - found_xsync=no -fi - -if test x$enable_xsync = xyes; then - if test "$found_xsync" = "no"; then - AC_MSG_ERROR([--enable-xsync forced and XSync not found]) - exit 1 - fi -fi - -if test "x$found_xsync" = "xyes"; then - XSYNC_LIBS=-lXext - AC_DEFINE(HAVE_XSYNC, , [Have the Xsync extension library]) -fi - -MUFFIN_LIBS="$MUFFIN_LIBS $XSYNC_LIBS $RANDR_LIBS $SHAPE_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS -lm" -MUFFIN_MESSAGE_LIBS="$MUFFIN_MESSAGE_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS" -MUFFIN_WINDOW_DEMO_LIBS="$MUFFIN_WINDOW_DEMO_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS -lm" -MUFFIN_PROPS_LIBS="$MUFFIN_PROPS_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS" - -found_sm=no -case "$MUFFIN_LIBS" in - *-lSM*) - found_sm=yes - ;; - *) - AC_CHECK_LIB(SM, SmcSaveYourselfDone, - [AC_CHECK_HEADERS(X11/SM/SMlib.h, - MUFFIN_LIBS="-lSM -lICE $MUFFIN_LIBS" found_sm=yes)], - , $MUFFIN_LIBS) - ;; -esac - -if test x$enable_sm = xno; then - found_sm=no -fi - -if test x$enable_sm = xyes; then - if test "$found_sm" = "no"; then - AC_MSG_ERROR([--enable-sm forced and -lSM not found]) - exit 1 - fi -fi - -if test "$found_sm" = "yes"; then - AC_DEFINE(HAVE_SM, , [Building with SM support]) -fi - -AM_CONDITIONAL(HAVE_SM, test "$found_sm" = "yes") - -HOST_ALIAS=$host_alias -AC_SUBST(HOST_ALIAS) - -AC_PATH_PROG(GDK_PIXBUF_CSOURCE, gdk-pixbuf-csource, no) - -if test x"$GDK_PIXBUF_CSOURCE" = xno; then - AC_MSG_ERROR([gdk-pixbuf-csource executable not found in your path - should be installed with GTK]) -fi - -AC_SUBST(GDK_PIXBUF_CSOURCE) - -AC_PATH_PROG(ZENITY, zenity, no) -if test x"$ZENITY" = xno; then - AC_MSG_ERROR([zenity not found in your path - needed for dialogs]) -fi - -AC_ARG_ENABLE(debug, - [ --enable-debug enable debugging],, - enable_debug=no) -if test "x$enable_debug" = "xyes"; then - CFLAGS="$CFLAGS -g -O" -fi - -GTK_DOC_CHECK([1.15], [--flavour no-tmpl]) - -AC_CHECK_DECL([GL_EXT_x11_sync_object], - [], - [AC_MSG_ERROR([GL_EXT_x11_sync_object definition not found, please update your GL headers])], - [#include ]) - -m4_ifdef([AX_COMPILER_FLAGS], - [AX_COMPILER_FLAGS([WARN_CFLAGS],[WARN_LDFLAGS])]) - -AC_ARG_ENABLE(clutter-doc, - [ --disable-clutter-doc disable Clutter docs generation],, - clutter_doc=yes) - -AM_CONDITIONAL(CLUTTER_DOC, test "$clutter_doc" = "yes") - -AC_CONFIG_FILES([ -Makefile -data/Makefile -doc/Makefile -doc/man/Makefile -doc/reference/Makefile -doc/reference/muffin/Makefile -doc/reference/muffin/muffin-docs.sgml -doc/reference/clutter/Makefile -doc/reference/clutter/clutter-docs.xml -doc/reference/cogl/Makefile -doc/reference/cogl/cogl-docs.xml -src/Makefile -src/wm-tester/Makefile -src/libmuffin.pc -src/muffin-plugins.pc -src/tools/Makefile -src/compositor/plugins/Makefile -po/Makefile.in -]) - -AC_OUTPUT - -COGL_PC_VERSION=$(grep Version: cogl/cogl/muffin-cogl-$MUFFIN_PLUGIN_API_VERSION.pc|awk '{ print $2; }') -AS_IF([test "x$COGL_PC_VERSION" != "x$MUFFIN_VERSION"], - [AC_MSG_ERROR([muffin-cogl pkg-config file not updated, rerun ./configure])]) - -CLUTTER_PC_VERSION=$(grep Version: clutter/clutter/muffin-clutter-$MUFFIN_PLUGIN_API_VERSION.pc|awk '{ print $2; }') -AS_IF([test "x$CLUTTER_PC_VERSION" != "x$MUFFIN_VERSION"], - [AC_MSG_ERROR([muffin-clutter pkg-config file not updated, rerun ./configure])]) - -if test x$enable_verbose_mode = xno; then - echo "*** WARNING WARNING WARNING WARNING WARNING" - echo "*** Building without verbose mode" - echo "*** This means there's no way to debug muffin problems." - echo "*** Please build normal desktop versions of muffin" - echo "*** with verbose mode enabled so users can use it when they report bugs." -fi - -dnl ========================================================================== -echo " -muffin-$VERSION - - prefix: ${prefix} - source code location: ${srcdir} - compiler: ${CC} - - XFree86 Xinerama: ${use_xfree_xinerama} - Solaris Xinerama: ${use_solaris_xinerama} - Startup notification: ${have_startup_notification} - libcanberra: ${have_libcanberra} - Introspection: ${found_introspection} - Session management: ${found_sm} - Shape extension: ${found_shape} - Xsync: ${found_xsync} - Xcursor: ${have_xcursor} -" diff --git a/data/Makefile.am b/data/Makefile.am deleted file mode 100644 index 35fca0a76..000000000 --- a/data/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -themedir = $(pkgdatadir)/theme -dist_theme_DATA = \ - theme/metacity-theme-3.xml diff --git a/data/default_icon.png b/data/default_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..5aad87988616760ef9b59b693226054cef706ac0 GIT binary patch literal 1184 zcmV;R1Yi4!P)m_86On(^3nhR1T9HK zK~#9!?O9816hRDquZYB~*npIMV4t&a6VAXDxBw^M1e_rYB!rL#At4q76iA{F2!Sz+ zD!XiV&oB*(3{qQB`cu`_{yx9z0cM$HmRW96IC5P!jNi0KJFfJcYbNZn>;pIl@Erj5 z^60DOJ3M{%eCM>jyg0{`$BzKu0f6ON1CCz4!Hd^#@!`{#oigD1>YJY41@K-k%Gl&x zQ+|^SB5?8b(p$ST^7HzKp5EGoLUML?hSSs2K1c!}NPzVp+8xxtc5L$ifTiB=V>++B zPS>adDCqa=bwR&XpZj=xjDv#%0C))C2*A712t-h&DQ546R1I};GZM|9raZliobqX$ z!j{Oi^#oFlYS-KVj(bC$X-B3|NjPJ+H5>&lQfckM!gixNC%i!;OKxufQ>ekF5Me5r zp+O@?MJ>&mdSY2(%5}XMR~d2ORtDq;EW-K{?=dDNIWiEnlO#K2q5;tZ z!>3)jni7MQvFI_ziKtdl6Qy)xD1ek$>^gVb6k4rT@Gd1-i;7Wu0Z{-5#i2-ypD?BP zKoJX3NLNB2>|+dRxlIZY&a(g&b=2$94XFmY)MAWKhD_wb7DBxvZLS_Q{WcZBcnY=f zvVwBP8@S3g#d-n>a(QRS6p@~MjK%9~B^0@E8jPCvG!Ifg03;$2yUM~CcJWP3Vk-3# zVJO<1k>ua>fdG{<#B_b9FyyoMB%J;94KjeQLmN`_)^+&xDOCQn&!PJ#ltddMU8qfn zgXev7>uBIRy?c*DIPRBaN)0q`H&m;SyPO8i>A{17Ul#gnwgTAk1ude>ckvCYIKj8gQ&X)WI3LA92t$uTOrB*YZl0pBcjdnSV5m7YPOQ66pwr^_1y&c8Ju>m7c006trmpJq zC)4OiCt^{1TCsf!=^Ex8II1kMuw4GrBUVzhFz;~xG+EEniIT>C#jY + + + + 'Super_L' + Modifier to use for extended window management operations + + This key will initiate the “overlay”, which is a combination window + overview and application launching system. The default is intended + to be the “Windows key” on PC hardware. + + It’s expected that this binding either the default or set to + the empty string. + + + + + false + Attach modal dialogs + + When true, instead of having independent titlebars, modal dialogs + appear attached to the titlebar of the parent window and are moved + together with the parent window. + + + + + false + Enable edge tiling when dropping windows on screen edges + + If enabled, dropping windows on vertical screen edges maximizes them + vertically and resizes them horizontally to cover half of the available + area. Dropping windows on the top screen edge maximizes them completely. + + + + + false + Workspaces are managed dynamically + + Determines whether workspaces are managed dynamically or + whether there’s a static number of workspaces (determined + by the num-workspaces key in org.cinnamon.desktop.wm.preferences). + + + + + false + Workspaces only on primary + + Determines whether workspace switching should happen for windows + on all monitors or only for windows on the primary monitor. + + + + + false + No tab popup + + Determines whether the use of popup and highlight frame should + be disabled for window cycling. + + + + + false + Delay focus changes until the pointer stops moving + + If set to true, and the focus mode is either “sloppy” or “mouse” + then the focus will not be changed immediately when entering a + window, but only after the pointer stops moving. + + + + + 10 + + Draggable border width + + The amount of total draggable borders. If the theme’s visible + borders are not enough, invisible borders will be added to meet + this value. + + + + + true + Auto maximize nearly monitor sized windows + + If enabled, new windows that are initially the size of the monitor + automatically get maximized. + + + + + false + Place new windows in the center + + When true, the new windows will always be put in the center of the + active screen of the monitor. + + + + + [] + Enable experimental features + + To enable experimental features, add the feature keyword to the list. + Whether the feature requires restarting the compositor depends on the + given feature. Any experimental feature is not required to still be + available, or configurable. Don’t expect adding anything in this + setting to be future proof. + + Currently possible keywords: + + • “scale-monitor-framebuffer” — makes muffin default to layout logical + monitors in a logical pixel coordinate + space, while scaling monitor + framebuffers instead of window content, + to manage HiDPI monitors. Does not + require a restart. + • “rt-scheduler” — makes muffin request a low priority + real-time scheduling. The executable + or user must have CAP_SYS_NICE. + Requires a restart. + • “autostart-xwayland” — initializes Xwayland lazily if there are + X11 clients. Requires restart. + • “x11-randr-fractional-scaling” — enable fractional scaling under X11 + using xrandr scaling. It might reduce + performances. + Does not require a restart. + + + + + 'Control_L' + Modifier to use to locate the pointer + + This key will initiate the “locate pointer” action. + + + + + 5000 + Timeout for check-alive ping + + Number of milliseconds a client has to respond to a ping request in + order to not be detected as frozen. Using 0 will disable the alive check + completely. + + + + + + + + + + Left']]]> + + + + Right']]]> + + + + [] + Select window from tab popup + + + + [] + Cancel tab popup + + + + p','XF86Display']]]> + Switch monitor configurations + + + + + Rotates the built-in monitor configuration + + + + diff --git a/data/org.cinnamon.muffin.wayland.gschema.xml.in b/data/org.cinnamon.muffin.wayland.gschema.xml.in new file mode 100644 index 000000000..5c4802052 --- /dev/null +++ b/data/org.cinnamon.muffin.wayland.gschema.xml.in @@ -0,0 +1,108 @@ + + + + F1']]]> + Switch to VT 1 + + + F2']]]> + Switch to VT 2 + + + F3']]]> + Switch to VT 3 + + + F4']]]> + Switch to VT 4 + + + F5']]]> + Switch to VT 5 + + + F6']]]> + Switch to VT 6 + + + F7']]]> + Switch to VT 7 + + + F8']]]> + Switch to VT 8 + + + F9']]]> + Switch to VT 9 + + + F10']]]> + Switch to VT 10 + + + F11']]]> + Switch to VT 11 + + + F12']]]> + Switch to VT 12 + + + Escape']]]> + Re-enable shortcuts + + + + + + + + false + Allow X11 grabs to lock keyboard focus with Xwayland + + Allow all keyboard events to be routed to X11 “override redirect” + windows with a grab when running in Xwayland. + + This option is to support X11 clients which map an “override redirect” + window (which do not receive keyboard focus) and issue a keyboard + grab to force all keyboard events to that window. + + This option is seldom used and has no effect on regular X11 windows + which can receive keyboard focus under normal circumstances. + + For a X11 grab to be taken into account under Wayland, the client must + also either send a specific X11 ClientMessage to the root window or be + among the applications white-listed in key “xwayland-grab-access-rules”. + + + + + [] + Xwayland applications allowed to issue keyboard grabs + + List the resource names or resource class of X11 windows either + allowed or not allowed to issue X11 keyboard grabs under Xwayland. + + The resource name or resource class of a given X11 window can be + obtained using the command “xprop WM_CLASS”. + + Wildcards “*” and jokers “?” in the values are supported. + + Values starting with “!” are blacklisted, which has precedence over + the whitelist, to revoke applications from the default system list. + + The default system list includes the following applications: + + “@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” + + Users can break an existing grab by using the specific keyboard + shortcut defined by the keybinding key “restore-shortcuts”. + + + + + + diff --git a/data/org.cinnamon.muffin.x11.gschema.xml.in b/data/org.cinnamon.muffin.x11.gschema.xml.in new file mode 100644 index 000000000..3e145fb0b --- /dev/null +++ b/data/org.cinnamon.muffin.x11.gschema.xml.in @@ -0,0 +1,30 @@ + + + + + + + + + + + "scale-ui-down" + + Choose the scaling mode to be used under X11 via Randr extension. + + Supported methods are: + + • “scale-up” — Scale everything up to the requested scale, shrinking + the UI. The applications will look blurry when scaling + at higher values and the resolution will be lowered. + • “scale-ui-down — Scale up the UI toolkits to the closest integer + scaling value upwards, while scale down the display + to match the requested scaling level. + It increases the resolution of the logical display. + + + + + + diff --git a/data/theme/metacity-theme-3.xml b/data/theme/metacity-theme-3.xml deleted file mode 100644 index b784faa63..000000000 --- a/data/theme/metacity-theme-3.xml +++ /dev/null @@ -1,1723 +0,0 @@ - - - - Adwaita - GNOME Art Team <art.gnome.org> - Â Intel, Â Red Hat, Lapo Calamandrei - 2014 - Default GNOME 3 window theme - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <title version="< 3.1" - x="(0 `max` ((width - title_width) / 2))" - y="(0 `max` ((height - title_height) / 2))" - color="C_title_focused_hilight_dark" /> - <title version="< 3.1" - x="(0 `max` ((width - title_width) / 2))" - y="(0 `max` ((height - title_height) / 2)) + 1" - color="C_title_focused" /> - <title version=">= 3.1" - x="(0 `max` ((frame_x_center - title_width / 2) `min` (width - title_width)))" - y="(0 `max` ((height - title_height) / 2)) + 2" - ellipsize_width="width" - color="C_title_focused_hilight" /> - <title version=">= 3.1" - x="(0 `max` ((frame_x_center - title_width / 2) `min` (width - title_width)))" - y="(0 `max` ((height - title_height) / 2))" - ellipsize_width="width" - color="C_title_focused_hilight_dark" /> - <title version=">= 3.1" - x="(0 `max` ((frame_x_center - title_width / 2) `min` (width - title_width)))" - y="(0 `max` ((height - title_height) / 2)) + 1" - ellipsize_width="width" - color="C_title_focused" /> -</draw_ops> - -<draw_ops name="title_unfocused"> - <title version="< 3.1" - x="(0 `max` ((width - title_width) / 2))" - y="(0 `max` ((height - title_height) / 2)) + 1" - color="C_title_unfocused"/> - <title version=">= 3.1" - x="(0 `max` ((frame_x_center - title_width/2) `min` (width - title_width)))" - y="(0 `max` ((height - title_height) / 2)) + 1" - ellipsize_width="width" - color="C_title_unfocused"/> -</draw_ops> - - <!-- window decorations --> - -<draw_ops name="entire_background_focused"> - <rectangle color="gtk:bg[NORMAL]" x="0" y="0" width="width" height="height" filled="true" /> -</draw_ops> - -<draw_ops name="entire_background_unfocused"> - <include name="entire_background_focused" /> -</draw_ops> - -<draw_ops name="titlebar_fill_focused"> - <gradient type="vertical" x="0" y="0" width="width" height="height"> - <color value="gtk:custom(wm_bg_a,blend/gtk:bg[NORMAL]/gtk:base[NORMAL]/0.4)" /> - <color value="gtk:custom(wm_bg_b,gtk:bg[NORMAL])" /> - </gradient> -</draw_ops> - - -<draw_ops name="titlebar_fill_unfocused"> - <rectangle color="C_titlebar_unfocused" x="0" y="0" width="width" height="height" filled="true" /> -</draw_ops> - -<draw_ops name="hilight"> - <line x1="0" y1="1" x2="width-1" y2="1" color="C_titlebar_focused_hilight" /> -</draw_ops> - -<draw_ops name="rounded_hilight"> - <line x1="5" y1="1" x2="width-6" y2="1" color="C_titlebar_focused_hilight" /> - <arc color="C_titlebar_focused_hilight" x="0" y="1" width="8" height="7" start_angle="270" extent_angle="90" /> - <arc color="C_titlebar_focused_hilight" x="width-10" y="1" width="9" height="7" start_angle="0" extent_angle="90" /> -</draw_ops> - -<draw_ops name="titlebar_focused"> - <include name="titlebar_fill_focused" /> - <include name="hilight" /> -</draw_ops> - -<draw_ops name="rounded_titlebar_focused"> - <include name="titlebar_fill_focused" /> - <include name="rounded_hilight" /> -</draw_ops> - -<draw_ops name="rounded_titlebar_focused_alt"> - <include name="titlebar_fill_focused" /> - <include name="rounded_hilight" /> -</draw_ops> - -<draw_ops name="rounded_titlebar_unfocused"> - <include name="titlebar_fill_unfocused" /> - <include name="rounded_hilight" /> -</draw_ops> - -<draw_ops name="titlebar_unfocused"> - <include name="titlebar_fill_unfocused" /> - <include name="hilight" /> -</draw_ops> - -<draw_ops name="border_focused"> - <rectangle color="C_border_focused" x="0" y="0" width="width-1" height="height-1" filled="false" /> -</draw_ops> - -<draw_ops name="border_unfocused"> - <rectangle color="C_border_unfocused" x="0" y="0" width="width-1" height="height-1" filled="false" /> -</draw_ops> - -<draw_ops name="rounded_border_focused"> - <line color="C_border_focused" x1="4" y1="0" x2="width-5" y2="0" /> - <line color="C_border_focused" x1="0" y1="height-1" x2="width-1" y2="height-1" /> - <line color="C_border_focused" x1="0" y1="4" x2="0" y2="height-2" /> - <line color="C_border_focused" x1="width-1" y1="4" x2="width-1" y2="height-2" /> - <arc color="C_border_focused" x="0" y="0" width="9" height="9" start_angle="270" extent_angle="90" /> - <arc color="C_border_focused" x="width-10" y="0" width="9" height="9" start_angle="0" extent_angle="90" /> - <!-- double arcs for darker borders --> - <arc color="C_border_focused" x="0" y="0" width="9" height="9" start_angle="270" extent_angle="90" /> - <arc color="C_border_focused" x="width-10" y="0" width="9" height="9" start_angle="0" extent_angle="90" /> -</draw_ops> - -<draw_ops name="rounded_border_unfocused"> - <line color="C_border_unfocused" x1="4" y1="0" x2="width-5" y2="0" /> - <line color="C_border_unfocused" x1="0" y1="height-1" x2="width-1" y2="height-1" /> - <line color="C_border_unfocused" x1="0" y1="4" x2="0" y2="height-2" /> - <line color="C_border_unfocused" x1="width-1" y1="4" x2="width-1" y2="height-2" /> - <arc color="C_border_unfocused" x="0" y="0" width="9" height="9" start_angle="270" extent_angle="90" /> - <arc color="C_border_unfocused" x="width-10" y="0" width="9" height="9" start_angle="0" extent_angle="90" /> - - <!-- double arcs for darker borders --> - <arc color="C_border_unfocused" x="0" y="0" width="9" height="9" start_angle="270" extent_angle="90" /> - <arc color="C_border_unfocused" x="width-10" y="0" width="9" height="9" start_angle="0" extent_angle="90" /> -</draw_ops> - - - -<draw_ops name="border_left_focused"> - <line - x1="0" y1="0" - x2="0" y2="height" - color="C_border_focused" /> -</draw_ops> - -<draw_ops name="border_left_unfocused"> - <line - x1="0" y1="0" - x2="0" y2="height" - color="C_border_unfocused" /> -</draw_ops> - - <!-- button icons--> - - -<draw_ops name="close_shadow_focused"> - <line - x1="(width-width%3)/3+D_icons_shrink-D_icons_grow" y1="(height-height%3)/3+D_icons_shrink-D_icons_grow" - x2="width-(width-width%3)/3-1-D_icons_shrink+D_icons_grow" y2="height-(height-height%3)/3-1-D_icons_shrink+D_icons_grow" - color="C_icons_shadow" /> - <line - x1="(width-width%3)/3+1+D_icons_shrink-D_icons_grow" y1="(height-height%3)/3+D_icons_shrink-D_icons_grow" - x2="width-(width-width%3)/3-1-D_icons_shrink+D_icons_grow" y2="height-(height-height%3)/3-2-D_icons_shrink+D_icons_grow" - color="C_icons_shadow" /> - <line - x1="(width-width%3)/3+D_icons_shrink-D_icons_grow" y1="(height-height%3)/3+1+D_icons_shrink-D_icons_grow" - x2="width-(width-width%3)/3-2-D_icons_shrink+D_icons_grow" y2="height-(height-height%3)/3-1-D_icons_shrink+D_icons_grow" - color="C_icons_shadow" /> - <line - x1="width-(width-width%3)/3-1-D_icons_shrink+D_icons_grow" y1="(height-height%3)/3+D_icons_shrink-D_icons_grow" - x2="(width-width%3)/3+D_icons_shrink-D_icons_grow" y2="height-(height-height%3)/3-1-D_icons_shrink+D_icons_grow" - color="C_icons_shadow" /> - <line - x1="width-(width-width%3)/3-2-D_icons_shrink+D_icons_grow" y1="(height-height%3)/3+D_icons_shrink-D_icons_grow" - x2="(width-width%3)/3+D_icons_shrink-D_icons_grow" y2="height-(height-height%3)/3-2-D_icons_shrink+D_icons_grow" - color="C_icons_shadow" /> - <line - x1="width-(width-width%3)/3-1-D_icons_shrink+D_icons_grow" y1="(height-height%3)/3+1+D_icons_shrink-D_icons_grow" - x2="(width-width%3)/3+1+D_icons_shrink-D_icons_grow" y2="height-(height-height%3)/3-1-D_icons_shrink+D_icons_grow" - color="C_icons_shadow" /> -</draw_ops> - -<draw_ops name="close_glyph_focused"> - <line - x1="(width-width%3)/3+D_icons_shrink-D_icons_grow" y1="(height-height%3)/3+D_icons_shrink-D_icons_grow" - x2="width-(width-width%3)/3-1-D_icons_shrink+D_icons_grow" y2="height-(height-height%3)/3-1-D_icons_shrink+D_icons_grow" - color="C_icons_focused" /> - <line - x1="(width-width%3)/3+1+D_icons_shrink-D_icons_grow" y1="(height-height%3)/3+D_icons_shrink-D_icons_grow" - x2="width-(width-width%3)/3-1-D_icons_shrink+D_icons_grow" y2="height-(height-height%3)/3-2-D_icons_shrink+D_icons_grow" - color="C_icons_focused" /> - <line - x1="(width-width%3)/3+D_icons_shrink-D_icons_grow" y1="(height-height%3)/3+1+D_icons_shrink-D_icons_grow" - x2="width-(width-width%3)/3-2-D_icons_shrink+D_icons_grow" y2="height-(height-height%3)/3-1-D_icons_shrink+D_icons_grow" - color="C_icons_focused" /> - <line - x1="width-(width-width%3)/3-1-D_icons_shrink+D_icons_grow" y1="(height-height%3)/3+D_icons_shrink-D_icons_grow" - x2="(width-width%3)/3+D_icons_shrink-D_icons_grow" y2="height-(height-height%3)/3-1-D_icons_shrink+D_icons_grow" - color="C_icons_focused" /> - <line - x1="width-(width-width%3)/3-2-D_icons_shrink+D_icons_grow" y1="(height-height%3)/3+D_icons_shrink-D_icons_grow" - x2="(width-width%3)/3+D_icons_shrink-D_icons_grow" y2="height-(height-height%3)/3-2-D_icons_shrink+D_icons_grow" - color="C_icons_focused" /> - <line - x1="width-(width-width%3)/3-1-D_icons_shrink+D_icons_grow" y1="(height-height%3)/3+1+D_icons_shrink-D_icons_grow" - x2="(width-width%3)/3+1+D_icons_shrink-D_icons_grow" y2="height-(height-height%3)/3-1-D_icons_shrink+D_icons_grow" - color="C_icons_focused" /> -</draw_ops> - -<draw_ops name="close_focused"> - <include name="close_shadow_focused" y="1" /> - <include name="close_glyph_focused" /> -</draw_ops> - -<draw_ops name="close_focused_pressed"> - <include name="close_focused"/> -</draw_ops> - -<draw_ops name="close_focused_prelight"> - <include name="close_focused"/> -</draw_ops> - -<draw_ops name="close_glyph_unfocused"> - <line - x1="(width-width%3)/3+D_icons_shrink-D_icons_grow" y1="(height-height%3)/3+D_icons_shrink-D_icons_grow" - x2="width-(width-width%3)/3-1-D_icons_shrink+D_icons_grow" y2="height-(height-height%3)/3-1-D_icons_shrink+D_icons_grow" - color="C_icons_unfocused" /> - <line - x1="(width-width%3)/3+1+D_icons_shrink-D_icons_grow" y1="(height-height%3)/3+D_icons_shrink-D_icons_grow" - x2="width-(width-width%3)/3-1-D_icons_shrink+D_icons_grow" y2="height-(height-height%3)/3-2-D_icons_shrink+D_icons_grow" - color="C_icons_unfocused" /> - <line - x1="(width-width%3)/3+D_icons_shrink-D_icons_grow" y1="(height-height%3)/3+1+D_icons_shrink-D_icons_grow" - x2="width-(width-width%3)/3-2-D_icons_shrink+D_icons_grow" y2="height-(height-height%3)/3-1-D_icons_shrink+D_icons_grow" - color="C_icons_unfocused" /> - <line - x1="width-(width-width%3)/3-1-D_icons_shrink+D_icons_grow" y1="(height-height%3)/3+D_icons_shrink-D_icons_grow" - x2="(width-width%3)/3+D_icons_shrink-D_icons_grow" y2="height-(height-height%3)/3-1-D_icons_shrink+D_icons_grow" - color="C_icons_unfocused" /> - <line - x1="width-(width-width%3)/3-2-D_icons_shrink+D_icons_grow" y1="(height-height%3)/3+D_icons_shrink-D_icons_grow" - x2="(width-width%3)/3+D_icons_shrink-D_icons_grow" y2="height-(height-height%3)/3-2-D_icons_shrink+D_icons_grow" - color="C_icons_unfocused" /> - <line - x1="width-(width-width%3)/3-1-D_icons_shrink+D_icons_grow" y1="(height-height%3)/3+1+D_icons_shrink-D_icons_grow" - x2="(width-width%3)/3+1+D_icons_shrink-D_icons_grow" y2="height-(height-height%3)/3-1-D_icons_shrink+D_icons_grow" - color="C_icons_unfocused" /> -</draw_ops> - -<draw_ops name="close_unfocused"> - <include name="close_glyph_unfocused" y="D_icons_unfocused_offset" /> -</draw_ops> - -<draw_ops name="close_glyph_unfocused_prelight"> - <line - x1="(width-width%3)/3+D_icons_shrink-D_icons_grow" y1="(height-height%3)/3+D_icons_shrink-D_icons_grow" - x2="width-(width-width%3)/3-1-D_icons_shrink+D_icons_grow" y2="height-(height-height%3)/3-1-D_icons_shrink+D_icons_grow" - color="C_icons_unfocused_prelight" /> - <line - x1="(width-width%3)/3+1+D_icons_shrink-D_icons_grow" y1="(height-height%3)/3+D_icons_shrink-D_icons_grow" - x2="width-(width-width%3)/3-1-D_icons_shrink+D_icons_grow" y2="height-(height-height%3)/3-2-D_icons_shrink+D_icons_grow" - color="C_icons_unfocused_prelight" /> - <line - x1="(width-width%3)/3+D_icons_shrink-D_icons_grow" y1="(height-height%3)/3+1+D_icons_shrink-D_icons_grow" - x2="width-(width-width%3)/3-2-D_icons_shrink+D_icons_grow" y2="height-(height-height%3)/3-1-D_icons_shrink+D_icons_grow" - color="C_icons_unfocused_prelight" /> - <line - x1="width-(width-width%3)/3-1-D_icons_shrink+D_icons_grow" y1="(height-height%3)/3+D_icons_shrink-D_icons_grow" - x2="(width-width%3)/3+D_icons_shrink-D_icons_grow" y2="height-(height-height%3)/3-1-D_icons_shrink+D_icons_grow" - color="C_icons_unfocused_prelight" /> - <line - x1="width-(width-width%3)/3-2-D_icons_shrink+D_icons_grow" y1="(height-height%3)/3+D_icons_shrink-D_icons_grow" - x2="(width-width%3)/3+D_icons_shrink-D_icons_grow" y2="height-(height-height%3)/3-2-D_icons_shrink+D_icons_grow" - color="C_icons_unfocused_prelight" /> - <line - x1="width-(width-width%3)/3-1-D_icons_shrink+D_icons_grow" y1="(height-height%3)/3+1+D_icons_shrink-D_icons_grow" - x2="(width-width%3)/3+1+D_icons_shrink-D_icons_grow" y2="height-(height-height%3)/3-1-D_icons_shrink+D_icons_grow" - color="C_icons_unfocused_prelight" /> -</draw_ops> - -<draw_ops name="close_unfocused_prelight"> - <include name="close_glyph_unfocused_prelight" y="D_icons_unfocused_offset" /> -</draw_ops> - -<draw_ops name="close_glyph_unfocused_pressed"> - <line - x1="(width-width%3)/3+D_icons_shrink-D_icons_grow" y1="(height-height%3)/3+D_icons_shrink-D_icons_grow" - x2="width-(width-width%3)/3-1-D_icons_shrink+D_icons_grow" y2="height-(height-height%3)/3-1-D_icons_shrink+D_icons_grow" - color="C_icons_unfocused_pressed" /> - <line - x1="(width-width%3)/3+1+D_icons_shrink-D_icons_grow" y1="(height-height%3)/3+D_icons_shrink-D_icons_grow" - x2="width-(width-width%3)/3-1-D_icons_shrink+D_icons_grow" y2="height-(height-height%3)/3-2-D_icons_shrink+D_icons_grow" - color="C_icons_unfocused_pressed" /> - <line - x1="(width-width%3)/3+D_icons_shrink-D_icons_grow" y1="(height-height%3)/3+1+D_icons_shrink-D_icons_grow" - x2="width-(width-width%3)/3-2-D_icons_shrink+D_icons_grow" y2="height-(height-height%3)/3-1-D_icons_shrink+D_icons_grow" - color="C_icons_unfocused_pressed" /> - <line - x1="width-(width-width%3)/3-1-D_icons_shrink+D_icons_grow" y1="(height-height%3)/3+D_icons_shrink-D_icons_grow" - x2="(width-width%3)/3+D_icons_shrink-D_icons_grow" y2="height-(height-height%3)/3-1-D_icons_shrink+D_icons_grow" - color="C_icons_unfocused_pressed" /> - <line - x1="width-(width-width%3)/3-2-D_icons_shrink+D_icons_grow" y1="(height-height%3)/3+D_icons_shrink-D_icons_grow" - x2="(width-width%3)/3+D_icons_shrink-D_icons_grow" y2="height-(height-height%3)/3-2-D_icons_shrink+D_icons_grow" - color="C_icons_unfocused_pressed" /> - <line - x1="width-(width-width%3)/3-1-D_icons_shrink+D_icons_grow" y1="(height-height%3)/3+1+D_icons_shrink-D_icons_grow" - x2="(width-width%3)/3+1+D_icons_shrink-D_icons_grow" y2="height-(height-height%3)/3-1-D_icons_shrink+D_icons_grow" - color="C_icons_unfocused_pressed" /> -</draw_ops> - -<draw_ops name="close_unfocused_pressed"> - <include name="close_glyph_unfocused_pressed" y="D_icons_unfocused_offset" /> -</draw_ops> - -<draw_ops name="maximize_glyph_focused"> - <rectangle - x="(width-width%3)/3+D_icons_shrink-D_icons_grow" y="(height-height%3)/3+D_icons_shrink-D_icons_grow" - width="width-2*(width-width%3)/3-1-2*D_icons_shrink+2*D_icons_grow" height="height-2*(height-height%3)/3-1-2*D_icons_shrink+2*D_icons_grow" - color="C_icons_focused" /> - <rectangle - x="(width-width%3)/3+1+D_icons_shrink-D_icons_grow" y="(height-height%3)/3+1+D_icons_shrink-D_icons_grow" - width="width-2*(width-width%3)/3-3-2*D_icons_shrink+2*D_icons_grow" height="height-2*(height-height%3)/3-3-2*D_icons_shrink+2*D_icons_grow" - color="C_icons_focused" /> -</draw_ops> - -<draw_ops name="maximize_shadow_focused"> - <rectangle - x="(width-width%3)/3+D_icons_shrink-D_icons_grow" y="(height-height%3)/3+D_icons_shrink-D_icons_grow" - width="width-2*(width-width%3)/3-1-2*D_icons_shrink+2*D_icons_grow" height="height-2*(height-height%3)/3-1-2*D_icons_shrink+2*D_icons_grow" - color="C_icons_shadow" /> - <rectangle - x="(width-width%3)/3+1+D_icons_shrink-D_icons_grow" y="(height-height%3)/3+1+D_icons_shrink-D_icons_grow" - width="width-2*(width-width%3)/3-3-2*D_icons_shrink+2*D_icons_grow" height="height-2*(height-height%3)/3-3-2*D_icons_shrink+2*D_icons_grow" - color="C_icons_shadow" /> -</draw_ops> - -<draw_ops name="maximize_focused"> - <include name="maximize_shadow_focused" y="1" /> - <include name="maximize_glyph_focused" /> -</draw_ops> - -<draw_ops name="maximize_focused_pressed"> - <include name="maximize_focused" /> -</draw_ops> - -<draw_ops name="maximize_focused_prelight"> - <include name="maximize_focused" /> -</draw_ops> - -<draw_ops name="maximize_glyph_unfocused"> - <rectangle - x="(width-width%3)/3+D_icons_shrink-D_icons_grow" y="(height-height%3)/3+D_icons_shrink-D_icons_grow" - width="width-2*(width-width%3)/3-1-2*D_icons_shrink+2*D_icons_grow" height="height-2*(height-height%3)/3-1-2*D_icons_shrink+2*D_icons_grow" - color="C_icons_unfocused" /> - <rectangle - x="(width-width%3)/3+1+D_icons_shrink-D_icons_grow" y="(height-height%3)/3+1+D_icons_shrink-D_icons_grow" - width="width-2*(width-width%3)/3-3-2*D_icons_shrink+2*D_icons_grow" height="height-2*(height-height%3)/3-3-2*D_icons_shrink+2*D_icons_grow" - color="C_icons_unfocused" /> -</draw_ops> - -<draw_ops name="maximize_unfocused"> - <include name="maximize_glyph_unfocused" y="D_icons_unfocused_offset" /> -</draw_ops> - -<draw_ops name="maximize_glyph_unfocused_prelight"> - <rectangle - x="(width-width%3)/3+D_icons_shrink-D_icons_grow" y="(height-height%3)/3+D_icons_shrink-D_icons_grow" - width="width-2*(width-width%3)/3-1-2*D_icons_shrink+2*D_icons_grow" height="height-2*(height-height%3)/3-1-2*D_icons_shrink+2*D_icons_grow" - color="C_icons_unfocused_prelight" /> - <rectangle - x="(width-width%3)/3+1+D_icons_shrink-D_icons_grow" y="(height-height%3)/3+1+D_icons_shrink-D_icons_grow" - width="width-2*(width-width%3)/3-3-2*D_icons_shrink+2*D_icons_grow" height="height-2*(height-height%3)/3-3-2*D_icons_shrink+2*D_icons_grow" - color="C_icons_unfocused_prelight" /> -</draw_ops> - -<draw_ops name="maximize_unfocused_prelight"> - <include name="maximize_glyph_unfocused_prelight" y="D_icons_unfocused_offset" /> -</draw_ops> - -<draw_ops name="maximize_glyph_unfocused_pressed"> - <rectangle - x="(width-width%3)/3+D_icons_shrink-D_icons_grow" y="(height-height%3)/3+D_icons_shrink-D_icons_grow" - width="width-2*(width-width%3)/3-1-2*D_icons_shrink+2*D_icons_grow" height="height-2*(height-height%3)/3-1-2*D_icons_shrink+2*D_icons_grow" - color="C_icons_unfocused_pressed" /> - <rectangle - x="(width-width%3)/3+1+D_icons_shrink-D_icons_grow" y="(height-height%3)/3+1+D_icons_shrink-D_icons_grow" - width="width-2*(width-width%3)/3-3-2*D_icons_shrink+2*D_icons_grow" height="height-2*(height-height%3)/3-3-2*D_icons_shrink+2*D_icons_grow" - color="C_icons_unfocused_pressed" /> -</draw_ops> - -<draw_ops name="maximize_unfocused_pressed"> - <include name="maximize_glyph_unfocused_pressed" y="D_icons_unfocused_offset" /> -</draw_ops> - -<draw_ops name="minimize_glyph_focused"> - <rectangle - x="(width-width%3)/3+1+D_icons_shrink-D_icons_grow" y="height-(height-height%3)/3-2-D_icons_shrink+D_icons_grow" - width="width-2*(width-width%3)/3-2-2*D_icons_shrink+2*D_icons_grow" height="2" filled="true" - color="C_icons_focused" /> -</draw_ops> - -<draw_ops name="minimize_shadow_focused"> - <rectangle - x="(width-width%3)/3+1+D_icons_shrink-D_icons_grow" y="height-(height-height%3)/3-2-D_icons_shrink+D_icons_grow" - width="width-2*(width-width%3)/3-2-2*D_icons_shrink+2*D_icons_grow" height="2" filled="true" - color="C_icons_shadow" /> -</draw_ops> - -<draw_ops name="minimize_focused"> - <include name="minimize_shadow_focused" y="1" /> - <include name="minimize_glyph_focused" /> -</draw_ops> - -<draw_ops name="minimize_focused_pressed"> - <include name="minimize_focused" /> -</draw_ops> - -<draw_ops name="minimize_focused_prelight"> - <include name="minimize_focused" /> -</draw_ops> - -<draw_ops name="minimize_glyph_unfocused"> - <rectangle - x="(width-width%3)/3+1+D_icons_shrink-D_icons_grow" y="height-(height-height%3)/3-2-D_icons_shrink+D_icons_grow" - width="width-2*(width-width%3)/3-2-2*D_icons_shrink+2*D_icons_grow" height="2" filled="true" - color="C_icons_unfocused" /> -</draw_ops> - -<draw_ops name="minimize_unfocused"> - <include name="minimize_glyph_unfocused" y="D_icons_unfocused_offset" /> -</draw_ops> - -<draw_ops name="minimize_glyph_unfocused_prelight"> - <rectangle - x="(width-width%3)/3+1+D_icons_shrink-D_icons_grow" y="height-(height-height%3)/3-2-D_icons_shrink+D_icons_grow" - width="width-2*(width-width%3)/3-2-2*D_icons_shrink+2*D_icons_grow" height="2" filled="true" - color="C_icons_unfocused_prelight" /> -</draw_ops> - -<draw_ops name="minimize_unfocused_prelight"> - <include name="minimize_glyph_unfocused_prelight" y="D_icons_unfocused_offset" /> -</draw_ops> - -<draw_ops name="minimize_glyph_unfocused_pressed"> - <rectangle - x="(width-width%3)/3+1+D_icons_shrink-D_icons_grow" y="height-(height-height%3)/3-2-D_icons_shrink+D_icons_grow" - width="width-2*(width-width%3)/3-2-2*D_icons_shrink+2*D_icons_grow" height="2" filled="true" - color="C_icons_unfocused_pressed" /> -</draw_ops> - -<draw_ops name="minimize_unfocused_pressed"> - <include name="minimize_glyph_unfocused_pressed" y="D_icons_unfocused_offset" /> -</draw_ops> - -<draw_ops name="menu_glyph_focused"> - <rectangle - x="(width-width%3)/3+1+D_icons_shrink-D_icons_grow" y="(height-height%3)/3+D_icons_shrink-D_icons_grow" - width="width-2*(width-width%3)/3-3-2*D_icons_shrink+2*D_icons_grow" height="height-2*(height-height%3)/3-1-2*D_icons_shrink+2*D_icons_grow" - color="C_icons_focused" /> - <rectangle - x="(width-width%3)/3+2+D_icons_shrink-D_icons_grow" y="(height-height%3)/3+1+D_icons_shrink-D_icons_grow" - width="width-2*(width-width%3)/3-5-2*D_icons_shrink+2*D_icons_grow" height="height-2*(height-height%3)/3-3-2*D_icons_shrink+2*D_icons_grow" - color="C_icons_focused" /> - <rectangle - x="(width-width%3)/3+4+D_icons_shrink-D_icons_grow" y="height/2-1-D_icons_shrink+D_icons_grow" - width="width-2*(width-width%3)/3-8-2*D_icons_shrink+2*D_icons_grow" height="2" filled="true" - color="C_icons_focused" /> -</draw_ops> - -<draw_ops name="menu_shadow_focused"> - <rectangle - x="(width-width%3)/3+1+D_icons_shrink-D_icons_grow" y="(height-height%3)/3+D_icons_shrink-D_icons_grow" - width="width-2*(width-width%3)/3-3-2*D_icons_shrink+2*D_icons_grow" height="height-2*(height-height%3)/3-1-2*D_icons_shrink+2*D_icons_grow" - color="C_icons_shadow" /> - <rectangle - x="(width-width%3)/3+2+D_icons_shrink-D_icons_grow" y="(height-height%3)/3+1+D_icons_shrink-D_icons_grow" - width="width-2*(width-width%3)/3-5-2*D_icons_shrink+2*D_icons_grow" height="height-2*(height-height%3)/3-3-2*D_icons_shrink+2*D_icons_grow" - color="C_icons_shadow" /> - <rectangle - x="(width-width%3)/3+4+D_icons_shrink-D_icons_grow" y="height/2-1-D_icons_shrink+D_icons_grow" - width="width-2*(width-width%3)/3-8-2*D_icons_shrink+2*D_icons_grow" height="2" filled="true" - color="C_icons_shadow" /> -</draw_ops> - -<draw_ops name="menu_focused"> - <include name="menu_shadow_focused" y="1" /> - <include name="menu_glyph_focused" /> -</draw_ops> - -<draw_ops name="menu_focused_pressed"> - <include name="menu_glyph_focused" /> -</draw_ops> - -<draw_ops name="menu_glyph_unfocused"> - <rectangle - x="(width-width%3)/3+1+D_icons_shrink-D_icons_grow" y="(height-height%3)/3+D_icons_shrink-D_icons_grow" - width="width-2*(width-width%3)/3-3-2*D_icons_shrink+2*D_icons_grow" height="height-2*(height-height%3)/3-1-2*D_icons_shrink+2*D_icons_grow" - color="C_icons_unfocused" /> - <rectangle - x="(width-width%3)/3+2+D_icons_shrink-D_icons_grow" y="(height-height%3)/3+1+D_icons_shrink-D_icons_grow" - width="width-2*(width-width%3)/3-5-2*D_icons_shrink+2*D_icons_grow" height="height-2*(height-height%3)/3-3-2*D_icons_shrink+2*D_icons_grow" - color="C_icons_unfocused" /> - <rectangle - x="(width-width%3)/3+4+D_icons_shrink-D_icons_grow" y="height/2-1-D_icons_shrink+D_icons_grow" - width="width-2*(width-width%3)/3-8-2*D_icons_shrink+2*D_icons_grow" height="2" filled="true" - color="C_icons_unfocused" /> -</draw_ops> - -<draw_ops name="menu_unfocused"> - <include name="menu_glyph_unfocused" y="D_icons_unfocused_offset" /> -</draw_ops> - -<draw_ops name="menu_glyph_unfocused_prelight"> - <rectangle - x="(width-width%3)/3+1+D_icons_shrink-D_icons_grow" y="(height-height%3)/3+D_icons_shrink-D_icons_grow" - width="width-2*(width-width%3)/3-3-2*D_icons_shrink+2*D_icons_grow" height="height-2*(height-height%3)/3-1-2*D_icons_shrink+2*D_icons_grow" - color="C_icons_unfocused_prelight" /> - <rectangle - x="(width-width%3)/3+2+D_icons_shrink-D_icons_grow" y="(height-height%3)/3+1+D_icons_shrink-D_icons_grow" - width="width-2*(width-width%3)/3-5-2*D_icons_shrink+2*D_icons_grow" height="height-2*(height-height%3)/3-3-2*D_icons_shrink+2*D_icons_grow" - color="C_icons_unfocused_prelight" /> - <rectangle - x="(width-width%3)/3+4+D_icons_shrink-D_icons_grow" y="height/2-1-D_icons_shrink+D_icons_grow" - width="width-2*(width-width%3)/3-8-2*D_icons_shrink+2*D_icons_grow" height="2" filled="true" - color="C_icons_unfocused_prelight" /> -</draw_ops> - -<draw_ops name="menu_unfocused_prelight"> - <include name="menu_glyph_unfocused_prelight" y="D_icons_unfocused_offset" /> -</draw_ops> - -<draw_ops name="menu_glyph_unfocused_pressed"> - <rectangle - x="(width-width%3)/3+1+D_icons_shrink-D_icons_grow" y="(height-height%3)/3+D_icons_shrink-D_icons_grow" - width="width-2*(width-width%3)/3-3-2*D_icons_shrink+2*D_icons_grow" height="height-2*(height-height%3)/3-1-2*D_icons_shrink+2*D_icons_grow" - color="C_icons_unfocused_pressed" /> - <rectangle - x="(width-width%3)/3+2+D_icons_shrink-D_icons_grow" y="(height-height%3)/3+1+D_icons_shrink-D_icons_grow" - width="width-2*(width-width%3)/3-5-2*D_icons_shrink+2*D_icons_grow" height="height-2*(height-height%3)/3-3-2*D_icons_shrink+2*D_icons_grow" - color="C_icons_unfocused_pressed" /> - <rectangle - x="(width-width%3)/3+4+D_icons_shrink-D_icons_grow" y="height/2-1-D_icons_shrink+D_icons_grow" - width="width-2*(width-width%3)/3-8-2*D_icons_shrink+2*D_icons_grow" height="2" filled="true" - color="C_icons_unfocused_pressed" /> -</draw_ops> - -<draw_ops name="menu_unfocused_pressed"> - <include name="menu_glyph_unfocused_pressed" y="D_icons_unfocused_offset" /> -</draw_ops> - -<!-- icon size used in GTK --> -<constant name="D_appmenu_icon_size" value="16" /> - -<draw_ops name="appmenu_icon_focused"> - <icon - x="(width-D_appmenu_icon_size)/2" y="(height-D_appmenu_icon_size)/2" - width="D_appmenu_icon_size" height="D_appmenu_icon_size" /> -</draw_ops> - -<draw_ops name="appmenu_focused"> - <include name="appmenu_icon_focused" /> -</draw_ops> - -<draw_ops name="appmenu_focused_pressed"> - <include name="appmenu_icon_focused" /> -</draw_ops> - -<draw_ops name="appmenu_icon_unfocused"> - <icon - x="(width-D_appmenu_icon_size)/2" y="(height-D_appmenu_icon_size)/2" - width="D_appmenu_icon_size" height="D_appmenu_icon_size" - alpha="0.4"/> -</draw_ops> - -<draw_ops name="appmenu_unfocused"> - <include name="appmenu_icon_unfocused" /> -</draw_ops> - -<draw_ops name="appmenu_icon_unfocused_prelight"> - <icon - x="(width-D_appmenu_icon_size)/2" y="(height-D_appmenu_icon_size)/2" - width="D_appmenu_icon_size" height="D_appmenu_icon_size" - alpha="0.6"/> -</draw_ops> - -<draw_ops name="appmenu_unfocused_prelight"> - <include name="appmenu_icon_unfocused_prelight" y="D_icons_unfocused_offset" /> -</draw_ops> - -<draw_ops name="appmenu_unfocused_pressed"> - <include name="appmenu_icon_unfocused_prelight" y="D_icons_unfocused_offset" /> -</draw_ops> - -<draw_ops name="shade_glyph_focused"> - <rectangle - x="(width-width%3)/3+D_icons_shrink-D_icons_grow" y="(height-height%3)/3+D_icons_shrink-D_icons_grow" - width="width-2*(width-width%3)/3-2*D_icons_shrink+2*D_icons_grow" height="2" filled="true" - color="C_icons_focused" /> - <rectangle - x="(width-width%3)/3+D_icons_shrink-D_icons_grow" y="height-(height-height%3)/3-2-D_icons_shrink+D_icons_grow" - width="width-2*(width-width%3)/3-2*D_icons_shrink+2*D_icons_grow" height="2" filled="true" - color="C_icons_focused" /> - <rectangle - x="(width-width%3)/3+D_icons_shrink-D_icons_grow" y="(height-height%3)/3+3+D_icons_shrink-D_icons_grow" - width="2" height="height-2*(height-height%3)/3-6-D_icons_shrink+D_icons_grow" filled="true" - color="C_icons_focused" /> - <rectangle - x="width-(width-width%3)/3-2-D_icons_shrink+D_icons_grow" y="(height-height%3)/3+3+D_icons_shrink-D_icons_grow" - width="2" height="height-2*(height-height%3)/3-6-D_icons_shrink+D_icons_grow" filled="true" - color="C_icons_focused" /> -</draw_ops> - -<draw_ops name="shade_shadow_focused"> - <rectangle - x="(width-width%3)/3+D_icons_shrink-D_icons_grow" y="(height-height%3)/3+D_icons_shrink-D_icons_grow" - width="width-2*(width-width%3)/3-2*D_icons_shrink+2*D_icons_grow" height="2" filled="true" - color="C_icons_shadow" /> - <rectangle - x="(width-width%3)/3+D_icons_shrink-D_icons_grow" y="height-(height-height%3)/3-2-D_icons_shrink+D_icons_grow" - width="width-2*(width-width%3)/3-2*D_icons_shrink+2*D_icons_grow" height="2" filled="true" - color="C_icons_shadow" /> -</draw_ops> - -<draw_ops name="shade_focused"> - <include name="shade_shadow_focused" y="1" /> - <include name="shade_glyph_focused" /> -</draw_ops> - -<draw_ops name="shade_focused_pressed"> - <include name="shade_glyph_focused" /> -</draw_ops> - -<draw_ops name="shade_glyph_unfocused"> - <rectangle - x="(width-width%3)/3+D_icons_shrink-D_icons_grow" y="(height-height%3)/3+D_icons_shrink-D_icons_grow" - width="width-2*(width-width%3)/3-2*D_icons_shrink+2*D_icons_grow" height="2" filled="true" - color="C_icons_unfocused" /> - <rectangle - x="(width-width%3)/3+D_icons_shrink-D_icons_grow" y="height-(height-height%3)/3-2-D_icons_shrink+D_icons_grow" - width="width-2*(width-width%3)/3-2*D_icons_shrink+2*D_icons_grow" height="2" filled="true" - color="C_icons_unfocused" /> - <rectangle - x="(width-width%3)/3+D_icons_shrink-D_icons_grow" y="(height-height%3)/3+3+D_icons_shrink-D_icons_grow" - width="2" height="height-2*(height-height%3)/3-6-D_icons_shrink+D_icons_grow" filled="true" - color="C_icons_unfocused" /> - <rectangle - x="width-(width-width%3)/3-2-D_icons_shrink+D_icons_grow" y="(height-height%3)/3+3+D_icons_shrink-D_icons_grow" - width="2" height="height-2*(height-height%3)/3-6-D_icons_shrink+D_icons_grow" filled="true" - color="C_icons_unfocused" /> -</draw_ops> - -<draw_ops name="shade_unfocused"> - <include name="shade_glyph_unfocused" y="D_icons_unfocused_offset" /> -</draw_ops> - -<draw_ops name="shade_glyph_unfocused_prelight"> - <rectangle - x="(width-width%3)/3+D_icons_shrink-D_icons_grow" y="(height-height%3)/3+D_icons_shrink-D_icons_grow" - width="width-2*(width-width%3)/3-2*D_icons_shrink+2*D_icons_grow" height="2" filled="true" - color="C_icons_unfocused_prelight" /> - <rectangle - x="(width-width%3)/3+D_icons_shrink-D_icons_grow" y="height-(height-height%3)/3-2-D_icons_shrink+D_icons_grow" - width="width-2*(width-width%3)/3-2*D_icons_shrink+2*D_icons_grow" height="2" filled="true" - color="C_icons_unfocused_prelight" /> - <rectangle - x="(width-width%3)/3+D_icons_shrink-D_icons_grow" y="(height-height%3)/3+3+D_icons_shrink-D_icons_grow" - width="2" height="height-2*(height-height%3)/3-6-D_icons_shrink+D_icons_grow" filled="true" - color="C_icons_unfocused_prelight" /> - <rectangle - x="width-(width-width%3)/3-2-D_icons_shrink+D_icons_grow" y="(height-height%3)/3+3+D_icons_shrink-D_icons_grow" - width="2" height="height-2*(height-height%3)/3-6-D_icons_shrink+D_icons_grow" filled="true" - color="C_icons_unfocused_prelight" /> -</draw_ops> - -<draw_ops name="shade_unfocused_prelight"> - <include name="shade_glyph_unfocused_prelight" y="D_icons_unfocused_offset" /> -</draw_ops> - -<draw_ops name="shade_glyph_unfocused_pressed"> - <rectangle - x="(width-width%3)/3+D_icons_shrink-D_icons_grow" y="(height-height%3)/3+D_icons_shrink-D_icons_grow" - width="width-2*(width-width%3)/3-2*D_icons_shrink+2*D_icons_grow" height="2" filled="true" - color="C_icons_unfocused_pressed" /> - <rectangle - x="(width-width%3)/3+D_icons_shrink-D_icons_grow" y="height-(height-height%3)/3-2-D_icons_shrink+D_icons_grow" - width="width-2*(width-width%3)/3-2*D_icons_shrink+2*D_icons_grow" height="2" filled="true" - color="C_icons_unfocused_pressed" /> - <rectangle - x="(width-width%3)/3+D_icons_shrink-D_icons_grow" y="(height-height%3)/3+3+D_icons_shrink-D_icons_grow" - width="2" height="height-2*(height-height%3)/3-6-D_icons_shrink+D_icons_grow" filled="true" - color="C_icons_unfocused_pressed" /> - <rectangle - x="width-(width-width%3)/3-2-D_icons_shrink+D_icons_grow" y="(height-height%3)/3+3+D_icons_shrink-D_icons_grow" - width="2" height="height-2*(height-height%3)/3-6-D_icons_shrink+D_icons_grow" filled="true" - color="C_icons_unfocused_pressed" /> -</draw_ops> - -<draw_ops name="shade_unfocused_pressed"> - <include name="shade_glyph_unfocused_pressed" y="D_icons_unfocused_offset" /> -</draw_ops> - - - <!-- button backgrounds --> - -<constant name="C_button_border" value="blend/#000000/gtk:bg[NORMAL]/0.8" /> -<constant name="C_button_hilight" value="gtk:custom(wm_highlight,blend/gtk:base[NORMAL]/gtk:bg[NORMAL]/0.6)" /> - -<draw_ops name="button_border"> - <line x1="6" y1="4" x2="width-7" y2="4" color="C_button_border" /> - <arc color="C_button_border" x="width-9" y="4" width="4" height="4" start_angle="0" extent_angle="90"/> - <line x1="width-5" y1="6" x2="width-5" y2="height-7" color="C_button_border" /> - <arc color="C_button_border" x="width-9" y="height-9" width="4" height="4" start_angle="90" extent_angle="90"/> - <line x1="width-6" y1="height-5" x2="6" y2="height-5" color="C_button_border" /> - <arc color="C_button_border" x="4" y="height-9" width="4" height="4" start_angle="180" extent_angle="90"/> - <line x1="4" y1="6" x2="4" y2="height-7" color="C_button_border" /> - <arc color="C_button_border" x="4" y="4" width="4" height="4" start_angle="270" extent_angle="90"/> - <line x1="width-7" y1="height-4" x2="7" y2="height-4" color="C_title_focused_hilight" /> -</draw_ops> - - -<draw_ops name="button_fill"> <!-- button background gradient --> - -</draw_ops> - -<draw_ops name="button_fill_prelight"> <!-- button background gradient for prelight status --> - <gradient type="vertical" x="5" y="5" width="width-10" height="height-10"> - <color value="gtk:custom(wm_button_hover_color_a,gtk:fg[NORMAL])" /> - <color value="gtk:custom(wm_button_hover_color_b,gtk:fg[NORMAL])" /> - </gradient> - <include name="button_border" /> -</draw_ops> - -<draw_ops name="button_fill_pressed"> <!-- button background gradient for pressed status --> - <gradient type="vertical" x="5" y="5" width="width-10" height="height-10"> - <color value="gtk:custom(wm_button_active_color_b,gtk:fg[NORMAL])" /> - <color value="gtk:custom(wm_button_active_color_c,gtk:fg[NORMAL])" /> - </gradient> - <line x1="5" y1="5" x2="width-6" y2="5" color="blend/#000000/gtk:custom(wm_button_active_color_a,gtk:fg[NORMAL])/0.9" /> - <line x1="4" y1="6" x2="width-5" y2="6" color="gtk:custom(wm_button_active_color_a,gtk:fg[NORMAL])" /> - <include name="button_border" /> -</draw_ops> - -<draw_ops name="button"> -</draw_ops> - -<draw_ops name="button_prelight"> - <include name="button_fill_prelight" /> -</draw_ops> - -<draw_ops name="button_pressed"> - <include name="button_fill_pressed" /> -</draw_ops> - -<!-- frame styles --> - -<frame_style name="normal_focused" geometry="normal"> - <piece position="entire_background" draw_ops="entire_background_focused" /> - <piece position="titlebar" draw_ops="rounded_titlebar_focused" /> - <piece position="title" draw_ops="title_focused" /> - <piece position="overlay" draw_ops="rounded_border_focused" /> - <button function="close" state="normal" draw_ops="close_focused" /> - <button function="close" state="pressed" draw_ops="close_focused_pressed" /> - <button function="close" state="prelight" draw_ops="close_focused_prelight" /> - <button function="maximize" state="normal" draw_ops="maximize_focused" /> - <button function="maximize" state="pressed" draw_ops="maximize_focused_pressed" /> - <button function="maximize" state="prelight" draw_ops="maximize_focused_prelight" /> - <button function="minimize" state="normal" draw_ops="minimize_focused" /> - <button function="minimize" state="pressed" draw_ops="minimize_focused_pressed" /> - <button function="minimize" state="prelight" draw_ops="minimize_focused_prelight" /> - <button function="menu" state="normal" draw_ops="menu_focused" /> - <button function="menu" state="pressed" draw_ops="menu_focused_pressed" /> - <button version=">= 3.5" function="appmenu" state="normal" draw_ops="appmenu_focused" /> - <button version=">= 3.5" function="appmenu" state="pressed" draw_ops="appmenu_focused_pressed" /> - <button function="shade" state="normal" draw_ops="shade_focused" /> - <button function="shade" state="pressed" draw_ops="shade_focused_pressed" /> - <button function="unshade" state="normal" draw_ops="shade_focused" /> - <button function="unshade" state="pressed" draw_ops="shade_focused_pressed" /> - - <button function="left_middle_background" state="normal" draw_ops="button"/> - <button function="left_middle_background" state="pressed" draw_ops="button_pressed"/> - <button function="left_middle_background" state="prelight" draw_ops="button_prelight"/> - <button function="right_middle_background" state="normal" draw_ops="button"/> - <button function="right_middle_background" state="pressed" draw_ops="button_pressed"/> - <button function="right_middle_background" state="prelight" draw_ops="button_prelight"/> - - <button function="above" state="normal"><draw_ops></draw_ops></button> - <button function="above" state="pressed"><draw_ops></draw_ops></button> - <button function="unabove" state="normal"><draw_ops></draw_ops></button> - <button function="unabove" state="pressed"><draw_ops></draw_ops></button> - <button function="stick" state="normal"><draw_ops></draw_ops></button> - <button function="stick" state="pressed"><draw_ops></draw_ops></button> - <button function="unstick" state="normal"><draw_ops></draw_ops></button> - <button function="unstick" state="pressed"><draw_ops></draw_ops></button> -</frame_style> - -<frame_style name="normal_unfocused" geometry="normal_unfocused"> - <piece position="entire_background" draw_ops="entire_background_unfocused" /> - <piece position="titlebar" draw_ops="rounded_titlebar_unfocused" /> - <piece position="title" draw_ops="title_unfocused" /> - <piece position="overlay" draw_ops="rounded_border_unfocused" /> - <button function="close" state="normal" draw_ops="close_unfocused"/> - <button function="close" state="prelight" draw_ops="close_unfocused_prelight"/> - <button function="close" state="pressed" draw_ops="close_unfocused_pressed"/> - <button function="maximize" state="normal" draw_ops="maximize_unfocused"/> - <button function="maximize" state="prelight" draw_ops="maximize_unfocused_prelight"/> - <button function="maximize" state="pressed" draw_ops="maximize_unfocused_pressed"/> - <button function="minimize" state="normal" draw_ops="minimize_unfocused"/> - <button function="minimize" state="prelight" draw_ops="minimize_unfocused_prelight"/> - <button function="minimize" state="pressed" draw_ops="minimize_unfocused_pressed"/> - <button function="menu" state="normal" draw_ops="menu_unfocused" /> - <button function="menu" state="prelight" draw_ops="menu_unfocused_prelight" /> - <button function="menu" state="pressed" draw_ops="menu_unfocused_pressed" /> - <button version=">= 3.5" function="appmenu" state="normal" draw_ops="appmenu_unfocused" /> - <button version=">= 3.5" function="appmenu" state="prelight" draw_ops="appmenu_unfocused_prelight" /> - <button version=">= 3.5" function="appmenu" state="pressed" draw_ops="appmenu_unfocused_pressed" /> - <button function="shade" state="normal" draw_ops="shade_unfocused" /> - <button function="shade" state="prelight" draw_ops="shade_unfocused_prelight" /> - <button function="shade" state="pressed" draw_ops="shade_unfocused_pressed" /> - <button function="unshade" state="normal" draw_ops="shade_unfocused" /> - <button function="unshade" state="prelight" draw_ops="shade_unfocused_prelight" /> - <button function="unshade" state="pressed" draw_ops="shade_unfocused_pressed" /> - <button function="above" state="normal"><draw_ops></draw_ops></button> - <button function="above" state="pressed"><draw_ops></draw_ops></button> - <button function="unabove" state="normal"><draw_ops></draw_ops></button> - <button function="unabove" state="pressed"><draw_ops></draw_ops></button> - <button function="stick" state="normal"><draw_ops></draw_ops></button> - <button function="stick" state="pressed"><draw_ops></draw_ops></button> - <button function="unstick" state="normal"><draw_ops></draw_ops></button> - <button function="unstick" state="pressed"><draw_ops></draw_ops></button> -</frame_style> - -<frame_style name="normal_max_focused" geometry="max"> - <piece position="entire_background" draw_ops="entire_background_focused" /> - <piece position="titlebar" draw_ops="titlebar_focused" /> - <piece position="title" draw_ops="title_focused" /> - <button function="close" state="normal" draw_ops="close_focused" /> - <button function="close" state="pressed" draw_ops="close_focused_pressed" /> - <button function="close" state="prelight" draw_ops="close_focused_prelight" /> - <button function="maximize" state="normal" draw_ops="maximize_focused" /> - <button function="maximize" state="pressed" draw_ops="maximize_focused_pressed" /> - <button function="maximize" state="prelight" draw_ops="maximize_focused_prelight" /> - <button function="minimize" state="normal" draw_ops="minimize_focused" /> - <button function="minimize" state="pressed" draw_ops="minimize_focused_pressed" /> - <button function="minimize" state="prelight" draw_ops="minimize_focused_prelight" /> - <button function="menu" state="normal" draw_ops="menu_focused" /> - <button function="menu" state="pressed" draw_ops="menu_focused_pressed" /> - <button version=">= 3.5" function="appmenu" state="normal" draw_ops="appmenu_focused" /> - <button version=">= 3.5" function="appmenu" state="pressed" draw_ops="appmenu_focused_pressed" /> - <button function="shade" state="normal" draw_ops="shade_focused" /> - <button function="shade" state="pressed" draw_ops="shade_focused_pressed" /> - <button function="unshade" state="normal" draw_ops="shade_focused" /> - <button function="unshade" state="pressed" draw_ops="shade_focused_pressed" /> - - <button function="left_middle_background" state="normal" draw_ops="button"/> - <button function="left_middle_background" state="pressed" draw_ops="button_pressed"/> - <button function="left_middle_background" state="prelight" draw_ops="button_prelight"/> - <button function="right_middle_background" state="normal" draw_ops="button"/> - <button function="right_middle_background" state="pressed" draw_ops="button_pressed"/> - <button function="right_middle_background" state="prelight" draw_ops="button_prelight"/> - - <button function="above" state="normal"><draw_ops></draw_ops></button> - <button function="above" state="pressed"><draw_ops></draw_ops></button> - <button function="unabove" state="normal"><draw_ops></draw_ops></button> - <button function="unabove" state="pressed"><draw_ops></draw_ops></button> - <button function="stick" state="normal"><draw_ops></draw_ops></button> - <button function="stick" state="pressed"><draw_ops></draw_ops></button> - <button function="unstick" state="normal"><draw_ops></draw_ops></button> - <button function="unstick" state="pressed"><draw_ops></draw_ops></button> -</frame_style> - -<frame_style name="normal_max_unfocused" geometry="max"> - <piece position="entire_background" draw_ops="entire_background_unfocused" /> - <piece position="titlebar" draw_ops="titlebar_unfocused" /> - <piece position="title" draw_ops="title_unfocused" /> - <button function="close" state="normal" draw_ops="close_unfocused"/> - <button function="close" state="prelight" draw_ops="close_unfocused_prelight"/> - <button function="close" state="pressed" draw_ops="close_unfocused_pressed"/> - <button function="maximize" state="normal" draw_ops="maximize_unfocused"/> - <button function="maximize" state="prelight" draw_ops="maximize_unfocused_prelight"/> - <button function="maximize" state="pressed" draw_ops="maximize_unfocused_pressed"/> - <button function="minimize" state="normal" draw_ops="minimize_unfocused"/> - <button function="minimize" state="prelight" draw_ops="minimize_unfocused_prelight"/> - <button function="minimize" state="pressed" draw_ops="minimize_unfocused_pressed"/> - <button function="menu" state="normal" draw_ops="menu_unfocused" /> - <button function="menu" state="prelight" draw_ops="menu_unfocused_prelight" /> - <button function="menu" state="pressed" draw_ops="menu_unfocused_pressed" /> - <button version=">= 3.5" function="appmenu" state="normal" draw_ops="appmenu_unfocused" /> - <button version=">= 3.5" function="appmenu" state="prelight" draw_ops="appmenu_unfocused_prelight" /> - <button version=">= 3.5" function="appmenu" state="pressed" draw_ops="appmenu_unfocused_pressed" /> - <button function="shade" state="normal" draw_ops="shade_unfocused" /> - <button function="shade" state="prelight" draw_ops="shade_unfocused_prelight" /> - <button function="shade" state="pressed" draw_ops="shade_unfocused_pressed" /> - <button function="unshade" state="normal" draw_ops="shade_unfocused" /> - <button function="unshade" state="prelight" draw_ops="shade_unfocused_prelight" /> - <button function="unshade" state="pressed" draw_ops="shade_unfocused_pressed" /> - <button function="above" state="normal"><draw_ops></draw_ops></button> - <button function="above" state="pressed"><draw_ops></draw_ops></button> - <button function="unabove" state="normal"><draw_ops></draw_ops></button> - <button function="unabove" state="pressed"><draw_ops></draw_ops></button> - <button function="stick" state="normal"><draw_ops></draw_ops></button> - <button function="stick" state="pressed"><draw_ops></draw_ops></button> - <button function="unstick" state="normal"><draw_ops></draw_ops></button> - <button function="unstick" state="pressed"><draw_ops></draw_ops></button> -</frame_style> - -<frame_style name="normal_max_shaded_focused" geometry="max"> - <piece position="entire_background" draw_ops="entire_background_focused" /> - <piece position="titlebar" draw_ops="titlebar_focused" /> - <piece position="title" draw_ops="title_focused" /> - <piece position="overlay"><draw_ops><line x1="0" y1="height-1" x2="width" y2="height-1" color="C_border_focused" /></draw_ops></piece> - <button function="close" state="normal" draw_ops="close_focused" /> - <button function="close" state="pressed" draw_ops="close_focused_pressed" /> - <button function="close" state="prelight" draw_ops="close_focused_prelight" /> - <button function="maximize" state="normal" draw_ops="maximize_focused" /> - <button function="maximize" state="pressed" draw_ops="maximize_focused_pressed" /> - <button function="maximize" state="prelight" draw_ops="maximize_focused_prelight" /> - <button function="minimize" state="normal" draw_ops="minimize_focused" /> - <button function="minimize" state="pressed" draw_ops="minimize_focused_pressed" /> - <button function="minimize" state="prelight" draw_ops="minimize_focused_prelight" /> - <button function="menu" state="normal" draw_ops="menu_focused" /> - <button function="menu" state="pressed" draw_ops="menu_focused_pressed" /> - <button version=">= 3.5" function="appmenu" state="normal" draw_ops="appmenu_focused" /> - <button version=">= 3.5" function="appmenu" state="pressed" draw_ops="appmenu_focused_pressed" /> - <button function="shade" state="normal" draw_ops="shade_focused" /> - <button function="shade" state="pressed" draw_ops="shade_focused_pressed" /> - <button function="unshade" state="normal" draw_ops="shade_focused" /> - <button function="unshade" state="pressed" draw_ops="shade_focused_pressed" /> - - <button function="left_middle_background" state="normal" draw_ops="button"/> - <button function="left_middle_background" state="pressed" draw_ops="button_pressed"/> - <button function="left_middle_background" state="prelight" draw_ops="button_prelight"/> - <button function="right_middle_background" state="normal" draw_ops="button"/> - <button function="right_middle_background" state="pressed" draw_ops="button_pressed"/> - <button function="right_middle_background" state="prelight" draw_ops="button_prelight"/> - - <button function="above" state="normal"><draw_ops></draw_ops></button> - <button function="above" state="pressed"><draw_ops></draw_ops></button> - <button function="unabove" state="normal"><draw_ops></draw_ops></button> - <button function="unabove" state="pressed"><draw_ops></draw_ops></button> - <button function="stick" state="normal"><draw_ops></draw_ops></button> - <button function="stick" state="pressed"><draw_ops></draw_ops></button> - <button function="unstick" state="normal"><draw_ops></draw_ops></button> - <button function="unstick" state="pressed"><draw_ops></draw_ops></button> -</frame_style> - -<frame_style name="normal_max_shaded_unfocused" geometry="max"> - <piece position="entire_background" draw_ops="entire_background_unfocused" /> - <piece position="titlebar" draw_ops="titlebar_unfocused" /> - <piece position="title" draw_ops="title_unfocused" /> - <piece position="overlay"><draw_ops><line x1="0" y1="height-1" x2="width" y2="height-1" color="C_border_unfocused" /></draw_ops></piece> - <button function="close" state="normal" draw_ops="close_unfocused"/> - <button function="close" state="prelight" draw_ops="close_unfocused_prelight"/> - <button function="close" state="pressed" draw_ops="close_unfocused_pressed"/> - <button function="maximize" state="normal" draw_ops="maximize_unfocused"/> - <button function="maximize" state="prelight" draw_ops="maximize_unfocused_prelight"/> - <button function="maximize" state="pressed" draw_ops="maximize_unfocused_pressed"/> - <button function="minimize" state="normal" draw_ops="minimize_unfocused"/> - <button function="minimize" state="prelight" draw_ops="minimize_unfocused_prelight"/> - <button function="minimize" state="pressed" draw_ops="minimize_unfocused_pressed"/> - <button function="menu" state="normal" draw_ops="menu_unfocused" /> - <button function="menu" state="prelight" draw_ops="menu_unfocused_prelight" /> - <button function="menu" state="pressed" draw_ops="menu_unfocused_pressed" /> - <button version=">= 3.5" function="appmenu" state="normal" draw_ops="appmenu_unfocused" /> - <button version=">= 3.5" function="appmenu" state="prelight" draw_ops="appmenu_unfocused_prelight" /> - <button version=">= 3.5" function="appmenu" state="pressed" draw_ops="appmenu_unfocused_pressed" /> - <button function="shade" state="normal" draw_ops="shade_unfocused" /> - <button function="shade" state="prelight" draw_ops="shade_unfocused_prelight" /> - <button function="shade" state="pressed" draw_ops="shade_unfocused_pressed" /> - <button function="unshade" state="normal" draw_ops="shade_unfocused" /> - <button function="unshade" state="prelight" draw_ops="shade_unfocused_prelight" /> - <button function="unshade" state="pressed" draw_ops="shade_unfocused_pressed" /> - <button function="above" state="normal"><draw_ops></draw_ops></button> - <button function="above" state="pressed"><draw_ops></draw_ops></button> - <button function="unabove" state="normal"><draw_ops></draw_ops></button> - <button function="unabove" state="pressed"><draw_ops></draw_ops></button> - <button function="stick" state="normal"><draw_ops></draw_ops></button> - <button function="stick" state="pressed"><draw_ops></draw_ops></button> - <button function="unstick" state="normal"><draw_ops></draw_ops></button> - <button function="unstick" state="pressed"><draw_ops></draw_ops></button> -</frame_style> - -<frame_style name="dialog_focused" geometry="normal"> - <piece position="entire_background" draw_ops="entire_background_focused" /> - <piece position="titlebar" draw_ops="rounded_titlebar_focused" /> - <piece position="title" draw_ops="title_focused" /> - <piece position="overlay" draw_ops="rounded_border_focused" /> - <button function="close" state="normal" draw_ops="close_focused" /> - <button function="close" state="pressed" draw_ops="close_focused_pressed" /> - <button function="close" state="prelight" draw_ops="close_focused_prelight" /> - <button function="maximize" state="normal" draw_ops="maximize_focused" /> - <button function="maximize" state="pressed" draw_ops="maximize_focused_pressed" /> - <button function="maximize" state="prelight" draw_ops="maximize_focused_prelight" /> - <button function="minimize" state="normal" draw_ops="minimize_focused" /> - <button function="minimize" state="pressed" draw_ops="minimize_focused_pressed" /> - <button function="minimize" state="prelight" draw_ops="minimize_focused_prelight" /> - <button function="menu" state="normal" draw_ops="menu_focused" /> - <button function="menu" state="pressed" draw_ops="menu_focused_pressed" /> - <button version=">= 3.5" function="appmenu" state="normal" draw_ops="appmenu_focused" /> - <button version=">= 3.5" function="appmenu" state="pressed" draw_ops="appmenu_focused_pressed" /> - <button function="shade" state="normal" draw_ops="shade_focused" /> - <button function="shade" state="pressed" draw_ops="shade_focused_pressed" /> - <button function="unshade" state="normal" draw_ops="shade_focused" /> - <button function="unshade" state="pressed" draw_ops="shade_focused_pressed" /> - - <button function="left_middle_background" state="normal" draw_ops="button"/> - <button function="left_middle_background" state="pressed" draw_ops="button_pressed"/> - <button function="left_middle_background" state="prelight" draw_ops="button_prelight"/> - <button function="right_middle_background" state="normal" draw_ops="button"/> - <button function="right_middle_background" state="pressed" draw_ops="button_pressed"/> - <button function="right_middle_background" state="prelight" draw_ops="button_prelight"/> - - <button function="above" state="normal"><draw_ops></draw_ops></button> - <button function="above" state="pressed"><draw_ops></draw_ops></button> - <button function="unabove" state="normal"><draw_ops></draw_ops></button> - <button function="unabove" state="pressed"><draw_ops></draw_ops></button> - <button function="stick" state="normal"><draw_ops></draw_ops></button> - <button function="stick" state="pressed"><draw_ops></draw_ops></button> - <button function="unstick" state="normal"><draw_ops></draw_ops></button> - <button function="unstick" state="pressed"><draw_ops></draw_ops></button> -</frame_style> - -<frame_style name="dialog_unfocused" geometry="normal_unfocused"> - <piece position="entire_background" draw_ops="entire_background_unfocused" /> - <piece position="titlebar" draw_ops="titlebar_unfocused" /> - <piece position="title" draw_ops="title_unfocused" /> - <piece position="overlay" draw_ops="rounded_border_unfocused" /> - <button function="close" state="normal" draw_ops="close_unfocused"/> - <button function="close" state="prelight" draw_ops="close_unfocused_prelight"/> - <button function="close" state="pressed" draw_ops="close_unfocused_pressed"/> - <button function="maximize" state="normal" draw_ops="maximize_unfocused"/> - <button function="maximize" state="prelight" draw_ops="maximize_unfocused_prelight"/> - <button function="maximize" state="pressed" draw_ops="maximize_unfocused_pressed"/> - <button function="minimize" state="normal" draw_ops="minimize_unfocused"/> - <button function="minimize" state="prelight" draw_ops="minimize_unfocused_prelight"/> - <button function="minimize" state="pressed" draw_ops="minimize_unfocused_pressed"/> - <button function="menu" state="normal" draw_ops="menu_unfocused" /> - <button function="menu" state="prelight" draw_ops="menu_unfocused_prelight" /> - <button function="menu" state="pressed" draw_ops="menu_unfocused_pressed" /> - <button version=">= 3.5" function="appmenu" state="normal" draw_ops="appmenu_unfocused" /> - <button version=">= 3.5" function="appmenu" state="prelight" draw_ops="appmenu_unfocused_prelight" /> - <button version=">= 3.5" function="appmenu" state="pressed" draw_ops="appmenu_unfocused_pressed" /> - <button function="shade" state="normal"><draw_ops></draw_ops></button> - <button function="shade" state="pressed"><draw_ops></draw_ops></button> - <button function="unshade" state="normal"><draw_ops></draw_ops></button> - <button function="unshade" state="pressed"><draw_ops></draw_ops></button> - <button function="above" state="normal"><draw_ops></draw_ops></button> - <button function="above" state="pressed"><draw_ops></draw_ops></button> - <button function="unabove" state="normal"><draw_ops></draw_ops></button> - <button function="unabove" state="pressed"><draw_ops></draw_ops></button> - <button function="stick" state="normal"><draw_ops></draw_ops></button> - <button function="stick" state="pressed"><draw_ops></draw_ops></button> - <button function="unstick" state="normal"><draw_ops></draw_ops></button> - <button function="unstick" state="pressed"><draw_ops></draw_ops></button> -</frame_style> - -<frame_style name="modal_dialog_focused" geometry="modal"> - <piece position="entire_background" draw_ops="entire_background_focused" /> - <piece position="titlebar" draw_ops="titlebar_focused" /> - <piece position="title" draw_ops="title_focused" /> - <piece position="overlay" draw_ops="border_focused" /> - <button function="close" state="normal" draw_ops="close_focused" /> - <button function="close" state="pressed" draw_ops="close_focused_pressed" /> - <button function="close" state="prelight" draw_ops="close_focused_prelight" /> - <button function="maximize" state="normal" draw_ops="maximize_focused" /> - <button function="maximize" state="pressed" draw_ops="maximize_focused_pressed" /> - <button function="maximize" state="prelight" draw_ops="maximize_focused_prelight" /> - <button function="minimize" state="normal" draw_ops="minimize_focused" /> - <button function="minimize" state="pressed" draw_ops="minimize_focused_pressed" /> - <button function="minimize" state="prelight" draw_ops="minimize_focused_prelight" /> - <button function="menu" state="normal" draw_ops="menu_focused" /> - <button function="menu" state="pressed" draw_ops="menu_focused_pressed" /> - <button version=">= 3.5" function="appmenu" state="normal" draw_ops="appmenu_focused" /> - <button version=">= 3.5" function="appmenu" state="pressed" draw_ops="appmenu_focused_pressed" /> - <button function="shade" state="normal" draw_ops="shade_focused" /> - <button function="shade" state="pressed" draw_ops="shade_focused_pressed" /> - <button function="unshade" state="normal" draw_ops="shade_focused" /> - <button function="unshade" state="pressed" draw_ops="shade_focused_pressed" /> - - <button function="left_middle_background" state="normal" draw_ops="button"/> - <button function="left_middle_background" state="pressed" draw_ops="button_pressed"/> - <button function="left_middle_background" state="prelight" draw_ops="button_prelight"/> - <button function="right_middle_background" state="normal" draw_ops="button"/> - <button function="right_middle_background" state="pressed" draw_ops="button_pressed"/> - <button function="right_middle_background" state="prelight" draw_ops="button_prelight"/> - - <button function="above" state="normal"><draw_ops></draw_ops></button> - <button function="above" state="pressed"><draw_ops></draw_ops></button> - <button function="unabove" state="normal"><draw_ops></draw_ops></button> - <button function="unabove" state="pressed"><draw_ops></draw_ops></button> - <button function="stick" state="normal"><draw_ops></draw_ops></button> - <button function="stick" state="pressed"><draw_ops></draw_ops></button> - <button function="unstick" state="normal"><draw_ops></draw_ops></button><button function="unstick" state="pressed"><draw_ops></draw_ops></button> -</frame_style> - -<frame_style name="modal_dialog_unfocused" geometry="modal"> - <piece position="entire_background" draw_ops="entire_background_unfocused" /> - <piece position="titlebar" draw_ops="titlebar_unfocused" /> - <piece position="title" draw_ops="title_unfocused" /> - <piece position="overlay" draw_ops="border_unfocused" /> - <button function="close" state="normal" draw_ops="close_unfocused"/> - <button function="close" state="prelight" draw_ops="close_unfocused_prelight"/> - <button function="close" state="pressed" draw_ops="close_unfocused_pressed"/> - <button function="maximize" state="normal" draw_ops="maximize_unfocused"/> - <button function="maximize" state="prelight" draw_ops="maximize_unfocused_prelight"/> - <button function="maximize" state="pressed" draw_ops="maximize_unfocused_pressed"/> - <button function="minimize" state="normal" draw_ops="minimize_unfocused"/> - <button function="minimize" state="prelight" draw_ops="minimize_unfocused_prelight"/> - <button function="minimize" state="pressed" draw_ops="minimize_unfocused_pressed"/> - <button function="menu" state="normal" draw_ops="menu_unfocused" /> - <button function="menu" state="prelight" draw_ops="menu_unfocused_prelight" /> - <button function="menu" state="pressed" draw_ops="menu_unfocused_pressed" /> - <button version=">= 3.5" function="appmenu" state="normal" draw_ops="appmenu_unfocused" /> - <button version=">= 3.5" function="appmenu" state="prelight" draw_ops="appmenu_unfocused_prelight" /> - <button version=">= 3.5" function="appmenu" state="pressed" draw_ops="appmenu_unfocused_pressed" /> - <button function="shade" state="normal" draw_ops="shade_unfocused" /> - <button function="shade" state="prelight" draw_ops="shade_unfocused_prelight" /> - <button function="shade" state="pressed" draw_ops="shade_unfocused_pressed" /> - <button function="unshade" state="normal" draw_ops="shade_unfocused" /> - <button function="unshade" state="prelight" draw_ops="shade_unfocused_prelight" /> - <button function="unshade" state="pressed" draw_ops="shade_unfocused_pressed" /> - <button function="above" state="normal"><draw_ops></draw_ops></button> - <button function="above" state="pressed"><draw_ops></draw_ops></button> - <button function="unabove" state="normal"><draw_ops></draw_ops></button> - <button function="unabove" state="pressed"><draw_ops></draw_ops></button> - <button function="stick" state="normal"><draw_ops></draw_ops></button> - <button function="stick" state="pressed"><draw_ops></draw_ops></button> - <button function="unstick" state="normal"><draw_ops></draw_ops></button> - <button function="unstick" state="pressed"><draw_ops></draw_ops></button> -</frame_style> - -<frame_style name="utility_focused" geometry="small"> - <piece position="entire_background" draw_ops="entire_background_focused" /> - <piece position="titlebar" draw_ops="titlebar_focused" /> - <piece position="title" draw_ops="title_focused" /> - <piece position="overlay" draw_ops="border_focused" /> - <button function="close" state="normal" draw_ops="close_focused" /> - <button function="close" state="pressed" draw_ops="close_focused_pressed" /> - <button function="close" state="prelight" draw_ops="close_focused_prelight" /> - <button function="maximize" state="normal" draw_ops="maximize_focused" /> - <button function="maximize" state="pressed" draw_ops="maximize_focused_pressed" /> - <button function="maximize" state="prelight" draw_ops="maximize_focused_prelight" /> - <button function="minimize" state="normal" draw_ops="minimize_focused" /> - <button function="minimize" state="pressed" draw_ops="minimize_focused_pressed" /> - <button function="minimize" state="prelight" draw_ops="minimize_focused_prelight" /> - <button function="menu" state="normal" draw_ops="menu_focused" /> - <button function="menu" state="pressed" draw_ops="menu_focused_pressed" /> - <button version=">= 3.5" function="appmenu" state="normal" draw_ops="appmenu_focused" /> - <button version=">= 3.5" function="appmenu" state="pressed" draw_ops="appmenu_focused_pressed" /> - <button function="shade" state="normal" draw_ops="shade_focused" /> - <button function="shade" state="pressed" draw_ops="shade_focused_pressed" /> - <button function="unshade" state="normal" draw_ops="shade_focused" /> - <button function="unshade" state="pressed" draw_ops="shade_focused_pressed" /> - - <button function="left_middle_background" state="normal" draw_ops="button"/> - <button function="left_middle_background" state="pressed" draw_ops="button_pressed"/> - <button function="left_middle_background" state="prelight" draw_ops="button_prelight"/> - <button function="right_middle_background" state="normal" draw_ops="button"/> - <button function="right_middle_background" state="pressed" draw_ops="button_pressed"/> - <button function="right_middle_background" state="prelight" draw_ops="button_prelight"/> - - <button function="above" state="normal"><draw_ops></draw_ops></button> - <button function="above" state="pressed"><draw_ops></draw_ops></button> - <button function="unabove" state="normal"><draw_ops></draw_ops></button> - <button function="unabove" state="pressed"><draw_ops></draw_ops></button> - <button function="stick" state="normal"><draw_ops></draw_ops></button> - <button function="stick" state="pressed"><draw_ops></draw_ops></button> - <button function="unstick" state="normal"><draw_ops></draw_ops></button> - <button function="unstick" state="pressed"><draw_ops></draw_ops></button> -</frame_style> - -<frame_style name="utility_unfocused" geometry="small_unfocused"> - <piece position="entire_background" draw_ops="entire_background_unfocused" /> - <piece position="titlebar" draw_ops="titlebar_unfocused" /> - <piece position="title" draw_ops="title_unfocused" /> - <piece position="overlay" draw_ops="border_unfocused" /> - <button function="close" state="normal" draw_ops="close_unfocused"/> - <button function="close" state="prelight" draw_ops="close_unfocused_prelight"/> - <button function="close" state="pressed" draw_ops="close_unfocused_pressed"/> - <button function="maximize" state="normal" draw_ops="maximize_unfocused"/> - <button function="maximize" state="prelight" draw_ops="maximize_unfocused_prelight"/> - <button function="maximize" state="pressed" draw_ops="maximize_unfocused_pressed"/> - <button function="minimize" state="normal" draw_ops="minimize_unfocused"/> - <button function="minimize" state="prelight" draw_ops="minimize_unfocused_prelight"/> - <button function="minimize" state="pressed" draw_ops="minimize_unfocused_pressed"/> - <button function="menu" state="normal" draw_ops="menu_unfocused" /> - <button function="menu" state="prelight" draw_ops="menu_unfocused_prelight" /> - <button function="menu" state="pressed" draw_ops="menu_unfocused_pressed" /> - <button version=">= 3.5" function="appmenu" state="normal" draw_ops="appmenu_unfocused" /> - <button version=">= 3.5" function="appmenu" state="prelight" draw_ops="appmenu_unfocused_prelight" /> - <button version=">= 3.5" function="appmenu" state="pressed" draw_ops="appmenu_unfocused_pressed" /> - <button function="shade" state="normal" draw_ops="shade_unfocused" /> - <button function="shade" state="prelight" draw_ops="shade_unfocused_prelight" /> - <button function="shade" state="pressed" draw_ops="shade_unfocused_pressed" /> - <button function="unshade" state="normal" draw_ops="shade_unfocused" /> - <button function="unshade" state="prelight" draw_ops="shade_unfocused_prelight" /> - <button function="unshade" state="pressed" draw_ops="shade_unfocused_pressed" /> - <button function="above" state="normal"><draw_ops></draw_ops></button> - <button function="above" state="pressed"><draw_ops></draw_ops></button> - <button function="unabove" state="normal"><draw_ops></draw_ops></button> - <button function="unabove" state="pressed"><draw_ops></draw_ops></button> - <button function="stick" state="normal"><draw_ops></draw_ops></button> - <button function="stick" state="pressed"><draw_ops></draw_ops></button> - <button function="unstick" state="normal"><draw_ops></draw_ops></button> - <button function="unstick" state="pressed"><draw_ops></draw_ops></button> -</frame_style> - -<frame_style name="border_focused" geometry="border"> - <piece position="entire_background" draw_ops="entire_background_focused" /> - <piece position="overlay" draw_ops="border_focused" /> - <button function="close" state="normal"><draw_ops></draw_ops></button> - <button function="close" state="pressed"><draw_ops></draw_ops></button> - <button function="maximize" state="normal"><draw_ops></draw_ops></button> - <button function="maximize" state="pressed"><draw_ops></draw_ops></button> - <button function="minimize" state="normal"><draw_ops></draw_ops></button> - <button function="minimize" state="pressed"><draw_ops></draw_ops></button> - <button function="menu" state="normal"><draw_ops></draw_ops></button> - <button function="menu" state="pressed"><draw_ops></draw_ops></button> - <button version=">= 3.5" function="appmenu" state="normal"><draw_ops></draw_ops></button> - <button version=">= 3.5" function="appmenu" state="pressed"><draw_ops></draw_ops></button> - <button function="shade" state="normal"><draw_ops></draw_ops></button> - <button function="shade" state="pressed"><draw_ops></draw_ops></button> - <button function="unshade" state="normal"><draw_ops></draw_ops></button> - <button function="unshade" state="pressed"><draw_ops></draw_ops></button> - <button function="above" state="normal"><draw_ops></draw_ops></button> - <button function="above" state="pressed"><draw_ops></draw_ops></button> - <button function="unabove" state="normal"><draw_ops></draw_ops></button> - <button function="unabove" state="pressed"><draw_ops></draw_ops></button> - <button function="stick" state="normal"><draw_ops></draw_ops></button> - <button function="stick" state="pressed"><draw_ops></draw_ops></button> - <button function="unstick" state="normal"><draw_ops></draw_ops></button> - <button function="unstick" state="pressed"><draw_ops></draw_ops></button> -</frame_style> - -<frame_style name="border_unfocused" geometry="border"> - <piece position="entire_background" draw_ops="entire_background_unfocused" /> - <piece position="overlay" draw_ops="border_unfocused" /> - <button function="close" state="normal"><draw_ops></draw_ops></button> - <button function="close" state="pressed"><draw_ops></draw_ops></button> - <button function="maximize" state="normal"><draw_ops></draw_ops></button> - <button function="maximize" state="pressed"><draw_ops></draw_ops></button> - <button function="minimize" state="normal"><draw_ops></draw_ops></button> - <button function="minimize" state="pressed"><draw_ops></draw_ops></button> - <button function="menu" state="normal"><draw_ops></draw_ops></button> - <button function="menu" state="pressed"><draw_ops></draw_ops></button> - <button version=">= 3.5" function="appmenu" state="normal"><draw_ops></draw_ops></button> - <button version=">= 3.5" function="appmenu" state="pressed"><draw_ops></draw_ops></button> - <button function="shade" state="normal"><draw_ops></draw_ops></button> - <button function="shade" state="pressed"><draw_ops></draw_ops></button> - <button function="unshade" state="normal"><draw_ops></draw_ops></button> - <button function="unshade" state="pressed"><draw_ops></draw_ops></button> - <button function="above" state="normal"><draw_ops></draw_ops></button> - <button function="above" state="pressed"><draw_ops></draw_ops></button> - <button function="unabove" state="normal"><draw_ops></draw_ops></button> - <button function="unabove" state="pressed"><draw_ops></draw_ops></button> - <button function="stick" state="normal"><draw_ops></draw_ops></button> - <button function="stick" state="pressed"><draw_ops></draw_ops></button> - <button function="unstick" state="normal"><draw_ops></draw_ops></button> - <button function="unstick" state="pressed"><draw_ops></draw_ops></button> -</frame_style> - -<frame_style name="borderless" geometry="borderless"> - <button function="close" state="normal"><draw_ops></draw_ops></button> - <button function="close" state="pressed"><draw_ops></draw_ops></button> - <button function="maximize" state="normal"><draw_ops></draw_ops></button> - <button function="maximize" state="pressed"><draw_ops></draw_ops></button> - <button function="minimize" state="normal"><draw_ops></draw_ops></button> - <button function="minimize" state="pressed"><draw_ops></draw_ops></button> - <button function="menu" state="normal"><draw_ops></draw_ops></button> - <button function="menu" state="pressed"><draw_ops></draw_ops></button> - <button version=">= 3.5" function="appmenu" state="normal"><draw_ops></draw_ops></button> - <button version=">= 3.5" function="appmenu" state="pressed"><draw_ops></draw_ops></button> - <button function="shade" state="normal"><draw_ops></draw_ops></button> - <button function="shade" state="pressed"><draw_ops></draw_ops></button> - <button function="unshade" state="normal"><draw_ops></draw_ops></button> - <button function="unshade" state="pressed"><draw_ops></draw_ops></button> - <button function="above" state="normal"><draw_ops></draw_ops></button> - <button function="above" state="pressed"><draw_ops></draw_ops></button> - <button function="unabove" state="normal"><draw_ops></draw_ops></button> - <button function="unabove" state="pressed"><draw_ops></draw_ops></button> - <button function="stick" state="normal"><draw_ops></draw_ops></button> - <button function="stick" state="pressed"><draw_ops></draw_ops></button> - <button function="unstick" state="normal"><draw_ops></draw_ops></button> - <button function="unstick" state="pressed"><draw_ops></draw_ops></button> -</frame_style> - -<frame_style name="attached_focused" geometry="attached"> - <piece position="entire_background" draw_ops="entire_background_focused" /> - <piece position="titlebar" draw_ops="titlebar_fill_focused" /> - <piece position="title" draw_ops="title_focused" /> - <piece position="overlay" draw_ops="border_focused" /> - <button function="close" state="normal"><draw_ops></draw_ops></button> - <button function="close" state="pressed"><draw_ops></draw_ops></button> - <button function="maximize" state="normal"><draw_ops></draw_ops></button> - <button function="maximize" state="pressed"><draw_ops></draw_ops></button> - <button function="minimize" state="normal"><draw_ops></draw_ops></button> - <button function="minimize" state="pressed"><draw_ops></draw_ops></button> - <button function="menu" state="normal"><draw_ops></draw_ops></button> - <button function="menu" state="pressed"><draw_ops></draw_ops></button> - <button version=">= 3.5" function="appmenu" state="normal"><draw_ops></draw_ops></button> - <button version=">= 3.5" function="appmenu" state="pressed"><draw_ops></draw_ops></button> - <button function="shade" state="normal"><draw_ops></draw_ops></button> - <button function="shade" state="pressed"><draw_ops></draw_ops></button> - <button function="unshade" state="normal"><draw_ops></draw_ops></button> - <button function="unshade" state="pressed"><draw_ops></draw_ops></button> - <button function="above" state="normal"><draw_ops></draw_ops></button> - <button function="above" state="pressed"><draw_ops></draw_ops></button> - <button function="unabove" state="normal"><draw_ops></draw_ops></button> - <button function="unabove" state="pressed"><draw_ops></draw_ops></button> - <button function="stick" state="normal"><draw_ops></draw_ops></button> - <button function="stick" state="pressed"><draw_ops></draw_ops></button> - <button function="unstick" state="normal"><draw_ops></draw_ops></button> - <button function="unstick" state="pressed"><draw_ops></draw_ops></button> -</frame_style> - -<frame_style name="attached_unfocused" geometry="attached"> - <piece position="entire_background" draw_ops="entire_background_unfocused" /> - <piece position="titlebar" draw_ops="titlebar_fill_unfocused" /> - <piece position="title" draw_ops="title_unfocused" /> - <piece position="overlay" draw_ops="border_unfocused" /> - <button function="close" state="normal"><draw_ops></draw_ops></button> - <button function="close" state="pressed"><draw_ops></draw_ops></button> - <button function="maximize" state="normal"><draw_ops></draw_ops></button> - <button function="maximize" state="pressed"><draw_ops></draw_ops></button> - <button function="minimize" state="normal"><draw_ops></draw_ops></button> - <button function="minimize" state="pressed"><draw_ops></draw_ops></button> - <button function="menu" state="normal"><draw_ops></draw_ops></button> - <button function="menu" state="pressed"><draw_ops></draw_ops></button> - <button version=">= 3.5" function="appmenu" state="normal"><draw_ops></draw_ops></button> - <button version=">= 3.5" function="appmenu" state="pressed"><draw_ops></draw_ops></button> - <button function="shade" state="normal"><draw_ops></draw_ops></button> - <button function="shade" state="pressed"><draw_ops></draw_ops></button> - <button function="unshade" state="normal"><draw_ops></draw_ops></button> - <button function="unshade" state="pressed"><draw_ops></draw_ops></button> - <button function="above" state="normal"><draw_ops></draw_ops></button> - <button function="above" state="pressed"><draw_ops></draw_ops></button> - <button function="unabove" state="normal"><draw_ops></draw_ops></button> - <button function="unabove" state="pressed"><draw_ops></draw_ops></button> - <button function="stick" state="normal"><draw_ops></draw_ops></button> - <button function="stick" state="pressed"><draw_ops></draw_ops></button> - <button function="unstick" state="normal"><draw_ops></draw_ops></button> - <button function="unstick" state="pressed"><draw_ops></draw_ops></button> -</frame_style> - -<frame_style name="tiled_left_focused" geometry="tiled_left"> - <piece position="entire_background" draw_ops="entire_background_focused" /> - <piece position="titlebar" draw_ops="titlebar_fill_focused" /> - <piece position="title" draw_ops="title_focused" /> - <!-- <piece position="overlay" draw_ops="border_right_focused" /> --> - <button function="close" state="normal" draw_ops="close_focused" /> - <button function="close" state="pressed" draw_ops="close_focused_pressed" /> - <button function="close" state="prelight" draw_ops="close_focused_prelight" /> - <button function="maximize" state="normal" draw_ops="maximize_focused" /> - <button function="maximize" state="pressed" draw_ops="maximize_focused_pressed" /> - <button function="maximize" state="prelight" draw_ops="maximize_focused_prelight" /> - <button function="minimize" state="normal" draw_ops="minimize_focused" /> - <button function="minimize" state="pressed" draw_ops="minimize_focused_pressed" /> - <button function="minimize" state="prelight" draw_ops="minimize_focused_prelight" /> - <button function="menu" state="normal" draw_ops="menu_focused" /> - <button function="menu" state="pressed" draw_ops="menu_focused_pressed" /> - <button version=">= 3.5" function="appmenu" state="normal" draw_ops="appmenu_focused" /> - <button version=">= 3.5" function="appmenu" state="pressed" draw_ops="appmenu_focused_pressed" /> - <button function="shade" state="normal" draw_ops="shade_focused" /> - <button function="shade" state="pressed" draw_ops="shade_focused_pressed" /> - <button function="unshade" state="normal" draw_ops="shade_focused" /> - <button function="unshade" state="pressed" draw_ops="shade_focused_pressed" /> - - <button function="left_middle_background" state="normal" draw_ops="button"/> - <button function="left_middle_background" state="pressed" draw_ops="button_pressed"/> - <button function="left_middle_background" state="prelight" draw_ops="button_prelight"/> - <button function="right_middle_background" state="normal" draw_ops="button"/> - <button function="right_middle_background" state="pressed" draw_ops="button_pressed"/> - <button function="right_middle_background" state="prelight" draw_ops="button_prelight"/> - - <button function="above" state="normal"><draw_ops></draw_ops></button> - <button function="above" state="pressed"><draw_ops></draw_ops></button> - <button function="unabove" state="normal"><draw_ops></draw_ops></button> - <button function="unabove" state="pressed"><draw_ops></draw_ops></button> - <button function="stick" state="normal"><draw_ops></draw_ops></button> - <button function="stick" state="pressed"><draw_ops></draw_ops></button> - <button function="unstick" state="normal"><draw_ops></draw_ops></button> - <button function="unstick" state="pressed"><draw_ops></draw_ops></button> -</frame_style> - -<frame_style name="tiled_left_unfocused" geometry="tiled_left"> - <piece position="entire_background" draw_ops="entire_background_unfocused" /> - <piece position="titlebar" draw_ops="titlebar_fill_unfocused" /> - <piece position="title" draw_ops="title_unfocused" /> - <!-- <piece position="overlay" draw_ops="border_right_unfocused" /> --> - <button function="close" state="normal" draw_ops="close_unfocused"/> - <button function="close" state="prelight" draw_ops="close_unfocused_prelight"/> - <button function="close" state="pressed" draw_ops="close_unfocused_pressed"/> - <button function="maximize" state="normal" draw_ops="maximize_unfocused"/> - <button function="maximize" state="prelight" draw_ops="maximize_unfocused_prelight"/> - <button function="maximize" state="pressed" draw_ops="maximize_unfocused_pressed"/> - <button function="minimize" state="normal" draw_ops="minimize_unfocused"/> - <button function="minimize" state="prelight" draw_ops="minimize_unfocused_prelight"/> - <button function="minimize" state="pressed" draw_ops="minimize_unfocused_pressed"/> - <button function="menu" state="normal" draw_ops="menu_unfocused" /> - <button function="menu" state="prelight" draw_ops="menu_unfocused_prelight" /> - <button function="menu" state="pressed" draw_ops="menu_unfocused_pressed" /> - <button version=">= 3.5" function="appmenu" state="normal" draw_ops="appmenu_unfocused" /> - <button version=">= 3.5" function="appmenu" state="prelight" draw_ops="appmenu_unfocused_prelight" /> - <button version=">= 3.5" function="appmenu" state="pressed" draw_ops="appmenu_unfocused_pressed" /> - <button function="shade" state="normal" draw_ops="shade_unfocused" /> - <button function="shade" state="prelight" draw_ops="shade_unfocused_prelight" /> - <button function="shade" state="pressed" draw_ops="shade_unfocused_pressed" /> - <button function="unshade" state="normal" draw_ops="shade_unfocused" /> - <button function="unshade" state="prelight" draw_ops="shade_unfocused_prelight" /> - <button function="unshade" state="pressed" draw_ops="shade_unfocused_pressed" /> - <button function="above" state="normal"><draw_ops></draw_ops></button> - <button function="above" state="pressed"><draw_ops></draw_ops></button> - <button function="unabove" state="normal"><draw_ops></draw_ops></button> - <button function="unabove" state="pressed"><draw_ops></draw_ops></button> - <button function="stick" state="normal"><draw_ops></draw_ops></button> - <button function="stick" state="pressed"><draw_ops></draw_ops></button> - <button function="unstick" state="normal"><draw_ops></draw_ops></button> - <button function="unstick" state="pressed"><draw_ops></draw_ops></button> -</frame_style> - -<frame_style name="tiled_right_focused" geometry="tiled_right"> - <piece position="entire_background" draw_ops="entire_background_focused" /> - <piece position="titlebar" draw_ops="titlebar_fill_focused" /> - <piece position="title" draw_ops="title_focused" /> - <piece position="overlay" draw_ops="border_left_focused" /> - <button function="close" state="normal" draw_ops="close_focused" /> - <button function="close" state="pressed" draw_ops="close_focused_pressed" /> - <button function="close" state="prelight" draw_ops="close_focused_prelight" /> - <button function="maximize" state="normal" draw_ops="maximize_focused" /> - <button function="maximize" state="pressed" draw_ops="maximize_focused_pressed" /> - <button function="maximize" state="prelight" draw_ops="maximize_focused_prelight" /> - <button function="minimize" state="normal" draw_ops="minimize_focused" /> - <button function="minimize" state="pressed" draw_ops="minimize_focused_pressed" /> - <button function="minimize" state="prelight" draw_ops="minimize_focused_prelight" /> - <button function="menu" state="normal" draw_ops="menu_focused" /> - <button function="menu" state="pressed" draw_ops="menu_focused_pressed" /> - <button version=">= 3.5" function="appmenu" state="normal" draw_ops="appmenu_focused" /> - <button version=">= 3.5" function="appmenu" state="pressed" draw_ops="appmenu_focused_pressed" /> - <button function="shade" state="normal" draw_ops="shade_focused" /> - <button function="shade" state="pressed" draw_ops="shade_focused_pressed" /> - <button function="unshade" state="normal" draw_ops="shade_focused" /> - <button function="unshade" state="pressed" draw_ops="shade_focused_pressed" /> - - <button function="left_middle_background" state="normal" draw_ops="button"/> - <button function="left_middle_background" state="pressed" draw_ops="button_pressed"/> - <button function="left_middle_background" state="prelight" draw_ops="button_prelight"/> - <button function="right_middle_background" state="normal" draw_ops="button"/> - <button function="right_middle_background" state="pressed" draw_ops="button_pressed"/> - <button function="right_middle_background" state="prelight" draw_ops="button_prelight"/> - - <button function="above" state="normal"><draw_ops></draw_ops></button> - <button function="above" state="pressed"><draw_ops></draw_ops></button> - <button function="unabove" state="normal"><draw_ops></draw_ops></button> - <button function="unabove" state="pressed"><draw_ops></draw_ops></button> - <button function="stick" state="normal"><draw_ops></draw_ops></button> - <button function="stick" state="pressed"><draw_ops></draw_ops></button> - <button function="unstick" state="normal"><draw_ops></draw_ops></button> - <button function="unstick" state="pressed"><draw_ops></draw_ops></button> -</frame_style> - -<frame_style name="tiled_right_unfocused" geometry="tiled_right"> - <piece position="entire_background" draw_ops="entire_background_unfocused" /> - <piece position="titlebar" draw_ops="titlebar_fill_unfocused" /> - <piece position="title" draw_ops="title_unfocused" /> - <piece position="overlay" draw_ops="border_left_unfocused" /> - <button function="close" state="normal" draw_ops="close_unfocused"/> - <button function="close" state="prelight" draw_ops="close_unfocused_prelight"/> - <button function="close" state="pressed" draw_ops="close_unfocused_pressed"/> - <button function="maximize" state="normal" draw_ops="maximize_unfocused"/> - <button function="maximize" state="prelight" draw_ops="maximize_unfocused_prelight"/> - <button function="maximize" state="pressed" draw_ops="maximize_unfocused_pressed"/> - <button function="minimize" state="normal" draw_ops="minimize_unfocused"/> - <button function="minimize" state="prelight" draw_ops="minimize_unfocused_prelight"/> - <button function="minimize" state="pressed" draw_ops="minimize_unfocused_pressed"/> - <button function="menu" state="normal" draw_ops="menu_unfocused" /> - <button function="menu" state="prelight" draw_ops="menu_unfocused_prelight" /> - <button function="menu" state="pressed" draw_ops="menu_unfocused_pressed" /> - <button version=">= 3.5" function="appmenu" state="normal" draw_ops="appmenu_unfocused" /> - <button version=">= 3.5" function="appmenu" state="prelight" draw_ops="appmenu_unfocused_prelight" /> - <button version=">= 3.5" function="appmenu" state="pressed" draw_ops="appmenu_unfocused_pressed" /> - <button function="shade" state="normal" draw_ops="shade_unfocused" /> - <button function="shade" state="prelight" draw_ops="shade_unfocused_prelight" /> - <button function="shade" state="pressed" draw_ops="shade_unfocused_pressed" /> - <button function="unshade" state="normal" draw_ops="shade_unfocused" /> - <button function="unshade" state="prelight" draw_ops="shade_unfocused_prelight" /> - <button function="unshade" state="pressed" draw_ops="shade_unfocused_pressed" /> - <button function="above" state="normal"><draw_ops></draw_ops></button> - <button function="above" state="pressed"><draw_ops></draw_ops></button> - <button function="unabove" state="normal"><draw_ops></draw_ops></button> - <button function="unabove" state="pressed"><draw_ops></draw_ops></button> - <button function="stick" state="normal"><draw_ops></draw_ops></button> - <button function="stick" state="pressed"><draw_ops></draw_ops></button> - <button function="unstick" state="normal"><draw_ops></draw_ops></button> - <button function="unstick" state="pressed"><draw_ops></draw_ops></button> -</frame_style> - -<!-- placeholder for unimplementated styles--> -<frame_style name="blank" geometry="normal"> - <button function="close" state="normal"><draw_ops></draw_ops></button> - <button function="close" state="pressed"><draw_ops></draw_ops></button> - <button function="maximize" state="normal"><draw_ops></draw_ops></button> - <button function="maximize" state="pressed"><draw_ops></draw_ops></button> - <button function="minimize" state="normal"><draw_ops></draw_ops></button> - <button function="minimize" state="pressed"><draw_ops></draw_ops></button> - <button function="menu" state="normal"><draw_ops></draw_ops></button> - <button function="menu" state="pressed"><draw_ops></draw_ops></button> - <button version=">= 3.5" function="appmenu" state="normal"><draw_ops></draw_ops></button> - <button version=">= 3.5" function="appmenu" state="pressed"><draw_ops></draw_ops></button> - <button function="shade" state="normal"><draw_ops></draw_ops></button> - <button function="shade" state="pressed"><draw_ops></draw_ops></button> - <button function="unshade" state="normal"><draw_ops></draw_ops></button> - <button function="unshade" state="pressed"><draw_ops></draw_ops></button> - <button function="above" state="normal"><draw_ops></draw_ops></button> - <button function="above" state="pressed"><draw_ops></draw_ops></button> - <button function="unabove" state="normal"><draw_ops></draw_ops></button> - <button function="unabove" state="pressed"><draw_ops></draw_ops></button> - <button function="stick" state="normal"><draw_ops></draw_ops></button> - <button function="stick" state="pressed"><draw_ops></draw_ops></button> - <button function="unstick" state="normal"><draw_ops></draw_ops></button> - <button function="unstick" state="pressed"><draw_ops></draw_ops></button> -</frame_style> - -<!-- frame style sets --> - -<frame_style_set name="normal_style_set"> - <frame focus="yes" state="normal" resize="both" style="normal_focused"/> - <frame focus="no" state="normal" resize="both" style="normal_unfocused"/> - <frame focus="yes" state="maximized" style="normal_max_focused"/> - <frame focus="no" state="maximized" style="normal_max_unfocused"/> - <frame focus="yes" state="shaded" style="normal_focused"/> - <frame focus="no" state="shaded" style="normal_unfocused"/> - <frame focus="yes" state="maximized_and_shaded" style="normal_max_shaded_focused"/> - <frame focus="no" state="maximized_and_shaded" style="normal_max_shaded_unfocused"/> - <frame version=">= 3.3" focus="yes" state="tiled_left" style="tiled_left_focused"/> - <frame version=">= 3.3" focus="no" state="tiled_left" style="tiled_left_unfocused"/> - <frame version=">= 3.3" focus="yes" state="tiled_right" style="tiled_right_focused"/> - <frame version=">= 3.3" focus="no" state="tiled_right" style="tiled_right_unfocused"/> - <frame version=">= 3.3" focus="yes" state="tiled_left_and_shaded" style="tiled_left_focused"/> - <frame version=">= 3.3" focus="no" state="tiled_left_and_shaded" style="tiled_left_unfocused"/> - <frame version=">= 3.3" focus="yes" state="tiled_right_and_shaded" style="tiled_right_focused"/> - <frame version=">= 3.3" focus="no" state="tiled_right_and_shaded" style="tiled_right_unfocused"/> -</frame_style_set> - -<frame_style_set name="dialog_style_set"> - <frame focus="yes" state="normal" resize="both" style="dialog_focused"/> - <frame focus="no" state="normal" resize="both" style="dialog_unfocused"/> - <frame focus="yes" state="maximized" style="blank"/> - <frame focus="no" state="maximized" style="blank"/> - <frame focus="yes" state="shaded" style="dialog_focused"/> - <frame focus="no" state="shaded" style="dialog_unfocused"/> - <frame focus="yes" state="maximized_and_shaded" style="blank"/> - <frame focus="no" state="maximized_and_shaded" style="blank"/> -</frame_style_set> - -<frame_style_set name="modal_dialog_style_set"> - <frame focus="yes" state="normal" resize="both" style="modal_dialog_focused"/> - <frame focus="no" state="normal" resize="both" style="modal_dialog_unfocused"/> - <frame focus="yes" state="maximized" style="blank"/> - <frame focus="no" state="maximized" style="blank"/> - <frame focus="yes" state="shaded" style="modal_dialog_focused"/> - <frame focus="no" state="shaded" style="modal_dialog_unfocused"/> - <frame focus="yes" state="maximized_and_shaded" style="blank"/> - <frame focus="no" state="maximized_and_shaded" style="blank"/> -</frame_style_set> - -<frame_style_set name="utility_style_set"> - <frame focus="yes" state="normal" resize="both" style="utility_focused"/> - <frame focus="no" state="normal" resize="both" style="utility_unfocused"/> - <frame focus="yes" state="maximized" style="blank"/> - <frame focus="no" state="maximized" style="blank"/> - <frame focus="yes" state="shaded" style="utility_focused"/> - <frame focus="no" state="shaded" style="utility_unfocused"/> - <frame focus="yes" state="maximized_and_shaded" style="blank"/> - <frame focus="no" state="maximized_and_shaded" style="blank"/> -</frame_style_set> - -<frame_style_set name="border_style_set"> - <frame focus="yes" state="normal" resize="both" style="border_focused"/> - <frame focus="no" state="normal" resize="both" style="border_unfocused"/> - <frame focus="yes" state="maximized" style="borderless"/> - <frame focus="no" state="maximized" style="borderless"/> - <frame focus="yes" state="shaded" style="blank"/> - <frame focus="no" state="shaded" style="blank"/> - <frame focus="yes" state="maximized_and_shaded" style="blank"/> - <frame focus="no" state="maximized_and_shaded" style="blank"/> -</frame_style_set> - -<frame_style_set name="attached_style_set"> - <frame focus="yes" state="normal" resize="both" style="attached_focused"/> - <frame focus="no" state="normal" resize="both" style="attached_unfocused"/> - <frame focus="yes" state="maximized" style="blank"/> - <frame focus="no" state="maximized" style="blank"/> - <frame focus="yes" state="shaded" style="blank"/> - <frame focus="no" state="shaded" style="blank"/> - <frame focus="yes" state="maximized_and_shaded" style="blank"/> - <frame focus="no" state="maximized_and_shaded" style="blank"/> -</frame_style_set> - - -<!-- windows --> - -<window type="normal" style_set="normal_style_set"/> -<window type="dialog" style_set="dialog_style_set"/> -<window type="modal_dialog" style_set="modal_dialog_style_set"/> -<window type="menu" style_set="utility_style_set"/> -<window type="utility" style_set="utility_style_set"/> -<window type="border" style_set="border_style_set"/> -<window version=">= 3.2" type="attached" style_set="attached_style_set"/> - -</metacity_theme> diff --git a/debian/README.Debian b/debian/README.Debian index c7dea1318..169b50e3c 100644 --- a/debian/README.Debian +++ b/debian/README.Debian @@ -1,13 +1,13 @@ -Muffin Compositor +Mutter Compositor =================== -Muffin includes a compositor based on Clutter. Muffin by default adds +Mutter includes a compositor based on Clutter. Mutter by default adds very simple effects using the compositor, such as a drop-shadow. The compositor may be used by plugins to add more effects. GNOME Shell is an example of one such plugin. The compositor can be enabled on the fly by setting the gconf key -/apps/muffin/general/compositing_manager to true by using +/apps/mutter/general/compositing_manager to true by using gconf-editor or gconftool-2. Before enabling the compositor, you need to make sure your X server diff --git a/debian/changelog b/debian/changelog index d24ea8bb7..5a55eaf49 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +muffin (5.3.0) UNRELEASED; urgency=medium + + * Mutter 3.36.9-0ubuntu0.20.04.1 rebase + + -- Michael Webster <miketwebster@gmail.com> Wed, 08 Jun 2022 12:00:00 -0500 + muffin (5.2.1) una; urgency=medium [ Michael Webster ] diff --git a/debian/clean b/debian/clean new file mode 100644 index 000000000..cca322ee2 --- /dev/null +++ b/debian/clean @@ -0,0 +1,2 @@ +HOME/ +XRD/ diff --git a/debian/compat b/debian/compat deleted file mode 100644 index f599e28b8..000000000 --- a/debian/compat +++ /dev/null @@ -1 +0,0 @@ -10 diff --git a/debian/control b/debian/control index 21e1285cd..e2d460d25 100644 --- a/debian/control +++ b/debian/control @@ -3,47 +3,84 @@ Section: x11 Priority: optional Maintainer: Linux Mint <root@linuxmint.com> Build-Depends: - autoconf-archive, - automake, - debhelper (>= 10), - gnome-pkg-tools (>= 0.10), - gobject-introspection (>= 0.9.12-5~), - gtk-doc-tools, - intltool (>= 0.34.90), - libcanberra-gtk3-dev, - libcinnamon-desktop-dev (>= 3.6), - libgirepository1.0-dev (>= 0.9.12), - libglvnd-dev, - libglib2.0-dev (>= 2.37.3), - libgtk-3-dev (>= 3.9.12), - libice-dev, - libpango1.0-dev (>= 1.14.0), - libjson-glib-dev, - libsm-dev, - libstartup-notification0-dev (>= 0.7), - libx11-dev, - libxcomposite-dev (>= 1:0.3), - libxcursor-dev, - libxdamage-dev, - libxext-dev, - libxfixes-dev, - libxinerama-dev, - libxkbcommon-x11-dev, - libxrandr-dev, - libxrender-dev, - libxcb-res0-dev, - libxt-dev, - libx11-xcb-dev, - libxcb-randr0-dev, - zenity, -Standards-Version: 3.9.4 + debhelper-compat (= 12), + dh-sequence-gir, + at-spi2-core <!nocheck>, + adwaita-icon-theme <!nocheck>, + cinnamon-desktop-data (>= 5.3.0), + dbus <!nocheck>, + dmz-cursor-theme <!nocheck>, + gnome-control-center-data, + gnome-pkg-tools (>= 0.10), + cinnamon-settings-daemon <!nocheck>, + gobject-introspection (>= 1.41.3), + gtk-doc-tools (>= 1.15), + libcairo2-dev (>= 1.10.0), + libcanberra-gtk3-dev, + libdrm-dev (>= 2.4.83) [linux-any], + libegl-dev, + libegl1-mesa-dev (>= 17) [linux-any], + libfribidi-dev (>= 1.0.0), + libgbm-dev (>= 10.3) [linux-any], + libgirepository1.0-dev (>= 0.9.12), + libgl1-mesa-dev (>= 7.1~rc3-1~), + libgles2-mesa-dev (>= 7.1~rc3-1~) | libgles2-dev, + libglib2.0-dev (>= 2.61.1), + libcinnamon-desktop-dev, + libgraphene-1.0-dev (>= 1.9.3), + libgtk-3-dev (>= 3.19.8), + libgudev-1.0-dev (>= 232) [linux-any], + libice-dev, + libinput-dev (>= 1.7) [linux-any], + libjson-glib-dev (>= 0.13.2-1~), + libnvidia-egl-wayland-dev [linux-any], + libpam0g-dev, + libpango1.0-dev (>= 1.2.0), + libpipewire-0.3-dev (>= 0.3.19) [linux-any], + libsm-dev, + libstartup-notification0-dev (>= 0.7), + libsystemd-dev (>= 212) [linux-any], + libwacom-dev (>= 0.13) [linux-any], + libwayland-dev (>= 1.13.0) [linux-any], + libxau-dev, + libx11-dev, + libx11-xcb-dev, + libxcb-randr0-dev, + libxcb-res0-dev, + libxcomposite-dev (>= 1:0.4), + libxcursor-dev, + libxdamage-dev, + libxext-dev, + libxfixes-dev, + libxi-dev (>= 2:1.7.4), + libxinerama-dev, + libxkbcommon-dev (>= 0.4.3), + libxkbcommon-x11-dev, + libxkbfile-dev, + libxrandr-dev, + libxrender-dev, + libxt-dev, + meson (>= 0.50), + pkg-config (>= 0.22), + wayland-protocols (>= 1.19) [linux-any], + xauth <!nocheck>, + xkb-data, + xserver-xorg-core [linux-any], + xvfb <!nocheck>, + xwayland [linux-any], + zenity +Rules-Requires-Root: no +Standards-Version: 4.5.0 Package: gir1.2-meta-muffin-0.0 Section: introspection Architecture: any Breaks: gir1.2-muffin-3.0 Replaces: gir1.2-muffin-3.0 -Depends: ${gir:Depends}, ${misc:Depends} +Depends: libmuffin0 (= ${binary:Version}), + ${gir:Depends}, + ${misc:Depends}, + ${shlibs:Depends} Description: GObject introspection data for Muffin Muffin is a window manager performing compositing as well based on GTK+ and Clutter and used in Cinnamon desktop environment. @@ -54,7 +91,7 @@ Description: GObject introspection data for Muffin Package: libmuffin0 Section: libs Architecture: any -Replaces: libmuffin-dev +Replaces: muffin-doc Pre-Depends: ${misc:Pre-Depends} Depends: muffin-common (= ${source:Version}), ${misc:Depends}, ${shlibs:Depends} Description: window and compositing manager (shared library) @@ -82,7 +119,7 @@ Description: window and compositing manager Package: muffin-common Section: misc Architecture: all -Depends: dconf-gsettings-backend | gsettings-backend, sgml-base (>= 1.26) +Depends: ${misc:Depends} Description: window and compositing manager (data files) Muffin is a window manager performing compositing as well based on GTK+ and Clutter and used in Cinnamon desktop environment. @@ -103,12 +140,40 @@ Description: window and compositing manager (debugging symbols) . This package contains the debugging symbols. -Package: muffin-doc -Section: doc -Architecture: all -Depends: devhelp, ${misc:Depends} -Description: Muffin documentation +Package: libmuffin-dev +Section: libdevel +Architecture: any +Multi-Arch: same +Breaks: libmuffin0 (<< 5.1) +Replaces: libmuffin0 (<< 5.1) +Depends: gir1.2-meta-muffin-0.0 (= ${binary:Version}), + gsettings-desktop-schemas-dev (>= 3.33.0), + libatk1.0-dev, + libcairo2-dev, + libdrm-dev, + libegl1-mesa-dev, + libgbm-dev, + libgdk-pixbuf2.0-dev, + libgles2-mesa-dev (>= 7.1~rc3-1~) | libgles2-dev, + libglib2.0-dev, + libgraphene-1.0-dev (>= 1.9.3), + libgtk-3-dev, + libinput-dev (>= 1.7), + libjson-glib-dev, + libmuffin0 (= ${binary:Version}), + libpango1.0-dev, + libudev-dev, + libwayland-dev, + libx11-dev, + libxcomposite-dev, + libxdamage-dev, + libxext-dev, + libxfixes-dev, + libxi-dev, + libxrandr-dev, + ${misc:Depends} +Description: window and compositing manager (development files) Muffin is a window manager performing compositing as well based on GTK+ and Clutter and used in Cinnamon desktop environment. . - This package contains the code documentation for Muffin. + This package contains the development files. diff --git a/debian/copyright b/debian/copyright index b52cbe27c..a926c9069 100644 --- a/debian/copyright +++ b/debian/copyright @@ -1,97 +1,169 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Upstream-Name: muffin -Upstream-Contact: Linux Mint Project <root@linuxmint.com> -Source: https://github.com/linuxmint/muffin +Source: https://download.gnome.org/sources/mutter/ + +Files: + * + debian/* +Copyright: + 2002-2020 the mutter authors + 1991-2000 Silicon Graphics Inc + 1999-2005 Brian Paul + 1999-2000 Erik Walthinsen + 2001-2008 Havoc Pennington, Red Hat, Inc., and others + 2002 The Gnome Foundation + 2007 The GNOME Project + 2002 Ross Burton + 2004-2006 Elijah Newren + 2001 Dominik Vogt, Matthias Clasen, and fvwm2 team + 2003-2004 Rob Adams + 2001-2003 Sun Microsystems Inc + 1986-1998 The Open Group + 1987 Digital Equipment Corporation + 2001 Anders Carlsson + 2008 Thomas Thurman + 1995-2000 GTK+ Team + 1988 Wyse Technology, Inc., + 2008 Iain Holmes + 2000-2001 Eazel, Inc. + 2001 Ximian, Inc. + 2002 Gaute Lindkvist + 2002 James M. Cape + 2002 Garrett LeSage + 2002 Tuomas Kuosmanen + 2002 Jorn Baayen + 1997-2000 Dan Pascu and Alfredo Kojima + 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + 1998 Tim Janik + 1999-2020 Free Software Foundation, Inc. + 1995-1997 Ulrich Drepper + 1994 X Consortium + 2004-2008 Rodney Dawes + 2004 Scott James Remnant + 2002 Simos Xenitellis + 2003-2006 Miloslav Trmac + 2008 GNOME i18n Project for Vietnamese + 2003-2006 Sharif FarsiWeb, Inc. + 2003 Åsmund Skjæveland. + 2005-2011 Canonical Ltd. and Rosetta Contributors + 2004-2006 Adam Weinberger and the GNOME Foundation + 2004 Kakilik Project + Croatiann team + 2006-2008 OpenedHand Ltd + 2007 William Jon McCann + 2007-2017 Intel Corporation + 2008 Matthew Allum + 2008 Tungsten Graphics Inc + 2002 Kjartan Maraas + 2002 Keld simonsen + 2002 Ole Laursen + 2004-2005 Martin Willemoes Hansen + 2006 Lasse Bang Mikkelsen + 2008 Kenneth Nielsen + 2008-2010 Igalia, S.L. + 2008-2011 Kristian Høgsberg + 2010-2012 Inclusive Design Research Centre, OCAD University + 2011 Joe Hansen + 2011-2014 Collabora Ltd + 2011 Robert Bosch Car Multimedia GmbH + 2007-2018 Ask Hjorth Larsen + 2002 Simos Xenitellis + 2001-2020 Red Hat Inc + 2016 Hyungwon Hwang + 2001-2008 Havoc Pennington + 2009 Sander Dijkhuis + 2005-2007 Olivier Fourdan + 2011 NVIDIA Corporation + 2012 Bastian Winkler + 2013 Keith Packard + 2013-2015 Emmanuele Bassi + 2014 Endless Mobile + 2014 Jonas Ådahl + 2014 Rico Tzschichholz + 2018-2020 DisplayLink (UK) Ltd. + 2018-2019 Robert Mader + 2005-2018 Canonical Ltd. + 2018-2020 Simon McVittie +License: GPL-2+ and LGPL-2+ and LGPL-2.1+ and Expat and NTP-BSD-variant and SGI-B-2.0 + +Files: + cogl/cogl/cogl-point-in-poly.c +Copyright: + 1970-2003 Wm. Randolph Franklin + 2011 Intel Corporation +License: WRF-BSD-variant + +Files: + src/x11/mutter-Xatomtype.h +Copyright: + 1987-1998 The Open Group + 1987 Digital Equipment Corporation +License: DEC-BSD-variant and OpenGroup-BSD-variant + +Files: + src/x11/xprops.c +Copyright: + 1987-1998 The Open Group + 1987 Digital Equipment Corporation + 1998 Wyse Technology Inc + 2001 Havoc Pennington + 2002 Red Hat Inc +License: DEC-BSD-variant and OpenGroup-BSD-variant and GPL-2+ -Files: * -Copyright: 1997-2000, Dan Pascu and Alfredo Kojima - 2001, Dominik Vogt, Matthias Clasen, and fvwm2 team - 2004-2006, Elijah Newren - 2010, Florian Müllner - 1989-1991, Free Software Foundation, Inc - 1995-2000, GTK+ Team - 2001, Havoc Pennington - 2001, Havoc Pennington (based on GDK code - 2001, Havoc Pennington, 99% copied from wrlib in - 2001, Havoc Pennington, Anders Carlsson - 2001, Havoc Pennington, error trapping inspired by GDK - 2008, Iain Holmes - 2008, Intel Corp - 2011-2012, Intel Corporation - 2002, Jorn Baayen <jorn@nl.linux.org> - 2003, Keith Packard - 2008, Matthew Allum - Matthias Clasen, Dominik Vogt - 2010, Milan Bouchet-Valat - 2005-2007, Olivier Fourdan - Owen - 2002, Red Hat Inc - 2010, Red Hat, Inc - Red Hat. So - 2003, Rob Adams - 2009, Sander Dijkhuis - 2002, Sun Microsystems - 2002, Sun Microsystems Inc - 2008, Thomas Thurman - Tom Tromey, Carsten Schaar - 2004-2006, Adam Weinberger and the GNOME Foundation - 2005, Canonical Ltd - 2006, Canonical Ltd. and Rosetta Contributors - Croatiann team - 2003, Free Software Foundation - 2003-2008, Free Software Foundation Inc - 2009, Free Software Foundation, Inc - 2009, GNOME i18n Project for Vietnamese - 2001-2008, Havoc Pennington, Red Hat, Inc, og andre - 2001-2008, Havoc Pennington, Red Hat, Inc. dy inšyja - 2001-2002, Havoc Pennington, Red Hat, Inc. və başqaları - 2001-2008, Havoc Pennington, Red Hat, Inc., ac eraill - 2001-2007, Havoc Pennington, Red Hat, Inc., and others - 2001-2002, Havoc Pennington, Red Hat, Inc., àti àwọn mìíràn - 2001-2002, Havoc Pennington, Red Hat, Inc., da saura - 2001-2008, Havoc Pennington, Red Hat, Inc., e të tjerë - 2001-2002, Havoc Pennington, Red Hat, Inc., et des ôtes - 2001-2008, Havoc Pennington, Red Hat, Inc., hag all - 2001-2002, Havoc Pennington, Red Hat, Inc., i ostali - 2001-2002, Havoc Pennington, Red Hat, Inc., nakwa ndị ọzọ - 2001-2002, Havoc Pennington, Red Hat, Inc., og - 2001-2002, Havoc Pennington, Red Hat, Inc., sy ireo hafa - 2001-2002, Havoc Pennington, Red Hat, Inc., ба бусад - 2001-2002, Havoc Pennington, Red Hat, Inc., և այլոք - 2001-2008, Havoc Pennington, Red Hat, Inc., व इतर - 2003-2006, Miloslav Trmac <mitr@volny.cz> - 2007, Rosetta Contributors and Canonical Ltd 2007 - 2011, Rosetta Contributors and Canonical Ltd 2011 - 2003-2006, Sharif FarsiWeb, Inc - 2002, Simos Xenitellis - 2011, Swecha Telugu Localisation Team <localization@swecha.net> - 2004-2005, The Free Software Foundation - 2007-2011, The GNOME Project - 2002, The Gnome Foundation - 2008, Thomas Thurman - 2001-2012, metacity - 2002-2011, the author(s) of muffin - 2003, Åsmund Skjæveland - 2001-2007, हावोक पेनिङटोन, रेड ह्याट, संस्था., र अन्य - 2001-2008, হ্যাভক পেনিংটন, Red Hat, Inc., ও অন্যান্যদের - 2001-2002, হ্যাভোক পেনিংটন, রেড হ্যাট্, ইন্‍কর্পোরেট এবং অন্যান্য License: GPL-2+ + This package is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + . + This package is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. +Comment: + On Debian systems, the complete text of the GNU General + Public License version 2 can be found in + /usr/share/common-licenses/GPL-2. + +License: LGPL-2+ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + . + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. +Comment: + On Debian systems, the complete text of the GNU Library General + Public License version 2 can be found in + /usr/share/common-licenses/LGPL-2, and the complete text of the + GNU Lesser General Public License version 2.1 can be found in + /usr/share/common-licenses/LGPL-2.1. + +License: LGPL-2.1+ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + . + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. +Comment: + On Debian systems, the complete text of the + GNU Lesser General Public License version 2.1 can be found in + /usr/share/common-licenses/LGPL-2.1. -Files: src/compositor/meta-sync-ring.c - src/core/async-getprop.c - src/core/async-getprop.h - src/core/muffin-Xatomtype.h - src/core/testasyncgetprop.c -Copyright: 1987, Digital Equipment Corporation, Maynard, Massachusetts - 2002, Havoc Pennington - 2011, NVIDIA Corporation - 1986-1998, The Open Group -License: MIT/X11 - Permission to use, copy, modify, distribute, and sell this software - and its documentation for any purpose is hereby granted without - fee, provided that the above copyright notice appear in all copies - and that both that copyright notice and this permission notice - appear in supporting documentation. +License: Expat + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: . The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. @@ -99,196 +171,117 @@ License: MIT/X11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR - ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - . - Except as contained in this notice, the name of The Open Group shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from The Open Group. - -Files: src/ui/metaaccellabel.c - src/ui/metaaccellabel.h -Copyright: 1995-1997, Peter Mattis, Spencer Kimball and Josh MacDonald - 2002, Red Hat, Inc - 1998, Tim Janik -License: LGPL-2+ + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. -Files: src/core/xprops.c -Copyright: 1987, Digital Equipment Corporation, Maynard, Massachusetts - 2001, Havoc Pennington - 2002, Red Hat Inc - 1987-1998, The Open Group - 1988, Wyse Technology, Inc., San Jose, Ca -License: GPL-2+_MIT/X11 - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - . - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - . - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - 02110-1335, USA. - . - *********************************************************************** - All Rights Reserved - . - Permission to use, copy, modify, and distribute this software and its - documentation for any purpose and without fee is hereby granted, - provided that the above copyright notice appear in all copies and that - both that copyright notice and this permission notice appear in - supporting documentation, and that the name Digital not be - used in advertising or publicity pertaining to distribution of the - software without specific, written prior permission. +License: NTP-BSD-variant + Permission to use, copy, modify, distribute, and sell this software and its + documentation for any purpose is hereby granted without fee, provided that + the above copyright notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting documentation, and + that the name of the copyright holders not be used in advertising or + publicity pertaining to distribution of the software without specific, + written prior permission. The copyright holders make no representations + about the suitability of this software for any purpose. It is provided "as + is" without express or implied warranty. . - DIGITAL AND WYSE DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - EVENT SHALL DIGITAL OR WYSE BE LIABLE FOR ANY SPECIAL, INDIRECT OR - CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF - USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. + EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + OF THIS SOFTWARE. + +License: WRF-BSD-variant + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: . - *********************************************************************** + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimers. + 2. Redistributions in binary form must reproduce the above + copyright notice in the documentation and/or other materials + provided with the distribution. + 3. The name of W. Randolph Franklin may not be used to endorse or + promote products derived from this Software without specific + prior written permission. . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +License: OpenGroup-BSD-variant Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. . - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - . - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - . - Except as contained in this notice, the name of The Open Group shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from The Open Group. - . - On Debian systems, the complete text of the GNU General Public License - version 2 can be found in `/usr/share/common-licenses/GPL-2'. - -Files: po/tk.po -Copyright: 2004, Free Software Foundation - 2001-2002, Havoc Pennington, Red Hat, Inc., and others - 2004, Kakilik Project <kakilik.sourceforge.net> -License: GPL - This file is distributed under the terms of GNU General Public License (GPL) - . - On Debian systems, the complete text of the GNU General Public License can be - found in `/usr/share/common-licenses/GPL'. - -Files: po/Makefile.in.in -Copyright: 2004-2008, Rodney Dawes <dobey.pwns@gmail.com> - 1995-1997, Ulrich Drepper <drepper@gnu.ai.mit.edu> -License: Permissive - This file may be copied and used freely without restrictions. It may - be used in projects which are not available under a GNU Public License, - but which still want to provide support for the GNU gettext functionality. - -Files: po/rw.po -Copyright: 2005, Free Software Foundation, Inc - 2001-2002, Havoc Pennington, Red Hat, Inc., and others -License: MPL-1.1_GPL-2+_LGPL-2.1+ - ***** BEGIN LICENSE BLOCK ***** - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - . - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - . - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - . - The Original Code is Mozilla Communicator client code, released - March 31, 1998. - . - The Initial Developer of the Original Code is - Netscape Communications Corporation. - Portions created by the Initial Developer are Copyright (C) 1998-1999 - the Initial Developer. All Rights Reserved. - . - Contributor(s): - . - Alternatively, the contents of this file may be used under the terms of - either of the GNU General Public License Version 2 or later (the "GPL"), - or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the GPL or the LGPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. . - ***** END LICENSE BLOCK ***** + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. . - On Debian systems, the complete text of the GNU General Public License - version 2 can be found in `/usr/share/common-licenses/GPL-2', likewise, the - complete text of the GNU Lesser General Public License version 2.1 can be - found in `/usr/share/common-licenses/LGPL-2.1'. - -Files: debian/* -Copyright: 2012, Nicolas Bourdaud <nicolas.bourdaud@gmail.com> - 2012, Laszlo Boszormenyi (GCS) <gcs@debian.hu> - 2011-2012, Michael Biebl - 2011-2012, Sjoerd Simons - 2012 Clement Lefebvre - 2012 Gwendal Le Bihan -License: GPL-2+ + Except as contained in this notice, the name of The Open Group shall not be + used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from The Open Group. -License: GPL-2+ - This package is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - . - This package is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - . - You should have received a copy of the GNU General Public License - along with this package; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +License: DEC-BSD-variant + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose and without fee is hereby granted, + provided that the above copyright notice appear in all copies and that + both that copyright notice and this permission notice appear in + supporting documentation, and that the name of Digital not be + used in advertising or publicity pertaining to distribution of the + software without specific, written prior permission. . - On Debian systems, the complete text of the GNU General Public License - version 2 can be found in `/usr/share/common-licenses/GPL-2'. + DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR + ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + SOFTWARE. -License: LGPL-2+ - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. +License: SGI-B-2.0 + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: . - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + The above copyright notice including the dates of first publication and + either this permission notice or a reference to + http://oss.sgi.com/projects/FreeB/ + shall be included in all copies or substantial portions of the Software. . - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the - Free Software Foundation, Inc., 51 Franklin Street - Suite 500, - Boston, MA 02110-1335, USA. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. . - On Debian systems, the complete text of the GNU Lesser General - Public License can be found in `/usr/share/common-licenses/LGPL-2'. + Except as contained in this notice, the name of Silicon Graphics, Inc. + shall not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization from + Silicon Graphics, Inc. diff --git a/debian/libmuffin-dev.install b/debian/libmuffin-dev.install new file mode 100644 index 000000000..33a217842 --- /dev/null +++ b/debian/libmuffin-dev.install @@ -0,0 +1,5 @@ +usr/include +usr/lib/*/lib*.so +usr/lib/*/muffin/*.so +usr/lib/*/muffin/*.gir +usr/lib/*/pkgconfig/*.pc diff --git a/debian/libmuffin0.bug-control b/debian/libmuffin0.bug-control new file mode 100644 index 000000000..3e4f057fd --- /dev/null +++ b/debian/libmuffin0.bug-control @@ -0,0 +1 @@ +package-status: libegl-vendor libglx-vendor libgl1-mesa-dri diff --git a/debian/libmuffin0.install b/debian/libmuffin0.install index 57b6c42d9..e66f14384 100644 --- a/debian/libmuffin0.install +++ b/debian/libmuffin0.install @@ -1,7 +1,3 @@ usr/lib/*/libmuffin.so.* -usr/lib/*/libmuffin*.so -usr/lib/*/muffin/*.so -usr/include -usr/lib/*/pkgconfig/*.pc -usr/lib/*/muffin/*.gir +usr/lib/*/muffin/*.so.* usr/libexec/muffin-restart-helper diff --git a/debian/muffin-common.install b/debian/muffin-common.install index 0eb2cc57b..765fb081e 100644 --- a/debian/muffin-common.install +++ b/debian/muffin-common.install @@ -1,4 +1,3 @@ usr/share/glib-2.0 usr/share/locale usr/share/man -usr/share/muffin diff --git a/debian/muffin-common.maintscript b/debian/muffin-common.maintscript deleted file mode 100644 index 9c56f2430..000000000 --- a/debian/muffin-common.maintscript +++ /dev/null @@ -1 +0,0 @@ -rm_conffile /etc/sgml/muffin-common.cat 3.5 diff --git a/debian/muffin-doc.install b/debian/muffin-doc.install deleted file mode 100644 index e0ba7d777..000000000 --- a/debian/muffin-doc.install +++ /dev/null @@ -1 +0,0 @@ -/usr/share/gtk-doc diff --git a/debian/muffin.docs b/debian/muffin.docs new file mode 100644 index 000000000..edc007104 --- /dev/null +++ b/debian/muffin.docs @@ -0,0 +1 @@ +NEWS diff --git a/debian/muffin.postinst b/debian/muffin.postinst new file mode 100644 index 000000000..e2e179227 --- /dev/null +++ b/debian/muffin.postinst @@ -0,0 +1,16 @@ +#!/bin/sh + +set -e + +action="$1" + +if [ "$action" = configure ]; then + # register the alternatives of x-window-manager manually + # because dh_installwm doesn't register manpage as slave yet. + update-alternatives --install /usr/bin/x-window-manager \ + x-window-manager /usr/bin/muffin 60 \ + --slave /usr/share/man/man1/x-window-manager.1.gz \ + x-window-manager.1.gz /usr/share/man/man1/muffin.1.gz +fi + +#DEBHELPER# diff --git a/debian/muffin.prerm b/debian/muffin.prerm new file mode 100644 index 000000000..8bae26e4f --- /dev/null +++ b/debian/muffin.prerm @@ -0,0 +1,12 @@ +#!/bin/sh + +set -e + +action="$1" + +if [ "$action" = remove ]; then + update-alternatives --remove x-window-manager \ + /usr/bin/muffin +fi + +#DEBHELPER# diff --git a/debian/not-installed b/debian/not-installed deleted file mode 100644 index c7453b296..000000000 --- a/debian/not-installed +++ /dev/null @@ -1,4 +0,0 @@ -# libtool not installed -usr/lib/*/libmuffin.la -# manpages are compressed -usr/share/man/man1/*.1 diff --git a/debian/rules b/debian/rules index 839e882e2..aa09acf54 100755 --- a/debian/rules +++ b/debian/rules @@ -1,42 +1,109 @@ #!/usr/bin/make -f -# -*- makefile -*- -# Uncomment this to turn on verbose mode. -#export DH_VERBOSE=1 +export DEB_BUILD_MAINT_OPTIONS = hardening=+all +export DEB_LDFLAGS_MAINT_APPEND = -Wl,-O1 -Wl,--as-needed -export DEB_LDFLAGS_MAINT_APPEND=-Wl,--as-needed -DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH) -DEB_BUILD_ARCH ?= $(shell dpkg-architecture -qDEB_BUILD_ARCH) +%: + dh $@ -ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) - NUMJOBS = $(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) - MAKEFLAGS += -j$(NUMJOBS) -endif +override_dh_autoreconf: + dh_autoreconf --as-needed -ifeq (ppc64el,$(filter $(DEB_BUILD_ARCH),ppc64el)) - CFLAGS += -O2 +ifeq ($(DEB_HOST_ARCH_OS),linux) +CONFFLAGS = \ + -Degl_device=true \ + -Dwayland=true \ + -Dwayland_eglstream=true \ + -Dnative_backend=true +else +CONFFLAGS += \ + -Dudev=false \ + -Dlibwacom=false \ + -Dwayland=false \ + -Dcore_tests=false \ + -Dnative_backend=false \ + -Dremote_desktop=false endif -%: - dh $@ --with gir +ifeq ($(DEB_HOST_ARCH),$(findstring $(DEB_HOST_ARCH),armel armhf)) +CONFFLAGS += \ + -Ddefault_driver=gles2 +else +CONFFLAGS += \ + -Ddefault_driver=gl +endif -override_dh_autoreconf: - NOCONFIGURE=1 dh_autoreconf --as-needed ./autogen.sh +# pipewire is not in Ubuntu main yet +ifeq ($(DEB_HOST_ARCH_OS),linux) +ifeq ($(shell dpkg-vendor --query vendor),Ubuntu) + CONFFLAGS += -Dremote_desktop=false +else + CONFFLAGS += -Dremote_desktop=true +endif +endif override_dh_auto_configure: dh_auto_configure -- \ - --libexecdir="\$${prefix}/libexec" \ - --disable-static \ - --enable-startup-notification=yes \ - --disable-silent-rules \ - --enable-gtk-doc \ - --disable-clutter-doc \ + -Dstartup_notification=true \ + -Degl=true \ + -Dgles2=true \ + -Dgles2_libname=libGLESv2.so.2 \ + -Dinstalled_tests=false \ + -Dprofiler=false \ + $(CONFFLAGS) + +# Use meson test directly as it allows us to use the timeout multiplier +BUILDDIR=$(CURDIR)/obj-$(DEB_HOST_GNU_TYPE) +TEST_COMMAND_BASE=env \ + -u XDG_CACHE_HOME \ + -u XDG_CONFIG_DIRS \ + -u XDG_CONFIG_HOME \ + -u XDG_DATA_DIRS \ + -u XDG_DATA_HOME \ + HOME=$(BUILDDIR)/HOME \ + XDG_RUNTIME_DIR=$(BUILDDIR)/XRD \ + GSETTINGS_SCHEMA_DIR=$(BUILDDIR)/data \ + dbus-run-session -- xvfb-run -s '+iglx -noreset' -a \ + meson test -C $(BUILDDIR) --no-rebuild --verbose --timeout-multiplier 6 \ + --no-stdsplit --print-errorlogs +TEST_COMMAND=$(TEST_COMMAND_BASE) --no-suite flaky +TEST_COMMAND_FLAKY=$(TEST_COMMAND_BASE) --suite flaky + +ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) + NUMJOBS = $(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) + TEST_COMMAND += --num-processes $(NUMJOBS) +endif + +# Ignore test failures on hurd, kfreebsd and s390x. Although the test results +# indicate there may be a serious issue, the port maintainers may +# prefer we do the build anyway. I plan to file a bug for this later. +# Don't run the tests on mips since they either time out or fail too much, +# blocking migration to testing +override_dh_auto_test: +ifeq (,$(filter nocheck, $(DEB_BUILD_OPTIONS))) + glib-compile-schemas $(BUILDDIR)/data + mkdir -m 700 $(BUILDDIR)/HOME + mkdir -m 700 $(BUILDDIR)/XRD +ifneq (,$(filter hurd-i386 kfreebsd-i386 kfreebsd-amd64 riscv64 s390x,$(DEB_HOST_ARCH))) + -$(TEST_COMMAND) + -$(TEST_COMMAND_FLAKY) +else ifeq (,$(filter mips mips64el mipsel,$(DEB_HOST_ARCH))) + $(TEST_COMMAND) + -$(TEST_COMMAND_FLAKY) +endif +endif + +override_dh_missing: + dh_missing --fail-missing override_dh_girepository: dh_girepository /usr/lib/$(DEB_HOST_MULTIARCH)/muffin +override_dh_makeshlibs: + dh_makeshlibs -V + +override_dh_shlibdeps: + dh_shlibdeps -Llibmuffin-0 -l/usr/lib/$(DEB_HOST_MULTIARCH)/muffin + override_dh_strip: dh_strip --dbg-package=muffin-dbg - -override_dh_install: - dh_install -X.la --fail-missing diff --git a/debian/tests/control b/debian/tests/control new file mode 100644 index 000000000..2c0cd2457 --- /dev/null +++ b/debian/tests/control @@ -0,0 +1,7 @@ +Tests: libmutter-6-dev +Depends: build-essential, + dbus, + libmutter-6-dev, + xauth, + xvfb +Restrictions: allow-stderr superficial diff --git a/debian/tests/libmutter-6-dev b/debian/tests/libmutter-6-dev new file mode 100755 index 000000000..ea89a7427 --- /dev/null +++ b/debian/tests/libmutter-6-dev @@ -0,0 +1,41 @@ +#!/bin/sh +# autopkgtest check: Build and run a program against libmutter, to verify +# that the headers and pkg-config file are installed correctly +# (C) 2012 Canonical Ltd. +# (C) 2018-2019 Simon McVittie +# Authors: Martin Pitt, Simon McVittie + +set -eux + +WORKDIR=$(mktemp -d) +export HOME="$WORKDIR" +export XDG_RUNTIME_DIR="$WORKDIR" +cleanup () { + rm -fr "$WORKDIR" +} +trap cleanup 0 INT QUIT ABRT PIPE TERM +cd "$WORKDIR" + +if [ -n "${DEB_HOST_GNU_TYPE:-}" ]; then + CROSS_COMPILE="$DEB_HOST_GNU_TYPE-" +else + CROSS_COMPILE= +fi + +cat <<'EOF' > trivial.c +#include <meta/util.h> + +int main(void) +{ + g_assert_false(meta_is_wayland_compositor()); + return 0; +} +EOF + +# Deliberately word-splitting pkg-config's output: +# shellcheck disable=SC2046 +"${CROSS_COMPILE}gcc" -o trivial trivial.c $("${CROSS_COMPILE}pkg-config" --cflags --libs libmutter-6) +echo "build: OK" +[ -x trivial ] +xvfb-run -a dbus-run-session -- ./trivial +echo "run: OK" diff --git a/doc/Makefile.am b/doc/Makefile.am deleted file mode 100644 index d16ae33fe..000000000 --- a/doc/Makefile.am +++ /dev/null @@ -1,4 +0,0 @@ -SUBDIRS = man reference - -EXTRA_DIST=theme-format.txt dialogs.txt code-overview.txt \ - how-to-get-focus-right.txt diff --git a/doc/compositor-control.txt b/doc/compositor-control.txt new file mode 100644 index 000000000..1253cc3d6 --- /dev/null +++ b/doc/compositor-control.txt @@ -0,0 +1,46 @@ +The compositor is the box of tricks inside the window manager which performs +special effects on the windows on your screen. Metacity's compositor is +under development. Your help is requested in finding and fixing bugs. This +document tells you how to configure Metacity so that you can use compositing. + +To turn the compositor on initially, you need to pass --enable-compositor to +the configure script. This will introduce a dependence on libcm, which you +can get from <URL:http://ftp.gnome.org/pub/GNOME/sources/libcm/>. + +When Metacity is compiled, you will need to turn the compositor on in gconf +for it to have any effect. You will find the boolean switch at + + /apps/metacity/general/compositing_manager + +When that's done, you can set some environment variables before you launch +Metacity to influence how the compositor works. These will eventually become +configuration options or gconf options when they grow up. Define them to any +value to turn them on; leave them undefined to turn them off. Currently the +options you can set are: + + LIBCM_DIRECT + + If this is set, the compositor will bypass the X server and do all its + work directly with the hardware. I know of no reason you would want to + do so, but perhaps you do. + + LIBCM_TFP + + If this is set ("tfp mode"), the compositor will feel free to use the + texture_from_pixmap extension; if this is not set ("non-tfp mode"), the + compositor will use a workaround. Many drivers require non-tfp mode in + order to work, and will paint all windows clear blue or clear white + without it. Thanks to Travis Watkins for suggesting this switch; he + cautions that some games or video players may require tfp mode. + + METACITY_BLING + + This turns on several pretty but non-essential animations (dialogues + fracturing and exploding, minimisations doing a shrinkydink effect, + and so on). If it is not set, the standard non-GL animations are + retained. This affects only window event animations; it doesn't change + menus zooming, dialogues being semi-transparent, and so on. Try it + and see whether you like it. + +If you have any problems, ask on mutter-devel-list@gnome.org, or +#gnome-hackers on gimpnet, or come and find me (tthurman at gnome) and ask. diff --git a/doc/how-constraints-works.txt b/doc/how-constraints-works.txt new file mode 100644 index 000000000..a6e02f3bc --- /dev/null +++ b/doc/how-constraints-works.txt @@ -0,0 +1,283 @@ +File contents: + Basic Ideas + Important points to remember + Explanation of fields in the ConstraintInfo struct + Gory details of resize_gravity vs. fixed_directions + +IMPORTANT NOTE: There's a big comment at the top of constraints.c +explaining how to add extra constraints or tweak others. Read it. I put +that information there because it may be enough information by itself for +people to hack on constraints.c. I won't duplicate that information in +this file; this file is for deeper details. + + +--------------------------------------------------------------------------- +Basic Ideas +--------------------------------------------------------------------------- +There are a couple basic ideas behind how this constraints.c code works and +why it works that way: + + 1) Split the low-level error-prone operations into a special file + 2) Add robustness by prioritizing constraints + 3) Make use of a minimal spanning set of rectangles for the + "onscreen region" (screen minus struts). + 4) Constraints can be user-action vs app-action oriented + 5) Avoid over-complification ;-) + +Some more details explaining these basic ideas: + + 1) Split tedious operations out + + boxes.[ch] have been added which contain many common, tedious, and + error-prone operations. I find that this separation helps a lot for + managing the complexity and ensuring that things work correctly. + Also, note that testboxes.c thoroughly tests all functionality in + boxes.[ch] and a testboxes program is automatically compiled. + + Note that functions have also been added to this file to handle some + of the tedium necessary for edge resistance as well. + + 2) Prioritize constraints + + In the old code, if each and every constraint could not be + simultaneously satisfied, then it would result in some + difficult-to-predict set of constraints being violated. This was + because constraints were applied in order, with the possibility for + each making changes that violated previous constraints, with no + checking done at the end. + + Now, all constraints have an associated priority, defined in the + ConstraintPriority enum near the top of constraints.c. The + constraints are all applied, and then are all checked; if not all are + satisfied then the least important constraints are dropped and the + process is repeated. This ensures that the most important constraints + are satisfied. + + A special note to make here is that if any one given constraint is + impossible to satisfy even individually (e.g. if minimum size hints + specify a larger window than the screen size, making the + fully-onscreen constraint impossible to satisfy) then we treat the + constraint as being satisfied. This sounds counter-intuitive, but the + idea is that we want to satisfy as many constraints as possible and if + we treat it as a violation then all constraints with a lesser priority + also get dropped along with the impossible to satisfy one. + + 3) Using maximal/spanning rectangles + + The constraints rely heavily on something I call spanning rectangles + (which Soeren referred to as maximal rectangles, a name which I think + I like better but I don't want to go change all the code now). These + spanning rectangles have the property that a window will fit on the + screen if and only if it fits within at least one of the rectangles. + Soeren had an alternative way of describing these rectangles, namely + that they were rectangles with the property that if you made any of + them larger in any direction, they would overlap with struts or be + offscreen (with the implicit assumption that there are enough of these + rectangles that combined they cover all relevant parts of the screen). + Note that, by necessity, these spanning/maximal rectangles will often + overlap each other. + + Such a list makes it relatively easy to define operations like + window-is-onscreen or clamp-window-to-region or + shove-window-into-region. Since we have a on-single-xinerama + constraint in addition to the onscreen constraint(s), we cache + number_xineramas + 1 of these lists in the workspace. These lists + then only need to be updated whenever the workarea is (e.g. when strut + list change or screen or xinerama size changes). + + 4) Constraints can be user-action vs app-action oriented + + Such differentiation requires special care for the constraints to be + consistent; e.g. if the user does something and one constraint + applies, then the app does something you have to be careful that the + constraint on the app action doesn't result in some jarring motion. + + In particular, the constraints currently allow offscreen movement or + resizing for user actions only. The way consistency is handled is + that at the end of the constraints, update_onscreen_requirements() + checks to see if the window is offscreen or split across xineramas and + updates window->require_fully_onscreen and + window->require_on_single_xinerama appropriately. + + 5) Avoid over-complification + + The previous code tried to reform the constraints into terms of a + single variable. This made the code rather difficult to + understand. ("This is a rather complicated fix for an obscure bug + that happened when resizing a window and encountering a constraint + such as the top edge of the screen.") It also failed, even on the + very example for which it used as justification for the complexity + (bug 312104 -- when keyboard resizing the top of the window, + Metacity extends the bottom once the titlebar hits the top panel), + though the reason why it failed is somewhat mysterious as it should + have worked. Further, it didn't really reform the constraints in + terms of a single variable -- there was both an x_move_delta and an + x_resize_delta, and the existence of both caused bug 109553 + (gravity with simultaneous move and resize doesn't work) + + +--------------------------------------------------------------------------- +Important points to remember +--------------------------------------------------------------------------- + + - Inner vs Outer window + + Note that because of how configure requests work and + meta_window_move_resize_internal() and friends are set up, that the + rectangles passed to meta_window_constrain() are with respect to inner + window positions instead of outer window positions (meaning that window + manager decorations are not included in the position/size). For the + constraints that need to be enforced with respect to outer window + positions, you'll need to make use of the extend_by_frame() and + unextend_by_frame() functions. + + - meta_window_move_resize_internal() accepts a really hairy set of + inputs. See the huge comment at the beginning of that function. + constraints gets screwed up if that function can't sanitize the input, + so be very careful about that. It used to be pretty busted. + + +--------------------------------------------------------------------------- +Explanation of fields in the ConstraintInfo strut +--------------------------------------------------------------------------- + +As of the time of this writing, ConstraintInfo had the following fields: + orig + current + fgeom + action_type + is_user_action + resize_gravity + fixed_directions + work_area_xinerama + entire_xinerama + usable_screen_region + usable_xinerama_region + +A brief description of each and/or pointers to more information are found +below: + orig + The previous position and size of the window, ignoring any window + decorations + current + The requested position and size of the window, ignoring any window + decorations. This rectangle gets modified by the various constraints + to specify the allowed position closest to the requested position. + fgeom + The geometry of the window frame (i.e. "decorations"), if it exists. + Otherwise, it's a dummy 0-size frame for convenience (i.e. this pointer + is guaranteed to be non-NULL so you don't have to do the stupid check). + action_type + Whether the action being constrained is a move, resize, or a combined + move and resize. Some constraints can run faster with this information + (e.g. constraining size increment hints or min size hints don't need to + do anything for pure move operations). This may also be used for + providing slightly different behavior (e.g. clip-to-region instead of + shove-into-region for resize vs. moving operations), but doesn't + currently have a lot of use for this. + is_user_action + Used to determine whether the action being constrained is a user + action. If so, certain parts of the constraint may be relaxed. Note + that this requires care to get right; see item 4 of the basic ideas + section for more details. + resize_gravity + The gravity used in the resize operation, used in order to make sure + windows are resized correctly if constraints specify that their size + must be modified. Explained further in the resize_gravity + vs. fixed_directions section. + fixed_directions + There may be multiple solutions to shoving a window back onscreen. + Typically, the shortest distance used is the solution picked, but if + e.g. an application only moved its window in a single direction, it's + more desirable that the window is shoved back in that direction than in + a different one. fixed_directions facilitates that. Explained further + in the resize_gravity vs. fixed_directions section. + work_area_xinerama + This region is defined in the workspace and just cached here for + convenience. It is basically the area obtained by taking the current + xinerama, treating all partial struts as full struts, and then + subtracting all struts from the current xinerama region. Useful + e.g. for enforcing maximization constraints. + entire_xinerama + Just a cache of the rectangle corresponding to the entire current + xinerama, including struts. Useful e.g. for enforcing fullscreen + constraints. + usable_screen_region + The set of maximal/spanning rectangles for the entire screen; this + region doesn't overlap with any struts and helps to enforce + e.g. onscreen constraints. + usable_xinerama_region + The set of maximal/spanning rectangles for the current xinerama; this + region doesn't overlap with any struts on the xinerama and helps to + enforce e.g. the on-single-xinerama constraint. + + +--------------------------------------------------------------------------- +Gory details of resize_gravity vs. fixed_directions +--------------------------------------------------------------------------- + +Note that although resize_gravity and fixed_directions look similar, they +are used for different purposes: + + - resize_gravity is only for resize operations and is used for + constraints unrelated to keeping a window within a certain region + - fixed_directions is for both move and resize operations and is + specifically for keeping a window within a specified region. + +Examples of where each are used: + + - If a window is simultaneously moved and resized to the southeast corner + with META_GRAVITY_SOUTH_EAST, but it turns out that the window was sized to + something smaller than the minimum size hint, then the size_hints + constraint should resize the window using the resize_gravity to ensure + that the southeast corner doesn't move. + - If an application resizes itself so that it grows downward only (which + I note could be using any of three different gravities, most likely + NorthWest), and happens to put the southeast part of the window under a + partial strut, then the window needs to be forced back on screen. + (Yes, shoved onscreen and not clipped; see bug 136307). It may be the + case that moving the window to the left results in less movement of the + window than moving the window up, which, in the absence of fixed + directions would cause us to chose moving to the left. But since the + user knows that only the height of the window is changing, they would + find moving to the left weird (especially if this were a dialog that + had been centered on its parent). It'd be better to shove the window + upwards so we make sure to keep the left and right sides fixed in this + case. Note that moving the window upwards (or leftwards) is probably + totally against the gravity in this case; but that's okay because + gravity typically assumes there's more than enough onscreen space for + the resize and we only override the gravity when that assumption is + wrong. + +For the paranoid, a fixed directions might give an impossible to fulfill +constraint (I don't think that's true currently in the code, but I haven't +thought it through in a while). If this ever becomes a problem, it should +be relatively simple to throw out the fixed directions when this happens +and rerun the constraint. Of course, it might be better to rethink things +to just avoid such a problem. + +The nitty gritty of what gets fixed: + User move: + in x direction - y direction fixed + in y direction - x direction fixed + in both dirs. - neither direction fixed + User resize: (note that for clipping, only 1 side ever changed) + in x direction - y direction fixed (technically opposite x side fixed too) + in y direction - x direction fixed (technically opposite y side fixed too) + in both dirs. - neither direction fixed + App move: + in x direction - y direction fixed + in y direction - x direction fixed + in both dirs. - neither direction fixed + App resize + in x direction - y direction fixed + in y direction - x direction fixed + in 2 parallel directions (center side gravity) - other dir. fixed + in 2 orthogonal directions (corner gravity) - neither dir. fixed + in 3 or 4 directions (a center-like gravity) - neither dir. fixed + Move & resize + Treat like resize case though this will usually mean all four sides + change and result in neither direction being fixed + Note that in all cases, if neither direction moves it is likely do to a + change in struts and thus neither direction should be fixed despite the + lack of movement. diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am deleted file mode 100644 index 6e0e55d78..000000000 --- a/doc/man/Makefile.am +++ /dev/null @@ -1,4 +0,0 @@ -man_MANS = muffin.1 muffin-theme-viewer.1 \ - muffin-window-demo.1 muffin-message.1 - -EXTRA_DIST = $(man_MANS) diff --git a/doc/man/meson.build b/doc/man/meson.build new file mode 100644 index 000000000..987f3750b --- /dev/null +++ b/doc/man/meson.build @@ -0,0 +1 @@ +install_man('muffin.1') diff --git a/doc/man/muffin-message.1 b/doc/man/muffin-message.1 deleted file mode 100644 index 8b2be8413..000000000 --- a/doc/man/muffin-message.1 +++ /dev/null @@ -1,60 +0,0 @@ -.\" Hey, EMACS: -*- nroff -*- -.\" First parameter, NAME, should be all caps -.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection -.\" other parameters are allowed: see man(7), man(1) -.\" ----- -.\" This file was confirmed to be licenced under the GPL -.\" by its author and copyright holder, Akira TAGOH, on June 1st 2008: -.\" -.\" > I'm comfortable with DFSG-free. that sounds great if you think it's -.\" > useful and worth containing it in upstream. -.\" ... -.\" > Right I know. any licenses that is DFSG-free, I'm ok with whatever, -.\" > since I have contributed that for Debian. so GPL is no problem for me. -.\" ----- -.TH MUFFIN\-MESSAGE 1 "28 August 2002" -.\" Please adjust this date whenever revising the manpage. -.\" -.\" Some roff macros, for reference: -.\" .nh disable hyphenation -.\" .hy enable hyphenation -.\" .ad l left justify -.\" .ad b justify to both left and right margins -.\" .nf disable filling -.\" .fi enable filling -.\" .br insert line break -.\" .sp <n> insert n+1 empty lines -.\" for manpage-specific macros, see man(7) -.SH NAME -MUFFIN\-MESSAGE \- a command to send a message to Muffin -.SH SYNOPSIS -.B MUFFIN\-MESSAGE -[restart|reload\-theme|enable\-keybindings|disable\-keybindings] -.SH DESCRIPTION -This manual page documents briefly the -.B muffin\-message\fP. -This manual page was written for the Debian distribution -because the original program does not have a manual page. -.PP -.\" TeX users may be more comfortable with the \fB<whatever>\fP and -.\" \fI<whatever>\fP escape sequences to invode bold face and italics, -.\" respectively. -\fBmuffin\-message\fP send a specified message to \fBmuffin\fP(1). -.SH OPTIONS -.TP -.B restart -Restart \fBmuffin\fP(1) which is running. -.TP -.B reload-theme -Reload a theme which is specified on gsettings database. -.TP -.B enable-keybindings -Enable all of keybindings which is specified on gsettings database. -.TP -.B disable-keybindings -Disable all of keybindings which is specified on gsettings database. -.SH SEE ALSO -.BR muffin (1) -.SH AUTHOR -This manual page was written by Akira TAGOH <tagoh@debian.org>, -for the Debian GNU/Linux system (but may be used by others). diff --git a/doc/man/muffin-theme-viewer.1 b/doc/man/muffin-theme-viewer.1 deleted file mode 100644 index 80170c2b8..000000000 --- a/doc/man/muffin-theme-viewer.1 +++ /dev/null @@ -1,43 +0,0 @@ -.\" In .TH, FOO should be all caps, SECTION should be 1-8, maybe w/ subsection -.\" other parms are allowed: see man(7), man(1) -.\" -.\" Based on template provided by Tom Christiansen <tchrist@jhereg.perl.com>. -.\" -.TH MUFFIN-THEME-VIEWER 1 "1 June 2004" -.SH NAME -muffin-theme-viewer \- view muffin themes -.SH SYNOPSIS -.B muffin-theme-viewer -[ -.I THEMENAME -] -.SH DESCRIPTION -.\" Putting a newline after each sentence can generate better output. -.B muffin-theme-viewer -allows you to preview any installed Muffin theme. -.PP -When designing a new Muffin theme, you can use -.B muffin-theme-viewer -to measure the performance of a window frame option, and to preview -the option. -.SH OPTIONS -.TP -.I THEMENAME -Name of the theme to be shown (\fIAtlanta\fR by default). -It is case-sensitive. -.SH FILES -.br -.nf -.TP -.I /usr/share/themes -system themes directory -.TP -.I /usr/share/themes/*/muffin-1/muffin-theme-1.xml -theme specification file -.SH AUTHOR -This manual page was written by Jose M. Moya <josem@die.upm.es>, for -the Debian GNU/Linux system (but may be used by others). -.SH "SEE ALSO" -.\" Always quote multiple words for .SH -.BR muffin (1), -.BR muffin-window-demo (1). diff --git a/doc/man/muffin-window-demo.1 b/doc/man/muffin-window-demo.1 deleted file mode 100644 index ef6107335..000000000 --- a/doc/man/muffin-window-demo.1 +++ /dev/null @@ -1,25 +0,0 @@ -.\" In .TH, FOO should be all caps, SECTION should be 1-8, maybe w/ subsection -.\" other parms are allowed: see man(7), man(1) -.\" -.\" Based on template provided by Tom Christiansen <tchrist@jhereg.perl.com>. -.\" -.TH MUFFIN-WINDOW-DEMO 1 "1 June 2004" -.SH NAME -muffin-window-demo \- demo of window features -.SH SYNOPSIS -.B muffin-window-demo -.SH DESCRIPTION -.\" Putting a newline after each sentence can generate better output. -This program demonstrates various kinds of windows that window -managers and window manager themes should handle. -.PP -Be sure to tear off the menu and toolbar, those are also a special -kind of window. -.SH AUTHOR -This manual page was written by Jose M. Moya <josem@die.upm.es>, for -the Debian GNU/Linux system (but may be used by others). -.SH "SEE ALSO" -.\" Always quote multiple words for .SH -.BR x-window-manager (1), -.BR muffin (1), -.BR muffin-theme-viewer (1). diff --git a/doc/man/muffin.1 b/doc/man/muffin.1 index aa6a35836..8b44cb5d3 100644 --- a/doc/man/muffin.1 +++ b/doc/man/muffin.1 @@ -18,23 +18,23 @@ .SH NAME MUFFIN \- Clutter based compositing GTK2 Window Manager .SH SYNOPSIS -.B muffin +.B MUFFIN [\-\-display=\fIDISPLAY\fP] [\-\-replace] [\-\-sm\-client\-id=\fIID\fP] [\-\-sm\-disable] [\-\-sm\-save\-file=\fIFILENAME\fP] [\-\-version] [\-\-help] .SH DESCRIPTION This manual page documents briefly -.B muffin\fP. +.B MUFFIN\fP. .PP .\" TeX users may be more comfortable with the \fB<whatever>\fP and .\" \fI<whatever>\fP escape sequences to invode bold face and italics, .\" respectively. -\fBmuffin\fP is a minimal X window manager aimed at nontechnical users and is designed to integrate well with the GNOME desktop. \fBmuffin\fP lacks some features that may be expected by traditional UNIX or other technical users; these users may want to investigate other available window managers for use with GNOME or standalone. +\fBMUFFIN\fP is a minimal X window manager aimed at nontechnical users and is designed to integrate well with the Cinnamon desktop. \fBMUFFIN\fP lacks some features that may be expected by traditional UNIX or other technical users; these users may want to investigate other available window managers for use with Cinnamon or standalone. .SH OPTIONS .TP .B \-\-display=DISPLAY Connect to X display \fIDISPLAY\fP. .TP .B \-\-replace -a window manager which is running is replaced by \fBmuffin\fP. Users are encouraged to change the GNOME window manager by running the new WM with the \-\-replace or \-replace option, and subsequently saving the session. +a window manager which is running is replaced by \fBMUFFIN\fP. Users are encouraged to change the Cinnamon window manager by running the new WM with the --replace or -replace option, and subsequently saving the session. .TP .B \-\-sm\-client\-id=ID Specify a session management \fIID\fP. @@ -51,10 +51,10 @@ Print the version number. .B \-?, \-\-help Show summary of options. .SH CONFIGURATION -\fBmuffin\fP configuration can be found under \fIPreferences\fP->\fIWindows\fP and \fIPreferences\fP->\fIKeyboard Shortcuts\fP on the menu-panel. Advanced configuration can be achieved directly through gsettings. +\fBMUFFIN\fP configuration can be found under \fIPreferences\fP->\fIWindows\fP and \fIPreferences\fP->\fIKeyboard Shortcuts\fP on the menu-panel. Advanced configuration can be achieved directly through gsettings. .SH SEE ALSO -.BR muffin-message (1) +.BR MUFFIN-message (1) .SH AUTHOR The original manual page was written by Thom May <thom@debian.org>. It was updated by Akira TAGOH <tagoh@debian.org> for the Debian GNU/Linux system (with permission to use by others), and then updated by Luke Morton and Philip O'Brien -for inclusion in muffin. +for inclusion in MUFFIN. diff --git a/rationales.txt b/doc/rationales.txt similarity index 100% rename from rationales.txt rename to doc/rationales.txt diff --git a/doc/reference/Makefile.am b/doc/reference/Makefile.am deleted file mode 100644 index 8e17beb6d..000000000 --- a/doc/reference/Makefile.am +++ /dev/null @@ -1,5 +0,0 @@ -SUBDIRS = muffin - -if CLUTTER_DOC -SUBDIRS += clutter -endif \ No newline at end of file diff --git a/doc/reference/clutter/ChangeLog b/doc/reference/clutter/ChangeLog deleted file mode 100644 index bd0702b6e..000000000 --- a/doc/reference/clutter/ChangeLog +++ /dev/null @@ -1,1076 +0,0 @@ -2008-12-08 Emmanuele Bassi <ebassi@linux.intel.com> - - * clutter/clutter-docs.xml: - * clutter/clutter-sections.txt: Add ClutterBindingPool - section and link. - -2008-11-12 Emmanuele Bassi <ebassi@linux.intel.com> - - * clutter/clutter-sections.txt: Add new symbols. - -2008-10-17 Emmanuele Bassi <ebassi@linux.intel.com> - - * clutter/clutter-sections.txt: Add the new ClutterColor - symbols. - -2008-09-25 Emmanuele Bassi <ebassi@linux.intel.com> - - * clutter/clutter-sections.txt: Add - clutter_get_option_group_without_init() - -2008-08-27 Emmanuele Bassi <ebassi@openedhand.com> - - * doc/reference/clutter/clutter-sections.txt: Add - clutter_script_list_objects(). - -2008-07-30 Ross Burton <ross@openedhand.com> - - * clutter/version.xml.in: - * cogl/version.xml.in: - Remove trailing newline as it upsets Devhelp - -2008-07-17 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter/subclassing-ClutterActor.xml: Update the ClutterActor - subclassing section by removing the cogl_push/pop_matrix() calls - where not needed. - -2008-07-10 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter/clutter-sections.txt: Add the missing X11 backend - API. - -2008-07-01 Emmanuele Bassi <ebassi@openedhand.com> - - * cogl/cogl-docs.sgml: Add an index to the COGL API reference - and the licensing information. - -2008-06-26 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter/clutter-overview.xml: Split the overview into its own - file, so we gtk-doc can linkify all class names. - - * clutter/building-clutter.xml: Split the building instructions - into its own file, for better maintainability. - - * clutter/clutter-animation.xml: - * clutter/creating-behaviours.xml: - * clutter/subclassing-ClutterActor.xml: Rename from SGML to XML; - these were not SGML files anyway, but templates. - - * clutter/clutter-docs.sgml: Use XInclude instead of the ugly - entities hack. - - * clutter/Makefile.am: Update the build. - -2008-06-25 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter/clutter-sections.txt: Add missing symbols. - -2008-06-25 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter/clutter-sections.txt: Add - clutter_backend_get_display_size() to the documented symbols. - -2008-06-24 Matthew Allum <mallum@openedhand.com> - - * cogl/Makefile.am: - * cogl/cogl-docs.sgml: - * cogl/version.xml.in: - * clutter/version.xml.in: - Add full version (including minor) to docs. - Add version to COGL docs - -2008-06-23 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter/clutter-sections.txt: Remove clutter_actor_get_paint_area() - and add clutter_actor_allocate_preferred_size(). - -2008-06-23 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter/subclassing-ClutterActor.sgml: Remove mention of the - get_paint_area() function and virtual function. - -2008-06-23 Øyvind Kolås <pippin@o-hand.com> - - * clutter/subclassing-ClutterActor.sgml: added missing call to - cogl_push_matrix () - -2008-06-16 Matthew Allum <mallum@openedhand.com> - - * cogl/cogl-docs.sgml: - Add an intro. - -2008-06-13 Øyvind Kolås <pippin@o-hand.com> - - * clutter/event-flow.png: fixed typo. - * clutter/event-flow.dia: added source for event-flow.png, this file - is not referred to in Makefile.am and thus not distributed in - tarballs. - -2008-06-12 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter/clutter-docs.sgml: Clean up. - - * clutter/clutter-sections.txt: Add missing new symbols. - - * clutter/clutter.types: Add ClutterChildMeta type. - -2008-06-11 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter/subclassing-ClutterActor.sgml: Add more notes and - remind to relayout when adding children to an actor. - -2008-06-10 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter/clutter-sections.txt: Update with the new API. - - * clutter/subclassing-ClutterActor.sgml: Update with the new - size negotiation API. - -2008-06-09 Chris Lord <chris@openedhand.com> - - * cogl/cogl-sections.txt: - Add missing cogl_path_arc - -2008-06-06 Emmanuele Bassi <ebassi@openedhand.com> - - Bug #927 - Created ports for clutter, clutter-cairo in macports - - * clutter/clutter-docs.sgml: Update the OSX build instructions - and mention that the preferred way to build Clutter for developing - applications is via MacPorts. (#927, Idan Gazit) - -2008-05-15 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter/clutter-sections.txt: Update with new symbols. - -2008-05-09 Neil Roberts <neil@o-hand.com> - - * clutter/clutter-sections.txt: Added - clutter_threads_add_frame_source, - clutter_threads_add_frame_source_full, clutter_frame_source_add - and clutter_frame_source_add_full. - -2008-04-29 Neil Roberts <neil@o-hand.com> - - * cogl/cogl-sections.txt: Added cogl_shader_ref, - cogl_shader_unref, cogl_is_shader, cogl_program_ref, - cogl_program_unref, cogl_is_program and cogl_is_offscreen. - -2008-04-29 Øyvind Kolås <pippin@o-hand.com> - - * cogl/cogl-sections.txt: updated after cogl primitives api rename - session. - -2008-04-28 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter/clutter-docs.sgml: Add index for the 0.8 symbols. - - * clutter/Makefile.am: - * cogl/Makefile.am: Revert back, as EXTRA_DIST has been defined - by gtk-doc.make and automake-1.9 complains loudly about a - redefinition of EXTRA_DIST. - -2008-04-22 Øyvind Kolås <pippin@o-hand.com> - - * clutter/Makefile.am: - * cogl/Makefile.am: s/EXTRA_DIST +=/EXTRA_DIST =/ since newer automake - is more stringent and EXTRA_DIST has not been defined earlier. - -2008-04-21 Neil Roberts <neil@o-hand.com> - - * cogl/cogl-sections.txt: Added CoglTextureVertex, - cogl_texture_can_polygon and cogl_texture_polygon. - -2008-04-18 Emmanuele Bassi <ebassi@openedhand.com> - - * cogl/cogl-docs.sgml: Fill out and add an "about" section. - - * cogl/cogl-sections.txt: Remove unused/redundant stuff, - divide into logical subsections and in general make the - documentation more structured. - - * cogl/Makefile.am: Ignore some private header files. - -2008-04-18 Emmanuele Bassi <ebassi@openedhand.com> - - * cogl/: Add COGL documentation. - - * Makefile.am: Add cogl/ to the list of SUBDIRS. - -2008-04-18 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter/: - * *: Moved everything into the clutter/ subdirectory, to make - room for the COGL API reference. - -2008-04-07 Neil Roberts <neil@o-hand.com> - - * clutter-sections.txt: Removed clutter_texture_new_from_pixbuf - and clutter_texture_{get,set}_pixbuf. Added - clutter_texture_{set,new}_from_file. - -2008-04-03 Neil Roberts <neil@o-hand.com> - - * clutter-sections.txt: Removed ClutterTexture functions that are - no longer neccessary to implement ClutterCloneTexture because of - the new COGL texture API. Added - clutter_texture_{get,set}_filter_quality and - clutter_texture_get_cogl_texture. - -2008-03-30 Neil Roberts <neil@o-hand.com> - - * clutter-sections.txt: Added clutter_win32_get_stage_from_window - -2008-03-26 Neil Roberts <neil@o-hand.com> - - * clutter-sections.txt: Added a section for the Win32 specific - API. - - * clutter-docs.sgml: Added comments about the Win32 backend. - - * Makefile.am: Added bits to ignore the headers for the Win32 - backend. - -2008-03-18 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-section.txt: Update after API change in ClutterScore. - -2008-03-18 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-section.txt: Add new score API. - -2008-03-18 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-section.txt: Add timeline-marker API. - -2008-03-07 Øyvind Kolås <pippin@o-hand.com> - - * Makefile.am: Ignore clutter-id-pool.h to avoid picking up - private symbols. - -2008-02-18 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-docs.sgml: Add building instructions for OSX - -2008-02-18 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-animation.sgml: Fix warning - - * creating-your-own-behaviours.sgml: Add a paragraph about - setting an initial state on the actors. - -2008-02-15 Matthew Allum <mallum@openedhand.com> - - * clutter-docs.sgml: - Minor tweakery. - -2008-02-15 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Fix ClutterMedia section. - -2008-02-15 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-docs.sgml: Move ClutterStage from the base actors - to the container actors section. - -2008-02-15 Tomas Frydrych <tf@openedhand.com> - - * clutter-docs.sgml: - Build instructions for Linux and Windows. - -2008-02-15 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-animation.sgml: Fix the animations documentation. - -2008-02-15 Chris Lord <chris@openedhand.com> - - * clutter-docs.sgml: Fix documentation. - -2008-02-15 Matthew Allum <mallum@openedhand.com> - - * clutter-docs.sgml: - Overhaul the overview. - -2008-02-15 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-animation.sgml: Fix some of the grammar; add a timeout-based - animation example. - - * creating-your-own-behaviours.sgml: Fix some of the linking. - - * subclassing-ClutterActor.sgml: Remove the FIXMEs; add the initial - structure of a section about containers. - -2008-02-15 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-docs.sgml: Fix varlistentry usage. - -2008-02-15 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Add last-minute API additions. - - * subclassing-ClutterActor.sgml: Fix some of the notes; the - Container implementation will need its own section. - -2008-02-14 Matthew Allum <mallum@openedhand.com> - - * clutter-animation.sgml: - Add new animation docs. Needs work. - -2008-02-13 Matthew Allum <mallum@openedhand.com> - - * Makefile.am: - * clutter-docs.sgml: - Add new appendix + FIXME for building - * creating-your-own-behaviours.sgml: - Add new initial doc on custom behaviour creation. - * subclassing-ClutterActor.sgml: - Add FIXME notes. - -2008-02-08 Emmanuele Bassi <ebassi@openedhand.com> - - * actor-box.png: - * Makefile.am: Add actor-box.png. - -2008-02-08 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-docs.sgml: Add dependencies inside the overview. - -2008-02-08 Emmanuele Bassi <ebassi@openedhand.com> - - * Makefile.am: - * alpha-func.png: - * event-flow.png: More figures. alpha-func.png is a graph - showing the flow of some alpha functions; event-flow.png maps - the path of an event coming from the underlying windowing - system into Clutter and through the entire library. - -2008-02-08 Emmanuele Bassi <ebassi@openedhand.com> - - * path-alpha-func.png: Image showing the effects of different - alpha functions on the same path behaviour. - - * Makefile.am: Add fixxref options. - -2008-02-04 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Add: - - clutter_actor_move_anchor_point - clutter_actor_move_anchor_point_from_gravity - clutter_actor_set_shader - clutter_actor_get_shader - clutter_actor_move_anchor_pointu - clutter_texture_new_from_actor - clutter_entry_set_cursor_position - clutter_entry_get_cursor_position - - Remove: - - clutter_actor_apply_shader - clutter_behaviour_scale_set_gravity - clutter_behaviour_scale_get_gravity - clutter_entry_set_position - clutter_entry_get_position - -2008-01-21 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Add ClutterBehaviourDepth properties - accessors. - -2008-01-18 Emmanuele Bassi <ebassi@openedhand.com> - - * subclassing-ClutterActor.sgml: Fix up the wording and the - examples a bit; add a paragraph about the ClutterActor::pick() - virtual method. - -2008-01-18 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Add the new ClutterBehaviourOpacity - accessors. - -2008-01-17 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Add the new ClutterBehaviourScale setters. - -2008-01-14 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Add clutter_model_insertv() - -2008-01-09 Emmanuele Bassi <ebassi@openedhand.com> - - * Makefile.am: Add clutter-model-private.h - - * clutter-docs.sgml: - * clutter-sections.txt: - * clutter.types: Rename ClutterModelDefault into ClutterListModel - -2008-01-07 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Remove symbols of the ClutterModelDefault - iterator class. - -2008-01-07 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Remove clutter_model_append_value() - and clutter_model_prepend_value(), and add clutter_model_appendv() - and clutter_model_prependv(). - -2008-01-04 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Add clutter_actor_move_byu() - -2007-12-24 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Add the units-based clip accessors - -2007-12-21 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Add clutter_group_add() and - clutter_stage_add() convenience macros. - -2007-12-21 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Add clutter_texture_set_area_from_rgb_data() - -2007-12-15 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Move the shorthand fixed point macros - in the private section - -2007-12-15 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Added all the unused symbols. - -2007-12-14 Emmanuele Bassi <ebassi@openedhand.com> - - * Makefile.am: - * clutter-docs.sgml: - * clutter-sections.txt: - * clutter.types: Update for ClutterModel changes. - -2007-12-10 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Add the new ClutterModel API. - -2007-12-10 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-docs.sgml: Add ClutterShader... - - * clutter.types: ... and its type function. - -2007-12-04 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter.types: - * clutter-docs.sgml: - * clutter-sections.txt: Fix ClutterScore symbols. - -2007-11-30 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Update with the newly added API. - -2007-11-28 Tomas Frydrych <tf@openedhand.com> - - * clutter-sections.txt: added new CLUTTER_UNITS_FROM_* macros. - -2007-11-28 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Documentation fixes. - - * clutter.types: Remove layout and boxes types. - -2007-11-28 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Add the new ClutterEffectTemplate::construct - method. - -2007-11-23 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-docs.sgml: Shuffle around non-actor classes. - -2007-11-23 Emmanuele Bassi <ebassi@openedhand.com> - - * subclassing-ClutterActor.sgml: Mention the chain-up needed when - overriding the request_coords() vfunc of ClutterActor. - -2007-11-23 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Add unused API. - -2007-11-21 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Add the new ClutterStage fog API. - -2007-11-19 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Add ClutterScore symbols and - ClutterLabel:justify accessors. - -2007-11-19 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Remove clutter_behaviour_bspline_append() and - add the new motion events settings API. - -2007-11-18 Emmanuele Bassi <ebassi@openedhand.com> - - * Makefile.am: Add clutter-x11.h to the headers scanned. - - * clutter-sections.txt: Update with the newly added and removed - symbols. - -2007-11-15 Emmanuele Bassi <ebassi@openedhand.com> - - * Makefile.am: Ignore the OSX backend subdirectory and - scan the clutter-x11.h header - - * clutter-docs.sgml: - * clutter-sections.txt: Update. - -2007-11-15 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Add new ClutterTimeline API - -2007-11-15 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Add new ClutterEffectTemplate constructor. - -2007-11-15 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Add new ClutterScript signal connection - functions. - -2007-11-15 Neil J. Patel <njp@o-hand.com> - - * clutter-sections.txt: - Fix typo. - -2007-11-15 Neil J. Patel <njp@o-hand.com> - - * clutter-docs.sgml: - * clutter-sections.txt: - * clutter.types: - Added support for ClutterModel. - -2007-11-14 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Update with the ClutterScriptable changes - and add clutter_get_script_id(). - -2007-10-28 Matthew Allum <mallum@openedhand.com> - - * clutter-animation.sgml: - Fix missing func param (#583) - -2007-10-25 Emmanuele Bassi <ebassi@openedhand.com> - - * Makefile.am: Ignore clutter-json.h header. - -2007-10-25 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter.types: - * clutter-sections.txt: - * clutter-docs.sgml: Add new ClutterScriptable API. - -2007-10-18 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Add new ClutterScript API. - -2007-10-10 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Add new API and rearrange the subsections. - -2007-10-10 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter.types: - * Makefile.am: Add ClutterScript and ignore clutter-script-private.h - to avoid picking up private symbols. - -2007-08-21 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Move ClutterStage and ClutterStageClass - symbols in the right section. - -2007-08-20 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Move ClutterTimeline and ClutterTimelineClass - symbols in the right section. - -2007-08-15 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Add clutter_effect_depth(). - -2007-08-14 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Rename raise() and lower() methods of - ClutterContainer. - -2007-08-13 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Add the new ClutterContainer methods. - - * clutter-docs.sgml: Generate the index for the symbols added - in the 0.5/0.6 cycle. - -2007-08-08 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Add the new clutter_threads_* API. - -2007-08-07 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Shuffle around a bit the symbols. - -2007-08-06 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Update with the new ClutterBox API. - -2007-08-04 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-docs.sgml: Add autogeneration of the per-version - indexes of symbols, plus the index of deprecated symbols. - -2007-08-01 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Add clutter_actot_get_r[xyz]ang() - functions. - -2007-07-31 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Update ClutterBackend API. - -2007-07-30 Matthew Allum <mallum@openedhand.com> - - * clutter-animation.sgml: - Note on ClutterEffects - -2007-07-28 Emmanuele Bassi <ebasso@openedhand.com> - - * clutter-sections.txt: Add new ClutterBehaviourEllipse - and ClutterStage API. - -2007-07-26 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Add new symbols. - -2007-07-26 Matthew Allum <mallum@openedhand.com> - - * Makefile.am: - * clutter-animation.sgml: - * clutter-docs.sgml: - An initial shot at some general animation documentation. - Needs some love. - -2007-07-25 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Rename clutter_behaviour_clear() to - clutter_behaviour_remove_all(). - -2007-07-24 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Add new rotate behaviour methods. - -2007-07-24 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Add undocumented symbols - -2007-07-09 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter.types: - * clutter-docs.sgml: - * clutter-sections.txt: Add ClutterBehaviourDepth. - -2007-07-04 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-docs.sgml: Remove partintro, as it messes up with - devhelp books. - - * clutter-sections.txt: Update functions. - -2007-07-04 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-docs.sgml: Use the right include file for the - effects section. - -2007-06-16 Emmanuele Bassi <ebassi@openedhand.com> - - * subclassing-ClutterActor.sgml: Add a chapter about how to - correctly subclass the actor base class. - - * clutter-docs.sgml: Include the new chapter about subclassing - ClutterActor; add a description for some of the API reference - parts. - -2007-06-14 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: - * clutter.types: - * clutter-docs.sgml: Add ClutterBox and subclasses. Rework - the layout of the API reference, now that we have fairly more - classes. - -2007-06-09 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Add ClutterTimeoutPool API. - -2007-06-07 Emmanuele Bassi <ebassi@openedhand.com> - - * tmpl/*.sgml: Remove from revision control the templates: - everything is now documented from within the source code. - - * clutter-sections.txt: Add missing titles. - -2007-06-07 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter.types: - * clutter-sections.txt: - * clutter-docs.sgml: Add ClutterLayout API. - -2007-06-07 Emmanuele Bassi <ebassi@o-hand.com> - - * clutter-sections.txt: Add new ClutterTimeline API. - -2007-06-01 Neil J. Patel <njp@o-hand.com> - - * clutter-sections.txt: - * tmpl/clutter-entry.sgml: - updated for new functions. - -2007-06-01 Neil J. Patel <njp@o-hand.com> - - * clutter-sections.txt: - * tmpl/clutter-entry.sgml: - Added new functions. - -2007-06-01 Neil J. Patel <njp@o-hand.com> - * clutter.types: - * tmpl/clutter-entry.sgml: - Updated for new signals/properties. - -2007-06-01 Neil J. Patel <njp@o-hand.com> - - * clutter-sections.txt: - * tmpl/clutter-entry.sgml: - Updated for new functions. - -2007-06-01 Tomas Frydrych <tf@openedhand.com> - - * tmpl/clutter-alpha.sgml: - * tmpl/clutter-fixed.sgml: - * tmpl/clutter-units.sgml: - * tmpl/clutter-behaviour-rotate.sgml: - * tmpl/clutter-behaviour-bspline.sgml: - * tmpl/clutter-behaviour-ellipse.sgml: - Updated templates. - -2007-05-31 Neil J Patel <njp@o-hand.com> - - * clutter-docs.sgml: - * clutter-sections.txt: - * tmpl/clutter-entry.sgml: - Added ClutterEntry - -2007-05-31 Tomas Frydrych <tf@openedhand.com> - - * tmpl/clutter-behaviour-ellipse.sgml: - Updated template. - -2007-05-31 Tomas Frydrych <tf@openedhand.com> - - * clutter.types: - Added clutter_vertices_get_type. - -2007-05-30 Tomas Frydrych <tf@openedhand.com> - - * clutter.types: - removed clutter_smoothstep_get_type. - - * tmpl/clutter-alpha.sgml: - * tmpl/clutter-actor.sgml: - * tmpl/clutter-media.sgml: - Updated templates. - -2007-05-22 Tomas Frydrych <tf@openedhand.com> - - * clutter-sections.txt: - * clutter-docs.sgml: - * tmpl/clutter-units.sgml: - Added clutter-units. - - * tmpl/clutter-alpha.sgml: - * tmpl/clutter-actor.sgml: - * tmpl/clutter-media.sgml: - * tmpl/clutter-behaviour-ellipse.sgml: - Updated templates. - -2007-05-17 Emmanuele Bassi <ebassi@openedhand.com> - - * Makefile.am: Ignore the sdl backend. - - * clutter-sections.txt: Add undocumented symbols. - -2007-05-16 Emmanuele Bassi <ebassi@openedhand.com> - - * Makefile.am: Use the newly added clutter_base_init() function - when scanning the library for documentation. - -2007-04-16 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-docs.sgml: - * clutter-sections.txt: - * clutter.types: Add new b-spline and rotate behaviours - to the API documentation. - -2007-03-27 Emmanuele Bassi <ebassi@openedhand.com> - - * Makefile.am: Ignore clutter/cogl: it's private API. - - * clutter-sections.txt: Remove the now private ClutterBackend - API; add the ClutterPerspective API. - -2007-03-25 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Add clutter_get_default_backend(). - -2007-03-23 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Remove duplicae symbol. - -2007-03-22 Emmanuele Bassi <ebassi@openedhand.com> - - * Makefile.am: Include the clutter-glx backend API. - -2007-03-22 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Update with the backend and API - changes - - * Makefile.am: Don't check into the backend subdirs. - -2007-01-18 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Add forgotten ClutterGroup API. - -2007-01-18 Matthew Allum <mallum@openedhand.com> - - * clutter-docs.sgml: - Update overview. - -2007-01-18 Tomas Frydrych <tf@openedhand.com> - - * clutter-docs.sgml: added clutter-fixed - * tmpl/clutter-fixed.sgml: added intro to fixed point math - -2007-01-18 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Remove old cruft. - - * clutter-docs.sgml: Add index of symbols. - - * tmpl/clutter-fixed.sgml: Fix doc template. - -2007-01-16 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Remove clutter_vblank_method(): it's - private. - -2007-01-16 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Update. - - * tmpl/*.sgml: Update templates. - -2006-12-13 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Update; add clutter_color_equal(). - - * tmpl/clutter-color.sgml: Update template. - -2006-12-13 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Update. - - * tmpl/*.sgml: Update the templates. - -2006-12-04 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Update with the newly added API. - - * tmpl/clutter-event.sgml: - * tmpl/clutter-fixed.sgml: Provide short and long descriptions. - - * tmpl/clutter-actor.sgml: - * tmpl/clutter-alpha.sgml: - * tmpl/clutter-behaviour-path.sgml: - * tmpl/clutter-behaviour-scale.sgml: - * tmpl/clutter-color.sgml: - * tmpl/clutter-feature.sgml: - * tmpl/clutter-main.sgml: Update templates. - -2006-11-20 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Remove debug macros; add clutter-version - section. - - * Makefile.am: Ignore the stamp files. - - * clutter-docs.sgml: Add a link to the version utils. - - * tmpl/clutter-actor.sgml: - * tmpl/clutter-main.sgml: - * tmpl/clutter-version.sgml: Update templates. - -2006-11-17 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Move stuff around: get_type and Private - stuff go in the Private subsection; remove private symbols like - pango stuff and the enum gtype signatures; remove cruft. - - * Makefile.am: Add more private files. - - * tmpl/clutter-fixed.sgml: - * tmpl/clutter-feature.sgml: - * tmpl/clutter-actor.sgml: - * tmpl/clutter-media.sgml: - * tmpl/clutter-behaviour-opacity.sgml: - * tmpl/clutter-behaviour-path.sgml: - * tmpl/clutter-behaviour-scale.sgml: - * tmpl/clutter-behaviour.sgml: - * tmpl/clutter-alpha.sgml: Add templates. - - * tmpl/clutter-0.0-unused.sgml: - * tmpl/clutter.sgml: - * tmpl/clutter-enum-types.sgml: - * tmpl/clutter-element.sgml: Remove old templates. - -2006-11-15 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: - * tmpl/*.sgml: Update with the latest API changes. - -2006-09-14 Emmanuele Bassi <ebassi@openedhand.com> - - D tmpl/clutter-video-texture.sgml - - * clutter-sections.txt: - * clutter.types: Remove ClutterVideoTexture. - -2006-08-30 Jorn Baayen <jorn@openedhand.com> - - * Makefile.am: - -2006-07-06 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Add clutter_actor_has_clip() and - clutter_actor_unparent(). - -2006-06-22 Matthew Allum <mallum@openedhand.com> - - reviewed by: <delete if not using a buddy> - - * tmpl/clutter-main.sgml: - -2006-06-22 Iain Holmes <iain@openedhand.com> - - * clutter-sections.txt: Remove clutter_util_can_create_texture - -2006-06-22 Ross Burton <ross@openedhand.com> - - * tmp/*.sgml: - Add lots of "no public members" and document some signals. - -2006-06-22 Iain Holmes <iain@openedhand.com> - - * clutter-sections.txt: Move _get_type to private sections - -2006-06-22 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-sections.txt: Add clutter_timeline_get_loop(). - - * Makefile.am: Add clutter-marshal.h to the ignored header - files. - -2006-06-22 Emmanuele Bassi <ebassi@openedhand.com> - - * clutter-docs.sgml: Fix typos. - -2006-06-22 Ross Burton <ross@openedhand.com> - - * tmpl/clutter-group.sgml: - Fix braindead source parser. - -2006-06-22 Ross Burton <ross@openedhand.com> - - * clutter.sections.txt: - * clutter-sections.txt: - Rename . to -, and add missing class members. - - * tmpl/*: - Resync - -2006-06-22 Matthew Allum <mallum@openedhand.com> - - * clutter-docs.sgml: - Add copyright info. - -2006-06-22 Matthew Allum <mallum@openedhand.com> - - * clutter-docs.sgml: - Add overview text. - -2006-06-22 Matthew Allum <mallum@openedhand.com> - - * Makefile.am: - * clutter-0.0-sections.txt: - * clutter-docs.sgml: - * clutter.sections.txt: - * clutter.types: - * tmpl/clutter-0.0-unused.sgml: - * tmpl/clutter-clone-texture.sgml: - * tmpl/clutter-color.sgml: - * tmpl/clutter-event.sgml: - * tmpl/clutter-group.sgml: - * tmpl/clutter-keysyms.sgml: - * tmpl/clutter-label.sgml: - * tmpl/clutter-main.sgml: - * tmpl/clutter-marshal.sgml: - * tmpl/clutter-rectangle.sgml: - * tmpl/clutter-stage.sgml: - * tmpl/clutter-texture.sgml: - * tmpl/clutter-timeline.sgml: - * tmpl/clutter-util.sgml: - * tmpl/clutter-video-texture.sgml: - Rejig a little and sync up with latest source. - -2006-06-13 Matthew Allum <mallum@openedhand.com> - - * ChangeLog: - * clutter-0.0-sections.txt: - * clutter.types: - * tmpl/clutter-0.0-unused.sgml: - * tmpl/clutter-enum-types.sgml: - * tmpl/clutter-group.sgml: - * tmpl/clutter-main.sgml: - * tmpl/clutter-stage.sgml: - * tmpl/clutter-video-texture.sgml: - rename element -> actor - -2006-05-26 Emmanuele Bassi <ebassi@openedhand.com> - - A clutter-0.0-sections.txt - - * clutter-0.0-sections.txt: Add the -section file: every method - signature should go in this file in order to let gtk-doc pick - it up when building the template for it. - -2006-05-26 Emmanuele Bassi <ebassi@openedhand.com> - - A tmpl - A tmpl/*.sgml - - * tmpl/*.sgml: Add gtk-doc templates. - -2006-05-26 Emmanuele Bassi <ebassi@openedhand.com> - - * *: Initial entry. - diff --git a/doc/reference/clutter/Makefile.am b/doc/reference/clutter/Makefile.am deleted file mode 100644 index 9fe7da31e..000000000 --- a/doc/reference/clutter/Makefile.am +++ /dev/null @@ -1,153 +0,0 @@ -DOC_MODULE = clutter -DOC_MAIN_SGML_FILE = $(DOC_MODULE)-docs.xml -DOC_SOURCE_DIR = $(top_srcdir)/clutter/clutter - -SCANGOBJ_OPTIONS = -SCAN_OPTIONS = -MKDB_OPTIONS = --xml-mode --output-format=xml --name-space=muffin-clutter -MKTMPL_OPTIONS = -FIXXREF_OPTIONS = \ - --extra-dir=$(GLIB_PREFIX)/share/gtk-doc/html/glib \ - --extra-dir=$(GLIB_PREFIX)/share/gtk-doc/html/gobject \ - --extra-dir=$(CAIRO_PREFIX)/share/gtk-doc/html/cairo \ - --extra-dir=$(PANGO_PREFIX)/share/gtk-doc/html/pango \ - --extra-dir=$(GDK_PREFIX)/share/gtk-doc/html/gdk \ - --extra-dir=$(ATK_PREFIX)/share/gtk-doc/html/atk \ - --extra-dir=../cogl/html - -BUILT_HFILES = \ - clutter-enum-types.h \ - clutter-version.h \ - clutter-marshal.h - -HFILE_GLOB = \ - $(top_srcdir)/clutter/clutter/*.h \ - $(top_builddir)/clutter/clutter/*.h \ - $(top_srcdir)/clutter/clutter/deprecated/*.h \ - $(top_srcdir)/clutter/clutter/x11/clutter-x11.h \ - $(top_srcdir)/clutter/clutter/x11/clutter-x11-texture-pixmap.h \ - $(top_srcdir)/clutter/clutter/egl/clutter-egl.h \ - $(top_srcdir)/clutter/clutter/wayland/clutter-wayland-compositor.h \ - $(top_srcdir)/clutter/clutter/cally/*.h - -CFILE_GLOB = \ - $(top_srcdir)/clutter/clutter/*.c \ - $(top_srcdir)/clutter/clutter/cally/*.c \ - $(top_srcdir)/clutter/clutter/cogl/*.c \ - $(top_srcdir)/clutter/clutter/x11/*.c \ - $(top_srcdir)/clutter/clutter/egl/*.c \ - $(top_srcdir)/clutter/clutter/wayland/*.c \ - $(top_srcdir)/clutter/clutter/deprecated/*.c - -IGNORE_HFILES = \ - config.h \ - clutter.h \ - clutter-actor-meta-private.h \ - clutter-actor-private.h \ - clutter-backend-private.h \ - clutter-bezier.h \ - clutter-cogl-compat.h \ - clutter-color-static.h \ - clutter-config.h \ - clutter-constraint-private.h \ - clutter-debug.h \ - clutter-deprecated.h \ - clutter-device-manager-private.h \ - clutter-easing.h \ - clutter-enum-types.h \ - clutter-event-translator.h \ - clutter-flatten-effect.h \ - clutter-gesture-action-private.h \ - clutter-id-pool.h \ - clutter-keysyms.h \ - clutter-keysyms-compat.h \ - clutter-keysyms-table.h \ - clutter-marshal.h \ - clutter-master-clock-default.h \ - clutter-master-clock.h \ - clutter-model-private.h \ - clutter-paint-node-private.h \ - clutter-paint-volume-private.h \ - clutter-private.h \ - clutter-script-private.h \ - clutter-settings-private.h \ - clutter-stage-manager-private.h \ - clutter-stage-private.h \ - clutter-stage-window.h \ - clutter-timeout-interval.h \ - cally-actor-private.h \ - cogl \ - egl \ - evdev \ - tslib \ - x11 \ - wayland - -EXTRA_HFILES = \ - $(top_srcdir)/clutter/clutter/x11/clutter-x11.h \ - $(top_srcdir)/clutter/clutter/x11/clutter-x11-texture-pixmap.h \ - $(top_srcdir)/clutter/clutter/egl/clutter-egl.h \ - $(top_srcdir)/clutter/clutter/wayland/clutter-wayland-compositor.h - -HTML_IMAGES = \ - actor-box.png \ - actor-example.png \ - animator-key-frames.png \ - bin-layout.png \ - box-layout.png \ - constraints-example.png \ - easing-modes.png \ - event-flow.png \ - flow-layout.png \ - path-alpha-func.png \ - offscreen-redirect.png \ - table-layout.png - -SVG_IMAGES = \ - animator-key-frames.svg \ - easing-modes.svg - -content_files = \ - glossary.xml \ - clutter-overview.xml \ - building-clutter.xml \ - running-clutter.xml \ - migrating-ClutterAnimation.xml \ - migrating-ClutterBehaviour.xml \ - migrating-ClutterEffect.xml \ - migrating-ClutterPath.xml - -expand_content_files = \ - glossary.xml \ - clutter-overview.xml \ - building-clutter.xml \ - running-clutter.xml \ - migrating-ClutterAnimation.xml \ - migrating-ClutterBehaviour.xml \ - migrating-ClutterEffect.xml \ - migrating-ClutterPath.xml - -GTKDOC_CFLAGS = -I$(top_srcdir) \ - -I$(top_builddir) \ - -DCLUTTER_DISABLE_DEPRECATION_WARNINGS \ - -DCLUTTER_ENABLE_COMPOSITOR_API \ - -DCLUTTER_ENABLE_EXPERIMENTAL_API \ - $(CLUTTER_CFLAGS) -GTKDOC_LIBS = $(top_builddir)/clutter/clutter/libmuffin-clutter-0.la $(CLUTTER_LIBS) - -include $(top_srcdir)/gtk-doc.make - -EXTRA_DIST += clutter.types -EXTRA_DIST += $(HTML_IMAGES) $(SVG_IMAGES) - -DISTCLEANFILES = $(DOC_MODULE).types $(DOC_MODULE)-sections.txt - -if ENABLE_GTK_DOC -TESTS_ENVIRONMENT = \ - DOC_MODULE=$(DOC_MODULE) \ - DOC_MAIN_SGML_FILE=$(DOC_MAIN_SGML_FILE) \ - SRCDIR=$(abs_srcdir) \ - BUILDDIR=$(abs_builddir) - -#TESTS = $(GTKDOC_CHECK) -endif diff --git a/doc/reference/clutter/actor-box.png b/doc/reference/clutter/actor-box.png deleted file mode 100644 index eb957b6eb18a37ba3f61422220cee491019817ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17917 zcmdVCbx>SE*FHG-00Rt8a7Y3KcL=T#9D=(9cXxLP5E3LL!Gne1?hXm=?h^vRCAe+# zzTa+b)z<D-?O*$&iel!{x9xVH^E~G~x1&{*UgBVpV?iJgoY${p)F2R~VDS45iVm*K z2&QF&Kd7!!uhpU8#}E283Vg?OdZptEfnY~J{2~eb8Ylr5AGyhDyS;I=aPu^AF^711 zda_$P*t(jTIGM9Mx>$bM7a@m0Xd$m<B-OpX?k#zj>uZ^?UpekIMDpNO{^@v3jkJJD zu?vwTd7^*(sxa)(0Uf!lo+FtkAzQ8P0~Vb-O0piQCDUDyx?yMT2f-(#Qk`g&ctJyG z1747YS?$@BQDdF)wCk@KXXVpAfxG+DX;0F{M0fYA+KiIr)H21Ec36wf>t<N1r?vau z*67~yKq4vo(okuqeF^aKPkE_OJBWg=MMkd6Ao-f&l0OKM9bqA>6p?r|XBmFSuYD~n z&`F_K^z_>%QqXq^35Y*m9C00+_G-T)1jX@In^-ccwvpR-pdmE=cPE)N&jW6}1P0_} zWT>hgSHzkR{13i(Qf{I{3U(4G1~L$u#Z%V@O$V)#=n(v|X_uP|=S9yI|IjI$(*TIW z?a>RUI&<<!^I<182DSHZe4a!C0({k%qQ^fU|H0;HcFIyK^2@)|7DeUGw{AUWF}jRN zRhf&5D#UI*PA>BT*GMJM1!<7mymn`~G)go-vOL1ach|4c?Wr*9BMLG?wV_jCP7XMz z=%c21RsB{*W|BBT^lVn5Nc~Eb7B~3y1h3I;CpO0ueO55q2vS2YBv2)J`!}Rj(s;_} z$j{8jH|Xhe*x#$I|4e)gImC`gI&PnwRA=}rg^#a#uAr!B{w)auwsKy^N`$pY5)#EE zixnPn=zlLKZQJ5#VnX-#7>=(>%ErnnVcRmo2{Y?kUpF1!paWIv>g$J@kO{*UYWuLm zrT%-3nFy=g-gl7`)`i=}`QKZ^O`u(zb|@k&K~YR4Va|Uy;rL^kJ#bojIj#r@zG@5? zYE+ckJ30xOBvTj?eGZWs6po)qCJjpWkRi*+JnQ}canXfiIu%?TA{3s#rr*?_!<nx1 z?%K#yjTVkGN4pq#F8++^kN3RFJ81jbh4RBUC!=-)3@eKLzk}5*Sji$H`^27B7=~Pn z32P+y=#3^(=4HsmS^k^i)6W->ptP8{@R;D{;&L<EFuLi$TT^4>R=X@RGACAJRu-<^ zU+$TD(J+NnR(0v%M1`>E#jBBzSfD=be{9+jomQG9*Pl0INGJ)(e#vMb;|!*-T@cj! zh|H=iePz)dh0mrW&}vTgx%~>8L}zd%y_@66BZ3Yl*(ag2^P{1QM*sTSJ>N*GeLVES ze=tdbRbBBnWpsKdLB!}zv(JtH2{E>;QF}$um_k_MJKgh!WEJDax7h@k?<|NIT*ewl z-spnwIVya{kDQlE&p|&J>`=&t<cLrRd7h$7y;}VoEkD!3f%d1L0bM`5x$3NjCA(c} zs=K`4eZ|bZcT{amd_?=n1a*cO0(sO)Ax@$fC*epxOkkg_t7_OtUx{7N>(7r^;j`qU zP%V)p6clpupmwVl>q8iF<wGYUTI3gFI(RShsjQ&&`7daZaDw$bG@W{8`(r!)%2KQd zCk96Zm9`8fn~6Cr>lhq0hkuWLsr0sd>r1(Ugd7e|FiI|+VN)*5R%hXFBB2h<@=5Im zn~3XlIK=of1zs>HP1Cx*Hvfy+p?T0zB;dR8nlGbEy&rG4`K6O|S<QT+HK}s?5d;!n zG(6+a-$`+nl2|b^vr!ZhS}@|}g=po@@ad6$7L{3y^zQAGWxp(_<=kxJcze~Rh=_Pi z?Y`r(YDaQ$z?~Keo8P&NhwPG(*fwI?fMusuh41L+FBsO8?h=cHt?~V<s4t$H#*a1! zZhrn^jS!8qzl4u`J*9<^NjWm1Dj@kCyv0T6L<{V3lwMvX40{XmTOz1tlGrbGWo}Dz z>E3%j*`L+wG)E!GA7zR}R~ppwy0SwT7y8ms($sI;x_Mnt>2-RBb%u*kD1$trZ0_VX z+?)7_RKQL+aLnuMYwTu$!7c@+^TZi5cS^|k(Nayr_V82!YQRNIY#k+&87m{#8}7r& zG??L6_X<lvyG0}xoSOrL&P8H7n2-uvrjR6Z<@D3T@gLYT|C}byl1WSFD#LA_IL#zK zedmS$eXQ4Up^W;ROQZVmCMnY1JKFvdn%CZr;MnB+{kqx1GB0i0knVuF+1U|u0mIgv z2Ktp%&};i$q~);1Ay3mx@iok_WvQ<<5i+H++BZQRKRhqUy;lk?+8l1UI7*6b>7sL( zH<X;7Rw4hyJZGzm6HIi`!Sbm2QsNP!rZMnJ0sZBs{w_r{IU8~b+THmP>-WT9f!z}0 z85QU=z6`O{j#wUCefhO1+wEl;J_126S^V5b;oDbnv3#u3W-CrXsTTG`xAiqTq;jjj zL*nec!5R;cPqbqByY;DkKN~KLk=rZ#+?J);hP&O0q4NlhqJ19wPp~Qt#tW2B=<hvw zLFa-YP9A^#43njUA5T!f;Kny>YYKTs92kXzWJeRlnPzmkra@kBZi$9ys9!LrXQc3a zH(+#LaDpor9Bj+zze|lpmt~UH&L->+vm`S7<WAu^>8^%UcTi-^ODGBbQQx&3l{sf1 z*{dn&#~mwYwVL?x5fjd0Ye6%^;O7ck&hFA|bN2%)eV#Ql5f*3DjtIlD{g=r4V%uFr z<j-HOO{HqkW;t8vP-#3y8BuN``}JzEmJt_1TY5ckOvj+*eqzPuG*HUSkTP{UMR?TX zXTG$+gpO{=r`ofhouzs%a8PK>n|s*#u8P6<ah~(SK0$9Kfz($1_FarBO;G#TbITqC zBZ<C@-0HDv;H~46c~c=V2Dsd6a^A)I_Df`Pa;a|85f{i?tpM~2f8!0=ZZ5tT+*li{ zH)zJKrjpjH?N(7!w+lO5sO9#?=A3o|eFtx%htFLHHP*Lh1u7e{Uzi;@1%ci8sSIj2 zka;gRoJiK#PS*WGFu!xpcL3OJk$r!<NC|SUrBd#Q=IQI4$4{Mn#!9DdFF&i1GoeY` z5x6^kA%CnB?o!?yufW7s9{8mF#kL{TSkJ-S-=R3%?U~5EqmWkgirK;EMvOBU#wTG! zwo1(^+Ya@BFnJd#S!jLI+Ph8}rS;k7I0}vvIvbPA@gF!d<FkC#4Gw}i0TW|zL5=dm z+c!Ega_#(l=muyDf-B;C^1-{`v40&qhX^esv5@$&T^{v3KCs&z9;umLJ{PJvLTlJ1 zSHprqe*_9-mf*lskO|u_V*`eDPA2o?ET5ji&;%=1jp-R}*QP&D#PU;%Cd)Db7>E89 z8eg<F6GJUW*xn!8YFpBh)tKKqUb(IPo$YSkYDqXh1YS%t0r?lx$T8hZ=dv^DUwUTP z)81Zdo*=NWt-E)uN|TV$zrGO?z0`$oF>n-gQOppkh}TPa`XxR*XcBoP@HvLG)lGpd z2?fnt$b;#oQTF~4uy;jkUO0dKx&{XghcI!nT#Jo6-sZrZqL?G8#2_ljOMmTcM=;%b z+VeM0Z58X}c#=rKT1BDbU3MNCkHJ1m7;f}(usLBVq~f`|6jnVy+A-~+<%OWCm3b){ z6q9a?cHswjy+GtW$7qUtOqm|b$fYmVSxPIH5Fdw0#Eedlsn7MN3<{ymAfAZn&^;fp zD{5JgoGid*SD&#!=syoALn=Fsy>kghrGB0kY->Z==z^J%=X4=sF*Ga9L-HLtk)Ym` zRo}JG(5hlT(k8T!C-3ZT=8+r1Wms!E#W8zYvCa=tM+M7vHh$9HkQ3ezqe=l!u@9ul zF`TY|bJ|W^Y8tua%aa)D*p(o0rzDdNy=vyQ%~dhDe$3R;px5pHm<}~)bNG2&(K`t6 zO@ghfV9RhWMzmgSPzOGbbunJ86+IGcxA*NYe1ROP?4vE}ba$gJl6<1JJJ05lU3q+6 zAkU!0G0&Fl$y?0%Ioio?xkoC`-@VOJkQ#P(l!V=~%a`Iu*!RZ{=1cH6?QCSa!EZ1! zsQp~&H@xU7h)dPS?T4_{=o<hZyv)aXJ>xAa*f=VFV}I3la?%m&oLm3H@dEkCE;BOV za~}!^j`4j|f~4}}_sEth3cHW6oTtz?w>boUzt(?Fy&C=q1CM&h>|6yZ9%K0)3MpGs zl@x9a+y=hE>ANvv{+EqemJc_F^DRG(xX|X>Pq%8*<?FHMcs&xU`FnS=1Bsqbfqk${ zvGdz3(6OU<&vb<z&mlOQf~WW0R|1h@pdsSM8i`@pj{y5#QkgC)s7e;QDS}>KbonOS z?dO|%ANuY@YYe>RBw&5u!Msjx?Cd+Xp6b(SBa@BIxz2MEQ9SbeBJyT4@Pcr)MmJVe z)Sw4!@h=TFOw0y=6L3h&^>tx3ZzVc{T6SM>Z!#(Tc{<4Fzu*4qMThPblE~*|uLX@* zu&^UtWhwgp;MC{$YHOBiV~TuG-NEHYIYRS1W&Jv{U)Wvp?m2~c#xa0J4GzseLOL{- zP!Z3gkvv^Vag4B<E3M2{UPV#VmNZ)#HVwUe#_MeHt8;k`{zy;SI#`a3qq<2QjtOyG z)asqE6!~hv&Gm+#>vN(PVwnK>(ah~}xR#Fa-J?DC`S7ksH5Pm)01@qJksb{`!UOm# zen{8}7GAN~pWNPMh`ONPc5SU^SW<MY<ydC?<nht?kI>BmQEdj!#8@YU`4rzs`p<s8 zrFUOyJOy!sZy#@3V&dn8zgK$^co7-+vn9oMu^}hgk!AqFh7n^sEvaIQn>qO4>5R1b zqLiwq{Et6o+L`=IY_!R?F+ErL39+hbsEq!Ijay1-Bpjubgid9|n!=xmiglM)?B1Rn zSA#|2eCk!cCK^4?tY#`*l?hOxt1Py-(2nUCsS{g`sXRdruL-nTr$gYVT|QOp)kd7J zJg}9QHIVA*arB)#9N&ST+E@!1^uVKb4ofzex=Q`$hB<A`bx{G559}|P<KE`vZwEAo zqj}5dq4oVgkq!f*8t-d!`W#K?7^_G&b(n}ia)*A8%(EywbDH5-`dr&)=bQyh1ge!} z$W(4`=R0^T5j>$ge$Sjrt=9C%Ix~9UWeXZQ6=@Xsssa_lh0;nKx?bCZ{SfUvFhd2y z^-C;7_+!klU|i_a!;6759MSVU9gK;m{6C|Z9)YW$o-Gu<peWG|eiJ^ebWKk`&$=Aq z(XQXnVCTQ~n=)SHUoviTM3h7Q8v3GB7tU+aTt+TbAzC{ZW~)L}rA(2z>~Z*5hN$lc zcBv6lPZbPaU)n|^!KLgEaC`$wJ!C4*j5u1<ECIojlTC*v60K$gp1`T06!cR*W)~-U z8$|>X9se}Bs+^=PP99MXfN2D}wp(!|t(f`NrA)cjpDEZ2rW;jjeROsL9qN28SqDPk zIe&!=42FHE3L2C?9){A~K+cza9mjjNyuo08J|~}1y6|$?9-k2Bpx|~|DDE}3bK$Bm zAv+YoOEK?orkt(C>6-OIDGPAM3W2m9<m#44J)26z4z^$T`Iehgk+5{9v$>t_A8Ae! z=u7LtV<>W%NfeXKeMpm!!SukaUHUY~RqKI3|9r7KbDj*5EVQdU*Zp%?aB%Rq*ilmO zh+LLxne*lT$QA_t(GRX$+Ty2zfQC;*W^3c@_!rckhr{7g?I$8$8Ijr9bTX=8E)9#& z2u;H#YJ~=U+?1*Lz`CoYQv1HDqU|*e=49PgFP)Td1%`?G!dhJ=$WM!^xWG)08Ef{` zQ2Pb88S9p(YmG-Zv1;E{3r-JnO5*57=^`M@F5b@#`TTl=4f${AQJsc7upI-EvCE?8 zvcc%w4c=DG<sV#pHqjwL$G|`WlVE0TT~vgfYC`sN^Q7FKqIAch-Zw`_D(Xc#M502w zdwg8&jRD7xiJAk1H?{su_%wN*8fK4ah1rr$l1PLE2BuZBP3OzgjlRRZF6EA4$F33q zgV1}oLyuXC=H*H8-BaOHiz~l{j>;dsXqC(MP8G3|xAF7NUrSS`oGE{wc+04wuAI|t zT%r6M&=WspPckf<05dfuRMOV>VkhZ}R62`=D5Qr6N-{$0I&p@B5oAK<WKcIIJ7zNx z$fGbJ!~Z3GrxDr(PnJV7A)|+N^}23{PMksxMaqiA{&^I6ioSkkvfz>XV}PUlv@~IZ zblqXWDqT0FCP%61k@_ijeJOUIGrMlV<O&(GXg{ywTkc0-hI(0(zYV-;8-1x7rdAYY zQ!~GnTY6p~9RJbk`3~ubK0C$)FMb4F{|5KBq&RGw+w~P&cU@MJwd(-0#oU1NOqmOg zx<;i?T8TV0lVamoW9YxaD=J%m_&-xazav>nVGmeeJXKdTAtOA3ZohGdol?lHaBt)L zO8N`cNocT-y!qwQ{p2JOh^dS-X%(q=f*p34jptvuXRbSP+%#)bgY|49MpJ^LXvW%q zbe0n)82?c_c3W!O-A0F`DWdlM@)a)}V*K_kYOTE^69lq~pt%<eq18T`y}9vYjG2Bv zvPt3j<J5b5z<&+fs6979tZ}`<!N_mNoScRx^5EJ&O>yFNXlN)4dca4Aq8|lf(zbqn zlsr5<an?<fZ9eCOiE57@KUP$}7V$cyJ=<T3Wht#kRu(xz-EY{;z)g0@i%mYc+9~Vf zo6!$__*aC<D&E~HUZYz6DOtqWarKD9-&B|B&@6rSTy0iv=oOiC)=TXav<Y74KZB3R zB7zN?JW8xFQ6+;W3Y5EehlqW%Z_XU=JrE<}H*0tcy6kyGN?!$$`kc#MH;3Ib->{N! ziHgQ0CgQ{J@K7MjcV~41tpV%Z(X}bjKGOaoh07bg9qV_K!c_6kG&8@5a&iWBMdBgM zXs*fb_7CnHhEBw;=SJ2azEcO@9F?Z*@nl}Y#6VMKCMG6Jn|>f_*ViX@#`RTfNc8>q z+sjVAK4+iG>lpSpy7%Q*#(Mt!t7W(IWoz5TWxcoOD+wT^=Nq@_f4#8M>)CojwdjS2 zyT~)T$}3GdvUl{Q_?C1rUDsOk#}@3P1d(H?$L?(KPH9tV@kY+_svvIVoZX6>`IsCm zm|7*13c0%~MC>>*fi`mlQI&biI-DUI3uXo3c=yMVQ$*w)p8uA#K^vm+WLP-y*W1H( z6uckS$KwA+rJ*4Z&n0&)tpS-9vrAr+ZE;v|n0H2`9e>k$r<j;n{L1apifo=*$CBqt z90)g3NWxd8X|7aqM_Lxl{U*LFhZPk)6FC{=VQD=BmA2Q~H~&?1-1ccG^qf4eGKK%6 z!G$pv-ev1J&aao$Eys8^Bd9LsXIjxA7aK-*<_}}02(YJ;h2|H~6>CV?Zq2_i?&LM8 zXaAv(+gWR3=j1$-Egk7}&~m;Wj6vP5D6oVI5p?+tRZ15M7v8Toa~0-iMk^u8F~zS` z3r-<uY{mQv=d`1+U_j||Hh#+u#~evZ%_GQB!|XptRL<zi#t98=n#}TdqZgcc$Pl{Q zSa3^x*>SV7f+ox5m6W|s?}5Kk@yFhZ^>1-FSZ+!66QznclBEgyp$=zblbqs!oH|g_ zWp%>)&*@lMT4`tb2krQm=k}334wmD<v%v*XP%^A=<cNp}r~BJ;6p0f9Njb?YvA0F2 zRI=||@eEdCjOR*|g<#ns5HLy~>Onh_2!z`yeQ_rzyCs>_m6$rbn{;Yp$@EmHB-Q;= zwpP!;Q%+K|`2B`UE-Putn}HA=_O8K=bs_tStLUrsjtxCy6-P7ZlW(p4XHvJ<BO)iT z)|(9uGhjA8WoGtmik&~#_ufeU^!2O$i9Ru^N^63ZGrnpCnYd;V?_D!BX18ZVP3(6* zPKd7)Ji>R42aZc66t<b+i@S0)UFUSTDk%aY#<LBsjHNAS^Emg5W8-T2(_pUk#R5}( ziVk=b$!cPYA8t3MZEg41qSq@^CPs~lkuBuZcjht}ITqrxaknwZQPRtI*DsI^va)_w zI)O7hmym*{+47@g+S0#nLWx83+nEXU$&=Ip11I^Q@Nl%7DWh9r%D#?+`?~|gWYL@Y z>;0yq&A_|Oi{Fgm4W<)3I_!@>rH3Ei)?cm+Qhl0so{2c<^L(F-^|hh`+k>#>?zF7$ z@Q{<*?@&@ZC7cuHe7M>X*JeP}A?{1U9P^ol5yJNLZ3Q&CUhl=F*q{QsCi~18JI+I; zX_D2|M4q{PJohb{1^wsv$phuK?(=6P3ih^}P7b&oH-3IIE5E(5bo+bbq}18FFp<el zh3x5I+m;4Se9nQZ?M_nc)nlKh$pbG_1EaxE{8mwD+V_{5oUixl5Tn`BUPnEoM+x^A z2`m{L1Lk4a*zY%vBRDjPSNfLj5AiNyH&|kmrRvLr3bmV8(dKy-n@>v|d*-Svk4Elq zMilX&J4`lWh11!7G;53ci;5G$(#mg(!kkR#T5}!DktQpJG>U6at&*q7-xG8!QmW^T zyFq^Bf7d{Db#<1{=@BY%WE_{jrXCBgcsgo+DmH<=hy8DZBk+;<)mVblX1eD(o1?cp z;^@5P!2jZxazIE~z-e*)-PMls#FW-!=G3*!=b>%a+geBeusI-*n|ZV|acXbWm4J0j zNIT#4+1h=;c@st1)4cAgmkFiUbf+Wf($&?do(ufiJFqiq5ij`tRoQ)vTwaLqLGwun zO6SVuu;*bohhO$l0K{oMS?e%cIk55QYunA%O99a(4K$>izt&bIYf4H|)h6;*I;`}} zBx}lwH8;8g2H%yw<P(MbwFV<&!`O~VJ-xlK)WRD6{Z=03XwHsg!zIlO#XpD+jI!nT z3~)%HmYMz}b;~|1Viz5Fr5B&=7cRD5ipR9w?X>j@(D=c%V0b7s`8Pk?A+-q!Mu(y= zBO^3#Zg&?cA*;PCrP}A0r|b+=vgI#dX!_X$7pG<5P7Iu`%UEfa9e-@Pu&2~Ze04IZ zg!oc_wc^{$ntgazrEx-hEfMN>-EeW?*g_Sn5(U!H!U@i>7DEGGx=)#oz7SrfaAODD z&dSwy@eYl}B>|ctCS)Qxm3>^O1WwtZ3cY=ON72fD>me(3W_`FfzcOzybEJ@_ik?l1 z>mK-=eEH&YznMT43ONka|9zcw@E9aMM0u;%r8vdK6LMcBn9h_MkW#^0H&XPRP80<? zGBX@t<sKoWLoxV0rux&0Em09aG!aLMxZh`r_;{=TwyQ}(G)f%24n29c-N}h#kBpBP zraURlq5t?j=G}E}tILPJ8@*D;cCE;~|Eqj7uhoL(%h9x(b3jOp1=U)56nGSCBtsT) zacXpb8rv2<9Tn5lJD40_G!&1SpU>}aVmFBTU9oI0sTWo{RLh?f!b*bA&Sv0}uO^=) z^|0ycY7WIt74eJe{<AilauvrKD~yYX+s-r2+m~0HodPY;gU#1y_8Tw?l+rsBAHO{O zJkyL`x9Bn;+s5(zw9NBrpS%!9@Fjky6y1KORfJm9yh_2)p{0c}4lci_fVi%14933j zqwjn|FuE@I*gE~LVyT({ER=2(gACbUhGj|{buvbQkPTm>Na9M2+IN==V9w@~^n>n) zt!H$6{kCCoj-=h^K!+7sF+!qgyZX`T{?~kI+GruRWL+$zeb)JFGGv44{^|zswCzyF z6m{|r>jJOq6#bR!%SVr^do04kk-6pgYNA;6wYR(kMjH==#qrMRmz+tjGL#geTef`J zS=*c1pA)2Zrbq;?ev+X1+wFG}*XqdQX0I2cglkxO-z(Ir=dfPd+8WZZkdv2}pHcRG zN>IIt5?Qz3Yp<O_PwtctWwHs3=NlDv34iXKq*dA~y6F)6*AG+Mm$%7{ulVP#tj;d? zp0Fe<&LqM^Vtaik@7=GW3~OD@>sIQDHW}+Rf;7JuHEpD5p*d>$o7Lg8dVX-9S9o4@ z&xv~VieL%ph+-%IZ1goRYK|2`a_)C{{Ze%j1@5dvLK$m8PT`Ij{-h`@IN-zYrBBlo zf%m8bMc3cH9xVveaT%C?E_$;q3`3g##K4aH+D+&5=``UfBm!d3)?7}&7fvUkhfT_e z|KAUK$TEs1|C4j8CGo)cpUX|5QJ*{ESta3YNIChOs8+Tn@<D~q{;wIj>KZ5GPY?f? z*A?Vcm?ZkY$?1(wcg{&ZH1vP|kOEPCLxx;kQ~p%q|F{t}<O%<u%feCrt$3Dz)&@&D zsFtJ_^*^0*GZuuG49GP?WcI%K(Tt4~sKa^LZ*+GqMx-E866FI?g~4EmF+bF4i#4Eh z!$vn+#TZCkK~dnM!d_?K*l?!2e>#(_AjAJ_(y=BTx9fpM0*fP`=ElXeQLhv<FBM6r zPLzGs&+<M`ZM^3%_D1F%5kNtnrpOjzcqX4;lSZq7rb<+?n4#o)e1){H8f9*!Z3{VN zw3#F{i_6h5Of0xxr^cv7&`Eq@7%-QKjRkl`hgtHa>bUH-a3cva9Jx|If=>|Y>%{3m zOtxE+H*5w~aZL)*!~&bCGaOAOkHB-wPQ$)9*2)?afU)nICSHb==(Xu?f30E>CFp#z zENE;`LmHmT^w6VZ4Y?8ZxHr|;n=-2BD1oQQuaGhTHtTw9o7!tq%bo9aSl>0s;zI}b zmtLnv)pCMW@@nJvue(PV#Ps`bj2s876!JZP{qI_U5(+&9+dLnkK{qm~2s$~AR%n;| zM|NC$Rj>fy#HcMi1qM*)KnUl%3(tvn_xcnH#8O}HTc{yYUk`MPFoM-K15>&0^7!0{ zB+o}F14@X9W(-v#!Sa$Outl2O-^N*pSQ8Ag?sTFgOCdJeVq>{;-Sh6`)HJ-{$X})( zZNx`b!D5clL=DCYxscku{xujh{u%qQ(2NXu(lyLp`V)h~Na$LlGqj!^)@QwVTeqQJ ze&zhJJtkZ?PJGHjs>s|V%Z~;)iujym8!CKz0_h;1Soo1a+fFAnbwu(2AN#a{B^f*d zX+r3pYs@6d$(aim`5D3)ZFn_XtQVe@Vf@F1ljqUw<Hww$WtJoN#I-n<b}$IJ!K<|! zk<QD@J2GBIU9i2Pxonn1_kX`Na!93BAnfE_b67z4bm3mU%T|}tW^y{^J;jNDxTlx1 zewt(bAM_orQ6bg-ui49Zo-->Hf?qeDCDsnlD&?ZYm|mrYEkvY^bh$0D)riNhd2@>3 zS@2`CJskw-P+O+Hdh%1W%%m-t0-YL316yOr*(ΞNae+W6h_m*ud%4v#X2YJ^mPc z><`vMfsfjV2~@>$>d(PKS66vt#0Pf8nMbAAo_>_76;NW-_p03_NT*;MyGOt|tL84+ zll0k_F!IS>_-RV;V^hf%0?HNYS!l_LTDTWx|G3FlAPmu6?1$NY>5#J+jB;3zzpAWQ zp&=2y&`4F41nqJLK37Umsqx^B;{{Z^fpT|k&CA9vp)@+n%~(EYJ||%2;N81!|9d^J z)jFy{Kk8D1ga$M8&nBQKR_y$_sGuG5h|P{ikAl;NItMpCuq&-_Qes5dOV9GF*I)rx z^<7u7Q9Fsd*&ug%lH|1x3JNS}s1PShpmu<Eo4Xd(Y9h><zRJ_l@8tl}>NGTXFhdlc z5^ik4@ONA#1}wZcVdivAfq_Q*mlFfcRKm2Z*sAt5T&e{X!cm{!ER2YIUT(mGaGe<$ z*9<%!{qPg}o1=mS?3E%H&!bOi3V!9-?(a+%I9;Dxl{A#U6N+I&n&;&C7|g?u?r9og z3lUP7<=;)juV1L`SPkNGhf4?XzliF^O*3V&yIsV9^#v!7R4v2_#n}7IzXu!eD6Q=) z+N67$K~q+qOm+PyH&rWaQ~4nFU+G`NL`4Q2qQ60dcQZse^;4IeCOu$CjZ8eLp-uLB z<2|%p5*8!Wvt3=UQ^RV>A|NHo(00ys|DgH~9c4h$UI3B?_9+$s&`7$ef4!X|BG=x< zGZ+wk$4^1?1xscW-V|PF4~#K;*NL&Sz-Y!}n-Zkbi7byb#;?;4OI}*K93A}wJ61^- zHCYho%QU10O*%*uo`P2FK`U}vIPaXie75({I`A_ktM)6nzE1B$J4A;E-vW5nIcNb| zKYi}Osuo&qPnI#0$r4f%5l>&piJBDhf#5v>IV4HwUWASo_V{k8(pa0sn2gh|i6eA` zoGgen^&>m_DG-bB37VPRR>=lWkE%&&7OS-4u{~9XOGMIDtBtCnmZ<x^Z<-#}m4;R@ zpoW=Cf(6SUWzVH4ZvTGsT^yaRei)YY7L#0~;AG?#B2dU()+i3e3Wqr2eGh$SPtV0V z$3{<^`P9MTZSPE&HRvva7VJ)c0_4t0z->n%;KAjI-xa*+0}HHW1xp1>_ZjNM1oY3J z;g!F2fDHpDR9+nhmen$syD9xLM^RthfD<Dl{@@^Op*onhQxFA2l5ljy$>swD`tG0G z;(beVLYws4ypaB1ACHhr)=acfP(&BhxG6C-*&_?Je@mWD@<vGXN6%ljw+Ib9(bbiz zu8(puS^Kagnx2)*)H;xn7A(q(>bN<aLCFCYAlO^TV2+~S$h;XYx7Tg}(i3ehbyoVX znUO!#*Gn_Qe%TOr?AnPy(j{mO6#SjOVE-)CY4MboUV4lQY|z=ySL080BsG~;YOozR z6a&>;@dACwnW4rORY%lfE#u6b@4SqKKdvF2P7>9kswt4YXy(sK#f=#w|E?CT2N5NL z;K<SGYfAutS@wF1uCo?#iYueImAF7A7m_w~HvNt^4?Z~5k@<Oh?{B>BWAHpQu{6c- zfK~iUfE0xhHKc$JoSrWKZSt1sEWs-lI%5m&7DD7(0?5EmFky35AZ+oGT`n~3*FXJp z>Qnv*2|1lhKau+u(ptGu@(n~EnCgFu5LPWwSM;?`sqr2N+!1MbqOTBy)RVYH$}G|O za!o53Ef;w~+wV|V*K`y*IcXKDEbr`#&bd(4`l%_y(hj-8Pj3Tmii%qCg3DDTIE7=G z{&v{W0UNF<mTC9A(2)~W?R%?^?uY6mu>5qGpX$cfj*^>X!^>vvCp1Y)R-boQtHOeb zY<54S{T@ryeauXxBI+;Hz+Ij8T@#-KOBCOxrLhO?lsZBJ>$DS1Dn$-TN}3%)`!}ar z1F<RR6_cMf)JwO5jdDLZL5BS7Eklc9m>Pih%lfcsbYPzE7aP9CBC&kgSm$bd0_u3` zZ=zyCRtNFPI%p;YK2@_g8qW>852-#CZh$OJYp=j_Bq^=K?l`9jfky^?*F>CP61=T^ zDnZc>fAuKQP271;rrdDBvw-jeu28Or8^c)7Vc@I&CoPJ=_&_y^?B+_dHaf$@Wder- zgjmu(bb-5g)^Z6#FTH;zQTpZNLRCW+gs>OlrGt3Fw&+2RKmMy7J7uFEr~d^9^H0~& zVbTbVkeGksB{^zB=9%y<i=~kL?<ukrv=((M=b`*>JA57X0%l0iZ;Z%}6v#ub%|B2w zDGX@0y9mV)EE%Yip<6=7WRC)0_CN8K-0G`Bo|k-y@1~}wP$eA29!&S1`?UwolO^#C zqK)h55^9nN`~+;c0R#-5pqchbOPrKib<(dIRLFlDwEl3|BT-<dQqMk?`2|TL6}Z^_ z*B4to-Au{5KbX*w3{d|^cy{}3<zVZo<>pKBzmfED2f=x=2nlg(_eP^m($H#lU4s0y z#YuhihyG?IRGWV{3b{SDUK&%I^>EpIZks-j<o(|px^y6~l{6IWp-*NBMxQMdM}O{v zZ#~|t|McX!){4S~OqC22smuAp4%Qpyma0lC=?8wKtvRrS^*UqA+@dPF#Z!$O>HX+x zxhC^mxXt9r1K(iNgFKm|O6oju_$bzfq|5W4nFMTz)<91e8FPQdOi-!P;4x<T@ukd) zk$l?xo{$y5M+Vb!&}szo=YK_p08qRmio?+k4gJ;9FzpNh?u@hpbgPqBZy#3;({a<z z$I!+C6LUbWdMY<Jss!?|)@ZEd<!RSK4Sob80l(*R@~7!1Ii<o4JhM7uO@gBCR6JTV zKX0FQ#{M!VCxmvaNg8-Xp0pBC19jkt00v;th3OPMSw7BPewcv>^P1MJS3BJYxHx^m zuY9Hz7%`Dd$T&qg#!R<3QD>=Sz?0eH&Lip^8lDn(SNo4=K&>e6z%hBvyWFLLO<4Zt zpvBs|1jgkJ;$*q#Qta%zhvFrtf21MKo^r(oQmUPFkZv=S>2`_n9xGv!&*d2Ct4az_ zbaC0967`{4p^zbCs<0`{5k`!iPsjv&{du?6sOQjFxF#ri#B<u&#&wDjA(2`$Nrl>8 zzL%o4+%NaERa(L2wA{LroN_nX;iCr^_akj-X-?OM?h$xYN(zC0;5LmOVq)fH^)yts zUY@WPCwFR(G)YRGl_8+c%7^-EB0g}=(J8r9VdfnV-kf)m(2QyfXenj0#K7cpm$=(5 zN#@U`#40HNBb~`to0pdUm6D4CN>h`)3Miw6j0%nINfx$oq7q~!NlkX5)wg0Ovvf)! zaj%7&xlgx4n)en6S1c{79`KB#k>0ScRWcSbU<z7T6A>WJF)o*?B8;w{d~iM)qh@J} z3<5ZT_5y6E038AN<5&%W*Bt@``z=<|KaB1@e6BNHx2ZAAjp%ez#0A86H%@LVHmU(4 z)B)hPBw?&N5v!}a4n6zsLwtI(kBU4S(n5UQd(NSh&$ob(0Ed%Yg6U}nafZ(3<_4Ka zq{xX1cgcRTXr{HZgIVw|@KCJ(<$QOq_y~D2Z24m4i<AkO)H5_XnG@kqa&*{Cc-jas zo%{yqR1xn%LT9IUg4{P~P0;DZi!5|>T008WY&cEK_~Xsr<QW*2Zq*gr4Wyk_N+|;% zb~`dje2U?L@l-|*GjB3qAc=>ynC(mXU)m@RO3`nvzrOMaecqzm+bK#do<W90HHEn0 zxgV$oZlx=0VWCNu|E)mkI+^Eg69XYQW##kVOSx%7^qw2ZKX>PocY`WSBxd=!eb4Eu zd_9#1k#!X{ioX)eeCgcJLe*d<hSC{3ni{KWYc`*TY}W9@wS}WZK79%0;jg`%`3pDs z9H&taSVE3kku7#Mx&J)^ag-j2SMy3URxYnw0R7utH;9MBQJr+Z>TbP@%l5f)8!$gA z$X~xb@ZH6&Q_|KHiE}eWu2hrc<RMgcEm5Cej^WZLJ=?Ncq?!u#ye*amG%`<ZMBzN| zuJa+Xep;@E)yr_eO~K=<+YGmPhDek0=Tu%Pw+B#8#RSUpF?vS$6(&{0kZ0uN*&S&u zRi>-44yP!d1;fM}GknqsY`q|rdsFC>!qyTuBH1qv_<*YnD&(I^O6IL9D+A!~Ny#kg zch16E>>SjD+tq7r%?w?4$CK;HrZxAAil26VHEn77=!FPN@pK*oEVtsifOF_hyFlgf ze}b_`Fy<UZW9X9~%LKE$bjDuP)zfSvu*4qvYBm2cG&M#$ia(XH9xZ(3^l+Ot8T)X@ z+f<NOy@dJyJ1L!>#ZR&N2)1x+4pb7}?!NSA279uekPvEN0as^cOO}<7-cI8I)P~%1 z{`SRW?L0q$*n9=TrsGeh=oh!w>~g^7a!&8<Po8R$KaBwiqYVS8FKJIvyHV0C*fDao z?Yz%_It7R=6VQG9TkMcn9UUVZ7A`fSj5+j{8|0*Isml@~!%d<%VGqegGg)+LPcBp+ z39<-ii17p+1Onh2Q>yI%NhcudQX{bi@6N0Rere{1KuoenXDE6w>5M-!C`^QHdXp7W z@sZ2o=P*e%=)b7ZHK%ox3{(i5UEf9^m)J35OuVzKt2Q%xo=00em9f;sI8`0-U9)c2 z8!5u1y^<9qMM2aIB+n;!1(r1AQhQS*@Cq~eEy&PazASdVBt!q<M-AAaI%};aKwcoD zqEW1OOt~7sP^^J^a&mMP#a1X5V5~zTG7^dqjLLzw9!Sg0jgS4P7OO?|2}`QXOP38k zqvU_1wW1%tKyXg7aedVG8msYj82nHK55#>z;(9xANw<!C+9n|?r?8@E(SkG{b07p{ zC`yO`W~fanK0Y4!Y0fR`Y9;p>ZDPV1+dkF<%^(USwP%#lSyBhI_4Vyac9JxW<+EN+ zTFMjY?e-VZOwE@1J5(nXeieDN;+?;`U#0a+4Rfl>Qtx1U#}zb-Kp^5OkZq`>v-*<c z@=|I)l^%HgRZ^%fQK-~^arygo7~59^i7y3yGyoAk>f}o?H!(FuMnOT@rME$ekVq)P zBdD8S<a2GP9VGhxW{UZ3QBq@Rl#DeFQ@B$=#)8xj`mi8`pc7@J<S0ETKBfz@p|v8f z>^4r0RO9S({Af(FgNy^jP7MeQviU%&3GmOmL6{!W4#?79`cYr{Wf(}af!uP|71p{Y zY5%PK@)bZUpx`g~7M4y?H_DA2n*MtrZLp}a!>I;Q^Ux$UXh_z^bWqwrPh@skm0e)f zL$x+o9sk@G3_og)tI-1+BF@wGtdW8?tbKNtOb_KtH+)MKEd2A^6g`yXcq$MppBEB? zK&E&sRYYC$L2m8n>fQKQ?%_x}!n;EeE@kZJC$ju3r8xFWC%9AB_M#Q9Z7Nus&KM7` zZxg@nvI}29IoD;Ih<=#d27BY0iAoepqr}B`OR=048|0jw8ai8^?Y`PEQR`13eUEgM zLICKbt#Q`g<_U0&Vrc`;!<jBGhKi^{2!}_`f0t$n#bkjol`xZIT#>z4<lbw)C+>5m z&3kK`g$Yuq40(3D-?WXm8lFWU0qU8**%Mh(U6HAyQ4F=kXaH7bcg+NfJ8u68S2|2y zUL_eT<nl6u5;bLmTOD5An!Q^2aS65%k9T$?@@dX)A^zBnvVbf91x1&#Z31=|T&`$Z z3bLuZ%FUBji^p&C3?D3gP3H1r?+6J(bt1q6-*J?S3gM`uA&vft{m!Wff>nS;O}H=A zc2Y$(g$urFcD|`TtM^G&0h_WGC$inrV=sm@pvIfD|0=DuC)H5OqA$L-RCV@4lGMgV zDqZoE`Y`1CeIPK^t0RN$R1~3U10CdKRt;Z%R<hQY4$#ih;=<0OrLsroJqX;TXn}9` zv(ctFXeGBHt?Ms(b3}Pg-O{A^;fJ~k&>?^{RS_(RFDb<6%UcjfsWI1R+-W?ly~5A6 z2a)Pb6*-fD0O~nAk0r#_XF5BIhTCiW!6CX&>3cuJg}!FK)Mlb(CNaT*wNsPZT>Jhb zE&-#bV@`%Up&d4EvxOR4pwHc2o79dT*RU4neY_eEV+$4|kX1E%m!$!CE?|06l}bb3 zMjI=(YqTs|-9nFVFMbY7AyulILiFEF$CZpW7^!)dKOKDuY*vkKxcvf<bmUn(omOFF zx%*jpGY%I|0Xk@X^C21QM~5UC@F~jWJq1U=)$e#XAKm<5MQ_iujsvNf2>UK;ghTy< zvAI%c;Tw%dsSgLNdqb%5y&WGhD%8SqgeK-gNNhHiG?<boEVM$or^Mo}3)M%)PZ|Zm zP4A}3H(Va2nAe!ss@%Tn-(7BD$`l-%!%m(CJP}aA_WuCHu6_%I<TjfW8WM<_{!}YE z^*(*Z$U+=;asomcWR$=60IH|?pq8V~Ob0~<QiZw=zLE~fx911qfnKj8y8vt{Op*(N zJH2=b(5Aqj`15q#)X(C4XvC<CCk1ieEk`=3Xd=7dTc5;ky77a0*>g*GYDM%4hx<1Z z7usmnI*~&f8us0ctm2G4NIG^|!|c1L$wNd%U|sGDt$z)Kt)J1w%Ko$=Uc2#Y&Wf2= zillp+hrDskS<k5Q6665DOF-cWK~7jM+jSmUJPJ={<lk$RWH~L%e^$@v2F$JUK%4|N zVjC80vJj2;WQQr_*#Ff^B(8L!4KZ_!n($7M9`8<lE}#shYDMjw?`qlN@oRCwjsv`x zg&4J}YH4R#1q+aF)>I@+ht(oFc8;E{z_Jc^0VQ2<Z6_F=xeUq{(q^tVp<dxG(E ziYmWqHPMEV5lwJ`8LF!*AVJy--*P<-UT2CiCPSy}v%ZzZK>@6uB{j61HLR-2e#OG{ zaneDik*EzBCo2oJK>1$1dHF8aq(?qc1iquX=5@=m4_xYNrm6<T$!HCapZl#AQ3))F zGfb0te{)k-oJ%OCzQzNC3$+#k$N;Ad94NY*L>IQE*|Ua!zA}ps%&{RggGjWnN=ayI zE^>1Y5wnH8kk77l%_A}02shgCy8o=JC4K8as8$)+*0<$hmnuct4WFg|mc%qYd^coK z#g;B!9s)n~*bf6h55!osnf?v?d6po8rH6ax=50C@(>vg^Qrk^&5hhWIiHWtXwW8bv zWoJWg;lx;R0lqo$debE@_xj+orrQS6K-gga=H*V9Nq20M%@S*+y3NiGVM**Jx+jse zacohhcsWSY(#iPNO%Nknu#?^&i-d(EgCtr;Yu_IqBNk0&L1E!oAVJBMmaYdl*`brA zA(W}JVNPd|B$kXVwPL}UGwE!}N;rtFTowS3o_X(1pk%W-k<$lZz_msI-p0=nqQN0S zCZm?E_q$aWe-H_Xyf+1!uvVY=P|rnYjOBpqy*&z}`K&ja!)wKO;_oaCeK0#JkErQT z_nS|YZh9SWUMy(#6G|J)>n*cQ?!zJL>96+2RLPR%MAErq>Tex0pWh7f2woizcnwWy zncc@zk@asrWT{vGk{WfVwq7c-CJ%Ux7<jtZC~$lgiDt|Qq{i^r?=C(&=o>a@ax%3* zkEHR1;fddHKIlr6{kPwUaAYZxA?xV_dkaTZk?S~Vj$fQgOM`JYc}lZP2@-v?w1AJv zwj52B^*Xj9sK_2s+KG7d*&2qDDra;Th~0ZHdR}ni0x1GZ>$0_Pons%3|0;@Lxho?r z>S8n|2)(Y=E#C+D0cB!0c%|;}unP}S;^=QX(_fwJ%<`8AV4v97*iUI`)&s%3J0Rf4 zyJo)<A8cC+g1EiJ83y@DodPt0lz4vk*M&b^We`QKn@;z+3G0#Km#+~OdZjHMOV~Hb zzGub<XM2#KkDJ5xjS4_yaGM|&)0g49A2M?JE1IzWe(WWehVaCCj6u^nP=CEkc#xLx zvBZalV&EY|;%UTN|8hSFjFLbE^I15MAYO(G<UgW$_FM#JYsG|%GQ7Vf*u}YufwX^_ zaNmA^-gY+=Q<hw;aWf@;OL(^#isx`qx?Ef$Hd4nqz=~+R7{&_-YP;;$Dt8OE?lA%~ zpu-Kv0K$f;gNI-ryI4@+olni??~_Z#)M!mp=(jMn?-f~gKy@e@Ic*fg2?MbKr{3OG zdyuwR;IIGqk@MuzD;5J?s;~JL$FV(5OFtNl4HxJUqI(g6=Tl{-wJPmplp<07HNrQs zX>3GJ|29$+PepcHcPmr+|NYT(lzsBF^?LG+ZR^=bLPjU>dS;!WCzVUFMdchwLZG9Q z(`6-fu60EsL1v5s{pHPbK&0bYl?aqMS#Gm25+VU5%fJAc4UkfK4F7s`BnW4X4IZ^X zZofY*^)&G^hTOZY_zSx4Q?{O7AiRz*H;+C8;a5lIWtx0zgc?@n^>`}$b+plQFSt_d zM=Xc7qZjq@p^=$>E<-ca-$l>zzc?Bm)hCa1rGM40P}w!Q+c0wax24())Ge0KYJ6$h z@a-?d8pRqv9qh;S^voWf-Xn@oK2CThQ!m`A$&Www{&=7b_Ux(HNe{<*EYO>cbx1bf zlLk6VuiT%nT%a5JT$(SsZ6w#9)Rfsbh&-C<*%Mffa&>hTto*^zrd_leO><8s%*g26 zv%kdB+BdkV^_9ly;?TtJue?#`))tf4VK82`K7&vK-Fr2;XX?zvgCiqmt%Q+-Mqz*z zGcvqyTgQSK`m%BRp0$&c$0WetGFA6X`JS)uIeMYwlajz?@$UwjR$6LD{HY$M%4_Qv zqx0!<%SF1;C2{qR5n`xr5qb3{T^!<fUQ_^o-H<~Ja`~ML6^|XzCPj|A2`^&XF0f%R z*eYS>MR!E4Op#~ccpi{P_lKLzUhr{qk1sXM)a18{icr#cBwV~(zUr*H`epFdVZQm5 zoQUTx8AJlb%iM=ttF&>!a8G{ahG9SOpDN{S1L6IM@5+LUz^F@8oqbnwlPBWWX6DNZ zHA%6L9bL*|n0=K_*Kq=!PD{Ol<Hy0P1(^ZlnRovR9&~j_34xTtwp9`APoc;cJA?0Y zYCxJ8Vl_yK1;S6lOeUW}_R7m+Y?f>>I{HH5szVYWOW4THh-*~SZlKr&ZG7ADe^vtQ zk4ydLvahp`&34GheO)AV=S<tR!R|sU70vC)eFGOyVfwNf1?}DP8|Af2M4z*V2T57e zoexY&q1zzrG#Z6(MC_XNZg=DkR%?%VP<5Uith8mHkLf;+p|3^dkIG~~cDg&f0v=LF z(=6G!t_}vz$8`0s3!gp;I5r{6Jj_$~`(}0vA$x`}s*yHwyKN`S8?K{OoBnXIb~1vv zdr8yNnl5~F=h;T_5-3y)+78kD&IXKn83Q&wSAW>-`JZM-9v%QwF1k>MIA6KH!*Qpu z@7*yxAzyR_Px_*$puCRc6~;j$_P%*)$&CQU;SH$vP39Gm!bCUC?HJA4@c_rl;kArv z(#4R1ILHl#PLogB5J#BM#?S+PIpe;@;N9+NkN=r-$ZOEJ!JKXs8hh2#77(P+A7X6b zfO~(S)f%F}5Q=xde?Tw575v3>x1B>t8L`rO=e~Hd8hWwnc&mxHG-?7y_%axSlUFcm z<t}bTV(LW2Ktn4O1?A_aOI#a`xI0$hzhBCxE~dzy_jUKRYn2UBtDDRJ7;YA3+TyDw zCT6RA1xk%9YsX_bTBF2oC&Xpps28gk;!*nSkwAZ0=EpYEb8&I;`5;*>N4JE2wL^je zq-^<;)DHdIjwI!HQQ7l7D#@B6P1WT5{si9O5y?OG`<F}8Q(9bV<F|KzQ?k;j3?{e^ zJpDzt0k(QXyf6e3X^T=5-XrU`-gbZPZgegXcp`8#?Acm%<jEx*%NYad3R?QzKpeSz zgnM%>(27*Thiho8oWq#mg$$+;a@a89@36G_pwqwTW)!RVbHo%gOFa1`z{kp<(Sxz2 zx*7<XV}R@&NNrtpGTBa39)zU%UmQ9|ZWl+^&K4Yvj`+Gb57+Pl$?(9MB_Scns)>Lj zgV$-ghl>Afm3f>_X_Z}EkLA8ZGJfNGuArdsATjPS#TUP>5^vgf1#byN$a_dTEY#W$ znd#cHva-5)><y4~!?WbEy5K;q1sERSt))92Z?)8HhJdKK+;SuXJHQ{nkG8AgHXuU2 zG87r|I-9fP0@BvHmaDvJ5(os%^x<59J$uE#14M#&d_%)?N}xGwFgH*bFbKRo{h|x2 zRr!J|KeWb}#;@=!9E_1EX0?%>vhVLzJJ-`PZPs<5d*k@ZU<oARPj7Bl?nSxNV9O^N z=hZa|K;r*fX96(QES%y<2t06WJG3|7y0em%8tD^3;7woP;^avJjd=WnLUwaFJv6DZ zB(igoG@Ol%jSH1O8fYrijEw(Wi-9*25Q1?lb3$1gA|qXQx7SBN3;Q2oT4~dMV{P;P zaSfY3S*<q=$>y~vZ2OIz_dH>V$DDcU+GCo_R|`g3a?!L<l_K@|yLoHSncBig$p-z1 zokl?2VQAZ*q_Tr(q4m^RI3Vxt(R$Ez?jJR8tx{|MICI3+=UI({T=eCox5qv39zjBK za+oE2F+KF4OZE$#FqC|27g{hea&y`^gW<+|J@BmfBFEoo-AzKD^XH(!55|+DR5<JO z)iZoR&TJ|VuG7V-`OGhV<(3w$3?T)<k@Kzjk+a2ms;RLeOn3uSuUIqv8S;Q8OdoR* zWO(Jew>6Q2UU;hdH$KBio+uXk736=P-Usvxsw+3Pmq~3twm@B=PorE|M>(su6{yzV zOBL9%5b1fl1jtOK??DUce_!FCrAKc6*aP0rk7EmFccR3QmX>}^8p>4TbEfc)8id?K z9z@di*LiUK8bTl#`d{`v{{NNE9Qgm%R~SU-uM{}RfxbFB3Cn&#sgV|(Bq3XCFa3;| z+=OfxhJ*9efEt`2kpqlTn2DenQ=Z`?N=k)Bk%wX+2Bad_VhW{;$HT*8{BOB65Tv1t z2d}2I3i9%HcbI^a8y=C9kAv@4pYpx!TwE$YxCMh_E_@jn8CmkJsd*rNx1Ry1w*LG& zH99J)v7J{@-*t!&a_ElIo|JT4R9xD~yk-i{q!7?|pVD}*CWdC*4++v|KTn%!*>{)6 zOpOIMt-6=_E~&AnUc;OM7NP>homPX^ybVKozzG*hCn9(lxRjib8(}9gRA#k)-(`Re zH9oSCgX1*jo4}XvNypR>V&ge<mo$Yx=cSF?-_7b)0-6+lxPdWpJ$!85{$3n!&YiYW zEMDtJs=9L0+yq40)%A`mt^29*QBgt`E3N*5Zd;={o8F#ChdT+_B{M$=ea+ygD}sI( z<>$XYD$fI(s=fIf)QAX!lhM%h4GFAJE_*E4YxFq>P`7((iEJX1Ui`ADxw3@dK9A?Y xlyJ*#2Bi&!pdrs7=iV9TMo0=J0iE}FTe0IP6|8e6;HVbJYgr|kQYqt*{|$>T#>@Z! diff --git a/doc/reference/clutter/actor-example.png b/doc/reference/clutter/actor-example.png deleted file mode 100644 index fa42044a96db081e5986f28d85db9889d7e63624..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4966 zcmds*c~nzZx4>f^aH&8)hazRt0xC$r8Z}Kr5?fj+qF}{>fDn{<mLw2D2vPeLYGqJB zFhr84OhpKT5W<`))c_$up%4Oulqq2f2!X^TBzc$j&-?SO@2|I3?^<Wwd(Uvs-skN7 z+xwpTS3Fz|_k6ww1Ogel{qWsY5NO*hP|oe%1=OI6ewzkvJFwrnUE2*@sk=jd1>Q|@ z-(Sah#fRbWH!-20@VNNcP%t(a6B-(ajflssY-b}up#2}+zWe4{@>7|J)Ht4aQ@YyU zH!dx`vn|*C2m612`m6EI>MwRYIG<eiJZQ`sT#fj<>+ZeRdzxvCfH(GxLwhO?%~VEo zUA_Bw+Ar95M}U3VVZVcW7GZ4<M_lf%UD^LTp|b@WuE-%uF?7i>ySu5jwE`F$0+mx$ zJUne#lSY<5+yMx>b(MPydsqG8J3vjBvC$b8UQa7?OCQ-37Z<}6Bf;3w$cnPIHaOEy zHe_ZGYB$<vXc!t4bY#(r^wpv_q9Cf|QIxGp3typ7CP7fhxUfEhXG5{?b<6EgjGin+ zrxA=0>+j5Q@4lIr$w-DZdqC|?wB)J#)z|C4a4&Qe-5fJNe7M`|fr+%9W65n0YrS_t zt37jR`&^qJg+#o*X)O!u4G0Km*<9nwUm2&JB9Tau=ctiqK8MHDfv)6UEXz&l=<I6p zsTz7IPScdJ*(l{P!kU78F?Ry^1X5CW8Z&a~Dg{%XI(7fJ<eiJLh2d#XJMAa?$NP+o zmOsdbqnHlY>yGF<BN8xD1j5wlHn=A!FpWGs=P0ua@2#MvM12PK3rX7dhvQAx{(Mdm zf|wN6sd^ZaT<-j&=bO09P2vIt<LT+CR;vS<+det(7RaDrqQ|UPxC^`w4uo3|qfIA@ z5wm6;_DnyXgXx`sw^cANj{)`iRnNBugcH+fe_BfUQyX5`;9?JGX@4M(vUV6@oxwOF za4m?sa7(m|?FF=b4$S||kKqCLs`0LJJ00nSX`3FK<9|G29QIW=<Af*5YuBBCZ_2Jl zngI$GvD#<BmEKjp%&4D+YXYb?!dRB*<?YGWXFktzR?n4;?U(TPahk2WYOQnjVovi4 zGk!f?rtTK93&ZKexZXsvToyk|38(XfQqmWANByDzcY~eQYjDg0FZ&7Y#_$%|O{;Q} z7v?L_%zE9&XBlh4e)3VedWOs&n9jC9=tj+SUx?c@niiRan(Fp1_+>z_v5r@-UIE5a z=En$|eEo}W3nnx-1bA>uXTOTRefu_Uc=KXo7N+F=4`ov)YwY?t$W-qIm#&ou9|uAU zrAs+!HpJzY@Z3@s3(AoGgvaC0#ZPP&WydaE&kYf`VCCcTep%ycOsy#ivZl)uYhGk- z)VUb-(1^<vs|h^X<EymD^z`(Bm~&YDZw8pZa;+OUmc)Z(%?I_h%4_Atc7nx?@dS<q zY&PHPD#N=W;{9_QQ|&DVe7V^gE9rA{bsZ~>YlsZ*eSYbFw)0eRiMUHw#&zt^wa)1t zCn?+-gyzbkcPnHCmXJEzi%Uw9l!VhLXrkap!oob62eZ=uITx9>QP;Khrl0JnSLzW3 zW^tQ-wA6)4ha1V~9ozrjT<@pk*$mcDBbKh0%ljJoB`1B*c^n@`uTInPrIe13QxK=k zu)GcE%!Fo{3x<N-8Qxr;xY?GKCRdEFGuhn}MA>6<@`qQOlV#+mC!I7HBV@#nWA)57 z8h#=X-?<@U^B2xmLBbVFo2o<PA{veMevl!qJ1Xv&CePl>p%+%rbb?d~wlHM!-cFSe zrN=I~xWF_eR{Sqrtq{wt)o3=dP}dVmkWj*3CW%`6=ujtV>XJ2qOBFjW<A$Qny5}H{ zvB-;Li8NXeCdoA2T8wJnhGWMa5RNFlsvp~9qW@i%G@3;sE?Yghc(PYUV=?`}z({VP zQ@;W7!(AK>m#ORY?Mx-S7>bHwjv5KO#*=D9DN5#>t5a8N1)QDD8!IUtv@;p>!*VH) z>&kbA7&u&iXjUjX(;gieBC;iaprlS>={%Jc3QC2>^QBJOlBEVua!s51#rnp^tb1Vq zEv$jUTpVTwKoi_@8<0s!9?mK)Y@SpxqeLcrv#^m;lqD&Z4u$&Mpy+h47RgC+0ZGc| z73$Y}ZF&ZRb9!167aK4`F93(y6p6)jKA*oi^DHCJ2Gy?YbQmG)&DT!G^VAz=quH@9 z7F*)9>KlnXrs|z(g>+GXrh5i_>{;s6EKk>Vb*rM7egiRKyrQ!dIG&z5mpLexK*9XW zP_p$<RN^=R;0k62ZrpFHmqA+8{WX2%m#LTyrXWX`Yu08?9<K***rHrncF*0^=6HuF zMR@L*Skbh;zTPO}KXB?iGdseP>gunLf_u2Nb}av}ep<1xAv_0}<DWM?ygFEnCn9f+ zpX)_d^f|T4`7rqL;@hc6oO&f>V_|51X~{f5xm-d9XRxPb^K{5@RNCCLYJZj^dxOe; z)Phy^^sEp(y=&CI!|fk$SrXRujRDZdPNdbnzDd)DTcu^)*vSo#SC$TL4a=#$@fh0= zgKzB|g{^tE$<6Z&>w2371L)L8M>#2LlaJ`vX1oYDHx{1i#wuoYhm1pR-#%r$IgOHN zkF%k?Fo-c~t=pS(PLZO(;Val=j{>cdiscmJ%K`ZNH^m4SWXU>$RMN2mv(wMx)8Kl= z>%G%)oRE)&Lc0|>?17Q<sjcZJSCWZ3*)JvoLqlgH{WbhzDin<T3e_y7U8@=z*OwfE zDdzAM8=~E^CJ0uNX~*g8P#RwfUAojFdZ}4%3-8IbbxS|KjgjLC_I(*LV8xQXW`k2b zD1xlvX(px6iUr7GDq;Y1dCQ3AHTu*B=GnmXc_vw76Yfr0;&62&JFXva4TP&gSb@TZ z^;;s+f`Wq9Py6>*4$syAEdj;F^M{3p#G;{MAkLL>%=6$Yt#BY3!lpiSVW(EzvD{eJ zEX`_y3N#<cMi-@YAY~&dZ#Tbu*V^vKD5$Dw|3a+M8LxG;t?)&tkK&fq*66q2CoRb! zt4T4uhsT#C{tc2hH%PKX08$kVX<g|tBXvhbB2g^fz>++kpz8Ih?a`jJ?8f$^=m)Y< zjxH`Pz8xu-$7Fz)UV<rP9poVU#}{pfqL{LfM(?Vu&g}7sGcQwBYc{6J&*eWGBcD8b z_RPn*AW}RxyN&1cTRr)^Y|^;L<}~I7-Nf?t`P><(2f~(}HsD5qVK1DE8-KD>vqDcH z)yZ0URH&!QhSuEn!q0T#Xre&Lrf>hup&O~ys%FtNy1$MC#i}E%`dI7+=lHKb{{24I zO1@lz9Ym9?#j0iT%%BN6Ur1ajCTRFvK>?VXz-fnfAP~aF$ic?xz?OyZyqa)Q#0g-( z<K@|ClD|Zuln$U&Yo$^Z4#o0UmKa!e|BO<(>A1hp`<{PqAZd!9plN)ZPtD`ND}I=e z8un_mN?ye-+5*EX1B?7Ef!m5-rI32-J@ICZZNSp_6P1Y_fmS3hpGDjj-+GSIpI#_= z1O!5hHKc>p{ab~skAMG+ncPY5X0hd>@dT-IKq#cROsI!9Uy-%A&n%LI#uCTWd)a`Q z8v$XWGeu<B@^?EH5-%pn=N~xs`P6nGrRd}YBR^aaQd{}pf;g*PTI~y4dgrqCvG*}x zDEQLATIsKNOWIf`f#^ZfYc6;~Ma^beJ>>fMiAESo*W=QnD)5H{UqJKW(xvuE!}#vE zS!U?>a&3Tnc3)SHb8b~lhhv*|z$uj9y%;B3S12UE+qz0<Z0*f7`CncGF-Gj46I*4C zW*X{ec=nXWz^|>=KmJJZ@4&?6)VPZc!oH_4>;QmC8-h+Hm2cFN5rEM=FmZ|l9Po4Q zK~CZXh70!h_<Fw74t?O>0MH#`28}aE!5Q9z0zu)%qQFzF{4)^@<fL0f5?zL$Idew+ zuj2XP*jNWJkP=p2vo}3__=k=_Pp02x05)@R4R`O}O^`0iWS4=oE8Wm6*9P#L`Gtj| zMr~3sbs@#u{xN{a%rqK?TL8}M^t;_U_CgfvQ+aJbBtod&E8j<CnrW`3q@)bIfBy*V z-;~+egb*c_n`xRRP^TU<qXm)*lr}P~@5y_`8AjpVV`)p3qSXTk)l432Iunw1vZvg} z%(cKUIBg<7q(LOueC^MQ6O~Q_Dacz3ltO$!z|73*QdEzPUiUk;D=H%51fXyXQGI`L z*REZsPo1jcZ3%gf%8PWuPN~Y<ERM(F2g@%H#^Ik=dZ7MS5C$(luQ7mS9mWY3k_`WF ztSu?o3L6z<R0bZsz0RHbW$*<ci_iIMal-;B7X>B(mE1AnN{9T<1D+w0J_<asDMon~ z)Yk6X5Ecr|Ku`$7A;E7mafykt{I6J9YadKBdm*4&GC;GQO_h8rYnoZ*SXpUTOwrL{ zy`YDao;&`>BucVJC&xNBhW%OdxY|uU<&!&t`+%jluMfDxWox|rZU6OYY>9L9aJ2wq z4yxluYtYb7K(*i>cis8+*VCYb-)?nyz7O=vr=g$||30z({L$}BL3@t&g0AfTM|F8$ z4{_R@3e`74oGd}PHa<@i=lGW2?uP(cr~e09*L$%wDa3%)$*v^Drz7_rb=-^!XWefN z&W=f;CQej!LP8nmjic=Oxts?B6uW=yYX0-=<NsNsxe?*^5la*OY!{rk`{3MEsHMrJ zq(_{c>^pt`p@aVEp<P})$^RM`9_S1@_~z0-(wqN}-THczk-YlG1kFtV0c?)VUuj*e z*}~t46zG#u<jZ}wk(my>N4Agc_<ubrg}Zs?PJEfcpc5|)<2ze}4ekiCUfFDSJD1}? zy->glHZmCH<x@>-lvmOpAfJ>L6k1Q1!z@7~ttsgx&JRP}18HYjVST)i1(ARei3^_D z$9x3IF<iSsm45=tV;*bvKW#3lZ+q#AzscGg9bMp@U-|R+Z)ZVui40m(!Ej8=(CCGi zv5?uyd(MZgDn7Xr3;cdXtBiU1oLz*a=)NHU(lJ%TaE8By1+h5*GCSPQ%rsuRwlcm8 zbS#>Qi+Rei1db=-!ZyPz><I*kbJ8|YQw{89WC(B?lFodYl>z#rDKbv>LBCzN->K5c TkYv7f_~iDz$9FZ~2HpE_-J3^} diff --git a/doc/reference/clutter/animator-key-frames.png b/doc/reference/clutter/animator-key-frames.png deleted file mode 100644 index c646dd3a0cdb480bcd71e5305e920faa4eb47847..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11936 zcmeHtRa9I-v+ls)8YH*`cS3N2!{8bqSa5fDCqaXU5FkMC03ld#cT0i=2<{GHaJSR^ z=e*p9dtdL%VXaxL*|T@=>guZR`>MO5)m7!NF~~3=5D2z{JWK-uK{x{+R5TQDr5=9? z3jQIvODSlffxiGWizx6N-9=u{9o#?l_(70j&hP;jNj+qAJv5!IJiJZaEFs?B-ki2h z_U`7UE|#3mZq^xa5i$tm8AJglspXTozhLX~W-5^X5cQcCKGH>C5xoYX&Z}k^$AoIH zs)Lf^?MtuEJx2w4jCZ3=C#rMlU$eZwo<-K#esv;fJ`y~ih|ik+L76-&pqR)1zL{Q; z5FK975K8Wacz_zk#UeqdklfO-agwnT)zuhsPhvQadNJ=lk|da=DiTW8!JjcyH)vM% z@57+QjB1f4y2Nn-(-S<rvA1rD^!PCgP8B+=DO>AqSFa(dkhB&@c3-Jt;&kP&;@f9_ zDMl4jo}Qix{(gQY^>f74F0{0?ezD4o(#pzMtE;ONEG#VD;A2&*f9D9<NN~RKDK1rE z9IuF#T^mafzt^3bn`^d^ApkEMmywfO8%Uz-CX3so1Gi%;3)yFr?b=n(7`)NbBMm<P zr&rs(@}xi)yy0`Y7ORY_YgI{QWu<1J#>VQaN+l)%u5{)0Z^gw?!hzSk(5$Gafk+_= zoJ_GmeZyC;@T|GhgZQp4Es75)sHw#@jEu_hip3s>%0E7K8@jx_#DfSU=oH)kwmLzj z4m^D|fJL_w4aVpPJ_<M;lcTY!zJfx?SV9~*I5>W`wTb20)6vrA3GMFfNh>ME;CJws z3|Y-h%+7uzXkvaGH~a5j?JRJKzE+oAxVfpRKrI*p4-fAuue_YIq}ObQC1ub;NK{l* zYDyXggPlx_k3-XyKhb%<%u>u4V)PIN7kSnAGqAye3_5v(5tB@cfuEw0q`}nW=}C6M z4YZx=OtiH4=n*gR@RH=YCV;`Px4Eh?7(G6g=l?#El!$H!!5fMP!2*LJIq;K5L_~yf zMj{as5k;)8TlDnxNpYs;7ZsuI@9%H#?q2IxuqDY?`kmSJ^!CyS3X<SQBhk^(ZSU{P zNJ~Q*85xPTDM!sriwUj-%d}(eZZ7CJIdQnt_vq~TGsY$+!g#EQfA2|<lat5f%O!|; zHVZ5T5b$R>4p*qfFo}v%M&eMq9bhIWAarc}N_E|zt@Ukn($yttyBcz)<>j5o=U`$& z-J7cDCpHcUjl`uMu5i%@t4N)rQBvu;CJT(EWo5-MH#gsg!)1Xzv$M0CXP?R9P}sD; zOZfS{?CR>unY1&lpL-!95*r_nW6<n{Et~Hex`fVAQ(4K?a@d7AYFAr1<6z_D6roW9 zb8uk)QC*!ozH>NZo!x0yJG|q`fRB!dh)7gor_XL{YwL49V@;DJ@3J*a$;->zVOI5w zg9AH*-?8g&*&CV^#aFLhy(pSW`LzL;pr)qoPhry;ot#828jns(BXL-0dipX8XGH9V zeKGhUFl}g4#xL^J^Th=6*Gaph+mjJG5fKWA33qzV_|6l2{I{{OSeYWe`1Q_9Ury}X zu6Iil<>}%56ga4a7|67Aba<qs(f|HA1YB*T0^^NFFQhT|MsuaXbhZx;`Xi}>ws8&) z4_#U=S7YRrm3x4FuJHLr-`2JnhrSHww#Gz;aoX7$TLOA~bof$x!jB)^7i+Dpt(9~8 z%&e?ZrlvGbi!DM$RG&ahT##N@nfH&*&FwjnQ&7Ov)NqY_H=ZJ)qSA42I1cyI>%YYE zL{Ol|rw|Ju$<56rAtUR`zCUF;Jv);u)G)ofKGSUv62+kq3^_V-t*NW~Z>KgjH@|xG zCT4Nb2nz>CiZz9ng#}&M8xE6~N5i2KiMm+y#|3c~bIEDjW@c^<W{VD?vR;Eip@RPB z?2m(e|IYp~HMQHR9`iLTM`&>|b5BnX1X6C$xH@K}rx%S)&M#4-Wp=hZSzK0@HEs{> z*xuf*k;vv16pXsR4}!_a(6F+;&xLmjUK>gPG)BY54qtHUFUk&j4}c6(UR?w*ke81S z0fK>nv3c5LRZU7AaEKswxeNs>pVQt>jS~s=YNi|-8oFFhRx_!d$<bm>N=d0*K8PWb zb#mf_<TN*vcXxMF?W?G$q@|^WfcTP??bAq=Q)1`gA%K{0k#KQwEsw!n1V{h;;dY#x z`Ju}W;VSb!aMdXBn5|pSAlXIy`Rf-H0w{$93nk%v(0R6`qy(&Rb&z4{<a;<A&QwQ^ zh2r7i0fFS@=Wl6nbL37>>q1<pi>a+^^~YvrgdFFtJ}4IQP>m}1B=?7;i_IlFc6N5U z`|W@FL<B$_2^pE@#f!0gQAWnT!05!(e*xspOUNHTd_Y_tr2cSz?xkC%%}j_<P*9Ll zUhdR+?^raB-f_17B|y`}<QYUKbvs$v=p{M^#^<T_Ty^Hdcht8K8XB6%$#$A_bVuU4 zp6$L~<li!9yogLkDM?pmgt#wJqoAU?9<9p!o34UBCPTS#d;IXQDzFBmb5q5Jj+U0s z{uidDPIcla{W33aYu`OZ=(5;=tc=XiP0qfGgaia1A0HAztxnC5JP4eQz&<P)@Ii~! z6V(s=*45pOM@1F?x>P$iFAs65!Z>?s?@w2TO0nAF7;TDT?wHM{N2HRaB|}qFQ>F8g z7~#{WD)u}iSeGCJ7eoWrn}OHUZ$l7c{728N_WqWsGZR+omr)$9=JS%p-CU%Xo2tTv zH7|;00BSUN?h(Nknj=F)5p>y!F3Q|wWMraZV|(fx=SHWdE_&d>`uc8-6cDS-RFhp3 zg>b1CMd}IB(Vd}C)F)(Q7+?*-lY$gDfVG~{(<7ncP;^8SFpVxQiaiKO#>D4xKFO65 z<>Pw_%z#1+8e9+n(qSGq)l`06jOQJ{TTga$r@UI6nu<Kx8d3BAZB`{wF_quiO8LC? z6dy2MrS%9^%h}&I?tYH?6tekvl9G~eDhg*U)|8uz#(=u+t}d6;?N<X9+*&$1`7JH; zt++oexE*F|(8>87IxwHNgy4!@hKL4;#X>ibxTho)FkeKm0JvpfV1R`5_4OgQ%Bo@h zvfys)7yj+>M5lBTvgrj0{u~{RZqVd`9%AqE*8s)#&nhW3H7b{A1GPY-xGwuAp}?`Z zAC{OF+@yYfel7r!Y>ip>y@WXpn~++Ka7(n_m%XVUKA{}dFe%2gIEG^UhD%?2;?AzD ztOy2Na(z@}_?(eZq+%f1X8U8$gXKJ-|LpX%Avhr_N_TYX>s7jl)$a*=0ioT%@|*7U zy92-0MbW5pSHISv|H&u4pX#{S*u5*=k+~WrqqDQ`pSNAU&0oChSTDXv$H_}}#1su3 zo$&1yx@dMzyUj~UOB39Gu>LkEZ1**YB_nRepfA1U)5uPEAi1>RGtFk5R*oD<gKXul z$4kfw?pb2ulSd2;4Gp!ix9_&j4(v<$bPF>#r-MudEG=@jhlPjJ(9>JY)?r%iw*E{` zrcJ7ZFScT4456eeM@&p;C3ux-?|rE-;jA7+FkT2Hpr(H4abz^UQSjbNbOsLT+3{#9 z3Q|#0I%!gol6rgNw`=e<I;&uO$7Ov0&!$!%Ai?r<m3gM(M8bSqAUQxMK!rj=LR9<Y z0!~QFFWFA&+_Zy&#P}ViLkbG$6YA2NTx#_>>YSHwI{4Djt)HA=YnMLtK3GJC{F|xn zzYC{!Ir}bh@|y=@VBFQBqVB#uN^`qP+}`2cc0!p@H`vInp{bdaoqaI&B_(C!OW=p( zkxTygAYye#M-K4I0#Bc)*r2?Z7e8dG_IrO3dWvEpd}bL7<(>b>+k)j~6ADp3Lj5u# zLqo&M({VM@?Vvsf{`{|BQNqK+nK?Nl3^@DWq2lJKGbd(c#Z8v#bnkeq_QjDKWw!(F zM?yha1*Aq*dUtmiDGqz{hMY>oCnPBeFE$~8j*II_RaF%;JA0T^ZU{hikX4^n%l@z% zg1}5lN{RwG$X3zv_7ULNiRc*^Xutz&Yioi*w+&NUiiH|TNJu{WV(lQk|NQxr`0-=d z>Z;lL`g#tKMXE&vV`F1*a}{rIfi2EMS3rGy0s`h17DxbCFaOrJg`4-sn|gQ<a;Ib2 zPnCO)EEyOY?jIS1ON9avg9mZhohY%To8cpi6CPDzBygH<IO^H^;nf`2XUn9ZOU!8y zGQQK(<hfUA-j4$yvU`F5#fwnD&hzcT!NZSQY~Gl;l@w5Hqx%+@prGKvtnCT_)_~ii z{^@#W>ObS-3#|cwnzFL8nAzAeE-v3c+5?moAmLVjzJ3KDp9P#3dxkOugsA%a6+qE3 zK<?bq>936hVD;@*cJN}L<Ae#<GiGKqFa<DO>ya-qDk^dPCt9pegN~E4A%|FJVPQyM z@jSF2?gs|Y7K3i~k$sqI(mo_7C#9uDH8cnU-th4B%x!EWy}P?p3m9G}1(jaC|N3#k z_O=Z@J^eFAMida6tSK14?OY^S+dDg*3(elXhv$I&2*DD;AJ)Qmqmva2(Qt4gREypL zS$}xQ6%iTPD1I3_WgHy%(Rvs05w;JzajSe!tRB@VEiEErGP++Y)!EsZT1(J|i{QK_ zzbd5yZUg*P*1ku4f_Q3xroH`MX8&s~ZEdltvikZ|f~ZTO$nGlUhe+Tvly{wbw3_QT zK3^Zp1;mQ>`)g*o_WxUf5g&A6ZpD+M4$%nWqkA4JD^Z3*WD+WVY_82Vx`6HBiNH_( zgdDS{7eP}ym=Vvk_$CSNl+#GM{m&y%0vknw5t^58Nd2cl(B#a{B;w3ezUOmBXdVAl z+t?&>Y#f5(h7Rh{;N81D*Qo4qbc1FTEp5cRyYhB%)gmZ2Pw1-IRFKqahx!GSpWJ0L zc2D~HGIHF>J3PR;XzyTa7-2*V^Sf@<spki-zWz}0JM;$k{^}t!gj2sMTnNxfOV^+F z)bNXPX_lv7EZdHgVc|B%v&6-f2d<7GI<Ie$?247QE}S7`?RUx3(RJJ$K*Pg3?(fRs zzW5b$^`Xz(J&<o4PER4ut;h~bID}7+{=`jB{B1gqZ2aD7&ILJW!*rNke`%E%ye2mr zSzC*6(86;gk^SulzR!VZ2#@f49Z$Z)F}Z5oQw0Koa;mHmapTM;d6L%F4(se8j!`C| zED0H8my^w|DH)}hTzI|%{}k!9a_(&ng8Ke`IWBAT$RU@yHvb8~+MM{eQbWUv^#?}A z5H)enyB!rbH?A+iV$h0~4{`tg$%8yz5>ox*k=2;|V0O`*@G_9>uukHWK1a9l{f4Z= z(wC_Dd1frEH1*e$G2V+My*uN63Hu{iQ0+3ruj~yl+QX}@#gPG8I=;)j_QkL`^0mZt z()jrJS6Z*nR(0B&LO+v@@J+Q}BFZbe#eHCUcx?o4syS{bC@^Wc+6)523+^A))#2UV zZWRHpJH<TEF5Po@NYU|`3Tt0YZ^GS$qqK17WoA)EzkjcDs1sa^M=sDOS@wyBMl#0w zi(aUjm@n1C@$+Vy6x9d%+5K{R2YL|P9q&-TBoGrbt<BaRtkg~&C#4c27ji>(c4!0x z1fkX=_tdw&#@{b|hNsi)pD<oMkAyY^%$yuemUaU@b|HdD=@Ncto!uIeYCL>yV{hwv zcAON9f2+J;;pWNkM`w3eM6Qu71;J-4OIltD(|7g6D3A}Ag9GLEdTLx}%g)|CE`F;_ zdDZ2nZp-}WNWbL<E|4?s+b*EMnYv1SpNr<{iR-%g`?R|H=At!wBPp1K#Ko{YLopYv z<Bc;VOg%B6Z|i<se7~pBy=;4%B<tMAoDOwnINSgyEE3Z&JZ3p}aeBMSOPS|pW&{J^ z`T4~DJ^Y|<buHl_uV|}uOcN*4zK17zO8nk@i~t(=E%@Oga9}vdem1pl#dNv--X1R| zpP}A7a_@M4+@=<z<=T$w{{G;(ivR7g<$?9Xx}g-};clsv&Po^DTfEBM`p@?|%@T|0 z7NMY|QW|4Tt@WAST@|xDuf9bp{K#5+YjM0zgF1$#e)S82tE;i<MgHdpJ4>SqB6)ed zQSo2yGPB)hQU}C)dy$9y<}Q8qX|<)4;&S0ke*V_MJjdOUeKOy}0)`GNk@@HTG0~^} zYJ=UEw6z8Qo%{ROZ}F+*z0#rmt{q>|_kj83oV~vvN}LvUd%wL_YyXM^NlE#V|3yk# zsJ&WOBtS6m9x=uevEKP&<XdFlic4No)70A0fILpYsg70kR_n&or&-lO_k~K7R0+1c z5-x{RWe!(|DUxm>xM6;>5qptsZo411o~10^e#MZBw-9sv6QwX!;l0)u=akSNd<d2J zWyJpq6gMLZ=0PVJtRQ~Jw=Qq*4)$K~^9L5!C?emkGqpUQF~-J)K3rFfQ<qj8bk8|Y zEl=v4SOqw#3`w`#IA!&(-CRI@dBjr!2%DDz)eSPY%u`ZCFYAMwU#y+<^*df3B_wpO zqy>p*YX6cTCUCy#zc~;9lEt4#tfDoLF!)4(ScEDe&NAnQCu?|;;G&`ZZVpq>Q}Ll^ zYoT2{jQYNk(Cg+@NkF5-UW)cu4eSKe*ri;+GmY<$@q^B*lSxRc{AvtarsGvI7G*TY z6XoVUam2i0KrhVcxH)cGdbm%$+<5-H)9x&j?KB~{C1!taseik8tF7Ai#7s*;X(!!U zq&<x^&I@b|Fg@D3cD#WTn=ofmFRZS4^5o%mM5oGg&%eQY#C`Us<6KLy!n22GFUaEP zoLi1iM%Dt9{e=&kmwb&;^-5poRC1w!c-cM>05ZjBzH$7(bFP4X`DSS=J#BhoqG9v; zoRL;4uB(g0!dfn`){_J{%EtCctXoqO;c&>A(=4~fqU{#H;f1vI7cJIM1J3Z?<1qBq z6|$w%d}`N#@OHnuvne^`_OGgo42(^~IpqdN4&;=ztG8GDnc_?QYxV;h<xqa8VZiaR z0nabrH;IMqOJM{|`Yx-mU$GT<6u%4kdo2!(rcOH-|HeWL-qBlQoQ6P_8@EWd@8dyP z{65BzdbHVl>)xOc-{)L!i7Z6{b1&W6;8(eq4~|jLH~B%5d+K<)lU5pCJ~CZive@u& zQ+5%Gd^|i7Ow4y#Ct=r5!x1m5#oajuRvjHf(!(O5OV>nChFGv}siYSo2Q7ezgaXd^ zG{c*2b<r}RHAU)&#)LyqoAYeS5L>6bL3_>r&yS1*e<Hri_F--tx!)ZF$@M(QsOG#P z^OUE_?Fo@#9V{Cz6vl)USS`0d><v$onM9rA0yANV4)bXL7Wa2&=pI1ULK_>)bHrS` z&amg-G$_$a=%(#Kn}S4}=Tk9D2z_YI5$=`!DIZLyqgd&?utxITAr$h-*sDwk#8v&; zxY27n$&<x$vN=?wl3Kq`odTLQqVEgnPZ^l<pEDp!ySifeQdc`sR+=G?jzT;<8-pUK z;&QREJQgJJh_}c-l8@*W%7jBVZbz4wb*LvwsMS?Dt6OZaP}Z{qLobEB=M#jU^+I7e zlAl9LtB_sR8J}?)y-g$08Nr2g?1asmh5oS#o40t|W%1U^hh#Ps0SOyRLYOP0BbP?r z+IQDkhnXueEvoG!q4$8WkLlm7H0AQidBKucAJ?4BYz$2II}3l#aOGbi6Han{DQpAm z&*eJI?VS`?Lc9ubzCqtq!4;sa^!U?StkW$E!~%`c-JufiIw_AOq0rIu3+cHf+_UXd z%a@kgY<bio5~ul?jRbC2IyBjtv7KQ^5iPjtrH114PGD129N+(d>NuWSE-{s6c#Vdp zSjYupn4WHYv*fB+SRU$bYPzl0=%%01XCh%?&qjOZ2irYEqxdW)AQdtcQM_pd;}d|o zga_!zqRhIvjW(MhL%-PIy_kr;l~^8qa-2Xd_dV5rn$d!r*J&=I&vA~6=FM$F%?o;@ zG8!72K;DF6KZ_p9!=$n@G%}L3x<D{y&$S=@->L3z+WF=~WHlS>IpQqQ@5G~sNTjm{ zB9W&Z1{yrjNmHNGbvRwv9Q+)R7z%}w5W8S-X}WODy19>i%D{xEC&bgPzUq+MJsUj_ zt~E>RvXGh`%8+mNC6LX+acpd~nXN>y8a7w1c?Nc!#aQ8R!*xpW_>TV6WkfEpmAd;5 zRkW!uFjS#b#$Od@*4+&P0dAH5Rw}LGxL@-N<@1WE#ivyB$rLu5UxS^k9B;Vr&rVY| zqqYYhhhwxcfm~TyM%mgO+hipEa;+~$i+fYoQH5l<kNKEo_1^HF{VZX;zcbMVv-<SB zyb^r;D3C-|<!6OWWGs`D+lEz$7yQn$&VEfDuL-W09t2sRa6q|BCj&Qk_q~1$e`lZg zw}hLo$|T{5Y0f1^_3r4Xc&44Y>H=>1S_YX`|INbwn2Ji2ligbyexgZKoE&i>y$-wR zTU_8jRPefI7wZZ(5u(IKq;XLaXPxizUiy0~7H<Fi4b!n=loA%M`j&@?Uhmw@)Qi3Y z?;G}Bl=S!Fx4YPX7cHPeFoYqUB`?t#7&!2p&3);fFU2soBa2elC3u|i)e;InA$5X% zByRq&Nykt7sYI`nuQ&HMU_E;ln<JZLWE$#ytCtMip5bGN)4&iD_1FiRToBmG4Nqn# z+bBlV<3R9%iChRcN)4B2%73pwU2bAe3f#of`1Vcx>Nn4}lFHKt4cet%btZi?1y9cb zA>TjdR{Ri>==V~u70|CWG(NR)QJYTexa=RAis-geAzNCGo}EG<Z&6UI?piNK)eT~s z-_##ddDA`z3#9~`nu~e+=Z`J4n{no&;{0MGfeN{Ro9jop>*QqD>)NSAZM|r|tzk)1 zUa3`=XE&#|VYT&ZeeNSef|DF$Zau&X3%6=gy{!@R-m|?grTGf<HbX-)3yZB>sL1G= zIk@hMg+7%*qA&k`?~G6rlRV9zyImzCuezykm+2kLCy9^7Yfz*GTV+i8?5a#3?ClcW zuWN3;{40qtH*+a1K!PeLAQEmFvy)+Sf-RvR!`c12F~kT(1d{LGG2b6N^p!aWbc<R7 zOZveGNHhxz%*-4zKK{*e87hTRfvzt;PnDVL+)xNI;Pd{Q4G#@Na=2V4U{+>Cns(3) z{zsCDAMO8HKW`&8SG6XDkdfeTrf5t}h5(K0%OU|q`q8bee5VmAT|{U&i#n2@c6m?w zlu`Gl_$>mBsA$M|v}bl8N~!*S^7tk`2g4V}Cmcvc1SR!OrVkatai`=0B8Y*^oH*9O zm(ugMn*yZUm?k2;gv9L^q8A27f1=SH?zibGMCo9^(517s?J@TM!H(vf^AAr(a(T&$ zYW4WY=KVHFGw;R{xY81zsfVvxye@rpfBcIC7ad_)f6Qs`;TG4UwG~lEmYyQw<(LRd zoGf9`5%T+`Aac{Jtnt}Qd~`7R?xXAnilOjum*X$HGNym*9!G#L;)V}~<y|aA`dPr1 ze@2A??|-I?9*+h#S3XR&%i38M%IVygNFffloRc{Pu8~)Mn?!uw7!VsCnSa~76s}T& z1Syu4OET7Gba@TyT9y#X6GC%#mXow)k!ordon;RVEuO1Jy}k_?_Nwc_s;Vl!Jg<KY zK1dP4kvII==6xVeX1--)t|~9)&m-6M%$MOGKa(w2@th2zYmj;EuVPsv`lWq}`1BUB zV6h1q0@k#5F#Dd6zyK-Y6CQjY#*-*WA>Zx_wI9xUH}7z6bD*Xw3xYo)KOea`o=T_Q z8h7<zJ`?~RKws`(zs4%<Q%5cFI7oq?2w*jJc{w!`dp35}+A*`O{z5C!2~~Eyj|PVu z2OvNO8Ujem8XHM4afuta^9q4){9^4q2pfx3X-ew;<`1!?tlsy<HMF`j{YyZxN^-W< zYbGjr{Tgj=`;n#2XQ~_g)}tQZ2F~xs=<p+<Y!yZ_f5S0Brc><)mXs8;vUJK@6hJ1& zzAMl_et|FD6G5KLO{1mvc0D((VFw3(5Lj)^v-TQ705MdKUzbfL;B%4Z{~Qol^RGzW z$8@_WV|j>*qE*h}O-&CdF+4tEtEZU|`|O|x9blVJjSwQDOYn)+{7f6ASGZKj?)ILI zaWzWQ7b=K^S)izN)+gkMmmEqU2ETtRme}l#Nz^N&+Hc+2DHij20`w1}mK<iTs4)4A z^)T3%rxpq6vRJi{p!dV_)c4BE_?&30jk4bnB9{ROjPK?m-~G%ESQgGpMfSe)(kIN* zOX}r|(1vF3+~>?sn%MJXdew_8rOmk>t?OB8TpQa=92{-1#Do()HI?Ed&UvYiML9DA z_q`(6+auk5d<(v4$wGYWuhb;p9ehLw{)BV*>r!?1Wk_FF7gBLNk*2j3qnlbL1hP#f zM%X}>*9&t0RZOclu5W(=osG+Az9Y!9NmSfC|4CM0SfL3PdZ;FAc+X0Rn*$bD5LK3` zD%vBn;$&uI9Bi8Q?^u8}d}~w&HX528$>EL*KYcr8hFOw2C<u|x2GHnLnI`h{xpqCI zQe|pvd|-61&?{#Wfo0sB#t{?$q2J%Ivrs5kL>QVnC3+_z#XlosLs9N7b*3l%sFV;0 z4&Gxgz$^3OWE(L3cP#`=IWI^=W@Wp(Uj-gM^V9kMB!?USgF>n2gBU3sW(I)0y@--T zB1n%E_*!K49|khqX(`@6L!cY)$ukL0`kIp5a?|4Effo~l&V%2zEsR>CUO#;bsMDv$ z`@7z|&v!Sb7&t^ZFOQ#YvOGM9XfjoSR~swZ*hnl!6ByzCp-W0C=49#Yp3p*Ir8Dk^ zd+V!`?5^v)y}3>_)_-68i70^|Xv8^TuN>PoS+CmUxe0ZhxOfa*^s&{)f&LH1TKtsp zm_w#t+#pPdT>Hl{b`HuNicv(=(pdpU8jc)pYFWpApZF*!<Gy{sKV@RVR42W9XS;9! ztV#ldjr=(~2gyi?S5`*l$e)6N-R!l}d3}~i6KiFm!)mI-N>i=-#H3o%iNE`+2D%~9 zSe^-ZC@Et|*Bwsr$9X=aXC-ZsIY}ZrHL?j<fsRG^RpMB<Z`lOt;tavXvy*2+;X9a{ zaHeX(#Kg0$2^Qx5e$mg^0FXf5Ntoq9dXvO?>}%obItlS+ytGow@1uxNf$386-U1kk zN_dNl@G+~`rDK3IH$C^3KgxsfyUlX_Y0@}4thxx7&jX7k$)e2oUC5uvR=`<m)kD?Z z9q>klVNBCPv+1M_(znE(WmCVG8sAD0AV5##yUy{4veD{OfFKX+*@68mdov*Bj-r@9 zmLCXI%<D)TQ)W)pkX?C)ChfAf(v0r_q}b>XBSuDWQIWBF=)o}Kb5)f%YpMzCm6Y&i zXLiP{#%$Evt#S1+Fd$yF<A_ykDccHaat4n(_N(F-bq;t9ta;)6>O~CT^d||lP-v8X z3+Zp3E!5y8Cd$igAknVX&%sdm4fxqL(oaenDxC$3&Q*<3UG<>d-&A>=7)J77e&Dkg zc)+;MCj@j7o;3y@))o!T%iS-9b4jT-XLsqr@u|Mn%KrW%`O16O%Vh{Lqj~yY<nall z8t&I@J18>vjgRBqY&!%_Zu|nl_aCDGEXd@NkxLKnjLVmo9L-KH)|f(_4rY-vG+5Nb zYba{J8}8wpon{D(Y3N3+Y}<sE(&`I>7pXsDYPqr8->Z|vj3I!jEG+-QRIQHyQ{ARg zl0p|xJz(NK5Ks-=uJyaF_%9Iv7((t=FG405n|=TGkH)s2zv!&8J_itV(*COPkQBVY z!s}(pe|IAfVIF3PNgN#VAYJ-D^F8J~kjJOBC312}?#J{Wz~0g<1p-1tyDb6y-!wwA z6pe%@Y&=dD_LwZ+o7|8giT=m*O*&;=VFsKomM~+G37aYa51&qz)9iI253my@oJZQ) z0*hBf=GNVv4yHp3nqC4n1+J7`AvRvVb{}!=V7wBIcsZn`<<4{b>*suog|g+uj(T&j z_{$$Zkcwlscm63d*j>PTfucfy&`<vDDjv@bx^N0*qr3Ja+2v&d+I;<sNOV{PN&>%} z1O)Cl^HzASzM3sL!03$=Cn#V3L#v>iiewQa!TnqD$aGic#pB=QnHVc~e?A4mUfQbG zujb;rLG&&Zm5Ydq6HN2OeUE%8#Lt89#l-;>0t_?3z>(FFjp#_h8%ogHMjW{4<>fP7 z%5bK=`AwQ2L5+*un{p6<nrh@19jY4C4~TO&i4GqAjvfb<|NbZe&Doyd@x7+S;{?cL zSkuQVk<;h*H;*OIUw)e8mGj{&!K?A?JT@N99E|8Tv1X}IrRS~dMztIrR^8`I4~u-R z_(|EO7s9@P36or}xVbqEK{>WLwg^JtGZeMKgCRPCf$Pb}(jBMQ9o$<zJ^_?V{nu*Z zGV*G;z<uGGKToKSaj`r<GuBn%T><iNu^GsBWM{{EBoFHiMSzd`2Ik=4?qt^f(L8u9 zhPJkr1W?SSa`7%_633WWo`?`6Y#iEyOIIN8x5oHsQrDbb;gQulgi7}rM)dqD9$%Tq z4GQth4vz1UOJ<Sb6EMGU4vyIy5seHjpburE|4f=N`pW=Re7}#~EDRbEOBUc`i|Hxh z0LB|(3>@SHZbId)hlp4&UJQr@lHnH-gi1?KpA8F-Zf)c`9T+`oQ_kc8wuozPqTnr@ zW7W)%K9fTm^8c=CwpG-KbGT_&_?#9nq&;}~fnt_2<wj6t0(b<pLsZ178E?fKR3_^j zI_hq9<A|EOJ5bU{pT0w-a`XyE^!EDKai@~8jE43k=OyjZ7^rJi?@x;cgk8H9C@Z+q z)ekpP<x9Rj)*UDW_(<g+w%M@GEMZo)W@o)Ix_Yk=c6!3({QswLViD90*^LTF2GB5N z<b%M0j115sysn)Z@?>^0e6@b54=@s_kNb=`j?uv|v{h|XjZA7%qTH)v{P<799|@$e zfIZL@7PM-rPo{czl})#HYzacO+4&;Y&Q?-O2@`n9X1)%aQctf1IUcE7ow#wiO^op4 zC)yu{z4=35wN}r|4MEu(ib|8G=YoW^Jbb<nidRW1Um;L=%(of=SwDT*FHS4WO9-+; z4&=&jNl8Q<<zI0<HoWmIM}6e_xtO`(4Ar`cp7$c!M$IVE-7i{S(MsAoaqgbOHzXss z?LpaXW+{XGhm}qA6SWtpDOHrD?Tx6KxOo}}@Hm?O=j4a>qt=_4dCj66GRiX>o}QkZ zZv|l&bNC#PWFSfdZ(KmVyd&Ub(pzf}!WQZ>L`OY75tjCqaXLlO!@@F`jSdQ6ud+l7 zQAZUh24Xxz=jV@vH8#8ZAHo8HcaNXKtCoO+xl}(6<o?>?=8(LDjf9&DHc0=D9i-)5 zAtkVMim#u7LIFs0pR~{KBTGt1<Q3l<<~}*cPPE~gkdbiWHy>(r2U5G+UdLZa5@FZ- zU^9#q7ULkr87U@C4HUjjL}U_}%KB%rizr`6qF@%<{;m|DtVeZ3_Y4B+^2d?eCbY2V z>0LHuKMTNx?*ENhkO&p2H8<aWC3_#U7FYvAe6j1%@J1^P)W>L`5W3A0j&ib<l=r@< zdA<Z>Dy*iKCa(+|^bde^K*1*%Oa1URcUm`A7S=(6-xcj-qfN3K#9GiyZr^^3Z%Ro? z<)|Hpa@OpfZ@I5eg%%aip&lR-vAXsOS7$^YW?#CeE!axcv}oilAiDgyN$6W6>8qh3 zct7L18>n#1>1h%3HG{jlg&+xE!I>8+pb<bB1=`wD+#3=Qh-x$vM|gPgQfmgABHk5q zhGIB877Gv}1oBaq?r~>GtZ6CGPUo%wl7S5r_qLzkR{_x2H?{L9Ltp2IZj2?oF7tW_ z+|A}MbYoehMUTpbTW4ypOwiF$g^HymhP-*?S#maYOBgRTQ5*^g=Iw!>h>ryqUf~p7 zOBpt(3Lba2`1m*P23465u~Crx^x8W!c*L*qz$A&kc^pe(d5UWR!JL<oK~p;ibP;Uf zizujOq5tfdj{U95h#ZB4K;XNIGYVwnQj&z!wFl3tjV|X*v1Dh5y|e61$c0A&vF+kL z#}8^{P&xPd8%4v0ziOC1ZnY$2St?QBAYo%mii%(rj-iDQBK59kGbZ<&V|gB#7vGf3 z343E0BI2R{W=S#Q1v{!MD^jUaVsEPxLHp_db~^t5ZS<69z>k*UOvN-r1#PQC$p)N} zFxo2leJ_7QW#!n>v&RNuk=~x34yXDlg%rh&D{vGZIf@MK9lHf5)IuK>H+)MBINLvG zW{R+TNItf+iVqGBcDps+ek1HC1T7#+78V7ge2))M$jHjl^6^a~E`J~lc~z*<>I0f} zz&SWx6F=zf`OFXvdkb1B$+TD}V<54~^)*?zSXj3W#l-{67Osy2`-5hrzK)KL1cXdf zNc8wlrh{h2(B|yVpFc0Ftw+95;>2fxX5C{MaNgeA+xr!?N~)$PreJm;DdT!V)H9U7 z8k5HL<x>aWR+ZP+>m-^zHvTq)(|ZabHw)eTv48^Y(%?|JP#m9#>jK*3!Bf;$ql!O! zXHB4$*A}!0{`0!|@KgmD67v6Od@fK&h46(qf`-s!(ESVAxqf7+7U4tW#(@Jku#13i tr}xkO3N?IHIa7_1UC=d$hl{QseAe&#%%wMkKsPx=K}Ho;E@krezW`N4SIqzb diff --git a/doc/reference/clutter/animator-key-frames.svg b/doc/reference/clutter/animator-key-frames.svg deleted file mode 100644 index 613ecec64..000000000 --- a/doc/reference/clutter/animator-key-frames.svg +++ /dev/null @@ -1,271 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!-- Created with Inkscape (http://www.inkscape.org/) --> - -<svg - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://creativecommons.org/ns#" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:svg="http://www.w3.org/2000/svg" - xmlns="http://www.w3.org/2000/svg" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="800px" - height="600px" - id="svg4624" - version="1.1" - inkscape:version="0.47 r22583" - sodipodi:docname="animator-key-frames.svg"> - <defs - id="defs4626"> - <marker - inkscape:stockid="StopM" - orient="auto" - refY="0.0" - refX="0.0" - id="StopM" - style="overflow:visible"> - <path - id="path6098" - d="M 0.0,5.65 L 0.0,-5.65" - style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt" - transform="scale(0.4)" /> - </marker> - <marker - inkscape:stockid="DotS" - orient="auto" - refY="0.0" - refX="0.0" - id="DotS" - style="overflow:visible"> - <path - id="path5993" - d="M -2.5,-1.0 C -2.5,1.7600000 -4.7400000,4.0 -7.5,4.0 C -10.260000,4.0 -12.5,1.7600000 -12.5,-1.0 C -12.5,-3.7600000 -10.260000,-6.0 -7.5,-6.0 C -4.7400000,-6.0 -2.5,-3.7600000 -2.5,-1.0 z " - style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;marker-end:none" - transform="scale(0.2) translate(7.4, 1)" /> - </marker> - <marker - inkscape:stockid="DotL" - orient="auto" - refY="0.0" - refX="0.0" - id="DotL" - style="overflow:visible"> - <path - id="path5987" - d="M -2.5,-1.0 C -2.5,1.7600000 -4.7400000,4.0 -7.5,4.0 C -10.260000,4.0 -12.5,1.7600000 -12.5,-1.0 C -12.5,-3.7600000 -10.260000,-6.0 -7.5,-6.0 C -4.7400000,-6.0 -2.5,-3.7600000 -2.5,-1.0 z " - style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;marker-end:none" - transform="scale(0.8) translate(7.4, 1)" /> - </marker> - <marker - inkscape:stockid="Arrow2Lstart" - orient="auto" - refY="0.0" - refX="0.0" - id="Arrow2Lstart" - style="overflow:visible"> - <path - id="path5943" - style="font-size:12.0;fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round" - d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z " - transform="scale(1.1) translate(1,0)" /> - </marker> - <inkscape:perspective - sodipodi:type="inkscape:persp3d" - inkscape:vp_x="0 : 300 : 1" - inkscape:vp_y="0 : 1000 : 0" - inkscape:vp_z="800 : 300 : 1" - inkscape:persp3d-origin="400 : 200 : 1" - id="perspective4632" /> - <inkscape:perspective - id="perspective8086" - inkscape:persp3d-origin="0.5 : 0.33333333 : 1" - inkscape:vp_z="1 : 0.5 : 1" - inkscape:vp_y="0 : 1000 : 0" - inkscape:vp_x="0 : 0.5 : 1" - sodipodi:type="inkscape:persp3d" /> - <inkscape:perspective - id="perspective8086-4" - inkscape:persp3d-origin="0.5 : 0.33333333 : 1" - inkscape:vp_z="1 : 0.5 : 1" - inkscape:vp_y="0 : 1000 : 0" - inkscape:vp_x="0 : 0.5 : 1" - sodipodi:type="inkscape:persp3d" /> - <inkscape:perspective - id="perspective8121" - inkscape:persp3d-origin="0.5 : 0.33333333 : 1" - inkscape:vp_z="1 : 0.5 : 1" - inkscape:vp_y="0 : 1000 : 0" - inkscape:vp_x="0 : 0.5 : 1" - sodipodi:type="inkscape:persp3d" /> - <inkscape:perspective - id="perspective8143" - inkscape:persp3d-origin="0.5 : 0.33333333 : 1" - inkscape:vp_z="1 : 0.5 : 1" - inkscape:vp_y="0 : 1000 : 0" - inkscape:vp_x="0 : 0.5 : 1" - sodipodi:type="inkscape:persp3d" /> - <inkscape:perspective - id="perspective8198" - inkscape:persp3d-origin="0.5 : 0.33333333 : 1" - inkscape:vp_z="1 : 0.5 : 1" - inkscape:vp_y="0 : 1000 : 0" - inkscape:vp_x="0 : 0.5 : 1" - sodipodi:type="inkscape:persp3d" /> - <inkscape:perspective - id="perspective8198-3" - inkscape:persp3d-origin="0.5 : 0.33333333 : 1" - inkscape:vp_z="1 : 0.5 : 1" - inkscape:vp_y="0 : 1000 : 0" - inkscape:vp_x="0 : 0.5 : 1" - sodipodi:type="inkscape:persp3d" /> - </defs> - <sodipodi:namedview - id="base" - pagecolor="#ffffff" - bordercolor="#666666" - borderopacity="1.0" - inkscape:pageopacity="0.0" - inkscape:pageshadow="2" - inkscape:zoom="1.4142136" - inkscape:cx="175.65326" - inkscape:cy="447.97925" - inkscape:current-layer="layer1" - inkscape:document-units="px" - showgrid="false" - inkscape:object-paths="true" - inkscape:object-nodes="true" - inkscape:snap-smooth-nodes="false" - inkscape:snap-nodes="true" - inkscape:window-width="1208" - inkscape:window-height="677" - inkscape:window-x="238" - inkscape:window-y="162" - inkscape:window-maximized="0" /> - <metadata - id="metadata4629"> - <rdf:RDF> - <cc:Work - rdf:about=""> - <dc:format>image/svg+xml</dc:format> - <dc:type - rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> - <dc:title></dc:title> - </cc:Work> - </rdf:RDF> - </metadata> - <g - id="layer1" - inkscape:label="Layer 1" - inkscape:groupmode="layer"> - <rect - style="fill:#808080;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.87221748px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - id="rect5408" - width="500.12778" - height="262.3963" - x="4.9361086" - y="4.9361086" - ry="10.774727" - inkscape:export-filename="/home/ebassi/Source/clutter/clutter/doc/reference/clutter/animator-key-frames.png" - inkscape:export-xdpi="90" - inkscape:export-ydpi="90" /> - <flowRoot - xml:space="preserve" - id="flowRoot8172" - style="font-size:36px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"><flowRegion - id="flowRegion8174"><rect - id="rect8176" - width="41.901608" - height="54.149387" - x="103.94469" - y="50.578033" - style="font-size:36px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;font-family:Sans;-inkscape-font-specification:Sans Bold" /></flowRegion><flowPara - id="flowPara8180">0.20.</flowPara></flowRoot> <g - id="g2899"> - <path - d="m 114.32613,193.09673 c 0,0 137.26963,-81.90085 137.26963,-81.90085" - style="fill:none;stroke:#d40000;stroke-width:3.75110221;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" - id="path8109" /> - <path - d="m 252.12133,110.67031 c 0,0 67.50359,0.8371 67.50359,41.25377 0,40.41667 65,41.25001 65,41.25001" - style="fill:none;stroke:#d40000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" - id="path8111" /> - </g> - <g - id="g2880"> - <g - transform="translate(2.1213203,21.92031)" - id="g8160"> - <path - style="fill:none;stroke:#000080;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:none" - d="M 35.001966,80 469.1647,80" - id="path7312" /> - <path - sodipodi:type="arc" - style="fill:#f2f2f2;fill-opacity:1;stroke:#000080;stroke-width:5;stroke-linecap:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" - id="path8072" - sodipodi:cx="129.16667" - sodipodi:cy="80" - sodipodi:rx="8.333333" - sodipodi:ry="8.333333" - d="m 137.5,80 c 0,4.602373 -3.73096,8.333333 -8.33333,8.333333 -4.60237,0 -8.33333,-3.73096 -8.33333,-8.333333 0,-4.602373 3.73096,-8.333333 8.33333,-8.333333 4.60237,0 8.33333,3.73096 8.33333,8.333333 z" - transform="translate(-15,0.41666667)" /> - <path - transform="translate(120.83334,0.41666632)" - sodipodi:type="arc" - style="fill:#f2f2f2;fill-opacity:1;stroke:#000080;stroke-width:5;stroke-linecap:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" - id="path8072-1" - sodipodi:cx="129.16667" - sodipodi:cy="80" - sodipodi:rx="8.333333" - sodipodi:ry="8.333333" - d="m 137.5,80 c 0,4.602373 -3.73096,8.333333 -8.33333,8.333333 -4.60237,0 -8.33333,-3.73096 -8.33333,-8.333333 0,-4.602373 3.73096,-8.333333 8.33333,-8.333333 4.60237,0 8.33333,3.73096 8.33333,8.333333 z" /> - <path - transform="translate(253.33333,-3.4057873e-6)" - sodipodi:type="arc" - style="fill:#f2f2f2;fill-opacity:1;stroke:#000080;stroke-width:5;stroke-linecap:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" - id="path8072-2" - sodipodi:cx="129.16667" - sodipodi:cy="80" - sodipodi:rx="8.333333" - sodipodi:ry="8.333333" - d="m 137.5,80 c 0,4.602373 -3.73096,8.333333 -8.33333,8.333333 -4.60237,0 -8.33333,-3.73096 -8.33333,-8.333333 0,-4.602373 3.73096,-8.333333 8.33333,-8.333333 4.60237,0 8.33333,3.73096 8.33333,8.333333 z" /> - </g> - <flowRoot - transform="translate(14.142135,33.234018)" - style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#f2f2f2;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans" - id="flowRoot8182" - xml:space="preserve"><flowRegion - id="flowRegion8184"><rect - style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#f2f2f2;font-family:Sans;-inkscape-font-specification:Sans" - y="27.950617" - x="83.438599" - height="36.769554" - width="59.396969" - id="rect8186" /></flowRegion><flowPara - id="flowPara8188">0.2</flowPara></flowRoot> <flowRoot - transform="translate(150.31407,32.203619)" - style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#f2f2f2;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans" - id="flowRoot8182-2" - xml:space="preserve"><flowRegion - id="flowRegion8184-7"><rect - style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#f2f2f2;font-family:Sans;-inkscape-font-specification:Sans" - y="27.950617" - x="83.438599" - height="36.769554" - width="59.396969" - id="rect8186-3" /></flowRegion><flowPara - id="flowPara8236">0.5</flowPara></flowRoot> <flowRoot - transform="translate(282.54304,31.496512)" - style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#f2f2f2;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans" - id="flowRoot8182-0" - xml:space="preserve"><flowRegion - id="flowRegion8184-4"><rect - style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#f2f2f2;font-family:Sans;-inkscape-font-specification:Sans" - y="27.950617" - x="83.438599" - height="36.769554" - width="59.396969" - id="rect8186-4" /></flowRegion><flowPara - id="flowPara8238">0.8</flowPara></flowRoot> </g> - </g> -</svg> diff --git a/doc/reference/clutter/bin-layout.png b/doc/reference/clutter/bin-layout.png deleted file mode 100644 index aeed4d6a0335a34ced6a157f49fecfff95442b5e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13424 zcmeHucTkgW*Jcn4qQDOo1qnq3fdGOu>7a-RNN*xtK$`U4u^@sFkg6a>kQPb=q<0h| zU3w=%=mBDY&_c-Gao=}mcV~8X_Me^ao81fseDajLoO7M)T<0WGTT_LO_9`s|0-;lV zcwZL+IRS@2s5WU%gCmR=VtBx>lb-if^=ZH>h{onE_&<x6@?$SO*Job7RvxwxI~P}H zTR~524_jLoPkUD{9Cfoi1i}eXy?<BV@6*PNzn{V4XB-|qsps?H=c5a!Pn|q@=6?Ix zHLtrST9xemQqImJYpW$Fl&4E<dU1Z`q5Xz+;6^2(Y#dt{;OvStzz!Rll-!UrKyXIA zeRPlW?6uCD-}}BUS8j61aB{}^@)!s5OrZO>*Lki@I5i3-y%EBta)CkqcdxKA)YW;c zQt(L#q~*u&^MnE4w=u;XZi7DFPrzBsdT`iw5-(dMoQs$h3+G~kL8%~+xX_ns5!r%# z-oI2#B23(SCU?N8!iJY%Y*C#g`6sV9*i<j`gO!5B4f4ZPRn1k;27midgZm@?-wvJ) zmc6>sYEdyy1I|)ib=z6P46GO&{vuoxf?KsSf+ZrK^tKes^ZH#2FP1z3fhg)qLvv%Z zZ%gfO*$eX;yMy6|aWSp5*gxWBiwXQbu(jagLK&~pk(v<fFi{?f53?WsEd&mQU1OvS zMfe`&HZ3%BlqcSJeFMBl|MMUCgZXa4$+%#+HUA`=E{wgKpbvpy!tQ8i{a%0>U&d-2 zz}<S3-j~u(MAq2&FPyvFY4lIx*m8=1dbvP|FhnuK18U*{?Q~C6yO|iRoD@yZ%M{B8 z?qub!QJVi2dIP%sYt~)>QJjS8=AeQorrP>*@sn!%u?fg5Z6Ei->**WN+?QN^?mZ?i zvM*#aLWH?u$9OEh@{SF)FyED0;ENS<YeAOSJc`;?Exdmy+<pv|c_&H@sablMf8D>) zLsq`ii1Sp`V7|}>DY;qkEa92eOJ*z$N_G(+ypuVr*0HdPJ6cH_z3aO4NyR1-BYF6P zNB(nyrnKtbw5L|blvbLA26)}bP{||K;+lwFGu~q{_B{jRXN0f&z)0ZwABVOn`fBXR zFVy5d#Sj@uMy^gYvt~zy{6!lL3zLMXBCIXlvEm=)x*>kJBD|3>YH~QyACl*d9bK&) zGuLx)aL`;D`1LC*Ir;L~EN)ajY{2GBR1%C=H8exbk#iUkKj|Qq!8Glq{}Csm%BV{H z3VBSDk9`=mrS(>}lAJWej!Is%GGMIT+sDLWx4MOl3=EPo0ym|CkGC@w7Kr8ntK6h@ zI|V(lt0Vaeq}5=4Z}4&i?u<uqAXkU-iwX->yHkXWTwRf)NDCp=y2WIZZ$Sqhf~Gav z=PnCqo0z1nt*v?O&G;4}5RPc(j8?Li*qu9ACktX~mCFp`&70G~%QEPJ)%?sRTyW;m z0uT4!`xzU5%m~`*yy4<oP|M-Mp?J&K=U!oBrsu-hSC8F$l!Bc#V5J{nPJfP)EWfE= zUcP-Dl|4|9EMS~HW)W)U+JJwv*+g`aBkc@D1mPy^GD{-Z10IUn_34XUH4tV_<Qf?r zMU<3iR9037EG8M*OjY$Mkb~ri>lM-m3kj7Ti)u4&-{}H~8`TCTCPnEozKE<WMKFiV zSw9RNX)C2!)>0wf>tHbj8^vGxEBuOi!JSz@CGaoj7<>p7&Lp9m$L6Y79XDGZ&pl>W zezmyT&!$4!=q;AibSsu@dm9mW=jnOB<AY`IKB;A1=JSrLgSmCbhuD$n>0+>|q3eyy z8G)rPHFKwDyoNNSw|hhx_Gf34+Awe#&8qa{GXwMO@3>Vn_kZvV4-S^&<if+l<G=8i z*4$G#=+xQ`4knWt@ExoHtGOw=!87H>)U&>Sh<no0J~utjbi5|rf|nI5m55&BV1)ZS zk~vP8BbPBoy41$ID><=ixhdv@$PhwNutnf{8EU7*H5hA+BOUKGBdccv)P2#x)#kwj zgW$b-^vqskBYqL@N56mcki)v{!^_s+*S?p1`EuWBtW@r|@a|_QG&o|a&t?-~DqfGa zJds}2yupLu=;}Jw5yJ|$Ag`}a)7!^qO)K;;fjxL<U?+3n)oinE_vLhtF1|Wo>tH9k zf-TU*SyHu>ACZKv@WvVvc6L^XXmZo7n%^&jarlFvwG9n)fXzg??O`iJNS2KVpDJzm zJ&rUjGqd#6)KvQY$+;?->1l>a2JmpwWVe+&6)>TbMbMwMD2`B5BXj>;T3XuO;EiuX zn!uk5XM?si(%m~)&NPraSY7q4t#hELfpp(l|DQ>1O2HeyEi!#39bhonAZ6P*j((pZ zHih(xkJ)#|bJuP6$#?^!!D21Qb()fMCzFzr3iI+F^ve_1sfhJ!h$64nQ&;Q<vXuiC z-m7q}ew|`-*^HPxBW$?N@&2c)DKsJCa59x%vbFXewbUoNI96L*TiS^4wHc>{^Ssw` zcsig*zGrT---5qjG=#oK?pH9Jf5GbVoAdRJ{qBqY?-YnF|InyFU%Q<Q^}jBpoHJmm zMFr_#Yh$ED2@p44x`Al(fJOy`i?Hv%xm2KU-A?W;gJ|;Lu_Jg7V{8Kfi*f>ZXTC-W zke1+H|Nn#kza;->#=zMx1y2~mP(ykc;ffg*0{plR9z!ZiKN=Oz{(m%TV{IYKNXp*} zu+%N_$J>NGI?Jcmp)X|Puzv1P9#^A-t$!an>mqR9q!e`q5>4O6_~G|k2}q0m|1cJd zQXYuqy6P^0Z*nmEu}NAyiR1xQY0AES3Q=S*{)?0RMKxYMqGiL+bil0s(oCg#=dAfe z=a+`otfR$6*e7X&7hP(`=16|)?kXl{XM-=f%8?oD6OpfFLz<5gZt{))%4(~V?!*i> zS38^FH(iudQ!nAx^<fv@FXDe1JwaGHm%P-=?_xb)Cn^D9z7C~YPgq&iL8%Kl^jnY- zFE*x_7{U{w%yCea*|vM9U@(2JVI7zPL4QQRB=6<qq|UjY!!2QTMo2?cw@{Jq(9L!q zoMAaqOB2Seb+@(2FU_m%Y^ukAGAu(bP`@LIizi99Uj|n|3coT;Y&{cIRRv?A@7BC& zdl0mhl2mBfbt$PYy(rbTTMPs-+k*!<lpUB*eJDAQP;6H8(6eIR%&a^|$Cy2~ftwpv zP-=+3jVf4MuQ2fMVA)DaikTdT#6>ERe(c?OlYlSoKWRKPHu?n+2x5p_&T#GsYc&5% zk&zRzKeTjH-070DQ$oTc_O0OLu_8s=+%8SYyP{1y++b!B<$hjJ!W{`m)GG$qP8a{x z@mf6}v4EAmC&@>-xnM3P-d8M&SB=cLUET42P|1{S>5Y}mo(Vn5IjnxJ1G^x#9w^tE zrS_~>w|8qXbvIn7!0m8{F~%8%ar9rmEv~Tp;qZ>LZbQ9^bWcfw?2E9MbaV(=tUzzg z($%ECOrh?Q5iQGK@Y&&}eum?E>Wlq4woTn!%3O5kn-2Ggve)_4B$uwWxj$v?+wk>~ zBP2@9`lLNoq3L)9Ea3zbQz~HuxmG|vMn|y4HgW`I?KP8}DGN9}_Y(h4kgY9(w7?^d zTS_y~))Or*BUV2jNai3v-VkcYvI!+y<!nHbxm~S3Bl_e`P(j;iFqzF7tC;ka)qzoP zmSC(xsh?f`#JJiSo6ZLRR5A%y6oh{|&scgLy8TX7a_i!m50)Y^9my#6p+G>9vIPY@ z26%HBa2?XpJFR<7`6UVms(C|+T<!O+mDFyjd6zy((h*bB6@iYH@?`uva|iv29(i8b zXLGn?%5|(XKSQ@1*)KW0AgM-ozF<QubnpzCm~klK+UK`!6WT06{u42Y4?T{Z58V9_ zTe1VQ^_!7y4DJ<QLzi=7%BU>4XjCjubgrDe4bSNtvlvUR-_%7khwfWXR#lZe{ydtW znQT4PF~wb1PuMjua<D|fquW-)$`Vv7oBzDL8j64Cb;P2!yNkdd6GwKBw!gERz;oot z1dB-@Tw_$ky^gervJa`DB&SOGgM~SUPS&>(_nvt6ibqve(gkur;`o5iD~cF9M^{!C zfm<*+I9|oqbh<sBGAjPnvb*sB=c~)-T#u9Y2DJDmY7;kB%9E+Tj74^<=DwL#9LxYC zhDUI)hlp+FFXB-n$IA+78{O{1+ne={Av*(BCGqUVq1~6A>oD{a?tQmT#Ie1;5f=fS zGDH<25rG>|Fyqo&^lSv@sk~7%Nz>>0?S(0#gzIQ2`q*ayLw|L=$&9k+_l?Hla2m?j zCqr<J<<@07EK{nv!+vB^6l-+)I#%66yvgc&LA0Q1eP*EMjMHfJ<T2#;Lx6q^?Mm0Y zn~v+UbNoJtvd|Z8$K1IzQS140uS$M9dY+9fN1_U<!Y0&c<27FIIRf)8F_#OlR;P6x z&w^jEfNlj3R7q5l@Ub};v9EMVB+7(zjO9*+ef|fo$Q~soUg$b>lkb)11&#A!67>FM z4*{xxr}K)d@rMK|o0yE$yXUN5yY**+L`26r)~LoqRZ9A0Jr}CSt4?2K9clK)uF$8e z@g2<uM#VgPOWk7i_qLVQ{DXt@eIaRSvHKbJ>hGR@{#AgCld3A2jbU9p@7`oFhCY@+ zU^bi4H_V_5Uv$@|Y6e!cL-OL~<krwt&cl1>AZKm>pif-iFvzYC9NtTdx}UhRDL)@& z{=7ef(M%(VYhcuHLWOy%Y-4Bc`4z6Vxf_|*4pUK^lZ##Bg^wSV?fMw)(m{xno7nJN z$nkOiNd;B$kq!AlygNBy|6uQ3&uckhw;$heK4Q{`5rumRvV+bsr*Y&J+9{vqW*!KI z90}LGkv_RGuMAb1MGbD8d-!HN^ugW)bP?FQ*#AD0R;;S=TCBK{f*d~`b{7yUn|HRg z6(*|5>crDwr2jcXpJ<bULpr1Yuj-KMb3Yj;_}}vNIKg7t6U@tiYyG@@rC(_Qssfo% zlsp0MUNip_TvYzzf5p6hq+riN!uY|ouV0gb%f5hAw^4=ZfNMVp*P#Q{i*D84FMN2v z@Wl%+Nwuw$C$^ZbbergNp{hLZ++~-dvHWxcO7)02((Q4i+kPDSovr_^h=oA}Pb?IS z?i1#JEh=yZLRC6vXM>Gow8Zdof$*c#rHIqQePG7r*9V4j*cfE9dKC`eKXrDl&4BaI z9;Ad0^jRG1f^jG{zbHabMSD)e&x94NKYldh+Fa7BaP(Q)s3hLQpF=r?PE5k_yT%=d zJ&xn7i96F-o$oGp>S@Pe9jICgK(w!E)8xA3>|%%!3i+I8K|cIb<aRMS{UPtpS`jVM z0?A@zUihXz)I5ABFSoh#vm*opoujcF1_0?@@+8-JZ?@<U5w{#5Eyc(X{*92YV9;OZ zExpEXG4SQ0)`GTpn0qWR3B;kokv0WaD3B?8scZ9hGIuOm2>kdrmdn1%cb}?S*H_b& z%@{f7`AJ`GL#U}>R?tL@P?2d+oO8p;nmUXXY-JAYn@8>^8{NW(KStae+S_SIM`4oQ zh?kX>wE6~o+UB=#zeNiLkw(d5X(664ZkhMmunRgKmWq*mng9)yrzS5sJLq`rZSDk_ zNl&v*lqqq{dd4<{hnKE%K+3}@!;EiiEL|VFNK@c8DW>tHMmqtnVBTKwj8EH`&%*d) z5I6U#<@wV?Wh?lg^<O0z$#`dgg^9q)t}<%_1OVIyJcr;qgUBFYM=E?uu4`y`=oadv zH?zfb!5^r2X9l{%Z-hMuiym#9jLP{vT!=8PdNi_}o*zF^v6v>NI-7mnpPH)EIz;7m zclqGm)orj*oaBX0V$<??)w*Y&jw6`OtU1ATws`l7xi*R)$vZiC-7ebVY#+s_DRWqQ z%pTiyMQC)V2x&;DUG6f{jW<{I!p>iarH~~5bLW@}iuLi)EC_j=Y<qp(Fn+6h^5D<+ zHRF1pVWVqQmJO8AolWlN0TYI4%4n!q1eU-w736Z5+6U63xx1J3?s`||h3r;1)~t(! z8<q}NG4Wpt*)!uN5*N7=YCle0b1S&2SOq-YqiZX`K-;8ftNq=`A1(5iF46wP>H?q* zNrx?N7alfj>(_b}N}Gom3pO9b)QuJE6z5n!D!%9O@5?)kOpBu``gBRQDTPZ%+l&1C z-GoH=Pt0D??#pxf?voCV<n7E#Y$VTcWk6;8oLg!BX^8P%$rC^2V^tC~Wp%t$Otbki z4-=!F^|);uDc{-W(J~~V$&EMD{jw)B0yXP1f^-{M?<_r+hayf>up_K^>oQZ}X1u!C z##Xnu!$9^<ZyoAdH`bu@lN7ClnEe)CzCDVXffDGuIzKzn8&Lne+{UOldJ?-PhRGxw z(~<u$(2kD86d81U$1`0i+A6Nlm-Wn}aJQ+=#<9vk;}eRdz@w+_jA0+|XnDFe=ol<# z@Vg32Udwjp=+^z(WKLOawP*dK9WtB0TB@9l(@#VosBEa`Xj%+_!3>@{=QVBS>#(KD zvlt*<3P$VDrF^B+!n`!5dKU5LkYIhhGzUl~bcTygQT}U?yoUUNO}Zbh@uK|IJ-na3 z|ERI_Zq<~2lV6#Dh0k&DU!ws?_?tEsjReHjYd(qzCbv6os>M?;pw49X>9arJGl=9{ z8VZEdkeiS;#+HJLAo&qfw--xjca=j!nS-C@Vh4$OV#|4H`XOtDrS$C^eh`~;03q}N z4@UIMXrY2gSlDy>p9C)tm%+C1RNrpF)NgK|ovhtt*dY@@ZDp2A&fOZ)8tVxq-bw07 zmnkd##Qp+c)av+@iyk0xwHdUKXrRYh4ktoAqv1`vPm(f&JVtNPvRn~RU(C-y_@fWt zCkzZWqgw$w83UwdW;!kx5kJBxAf8Q#WaIx4KpG{fC$FqHA=wDz;7_erAT=?-Q=TUG z=dW$|4Mi6rZ(faUF)=N!Qx_UZY$n$0G!CYELaF}F<A>T(&%nBCkWy25xv7?I4}YqJ z#t^dRp6$8I(UVeHrUrDJCIFjm%=7X7Dh?$XCG~tvz!pX`P$s3RH)AJ%10+c~73yX4 zG@LS&6GayFGIcl5B(u`|+ogUds7A~@B5w*k`O(`-70v%C`lRJJZNApnx@(Butfg@N zwwo^BUr?FK0~tnkNr@VPz{eD$21u|lFL2S9-rkfv>n}*@ydRo6#iW^zShYBeuNx~h z$S&fy+lGWa0?zoRy<C8el!PqsTk4s9)Z%`LA$%A==`>m4k$YI>Vvt>-SNMV|_w;ES zo&*nFzRq$R|HiF-($?k6T_*Zp6qUo(V&x2hu@*%QY4vN|f0B&olTxX?Vw$ytK6-Y) zex4FvDSMd=OjO@<F1%cJLIJ~lnbu+X6$4^1lIId`MH_ZiLuH<Eo{yVvU`9|CFcu9t zTtkkTmRxSO!_Y7VA>Q<d7{2K05+KnJf)w)EF}4}8SlyhI@Q6N80R&G@6G;@K;*u=; z-@VPsyBTOL4F`}t3B**aka~(^H}DNhq7OImaBv{0Gb#=9Q<IBAhWx&t4tB$q1d!U! zjT{c^dCcRBXCKwu^g+dsNN77}SqSr4;Kv<ZKu~QrwzJ)s?$GDTmJ1~n%>uo#a&>o# z30+|~jA9-yQ^J}0rc;hGnKzsJ2uQ41L;H$ZUE+}6yvC<I|Aky4^LU~`@bLjm{&1x@ zI%Q=|x7#{)mE;;~^4Z8DDg9xM1mN|Kfye%ho+QE~X}v;iXQxJD^f(GG|3vRro&A4z zCtb<lI@o0)_5s?Dg&?uH%HgMIa=c8|M=$kGNWET{T$}o)nzmV^L`m@ccoz=il5Go* z%exl@Z}|iZ{GC>qRJZN~9#yncgE8d*QK-_nomPA{wE5}AMro`s1f}z(P<1Nw*i&5L zuz<)Po17b8>nVQlC1INF4CDb&uq=Bl4D(daU8xJviB5Rr*c}^MoX#Nk4X3tZ`gU_N zw}Xfq+obS!+0C`b$EpeX!JD<;CzJo>JuQ!06Zujb+&*Kge>)s(xK?6X&m^sHczZ)H z0w(HwfR7#7o((L8W9Uwcul~3g!L;~yn}M5jPz+n<*v|+>gEYx6A!9>hBJHR7>zq<X z(QdDF-@grf^*H$@fdETaKsVk7N*cK40Wcb{hi-)I4<P%h0($cG-rmxf+ok~J!N5Zj zn+9ssPl$_CAkIpz{f*MdUmj@r1Gv8GE%S!C@v2GkzKVAfzT<61_Iw^2gM2|orIXoI zbMrTS?g~3V^b+w^lwd&zh~^Cttdj&E|DHUyc6N3oZf7!0HBMFDegI>NLEx`619SJb zg8)$fe7Chu+IN=$a^t?_3E>MM`p$iG*j%4>A8vdWL!p##=X%i&dp9UZHW$|r)?Z6+ zVcZrFj{nu6Qf&)ucAxv7pfd8wq=^`545$PcP`Vx}#w{%~a(uKMul~YB+bkWQH1cmG zQmPOD7=)SJ%n=k^17fR@kSvQJAonxC*&eFD<0tN=q!eY<O%hDlsao9rB%E!D6Hrwa zeO6Q9i304%h2S#1(s!(qhT)x@T$>C6d<uv-fH#O{{0le5x^;i$ZnNr@eF(VYqK`oK zCz0x}vC~pgqOo0$g5sW)E=RjRrywqX3NxQIG^#JRkh!1(EVgugO0cs@UO6?*mghq0 zI@-warq<mTc%l^WY6@Y9-tX=<n?SO~#&)uXaJ<Lx&Q28GH%j5J-($K`?{n<}B>E%> z0}qo?H!M^m`H58*&$drZnN3uu#m{{OKm5d909RYY7<B)?gV003V`{yUkk(Ub@SJVd zy>jc@xleB!?K&R>v6vb3f_OnetpnJrUq5XK{MJ>1GVH#t<Xa%c9%GNO_iud78Fo9; z?c`S6BHrd(_TpMajv#+ywp8C^bEMPW6R+no+eKfb^yxUyQ8G>-ZwMgA_DL>gass(G zBrt)O;ZzxlEtTgUf3gwDQ4#X^SHScCxfLL4vRL7qdq|x5_zsPH*`;Q*yKxgt%IV7a z+-w~wmLJl~fX4uG@lz>7Q4z#}9OwC&nbO|&lC*dA9p#q_3fwj>D;FLgyZg`bghc|1 zy%op9+_Tcj6%UZs&Gy!;rFMITU46N0wco3|Ov59!K5ylKnB}t?<@^^FekxJO;JbId zcif=LPo9{5e8<DAzdBvZf(%>I%_`UBMnMw>l2$*y_4VdsiezriB>sCmP4O2Fcr?1~ z(_XO2fXf!~6t2wF`)Rf7ct#trz4C)?uqD=0QMic&9ZJSUNo}{1lDicA%ke}ulny#s zu(UTHxWyt*=KAEZN&?S6+N(zguur$YCy{u*TeV9|PdA>r06Bkgj%MK+2yrJqnvTy& zuAv(yDg#fQhQTO=LnLa#6c5z@!)eb&_tm_WGHqVWwrVZnFY{Dnr%ePVUL}#^xdUJ> zYJGCC@3ky@Qf2_+X6!2iRJ?J8e#P^TPQ=*CDp*}$wG;77*n3V&&U+99`yis+G^mSl z)}^Li3nmATEm0^OP@4iDA*BOoY5x+vjF%^TPct{r@U0nUQMb@gWLQ`+vVX<R8)O@D zxF+l@c$`M<%60Ha#|K)Koq2#~=xr!psjVV|$O44Rq?J{7=kxz{EA+xepYdv&IUj`p zH}N9{fbcb)HuTLQ^$;j?mR*)TviBg6i@TIwfJ<W?%%$@mMa2Q%GL@;;QOl(N1*A%r zO!cmRnfyXw_UaH*ap7(G{(&-Qpj3Gg)*Mw4QaD+S=B=*Vm1`?PLV#QZDdlc2)k<rA zt2CG+V9nU5ArC<LVk;5(<vy?*J1@+Jy;D)ZXsNfm;VSD(t>!hD25EZPw7%8nW`nY_ z^jf!t;YRqCI%zoDyF%aZr-9^QMu``cdnDO90G`J(LnAvdQ<C9}1}vnzJu=s|Uvv+M zdcK|9QZXu8oLLSQN7;E6{<%RPWgYC8f&1P=Hs0h(>hd#jK~YmE6=$r5^eWeZ2#pG= zipjiMbB>PH^pnAptn7Q+xEduwig{`R@7Bpzsk`k$j-$<_G+GhKFAAn0tbnA%%NwjM z(6@eChttu)OulmFY@a1oJ=fWra_xqr%sv@E0Z9zJaYI6*`EYHg<W)IiTyid8InPWz zW0r!5Q!Hqlha`}yu%i9E;=;ezBq74OK)qUaOcv^2QL~a^H=-!Yp;Ho9><I5)re5tm z*sb>Nscy=Rm+~}iL`;AT(rZ?>_aK)1YdX!PYf_FIv$5eAvR-E8+HU}&PCG?p_*v4G ztIkw_(EU<7;g^;n?lcTaa<B|3JpdZ*6S)UGTBFfUr8*NYPXYN!$NQLojQaL1dh*6U zf|**%pfn893$cwZe(}}U7t4KJaxn$?7iTUxId%8>L4;3GMoSAs`ih`hAKCpZyhNeB zeu<WRVd{3j(buNg_KDyhAd&LuypY5mSbUG)2nN#qwSa96U@?j556?Sg0t8W3VWTi} zBZAa2MaN$BKDhqj72W#y=OywUxm@}t<ouO68pR<{7S#X;o_Wna9a|frEio-D%p^TG zL<Z688zPPe)eS1W3fovEcpF^ODOn!w4IS`EZkfw6M;*!Bz!HGL8u%RHQyc8xcY*pV z_x4h5W_H5HJGbX1GVDRxWpFs-#v34UQ0TZ~uIDmh>td!h>YdP4S8LSM$*QN}U{{Q? zvfJ7x*q&q|)C|;95J!o6`g<SyDFNiMQ_*!n!6>mi{4DhROpy=O(C=<*o0nQDy#l2L z*kh9-u<b`oOe`}fk8j>h2YEi^<2@->4v2`d<cYY&ZHFcAF}|Habrv(5folJXs#))p zCGzhxxB50|1k?coU;-JV+nT-<ij9Zo<D=&1#2imfLG|P@{_bV<(4B?jx)vLY%&TB| z41w@qs&xtyy?C6@6L#BbtCOebC|Xox%KneG6Ii#+M=&K2*|a!0U3K0Ar2#-@o(1>? zLK<c-Hqt)v%cxz3&RCi&J@yS6631_i;o%MYw0-H4{b5QIm)4sI7q+R<4ii@c*-IV{ z&n`w|3V>g31k6V=W=_?(rp)`uLdsvco#a$4Z!o7IA*^4TALINTI|}qaCZHnM30Fk^ zCG5x$@n?n(RGb$<LL5vnq0rS_T7AQ3-^^fFM<^=zrd?)l*G1coA^>GGq5H3V$eX_9 zlxpZ1h{yxU6XPgg{qxbHAiH<ySU%A)Ir(jSj>25L58Ez5Tgsfhk;XZILW(&?6zu&S z7LYC6!YqRu*W^hKOno2T5BR{H`GGb{+1o=2=c|?Zb&oDlPgOZ=GlUk*YNUC{F+rFm zKr%`NGCPCiPdUJ-`}gm$0JmJJ9Q(GB5m?jP69Pou036oBXm4%gB#@y%#`otoKz0rC zV2Zv+&utc0Cty8<ouSEqy_rua9=?gGqDqT{C?K185JqJvY>J{eMd*vz!SgJ<lR&-7 zwxJ|J&0+aFgA+(J_y8`nt#?qNbYw3L9s)p3FEXsH8+<78H*U9BX^@VV4TyzWs^4oJ zsxT|x12+fW;6jYvCnq;Z-^WtK+d2c*rfs&3kWDF<Ejr7#-|t^R=({m{PJJ<V5U$(L zz%q#z2aA!H?ttQg{isnh0x)w_PlCzxJXZomnWJcLRm+(vZ0~9n>|wcnykA~)bVN&l z1Rb!oMSj5~6fUJkgq2dXhNxUBMvj$L&*XVqkPwH}F1>z%JRgU_P8tB+N+o!aAMv<B z67$Zb;~ZE-`$e^l{eJRr2Ki8EBJ#drhsG|UkWiREOjt@|abCs~ffS<$#0qZDCHt+m za3GBUMq`%B7lwy}wED}Ip60+htIMx5K$F-P-n?s%dP>{46$PZr)R4ubR1bXncWGY_ zfr=cR4ZnRWafPk7hY~J5YmEY+j3|d4Ewr1dvvS6rJ*iJ&6Cj-oY&}J}2si|MOMvRp zNnn?sjguWgrAFBoHyYuKF0rw&=&1jC@hqX(B%h*^0$w`29!mBFRZ6oD&vz;Hnmiet z{>ows6K=hS;3e`5g#jWy-{4^OW;NOn<%C=vH*wMV`uW<J9<^}CqxFOsNc2^}$MS+V zJyU%S7J<<FeJT>e3wkQ@EJ$ju<{`C{7D4W&=m#C}_HRIf`nH598b0h1#fV&Gu$+pj ztahTPt>Q)&B~4bJQX!U4DO~uRz7ci>i!_>PztX)$M-EelT{YOB@vS^OXYs2J9RE`2 zU~1;QF<u2KNTYSg5Cg1B&E2^@bV@?*HcLgT>dg^QTL~biq4j};O7Mb2Ujs`K4b&&E z9$+%hCdzk`YHrL)I{MF_C2f><5AVOTu+J*fDYW<Md0+#aSJ67BihQ*EgajhySb~=3 zblN8wcpW;##3b}^D3Ta>GVV4-MK8-{5fuXkI9uc7Npruunj%t1=~8e|w;;3%Ru?SZ zY1W}Aav*dt^`>%L=;&;^GGZjvUVp!8|9m*3`AAtXRxUYYc857;Y5-`XmjVa|-nUHh z5V`7}Wb_F|ilqG}*KhZEZ#}`#_|z%Kz+K}B{QleBWv+xZf6!{9u&-!~V#`k@@1n(4 zza;2OyJmn~@P@RQJk&?F6wnf2E&5|7u7#xbD<kz*N`}kAm(M>(m;T~M+HYkmZzUxz z1V}?XqJb$sr$jJo*G7ZZ$tU8Z!!ZDJaKB7Vk-`k$S)KlR9KwE5EQu}jNCkPY4U|gk zll#(zi6FnC5I>47{RzbJ9UT)veI%(`D|8~TDD!7uI><N`#)hcktij?lo*f-=7$xs> z00FuXuRzu-tEw89D8txWE^E>O0|P;oLMX#Qo|+-9p1ZwVWHT$v#1Z`MC@E>nukj<t z18*oOhtH>{U)}$s1TwFJSvuC?=HPlT2vC1s!g*FPTmV8fU^Sq~0g|5uAatd=6Gmu9 z$FScskM)DoBw}X!*i<@?L%4y&PT~kD=xZiv%+5bOh<djuc*_v*9NK&hJu9VGw0Vzo zvKmZ}I};Z9c*pmc<$$LH11!&1!2^BV2REt+^rhb3sPKCfiD?3j)DI0E&Da&m_;K$V zC_#G4(Lt;!L(tz>Q#T-g>@TqIIPY9X^6_pw$m7@2D#N%>;A<|JnZ<u;>P@rtZ(Oyr zG#PD*ji)ya_W~`3gP!HiQm>FfH9u{?tlNvp^iQ7_UIMo8AO?uRN5gvFgVYT6+v&at z!fO7I)<<{IKB$VO2;Ww}Tyj5ZyNK%HygVFYs;zBSf(hAI>TSl*Q)<z!R#v6?uNnVn zrE&=w=~Mp$gi>xG>lJ1aKWT=nT+<-VUont%G8}a+d^NyWj5KOJ>0c@t_I@s35@N)} z=AF27gbFPHrd)Zv={vcd(#$(L&{`Xg2?tsCrYTeJhxgcz5N2usprzYD&|Lz$vrpUE zwI`Ko^_jtjY(mXF8!jC$00A`k<evw&256OGx5L~{#xVi4w(ZU7Q$kITDH3H}f6xPp z+)TNmA`ZpdjU8D~ey1Ni>u(CBR=hAr!`Us+Y!N<`&ktH6fTxVq`&Xof9H>_|@6R`x ztXn?k1sb1d(~<2dCnrx3{j5PE%*g|y-|?1*!6%<oAQ2gUsWleVlKs4-!eL;8g74fo zmShmI162~~C04Zd$YAc@v4Q$rTwro;o5PS8X!0@>B`;b~)N>#59K)Jvr5dO_C9dIs zSpdy#DIo7+#^N@gq;1sFY*59TP@@<yd*Kd{sCQh_5-#ZCR@bk!i3Czi8?LFSbfkzW zgd7ZV`y`-ui9ijrtBriPuG{^I6lP`t>heoIJ^hfaPU*EetQb(2Jmk0`)?l|RdjP>f z9PJDlgdDDV#H+SXPKo~-FL;qI!{p#%SX`n3YAW2{=YoskLD5a~`Zb;;wdS{7-?#RI zwvrPI0NYa*wL^gYGsyIWgWiGKjH_X{qk!k%dMuv_)FI#|Me{wP+^Rm;Kijw>DLO%L zFbJo-Op!m~sJ-wUQ$O?F`&I`efEoo^RfesH0l;rODTAX_xu$^xN~^EWtF7}MTL@7! zr-bPLd@aKN$vT?<Zw!~xH4TA$SlK*KwJyyU7EmST^s~tnhSo^<dbW<YMEwVD``-7E zqgu$oNY-Y6o<im`G%7!<HYkmVkZ9`HHvmw%P3+5+TQ3HjV7C6-iukveozi&-S`I;R z>~B*$<usOM$*0+z(A)6PEGkIY^Xt%7%B(>f<2}BqB}=e6%m9|8s&1%2OTpI|R31n^ zb!&eQissePQ=Xkt(C}CPz~eBI9?(8da4z`xUKQq{DJL}q@<vf|i4Wy&W4vnp58qTW zNTWb+J>}$w^q{G}lqF?Z^2w*)Z(~7o`S7s<{qtBOwI3c5S0F8qzmd_GFv3A|v~9Pw zCVbS`alb=DTotQkQl`#=M$5~FP<NWw)=iVRuaQgw$wO#Co}`|+*AR&Hn?=UG`Bu=H z;oqfsa}j?q)cjR;D|xJwou(U3$nW>{TBn}B01>``xz<*^1Iw{pwccJtQlAGcL5b<n z>agiOr*3RQ^|yPogHh8Ow2+%HExl4Z;p?(y=L7vItNq~mpir995SWJ4YL0doXpmNC z4^{NJUiw1LdF#}>1%8??>^4s3zLoJ&;0egq&<p-|@QP3|c*OS&H`cii5wzV!OdIrk zptYW5RZpaiX$127CW;-W;wNCtewhg@7kBqo!PkbHW8e`Dc!sg1fYU82zcU&BpTine zwTEi-O}g>xttq1W@!oG^g5qhpPH{7B?z!WZTU&9&nRFSjDCJz&_-^t^??;_)$|eR! zAJA8n<#<`;C6@NR=0eKTYS{h3Qd(@u@oEv)k918rO5``q{Jp;Htj)LX-cp%-#p-wF z&aA>!y@-j+;5<zKY<OGEAijodg$<4<Vz?3-XvC@~?IpHJrv^Tb4h>9m#W~>+m|6C3 z+!ahHC1vY-rjLQ43+t?JG&LfvN+dTqVu+dBD~yycjew(#F9Te$8|2$LOsK}pK=Az( z_O+<zlv^nT2D*~NrpXvaBPbi2ADUgAqeO9&44krMe;K+{PQbIvK0h*k1HNkk5xy;{ c6nsR^nT#OJy#KZjE{CWpYu+!tXZiBK0CBpIC;$Ke diff --git a/doc/reference/clutter/box-layout.png b/doc/reference/clutter/box-layout.png deleted file mode 100644 index 6e50ef19be8030edf1158d1ba60798fc5b98ab6c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10557 zcmdUVcU05cw)GDcP!Um4IfB4BM}&h2s1T8kiu7Iu4A|&Rq?Z6zR1}U>>AhE}ngFpQ zy@U{o0hJOU1f+yW34AN(-toTo#{J_P?|%2a@g8F+B=F1Ld+oL6nse^`*vLSWdpG}X z1VOm9wbV@zWE%=W*t~Xfz&nw$R$=gMhxY|-vz_o2vh(I6czwj@(q$i0PX{0WYq#wY zM-NYTdr9vbx9#mcyq!FK=C|Wj5ad@xTm8IQKq`$K>=Q?CoL}hL5r;hZbKk)~Z*$cb zYF_$qFX)fo5A0$$e(RRw(cnhi7T+kp^5~=c%b{Dw`+Lf+`MdIHp=(dtBtB4A_Yu=L z{Ohkfe(c=goVnxP74s)|UW^BChCfZZb|&$Q=u+EyZGY+b>#z(;(r?0{N$r-~V2=Ox zWfUv+VZ+Fd4MCFcK3E%4c%zZtK;1Gl&q;XTFduE`{$yrhi@MfOC?wn?cV?^0SUGfr z9-AE$f;1@!bs74IzIl;*0$(Ajedhu<f~a}(R>=I8uVa!oN;*M2YeKj=0Uvz7pse%$ zizobc%8vMC5uRfZz+Vr4pz4J?AD`xAp4&Obj6e9dH*1JVr^bYxiaQNtOtvG)^$Rv> zNAebUWXpUeNycoWf3$1CAWk0NCj^{MOstRaYq-FedXH4sYZbc9QZXN<-3G4Z!p?lS zdv=jqR&`1*vuH0W{nZo^-rHBV<l}HEzqYd>`jc4q)a(v;wEb8g1VU^dd`vj+PMFu5 zUHADB<m(RBVs35Ag2&F?F@l+-sujXQ41WD*{=6p2j}7TITG?`b-PCGT)*5TCAf0t@ zO(h^v!7kXmrfpldIt-oqT<LpQ@o+~D5$oO%<^D%sl>Al}b#pB&2YonP^g<!q*Qa%4 zskmajiP4Y(-b-Po@3ww9NQ*&ae}lOe9A)}c*QuU1Ec-q@)oMvm#~nrVAIa_BeoKdP z&2lDLbt@73^p(aX=|&;i?Y})zAE4wykT(|R8O;d`c`Y|YM4T?b+B=Ji3%kEH)XtnM zw5!o&>%Jdg$c@OoaGn?Nq^3x28QSOBmAnsc;+I`|?qtcHxof`*^6KrF@qDmMZg38I zXSmZhlHq?%82>e!bb;!`hah*x(W>G@$B{>;pZ+sD`mdSFKb2ltzBOD3BHQqMbu0&c zcd^`VKkY#GyHl)c`Txn$|Be+|YvRHu--$FfhQ;32sV{nW0+mnA!{SJ%KDO}EdarAI zEYfk`@_y{s=x-#Z)3zMhK+QoP2-h-C+AWN(@T?Oe(gVk`(cJs?Yq)d<ZGEL!2m3^a z%8h5xaS~fr>=BVQ8*0~T+MbAeQ9c$C1HJg`e=IsBZp(~n3i8AcF>5e2ZOF`hBkz73 zXWbMZ=3$9@$x`39h5+TbGbZwR!`WyHy~nN-J@#A6rp)oXKUt6NH4s+L+a4xmF)Gfd zi948SuoLAd_{X{iCam|PBAFr9azcDv^vNMMHNp_Hmol>ydB=sE?l1c5+5Ik^XJpdK z*WNnXy7DA)s<qwv8GCQBX7P_zY<Z6qd!bCIO9rtT9rI+%>w_Y*KI~|Z;jpO2%ij?v zh4rl(&4?x4c-1qStH-=WwBf&+u)*{{EIIB+pZ-+s@!F}<b}+W!LE=`dl2CLNV_ZC^ z*}O-J3rYSEUtvp;NmD%&fe*dV{###ad_VmF#?nj2^ekRH);XlU4TYs1?~#(2Y{1NO zn5P!Uh&1{(2c?ZR#fxr+I>nW2Luz*1Pp(#q@t8lYUeEaD0L|q35KXr{%5N9KkL1Wc zy3|ncFG0lrs%&!-q(N`vmY!cb)FZ{_bo+m0abFo<2*^g?Z9fV4q!xRf)y~e{dCs4? ze}Wv0i52!9kJ%7a6-8t@{|Bz_uU6OjS@HzY&R?jzzCc1mdyK<}Ku%=Dh_(8%sg*(l z?NHz9RPEVFk+N()OPMa=wO^YkE}Kc}HaHgK|JctN*$0hSP3Cl_H|IQqtXN~d)hTG^ zeE8!N<kz}=F5wQJL?qWk@U5YReLvD$dZaj!>l|4eP8ugVmcJyYEe0qh%gmUhk)ALX zx2wHkebAzCMrhHJ&By5;SI$L_YsjO0TiiR6AD40Bjjv66G3Q-5_BkP$dw(fnOMZOl zQl7#F)0w=QXxO;4Y1wsC`L-|q4-0nW<vpYAvb=_yCsC|T(Hr|8*yGA_(8$-S=emnI zXsF{~{+1j8+u9Yo+FMf^4gkTi4p2&e9MdX-30v{1`oyr0F*yC7Z5#K(mD1HR+6Hb> zn@{j{5*~OX;c712D52=)bu9yf{`<Rl&8}Se5?5R6#K|MnH{KFUEVGe2E+R7ZNx-u& zLOAr79u=3(A5T6C-+YGlzBn7UG}*y_>Z;myvoQ%H_m=@YY?<Qhf<>ogl9E(b$9a#7 ziMcM0x9FQ&M#=>)-V9U{DzmQD3ENs9rT-j@cAfk3dOz)bJAV;2e?J$UGCuC~<&~HI z?b6Gygphsu*O+VKD3m#VlU`A4-*$LjDY`j_WEY0M$H8qv?RQMZSel!QOGxNq)|QP; zOk(EnTcK%6fxS3=TibMxM!E$IPW>J!-7mcLv$-<Cd>HFnVq#(vvgsu!lb4(8G+gKY zJOgvTwXMx}ZFyQlHA=*Ns7Bk$$_hJM)fV^XpP4;5n$(<Vl^7BF{HPtyj}{{$c<z>( zmzUStOi6`^wxa)>+14iWIP<6Kda|ACrYAl-`$Dxthe?HPV;=;~-qCTr??;5{#`(l6 zw;vDHdseuXzt(`K_E>vY(hW0I%BBegC9b6MnW5T}e8Y@6Z^`Y-85`8{)t&wswM4UF zlodX-QB*%Uw=+#q;<w+<*OUEHqK?X&P~|C;lP6Fp)YQ_MKI*%zFRmq$UxN9j<&kiS zce_zALZ4^Yx((Xv;~|x$(IBd%q*ayrp+kpaavyN<osg5W)J>EkuF<K!<Dd6;B%|7J zn`HmdvJ?-jHqL*(Uva)6Cp9${0*2dIY$Fz#iZK~sTlM}Un!=de4<FRgeuMVU(*gyL zD*Ea1iW#`YT$S;gy=-r9KiwvcS8}up3c@ZfEgjcxOO&=uIqTj)l8}}*ywMy*x5BSQ zxYIw|)H-HhEF>(;`&=s;^E*=Hs7qa{jKR5QawFZ@mm+I|86Mn6&Zu)8KDm<>C&#Yz zGWX#+XF|UIP>pl!ZZ0mAW9QKf8Z*NXMXd;J*j%Gx86&~(M;zTzL_d9p_7_>4LIG;Q zE3-Wbk~Rm0g)5R|966LmFGlPwDlF83KlSXU*cXx>Y`rE~*yz8VLyJ%lq+GG9b3=Cq zBXa!s;481OSy)PqOH65I<{KA&S*JfICME(4>fMJO8iVMI26llH@n=0pl!kHs6{}oz zrTLb&fgjJDInzL>9}UGdLUx?5e{AOE^-|KhW-7J0x=Y11W|pG5^*T+#xA=VY^!(Si z_s-h49>h&$N0xe1I#)jM8V+P#jA(D4ZDfp8x3}xb$mkjx)*q2^7=X#Nx1T(A?7c<# z6=w&>Ipf;oQA;YRB7;e<2;&Y2(OwyJ%m^&d)zvM7U9IgGaA7uK)~!7}%Kd{@7bg;8 zV!l^5ZY{OoCu?0vLqEQ~ZzQRtVmL~~yHN|4SFX4z2QBY>)$#pfq<e3!w!`6#z#}uh z`#WE+cX9d6|1QsoJUSHP5gRAvd_OlUMk=Atrk6cNK}$i}sc_dz?~>Be<s?#_yNxTc zIKI|}*!unZcfFX8A3p{rhAn*LI|~I*{qnk+Ti|TF%I43p$^@d%#!oNmz{?y#m5_nG zf(kbU75!?)nxjdpzq41l5KmBvB_#Q1A?2VKBCexNjqW22ug^yx(St}rf@1u-lo>CQ z1{tGap5o%-e&0Xr($&*rJ#GWV&no;N#+*Ckp~GQ?z7NgK!_SXtZWEH};~{F1qNAhh zb2Oua3Zjq7Utd^QP@%4=X1I8SeSO0wpcGIU9~Y-y({&ZaZr$WHrh)tRP~hb0(>($+ zHnlE?Zlyft6&r#8b)5XkD!1SJUUMe%&5m5Uy%*Uh!LQu+Q{ddKOw3}7*l%1V#l=;S z0>kC6zCU@CVBXf=UPH+U8%YnIlgBM}Dqa+-$cjryuwGxGNvf*iTcWJoN1HGSadG2m zLNX3dp%l7$dwbj4-Ik|%SosAxz$iCe5(-pG_YS?aGC!(1rKNvv=^a`%)i{2rPStlN zj$2seOMj`=SapNSx-3_SKH!_%=Ekbu@|1B&VPR#OqCdx;3y{72P{!+P)QZM7mtfn6 zLFgUDGDhww5^VB2W!U87-|i=KFjJF@ObcdSHVY9rg+nsuo7N2k<UIO1<VI)Fp>2}& zPHhR23SQsu8>A~0K{Y+7Z69SaMk`3R!TJ^WO)S9g=0l|inVqUzArq66E*~E4e->J5 zoTK4PpCPVIrg+xeXx^*LTqa<bdvzPz2m}Jkf9^_NUY>RgtXh`!b3p;;7rWcHtNJVK z=4Iwbg6GXGED|g#Y|DCkO_Z0rFFx~ANlHpeRt;;?(a|w8G0En$4LA?)Tys~1aw7YZ z(AYUFmESGH<g058063r(WTP`}s5WT)x#l(x8zZC4JKH&D?s7@}=q#cAmFphvD0ZCx zxAg76oPC9gib_js6750<Ik@?6!gJLn<=EB{3<EvC=syzJEQQ~=t*fI`wToBu=hJ{4 zHj@>_#jUKgYYb-86&DvjBG{h1+!$2*j33pi;4^g<jrDoSN*^f6hPKEjPxNBk$yj20 zJD`|;3~i)w7-!HCy!?(!`f`CmTF7L4V&X8bq0%)d%1RG1*2>S%?~VJt4laLYRn-~5 z(qweNw+DXT9`FGY5*qNLT(ylZ4fv8Z<55g9dy^<TJNwz7WhZKP*1f#^{GpiRy4#{| z>t(2r(*q}uWMD`u4SVR=oo0@iL+={@TJeVi4^Er#P7xY9WvUk+>S>3&a_spf)4nai z`N!9{AaW4v9nsA)#wJO*^Ia+i{Xd)ZdW-sdBzPX7FI~C>^c?vbG4g+{g8MJ_pk!BE zLwu$=kPrM=A30OjPrsh=nfAz^>g7h%ZeB0e_1Ayy_ov5Bc<+l8S-R<GcF^)v7VOCh zXcB{igEM4YebCBm5z4jyeq#lpz|eK3uV@B91QI(gEsf?q^3A7Xub)&_9S`LSlbFgk z?aGGS($MprE*J0J+sl1Niu`OiFZlgKZtH4?XQGDbr8XX~FF}tr4-IX~*GtOgvkN&r zivg5yhAM1rY3WJvY$}o)4Ixm@{ku=T_jtJ$K?>2;bG>NHtd@e7<`XG$&vb92D@jU5 zMiJ&LPk8+J@wNF9&(Wrp&Gq@<0&j0`Os8sU`QY2m<9#c1n)aa<n40zO*8_RDx}gh1 zfn8W1%>rHjO6H}iil09N6#Zsj_+u4B%()6&{VKh8)nYKX2+c)nBs?Lz=i)Pb{!A}< zAS?eYL<%cKew$BKG%-yqAAIg6T--E1ep5nHl5XJn<<;r0r{4!kB5Jz(4GJH(z$7mu z&S6VDHECKa@kvRL%_qz3@V3<cGQ#X&HKwjYmo%$Y$74PUJWn=w#VtM|p*S;BO~#@9 z$6(mWhQr9O7P9M7<U3J<#Uqyqy*MAvl)beTkbS{F-f~I;C<0Tu0j;@mg*F_VNXm2d z>j;FsFdv1uUW2Gt`_YE1TwIDJ(bzu6t>^H8nR)xrST<)MTdkizJH@E3b0V@)x3E6V zH&b@}8pi@0=!QU!GK4V8#`ZUFs^dfuwPUUz1H(U^3ixrATTsCa04({`wY#D861z)( z{rWHVo;e8L3acmkkZO720sSkS$j&G!a>qe5R>1Zm`rgn=b>NZ%_b;b1&quK#kB*|T zDdI3}dTQ#?X999kL-vST<e^wJRv9FCb#;79Og4m7dGYhH6Vjd=^=v(PxE0mMdwmT7 zj4HHaMT?+O>u70pyVsNRk7-8TN9)#hsjTZksdnp1Hy*qd=-!nxRDQk?yOBYurD?|8 z_V#Yf%5O@0)7I8T|M8wjLSEjAxke`d#c^p|LBfa9mc9i;5>&3w<44PJbJ%3zyEo*% z+`3n0Q{SmL|A5c75&~*<{`?()p|(%a!k*D8YlZ%Sj5)G<Pxd9h*@4r;FK<NDi{B`; zXHyAp)`&XleEj%v3lo#;Fuj`5jY&EB=G6=%9bMg&+@!puL9{>Fo=4?pW>>_tISWge zl(5Z$q$FUeHX$Jm%sGGjlED@gzgd#>V2&9VA8&7o_KgR&-rBS_Bas5krE4um<5^X- z>gK@Sqvx*jsBTm;zw_Y>Ye$S2H-G;4R(E?sM=^Bc6>YG(`HYMV?GC5VPTXOc>O&G1 zmlLJXAu3ayc9j(4OxJzI<!W6^YU``ekIGC73@mJIJsh&^xU$OUO%0VN8q?Pq^Y#0W zX`ExQ#UlH55$hSI^c;D=>GDAvF)^{`f_eiCY>o#Sd+fCsz<WP5_DWZvWR|7DjJY}p znl-~2h|EEQKYmn5bT27&haQ%;b&D0%Uo;@q^9JbXw8}Gcz^=8f3W`YHrx@*$IG2q6 z6KKZ_f&F#UR4=;z?5?+SEuWqV&>jkSR6-N+yzD_NHXo>6rVW!EI#aEv3nlEqLhQw= zX6QTVlshXjUf<Pi8UkMWV`0Cy`>u)hAx<qUYT()`MV@bDr28w#$<?3NbaA<uIQKP6 zbU;~KTl?ke5@i@9Mp<_DJHNRv)75yR+SyV3C=hc;U^-XIP<;od0uN5{-!GQvmS3MQ zXlVGN;5&2EE{s|0Z;Mg9Q;?hc^GX+l7rdAnC+OfWXuWCi@p-<~{y^NRQRs%;fhQo3 z6<=Lth=6<mz<LrHNf@eirGGvat!}0ZOI}`R7N#=rTbOSAHm((=-9FqGh=(3+h3?+H zTlUshHT12w>?476+Ky04nt!^tG8^(d^05@TqG_#|K22zjiHUIoeAZu_B<CNDL}Txf zWAEPGCZHTt<2%*;*2L7*y(Q+jZ*g8tO&`3VB{`<=x~%zcIY61kXMh6AFg1k5WGMKy z0zO}d!1UL9+O>6dI^=SwMT%PDe1esPRPN;^Ikzxwz6ocuu5(M`;1N1XGeO>1eXG&V z%sOsl`1f{{c}g{e2SGAlN46LdOu{;PQoW!(^&F1P;<)t|R7M489PuH0SzTvmXJ8Sb zU?=XoG1W`ftBork>R440sIG&2bpH14LD1$ZMS%7Tw{ciU80WT@wl>0x(>GX}aE^?l zLS}cfv?1mTB|X@Hi%-g}%GMS6qL%29dHC6?MD52&J}OHs+b5#?otm9?61O<|CW{Kv zdoS`R=PC!UOx@#A=?0!y5<K_1V5GV6`xA-f>I|lyXTyR<BZED2;t>G(^U~ozldGU# zW+^CeQg5LX*TGa;202@-87;&Qlyh-$5jtYoNMmpbXe3s<^Cz$Q<m~NVz~*0N;7;T2 zkxIq;l+R(-YVr-zidh=+`0-27W6yU@zvofyg9U|5vRjYhAKt<dNPh1BC`fH9C_aEc z9!;wbEGgZqD^0x1&b8bkmT}+Q+uAzWqRe^%EvKqFIy`YjVTmo4m^RIpS)PnZoYU%e z*U}%%vk4VO_)2rU3-^+qkBDjeH4FM*1~L!b*Qz;6kOrt%_5J(x6y@MLvfr@#ewxH( z+U~LK6Bm3(JZ9&<eoJkRHB@mXq5ad!(768oa<nVyino5Zw*V+IV9sPm+e|vs^--=O zCX>lrBjM|S@ege>*Bi-r$Btxks>)rO#GmyeL2aL&9^tj<u&Hx<87bW~0D_+eMn>h^ zdz?1L#?SqS-@Utl8;{X_ryzweT8OOB+wgT{>DF)YR9_WLyXgBWYFS0Q3XSti8cg~W zx5?`Kf6evVM&%x2AS==l!9tkzm0FM{ql#%MDFVx1hU(m1!FEt}QMPqQsoyTYvqGx( z9QDSAMG)j9Q`eV4wOMtgE7Mp)eE>CzVUW*;ZHCxXUcIBdGH^p>T@i>jC^o5aFSeRJ z^u4Ix{Df-%<ILLrHnCM<=>Z=M&NyP}{TVX~?bGaDp}9bo{CRn!Ib>!h%EXlX{r4|7 z?kkY44)>Q5@az8P1m`Z20Zo*sgVhC?wdn$i8(--p2rLp5X&K~F9T4>lcP=h28l>A^ zD}nHYtiLl7bfT}o1yjH2sBuo0Tyotp+OL9c*d}t}cHho&{mk_;jXBon>Ix>_)Ux^^ z;mseM8G$V=Ef&_+Gif6rW#v)oy=f}lweC-!C#y224f`8|{fBFuP2bS&5|yrh*cnW# zCC%m~+E%U4;kq1$^K=u3X!WB)Rc8^&i|4XLMR7iwLp``GS$jw^^&xj$lVGmEZM!=P zj_X{$c!6rgfLG9Y;sFEcR8j=dJh-pWIB1K>z)b4DICZ|-vCG2QxrhaAH$FY}u8U+P zj%y0ABtYVl++1~NpFu#b<C2n&yiHoOhP`093D9=6E<W6|>y?2!ibA1Kfv#Xd8-X0* zaR&1XxINAvXI^6A41@WWb0fLGO!W%3U|;I&e|iAss0g$a*xT?k1tW@E*xR}K<U+-O z!lgeXB&tDWbsym6ErZIdyZUw;NM1}CWf?S;O}z)Xw6d~WaUSyZFB$;u(@7MHm>`7? zGT?shQ^4cn-qzac20Gv`IRI?I2@I0zs;Vk$Mi&2kSxM-9YpE84)N}i*CZUxM413~f zWJ~bH$UX#p2fs=E4`iIbXN=s$_D9^eYjx#}%3k|%j@G%SfQ=EdIXgV+-KAUrEB{RC zO1|e@PT|)>yBg@~5~g}`=mR&RQ5VdS>&EBM*j=bc&K+<9+*f2u?=v-=UY;hbC5El? zp<yS3CX*cb-L^WWue?7LiQ4Xz{%#klEXPvlYXVfB>r{6ZaDEc-(B%?4=82)>Y-*A3 z{yH08d3U5JOIL22OXoAu{Vci$6tFK?npwd12F216dxew=TVlmZAWAGk2EI`tkdaf_ zn4b)8mrnkYCL?Ct^^VDo6x7u>;g$Vqz;!0ulg2QHkz2CJtA{`lS+?fHLO=~z4ov2J z7-=k8wfwa=MWZJA^4d3IT<xb`--X23*fGNL=@-m(#(GHSUyri#FJh+Q%Vof2M!tRu zkfgje)YC&22(t4%>n?y4PH)$)UHs7h>Th^~HOMMp?Osqf2l@C4plRyF)Ob@2SZ-pB zXTju51xi!=u5V$&!5WELyb(jhEYWq#IPVtjKBuCGJ4H~NG-Kqex!6!P|58L;PL3qt za+lUMwoq7AWdgKpF+Hrq8M$SAIm?04nYIQ%QX*0Q>Yd}Jjb~%taovPMFe77XZhgDJ z(&E#-dDh@1f_a#2RqYT+!b5%e67=PqflUTMYmbYK<?TNc1~Q;~JC9N(^eC3te-a%{ zYEP0mrm%oL2WmysAay|Gt;6iV%huM`UJ%KFomI=rJ`)s*ZcKu-UHMt}p@0fjj(v&} zq*jO0Kdb*|%s$|ex8}4()`u&v-2+D>2X>g6VB^sPbR|9`qe9#?f9fNj-5%<z+BAQC zDCPb-cR&t;D9f{b@ZdqRjHAK8-=hW2Qf_wk@8FFnjc;yrDW`%ElX6)>W0|Y|w&fL* z-FfT(v;&u=x?j#LV&*Ek=;8uiENg{g=lTl$?!CN6rgzEVVm^~X?6JU+e#YfUKIuA8 z4VP;0L!AQ1^=DUTy@JI{w=t*)DKhF1AKx$_z9Zv{cXU$P>LX@c+(8!L9~TuJS{Q4V z6c=v+lf@ZKg_Y1*Ora642aLE>`~V9B@|E^qCD4^U3d@OEb<yL2HlsK6Q_uAP#l1pd z!cqQ*Dh(dgW-=)4!p^p5dEz*q^<hv~fNg;V%}<Zq0LZGYsgaeDVbQd|EGGh?k=oZF zdPm``<`7wN00o+dU!w26f=A|3luxecWis&{EQxaY-`Pmi2GtAP;g=8pO><@`NXsSU z&-N<2^!-t0+h{!+vh)n}NmfBdsCA-kP?3Kic*2vNX(ceOwqwvldzzx<^z<|vgRk(0 z_eCgxY=6TGf^uejKi2%pqF_lGHx3;<==Al?9qiY;T>Pbeh|?|>t1wDSL{|pUT?9}r zaV&y~^_jj74s;E)-oQk@Lx++?SQdX$(xJnLlSPIbgX{g%l1U;)&68TVU{2hptU2vM zCcBN?fKTBVhr)dFXvB=QVDX$*dOcmfAApO+Pm4&KSAw4*PFCuP9&fm}bL{D^vTu_O z`0*9ak`d$c7j@t4|2x-ARt{2y`y~J2;t8PBCsuoL8#v`VJ75fYn9wW?C&Mc*`|<>k z@U?7Rf0<fess+g0snIRws5w|zVi_SOM~)mhaq{GzU}24DVMLAV0I1S`RE^0uMY3Tx zyOLxy;gF&C=fW8A<qb`cvIg*S(K-B=snqSyI{W&|;Py-6hntCW^4^n9K(mG*CSb_d zx(!x6GQgIzu<IeWfNbbSKt>=KAJtH{2N#-(HQkCeN8rYcahY(F<x<!(5OM6vkZUa< z2ppEA4t9?j0~dVABRq$ehC`Xi!;-yplAW|RtN(#It$<|JiFvr^NcPjGd&pkRf-}UD z#IE!AB$r4PcB+kVlEAO%S1RKC@yQ|V>ST(*EawU^S2|cH88TbA`6dDjgEO`^C~IwY zo7pfY+0P5x9s>XYPo{c51t&-XszPxMV7pVElDy=yE`)?%=IxA_XXi$}4c!@}Bm`#R z38}f}x9Q+P6g6zLN9<2Y0#A;Gy{)Y}+PzVNin8FU0v;BJZEXgDaZU%;eRBLv7@RK< z0j1;O;zYC+f|d(oVq*nnBUV^0DE#}8x(bxygt)jdSVnYUzp^t0xRq&wCirb@(}rO) zY4u@Sq2wTH*+>sR+~mp3+bP!9M>WK{a`0=<0LOypn;RQv!6cHB<hr#SHExdtjB$ep zei^?pAx-z(TJgLlx#Zt-iEo-<s7g1eu&FOsDe#Jda-orNjMQe3qQoXlFwFeyS~JlO zLnm6ly#Ao8VWKV3_4A*<jZA}cA*dA4ttdEaX(|-0X>M-LZTANP=d^l$(@o$!vnUbB zLT578H(5E@?_#<}87mI}-08~%LkTf4O<<sDU|G-?+oWB=;~DW4)q9aSSnUWkYX<8~ zK7B)@Y@Lh9N-jPWI7HxARskko2J4*;su&!Uv{|*(#6(9+J4|g_*ygHe3lMf{^~OIk z7;9I#88vb-cru4vw9!~}Sl4HksR9QeF3_i0wqv-cWrf^sIjeZ?4|F5bD_2TODw?dp zK{5qil#SktAo?d#jR*=s6TcmRv%j8i?;~>1aK_$|Aj2(*7RrON%#!D2-79O;_<!E{ zdc>}(ReWx}FwV?(<(i}L?&WX6lM4Z%zl+<N4D;KS;G+}!G<pM{T~UJLS0B;tRF(Cg z=T$k5W?VHL7TY~M7=NP6WBFdLMT`<E!BW;@0`8)r%%+-+Ov{BY>eC<T(~hCmPWPEj z>AhGz-*hLxD#0CQ$8SwXbYF)aEi2kIH~aiNdB!+dhkdUs@fs(H*O%s$=QEmgCw*Uw zqL_CAMY|3<h3@k_1MAbzQHV8Dosl&$mFeyaiPleLU3bfLHpBn+N+F_egTF^hpUx;7 z7jRNyt7C^tc1}dAT!&XhtEf_ZXz|{2Ld<iwO_yN!?t%7s<2>(bowBzdcqc7kVfk0H cnl{6x{i5Svo>_(CFa*)QWT0Mt;p*N01M>vxh5!Hn diff --git a/doc/reference/clutter/building-clutter.xml b/doc/reference/clutter/building-clutter.xml deleted file mode 100644 index c922a1297..000000000 --- a/doc/reference/clutter/building-clutter.xml +++ /dev/null @@ -1,284 +0,0 @@ -<part id="building-clutter"> - <partinfo> - <author> - <firstname>Emmanuele</firstname> - <surname>Bassi</surname> - <affiliation> - <address> - <email>ebassi@openedhand.com</email> - </address> - </affiliation> - </author> - </partinfo> - - <title>Building Clutter - - - -
- Clutter Dependencies - - - - GLib - - A general-purpose utility library, not specific to - graphical user interfaces. GLib provides many useful data - types, macros, type conversions, string utilities, file - utilities, a main loop abstraction, and so on. - - - - GObject - - The GLib Object System provides the required - implementations of a flexible, extensible and intentionally - easy to map (into other languages) object-oriented framework - for C. - - - - Pango - - Pango is a library for laying out and rendering - text, with an emphasis on internationalization. - - - - Backend Windowing System Library - - GLX, EGL (1.1), Cocoa (OS X) and WGL (Windows) - - - - Graphics Rendering - - Open GL (1.3+ or 1.2 with multitexturing support) or - Open GL ES (1.1 or 2.0) - - - - -
- -
- Platform-specific instructions - -
- Linux - - If you are using Debian or Ubuntu, you can install pre-compiled - binary packages the normal Debian way following the instructions at - - http://debian.o-hand.com/. - - - To build Clutter clutter from sources, get the latest source - archives from - http://www.clutter-project.org/sources/. Once you have extracted - the sources from the archive execute the following commands in the - top-level directory: - - - - $ ./configure - $ make - # make install - - - You can configure the build with number of additional arguments - passed to the configure script, the full list of which can be obtained - by running ./configure --help. The following arguments are specific to - Clutter: - - - - --enable-debug=[no/minimum/yes] - - Controls the Clutter debugging level. Possible values - are: yes (all GLib asserts, checks and runtime debug - messages); minimum - just GLib cast checks and runtime - debug messages; no (no GLib asserts or checks and no - runtime debug messages). The default is yes for development - cycles, and minimum for stable releases. You should not use - no, unless the only performance critical paths are the - GLib type system checks. - - - - - --enable-cogl-debug=[no/minimum/yes] - - Controls the COGL debugging level, similarly to - --enable-debug. - - - - - --enable-maintainer-flags=[no/yes] - - Use strict compiler flags; default=no. - - - - - - --enable-gtk-doc - - Use gtk-doc to build documentation; default=no. - - - - - - --enable-manual=[no/yes] - - Build application developers manual; requires jw and - xmlto binaries; default=no. - - - - - - --with-flavour=[glx/eglx/eglnative/win32/osx/cex100] - - Select the Clutter backend; default=glx. - - - - - - --with-imagebackend=[gdk-pixbuf/quartz/internal] - - Select the image loading backend; default is - set to gdk-pixbuf on Linux and Windows, and to quartz - on OS X. The internal image loading backend should only - be used when porting to a new platform or for testing - purposes, and its stability or functionality are not - guaranteed. - - - - - --with-gles=[1.1/2.0] - - Select the version of GLES to support in COGL; - default is 1.1. - - - - - --with-json=[internal/check] - - Select whether to use the internal copy of - JSON-GLib to parse the ClutterScript UI definition - files, or to check for the system installed library; - default is internal. - - - - - --enable-xinput=[no/yes] - - Whether to enable XInput 1 support; default is - no. - - - - - --enable-introspection=[no/auto/yes] - - Whether to generate GObject Introspection data - at build time; default is auto. - - - - - - - -
- -
- Windows - - The recommended way of building Clutter for Windows is using the - mingw tool chain. This - will work either by cross compiling from a Linux - installation or directly on Windows using MSYS. See - the - wiki for more information. - -
- -
- OSX - - Before you start you should install XCode either from the OSX - installation disk or by downloading it from the Apple website. - - - - Note: These instructions have only been tested on OS X 10.6 - (a.k.a Snow Leopard) - - - - Currently the only way to install Clutter for developing - applications, or hacking on Clutter itself, is to build it yourself. - The recommended route is to install the dependencies with - the MacPorts - project, by simply invoking: - - - - $ sudo port install libpixman-devel cairo-devel pango gtk-doc - - - - on a terminal, after installing and updating MacPorts. - This should give you all of the required dependencies for building - Clutter. - - - - It should be noted that building gtk-doc pulls in a lot of other - MacPorts dependencies and takes some considerable time. You can omit - this dependency so long as you disable documentation when you are - configuring the build with - --disable-gtk-doc --disable-docs - - - - The Clutter Quartz backend is built by passing the - --with-flavour=osx command line argument - to the configure script. If not passed, the GLX backend will - be built. By default, the Quartz backend depends on CoreGraphics - in order to load images into textures, but it can also depend - on GDK-Pixbuf or an internal, highly experimental PNG and JPEG - loader. - - - - GTK introspection is untested on OSX (as there isn't a MacPorts - package) so it is recommended that you disable this with the - --disable-introspection. - - - - If building on top of MacPorts, as recommended, the following - configure command should suffice: - - - - ./configure --with-flavour=osx --disable-introspection --prefix=/opt - -
- -
- -
- diff --git a/doc/reference/clutter/clutter-docs.xml.in b/doc/reference/clutter/clutter-docs.xml.in deleted file mode 100644 index 2bad2b1a1..000000000 --- a/doc/reference/clutter/clutter-docs.xml.in +++ /dev/null @@ -1,449 +0,0 @@ - - -]> - - - - Clutter Reference Manual - for Muffin Clutter - - - 2006 - 2007 - 2008 - OpenedHand LTD - - - - 2009 - 2010 - 2011 - 2012 - Intel Corporation - - - - - Permission is granted to copy, distribute and/or modify this - document under the terms of the GNU Free - Documentation License, Version 1.1 or any later - version published by the Free Software Foundation with no - Invariant Sections, no Front-Cover Texts, and no Back-Cover - Texts. You may obtain a copy of the GNU Free - Documentation License from the Free Software - Foundation by visiting their Web site or by writing - to: - -
- The Free Software Foundation, Inc., - 59 Temple Place - Suite 330, - Boston, MA 02111-1307, - USA -
-
-
-
- - - - - - - Clutter Core Reference - - - Abstract classes and interfaces - - - - - - - - - - - - - - - Base actors - - - - - - - - Layout managers - - - - - - - - - - Actions - - - - - - - - - - - - - - Constraints - - - - - - - - - Effects - - - - - - - - - - - - - - Content - - - - - - - Paint Objects - - - - - - - - - Clutter Animation Framework - - - Clutter has a fully extensible animation framework - providing support for explicit and implicit animations of - single actors as well as groups of actors. - - - - Base classes - - - - - - - - - - - - - - Clutter Tools - - - General purpose API - - - - - - - - - - - - - - - - - - - - User interface definition - - - - - - - Generic list model - - - - - - - - - Clutter Backends - - - Clutter is usually compiled against a specific drawing backend. - All backends have a common API for querying the underlying platform, - and some of them might have specific API exposed by Clutter. - - - - - - - - - - Accessibility - - - Clutter provides support for accessibility technologies by - implementing the ATK interfaces. Since Clutter is a low-level tool - kit, and developers are supposed to create more complex actor - classes, we expose a low level API under the Cally namespace; this - API can be used as the base to build more accessibility features - inside custom derived ClutterActor classes. - - - - Base Classes - - - - - - - - - - - - Utility API - - - - - - - - - Migrating from previous version of Clutter - - - This section describes the changes that need to be - done in applications using Clutter to use new features or - to migrate from old, deprecated API to the new ones. - - - - - - - - - - - Deprecated Classes - - - - - - - - - - - - - - - - - - - - - - - - Clutter Actors and Objects - - - Object Hierarchy - - - - - - Object Index - - - - - - - Glossaries - - - - - - - Index of all symbols - - - - - Index of deprecated symbols - - - - - Index of new symbols in 0.2 - - - - - Index of new symbols in 0.4 - - - - - Index of new symbols in 0.6 - - - - - Index of new symbols in 0.8 - - - - - Index of new symbols in 1.0 - - - - - Index of new symbols in 1.2 - - - - - Index of new symbols in 1.4 - - - - - Index of new symbols in 1.6 - - - - - Index of new symbols in 1.8 - - - - - Index of new symbols in 1.10 - - - - - Index of new symbols in 1.12 - - - - - Index of new symbols in 1.14 - - - - - Index of new symbols in 1.16 - - - - - Index of new symbols in 1.18 - - - - - Index of new symbols in 1.20 - - - - - Index of new symbols in 1.22 - - - - - Index of new symbols in 1.24 - - - - - Index of new symbols in 1.26 - - - - - License - - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General - Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) - any later version. - - - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for - more details. - - - - You may obtain a copy of the GNU Library General - Public License from the Free Software Foundation by - visiting their Web - site or by writing to: - -
- Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307 - USA -
-
-
-
diff --git a/doc/reference/clutter/clutter-overview.xml b/doc/reference/clutter/clutter-overview.xml deleted file mode 100644 index c14d02b42..000000000 --- a/doc/reference/clutter/clutter-overview.xml +++ /dev/null @@ -1,62 +0,0 @@ - - - - Emmanuele - Bassi - -
- ebassi@openedhand.com -
-
-
-
- - Overview - - - - Clutter is a GObject based library for creating fast, visually - rich, graphical user interfaces. - - Clutter works by manipulating a scene-graph of 2D surfaces, or - 'actors', inside a 3D space. - - #ClutterActor is the base class for such surfaces. All - #ClutterActors can be positioned, scaled and rotated in 3D space. - In addition, other properties can be set, such as 2D clipping, children and - opacity. Tranforms applied to a parent actor also apply to any children. - Actors are also able to receive events. - - Subclasses of #ClutterActor include #ClutterStage, #ClutterTexture, - #ClutterText, #ClutterRectangle, #ClutterCairoTexture, #ClutterGroup and - #ClutterBox. #ClutterActors are added to a parent, transformed - and then made visible. - - #ClutterStage is the top level #ClutterActor - it's the - representation of a window, or framebuffer. It is created automatically - when Clutter is initialised. #ClutterStage is a #ClutterGroup, a class - implementing the #ClutterContainer interface. - - Clutter allows explicit positioning and sizing through the - #ClutterFixedLayout layout manager; and implicit positioning and sizing - through fluid layout managers like #ClutterBoxLayout, #ClutterFlowLayout - and #ClutterTableLayout. Actors inside fixed layout managers like - #ClutterGroup and #ClutterStage can also be positioned and sized implicitly - using the #ClutterConstraint sub-classes. - - #ClutterTimelines provide the basis for Clutter's animation - utilities. #ClutterActors can be animated using explicit animations - through the various #ClutterBehaviour implementations, or implicit - animations, through the clutter_actor_animate() function. Animations can - also be defined as named states through the #ClutterState class. - - Clutter further contains a number of utilities, including; - #ClutterScript - for loading 'UI definition' files formatted in - JSON; #ClutterShader - a - class for applying GPU shaders to actors, #ClutterModel - a utility class - for MVC list type implementations; #ClutterActions, - #ClutterConstraints and #ClutterEffects. - - - -
diff --git a/doc/reference/clutter/constraints-example.png b/doc/reference/clutter/constraints-example.png deleted file mode 100644 index c2a71b2d273a7f2521cbbb4a4ad0dcbc2591cda7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6199 zcmdUz2UL@3y2n4tsH@|kqlk1z0}Mk`T0oi$B1Vw76ai@}O-cZ10Ybns>JAK|2}NoK zq*oCEX#r$JYBCavv?K@tsgYtrD9OH=*||G+?@rmdv-g~PI5{M5^1k2mw*T+>KVMz2 zG~2sdVmAaqdl6?(TS1WEEeH~LyK4t%iCQS@1OEhqt;~#}a+1_6_^{)ux!Gxm$N&4L zsQ?dJ{uFrDAsB-89N@nMptOv`pmApi;=Jk3(H#dr6+005RcjCgiPa)b|Jf#dWO01d zE@>v4xhy+zM8JCgahaSOXO<6sggS@{OLr=hQ5}5gW7jacgr&&O()#a@Erx|EEROUB zhAwE1ySZaVw59)Ib84T+}9|V223%UWC zPwf(fo`fVm5~N>g)aGd6pZvA4aSJXl5Ptchu)x3i@e$Dc3uFDpum356-`MMC;{R#y z&#r;({TFlm>2H49*Ei%uZy7}_zT$NH8nF~1NMBGcpWZt8A;I>dji-sT^PF~n9J&*j*_N=w(X58Y;}s9?7MBqx6%ATPtbSLaZeW0=&2KG@AJ7eEg`6=nKJBKMa(Lx$sy9x z(4($JhwCQm`uqE*Iu!^#(_ZkIJGa$fi1MgF2J!krq(7Ra$#gz0$m<_(Kx^pe zJeqiT#q1#T#9g^qv~_rRI3zSQf72LUj&ve}F~;1$ny#`?{!~2oCifZonTPM>APj*q z!{Cs1LU?ySKTSl?)Vm2O-N^7(wzRBlbAY1>wv8Y?uKtYcx0suCiT2 z+}Zh}l9FI|0Vs}|b7{Z+K&1LBq!ih#O}00#1qQZmmD}jQSYH|)84C7_V)Pxs*JMb2 z?ezt4+^p>Ec-~H=Erz5HcdZ)l&ge=a`1UXujG~Hwv)x=F#FF#lUC@(*{An!h8Asrf zw^fGUJUNk+)U9#i#6x&AXXDl;9M0?1aQFoXf?-#ZVT;Ma<#EZoX($a z3|`OdA(1?Xf*Yo>3YT%3ntnZ5(@nbAd@UxIJKj8OFSZdsrH~bVR7GW{lr2!(s0(`N z1q-XhxD-`)Pfz(!$+_Tf^5mRn^o&+@OD-B@!W5NMx>+c_Lt|dF)y=2glld7aJ^bs+ z*G|pR1}|T}jPT)DJ2ZqjOVnx_u04v2i?eocNG%|^WKNHtFDfs;ZUe5b@n3MmuV0(3 zRx3~_6m}Wipb%UY-RQUBVa$3j;c0MU|q`ASl6Pmpp>=bj5FE&5yM-JdYQK z!kvuY<6T)0M4!;V0>oDanc!|3n9ZaM9Wqi{hIsa+05N>!mQhHU>VHBp2cu+(g3mu8 z(7&(FztHpF$At ztKt%0>#Gtnq_wq>=#2p0v8t*nP5^C_si=4&32Nzk+yCBVZg#N~U~Flu4xdGpIRMT_ z>nl?`yO~?Oz0eaI<@(iByNc*XHLRMC_wMzG^gOAhRjvD^S+2Ue1P7apIZT#p4mXf{ zDaWCrn+f0;N013=XmahErM~cg0!fit({ylR6adxi&QW*t zxL#pDVnKgx-lT4Yn>5xKs$p$y&Bs&vJ!;RJH}<$(A5&Xx)L7z+kk2yrlzyAZTsoJ1 z;Ve*LCt(@AXyt&W?TZ^5o9eo{sm9q4CLT^?_!uO?MYg}--_<4(lWOo#!wcyZ5~2y# zY*l9dWDFBq>pz|*J&Nub-SPd(h_>#P)OJU%Qf(?qN$)!XFCl9^0|SqEjgqJHDjE}E z-u^z8$N=O?J#wBmnlctk?dh>NNeYD_(!$_!h)4{kFO;a^;o&jN-XfMdG-->9ii#hW zIy*mWEiNwJIb7xS6wMTyiJuH2GZrw>t`fC==RG_aV=NHw9x=7t+~+W||40U3)tWKv z)2c3wkAS!#N;&UNjn2I5w!309gja>;vHJ>+Aa%tC^n;^L^n6t&+pBnt}aIEqemT* z%~9Ca?eui^)FO>5k6J`2Dm9@|E|l_oz`))`YimdR&6_tH*BN5Gxq*6eu*umW4rwbz zjJVM8R@Ma>T86Mct!szDqt*oun0WlR-qmLdqfakoQyIkMUu-Y5L86-%L zf}|#Rx$h;clg*uHS4DAFA`+06meVxu3^@q2KU*+*&}RjY2X^Fru&kk`>xWt zK1vbIr1oxnkX!;8i~}($V$i6{a9d~_oCvEL)acSXeiAWL9sG&}Gp!4sHTLxMw5rWE z+_yUvqE=8S7t74mbItKZ)A1)o7s+ ze1*lthIR>x6xY{>dGiL}PfeXBp$SMF*=esZboq*$c_^K*B_9~X)Z<+&wV$8>x=I-z zMr*ik3Qr5JhF^%r952F@K*Q}I#ZAKF4(bpmog4z&JFxy$x(AUxs{5?yOOAwXJ# zFUOes_}a-K+Ih#b;L*#G=VHxQnwZf>z!*^+0pin5F5Z$kVm-LBSDW5QDHcV7vx_0(D!Zknut*tj3 zBi{7_|0{9;_mN{i9zfQC%H8m9^D`#<a%a=!Zz<3W> z(CHdBi#63AFX>PfdH!OB3m&G+UM`+!6>{w&Nt5&P^W~9-9CvM_23<9&sLv2VjN3}= zcsJmDstO{QPQvn?Q{TGd+&L?Z`!djFgky-(Es(&>&dpf>b~zEAXMv&y@|a&x5S7^5 zi{Wb}>wb+NY7DqO<~8KXtj}c}*b{jKpl-%7GZD3Q;^gEc8wGsF^MKKnf@H6#D1Bgl zi;6GJf~yXY)m1cz_cj=>r@P%TzCtAol{u#jAS+1K*}k)~?~vdy+%=Rq2Xerzb^=fruK;+I5aK(Aa^=cssh)b+mcel27n~SRCZ@)cF zU1!YiS)z?KDg^LYaBtrLa|ds4T&}mBb!=?xG^?nnth1%%l*`si+;Dy9sH+w+ey=12 zlLu!uv0dio=f;l~xa3fR%@ZR~7QUpg4lkJ{)# zHPowRTHyF-MJ;-19M^f^SnJOqWfpz?_1B=dgW+z+Y_9~z2dqx33_poB@kfr6)VSMX zAh>RDDwe2C>7%s)Ug7RK($WOp2cYi`Xq6fPEp6@TCOnhzuJV{}G@zh=aXVNtcv%hFWqi zCc1}(goGn_a{rU99A1M-wfvR+!^`A0P`*4eFi;)0iV>Fm_It+CHl1nYO8~O;XgTwU z_dkW~fscNGY*$K>7bV}T3Qcw)$U`lYpWfmtBjE_tVzs-~$S`lu`aLlyq5VKU1dN~{ z^!{)Jtl)0uRY53x?MH|E+X{=nU|s*YGRvphe`HX81=skygFjmm{@>&DKNt3YFJAu` zsWJ*wz|H`Q!{wX!IkBep_=U6;$;hgsJ7}a^uUl F{s#Q7IQako diff --git a/doc/reference/clutter/easing-modes.png b/doc/reference/clutter/easing-modes.png deleted file mode 100644 index c1cbe1460e69a280682eb256be7eaff86808e13e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51834 zcmeFZXH-b(ty1SYK%t(XQgU_L?iiMR;6K zK6@6t-m^e3ba;IG&cc*w)@J6NwW0C-1A5R8NUYp^_ zg5=`FMv-Gg44zVm5qm_J55t+N0yT2A>_2YQf-{qvh+w7FI_!mk5EB{cpNbFveZv3! z7y1#@$Y4mtpT8{3%*?oCJx5<%e0=iQV8P`;AhQRCPEHyc8j;iM95m5dBgz;~*tKZ0 z4zJ?#2M>JNo&<4w5aQ28j=pv7O6FBA*iV9K^yPerK6?Bt*I@PX%2=iAaZ{5=qjRP$ zGt_Czo4x$1L0fLlHZ^w5A%AbT^ooHmMRV`XunvavjP>gH_ZqM7F8VLdUI)@1qnrF@ zn^8lDa9-?{E#W$);BRF+_OL%cJClwpoc;C8m0QlOuXVkW!e7#wcleR;Um%?-8||qA zn$cX9VW9*(c3I?4k4_S|e0N0&m5`<1^7UB^FVKi5e5x)z88RO;H12h#@T*T{oV+ZE z{evp`17uH4`M&l$R{GB=-%TFuANgQD7_<_unp74BG{V0P4J*3Zg0+~e_bXPViT!=o z3W?uPH>N>YSN(b8*z)Mnbh*;$Q=hxLyZ`L2Fv-Q~F%780J}`SX8KmPc(NXLqxy5Ok z@34zQZ}4rsQoBGvfQ-Vjfa($Q_U+rCLpu*> z?Gd3JHZ6lqe2%f_hUA8rfX5f`|>EU9D(UpK3AyjCDB73fPCAMP}t-A=?^XQ;}L1 zVuy|1P*S2b5OnuBX*FSz{c5Kl1jyLAt&^oH>eI8t>Uzkr=?bw#BX?v{DP~x9V_qXZ zxh;^<{EcWAjEt?)(u~wXIMKXf#8blhe>D!Z95+q4d1xpaVE8SkrCFOAo1k~a+WFL$VRq0Xw=M2l!*~; zhzRZHhsAQ*KK&TE%^Q(0nLMcWii1|`K0K1*szw`=Zuk~83+!l~u z6l8XzXJbAB?k0e{izI7KQ?qUykFe@brY09>V%DW++X$vnjO@_}hvn3-Y-^6bTag;~ zgT2k;W#q6x2pZ9d{tnjVfj_$k`s}A2e1XIEDM6!w0bx-!_o1CmivmtY8OAtI{)uPk zE=;~d_FdEie_mvxTi3lf3c(Okidh~^e#Nn>6oD}bo~m%Xc=2K!E);s>b9O@PprZ-x zq)Ub97)KbXKwsovZ>y+>&v&PZCs{W)-T-!N>>ZC;DN^hFLqyv*rYk__($2$J9>gqD zll$;SJilG0lBxK%uC6Xa;)_OygvR+)#dhejE3cU%p3iEUL`BvyAoJe*k343EggS@;UaOwlnjv8TXw;>?T_%V_~5cL2FZ|R^jgSF`iz~r?vkI}0{!I62R zt8q;H(MR6fw?BwrXwe2*K)j#XmFh@J4lGr)eEa^6v>j-ET04qHSu=tW=>`q%s_vWL zG<2}IS^OKe@yE9WyAoas`oz8zXr)F}QN!Hh{e`RoC@3Se=02JX91&-FOAbG`LO&0W z=;MPGof?05yhxVnRwe!nDCu+O*8*2H{;S7_ zclrxgz6p@K{7_Nr^nX0Fz^zy5nukC{K!5qQlNN{qT9)WoYBDugt}4vPzCHU#Yb67j z5cjH{iy$Y@ZHk+*)Nyd)L+fMJKSsJfBGZ){PwVNV11A28reCTk3>pSh!uAQCm9htI zvY%mQoV`l-f&J3F*Dip%hvbJwB9?Q*Rq=fd#~=MOu#I>Q^?~wh94xV9+O5&g5ymiR zpxYA^l3@naN;Kha7) zbKZ{5d17ORw3dMW%?Olhow@D_mzj#tFS?~m*$_g<*hSTr!oCXg6ry`88)8Kl;ik(a zm^Ppmshh{-#IicZrowZahMy%GcE65oW9Fj?Y&2HKt-?^68$Z}BOKod!zQl#9ou;Hw=g<=1Rb-8|IVSJ#`RWQM`%!+ikhatU38#J)e*z1{4`Vn!)NG-Zc2igZwh&v~l zs2L{eeC94V$HxouTD>#UNR5k65C_sUqB2OOo2i9!+%k<2G2d`P8MQDA`GLLzz?zaRZX-Ge71uMegumA7A5LHb$7*iKL4awH-R>Un)2}qI%xMD}-%6}eF zGzsuWUFI!T{|?jV_x~I>VE^^Q|90#!_)z$tPbX4Tz+atv_~nY0eSC?GA7-f7v@ltw zF!Ofzslv>wJ(ay`yDOEw+;^r!ag%qaL#L)E!**9|r^6a#EFA*p(<~is=--5-TxP`X z&R6*nJLjJL-Sw7({oUi6W3Jhu+heYsJ9)3Ln@yzPk?gf}MLib1CZk zJNYtYkcObrWT1^@N5|Ck`~oDw2X{x`IDL#hD*J2HIYo7Q)H&(g&dfbVwVf-@V8aR| z@%={Uaqq^B3%Fg?xkTA-igWbN{*!(q_ID@IyZgU?e2ih_zu5!!=OY!4>%5i={lw;u zb8n`%?9EGs|4onqn|Al1qK7hGz*r3yB+1;PW+ZMiMKW)-(TZeV(XVi50+!%}ptmybUHBr^viIkURMOx1bjPs2^PKC;DDx7FGMno?UbU0{-@R%BN6^iT zHKfs4S8)0IT;5~2RK^7umJ-W~v%h8&q?&hT6Ox{(h2poC2Ago2DHXf< z+2F(wwzsn}6{@scTKP?B`Sd!W%nsPr?zB$&V`r{?N)_k?Uk3U-Dbuf&|N6cxZ&<5e zE^qjj0d4zlPK=7{Slauc%`NS(_o(l0q=fIy@tdz_FE?X$#SR?93D^FJU#3ELX* z6<^Ef@c6Vd>+m@B_;m5!o$%>;KV7?@(!5sl{bs{z%?lY$d*6O-PWx*;&{6O5^J_i% zDQft|{1k3*K**4B?&PYx_W6MqY@y86N2-thg+?4%{2QsD88+g7+shJEOfJV*qc_jkI8W4+a2 z(QYt*6&#RE3-o1N((V1nuBY24p47WXJ^Mm~5{GgnD@6BId!E$xBfcPckit){>`0~x_v3W;A zRQEjeP6vAn>ThxCsMj@^{J(bkK)QXLNtNwuP|j9lp7?9?uRfjX&%i?F|WzO^&;S;%T$s{4g7z&Nz{*fY~^a zAZ##c_HSamVi3c#uAngXBV1@Y?%@tYtz| zsH!VbW$2yN2wQ`O>V%<;zncra+3M3770q}|Nk#LYwZiU7d@o7E)Xw~R^N~S$<;};& zFyzMbeFH~xNAy9_o;{eUV7k7SA!>P3FdA2~X?o5$IB#3qXA(RUdN6n8l@C#rM>x3d zkd&I&VfQtD08-5|+hD??NOs7d&m!3YK5sBBc-9W%v%5+thY}u3;MFiQt6RTUG>!g? zYOy>REd!f?$@;(+?=EV0b;-J!s3Veftr_6>3ceRQ@XycBk427ewjGgb{M~k>Q;uY`92#E*xzy^2 zrEG_qx18HK)%0*|*8yQY{9t$bz@llYJg9VkE&BM)x*yTU8#lj0 z=JxW7MxSS$W94;571(C^o5Sm14T2V;dduXYX3{ssqZA~U23}uEm$Xkj2K+EN8u#|f zd2iOM)!!6bkFVTnUJbBW@vj7%mBz-2T>{aT)qM4+HQzr%2T9|B_p~dPT&Y=g-}rCX z%G)l!;1!vQmzIq=J3R%P2~X7nh^yJImosTK3+yQI78~j26m=N-dn)@%${hA!sCR5j z%`X&a9He%W$Jf`Ia8tqSO|`pfv6vS?=iW}?RB;n`dR1`&>UWc3&}!}>H6%+GNXWx` zzZh>JTCffzYttyt~%0zKy?; zraW&b*PNKXPOBxK;qJCiGCl{T_~3eE4bjTi^?M*zr!8Z0@6V7{S9>f~NnUY|cq-9F zd1?dBar6@!Rst_-E4reS-%^_*PV}Jpm&#b$`E;;b+Bx+cE@Z*HNi6Jii9<7@PKA+; z$=-}?UV6w=%&(#^k#mJ6)-J2XQeESgCM~ai>36fY!sHMG2Y!>T!sjL5|9o^w@_qXe zQ8Nw5T?TfT6>ZA_biNlz3#?h1%RwX1ZJ^-KWkPqifl^k;kW(}8DBjA!-I>%GAtY>v zqB()uIx|g*94*!2P3+F+)nl6z+Gi?nit<^+~1JZkP#Br4)d^OSp^`MNJ*%beE7{w`4z%+#B;_=OPRzu)aWOWG1iMY6M{eYj)#1gB+ z7x?p`4&PF<_t~RXe&J6(+1C3)vmxm(m{a?>mV?P7cG%|C+s^6A!dXM##5F1?9%6Fg z)@hs_)K1Wfxa@dcDumH%D!{e->YZZif8<|Z^jx$X>H6nW`8aB36fkH{;-`NG5leR!c6jOrcuU6n0+U=(DIU1r}l^2 z;+RidNaT{qb5}2=Wq#4!Ql2tfXSFMQ`Lwt|uFosC2`&lAA%fAY{hV16BbuR@=SH3; zYtZu@+Alh_r~~u&Z#Wt1%3p*wX|3C~RNPM!KR}f4u5cf?W#;Z^#~~-FE#dtRG&yr( zl5A+sj?m{^CVz+9BRG_9WR~OCQR|ZR$x7-SuE0n@mSUm9ynGiCbP)d-ol@Ll5tw|I zZ&)jerNMnVuVdQADsLmVJYgz*R(>SlJe#^0gW0av!9K}Cs|T>UbeoRh8tOx)+Zsdu z{+a)h9(*)#!h7c6_)TTzG*NdZG|WRdPV`~nF`kCm2GPE|yq2;fdZmliE;aJEOt0ib zX6@~5_NpK3Ro)FTUkNDA6LscGvM?As8fCFHiaTXPHXKn59SiYW8&r=Z>(x-w&(4ob zGJMkJt({&d{8RMocz^3J!*Kjy_WqWL_Z6lj_{D}yj|&$gzYE0h-2NmG6Chg}RMwts zLFFECLdlTVas8t!6WI87be5rb{=?|j=hIiN+(&#OMQZ9{lLmD)dh##qokZXGkF)6t9K zkC$52O7G;{*l+R8_wRHlGMcQD?kBv&Q>W=nD)hHniu2mXX}&n=yK=jH=RzF2J$1DL zx8qXd6XZbrwAaMER#2jr`~r`i*fqTw#~orZvOl0g?FRkclNuOI{$N< z!73~zZgVKNN0SG2o$7yvZM~bY!?vAv0Y4saIt1i$7HT^$Fb?q-^Ax{SUCg=1ptOjP zdRUm&XmhM^FY@GVVVlsD3s~(rg^~8hm*=E*!`!KDsy6H|uNPV%#e76JhN;WAM()2l zIke($z1}6SVKo@E7z{U-?Y3zvp>m+qduA{1X>%-p+O%MgXr#Y;H?_89ohz1{<5x#hdzVP+N9l+eiLR&a>0LNGz%sm32)QK=c*&d9;c0*B(S^jjSDVn@e!xS1XJ+68;0S;Q9Qqn}>z z6FThN@>hy+a)GZjn4SKUN^&`aNXK~-vVt0pB7#v9Iuvy?N3cExRTz|w(m{3Mo0YVx zW$AjbHdxDrGNgvDop8obn6_;{3mZ3$xU@-3iG)~?dc6Tk0gv+6AGt&@s7kxNVe)s- zlJb|B6!&kp*N*i;{(;#4(GY{BNo2^)035KVI`om zB?Pu4P1K9g+8Z%3YlV~h?wR>ou_x>Di~|RK(EH1wB`t&TS5_yC+6)g2P+ zV~)xL`z*OBi-w%K4nD)tjq2`~YcXzQu`JbM=@=ZFl$qsAr;l4hRN+k_yg3fa@Qjm zC6s{aOvN!83G}d!xs3eGfCbl4*igjs7=Jw<_u}%td%|m%ouQ4G>jfnRTg~X-#eAoX z`XWrkkC{mh&A26$>>JRs+v@}un9UE}G)l`b>N@EjD}S#P>3B3VIX|fQcG3M<506;5 zZ4*DQCDzKeP7Y@Ju_W4-EUhN&Mncnm3+7pJ#h;&aupx&rS=4?8(wcP?w%i@v3kEI(WB%M)t`8B-^n2d z)TG63`CO5M`?BZg62T2wA#q)-aQlADqyZzBG!(9MP%a6(fU|BX+%4I?seZ?dR%}v% z@RF*{KO7a5^QUCn0(U76uB>L<;N8Ms-GIW4KQ9iuyigcsvRcnKmK$ItZnhd=v2o9X zveJHkbwo)j)URx3kfIWkk9S1tpzj=wmHUl;dZ{{vyGSg|BBUs?&btZV|t<@SMgtYTSW#(OtxTP6{on{LMtwys==ec)!@L!9oyI zx4ok`ZK;xv%MIwsLJr<<#5};f?94Cs$+gcit1wqHXTTn8#ZnRY(RWu{2ZnWn;mX5d z7k#Sm=EA?zj4WI7DEaX3#~sTeMh;BFi~V)xsH@fEm3>3mMNoT7N@L2DQ5QyR#WUFr z7sF8dqjO%9>X#8q{fhYJ&iC=Vc7J2saAWfO{RA^G7P*QRtCh(fBc_)7t^1{vSamQ9 z>fK!9S)78XTJT=;H+)0Vj*r0UUKVy2hB*?dn=4xGCiR-_SGQhRC=RfkL(CtO+bC>r z!5b68mAzTKs8cOGG4+kmqT2ko;I6~-D;6PTt}os546xcqoY)-24a{aOM=s%X=9H?H zZ88dRH`4D}p~st5PaB?~;beyeyL9eLN1K_(6h-S-Ri7NMq|qYh3;vQ!<-biwbG;EQ zZE?5r_%q?D+fO~Y5n>u5{)n{G<^I~(;VHqwXC-dE^yh<&BXT11iYC!?QD&x1Z(a4$ zc9OA9-{>+|bOhYsy~R?Wd{sTzj;e-)Yy20s!noNXH&#b^_9}nM53lNseDXwZzOx(upJ~)<{w|S4_eCNU#CCn__7oSCnUR}^+@R_L=jpG7?Ns*{N4W>Zu55dKW_a0 zX0+hHd+Wmbuxt=6L0ZlKcdX6(Y1erRD=Q--qZynv42h?)RcEr;a-@0WTY`H#T#>;V z%d70aGWs@u+WQDi^dq9Q^QPb_0{}zwi0UZh75tF#eJJV_a?h z_7=_@tMR|%HeuOEVTgWrZc$0=N7>og-aV{_kUKk8W_bj1sWwlqySqYOgYNY^umR07 zn}-!&UsPDVz4~C<^`4cmxC~QP7@~BsB~=CO#W_$o)n(BF;zcrx{mz|<$7CTN5%8JM zCEXYh8j!a0Gk0)s$eMPghQ(SoMqb5J#KKs#S-)^P@*E4mE;?*SefMw|_#cFFZXtqUDoN*WX-RF|t#fuge7EehnRYg2RG9ydt{a!#muyyRj zd&r}|fU~~NXTd-QXtpZ=BcTY3vEci)PysyluVucZD*#_zu}nov*5k*I=Rgn*mM36D zk?J;HKS6?*f~UhbFVB9wc6DAcB7m9tBw#bHh_G>ui!+KCK-}3`moHBtSMtX0X)>53 zMI!8xwr%?6AHnSU_d$Nd@XK`A7lt$~K_{A=`dISE_b3G4u+q_2|9O)q$iftcvj>i4 z<>SuuVD{1oTDI!ufGG4z*_XjWPIh+oW0j%7H*VZ0o_6I7BL$+b+$Lg34D=#~Yg0|Z zcb#jzN`TwatEHC#h6u7)b=?00IcS$I@6nK*h|u!!vd=nOMs!BYL{nV#OO>WDG8JMl zy=O-A`#5*(Hbx!_EKT8>TA5%>Lfe(@4%dR6!K8#uG{RL_HDO;Z|rG6dHOSzt%_-Xh zi^{XD1wQ<5TMmX<6HURmwf4C4vrNc$@BQh|HBmZprjay9xG(n!>yryB+05L;BG2^{QfY-~HB z{`&%;7v=#}UT=Js9u9M5fbS&pk-pWtU(L>Y*T1E=Z+bb8S49Xg7sq>Zj-G`GDtdh~ zL`L4x(PvInsbcL3E#dYnq$`d{T)L)`S<^a~@N zKo7We#e)vk^7hXy9jK8PvmYB90rz*?*`ngx*RNmaHBF-=@73$QVuhZ_Gx{9f>Rqam zcm>XfG#cIbv9+WP1T@!&#_m!?1V}r_Ba8!84)&l3>e+(pUx3?33b$L@<~=0p!Z#R6 zg=z}A4EY%Wvs3`nWw)HjC>CdY7C{Y^?c=Qzk+DW^SmoOiPq{}?AW~Jhi(Iao1A`VM z9tIwa7_+)jySeP-{lf)39mUKaeVkT{;yEu&>_g?Xi(z45YO)2R4;^VW(z-;lxIpBQ z3BK|CIEb5yw)B#r*;lQdJuj1`dX`pw|BL;!B{2cpV_nt6#u7m#_*Zt=qoU9HpY@m? z!6;Z_BE`UmDtf`Y@k0iDI!5#*Mj-%_QA9i|D~LPK5{1Ob7*Wmunq{4bRq4Mj5LH>0 zt~66H){SDK;iE#q_S&A#^UCCsBSd%lo@@b_D{@9pXruJw7BY`X*OA@~d{16+<*xe- z5jiuOrUOT4wRXg8W>edZ6+2!?{|qDl(Sc+~qTXKri>o*Sp0n2(Q}7CK1-~idh)sO5 zBQ_!N1*m04AK8q8nw+reL!_48m~5vI!^cy@?E*M<;&Wbc+djRUOv?+?_(*C(_tZ$D z3~j-cgs0L%#x&O$Kxa*o7{_))^%r3@bfBFks2yo%9?4Q^ikUX38@~mDTcpNiJI`S2 zVZRyqpFf%c*xso;;hYQ^1`c4z@_a5+fKf?xQxR7_tKv+LG}8K>+Xfy-4JJ~NRc*Zs zKGDbMjr=jBT*&yT2r~g6F8(YTDun20?xSO%DFK?Dw#fSchT6DM2m`F<88u=fZ#0D~ zZ;2b9pa_9*L1bfqzeL2f6Un7~;NDj66{FAk0A;IY`u%_$M~iISsWOFqz7PVe9@GJF zuPk^EeX9=~3=<+SbVuP!xb9h&82OK~ov@uGUa@CM0srsgdshcGL+>G6#$CkMl?dfDa;5x5>fhGdyWQGICShALHYpfG3#bCNUCU zq@&qmcfu)xen58Y@_V?(I3oUwMitG5wY9xDUwDIu)u)+b%FnEz9OZ11TUNvYf^t7i+4QNj)q6K)FW}dX{ zLq!TEakx6{tzbEQVI(=U)%YCzb@)0Mo{3m3!N?3j^wAklv)@|-rDIUEA6#$5E`ATD zr5W)Qj%p*?kVMB@t_%ldIZ_Zp*iwet_s`?K|)a=B1}&vNLJ5$`ZMi&zc|-;-eY) z)h5;lkE)AFCd&M}&nkE{oJ2iIMm)b%3t%F0jYl`J;`V(8uc&Jz$v;27LEr>C{SVKO zJc`oqe4C5hAaZz5?dweL`Mi_y2`6NG&iJo@wV%o;IYNuZ7I0Hh(zLb&I`Q!bJyl(N z$_A$^{f_Bo`YyLDip)^E!Z(%*k3$f5Mw#u2igd}b*rtx||0Iu92s3{{R+P;VPXCrpnY+Ksm{RJLph6O>6=3|u$ zSq~|6Hh(?j75`q#$`6-MYX-fiFe&t}a^#X1GwE-0d>b+IOywMS$QRH75A?vjN-`lT z!r>VxZ0{`;EF7z+7a}Kc8ig9O{sTgt`5&LP{_jsMK!e;fD|H3vhr0{>p)gFir0f-3q;}?*4^xUU~ zNRb)d!tetKlu`Ia3RZsq7h77dBLY#`p)UICU|Wq_^U^nfBv}T8W1yIfXAg-oaMcGp zT7U_->w^OfIKs$4V2JYFav6~C08U@IG9BlVI*m zBJ6UoR|t+UQjX0b@Bbyl4ym9UJpdDfSTU}DD4X>=BxtK7NNt`dohl^eCP#({H&OGs z^~4e*aZWwZMm~jq{Ur`?WDraig!`~fbiVw0(MdY@b5#S+;JtUrj7IK#fB<^M}U*<4qdZP!xXb_RcHArF&xHpNk*<8w0;33RbD|7gd1^bl4 zal|FRkla5E6DhbrbkRr!uDoGt;qcz${{_M=DUD;7A*2Iv9f_w%xj}0S5Jv|X25w*$ zh;ho!Arb{*UQvm8)}69eLJ#QAo!>t?dG7Scbn)Ctl=&y_FxgvDUXMYQl;3WdcAF3B zAfhzVzhX}$E6&EANc>BR_!4?cr2Yxq>k}hg9xgqHUeDuqMxA1K{YRZTGfAH(O9o`Y z04yK|hpiekP+qMXL}jIv?;cf{xb^X<0@q`3{?5)`M^_w1R5!xbKp@q?j~Oc3T^@!$Y}Z-9QggvJ-m6}_w{xy)QDCeiE5pWnN;oHWc* z3H)=-xj_FJ$P!_zXk6T{9~WpTvP&>y=kro z!gL!0J5@;Z)f*Wi5ZDq1u|I=>-@DKUmIQTx7Xrr6$~hSjiQr>T?e0S7r_6JM86=L;wN|FlgSpg(2fdCsWS(3R3B%CKs*)=Cw$7>drII!eqY%8;~&BKaK|U=5?^l5Sn@HDfd@hj^e{KhCd*jpA1OG#OR5`ZSZy zVT$sTl`uu9gYciksJWcW{vHHADYy{9wQ~7?W3kQvZsoV5%{1@t+SzP|k%!s%?)eV;?_b;T$)UG%NR=>?MX-&vj)$2oJyn zO1QJ@)=I{`CZ#3~tMf62LdHIM_$GjXK`fYm%QQrT0wnYnza^oe`(^h<2;)STxb~1> z&GcX&jYIs5uz!dfau1RMaoQ=Y3K01AkxGhT$Y+EY{N-M6%7QA&uf1`x3Sj=w zj;2QL7X-2atf*vLyDdrHmlcqQ!;xnF z(~%YmVFNSe*UR|_g^C+QByMZ4WSHDOWeMzWvelaKKC_3-2ZvYqYXmY>f9apqY8w7K zHb<3aTg_O$p?i7m{4`4}W-%MWEwchUcblmS)=41JLK6oi)xV69F1pY0_GjUAyW4Ri z$OOq(N{t}<4fyTacU8?Zq9B1+oG_XF`PBC2`}wD~iRVb`Sx5z-A*EyFo8;X? z$ZV?h$DzG%q{yR-hF@S0c*}~UQ?d88_j9N(M~&9+;{&Tw#*H7CX>&A9Ln{(kmZV)s zOWdC@2Wv={j=tIQ`9Y#`SLa{GaEsZyn)4jZ^yT+E*fPhNM~2iJ#pEpe01g*g-^{}e z)$fK*H&^Jzp2`_UUdGNJ;Nk!xqIk^$1xf?RScbPZj!HnWo zi80fikNk}c)^Rd^jbiEm|AGjiRo-cNCYEZ)pab{R!=+>-gG8I2#fKVEFT1DP$w~K7 z+#Bcj`=sYKdf>>LX3vj)dn2MGsCZk0R+zF?$x+y)khpZq-3_FrJDS1vdy#-rn;<=* z;_gc=T6{btbnCl-s`y4CV?^HX@=rPnOSA7RH?pMy7aov65S2Ul7sWjJPOkOM(%#A( zDx8SwUjNdF-|g4o58dk5nIi0y2#`DL1h+iHk;{(e-dp4BOyl#8Bh@5c>CCS~c)Mv| zL;Y?b#5;!kxwyXmMDZ9vHUZq!1e-3W78{`}^2@fvef8Vd%kgNtFn?hqlFA}TJr7?9 z0>Kr3Hc6|*7YDd8)_8S>9C$QulWnw&E_K<)JU zg_SEB(}r9QIOSAM)_C&PP?qS26LImZBs;!|>5BV@qX~7yYLd6O`Q+KB$p0v&mA*`Y zn*8#luCL~h;H)GerGY+mU)dph5jLI7I(QrU`_r=f@>+TDz85fvG7sx3Xsa9%r61LKo_t|Q;No{`thuO_N(`!M}4mPLsB!s zzZ`bTDOW4DJ1Mj|p79W&V|2`jAk$-~@Z zd8ovgb^;rYsRhPr`!6p<<65Ee8{wR#u0jRee@WA5|HR}f=rn8)q(n|Jkymq);++3uB zQj2q09J<2i+owUz>ua<%H$Fe1R_Y$jF&Gf9ZKd%8`SEEJA{Zmdx)7A%N1QyDetM` z`)AwTR!i{eM-$Ou*OV+nOibgry~lj=CcQ-shG33!Q2{9)U2*Yu*+j&c%hTGq9o-(h zF`RXQj7aPcbRlOg6Mf~a!^S+a#z+*5 z&FHRVx#urvJfdASpwm@bJ3Cr+)rz-d{KQu-_xb$p7I?2#wWUp*iqC92px=X5iyT0f z1ayX*>Sp$un#;Rr8%BK z{6{{&RHB%4lF6=R7n@upVDMs*+`tH_b7 zfpSIj>V98Q>|ax06G8DCHI3}XV(a2r&6C+ufF{q%q8(R%zG0PhPY1h3^twAwKCW;C z|9;jIy$%N0oqC0qc2%xV@e(2Lq|i{9yKqrL=LuAA|H+lMHa^3mtWj3B=h7yG{`+~D zB)21;d0=yN0CqJUUh&`aeLCWTrn_|j{$yaL+E1rhmTIOl7tfl18S!4!hj0kk_J=zj zIBqo5;&E`K2w&vN=XnJ39b(AeroZswKL7hy#9 zpuEz>Y-r zLT8y~OUWU2Kxc(Lkat!fW%C5^#&Cz&D_A!C%=15QOI@X{E&c?1fbJJ}D%mZN2*4D{ z-9opTE#wEi-t2EZ&s(~dPgP(3hlS0(qAJgJ^&Q;FtN+a|86{JYV|_N=la*r*mIwLU zme`&tyxYiedqYYt|0d(84*8EOO6AQJ`&#Ro^V(SBxX|kFV$@<%dMl$N;x;Y0%lXSF zTrpV+RTRe6o|R{OpjZn9-v@b7P;yks_|&4c+<0F8AEs3R?(m}-JsxDZ%vMwCMP`>j z#`{nX)T_CRY@O!y@*6~&h~M*@^54r%D|(w1-UoEIyJGxquy`3SuE>5^t28UA0MEM` zCZc3uc3?NDXuR==S7e-4KzM5_9D6q|nbnUUbzB5<>_gDgN~$UDI`I#Ans39l>D4pMEYM+gJ8$VT`wu*ZeFHWG9Q9z;sEow! zqu0SFz*k5Nh#9)8%Wu5i&95_#%(8T;7)1MG}bQm<}_XJuCq%XRCDLuI49!SdGSSKS4sU|I<{8mW%! z#c3#mC1-jtbOd|R*UrjgcUwye z^;I8(tm-g)vbeD<@Rd%hnq7}gy0ac@DQmo~cZuC>H#Zm4Du066>lc@Fr~S8~h!S#L zdHJ2~%2QQ>Qr5OKb6%E1&ml(`@P;*ws7fV=fyjS)MX18w{^0s zGBG4qHoj^=yLrtx_|^8sq4059uCH$5k=I2^Q=bi}0?Scbo5&&}_%N3Bt{M2O;xC`X zY6N{5QZ&XIV5P0kNEitH<486`A{@hioO|Dw1G6{PWBS;T#Zo0MqWgFLj-zxFmkqO0n7##0H%Z#t2Y9S%7y zot?7+3pDOg9d+Li2P_TTGLR9lP;Ek<*i=B*=mB9l_gSCtM`v{0$qdvKQr09KgaW5E zCy0k6O&`CPdeJwg2>-jC6*`As1xc=uQ!6`GmX{cqt>8$tLzkt|U8kr~EY~2H3y&JnLdpZ;3 z2y6F|Dc~nN>wH)WrxRCv0nU6Qu3cbHYli+lBY2~??$cpVl40Y>=0YuSq`j2s41vto zF2E^rc_~vpRfC{($7q><3gU#0rwu{<0O8Lt!CO>qF+oQV7S-{T*F9UN@=xW4{n59OpAotHNDLIA;h?dbp=M!32K0LaE{YUw?fm%@%3kF9 zC%F0LsXRn10V*n}Dj#N|EzY>Pd7?MRzFB2p?T{t{J$(i+qw`6vl*R4C*AR`mJLE;h zHz%Roz`&-D9(X-YO^Tj?z-P-0~ec_8#|Zsln)tRfKOcf8We7II_mhCU^> z^?(dv5(g^tgl!#%x$D`c{|i8p zI#qPMJ~Q1CL`>Ga>>a9#a&mG&;igM!)rI${l0Z6jBQ8`m*t7cy6kEXplIj(!1s@d% zo>6dUB(?*z5VpYOh#S~u1~zB+3%3Phk)Aea76Pf+&;_K;49 z0o3VfAw%?^@ms!Kwe9=!6XYatp=63^cb<281HiY)HW<@qEl^vBf5;W~`RNVY^tg{? zJ4tCVA1R=l2+NRmy!zlT@Qy-Y1da0utXN;R8wm?~r2*-iY<#$cjt#^E{!@@p4 zVV`ya1)VNxU#0$xd=DSs1b|kU@zpZR3MlIs+njxq+yEvnZ@T>-V8>QZMk&KQ+PZ0P_dp^s$WewC?|7JY(p>9gCPPx13Vg(KX6;((fO z%&aUbx>PK5NPK=4ISuOHnG$##2f&3w!>eDz!m~q%q0n1ZEo`r=lJO%b-4Mn}u1CN`M7~!v@m%%8bn9pg6}A&N`BdL5S(CsZcpH2fpt~X(`mNbxl(a2{BPo(ck~xnflli%vPr!4Ej9~m0ju6x`;NekFAWKHNdCm zXElJe362*sdjp2y*l?l+U%eXJ$(40R4Re z52!jn`UWoZ^{w`?&syinbi;@4z?{;6W`sUJMZA7@`v}KrtC^-O^%f}Zx~C@Io&bst zL6a}Xj_etz^AqtVej5}qdSo?N_)JX0#ux(d($r{8U_T1ulJoMQ%-+prb#Di#ngTx5 zKbDiWT}}hc9j(9cGt^-2IHjH9e=4|L_{@L=$-S@$FhE%H}RGdWFz@4*|k{&+sMuWZP^F;-p@xcN8K0)Qd00v$+3 z(sQu9$kF#TrwhNwypFZlS{&4`&WkaWrDS5WVV)`(f$9YWO}plum;itYh4@im#aMuH zgu@Z`qpQzeEkC{PQ?~eHP@jzAfyI4S5+TNawL?p%?)3-3{jE+UV=+L5K&>zl*noCb zo$zGM=_7y{p|GzqjDcFUisX`}|DCD_*+!spsgf&<7e7~RCzgGIMI{@?7<%836XCom z#PCq>P$^Sy+VMYnbZYe&)CzAlL-v$aN$vkRCu;6aOy08LTHq#2b+SS zu;M#h=y)-JzGSrXgm2v^<6{BKYU+N`0&L)NmA}NKx==?aU|%$@tJ|C(G8i;?&B+pb z@q8Oo*i}lF)O})`Z)-f3@B*hK0Z7ASR<3iY=w-o6Jt0uFv=T|2%#-{&)U2{^yO)^7hfZQfiT^;2J)P1Jb@ey#EA`-2(o*y4AL(a(>I{gZaFMqj?1 zg6kOUJU{+H|De)YKhx6*ydi8efFu@qO}B1m#&+SIkN^;_>1zvnQKjO%kr7TJJ}QCk zfnfWp;UH!OlsGq|58S*9P7%G^jt$6%x>b4`sgO<(f}8FP05t%0d?&Y##EX%uZ!35z z+pitsm19@id<0;PR-i0%w5x<*0!KA{eb`o;Mn#O(!{Kjfbq;a*14N4^1R0y zCjD&+yBL>l^p0)EdC^--S#q~b%=GP6y-aua5B#}J5l2`i&DNe)7>n`^iVAmKX8WxF znpelJWv{^&lD)g|)eguk3B%=^&Vrj%5}uKoyXV%49mDKmEZci_V01-qfce_ySYm7E zvElMBQineRp@c2D=&5v-mjxXg>A6W%n72Axg7t~cbMHvqD1#L6>bV&&IFGm~VZn8B zFDY5O_WC%KFG0n2qM7qp<0$zk8}G5^V#C{yBzgITznORK0E!;imD~%y(9rJlc2WBW zN#A34k!%!$W~)3{%PK0M9D%AOi#Yk(=*q9Rk9DlwJ>~`tqYldm!M1*1hA7A0nKvb_ za*qBG-83a^7=51N+GlnCMP~Dz!5t*au)%Qhn|uXhZ*SNETtV6DguUrok6mZMd@&K- zzHfJENPvaKp|V6Tf%E5&)S)dzBAd@x)ASqIu|~l+Ql!0HOOMJqp61&JAa|mHJ;k(a zktmV>JJ#uoGz06jC$bOgfCr|}%)bEfDPIerlJsjmHjK-VIMHNsa+S4nhXH(j)F{b0 z=xOOa^Js(A1(nv_C=PSy8K8ZN7Y*_;SiNPDBPJ-fCb(tuAKoc+aU6DbfIfG021mkE z2zH81-H_TO0JP!%zj;poIy4IVmua4~%u={@k$c%*XH~#Wd3ih^%~F;FptJwO;ew>P zbNs=MHW6%BjhyShSfSsjqz0{zK7}j4Z(Gf-XHFpz+THsO#oiD^bq|FcQt#`k|(=}49vi+pHcKQcXB`~%$FhFNIRko+lkwzo_KT3*F zBIhURj3wo-F|s8uCt_sdq``DbN=oq}voCpXhEBTDtfxr=(+1GM#3<28Tk#t19gv;{ zpd)*)(&<98#jOm4QegCT?Vya3`o(rxTzwC@XI49Dl6m=$N`O%pj=K!q%2-`Q^~Wpk z^QNWT3C`ejN-pi%$ph0K&<- z8yKghVPUEhd73F?DSFz;B&h7U$|%!OTLIz*3V2%k=qRO?)-@)w!eJ?_s8MsN&&o`5 z=@F8KXDFmTq|oaugWYv#z>=Az6E~k6+rv}?g^+HolL09RN|}VNG6_;HsC^LcWsw6* zJ#0K0-*r6p!v?qrs;_Q5d-iVzEa&%OCV*+e_VbJ?IOCuI zZ~o&@-3J+Fmo~zw63sv`skL@wXh#5D&RC$$b{l!?{raRa2-^XIpuJ3jnpP_;DJ3V@ zjd<2Ds`-`_)FnEq>R!XTCj*VPOiU*FLgByuEhV}pprR1@Vd4^QNvn+xdr`%SM9?v8 z6lV`$M>%oj%bRc1_=0_%bh4Pe3(7n#^VcaF68JN_>1-&qJx3Y+D%*yD4T{r}XLj(^ zMyr<+_=;uIzRRyz#;7|9>L?mS9suq^{cO=}5M7_vp)^K|@6Wh13MUN!n%uz@kA*B* zOqou7Vk*yy#xqdN;w!+pTwi*!j6&AoKx@}=>f4KV@^y1BfczjkH0tIvDjW~+Rq3u?*^p+q{8;z&?4>bRSW#Z^2u2S6A7pC75a@p4WR)STz}E( zWAU;+DR=liof~KKE;b_w?Q@;MY#AHz6|s&WbQX<<(=}I1HVX2#P9-a;-a8@ZVZq&l zPDz`ueHV+PL%D*7T4V=;)une>4P3I%8Yh(ULU))i>HykBHCtqB-4092!g zYrF)OnqW%V>a;=BVh9~8cjXtPJ!R?-Dd?XBg4W1Fri*L?Letm)s z6-@ez0Wgez9*WxR#2UyTiydXqsXCOtZU|1W_{~hfrXe_9|ZHi94n#nha80Sv8=ER|w9h1#ncoW4S zf1LQkH(Z0b9l)ZS68s6Pf%fICDGV$e`PZ^ecOIuP2Xers&8q2hEzdI5`mb!AS_Z4+ z=tU--hm-XM1O5=krX?<>&r&)TU!pDM!eI4{rZm#YNdqZSbaGNDkz6zHT0t&yvlctK zEt42qa1trzB#`-S-CL(%G5d!tkZ6cIuv)M@DN4fw4hVpO{5_y3Ymu|~Jko(pLHrw2 z2Q%Uuxk`VrXe;Pk`OTEkHmw4P5^uNOEmQ*mUHEZ!Wo8!g&bRKF03@X#uN8F;R&WZU zxsl(Q*9M4Xv;X&VzZIklzX}i`iH~SoM($#rMcgplWGMgW-JYk}cC=#vK9|S~4_}vz&25NbT*ZX*+%a)mMO>py2(^>18 z>Ivo3BEtF6BTS(uu+gm0ghZvkUl~3AWaWZ-mQS^8_DTubmdg<3IxSqBZhU-0-E9IZ zF4xKPl@Zyqmc8p8Hst1@aRLt*ua=CsCO05|4Oe*OqCo4B5Mbd{5dDfSP|27F47{T) z_k8k6(SJ>_g}Z;e*fyZ{lv9uSQgBsqDKA7ZTK$?0s`g8IZG_NSE$<03^R?1I%V)pa zj^VUrkTtbtTLx04teo7;nse1n&toG>CwC=nsS_5c+h3UGjVKA*QH-jHC<%-#(kQ^& zgg0FNOfQykT|=^3OnW9@6-Lsreq$N|AD`iS5o-y$+fRH+(2YAWll$UZsn6x=u>V{N&19EL<(2cozB7a-z%EID0N1OYiquTR__Yz#i4TILaCO20aV>4>e?YpD{ zc#CNkVpU8~+R9_-a{~>OA_F3i^Y24)9X%oD5uVcz{jhB%3%SF4osr;^1`g-)R|=Pn z`S+)KML=9&`1}bnO$Kdd&8l?SF(rw`R`+kIU|>YzFi$<%gY1qu$Pr_t(HiblY`$aL zr$=_b8RAK+0G(%1BO4?{my?N1Oy2T+oX$~~)ZhIkZpucNr2-4K8^|7U>iblXJ*cdk zL&?!$-60erleiCeKH^v%iuNdyH%O0xN6Oc3X>`{)Ivsoh*_Qp-U8T$D(a_Oqhnm7Y z=ek3QzrsZ1iQfh6j2P^y;}7S2GUf!0769!M0^<$@WEMs}R8xGySqqe-2G8%05Y}&{ zv;IYt&?B)Jz8D;ErI~Ssh)W5G>QC0#h&TnPgqe)jvCVgHN z2kT=D#j}&_%tI}+O(vDPLrmM^Z5!wG;=IHQh}EVT3bE=spWJ%C-VX-;^SlXT!Z1yB z!q}LKV)2&0U$l{H8)2ryg$o!d>B48THlquVjI&on01(zpTvVUGWY{e?-DP1vlHyE? zl<-l08paeJk=K21)h_af$)%nnEG((H44=&5%JWjz>OX60@!DK=MWAzJ3oBoX%2PnI zT-F)rEulEv%~`!dpG*GiwviNimPfiRcbTghLUO?rjlx~eU3#R+r|X(-5Hs97LIF2ZsRMVXXY>x_71=@l(ZxGutjGVz~jE9x;|&(<&5 zIBHa~o}IG8Toiw!tYdS+*gCv8DtUNIvDfA9P_J8M^A9K3#AE0R8B{oKY-Zi(VqGnp zzj%msr!y(${g^|+k6m@?Mg9@{cgiRXA1T1>DGsqn`%LTr*f=elyrcXcxZpp3rV*>Qv-v6_Hn*X|#_RhLMQ7c7yO&$V@$SK7;1cprrXSbVhaL>GO*K(1$W29WPHndRLYKk=wGAl?Q zpxQ(v6g0;;?`KRf2AfuY!FqaC0RPFojmnyC#R!3=3A~3>W4kJy>o(eMt^kmpvfk>X2AW z$(bBdfAsnkwTSOsOi@z2d0jT8C@g2Ta3w4H$#9MyDXlleiDHF0)cx`+Q%zdWB{yK? zF%VeUr#!E@3X;8A@`uy)3V}>2*mTohM{q)-1v%y| zR=O8>nv)EzHs#0}W2M^7eb1C|&Iu_FcVfHv&dDwHAGMxKx@q*y`%LxyeAZ&QD8T$W zH8clKjYuJ!EIeq<(G^I@lD5ct>=`6btEE=L*=kfUs4Qv|Wt~~9m&te3C=DC+qENKx za}Ubm<|($Lqq}TGov#P^)y^}>o}_7Uw1Ah7PQpA}p`A3sVpC>V?v=bnY?7YLE~DK( z60Q;X2m{$jYi(;+o3lY8`WP<4rZRE{Uw17&IMn=vwJwnulC-;PwL6f|?d=<qrle$i~EUjFdg(%vA;IwsyV955sKmV?YiGo#Zv#fG!p z0(M-3v`K1XmB0)|@Ygq*Oc`!`;BUdvsj;rTdU#9SzM@fNIMG4rlUm6{4%2_}eZnL?c|u-Xh!7yX-8NgV?OvsJ`KpNe zn2q~s$~znFzKj_fv551E(K+vyqAbDQ8IWV|YG=)K6VOoyxWMh29jUTh$k= zUP#{3;%Fo)b=Cq^QN3c|D?-YsYyWH5O#HRYyx=Zu+RG}%*_X?!7ALGu4E!<*%vwLY zkTe`1{!;*7=rTgh19~QT{VA)3JU&Gub7EN0(;1p?+OwBO`e!d)t(0BCJ1F5oP7W9Y z7A-0G)Rb{Nr=><_QUD=6^ZS#M*a`Q0vDWbd5ngGz%eIp|nqvC=hBA^Xeuzo~nd>o4 zBrf?;Pv`5EZK(y;?q+Sso9*%<4sJf$dq*#dAVb;Hlc{r_qY4&)_E5XYg`=f~YecmIbfIwHYES65HDz?~_A}1Mm!8N-maO-pMV3P> zBXI1MPvr_#U%S}3Pv`5AVp|nb&-HPehfkXZK^)OgY>!(UrOPYayNvq1!@AcbvEkI| zPHs$)Y>m+7@Mp2yjnvDbnQAv}KY;O9RLVg*X^uw)+z;655>HpLaxYFxHsNkW8`=(y z^~xil1tM8RS0AU#3vC{fT@}!g2%pl;9@}&zmgi*pga3^SDp_gyQ$;-+ zOW+s zFS^8w;GvPqtwRB?S0%5#Xb2GF;bGd^zrVmW>7uPXE8-la#emJwanpV~2L}gY!}>%l zETS&BL@e9GYLHNQpa=9y2=&%3L5g~q>@F6BB9I`!kL9M{ylE(=s2u_8ym3P>%ixkf z?(xxlNPcb@AE~W`&eXWy-MA|inGmY%!&#>pG^bL+W*>yIx;?{3#c8TNT*RD$ATF(rIzDpBxm z)9odwpC;%{$W`BfK=LrhtQ}zS2#Hq+L}r+fO3d>D@2*S$tL)iphjT~*$fbubX&wO= z_A8!)-17QjkcY7QjN(emx*~^qme4)EZAKbWJ6K*tEFa|8S}TQBmU~0+_DnCnS;dbD zvz_p-D+YIOWwl^fPcB1gGJ0#1EaMi;b*Od$zmFO@$lE&ykgLSWG>!|h<$Sj(&hD)@+m5J3Y&pMcPsoPb6DD3Xj>d?BD%if3!fPY zGEIM^J#8-OZnv#aYu$scAPw~_yU|I>RjP!e`B(rwFYhFA?D);BOwkt?>`9=BN+(fO z>X!A`dKRbk8|fvL>m`%V4>;m&O+cbsb|vcTFB)R}87FJ@E~!N<&uL3QRZwHtUg&_gY0RmVJh?|(yw;^v zNTfAQ2XMn6U)(CfEmBm5jv%L}Bo<&ew}~CSGM%9f4auz)el-wXjLxvRY>xkwe+`!b z=x&q98!y}T!(@oh4M08z3*DN(m#%hazv0&N5aViIr|vpzSNbYNp-~kUA(bzVRDnT9 z@>7((%}Do~SD|kotgWrx@OX*}2H6<8ao*ixSG43D4t=F+u6V(f(%M*PZk6W1Dry4r zX4M(*GN66p<}&);9_S};7S33g-3JmN06hBFKj962_PH+oKi4%^{l4sp3I2Wdn!9}W zQa?HDEqH%yPO-kewQ##(4xNFcP1EMB(;FE0G61p#6Z}(E96^?e40$O=kgg?Nqt$s? zoNsAg1h?*;-@g;(IyA%d_)@L%uEApWQastml^WytGh+XZ@AaT1qwt&78Sr=+y~9LU zO;2l1@9X=K1*_zuck<&4tygCTwzupQc>sP#0b|>niXj*sQB+^Wn58z$A!Br7x{k^F z`~$vQJ~IRQwhAf3{E*h4v%BmuzZt1}`)EeZnc~}7a)Ctdy!g4C(_pZ44KUHyKQFuR z;=)_+al@20ID8+n%jSz_Z`UE(RIgjQvgA6P{Q&s_p{~aRNqBF3OmstF9&(-zCaBCM*CM$a;VlQs1Nio38aS%O3-K{T+J%JFx=%0el{!VE>k)JhAaa< zgwJ)-@}uShh+W|v?%v)$!!~PBynST9Y+~e3!D6&kJc~85{926J6~V~mZvH=Hu$i^soM%ADV5D`KHucwZ#=%Ze zlO!xxGko>qaWMlW*z|iluXoF{C7iwoEA<~@r)6XyU>Axkc9R_Q4n}Qm&NO`jk-Hx9 zjjD?aU%`!|#X*ca3Y$G0HDVSP3NZ-%T`=76cx-;a}EPh=muE zFI!?AL6hw@x%?)0S-E!=kHBD$Fx>P9Amek<1Q+&o`TNL@CLQm7!`$vpIcFivH1F0!yiwy>|AEapKHl;6?OPyrJ;H-IC3-bck)2oB27Eb>#Th|x zA$#u0HtH&ZFGSyg&>a1$yWfVkjHCC4?qquq8+`!gncZw3d!4o-c=w;N*IN+_fYeh8 zE+P6(Ls00-PkN3@Re%DBJOUz>9-hu4Y@#L0kt;l}0ze-LP9A_*Rj-kFfF_H~`)ZZ4 z6j5GI55S_~z4_J8Bck`p^8R%X^6x5r1HdfhiP8odYlHW*+rv;)0?0iP09k~%S#stf zUAyaob07e&L~G$H?IiW*1(0`$T6rPib<97`F@SCwKoMeheJBAP>7)h;Fd0^90(!tGb}_hvlngwa_5nl^xp5Zo zX*}_r@*0DwTSaYst~*w{fG!aqd9`8-xXcZ#fzTNFkVYGNy;XD+XyEpNNsYuxd()*6 z%OB=*r2rTx>f&=8^vFTlPzZU|qis6?(;`T0k)N=sIvrrzVmwNl?oDRN-D@j)n~h8F zRq0}BE&MK*<-ad5)v?~!!NGpl(!0ej7J1o&!(A0>zkv*P>AM>U&U;sRA(SDH%^T(5 zyf34`BdOI@eyr z=g*XWH!aj2om%je15KXZ=~9v50LkVf)FH>`%Ipb#8(Q=MV*h{LD?kyPpA3 zC+qahxLH=wLAaOFcW;M)`b~mt?<^g@7xE_k*(llE`Pu5hnNuy;Q}imw$1s= zB>FrfTr&a#4%0d137JwRI(eackZ(-nc(GtOc%@uW?qv8Bf&cg+?b-b z9i8!Jh+lHZ*XD-%=0no|*OR65)nylAy~sv(F$hd>(%dd`h((qzt~MF3oju2@W2)j) z0clVGI#dC(ty=v?>AI@c!;bw>O9%!az~RzkXT>xToh9w-RbRZAt|O~KT>=OwPIx<9 zfw_ToNmolWIQ%VZ5CkOZ*!^x`?IN>FAo?C@Ho8{a#Y`yzQPGW-ol}E);r*W(?=-)T zs!L$`cF_S58UF`s%HWm(nKZ&Wg9a{*BHQNbopNA$D(@_`r%lWWNVK2XdE04f%mVGR zcXrN(FkJf*{g8j7f)VB@aN_~Hl<1t(BszMFZ&Cu^q3uNmY>Q|rG`rN3e>~SkoXo-8 zX9$x)Xk@%bFIXQ#oCHLTP9#4prw{n&Jq?B{88|qPW0%^&+Xu`%zDyN^wdy@eDj0Q2 z!2=owgi#M-)<&|IgdBOCq-^bmL5kMmjl}P{?2K2*XK8GCOUC??b3A|@MEcw~eKfc+8 zwG6yx?g4T;f>+&ke;!b%-rd60^u>MZKxF3COZH!fo`aX@xMRu_WvCJGA*+Cg%ngkH zy?|uc99;}}qV3?iU7)bN2AcMncCwi({Wbz4Z`gsTyXj(XDPYB{-}qt?{4#n#%nim< zL*zdruhW14Wtw8c5;+LQriKKaXrW^3vD)_)0_V;cq@NWPLlgJR6N(OI%vb-b08IxYIU@K2 zxFG(3hYJLj^#g#t>)n%!8Aoy;+<~MX9#Vq)1-G!>s)|RN&87f!TYg?7vVlh zDd!of9;XXT!89H`*U{i*0Y4ZSd)z{5D|^#tCNhss*~7e!xrQj%PvgIQb|FzZ!0ZR*w#Xck)NDd<0D#OR@_1 z4mPf40pNM^0D7{!hj{gm9)S|&qEenNmfVbxNhhikUgS|Q{JpFA?*d;K@6NC)yjHXk z=|o0j+I}#pu?ymleyyW$6gWgC+ncO6H}j1AF#^mb{LG33PoE!q_Zw21!L zm!z*yCMi3=-WMjZyTd|A-ntqHndaUCgHZ;+IT$uO$O3zuzB^->u{xz2R2^*>=$*6%s~+NbvMX2f zPC2m!@T`EP{J1|@xt;)9>vLB;R0};=nMEKLWDdtwOjW$@@CJIKbr1}BLnFnj4nH&f2G14$}1%%@4qf%T>J=8I=73;bcwf6x=u0tn8 zyjD9K&%%4{t8RTMrzf6#`!V0;24x5h13$jP%FLzroqPY8 zpv#x-Uk7N%HU(^LPS}3s>Or11;Ly^U$i>pKwNFX>;5?TYb=P%{#iI6V!?^Xfa}P)7 zy~QWKyoFK>e?Y{0C~5Z8&!pNPaEC_rOBa1t7Wv)r!wR4IAVOe>Qz>GwKIW)Ezu~Hf{Hw>A#bnc7cKB&=p`;cdQDKoY#O%`^%X=#PeF^1c04`z(UHZ&o2tvnavI*%qRnb z7T0kC#*$gH1u^FuFZd+1wO`!47_TYjm>RLBwD?2Mmq6#`)C1wuFkB?Pjlfq4%37`# z_97;B^`i}^i-Vo1&Hi=zTByeBIoIEzrRy}Spp4Yk!xMB{|~BcJ9k1KUojj#jt`M2O4qG!Z2LmyOTNY8D>d@j`a za)g2DmR!5RJ|(&UltS=7s0k*=;Jb7_>4EZ{REeh+t4?ii`F2qAgzB7TUs|8MOrjUg zu+MfHEOMIPO|&G+z4NI~e9Fk|6}>!H+~IH_NA4;nZ07_37o_N{O@TQA0<>KG^j3#z znT5qM@^Sxqk5datNP4o~1Ihv9W==+q!sf%_#%WbYB#D20gZtb8xF)15zT3eQ=CVAM zfL=H0Q!Ms8$qwUX=VgTt2 zmJFe}Z8IVg5URmG5m{EF#U0B=`o-tJfF&vdfUY-#KNY=(txFnmDfGgf2Nil7=6=)` z{4eyk>lIrIgo__UAPQpWmFmc@7yOaTAFs8qupCwQAg(n;mcP={LUvc>190RonV)ws zLdd&(q@zH;e1W9BSS4m5oDyDA{0?t=gcT8)&OCyOM~E9!Nifb+fxMdRq6V`&Tjy$h zLqkJrl-M|78RkCaDp+oS86fy&!FGyV-pTOqW<-1d%kCeIv{!6&o@hgVC!oV3bmkcC zh|LWUB8#t7I#DTuus84Qxe9`NVS4X8rI?n313AdhIdHK9KsTn%qWF-a)wM2>T+vwDoY%puc zU|=G7io>-2AMTB-%&5-RGzQ%-Zv%}w(>V5mA+QUN7>6aVdwc&iRP>r2AHCLVI!069 zkjyjUq*XmO(s`M(*S1wK=VJtck>u1Z&wH%Bl?BeSCoFBT&A`z<(XT2yx4xJn3L|ZH=z5u6aT1CSL0BP3km7z42rr*x5-DJ>xhx3*RF23+at$T%JR_g+@gr)?vPb@tA+QKzNW z^+v!pn}u`eV#jHe>)h(|V6!Q6JZ?6E0HVP`KKK}Fl%Y5eAXDh+W*^i$spw4rOM31V z!lM>mMqi`{XflGW9{r1%!o6XZ@$+D0HUDl-VK^4vrZAEj6_(m#hm#q&*CzF|3>fNM zLk0sgdbS`;3%EO=#bb*4wA~wapO@#nI~Zyyp$3{oD4v<^?g5FZAW+tWK1GV45`2-@ zoC)KFw5|ohcmzY^pY(_1OW+qapy>9wNV#~^%_Va6!Jp`g^=AHtMNuCborX-1!9{>( zI&Abc%s!^mn`c`L)Z#ZtuXQ_H{F%b^4|t{&l{ijkAik9hADE$s{eHaKfUkb{51m|_ z^0~#79!4F}c%5b~5BvSOXZXQAH#|TOq1XDjs*bW*%UVWl7>71o5zC_>hS*l2ukkQU ze9qQy1ydiGq<&{$eSJfIYXS_8Cr?HxG1I8031&;ZF;{IOD2&ADB4ViX<$pMKIbDvT zMA*y|=KoEiUI&qLy9!X2sH=n#hM8qd@helJcrTPOP6c`}6~zA^8{81o95R4%A>NLKo)^;)-QWO52*-1yK5g=)t2Spg~ zgh|t&EK9QpFA94enDcTtJd~N^Ob+v{zX}(!K;Qhw96=tLG^o=U85psN CZlALLr zUCmzj!c^Ua57>~tZy;bv*WVCCW#pG`}RK^mh0$oi77>=3gy8+-x2x^RD8 zYpl$-2^Z2io(wpG;V<)Bib?**S?Ib&qJviIh1FNCGa*#QdYH<|A~h@i>R~Wts z-}+aMY(dTnDjIZbsR+t?>4rRvK3AykQr|DaC6L8=YFj<)QHz?(W#l4Oo}}x9ElABB ztJA@oPF()<3fLsVgqNA)XV|tBR*<1bM;Zr7@&=)o18o$n{U2rak&EgX(dY}ekY|A_ z1X@G-Q|Po{WT$KfH^K&=Esj?LGyU0&4F`FK8K5RJT2!}o=VytcoaNP@VFGrFh+*lvm(1LP~4T0bp2%fmON(BKP4(>O*2| zD-!FerT~VTb*zSzKY{(}#O?u|V-6>*PMHMe@Le$yMbn?N^%@F#nE}6TtMgyMhT#SP zEYrC}dEr@z)g;Kje6pe1?DfVO@$P#oN?SOv8bi9`CN($*2IS?XO2Z4``d2l?$T>d#jqm`**LT~0NF z0~XU1hK;q{<@Gx-Dv&bT@qD?d2|cG0y%uVBUMtY3n+S5OSa7dc51_l|dy(#pf#A&#*LnPGz+cnSzTt6@13qI^hE8p3u~L>%wfGXXDUx2`pzJZ3A?_LzyKTjeZf(N4EV1O@swTSm5aNP-Or)>oYjP+eP6e1LRHOt4qqklmq3cw zS2>F*>4Lt-mn$OpkzMb-uxmrI13w+8@#*KTbidMRBXFZQ))@Z3`^OW^S8=aw*|wY7 zd9`G8z|Q+~`}vjqvfB&=?i%ETougA?e%8PI;bMp6saSobBDVuYiT`N}gT}pN~(c%7;GHGt_iGLx(ekzs|PVtW8hI zAdT2_V~U(Hrx!AIe)oE9Ns8mEGx{m>51)c_d}iNKB#r;kkE>Ig^tQwah_uw+vg_0ir!Dh3ED5qY2F{#z!=3w{vK|zSv*aFCL zQOUw_d5*f8>PU4L1*Y=ll=ZCQy!Y*S$)0_rfcuTIm3yboY|+IV0=vC08gkfRjt=Z> z3h{2a_4no?cML0vBaG=M7N)+Wr%Kn6=Y^4b!ngG)KfDyM!(1P!^Q>4n*xd?a08+VG z?s*wk*#_%fZQfx3{njo`Iji0o8K%agDpr|$+%M^OFWKDci|Gj2TX5~!Y_4D?cUmKT z-A5Z+)gzN}8pHY}u3HCpJ^tN*)8LYkpjx&qzOk?PR2oiHj&>l=R$x-no(tW+3gEnL=@eP$Ezs1(_Tle6PqyGHdf zYD50ET9pyH>^tRKA-E|!I`w{$UY4z&R8;0G8#d)6&!t#m#2ou)kiHEsR#;oLNEWZ` zB}@-3sF+=_@-OVPPiKXgT~y&PTZ8s{-T~#P0znFhu&wu^X4o3}+`2uiZJIl{kjSUr zZF`#|slANvq|YW5#E#Kj1oihneKT_?8Q)%-$?999ZMN&n3Jc(d_+QF{J3I2E>;mC_ zQAT$RZ&JjzFBLZLo__D?47w5SY5ct6l>U^GZOok|TGHJvDgo7pELOItF9L-8J1ZjM zsueHVo*H6K2S!l~1TH-TcyB&sBPZz{xo9J@l>pDTTHlri+s3<9%~%vpx=urCeTR5~ z08RQsJmsas=aLX48M$P-Me!P5MR6cdptE4SKd|y>d(t`cnjUVEmH`>O(DfNg-`PUf zE^f(ial3jaQcQu%%zDvi>AUz3#?+dUqAIV`#?3Fi+)qtePWA22$c>q=Yri$YuD*`c zD45Orr8{+Uz=ryF!-K}!xwS~D7l)}`VWZb)edXa7&nK~?HaBt?A}2JHkW<1HAYE93 z6l^Ce3aoDGBF+_&Z=Q-?wa~~~Exhs^Bh`YE>696d86c%|5iZ2vzkbd5r*Iu@0T-HCU)^yuj>55{(!Csv+EVo#71uq9(Yaf(B zboB#+r2NY&Ug@0Tq?5!~bDWNjyKDmW*>p)tNP`^l7i#x84{@hhi#l^{y0E^4R(^%N zZO4LDV-?@29N874nVx*{_D`D4t7|tdq&Txwl{`H1OXkfAN+nKBdsPjCLJ<@TS)~;R zg1Q5PXoSzi8$r9bbp+9BHk|`TCqgLYlK@fr6UpR@(HWR)tbnOxgp*-+W0;^X?$Vak+L$th;^QTD(yx&1!V)-D9CqVd?^48jNREoJv{&G{gk zx&-GF;2f36_tA$3M7i%I(7ePS5#u=x!w%h)_`7dh=A1RE8%a%XPcK@-3U}>1?94-r zAc&}E9mFOJA&O|-K^CF?3(5&S9c8w*L{%TNx!Jkwu-xY4VV0z$4H4@8rPXP~FzLYT zS4dLQuvv@2N&6E!WJk5PeG5tlfg&QLE4h@yNCz%MXR~b@Kf|%e+JNA+a|7yNl&%P_ zF9cHB>Ip${Wfk61@*N_+$fY2n>RtW^GiqXcIj4?8V*cVYmYcwj(&`_eN6j1+`4(1y z??qPf9CJpBYmk1O8hAHvX5%^+f{fSe3RL0ki?nqd7t9|f-6^><7C#@`kYlh#u$#Ce7}yZ`jfer?+Dt3X|rKP)EL|SeOj|2Mt)vyk+So^ zg-X3Stg9Jzifc#9Lm|~7jY7O-TEWYVShhCY_iyTb$G>gIu9OPow73KC1c0%th?#vz4bZKGg(V zk*4`moh9ACM3i%-$C*j-B}%)&H`S70>0wmW54LvS!Ole+RPSmRt?XSPv5*P^(g_Bd zsk)@nm2IP*rq_l@r4uG~X*2as>f7ch0r3WXmz#+9}D*l&N(#gi=o z$+lFBbkM2dLEFeG4DrDw$!|g{=n)H~}nq*A1K!mt4 z-HE|xXS5YFp*hg(`$9^~s$L={K3mhV>#GotkEDHt=OrXE`-h~PKD}NKE4Nmkp3)2I z;J-yx8P#X-pO^my+Wc2<2C)|X|Ef-GHEI`8#;7rndpT}q(ardW0^0x==YOz<%t5gk zQ~4hS=Koqt{m?)c(F00N}nivI1V=b#Qsli-CrKxv7!p*1gAI z8EFj3w?$_qs}b~HL?6-%`=W$7Jsn0j5~IHUCJ{LM`yExZKV<7edSC0-z5TE(0DvRV zQ@VP6H1e8t@3LtB%2^aAXziqcE0a+5AYJN_if^z9yRv^;ir^VFS3UuqiM|Tw0)NzX zf+tZ99LVcPAmivN@;@b7z(yf9X4vuHKZzRGIig>Le2d-Hy^eDZD1@T>&G3LvNsh5Q z4sw1`!!tDfv}V_MFHCExv%)#gHKX0bPD?{U=;zj;@1VmA4uChLOybRvph#ig*Gm1f zZ~DEX?Ll+0dvNL4SW?W%aBZ+#!vOFbvD@15vAFG!>rR;~?k$r!e3*_c^f};1>>C30 zyI>CxHv>a%`ec*cyd@``3#AtNwTZhxqwoHGRd-0Ji2F?}g1HEvT4T|mIU}lQxO+u* z$T2_aJaIIfUZftnR1K5SmK#Num$Pdz`UniaFY4e)9_^ZTZ|vms`6aVHg+uftYRL=@ zxB!6JU9e2OvP;|N)LPUg5c;P0PfC9=1hOAn58D@@8CQvJ`Bw{n{d1(K?1mQpNCR5M z3-(F3wWdX^!=l;V-WOB%w|#sd{u^wq8mn`Vw6ME3TOU?c_V#9jGoaiKrEq1*S& zmmLP69U>EG@b2eI(tIBpmu&39W#v`7@h%KeDj^h5)S){oBtWT9syY;hsa_2>hYOb=zn&5 z3|Gm468KTj`L#rg4=uG^7)QZ?p;6;~M%mYI*zA(!joK}B*?WwhS+=J2{k$TjNDQs@J+Yc^^nfyR)Z!98FKoTQKu#apCbOas?`9a27ScCJbAM-3MQs z|Mf>{y@dzpgneX&BfS|i)(>echa!mw<+(P6N76{uiAe*ib3Y*7;hf2AKa{S!o5a(7 z3~n8dq+uh1NU@j97{iU>2d8Xsq$~cC0{pka{!;8>%_?z*{pyj`^#Tiej$Z4&&@Zrg z6u8Kb>6U2LrqQ9m<0)p^Byf)^;Bi7+dZH4+pN?Gjhg~6{P5k_syNgQ^(Jb4~!jE{# zn;iX@ZzOFhnQndsWRekBMx|@kK_hYxWxWPOY;+4RulCPw644+7*MafJohag# z*BvfH^M5ePDUy@;5KMzOHsWhNHR(Fbe_axx!moHyH?DIbc zk=sQrDi%v!@xmD=XN445BJaICD~WncKwcx9a4tn8+#R5vLv{_Ff)t@#%A3g2WnIt(Mc+}sEX@#_-@JnmhMD9(rgUXaM(GikU%n|}112kr_-I%k?f8Q8*GbpJZ(*lXOBeSS z)DTPjTInJ8S-16hW^e^}Z`g4QFW*lY+LUlu;}ok-{T#;hzyhEATcJ;zR1&`pzdd-v zkUK$D#d#=hbE@d4<8!w!Fj&I*O*=0xgKY2k1O%_bK(hoU`SO`%gtio>*()Bwy?V4K zQq;{|tt^C7?3|Zfb{U(n+eHzb>;mDhJNSO#m*dv}49OiWBl!8cmV8UQ}|4?a~tdfi_u<9K=A2Te+v z@HlleJVREn9rJ$J9Aw*va#NKF?wYCjT}ij+za++VVrC|eL`iY%{rge9r?6VNLZO}4 zozQ4@QYpW{19yM>61l0cWA-j$N@t~ZKEdb~l2nyOkC}*KONL6CI)`xswIWZUdft> z&dw!%ZoW3M*i$G!RBDpyc=J$Fs)&ntq50Xh{=ctWa{k-8E-l61@%C4&@&DY**g?-Y zGptojwY)J_6MT`JLKgACws-iN3-*?UzdzeN;GSx48lGT(kn8TDF;aKk18mDzN0KJ6 zP1YFVW0rThxI2!2izgY49X#X|D#lgFbr!kb_PAuiAwlD@kpAFjFXyhH78+zIpAs>3gjog7*$ zEwnZLVYRyc-jnN$%r4uf*NDoHlz$*jcmx{BmR2`&o#FpsPpEvmDpP2;uM;raY*pSr z#z>&;Vsfvf8%y6r)sH~~u&VwRJs(n40e(e^n#J$q zYo!8broQ%HI3ul9RD0}qmh=M$*|YnCXO6(;>VdfZqp#ieTXbEyFAyCnNnJSq< z=Q2K8eSXM>b+T&s%bh&K_J>9St>8mD!41YG(XswM(#f)BVXo-*ZD>P!gVu6yh8@Z4 zHJxWIPfTg<#f?o=IRKxkp^Wm$6!(eJBk;%+-TIsLu(?M6l;iTAh5=*Pr0#C@D%eQZ z{k1%jw`^}oT^tGl=hc+h_pvz(^P1?+YGLy}dI7Hw+Cc2mS?Qa$)3^Li#xXGj?vP)W;axsG}0zJ zYuK-xUW1yOUJ@!ufx8||9W3mHbC?T`K-!yhDB~XTNu2Jp6_1HhErLaier4pI59!zU z!`!*KX%M0bxui?G3REX$3wv^_;;X&j4fpPDj5oeJY2{hhN}8{hj}QG;t@dPl8-z9bq{c$bV-k>%OHN_F`dDaP`A$ z2ezTk2An17%32{Wxb0s5c9Z@;&7Ju_l;8jVZABv_((KOYa)%nLt+<6d#T4D9AW)>y`xW(aW1>#}L{agom)(>H6gtbV)dWgzeE;IYyL z4?{J%JI+9U*)=W{-v|0M^b{(E}Ey8Mu z#H{86Y+hp-%O|tu&QuQ7sz+!X-0zUErZT?vK-1|85Ev2iUKj=C7_W7_a0ANdDQdsR zU|fFLxaz}=nH(z1Z%T#mN!rC)%W@ph5CwI^#LRQ|g92}#Hz=u`b_N%gKLRQcQSX+J zvp>AMrGN0?LBna+z|A2?!d7F@@kE{YCv~@Z0~*gaSxqE~OE+2}^?5Obzhg*mX-Z?4 ztR6@O;7_T&4r@BJj)oIrn>hc;xWg;XpH&H=HfuAjz@J z23rJhtk-{`V}11QuF25RQBP5@Rb*f61)>2Ur3kLeqzA&U%oDu@yJqPTOvCi<$X7Y; zxz7rKJ{UO1kKXBa1uL#eA1O)V=%)v_=X@e!(|nIMp@zyGk}Y2CcQ$yXiJ|xGP^`zD zNf@)3*e%bS8Q1e|-;dqEW97u*iU0a{UW|HCgwfyc>?O_1nBb;=TwaFl8?5U2@}cNx zMj;m#vo35Q=}0JHp4I?wAohFU1-)7alV`(3OdtXN;_-9#RS3^J_4@|1HNLzrI*O%!xPI$OaZWYjA0Bko zG~m^9C;8p*bM9ORbs&!mWnKEo*~u!9;3TeHbte4>DSPg0;eN;B=ImRMbUivNk@GkE zsAE=_;yM$1-C<@yQp-q9 zzi@gp?xT#(6vziFGn#fbmSYLo{;vs#BsA>vI%wz=JURCw^M01kG?NzFv@1G>NeAJd z{;i4R{uOY~&IG4AsR!ujAEh816b$V99FKjbui2-DjkT+nX60xj*gDzRatmkB(Oym z7nTdxHLDt`wKLpMrN^0o=p|cu^i!2@KL&B-6V%J z&o%PoJkIL|yU6p)u@zI{ z?|(OcKi<<9&+F`ZKHJe;+MpT)eR_fk7mszNf`;P?9qsXK_z2#s@BCR0cE5E(nCNJ8 z@80Q?`d=L2Hbzv?pgfClxqKsMuH&TXZhIGH5B;Ar20p(?~H5Pj>?Y z{+&mF@^m}ubp(IUVD)Ro&wM+osfaobR^9p<9B`TE>6HFtTy1p)4bHb}V!J|+`p&-@ zH8WpcTx-Kl&?f9Ht7PaWWJi+1-ZjGC5b@jZ1!2F%oYgn~&30yk8n&B^ ziwdLl_2xBiM(nXw>MvQOORA@tcKC*ZL|ciXYoDw&s$OCR#8qB`oJv!_TLx~v`jRzb zb%(3*#ct9jd0*}E3ox$n32j%i3e;GNb9=qb7+=p! zWZnSwT<-I1jL)ZZ?Be{jP|3sIKe+5OkjF5u%qsG9vVfl*E?hK?ANBZn(s0HqW&_V_ zV)Znzs;E7InF#(j1jvHul>Vj5l@hn#3M;TGl>vN<%-um03+7U@LgF}ES?jqroiYP| zLRev`z)%4EkbzMDz*olpE~6YFew*`iMuv@|HRq%C|GyiKF@LkjUTh(Ok!q@`3Bfo8 z%y@rdpU7&VV~~Y(%*DgQ+Jr@yw(^E^%#1PHr?E{u_MFSYVnen;myP(}ml-=OIE7+m zr22aFo20enAWp9GLh5wURFjfTo&2Un&5Rs8SvMD7KsQ zsZ9n1aEeT`l_Wcaj=6wHEx^^nayUSmDGowyM5aL;17I@DIp&4aNw8FQvo$rwL3*Jj z>&%eY!et&I&DwSzA>05srxmk-s|BW?DuFpDcp+!0_lf{Vf0ZfO0TI55zaY15xG>1X z43xrqIe)nne&!0hw`w!NK{n7h!s7=QpAsGmdP8WDc^>DyfCq&}Yij66eUMp}>;Oc+ zL0vf9FNiXPLrl_p;u<%Eq$+ek$nh;5P(u9HjQ$o4HHWPdvC@2ZI!AO>mG2e0Q}5RkyXqW0H+c4Qt_`D=KL$ z{$)Jg#h%BjY3uWR#i3;dry;A>x~Nx>mKofGQy#$r97q}?pkxUOVEYOHmgJx>xmbt9 zX&c@55}5&2hHXQ^5GibkgAipAZ;13ZcLDoh&q(S*Smb2$e|Fl50~`tR^YmD#mLCH= zEI@?p^V&368GssLz7BDNm1m~tZ0>n7S`Wu@rJwB`6QA?q5T!C5fRi|ACvF?v(iHbH zbIKGb60lq@gquhKBarvI-8FF>P4!nhr=e}lMq+00ae5IW- zqGp}8HB!bwIY~g;mhiWNzzip#DFF{c zCdlFgq&6JTC;_8*SEI*m<&)H?;9}X_k>vLy!32Dc+eHH2ypeNCos}(QCRW7fPtVY2 zSHJx8Ij(*?rlI_R7lsr_V*bU*-Ts>)W-Ln-DePp6DGLQz9Jt0jIx`(r#DU=bhL>a^ z>*??L;USmZq&91z~%e2pIHT?Syz)ao;TLDPHR?)$I_4*#h! z|7yhL+&%qa7bP4-p%ky1f><@cRyz*IezFZ^5-dF`8e<2GPZ$40sg*!YwjkRJ(*3vC zeQK~DN*SjMXh}`cZaw|LY%RFizK% zrYS!T?H?BYja`Yfa2$NzL`LBkBda;2ukkWRQl5D%0@7KnY^z{G?Rd4a4St0rQ}Vu* zgYYBY^!+*P@gH5@-8PZ+x$#Vy2|63o>D*ibVPSn_{td~ct`v?op&#uq^AxhUbP}(? zafD|qULKcZO>)3GXI~1>*t4C7M$g{dc}QS7fujjtw~`3m8SOL7CJrIAb$OG>cqD5I zRX5_=-PIkJ*iluLWJfYbe%Fthv2I+g@bViQ>{p1*qr#u4W}ZCs)i?8Gj(peYz5s3Y zxRe5{VO#TNJA@XWr-Y1!b{eqtWG7>CTSQjmQxpgWkrb6VC5jQrX!+(=!f(ILk`Ras z7hm%yR(RAH7FWcTZiP-#7$@T1MRrCMWjncDz-K#=#{B0{HF|7q`V+ouMXRaNr!F4p z`wwW!zt`5CN&9EWa%0=v;YHEKD-(u_ctG*X!Dhcs{9&oBcz*easd)Z6F0B)0Tvyt` zz6j`${C0lw1TwP#)(J23WPR=6eZC){&^VwrUbHQXZvml+_JwjRE*i&o|Fu`Nav&}j z@DO+UE3zPp9$wincJWzNgWD>rc~a&|Q-^{C(Q3!Sft>ju4H3Ejwplh^52T-11 zq537O%y}V!n;;q#cp+Z6U82f>sIRFytgw&0mP#k5JTQCi%!LwI}i z5JN&`dw^v`42cOz?b~cd(IV}t|Dv|L{lP>o-(-AXWum8zb)KIvDs2wlf8syv=*+gbClsO+$?nG3Bh=HK=$~uhWZaYe^euj}y(7MqKnX!~5}~ zbYqdVf++qu1=@aIW3rLhe=%Lj`@=TB;#c0&2yN;fZH+OHibdP-bC{GU^ER6%zGQ(3 zDR!z=!?*os`i)T43N^pkGXJCJT(7^243SHow9@I6)(LGP6R+Tvj=sH7v}%|$GJ%h^ zHBYq=B8TfZw&kHI8yR*}rU&E|OM8M>#BK*0%{J2J4@{ez7t&zj2bxiHUWGb}OZQa8 zd}a$n!Az)3Wh^>?y^!M-8<|tv{bpil-r-Hw3KZhFwkX*jZ9Y+!R`XH_;d|TbG)8Z%vnenZwj{NdhI1u6hs^>W)u2(eifKPP-8V_z+G|;wwguVD_)%sY zm=Bvpmj}~;b;5K@`N;1?N(9M-BC67w>=hY9em?XUzrs6i(76nV_<=bE50qhEoc5_D zQVh0k-;691!aw5wG3D(??$#KwAhse7i zJ$tO|&@RQflb#9Bn$*1B&yD_6Q%@VZzW0i;xnBb|`CT*RlO4w!C?;%ogzo3#32C>A zqK-Z6o)48x?U^r+hB7b&I4NY8Rzr%bMu8HVMuYmA;=Tpz58Gv_m_!XH8fj;M5M;{84!O zJ^l&42WQ(QM%K*juS%cA7XP+OrEJ|~^e}DVW|y>__J3NskuCJc{m<{-h>AYc2^5J= z$RWbjM1skCv#~6-w&;7#0y?@9uNdl^anT+`@iXK86H*$&Xr0=Q;?*KKF48{IlA5;o1*I8`^Q$qTJlV3ZM!9c)!=7-s0OU-g>*spVp{-qRD@oxLO<` zHferxjJBU%VsW8Rz~&2zw3BJ8`K7pytm{cTvDquwE4{3jTC=AH28ha=Dva$*OZZ=_xDktV6_}*^KK{mw5qA&$``wP#)$yL!WPEIj}mI zQ?Xs*Y41BMbTt;N213qsKYKVp)1U2OJS_1&e(lKHcQHNlQsiK>Bdurx;7hkHJ6>~} z@=^d=OP__t+B{u+XM620Yh`tf_<$X#oakV#F^ z`OUANur)snM-N!u>=)!2xNo1P=5^Vmd@CJ&`xU7{f*QZlowA>rA$hgZ@SZq1Q9c)E zfFZj6wJv)Qers2n*7>0>$Q7c;$uP*n?>jax`H}2rQ<`a>ZrK^1vzBj;Glt!oMRHze z=AFeHtWiKk#cNp=qDGRcM6aO{J}&Xy!m$&i@7Bi|L_tp;GoIjq{-BoiVs0V5xIgZ} zs6ni7gjy19_t_;qcLTJ}cW=CM7v9A0yj`w+4XG{u~+Q>7@J5DD*zb1Tx2u z*DK!lOGxL|MVj|(0?PNuAE{WOU1 zdiiQddqZe@s&HOF8v01+cm(xm=@W&@fHX>t1W=7ie(y`SxNdd0gYMIjzY? zWK#L^F^aNI0~D$5McfYQpc#5K$UEKTSj%W!n*5QpM>->5YIaCr;~%n)7{SKuu^8i{ zWG=rL<*bI{VdXqn59V?wwUBX=K_Z2YiH=!yo~j%@vdGEEyxgNrrn!2?_07NVc@Po- zIeUG*^D^QRlK!-wWVi6j?+i`;jyj-AXl@R)8*C3@cl*@@+ia*c7N8h9#>x zAr{f*JekRQODI;CxlU?NL~E0w0%_adG>P2ef_Wb%B zAEeX-cMxtB3#y$h4{9+neNE{{4&zIP+B%H*Jc@F+RtE&Z{FSoiZfc=22G7p1L| z)O+peEA7JkHJHDpTR}&hhVBa}58TD4Vw&JO%B5yzXvGgVZe=@WT{1qxb5$%z7FC~( zGsEGy7e%Q#*={thx4GeY?u+%$rwd&k)sA%Vdx+e$~=ag zZednmg)WcQedx>8&iKAjzQNsq){Q4J%eI2N)N00A5$39`{aG?RGM>3+g{dX&xEnbv zrMF`JK`YngxkVLn86Ws07xhMN5_#NJ1%UP_K6SuudOi3J3`0i=dqkk3PbzPq8#AO4 zzm(0$YY6!W1smDg^NAy>-WF3iud?s49?6}@Ao>;YvM}k;7((11{~>3R(nwnPo#kZl z0PQ{P!SdOuxc&XFQy9wCapQe2%;PuS4qqcbTsOs!*{7ar{t$*YNn>D0B0F*#C(C5< zBvsyo^~NEYB@|Pbxtn+2cG*8NHV=b6iG#%4ETM*#PI7F)@5gc#MHMX=lfB%3E+LNO zM?7kS+m?FhJtVu@4oOvOQxhzsf(qATvD%HxSqgJn%st{^#N&T5$N85OC>hpWz~CCO z^w2~VP7*XGZA;!o-lYNm%S13A1o9X)y02|JI@_Q7EfOv;~(P{`_qgX)1H%C+`VQJi`zDm&(dB^eJU}g zw6crH7?L6JE^5tM72518p6_F(ikkrAC>57TlPy#I)U@A9v_|#%8^|z^4F$1H52+<7 zdLG{q+D?ibNh(-sBz>be%1@D|Mv3ezSV8|KFJqZ5(WsvW=w_M#44C;5UzCqTtO!M} zX(g^<%2FHCnk9s0o=ACU?@oCBJC!CdlE0o!3G#f&NI4gPiUjsKqSQBE-pRdbivJhI z$}%4D@>0t~NW69W;8V4Ll-RQtp`o(v06l0*dReu8A0oCPZAk2(@3n=qXS+z{SW3RE za5OBg`?x#dW%%*zWNxu!e%M*O*zdqZB2T=A^zFx{SsI<~H{(N6w1xxentIi$BT~(t zrTrbJ1CdTf+J`pmHymMW)WCdx+PUV0o7|QYFUHEv%Sn3x=ziau(UlE3@?f)nYrO-$ zLF1_=VZD5uqCyI6t}EQyr|rE>ER>dHEZW~$l5cmJD$jBh{NJQGa%Rte6X?ja|4k*c a_@7)~t*SD<69QnJTvo?zEvn7WCj1{4fjx!* diff --git a/doc/reference/clutter/easing-modes.svg b/doc/reference/clutter/easing-modes.svg deleted file mode 100644 index 34e0b34a3..000000000 --- a/doc/reference/clutter/easing-modes.svg +++ /dev/null @@ -1,920 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/doc/reference/clutter/event-flow.dia b/doc/reference/clutter/event-flow.dia deleted file mode 100644 index b0ff1bbd5ff666ec2c431fe4ad4ca0fba0ca0283..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4543 zcmV;w5kT%AiwFP!000021MOYibKAxdf7f5ZQC`{^`gGqPVeE|UCT(XjZDyLjAREB=;;AwNtwWB>ra!iEEX5HWjb0W*Xi5Si)8x8 zyvT2tv(rjyEjP`xycpdj+1u0alu}xW)3fzq&Nhy-11gw4A^D?mhpmI;HgokH^|}qK!(*>!g@3me2Lr zYm-$Mf+9^RwHHGeZLs2sJY18*)m;p$E*n-|F|4}9>ii}z$|6~m&sARJd6p*2N^4o% zrrq_drb%XRv0Y|)SaG>1%Y4uIUnbeAjRDoiU!Jx@pWJz|nC*UWHzXR4@@X+Eug*UQ zx?I)K?*kqEZn0WiWa+lEUo6Ys4u9Xz;p@MS^WKkN_q-dbqctPXCH!|dJj`zwvvjrR zHrteGIMUTx>}=mvugkT)Fx5vjuy!i4^GkErtZ2e6%-h6RCrJH_on`@yI zQ8A|A()?7_pP5#VW*0>^9-S|*)9t@!y1c#K5=!g}Cbr>W6Q-X%!dZ8GBi{Ii%$QiG zN<~1BBS;I-!j*+Nill`(VgC#YbDnm!!a9u9(+7+M1U|}<&GO9Si+=UMM>#drMBobz ze6vx2*9)Sleh#N^KIGXfJf@P+2x^@pu?WhL;>U%c^wlCL^+ixBk>M8JB$7cv)aud3 z=@Ax2nE_0-pOK(2+JkXzkd#ns%~Nz!0io2`IAlYYi8*A1(wIZOiX4(L#1v$a1hEa5 z6Z6QBD9F6?NSosUP$;BS&{UEjWhy;XOl($Ep`ZzyO!^zw5(SMAL6MJiMezuB5$qz^ z^$d1IBSr!2C}K=SuMu|Oxs2AQB( z=V?(JpbMGZ(bo(NtE)6A&fQPDu*k{v@>j5RW5kX);> z>Ko6sgm=YpEQ2oAIYx>R6Qb7Zc7bb*UCn8gQ;FI`6>^bIAhP-VinvG@ldV>;_c6OI z%d`LvT)Lc{oSei3wjg+iI0U!YaHfwd-NLUH@1%E<kjj2E~ zXrAS3R2%e@A*q;Qu`O2lh5?@U%W1kQ^I~=KF}W#ki!>%(!OMQaJ^Bo(m~{pdK*jUu7~+BmNAFKg1v!@h8NhQ<2^zMN(S$*@8pb z7l#-kusjnGgBZe$V91k|O@=H6Ni!xGQK5pOk(Xg@kVuDIc0wF0f~C@gXeqer2z%LL zneMX#*UOAui<(XuJgK+AVDNI0Wi3?rR5FJ_T6e7+PSh1N)L@!RTdx&{e}Xl)livyp ziJ5a>5sE`Yv9dnTM*3Xh2*i7VxasD~7B}Ztd9nDfy_=G3=ks410CBJy3+Hez`YUM@ zRM@b1IZKL}jVXSy-e*fNVS3=NXvLMi2era1WKaPu1d4L2i5X07f@_eCKF0>$c3fYY z=F8=Ix|}(CI$60zR06S7f~diw2kh1wh_K6_C`-FHNfp#sWc_7< zH^0rFkJ_l6Qop$g@gA2!5#y5Tv8ybFY=%NqG0B`BNKrJEd~EYt8kVWxZ(W-_#Xv5> zx#5OMNr)6d^A^#|K#iEU#JuID@|LMRTPtp3(zH0U*X%AGpMWkn#xz?@|9CUC7dWyB z2gqiy7!!u1R56{2>CD0D4DlXk0{JwQDsk6RWvl2zBEb#Tpos`cCJI2*P>2f@!8C9- zv(?6?hp~I45|fy3Hi^--B!(Z7#E@DNLwiYLS~w5t?>yj%2|Mr4x(qx{|uh#;pa{wU`t#dXVTr4)P#s(*@{*{71b2OM9=O{$-I| z=Wa;xGau4NKk*PGLsO9qfr6^BbUZ^wXyCTu@Ki&Nur&u$W0Nw>l~ExXAC4tMwB{OP zX^6x!k`eck5t(2@Fa}F&j4IZ3^wyBo#UEqcFnCuMLDFD0cCm~mv2-}l@L_hH~ zOeFB+L++GJ7)4ec4?6+F+o+dj#na8P#2C|vOvgZz|7kfJRUExvi+q}{R`$~fPQk&+ zICsDh<&iDlKQ!&grldbrUI^u;*BZ)sP{zE#l_IS;pAhR#u%?h#VPjZW(!9Tkt?&vN zm*&83V@zr$Le6mFh)`}Y;TRiXY{C%n>libuzpqB~BDuIoXEDbbf}4Src12l24Ua%J zP>!W~SXLlht1%;8)1J2L3fNR?w3twV7$J1bIFdT-Y+Y~jT1^~81R&+{6}A^lu_vTT z!eV9cDDtnrTCf_upO*H*Pm?TztG0^3H9&DtVKHV5@mLug3bk|((=w>_e2_OY7IxGx$F1E{P$#D zqj-@ARP%3_#fS?{fyZF94B9ShH9-l{-Y;BE0Ban`83fh0j(Uso>U=-LtI5P2q5>JY zQ}6*QHw6zq`Mg+c-h{huz~&yOL-Z!MHr&r|%Pok|XM@&DbJ8e{q_jP>R@vB_+k%x= zW7M18Noft68{!_SPmq04g@g`FYn7tX!`!}3%D!V5Nfx^LffobzK4###NWCgA zoqUYtrGd*!R3jY&@__?#+C#r*wW)eW zk~bRJENah+)|#*z7hdY3F)WW^`Bxj3AJ!~V>oidV^_o%dR@H|xl0-UebzNBJz!fM` zn(&GJn@Yo6BZpQzbhp`dE4K?}Z4xJZ95GulaR& zP3{qU$(NZDLU})J{*(u9(bcdU6|lRpta|(f1EuhOkRJbP`oBXNhrOCgF3s~qjf9&*dp!7nszmRTYJ0in3`}-Lf+x=rxN^JK(;&%TkoFRrq zQtz;9F0z+$0sMRd2`NLC3#=vz0A>|g#F|iAy;a>=0S6QewpqACR3f=Y&Mh;x6!W25 z#F{~@8NAxCzaF|D7Wco9(6p`GcuaSs|H0a=3=H1q2 z@xfHdgba#Gpr^`}1fY_u+e=86RA7cs4+h2}Uo7&)BHxi>mqf;~Dj1@XAv7>Uh zeyPz0U!;NtK^Uf`lwlK4Ybv!OFhQunz#WqNh(7|Ec0w>jX}3zq`C5x{qz@N+jeMjK z--{fl$Z_gGPpB~r@IgK4VR{={JOAFgNkea92zsD<5;%h9P}{hW6nDD+dYs#?;$0kWN^W3UN>1Xm%IsJtEYPIRVDwsd$+ z25u#O6474JMw3Lf@r^aP-o0ZC5u@jP6*PG6<2lW+p3}SkmAPe4=|}%=SKr34?pal| zp}pDCA*aq;J(?TsCNgntCQKkq6$iyqP!_m-sKLtS)k7;7M~_4|a=05Y%@f=9`w>Q7 zwnFFKjQC}BEjYaZHi&REH%EF?2=ldC9dvo7$-teGY)@ph<}0)k!yatH7=T63`D#69 z-S-_-@nbkh0M?R}<=uG+!BEAerD46MaO7aChg762;?hIwQ$mxn{0)qxtVqg=q^u() zW!d-*VkM%Hj-;&qNm)(R1JeVW7`ydx6}EI>jB;uy*9uApgkb_()=?3B^2jz5n*q*> z#kxU^ep^SsUjkVDqM1MU?sog)!h^@Kc)fnBA?+u8tut`i-(cMiNx6s1;}ZJTVy~Yh z8MFTA_c~<#y%HMvuujvz84EVu71D3Hp`F*Hh(EA=xbvXU01?(_HW{~5bmvG+IP-Qw z`*}ccMF!vjMH+eZy05<0>ctTvc)(gKr+rMhBVz^>@6bc;B&ZRlnsLXmean%e;b+|W znHLMKvCtX|t;aj!PGAN*voahDt;2S|a@GgE)c}szkXi<(w*q1jiWs#iLp3fRZW|Gr z+`84kouWI56ZX`J5N*Y*y_&Yk8)|YfZ-{xr@#hUT`tC1pkOOgKxqm;FuxP2M^GceT zuu})94XMZ0$w*1~_ri1!)n|)T{GR?Raeh_Yg@*mp?ESIFb@Bg92KBjiZ!;@qxf74$Euv zH!t$qBCjp-+Kx10=P>w%jiHZ#VH0_6!!!^J(i3Vy-?x3DL*f=em@s8E2}~%TfMTPC zy<-FxIyAGQ$;>U11QEE6v2}B?5Eu)AhZO<^Ze~X8=T+z+jU8?2vBJBx;{gRA9K~J3 z(RSX1!}u?!iP^x{4bG;pwn>pzK^d}*HtrDJ%V}ND#O^2;yOE>&JWltiefX{7VDDMI d&yxGJcz060vH#DDau diff --git a/doc/reference/clutter/event-flow.png b/doc/reference/clutter/event-flow.png deleted file mode 100644 index 6d2b3ab0fa8e98375257edd5a67892bcbc7196be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53730 zcmbrmWmFwOw=KGf0KwfQI01qLcS3M?3+@oyodkCc5InfM1rHwF-QC^&R&vg{_Z#Qu zdwVdTcT08k>Z&Dk&LUV&Midba4-Nu>Ac~6#DL^1Ei6D>{@~|(!9wCw|L-6ONy`Z=f zEG+E&s_Y8*`o=~~-5&h?_kr3o!pep~-a^EMJ}SAS94tDkDXQW_PGVm}wWo!^{!zfN z`H7I2nV*l@7LNXkCZzGx=MuuHLSJO{8foi&&&VX|6ZphGu?{+!>HcBE5(q-O8#vKK`YSy+lc-)@%PCg0)}sE{~!x$-=9A&!Rf80pP(QPo#)%bnG7PR zgs;KDRjx#hRXjXAnxaA>OmLm2okK%>Jl3c@IA$uFpiqQgXZ2Wa7Mm{!1*slh8anD6 z%@PuYfu;;(4h4AkCgHVp>D*tY zh8OzssSIqo^>u*i)Tfgi2w6EIq_4Ti>uR9;jDypbV#aV$K zLPnBK>2>(Hp3@77-qUHSDQOmG7F+P@cP?<+cRF{;{61&qM%R2H~xM8x44~g z8n*+9z9?KyXNEA5J&eVcWY6*G!S(ek>$TyqB+2qwq_QbL6$;Svq;Of?F6J*Tnj4+r zw@5>==x&~Rh)aq~=9k33$HsQN^t!yee8%6s2v*Ehi@>R%B{!T3!^NL2>zRKah!D)@ zJk-~&f7=%qPbNaAQ*RemRi$fv<>b`U(XqL?={-~Z?qFv$q7&1YZ4_=($c7ciR$WvJZU}a zj;A5C2@H91)U6h?XD!v$6&1Gg>E5J%@o)qCcc*#jcJ}t4H*Icyj_!AMT2Gf6eMsbg zzQTVl_>_?`%gHH4c|I0L3rnJkjosvVn8fP9E-z0Q`JReBp-VrN%N>h^<;LI)yWH@Npy~Zk>Lw;8__+xN9fd@xt)+G^ zr3N72`k*v8-B#)vc=Pf;tskVM)S9f4sZ~~1wtf8g?dhpVwe-Pl_Jd#4x0a_n>sCT0 zeZQDY(qJJ$*n<50l{^G|E)0^3hc5UGy@TbdK#81EwdT94RBq4-GG=t|k%fgYluSA5 zn*?8IBn*%E=fAgx#E5HVsi>=~!;*mEBa_lEOUI@6D;&`)3*~uP03QBH@em=5DRE%r z#KtcwH5_rN@=H$yQ)#LD)gk@|iyyO5B(NkrZFj}*y&t~m&7A#w`~H1NL{Imo9rpv; zzhP7lhLLa@UpR_JlkP`Rq%FI83^-vG6|Cp6&Y556sveJbtb(T5HI7t6!mzfkJmgXQ zs~y7FnOW*|Q;<)e+Q@WT-2720iI@aU`J?k>t?zD4&<)nl^JGpvnfxNthKC zA0(gtc}y`%+Z>gIQcX@=Tu!62jb-o0NdcX7!HoQZg8E28_p_ObT9~{R&rp;kZg;kD z5oQ*ag|mK!hrGhVLKH!fm(Z|84Ar*ROU)K+?vHiLNG!}*a@3yp7pG?zJovb?(WXX* zh9~OM6}Gl6k}6JYf~E^I6%rvK%bw@qD{b7)$Hrj9SkJLo?8wo?nVagCA6_rNM&@vT zdWhtIoT#&2uF8{Ht;*#h{Olt1N^obs<_qh@B=~97YOEz=fcg76gisAwuXMbhJu6yU zD=W`-W2t~g@OW5h>qf+%v2dCvoA$i7T!^JAQZ075eYj1ZuU#$Lvmv>^nw*+iYH*S+ z*Y_Fe?##|s=i^hKo%JT0;@T(>!=L_eh;B*}tNKANsx(}32KDn}P zdFG>Fb?licQDxBaIyuQ$c~_?0n#SkuWUeun@p!Ko6N`K_-y{3yW=K@n^Lah8kcK8t zCZ)WlVpr1wHe=rT*z39jxxw?ko6p7OZbRHdkoWJCkYl~+DBs)Lvz)K<8a3SAw5nL-P140pQG!S{vU=(OailTeT2@j`?K0qMpIi;n17BemSa@^)_gg9|6KLNG zmx^V-H|S<8NtcX8(H(*9nN*ND5)MOu-*2>#S8Zh|BcTY46LokWen?Rwvk~)n-brzC zayF$3k=AoG;^E<>aoXdNWak#*J(E_{)<*nMgNjn}`J}?(v9hZ{N1<^yl>qh!MTeB{<~$6`oR%7f1>Je6#cVAg1Wy84V7a^9$}A@TP4roQ>z}+u3pO+}+dSNSPb+Et?1C1& zv9e;St7~&N0AgEVp+x(6=U&pB)f+5G@RZXZxDLiAVj3BlA=&kG#zZMn!IuI)7k?)D zCT9MCrZTg3PR;lC4A#=h)dblF;*mal_%PK`e79q&STF&emXNhCcYXV6Kd+9|McLuP zpZ%S+W-5VpUbfM83%X7|ue`Xexb%C&lr@S^S-8nK=!9L*r-8+A@bE{Ajg6+!*2>D0 zi|)?dVYcHFBYxn)R@}7BS%1qdgImM-f3Vx2Mnm)Z4CA3!lJACuS|^rO z%O=}((|)L{Aw;K4z!6u{(9!*}zm_pJhJLQqwX+*5Qe`M94v4UIw0Cgu0Yk)1&3sa) zY}tlZk|wUfG`egQLYCRF+Xh@jXGPYIR%!ELevd5rFHQPU)L?{Qp%1KVcszf?gh&yI z`P%LGSa5L@Wv-3C800PMJWuS3`9+0|Pxj81SYD zk=_oZBD*SMkD68s!(#^q29o+6h^X_6y9}+L1|dnjGBh$0MItUN$q~;Q&2@DHJYqdLo?UlSQHbZ z?=4=ahfn-m{rK|aRgt?7lt9eo4@@7fIgKn!Q4&An;Us386@ko-XlM{fLp>iI9PUiN zm_<|)JrxMs^9JPxbgQXSS-zJhBurh|q!o@)T{Sc`G#*UhU33o!3k&O7`3TzSb|KfxkNpSEz?HRVJNpaQ$>(a4=^@hXT?pH!N1dGBK$|AbRe?V_mk3g%vLp zNXEOdxsh;l`^D6B=W4Wq$avD;J0ez${QO&P#1)%^`mB7GMf~g6U(C#cA84kg$PySn zXOxtbWRdhSa<@loWMq_S5G~{Vc!@12mU#sI0>V`aldWQ2 zNONRGZ^3q7^iEMUteldIz^p@;@gd<=et!Pd^gjE99qj0;19Ym4b9Eh|p|M2X`1Zi* zY0{Q-)@Y~0drQm1&3=`zY9jHxey;FZaKf1V`KXMfxVSLvU^;*LjzG2|=z@eqNJKkmnePuy7Y}DZHhH{nXb4YWS0>gpQ7_aQ8JgY)j)2kQ1<2n@m`an8+;>^A4aI@;TxH!e6QB_*x*L{f2K z?Y{b?0=aNNOVxPy0Vhq7Cn+geQ>*(IM70C@!;d(9UO{867zrCvB^%at*t#?qj2C_ z^!S+=JPOI|xJ7W~S%#t<1~{zGZy#@p&;?0fBId3o6obX*n$&;MUZzPLUPoN!^C**to%K zX)OxFdxFHHm<}3$@0yA$MRqSMi+5^LTuZvf`}v7hwHS}*NBKK_5Wc|7CQiQvA+DE-D_Ax;(KT*GG@v`CA$6l zYYxbrgkb#X0@RAtDkRF%(;6D)I8?X!=H`S%$>|H;nZX7WcjmUVJe_U!g9%89rudBz zGV%s3L1WZZ35GivnV1iOfWvgEm{YJ$jS7qM>yBDyd*_Vd5dkp>6(-D;krA(q-oTxm z(MMc$iv)mo5{iB6<|36TM{X2q#j0FW){10jW0O5W;o`)Ep}G0kqjMb;gp^!87(PxA*OFO6S$Gx{w`s#3y|-Pr?|`Aq&CM}E zTAl!Yfv5*|v${6%a2Y?wK(je-EkOF6hbkgeqbl& zvEQO2iri+IlM$pez22WUDK3gF3<=4|Snb0s8XO?Eiec~?5g5dP*OhHi*9uDs8^t7O;2>#8R)ARH7^nT;2(2$U;eMGWAnsly%M%^1n1B3WM zr^YU>rR7^vVMuaOtQ9d~CK+0y61541jK9A>cy&q&3S;B3KL;%#kkq&D3NV9(Dsedl zB^9%*(_30XJsT_2OMlfgkl+vyc$}bVHz35{r*~}rKxEIavu4qPwxZ8yav*{R&795u(`33E1NFkKsUC# zJZK4x98=9?0r{N}6O?{Kj%K!TlHuuC&B|Ki;h8Y9YbPXn@w&LU82J9oe;=?x_x?Sq zAWi@#Hum~%!b)wA0~aBQP=*}2%?}A`QJ5av^@YFwIf>*KtAkN_4J8(LUY+I5*5tf$G_z>^43#!`i)?=;THe*D<>XXN*!8B3PImtD|R zEQyVBIVY!xe6~80XtAZGB_EwyZyT7%17lKT=qczIZ&}GnYw(PXGC)o#tvu)*%#aX_&MsEAP=MrPNxzJRKb!_4HPoT+in?RkgLB78{)x(Tu6;!*TaF zb{1x4b`Cj(Kdzp~28xl#Y)=$8TP>(H>9*CwV{gxe=-C8}-Nhh& zzy;e{R8&&pd2^x{?Hqyffr&}0#x5LWAmA0StL9y)YJ%8IuhVdG+7Zb7dJL)e+cKiX zb8`Kn!`F)osK@7}SpDvOFXa`!L2fOPuZO!V0W)n|BlQ&4PDNWS>~ zo!l7-QD=S)J}oVc;@<~sxb#PpiSF(1gQrSOO{J1eTadA)RVl{#U>GFy$hkDt8BD~+ zRtt{W8@u%P*0AStn6CV;ijL;4wVE6mp=Mxcb$|AvqR-3D-q||HU)GTo7k~Hrd7r7& zO5e@=jahk5BtF6cn=6vNkS3 zady5~OjBc^w6yf`(xw>*;pX5rv=ctj^ zg<{WhCOo_BPnCSGv%+-zK`KHT&66i%P@&e_D-Q2zOnkr365DIx7*-iGwiidcJ&@Fu zuIfNf6VkEjv0H<1aT%bYA@|3Sx#}CU$pD(Ov^heDObW;9!2w;1WK^#qdtF69z{{Z& zUdx}$I?~dttFHQ5o-YN(WMr(C7V4i`T6`w!xo+kgltY#a*YMs%iy4v}!bbmj=36d= z`3oFAx2A>>ht%;0yOYihT4K>_{`xXq3T!Ex#3Ei!*!qnKAHUJ%bnTsDt}YJf`K#yE z6YL0!nR2K%bOaw^SHFmsYB#$*KY8-=w_aR0w57dH*J^gVOmOmH5U6)O-%4Wrk}I7& z#a3RrVr^w$wbbEs@(Kbg+|F3s(BL+I#c+RU1?E=g@Uw@~1adN)1gzW>A|igey{0AWBPozGK{ETT%yqA691Qug{xqs}`>gZJ$;$(WucD%&tbCZ2<#}O>lRTKl=#`n3rO1x3Wx4R{G~N5D z-hNw#y_n0w)Re>f$--ELGNE7EHF)>X^2rIT3RF)$!^Fn;>ffzNKWf=+;oAYx!Z_AJ)M8DW_&EhBT}LPd^NP+y-Y zlV@MAi5Ct`NZ;Uko(t0P=+Upc%;cxqCwU<2S+0AKS68oJAGZ8k7-y@scnI?^dijNG zATo~B5q$U|lJ#Eu0NzzOQh+jcdmzpIY~ysGcwn@atwMHUgGNeWN$_0Sk<*pr9bz z^=_s_DGG`l+0;Ke96owD-m9>8znnG{`K9Lg?uAo>9HHQ(bYTSgP+~PMkMp=a@+tfU z)qm;AKR?NNmG=O+^L(3u2M;x3r18|Chl7K|RW_ND1qP2%_xD$*=jC+>In(^s^yPy@=FOewW!I>VRRnxi2~#QnlTt+xd0y@* zUv%YL1>s_&qu*bMKODC{)1Rf)SEDQ9Xqdh7&NBT_h|0$gdg={urmCfy(Q$FC0U*vt zVRdG!1VG>61OU)+XIK1)=(hkhUO1cS%Fm`IXB8~00BGoRuHxKWViqc zBw5$g7!4I|KD(Rp9^1(Cv$L(CRH`X)m&K}`gUNkWYz7ekGMnFRN~fB)Xa9h95L z-VdmFSX*^2rwg-H00~AFj8S<-`~I@z2U}eQAWv#*w}urLT09%`@~8szid4(Ch<(e> zP0h{G99#o(>VDjI71aDagnuvtHS56pDfO^HBjIi^!8HL?UO&^CUmBvd{E4B%RYfS2}gB z*1Y>$N8qQcqr(N|jg6fw5rkEb-5;f|ckt1uAIsfjo0!c~!u?+5MAutq`6+d=GONCxg7V1B z%@`}Tm&cLo>}*p~|Be#%i#8aEPAe-dCc|hNKL%!~-k9y;9%_~Xhr4~Wn5Cu3rG+3x zprA00Vqrzb2C~6OB3=a*m9g=CQ3pB*B%0)4>SbVuE5UPdZY>)(_x{B0pVEngqmU`d zDPh(8t*U9vJGGdcyjEW4CptmuEAfZGO1ri^06GAWQ2O#JjmczalU7xY4ogr>L}aVy za-Z9i6QM(4*|?K0*yKav=^I&Of`z{c&Fwh3h=Rge%cHx5q$L0MxMfci#ixo8g?lj9 zkOKXKxoeTu{?+Z}_2D-uT#g|<>xs$9*WZa>K)y!2wNrsf9`t%3|0pTBe>h)#jy;5` zV6JY%F3{GqNbreWrvkmwzLHG#v1|PlEsZL^iQ#cVk3pyT&iL_el%C%EU?y5eZe?$6 zZLB6n-e?oknYi=0)K;5_F8!SBoSrWJFQ1`{MgI&9 z>3v94%#*P+X(rkUiHs8*3`Tkdc`NZs_J>iWTF*0ANp9}d-ekXILM8=C@7rjxM(5+H z@$vOxN~_N#4a#Q5ej~G0CW8Y5rYuR{zI}9YaRGz7j47NrJ~q|>L;+9*fBDkC{3x=s z*`WUM<5O>JPratqSpW2E;jVPvmfYN}oeF~^BBGY3C*Vi4G&iT)4f(v1qVCvydkxdL zz1e8?c=%{26D1^vU;f@4&Wb2$??(AZ-1S` zht4u#b1O4WPkIS)@!Q#RlWA*BGA;r?l)ixhDG7I~P`N`?(>Z+-!DJm+020c7HijY2EzU2_3bWxL&i)w6i*V0N&PW~(>htk@7xY?j6 zF5X*VfJ%q8?*}1GP2siBN0=+Go0HyX z<`=x~@#W9ITR;_gP0Y6dMvA(+u!B(Q^u)w>s$>ukA zccto8#*>B0xVX3_A|-xTZ^j_mP_D19e{*QbFm2h_*B2q;$6CkII{2q= zVCZnGs7^s%-EsS))NUZCIV(ZOdA*;)W?Wt|CBDxaPWd~h2aQ{0#NE-JHDdy&xYiEm z9q1FdO@;`l;oc$Q*4r016WHLnvDXHskItptWrIdshEqt2YDX7HUNs z>=f$B`T2aky$P_lmKLFRRDq@076{Af+|EN26AtHFgC#VOH;1dCK{aR&+`wP8M+UI6 zu^De};~#dqlo>x6N+UxkrN8PL$vFEv^ZgTxO^KH~0fqfL|) z-w+{l2^yc8Z~FH4SBIcx#KFN^=^B7Q#)K3UX#M1*Ef>SNodLjMwbX!`e)4_C=82+O z(Bbp9Z{L(?9A_(yxSbAuIUVxXvCbDTEf%7SiuOcBp-{%wf0?ESh(Bseh)jM_5h5~j zNl}q!g3bvSMfi-aM(@CoE6#m(LH+G!(MI$A6<`QaFy92|$)BzErSjLt<6ZvzA~H0$lu z1*d#gF*7eOE`S4`=NtfmzPC46CXYe8iQ}L(bld;xYl59s&D!1XZ!g)cmkb$koR1bb zZC1XT>ioe5kroynxu~#|hK@$Y>oVZC7++3d!`+hakC^M6xHwE0)K?JWTk74Q>V1BpJeHHT0n z)sFj9-QC?Pgn0P)ROIC4vj;afE>F-Nf(%qDgM)*psH>ZsMie>3X;jVMXI@*;vEA=h zVKXde10P4LN-vsrSCo@eKVPaXCs%HAd^Ax#5zyTY!(_{OeAaL{wickLrlFAp;x`m* z20$jawv3sX6@TGyK|!MZZH~ivYTeB*t5&?gY4XLVK`(8{y;|z{0nP;`>t*#7Iw}p-+qQb2H^1731zbuSC{*$vMD@E6BFcTMNI%N99~+)#ofKUM7$>M z+S-&{t)mF+=>7BOdqTqX)fMGG%xH_vH{%62L_sq1_+oowYczkN%@D1F6(|)Z2A_@wl>>+nAfW&Z^k+n9bYa@NOr8d2M5Q8gcPQzfYq+~dHVD*E-yy@m zbDHs7a4|7Spg;2b4D=L73yB9Q2NBknG$_;@oqQuZ>TFuz*$6_i8!WRZ8Pm`6r&F`Da@pd|b$CP!mX$7YL| zo4U3((?H+a6hFJYojm~i->X4ig&LZer1CoF0zj>{mVQ-O!Sj=^X;vJ|($aVk5+JkP z*m_gHQ0#z7_~4TX{9F0S$laYAAQotzAME#g$2p*VZJ*XCYzJgXCA{=Tn?)-e9WT|@ z6M;d8dV8P7h+KG<`0K0*!(pvWP5%t`d!wAI?VZyAu2gH9`L8Ej>sJ+~IHskg?T8Ez zSA-S-vJhe(7Z)9EnWwW!d_=@>z$WPbeg6hTt^Ex7Wo5|xcuw0xhY@A2#U&+(h}>r@ zZJun&sV6*4x0Co*$m$GlfDA&7m$Igv@xWEz4#X5>VhJ+R_QV0KOtQVxG(Jze{q$tu z3#Xs!wLYtgI&kQJ8;)?hA`KqgT4?lUe=t?kg3&f}bGu7xZahC*Ql6gp8#9&8TJQw{ zXZx1W?YAZ^A5kRsGmmZcA+_H~^hn2&HnUuUG1av>Kpda%_b~Coo$i-D?ao}468d*h zOtRJhC}n$V3&bh+sp45sCJ07u*wq6I(o$Zb3Q}`#FD6&l@#g%(26lNf8Vl@#lF;uN zbFwhH1Wi(H{Y(TPcXBN)tp>X0pXCBE>~VmiM>bfep`i^%%I0QaVdD!6uOhIpV)?x? za|#Q{)@$4KcNifnOp}w7CPQg7)YQ6Fv%|64EewwWO4Z;dZly%=U<7dx$Q;D_t*T&c zJU?lFrv_yno`qG*)x0C1T!ebg#9#Xh=Ma;#^F*(ox&VjwU0F#D8UJo)v;$N<_Qv7ohvx6V}?;3Uuqh22kruNcr`C6_u_ z2zwRIS}v?C!@@5a{YHS9O{CJz%*~zFyDzC^*HHv<)j12S$0@wGg+N!)ibQi&Vvv_d zv}2B;uZ%$|5=q35%VP@Q{?Xo689>u1DJcP045}#NzP{iHByj8DDFYSQD>@cDM3T<< zhH&>B=*YlkaZh~gXN#5J9|7Tn8tk$C5n)3awBG=j^NQb!v`E=1F(ntD5@RY0L#w`= z-Xp(%FE<1P7GGfn%qg&L5I>5QkT18^VCvdof~!!!O-Rt`mj2xw;r<9tV8ILTS+}j% z%zXJ*0wPf71CE<2(SR@tzPgc!m2~>R75qD$_V4LRG?+9D;0UA{C0j-RW6r295;yoZ z0{{2m2Nt{ql>fO-C{l%%3uo=BXMDbWy;7z*T-Q5WVg6mh98@_9(BjD;Y83yGGMt=a5^>VS6 zqyxs!PrxIHJAfAl$rhqgECLfmGJ!sX4WodBmUe%Ysi2|ZZnXmjASHYTHz%l|y-4Do z_=E&>LP^oMxCB%}AV2ylyJu*wtg4!PLZ@AwA%;jnVT2qheu8xg3xE%Bh4pgo=EfEZ zAw0N=8DxA$I8u;=%b(daj@2lBHKJiHqQ+-m?xwZnbLJ;()D zltwU-ztl(AQM(Z^9wjpFs?nQKZ#WadO%j%}V7~-9uz#(ZoYJA!Rz%RKggo_&WS! z_mFpN?#@O{O~#5Iuv{at0BW-QTnlt?R`=(!AVn3R+Zs$XFfyABM(0k{h)YP&X|c<( z-ea+^ZNK|z=G{RZOB4{2_~L^)?dBkf7wv?pJZ~U=4}lcFJ5@Se}9bwUz@!}Oa4no z=|(J8B7{s_r$uZQ<xhYW_>WxKqQW{sE&}FmF6-I5jpp8e|VR z0Y=*!QmG$|Qj+llJHS+i({9Ft1`HozMs~I-uLbp}ya!RDln88Z?`RJP(6dMec6Rdm zr+55x2a^jApdZKv`Y#?H=J+s)P@$gFpdf@oIdV$M--9DEKRG?rhxcz@em6aR%!b;5 z218(=V!a3Z=4NEqp{*MXE3(y9ApU^tWI!VmtsSza?oek7na-?^jVWYiL7HK+RY(=( z)p0#{V}?^WeZoZ}35yB}NNC6*0?5J{avPhQ!4ZNIQR0k6I1aQo0q8m9L9p}*{m+$^ zg?lr-v9G%Simbj`K^MeP11dzP*(>#Vb9H1SH<$9o`oF2p?mHpT8R6%D>cZnE*L#1R zH=IVnMF1{>IM4!v(s5I5Kl#GIW_ZFNm8;QZc0fVIqByIJ!-?6E;tR#!0vPEFkXsn^ zpb^4GK{JMHT_E`fAmK2s0O6ew%nL{q9WpU*gZuteV^b4oVxh$yyMr;4>_w1BmaD59 zJtD&QjM45eVp#_c0X#8NFpjD6=0Vm&%~eoPu^M?ek8pX9PAEoYTfg9Z`x+=wzhb!Q zXy7@Xt^tJU`gk@rI`PdLtcsIt8fwOJ>*W^MjOAJ@OEWVPF6y_4N6Lzd z(hhI6GIKxt*g@fvRTtmgOvV7#6@Vi|LQGvf1f2SSlr%{jsYFpW9Ep;)w%1YnYyGSj z3ZK>#XelU!%gQLHCzOzJ_4R&Q3pj8zBL(O=A1^ZD=?dg1py{*(5MM)rrtZha;73R8 zO@_N${azI%*GL!Ih_-j={ecS#G0agZr0I*LiYO~9tE;I<=9)yObVt(%&U{t0%Wtzj8hPWLR$PIfNpnV$bHqk~a9$z=96`i5n0Xe13MBw+!l>y5e6Z_ zy!DI9%+&w-JdN7Zjw%QQ8n&|O6+uM$n1Mm)RHQN~Z-FOl3_gxee{1$U8PVIg`Vd{r~94nTs-E^y?4xNll&%lt( z{w3GPhi4QOYD5tTy+T4mgYgR5U!CByTg?2{Wo&9{I^!RD4i694sxik*mC*qtjOg7P zBqTnUled8#dR4Q5NQ7`mNZrVd|4ChM_1sDUEay>!LJesCgo4T^`hYg1OV=JRyw)`O z7>MkI{GqsfBy#R<28g*F)RY}3r5I!>gh|G&p&;q3j(r%)m~jA<#pAXmm9KmD%Nz%q zRyhB$U0X6x3XqXyfz&cTA7D*nl9G~5gdOE;Yx+DdJL*cYdpCuI8QUtWYW%;^zC{DD zeEg>Yn8d_Cfb{Zs3=a=`6Aa~n`XQ0$%a%p5{9jHqO_8#Iniic96~Y^tlA;Opo%`(8 zxL7IC^(M zsEI8HM1k&Zi~=4$w3R`dr`%*%fSFlPABAhWumspxSX30mrwX-Vq^tGaU3G=OpS9iH zUj751WC0B~G&Bqi4aHK)K22<@6ss{A{z1|Az60lD2M51`hGdJ>Vd=b$6`$$|+}*uW zR#4Dh+b+w=nM_r+4&;z1^e{^wPUHPtZ7L5y3DXXg_h`W^y#^n&;=Q(yES=dC+>s6X z`e<9K(bd&w+g?g{p%S44_Z99vw3B9LMacl@(Z+OVIGL?J5>RgkGeG`(#O=b!OO`eN z0_EdgycGb2z7Q#DoGuikvoKkKmd0P-gjqpS@sp(F7qE;YCdSlw zZ)1D={^q8$rw5RN4`o1TQw``^twtvh)f2vdr&B9m8O;)fhK5E(Ma|-$+Ue*?0iy>9 zH&~4NFucSu{ZIn*fG|dIxc!Z1yb$Rl&`<+V;d@*hugA?vHBjJ><>}`05HWCZ-HmxW zYuqT2Kit$=%vJ*R9)N*8t^-0s;Fy`Kii_!h=;BI8c$$-oqp$CeW`oCQ+tQU;`+56X z48vhYx>f7xI#m!G&4@54CR=UKxkly1II%(kor9>kaF)F2e1w9k z;{JSH8Sq0sK0f(w+6@i`zP=rg_tyYhya`WCOcWOv2W2~u%<%E?0rs@n`?)1OUB}Ih z%L~#XN5RJCbh_51m@C!BD0Q+$sO_I~sD8*Fnqc-H1auqUZ3ZO;1*k!ul9H~5(ZYz! zD5~^2pvjBl2lBN2#lrB6$jE5zpB^}qqsj7>_8K3i*k8<1F)&!`zo>gn0q-w3bA{kL zIM~y08BbVBjUn;rlkbWMyU&}c-aoCdVTh0sM{C^6uGIcbfZ`xsy~CkN!+(6bKlY(=B7XwX zB=J~Ez_{t*7@L~9tal^w@PBz$4wBQ**xO~!`=xnQ#9pAzNjOI-7~N*$Y|q5Xba|;o znwu{GAg8T>0Ky>#YLDoL!ej>C#r`k*)~$}`!W8JqgG#H-=4^Int&IAosXyy64j zis)0H*P*X^;)Miv?9iT;eO!3sT0HOJ`1ZHAu~AW(tQI&ZV+*pgC$1baOgyhU=O$;d*YIA&##tOF>Saosppjlp)d4(Xb>y3ZTpQ zLu#u#9RF5yjY1g#5s}|f<=zu+@{~`f)oXCoCIFduss6^-*Z2A1T-I-dec59?n4@v1 zbEb3Hxwm2+b?fC|zS3N>Qn2<0EV=sJd|g7BCJ7f@#b-R6Kf^^Q*@b`unMh<_MMaGR z`nE!v!*nD_l+9Y5vL^->$KIv%APX{4d#|%liLj z`mmmM|5J&$m5?khD_d7yE+;2<117Sb2fP>*>hsz7gd8#dR84)oYgp0z_gjvrdS0*t^r=Lm7r?OoettKenp8wMI5=2XQxg*y=;*%7<`(nqfeD4P zt=`W-ymJ!2vZ8Bkecab40W>J@kH6UfumvfT9tzftN%ue4 zJ0C$bdHFIP=)pxlOOCe<1&ELpE1^MRw$7Hlfnw)OtLaDnAvMS-fUX44hH7d!OO^l4 z&e{GistrXDkWLRrjmNL1-z>Ixx{qcG1O0AC$4lZnLD<{>r0Q<+mFKZq{+|pnl6C_S zd@4X_lQ$0HBkdNuz%P&pJwEN1T|eDYadRg}LB4)RRW}!=j1>vT>0Y$~qau|cRe19K zPB0Ea_ronbsvzE;xkx~OP~gk2*)Dj*&u5cG5dKz}I&1GLC(COpHJkt-JqG;H%>4ZN zd!IPTd2{z|D24+dP0?<|v0i9)zXrl0u#63yaq8dI|qG@mmf5U!+{p zNW2s1`0;F2ASikK{DKa z->jv98wXr+ax%C3l||F&@-jdF--Vw*WId3=S!D_T?2wUT4i*dm+O?>t=>Gbc-(g2? zwDm0VRV>XDDLz7nE-3Nick*!Rsu?>X(;dpIdV2>s@lb1BqSI4SsIL(Z>a)EbC|OxI z2WH1_ynJTsk3rS?b*Q|m=F#!o*j5KPj@RjSetgC!E>Zot18(faUGx zt*ImQM}b4+KG@!0ev;~Chy#vleI1>cc=-7<4M5nB7V3L@djT=VZ@-1m(u|-jU<4v3 zKuv+LO-fuG2#Ycl3iR~!fYt$I9?PEBU>4s0mDgrvNlQtMcwZ}Z6R$r%oILB}sAy<3 z=(hQYMiSxT;0Or`g;`Z8)LB}1JPh$WN`aySNV$L(i4!oXL(NMnZR^Nhx0~1x(i|Q) z<)C0(=|>%f@j(#;!VB!oAu>O0^45WV1`NGnEvkz{w7YjJ$6=+VM;V_2|1PDtSiUZN zlzj$71pniOqLo!CI26hM1e8K^r^BZI(&0nEXM0^AX%*%3-M@zsl8lg<28rl>S-))g z-Sx4K{OJCXRPa40=8PzS+~VO%XMWTal;Pl00S$4(w0$3DV$TtoPB{}^DFRFQhPS$t zK>!rzN~!BPDo4w$!>zQD2?nkgJELW-Pk0y@fOeN|O6}4I;`7BOS9@UAWv_cnpbiF_ zPvC@j9ru*{P*P<8Gr3S{Bxz%F0`~i9!w;8gOghwq+#001K(IPCKF*K-S#(Vl7846g zCY8&vKmI*BmCV7#J|~(SmA4Hx-a&xq_pUl> zq>@die^8?whHuxVxiA)x+_y)cHA5S9I9ub~sl9$aW(WlfN}shvg)&^wZvC z5m4?}T37%9TTeLtwQ#z;rzbC8cYmzk(3zIX&HL)fXN^kP%zByBZ$e2KEPT}oo)XxeO<_4VpIP=a3?Jj^TvBWFQ?1L|I|`uY~T-LZVw$p`xjW+EV+mw(x& ziexQ%U;H9-joUE2FTK0HJzS`-0;;*vQkfn1$)~(!84}{QP`Jmi8|MLTH4)eg&2AA9 zbp9c{HpYXaX7{x5JO)Ih?sJ+E#I)|7;Y5D#Z)L}!okCvgnYZV0ao=IX;Ka}?j?V)0 zWDSuQL8NA7^jguTPV`}%?Z(_O$I00<$0UTdz=nPI8YetXEMKOW4bv(VJH ze*cYOKG@m<1lDx$G%d?b?JFIbJUtwzQ-zE5o(cdXPFp=H zDl0F>EeS=CLp;|G&F@Qr4Hn186=h{3z4=Qg|GkOADA{ekETni;pF$Mg?-kLbF3!$k zh2(*{J~cK=JUG8zkdiFbtCS#oU}hpVr6eO`_I?sXH;856)vE4fN^VS8v8&%^NO8a1 z%ZZ7xo7kiUM7NGZ!>?_PZ!*61Dq;inB~5wK?w5CtPBQL*dMu6mQhaA1jsoEh6=``0rv)mP%0nx zV49v7SZ;~}JfQzY$fABc#oS{mNsRPMb3 z_ydrA)LD;%T#s}(C9vu5Kj1LU`7Byub9@HRK@gET_y-uh@<%aP+1J1iJ@V%L`@xl}B?VvsRaImF-0uJi0?H;aG|O}i z4UM58dON$bykQ*_%i&Bwka<0BvU75I_8diBT~|W{V#I~e6jhgPp4N=OIc%#;@R0**bE@$)&?2C*w_c!{bhH0um~K?d9b1htV8rk zo?oF@yuaLc2KsNWez0g6Xwm){+5x@*WPxBU$@Q}LGL6#1)7wO;ZWw+4tMva{VEWeh zWYs?OfR#e5%*^9+> z#RWrO>bnqE;vN@v$ixr{a=xPMY-x~hUV{Z<_GEV+IvIY)E$vUxs)mMyD1eqjTKWro zwt#?u;NWgJ40gN$>`sV}4-5*z6}987Eh({C8^~#FY&XAU$ zghB#uxy|BpcLOl#DJkKFv|?gm9qsMq=I4Vgut4;8gyI#|xahg=KSWRrYVY$Hv;QeK zz3|8*b7wMl|3vAc`|)Z2-@mZ}w)d}`7WWpLZ}($Cn#aa^(Qd2m`FUqs8xA=(Lc)Ep zx`}50{JA)yn{{@y8W$N!`ktjGBg1Fqi*pWWsNiu2r586SH~w;b!O9YVPYVER0?&Ke ztHsUn3Sw4G@vMFUetvci4qQ(95U zd#*5c0h}u}`je}Y2g^n?NE3Zil}!`@7-n$a?zV>WTXVksOOJ$vbn)bl_D8Cqlb@PTArFGiM$HxcWW+;iFDvJXU)=`g`NyOdV9iZj;mLOQ^&k@gm zu#?u^gN71q=FF^->8U%W05KjGsZwgxj7;xQT74#gje$C*m7%k2osrr-Xz_z`IU!2ERU3hQ}WcbC>NY0lF%h9NJzl6K=uUe3jl5$Urh`^s}Gh~N!o{08|%J*r#PC%@j z7?)H3?7af_+JC`-+P5k#m@uas|DnhRIuQR0$Xqg1LIAx`n2o*-D_<#Gc%y-f!6}I>-%@8 z05K5?H$w^K|K2Vf!_t`5o547E8U77UlS=;AD)x8#6z%Y$J0;Kt2ZjzOqG^ix`T6A& z`Tc~J6fP5mJg#6{-)$v+{My_eBkm6u8=HECC1pK|&@ME0IQ(5BBRu!+r40VO_3!6o z9`vv|gZ8+hfIwIYUL8*7HmOQsY)&^c%&hijd9n6q0q*F=d-Y9-qig!+hZ>!(ObcD3 z8y#&J@+lbKA*osT=34{v=llRYw&f9L8v(}IH@#bZv=Qx2509{D!=wRCf!>lRoY$Th z;R&ub$w<@!3*p58+|DQruS7H@=DxJhcC>ry$B)q2?m)yq01+!KFAhQ#xkuX#c01vN ziI#E@7}$E_J`OK^6)I%tqd!tk&Yf#!3dRgswZa*XgkMS`z4-rhDWDFb0rqz&pOgdc z8Er7NBPI7%Ly8z$3YfJBWWt_YS(U8=Vvu;#JHxe1){8K?e&~w-Wh`WBYNf;UFrNB_@>c^;V$R4xvkvRk% zU#b5uf8CksVU<1b++GTc!~`?ws;;8H%5s$b{Bb<3@eapGx_ zm@w3rS17VBrk^?59X$A=ll6@5%Uzaa#J?ygEC*8oZ&E4cpGXe=Zf+IVADv?Tc|oVKhoKN;j9&LEG_f}+Gcb?zekk~UBE_>IA`mR4)) z?_JJD(N8QYvER{a{CBC?ZI`-0#Tk5jBlEm}=ilqes>Qp@$w)|eJXY~O3hx~3%$RvG zP(_m5s=;t^ak2C^g_j~C%^Jmj{?`C&T`gBpSe9w1VsUyFB zg+7f4AD@GN0H7<|V<~Q0w3{ttZcdao3~U?h*FSUI+sJRe^u4@rP{GZB>c=UBrcs3% znN?e-rtK0J0z=pvp{Lk8I54-c01*P!)y5Bt@khFK6T`#NiHTPmqa1d0F)u7FEbJW} zsf(}g0P|j~4yVPFCr93pV*0*VFJnMj=;BILH8QLOl%I&?uZNJ1@mVMMFJuwJESr-Ec@qR_5pX z2L}N%Sz2D^o+D4q&4rWqBUF|1b-}&GGEF6H7?SbIrY8 z4>>eedj|&_Yn%nJYQIJK@C<>TB3-pc3TKxOxx(!*ax%)v{| z80+rcg2KY!prFfHU+Sxq`4DhX_8lMZ@1Jj0Oh>V5NoMsE5`dwf0*(jE$tnh@X5n-( zGU9r(fd6?(#X#hK1TOMD9JGnOk7M~>k85-hZ zVcFOpI`Ct+U@A?aeKGLqcI7qr@-UwhK-ooPjzz3{ui^ICb z!J_;q+oSytY3py(-o4ois!bW@Yzqn{CFM_ale2tVLu)YPa=YV&bTw2M6jDf5f(-r+ z!Z9>lpyhaRvWv?ouK}xle4Lw`o1BD1yUvw#QaY^<7Wu*9A?Vcv46hAZgFiSqS@XmT zxEv*G!Ce6w1=P=xk%K$?H{PD{@$=;*52Mmi6M#kmpk}U zCD6nv8_f$D6*Vp{F3q+c8ZiclDJwP%XIzduW5lO8=X zqCT!G^-M^}pF`vt6xh4`qy|lY^=9f#P@^)c;Pa&bTCT5u@9YFG4`lMbCCD2D#@kF zohjR|FL9Bd*(^YbB-Psrr3&!7Vvl$i?v8%fZ*rV=&Hrq;ovzAnd-Tg^mRzi<356P*00;=*5pxK87KjN9jo#j! z3O~O%4Q0LgYaA=KVgKmv*OlL$`e?U8UX~yt?5L_bS3$VokRn1K9Rq_8jkL23`_RWg z8bRvdle&sTB0A4H$5t zKDW-tl9A_{t$)W7cLK|XVpul~OLayUuWB&FmH6q?zg$M|2=--7J;|(gpWr{e{^$;f1}e^SeNt z*z3;ggS=l+) zDJgrHw4K9i)9R66VHz5=H|B;le1_W*jHEK{A#y=MW#v!zF#~k#-!<~SZZLpoM&Ms+ zYbn=-;ZvYt!pD$K6fI7V&687+!1?sN+*)ffGkM1&N;(QKIy*a{c>IHEb=6;0TGt(p zJ8th|1UNhEEl9iG9E)gwr$+tkY2X*#e4u%d&2aWNx3vjV`!)gk_OrT(vzPm1q}$*B zxuBpHQyx>_ZsS{dEJ78|MZ!oVHo*r(y-{>*G;k+9F_rRm`v$&=aB@f7i|`YlE6I2S zHL|1>f|RkLN!iWU=?Y9wZ_RA^%&SRuD#7rlXc~=1uR#n-69{tLDSP&ofdLr;b3J=y z>y};`0@AR(}^DJezsc(Gam2E*3FNm zUZk`MIgvz1M*7+F%wa3#DfIpwNbY8*i;$tmYkxbs2PYF$ax#hi4GnDcP71IM&CMg@ z(;-=~26?51XD$u%qm%3mg4zXpV|-c9s@}TMOV|DUt^zEXzkQ?ctc)u@^xtPhMdhce zXJreOOw*@)h#&^3#iwVMjl397!s6or%<{4)FnD9N{e9v$VM29@QF(RB$Jswx+-K+K z#lf=iBBqCmQ1_|6vK@S=jDuWU5?gBXo9V-c53dvAg=t1cN43<|1)XrBqpv$!oP+BM z9bStls&NNmW0XVe%lZ5F5E#pd=l5~EA`PFo?sAD7!^dkYG&U+KKGy&37X;T&Wo2KZ zGKq#1zn}w1mM?bl6vBCd%8wz5yEA2C#KlbSmK3I+M8>-NJ4G-V@;YqoR9s*<>GW9ol&jHg15HYuw zA47kW08(AaqN`VGy+`Mn*5BWcjXo6=j7>(qW@cteKtRa->m>O*(?ixjj~{$bR`M0H zKdqQ1BO^zl#zR1`zOg4}F~}xF2kp&D(BP;Rs=rOPvc8mjrK_7n(-eUms(JZXLIS08 zbSYQ)6%KL?->|dK`g2Q8ujw79nu3A^AD=~U-}j(>i?ZHZ=zVUWCVf%PJFr-F)(DLo^D z)u_kD;k$A|D!V~TAmzAY;qe&F_Zoj$kiE};mK(3we5sZssAAutB;}I(Gp39ny#RcYzzYVQisgQ&>ZhqfS zoIc{Mc64=jl2y|-ZbKgs8Yrkf{4PgN?>(7n6V`>usqfk8DLJG~q4y02J0d&$>Fyi_ zRQ)X}LE++>poWfTU~s^-w)V*#nRG~@qeTOw(VHtOu({Hqy?JAP(JrkC`n343^r6WJ zC&;kO&2s|M()y9vfzaBXE78`~6r9VOZB1W-7+C~rCnlzjVl1gLkozm<41hYb>pDL#N3Qh8 zkHWk>=7$fjMg(E6hwv7!Kn%~2C!Cx*+vQ=5_P5~atuN5cNWU-S9^YnE%IG2L$M8M} z_QL+YzwrWQ_rs*WMuzEZt?_y!2C;=aSzlS%7$c2O*k=(GoO-FNAS;&ky)wP77=696 zg^^<)-Mg`Y7lX>o%4&ai^lx9E`(n>@id!?ihE`9SQjYy$`6?;N^j$&Q%$V}>!}Z}m zY2pyib0>$efdZ0!>~-{w&3c+b*eI|nn%gyW6|Tq1+qxgE3~`EtM`}J~eyFMRN9AiI zw8#*Jr4wBg8X5VUH(Q};eixINCAIs9)5%I>0C7*jvijPp=`!3iJO8PZWS)l)Sy#8V zf`e+YKM*1aH$XYf?Q*{Ju0}#l?JcR(P+kM zZf#M;rv6|mj*pKYt~%Ub9!;M2mZjJ*U0aiV-buRiGZ>dBfY6rF`Kvx1bjqmv8cWb5 zMuUlHngJx3bte~{fsCt=s`06@aTo7;0K>Ow)zmB|?hid)26S&~m4#(L5*fR0_7KSa zB_#pT$^L_@l#hvpQ7wVL=Kh|w+{g0uwl@h!+hcnD&dTaB3zO^h7Uj@K1eyUfWUuku zK}_ODcn#&yEYv1=7Y0w2XQNr-JF^kJNz??DxQ5anAV}dKVHG{z(cN8a+oa|0@)F@z)N#IML+$wI<-+7`o-(FpW_g8$zj*zh07+|VlI@$Kf*|?i zZO7L?ac-POCTM#%(KwAF)mD>r8rs_QZR`F|i{%Qwh^PLH$w>_6@}hx%-r6!lxma(r zf>JRt@%8@l^`u8{`_zvgbt#o)fsHt)*ja>y%m6(@Lq$PAun_Rv^sT@!HczY zu(V;eoXU7PhtpM!0*f9q2^q&zFK8`Y<> zXm@7)E`g|os-#1K?{Z;6BitG$2;8SIUshLw(66EQw{{e{xG)`V-3w(b zdb_&0WyvQzrwxPt6R@G)>q=ln&vi-N@^f-NTwl4_!DSkS?(@Hatb&XTaG>~z(*l-d zXk_$e&j#6OOM6|X+6z3p#aIg-5I1IJMcq@ro}OI4+3F`|>H`5t2X@hqbyD*Rde+;uss~ zvRYRo@UQVSK)TquJf4OCzncuQ?WtOLaC-Ddf z$^hgT8d8PcWGe>|3CYdX61_v3Cnm|h>HVB;~_A;YeCoeN1kVDrs5BopGIeR{H`kn-~4 zhkImfZ1@S!tszzdIC)H|{{28M1urk}4VrV24_^qFG2lVic@qkuHt+ZV1vJFO29o~b zd$dcx?^o0lrD0SGtT1%GDgE!}c_)mn5Vp$w;PtlGC{tbln%D&r^lN z`lYVbsS+b4s~m{Qg2=fnFh{UH3|ey-b&b@qS~r~qK?|fNWp?_P;WqTY+JBKq!o$K& z%{!NYz-viVOM(3`qCXtr+QJ{h-_`%_4m|9zaL9rr;b^P0S;UAXY47M58X8LF14kx? z4;Vx1FORgg6yYB8+OH8L$YWz-&Rg2q+Y5m1571r%gEX-5dFr;QfBi~OQBeVzyU%!e zDMzj$4vNd^;+vqU4Efe-NZ`y&9rI?Vn;nMx!T356ANdlTbx$V{X7<8q~h zR5<62pSTeDNtczEkJoQ|Mh;R)6ARw0VLs;6O|unq^+&L|NQyvZ1{Yn z*Z^)7taR_zzF$pEpsXrPP5nDH)tz8t2RqN!mgNmPi;4<3)r;5NE09X9I)s1l#7A^j zyZRB2Nkv~)OF8FL*nb?APi^-pd9zp_J+cH6>VoHbAjcFs|36UWg+v6i9N=Jc{v5XSKgiqP!4cejzE0quRMHFWeyqd zU_*G)E+M{6y_LOWCVBGt^XI_ef}uk`i-Tn4y5GgQ%J=C8JIp=d;_B{pk2>M`7#9Rt zA^FE+Y%yM2Bp|_b1g_T4&(F0MBhnPGJ<<=Grna^mx{v7>#A(W7b9sMq5)wfy+wKk%!oQpK z{axDeigGyP?buiutl8_iUMi!=p^8|yn4-kgS`s?Fspd|&{OX2*eP{~`?=&6QGbqkB2w9VAdEt$XOlwzCJ z-rrJyLzY1v=uX*I9v4T%-^(F19ea8Ro5?B42cXNxG-Ek3^N6D()rJRl7Z!xy0Ap@7 zwql{D*S3wBBKOD6&W?_*2vF#~a~lL#Jos>ZCJ?3FVcNY@lMCVTtgE@JfY341!-wsDA^76iHjUW7oP1|qsSIWWW5Kf(_C*{Owbkt$ zYlpK4t}*1fhQU)mIC!}jt$SOD^GzHI1r{+G8E}!mFC_(Qgqr>b$HZ`K-oza|Qk+s! z68=0Rm6(#^j?n#k0MpB2=3Sm+jf_9T@e{|~*N{!vNO8OMjSUjBLT3aJ+wv-JE;AS8 zaLLQdRtjO=xx?>~NbbON5Uu+NNTEAD&pMbp6nuPPE8XE_x<$|eUR96NLmSaIHJ_GM zzI@M6WoI`eUw?KKK-|`;9C#QsmogFvz4>{)WDjS(EEBv)6TU8Jti1572ISmz8K893u? z7IP=>xj+;);lkoW8yhsQ(6(>o>a8#Tzoj1X9;3{inO&#hMdlywt5PX1kzL=xzN2~D zLymG!kKGub3J7yXTp2VkyJI`X`}Zj>PqVZttN>deT?_?^_&=%lyN@5vI#wxbsC;1J zFRQBZFH*xL{1vI0lb7@7TVXKGm#<$3O5Q$dI{&fP1YxkpAo~Gg2`=P4l|0;W7C;>@ zPTpIZ(;XR))Vgpxzmk-^{a;@&G%T!f(soCpsi_I7oX&cgFQ%sb+EG8HWn?BRKU{*K zoZy*;ppNvng8%;l^63L6rrRf0zr!+~$`KlRN~&zg|>kWf`-e+VI4GYCh5Rs0AO%pKY2C0e_5ITZPUxD|A~MMr3EZgT)rPKz4sOHcAZ$*m4P20@&A}B~0<>Ob@ z*Ma#Y+a5+NGeD~PHqJP_I=fEa49|#A;f4FvuNx&r^oI}89`#DfTCG`T=%s-F=;}`A zC})LB(}U@?vXbYinsBRYpWEk<>tG&h{yCE(b#~4KQoI@vz7nqs!!nHmojN#3TtQd> z+M|<`ld`g>`EUGToy5vY z5&AgRY_rb`aFACwH#?o9;tp9VDvF9K(@&b)=RvBDe}Y0;4ax|xCxW_lA1JXE1e{@5 zv!6+dg~Y(wk{~biVJ{uTDGzSesUC#-!EN+8ISA-9WXH$Hm;ZcK0rBlw72Nw8-TfOA zv&=IxUqClD_4lvM;o2aq4!469+`XRh;LQ3J!KPLZDGDB{_ho8bIB1_hv*U3!N?cO% zOKDy_F4jW5K5QBvy#WUb06veanuG+(FzKgkY$s44|5Uhp&BZ?PWnbBsT3uJy%FGPX z3^>yT&mfkPoSfXQuK7W~G0IGPM4(J}?Aq$;DcssQd@A(os>-)-GqQe(t*@B^9=d|2 zW9s9)e`N7S$y7$;nRlbKbf6HaGj#G_6^2XT&Q(+}MzrgKu79yJ8ue!T@wq3t(Ifni z=K^LC>J6z;o;R(Z;gkk}k(PwSTj>f}_dDfKKqcL|v{KqL;PqD2)=c~sKeXrYDbkCf z74q73KxzlPuKn5o*orqH=&lWmF8IH1I1fboj@AkEb`Qy;F;)vJb2N7L^guC2y_+*T zE%}-Jz5Ch@5{Py5&CJG!hq+Jkj0_CsVTKjGMVI#d4*Z&N-6#CSceWCspPE){Law=MU@16mmOvcC;%!eu z?Zd?x5LBC#Ko?G3_=XOguuzOa^}|AB_LU``ukjVo)L)T6KtM-J``NV*IOHpk2&v_( zf4ur4pY$J68^?9f-*;`z6gF*3_4@XKSCyK^a4)4^2Y}9_ffr|%Azg*JaH_5@YxHMK zkBzg-ImC6s(&gTLj~LNTppF1N;*0wr(R*ioDU%LquqU6S7{#t3x&bmT&llbumBufJ zs-=Mc3}Aherx0h>8p*8I+bn%U%pPs~AAgyzr^BKM;TdDTot~aPF)85c_5;oKwGWiA zud9b_ODjS`kF9X9AyaTihffX0%Z=zF!YWBPCGNe(*IwY)uUgE;+pdP zj8k*p>l6ry&)w|~gNmN4(qI_+z!L&Ip_e&CfSUX)$7x_h#iD=;{3bI$qCLN`aH`6l zxyr5CimvHyl0SSYC_Gz3sHxdC-oVojP8yvmyN73lCSO-eX_@HgE`R;r|Hl1?f`p{f zWgD~<9&j2TeD@zL-g$NhPfmu+rhni|_9inGv>eiV_a*|76o4r24Ts=U~X81}cVM+w+eEpOlY?H9z3z+sl!X99g7EJ0{c zKtCf{kv1&}-5YeTlFuj-{K4n!0nf1_76?h>D=Lmb!QN$5iaOjdRHUnr))$|U5D^j4 zw^|A=XOOmvW%l?NwzPa!o=pMBrpq|S0IvalDQ%IC8;l>juSWcgHbN6pGS8A0`I9oa z25o)-t~uJC`yACp3ea{j)nR0B5a2H?qyr$wLX=mX#aNWQGI@>-x7D&&D+a7gH@dxi z15#$hTMG1epe3*{CxR4Zq4ut1k95EEva*9%POAO<<=w|5?qxP)kc4Xb$J7z(*0>7G zhG+~y&}dQ$9$glXW;apaiGiCqOae3!NYAjQf?UE`wV(qoK_Rt2%LlsOM6KxRr}b>A z3iBj#4X>rU`)j)c3tptyuHeWo8LHV8+f$60>7=A9Jx`xJmzQxqUHffX!CA`IvFM|% zuPr-}^Sr6}EGASzUd+ z1^MbAC>pt_0w|yQb{j*FIm|TKgj7(n5^aEUCORVX%q=#vFluKh{*Mi6)6ld|2l1W$V*?SntG~QPMgRV~8?jfAOh{CLtV*S#J zqFA!WTE;NF;u~KdP(%x}&lrMuAVAg&w9NjwYb_ovsC2Yf?Cei9OIzG>=?_hB&eB>J z$6T{qTx6(pAF(`2>C+p!M?wlyP#)oekSr=TYOgrT7(N2Lf6$$v6S8oGr95a$CE-{w zGn+s5LBI(FwPL^VFM$bxrS9^jcJ%3*5BQ`X4lhyFzZxqw)0c}L_M43M=nf4GYAG74 zsj7TVz$n)-U*4#Bwb6k?=?N*J0HCqadEX6W4_nSR4!V3-FwEv`A1lx$2?O; z(|IkgM$IyBBKs9){`?#!mT!b^D7evvCnq`C*j{RDzShxVtV%jYB%-8*2^zD^YK0Ia z`V^|$Wua?QHB*Mau+0sAsR!{$%gH#Px-eenT!4#kLjZ*uaKC zM8zj%=**m)NETFtHz0xI3fc~Qli1OL2?F;sf&~?R`otVUf627P8mGvkg?DOdj`sE{ zBRRcLPEl(SD3-w-yO9x>*{mku8F=}sm68k>>$=kXe#_#g!_*kqe{hrFF8@D>t?2y- z5Q$7qPJ)9y)Z;k|1(xx_MtW-M98{Mp)>;s<1QrA}H8pkhZ%IkiA-aLdX!^>fA;7cd zyn9IeIAMEbr2)e7koEQSXzt(VW#3~;5X{VQ02tC}DFP-o{3vhKS*W4^jN~QeYGUCQ zA8VOh#Me1MPe&&JsUMI4P4uc$(fKW2P+;bC8hP>Lpi}K`uHKlS&OCI4$8a z00jp+pi6;KXxd_4OaUHJS=C1gw3=v2atJ;i9#p=)Po!`!59d4Dq`@RPzOl(s8J+qP zdfcDy=`c1oVB+7y2P`J0mPex-d}q{obysy-6_!z72{2jM+V6F%Fh2r?f{G3~-0PI$ zoa$<3rnNC>PbA)xmVqHdyT9YBRiY_tJyjq2WwTY zX!ndD(?kvI>p=E_Op2(gSx?TjEJs7}Juc{klEI6>&wpo+iKZCl9`qy#MZ}yg7t_fY;>!Z!_m7Dwoz`a4}dLY#5htCMi1K8ogEhJep z0nPy=L_{DyAdA7{Y?V>4o~IGlTDerw&e2gyLLyZb2KwS4KYaAi5(|5BV>7Lwz?()I zu0s&H;v(UqdMm>c{iAYGoKG;HczA%5vp&XxOIb>5AC|*Ly!kOF6{0%2bIoh$=#O8& z05_@^&3|F~x63GJ7@(P+MM;NrX-`jtgI$oWh6uu7Pf+8|;)8++RdmKPTx3?!s zeSJQCE%~|NesXRu871YP{v98mhS=Dk)YOu>v%~DEDXM%#1YsT+f~8&QhmBj!iokog`g>LqPy>SJnQrXcT)!L^KWZcn6<(0v3t>%h6-}FJNHYo)AI|dBoUt6-o7T;&B+;kz{|%+ zTO=_wJdD0%Lt9W^FC-vvcl|-LxNN}6BpM2`fGWD(deQou81(v`sK@w6_Zx*3f#w1%B$}q4J7_>dUJgSM$wc!&bo3?xG;6JqdMEr zOkBSg6+ITbQk1vkf>27c?Kb8I=G!X-T^YA#SmB|COfpSu1ws2A!(w$1*gEYQek$ki zl#b&Y)>Kg2ZuzqgI=+TxQ1Ez^l{==V3-t~5adC6Fow4L4vw8Tecl@+1IOP>=196|N zEtP=t$nbQl9vi0Y^L27EePoO;RgkvC#mOmO372bZY`joH@+lYR-ccEXE$Bx5`tc+r zG8Vq31ID69iG_fVoHO_mRO>$q>rM~JZ8?+$C^rEmOP%+g*YtMTAd4dd^a?^2;N48u z$^B(JN$%VidW7sb0}v^=E1JG!SKVw?1=u@`wQfGqsVHlk%*X z1Cq4vvG1*|a~FLeC&8hb2q*NSfw~1lP1p|Z1NsV&&VC$ssSzM8CQ?$<9qsK$*2ldA z1F<9MFtBiID(Id2WEWhawKZs0V_uNlLY^yvN&<$A07;=)X0q#4AHT3z>+k26$&p+d zF+!$YA}aEqOVjeHQLnD!aejf>_YyWKoP~{_9MHPJD0)$t2DQNmCys~|0u+1}W}VCr z)>b~Ly#I(S5*Ir-@TzEEQ>dlb9%6L1rxGTXe_jON)ibkh$3XF6rm3PSC-V*N?j8ta z0rqWQgTvOw79#)ylo;Q*tpusA{T>a&zRPzG`BeNtLkd|O82++kWO2y&90=NC(!GzPbYN37#wN5`MJnp^Lj?oYt}-(dZdp5*m^uEmWE z)2q>NiI8A$@Y?Nq<`mNy6b}vVj9>m+3-Efj%BJl^PeGvvR8=soNf>8A%uMUGh`zBJ zHy17vjbU%55$E6_n7PRIuzlsTS||LvJ6(KK%!NZgf6a$VZ^oP)?kIuV8+uHL!zg9u zq+37j7;r1@q5}1nq=|rl)q5z)0+{_tV9^-in)9^fFg|z`OL@rU6UmNwhVmMGmLg(gE;oM%J^6dK^^a3?j#7=))py^-(Hf8& zJZXCD9PBd$+Le?cx#GG$GdnlKSkR{i!}H1CfdS1Llj4*Vs8A3-GO@DC^hlFu)cD_5 z4^_L>2ioWmIC`J~ow~(phCqS}6rYQWui{o2>QeAG!XzT5C=JLA^er&G#MN1d&4`k6Q~f5`Isydv2>1tAlh7z?=BL5?_t`l( zfEOhSJwO8uLbl;Go+JJ)IONAPMC%XeG4op>DIDQTfe$7T%GO8@hNJ&~zlsEGY;|=> zKdW6#%+`@nd?0A)4P{um=KzMM0_01Rb&`FC>fVX}!W$6*4TY6;b7p38skEz)T82LS zIP=dse=TSPi|@X`ySZ$FDW#{$_MmZqn`T zy@vMfRzJxtgm8H+V18C;(Q`C2$`bZbSw1AS&2Q>dLFk&tF2`#E1dUp)OLy3s_TZ_fdRMsN)h4 z7+~Rjen8MMRG`bMyTv=j_byXDp^Ag8t;Oh85(onSz1AC3&07S-^q%*SkeYyMll&}+ z&!-J|6DW9={?q|$TJcea{brHn;bN-YNd5H?L64-hG*@xR44Md;M1S5m$f8NjNokL0 zK!CLpIJonR@M}H-!Z$E%qwP#D)fhf3it3L`1=KD$0p=3!Etum$a6CebzVs}{b68xB z98b8=(Wla~vUmN) z5G2%^CHpPr52zf0b#Kbrmqon!nADd4`K2PDp&qNV@b#{x!}0~-0P&)Nk7wsnbPnU@ ztx;LEZ@x8+w2@IM$O_ENFtfjjgFd#h@FF~E@yV0hdBsSxw0H$#vYpSV85zLf<1bzY za{F~01O$Ake?r=FlfE~N!=ZseavJkHfjKLPyjoI2=m#m=udun77_})WuIs)21e}GsuDd8PFJAw&c?*K` zs`vjfI8Fi_2)oEmi825OaN>a03~(b5x&Iso1HT~fZwgf1YEbrq{RC`-Iy!0;{0BkR z)xHorLK2d|ZFN$CY`=JxeLpf=<$!qVuLJyjEhsEM^FmMJbyk09!f0V@v?WyFs2xWQuSr^o{ym+ zBUVUq)<^@!2TsI3e}cF_lHA~ph7NZU9G||_?mN4?qz3dbMvL8dzoXPxL8#1K80XUi zIqgclzPege*vn2={YoApZ9W4oX{+XiK)qL)XhYJxQ?dm26_o`ao4NU<#>;i(^CmaNq2K&;H6;# zItR&}Eu#Ne4a+Mkfd7UTF!g4cfRm;i;uhc~tt~CIXtd1Coe8RtBSlO^1ZGT#NCC00 z&;?TyHZeU>z#-(cY=yv?+GRfU!*f%lS`-el&uXv1fr(2%@J3(1eK;Hb6{xhEXaYxc zc8!){jQAN3mIW|Ro8+!gt(5(sz z*}z0n*ij8MLIQb5;wovqLt$yHoL5|6O@e9k;3;qof?=K_~a68>ugfPxFMI z`{5cxj{;VMdRx09h{(RZxSt@uy|(p+oy3mUyU~zs#SWa`q;!+nVM$5H53clGT==|b z1Ox<9QWz&Dhc)-FqZ%Mgy)i$0aD3clf9Mb-Y`+66e2dh$F~B#2nX4XjCl*K*ORCAIF5{*+v;dhS0CNCX_vDaVBnmbhoE?>toXnl12a&cMH%$n0z2|)N_nIQ zE(X=jcAnVR+dEP->geA=@KHxm&SDIe1Cerr7V zDX^=tWSU{ag*Ivh$iF_HPa2$fx5vvljf{>F6A=nJpCp%C&^BrL_@MmxBNtce_LQ^S ziHh6`Y>%xnen4FRI!Y3jZm3cfRuZPx5QH)J=(xf19$*sr$mhVS{T*#xm|h;pO(6ID z#Mz%dy@1%W?^vkhPW*ygTkhh`y7--WFCp0p!n``WTxq)=!s)dPU@A=GK(`GY@fyI8 z##o{2#6CL08b|yA<`O6trvEQv|D`wEKO1s@1Ofj5CZf8!dLE4VfB$|DMk5D~r=Y-M zZyE9c0FJ#p9gYN$yFDpr`9E5*!J#2N$}cay|LYC3{*@}L6<{*EXKtZyDagm;R1wu1 zlKaIMT+#_b9#h@j!P4|lz1`%UOl0-a7Q#qOC_IE5PX33&ZSesrRuMxQ)c#fm2HuZ2 zA8|$MA&Y=^0XV)&kFTF@jkPQT?766V+1M&nHcl|fhY^uOPn5DYMeex=uH z;{*iAecT4@P;x=|PyNXS$nG`r4Z_4BZvfIx#A(4WeY4XUR6`86$;}wr#7T{MT z-{EjvYKI!J0s~GOX%f5`mP0`i*bZ^A!5OCuGtT29Zt2Y!ZK`y<-b(V&Aw3txLx8qg z`U?;~ATr(xF<7PRd{bPh)hk#6+!C;hP&kO**baw>hapJ;(k87Syh9`ucJG6uqg1IB zH^Z10OMtS2ZQfV=O>+|pkbk>SLTQ63FOXT0l$2}}Yt+C*uPsEc_a|q6rd+l4EMkvB zVRkmbO#Nj0`}Qx?J$m7gMEf095+vH+kI;aGN(l3};{yfm%LjJ6m*ZCTl#AAu?}xj) zE&uC^YQRKuz{Me%&tEk_q709pNM{npGyeSc_23)dJrM-Wam^lG9>|h<_?_ARuKF+r zLOU2l7iNox+S?y8Ffbf{=x&V)f|#iPfG@j`IYlD6mwS@!7A` z`HIw&z_+})dAZ*sR64rRsH^zD6cx{{ZEZ_I!h1hbuMYNC*j!CbbGa?XSROy_+3qAH zSeOp3lgMf!tHHme!i+#q8LJ0U_Q&LLC{0$!%CBDDf$njk`8XWgx9O+NV#mxJZ4c;} zeUZ1H%qYytg+mr|)Yq?UB!Ms%6%-v5laM>m3rH;79MGTHM&B1nBDLT`je(8mMvTJ7ELz` z3yThj!b@;3Uy!lu!kF531-@C(e}5fVn3$ljn`ngjr?tb9a2VeDbT;WY4V4vWHTMpg zfWmOss(&sc=YGMX_^-pW5Obix%Qz(i$Yo%Bd>>M2czJmC42I?*&V!bgPE&Jg=cp_k zU?7BM(irhX_O}a0?eH0!xRoA!eb=7}qJgL7v6-2V=;$Cn;u@EV>b0tBW_H^#IW|l^ zZ@D7};Xw`fQ2v~{JwtE;$5MJ`CU88?R%0;7r8%#^&h>Pzd-B^o{ILdPc=|ngI@|wr zyCrhWDeF@6@SL>5;Q{i@uLEBpEpw}->|kK5YV6Nc9Lo18XQ(R=R{KxgBH=Yat%7>v z9@;NGwkx-j-Y?bYP0vLUASt(S>y^`pbJ1N6<5;=9S1`tXtCkO@bS%s0A^iJF6}#OJ zBwyrK0;$(0G<~s!_rTM9322q!LW!sKmP@a94LFW(;h@7asdjbI)IHQaXutUBoE9YU z;*zi3j;|=K3?d9+kd|~=ds!r*H{U7h?f=u;cZXvghX1}wLMo9^2@Q&fQnH0mM6$QY zD67cG4r$0r(lE+McJ?MpvP1SrWbeH>pSRyRzca3L&UOAeuC6N*Uf=KYeV+UN+@C>~ z9$|7sXmhUH*+IG{@j4m>_f5M2w{ekTwxjEAVsmqI3X!7awTT4kLyU@NxpgkKwulDp z@e#-qFs<{E)GOCUN|6p6-EXMRK(=#2~I zQ)Z}39R|lo!n%Uk!$?>zAeRPH{>d&sM!AGv>-hrf^YQDRE+nLE4{@l!FxRm(e#{p% zkkWL{DLMAPPOH1^akJpqffWQZWz1xS-FQ7Eq8pALOa1;$3ggfuqm@h$N+LyRHy15; z5ruv%sHS0vO|&2q%_hciukwv`<(*4TUQZC;{`&i#FW3J^@0l*G{W(vQe0;vQDcXTV z41u+%0<8I-K3(baJwx3P85a^hmsI?r$26lJG7U%%&XRfUvt?gxP7K9-$m4yH+uSOC zVN@qvTuDB{&A)%Uk1f{r^&OSp7JT?Rel6b|OXGVN4+~a1-(^;|(tE^0j$xFQmGmxM zPYcrT>|9*d3Xv4_bzN}1szuU-_qhuMQjfa#GM9CcxHH&0YGY(1xje%2BasvfkR|VX zvzoml(pfY$Gf$nyiOeY|m=7`-xN*ny>YAGuU&d*Y!{^4qJ%FDxae&72YE5{lrhOXqEr`nV&xt|c=(>!UUP^h8T>5W6s{KEwu$k$0 zIKYsRip}mZOg}Zu%jy-KZd;9x^EZ+)d2Z6f)jz-k^ z>LY|=r?o}Pws;-@6>s0(!J*88>qBGt+|qa-DPxb+B1}!N$#pRylL!l^6+7UR`t1t+tM@i?rq@%pRnGm?T}19d_}qRP*NG|tMJ~~q z|A~LGs;=%po;}l3DVo2r0*4jU)CMuM_?#&SBpJKMm$*wZdAwEi_2yQ0W-)}~H9EYc zq#&*D{ySNlU+(I&9kv4dfX5rmGN#VYFB&jyqqZk@DUKtOV~^2|<|bB;Ud7 zVB3YAjKGZA7rP*KDc8c}_m6?q0wN}|c}GY4u2_gWUK9|B)~!h%(jpEI1&K|Hi@KWH zfg?xYo3%EgD;8Byu-2-7hW+^WuibC^c5-Qc2!O5h{uI%{q3B~>zC4S5!FiMn^tqDM z5XOY-hT~i7WdAA$gH0;-m#?fgZ)>{gYOkg^J%IB~^BEB&rAqwo>2%XZI@ zlZ7WgoAu!pRL^*-F(?!Lqjc@s!gs$OuS4nqZnB1k5_hyH_a}a9?tMW=$)$5y=64y# z@zS-{((RycX(YWJecQHnkF~%Hb+kMjPXJ^kBqdM@(dFL`&VfzCurnZ0J>O?xH9SYD z-6XH7oxH-Svzv{R(~IRty-Yy#N=snH?f4O7TLX*J8XKt#e|e!#TE*JhdVFIio-jzp zIn`2r{#q9^U)gk-U-sN_;cGx`l?x&+2HvfhU1hSu<8-Nds_#bedJh{j1S-IiH)UpBuDw5fUL>qlqY$6 z$3U){5;s`U5peB^B13$twXyNO{d`$s)w^k*s1d~9G&a6q+V^LwSm<|0mDbN25JA|D zf4XSJM=5!&l`9cgF6g7MXWRXkV4LiJdK7*R)Li%eU4=pQK%uu#}D^r zCbj~5jP=vyWc9wkky{xnm)7)g=bP6Iws~C>o%ZAhw{K_v)!Ir=pOF&xu{+PzVNm;A zkA=X9*E^)ah5(y$-`eN}O$&iTC zIyq^Xn#TENRDaH|P&G9*b=$PW{7&KtaK*2WAAz&eZ(`Cas+nVj@W+~@)9~~xKD0x= zRz5iR2Iffz54F>C>x}1_F&h>1+2qNSc~uV}%a{Iw-c!He50w{%gm%bJW7FEuw0iv| zg^o%TL zTUX_;Qcdp#wkYDhd06%Go`a=X5HX#_?Ko$maLil&buTl$1J|qSh3UIf9l@QI-TO8Z zF~6H0@5L*{r01~nN>xgD(ABD|Zf?aQp_4`y>YF5Prcw1YqW5fV=`KKW!6f4Jyw=3r z?33c|w;hoKJ{0Q&FV?vAD+0|Yz8JtIz~1IQH|LoG_Y#j$EraXRm8n7w^E1UP1`Ur( ztu@OOx9p59jVvwamNaK)BKq?e=jXQYTSf;_M?re)tf2pGPk1&;lkH8@{NK0$QdA9;pI!z92^d!$mpmpZ@dSeD%#llFIi&TRs!B=` z!p7-<`s>9k8Tspu2?@#Q>bfq5X+kdVxyMs%hqJmae;R3p*jA>ogn_u)AlHR=8!PmY z7x?)rbaD|Q3T)yaAJ>ncKi`}4iiA>U#&yfq*VMd##{aBcdPsOgnNRl+v_wzOojU77t_CXrxH!a$Ad)aXmEDlIKtRJ?$n zHM_FTKA_00mv3?NrUH3TY;}ru37g2oU~}%W!%!{V@i_Ge>ZHVEXY0zNAf`#kc7-Hn zXGaeepBtL#Pp=L&40ZpUq&;LMM}9C*cru}x8ND3aH+ITs)tuRsZ+Z`$Cp$6ofB_@F zRgA#Jwh|k7j|E+D|+i-%`O6M@GwCo&Vg` z&Wv@9(E$67ZW_THXlPS#D}DC+|GJr(lMp;qBr>;gfLr%6R1AhCBQ0(tH^y;4*x0`7 za67DJGi^i$)(?T%fc@;IFOND!l3vCQP0f|8XE9A9-qeUGl6mm(AuYOTUti5u<)+E5 zVxhTYM(gYY1cIz!S1Tnt^FIe121XG-_&`|C)fIE>G*5fP<=*1S)v>x$Wp{HZNjnGc zny9@3JNEsfQUktU{NzF)$cwsYfW36q%49J=EdI@Hn;TcbQ8hZY1~gklXkI5uU8K5z z<`BDNFhCf}*S!^nX{#B;AA4dPYcbyAThTwvzQ zF{l)jOpLniv zLv40$Y~WmvNa(O?J-j*R{f~%zH_159_bZO<+C;q;7I_GDvWH=IwvmNp#eH*>pm*=z zr#|fbz?pK-`nv1J`c{xqewIe3hIXgMF8>N=|6^Ngf8Phfg?wDV)%atC-2L!Nj$IkT zJ7t`A%B;0&?Q(h%#3;QsjOVjMOG`!l5;?2g!h#NW=qLvvW@i)~fr>6a|JWz)o6{~^ zP|dinaW$(_OUVALc~gG+K(i`AcCQp?AeGnMR=cjYa0!5EqcmiS<#R)@dsEik!Rr0` z?c0QePuF#Kcw}D6+(sA$J4so$tXIIk?^_xz`==D7#OxVw?;rBrMM5HF!JylYeTcwf zg(DDeN4;o0c^F&@U4`<(Qzv(R^+`&yXjP1b9+y@EmmF3PYr_|$$Rpm75`J<@aWYT^ zvt9d`PZ~(T(|k!ePDytM0X!6~hmI4^o}+z_&8K9r!QWzfIsO&>#mdBdyw| zbCbruSeGykkL_Gu)7I8ZyLxr=;{7M1SM^7Uhe;@bAh|D!?n!HGn?{112kTYqZ%-bf zzV7Ma=H|wX@B~b+GUcZM70=NMr_Cg$mef^NN9W5EJX*b~+ekbPA{GPzKrG%TIZk@} zcvDMAcear(ukEsF_RHk^%RvZ~A|CmEfLmze6pF^XpM(qT%z)vk67iB%kzYtzc5%zG zx6mZ<_=|_>-@lNW5(>&*(Gg_1r8o)iZ`Av75r zR5F&};|cSEqBYI3^U?No2txk2LQ!d2+_$zLm?G9sF zkRCp8K=g1t{|yCyfrj5pY6?9WLm?`mWGuV!3S!p^>9rxz+y=W9#nw)bKPB148w7|t`v>w-R zKBIUhAu*8V@t%$L(vkOg0hgj1lDN3Ow`o9-txn&X(?e-;_KkPo?MqFywOk4j7p-oZ zB*ezQxyK1b%%f35lH&|fbRP4{%BtsigPu2eN=5>ay8DT{Zvin%c?B0oM$OK>scA2@ zMRQY7Y;I{>?5_5|&QYsQ?F*n`#Q2{%ZNGjSX3M94$FU`Oya7dyL5ltp>= zwX0TnSH)FTEmzi<D{nCzWZ)*J zXm0#9x}||JRjk}^3|0!Axaw-#mDII`rWV5$xYb>nx5?6C2@&Ft9+S*qvNSTraWpeK z8*zYdV|U71NW)NFAQ3Iv|1x91QD|HEGtv(oYB&5uFW%AX%|h^)zpkP(J-3*d&I5+5 zM&{j_8b<5gfA8FX{48zeDw_9#qZyfU-F`&U}DH}!72tmjE#t3G5(wR>5N?@CY;#M9wOwX)`@ z`T7mVDGn~(^wTHJ-d?o2VtkA5PIpJZxW&ZFkeAzBifXQ1lPV_lxR0Wf;6Zwh@2A7P z`|q2Kaa#`5>{U`#rTeV~Gv%8%eK9>UyA9lN_NpIL-=992=@*eS0vx<+1|e#B->rR?95vQE?(r|IJu0M|MuPPjz)qcGw~80ufg+GdT#SH z*Xf~J?e|GZ!prA>R92pO&1`68b#HTBf6?CPzFlU9%`AF8vJx7P4`f)1(|6zv|C-mx z2Zb=uj?`3Z&?pR2jxaMr$OreJ)nUo#2D0QMlnutly5UTC&_R5MAw(#*Yvc=^6MrWM zi%k{;b(wUF_T|%Vcgf1)J9V1O;E8zVHV^f8BF@>Nq3Y1sqTWZW0yQI}!0SYen%nB? zCXu$`l{ZWs^D*IU>FzB@nh1EzM5?1iQ!H9C#7*gO zmS#nfia?cq?cD{q$$)=i`_*SRkUr1vP-9ndi#+TeeFjlDu=pD^6dFG$SDh!*iG zMHT(M@A4G(@Ef`+XTrjDTT(RR;`nc<%Q)ZgNKNs-&`d{ieLE_Dy@`x^QKI+-+GG?I zqAP!cVc1A5aYI>IY~?TQKZhQE)aCOcUtu(j|3S`*u_`Dk0uT%r)6vr}^*B%AP*!|* zAsMj&onPR}%%zhXNS%K7kHjB=(um;u3&e{kOKo>POWa-m*mhU&2llEb&Ckp*RmFAU zJF2H@_5Tq?+G$;dZ5P9#u@5?294GZK<8w4a1GlYG|J@ z-<;^+F6_u3s@D>Y+yd%}0x%*&RYe7%$`$41kc9_OAH}VQojE?kzxMFj1l@1zFI_d? zdhDSWeIDN3mSeS_+eJeg5p zL1Mp#5SbURx!PTgVTqt2j?&oMNPK9^Fbyy>W%F(e$kNZ5JO=9-4C$Ye6gwTef4P|S zOW-5ovyzPok9F~iG$76&KZYA)c4XXiB{+IVjn2=rL z;y9J;qST!64oSuu)dU7UVnKZL*qJk_F`p2jl7xqGDe~%7Pa`-G;-N|j$KUK^WC~PN zr%lopnT3Bgv>at;XU}EAXrzTj<ztdl-M-FF zRhE1WvMrQ5rzTZNL4m`10!IQ$9MoGlor~8Uk&@lPy~x4k$)gYz~CBZHXL7OUUo2Y(O4gE(o40a|fW| zeX_8NF>|cm$|R=Zo6hj~c#@;u%0|G}$Z#)JT|VI@4jh7`2)n|O0AIy*A+fAXzVqkp zit=2TlTLFzs=&_+a$efJw|uu%TlS^M11)X+sXwD-hICU;+C;5;w#n_P?lGZ()i>MZ zeIVBMY^(F(LOClgn-k7E%9C!Saqr~W51`@;%f3yPsRulP?PR~bb}ltp_qcdH#P{~5 z<_>knsVaOlD*xlh9MRel4N^tpoo9kV_zaTqN>M~P2h!j@0 zD}Pj_BwACC*$^a2VYx`y4rq-y?qp{-y?GOcF7DTL>wY$4hUhjon3VH-)2ZpBo^1#r zw4%Dmb;v{wQlcyJSKD&j6(zmAAJK?Ly7zxy`0+y*L@&h%)o<*vEb67x#4>+74HMG_ zxMDKW(vZGD@_L+|U0Ju`C$y)zW+RP{MIwUR665MQQcisQ)zU2HG=I{iVsYo*N#6ot zrQ5eH1@14`@8TW8%))9j9OdYqxFz2fk{B9dm-qwGKuC*%4Ify#d3h^Pta7`^O`oL0 ziI4NN&|;ZhpXiPa13`W8N-Ms=8Uf7GrjdE8z0Z)?jH8=ccw-PiDJ(S*+5GL>U&JaM z-4u-f+12>MMI`x&YGX&oY(->=e&PPF12*y8qjX2a+zzK5Ti@L91YyMc<=BaUBg(L< zF+daKL4q(o_jcP=z@VYkB2dDuE{y44&_PB!(s){uG!X+eVblwIFpPH!bh(IO^zg>S zDb9WTxHomWVfiyKP;xReiG&!JX!8#~Ebum6v$~`ueE?Vc+O_r!{`BmWSEEr*6+?3{ zIar+ZO|t%U#(9=cR3PiahoI3Y!buPGe&VO07`CWVbYBb@X?#m_(uAubx_hzS@Tb>`cd z%gM>XGR54LCb{)tkxvG4OWhE{08WEvC<2$n?)7;ip#Yx!u$fw2)vpR{>F9XtBC>H) z=^l)>0HoH1Zzay1aOghlg0J}_luds?)Z$hK?F;3gM1$A=F8d1NIFStd0BQAm9)C4V zd&RBG0YaZO<}_B;)?0|iSY^O3)zi~cY}t8%nK@FF3~7>&T<^(Q&zaV(kHkf? zDTHZgX>+ccEaWp+DXG@0i~>+a0-W?+^c5pg1#1wl>!QWP|GjpUmd^dc~i`IH562#L7iQ zBI=Wql?4Mt&@nC?JsK785F}^?d3hE1iD$bm)Co!`V7j=lfDAeP^jno+ z)?VItw1+O_OhU>DHg(lj*dd?pYn=u*pTKc5qkX5l(A@>C!*Lns&I$3Ox%ydBb;N+W zR|_`?BLd=^l^?Uqbm>lJ7nX}XnYU?2Y`m(hb`s-oe{ZK?1*;l*9^C>8cFo+of65;1 zqF_ZSq+jfkXI32ZAvrl&U{yAoAZyV|UnmsRwtAtCkd-Hi7**IwnSTbO5i?17LnD6D`fxo&MRPuB*p=RfUBd6>XnD?O<072O~Q^IkCPl zq^Ya%sJ|*mE4XVOxBBN+_WC|cG{1x9+1A#!s=8WIvP>EWPT2`SdKTlczsBOd1COdz zc6;t@OWNkh7)DJ>2qZh7W!L)R21kTCmc~TKhPkxQk4YJQZS?}v`bm5R<`5Gm2e?zV z4Ilc~bV|wWWam0oUDoxh$G)b$BuX=>52lXzVS8`YVG)Fh+9u#SfBbmim=KnTstP(| z;7#a^Z`5!k$H&jzwJmlXS`3a;l#nQ++D-M_AObdazVt?o)*tst9NB+>Uf6M2%b|HE zL-xO>v*TBDYXy6(@B=j^ZS6yhd1K%G#!}xs!_ny=Gbvy4rlqIho`^_)&&JLls)P;i zf4%#+Kle>;8LPix5PF_fL~R?PTJ~0GiRto=^3CV9)%AYIa8KSL ziJ>4~z+W5>=5w=C>b};-zVFrh<{!7~fH%(Xr3R#7hly>ewAXMn?Dzv?dn-MeoiIxx#E=kyAm`O_O|6dIL`8>5x z`#js6_qj1Iv9A&_QIC1_m;3ZIwr`h-llxi{h8hNjX$c%vyZtPH=m&B%PVXfp6v}UZ z7w*1vq*+z=P<&o9ZDhSn$~I~NT&vs2Gr3VymUo2UQTlJl2F({0UMSRHKTurY@BdF9 zQYpjkz^cw4vi(sBLJZ|*z%~Md|LNM=?;ZXh8_ZyY$e3euXKXY+g?Ty` z6BFNI#i^yK$;rX7`VW3k(xvx!Nkm7!@I)oYj!cdwv7AXwj6Os|^AU#2K@aB29?cPP zhs-Rifk9Z;UDrM4af^snG8_O#lNGzdaL62mcVD02Sh4|I@D=izyUeD-Rm*0-_DTHs zM)(cf=52>og71z%1C+uqYAfA9kP&QF{URppsIff$;6$_Px)%|r^9@F48(c{halW&? zJ$9_X$>~^Yisn{pUWR}`yIW8HRJXf^Mor%w;wE;nGysu2{tljrKKTcU--~D9wMyvp zUI2NM+zQ~W;)^9EC9njY7x9Zv6`!l`s##C9HJ$k0Hf&~YJn$FXl)Y|Qgco}nD8&yZ zX=W%WO9qc}Kyk#ze&WOp-SRDXLqg~;t*uQXA>36_`OftX(d2> zdaB|RQW#^jNMd$iZSh?XR0nPrlTXRwnHcIrzT?3I2X%H!E-u6<w{DqbM_VSHuAyLs^r^}7V@dl)3)46g z_O$5DrOHw~yV&%PrqGEW{PXGqfzT+aq*Pj8-BeYE%IaoA8S&^jA2`%zcKdd+PM*`c zqoM#?lXKzYZiYiBsmrh_(fkLM?F8|o zkTVJjJzuzMXTrlk%SOuWzO_AVkb@O57Qj3&@bWezh=HNk{F9gs^?@CMEX2O z$Iteg=mnEv9}N^f*ab`coh4*IK~Dw8y?yg0^5VUknr|BDz5CVdVH?w{zK!Qs?-CV( z@bpq>h@G9yeOvomJPgWgin{spu2*eB0`YBD?U=P+Ya_m0VSb6p*i8H;FFKNc=kRr9 z)i=FUM#5FsRTrk_?n(Y3i@?ap^V|zi4rJ)Sa2u=vV^hw)bSjm*$w4pUZIYU~#(! z8exh}QE9SOjDI-AbOy%y`S&YqD}MgsMWgc+SNH)i{NoBP3gSxc{!8IQprLdhAt8Jl zEB*R-CN0fjvZp)4eJgoLnsQ3OwE@TJEu;bJozM5Rte8CWP2#bJmdPz zh_Btam7nj1F8!C@(iFNc)UnaY8@1~CBLUww7*6OZD>p^BuC2Sc1~7@b^bI!<+_%&x zg<)TIZ!*Py(H;+Di*_jhW2uNlfLVUhhj&nJ*U5e?mTV@Y#H5)0ytPKWhZ4I2;0J1nu<)?O zi5@1~#qpYvCjG@Lg4cF002d-VwtzvEda~9zx579x-+jGvD=4O+l{>_5wZCHhKM?Gm zw*tPU1{d1{n1%*HMg5jW{pGrs*$$rj6YV(x)aeF2!a=0KA7VhdLz{|b1)>X-?N2_* z)BJa=_}IP`c^8YN)l#U>FTPLwR?xBxGRIc>nzQ6M2MUuB(}k2YAE?gnc4cq%Ns|I*TYV0jK#-pGJjUmOsP0^Uv4E zm(PDt5pw#mEU#ChoE{u#e(@mA6Mn#pudHs7{XQ$sy9tJp%=<9A&juvW>KwYy zFfsQ{w8Y@Vm|1PE39v)Ex45|Yv1!D!mg7%kSrO*}-+@1WN^hO5@H?aqx`+9RB86s| zAdv+v`}(vZ?n~tVwX;4RfJr@O+t9Mn(gttexo3W(TW_`J1+9{jsbcuEm9bP#`ZH|b z%46BsdSn$~^f=b8sjcnY@3Xs=miDWA``H`T-kzR)J^}ps1$j$F-m+3sQei?4@I@Qn zYX=a0uO{{A&=^srWj;7BkYVz~`7(j>53Q#m7B#s!Cuc$;;nY1YR#vmB{eR>H!;1}i z3iE6SaR(2C@s0<;tP@r`i>qp&(<&%HS>fM%BC>vH#u1WSxmTy(2-tpnuk^2T9|RVn zQ(zAnsYUA_3|<#zXVXCjSzN@|;51}qy#)(>^p=oCf~~;A?kA1@p-c(3h;M}-;5?tj z@ZmG8$I(A6B}u*SRB_$kuAFMTbhvYj2DWU7XI=%|0*fkgR!+4fVz-5>j~ZulW6GV_ zJi5B%$Y6FMBxrB>$0m>IutMvUc#gvvokB-}#YS?b2{^5p&!~Hu)=p|Ye+}V?|KX(S zW$cq6AZ4U6ZY+l7ZEQL3VtHx?3=C^?sCH{&h`_~_tjO;c@hYO&vHfhC8rz3g+nt9Z6}Gsby?i(y_$RPbq?g;~ z=^P}A6G%7U$P1P_oO!{Z_SRP3ru>-_aY^IoR84X||u%P3Pl3Gga4JphCZ+(ZtZ;{pOFL zU{B8@B5tQ&P&in03v!(_Yn==SrDo%Bx=F2|KFK)V>Nqv+Ih#0G6*I*%%7f0soUcn7+!D` z+i!JucYjv#m)1tEsb`XSYVXgFbUIkgt*m1PUVZj21uLGB?qWJZBWc6cZz(5^>&VHz z&!-GLf)|LeGP>gZ-W-4-7rXMhotH!(%zmq|4a1ScIYbO5eFfkE$UZ3280#P|L$3fO zEG!FQv+F)r%dguBTd?xk2h^E@}I~fWxX|6^9I8jD2tv41n?uc zD9x~3UEej!Y2gmi2})0uwPqQv*!;O?rPtFkJ^j38;5yaPv_6D^l-zD^vU(XQ=9cfrv3QU2{MxZ2S{b`M9oL1l@l-5t#jkUnWACD)w-egA>Cm-KDHmdvg z?v1R`-Vup&(!`E@x}Y@;gfYjVa0d__G5dv?oDR5WuCBG+&Xc)X1GCA zPtQBBEGo+K&!5z;PHw}HU%y(Ma`XTGu5+KAzalI9T4Sn=#l}TcjBDaMtmE=@CYwy@ z+8?YOR$yoSt9iLR;~8Z_;&$pYI_5aFDYBEWOzy6xntq}g*K*CDnJZ4s@+@V|ZQ&3) zv(?Z)n=&DkZJCji(TVK%mDdcVJM=b64R~}8PwbwT!FUKd52N*qicfPzG~~>yF^Hk0 zoP;U{Yw_xlr-Nnm9+!N~LF))Ks2(-`KzaNTas*A(TG%69aYa_NwhJ7tt4*>f4JNIR z6a#;1aL)=m#j6kze?j|9r~%^h7!~(=|DkB0GnBD)SZ^?@=yAN5 zI1f2!_~UnT&}~GDIOiL<4S!OKmePp$G`+G8tq`ZWA!uLi!Et#j4to4ox5@4#R!Jao zIX5)MLIwaP=&wX;vnPsI?d%!k$lEgR2io=nR zkP;^OiR1D^{|NI=}cd-NOLt@KfOwrasgU25fPSm;i2^dHmBlA z4P^hL5ooF$=&7o8SJLet=efW=2_;o!p~Fz(r%zNSyWyM6u5j2K>M(1wn%t0Xkfug? z317GW;|bi*TnS!|`30c~+<}<(b^7}Hl9}oP=N`B^4%wX9ojV+-T*F@4Fy&Fc{|9$n zDYv?FRX$H|cK9C3+tS~AzLo2aY;DN?md9aHyx~j}OhdZVRaNBrm~)VhaW1c9W#uiNSE}?}K^c3ePh+gqYmHqY!t8$w{e5$uO^QnSQ2Mp`(aTpp zQ*EMC-75$gJ{lHTJ@8#GFYN7G3G!2hAzfUKERz$wgvv*l784rZ=jEL^wII!#mj2L3j%O8#qEwD*AtO!y@IxOL2lxXKsJ?0Ejmc{>GogO0IGC9(M8GbJa245K2g8Euf%8QcimKh z*yFDPw63dIz^ExbcRq^0%^#FV&}%gq*Lv{4$*1Ps&~PuBwaWgPgoH$2&7>vuq~R?p zPf`;BlN!!Lk0r9eiUW?IeW#c-pt#d^GFh9Q1cX^=UQ#24_Y^LWj zY!ed9$x5^cr&t!v7SJYfQSK7588-yDhxqefHQ3IE(rqX3 z{J^Eb8pst8qLFax&NH%~J`4j030b(J14ag54UoNPZSO8$&0Iq!1D0=xk|pR*vv{w& z4PO^qTUy=97l5L8mp;dAR+4vtd*N{+x7ldh`x_~ht(X~I+X z9y81XE|Z@+Jvuelw$ttL?*;P~Kz^HR70jFwV(i}Q>(ytb3O5$3@B?oTj$M0)=$oGR z9p^dKtA6}gFEo||CyMpf+?kRvfd@7VRUx{dA6M#YQh9vpsw%#0N5R5~E8|txm+)3= zulf*1o6vkp$d=DlY3Ds)VmgfTE0CY*kdWS3zYsdszgCe;0|#Y!2?Q@f9;NtSER4DcA&21~ zL2u5PtPeeAmVfSt8vqS8yJDE*@X~K*`(lSJQP$(PHeJZPZr-`G+F!E8lQQZo)|DqK|wVvIkdKSYo-3hKy~x4Ur~FQ@WOzk9|*YldWLMn*()Y}S6?hJTk$Z1q`cf`0Ww%DTiva*vnqT{p|)R9f*qf#t-eSVhM8?!5I_N8-m< ME-Of-NEmqj7p6!)jQ{`u diff --git a/doc/reference/clutter/flow-layout.png b/doc/reference/clutter/flow-layout.png deleted file mode 100644 index 809ae918aebd7ebab3bb3a0b0a8b5f08a51c2733..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1850 zcmeAS@N?(olHy`uVBq!ia0y~yV4MQPVjOHh5y!oW#XyRs*vT`50|;t3QaXTq$r9Iy zlHmNblJdl®4t{M=OC;^d;#)V$)1{F3*~`|TJQ*v@#mIEGZrd3(z~FD6vt*u(s! z=o>;JYB`5oRdg`r6iKUWlaNH#>Ai*tV>RCWe5ndvWkjM>5Osdl>I+* z;g0Xe9)FazIbi+x$+OBOi;eeP^mwk(RrfP3h85@z28IJ`E{dLCe~Yog*k|3X>(%#6 zer13E`!T40s}lQf`!9C)|2_LGIzPpd@7>v*_x+i7-fu5{S8g=ncW%tS`;*Jt3b)Vp z|NZ}+9Pg95?a%MLf8BWJeck!Ld2iqBi}kfp3pJg0Q#~}a){(Ixa`si0l$g+Td_fVuUkwbF4gnDcB^K5O4o5}> zr=h}?_-b?eN6Po}kEhO0;e7Yr{$1_AjQ4v%=`ip7&ij*rsqERD-?{I3AOCk`|NYqe z{I>6PJKH8dk$qEt;df2-``_Rc`)&V@cgkz-tetyzcW7xu==s}Ub6$N-43*`59IwW3 z-EXLb1ycMaUHP2zc>Dc&+qj>e3>B$&Z{6G*9oioHbx-X1WpVOhS0{1~v3N%E+mK0{ zRB*HFoRF)TyU(r4y0gx6ch;59%f7CvTD{6_byjxP`?&mV_4_v7+06W*%VOm!@zByM z>kgO6`o7h__IyuekZ%xYOxs%68qM%-hH)f z$~xi4tB$Ho**9a(6#XxZ_e5g(cYU3&Hs$3EpZeuRi&%cqXs@ awx5yFRv_-t(Z?G=b&jX2pUXO@geCxI_g^Uh diff --git a/doc/reference/clutter/glossary.xml b/doc/reference/clutter/glossary.xml deleted file mode 100644 index 5a71a8902..000000000 --- a/doc/reference/clutter/glossary.xml +++ /dev/null @@ -1,142 +0,0 @@ - - - - - Glossary - - - actor - - An item on the scenegraph. Every - actor has a parent, except the stage, and some actors can be containers. Every actor has a geometry and, when visible, it should paint its - contents. The base class for actors is #ClutterActor. - - - - - allocation - - The final size of an actor within its - parent. For example, an actor might have - a preferred minimum size of - 20×20 pixels and a natural - size of - 40×40 pixels, but its parent may decide to allocate 50×20 pixels for - it instead. - - minimum size - natural size - - - - - - child - - A container's child is an - actor contained inside it. - - - - - container - - An actor which can contain other - actors. If a container is meant to be extended using public API it should implement - the #ClutterContainer interface; otherwise it is a composite actor. A container - can let its children manage their geometry, like #ClutterGroup, or they can take care of - assigning one. - - - - - event - - Events are the way in which the Clutter backend informs Clutter about external - events like pointer motion, button clicks, key presses, etc. - - - - - geometry - - An actor's position and size. A - geometry can be expressed in actor-relative - untransformed coordinates; or in - stage-relative, transformed coordinates. - - - - - minimum size - - The minimum, useful size of an actor. - For instance, a button might have a minimum size of 20×20 millimeters on a - touch screen, to retain the ability for the user to press it. A container that manages the size of its children should always try to allocate at least their minimum size. - - natural size - allocation - - - - - - natural size - - The default size requested by an actor. - - minimum size - allocation - - - - - - parent - - An actor's parent is the - container inside which the actor - resides. - - - - - scenegraph - - The tree of all actors, starting - from the stage at the root and following - the containers. - - - - - stage - - The top-level container for - actors. Depending on the Clutter back end a - stage can be associated to a window or to a frame buffer; also depending on the back - end is the number of instantiatable stages. Stages in Clutter can be manipulated using - the #ClutterStage API. - - - - - transformation - - A rotation, scaling or traslation of an actor. Transformations are independent - of the actor's geometry. - - - - diff --git a/doc/reference/clutter/migrating-ClutterAnimation.xml b/doc/reference/clutter/migrating-ClutterAnimation.xml deleted file mode 100644 index 87b6ac1eb..000000000 --- a/doc/reference/clutter/migrating-ClutterAnimation.xml +++ /dev/null @@ -1,139 +0,0 @@ - - - - - - - Emmanuele - Bassi - -
- ebassi@gnome.org -
-
-
-
- - Migrating from ClutterAnimation - - The #ClutterAnimation class, along with the #ClutterActor wrappers - clutter_actor_animate(), clutter_actor_animate_with_timeline() and - clutter_actor_animate_with_alpha(), has been deprecated in Clutter 1.12, - and should not be used in newly written code. - - The direct replacement for a #ClutterAnimation is the - #ClutterPropertyTransition class, which allows the transition of a - single #GObject property from an initial value to a final value over a - user-defined time using a user-defined easing curve. - - The #ClutterPropertyTransition class inherits from #ClutterTransition, - which allows setting the transition interval, as well as the animatable - instance to be transitioned; and from #ClutterTimeline, which allows setting - the duration and easing curve of the transition. - - For instance, the following #ClutterAnimation set up: - - - - Can be replaced by #ClutterPropertyTransition: - - - - It is important to note that only #ClutterAnimatable implementations - can be used directly with #ClutterTransition. - - A #ClutterPropertyTransition can only animate a single property; if - more than one property transition is required, you can use the - #ClutterTransitionGroup class to group the transitions together. - -
- Migrating clutter_actor_animate() - - #ClutterActor animatable properties can use implicit transitions - through their setter functions. The duration and easing curve of the - animation is controlled by clutter_actor_set_easing_duration() and by - clutter_actor_set_easing_mode(), respectively; for instance, the - equivalent of the following clutter_actor_animate() call: - - - - Can be replaced by the following: - - - - The default easing duration for the 1.0 API series is set to 0, - which means no transition at all. - - It is possible to set the easing state of a #ClutterActor to its - default values by using clutter_actor_save_easing_state(), and return - to the previous values by calling clutter_actor_restore_easing_state() - instead. The easing state affects all the animatable properties that - are modified after changing it; so, for instance: - - - - The animation above will implicitly transition the opacity from - its current value to 255 in 500 milliseconds using the default easing - curve; at the same time, the size of the actor will be transitioned in - 500 milliseconds after a delay of 500 milliseconds to the new size - stored in the variables width and - height. - -
- -
diff --git a/doc/reference/clutter/migrating-ClutterBehaviour.xml b/doc/reference/clutter/migrating-ClutterBehaviour.xml deleted file mode 100644 index cc4c39ea0..000000000 --- a/doc/reference/clutter/migrating-ClutterBehaviour.xml +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - Emmanuele - Bassi - -
- ebassi@linux.intel.com -
-
-
-
- - Migrating from ClutterBehaviour - - The #ClutterBehaviour class and its sub-classes have been deprecated - since Clutter 1.6. The animation framework provided by #ClutterAnimation, - #ClutterAnimator and #ClutterState fully replaces all functionality from the - #ClutterBehaviour classes. - - Generally, animations using #ClutterBehaviour sub-classes can be - effectively re-implemented just by using #ClutterActor properties. - - Here is an example of an animation using a - #ClutterBehaviourOpacity instance: - - - - ClutterTimeline *timeline = clutter_timeline_new (250); - ClutterAlpha *alpha = clutter_alpha_new_full (timeline, CLUTTER_LINEAR); - ClutterBehaviour *behaviour = clutter_behaviour_opacity_new (alpha, 255, 0); - - clutter_behaviour_apply (behaviour, some_actor); - - clutter_timeline_start (timeline); - - - - The same effect can be achieved by using clutter_actor_animate() and - the #ClutterActor:opacity property: - - - - clutter_actor_set_opacity (some_actor, 255); - clutter_actor_animate (some_actor, CLUTTER_LINEAR, 250, - "opacity", 0, - NULL); - - - - #ClutterBehaviours used for continuous animations with looping - timelines can still be effectively replaced by looping animations; for - instance, the following example of a "pulsating" actor using - #ClutterBehaviourScale: - - - -static void -reverse_timeline (ClutterTimeline *timeline) -{ - ClutterTimelineDirection dir = clutter_timeline_get_direction (timeline); - - if (dir == CLUTTER_TIMELINE_FORWARD) - dir = CLUTTER_TIMELINE_BACKWARD; - else - dir = CLUTTER_TIMELINE_FORWARD; - - clutter_timeline_set_direction (timeline, dir); -} - - ClutterTimeline *timeline = clutter_timeline_new (500); - ClutterAlpha *alpha = clutter_alpha_new_full (timeline, CLUTTER_LINEAR); - ClutterBehaviour *behaviour; - - g_object_set (some_actor, "scale-gravity", CLUTTER_GRAVITY_CENTER, NULL); - behaviour = clutter_behaviour_scale_new (alpha, - 1.0, 2.0, - 1.0, 2.0); - clutter_behaviour_apply (behaviour, some_actor); - - g_signal_connect (timeline, - "completed", G_CALLBACK (reverse_timeline), - NULL); - - clutter_timeline_set_loop (timeline); - clutter_timeline_start (timeline); - - - - The same effect can be achieved using a #ClutterAnimation: - - - - ClutterAnimation *animation = - clutter_actor_animate (some_actor, CLUTTER_LINEAR, 500, - "scale-x", 2.0, - "scale-y", 2.0, - "fixed::scale-gravity", CLUTTER_GRAVITY_CENTER, - NULL); - - ClutterTimeline *timeline = clutter_animation_get_timeline (animation); - clutter_timeline_set_repeat_count (timeline, -1); - clutter_timeline_set_auto_reverse (timeline, TRUE); - - - - #ClutterBehaviour sub-classes can be applied to multiple actors, in - order to share the duration and the easing mode. It is possible to use the - same underlying #ClutterTimeline and #ClutterAlpha instances with - #ClutterAnimation to achieve the same effect. Complex animations, spanning - multiple actors, should use the #ClutterAnimator and #ClutterState classes - instead. - -
diff --git a/doc/reference/clutter/migrating-ClutterEffect.xml b/doc/reference/clutter/migrating-ClutterEffect.xml deleted file mode 100644 index 5b6f109ae..000000000 --- a/doc/reference/clutter/migrating-ClutterEffect.xml +++ /dev/null @@ -1,137 +0,0 @@ - - - - - - - Emmanuele - Bassi - -
- ebassi@linux.intel.com -
-
-
-
- - Migrating from ClutterEffect - - Since version 1.0, Clutter provides the #ClutterAnimation API - and the clutter_actor_animate() family of functions as replacements - for the ClutterEffectTemplate and - clutter_effect_* API for creating simple, one-off animations. - -
- Using <function>clutter_actor_animate()</function> - - Prior to Clutter 1.0, the way to create simple, one-off - animations involving a single actor was the ClutterEffect API. The - major downside of this API was that to abstract the duration and - easing function of the animation the application developer had to - create a ClutterEffectTemplate and keep it - around for the duration of the application. - - The clutter_actor_animate() function performs all of the - memory management that was delegated to the - ClutterEffectTemplate, freeing the developer - from having to deal with object bookkeeping. - - Another downside of the ClutterEffect API is that every - possible animation has its own function (scaling, opacity, rotation, - movement, etc.), and new functions cannot be added outside of - Clutter. - - - Effect example - The following code shows a simple animation using - the ClutterEffect API. It animates an actor linearly in 500 - milliseconds, by moving it to the (100, 100) coordinates - while fading it out. - - ClutterEffectTemplate *tmpl; - - tmpl = clutter_effect_template_new_for_duration (500, clutter_ramp_inc_func); - clutter_effect_move (tmpl, actor, 100, 100, NULL, NULL); - clutter_effect_fade (tmpl, actor, 0, NULL, NULL); - - g_object_unref (tmpl); - - - - The clutter_actor_animate() function will implicitely - create a #ClutterAnimation with the passed duration and easing - mode, and will bind all the passed properties. All readable and - writable properties specified by a #ClutterActor are animatable - through clutter_actor_animate(). - - - Animation example - The following code shows the clutter_actor_animate() call - equivalent to the previous ClutterEffect example. - - clutter_actor_animate (actor, CLUTTER_LINEAR, 500, - "x", 100.0, - "y", 100.0, - "opacity", 0, - NULL); - - - - The ClutterEffect API provided a way to be notified of the - effect completion. Since the clutter_actor_animate() function creates - a #ClutterAnimation instance it's possible to use the - #ClutterAnimation::completed signal for the same notification. - - - Effect complete example - The following code shows how to receive notification of the - completion of the animation. - -static void -on_fade_complete (ClutterActor *actor, - gpointer data) -{ - clutter_actor_hide (actor); -} - - ClutterEffectTemplate *tmpl; - - tmpl = clutter_effect_template_new_for_duration (500, clutter_ramp_inc_func); - clutter_effect_fade (tmpl, actor, 0, on_fade_complete, NULL); - - g_object_unref (tmpl); - - - - The clutter_actor_animate() function also has a convenience - wrapper that allows to inline the signal connection: - - - Animation completed example - The following code shows how to get the same notification - as the example above. - - ClutterAnimation *animation; - - animation = clutter_actor_animate (actor, CLUTTER_LINEAR, 500, - "opacity", 0, - NULL); - g_signal_connect_swapped (animation, - "completed", G_CALLBACK (clutter_actor_hide), - actor); - - /* OR */ - - clutter_actor_animate (actor, CLUTTER_LINEAR, 500, - "opacity", 0, - "signal-swapped::completed", clutter_actor_hide, actor, - NULL); - - - -
- -
diff --git a/doc/reference/clutter/migrating-ClutterPath.xml b/doc/reference/clutter/migrating-ClutterPath.xml deleted file mode 100644 index 4273fa3b6..000000000 --- a/doc/reference/clutter/migrating-ClutterPath.xml +++ /dev/null @@ -1,167 +0,0 @@ - - - - - - - Emmanuele - Bassi - -
- ebassi@linux.intel.com -
-
-
-
- - Migrating to ClutterPath - - Between Clutter 0.8 and Clutter 1.0 the #ClutterBehaviourPath - behaviour lost all the path manipulation functions and the - ClutterBehaviourBspline class was entirely - deprecated. - - The class that replaced the path description and manipulation - functionality is called #ClutterPath. A #ClutterPath allows - describing a path using a sequence of #ClutterPathNodes or - using a subset of the SVG path description syntax. A Path instance - also allows describing complex paths, with linear and Bezier segments - and with gaps. - - Finally, #ClutterPath also provides integration with Cairo, - by being able to add paths described by the Cairo - cairo_path_t data structure and being able - to "replay" a #ClutterPath onto a cairo_t - Cairo context. - -
- Creating a #ClutterPath - - Before Clutter 1.0, all the path-related functions inside - #ClutterBehaviourPath and ClutterBehaviourBspline - were replicated, but were also subtly different given the different nature - of the types of path handled by the two #ClutterBehaviours. - - - ClutterBehaviourPath example - The following code shows how a #ClutterBehaviourPath was - created prior to the introduction of #ClutterPath. The path described - is a square box between 100, 100 and 200, 200. - - ClutterBehaviour *behaviour; - ClutterKnot knots[] = { - { 100, 100 }, - { 200, 100 }, - { 200, 200 }, - { 100, 200 }, - { 100, 100 } - }; - - behaviour = clutter_behaviour_path_new (alpha, knots, G_N_ELEMENTS (knots)); - - - - The construction for a B-Spline path behaviour was similar, though - the #ClutterKnots could only describe a curvilinear path. - - - Constructing ClutterPath - The following code shows how to construct a #ClutterPath and - assign it to a #ClutterBehaviourPath. The created path is the same as - the example above. - - ClutterBehaviour *behaviour; - ClutterPath *path; - - path = clutter_path_new (); - clutter_path_add_move_to (path, 100, 100); - clutter_path_add_line_to (path, 200, 100); - clutter_path_add_line_to (path, 200, 200); - clutter_path_add_line_to (path, 100, 200); - clutter_path_add_close (path); - - behaviour = clutter_behaviour_path_new (alpha, path); - - - - A #ClutterPath object can be shared across behaviours, just - like the #ClutterAlpha objects can. - - Path can be described by using a subset of the SVG notation for - paths as well as using #ClutterPathNode structures. - - - Describing ClutterPath - The SVG path notation subset used by #ClutterPath is in - string format and can be both set as the whole path description - using clutter_path_set_description() or can be added to an - existing #ClutterPath using clutter_path_add_string(). The following - example shows the same path as the two examples above. - - ClutterPath *path = clutter_path_new (); - - clutter_path_set_description (path, - "M 100,100 " /* move to */ - "L 200,100 " /* line to */ - "L 200,200 " - "L 100,200 " - "z" /* close */); - - - - A #ClutterPath can describe not only linear, closed paths; it - can also describe paths with Beziér curvers and can add gaps. - - - Describing a mixed ClutterPath - A mixed #ClutterPath, with a Beziér curve between the point - at 200, 200 and 100, 100 and both control points in 100, 200. - - ClutterPath *path = clutter_path_new (); - - clutter_path_set_description (path, - "M 100,100 " - "L 200,100 " - "L 200,200 " - "C 100,200 100,200 100,100"); - - - -
- -
- Iterating over a #ClutterPath - - It is possible to iterate over all the #ClutterPathNodes - inside a #ClutterPath by using clutter_path_get_nodes(), which will return - a #GSList of #ClutterPathNodes; or by using clutter_path_foreach() - with a function. - - The function pointer passed to clutter_path_foreach() should have the - following definition: - - - static void - foreach_node (ClutterPathNode *path_node, - gpointer user_data) - { - } - -
- -
- Integration with Cairo - - A #ClutterPath can use a previously defined - cairo_path_t to add new nodes, by using - the clutter_path_add_cairo_path() function. - - It is also possible to paint a #ClutterPath on a Cairo context, - by moving the Cairo pen across the nodes of the path using the - clutter_path_to_cairo_path() function. -
- -
diff --git a/doc/reference/clutter/offscreen-redirect.png b/doc/reference/clutter/offscreen-redirect.png deleted file mode 100644 index ff36c808275bdcb5c98e359b40e1c6127bb2e7a4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4821 zcmbtYcT`i^yN#ltsGumIw5S7EXoGYZ0qGIJp@h&8G4zBMYJdoes0fUpL_j(iktR|? zM-&J}x)4YNr3MH^N+LD9!|%O6URiJ6to2q_%00RFp7VX*{`TJIKKavF{{*K1Cj2>wurBz80joTWAg(u-`S**MaQqzcT9yiD2ZYw}F)( z1aj>3{`&wV<@H%G$bo?w>2grn*m&3#Sbov%VCWo1*Ak=cg+d|G7>Kqn(h-BacRtV! z<9c2nX7nc_f{Pyl;rSh=bHhA{vN($KJ~J&$TIqT8mnM&afe!2nB3x9|LQ5+`d=_#+ zH}{72g^A2pu9)8ZXHPL&E}mJp@^kL!7R-Kh<&>XBTroeX$2N37?ufu&H+fx8Uu2y( zzZju)#Mz)>Hz)BpZBz_D#q)cegPdC8!s4R(_O~UMj8QCeNLKDNcg6vnwnc$&iX%&iAfY4#qI4TyKXibOiP;|tH;L7EEoLI ziI+hH1XQw^#KtQM3h?RaY0ruS-ZNj$Nm;(vY;SLW`uOpmIyw&%5)&Dz-*@x~w=>YI zkkGjZI)}za#Oms*xrN1yY#1E=vLTOieAmB!>20T|uJu^j!)W^pC$B&BRw4Mw^XlPw=J<~djF^CYh z$S88_l`q`OJJ=9D1T*-Mn=5+k#EFWPNfNeB-K}4At+FP;vp*Ns)!kTJ+`Yx1yU5DQ zGP{(%2c^v{)h;W-m`xne@*q~1(H_O4Bw4hxr$?#0>rzJOU1@x0O~9hNii!%e-%w`c z1F~}=9lKOoY*(AoIsM_b`erlTB{3o4Zd6p1g{7tI;lqa&J%%K~@>6y7^{J&!q;GF< z<5B##5~8A`v7_RGLMpz^6B84XmoK-yxs`m^FiEmBGV-8Jm3P)CX23|iJw0gRXbIIo z+e%uv!LIvJ)0c%Y?6LyP!rXkyBu-x>xLI_hHC9lqP+cr}Qn}LWd&B*OvIyHoW8Sz# zaib3^elxE`v6Hb%2L!NEa3DAdcu#01Sz$}T1*#>dNxTv=JMu(MkvyOjA%>LuRuqjmcWW`IDoA001s z*qukrD963T^aQOPeqo)_9+7m^zk;pu1 zxqiHe0?9{GPHw-8^*MfkdTlg`FOH+Hq|@J+y~z&LN#~8c0n@a!4xtwJzu_b zr>VKHad4G4gl${H;qYj(OQxWFgmt4aKgehdpVaE`kCb<=4%$IMRiyQE=gtk~8S<-z z?^IDY%FE@C9X+~oq%Ns@kLnn*v*EK}3CSy0+G{X#cd^Wc3*(eKUtY=bojNtX)^DIa z3?M-rE_K?aT+!H?{VnkxxBAAN$*O3PkTw+dtP=WlwXHOfEkHXsWPR4LqM|~W53Hcf zx$7FN5=E_SZEO@a7KZNwAJe?$-{D=DpI;ijyOj)Jd5m9L-li`5#hjZeKVWeoc*B1si|HKu$l@J45mC*K;hlUTz`MRq`3H- z5jOHrk&TqBY+qz#KiLNJNsK@^rOWYD*4ln)a}gAr8PB_eMqaSQiMo8$Cz=2 zJwuAFs&{u)k;*B_MYh%bq9YS6F>C={EBz-lE?mg+u?-Jz=!yAQR6R3%@(q>fMT8ev zDA>QiO+D8)AS!ZlaaBG!eMwPmREqfRZc|fJxNy}LV60R{l>4wgJqAkxtW$BGkW5lZd1qP%XM#c%v36)0wJ&KIdpiVa`??_bkc+;&>+GSWmgXm? zUp{}Hm1l_GU+J;oP~3VB^op36E}dLLj*)4&O!9ew$CHcc*X}kS84aMKu3ov4#TaHc zBNz`>`_amsy96=@3hnEy0rRA&`n$)_8t=AnCMVm6Zz55{@0*+q3=DdqdmE(Ixw5h{ zf98T!kqvR_T}cnqv$y=FOa07nW^Qh?5Xr4heQGgmO!bT6aU>FHk0EJ=X3}0iuMD;pf@woug@Ln$Y9MCu#X3 zAV*VMqiJ^56}z|ltG>a7Tx@rMP8%Nbm=HF}0Ikj^Am9#z!BDL9Oes2f4)?)xV z;KHkJVZsQgF<5jaP>4D^45Gag6CLWaMFtx z_rRU``1qXnc|Uk{4H(QA*Ce;fNai2a^p?aa|0f)`Kd%0;ExUr(c%=LlW)VC%% zlGm>FM?QG42;{Wl%a>a=M0A?XUZX_*^sqex_=-Tq;7an>KTS+d{l%EXe?0KReOrqi zVjV*gh5YoMXnx{Mm>VG6CKR&)_ZGzd0Loo8x6pT^^VEHgt^R)BLy(dUaJn=?**N_V zD^M9JkN&M7<7T9rJx8V_(9}K<8ZQseMPM}UG(}1jf8*ul1)+JZs;EH5&z^5-X`y^T z#_&no&MJm?r6>sVoJ2%2=wv#7<3<$E>C+XVo4&k!e3kPJqnfVo#+;m-7`@uub1Nh$ zd2@|6qUP=Iv8;Bge_#ML)%ILuGHlnvCKJ0vq=ivg9qsM1Fe%p2E#~DwKSub%u$B?bcG+y7?6zpAV=n-42P#rpVmxt&I6y8o?eXXOzQImTZl#E z=SL?Jax+-#1QGHlK=?x&fuDbLaX>>eWu00tOG@4eX&`M#X!5XO8SNbB~(ar*KqfEb|m`eHhcwFd1< zmecRfFu#{Zi0z==sH9hU4bLfP+%?oia#NVzH&!)iV7; zw-<@Lr%&hHc)(sAD*wmUmIFyI6_YkL`iMi*NYS?2+6yDBcO z7q7nMI*9?2mh!t}By*8U01|#xMa2qK$+`xU55&jZ)HM458@oKUM(}z_IdFuG*_?Pl zQ^vZwx*|$v|V}NvOTaLvqi+Qeh>uP8vUYF;jc#y z+auL}goK2IVZ)CKB+Z!E*ou92v3FRbrQ}R1qZ@q!0msBVdsaR*b&u$V+uQ!0I;qU; zR$H!$m64DrLyy*2q0#6vu7Szv6Q#>Jr-+lh&Z3cgcqt$V*+yeRKE z{QEB5Vb3=e4dA#hTmXe|E2|OZ^@R~LfP}RI;@(VG>LAg}0qNpW8{1eOCD1kv+ry#t zKD#Zp#P9=g$m{6187rt{oUjh8m|YT^^Q~LYMCS@h8nPK+6GVM5sf?=GTg86gPA66U z{OLXT^=r`U^r5d`-v%y^jmZ>lt$5;BSAAneu2Y z6?6p>Fy8ZD^UZ+tGD1QmVYKcvk2PQCFR!vdJLG3(ex%d!>X(M`U}a&O(|AgiPYyN6 ztEcxwGnfQNUo7&UrH`CFdi3bl&(GYW^PWKaw@4bS@j$yxvt>ZuFGceRgtF-SNlw_d z?(U(w;I;KFdI^0z8XAB_H9tOO-56f)+>>6Eu`_iE?9Kp{c@6r`d`Zs9&c4|7TEz^Y zxTCG@PgmEs9i5$kpmTvQpP$A%pnXMv(H=}u@OY7$T9A;y1DMJUkhh2f>yUeJf;@^M z5B!vAa&mGgwrHfOm8R&1&D-pD?|7bq$ar3K%dxK|v2-*O-8KzKeu! zII4whm6MS}gM%ZWVLWP=YUqVP2Lga8rleoTT7P{>s1BhqZ)83Yc@MX>EqwOuc>VTL zZOuxnpo)Oq`0Cmk+|u%Gj(&XQMqjR`OaBFp05zbWX=;JS`yHCUB4Mek8wH$aIcClj sxEPZQ=Y{gwA>JgJ2)6y_46IFP@nfjyskFiU2T>51uCY$B)}6?I19$jXc>n+a diff --git a/doc/reference/clutter/path-alpha-func.png b/doc/reference/clutter/path-alpha-func.png deleted file mode 100644 index ede962aa9beadfea77ce1d5d6fd8623bb9355eb5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41123 zcmYg&2RN1Q|G!ZrM}+LG5R!H5nZ4H`A!Ki|M?$i9_6i}SvUm18wm8{)XC7Pj|33Bo z{H}jpuAFn8b3ga}-tX7z{S>CIDu;KM;w~B*8lHl@Gz<+5V;B6;-@yX!B=f7>2LGVD zz~m&+iU+ASzzZxBB{^xd8`R%VjRo=G9UMn_T^BSo+%VJ+I)6`J5qJ~ZRY64tdjjJQ z1d6-vaJLK%jTTKoT0+ZnYI{~US^veGxw9KFmwwa1FlERs973})9kT&*g=)5X1|{1n zpN*FnM6NaBGWf6Zyq^}%I`kze7W=blmvz%eprM;|dxeKa3NH26bI{+HCPc$2MKiLpcV@*<{d|$<9X(r2W=y4)S7_q51~Jwv$9Mw?B=67#61-Ai8O3nGv~8(x zna7-dCdZQKyR*~GREkObP8|C>YV7>g@x@i5_P0(?5epG&qTuXHl7HX)LlM3Fp~tM- zjQf`j@7%LP za*Vk9yw9mY+CYAPDK6N&5e`s2%tB_t&@FU|gQ>rk-+OpF;Nh zc+&^`j!*q=PB#&1;*1J}X*HBeC~Jqx(H_Tc746eAbS?= z+LYjy-*qcC&6g)Hish|H|K4bcMIkN_yxv2-PkZN@>Q9Uu`IV<5w(sYvYqjx`S2c6q zNYM?FM}PIvp-BSgLN=aKqduq{yTSQ0Tn5fRh<-D7dUcj{wQc#Qi6fWk-?cb)!=_i{r3yb?!Rx``R|v|5DU>lVQoc~o2yUm@%Szo z9IueLY1p$X-*!(mvc|_nYhF7~hcw=lco)YU9Lo7T{HK0F{9Q$suT^&wZEok$MiWt7 z;9&(UijLPi?u#f&5X)}cAqj(rMNciKNn8#q%*sBG|i_$=2SXwbd)#F`d5603k#V87G75` zOUf!6LSf;Ykh7f<@rK8>mKEep7gtClGOPjF2-#e>`Gw4(b#PsB;pjIw`?wwv7TthF zg!tRHiP{xGV`*n+x^r*VRj8(oeS89DGp;u5o$J_==RFfA>&S!K=|VzwOj~C;i7khU z_PWxO%XSq0G`St}%{s(z-f2FmdSUx~?#+b?_zK#^1)lHKw|QmE8g62a#<%|ba}ANk z%3l+zYuqQMW&}xQ48|7^C`-!UxZi%q9RBCGM-~{%9gxw!>)3+1elqNuH7_~0?~P6 zYgwxExLXhPz>J(m|0lmoqZ}>Pvhp7ycsm~VsMrv1zl>+~nL9nSJijq1~Fqay8dQ1o+q6JJ@mk##dJ?E9F$H(re|!8+;|u7ZgES zYM*}9h$(h3Ld7yT4wSHN1gQPh-8}j89)kzU#jdC&wk)(@(g)=Bv*9gORpQI1O4X9!`)*yu4 zON}N;EQdW$0<-UCB3(>s#kkAu8hCY3H*}i(|ksCYyU;gz5U#Nk4fzBh|Wy3opQ?NU};h zTTC-oOtX{oF-P634UPAAo2s_S!*9%aR#ZH-J}wW@h7KK(X}o>}aJTMt7qkwi{;{=_ zBec%yr`m(;6}3ES7o}1)hzu;`u%qjEEwka9Gm*|EGf0V_yQ!W@LXW5CZsU-tw@Zks zx3gcLWzwHP;nyZ)SRqAxC}Sj_bG!K$NG6XbY-air3D?=bV>kjowDeAPS=Zj%vG_xbj-W?c$vigI0sqC&}z_0~R>#p+m*`?bXdGv+RlCK)|ma&HxLXxSp^C zyM#XJ`(^W7ag~sx`G8O%?qG7%_U(o6JO+p|1hdb_U$G|(cr3D^6|K=xZl(X)^GN9BZ4j=w%QIh{+(B>#PU{`O$MfU5f5>chXDMb~LVqI-Nevb5Aec;c1~Pc{nWZsLFIf z;H2_iBVuD1iBEPfIH8ZR>3D5x1=q{L*Eij;CdNezTbvAn6QdXi0>Sp#^YBi3W3sZk zGMQ%n6n6Pz?p;jF>s*1%q-m=nYd*d0*-;g_zj;L7QI4hapqEg|l7tH)Q-jDw?82B= za009-T5y9zfN=C|LEIS}hFp5`_%5_5jJq+D;G%uD4mT!aZl_hzJa0t5@W$3}bdHkn zb0q$ygb2#wFP=B^v3Gg%s!l%|d9`N`Y5z1&qbxk(nb}AA+OVrq`Lb-NRf1^Tt@L3! zEo4t5#-`|?%Jf5@n$14C-T+DNaEfYyQkj;SgK<*(7+uz@W(l#Z8xswO5;bDkc$vn- zitisq1FR{IynWK5NP;9Ye=|?a>*{<RA)iFT-rANY< z<_|rdA4TiA4UTjRwg1G6UktAdBK3ahvOOrc86-W>sg_C0j||Q=J>K-_TXjaHo`FDA z?E40lB-!B~9 zUek0XB&4Dd%#}gTL4pg%IJ|oAU3k>_{Vi}WkT1QjHY7*Wv*z=CCXCO%sH}ai_LGle zs4Z>>u8OF@J(G+UKdYd@j2F78hY#=!Y%Go06!lKed*j00exG7T%9(B+Qv{i0u0kVR zg$?2uVm<0mak3+Vdgk#C&3ekq6ig;c7Dfebyl%a%4K~M(FZJQpzGVwM(WaGanbbS& zi=i#}%=6E4%9}kL*+TtNt;rC3AM;seRgn`z$iPDdN2IF7wbE^E?V$yMd)9G;!E|@k zgVFDfXql23O~P-&1UP#gOn_{>b*z9$(5_Hf{-n^%Z)9(eS;U*?jFSh! z@DtfN;fC_JA7~V+63Z~`8e36W(-93vnxhcJ?SlGx?@IjX4kt-q ze-xMcSa~g{m|e?U!N!hf$1lnrrVE6h4S3T~c^4_NTpzu<4Ad8sYvL4K=rQBg_q`%K z#I3L@symrnpJ}R6jbpI0-`)c^`J&a^&(S};b&@ysx1d{+!QZvi2Kg8YH0&^|Z~EHf zM#nmMS%8P~sa;=NH5&xc;`UG(A)-C*Fjv(Yi^N74C_>3&_N|nO;YV+-O5U=cNoF!b z!rFSG^EQ&Flq_6yyK=dF2{^a$dsfT8f6t_YVB|0_Eyr9x+sm8PP+BEXYL_8a7Vety zAh5?pq&4IRTy?oZmY6LFI^mfCs=Uj?DTXz0M@|#-<9=7j_!!^B+?1&M&+LRHqvqBI zW24kDjpnoGYou#?SMRE(w?GmbwI&}LRTDQgcB1a%*3}hl-$~!PB|(dH{ae0UepEzg zHDB!3U+&Cb?>w5X71I>9(YO;*)b9PGUD+Zh0&#xY*yzL7mjh#=!QJwRSWZ!`mm-s8 zV;jg#`4zxVSyb|Ue9)o-L4LmIC=c?tc6?K*K#VaN$YaJ^1bx+o+K(et186@@TFtJD zK@*C@@1VXLYTkviB2Na?#dR+0I);W8US6pd6)ep%bgJ3%>8?3c>Aq3! z2{O5Rk)dA^tC8dMug|#UQGw%-dIqVkNK%XAG{rFW32YEwY5TUhiM>%_LinuZ@Q!*F zc8X%}45|YoWd&V`YO=;s`2#Jh;M-k2W<;fNye7l8nibfd!FE`vc2C}sRPy7UDEcuh zZ;4dAX4MaRR(R2|rD@ijTStyjWI;)-gy62Ic1HDm))bYj7vB|YfB>cyw}tfVZdsgl z52POD`JlUTiZikQ8Rl$<{or1%NElyfRG?r%-$z8ASrli&zkVDg)yI;#zdNa?eG}W6 zW3r~m6v0;5yh60L>8cgYKA{R>&=!Tp-`zI00kWFJ?+q*r!#GG9`a1sE0>3nhY~zsO zzfG$f(LClG_|lT}$~>W#OfepcX^}zwB$X+t(jBGLzgt%Qta7i79-PeKBi$$#`6IKj z9jUZWVE^KfNfbT*g^{TX+_T=ZYxuaB<`hFo%XA9bZ|2tEH79~%#Q0LJyq>PXAd2hLQ_xou& z%V09@K2$05S67kJl&;H=t!1GM0lBYuY`l~Eu8fG!M(5?r|F@Gkf1eMY+gRrA0o*+r zM$Hw=)&tbt|DT?)%HX~_OSEjT%cQf>lDXxD1vIogVp4Yfg$$3Tb`IZt zrRwTxL2viO@mGEsXJ>WRj?K=iP_fHBskiffU*NqK&`T8BV$GNS7N8!tBm}N>>-5)3 zt~U$b9`w-Ex^3~jZrB$hV684p}?2EJiy-!;3qV#Z_np^FN7gj znAJ5NXen8*Kpi#bcf)^qx!w#CXokn!*}eITIS;PLkcg@#8pq`>Ja&UOK^2xm*$Ei5 z@%w))Z?@sm8XZM1YgkBde{J!C<$H$wu5o=&>+zioVzNLM;(}_5$2!H40|`1&$Z!mn zk|tOM%3S{H(qiHD?rxYi?%L>!E&%qZTIJh3BuC@ZaoT(%I+!8c2UhjEI_{gO9=Jf> zxC_-^fgp!Ie;T&jbN=0SyjYWsM908j(WCj|L#xqVRZL<&OU>(&vWA9!VPwO=$q8TX zaOev|ub`ly+t-JF*M8*pLO_5Pzib~Oi;_i5@9ysIBd=$h&ArYb*w}a|GY%oOjz8Xq zU>n~TFH_K1>3{d2L}p-Pnc}`;Fv>VslEEDuW=%jmqq$tTKx?=>knz2k#4^Uji!RINSA@U)&rW@?4G@uXA2y6&9{XyVcs5PEb8< zpMc>e`KlPk`ltgcn|lYA{qh2CN^&{hGcqBQj=7R0V z!-FIa-fh%fXOVTxU8k6ps@7F{fyRGYwn!pmd@q-27B8;LoYUm?&(`@pk4Kf**x3&@ z3bIDFj*&DePa`5oUo9PvzgoUJ^=qG-YXUCRam6_GiD*4~a{{+xszZy#MKy-8M5Twq zxED(ibsyt=>w_uV5*X`)I$-g@+B>GEgrd3{t5!e(j}kfY-P^wV5wCtCPn(BLZHgvm zXA87g5nIQ*-VfV31-wt#=C5`=>fCpP{Qk5TJm!-{$(4m)l}e0ez{Rb!+fbc;m`TRA z-}cPjuxAHWg-tjGBACb_3CS8TwDGf*cr{OC(*7*O#&OrKXJ?aI8B>O{Iktf=uPY`|B?!bd-Su+(zk zLq#f9g{oTHk3U^h@NB&z7#m5?`XT7j-90?WAy|*kgBSumogUo1-E=XF9I@d&`?D<0 zNfGsD=e1v7*7ZhKX?=ZPmF+k>fSNB?9*dh;TgUoc!u?E4O)*oB-ZpEp<|fc5_hnZB zd|JHJ;%W;NlS@nVH*52kj4w)jyGs17#3Tr)yxD+lH!O4&x@f@-^J&!HOs=V9krxcT zpJuWR=9XWIxx2GIm|^PVXiNrr za}fQgH`z=I5Eiz!>70<=v-$};zP$#Bl9CdluWIbGHEXLuC}}L#xl^!Pv#N0K{d|(U zDg)G@mVi}umHWqe+O_%^8>1t5X#O15)d`|G%r$t;Q+EOEt5!y%o5Syn9RMXnl`o4( zZjRJ$0(ewFqXHZf1#-{1&{(Gt-iogXie5IFzE|^lo+&)1#OJcAiWj7ey{l!vLy9OY z@r%iu+Sh)6n1xa+=0UL`Ko`bGR&WngQnR0wzdp!UES!+ihN{?{Jkt{nhxc+q^vAEJ zw%FL%00s%b?BrD7eDOD8$|KfZ{mIrvF+2L_oOy47yUlqwTbP<2W>bqp9<}Ywy`zEe z7rs1w1ddyvjM?6i>!bx2Q`Cp#vFJXs_(&aLh%MKHA+c}v{-XWs_!fgg8$i83uNmCg zSKe?Hauv#0Kd4f0Bwb<&uk0~Yx8PtNRuh5QFOc6?GE670mm9ommSiBp6<^fqO&rk~ z^5eR{A7Y)RH~{J_Pyj4-#@fgT4_1g34@W=|C((xvA*0Ii-|s7W%k68uzc@b^0`$Wa z=GF|-f~>1@?P{#(CHEmH9)LJJeLJU&2)w^vKzZ6lD1vfL{?$v2wrtStr9vSQ5i=j3 zjKstTY+GB+7`wk3UM6({*q^Zhq(oF^=P1-ZB8mwp?J!hll7Fh42rHNEuYYKf!JgD# z8WAs$5@`xl!3hZf<|p#2Us$=O4#cmZ2B)!VJPeR7X&Jy0RTCq}H zIO)S}5gKPq_?S67XTu@Dawya1_w>NvU`|z18qkJmfxnX(K|%QU3=?u^KE3z#1ZwKv zRnm<8-J1Duwx?QPI8Wy2lng0f$dD;s6NDj%=Eldz3!uo;EzL`F7&x~lVOz(-vS>_W zQy3PN=HbrmtjV`*Luq?`c90?c@$lR6o zT?uYf2k(bd($%L9Lmhg- zG~<#fDUw;f2j0vXCLPfGbNu}L8j1=)e@lgq2FU<6v*IyXr_C8|u2GR9ptL)+TRY^+ zr!!>&<|N)myFYRAq%sF%xdZEy9iHyd)UR#2;`=?cVV1$afF?4r+Bs8FQ;mInGr>Y2 z0=;nO3q^S2n(z>Ggfl-+fg#z!GIDtu9aBd9%oSY4MEPT%NrplN)BhIqk(~d(#lHdLM{3`7;hS>iv@Kb742&WipareJm{#xVguhmh}6QfL%27Ju?>>dUOY4 zY$ zyLKyntB_>svBvrn4&?#*Pmx9Y#S5Bq_YqcDC~2}W*^09ufDfFgOsC_IUwM0bZzGXJ zGWcT93>R1v?>aORGD1wH6z}o5E&#X*HGL^|Vdr`6psxn6O2&0{b?Jb_%gS22y09)TE-Lk +-5LRAqRv@YiS<<=b zP__{Q+0O0ACMN+MX{08$l=Xo{%lB#XPFn?Ax&5|ak0Rc_zP=d!L*Jb#-uJX0{E3$Y zAzOO3m18T1UZ75tV~Wq7M?xv0e(I@V)_+)F?^worJY^!zTuzhpTUHlFtP3?8+~D4F z?Rn`Bnj;QZ&-s~|TSn&QtJxNF5;k)|o`#s-g<3hV!Vmc@AngI1MUh3XDCzAS${@@> z>p79FPU5isUlRp-RuB2PBl9GKJG78?>u=qOiHRXi8Ni13?S?7N{UxSrI1?vz#w&k+YYG=JrXNs1fLP%%Vye zN^zZ(iDkYQ6{+-DQ0Gra{#`lfWGIb&JpG$H`mWIDgypvBB8b*u>l%paF5VP_e|htFYZr9o15WiW-fuSPX7(0ZFE1 zgPsbXe6HDg;NtR9WO{m8NKgaKA~SRk|?o>Vp4f0UU+RqMq@o6E58kGVVSY z;cvT^JoOH*OMT`Z!c!f7(gzB71sj*v)^-DA!m5yo|I|ai`DiqyOw(DF^{?<^Ugh9n zg~3(TEyhbe5!gQkr=9{J(iDBIM)`O`eN~Ow9m&{=Db3k_FUg> zQL0Bt5`;@!y%rU~NaFfdsW;C-IRHNpBwk_w1E#_^kn<8F0M%UC<^=|x3PK`{U- zt{PGvN`rJmBO_)N(ezUNa3|%|y*Oa`ri8Zf8K3&2Ul}L-_^h``#$^e`+jP&0B<}$g zwunWw{oz3$hh~ws2ENxl9|5WnhZ^&}KmqhTSlHqE(6Rukm=nnSRdmrLZa=DbwD6oi zwK~96xzING@7nn!AsU%@&0Vyqm8H&+DY`ZAuj6frE$kgcu>%$~f|ZXI+Pb=e`+-`B zQ}V;sy}*@Vfp`Hb@!DEm^Tw;ze9useT#uU&-Y z?s#aSpbtqSAIRMP2BD7`vW8q1+k)io?r0E~H8u_`E@neM5vb8saIpKJq4Fn`$U zr$Y_kK0rg*gNCX-Hsm#qmLLEak=3D*%jnbRwVa zV{01`6@@ohDiiv+quQRWukF+aH2+ycpuMWEuixI;>FKgW?ePb_y|cH7)FU=R20oVX zj~f+n)*2PqwX%T;i#Ypc0j*C;8V&bQt7TiDCz-_eiH(=8aHi_QRE{pKhFek(Zm z*}qLltIScz+DsE|;oBA65m45DTSO^kwp`f8$GodxQClWBP3(PcikF?U#@lMW#Yp{-J= z@|Of1HMpa;^ZBt?@_g0Nocc(8c zp@ld?1}gwPLp5aBssoetkHC0r8yZ z#``37yqTicbm};QP@`e{iUs%GdI`-Zy@wk{##N$ST@l*8ln^D(g7E(;YgtEH&UrI~wogpYr=i=y7bQk-Z1Zc2$$s2xcdQne2O zt-?og^=i3OeLoI1HGHy@_Xj=!7Y{S<4@XsiD?Xmd)E7A|{fw&cl(0POj!3k%Q8vuqGc2(-i6XAD5KCDBjPcuMd6QNXR zZ;>%qrXsMZnl-8%F#Cz^_0oEOM%u~ikpdrkdzD_(z(4s}jo8;_iEwsKfqKrFjr=AJ)w{HD+zRAo zH%uveUSN%di?(QUWe5n1x)9`%WC(;560)8wWM{o-Js4KD*`^8cDu^)c06G4$!*}8M zhendbHpt1TF5aix9}CbltpQ?x`_L;M44Q1@B~#a_{m-1g`0MGcI_iB zT8AZvBJZnOE>*~O8*96JK|X>N z24?JVMM^qUZ`VtD_dbE5-+s|+4BEB*1Z$=U&T;thhFxVgk6XbIFnFt|tSKx-nv{dMqNz?Tky#E)$(%@mA@j*t}cb&GwX zk{9s5(o>%%jvOn@z(*-6cP=HSdDp0qomJhe_fAfuzcuCSQqQ)Fr5 zWQgxkXHV8p90tBPKiv+y|HK?kcjhTWZA8JtaDR#I;X4uA!RB3I0ogFcu@s>0_v2z^ zVhgVyj5$W8fR0nv3x%_Ji?rv>3|3y66L@y#tR%+g!w4}JT%`8c?w-Va*FA7V@p)$g!c+Gdd-0OUBk5f2R@N;em$E+qmWdB8+^Qgwg50j%hECwW(xRQOWG z;!9ugnzifLSoyL0XuJ~cBvNFZ{E4n(9101ToYVyX)H`!sDr)MSDp^~V z0z@o2A+U-bg(?Z)85`q(Ln=d&H96D9j0k$$K(!*x{&rYP&bYBS8zTHbYln^kU}WKA zp)QkMq7{P@Hcs9=QcqYpk?u~TjTIw;Pd-^ikukB~wpE_Ht2(+>JnaMWjkZ>8L4o%q zb!^Ssdu@c~wytWz-91xioet_rgWN;Ra3{~z#23_c`Jg0HvH?Q;bXmf zVb^8P0S!@};>y9MqUhZpI^xr7WK`~0X%^L!a=+dy$rpAF_5`6u(DH(ksN;rHw(eslS&`XWNbBsO&) zYUVs0ef^Gd>Rq)PkbIAi-B7!WEPlOLp8*NTT`)X=&FPWROyBC^QAtWp7IayI~sfq@uWnvvTI1%I!>T& z!H|uFW*5!CW~vkS3u(%w^CP7p{`_P-sQ}uZ{q+*7HCFN;v+Pb(M8S06_!bpCySv5x z#ke@TORn;j5|0PVX%YZ^%`nv>HucOJ(9&hH1;v{EhgR(+6{|0r4}`?o{MfP8m;5Wo zAR$sBLl?bU3R&*^Ia8Zc2*T8QJW1S)^z|ryl0QcXHQ;oXmX;x4Mwx|<2pnSrfU4D3 ztVMujo?!lDg0Cy`)zrhxC9}X{*j}@`=?A>tE{UOO(1`Ps_BYYJb&v7N$6?=%2{@88 zKFjaMx9930$O8e;gFv1ZV7ECNJpu8Zs6a!yum^O#eI-QsOy|tRnSE58%SUBVD_VA+ zj_6tROvA@?uq59e4ponVwn&4Gq~K+dpJ1huO1)?7DitSQXfyGgiWEY4W_haWnHVL? z6hylUrJnSI(}K8rS7i*6>huOkn>+VO2h@R+Y;V#s%V~E;5KM;!8-GeL5uvWAs_JZQ z_3x(-CyldCyZjU770kNOHArg7|3H06w%_dSl1{G)Dxlw$o?7ATEhEyhmJ@_sbz&(V zIwZg6?fO9OPM3)bIKLtBn~!#U5$3wgdB0CD!0>m#Bf~GBz&tG&gW*Y6sT?DoNf7tp zl@iz-Iefs(T#v&sE_DzMYVTHqkDO6CMCOzC0N5iUVPpI?0nj8l)A=U&Whgd$D1#GX zKJB*O=1dg=C{S3T763gtA%Xy2_V%XiEB`ZS(#;HGrnN1oO;Xm!0k&`}kGbuaiM>d> zggV0rlcLJzmmv!ZIe$?>H%ew4KpMv=vIH5ESrq{~Kr*`pH2Y|?4jw;H6H-e8T@@|y zfeb)7@%b8{bF$De>nm9*;0splc`0_Nnrx0#KYs`CYfp#TVx=m*Ji`*ihU>)SWcK)$ z6Try;tk-C$Hs%KC`K2Qq%?Lov8>;8iSjuaF42GIsn0{o51u#cIYr3@ar~p_{S5FUv z_6`Q5oi?2Q~LmgdRV+#wcB3{tQ zkb`FwW@?=<+c`s*brk<<(8#e>sX@zjAmeq%Y`5E{9c!1^-1Atvr`< z*z*Gm^zomyzZvV2fVqAv9oeW2XRml z;aAlxs9{97Xu?=Didz*did7((fBB1=G5lnLHj=0L<_Zb0d%?fCs2LPz;%rU?B>P0z zc{~qnyBiSZT|0}+)^3bo6K9_#z^Dhx8f2!-;3cI*T7Y^g)UK87m{gAcF$;%2`a4jv zugt9y59%9>!GzjLYiEJbXlxQG%@dfNRMR@jmcoMyWk7|)RSZ?u=K*Dti(xX<5O+Kj zAa%fuEy#mgU%qaX$yTRT;T4~wIXI;W3dDKW#?8~07g~|H*HlCoggU1FXBE)#s5Hw8 z_r~TpMy31!lR>s1Yy*G}aFy{AqFF<^RThAzj6X#0m`r84Mg91vv$WPzi}E&zP$g{24mr^A8MG+b2v5sJI^un8L$w*BS&o>%%7s*H-I+) zBnM;RLQK!r!i6(Ep7$kSt;9Rqel4AN23zQ~sM+&`zeiz1u&NLN*}#vCU{(iYG(|3P z@u7nQZZv>gFsJ=0kAa(#(}LlfEMJPCEIq0~Mm{+2`(KhQ-6?dSkOUHu%KLW~O}bep zs@_%ZD!nLx`vJBhN)|AOf&v17gw3f+Xa=K6SLA?+94Kv3RnMlh{K@QW!C7QFl;;1> z&!|9EcRc!{P>Z$2%)N1ZYk0?f!@V99Me>e*?hI24oV}nZwvxFG2CTjX{y|$swbLpPCcr+5`(*;d%wYxq zUmSykEf}$XQ!N>54)T~a4+Z}B#%4q>OcGEB*B>bu*`rEZ9MmmRJm2LTMWwpEVXJ*8 z@+eLM%!)ZJom?={*jbXv#80jkm;5msVpJwhw!~y};hxrKP3*R)0BIFUbq}bB79yor zL^A7;%;4odM74hCC6sXwP{4=KJmRyrnRa|nUX!2>Mr0koreTCcLDvgpppQt`Es*=i zEPy!o!KQZBJwN*@TKWlyDh*n=EF^!iOT|3EgaZuBQQ-5il?V~4Xius5yfv=!7&s8sPtI{k_XNKl5hE*7Akx)&NdmYW=T{8Q!#66 zOhwvTb#JaffZ94HgJ3b|Mc?*l=VVS)oTz^KPYWNc0*sf+7s2RSxD|1d;+IKGZ73e= ziMpQfT@d-I?mF~xHq^LJS3S_R92wbfJe_-_5NBypw$c7m4^&COeHI-weL?7XX~W#DzMu5m|79 zM&PYeOWhPbFgAA5P8iVfXf*sgdHD)8%;Vf_fFS5s87go$0w~$A#KnR!V1vrpTsWUJ z#gmVXgnlp?^ZWXj4rn<2`IT4`(lm`JQStV;TZ~(HnSHuGyBxtSfJ%xC#q);)9@0*!=lY&0HhY!3R z-VDg3_Ixc?MKWmQFo(~*+hc0rhY!f0Nl2oxC^Cl8{<$1m!XUUWaDQF;-TudiNMHVn zVGOQ{Z(#-W^v)}J2x}4&68QoIc*yYEs1dVP=RSmuh`w5FLWmk^nYpe38f5KnsON6t z=_sPas;W%6Q$bS#D@-tC&RMwTcE*fIqckt%mF!U7E4U;l5Kt%xHyth*%Y;T|30RKJOxEpXJkUNzTW>!|e>-2>5k~;VH zN)36y>gD^G0pX;U1@RW&;yZEJ?AjmM@{`9TkmHSWjJ|AK4ViH>5aNt}jd*|IGsLD1ocSJSj{Vgzps5ycV)WMdg4MkNUE$I=ASJZrMnu$$76ZIN$d zBsxCZL_3%Z&m#iD4@ObWqj+`*0HZq419T_x<~_c zqhbumkETvp%Xd{LvQNsy3Zo6ArF}UKh89%W`(Z4~9v-(5I?M}~ zRv~qEq=?_QPiXJl36lIM=98wyDnoGV3a0=>Op`Lt%ek6>ci^UV`duJk_n7$w8u%Lk zb(JNNG9f?f*y4}u(Wl&E_pGU{!l(mVN7~ImXv4)bE0tiLh>TB+Sa51?zvNydL4++E9$zsIDHjn zYD$K+?+JPjB>}3j2pO>9W4~asgpao~b_B2fowAno_= zn$Qp+%mq6uE0g$kY*X~hUYDfD48}nKWIOm4BIFw?H*nwmhxJTL2Pds5e`?HXPcTIw zM6Kl3{rg^v5KOFP>X_aIKXbMozU=3Ei-$um0UwF9Eme?iy-K;mY2^vN%rZ7DpAk@Yl5C!7MrKN}h4?peuWJzW}>$vx47$-i^yfhPOLV+&j zlogf`V9r_@!CXs2WM~9)gxR^4CuH1mFfyT}HjTZj8B3_}Euc`t{r-JHdMqp~0j~oF zAUo9psXSOVVq@U}UrID~r1BrKPc7{9@W-{@{tE38d!@XJlL`yBnUWT{2#dKX`{Jvo zSR?KOF%I&m0Q&Aw1Uyx1W)=ukT7WRNx5tA!y))dB`aN0|5lR)YuzQ>70e_eK<38EP z5tKR;!E$`RjD%ojJh11sa$p;T{-UYM+}zx4EiGuk`mdg=_N{WSI;T3+e8XgO_V#bI zuCW` zplO+$#~?o1mY@RDgpTHdJYEL$GP*iCwA3-6i#hw98v`mi)HodNonL+i(uNre)X;}> z;!t^Ep0<~dP0Wgfg5L;-H}JfjU!QCAX5-*^($XFK0+}*15mv5$ZxP!l)zPN3y>6IY zqyF@~iVb(V8YG2V5-lKp4_j4=|7h}v+w{`gR+Ba?Te!Ek*25!yy2cf`_Y2?CqoUit+=PKx_!XdH*ba8stOo_{cvUQewxu*UvvdXz!mmrI{BS zHhw*&zkk+hrNRfyQ3`xqp&L?KC7uFrLqEi9?0YaJvl8-oE{vX@K7m0+tyN$?pttq-sFPKbi-Xw-L^tR6O;I%DsX09&^ zP;?Ri*K0>BBBckr3O4@mu$z-#T!}TK!_B~1__lWPiw)Ob^SaXDkJ%7z#>X^eCeMpm z{?w0YpY#gRu}T_!qY;*>#vxjr!0zbj%h!YQmo*DWL#6589*nC^P7WIDGFc90tR1Dw zjE&bYlZ3wsMy)07>Hi4ajZ;`$sZb|hhwc6?^y019>7L~u>_kMSZ`}W0qYT>dk@nHi%? zo~j&vNIFOuC1YJBJX7z|>}McAxOgS&% zNzmuVe&Tm9BAbdlo!pBoOUF%O*Bt8jDorOJ8li9``dc zHH`<8&!<=8lRtkF-0U=8y$`{sIT)6s0i|{_yTM9Z&>@IRXxGc)z5`%%H}j(DJ?+Bw zBovG_*I$AGaX-+Ros=jQAi&^14dE^HoAZ)p6C>I_Y?`+%-QAo$W^s9Wa+inVH@LIK zLOEgGT#(%&cd+5o_6wT#=DIpb3g0G2DjprY*G-ZUO8l(xy0rSoU|Ww@Ip*Yb$G$YT zKN7n#ZKnY1MLVZ_p5`szXH|OMZ)$0}xw(au%XH}DRiHdP@_De;-5qbUa`G-XT;3cO zC`kvZzh;6F<9o7bqP9FC57 zkj*#jqc(}4A2ZkeDC!-o#X0~+u5GCbln8DmC^BkmYu7n0e#~UPe@hG@vjjVBli82N(fjY2c`g@4C=V$Q@3^ug_Ieh>|E$y+vd!n#dmzhy{OAIJ zO%KSH5fKF`>FKMRqu+=l8sp{RPPM*QO4onj;!dZ#q6^bL7)t{8Xnc_<>JI1OxEIHbgv#hRK@KR zrw~^r8Ik*@EW1Jx|viDl+UGF>RGv|EfGYcb3?~BsUG@Q;&@e2z#?+oBSAbHzm z1zG@ZdCeQC-ZtLiZnyxASxO9}6HfF0GnRMrd zQozx|-IN%%500(} zXk466U8n`^Brpn!iZ%`mkilLYM=SPu@6%J@KQ1&n`&2m<6kSl@2z+}uF*EHksb>j& zllIRR)R}i${4xpnCh9zkM3fH3#N_1VKc;5Pj2{WEJ1lTec7u&J`k}z8EXk0il@DgS z`w5rDRRN1q8rT9hHZQEQ6xV2)q~euHVjkb2P!dY*4ZJvzTfN(jF$8}Xg}t4pa)<2T zbLmT_)VQ!N3T!kqbXIPD@8XM1={wqd%x)fM&OE?BVkSmOL1tpMngODGr(x4T&$O6* zl^VmV9j>;2{K?JGFDF+@qem**j@#M7FGX2=vJrY%r`6$ZsFBCIRV61a@%A=tv`I>x z_@VViLx9NZHZtwPfS=IVkoh!H=6t(v%4T*&_6_+aG@`+S!sSqmTVAxEj&VVNvEJ|;vHeD&%!kQ{C) zQ-&MP=dwRj?}K{d&xN1$etS0DN~~n2b6hu_1x7u1T}1SO!w2T+gQNS-pKF&dwmJT} zSps!c)m-ex<1t*Yt01_ckkxPDZy!<6>*!VC?pGYp2evIubl?^oT__F z8a(aKX!h$W91|4SmdhkO#ML${;(K$Ta%W~5+>xv)-eyn53l}&%9kdtHca-ci_wk8r z$_xo|EVk5TeRu8eu<*f^3m?f?TiQSQCyeG^eBdK8M;%CsA|hp*9lkr3oZ2k>?tmQQ zC5|M{fS`SXzgiL0vF8TfO zT5A6~plA|2oKnX(sS``CYN|y z+_JjrckzsG3Vr8;5_byQpkTru`xxsAA1L&F9aI$lTbVw#G$Eu?f~~u{j~iRsQ0aI7 zg>CYi*qGlALi{QTT`Sjea&qBqot-c+Ff_Xw{G*0*@f#JG)P19t{iQ!!YI_;C65?$B zX2-1zE-bl*B#;Y+faZDDJsz9 zgqA@|fBz+!A$PcO08inj@cj=+NG3Mk<%E5N_XdaRX|c~6EriMum*+~kUE0IK#*tR) zHnVHPt{F7vO`i=oW$sl)u$VG2RZ4t0|EiSNyp#2uQZ?PgA>fr4;z_narbZ!b#N#F| z$~g6+p*$IW-yfB1uiAcT5uu~{&vm%vawjr1{c4Rt(_wyxj;h+{=$?3*QJfQCG@+FD zuWu{2SXfwmJR&cJa#-aW2~mV?B{JZkYY3a2erE!h0oB#Ms%hd~9gM~+l|h6rG5v6_ zpqc6-6#UTcc1H%_%F@zOh!mJ9qhWiCd84?=$>)HC?K;=4f(6;N!!EU;=8Hqd3*xZm z$|8L=wuIXAV|&&F#qe<4ONZNWGL5^Em~Jq;TWqB2E>!W1s=0$RKjkxSelvBh92-B} z5hiAo{Bm@UAbZIEdSSpRO`_X=9?RRpIk&mvf=5qOXk*xngIp5;t3c!Vkezz|Uj^0# zpUFA$@Wh3C!hc0h^1nYUVz>Y=B1GF8m|z_p#+(u4<~hZFCDAQWP5QX3@|%Vz4&pA$ z+CGQ~6=C_*)afguQ^BK7>C`h#=$&f&s9I1~pVYXKNPV48vpXL-as zO%C~Z-kd9YPT1=GXu^1RRZ2F|7QC0N~~ zlZFd1Abc7i4%&tr9?;@`u$(<<3i+i78!Kh8{=?U^g#OJumF&pcnxLa@;~i*uv~Pu6 zQfy&vqRu5mLiAbgdBDhq%+Wml!p?31IT=n?-3h1ATeYD`p*NF(bm0$3;9pic zBR*J~rYyS4@Jyk%B{!=NPP$HT@h&s=?GmqRb69LLq%w54)?4XE$owrrCUp!4m!6T3 zLKv^jR0Z8cQ3<=;>C#~s&(qz@>s(q<6Es~RbAn(bkCg>>cfX#Bm!RAeZrCdrVi!?AN@Jq)%9fy8&8*)LUAR{g!< zRqc94nM$XBQjw~f>$98I-8$!r1xLObAY_f$NsCJEf#(lv#}B4L013z z6kELVR+HLfOND<#{e;sl^5QHaFcZl~Xl0cvb}=@3&R^@lBpt`Vvk6r-_9d}$pUZ z4v3NLAa|APkmn~14JdqZ@xK4Shq-BMiv&XK0GUQldOju!e11`(#-4GZN~iIe=)Q*5 zUCEMBLYAzSS1qRh4AD+FRW=krxVF{F2cH3RSD@v8(e%SnHACOR%&k^NW5buhdviRv za5`NzmzsfwIbIoyBu381CpeFB93o}sTHpAY_{{Tfr^jRMAsb&c6n`~%g=fw*ohvHc zGPdxwwVdJ~9~+q+4-@=4c<0{$G50O+yDlrAxsC2Oad87H9#ya)5)$|un8XKf>1J8` zLqLH_3Lgli7neuZah zth2Jr@f~QY=y%F&ux|&2lG8Fw9n8Knj$Qhhy%VC5GI~UV8-aV01RGa~Qp$x8tZsg{ zeO*Gha!Oa;HL@uX6{143ow$@AE?bl$7)e+Hghrb=Wg@xTlSRo8oCs zGQSU2YclXqp>d)91zH`R=?vp6{df;Zo^mGox;RJqdo#Lh?DD!!81;II(&M%;(G$fh zutH6D3jIy`gbl-L1Kr~idaqT`U?JctCptF!N<=H6F z4~~!)8M3?H!beR{+bE=>u|mPFmc~SO?OEWgYvPl{KnN%zOMMn8!cBjaCgj$g^DKebQ8IC+wRCBwJhOWZq5_Qf0Bmn1qti%ybaylxB9DT6K5^ zwQ=&kJJIM+wY8X-##Mw6(9O4Dx(L-zW!(8_M1=|j-Q9JK_SCp59{Am>Qm1}(A)6sxTLsKsk)yx(=4j?pj1=B%ra{?>%-;3Kc=O&^AT!&(1w1sHD~q& z#lVgFh!#__u1Uqvxhihn0!WEGVhM#4uFBoRFC^J{JjT{*MSzvN_OwXk7*1ShDWc;C za$^VXKI~zh_W)_kfsC(@M%JW>ukDrP#F3sJRqP)%CBI^LozZIPm?xWGI7l0+QtMOZ zmqOC51n${{rESoglV`n&iFvEc2H-mGkrS)3KpM{HA&33|vz^6+hchHA6Tcly-YVS& zxiG?H<&>zrYlJP0o>C0s`pqliUkCHfy+8_XZ?r8}dh%iY)*;g?2c8Dk_@^AQS(DT4 z`$(M+(37L{p$(#?t*zt}#wb~ZY(MnGhS%u$hy|*Z@X@1C{AoOXi!<$miQoYGxE$n>@!Q-W24)0dOO?)4;`DE9QEzHjv>?Jj}4Ec1*}fj>`Q zd0+kK?N-H*|GX}FG*s{XE+H#y*8duMi{G>x(vy*8C)*B+ZU4;n z+!G?B_?w;6{?bo~lk$dFS>L&Wc2}3?yB?>ckJc-RD|>P$T-o@&atV6na^h*TvkMsJ zBBbXAHfqk^CHWQfJ71xRc`R1UC(lipJz)n~q=$$J6k`j-7~GT_j4kKnHb_W;m?7iV zwgUTP%AV(7o~yPQ6c!0#4H&$Y_z5vl{Y|=2DxX2MfDC1}lY5&`PQUM+)X_A-mb~g| z11u?rLTAXC8g^t3IjHj_b}iw1h#P{DN>)1PwuYo_wdXF19GyJ9c|MbiB}AtJ5gckx z$<@s@Q@euP2Mih}apNNTrW{$qpQgx&*JCV&Tdeb)vGYl`z=l_ZU3UAt=6zN&D|_?k z1^Il7(&Y2`KXP@kbD|J|9v*Vc`IBp34=vtS4-db3!p_r(I@djms)bYObIh7csb;22 znZ9PK#|C*c@&t3qfFH7-74tAw5+8+?=iyeVoJFNKw@n?LtA=75>!|FuV2qfu;8f(G zfIeEiUM-ng={tCr$)aSPXYag4cDXOi_2Io}Bqri+v`AqaWfvcs_u4s8a)Fq*p+2xE zA=)w)z%LaIQEPs!bNrO5Y0JYu!0tYZGZjc|Eb(s&bQV~x9{yz#;Q-;HgM)+H zd3mWUGii=h4pdTt>}cNo`{Eup)eX9+|M_{UQJ zs~7gS%@c68MhKsvDX+@PimnBGLZa(?EiOU1TRl-9K3E>;D<22Bxa_PL8T*c;ZPD2>ue2{Xjgy%*KYKg|CyyB7=5ZWpLfQYg@9&_)BSBc}onhQ~!$B zh|biyqxFwUwE`>9{H(02CI>hWi&hg|EkASQWM^ZKlx2Yz?|^LQznNp5TLmEx)ZUK_ zLh>_=vYv7XNQ(FD?Xkl9f(Va(`3#B&%*;igGnM=7)7V`>I0^xKNn9rntyw_`rs0TG zu=H8o`RWYG2TRiEj^hyT0JAsSQN`z*I1lba-YSV}o$di|;?KTGQVCf*Z!^2n(ecVH zGD#F&gZ7jY@|M+-^)b0pLv2vPi8os9zEpYD{euah*uLw^AvQeobe1U@ojd@C^~))> zORwNpL8|w0C1loH$@xKbZvyq(u0nxz_Dr#?TrW*c=KTAVVh+{#^`M2~EcGeeu8j2xXKN(OWp(}DGTEf2R04@N^}Ig^XR0JP--`+#k&s~JnDRkR zyYBC2qx{kxo0x)_jq{D&>dTNtV^3C|_GOrH(SfKL904_7z!dTMPEx~`8i+$oN$w-P zf(5><`9+}3DhtkkX2s5d_wnj%KUGpWnfr`ixOQ+{6462}w<*x!ny$NJ3XFi}{LPay z^-U>%u6&eZH(w)B7$24lo(s{n${brWq;NO{T{51Y+UDNd?1#t5jSa-+i751}N_Fs; zeGeL@?r=ScyMtxWA@!qCgTn&7wwv~-kO~8UlR7}U;t2=>on4GaBGzgoZ)Y9&7J8d_ zO!)pHoi6%-kc{3u>7&1KvHH!OIqcMtggEXeO76-cjP0+T50zn!4D%m4uw&$yCj~7}^Sa zGeOdTJ~R4uvAW=Y;WKM*lH!v|Qs_7r_Rt4mJn?jSyRRa~Sr;cK$~grm{DDadPL3iw zWmcjR>Br+nHFzl_SJBZ_ygP##=kJ5hmx33^%I*Cq7Y@%%#ffILqMssEzK*hvJCQq; z<5ePGjX63Dx4F@CcQj3&4PR6v+uSD3E!zq7UU2dC2E9Pv&A&Kn&wDoRyD3#u{4w1I z9(s;p{8=6a-+IuUD%Cj*K60; z^D}~X+}5}<2z6o~NyIl^kJxAa@BJRlJo2j=y!FQkt)#1Wmu!d=u4|DeE1towp0|g6 z#1LGhB}tz{PBe%58-<9+OY`}pC7>vg{54s1P?gR0c7n&O>rgnv>=4y;o>qR zm8^d#=JvubDa#~tYUCqqNS?nDn4q3RofWSjf zpO34Zc!@KnHQR@CV|x=t7?TY7h^cogC$hBH$rACS+>(2K5sjwZEJ;m$C6RW%5zzgG zJZ?~x)rLJmQ%?R)T&xBIT~>S-$H)JJC1=6TxGindAYj&Zb zb#6&BrnI9Do5pNeg&c4tC?N0D;a#3Br)BBxepC4U?XQK%p|w}~ca{6FK}7XiY>YZR zV=kYRin+;W5m%4Ow%JlWj@R&nu)+bUR26e3-r}$a<+QYutAaDu54;*wrTA1nxqOsk zd*mDNX@4-cOHFM~j`=KQ@BRaf@uC=iT<@Q=6#q?A;RZfoL6Klht+IGhi<{wRkuQ_V zxwcjU?>pK%dwZUyeEduvw>BO1-)f@oj@$8<6*qP62w>~$Teyie7ijT*M+zs#lPY}{ zXmPzp{$Tj?BfENwuBswydB1i z?FNvW>Px!Go!~tcNHy$vv|kiFNPGqjQ`@s^2K50^AlHBKSUhbplz5VzENWn-EJ`k` z)r`N;;OKpyOoJC|3*se$UNL7=u%x7Uq$Pr|pdh|?;RpRy!cZ%5l_0C|@p1Zves#M? zkE$}?5~X0)4(1&==H%v9d#o@6(bcc6>GYHy6u3|Kix`3V4suW%8#leYynyw27}R)p zD9RXg_zY8M4cgBSMvC~I3#F+hacN60Sj(K~|4Nr?vCc4T+m&QvW2^Gn_AE5McvoKT z86FW)9dw4%=?)ag zp8iX2Jxc(In4d%W+PXTTkS=)(8}e4L;j0?MFEO~!yit7KXX0HN*I4jeTHq*iSC8s` z;4%CnDLzK9ivREZjUodZS669=i-Nl_vUaeX=}X(A*4mIlIzt{IRM?Im3{@zyCBS9r zJA6?m?(|9d+A`KYJ|BY*BQkckX2|B|%ukUGXS^xBiuE91XMgQ4&$&g_yoPgncxfh7_$j#gfo&xO%ra^FJEYJwk_s8Tkq*r2YV6UwQK_Rf}RD!(pEEd zgW=nh(Poew<`MJT=a)X*ZaZG=PukVrm#MIxvS`F!ewk!S5*gxeA+QNhgLukc? zdilwWHiS4PlW|AEv45~x{#ZheQCK5-Ugoy8><&+Q8O?sZd6Wv)yR9Ar}<)1;beZEwc)T$#%*`; zuJrM;xp>;IkPVvf?Shum1PBb^C<)?Ty?O|Tyyf_~yFzBqLcI^S)W8?P=6 z*z50rAaZ=18?JDRj*bpPA9E2^7NrMvCQw>|7EO%{@>bcvVXUa|GI_VM3q?>2wM1D> zZFfoLB3Z9Ml{4}3=fM^FE;pKNwxeIz{^A+d#|Mt>Ngp~LoXwA=Cv4uw4Cd;}xQEZS z;-vW){JSDINTOtY&=ZXDeM_L%!c&OMw*}>%*@F#<+Jmtx4AKT)^a`N$Qw)~el|BNr zCUegmfdh^q9sqfcPbC3873}Rzw$ffngnIVu8JI`f!7|a{b9#`w!*1L)aGI#WuwibD zFMPy3U}DlLDm~opP#$kk`>xfpBMEM=Jb_&oUeeD_JTMpk-4eiQ&{Jbi>QI)LZ2oYxpIWGAlq^NYyhPNNDfhAH@(6mK2uEudk~o!b-Hp}~==yakiJtV0Sl#+T z^d9Uh*FXI>E++?RkBaPt^`Xza@?v*q=jX7KGo1JR{p+al>JtM`RBEbzgpmH#DvqbStl27YYYd%F7G>3T;x40Gh#Q& zm)hSh)3~G8HSaES4%@t}|FbB6e*f2#u~G0PUK7 zj{K#*Qn#7QiTPnQ*>tOh-401W8zn0q6r>(xwjt14p1V@kXZxa;>1vr78qLAY5hh7(y{%+hb>B~lO`$kJig;M^`+ILqs|oLgGZ78Oei`! zPVzg53W~@bg=}&L9l~0!E)o$I6+#;Ky3DB`LyNsVchD*SqqQ}7W=W*g?w>oTx?Q5|?QIsi1Kf&=&UrVX z5?#*SUD0^FzbL$b9l8KzN^0EEjg86rAj>~zwpzb3I;7^Ss;1QC)374{tg$NHuIXPE zl<$sVVgf{3QuEqc7jD-!d+_i>*oG+UliLH;^iHD6wgCpbet^cWc>5-U&w*dE7aE$Q zjy>NnHAcw+nsZ0jp+}@$FJD9^X?=w@l_(s20s zeRryrl!&<6j(Do$@d_;7g={#2&q|Y>&8xgFk_v$Hw^H^KF8OTGhaBTz?Y-L4%j`7-YseV3-4b|TJ)?) zc#H0@oipvo8G;9`4dIvoxtCLYXBX zt_0DKR)Gd1t>5Ct65xbJn_!kyOMBB938V}!#TWPowOZyb=Aj#5VUJ`?@jMZt{T!1b zBgU9WIdtZP`Tw#Ic_I2O?tbJs4L4RN{~2X*Da$fW^?+3<%Bce!0Q)4V%-f7SoF zdpXVKeYyKmq*gww7m{;qf`=tP-=eZoS0*q8wOhDoNBzFNUEzHmTUY?@|Ncr}n4xo~x8Xl5 z*-=Tb5`H3>8pgyl?v%huNi#lTV&k6Bo50@CA9df-;#FqM_1VOqnTF;E4xgmYLOqdp zR8-$_CPJW5MkJOA;GMg##f!e&Kj69A!1YiI0pKXyri~%P4};Dz(1`^Bx68GW0T-Ed zPp9{%&OSgib5Rl%L0r9yLO9(0bgH`e^$wtd_neesXWJd%AMckLb(A`4^`)5~%|2F| zo15zH+#*%v1z)XXZVoH)MUA`ZRPyrRS834^;`8e2YL;UC37t2qTYRv2#%@K+ln>a# zQH~t4!$%c;vk>T78O&A89sG#Mz=?VDhEG_y9k|T;`ugGu%sXdwXSkPkhZ~rHavruz#*$>uo{XiHyH5H7@ zhU}~>jT(u`v2?#)fy~VF*rcZ%t;vGc&^kn|b{dHMw?l{$rbytzoznVJ#cw_?>t{;r zL)#%6$d<_y1)}VpZ_41K1}<6vS0Is}j@JcqoTu773~8~kzo$!ehXUlY9g_%pCMe=O z5YuMEP6km;i0Ph^CH@r%!jQ(g*Y>L)?R4VhJq+>4-1>uT<4Sxa(Fdzs(^nliDAFI* z=4UBsZ?9v#(t(m=cIfMan6d|;3wSJB_JqTns14Cpt{byMoJXU&DaY<&Ug6>4osx6c z`RR$=cjgtL0SQ#L`gT2j%g#$Iq_Rm`{xUH6nDX_XX&!&>4%5ZIcU6t*l)UT-2ty&9 z^*wB-qsYmPbJisU(-k>v2k)7C_)23bcTF)h1PXR7EmL*~2=8spULH;$)arWY&rTwY z(o@rJ%SfH2ZLTF)N){Kr$GQ^!AkgJ)qmbg#?$_6kVHfZPFiut2cFa-arU1uzw}<9v(LVJAHeU+&%u~s`@TzYdT=e{fr`K zhjD5kf_zhyRE+64x7%V-@U7?ErpFAB${8xP)|K)vY*2meh=e$mUs_sKk^!S*;8xv} zHEhhT%Pmk-J3eLPY4J*)ig!So?K(fj_=0{heMGT*oG5xp2EF!US5R>Lcp7`BBLHl7 zy=7n)O4RtK>%raVv0EEA(1jA;_sv9T&s3k7ifCiP_ARdGC zTD$_(f+6zatlu0|%BecoZD7abj10ceMaO5P13JooUi|VTKTo79tNC;(!yU%n72k~T z66pFFMlgQVA6NGMjPxCM5<1Y}@OiqW?U&d9c4#*M1+O=;vC`T;+P#QKdMg|AP!Aq& zlb5z-MoSL)y?>Gg4g9xWKtvjPl^F1=UtPWPfWHW>rL_}Ltb(>McyUwZK64ApuxHwZ zeD!6r_njAhM>y9ujg6M-jZa4=*Lo9oyQcdEvNJ5rEOd)M-N~TDxdbFhD1rzi_qfN^ zZVuHtJ2-qpzKJAREhBz)5cI>N24}+Q;^LEBRwj1NG*2J?#x6ujv+Nmfxs$**W)B-L zHKjU(!y0hdV6i#dTd|IvX( z@Gf&E;)BBaEFjyyo0BZ@c+t_()Zv*a-tpQWEp;tq4zaQ(UQV6j9>@(}4~0zIlfl71 zUcBU2yv5ezIz4F&jF-lNgVgyGKi#sp{6}L!!x0^Tj8zh5=Bv&AFf4Jg7ZcK@YjS3% zc$12~H>Cz<0;W9SL>?ojXjv+BQFM{|j?rYICTiuVEJ5+VQ2d`zSQj<(8XnBTG!Nwi zOd5Cjh*@@s`&ZlUGWY$l5dw-P1G`$fCg!ygMpg7KFLQ*3hJMWH0s&f3O_%iB!|N{j zmM#`5b}wwj7tCE?O%bd%KwB|%QUfLn5O0;>#oQFraHbD#a-y=QF0yk_lQYrz`ELD> zA1~HwK(2j_>2>W_<%0BiWy^qh>R(sN#s=ctq>3ush9K&+2O7s;1@b+x)j*&$7K^iVBRzA~~t|XT-ZN z``Y52lDh2MzK%C+q@=AoeoV95#ybyVs3>&!< zD;}WCIW?*1J`7>h=o{4t8-cE_?xYoc-Ag8G%j&3r!&}LjnVYAxQIV1{bE5NZ)l?|o zO2^c$E-=-aeFz1r#mJF%Ty~kdH$^%)pMN8}Lo+Vu?Po=yQPQqlsm>@@hZ{No71$EW zyu28w-~@z}&dr>llh04xn~_MNTB8qYX|pqJ(JA|PnWyygG{*=wc?Wib)<^jFYok4q zJO5JVUThWNFzAcL-6k`r-H}g8nza74WbWyi2wn9RUc%1rvEN}oe~B`^m-=R+wkugp z`c`e7%5D0^$*YVm=oVs3>ke-Pau)8gP84-Yov1Gp`8HyTja<{`B!M%S2A7$AdB~ zh4-X%@Z=Wec0u=4Q#L*{ogFJUKkDe!fpBg=Q$v|Tv5uyT%;!IxgID|pY*hmeXj;&l zp>uEP8J7;^8P%6JhQ7%|-%*P{PZE;u#u2mBCPcbb20ZV&zWPl*CSn>CqLFrcRc}Cv znn0#D)#op`sjptUQ^q)N{*8>@AbgHQh1Cbhc;0fGliB9F-+OzuhKhn7*B7Z}LUULO z*lK8DBPj2M84OT#fgPdvx7eIQPHwuGeg@bVGo~6W zES%$)a&DkQ{p5z61gm~D?j>@y3JZTbIpYS5Fdjzm=klc+3bIBu(C`a6#JRaSV8$#R zix?Fp6&LeQ_kZ#x^?iJ)Z((-1KWp#cV0PcHI`~2w=+XeIDlAC@P9(D`BGNr*l|$DX zvAEdP)Q5fKVQXyvmiF6Z5X=aaV@k?Gq21A;#5!WW8fWXwJ6XQ9OMz}~@6yxLmxwmu zf}mCcTD;E{;GF&wndrP0!IGC4p-dQ{vDZ($BnTr+?2o`L;xL|Xaz(N-c0 z(!Jx8dN#bk$j~q_VB|`E{J0O)OUN~Xrb4cf!`POe?Rwd7NLJS}sbx2h#L#^@+3VbQ_C-g)GO&EM}O9?kH{lx+f`NB=XD}&pB z95831MhNUd%dH#H^bLNA#i=4qd?WO9bEvC~Z|SI?y2{Sqho)F?j{N-m4-Uo9u_GJ4 z&gFVzosZ{zTYT~#^CjGR+WG7{&Yku-e@E_cQxZbl?V|t~R|{SBLw51q3(#H-eZsWC z0(a%$I#=iOw8VUm1X$3h89U)o(V$PMG8bZrE;D6I%`Lv5zpK_6o3ZI zzYXeu>)o!$C*z=~+9JNVKlKy;Ze{Aiv)rnKZsUP|j(enHjWZZ+cxWp=uJ)e{lxBnr zkJtHYKc?^vhlLRH+HJ3VP_Nf!%rX6uEw$m84iF@erlH#zlKfZ&TG3kh*|YGryUj$2 z;(Jw8&u57D3JM3dj&#HWQ%*MPa)0wMUo|S%n^^M=j<290^<7NnXDLOe`#ifCAmhrz z2tGp=3R*@k(MuKe?R5{c|? zZEbar@OlAO1jJ48IZAf@%Mj7F|F!?fWi^55MAW2cBC(8xi7BabwQS3h^~n}Ts(gow z^0T&o7mhD=p*1%{;76G(a$|8Oi~y|1lV=IjssZXJOkWUJV|Cd(tg= z5FX-@yE}DkOWl*Cj}pN~QX9+z&!NR05~I9AH=&%uCn6#*o~CtaA%=JZOe|O>;LJdS z%f^PIT{$GQ=|p394|N6ZBDGXWuAmuHi!^69E)J%sQ&O{5w)wngE|(_p^!FnT;oiOc z$E>Zaei$<;tfR_Ox-2whedk~tbl(!Z3rHn~o5Hv|XnKWje%CcWd5`hrAtDl>CTZtV z^3mQiTq;T%pE~YO5*;lBR1{;6zve&mcXs9llg3Li=B+&j{f#Q~=o1=R+Al>#APrI# zcmiAnh!&-@B+4986BF30(dQ??_Z)bh8R$Jf7kyC1Ro1=si;wVS z6H~Y;%D0le8{O( zTCA%e<4l?A%WDPgumcE5pouV@s)`}kfX7}HQCrbKj$om`-eO{6@?vHNda9rwV?!kz z1bjF@a8!8{ln$EiO-flwU(mnU?^3KkUu)2^p^8WOG9XuMgZqCMrhBc_@S#L~p4^s9 z#HYp`GI<-`hfXt8tTW<;ZdVBO|Nf;7H8Bo-2 ziZxFVOFxBgEd-+?wZTg^HpIYUh}LngT+uhQ+(Q{YT%ou*$T~IE_p|HSSK^z;!qn9U zkmiRL0&qNf1#;3EQztCIAkH@HVin8?jxEypN*yP7a(+TF=XygELNhv)i zk!b6_l7Q9s_?R6t=IuXbY$5+=;($8LYenv6Qna2ZVa_!*od?Da-a5v514OxQTNy3S zUoKgT5=CrITAm(zVhP7GTBA;V^>}|MM!|`sz{9EcRzo~QcyJ*%*^jk@A6q-DOH?l4 zUezTCqZrHPvS~Z>edM3p@_U>fB102xP6tNJo0R!Vh7ZtT;AWqBcvEL*CqbCke%TX| z5^jQ|ZfJN0PY#k~2R(#g7rPhDhZpC@l24v^C@1{c!Xt2QD7YdDhGL>sL|7CCJmHk; z;@8!UpC0wyd7Q=hCeq`2Mqfu`Bd`h%z_Qq78`dcCQG@nNWPQE#&e7@QmE7S%mUY0TR)Ph^rrSE8RrMD{|n>q7Tl!S~;LK0aH&Bv|8aJ~Ng5x~7>wv_ynCs!q_dRIKwRJ)J=qkm!&d2EN1qS2)G2 z_}io>JgWKYK^wln1^g`U%>ge&GQuUKt<>5Up(#wd@@v|tXgEXcvYYq3Ia`9d8iL*? zl76R{LtKo0dkUS@1?k>T@x$Gm!0A$_@N6;aHdDb;GHE5#vIZ^zLoiPwo zdL~;@@$qn#t9C&kFP;=tcOmVWp%z9OUr2-k&jUm#K!AYH0QZByO`hg!5Wo;leV#er zxU#Zh3NHmHz&uGX;VB*lB(1M=gWFQd{*s^q5B)58Lztb%nC-oiIsxvz19e#=I(Q&} zTA;VUlSD8m1eGhDG-VsD}U(ah}S@-NoPiG*&zm^?|(LO^3gg?IzwNq$r*bXQcP z6Efb?(x{ut&X@PEcyJ_jbH1YQe2elzKzpT6osqDJ2uuTjR&;QgU~nI1e%7K^cS&*< z(G~YP6OXkm5f^M3`$LhoM4th~2j(ebH8o-wZ2^7*UKO-j1NZCa&)2WPz|22UbZyVs|{0XqV%wu8wG_8cAyf>nFuhCIy}TS z<>VZ3(($ikh|oRsBZ_fjafFsR96YlqoLEzrr555ldk6pU{Ywu3`|jcK9-O@aPqC za-c5MO@$mWIsSQr(8N68Q&{DshB`cE5WpXxqr5bw1^`({`jsaMG?N0Sy;nRD6JRu9 zq!xK7!Vw9%EN(+`c6=1?5jT`v7fbtopw6ezxeys zr;g*laBK6t1gN^YI)Dlw5)1NTScdloil1_<$7GH>qJ1TQqxbgK*LljEW$R&m@Nh#3uV3#6UjuE>!1u!p$mq4YLm6#I{`Y1_=7bZ> zu|Tsy-;HU2G;rBp`qdGEuJYdgzU{j=u>2ToI%gahhR|YhUnVL254SV#l$lJfOiQwS zu9=Y~#RHDy9^B}D5e#kD$b%4{tN^8c89&kE7e9o@nS~+1$a}keX-bF)9)c1%Gqtv*g4=x zEPIGUlmRCT)VCXrU5<0TyeW8+xnS;NP_OOZ{5JJ_oQskH|v;f{bl~ z4IpUNsR_>TsH>+MLts49zmx|!WneRAx2yby03R~((??8}-;=YlF4ntCX=ODc?xz`t z1$8m@E92G%kz)W~oSX*Mzl<)xQ7_PfeFELXurolp3|TRh3s~oBOszY$B(8T z|GG%l)l-u~#IWS25JjNKg?TcCv`ShtIUULI_o6a~JZGx3{) z7LI-?8!ZtJtVdyY;R+IBBP&2=4S)+|UcmnZNUK2;^pH~m@I)3nWZ3JALl9co6fyCT zWSH5#Ig(*tc^k3~gAT$VRtJ8$)~JZ620*e$x?N%yZ$oRLCdb}EiN~?fKKAJ=j0jN) zwm&#=7Z(!n?J#Z)d?QSu14+I5Ug&muy)D|7wjFVG)aeOmc7QI?+`eB_n;FP}rKvn_ zs^d!kBz_aJNR}qHQ5DEu*g6&w;U0fLnJeZ7w9^KiiZ+?N1)XHTpjZ%&XypCzl!?Pg zyWNGT8$>pXhMzzb<5a1SQTjqC3ME@W954=%RYzRu)?fX;S|zBz&U>0sA_|BO zf36J9AD?)ZVIIp3l12~?Br1hj2t>_^-uK>cIbO1%dZzBO=>`GO9^*x1t^u0}U*k?! z!qp&$L^wtm`W583;^RqAgJdAL4RuP4ZXYWd{DC$m9RD_KEG%tm21yeW(~um;(g2{V zO&Z;_1*I>?$64xNu(ti`;8Z&xaT)f5siGf460PaXWQQsmQkOs=E)JZ>qa!ERa|Cs+ z;ny8=wMSqyBnkN0m}{^G&z{ZW;(Ay-mi=mf*$nJ!Z#iNK(TBTi(u^SoU46B#^%g$at2EO2`^!JvmXeB8IVnD}i)Px`x zh?Wx*kKNVVaNz_8+DdlqSX--+Pk})~F0)8Y{yD@i-yw+PrUWfdcyv&*fL%T7g#ZF4 zNXfw688u9!oP?<*!4-(- z?Bt8-Nt@|&#tUrk%==WVbv`y!(c28SpQ_@aJj6IIZ@8{ zk+n2Ub=4)8GXh?kQ)BkjU6SAZ6r}OkO-sA3fZzcxg99=vuJYEeGtv%`o$tj*jb5B) z+{(zMh$|Hn&QTPA!>I%}2e8Y=1`o1PIyxX@UR+TT{_nIpyYdwL+sw{ZF3!#lZ;#Y2 zu5}10GDzeYYQTY9aHX$J6sWVeZzWTtWk~(AY+8biT{htax%%Xk6xfr1Awky-_A#VY ze#vM*c@tTi*)-uoZ`W{i9gsVxl$1kkOurk#lNG)#drLF_Q|;*;>?hIGX+&5orKLT_ zRgFJ;u0b{ojyynqf#h){w_=E)?BwAziYt+?{_t|HR+f}ts3(g4%%~{#t3nd=2Sar6 z_tFY&C;H;;)VWvkQ>r@T|}Bfn(;6fZ$5uv~8_ToI_-=T(Pew3)J(2iGi*r%vfq z&yR=2Uo#t8d3k-nOtpoVdgBpM?KwmanSn_%87yzR)gwFL-NCAJRBg_QzGo)YASd6` zr$iZ_leLt1P&}@AW19livxl7_V0OS?oSz4s&TI{$US+9V03ZG=ukS0^=)<{brWvnP zn7FvPKg&B{31FzrOr7h!+h?$(K)i+HSjJl?zw}GwqeR^r0^GoY0?wW|M)5*zi5gcd zi9qAd%?IGjn>@vD{%gw<4LFo9{s=`ZGR%(IZgNJnaDS4LKeEl={+A06oLgham3VsI zc;S`*_@K^vRMP9s)&Zpo@{yHIq#Nr)`Hd6|lN~mKos{&goSFS%&qF@_2;zJ`=AEC* z|Ih-P2t#Q4_s7w#+G8ymY=aNcPpcvzCIM+OU>m1lnBS4~FQ%PzDa|`#`P|)T2Zi{Q zp#iYHfNtuovIA!$hFu>?|7x0HGsbmik1#bA*&}1nxZx!z7WheUNfq*jcWyipe+UQ} zdaA^$7-=MwOGjsC&U^>*gfQwCY)icLZH*=k|264%#%lYyu4c~M!auqk7Qg^1UY(Y3 zZY{%!uCFdf(qq9V^w>UFO1b8m4GQsRm?OQrOVSTJ{(OKXVeVT2|sOwmRGL*`(cpHbzkZui3+cF-JpCD&E;R|D=D1Ym)2au?Gz9g?N@N#+DA%= zdpKRh1C3H?vAZL8iQu30OxA%GtXAq^*|it%+|ODN@Qs-+UHy$|I%hg8rRXjwm-A&0}O6uHW&dh ze2F}Mn5zmg!Q*n^>~bltA{pf&KEj|cFF%j9brdLTu5Q2+-Os`T&9kU0G?hpdNd}hk zw4B{HCKRt{-I; z@WpW)bZ`Na-nrpS7#kZK=W@{BVUa@^*31FzY8TDRZm!$2kLhz;7|&gjXU!c`=jJ+m zK;^_++GxHfd5~U0SXE6818JOtcJ*OQh-ahh{60Qv!|N(x{jPAeDK#~9AK@kDojK@# z&gg@=0jz%$WX(x0H#JV~v-4C&r>8ST6Lj|xPR%^U!}f6rj{W0x9EIjrAuk$!R5#h! zbc>8A)bwrlBB1*!1IkPnJV0sXdKQAC@_j6EfkgmU{vG?lJVM?I_M8g8%xiMUy_z8= z{T^SZMahYlMuVZI%OE-atXnmx?ftRa-yH9QVi7*t1Ti6`e|M+)wBDO&Awoo^p%V!6 zK(xJ;ruvLCk(!==u`tXPtPcd4%-`!6r4uT-di{?L~Rr#UwSAEEhX zSihUD4o|dF_CHxHJFk;JD5`yfKGWveX0o$TDjMo#BmpYK1nX*qQuaKgs0ZiyZm*eyj0Ou$Cvzjt#9565gDh&!ZWypc~|CR3t#2BA0;$EJL{Hf4_C;aM3vST-+cUq1 zV^nmtMaWi|cD&9#W1;N^B!&10q3vGG)s8lT-HmJg!A09pDTzJhO#H$E%r`L*# zKe|A9EmTo)U@9}nRa!A1C>3OADMAT?f})6&AwW?i%%V&QsHISbh!g^% zauE@zH%tNnAz?J4Ol2}kAfQPINJ9inf+QqeQTuWq?|ry0H*Y!L;pDLQ+54>Zul4`` zn*-pW2%b-iq_auvK_J?11-S=koc2~gI`|IFY`yLrvQZu$P%(+PUw7T6gOXqm3&PXx zJ1<06?zW%pGmct0)g8Z!tt}}pSD7F#nFs3mpa=$aCH`Ei>n7_cco0CSkgU2J%%-Xlc$Bni;>@8e>4nKeK#zD&}2P1+C9 zZ;aAx%cYQl@4LUhb;xqytlHp6Xj5~HPzS0YMLSPqW$B=j(N}{|J4elmZWb|L^th|C z@m^=VA1|z!*_c12v4?IA43rIeYH201h$ z$lF;DpZg6E1UtzJ*GQRcqd$ozid;^U!ReY9ftBVd;9TuA*^Vt)TH25B6NAk~GZ$lE z5aAH%=j}Dy-*N(YwYAN)@TStz(CKQL`WK;kVJ^K5RnTXkys3^%{_f$+Ah_FZC&!Jv zch?7I(`aNiWWR*RQ3ia^mc!?Duy!DLG^E}Pdw zRuQpoE23OSdsy}S1QtYO;l#`Y(s!VtKe`BV16naLim?;gS_+OzxNRAZt9Y!KO7dlu zKUM)L21xjEg zkn3`T=Kjz#-%~NKJNJZD5By(agfW-2zR#d0hsL3>1?~t>z_7x06AN$M)KlJ=3j^Y? zD-0ceB9RjM5I_V5Z`q%(U;LCn!a*HdUviE$V!FBO)ixRph`IyGoxLDZN!p*2qur_d zHt@_WeLW9OrLUbcMk4Sb<}F7;Dg>Z33Qcs$7n7$yPeb63Jea!wGAVW>k~tSJ*_8RM zX$SLN4}Bf->ifa3;%pLrH_m_7K+~p^FX!+YKhwOB!9A*-i|^wK7)vhz*EoOEgv8g> z+^DLCKa_O&H)t3FdPwXx2>doL0-jgX{;0DwSAT6ySULV?vKf=fbi4r)uhQ-2=Uw{1 zEy!Ok)8Qjqkfq1(5x;S?%I{oQI{tOR9m~)mxPO|(g}nyL76hU45(qf~9j$nT$5*HM1v3F57G7PEJ^vk7D zSC`jUlWf6*7z~<_+{(2$gd7$7&snDEUrwsfzhb%C^<+D6*WbCu?_cee~yJbBHP@rVlL}G7{ zd#}A6N2FVUyYdv3E%xwhfJc-SQ;O6x7}_+}=$#z#>;x#g77x6tL&MU6aWhga(V3hI zFZMr{Vqd!2uQDHLc=Sn>k=S{)9u1uxA%059Mp~%o&?|AR-$$_xIsu7KA+>J+@ld^O zAWb`h`BToGD0Fu@8pTcoj6Af_(MY+AE8qy%bZ`n(x8f``wpD`*rBRQfFe|CCN13%? z3!-zlp@64^cL@fi6lsJr@+H8`un$99 z*UAx#yy9b9oFH8CsO#ZB=U)o%V=Yg%MHSB%Im33NpEqb`NBmaut!~biId$=oH#`=PfJDlj3om`el#EWwj^n%jSSx zdrw!tEuI!Rj)U$p6>Py+44mC;iFm$*KM_E1A{V9HE9eY0iMGz(2@ifZxsUCPo<@0EqfqZX~%ZQA6j7fiEgLO%e!1U?GA zftEJGa*OW{KK)v)O3ddmX`?jZr62llBww4EMxbF)YtimSJp zb-Qb_0n6njbI7Dz<4Jtrd>W-N&oMekPzp{>2v*kv4eXaH(#2fZXX0Ib0_ z03tC8q9?br$ac-#N?8e+NEAFX!7M3;goYwjls}#ht?o;iexfeGmq~IW;q5Ro`|z$H zuws(cm6JfaVJVIGEYi!Cz}d4y)#aKcZK(;K<+ zkvgkN*^Ug-Sz>s6wNH!v*ZH7QQ~5|bat2s^P~YcpSkQ(H+{XLiG`?;sR?)|NGvn}s z*&(fo#Y2N%yyd1y&@i3vK+T^5c2^RGynn@c&}I9L*YW}a9mbV z(U%o9H4!SSlGJwd&4HZr67kUImr`_Q*d5c*+JcLq$e r4%B{OEPFZyEB`!ok}(>1XBI0*J9YcwzUK|IGVpOe;^t6o?|yE diff --git a/doc/reference/clutter/running-clutter.xml b/doc/reference/clutter/running-clutter.xml deleted file mode 100644 index ca50218b2..000000000 --- a/doc/reference/clutter/running-clutter.xml +++ /dev/null @@ -1,402 +0,0 @@ - - - - Emmanuele - Bassi - -
- ebassi@linux.intel.com -
-
-
-
- - Running Clutter - - - -
- Environment Variables - - - Clutter automatically checks environment variables during - its initialization. These environment variables are meant - as debug tools, overrides for default behaviours or to - address known hardware issues: - - - - - CLUTTER_BACKEND - - Changes the windowing system backend used by Clutter. - The allowed values for this environment variable depend on - the configuration options used when compiling Clutter. The - available values are: - - x11, for the X11 backend - wayland, for the Wayland backend - win32, for the Windows backend - osx, for the MacOS X backend - gdk, for the GDK backend - eglnative, for the EGL/KMS backend - cex100, for the CEx100 backend - - All of the above options except for the eglnative - and cex100 backends also have an input backend. - - - - CLUTTER_INPUT_BACKEND - - Changes the input backend used by Clutter. - The allowed values for this environment variable depend on - the configuration options used when compiling Clutter. The - available values are: - - tslib - evdev - null - - This environment variable is only useful for setting the input - backend when using a windowing system backend that does not have an - input API, like the eglnative or the cex100 - windowing system backends. - - - - CLUTTER_DRIVER - - Changes the GL driver used when initializing Clutter. - The allowed values for this environment variable are: - - gl3, for the GL driver using a 3.2+ core profile - gl, for the GL driver using a legacy profile - gles2, for the GLES 2.0 driver - any, for the default chosen by Cogl - - The special '*' value can be used to ask Clutter to use the - default list of drivers, e.g. 'CLUTTER_DRIVER=gles2,*' will ask Clutter - to try the GLES 2.0 driver first, and then fall back to the default list - of Cogl drivers. - - - - CLUTTER_SCALE - - Forces the window scaling factor to that value - inside Clutter instead of relying on what backends detect. - - - - CLUTTER_TEXT_DIRECTION - - Forces the text direction of every Pango layout - inside Clutter. Valid values are: ltr or rtl - - - - CLUTTER_SHOW_FPS - - Prints out the frames per second achieved by Clutter. - - - - CLUTTER_DEFAULT_FPS - - Sets the default framerate. - - - - CLUTTER_DISABLE_MIPMAPPED_TEXT - - Disables mipmapping when rendering text. - - - - CLUTTER_FUZZY_PICK - - Enables "fuzzy picking". - - - - CLUTTER_DEBUG - - Enables debugging modes for Clutter; debugging modes are - used to print debugging messages on the console. Clutter must be - compiled with the --enable-debug configuration switch for these - messages to be printed out. Multiple debugging modes can be - enabled by separating them using a colon (":") or a comma - (","). - - - - CLUTTER_PAINT - - Enables paint debugging modes for Clutter; the modes change - the way Clutter paints a scene and are useful for debugging the - behaviour of the paint cycle. - - - - CLUTTER_ENABLE_DIAGNOSTIC - - When set to 1, enables diagnostic messages for run-time - deprecations, similarly to G_ENABLE_DIAGNOSTIC in - GLib. - - - - - On the GLX backend there is also: - - - - CLUTTER_VBLANK - - Selects the sync-to-vblank mode to be used. - Valid values are: none, dri or glx - - - - -
- -
- Command Line Arguments - - Similarly to the environment variables, Clutter also installs - command line switches that are parsed during initialization: - - - - --clutter-show-fps - Equivalent of CLUTTER_SHOW_FPS. Prints the - current rendering speed in frames per second. - - - --clutter-default-fps=FPS - Equivalent of CLUTTER_DEFAULT_FPS. Sets the - default framerate. - - - --clutter-text-direction=DIRECTION - Equivalent of CLUTTER_TEXT_DIRECTION. Sets the - direction for the text. - - - --clutter-disable-mipmapped-text - Equivalent of CLUTTER_DISABLE_MIPMAPPED_TEXT. - Disables mipmapping when rendering text. - - - --clutter-use-fuzzy-picking - Equivalent of CLUTTER_FUZZY_PICK. Enables - "fuzzy" picking. - - - --clutter-debug=FLAGS - Equivalent of CLUTTER_DEBUG. Sets FLAGS as the - Clutter debugging flags. - - - --clutter-no-debug=FLAGS - Unsets FLAGS from the Clutter debugging - flags. - - - --cogl-debug=FLAGS - Equivalent of COGL_DEBUG. Sets FLAGS as the - Cogl debugging flags. - - - --cogl-no-debug=FLAGS - Unsets FLAGS from the Cogl debugging - flags. - - - --clutter-enable-accessibility - Enables accessibility support. - - - - The X11 backends also have the following command line - options: - - - - --display=DISPLAY - Sets the X11 display to use. - - - --screen=SCREEN - Sets the X11 screen number to use. - - - --synch - Make X11 calls synchronous. - - -
- - The GLX backend also has the following command line option: - - - - --vblank=METHOD - Equivalent of CLUTTER_VBLANK. Sets the sync-to-vblank - method to be used. - - - -
- Debug flags for Clutter - - The debugging flags can be used for the CLUTTER_DEBUG environment - variable and the --clutter-debug command line switch. Multiple flags can - be separated by a colon (:) or a comma (,). - - - - - actor - Generic actor-related notes - - - animation - #ClutterAnimation notes - - - backend - Backend-related notes, including initialization of - the backend features and GL context creation - - - event - Event handling notes - - - layout - #ClutterLayoutManager notes - - - misc - Miscellaneous notes - - - scheduler - Notes related to timelines and the master - clock - - - script - Notes related to #ClutterScript - - - - It is possible to get all the debugging notes using the - special "all" flag. - -
- -
- Configuration File - - Clutter will look for files named settings.ini - located in the /etc/clutter-1.0 and - $XDG_CONFIG_HOME/clutter-1.0 directories. These files - must be valid key files (see #GKeyFile in the GLib documentation) and may - have three sections: - - - - Environment - The keys in this section map the environment variables - honoured by Clutter. - - - Debug - The keys in this section related to the debugging notes - that Clutter exposes when compiled with debugging support; similarly to - the environment variables and command line arguments related to the - debugging notes, Clutter must be compiled with support for these notes - in order to use them. - - - Settings - The keys in this section strictly map to the #GObject - properties exposed by the #ClutterSettings type; if Clutter is running - on an X11 platform, the XSettings manager will take precedence over the - values specified in the settings.ini - file. - - - -
- Keys available for the Environment group - - - - ShowFps - A boolean value, equivalent to setting - CLUTTER_SHOW_FPS. - - - DisableMipmappedText - A boolean value, equivalent to setting - CLUTTER_DISABLE_MIPMAPPED_TEXT. - - - UseFuzzyPicking - A boolean value, equivalent to setting - CLUTTER_FUZZY_PICK. - - - EnableAccessibility - A boolean value, equivalent to setting - CLUTTER_ENABLE_ACCESSIBILITY. - - - DefaultFps - An integer value, equivalent to setting - CLUTTER_DEFAULT_FPS. - - - TextDirection - A string value, equivalent to setting - CLUTTER_TEXT_DIRECTION. - - -
- -
- Keys available for the Debug group - - - - Debug - A string containing the debugging flags, in the same - format that should be used with the CLUTTER_DEBUG - environment variable. - - - PaintDebug - A string containing the paint debugging flags, in the same - format that should be used with the CLUTTER_PAINT - environment variable. - - - PickDebug - A string containing the pick debugging flags, in the same - format that should be used with the CLUTTER_PICK - environment variable. - - -
- -
- -
-
diff --git a/doc/reference/clutter/table-layout.png b/doc/reference/clutter/table-layout.png deleted file mode 100644 index b0b36174317d010a028b25aba4c99cbeffea5a2e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20058 zcmb^ZbyQVf)HVzs8tDeIZ zzjwS0;2bu4?^ScndClvZ`$VZI$)F+;B0(S!RM~fuY7hw2DEM(hga=2oKQ|eG7g!f@ zS#?D4<%{?s68!zzRZ83Sy~9UW4-;o|h=sj_o%tIVGiP&idlyRw*JGHrw-5+9L{?Hv z-ShjwqL;7w)S}4ANXEAh9Gn9mmT9SjY;DEhW-)_GH1JgM_Jeh;vP=Vh&elq^I zbe9n<=WW651(y-1$p7oh8$Bmvo#atoQgV_gisZ4>dYf7dM=C|DR0NiSzycn z?YMYSi3mA_Q=z2HZDoNdLQTN6dv&$3ER-S4nNLwsQto}@vP4Ra#d}7Ye!_)9JP5+V z#H_^)EHEyH9gTDlOd0BG{GVg_V((X)**zO8TD~s9;KKH5?CD6V9`LEM_U$J$%8@lM zaar#9EfEMMTM~}jd0=5yz5_SkhaMI16d1cREV{oI?SVu7P)ZU{7g}r6)Py8FtYt)U ze8i~2>bC4h1r99Itjx7dhZL^Qr9e+ZGx=moN=n)lj|q74-@fS5t#Vn+WILB%!7gOfFh}6{1uq=2=gglOu+R zG`?^~oIVtrMu=TfvZwOiEO^Q~WP-u2;iv$D7x?9iXlOV*B_H3(S34KJ??t7Yc?AWe zQ&XsNBm*sTlrTQsO;1IoV}e-L<)?}jt&7> z*c*8PNii%XU%X!qbc(Z@~!UC=H`teko&x?yg=V;!`GRo(xQ8F_lnwW?=f-aWZ ziAqVm`7>xEV5_IDPT$#?7F?jlP;N&ULkPZARVl!%7L}Dr=;&};+bH^-HppjnLF6V8 ztZJbM_^QZ)Ltt{$7=(vqz)dMB3BVLZMn`vV4$`m@+UT|1B12;k5rscJnq`mu68X*$ zM(#`GNJ)87R8%BoXy}w~GMY{PM(zE2_Vm8M;_s6a^wZP$cM6|_#8)%=T5yrz5)w>vCg8Hm%8*{Y8Uu!QA*Tb$o`5s%j^qNJ z0!Ag_>zlNZW8%SpgM>nW0Ta_pmYnQ11ht^&+6Y;2l0gC^RMFM#@yQd$co`u%A~d)q zCK1t5?aHj0x;mn`M99iEossg%$A?FacS^A^kV?3bueo^=n3$N%Ht0_u!KB3}mgu5t@&N;5 zCGOWR&w;p&FW0A};D7n*j2QU%uQFJ&*Sp_DQ8M@RupP~Y%)Kuh)z(8!){JhSRG0MM z7DQB#hxyPvy;C!*lK3s^&*Qxb3w_{@t2haE$f)44a^^_NGAXH|nV$%? zh046OiiI}T^GOU#R`UaiMM9n!TMxdGN_1cmF`ZlNI*x``P?5$dd3cC#Z}V%W;)VKv z$;!jQTLU9umk@xGnhYcWd5c z*L2cLgh(Wa2jl->78*;sxcgh18FLxf8`P#cbDVyJZA6-_$;9;G(F`tl7&AT?0R7k0%J*q zF=1f~3MhB!M1oBIG1Ef}kiG%__k#s~Zc+b^=Aw|BpU7ydd&{d}HiSU9z}vZ$;+|_f zh~|}Ols83;bWHy{D~T+YbX5F+YeD_RdQ7Egsd0X##8*=3JRO>bu{mvzZ+^Xcm9Ver zv4t|+e1WBq!csfWX(NF%_9Z>~T>fjjRW+VF z!opN##UUc1J^c1gwL4k)t=OsznJgOHP@zCZ(aoKWzHV*Fy5RmtlNL6y> zb2Pbip3D&5chb4~BlkVvkehFBPe4J>Wev7w*%y1Kd(`ao>l^yn)|M_;mL`(z6c#B7 zrPx06Sw==j|J`x-1cSP<$p?h>ic1 zd6%t7Ba1I+Jm4Yky*ZSk*z?}h_D9;0OvLlpVa}{$P>E!zBNeP-r^eh!O18pZX-AG959=| z6XHr@!gk|*ajYd2bO>M~yW8kpI=QNU-FYt@>I@7=TJ(r@;h$Vz81 z2ySWA{aORbzS|i~pUyAn&AZR!HLENN+#RQpwc;jRLO4`H$(Hm>sx2#<=&Bo%#QfUX znGPS{JEyAylQw7{QCojgAX1l{BHx-qAGWzSm5zqM`|qEew~#br$|Bm}RB6Jv`_x_A zLQRr~vy zvx%f4{o(J=PW>AAfHP7stkyq7=)KF#%Bo3M`akrf7IU8r9!A>^qERlYrI3AbVdybc z(YsD|i3miaA|r*`A##$FU9Lks8RW@Lk|HDfVZfOi>E64hFfBhdTCl;{x3oDPOAI*eKG`pDBeE#Mgmsb^tR5z&SKxnt zuVPd<7(-|%_e}Ug_y4c99TBHr&Wsazi0|lj0GF9}}`&U!xJ3q)v+r%kD;o~HNX?X7)8^}LVk|QcgWFf(=thcEC zZ{N>kb0@sIpsKBQCi+6?+9~vnI{t%*r2kis`tK{yEAQx4ahhze@iB=zFL7Unsqy>F zS^eRDxe5eO4-KJ@Zy3aYU3I7$9beYW++UD<2T;>+^_T98v#;=dV7LBRvtntvbHwQN z*Lf3Zxa~>ckNc72GaNF8z(*9=uAGLA`Q zndC0MQTE#Mv-I=x9V<1fK4P*VYk=wsMn&aIZ)aypOI6)=Fq}2Z0{KPSno8Gkm7?Li zj@#lIIW4~2oeioKP1S6TEEOKVoUNl>VJLN#?vU%+hsHPbu`-43=2q-A1|%$t3^pH2 zbmC_Y*yu{p`G+pK99RY{>L8Zf9oR}Lq`}GqW=3p(2q0(kYp^Tt+GwaIfs@mwmkfEMoa( zBP=qK^WdGHZ&7S@AYdA^wJTRT=u$7~!9vMppixlCPnbt%?=k(Zbi-o=JfJ zSYpzn{9i-ca}HK})wW_xKZC{It4?*!t*BEp(3JtW_b|11!jd z$76O+Vj~^QLy`Qgj3l}D9M{G3Dmo^Yr=y3~wq9^xwpfT`-}56`2`9&w=RT3n`hd0r zPTS&Zu(G)o0KJ=zQ=@2CL2~kBBye#i7rCudvQ@}!541r<%{3h%-DtTc-TV2osm%Av z%MW3?lZLYLy*1Z6uT{8(27h77qsnkmpFm?xBomrzQ_7_kU#tF^x^RmX28Q zmB#2vk!r8;?kc_bos#+Bmrwn%_LSVd2z8zaQ07cw7bX6!)=2G5s{b= zW0y&b()M8Hr~=iE6L_eEm~1tQqj(v%1CO>40gf85H@NR8B-k$M+NAn3JpN?z)^VQy zcSH0r=xX%0kwKL$@NHkd996_j!=aLXo?i}Vvx?M}{y)t|SFxLYx!NmjY25arGEl<` zZ@$C>pls0qcMtx>4vtD(8@{Y|#Wy=rs0RhrZ1e$(>Hrp%kvnP4 zeo%nff6a!t!HYu`qC zT1mNf)YJr^a2PO)DyMaf>lrgY0Z+rilk2|he0iVcJVDp@FHQ(P>lhn_h!ux2vSEOmVDNdei61v(H%?BnlxK;TOE2Wb<+^SwO=byhJH7obx$)w` z`|TJr&_Ys}gE+|B_sye}=m>4BRRXS!M>T6Q=LusW-jh|pi9BJ6# z$3*|eiB~RSP%P!TVV!Xz(%l;ak>B2uU?$Rf`Q;#V9nAI{)uEx19#Q@I-;HelDl$gu z;k~j~3-S8XW53_E!KD8=D!}4}XVzuKVgvum*^cHT`ehTpoSh9KDkvrw7uXeFc%wY@ zusWJP`NnzY9Ms*xD}khQ7Zz%4qChP1%StV!z9!R456t3(!%HM01W1JRtjj8-Pydzk zot<>C9W5e{?IyiBCX!lmK^JeS(qy?LezD$f0iJx6w2EhQEy{X2uZLN6f}@X{*QZuK zRu;8K-JZw4>}*x7?PLyE5s_}82R86>J#s1T_s;+2Y8_+e8ZCEnC`e&X@cH1^)jz#4 z_KW)$^+JiS065HD=|XS8DuWAy&dHM&+ZS`l_}>^!jZDHj%oN=djfSA~cwj+)d%wI| zqia6${1GgY<7tM6O0#*i))~5jtk`I_n0-dq%C6vxL$295_Sd=+GH@3>d%lrLI$C%& zwwWLtz_6L+e`^k~KKZ>FT}d{1Xe{xoFru#dh2g&*FR`0Ct)6cu0yR;1ISrdmrOIDe zGD702Ip0~Qy#IE{!I*{qi}3Miwb`QKx5yTi|6FZ?r0|JoVMcTe}`BR`)O_>=6Hm)=O!@jA~Q(my@8 zXh%nz4{7CSQn@bh>74(_eA!b1KPD|dWce{Q>c8~h!||z`w1g7cpSB0JD_<&FrKIm) ziLCDdj-}lD;@%FSuhrE#FB9=2Oh!QelV(vEMTs<*)8XY~j>b#oL7i;1p232CqqYxR}+qB+CMZs33 zVfam&%23D|7QC#%z?|MiVtRJZ&x>QaB^X&2l}Xh9TQlYRpigaR50ZwN80n(CJoCZ# zB$yQZZ$gS304#w$zdn>mFpP89`r8rC@cxU2PE#i6$G=gF&Qi zTh?l)X2x1XpmZeQ1zipORrsqY*SXHXFnWJ)=Bkd9sjS>LU#R5fmKaHmje}J8H8-)- zis!ojmE@2iv9)M5qBO2PVIJoDr2_&J0xWy0mD4a;=PI5rE{*PHuqhS zl?HA?S3#OjUo#x_eZem|PGJhDW41swk1qn$r7HbzVYF;*4=|(Y7CzH|a{SXw^;w+e z@$jqI3o>>$c9Mo4o}M&*+!!DrApVR|OUP4*o#wW$o6ou9YB$VnSzAB8_TDyrAoSJz z?^@ZyFSkQc?~ufbZINP0;5br{bN@z{A^ZDd;0Sv_6fj_CQ{K4B9yqxmPJ<2UZtP-6 z%JFeXybTYEqcQ{4Gg^_BdiSzC?%PnLgHxthVOPgDPE4kAm|e+C40T4t;L+9e+8t-H zB(GZXWF>@-7*d^-_w?C~CeX$f{BQ7NcW<2LJT4aE0)<0+b|uRfm-c34W@qij?fwqg zUC;cOnc14g&dsZSBVu$VfaN7#tSRrW(4}g`YBLLPj|x0&e_G*p9LD5>xFar*^(YOJ z?}7Ls$j1GaG#Wq~E3VuH(+LN#P!Cu;Q*(wCrZABwy+6wrid%zwf`wx=cM)DcM9EqoYqg;EJl9I)tUY!U>5Mk z!LDDX9M1&#V67YHlATY04PsRioF)~ zLx8aq)P>Jst0m0x-4?7 z*yhYymEt&3v%#O#N~LCIs*4&{z4l1OFfcg%8q0J(p+#&!Lpt~PcX<4+Fhcf zr##r^f?QQ6!V#*S%_6q!c0ej6A$XMC?8DGc3SRtSyyy~@V}O7s2ep}btb|AV-_dgu zT6t}4%V$b4Cj0NGgf6?KlzF*-1psq(fX>_i20u_w*bWLHffpR_{aO{rm5#RaUZjy3;dzX^-X~$~f!${p(JJjs?kE0jb40-Awk87&5 z3L`+hRU1M~tq(Pv8rE7TC#yBf4i`zC%VgoRKLHf)PpbrRqIQAoZIKLszk6YXgg;R0 z!ea?(_(u{*1XmKg#Nf{dg*sOC{GAO9qZG5p3&B;?D7wLOv|?AXx7N)21g+J>U&+uZy*nzDq0W2M=I z9dD21Wt$O_k)z$W>>tB6L2((s@<8BHw#XBdI2U{&$a6qac0oW8wUfT=u z2tWW#eivf6SBsqFeBm<0bLn#nq{Ug)F)+?oLK4o)|MUlz=jLK_+hhUYC9&ju)8-_GPta6ocLCI~NYl5^noe&l7P%-h_pF=c6D(2Zy7G-F?E{dCnsf z+syB?1Yk(+w|&^m@Z2oPDmCRxP@j~awT)p*FDEH@4-ZT3eD=ZWTcbYxW1ooe8-`u| zP5TZJN@y57=JwP#dKf(JWo0cAAP+?W-h3Efx`V&p3=em|9xlbqIkY<63&AVD0O(11 zeqyxADL0|dOhxL5B*KK&QPGSur6n)?C{%VYNf*g* zljLq9BB($rxX}6$)n2a_X|7wca>>Sxi;H}lw=HO9?BnLfM187|D(j|eql%V=w8Cd( zxy^DBCInQHPuV#VCQPg;NgiVbiaWdxq`@?3kKTV+`3N5InMDsI&~wgK#MH@zKh2df zgRFSf(z4zvu#uDtW?~$J!e$%nI%{k={0CN}Si$Mah?<_SeoMKrvEe3Hwvx&jpL){> zLE>*RJQBgrivI7+nNN`xF&Ltuf&q;JZ<&~wb2yFepObTfjP_MXRt^pD$!h>8X8Z~H zFV+C69TgRii%VMoB^v{l;NwVdzQ?lNoRD5{npvMpjT_S%sn1`gpW5>numA{wZ&(79 zQFM~MM~=mfnt9b<=E#IKKbx|-a;Bb3=|5T8x^`|l8{Drgsymp0t=J=}Dk&>VLrEne zpim0v=V!8K0{*tA+8@m%wAdB43z4Hv>)AwX**`T7arcz6qyfiBI@D|@E4PCUyK*(3 z*d{E4V^Yi0Xpc#Gnf)R#Er3Um96e+ERpGPn^denO`#Ax`RqGK>P}W+n zh3iOf9Ve$Kd~TiVru`04OVG%qm+p_dtat{$7S?@S-MbV(c|A@B zHO$%?C53C(5pT<@7X`?KL&t>cpWI#;BR3(6VJk6+SqbO(z-s{Ni?7KN^B_4nqu6?c z?h~6qb0pQzj~)6dyU~CCkFNzoZn9_@Hrm7GbAD@{y6@LZ6NKN}BR@ruR zwI|$@6%gyv_K>f9`DcNmQNM`a3A!-g$t6yUXzvvc5|owIX=Loxc<$p1rKd_}%AupG zO>fum7804kj~(9N0>w+00jBfi7Uu7d%TkI3{Rj(ByB4t(bJNVk0q3?gK) z-T63`dO{-LM+uaMv*G~tTbWG7!;|}v^&DDT^iIuNEI-&tn;;k-HMrL}kb?~aNkn8| zbJrCrG6q#fA_SL(#s3)Zg;J)c+hzn-2MKtNU50jLV0h2t&XsRh7emA-&M=Q=D}3$ew;t-qUYqdb1RZXpy3vKfT3pM$kpJ=Y7C3(F3I z!MtpTi3C1>Cju=jJK+kC?Dgy5HB+j+{g$62HV!=$`nhk53JRcr){{Vs10{O%L-t+3 zyL-e;x#=|3h-%^Zv^Ov7nWu}c>`BXfvm|0rxS!yzU(BSr` z<^6xrlDCsNImH`Rm>mD7$AXQc-=KyT-NVAr0wBQ0IW83cN1#(YF0zaOHR8c--*F|= z$9SP_nGR3iarUtOY=DlB&5Hw2pP^lor%NTmK|8Lwt7}sF+Ko6V&nF17P5ThhHvf42 z;(kTo7X6ZDZKeGEUwv2Fy>2nx{wsFY8J1~hLi?%8u;mlBvTztDYfI?dUxoUEacEC1 zXD+Vnvr&oF<#dj+vJ40|Bn5GwkUD@KZJ_dV31po`=-5)2aB%sc zXdodA;Q|>=`VTT|y9hH1&{D#7#8}l_8;t)9g#i~%Gyj{y^z6fr<`ZaFD=UL1VB7xIWx!5f%y4^}Q#N~2OzaQc)YIDr#GAt6OU<+(~Nvc(h z9K;L_*~8HeS-mKu062SfzTL&jjKbe`i(1yxlTi|~Av9gtmmfIBs;+b}Zeh>pIIx0VZk)R8FEr9=;w07ydM$_5`F@S`Y z?W#wDOSww?1lmo*PZ#mwA=}-3%t@Nr2P9^s&juze>g!;awwo~K(sLjt{k^?q+uqKz zon|Qt4qm}0MiFTtg@T9Sii#TT?UNwEg=-sCDRLD+oW?@~_UXvO)o!Ts%0}lk;Bwpb zRUm+wA+)hsEh-P|`VhS1>fV^y+HF$ZuG#66?hJw)B}7r|S8gu6#R#5p{};&tVO2m$ zp4ioy++;n4o>#WT)+{!y)(mjM(hCqIf=_5ml4RNL58I<^l`o+^`4A$C~UCaLgn zHWE^2APB2<0Vhy*!dC=IgjR_O{Y^=PsFSL`z3=V84w?)Hl?49&3^hM1>-{Rg9=*Am zXSdyyTR07PMsTA}iQKpM2i(1a{Qi;k1;7E4uJ5I!aO)j&FnILx=C?uM$SqXrS&TrZ zy4)6#0n}~+J};e@tiijEO{}recA(;)R(^}L|Femus;~blqAN-)1WQPlX$qhs29ale z(~rZFw{1^hK!#EAxcjxity}B@x(6iRq+jESQ`YA@U1~->faR;(aBfi1)Qq|F<~*vW zf+LK%PgI3XMiL7_pkjN2`UuRk_wnAzYlv_%gMXqFpKZrJSUl(#P)YhvRujgxH2=vi z%1dHJ<{~Bzd@3uG2gM-5{)qtc73Jk(@OrS&`d;Gp`akibxNM6H8VAZmQ;!ZY za1*|8?^s!01zj``fetc6?*xE|{H`V(9(g#6Ra9J@3zTTk*!BByg7&IT*D--w1M;lg ztsAGwjJGjBSRDJ32xDVqm8Ewg$^vA1>c3fWfWeG^xRH~RLQOewd6B^ydOq58=gapL zm6XUh*FbrLV{rE2!s4a#F`Qw7u z>>5Eq02v}Zj^-E+v{lw<+tz#6LZitnKS0J`zgQsyOG@OYPr8%SdZ4!Ib9c98+{Zn& zYkFp88N2f0rqb2K7m^WAvy?=uQZu`LCi3Qn{^FPnMnt5w=i&n>rvSJ6UY9J~-DXdj zkUU6}o1KjU;#p)|oVcVU8y6w>^|u4D?@IV`@}-WuYV08vbT90qmUg*2P-<~|dZa@m z5UBnuKk|kjx8HJ(0xkC?Gi~Z~<-D}qU#dXM^!FnXfLw@(Co=l_uwc=Jb@9Fk^w~Rf zharct5$>-zH`E!B)V|oNA>AiRVl+BJLgxPA*5Kx5EJ>*_asdGxP${I&NCQ)X&rhtR zt}(T`)>(>T)-?#o1~MpqNUma+;D&WrA2;gAo^YNxX%o zX)$O{_kSwGCLqy0z3sa+FLQ3jM?Ad6dk>H^uCqN3&W}yWAL#(3x0_bGIIG~B0PmHh zX5?^m#E1d4;{FlHm837nD9>KBQ=syCq9+yM*B`gWFB-t*zKsAP4kaae6@uJG*G)aN z>a___f&NGF1sA?(ivPb0!G!*=fGoKI1qKf;1FP}BiZ8fCAE?K|Vk=vNlCCb96+1no z|1~!QlmFH%s6M-?R8&&9U)RL0aM%Jg;Z5wZJR@)~y`yB3C)>zOFUndVmF@p zvpx^jABedNVM;~1>yQKNnCqqyQbG`&KSP4HB17|7{t%$-I3EW zX^jS9~xmS4o>$@RnZHuO7c;VoZIg!eoOV&$3}M=wA3r za8T?1UE3KN`c4l~s4yFFIZ%QwJD8R4(?%gbO0aN+EV$RDpL?7jK#wu9Q=gVN5qQ=9!c zf)U^)NOHp`wz>s|8Z~!a;SJJVYT@4~XekU;DoWAXrdO3K3W%-VT5F`yqpFcA2k}Tp z=S9bH1YS|R*nZxo-EddgXPwc@dmhn$n^U#27K}V%Sw9@y{_5L?vpmh8yTX%vB>n!% zu1xdFTRQf$bYf)W%lN)mP0#6(3_j5}DK>&(9+F09;LJY=c#CtL)ol(M z%4A!4^4V&qYMm8iMgh0z{p+Uqv|sx>lvx4hS7&6U78fL?(w~X~dda93npr{lf1%~S z!GU)j4cyyo&IA2hTzOyP#J7mP_22R#{F7rU!`0NEb%PTuIQXKUWrzKn!oh`f?`&`7 z7rzN32gQA!?ZNYy|7RU`>90JAfLv$6ytKsDRBq4NMqiEgX$urki0OVEMNsEVJp6P# ztGU}-Mi7!09cy~ueONU$gTeV09-YJ=QMaqEt2QVq$kTB-gzxMOli2T){yQEWrHr)c zO=Y-z#mJ0D@7muIPQJ5qsw%?r(OxS|VID$s-&2TBwx5EJ$MB=1>aRLkPdj;fCn)@l zf+LzTJ8xgnJv_c0M;A`V9% zi9D)Zd+?@1bJ)r+#xh)+$09ntxq|Qhq^g~bH-emz`qBG+aF2K9M-;lZlc;l zfmhkXzL92)6ZXjzR~x7D+{uxcY36TfDwUWl2WI-NMuwDseo=#bj~)C~aXZ~cDy5Wruf38WqU@q^jw@Lb!q#zB!2h09WgOSI}58R3RmpG~?9C3WW}%FnDV z>DyPkShIg!U_e7tj%-p+A0*C?4@88DI2;^? zr=1SLkw3sP-i7KZQaAbsaFLS}dn{f;T^&DTlKS5uLX4lE$V?7qmc{a-?A>B@Nj_a% zgbh_rOyGCgSN23<%d?oo#SX(}^HuGxVdqK6}*Sid=a-gUj#TWc|;+$9h#R{larfQ3y4YJ;;@ zFLphkB1f&wzNFoKNC!Fi`JC`?o9SO$(@KT7Iyy{W(wi_*QNtYhm?01`mEQuaZw|ll zcuC2`N!Zybo$n_kw4@5Sd8C81OnH4{z?|fFbWr?%S}ZRC=N9iw^*SlApj7tt<->xp zT@<@mt6KO}1+6qAix14wibGxsna!Z)8zx6HqJ8(5$)bQ_>3MMQUEP3uIa=6|=HkQL zheq!Sj;JCZ5S4%b`>X{kYp~?&;&*JO zHnzX5iTO^}@r0G2u<4%2u8xgHt@&yh>~M#_>!3#Gqu|NE2Jd2Aw*MJ#^wSJkt*sYQ zQkk)T?p4rc-sE%JBjL-?jN9XJ-oW}Uc-?_&-Wt){D}b&iFPQ-lz~w8okE^6YH^gdc zTVj>U_D?#NI~YHH2nB^8WOWH&Kh)mdq_Q(PUhGiXF2BX((L*&g?Oo4_K&xw{<2UKF zCKk95YQ0%AESfTTr|><Ru5v=%Y{b$I`lKaPC^1o2V zP{yrS=GLbzaDmA{M*+acu?cuH$;otpi@-}5wKAnOt2j0$=B37ePdNNn!2~^F-Fs3kdOz-yEZdsvXRsrd?=r@&36xyM7WL zb+5mNKinm1EcAM16XxC)>5crq$Vt|ae}8(NERoL4?;YY>B7Q8m`MN<(gfmq8Ytdqh zm3I);YyL)0_B|G(-q7nMiP1o)A^|@_x@Aw8C{7D^kEtSLkYQjp5Hs9_WP`#sxvAxw3P~Gv;_yL!Cx*Z2!5Lr@NC;1m3+jwE&Ef({IK1Ff4ZGY@Zi=C z`OtiZ^!?wz>FmK((cWCC87@z@Ct{MAfZ@!T@Xp`U+3cLyf&~g4cV94UU-O`Nr7t$Y zE0^m>nXopG7GJ#xSBxDGe&_K&lskD{T7d{n^hM)aSU%m?-#~=!Wn$Ywnc*};ui5%w zl3;?>Yey1+<cd4l{PUU)~ z*B2AgurY5_MJq@oc-%%70%Q-6$JP5R3VdMJ4P9&Tp_$I-U_!=_I`CbAvW@)QO;=q# zBkU(oqLh(P+OR=IAWFl>e^2c%a8VdJ)@y9~SF)M+N!a$!{3N4dkpK?z1U{uSQ3!z@ z3SI$g_fLt;o&;?9w29_#x3pWdLp|#ZaT3RseLF>Co^Kz$n*H|d>h@fe7ldyHJ)VMV z3jds3ey(I^wk42uAc<*i6yi^lpIra@)(cA_;O@PpnJEUR6J>APHR%~oZ7cj#PR=`{ zdW^YL0`Q+Nt&SAoLifx{%sS)WY0rmv0rQ@XU&PUcK=f^8M?gmq; zk0V4R&+_8de1L*`RQ#TR%>vDR!A1GKWB%KaYf(X9IMtLka6DV~k|q)q%xK6EQ3iUw z{PYx#%AtmHwJnpm3agK6A# z%NTb5JGOUYV$IDQ21VI6JxCk&3z6ZS;(W}C)7ja!ey9b1ZG6D5^az8A))x3dG_u|# z)bh%X(A^2AJ(At&>>XFrgQjE3!*3R8ai|X+=nyVNmb6Bjl#S;8I`$W}zSs17C4byy z;-+2&iKY;o7OTn;>v;zh~oCFKHa46g@4Osl}=oR54Aqtzp?G+&xF0RRZD6seJFaD_3 zsPNQ(Q^&SE*Fw-K%}z}RZoeFxK@Quunuq#RlY{&l{fGMIh#24S;8MwEP2Qz85S%vN zY)!*wKp|L=N|x~exa-}BgR82XQs>3_(fotx^f53;mdZnJOGcLPx5by-mMknU2-!x( zg3WlVBV@GK+aGmFTbijE?H*?d<}k3wO02x)_f&OUjfi!kz1dN(dz|8@jL8RY@e5en z!DZS28Yp0oq3o(=%?Z4!9?rVVRnxy);eU!)`=D;w+rIo-h@6pKHVhd9g=YbJ+Z7#? zg;~-jf^lUy2QxvDm{bDEytjB)FO>lPjCdBzy*2TJ7=_VY;n75MLY>eMjo*xAZ+{Xl z%RiAqj3@FHwO#B{V@KXDegAk{w3%9E2hGKZ`jPr?ATkSaC0{JA4pWsyFRAS1>pC}L z|F2J+pJNGQz%s;q1oV_}mO9?#be(af6(K}r3E+Y?G25syAMNQ`T?DHSea2Wc(e(!O7Wa}~zQH3xUG=;56H6ucB?eD}2Od}9jh-R$b zEbZbacBU`OU*e+X=}c#~Ol}%)Y>54L*ihyijt8mXX-$_y?yKGe5ZTW=6T$lnV6=%m z`aD?QR8miGd#w9M*xk;bWRNV2-Sn-dw%Q1QClwui|2a|bCz@Mvsw#7sTw32CAgo9G z9QXWwg>B5p*jb-!SJ}bNq?t`2LN-sQ)V*cWrSfn&?YVPeVyU-4gsPy>9dds~0UkTD zZ8+rd6>ub1dVV3EnZVxY96?`RY{bn+KsVh_Wxvt0W_0GUZHE!`pmg4Nr!%L}n$sdh z_J48)zjrJYGK+_IjcrHv7QH}C$1o`OUd_PR zMKn2#I=AL{B&7^)b|R4Z1`2|*M+yoGL^QNsV4){ZKz!SD9?(Rmq-^A_^U0oUG4#9C z0HWA)Z@}|)fZ1Ai6eRHR{(8OTdZ}xwRO|Ggo`ahUY80rPuH&6NLYAlxCa<4T@|f_T ztxQcNAm(?51!p_B35kf1nE|EP%Bq<8a%bRfe3=r{4c)%zO=4LYbMwtwbYxUiM<5i; z$seZ5cI(>Ta_f$KRhDCvD5OFJV`F2f!ah7m$jI{>$=|+3F}yDzr>2JO3PSLP&rIrb zzz(Wk1H?>BC_q;(k~rH6)xdw*F?IPQ+;Z(R(2 zebZ%A+47HZvBrE*MO{5q1J(@hYtC?;}MtnZBmqbq{N-cK~vT};67}YqvV#gx`@GnVj=K3+1c3|jb7(l zwfr7S&0gi+DG}&oy@|?iXBmesb|>PKlW7{>+DupU6ey;j+-_&(m6RZ9XlUF#oR6ID z7G|w=p^LayI)Qm(zY?7vtHHnNL}p!ixINcybY*}?BaQ?@?u;#uC0E)OS1>ss*~rPs zvo+r0MZ>MGuCk>MK_D^G6I)9R5PBRWzKmfW^E!)%o70=i%7B=GM7lbGR*z%D=Bqgy zKF5{7zQZeAzg>s;$i|2yQhGA8-FC2k@$vCN{*QOuWP^i)Hi;GW^#roAvUagOeSN%b zJOn6wo+sqsu@K>kk==Ba{MLE?M)VIH+!;k zaB`{|8pe7oc@-|2%#@TcmKnAXnwy)`Gck4TO_f%E93o`asrkV_bhbHo+DqiHvJOf( z%*|;S85yf=rdbreaY#A)`9Ga!t%E7;{gccTpO_f3w`Xk&{KztJET`l0tOH{o0M`AI zHG>AB47~E6-2Y{3VQ!w!=ddKi&djW!AS;V${p;;5X_KS43}NWJ+;c6Vc0v6?$e%e z=k9bixY#%zx1@tyUX7Z@@A&I(llM$rbv4xXuwS6h(JhfWqg~2Z#k2RtzX*7bJZ64w zGb}ju?TLXe*MjzIpB&rU#HxDvf9?U=urs=+1Rw}9m|WJ{~_%E5J3J3P2pP&c*K{Pkulb6 zxs^<`Se=Uhb}ap?s;Uz)14CRLzkRLd+Ru@r?rbrU?#be&Y|V(g8V>Al-`b>2*FqqH zX=%0x3tl3gU@cmOcS?o$S4a8h8{0cAHG(N#vcfQDlxp0CWs3A)z8yINBq_!=uEU?3)*MBxkx%G=H3e#~lmwC}yHC zAYhQg+PcPs?Uw=h#?7e_1^1=wXM$6K;9&UnWurKd`=|084sLOM`{qE&V8x=QMjFx9 zMyjfs7oYhgq?F-(AHE<|nl5M#3meK?cq-{&e z>EP^kFh`x=IFDro+J1ZpXlm(8N}`)1mY4S_7^>dcaVjbwYA}CYTRS_tdsoYEsNY<; zD5S^8B=~u9@?R4k4Yh)dx%qx=rf@lE@8Vdbw5!=ZzphrRa6cj~?VRN6w3Z`cN`D^? zu3t18zp{%(7T+Ja&nQlx}s!ZvD5^8V;4z-^ay;v!WcJR(Jms8UHDC z-rnc*>-N6uqcKkkIepRP7R*N%+4Nt$tsQc>SR9C;z0gn;dp99AHYo5O7NKw{*B}1x zcdx3&Ko*(B1qO+nlk<9%?CaXP-Dg(}IeBz%{gkCpKpVW>I_+aM>wvBvnl_8uTw7?k zc4(~XbgQoRSRc<C{OEF8|r=hG)AT{0gA zj={T^8BOKhCs1dMVfMPh0ghMN&JK-MVTVY5o}c)m@6#B-}jmnoQ zB4jWLci9<&ZP5t{epU1P#0dcI(ow;&t>Nb8CZG2OJtGrS z4qzGa@gtnpd&TnC0xXPHVn}%9gDhc*>;!?Z2pQyzBA_6PqUl1#etc?=89_OHB_QTV7k)t9=-2f7m|>~2TJ2}079?&tgch{jy%+uB6s%@RV=uA$ zPi^&t!1QMAyToJn5^DZz)=HF8d7zObp6uhIo#MNzNa;Dhbu)J6eu1F-(L&@9P+S;i~6v|cS}#G)zm_kWnel2G3;c-%#ra-}vuaxm=YO4j&v{9%1@Wi6 ziVCuo%dp5gr6lZqYGm-`8f}nR1~XE90CI-hK9F_Vy_qAA^7AVxyIZD#OxNoz(N`{B zOh5;4ie}$Gv!2iwg?5z1=EUG|cpV5BjS1lq5mdp~NW+|SUEhwpX=%ZAl54%+|8-x* zz_Z?EZ!lX%My4)c1a0hUYnw4SrRkn43;n1XErAtj<(_5?HR{^Bxw&0#6$*txBfCPs zg{?a&DJfCg8v%cJX_?j6*Sl2TG`UoD5Rx>Bv$`?Skrd1tBa%pt6iO>Fpmr->Ku%3e zOsuG^vIR0 zK!5=_bSEAV^ly27)Y)62PJHkT}#Pw(q}oo?y#J`%O%mcJiE{7EN$M$TE9Pw4OBD zD4h}nWi)udf4XcW1{Lhf=c!HI-d%m#Qx8{G4qKfxnVy;17miY zrO_r1`wkO8qyy)b^{$vsr>AZ7=IZk&I;mn>&?U&W@j8aG`%*?$Hf*LxX?k{+27FGR z^cf{+idyH*$<04G=bf38QvrBaR$CiVXKi7TYL$;IM!Gi4btD}C_Q)8R|3q_Sbl_$h z8qf#?BB@Rjfhe!6L@q2#Kt~D2dAJxCpvHm827tH?T^YY%Z)c|{eD&&;mVtq5P*4yU zu?-JzXb2o5N^(Y+BtIa|yL);*(Vc5E^YZ8cBMtLQV=ND~5O43&nVu)IA61o={UpO6 z!Z+O{sfYc*eE@U<4t#br@3%SZEAn z*MWJ36#0CAbZ#??b&EN2a1r=u&9J`*1rKUz{abA4`HL6FdI6H_7QstE{W}(m&CJgB z@!>Blpz;*d)EKgwR+biV!;9g1`ubEcpOBDRAdnSSHzne@(%ks{t5IwopMS2-h`gpz z^z7XYGgB_#ko-~C&5t=^@8neWvt!j9nBH0x+oi@cB{(>^ z1XaSwT0Vd~M7KC1FOQ&hK2J}VQ89|L`zh6=yu2J6GGYJlfe2{JKfayuI=ma0k6-ESh;qCN3a>o+R`%G5Oo ziVctN=%-cdpmg&MJjCH;xbJYhp=dh{YGa&8i-||tB<&AgO+_`qLSL>3Qk2smsI`Q! zD~`66_qiRppQ4F123|fsB-iMyl}2vg*0wK*AELZfeEK-3PaGQeR(Q)EKYH-9HSg3Y zA=?Gz@Nho~f_8|>t(+DultQag!eg@~5$K!zLF>A`)BL5)hij1_djV`_CRUfKF5XD^ E2Z?O))c^nh diff --git a/doc/reference/cogl/Makefile.am b/doc/reference/cogl/Makefile.am deleted file mode 100644 index a1c78d8da..000000000 --- a/doc/reference/cogl/Makefile.am +++ /dev/null @@ -1,130 +0,0 @@ -## Process this file with automake to produce Makefile.in - -# We require automake 1.6 at least. -AUTOMAKE_OPTIONS = 1.6 - -# This is a blank Makefile.am for using gtk-doc. -# Copy this to your project's API docs directory and modify the variables to -# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples -# of using the various options. - -# The name of the module, e.g. 'glib'. -DOC_MODULE=cogl - -# The top-level SGML file. You can change this if you want to. -DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.xml - -# The directory containing the source code. Relative to $(srcdir). -# gtk-doc will search all .c & .h files beneath here for inline comments -# documenting the functions and macros. -# e.g. DOC_SOURCE_DIR=../../../gtk -DOC_SOURCE_DIR=../../../cogl - -# Extra options to pass to gtkdoc-scangobj. Not normally needed. -SCANGOBJ_OPTIONS=--type-init-func="g_type_init()" - -# Extra options to supply to gtkdoc-scan. -# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" -SCAN_OPTIONS=--deprecated-guards="COGL_DISABLE_DEPRECATED" - -# Extra options to supply to gtkdoc-mkdb. -# e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml -MKDB_OPTIONS=--sgml-mode --output-format=xml --name-space=muffin-cogl - -# Extra options to supply to gtkdoc-mktmpl -# e.g. MKTMPL_OPTIONS=--only-section-tmpl -MKTMPL_OPTIONS= - -# Extra options to supply to gtkdoc-fixref. Not normally needed. -# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html -FIXXREF_OPTIONS=\ - --extra-dir=$(GLIB_PREFIX)/share/gtk-doc/html/glib \ - --extra-dir=$(GDKPIXBUF_PREFIX)/share/gtk-doc/html/gdk-pixbuf - -# Used for dependencies. The docs will be rebuilt if any of these change. -# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h -# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c -HFILE_GLOB=\ - $(top_srcdir)/cogl/cogl/*.h \ - $(top_builddir)/cogl/cogl/*.h \ - $(top_srcdir)/cogl/cogl/winsys/*.h -CFILE_GLOB=$(top_srcdir)/cogl/cogl/*.c - -# Header files to ignore when scanning. -# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h -cogl_private_headers := \ - $(shell cd $(top_srcdir)/cogl && echo *-private.h && cd - && \ - cd $(top_srcdir)/cogl/cogl/winsys && echo *-private.h && cd -) - -IGNORE_HFILES=\ - driver \ - tesselator \ - cogl.h \ - $(cogl_private_headers) \ - cogl-atlas.h \ - cogl-bitmap-packing.h \ - cogl-bitmask.h \ - cogl-blend-string.h \ - cogl-blit.h \ - cogl-boxed-value.h \ - cogl-clip-stack.h \ - cogl-debug.h \ - cogl-debug-options.h \ - cogl-defines.h \ - cogl-driver.h \ - cogl-enum-types.h \ - cogl-flags.h \ - cogl-gles2-types.h \ - cogl-gl-header.h \ - cogl-glsl-shader-boilerplate.h \ - cogl-profile.h \ - cogl-rectangle-map.h \ - cogl-spans.h \ - cogl-texture-driver.h \ - cogl-util.h \ - $(NULL) - -EXTRA_HFILES= - -# Images to copy into HTML directory. -# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png -HTML_IMAGES = \ - fill-rule-non-zero.png \ - fill-rule-even-odd.png \ - quad-indices-order.png \ - quad-indices-triangles.png \ - cogl_ortho.png - -# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). -# e.g. content_files=running.sgml building.sgml changes-2.0.sgml -content_files = \ - blend-strings.xml - -# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded -# These files must be listed here *and* in content_files -# e.g. expand_content_files=running.sgml -expand_content_files = \ - blend-strings.xml - -# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library. -# Only needed if you are using gtkdoc-scangobj to dynamically query widget -# signals and properties. -# e.g. AM_CPPFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) -# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) - -AM_CPPFLAGS = -I$(top_srcdir) \ - -I$(top_builddir)/cogl \ - -DCOGL_ENABLE_EXPERIMENTAL_API \ - -DCOGL_ENABLE_EXPERIMENTAL_2_0_API \ - -DCOGL_ENABLE_MUFFIN_API \ - $(COGL_DEP_CFLAGS) -GTKDOC_LIBS = $(top_builddir)/clutter/clutter/libmuffin-cogl-0.la $(COGL_DEP_LIBS) - -include $(top_srcdir)/gtk-doc.make - -EXTRA_DIST = - -# Other files to distribute -# e.g. EXTRA_DIST += version.xml.in - -EXTRA_DIST += $(HTML_IMAGES) $(content_files) diff --git a/doc/reference/cogl/blend-strings.xml b/doc/reference/cogl/blend-strings.xml deleted file mode 100644 index 421ab2353..000000000 --- a/doc/reference/cogl/blend-strings.xml +++ /dev/null @@ -1,129 +0,0 @@ - - -]> - - - -Blend Strings -3 -COGL Library - - - -Blend Strings -A simple syntax and grammar for describing blending and texture -combining functions. - - - -Cogl Blend Strings - -Describing GPU blending and texture combining states is rather awkward to do -in a consise but also readable fashion. Cogl helps by supporting -string based descriptions using a simple syntax. - - -
-Some examples - -Here is an example used for blending: - -"RGBA = ADD (SRC_COLOR * (SRC_COLOR[A]), DST_COLOR * (1-SRC_COLOR[A]))" - -In OpenGL terms this replaces glBlendFunc[Separate] and -glBlendEquation[Separate] - -Actually in this case it's more verbose than the GL equivalent: - - -glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - -But unless you are familiar with OpenGL or refer to its API documentation -you wouldn't know that the default function used by OpenGL is GL_FUNC_ADD -nor would you know that the above arguments determine what the source color -and destination color will be multiplied by before being adding. - - -Here is an example used for texture combining: - -"RGB = REPLACE (PREVIOUS)" -"A = MODULATE (PREVIOUS, TEXTURE)" - - -In OpenGL terms this replaces glTexEnv, and the above example is equivalent -to this OpenGL code: - - - glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); - glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE); - glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS); - glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); - glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE); - glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS); - glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_COLOR); - glTexEnvi (GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE); - glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_COLOR); - - -
- -
-Here's the syntax - - -<statement>: - <channel-mask>=<function-name>(<arg-list>) - - You can either use a single statement with an RGBA channel-mask or you can use - two statements; one with an A channel-mask and the other with an RGB - channel-mask. - -<channel-mask>: - A or RGB or RGBA - -<function-name>: - [A-Za-z_]* - -<arg-list>: - <arg>,<arg> - or <arg> - or "" - - I.e. functions may take 0 or more arguments - -<arg>: - <color-source> - 1 - <color-source> : Only intended for texture combining - <color-source> * ( <factor> ) : Only intended for blending - 0 : Only intended for blending - - See the blending or texture combining sections for further notes and examples. - -<color-source>: - <source-name>[<channel-mask>] - <source-name> - - See the blending or texture combining sections for the list of source-names - valid in each context. - - If a channel mask is not given then the channel mask of the statement - is assumed instead. - -<factor>: - 0 - 1 - <color-source> - 1-<color-source> - SRC_ALPHA_SATURATE - - -
- - -
- - -
diff --git a/doc/reference/cogl/cogl-docs.xml.in b/doc/reference/cogl/cogl-docs.xml.in deleted file mode 100644 index 7bb8a9168..000000000 --- a/doc/reference/cogl/cogl-docs.xml.in +++ /dev/null @@ -1,226 +0,0 @@ - - -]> - - - - Cogl 2.0 Reference Manual - for Muffin Cogl - - - 2008 - OpenedHand LTD - - - - 2009 - 2010 - 2011 - 2012 - 2013 - Intel Corporation - - - - - Permission is granted to copy, distribute and/or modify this - document under the terms of the GNU Free - Documentation License, Version 1.1 or any later - version published by the Free Software Foundation with no - Invariant Sections, no Front-Cover Texts, and no Back-Cover - Texts. You may obtain a copy of the GNU Free - Documentation License from the Free Software - Foundation by visiting their Web site or by writing - to: - -
- The Free Software Foundation, Inc., - 59 Temple Place - Suite 330, - Boston, MA 02111-1307, - USA -
-
-
- -
- - - Cogl - a modern 3D graphics API - -
- About Cogl - - Cogl is a modern 3D graphics API with associated utility - APIs designed to expose the features of 3D graphics hardware - using a more object oriented design than OpenGL. The library has - primarily been driven by the practical needs of Clutter but it - is not tied to any one toolkit or even constrained to developing - UI toolkits. - -
- -
- General API concepts - - - -
- -
- Setting Up A Drawing Context - - - -
- -
- Setting Up A GPU Pipeline - - - - -
- -
- Allocating GPU Memory - - - -
- -
- Describing the layout of GPU Memory - - -
- -
- Geometry - - -
- -
- Textures - - -
- -
- Meta Textures - - - - -
- -
- Primitive Textures - - - - -
- -
- Framebuffers - - - -
- -
- Utilities - - - - - - - - -
- -
- Binding and Integrating - - - -
- -
- - - Glossaries - - - - - - Index of all symbols - - - - - Index of deprecated symbols - - - - - Index of new symbols in 0.8 - - - - - Index of new symbols in 1.0 - - - - - Index of new symbols in 1.2 - - - - - Index of new symbols in 1.4 - - - - - License - - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General - Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) - any later version. - - - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for - more details. - - - - You may obtain a copy of the GNU Library General - Public License from the Free Software Foundation by - visiting their Web - site or by writing to: - -
- Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307 - USA -
-
-
- -
diff --git a/doc/reference/cogl/cogl-sections.txt b/doc/reference/cogl/cogl-sections.txt deleted file mode 100644 index 7f13ac09b..000000000 --- a/doc/reference/cogl/cogl-sections.txt +++ /dev/null @@ -1,938 +0,0 @@ -
-cogl-object -The Object Interface -CoglObject -cogl_object_ref -cogl_object_unref -CoglUserDataKey -CoglUserDataDestroyCallback -cogl_object_get_user_data -cogl_object_set_user_data -
- -
-cogl-error -Exception handling -CoglError -cogl_error_matches -cogl_error_free -cogl_error_copy -COGL_GLIB_ERROR -
- -
-cogl-types -Common Types - -CoglVertexP2 -CoglVertexP3 -CoglVertexP2C4 -CoglVertexP3C4 -CoglVertexP2T2 -CoglVertexP3T2 -CoglVertexP2T2C4 -CoglVertexP3T2C4 -CoglVerticesMode - - -CoglFuncPtr -CoglPixelFormat -CoglBufferTarget -CoglBufferBit -CoglAttributeType -CoglColorMask - - -CoglTextureFlags - - -CoglBool -
- -
-cogl-renderer -CoglRenderer: Connect to a backend renderer - -CoglRenderer -cogl_is_renderer - - -cogl_renderer_new -cogl_renderer_get_n_fragment_texture_units -cogl_renderer_connect - - -CoglWinsysID -cogl_renderer_set_winsys_id -cogl_renderer_get_winsys_id -CoglRendererConstraint -cogl_renderer_add_constraint -cogl_renderer_remove_constraint - - -cogl_xlib_renderer_set_foreign_display -cogl_xlib_renderer_get_foreign_display - - -CoglXlibFilterFunc -CoglFilterReturn -cogl_xlib_renderer_add_filter -cogl_xlib_renderer_remove_filter -cogl_xlib_renderer_handle_event - -
-cogl-onscreen-template -CoglOnscreenTemplate: Describe a template for onscreen framebuffers - -CoglOnscreenTemplate -cogl_is_onscreen_template - - -cogl_onscreen_template_new -cogl_onscreen_template_set_swap_throttled -cogl_onscreen_template_set_samples_per_pixel -
- -
-cogl-display -CoglDisplay: Setup a display pipeline - -CoglDisplay -cogl_is_display - - -cogl_display_new -cogl_display_get_renderer -cogl_display_setup - - -cogl_wayland_display_set_compositor_display -
- -
-cogl-context -The Top-Level Context - - -CoglContext -cogl_is_context -cogl_context_new -cogl_context_get_display - - -CoglFeatureID -cogl_has_feature -cogl_has_features -CoglFeatureCallback -cogl_foreach_feature - - -CoglReadPixelsFlags - - -COGL_TYPE_ATTRIBUTE_TYPE -COGL_TYPE_BLEND_STRING_ERROR -COGL_TYPE_BUFFER_ACCESS -COGL_TYPE_BUFFER_TARGET -COGL_TYPE_BUFFER_UPDATE_HINT -COGL_TYPE_BUFFER_USAGE_HINT -COGL_TYPE_DEBUG_FLAGS -COGL_TYPE_DRIVER_ERROR -COGL_TYPE_INDICES_TYPE -COGL_TYPE_PIXEL_FORMAT -COGL_TYPE_READ_PIXELS_FLAGS -COGL_TYPE_TEXTURE_FLAGS -COGL_TYPE_VERTICES_MODE - - -COGL_DRIVER_ERROR -CoglDriverError -cogl_attribute_type_get_type -cogl_buffer_bit_get_type -cogl_buffer_target_get_type -cogl_debug_flags_get_type -cogl_driver_error_get_type -cogl_indices_type_get_type -cogl_pixel_format_get_type -cogl_read_pixels_flags_get_type -cogl_shader_type_get_type -cogl_texture_flags_get_type -cogl_vertices_mode_get_type -COGL_AFIRST_BIT -COGL_A_BIT -COGL_BGR_BIT -COGL_PREMULT_BIT -
- -
-cogl-poll -Main loop integration -CoglPollFDEvent -CoglPollFD -cogl_poll_renderer_get_info -cogl_poll_renderer_dispatch -cogl_glib_source_new -cogl_glib_renderer_source_new -
- -
-cogl-attribute -Vertex Attributes -CoglAttribute -cogl_attribute_new -cogl_is_attribute -cogl_attribute_set_normalized -cogl_attribute_get_normalized -cogl_attribute_get_buffer -cogl_attribute_set_buffer -
- -
-cogl-indices -Indices - - -CoglIndices -cogl_is_indices - - -CoglIndicesType -cogl_indices_new - - -cogl_get_rectangle_indices -
- -
-cogl-primitive -Primitives -CoglPrimitive -cogl_primitive_new -cogl_primitive_new_with_attributes -cogl_primitive_new_p2 -cogl_primitive_new_p3 -cogl_primitive_new_p2c4 -cogl_primitive_new_p3c4 -cogl_primitive_new_p2t2 -cogl_primitive_new_p3t2 -cogl_primitive_new_p2t2c4 -cogl_primitive_new_p3t2c4 -cogl_is_primitive -cogl_primitive_get_first_vertex -cogl_primitive_set_first_vertex -cogl_primitive_get_n_vertices -cogl_primitive_set_n_vertices -cogl_primitive_get_mode -cogl_primitive_set_mode -cogl_primitive_set_attributes -cogl_primitive_get_indices -cogl_primitive_set_indices -cogl_primitive_copy -CoglPrimitiveAttributeCallback -cogl_primitive_foreach_attribute -cogl_primitive_draw -
- -
-cogl-snippet -Shader snippets -CoglSnippet -CoglSnippetHook -cogl_snippet_new -cogl_snippet_get_hook -cogl_is_snippet -cogl_snippet_set_declarations -cogl_snippet_get_declarations -cogl_snippet_set_pre -cogl_snippet_get_pre -cogl_snippet_set_replace -cogl_snippet_get_replace -cogl_snippet_set_post -cogl_snippet_get_post -
- -
-cogl-paths -Path Primitives -CoglPath -cogl_is_path -cogl_path_new -cogl_path_copy -cogl_path_move_to -cogl_path_close -cogl_path_line_to -cogl_path_curve_to -cogl_path_arc -cogl_path_rel_move_to -cogl_path_rel_line_to -cogl_path_rel_curve_to -cogl_path_line -cogl_path_polyline -cogl_path_polygon -cogl_path_rectangle -cogl_path_round_rectangle -cogl_path_ellipse - - -CoglPathFillRule -cogl_path_set_fill_rule -cogl_path_get_fill_rule -
- -
-cogl-bitmap -Bitmap - - -CoglBitmap -cogl_is_bitmap - - -cogl_bitmap_new_from_file -cogl_bitmap_new_from_buffer -cogl_bitmap_new_with_size -cogl_bitmap_new_for_data - - -cogl_bitmap_get_format -cogl_bitmap_get_width -cogl_bitmap_get_height -cogl_bitmap_get_rowstride -cogl_bitmap_get_buffer -cogl_bitmap_get_size_from_file - - -cogl_texture_new_from_bitmap - - -COGL_BITMAP_ERROR -CoglBitmapError -
- -
-cogl-texture -The Texture Interface -CoglTexture -cogl_is_texture - - -COGL_TEXTURE_ERROR -CoglTextureError - - -cogl_texture_allocate -cogl_texture_get_width -cogl_texture_get_height -cogl_texture_is_sliced -cogl_texture_get_data -cogl_texture_set_data -cogl_texture_set_region -CoglTextureType -CoglTextureComponents -cogl_texture_set_components -cogl_texture_get_components -cogl_texture_set_premultiplied -cogl_texture_get_premultiplied - - -COGL_TEXTURE_MAX_WASTE -
- -
-cogl-texture-2d -2D textures - - -CoglTexture2D -cogl_is_texture_2d - - -cogl_texture_2d_new_with_size -cogl_texture_2d_new_from_file -cogl_texture_2d_new_from_bitmap -cogl_texture_2d_new_from_data -cogl_texture_2d_gl_new_from_foreign -
- -
-cogl-texture-rectangle -Rectangle textures (non-normalized coordinates) -CoglTextureRectangle -cogl_texture_rectangle_new_with_size -cogl_texture_rectangle_new_from_bitmap -cogl_is_texture_rectangle -
- -
-cogl-texture-3d -3D textures -CoglTexture3D -cogl_texture_3d_new_with_size -cogl_texture_3d_new_from_bitmap -cogl_texture_3d_new_from_data -cogl_is_texture_3d -
- -
-cogl-meta-texture -High Level Meta Textures -CoglMetaTexture -CoglMetaTextureCallback -cogl_meta_texture_foreach_in_region -
- -
-cogl-primitive-texture -Low-level primitive textures -CoglPrimitiveTexture -cogl_is_primitive_texture -cogl_primitive_texture_set_auto_mipmap -
- -
-cogl-sub-texture -Sub Textures -CoglSubTexture -cogl_sub_texture_new -cogl_is_sub_texture -
- -
-cogl-atlas-texture -Atlas Textures -CoglAtlasTexture -cogl_atlas_texture_new_with_size -cogl_atlas_texture_new_from_file -cogl_atlas_texture_new_from_data -cogl_atlas_texture_new_from_bitmap -cogl_is_atlas_texture -
- -
-cogl-texture-2d-sliced -Sliced Textures -CoglTexture2DSliced -cogl_texture_2d_sliced_new_with_size -cogl_texture_2d_sliced_new_from_file -cogl_texture_2d_sliced_new_from_data -cogl_texture_2d_sliced_new_from_bitmap -cogl_is_texture_2d_sliced -
- -
-cogl-texture-pixmap-x11 -X11 Texture From Pixmap - -CoglTexturePixmapX11 -cogl_is_texture_pixmap_x11 - - -cogl_texture_pixmap_x11_new - - -cogl_texture_pixmap_x11_update_area -cogl_texture_pixmap_x11_is_using_tfp_extension -CoglTexturePixmapX11ReportLevel -cogl_texture_pixmap_x11_set_damage_object -
- -
-cogl-framebuffer -CoglFramebuffer: The Framebuffer Interface -CoglFramebuffer -COGL_FRAMEBUFFER -cogl_framebuffer_allocate -cogl_framebuffer_get_width -cogl_framebuffer_get_height -cogl_framebuffer_set_viewport -cogl_framebuffer_get_viewport_x -cogl_framebuffer_get_viewport_y -cogl_framebuffer_get_viewport_width -cogl_framebuffer_get_viewport_height -cogl_framebuffer_get_viewport4fv -cogl_framebuffer_get_red_bits -cogl_framebuffer_get_green_bits -cogl_framebuffer_get_blue_bits -cogl_framebuffer_get_alpha_bits -cogl_framebuffer_get_depth_bits -cogl_framebuffer_get_color_mask -cogl_framebuffer_set_color_mask -cogl_framebuffer_get_samples_per_pixel -cogl_framebuffer_set_samples_per_pixel -cogl_framebuffer_resolve_samples -cogl_framebuffer_resolve_samples_region -cogl_framebuffer_get_context -cogl_framebuffer_clear -cogl_framebuffer_clear4f -cogl_framebuffer_read_pixels_into_bitmap -cogl_framebuffer_read_pixels -cogl_framebuffer_set_dither_enabled -cogl_framebuffer_get_dither_enabled - - -cogl_framebuffer_draw_rectangle -cogl_framebuffer_draw_textured_rectangle -cogl_framebuffer_draw_multitextured_rectangle -cogl_framebuffer_draw_rectangles -cogl_framebuffer_draw_textured_rectangles -cogl_framebuffer_stroke_path -cogl_framebuffer_fill_path - - -cogl_framebuffer_discard_buffers -cogl_framebuffer_finish - - -cogl_framebuffer_push_matrix -cogl_framebuffer_pop_matrix -cogl_framebuffer_identity_matrix -cogl_framebuffer_scale -cogl_framebuffer_translate -cogl_framebuffer_rotate -cogl_framebuffer_rotate_euler -cogl_framebuffer_rotate_quaternion -cogl_framebuffer_transform -cogl_framebuffer_get_modelview_matrix -cogl_framebuffer_set_modelview_matrix - - -cogl_framebuffer_perspective -cogl_framebuffer_frustum -cogl_framebuffer_orthographic -cogl_framebuffer_get_projection_matrix -cogl_framebuffer_set_projection_matrix - - -cogl_framebuffer_push_scissor_clip -cogl_framebuffer_push_rectangle_clip -cogl_framebuffer_push_path_clip -cogl_framebuffer_push_primitive_clip -cogl_framebuffer_pop_clip -
- -
-cogl-onscreen -CoglOnscreen: The Onscreen Framebuffer Interface - -CoglOnscreen -cogl_is_onscreen -COGL_ONSCREEN - - -cogl_onscreen_new - - -CoglOnscreenX11MaskCallback -cogl_x11_onscreen_set_foreign_window_xid -cogl_x11_onscreen_get_window_xid -cogl_x11_onscreen_get_visual_xid - - -cogl_onscreen_show -cogl_onscreen_hide - - -CoglFrameCallback -CoglFrameClosure -cogl_onscreen_add_frame_callback -cogl_onscreen_remove_frame_callback - - -CoglOnscreenDirtyInfo -CoglOnscreenDirtyCallback -CoglOnscreenDirtyClosure -cogl_onscreen_add_dirty_callback -cogl_onscreen_remove_dirty_callback - - -CoglOnscreenResizeCallback -CoglOnscreenResizeClosure -cogl_onscreen_add_resize_callback -cogl_onscreen_remove_resize_callback - - -cogl_onscreen_swap_buffers -cogl_onscreen_swap_buffers_with_damage -cogl_onscreen_swap_region -cogl_onscreen_set_swap_throttled -
- -
-cogl-offscreen -Offscreen Framebuffers - -CoglOffscreen -cogl_is_offscreen - - -cogl_offscreen_new_with_texture -
- -
-cogl-color -Color Type -CoglColor -cogl_color_copy -cogl_color_free -cogl_color_init_from_4ub -cogl_color_init_from_4f -cogl_color_init_from_4fv - - -cogl_color_get_red -cogl_color_get_green -cogl_color_get_blue -cogl_color_get_alpha - - -cogl_color_get_red_byte -cogl_color_get_green_byte -cogl_color_get_blue_byte -cogl_color_get_alpha_byte - - -cogl_color_get_red_float -cogl_color_get_green_float -cogl_color_get_blue_float -cogl_color_get_alpha_float - - -cogl_color_set_red -cogl_color_set_green -cogl_color_set_blue -cogl_color_set_alpha - - -cogl_color_set_red_byte -cogl_color_set_green_byte -cogl_color_set_blue_byte -cogl_color_set_alpha_byte - - -cogl_color_set_red_float -cogl_color_set_green_float -cogl_color_set_blue_float -cogl_color_set_alpha_float - - -cogl_color_premultiply -cogl_color_unpremultiply -cogl_color_equal - - -cogl_color_init_from_hsl -cogl_color_to_hsl -
- -
-cogl-matrix -Matrices -CoglMatrix -cogl_matrix_init_identity -cogl_matrix_init_from_array -cogl_matrix_init_translation -cogl_matrix_init_from_quaternion -cogl_matrix_init_from_euler -cogl_matrix_copy -cogl_matrix_equal -cogl_matrix_free -cogl_matrix_frustum -cogl_matrix_orthographic -cogl_matrix_perspective -cogl_matrix_look_at -cogl_matrix_multiply -cogl_matrix_rotate -cogl_matrix_rotate_quaternion -cogl_matrix_rotate_euler -cogl_matrix_translate -cogl_matrix_scale -cogl_matrix_transpose -cogl_matrix_get_array -cogl_matrix_get_inverse -cogl_matrix_transform_point -cogl_matrix_transform_points -cogl_matrix_project_points -cogl_matrix_is_identity -
- -
-cogl-matrix-stack -Matrix Stacks -CoglMatrixStack -CoglMatrixEntry -cogl_matrix_stack_new -cogl_matrix_stack_push -cogl_matrix_stack_pop -cogl_matrix_stack_load_identity -cogl_matrix_stack_scale -cogl_matrix_stack_translate -cogl_matrix_stack_rotate -cogl_matrix_stack_rotate_quaternion -cogl_matrix_stack_rotate_euler -cogl_matrix_stack_multiply -cogl_matrix_stack_frustum -cogl_matrix_stack_perspective -cogl_matrix_stack_orthographic -cogl_matrix_stack_get_inverse -cogl_matrix_stack_get_entry -cogl_matrix_stack_get -cogl_matrix_entry_get -cogl_matrix_stack_set -cogl_matrix_entry_calculate_translation -cogl_matrix_entry_is_identity -cogl_matrix_entry_equal -cogl_matrix_entry_ref -cogl_matrix_entry_unref -
- -
-cogl-euler -Eulers (Rotations) -CoglEuler -cogl_euler_init -cogl_euler_init_from_matrix -cogl_euler_init_from_quaternion -cogl_euler_equal -cogl_euler_copy -cogl_euler_free -
- -
-cogl-quaternion -Quaternions (Rotations) -CoglQuaternion -cogl_quaternion_init_identity -cogl_quaternion_init -cogl_quaternion_init_from_angle_vector -cogl_quaternion_init_from_array -cogl_quaternion_init_from_x_rotation -cogl_quaternion_init_from_y_rotation -cogl_quaternion_init_from_z_rotation -cogl_quaternion_init_from_euler -cogl_quaternion_equal -cogl_quaternion_copy -cogl_quaternion_free -cogl_quaternion_get_rotation_angle -cogl_quaternion_get_rotation_axis -cogl_quaternion_normalize -cogl_quaternion_dot_product -cogl_quaternion_invert -cogl_quaternion_multiply -cogl_quaternion_pow -cogl_quaternion_slerp -cogl_quaternion_nlerp -cogl_quaternion_squad -cogl_get_static_identity_quaternion -cogl_get_static_zero_quaternion -
- -
-cogl-pipeline -Pipeline -CoglPipeline -cogl_pipeline_new -cogl_pipeline_copy -cogl_is_pipeline - -cogl_pipeline_set_color -cogl_pipeline_set_color4ub -cogl_pipeline_set_color4f -cogl_pipeline_get_color - -CoglPipelineAlphaFunc -cogl_pipeline_set_alpha_test_function - -COGL_BLEND_STRING_ERROR -CoglBlendStringError -cogl_pipeline_set_blend -cogl_pipeline_set_blend_constant -cogl_pipeline_set_point_size -cogl_pipeline_get_point_size -cogl_pipeline_set_per_vertex_point_size -cogl_pipeline_get_per_vertex_point_size - -cogl_pipeline_get_color_mask -cogl_pipeline_set_color_mask - -cogl_pipeline_set_depth_state -cogl_pipeline_get_depth_state - -CoglPipelineCullFaceMode -cogl_pipeline_set_cull_face_mode -CoglWinding -cogl_pipeline_set_front_face_winding - -cogl_pipeline_set_layer_texture -cogl_pipeline_set_layer_null_texture -cogl_pipeline_get_layer_texture -CoglPipelineFilter -cogl_pipeline_set_layer_filters -cogl_pipeline_get_layer_min_filter -cogl_pipeline_get_layer_mag_filter -CoglPipelineWrapMode -cogl_pipeline_set_layer_wrap_mode -cogl_pipeline_set_layer_wrap_mode_s -cogl_pipeline_set_layer_wrap_mode_t -cogl_pipeline_set_layer_wrap_mode_p -cogl_pipeline_set_layer_combine -cogl_pipeline_set_layer_combine_constant -cogl_pipeline_set_layer_point_sprite_coords_enabled -cogl_pipeline_get_layer_point_sprite_coords_enabled - -cogl_pipeline_remove_layer - -cogl_pipeline_get_n_layers -CoglPipelineLayerCallback -cogl_pipeline_foreach_layer - -cogl_pipeline_get_uniform_location -cogl_pipeline_set_uniform_1f -cogl_pipeline_set_uniform_1i -cogl_pipeline_set_uniform_float -cogl_pipeline_set_uniform_int -cogl_pipeline_set_uniform_matrix - -cogl_pipeline_add_snippet -cogl_pipeline_add_layer_snippet - - -cogl_blend_string_error_get_type -cogl_blend_string_error_domain -
- -
-cogl-depth-state -Depth State -CoglDepthState -CoglDepthTestFunction -cogl_depth_state_init -cogl_depth_state_set_test_enabled -cogl_depth_state_get_test_enabled -cogl_depth_state_set_test_function -cogl_depth_state_get_test_function -cogl_depth_state_set_write_enabled -cogl_depth_state_get_write_enabled -cogl_depth_state_set_range -cogl_depth_state_get_range -
- -
-cogl-buffer -CoglBuffer: The Buffer Interface -CoglBuffer -cogl_is_buffer -cogl_buffer_get_size -CoglBufferUsageHint -CoglBufferUpdateHint -cogl_buffer_set_update_hint -cogl_buffer_get_update_hint -CoglBufferAccess -CoglBufferMapHint -cogl_buffer_map -cogl_buffer_map_range -cogl_buffer_unmap -cogl_buffer_set_data - - -CoglPixelBuffer -cogl_pixel_buffer_new -cogl_is_pixel_buffer - - -cogl_buffer_access_get_type -cogl_buffer_update_hint_get_type -cogl_buffer_usage_hint_get_type -
- -
-cogl-attribute-buffer -CoglAttributeBuffer: Buffers of vertex attributes -CoglAttributeBuffer -cogl_attribute_buffer_new_with_size -cogl_attribute_buffer_new -cogl_is_attribute_buffer -
- -
-cogl-index-buffer -CoglIndexBuffer: Buffers of vertex indices -CoglIndexBuffer -cogl_index_buffer_new -cogl_is_index_buffer -
- -
-cogl-vector -3 Component Vectors -cogl_vector3_init -cogl_vector3_init_zero -cogl_vector3_equal -cogl_vector3_equal_with_epsilon -cogl_vector3_copy -cogl_vector3_free -cogl_vector3_invert -cogl_vector3_add -cogl_vector3_subtract -cogl_vector3_multiply_scalar -cogl_vector3_divide_scalar -cogl_vector3_normalize -cogl_vector3_magnitude -cogl_vector3_cross_product -cogl_vector3_dot_product -cogl_vector3_distance -
- -
-cogl-fence -GPU synchronisation fences -CoglFence -CoglFenceCallback -CoglFenceClosure -cogl_fence_closure_get_user_data -cogl_framebuffer_add_fence_callback -cogl_framebuffer_cancel_fence_callback -
- -
-cogl-version -Versioning utility macros -COGL_VERSION_MAJOR -COGL_VERSION_MINOR -COGL_VERSION_MICRO -COGL_VERSION_STRING -COGL_VERSION -COGL_VERSION_ENCODE -COGL_VERSION_CHECK -COGL_VERSION_GET_MAJOR -COGL_VERSION_GET_MINOR -COGL_VERSION_GET_MICRO -
- -
-cogl-gtype -GType Integration API -cogl_gtype_matrix_get_type -
- -
-cogl-gles2 -GLES 2.0 context - - -CoglGLES2Context -CoglGLES2Vtable -COGL_GLES2_CONTEXT_ERROR -CoglGLES2ContextError -cogl_gles2_context_new -cogl_is_gles2_context - - -cogl_gles2_context_get_vtable -cogl_push_gles2_context -cogl_pop_gles2_context -cogl_gles2_get_current_vtable - - -cogl_gles2_texture_2d_new_from_handle -cogl_gles2_texture_get_handle -
diff --git a/doc/reference/cogl/cogl_ortho.png b/doc/reference/cogl/cogl_ortho.png deleted file mode 100644 index 2c2a1fd20be98e26e1ef6f3eb2bc664970f5fc62..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12650 zcmb_@cRbbq`}g}CP6p2^64 z`FzLk`+5An_x;y>9uJkH^Ios(^}L?r5~Oll?kqkvK7t@;735{r5Co+SUm|#DcqjM$ zwi*0|a#oX*LGr)RF2FZu9OQMK5#-#xlP^@3ROSPC^YlZ7TQ^P*W2jN0JPyyvrV)ez zQIM6^a2sAp^3W$8C~Fa7oI2{mx*Ld~OWp9P<{R72OKHk$kS(ivmRWibl|8-@QtF$z zc>a7y)-Nr+g9!9p4Hdfcxmam3D{24I8FFdPE7F1TgaO2USQ)3|Sm&))Htf%)US6j(@b5nrO~2ql7K!KJ0bjrgA29w&VL&l{8V_4P;vITEGl z<5PDx7ptd7Gs=Rfa3&=sUB7;PF&BL&MKUk}7g02GbK7f;WP^8BR#qG$5$uq-$FA}% zP2ctzk|5cN>qx4`*RNkiMMe8GFv(Irb`}<=h0Y*R!C_%%6FRhv$lX>-2PRojzG~eA z1C&9sRypV^hSeVm3;p2WZKqmd5#e0qS!0}tGwUcLq9SNgsB=pb%Ru~6p5^4&Rh+!y z;)La=5&m2`-z_}}+MNf9{DOkxwO%9j^}dSfqQb)18RQ`@Gjm#Pt)#lTdZ{%*mT)j* z((Q9ZMBm!lL?6z-Oi3|PP&lJOgq8bHQu5QOa&eGZ#Y``?uC6XCYyQvCfsp+;*X7I1 zk*yxP%c@@Yaghwn<;%INt9AzTly3Xm50sTdD=S50zI1nQ6n9GAFCLPRkWi6A4C+69 zLKl=F=Z(&E_4caAQI5M!pB);DCc@D}97KMDg+Q5j{(DvGp4tH`H(DWR=s@ z{QivITb=o+(! zINcJS5Emy6_bP{Z?BVhKHfGQBPe~Tm$!T+QrhTp>;j{owm!zVSQsk>w@bli@UZZL^ zMhQC;6Ex>KeNj=-7t?FeiqXT!&Z#a|3N9Uoqy3%DO(!KKrJ?l4H*el_yFvfiS$}e- zJ?8f9+c^)r;2%B*E9E;&12Hi%N-VGX`}b2KOM7^DV6na-Aq2v* z)1xv>5ijVaYTdVHH#avUjsx?{F+2tzw`XFE%q=XQ1)RL{45|dLUF(^cpwFowd!s@{ zP2D!*goA@~j#k)Vy7}yS(9Mb)JVo>Vr_ae;zkVl4^pY#JU9U6Cp5tO)_S2`Q&ZG)@ zZgmLJd#4jZiIZ)t5-!1Q!+LK?d=4NQE_o+>{Ol0^=myV-@cXkSYsP{}8(EclpFVxEvbNUc(vp$+ zg8NjH@Awwz`*?x4q`lFnI17F50#j1*7C{Hm-KhY ziGyT&zRSY7bi$Pmx}siM4Js=R$(N%2j6Y_$`Rhgb!3)dqQoZDX7HY__E%XAPR=)n3 zj?D+Sdd?hTBY9O-2{Lbd^-7w#Pn|mD<>jTWjS`nT&G_lr-Kp8x*~P`XMn+e>ew3D% z_geBhg!ET5b#)QPkWIPe_y#wIp$b^8T`NjWMXIheH8t_@@N{9-eac}SP5f}+ft9FW zsHv$1Z3gR23ds^1r#D_jM*dnEc~)?*?r^ic|GgeLWmtphweX8#WscL$^xk{Yy^pxr z+2_}Mjy*Iq`hIWCT`~9=6(5hU%kq7KTZ6MSJ3HuR+QQOO?oG^kqF9CZ(c>mI-ng&6 zzP|naT9~=0*ROeWi%h@gXx>la6&4m&ZH!MyI7cTwKRLO+w{gG8LQ7lwSzw?7%PYNd zI}uUQ@e0TLBu&{gP&{E_VJ3xC=4Y*f_1wghRoFde9&BuE{8}ATFR1h{NNk*3Sb$2t zwGa@dy0NvTe&{syvo(@b;A>Np*+NhHv# z6B9>N@#xvpr%wq92~EQvy1H7Jn@hTHn!*Nsc8=b#(rL!$Xuu~uJ-w;9`CGgIffySf zUu2WXnZQqf{`{#sTCsop_;GD*?Vy~E;K7#&=8lezk#hT%j60d{-qA{W#wxSQ$;llY z9NaO}*Jg@%mzgOfAn?7v|67Wb58QBRY3YLp4*=P3+_=F-ahaF*LwY)<;0J+~l~_o`#KhRx*iQLR{rvfGYqsO);MaY&!@cQncXxN~e0^y= z+wp1il-r+Xc4v|PAwp~_`tb8D;k!-v?epNdViB2J%2M#NZI zXJO?-D6h;qRT}vm2?WaAGh;0EyAA7oodL*Tg2_Vvwr#VW!IJA zz@6IFiMo`iC>9Au35lbcU*nBsG2D7u`uf!mdRc8KV&dY4D2+V*Y~kzzf`TTC45w2% zuW)l;Y-c%r`n0|MT13l`jUY4$Lc+YfJXyTT%1SdcGpK6mLlbNzFB=*fq>c~O{WQ~Zu$r3DZ{FN9 zGNLb|Atw(sF2YHTF0cGu8WdNyEx4x*w>19Z+*CI?BnI>Y3Osbla<9TnNsI4^(j6+9v(ny zDnr0a74|3rx1J`HFFpfF(BgLr*!Zt#DA_qUV8N7G`M9}nv5)|AWTvMx2JjeGe=#pU zFSEP5%fZ31R(Jg835H;{BVlfJ_0O2=MD**|uVZ3_`1$oKozjbo`2+;W86VEHMepvq z@JF;p7k$vl3k@X<=&E#{17d-P`)R1y;^M`Nb^D9CH$o`POig8FWgUbQ-@Rj@2#JRN zl#&uY_~R{pwI=d{1QVAlRxS4U@icbABe5I#rBcH7j# z;xdt5|Hz0nJdvHC36sLT?ld_Tl2+Kjm?jjmdbqz-aDrO_-VfVW&MQCEpWIy;fdbK4 zMWDMs*qVwCN#6+Gy3Rm6`z`69t(TuEk2p1fii#?0%+v1-X6k&9EIB#3UYX6tuV3Y5 zWwRS@gFMwGrxEgS0_Bl}PXJ;+e*DPQF8H%MVh?*C_EJb#SfHB@!u!S%^+qM@CMWM= z9%GX+&W^(slyQ$ON`IW}$L|-&sU8%T)C1S;8+A|AWHqq5)VwmJ`Zf-7Yx(@72oJK* z+V`@#xfvjUhKfohTLa47;klqR192)hQjHc(qNAlvjE;UZ-^C~;Rrl%@$@-aXJS^tn zbHI|fZ{HsLTAQeLFV4#&)blwLl7YoUWuYT=)bZG(p+7Z${%owyOMCI6)WI^JV8U2$ zFHW)_onKKihE>#+SVd5WlZS)P;#)~sSy@pLy3#6Q_E2TSk&iOZdX>CPmTgKr}UhDE7iM;3LMzv{}#a&of z*b+|P@y8Jo zAhDx{dOnq#Y-(l}(Q3*W9lWyn+jBk0d}?7qA+r~F^0UT>gkLupi2L&8c)4v+g*u5T zDS#<`Jw0fFn=jg9uJBP2iiuSLO*-Z82*AHJ*XggvpF8|DSz_edw|uytqN2?t*YOB- zlzwup+b*7l6b}O#KJe#CeLG|0N!X-zqZOzfy|#3vm|7^N<>lp|j!HpMS6(KmLV^sw%N(jed!vz8TsH zz zK&Xk${rl5%bD7hey!V?41qx-=bHX?qZk?c6@CbS^UgW{5bAXDgt5Befsu1PK@UUWU zKGORFj;Q&zq4??O=%~Jd!P3%Fdhq!8`0ccAxGhml+l+CJu4Ucp5fKp>3?`N`I3&bC zU;l&{!PU=OF(+^wM6)d|EZp*PEIbuXz!31{$rEZCnzXlX#l^*ggM-!7)ft;nAx$4W ze_sod9jyr)sj^=I6X1a{hy_yIkKissCkkC%Jox|o& z1@fpO&)-hk+5;T%nbhi;l#lWSDJUqWZIZK+@UfmKOsFWghJrHFd?Xx_pFCD{QGf?2 zeA>)(>C(*lRHNxN;5@?<6Dc>-W@cuN{v51%N~Xv%t&G<|?GiEejg2M6#fk9q%ciT5 zl90HGkF%wC7Fm7IX(ituv9C)KcUNO4vl}V9C3^g@&&jNVhK}yrw{Ncn9`)G+{RQ|O z7#KJ{m^gkB9$o-Nfsa32W;+r_BLpS%T=qwU|LL)@v8n#cG_Vb6S&61f@vQ*gq3k{w z+Hy%AA8tKb>c2Olpr9b;vRq$w!rG>%dxwTNBINN22sp?T<>kMuj#YK0NQIk`?(Ym3 zvEA*D7qHIKScE+V!lLBif*KoJW|iw2C%g7H@u8K%+DE@u4XDFrmzEM@V?pbHfS8$_ zB&MWvo%$3AJ2f>mwZ0x(vA|j1+w0s{`jiwcM2?4#Z*ncpLEA7J4VRgppAYEQ@}kc3 zcMsI++IY?2>M(57e1pprA(u$bBy_kudUQ0O7S2MVU~g|fKB%Fk)s|iVElI4%#I-@!)D80i}6IJVwX>)@~vAOWNk@euJ7zhN=uvewFdj{vqlCHQ`6EOZgonL>qE=Z zbI}(4WPk78d17J*xap>u+n??-MX+~ZrCCVKT+g08YnC~WUKAvJm*hJ1TqPWM=Wc z&F=DE|N8oe<%`Fi!oA1#)0?LV+%8pACp4;KjPc(jy?OIyI}sE!;1Zp<+d4d55J|9Q zBQFDU1{%7!u+S05Czt;^^lpBlyHf_|9tCgB*Ca9RkCIM3lax%P!Ob87cjM=Yk*-!-OgFw3E{lR#JZyqgz3IywS`nLLe+K575s ziTF$r&u?eKF=7)E=H}-7uOrcZdf~`0TD^u;mg%)Do<7RbD%@9|f{-6Vwoba z7^KwXZ3FdrnST-m4BNnyR3bmdA+=j1g!gGV`ER?K@sVv zsJ}EH()U^* zbX3l*6yu4^;Ka%(ObZL=zwfqyjTN571)JL(y3$R=Snd=H*Vf!3MeWrPCsow z_E8{=wRJX>B1ksH=g)7T7oZK@#go(1FRf0as<{%u-XNN}*>(6oAiBMQ{>4_91UTU$KFA)Okqcuq{oc-%kT`hPQ0;yo6> zGlOVTapa-S!!a>6<=YS;U7Du z)UU5oQ!-3up*igcDnK}X{HWN=cLw(fh!^UxQ_(nwY0Q%XJiZC|R2ME}OUl`rnwm;W zqbR1cDk=uSK!7%=B2q6!9cJ^*@_Py9xp0o};=p-a3_ZSMT-8fxFv}R=go74{ezS|3EwWW@axbDQTu*qIo%n*BlHC zARum=*6BVZq@-|^^D-a{z>IS0ZYYU%G|$tns`StCkwfOu&}DjV7Cd`)TJo&1Eee+E zC^nW#pAZb7w$4tYn#Tg8GzcY}`c9%S2r)2AG}YDp(`!T=e|!ct=)F2B!W1EF@huUU zQeR(RVj}Iexa#{YM1EM_ZtXX4=0Wo6>gwIK2_NuZ!PRwjbXlW67^<+7;Rk*)=C$M>PL}Wh zsWsb~LQhIs3{(etyX{2n5wt9~?fLUbw_y*uxVV7-30jksduFQf+0f7sNzmuv;m3_n z&x(kM0N*eyv5Y7!-HBk9tFEcJZ(;(Lcdgro2~P|SJV+7}CJX=f?`;hX#>hHiY5o2E z!8TQ|BeLT(wy`1PMA*ZprtU$B*)$YXRUNFa^CoocZf$LCZsz3Wjh0%+ELZt&v|QYQ zx3;%!?Cf3y2g~4fB#MBxeh;?7?()z>Q3-DYyMl9R&; z4-3rmW#NqTAWG7Pd0$^>Gl!jGRe3iHnZ?V>^WBucb<2#G3Oq7>o?kzjLh!#OT8^rU z01^6^V-cPEeY#v)z!n8h0c2O0{7=M^-3NT1TCW3eJOSD&_4A8D5(KO%QabBgR^lJl ziwOz+DjhIXPd`gNM1hba4sz^dCeyccOanmffqy<$>qW!ZH!(5M*T)hepCQZ;*pd0F z4E@2S7RU#Pb2@VJrnxOj9(^4s5F?}Tu;%cR1|V*W=F0ipz9IONzpDc2P`=ExL~I-! zK}{yWf@kLDz_kVss{m{mSW^4yjZ;Cg!9hXU`S}1vf4La8PQ99|qm}B0hJS!XLy16# z>gxk7lyut%R^Y!l5nN#0zB>!1?4?VW)cNl_;o+k7HL&Me7;Cz^x*n`?pzemsvnw)U0di(p7G;)LW$4|{IF7BB}`t;c| z$B^oP`(Hj!_#8_>|BaTWuKPWka87a$OP$dJlB017TcNrhPEm1#os5;072=!FM>62Y zfnadtAm}Xf1)r011g&F!!k0~|dcKaX=iwY%`sqEFefy&_2rO%Ocvb_7{kqKTg6^m7bY-y5O_3 zaISAK^VRDoC#I+Zzf|d%vsBJk@9DKrkcqD2?sC!Zs{o|H)+y4-g8*WoYOU74Bz=;8 z#X$*d*1LBh8KQ}hFDWml|LtGrJoh3cg+U4I zLrB!|@08;>#cvp02ckqvbMyXzfoDowB^x+#?F~|*^AxmA1apq4YjIzv98#a6d{=Yo ztqW?J&5NgqP`;=9itzy)0Mwr7p|IK8zkW>*u01V75KFp~5U#jbU7Z}vJhz%gT*R0w zK;{iRjQAYnBC5C{d4c|h!!G`|-{YGChp!ZoC!4EoIn7MVgYRJjF4tA$>@@1KRL(o)a zHffa9o2X&#Ohx*hIq6x99M z2W16uA*W<!9MHrkXrAD0Yw4dHgB=6hP&M4>A8AtqrI@HFF1jHgU!-~|RQNM$g@CV z0`@JKxX?X-H$z1H`ZYzhA}(T};rH>QsAv*TggkgyKo-H4g<6JBdHf>2qO#KNN7 zUB)c;!p*~@<@0B8pFf@(KboM;0K#Yd)w>&vyDUp2Ja!oZUUTU_(GEgVLpXgOt^Fei zfQ|X=BII}OYHB29Ny*87#y!^VjkLe!zRbfjUh*Ikf?F3z-!sJ+dZS}wlVe@`7C%u-iV8}~Ur z!Vpk=O%UoF8#{tc-T09cE*f|%+?`D@-L8}kSp5` zw58w?Zr+hPf@C>p#oWy7JYE1~58V0{>yXS{*2+`aIClBJMd%!0Up%gSs+E)CodW*p=aPqG0U+6|l9o=Hus2gmH<*@44jF9Jq)jLDqRE z(nmL+WY4dyV%~mQypEl6A+&(%wBtDZclSeK}aUJtn#_SqpKxu-0; zKhJUkwCHX*)Xu)h=g*%lvlc+tfzJcH-t?M#%ZrO>zxwv}+=>ceLBal(mX@9#l9LGm zceo8u_>dt7$-V_mKe~#9C2ymYOa0baf zktl4r0|;YoJ}Y(n`wjpK*S_WL+us&?Gr=PQA##V|WJmm`NV?8K5)u-Usm6p%qGjm= z=hKiZ-{x!F-EuQjk5qAF=>dW?hHJDPx4R=kHBiqb@qO{L2-==YiqgTYrs`Tc(~!dh z@!c)QoZR~SLp=n(MR?{PY-Ewcr;(Ml^X&hOvcPG;WBg~Bbya*F-$(whFiR|%Z{utQ z9t;j0qfS1%jrZ4)s$qtRH-G$c#XtIc*MrHGKDT>?I^aaGM#uv|;o2iG^1!S?k)I2_ zLO`Gtgb?Sfw8K^41wQL%2gvE^Cx(Yb7v)Y27FjZ4ku8P_DumOQPyGzBASXyJkR^F{ z*hE{w&>ek`LG-&OpWjbAh1cHR4)IWDM+Y|t$Hw+HKObKsI`S$NApt?i6-ej~e{Vs{ zyWgaEg`M3E5{_2W&8!sIdVt!xckhCrF*h|mN#>iHFb9^Vl}@uqo9$Po3(KINgOXWT zSb$VV%58lT8tre-KVW@(O*e;~*osi`JL~II?czu*3(2in;0Q+Lc1aI~I5-|au?+4) z4MJKfDketocgOlpy4porTJNKs0o5y1baaMBMp9ai*8O>J)Ur<#(N;WM=;=vUN=i&z z9j_77s$}k<2``2Dk@Rj$V6m|Em07p?vem)Kf}R87CMzcgA6|rnQ3#T68IBK4yW-== z@j4&+5ib~QNk|xh9t?)qe|4%q^uj36mgye&^vRHwkG;>zda3RQcB09MI9(^q7V-0I zNLPYz{C_#tr4;p)EAHw#;IQ%X8pAZt3WUOH>`}1f3;}RCKnx4(O(7%q_V!k0B^A5H zlS&od0-ovu3^lnlnG}YHhud(Rc!*B}18-ol_2B-JM~R78!+zq|5P_MTF#&%5&;2Sm z$P0E=OukW_Bxu~nJByGv0Ik-{)#BKZn%Z!~V|-8|6+j%POebIz>+jzPgeHCN%PBHz zTidZBvvy&=JXrAyR8*mLqpi9G2=(C$u=*o!XGY4i5IviooJ?Il{uw4Tj>Xf|)Kmxu zkygnj()>?P+wh;B_Fg-9+DK{xC$Gn@4Mcws9JIByoiO_gH@-YwdJJ;lqCn7|%h0ON;(j4V&5@KbZMdF!i7&|m=Qwz|4hoSd92E$3fdQX-al zC<<@`%twxaI8ogF8o)FFbsqtzw>s=#AUVMMV7enYG0_uZUU0P~Bx(xVq6Na0S;Jd~ zJ$|iTVq=37iv9ID{c5+uckfJrTz*Rwp(UDwtOCS3Y#aO9-x&`B&`8F<*e6%B4ag@y ztRJYA*-v;c4_=+&UZ%g0pPQZ@*f|HrHx0}H$@Lc)*;`wCK&AyV3Y8TV%9qN*P0LPE-U zHC2HV1pWuu(1ns`iHIa0Es{~YK2b3;GOF-FQtxpZ+u7CH3>6hh!l2!g0~8Yf9$lbZ z4Zg0=?AHqpqDU6G+c$>()z1lB6iYtGzkCWkGZDnruNxXX;E`W2sXfuzv)SgM#37Q3 zY26tn$!&QU--QPdP=b)xNc7M)+Yo2`tG~U-5>93VbT1)+Mu0kL1WDNK?hPDhcF!eq zj-YvD<>duHFOjAHPUR3JDN15fRzwEP!;*eD4P7BipF~XTMds^@yNEgI5e9!X7DQdn ze}atZk}SPfpsCEZDwd`}WIt=s4-S*M#K}v?OYR$pMN$K&(bKpmEoU_cLWQ@z3y^uh zEEyE8Lmdh$=YfkL^N+*-sSKNCr!9#2;=Y1?3tQ_KG)`EHCJNAwsh2rb)YVVSJ&<)U z8o{ks1~I$G+w%5BmQTO440|{e&DrDD~O7rI#<8Q8=lya12z9?M{?bblVwtXrqtRh;uGt}CP>!A*0$ze<5N&vfSOnCmV6l=-UliP>GsvDSAn6zkmuEy_9GZp zfeA7h8JVA7!OHB`umK_N=Xh0I9P)HN*H!(1m;dq`%fP(+o8`EKQ(5u_I5W&Y!Q~I; z*VIUq^-XkkLVG9%^#sy{k>7dtYe`87sBdt;dKb1q7q+!22E0s2(9_a_nXAz(^H4J! zP`Hypg@umb_gYxYl}~twNZ6!@tV8fp*+@ERU2Il$G@l568F9 zaE@3Pn|J)!`VH}}9@y0`EHJg!6igl+9i79EgE&a*+T+8O59H~B$E&8Rn=O8Z7(Y-4 z?*q)iFaahOqZdHB#L(sV*Vq&oTs_bMh9+j@IuLI0Qw6wRije8&1y1M=X`zgD) zcngXJxCEr^me$tRR#taQEYDL=+N=zhUNNeTl4sH9aea3IT<+;Y6jH)+SwTkT34c;E zMC~v)_}cF}<~T@&-NxFwQO4Ctn3nu-92`D+Nl%zZ7OsJZO>K55qNCY;dtMdD7?>fT zn%Ec^>Q968yF%%;4NSyW3?JzoVpfrW*=qpZ zQ*XmL(Ey}f%qm8IG47A}U#>RIr#Z>baa;#cqk+92YXY?2nA7*<$DFCs%9r-%1AOPx zd|$u06xUujpLXWVnVd7rjA4?T60Z^xV2^3q02bk6;nVdvXTzeN+HZFko_v5OHB-QO z4Mv6Jxc9|-zj%gEcwC)Mi7M?w`KEXjGz1;f|(dd diff --git a/doc/reference/cogl/fill-rule-even-odd.png b/doc/reference/cogl/fill-rule-even-odd.png deleted file mode 100644 index 1e4fbb0f2a2dc04953609dfb942f48db046e46c1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3121 zcmb7Gc|4Tc8-HiPkU=SBWEr`%a7}j*VGOcWqTHJrVPu&ZvX1OiV~I~mDUxN<$dbB7 zY6c;Dv@k<B)-w{bp(ui5|AX7016?3|7KF+7 z{)6924RwRCvIx%l7ZxdEs+W51pL)Ga>ZqSNtOtk<3rIl=zU!LnJ=qC;g%$K#*tud|YePErg3$5j8yC zGrwz&n`NK{4gx|=rw_cq;p{9sTk&#zN^R?587+7{-wtr5!qqd?ME zD(?zWlYuUX)qixAZg9ULYSiAC>Y;lQA#^wJc_r=lHwEr{pwj)2CJfj;IhP(2ST@ZW+c}uA*N*xm($z?(scfC=>~+5`;W9p zR%aLW2UCGSVTsejsnkuH78M3$4To%C!XrbhFgZ7M@*#BkiluF|b_pT3G2UTm^{JmY z{_oaPX3r~>5ClmWcy0gI%J1)q3)=$#teQLD1!3JsZ$xHiY_5-DP*fZo3q)b8zsb2( zyZN+#_$uAEP-+e?!tMQonAF#Y zOESX9L#X=e6C0lTB#hYtyGOOQCutR#T zhqc~SRqqJnzRg`adVjX=ik{$l?o4yclBud^ZQ2>3IJE!4y`Aj|>}Rhoq^Awnq-rwq zaP2l7iwFBmt~!4zT2@gBxz1{-d~c`Ae-oe#>IIiMMZ>ikXokGrz}`t6bMa&y!3}cn z+ZkHYh&U92+?Fcja|S^FNZyg~;C^QGPoDH1jG|@Uyd?CzK-#v5!=})-q-JQo zz&-s;`^Wav*i^O4qIuTpE*B*ZHmrMg>AP~9d+WP1O*26&U$^3(TJWn`8rw5v7dl=I zjE@c4Cx-w-`tgARZGvrdIQOO_5%=0y)w2z@uiy@nWDTvj!rqIX8xk9|hy^KK1#Qys zUn@+mBu}87kICOiVt1kaXNE(5jz$VSXFZ7JCRF7YgzWiah6i?Zt>E6`_hM9q6Kkux zqETMxIew6j#@LT4(&p%!^@X+F_42~z7zEkfl0W0zhCoHfu`)D)a}#}wm4o|`X1@@tUjpFo`K#8#+TnEDL2OiKQ1dZl^lf9XHpW!-ne2~#Q`{n_^Gnu zq1~=krS?xZ5f}|HlzGdbseq!&S4}BONATGjDZvmh8fNx2y&f5DDOCj0saW`^1wZC4 zNpoBR?tD^nI*pgFyNQznHOO%+?Xv_GpZsrtlm&;Rp?>9fJpVe^dqLq#$c{zbI z?lC)DnL}B=1vg00!yC$X#wnlaPe?N=Fx7pjO9cX}wvP2T7<@+UKb4>-$CK;ae-?N< zj4#ut^UW=7*`4$tg|xecB!sV#?t@U4;;byi8k)c+2hdcAksYs$a8r~H~~yZ&1-_p(`2(|BGvf}~b}X6jR!sz?JWhFwPg8OU3`CDtp3Ikq)EYK+*_ zM0!}0q)}km;3B(Xw#aH!zgr02el!xo62LY_?=+VxinJ`Zcp98nneSe!hkWSS33Aoh zB17;uc5Le)41MSmWhd45(nzp@uv+LbF|>kazderfYB{G4b)wu>c!!xSaB`gh~)yLmi>&rIsdx5{!82y-ieu_K9n(Xo30 zT$fIS+O>BhChWp0{Q@h5FPK|{7z!U+1ll$jmn6=sjy{o4iZ{k3v2fdqSOA#r^-5-Y zMN?N*xLp&DYqZ>-*;ovbXn9Sp-AzpYkQ{(Fz9_n23pH#$+=%+i0n0WpJ(tyg_|lhJPQ-WLfej!oL{G0EnVT3Zxq=K3fDAlzU18 zB7LdQ23%NY7&xVqvrUU*sPA)l?xZmlLe*pn!H%g%bP)?Y1$pzSnjp%N5JQIY_~DM6}bf#RywtLIa;6 zDt$W5@y05%9KFkul(6nHMC=+KU!%du+8B+`hPHy`PyDgIf$aFcx)q;}4uhH~72$b> z+cTL51{ST3)9@Q>&zGGdppCr}#iXLM7iKn|kuLNkdE#j=gZ(xep7~`g{v$-fMa5ds z+ib$3IhKYb$!IUaMCDw$;*e>X_QsVoFuRt0qpyuIU7{uKWcZY&7EN9S%Rh5muT zV_6hnKDf3-C*9QfqM#%|xD7y^>pA%Fm#X>y=oX}RUH+J{bZd|NM2l#eoz;mWr541v F{{i05cM$*p diff --git a/doc/reference/cogl/fill-rule-non-zero.png b/doc/reference/cogl/fill-rule-non-zero.png deleted file mode 100644 index 2d8ad314c4baacc70c84b83b0b83b35e6a93a01c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3143 zcmb7Gc|25WA3w7g#$H5JmK2gKVKRlr(rarN?M#c(7=y7iqDwKD=th_OCJn~k-k2~eBOKie4q3AopYYw{`}7GJkR%6oQJc5tfnjg01B=y zPDcO$N(A3KWf0)qVVpAuJ|L7M&JF;JxAikPL0oWmb^_KUS3&*5+aL!S=Hg8O067&2 zL4a(=W{@cz;fg&ZEkLNt>uF0nrRIYyjfg|1A{;}>WI{*;;CP8}K7w#jCyEpipyTX{ z#hr{-R0katxjNY&yCRq#?#eDUR7T)t-!3=qjVbGTW1ah(=5;8qW^f?SRnvI!{zfbk z^!dL*6+iGim`*{t9ryQde}|;YBLH?)YW}$fVyiTuoE(M#bQs^ClG=~9liU_PV^jcT z9J6Nj_#Bd^Ahae{2Bc*(0w}YbdU-_vjEm<-EZ(=>4TwFt5*33U|_+*wk2V@IIPI1J9qG9&FhqYPs<{Owk(GXUHVfTU6#C3Et<%L_6=H<15vC<%!;(hsX)-ee7?~z^61JjzMu`bR_DOJ&_x1S9e^@o{fEQ_x1tt9~LkKv1r zKTgBN3Taje#m$EeVFgwTw)l!36fso${Y+)$E;>Yqv9hs~jozY!zEyv&S)Q6{8xki) z_HaYE7RpmO9k0$lPDBx(E$oQt7X*J^*u({Yjs}?k0pqkrJKO?@{?l;vrhw5w%bOJI zWk5QMYXrOZRi*IV-NnQ7>e&)3n8mEfYp!p)Xj65nc;m}h&4t(Y$G}9QC^w?UAYYC< z2+HyN?%%R}5ttdR^CPajqj?YN;K>1n1^v18(;hxAM=vX+C1?OG-iy@Cf1`-BbTuP7 zk^snGR9s{wu+iu6u>uw-Pu;>h3-!5$W7mBx&#~+_IZF#AFQN27yZ6)+m(-`NGRQFR zXG$_k`#!lFs&E?)4;;0#n%_Br{pC;0ol@?T$gFbEv9MTll{?J!9g8Un5BuK5 zp=mpM_r5DzojW|(47HzB4z)|7r`0rWSdLZisET}Xv8xo1Smv2`K?MgVF!4=SaS?Vx zJ7=DW&yA~;aZ@);OiZ|uGF|CrN88YXp=`kMM2*s!ms&dtu8A~d;9#{>v(jqT zx@`Eu-fo-5QvrT03lo_>5b{Eerw*9VhxtW%+vekB-bQH_O8+#a>*R+GfypLrQc&@E zyO7+pUzi)zIztrvn+8jdkI!UWjSC#PN>5uB`e}t^#E~e0B(2(;{Tw)T$~Ng|$=w4= zo=4R<9*TuH1W-*+UY)k}et!%s1MuE1ZOpmJL|_sWbkq<=#djpV-}!LB-U0>gEw9Q% zipcG8$$QUbfTsmB%xJl%n~@jpgjp6(_w|>Bn{ET!{maKn9#qgZ`YJ>N=pB=T9DoT7 z?FsBrb)cw>GCzjT)~iHUletkJz&!?7D5F&EYrR~T;$JNf&?@|4f{p&s$h~%W1W=Yb z%(waF!vJ5vn1TK=;QQb&^+;5|)sV2410Gq-L24B(_e8>PVBfw(h2X_4MABC>ML1WR ze%Yt!B*LNu>+@0A9k${VsLUcxh@O0)IAfmH_z~LVS9>4(P*W1Td8{k6ib$wW#_hEr z-=QRDIaR2p4joB6ulS_agFBe~u-^xmuUoA?Pj*8Sq;66X2^uZlyA9TM0(Z^=^9>KK zBOzD}tl3yAE!2n&ILY~AG=*KkI`qm<=Ht!B_t$0oF!m`yJ>ly|ZF^hasLxPz(Q9l7 zw6CeBWyQi9}G8cnU;qAB1ZjW^r zzYdxnIF!8#VXH_@qZGri%ujyHP?ORZaIEi41K* z3$ph~S8Oi~R_Q#_Ere4~kb*{3+n>NIurA_@5U>+3JbE59yL6hnw5#l^7`+Z&p5|N+ zoXK3-*exo6P{UBi4CS_PQ4p+)BpqhUo(>$DyA4t@YmyC~c<<$opfH%CQ*tH+%L0I@t}8JX!cHlY{~Nd&BjKk_IhKs>pHlj%o&TVxu7icI1xS zX69R56*6EKi2}utS450qRih*s|D5#5HpTTQYP=8`LaS5-7SjVR;!n2KD7-?~aX`P| z{=E()aDT3h66r;C~pU3x`5ag5}DUC57 z`*PaSAB2^yW1Ho$9l4>TK)*bt0Ak9?AQg#9v=WhMk%SVSgmjo_s_EdgWr+RK77dD| zo9YrVt8c! zAQJ1xg2TH%-fzZfdqs@$XA9TL4N#tHO(2d-G)-O+N9VL^ndL{4XnVylH7%U><)oRP zotJAV{$tNvJn6h9{*e y<{bqu5{34YKxrUl;;`YAegRT~^Z(xwRI|HEi+|4z8yuaqp`EUN3?>YD0bGLKuxu0{-=X?2YL4F8* zGkp*UgdmfMAsXAMk>7N6G#VdV_DN&3SzhGBx|)}z8_U!9dQ4InOH<$Tmw>&t-%i&A zO;dc1rGzr5DQPFp#DUV%(j4i@39OhC%s5BJ8QSe}yqTu4kxV>rIK52WpK&!Z&XhAX zy!E&})F>?W5L@^Wm4DGz_qg_k8}Xo45Yo`6zQHD*w02q#jL_L=bqf`*tz}>3d-;yT z@l8gBLX@t)?fLV%jwn=I((+Qro~}KZ@-IgQ_>G|z(XL!*B~dgnJ{Js)$`)>&H21AH^dlX44w#C+1g;<;EGvmQ0(n5L=S3lwOpc)Au8xWkvk8u(|;X2`R=g*VUY$U6O!;wVJ?MH! zGw-hxN|%U42T(GETIc-~6hN;iQo|Gb`7K5t8P4~)-@)B5QOx!`wg8*om`xogv*K}* z8Po$}`|0B8UQ!ndT@MzW*na0FAm=wGP%W{z6lz4`2ZPmO)t;fBU0Jrw4BE(u`(V<; zi7{=w56d;lbn=m&YOptKKu0iqVL4UDn3lO>)-fcXZY8MizwdCJ0aJ2_QgFRoT55MJ zE>Auk`gTjvcQstZ&dD-5_sxN^8EHQMtTsgQT561$X`NCL+f{Ie$|K%OA;v6_)|-dx z;JZu(Jxn&0OSRhU+!!~L2r6>ZFB3bS|L9PEJMZ%6F6O%nTM@haBkl7#~p~2V1!6=KhsWT z*jwPTdO$gf6n_)8feg#_c4qbgMA~;@U28U=2Y`XoZVW{WTnhd>EcqIbP?d3NK4MvG z?^;mo3;A>{6z4EkE?r3-?j3~Wqlaz-1@S?hNd_w@v_PDxu*qSW)v1jGFxh!voGXGLqY^9rQ|S*JPP9ZKXU#DQ9>33kodHLelNpoNSla)QX6ed{WmA zwCDP=e$(T=UBG8IyCId!dl-q0-@R!5u}E`eWqfc#&E@m3H&qvM z>dk11E+CAb@%5KE-vL8&5B&|u^)>0eMN%SRPtmrb6>xY3tAtcvk(=GR@lA}+vOBXf>ma)RGOeoVo z(>Az~yf2~0cXpRjNbWCm6HkEbf_)E$B0KTGe8qbwHho`M-TTAMzE>_kAcayxRxKX< z+r3jaz%<7x&y7ERe^GLE+lQ2kB{4rrO+)H|4Sm(( zb>LYNf6o?+`fS8*dgR$jTQ)#2*EHH^eZU9jwZR+@~o;h>wt!zy4$5$ z(1ypD=b7`o6!*#R>V4!-K=9(`bzQlN5*+6H%lMu+hf*0 z?Q@|gZ9+~|?b+ipa%3?6M)!WA6zZs>6Fq|mMI@0z3eYD#CbKCM?0C)HQyq8PJcJ=# z@>PL~`P5tu$I6@umUo>r%197p?J^otK-vI8itU+D*$%%a6xD_7kcFa1$ygEhI;znH^OvBu7- iLUDTR^7K~=tFVxb$A9t|_ej$G^gv{vAfm{Na{f;SUWiKo diff --git a/doc/reference/cogl/quad-indices-triangles.png b/doc/reference/cogl/quad-indices-triangles.png deleted file mode 100644 index 18c42c845ed165d3b15dbd431f905be823416276..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8018 zcmXw82|UyP|KH4zGs%5tqH?y8ifK8roRyL!d@;#LlKa|xBloO>k)s;A97W`wq){81 zkX&MLlAl^duTjZ!{x+Wic{QJ+JFrVw+ zJ7={!h9hySv+Lpc#$7{8c>|jxL&Kq+jQdL_dy_i#DxowRGI}bwq|nU+*Ggc1U4y&XC{Iy|CXvDHU+pFj>u z8_CNIwMC{uLrBYZS8e&z2o$E^hOFtMa~udqqXMO;*Z&7nQAX`z9Tq0~wlWNPEMfl6 zJy|p%+8}Kg4PQH~3_F*#tX~V$tDJ*Lvo6WF!OQ58687INxkt05kn)bJqX^9uKVRL{ zt582^<;e@8%^OBLw;Z6)q4)0%dF-@N$5k8Ykynm{%2$x6ZR(|aeM8)x*o`)BN=C8o z7sz^*W2P<=N&~jb&!JB=rsB988H36Qz6}%c?Y38RRo{ zu7(ysQ>-KQ-R)AzzQCBd;!dBTpCFuFGSIFW#nB$m&~@V;kpH+od7Sw1lFSL1saDf1 zsyt!tdyc3<<>CL9{CL%a90S(xU$`k=ys=r%j8Wj-cwC+aZ>jnRhh&RM9Z+z5rpIGd zC&}?!nKjW>ox z;FwL$-g(hK6<=*P2tiK9d4rdDH+K0-x)(oRIE;<`@y#Nj-JdQ^t#u}>Bx-kAN7UwS z(#NtsL4iWy|88ZT$@QTp5@LdC<3w1fWqL?iK`7_wM8kV>+ zZshf)lu!M(Zu;$rFq@d>@=qVFcT(M9>{Wv=CwTa+B5GLO@2a9P=nifo!aKHpnob9o zr@tLVU&cwzP@|D->4D7?g>^zqz}>Im71g4shOp+6w? z6RkZ>H2dX9sF*j>PbPcE-P}x*=tX0dnoVCtVg9cqF;aF}BAr1Rj4AJFBo;z5gMA)M zA4JMShjd;X6mq^TuKMN2Ka7vR2^ioae}ZquJ~vWgJ?jO?!xuJC?gWH;K{ zpQ~S^=tlacz6A;BR8m4Z1swgef@wa+a;2%&7QY&tGD1!GnM9Rt#BdME@9!VaHjGCPp(8Lo1Vn;0>bij~1cHk^y5yYfY4a#5{ixjNr|{i(;>azSv5x z8oe5WW#vZu>j@NR4igHz2SZ^d`_f0>``hDTvmFM)U43cO$z!!Yrw*g^opU0;&Rylm z$-BO=4p^^7>r3+f@~{brd`)5YPUpu_m|{^H{iqk()?-iJ{$f~4>w7s{ei^AP{!!9- zwL9)&=HQVyBL~U z(0aZ%?(Ay8%ij7J>-DOZB=Wo6t3o;HKiW@Q#f2028Ti@_QC#)Dku%RzZ#G!6gr>Fl zT0W^xU*BNWz4?X4bI zLk+tcX_luH*7{C!Wgj_>A8OQqz&6>|L6l;?Sss$QZh zG!->oDX34Q+DifMtRbtg>)%7}3rCsL0|n!v)m#urA@w4kU*#qm zV!HLb!YfVRO5gl(MQhH5mZ6?@KM3#P+h;NV%cXyI5`Kv%{mydzr3g_u65gUiap7}u z+rsT}Yg#4kE_rr({PXaXOujttlb!R{*gVk#s7mMg+MdxjiKWqs&HH2cUMp@z#eN#g zzA!z8tLCZLhn~H5gnfA90aFuO@NLCqr%bmiE1Qz8dUtvxPm{s-p=iQPYVqIm_%=`)xEdOM9wSC>l2xGDViCq*M|;!*6co#cP`EQB)Cl#-v{&Az;tX>m$L$(-hWl71#LU?Tl`Hv8uN5S@n?lq(NY)bT@SLG_%=l(mT zFv^=eU6){5Q9H=^_M|nE*Ea6{8N!WenVbB2Vu2YHMM=Lre&#Wg?-WTL{?8YAEbomQA*EiV&TWfAG~k$c^b){SDwRuOHwiuA`iP=l;)T|l^*{h zlbvnSzJr)REn8Knl->OSCbpY8rC+5&Zo0FKj5?0FX1ffZC#Ar8jtUWHpRB`Vv0E)A z%K5+*&oP$r!aN!D`_908itANe+wXOZ!~W=nDmkp1)sbEH3*j{?P7%WV%WaYTX-U*9 zg29xLPU)L!8ZXjiZ|O6Ysr%@C>5_;vzH_t*&XO=sXNHoQpXxLc%Rh#^^2doJ4SVMe zmBKh2iN2r!MQlo(&r2uNNmj#^(turN(UDStjZzhnchb(ypBQ{j%CfxEQ%mClD${4M z>tlX*qRx|~`IYo5UC)H=kb_~ncn-j_`bnX5Q;C$l29mso$-C)-SUYvF&3R1(&BV*gQ}t{w9&?>wwu$^6vD=~&6$myH$w|3 zk2%ylZ&H~`Kb`Ce$7VsEji(&`N|Am2kV$ zI~_t+YE4|N%k1GGZEK#Ny|;t(zw<* zUBSiuVPS2ntfNBjkF$)T&M|+&JLb<<)idz3Phs(eb|~{}&sC=J?0U{Ww&6Jb0A%HD z=JN-}{LzWj(D{8Obca0gTB%IV?qyXGr^^VFe-oWj_gN*xVrLIl)|E+$qja3dd%6g} z=5KypVx(xGH&MF^h!H)3ZQ?2}s2DRg?^EQSem@7{7eJA;-Bplt-)egQB^8u zcNLVSye%m_gtEBy?>^bgM3@U?PIB@=ScXUQ;qqJ zeICtYCM1Md%QQI7ki}>sk2pK|3h3gSkad;Z(JzTxlPiFi9xt zsS|u}&icg}nrW7%T15#KClza@>#3^+xw&hw9}ydP^+p&We_^pj`|j>`$}IhDiTl&b zU&ha4SO#IdUwYuamh6+rdZP&8QnP!UD)|ZxZW)Nhx&R0HZ_I+rpQz5kjlFO}CEG}} zUI_o)we2dxyjc_2pvhGd6}t1jm`h4?`gjVswG=s@raUt2$aPg{y=Kd;{GJUDW(wR_ zAh42>=Z)j`_0rFzyT!eYZwJ@+*(m+;O278piTHPkMcc*r$VpC=5M-&a zop2%kz_+Nj3-FyWrssZuy-94?iT)W_u-r*}Nm|}jAs6T&5`NVEI7kDZwkrVonhE;y z#tS0KWZn;1|Am1&3CJT}OD!nY_)l47YP&1w<D8>B z>?wk9y&0>Tzt0K@b;=zOK<1(wD+`5R0&j%Iq}29%s>z-jRuQ|Jsdd!}4Z43Sa1W}= zhzB!+cg!oYZxS6lZW(JF+_NrrN}>K37{EgyE02z-1<8zfel`Z@Xdz6}O&jWK6E-~e zsJ$HB+4h3pN{*llT|14*fxm8JblysB@58Xx$<^;B=72@PuC^D6RylF2QYZRJu|#{5 zjSGJv$6sJIe+Bc@%RFBp$)0JwF;>ijog1(8Nv8sDH`v#ZE{AGg6rvC&srD9tvt?GsXGt#PKTXui4|PDAGR@Y?W5;qMMPtokGYcl&(wB06Q2f3dP&@k z?Q710g=LK86F>3Yzr{b@nK^XcK@jj9mbMn0FCK30Wo`%}jU-SHE$Fs(IMQ89Ge)!B z47Obl#}}ZKwX9$SH^?Ip%Hdn%pRHdiwO-?R_a24+{z2Qsg&T37p2}PH6EI=J< zL+)_`kk8)#(5P<*Hk56WkSN3ora9w6Dk&n^?cy&?3%Coh8;QodIhB;3Ss)-!U@VR; zXPX`EELFXlBqrykQ~IpX1~Gin(4$aAghvPD^c^T{UgmNw)hy0GPE2s|4XqVd?ey2X zM!xvrhY1aeN|#>-gXD&qUz<@w4F7A7jC`oVgj~eqoN@+Ixls8lrVF8MsqO0XRt@d9 z@G1|DR#eIP^pe}I7tBUvw~lLN_MLUuOST+OvbUF{0t-E0p$}R*pBCWgW3H3tcG@4@ z*+Gt+|4wMK*I?3Q!9|x#Tf39SvjwnDkOQzSO)EEOnL(ux1MdJXC~LK5#prKqZNAsqea3^qr&Ljck+ornZf!^#wYaEf&>C@Q}PsLGr#U^)93mQ zp+RXr@NkQ$xcTD0kk{WB8`d_MG>dzITlodxtC_B@I?ZF;@%<|ibpYKqgF?!a{>Sb2 zXdaFl=xF|e!hJ=J)fNHEpETRh z$g;U7UMm~8d)^y!Nn%d_dER#5N^k6QJOxk72Wsi<1&xxgnJ#kdo_M%ih3NbROuoFB zjmh5eG9Y|cq4GQ$T+J1YVWpR+6Vpyj^r92b= z4KUY1z{6rCA(oRw4uYs$6xwGBEZJ6T(iMDxmqfz-+=&$J+`p(8i+`sfMV%%HG4Wnr z<|`m{TW;uj725O7#0E_z$BGl%kc<#72njnS5*`WKrr-P;eh*?eZdK;b1ri^uS-0#2y+M%98V2k$ZHXsm}4GA}ia-If5rGSO&D3Cwb!G zMHE*B*~~NcyXkw)!CY4ltB2hdTs+8$ZujSgyeCUM+*Tx9m;Ipq*8L;kEPb*LIIBS0 z3OwOCRJo+4_VNaZHI!!sj@EAfFd>`iQXJZMAKWhpu_=;qr2aud6l6Y*qD|V4R_Bd! zU&DD)0_0HcfHP1N6R?g!$$vC_UDzsM6mojQFL3q#wiNFj7n`%}C5gdjGg8~jK=v|7 z!D#f}MK`#wp?ei2Pfj+oG@iPO@P{gJCFd!}@e@!~KT*(HNJJWaPIvemNjSrz9;^n~ z04+@stk3uvF+XqfkpP^ArKOj_f-*}ibJ@*Zf_)h{P6RW_Sdu?neb00k2fH*2s7--? zNLDse5qP%m0HO--gJ05ZUt*iIKiV_?)|5&Z5 z0k&!atk#LF{K1@gwynls_T$6vXmBGP0FWpSJ%>J};Ib2|3l51rYc?WPklSdptr~T3 zQ(yEsQZc_}_J9G-@JxiySMjzN7MaTwDvY4a?KPSF*-97g1t$;g(JfP*ivz54x9@B? zDDpMLrf5O#W(^S~^P0iXN!u1G4e|;!q!>hoHC78MS?**>wCNvXRfg4deKnXICY)g4 zKT?Z{r!#{M(7IdGM3h9}U5cw0uBRmQUb<#F6ik7OiL`vcZ81X4Vzst^(Jv_WQPJ6K zMBXjm6KE?-96W)EqgoT@AYiE5UN44j)n8Er*-|8IKF$+A{E<;@HTQfjX~_i!GeGfl;d;`!yx7YH_`Bu~Jl3+8lGn1}UFC;yenDe4IoTL-@lsWH=2f<;1S1 z1A5!?ya`vHz3wOSThIMDg_+fNmTNk-3){@w$9rj?RV6GIRe1(<k9pa>q4SEj#${{_$g^#c!m$8MaXoP^One`A90Q=upqFcn=(I15rG#%H8Y@RY zB-wirjeO5VHi%%NwVhwMdSLG%sXGbOqYJmcwZeT>0uw01EF0O(Qws6Edq3RT*jI6Q zJ^-VXOn2o9EfB3sK%l#xs9qHXn_NQC4FiAkYr+v})Q=oa%?|G7OQ5*=;oP`F4Z{{# zAKCpm2ROPJm&m|_8Lt>r9ODY+Jaqi{8@a_0un=4Y%jcbBYVHE%T!u6tMz`F7-n9GT zvYB0qb&=Z-M*&9}fPl~#7BWnUeU~e_ub5DysC-4)tjj#O=aCU# zbOJR){b#bzR`h97R%^kbKy7;0MpKUvcVqagw}7O? z)cwU~#G=lT62X4QLUIqpl9rABOfG(tTT~4j>h1sQ_$EgnF-wr8g*wKKLq(Q6l2v68 zs0sFk(U$LH0bKEwBJX84wtY01Y@L6SSmXs5LYS;Jtq>*E_6(>j+Yov5#lS=vF<))k zHEM;C33{k3p#ary{qq1i4ztfHLZ%=w(g$+|mJWNDJ#g{=l`_4nKekk*YsZiWj$UHy z3l0VA!C)Bq!vc4Bi(i#FXTMFMVr(_pS#2wS+K#YH8#1>dns>Ek|3iSswoKxN0oWLh zZqKuz3xCC(d2APTA;WwdI0?sC!yNCGcrKjkC}~%UUq34h_0nK^E*wY+6ZF1rp z(Q2S+^tglHwsPF^Q@=dDRd`T8qPvHxx?a_b5 z`2a^S`+ISe+wJ76|_i z41-B~^*9gXrpJ*x@3c&i@97SjJLuq6qS@itjNbKECBCO? zsNy(7S&m2ECNIXmwrbs#_$QqzzxLm&k|*C~cro3hNe_%MJ9!O2>+)hgc;I>{&RO== zk-^UXxF75e88PgdQ{Dy~GpvVfExD_mT%NUwnok~YItB51P#ZahER}*wLHO91di${+ z@vhq_bxOnF_+{JysMtg!<7egFuf#&t_CEQ;BAX?1BuJY_(KX7rFQgVGrUpY#;8&PmwrpS|;HQ{XWpU&hAf;$`)|_x=UL z&K}^Y5a0ZVi#>v8k{?k@2|mTH&?t33r9{(?9Yo82!UEPWVhcj5Jy(_&US8~}XgVl~ zQW$0Wn|_JkRPOQ@`!IUFLDEfEY9pU1OZ&))rWZv_=n4F1QB7mX)fP90R$onzovdzl zb~}MlBS+h<@P1?dv7Ku1_$^a~eWlcH^Y&5UY{v+-1|44*V3l)!SUHD(tK0Nre5+Ku ze=|$t9WmiJ%gdeNs8k&k5E<2Eln(36TBctD4;|5n`qY@i>-`dao&Fi+&5sHPI_zFY ze#`li@`yTDRI{5mI)x$vt7aN()@tcu%&znO?7A?*UzS$ei)mJue~%=t2ot_9@J_2_ z6Df)!GxzDy^-ySby?ei`|)BVLMU#2a1-h+*2+tVac8QfQ7r4M%VSY z_#oygB=fJtZBXP&6$;oh7#r10kF`(Do+;J(;8mN$u?QKFl z!qp-FSz%_oU4G5@0qJu_@*HgGP#56c9#7n}apkpv%Hj-yBBG5|3f1#2{V_gwHS&Rc7pjQS-p1@OUoBo`n=Zj$-ScJevTRw@sn=i*BT^ zbSQ{BlPxDc$BDiN2a-st?-XnH!EGENM}Is!ZBZ&^hRD1Nl(jR45;w@EGIyZr2CTJdV#geOD(hB$t*(P^~TSfg5Hg zPXIZwrAKfgS|z_s#r$e9evy8|ufpc4n+muj-kcoTEl~!UooQQGi#@-BjZkS({0%<; OhF~r1%*&3u6aNpuN&@u& diff --git a/doc/reference/muffin-docs.sgml b/doc/reference/muffin-docs.sgml deleted file mode 100644 index 8eaf3c4a1..000000000 --- a/doc/reference/muffin-docs.sgml +++ /dev/null @@ -1,55 +0,0 @@ - - - -]> - - - Muffin Reference Manual - - This document is for Muffin &version;. - - - - - - - - Muffin Core Reference - - - - - - - - - - - - - - - - - - - - - - Object Hierarchy - - - - API Index - - - - Index of deprecated API - - - - - diff --git a/doc/reference/muffin-docs.sgml.in b/doc/reference/muffin-docs.sgml.in deleted file mode 100644 index 250c8795e..000000000 --- a/doc/reference/muffin-docs.sgml.in +++ /dev/null @@ -1,55 +0,0 @@ - - - -]> - - - Muffin Reference Manual - - This document is for Muffin &version;. - - - - - - - - Muffin Core Reference - - - - - - - - - - - - - - - - - - - - - - Object Hierarchy - - - - API Index - - - - Index of deprecated API - - - - - diff --git a/doc/reference/muffin-overview.xml b/doc/reference/muffin-overview.xml deleted file mode 100644 index 1d5dda5ae..000000000 --- a/doc/reference/muffin-overview.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - Overview - - - - Muffin is a GObject-based library for creating compositing window managers. - - Compositors that wish to use Mutter must implement a subclass of #MetaPlugin and register it with meta_plugin_manager_set_plugin_type() before calling meta_init() but after g_type_init(). - - #MetaPlugin provides virtual functions that allow to override default behavior in the window management code, such as the effect to perform when a window is created or when switching workspaces. - - - - diff --git a/doc/reference/muffin/Makefile.am b/doc/reference/muffin/Makefile.am deleted file mode 100644 index 6073fda59..000000000 --- a/doc/reference/muffin/Makefile.am +++ /dev/null @@ -1,174 +0,0 @@ -## Process this file with automake to produce Makefile.in - -# We require automake 1.6 at least. -AUTOMAKE_OPTIONS = 1.6 - -# This is a blank Makefile.am for using gtk-doc. -# Copy this to your project's API docs directory and modify the variables to -# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples -# of using the various options. - -# The name of the module, e.g. 'glib'. -DOC_MODULE=muffin - -# Uncomment for versioned docs and specify the version of the module, e.g. '2'. -#DOC_MODULE_VERSION=2 - - -# The top-level SGML file. You can change this if you want to. -DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml - -# Directories containing the source code, relative to $(srcdir). -# gtk-doc will search all .c and .h files beneath these paths -# for inline comments documenting functions and macros. -# e.g. DOC_SOURCE_DIR=../../../gtk ../../../gdk -DOC_SOURCE_DIR=../../../src - -# Extra options to pass to gtkdoc-scangobj. Not normally needed. -SCANGOBJ_OPTIONS= - -# Extra options to supply to gtkdoc-scan. -# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" -SCAN_OPTIONS=--rebuild-types --rebuild-sections - -# Extra options to supply to gtkdoc-mkdb. -# e.g. MKDB_OPTIONS=--xml-mode --output-format=xml -MKDB_OPTIONS=--xml-mode --output-format=xml - -# Extra options to supply to gtkdoc-mktmpl -# e.g. MKTMPL_OPTIONS=--only-section-tmpl -MKTMPL_OPTIONS= - -# Extra options to supply to gtkdoc-mkhtml -MKHTML_OPTIONS= - -# Extra options to supply to gtkdoc-fixref. Not normally needed. -# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html -FIXXREF_OPTIONS = \ - --extra-dir=$(GLIB_PREFIX)/share/gtk-doc/html/glib \ - --extra-dir=$(GLIB_PREFIX)/share/gtk-doc/html/gobject \ - --extra-dir=$(CAIRO_PREFIX)/share/gtk-doc/html/cairo \ - --extra-dir=$(PANGO_PREFIX)/share/gtk-doc/html/pango \ - --extra-dir=$(GDK_PREFIX)/share/gtk-doc/html/gdk \ - --extra-dir=$(ATK_PREFIX)/share/gtk-doc/html/atk \ - --extra-dir=$(GDKPIXBUF_PREFIX)/share/gtk-doc/html/gdk-pixbuf \ - --extra-dir=../cogl/html \ - --extra-dir=../clutter/html - -# Used for dependencies. The docs will be rebuilt if any of these change. -# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h -# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c -HFILE_GLOB=$(top_srcdir)/src/*/*.h -CFILE_GLOB=$(top_srcdir)/src/*/*.c - -# Extra header to include when scanning, which are not under DOC_SOURCE_DIR -# e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h -EXTRA_HFILES= - -# Header files or dirs to ignore when scanning. Use base file/dir names -# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h private_code -IGNORE_HFILES= \ - async-getprop.h \ - atoms.h \ - bell.h \ - boxes-private.h \ - clutter-utils.h \ - cogl-utils.h \ - compositor-private.h \ - constraints.h \ - core.h \ - display-private.h \ - draw-workspace.h \ - edge-resistance.h \ - eventqueue.h \ - frame.h \ - frames.h \ - group-private.h \ - group-props.h \ - iconcache.h \ - inlinepixbufs.h \ - keybindings-private.h \ - meta-background-actor-private.h \ - meta-background-group-private.h \ - meta-dbus-login1.h \ - meta-module.h \ - meta-plugin-manager.h \ - meta-shadow-factory-private.h \ - meta-texture-rectangle.h \ - meta-texture-tower.h \ - meta-window-actor-private.h \ - meta-window-group.h \ - meta-window-shape.h \ - muffin-enum-types.h \ - muffin-Xatomtype.h \ - place.h \ - preview-widget.h \ - region-utils.h \ - resizepopup.h \ - screen-private.h \ - session.h \ - stack.h \ - stack-tracker.h \ - stamp-muffin-enum-types.h \ - tabpopup.h \ - theme.h \ - theme-private.h \ - tile-preview.h \ - ui.h \ - window-private.h \ - window-props.h \ - workspace-private.h \ - xprops.h \ - $(NULL) - -MKDB_OPTIONS+=--ignore-files="$(IGNORE_HFILES)" - -# Images to copy into HTML directory. -# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png -HTML_IMAGES= - -# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). -# e.g. content_files=running.sgml building.sgml changes-2.0.sgml -content_files= \ - muffin-overview.xml \ - running-muffin.xml \ - $(NULL) - -# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded -# These files must be listed here *and* in content_files -# e.g. expand_content_files=running.sgml -expand_content_files= \ - muffin-overview.xml \ - running-muffin.xml \ - $(NULL) - -# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library. -# Only needed if you are using gtkdoc-scangobj to dynamically query widget -# signals and properties. -# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) -# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) -GTKDOC_CFLAGS=$(WARN_CFLAGS) $(MUFFIN_CFLAGS) -GTKDOC_LIBS=$(MUFFIN_LIBS) $(top_builddir)/src/libmuffin.la - -# This includes the standard gtk-doc make rules, copied by gtkdocize. -include $(top_srcdir)/gtk-doc.make - -# Other files to distribute -# e.g. EXTRA_DIST += version.xml.in -EXTRA_DIST += - -# Files not to distribute -# for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types -# for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt -DISTCLEANFILES = $(DOC_MODULE).types $(DOC_MODULE)-sections.txt - -# Comment this out if you want 'make check' to test you doc status -# and run some sanity checks -if ENABLE_GTK_DOC -TESTS_ENVIRONMENT = cd $(srcdir) && \ - DOC_MODULE=$(DOC_MODULE) DOC_MAIN_SGML_FILE=$(DOC_MAIN_SGML_FILE) \ - SRCDIR=$(abs_srcdir) BUILDDIR=$(abs_builddir) -#TESTS = $(GTKDOC_CHECK) -endif - --include $(top_srcdir)/git.mk diff --git a/doc/reference/muffin/muffin-docs.sgml.in b/doc/reference/muffin/muffin-docs.sgml.in deleted file mode 100644 index 250c8795e..000000000 --- a/doc/reference/muffin/muffin-docs.sgml.in +++ /dev/null @@ -1,55 +0,0 @@ - - - -]> - - - Muffin Reference Manual - - This document is for Muffin &version;. - - - - - - - - Muffin Core Reference - - - - - - - - - - - - - - - - - - - - - - Object Hierarchy - - - - API Index - - - - Index of deprecated API - - - - - diff --git a/doc/reference/muffin/muffin-overrides.txt b/doc/reference/muffin/muffin-overrides.txt deleted file mode 100644 index e69de29bb..000000000 diff --git a/doc/reference/muffin/muffin-overview.xml b/doc/reference/muffin/muffin-overview.xml deleted file mode 100644 index 1d5dda5ae..000000000 --- a/doc/reference/muffin/muffin-overview.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - Overview - - - - Muffin is a GObject-based library for creating compositing window managers. - - Compositors that wish to use Mutter must implement a subclass of #MetaPlugin and register it with meta_plugin_manager_set_plugin_type() before calling meta_init() but after g_type_init(). - - #MetaPlugin provides virtual functions that allow to override default behavior in the window management code, such as the effect to perform when a window is created or when switching workspaces. - - - - diff --git a/doc/reference/muffin/running-muffin.xml b/doc/reference/muffin/running-muffin.xml deleted file mode 100644 index fabcf6ab2..000000000 --- a/doc/reference/muffin/running-muffin.xml +++ /dev/null @@ -1,100 +0,0 @@ - - - Running Muffin - - - -
- Environment Variables - - - Muffin automatically checks environment variables during - its initialization. These environment variables are meant - as debug tools or overrides for default behaviours: - - - - - MUFFIN_VERBOSE - - Enable verbose mode, in which more information is printed to the console. Muffin needs to be built with the --enable-verbose-mode option (enabled by default). For more fine-grained control of the output, see meta_add_verbose_topic(). - - - - MUFFIN_DEBUG - - Traps and prints X errors to the console. - - - - MUFFIN_G_FATAL_WARNINGS - - Causes any logging from the domains Muffin, Gtk, Gdk, Pango or GLib to terminate the process (only when using the log functions in GLib). - - - - MUFFIN_USE_LOGFILE - - Log all messages to a temporary file. - - - - MUFFIN_DEBUG_XINERAMA - - Log extra information about support of the XINERAMA extension. - - - - MUFFIN_DEBUG_SM - - Log extra information about session management. - - - - MUFFIN_DEBUG_BUTTON_GRABS - - Log extra information about button grabs. - - - - MUFFIN_SYNC - - Call XSync after each X call. - - - - MUFFIN_DISPLAY - - Name of the X11 display to use. - - - - META_DISABLE_MIPMAPS - - Disable use of mipmaps for the textures that back window pixmaps. - - - - MUFFIN_USE_STATIC_GRAVITY - - Enable support for clients with static bit-gravity. - - - - MUFFIN_WM_CLASS_FILTER - - Comma-separated list of WM_CLASS names to which to restrict Muffin to. - - - - MUFFIN_DISABLE_FALLBACK_COLOR - - Disable fallback for themed colors, for easier detection of typographical errors. - - - - -
- -
-
diff --git a/doc/reference/running-muffin.xml b/doc/reference/running-muffin.xml deleted file mode 100644 index fabcf6ab2..000000000 --- a/doc/reference/running-muffin.xml +++ /dev/null @@ -1,100 +0,0 @@ - - - Running Muffin - - - -
- Environment Variables - - - Muffin automatically checks environment variables during - its initialization. These environment variables are meant - as debug tools or overrides for default behaviours: - - - - - MUFFIN_VERBOSE - - Enable verbose mode, in which more information is printed to the console. Muffin needs to be built with the --enable-verbose-mode option (enabled by default). For more fine-grained control of the output, see meta_add_verbose_topic(). - - - - MUFFIN_DEBUG - - Traps and prints X errors to the console. - - - - MUFFIN_G_FATAL_WARNINGS - - Causes any logging from the domains Muffin, Gtk, Gdk, Pango or GLib to terminate the process (only when using the log functions in GLib). - - - - MUFFIN_USE_LOGFILE - - Log all messages to a temporary file. - - - - MUFFIN_DEBUG_XINERAMA - - Log extra information about support of the XINERAMA extension. - - - - MUFFIN_DEBUG_SM - - Log extra information about session management. - - - - MUFFIN_DEBUG_BUTTON_GRABS - - Log extra information about button grabs. - - - - MUFFIN_SYNC - - Call XSync after each X call. - - - - MUFFIN_DISPLAY - - Name of the X11 display to use. - - - - META_DISABLE_MIPMAPS - - Disable use of mipmaps for the textures that back window pixmaps. - - - - MUFFIN_USE_STATIC_GRAVITY - - Enable support for clients with static bit-gravity. - - - - MUFFIN_WM_CLASS_FILTER - - Comma-separated list of WM_CLASS names to which to restrict Muffin to. - - - - MUFFIN_DISABLE_FALLBACK_COLOR - - Disable fallback for themed colors, for easier detection of typographical errors. - - - - -
- -
-
diff --git a/doc/strut-and-related-updating.txt b/doc/strut-and-related-updating.txt new file mode 100644 index 000000000..a00cee4b2 --- /dev/null +++ b/doc/strut-and-related-updating.txt @@ -0,0 +1,54 @@ +How updates happen for struts, workareas, and screen/xinerama regions/edges: + One of three things causes meta_window_update_struts to be called + (a) initial window map (window.c:meta_window_new_with_attrs()) + (b) update of _net_wm_strut* properties (window.c:process_property_notify()) + (c) screen resizes (e.g. via xrandr; from screen.c:meta_screen_resize_func()) + meta_window_update_struts (MetaWindow *window) + - Gets new list of struts from window properties + - Makes sure window doesn't single-handedly fill the screen + - records new struts if different and calls invalidate_work_areas() + invalidate_work_areas () + - Calls meta_workspace_invalidate_work_area() for each workspace it's on + meta_workspace_invalidate_work_area() + - Cleans out all strut lists + - queues all windows for resizing + - Calls meta_screen_queue_workarea_recalc (workspace->screen); + meta_screen_queue_workarea_recalc() + - Adds set_work_area_idle_func() as an idle handler + + set_work_area_idle_func() + - Calls set_work_area_hint() + set_work_area_hint() + - Calls meta_workspace_get_work_area_all_xineramas() + - Sets _NET_WORKAREA property + meta_workspace_get_work_area_all_xineramas() + - Calls ensure_work_areas_validated() + ensure_work_areas_validated() + - Loops over xineramas + - Loops over windows, then struts: + - Adds struts to list first time through xinerama loop + - Find the amount of the strut on the given xinerama for _strut + - Just max the amount of the strut with the all__strut + - Makes sure there's a non-empty xinerama workarea + - Record the xinerama workarea + - Make sure there's a non-empty screen workarea + - Record the screen workarea + - Cache the spanning rects for the screen and xinerama regions + - Cache the screen and xinerama edges + + Alternatively to all the above, if the idle function for the screen + has not yet fired, constraints.c:setup_constraint_info() can call + either workspace.c:meta_workspace_get_onscreen_region() or + workspace.c:meta_workspace_get_onxinerama_region() which in turn + call workspace.c:ensure_work_areas_validated(). + +Meaning of related functions that might be difficult to tell apart: + screen.c:meta_screen_get_current_xinerama () + - Finds out which xinerama the mouse is on with an XQueryPointer + window.c:meta_window_get_work_area_current_xinerama() + window.c:meta_window_get_work_area_for_xinerama() + window.c:meta_window_get_work_area_all_xineramas () + - All three are for finding the intersection of workareas across + multiple workspaces so that placement of windows can be + determined in such a way that they remain in the workarea for + all workspaces that they are on. diff --git a/doc/theme-format.txt b/doc/theme-format.txt deleted file mode 100644 index 2a58e3550..000000000 --- a/doc/theme-format.txt +++ /dev/null @@ -1,396 +0,0 @@ -Themes are in a simple XML-subset format. There are multiple versions -of the theme format, and a given theme can support more than one format. - -Version 1: THEMEDIR/metacity-1/metacity-theme-1.xml - (original metacity format) -Version 2: THEMEDIR/metacity-1/metacity-theme-2.xml -Version 3: THEMEDIR/metacity-1/metacity-theme-3.xml - -The subdirectory name is "metacity-1" in all versions. - -As you might expect, older versions of metacity will not understand -newer theme formats. However, newer versions will use old themes. -Metacity will always use the newest theme format it understands that -the X server supports. Some format versions are only supported if you -have the right X server features. - -Each format *requires* the corresponding filename. If you put version -2 format features in the metacity-1/metacity-theme-1.xml file, then -metacity will get angry. - -This document has separate sections for each format version. You may -want to read the document in reverse order, since the base features -are discussed under version 1. - -New Features in Theme Format Version 3.4 -======================================== - -An additional color type is added to pick up custom colors defined -in the GTK+ theme's CSS: - - gtk:custom(name,fallback) - -where refers to a custom color defined with @define-color in -the GTK+ theme, and provides an alternative color definition -in case the color referenced by is not found. - -New Features in Theme Format Version 3.3 -======================================== - -Add two additional button background functions - left_single_background and -right_single_background - for button groups with just a single button. - -There are now additional frame states to style left/right tiled windows -differently ("tiled_left", "tiled_right", "tiled_left_and_shaded", -"tiled_right_and_shaded"). - -New Features in Theme Format Version 3.2 -======================================== - -A new window type 'attached' is added for modal dialogs which are -attached to their parent window. (When the attach_modal_dialogs preference -is turned on.) If no style is defined for the 'attached' window type, -the 'border' window type will be used instead. - -New Features in Theme Format Version 3.1 -======================================== - -Additional predefined variables are added for positioning expressions: - - frame_x_center: the X center of the entire frame, with respect to the - piece currently being drawn. - frame_y_center: the Y center of the entire frame, with respect to the - piece currently being drawn. - -The element now supports an "ellipsize_width" attribute. When -specified, this gives a width at which to ellipsize the title. If not -specified, the title will simply be clipped to the title area. - -New Features in Theme Format Version 3 -====================================== - -Format version 3 has exactly one new feature; any element in the file -can now have a version attribute: - - version="[<|<=|=>|>] MAJOR.MINOR" - -(< and > should be to be entity escaped as < and >). If this -version check is not met, then the element and its children will be -ignored. This allows having alternate sections of the theme file for -older and newer version of the Metacity theme format. - -When placed on the toplevel <metacity_theme> element, an unsatisfied -version check will not just cause the contents of the file to be -ignored, it will also cause the lookup of a theme file to proceed on -and look for an older format 2 or format 1 file. This allows making a -metacity-theme-3.xml file that is only used the format version 3.2 or -newer is supported, and using metacity-theme-1.xml for older window -managers. - -New Features in Theme Format Version 2 -====================================== - -The optional attributes rounded_top_left, rounded_top_right, -rounded_bottom_left and rounded_bottom_right on <frame_geometry> -should now be the radius of the corner in pixels. You may still use -the values "false" for 0 and "true" for 5, which means v1 values will -still work just fine. - -<frame_geometry> has a new optional attribute, hide_buttons. If this -is true, no buttons will be displayed on the titlebar. - -Anywhere you can use a positive integer, you can use an integer constant. - -As well as constant integers and reals, you may define constant colours, -thus: - <constant name="RevoltingPink" value="#FF00FF"/> - <constant name="Background" value="gtk:bg[NORMAL]"/> - -<frame_style> has two new optional attributes, background and alpha. -If you specify alpha, you must specify background. background is a -colour used for the background of the frame. alpha is the transparency -as a real between 0.0 and 1.0. If the current X server does not support -alpha channels, the value is ignored. - -The filename attribute of <image> may begin with "theme:". If so, the -rest of the string is the name of a theme icon. The 64x64 version of the -icon is used, except for fallback mini_icons, which use the 16x16 version. -This does not affect ordinary resizing. For example: - <button function="close" state="normal"> - <draw_ops> - <include name="active_button"/> - <image filename="theme:gnome-logout" x="2" y="2" - width="width-4" height="height-4"/> - <!-- Note: not "theme:gnome-logout.png" or similar. --> - </draw_ops> - </button> - -<menu_icon>s are parsed but ignored. - -Fallback icons can be specified using <fallback>. There are two -optional arguments, icon and mini_icon. The values of these arguments -are identical to that of the filename attribute of <image>. Fallback -icons are used when a window does not supply its own icon. If a fallback -icon is not specified with <fallback>, Metacity will use a built-in -icon, as in metacity-theme-1. - -The <arc> element, as well as the original start_angle and end_angle -attributes, may be given from and to attributes. The values of these -attributes are given in degrees clockwise, with 0 being straight up. -For example: - <arc from="0.0" to="90.0" filled="true" color="#FF00FF" - x="0" y="5" width="15" height="15"/> - -<frame state="shaded"> may now take an optional resize attribute, with -the same interpretation as the resize attribute on <frame state="normal">. -If this attribute is omitted for state="shaded", it defaults to "both". -(If it is omitted for state="normal", it remains an error.) - -In addition to the four <button> functions which are required in -metacity-theme-1, there are six new functions in metacity-theme-2: -shade, unshade, above, unabove, stick and unstick. - -Overview of Theme Format Version 1 -================================== - -<?xml version="1.0"?> -<metacity_theme> -<!-- Only one info section is allowed --> -<info> - <name>Foo</name> - <author>Foo P. Bar</author> - <copyright>whoever, 2002</copyright> - <date>Jan 31 2005</date> - <description>A sentence about the theme.</description> -</info> - -<!-- define a frame geometry to be referenced later --> -<!-- frame_geometry has an optional has_title attribute which - determines whether the title text height is included in the - height calculation. if not specified, defaults to true. - It also has an optional text_size="medium" attribute - (same sizes as with Pango markup, xx-small thru medium thru - xx-large) - - Finally it has optional args rounded_top_left=true, - rounded_top_right=true, rounded_bottom_left=true, - rounded_bottom_right=true. - - --> -<frame_geometry name="normal" has_title="true" title_scale="medium"> - <distance name="left_width" value="6"/> - <distance name="right_width" value="6"/> - <distance name="bottom_height" value="7"/> - <distance name="left_titlebar_edge" value="6"/> - <distance name="right_titlebar_edge" value="6"/> - <distance name="button_width" value="17"/> - <distance name="button_height" value="17"/> - <!-- alternative to button_width button_height distances --> - <aspect_ratio name="button" value="1.0"/> - <distance name="title_vertical_pad" value="4"/> - <border name="title_border" left="3" right="12" top="4" bottom="3"/> - <border name="button_border" left="0" right="0" top="1" bottom="1"/> -</frame_geometry> - -<!-- inheritance is allowed; simply overwrites values from parent --> -<frame_geometry name="borderless" parent="normal"> - <distance name="left_width" value="0"/> - <distance name="right_width" value="0"/> - <distance name="bottom_height" value="0"/> - <distance name="left_titlebar_edge" value="0"/> - <distance name="right_titlebar_edge" value="0"/> -</frame_geometry> - -<!-- define a constant to use in positions/sizes of draw operations; - constant names must start with a capital letter. - --> -<constant name="LineOffset" value="3"/> - -<!-- define drawing operations to be referenced later; - these draw-op lists can also be placed inline. - - Positions/lengths are given as expressions. - Operators are: +,-,*,/,%,`max`,`min` - All operators are infix including `max` and `min`, - i.e. "2 `max` 5" - - Some variables are predefined, and constants can also - be used. Variables are: - - width - width of target area - height - height of target area - object_width - natural width of object being drawn - object_height - natural height of object being drawn - left_width - distance from left of frame to client window - right_width - distance from right of frame to client window - top_height - distance from top of frame to client window - bottom_height - distance from bottom of frame to client window - mini_icon_width - width of mini icon for window - mini_icon_height - height of mini icon - icon_width - width of large icon - icon_height - height of large icon - title_width - width of title text - title_height - height of title text - - All these are always defined, except object_width/object_height - which only exists for <image> right now. - - --> - -<draw_ops name="demo_all_ops"> - <line color="#00FF00" x1="LineOffset" y1="0" x2="0" y2="height"/> - <line color="gtk:fg[NORMAL]" - x1="width - 1" y1="0" x2="width - 1" y2="height" - width="3" dash_on_length="2" dash_off_length="3"/> - <rectangle color="blend/gtk:fg[NORMAL]/gtk:bg[NORMAL]/0.7" - x="0" y="0" width="width - 1" height="height - 1" filled="true"/> - <arc color="dark gray" x="0" y="0" width="width - 1" height="height - 1" - filled="false" start_angle="30" extent_angle="180"/> - <tint color="orange" alpha="0.5" x="0" y="0" width="width" height="height"/> - <!-- may be vertical, horizontal, diagonal --> - <gradient type="diagonal" - x="10" y="30" width="width / 3" height="height / 4"> - <!-- any number of colors allowed here. A color can be - a color name like "blue" (look at gcolorsel), a hex color - as in HTML (#FFBB99), or a color from the gtk theme - given as "gtk:base[NORMAL]", "gtk:fg[ACTIVE]", etc. - --> - <color value="gtk:fg[SELECTED]"/> - <!-- color obtained by a 0.5 alpha composite of the second color onto the first --> - <color value="blend/gtk:bg[SELECTED]/gtk:fg[SELECTED]/0.5"/> - </gradient> - <!-- image has an optional colorize="#color" attribute to give the - image a certain color --> - <image filename="foo.png" alpha="0.7" - x="10" y="30" width="width / 3" height="height / 4"/> - <gtk_arrow state="normal" shadow="in" arrow="up" - filled="true" - x="2" y="2" width="width - 4" height="height - 4"/> - <gtk_box state="normal" shadow="out" - x="2" y="2" width="width - 4" height="height - 4"/> - <gtk_vline state="normal" x="2" y1="0" y2="height"/> - <!-- window's icon --> - <icon alpha="0.7" - x="10" y="30" width="width / 3" height="height / 4"/> - <!-- window's title --> - <title color="gtk:text[NORMAL]" x="20" y="30"/> - <!-- include another draw ops list; has optional x/y/width/height attrs --> - <include name="some_other_draw_ops"/> - <!-- tile another draw ops list; has optional - x/y/width/height/tile_xoffset/tile_yoffset --> - <tile name="some_other_draw_ops" tile_width="10" tile_height="10"/> -</draw_ops> - -<frame_style name="normal" geometry="normal"> - <!-- How to draw each piece of the frame. - For each piece, a draw_ops can be given inline or referenced - by name. If a piece is omitted, then nothing will be drawn - for that piece. - - For each piece, the "width" and "height" variables in - coordinate expressions refers to the dimensions of the piece, - the origin is at the top left of the piece. - - So <rectangle x="0" y="0" width="width-1" height="height-1"/> - will outline a piece. - --> - - <piece position="entire_background" draw_ops="demo_all_ops"/> - <piece position="left_titlebar_edge"> - <draw_ops> - <line color="#00FF00" x1="0" y1="0" x2="0" y2="height"/> - </draw_ops> - </piece> - - <!-- The complete list of frame pieces: - - entire_background: whole frame - titlebar: entire area above the app's window - titlebar_middle: area of titlebar_background not considered - part of an edge - left_titlebar_edge: left side of titlebar background - right_titlebar_edge: right side of titlebar background - top_titlebar_edge: top side of titlebar background - bottom_titlebar_edge: bottom side of titlebar background - title: the title area (doesn't include buttons) - left_edge: left edge of the frame - right_edge: right edge of the frame - bottom_edge: bottom edge of the frame - overlay: same area as entire_background, but drawn after - drawing all sub-pieces instead of before - - --> - - <!-- For buttons, drawing methods have to be provided for - each of three states: - normal, pressed, prelight - and the button function or position must be provided: - close, maximize, minimize, menu, - left_left_background, left_middle_background, - left_right_background, right_left_background, - right_middle_background, right_right_background - So a working theme needs 3*4 = 12 button declarations - and a theme may have up to 3*10 = 30 button declarations - in order to handle button-rearrangement preferences. - - (The name "function" for the attribute is from before the - background values existed.) - --> - - <button function="close" state="normal" draw_ops="previously_named"/> - <button function="menu" state="normal"> - <draw_ops> - <icon alpha="0.7" - x="0" y="0" width="object_width" height="object_height"/> - </draw_ops> - </button> - -</frame_style> - -<!-- styles can inherit from each other with the parent="" attribute. - In a subclass anything can be re-specified to override - the parent style. --> -<frame_style name="focused" parent="normal"> - <piece position="title"> - <draw_ops> - <rectangle color="gtk:bg[SELECTED]" - x="0" y="0" width="width-1" height="height-1"/> - <title color="gtk:fg[SELECTED]" x="(width - title_width) / 2" - y="(height - title_height) / 2"/> - </draw_ops> - </piece> -</frame_style> - -<!-- Maps styles to states of frame. - - Focus: yes (focused), no (not focused) - Window states: normal, maximized, shaded, maximized_and_shaded - Window resizability: none, vertical, horizontal, both - - Everything unspecified just does the same as - unfocused/normal/both. - - only state="normal" needs a resize="" attribute. - --> -<frame_style_set name="normal"> -<frame focus="yes" state="normal" resize="both" style="focused"/> -<frame focus="no" state="normal" resize="both" style="normal"/> -</frame_style_set> - -<!-- Each window type needs a style set - Types: normal, dialog, modal_dialog, menu, utility, border - --> -<window type="normal" style_set="normal"/> - - -<!-- For menu icons, drawing methods are needed for the same - four types as the buttons, and GTK states - (insensitive,prelight,normal,etc.) - --> - -<menu_icon function="close" state="normal" draw_ops="previously_named"/> - - -</metacity_theme> - - diff --git a/meson.build b/meson.build new file mode 100644 index 000000000..2fdec9736 --- /dev/null +++ b/meson.build @@ -0,0 +1,480 @@ +project('muffin', 'c', + version: '5.3.0', + meson_version: '>= 0.50.0', + license: 'GPLv2+' +) + +mutter_plugin_api_version = '3' + +split_version = meson.project_version().split('.') + +# Automatically increase API version each development cycle, +# starting with 0 in 3.23.x +api_version = 0 +libmutter_api_version = '@0@'.format(api_version) + +# generic version requirements +fribidi_req = '>= 1.0.0' +glib_req = '>= 2.61.1' +gi_req = '>= 0.9.5' +graphene_req = '>= 1.9.3' +gtk3_req = '>= 3.19.8' +gdk_pixbuf_req = '>= 2.0' +uprof_req = '>= 0.3' +pango_req = '>= 1.2.0' +cairo_req = '>= 1.10.0' +pangocairo_req = '>= 1.20' +json_glib_req = '>= 0.12.0' +upower_glib_req = '>= 0.99.0' +xcomposite_req = '>= 0.4' +xkbcommon_req = '>= 0.4.3' +xfixes_req = '>= 3' +xi_req = '>= 1.7.4' +xrandr_req = '>= 1.5.0' +libstartup_notification_req = '>= 0.7' +libcanberra_req = '>= 0.26' +libwacom_req = '>= 0.13' +atk_req = '>= 2.5.3' + +# optional version requirements +udev_req = '>= 228' +gudev_req = '>= 232' + +# wayland version requirements +wayland_server_req = '>= 1.13.0' +wayland_protocols_req = '>= 1.19' + +# native backend version requirements +libinput_req = '>= 1.7' +gbm_req = '>= 10.3' + +# screen cast version requirements +libpipewire_req = '>= 0.3.0' + +# profiler requirements +sysprof_req = '>= 3.35.2' + +gnome = import('gnome') +pkg = import('pkgconfig') +i18n = import('i18n') +cc = meson.get_compiler('c') + +prefix = get_option('prefix') + +bindir = join_paths(prefix, get_option('bindir')) +datadir = join_paths(prefix, get_option('datadir')) +libdir = join_paths(prefix, get_option('libdir')) +libexecdir = join_paths(prefix, get_option('libexecdir')) +includedir = join_paths(prefix, get_option('includedir')) +sysconfdir = get_option('sysconfdir') + +pkgname = '@0@'.format(meson.project_name()) + +pkgdatadir = join_paths(datadir, pkgname) +pkglibdir = join_paths(libdir, pkgname) +pkgincludedir = join_paths(includedir, pkgname) + +pcdir = join_paths(libdir, 'pkgconfig') + +gettext_package = meson.project_name() +localedir = join_paths(datadir, 'locale') + +libmutter_name = 'muffin' + +mutter_installed_tests_datadir = join_paths( + datadir, 'installed-tests', libmutter_name) + +mutter_installed_tests_libexecdir = join_paths( + libexecdir, 'installed-tests', libmutter_name) + +m_dep = cc.find_library('m', required: true) +x11_dep = dependency('x11') +graphene_dep = dependency('graphene-gobject-1.0', version: graphene_req) +gtk3_dep = dependency('gtk+-3.0', version: gtk3_req) +gdk_pixbuf_dep = dependency('gdk-pixbuf-2.0') +pango_dep = dependency('pango', version: pango_req) +cairo_dep = dependency('cairo', version: cairo_req) +cairo_gobject_dep = dependency('cairo-gobject', version: cairo_req) +pangocairo_dep = dependency('pangocairo', version: pangocairo_req) +fribidi_dep = dependency('fribidi', version: fribidi_req) +glib_dep = dependency('glib-2.0', version: glib_req) +gio_dep = dependency('gio-unix-2.0', version: glib_req) +gio_unix_dep = dependency('gio-unix-2.0', version: glib_req) +gobject_dep = dependency('gobject-2.0', version: glib_req) +gthread_dep = dependency('gobject-2.0', version: glib_req) +gmodule_no_export_dep = dependency('gmodule-no-export-2.0', version: glib_req) +json_glib_dep = dependency('json-glib-1.0', version: json_glib_req) +cinnamon_desktop_dep = dependency('cinnamon-desktop', version: '>= 5.3') +xcomposite_dep = dependency('xcomposite', version: xcomposite_req) +xcursor_dep = dependency('xcursor') +xdamage_dep = dependency('xdamage') +xext_dep = dependency('xext') +xfixes_dep = dependency('xfixes', version: xfixes_req) +xi_dep = dependency('xi', version: xi_req) +xtst_dep = dependency('xtst') +xkbfile_dep = dependency('xkbfile') +xkeyboard_config_dep = dependency('xkeyboard-config') +xkbcommon_dep = dependency('xkbcommon', version: xkbcommon_req) +xkbcommon_x11_dep = dependency('xkbcommon-x11') +xrender_dep = dependency('xrender') +x11_xcb_dep = dependency('x11-xcb') +xrandr_dep = dependency('xrandr', version: xrandr_req) +xcb_randr_dep = dependency('xcb-randr') +xcb_res_dep = dependency('xcb-res') +xinerama_dep = dependency('xinerama') +xau_dep = dependency('xau') +ice_dep = dependency('ice') +atk_dep = dependency('atk', version: atk_req) +libcanberra_dep = dependency('libcanberra', version: libcanberra_req) +dbus_dep = dependency('dbus-1') + +# For now always require X11 support +have_x11 = true + +have_gl = get_option('opengl') +if have_gl + gl_dep = dependency('gl') + gl_libname = get_option('opengl_libname') +endif + +have_egl = get_option('egl') +if have_egl + egl_dep = dependency('egl') +endif + +have_glx = get_option('glx') +if have_glx + if not have_gl + error('GLX support requires OpenGL to be enabled') + endif +endif + +have_egl_xlib = have_egl and have_x11 + +have_gles2 = get_option('gles2') +if have_gles2 + gles2_dep = dependency('glesv2') + gles2_libname = get_option('gles2_libname') + + if not have_egl + error('GLESv2 support requires EGL to be enabled') + endif +endif + +have_wayland = get_option('wayland') +if have_wayland + wayland_server_dep = dependency('wayland-server', version: wayland_server_req) + wayland_client_dep = dependency('wayland-client', version: wayland_server_req) + wayland_protocols_dep = dependency('wayland-protocols', + version: wayland_protocols_req) + wayland_egl_dep = dependency('wayland-egl') + + if not have_egl + error('Wayland support requires EGL to be enabled') + endif +endif + +have_libgudev = get_option('udev') +if have_libgudev + libudev_dep = dependency('libudev', version: udev_req) + gudev_dep = dependency('gudev-1.0', version: gudev_req) +endif + +have_native_backend = get_option('native_backend') +if have_native_backend + libdrm_dep = dependency('libdrm') + libgbm_dep = dependency('gbm', version: gbm_req) + libinput_dep = dependency('libinput', version: libinput_req) + + libsystemd_dep = dependency('libsystemd', required: false) + if libsystemd_dep.found() + logind_provider_dep = libsystemd_dep + else + logind_provider_dep = dependency('libelogind') + endif + + if not have_egl + error('The native backend requires EGL to be enabled') + endif + + if not have_gles2 + error('The native backend requires GLESv2 to be enabled') + endif + + if not have_libgudev + error('The native backend requires udev to be enabled') + endif +endif + +have_egl_device = get_option('egl_device') + +have_wayland_eglstream = get_option('wayland_eglstream') +if have_wayland_eglstream + wayland_eglstream_protocols_dep = dependency('wayland-eglstream-protocols') + dl_dep = cc.find_library('dl', required: true) + + if not have_wayland + error('Wayland EGLStream support requires Wayland to be enabled') + endif +endif + +default_driver = get_option('default_driver') + +have_sm = get_option('sm') +if have_sm + sm_dep = dependency('sm') +endif + +have_libwacom = get_option('libwacom') +if have_libwacom + libwacom_dep = dependency('libwacom', version: libwacom_req) +endif + +have_pango_ft2 = get_option('pango_ft2') +if have_pango_ft2 + pangoft2_dep = dependency('pangoft2') +endif + +have_startup_notification = get_option('startup_notification') +if have_startup_notification + libstartup_notification_dep = dependency('libstartup-notification-1.0', + version: libstartup_notification_req) +endif + +have_remote_desktop = get_option('remote_desktop') +if have_remote_desktop + libpipewire_dep = dependency('libpipewire-0.3', version: libpipewire_req) +endif + +have_introspection = get_option('introspection') +if have_introspection + gobject_introspection_dep = dependency('gobject-introspection-1.0') + + introspection_args = [ + '--quiet', + '-U_GNU_SOURCE', + ] +endif + +have_tests = get_option('tests') +have_core_tests = false +have_cogl_tests = false +have_clutter_tests = false +have_installed_tests = false + +if have_tests + have_core_tests = get_option('core_tests') + if have_core_tests + if not have_wayland + error('Tests require Wayland to be enabled') + endif + endif + + have_cogl_tests = get_option('cogl_tests') + have_clutter_tests = get_option('clutter_tests') + have_installed_tests = get_option('installed_tests') +endif + +have_profiler = get_option('profiler') +if have_profiler + sysprof_dep = dependency('sysprof-capture-3', version: sysprof_req) +endif + +required_functions = [ + 'ffs', + 'clz', + 'memmem', +] +foreach function : required_functions + if not cc.has_function(function) + error('Required function ' + function + ' missing') + endif +endforeach + +if host_machine.cpu_family() == 'x86' + add_project_arguments('-ffloat-store', language: 'c') +endif +add_project_arguments('-D_GNU_SOURCE', language: 'c') + +buildtype = get_option('buildtype') +if buildtype != 'plain' + all_warnings = [ + '-fno-strict-aliasing', + '-Wpointer-arith', + '-Wmissing-declarations', + '-Wimplicit-function-declaration', + '-Wformat=2', + '-Wformat-nonliteral', + '-Wformat-security', + '-Wstrict-prototypes', + '-Wmissing-prototypes', + '-Wnested-externs', + '-Wold-style-definition', + '-Wundef', + '-Wunused', + '-Wcast-align', + '-Wmissing-noreturn', + '-Wmissing-format-attribute', + '-Wmissing-include-dirs', + '-Wlogical-op', + '-Wignored-qualifiers', + '-Werror=redundant-decls', + '-Werror=implicit', + '-Werror=nonnull', + '-Werror=init-self', + '-Werror=main', + '-Werror=missing-braces', + '-Werror=sequence-point', + '-Werror=return-type', + '-Werror=trigraphs', + '-Werror=array-bounds', + '-Werror=write-strings', + '-Werror=address', + '-Werror=int-to-pointer-cast', + '-Werror=pointer-to-int-cast', + '-Werror=empty-body', + '-Werror=write-strings', + ] + supported_warnings = cc.get_supported_arguments(all_warnings) + add_project_arguments(supported_warnings, language: 'c') +endif + +if get_option('debug') + debug_c_args = [ + '-DG_ENABLE_DEBUG', + '-fno-omit-frame-pointer' + ] + supported_debug_c_args = cc.get_supported_arguments(debug_c_args) + add_project_arguments(supported_debug_c_args, language: 'c') +endif + +cc.compiles('void main (void) { __builtin_ffsl (0); __builtin_popcountl (0); }') + +cdata = configuration_data() +cdata.set_quoted('GETTEXT_PACKAGE', gettext_package) +cdata.set_quoted('VERSION', meson.project_version()) +cdata.set_quoted('PACKAGE_VERSION', meson.project_version()) + +cdata.set('HAVE_EGL', have_egl) +cdata.set('HAVE_WAYLAND', have_wayland) +cdata.set('HAVE_NATIVE_BACKEND', have_native_backend) +cdata.set('HAVE_REMOTE_DESKTOP', have_remote_desktop) +cdata.set('HAVE_EGL_DEVICE', have_egl_device) +cdata.set('HAVE_WAYLAND_EGLSTREAM', have_wayland_eglstream) +cdata.set('HAVE_LIBGUDEV', have_libgudev) +cdata.set('HAVE_LIBWACOM', have_libwacom) +cdata.set('HAVE_SM', have_sm) +cdata.set('HAVE_STARTUP_NOTIFICATION', have_startup_notification) +cdata.set('HAVE_INTROSPECTION', have_introspection) +cdata.set('HAVE_PROFILER', have_profiler) + +xkb_base = xkeyboard_config_dep.get_pkgconfig_variable('xkb_base') +cdata.set_quoted('XKB_BASE', xkb_base) + +if cc.has_header_symbol('sys/prctl.h', 'prctl') + cdata.set('HAVE_SYS_PRCTL', 1) +endif + +have_xwayland_initfd = false +if have_wayland + xwayland_path = get_option('xwayland_path') + if xwayland_path == '' + xwayland_path = find_program('Xwayland').path() + endif + cdata.set_quoted('XWAYLAND_PATH', xwayland_path) + + # For Xwayland authority file generation. + if cc.has_header_symbol('sys/random.h', 'getrandom') + cdata.set('HAVE_SYS_RANDOM', 1) + elif cc.has_header_symbol('linux/random.h', 'getrandom') + cdata.set('HAVE_LINUX_RANDOM', 1) + else + error('Required function getrandom not found') + endif + + # For Xwayland -initfd usage + use_initfd = get_option('xwayland_initfd') + if use_initfd.auto() + xwayland_options = run_command(xwayland_path, '-help') + have_xwayland_initfd = xwayland_options.stderr().contains('-initfd') + else + have_xwayland_initfd = use_initfd.enabled() + endif + + if (have_xwayland_initfd) + cdata.set('HAVE_XWAYLAND_INITFD', 1) + endif +endif + +xwayland_grab_default_access_rules = get_option('xwayland_grab_default_access_rules') +cdata.set_quoted('XWAYLAND_GRAB_DEFAULT_ACCESS_RULES', + xwayland_grab_default_access_rules) + +cdata.set_quoted('MUTTER_PLUGIN_DIR', join_paths(pkglibdir, 'plugins')) +cdata.set_quoted('MUTTER_LOCALEDIR', localedir) +cdata.set_quoted('MUTTER_LIBEXECDIR', libexecdir) +cdata.set_quoted('MUTTER_PKGDATADIR', pkgdatadir) + +config_h = configure_file( + input: 'config.h.meson', + output: 'config.h', + configuration: cdata +) + +top_includepath = include_directories('.') + +subdir('cogl') +subdir('clutter') +subdir('data') +subdir('src') +subdir('po') +subdir('doc/man') + +meson.add_install_script('meson/meson-postinstall.sh') + +output = [ + '', + '', + ' Mutter ' + meson.project_version(), + ' ===============', + '', + ' Prefix....................... ' + prefix, + ' libexecdir................... ' + libexecdir, + ' pkgdatadir................... ' + pkgdatadir, + '', + ' Rendering APIs:', + '', + ' OpenGL................... ' + have_gl.to_string(), + ' GLES2.................... ' + have_gles2.to_string(), + ' EGL...................... ' + have_egl.to_string(), + ' GLX...................... ' + have_glx.to_string(), + '', + ' Options:', + '', + ' Wayland.................. ' + have_wayland.to_string(), + ' Wayland EGLStream........ ' + have_wayland_eglstream.to_string(), + ' Native Backend........... ' + have_native_backend.to_string(), + ' EGL Device............... ' + have_egl_device.to_string(), + ' Default driver........... ' + default_driver, + ' Remote desktop........... ' + have_remote_desktop.to_string(), + ' gudev.................... ' + have_libgudev.to_string(), + ' Wacom.................... ' + have_libwacom.to_string(), + ' SM....................... ' + have_sm.to_string(), + ' Startup notification..... ' + have_startup_notification.to_string(), + ' Introspection............ ' + have_introspection.to_string(), + ' Profiler................. ' + have_profiler.to_string(), + ' Xwayland initfd.......... ' + have_xwayland_initfd.to_string(), + '', + ' Tests:', + '', + ' Enabled.................. ' + have_tests.to_string(), + ' Core tests............... ' + have_core_tests.to_string(), + ' Cogl tests............... ' + have_cogl_tests.to_string(), + ' Clutter tests............ ' + have_clutter_tests.to_string(), + ' Installed tests.......... ' + have_installed_tests.to_string(), + '', + ' Now type \'ninja -C ' + meson.build_root() + '\' to build ' + meson.project_name(), + '', + '', +] +message('\n'.join(output)) diff --git a/meson/meson-postinstall.sh b/meson/meson-postinstall.sh new file mode 100755 index 000000000..4500dcb01 --- /dev/null +++ b/meson/meson-postinstall.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +# Package managers set this so we don't need to run +if [ -z "$DESTDIR" ]; then + echo Compiling GSettings schemas... + glib-compile-schemas ${MESON_INSTALL_PREFIX}/share/glib-2.0/schemas + + echo Updating desktop database... + update-desktop-database -q ${MESON_INSTALL_PREFIX}/share/applications +fi diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 000000000..ba0313cd1 --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,166 @@ +option('opengl', + type: 'boolean', + value: true, + description: 'Enable OpenGL' +) + +option('opengl_libname', + type: 'string', + value: 'libGL.so.1', + description: 'OpenGL library file name' +) + +option('gles2_libname', + type: 'string', + value: 'libGLESv2.so.2', + description: 'GLESv2 library file name' +) + +option('gles2', + type: 'boolean', + value: true, + description: 'Enable GLES2 support' +) + +option('egl', + type: 'boolean', + value: true, + description: 'Enable EGL support' +) +option('glx', + type: 'boolean', + value: true, + description: 'Enable GLX support' +) + +option('wayland', + type: 'boolean', + value: true, + description: 'Enable Wayland support' +) + +option('native_backend', + type: 'boolean', + value: true, + description: 'Enable the native backend' +) + +option('remote_desktop', + type: 'boolean', + value: true, + description: 'Enable remote desktop and screen cast support' +) + +option('egl_device', + type: 'boolean', + value: false, + description: 'Enable EGLDevice and EGLStream renderer support' +) + +option('wayland_eglstream', + type: 'boolean', + value: false, + description: 'Enable Wayland EGLStream support client support' +) + +option('udev', + type: 'boolean', + value: true, + description: 'Enable udev support when using the X11 backend' +) + +option('libwacom', + type: 'boolean', + value: true, + description: 'Enable libwacom support' +) + +option('pango_ft2', + type: 'boolean', + value: true, + description: 'Enable PangoFt2 support' +) + +option('startup_notification', + type: 'boolean', + value: true, + description: 'Enable startup notification support' +) + +option('sm', + type: 'boolean', + value: true, + description: 'Enable X11 session management support' +) + +option('introspection', + type: 'boolean', + value: true, + description: 'Enable GObject introspection' +) + +option('cogl_tests', + type: 'boolean', + value: true, + description: 'Enable cogl tests' +) + +option('clutter_tests', + type: 'boolean', + value: true, + description: 'Enable clutter tests' +) + +option('core_tests', + type: 'boolean', + value: true, + description: 'Enable mutter core tests' +) + +option('tests', + type: 'boolean', + value: false, + description: 'Enable tests globally. Specific test suites can be controlled with core_tests, clutter_tests, and cogl_tests' +) + +option('profiler', + type: 'boolean', + value: true, + description: 'Enable Sysprof tracing' +) + +option('installed_tests', + type: 'boolean', + value: false, + description: 'Enable mutter installed tests' +) + +option('verbose', + type: 'boolean', + value: true, + description: 'Enable verbose logging ability' +) + +option('xwayland_path', + type: 'string', + value: '', + description: 'Path to Xwayland executable' +) + +option('xwayland_grab_default_access_rules', + type: 'string', + value: 'gnome-boxes,remote-viewer,virt-viewer,virt-manager,vinagre,vncviewer,Xephyr', + description: 'Comma delimited list of applications ressources or class allowed to issue X11 grabs in Xwayland' +) + +option('xwayland_initfd', + type: 'feature', + value: 'auto', + description: 'Whether -initfd argument is passed to Xwayland to guarantee services (e.g. gsd-xsettings) startup before applications' +) + +option('default_driver', + type: 'combo', + choices: ['auto', 'gl', 'gl3', 'gles2', 'nop'], + value: 'auto' +) diff --git a/mutter.doap b/mutter.doap new file mode 100644 index 000000000..99bc711ad --- /dev/null +++ b/mutter.doap @@ -0,0 +1,71 @@ +<Project xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" + xmlns:foaf="http://xmlns.com/foaf/0.1/" + xmlns:gnome="http://api.gnome.org/doap-extensions#" + xmlns="http://usefulinc.com/ns/doap#"> + + <name xml:lang="en">mutter</name> + <shortdesc xml:lang="en">Window and compositing manager based on Clutter</shortdesc> + <description>Mutter is a window and compositing manager that displays and +manages your desktop via OpenGL. Mutter combines a sophisticated display engine +using the Clutter toolkit with solid window-management logic inherited from the +Metacity window manager. + +While Mutter can be used stand-alone, it is primarily intended to be used as +the display core of a larger system such as GNOME Shell. For this reason, +Mutter is very extensible via plugins, which are used both to add fancy visual +effects and to rework the window management behaviors to meet the needs of the +environment.</description> + <!-- + <homepage rdf:resource="http://www.gnome.org/" /> + --> + <mailing-list rdf:resource="http://mail.gnome.org/mailman/listinfo/gnome-shell-list" /> + <download-page rdf:resource="http://download.gnome.org/sources/mutter/" /> + <bug-database rdf:resource="https://gitlab.gnome.org/GNOME/mutter/issues/" /> + + <category rdf:resource="http://api.gnome.org/doap-extensions#core" /> + <programming-language>C</programming-language> + + <author> + <foaf:Person> + <foaf:name>Tomas Frydrych</foaf:name> + <foaf:mbox rdf:resource="mailto:tf@linux.intel.com" /> + <gnome:userid>tomasf</gnome:userid> + </foaf:Person> + </author> + <author> + <foaf:Person> + <foaf:name>Owen Taylor</foaf:name> + <foaf:mbox rdf:resource="mailto:otaylor@redhat.com" /> + <gnome:userid>otaylor</gnome:userid> + </foaf:Person> + </author> + <maintainer> + <foaf:Person> + <foaf:name>Jonas Ådahl</foaf:name> + <foaf:mbox rdf:resource="mailto:jadahl@gmail.com" /> + <gnome:userid>jadahl</gnome:userid> + </foaf:Person> + </maintainer> + <maintainer> + <foaf:Person> + <foaf:name>Carlos Garnacho</foaf:name> + <foaf:mbox rdf:resource="mailto:carlosg@gnome.org" /> + <gnome:userid>carlosg</gnome:userid> + </foaf:Person> + </maintainer> + <maintainer> + <foaf:Person> + <foaf:name>Georges Basile Stavracas Neto</foaf:name> + <foaf:mbox rdf:resource="mailto:gbsneto@gnome.org" /> + <gnome:userid>gbsneto</gnome:userid> + </foaf:Person> + </maintainer> + <maintainer> + <foaf:Person> + <foaf:name>Florian Müllner</foaf:name> + <foaf:mbox rdf:resource="mailto:fmuellner@gnome.org" /> + <gnome:userid>fmuellner</gnome:userid> + </foaf:Person> + </maintainer> +</Project> diff --git a/po/ChangeLog b/po/ChangeLog deleted file mode 100644 index 3e89bb918..000000000 --- a/po/ChangeLog +++ /dev/null @@ -1,5062 +0,0 @@ -2009-04-05 Kjartan Maraas <kmaraas@gnome.org> - - * nb.po: Updated Norwegian bokmål translation. - -2009-03-30 Baris Cicek <baris@teamforce.name.tr> - - * tr.po: Updated Turkish translation. - -2009-03-28 Simos Xenitellis <simos@gnome.org> - - * el.po: Updated Greek translation. - -2009-03-27 Simos Xenitellis <simos@gnome.org> - - * el.po: Updated Greek translation. - -2009-03-21 Goran Rakic <grakic@devbase.net> - - * sr.po, sr@latin.po: Updated Serbian translation by Miloš Popović. - -2009-03-19 Tomasz Dominikowski <tdominikowski@aviary.pl> - - * pl.po: Updated Polish translation - -2009-03-19 Kjartan Maraas <kmaraas@gnome.org> - - * nb.po: Updated Norwegian bokmål translation. - -2009-03-18 Ignacio Casal Quinteiro <icq@gnome.org> - - * gl.po: Updated Galician translation by Suso Baleato. - -2009-03-18 Kostas Papadimas <pkst@gnome.org> - - * el.po: Updated Greek Translation by Fotis Tsamis. - -2009-03-18 Djihed Afifi <djihed@gmail.com> - - * ar.po: Updated Arabic translation. - -2009-03-17 Alexander Shopov <ash@contact.bg> - - * bg.po: Updated Bulgarian translation by - Alexander Shopov <ash@contact.bg> - -2009-03-16 Amitakhya Phukan <amitakhya@svn.gnome.org> - - * as.po: Updated Assamese translations. - -2009-03-15 Rajesh Ranjan <rajeshkajha@yahoo.com> - - * mai.po: added Maithili translation. - * LINGUAS: Added Maithili (mai) to the list of Languages. - -2009-03-15 Ankitkumar Patel <ankit@redhat.com> - - * gu.po: Updated Gujarati Translations. - -2009-03-14 Gintautas Miliauskas <gintautas@miliauskas.lt> - - * lt.po: Updated Lithuanian translation. - -2009-03-14 Nickolay V. Shmyrev <nshmyrev@yandex.ru> - - * ru.po: Updated Russian translation by Yuriy Penkin. - -2009-03-14 Sandeep Shedmake <sshedmak@redhat.com> - - * mr.po: Updated Marathi Translations. - -2009-03-14 Rajesh Ranjan <rranjan@redhat.com> - - * hi.po: Updated Hindi Translation. - -2009-03-13 Kostas Papadimas <pkst@gnome.org> - - * el.po: Updated Greek Translation by Jennie Petoumenou. - -2009-03-13 Priit Laes <plaes at svn dot gnome dot org> - - * et.po: Translation updated by Mattias Põldaru - -2009-03-12 Manoj Kumar Giri <mgiri@redhat.com> - - * or.po: Updated Oriya Translation. - -2009-03-11 Krishnababu K <kkrothap@redhat.com> - - * te.po: Updated Telugu Translation. - * LINGUAS: Added Telugu [te] language. - -2009-03-10 Runa Bhattacharjee <runab@redhat.com> - - * bn_IN.po: Updated partial Bengali India Translation - -2009-03-08 Petr Kovar <pknbe@volny.cz> - - * cs.po: Updated Czech translation. - -2009-03-07 Mark Krapivner <mark125@gmail.com> - - * he.po: Updated Hebrew translation. - -2009-03-06 Milo Casagrande <milo@ubuntu.com> - - * it.po: Updated Italian translation by Luca Ferretti. - -2009-03-04 Luca Ferretti <elle.uca@libero.it> - - * it.po: Updated Italian translation - -2009-03-02 Claude Paroz <claude@2xlibre.net> - - * fr.po: Updated French translation by Frédéric Peters and Claude Paroz. - -2009-03-02 I. Felix <ifelix@redhat.com> - - * ta.po: Tamil Translation updated by Tirumurthi Vasudevan - -2009-02-28 Duarte Loreto <happyguy_pt@hotmail.com> - - * pt.po: Updated Portuguese translation. - -2009-02-23 Philip Withnall <philip@tecnocode.co.uk> - - * en_GB.po: Updated British English translation. - -2009-02-23 Gil Forcada <gforcada@gnome.org> - - * ca.po: Updated Catalan translation by David Planella. - -2009-02-23 Ilkka Tuohela <hile@iki.fi> - - * fi.po: Updated Finnish translation. - -2009-02-21 Christian Kirbach <Christian.Kirbach@googlemail.com> - - * de.po: Updated German translation. - -2009-02-20 Og Maciel <ogmaciel@gnome.org> - - * pt_BR.po: Updated Brazilian Portuguese translation by - Vladimir Melo. - -2009-02-19 Jani Monoses <jani@ubuntu.com> - - * ro.po: Updated Romanian translation - by Adi Roiban <adi@roiban.ro> - -2009-02-19 Ilkka Tuohela <hile@iki.fi> - - * fi.po: Updated Finnish translation. - -2009-02-18 Chao-Hsiung Liao <j_h_liau@yahoo.com.tw> - - * zh_HK.po: Updated Traditional Chinese translation(Hong Kong). - * zh_TW.po: Updated Traditional Chinese translation(Taiwan). - -2009-02-18 Changwoo Ryu <cwryu@debian.org> - - * ko.po: Updated Korean translation. - -2009-02-17 Gabor Kelemen <kelemeng@gnome.hu> - - * hu.po: Translation updated. - -2009-02-16 Wouter Bolsterlee <wbolster@svn.gnome.org> - - * nl.po: Updated Dutch translation by Wouter Bolsterlee. - -2009-02-15 Kenneth Nielsen <k.nielsen81@gmail.com> - - * da.po: Updated Danish translation by Ask H. Larsen - -2009-02-15 Chao-Hsiung Liao <j_h_liau@yahoo.com.tw> - - * zh_HK.po: Updated Traditional Chinese translation(Hong Kong). - * zh_TW.po: Updated Traditional Chinese translation(Taiwan). - -2009-02-14 Ihar Hrachyshka <booxter@lacinka.org> - - * be@latin.po: Updated Belarusian Latin translation by Ihar Hrachyshka. - -2009-02-13 Theppitak Karoonboonyanan <thep@linux.thai.net> - - * th.po: Updated Thai translation. - -2009-02-12 Inaki Larranaga Murgoitio <dooteo@euskalgnu.org> - - * eu.po: Updated Basque translation. - -2009-02-11 Daniel Nylander <po@danielnylander.se> - - * sv.po: Updated Swedish translation. - -2009-02-11 Takeshi AIHANA <takeshi.aihana@gmail.com> - - * ja.po: Updated Japanese translation. - -2009-02-10 Gil Forcada <gforcada@gnome.org> - - * ast.po: Updated Asturian translation on behalf of Mikel González. - -2009-02-07 Clytie Siddall <clytie@riverland.net.au> - - * vi.po: Updated Vietnamese translation. - -2009-02-03 Jorge Gonzalez <jorgegonz@svn.gnome.org> - - * es.po: Updated Spanish translation. - -2009-02-01 Gil Forcada <gforcada@gnome.org> - - * ca.po: Updated Catalan translation by David Planella. - -2009-01-31 Jorge Gonzalez <jorgegonz@svn.gnome.org> - - * es.po: Updated Spanish translation - -2009-01-31 Daniel Nylander <po@danielnylander.se> - - * sv.po: Updated Swedish translation. - -2009-01-29 Kjartan Maraas <kmaraas@gnome.org> - - * nb.po: Updated Norwegian bokmål translation. - -2009-01-29 Changwoo Ryu <cwryu@debian.org> - - * ko.po: Updated Korean translation. - -2009-01-24 Raivis DEjus <orvils@gmail.com> - - * lv.po: Updated Latvian translation. - -2009-01-22 Yair Hershkovitz <yairhr@gmail.com> - - * he.po: Updated Hebrew translation. - -2009-01-17 Thomas Thurman <tthurman@gnome.org> - - * ig.po: Added Igbo translation by Sylvester Onye. - * yo.po Added Yoruba translation by Sunday Ayo Fajuyitan. - * ha.po: Added Hausa translation by Saudat Mohammed. - * LINGUAS: added Igbo, Yoruba and Hausa. - -2009-01-17 Gabor Kelemen <kelemeng@gnome.hu> - - * hu.po: Translation updated. - -2009-01-09 Daniel Nylander <po@danielnylander.se> - - * sv.po: Updated Swedish translation. - -2009-01-03 甘露(Gan Lu) <rhythm.gan@gmail.com> - - * zh_CN.po: Updated Chinese Simplified translation - -2009-01-03 Priit Laes <plaes at svn dot gnome dot org> - - * et.po: Translation updated by Mattias Põldaru - -2008-12-26 Jorge Gonzalez <jorgegonz@svn.gnome.org> - - * es.po: Updated Spanish translation. - -2008-12-12 Luca Ferretti <elle.uca@libero.it> - - * it.po: Imported updated translation from gnome-2-24 branch. - -2008-12-08 Priit Laes <plaes at svn dot gnome dot org> - - * et.po: Translation updated by Mattias Põldaru - -2008-11-23 Jorge Gonzalez <jorgegonz@svn.gnome.org> - - * es.po: Updated Spanish translation - -2008-11-14 Thomas Thurman <tthurman@gnome.org> - - * la.po: Updated Latin translation - -2008-11-14 Jorge Gonzalez <jorgegonz@svn.gnome.org> - - * es.po: Updated Spanish translation - -2008-11-09 Jorge Gonzalez <jorgegonz@svn.gnome.org> - - * es.po: Updated Spanish translation - -2008-11-08 Jorge Gonzalez <jorgegonz@svn.gnome.org> - - * es.po: Updated Spanish translation - -2008-11-03 Leonardo Ferreira Fontenelle <leonardof@gnome.org> - - * pt_BR.po: Merged from branch gnome-2-24. Minor capitalization fix in - the Brazilian Portuguese translation. - -2008-10-27 Og Maciel <ogmaciel@gnome.org> - - * pt_BR.po: Updated Brazilian Portuguese translation by - Og Maciel. - -2008-10-27 Daniel Nylander <po@danielnylander.se> - - * sv.po: Updated Swedish translation. - -2008-10-23 Gil Forcada <gforcada@gnome.org> - - * LINGUAS: Added ast. - * ast.po: Added Asturian translation on behalf of Mikel González. - -2008-10-22 Jordi Mallach <jordi@sindominio.net> - - * ca@valencia.po: New Valencian (Southern Catalan) translation - based on the Catalan file. - * LINGUAS: Added Valencian (Southern Catalan) (ca@valencia). - -2008-10-22 Jordi Mallach <jordi@sindominio.net> - - * ca.po: Apply Catalan fixes from Robert Millan. - -2008-10-17 Thomas Thurman <tthurman@gnome.org> - - * la.po: Updated Latin translation. - -2008-10-16 Marcel Telka <marcel@telka.sk> - - * sk.po: Updated Slovak translation by Pavol Šimo. - -2008-10-15 Thomas Thurman <tthurman@gnome.org> - - * la.po: Updated Latin translation. - -2008-10-15 Thomas Thurman <tthurman@gnome.org> - - * la.po: Updated Latin translation. - -2008-10-12 Kjartan Maraas <kmaraas@gnome.org> - - * nb.po: Updated Norwegian bokmål translation. - -2008-10-12 Theppitak Karoonboonyanan <thep@linux.thai.net> - - * th.po: Updated Thai translation (merged from gnome-2-24 branch). - -2008-10-11 Claude Paroz <claude@2xlibre.net> - - * fr.po: Fixed minimize/unmaximize French translation (sync with 2.24) and - complete some other translations. - -2008-09-30 Og Maciel <ogmaciel@gnome.org> - - * pt_BR.po: Updated Brazilian Portuguese translation by Vladimir Melo. - -2008-09-29 Alexander Shopov <ash@contact.bg> - - * bg.po: Updated Bulgarian translation by - Alexander Shopov <ash@contact.bg> - -2008-09-27 Gil Forcada <gforcada@gnome.org> - - * ca.po: Updated Catalan translation. - -2008-09-27 Laurent Dhima <laurenti@alblinux.net> - - * sq.po: Updated Albanian Translation. - -2008-09-24 Priit Laes <plaes at svn dot gnome dot org> - - * et.po: Translation updated by Ivar Smolin - -2008-09-22 Kenneth Nielsen <k.nielsen81@gmail.com> - - * da.po: Updated Danish translation by Kenneth Nielsen - -2008-09-22 Kenneth Nielsen <k.nielsen81@gmail.com> - - * da.po: Updated Danish translation by Kenneth Nielsen - -2008-09-22 Mugurel Tudor <mugurelu@gnome.ro> - - * ro.po: Updated Romanian translation by - Mişu Moldovan <dumol@gnome.ro> - -2008-09-21 Theppitak Karoonboonyanan <thep@linux.thai.net> - - * th.po: Updated Thai translation. - -2008-09-21 Gintautas Miliauskas <gintas@akl.lt> - - * lt.po: Updated Lithuanian translation. - -2008-09-20 Priit Laes <plaes at svn dot gnome dot org> - - * et.po: Translation updated by Ivar Smolin - -2008-09-17 Gabor Kelemen <kelemeng@gnome.hu> - - * hu.po: Translation updated. - -2008-09-14 Duarte Loreto <happyguy_pt@hotmail.com> - - * pt.po: Fixed Portuguese terminology. - -2008-09-12 Hendrik Richter <hendrikr@gnome.org> - - * de.po: Updated German translation. - -2008-09-12 Goran Rakić <grakic@devbase.net> - - * sr.po, sr@latin.po: Updated Serbian translation (by Miloš Popović). - -2008-09-09 Robert Sedak <robert.sedak@sk.t-com.hr> - - * hr.po: Updated Croatian translation. - -2008-09-08 Priit Laes <plaes at svn dot gnome dot org> - - * et.po: Translation updated by Mattias Põldaru - -2008-09-07 Seán de Búrca <sdeburca@svn.gnome.org> - - * ga.po: Updated Irish translation. - -2008-09-06 Funda Wang <fundawang@gmail.com> - - * zh_CN.po: Updated zh_CN translation. - -2008-09-06 Claude Paroz <claude@2xlibre.net> - - * fr.po: Updated French translation. - -2008-08-24 Gintautas Miliauskas <gintas@akl.lt> - - * lt.po: Updated Lithuanian translation. - -2008-08-23 Inaki Larranaga Murgoitio <dooteo@euskalgnu.org> - - * eu.po: Updated Basque translation. - -2008-08-21 Laurent Dhima <laurenti@alblinux.net> - - * sq.po: Updated Albanian Translation. - -2008-08-14 Duarte Loreto <happyguy_pt@hotmail.com> - - * pt.po: Updated Portuguese translation. - -2008-08-13 Leonardo Ferreira Fontenelle <leonardof@gnome.org> - - * pt_BR.po: Brazilian Portuguese translation updated by Djavan - Fagundes. - -2008-08-13 Ilkka Tuohela <hile@iki.fi> - - * fi.po: Updated Finnish translation. - -2008-08-09 Petr Kovar <pknbe@volny.cz> - - * cs.po: Updated Czech translation. - -2008-08-07 Ignacio Casal Quinteiro <nacho.resa@gmail.com> - - gl.po: Updated Galician translation - -2008-08-6 Djihed Afifi <djihed@gmail.com> - - * ar.po: Updated Arabic Translation by Khaled Hosny. - -2008-08-02 Takeshi AIHANA <takeshi.aihana@gmail.com> - - * ja.po: Updated Japanese translation. - -2008-07-29 Djihed Afifi <djihed@gmail.com> - - * ar.po: Updated Arabic Translation by Khaled Hosny. - -2008-07-29 Wouter Bolsterlee <wbolster@svn.gnome.org> - - * nl.po: Dutch translation updated by Wouter Bolsterlee. - -2008-07-25 Daniel Nylander <po@danielnylander.se> - - * sv.po: Updated Swedish translation. - -2008-07-24 Leonardo Ferreira Fontenelle <leonardof@gnome.org> - - * pt_BR.po: Terminology fixes by Vladimir Melo. - -2008-07-17 Daniel Nylander <po@danielnylander.se> - - * sv.po: Updated Swedish translation. - -2008-07-14 Luca Ferretti <elle.uca@libero.it> - - * it.po: Updated Italian translation. - -2008-07-10 Matej Urbančič <mateju@svn.gnome.org> - - * sl.po: Updated Slovenian Translation. - -2008-07-10 Theppitak Karoonboonyanan <thep@linux.thai.net> - - * th.po: Updated Thai translation. - -2008-07-09 Kjartan Maraas <kmaraas@gnome.org> - - * nb.po: Updated Norwegian bokmål translation. - -2008-07-01 Kjartan Maraas <kmaraas@gnome.org> - - * nb.po: Updated Norwegian bokmål translation. - -2008-06-24 Daniel Nylander <po@danielnylander.se> - - * sv.po: Updated Swedish translation. - -2008-06-21 Gabor Kelemen <kelemeng@gnome.hu> - - * hu.po: Translation updated. - -2008-06-16 Alexander Shopov <ash@contact.bg> - - * bg.po: Updated Bulgarian translation by - Yavor Doganov <yavor@gnu.org> - -2008-06-15 Jorge Gonzalez <jorgegonz@svn.gnome.org> - - * es.po: Updated Spanish translation - -2008-06-12 Theppitak Karoonboonyanan <thep@linux.thai.net> - - * th.po: Updated Thai translation. - -2008-06-11 Djihed Afifi <djihed@gmail.com> - - * ar.po: Updated Arabic Translation by Khaled Hosny. - -2008-06-11 Yannig Marchegay <yannig@marchegay.org> - - * oc.po: Updated Occitan translation. - -2008-06-08 Kjartan Maraas <kmaraas@gnome.org> - - * nb.po: Updated Norwegian bokmål translation. - -2008-06-01 Clytie Siddall <clytie@riverland.net.au> - - * vi.po: Updated Vietnamese translation. - -2008-05-22 Djihed Afifi <djihed@gmail.com> - - * ar.po: Updated Arabic Translation by Khaled Hosny. - -2008-05-20 Vincent van Adrighem <adrighem@gnome.org> - - * nl.po: Translation updated by Tino Meinen. - -2008-05-19 Djihed Afifi <djihed@gmail.com> - - * ar.po: Updated Arabic Translation by Khaled Hosny. - -2008-05-18 Theppitak Karoonboonyanan <thep@linux.thai.net> - - * th.po: Updated Thai translation. - -2008-05-14 Kjartan Maraas <kmaraas@gnome.org> - - * nb.po: Updated Norwegian bokmål translation. - -2008-05-13 Vincent van Adrighem <adrighem@gnome.org> - - * nl.po: Translation updated by Tino Meinen. - -2008-05-06 Kjartan Maraas <kmaraas@gnome.org> - - * nb.po: Updated Norwegian bokmål translation. - -2008-05-01 Gabor Kelemen <kelemeng@gnome.org> - - * hu.po: Translation updated. - -2008-04-20 Yair Hershkovitz <yairhr@gmail.com> - - * he.po: Updated Hebrew translation. - -2008-04-10 Yair Hershkovitz <yairhr@gmail.com> - - * he.po: Updated Hebrew translation. - -2008-04-04 Eskild Hustvedt <eskildh@gnome.org> - - * nn.po: Updated Norwegian Nynorsk translation - -2008-03-31 Baris Cicek <baris@teamforce.name.tr> - - * tr.po: Updated Turkish translation - -2008-03-30 Jorge Gonzalez <jorgegonz@svn.gnome.org> - - * es.po: Updated Spanish translation - -2008-03-23 Nguyễn Thái Ngọc Duy <pclouds@gmail.com> - - * vi.po: Update Vietnamese translation - -2008-03-20 Abel Cheung <abelcheung@gmail.com> - - * zh_HK.po, zh_TW.po: Typo fix for traditional Chinese translations. - -2008-03-18 Gabor Kelemen <kelemeng@gnome.hu> - - * hu.po: Translation updated - -2008-03-09 Kenneth Nielsen <k.nielsen81@gmail.com> - - * da.po: Updated Danish translation - -2008-03-09 Gabor Kelemen <kelemeng@gnome.hu> - - * hu.po: Translation updated - -2008-03-09 Daniel Nylander <po@danielnylander.se> - - * sv.po: Updated Swedish translation. - -2008-03-09 Vasiliy Faronov <qvvx@yandex.ru> - - * ru.po: Updated Russian translation. - -2008-03-07 Maxim Dziumanenko <dziumanenko@gmail.com> - - * uk.po: Updated Ukrainian translation. - -2008-03-03 Jorge Gonzalez <jorgegonz@svn.gnome.org> - - * es.po: Updated Spanish translation - -2008-03-01 Chao-Hsiung Liao <j_h_liau@yahoo.com.tw> - - * zh_HK.po: Updated Traditional Chinese translation(Hong Kong). - * zh_TW.po: Updated Traditional Chinese translation(Taiwan). - -2008-02-27 Stéphane Raimbault <stephane.raimbault@gmail.com> - - * fr.po: Updated French translation (merged from gnome-2-22). - -2008-02-25 Changwoo Ryu <cwryu@debian.org> - - * ko.po: Updated Korean translation. - -2008-02-24 Ilkka Tuohela <hile@iki.fi> - - * fi.po: Updated Finnish translation (bug #518255). - -2008-02-23 Ihar Hrachyshka <booxter@lacinka.org> - - * be@latin.po: Updated Belarusian Latin translation. - -2008-02-20 Ilkka Tuohela <hile@iki.fi> - - * fi.po: Updated Finnish translation. - -2008-02-18 Wouter Bolsterlee <wbolster@svn.gnome.org> - - * nl.po: Updated Dutch translation by Wouter Bolsterlee. - -2008-02-18 Ihar Hrachyshka <booxter@lacinka.org> - - * be@latin.po: Updated Belarusian Latin translation. - -2008-02-15 Runa Bhattacharjee <runabh@gmail.com> - - * kn.po: Added Kannada Translations by Shankar Prasad - * LINGUAS: Added Kannada (kn) to the List of Languages - -2008-02-14 Ignacio Casal Quinteiro <nacho.resa@gmail.com> - - * gl.po: Updated Galician Translation. - -2008-02-14 Pawan Chitrakar <chautari@gmail.com> - - * ne.po: Updated Nepali Translation. - -2008-02-14 Ilkka Tuohela <hile@iki.fi> - - * fi.po: Updated Finnish translation. - -2008-02-13 Ilkka Tuohela <hile@iki.fi> - - * fi.po: Updated Finnish translation. - -2008-02-10 Duarte Loreto <happyguy_pt@hotmail.com> - - * pt.po: Updated Portuguese translation. - -2008-02-09 Hendrik Brandt <heb@gnome-de.org> - - * de.po: Updated German translation. - -2008-02-07 Artur Flinta <aflinta@svn.gnome.org> - - * pl.po: Updated Polish translation by GNOME PL Team. - -2008-02-05 Rhys Jones <rhys@sucs.org> - - * cy.po: Updated Welsh translation. - -2008-02-03 Amitakhya Phukan <amitakhya@svn.gnome.org> - - * LINGUAS: Added as to LINGUAS. - * as.po: Updated assamese translations. - -2008-02-03 Arangel Angov <arangel@linux.net.mk> - - * mk.po: Updated Macedonian translation. - -2008-02-03 Takeshi AIHANA <takeshi.aihana@gmail.com> - - * ja.po: Updated Japanese translation. - -2008-02-02 Luca Ferretti <elle.uca@libero.it> - - * it.po: Updated Italian translation. - -2008-02-01 Theppitak Karoonboonyanan <thep@linux.thai.net> - - * th.po: Updated Thai translation. - -2008-01-31 Djihed Afifi <djihed@gmail.com> - - * ar.po: Updated Arabic Translation by Khaled Hosny. - -2008-01-30 Rahul Bhalerao <b.rahul.pm@gmail.com> - - * mr.po: Updated Marathi translations by Sandeep Shedmake. - -2008-01-27 Baris Cicek <baris@teamforce.name.tr> - - * tr.po: Fixed typo in Turkish translation. - -2008-01-25 Petr Kovar <pknbe@volny.cz> - - * cs.po: Updated Czech translation. - -2008-01-22 Andre Klapper <a9016009@gmx.de> - - * de.po: Sync "beep" translation. - -2008-01-15 Daniel Nylander <po@danielnylander.se> - - * sv.po: Updated Swedish translation. - -2008-01-14 Inaki Larranaga Murgoitio <dooteo@euskalgnu.org> - - * eu.po: Updated Basque translation. - -2008-01-14 Kjartan Maraas <kmaraas@gnome.org> - - * nb.po: Updated Norwegian bokmål translation. - -2008-01-13 Jorge Gonzalez <jorgegonz@svn.gnome.org> - - * es.po: Updated Spanish translation - -2008-01-09 Yair Hershkovitz <yairhr@gmail.com> - - * he.po: Updated Hebrew translation. - -2008-01-06 Ihar Hrachyshka <booxter@lacinka.org> - - * be@latin.po: Updated Belarusian Latin translation. - -2008-01-05 Clytie Siddall <clytie@riverland.net.au> - - * vi.po: Updated Vietnamese translation. - -2007-12-31 Yannig Marchegay <yannig@marchegay.org> - - * oc.po: Updated Occitan translation. - -2007-12-31 Daniel Nylander <po@danielnylander.se> - - * sv.po: Updated Swedish translation. - -2007-12-22 Seán de Búrca <sdeburca@svn.gnome.org> - - * ga.po: Updated Irish translation. - -2007-12-22 Seán de Búrca <sdeburca@svn.gnome.org> - - * POTFILES.in: Remove dead files. - -2007-12-20 Kjartan Maraas <kmaraas@gnome.org> - - * POTFILES.in: Rearrange after stuff moved around. - * nb.po: Update - -2007-12-19 Kjartan Maraas <kmaraas@gnome.org> - - * nb.po: Updated Norwegian bokmål translation. - -2007-12-19 Jorge Gonzalez <jorgegonz@svn.gnome.org> - - * es.po: Updated Spanish translation. - -2007-12-17 Daniel Nylander <po@danielnylander.se> - - * sv.po: Updated Swedish translation. - -2007-12-15 Kjartan Maraas <kmaraas@gnome.org> - - * nb.po: Updated Norwegian bokmål translation. - -2007-12-10 Jorge Gonzalez <jorgegonz@svn.gnome.org> - - * es.po: Updated Spanish translation, fixes bug #500562 and bug #500831 - -2007-12-10 Matej Urbančič <mateju@svn.gnome.org> - - * sl.po: Updated Slovenian Translation. - -2007-12-10 Jorge Gonzalez <jorgegonz@svn.gnome.org> - - * es.po: Updated Spanish translation, fixes bug #500831 - -2007-12-09 Jorge Gonzalez <jorgegonz@svn.gnome.org> - - * es.po: Updated Spanish translation, fixes bug #500562 - -2007-12-08 Jakub Friedl <jfriedl@suse.cz> - - * cs.po: Czech Translation updated by Petr Kovar. - -2007-12-08 Ihar Hrachyshka <booxter@lacinka.org> - - * be@latin.po: Updated Belarusian Latin translation. - -2007-12-08 Leonardo Ferreira Fontenelle <leonardof@svn.gnome.org> - - * pt_BR.po: Fixes in Brazilian Portuguese translation by Luiz Armesto. - -2007-12-07 Leonardo Ferreira Fontenelle <leonardof@svn.gnome.org> - - * pt_BR.po: Fixed attributes in Brazilian Portuguese translation by - Rodrigo Flores. - -2007-12-02 Marcel Telka <marcel@telka.sk> - - * sk.po: Updated Slovak translation by Pavol Šimo. - -2007-11-28 Ignacio Casal Quinteiro <nacho.resa@gmail.com> - - * gl.po: Updated Galician Translation. - -2007-11-12 Matej Urbančič <mateju@svn.gnome.org> - - * sl.po: Updated Slovenian translation. - -2007-11-08 Daniel Nylander <po@danielnylander.se> - - * sv.po: Updated Swedish translation. - -2007-11-01 Jorge Gonzalez <jorgegonz@svn.gnome.org> - - * es.po: Updated Spanish translation - -2007-10-25 Matej Urbančič <mateju@svn.gnome.org> - - * sl.po: Updated Slovenian translation. - -2007-10-23 Djihed Afifi <djihed@gmail.com> - - * ar.po: Updated Arabic Translation by Djihed Afifi. - -2007-10-21 Djihed Afifi <djihed@gmail.com> - - * ar.po: Updated Arabic Translation by Djihed Afifi. - -2007-09-30 Stéphane Raimbault <stephane.raimbault@gmail.com> - - * fr.po: Fixed French translation. - -2007-09-27 Changwoo Ryu <cwryu@debian.org> - - * ko.po: Updated Korean translation. - -2007-09-25 Gil Forcada <gforcada@svn.gnome.org> - - * ca.po: Fixed a string in Catalan translation thanks to Sílvia Miranda. - -2007-09-21 Gil Forcada <gforcada@svn.gnome.org> - - * ca.po: Updated Catalan translation by Joan Duran. - -2007-09-17 Artur Flinta <aflinta@svn.gnome.org> - - * pl.po: Updated Polish translation by GNOME PL Team. - -2007-09-17 Alexander Shopov <ash@contact.bg> - - * bg.po: Updated Bulgarian translation by - Alexander Shopov <ash@contact.bg> - -2007-09-17 Wouter Bolsterlee <wbolster@svn.gnome.org> - - * nl.po: Translation updated by Wouter Bolsterlee. - -2007-09-17 Djihed Afifi <djihed@gmail.com> - - * ar.po: Updated Arabic Translation by Djihed Afifi. - -2007-09-16 Gil Forcada <gforcada@svn.gnome.org> - - * ca.po: Updated Catalan translation. - -2007-09-16 Takeshi AIHANA <takeshi.aihana@gmail.com> - - * ja.po: Translation improved. - -2007-09-16 Mugurel Tudor <mugurelu@gnome.ro> - - * ro.po: Updated Romanian translation - -2007-09-15 Nickolay V. Shmyrev <nshmyrev@yandex.ru> - - * ru.po: Updated Russian translation. - -2007-09-15 Stéphane Raimbault <stephane.raimbault@gmail.com> - - * fr.po: Fixed French translation by Vincent Untz and Stéphane - Raimbault. - -2007-09-15 Andre Klapper <a9016009@gmx.de> - - * sk.po: Updated Slovak translation on behalf of Peter Tuharsky - <tuharsky@misbb.sk>. - -2007-09-14 Clytie Siddall <clytie@riverland.net.au> - - * vi.po: Updated Vietnamese translation. - -2007-09-14 Luca Ferretti <elle.uca@libero.it> - - * it.po: Updated Italian translation. - -2007-09-13 Djihed Afifi <djihed@gmail.com> - - * ar.po: Updated Arabic Translation by Khaled Hosny. - -2007-09-14 Gabor Kelemen <kelemeng@gnome.hu> - - * hu.po: Translation updated. - -2007-09-13 Ihar Hrachyshka <ihar.hrachyshka@gmail.com> - - * be@latin.po: Updated Belarusian Latin translation. - -2007-09-12 Maxim Dziumanenko <dziumanenko@gmail.com> - - * uk.po: Update Ukrainian translation. - -2007-09-12 Goran Rakić <grakic@devbase.net> - - * sr.po, sr@Latn.po: Updated Serbian translation. - -2007-09-09 Kenneth Nielsen <k.nielsen81@gmail.com> - - * da.po: Updated Danish translation - -2007-09-08 Inaki Larranaga Murgoitio <dooteo@zundan.com> - - * eu.po: Fixed some typos in Basque translation. - -2007-09-05 Jovan Naumovski <jovan@lugola.net> - - * mk.po: Updated Macedonian translation. - -2007-09-03 Clytie Siddall <clytie@riverland.net.au> - - * vi.po: Updated Vietnamese translation. - -2007-09-03 Duarte Loreto <happyguy_pt@hotmail.com> - - * pt.po: Updated Portuguese translation. - -2007-09-03 Jovan Naumovski <jovan@lugola.net> - - * mk.po: Updated Macedonian translation. - -2007-09-01 Jovan Naumovski <jovan@lugola.net> - - * mk.po: Updated Macedonian translation. - -2007-09-01 Stéphane Raimbault <stephane.raimbault@gmail.com> - - * fr.po: Updated French translation. - -2007-08-30 Ani Peter <peter.ani@gmail.com> - - * ml.po: Updated Malayalam Translation - -2007-08-29 I. Felix <ifelix@svn.gnome.org> - - * ta.po: Tamil Translation updated by Tirumurthi Vasudevan - -2007-08-26 Raphael Higino <raphaelh@svn.gnome.org> - - * pt_BR.po: Updated Brazilian Portuguese translation - by Og Maciel <ogmaciel@ubuntu.com>. - -2007-08-15 Adam Weinberger <adamw@gnome.org> - - * en_CA.po: Updated Canadian English translation. - -2007-08-13 Takeshi AIHANA <takeshi.aihana@gmail.com> - - * ja.po: Updated Japanese translation. - -2007-08-13 Žygimantas Beručka <zygis@gnome.org> - - * lt.po: Updated Lithuanian translation. - -2007-08-11 Daniel Nylander <po@danielnylander.se> - - * sv.po: Updated Swedish translation. - -2007-08-10 I. Felix <ifelix@svn.gnome.org> - - * ta.po: Tamil Translation updated by Tirumurthi Vasudevan - -2007-08-10 Ankit Patel <ankit644@yahoo.com> - - * gu.po: Updated Gujarati Translation. - -2007-08-09 Ilkka Tuohela <hile@iki.fi> - - * fi.po: Updated Finnish translation. - -2007-08-08 Ankit Patel <ankit644@yahoo.com> - - * gu.po: Updated Gujarati Translation. - -2007-08-07 Jorge Gonzalez <jorgegonz@svn.gnome.org> - - * es.po: Updated Spanish translation - -2007-08-07 Theppitak Karoonboonyanan <thep@linux.thai.net> - - * th.po: Updated Thai translation. - -2007-08-06 Ilkka Tuohela <hile@iki.fi> - - * fi.po: Updated Finnish translation. - -2007-08-05 Inaki Laranaga Murgoitio <dooteo@zundan.com> - - * eu.po: Updated Basque translation. - -2007-07-25 Alexander Shopov <ash@contact.bg> - - * bg.po: Updated Bulgarian translation by - Alexander Shopov <ash@contact.bg> - -2007-07-21 Gabor Kelemen <kelemeng@gnome.hu> - - * hu.po: Translation updated. - -2007-07-18 Vincent van Adrighem <adrighem@gnome.org> - - * nl.po: Translation updated. - -2007-07-17 Daniel Nylander <po@danielnylander.se> - - * sv.po: Updated Swedish translation. - -2007-07-16 Ilkka Tuohela <hile@iki.fi> - - * fi.po: Updated Finnish translation. - -2007-07-10 Theppitak Karoonboonyanan <thep@linux.thai.net> - - * th.po: Updated Thai translation. - -2007-07-08 Takeshi AIHANA <takeshi.aihana@gmail.com> - - * ja.po: Updated Japanese translation. - -2007-07-02 Nguyễn Thái Ngọc Duy <pclouds@gmail.com> - - * vi.po: Updated Vietnamese translation. - -2007-06-27 Clytie Siddall <clytie@riverland.net.au> - - * vi.po: Updated Vietnamese translation. - -2007-06-25 Jorge Gonzalez <jorgegonz@svn.gnome.org> - - * es.po: Updated Spanish translation - -2007-06-24 Kjartan Maraas <kmaraas@gnome.org> - - * POTFILES.in: Add src/core.c - * nb.po: Updated Norwegian bokmål translation. - -2007-06-19 Jorge Gonzalez <jorgegonz@svn.gnome.org> - - * es.po: Updated Spanish translation - -2007-06-16 Funda Wang <fundawang@gmail.com> - - * zh_CN.po: Updated Simplified Chinese translation - -2007-06-15 Jorge Gonzalez <jorgegonz@svn.gnome.org> - - * es.po: Updated Spanish translation - -2007-06-13 Pema Geyleg <pema.geyleg@gmail.com> - - * dz.po: Updated dzongkha translation - -2007-05-18 Theppitak Karoonboonyanan <thep@linux.thai.net> - - * th.po: Updated Thai translation. - -2007-05-09 Jovan Naumovski <jovan@lugola.net> - - * mk.po: Updated Macedonian translation. - -2007-05-2 Djihed Afifi <djihed@gmail.com> - - * ar.po: Updated Arabic Translation by Khaled Hosny. - -2007-04-24 Ihar Hrachyshka <iharh@gnome.org> - - * be@latin.po: Updated Belarusian Latin translation. - -2007-04-23 David Lodge <dave@cirt.net> - - * en_GB.po: Updated British English translation - -2007-04-22 Ignacio Casal Quinteiro <nacho.resa@gmail.com> - - * gl.po: Updated Galician Translation. - -2007-04-22 Jorge Gonzalez <jorgegonz@svn.gnome.org> - - * es.po: Updated Spanish translation. - -2007-04-21 Daniel Nylander <po@danielnylander.se> - - * sv.po: Updated Swedish translation. - -2007-04-14 Djihed Afifi <djihed@gmail.com> - - * ar.po: Updated Arabic Translation by Khaled Hosny. - -2007-04-10 Kjartan Maraas <kmaraas@gnome.org> - - * nb.po: Updated Norwegian bokmål translation. - -2007-04-05 Bastien Nocera <hadess@hadess.net> - - * POTFILES.in: add the XML keys definitions to the list - -2007-04-05 Raivis Dejus <orvils@gmail.com> - - * lv.po: Updated Latvian Translation. - -2007-04-02 Alessio Frusciante <algol@firenze.linux.it> - - * it.po: Fixed a typo in translation. Closes #420494. - -2007-03-30 Ihar Hrachyshka <iharh@gnome.org> - - * be@latin.po: Added Belarusian Latin translation by Ales Navicki. - -2007-03-29 Priit Laes <plaes@svn.gnome.org> - - * et.po: Updated Estonian translation by Ivar Smolin <okul@linux.ee>. - -2007-03-27 Gabor Kelemen <kelemeng@gnome.hu> - - * hu.po: Translation updated. - -2007-03-17 Kjartan Maraas <kmaraas@gnome.org> - - reviewed by: <delete if not using a buddy> - - * nb.po: - -2007-03-14 David Lodge <dave@cirt.net> - - * en_GB.po: Updated English (British) translation - -2007-03-12 Jakub Friedl <jfriedl@suse.cz> - - * cs.po: Updated Czech translation. - -2007-03-11 Goran Rakić <grakic@devbase.net> - - * sr.po, sr@Latn.po: Updated Serbian translation. - -2007-03-11 Josep Puigdemont i Casamajó <josep.puigdemont@gmail.com> - - * ca.po: Updated Catalan translation by - Jordi Mallach <jodri@sindominio.net>. - -2007-03-10 Artur Flinta <aflinta@svn.gnome.org> - - * pl.po: Updated Polish translation by GNOME PL Team. - -2007-03-09 Nickolay V. Shmyrev <nshmyrev@yandex.ru> - - * ru.po: Updated Russian translation. - -2007-03-07 Artur Flinta <aflinta@svn.gnome.org> - - * pl.po: Updated Polish translation by GNOME PL Team. - -2007-03-06 Takeshi AIHANA <takeshi.aihana@gmail.com> - - * ja.po: Updated Japanese translation. - -2007-03-06 Jovan Naumovski <jovan@lugola.net> - - * mk.po: Updated Macedonian translation. - -2007-03-05 Vincent van Adrighem <adrighem@gnome.org> - - * nl.po: Translation updated by Reinout van Schouwen. - -2007-03-04 Gintautas Miliauskas <gintas@akl.lt> - - * lt.po: Updated Lithuanian translation. - -2007-03-04 Erdal Ronahi <erdal dot ronahi at gmail dot com> - - * ku.po: Updated Kurdish translations - -2007-03-04 Pema Geyleg <pema.geyleg@gmail.com> - - * dz.po: Updated Dzongkha Translation. - -2007-03-04 Chao-Hsiung Liao <j_h_liau@yahoo.com.tw> - - * zh_HK.po: Updated Traditional Chinese translation(Hong Kong). - * zh_TW.po: Updated Traditional Chinese translation(Taiwan). - -2007-03-02 Leonardo Ferreira Fontenelle <leonardof@svn.gnome.org> - - * pt_BR.po: Updated Brazilian Portuguese translation by Leonardo - Ferreira Fontenelle <leo.fontenelle@gmail.com> (me!) and Raul Pereira - <contato@raulpereira.com>. - -2007-02-27 Gintautas Miliauskas <gintas@akl.lt> - - * lt.po: Updated Lithuanian translation. - -2007-02-26 Luca Ferretti <elle.uca@libero.it> - - * it.po: Updated Italian translation. - -2007-02-25 Gabor Kelemen <kelemeng@gnome.hu> - - * hu.po: Translation updated. - -2007-02-24 Raphael Higino <raphaelh@svn.gnome.org> - - * pt_BR.po: Updated Brazilian Portuguese translation. - -2007-02-24 Nguyễn Thái Ngọc Duy <pclouds@gmail.com> - - * vi.po: Updated Vietnamese translation. - -2007-02-22 Abel Cheung <abelcheung@gmail.com> - - * zh_CN.po: Updated simplified Chinese translation on behalf of - Funda Wang. - -2007-02-21 Maxim Dziumanenko <dziumanenko@gmail.com> - - * uk.po: Update Ukrainian translation. - -2007-02-21 Artur Flinta <aflinta@cvs.gnome.org> - - * pl.po: Updated Polish translation by GNOME PL Team. - -2007-02-20 Alexander Shopov <ash@contact.bg> - - * bg.po: Updated Bulgarian translation by - Alexander Shopov <ash@contact.bg> - -2007-02-16 Ilkka Tuohela <hile@iki.fi> - - * fi.po: Updated Finnish translation. - -2007-02-15 Changwoo Ryu <cwryu@debian.org> - - * ko.po: Updated Korean translation. - -2007-02-15 Duarte Loreto <happyguy_pt@hotmail.com> - - * pt.po: Updated Portuguese translation. - -2007-02-14 Ilkka Tuohela <hile@iki.fi> - - * fi.po: Updated Finnish translation. - -2007-02-09 Changwoo Ryu <cwryu@debian.org> - - * ko.po: Updated Korean translation. - -2007-01-31 Stéphane Raimbault <stephane.raimbault@gmail.com> - - * fr.po: Updated French translation by Robert-André Mauchin. - -2007-01-27 Priit Laes <plaes@svn.gnome.org> - - * et.po: Updated Estonian translation by Ivar Smolin <okul@linux.ee>. - -2007-01-22 Jakub Friedl <jfriedl@suse.cz> - - * cs.po: Updated Czech translation. - -2007-01-16 Hendrik Richter <hendrikr@gnome.org> - - * de.po: Updated German translation. - -2007-01-15 Djihed Afifi <djihed@gmail.com> - - * ar.po: Updated Arabic Translation by Khaled Hosny. - -2007-01-13 Daniel Nylander <po@danielnylander.se> - - * sv.po: Updated Swedish translation. - -2007-01-05 Jakub Friedl <jfriedl@suse.cz> - - * cs.po: Updated Czech translation. - -2007-01-3 Djihed Afifi <djihed@gmail.com> - - * ar.po: Updated Arabic Translation by Djihed Afifi. - -2007-01-01 David Lodge <dave@cirt.net> - - * en_GB.po: Updated English (British) translation - -2006-12-29 Kjartan Maraas <kmaraas@gnome.org> - - * nb.po: Updated Norwegian bokmål translation. - -2006-12-29 Theppitak Karoonboonyanan <thep@linux.thai.net> - - * th.po: Updated Thai translation. - -2006-12-27 Djihed Afifi <djihed@gmail.com> - - * ar.po: Updated Arabic Translation. - -2006-12-24 Djihed Afifi <djihed@gmail.com> - - * ar.po: Updated Arabic Translation. - -2006-12-23 Raivis Dejus <orvils@gmail.com> - - * lv.po: Updated Latvian Translation. - -2006-12-18 Kjartan Maraas <kmaraas@gnome.org> - - * nb.po: Updated Norwegian bokmål translation. - -2006-12-18 Djihed Afifi <djihed@gmail.com> - - * ar.po: Updated Arabic Translation. - -2006-12-18 Ales Nyakhaychyk <nab@mail.by> - - * be.po: Updated Belarusian Translation by Ihar Hrachyshka. - -2006-12-15 Theppitak Karoonboonyanan <thep@linux.thai.net> - - * th.po: Updated Thai translation. - -2006-12-13 Mugurel Tudor <mugurelu@gnome.ro> - - * ro.po: Updated Romanian translation. - -2006-12-11 Jordi Mallach <jordi@sindominio.net> - - * ca.po: Updated Catalan translation. - -2006-12-11 Kjartan Maraas <kmaraas@gnome.org> - - * nb.po: Updated Norwegian bokmål translation. - -2006-12-04 Jakub Friedl <jfriedl@suse.cz> - - * cs.po: Updated Czech translation. - -2006-11-22 Yair Hershkovitz <yairhr@gmail.com> - - * he.po: Updated Hebrew translation. - -2006-11-19 Priit Laes <plaes@cvs.gnome.org> - - * et.po: Translation updated by Ivar Smolin. - -2006-11-19 Duarte Loreto <happyguy_pt@hotmail.com> - - * pt.po: Partial updated Portuguese translation. - -2006-11-19 Priit Laes <plaes@cvs.gnome.org> - - * et.po: Translation updated by Ivar Smolin. - -2006-11-18 Priit Laes <plaes@cvs.gnome.org> - - * et.po: Translation updated by Ivar Smolin. - -2006-11-07 Francisco Javier F. Serrador <serrador@openshine.com> - - * es.po: Updated Spanish translation. - -2006-11-03 Jakub Friedl <jfriedl@suse.cz> - - * cs.po: Updated Czech translation. - -2006-10-26 Francisco Javier F. Serrador <serrador@openshine.com> - - * es.po: Updated Spanish translation. - -2006-10-26 Ilkka Tuohela <hile@iki.fi> - - * fi.po: Updated Finnish translation. - -2006-10-26 Ilkka Tuohela <hile@iki.fi> - - * fi.po: Updated Finnish translation. - -2006-10-22 Christophe Merlet <redfox@redfoxcenter.org> - - * fr.po: Updated French translation. - -2006-10-19 Kjartan Maraas <kmaraas@gnome.org> - - * nb.po: Updated Norwegian bokmål translation. - -2006-10-15 Ilkka Tuohela <hile@iki.fi> - - * fi.po: Updated Finnish translation. - -2006-10-02 Josep Puigdemont i Casamajó <josep.puigdemont@gmail.com> - - * ca.po: Updated Catalan translation. - -2006-09-29 Alexander Shopov <ash@contact.bg> - - * bg.po: Updated Bulgarian translation with - bugfixes prompted by Yavor Doganov - -2006-09-21 Gabor Kelemen <kelemeng@gnome.hu> - - * hu.po: Translation updated. - -2006-09-19 Runa Bhattacharjee <runabh@gmail.com> - - * bn_IN.po: Updated Bengali India Translation. - -2006-09-15 Wouter Bolsterlee <wbolster@gnome.org> - - * nl.po: Translation updated by Wouter Bolsterlee. - -2006-09-15 Matic Zgur <mr.zgur@gmail.com> - - * sl.po: Updated Slovenian translation. - -2006-09-14 Francisco Javier F. Serrador <serrador@openshine.com> - - * es.po: Updated Spanish translation. - -2006-09-14 Alexander Shopov <ash@contact.bg> - - * bg.po: Updated Bulgarian translation by - Alexander Shopov <ash@contact.bg> - -2006-09-13 Josep Puigdemont i Casamajó <josep.puigdemont@gmail.com> - - * ca.po: Updated Catalan translation. - -2006-09-13 Ilkka Tuohela <hile@iki.fi> - - * fi.po: Updated Finnish translation. - - concistency fixes with libwnck - -2006-09-13 Rajesh Ranjan <rajeshkajha@yahoo.com> - - * hi.po: Updated Hindi Translation. - -2006-09-13 Abel Cheung <abel@oaka.org> - - * zh_HK.po: Updated Chinese (Hong Kong) translation. - * zh_TW.po: Updated Chinese (Taiwan) translation. - -2006-09-13 Ani Peter <peter.ani@gmail.com> - - * ml.po: Updated Malayalam translation - -2006-09-13 I.Felix <ifelix25@gmail.com> - - * ta.po: Updated Tamil Translation. - -2006-09-13 Ankit Patel <ankit644@yahoo.com> - - * gu.po: Updated Gujarati Translation. - -2006-09-13 Ahmad Riza H Nst <rizahnst@eriagempita.co.id> - - * id.po: Updated. - -2006-09-10 David Lodge <dave@cirt.net> - - * en_GB.po: Updated English (British) translation. - -2006-09-08 Priit Laes <plaes@cvs.gnome.org> - - * et.po: Translation updated by Ivar Smolin. - -2006-09-07 Matic Zgur <mr.zgur@gmail.com> - - * sl.po: Updated Slovenian translation. - -2006-09-04 Nickolay V. Shmyrev <nshmyrev@yandex.ru> - - * ru.po: Updated Russian translation by - Vasiliy Faronov <qvvx@yandex.ru>. - -2006-09-04 Rahul Bhalerao <b.rahul.pm@gmail.com> - - * mr.po: Updated Marathi translations. - -2006-09-04 Runa Bhattacharjee <runabh@gmail.com> - - * bn_IN.po: Modified the accelerators to English. - -2006-09-04 Abel Cheung <abel@oaka.org> - - * zh_HK.po: Updated Chinese (Hong Kong) translation from - Woodman Tuen <wmtuen@gmail.com>. - * zh_TW.po: Updated Chinese (Taiwan) translation from - Woodman Tuen <wmtuen@gmail.com>. - -2006-09-04 Kostas Papadimas <pkst@gnome.org> - - * el.po: Updated Greek translation. - -2006-09-04 Ani Peter <peter.ani@gmail.com> - - * ml.po: Updated Malayalam translation - -2006-09-04 Rahul Bhalerao <b.rahul.pm@gmail.com> - - * mr.po: Added the file and updated Marathi translation. - * LINGUAS: Added an entry for Marathi(mr). - -2006-09-03 Christophe Merlet <redfox@redfoxcenter.org> - - * fr.po: Updated French translation from - Jonathan Ernst <jonathan@ernstfamily.ch>. - -2006-09-03 Danilo Šegan <danilo@gnome.org> - - * sr.po, sr@Latn.po: Updated by Goran Rakić. - -2006-09-03 Gabor Kelemen <kelemeng@gnome.hu> - - * hu.po: Translation updated. - -2006-09-03 Gabor Kelemen <kelemeng@gnome.hu> - - * hu.po: Translation updated. - -2006-09-01 Maxim Dziumanenko <dziumanenko@gmail.com> - - * uk.po: Update Ukrainian translation. - -2006-09-01 Duarte Loreto <happyguy_pt@hotmail.com> - - * pt.po: Updated Portuguese translation. - -2006-08-30 Josep Puigdemont i Casamajó <josep.puigdemont@gmail.com> - - * ca.po: Updated Catalan translation. - -2006-08-27 Gintautas Miliauskas <gintas@akl.lt> - - * lt.po: Updated Lithuanian translation. - -2006-08-20 Daniel Nylander <po@danielnylander.se> - - * sv.po: Updated Swedish translation. - -2006-08-19 Ahmad Riza H Nst <rizahnst@eriagempita.co.id> - - * id.po: Updated. - -2006-08-18 Alexander Shopov <ash@contact.bg> - - * bg.po: Updated Bulgarian translation by - Alexander Shopov <ash@contact.bg> - -2006-08-17 Jordi Mas <jmas@softcatala.org> - - * ca.po: Fixes small mistakes in Catalan translation - -2006-08-16 Gabor Kelemen <kelemeng@gnome.hu> - - * hu.po: Translation updated. - -2006-08-13 Wouter Bolsterlee <uws+gnome@xs4all.nl> - - * nl.po: Translation updated by Wouter Bolsterlee. - -2006-08-09 Funda Wang <fundawang@linux.net.cn> - - * zh_CN.po: Updated Simplified Chinese translation. - -2006-08-08 Wouter Bolsterlee <uws+gnome@xs4all.nl> - - * nl.po: Translation updated by Wouter Bolsterlee. - -2006-08-07 Leonid Kanter <leon@asplinux.ru> - - * ru.po: Updated Russian translation - -2006-08-07 Inaki Larranaga <dooteo@euskalgnu.org> - - * eu.po: Fixed some typos. - -2006-08-03 Kjartan Maraas <kmaraas@gnome.org> - - * nb.po: Updated Norwegian bokmål translation. - -2006-08-03 Yair Hershkovitz <yairhr@gmail.com> - - * he.po: Updated Hebrew translation. - -2006-08-02 Jovan Naumovski <jovan@lugola.net> - - * mk.po: Updated Macedonian translation. - -2006-07-31 Jakub Friedl <jfriedl@suse.cz> - - * cs.po: Updated Czech translation. - -2006-07-23 Satoru SATOH <ss@gnome.gr.jp> - - * ja.po: Updated Japanese translation. - -2006-07-22 Christophe Merlet <redfox@redfoxcenter.org> - - * fr.po: Updated French translation from - Jonathan Ernst <jonathan@ernstfamily.ch>. - -2006-07-22 Kostas Papadimas <pkst@gnome.org> - - * el.po: Updated Greek translation - -2006-07-21 Christophe Merlet <redfox@redfoxcenter.org> - - * fr.po: Updated French translation from - Jonathan Ernst <jonathan@ernstfamily.ch>. - -2006-07-18 Hendrik Richter <hendrikr@gnome.org> - - * de.po: Updated German translation. - -2006-07-03 Runa Bhattacharjee <runabh@gmail.com> - - * bn_IN.po: Added Bengali India Translation - * LINGUAS: Added Bengali India (bn_IN) to the list of languages. - -2006-07-03 Ilkka Tuohela <hile@iki.fi> - - * fi.po: Updated Finnish translation. - -2006-06-29 Thierry Randrianiriana <thierryR@cvs.gnome.org> - - * mg.po: Added Malagasy translation - -2006-06-28 Rajesh Ranjan <rajeshkajha@yahoo.com> - - * hi.po: Updated Hindi Translation. - -2006-06-27 Rajesh Ranjan <rajeshkajha@yahoo.com> - - * hi.po: Updated Hindi Translation. - -2006-06-26 Rajesh Ranjan <rajeshkajha@yahoo.com> - - * hi.po: Updated Hindi Translation. - -2006-05-28 Pema Geyleg <pema.geyleg@gmail.com> - - * dz.po: Updated Dzongkha translation. - -2006-05-26 Clytie Siddall <clytie@riverland.net.au> - - * vi.po: Updated Vietnamese translation. - -2006-05-25 Inaki Larranaga <dooteo@euskalgnu.org> - - * eu.po: Updated Basque translation. - -2006-05-23 Theppitak Karoonboonyanan <thep@linux.thai.net> - - * th.po: Updated Thai translation. - -2006-05-14 Chao-Hsiung Liao <j_h_liau@yahoo.com.tw> - - * zh_HK.po: Updated Traditional Chinese translation(Hong Kong). - * zh_TW.po: Updated Traditional Chinese translation(Taiwan). - -2006-05-10 Ignacio Casal Quinteiro <nacho.resa@gmail.com> - - * gl.po: Updated Galician Translation. - -2006-05-06 Francisco Javier F. Serrador <serrador@cvs.gnome.org> - - * es.po: Updated Spanish translation. - -2006-05-02 Funda Wang <fundawang@linux.net.cn> - - * zh_CN.po: Updated Simplified Chinese translation. - -2006-04-30 Kjartan Maraas <kmaraas@gnome.org> - - * nb.po: Updated Norwegian bokmål translation. - -2006-04-26 Gora Mohanty <gmohanty@cvs.gnome.org> - - * lv.po: Updated Latvian translation by Raivis Dejus <orvils@gmail.com> - -2006-04-21 Theppitak Karoonboonyanan <thep@linux.thai.net> - - * th.po: Updated Thai translation. - -2006-04-20 Ankit Patel <ankit644@yahoo.com> - - * gu.po: Updated Gujarati Translation. - -2006-04-19 Ankit Patel <ankit644@yahoo.com> - - * gu.po: Updated Gujarati Translation. - -2006-04-17 Clytie Siddall <clytie@riverland.net.au> - - * vi.po: Updated Vietnamese translation. - -2006-04-17 Josep Puigdemont Casamajó <josep.puigdemont@gmail.com> - - * ca.po: Updated Catalan translation. - -2006-04-16 Funda Wang <fundawang@linux.net.cn> - - * zh_CN.po: Updated Simplified Chinese translation. - -2006-04-14 Francisco Javier F. Serrador <serrador@cvs.gnome.org> - - * es.po: Updated Spanish translation. - -2006-04-14 Raphael Higino <raphaelh@cvs.gnome.org> - - * pt_BR.po: Updated Brazilian Portuguese translation. - -2006-04-14 Åsmund Skjæveland <aasmunds@fys.uio.no> - - * nn.po: Updated Norwegian Nynorsk translation. - -2006-04-14 Ilkka Tuohela <hile@iki.fi> - - * fi.po: Updated Finnish translation. - -2006-04-14 Wouter Bolsterlee <uws+gnome@xs4all.nl> - - * nl.po: Translation updated by Wouter Bolsterlee. - -2006-04-14 Alexander Shopov <ash@contact.bg> - - * bg.po: Updated Bulgarian translation by - Alexander Shopov <ash@contact.bg> - -2006-04-09 Vincent van Adrighem <adrighem@gnome.org> - - * nl.po: Translation updated by Michiel Sikkes. - -2006-04-02 Kjartan Maraas <kmaraas@gnome.org> - - * nb.po: Updated Norwegian bokmål translation. - * no.po: Same. - -2006-03-24 Gora Mohanty <gmohanty@cvs.gnome.org> - - * or.po: Updated Oriya translation. - -2006-03-21 Priit Laes <amd@store20.com> - - * et.po: Translation updated by Ivar Smolin. - -2006-03-17 Priit Laes <amd@store20.com> - - * et.po: Translation updated by Ivar Smolin. - -2006-03-15 Žygimantas Beručka <zygis@gnome.org> - - * lt.po: Updated Lithuanian translation. - -2006-03-14 Mugurel Tudor <mugurelu@gnome.ro> - - * ro.po: Updated Romanian translation - -2006-03-14 Miloslav Trmac <mitr@volny.cz> - - * cs.po: Updated Czech translation. - -2006-03-13 Jordi Mallach <jordi@sindominio.net> - - * ca.po: Updated Catalan translation. - -2006-03-13 Vincent van Adrighem <adrighem@gnome.org> - - * nl.po: Translation updated by Tino Meinen. - -2006-03-13 Danilo Šegan <danilo@gnome.org> - - * sr.po, sr@Latn.po: Updated Serbian translation. - -2006-03-13 Alexander Shopov <ash@contact.bg> - - * bg.po: Updated Bulgarian translation by - Alexander Shopov <ash@contact.bg> - -2006-03-13 Laurent Dhima <laurenti@alblinux.net> - - * sq.po: Updated Albanian translation. - -2006-03-13 Francisco Javier F. Serrador <serrador@cvs.gnome.org> - - * es.po: Updated Spanish translation. - -2006-03-13 Maxim Dziumanenko <mvd@mylinux.ua> - - * uk.po: Updated Ukrainian translation. - -2006-03-13 Rajesh Ranjan <rranjan@redhat.com> - - * hi.po: Updated Hindi Translation. - -2006-03-13 Theppitak Karoonboonyanan <thep@linux.thai.net> - - * th.po: Updated Thai translation (merged from gnome-2-14 branch). - -2006-03-13 Satoru SATOH <ss@gnome.gr.jp> - - * ja.po: Updated Japanese translation. - -2006-03-13 Duarte Loreto <happyguy_pt@hotmail.com> - - * pt.po: Updated Portuguese translation. - -2006-03-12 Guilherme de S. Pastore <gpastore@gnome.org> - - * pt_BR.po: Updated Brazilian Portuguese translation. - -2006-03-13 Frank Arnold <farnold@cvs.gnome.org> - - * de.po: Updated German translation. - -2006-03-13 Daniel Nylander <po@danielnylander.se> - - * sv.po: Updated Swedish translation. - -2006-03-12 Ignacio Casal Quinteiro <nacho.resa@gmail.com> - - * gl.po: Updated Galician Translation. - -2006-03-12 Raphael Higino <raphaelh@cvs.gnome.org> - - * pt_BR.po: Updated Brazilian Portuguese translation. - -2006-03-12 Priit Laes <amd@store20.com> - - * et.po: Translation updated by Ivar Smolin. - -2006-03-12 Miloslav Trmac <mitr@volny.cz> - - * cs.po: Updated Czech translation by Petr Tomeš. - -2006-03-12 Roozbeh Pournader <roozbeh@farsiweb.info> - - * fa.po: Updated Persian translation by Meelad Zakaria, - Elnaz Sarbar, and Farzaneh Sarafraz. - -2006-03-09 Hendrik Richter <hendrikr@gnome.org> - - * de.po: Updated German translation. - -2006-03-09 Laurent Dhima <laurenti@alblinux.net> - - * sq.po: Updated Albanian translation. - -2006-03-08 Laurent Dhima <laurenti@alblinux.net> - - * sq.po: Updated Albanian translation. - -2006-03-08 Gabor Kelemen <kelemeng@gnome.hu> - - * hu.po: Hungarian translation updated. - -2006-03-06 Funda Wang <fundawang@linux.net.cn> - - * zh_CN.po: Updated Simplified Chinese translation. - -2006-03-06 Daniel Nylander <po@danielnylander.se> - - * sv.po: Updated Swedish translation - -2006-03-05 Mugurel Tudor <mugurelu@gnome.ro> - - * ro.po: Updated Romanian translation - -2006-03-05 Alexander Shopov <ash@contact.bg> - - * bg.po: Updated Bulgarian translation by - Alexander Shopov <ash@contact.bg> - -2006-03-04 Hendrik Richter <hendrikr@gnome.org> - - * de.po: Updated German translation. - -2006-03-03 Maxim Dziumanenko <mvd@mylinux.ua> - - * uk.po: Updated Ukrainian translation. - -2006-03-02 Hendrik Richter <hendrikr@gnome.org> - - * de.po: Updated German translation. - -2006-03-02 Hendrik Richter <hendrikr@gnome.org> - - * de.po: Updated German translation. - -2006-03-02 Rhys Jones <rhys@sucs.org> - - * cy.po: Updated Welsh translation. - -2006-03-01 Leonid Kanter <leon@asplinux.ru> - - * ru.po: Updated Russian translation - -2006-03-01 Josep Puigdemont i Casamajó <josep.puigdemont@gmail.com> - - * ca.po: Updated Catalan translation. - -2006-02-27 Leonid Kanter <leon@asplinux.ru> - - * ru.po: Updated Russian translation - -2006-02-27 Lasse Bang Mikkelsen <lbm@fatalerror.dk> - - * da.po: Updated Danish translation. - -2006-02-25 Miloslav Trmac <mitr@volny.cz> - - * cs.po: Updated Czech translation. - -2006-02-23 Inaki Larranaga <dooteo@euskalgnu.org> - - * eu.po: Updated Basque translation. - -2006-02-23 Clytie Siddall <clytie@riverland.net.au> - - * ka.po: Added Georgian translation by Alexander Didebulidze <didebuli@in.tum.de>. - -2006-02-23 Duarte Loreto <happyguy_pt@hotmail.com> - - * pt.po: Updated Portuguese translation. - -2006-02-23 Žygimantas Beručka <zygis@gnome.org> - - * lt.po: Updated Lithuanian translation. - -2006-02-21 Vincent van Adrighem <adrighem@gnome.org> - - * nl.po: Translation updated by Tino Meinen. - -2006-02-21 Clytie Siddall <clytie@riverland.net.au> - - * vi.po: Updated Vietnamese translation. - -2006-02-21 Slobodan D. Sredojevic <slobo@akrep.be> - - * sr.po, sr@Latn.po: Updated Serbian translation - -2006-02-21 Ignacio Casal Quinteiro <nacho.resa@gmail.com> - - * gl.po: Updated Galician Translation. - -2006-02-01 Ankit Patel <ankit644@yahoo.com> - - * gu.po: Updated Gujarati Translation. - -2006-02-20 Kostas Papadimas <pkst@gnome.org> - - * el.po: Updated Greek translation. - -2006-02-20 Ilkka Tuohela <hile@iki.fi> - - * fi.po: Updated Finnish translation. - -2006-02-18 Takeshi AIHANA <takeshi.aihana@gmail.com> - - * ja.po: Updated Japanese translation. - -2006-02-18 Francisco Javier F. Serrador <serrador@cvs.gnome.org> - - * es.po: Updated Spanish translation. - -2006-02-18 Kjartan Maraas <kmaraas@gnome.org> - - * nb.po: Updated Norwegian bokmål translation. - * no.po: Same. - -2006-02-13 Miloslav Trmac <mitr@volny.cz> - - * cs.po: Updated Czech translation. - -2006-02-06 Funda Wang <fundawang@linux.net.cn> - - * zh_CN.po: Updated Simplified Chinese translation. - -2006-02-03 Kjartan Maraas <kmaraas@gnome.org> - - * nb.po: Updated Norwegian bokmål translation. - * no.po: Same. - -2006-01-31 Vincent van Adrighem <adrighem@gnome.org> - - * nl.po: Translation updated by Tino Meinen. - -2006-01-31 Slobodan D. Sredojevic <slobo@akrep.be> - - * sr.po, sr@Latn.po: Updated Serbian translation - -2006-01-28 Theppitak Karoonboonyanan <thep@linux.thai.net> - - * th.po: Updated Thai translation. - -2006-01-27 Josep Puigdemont i Casamajó <josep.puigdemont@gmail.com> - - * ca.po: Updated Catalan translation. - -2006-01-26 Adam Weinberger <adamw@gnome.org> - - * en_CA.po: Updated Canadian English translation. - -2006-01-26 Evandro Fernandes Giovanini <evandrofg@ig.com.br> - - * pt_BR.po: Updated Brazilian Portuguese translation. - -2006-01-24 Ignacio Casal Quinteiro <nacho.resa@gmail.com> - - * gl.po: Updated Galician Translation. - -2006-01-23 Ankit Patel <ankit644@yahoo.com> - - * gu.po: Updated Gujarati Translation. - -2006-01-23 Funda Wang <fundawang@linux.net.cn> - - * zh_CN.po: Updated Simplified Chinese translation. - -2006-01-22 Kjartan Maraas <kmaraas@gnome.org> - - * nb.po: Updated Norwegian bokmål translation. - * no.po: Same. - -2006-01-21 Ilkka Tuohela <hile@iki.fi> - - * fi.po: Updated Finnish translation. - -2006-01-22 Clytie Siddall <clytie@riverland.net.au> - - * vi.po: Updated Vietnamese translation. - -2006-01-21 Ilkka Tuohela <hile@iki.fi> - - * fi.po: Updated Finnish translation. - -2006-01-21 Francisco Javier F. Serrador <serrador@cvs.gnome.org> - - * es.po: Updated Spanish tranlation. - -2006-01-21 Ignacio Casal Quinteiro <nacho.resa@gmail.com> - - * gl.po: Updated Galician Translation. - -2006-01-20 Vincent van Adrighem <adrighem@gnome.org> - - * nl.po: Translation updated by Tino Meinen. - -2006-01-18 Funda Wang <fundawang@linux.net.cn> - - * zh_CN.po: Updated Simplified Chinese translation. - -2006-01-17 Ignacio Casal Quinteiro <nacho.resa@gmail.com> - - * gl.po: Updated Galician Translation. - -2006-01-16 Ilkka Tuohela <hile@iki.fi> - - * fi.po: Updated Finnish translation. - -2006-01-15 Francisco Javier F. Serrador <serrador@cvs.gnome.org> - - * es.po: Updated Spanish translation. - -2006-01-15 Takeshi AIHANA <takeshi.aihana@gmail.com> - - * ja.po: Updated Japanese translation. - -2006-01-11 Adam Weinberger <adamw@gnome.org> - - * en_CA.po: Updated Canadian English translation. - -2006-01-11 Theppitak Karoonboonyanan <thep@linux.thai.net> - - * th.po: Updated Thai translation. - -2006-01-11 Ankit Patel <ankit644@yahoo.com> - - * gu.po: Updated Gujarati Translation. - -2006-01-11 Clytie Siddall <clytie@riverland.net.au> - - * vi.po: Updated Vietnamese translation. - -2005-12-30 Clytie Siddall <clytie@riverland.net.au> - - * vi.po: Updated Vietnamese translation. - -2006-01-06 Kjartan Maraas <kmaraas@gnome.org> - - * nb.po: Updated Norwegian bokmål translation. - * no.po: Same - -2005-12-31 Ilkka Tuohela <hile@iki.fi> - - * fi.po: Updated Finnish translation. - -2005-12-25 Kang Jeong-Hee <Keizi@mail.co.kr> - - * ko.po: Updated Korean translation. - -2005-12-11 Miloslav Trmac <mitr@volny.cz> - - * cs.po: Updated Czech translation. - -2005-12-11 Ankit Patel <ankit644@yahoo.com> - - * gu.po: Updated Gujarati Translation. - -2005-12-03 Adam Weinberger <adamw@gnome.org> - - * en_CA.po: Updated Canadian English translation. - -2005-12-03 Kjartan Maraas <kmaraas@gnome.org> - - * nb.po: Updated Norwegian bokmål translation. - * no.po: Same - -2005-11-22 Marcel Telka <marcel@telka.sk> - - * sk.po: Updated Slovak translation. - -2005-11-22 Alexander Shopov <ash@contact.bg> - - * bg.po: Updated Bulgarian translation by - Alexander Shopov <ash@contact.bg> - -2005-11-22 Theppitak Karoonboonyanan <thep@linux.thai.net> - - * th.po: Updated Thai translation. - -2005-11-21 Francisco Javier F. Serrador <serrador@cvs.gnome.org> - - * es.po: Updated Spanish translation. - -2005-11-20 Francisco Javier F. Serrador <serrador@cvs.gnome.org> - - * es.po: Updated Spanish translation. - -2005-11-20 Ignacio Casal Quinteiro <nacho.resa@gmail.com> - - * gl.po: Updated Galician Translation. - -2005-11-20 Takeshi AIHANA <aihana@gnome.gr.jp> - - * ja.po: Updated Japanese translation. - -2005-11-17 Vincent van Adrighem <adrighem@gnome.org> - - * nl.po: Translation updated by Wouter Bolsterlee. - -2005-11-13 Theppitak Karoonboonyanan <thep@linux.thai.net> - - * th.po: Updated Thai translation. - -2005-11-03 Miloslav Trmac <mitr@volny.cz> - - * cs.po: Updated Czech translation. - -2005-10-28 Francisco Javier F. Serrador <serrador@cvs.gnome.org> - - * es.po: Updated Spanish translation. - -2005-10-28 Takeshi AIHANA <aihana@gnome.gr.jp> - - * ja.po: Updated Japanese translation. - -2005-10-27 Erdal Ronahi <erdal.ronahi@gmail.com> - - * ku.po: Added Kurdish translation. - -2005-10-17 Marcel Telka <marcel@telka.sk> - - * sk.po: Updated Slovak translation. - -2005-10-15 Vincent van Adrighem <adrighem@gnome.org> - - * nl.po: Translation updated. - -2005-10-14 Vincent van Adrighem <adrighem@gnome.org> - - * nl.po: Translation updated. - -2005-10-14 Kostas Papadimas <pkst@gnome.org> - - * el.po: Updated Greek translation. - -2005-10-10 Priit Laes <plaes@cvs.gnome.org> - - * et.po: Translation updated by Ivar Smolin. - -2005-10-04 Alexander Shopov <ash@contact.bg> - - * bg.po: Updated Bulgarian translation by - Alexander Shopov <ash@contact.bg> - -2005-10-04 Funda Wang <fundawang@linux.net.cn> - - * zh_CN.po: Updated Simplified Chinese translation. - -2005-10-04 Adam Weinberger <adamw@gnome.org> - - * en_CA.po: Updated Canadian English translation. - -2005-10-03 Runa Bhattacharjee <runa@bengalinux.org> - * bn.po: Updated Bengali Translation by Mahay Alam Khan <makl10n@yahoo.com> - -2005-10-02 Christian Rose <menthos@menthos.com> - - * sv.po: Reverted unauthorized changes made by - user 'kloczek'. - -2005-09-26 Alessio Frusciante <algol@firenze.linux.it> - - * it.po: Updated Italian translation by - Luca Ferretti <elle.uca@infinito.it>. - -2005-09-24 Funda Wang <fundawang@linux.net.cn> - - * zh_CN.po: Updated Simplified Chinese translation. - -2005-09-21 Francisco Javier F. Serrador <serrador@cvs.gnome.org> - - * es.po: Updated Spanish translation. - -2005-09-20 Christian Rose <menthos@menthos.com> - - * sv.po: Updated Swedish translation. - -2005-09-16 Clytie Siddall <clytie@riverland.net.au> - - * vi.po: Updated Vietnamese translation. - -2005-09-08 Inaki Larranaga <dooteo@euskalgnu.org> - - * eu.po: Updated Basque translation. - -2005-09-07 Priit Laes <plaes@cvs.gnome.org> - - * et.po: Translation updated by Ivar Smolin. - -2005-09-04 Danilo Šegan <danilo@gnome.org> - - * hy.po: Added Armenian translation by Norayr Chilingaryan - <asprayama@yahoo.com>. - -2005-09-04 Ignacio Casal Quinteiro <nacho.resa@gmail.com> - - * gl.po: Updated Galician Translation. - -2005-09-03 Danilo Šegan <danilo@gnome.org> - - * sr.po, sr@Latn.po: Updated. - -2005-09-02 Leonid Kanter <leon@asplinux.ru> - - * ru.po: Updated Russian translation - -2005-09-01 Baris Cicek <baris@teamforce.name.tr> - - * tr.po: Updated Turkish Translation - -2005-08-31 Žygimantas Beručka <zygis@gnome.org> - - * lt.po: Updated Lithuanian translation. - -2005-08-30 Hendrik Richter <hendi@gnome-de.org> - - * de.po: Updated German translation. - -2005-08-30 Changwoo Ryu <cwryu@debian.org> - - * ko.po: Updated Korean translation by Young-Ho Cha. - -2005-08-29 Telsa Gwynne <hobbit@aloss.ukuu.org.uk> - - * cy.po: Updated Welsh translation. - -2005-08-28 Christophe Merlet <redfox@redfoxcenter.org> - - * fr.po: Updated French translation. - -2005-08-25 Vincent van Adrighem <adrighem@gnome.org> - - * nl.po: Translation updated by Michiel Sikkes. - -2005-08-20 Josep Puigdemont i Casamajó <josep.puigdemont@gmail.com> - - * ca.po: Updated Catalan translation. - -2005-08-19 Priit Laes <plaes@cvs.gnome.org> - - * et.po: Translation updated by Ivar Smolin. - -2005-08-17 Laurent Dhima <laurenti@alblinux.net> - - * sq.po: Updated Albanian translation. - -2005-08-15 Maxim Dziumanenko <mvd@mylinux.ua> - - * uk.po: Updated Ukrainian translation. - -2005-08-15 Gabor Kelemen <kelemeng@gnome.hu> - - * hu.po: Hungarian translation updated. - -2005-08-15 Mugurel Tudor <mugurelu@gnome.ro> - - * ro.po: Updated Romanian translation - -2005-08-14 Mohammad DAMT <mdamt@gnome.org> - - * id.po: Updated Indonesian translation - -2005-08-13 Kostas Papadimas <pkst@gnome.org> - - * el.po: Updated Greek translation. - -2005-08-11 Duarte Loreto <happyguy_pt@hotmail.com> - - * pt.po: Updated Portuguese translation. - -2005-08-10 Alexander Shopov <ash@contact.bg> - - * bg.po: Updated Bulgarian translation by - Rostislav Raykov <zbrox@i-space.org> - -2005-08-02 Chao-Hsiung Liao <j_h_liau@yahoo.com.tw> - - * zh_TW.po: Updated Traditional Chinese translation. - -2005-07-31 Yair Hershkovitz <yairhr@gmail.com> - - * he.po: Updated Hebrew translation by Yuval Tanai. - -2005-07-28 Artur Flinta <aflinta@cvs.gnome.org> - - * pl.po: Updated Polish translation by GNOME PL Team. - -2005-07-26 Raphael Higino <raphaelh@cvs.gnome.org> - - * pt_BR.po: Converted to UTF-8. - -2005-07-26 Raphael Higino <raphaelh@cvs.gnome.org> - - * pt_BR.po: Updated Brazilian Portuguese translation. - -2005-07-24 Ilkka Tuohela <hile@iki.fi> - - * fi.po: Updated Finnish translation. - -2005-07-24 Kjartan Maraas <kmaraas@gnome.org> - - * nb.po: Updated Norwegian bokmål translation. - * no.po: Same - -2005-07-23 Clytie Siddall <clytie@riverland.net.au> - - * vi.po: Updated Vietnamese translation. - -2005-07-23 Funda Wang <fundawang@linux.net.cn> - - * zh_CN.po: Updated Simplified Chinese translation. - -2005-07-21 Ankit Patel <ankit644@yahoo.com> - - * gu.po: Updated Gujarati Translation. - -2005-07-20 Marcel Telka <marcel@telka.sk> - - * sk.po: Updated Slovak translation. - -2005-07-18 Adam Weinberger <adamw@gnome.org> - - * en_CA.po: Updated Canadian English translation. - -2005-07-17 Christophe Merlet <redfox@redfoxcenter.org> - - * fr.po: Updated French translation. - -2005-07-17 Francisco Javier F. Serrador <serrador@cvs.gnome.org> - - * es.po: Updated Spanish translation. - -2005-07-17 Theppitak Karoonboonyanan <thep@linux.thai.net> - - * th.po: Updated Thai translation. - -2005-07-17 Nikos Charonitakis <charosn@her.forthenet.gr> - - * el.po: Updated Greek translation. - -2005-07-16 Takeshi AIHANA <aihana@gnome.gr.jp> - - * ja.po: Updated Japanese translation. - -2005-07-15 Ignacio Casal Quinteiro <nacho.resa@gmail.com> - - * gl.po: Updated Galician Translation. - -2005-07-14 Yair Hershkovitz <yairhr@gmail.com> - - * he.po: Updated Hebrew translation. - -2005-07-14 Miloslav Trmac <mitr@volny.cz> - - * cs.po: Updated Czech translation. - -2005-07-13 Marcel Telka <marcel@telka.sk> - - * sk.po: Updated Slovak translation. - -2005-07-12 Priit Laes <plaes@cvs.gnome.org> - - * et.po: Translation updated by Ivar Smolin. - -2005-07-08 Clytie Siddall <clytie@riverland.net.au> - - * vi.po: Updated Vietnamese translation. - -2004-07-06 Christian Rose <menthos@menthos.com> - - * gl.po: Updated Galician translation by - Ignacio Casal Quinteiro <nacho.resa@gmail.com>. - -2005-07-04 Hendrik Richter <hendi@gnome-de.org> - - * de.po: Fixed German translation by - Jens Seidel <jensseidel@users.sf.net>. - -2005-06-23 Ignacio Casal Quinteiro <nacho.resa@gmail.com> - - * gl.po: Updated Galician translation. - -2005-06-22 Abel Cheung <maddog@linuxhall.org> - - * zh_TW.po: Fix language team reference. - -2005-06-05 Theppitak Karoonboonyanan <thep@linux.thai.net> - - * th.po: Updated Thai translation. - -2005-06-01 Priit Laes <plaes@cvs.gnome.org> - - * et.po: Translation updated. - -2005-05-19 Nikos Charonitakis <charosn@her.forthnet.gr> - - * el.po: Updated Greek translation. - -2005-05-11 Kostas Papadimas <pkst@gnome.org> - - * el.po: Updated Greek Translation. - -2005-05-10 Adi Attar <aattar@cvs.gnome.org> - - * xh.po: Updated Xhosa translation. - -2005-04-28 Kostas Papadimas <pkst@gnome.org> - - * el.po: Updated Greek translation - -2005-04-25 Priit Laes <plaes@cvs.gnome.org> - - * et.po: Translation updated by Ivar Smolin. - -2005-04-17 Pauli Virtanen <pauli.virtanen@hut.fi> - - * fi.po: Fix a small mistranslation. - -2005-04-09 Christopher Orr <chris@protactin.co.uk> - - * en_GB.po: Updated British English translation. - -2005-04-06 Roozbeh Pournader <roozbeh@farsiweb.info> - - * fa.po: Updated Persian translation by - Elnaz Sarbar <elnaz@farsiweb.info>. - -2005-04-05 Pawan Chitrakar <pawan@nplinux.org> - - * ne.po: Added Nepali Translation. - -2005-04-03 Gabor Kelemen <kelemeng@gnome.hu> - - * hu.po: Hungarian translation updated. - -2005-03-31 Steve Murphy <murf@e-tools.com> - - * rw.po: Added Kinyarwanda translation. - -2005-03-29 Adi Attar <aattar@cvs.gnome.org> - - * xh.po: Updated Xhosa translation. - -2005-03-17 Adam Weinberger <adamw@gnome.org> - - * en_CA.po: Updated Canadian English translation. - -2005-03-12 Baris Cicek <baris@teamforce.name.tr> - - * tr.po: Updated Turkish Translation - -2005-03-10 Adi Attar <aattar@cvs.gnome.org> - - * xh.po: Added Xhosa translation. - -2005-03-07 Vincent van Adrighem <adrighem@gnome.org> - - * nl.po: Translation updated by Reinout van Schouwen. - -2005-03-07 Mugurel Tudor <mugurelu@go.ro> - - * ro.po: Updated Romanian translation. - -2005-03-04 Laszlo Dvornik <dvornik@gnome.hu> - - * hu.po: Hungarian translation updated by Gabor Kelemen. - -2005-03-03 Alexander Shopov <ash@contact.bg> - - * bg.po: Updated Bulgarian translation by - Vladimir Petkov <vpetkov@i-space.org> - -2005-03-03 Žygimantas Beručka <uid0@akl.lt> - - * lt.po: Updated Lithuanian translation. - -2005-03-02 Danilo Šegan <dsegan@gmx.net> - - * sr.po, sr@Latn.po: Updated Serbian translation. - -2005-03-02 Abel Cheung <maddog@linuxhall.org> - - * zh_TW.po: Updated traditional Chinese translation from GNOME HK Team - -2005-02-28 Vincent van Adrighem <adrighem@gnome.org> - - * nl.po: Translation updated by Reinout van Schouwen. - -2005-02-27 Alessio Frusciante <algol@firenze.linux.it> - - * it.po: Updated Italian translation by - Luca Ferretti <elle.uca@infinito.it>. - -2005-02-24 Artur Flinta <aflinta@cvs.gnome.org> - - * pl.po: Updated Polish translation by GNOME PL Team. - -2005-02-24 Ankit Patel <ankit644@yahoo.com> - - * gu.po: Updated Gujarati Translation. - -2005-02-23 Vincent van Adrighem <adrighem@gnome.org> - - * nl.po: Translation updated by Michiel Sikkes. - -2004-02-22 Roozbeh Pournader <roozbeh@farsiweb.info> - - * fa.po: Updated Persian translation by - Elnaz Sarbar <elnaz@farsiweb.info>. - -2005-02-22 Raphael Higino <raphaelh@cvs.gnome.org> - - * pt_BR.po: Updated Brazilian Portuguese translation. - -2005-02-21 Christophe Merlet <redfox@redfoxcenter.org> - - * fr.po: Updated French translation. - -2005-02-21 Bastien Nocera <hadess@hadess.net> - - * en_GB.po: the file is actually in UTF-8 - -2005-02-21 Martin Willemoes Hansen <mwh@sysrq.dk> - - * da.po: Updated Danish translation. - -2005-02-21 Priit Laes <plaes@cvs.gnome.org> - - * et.po: Translation updated by Tõivo Leedjärv. - -2005-02-18 Changwoo Ryu <cwryu@debian.org> - - * ko.po: Updated Korean translation. - -2005-02-18 Duarte Loreto <happyguy_pt@hotmail.com> - - * pt.po: Updated Portuguese translation. - -2005-02-17 Vincent van Adrighem <adrighem@gnome.org> - - * nl.po: Translation updated by Tino Meinen. - -2005-02-17 Laurent Dhima <laurenti@alblinux.net> - - * sq.po: Updated Albanian translation. - -2005-02-16 Jordi Mallach <jordi@sindominio.net> - - * ca.po: Updated Catalan translation. - -2005-02-15 Maxim Dziumanenko <mvd@mylinux.com.ua> - - * uk.po: Updated Ukrainian translation. - -2005-02-15 Kjartan Maraas <kmaraas@gnome.org> - - * nb.po: s/applikasjon/program - * no.po: Same - -2005-02-12 Marcel Telka <marcel@telka.sk> - - * sk.po: Updated Slovak translation. - -2005-02-12 Takeshi AIHANA <aihana@gnome.gr.jp> - - * ja.po: Updated Japanese translation. - -2005-02-11 Kostas Papadimas <pkst@gnome.org> - - * el.po: Updated Greek translation. - -2005-02-10 Francisco Javier F. Serrador <serrador@cvs.gnome.org> - - * es.po: Updated Spanish translation. - -2005-02-08 Leonid Kanter <leon@asplinux.ru> - - * ru.po: Updated Russian translation - -2005-02-08 Kjartan Maraas <kmaraas@gnome.org> - - * nb.po: Update - * no.po: Update - -2005-02-07 David Lodge <dave@cirt.net> - - * en_GB.po: Updated British translation. - -2005-02-06 Adam Weinberger <adamw@gnome.org> - - * en_CA.po: Updated Canadian English translation. - -2005-02-06 Miloslav Trmac <mitr@volny.cz> - - * cs.po: Updated Czech translation. - -2005-02-06 Alexander Shopov <ash@contact.bg> - - * bg.po: Updated Bulgarian translation by - Vladimir Petkov <vpetkov@i-space.org> - -2005-02-06 Pauli Virtanen <pauli.virtanen@hut.fi> - - * fi.po: Updated Finnish translation. - -2005-02-05 Frank Arnold <farnold@cvs.gnome.org> - - * de.po: Updated German translation. - -2005-02-05 Francisco Javier F. Serrador <serrador@cvs.gnome.org> - - * es.po: Updated Spanish translation. - -2005-02-05 Žygimantas Beručka <uid0@akl.lt> - - * lt.po: Updated Lithuanian translation. - -2005-02-04 Francisco Javier F. Serrador <serrador@cvs.gnome.org> - - * es.po: Updated Spanish translation. - -2005-02-04 Changwoo Ryu <cwryu@debian.org> - - * ko.po: Updated Korean translation. - -2005-02-02 Miloslav Trmac <mitr@volny.cz> - - * cs.po: Updated Czech translation. - -2005-02-02 Frank Arnold <farnold@cvs.gnome.org> - - * de.po: Updated German translation. - -2005-02-01 Kjartan Maraas <kmaraas@gnome.org> - - * nb.po: Update - * no.po: Update - -2005-02-01 Adam Weinberger <adamw@gnome.org> - - * en_CA.po: Updated Canadian English translation. - -2005-02-01 Žygimantas Beručka <uid0@akl.lt> - - * lt.po: Updated Lithuanian translation. - -2005-01-31 Christian Rose <menthos@menthos.com> - - * sv.po: Updated Swedish translation. - -2005-01-31 Miloslav Trmac <mitr@volny.cz> - - * cs.po: Updated Czech translation. - -2005-01-31 Christian Rose <menthos@menthos.com> - - * sv.po: Updated Swedish translation. - -2005-01-30 Žygimantas Beručka <uid0@akl.lt> - - * lt.po: Updated Lithuanian translation. - -2005-01-29 Francisco Javier F. Serrador <serrador@cvs.gnome.org> - - * es.po: Updated Spanish translation. - -2005-01-29 Miloslav Trmac <mitr@volny.cz> - - * cs.po: Updated Czech translation. - -2005-01-29 Marcel Telka <marcel@telka.sk> - - * sk.po: Updated Slovak translation. - -2005-01-29 Adam Weinberger <adamw@gnome.org> - - * en_CA.po: Updated Canadian English translation. - -2005-01-28 Kjartan Maraas <kmaraas@gnome.org> - - * nb.po: Update - * no.po: Update - -2005-01-26 Adam Weinberger <adamw@gnome.org> - - * en_CA.po: Updated Canadian English translation. - -2005-01-26 Francisco Javier F. Serrador <serrador@cvs.gnome.org> - - * es.po: Updated Spanish translation. - -2005-01-26 Duarte Loreto <happyguy_pt@hotmail.com> - - * pt.po: Updated Portuguese translation. - -2005-01-25 Theppitak Karoonboonyanan <thep@linux.thai.net> - - * th.po: Updated Thai translation. - -2005-01-23 Funda Wang <fundawang@linux.net.cn> - - * zh_CN.po: Updated Simplified Chinese translation. - -2005-01-21 Kjartan Maraas <kmaraas@gnome.org> - - * nb.po: Update this too while we're at it. - -2005-01-21 Kjartan Maraas <kmaraas@gnome.org> - - * nn.po: Update - -2005-01-15 Frank Arnold <farnold@cvs.gnome.org> - - * de.po: Updated German translation. - -2005-01-01 Francisco Javier F. Serrador <serrador@cvs.gnome.org> - - * es.po: Updated Spanish translation. - -2004-12-28 Christian Rose <menthos@menthos.com> - - * sv.po: Updated Swedish translation. - -2004-12-25 Miloslav Trmac <mitr@volny.cz> - - * cs.po: Updated Czech translation. - -2004-12-21 Takeshi AIHANA <aihana@gnome.gr.jp> - - * ja.po: Updated Japanese translation. - -2004-12-20 Adam Weinberger <adamw@gnome.org> - - * en_CA.po: Updated Canadian English translation. - -2004-12-16 Alexander Shopov <ash@contact.bg> - - * bg.po: Updated Bulgarian translation by - Vladimir Petkov <vpetkov@i-space.org> - -2004-12-07 Martin Willemoes Hansen <mwh@sysrq.dk> - - * da.po: Updated Danish translation. - -2004-11-23 Martin Willemoes Hansen <mwh@sysrq.dk> - - * da.po: Updated Danish translation. - -2004-11-14 Christophe Merlet <redfox@redfoxcenter.org> - - * fr.po: Updated French translation from - Baptiste Mille-Mathias <baptiste@mille-mathias.info>. - -2004-11-13 Žygimantas Beručka <uid0@akl.lt> - - * lt.po: Updated Lithuanian translation. - -2004-11-04 Takeshi AIHANA <aihana@gnome.gr.jp> - - * ja.po: Updated Japanese translation. - -2004-10-30 Francisco Javier F. Serrador <serrador@cvs.gnome.org> - - * es.po: Updated Spanish translation. - -2004-10-19 Laurent Dhima <laurenti@alblinux.net> - - * sq.po: Updated Albanian translation. - -2004-10-15 Danilo Šegan <dsegan@gmx.net> - - * sr.po, sr@Latn.po: Updated Serbian translation. - -2004-10-14 Miloslav Trmac <mitr@volny.cz> - - * cs.po: Updated Czech translation. - -2004-10-14 Adam Weinberger <adamw@gnome.org> - - * en_CA.po: Updated Canadian English translation. - -2004-10-13 David Lodge <dave@cirt.net> - - * en_GB.po: Updated British English translation. - -2004-09-26 Adam Weinberger <adamw@gnome.org> - - * en_CA.po: Updated Canadian English translation. - -2004-09-19 Alessio Frusciante <algol@firenze.linux.it> - - * it.po: Updated Italian translation by - Luca Ferretti <elle.uca@infinito.it>. - -2004-09-14 Gora Mohanty <gmohanty@cvs.gnome.org> - - * or.po: Updated Oriya translation. - -2004-09-12 Paisa Seeluangsawat <paisa@users.sf.net> - - * th.po: Updated Thai translation. - -2004-09-12 Dafydd Harries <daf@muse.19inch.net> - - * cy.po: Updated Welsh translation. - -2004-09-11 Abel Cheung <maddog@linuxhall.org> - - * zh_TW.po: Updated traditional Chinese translation by GNOME HK Team. - -2004-09-10 Christophe Merlet <redfox@redfoxcenter.org> - - * fr.po: Updated French translation. - -2004-09-08 Abel Cheung <maddog@linux.org.hk> - - * zh_TW.po: Updated traditional Chinese translation by GNOME HK Team. - -2004-09-08 Raphael Higino <raphaelh@cvs.gnome.org> - - * pt_BR.po: Updated Brazilian Portuguese translation. - -2004-09-08 Arafat Medini <lumina@arabeyes.org> - - * ar.po: Updated Arabic translation - -2004-09-07 Mugurel Tudor <mugurelu@go.ro> - - * ro.po: Updated Romanian translation. - -2004-09-05 Miloslav Trmac <mitr@volny.cz> - - * cs.po: Updated Czech translation. - -2004-09-03 Baris Cicek <baris@teamforce.name.tr> - - * tr.po: Updated Turkish Translation - -2004-08-31 Åsmund Skjæveland <aasmunds@fys.uio.no> - - * nn.po: Updated Norwegian Nynorsk translation. - -2004-08-29 Kostas Papadimas <pkst@gnome.org> - - * el.po: Updated Greek translation. - -2004-08-28 Francisco Javier F. Serrador <serrador@cvs.gnome.org> - - * es.po: Updated Spanish translation. - -2004-08-26 Iñaki Larrañaga <dooteo@euskalgnu.org> - - * eu.po: Updated Basque translation. - -2004-08-23 Maxim Dziumanenko <mvd@mylinux.com.ua> - - * uk.po: Updated Ukrainian translation. - -2004-08-21 Jordi Mallach <jordi@sindominio.net> - - * ca.po: Updated Catalan translation. - -2004-08-20 Laurent Dhima <laurenti@alblinux.net> - - * sq.po: Updated Albanian translation. - -2004-08-18 Pauli Virtanen <pauli.virtanen@hut.fi> - - * fi.po: Updated Finnish translation. - -2004-08-18 Laurent Dhima <laurenti@alblinux.net> - - * sq.po: Updated Albanian translation. - -2004-08-17 Christian Rose <menthos@menthos.com> - - * bs.po: Added Bosnian translation by - Kemal Sanjta <gomez@lugzdk.ba>. - -2004-08-17 Metin Amiroff <metin@karegen.com> - - * az.po: Translation updated. - -2004-08-16 Kjartan Maraas <kmaraas@gnome.org> - - * nb.po: Added this here. - -2004-08-15 Changwoo Ryu <cwryu@debian.org> - - * ko.po: Updated Korean translation. - -2004-08-13 Tommi Vainikainen <thv@iki.fi> - - * fi.po: Unified some fields in po headers for Finnish team. - -2004-08-13 Gurban M. Tewekgeli <gmtavakkoli@yahoo.com> - - * tk.po: Added Turkmen translation. - -2004-08-11 Dmitry G. Mastrukov <dmitry@taurussoft.org> - - * ru.po: Updated Russian translation - from Russian team <gnome-cyr@gnome.org>. - -2004-08-10 Artur Flinta <aflinta@cvs.gnome.org> - - * pl.po: Updated Polish translation by GNOME PL Team. - -2004-08-07 Danilo Šegan <dsegan@gmx.net> - - * sr.po, sr@Latn.po: Updated Serbian translation. - -2004-08-06 Funda Wang <fundawang@linux.net.cn> - - * zh_CN.po: Updated Simplified Chinese translation. - -2004-08-06 Takeshi AIHANA <aihana@gnome.gr.jp> - - * ja.po: Updated Japanese translation. - -2004-08-03 Vincent van Adrighem <adrighem@gnome.org> - - * nl.po: Translation updated by Michiel Sikkes. - -2004-08-02 Duarte Loreto <happyguy_pt@hotmail.com> - - * pt.po: Updated Portuguese translation. - -2004-08-02 Adam Weinberger <adamw@gnome.org> - - * en_CA.po: Updated Canadian English translation. - -2004-08-01 Kjartan Maraas <kmaraas@gnome.org> - - * no.po: Updated Norwegian translation. - -2004-07-30 Martin Willemoes Hansen <mwh@sysrq.dk> - - * da.po: Reviewed and updated fuzzy messages. - -2004-07-30 Kartik Mistry <kartik_m@magnet-i.com> - - * gu.po: Updated and added Gujarati translation. - -2004-07-29 Changwoo Ryu <cwryu@debian.org> - - * ko.po: Updated Korean translation. - -2004-07-28 Laurent Dhima <laurenti@alblinux.net> - - * sq.po: Updated Albanian translation. - -2004-07-27 Alexander Shopov <ash@contact.bg> - - * bg.po: Updated Bulgarian translation by - Rostislav "zbrox" Raykov <zbrox@i-space.org> - -2004-07-27 Laurent Dhima <laurenti@alblinux.net> - - * sq.po: Updated Albanian translation. - -2004-07-25 Christian Rose <menthos@menthos.com> - - * sv.po: Updated Swedish translation. - -2004-07-25 Christian Neumair <chris@gnome-de.org> - - * de.po: Updated German translation. - -2004-07-25 David Lodge <dave@cirt.net> - - * en_GB.po: Added British translation. - -2004-07-24 Francisco Javier F. Serrador <serrador@cvs.gnome.org> - - * es.po: Updated Spanish translation. - -2004-07-23 Miloslav Trmac <mitr@volny.cz> - - * cs.po: Updated Czech translation. - -2004-07-23 Žygimantas Beručka <uid0@akl.lt> - - * lt.po: Updated Lithuanian translation. - -2004-07-22 Gustavo Maciel Dias Vieira <gustavo@sagui.org> - - * pt_BR.po: Updated Brazilian Portuguese translation done by - Goedson Teixeira Paixao <goedson@debian.org>. - -2004-07-21 Guntupalli Karunakar <karunakar@freedomink.org> - - * hi.po: Updated Hindi translation. - -2004-07-14 Christian Rose <menthos@menthos.com> - - * sv.po: Updated Swedish translation. - -2004-07-12 Åsmund Skjæveland <aasmunds@fys.uio.no> - - * nn.po: Updated Norwegian Nynorsk translation. - -2004-07-08 Alexander Shopov <ash@contact.bg> - - * bg.po: Updated Bulgarian translation by - Vladimir "Kaladan" Petkov <vpetkov@i-space.org> - -2004-07-07 Laszlo Dvornik <ldvornik@cvs.gnome.org> - - * hu.po: Updated Hungarian translation. - -2004-07-06 Francisco Javier F. Serrador <serrador@cvs.gnome.org> - - * es.po: Updated Spanish translation. - -2004-07-05 Laurent Dhima <laurenti@alblinux.net> - - * sq.po: Updated Albanian translation. - -2004-07-04 Vincent van Adrighem <adrighem@gnome.org> - - * nl.po: Translation updated by Tino Meinen. - -2004-07-02 Christian Neumair <chris@gnome-de.org> - - * de.po: Updated German translation. - -2004-06-29 Laurent Dhima <laurenti@alblinux.net> - - * sq.po: Translation updated. - -2004-06-28 Laurent Dhima <laurenti@alblinux.net> - - * sq.po: Translation updated. - -2004-06-25 Gareth Owen <gowen72@yahoo.com> - - * en_GB.po: Updated British English translation - -2004-06-26 Funda Wang <fundawang@linux.net.cn> - - * zh_CN.po: Updated Simplified Chinese translation. - -2004-06-25 Miloslav Trmac <mitr@volny.cz> - - * cs.po: Updated Czech translation. - -2004-05-31 Alexander Shopov <ash@contact.bg> - * bg.po: Updated Bulgarian translation by - Vladimir Petkov <vpetkov@i-space.org> - -2004-04-23 Dafydd Harries <daf@muse.19inch.net> - - * ca.po: Updated Catalan translation from Jordi Mallach. - -2004-04-16 Iñaki Larrañaga <dooteo@euskalgnu.org> - - * eu.po: Added Basque translation. - -2004-04-15 Andras Timar <timar@gnome.hu> - - * hu.po: Updated Hungarian translation. - -2004-04-09 Guntupalli Karunakar <karunakar@freedomink.org> - - * gu.po: Added Gujurati translation by - Gujarati Team <magnet@magnet-i.com>. - -2004-04-06 Mohammad DAMT <mdamt@bisnisweb.com> - - * id.po: Updated Indonesian translation - -2004-04-03 Mugurel Tudor <mugurelu@go.ro> - - * ro.po: Updated Romanian translation - -2004-03-29 Jordi Mallach <jordi@sindominio.net> - - * ca.po: Updated Catalan translation. - -2004-03-27 Tõivo Leedjärv <toivo@linux.ee> - - * et.po: Added Estonian translation. - -2004-03-24 Guntupalli Karunakar <karunakar@freedomink.org> - - * pa.po: Added Punjabi translation by - Jaswinder Singh Phulewala <jaswinderlinux@netscape.net>. - -2004-03-20 Mugurel Tudor <mugurelu@go.ro> - - * ro.po: Updated Romanian translation. - -2004-03-20 Gareth Owen <gowen72@yahoo.com> - - * en_GB.po: Updated British translation - -2004-03-19 Andras Timar <timar@gnome.hu> - - * hu.po: Updated Hungarian translation. - -2004-03-18 Arafat Medini <lumina@silverpen.de> - - * ar.po: Updated Arabic translation. - -2004-03-17 Leonid Kanter <leon@asplinux.ru> - - * ru.po: Updated Russian translation - -2004-03-16 Dafydd Harries <daf@muse.19inch.net> - - * cy.po: Updated Welsh translation. - -2004-03-15 Alessio Frusciante <algol@firenze.linux.it> - - * it.po: Updated Italian translation by - Luca Ferretti <elle.uca@infinito.it>. - -2004-03-15 Nikos Charonitakis <frolix68@yahoo.gr> - - * el.po: Updated Greek translation. - -2004-03-14 Christophe Merlet <redfox@redfoxcenter.org> - - * fr.po: Updated French translation. - -2004-03-13 Christophe Merlet <redfox@redfoxcenter.org> - - * fr.po: Updated French translation. - -2004-03-13 Theppitak Karoonboonyanan <thep@linux.thai.net> - - * th.po: Updated Thai translation. - -2004-03-12 Funda Wang <fundawang@linux.net.cn> - - * zh_CN.po: Updated Simplified Chinese translation. - -2004-03-12 Yuriy Syrota <rasta@cvs.gnome.org> - - * uk.po: Updated Ukrainian translation. - -2004-03-11 Alessio Frusciante <algol@firenze.linux.it> - - * it.po: Updated Italian translation. - -2004-03-11 Christophe Merlet <redfox@redfoxcenter.org> - - * fr.po: Updated French translation. - -2004-03-10 Theppitak Karoonboonyanan <thep@linux.thai.net> - - * th.po: Updated Thai translation. - -2004-03-09 Alessio Frusciante <algol@firenze.linux.it> - - * it.po: Updated Italian translation by - Luca Ferretti <elle.uca@infinito.it>. - -2004-03-09 Kjartan Maraas <kmaraas@gnome.org> - - * no.po: Updated Norwegian translation. - -2004-03-09 Francisco Javier F. Serrador <serrador@cvs.gnome.org> - - * es.po: Updated Spansih translation. - -2004-03-08 Alastair McKinstry <mckinstry@computer.org> - - * ga.po: Updated Irish translation. - -2004-03-08 Theppitak Karoonboonyanan <thep@linux.thai.net> - - * th.po: Updated Thai translation. - -2004-03-06 Mətin Əmirov <metin@karegen.com> - - * az.po: Translation updated. - -2004-03-07 Funda Wang <fundawang@linux.net.cn> - - * zh_CN.po: Updated Simplified Chinese translation. - -2004-03-04 Paisa Seeluangsawat <paisa@users.sf.net> - - * th.po: Added Thai translation. - -2004-03-3 Arafat Medini <lumina@silverpen.de> - - * ar.po: Updated Arabic translation. - -2004-03-02 Stanislav Visnovsky <visnovsky@kde.org> - - * sk.po: Convert to UTF-8. - -2004-02-26 Guntupalli Karunakar <karunakar@freedomink.org> - - * hi.po: Updated Hindi translations. - -2004-02-23 Laurent Dhima <laurenti@alblinux.net> - - * sq.po: Updated Albanian translation. - -2004-02-22 Christian Rose <menthos@menthos.com> - - * en_CA.po: Added Canadian English translation by - Adam Weinberger <adamw@FreeBSD.org>. - -2004-02-17 Takeshi AIHANA <aihana@gnome.gr.jp> - - * ja.po: Updated Japanese translation. - -2004-02-11 Kjartan Maraas <kmaraas@gnome.org> - - * no.po: Updated Norwegian translation. - -2004-02-07 Robert Sedak <robert.sedak@sk.htnet.hr> - - * hr.po: Updated Croatian translation. - -2004-02-08 Changwoo Ryu <cwryu@debian.org> - - * ko.po: Updated Korean translation. - -2004-02-05 Pauli Virtanen <pauli.virtanen@hut.fi> - - * fi.po: Updated Finnish translation. - -2004-02-03 Kostas Papadimas <pkst@gnome.org> - - * el.po: Updated Greek translation. - -2004-02-02 Laurent Dhima <laurenti@alblinux.net> - - * sq.po: Updated Albanian translation. - -2004-02-01 Ole Laursen <olau@hardworking.dk> - - * da.po: Updated Danish translation. - -2004-01-31 Mətin Əmirov <metin@karegen.com> - - * az.po: Translation updated. - -2004-01-28 Miloslav Trmac <mitr@volny.cz> - - * cs.po: Fixed Czech translation. - -2004-01-20 Artur Flinta <aflinta@cvs.gnome.org> - - * pl.po: Updated Polish translation by GNOME PL Team. - -2004-01-18 Christian Neumair <chris@gnome-de.org> - - * de.po: Updated German translation. - -2004-01-16 Hasbullah Bin Pit <sebol@ikhlas.com> - - * ms.po: Updated Malay translation. - -2004-01-15 Laurent Dhima <laurenti@alblinux.net> - - * sq.po: Updated Albanian translation. - -2004-01-13 Kjartan Maraas <kmaraas@gnome.org> - - * no.po: Updated Norwegian translation. - -2004-01-13 Artur Flinta <aflinta@cvs.gnome.org> - - * pl.po: Updated Polish translation by GNOME PL Team. - -2004-01-12 Žygimantas Beručka <uid0@tuxfamily.org> - - * lt.po: Updated Lithuanian translation by Tomas Kuliavas. - -2004-01-11 Christophe Merlet <redfox@redfoxcenter.org> - - * fr.po: Updated French translation. - -2004-01-11 Changwoo Ryu <cwryu@debian.org> - - * ko.po: Updated Korean translation. - -2004-01-05 Vincent van Adrighem <adrighem@gnome.org> - - * nl.po: Translation updated by Tino Meinen. - -2004-01-04 Duarte Loreto <happyguy_pt@hotmail.com> - - * pt.po: Updated and revised Portuguese translation. - -2004-01-03 Sanlig Badral <badral@openmn.org> - - * mn.po: Updated Mongolian translation. - -2004-01-03 Robert Sedak <robert.sedak@sk.htnet.hr> - - * hr.po: Updated Croatian translation. - -2004-01-02 Sanlig Badral <Badral@openmn.org> - - * mn.po: Updated Mongolian translation. - -2004-01-02 Taneem Ahmed <taneem@bengalinux.org> - - * bn.po: Updated Bangla (Bengali) translation. - -2003-12-29 Christian Neumair <chris@gnome-de.org> - - * de.po: Updated German translation. - -2003-12-29 Åsmund Skjæveland <aasmunds@fys.uio.no> - - * nn.po: Updated Norwegian Nynorsk translation. - -2003-12-24 Francisco Javier F. Serrador <serrador@cvs.gnome.org> - - * es.po: Updated Spanish translation. - -2003-12-23 Gustavo Noronha Silva <kov@debian.org> - - * pt_BR.po: updated translation. - -2003-12-22 Miloslav Trmac <mitr@volny.cz> - - * cs.po: Updated Czech translation. - -2003-12-22 Danilo Šegan <dsegan@gmx.net> - - * sr.po, sr@Latn.po: Updated Serbian translation. - -2003-12-22 Christian Rose <menthos@menthos.com> - - * sv.po: Updated Swedish translation. - -2003-12-21 Francisco Javier F. Serrador <serrador@cvs.gnome.org> - - * es.po: Updated Spanish translation. - -2003-12-21 Danilo Šegan <dsegan@gmx.net> - - * sr.po, sr@Latn.po: Updated Serbian translation. - -2003-12-20 Arafat Medini <lumina@silverpen.de> - - * ar.po: Added Arabic translation. - -2003-12-19 Gustavo Noronha Silva <kov@debian.org> - - * pt_BR.po: updated translation. - -2003-12-18 Yukihiro Nakai <nakai@gnome.gr.jp> - - * ja.po: Minor update. - -2003-12-14 Francisco Javier F. Serrador <serrador@cvs.gnome.org> - - * es.po: Updated Spanish translation - -2003-12-04 Danilo Šegan <dsegan@gmx.net> - - * sr.po, sr@Latn.po: Cleared up Serbian translation. - -2003-12-03 Sanlig Badral <badral@openmn.org> - - * mn.po: Updated Mongolian translation. - -2003-12-02 Miloslav Trmac <mitr@volny.cz> - - * cs.po: Updated Czech translation. - -2003-11-29 Ole Laursen <olau@hardworking.dk> - - * da.po: Updated Danish translation. - -2003-11-26 Vincent van Adrighem <adrighem@gnome.org> - - * nl.po: Dutch translation updated by Vincent van Adrighem. - -2003-11-10 Pablo Gonzalo del Campo <pablodc@bigfoot.com> - - * es.po: Updated Spanish translation by - Francisco Javier F. Serrador <serrador@arrakis.es>. - -2003-11-08 Danilo Šegan <dsegan@gmx.net> - - * sr.po, sr@Latn.po: Updated Serbian translation. - -2003-10-30 Kostas Papadimas <pkst@gnome.org> - - * el.po: Updated Greek translation. - -2003-10-20 Andras Timar <timar@gnome.hu> - - * hu.po: Updated Hungarian translation. - -2003-10-15 Danilo Šegan <dsegan@gmx.net> - - * sr.po, sr@Latn.po: Updated Serbian translation. - -2003-10-15 Yukihiro Nakai <nakai@gnome.gr.jp> - - * ja.pp: Update Japanese translation. - -2003-10-13 Danilo Šegan <dsegan@gmx.net> - - * sr.po, sr@Latn.po: Updated Serbian translation. - -2003-10-08 Andras Timar <timar@gnome.hu> - - * hu.po: Updated Hungarian translation. - -2003-10-06 Žygimantas Beručka <uid0@tuxfamily.org> - - * lt.po: Added Lithuanian translation by Tomas Kuliavas - <tokul@users.sourceforge.net>. - -2003-10-06 Mugurel Tudor <mugurelu@go.ro> - - * ro.po: Updated Romanian translation - -2003-09-30 Kjartan Maraas <kmaraas@gnome.org> - - * no.po: Update Norwegian translation. - -2003-09-30 Christian Neumair <chris@gnome-de.org> - - * de.po: Updated German translation. - -2003-09-27 Metin Amiroff <metin@karegen.com> - - * az.po: Updated Azerbaijani translation. - -2003-09-27 Åsmund Skjæveland <aasmunds@fys.uio.no> - - * nn.po: Updated Norwegian (nynorsk) translation. - -2003-09-24 Stanislav Visnovsky <visnovsky@nenya.ms.mff.cuni.cz> - - * sk.po: Updated Slovak translation. - -2003-09-22 Taneem Ahmed <taneem@bengalinux.org> - - * bn.po: Added Bangla translation by Dr Anirban Mitra - of Ankur group <gnome-translation@bengalinux.org>. - -2003-09-23 Changwoo Ryu <cwryu@debian.org> - - * ko.po: Updated Korean translation. - -2003-09-21 Metin Amiroff <metin@karegen.com> - - * az.po: Updated Azerbaijani file - -2003-09-21 Åsmund Skjæveland <aasmunds@fys.uio.no> - - * nn.po: Updated Norwegian (Nynorsk) translation. - -2003-09-21 Åsmund Skjaeveland <aasmunds@fys.uio.no> - - * nn.po: Updated Norwegian (nynorsk) translation. - -2003-09-20 Åsmund Skjæveland <aasmunds@fys.uio.no> - - * nn.po: Started Norwegian (nynorsk) translation. - -2003-09-17 Fatih Demir <kabalak@gtranslator.org> - - * ta.po: Committed new Tamil translation by Dinesh. - -2003-09-09 Guntupalli Karunakar <karunakar@freedomink.org> - - * hi.po: Updated Hindi translation by - Ravishankar Shrivastava <raviratlami@yahoo.com>. - -2003-09-08 Pablo Saratxaga <pablo@mandrakesoft.com> - - * vi.po: Updated Vietnamese file - * az.po,sq.po: Fixed syntax errors - -2003-09-07 Nikos Charonitakis <frolix68@yahoo.gr> - - * el.po: Review of Greek translation. - -2003-09-06 Takeshi AIHANA <aihana@gnome.gr.jp> - - * ja.po: Fixed mistranslations for Japanese. - -2003-09-05 Kjartan Maraas <kmaraas@gnome.org> - - * no.po: Updated Norwegian translation. - -2003-09-04 Laurent Dhima <laurenti@alblinux.net> - - * sq.po: Updated Albanian translation. - -2003-09-03 Guntupalli Karunakar <karunakar@freedomink.org> - - * hi.po: Updated Hindi translations. - -2003-09-03 Mugurel Tudor <mugurelu@go.ro> - - * ro.po: Updated Romanian translation - -2003-09-01 Stanislav Visnovsky <visnovsky@nenya.ms.mff.cuni.cz> - - * sk.po: Updated Slovak translation. - -2003-08-29 Dafydd Harries <daf@parnassus.ath.cx> - - * cy.po: Updated Welsh translation. - -2003-08-27 Pablo Gonzalo del Campo <pablodc@bigfoot.com> - - * es.po: Revision of Spanish translation by - Francisco Javier F. Serrador <serrador@arrakis.es>. - -2003-08-26 Guntupalli Karunakar <karunakar@freedomink.org> - - * hi.po: Added Hindi translation. - -2003-08-25 Duarte Loreto <happyguy_pt@hotmail.com> - - * pt.po: Fixed missing accel in Portuguese translation. - -2003-08-26 Changwoo Ryu <cwryu@debian.org> - - * ko.po: Updated Korean translation by - Young-Ho Cha <ganadist at mizi.com>. - -2003-08-24 Changwoo Ryu <cwryu@debian.org> - - * ko.po: Updated Korean translation. - -2003-08-22 Stanislav Visnovsky <visnovsky@nenya.ms.mff.cuni.cz> - - * sk.po: Update Slovak translation. - -2003-08-20 Kjartan Maraas <kmaraas@gnome.org> - - * no.po: Update Norwegian translation. - -2003-08-19 Dafydd Harries <daf@parnassus.ath.cx> - - * cy.po: Updated Welsh translation. - -2003-08-18 Danilo Å egan <dsegan@gmx.net> - - * be.po: Updated Belarusian translation by Ales Nyakhaychyk - <nab@mail.by>. - -2003-08-18 Metin Amiroff <metin@karegen.com> - - * az.po: Updated Azerbaijani translation. - -2003-08-16 Pauli Virtanen <pauli.virtanen@hut.fi> - - * fi.po: Updated Finnish translation. - -2003-08-13 Laurent Dhima <laurenti@alblinux.net> - - * sq.po: Added Albanian file. - -2003-08-12 Dafydd Harries <daf@parnassus.ath.cx> - - * cy.po: Updated Welsh translation. - -2003-08-09 Wang Jian <lark@linux.net.cn> - - * zh_CN.po: Updated Simplified Chinese translation by - Funda Wang <fundawang@linux.net.cn>. - -2003-08-09 Christophe Merlet <redfox@redfoxcenter.org> - - * fr.po: Updated French translation. - -2003-08-08 Danilo Å egan <dsegan@gmx.net> - - * sr.po, sr@Latn.po: Updated Serbian translation. - -2003-08-07 Hasbullah Bin Pit <sebol@ikhlas.com> - - * ms.po: Updated Malay translation. - -2003-08-06 Metin Amiroff <metin@karegen.com> - - * az.po: Updated Azerbaijani translation. - -2003-08-05 Ole Laursen <olau@hardworking.dk> - - * da.po: Updated Danish translation. - -2003-08-05 Pablo Gonzalo del Campo <pablodc@bigfoot.com> - - * es.po: Updated Spanish translation. - -2003-07-29 Andras Timar <timar@gnome.hu> - - * hu.po: Updated Hungarian translation. - -2003-07-25 Dafydd Harries <daf@parnassus.ath.cx> - - * cy.po: Updated Welsh translation. - -2003-07-24 Pablo Saratxaga <pablo@mandrakesoft.com> - - * vi.po: Updated Vietnamese file - * is.po: fixed syntax error - -2003-07-20 Evandro Fernandes Giovanini <evandrofg@ig.com.br> - - * pt_BR.po: Updated Brazilian Portuguese translation. - -2003-07-20 Takeshi AIHANA <aihana@gnome.gr.jp> - - * ja.po: Updated Japanese translation. - -2003-07-18 Duarte Loreto <happyguy_pt@hotmail.com> - - * pt.po: Updated Portuguese translation. - -2002-07-17 Kostas Papadimas <pkst@gmx.net> - - * el.po: Updated Greek translation. - -2003-07-17 Vincent van Adrighem <V.vanAdrighem@dirck.mine.nu> - - * nl.po: Dutch translation updated by Tino Meinen. - -2003-07-12 Christian Neumair <chris@gnome-de.org> - - * de.po: Updated German translation. - -2003-07-12 Pablo Saratxaga <pablo@mandrakesoft.com> - - * wa.po: Added Walloon file - -2003-07-12 Alessio Frusciante <algol@firenze.linux.it> - - * it.po: Updated Italian translation. - -2003-07-07 Vincent van Adrighem <V.vanAdrighem@dirck.mine.nu> - - * nl.po: Dutch translation updated by Kees van den Broek. - -2003-07-07 Abel Cheung <maddog@linux.org.hk> - - * zh_TW.po: Updated traditional Chinese translation. - -2003-07-06 Evandro Fernandes Giovanini <evandrofg@ig.com.br> - - * pt_BR.po: Updated Brazilian Portuguese translation. - -2003-07-02 Artur Flinta <aflinta@cvs.gnome.org> - - * pl.po: Updated Polish translation. - -2003-06-28 Jordi Mallach <jordi@sindominio.net> - - * ca.po: Updated Catalan translation. - -2003-06-28 Miloslav Trmac <mitr@volny.cz> - - * cs.po: Updated Czech translation. - -2003-06-28 Christian Rose <menthos@menthos.com> - - * sv.po: Updated Swedish translation. - -2003-06-27 Mohammad DAMT <mdamt@bisnisweb.com> - - * id.po: Updated Indonesian translation - -2003-06-26 Ole Laursen <olau@hardworking.dk> - - * da.po: Updated Danish translation. - -2003-06-26 Mohammad DAMT <mdamt@bisnisweb.com> - - * id.po: Added Indonesian translation - -2003-06-23 Vincent van Adrighem <V.vanAdrighem@dirck.mine.nu> - - * nl.po: Dutch translation updated by Kees van den Broek. - -2003-06-22 Samúel Jón Gunnarsson <sammi@techattack.nu> - - * is.po: Added Icelandic translation - -2003-06-21 Christophe Merlet <redfox@redfoxcenter.org> - - * fr.po: Updated French translation. - -2003-06-17 Pauli Virtanen <pauli.virtanen@hut.fi> - - * fi.po: Updated Finnish translation. - -2003-06-12 Pablo Gonzalo del Campo <pablodc@bigfoot.com> - - * es.po: Updated Spanish translation. - -2003-06-08 Christophe Merlet <redfox@redfoxcenter.org> - - * fr.po: Updated French translation. - -2003-06-07 Christian Neumair <chris@gnome-de.org> - - * de.po: Updated German translation. - -2003-06-06 Jordi Mallach <jordi@sindominio.net> - - * ca.po: Updated Catalan translation. - -2003-06-04 Dmitry G. Mastrukov <dmitry@taurussoft.org> - - * be.po: Updated Belarusian translation - from Belarusian team <i18n@mova.org>. - -2003-06-04 Dmitry G. Mastrukov <dmitry@taurussoft.org> - - * ru.po: Updated Russian translation - from Russian team <gnome-cyr@gnome.org>. - - -2003-05-31 Dafydd Harries <daf@parnassus.ath.cx> - - * cy.po: Updated Welsh translation. - -2003-05-30 Paul Duffy <dubhthach@frink.nuigalway.ie> - - * ga.po: Updated Irish Translation. - -2003-05-30 Abel Cheung <maddog@linux.org.hk> - - * zh_TW.po: Updated traditional Chinese translation. - -2003-05-26 Duarte Loreto <happyguy_pt@hotmail.com> - - * pt.po: Updated Portuguese translation. - -2003-05-21 Miloslav Trmac <mitr@volny.cz> - - * cs.po: Updated Czech translation. - -2003-05-20 Christian Rose <menthos@menthos.com> - - * sv.po: Updated Swedish translation. - -2003-05-19 Telsa Gwymme <hobbit@aloss.ukuu.org.uk> - - * cy.po: Updated Welsh translation from - Dafydd Harries <daf@parnassus.ath.cx> - -2003-05-19 Christophe Merlet <redfox@redfoxcenter.org> - - * fr.po: Updated French translation. - -2003-05-16 Telsa Gwynne <hobbit@aloss.ukuu.org.uk> - - * cy.po: Added Welsh translation from - Dafydd Harries <daf@parnassus.ath.cx> - -2003-05-16 Pablo Gonzalo del Campo <pablodc@bigfoot.com> - - * es.po: Updated Spanish translation. - -2003-05-12 Duarte Loreto <happyguy_pt@hotmail.com> - - * pt.po: Updated Portuguese translation. - -2003-05-10 KAMAGASAKO Masatoshi <emerald@gnome.gr.jp> - - * ja.po: Updated Japanese translation. - -2003-05-10 Jordi Mallach <jordi@sindominio.net> - - * ca.po: Updated Catalan translation. - -2003-05-09 Evandro Fernandes Giovanini <evandrofg@ig.com.br> - - * pt_BR.po: Updated Brazilian Portuguese translation. - -2003-05-08 Christian Rose <menthos@menthos.com> - - * sv.po: Updated Swedish translation. - -2003-05-08 Changwoo Ryu <cwryu@debian.org> - - * ko.po: Updated Korean translation. - -2003-05-06 Danilo Å egan <dsegan@gmx.net> - - * sr.po, sr@Latn.po: Added Serbian translation by - http://Prevod.org/. - -2003-04-29 Miloslav Trmac <mitr@volny.cz> - - * cs.po: Updated Czech translation. - -2003-04-15 Dmitry G. Mastrukov <dmitry@taurussoft.org> - - * ru.po: updated Russian translation - from Russian team <gnome-cyr@gnome.org>. - -2003-04-03 Christophe Merlet <redfox@redfoxcenter.org> - - * fr.po: Updated French translation. - -2003-03-27 Christophe Merlet <redfox@redfoxcenter.org> - - * fr.po: Updated French translation. - -2003-03-13 Christian Rose <menthos@menthos.com> - - * ml.po: Added Malayalam translation by - FSF-India <locale@gnu.org.in>. - -2003-03-11 Paul Duffy <dubhthach@zion.nuigalway.ie> - - * ga.po: Added Irish translation - -2003-03-10 Roozbeh Pournader <roozbeh@sharif.edu> - - * fa.po: Added Persian translation. - -2003-02-26 Dmitry G. Mastrukov <dmitry@taurussoft.org> - - * be.po: Added Belarusian translation - from Belarusian team <i18n@infonet.by>. - -2003-02-25 Pablo Gonzalo del Campo <pablodc@bigfoot.com> - - * es.po: Fixed a translation string to match with libwnck. - -2003-02-22 Rob Adams <robadams@ucla.edu> - - * *.po: change toggle_maximized to toggle_maximize and - toggle_shaded to toggle_shade in action_double_click_titlebar long - description to match the values used by metacity - -2003-02-12 Christian Rose <menthos@menthos.com> - - * sv.po: Some fixes for problems catched in translation review. - -2003-02-11 Fatih Demir <kabalak@gtranslator.org> - - * tr.po: Branchy. - -2003-02-09 Fatih Demir <kabalak@gtranslator.org> - - * tr.po: Take over from branch... - -2003-02-08 Fatih Demir <kabalak@gtranslator.org> - - * tr.po: Committed updated Turkish translation by Sinan. - -2003-02-05 Abel Cheung <maddog@linux.org.hk> - - * en_GB.po: Fix header. - * ko.po, pt_BR.po: Fix positional parameters. - -2003-02-05 Abel Cheung <maddog@linux.org.hk> - - * zh_TW.po: Updated traditional Chinese translation. - -2003-02-03 Daniel Yacob <locales@geez.org> - - * am.po: Updated Amharic translation. - -2003-01-30 Marius Andreiana <marius galuna.ro> - - * ro.po: updated ( thanks to Mugurel Tudor ) - -2003-01-25 Christophe Merlet <redfox@redfoxcenter.org> - - * fr.po: Updated French translation from - Guy Clotilde <guy.clotilde@wanadoo.fr>. - -2003-01-25 Kjartan Maraas <kmaraas@gnome.org> - - * no.po: Updated Norwegian (bokmal) translation. - -2003-01-23 He Qiangqiang <carton@linux.net.cn> - - * zh_CN.po: Updated Simplified Chinese translation by - Xiong Jiang <jxiong@offtopic.org>. - -2003-01-23 Dmitry G. Mastrukov <dmitry@taurussoft.org> - - * ru.po: updated Russian translation - from Russian team <gnome-cyr@gnome.org>. - -2003-01-23 Abel Cheung <maddog@linux.org.hk> - - * zh_TW.po: Updated traditional Chinese translation. - -2003-01-22 Christian Rose <menthos@menthos.com> - - * mn.po: Added Mongolian translation by - Ochirbat Batzaya <buuvei@yahoo.com>. - -2003-01-21 Dmitry G. Mastrukov <dmitry@taurussoft.org> - - * ru.po: updated Russian translation - from Russian team <gnome-cyr@gnome.org>. - -2003-01-21 Kjartan Maraas <kmaraas@gnome.org> - - * no.po: Updated Norwegian (bokmal) translation. - -2003-01-20 Christian Neumair <chris@gnome-de.org> - - * de.po: Updated German translation. - -2003-01-20 Dmitry G. Mastrukov <dmitry@taurussoft.org> - - * ru.po: updated Russian translation - from Russian team <gnome-cyr@gnome.org>. - -2003-01-20 Dmitry G. Mastrukov <dmitry@taurussoft.org> - - * ru.po: updated Russian translation - from Russian team <gnome-cyr@gnome.org>. - -2003-01-20 Dmitry G. Mastrukov <dmitry@taurussoft.org> - - * ru.po: updated Russian translation - from Russian team <gnome-cyr@gnome.org>. - -2003-01-19 Abel Cheung <maddog@linux.org.hk> - - * zh_TW.po: Updated traditional Chinese translation, and replaced - copyright symbol with correct one. - -2003-01-17 Gustavo Noronha Silva <kov@debian.org> - - * pt_BR.po: translation update - -2003-01-16 Vincent van Adrighem <V.vanAdrighem@dirck.mine.nu> - - * nl.po: Dutch translation updated by Tino Meinen. - -2003-01-16 Vincent van Adrighem <V.vanAdrighem@dirck.mine.nu> - - * nl.po: Dutch translation updated by Tino Meinen. - -2003-01-14 Yanko Kaneti <yaneti@declera.com> - - * bg.po: Full Bulgarian translation by - Alexander Shopov <al_shopov@yahoo.com>. - -2003-01-11 Kjartan Maraas <kmaraas@gnome.org> - - * no.po: Updated Norwegian (bokmal) translation. - -2003-01-10 Vincent van Adrighem <V.vanAdrighem@dirck.mine.nu> - - * nl.po: Dutch translation updated by Tino Meinen. - -2003-01-10 Andras Timar <timar@gnome.hu> - - * hu.po: Updated Hungarian translation. - -2003-01-10 Yukihiro Nakai <nakai@gnome.gr.jp> - - * ja.po: Minor fix. - -2003-01-09 Vincent van Adrighem <V.vanAdrighem@dirck.mine.nu> - - * nl.po: Dutch translation updated by Tino Meinen. - -2003-01-08 Pauli Virtanen <pauli.virtanen@hut.fi> - - * fi.po: Fixed a string that had an invalid printf format. - -2003-01-09 Abel Cheung <maddog@linux.org.hk> - - * zh_TW.po: Updated traditional Chinese translation. - -2003-01-07 Daniel Yacob <locales@geez.org> - - * am.po: Updated Amharic translation. - -2003-01-06 Vincent van Adrighem <V.vanAdrighem@dirck.mine.nu> - - * nl.po: Dutch translation added by Tino Meinen. - -2003-01-05 Pablo Saratxaga <pablo@mandrakesoft.com> - - * vi.po: Updated Vietnamese file - * pt_BR.po: fixed syntax errors - -2003-01-05 Pauli Virtanen <pauli.virtanen@hut.fi> - - * fi.po: Added Finnish translation. - -2003-01-05 Stanislav Visnovsky <visnovsky@nenya.ms.mff.cuni.cz> - - * sk.po: Updated Slovak translation. - -2003-01-03 Kjartan Maraas <kmaraas@gnome.org> - - * no.po: Updated Norwegian (bokmal) translation. - -2003-01-02 Zbigniew Chyla <cyba@gnome.pl> - - * pl.po: Updated Polish translation by - GNOME PL Team <translators@gnome.pl>. - -2002-12-29 Daniel Yacob <locales@geez.org> - - * am.po: Updated Amharic translation. - -2002-12-29 Kostas Papadimas <pkst@gmx.net> - - * el.po: Updated Greek translation. - -2002-12-25 Ole Laursen <olau@hardworking.dk> - - * da.po: Updated Danish translation. - -2002-12-25 Kostas Papadimas <pkst@gmx.net> - - * el.po: Updated Greek translation. - -2002-12-22 Daniel Yacob <locales@geez.org> - - * am.po: Updated Amharic translation. - -2002-12-22 Artis Trops <hornet@navigator.lv> - - * lv.po: Updated Latvian translation. - -2002-12-21 Daniel Yacob <locales@geez.org> - - * am.po: Updated Amharic translation. - -2002-12-20 Christian Neumair <chris@gnome-de.org> - - * de.po: Updated German translation. - -2002-12-20 Miloslav Trmac <mitr@volny.cz> - - * cs.po: Updated Czech translation. - -2002-12-19 Hasbullah Bin Pit <sebol@ikhlas.com> - - * ms.po: Updated Malay Translation. - -2002-12-19 Yanko Kaneti <yaneti@declera.com> - - * bg.po (added): Added start of Bulgarian translation by - Alexander Shopov <al_shopov@yahoo.com>. - -2002-12-18 Pablo Gonzalo del Campo <pablodc@bigfoot.com> - - * es.po: Updated Spanish translation. - -2002-12-17 Miloslav Trmac <mitr@volny.cz> - - * cs.po: Updated Czech translation. - -2002-12-17 Christian Rose <menthos@menthos.com> - - * sv.po: Updated Swedish translation. - -2002-12-17 Christian Rose <menthos@menthos.com> - - * sv.po: Updated Swedish translation. - -2002-12-16 Christian Neumair <chris@gnome-de.org> - - * de.po: Updated German translation. - -2002-12-16 Miloslav Trmac <mitr@volny.cz> - - * cs.po: Updated Czech translation. - -2002-12-16 Ole Laursen <olau@hardworking.dk> - - * da.po: Updated Danish translation. - -2002-12-14 Kjartan Maraas <kmaraas@gnome.org> - - * no.po: Updated Norwegian (bokmÃ¥l) translation. - -2002-12-13 Daniel Yacob <locales@geez.org> - - * am.po: Added Amharic translation. - -2002-12-13 Christian Rose <menthos@menthos.com> - - * sv.po: Updated Swedish translation. - -2002-12-12 Ole Laursen <olau@hardworking.dk> - - * da.po: Updated Danish translation. - -2002-12-11 Christian Neumair <chris@gnome-de.org> - - * POTFILES.in: Added src/tools/metacity-message.c. - * de.po: Updated German translation. - -2002-12-11 Evandro Fernandes Giovanini <evandrofg@ig.com.br> - - * pt_BR.po: Updated Brazilian Portuguese translation. - -2002-12-09 Pablo Gonzalo del Campo <pablodc@bigfoot.com> - - * es.po: Updated Spanish translation. - -2002-12-09 Miloslav Trmac <mitr@volny.cz> - - * cs.po: Updated Czech translation. - -2002-12-04 Pablo Gonzalo del Campo <pablodc@bigfoot.com> - - * es.po: Updated Spanish translation. - -2002-11-25 Kjartan Maraas <kmaraas@gnome.org> - - * no.po: Updated Norwegian (bokmÃ¥l) translation. - -2002-11-25 Yanko Kaneti <yaneti@declera.com> - - * *.po: Convert all to UTF-8. - -2002-11-24 Kostas Papadimas <pkst@gmx.net> - - * el.po: Updated Greek translation. - -2002-11-23 Kostas Papadimas <pkst@gmx.net> - - * el.po: Updated Greek translation. - -2002-11-19 Andras Timar <timar@gnome.hu> - - * hu.po: Updated Hungarian translation. - -2002-11-15 Kjartan Maraas <kmaraas@gnome.org> - - * no.po: Updated Norwegian (bokmÃ¥l) translation. - -2002-11-14 Gustavo Noronha Silva <kov@debian.org> - - * pt_BR.po: Update translation. - -2002-11-14 Pablo Gonzalo del Campo <pablodc@bigfoot.com> - - * es.po: Updated Spanish translation. - -2002-11-13 Christian Neumair <chris@gnome-de.org> - - * de.po: Updated German translation. - -2002-11-11 Peteris Krisjanis <peteris.krisjanis@os.lv> - - * lv.po: Updated Latvian translation. - -2002-11-11 Changwoo Ryu <cwryu@debian.org> - - * ko.po: Updated Korean translation by Young-Ho Cha - <ganadist@chollian.net>. - -2002-11-10 Ole Laursen <olau@hardworking.dk> - - * da.po: Updated Danish translation. - -2002-11-05 Hasbullah Bin Pit <sebol@ikhlas.com> - - * ms.po: Updated Malay Translation. - -2002-11-05 Christian Rose <menthos@menthos.com> - - * POTFILES.in: Added missing file. - * sv.po: Updated Swedish translation. - -2002-11-01 Christian Neumair <chris@gnome-de.org> - - * de.po: Updated German translation. - -2002-10-31 Pablo Gonzalo del Campo <pablodc@bigfoot.com> - - * es.po: Updated Spanish translation. - -2002-10-28 Ole Laursen <olau@hardworking.dk> - - * da.po: Updated Danish translation. - -2002-10-28 Peteris Krisjanis <peteris.krisjanis@os.lv> - - * lv.po: Updated Latvian translation. - -2002-10-24 Christian Rose <menthos@menthos.com> - - * POTFILES.in: Added missing file. - * sv.po: Updated Swedish translation. - -2002-10-24 Pablo Saratxaga <pablo@mandrakesoft.com> - - * vi.po: Updated Vietnamese file - -2002-10-22 Ole Laursen <olau@hardworking.dk> - - * da.po: Updated Danish translation. - -2002-10-21 Kjartan Maraas <kmaraas@gnome.org> - - * no.po: Updated Norwegian (bokmÃ¥l) translation. - -2002-10-17 Andras Timar <timar@gnome.hu> - - * hu.po: Added Hungarian translation. - -2002-10-17 Christophe Merlet <christophe@merlet.net> - - * fr.po: Updated French translation. - -2002-10-16 Christian Neumair <chris@gnome-de.org> - - * de.po: Updated German translation. - -2002-10-16 Yukihiro Nakai <ynakai@redhat.com> - - * ja.po: Minor fix - -2002-10-16 Bastien Nocera <hadess@hadess.net> - - * en_GB.po: added, more colours for your theme, time to upgrade! - -2002-10-15 Kjartan Maraas <kmaraas@gnome.org> - - * no.po: Updated Norwegian (bokmÃ¥l) translation. - -2002-10-15 Ole Laursen <olau@hardworking.dk> - - * da.po: Updated Danish translation. - -2002-10-13 Hasbullah Bin Pit <sebol@ikhlas.com> - - * ms.po: Updated Malay Translation. - -2002-10-11 Stanislav Brabec <sbrabec@suse.cz> - - * cs.po: Updated Czech translation from Miloslav Trmac - <mitr@volny.cz>. - -2002-10-10 Zbigniew Chyla <cyba@gnome.pl> - - * pl.po: Updated Polish translation by - GNOME PL Team <translators@gnome.pl>. - -2002-10-06 Zbigniew Chyla <cyba@gnome.pl> - - * pl.po: Updated Polish translation by - GNOME PL Team <translators@gnome.pl>. - -2002-10-01 Stanislav Brabec <sbrabec@suse.cz> - - * cs.po: Added Czech translation from Miloslav Trmac - <mitr@volny.cz>. - -2002-09-28 Ole Laursen <olau@hardworking.dk> - - * da.po: Updated Danish translation. - -2002-09-26 Christian Neumair <chris@gnome-de.org> - - * de.po: Updated German translation. - -2002-09-25 Christophe Merlet <christophe@merlet.net> - - * fr.po: Updated French translation. - -2002-09-25 Christian Meyer <chrisime@gnome.org> - - * de.po: Updated German translation. - -2002-09-24 Christian Rose <menthos@menthos.com> - - * sv.po: Updated Swedish translation. - -2002-09-23 Christian Rose <menthos@menthos.com> - - * sv.po: Updated Swedish translation. - -2002-09-20 Christian Neumair <chris@gnome-de.org> - - * de.po: Updated German translation. - -2002-09-20 Pablo Saratxaga <pablo@mandrakesoft.com> - - * vi.po: Updated Vietnamese file - -2002-09-11 Kjartan Maraas <kmaraas@gnome.org> - - * no.po: Updated Norwegian (bokmÃ¥l) translation. - -2002-09-10 Pablo Gonzalo del Campo <pablodc@bigfoot.com> - - * es.po: Updated Spanish translation. - -2002-09-11 Duncan Mak <duncan@ximian.com> - - * ro.po: Remove diff conflicts. - -2002-09-06 Frederic Crozat <fcrozat@mandrakesoft.com> - - * fr.po: Updated French translation. - -2002-09-05 Ole Laursen <olau@hardworking.dk> - - * da.po: Updated Danish translation. - -2002-09-05 Christian Neumair <chris@gnome-de.org> - - * de.po: Updated German translation. - -2002-09-05 Akira TAGOH <tagoh@gnome.gr.jp> - - * ja.po: Updated Japanese translation. - -2002-09-04 Marius Andreiana <mandreiana@yahoo.com> - - * ro.po: added ( thanks to Mugurel Tudor <mugurelu@go.ro> ) - -2002-08-30 Pablo Gonzalo del Campo <pablodc@bigfoot.com> - - * es.po: Updated Spanish translation. - -2002-08-28 Hasbullah Bin Pit <sebol@ikhlas.com> - - * ms.po: Updated Malay Translation. - -2002-08-27 Christian Neumair <christian-neumair@web.de> - - * de.po: Updated German translation. - -2002-08-26 Ole Laursen <olau@hardworking.dk> - - * da.po: Updated Danish translation. - -2002-08-26 Dmitry G. Mastrukov <dmitry@taurussoft.org> - - * ru.po: updated Russian translation. - -2002-08-26 Christian Rose <menthos@menthos.com> - - * sv.po: Updated Swedish translation. - -2002-08-24 Pablo Gonzalo del Campo <pablodc@bigfoot.com> - - * es.po: Updated Spanish translation. - -2002-08-23 Pablo Gonzalo del Campo <pablodc@bigfoot.com> - - * es.po: Updated Spanish translation. - -2002-08-23 Christian Rose <menthos@menthos.com> - - * sv.po: Updated Swedish translation. - -2002-08-22 Zbigniew Chyla <cyba@gnome.pl> - - * pl.po: Updated Polish translation by - GNOME PL Team <translators@gnome.pl>. - -2002-08-21 Pablo Gonzalo del Campo <pablodc@bigfoot.com> - - * es.po: Updated Spanish translation. - -2002-08-21 Anders Carlsson <andersca@gnu.org> - - * lv.po: Fix build. - -2002-08-21 Peteris Krisjanis <peteris.krisjanis@os.lv> - - * lv.po: Updated Latvian translation. - -2002-08-21 Akira TAGOH <tagoh@gnome.gr.jp> - - * ja.po: Updated Japanese translation. - -2002-08-19 Ole Laursen <olau@hardworking.dk> - - * da.po: Updated Danish translation. - -2002-08-19 Christian Rose <menthos@menthos.com> - - * sv.po: Fixed a bug. Thanks to rhult for reporting it. - -2002-08-19 Christian Rose <menthos@menthos.com> - - * sv.po: Updated Swedish translation. - -2002-08-18 Hasbullah Bin Pit <sebol@ikhlas.com> - - * ms.po: Updated Malay Translation. - -2002-08-18 Christian Neumair <christian-neumair@web.de> - - * de.po: Updated German translation. - -2002-08-18 Christian Neumair <christian-neumair@web.de> - - * de.po: Updated German translation. - -2002-08-17 Simos Xenitellis <simos@hellug.gr> - - * el.po: Added initial Greek translation. - -2002-08-17 Evandro Fernandes Giovanini <evandrofg@ig.com.br> - - * pt_BR.po: Added Brazilian Portuguese translation. - -2002-08-17 Changwoo Ryu <cwryu@debian.org> - - * ko.po: Updated Korean translation by Young-Ho Cha - <ganadist@chollian.net>. - -2002-08-16 Zbigniew Chyla <cyba@gnome.pl> - - * pl.po: Updated Polish translation by - GNOME PL Team <translators@gnome.pl>. - -2002-08-16 Dmitry G. Mastrukov <dmitry@taurussoft.org> - - * ru.po: updated Russian translation. - -2002-08-13 Ole Laursen <olau@hardworking.dk> - - * da.po: Updated Danish translation. - -2002-08-12 Christian Rose <menthos@menthos.com> - - * sv.po: Updated Swedish translation. - -2002-08-12 Stanislav Visnovsky <visnovsky@nenya.ms.mff.cuni.cz> - - * sk.po: Updated Slovak translation. - -2002-08-11 Dmitry G. Mastrukov <dmitry@taurussoft.org> - - * ru.po: updated Russian translation. - -2002-08-10 He Qiangqiang <carton@linux.net.cn> - - * zh_CN.po: Fixed c-format specifiers position error. - -2002-08-08 Akira TAGOH <tagoh@gnome.gr.jp> - - * ja.po: Updated Japanese translation. - -2002-08-07 Pablo Gonzalo del Campo <pablodc@bigfoot.com> - - * es.po: Updated Spanish translation. - -2002-08-06 Manuel Borchers <webmaster@matronix.de> - - * de.po: Update German translation by - Christian Neumair <christian-neumair@web.de> - -2002-08-05 He Qiangqiang <carton@linux.net.cn> - - * zh_CN.po: Added simplified Chinese translation from - Sun G11n <gnome_int_l10n@ireland.sun.com>. - -2002-08-05 Christian Rose <menthos@menthos.com> - - * sv.po: Fixed Swedish translation. - -2002-08-04 Kjartan Maraas <kmaraas@gnome.org> - - * no.po: Updated Norwegian (bokmÃ¥l) translation. - -2002-07-30 Pablo Saratxaga <pablo@mandrakesoft.com> - - * vi.po: Updated Vietnamese file - -2002-07-28 Christophe Merlet <christophe@merlet.net> - - * fr.po: Updated French translation from contribution of - Sun G11n <gnome_int_l10n@ireland.sun.com>. - -2002-07-27 Hasbullah Bin Pit <sebol@ikhlas.com> - - * ms.po: Updated Malay Translation. - -2002-07-25 Christian Rose <menthos@menthos.com> - - * sv.po: Updated Swedish translation. - -2002-07-25 Zbigniew Chyla <chyla@gnome.pl> - - * pl.po: Updated Polish translation by - GNOME PL Team <translators@gnome.pl>. - -2002-07-25 Dmitry G. Mastrukov <dmitry@taurussoft.org> - - * ru.po: updated Russian translation with help from - SUN G11n <gnome_int_l10n@ireland.sun.com>. - -2002-07-25 Christian Rose <menthos@menthos.com> - - * sv.po: Updated Swedish translation. - -2002-07-25 Christian Rose <menthos@menthos.com> - - * sv.po: Updated Swedish translation and merged the - Sun changes that are sane. - -2002-07-24 Stanislav Visnovsky <visnovsky@nenya.ms.mff.cuni.cz> - - * sk.po: Updated Slovak translation. - -2002-07-23 Pablo Gonzalo del Campo <pablodc@bigfoot.com> - - * es.po: Updated Spanish translation. - -2002-07-24 Zbigniew Chyla <chyla@gnome.pl> - - * pl.po: Updated Polish translation by - GNOME PL Team <translators@gnome.pl>. - -2002-07-19 Pablo Gonzalo del Campo <pablodc@bigfoot.com> - - * es.po: Updated Spanish translation. - -2002-07-16 Kjartan Maraas <kmaraas@gnome.org> - - * no.po: Updated Norwegian (bokmÃ¥l) translation. - -2002-07-15 Ole Laursen <olau@hardworking.dk> - - * da.po: Fixed a string. - -2002-07-13 Christophe Fergeau <teuf@users.sourceforge.net> - - * fr.po: Added French translation. - -2002-07-13 Ole Laursen <olau@hardworking.dk> - - * da.po: Updated Danish translation. - -2002-07-12 Pablo Gonzalo del Campo <pablodc@bigfoot.com> - - * es.po: Updated Spanish translation. - -2002-07-11 Christian Rose <menthos@menthos.com> - - * sv.po: Updated Swedish translation. - -2002-07-11 Christian Rose <menthos@menthos.com> - - * sv.po: Updated Swedish translation. - -2002-07-08 Christian Rose <menthos@menthos.com> - - * sv.po: Updated Swedish translation. - -2002-07-02 Stanislav Visnovsky <visnovsky@nenya.ms.mff.cuni.cz> - - * sk.po: Updated Slovak translation. - -2002-06-24 Pablo Gonzalo del Campo <pablodc@bigfoot.com> - - * es.po: Updated Spanish translation. - -2002-06-24 Zbigniew Chyla <chyla@buy.pl> - - * pl.po: Updated Polish translation by - GNOME PL Team <translators@gnome.pl>. - -2002-06-25 Abel Cheung <maddog@linux.org.hk> - - * zh_TW.po: Updated traditional Chinese translation. - -2002-06-23 Kjartan Maraas <kmaraas@gnome.org> - - * no.po: Updated Norwegian (bokmÃ¥l) translation. - -2002-06-23 Christian Rose <menthos@menthos.com> - - * sv.po: Updated Swedish translation. - -2002-06-19 Ole Laursen <olau@hardworking.dk> - - * da.po: Updated Danish translation. - -2002-06-16 Pablo Gonzalo del Campo <pablodc@bigfoot.com> - - * es.po: Updated Spanish translation. - -2002-06-16 Christian Rose <menthos@menthos.com> - - * POTFILES.in: Added missing file. - * sv.po: Updated Swedish translation. - -2002-06-15 Akira TAGOH <tagoh@gnome.gr.jp> - - * ja.po: Updated Japanese translation. - -2002-06-14 Changwoo Ryu <cwryu@debian.org> - - * ko.po: Updated Korean translation. - -2002-06-10 Pablo Gonzalo del Campo <pablodc@bigfoot.com> - - * es.po: Updated Spanish translation. - -2002-06-10 Stanislav Visnovsky <visnovsky@nenya.ms.mff.cuni.cz> - - * sk.po: Updated Slovak translation. - -2002-06-09 Pablo Gonzalo del Campo <pablodc@bigfoot.com> - - * es.po: Updated Spanish translation. - -2002-06-09 Christian Rose <menthos@menthos.com> - - * sv.po: Updated Swedish translation. - -2002-06-07 Zbigniew Chyla <chyla@buy.pl> - - * pl.po: Updated Polish translation by - GNOME PL Team <translators@gnome.pl>. - -2002-06-06 Pablo Gonzalo del Campo <pablodc@bigfoot.com> - - * es.po: Updated Spanish translation. - -2002-06-06 Christian Rose <menthos@menthos.com> - - * sv.po: Updated Swedish translation. - -2002-06-05 Pablo Gonzalo del Campo <pablodc@bigfoot.com> - - * es.po: Updated Spanish translation. - -2002-06-05 Christian Rose <menthos@menthos.com> - - * sv.po: Updated Swedish translation. - -2002-06-04 Christian Rose <menthos@menthos.com> - - * sv.po: Updated Swedish translation. - -2002-06-04 Stanislav Visnovsky <visnovsky@nenya.ms.mff.cuni.cz> - - * sk.po: Updated Slovak translation. - -2002-06-04 Christian Rose <menthos@menthos.com> - - * sv.po: Updated Swedish translation. - -2002-06-03 Kjartan Maraas <kmaraas@gnome.org> - - * no.po: Updated Norwegian (bokmÃ¥l) translation. - -2002-06-03 Stanislav Visnovsky <visnovsky@nenya.ms.mff.cuni.cz> - - * sk.po: Updated Slovak translation. - -2002-06-03 Changwoo Ryu <cwryu@debian.org> - - * ko.po: Updated Korean translation by Young-Ho Cha - <ganadist@chollian.net>. - -2002-06-01 Ole Laursen <olau@hardworking.dk> - - * da.po: Updated Danish translation. - -2002-05-31 Pablo Gonzalo del Campo <pablodc@bigfoot.com> - - * es.po: Updated Spanish translation. - -2002-05-31 Stanislav Visnovsky <visnovsky@nenya.ms.mff.cuni.cz> - - * sk.po: Updated Slovak translation. - -2002-05-31 Kjartan Maraas <kmaraas@gnome.org> - - * no.po: Updated Norwegian (bokmÃ¥l) translation. - -2002-05-28 Pablo Gonzalo del Campo <pablodc@bigfoot.com> - - * es.po: Updated Spanish translation. - -2002-05-28 Ole Laursen <olau@hardworking.dk> - - * da.po: Updated Danish translation. - -2002-05-28 Abel Cheung <maddog@linux.org.hk> - - * zh_TW.po: New traditional Chinese translation. - -2002-05-27 Christian Rose <menthos@menthos.com> - - * sv.po: Updated Swedish translation. - -2002-05-26 Matthias Warkus <mawarkus@gnome.org> - - * de.po: German translation added. - -2002-05-26 Zbigniew Chyla <cyba@gnome.pl> - - * pl.po: Updated Polish translation by - GNOME PL Team <translators@gnome.pl>. - -2002-05-24 Stanislav Visnovsky <visnovsky@nenya.ms.mff.cuni.cz> - - * sk.po: Updated Slovak translation. - -2002-05-21 Changwoo Ryu <cwryu@debian.org> - - * ko.po: Updated Korean translation by Young-Ho Cha - <ganadist@chollian.net>. - -2002-05-20 Alessio Frusciante <algol@perseus> - - * it.po: Added Italian translation. - -2002-05-20 Pablo Saratxaga <pablo@mandrakesoft.com> - - * ca.po: Added Catalan file - * az.po,es.po,ms.po,lv.po: Corrected syntax errors - -2002-05-18 Kjartan Maraas <kmaraas@gnome.org> - - * no.po: Updated Norwegian (bokmÃ¥l) translation. - -2002-05-18 Ole Laursen <olau@hardworking.dk> - - * da.po: Updated Danish translation. - -2002-05-16 Stanislav Visnovsky <visnovsky@nenya.ms.mff.cuni.cz> - - * sk.po: Updated Slovak translation. - -2002-05-06 Duarte Loreto <happyguy_pt@hotmail.com> - - * pt.po: Updated Portuguese translation and converted to UTF-8. - -2002-04-26 Zbigniew Chyla <cyba@gnome.pl> - - * pl.po: Updated Polish translation by - GNOME PL Team <translators@gnome.pl>. - -2002-04-25 Changwoo Ryu <cwryu@debian.org> - - * ko.po: Updated Korean translation from Young-Ho Cha - <ganadist@chollian.net>. - -2002-04-22 Kjartan Maraas <kmaraas@gnome.org> - - * no.po: Updated Norwegian (bokmÃ¥l) translation. - -2002-04-19 Changwoo Ryu <cwryu@debian.org> - - * ko.po: Updated Korean translation from Young-Ho Cha - <ganadist@chollian.net>. - -2002-04-17 Changwoo Ryu <cwryu@debian.org> - - * ko.po: Added Korean translation from Young-Ho Cha - <ganadist@chollian.net>. - -2002-04-16 Akira TAGOH <tagoh@gnome.gr.jp> - - * ja.po: Add Japanese translation. - -2002-04-16 Abel Cheung <maddog@linux.org.hk> - - * .cvsignore: Added some file(s). - * POTFILES.in: Synced with source tree. - -2002-04-15 Zbigniew Chyla <cyba@gnome.pl> - - * pl.po: Updated Polish translation by - GNOME PL Team <translators@gnome.pl>. - -2002-03-28 Kjartan Maraas <kmaraas@gnome.org> - - * no.po: Updated Norwegian (bokmÃ¥l) translation. - -2002-03-27 Kjartan Maraas <kmaraas@gnome.org> - - * no.po: Updated Norwegian (bokmÃ¥l) translation. - -2002-03-22 Zbigniew Chyla <cyba@gnome.pl> - - * pl.po: Added Polish translation. - -2002-02-22 Kjartan Maraas <kmaraas@gnome.org> - - * no.po: Updated Norwegian (bokmÃ¥l) translation. - -2002-02-17 Kjartan Maraas <kmaraas@gnome.org> - - * no.po: Updated Norwegian (bokmÃ¥l) translation. - -2002-02-16 Kjartan Maraas <kmaraas@gnome.org> - - * no.po: Updated Norwegian (bokmÃ¥l) translation. - -2002-02-12 Kjartan Maraas <kmaraas@gnome.org> - - * no.po: Updated Norwegian (bokmÃ¥l) translation. - -2002-02-11 Duarte Loreto <happyguy_pt@hotmail.com> - - * pt.po: Updated Portuguese translation. - -2002-02-10 Hasbullah Bin Pit <sebol@ikhlas.com> - - * ms.po: Updated Malay Translation. - -2002-02-10 Kjartan Maraas <kmaraas@gnome.org> - - * no.po: Updated Norwegian (bokmÃ¥l) translation. - -2002-02-08 Christian Rose <menthos@menthos.com> - - * sv.po: Updated Swedish translation. - -2002-02-08 Christian Rose <menthos@menthos.com> - - * POTFILES.in: Added missing file. - -2002-02-08 Havoc Pennington <hp@pobox.com> - - * da.po: fix a missing newline that made build fail once po was - added to subdirs - -2002-02-02 Kjartan Maraas <kmaraas@gnome.org> - - * no.po: Updated Norwegian (bokmÃ¥l) translation. - -2002-01-31 Christian Rose <menthos@menthos.com> - - * sv.po: Updated Swedish translation. - -2002-01-30 Stanislav Visnovsky <visnovsky@nenya.ms.mff.cuni.cz> - - * sk.po: Updated Slovak translation. - -2002-01-30 Stanislav Visnovsky <visnovsky@nenya.ms.mff.cuni.cz> - - * sk.po: Updated Slovak translation. - -2002-01-29 Kjartan Maraas <kmaraas@gnome.org> - - * no.po: Updated Norwegian (bokmÃ¥l) translation. - -2002-01-27 Peteris Krisjanis <peteris.krisjanis@ttc.lv> - - * lv.po: Added Latvian translation. - -2002-01-22 Hasbullah Bin Pit <sebol@ikhlas.com> - - * ms.po: Added Malay Translation. - -2002-01-11 Kjartan Maraas <kmaraas@gnome.org> - - * no.po: Updated Norwegian (bokmÃ¥l) translation. - -2002-01-09 Stanislav Visnovsky <visnovsky@nenya.ms.mff.cuni.cz> - - * sk.po: Updated Slovak translation. - -2002-01-08 Duarte Loreto <happyguy_pt@hotmail.com> - - * pt.po: Updated Portuguese translation. - -2002-01-06 Fatih Demir <kabalak@gtranslator.org> - - * tr.po: Added Turkish translation by Görkem Cetin. - -2002-01-05 Christian Rose <menthos@menthos.com> - - * POTFILES.in: Added missing files. - * sv.po: Updated Swedish translation. - -2001-12-27 Duarte Loreto <happyguy_pt@hotmail.com> - - * pt.po: Added portuguese translation - -2001-12-27 Jesus Bravo Alvarez <jba@pobox.com> - - * gl.po: Updated Galician translation from - Manuel A. Fernandez Montecelo <manuel@sindominio.net> - -2001-12-26 Vasif Ismailogu MD <azerb_linux@hotmail.com> - - * az.po: updating Azerbaijani translation file - -2001-12-16 Kjartan Maraas <kmaraas@gnome.org> - - * no.po: Updated Norwegian (bokmï¿œ) translation. - -2001-12-15 Christian Rose <menthos@menthos.com> - - * sv.po: Updated Swedish translation. - -2001-12-13 Stanislav Visnovsky <visnovsky@nenya.ms.mff.cuni.cz> - - * sk.po: Updated Slovak translation. - -2001-12-11 Stanislav Visnovsky <visnovsky@nenya.ms.mff.cuni.cz> - - * sk.po: Added Slovak translation. - -2001-11-27 Jesus Bravo Alvarez <jba@pobox.com> - - * gl.po: Added Galician translation from - Manuel A. Fernï¿œdez Montecelo <manuel@sindominio.net> - -2001-10-29 Yuriy Syrota <rasta@renome.rovno.ua> - - * uk.po: Added Ukrainian translation file. - -2001-10-28 Hï¿œtor Garcï¿œ ï¿œvarez <hector@scouts-es.org> - - * es.po: Updated Spanish translation. - -2001-10-14 Hï¿œtor Garcï¿œ ï¿œvarez <hector@scouts-es.org> - - * es.po: Added Spanish translation. - -2001-10-14 Valek Filippov <frob@df.ru> - - * ru.po: Added russian translation. - -2001-10-11 Christian Rose <menthos@menthos.com> - - * sv.po: Fixed some typos. Thanks to Tomas ï¿œren <stric@ing.umu.se> - for spotting many of them. - -2001-10-11 Christian Rose <menthos@menthos.com> - - * sv.po: Added Swedish translation. - * POTFILES.in: Added files. - * .cvsignore: Added messages and *.pot. diff --git a/po/LINGUAS b/po/LINGUAS index 3f38817bf..f11ca4909 100644 --- a/po/LINGUAS +++ b/po/LINGUAS @@ -29,7 +29,9 @@ eu fa fi fr +fur ga +gd gl gu ha @@ -44,6 +46,7 @@ is it ja ka +kk kn ko ku @@ -80,6 +83,7 @@ sr@latin sv ta te +tg th tk tr diff --git a/po/Makefile.in.in b/po/Makefile.in.in deleted file mode 100644 index fcd2c3b70..000000000 --- a/po/Makefile.in.in +++ /dev/null @@ -1,221 +0,0 @@ -# Makefile for program source directory in GNU NLS utilities package. -# Copyright (C) 1995, 1996, 1997 by Ulrich Drepper <drepper@gnu.ai.mit.edu> -# Copyright (C) 2004-2008 Rodney Dawes <dobey.pwns@gmail.com> -# -# This file may be copied and used freely without restrictions. It may -# be used in projects which are not available under a GNU Public License, -# but which still want to provide support for the GNU gettext functionality. -# -# - Modified by Owen Taylor <otaylor@redhat.com> to use GETTEXT_PACKAGE -# instead of PACKAGE and to look for po2tbl in ./ not in intl/ -# -# - Modified by jacob berkman <jacob@ximian.com> to install -# Makefile.in.in and po2tbl.sed.in for use with glib-gettextize -# -# - Modified by Rodney Dawes <dobey.pwns@gmail.com> for use with intltool -# -# We have the following line for use by intltoolize: -# INTLTOOL_MAKEFILE - -GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ -PACKAGE = @PACKAGE@ -VERSION = @VERSION@ - -SHELL = @SHELL@ - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -top_builddir = @top_builddir@ -VPATH = @srcdir@ - -prefix = @prefix@ -exec_prefix = @exec_prefix@ -datadir = @datadir@ -datarootdir = @datarootdir@ -libdir = @libdir@ -localedir = @localedir@ -subdir = po -install_sh = @install_sh@ -# Automake >= 1.8 provides @mkdir_p@. -# Until it can be supposed, use the safe fallback: -mkdir_p = $(install_sh) -d - -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ - -GMSGFMT = @GMSGFMT@ -MSGFMT = @MSGFMT@ -XGETTEXT = @XGETTEXT@ -INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ -INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ -MSGMERGE = INTLTOOL_EXTRACT="$(INTLTOOL_EXTRACT)" XGETTEXT="$(XGETTEXT)" srcdir=$(srcdir) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --dist -GENPOT = INTLTOOL_EXTRACT="$(INTLTOOL_EXTRACT)" XGETTEXT="$(XGETTEXT)" srcdir=$(srcdir) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --pot - -ALL_LINGUAS = @ALL_LINGUAS@ - -PO_LINGUAS=$(shell if test -r $(srcdir)/LINGUAS; then grep -v "^\#" $(srcdir)/LINGUAS; else echo "$(ALL_LINGUAS)"; fi) - -USER_LINGUAS=$(shell if test -n "$(LINGUAS)"; then LLINGUAS="$(LINGUAS)"; ALINGUAS="$(ALL_LINGUAS)"; for lang in $$LLINGUAS; do if test -n "`grep \^$$lang$$ $(srcdir)/LINGUAS 2>/dev/null`" -o -n "`echo $$ALINGUAS|tr ' ' '\n'|grep \^$$lang$$`"; then printf "$$lang "; fi; done; fi) - -USE_LINGUAS=$(shell if test -n "$(USER_LINGUAS)" -o -n "$(LINGUAS)"; then LLINGUAS="$(USER_LINGUAS)"; else if test -n "$(PO_LINGUAS)"; then LLINGUAS="$(PO_LINGUAS)"; else LLINGUAS="$(ALL_LINGUAS)"; fi; fi; for lang in $$LLINGUAS; do printf "$$lang "; done) - -POFILES=$(shell LINGUAS="$(PO_LINGUAS)"; for lang in $$LINGUAS; do printf "$$lang.po "; done) - -DISTFILES = Makefile.in.in POTFILES.in $(POFILES) -EXTRA_DISTFILES = ChangeLog POTFILES.skip Makevars LINGUAS - -POTFILES = \ -# This comment gets stripped out - -CATALOGS=$(shell LINGUAS="$(USE_LINGUAS)"; for lang in $$LINGUAS; do printf "$$lang.gmo "; done) - -.SUFFIXES: -.SUFFIXES: .po .pox .gmo .mo .msg .cat - -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -INTLTOOL_V_MSGFMT = $(INTLTOOL__v_MSGFMT_$(V)) -INTLTOOL__v_MSGFMT_= $(INTLTOOL__v_MSGFMT_$(AM_DEFAULT_VERBOSITY)) -INTLTOOL__v_MSGFMT_0 = @echo " MSGFMT" $@; - -.po.pox: - $(MAKE) $(GETTEXT_PACKAGE).pot - $(MSGMERGE) $* $(GETTEXT_PACKAGE).pot -o $*.pox - -.po.mo: - $(INTLTOOL_V_MSGFMT)$(MSGFMT) -o $@ $< - -.po.gmo: - $(INTLTOOL_V_MSGFMT)file=`echo $* | sed 's,.*/,,'`.gmo \ - && rm -f $$file && $(GMSGFMT) -o $$file $< - -.po.cat: - sed -f ../intl/po2msg.sed < $< > $*.msg \ - && rm -f $@ && gencat $@ $*.msg - - -all: all-@USE_NLS@ - -all-yes: $(CATALOGS) -all-no: - -$(GETTEXT_PACKAGE).pot: $(POTFILES) - $(GENPOT) - -install: install-data -install-data: install-data-@USE_NLS@ -install-data-no: all -install-data-yes: all - linguas="$(USE_LINGUAS)"; \ - for lang in $$linguas; do \ - dir=$(DESTDIR)$(localedir)/$$lang/LC_MESSAGES; \ - $(mkdir_p) $$dir; \ - if test -r $$lang.gmo; then \ - $(INSTALL_DATA) $$lang.gmo $$dir/$(GETTEXT_PACKAGE).mo; \ - echo "installing $$lang.gmo as $$dir/$(GETTEXT_PACKAGE).mo"; \ - else \ - $(INSTALL_DATA) $(srcdir)/$$lang.gmo $$dir/$(GETTEXT_PACKAGE).mo; \ - echo "installing $(srcdir)/$$lang.gmo as" \ - "$$dir/$(GETTEXT_PACKAGE).mo"; \ - fi; \ - if test -r $$lang.gmo.m; then \ - $(INSTALL_DATA) $$lang.gmo.m $$dir/$(GETTEXT_PACKAGE).mo.m; \ - echo "installing $$lang.gmo.m as $$dir/$(GETTEXT_PACKAGE).mo.m"; \ - else \ - if test -r $(srcdir)/$$lang.gmo.m ; then \ - $(INSTALL_DATA) $(srcdir)/$$lang.gmo.m \ - $$dir/$(GETTEXT_PACKAGE).mo.m; \ - echo "installing $(srcdir)/$$lang.gmo.m as" \ - "$$dir/$(GETTEXT_PACKAGE).mo.m"; \ - else \ - true; \ - fi; \ - fi; \ - done - -# Empty stubs to satisfy archaic automake needs -dvi info ctags tags CTAGS TAGS ID: - -# Define this as empty until I found a useful application. -install-exec installcheck: - -uninstall: - linguas="$(USE_LINGUAS)"; \ - for lang in $$linguas; do \ - rm -f $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE).mo; \ - rm -f $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE).mo.m; \ - done - -check: all $(GETTEXT_PACKAGE).pot - rm -f missing notexist - srcdir=$(srcdir) $(INTLTOOL_UPDATE) -m - if [ -r missing -o -r notexist ]; then \ - exit 1; \ - fi - -mostlyclean: - rm -f *.pox $(GETTEXT_PACKAGE).pot *.old.po cat-id-tbl.tmp - rm -f .intltool-merge-cache - -clean: mostlyclean - -distclean: clean - rm -f Makefile Makefile.in POTFILES stamp-it - rm -f *.mo *.msg *.cat *.cat.m *.gmo - -maintainer-clean: distclean - @echo "This command is intended for maintainers to use;" - @echo "it deletes files that may require special tools to rebuild." - rm -f Makefile.in.in - -distdir = ../$(PACKAGE)-$(VERSION)/$(subdir) -dist distdir: $(DISTFILES) - dists="$(DISTFILES)"; \ - extra_dists="$(EXTRA_DISTFILES)"; \ - for file in $$extra_dists; do \ - test -f $(srcdir)/$$file && dists="$$dists $(srcdir)/$$file"; \ - done; \ - for file in $$dists; do \ - test -f $$file || file="$(srcdir)/$$file"; \ - ln $$file $(distdir) 2> /dev/null \ - || cp -p $$file $(distdir); \ - done - -update-po: Makefile - $(MAKE) $(GETTEXT_PACKAGE).pot - tmpdir=`pwd`; \ - linguas="$(USE_LINGUAS)"; \ - for lang in $$linguas; do \ - echo "$$lang:"; \ - result="`$(MSGMERGE) -o $$tmpdir/$$lang.new.po $$lang`"; \ - if $$result; then \ - if cmp $(srcdir)/$$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ - rm -f $$tmpdir/$$lang.new.po; \ - else \ - if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ - :; \ - else \ - echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ - rm -f $$tmpdir/$$lang.new.po; \ - exit 1; \ - fi; \ - fi; \ - else \ - echo "msgmerge for $$lang.gmo failed!"; \ - rm -f $$tmpdir/$$lang.new.po; \ - fi; \ - done - -Makefile POTFILES: stamp-it - @if test ! -f $@; then \ - rm -f stamp-it; \ - $(MAKE) stamp-it; \ - fi - -stamp-it: Makefile.in.in $(top_builddir)/config.status POTFILES.in - cd $(top_builddir) \ - && CONFIG_FILES=$(subdir)/Makefile.in CONFIG_HEADERS= CONFIG_LINKS= \ - $(SHELL) ./config.status - -# Tell versions [3.59,3.63) of GNU make not to export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/po/POTFILES.in b/po/POTFILES.in index 7a4a759a2..58bc3ce59 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -1,29 +1,33 @@ # List of source files containing translatable strings. # Please keep this file sorted alphabetically. +data/50-mutter-navigation.xml +data/50-mutter-system.xml +data/50-mutter-wayland.xml +data/50-mutter-windows.xml +data/mutter.desktop.in +data/org.gnome.mutter.gschema.xml.in +data/org.gnome.mutter.wayland.gschema.xml.in +src/backends/meta-input-settings.c +src/backends/meta-monitor.c +src/backends/meta-monitor-manager.c +src/backends/meta-profiler.c src/compositor/compositor.c +src/compositor/meta-background.c src/core/bell.c -src/core/core.c -src/core/delete.c src/core/display.c -src/core/errors.c src/core/keybindings.c src/core/main.c -src/core/muffin.c +src/core/meta-close-dialog-default.c +src/core/mutter.c src/core/prefs.c -src/core/screen.c -src/core/session.c src/core/util.c src/core/window.c -src/core/window-props.c -src/core/xprops.c -src/muffin.desktop.in -src/org.cinnamon.muffin.gschema.xml.in -src/tools/muffin-message.c src/ui/frames.c -src/ui/menu.c -src/ui/metaaccellabel.c -src/ui/resizepopup.c src/ui/theme.c -src/ui/theme-parser.c -src/ui/theme-viewer.c - +src/wayland/meta-wayland-tablet-pad.c +src/x11/meta-x11-display.c +src/x11/meta-x11-errors.c +src/x11/meta-x11-selection-input-stream.c +src/x11/session.c +src/x11/window-props.c +src/x11/xprops.c diff --git a/po/POTFILES.skip b/po/POTFILES.skip index 1b09a3274..81912451b 100644 --- a/po/POTFILES.skip +++ b/po/POTFILES.skip @@ -1,81 +1,4 @@ -src/metacity.schemas.in -clutter/clutter/clutter-actor-meta.c -clutter/clutter/clutter-actor.c -clutter/clutter/clutter-align-constraint.c -clutter/clutter/clutter-backend.c -clutter/clutter/clutter-bin-layout.c -clutter/clutter/clutter-bind-constraint.c -clutter/clutter/clutter-binding-pool.c -clutter/clutter/clutter-box-layout.c -clutter/clutter/clutter-brightness-contrast-effect.c -clutter/clutter/clutter-canvas.c -clutter/clutter/clutter-child-meta.c -clutter/clutter/clutter-click-action.c -clutter/clutter/clutter-clone.c -clutter/clutter/clutter-color.c -clutter/clutter/clutter-colorize-effect.c -clutter/clutter/clutter-container.c -clutter/clutter/clutter-content.c -clutter/clutter/clutter-deform-effect.c -clutter/clutter/clutter-desaturate-effect.c -clutter/clutter/clutter-device-manager.c -clutter/clutter/clutter-drag-action.c -clutter/clutter/clutter-drop-action.c -clutter/clutter/clutter-flow-layout.c -clutter/clutter/clutter-gesture-action.c -clutter/clutter/clutter-grid-layout.c -clutter/clutter/clutter-image.c -clutter/clutter/clutter-input-device-tool.c -clutter/clutter/clutter-input-device.c -clutter/clutter/clutter-input-method.c -clutter/clutter/clutter-interval.c -clutter/clutter/clutter-layout-manager.c -clutter/clutter/clutter-layout-meta.c -clutter/clutter/clutter-main.c -clutter/clutter/clutter-paint-node.c -clutter/clutter/clutter-pan-action.c -clutter/clutter/clutter-path-constraint.c -clutter/clutter/clutter-property-transition.c -clutter/clutter/clutter-rotate-action.c -clutter/clutter/clutter-script.c -clutter/clutter/clutter-scroll-actor.c -clutter/clutter/clutter-settings.c -clutter/clutter/clutter-shader-effect.c -clutter/clutter/clutter-shader-types.c -clutter/clutter/clutter-snap-constraint.c -clutter/clutter/clutter-stage.c -clutter/clutter/clutter-swipe-action.c -clutter/clutter/clutter-tap-action.c -clutter/clutter/clutter-text-buffer.c -clutter/clutter/clutter-text.c -clutter/clutter/clutter-timeline.c -clutter/clutter/clutter-transition.c -clutter/clutter/clutter-units.c -clutter/clutter/clutter-virtual-input-device.c -clutter/clutter/clutter-zoom-action.c -clutter/clutter/deprecated/clutter-alpha.c -clutter/clutter/deprecated/clutter-animation.c -clutter/clutter/deprecated/clutter-animator.c -clutter/clutter/deprecated/clutter-behaviour-depth.c -clutter/clutter/deprecated/clutter-behaviour-ellipse.c -clutter/clutter/deprecated/clutter-behaviour-opacity.c -clutter/clutter/deprecated/clutter-behaviour-path.c -clutter/clutter/deprecated/clutter-behaviour-rotate.c -clutter/clutter/deprecated/clutter-behaviour-scale.c -clutter/clutter/deprecated/clutter-behaviour.c -clutter/clutter/deprecated/clutter-box.c -clutter/clutter/deprecated/clutter-cairo-texture.c -clutter/clutter/deprecated/clutter-media.c -clutter/clutter/deprecated/clutter-rectangle.c -clutter/clutter/deprecated/clutter-shader.c -clutter/clutter/deprecated/clutter-state.c -clutter/clutter/deprecated/clutter-table-layout.c -clutter/clutter/deprecated/clutter-texture.c -clutter/clutter/evdev/clutter-input-device-evdev.c -clutter/clutter/evdev/clutter-virtual-input-device-evdev.c -clutter/clutter/wayland/clutter-wayland-surface.c -clutter/clutter/x11/clutter-backend-x11.c -clutter/clutter/x11/clutter-keymap-x11.c -clutter/clutter/x11/clutter-x11-texture-pixmap.c -cogl/cogl/cogl-debug-options.h -cogl/cogl/cogl-debug.c +# List of source files that should NOT be translated. +# Please keep this file sorted alphabetically. +clutter +cogl diff --git a/po/am.po b/po/am.po index 13570b803..0e7097351 100644 --- a/po/am.po +++ b/po/am.po @@ -12,6 +12,7 @@ msgstr "" "PO-Revision-Date: 2003-02-03 10:16+EDT\n" "Last-Translator: Ge'ez Frontier Foundation <locales@geez.org>\n" "Language-Team: Amharic <locales@geez.org>\n" +"Language: am\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" diff --git a/po/ar.po b/po/ar.po index 66ba001fc..82df3c230 100644 --- a/po/ar.po +++ b/po/ar.po @@ -4,442 +4,619 @@ # Arafat Medini <lumina@silverpen.de>, 2003. # Abdulaziz Al-Arfaj <alarfaj0@yahoo.com>, 2004. # Djihed Afifi <djihed@gmail.com>, 2006. -# Khaled Hosny <khaledhosny@eglug.org>, 2006, 2007, 2008, 2009, 2010, 2011. +# Khaled Hosny <khaledhosny@eglug.org>, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2017, 2019. # Anas Afif Emad <anas.e87@gmail.com>, 2008. msgid "" msgstr "" "Project-Id-Version: metacity.HEAD\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2011-03-11 15:15+0200\n" -"PO-Revision-Date: 2011-03-11 15:15+0300\n" +"POT-Creation-Date: 2019-03-15 23:40+0200\n" +"PO-Revision-Date: 2019-03-15 23:42+0200\n" "Last-Translator: Khaled Hosny <khaledhosny@eglug.org>\n" "Language-Team: Arabic <doc@arabeyes.org>\n" +"Language: ar\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Language: ar\n" "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " "&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n" -"X-Generator: Virtaal 0.6.1\n" +"X-Generator: Virtaal 0.7.1\n" +"X-Project-Style: gnome\n" -#: ../src/core/all-keybindings.h:88 -msgid "Switch to workspace 1" -msgstr "انتقل إلى مساحة العمل 1" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "الإبحار" -#: ../src/core/all-keybindings.h:90 -msgid "Switch to workspace 2" -msgstr "انتقل إلى مساحة العمل 2" +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "انقل النافذة إلى مساحة العمل 1" -#: ../src/core/all-keybindings.h:92 -msgid "Switch to workspace 3" -msgstr "انتقل إلى مساحة العمل 3" +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "انقل النافذة إلى مساحة العمل 2" -#: ../src/core/all-keybindings.h:94 -msgid "Switch to workspace 4" -msgstr "انتقل إلى مساحة العمل 4" +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "انقل النافذة إلى مساحة العمل 3" -#: ../src/core/all-keybindings.h:96 -msgid "Switch to workspace 5" -msgstr "انتقل إلى مساحة العمل 5" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "انقل النافذة إلى مساحة العمل 4" -#: ../src/core/all-keybindings.h:98 -msgid "Switch to workspace 6" -msgstr "انتقل إلى مساحة العمل 6" +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "انقل النافذة إلى مساحة العمل الأخيرة" -#: ../src/core/all-keybindings.h:100 -msgid "Switch to workspace 7" -msgstr "انتقل إلى مساحة العمل 7" +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "انقل النافذة مساحة عمل واحدة إلى الأعلى" -#: ../src/core/all-keybindings.h:102 -msgid "Switch to workspace 8" -msgstr "انتقل إلى مساحة العمل 8" +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "انقل النافذة مساحة عمل واحدة إلى الأسفل" -#: ../src/core/all-keybindings.h:104 -msgid "Switch to workspace 9" -msgstr "انتقل إلى مساحة العمل 9" +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "انقل النافذة شاشة واحدة إلى اليسار" -#: ../src/core/all-keybindings.h:106 -msgid "Switch to workspace 10" -msgstr "انتقل إلى مساحة العمل 10" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "انقل النافذة شاشة واحدة إلى اليمين" -#: ../src/core/all-keybindings.h:108 -msgid "Switch to workspace 11" -msgstr "انتقل إلى مساحة العمل 11" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "انقل النافذة شاشة واحدة إلى الأعلى" -#: ../src/core/all-keybindings.h:110 -msgid "Switch to workspace 12" -msgstr "انتقل إلى مساحة العمل 12" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "انقل النافذة شاشة واحدة إلى الأسفل" -#: ../src/core/all-keybindings.h:122 -msgid "Switch to workspace on the left of the current workspace" -msgstr "انتقل إلى مساحة العمل على يسار الحالية" +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "تنقل بين التطبيقات" -#: ../src/core/all-keybindings.h:126 -msgid "Switch to workspace on the right of the current workspace" -msgstr "انتقل إلى مساحة العمل على يمين الحالية" +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "انتقل إلى التطبيق السابق" -#: ../src/core/all-keybindings.h:130 -msgid "Switch to workspace above the current workspace" -msgstr "انتقل إلى مساحة العمل فوق الحالية" +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "تنقل بين النوافذ" -#: ../src/core/all-keybindings.h:134 -msgid "Switch to workspace below the current workspace" -msgstr "انتقل إلى مساحة العمل تحت الحالية" +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "انتقل إلى النافذة السابقة" -#: ../src/core/all-keybindings.h:150 -msgid "Move between windows of an application, using a popup window" -msgstr "تنقل بين نوافذ تطبيق بنافذةٍ قافزة" +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "تنقل بين نوافذ التطبيق" -#: ../src/core/all-keybindings.h:153 -msgid "Move backward between windows of an application, using a popup window" -msgstr "تنقل إلى الوراء بين نوافذ تطبيق بنافذةٍ قافزة" +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "انتقل إلى نافذة التطبيق السابقة" -#: ../src/core/all-keybindings.h:157 -msgid "Move between windows, using a popup window" -msgstr "تنقل بين النوافذ بنافذةٍ قافزة" +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "تنقل بين تحكمات النظام" -#: ../src/core/all-keybindings.h:160 -msgid "Move backward between windows, using a popup window" -msgstr "تنقل إلى الوراء بين النوافذ بنافذةٍ قافزة" +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "انتقل إلى تحكم النظام السابق" -#: ../src/core/all-keybindings.h:163 -msgid "Move between panels and the desktop, using a popup window" -msgstr "تنقل بين الأشرطة و سطح المكتب بنافذةٍ قافزة" +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "تنقل مباشرة بين النوافذ" -#: ../src/core/all-keybindings.h:166 -msgid "Move backward between panels and the desktop, using a popup window" -msgstr "تنقل إلى الوراء بين الأشرطة و سطح المكتب بنافذةٍ قافزة" +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "انتقل مباشرة إلى النافذة السابقة" -#: ../src/core/all-keybindings.h:171 -msgid "Move between windows of an application immediately" -msgstr "تنقل بين نوافذ تطبيق حالًا" +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "تنقل مباشرة بين نوافذ التطبيق" -#: ../src/core/all-keybindings.h:174 -msgid "Move backward between windows of an application immediately" -msgstr "تنقل إلى الوراء بين نوافذ تطبيق حالًا" +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "انتقل مباشرة إلى نافذة التطبيق السابقة" -#: ../src/core/all-keybindings.h:177 -msgid "Move between windows immediately" -msgstr "تنقل بين النوافذ حالًا" +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "تنقل مباشرة بين تحكمات النظام" -#: ../src/core/all-keybindings.h:180 -msgid "Move backward between windows immediately" -msgstr "تنقل إلى الوراء بين النوافذ حالًا" +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "انتقل مباشرة إلى تحكم النظام السابق" + +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "أخفِ كل النوافذ العادية" + +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "انتقل إلى مساحة العمل 1" + +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "انتقل إلى مساحة العمل 2" + +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "انتقل إلى مساحة العمل 3" -#: ../src/core/all-keybindings.h:183 -msgid "Move between panels and the desktop immediately" -msgstr "تنقل بين الأشرطة و سطح المكتب حالًا" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "انتقل إلى مساحة العمل 4" -#: ../src/core/all-keybindings.h:186 -msgid "Move backward between panels and the desktop immediately" -msgstr "تنقل إلى الوراء بين الأشرطة و سطح المكتب حالًا" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "انتقل إلى مساحة العمل الأخيرة" -#: ../src/core/all-keybindings.h:203 -msgid "Hide all normal windows and set focus to the desktop" -msgstr "أخفِ كل النوافذ و ركّز على سطح المكتب" +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "انقل لمساحة العمل أعلى" -#: ../src/core/all-keybindings.h:206 -msgid "Show the panel's main menu" -msgstr "اعرض قائمة الشريط الرئيسية" +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "انقل لمساحة العمل أسفل" -#: ../src/core/all-keybindings.h:209 -msgid "Show the panel's \"Run Application\" dialog box" -msgstr "أظهر حوار الشّريط لتشغيل التّطبيقات" +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "النظام" -#: ../src/core/all-keybindings.h:211 -msgid "Start or stop recording the session" -msgstr "ابدأ أو أوقف تسجيل الجلسة" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "أظهر محث تشغيل أمر" -#: ../src/core/all-keybindings.h:252 -msgid "Take a screenshot" -msgstr "خذ لقطة شاشة" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "أظهر نظرة عامة على الأنشطة" -#: ../src/core/all-keybindings.h:254 -msgid "Take a screenshot of a window" -msgstr "خذ لقطة لنافذة" +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "استعد اختصارات لوحة المفاتيح" -#: ../src/core/all-keybindings.h:256 -msgid "Run a terminal" -msgstr "شغّل طرفية" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "النوافذ" -#: ../src/core/all-keybindings.h:271 +#: data/50-mutter-windows.xml:8 msgid "Activate the window menu" msgstr "فعّل قائمة النافذة" -#: ../src/core/all-keybindings.h:274 +#: data/50-mutter-windows.xml:10 msgid "Toggle fullscreen mode" msgstr "بدّل نمط ملء الشاشة" -#: ../src/core/all-keybindings.h:276 +#: data/50-mutter-windows.xml:12 msgid "Toggle maximization state" msgstr "بدّل حالة التكبير" -#: ../src/core/all-keybindings.h:278 -msgid "Toggle whether a window will always be visible over other windows" -msgstr "بدّل حالة ظهور النافذة فوق النوافذ الأخرى" - -#: ../src/core/all-keybindings.h:280 +#: data/50-mutter-windows.xml:14 msgid "Maximize window" msgstr "كبّر النّافذة" -#: ../src/core/all-keybindings.h:282 +#: data/50-mutter-windows.xml:16 msgid "Restore window" msgstr "استعد النّافذة" -#: ../src/core/all-keybindings.h:284 -msgid "Toggle shaded state" -msgstr "بدّل حالة الإخفاء" - -#: ../src/core/all-keybindings.h:286 -msgid "Minimize window" -msgstr "صغّر النّافذة" - -#: ../src/core/all-keybindings.h:288 +#: data/50-mutter-windows.xml:18 msgid "Close window" msgstr "أغلق النّافذة" -#: ../src/core/all-keybindings.h:290 +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "أخفِ النّافذة" + +#: data/50-mutter-windows.xml:22 msgid "Move window" msgstr "انقل النّافذة" -#: ../src/core/all-keybindings.h:292 +#: data/50-mutter-windows.xml:24 msgid "Resize window" msgstr "حجّم النّافذة" -#: ../src/core/all-keybindings.h:295 -msgid "Toggle whether window is on all workspaces or just one" -msgstr "بدّل حالة ظهور النافذة على جميع مساحات العمل" +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "بدّل حالة ظهور النافذة على جميع مساحات العمل أو واحدة منها" -#: ../src/core/all-keybindings.h:299 -msgid "Move window to workspace 1" -msgstr "انقل النافذة إلى مساحة العمل 1" +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "ارفع النافذة إذا كانت أخرى تغطيها، أو أخفضها في ما عدا ذلك" -#: ../src/core/all-keybindings.h:302 -msgid "Move window to workspace 2" -msgstr "انقل النافذة إلى مساحة العمل 2" +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "ارفع النافذة فوق النوافذ الأخرى" -#: ../src/core/all-keybindings.h:305 -msgid "Move window to workspace 3" -msgstr "انقل النافذة إلى مساحة العمل 3" +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "اخفض النافذة تحت النوافذ الأخرى" -#: ../src/core/all-keybindings.h:308 -msgid "Move window to workspace 4" -msgstr "انقل النافذة إلى مساحة العمل 4" +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "كبّر النافذة رأسيا" -#: ../src/core/all-keybindings.h:311 -msgid "Move window to workspace 5" -msgstr "انقل النافذة إلى مساحة العمل 5" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "كبّر النافذة أفقيا" -#: ../src/core/all-keybindings.h:314 -msgid "Move window to workspace 6" -msgstr "انقل النافذة إلى مساحة العمل 6" +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "المنظور مقسوم على اليمين" -#: ../src/core/all-keybindings.h:317 -msgid "Move window to workspace 7" -msgstr "انقل النافذة إلى مساحة العمل 7" +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "المنظور مقسوم على اليسار" -#: ../src/core/all-keybindings.h:320 -msgid "Move window to workspace 8" -msgstr "انقل النافذة إلى مساحة العمل 8" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "مَتَر" -#: ../src/core/all-keybindings.h:323 -msgid "Move window to workspace 9" -msgstr "انقل النافذة إلى مساحة العمل 9" +#: data/org.gnome.mutter.gschema.xml.in:7 +msgid "Modifier to use for extended window management operations" +msgstr "المغير الذي سيُستعمل لتمديد عمليات إدارة النوافذ " -#: ../src/core/all-keybindings.h:326 -msgid "Move window to workspace 10" -msgstr "انقل النافذة إلى مساحة العمل 10" +#: data/org.gnome.mutter.gschema.xml.in:8 +msgid "" +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." +msgstr "" -#: ../src/core/all-keybindings.h:329 -msgid "Move window to workspace 11" -msgstr "انقل النافذة إلى مساحة العمل 11" +#: data/org.gnome.mutter.gschema.xml.in:20 +#, fuzzy +msgid "Attach modal dialogs" +msgstr "صندوق حوار سائد" -#: ../src/core/all-keybindings.h:332 -msgid "Move window to workspace 12" -msgstr "انقل النافذة إلى مساحة العمل 12" +#: data/org.gnome.mutter.gschema.xml.in:21 +msgid "" +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." +msgstr "" -#: ../src/core/all-keybindings.h:344 -msgid "Move window one workspace to the left" -msgstr "انقل النافذة مساحة عمل واحدة إلى اليسار" +#: data/org.gnome.mutter.gschema.xml.in:30 +msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "" -#: ../src/core/all-keybindings.h:347 -msgid "Move window one workspace to the right" -msgstr "انقل النافذة مساحة عمل واحدة إلى اليمين" +#: data/org.gnome.mutter.gschema.xml.in:31 +msgid "" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." +msgstr "" -#: ../src/core/all-keybindings.h:350 -msgid "Move window one workspace up" -msgstr "انقل النافذة مساحة عمل واحدة إلى الأعلى" +#: data/org.gnome.mutter.gschema.xml.in:40 +msgid "Workspaces are managed dynamically" +msgstr "" -#: ../src/core/all-keybindings.h:353 -msgid "Move window one workspace down" -msgstr "انقل النافذة مساحة عمل واحدة إلى الأسفل" +#: data/org.gnome.mutter.gschema.xml.in:41 +msgid "" +"Determines whether workspaces are managed dynamically or whether there’s a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." +msgstr "" -#: ../src/core/all-keybindings.h:356 -msgid "Raise window if it's covered by another window, otherwise lower it" -msgstr "ارفع النافذة إذا كانت أخرى تغطيها، أو أخفضها في ما عدا ذلك" +#: data/org.gnome.mutter.gschema.xml.in:50 +msgid "Workspaces only on primary" +msgstr "" -#: ../src/core/all-keybindings.h:358 -msgid "Raise window above other windows" -msgstr "ارفع النافذة فوق النوافذ الأخرى" +#: data/org.gnome.mutter.gschema.xml.in:51 +msgid "" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." +msgstr "" -#: ../src/core/all-keybindings.h:360 -msgid "Lower window below other windows" -msgstr "اخفض النافذة تحت النوافذ الأخرى" +#: data/org.gnome.mutter.gschema.xml.in:59 +msgid "No tab popup" +msgstr "" -#: ../src/core/all-keybindings.h:364 -msgid "Maximize window vertically" -msgstr "كبّر النافذة عموديا" +#: data/org.gnome.mutter.gschema.xml.in:60 +msgid "" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." +msgstr "" -#: ../src/core/all-keybindings.h:368 -msgid "Maximize window horizontally" -msgstr "كبّر النافذة أفقيا" +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "" -#: ../src/core/all-keybindings.h:372 -msgid "Move window to north-west (top left) corner" -msgstr "انقل النافذة للزاوية شمال-غربي الشاشة (أعلى اليسار)" +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" -#: ../src/core/all-keybindings.h:375 -msgid "Move window to north-east (top right) corner" -msgstr "انقل النافذة للزاوية شمال-شرقي الشاشة (أعلى اليمين)" +#: data/org.gnome.mutter.gschema.xml.in:79 +msgid "Draggable border width" +msgstr "" -#: ../src/core/all-keybindings.h:378 -msgid "Move window to south-west (bottom left) corner" -msgstr "انقل النافذة للزاوية جنوب-غرب الشاشة (أدنى اليسار)" +#: data/org.gnome.mutter.gschema.xml.in:80 +msgid "" +"The amount of total draggable borders. If the theme’s visible borders are " +"not enough, invisible borders will be added to meet this value." +msgstr "" -#: ../src/core/all-keybindings.h:381 -msgid "Move window to south-east (bottom right) corner" -msgstr "انقل النافذة للزاوية جنوب-شرق الشاشة (أدنى اليمين)" +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "" -#: ../src/core/all-keybindings.h:385 -msgid "Move window to north (top) side of screen" -msgstr "انقل النافذة للجانب الشمالي من الشاشة (فوق)" +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" -#: ../src/core/all-keybindings.h:388 -msgid "Move window to south (bottom) side of screen" -msgstr "انقل النافذة للجانب الجنوبي من الشاشة (تحت)" +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "" -#: ../src/core/all-keybindings.h:391 -msgid "Move window to east (right) side of screen" -msgstr "انقل النافذة للجانب الشرقي من الشاشة (يمين)" +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" -#: ../src/core/all-keybindings.h:394 -msgid "Move window to west (left) side of screen" -msgstr "انقل النافذة للجانب الغربي من الشاشة (يسار)" +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "" -#: ../src/core/all-keybindings.h:397 -msgid "Move window to center of screen" -msgstr "انقل النافذة إلى وسط الشاشة" +#: data/org.gnome.mutter.gschema.xml.in:108 +msgid "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart." +msgstr "" -#: ../src/core/bell.c:302 -msgid "Bell event" -msgstr "حدث جرس" +#: data/org.gnome.mutter.gschema.xml.in:141 +msgid "Select window from tab popup" +msgstr "" -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "طلب معلومات نافذة مجهول: %d" +#: data/org.gnome.mutter.gschema.xml.in:146 +msgid "Cancel tab popup" +msgstr "" -#. Translators: %s is a window title -#: ../src/core/delete.c:94 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> لا يستجيب" +#: data/org.gnome.mutter.gschema.xml.in:151 +#, fuzzy +msgid "Switch monitor configurations" +msgstr "غيّر الشاشة" -#: ../src/core/delete.c:99 -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "ربما ترغب في الانتظار قليلا ليُكمِل أو إجبار التطبيق على الإنهاء كُلّية." +#: data/org.gnome.mutter.gschema.xml.in:156 +msgid "Rotates the built-in monitor configuration" +msgstr "" -#: ../src/core/delete.c:108 -msgid "_Wait" -msgstr "ا_نتظر" +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +#, fuzzy +msgid "Switch to VT 1" +msgstr "انتقل إلى مساحة العمل 1" -#: ../src/core/delete.c:108 -msgid "_Force Quit" -msgstr "أ_جبر الإنهاء" +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +#, fuzzy +msgid "Switch to VT 2" +msgstr "انتقل إلى مساحة العمل 2" -#: ../src/core/display.c:365 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "الامتداد %s مفقود، لكنه مطلوب للتركيب" +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +#, fuzzy +msgid "Switch to VT 3" +msgstr "انتقل إلى مساحة العمل 3" -#: ../src/core/display.c:431 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "فشل فتح عرض نظام نوافذ إكس '%s'\n" +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +#, fuzzy +msgid "Switch to VT 4" +msgstr "انتقل إلى مساحة العمل 4" -#: ../src/core/keybindings.c:759 -#, c-format +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +#, fuzzy +msgid "Switch to VT 5" +msgstr "انتقل إلى مساحة العمل 5" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +#, fuzzy +msgid "Switch to VT 6" +msgstr "انتقل إلى مساحة العمل 6" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +#, fuzzy +msgid "Switch to VT 7" +msgstr "انتقل إلى مساحة العمل 7" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +#, fuzzy +msgid "Switch to VT 8" +msgstr "انتقل إلى مساحة العمل 8" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +#, fuzzy +msgid "Switch to VT 9" +msgstr "انتقل إلى مساحة العمل 9" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +#, fuzzy +msgid "Switch to VT 10" +msgstr "انتقل إلى مساحة العمل 10" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +#, fuzzy +msgid "Switch to VT 11" +msgstr "انتقل إلى مساحة العمل 11" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +#, fuzzy +msgid "Switch to VT 12" +msgstr "انتقل إلى مساحة العمل 12" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow grabs with Xwayland" +msgstr "" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "يستعمل برنامج آخر المفتاح %s بالفعل مع المغيرين %x كرابط\n" +"Allow keyboard grabs issued by X11 applications running in Xwayland to be " +"taken into account. For a X11 grab to be taken into account under Wayland, " +"the client must also either send a specific X11 ClientMessage to the root " +"window or be among the applications white-listed in key “xwayland-grab-" +"access-rules”." +msgstr "" -#. Displayed when a keybinding which is -#. * supposed to launch a program fails. -#. -#: ../src/core/keybindings.c:2468 -#, c-format +#: data/org.gnome.mutter.wayland.gschema.xml.in:77 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:78 msgid "" -"There was an error running <tt>%s</tt>:\n" -"\n" -"%s" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." msgstr "" -"حصل خطأ عند تشغيل <tt>%s</tt>:\n" -"\n" -"%s." -#: ../src/core/keybindings.c:2558 +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. +#. +#: src/backends/meta-input-settings.c:2424 +#, c-format +msgid "Mode Switch (Group %d)" +msgstr "تغيير الأوضاع (مجموعة %d)" + +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2447 +msgid "Switch monitor" +msgstr "غيّر الشاشة" + +#: src/backends/meta-input-settings.c:2449 +msgid "Show on-screen help" +msgstr "اعرض المساعدة على الشاشة" + +#: src/backends/meta-monitor-manager.c:955 +msgid "Built-in display" +msgstr "شاشة مدمجة" + +#: src/backends/meta-monitor-manager.c:987 +msgid "Unknown" +msgstr "غير معروفة" + +#: src/backends/meta-monitor-manager.c:989 +msgid "Unknown Display" +msgstr "شاشة غير معروفة" + +#: src/backends/meta-monitor-manager.c:997 #, c-format -msgid "No command %d has been defined.\n" -msgstr "لم يُعرّف أمر %d.\n" +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" -#: ../src/core/keybindings.c:3570 +#: src/backends/meta-monitor-manager.c:1005 #, c-format -msgid "No terminal command has been defined.\n" -msgstr "لم يُعرّف أمر طرفيّة.\n" +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" -#: ../src/core/main.c:206 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:482 +#, c-format +msgid "" +"Another compositing manager is already running on screen %i on display “%s”." +msgstr "يعمل مدير مزج آخر على الشاشة %i و العرض ”%s“." + +#: src/core/bell.c:192 +msgid "Bell event" +msgstr "حدث جرس" + +#: src/core/main.c:185 msgid "Disable connection to session manager" msgstr "عطّل الاتصال بمدير الجلسة" -#: ../src/core/main.c:212 +#: src/core/main.c:191 msgid "Replace the running window manager" msgstr "استبدل بمدير النوافذ الذي يعمل" -#: ../src/core/main.c:218 +#: src/core/main.c:197 msgid "Specify session management ID" msgstr "حدّد رقم هويّة إدارة الجلسة" -#: ../src/core/main.c:223 +#: src/core/main.c:202 msgid "X Display to use" msgstr "معراض س الذي سيستعمل" -#: ../src/core/main.c:229 +#: src/core/main.c:208 msgid "Initialize session from savefile" msgstr "ابدأ الجلسة من ملف محفوظ" -#: ../src/core/main.c:235 +#: src/core/main.c:214 msgid "Make X calls synchronous" msgstr "اجعل نداءات س متزامنة" -#: ../src/core/main.c:508 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "فشلت قراءة دليل السِمات : %s\n" +#: src/core/main.c:221 +msgid "Run as a wayland compositor" +msgstr "" + +#: src/core/main.c:227 +msgid "Run as a nested compositor" +msgstr "" -#: ../src/core/main.c:524 +#: src/core/main.c:233 +msgid "Run wayland compositor without starting Xwayland" +msgstr "" + +#: src/core/main.c:241 +msgid "Run as a full display server, rather than nested" +msgstr "" + +#: src/core/main.c:247 +msgid "Run with X11 backend" +msgstr "" + +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:151 #, c-format +msgid "“%s” is not responding." +msgstr "”‏%s“ لا يستجيب." + +#: src/core/meta-close-dialog-default.c:153 +msgid "Application is not responding." +msgstr "لا يستجيب التطبيق" + +#: src/core/meta-close-dialog-default.c:158 msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "تعذّر إيجاد سِمة! تأكد من وجود %s و احتواءه على السِمات المعتادة.\n" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." +msgstr "ربما ترغب في الانتظار قليلا ليُكمِل أو إجبار التطبيق على الإنهاء كُلّية." + +#: src/core/meta-close-dialog-default.c:165 +msgid "_Force Quit" +msgstr "أ_جبر الإنهاء" -#: ../src/core/muffin.c:42 +#: src/core/meta-close-dialog-default.c:165 +msgid "_Wait" +msgstr "ا_نتظر" + +#: src/core/mutter.c:38 #, c-format msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" "This is free software; see the source for copying conditions.\n" "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " "PARTICULAR PURPOSE.\n" @@ -449,1397 +626,1068 @@ msgstr "" "هذا برنامج حر، راجع المصدر لشروط النسخ.\n" "لا يوجد أي ضمان: و لا حتى ضمان قابلية التسويق أو المناسبة لأي هدف.\n" -#: ../src/core/muffin.c:56 +#: src/core/mutter.c:52 msgid "Print version" msgstr "اطبع الإصدارة" -#: ../src/core/muffin.c:62 -msgid "Comma-separated list of compositor plugins" -msgstr "قائمة بملحقات المزج مفصولة بفاصلة" - -#. -#. * We found it, but it was invalid. Complain. -#. * -#. * FIXME: This replicates the original behaviour, but in the future -#. * we might consider reverting invalid keys to their original values. -#. * (We know the old value, so we can look up a suitable string in -#. * the symtab.) -#. * -#. * (Empty comment follows so the translators don't see this.) -#. -#. -#: ../src/core/prefs.c:536 ../src/core/prefs.c:697 -#, c-format -msgid "GConf key '%s' is set to an invalid value\n" -msgstr "مفتاح GConf '%s' مضبوط لقيمة غير صحيحة\n" +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "ملحق مَتَر الذي سيُستخدم" -#: ../src/core/prefs.c:623 ../src/core/prefs.c:866 +#: src/core/prefs.c:1786 #, c-format -msgid "%d stored in GConf key %s is out of range %d to %d\n" -msgstr "%d المحفوظ في مفتاح GConf %s خارج المدى من %d إلى %d\n" +msgid "Workspace %d" +msgstr "مساحة العمل %d" -#: ../src/core/prefs.c:667 ../src/core/prefs.c:744 ../src/core/prefs.c:792 -#: ../src/core/prefs.c:856 ../src/core/prefs.c:1317 ../src/core/prefs.c:1333 -#: ../src/core/prefs.c:1350 ../src/core/prefs.c:1366 -#, c-format -msgid "GConf key \"%s\" is set to an invalid type\n" -msgstr "مفتاح GConf \"%s\" مضبوط لنوع غير صحيح\n" +#: src/core/util.c:121 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "جُمِّع مَتَر دون دعم للنمط المطنب\n" -#: ../src/core/prefs.c:1196 +#: src/wayland/meta-wayland-tablet-pad.c:567 #, c-format -msgid "GConf key %s is already in use and can't be used to override %s\n" +msgid "Mode Switch: Mode %d" msgstr "" -#: ../src/core/prefs.c:1255 +#: src/x11/meta-x11-display.c:666 #, c-format -msgid "Can't override GConf key, %s not found\n" +msgid "" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." msgstr "" +"الشاشة ”%s“ لها مدير نوافذ بالفعل، حاول استعمال خيار التبديل --replace لتحُلّ " +"محلّ مدير النوافذ الحالي." -#: ../src/core/prefs.c:1440 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" +#: src/x11/meta-x11-display.c:1008 +msgid "Failed to initialize GDK\n" msgstr "" -"عطّلت الحلول الجزئيّة للتطبيقات المعطوبة . ربما لن تتصرف بعض التطبيقات " -"بسلامة.\n" -#: ../src/core/prefs.c:1517 +#: src/x11/meta-x11-display.c:1032 #, c-format -msgid "Could not parse font description \"%s\" from GConf key %s\n" -msgstr "لا يمكن تحليل وصف الخط \"%s\" من مفتاح GConf %s\n" +msgid "Failed to open X Window System display “%s”\n" +msgstr "فشل فتح عرض نظام نوافذ إكس ”%s“\n" -#: ../src/core/prefs.c:1579 +#: src/x11/meta-x11-display.c:1113 #, c-format +msgid "Screen %d on display “%s” is invalid\n" +msgstr "الشاشة %d على العرض ”%s“ غير صحيحة\n" + +#: src/x11/session.c:1821 msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." msgstr "" -"\"%s\" الموجود في قاعدة بيانات الإعدادات ليس قيمة سليمة لمغير أزرار الفأرة\n" +"هذه النوافذ لا تدعم ” الضبط الحالي" إعادة تشغيلها يدويا عند الولوج " +"المرة القادمة." -#: ../src/core/prefs.c:2006 +#: src/x11/window-props.c:569 #, c-format -msgid "Error setting number of workspaces to %d: %s\n" -msgstr "خطأ عند تعيين عدد مساحات العمل لـ %d: %s\n" +msgid "%s (on %s)" +msgstr "%s (على %s)" -#: ../src/core/prefs.c:2190 ../src/core/prefs.c:2692 -#, c-format -msgid "Workspace %d" -msgstr "مساحة العمل %d" +#~ msgid "Move window one workspace to the left" +#~ msgstr "انقل النافذة مساحة عمل واحدة إلى اليسار" -#: ../src/core/prefs.c:2222 ../src/core/prefs.c:2400 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "" -"\"%s\" الموجود في قاعدة بيانات الإعدادات ليس قيمة سليمة لارتباط المفتاح \"%s" -"\"\n" +#~ msgid "Move window one workspace to the right" +#~ msgstr "انقل النافذة مساحة عمل واحدة إلى اليمين" -#: ../src/core/prefs.c:2773 -#, c-format -msgid "Error setting name for workspace %d to \"%s\": %s\n" -msgstr "خطأ عند تحديد اسم مساحة العمل %d لـ \"%s\": %s\n" +#~ msgid "Move to workspace left" +#~ msgstr "انقل لمساحة العمل على اليسار" -#: ../src/core/prefs.c:2987 -#, c-format -msgid "Error setting live hidden windows status status: %s\n" -msgstr "" +#~ msgid "Move to workspace right" +#~ msgstr "انقل لمساحة العمل على اليمين" -#: ../src/core/prefs.c:3015 -#, c-format -msgid "Error setting no tab popup status: %s\n" -msgstr "خطأ عند ضبط حالة لا لسان منبثق: %s\n" +#~ msgid "Toggle shaded state" +#~ msgstr "بدّل حالة الإخفاء" -#: ../src/core/screen.c:577 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "الشاشة %d على العرض '%s' غير صحيحة\n" +#~ msgid "Unknown window information request: %d" +#~ msgstr "طلب معلومات نافذة مجهول: %d" + +#~ msgid "Missing %s extension required for compositing" +#~ msgstr "الامتداد %s مفقود، لكنه مطلوب للتركيب" + +#~ msgid "" +#~ "Some other program is already using the key %s with modifiers %x as a " +#~ "binding\n" +#~ msgstr "يستعمل برنامج آخر المفتاح %s بالفعل مع المغيرين %x كرابط\n" + +#~ msgid "\"%s\" is not a valid accelerator\n" +#~ msgstr "‏\"%s\" ليس اختصارا صحيحا\n" + +#~ msgid "Failed to scan themes directory: %s\n" +#~ msgstr "فشلت قراءة دليل السِمات : %s\n" + +#~ msgid "" +#~ "Could not find a theme! Be sure %s exists and contains the usual themes.\n" +#~ msgstr "تعذّر إيجاد سِمة! تأكد من وجود %s و احتواءه على السِمات المعتادة.\n" + +#~ msgid "" +#~ "Workarounds for broken applications disabled. Some applications may not " +#~ "behave properly.\n" +#~ msgstr "" +#~ "عطّلت الحلول الجزئيّة للتطبيقات المعطوبة . ربما لن تتصرف بعض التطبيقات " +#~ "بسلامة.\n" + +#~ msgid "Could not parse font description \"%s\" from GSettings key %s\n" +#~ msgstr "لا يمكن تحليل وصف الخط \"%s\" من مفتاح GSettings‏ %s\n" + +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" +#~ msgstr "" +#~ "\"%s\" الموجود في قاعدة بيانات الإعدادات ليس قيمة سليمة لمغير أزرار " +#~ "الفأرة\n" + +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for " +#~ "keybinding \"%s\"\n" +#~ msgstr "" +#~ "\"%s\" الموجود في قاعدة بيانات الإعدادات ليس قيمة سليمة لارتباط المفتاح " +#~ "\"%s\"\n" + +#~ msgid "" +#~ "Could not acquire window manager selection on screen %d display \"%s\"\n" +#~ msgstr "لا يمكن الحصول على اختيار مدير النوافذ على الشاشة %d العرض \"%s\"\n" + +#~ msgid "Screen %d on display \"%s\" already has a window manager\n" +#~ msgstr "الشاشة %d على العرض \"%s\" لها مدير نوافذ بالفعل\n" + +#~ msgid "Could not release screen %d on display \"%s\"\n" +#~ msgstr "لا يمكن ترك الشاشة %d على العرض \"%s\"\n" + +#~ msgid "Could not create directory '%s': %s\n" +#~ msgstr "لا يمكن إنشاء الدليل '%s': %s\n" + +#~ msgid "Could not open session file '%s' for writing: %s\n" +#~ msgstr "لا يمكن فتح ملف الجلسة '%s' لكتابة: %s\n" + +#~ msgid "Error writing session file '%s': %s\n" +#~ msgstr "خطأ عند كتابة ملف الجلسة '%s': %s\n" + +#~ msgid "Error closing session file '%s': %s\n" +#~ msgstr "خطأ عند غلق ملف الجلسة '%s': %s\n" + +#~ msgid "Failed to parse saved session file: %s\n" +#~ msgstr "خطأ عند تحليل ملف الجلسة المحفوظ: %s\n" + +#~ msgid "<mutter_session> attribute seen but we already have the session ID" +#~ msgstr "صفة <mutter_session> مرئية لكن لدينا هوية الجلسة بالفعل" + +#~ msgid "Unknown attribute %s on <%s> element" +#~ msgstr "صفة مجهولة %s على عنصر <%s>" + +#~ msgid "nested <window> tag" +#~ msgstr "وسْم <window> معشّش" + +#~ msgid "Unknown element %s" +#~ msgstr "عنصر مجهول %s" + +#~ msgid "Failed to open debug log: %s\n" +#~ msgstr "فشل فتح سِجِلّ التنقيح: %s\n" + +#~ msgid "Failed to fdopen() log file %s: %s\n" +#~ msgstr "فشل fdopen() ملف الرسائل %s: %s\n" + +#~ msgid "Opened log file %s\n" +#~ msgstr "فُتِح ملف السِّجِل %s\n" + +#~ msgid "Window manager: " +#~ msgstr "مدير النوافذ: " + +#~ msgid "Bug in window manager: " +#~ msgstr "علّة في مدير النوافذ: " + +#~ msgid "Window manager warning: " +#~ msgstr "تحذير مدير النوافذ: " + +#~ msgid "Window manager error: " +#~ msgstr "خطأ مدير النوافذ: " + +#~ msgid "" +#~ "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " +#~ "window as specified in the ICCCM.\n" +#~ msgstr "" +#~ "ضبطت النافذة %s SM_CLIENT_ID على نفسه، عوض ضبطه على نافذةWM_CLIENT_LEADER " +#~ "مثل ما هو محدد من طرف الـ ICCCM.\n" + +#~ msgid "" +#~ "Window %s sets an MWM hint indicating it isn't resizable, but sets min " +#~ "size %d x %d and max size %d x %d; this doesn't make much sense.\n" +#~ msgstr "" +#~ "ضبطت النافذة %s تلميحة MWM يدل على انه لا يمكن تحجيمها، لكنها تضبط الحجم " +#~ "الأدنى %d x %d و الحجم الأقصى %d x %d، هذا ليس له أي معنى.\n" + +#~ msgid "Application set a bogus _NET_WM_PID %lu\n" +#~ msgstr "ضبط التطبيق رمز NET_WM_PID غير مفهوم %lu\n" + +#~ msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +#~ msgstr "نافذة WM_TRANSIENT_FOR 0x%lx غير صحيحة ل %s.\n" + +#, fuzzy +#~ msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" +#~ msgstr "نافذة WM_TRANSIENT_FOR 0x%lx غير صحيحة ل %s.\n" + +#~ msgid "" +#~ "Window 0x%lx has property %s\n" +#~ "that was expected to have type %s format %d\n" +#~ "and actually has type %s format %d n_items %d.\n" +#~ "This is most likely an application bug, not a window manager bug.\n" +#~ "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +#~ msgstr "" +#~ "للنافذة 0x%lx الخاصية %s\n" +#~ "التي كام مرتقبا ان تكون لها النوع %s التهيئة %d\n" +#~ "لكنها فعليا لها النوع %s التهيئة %d n_items %d.\n" +#~ "هذا خلل تطبيق، لا خلل في مدير النوافذ.\n" +#~ "للنافذة العنوان =\"%s\" الطبقة=\"%s\" الاسم=\"%s\"\n" + +#~ msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +#~ msgstr "الخاصية %s على النافذة 0x%lx تحتوي UTF-8 غير صحيح\n" + +#~ msgid "" +#~ "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the " +#~ "list\n" +#~ msgstr "" +#~ "الخاصية %s على النافذة 0x%lx تحتوي UTF-8 غير صحيح للعنصر %d في القائمة\n" + +#~ msgid "Mi_nimize" +#~ msgstr "_صغّر" + +#~ msgid "Ma_ximize" +#~ msgstr "_كبّر" + +#~ msgid "Unma_ximize" +#~ msgstr "ألغ التكبي_ر" + +#~ msgid "Roll _Up" +#~ msgstr "لف إلى ال_أعلى" + +#~ msgid "_Unroll" +#~ msgstr "ال_غي اللف" + +#~ msgid "_Move" +#~ msgstr "ا_نقل" + +#~ msgid "_Resize" +#~ msgstr "_حجّم" + +#~ msgid "Move Titlebar On_screen" +#~ msgstr "انقل _شريط العنوان على الشاشة" + +#~ msgid "Always on _Top" +#~ msgstr "دائما في ال_قمّة" + +#~ msgid "_Always on Visible Workspace" +#~ msgstr "دائمًا على مساحة العمل ال_مرئيّة" + +#~ msgid "_Only on This Workspace" +#~ msgstr "فقط على مساحة العمل _هذه" + +#~ msgid "Move to Workspace _Left" +#~ msgstr "انقل لمساحة العمل على ال_يسار" + +#~ msgid "Move to Workspace R_ight" +#~ msgstr "انقل لمساحة العمل على الي_مين" + +#~ msgid "Move to Workspace _Up" +#~ msgstr "انقل لمساحة العمل _فوق" + +#~ msgid "Move to Workspace _Down" +#~ msgstr "انقل لمساحة العمل _تحت" + +#~ msgid "_Close" +#~ msgstr "أ_غلق" + +#~ msgid "Workspace %d%n" +#~ msgstr "مساحة العمل %d%n" + +#~ msgid "Workspace 1_0" +#~ msgstr "مساحة العمل _10" + +#~ msgid "Workspace %s%d" +#~ msgstr "مساحة العمل %s%d" + +#~ msgid "Move to Another _Workspace" +#~ msgstr "انقل ل_مساحة عمل أخرى" + +#~ msgid "Shift" +#~ msgstr "Shift" + +#~ msgid "Ctrl" +#~ msgstr "Ctrl" + +#~ msgid "Alt" +#~ msgstr "Alt" + +#~ msgid "Meta" +#~ msgstr "Meta" + +#~ msgid "Super" +#~ msgstr "Super" + +#~ msgid "Hyper" +#~ msgstr "Hyper" + +#~ msgid "Mod2" +#~ msgstr "Mod2" + +#~ msgid "Mod3" +#~ msgstr "Mod3" + +#~ msgid "Mod4" +#~ msgstr "Mod4" + +#~ msgid "Mod5" +#~ msgstr "Mod5" + +#~ msgid "%d x %d" +#~ msgstr "%d × %d" + +#~ msgid "top" +#~ msgstr "أعلى" + +#~ msgid "bottom" +#~ msgstr "أسفل" + +#~ msgid "left" +#~ msgstr "يسار" + +#~ msgid "right" +#~ msgstr "يمين" + +#~ msgid "frame geometry does not specify \"%s\" dimension" +#~ msgstr "هندسة الإطار لا تخصص البعد \"%s\"" + +#~ msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" +#~ msgstr "هندسة الإطار لا تخصص البعد \"%s\" للحد \"%s\"" + +#~ msgid "Button aspect ratio %g is not reasonable" +#~ msgstr "النسبة الجانبية للزر %g غير معقولة" + +#~ msgid "Frame geometry does not specify size of buttons" +#~ msgstr "هندسة الإطار لا تخصص حجم الأزرار" + +#~ msgid "Gradients should have at least two colors" +#~ msgstr "يجب أن يكون للتّدرُّجات لونان على الأقل" + +#, fuzzy +#~ msgid "" +#~ "GTK custom color specification must have color name and fallback in " +#~ "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" +#~ msgstr "" +#~ "يحب أن يكون لتخصيص حالة ألوان جتك قوس غلق قائم بعد الحالة/ مثال gtk:" +#~ "fg[NORMAL]، NORMAL هنا هو الحالة، لا يمكن تحليل \"%s\"" + +#, fuzzy +#~ msgid "" +#~ "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " +#~ "fit the format" +#~ msgstr "" +#~ "تهيئة التظليل هي \"تظليل/اللون_الأساسي/العامل\"، \"%s\" لا يناسب التهيئة" + +#~ msgid "" +#~ "GTK color specification must have the state in brackets, e.g. gtk:" +#~ "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "يجب أن تكون حالة تخصيصات ألوان جتك في قوسان قائمان، مثال gtk:fg[NORMAL] " +#~ "NORMAL هنا هو الحالة، لا يمكن تحليل \"%s\"" + +#~ msgid "" +#~ "GTK color specification must have a close bracket after the state, e.g. " +#~ "gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "يحب أن يكون لتخصيص حالة ألوان جتك قوس غلق قائم بعد الحالة/ مثال gtk:" +#~ "fg[NORMAL]، NORMAL هنا هو الحالة، لا يمكن تحليل \"%s\"" + +#~ msgid "Did not understand state \"%s\" in color specification" +#~ msgstr "لم تفهم الحالة \"%s\" في تخصيص الألوان" + +#~ msgid "Did not understand color component \"%s\" in color specification" +#~ msgstr "لم يفهم جزء اللون \"%s\" في تخصيص اللون" + +#~ msgid "" +#~ "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit " +#~ "the format" +#~ msgstr "" +#~ "تهيئة الخلط \"blend/bg_color/fg_color/alpha\"، \"%s\"لا يناسب التهيئة" -#: ../src/core/screen.c:593 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"الشاشة %d على العرض \"%s\" لها مدير نوافذ بالفعل، حاول استعمال خيار التبديل " -"--replace لتحُلّ محلّ مدير النوافذ الحالي.\n" +#~ msgid "Could not parse alpha value \"%s\" in blended color" +#~ msgstr "لا يمكن تحليل قيمة الشفافية \"%s\" في اللون المخلط" -#: ../src/core/screen.c:620 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "لا يمكن الحصول على اختيار مدير النوافذ على الشاشة %d العرض \"%s\"\n" +#~ msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" +#~ msgstr "قيمة الشفافية \"%s\" في اللون المخلوط ليست بين 0.0 و 1.0" -#: ../src/core/screen.c:675 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "الشاشة %d على العرض \"%s\" لها مدير نوافذ بالفعل\n" +#~ msgid "" +#~ "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the " +#~ "format" +#~ msgstr "" +#~ "تهيئة التظليل هي \"تظليل/اللون_الأساسي/العامل\"، \"%s\" لا يناسب التهيئة" -#: ../src/core/screen.c:860 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "لا يمكن ترك الشاشة %d على العرض \"%s\"\n" +#~ msgid "Could not parse shade factor \"%s\" in shaded color" +#~ msgstr "لا يمكن تحليل عامل التظليل \"%s\" في اللون المظلل" -#: ../src/core/session.c:863 ../src/core/session.c:870 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "لا يمكن إنشاء الدليل '%s': %s\n" +#~ msgid "Shade factor \"%s\" in shaded color is negative" +#~ msgstr "عامل التظليل \"%s\" في اللون المظلل سلبي" -#: ../src/core/session.c:880 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "لا يمكن فتح ملف الجلسة '%s' لكتابة: %s\n" +#~ msgid "Could not parse color \"%s\"" +#~ msgstr "لا يمكن تحليل اللون \"%s\"" -#: ../src/core/session.c:1021 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "خطأ عند كتابة ملف الجلسة '%s': %s\n" +#~ msgid "Coordinate expression contains character '%s' which is not allowed" +#~ msgstr "تعبير الإحداثيّات يحتوي على الرمز '%s' الممنوع" -#: ../src/core/session.c:1026 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "خطأ عند غلق ملف الجلسة '%s': %s\n" +#~ msgid "" +#~ "Coordinate expression contains floating point number '%s' which could not " +#~ "be parsed" +#~ msgstr "تعبير الإحداثيّات يحتوي على عدد نقطة متغيرة '%s' تعذّر تحليله" -#: ../src/core/session.c:1156 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "خطأ عند تحليل ملف الجلسة المحفوظ: %s\n" +#~ msgid "" +#~ "Coordinate expression contains integer '%s' which could not be parsed" +#~ msgstr "تعبير الإحداثيّات يحتوي على عدد صحيح '%s' تعذّر تحليله" -#: ../src/core/session.c:1205 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "صفة <muffin_session> مرئية لكن لدينا هوية الجلسة بالفعل" +#~ msgid "" +#~ "Coordinate expression contained unknown operator at the start of this " +#~ "text: \"%s\"" +#~ msgstr "تعبير الإحداثيّات يحتوي على مقسوم مجهول عند بداية هذا النص: \"%s\"" -#: ../src/core/session.c:1218 ../src/core/session.c:1293 -#: ../src/core/session.c:1325 ../src/core/session.c:1397 -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "صفة مجهولة %s على عنصر <%s>" +#~ msgid "Coordinate expression was empty or not understood" +#~ msgstr "تعبير الإحداثيّات فارغ أو لم يفهم" -#: ../src/core/session.c:1235 -#, c-format -msgid "nested <window> tag" -msgstr "وسْم <window> معشّش" +#~ msgid "Coordinate expression results in division by zero" +#~ msgstr "تعبير الإحداثيّات ينتُج عند القسمة على صفر" -#: ../src/core/session.c:1477 -#, c-format -msgid "Unknown element %s" -msgstr "عنصر مجهول %s" +#~ msgid "" +#~ "Coordinate expression tries to use mod operator on a floating-point number" +#~ msgstr "تعبير الإحداثيّاتيّات يحاول استعمال مقسوم mod على عدد فاصلة متحرّكة" -#: ../src/core/session.c:1829 -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" -"هذه النوافذ لا تدعم "احفظ الضبط الحالي" يجب إعادة تشغيلها يدويا " -"عند الولوج المرة القادمة." +#~ msgid "" +#~ "Coordinate expression has an operator \"%s\" where an operand was expected" +#~ msgstr "تعبير الإحداثيّات له مقسوم \"%s\" بالرغم من ترقبه قاسم" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "فشل فتح سِجِلّ التنقيح: %s\n" +#~ msgid "Coordinate expression had an operand where an operator was expected" +#~ msgstr "تعبير الإحداثيّات له قاسم بالرغم من ترقبه لمقسوم" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "فشل fdopen() ملف الرسائل %s: %s\n" +#~ msgid "Coordinate expression ended with an operator instead of an operand" +#~ msgstr "انتهى تعبير الإحداثيّات بمقسوم عوضا عن قاسم" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "فُتِح ملف السِّجِل %s\n" +#~ msgid "" +#~ "Coordinate expression has operator \"%c\" following operator \"%c\" with " +#~ "no operand in between" +#~ msgstr "لتعبير الإحداثيّات مقسوم \"%c\" يتبع القاسم \"%c\" بدون قاسم بينهما" -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "جُمِّع مَتَر دون دعم للنمط المطنب\n" +#~ msgid "Coordinate expression had unknown variable or constant \"%s\"" +#~ msgstr "كان لتعبير الإحداثيّات متغير أو ثابت \"%s\"" -#: ../src/core/util.c:286 -msgid "Window manager: " -msgstr "مدير النوافذ: " +#~ msgid "Coordinate expression parser overflowed its buffer." +#~ msgstr "غمر محلّل تعبير الإحداثيّات مجاله" -#: ../src/core/util.c:434 -msgid "Bug in window manager: " -msgstr "علّة في مدير النوافذ: " +#~ msgid "" +#~ "Coordinate expression had a close parenthesis with no open parenthesis" +#~ msgstr "كان لتعبير الإحداثيّات قوس غلق بدون قوس فتح" -#: ../src/core/util.c:467 -msgid "Window manager warning: " -msgstr "تحذير مدير النوافذ: " +#~ msgid "" +#~ "Coordinate expression had an open parenthesis with no close parenthesis" +#~ msgstr "كان لتعبير الإحداثيات قوس فتح بدون قوس غلق" -#: ../src/core/util.c:495 -msgid "Window manager error: " -msgstr "خطأ مدير النوافذ: " +#~ msgid "Coordinate expression doesn't seem to have any operators or operands" +#~ msgstr "تعبير الإحداثيات لا يملك قاسمات و مقسومات" -#. Translators: This is the title used on dialog boxes -#: ../src/core/util.c:616 ../src/muffin.desktop.in.h:1 -#: ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "مَتَر" +#~ msgid "Theme contained an expression that resulted in an error: %s\n" +#~ msgstr "احتوت السِمة على تعبير ادى الى خطأ: %s\n" -#. first time through -#: ../src/core/window.c:6550 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"ضبطت النافذة %s SM_CLIENT_ID على نفسه، عوض ضبطه على نافذةWM_CLIENT_LEADER " -"مثل ما هو محدد من طرف الـ ICCCM.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7213 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %" -"d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"ضبطت النافذة %s تلميحة MWM يدل على انه لا يمكن تحجيمها، لكنها تضبط الحجم " -"الأدنى %d x %d و الحجم الأقصى %d x %d، هذا ليس له أي معنى.\n" +#~ msgid "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " +#~ "specified for this frame style" +#~ msgstr "" +#~ "يجب تخصيص <button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> " +#~ "لأسلوب الإطار هذا" -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "ضبط التطبيق رمز NET_WM_PID غير مفهوم %lu\n" +#~ msgid "" +#~ "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/" +#~ ">" +#~ msgstr "" +#~ "<frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/> مفقود" -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (على %s)" +#~ msgid "Failed to load theme \"%s\": %s\n" +#~ msgstr "فشل تحميل السِمة \"%s\": %s\n" -#: ../src/core/window-props.c:1479 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "نافذة WM_TRANSIENT_FOR 0x%lx غير صحيحة ل %s.\n" +#~ msgid "No <%s> set for theme \"%s\"" +#~ msgstr "لا <%s> ضبط للسِمة \"%s\"" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"للنافذة 0x%lx الخاصية %s\n" -"التي كام مرتقبا ان تكون لها النوع %s التهيئة %d\n" -"لكنها فعليا لها النوع %s التهيئة %d n_items %d.\n" -"هذا خلل تطبيق، لا خلل في مدير النوافذ.\n" -"للنافذة العنوان =\"%s\" الطبقة=\"%s\" الاسم=\"%s\"\n" +#~ msgid "" +#~ "No frame style set for window type \"%s\" in theme \"%s\", add a <window " +#~ "type=\"%s\" style_set=\"whatever\"/> element" +#~ msgstr "" +#~ "لا أسلوب إطار مضبوط لنوع النافذة \"%s\" في السِمة \"%s\"، اضف عنصر <window " +#~ "type=\"%s\" style_set=\"whatever\"/>" -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "الخاصية %s على النافذة 0x%lx تحتوي UTF-8 غير صحيح\n" +#~ msgid "" +#~ "User-defined constants must begin with a capital letter; \"%s\" does not" +#~ msgstr "" +#~ "الثوابت المعرفة من طرف المستخدم يجب أن تبدأ بحروف كبيرة، \"%s\" لا يبدأ " +#~ "بذلك" -#: ../src/core/xprops.c:494 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"الخاصية %s على النافذة 0x%lx تحتوي UTF-8 غير صحيح للعنصر %d في القائمة\n" +#~ msgid "Constant \"%s\" has already been defined" +#~ msgstr "عُرِّف الثابت \"%s\" بالفعل" -#: ../src/muffin.schemas.in.h:1 -msgid "Attach modal dialogs" -msgstr "" +#~ msgid "No \"%s\" attribute on element <%s>" +#~ msgstr "لا صفة \"%s\" على العنصر <%s>" -#: ../src/muffin.schemas.in.h:2 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" +#~ msgid "Line %d character %d: %s" +#~ msgstr "سطر %d محْرف %d: %s" -#: ../src/muffin.schemas.in.h:3 -msgid "Live Hidden Windows" -msgstr "" +#~ msgid "Attribute \"%s\" repeated twice on the same <%s> element" +#~ msgstr "الصفة \"%s\" معادة مرتان في نفس العنصر <%s>" -#: ../src/muffin.schemas.in.h:4 -msgid "Modifier to use for extended window management operations" -msgstr "المغير الذي سيُستعمل لتمديد عمليات إدارة النوافذ " +#~ msgid "Attribute \"%s\" is invalid on <%s> element in this context" +#~ msgstr "الصفة \"%s\" مغلوطة في العنصر <%s> في هذا السياق" -#: ../src/muffin.schemas.in.h:5 -msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." -msgstr "" +#~ msgid "Could not parse \"%s\" as an integer" +#~ msgstr "تعذّر تحليل \"%s\" كعدد صحيح" -#: ../src/muffin.schemas.in.h:6 -msgid "" -"When true, instead of having independent titlebars, modal dialogs appear " -"attached to the titlebar of the parent window and are moved together with " -"the parent window." -msgstr "" +#~ msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +#~ msgstr "لم أفهم المحارف المتدلية \"%s\" في السلسلة \"%s\"" -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "الاستخدام: %s\n" +#~ msgid "Integer %ld must be positive" +#~ msgstr "العدد الصحيح %ld يجب أن يكون ايجابيا" -#: ../src/ui/frames.c:1099 -msgid "Close Window" -msgstr "أغلق النافذة" +#~ msgid "Integer %ld is too large, current max is %d" +#~ msgstr "العدد الصحيح %ld كبير جدا، الحد الأقصى هو %d" -#: ../src/ui/frames.c:1102 -msgid "Window Menu" -msgstr "قائمة النافذة" +#~ msgid "Could not parse \"%s\" as a floating point number" +#~ msgstr "لا يمكن تحليل \"%s\" كعدد فاصلة متحرّكة" -#: ../src/ui/frames.c:1105 -msgid "Minimize Window" -msgstr "صغّر النافذة" +#~ msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" +#~ msgstr "يجب أن تكون القيم البوليانيّة \"صحيح\" أو \"خاطئ\" لا \"%s\"" -#: ../src/ui/frames.c:1108 -msgid "Maximize Window" -msgstr "كبّر النافذة" +#~ msgid "Angle must be between 0.0 and 360.0, was %g\n" +#~ msgstr "يجب أن تكون الزاوية بين 0.0 و 360.0،وهي كانت%g\n" -#: ../src/ui/frames.c:1111 -msgid "Restore Window" -msgstr "استعد النّافذة" +#~ msgid "" +#~ "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" +#~ msgstr "" +#~ "يجب أن تكون الشفافية بين 0.0 (مختف) و 1.0 (دامس تماما)، وهي كانت %g\n" -#: ../src/ui/frames.c:1114 -msgid "Roll Up Window" -msgstr "لُفّ النافذة الأعلى" - -#: ../src/ui/frames.c:1117 -msgid "Unroll Window" -msgstr "ألغى لفّ النافذة" - -#: ../src/ui/frames.c:1120 -msgid "Keep Window On Top" -msgstr "ابقي النافذة على القمة" - -#: ../src/ui/frames.c:1123 -msgid "Remove Window From Top" -msgstr "احذف من القمّة" - -#: ../src/ui/frames.c:1126 -msgid "Always On Visible Workspace" -msgstr "دائما مساحة العمل المرئية" - -#: ../src/ui/frames.c:1129 -msgid "Put Window On Only One Workspace" -msgstr "ضع النافذة على مساحة عمل واحدة فقط" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "_صغّر" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "_كبّر" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "ألغ التكبي_ر" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "لف إلى ال_أعلى" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "ال_غي اللف" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "ا_نقل" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "_حجّم" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "انقل _شريط العنوان على الشاشة" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "دائما في ال_قمّة" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "فقط على مساحة العمل ال_مرئيّة" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "فقط على مساحة العمل _هذه" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "انقل لمساحة العمل على ال_يسار" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "انقل لمساحة العمل على الي_مين" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "انقل لمساحة العمل _فوق" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "انقل لمساحة العمل _تحت" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "أ_غلق" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "مساحة العمل %d%n" +#~ msgid "" +#~ "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," +#~ "large,x-large,xx-large)\n" +#~ msgstr "" +#~ "حجم عنوان غير سليم \"%s\" (يجب أن يكون واحد من xx-small,x-small,small," +#~ "medium,large,x-large,xx-large)\n" -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "مساحة العمل _10" +#~ msgid "<%s> name \"%s\" used a second time" +#~ msgstr "<%s> استُعمل الاسم \"%s\" للمرّة الثانية" -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "مساحة العمل %s%d" +#~ msgid "<%s> parent \"%s\" has not been defined" +#~ msgstr "<%s> لم يُعرّف الأب \"%s\"" -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "انقل ل_مساحة عمل أخرى" +#~ msgid "<%s> geometry \"%s\" has not been defined" +#~ msgstr "<%s> لم تُعرّف الهندسة \"%s\"" -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" +#~ msgid "<%s> must specify either a geometry or a parent that has a geometry" +#~ msgstr "يجب ان يخصص <%s> هندسة أو اب له هندسة" -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d × %d" +#~ msgid "You must specify a background for an alpha value to be meaningful" +#~ msgstr "يجب أن تحدّد خلفية ليصبح لقيمة ألفا معنى" -#: ../src/ui/theme.c:255 -msgid "top" -msgstr "أعلى" +#~ msgid "Unknown type \"%s\" on <%s> element" +#~ msgstr "نوع مجهول \"%s\" على عنصر <%s>" -#: ../src/ui/theme.c:257 -msgid "bottom" -msgstr "أسفل" +#~ msgid "Unknown style_set \"%s\" on <%s> element" +#~ msgstr "style_set مجهول \"%s\" على العنصر <%s>" -#: ../src/ui/theme.c:259 -msgid "left" -msgstr "يسار" +#~ msgid "Window type \"%s\" has already been assigned a style set" +#~ msgstr "اعطى لنوع النافذة \"%s\" مجموعة أساليب بالفعل" -#: ../src/ui/theme.c:261 -msgid "right" -msgstr "يمين" +#~ msgid "Element <%s> is not allowed below <%s>" +#~ msgstr "العنصر <%s> غير مسموح به تحت <%s>" -#: ../src/ui/theme.c:288 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "هندسة الإطار لا تخصص البعد \"%s\"" +#~ msgid "" +#~ "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio" +#~ "\" for buttons" +#~ msgstr "" +#~ "لا يمكن تخصيص \"button_width\"/\"button_height\" و \"aspect_ratio\" " +#~ "للأزرار" -#: ../src/ui/theme.c:307 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "هندسة الإطار لا تخصص البعد \"%s\" للحد \"%s\"" +#~ msgid "Distance \"%s\" is unknown" +#~ msgstr "المسافة \"%s\" مجهولة" -#: ../src/ui/theme.c:344 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "النسبة الجانبية للزر %g غير معقولة" +#~ msgid "Aspect ratio \"%s\" is unknown" +#~ msgstr "نسبة الجانب \"%s\" مجهولة" -#: ../src/ui/theme.c:356 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "هندسة الإطار لا تخصص حجم الأزرار" +#~ msgid "Border \"%s\" is unknown" +#~ msgstr "الحدّ \"%s\" مجهول" -#: ../src/ui/theme.c:1064 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "يجب أن يكون للتّدرُّجات لونان على الأقل" +#~ msgid "No \"start_angle\" or \"from\" attribute on element <%s>" +#~ msgstr "لا صفة \"start_angle\" أو \"from\" على العنصر <%s>" -#: ../src/ui/theme.c:1202 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"يجب أن تكون حالة تخصيصات ألوان جتك في قوسان قائمان، مثال gtk:fg[NORMAL] " -"NORMAL هنا هو الحالة، لا يمكن تحليل \"%s\"" +#~ msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" +#~ msgstr "لا صفة \"extent_angle\" أو \"to\" على العنصر <%s>" -#: ../src/ui/theme.c:1216 -#, c-format -msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"يحب أن يكون لتخصيص حالة ألوان جتك قوس غلق قائم بعد الحالة/ مثال gtk:fg" -"[NORMAL]، NORMAL هنا هو الحالة، لا يمكن تحليل \"%s\"" +#~ msgid "Did not understand value \"%s\" for type of gradient" +#~ msgstr "لم أفهم القيمة \"%s\" لنوع التدرّج" -#: ../src/ui/theme.c:1227 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "لم تفهم الحالة \"%s\" في تخصيص الألوان" +#~ msgid "Did not understand fill type \"%s\" for <%s> element" +#~ msgstr "لم أفهم نوع الملأ \"%s\" للعنصر <%s>" -#: ../src/ui/theme.c:1240 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "لم يفهم جزء اللون \"%s\" في تخصيص اللون" +#~ msgid "Did not understand state \"%s\" for <%s> element" +#~ msgstr "لم أفهم حالة \"%s\" العنصر <%s>" -#: ../src/ui/theme.c:1270 -#, c-format -msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" -msgstr "تهيئة الخلط \"blend/bg_color/fg_color/alpha\"، \"%s\"لا يناسب التهيئة" +#~ msgid "Did not understand shadow \"%s\" for <%s> element" +#~ msgstr "لم أفهم ظل \"%s\" العنصر <%s>" -#: ../src/ui/theme.c:1281 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "لا يمكن تحليل قيمة الشفافية \"%s\" في اللون المخلط" +#~ msgid "Did not understand arrow \"%s\" for <%s> element" +#~ msgstr "لم أفهم السهم \"%s\" للعنصر <%s>" -#: ../src/ui/theme.c:1291 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "قيمة الشفافية \"%s\" في اللون المخلوط ليست بين 0.0 و 1.0" +#~ msgid "No <draw_ops> called \"%s\" has been defined" +#~ msgstr "لم يعرف <draw_ops> مسمى \"%s\"" -#: ../src/ui/theme.c:1338 -#, c-format -msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "" -"تهيئة التظليل هي \"تظليل/اللون_الأساسي/العامل\"، \"%s\" لا يناسب التهيئة" +#~ msgid "Including draw_ops \"%s\" here would create a circular reference" +#~ msgstr "تضمين draw_ops \"%s\" هنا سينشئ مرجعا دائريا" -#: ../src/ui/theme.c:1349 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "لا يمكن تحليل عامل التظليل \"%s\" في اللون المظلل" +#~ msgid "Unknown position \"%s\" for frame piece" +#~ msgstr "موقع مجهول \"%s\" لقطعة الإطار" -#: ../src/ui/theme.c:1359 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "عامل التظليل \"%s\" في اللون المظلل سلبي" +#~ msgid "Frame style already has a piece at position %s" +#~ msgstr "أسلوب الإطار له قطعة في الموقع %s" -#: ../src/ui/theme.c:1388 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "لا يمكن تحليل اللون \"%s\"" +#~ msgid "No <draw_ops> with the name \"%s\" has been defined" +#~ msgstr "لم تعرف <draw_ops> بالاسم \"%s\"" -#: ../src/ui/theme.c:1646 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "تعبير الإحداثيّات يحتوي على الرمز '%s' الممنوع" +#~ msgid "Unknown function \"%s\" for button" +#~ msgstr "وظيفة مجهولة \"%s\" للزر" -#: ../src/ui/theme.c:1673 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "تعبير الإحداثيّات يحتوي على عدد نقطة متغيرة '%s' تعذّر تحليله" +#~ msgid "Button function \"%s\" does not exist in this version (%d, need %d)" +#~ msgstr "لا وجود لوظيفة الزر \"%s\" في هذه الإصدارة (%d، تحتاج %d)" -#: ../src/ui/theme.c:1687 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "تعبير الإحداثيّات يحتوي على عدد صحيح '%s' تعذّر تحليله" +#~ msgid "Unknown state \"%s\" for button" +#~ msgstr "حالة مجهولة \"%s\" للزر" -#: ../src/ui/theme.c:1809 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "تعبير الإحداثيّات يحتوي على مقسوم مجهول عند بداية هذا النص: \"%s\"" +#~ msgid "Frame style already has a button for function %s state %s" +#~ msgstr "أسلوب الإطار له بالفعل زر للوظيفة %s الحالة %s" -#: ../src/ui/theme.c:1866 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "تعبير الإحداثيّات فارغ أو لم يفهم" +#~ msgid "\"%s\" is not a valid value for focus attribute" +#~ msgstr "\"%s\" قيمة غير سليمة لصفة التركيز" -#: ../src/ui/theme.c:1977 ../src/ui/theme.c:1987 ../src/ui/theme.c:2021 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "تعبير الإحداثيّات ينتُج عند القسمة على صفر" +#~ msgid "\"%s\" is not a valid value for state attribute" +#~ msgstr "\"%s\" قيمة غير سليمة لصفة الحالة" -#: ../src/ui/theme.c:2029 -#, c-format -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "تعبير الإحداثيّاتيّات يحاول استعمال مقسوم mod على عدد فاصلة متحرّكة" +#~ msgid "A style called \"%s\" has not been defined" +#~ msgstr "لم يعرف أسلوب مسمى بـ \"%s\"" -#: ../src/ui/theme.c:2085 -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "تعبير الإحداثيّات له مقسوم \"%s\" بالرغم من ترقبه قاسم" +#~ msgid "\"%s\" is not a valid value for resize attribute" +#~ msgstr "\"%s\" ليس قيمة سليمة لصفة التحجيم" -#: ../src/ui/theme.c:2094 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "تعبير الإحداثيّات له قاسم بالرغم من ترقبه لمقسوم" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized/shaded " +#~ "states" +#~ msgstr "لا يجب أن تكون صفة \"التحجيم\" على عنصر <%s> لحالات التكبير/الاخفاء" -#: ../src/ui/theme.c:2102 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "انتهى تعبير الإحداثيّات بمقسوم عوضا عن قاسم" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized states" +#~ msgstr "لا يجب أن تكون صفة \"التحجيم\" على عنصر <%s> لحالات التكبير" -#: ../src/ui/theme.c:2112 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "لتعبير الإحداثيّات مقسوم \"%c\" يتبع القاسم \"%c\" بدون قاسم بينهما" +#~ msgid "Style has already been specified for state %s resize %s focus %s" +#~ msgstr "حُدّد بالفعل أسلوب للحالة %s التحجيم %s التركيز %s" -#: ../src/ui/theme.c:2263 ../src/ui/theme.c:2308 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "كان لتعبير الإحداثيّات متغير أو ثابت \"%s\"" +#~ msgid "Style has already been specified for state %s focus %s" +#~ msgstr "حُدّد بالفعل أسلوب للحالة %s التركيز %s" -#: ../src/ui/theme.c:2362 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "غمر محلّل تعبير الإحداثيّات مجاله" +#~ msgid "" +#~ "Can't have a two draw_ops for a <piece> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "لا يمكن ان يوجد draw_ops اثنان لعنصر <piece> (خصصت السِمة صفة draw_ops و " +#~ "عنصر <draw_ops>، أو عنصران محدّدان)" -#: ../src/ui/theme.c:2391 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "كان لتعبير الإحداثيّات قوس غلق بدون قوس فتح" +#~ msgid "" +#~ "Can't have a two draw_ops for a <button> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "لا يمكن ان يوجد draw_ops اثنان لعنصر <button> (خصصت السِمة صفة draw_ops و " +#~ "عنصر <draw_ops>، أو عنصران محدّدان)" -#: ../src/ui/theme.c:2455 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "كان لتعبير الإحداثيات قوس فتح بدون قوس غلق" +#~ msgid "" +#~ "Can't have a two draw_ops for a <menu_icon> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "لا يمكن ان يوجد draw_ops اثنان لعنصر<menu_icon> (خصصت السِمة صفة draw_ops " +#~ "و عنصر <draw_ops>، أو عنصران محدّدان)" -#: ../src/ui/theme.c:2466 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "تعبير الإحداثيات لا يملك قاسمات و مقسومات" +#~ msgid "Outermost element in theme must be <metacity_theme> not <%s>" +#~ msgstr "يجب أن يكون أخرج عنصر في السِمة <metacity_theme> لا <%s>" -#: ../src/ui/theme.c:2676 ../src/ui/theme.c:2696 ../src/ui/theme.c:2716 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "احتوت السِمة على تعبير ادى الى خطأ: %s\n" +#~ msgid "" +#~ "Element <%s> is not allowed inside a name/author/date/description element" +#~ msgstr "العنصر <%s> غير مسموح به داخل عنصر اسم/كاتب/تاريخ/وصف" -#: ../src/ui/theme.c:4410 -#, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" -"يجب تخصيص <button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> " -"لأسلوب الإطار هذا" +#~ msgid "Element <%s> is not allowed inside a <constant> element" +#~ msgstr "العنصر <%s> غير مسموح به داخل عنصر <constant>" -#: ../src/ui/theme.c:4940 ../src/ui/theme.c:4965 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" -"<frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/> مفقود" +#~ msgid "" +#~ "Element <%s> is not allowed inside a distance/border/aspect_ratio element" +#~ msgstr "العنصر <%s> غير مسموح به داخل عنصر مسافة/حد/aspect_ratio" -#: ../src/ui/theme.c:5013 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "فشل تحميل السِمة \"%s\": %s\n" +#~ msgid "Element <%s> is not allowed inside a draw operation element" +#~ msgstr "العنصر <%s> غير مسموح به داخل عنصر عملية متعادلة" -#: ../src/ui/theme.c:5149 ../src/ui/theme.c:5156 ../src/ui/theme.c:5163 -#: ../src/ui/theme.c:5170 ../src/ui/theme.c:5177 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "لا <%s> ضبط للسِمة \"%s\"" +#~ msgid "Element <%s> is not allowed inside a <%s> element" +#~ msgstr "العنصر <%s> غير مسموح به داخل عنصر <%s>" -#: ../src/ui/theme.c:5185 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" -"لا أسلوب إطار مضبوط لنوع النافذة \"%s\" في السِمة \"%s\"، اضف عنصر <window " -"type=\"%s\" style_set=\"whatever\"/>" +#~ msgid "No draw_ops provided for frame piece" +#~ msgstr "لا draw_ops مزودة لقطعة الإطار" -#: ../src/ui/theme.c:5635 ../src/ui/theme.c:5697 ../src/ui/theme.c:5760 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" -"الثوابت المعرفة من طرف المستخدم يجب أن تبدأ بحروف كبيرة، \"%s\" لا يبدأ بذلك" +#~ msgid "No draw_ops provided for button" +#~ msgstr "لا draw_ops مزودة للزر" -#: ../src/ui/theme.c:5643 ../src/ui/theme.c:5705 ../src/ui/theme.c:5768 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "عُرِّف الثابت \"%s\" بالفعل" +#~ msgid "No text is allowed inside element <%s>" +#~ msgstr "لا يُسمح بنص داخل العنصر <%s>" -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. -#. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "لا صفة \"%s\" على العنصر <%s>" +#~ msgid "<%s> specified twice for this theme" +#~ msgstr "<%s> محدّد مرتان لهذه السِمة" -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "سطر %d محْرف %d: %s" +#~ msgid "Failed to find a valid file for theme %s\n" +#~ msgstr "فشل العثو على سِمة صحيحة في %s\n" -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "الصفة \"%s\" معادة مرتان في نفس العنصر <%s>" +#~ msgid "Usage: %s\n" +#~ msgstr "الاستخدام: %s\n" -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "الصفة \"%s\" مغلوطة في العنصر <%s> في هذا السياق" +#~ msgid "_Windows" +#~ msgstr "_نوافذ" -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "تعذّر تحليل \"%s\" كعدد صحيح" +#~ msgid "_Dialog" +#~ msgstr "_صندوق حوار" -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "لم أفهم المحارف المتدلية \"%s\" في السلسلة \"%s\"" +#~ msgid "_Modal dialog" +#~ msgstr "صندوق حوار _سائد" -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "العدد الصحيح %ld يجب أن يكون ايجابيا" +#~ msgid "_Utility" +#~ msgstr "أ_داة" -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "العدد الصحيح %ld كبير جدا، الحد الأقصى هو %d" +#~ msgid "_Splashscreen" +#~ msgstr "_شاشة بدء" -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "لا يمكن تحليل \"%s\" كعدد فاصلة متحرّكة" +#~ msgid "_Top dock" +#~ msgstr "الرصيف ال_علوي" -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "يجب أن تكون القيم البوليانيّة \"صحيح\" أو \"خاطئ\" لا \"%s\"" +#~ msgid "_Bottom dock" +#~ msgstr "الرصيف الس_فلي" -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "يجب أن تكون الزاوية بين 0.0 و 360.0،وهي كانت%g\n" +#~ msgid "_Left dock" +#~ msgstr "الرصيف الأ_يسر" -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "يجب أن تكون الشفافية بين 0.0 (مختف) و 1.0 (دامس تماما)، وهي كانت %g\n" +#~ msgid "_Right dock" +#~ msgstr "الرصيف الأي_من" -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"حجم عنوان غير سليم \"%s\" (يجب أن يكون واحد من xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" +#~ msgid "_All docks" +#~ msgstr "_جميع الأرصفة" -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s> استُعمل الاسم \"%s\" للمرّة الثانية" +#~ msgid "Des_ktop" +#~ msgstr "س_طح المكتب" -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "<%s> لم يُعرّف الأب \"%s\"" +#~ msgid "Open another one of these windows" +#~ msgstr "افتح نافذة أخرى من هذه النوافذ" -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "<%s> لم تُعرّف الهندسة \"%s\"" +#~ msgid "This is a demo button with an 'open' icon" +#~ msgstr "هذا زر عرض بأيقونة 'افتح'" -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "يجب ان يخصص <%s> هندسة أو اب له هندسة" +#~ msgid "This is a demo button with a 'quit' icon" +#~ msgstr "هذا زر عرض بأيقونة 'انهي'" -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "يجب أن تحدّد خلفية ليصبح لقيمة ألفا معنى" +#~ msgid "This is a sample message in a sample dialog" +#~ msgstr "هذا رسالة عيّنة في حوار عيّنة" -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "نوع مجهول \"%s\" على عنصر <%s>" +#~ msgid "Fake menu item %d\n" +#~ msgstr "عنصر قائمة مستعار %d\n" -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "style_set مجهول \"%s\" على العنصر <%s>" +#~ msgid "Border-only window" +#~ msgstr "نافذة ذات حدود فقط" -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "اعطى لنوع النافذة \"%s\" مجموعة أساليب بالفعل" - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "العنصر <%s> غير مسموح به تحت <%s>" +#~ msgid "Bar" +#~ msgstr "شريط" -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" -msgstr "" -"لا يمكن تخصيص \"button_width\"/\"button_height\" و \"aspect_ratio\" للأزرار" +#~ msgid "Normal Application Window" +#~ msgstr "نافذة تطبيق عادية" -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "المسافة \"%s\" مجهولة" +#~ msgid "Dialog Box" +#~ msgstr "صندوق حوار" -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "نسبة الجانب \"%s\" مجهولة" +#~ msgid "Modal Dialog Box" +#~ msgstr "صندوق حوار سائد" -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "الحدّ \"%s\" مجهول" +#~ msgid "Utility Palette" +#~ msgstr "لوحة أدوات" -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "لا صفة \"start_angle\" أو \"from\" على العنصر <%s>" +#~ msgid "Torn-off Menu" +#~ msgstr "قائمة مفصولة" -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "لا صفة \"extent_angle\" أو \"to\" على العنصر <%s>" +#~ msgid "Border" +#~ msgstr "حد" -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "لم أفهم القيمة \"%s\" لنوع التدرّج" +#~ msgid "Button layout test %d" +#~ msgstr "تجربة تصميم الأزرار %d" -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "لم أفهم نوع الملأ \"%s\" للعنصر <%s>" +#~ msgid "%g milliseconds to draw one window frame" +#~ msgstr "%g ملي ثانية لرسم إظار واحد للنافذة" -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "لم أفهم حالة \"%s\" العنصر <%s>" +#~ msgid "Usage: metacity-theme-viewer [THEMENAME]\n" +#~ msgstr "الإستعمال: metacity-theme-viewer [THEMENAME]\n" -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "لم أفهم ظل \"%s\" العنصر <%s>" +#~ msgid "Error loading theme: %s\n" +#~ msgstr "خطأ عند تحميل السِمة: %s\n" -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "لم أفهم السهم \"%s\" للعنصر <%s>" +#~ msgid "Loaded theme \"%s\" in %g seconds\n" +#~ msgstr "حُمِّلت السِمة \"%s\" في %g ثواني\n" -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "لم يعرف <draw_ops> مسمى \"%s\"" +#~ msgid "Normal Title Font" +#~ msgstr "خط عنوان عادي" -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "تضمين draw_ops \"%s\" هنا سينشئ مرجعا دائريا" +#~ msgid "Small Title Font" +#~ msgstr "خط عنوان صغير" -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "موقع مجهول \"%s\" لقطعة الإطار" +#~ msgid "Large Title Font" +#~ msgstr "خط عنوان كبير" -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "أسلوب الإطار له قطعة في الموقع %s" +#~ msgid "Button Layouts" +#~ msgstr "تصاميم الأزرار" -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "لم تعرف <draw_ops> بالاسم \"%s\"" +#~ msgid "Benchmark" +#~ msgstr "علامة إهتداء" -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "وظيفة مجهولة \"%s\" للزر" +#~ msgid "Window Title Goes Here" +#~ msgstr "عنوان النافذة يكون هنا" -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "لا وجود لوظيفة الزر \"%s\" في هذه الإصدارة (%d، تحتاج %d)" +#~ msgid "" +#~ "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and " +#~ "%g seconds wall clock time including X server resources (%g milliseconds " +#~ "per frame)\n" +#~ msgstr "" +#~ "دفعت %d إطارات في %g ثوان بإتجاه العميل (%g ملي ثانية لكل إطار) و %g " +#~ "ثواني بوقت ساعة حائطية مع مصادر خادوم X (%g ملي ثانية لكل إطار)\n" -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "حالة مجهولة \"%s\" للزر" +#~ msgid "position expression test returned TRUE but set error" +#~ msgstr "أرجع إختبار تعبير الموقع TRUE لكنه لم يكتشف الخطأ" -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "أسلوب الإطار له بالفعل زر للوظيفة %s الحالة %s" +#~ msgid "position expression test returned FALSE but didn't set error" +#~ msgstr "أرجع إختبار تعبير الموقع خطأ لكنه لم يكتشف الخطأ" -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "\"%s\" قيمة غير سليمة لصفة التركيز" +#~ msgid "Error was expected but none given" +#~ msgstr "تُرُقِّب خطأ لكن لم يعطى أي خطأ" -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "\"%s\" قيمة غير سليمة لصفة الحالة" +#~ msgid "Error %d was expected but %d given" +#~ msgstr "تُرقّب %d لكن أعطى %d" -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "لم يعرف أسلوب مسمى بـ \"%s\"" +#~ msgid "Error not expected but one was returned: %s" +#~ msgstr "لم يُترقب خطأ لكنه أرجع واحدًا: %s" -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "\"%s\" ليس قيمة سليمة لصفة التحجيم" +#~ msgid "x value was %d, %d was expected" +#~ msgstr "قيمة س كانت %d، تُرُقِّب %d" -#: ../src/ui/theme-parser.c:3147 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "لا يجب أن تكون صفة \"التحجيم\" على عنصر <%s> لحالات التكبير/الاخفاء" +#~ msgid "y value was %d, %d was expected" +#~ msgstr "قيمة ص كانت %d، تُرُقَِب %d" -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "لا يجب أن تكون صفة \"التحجيم\" على عنصر <%s> لحالات التكبير" +#~ msgid "" +#~ "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" +#~ msgstr "حُلِّلت %d تعابير الإحداثيات في %g ثواني (بمعدّل %g ثوان)\n" -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "حُدّد بالفعل أسلوب للحالة %s التحجيم %s التركيز %s" +#~ msgid "Minimize window" +#~ msgstr "صغّر النّافذة" -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "حُدّد بالفعل أسلوب للحالة %s التركيز %s" +#~ msgid "Comma-separated list of compositor plugins" +#~ msgstr "قائمة بملحقات المزج مفصولة بفاصلة" -#: ../src/ui/theme-parser.c:3294 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"لا يمكن ان يوجد draw_ops اثنان لعنصر <piece> (خصصت السِمة صفة draw_ops و عنصر " -"<draw_ops>، أو عنصران محدّدان)" +#~ msgid "Switch to workspace on the left of the current workspace" +#~ msgstr "انتقل إلى مساحة العمل على يسار الحالية" -#: ../src/ui/theme-parser.c:3332 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"لا يمكن ان يوجد draw_ops اثنان لعنصر <button> (خصصت السِمة صفة draw_ops و " -"عنصر <draw_ops>، أو عنصران محدّدان)" +#~ msgid "Switch to workspace on the right of the current workspace" +#~ msgstr "انتقل إلى مساحة العمل على يمين الحالية" -#: ../src/ui/theme-parser.c:3370 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"لا يمكن ان يوجد draw_ops اثنان لعنصر<menu_icon> (خصصت السِمة صفة draw_ops و " -"عنصر <draw_ops>، أو عنصران محدّدان)" +#~ msgid "Switch to workspace above the current workspace" +#~ msgstr "انتقل إلى مساحة العمل فوق الحالية" -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "" +#~ msgid "Switch to workspace below the current workspace" +#~ msgstr "انتقل إلى مساحة العمل تحت الحالية" -#: ../src/ui/theme-parser.c:3507 -msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" -msgstr "" +#~ msgid "Move between windows of an application, using a popup window" +#~ msgstr "تنقل بين نوافذ تطبيق بنافذةٍ قافزة" -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "" +#~ msgid "" +#~ "Move backward between windows of an application, using a popup window" +#~ msgstr "تنقل إلى الوراء بين نوافذ تطبيق بنافذةٍ قافزة" -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "يجب أن يكون أخرج عنصر في السِمة <metacity_theme> لا <%s>" +#~ msgid "Move between windows, using a popup window" +#~ msgstr "تنقل بين النوافذ بنافذةٍ قافزة" -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "العنصر <%s> غير مسموح به داخل عنصر اسم/كاتب/تاريخ/وصف" +#~ msgid "Move backward between windows, using a popup window" +#~ msgstr "تنقل إلى الوراء بين النوافذ بنافذةٍ قافزة" -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "العنصر <%s> غير مسموح به داخل عنصر <constant>" +#~ msgid "Move between panels and the desktop, using a popup window" +#~ msgstr "تنقل بين الأشرطة و سطح المكتب بنافذةٍ قافزة" -#: ../src/ui/theme-parser.c:3599 -#, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "العنصر <%s> غير مسموح به داخل عنصر مسافة/حد/aspect_ratio" +#~ msgid "Move backward between panels and the desktop, using a popup window" +#~ msgstr "تنقل إلى الوراء بين الأشرطة و سطح المكتب بنافذةٍ قافزة" -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "العنصر <%s> غير مسموح به داخل عنصر عملية متعادلة" +#~ msgid "Move between windows of an application immediately" +#~ msgstr "تنقل بين نوافذ تطبيق حالًا" -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "العنصر <%s> غير مسموح به داخل عنصر <%s>" +#~ msgid "Move backward between windows of an application immediately" +#~ msgstr "تنقل إلى الوراء بين نوافذ تطبيق حالًا" -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "لا draw_ops مزودة لقطعة الإطار" +#~ msgid "Move between windows immediately" +#~ msgstr "تنقل بين النوافذ حالًا" -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "لا draw_ops مزودة للزر" +#~ msgid "Move backward between windows immediately" +#~ msgstr "تنقل إلى الوراء بين النوافذ حالًا" -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "لا يُسمح بنص داخل العنصر <%s>" +#~ msgid "Move between panels and the desktop immediately" +#~ msgstr "تنقل بين الأشرطة و سطح المكتب حالًا" -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "<%s> محدّد مرتان لهذه السِمة" +#~ msgid "Move backward between panels and the desktop immediately" +#~ msgstr "تنقل إلى الوراء بين الأشرطة و سطح المكتب حالًا" -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "فشل العثو على سِمة صحيحة في %s\n" +#~ msgid "Hide all normal windows and set focus to the desktop" +#~ msgstr "أخفِ كل النوافذ و ركّز على سطح المكتب" -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "_نوافذ" +#~ msgid "Show the panel's main menu" +#~ msgstr "اعرض قائمة الشريط الرئيسية" -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "_صندوق حوار" +#~ msgid "Show the panel's \"Run Application\" dialog box" +#~ msgstr "أظهر حوار الشّريط لتشغيل التّطبيقات" -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "صندوق حوار _سائد" +#~ msgid "Start or stop recording the session" +#~ msgstr "ابدأ أو أوقف تسجيل الجلسة" -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "أ_داة" +#~ msgid "Take a screenshot" +#~ msgstr "خذ لقطة شاشة" -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "_شاشة بدء" +#~ msgid "Take a screenshot of a window" +#~ msgstr "خذ لقطة لنافذة" -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "الرصيف ال_علوي" +#~ msgid "Run a terminal" +#~ msgstr "شغّل طرفية" -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "الرصيف الس_فلي" +#~ msgid "Toggle whether a window will always be visible over other windows" +#~ msgstr "بدّل حالة ظهور النافذة فوق النوافذ الأخرى" -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "الرصيف الأ_يسر" +#~ msgid "Toggle whether window is on all workspaces or just one" +#~ msgstr "بدّل حالة ظهور النافذة على جميع مساحات العمل" -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "الرصيف الأي_من" +#~ msgid "Move window to workspace 5" +#~ msgstr "انقل النافذة إلى مساحة العمل 5" -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "_جميع الأرصفة" +#~ msgid "Move window to workspace 6" +#~ msgstr "انقل النافذة إلى مساحة العمل 6" -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "س_طح المكتب" +#~ msgid "Move window to workspace 7" +#~ msgstr "انقل النافذة إلى مساحة العمل 7" -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "افتح نافذة أخرى من هذه النوافذ" +#~ msgid "Move window to workspace 8" +#~ msgstr "انقل النافذة إلى مساحة العمل 8" -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "هذا زر عرض بأيقونة 'افتح'" +#~ msgid "Move window to workspace 9" +#~ msgstr "انقل النافذة إلى مساحة العمل 9" -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "هذا زر عرض بأيقونة 'انهي'" +#~ msgid "Move window to workspace 10" +#~ msgstr "انقل النافذة إلى مساحة العمل 10" -#: ../src/ui/theme-viewer.c:253 -msgid "This is a sample message in a sample dialog" -msgstr "هذا رسالة عيّنة في حوار عيّنة" +#~ msgid "Move window to workspace 11" +#~ msgstr "انقل النافذة إلى مساحة العمل 11" -#: ../src/ui/theme-viewer.c:336 -#, c-format -msgid "Fake menu item %d\n" -msgstr "عنصر قائمة مستعار %d\n" +#~ msgid "Move window to workspace 12" +#~ msgstr "انقل النافذة إلى مساحة العمل 12" -#: ../src/ui/theme-viewer.c:370 -msgid "Border-only window" -msgstr "نافذة ذات حدود فقط" +#~ msgid "Raise window if it's covered by another window, otherwise lower it" +#~ msgstr "ارفع النافذة إذا كانت أخرى تغطيها، أو أخفضها في ما عدا ذلك" -#: ../src/ui/theme-viewer.c:372 -msgid "Bar" -msgstr "شريط" +#~ msgid "Move window to north-west (top left) corner" +#~ msgstr "انقل النافذة للزاوية شمال-غربي الشاشة (أعلى اليسار)" -#: ../src/ui/theme-viewer.c:389 -msgid "Normal Application Window" -msgstr "نافذة تطبيق عادية" +#~ msgid "Move window to north-east (top right) corner" +#~ msgstr "انقل النافذة للزاوية شمال-شرقي الشاشة (أعلى اليمين)" -#: ../src/ui/theme-viewer.c:393 -msgid "Dialog Box" -msgstr "صندوق حوار" +#~ msgid "Move window to south-west (bottom left) corner" +#~ msgstr "انقل النافذة للزاوية جنوب-غرب الشاشة (أدنى اليسار)" -#: ../src/ui/theme-viewer.c:397 -msgid "Modal Dialog Box" -msgstr "صندوق حوار سائد" +#~ msgid "Move window to south-east (bottom right) corner" +#~ msgstr "انقل النافذة للزاوية جنوب-شرق الشاشة (أدنى اليمين)" -#: ../src/ui/theme-viewer.c:401 -msgid "Utility Palette" -msgstr "لوحة أدوات" +#~ msgid "Move window to north (top) side of screen" +#~ msgstr "انقل النافذة للجانب الشمالي من الشاشة (فوق)" -#: ../src/ui/theme-viewer.c:405 -msgid "Torn-off Menu" -msgstr "قائمة مفصولة" +#~ msgid "Move window to south (bottom) side of screen" +#~ msgstr "انقل النافذة للجانب الجنوبي من الشاشة (تحت)" -#: ../src/ui/theme-viewer.c:409 -msgid "Border" -msgstr "حد" +#~ msgid "Move window to east (right) side of screen" +#~ msgstr "انقل النافذة للجانب الشرقي من الشاشة (يمين)" -#: ../src/ui/theme-viewer.c:413 -msgid "Attached Modal Dialog" -msgstr "صندوق حوار سائد" +#~ msgid "Move window to west (left) side of screen" +#~ msgstr "انقل النافذة للجانب الغربي من الشاشة (يسار)" -#: ../src/ui/theme-viewer.c:744 -#, c-format -msgid "Button layout test %d" -msgstr "تجربة تصميم الأزرار %d" +#~ msgid "Move window to center of screen" +#~ msgstr "انقل النافذة إلى وسط الشاشة" -#: ../src/ui/theme-viewer.c:773 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g ملي ثانية لرسم إظار واحد للنافذة" +#~ msgid "" +#~ "There was an error running <tt>%s</tt>:\n" +#~ "\n" +#~ "%s" +#~ msgstr "" +#~ "حصل خطأ عند تشغيل <tt>%s</tt>:\n" +#~ "\n" +#~ "%s." -#: ../src/ui/theme-viewer.c:818 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "الإستعمال: metacity-theme-viewer [THEMENAME]\n" +#~ msgid "No command %d has been defined.\n" +#~ msgstr "لم يُعرّف أمر %d.\n" -#: ../src/ui/theme-viewer.c:825 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "خطأ عند تحميل السِمة: %s\n" +#~ msgid "No terminal command has been defined.\n" +#~ msgstr "لم يُعرّف أمر طرفيّة.\n" -#: ../src/ui/theme-viewer.c:831 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "حُمِّلت السِمة \"%s\" في %g ثواني\n" +#~ msgid "GConf key '%s' is set to an invalid value\n" +#~ msgstr "مفتاح GConf '%s' مضبوط لقيمة غير صحيحة\n" -#: ../src/ui/theme-viewer.c:875 -msgid "Normal Title Font" -msgstr "خط عنوان عادي" +#~ msgid "%d stored in GConf key %s is out of range %d to %d\n" +#~ msgstr "%d المحفوظ في مفتاح GConf %s خارج المدى من %d إلى %d\n" -#: ../src/ui/theme-viewer.c:881 -msgid "Small Title Font" -msgstr "خط عنوان صغير" +#~ msgid "GConf key \"%s\" is set to an invalid type\n" +#~ msgstr "مفتاح GConf \"%s\" مضبوط لنوع غير صحيح\n" -#: ../src/ui/theme-viewer.c:887 -msgid "Large Title Font" -msgstr "خط عنوان كبير" +#~ msgid "Error setting number of workspaces to %d: %s\n" +#~ msgstr "خطأ عند تعيين عدد مساحات العمل لـ %d: %s\n" -#: ../src/ui/theme-viewer.c:892 -msgid "Button Layouts" -msgstr "تصاميم الأزرار" +#~ msgid "Error setting name for workspace %d to \"%s\": %s\n" +#~ msgstr "خطأ عند تحديد اسم مساحة العمل %d لـ \"%s\": %s\n" -#: ../src/ui/theme-viewer.c:897 -msgid "Benchmark" -msgstr "علامة إهتداء" +#~ msgid "Error setting no tab popup status: %s\n" +#~ msgstr "خطأ عند ضبط حالة لا لسان منبثق: %s\n" -#: ../src/ui/theme-viewer.c:949 -msgid "Window Title Goes Here" -msgstr "عنوان النافذة يكون هنا" +#~ msgid "Close Window" +#~ msgstr "أغلق النافذة" -#: ../src/ui/theme-viewer.c:1055 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"دفعت %d إطارات في %g ثوان بإتجاه العميل (%g ملي ثانية لكل إطار) و %g ثواني " -"بوقت ساعة حائطية مع مصادر خادوم X (%g ملي ثانية لكل إطار)\n" +#~ msgid "Window Menu" +#~ msgstr "قائمة النافذة" -#: ../src/ui/theme-viewer.c:1274 -msgid "position expression test returned TRUE but set error" -msgstr "أرجع إختبار تعبير الموقع TRUE لكنه لم يكتشف الخطأ" +#~ msgid "Minimize Window" +#~ msgstr "صغّر النافذة" -#: ../src/ui/theme-viewer.c:1276 -msgid "position expression test returned FALSE but didn't set error" -msgstr "أرجع إختبار تعبير الموقع خطأ لكنه لم يكتشف الخطأ" +#~ msgid "Maximize Window" +#~ msgstr "كبّر النافذة" -#: ../src/ui/theme-viewer.c:1280 -msgid "Error was expected but none given" -msgstr "تُرُقِّب خطأ لكن لم يعطى أي خطأ" +#~ msgid "Restore Window" +#~ msgstr "استعد النّافذة" -#: ../src/ui/theme-viewer.c:1282 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "تُرقّب %d لكن أعطى %d" +#~ msgid "Roll Up Window" +#~ msgstr "لُفّ النافذة الأعلى" -#: ../src/ui/theme-viewer.c:1288 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "لم يُترقب خطأ لكنه أرجع واحدًا: %s" +#~ msgid "Unroll Window" +#~ msgstr "ألغى لفّ النافذة" -#: ../src/ui/theme-viewer.c:1292 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "قيمة س كانت %d، تُرُقِّب %d" +#~ msgid "Keep Window On Top" +#~ msgstr "ابقي النافذة على القمة" -#: ../src/ui/theme-viewer.c:1295 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "قيمة ص كانت %d، تُرُقَِب %d" +#~ msgid "Always On Visible Workspace" +#~ msgstr "دائما مساحة العمل المرئية" -#: ../src/ui/theme-viewer.c:1360 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "حُلِّلت %d تعابير الإحداثيات في %g ثواني (بمعدّل %g ثوان)\n" +#~ msgid "Put Window On Only One Workspace" +#~ msgstr "ضع النافذة على مساحة عمل واحدة فقط" #~ msgid "" #~ "Don't make fullscreen windows that are maximized and have no decorations" @@ -1850,6 +1698,3 @@ msgstr "حُلِّلت %d تعابير الإحداثيات في %g ثواني ( #~ msgid "Error setting clutter plugin list: %s\n" #~ msgstr "خطأ عند تحديد قائمة ملحقات كلتر: %s\n" - -#~ msgid "Clutter Plugins" -#~ msgstr "ملحقات كلتر" diff --git a/po/as.po b/po/as.po index 4c7849193..55dee28d7 100644 --- a/po/as.po +++ b/po/as.po @@ -4,405 +4,301 @@ # # Amitakhya Phukan <amitakhya@svn.gnome.org>, 2008. # Amitakhya Phukan <aphukan@fedoraproject.org>, 2009. -# Nilamdyuti Goswami <ngoswami@redhat.com>, 2011, 2012. +# Nilamdyuti Goswami <ngoswami@redhat.com>, 2011, 2012, 2013, 2014. msgid "" msgstr "" "Project-Id-Version: as\n" -"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug." -"cgi?product=muffin&keywords=I18N+L10N&component=general\n" -"POT-Creation-Date: 2012-03-11 21:56+0000\n" -"PO-Revision-Date: 2012-03-12 14:26+0530\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=mutter&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2014-08-18 09:48+0000\n" +"PO-Revision-Date: 2014-08-18 21:37+0530\n" "Last-Translator: Nilamdyuti Goswami <ngoswami@redhat.com>\n" -"Language-Team: as_IN <kde-i18n-doc@kde.org>\n" +"Language-Team: Assamese <kde-i18n-doc@kde.org>\n" +"Language: as\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Lokalize 1.0\n" +"X-Generator: Lokalize 1.5\n" "Plural-Forms: nplurals=2; plural=(n!=1)\n" -#: ../src/50-muffin-windows.xml.in.h:1 -#| msgid "_Windows" +#: ../data/50-mutter-navigation.xml.in.h:1 +msgid "Navigation" +msgstr "মাৰ্গদৰ্শন" + +#: ../data/50-mutter-navigation.xml.in.h:2 +msgid "Move window to workspace 1" +msgstr "উইন্ডোক কৰ্মস্থান ১লে স্থানান্তৰ কৰক" + +#: ../data/50-mutter-navigation.xml.in.h:3 +msgid "Move window to workspace 2" +msgstr "উইন্ডোক কৰ্মস্থান ২লে স্থানান্তৰ কৰক" + +#: ../data/50-mutter-navigation.xml.in.h:4 +msgid "Move window to workspace 3" +msgstr "উইন্ডোক কৰ্মস্থান ৩লে স্থানান্তৰ কৰক" + +#: ../data/50-mutter-navigation.xml.in.h:5 +msgid "Move window to workspace 4" +msgstr "উইন্ডোক কৰ্মস্থান ৪লে স্থানান্তৰ কৰক" + +#: ../data/50-mutter-navigation.xml.in.h:6 +#| msgid "Move window to workspace 1" +msgid "Move window to last workspace" +msgstr "উইন্ডোক সৰ্বশেষ কৰ্মস্থানলৈ স্থানান্তৰ কৰক" + +#: ../data/50-mutter-navigation.xml.in.h:7 +msgid "Move window one workspace to the left" +msgstr "উইন্ডোক বাওঁফালে এটা কৰ্মস্থানলে স্থানান্তৰ কৰক" + +#: ../data/50-mutter-navigation.xml.in.h:8 +msgid "Move window one workspace to the right" +msgstr "উইন্ডো সোঁফালে এটা কৰ্মস্থানলে স্থানান্তৰ কৰক" + +#: ../data/50-mutter-navigation.xml.in.h:9 +msgid "Move window one workspace up" +msgstr "উইন্ডো এটা কৰ্মস্থান ওপৰত স্থানান্তৰ কৰক" + +#: ../data/50-mutter-navigation.xml.in.h:10 +msgid "Move window one workspace down" +msgstr "উইন্ডো এটা কৰ্মস্থান তলত স্থানান্তৰ কৰক" + +#: ../data/50-mutter-navigation.xml.in.h:11 +#| msgid "Move window one workspace to the left" +msgid "Move window one monitor to the left" +msgstr "উইন্ডোক বাওঁফালে এটা মনিটৰ স্থানান্তৰ কৰক" + +#: ../data/50-mutter-navigation.xml.in.h:12 +#| msgid "Move window one workspace to the right" +msgid "Move window one monitor to the right" +msgstr "উইন্ডো সোঁফালে এটা মনিটৰ স্থানান্তৰ কৰক" + +#: ../data/50-mutter-navigation.xml.in.h:13 +#| msgid "Move window one workspace up" +msgid "Move window one monitor up" +msgstr "উইন্ডো এটা মনিটৰ ওপৰত স্থানান্তৰ কৰক" + +#: ../data/50-mutter-navigation.xml.in.h:14 +#| msgid "Move window one workspace down" +msgid "Move window one monitor down" +msgstr "উইন্ডো এটা মনিটৰ তলত স্থানান্তৰ কৰক" + +#: ../data/50-mutter-navigation.xml.in.h:15 +msgid "Switch applications" +msgstr "এপ্লিকেচনসমুহ অদল বদল কৰক" + +#: ../data/50-mutter-navigation.xml.in.h:16 +#| msgid "Switch applications" +msgid "Switch to previous application" +msgstr "আগৰ এপ্লিকেচনলৈ যাওক" + +#: ../data/50-mutter-navigation.xml.in.h:17 +msgid "Switch windows" +msgstr "উইন্ডোসমূহ চুইচ কৰক" + +#: ../data/50-mutter-navigation.xml.in.h:18 +#| msgid "Switch windows" +msgid "Switch to previous window" +msgstr "আগৰ উইন্ডোলৈ যাওক" + +#: ../data/50-mutter-navigation.xml.in.h:19 +msgid "Switch windows of an application" +msgstr "এটা এপ্লিকেচনৰ উইন্ডোসমূহ অদল বদল কৰক" + +#: ../data/50-mutter-navigation.xml.in.h:20 +#| msgid "Switch windows of an application" +msgid "Switch to previous window of an application" +msgstr "এটা এপ্লিকেচনৰ আগৰ উইন্ডোলৈ যাওক" + +#: ../data/50-mutter-navigation.xml.in.h:21 +msgid "Switch system controls" +msgstr "চিস্টেম নিয়ন্ত্ৰণসমূহ অদল বদল কৰক" + +#: ../data/50-mutter-navigation.xml.in.h:22 +#| msgid "Switch system controls" +msgid "Switch to previous system control" +msgstr "আগৰ চিস্টেম নিয়ন্ত্ৰণলৈ যাওক" + +#: ../data/50-mutter-navigation.xml.in.h:23 +msgid "Switch windows directly" +msgstr "উইন্ডোসমূহ প্ৰত্যক্ষভাৱে অদল বদল কৰক" + +#: ../data/50-mutter-navigation.xml.in.h:24 +msgid "Switch directly to previous window" +msgstr "প্ৰত্যক্ষভাৱে আগৰ উইন্ডোলৈ যাওক" + +#: ../data/50-mutter-navigation.xml.in.h:25 +msgid "Switch windows of an app directly" +msgstr "এটা এপ্লিকেচনৰ উইন্ডোসমূহ প্ৰত্যক্ষভাৱে অদল বদল কৰক" + +#: ../data/50-mutter-navigation.xml.in.h:26 +#| msgid "Switch windows of an application" +msgid "Switch directly to previous window of an app" +msgstr "প্ৰত্যক্ষভাৱে এটা এপ্লিকেচনৰ আগৰ উইন্ডোলৈ যাওক" + +#: ../data/50-mutter-navigation.xml.in.h:27 +msgid "Switch system controls directly" +msgstr "চিস্টেম নিয়ন্ত্ৰণসমূহ প্ৰত্যক্ষভাৱে অদল বদল কৰক" + +#: ../data/50-mutter-navigation.xml.in.h:28 +#| msgid "Switch system controls" +msgid "Switch directly to previous system control" +msgstr "প্ৰত্যক্ষভাৱে আগৰ চিস্টেম নিয়ন্ত্ৰণলৈ যাওক" + +#: ../data/50-mutter-navigation.xml.in.h:29 +msgid "Hide all normal windows" +msgstr "সকলো স্বাভাৱিক উইন্ডো লুকাওক" + +#: ../data/50-mutter-navigation.xml.in.h:30 +msgid "Switch to workspace 1" +msgstr "কৰ্মস্থান ১লে পৰিবৰ্তন কৰক" + +#: ../data/50-mutter-navigation.xml.in.h:31 +msgid "Switch to workspace 2" +msgstr "কৰ্মস্থান ২লে পৰিবৰ্তন কৰক" + +#: ../data/50-mutter-navigation.xml.in.h:32 +msgid "Switch to workspace 3" +msgstr "কৰ্মস্থান ৩লে পৰিবৰ্তন কৰক" + +#: ../data/50-mutter-navigation.xml.in.h:33 +msgid "Switch to workspace 4" +msgstr "কৰ্মস্থান ৪লে পৰিবৰ্তন কৰক" + +#: ../data/50-mutter-navigation.xml.in.h:34 +#| msgid "Switch to workspace 1" +msgid "Switch to last workspace" +msgstr "সৰ্বশেষ কৰ্মস্থানলৈ যাওক" + +#: ../data/50-mutter-navigation.xml.in.h:35 +msgid "Move to workspace left" +msgstr "বাওঁফালৰ কৰ্মক্ষেত্ৰলে স্থানান্তৰ কৰক" + +#: ../data/50-mutter-navigation.xml.in.h:36 +msgid "Move to workspace right" +msgstr "সোঁফালৰ কৰ্মক্ষেত্ৰলে স্থানান্তৰ কৰক" + +#: ../data/50-mutter-navigation.xml.in.h:37 +msgid "Move to workspace above" +msgstr "ওপৰৰ কৰ্মক্ষেত্ৰলে স্থানান্তৰ কৰক" + +#: ../data/50-mutter-navigation.xml.in.h:38 +msgid "Move to workspace below" +msgstr "তলৰ কৰ্মক্ষেত্ৰলে স্থানান্তৰ কৰক" + +#: ../data/50-mutter-system.xml.in.h:1 +msgid "System" +msgstr "চিস্টেম" + +#: ../data/50-mutter-system.xml.in.h:2 +msgid "Show the run command prompt" +msgstr "ৰান কমান্ড প্ৰম্পট দেখুৱাওক" + +#: ../data/50-mutter-system.xml.in.h:3 +msgid "Show the activities overview" +msgstr "কাৰ্য্যসমূহৰ অভাৰভিউ দেখুৱাওক" + +#: ../data/50-mutter-windows.xml.in.h:1 msgid "Windows" msgstr "উইন্ডোসমূহ" -#: ../src/50-muffin-windows.xml.in.h:2 -msgid "View split on left" -msgstr "বিভাজনক বাঁওফালে দৰ্শন কৰক" - -#: ../src/50-muffin-windows.xml.in.h:3 -msgid "View split on right" -msgstr "বিভাজনক সোঁফালে দৰ্শন কৰক" - -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format -msgid "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." -msgstr "অন্য এটা পৰ্দা %i -ত অন্য সংযুক্তি ব্যৱস্থাপক ইতিমধ্যে চলি আছে প্ৰদৰ্শন \"%s\" । " - -#: ../src/core/bell.c:307 -msgid "Bell event" -msgstr "ঘন্টা ঘটনা" - -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "অজ্ঞাত উইন্ডো তথ্য অনুৰোধ: %d" - -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> -এ প্ৰতিক্ৰিয়া কৰা নাই।" - -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "অনুপ্ৰয়োগে প্ৰতিক্ৰিয়া কৰা নাই।" - -#: ../src/core/delete.c:119 -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "" -"আপুনি ই চলি থাকিবলে অকন সময় অপেক্ষা কৰিব পাৰে অথবা অনুপ্ৰয়োগক সম্পূৰ্ণভাৱে প্ৰস্থান " -"কৰিবলে বাধ্য কৰিব পাৰে।" - -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "অপেক্ষা কৰক (_W)" - -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "বলপূৰ্বক বন্ধ কৰক (_F)" - -#: ../src/core/display.c:361 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "সংযুক্তিৰ কাৰণে সন্ধানহিন %s সম্প্ৰসাৰনৰ প্ৰয়োজন " - -#: ../src/core/display.c:427 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "X উইন্ডো চিস্টেম প্ৰদৰ্শন '%s'খোলিব পৰা নগল \n" - -#: ../src/core/keybindings.c:852 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "" -"অন্য কোনো প্ৰগ্ৰামে ইতিমধ্যে চাবি %s -ক বাইন্ডিং হিচাপে পৰিৱৰ্তক %x -ৰ সৈতে ব্যৱহাৰ " -"কৰি আছে\n" - -#: ../src/core/main.c:206 -msgid "Disable connection to session manager" -msgstr "অধিবেশন ব্যৱস্থাপকৰ সৈতে সংযোগ বিচ্ছিন্ন কৰক" - -#: ../src/core/main.c:212 -msgid "Replace the running window manager" -msgstr "চলি থকা উইন্ডো ব্যৱস্থাপকক প্ৰতিস্থাপন কৰক" - -#: ../src/core/main.c:218 -msgid "Specify session management ID" -msgstr "অধিবেশন পৰিচালনাৰ ID উল্লেখ কৰক" - -#: ../src/core/main.c:223 -msgid "X Display to use" -msgstr "ব্যৱহাৰৰ বাবে X প্ৰদৰ্শন" - -#: ../src/core/main.c:229 -msgid "Initialize session from savefile" -msgstr "সংৰক্ষণ নথিপত্ৰৰ পৰা অধিবেশন আৰম্ভ কৰক" - -#: ../src/core/main.c:235 -msgid "Make X calls synchronous" -msgstr "X কলসমূহ সংমিহলি কৰক" - -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "থীমৰ ডাইৰেকটৰি স্কেন কৰিব পৰা নগল: %s\n" - -#: ../src/core/main.c:520 -#, c-format -msgid "Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "" -"এটা থীম পোৱা নগল! সুনিশ্চিত হওক %s অস্তিত্ববান আৰু স্বাভাৱিক থিমসমূহ অন্তৰ্ভুক্ত কৰে।\n" - -#: ../src/core/muffin.c:40 -#, c-format -msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" -"muffin %s\n" -"উপাদানধিকাৰ (C) ২০০১-%d Havoc Pennington, Red Hat, Inc., আৰু অন্য\n" -"এইটো এটা বিনামুলীয়া চফ্টওৱেৰ; কপিৰ চুক্তিসমূহৰ বাবে উৎস চাওক।\n" -"ইয়াৰ কোনো ওৱাৰেন্টি নাই; ব্যৱশায়ীক অথবা এটা বিশেষ কাৰণৰ বাবে উপযুক্ত হলেও নহয়।\n" - -#: ../src/core/muffin.c:54 -msgid "Print version" -msgstr "সংস্কৰণ প্ৰিন্ট কৰক" - -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "সংৰূপক প্লাগিনসমূহৰ কমা-পৃথকিত তালিকা" - -#: ../src/core/prefs.c:1077 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"ক্ষতিগ্ৰস্ত অনুপ্ৰয়োগেৰ ত্ৰুটি অগ্ৰাহ্য কৰাৰ প্ৰণালী নিষ্ক্ৰিয় কৰা হৈছে । কিছুমান অনুপ্ৰয়োগ " -"সম্ভৱত সঠিকৰূপে চলোৱা সম্ভৱ নহব।\n" - -#: ../src/core/prefs.c:1152 -#, c-format -#| msgid "Could not parse font description \"%s\" from GConf key %s\n" -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "GSettings চাবি %s ৰ পৰা ফন্ট বিৱৰণ \"%s\" বিশ্লেষণ কৰিব নোৱাৰি\n" - -#: ../src/core/prefs.c:1218 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "সংৰূপ ডাটাবেইচত উপস্থিত \"%s\" মাউচ বুটাম পৰিবৰ্তকৰ বাবে বৈধ মানে নহয়\n" - -#: ../src/core/prefs.c:1736 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "সংৰূপ ডাটাবেইচত উপলব্ধ \"%s\", \"%s\" কি-বাইন্ডিং'ৰ ক্ষেত্ৰত বৈধ মান নহয়\n" - -#: ../src/core/prefs.c:1833 -#, c-format -msgid "Workspace %d" -msgstr "কৰ্মস্থান %d" - -#: ../src/core/screen.c:730 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "পৰ্দা %d (প্ৰদৰ্শন '%s') অবৈধ\n" - -#: ../src/core/screen.c:746 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"পৰ্দা %d'ৰ (\"%s\" প্ৰদৰ্শন) ক্ষেত্ৰত এটা উইন্ডো ব্যৱস্থাপক বৰ্তমানে উপস্তিত আছে; " -"বৰ্তমানে উইন্ডো ব্যৱস্থাপক পৰিবৰ্তন কৰোঁতে --replace বিকল্প প্ৰয়োগ কৰক ।\n" - -#: ../src/core/screen.c:773 -#, c-format -msgid "Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "পৰ্দা %d প্ৰদৰ্শন \"%s\" -ত উইন্ডো ব্যৱস্থাপকৰ নিৰ্বাচিত অংশ গ্ৰহণ কৰোঁতে ব্যৰ্থ\n" - -#: ../src/core/screen.c:828 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "পৰ্দা %d'ৰ \"%s\" প্ৰদৰ্শন ক্ষেত্ৰত এটা উইন্ডো ব্যৱস্থাপক ইতিমধ্যে আছে\n" - -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "পৰ্দা %d মুক্ত কৰিব পৰা নগল প্ৰদৰ্শন \"%s\"\n" - -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "ডাইৰেকটৰি '%s' সৃষ্টি কৰিব পৰা নগল: %s\n" - -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "লিখাৰ বাবে অধিবেশন নথিপত্ৰ '%s' খোলিব পৰা নগল: %s\n" - -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "অধিবেশন নথিপত্ৰ '%s' লিখোতে ত্ৰুটি: %s\n" - -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "অধিবেশন নথিপত্ৰ '%s' বন্ধ কৰোতে ত্ৰুটি: %s\n" - -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "সংৰক্ষিত অধিবেশন নথিপত্ৰ বিশ্লেষণ কৰিব পৰা নগল: %s\n" +# #-#-#-#-# as.po (as) #-#-#-#-#: ../src/50-mutter-windows.xml.in.h:2 +#: ../data/50-mutter-windows.xml.in.h:2 +msgid "Activate the window menu" +msgstr "উইন্ডো মেনু সক্ৰিয় কৰক" -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "<muffin_session> বৈশিষ্ট্য প্ৰদৰ্শিত কিন্তু অধিবেশন ID বৰ্তমানে উপস্থিত আছে" +#: ../data/50-mutter-windows.xml.in.h:3 +msgid "Toggle fullscreen mode" +msgstr "সম্পূৰ্ণপৰ্দা অৱস্থা অদল-বদল কৰক" -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "অজ্ঞাত বৈশিষ্ট্য %s, <%s> উপাদানত চিহ্নিত হৈছে" +#: ../data/50-mutter-windows.xml.in.h:4 +msgid "Toggle maximization state" +msgstr "সৰ্বোচ্চ অবস্থা অদল-বদল কৰক" -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "নেস্টেড <window> টেগ" +#: ../data/50-mutter-windows.xml.in.h:5 +msgid "Maximize window" +msgstr "উইন্ডো ডাঙৰ কৰক" -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "অজ্ঞাত উপাদান %s" +# #-#-#-#-# as.po (as) #-#-#-#-#: ../src/50-mutter-windows.xml.in.h:6 +#: ../data/50-mutter-windows.xml.in.h:6 +msgid "Restore window" +msgstr "উইন্ডো পুনৰুদ্ধাৰ কৰক" -#: ../src/core/session.c:1809 -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" -"এই উইন্ডোসমূহৰ দ্বাৰা " সমৰ্থিত নহয়;বৰ্তমান সংস্থাপন সঞ্চয় কৰক" আৰু পৰৱৰ্তী " -"বাৰ লগিন কৰোতে আপুনি ইয়াক হস্তচালিতভাৱে পুনৰাম্ভ কৰিব লাগিব।" +#: ../data/50-mutter-windows.xml.in.h:7 +msgid "Toggle shaded state" +msgstr "ছায়াবৃত অবস্থা অদল-বদল কৰক" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "ডিবাগ লগ খোলিব পৰা নগল: %s\n" +#: ../data/50-mutter-windows.xml.in.h:8 +msgid "Close window" +msgstr "উইন্ডো বন্ধ কৰক" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "fdopen() লগ নথিপত্ৰ %s খোলিব পৰা নগল: %s\n" +#: ../data/50-mutter-windows.xml.in.h:9 +msgid "Hide window" +msgstr "উইন্ডোক লুকাওক" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "লগ নথিপত্ৰ %s খোলা হৈছে\n" +#: ../data/50-mutter-windows.xml.in.h:10 +msgid "Move window" +msgstr "উইন্ডো স্থানান্তৰ কৰক" -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "ভাৰ্বোচ অৱস্থাৰ সমৰ্থন নোহোৱাকৈ Muffin কম্পাইল কৰা হৈছে\n" +#: ../data/50-mutter-windows.xml.in.h:11 +msgid "Resize window" +msgstr "উইন্ডোক পুনৰ আকাৰ দিয়ক" -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "উইন্ডো ব্যৱস্থাপক: " +#: ../data/50-mutter-windows.xml.in.h:12 +msgid "Toggle window on all workspaces or one" +msgstr "সকলো কৰ্মস্থানত অথবা এটাত থকা উইন্ডো অদল বদল কৰক" -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "উইন্ডো ব্যৱস্থাপকত বাগ: " +#: ../data/50-mutter-windows.xml.in.h:13 +msgid "Raise window if covered, otherwise lower it" +msgstr "যদি উইন্ডো ঢকা থাকে তাক উত্থাপন কৰক, নহলে তলত নমাওক" -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "উইন্ডো ব্যৱস্থাপক সতৰ্কবাৰ্তা: " +#: ../data/50-mutter-windows.xml.in.h:14 +msgid "Raise window above other windows" +msgstr "অন্যান্য উইন্ডোৰ ওপৰত উইন্ডো উত্থাপন কৰক" -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "উইন্ডো ব্যৱস্থাপক ত্ৰুটি: " +#: ../data/50-mutter-windows.xml.in.h:15 +msgid "Lower window below other windows" +msgstr "উইন্ডোটোক অন্য উইন্ডোৰ তলত নমাওক" -#. first time through -#: ../src/core/window.c:7224 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"উইন্ডো %s দ্বাৰা ICCCMলে নিৰ্ধাৰিত WM_CLIENT_LEADER উইন্ডোৰ পৰিবৰ্তে নিজৰ উপৰ " -"SM_CLIENT_ID নিৰ্ধাৰিত হৈছে ।\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7887 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %" -"d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"উইন্ডো %s -এ এটা MWM আভাস সংহতি কৰে ইংগিত দিয়াকৈ যে ইয়াক পুনৰআকৃতি কৰিব " -"নোৱাৰি, কিন্তু নূন্যতম আকাৰ %d x %d আৰু সৰ্বাধিক আকাৰ %d x %d সংহতি কৰে; ই বিশেষ " -"এটা সংজ্ঞা নিদিয়ে।\n" +#: ../data/50-mutter-windows.xml.in.h:16 +msgid "Maximize window vertically" +msgstr "উইন্ডোক উলম্বভাৱে ডাঙৰ কৰক" -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "অনুপ্ৰয়োগ দ্বাৰা ভুল _NET_WM_PID %lu নিৰ্ধাৰিত হৈছে\n" +#: ../data/50-mutter-windows.xml.in.h:17 +msgid "Maximize window horizontally" +msgstr "উইন্ডোক আনুভূমিকভাৱে ডাঙৰ কৰক" -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (%s'ৰ উপৰ)" - -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "অবৈধ WM_TRANSIENT_FOR উইন্ডো 0x%lx, %s'ৰ বাবে নিৰ্ধাৰিত হৈছে ।\n" - -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "WM_TRANSIENT_FOR window 0x%lx %s -ৰ বাবে লুপ সৃষ্টি কৰিব।\n" - -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"উইন্ডো 0x%lx -ৰ %s বৈশিষ্ট আছে\n" -"যাৰ ধৰণ %s আৰু বিন্যাস %d থাকিব বুলি আশা কৰা হৈছিল\n" -"আৰু প্ৰকৃততে ধৰণ %s বিন্যাস %d n_items %d আছে।\n" -"ই খুব সম্ভব এটা অনুপ্ৰয়োগ বাগ, এটা উইন্ডো ব্যৱস্থাপক বাগ নহয়।\n" -"উইন্ডোৰ শীৰ্ষক হল=\"%s\" ক্লাচ=\"%s\" নাম=\"%s\"\n" - -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "বৈশিষ্ট %s window 0x%lx -ত অন্তৰ্ভুক্ত কৰিছিল অবৈধ UTF-8\n" +#: ../data/50-mutter-windows.xml.in.h:18 +msgid "View split on left" +msgstr "বিভাজনক বাঁওফালে দৰ্শন কৰক" -#: ../src/core/xprops.c:494 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"বৈশিষ্ট %s window 0x%lx -ত তালিকাৰ উপাদান %d -ৰ বাবে অবৈধ UTF-8 অন্তৰ্ভুক্ত " -"কৰিছিল\n" +#: ../data/50-mutter-windows.xml.in.h:19 +msgid "View split on right" +msgstr "বিভাজনক সোঁফালে দৰ্শন কৰক" -#: ../src/muffin.desktop.in.h:1 ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" +#: ../data/mutter.desktop.in.h:1 +msgid "Mutter" +msgstr "Mutter" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 +#: ../data/org.gnome.mutter.gschema.xml.in.h:1 msgid "Modifier to use for extended window management operations" -msgstr "প্ৰসাৰীত উইন্ডো ব্যৱস্থাপনা কাৰ্য্যসমূহৰ কাৰণে ব্যৱহৃত পৰিৱৰ্তক" +msgstr "প্ৰসাৰীত উইন্ডো ব্যৱস্থাপনা কাৰ্য্যসমূহৰ বাবে ব্যৱহৃত পৰিৱৰ্তক" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 +#: ../data/org.gnome.mutter.gschema.xml.in.h:2 msgid "" "This key will initiate the \"overlay\", which is a combination window " "overview and application launching system. The default is intended to be the " "\"Windows key\" on PC hardware. It's expected that this binding either the " "default or set to the empty string." msgstr "" -"এই চাবিয়ে \"overlay\" -ক আৰম্ভ কৰিব, যোনটো এটা সংযোগ উইন্ডো আৰু অনুপ্ৰয়োগ লঞ্চ " -"চিস্টেম। অবিকল্পিত PC হাৰ্ডওৱাৰৰ \"Windows key\" হিচাপে সংকল্পিত। এইটো আশা কৰা " +"এই কি'য়ে \"overlay\" ক আৰম্ভ কৰিব, যোনটো এটা সংযোগ উইন্ডো আৰু এপ্লিকেচন লঞ্চ " +"চিস্টেম। অবিকল্পিত PC হাৰ্ডৱেৰৰ \"Windows key\" হিচাপে সংকল্পিত। এইটো আশা কৰা " "হৈছে যে এই বন্ধন হৈতো অবিকল্পিত নহলে ৰিক্ত স্ট্ৰিংলে সংহিত।" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 +#: ../data/org.gnome.mutter.gschema.xml.in.h:3 msgid "Attach modal dialogs" msgstr "মোডাল ডাইলগসমূহ সংযুক্ত কৰক" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 +#: ../data/org.gnome.mutter.gschema.xml.in.h:4 msgid "" "When true, instead of having independent titlebars, modal dialogs appear " "attached to the titlebar of the parent window and are moved together with " @@ -411,565 +307,574 @@ msgstr "" "যেতিয়া সত্য, স্বাধিন টাইটেলবাৰসমূহৰ পৰিৱৰ্তে, মোডাল ডাইলগসমূহ উপধায়ক উইন্ডোৰ " "টাইটেলবাৰৰ লগত সংযুক্ত পোৱা যায় আৰু উপধায়ক উইন্ডো লগত আতৰোৱা হয়।" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -msgid "Live Hidden Windows" -msgstr "জীৱন্ত লুকাই থকা উইন্ডোসমূহ" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"লুকাই থকা উইন্ডোসমূহ (যেনে নূন্যতম উইন্ডোসমূহ আৰু বৰ্তমানক এৰি অন্য কৰ্মস্থানত থকা " -"উইন্ডোসমূহ) জীৱন্ত ৰখা হব নে।" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 +#: ../data/org.gnome.mutter.gschema.xml.in.h:5 msgid "Enable edge tiling when dropping windows on screen edges" msgstr "উইন্ডোসমূহক পৰ্দাৰ প্ৰান্তসমূহত এৰোতে প্ৰান্ত টাইলিং সামৰ্থবান কৰক" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 +#: ../data/org.gnome.mutter.gschema.xml.in.h:6 msgid "" "If enabled, dropping windows on vertical screen edges maximizes them " "vertically and resizes them horizontally to cover half of the available " "area. Dropping windows on the top screen edge maximizes them completely." msgstr "" -"যদি সামৰ্থবান থাকে, উলম্ব পৰ্দা প্ৰান্তসমূহত উইন্ডোসমূহ ড্ৰপ কৰিলে সিহত উলম্বভাৱে সৰ্বোত্তম " -"আকাৰ আৰু আনুভূমিকভাৱে পুনৰ আকাৰ প্ৰাপ্ত কৰে উপলব্ধ স্থানৰ অৰ্ধেক পূৰ্ণ কৰিবলে। উপৰ " -"পৰ্দা প্ৰান্তত উইন্ডোসমূহ ড্ৰপ কৰিলে সিহত সম্পূৰ্ণভাৱে সৰ্বোত্তম আকাৰ প্ৰাপ্ত কৰে।" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 +"যদি সামৰ্থবান থাকে, উলম্ব পৰ্দা প্ৰান্তসমূহত উইন্ডোসমূহ ড্ৰপ কৰিলে সিহত " +"উলম্বভাৱে " +"সৰ্বোত্তম আকাৰ আৰু আনুভূমিকভাৱে পুনৰ আকাৰ প্ৰাপ্ত কৰে উপলব্ধ স্থানৰ অৰ্ধেক " +"পূৰ্ণ কৰিবলে। " +"ওপৰ পৰ্দা প্ৰান্তত উইন্ডোসমূহ ড্ৰপ কৰিলে সিহত সম্পূৰ্ণভাৱে সৰ্বোত্তম আকাৰ " +"প্ৰাপ্ত কৰে।" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:7 msgid "Workspaces are managed dynamically" -msgstr "কাৰ্য্যস্থানসমূহক চলমানভাৱে ব্যৱস্থাপনা কৰা হয়" +msgstr "কৰ্মক্ষেত্ৰসমূহক চলমানভাৱে ব্যৱস্থাপনা কৰা হয়" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 +#: ../data/org.gnome.mutter.gschema.xml.in.h:8 msgid "" "Determines whether workspaces are managed dynamically or whether there's a " "static number of workspaces (determined by the num-workspaces key in org." "gnome.desktop.wm.preferences)." msgstr "" -"কাৰ্য্যস্থানসমূহ চলমানভাৱে ব্যৱস্থাপনা কৰা হয় নে কাৰ্য্যস্থানৰসমূহৰ এটা স্থিৰ সংখ্যা আছে " -"নিৰ্ধাৰণ কৰে (org." -"gnome.desktop.wm.preferences ত num-workspaces কি দ্বাৰা নিৰ্ধাৰিত)।" +"কৰ্মক্ষেত্ৰসমূহ চলমানভাৱে ব্যৱস্থাপনা কৰা হয় নে কৰ্মক্ষেত্ৰৰসমূহৰ এটা স্থিৰ " +"সংখ্যা আছে " +"নিৰ্ধাৰণ কৰে (org.gnome.desktop.wm.preferences ত num-workspaces কি দ্বাৰা " +"নিৰ্ধাৰিত)।" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 +#: ../data/org.gnome.mutter.gschema.xml.in.h:9 msgid "Workspaces only on primary" -msgstr "প্ৰাথমিকত থকা কৰ্নস্থানসমূহ" +msgstr "প্ৰাথমিকত থকা কৰ্মক্ষেত্ৰসমূহ" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 +#: ../data/org.gnome.mutter.gschema.xml.in.h:10 msgid "" "Determines whether workspace switching should happen for windows on all " "monitors or only for windows on the primary monitor." msgstr "" -"নিৰ্ধাৰন কৰে যে কৰ্মস্থান অদল বদল সকলো মনিটৰৰ উইন্ডোৰ কাৰণে হব লাগে নে কেৱল " -"প্ৰাথমিক মনিটৰৰ উইন্ডোৰ কাৰণে হব লাগে।" +"নিৰ্ধাৰণ কৰে যে কৰ্মস্থান অদল বদল সকলো মনিটৰৰ উইন্ডোৰ বাবে হব লাগে নে কেৱল " +"প্ৰাথমিক মনিটৰৰ উইন্ডোৰ বাবে হব লাগে।" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 +#: ../data/org.gnome.mutter.gschema.xml.in.h:11 msgid "No tab popup" msgstr "কোনো টেব পপআপ নাই" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 +#: ../data/org.gnome.mutter.gschema.xml.in.h:12 msgid "" "Determines whether the use of popup and highlight frame should be disabled " "for window cycling." msgstr "" -"উইন্ডো চক্ৰৰ বাবে পপআপ আৰু উজ্জ্বলকৰণ ফ্ৰেইমৰ ব্যৱহাৰ অসামৰ্থবান কৰা হব নে নিৰ্ধাৰণ কৰে।" +"উইন্ডো চক্ৰৰ বাবে পপআপ আৰু উজ্জ্বলকৰণ ফ্ৰেইমৰ ব্যৱহাৰ অসামৰ্থবান কৰা হব নে " +"নিৰ্ধাৰণ " +"কৰে।" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 +#: ../data/org.gnome.mutter.gschema.xml.in.h:13 +msgid "Delay focus changes until the pointer stops moving" +msgstr "বিলম্বৰ ফকাচ পৰিবৰ্তন হয় যেতিয়ালৈকে পইন্টাৰে গমন কৰা বন্ধ নকৰে" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:14 +msgid "" +"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " +"the focus will not be changed immediately when entering a window, but only " +"after the pointer stops moving." +msgstr "" +"যদি true লে সংহতি কৰা হয়, আৰু ফকাচ অৱস্থা হয় \"sloppy\" অথবা \"mouse\" তেন্তে " +"এটা উইন্ডোত সুমাওতে ফকাচ তৎক্ষনাত পৰিবৰ্তন নহয়, পইন্টাৰ গমন কৰা বন্ধ কৰাৰ " +"পিছত হয়।" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:15 msgid "Draggable border width" msgstr "ড্ৰেগ কৰিব পৰা সীমা প্ৰস্থ" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 +#: ../data/org.gnome.mutter.gschema.xml.in.h:16 msgid "" "The amount of total draggable borders. If the theme's visible borders are " "not enough, invisible borders will be added to meet this value." msgstr "" -"ড্ৰেগ কৰিব পৰা সৰ্বমুঠ প্ৰস্থসমূহৰ পৰিমাণ। যদি থীমৰ দৃশ্যমান সীমা পৰ্যাপ্ত নহয়, এই মান পুৰন " -"কৰিবলে " -"অদৃশ্য সীমাসমূহ।" +"ড্ৰেগ কৰিব পৰা সৰ্বমুঠ প্ৰস্থসমূহৰ পৰিমাণ। যদি থীমৰ দৃশ্যমান সীমা পৰ্যাপ্ত " +"নহয়, এই মান " +"পূৰ্ণ কৰিবলে অদৃশ্য সীমাসমূহ।" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:17 -#| msgid "Remove Window From Top" +#: ../data/org.gnome.mutter.gschema.xml.in.h:17 +msgid "Auto maximize nearly monitor sized windows" +msgstr "মনিটৰৰ প্ৰায় সমান আকাৰৰ উইন্ডোসমূহক স্বচালিতভাৱে ডাঙৰ কৰক" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:18 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" +"যদি সামৰ্থবান থাকে, আৰম্ভণিত মনিটৰৰ আকাৰৰ নতুন উইন্ডোসমূহ স্বচালিতভাৱে " +"সৰ্বোচ্চ আকাৰ " +"প্ৰাপ্ত কৰে।" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:19 +msgid "Place new windows in the center" +msgstr "নতুন উইন্ডোসমূহক কেন্দ্ৰত থওক" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:20 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" +"যেতিয়া সত্য, নতুন উইন্ডোসমূহক সদায় মনিটৰৰ সক্ৰিয় পৰ্দাৰ কেন্দ্ৰত থোৱা হব।" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:21 msgid "Select window from tab popup" msgstr "টেব পপআপৰ পৰা উইন্ডো বাছক" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:18 +#: ../data/org.gnome.mutter.gschema.xml.in.h:22 msgid "Cancel tab popup" msgstr "টেব পপআপ বাতিল কৰক" -#: ../src/tools/muffin-message.c:123 +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:1 +#| msgid "Switch to workspace 1" +msgid "Switch to VT 1" +msgstr "VT 1 লৈ চুইচ কৰক" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:2 +#| msgid "Switch to workspace 2" +msgid "Switch to VT 2" +msgstr "VT 2 লৈ চুইচ কৰক" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:3 +#| msgid "Switch to workspace 3" +msgid "Switch to VT 3" +msgstr "VT 3 লৈ চুইচ কৰক" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:4 +#| msgid "Switch to workspace 4" +msgid "Switch to VT 4" +msgstr "VT 4 লৈ চুইচ কৰক" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:5 +#| msgid "Switch to workspace 5" +msgid "Switch to VT 5" +msgstr "VT 5 লৈ চুইচ কৰক" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:6 +#| msgid "Switch to workspace 6" +msgid "Switch to VT 6" +msgstr "VT 6 লৈ চুইচ কৰক" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:7 +#| msgid "Switch to workspace 7" +msgid "Switch to VT 7" +msgstr "VT 7 লৈ চুইচ কৰক" + +#: ../src/backends/meta-monitor-manager.c:412 +msgid "Built-in display" +msgstr "বিল্ট-ইন প্ৰদৰ্শন" + +#: ../src/backends/meta-monitor-manager.c:437 +#| msgid "Unknown %s" +msgid "Unknown" +msgstr "অজ্ঞাত" + +#: ../src/backends/meta-monitor-manager.c:439 +#| msgid "Unknown %s" +msgid "Unknown Display" +msgstr "অজ্ঞাত প্ৰদৰ্শন" + +#. TRANSLATORS: this is a monitor vendor name, followed by a +#. * size in inches, like 'Dell 15"' +#. +#: ../src/backends/meta-monitor-manager.c:447 #, c-format -msgid "Usage: %s\n" -msgstr "ব্যৱহাৰপদ্ধতি: %s\n" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/frames.c:1158 -msgid "Close Window" -msgstr "উইন্ডো বন্ধ কৰক" +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: ../src/compositor/compositor.c:441 +#, c-format +msgid "" +"Another compositing manager is already running on screen %i on display \"%s" +"\"." +msgstr "অন্য মিশ্ৰণ ব্যৱস্থাপক ইতিমধ্যে চলি আছে পৰ্দা %i প্ৰদৰ্শন \"%s\"।" -#: ../src/ui/frames.c:1161 -msgid "Window Menu" -msgstr "উইন্ডো মেনু" +#: ../src/compositor/meta-background.c:1044 +msgid "background texture could not be created from file" +msgstr "পটভূমিৰ ৰূপ ফাইলৰ পৰা সৃষ্টি কৰিব পৰা নগল" -#: ../src/ui/frames.c:1164 -msgid "Minimize Window" -msgstr "উইন্ডো লুকাওক" +#: ../src/core/bell.c:214 +msgid "Bell event" +msgstr "ঘন্টা ঘটনা" -#: ../src/ui/frames.c:1167 -msgid "Maximize Window" -msgstr "উইন্ডো ডাঙৰ কৰক" +#: ../src/core/delete.c:127 +#, c-format +msgid "“%s” is not responding." +msgstr "“%s” এ প্ৰতিক্ৰিয়া কৰা নাই।" -# -#: ../src/ui/frames.c:1170 -msgid "Restore Window" -msgstr "উইন্ডো পুনৰ সংৰক্ষণ কৰক" - -#: ../src/ui/frames.c:1173 -msgid "Roll Up Window" -msgstr "উইন্ডো মেৰিয়াওক" - -#: ../src/ui/frames.c:1176 -msgid "Unroll Window" -msgstr "উইন্ডো খোলক" - -#: ../src/ui/frames.c:1179 -msgid "Keep Window On Top" -msgstr "উইন্ডোক উপৰত ৰাখক" - -#: ../src/ui/frames.c:1182 -msgid "Remove Window From Top" -msgstr "উইন্ডোক উপৰৰ পৰা আতৰাওক" - -#: ../src/ui/frames.c:1185 -msgid "Always On Visible Workspace" -msgstr "সদায় দৃশ্যমান কৰ্মস্থানত" - -#: ../src/ui/frames.c:1188 -msgid "Put Window On Only One Workspace" -msgstr "উইন্ডোক কেৱল এটা কৰ্মস্থানত ৰাখক" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "সৰু কৰক (_n)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "ডাঙৰ কৰক (_x)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "ডাঙৰৰ পৰা সৰু কৰক (_x)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "মেৰিয়াওক (_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "খোলক (_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "স্থানান্তৰ কৰক (_M)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "পুনৰ আকাৰ দিয়ক (_R)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "পৰ্দাৰ উপৰ শীৰ্ষকবাৰ স্থানান্তৰ কৰক (_s)" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "সদায় উপৰত" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "সদায় দৃশ্যমান কৰ্মস্থানত (_A)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "কেৱল এই কৰ্মস্থানত (_O)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "বাওঁফালৰ কৰ্মস্থানত স্থানান্তৰ কৰক (_L)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "সোঁফালৰ কৰ্মস্থানত স্থানান্তৰ কৰক (_i)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "ওপৰৰ কৰ্মস্থানত স্থানান্তৰ কৰক (_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "তলৰ কৰ্মস্থানত স্থানান্তৰ কৰক (_D)" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "বন্ধ কৰক (_C)" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "কৰ্মস্থান %d%n" - -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "কৰ্মস্থান ১০ (_0)" - -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "কৰ্মস্থান %s%d" - -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "অন্য কৰ্মস্থানত স্থানান্তৰ কৰক (_W)" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "মেটা" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "উত্তম" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "চঞ্চল" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" +#: ../src/core/delete.c:129 +msgid "Application is not responding." +msgstr "এপ্লিকেচন প্ৰতিক্ৰিয়া কৰা নাই।" + +#: ../src/core/delete.c:134 +msgid "" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." +msgstr "" +"আপুনি এপ্লিকেচন চলি থাকিবলে অলপ সময় অপেক্ষা কৰিব পাৰে অথবা ইয়াকক সম্পূৰ্ণভাৱে " +"প্ৰস্থান কৰিবলে বাধ্য কৰিব পাৰে।" + +#: ../src/core/delete.c:141 +msgid "_Wait" +msgstr "অপেক্ষা কৰক (_W)" + +#: ../src/core/delete.c:141 +msgid "_Force Quit" +msgstr "বলপূৰ্বক বন্ধ কৰক (_F)" + +#: ../src/core/display.c:547 +#, c-format +msgid "Failed to open X Window System display '%s'\n" +msgstr "X উইন্ডো চিস্টেম প্ৰদৰ্শন '%s'খোলিব পৰা নগল \n" + +#: ../src/core/main.c:176 +msgid "Disable connection to session manager" +msgstr "অধিবেশন ব্যৱস্থাপকৰ সৈতে সংযোগ বিচ্ছিন্ন কৰক" + +#: ../src/core/main.c:182 +msgid "Replace the running window manager" +msgstr "চলি থকা উইন্ডো ব্যৱস্থাপকক প্ৰতিস্থাপন কৰক" + +#: ../src/core/main.c:188 +msgid "Specify session management ID" +msgstr "অধিবেশন ব্যৱস্থাপনাৰ ID উল্লেখ কৰক" + +#: ../src/core/main.c:193 +msgid "X Display to use" +msgstr "ব্যৱহাৰৰ বাবে X প্ৰদৰ্শন" + +#: ../src/core/main.c:199 +msgid "Initialize session from savefile" +msgstr "সংৰক্ষণ ফাইলৰ পৰা অধিবেশন আৰম্ভ কৰক" + +#: ../src/core/main.c:205 +msgid "Make X calls synchronous" +msgstr "X কলসমূহ সংমিহলি কৰক" + +#: ../src/core/main.c:212 +msgid "Run as a wayland compositor" +msgstr "wayland কম্পচিটৰ ৰূপে চলাওক" + +#: ../src/core/main.c:220 +msgid "Run as a full display server, rather than nested" +msgstr "এটা সম্পূৰ্ণ প্ৰদৰ্শন চাৰ্ভাৰ ৰূপে চলাওক, নেস্টেডৰ পৰিৱৰ্তে" + +#: ../src/core/main.c:464 +#, c-format +msgid "Failed to scan themes directory: %s\n" +msgstr "থীমৰ ডাইৰেকটৰি স্কেন কৰিব পৰা নগল: %s\n" + +#: ../src/core/main.c:480 +#, c-format +msgid "" +"Could not find a theme! Be sure %s exists and contains the usual themes.\n" +msgstr "" +"এটা থীম পোৱা নগল! সুনিশ্চিত হওক %s অস্তিত্ববান আৰু স্বাভাৱিক থীমসমূহ " +"অন্তৰ্ভুক্ত কৰে।\n" + +#: ../src/core/mutter.c:39 +#, c-format +msgid "" +"mutter %s\n" +"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" +msgstr "" +"mutter %s\n" +"স্বত্বাধিকাৰ (C) ২০০১-%d Havoc Pennington, Red Hat, Inc., আৰু অন্য\n" +"ই এটা বিনামুলীয়া চফ্টৱেৰ; কপিৰ চুক্তিসমূহৰ বাবে উৎস চাওক।\n" +"ইয়াৰ কোনো ৱাৰেন্টি নাই; ব্যৱশায়ীক অথবা এটা বিশেষ কাৰণৰ বাবে উপযুক্ত হলেও " +"নহয়।\n" + +#: ../src/core/mutter.c:53 +msgid "Print version" +msgstr "সংস্কৰণ প্ৰিন্ট কৰক" + +#: ../src/core/mutter.c:59 +msgid "Mutter plugin to use" +msgstr "ব্যৱহাৰ কৰিবলে Mutter প্লাগিন" + +#: ../src/core/prefs.c:2100 +#, c-format +msgid "Workspace %d" +msgstr "কৰ্মস্থান %d" + +#: ../src/core/screen.c:548 +#, c-format +msgid "Screen %d on display '%s' is invalid\n" +msgstr "পৰ্দা %d প্ৰদৰ্শন '%s' ত অবৈধ\n" + +#: ../src/core/screen.c:564 +#, c-format +msgid "" +"Screen %d on display \"%s\" already has a window manager; try using the --" +"replace option to replace the current window manager.\n" +msgstr "" +"পৰ্দা %d প্ৰদৰ্শন \"%s\" ৰ এটা উইন্ডো ব্যৱস্থাপক ইতিমধ্যে আছে; বৰ্তমানে " +"উইন্ডো " +"ব্যৱস্থাপক পৰিবৰ্তন কৰোঁতে --replace বিকল্প প্ৰয়োগ কৰক।\n" + +#: ../src/core/screen.c:657 +#, c-format +msgid "Screen %d on display \"%s\" already has a window manager\n" +msgstr "পৰ্দা %d প্ৰদৰ্শন \"%s\" ৰ এটা উইন্ডো ব্যৱস্থাপক ইতিমধ্যে আছে\n" + +#: ../src/core/util.c:118 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "ভাৰ্বোচ অৱস্থাৰ সমৰ্থন নোহোৱাকৈ Mutter কম্পাইল কৰা হৈছিল\n" #. Translators: This represents the size of a window. The first number is #. * the width of the window and the second is the height. #. -#: ../src/ui/resizepopup.c:113 +#: ../src/ui/resizepopup.c:134 #, c-format msgid "%d x %d" msgstr "%d x %d" -#: ../src/ui/theme.c:253 +#: ../src/ui/theme.c:233 msgid "top" msgstr "ওপৰত" -#: ../src/ui/theme.c:255 +#: ../src/ui/theme.c:235 msgid "bottom" msgstr "তলত" -#: ../src/ui/theme.c:257 +#: ../src/ui/theme.c:237 msgid "left" msgstr "বাওঁফালে" -#: ../src/ui/theme.c:259 +#: ../src/ui/theme.c:239 msgid "right" msgstr "সোঁফালে" -#: ../src/ui/theme.c:286 +#: ../src/ui/theme.c:267 #, c-format msgid "frame geometry does not specify \"%s\" dimension" msgstr "ফ্ৰেইম জ্যামিতি দ্বাৰা \"%s\" পৰিমাপ নিৰ্ধাৰিত নহয়" -#: ../src/ui/theme.c:305 +#: ../src/ui/theme.c:286 #, c-format msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "ফ্ৰেইম জ্যামিতি দ্বাৰা \"%s\" পৰিমাপ \"%s\" প্ৰান্তৰ বাবে নিৰ্ধাৰিত নহয়" +msgstr "" +"ফ্ৰেইম জ্যামিতি দ্বাৰা \"%s\" পৰিমাপ \"%s\" প্ৰান্তৰ বাবে নিৰ্ধাৰিত নহয়" -#: ../src/ui/theme.c:342 +#: ../src/ui/theme.c:323 #, c-format msgid "Button aspect ratio %g is not reasonable" msgstr "বুটামৰ এচপেক্ট অনুপাত %g যথাযথ নহয়" -#: ../src/ui/theme.c:354 +#: ../src/ui/theme.c:335 #, c-format msgid "Frame geometry does not specify size of buttons" msgstr "ফ্ৰেইম জ্যামিতি দ্বাৰা বুটামৰ মাপ নিৰ্ধাৰিত নহয়" -#: ../src/ui/theme.c:1067 +#: ../src/ui/theme.c:1061 #, c-format msgid "Gradients should have at least two colors" -msgstr "গ্ৰেডিয়েন্টেৰ ক্ষেত্ৰত দুটা ৰঙ নিৰ্ধাৰিত হোৱা আবশ্যক" +msgstr "গ্ৰেডিয়েন্টৰ ক্ষেত্ৰত দুটা ৰঙ নিৰ্ধাৰিত হোৱা আবশ্যক" -#: ../src/ui/theme.c:1219 +#: ../src/ui/theme.c:1211 #, c-format msgid "" "GTK custom color specification must have color name and fallback in " "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" msgstr "" -"GTK স্বনিৰ্বাচিত ৰঙ ধাৰ্য্যৰ ব্ৰেকেটত ৰঙ নাম আৰু ফলবেক থাকিব লাগিব, উদাহৰনস্বৰুপে " -"gtk:custom(foo,bar); \"%s\" -ক বিশ্লেষণ কৰিব নোৱাৰে" +"GTK স্বনিৰ্বাচিত ৰঙ ধাৰ্য্যৰ ব্ৰেকেটত ৰঙ নাম আৰু ফলবেক থাকিব লাগিব, " +"উদাহৰনস্বৰুপে " +"gtk:custom(foo,bar); \"%s\" ক বিশ্লেষণ কৰিব নোৱাৰে" -#: ../src/ui/theme.c:1235 +#: ../src/ui/theme.c:1227 #, c-format msgid "" "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" "_ are valid" -msgstr "gtk:custom -ৰ color_name প্ৰাচলত অবৈধ আখৰ '%c', কেৱল A-Za-z0-9-_ সমূহ বৈধ" +msgstr "" +"gtk:custom ৰ color_name প্ৰাচলত অবৈধ আখৰ '%c', কেৱল A-Za-z0-9-_ সমূহ বৈধ" -#: ../src/ui/theme.c:1249 +#: ../src/ui/theme.c:1241 #, c-format msgid "" "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " "fit the format" msgstr "" -"Gtk:custom বিন্যাস হল \"gtk:custom(color_name,fallback)\", \"%s\" বিন্যাসত খাপ " +"Gtk:custom বিন্যাস হল \"gtk:custom(color_name,fallback)\", \"%s\" বিন্যাসত " +"খাপ " "নাখায়" -#: ../src/ui/theme.c:1294 +#: ../src/ui/theme.c:1286 #, c-format msgid "" "GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " "where NORMAL is the state; could not parse \"%s\"" msgstr "" -"GTK ৰঙ ধাৰ্য্যকৰণৰ অৱস্থা ব্ৰেকেটত থাকিব লাগিব, উদাহৰনস্বৰুপে gtk:fg[NORMAL] যত " -"NORMAL iহল অৱস্থা; বিশ্লেষণ কৰিব নোৱাৰি \"%s\"" +"GTK ৰঙ ধাৰ্য্যকৰণৰ অৱস্থা ব্ৰেকেটত থাকিব লাগিব, উদাহৰনস্বৰুপে gtk:fg[NORMAL] " +"যত " +"NORMAL হল অৱস্থা; বিশ্লেষণ কৰিব নোৱাৰি \"%s\"" -#: ../src/ui/theme.c:1308 +#: ../src/ui/theme.c:1300 #, c-format msgid "" "GTK color specification must have a close bracket after the state, e.g. gtk:" "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" msgstr "" -"GTK ৰঙ ধাৰ্য্যকৰণৰ অৱস্থাৰ পিছত এটা বন্ধ ব্ৰেকেট থাকিব লাগিব, উদাহৰনস্বৰুপে gtk:fg" -"[NORMAL] যত NORMAL হল অৱস্থা; বিশ্লেষণ কৰিব নোৱাৰি \"%s\"" +"GTK ৰঙ ধাৰ্য্যকৰণৰ অৱস্থাৰ পিছত এটা বন্ধ ব্ৰেকেট থাকিব লাগিব, উদাহৰনস্বৰুপে " +"gtk:" +"fg[NORMAL] যত NORMAL হল অৱস্থা; বিশ্লেষণ কৰিব নোৱাৰি \"%s\"" -#: ../src/ui/theme.c:1319 +#: ../src/ui/theme.c:1311 #, c-format msgid "Did not understand state \"%s\" in color specification" -msgstr "ৰঙ ধাৰ্যকৰণত অৱস্থা \"%s\" বোধগম্য নহয়" +msgstr "ৰঙ ধাৰ্যকৰণত অৱস্থা \"%s\" বোধগম্য নহয়" -#: ../src/ui/theme.c:1332 +#: ../src/ui/theme.c:1324 #, c-format msgid "Did not understand color component \"%s\" in color specification" -msgstr "ৰঙ ধাৰ্য্যকৰণত ৰঙ'ৰ উপাদান \"%s\" বোধগম্য নহয়" +msgstr "ৰঙ ধাৰ্য্যকৰণত ৰঙৰ উপাদান \"%s\" বোধগম্য নহয়" -#: ../src/ui/theme.c:1361 +#: ../src/ui/theme.c:1352 #, c-format msgid "" "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " "format" -msgstr "ব্লেন্ড বিন্যাস \"blend/bg_color/fg_color/alpha\", \"%s\" বিন্যাসৰ সৈতে খাপ নাখায়" +msgstr "" +"ব্লেন্ড বিন্যাস \"blend/bg_color/fg_color/alpha\", \"%s\" বিন্যাসৰ সৈতে খাপ " +"নাখায়" -#: ../src/ui/theme.c:1372 +#: ../src/ui/theme.c:1363 #, c-format msgid "Could not parse alpha value \"%s\" in blended color" msgstr "ব্লেন্ড কৰা ৰঙলে আল্ফা মান \"%s\" বিশ্লেষণ কৰিব পৰা নগল" -#: ../src/ui/theme.c:1382 +#: ../src/ui/theme.c:1373 #, c-format msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "ব্লেন্ড কৰা ৰঙলে আল্ফা মান \"%s\" 0.0 আৰু 1.0 -ৰ মাজত নহয়" +msgstr "ব্লেন্ড কৰা ৰঙলে আল্ফা মান \"%s\" 0.0 আৰু 1.0 ৰ মাজত নহয়" -#: ../src/ui/theme.c:1429 +#: ../src/ui/theme.c:1419 #, c-format -msgid "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "ছায়াৰ বিন্যাস \"shade/base_color/factor\", \"%s\" বিন্যাসেৰ সৈতে খাপ নাখায়" +msgid "" +"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" +msgstr "" +"ছায়াৰ বিন্যাস \"shade/base_color/factor\", \"%s\" বিন্যাসৰ সৈতে খাপ নাখায়" -#: ../src/ui/theme.c:1440 +#: ../src/ui/theme.c:1430 #, c-format msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "ছায়াযুক্ত ৰঙ'ৰ ক্ষেত্ৰত ছায়াৰ মাপ \"%s\" বিশ্লেষণ কৰিব পৰা নগল" +msgstr "ছায়াযুক্ত ৰঙৰ ক্ষেত্ৰত ছায়াৰ মাপ \"%s\" বিশ্লেষণ কৰিব পৰা নগল" -#: ../src/ui/theme.c:1450 +#: ../src/ui/theme.c:1440 #, c-format msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "ছায়াযুক্ত ৰঙ'ৰ ক্ষেত্ৰত ছায়াৰ মান \"%s\" ঝণাত্মক" +msgstr "ছায়াযুক্ত ৰঙৰ ক্ষেত্ৰত ছায়াৰ মান \"%s\" ঋণাত্মক" -#: ../src/ui/theme.c:1479 +#: ../src/ui/theme.c:1469 #, c-format msgid "Could not parse color \"%s\"" msgstr "\"%s\" ৰঙ বিশ্লেষণ কৰিব পৰা নগল" -#: ../src/ui/theme.c:1790 +#: ../src/ui/theme.c:1778 #, c-format msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "অক্ষ অভিব্যক্তিয়ে '%s' আখৰ অন্তৰ্ভুক্ত কৰে যাৰ ব্যৱহাৰ অনুমোদিত নহয়" +msgstr "অক্ষ অভিব্যক্তিয়ে '%s' আখৰ অন্তৰ্ভুক্ত কৰে যাৰ ব্যৱহাৰ অনুমোদিত নহয়" -#: ../src/ui/theme.c:1817 +#: ../src/ui/theme.c:1805 #, c-format msgid "" "Coordinate expression contains floating point number '%s' which could not be " "parsed" -msgstr "অক্ষ অভিব্যক্তিয়ে '%s' দশমিক সংখ্যা অন্তৰ্ভুক্ত কৰে যি বিশ্লেষণ কৰিব পৰা নগল" +msgstr "" +"অক্ষ অভিব্যক্তিয়ে '%s' দশমিক সংখ্যা অন্তৰ্ভুক্ত কৰে যি বিশ্লেষণ কৰিব পৰা নগল" -#: ../src/ui/theme.c:1831 +#: ../src/ui/theme.c:1819 #, c-format msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "অক্ষ অভিব্যক্তিয়ে '%s' পূৰ্ণ সংখ্যা অন্তৰ্ভুক্ত কৰে যি বিশ্লেষণ কৰিব পৰা নগল" +msgstr "" +"অক্ষ অভিব্যক্তিয়ে '%s' পূৰ্ণ সংখ্যা অন্তৰ্ভুক্ত কৰে যি বিশ্লেষণ কৰিব পৰা নগল" -#: ../src/ui/theme.c:1953 +#: ../src/ui/theme.c:1940 #, c-format msgid "" "Coordinate expression contained unknown operator at the start of this text: " "\"%s\"" -msgstr "অক্ষ অভিব্যক্তিয়ে এই লিখনীৰ আৰম্ভণি স্থানত অজ্ঞাত অপাৰেটৰ অন্তৰ্ভুক্ত কৰিছিল: \"%s\"" +msgstr "" +"অক্ষ অভিব্যক্তিয়ে এই লিখনিৰ আৰম্ভণি স্থানত অজ্ঞাত অপাৰেটৰ অন্তৰ্ভুক্ত কৰিছিল: " +"\"%s\"" -#: ../src/ui/theme.c:2010 +#: ../src/ui/theme.c:1997 #, c-format msgid "Coordinate expression was empty or not understood" msgstr "অক্ষ অভিব্যক্তি ৰিক্ত অথবা বোধগম্য নহয়" -#: ../src/ui/theme.c:2121 ../src/ui/theme.c:2131 ../src/ui/theme.c:2165 +#: ../src/ui/theme.c:2110 ../src/ui/theme.c:2120 ../src/ui/theme.c:2154 #, c-format msgid "Coordinate expression results in division by zero" msgstr "অক্ষ অভিব্যক্তিয়ে শূণ্য দ্বাৰা ভাগ কৰাৰ অবস্থা উৎপন্ন কৰে" -#: ../src/ui/theme.c:2173 +#: ../src/ui/theme.c:2162 #, c-format -msgid "Coordinate expression tries to use mod operator on a floating-point number" -msgstr "অক্ষ অভিব্যক্তিয়ে এটা দশমিক সংখ্যাৰ উপৰত mod অপাৰেটৰ ব্যৱহাৰ কৰাৰ চেষ্টা কৰে " +msgid "" +"Coordinate expression tries to use mod operator on a floating-point number" +msgstr "" +"অক্ষ অভিব্যক্তিয়ে এটা দশমিক সংখ্যাৰ ওপৰত mod অপাৰেটৰ ব্যৱহাৰ কৰাৰ চেষ্টা কৰে " -#: ../src/ui/theme.c:2229 +#: ../src/ui/theme.c:2218 #, c-format -msgid "Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "অক্ষ অভিব্যক্তিৰ এটা \"%s\" অপাৰেটৰ আছে যত এটা অপাৰেন্ডৰ আশা কৰা হৈছিল" +msgid "" +"Coordinate expression has an operator \"%s\" where an operand was expected" +msgstr "অক্ষ অভিব্যক্তিৰ এটা \"%s\" অপাৰেটৰ আছে যত এটা অপাৰেন্ডৰ আশা কৰা হৈছিল" -#: ../src/ui/theme.c:2238 +#: ../src/ui/theme.c:2227 #, c-format msgid "Coordinate expression had an operand where an operator was expected" -msgstr "অক্ষ অভিব্যক্তিৰ এটা অপাৰেন্ড আছিল যত এটা অপোৰেটৰৰ আশা কৰা হৈছিল" +msgstr "অক্ষ অভিব্যক্তিৰ এটা অপাৰেন্ড আছিল যত এটা অপোৰেটৰৰ আশা কৰা হৈছিল" -#: ../src/ui/theme.c:2246 +#: ../src/ui/theme.c:2235 #, c-format msgid "Coordinate expression ended with an operator instead of an operand" msgstr "অক্ষ অভিব্যক্তি এটা অপাৰেন্ডেৰ পৰিবৰ্তে অপাৰেটৰ দি সমাপ্ত হৈছে" -#: ../src/ui/theme.c:2256 +#: ../src/ui/theme.c:2245 #, c-format msgid "" "Coordinate expression has operator \"%c\" following operator \"%c\" with no " "operand in between" msgstr "" -"অক্ষ অভিব্যক্তিৰ ক্ষেত্ৰত \"%c\" অপাৰেটৰেৰ পিছত \"%c\" অপাৰেটৰ আছে আৰু দুটাৰ মাজত " +"অক্ষ অভিব্যক্তিৰ ক্ষেত্ৰত \"%c\" অপাৰেটৰেৰ পিছত \"%c\" অপাৰেটৰ আছে আৰু দুটাৰ " +"মাজত " "কোনো অপাৰেন্ড উপস্থিত নাই" -#: ../src/ui/theme.c:2407 ../src/ui/theme.c:2452 +#: ../src/ui/theme.c:2396 ../src/ui/theme.c:2441 #, c-format msgid "Coordinate expression had unknown variable or constant \"%s\"" msgstr "অক্ষ অভিব্যক্তিৰ অজ্ঞাত চলক অথবা ধ্ৰুৱক \"%s\" আছিল" -#: ../src/ui/theme.c:2506 +#: ../src/ui/theme.c:2495 #, c-format msgid "Coordinate expression parser overflowed its buffer." msgstr "অক্ষ অভিব্যক্তিৰ বিশ্লেষকে বাফাৰৰ সীমা পাৰ কৰিছে।" -#: ../src/ui/theme.c:2535 +#: ../src/ui/theme.c:2524 #, c-format msgid "Coordinate expression had a close parenthesis with no open parenthesis" msgstr "অক্ষ অভিব্যক্তিৰ কোনো খোলা ব্ৰেকেট নথকা এটা বন্ধ ব্ৰেকেট আছিল" -#: ../src/ui/theme.c:2599 +#: ../src/ui/theme.c:2588 #, c-format msgid "Coordinate expression had an open parenthesis with no close parenthesis" msgstr "অক্ষ অভিব্যক্তিৰ কোনো বন্ধ ব্ৰেকেট নথকা এটা খোলা ব্ৰেকেট আছিল" -#: ../src/ui/theme.c:2610 +#: ../src/ui/theme.c:2599 #, c-format msgid "Coordinate expression doesn't seem to have any operators or operands" msgstr "অক্ষ অভিব্যক্তিৰ কোনো অপাৰেটৰ অথবা অপাৰেন্ড উপস্থিত নাই" -#: ../src/ui/theme.c:2822 ../src/ui/theme.c:2842 ../src/ui/theme.c:2862 +#: ../src/ui/theme.c:2812 ../src/ui/theme.c:2832 ../src/ui/theme.c:2852 #, c-format msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "থীমে এটা অভিব্যক্তি অন্তৰ্ভুক্ত কৰিছিল যাৰ ফলত এটা ত্ৰুটি হৈছিল: %s\n" +msgstr "থীমে এটা অভিব্যক্তি অন্তৰ্ভুক্ত কৰিছিল যাৰ ফলত এটা ত্ৰুটি হৈছে: %s\n" -#: ../src/ui/theme.c:4533 +#: ../src/ui/theme.c:4455 #, c-format msgid "" "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " @@ -978,37 +883,41 @@ msgstr "" "এই ফ্ৰেইম শৈলীৰ বাবে <button function=\"%s\" state=\"%s\" draw_ops=\"whatever" "\"/> উল্লেখ কৰা আবশ্যক" -#: ../src/ui/theme.c:5066 ../src/ui/theme.c:5091 +#: ../src/ui/theme.c:4970 ../src/ui/theme.c:4995 #, c-format -msgid "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "<frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/> সন্ধানহিন" +msgid "" +"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" +msgstr "" +"<frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/> সন্ধানহীন" -#: ../src/ui/theme.c:5139 +#: ../src/ui/theme.c:5041 #, c-format msgid "Failed to load theme \"%s\": %s\n" -msgstr "\"%s\" থিম লোড কৰিব পৰা নগল: %s\n" +msgstr "\"%s\" থীম ল'ড কৰিব পৰা নগল: %s\n" -#: ../src/ui/theme.c:5275 ../src/ui/theme.c:5282 ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 ../src/ui/theme.c:5303 +#: ../src/ui/theme.c:5177 ../src/ui/theme.c:5184 ../src/ui/theme.c:5191 +#: ../src/ui/theme.c:5198 ../src/ui/theme.c:5205 #, c-format msgid "No <%s> set for theme \"%s\"" -msgstr "\"%s\" থিমৰ বাবে <%s> সংহিত নাই" +msgstr "\"%s\" থীমৰ বাবে <%s> সংহিত নাই" -#: ../src/ui/theme.c:5311 +#: ../src/ui/theme.c:5213 #, c-format msgid "" "No frame style set for window type \"%s\" in theme \"%s\", add a <window " "type=\"%s\" style_set=\"whatever\"/> element" msgstr "" -"থীম \"%s\" -ত উইন্ডো ধৰণ \"%s\" -ৰ বাবে কোনো ফ্ৰোইম শৈলী সংহিত নাই, এটা " -"<window type=\"%s\" style_set=\"whatever\"/> উপাদন যোগ কৰক" +"থীম \"%s\" ত উইন্ডো ধৰণ \"%s\" ৰ বাবে কোনো ফ্ৰেইম শৈলী সংহিত নাই, এটা <window " +"type=\"%s\" style_set=\"whatever\"/> উপাদন যোগ কৰক" -#: ../src/ui/theme.c:5709 ../src/ui/theme.c:5771 ../src/ui/theme.c:5834 +#: ../src/ui/theme.c:5620 ../src/ui/theme.c:5682 ../src/ui/theme.c:5745 #, c-format -msgid "User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "ব্যৱহাৰকাৰী-বিৱৰিত ধ্ৰুৱকসমূহ এটা ডাঙৰ ফলাৰ সৈতে আৰম্ভ হব লাগিব; \"%s\" নহয়" +msgid "" +"User-defined constants must begin with a capital letter; \"%s\" does not" +msgstr "" +"ব্যৱহাৰকাৰী-বিৱৰিত ধ্ৰুৱকসমূহ এটা ডাঙৰ ফলাৰ সৈতে আৰম্ভ হব লাগিব; \"%s\" নহয়" -#: ../src/ui/theme.c:5717 ../src/ui/theme.c:5779 ../src/ui/theme.c:5842 +#: ../src/ui/theme.c:5628 ../src/ui/theme.c:5690 ../src/ui/theme.c:5753 #, c-format msgid "Constant \"%s\" has already been defined" msgstr "ধ্ৰুৱক \"%s\" ইতিমধ্যে বিৱৰিত" @@ -1016,593 +925,823 @@ msgstr "ধ্ৰুৱক \"%s\" ইতিমধ্যে বিৱৰিত" #. Translators: This means that an attribute which should have been found #. * on an XML element was not in fact found. #. -#: ../src/ui/theme-parser.c:236 +#: ../src/ui/theme-parser.c:234 #, c-format msgid "No \"%s\" attribute on element <%s>" msgstr "<%s> উপাদানত কোনো \"%s\" বৈশিষ্ট্য উপস্থিত নাই" -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 +#: ../src/ui/theme-parser.c:263 ../src/ui/theme-parser.c:281 #, c-format msgid "Line %d character %d: %s" msgstr "শাৰী %d আখৰ %d: %s" -#: ../src/ui/theme-parser.c:479 +#: ../src/ui/theme-parser.c:481 #, c-format msgid "Attribute \"%s\" repeated twice on the same <%s> element" msgstr "একে <%s> উপাদানত \"%s\" বৈশিষ্ট্য দুইবাৰ উল্লিখিত হৈছে" -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 +#: ../src/ui/theme-parser.c:505 ../src/ui/theme-parser.c:554 #, c-format msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "এই পৰিপ্ৰেক্ষতিত <%s> উপাদানৰ উপৰত \"%s\" বৈশিষ্ট্যটো বৈধ নহয়" +msgstr "এই পৰিপ্ৰেক্ষতিত <%s> উপাদানৰ ওপৰত \"%s\" বৈশিষ্ট্যটো বৈধ নহয়" -#: ../src/ui/theme-parser.c:594 +#: ../src/ui/theme-parser.c:596 #, c-format msgid "Could not parse \"%s\" as an integer" msgstr "পূৰ্ণসংখ্যা ৰূপে \"%s\" বিশ্লেষণ কৰিব পৰা নগল" -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 +#: ../src/ui/theme-parser.c:605 ../src/ui/theme-parser.c:660 #, c-format msgid "Did not understand trailing characters \"%s\" in string \"%s\"" msgstr "অন্তিম অংশৰ \"%s\" আখৰসমূহ \"%s\" শাৰীত বোধগম্য নহয়" -#: ../src/ui/theme-parser.c:613 +#: ../src/ui/theme-parser.c:615 #, c-format msgid "Integer %ld must be positive" msgstr "পূৰ্ণসংখ্যা %ld ধণাত্মক হব লাগিব" -#: ../src/ui/theme-parser.c:621 +#: ../src/ui/theme-parser.c:623 #, c-format msgid "Integer %ld is too large, current max is %d" msgstr "পূৰ্ণসংখ্যা %ld অত্যাধিক ডাঙৰ, বৰ্তমানে সৰ্বাধিক মান %d" -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 +#: ../src/ui/theme-parser.c:651 ../src/ui/theme-parser.c:767 #, c-format msgid "Could not parse \"%s\" as a floating point number" -msgstr "\"%s\" -ক দশমিক সংখ্যা ৰূপে বিশ্লেষণ কৰিব পৰা নগল" +msgstr "\"%s\" ক দশমিক সংখ্যা ৰূপে বিশ্লেষণ কৰিব পৰা নগল" -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 +#: ../src/ui/theme-parser.c:682 ../src/ui/theme-parser.c:710 #, c-format msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "বুলিয়ান মান \"true\" অথবা \"false\" হোৱা আবশ্যক, \"%s\" ব্যৱহাৰ কৰিব পৰা নগল" +msgstr "" +"বুলিয়ান মান \"true\" অথবা \"false\" হোৱা আবশ্যক, \"%s\" ব্যৱহাৰ কৰিব পৰা নগল" -#: ../src/ui/theme-parser.c:735 +#: ../src/ui/theme-parser.c:737 #, c-format msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "কোণ 0.0ৰ পৰা 360.0 -ৰ মাজত হব লাগিব, %g উল্লিখিত\n" +msgstr "কোণ 0.0ৰ পৰা 360.0 ৰ মাজত হব লাগিব, %g উল্লিখিত\n" -#: ../src/ui/theme-parser.c:798 +#: ../src/ui/theme-parser.c:800 #, c-format msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "আলফাৰ মান 0.0 (অদৃশ্য)ৰ পৰা 1.0 (সম্পূৰ্ণ অস্বচ্ছ) -ৰ মাজত হব লাগিব, %g উল্লিখিত\n" +msgstr "" +"আলফাৰ মান 0.0 (অদৃশ্য) ৰ পৰা 1.0 (সম্পূৰ্ণ অস্বচ্ছ) ৰ মাজত হব লাগিব, %g " +"উল্লিখিত\n" -#: ../src/ui/theme-parser.c:863 +#: ../src/ui/theme-parser.c:865 #, c-format msgid "" "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," "large,x-large,xx-large)\n" msgstr "" -"শীৰ্ষকৰ মাত্ৰা \"%s\" বৈধ নহয় (xx-সৰু, x-সৰু, সৰু, মধ্যম, ডাঙৰ, x-ডাঙৰ,xx-ডাঙৰ " +"শীৰ্ষকৰ মাত্ৰা \"%s\" বৈধ নহয় (xx-সৰু, x-সৰু, সৰু, মধ্যম, ডাঙৰ, " +"x-ডাঙৰ,xx-ডাঙৰ " "মানসমূহত যে কোনো এটা হোৱা আবশ্যক)\n" -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 +#: ../src/ui/theme-parser.c:1021 ../src/ui/theme-parser.c:1084 +#: ../src/ui/theme-parser.c:1118 ../src/ui/theme-parser.c:1221 #, c-format msgid "<%s> name \"%s\" used a second time" -msgstr "<%s> নাম \"%s\" দ্বিতীয়বাৰ ব্যৱহৃত হৈছে " +msgstr "<%s> নাম \"%s\" দ্বিতীয়বাৰ ব্যৱহৃত হৈছে " -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 +#: ../src/ui/theme-parser.c:1033 ../src/ui/theme-parser.c:1130 +#: ../src/ui/theme-parser.c:1233 #, c-format msgid "<%s> parent \"%s\" has not been defined" msgstr "<%s> উপধায়ক \"%s\" নিৰ্ধাৰিত নহয়" -#: ../src/ui/theme-parser.c:1141 +#: ../src/ui/theme-parser.c:1143 #, c-format msgid "<%s> geometry \"%s\" has not been defined" -msgstr "<%s> জ্যামিতি \"%s\" বিৱৰণ দিয়া হোৱা নাই" +msgstr "<%s> জ্যামিতি \"%s\" বিৱৰণ দিয়া হোৱা নাই" -#: ../src/ui/theme-parser.c:1154 +#: ../src/ui/theme-parser.c:1156 #, c-format msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "<%s> -এ এটা জ্যামিতি বা এজন উপধায়ক যাৰ জ্যামিতি আছে ধাৰ্য্য কৰিব লাগিব " +msgstr "<%s> এ এটা জ্যামিতি বা এজন উপধায়ক যাৰ জ্যামিতি আছে ধাৰ্য্য কৰিব লাগিব" -#: ../src/ui/theme-parser.c:1196 +#: ../src/ui/theme-parser.c:1198 msgid "You must specify a background for an alpha value to be meaningful" msgstr "এটা আল্ফা মান যুক্তি-যুক্ত হবলে আপুনি এটা পটভূমি ধাৰ্য্য কৰিব লাগিব" -#: ../src/ui/theme-parser.c:1264 +#: ../src/ui/theme-parser.c:1266 #, c-format msgid "Unknown type \"%s\" on <%s> element" msgstr "<%s> উপাদানত অজ্ঞাত ধৰণ \"%s\" উপস্থিত।" -#: ../src/ui/theme-parser.c:1275 +#: ../src/ui/theme-parser.c:1277 #, c-format msgid "Unknown style_set \"%s\" on <%s> element" msgstr "<%s> উপাদানত অজ্ঞাত style_set \"%s\" উপস্থিত" -#: ../src/ui/theme-parser.c:1283 +#: ../src/ui/theme-parser.c:1285 #, c-format msgid "Window type \"%s\" has already been assigned a style set" -msgstr "উইন্ডো ধৰণ \"%s\" -ক এটা শৈলী সংহতি ইতিমধ্য ধাৰ্য্য কৰা হৈছে" +msgstr "উইন্ডো ধৰণ \"%s\" ক এটা শৈলী সংহতি ইতিমধ্য ধাৰ্য্য কৰা হৈছে" -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 +#: ../src/ui/theme-parser.c:1315 ../src/ui/theme-parser.c:1379 +#: ../src/ui/theme-parser.c:1605 ../src/ui/theme-parser.c:2840 +#: ../src/ui/theme-parser.c:2886 ../src/ui/theme-parser.c:3036 +#: ../src/ui/theme-parser.c:3272 ../src/ui/theme-parser.c:3310 +#: ../src/ui/theme-parser.c:3348 ../src/ui/theme-parser.c:3386 #, c-format msgid "Element <%s> is not allowed below <%s>" -msgstr "<%s> উপাদান <%s> -ৰ অনুমোদিত নহয়" +msgstr "<%s> উপাদান <%s> ৰ অনুমোদিত নহয়" # -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 +#: ../src/ui/theme-parser.c:1429 ../src/ui/theme-parser.c:1443 +#: ../src/ui/theme-parser.c:1488 msgid "" "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " "for buttons" msgstr "" -"বুটামসমূহৰ বাবে \"button_width\"/\"button_height\" আৰু \"aspect_ratio\" (এস্পেক্ট " +"বুটামসমূহৰ বাবে \"button_width\"/\"button_height\" আৰু \"aspect_ratio\" " +"(এচপেক্ট " "অনুপাত) একেলগে ধাৰ্য্য কৰিব নোৱাৰি" -#: ../src/ui/theme-parser.c:1450 +#: ../src/ui/theme-parser.c:1452 #, c-format msgid "Distance \"%s\" is unknown" msgstr "দুৰত্ব \"%s\" অজ্ঞাত" -#: ../src/ui/theme-parser.c:1495 +#: ../src/ui/theme-parser.c:1497 #, c-format msgid "Aspect ratio \"%s\" is unknown" -msgstr "এস্পেক্ট অনুপাত \"%s\" অজ্ঞাত" +msgstr "এচপেক্ট অনুপাত \"%s\" অজ্ঞাত" -#: ../src/ui/theme-parser.c:1557 +#: ../src/ui/theme-parser.c:1559 #, c-format msgid "Border \"%s\" is unknown" msgstr "প্ৰান্ত \"%s\" অজ্ঞাত" -#: ../src/ui/theme-parser.c:1868 +#: ../src/ui/theme-parser.c:1870 #, c-format msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "উপাদানত কোনো \"start_angle\" অথবা \"from\" বৈশিষ্ট নাই <%s>" +msgstr "উপাদানত কোনো \"start_angle\" অথবা \"from\" বৈশিষ্ট নাই <%s>" -#: ../src/ui/theme-parser.c:1875 +#: ../src/ui/theme-parser.c:1877 #, c-format msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" msgstr "উপাদানত কোনো \"extent_angle\" অথবা \"to\" বৈশিষ্ট নাই <%s>" -#: ../src/ui/theme-parser.c:2115 +#: ../src/ui/theme-parser.c:2117 #, c-format msgid "Did not understand value \"%s\" for type of gradient" -msgstr "গ্ৰেডিয়েন্টেৰ ধৰণৰ বাবে \"%s\" মান বোধগম্য নহয়" +msgstr "গ্ৰেডিয়েন্টৰ ধৰণৰ বাবে \"%s\" মান বোধগম্য নহয়" -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 +#: ../src/ui/theme-parser.c:2195 ../src/ui/theme-parser.c:2570 #, c-format msgid "Did not understand fill type \"%s\" for <%s> element" msgstr "<%s> উপাদানৰ ভৰোৱাৰ ধৰণ \"%s\" বাবে বোধগম্য নহয়" -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 +#: ../src/ui/theme-parser.c:2362 ../src/ui/theme-parser.c:2445 +#: ../src/ui/theme-parser.c:2508 #, c-format msgid "Did not understand state \"%s\" for <%s> element" msgstr "<%s> উপাদানৰ বাবে অবস্থা \"%s\" বোধগম্য নহয়" -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 +#: ../src/ui/theme-parser.c:2372 ../src/ui/theme-parser.c:2455 #, c-format msgid "Did not understand shadow \"%s\" for <%s> element" msgstr "<%s> উপাদানৰ বাবে ছায়া \"%s\" বোধগম্য নহয়" -#: ../src/ui/theme-parser.c:2380 +#: ../src/ui/theme-parser.c:2382 #, c-format msgid "Did not understand arrow \"%s\" for <%s> element" msgstr "<%s> উপাদানৰ বাবে কাঁড় \"%s\" বোধগম্য নহয়" -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 +#: ../src/ui/theme-parser.c:2696 ../src/ui/theme-parser.c:2792 #, c-format msgid "No <draw_ops> called \"%s\" has been defined" msgstr "\"%s\" নামক কোনো <draw_ops> নিৰ্ধাৰিত নহয়" -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 +#: ../src/ui/theme-parser.c:2708 ../src/ui/theme-parser.c:2804 #, c-format msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "ইয়াত অকাঁ কাৰ্য্য \"%s\" অন্তৰ্ভুক্ত কৰিলে এটা ঘুৰনীয় প্ৰসংগ সৃষ্টি কৰিব (_o)" +msgstr "" +"ইয়াত অকাঁ কাৰ্য্য \"%s\" অন্তৰ্ভুক্ত কৰিলে এটা ঘুৰনীয় প্ৰসংগ সৃষ্টি কৰিব (_o)" -#: ../src/ui/theme-parser.c:2917 +#: ../src/ui/theme-parser.c:2919 #, c-format msgid "Unknown position \"%s\" for frame piece" msgstr "ফ্ৰেইমৰ অংশৰ বাবে অজ্ঞাত অবস্থান \"%s\"" -#: ../src/ui/theme-parser.c:2925 +#: ../src/ui/theme-parser.c:2927 #, c-format msgid "Frame style already has a piece at position %s" -msgstr "ফ্ৰেইম শৈলীৰ %s অৱস্থানত ইতিমধ্যে এটা অংশ উপস্থিত আছে" +msgstr "ফ্ৰেইম শৈলীৰ %s অৱস্থানত ইতিমধ্যে এটা অংশ উপস্থিত আছে" -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 +#: ../src/ui/theme-parser.c:2944 ../src/ui/theme-parser.c:3021 #, c-format msgid "No <draw_ops> with the name \"%s\" has been defined" msgstr "\"%s\" নামৰ কোনো <draw_ops> নিৰ্ধাৰিত নহয়" -#: ../src/ui/theme-parser.c:2972 +#: ../src/ui/theme-parser.c:2974 #, c-format msgid "Unknown function \"%s\" for button" msgstr "বুটামৰ বাবে অজ্ঞাত ফলন \"%s\"" -#: ../src/ui/theme-parser.c:2982 +#: ../src/ui/theme-parser.c:2984 #, c-format msgid "Button function \"%s\" does not exist in this version (%d, need %d)" msgstr "বুটাম ফলন \"%s\" এই সংস্কৰণত অস্তিত্ববান নহয় (%d, প্ৰয়োজন %d)" -#: ../src/ui/theme-parser.c:2994 +#: ../src/ui/theme-parser.c:2996 #, c-format msgid "Unknown state \"%s\" for button" msgstr "বুটামৰ অজ্ঞাত অবস্থা \"%s\"" -#: ../src/ui/theme-parser.c:3002 +#: ../src/ui/theme-parser.c:3004 #, c-format msgid "Frame style already has a button for function %s state %s" -msgstr "ফ্ৰেইম শৈলীৰ ইতিমধ্যে ফলন %s অৱস্থা %s -ৰ বাবে এটা বুটাম আছে" +msgstr "ফ্ৰেইম শৈলীৰ ইতিমধ্যে ফলন %s অৱস্থা %s ৰ বাবে এটা বুটাম আছে" -#: ../src/ui/theme-parser.c:3073 +#: ../src/ui/theme-parser.c:3075 #, c-format msgid "\"%s\" is not a valid value for focus attribute" msgstr "focus বৈশিষ্ট্যৰ বাবে \"%s\" এটা বৈধ মান নহয়" -#: ../src/ui/theme-parser.c:3082 +#: ../src/ui/theme-parser.c:3084 #, c-format msgid "\"%s\" is not a valid value for state attribute" -msgstr "state বৈশিষ্ট্যৰ বাবে \"%s\" এটা বৈধ মান নহয়" +msgstr "state বৈশিষ্ট্যৰ বাবে \"%s\" এটা বৈধ মান নহয়" -#: ../src/ui/theme-parser.c:3092 +#: ../src/ui/theme-parser.c:3094 #, c-format msgid "A style called \"%s\" has not been defined" msgstr "\"%s\" নামৰ এটা শৈলীৰ বিৱৰণ দিয়া হোৱা নাই" -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 +#: ../src/ui/theme-parser.c:3115 ../src/ui/theme-parser.c:3138 #, c-format msgid "\"%s\" is not a valid value for resize attribute" msgstr "resize বৈশিষ্ট্যৰ বাবে \"%s\" এটা বৈধ মান নহয়" -#: ../src/ui/theme-parser.c:3147 +#: ../src/ui/theme-parser.c:3149 #, c-format msgid "" "Should not have \"resize\" attribute on <%s> element for maximized/shaded " "states" msgstr "" -"সৰ্বোচ্চ মাপ/ছায়াবৃত অবস্থাৰ বাবে <%s> উপাদানত \"resize\" বৈশিষ্ট্য উপস্থিত থকা " +"সৰ্বোচ্চ মাপ/ছায়াবৃত অবস্থাৰ বাবে <%s> উপাদানত \"resize\" বৈশিষ্ট্য উপস্থিত " +"থকা " "উচিত নহয়" -#: ../src/ui/theme-parser.c:3161 +#: ../src/ui/theme-parser.c:3163 #, c-format -msgid "Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "সৰ্বোচ্চ অৱস্থাসমূহৰ বাবে <%s> উপাদানত \"resize\" বৈশিষ্ট থাকিব নালাগিব" +msgid "" +"Should not have \"resize\" attribute on <%s> element for maximized states" +msgstr "" +"সৰ্বোচ্চ অৱস্থাসমূহৰ বাবে <%s> উপাদানত \"resize\" বৈশিষ্ট থাকিব নালাগিব" -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 +#: ../src/ui/theme-parser.c:3177 ../src/ui/theme-parser.c:3221 #, c-format msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "state %s resize %s focus %s -ৰ বাবে শৈলী ইতিমধ্য ধাৰ্য্য কৰা আছে" +msgstr "state %s resize %s focus %s ৰ বাবে শৈলী ইতিমধ্য ধাৰ্য্য কৰা আছে" -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 +#: ../src/ui/theme-parser.c:3188 ../src/ui/theme-parser.c:3199 +#: ../src/ui/theme-parser.c:3210 ../src/ui/theme-parser.c:3232 +#: ../src/ui/theme-parser.c:3243 ../src/ui/theme-parser.c:3254 #, c-format msgid "Style has already been specified for state %s focus %s" -msgstr "state %s focus %s -ৰ বাবে শৈলী ইতিমধ্যে ধাৰ্য্যত আছে" +msgstr "state %s focus %s ৰ বাবে শৈলী ইতিমধ্যে ধাৰ্য্যত আছে" -#: ../src/ui/theme-parser.c:3294 +#: ../src/ui/theme-parser.c:3293 msgid "" "Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " "attribute and also a <draw_ops> element, or specified two elements)" msgstr "" -"এটা <piece> উপাদানৰ সৈতে দুটি draw_ops উপস্থিত থকা সম্ভৱ নহয় (থিম দ্বাৰা এটা " +"এটা <piece> উপাদানৰ সৈতে দুটি draw_ops উপস্থিত থকা সম্ভৱ নহয় (থীম দ্বাৰা এটা " "draw_ops বৈশিষ্ট্য আৰু <draw_ops> উপাদান অথবা দুটি উপাদান উল্লিখিত হৈছে)" -#: ../src/ui/theme-parser.c:3332 +#: ../src/ui/theme-parser.c:3331 msgid "" "Can't have a two draw_ops for a <button> element (theme specified a draw_ops " "attribute and also a <draw_ops> element, or specified two elements)" msgstr "" -"এটা <button> উপাদানৰ সৈতে দুটি draw_ops উপস্থিত থকা সম্ভৱ নহয় (থিম দ্বাৰা এটা " +"এটা <button> উপাদানৰ সৈতে দুটি draw_ops উপস্থিত থকা সম্ভৱ নহয় (থীম দ্বাৰা এটা " "draw_ops বৈশিষ্ট্য আৰু <draw_ops> উপাদান অথবা দুটি উপাদান উল্লিখিত হৈছে)" -#: ../src/ui/theme-parser.c:3370 +#: ../src/ui/theme-parser.c:3369 msgid "" "Can't have a two draw_ops for a <menu_icon> element (theme specified a " "draw_ops attribute and also a <draw_ops> element, or specified two elements)" msgstr "" -"এটা <menu> উপাদানৰ সৈতে দুটি draw_ops উপস্থিত থকা সম্ভৱ নহয় (থিম দ্বাৰা এটা " +"এটা <menu> উপাদানৰ সৈতে দুটি draw_ops উপস্থিত থকা সম্ভৱ নহয় (থীম দ্বাৰা এটা " "draw_ops বৈশিষ্ট্য আৰু <draw_ops> উপাদান অথবা দুটি উপাদান উল্লিখিত হৈছে)" -#: ../src/ui/theme-parser.c:3434 +#: ../src/ui/theme-parser.c:3433 #, c-format msgid "Bad version specification '%s'" msgstr "বেয়া সংস্কৰণ ধাৰ্য্য '%s'" -#: ../src/ui/theme-parser.c:3507 +#: ../src/ui/theme-parser.c:3506 msgid "" "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" "theme-2.xml" msgstr "" -"\"version\" বৈশিষ্টক metacity-theme-1.xml অথবা metacity-theme-2.xml -ত " -"ব্যৱহাৰ কৰিব নোৱাৰি" +"\"version\" বৈশিষ্টক metacity-theme-1.xml অথবা metacity-theme-2.xml ত ব্যৱহাৰ " +"কৰিব নোৱাৰি" -#: ../src/ui/theme-parser.c:3530 +#: ../src/ui/theme-parser.c:3529 #, c-format msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "থীমৰ %s সংস্কৰণৰ প্ৰয়োজন কিন্তু সেহতীয়া সমৰ্থিত থীম হল %d।%d" +msgstr "থীমৰ %s সংস্কৰণৰ প্ৰয়োজন কিন্তু শেহতীয়া সমৰ্থিত থীম হল %d.%d" -#: ../src/ui/theme-parser.c:3562 +#: ../src/ui/theme-parser.c:3561 #, c-format msgid "Outermost element in theme must be <metacity_theme> not <%s>" msgstr "থীমৰ বহিৰ্তম উপাদান <metacity_theme> হব লাগিব <%s> নহয়" -#: ../src/ui/theme-parser.c:3582 +#: ../src/ui/theme-parser.c:3581 #, c-format -msgid "Element <%s> is not allowed inside a name/author/date/description element" +msgid "" +"Element <%s> is not allowed inside a name/author/date/description element" msgstr "এটা নাম/লেখক/তাৰিখ/বিৱৰণ উপাদানৰ ভিতৰত <%s> উপাদানৰ অনুমতি নাই" -#: ../src/ui/theme-parser.c:3587 +#: ../src/ui/theme-parser.c:3586 #, c-format msgid "Element <%s> is not allowed inside a <constant> element" msgstr "এটা <constant> উপাদানৰ ভিতৰত <%s> উপাদানৰ অনুমতি নাই" -#: ../src/ui/theme-parser.c:3599 +#: ../src/ui/theme-parser.c:3598 #, c-format -msgid "Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "দুৰত্ব/সীমা/এস্পেক্ট অনুপাত এটা <%s> উপাদানৰ ভিতৰত অনুমোদিত নহয় (_r)" +msgid "" +"Element <%s> is not allowed inside a distance/border/aspect_ratio element" +msgstr "দুৰত্ব/সীমা/এচপেক্ট অনুপাত এটা <%s> উপাদানৰ ভিতৰত অনুমোদিত নহয় (_r)" -#: ../src/ui/theme-parser.c:3621 +#: ../src/ui/theme-parser.c:3620 #, c-format msgid "Element <%s> is not allowed inside a draw operation element" msgstr "অকাঁ কাৰ্য্য উপাদানৰ ভিতৰত <%s> উপাদান অনুমোদিত নহয়" -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 +#: ../src/ui/theme-parser.c:3630 ../src/ui/theme-parser.c:3660 +#: ../src/ui/theme-parser.c:3665 ../src/ui/theme-parser.c:3670 #, c-format msgid "Element <%s> is not allowed inside a <%s> element" msgstr "<%s> উপাদানটো <%s> উপাদানৰ ভিতৰত অনুমোদিত নহয়" -#: ../src/ui/theme-parser.c:3899 +#: ../src/ui/theme-parser.c:3898 msgid "No draw_ops provided for frame piece" msgstr "ফ্ৰেইমৰ অংশৰ বাবে অকাঁ কাৰ্য্য উপলব্ধ নাই (_o)" -#: ../src/ui/theme-parser.c:3914 +#: ../src/ui/theme-parser.c:3913 msgid "No draw_ops provided for button" msgstr "বুটামৰ বাবে অকাঁ কাৰ্য্য উপলব্ধ নাই (_o)" -#: ../src/ui/theme-parser.c:3968 +#: ../src/ui/theme-parser.c:3967 #, c-format msgid "No text is allowed inside element <%s>" -msgstr "<%s> উপাদানৰ ভিতৰত কোনো লিখনীৰ অনুমতি নাই" +msgstr "<%s> উপাদানৰ ভিতৰত কোনো লিখনিৰ অনুমতি নাই" -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 +#: ../src/ui/theme-parser.c:4025 ../src/ui/theme-parser.c:4037 +#: ../src/ui/theme-parser.c:4049 ../src/ui/theme-parser.c:4061 +#: ../src/ui/theme-parser.c:4073 #, c-format msgid "<%s> specified twice for this theme" msgstr "<%s> এই থীমৰ বাবে দুবাৰ ধাৰ্য্য কৰা হৈছে" -#: ../src/ui/theme-parser.c:4348 +#: ../src/ui/theme-parser.c:4335 #, c-format msgid "Failed to find a valid file for theme %s\n" -msgstr "থীম %s -ৰ বাবে এটা বৈধ নথিপত্ৰ সন্ধান কৰিবলে ব্যৰ্থ\n" +msgstr "থীম %s ৰ বাবে এটা বৈধ ফাইল সন্ধান কৰিবলে ব্যৰ্থ\n" + +#: ../src/x11/session.c:1815 +msgid "" +"These windows do not support "save current setup" and will have to " +"be restarted manually next time you log in." +msgstr "" +"এই উইন্ডোসমূহৰ দ্বাৰা "save current setup" সমৰ্থিত নহয় আৰু পৰৱৰ্তী " +"বাৰ " +"লগিন কৰোতে আপুনি ইয়াক হস্তচালিতভাৱে পুনৰাম্ভ কৰিব লাগিব।" -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "উইন্ডোসমূহ (_W)" +#: ../src/x11/window-props.c:515 +#, c-format +msgid "%s (on %s)" +msgstr "%s (%s ৰ ওপৰত)" + +#~ msgid "Unknown window information request: %d" +#~ msgstr "অজ্ঞাত উইন্ডো তথ্য অনুৰোধ: %d" + +#~ msgid "Missing %s extension required for compositing" +#~ msgstr "মিশ্ৰণৰ বাবে সন্ধানহীন %s সম্প্ৰসাৰনৰ প্ৰয়োজন" + +#~ msgid "" +#~ "Some other program is already using the key %s with modifiers %x as a " +#~ "binding\n" +#~ msgstr "" +#~ "অন্য কোনো প্ৰগ্ৰামে ইতিমধ্যে কি' %s ক বাইন্ডিং হিচাপে পৰিৱৰ্তক %x ৰ সৈতে ব্যৱহাৰ " +#~ "কৰি আছে\n" -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "ডাইলগ (_D)" +#~ msgid "\"%s\" is not a valid accelerator\n" +#~ msgstr "\"%s\" এটা বৈধ ত্বৰক নহয়\n" -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "মোডাল ডাইলগ (_M)" +#~ msgid "" +#~ "Workarounds for broken applications disabled. Some applications may not " +#~ "behave properly.\n" +#~ msgstr "" +#~ "ক্ষতিগ্ৰস্ত এপ্লিকেচনৰ ত্ৰুটি অগ্ৰাহ্য কৰাৰ প্ৰণালী নিষ্ক্ৰিয় কৰা হৈছে। কিছুমান " +#~ "এপ্লিকেচন সম্ভৱত সঠিকৰূপে চলোৱা সম্ভৱ নহব।\n" -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "সামগ্ৰী (_U)" +#~ msgid "Could not parse font description \"%s\" from GSettings key %s\n" +#~ msgstr "GSettings কি' %s ৰ পৰা ফন্ট বিৱৰণ \"%s\" বিশ্লেষণ কৰিব নোৱাৰি\n" -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "স্প্ল্যাশ-স্ক্ৰিন (_S)" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" +#~ msgstr "সংৰূপ ডাটাবেইচত উপস্থিত \"%s\" মাউছ বুটাম পৰিবৰ্তকৰ বাবে বৈধ মানে নহয়\n" -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "উপৰৰ বন্দৰ (_T)" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for " +#~ "keybinding \"%s\"\n" +#~ msgstr "" +#~ "সংৰূপ ডাটাবেইচত উপলব্ধ \"%s\", \"%s\" কি-বাইন্ডিং ৰ ক্ষেত্ৰত বৈধ মান নহয়\n" -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "তলৰ বন্দৰ (_B)" +#~ msgid "" +#~ "Could not acquire window manager selection on screen %d display \"%s\"\n" +#~ msgstr "উইন্ডো ব্যৱস্থাপকৰ নিৰ্বাচন গ্ৰহণ কৰোঁতে ব্যৰ্থ পৰ্দা %d প্ৰদৰ্শন \"%s\"\n" -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "বাওফালৰ বন্দৰ (_L)" +#~ msgid "Could not release screen %d on display \"%s\"\n" +#~ msgstr "পৰ্দা %d মুক্ত কৰিব পৰা নগল প্ৰদৰ্শন \"%s\"\n" -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "সোফালৰ বন্দৰ (_R)" +#~ msgid "Could not create directory '%s': %s\n" +#~ msgstr "ডাইৰেকটৰি '%s' সৃষ্টি কৰিব পৰা নগল: %s\n" -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "সকলো বন্দৰ (_A)" +#~ msgid "Could not open session file '%s' for writing: %s\n" +#~ msgstr "লিখাৰ বাবে অধিবেশন ফাইল '%s' খোলিব পৰা নগল: %s\n" -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "ডেস্কটপ (_k)" +#~ msgid "Error writing session file '%s': %s\n" +#~ msgstr "অধিবেশন ফাইল '%s' লিখোতে ত্ৰুটি: %s\n" -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "এই ধৰণৰ আৰু এটা উইন্ডো খোলক" +#~ msgid "Error closing session file '%s': %s\n" +#~ msgstr "অধিবেশন ফাইল '%s' বন্ধ কৰোতে ত্ৰুটি: %s\n" -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "'খোলা' আইকন বিশিষ্ট এইটো এটা নমূনা বুটাম" +#~ msgid "Failed to parse saved session file: %s\n" +#~ msgstr "সংৰক্ষিত অধিবেশন ফাইল বিশ্লেষণ কৰিব পৰা নগল: %s\n" -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "'প্ৰস্থান' আইকন বিশিষ্ট এইটো এটা নমূনা বুটাম" +#~ msgid "<mutter_session> attribute seen but we already have the session ID" +#~ msgstr "<mutter_session> বৈশিষ্ট্য প্ৰদৰ্শিত কিন্তু অধিবেশন ID বৰ্তমানে উপস্থিত আছে" -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "এইটো নমুনা সম্বাদ বাকচত এটা নমুনা বাৰ্তা" +#~ msgid "Unknown attribute %s on <%s> element" +#~ msgstr "অজ্ঞাত বৈশিষ্ট্য %s, <%s> উপাদানত চিহ্নিত হৈছে" -#: ../src/ui/theme-viewer.c:328 -#, c-format -msgid "Fake menu item %d\n" -msgstr "নকল মেনু বস্তু %d\n" +#~ msgid "nested <window> tag" +#~ msgstr "নেস্টেড <window> টেগ" -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "অকল প্ৰান্তবিশিষ্ট উইন্ডো" +#~ msgid "Unknown element %s" +#~ msgstr "অজ্ঞাত উপাদান %s" -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "বাৰ" +#~ msgid "Failed to open debug log: %s\n" +#~ msgstr "ডিবাগ লগ খোলিব পৰা নগল: %s\n" -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "স্বাভাবিক অনুপ্ৰয়োগ উইন্ডো" +#~ msgid "Failed to fdopen() log file %s: %s\n" +#~ msgstr "fdopen() লগ ফাইল %s খোলিব পৰা নগল: %s\n" -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "ডাইলগ বাকচ" +#~ msgid "Opened log file %s\n" +#~ msgstr "লগ ফাইল %s খোলা হৈছে\n" -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "মোডাল ডাইলগ বাকচ" +#~ msgid "Window manager: " +#~ msgstr "উইন্ডো ব্যৱস্থাপক: " -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "সৰঞ্জাম পেলেট" +#~ msgid "Bug in window manager: " +#~ msgstr "উইন্ডো ব্যৱস্থাপকত বাগ: " -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "পৰিবৰ্তনশীল অবস্থানৰ মেনু" +#~ msgid "Window manager warning: " +#~ msgstr "উইন্ডো ব্যৱস্থাপক সতৰ্কবাৰ্তা: " -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "প্ৰান্ত" +#~ msgid "Window manager error: " +#~ msgstr "উইন্ডো ব্যৱস্থাপক ত্ৰুটি: " -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "সংযুক্ত মোডাল ডাইলগ" +#~ msgid "" +#~ "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " +#~ "window as specified in the ICCCM.\n" +#~ msgstr "" +#~ "উইন্ডো %s এ ICCCM ত নিৰ্ধাৰিত WM_CLIENT_LEADER উইন্ডোৰ পৰিবৰ্তে নিজৰ ওপৰত " +#~ "SM_CLIENT_ID সংহতি কৰে।\n" -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "বুটাম বিন্যাসৰ পৰীক্ষা %d" +#~ msgid "" +#~ "Window %s sets an MWM hint indicating it isn't resizable, but sets min " +#~ "size %d x %d and max size %d x %d; this doesn't make much sense.\n" +#~ msgstr "" +#~ "উইন্ডো %s এ এটা MWM আভাস সংহতি কৰে এটা ইংগিত দি যে ইয়াক পুনৰ আকাৰ দিব কৰিব " +#~ "নোৱাৰি, কিন্তু নূন্যতম আকাৰ %d x %d আৰু সৰ্বাধিক আকাৰ %d x %d সংহতি কৰে; ই " +#~ "বিশেষ এটা সংজ্ঞা নিদিয়ে।\n" -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "এটা উইন্ডো ফ্ৰেইম আকিবলে %g মিলিছেকেণ্ডসমূহ" +#~ msgid "Application set a bogus _NET_WM_PID %lu\n" +#~ msgstr "এপ্লিকেচন দ্বাৰা ভুল _NET_WM_PID %lu নিৰ্ধাৰিত হৈছে\n" -#: ../src/ui/theme-viewer.c:813 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "ব্যৱহাৰপদ্ধতি: metacity-theme-viewer [THEMENAME]\n" +#~ msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +#~ msgstr "অবৈধ WM_TRANSIENT_FOR উইন্ডো 0x%lx, %s ৰ বাবে নিৰ্ধাৰিত হৈছে।\n" -#: ../src/ui/theme-viewer.c:820 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "থিম লোড কৰোঁতে সমস্যা: %s\n" +#~ msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" +#~ msgstr "WM_TRANSIENT_FOR window 0x%lx এ %s ৰ বাবে লুপ সৃষ্টি কৰিব।\n" -#: ../src/ui/theme-viewer.c:826 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "\"%s\" থিম %g ছেকেণ্ডসমূহত লোড কৰা হৈছে\n" +#~ msgid "" +#~ "Window 0x%lx has property %s\n" +#~ "that was expected to have type %s format %d\n" +#~ "and actually has type %s format %d n_items %d.\n" +#~ "This is most likely an application bug, not a window manager bug.\n" +#~ "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +#~ msgstr "" +#~ "উইন্ডো 0x%lx ৰ %s বৈশিষ্ট আছে\n" +#~ "যাৰ ধৰণ %s আৰু বিন্যাস %d থাকিব বুলি আশা কৰা হৈছিল\n" +#~ "আৰু প্ৰকৃততে ধৰণ %s বিন্যাস %d n_items %d আছে।\n" +#~ "ই খুব সম্ভব এটা এপ্লিকেচন বাগ, এটা উইন্ডো ব্যৱস্থাপক বাগ নহয়।\n" +#~ "উইন্ডো শীৰ্ষক=\"%s\" শ্ৰেণী=\"%s\" নাম=\"%s\"\n" -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "স্বাভাবিক শীৰ্ষক ফন্ট" +#~ msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +#~ msgstr "বৈশিষ্ট %s window 0x%lx ত অন্তৰ্ভুক্ত কৰিছিল অবৈধ UTF-8\n" -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "সৰু শীৰ্ষক ফন্ট" +#~ msgid "" +#~ "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the " +#~ "list\n" +#~ msgstr "" +#~ "বৈশিষ্ট %s window 0x%lx ত তালিকাৰ উপাদান %d ৰ বাবে অবৈধ UTF-8 অন্তৰ্ভুক্ত " +#~ "কৰিছিল\n" -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "ডাঙৰ শীৰ্ষক ফন্ট" +#~ msgid "Mi_nimize" +#~ msgstr "সৰু কৰক (_n)" -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "বুটামৰ বিন্যাসসমূহ" +#~ msgid "Ma_ximize" +#~ msgstr "ডাঙৰ কৰক (_x)" -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "বেঞ্চমাৰ্ক" +#~ msgid "Unma_ximize" +#~ msgstr "ডাঙৰৰ পৰা সৰু কৰক (_x)" -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "উইন্ডো শীৰ্ষক ইয়াত যাব" +#~ msgid "Roll _Up" +#~ msgstr "ৰল আপ কৰক (_U)" -#: ../src/ui/theme-viewer.c:1047 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"%d ফ্ৰেইমসমূহক %g ক্লাএন্ট-কাষ ছেকেণ্ডসমূহ (%g মিলিছেকেণ্ড প্ৰতি ফ্ৰেইম) আৰু %" -"gছেকেণ্ডসমূহ ৱাল ঘড়ী সময় X চাৰ্ভাৰ সম্পদসমূহ (%g মিলিছেকেণ্ড প্ৰতি ফ্ৰেইম) অন্তৰ্ভুক্ত " -"কৰিঅকাঁ হৈছিল\n" +#~ msgid "_Unroll" +#~ msgstr "আনৰল কৰক (_U)" -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "অবস্থান অভিব্যক্তিৰ পৰীক্ষায়ে TRUE ঘুৰাই দিলেও ত্ৰুটি সংহিত হৈছে" +#~ msgid "_Move" +#~ msgstr "স্থানান্তৰ কৰক (_M)" -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "অবস্থান অভিব্যক্তিৰ পৰীক্ষায়ে FALSE ঘুৰাই দিলেও ত্ৰুটি সংহিত নাই হোৱা" +#~ msgid "_Resize" +#~ msgstr "পুনৰ আকাৰ দিয়ক (_R)" -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "ত্ৰুটি প্ৰত্যাশিত আছিল কিন্তু কোনো এটা দিয়া হোৱা নাই" +#~ msgid "Move Titlebar On_screen" +#~ msgstr "পৰ্দাৰ ওপৰ শীৰ্ষকবাৰ স্থানান্তৰ কৰক (_s)" -#: ../src/ui/theme-viewer.c:1274 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "ত্ৰুটি %d প্ৰত্যাশিত আছিল কিন্তু %d প্ৰদান কৰা হৈছে" +#~ msgid "Always on _Top" +#~ msgstr "সদায় ওপৰত (_T)" -#: ../src/ui/theme-viewer.c:1280 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "ত্ৰুটি প্ৰত্যাশিত নহয় কিন্তু প্ৰাপ্ত: %s" +#~ msgid "_Always on Visible Workspace" +#~ msgstr "সদায় দৃশ্যমান কৰ্মস্থানত (_A)" -#: ../src/ui/theme-viewer.c:1284 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "x'ৰ মান %d, %d প্ৰত্যাশিত" +#~ msgid "_Only on This Workspace" +#~ msgstr "কেৱল এই কৰ্মস্থানত (_O)" -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "y'ৰ মান %d, %d প্ৰত্যাশিত" +#~ msgid "Move to Workspace _Left" +#~ msgstr "বাওঁফালৰ কৰ্মস্থানত স্থানান্তৰ কৰক (_L)" -#: ../src/ui/theme-viewer.c:1352 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "%d অক্ষ অভিব্যক্তিসমূহ %g ছেকেণ্ডসমূহত বিশ্লেষণ কৰা হৈছে (গড় %g ছেকেণ্ডসমূহ)\n" +#~ msgid "Move to Workspace R_ight" +#~ msgstr "সোঁফালৰ কৰ্মস্থানত স্থানান্তৰ কৰক (_i)" -#~ msgid "Switch to workspace 1" -#~ msgstr "কৰ্মস্থান ১লে পৰিবৰ্তন কৰক" +#~ msgid "Move to Workspace _Up" +#~ msgstr "ওপৰৰ কৰ্মস্থানত স্থানান্তৰ কৰক (_U)" -#~ msgid "Switch to workspace 2" -#~ msgstr "কৰ্মস্থান ২লে পৰিবৰ্তন কৰক" +#~ msgid "Move to Workspace _Down" +#~ msgstr "তলৰ কৰ্মস্থানত স্থানান্তৰ কৰক (_D)" -#~ msgid "Switch to workspace 3" -#~ msgstr "কৰ্মস্থান ৩লে পৰিবৰ্তন কৰক" +#~ msgid "_Close" +#~ msgstr "বন্ধ কৰক (_C)" -#~ msgid "Switch to workspace 4" -#~ msgstr "কৰ্মস্থান ৪লে পৰিবৰ্তন কৰক" +#~ msgid "Workspace %d%n" +#~ msgstr "কৰ্মস্থান %d%n" -#~ msgid "Switch to workspace 5" -#~ msgstr "কৰ্মস্থান ৫লে পৰিবৰ্তন কৰক" +#~ msgid "Workspace 1_0" +#~ msgstr "কৰ্মস্থান ১০ (_0)" -#~ msgid "Switch to workspace 6" -#~ msgstr "কৰ্মস্থান ৬লে পৰিবৰ্তন কৰক" +#~ msgid "Workspace %s%d" +#~ msgstr "কৰ্মস্থান %s%d" -#~ msgid "Switch to workspace 7" -#~ msgstr "কৰ্মস্থান ৭লে পৰিবৰ্তন কৰক" +#~ msgid "Move to Another _Workspace" +#~ msgstr "অন্য কৰ্মস্থানত স্থানান্তৰ কৰক (_W)" + +#~ msgid "Shift" +#~ msgstr "Shift" + +#~ msgid "Ctrl" +#~ msgstr "Ctrl" + +#~ msgid "Alt" +#~ msgstr "Alt" + +#~ msgid "Meta" +#~ msgstr "মেটা" + +#~ msgid "Super" +#~ msgstr "উত্তম" + +#~ msgid "Hyper" +#~ msgstr "প্ৰবল" + +#~ msgid "Mod2" +#~ msgstr "Mod2" + +#~ msgid "Mod3" +#~ msgstr "Mod3" + +#~ msgid "Mod4" +#~ msgstr "Mod4" + +#~ msgid "Mod5" +#~ msgstr "Mod5" + +#~ msgid "Usage: %s\n" +#~ msgstr "ব্যৱহাৰপদ্ধতি: %s\n" + +#~ msgid "_Windows" +#~ msgstr "উইন্ডোসমূহ (_W)" + +#~ msgid "_Dialog" +#~ msgstr "ডাইলগ (_D)" + +#~ msgid "_Modal dialog" +#~ msgstr "মোডাল ডাইলগ (_M)" + +#~ msgid "_Utility" +#~ msgstr "সঁজুলি (_U)" + +#~ msgid "_Splashscreen" +#~ msgstr "স্প্লেশস্ক্ৰিন (_S)" + +#~ msgid "_Top dock" +#~ msgstr "ওপৰৰ ডক (_T)" + +#~ msgid "_Bottom dock" +#~ msgstr "তলৰ ডক (_B)" + +#~ msgid "_Left dock" +#~ msgstr "বাওফালৰ ডক (_L)" + +#~ msgid "_Right dock" +#~ msgstr "সোফালৰ ডক (_R)" + +#~ msgid "_All docks" +#~ msgstr "সকলো ডক (_A)" + +#~ msgid "Des_ktop" +#~ msgstr "ডেস্কটপ (_k)" + +#~ msgid "Open another one of these windows" +#~ msgstr "এই ধৰণৰ আৰু এটা উইন্ডো খোলক" + +#~ msgid "This is a demo button with an 'open' icon" +#~ msgstr "'খোলা' আইকন বিশিষ্ট এইটো এটা নমূনা বুটাম" + +#~ msgid "This is a demo button with a 'quit' icon" +#~ msgstr "'প্ৰস্থান' আইকন বিশিষ্ট এইটো এটা নমূনা বুটাম" + +#~ msgid "This is a sample message in a sample dialog" +#~ msgstr "এইটো নমুনা সম্বাদ বাকচত এটা নমুনা বাৰ্তা" + +#~ msgid "Fake menu item %d\n" +#~ msgstr "নকল মেনু বস্তু %d\n" + +#~ msgid "Border-only window" +#~ msgstr "অকল প্ৰান্তবিশিষ্ট উইন্ডো" + +#~ msgid "Bar" +#~ msgstr "বাৰ" + +#~ msgid "Normal Application Window" +#~ msgstr "স্বাভাবিক এপ্লিকেচন উইন্ডো" + +#~ msgid "Dialog Box" +#~ msgstr "ডাইলগ বাকচ" + +#~ msgid "Modal Dialog Box" +#~ msgstr "মোডাল ডাইলগ বাকচ" + +#~ msgid "Utility Palette" +#~ msgstr "সঁজুলি পেলেট" + +#~ msgid "Torn-off Menu" +#~ msgstr "পৰিবৰ্তনশীল অবস্থানৰ মেনু" + +#~ msgid "Border" +#~ msgstr "প্ৰান্ত" + +#~ msgid "Attached Modal Dialog" +#~ msgstr "সংযুক্ত মোডাল ডাইলগ" + +#~ msgid "Button layout test %d" +#~ msgstr "বুটাম বিন্যাসৰ পৰীক্ষা %d" + +#~ msgid "%g milliseconds to draw one window frame" +#~ msgstr "এটা উইন্ডো ফ্ৰেইম আকিবলে %g মিলিছেকেণ্ড" + +#~ msgid "Usage: metacity-theme-viewer [THEMENAME]\n" +#~ msgstr "ব্যৱহাৰপদ্ধতি: metacity-theme-viewer [THEMENAME]\n" + +#~ msgid "Error loading theme: %s\n" +#~ msgstr "থীম ল'ড কৰোতে ত্ৰুটি: %s\n" + +#~ msgid "Loaded theme \"%s\" in %g seconds\n" +#~ msgstr "\"%s\" থীম %g ছেকেণ্ডত ল'ড কৰা হৈছে\n" + +#~ msgid "Normal Title Font" +#~ msgstr "স্বাভাবিক শীৰ্ষক ফন্ট" + +#~ msgid "Small Title Font" +#~ msgstr "সৰু শীৰ্ষক ফন্ট" + +#~ msgid "Large Title Font" +#~ msgstr "ডাঙৰ শীৰ্ষক ফন্ট" + +#~ msgid "Button Layouts" +#~ msgstr "বুটামৰ বিন্যাসসমূহ" + +#~ msgid "Benchmark" +#~ msgstr "ধাপ" + +#~ msgid "Window Title Goes Here" +#~ msgstr "উইন্ডো শীৰ্ষক ইয়াত যাব" + +#~ msgid "" +#~ "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and " +#~ "%g seconds wall clock time including X server resources (%g milliseconds " +#~ "per frame)\n" +#~ msgstr "" +#~ "%d ফ্ৰেইমসমূহক %g ক্লাএন্ট-কাষ ছেকেণ্ড (%g মিলিছেকেণ্ড প্ৰতি ফ্ৰেইম) আৰু %g ছেকেণ্ড " +#~ "ৱাল ঘড়ী সময় X চাৰ্ভাৰ সম্পদসমূহ (%g মিলিছেকেণ্ড প্ৰতি ফ্ৰেইম) অন্তৰ্ভুক্ত কৰি অকাঁ " +#~ "হৈছিল\n" + +#~ msgid "position expression test returned TRUE but set error" +#~ msgstr "অবস্থান অভিব্যক্তিৰ পৰীক্ষায়ে TRUE ঘুৰাই দিলেও ত্ৰুটি সংহিত হৈছে" + +#~ msgid "position expression test returned FALSE but didn't set error" +#~ msgstr "অবস্থান অভিব্যক্তিৰ পৰীক্ষায়ে FALSE ঘুৰাই দিলেও ত্ৰুটি সংহিত নাই হোৱা" + +#~ msgid "Error was expected but none given" +#~ msgstr "ত্ৰুটি প্ৰত্যাশিত আছিল কিন্তু কোনো এটা দিয়া হোৱা নাই" + +#~ msgid "Error %d was expected but %d given" +#~ msgstr "ত্ৰুটি %d প্ৰত্যাশিত আছিল কিন্তু %d প্ৰদান কৰা হৈছে" + +#~ msgid "Error not expected but one was returned: %s" +#~ msgstr "ত্ৰুটি প্ৰত্যাশিত নহয় কিন্তু প্ৰাপ্ত: %s" + +#~ msgid "x value was %d, %d was expected" +#~ msgstr "x ৰ মান %d, %d প্ৰত্যাশিত" + +#~ msgid "y value was %d, %d was expected" +#~ msgstr "y ৰ মান %d, %d প্ৰত্যাশিত" + +#~ msgid "" +#~ "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" +#~ msgstr "%d অক্ষ অভিব্যক্তিসমূহ %g ছেকেণ্ডত বিশ্লেষণ কৰা হৈছে (গড় %g ছেকেণ্ড)\n" + +#~ msgid "Minimize window" +#~ msgstr "উইন্ডো লুকাওক" + +#~ msgid "Comma-separated list of compositor plugins" +#~ msgstr "মিশ্ৰক প্লাগিনসমূহৰ কমা-পৃথকিত তালিকা" + +#~ msgid "Live Hidden Windows" +#~ msgstr "জীৱন্ত লুকাই থকা উইন্ডোসমূহ" + +#~ msgid "" +#~ "Determines whether hidden windows (i.e., minimized windows and windows on " +#~ "other workspaces than the current one) should be kept alive." +#~ msgstr "" +#~ "লুকাই থকা উইন্ডোসমূহ (যেনে নূন্যতম উইন্ডোসমূহ আৰু বৰ্তমানক এৰি অন্য কৰ্মস্থানত থকা " +#~ "উইন্ডোসমূহ) জীৱন্ত ৰখা হব নে।" + +#~ msgid "Close Window" +#~ msgstr "উইন্ডো বন্ধ কৰক" + +#~ msgid "Window Menu" +#~ msgstr "উইন্ডো মেনু" + +#~ msgid "Minimize Window" +#~ msgstr "উইন্ডো লুকাওক" + +#~ msgid "Maximize Window" +#~ msgstr "উইন্ডো ডাঙৰ কৰক" + +# +#~ msgid "Restore Window" +#~ msgstr "উইন্ডো পুনৰ সংৰক্ষণ কৰক" + +#~ msgid "Roll Up Window" +#~ msgstr "উইন্ডো মেৰিয়াওক" + +#~ msgid "Unroll Window" +#~ msgstr "উইন্ডো খোলক" + +#~ msgid "Keep Window On Top" +#~ msgstr "উইন্ডোক ওপৰত ৰাখক" + +#~ msgid "Remove Window From Top" +#~ msgstr "উইন্ডোক ওপৰৰ পৰা আতৰাওক" + +#~ msgid "Always On Visible Workspace" +#~ msgstr "সদায় দৃশ্যমান কৰ্মস্থানত" + +#~ msgid "Put Window On Only One Workspace" +#~ msgstr "উইন্ডোক কেৱল এটা কৰ্মস্থানত ৰাখক" #~ msgid "Switch to workspace 8" #~ msgstr "কৰ্মস্থান ৮লে পৰিবৰ্তন কৰক" @@ -1621,29 +1760,30 @@ msgstr "%d অক্ষ অভিব্যক্তিসমূহ %g ছেক # #~ msgid "Switch to workspace on the left of the current workspace" -#~ msgstr "বৰ্তমান কৰ্মস্থানৰ বাঁওফালে থকা কৰ্মস্থানলে পৰিৱৰ্তন কৰক" +#~ msgstr "বৰ্তমান কৰ্মস্থানৰ বাঁওফালে থকা কৰ্মস্থানলে পৰিবৰ্তন কৰক" # #~ msgid "Switch to workspace on the right of the current workspace" -#~ msgstr "বৰ্তমান কৰ্মস্থানৰ সোঁফালে থকা কৰ্মস্থানলে পৰিৱৰ্তন কৰক" +#~ msgstr "বৰ্তমান কৰ্মস্থানৰ সোঁফালে থকা কৰ্মস্থানলে পৰিবৰ্তন কৰক" # #~ msgid "Switch to workspace above the current workspace" -#~ msgstr "বৰ্তমান কৰ্মস্থানৰ উপৰত থকা কৰ্মস্থানলে পৰিৱৰ্তন কৰক" +#~ msgstr "বৰ্তমান কৰ্মস্থানৰ ওপৰত থকা কৰ্মস্থানলে পৰিবৰ্তন কৰক" # #~ msgid "Switch to workspace below the current workspace" -#~ msgstr "বৰ্তমান কৰ্মস্থানৰ তলত থকা কৰ্মস্থানলে পৰিৱৰ্তন কৰক" +#~ msgstr "বৰ্তমান কৰ্মস্থানৰ তলত থকা কৰ্মস্থানলে পৰিবৰ্তন কৰক" # #~ msgid "Move between windows of an application, using a popup window" -#~ msgstr "এটা অনুপ্ৰয়োগৰ উইন্ডোসমূহৰ মাজত পপ-আপ উইন্ডো প্ৰয়োগ কৰি স্থান পৰিবৰ্তন কৰক" +#~ msgstr "এটা এপ্লিকেচনৰ উইন্ডোসমূহৰ মাজত পপ-আপ উইন্ডো প্ৰয়োগ কৰি স্থান পৰিবৰ্তন কৰক" # #~ msgid "" #~ "Move backward between windows of an application, using a popup window" #~ msgstr "" -#~ "এটা অনুপ্ৰয়োগৰ উইন্ডোসমূহৰ মাজত পপ-আপ উইন্ডো প্ৰয়োগ কৰি পিছফালে স্থান পৰিবৰ্তন কৰক" +#~ "এটা এপ্লিকেচনৰ উইন্ডোসমূহৰ মাজত পপ-আপ উইন্ডো প্ৰয়োগ কৰি পিছফালে স্থান পৰিবৰ্তন " +#~ "কৰক" # #~ msgid "Move between windows, using a popup window" @@ -1663,11 +1803,11 @@ msgstr "%d অক্ষ অভিব্যক্তিসমূহ %g ছেক #~ "পেনেল আৰু ডেস্কটপৰ মাজত পপ-আপ উইন্ডো প্ৰয়োগ কৰি পিছফালে স্থান পৰিবৰ্তন কৰক" #~ msgid "Move between windows of an application immediately" -#~ msgstr "অনুপ্ৰয়োগেৰ উইন্ডোসমূহৰ মাজত তৎক্ষনাৎ স্থান পৰিবৰ্তন কৰক" +#~ msgstr "এপ্লিকেচনৰ উইন্ডোসমূহৰ মাজত তৎক্ষনাৎ স্থান পৰিবৰ্তন কৰক" # #~ msgid "Move backward between windows of an application immediately" -#~ msgstr "অনুপ্ৰয়োগৰ উইন্ডোসমূহৰ মাজত তৎক্ষনাৎ পিছফালে স্থান পৰিবৰ্তন কৰক" +#~ msgstr "এপ্লিকেচনৰ উইন্ডোসমূহৰ মাজত তৎক্ষনাৎ পিছফালে স্থান পৰিবৰ্তন কৰক" #~ msgid "Move between windows immediately" #~ msgstr "উইন্ডোসমূহৰ মাজত তৎক্ষনাৎ স্থান পৰিবৰ্তন কৰক" @@ -1692,7 +1832,7 @@ msgstr "%d অক্ষ অভিব্যক্তিসমূহ %g ছেক # #~ msgid "Show the panel's \"Run Application\" dialog box" -#~ msgstr "পেনেলেৰ \"অনুপ্ৰয়োগ চলাওক\"-ৰ ডাইলগ বাকচ প্ৰদৰ্শন কৰক" +#~ msgstr "পেনেলেৰ \"এপ্লিকেচন চলাওক\"ৰ ডাইলগ বাকচ প্ৰদৰ্শন কৰক" #~ msgid "Start or stop recording the session" #~ msgstr "অধিবেশন ৰেকৰ্ড কৰা আৰম্ভ অথবা বন্ধ কৰক" @@ -1706,58 +1846,14 @@ msgstr "%d অক্ষ অভিব্যক্তিসমূহ %g ছেক #~ msgid "Run a terminal" #~ msgstr "টাৰ্মিনেল আৰম্ভ কৰক" -# -#~ msgid "Activate the window menu" -#~ msgstr "উইন্ডো মেনু সক্ৰিয় কৰক" - -#~ msgid "Toggle fullscreen mode" -#~ msgstr "সম্পূৰ্ণপৰ্দা অৱস্থা অদল-বদল কৰক" - -#~ msgid "Toggle maximization state" -#~ msgstr "সৰ্বোচ্চ অবস্থা অদল-বদল কৰক" - # #~ msgid "Toggle whether a window will always be visible over other windows" -#~ msgstr "উইন্ডোটো সদায় অন্য সকল উইন্ডোৰ উপৰ প্ৰদৰ্শিত হ'ব নে সেয়া অদল বদল কৰক" - -#~ msgid "Maximize window" -#~ msgstr "উইন্ডো ডাঙৰ কৰক" - -# -#~ msgid "Restore window" -#~ msgstr "উইন্ডো পুনৰ সংৰক্ষণ কৰক" - -#~ msgid "Toggle shaded state" -#~ msgstr "ছায়াবৃত অবস্থা অদল-বদল কৰক" - -#~ msgid "Minimize window" -#~ msgstr "উইন্ডো লুকাওক" - -#~ msgid "Close window" -#~ msgstr "উইন্ডো বন্ধ কৰক" - -#~ msgid "Move window" -#~ msgstr "উইন্ডো স্থানান্তৰ কৰক" - -#~ msgid "Resize window" -#~ msgstr "উইন্ডোৰ আকাৰ পৰিবৰ্তন কৰক" +#~ msgstr "উইন্ডোটো সদায় অন্য সকল উইন্ডোৰ ওপৰ প্ৰদৰ্শিত হ'ব নে সেয়া অদল বদল কৰক" # #~ msgid "Toggle whether window is on all workspaces or just one" #~ msgstr "উইন্ডো সকলো কৰ্মস্থানত আছে নে এটাত সেয়া অদল বদল কৰক" -#~ msgid "Move window to workspace 1" -#~ msgstr "উইন্ডোক কৰ্মস্থান ১লে স্থানান্তৰ কৰক" - -#~ msgid "Move window to workspace 2" -#~ msgstr "উইন্ডোক কৰ্মস্থান ২লে স্থানান্তৰ কৰক" - -#~ msgid "Move window to workspace 3" -#~ msgstr "উইন্ডোক কৰ্মস্থান ৩লে স্থানান্তৰ কৰক" - -#~ msgid "Move window to workspace 4" -#~ msgstr "উইন্ডোক কৰ্মস্থান ৪লে স্থানান্তৰ কৰক" - #~ msgid "Move window to workspace 5" #~ msgstr "উইন্ডোক কৰ্মস্থান ৫লে স্থানান্তৰ কৰক" @@ -1782,43 +1878,19 @@ msgstr "%d অক্ষ অভিব্যক্তিসমূহ %g ছেক #~ msgid "Move window to workspace 12" #~ msgstr "উইন্ডোক কৰ্মস্থান ১২লে স্থানান্তৰ কৰক" -#~ msgid "Move window one workspace to the left" -#~ msgstr "উইন্ডোক বাওঁফালে এটা কৰ্মস্থানলে স্থানান্তৰ কৰক" - -#~ msgid "Move window one workspace to the right" -#~ msgstr "উইন্ডো সোঁফালে এটা কৰ্মস্থানলে স্থানান্তৰ কৰক" - -#~ msgid "Move window one workspace up" -#~ msgstr "উইন্ডো এটা কৰ্মস্থান উপৰত স্থানান্তৰ কৰক" - -#~ msgid "Move window one workspace down" -#~ msgstr "উইন্ডো এটা কৰ্মস্থান তলত স্থানান্তৰ কৰক" - # #~ msgid "Raise window if it's covered by another window, otherwise lower it" #~ msgstr "" -#~ "অন্য উইন্ডো দ্বাৰা ঢাকা থাকলে উইন্ডোটি উপৰত উইন্ডো উত্থাপন কৰক, অন্যথা সেটি তলত " +#~ "অন্য উইন্ডো দ্বাৰা ঢাকা থাকলে উইন্ডোটি ওপৰত উইন্ডো উত্থাপন কৰক, অন্যথা সেটি তলত " #~ "নমাওক" -#~ msgid "Raise window above other windows" -#~ msgstr "অন্যান্য উইন্ডোৰ উপৰত উইন্ডো উত্থাপন কৰক" - -#~ msgid "Lower window below other windows" -#~ msgstr "উইন্ডোটোক অন্য উইন্ডোৰ তলত নমাওক" - -#~ msgid "Maximize window vertically" -#~ msgstr "উইন্ডো উলম্ব দিশত ডাঙৰ কৰক" - -#~ msgid "Maximize window horizontally" -#~ msgstr "উইন্ডো আনুভূমিক দিশত ডাঙৰ কৰক" - # #~ msgid "Move window to north-west (top left) corner" -#~ msgstr "উইন্ডোক উত্তৰ-পশ্চিম (উপৰত বাওঁফালে) চুকত স্থানান্তৰ কৰক" +#~ msgstr "উইন্ডোক উত্তৰ-পশ্চিম (ওপৰত বাওঁফালে) চুকত স্থানান্তৰ কৰক" # #~ msgid "Move window to north-east (top right) corner" -#~ msgstr "উইন্ডোক উত্তৰ-পূৰ্ব (উপৰত বাওঁফালে) চুকত স্থানান্তৰ কৰক" +#~ msgstr "উইন্ডোক উত্তৰ-পূৰ্ব (ওপৰত বাওঁফালে) চুকত স্থানান্তৰ কৰক" # #~ msgid "Move window to south-west (bottom left) corner" @@ -1830,7 +1902,7 @@ msgstr "%d অক্ষ অভিব্যক্তিসমূহ %g ছেক # #~ msgid "Move window to north (top) side of screen" -#~ msgstr "উইন্ডোক পৰ্দাৰ উত্তৰ (উপৰ) কাষত স্থানান্তৰ কৰক" +#~ msgstr "উইন্ডোক পৰ্দাৰ উত্তৰ (ওপৰ) কাষত স্থানান্তৰ কৰক" # #~ msgid "Move window to south (bottom) side of screen" @@ -1864,26 +1936,26 @@ msgstr "%d অক্ষ অভিব্যক্তিসমূহ %g ছেক #~ msgstr "টাৰ্মিনেলত কোনো কমান্ডৰ ব্যাখ্যা দিয়া হোৱা নাই।\n" #~ msgid "GConf key '%s' is set to an invalid value\n" -#~ msgstr "GConf-কি \"%s\"'ৰ মান বৈধ নহয়\n" +#~ msgstr "GConf-কি \"%s\" ৰ মান বৈধ নহয়\n" #~ msgid "%d stored in GConf key %s is out of range %d to %d\n" -#~ msgstr "%d মান যি GConf-কি %s-ত সংৰক্ষিত আছে, %d -ৰ পৰা %d বিস্তাৰৰ বাহিৰ\n" +#~ msgstr "%d মান যি GConf-কি %sত সংৰক্ষিত আছে, %d ৰ পৰা %d বিস্তাৰৰ বাহিৰ\n" #~ msgid "GConf key \"%s\" is set to an invalid type\n" #~ msgstr "GConf-কি \"%s\" এটা অবৈধ ধৰণলে সংহতি কৰা হৈছে\n" #~ msgid "GConf key %s is already in use and can't be used to override %s\n" #~ msgstr "" -#~ "GConf চাবি %s ইতিমধ্যে ব্যৱহৃত আৰু %s -ক অভাৰাইড কৰিবলে ব্যৱহাৰ কৰিব নোৱাৰি\n" +#~ "GConf কি' %s ইতিমধ্যে ব্যৱহৃত আৰু %s ক অভাৰাইড কৰিবলে ব্যৱহাৰ কৰিব নোৱাৰি\n" #~ msgid "Can't override GConf key, %s not found\n" -#~ msgstr "GConf চাবি অভাৰাইড কৰিব নোৱাৰি, %s পোৱা নগল\n" +#~ msgstr "GConf কি' অভাৰাইড কৰিব নোৱাৰি, %s পোৱা নগল\n" #~ msgid "Error setting number of workspaces to %d: %s\n" -#~ msgstr "কৰ্মস্থানসমূহৰ সংখ্যা %d -ত সংহতি কৰিব পৰা নগল: %s\n" +#~ msgstr "কৰ্মস্থানসমূহৰ সংখ্যা %d ত সংহতি কৰিব পৰা নগল: %s\n" #~ msgid "Error setting name for workspace %d to \"%s\": %s\n" -#~ msgstr "কৰ্মস্থান %d'ৰ নাম \"%s\" ৰূপে নিৰ্ধাৰণ কৰিব পৰা নগল: %s\n" +#~ msgstr "কৰ্মস্থান %d ৰ নাম \"%s\" ৰূপে নিৰ্ধাৰণ কৰিব পৰা নগল: %s\n" #~ msgid "Error setting live hidden windows status status: %s\n" #~ msgstr "জীৱন্ত লুকাই থকা উইন্ডোৰ অৱস্থা সংহতি কৰোতে ত্ৰুটি অৱস্থা: %s\n" diff --git a/po/ast.po b/po/ast.po index c5d15ead5..4fa5ea45b 100644 --- a/po/ast.po +++ b/po/ast.po @@ -12,7 +12,7 @@ msgid "" msgstr "" "Project-Id-Version: metacity\n" "Report-Msgid-Bugs-To: " -"http://bugzilla.gnome.org/enter_bug.cgi?product=muffin&component=general\n" +"http://bugzilla.gnome.org/enter_bug.cgi?product=mutter&component=general\n" "POT-Creation-Date: 2010-03-27 15:48+0000\n" "PO-Revision-Date: 2010-03-30 06:02+0200\n" "Last-Translator: Xandru Armesto <xandru@softastur.org>\n" @@ -37,7 +37,6 @@ msgstr "Petición d'información ventana desconocida: %d" #. Translators: %s is a window title #: ../src/core/delete.c:95 #, c-format -#, c-format msgid "<tt>%s</tt> is not responding." msgstr "<tt>%s</tt> nun ta respondiendo." @@ -122,15 +121,14 @@ msgstr "Comandu de terminal nun definíu.\n" #: ../src/core/main.c:130 #, c-format -#, c-format msgid "" -"muffin %s\n" +"mutter %s\n" "Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" "This is free software; see the source for copying conditions.\n" "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " "PARTICULAR PURPOSE.\n" msgstr "" -"muffin %s\n" +"mutter %s\n" "Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., y otros\n" "Esti software ye llibre, mira'l códigu pa ver les condiciones de copia.\n" "Entrégase ensin garantía NENGUNA, yá seya pa usu COMERCIAL o PA FINES " @@ -141,8 +139,8 @@ msgid "Disable connection to session manager" msgstr "Desconectar xestor de sesión" #: ../src/core/main.c:267 -msgid "Replace the running window manager with Muffin" -msgstr "Camuda'l xestor ventanes por Muffin" +msgid "Replace the running window manager with Mutter" +msgstr "Camuda'l xestor ventanes por Mutter" #: ../src/core/main.c:273 msgid "Specify session management ID" @@ -261,7 +259,6 @@ msgstr "Error axustando númberu d'arees de trabayu a %d: %s\n" #: ../src/core/prefs.c:2028 ../src/core/prefs.c:2531 #, c-format -#, c-format msgid "Workspace %d" msgstr "Espaciu de Trabayu %d" @@ -275,7 +272,6 @@ msgstr "\"%s\" atopau na base de datos de configuración nun ye un valor válidu #: ../src/core/prefs.c:2612 #, c-format -#, c-format msgid "Error setting name for workspace %d to \"%s\": %s\n" msgstr "Fallu al afitar nome pal espaciu de trabayu %d a \"%s\": %s\n" @@ -286,19 +282,16 @@ msgstr "Fallu al afitar l'estáu del compositor: %s\n" #: ../src/core/prefs.c:2845 #, c-format -#, c-format msgid "Error setting clutter plugin list: %s\n" msgstr "Fallu al afitar la llista desordenada de plugin: %s\n" #: ../src/core/prefs.c:2889 #, c-format -#, c-format msgid "Error setting live hidden windows status status: %s\n" msgstr "Fallu al afitar l'estáu de les ventanes anubríes: %s\n" #: ../src/core/prefs.c:2917 #, c-format -#, c-format msgid "Error setting no tab popup status: %s\n" msgstr "Fallu al afitar l'estáu de les llingüetes emerxentes: %s\n" @@ -358,9 +351,8 @@ msgstr "Falló analizar ficheru de sesión guardáu: %s\n" #: ../src/core/session.c:1198 #, c-format -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "Vióse l'atributu <muffin_session> pero yá tenemos la ID de sesión" +msgid "<mutter_session> attribute seen but we already have the session ID" +msgstr "Vióse l'atributu <mutter_session> pero yá tenemos la ID de sesión" #: ../src/core/session.c:1211 ../src/core/session.c:1286 #: ../src/core/session.c:1318 ../src/core/session.c:1390 @@ -402,11 +394,10 @@ msgstr "Falló ficheru rexistru actividá fdopen() %s: %s\n" msgid "Opened log file %s\n" msgstr "Abiertu archivu log %s\n" -#: ../src/core/util.c:139 ../src/tools/muffin-message.c:176 +#: ../src/core/util.c:139 ../src/tools/mutter-message.c:176 #, c-format -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "Muffin compilose ensin sofitu pal mou testu\n" +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter compilose ensin sofitu pal mou testu\n" #: ../src/core/util.c:239 msgid "Window manager: " @@ -426,10 +417,10 @@ msgstr "Error xestor ventanes: " #. Translators: This is the title used on dialog boxes #. eof all-keybindings.h -#: ../src/core/util.c:573 ../src/muffin.desktop.in.h:1 -#: ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" +#: ../src/core/util.c:573 ../src/mutter.desktop.in.h:1 +#: ../src/mutter-wm.desktop.in.h:1 +msgid "Mutter" +msgstr "Mutter" #. first time through #: ../src/core/window.c:6217 @@ -499,19 +490,19 @@ msgid "" msgstr "La propiedá %s del ventanu 0x%lx contien un códigu UTF-8 non válidu pal " "elementu %d na llista\n" -#: ../src/include/all-keybindings.h:88 +#: ../src/include/all-keybindings.h:88 ../src/50-mutter-navigation.xml.in.h:18 msgid "Switch to workspace 1" msgstr "Cambiar a espaciu de trabayu 1" -#: ../src/include/all-keybindings.h:90 +#: ../src/include/all-keybindings.h:90 ../src/50-mutter-navigation.xml.in.h:19 msgid "Switch to workspace 2" msgstr "Cambiar a espaciu de trabayu 2" -#: ../src/include/all-keybindings.h:92 +#: ../src/include/all-keybindings.h:92 ../src/50-mutter-navigation.xml.in.h:20 msgid "Switch to workspace 3" msgstr "Cambiar a espaciu de trabayu 3" -#: ../src/include/all-keybindings.h:94 +#: ../src/include/all-keybindings.h:94 ../src/50-mutter-navigation.xml.in.h:21 msgid "Switch to workspace 4" msgstr "Cambiar a espaciu de trabayu 4" @@ -640,47 +631,57 @@ msgstr "Saca una semeya d'una ventana" msgid "Run a terminal" msgstr "Executar una terminal" -#: ../src/include/all-keybindings.h:271 +#: ../src/include/all-keybindings.h:271 ../src/50-mutter-windows.xml.in.h:1 msgid "Activate the window menu" msgstr "Activar el menú de la ventana" -#: ../src/include/all-keybindings.h:274 +#: ../src/include/all-keybindings.h:274 ../src/50-mutter-windows.xml.in.h:13 +#, fuzzy msgid "Toggle fullscreen mode" -msgstr "Camudar a modu pantalla completa" +msgstr "" +"#-#-#-#-# ast.po (metacity) #-#-#-#-#\n" +"Camudar a modu pantalla completa\n" +"#-#-#-#-# ast.po (metacity) #-#-#-#-#\n" +"Camudar a mou pantalla completa" -#: ../src/include/all-keybindings.h:276 +#: ../src/include/all-keybindings.h:276 ../src/50-mutter-windows.xml.in.h:14 +#, fuzzy msgid "Toggle maximization state" -msgstr "Camudar a estáu maximizáu" +msgstr "" +"#-#-#-#-# ast.po (metacity) #-#-#-#-#\n" +"Camudar a estáu maximizáu\n" +"#-#-#-#-# ast.po (metacity) #-#-#-#-#\n" +"Conmutar l'estáu maximizáu" #: ../src/include/all-keybindings.h:278 msgid "Toggle whether a window will always be visible over other windows" msgstr "Conmutar si una ventana siempres se verá encima d'otres ventanes" -#: ../src/include/all-keybindings.h:280 +#: ../src/include/all-keybindings.h:280 ../src/50-mutter-windows.xml.in.h:4 msgid "Maximize window" msgstr "Maximizar ventana" -#: ../src/include/all-keybindings.h:282 +#: ../src/include/all-keybindings.h:282 ../src/50-mutter-windows.xml.in.h:12 msgid "Restore window" msgstr "Restaurar la ventana" -#: ../src/include/all-keybindings.h:284 +#: ../src/include/all-keybindings.h:284 ../src/50-mutter-windows.xml.in.h:15 msgid "Toggle shaded state" msgstr "Activa estáu endolcáu" -#: ../src/include/all-keybindings.h:286 +#: ../src/include/all-keybindings.h:286 ../src/50-mutter-windows.xml.in.h:7 msgid "Minimize window" msgstr "Minimizar ventana" -#: ../src/include/all-keybindings.h:288 +#: ../src/include/all-keybindings.h:288 ../src/50-mutter-windows.xml.in.h:2 msgid "Close window" msgstr "Zarrar ventana" -#: ../src/include/all-keybindings.h:290 +#: ../src/include/all-keybindings.h:290 ../src/50-mutter-windows.xml.in.h:8 msgid "Move window" msgstr "Mover ventana" -#: ../src/include/all-keybindings.h:292 +#: ../src/include/all-keybindings.h:292 ../src/50-mutter-windows.xml.in.h:11 msgid "Resize window" msgstr "Cambiar el tamañu la ventana" @@ -689,18 +690,22 @@ msgid "Toggle whether window is on all workspaces or just one" msgstr "Conmutar si la ventana apaez en toles árees de trabayu o namái nuna" #: ../src/include/all-keybindings.h:299 +#: ../src/50-mutter-navigation.xml.in.h:10 msgid "Move window to workspace 1" msgstr "Mover ventana al espaciu de trabayu 1" #: ../src/include/all-keybindings.h:302 +#: ../src/50-mutter-navigation.xml.in.h:11 msgid "Move window to workspace 2" msgstr "Mover ventana al espaciu de trabayu 2" #: ../src/include/all-keybindings.h:305 +#: ../src/50-mutter-navigation.xml.in.h:12 msgid "Move window to workspace 3" msgstr "Mover ventana al espaciu de trabayu 3" #: ../src/include/all-keybindings.h:308 +#: ../src/50-mutter-navigation.xml.in.h:13 msgid "Move window to workspace 4" msgstr "Mover ventana al espaciu de trabayu 4" @@ -736,19 +741,24 @@ msgstr "Mover ventana al espaciu de trabayu 11" msgid "Move window to workspace 12" msgstr "Mover ventana al espaciu de trabayu 12" -#: ../src/include/all-keybindings.h:344 +#: ../src/include/all-keybindings.h:344 ../src/50-mutter-navigation.xml.in.h:7 msgid "Move window one workspace to the left" msgstr "Mover ventana un espaciu de trabayu a manzorga" -#: ../src/include/all-keybindings.h:347 +#: ../src/include/all-keybindings.h:347 ../src/50-mutter-navigation.xml.in.h:8 +#, fuzzy msgid "Move window one workspace to the right" -msgstr "Mover ventana un espaciu de trabayu a derecha" +msgstr "" +"#-#-#-#-# ast.po (metacity) #-#-#-#-#\n" +"Mover ventana un espaciu de trabayu a derecha\n" +"#-#-#-#-# ast.po (metacity) #-#-#-#-#\n" +"Mover ventana un espaciu de trabayu a madrecha" -#: ../src/include/all-keybindings.h:350 +#: ../src/include/all-keybindings.h:350 ../src/50-mutter-navigation.xml.in.h:9 msgid "Move window one workspace up" msgstr "Mover ventana un espaciu de trabayu p'arriba" -#: ../src/include/all-keybindings.h:353 +#: ../src/include/all-keybindings.h:353 ../src/50-mutter-navigation.xml.in.h:6 msgid "Move window one workspace down" msgstr "Mover ventana un espaciu de trabayu p'abaxo" @@ -757,19 +767,29 @@ msgid "Raise window if it's covered by another window, otherwise lower it" msgstr "" "Llevantar la ventana si ta cubierta por otra ventana, minimizala n'otru casu" -#: ../src/include/all-keybindings.h:358 +#: ../src/include/all-keybindings.h:358 ../src/50-mutter-windows.xml.in.h:9 +#, fuzzy msgid "Raise window above other windows" -msgstr "Poner el ventanu en primer planu" +msgstr "" +"#-#-#-#-# ast.po (metacity) #-#-#-#-#\n" +"Poner el ventanu en primer planu\n" +"#-#-#-#-# ast.po (metacity) #-#-#-#-#\n" +"Poner la ventana en primer planu" -#: ../src/include/all-keybindings.h:360 +#: ../src/include/all-keybindings.h:360 ../src/50-mutter-windows.xml.in.h:3 +#, fuzzy msgid "Lower window below other windows" -msgstr "Ventanu más baxu per debaxo d'otros ventanos" +msgstr "" +"#-#-#-#-# ast.po (metacity) #-#-#-#-#\n" +"Ventanu más baxu per debaxo d'otros ventanos\n" +"#-#-#-#-# ast.po (metacity) #-#-#-#-#\n" +"Ventana más baxa per debaxo d'otres ventanes" -#: ../src/include/all-keybindings.h:364 +#: ../src/include/all-keybindings.h:364 ../src/50-mutter-windows.xml.in.h:6 msgid "Maximize window vertically" msgstr "Maximizar ventana verticalmente" -#: ../src/include/all-keybindings.h:368 +#: ../src/include/all-keybindings.h:368 ../src/50-mutter-windows.xml.in.h:5 msgid "Maximize window horizontally" msgstr "Maximizar ventana horizontalmente" @@ -809,11 +829,11 @@ msgstr "Mover la ventana al llau oeste (esquierda) de la pantalla" msgid "Move window to center of screen" msgstr "Mover la ventana al centru de la pantalla" -#: ../src/muffin.schemas.in.h:1 +#: ../src/mutter.schemas.in.h:1 msgid "Clutter Plugins" msgstr "Plugins Enllenos" -#: ../src/muffin.schemas.in.h:2 +#: ../src/mutter.schemas.in.h:2 msgid "" "Determines whether hidden windows (i.e., minimized windows and windows on " "other workspaces than the current one) should be kept alive." @@ -821,19 +841,19 @@ msgstr "" "Determina si les ventanes anubríes (por exemplu ventanes minimizaes y " "ventanes y otros espacios de trabayu actuales) deberíen mantenese." -#: ../src/muffin.schemas.in.h:3 +#: ../src/mutter.schemas.in.h:3 msgid "Live Hidden Windows" msgstr "Amosar Ventanes Anubríes" -#: ../src/muffin.schemas.in.h:4 +#: ../src/mutter.schemas.in.h:4 msgid "Modifier to use for extended window management operations" msgstr "Modificador a usar pa les aiciones de xestión de ventanes estendida" -#: ../src/muffin.schemas.in.h:5 +#: ../src/mutter.schemas.in.h:5 msgid "Plugins to load for the Clutter-based compositing manager." msgstr "Plugins pa cargar dende xestor de composición Clutter-based." -#: ../src/muffin.schemas.in.h:6 +#: ../src/mutter.schemas.in.h:6 msgid "" "This key will initiate the \"overlay\", which is a combination window overview " "and application launching system. The default is intended to be the " @@ -845,7 +865,7 @@ msgstr "" "tecla\" nel hardware del PC. Espérase que seya vinculante por defeutu o " "afitáu a cadena erma." -#: ../src/tools/muffin-message.c:150 +#: ../src/tools/mutter-message.c:150 #, c-format msgid "Usage: %s\n" msgstr "Emplegu: %s\n" @@ -983,7 +1003,6 @@ msgstr "Espaciu de Trabayu %d%n" #: ../src/ui/menu.c:213 #, c-format -#, c-format msgid "Workspace 1_0" msgstr "Espaciu de Trabayu 1_0" @@ -1724,7 +1743,6 @@ msgstr "Nun se permite testu dientro del elementu <%s>" #: ../src/ui/theme-parser.c:3748 ../src/ui/theme-parser.c:3760 #: ../src/ui/theme-parser.c:3772 #, c-format -#, c-format msgid "<%s> specified twice for this theme" msgstr "<%s> especificáu dos vegaes pa esti tema" @@ -1936,6 +1954,96 @@ msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" msgstr "%d espresiones de coordenaes interpretaes en %g segundos (%g segundos de " "media)\n" +#: ../src/50-mutter-navigation.xml.in.h:1 +#, fuzzy +msgid "Hide all normal windows" +msgstr "Anubrir toles ventanes normales" + +#: ../src/50-mutter-navigation.xml.in.h:2 +#, fuzzy +msgid "Move to workspace above" +msgstr "Mover al área de trabayu d'arriba" + +#: ../src/50-mutter-navigation.xml.in.h:3 +#, fuzzy +msgid "Move to workspace below" +msgstr "Mover al área de trabayu d'abaxo" + +#: ../src/50-mutter-navigation.xml.in.h:4 +#, fuzzy +msgid "Move to workspace left" +msgstr "Mover al área de trabayu de la izquierda" + +#: ../src/50-mutter-navigation.xml.in.h:5 +#, fuzzy +msgid "Move to workspace right" +msgstr "Mover al área de trabayu de la derecha" + +#: ../src/50-mutter-navigation.xml.in.h:14 +#, fuzzy +msgid "Navigation" +msgstr "Navegación" + +#: ../src/50-mutter-navigation.xml.in.h:15 +#, fuzzy +msgid "Switch applications" +msgstr "Movese ente aplicaciones" + +#: ../src/50-mutter-navigation.xml.in.h:16 +#, fuzzy +msgid "Switch system controls" +msgstr "Cambiar ente controles del sistema" + +#: ../src/50-mutter-navigation.xml.in.h:17 +#, fuzzy +msgid "Switch system controls directly" +msgstr "Movese ente los controles del sistema direutamente" + +#: ../src/50-mutter-navigation.xml.in.h:22 +#, fuzzy +msgid "Switch windows directly" +msgstr "Cambiar ventanes direutamente" + +#: ../src/50-mutter-navigation.xml.in.h:23 +#, fuzzy +msgid "Switch windows of an app directly" +msgstr "Movese ente les ventanes d'una aplicación direutamente" + +#: ../src/50-mutter-navigation.xml.in.h:24 +#, fuzzy +msgid "Switch windows of an application" +msgstr "Movese ente les ventanes d'una aplicación" + +#: ../src/50-mutter-system.xml.in.h:1 +#, fuzzy +msgid "Show the activities overview" +msgstr "Amosar el resume d'actividaes" + +#: ../src/50-mutter-system.xml.in.h:2 +#, fuzzy +msgid "Show the run command prompt" +msgstr "Amosar l'elementu «executar comando»" + +#: ../src/50-mutter-system.xml.in.h:3 +#, fuzzy +msgid "System" +msgstr "Sistema" + +#: ../src/50-mutter-windows.xml.in.h:10 +#, fuzzy +msgid "Raise window if covered, otherwise lower it" +msgstr "Llevantar la ventana si ta cubierta, minimizala n'otru casu" + +#: ../src/50-mutter-windows.xml.in.h:16 +#, fuzzy +msgid "Toggle window on all workspaces or one" +msgstr "Conmutar la ventana en toles árees de trabayu o namái nuna" + +#: ../src/50-mutter-windows.xml.in.h:17 +#, fuzzy +msgid "Windows" +msgstr "Ventanes" + #~ msgid "Desktop" #~ msgstr "Escritoriu" diff --git a/po/az.po b/po/az.po index 0c6a3f762..bc3db2170 100644 --- a/po/az.po +++ b/po/az.po @@ -12,10 +12,10 @@ msgstr "" "PO-Revision-Date: 2004-08-17 21:53+0300\n" "Last-Translator: Metin Amiroff <metin@karegen.com>\n" "Language-Team: Azerbaijani <translation-team-az@lists.sourceforge.net>\n" +"Language: az\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"net>\n" "X-Generator: KBabel 1.3.1\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" diff --git a/po/be.po b/po/be.po index 3eaf0cfb2..94ed8119f 100644 --- a/po/be.po +++ b/po/be.po @@ -1,448 +1,314 @@ -# Ihar Hrachyshka <ihar.hrachyshka@gmail.com>, 2011. +# Ihar Hrachyshka <ihar.hrachyshka@gmail.com>, 2011, 2013. +# Yuras Shumovich <shumovichy@gmail.com>, 2017. msgid "" msgstr "" -"Project-Id-Version: muffin.master\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-02-26 22:15+0300\n" -"PO-Revision-Date: 2012-02-26 22:23+0300\n" -"Last-Translator: Ігар Грачышка <ihar.hrachyshka@gmail.com>\n" +"Project-Id-Version: mutter.master\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2018-07-07 09:58+0000\n" +"PO-Revision-Date: 2018-09-06 18:47+0300\n" +"Last-Translator: Yuras Shumovich <shumovichy@gmail.com>\n" "Language-Team: Belarusian <i18n-bel-gnome@googlegroups.com>\n" "Language: be\n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" +"Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Pootle 2.1.6\n" +"X-Generator: Poedit 2.1.1\n" -#: ../src/50-muffin-windows.xml.in.h:1 -msgid "Windows" -msgstr "Вокны" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Навігацыя" -#: ../src/50-muffin-windows.xml.in.h:2 -msgid "View split on left" -msgstr "Падзяліць прагляд злева" +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Перамясціць акно ў прастору 1" -#: ../src/50-muffin-windows.xml.in.h:3 -msgid "View split on right" -msgstr "Падзяліць прагляд справа" +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Перамясціць акно ў прастору 2" -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format -msgid "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." -msgstr "" -"Іншы кампазітны кіраўнік вокнаў ужо абслугоўвае экран %i дысплея \"%s\"." +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Перамясціць акно ў прастору 3" -#: ../src/core/bell.c:307 -msgid "Bell event" -msgstr "Падзея з сігналам" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Перамясціць акно ў прастору 4" -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Невядомы запыт інфармацыі пра акно: %d" +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Перамясціць акно ў апошнюю прастору" -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> не адказвае на запыты." +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "Перамясціць акно ў прастору зверху ад дзейнай" -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "Праграма не адказвае на запыты." +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "Перамясціць акно ў прастору знізу ад дзейнай" -#: ../src/core/delete.c:119 -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "" -"Вы можаце альбо крыху пачакаць адказу, альбо змусіць праграму да выхаду." +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "Перамясціць акно на манітор злева ад дзейнага" -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "_Пачакаць" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "Перамясціць акно на манітор справа ад дзейнага" -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "_Змусіць да выхаду" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "Перамясціць акно на манітор зверху ад дзейнага" -#: ../src/core/display.c:361 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "" -"Адсутнічае пашырэнне \"%s\", патрэбнае для ажыццяўлення кампазітнага вываду" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "Перамясціць акно на манітор знізу ад дзейнага" -#: ../src/core/display.c:427 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Не ўдалося адкрыць X-дысплей аконнай сістэмы \"%s\"\n" +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "Пераключэнне праграм" -#: ../src/core/keybindings.c:852 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "" -"Нейкая іншая праграма ўжо выкарыстоўвае як скарот клавішу %s з " -"мадыфікатарамі %x\n" +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "Пераключыць на папярэднюю праграму" -#: ../src/core/main.c:206 -msgid "Disable connection to session manager" -msgstr "Выключыць злучэнне з кіраўніком сеансаў" +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "Пераключэнне вокнаў" -#: ../src/core/main.c:212 -msgid "Replace the running window manager" -msgstr "Замяніць дзейнага кіраўніка вокнаў" +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "Перайсці на папярэдняе акно" -#: ../src/core/main.c:218 -msgid "Specify session management ID" -msgstr "Вызначыць ідэнтыфікатар для кіравання сеансам" +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "Пераключэнне вокнаў праграмы" -#: ../src/core/main.c:223 -msgid "X Display to use" -msgstr "Патрэбны X-дысплей" +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "Перайсці на папярэдняе акно праграмы" -#: ../src/core/main.c:229 -msgid "Initialize session from savefile" -msgstr "Ініцыяваць сеанс з файла" +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "Пераключэнне паміж сістэмнымі элементамі кіравання" -#: ../src/core/main.c:235 -msgid "Make X calls synchronous" -msgstr "Сінхронна выконваць выклікі X-сістэмы" +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "Пераключыць на папярэдні сістэмны элемент кіравання" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Не ўдалося праглядзець каталог з матывамі аздаблення: %s\n" +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "Непасрэднае пераключэнне вокнаў" -#: ../src/core/main.c:520 -#, c-format -msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "" -"Не ўдалося адшукаць матыў аздаблення! Праверце, каб каталог %s існаваў і " -"змяшчаў звычайныя матывы.\n" +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "Перайсці непасрэдна на папярэдняе акно" -#: ../src/core/muffin.c:40 -#, c-format -msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" -"muffin %s\n" -"Аўтарскія правы (C) 2001-%d Havoc Pennington, Red Hat, Inc. і інш.\n" -"Гэта свабоднае апраграмаванне. Умовы яго капіравання глядзіце ў выточным " -"кодзе праграмы.\n" -"Аўтары не даюць ніякіх гарантый, у тым ліку камерцыйнай вартасці праграмы і " -"наогул яе карысці.\n" - -#: ../src/core/muffin.c:54 -msgid "Print version" -msgstr "Вывесці нумар версіі праграмы" - -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "Спіс плугінаў кампазітнага вываду, падзеленых коскамі" - -#: ../src/core/prefs.c:1069 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"Асаблівыя паводзіны для некаторых хібных праграм выключаныя. Некаторыя " -"праграмы могуць перастаць працаваць, як мае быць.\n" +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "Непасрэднае пераключэнне вокнаў праграмы" -#: ../src/core/prefs.c:1144 -#, c-format -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "Не ўдалося разабраць азначэнне шрыфту \"%s\" з GSettings-ключа %s\n" +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "Перайсці непасрэдна на папярэдняе акно праграмы" -#: ../src/core/prefs.c:1210 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"Значэнне \"%s\", знойдзенае ў базе канфігурацыйных даных, не азначае " -"мадыфікатар мышынай кнопкі\n" - -#: ../src/core/prefs.c:1722 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "" -"Значэнне \"%s\", знойдзенае ў базе канфігурацыйных даных, не азначае " -"клавіятурны скарот \"%s\"\n" - -#: ../src/core/prefs.c:1819 -#, c-format -msgid "Workspace %d" -msgstr "Прастора працы %d" +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "Непасрэднае пераключэнне паміж сістэмнымі элементамі кіравання" -#: ../src/core/screen.c:730 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "Экран %d на дысплеі \"%s\" хібны\n" +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "Перайсці непасрэдна на папярэдні сістэмны элемент кіравання" -#: ../src/core/screen.c:746 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"Экран %d на дысплеі \"%s\" ужо мае аконнага кіраўніка. Каб замяніць яго " -"новым, дадайце опцыю --replace.\n" +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "Схаваць усе звычайныя вокны" -#: ../src/core/screen.c:773 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "" -"Не ўдалося пераняць вылучэнне кіраўніка вокнаў для экрана %d дысплея \"%s\"\n" +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "Перайсці ў прастору працы 1" -#: ../src/core/screen.c:828 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "Экран %d на дысплеі \"%s\" ужо мае кіраўніка вокнаў\n" +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "Перайсці ў прастору працы 2" -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "Не ўдалося вызваліць экран %d на дысплеі \"%s\"\n" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "Перайсці ў прастору працы 3" -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Не ўдалося стварыць каталог \"%s\": %s\n" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "Перайсці ў прастору працы 4" -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "Не ўдалося адкрыць файл сеанса \"%s\" для запісу: %s\n" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "Перайсці ў апошнюю прастору працы" -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Не ўдалося запісаць файл сеанса \"%s\": %s\n" +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "Перамясціць на прастору працы зверху" -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Не ўдалося закрыць файл сеанса \"%s\": %s\n" +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "Перамясціць на прастору працы знізу" -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Не ўдалося разабраць захаваны файл сеанса: %s\n" +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "Сістэма" -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "" -"сустрэты атрыбут <muffin_session>, але мы ўжо маем ідэнтыфікатар сеанса" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Паказаць акенца для выканання загаду" -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Элемент <%2$s> мае невядомы атрыбут %1$s" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Паказаць агляд дзейнасцяў" -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "укладзены тэг <window>" +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Аднавіць клавіятурныя скароты" -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "Невядомы элемент %s" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Вокны" -#: ../src/core/session.c:1809 -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" -"Гэтыя вокны не падтрымліваюць функцыі захавання дзейнага ладу працы, і таму " -"іх прыйдзецца запусціць уручную пасля наступнага ўваходу ў сістэму." +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "Адкрыць меню акна" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Не ўдалося адкрыць адладачны журнал: %s\n" +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Перамяніць рэжым \"на ўвесь экран\"" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Не ўдалося выканаць fdopen() для журнальнага файла %s: %s\n" +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "Перамяніць максімалізацыю акна" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "Журнальны файл %s адкрыты\n" +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "Максімалізаваць акно" -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "" -"Праграма \"Muffin\" была скампіляваная без падтрымкі падрабязнага " -"пратакаліравання\n" +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Аднавіць былы памер акна" -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "Кіраўнік вокнаў: " +#: data/50-mutter-windows.xml:18 +msgid "Close window" +msgstr "Закрыць акно" -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "Хіба ў кіраўніку вокнаў: " +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "Схаваць акно" -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "Перасцярога ад кіраўніка вокнаў: " +#: data/50-mutter-windows.xml:22 +msgid "Move window" +msgstr "Перамясціць акно" -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "Памылка кіраўніка вокнаў: " +#: data/50-mutter-windows.xml:24 +msgid "Resize window" +msgstr "Змяніць памер акна" -#. first time through -#: ../src/core/window.c:7224 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"Акно %s прызначыла SM_CLIENT_ID для сябе, а не для акна WM_CLIENT_LEADER, як " -"таго вымагае спецыфікацыя ICCCM.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7887 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size " -"%d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"Акно %s уключыла для сябе MWM-уласцівасць, якая азначае незмяняльнасць " -"памеру, але разам з гэтым прызначыла для сябе мінімальны памер %d x %d і " -"максімальны памер %d x %d. Такія паводзіны не маюць сэнсу.\n" +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "Перамяніць, ці бачнае акно на ўсіх прасторах працы" -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "Праграма прызначыла памылковае значэнне _NET_WM_PID %lu\n" +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "Узняць акно, калі яно закрыта іншымі вокнамі, іначай апусціць яго" -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (на %s)" +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "Узняць акно над астатнімі" -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "Для %2$s вызначана хібнае акно WM_TRANSIENT_FOR 0x%1$lx.\n" +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "Апусціць акно пад астатнія" -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "WM_TRANSIENT_FOR акно 0x%lx для %s стварыла б цыкл.\n" +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "Вертыкальна максімалізаваць акно" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"Акно 0x%lx мае ўласцівасць %s,\n" -"якая мусіла мець тып %s, фармат %d,\n" -"а ў сапраўднасці мае тып %s, фармат %d, n_items %d.\n" -"Відаць, гэта хіба самой праграмы, а не кіраўніка вокнаў.\n" -"Акно мае загаловак=\"%s\", клас=\"%s\", назву=\"%s\"\n" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "Гарызантальна максімалізаваць акно" -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "Уласцівасць %s акна 0x%lx змяшчала хібныя для UTF-8 знакі\n" +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "Падзяліць прагляд злева" -#: ../src/core/xprops.c:494 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"Уласцівасць %s акна 0x%lx змяшчала хібныя для UTF-8 знакі ў складніку %d " -"спіса\n" +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "Падзяліць прагляд справа" -#: ../src/muffin.desktop.in.h:1 ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 +#: data/org.gnome.mutter.gschema.xml.in:7 msgid "Modifier to use for extended window management operations" msgstr "" "Клавіша-мадыфікатар для доступу да пашыраных аперацый кіравання вокнамі" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 +#: data/org.gnome.mutter.gschema.xml.in:8 msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." msgstr "" +"Гэта клавіша запусціць \"перакрыццё\", якое прадстаўляе спалучэнне агляду " +"вокнаў і сістэму запуску праграм. Прадвызначаная клавіша для гэтай аперацыі " +"- гэта клавіша \"Windows\" на PC-камп'ютары. Чакаецца, што гэты скарот будзе " +"або прадвызначаным значэннем, або пустым тэкставым ланцужком." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 +#: data/org.gnome.mutter.gschema.xml.in:20 msgid "Attach modal dialogs" msgstr "Прычапляць мадальныя дыялогавыя акенцы" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 +#: data/org.gnome.mutter.gschema.xml.in:21 msgid "" "When true, instead of having independent titlebars, modal dialogs appear " "attached to the titlebar of the parent window and are moved together with " "the parent window." msgstr "" +"Калі ўключана, замест незалежных загалоўных стужак мадальныя дыялогавыя " +"акенцы будуць прычэплівацца да загалоўных стужак галоўных вокнаў і " +"перасоўвацца разам з імі." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -msgid "Live Hidden Windows" -msgstr "Дзейныя схаваныя вокны" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"Вызначае, ці трэба захоўваць дзейнымі схаваныя вокны (напрыклад, " -"мінімалізаваныя або вокны з іншых прастор працы)." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 +#: data/org.gnome.mutter.gschema.xml.in:30 msgid "Enable edge tiling when dropping windows on screen edges" -msgstr "" +msgstr "Уключыць кафляванне пры перацягванні вокнаў на бераг экрана" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 +#: data/org.gnome.mutter.gschema.xml.in:31 msgid "" "If enabled, dropping windows on vertical screen edges maximizes them " "vertically and resizes them horizontally to cover half of the available " "area. Dropping windows on the top screen edge maximizes them completely." msgstr "" +"Калі ўключана, перацягванне вокнаў на вертыкальныя берагі экрана " +"максімалізуе іх па вертыкалі і змяняе памер па гарызанталі, каб тыя " +"закрывалі палову наяўнага месца. Перацягванне вокнаў на верхні бераг экрана " +"максімалізуе іх ва ўсіх накірунках." + +#: data/org.gnome.mutter.gschema.xml.in:40 +msgid "Workspaces are managed dynamically" +msgstr "Дынамічнае кіраванне прасторамі працы" + +#: data/org.gnome.mutter.gschema.xml.in:41 +msgid "" +"Determines whether workspaces are managed dynamically or whether there’s a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." +msgstr "" +"Вызначае, ці трэба дынамічна кіраваць колькасцю прастор працы, або трэба " +"проста ўжыць іх нязменную колькасць (канкрэтнае значэнне вызначаецца ключом " +"num-workspaces у org.gnome.desktop.wm.preferences)." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 +#: data/org.gnome.mutter.gschema.xml.in:50 msgid "Workspaces only on primary" msgstr "Працоўныя прасторы толькі на галоўным экране" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 +#: data/org.gnome.mutter.gschema.xml.in:51 msgid "" "Determines whether workspace switching should happen for windows on all " "monitors or only for windows on the primary monitor." @@ -450,1154 +316,1132 @@ msgstr "" "Вызначае, ці трэба пераменьваць прасторы працы для вокнаў на ўсіх маніторах " "або толькі на першым." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 +#: data/org.gnome.mutter.gschema.xml.in:59 msgid "No tab popup" msgstr "Няма выплыўнога акенца" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 +#: data/org.gnome.mutter.gschema.xml.in:60 msgid "" "Determines whether the use of popup and highlight frame should be disabled " "for window cycling." msgstr "" +"Вызначае, ці трэба выключыць выплыўную рамку з падсветкай для пракручвання " +"спіса вокнаў." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Затрымліваць змяненне фокусу да спынення паказальніка мышы" + +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" +"Калі ўключана, а рэжым фокусу ці \"sloppy\", ці \"mouse\", тады фокус не " +"будзе пераключацца паміж вокнамі імгненна, але толькі пасля спынення " +"паказальніка мышы." + +#: data/org.gnome.mutter.gschema.xml.in:79 msgid "Draggable border width" msgstr "Шырыня аблямоўкі для перацягвання" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 +#: data/org.gnome.mutter.gschema.xml.in:80 msgid "" -"The amount of total draggable borders. If the theme's visible borders are " +"The amount of total draggable borders. If the theme’s visible borders are " "not enough, invisible borders will be added to meet this value." msgstr "" +"Памер аблямоўкі для перацягвання. Калі бачнай аблямоўкі матыву недастаткова, " +"будуць дададзена нябачная рамка, каб задаволіць гэту настройку." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "" +"Аўтаматычна максімалізаваць вокны, якія расцягнутыя амаль на ўвесь экран" + +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" +"Калі ўключана, новыя вокны з памерам, блізкім да памераў манітора, будуць " +"аўтаматычна максімалізавацца." + +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Змяшчаць новыя вокны ў цэнтры" + +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" +"Калі ўключана, новыя вокны будуць заўсёды з'яўляцца пасярэдзіне дзейнага " +"манітора." + +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Уключыць эксперыментальныя функцыі" + +#: data/org.gnome.mutter.gschema.xml.in:108 +msgid "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart." +msgstr "" +"Каб уключыць эксперыментальныя функцыі, дадайце адпаведнае ключавое слова ў " +"гэты ліст. Некаторыя функцыі могуць патрабаваць перазапуску кампазітара. " +"Эксперыментальны функцыі могуць быць недаступныя. Не чакайце, што функцыі, " +"дададзеныя ў гэты спіс, будуць працаваць і далей. Магчымыя ключавыя словы: • " +"\"scale-monitor-framebuffer\" - прымушае mutter прадвызначана размяшчаць " +"лагічныя маніторы ў лагічнай прасторы каардынат пікселаў, пры гэтым " +"маштабаваць кадравы буфер, а не змесціва акна, для падтрымкі HiDPI " +"манітораў. Не патрабуе перазапуску." + +#: data/org.gnome.mutter.gschema.xml.in:141 msgid "Select window from tab popup" msgstr "Выбраць акно з выплыўнога акенца" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 +#: data/org.gnome.mutter.gschema.xml.in:146 msgid "Cancel tab popup" msgstr "Закрыць выплыўное акенца" -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "Правілы выкарыстання: %s\n" +#: data/org.gnome.mutter.gschema.xml.in:151 +msgid "Switch monitor configurations" +msgstr "Пераключыць канфігурацыі манітора" -#: ../src/ui/frames.c:1157 -msgid "Close Window" -msgstr "Закрыць акно" +#: data/org.gnome.mutter.gschema.xml.in:156 +msgid "Rotates the built-in monitor configuration" +msgstr "Паварочвае убудаваны манітор" -#: ../src/ui/frames.c:1160 -msgid "Window Menu" -msgstr "Меню акна" +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Перайсці ў віртуальны тэрмінал 1" -#: ../src/ui/frames.c:1163 -msgid "Minimize Window" -msgstr "Мінімалізаваць акно" +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Перайсці ў віртуальны тэрмінал 2" -#: ../src/ui/frames.c:1166 -msgid "Maximize Window" -msgstr "Максімалізаваць акно" +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Перайсці ў віртуальны тэрмінал 3" -#: ../src/ui/frames.c:1169 -msgid "Restore Window" -msgstr "Аднавіць былы памер акна" +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Перайсці ў віртуальны тэрмінал 4" -#: ../src/ui/frames.c:1172 -msgid "Roll Up Window" -msgstr "Скруціць акно ў загаловак" - -#: ../src/ui/frames.c:1175 -msgid "Unroll Window" -msgstr "Раскруціць акно з загалоўка" - -#: ../src/ui/frames.c:1178 -msgid "Keep Window On Top" -msgstr "Трымаць акно над астатнімі" - -#: ../src/ui/frames.c:1181 -msgid "Remove Window From Top" -msgstr "Прыбраць акно з верху" - -#: ../src/ui/frames.c:1184 -msgid "Always On Visible Workspace" -msgstr "Заўсёды на бачнай прасторы працы" - -#: ../src/ui/frames.c:1187 -msgid "Put Window On Only One Workspace" -msgstr "Змясціць акно на адзінай прасторы працы" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "_Мінімалізаваць" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "Ма_ксімалізаваць" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "Скасаваць ма_ксімалізацыю" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "_Скруціць акно ў загаловак" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "Рас_круціць акно з загалоўка" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "_Перамясціць акно" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "_Змяніць памер акна" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "Перамясціць загаловак акна па _экране" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "Заўсёды _наверсе" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "Заўсёды на _бачнай прасторы працы" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "_Толькі на гэтай прасторы працы" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "Перамясціць на прастору працы з_лева" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "Перамясціць на прастору працы с_права" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "Перамясціць на прастору працы з_верху" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "Перамясціць на прастору працы з_нізу" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "_Закрыць акно" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "Прастора працы %d%n" +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Перайсці ў віртуальны тэрмінал 5" -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "Прастора працы 1_0" +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Перайсці ў віртуальны тэрмінал 6" -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "Прастора працы %s%d" +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Перайсці ў віртуальны тэрмінал 7" -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "П_ерамясціць на іншую прастору працы" +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Перайсці ў віртуальны тэрмінал 8" -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Перайсці ў віртуальны тэрмінал 9" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Перайсці ў віртуальны тэрмінал 10" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Перайсці ў віртуальны тэрмінал 11" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Перайсці ў віртуальны тэрмінал 12" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "Уключыць назад клавіятурныя скароты" -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow grabs with Xwayland" +msgstr "Дазволіць захоп клавіятуры з Xwayland" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 +msgid "" +"Allow keyboard grabs issued by X11 applications running in Xwayland to be " +"taken into account. For a X11 grab to be taken into account under Wayland, " +"the client must also either send a specific X11 ClientMessage to the root " +"window or be among the applications white-listed in key “xwayland-grab-" +"access-rules”." +msgstr "" +"Дазволіць прымаць у разлік захоп клавіятуры прыстасаваннямі X11, якія " +"працуюць у Xwayland. Каб гэта працавала, карыстальнік павінны таксама " +"даслаць адпаведнае X11 паведамленне ClientMessage каранёваму акну, ці быць " +"сярод дазволеных дастасаванняў у \"xwayland-grab-access-rules\"." + +#: data/org.gnome.mutter.wayland.gschema.xml.in:77 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "Xwayland дастасаванні, якім дазволена захапляць клавіятуру" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:78 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "" +"Спіс назваў ці класаў рэсурсаў вокнаў X11, якім дазволена ці не дазволена " +"захопліваць клавіятуру пад Xwayland. Назву і клас рэсурса акна X11 можна " +"атрымаць з дапамогай каманды \"xprop WM_CLASS\". Значэнні могуць змяшчаць " +"шаблоны \"*\" і \"?\". Значэнні, якія пачынаюцца з \"!\", азначаюць " +"забарону, што мае перавагу перад дазволам і адклікае дастасаванні з " +"прадвызначанага сістэмнага спіса. Апошні змяшчае наступныя дастасаванні: " +"\"@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@\". Карыстальнікі могуць спыніць " +"дзейнічаючы захоп з дапамогай клавіятурнага скароту, азначанага ключом " +"\"restore-shortcuts\"." + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. #. -#: ../src/ui/resizepopup.c:113 +#: src/backends/meta-input-settings.c:2325 #, c-format -msgid "%d x %d" -msgstr "%d x %d" +msgid "Mode Switch (Group %d)" +msgstr "Пераключыць рэжым (група %d)" -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "верхнюю" +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2348 +msgid "Switch monitor" +msgstr "Пераключыць манітор" + +#: src/backends/meta-input-settings.c:2350 +msgid "Show on-screen help" +msgstr "Паказаць экранную даведку" -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "ніжнюю" +#: src/backends/meta-monitor-manager.c:907 +msgid "Built-in display" +msgstr "Убудаваны дысплей" -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "левую" +#: src/backends/meta-monitor-manager.c:930 +msgid "Unknown" +msgstr "Невядомы" -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "правую" +#: src/backends/meta-monitor-manager.c:932 +msgid "Unknown Display" +msgstr "Невядомы дысплей" -#: ../src/ui/theme.c:286 +#. TRANSLATORS: this is a monitor vendor name, followed by a +#. * size in inches, like 'Dell 15"' +#. +#: src/backends/meta-monitor-manager.c:940 #, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "апісанне геаметрыі рамкі акна не вызначае %s граніцу" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme.c:305 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:481 #, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" +msgid "" +"Another compositing manager is already running on screen %i on display “%s”." msgstr "" -"апісанне геаметрыі рамкі акна не вызначае %s граніцу для аблямоўкі \"%s\"" +"Іншы кампазітны кіраўнік вокнаў ужо абслугоўвае экран %i дысплея \"%s\"." -#: ../src/ui/theme.c:342 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "Прапорцыі кнопкі %g не маюць сэнсу" +#: src/core/bell.c:254 +msgid "Bell event" +msgstr "Падзея з сігналам" -#: ../src/ui/theme.c:354 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "Апісанне геаметрыі рамкі акна не вызначае памер кнопак" +#: src/core/main.c:191 +msgid "Disable connection to session manager" +msgstr "Выключыць злучэнне з кіраўніком сеансаў" -#: ../src/ui/theme.c:1067 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "Градыент мусіць мець прынамсі два колеры" +#: src/core/main.c:197 +msgid "Replace the running window manager" +msgstr "Замяніць дзейнага кіраўніка вокнаў" + +#: src/core/main.c:203 +msgid "Specify session management ID" +msgstr "Вызначыць ідэнтыфікатар для кіравання сеансам" -#: ../src/ui/theme.c:1219 +#: src/core/main.c:208 +msgid "X Display to use" +msgstr "Патрэбны X-дысплей" + +#: src/core/main.c:214 +msgid "Initialize session from savefile" +msgstr "Ініцыяваць сеанс з файла" + +#: src/core/main.c:220 +msgid "Make X calls synchronous" +msgstr "Сінхронна выконваць выклікі X-сістэмы" + +#: src/core/main.c:227 +msgid "Run as a wayland compositor" +msgstr "Запусціць у якасці кампазітара wayland" + +#: src/core/main.c:233 +msgid "Run as a nested compositor" +msgstr "Запусціць у якасці ўложанага кампазітара" + +#: src/core/main.c:239 +msgid "Run wayland compositor without starting Xwayland" +msgstr "Запусціць наборшчык wayland без Xwayland" + +#: src/core/main.c:247 +msgid "Run as a full display server, rather than nested" +msgstr "Запусціць у якасці паўнавартаснага сервера дысплея, я не як уложаны " + +#: src/core/main.c:253 +msgid "Run with X11 backend" +msgstr "Запусціць з драйверам X11" + +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:148 #, c-format +msgid "“%s” is not responding." +msgstr "\"%s\" не адказвае на запыты." + +#: src/core/meta-close-dialog-default.c:150 +msgid "Application is not responding." +msgstr "Праграма не адказвае на запыты." + +#: src/core/meta-close-dialog-default.c:155 msgid "" -"GTK custom color specification must have color name and fallback in " -"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." msgstr "" -"Уласная спецыфікацыя колеру GTK мусіць змяшчаць назвы асноўнага і запаснога колераў " -"у дужках, напрыклад, gtk:custom(foo,bar). Не ўдалося разабраць \"%s\"" +"Вы можаце альбо крыху пачакаць адказу, альбо змусіць праграму да выхаду." + +#: src/core/meta-close-dialog-default.c:162 +msgid "_Force Quit" +msgstr "_Змусіць да выхаду" + +#: src/core/meta-close-dialog-default.c:162 +msgid "_Wait" +msgstr "_Пачакаць" -#: ../src/ui/theme.c:1235 +#: src/core/mutter.c:39 #, c-format msgid "" -"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" -"_ are valid" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" msgstr "" -"Хібны знак \"%c\" у параметры color_name спецыфікацыі gtk:custom, дазволеныя толькі A-Za-z0-9-" -"_" +"mutter %s\n" +"Аўтарскія правы (C) 2001-%d Havoc Pennington, Red Hat, Inc. і інш.\n" +"Гэта свабоднае апраграмаванне. Умовы яго капіравання глядзіце ў выточным " +"кодзе праграмы.\n" +"Аўтары не даюць ніякіх гарантый, у тым ліку камерцыйнай вартасці праграмы і " +"наогул яе карысці.\n" + +#: src/core/mutter.c:53 +msgid "Print version" +msgstr "Вывесці нумар версіі праграмы" + +#: src/core/mutter.c:59 +msgid "Mutter plugin to use" +msgstr "Патрэбны плугін Mutter" -#: ../src/ui/theme.c:1249 +#: src/core/prefs.c:1915 #, c-format -msgid "" -"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " -"fit the format" +msgid "Workspace %d" +msgstr "Прастора працы %d" + +#: src/core/util.c:120 +msgid "Mutter was compiled without support for verbose mode\n" msgstr "" -"Фармат gtk:custom: \"gtk:custom(назва_колеру,запасны_колер)\"; \"%s\" не адпавядае " -"фармату" +"Праграма \"Mutter\" была скампіляваная без падтрымкі падрабязнага " +"пратакаліравання\n" -#: ../src/ui/theme.c:1294 +#: src/wayland/meta-wayland-tablet-pad.c:567 #, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"Спецыфікацыя колеру GTK мусіць мець стан у квадратных дужках, напрыклад, gtk:" -"fg[NORMAL], дзе NORMAL - гэта стан. Не ўдалося разабраць \"%s\"" +msgid "Mode Switch: Mode %d" +msgstr "Пераключыць рэжым: %d" -#: ../src/ui/theme.c:1308 +#: src/x11/meta-x11-display.c:666 #, c-format msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." msgstr "" -"Спецыфікацыя колеру GTK мусіць мець закрытыя квадратныя дужкі пасля стану, " -"напрыклад, gtk:fg[NORMAL], дзе NORMAL - гэта стан. Не ўдалося разабраць \"%s" -"\"" +"Дысплеі \"%s\" ужо мае аконнага кіраўніка. Каб замяніць яго новым, дадайце " +"опцыю --replace." -#: ../src/ui/theme.c:1319 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "Незразумелы стан \"%s\" у спецыфікацыі колеру" +#: src/x11/meta-x11-display.c:1010 +msgid "Failed to initialize GDK\n" +msgstr "Не ўдалося ініцыяваць GDK\n" -#: ../src/ui/theme.c:1332 +#: src/x11/meta-x11-display.c:1034 #, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "Незразумелы складнік колеру \"%s\" у спецыфікацыі колеру" +msgid "Failed to open X Window System display “%s”\n" +msgstr "Не ўдалося адкрыць дысплей аконнай сістэмы X \"%s\"\n" -#: ../src/ui/theme.c:1361 +#: src/x11/meta-x11-display.c:1117 #, c-format +msgid "Screen %d on display “%s” is invalid\n" +msgstr "Экран %d на дысплеі \"%s\" хібны\n" + +#: src/x11/session.c:1819 msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." msgstr "" -"Фармат змяшанага колеру - \"blend/bg_color/fg_color/alpha\". \"%s\" не " -"адпавядае фармату." +"Гэтыя вокны не падтрымліваюць функцыі захавання дзейнага ладу працы, і таму " +"іх прыйдзецца запусціць уручную пасля наступнага ўваходу ў сістэму." -#: ../src/ui/theme.c:1372 +#: src/x11/window-props.c:565 #, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "Не ўдалося разабраць значэнне альфа \"%s\" ў змяшаным колеры" +msgid "%s (on %s)" +msgstr "%s (на %s)" -#: ../src/ui/theme.c:1382 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "" -"Значэнне альфа \"%s\" у змяшаным колеры не ўваходзіць у дыяпазон ад 0.0 да " -"1.0" +#~ msgid "Move window one workspace to the left" +#~ msgstr "Перамясціць акно ў прастору злева ад дзейнай" -#: ../src/ui/theme.c:1429 -#, c-format -msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "" -"Фармат ценю - \"shade/base_color/factor\". \"%s\" не адпавядае фармату." +#~ msgid "Move window one workspace to the right" +#~ msgstr "Перамясціць акно ў прастору справа ад дзейнай" -#: ../src/ui/theme.c:1440 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "Не ўдалося разабраць каэфіцыент ценю \"%s\" у зацененым колеры" +#~ msgid "Move to workspace left" +#~ msgstr "Перамясціць на прастору працы злева" -#: ../src/ui/theme.c:1450 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "Каэфіцыент ценю \"%s\" у зацененым колеры адмоўны" +#~ msgid "Move to workspace right" +#~ msgstr "Перамясціць на прастору працы справа" -#: ../src/ui/theme.c:1479 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Не ўдалося разабраць колер \"%s\"" +#~ msgid "Toggle shaded state" +#~ msgstr "Перамяніць скручанасць акна ў загаловак" -#: ../src/ui/theme.c:1790 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "Каардынатны выраз змяшчае забаронены знак \"%s\"" +#~ msgid "background texture could not be created from file" +#~ msgstr "не ўдалося стварыць фонавую тэкстуру з файла" -#: ../src/ui/theme.c:1817 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "Каардынатны выраз змяшчае незразумелы лік з нефіксаванай коскай \"%s\"" +#~ msgid "Unknown window information request: %d" +#~ msgstr "Невядомы запыт інфармацыі пра акно: %d" -#: ../src/ui/theme.c:1831 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "Каардынатны выраз змяшчае незразумелы цэлы лік \"%s\"" +#~ msgid "Missing %s extension required for compositing" +#~ msgstr "" +#~ "Адсутнічае пашырэнне \"%s\", патрэбнае для ажыццяўлення кампазітнага " +#~ "вываду" -#: ../src/ui/theme.c:1953 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "" -"Каардынатны выраз змяшчае невядомы аператар у пачатку гэтага тэксту: \"%s\"" +#~ msgid "" +#~ "Some other program is already using the key %s with modifiers %x as a " +#~ "binding\n" +#~ msgstr "" +#~ "Нейкая іншая праграма ўжо выкарыстоўвае як скарот клавішу %s з " +#~ "мадыфікатарамі %x\n" -#: ../src/ui/theme.c:2010 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "Каардынатны выраз пусты ці незразумелы" +#~ msgid "\"%s\" is not a valid accelerator\n" +#~ msgstr "\"%s\" - гэта хібны клавіятурны скарот\n" -#: ../src/ui/theme.c:2121 ../src/ui/theme.c:2131 ../src/ui/theme.c:2165 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "Каардынатны выраз вымагае дзялення на нуль" +#~ msgid "Failed to scan themes directory: %s\n" +#~ msgstr "Не ўдалося праглядзець каталог з матывамі аздаблення: %s\n" -#: ../src/ui/theme.c:2173 -#, c-format -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "" -"Каардынатны выраз спрабуе ўжыць аператар дзялення па модулі для ліку з " -"нефіксаванай коскай" +#~ msgid "" +#~ "Could not find a theme! Be sure %s exists and contains the usual themes.\n" +#~ msgstr "" +#~ "Не ўдалося адшукаць матыў аздаблення! Праверце, каб каталог %s існаваў і " +#~ "змяшчаў звычайныя матывы.\n" -#: ../src/ui/theme.c:2229 -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "" -"У каардынатным выразе ўжыты аператар \"%s\" там, дзе мусіў быць аперанд" +#~ msgid "" +#~ "Workarounds for broken applications disabled. Some applications may not " +#~ "behave properly.\n" +#~ msgstr "" +#~ "Асаблівыя паводзіны для некаторых хібных праграм выключаныя. Некаторыя " +#~ "праграмы могуць перастаць працаваць, як мае быць.\n" -#: ../src/ui/theme.c:2238 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "У каардынатным выразе ўжыты аперанд там, дзе мусіў быць аператар" +#~ msgid "Could not parse font description \"%s\" from GSettings key %s\n" +#~ msgstr "Не ўдалося разабраць азначэнне шрыфту \"%s\" з GSettings-ключа %s\n" -#: ../src/ui/theme.c:2246 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "Каардынатны выраз заканчваецца аператарам, а не аперандам" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" +#~ msgstr "" +#~ "Значэнне \"%s\", знойдзенае ў базе канфігурацыйных даных, не азначае " +#~ "мадыфікатар мышынай кнопкі\n" -#: ../src/ui/theme.c:2256 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" -"У каардынатным выразе за аператарам \"%c\" ідзе аператар \"%c\", але паміж " -"імі няма аперанда" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for " +#~ "keybinding \"%s\"\n" +#~ msgstr "" +#~ "Значэнне \"%s\", знойдзенае ў базе канфігурацыйных даных, не азначае " +#~ "клавіятурны скарот \"%s\"\n" -#: ../src/ui/theme.c:2407 ../src/ui/theme.c:2452 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "У каардынатным выразе невядомая зменная альбо канстанта \"%s\"" +#~ msgid "" +#~ "Could not acquire window manager selection on screen %d display \"%s\"\n" +#~ msgstr "" +#~ "Не ўдалося пераняць вылучэнне кіраўніка вокнаў для экрана %d дысплея \"%s" +#~ "\"\n" + +#~ msgid "Screen %d on display \"%s\" already has a window manager\n" +#~ msgstr "Экран %d на дысплеі \"%s\" ужо мае кіраўніка вокнаў\n" -#: ../src/ui/theme.c:2506 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "Прылада для разбору каардынатных выразаў перапоўніла свой буфер." +#~ msgid "Could not release screen %d on display \"%s\"\n" +#~ msgstr "Не ўдалося вызваліць экран %d на дысплеі \"%s\"\n" -#: ../src/ui/theme.c:2535 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "" -"У каардынатным выразе ўжытыя дужкі, якія закрываюцца, але няма тых, якія б " -"адкрываліся" +#~ msgid "Could not create directory '%s': %s\n" +#~ msgstr "Не ўдалося стварыць каталог \"%s\": %s\n" -#: ../src/ui/theme.c:2599 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "" -"У каардынатным выразе ўжытыя дужкі, якія адкрываюцца, але няма тых, якія б " -"закрываліся" +#~ msgid "Could not open session file '%s' for writing: %s\n" +#~ msgstr "Не ўдалося адкрыць файл сеанса \"%s\" для запісу: %s\n" -#: ../src/ui/theme.c:2610 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "У каардынатным выразе няма ні аператараў, ні аперандаў" +#~ msgid "Error writing session file '%s': %s\n" +#~ msgstr "Не ўдалося запісаць файл сеанса \"%s\": %s\n" -#: ../src/ui/theme.c:2822 ../src/ui/theme.c:2842 ../src/ui/theme.c:2862 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "Матыў аздаблення змяшчае выраз, які стаў прычынай памылкі: %s\n" +#~ msgid "Error closing session file '%s': %s\n" +#~ msgstr "Не ўдалося закрыць файл сеанса \"%s\": %s\n" -#: ../src/ui/theme.c:4533 -#, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" -"Для гэтага стылю рамкі трэба вызначыць <button function=\"%s\" state=\"%s\" " -"draw_ops=\"whatever\"/>" +#~ msgid "Failed to parse saved session file: %s\n" +#~ msgstr "Не ўдалося разабраць захаваны файл сеанса: %s\n" -#: ../src/ui/theme.c:5066 ../src/ui/theme.c:5091 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" -"Няма <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"што-небудзь\"/>" +#~ msgid "<mutter_session> attribute seen but we already have the session ID" +#~ msgstr "" +#~ "сустрэты атрыбут <mutter_session>, але мы ўжо маем ідэнтыфікатар сеанса" -#: ../src/ui/theme.c:5139 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Не ўдалося загрузіць матыў аздаблення \"%s\": %s\n" +#~ msgid "Unknown attribute %s on <%s> element" +#~ msgstr "Элемент <%2$s> мае невядомы атрыбут %1$s" -#: ../src/ui/theme.c:5275 ../src/ui/theme.c:5282 ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 ../src/ui/theme.c:5303 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "Для матыву аздаблення \"%2$s\" не прызначана <%1$s>" +#~ msgid "nested <window> tag" +#~ msgstr "укладзены тэг <window>" -#: ../src/ui/theme.c:5311 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" -"Стыль рамкі не вызначаны для вокнаў тыпу \"%s\" для матыву аздаблення \"%s\". Дадайце <window " -"type=\"%s\" style_set=\"штосьці\"/>." +#~ msgid "Unknown element %s" +#~ msgstr "Невядомы элемент %s" -#: ../src/ui/theme.c:5709 ../src/ui/theme.c:5771 ../src/ui/theme.c:5834 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" -"Назвы канстантаў, вызначаных карыстальнікам, мусяць пачынацца з вялікай літары. \"%s\" не адпавядае гэтаму патрабаванню." +#~ msgid "Failed to open debug log: %s\n" +#~ msgstr "Не ўдалося адкрыць адладачны журнал: %s\n" -#: ../src/ui/theme.c:5717 ../src/ui/theme.c:5779 ../src/ui/theme.c:5842 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "Канстанта \"%s\" ужо азначана" +#~ msgid "Failed to fdopen() log file %s: %s\n" +#~ msgstr "Не ўдалося выканаць fdopen() для журнальнага файла %s: %s\n" -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. -#. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "Элемент <%2$s> не мае атрыбута \"%1$s\"" +#~ msgid "Opened log file %s\n" +#~ msgstr "Журнальны файл %s адкрыты\n" -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Радок %d, знак %d: %s" +#~ msgid "Window manager: " +#~ msgstr "Кіраўнік вокнаў: " -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "Атрыбут \"%s\" двойчы азначаны для элемента <%s>" +#~ msgid "Bug in window manager: " +#~ msgstr "Хіба ў кіраўніку вокнаў: " -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "У гэтым кантэксце атрыбут \"%s\" элемента <%s> з'яўляецца хібным" +#~ msgid "Window manager warning: " +#~ msgstr "Перасцярога ад кіраўніка вокнаў: " -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "Не ўдалося інтэрпрэтаваць \"%s\" як цэлы лік" +#~ msgid "Window manager error: " +#~ msgstr "Памылка кіраўніка вокнаў: " -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "Спатканыя незразумелыя знакі \"%s\" у канцы ланцужка \"%s\"" +#~ msgid "" +#~ "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " +#~ "window as specified in the ICCCM.\n" +#~ msgstr "" +#~ "Акно %s прызначыла SM_CLIENT_ID для сябе, а не для акна WM_CLIENT_LEADER, " +#~ "як таго вымагае спецыфікацыя ICCCM.\n" -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "Цэлы лік %ld мусіць быць дадатным" +#~ msgid "" +#~ "Window %s sets an MWM hint indicating it isn't resizable, but sets min " +#~ "size %d x %d and max size %d x %d; this doesn't make much sense.\n" +#~ msgstr "" +#~ "Акно %s уключыла для сябе MWM-уласцівасць, якая азначае незмяняльнасць " +#~ "памеру, але разам з гэтым прызначыла для сябе мінімальны памер %d x %d і " +#~ "максімальны памер %d x %d. Такія паводзіны не маюць сэнсу.\n" -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "Цэлы лік %ld надта вялікі, максімальна дазволенае значэнне роўнае %d" +#~ msgid "Application set a bogus _NET_WM_PID %lu\n" +#~ msgstr "Праграма прызначыла памылковае значэнне _NET_WM_PID %lu\n" -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "" -"Не ўдалося разабраць значэнне \"%s\" як дробны лік з нефіксаванай коскай" +#~ msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +#~ msgstr "Для %2$s вызначана хібнае акно WM_TRANSIENT_FOR 0x%1$lx.\n" -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "" -"Булева зменная можа мець значэнне \"true\" або \"false\", але не \"%s\"" +#~ msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" +#~ msgstr "WM_TRANSIENT_FOR акно 0x%lx для %s стварыла б цыкл.\n" -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "Вугал можа мець значэнне ад 0.0 да 360.0, а не %g\n" +#~ msgid "" +#~ "Window 0x%lx has property %s\n" +#~ "that was expected to have type %s format %d\n" +#~ "and actually has type %s format %d n_items %d.\n" +#~ "This is most likely an application bug, not a window manager bug.\n" +#~ "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +#~ msgstr "" +#~ "Акно 0x%lx мае ўласцівасць %s,\n" +#~ "якая мусіла мець тып %s, фармат %d,\n" +#~ "а ў сапраўднасці мае тып %s, фармат %d, n_items %d.\n" +#~ "Відаць, гэта хіба самой праграмы, а не кіраўніка вокнаў.\n" +#~ "Акно мае загаловак=\"%s\", клас=\"%s\", назву=\"%s\"\n" -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" -"Вартасць альфа мусіць быць ад 0.0 (нябачная) да 1.0 (поўнасцю непразрыстая), " -"а пададзена %g\n" +#~ msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +#~ msgstr "Уласцівасць %s акна 0x%lx змяшчала хібныя для UTF-8 знакі\n" -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"Хібны маштаб загалоўка \"%s\" (магчымыя значэнні: xx-small, x-small, small, " -"medium, large, x-large, xx-large)\n" +#~ msgid "" +#~ "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the " +#~ "list\n" +#~ msgstr "" +#~ "Уласцівасць %s акна 0x%lx змяшчала хібныя для UTF-8 знакі ў складніку %d " +#~ "спіса\n" -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "Назва <%s> \"%s\" ужытая другі раз" +#~ msgid "Mi_nimize" +#~ msgstr "_Мінімалізаваць" -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "Продак <%s> \"%s\" не азначаны" +#~ msgid "Ma_ximize" +#~ msgstr "Ма_ксімалізаваць" -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "Памеры віджэта <%s> \"%s\" не азначаны" +#~ msgid "Unma_ximize" +#~ msgstr "Скасаваць ма_ксімалізацыю" -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "<%s> мусіць вызначыць або памеры віджэта, або продка, які мае памеры" +#~ msgid "Roll _Up" +#~ msgstr "_Скруціць акно ў загаловак" -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "Трэба вызначыць фон для значэння альфа, каб яно мела сэнс" +#~ msgid "_Unroll" +#~ msgstr "Рас_круціць акно з загалоўка" -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Невядомы тып \"%s\" для элемента <%s>" +#~ msgid "_Move" +#~ msgstr "_Перамясціць акно" -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "Невядомае значэнне style_set \"%s\" для элемента <%s>" +#~ msgid "_Resize" +#~ msgstr "_Змяніць памер акна" -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "Тыпу акна \"%s\" ужо прызначаны збор стыляў" - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "Элемент <%s> забаронены ніжэй за <%s>" +#~ msgid "Move Titlebar On_screen" +#~ msgstr "Перамясціць загаловак акна па _экране" -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" -msgstr "" -"Немагчыма вызначыць для кнопак адначасова \"button_width\"/\"button_height\" " -"і \"aspect_ratio\"" +#~ msgid "Always on _Top" +#~ msgstr "Заўсёды _наверсе" -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "Адлегласць \"%s\" невядомая" +#~ msgid "_Always on Visible Workspace" +#~ msgstr "Заўсёды на _бачнай прасторы працы" -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "Каэфіцыент прапарцыянальнасці \"%s\" невядомы" +#~ msgid "_Only on This Workspace" +#~ msgstr "_Толькі на гэтай прасторы працы" -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "Аблямоўка \"%s\" невядомая" +#~ msgid "Move to Workspace _Left" +#~ msgstr "Перамясціць на прастору працы з_лева" -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "Няма атрыбутаў \"start_angle\" ці \"from\" для элемента <%s>" +#~ msgid "Move to Workspace R_ight" +#~ msgstr "Перамясціць на прастору працы с_права" -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "Няма атрыбутаў \"extent_angle\" ці \"to\" для элемента <%s>" +#~ msgid "Move to Workspace _Up" +#~ msgstr "Перамясціць на прастору працы з_верху" -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "Незразумелае значэнне \"%s\" для тыпу градыента" +#~ msgid "Move to Workspace _Down" +#~ msgstr "Перамясціць на прастору працы з_нізу" -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "Незразумелы тып запаўнення \"%s\" для элемента <%s>" +#~ msgid "_Close" +#~ msgstr "_Закрыць акно" -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "Незразумелы стан \"%s\" для элемента <%s>" +#~ msgid "Workspace %d%n" +#~ msgstr "Прастора працы %d%n" -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "Незразумелы цень \"%s\" для элемента <%s>" +#~ msgid "Workspace 1_0" +#~ msgstr "Прастора працы 1_0" -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "Незразумелая стрэлка \"%s\" для элемента <%s>" +#~ msgid "Workspace %s%d" +#~ msgstr "Прастора працы %s%d" -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "<draw_ops> з назвай \"%s\" не азначаны" +#~ msgid "Move to Another _Workspace" +#~ msgstr "П_ерамясціць на іншую прастору працы" -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "Уключэнне тут draw_ops \"%s\" створыць цыклічную адсылку" +#~ msgid "Shift" +#~ msgstr "Shift" -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Невядомая пазіцыя \"%s\" для кавалка рамкі" +#~ msgid "Ctrl" +#~ msgstr "Ctrl" -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "У стылі рамкі ўжо ёсць кавалак у пазіцыі %s" +#~ msgid "Alt" +#~ msgstr "Alt" -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "<draw_ops> з назвай \"%s\" не азначаны" +#~ msgid "Meta" +#~ msgstr "Meta" -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Невядомая функцыя \"%s\" для кнопкі" +#~ msgid "Super" +#~ msgstr "Super" -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "Функцыя кнопкі \"%s\" не існуе ў гэтай версіі (%d, патрэбна %d)" +#~ msgid "Hyper" +#~ msgstr "Hyper" -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Невядомы стан \"%s\" для кнопкі" +#~ msgid "Mod2" +#~ msgstr "Mod2" -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "У стылі рамкі ўжо ёсць кнопка для функцыі %s, стану %s" +#~ msgid "Mod3" +#~ msgstr "Mod3" -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "\"%s\" - няправільнае значэнне для атрыбута \"focus\"" +#~ msgid "Mod4" +#~ msgstr "Mod4" -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "\"%s\" - няправільнае значэнне для атрыбута \"state\"" +#~ msgid "Mod5" +#~ msgstr "Mod5" -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "Стыль \"%s\" не азначаны" +#~ msgid "%d x %d" +#~ msgstr "%d x %d" -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "\"%s\" - няправільнае значэнне для атрыбута \"resize\"" +#~ msgid "top" +#~ msgstr "верхнюю" -#: ../src/ui/theme-parser.c:3147 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" -"Для максімалізаванага і зацененага стану нельга мець атрыбут \"resize\" у " -"элеменце <%s>" +#~ msgid "bottom" +#~ msgstr "ніжнюю" -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "" -"Для максімалізаванага стану нельга мець атрыбут \"resize\" у элеменце <%s>" +#~ msgid "left" +#~ msgstr "левую" -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "Стыль для state %s, resize %s, focus %s ужо вызначаны" +#~ msgid "right" +#~ msgstr "правую" -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "Стыль для state %s, focus %s ужо вызначаны" +#~ msgid "frame geometry does not specify \"%s\" dimension" +#~ msgstr "апісанне геаметрыі рамкі акна не вызначае %s граніцу" -#: ../src/ui/theme-parser.c:3294 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Немагчыма двойчы ўжыць draw_ops для элемента <piece> (матыў аздаблення " -"вызначыў атрыбут draw_ops, а таксама элемент <draw_ops>, або вызначыў два " -"элементы)" +#~ msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" +#~ msgstr "" +#~ "апісанне геаметрыі рамкі акна не вызначае %s граніцу для аблямоўкі \"%s\"" -#: ../src/ui/theme-parser.c:3332 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Немагчыма двойчы ўжыць draw_ops для элемента <button> (матыў аздаблення " -"вызначыў атрыбут draw_ops, а таксама элемент <draw_ops>, або вызначыў два " -"элементы)" +#~ msgid "Button aspect ratio %g is not reasonable" +#~ msgstr "Прапорцыі кнопкі %g не маюць сэнсу" -#: ../src/ui/theme-parser.c:3370 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Немагчыма двойчы ўжыць draw_ops для элемента <menu_icon> (матыў аздаблення " -"вызначыў атрыбут draw_ops, а таксама элемент <draw_ops>, або вызначыў два " -"элементы)" +#~ msgid "Frame geometry does not specify size of buttons" +#~ msgstr "Апісанне геаметрыі рамкі акна не вызначае памер кнопак" -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "Хібная спецыфікацыя версіі \"%s\"" +#~ msgid "Gradients should have at least two colors" +#~ msgstr "Градыент мусіць мець прынамсі два колеры" -#: ../src/ui/theme-parser.c:3507 -msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" -msgstr "" -"Атрыбут \"version\" не можа быць ужыты ў metacity-theme-1.xml ці metacity-" -"theme-2.xml" +#~ msgid "" +#~ "GTK custom color specification must have color name and fallback in " +#~ "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" +#~ msgstr "" +#~ "Уласная спецыфікацыя колеру GTK мусіць змяшчаць назвы асноўнага і " +#~ "запаснога колераў у дужках, напрыклад, gtk:custom(foo,bar). Не ўдалося " +#~ "разабраць \"%s\"" -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "Матыў аздаблення патрабуе версію %s, але апошняя версія матываў, якая падтрымліваецца, - гэта %d.%d" +#~ msgid "" +#~ "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-" +#~ "z0-9-_ are valid" +#~ msgstr "" +#~ "Хібны знак \"%c\" у параметры color_name спецыфікацыі gtk:custom, " +#~ "дазволеныя толькі A-Za-z0-9-_" -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "" -"Самы вонкавы элемент у матыве аздаблення мусіць быць <metacity_theme>, а не <" -"%s>" +#~ msgid "" +#~ "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " +#~ "fit the format" +#~ msgstr "" +#~ "Фармат gtk:custom: \"gtk:custom(назва_колеру,запасны_колер)\"; \"%s\" не " +#~ "адпавядае фармату" -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "Элемент <%s> забаронены ўнутры элементаў name/author/date/description" +#~ msgid "" +#~ "GTK color specification must have the state in brackets, e.g. gtk:" +#~ "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "Спецыфікацыя колеру GTK мусіць мець стан у квадратных дужках, напрыклад, " +#~ "gtk:fg[NORMAL], дзе NORMAL - гэта стан. Не ўдалося разабраць \"%s\"" -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "Элемент <%s> забаронены ўнутры элемента <constant>" +#~ msgid "" +#~ "GTK color specification must have a close bracket after the state, e.g. " +#~ "gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "Спецыфікацыя колеру GTK мусіць мець закрытыя квадратныя дужкі пасля " +#~ "стану, напрыклад, gtk:fg[NORMAL], дзе NORMAL - гэта стан. Не ўдалося " +#~ "разабраць \"%s\"" + +#~ msgid "Did not understand state \"%s\" in color specification" +#~ msgstr "Незразумелы стан \"%s\" у спецыфікацыі колеру" + +#~ msgid "Did not understand color component \"%s\" in color specification" +#~ msgstr "Незразумелы складнік колеру \"%s\" у спецыфікацыі колеру" + +#~ msgid "" +#~ "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit " +#~ "the format" +#~ msgstr "" +#~ "Фармат змяшанага колеру - \"blend/bg_color/fg_color/alpha\". \"%s\" не " +#~ "адпавядае фармату." + +#~ msgid "Could not parse alpha value \"%s\" in blended color" +#~ msgstr "Не ўдалося разабраць значэнне альфа \"%s\" ў змяшаным колеры" + +#~ msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" +#~ msgstr "" +#~ "Значэнне альфа \"%s\" у змяшаным колеры не ўваходзіць у дыяпазон ад 0.0 " +#~ "да 1.0" + +#~ msgid "" +#~ "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the " +#~ "format" +#~ msgstr "" +#~ "Фармат ценю - \"shade/base_color/factor\". \"%s\" не адпавядае фармату." + +#~ msgid "Could not parse shade factor \"%s\" in shaded color" +#~ msgstr "Не ўдалося разабраць каэфіцыент ценю \"%s\" у зацененым колеры" + +#~ msgid "Shade factor \"%s\" in shaded color is negative" +#~ msgstr "Каэфіцыент ценю \"%s\" у зацененым колеры адмоўны" + +#~ msgid "Could not parse color \"%s\"" +#~ msgstr "Не ўдалося разабраць колер \"%s\"" + +#~ msgid "Coordinate expression contains character '%s' which is not allowed" +#~ msgstr "Каардынатны выраз змяшчае забаронены знак \"%s\"" + +#~ msgid "" +#~ "Coordinate expression contains floating point number '%s' which could not " +#~ "be parsed" +#~ msgstr "" +#~ "Каардынатны выраз змяшчае незразумелы лік з нефіксаванай коскай \"%s\"" + +#~ msgid "" +#~ "Coordinate expression contains integer '%s' which could not be parsed" +#~ msgstr "Каардынатны выраз змяшчае незразумелы цэлы лік \"%s\"" + +#~ msgid "" +#~ "Coordinate expression contained unknown operator at the start of this " +#~ "text: \"%s\"" +#~ msgstr "" +#~ "Каардынатны выраз змяшчае невядомы аператар у пачатку гэтага тэксту: \"%s" +#~ "\"" + +#~ msgid "Coordinate expression was empty or not understood" +#~ msgstr "Каардынатны выраз пусты ці незразумелы" + +#~ msgid "Coordinate expression results in division by zero" +#~ msgstr "Каардынатны выраз вымагае дзялення на нуль" + +#~ msgid "" +#~ "Coordinate expression tries to use mod operator on a floating-point number" +#~ msgstr "" +#~ "Каардынатны выраз спрабуе ўжыць аператар дзялення па модулі для ліку з " +#~ "нефіксаванай коскай" + +#~ msgid "" +#~ "Coordinate expression has an operator \"%s\" where an operand was expected" +#~ msgstr "" +#~ "У каардынатным выразе ўжыты аператар \"%s\" там, дзе мусіў быць аперанд" + +#~ msgid "Coordinate expression had an operand where an operator was expected" +#~ msgstr "У каардынатным выразе ўжыты аперанд там, дзе мусіў быць аператар" + +#~ msgid "Coordinate expression ended with an operator instead of an operand" +#~ msgstr "Каардынатны выраз заканчваецца аператарам, а не аперандам" + +#~ msgid "" +#~ "Coordinate expression has operator \"%c\" following operator \"%c\" with " +#~ "no operand in between" +#~ msgstr "" +#~ "У каардынатным выразе за аператарам \"%c\" ідзе аператар \"%c\", але " +#~ "паміж імі няма аперанда" + +#~ msgid "Coordinate expression had unknown variable or constant \"%s\"" +#~ msgstr "У каардынатным выразе невядомая зменная альбо канстанта \"%s\"" + +#~ msgid "Coordinate expression parser overflowed its buffer." +#~ msgstr "Прылада для разбору каардынатных выразаў перапоўніла свой буфер." + +#~ msgid "" +#~ "Coordinate expression had a close parenthesis with no open parenthesis" +#~ msgstr "" +#~ "У каардынатным выразе ўжытыя дужкі, якія закрываюцца, але няма тых, якія " +#~ "б адкрываліся" + +#~ msgid "" +#~ "Coordinate expression had an open parenthesis with no close parenthesis" +#~ msgstr "" +#~ "У каардынатным выразе ўжытыя дужкі, якія адкрываюцца, але няма тых, якія " +#~ "б закрываліся" + +#~ msgid "Coordinate expression doesn't seem to have any operators or operands" +#~ msgstr "У каардынатным выразе няма ні аператараў, ні аперандаў" + +#~ msgid "Theme contained an expression that resulted in an error: %s\n" +#~ msgstr "Матыў аздаблення змяшчае выраз, які стаў прычынай памылкі: %s\n" + +#~ msgid "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " +#~ "specified for this frame style" +#~ msgstr "" +#~ "Для гэтага стылю рамкі трэба вызначыць <button function=\"%s\" state=\"%s" +#~ "\" draw_ops=\"whatever\"/>" + +#~ msgid "" +#~ "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/" +#~ ">" +#~ msgstr "" +#~ "Няма <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"што-небудзь\"/" +#~ ">" -#: ../src/ui/theme-parser.c:3599 -#, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "Элемент <%s> забаронены ўнутры элементаў distance/border/aspect_ratio" +#~ msgid "Failed to load theme \"%s\": %s\n" +#~ msgstr "Не ўдалося загрузіць матыў аздаблення \"%s\": %s\n" -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "Элемент <%s> забаронены ўнутры элемента аперацыі малявання" +#~ msgid "No <%s> set for theme \"%s\"" +#~ msgstr "Для матыву аздаблення \"%2$s\" не прызначана <%1$s>" -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "Элемент <%s> забаронены ўнутры элемента <%s>" +#~ msgid "" +#~ "No frame style set for window type \"%s\" in theme \"%s\", add a <window " +#~ "type=\"%s\" style_set=\"whatever\"/> element" +#~ msgstr "" +#~ "Стыль рамкі не вызначаны для вокнаў тыпу \"%s\" для матыву аздаблення \"%s" +#~ "\". Дадайце <window type=\"%s\" style_set=\"штосьці\"/>." + +#~ msgid "" +#~ "User-defined constants must begin with a capital letter; \"%s\" does not" +#~ msgstr "" +#~ "Назвы канстантаў, вызначаных карыстальнікам, мусяць пачынацца з вялікай " +#~ "літары. \"%s\" не адпавядае гэтаму патрабаванню." -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "Для кавалка рамкі не вызначана элементаў draw_ops" +#~ msgid "Constant \"%s\" has already been defined" +#~ msgstr "Канстанта \"%s\" ужо азначана" -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "Для кнопкі не вызначана элементаў draw_ops" +#~ msgid "No \"%s\" attribute on element <%s>" +#~ msgstr "Элемент <%2$s> не мае атрыбута \"%1$s\"" -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "Выкарыстанне тэксту ўнутры элемента <%s> забаронена" +#~ msgid "Line %d character %d: %s" +#~ msgstr "Радок %d, знак %d: %s" -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "<%s> двойчы вызначаны для гэтага матыву аздаблення" +#~ msgid "Attribute \"%s\" repeated twice on the same <%s> element" +#~ msgstr "Атрыбут \"%s\" двойчы азначаны для элемента <%s>" -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Памылка пошуку правільнага файла для матыву аздаблення %s\n" +#~ msgid "Attribute \"%s\" is invalid on <%s> element in this context" +#~ msgstr "У гэтым кантэксце атрыбут \"%s\" элемента <%s> з'яўляецца хібным" -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "_Вокны" +#~ msgid "Could not parse \"%s\" as an integer" +#~ msgstr "Не ўдалося інтэрпрэтаваць \"%s\" як цэлы лік" -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "_Дыялогавае акенца" +#~ msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +#~ msgstr "Спатканыя незразумелыя знакі \"%s\" у канцы ланцужка \"%s\"" -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "_Мадальнае дыялогавае акенца" +#~ msgid "Integer %ld must be positive" +#~ msgstr "Цэлы лік %ld мусіць быць дадатным" -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "_Дапаможная праграма" +#~ msgid "Integer %ld is too large, current max is %d" +#~ msgstr "" +#~ "Цэлы лік %ld надта вялікі, максімальна дазволенае значэнне роўнае %d" -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "_Экранная застаўка" +#~ msgid "Could not parse \"%s\" as a floating point number" +#~ msgstr "" +#~ "Не ўдалося разабраць значэнне \"%s\" як дробны лік з нефіксаванай коскай" -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "_Верхняя ўбудова" +#~ msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" +#~ msgstr "" +#~ "Булева зменная можа мець значэнне \"true\" або \"false\", але не \"%s\"" -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "_Ніжняя ўбудова" +#~ msgid "Angle must be between 0.0 and 360.0, was %g\n" +#~ msgstr "Вугал можа мець значэнне ад 0.0 да 360.0, а не %g\n" -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "_Левая ўбудова" +#~ msgid "" +#~ "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" +#~ msgstr "" +#~ "Вартасць альфа мусіць быць ад 0.0 (нябачная) да 1.0 (поўнасцю " +#~ "непразрыстая), а пададзена %g\n" -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "_Правая ўбудова" +#~ msgid "" +#~ "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," +#~ "large,x-large,xx-large)\n" +#~ msgstr "" +#~ "Хібны маштаб загалоўка \"%s\" (магчымыя значэнні: xx-small, x-small, " +#~ "small, medium, large, x-large, xx-large)\n" -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "_Усе ўбудовы" +#~ msgid "<%s> name \"%s\" used a second time" +#~ msgstr "Назва <%s> \"%s\" ужытая другі раз" -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "_Стол" +#~ msgid "<%s> parent \"%s\" has not been defined" +#~ msgstr "Продак <%s> \"%s\" не азначаны" -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "Адкрыць чарговае з гэтых вокнаў" +#~ msgid "<%s> geometry \"%s\" has not been defined" +#~ msgstr "Памеры віджэта <%s> \"%s\" не азначаны" -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "Гэта дэманстрацыйная кнопка са значком \"Адкрыць\"" +#~ msgid "<%s> must specify either a geometry or a parent that has a geometry" +#~ msgstr "" +#~ "<%s> мусіць вызначыць або памеры віджэта, або продка, які мае памеры" -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "Гэта дэманстрацыйная кнопка са значком \"Выйсці\"" +#~ msgid "You must specify a background for an alpha value to be meaningful" +#~ msgstr "Трэба вызначыць фон для значэння альфа, каб яно мела сэнс" -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "Гэта ўзорнае паведамленне ва ўзорным дыялогавым акенцы" +#~ msgid "Unknown type \"%s\" on <%s> element" +#~ msgstr "Невядомы тып \"%s\" для элемента <%s>" -#: ../src/ui/theme-viewer.c:328 -#, c-format -msgid "Fake menu item %d\n" -msgstr "Несапраўдны пункт меню %d\n" +#~ msgid "Unknown style_set \"%s\" on <%s> element" +#~ msgstr "Невядомае значэнне style_set \"%s\" для элемента <%s>" -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "Акно толькі з аблямоўкай" +#~ msgid "Window type \"%s\" has already been assigned a style set" +#~ msgstr "Тыпу акна \"%s\" ужо прызначаны збор стыляў" -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "Стужка" +#~ msgid "Element <%s> is not allowed below <%s>" +#~ msgstr "Элемент <%s> забаронены ніжэй за <%s>" -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "Звычайнае акно праграмы" +#~ msgid "" +#~ "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio" +#~ "\" for buttons" +#~ msgstr "" +#~ "Немагчыма вызначыць для кнопак адначасова \"button_width\"/\"button_height" +#~ "\" і \"aspect_ratio\"" -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "Дыялогавае акенца" +#~ msgid "Distance \"%s\" is unknown" +#~ msgstr "Адлегласць \"%s\" невядомая" -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "Мадальнае дыялогавае акенца" +#~ msgid "Aspect ratio \"%s\" is unknown" +#~ msgstr "Каэфіцыент прапарцыянальнасці \"%s\" невядомы" -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "Дапаможная палітра" +#~ msgid "Border \"%s\" is unknown" +#~ msgstr "Аблямоўка \"%s\" невядомая" -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "Адчэпленае меню" +#~ msgid "No \"start_angle\" or \"from\" attribute on element <%s>" +#~ msgstr "Няма атрыбутаў \"start_angle\" ці \"from\" для элемента <%s>" -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "Аблямоўка" +#~ msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" +#~ msgstr "Няма атрыбутаў \"extent_angle\" ці \"to\" для элемента <%s>" -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "Прычапленае мадальнае дыялогавае акенца" +#~ msgid "Did not understand value \"%s\" for type of gradient" +#~ msgstr "Незразумелае значэнне \"%s\" для тыпу градыента" -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "Выпрабаванне размяшчэння кнопак %d" +#~ msgid "Did not understand fill type \"%s\" for <%s> element" +#~ msgstr "Незразумелы тып запаўнення \"%s\" для элемента <%s>" -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g мілісекунд, каб намаляваць адну рамку акна" +#~ msgid "Did not understand state \"%s\" for <%s> element" +#~ msgstr "Незразумелы стан \"%s\" для элемента <%s>" -#: ../src/ui/theme-viewer.c:813 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Правілы карыстання: metacity-theme-viewer [НАЗВА_МАТЫВУ]\n" +#~ msgid "Did not understand shadow \"%s\" for <%s> element" +#~ msgstr "Незразумелы цень \"%s\" для элемента <%s>" -#: ../src/ui/theme-viewer.c:820 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "Памылка загрузкі матыву аздаблення: %s\n" +#~ msgid "Did not understand arrow \"%s\" for <%s> element" +#~ msgstr "Незразумелая стрэлка \"%s\" для элемента <%s>" -#: ../src/ui/theme-viewer.c:826 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "Матыў аздаблення \"%s\" загружаны за %g секунд\n" +#~ msgid "No <draw_ops> called \"%s\" has been defined" +#~ msgstr "<draw_ops> з назвай \"%s\" не азначаны" -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "Звычайны шрыфт загалоўка" +#~ msgid "Including draw_ops \"%s\" here would create a circular reference" +#~ msgstr "Уключэнне тут draw_ops \"%s\" створыць цыклічную адсылку" -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "Маленькі шрыфт загалоўка" +#~ msgid "Unknown position \"%s\" for frame piece" +#~ msgstr "Невядомая пазіцыя \"%s\" для кавалка рамкі" -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "Вялікі шрыфт загалоўка" +#~ msgid "Frame style already has a piece at position %s" +#~ msgstr "У стылі рамкі ўжо ёсць кавалак у пазіцыі %s" -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "Размяшчэнне кнопак" +#~ msgid "No <draw_ops> with the name \"%s\" has been defined" +#~ msgstr "<draw_ops> з назвай \"%s\" не азначаны" -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "Выпрабаванне" +#~ msgid "Unknown function \"%s\" for button" +#~ msgstr "Невядомая функцыя \"%s\" для кнопкі" -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "Месца для загалоўка акна" +#~ msgid "Button function \"%s\" does not exist in this version (%d, need %d)" +#~ msgstr "Функцыя кнопкі \"%s\" не існуе ў гэтай версіі (%d, патрэбна %d)" -#: ../src/ui/theme-viewer.c:1047 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"Намалявана %d рамак цягам %g секунд кліенцкага часу (%g мілісекунд на рамку) " -"і %g секунд каляндарнага часу, уключна з рэсурсамі X-сервера (%g мілісекунд " -"на рамку)\n" +#~ msgid "Unknown state \"%s\" for button" +#~ msgstr "Невядомы стан \"%s\" для кнопкі" -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "выпрабаванне выразу пазіцыі вярнула TRUE, але паведаміла аб памылцы" +#~ msgid "Frame style already has a button for function %s state %s" +#~ msgstr "У стылі рамкі ўжо ёсць кнопка для функцыі %s, стану %s" -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "" -"выпрабаванне выразу пазіцыі вярнула FALSE, але не паведаміла аб памылцы" +#~ msgid "\"%s\" is not a valid value for focus attribute" +#~ msgstr "\"%s\" - няправільнае значэнне для атрыбута \"focus\"" -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "Чакалася памылка, але звесткі не атрыманыя" +#~ msgid "\"%s\" is not a valid value for state attribute" +#~ msgstr "\"%s\" - няправільнае значэнне для атрыбута \"state\"" -#: ../src/ui/theme-viewer.c:1274 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "Чакалася памылка %d, але атрымана %d" +#~ msgid "A style called \"%s\" has not been defined" +#~ msgstr "Стыль \"%s\" не азначаны" -#: ../src/ui/theme-viewer.c:1280 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "Атрымана нечаканая памылка: %s" +#~ msgid "\"%s\" is not a valid value for resize attribute" +#~ msgstr "\"%s\" - няправільнае значэнне для атрыбута \"resize\"" -#: ../src/ui/theme-viewer.c:1284 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "X-значэнне было %d, а чакалася %d" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized/shaded " +#~ "states" +#~ msgstr "" +#~ "Для максімалізаванага і зацененага стану нельга мець атрыбут \"resize\" у " +#~ "элеменце <%s>" -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "Y-значэнне было %d, а чакалася %d" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized states" +#~ msgstr "" +#~ "Для максімалізаванага стану нельга мець атрыбут \"resize\" у элеменце <%s>" -#: ../src/ui/theme-viewer.c:1352 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "" -"%d каардынатных выразаў разабраныя за %g секунд (у сярэднім %g секунд)\n" +#~ msgid "Style has already been specified for state %s resize %s focus %s" +#~ msgstr "Стыль для state %s, resize %s, focus %s ужо вызначаны" + +#~ msgid "Style has already been specified for state %s focus %s" +#~ msgstr "Стыль для state %s, focus %s ужо вызначаны" + +#~ msgid "" +#~ "Can't have a two draw_ops for a <piece> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Немагчыма двойчы ўжыць draw_ops для элемента <piece> (матыў аздаблення " +#~ "вызначыў атрыбут draw_ops, а таксама элемент <draw_ops>, або вызначыў два " +#~ "элементы)" + +#~ msgid "" +#~ "Can't have a two draw_ops for a <button> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Немагчыма двойчы ўжыць draw_ops для элемента <button> (матыў аздаблення " +#~ "вызначыў атрыбут draw_ops, а таксама элемент <draw_ops>, або вызначыў два " +#~ "элементы)" + +#~ msgid "" +#~ "Can't have a two draw_ops for a <menu_icon> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Немагчыма двойчы ўжыць draw_ops для элемента <menu_icon> (матыў " +#~ "аздаблення вызначыў атрыбут draw_ops, а таксама элемент <draw_ops>, або " +#~ "вызначыў два элементы)" + +#~ msgid "Bad version specification '%s'" +#~ msgstr "Хібная спецыфікацыя версіі \"%s\"" + +#~ msgid "" +#~ "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" +#~ "theme-2.xml" +#~ msgstr "" +#~ "Атрыбут \"version\" не можа быць ужыты ў metacity-theme-1.xml ці metacity-" +#~ "theme-2.xml" + +#~ msgid "" +#~ "Theme requires version %s but latest supported theme version is %d.%d" +#~ msgstr "" +#~ "Матыў аздаблення патрабуе версію %s, але апошняя версія матываў, якая " +#~ "падтрымліваецца, - гэта %d.%d" + +#~ msgid "Outermost element in theme must be <metacity_theme> not <%s>" +#~ msgstr "" +#~ "Самы вонкавы элемент у матыве аздаблення мусіць быць <metacity_theme>, а " +#~ "не <%s>" + +#~ msgid "" +#~ "Element <%s> is not allowed inside a name/author/date/description element" +#~ msgstr "" +#~ "Элемент <%s> забаронены ўнутры элементаў name/author/date/description" + +#~ msgid "Element <%s> is not allowed inside a <constant> element" +#~ msgstr "Элемент <%s> забаронены ўнутры элемента <constant>" + +#~ msgid "" +#~ "Element <%s> is not allowed inside a distance/border/aspect_ratio element" +#~ msgstr "" +#~ "Элемент <%s> забаронены ўнутры элементаў distance/border/aspect_ratio" + +#~ msgid "Element <%s> is not allowed inside a draw operation element" +#~ msgstr "Элемент <%s> забаронены ўнутры элемента аперацыі малявання" + +#~ msgid "Element <%s> is not allowed inside a <%s> element" +#~ msgstr "Элемент <%s> забаронены ўнутры элемента <%s>" + +#~ msgid "No draw_ops provided for frame piece" +#~ msgstr "Для кавалка рамкі не вызначана элементаў draw_ops" + +#~ msgid "No draw_ops provided for button" +#~ msgstr "Для кнопкі не вызначана элементаў draw_ops" + +#~ msgid "No text is allowed inside element <%s>" +#~ msgstr "Выкарыстанне тэксту ўнутры элемента <%s> забаронена" + +#~ msgid "<%s> specified twice for this theme" +#~ msgstr "<%s> двойчы вызначаны для гэтага матыву аздаблення" + +#~ msgid "Failed to find a valid file for theme %s\n" +#~ msgstr "Памылка пошуку правільнага файла для матыву аздаблення %s\n" diff --git a/po/be@latin.po b/po/be@latin.po index 9a29627d6..a2fc69a29 100644 --- a/po/be@latin.po +++ b/po/be@latin.po @@ -11,6 +11,7 @@ msgstr "" "PO-Revision-Date: 2009-02-14 19:37+0200\n" "Last-Translator: Ihar Hrachyshka <ihar.hrachyshka@gmail.com>\n" "Language-Team: i18n@mova.org <i18n@mova.org>\n" +"Language: be@latin\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" diff --git a/po/bg.po b/po/bg.po index c205a4376..c21cee186 100644 --- a/po/bg.po +++ b/po/bg.po @@ -1,423 +1,295 @@ -# Bulgarian translation of muffin po-file. +# Bulgarian translation of mutter po-file. # Copyright (C) 2002, 2004, 2006, 2007, 2008 Free Software Foundation, Inc. -# Copyright (C) 2009, 2010, 2011, 2012 Free Software Foundation, Inc. -# Alexander Shopov <ash@kambanaria.org>, 2002, 2006, 2007, 2009, 2010, 2011, 2012. +# Copyright (C) 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. +# Copyright (C) 2014, 2015, 2016, 2017 Free Software Foundation, Inc. +# Alexander Shopov <ash@kambanaria.org>, 2002, 2006, 2007, 2009, 2010. +# Alexander Shopov <ash@kambanaria.org>, 2011, 2012, 2013, 2014, 2015. +# Alexander Shopov <ash@kambanaria.org>, 2016, 2017. # Vladimir Petkov <kaladan@gmail.com>, 2004. # Rostislav Raykov <zbrox@i-space.org>, 2004. # Yavor Doganov <yavor@gnu.org>, 2008. # -# msgid "" msgstr "" -"Project-Id-Version: muffin master\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-03-12 06:45+0200\n" -"PO-Revision-Date: 2012-03-12 06:45+0200\n" +"Project-Id-Version: mutter master\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?" +"product=mutter&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-09-10 11:09+0000\n" +"PO-Revision-Date: 2017-09-10 17:41+0300\n" "Last-Translator: Alexander Shopov <ash@kambanaria.org>\n" "Language-Team: Bulgarian <dict@fsa-bg.org>\n" "Language: bg\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=n != 1;\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ../src/50-muffin-windows.xml.in.h:1 -msgid "Windows" -msgstr "Прозорци" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Навигация" -#: ../src/50-muffin-windows.xml.in.h:2 -msgid "View split on left" -msgstr "Изглед разделен отляво" +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Преместване на прозореца на работен плот 1" -#: ../src/50-muffin-windows.xml.in.h:3 -msgid "View split on right" -msgstr "Изглед разделен отдясно" +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Преместване на прозореца на работен плот 2" -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format -msgid "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." -msgstr "На екран %i от дисплея „%s“ вече има мениджър за наслагване." +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Преместване на прозореца на работен плот 3" -#: ../src/core/bell.c:307 -msgid "Bell event" -msgstr "Събитие за звънец" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Преместване на прозореца на работен плот 4" -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Неизвестна заявка за информация за прозорец: %d" +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Преместване на прозореца на последния работен плот" -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> не отговаря на съобщенията." +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace to the left" +msgstr "Преместване на прозореца един работен плот наляво" -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "Програмата не отговаря на съобщенията." +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace to the right" +msgstr "Преместване на прозореца един работен плот надясно" -#: ../src/core/delete.c:119 -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "" -"Можете да изчакате малко преди изрично да накарате приложението да спре " -"работата си." +#: data/50-mutter-navigation.xml:30 +msgid "Move window one workspace up" +msgstr "Преместване на прозореца един работен плот нагоре" -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "Из_чакване" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one workspace down" +msgstr "Преместване на прозореца един работен плот надолу" -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "_Принудително спиране" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor to the left" +msgstr "Преместване на прозореца един екран наляво" -#: ../src/core/display.c:361 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "Липсва разширението „%s“, необходимо за наслагване" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor to the right" +msgstr "Преместване на прозореца един екран надясно" -#: ../src/core/display.c:427 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Неуспех при отварянето на дисплея на X Window „%s“\n" +#: data/50-mutter-navigation.xml:42 +msgid "Move window one monitor up" +msgstr "Преместване на прозореца един екран нагоре" -#: ../src/core/keybindings.c:852 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "Някоя друга програма използва бързия клавиш %s с модификатори %x\n" +#: data/50-mutter-navigation.xml:45 +msgid "Move window one monitor down" +msgstr "Преместване на прозореца един екран надолу" -#: ../src/core/main.c:206 -msgid "Disable connection to session manager" -msgstr "Прекъсване на връзката към мениджъра на сесиите" +#: data/50-mutter-navigation.xml:49 +msgid "Switch applications" +msgstr "Преместване на фокуса между програмите" -#: ../src/core/main.c:212 -msgid "Replace the running window manager" -msgstr "Замяна на текущия мениджър на прозорци" +#: data/50-mutter-navigation.xml:54 +msgid "Switch to previous application" +msgstr "Преместване на фокуса към предишната програма" -#: ../src/core/main.c:218 -msgid "Specify session management ID" -msgstr "Определяне на идентификатор за управлението на сесии" +#: data/50-mutter-navigation.xml:58 +msgid "Switch windows" +msgstr "Преместване на фокуса между прозорците" -#: ../src/core/main.c:223 -msgid "X Display to use" -msgstr "X дисплеят, който да се използва" +#: data/50-mutter-navigation.xml:63 +msgid "Switch to previous window" +msgstr "Преместване на фокуса към предишния прозорец" -# Ако „запазено“ не се членува, низът се събира на един ред без -# пренасяне. -#: ../src/core/main.c:229 -msgid "Initialize session from savefile" -msgstr "Инициализиране на сесия от файл със запазено състояние" +#: data/50-mutter-navigation.xml:67 +msgid "Switch windows of an application" +msgstr "Преместване на фокуса между прозорците на една програма" -#: ../src/core/main.c:235 -msgid "Make X calls synchronous" -msgstr "Извикванията на X да са синхронни" +#: data/50-mutter-navigation.xml:72 +msgid "Switch to previous window of an application" +msgstr "Преместване на фокуса към предишния прозорец на програма" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Неуспех при сканирането на папката с темите: %s\n" +#: data/50-mutter-navigation.xml:76 +msgid "Switch system controls" +msgstr "Към следващия служебен обект" -#: ../src/core/main.c:520 -#, c-format -msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "" -"Неуспех при намирането на тема! Проверете дали %s съществува и съдържа " -"обичайните теми.\n" +#: data/50-mutter-navigation.xml:81 +msgid "Switch to previous system control" +msgstr "Към предишния служебен обект" -#: ../src/core/muffin.c:40 -#, c-format -msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" -"muffin %s\n" -"Авторски права (C) 2001-%d Havoc Pennington, Red Hat, Inc., и други\n" -"Тази програма (muffin) е свободен софтуер, прегледайте изходния код относно " -"условията за разпространение.\n" -"Тази програма се разпространява БЕЗ НИКАКВИ ГАРАНЦИИ, дори и за ПРОДАЖБА или " -"СЪОТВЕТСТВИЕ С КАКВАТО И ДА Е УПОТРЕБА.\n" +#: data/50-mutter-navigation.xml:85 +msgid "Switch windows directly" +msgstr "Незабавно преместване на фокуса между прозорците" -#: ../src/core/muffin.c:54 -msgid "Print version" -msgstr "Отпечатване на версията на програмата" +#: data/50-mutter-navigation.xml:90 +msgid "Switch directly to previous window" +msgstr "Незабавно преместване на фокуса към предишния прозорец" -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "Списък с приставки за мениджъра за наслагването разделени с „,“" +#: data/50-mutter-navigation.xml:94 +msgid "Switch windows of an app directly" +msgstr "Незабавно преместване на фокуса между прозорците на една програма" -#: ../src/core/prefs.c:1077 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" +#: data/50-mutter-navigation.xml:99 +msgid "Switch directly to previous window of an app" msgstr "" -"Триковете за развалените програми са изключени. Някои програми могат да са с " -"неправилно поведение.\n" +"Незабавно преместване на фокуса към предишния прозорец на една програма" -#: ../src/core/prefs.c:1152 -#, c-format -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "" -"Описанието на шрифт „%s“ от ключа на GSettings — %s, не може да бъде " -"анализирано\n" +#: data/50-mutter-navigation.xml:103 +msgid "Switch system controls directly" +msgstr "Незабавно преместване на фокуса между служебните обекти" -#: ../src/core/prefs.c:1218 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"„%s“, който е открит в базата от данни с настройките, не е валиден " -"модификатор на бутон на мишката\n" +#: data/50-mutter-navigation.xml:108 +msgid "Switch directly to previous system control" +msgstr "Незабавно преместване на фокуса към предишния служебен обект" -#: ../src/core/prefs.c:1739 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "" -"Низът „%s“ открит в базата от данни с настройки е невалиден за стойност на " -"клавишната комбинация „%s“\n" +#: data/50-mutter-navigation.xml:111 +msgid "Hide all normal windows" +msgstr "Скриване на всички обикновени прозорци" -#: ../src/core/prefs.c:1836 -#, c-format -msgid "Workspace %d" -msgstr "Работен плот %d" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 1" +msgstr "Превключване към работен плот 1" -#: ../src/core/screen.c:730 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "Екранът %d на дисплей „%s“ е невалиден\n" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 2" +msgstr "Превключване към работен плот 2" -#: ../src/core/screen.c:746 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"Екранът %d на дисплей „%s“ вече има мениджър на прозорци; пробвайте да го " -"замените с опцията --replace.\n" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to workspace 3" +msgstr "Превключване към работен плот 3" -#: ../src/core/screen.c:773 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "" -"Неуспех при получаването на избрания мениджър за прозорци на екран %d, " -"дисплей „%s“\n" +#: data/50-mutter-navigation.xml:123 +msgid "Switch to workspace 4" +msgstr "Превключване към работен плот 4" -#: ../src/core/screen.c:828 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "Екран %d на дисплей „%s“ вече има мениджър за прозорци\n" +#: data/50-mutter-navigation.xml:126 +msgid "Switch to last workspace" +msgstr "Превключване към последния работен плот" -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "Неуспех при отстъпването на екран %d на дисплей „%s“\n" +#: data/50-mutter-navigation.xml:129 +msgid "Move to workspace left" +msgstr "Преместване на левия работен плот" -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Неуспех при създаването на папката „%s“: %s\n" +#: data/50-mutter-navigation.xml:132 +msgid "Move to workspace right" +msgstr "Преместване на десния работен плот" -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "Неуспех при отварянето на сесийния файл „%s“ за запис: %s\n" +#: data/50-mutter-navigation.xml:135 +msgid "Move to workspace above" +msgstr "Преместване на горния работен плот" -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Грешка при записване на сесийния файл „%s“: %s\n" +#: data/50-mutter-navigation.xml:138 +msgid "Move to workspace below" +msgstr "Преместване на долния работен плот" -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Грешка при затваряне на сесийния файл „%s“: %s\n" +#: data/50-mutter-system.xml:6 +msgid "System" +msgstr "Система" -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Неуспех при анализирането на записания сесиен файл: %s\n" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Показване на прозореца за стартиране на команда" -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "" -"Атрибутът <muffin_session> е видян, но вече имаме сесийния идентификатор" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Преглед на дейностите" -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Непознат атрибут %s на елемента <%s>" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Прозорци" -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "вложен етикет <window>" +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "Задействане на менюто за прозорците" -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "Непознат елемент %s" +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Превключване на режима за цял екран" -#: ../src/core/session.c:1809 -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" -"Тези прозорци не поддържат операцията по записване на текущото състояние и " -"ще трябва да се стартират ръчно при следващото ви влизане." - -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Неуспех при отварянето на дневника за изчистване на грешки: %s\n" +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "Превключване на състоянието на максимизиране" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Неуспех при изпълнението на fdopen() върху журналния файл %s: %s\n" +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "Максимизиране на прозорец" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "Отворен е дневника %s\n" +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Възстановяване на прозорец" -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "Muffin е компилиран без поддръжка на подробен режим\n" +#: data/50-mutter-windows.xml:18 +msgid "Toggle shaded state" +msgstr "Превключване на състоянието на навиване" -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "Мениджър на прозорци: " +#: data/50-mutter-windows.xml:20 +msgid "Close window" +msgstr "Затваряне на прозореца" -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "Грешка в мениджъра на прозорци: " +#: data/50-mutter-windows.xml:22 +msgid "Hide window" +msgstr "Скриване на прозорец" -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "Предупреждение от мениджъра на прозорци: " +#: data/50-mutter-windows.xml:24 +msgid "Move window" +msgstr "Преместване на прозорец" -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "Грешка от мениджъра на прозорци: " +#: data/50-mutter-windows.xml:26 +msgid "Resize window" +msgstr "Оразмеряване на прозорец" -#. first time through -#: ../src/core/window.c:7224 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"Прозорецът %s зададе SM_CLIENT_ID за себе, а не за прозореца " -"WM_CLIENT_LEADER, както е указано в ICCCM.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7887 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size " -"%d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"Прозорецът %s задава подсказка MWM за това, че размерът му не може да се " -"променя, но едновременно с това указва минимален размер %d x %d и максимален " -"размер %d x %d. Това не е смислено.\n" +#: data/50-mutter-windows.xml:29 +msgid "Toggle window on all workspaces or one" +msgstr "Превключване на появата на прозореца на всички работни места" -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "Приложението зададе неверен _NET_WM_PID %lu\n" +#: data/50-mutter-windows.xml:31 +msgid "Raise window if covered, otherwise lower it" +msgstr "Ако прозорецът е под друг, го издига, иначе го понижава" -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (от %s)" +#: data/50-mutter-windows.xml:33 +msgid "Raise window above other windows" +msgstr "Издигане на прозореца над другите" -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "За %2$s е указан неправилен WM_TRANSIENT_FOR, прозорец 0x%1$lx.\n" +#: data/50-mutter-windows.xml:35 +msgid "Lower window below other windows" +msgstr "Понижаване на прозореца под другите прозорци" -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "WM_TRANSIENT_FOR за прозорец 0x%lx за %s ще зацикли.\n" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window vertically" +msgstr "Максимизиране на прозореца вертикално" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"Прозорецът 0x%lx има свойството %s\n" -"което трябва да е от вида: %s, формат: %d\n" -"а всъщност има вида: %s, формат: %d, брой: %d.\n" -"Това най-вероятно е грешка в приложението, а не в мениджъра на прозорци.\n" -"Прозорецът е със заглавие=„%s“, клас=„%s“, име=„%s“\n" +#: data/50-mutter-windows.xml:39 +msgid "Maximize window horizontally" +msgstr "Максимизиране на прозореца хоризонтално" -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "Свойството %s на прозореца 0x%lx съдържа невалиден UTF-8\n" +#: data/50-mutter-windows.xml:43 +msgid "View split on left" +msgstr "Изглед разделен отляво" -#: ../src/core/xprops.c:494 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"Свойството %s на прозореца 0x%lx съдържа невалиден UTF-8 за елемента %d в " -"списъка\n" +#: data/50-mutter-windows.xml:47 +msgid "View split on right" +msgstr "Изглед разделен отдясно" -#: ../src/muffin.desktop.in.h:1 ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 +#: data/org.gnome.mutter.gschema.xml.in:7 msgid "Modifier to use for extended window management operations" msgstr "" "Модификатор, който да се ползва за допълнителните действия по прозорците" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 +#: data/org.gnome.mutter.gschema.xml.in:8 msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." msgstr "" "Този клавиш стартира наслагването, което е комбинация от прозорец и система " "за стартиране на програми. Стандартно клавишът е „Windows“ при системите " "съвместими с PC. Очаква се да е или стандартната стойност или празен низ." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 +#: data/org.gnome.mutter.gschema.xml.in:20 msgid "Attach modal dialogs" msgstr "Прилепени модални диалогови прозорци" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 +#: data/org.gnome.mutter.gschema.xml.in:21 msgid "" "When true, instead of having independent titlebars, modal dialogs appear " "attached to the titlebar of the parent window and are moved together with " @@ -427,25 +299,13 @@ msgstr "" "заглавната лента на родителския си прозорец и се местят с него, вместо да са " "отделни и да имат собствена заглавна лента." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -msgid "Live Hidden Windows" -msgstr "Обновяване на скритите прозорци" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"Дали скритите прозорци (т.е. минимизираните или на другите плотове) да се " -"обновяват." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 +#: data/org.gnome.mutter.gschema.xml.in:30 msgid "Enable edge tiling when dropping windows on screen edges" msgstr "" "Включване на прилепването и максимизирането на прозорците по границите на " "екрана" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 +#: data/org.gnome.mutter.gschema.xml.in:31 msgid "" "If enabled, dropping windows on vertical screen edges maximizes them " "vertically and resizes them horizontally to cover half of the available " @@ -454,39 +314,39 @@ msgstr "" "Ако е включено, прозорците ще се максимизират по вертикала и ще заемат " "половината площ по хоризонтала при поставянето им край вертикалните граници " "на екрана. При поставянето им край горната граница прозорците ще се " -"максимзират изцяло." +"максимизират изцяло." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 +#: data/org.gnome.mutter.gschema.xml.in:40 msgid "Workspaces are managed dynamically" msgstr "Динамично управление на работните места" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 +#: data/org.gnome.mutter.gschema.xml.in:41 msgid "" -"Determines whether workspaces are managed dynamically or whether there's a " +"Determines whether workspaces are managed dynamically or whether there’s a " "static number of workspaces (determined by the num-workspaces key in org." "gnome.desktop.wm.preferences)." msgstr "" "Определя дали се ползва динамично управление на работните места или броят им " -"е установено число (зададено чрез ключа „num-workspaces“ в org.cinnamon.desktop." -"wm.preferences)." +"е установено число (зададено чрез ключа „num-workspaces“ в „org.gnome." +"desktop.wm.preferences“)." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 +#: data/org.gnome.mutter.gschema.xml.in:50 msgid "Workspaces only on primary" -msgstr "Работни плотове само на основния монитор" +msgstr "Работни плотове само на основния екран" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 +#: data/org.gnome.mutter.gschema.xml.in:51 msgid "" "Determines whether workspace switching should happen for windows on all " "monitors or only for windows on the primary monitor." msgstr "" -"Дали смяната на работни плотове да се извършва на всички монитори или само " -"на основния." +"Дали смяната на работни плотове да се извършва на всички екрани или само на " +"основния." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 +#: data/org.gnome.mutter.gschema.xml.in:59 msgid "No tab popup" msgstr "Без изскачащ прозорец при обхождане" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 +#: data/org.gnome.mutter.gschema.xml.in:60 msgid "" "Determines whether the use of popup and highlight frame should be disabled " "for window cycling." @@ -494,1146 +354,334 @@ msgstr "" "Дали отбелязването на рамка и изскачащият прозорец при обхождане на " "прозорците да се изключат." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Смяната на фокуса да изчака спирането на показалеца" + +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" +"Ако е включено и начинът за фокусиране е „sloppy“ (мързеливо) или " +"„mouse“ (под мишката), тогава фокусът няма да се предава веднага при " +"навлизането в прозорец, а едва след като показалецът спре да се движи." + +#: data/org.gnome.mutter.gschema.xml.in:79 msgid "Draggable border width" msgstr "Широчина на границата за влачене" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 +#: data/org.gnome.mutter.gschema.xml.in:80 msgid "" -"The amount of total draggable borders. If the theme's visible borders are " +"The amount of total draggable borders. If the theme’s visible borders are " "not enough, invisible borders will be added to meet this value." msgstr "" "Общ размер на границите за влачене. Ако видимите граници на темата са по-" "малки, се добавят невидими граници, за да се достигне тази величина." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:17 -msgid "Select window from tab popup" -msgstr "Избиране при обхождане чрез изскачащ прозорец" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:18 -msgid "Cancel tab popup" -msgstr "Без изскачащ прозорец при обхождане" - -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "Употреба: %s\n" - -#: ../src/ui/frames.c:1158 -msgid "Close Window" -msgstr "Затваряне на прозореца" - -#: ../src/ui/frames.c:1161 -msgid "Window Menu" -msgstr "Меню за прозорците" - -#: ../src/ui/frames.c:1164 -msgid "Minimize Window" -msgstr "Минимизиране на прозореца" - -#: ../src/ui/frames.c:1167 -msgid "Maximize Window" -msgstr "Максимизиране на прозореца" - -#: ../src/ui/frames.c:1170 -msgid "Restore Window" -msgstr "Възстановяване на прозорец" - -#: ../src/ui/frames.c:1173 -msgid "Roll Up Window" -msgstr "Навиване на прозореца" - -#: ../src/ui/frames.c:1176 -msgid "Unroll Window" -msgstr "Развиване на прозореца" - -#: ../src/ui/frames.c:1179 -msgid "Keep Window On Top" -msgstr "Прозорецът да е отгоре" - -#: ../src/ui/frames.c:1182 -msgid "Remove Window From Top" -msgstr "Прозорецът да не е само отгоре" - -#: ../src/ui/frames.c:1185 -msgid "Always On Visible Workspace" -msgstr "Винаги на видимия работен плот" - -#: ../src/ui/frames.c:1188 -msgid "Put Window On Only One Workspace" -msgstr "Прозорецът да се появява само на едно работен плот" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "Ми_нимизиране" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "_Максимизиране" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "Де_максимизиране" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "На_виване" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "_Развиване" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "_Преместване" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "О_размеряване" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "Преместване на лентата за заглавието по _екрана" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "Винаги _отгоре" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "_Винаги на видимия работен плот" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "_Само на този работен плот" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "Преместване на _левия работен плот" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "Преместване на десни_я работен плот" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "Преместване на _горния работен плот" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "Преместване в _долния работен плот" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "_Затваряне" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "Работен плот %d%n" - -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "Работен плот 1_0" - -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "Работен плот %s%d" - -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "Преместване на др_уг работен плот" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" - -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d×%d" - -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "горния" - -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "долния" - -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "левия" - -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "десния" - -#: ../src/ui/theme.c:286 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "геометрията на рамката не указва „%s“ размер" - -#: ../src/ui/theme.c:305 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "геометрията на рамката не указва „%s“ размер на „%s“ ръб" - -#: ../src/ui/theme.c:342 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "Отношението на размерите на бутона %g е неподходящо" - -#: ../src/ui/theme.c:354 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "Геометрията на рамката не указва размера на бутоните" - -#: ../src/ui/theme.c:1067 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "Преливките трябва да имат поне два цвята" - -#: ../src/ui/theme.c:1219 -#, c-format -msgid "" -"GTK custom color specification must have color name and fallback in " -"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" -msgstr "" -"Цветовата спецификация на GTK трябва да съдържа в скоби име на основен и " -"резервен цвят: напр. gtk:custom(foo,bar). Неуспех при анализа на „%s“" - -#: ../src/ui/theme.c:1235 -#, c-format -msgid "" -"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" -"_ are valid" +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" msgstr "" -"Неправилен знак „%c“ в параметъра за име на цвят (color_name) на gtk:custom. " -"Позволени са само A-Za-z0-9-_." +"Автоматично максимизиране на прозорци с размер близък до този на екрана" -#: ../src/ui/theme.c:1249 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:90 msgid "" -"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " -"fit the format" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." msgstr "" -"Форматът на Gtk:custom е „gtk:custom(основен_цвят,резервен_цвят)“, „%s“ не " -"съответства на формата" +"Ако е включено, новите прозорци, чийто размер е близък на този на екрана, " +"автоматично ще се максимизират." -#: ../src/ui/theme.c:1294 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"Цветовата спецификация на GTK трябва да указва състоянието в квадратни " -"скоби, напр. gtk:fg[NORMAL], където NORMAL е състоянието. Неуспех при " -"анализира „%s“" +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Поставяне на новите прозорци в центъра на екрана" -#: ../src/ui/theme.c:1308 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:99 msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"Цветовата спецификация на GTK трябва да съдържа квадратна скоба след " -"състоянието, напр. gtk:fg[NORMAL], където NORMAL е състоянието. Неуспех при " -"анализа на „%s“" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "Ако е включено, новите прозорци ще се поставят в центъра на екрана." -#: ../src/ui/theme.c:1319 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "Неуспех при анализа на състоянието „%s“ в цветовата спецификация" +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Включване на експерименталните възможности" -#: ../src/ui/theme.c:1332 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "Неуспех при анализа на цветови компонент „%s“ в цветовата спецификация" - -#: ../src/ui/theme.c:1361 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:108 msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “remote-desktop” — " +"enables remote desktop support. To support remote desktop with screen " +"sharing, “screen-cast” must also be enabled. • “screen-cast” — enables " +"screen cast support." msgstr "" -"Форматът на смесването е „blend/bg_color/fg_color/alpha“, „%s“ не се " -"подчинява на формата" - -#: ../src/ui/theme.c:1372 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "Неуспех при анализира на алфа стойността „%s“ в смесения цвят" +"За да включите експерименталните възможности, добавете ги към списъка. В " +"някои случаи това изисква рестартиране на мениджъра за наслагване. " +"Експерименталните възможности може да не са инсталирани или може да не се " +"настройват. Тази секция не гарантира никаква бъдеща съвместимост. Възможните " +"стойности са: • „scale-monitor-framebuffer“ — обединяване на всички монитори " +"в съвместно графично пространство с логически координати на пикселите, при " +"което се мащабират буферите за кадри, а не съдържанието на прозорците — за " +"управление на мониторите с висока разделителна способност, не изисква " +"рестартиране. • „remote-desktop“ — поддръжка на отдалечено работно място. " +"Отдалеченото работно място изиска и предаването на екрана със „screen-cast“. " +"• „screen-cast“ — предаване на екрана." -#: ../src/ui/theme.c:1382 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "Алфа стойността „%s“ в смесения цвят не е между 0.0 и 1.0" - -#: ../src/ui/theme.c:1429 -#, c-format -msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "" -"Форматът на навиването е „shade/base_color/factor“, „%s“ не съответства на " -"формата" - -#: ../src/ui/theme.c:1440 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "Неуспех при анализа на фактора на навиването „%s“ в цвета за навиване" - -#: ../src/ui/theme.c:1450 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "Факторът на навиване „%s“ в цвета за сянката е отрицателен" - -#: ../src/ui/theme.c:1479 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Неуспех при анализа на цвета „%s“" - -#: ../src/ui/theme.c:1790 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "Изразът за координати съдържа символа „%s“, който не е позволен" - -#: ../src/ui/theme.c:1817 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "" -"Изразът за координати съдържа числото с плаваща запетая „%s“, което не може " -"да бъде анализирано" - -#: ../src/ui/theme.c:1831 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "" -"Изразът за координати съдържа цялото число „%s“, което не може да бъде " -"анализирано" - -#: ../src/ui/theme.c:1953 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "" -"Изразът за координати съдържа непознат оператор в началото на този текст: " -"„%s“" - -#: ../src/ui/theme.c:2010 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "Изразът за координати бе празен или не бе разбран" - -#: ../src/ui/theme.c:2121 ../src/ui/theme.c:2131 ../src/ui/theme.c:2165 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "Изразът за координати дава деление на нула" - -#: ../src/ui/theme.c:2173 -#, c-format -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "" -"Изразът за координати използва оператора mod върху число с плаваща запетая" - -#: ../src/ui/theme.c:2229 -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "" -"Изразът за координати използва оператора „%s“ на място, където се очаква " -"операнд" +#: data/org.gnome.mutter.gschema.xml.in:145 +msgid "Select window from tab popup" +msgstr "Избиране при обхождане чрез изскачащ прозорец" -#: ../src/ui/theme.c:2238 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "" -"Изразът за координати използва оператор на място, където се очаква операнд" +#: data/org.gnome.mutter.gschema.xml.in:150 +msgid "Cancel tab popup" +msgstr "Без изскачащ прозорец при обхождане" -#: ../src/ui/theme.c:2246 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "Изразът за координати завършва с оператор вместо с операнд" +#: data/org.gnome.mutter.gschema.xml.in:155 +msgid "Switch monitor configurations" +msgstr "Смяна на настройките на екрана" -#: ../src/ui/theme.c:2256 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" -"Изразът за координати използва оператора „%c“ след „%c“ без да има операнд " -"между тях" +#: data/org.gnome.mutter.gschema.xml.in:160 +msgid "Rotates the built-in monitor configuration" +msgstr "Завъртане на вградения екран" -#: ../src/ui/theme.c:2407 ../src/ui/theme.c:2452 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "" -"Изразът за координати използва непознатата променлива или константа „%s“" +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Превключване към виртуална графична конзола 1" -#: ../src/ui/theme.c:2506 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "Анализаторът на изрази за координати препълни буфера си." +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Превключване към виртуална графична конзола 2" -#: ../src/ui/theme.c:2535 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "В израза за координати има затваряща скоба без съответна отваряща" +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Превключване към виртуална графична конзола 3" -#: ../src/ui/theme.c:2599 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "В изразът за координати има отваряща скоба без съответна затваряща" +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Превключване към виртуална графична конзола 4" -#: ../src/ui/theme.c:2610 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "Изразът за координати не съдържа нито оператори, нито операнди" +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Превключване към виртуална графична конзола 5" -#: ../src/ui/theme.c:2822 ../src/ui/theme.c:2842 ../src/ui/theme.c:2862 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "Темата съдържа израз, който даде грешка: %s\n" +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Превключване към виртуална графична конзола 6" -#: ../src/ui/theme.c:4533 -#, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" -"За този стил на рамката трябва да се укаже <button function=\"%s\" state=\"%s" -"\" draw_ops=\"нещо си\"/>" +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Превключване към виртуална графична конзола 7" -#: ../src/ui/theme.c:5066 ../src/ui/theme.c:5091 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" -"Липсва <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"нещо си\"/>" +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Превключване към виртуална графична конзола 8" -#: ../src/ui/theme.c:5139 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Неуспех при зареждането на темата „%s“: %s\n" +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Превключване към виртуална графична конзола 9" -#: ../src/ui/theme.c:5275 ../src/ui/theme.c:5282 ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 ../src/ui/theme.c:5303 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "Не е даден елементът <%s> за темата „%s“" +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Превключване към виртуална графична конзола 10" -#: ../src/ui/theme.c:5311 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" -"Няма указан стил на рамката за „%s“ прозорците в тема „%s“. Добавете елемент " -"<window type=\"%s\" style_set=\"нещо си\"/>" +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Превключване към виртуална графична конзола 11" -#: ../src/ui/theme.c:5709 ../src/ui/theme.c:5771 ../src/ui/theme.c:5834 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" -"Константите определени от потребителя трябва да започват с главна буква, а " -"„%s“ не започва така" +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Превключване към виртуална графична конзола 12" -#: ../src/ui/theme.c:5717 ../src/ui/theme.c:5779 ../src/ui/theme.c:5842 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "Константата „%s“ вече е дефинирана" +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "Включване на клавишните комбинации" -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. #. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "Елементът <%s> няма атрибут „%s“" - -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Ред %d, знак %d: %s" - -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "Атрибутът „%s“ се повтаря два пъти в един елемент <%s>" - -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "Атрибутът „%s“ е невалиден за елемента <%s> в този контекст" - -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "„%s“ не може да се анализира като цяло число" - -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "Крайните символи „%s“ в низа „%s“ са неразбираеми" - -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "Цялото число %ld трябва да е положително" - -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "Цялото число %ld е прекалено голямо, максимумът е %d" - -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 +#: src/backends/meta-input-settings.c:2151 #, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "„%s“ не може да се интерпретира като число с плаваща запетая" +msgid "Mode Switch (Group %d)" +msgstr "Смяна на режима (режим %d)" -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "Булевите стойности са или „истина“, или „лъжа“. Не са „%s“" - -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "Ъгълът трябва да е между 0.0 и 360.0, а е %g\n" - -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" -"Алфа трябва да е между 0.0 (пълна прозрачност) и 1.0 (пълна непрозрачност), " -"а е %g\n" - -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"Невалидно увеличение на заглавието „%s“ (трябва да е едно от „xx-small“, „x-" -"small“, „small“,„medium“, „large“, „x-large“, „xx-large“)\n" - -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "Името „%2$s“ на <%1$s> е използвано втори път" +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2174 +msgid "Switch monitor" +msgstr "Смяна на екрана" -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "Родителят „%2$s“ на <%1$s> не е дефиниран" +#: src/backends/meta-input-settings.c:2176 +msgid "Show on-screen help" +msgstr "Показване на помощта на екрана" -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "Геометрията „%2$s“ на <%1$s> не е дефинирана" +#: src/backends/meta-monitor-manager.c:903 +msgid "Built-in display" +msgstr "Вграден екран" -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "<%s> трябва да указва или геометрия, или родител с геометрия" +#: src/backends/meta-monitor-manager.c:926 +msgid "Unknown" +msgstr "Непознат" -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "За да бъде алфа стойността валидна, трябва да е указан фон" +#: src/backends/meta-monitor-manager.c:928 +msgid "Unknown Display" +msgstr "Непознат екран" -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Непознат вид „%s“ на елемента <%s>" - -#: ../src/ui/theme-parser.c:1275 +#. TRANSLATORS: this is a monitor vendor name, followed by a +#. * size in inches, like 'Dell 15"' +#. +#: src/backends/meta-monitor-manager.c:936 #, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "Непознат style_set „%s“ на елемента <%s>" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "Видът прозорци „%s“ вече има установен вид на стила" - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:476 #, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "Елементът <%s> не е позволен под <%s>" - -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" -msgstr "" -"Не може да се указват едновременно и двата размера („button_width“, " -"„button_height“ — височина и широчина на бутоните), и отношението на " -"размерите им — „aspect_ratio“" - -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "Разстоянието „%s“ е неизвестно" - -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "Пропорцията „%s“ е неизвестна" - -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "Границата „%s“ е непозната" - -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "Елементът <%s> няма атрибут „start_angle“ или „from“" - -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "Елементът <%s> няма атрибут „extent_angle“ или „to“" - -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "Стойността „%s“ не може да се анализира като вид градиент" - -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "Непознато запълване „%s“ за елемента <%s>" - -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "Неуспех при анализа на състоянието „%s“ на елемента <%s>" - -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "Неуспех при анализа на сянката „%s“ на елемента <%s>" - -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "Неуспех при анализа на стрелката „%s“ на елемента <%s>" - -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "Няма дефинирани <draw_ops> с име „%s“" - -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "Включването на draw_ops „%s“ тук би предизвикало циклична зависимост" - -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Непозната позиция „%s“ за елемент на рамката" - -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "Стилът на рамката вече има елемент на позицията %s" +"Another compositing manager is already running on screen %i on display “%s”." +msgstr "На екран %i от дисплея „%s“ вече има мениджър за наслагване." -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "Няма дефиниран <draw_ops> с името „%s“" +#: src/core/bell.c:194 +msgid "Bell event" +msgstr "Събитие за звънец" -#: ../src/ui/theme-parser.c:2972 +#: src/core/display.c:608 #, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Непозната функция „%s“ за бутона" +msgid "Failed to open X Window System display “%s”\n" +msgstr "Неуспешно отваряне на дисплея на X Window „%s“\n" -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "" -"Функцията на бутона „%s“ не съществува в тази версия (%d, а трябва да е %d)" +#: src/core/main.c:189 +msgid "Disable connection to session manager" +msgstr "Прекъсване на връзката към мениджъра на сесиите" -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Непознато състояние „%s“ за бутона" +#: src/core/main.c:195 +msgid "Replace the running window manager" +msgstr "Замяна на текущия мениджър на прозорци" -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "Стилът на рамката има бутон за функция %s, състояние %s" +#: src/core/main.c:201 +msgid "Specify session management ID" +msgstr "Определяне на идентификатор за управлението на сесии" -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "„%s“ не е валидна стойност за атрибута фокус" +#: src/core/main.c:206 +msgid "X Display to use" +msgstr "X дисплеят, който да се използва" -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "„%s“ не е валидна стойност за атрибута състояние" +# Ако „запазено“ не се членува, низът се събира на един ред без +# пренасяне. +#: src/core/main.c:212 +msgid "Initialize session from savefile" +msgstr "Инициализиране на сесия от файл със запазено състояние" -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "Не е дефиниран стил на име „%s“" +#: src/core/main.c:218 +msgid "Make X calls synchronous" +msgstr "Извикванията на X да са синхронни" -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "„%s“ не е валидна стойност за атрибута оразмеряване" +#: src/core/main.c:225 +msgid "Run as a wayland compositor" +msgstr "Wayland да е мениджър за наслагване" -#: ../src/ui/theme-parser.c:3147 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" -"Елементът <%s> не трябва да има атрибут „resize“ за състоянията максимизиран/" -"засенчен" +#: src/core/main.c:231 +msgid "Run as a nested compositor" +msgstr "Изпълнение като вложен сървър за изобразяване" -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "" -"Елементът <%s> не трябва да има атрибут „resize“ за състоянието максимизиран" +#: src/core/main.c:239 +msgid "Run as a full display server, rather than nested" +msgstr "Изпълнение като самостоятелен, а не вложен сървър за изобразяване" -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:147 #, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "Вече е указан стил за състояние %s, оразмеряване %s, фокус %s" +msgid "“%s” is not responding." +msgstr "„%s“ не отговаря на съобщенията." -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "Вече е указан стил за състояние %s, фокус %s" +#: src/core/meta-close-dialog-default.c:149 +msgid "Application is not responding." +msgstr "Програмата не отговаря на съобщенията." -#: ../src/ui/theme-parser.c:3294 +#: src/core/meta-close-dialog-default.c:154 msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." msgstr "" -"Не може да има два draw_ops за елемент <piece> (темата е указала атрибут " -"draw_ops и елемент <draw_ops> или два елемента)" +"Можете да изчакате малко, преди изрично да накарате програмата да спре " +"работата си." -#: ../src/ui/theme-parser.c:3332 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Не може да има два draw_ops за елемент <button> (темата е указала атрибут " -"draw_ops и елемент <draw_ops> или два елемента)" +#: src/core/meta-close-dialog-default.c:161 +msgid "_Force Quit" +msgstr "_Принудително спиране" -#: ../src/ui/theme-parser.c:3370 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Не може да има два draw_ops за елемент <menu_icon> (темата е указала атрибут " -"draw_ops и елемент <draw_ops> или два елемента)" +#: src/core/meta-close-dialog-default.c:161 +msgid "_Wait" +msgstr "Из_чакване" -#: ../src/ui/theme-parser.c:3434 +#: src/core/mutter.c:39 #, c-format -msgid "Bad version specification '%s'" -msgstr "Неправилна версия „%s“" - -#: ../src/ui/theme-parser.c:3507 msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" msgstr "" -"Атрибутът „version“ (версия) не може да се използва в in metacity-theme-1." -"xml или metacity-theme-2.xml" +"mutter %s\n" +"Авторски права (C) 2001-%d Havoc Pennington, Red Hat, Inc., и други\n" +"Тази програма (mutter) е свободен софтуер, прегледайте изходния код относно " +"условията за разпространение.\n" +"Тази програма се разпространява БЕЗ НИКАКВИ ГАРАНЦИИ, дори и за ПРОДАЖБА или " +"СЪОТВЕТСТВИЕ С КАКВАТО И ДА Е УПОТРЕБА.\n" -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "Темата изисква версия %s, но най-високата поддържана версия е %d.%d" +#: src/core/mutter.c:53 +msgid "Print version" +msgstr "Отпечатване на версията на програмата" -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "Най-външният елемент в темата трябва да е <metacity_theme>, а не <%s>" +#: src/core/mutter.c:59 +msgid "Mutter plugin to use" +msgstr "Приставка, която да се ползва" -#: ../src/ui/theme-parser.c:3582 +#: src/core/prefs.c:1997 #, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "Елементът <%s> не е разрешен в елементите name/author/date/description" - -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "Елементът <%s> не е позволен в <constant> елемент" +msgid "Workspace %d" +msgstr "Работен плот %d" -#: ../src/ui/theme-parser.c:3599 +#: src/core/screen.c:580 #, c-format msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "Елементът <%s> не е позволен в елемент distance/border/aspect_ratio" - -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "Елементът <%s> не е позволен в елемент с операция за чертане" - -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "Елементът <%s> не е позволен в елемент <%s>" - -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "Няма draw_ops за детайл от рамката" - -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "Няма draw_ops за бутон" - -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "Не е позволен текст в елемента <%s>" - -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "<%s> е указан два пъти за тази тема" - -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Неуспех при намирането на валиден файл за темата %s\n" - -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "_Прозорци" - -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "_Диалогов прозорец" - -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "_Модален диалогов прозорец" - -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "_Инструмент" - -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "_Стартиращ екран" - -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "_Горен док" - -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "_Долен док" - -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "_Ляв док" - -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "_Десен док" - -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "_Всички докове" - -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "Работен _плот" - -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "Отваряне на друг от следните прозорци" - -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "Демонстрационен бутон с икона за отваряне" - -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "Демонстрационен бутон с икона за спиране на програмата" - -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "Това е примерно съобщение в примерен диалогов прозорец" - -#: ../src/ui/theme-viewer.c:328 -#, c-format -msgid "Fake menu item %d\n" -msgstr "Фалшив обект на менюто %d\n" - -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "Прозорец само с граници" - -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "Лента" - -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "Нормален прозорец на програма" - -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "Диалогов прозорец" - -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "Модален диалогов прозорец" - -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "Палитра на инструментите" - -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "Откъсване на менюто" - -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "Граница" - -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "Прилепени модални диалогови прозорци" - -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "Тест за подредбата на бутоните %d" - -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g милисекунди за да изрисува една прозоречна рамка" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." +msgstr "" +"Вече има мениджър на прозорци на дисплей „%s“. Пробвайте да го замените с " +"опцията „--replace“." -#: ../src/ui/theme-viewer.c:813 +#: src/core/screen.c:665 #, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Употреба: metacity-theme-viewer [ИМЕНАТЕМАТА]\n" +msgid "Screen %d on display “%s” is invalid\n" +msgstr "Екранът %d на дисплей „%s“ е невалиден\n" -#: ../src/ui/theme-viewer.c:820 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "Грешка при зареждането на темата: %s\n" +#: src/core/util.c:120 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter е компилиран без поддръжка на подробен режим\n" -#: ../src/ui/theme-viewer.c:826 +#: src/wayland/meta-wayland-tablet-pad.c:563 #, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "Темата „%s“ е заредена за %g секунди\n" - -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "Нормален шрифт на заглавието" - -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "Малък шрифт на заглавието" - -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "Голям шрифт на заглавието" +msgid "Mode Switch: Mode %d" +msgstr "Смяна на режима: режим %d" -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "Изглед на бутоните" - -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "Статистика" - -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "Тук се поставя заглавието на прозорците" - -#: ../src/ui/theme-viewer.c:1047 -#, c-format +#: src/x11/session.c:1815 msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." msgstr "" -"Изчертаха се %d кадъра за %g секунди от страна на клиента (по %g милисекунди " -"на кадър) и %g секунди нормално време, което включва ресурси от страна на " -"сървъра X (по %g милисекунди на кадър)\n" - -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "" -"изразът за проверка на разположението върна TRUE, но зададе състояние за " -"грешка" - -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "" -"изразът за проверка на разположението върна FALSE, но не зададе състояние за " -"грешка" - -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "Очакваше се грешка, но не беше дадена никаква" - -#: ../src/ui/theme-viewer.c:1274 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "Очакваше се грешка %d, но беше дадена %d" - -#: ../src/ui/theme-viewer.c:1280 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "Не се очакваше грешка, но беше върната една: %s" - -#: ../src/ui/theme-viewer.c:1284 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "стойността на x бе %d, а се очакваше %d" - -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "стойността y бе %d, а се очакваше %d" +"Тези прозорци не поддържат операцията по записване на текущото състояние и " +"ще трябва да се стартират ръчно при следващото ви влизане." -#: ../src/ui/theme-viewer.c:1352 +#: src/x11/window-props.c:559 #, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "%d координатен израз обработен за %g секунди (%g секунди средно)\n" +msgid "%s (on %s)" +msgstr "%s (от %s)" diff --git a/po/bn.po b/po/bn.po index d45d60687..3c9cd8810 100644 --- a/po/bn.po +++ b/po/bn.po @@ -13,6 +13,7 @@ msgstr "" "PO-Revision-Date: 2005-10-03 01:16+0600\n" "Last-Translator: Mahay Alam Khan <makl10n@yahoo.com>\n" "Language-Team: Bengali <gnome-trans@bengalinux.org>\n" +"Language: bn\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" diff --git a/po/bn_IN.po b/po/bn_IN.po index 590ccd965..36e97a209 100644 --- a/po/bn_IN.po +++ b/po/bn_IN.po @@ -8,1785 +8,901 @@ # Samia Niamatullah <mailsamia2001@yahoo.com>, 2005. # Runa Bhattacharjee <runabh@gmail.com>, 2006. # Runa Bhattacharjee <runab@redhat.com>, 2009. +# Sayak Sarkar <sayak.bugsmith@gmail.com>, 2012. +# sray <sray@redhat.com>, 2013, 2014. #zanata. msgid "" msgstr "" "Project-Id-Version: bn_IN\n" -"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=metacity&component=general\n" -"POT-Creation-Date: 2009-02-05 16:08+0000\n" -"PO-Revision-Date: 2009-03-10 22:35+0530\n" -"Last-Translator: Runa Bhattacharjee <runab@redhat.com>\n" -"Language-Team: Bengali INDIA <discuss@lists.ankur.org.in>\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=mutter&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2014-09-24 22:01+0000\n" +"PO-Revision-Date: 2014-09-25 13:56+0000\n" +"Last-Translator: \n" +"Language-Team: Bengali (India) <kde-i18n-doc@kde.org>\n" +"Language: bn_IN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: KBabel 1.11.4\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "\n" "\n" +"X-Generator: Lokalize 1.5\n" -#: ../src/50-metacity-desktop-key.xml.in.h:1 -#| msgid "top" -msgid "Desktop" -msgstr "ডেস্কটপ" +#: ../data/50-mutter-navigation.xml.in.h:1 +msgid "Navigation" +msgstr "ন্যাভিগেশন" -#: ../src/50-metacity-key.xml.in.h:1 -#| msgid "Window manager: " -msgid "Window Management" -msgstr "উইন্ডো পরিচালন ব্যবস্থা" - -#: ../src/core/core.c:206 -#, c-format -msgid "Unknown window information request: %d" -msgstr "উইন্ডোর তথ্য সম্বন্ধে অজানা অনুরোধ: %d" - -#: ../src/core/delete.c:70 ../src/core/delete.c:97 -#: ../src/ui/metacity-dialog.c:50 ../src/ui/theme-parser.c:522 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "পূর্ণসংখ্যা রূপে \"%s\" পার্স করতে ব্যর্থ" - -#: ../src/core/delete.c:77 ../src/core/delete.c:104 -#: ../src/ui/metacity-dialog.c:57 ../src/ui/theme-parser.c:531 -#: ../src/ui/theme-parser.c:586 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "অন্তিম অংশের \"%s\" অক্ষরগুলি \"%s\" পংক্তির মধ্যে বোধগম্য নয়" - -#: ../src/core/delete.c:135 -#, c-format -msgid "Failed to parse message \"%s\" from dialog process\n" -msgstr "ডায়লগের প্রসেস থেকে প্রাপ্ত \"%s\" বার্তা পার্স করতে ব্যর্থ\n" - -#: ../src/core/delete.c:253 -#, c-format -msgid "Error reading from dialog display process: %s\n" -msgstr "ডায়লগ প্রদর্শনের প্রক্রিয়া থেকে পড়তে সমস্যা : %s\n" - -#: ../src/core/delete.c:336 -#, c-format -msgid "Error launching metacity-dialog to ask about killing an application: %s\n" -msgstr "" -"অ্যাপ্লিকেশন বন্ধ (kill) করার সম্মতি জানতে ব্যবহৃত metacity-dialog প্রদর্শন করতে " -"সমস্যা: %s\n" - -#: ../src/core/delete.c:445 -#, c-format -msgid "Failed to get hostname: %s\n" -msgstr "হোস্ট-নেম প্রাপ্ত করতে ব্যর্থ: %s\n" - -#: ../src/core/display.c:256 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "কম্পোসিটিং-র জন্য আবশ্যক %s এক্সটেনশন অনুপস্থিত" - -#: ../src/core/display.c:334 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "X উইন্ডো সিস্টেম প্রদর্শন খুলতে ব্যর্থ '%s'\n" - -#: ../src/core/errors.c:272 -#, c-format -msgid "" -"Lost connection to the display '%s';\n" -"most likely the X server was shut down or you killed/destroyed\n" -"the window manager.\n" -msgstr "" -"ডিসপ্লে '%s'-র সাথে সংযোগ বিচ্ছিন্ন হয়েছে;\n" -"সম্ভবত X সার্ভার বন্ধ করা হয়েছে অথবা উইন্ডো পরিচালন ব্যবস্থা kill/বন্ধ\n" -"করা হয়েছে।\n" - -#: ../src/core/errors.c:279 -#, c-format -msgid "Fatal IO error %d (%s) on display '%s'.\n" -msgstr "গুরুতর IO সমস্যা %d (%s) '%s' প্রদর্শনে।\n" - -# " উইন্ডো অবৃহদায়ত কর" -#: ../src/core/keybindings.c:680 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "একটি পৃথক প্রোগ্রাম দ্বারা বর্তমানে %s-কি, %x বাইন্ডিং সহ ব্যবহৃত হচ্ছে\n" - -#. Displayed when a keybinding which is -#. * supposed to launch a program fails. -#. -#: ../src/core/keybindings.c:2294 -#, c-format -#| msgid "" -#| "There was an error running \"%s\":\n" -#| "%s." -msgid "" -"There was an error running <tt>%s</tt>:\n" -"\n" -"%s" -msgstr "" -"<tt>%s</tt> সঞ্চালনে সমস্যা:\n" -"\n" -"%s" - -#: ../src/core/keybindings.c:2381 -#, c-format -msgid "No command %d has been defined.\n" -msgstr "%d কমান্ড ব্যাখ্যা করা হয়নি।\n" - -#: ../src/core/keybindings.c:3335 -#, c-format -msgid "No terminal command has been defined.\n" -msgstr "টার্মিনালে ব্যবহারযোগ্য কোনো কমান্ড ব্যাখ্যা করা হয়নি।\n" - -#: ../src/core/main.c:116 -#, c-format -#| msgid "" -#| "metacity %s\n" -#| "Copyright (C) 2001-2002 Havoc Pennington, Red Hat, Inc., and others\n" -#| "This is free software; see the source for copying conditions.\n" -#| "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -#| "PARTICULAR PURPOSE.\n" -msgid "" -"metacity %s\n" -"Copyright (C) 2001-2008 Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" -"metacity %s\n" -"স্বত্বাধিকার (C) ২০০১-২০০৮ হ্যাভক পেনিংটন, Red Hat, Inc., ও অন্যান্যদের\n" -"এটি একটি মুক্ত সফ্টওয়্যার; পুনব্যবহারের নিয়মাবলীর জন্য সোর্সের মধ্যে উপলব্ধ নথিপত্র দেখুন।\n" -"এর কোনো ওয়ারেন্টি উপলব্ধ নেই; বাণিজ্যিক ও কোনো সুনির্দিষ্ট কর্ম সাধনের জন্যও নয়।\n" - -#: ../src/core/main.c:253 -msgid "Disable connection to session manager" -msgstr "সেশান পরিচালন ব্যবস্থার সাথে সংযোগ বিচ্ছিন্ন করা হবে" - -#: ../src/core/main.c:259 -msgid "Replace the running window manager with Metacity" -msgstr "বর্তমানে ব্যবহৃত উইন্ডো পরিচালন ব্যবস্থার পরিবর্তে Metacity প্রয়োগ করা হবে" - -#: ../src/core/main.c:265 -msgid "Specify session management ID" -msgstr "সেশান পরিচালনার ID উল্লেখ করুন" - -#: ../src/core/main.c:270 -msgid "X Display to use" -msgstr "ব্যবহারের জন্য এক্স ডিসপ্লে" - -#: ../src/core/main.c:276 -msgid "Initialize session from savefile" -msgstr "সংরক্ষণ ফাইল থেকে সেশন চালু করো" - -#: ../src/core/main.c:282 -msgid "Print version" -msgstr "প্রিন্ট সংস্করণ" - -#: ../src/core/main.c:288 -msgid "Make X calls synchronous" -msgstr "X-র কল সিঙ্ক্রোনাস করা হবে" - -#: ../src/core/main.c:294 -msgid "Turn compositing on" -msgstr "কম্পোসিটিং ব্যবস্থা চালু করুন" - -#: ../src/core/main.c:300 -msgid "Turn compositing off" -msgstr "কম্পোসিটিং ব্যবস্থা বন্ধ করুন" - -#: ../src/core/main.c:478 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "থীম এর ডিরেক্টরি স্ক্যান করতে ব্যর্থ: %s\n" - -#: ../src/core/main.c:494 -#, c-format -#| msgid "" -#| "Could not find a theme! Be sure %s exists and contains the usual themes." -msgid "Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "কোনো থিম খুঁজে পাওয়া যায়নি! অনুগ্রহ করে পরীক্ষা করুন %s উপস্থিত আছে কি না ও এর মধ্যে সাধারণ থিমগুলি অন্তর্ভুক্ত কি না।\n" - -#: ../src/core/main.c:550 -#, c-format -msgid "Failed to restart: %s\n" -msgstr "আবার চালু করতে পারলাম না: %s\n" - -#. -#. * We found it, but it was invalid. Complain. -#. * -#. * FIXME: This replicates the original behaviour, but in the future -#. * we might consider reverting invalid keys to their original values. -#. * (We know the old value, so we can look up a suitable string in -#. * the symtab.) -#. * -#. * (Empty comment follows so the translators don't see this.) -#. -#. -#: ../src/core/prefs.c:505 ../src/core/prefs.c:660 -#, c-format -msgid "GConf key '%s' is set to an invalid value\n" -msgstr "GConf-কি \"%s\"'র মান বৈধ নয়\n" - -#: ../src/core/prefs.c:586 ../src/core/prefs.c:829 -#, c-format -#| msgid "%d stored in GConf key %s is out of range 0 to %d\n" -msgid "%d stored in GConf key %s is out of range %d to %d\n" -msgstr "%d মান যা GConf-কি %s-র মধ্যে সংরক্ষিত রয়েছে, %d থেকে %d-র সীমাবহির্ভূত\n" - -#: ../src/core/prefs.c:630 ../src/core/prefs.c:707 ../src/core/prefs.c:755 -#: ../src/core/prefs.c:819 ../src/core/prefs.c:1112 ../src/core/prefs.c:1128 -#: ../src/core/prefs.c:1145 ../src/core/prefs.c:1161 -#, c-format -msgid "GConf key \"%s\" is set to an invalid type\n" -msgstr "GConf-কি \"%s\"'র ধরন বৈধ নয়\n" - -#: ../src/core/prefs.c:1231 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"ক্ষতিগ্রস্ত অ্যাপ্লিকেশনের ত্রুটি অগ্রাহ্য করার প্রণালী নিষ্ক্রিয় করা হয়েছে। কয়েকটি " -"অ্যাপ্লিকেশন সম্ভবত সঠিকরূপে চালানো সম্ভব হবে না।\n" - -#: ../src/core/prefs.c:1302 -#, c-format -msgid "Could not parse font description \"%s\" from GConf key %s\n" -msgstr "\"%s\" ফন্টের বিবরণ GConf-কি %s থেকে পার্স করতে ব্যর্থ\n" - -#: ../src/core/prefs.c:1364 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "কনফিগারেশন ডাটাবেসের মধ্যে উপস্থিত \"%s\" মাউস বাটন পরিবর্তকের জন্য বৈধ মান নয়\n" - -#: ../src/core/prefs.c:1782 -#, c-format -msgid "Error setting number of workspaces to %d: %s\n" -msgstr "কর্মক্ষেত্রের সংখ্যা %d রূপে নির্ধারণ করতে ব্যর্থ: %s\n" - -#: ../src/core/prefs.c:1971 ../src/core/prefs.c:2474 -#, c-format -msgid "Workspace %d" -msgstr "কর্মক্ষেত্র %d" - -#: ../src/core/prefs.c:2001 ../src/core/prefs.c:2179 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "" -"কনফিগারেশন ডাটাবেসের মধ্যে উপলব্ধ \"%s\", \"%s\" কি-বাইন্ডিং'র ক্ষেত্রে বৈধ মান " -"নয়\n" - -#: ../src/core/prefs.c:2555 -#, c-format -msgid "Error setting name for workspace %d to \"%s\": %s\n" -msgstr "কর্মক্ষেত্র %d'র নাম \"%s\" রূপে নির্ধারণ করতে ব্যর্থ: %s\n" - -#: ../src/core/prefs.c:2753 -#, c-format -#| msgid "Error setting name for workspace %d to \"%s\": %s\n" -msgid "Error setting compositor status: %s\n" -msgstr "কম্পোসিটারের অবস্থা নির্ধারণ করতে ত্রুটি: %s\n" - -#: ../src/core/screen.c:350 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "পর্দা %d (ডিসপ্লে '%s') বৈধ নয়\n" - -#: ../src/core/screen.c:366 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"পর্দা %d'র (\"%s\" ডিসপ্লে) ক্ষেত্রে একটি উইন্ডো পরিচালনব্যবস্থা বর্তমানে উপস্তিত " -"রয়েছে; বর্তমানে উইন্ডো পরিচালন ব্যবস্থা পরিবর্তন করতে --replace বিকল্প প্রয়োগ করুন।\n" - -#: ../src/core/screen.c:393 -#, c-format -msgid "Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "" -"পর্দা %d (ডিসপ্লে \"%s\")'র মধ্যে উইন্ডো পরিচালন ব্যবস্থার নির্বাচিত অংশ গ্রহণ করতে " -"ব্যর্থ\n" - -#: ../src/core/screen.c:451 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "পর্দা %d'র ( \"%s\" ডিসপ্লে) ক্ষেত্রে একটি উইন্ডো পরিচালন ব্যবস্থা উপস্থিত রয়েছে\n" - -#: ../src/core/screen.c:661 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "পর্দা %d (ডিসপ্লে \"%s\") মুক্ত করতে ব্যর্থ\n" - -#. Translators: Please don't translate "Control", "Shift", etc, since these -#. * are hardcoded (in gtk/gtkaccelgroup.c; it's not metacity's fault). -#. * "disabled" must also stay as it is. -#. -#: ../src/core/schema-bindings.c:169 -#| msgid "" -#| "The keybinding used to close a window. The format looks like \"<" -#| "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#| "liberal and allows lower or upper case, and also abbreviations such as " -#| "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#| "special string \"disabled\", then there will be no keybinding for this " -#| "action." -msgid "" -"The format looks like \"<Control>a\" or <Shift><Alt>F1\".\n" -"\n" -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -"special string \"disabled\", then there will be no keybinding for this " -"action." -msgstr "" -"যে কি-বাইন্ডিং দ্বারা উইন্ডো বন্ধ করা হবে। \"<Control>a\" অথবা <Shift><Alt>F1\" বিন্যাস ব্যবহৃত হবে। \n" -"\n" -"পার্সার হরফের ছাঁদ সম্পর্কে সচেতন নয় এবং প্রয়োজনে \"<Ctl>\" ও \"<Ctrl>\"-র অনুরূপ সংক্ষিপ্ত রূপও ব্যবহার করা " -"যাবে। বিকল্পের ক্ষেত্রে বিশেষ পংক্তি \"disabled\" প্রয়োগ করা হলে এই কর্মের জন্য কোনো কি-বাইন্ডিং ব্যবহার করা হবে না।" - -#: ../src/core/schema-bindings.c:177 -#| msgid "" -#| "The keybinding used to close a window. The format looks like \"<" -#| "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#| "liberal and allows lower or upper case, and also abbreviations such as " -#| "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#| "special string \"disabled\", then there will be no keybinding for this " -#| "action." -msgid "" -"The format looks like \"<Control>a\" or <Shift><Alt>F1\".\n" -"\n" -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -"special string \"disabled\", then there will be no keybinding for this " -"action.\n" -"\n" -"This keybinding may be reversed by holding down the \"shift\" key; " -"therefore, \"shift\" cannot be one of the keys it uses." -msgstr "" -"যে কি-বাইন্ডিং দ্বারা উইন্ডো বন্ধ করা হবে। \"<Control>a\" অথবা <Shift><Alt>F1\" বিন্যাস ব্যবহৃত হবে। \n" -"\n" -"পার্সার হরফের ছাঁদ সম্পর্কে সচেতন নয় এবং প্রয়োজনে \"<Ctl>\" ও \"<Ctrl>\"-র অনুরূপ সংক্ষিপ্ত রূপও ব্যবহার করা " -"যাবে। বিকল্পের ক্ষেত্রে বিশেষ পংক্তি \"disabled\" প্রয়োগ করা হলে এই কর্মের জন্য কোনো কি-বাইন্ডিং ব্যবহার করা হবে না।\n" -"\n" -"\"shift\" কি টেপা হলে কি-বাইন্ডিংগুলির বিপরীত ব্যবহার করা হবে; " -"অর্থাৎ, \"shift\" কি এই ক্ষেত্রে ব্যবহার করা যাবে না।" - -#: ../src/core/session.c:837 ../src/core/session.c:844 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "ডিরেক্টরি '%s' নির্মাণ করতে ব্যর্থ: %s\n" - -#: ../src/core/session.c:854 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "লেখার উদ্দেশ্যে সেশান ফাইল '%s' খুলতে ব্যর্থ: %s\n" - -#: ../src/core/session.c:995 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "সেশান ফাইল '%s' লিখতে ব্যর্থ: %s\n" - -#: ../src/core/session.c:1000 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "সেশান ফাইল '%s' বন্ধ করতে ব্যর্থ: %s\n" - -#. oh, just give up -#: ../src/core/session.c:1093 -#, c-format -msgid "Failed to read saved session file %s: %s\n" -msgstr "সংরক্ষিত সেশান ফাইল %s পড়তে ব্যর্থ: %s\n" - -#: ../src/core/session.c:1132 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "সংরক্ষিত সেশান ফাইল পার্স করতে ব্যর্থ: %s\n" +#: ../data/50-mutter-navigation.xml.in.h:2 +msgid "Move window to workspace 1" +msgstr "উইন্ডো কর্মক্ষেত্র ১ এ সরান" -#: ../src/core/session.c:1181 -#, c-format -msgid "<metacity_session> attribute seen but we already have the session ID" -msgstr "<metacity_session> বৈশিষ্ট্য প্রদর্শিত কিন্তু সেশান ID বর্তমানে উপস্থিত রয়েছে" +#: ../data/50-mutter-navigation.xml.in.h:3 +msgid "Move window to workspace 2" +msgstr "উইন্ডো কর্মক্ষেত্র ২ এ সরান" -#: ../src/core/session.c:1194 ../src/core/session.c:1269 -#: ../src/core/session.c:1301 ../src/core/session.c:1373 -#: ../src/core/session.c:1433 -#, c-format -#| msgid "Unknown attribute %s on <window> element" -msgid "Unknown attribute %s on <%s> element" -msgstr "অজানা বৈশিষ্ট্য %s, <%s> স্বত্বায় চিহ্নিত হয়েছে" +#: ../data/50-mutter-navigation.xml.in.h:4 +msgid "Move window to workspace 3" +msgstr "উইন্ডো কর্মক্ষেত্র ৩ এ সরান" -#: ../src/core/session.c:1211 -#, c-format -msgid "nested <window> tag" -msgstr "নেস্টেড <window> ট্যাগ" +#: ../data/50-mutter-navigation.xml.in.h:5 +msgid "Move window to workspace 4" +msgstr "উইন্ডো কর্মক্ষেত্র ৪ এ সরান" -#: ../src/core/session.c:1453 -#, c-format -msgid "Unknown element %s" -msgstr "অজানা স্বত্বা %s" +#: ../data/50-mutter-navigation.xml.in.h:6 +#| msgid "Move window to workspace 1" +msgid "Move window to last workspace" +msgstr "উইন্ডো শেষ কর্মক্ষেত্র এ সরান" -#: ../src/core/session.c:1879 -#, c-format -msgid "" -"Error launching metacity-dialog to warn about apps that don't support " -"session management: %s\n" -msgstr "" -"সেশান পরিচালনব্যবস্থা সমর্থন করতে ব্যর্থ অ্যাপ্লিকেশন সম্পরকে সূচিত করে ব্যবহৃথ " -"metacity-dialog: %s\n" +#: ../data/50-mutter-navigation.xml.in.h:7 +msgid "Move window one workspace to the left" +msgstr "উইন্ডো বাম দিকে এক কর্মক্ষেত্র সরান" -#: ../src/core/util.c:101 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "ডিবাগ লগ খুলতে ব্যর্থ: %s\n" +#: ../data/50-mutter-navigation.xml.in.h:8 +msgid "Move window one workspace to the right" +msgstr "উইন্ডো ডান দিকে এক কর্মক্ষেত্র সরান" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "fdopen() লগ ফাইল %s খুলতে ব্যর্থ: %s\n" +#: ../data/50-mutter-navigation.xml.in.h:9 +msgid "Move window one workspace up" +msgstr "উইন্ডো এক কর্মক্ষেত্র উপরে সরান" -#: ../src/core/util.c:117 -#, c-format -msgid "Opened log file %s\n" -msgstr "লগ ফাইল %s খোলা হয়েছে\n" +#: ../data/50-mutter-navigation.xml.in.h:10 +msgid "Move window one workspace down" +msgstr "উইন্ডো এক কর্মক্ষেত্র নীচে সরান" -#: ../src/core/util.c:136 ../src/tools/metacity-message.c:176 -#, c-format -msgid "Metacity was compiled without support for verbose mode\n" -msgstr "ভার্বোস মোডের সমর্থন অন্তর্ভুক্ত না করে Metacity কম্পাইল করা হয়েছে\n" +#: ../data/50-mutter-navigation.xml.in.h:11 +#| msgid "Move window one workspace to the left" +msgid "Move window one monitor to the left" +msgstr "উইন্ডো বাম দিকে এক মনিটর সরান" -#: ../src/core/util.c:236 -msgid "Window manager: " -msgstr "উইন্ডো পরিচালন ব্যবস্থা: " +#: ../data/50-mutter-navigation.xml.in.h:12 +#| msgid "Move window one workspace to the right" +msgid "Move window one monitor to the right" +msgstr "উইন্ডো ডান দিকে এক মনিটর সরান" -#: ../src/core/util.c:388 -msgid "Bug in window manager: " -msgstr "উইন্ডো পরিচালনব্যবস্থা সংক্রান্ত সমস্যা: " +#: ../data/50-mutter-navigation.xml.in.h:13 +#| msgid "Move window one workspace up" +msgid "Move window one monitor up" +msgstr "উইন্ডো এক মনিটর উপরে সরান" -#: ../src/core/util.c:421 -msgid "Window manager warning: " -msgstr "উইন্ডো পরিচালন ব্যবস্থা সংক্রান্ত সতর্কবার্তা: " +#: ../data/50-mutter-navigation.xml.in.h:14 +#| msgid "Move window one workspace down" +msgid "Move window one monitor down" +msgstr "উইন্ডো এক মনিটর নীচে সরান" + +#: ../data/50-mutter-navigation.xml.in.h:15 +msgid "Switch applications" +msgstr "অ্যাপ্লিকেশনগুলি স্যুইচ করুন" + +#: ../data/50-mutter-navigation.xml.in.h:16 +#| msgid "Switch applications" +msgid "Switch to previous application" +msgstr "পূর্ববর্তী অ্যাপ্লিকেশনে স্যুইচ করুন" + +#: ../data/50-mutter-navigation.xml.in.h:17 +msgid "Switch windows" +msgstr "উইন্ডোগুলি স্যুইচ করুন" + +#: ../data/50-mutter-navigation.xml.in.h:18 +#| msgid "Switch windows" +msgid "Switch to previous window" +msgstr "পূর্ববর্তী উইন্ডোতে স্যুইচ করুন" + +#: ../data/50-mutter-navigation.xml.in.h:19 +msgid "Switch windows of an application" +msgstr "কোনো অ্যাপ্লিকেশনের উইন্ডোগুলি স্যুইচ করুন" + +#: ../data/50-mutter-navigation.xml.in.h:20 +#| msgid "Switch windows of an application" +msgid "Switch to previous window of an application" +msgstr "অ্যাপ্লিকেশনের পূর্ববর্তী উইন্ডোতে স্যুইচ করুন" + +#: ../data/50-mutter-navigation.xml.in.h:21 +msgid "Switch system controls" +msgstr "সিস্টেম কন্ট্রোলগুলি স্যুইচ করুন" + +#: ../data/50-mutter-navigation.xml.in.h:22 +#| msgid "Switch system controls" +msgid "Switch to previous system control" +msgstr "পূর্ববর্তী সিস্টেম কন্ট্রোলে স্যুইচ করুন" + +#: ../data/50-mutter-navigation.xml.in.h:23 +msgid "Switch windows directly" +msgstr "উইন্ডোগুলি সরাসরি স্যুইচ করুন" + +#: ../data/50-mutter-navigation.xml.in.h:24 +msgid "Switch directly to previous window" +msgstr "সরাসরি পূর্ববর্তী উইন্ডোতে স্যুইচ করুন" + +#: ../data/50-mutter-navigation.xml.in.h:25 +msgid "Switch windows of an app directly" +msgstr "কোনো অ্যাপ্লিকেশনের উইন্ডোগুলি সরাসরি স্যুইচ করুন" + +#: ../data/50-mutter-navigation.xml.in.h:26 +#| msgid "Switch windows of an application" +msgid "Switch directly to previous window of an app" +msgstr "সরাসরি কোনো অ্যাপ্লিকেশনের পূর্ববর্তী উইন্ডোতে স্যুইচ করুন" + +#: ../data/50-mutter-navigation.xml.in.h:27 +msgid "Switch system controls directly" +msgstr "সিস্টেম কন্ট্রোলগুলি সরাসরি স্যুইচ করুন" + +#: ../data/50-mutter-navigation.xml.in.h:28 +#| msgid "Switch system controls" +msgid "Switch directly to previous system control" +msgstr "সরাসরি পূর্ববর্তী সিস্টেম কন্ট্রোলে স্যুইচ করুন" + +#: ../data/50-mutter-navigation.xml.in.h:29 +msgid "Hide all normal windows" +msgstr "সমস্ত সাধারণ উইন্ডো লুকান" + +#: ../data/50-mutter-navigation.xml.in.h:30 +msgid "Switch to workspace 1" +msgstr "কর্মক্ষেত্র ১ এ স্যুইচ করুন" -#: ../src/core/util.c:449 -msgid "Window manager error: " -msgstr "উইন্ডো পরিচালন ব্যবস্থা সংক্রান্ত ত্রুটি: " +#: ../data/50-mutter-navigation.xml.in.h:31 +msgid "Switch to workspace 2" +msgstr "কর্মক্ষেত্র ২ এ স্যুইচ করুন" -#. Translators: This is the title used on dialog boxes -#. eof all-keybindings.h -#: ../src/core/util.c:577 ../src/metacity.desktop.in.h:1 -#: ../src/metacity-wm.desktop.in.h:1 -msgid "Metacity" -msgstr "Metacity" +#: ../data/50-mutter-navigation.xml.in.h:32 +msgid "Switch to workspace 3" +msgstr "কর্মক্ষেত্র ৩ এ স্যুইচ করুন" -#. first time through -#: ../src/core/window.c:5626 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"উইন্ডো %s দ্বারা ICCCM'এ নির্ধারিত WM_CLIENT_LEADER উইন্ডোর পরিবর্তে নিজের উপর " -"SM_CLIENT_ID নির্ধারিত হয়েছে।\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:6191 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %" -"d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:33 +msgid "Switch to workspace 4" +msgstr "কর্মক্ষেত্র ৪ এ স্যুইচ করুন" -#: ../src/core/window-props.c:260 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "অ্যাপ্লিকেশন দ্বারা ভুল _NET_WM_PID %lu নির্ধারিত হয়েছে\n" +#: ../data/50-mutter-navigation.xml.in.h:34 +#| msgid "Switch to workspace 1" +msgid "Switch to last workspace" +msgstr "শেষ কর্মক্ষেত্রে স্যুইচ করুন" -#: ../src/core/window-props.c:377 -#, c-format -msgid "%s (on %s)" -msgstr "%s (%s'র উপর)" +#: ../data/50-mutter-navigation.xml.in.h:35 +msgid "Move to workspace left" +msgstr "বাম দিকের কর্মক্ষেত্রে সরান" -#: ../src/core/window-props.c:1358 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "অবৈধ WM_TRANSIENT_FOR উইন্ডো 0x%lx, %s'র জন্য নির্ধারিত হয়েছে।\n" +#: ../data/50-mutter-navigation.xml.in.h:36 +msgid "Move to workspace right" +msgstr "ডান দিকের কর্মক্ষেত্রে সরান" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:37 +msgid "Move to workspace above" +msgstr "উপরের দিকের কর্মক্ষেত্রে সরান" -#: ../src/core/xprops.c:401 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "%s বৈশিষ্ট্যটি 0x%lx উইন্ডোর উপর উপস্থিত ও এর মধ্যে অবৈধ UTF-8 অক্ষর অন্তর্ভুক্ত রয়েছে\n" +#: ../data/50-mutter-navigation.xml.in.h:38 +msgid "Move to workspace below" +msgstr "নীচের দিকের কর্মক্ষেত্রে সরান" -# FIXME msgstr "%s বিশেষত্বটি জানালা 0x%lx -তে অন্যায্য UTF-8 আছে\n -#: ../src/core/xprops.c:484 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "%s বৈশিষ্ট্যটি 0x%lx উইন্ডোর উপর উপস্থিত ও এর তালিকায় %d সংখ্যক বস্তুর মধ্যে অবৈধ UTF-8 অক্ষর অন্তর্ভুক্ত রয়েছে\n" +#: ../data/50-mutter-system.xml.in.h:1 +msgid "System" +msgstr "সিস্টেম" -#: ../src/include/all-keybindings.h:88 -msgid "Switch to workspace 1" -msgstr "কর্মক্ষেত্র ১'এ পরিবর্তন করুন" +#: ../data/50-mutter-system.xml.in.h:2 +msgid "Show the run command prompt" +msgstr "চালনা কম্যান্ড প্রমপ্ট দেখান" -#: ../src/include/all-keybindings.h:90 -msgid "Switch to workspace 2" -msgstr "কর্মক্ষেত্র ১৩'এ পরিবর্তন করুন" +#: ../data/50-mutter-system.xml.in.h:3 +msgid "Show the activities overview" +msgstr "ক্রিয়াকলাপের পূর্বরূপ দেখান" -#: ../src/include/all-keybindings.h:92 -msgid "Switch to workspace 3" -msgstr "কর্মক্ষেত্র ৩'এ পরিবর্তন করুন" +#: ../data/50-mutter-windows.xml.in.h:1 +msgid "Windows" +msgstr "উইন্ডোগুলি" -#: ../src/include/all-keybindings.h:94 -msgid "Switch to workspace 4" -msgstr "কর্মক্ষেত্র ৪'এ পরিবর্তন করুন" - -#: ../src/include/all-keybindings.h:96 -msgid "Switch to workspace 5" -msgstr "কর্মক্ষেত্র ৫'এ পরিবর্তন করুন" - -#: ../src/include/all-keybindings.h:98 -msgid "Switch to workspace 6" -msgstr "কর্মক্ষেত্র ৬'এ পরিবর্তন করুন" - -#: ../src/include/all-keybindings.h:100 -msgid "Switch to workspace 7" -msgstr "কর্মক্ষেত্র ৭'এ পরিবর্তন করুন" - -#: ../src/include/all-keybindings.h:102 -msgid "Switch to workspace 8" -msgstr "কর্মক্ষেত্র ৮'এ পরিবর্তন করুন" - -#: ../src/include/all-keybindings.h:104 -msgid "Switch to workspace 9" -msgstr "কর্মক্ষেত্র ৯'এ পরিবর্তন করুন" - -#: ../src/include/all-keybindings.h:106 -msgid "Switch to workspace 10" -msgstr "কর্মক্ষেত্র ১'এ পরিবর্তন করুন" - -#: ../src/include/all-keybindings.h:108 -msgid "Switch to workspace 11" -msgstr "কর্মক্ষেত্র ১১'এ পরিবর্তন করুন" - -#: ../src/include/all-keybindings.h:110 -msgid "Switch to workspace 12" -msgstr "কর্মক্ষেত্র ১২'এ পরিবর্তন করুন" - -#: ../src/include/all-keybindings.h:122 -#| msgid "Switch to workspace on the left" -msgid "Switch to workspace on the left of the current workspace" -msgstr "বাঁদিকের পার্শ্ববর্তী কর্মক্ষেত্রে পরিবর্তন করুন" - -#: ../src/include/all-keybindings.h:126 -#| msgid "Switch to workspace on the right" -msgid "Switch to workspace on the right of the current workspace" -msgstr "ডানদিকের পার্শ্ববর্তী কর্মক্ষেত্রে পরিবর্তন করুন" - -#: ../src/include/all-keybindings.h:130 -#| msgid "Switch to workspace above this one" -msgid "Switch to workspace above the current workspace" -msgstr "ঊর্ধস্থ কর্মক্ষেত্রে পরিবর্তন করুন" - -#: ../src/include/all-keybindings.h:134 -#| msgid "Switch to workspace below this one" -msgid "Switch to workspace below the current workspace" -msgstr "নিম্নস্থিত কর্মক্ষেত্রে পরিবর্তন করুন" - -#: ../src/include/all-keybindings.h:150 -#| msgid "Move between windows of an application with popup" -msgid "Move between windows of an application, using a popup window" -msgstr "অ্যাপ্লিকেশনের উইন্ডোগুলির মধ্যে পপ-আপ উইন্ডো প্রয়োগ করে স্থান পরিবর্তন করুন" - -#: ../src/include/all-keybindings.h:153 -#| msgid "Move backwards between windows of an application with popup" -msgid "Move backward between windows of an application, using a popup window" -msgstr "অ্যাপ্লিকেশনের উইন্ডোগুলির মধ্যে পপ-আপ উইন্ডো প্রয়োগ করে বিপরীতদিকে স্থান পরিবর্তন করুন" - -#: ../src/include/all-keybindings.h:157 -#| msgid "Move between windows with popup" -msgid "Move between windows, using a popup window" -msgstr "উইন্ডোগুলির মধ্যে পপ-আপ উইন্ডো প্রয়োগ করে স্থান পরিবর্তন করুন" - -#: ../src/include/all-keybindings.h:160 -#| msgid "Move focus backwards between windows using popup display" -msgid "Move backward between windows, using a popup window" -msgstr "উইন্ডোগুলির মধ্যে পপ-আপ উইন্ডো প্রয়োগ করে বিপরীতদিকে স্থান পরিবর্তন করুন" - -#: ../src/include/all-keybindings.h:163 -#| msgid "Move between panels and the desktop with popup" -msgid "Move between panels and the desktop, using a popup window" -msgstr "প্যানেল ও ডেস্কটপের মধ্যে পপ-আপ উইন্ডো প্রয়োগ করে স্থান পরিবর্তন করুন" - -#: ../src/include/all-keybindings.h:166 -#| msgid "Move backwards between panels and the desktop with popup" -msgid "Move backward between panels and the desktop, using a popup window" -msgstr "প্যানেল ও ডেস্কটপের মধ্যে পপ-আপ উইন্ডো প্রয়োগ করে বিপরীত দিশায় স্থান পরিবর্তন করুন" - -#: ../src/include/all-keybindings.h:171 -msgid "Move between windows of an application immediately" -msgstr "অ্যাপ্লিকেশনের উইন্ডোগুলির মধ্যে তৎক্ষনাৎ স্থান পরিবর্তন করা হবে" - -#: ../src/include/all-keybindings.h:174 -#| msgid "Move backwards between windows of an application immediately" -msgid "Move backward between windows of an application immediately" -msgstr "অ্যাপ্লিকেশনের উইন্ডোগুলির মধ্যে তৎক্ষনাৎ বিপরীতদিকে স্থান পরিবর্তন করুন" - -#: ../src/include/all-keybindings.h:177 -msgid "Move between windows immediately" -msgstr "উইন্ডোগুলির মধ্যে তৎক্ষনাৎ স্থান পরিবর্তন করা হবে" - -#: ../src/include/all-keybindings.h:180 -#| msgid "Move backwards between windows immediately" -msgid "Move backward between windows immediately" -msgstr "উইন্ডোগুলির মধ্যে তৎক্ষনাৎ বিপরীতদিকে স্থান পরিবর্তন করুন" - -#: ../src/include/all-keybindings.h:183 -msgid "Move between panels and the desktop immediately" -msgstr "প্যানেল ও ডেস্কটপের মধ্যে তৎক্ষনাৎ স্থান পরিবর্তন করা হবে" - -#: ../src/include/all-keybindings.h:186 -msgid "Move backward between panels and the desktop immediately" -msgstr "প্যানেল ও ডেস্কটপের মধ্যে তৎক্ষনাৎ বিপরীত দিশায় স্থান পরিবর্তন করা হবে" - -#: ../src/include/all-keybindings.h:191 -#| msgid "Hide all windows and focus desktop" -msgid "Hide all normal windows and set focus to the desktop" -msgstr "সমস্ত সাধারণ উইন্ডো আড়াল করে ডেস্কটপ উজ্জ্বল করা হবে" - -#: ../src/include/all-keybindings.h:194 -#| msgid "Show the panel menu" -msgid "Show the panel's main menu" -msgstr "প্যানেলের প্রধান মেনু প্রদর্শন করা হবে" - -#: ../src/include/all-keybindings.h:197 -#| msgid "Show the panel run application dialog" -msgid "Show the panel's \"Run Application\" dialog box" -msgstr "প্যানেলের \"অ্যাপ্লিকেশন সঞ্চালনা\"-র ডায়লগ বক্স প্রদর্শন করা হবে" - -#: ../src/include/all-keybindings.h:238 -msgid "Take a screenshot" -msgstr "পর্দার ছবি নিন" - -#: ../src/include/all-keybindings.h:240 -msgid "Take a screenshot of a window" -msgstr "উইন্ডোর ছবি নিন" - -#: ../src/include/all-keybindings.h:242 -msgid "Run a terminal" -msgstr "টার্মিনাল আরম্ভ করুন" - -#: ../src/include/all-keybindings.h:257 -#| msgid "Activate window menu" +#: ../data/50-mutter-windows.xml.in.h:2 msgid "Activate the window menu" msgstr "উইন্ডো মেনু সক্রিয় করুন" -#: ../src/include/all-keybindings.h:260 +#: ../data/50-mutter-windows.xml.in.h:3 msgid "Toggle fullscreen mode" -msgstr "সম্পূর্ণ পর্দা জুড়ে প্রদর্শনের মোড অদল-বদল করা হবে" +msgstr "সম্পূর্ণ পর্দা মোড টগল করুন" -#: ../src/include/all-keybindings.h:262 +#: ../data/50-mutter-windows.xml.in.h:4 msgid "Toggle maximization state" -msgstr "সর্বোচ্চ মাপে প্রদর্শনের অবস্থা অদল-বদল করা হবে" - -#: ../src/include/all-keybindings.h:264 -#| msgid "Lower window below other windows" -msgid "Toggle whether a window will always be visible over other windows" -msgstr "উইন্ডোটি সর্বদা অন্য সকল উইন্ডোর উপর প্রদর্শিত হবে কিনা তা টগল করে চিহ্নিত করুন" +msgstr "বড় করার অবস্থা টগল করুন" -#: ../src/include/all-keybindings.h:266 +#: ../data/50-mutter-windows.xml.in.h:5 msgid "Maximize window" msgstr "উইন্ডো বড় করুন" -#: ../src/include/all-keybindings.h:268 -#| msgid "Resize window" +#: ../data/50-mutter-windows.xml.in.h:6 msgid "Restore window" -msgstr "উইন্ডো প্রদর্শন করুন" +msgstr "উইন্ডো পূর্বাবস্থা করুন" -#: ../src/include/all-keybindings.h:270 +#: ../data/50-mutter-windows.xml.in.h:7 msgid "Toggle shaded state" -msgstr "ছায়াবৃত প্রদর্শনের অবস্থা অদল-বদল করা হবে" +msgstr "ছায়াবৃত অবস্থা টগল করুন" -#: ../src/include/all-keybindings.h:272 -msgid "Minimize window" -msgstr "উইন্ডো আড়াল করুন" - -#: ../src/include/all-keybindings.h:274 +#: ../data/50-mutter-windows.xml.in.h:8 msgid "Close window" msgstr "উইন্ডো বন্ধ করুন" -#: ../src/include/all-keybindings.h:276 +#: ../data/50-mutter-windows.xml.in.h:9 +msgid "Hide window" +msgstr "উইন্ডো লুকান" + +#: ../data/50-mutter-windows.xml.in.h:10 msgid "Move window" -msgstr "উইন্ডো স্থানান্তরণ" +msgstr "উইন্ডো সরান" -#: ../src/include/all-keybindings.h:278 +#: ../data/50-mutter-windows.xml.in.h:11 msgid "Resize window" msgstr "উইন্ডোর মাপ পরিবর্তন করুন" -#: ../src/include/all-keybindings.h:281 -#| msgid "Toggle window on all workspaces" -msgid "Toggle whether window is on all workspaces or just one" -msgstr "সকল কর্মক্ষেত্র অথবা একটি কর্মক্ষেত্রে উইন্ডো প্রদর্শন করা হবে কি না তা টগল করে চিহ্নিত করুন" - -#: ../src/include/all-keybindings.h:285 -msgid "Move window to workspace 1" -msgstr "কর্মক্ষেত্র ১'এ স্থানান্তর করুন" - -#: ../src/include/all-keybindings.h:288 -msgid "Move window to workspace 2" -msgstr "কর্মক্ষেত্র ২'এ স্থানান্তর করুন" - -#: ../src/include/all-keybindings.h:291 -msgid "Move window to workspace 3" -msgstr "কর্মক্ষেত্র ৩'এ স্থানান্তর করুন" - -#: ../src/include/all-keybindings.h:294 -msgid "Move window to workspace 4" -msgstr "কর্মক্ষেত্র ৪'এ স্থানান্তর করুন" - -#: ../src/include/all-keybindings.h:297 -msgid "Move window to workspace 5" -msgstr "কর্মক্ষেত্র ৫'এ স্থানান্তর করুন" - -#: ../src/include/all-keybindings.h:300 -msgid "Move window to workspace 6" -msgstr "কর্মক্ষেত্র ৬'এ স্থানান্তর করুন" - -#: ../src/include/all-keybindings.h:303 -msgid "Move window to workspace 7" -msgstr "কর্মক্ষেত্র ৭'এ স্থানান্তর করুন" - -#: ../src/include/all-keybindings.h:306 -msgid "Move window to workspace 8" -msgstr "কর্মক্ষেত্র ৮'এ স্থানান্তর করুন" - -#: ../src/include/all-keybindings.h:309 -msgid "Move window to workspace 9" -msgstr "কর্মক্ষেত্র ৯'এ স্থানান্তর করুন" - -#: ../src/include/all-keybindings.h:312 -msgid "Move window to workspace 10" -msgstr "কর্মক্ষেত্র ১০'এ স্থানান্তর করুন" - -#: ../src/include/all-keybindings.h:315 -msgid "Move window to workspace 11" -msgstr "কর্মক্ষেত্র ১১'এ স্থানান্তর করুন" - -#: ../src/include/all-keybindings.h:318 -msgid "Move window to workspace 12" -msgstr "কর্মক্ষেত্র ১২'এ স্থানান্তর করুন" - -#: ../src/include/all-keybindings.h:330 -msgid "Move window one workspace to the left" -msgstr "উইন্ডো বাঁদিকের পার্শ্ববর্তী কর্মক্ষেত্রে স্থানান্তরণ করা হবে" - -#: ../src/include/all-keybindings.h:333 -msgid "Move window one workspace to the right" -msgstr "উইন্ডো ডানদিকের পার্শ্ববর্তী কর্মক্ষেত্রে স্থানান্তরণ করা হবে" +#: ../data/50-mutter-windows.xml.in.h:12 +msgid "Toggle window on all workspaces or one" +msgstr "সমস্ত কর্মক্ষেত্রে বা একটিতে উইন্ডো টগল করুন" -#: ../src/include/all-keybindings.h:336 -msgid "Move window one workspace up" -msgstr "উইন্ডো একটি কর্মক্ষেত্র উপরে স্থানান্তরণ করা হবে" - -#: ../src/include/all-keybindings.h:339 -msgid "Move window one workspace down" -msgstr "উইন্ডো একটি কর্মক্ষেত্র নীচে স্থানান্তরণ করা হবে" - -#: ../src/include/all-keybindings.h:342 -#| msgid "Raise window above other windows" -msgid "Raise window if it's covered by another window, otherwise lower it" -msgstr "অন্য উইন্ডো দ্বারা ঢাকা থাকলে উইন্ডোটি উপরে উইন্ডো উত্থাপন করা হবে, অন্যথা সেটি নীচে নামানো হবে" +#: ../data/50-mutter-windows.xml.in.h:13 +msgid "Raise window if covered, otherwise lower it" +msgstr "ঢাকা থাকলে উইন্ডো ওঠান অথবা এটিকে নামান" -#: ../src/include/all-keybindings.h:344 +#: ../data/50-mutter-windows.xml.in.h:14 msgid "Raise window above other windows" -msgstr "অন্যান্য উইন্ডোর উপরে উইন্ডো উত্থাপন করা হবে" +msgstr "উইন্ডো অন্যান্য উইন্ডোর উপরে ওঠান" -#: ../src/include/all-keybindings.h:346 +#: ../data/50-mutter-windows.xml.in.h:15 msgid "Lower window below other windows" -msgstr "উইন্ডোটিকে অন্য উইন্ডোর নীচে নামানো হবে" +msgstr "উইন্ডো অন্যান্য উইন্ডোর নীচে নামান" -#: ../src/include/all-keybindings.h:350 +#: ../data/50-mutter-windows.xml.in.h:16 msgid "Maximize window vertically" -msgstr "উইন্ডো উলম্ব দিশায় বড় করুন" +msgstr "উইন্ডো উল্লম্বভাবে বড় করুন" -#: ../src/include/all-keybindings.h:354 +#: ../data/50-mutter-windows.xml.in.h:17 msgid "Maximize window horizontally" -msgstr "উইন্ডো অনুভূমিক দিশায় বড় করুন" - -#: ../src/include/all-keybindings.h:358 -#| msgid "Move window one workspace to the left" -msgid "Move window to north-west (top left) corner" -msgstr "পর্দার উপরে বাঁদিকের কোণে উইন্ডো স্থাপন করা হবে" - -#: ../src/include/all-keybindings.h:361 -#| msgid "Move window one workspace to the right" -msgid "Move window to north-east (top right) corner" -msgstr "পর্দার উপরে ডানদিকের কোণে উইন্ডো স্থাপন করা হবে" +msgstr "উইন্ডো অনুভূমিক ভাবে বড় করুন" -#: ../src/include/all-keybindings.h:364 -msgid "Move window to south-west (bottom left) corner" -msgstr "পর্দার নীচে বাঁদিকের কোণে উইন্ডো স্থাপন করা হবে" +#: ../data/50-mutter-windows.xml.in.h:18 +msgid "View split on left" +msgstr "বাম বিভক্ত দেখুন" -#: ../src/include/all-keybindings.h:367 -msgid "Move window to south-east (bottom right) corner" -msgstr "পর্দার নীচে ডানদিকের কোণে উইন্ডো স্থাপন করা হবে" +#: ../data/50-mutter-windows.xml.in.h:19 +msgid "View split on right" +msgstr "ডান বিভক্ত দেখুন" -#: ../src/include/all-keybindings.h:371 -msgid "Move window to north (top) side of screen" -msgstr "পর্দার উপরের অংশে উইন্ডো স্থাপন করা হবে" +#: ../data/mutter.desktop.in.h:1 +msgid "Mutter" +msgstr "Mutter" -#: ../src/include/all-keybindings.h:374 -msgid "Move window to south (bottom) side of screen" -msgstr "পর্দার নীচের অংশে উইন্ডো স্থাপন করা হবে" +#: ../data/org.gnome.mutter.gschema.xml.in.h:1 +msgid "Modifier to use for extended window management operations" +msgstr "বর্ধিত উইন্ডো পরিচালনা কাজের জন্য ব্যবহার করার সংশোধক" -#: ../src/include/all-keybindings.h:377 -msgid "Move window to east (right) side of screen" -msgstr "পর্দার ডানদিকের অংশে উইন্ডো স্থাপন করা হবে" - -#: ../src/include/all-keybindings.h:380 -msgid "Move window to west (left) side of screen" -msgstr "পর্দার বাঁদিকের অংশে উইন্ডো স্থাপন করা হবে" - -#: ../src/include/all-keybindings.h:383 -#| msgid "Move window one workspace down" -msgid "Move window to center of screen" -msgstr "পর্দার কেন্দ্রে উইন্ডো স্থাপন করা হবে" - -#: ../src/metacity.schemas.in.in.h:1 -msgid "(Not implemented) Navigation works in terms of applications not windows" -msgstr "(কার্যকরী নয়) উইন্ডোর পরিবর্তে অ্যাপ্লিকেশন অনুসারে চলাচল করা সম্ভব" - -#: ../src/metacity.schemas.in.in.h:2 +#: ../data/org.gnome.mutter.gschema.xml.in.h:2 msgid "" -"A font description string describing a font for window titlebars. The size " -"from the description will only be used if the titlebar_font_size option is " -"set to 0. Also, this option is disabled if the titlebar_uses_desktop_font " -"option is set to true." -msgstr "" -"উইন্ডোর শিরোনামে ব্যবহৃত ফন্টের ব্যাখ্যা রূপে একটি পংক্তি। titlebar_font_size " -"বিকল্পের মান 0 রূপে ধার্য করা হলে ফন্টের ব্যাখ্যায় উল্লিখিত ফন্টের মাপ ব্যবহৃত হবে। " -"titlebar_uses_desktop_font বিকল্পের মান true হলে এই বিকল্পের ব্যবহার নিষ্ক্রিয় " -"করা হবে।" - -#: ../src/metacity.schemas.in.in.h:3 -msgid "Action on title bar double-click" -msgstr "শিরোনামের বারে দুইবার ক্লিক করা হলে করণীয় কর্ম" - -#: ../src/metacity.schemas.in.in.h:4 -#| msgid "Action on title bar double-click" -msgid "Action on title bar middle-click" -msgstr "শিরোনামের বারে মাউসের মাঝের বাটন ক্লিক করা হলে সঞ্চালনযোগ্য কর্ম" - -#: ../src/metacity.schemas.in.in.h:5 -#| msgid "Action on title bar double-click" -msgid "Action on title bar right-click" -msgstr "শিরোনামের বারে মাউসের ডানদিকের বাটন ক্লিক করা হলে সঞ্চালনযোগ্য কর্ম" - -#: ../src/metacity.schemas.in.in.h:6 -msgid "Arrangement of buttons on the titlebar" -msgstr "শিরোনাম বারে বাটনের বিন্যাস" - -#: ../src/metacity.schemas.in.in.h:7 -#, fuzzy -#| msgid "" -#| "Arrangement of buttons on the titlebar. The value should be a string, " -#| "such as \"menu:minimize,maximize,close\"; the colon separates the left " -#| "corner of the window from the right corner, and the button names are " -#| "comma-separated. Duplicate buttons are not allowed. Unknown button names " -#| "are silently ignored so that buttons can be added in future metacity " -#| "versions without breaking older versions." +"This key will initiate the \"overlay\", which is a combination window " +"overview and application launching system. The default is intended to be the " +"\"Windows key\" on PC hardware. It's expected that this binding either the " +"default or set to the empty string." +msgstr "" +"এই কী \"ওভারলে\" এর সূচনা করবে, যা হল এক সমন্বয় উইন্ডো পূর্বরূপ এবং " +"অ্যাপ্লিকেশন " +"লঞ্চিং সিস্টেম। অভিপ্রেত ডিফল্ট হল PC হার্ডওয়্যারে \"Windows কী\"। প্রত্যাশিত " +"হল, এই " +"বন্ধন হয় ডিফল্ট বা খালি স্ট্রীঙে সেট করা।" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:3 +msgid "Attach modal dialogs" +msgstr "মোডেল ডায়ালগ সংযুক্ত করুন" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:4 msgid "" -"Arrangement of buttons on the titlebar. The value should be a string, such " -"as \"menu:minimize,maximize,spacer,close\"; the colon separates the left " -"corner of the window from the right corner, and the button names are comma-" -"separated. Duplicate buttons are not allowed. Unknown button names are " -"silently ignored so that buttons can be added in future metacity versions " -"without breaking older versions. A special spacer tag can be used to insert " -"some space between two adjacent buttons." +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." msgstr "" -"শিরোনাম বারের মধ্যে বাটনের বিন্যাস। চিহ্নিত মান একটি পংক্তি হওয়া আবশ্যক যেমন " -"\"menu:minimize,maximize,close\"; কোলোন চিহ্ন দ্বারা উইন্ডোর বাঁদিকের কোণার ও " -"ডানদিকের কোণার মান বিভাজিত করা হয় এবং বাটনের নামগুলি কমা-চিহ্ন দ্বারা বিভক্ত।দুটি " -"বাটন অনুরূপ হওয়া সম্ভব নয়। অজানা বাটনের নাম সতর্কবাণী বিনা অগ্রাহ্য করা হয় যার ফলে " -"ভবিষ্যতে প্রকাশিত metacity'র সংস্করণের সাথে বিনা দ্বন্দ্বে বাটন যোগ করা সম্ভব হবে।" - -#: ../src/metacity.schemas.in.in.h:8 -msgid "Automatically raises the focused window" -msgstr "ব্যবহৃত উইন্ডো স্বয়ংক্রিয়রূপে বড় করা হবে" - -#: ../src/metacity.schemas.in.in.h:9 -#, fuzzy -#| msgid "" -#| "Clicking a window while holding down this modifier key will move the " -#| "window (left click), resize the window (middle click), or show the window " -#| "menu (right click). Modifier is expressed as \"<Alt>\" or \"<" -#| "Super>\" for example." -msgid "" -"Clicking a window while holding down this modifier key will move the window " -"(left click), resize the window (middle click), or show the window menu " -"(right click). The left and right operations may be swapped using the " -"\"mouse_button_resize\" key. Modifier is expressed as \"<Alt>\" or " -"\"<Super>\" for example." -msgstr "" -"চিহ্নিত পরিবর্তক-কি টিপে ধরে উইন্ডোর উপর ক্লিক করা হলে উইন্ডোটির স্থান পরিবর্তন " -"(বাঁদিকের বাটনে ক্লিক), মাপ পরিবর্তন (মধ্যবর্তী বাটনে ক্লিক) অথবা উইন্ডোর মেনু " -"পরিবর্তন(ডানদিকের বাটনে ক্লিক) করা সম্ভব হবে। পরিবর্তক লেখার জন্য \"<Alt>\" " -"অথবা \"<Super>\" প্রভৃতি বিন্যাস ব্যবহার করা হয়।" - -#: ../src/metacity.schemas.in.in.h:10 -msgid "Commands to run in response to keybindings" -msgstr "কি-বাইন্ডিং ব্যবহৃত হলে সঞ্চালনযোগ্য কমান্ড" - -#: ../src/metacity.schemas.in.in.h:11 -msgid "Compositing Manager" -msgstr "কম্পোসিটিং পরিচালন ব্যবস্থা" - -#: ../src/metacity.schemas.in.in.h:12 -msgid "Control how new windows get focus" -msgstr "নতুন উইন্ড উজ্জ্বল করার প্রণালী নিয়ন্ত্রণ করুন" +"সত্য হলে, স্বতন্ত্র টাইটেলবার থাকার পরিবর্তে, মোডেল ডায়ালগ পেরেন্ট উইন্ডোর " +"টাইটেল " +"বারে সংযুক্ত অবস্থায় অাসে এবং পেরেন্ট উইন্ডোর সাথে একসাথে অবস্থান পরিবর্তন " +"করে।" -#: ../src/metacity.schemas.in.in.h:13 -msgid "Current theme" -msgstr "বর্তমানে ব্যবহৃত থিম" +#: ../data/org.gnome.mutter.gschema.xml.in.h:5 +msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "উইন্ডো স্ক্রীন কিনারায় অানার সময়ে কিনারা টাইল পরিবৃত করা সক্ষম করুন" -#: ../src/metacity.schemas.in.in.h:14 -msgid "Delay in milliseconds for the auto raise option" -msgstr "স্বয়ংক্রিয়রূপে উইন্ডোর বড় করার পূর্বে বিলম্বক্ষণ, মিলিসেকেন্ডে ব্যক্ত" - -#: ../src/metacity.schemas.in.in.h:15 -msgid "Determines whether Metacity is a compositing manager." -msgstr "কমপোসিটিং পরিচালন ব্যবস্থা রূপে Metacity প্রয়োগ করা হবে কি না তা ধার্য করা হবে।" - -#: ../src/metacity.schemas.in.in.h:16 +#: ../data/org.gnome.mutter.gschema.xml.in.h:6 msgid "" -"Determines whether applications or the system can generate audible 'beeps'; " -"may be used in conjunction with 'visual bell' to allow silent 'beeps'." -msgstr "" -"অ্যাপ্লিকেশন অথবা সিস্টেমের দ্বারা শ্রুতিগম্য 'beeps' শব্দ উৎপন্ন করা হবে কিনা তা " -"নির্ধারণ করে; নিঃশব্দ 'beeps' শব্দের জন্য 'visual bell'-র সাথে ব্যবহারযোগ্য।" - -#: ../src/metacity.schemas.in.in.h:17 -msgid "Disable misfeatures that are required by old or broken applications" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." msgstr "" -"পুরোনো অথবা ক্ষতিগ্রস্ত অ্যাপ্লিকেশনের ক্ষেত্রে আবশ্যক ত্রুটিপূর্ণ বৈশিষ্ট্যের ব্যবহার " -"নিষ্ক্রিয় করা হবে" +"সক্রিয় করা হলে, উইন্ডো উল্লম্ব স্ক্রীন কিনারায় রাখা হলে, তা উল্লম্ব ভাবে " +"বর্ধিত হয় " +"এবং উপলব্ধ অঞ্চলের অর্ধেক অাবৃত করতে তাদের মাপ অনুভূমিক ভাবে পরিবর্তন করে। " +"উইন্ডো " +"উপরের স্ক্রীন কিনারায় ছাড়া হলে তা তাদের সম্পূর্ণ ভাবে বড় করে।" -#: ../src/metacity.schemas.in.in.h:18 -msgid "Enable Visual Bell" -msgstr "Visual Bell সক্রিয় করা হবে" - -#: ../src/metacity.schemas.in.in.h:19 -msgid "" -"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " -"the focused window will be automatically raised after a delay specified by " -"the auto_raise_delay key. This is not related to clicking on a window to " -"raise it, nor to entering a window during drag-and-drop." -msgstr "" -"মান true ধার্য করা হলে ও উজ্জ্বল করার মোড \"sloppy\" অথবা \"mouse\" হয়ে থাকলে " -"auto_raise_delay কি দ্বারা চিহ্নিত মিলিসেকেন্ড পরে উজ্জ্বলিত উইন্ডোটি স্বয়ংক্রিয়রূপে " -"বড় করা হবে। উইন্ডোর উপর ক্লিক করে উইন্ডো বড় করার বৈশিষ্ট্য অথবা ড্র্যাগ-ড্রপ কর্ম " -"সঞ্চালনকালে উইন্ডোর মধ্যে প্রবেশের সাথে এর কোনো সম্পর্ক নেই।" - -#: ../src/metacity.schemas.in.in.h:20 -msgid "" -"If true, ignore the titlebar_font option, and use the standard application " -"font for window titles." -msgstr "" -"মান true হলে, titlebar_font বিকল্পটি অগ্রাহ্য করা হবে ও উইন্ডোর শিরোনামের জন্য " -"অ্যাপ্লিকেশনের ক্ষেত্রে চিহ্নিত প্রমিত ফন্ট ব্যবহৃত হবে।" +#: ../data/org.gnome.mutter.gschema.xml.in.h:7 +msgid "Workspaces are managed dynamically" +msgstr "কর্মক্ষেত্রগুলি ডায়নামিক ভাবে ব্যবস্থাপনা করা হয়" -#: ../src/metacity.schemas.in.in.h:21 +#: ../data/org.gnome.mutter.gschema.xml.in.h:8 msgid "" -"If true, metacity will give the user less feedback by using wireframes, " -"avoiding animations, or other means. This is a significant reduction in " -"usability for many users, but may allow legacy applications to continue " -"working, and may also be a useful tradeoff for terminal servers. However, " -"the wireframe feature is disabled when accessibility is on." +"Determines whether workspaces are managed dynamically or whether there's a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." msgstr "" -"মান true হলে, metacity দ্বারা ব্যবহারকারীদের কম ফিড-ব্যাক প্রদান করা হবে এবং এর " -"জন্য অ্যানিমেশন প্রভৃতি উপেক্ষা করে ওয়াইর-ফ্রেম ব্যবহার করা হবে। এর ফলে অনেক " -"ব্যবহারকারীর ক্ষেত্রে ব্যবহারযোগ্যতা হ্রাস পেলেও লিগাসি অ্যাপ্লিকেশন সঞ্চালন করা যাবে " -"এবং টারমিনাল সার্ভারের ক্ষেত্রে বিশেষ কর্মোপযোগিতা উপলব্ধ করবে। তথাপি সহায়ক " -"প্রযুক্তির ব্যবহার সক্রিয় থাকাকালীন ওয়াইর-ফ্রেমের ব্যবহার নিষ্ক্রিয় করা হয়।" - -# fuzzy -#: ../src/metacity.schemas.in.in.h:22 -msgid "" -"If true, then Metacity works in terms of applications rather than windows. " -"The concept is a bit abstract, but in general an application-based setup is " -"more like the Mac and less like Windows. When you focus a window in " -"application-based mode, all the windows in the application will be raised. " -"Also, in application-based mode, focus clicks are not passed through to " -"windows in other applications. Application-based mode is, however, largely " -"unimplemented at the moment." -msgstr "" -"মান true হলে, উইন্ডোর পরিবর্তে Metacity অ্যাপ্লিকেশন অনুযায়ী কর্ম সঞ্চালন করবে। " -"অ্যাপ্লিকেশন-ভিত্তিক পরিবেশ Mac'র অনুরূপ ও Windows'র সাথে এর সাদৃশ্য কম। অ্যাপ্লিকেশন-" -"ভিত্তিক মোডে কোনে উইন্ডো উজ্জ্বল করা হলে সংশ্লিষ্ট অ্যাপ্লিকেশনের সমস্ত উইন্ডো বড় করা " -"হবে। উপরন্তু উজ্জ্বল করার সময় কৃত ক্লিক, উইন্ডোর মাধ্যমে অন্যান্য অ্যাপ্লিকেশনে প্রেরিত " -"হয় না। বাস্তবে অ্যাপ্লিকেশন-ভিত্তিক মোড বর্তমানে বিশেষ প্রয়োগ করা হয় না।" - -#: ../src/metacity.schemas.in.in.h:23 -msgid "If true, trade off usability for less resource usage" -msgstr "মান true হলে, রিসোর্সের ব্যবহার হ্রাস করতে কর্মক্ষমতা হ্রাস করা হবে" - -#: ../src/metacity.schemas.in.in.h:24 -msgid "Modifier to use for modified window click actions" -msgstr "পরিবর্তিত উইন্ডো ক্লিক কর্মের ফলে ব্যবহারযোগ্য পরিবর্তক" +"কর্মক্ষেত্রগুলি ডায়নামিক ভাবে পরিচালিত হয় নাকি কর্মক্ষেত্রের সংখ্যা স্থির তা " +"নির্ধারণ " +"করে (এখানে num-workspaces কী দ্বারা নির্ধারিত হয় org.gnome.desktop.wm." +"preferences)।" -#: ../src/metacity.schemas.in.in.h:25 -msgid "Name of workspace" -msgstr "কর্মক্ষেত্রের নাম" +#: ../data/org.gnome.mutter.gschema.xml.in.h:9 +msgid "Workspaces only on primary" +msgstr "কর্মক্ষেত্রগুলি শুধুমাত্র প্রাথমিকে" -#: ../src/metacity.schemas.in.in.h:26 -msgid "Number of workspaces" -msgstr "কর্মক্ষেত্রের সংখ্যা" - -#: ../src/metacity.schemas.in.in.h:27 +#: ../data/org.gnome.mutter.gschema.xml.in.h:10 msgid "" -"Number of workspaces. Must be more than zero, and has a fixed maximum to " -"prevent making the desktop unusable by accidentally asking for too many " -"workspaces." +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." msgstr "" -"কর্মক্ষেত্রের সংখ্যা। শূণ্যের অধিক হওয়া আবশ্যক ও সর্বোচ্চ অনুমোদিত কর্মক্ষেত্রের সংখ্যা " -"চিহ্নিত হওয়া আবশ্যক যার ফলে ভুলবসত অত্যাধিক কর্মক্ষেত্রের উপস্থিতির ফলে ডেস্কটপ " -"ক্ষতিগ্রস্ত না হয়।" +"কর্মক্ষেত্র একটি থেকে অন্যটিতে পাল্টানো সমস্ত মনিটরের উইন্ডোর জন্য নাকি " +"শুধুমাত্র " +"প্রাথমিক মনিটরের উইন্ডোর জন্য ঘটবে তা নির্ধারণ করে।" -#: ../src/metacity.schemas.in.in.h:28 -msgid "Run a defined command" -msgstr "একটি সুনির্দিষ্ট কমান্ড সঞ্চালন করুন" +#: ../data/org.gnome.mutter.gschema.xml.in.h:11 +msgid "No tab popup" +msgstr "কোনো ট্যাব পপ-অাপ নেই" -#: ../src/metacity.schemas.in.in.h:29 +#: ../data/org.gnome.mutter.gschema.xml.in.h:12 msgid "" -"Set this to true to resize with the right button and show a menu with the " -"middle button while holding down the key given in \"mouse_button_modifier\"; " -"set it to false to make it work the opposite way around." +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." msgstr "" +"উইন্ডো অাবর্তনের ক্ষেত্রে পপ-অাপ এবং ফ্রেম হাইলাইট ব্যবহার করা হবে কিনা তা " +"নির্ধারণ " +"করে।" -#: ../src/metacity.schemas.in.in.h:30 -msgid "" -"Setting this option to false can lead to buggy behavior, so users are " -"strongly discouraged from changing it from the default of true. Many actions " -"(e.g. clicking in the client area, moving or resizing the window) normally " -"raise the window as a side-effect. Setting this option to false, which is " -"strongly discouraged, will decouple raising from other user actions, and " -"ignore raise requests generated by applications. See http://bugzilla.gnome." -"org/show_bug.cgi?id=445447#c6. Even when this option is false, windows can " -"still be raised by an alt-left-click anywhere on the window, a normal click " -"on the window decorations, or by special messages from pagers, such as " -"activation requests from tasklist applets. This option is currently disabled " -"in click-to-focus mode. Note that the list of ways to raise windows when " -"raise_on_click is false does not include programmatic requests from " -"applications to raise windows; such requests will be ignored regardless of " -"the reason for the request. If you are an application developer and have a " -"user complaining that your application does not work with this setting " -"disabled, tell them it is _their_ fault for breaking their window manager " -"and that they need to change this option back to true or live with the \"bug" -"\" they requested." -msgstr "" +#: ../data/org.gnome.mutter.gschema.xml.in.h:13 +msgid "Delay focus changes until the pointer stops moving" +msgstr "ফোকাসে বিলম্ব পয়েন্টার অবস্থান পরিবর্তন করা পর্যন্ত পরিবর্তিত হয়" -#: ../src/metacity.schemas.in.in.h:31 +#: ../data/org.gnome.mutter.gschema.xml.in.h:14 msgid "" -"Some applications disregard specifications in ways that result in window " -"manager misfeatures. This option puts Metacity in a rigorously correct mode, " -"which gives a more consistent user interface, provided one does not need to " -"run any misbehaving applications." +"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " +"the focus will not be changed immediately when entering a window, but only " +"after the pointer stops moving." msgstr "" -"কয়েকটি অ্যাপ্লিকেশন দ্বারা সুনির্দিষ্ট বৈশিষ্ট্যের মান অগ্রাহ্য করা হয় যার ফলে উইন্ডো " -"পরিচালন ব্যবস্থা ক্ষতিগ্রস্ত হয়। এই বিকল্পের দ্বারা Metacity সুস্পষ্টরূপে সঠিক চালনার " -"মোডে স্থাপিত হবে যার ফলে ইউজার ইন্টারফেস তুলনামূলকরূপে স্থায়ী হবে যদি কোনো " -"অ্যাপ্লিকেশনের গতিবিধি উশৃঙ্খল না হয়ে থাকে।" +"সত্য হিসাবে সেট করা হলে, এবং ফোকাস মোড \"sloppy\" বা \"mouse\" হলে একটি " +"উইন্ডোতে প্রবেশ করার সময়ে ফোকাস সংগে সংগে পরিবর্তিত হবে না, তবে তা ঘটবে " +"পয়েন্টার " +"অবস্থান পরিবর্তন করা থামালে তবেই।" -#: ../src/metacity.schemas.in.in.h:32 -msgid "System Bell is Audible" -msgstr "সিস্টেম ঘন্টি শোনা যাবে" +#: ../data/org.gnome.mutter.gschema.xml.in.h:15 +msgid "Draggable border width" +msgstr "টানা যায় এমন কিনারার প্রস্থ" -#: ../src/metacity.schemas.in.in.h:33 +#: ../data/org.gnome.mutter.gschema.xml.in.h:16 msgid "" -"Tells Metacity how to implement the visual indication that the system bell " -"or another application 'bell' indicator has been rung. Currently there are " -"two valid values, \"fullscreen\", which causes a fullscreen white-black " -"flash, and \"frame_flash\" which causes the titlebar of the application " -"which sent the bell signal to flash. If the application which sent the bell " -"is unknown (as is usually the case for the default \"system beep\"), the " -"currently focused window's titlebar is flashed." +"The amount of total draggable borders. If the theme's visible borders are " +"not enough, invisible borders will be added to meet this value." msgstr "" -"এর দ্বারা Metacity'কে সিস্টেম ঘন্টি অথবা অন্য কোনো অ্যাপ্লিকেশনের 'ঘন্টি' থেকে " -"উৎপন্ন শব্দের সংকেত প্রদর্শনের নির্দেশ প্রদান করা হয়। বর্তমানে দুটি বৈধ মান উপস্থিত " -"রয়েছে, \"fullscreen\" যার ফলে সম্পূর্ণ পর্দা জুড়ে সাদা-কালো ঝলকানি হয় এবং " -"\"frame_flash\" যার ফলে ঘন্টির শব্দ উৎপন্নকারী অ্যাপ্লিকেশনের শিরোনাম-বারে ঝলকানি " -"সৃষ্টি করা হবে। শব্দ উৎপন্নকারী অ্যাপ্লিকেশনের পরিচয় জানতে পারা না গেলে (ডিফল্ট " -"\"system beep (সিস্টেম বিপ)\"'র ক্ষেত্রে) বর্তমানে উজ্জ্বলিত উইন্ডোর শিরোনামের বারে " -"ঝলকানি সৃষ্টি করা হবে।" - -#: ../src/metacity.schemas.in.in.h:34 -msgid "" -"The /apps/metacity/global_keybindings/run_command_N keys define keybindings " -"that correspond to these commands. Pressing the keybinding for run_command_N " -"will execute command_N." -msgstr "" -"/apps/metacity/global_keybindings/run_command_N কিগুলি দ্বারা এই সমস্ত কমান্ডের " -"ক্ষেত্রে সংশ্লিস্ট কি-বাইন্ডিং ব্যাখ্যা করা হয়।run_command_N'র কি-বাইন্ডিং প্রয়োগ করা " -"হলে command_N সঞ্চালিত হবে।" +"টানা যায় এমন সর্বমোট কিনারার পরিমাণ। থিমের দৃশ্যমান কিনারা পর্যাপ্ত না হলে, " +"এই " +"মান পূরণ করতে অদৃশ্যমান কিনারা যোগ করা হবে।" -#: ../src/metacity.schemas.in.in.h:35 -msgid "" -"The /apps/metacity/global_keybindings/run_command_screenshot key defines a " -"keybinding which causes the command specified by this setting to be invoked." -msgstr "" -"/apps/metacity/global_keybindings/run_command_screenshot কি দ্বারা একটি কি-" -"বাইন্ডিং ব্যাখ্যা করা হয় যার ফলে এই বৈশিষ্ট্য দ্বারা চিহ্নিত কমান্ড সঞ্চালিত হবে।" - -#: ../src/metacity.schemas.in.in.h:36 -msgid "" -"The /apps/metacity/global_keybindings/run_command_window_screenshot key " -"defines a keybinding which causes the command specified by this setting to " -"be invoked." -msgstr "" -"/apps/metacity/global_keybindings/run_command_window_screenshot কি দ্বারা " -"একটি কি-বাইন্ডিং ব্যাখ্যা করা হয় যার ফলে এই বৈশিষ্ট্য দ্বারা চিহ্নিত কমান্ড সঞ্চালিত " -"হবে।" +#: ../data/org.gnome.mutter.gschema.xml.in.h:17 +msgid "Auto maximize nearly monitor sized windows" +msgstr "প্রায় মনিটরের মাপের উইন্ডো স্বয়ংক্রিয় ভাবে বড় করুন" -#: ../src/metacity.schemas.in.in.h:37 +#: ../data/org.gnome.mutter.gschema.xml.in.h:18 msgid "" -"The keybinding that runs the correspondingly-numbered command in /apps/" -"metacity/keybinding_commands The format looks like \"<Control>a\" or " -"\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -"lower or upper case, and also abbreviations such as \"<Ctl>\" and " -"\"<Ctrl>\". If you set the option to the special string \"disabled\", " -"then there will be no keybinding for this action." +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." msgstr "" -"যে কি-বাইন্ডিং দ্বারা /apps/metacity/keybinding_commands থেকে সংশ্লিষ্ট সংখ্যা " -"দ্বারা চিহ্নিত কমান্ড সঞ্চালিত হবে। \"<Control>a\" অথবা \"<Shift><" -"Alt>F1\" বিন্যাস ব্যবহৃত হবে। পার্সার হরফের ছাঁদ সম্পর্কে সচেতন নয় এবং প্রয়োজনে " -"\"<Ctl>\" ও \"<Ctrl>\"'র অনুরূপ সংক্ষিপ্ত রূপও ব্যবহার করা যাবে। " -"বিকল্পের ক্ষেত্রে বিশেষ পংক্তি \"disabled\" প্রয়োগ করা হলে এই কর্মের জন্য কোনো কি-" -"বাইন্ডিং ব্যবহার করা হবে না।" - -#: ../src/metacity.schemas.in.in.h:38 -msgid "The name of a workspace." -msgstr "কর্মক্ষেত্রের নাম" - -#: ../src/metacity.schemas.in.in.h:39 -msgid "The screenshot command" -msgstr "পর্দার ছবি নেওয়ার কমান্ড" - -#: ../src/metacity.schemas.in.in.h:40 -msgid "" -"The theme determines the appearance of window borders, titlebar, and so " -"forth." -msgstr "থিম দ্বারা উইন্ডোর প্রান্ত, শিরোনামের-বার প্রভৃতির বিন্যাস নির্ধারিত হবে।" +"সক্রিয় করা হলে, প্রাথমিক ভাবে মনিটরের সমান মাপের নতুন উইন্ডোগুলি স্বয়ংক্রিয় " +"ভাবে বড় " +"হয়।" -#: ../src/metacity.schemas.in.in.h:41 -msgid "" -"The time delay before raising a window if auto_raise is set to true. The " -"delay is given in thousandths of a second." -msgstr "" +#: ../data/org.gnome.mutter.gschema.xml.in.h:19 +msgid "Place new windows in the center" +msgstr "কেন্দ্রে নতুন উইন্ডোগুলি রাখুন" -#: ../src/metacity.schemas.in.in.h:42 +#: ../data/org.gnome.mutter.gschema.xml.in.h:20 msgid "" -"The window focus mode indicates how windows are activated. It has three " -"possible values; \"click\" means windows must be clicked in order to focus " -"them, \"sloppy\" means windows are focused when the mouse enters the window, " -"and \"mouse\" means windows are focused when the mouse enters the window and " -"unfocused when the mouse leaves the window." -msgstr "" - -#: ../src/metacity.schemas.in.in.h:43 -msgid "The window screenshot command" -msgstr "উইন্ডোর ছবি নেওয়ার জন্য ব্যবহৃত কমান্ড" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" +"সত্য হলে, নতুন উইন্ডোগুলি সর্বদা মনিটরের সক্রিয় স্ক্রিনের কেন্দ্রে বসবে।" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:21 +msgid "Select window from tab popup" +msgstr "উইন্ডো ট্যাব পপ-অাপ থেকে নির্বাচন করুন" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:22 +msgid "Cancel tab popup" +msgstr "ট্যাব পপ-অাপ বাতিল করুন" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:1 +#| msgid "Switch to workspace 1" +msgid "Switch to VT 1" +msgstr "VT ১ এ স্যুইচ করুন" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:2 +#| msgid "Switch to workspace 2" +msgid "Switch to VT 2" +msgstr "VT 2 ২ এ স্যুইচ করুন" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:3 +#| msgid "Switch to workspace 3" +msgid "Switch to VT 3" +msgstr "VT 3 ৩ এ স্যুইচ করুন" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:4 +#| msgid "Switch to workspace 4" +msgid "Switch to VT 4" +msgstr "VT 4 ৪ এ স্যুইচ করুন" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:5 +#| msgid "Switch to workspace 1" +msgid "Switch to VT 5" +msgstr "VT ৫ এ স্যুইচ করুন" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:6 +#| msgid "Switch to workspace 1" +msgid "Switch to VT 6" +msgstr "VT ৬ এ স্যুইচ করুন" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:7 +#| msgid "Switch to workspace 1" +msgid "Switch to VT 7" +msgstr "VT ৭ এ স্যুইচ করুন" + +#: ../src/backends/meta-monitor-manager.c:412 +msgid "Built-in display" +msgstr "অন্তর্গঠিত প্রদর্শন" + +#: ../src/backends/meta-monitor-manager.c:437 +msgid "Unknown" +msgstr "অজানা" + +#: ../src/backends/meta-monitor-manager.c:439 +msgid "Unknown Display" +msgstr "অজানা প্রদর্শন" + +#. TRANSLATORS: this is a monitor vendor name, followed by a +#. * size in inches, like 'Dell 15"' +#. +#: ../src/backends/meta-monitor-manager.c:447 +#, c-format +msgid "%s %s" +msgstr "%s %s" -#: ../src/metacity.schemas.in.in.h:44 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: ../src/compositor/compositor.c:443 +#, c-format msgid "" -"This option determines the effects of double-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, 'toggle_maximize' which will maximize/unmaximize the window, " -"'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which will " -"maximize/unmaximize the window in that direction only, 'minimize' which will " -"minimize the window, 'shade' which will roll the window up, 'menu' which " -"will display the window menu, 'lower' which will put the window behind all " -"the others, and 'none' which will not do anything." +"Another compositing manager is already running on screen %i on display \"%s" +"\"." msgstr "" +"অন্য কম্পোসিটিং পরিচালককে পর্দা %i-তে ইতিমধ্যেই চলমান প্রদর্শন করা হয়েছে \"%" +"s\"।" -#: ../src/metacity.schemas.in.in.h:45 -msgid "" -"This option determines the effects of middle-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, 'toggle_maximize' which will maximize/unmaximize the window, " -"'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which will " -"maximize/unmaximize the window in that direction only, 'minimize' which will " -"minimize the window, 'shade' which will roll the window up, 'menu' which " -"will display the window menu, 'lower' which will put the window behind all " -"the others, and 'none' which will not do anything." -msgstr "" +#: ../src/core/bell.c:185 +msgid "Bell event" +msgstr "বেল ইভেন্ট" -#: ../src/metacity.schemas.in.in.h:46 -msgid "" -"This option determines the effects of right-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, 'toggle_maximize' which will maximize/unmaximize the window, " -"'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which will " -"maximize/unmaximize the window in that direction only, 'minimize' which will " -"minimize the window, 'shade' which will roll the window up, 'menu' which " -"will display the window menu, 'lower' which will put the window behind all " -"the others, and 'none' which will not do anything." -msgstr "" +#: ../src/core/delete.c:127 +#, c-format +msgid "“%s” is not responding." +msgstr "“%s” সাড়া দিচ্ছে না।" -#: ../src/metacity.schemas.in.in.h:47 -msgid "" -"This option provides additional control over how newly created windows get " -"focus. It has two possible values; \"smart\" applies the user's normal focus " -"mode, and \"strict\" results in windows started from a terminal not being " -"given focus." -msgstr "" +#: ../src/core/delete.c:129 +msgid "Application is not responding." +msgstr "অ্যাপ্লিকেশনটির থেকে প্রতিক্রিয়া পাওয়া যাচ্ছে না।" -#: ../src/metacity.schemas.in.in.h:48 +#: ../src/core/delete.c:134 msgid "" -"Turns on a visual indication when an application or the system issues a " -"'bell' or 'beep'; useful for the hard-of-hearing and for use in noisy " -"environments." +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." msgstr "" +"এটি চালু হওয়ার জন্য আপনি একটি সংক্ষিপ্ত সময় অপেক্ষা করতে পারেন " +"বাঅ্যাপ্লিকেশনটিকে " +"সম্পূর্ণরূপে বন্ধ হতে বাধ্য করতে পারেন‌।" -# "অবৃহদায়ত কর" -#: ../src/metacity.schemas.in.in.h:49 -msgid "Use standard system font in window titles" -msgstr "উইন্ডোর শিরোনামে সিস্টেমের প্রমিত মাপের ফন্ট ব্যবহার করা হবে" - -#: ../src/metacity.schemas.in.in.h:50 -msgid "Visual Bell Type" -msgstr "ভিসুয়্যল বেলের ধরন" +#: ../src/core/delete.c:141 +msgid "_Wait" +msgstr "অপেক্ষা করা হবে (_W)" -#: ../src/metacity.schemas.in.in.h:51 -msgid "Whether raising should be a side-effect of other user interactions" -msgstr "ব্যবহারকারীদের দ্বারা সঞ্চালিত কর্মের ফলে উইন্ডো বড় করা হবে কি না" +#: ../src/core/delete.c:141 +msgid "_Force Quit" +msgstr "বলপূর্বক বন্ধ করুন (_F)" -#: ../src/metacity.schemas.in.in.h:52 -msgid "Whether to resize with the right button" -msgstr "ডানদিকের বাটন প্রয়োগ করে মাপ পরিবর্তন করা হবে কি না" +#: ../src/core/display.c:547 +#, c-format +msgid "Failed to open X Window System display '%s'\n" +msgstr "X উইন্ডো সিস্টেম প্রদর্শন খুলতে ব্যর্থ '%s'\n" -#: ../src/metacity.schemas.in.in.h:53 -msgid "Window focus mode" -msgstr "উইন্ডো উজ্জ্বল করার মোড" +#: ../src/core/main.c:176 +msgid "Disable connection to session manager" +msgstr "সেশান পরিচালন ব্যবস্থার সাথে সংযোগ বিচ্ছিন্ন করা হবে" -#: ../src/metacity.schemas.in.in.h:54 -msgid "Window title font" -msgstr "উইন্ডোর শিরোনামে ব্যবহৃত ফন্ট" +#: ../src/core/main.c:182 +msgid "Replace the running window manager" +msgstr "চলমান উইন্ডো পরিচালন ব্যবস্থা প্রতিস্থাপন করুন" -#: ../src/tools/metacity-message.c:150 -#, c-format -msgid "Usage: %s\n" -msgstr "ব্যবহারপদ্ধতি: %s\n" +#: ../src/core/main.c:188 +msgid "Specify session management ID" +msgstr "সেশান পরিচালনার ID উল্লেখ করুন" -#: ../src/ui/frames.c:1118 -msgid "Close Window" -msgstr "উইন্ডো বন্ধ করুন" +#: ../src/core/main.c:193 +msgid "X Display to use" +msgstr "ব্যবহারের জন্য এক্স ডিসপ্লে" -#: ../src/ui/frames.c:1121 -msgid "Window Menu" -msgstr "উইন্ডো মেনু" +#: ../src/core/main.c:199 +msgid "Initialize session from savefile" +msgstr "সংরক্ষণ ফাইল থেকে সেশন চালু করো" -#: ../src/ui/frames.c:1124 -msgid "Minimize Window" -msgstr "উইন্ডো আড়াল করুন" +#: ../src/core/main.c:205 +msgid "Make X calls synchronous" +msgstr "X-র কল সিঙ্ক্রোনাস করা হবে" -# "উইন্ডো ক্ষুদ্রায়ত কর" -#: ../src/ui/frames.c:1127 -msgid "Maximize Window" -msgstr "উইন্ডো বড় করুন" +#: ../src/core/main.c:212 +msgid "Run as a wayland compositor" +msgstr "ওয়েল্যান্ড কম্পোজিটর হিসাবে চালান" -#: ../src/ui/frames.c:1130 -#| msgid "Resize window" -msgid "Restore Window" -msgstr "উইন্ডো প্রদর্শন করুন" +#: ../src/core/main.c:220 +msgid "Run as a full display server, rather than nested" +msgstr "নেস্টেড'র পরিবর্তে সম্পূর্ণ প্রদর্শন সার্ভার হিসাবে চালান" -#: ../src/ui/frames.c:1133 -#| msgid "Roll _Up" -msgid "Roll Up Window" -msgstr "উইন্ডো গুটিয়ে ফেলুন" +#: ../src/core/main.c:451 +#, c-format +msgid "Failed to scan themes directory: %s\n" +msgstr "থীম এর ডিরেক্টরি স্ক্যান করতে ব্যর্থ: %s\n" -#: ../src/ui/frames.c:1136 -#| msgid "Close Window" -msgid "Unroll Window" +#: ../src/core/main.c:467 +#, c-format +msgid "" +"Could not find a theme! Be sure %s exists and contains the usual themes.\n" msgstr "" +"কোনো থিম খুঁজে পাওয়া যায়নি! অনুগ্রহ করে পরীক্ষা করুন %s উপস্থিত আছে কি না ও " +"এর মধ্যে " +"সাধারণ থিমগুলি অন্তর্ভুক্ত কি না।\n" -#: ../src/ui/frames.c:1139 -msgid "Keep Window On Top" -msgstr "উইন্ডো সর্বোচ্চ স্তরে স্থাপন করা হবে" - -#: ../src/ui/frames.c:1142 -msgid "Remove Window From Top" -msgstr "উইন্ডো সর্বোচ্চ স্তর থেকে সরিয়ে ফেলা হবে" - -#: ../src/ui/frames.c:1145 -#| msgid "_Always on Visible Workspace" -msgid "Always On Visible Workspace" -msgstr "দৃশ্যমান কর্মক্ষেত্রে সর্বদা উপস্থিত" - -#: ../src/ui/frames.c:1148 -#| msgid "Toggle window on all workspaces" -msgid "Put Window On Only One Workspace" -msgstr "শুধুমাত্র একটি কর্মক্ষেত্রের মধ্যে উইন্ডো স্থাপন করা হবে" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:70 -msgid "Mi_nimize" -msgstr "আড়াল করুন (_n)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:72 -msgid "Ma_ximize" -msgstr "বড় করুন (_x)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:74 -msgid "Unma_ximize" -msgstr "স্বাভাবিক মাপ (_x)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:76 -msgid "Roll _Up" -msgstr "গোটাও (_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:78 -msgid "_Unroll" -msgstr "খোলো (_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:80 -msgid "_Move" -msgstr "স্থানান্তরণ (_M)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:82 -msgid "_Resize" -msgstr "মাপ পরিবর্তন (_R)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:84 -msgid "Move Titlebar On_screen" -msgstr "পর্দার উপর শিরোনামের বার স্থানান্তর করুন (_s)" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:87 ../src/ui/menu.c:89 -msgid "Always on _Top" -msgstr "সর্বদা উপরে (_T)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:91 -msgid "_Always on Visible Workspace" -msgstr "দৃশ্যমান কর্মক্ষেত্রে সর্বদা উপস্থিত (_A)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:93 -msgid "_Only on This Workspace" -msgstr "শুধুমাত্র বর্তমান কর্মক্ষেত্রে (_O)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:95 -msgid "Move to Workspace _Left" -msgstr "বাঁদিকের কর্মক্ষেত্রে স্থানান্তর করুন (_L)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:97 -msgid "Move to Workspace R_ight" -msgstr "ডান দিকের কর্মক্ষেত্রে স্থানান্তর করুন (_i)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:99 -msgid "Move to Workspace _Up" -msgstr "উপরের কর্মক্ষেত্রে স্থানান্তরণ (_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:101 -msgid "Move to Workspace _Down" -msgstr "নীচের কর্মক্ষেত্রে স্থানান্তরণ (_D)" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:105 -msgid "_Close" -msgstr "বন্ধ করুন (_C)" - -#: ../src/ui/menu.c:203 -#, c-format -#| msgid "Workspace %d" -msgid "Workspace %d%n" -msgstr "কর্মক্ষেত্র %d%n" - -#: ../src/ui/menu.c:213 -#, c-format -msgid "Workspace 1_0" -msgstr "কর্মক্ষেত্র ১০ (_0)" - -#: ../src/ui/menu.c:215 -#, c-format -msgid "Workspace %s%d" -msgstr "কর্মক্ষেত্র %s%d" - -#: ../src/ui/menu.c:395 -msgid "Move to Another _Workspace" -msgstr "পৃথক কর্মক্ষেত্রে স্থানান্তর করুন (_W)" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:104 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:110 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:116 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:122 -msgid "Meta" -msgstr "মিটা" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:128 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:134 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:140 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:146 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:152 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:158 -msgid "Mod5" -msgstr "Mod5" - -#: ../src/ui/metacity-dialog.c:90 +#: ../src/core/mutter.c:39 #, c-format -#| msgid "The window \"%s\" is not responding." -msgid "\"%s\" is not responding." -msgstr "\"%s\" থেকে প্রতিক্রিয়া পাওয়া যাচ্ছে না।" - -#: ../src/ui/metacity-dialog.c:97 msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." +"mutter %s\n" +"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" msgstr "" +"mutter %s\n" +"স্বত্বাধিকার (C) ২০০১-%d হ্যাভক পেনিংটন, Red Hat, Inc., ও অন্যান্যদের\n" +"এটি একটি মুক্ত সফ্টওয়্যার; পুনব্যবহারের নিয়মাবলীর জন্য সোর্সের মধ্যে উপলব্ধ " +"নথিপত্র " +"দেখুন।\n" +"এর কোনো ওয়ারেন্টি উপলব্ধ নেই; বাণিজ্যিক ও কোনো সুনির্দিষ্ট কর্ম সাধনের জন্যও " +"নয়।\n" -#: ../src/ui/metacity-dialog.c:107 -msgid "_Wait" -msgstr "অপেক্ষা করা হবে (_W)" +#: ../src/core/mutter.c:53 +msgid "Print version" +msgstr "প্রিন্ট সংস্করণ" -#: ../src/ui/metacity-dialog.c:109 -msgid "_Force Quit" -msgstr "বলপূর্বক বন্ধ করুন (_F)" +#: ../src/core/mutter.c:59 +msgid "Mutter plugin to use" +msgstr "Mutter-এর ব্যবহারযোগ্য প্লাগইন" -#: ../src/ui/metacity-dialog.c:206 -msgid "Title" -msgstr "শিরোনাম" +#: ../src/core/prefs.c:2065 +#, c-format +msgid "Workspace %d" +msgstr "কর্মক্ষেত্র %d" -#: ../src/ui/metacity-dialog.c:218 -msgid "Class" -msgstr "শ্রেণী" +#: ../src/core/screen.c:543 +#, c-format +msgid "Screen %d on display '%s' is invalid\n" +msgstr "পর্দা %d (ডিসপ্লে '%s') বৈধ নয়\n" -#: ../src/ui/metacity-dialog.c:244 +#: ../src/core/screen.c:559 +#, c-format msgid "" -"These windows do not support \"save current setup\" and will have to be " -"restarted manually next time you log in." +"Screen %d on display \"%s\" already has a window manager; try using the --" +"replace option to replace the current window manager.\n" msgstr "" -"এই উইন্ডোগুলির দ্বারা\"save current setup\" বৈশিষ্ট্য সমর্থিত হয় না এবং পরবর্তীবার " -"লগ-ইন করা হলে ব্যবহারকারীর দ্বারা পুনরায় আরম্ভ করা প্রয়োজন।" +"পর্দা %d'র (\"%s\" ডিসপ্লে) ক্ষেত্রে একটি উইন্ডো পরিচালনব্যবস্থা বর্তমানে " +"উপস্তিত " +"রয়েছে; বর্তমানে উইন্ডো পরিচালন ব্যবস্থা পরিবর্তন করতে --replace বিকল্প প্রয়োগ " +"করুন।\n" -#: ../src/ui/metacity-dialog.c:310 +#: ../src/core/screen.c:652 #, c-format -msgid "" -"There was an error running \"%s\":\n" -"%s." +msgid "Screen %d on display \"%s\" already has a window manager\n" msgstr "" -"\"%s\" সঞ্চালনে সমস্যা:\n" -"%s." +"পর্দা %d'র ( \"%s\" ডিসপ্লে) ক্ষেত্রে একটি উইন্ডো পরিচালন ব্যবস্থা উপস্থিত " +"রয়েছে\n" + +#: ../src/core/util.c:118 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "ভার্বোস মোডের সমর্থন অন্তর্ভুক্ত না করে Mutter কম্পাইল করা হয়েছে\n" #. Translators: This represents the size of a window. The first number is #. * the width of the window and the second is the height. #. -#: ../src/ui/resizepopup.c:113 +#: ../src/ui/resizepopup.c:134 #, c-format msgid "%d x %d" msgstr "%d x %d" -#: ../src/ui/theme.c:254 +#: ../src/ui/theme.c:233 msgid "top" msgstr "উপরে" -#: ../src/ui/theme.c:256 +#: ../src/ui/theme.c:235 msgid "bottom" msgstr "নীচে" -#: ../src/ui/theme.c:258 +#: ../src/ui/theme.c:237 msgid "left" msgstr "বাঁদিকে" -#: ../src/ui/theme.c:260 +#: ../src/ui/theme.c:239 msgid "right" msgstr "ডানদিকে" -#: ../src/ui/theme.c:287 +#: ../src/ui/theme.c:267 #, c-format msgid "frame geometry does not specify \"%s\" dimension" msgstr "ফ্রেম জ্যামিতি দ্বারা \"%s\" পরিমাপ নির্ধারিত হয়নি" -#: ../src/ui/theme.c:306 +#: ../src/ui/theme.c:286 #, c-format msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "ফ্রেম জ্যামিতি দ্বারা \"%s\" পরিমাপ \"%s\" প্রান্তের জন্য নির্ধারিত হয়নি" +msgstr "" +"ফ্রেম জ্যামিতি দ্বারা \"%s\" পরিমাপ \"%s\" প্রান্তের জন্য নির্ধারিত হয়নি" -#: ../src/ui/theme.c:343 +#: ../src/ui/theme.c:323 #, c-format msgid "Button aspect ratio %g is not reasonable" msgstr "বাটনের অ্যাপেক্ট অনুপাত %g যথাযথ নয়" -#: ../src/ui/theme.c:355 +#: ../src/ui/theme.c:335 #, c-format msgid "Frame geometry does not specify size of buttons" msgstr "ফ্রেম জ্যামিতি দ্বারা বাটনের মাপ নির্ধারিত হয়নি" -#: ../src/ui/theme.c:1020 +#: ../src/ui/theme.c:1061 #, c-format msgid "Gradients should have at least two colors" msgstr "গ্রেডিয়েন্টের ক্ষেত্রে দুটি রং নির্ধারিত হওয়া আবশ্যক" -#: ../src/ui/theme.c:1146 +#: ../src/ui/theme.c:1211 +#, c-format +msgid "" +"GTK custom color specification must have color name and fallback in " +"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" +msgstr "" +"GTK কাস্টম রঙ বিশেষীকরণে অবশ্যই বন্ধনীর মধ্যে রঙের নাম এবং ফলব্যাকের উল্লেখ " +"রাখতে " +"হবে, উদাঃ gtk:custom(foo,bar); \"%s\" পার্জ করা যায়নি" + +#: ../src/ui/theme.c:1227 +#, c-format +msgid "" +"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" +"_ are valid" +msgstr "" +"অবৈধ অক্ষর '%c' color_name প্যারামিটারে gtk:custom এর, শুধুমাত্র A-Za-z0-9-_ " +"বৈধ" + +#: ../src/ui/theme.c:1241 +#, c-format +msgid "" +"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " +"fit the format" +msgstr "" +"Gtk:কাস্টম ফর্ম্যাট হল \"gtk:custom(color_name,fallback)\", \"%s\" ফর্ম্যাটে " +"মানানসই নয়" + +#: ../src/ui/theme.c:1286 #, c-format msgid "" "GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " "where NORMAL is the state; could not parse \"%s\"" msgstr "" +"GTK রঙের বিশেষীকরণে অবশ্যই বন্ধনীর মধ্যে অবস্থার উল্লেখ করতে হবে, উদাঃ gtk:" +"fg[NORMAL] যেখানে NORMAL হল অবস্থা; \"%s\" পার্জ করা যায়নি" -#: ../src/ui/theme.c:1160 +#: ../src/ui/theme.c:1300 #, c-format msgid "" "GTK color specification must have a close bracket after the state, e.g. gtk:" "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" msgstr "" +"GTK রঙ বিশেষীকরণে অবশ্যই অবস্থার পরে একটি সমাপ্তি বন্ধনী থাকতে হবে, উদাঃ gtk:" +"fg[NORMAL] যেখানে NORMAL হল অবস্থা; \"%s\" পার্জ করা যায়নি" -#: ../src/ui/theme.c:1171 +#: ../src/ui/theme.c:1311 #, c-format msgid "Did not understand state \"%s\" in color specification" msgstr "রং নির্ধারণের জন্য state \"%s\" বোধগম্য হয়নি" -#: ../src/ui/theme.c:1184 +#: ../src/ui/theme.c:1324 #, c-format msgid "Did not understand color component \"%s\" in color specification" msgstr "রং নির্ধারণের জন্য রং'র বিষয়বস্তু \"%s\" বোধগম্য হয়নি" -#: ../src/ui/theme.c:1214 +#: ../src/ui/theme.c:1352 #, c-format msgid "" "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " "format" -msgstr "ব্লেন্ড বিন্যাস \"blend/bg_color/fg_color/alpha\", \"%s\" বিন্যাসের সাথে সুসংগত নয়" +msgstr "" +"ব্লেন্ড বিন্যাস \"blend/bg_color/fg_color/alpha\", \"%s\" বিন্যাসের সাথে " +"সুসংগত নয়" -#: ../src/ui/theme.c:1225 +#: ../src/ui/theme.c:1363 #, c-format msgid "Could not parse alpha value \"%s\" in blended color" msgstr "ব্লেন্ড করা রং'এ আল্ফা মান \"%s\" পার্স করতে ব্যর্থ" -#: ../src/ui/theme.c:1235 +#: ../src/ui/theme.c:1373 #, c-format msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" msgstr "ব্লেন্ড করা রং'এ আল্ফা মান \"%s\" 0.0 ও1.0 সীমারেখার মধ্যে নয়" -#: ../src/ui/theme.c:1282 +#: ../src/ui/theme.c:1419 #, c-format -msgid "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "ছায়ার বিন্যাস \"shade/base_color/factor\", \"%s\" বিন্যাসের সাথে সুসংগত নয়" +msgid "" +"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" +msgstr "" +"ছায়ার বিন্যাস \"shade/base_color/factor\", \"%s\" বিন্যাসের সাথে সুসংগত নয়" -#: ../src/ui/theme.c:1293 +#: ../src/ui/theme.c:1430 #, c-format msgid "Could not parse shade factor \"%s\" in shaded color" msgstr "ছায়াযুক্ত রং'র ক্ষেত্রে ছায়ার মাপ \"%s\" পার্স করতে ব্যর্থ" -#: ../src/ui/theme.c:1303 +#: ../src/ui/theme.c:1440 #, c-format msgid "Shade factor \"%s\" in shaded color is negative" msgstr "ছায়াযুক্ত রং'র ক্ষেত্রে ছায়ার মান \"%s\" শূণ্যের কম" -#: ../src/ui/theme.c:1332 +#: ../src/ui/theme.c:1469 #, c-format msgid "Could not parse color \"%s\"" msgstr "\"%s\" রং পার্স করতে ব্যর্থ" -#: ../src/ui/theme.c:1582 +#: ../src/ui/theme.c:1778 #, c-format msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে '%s' অক্ষর উপস্থিত এবং এর ব্যবহার অনুমোদিত নয়" +msgstr "" +"কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে '%s' অক্ষর উপস্থিত এবং এর ব্যবহার অনুমোদিত নয়" # what is bengali for Coordinate expression ? অবস্থানের মান or অবস্থানের সমীকরণ? -#: ../src/ui/theme.c:1609 +#: ../src/ui/theme.c:1805 #, c-format msgid "" "Coordinate expression contains floating point number '%s' which could not be " "parsed" msgstr "" -"কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে '%s' ফ্লোটিং পয়েন্ট সংখ্যা উপস্থিত যা পার্স করা সম্ভব " +"কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে '%s' ফ্লোটিং পয়েন্ট সংখ্যা উপস্থিত যা পার্স " +"করা সম্ভব " "হয়নি" -#: ../src/ui/theme.c:1623 +#: ../src/ui/theme.c:1819 #, c-format msgid "Coordinate expression contains integer '%s' which could not be parsed" msgstr "" +"কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে '%s' ইন্টিজার সংখ্যা উপস্থিত যা পার্স করা " +"সম্ভব হয়নি" -#: ../src/ui/theme.c:1745 +#: ../src/ui/theme.c:1940 #, c-format msgid "" "Coordinate expression contained unknown operator at the start of this text: " "\"%s\"" -msgstr "কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে টেক্সটের প্রারম্ভিক স্থানে অজানা অপারেটর: \"%s\"" +msgstr "" +"কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে টেক্সটের প্রারম্ভিক স্থানে অজানা অপারেটর: \"%" +"s\"" -#: ../src/ui/theme.c:1802 +#: ../src/ui/theme.c:1997 #, c-format msgid "Coordinate expression was empty or not understood" msgstr "কো-ওর্ডিনেট এক্সপ্রেশন ফাঁকা অথবা বোধগম্য নয়" -#: ../src/ui/theme.c:1913 ../src/ui/theme.c:1923 ../src/ui/theme.c:1957 +#: ../src/ui/theme.c:2110 ../src/ui/theme.c:2120 ../src/ui/theme.c:2154 #, c-format msgid "Coordinate expression results in division by zero" msgstr "কো-ওর্ডিনেট এক্সপ্রেশনের ফলাফলে শূণ্য দ্বারা ভাগ করার অবস্থা উৎপন্ন হয়" -#: ../src/ui/theme.c:1965 +#: ../src/ui/theme.c:2162 #, c-format -msgid "Coordinate expression tries to use mod operator on a floating-point number" +msgid "" +"Coordinate expression tries to use mod operator on a floating-point number" msgstr "" -"কো-ওর্ডিনেট এক্সপ্রেশন দ্বারা ফ্লোটিং পয়েন্ট সংখ্যার উপর mod অপারেটর ব্যবহারের প্রয়াস " +"কো-ওর্ডিনেট এক্সপ্রেশন দ্বারা ফ্লোটিং পয়েন্ট সংখ্যার উপর mod অপারেটর " +"ব্যবহারের প্রয়াস " "করা হয়েছে" -#: ../src/ui/theme.c:2021 +#: ../src/ui/theme.c:2218 #, c-format -msgid "Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে \"%s\" অপারেটর উপস্থিত কিন্তু অপারেন্ড প্রত্যাশিত" +msgid "" +"Coordinate expression has an operator \"%s\" where an operand was expected" +msgstr "" +"কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে \"%s\" অপারেটর উপস্থিত কিন্তু অপারেন্ড " +"প্রত্যাশিত" -#: ../src/ui/theme.c:2030 +#: ../src/ui/theme.c:2227 #, c-format msgid "Coordinate expression had an operand where an operator was expected" -msgstr "কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে প্রত্যাশিত অপারেন্ডের পরিবর্তে অপারেটর উপস্থিত" +msgstr "" +"কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে প্রত্যাশিত অপারেন্ডের পরিবর্তে অপারেটর উপস্থিত" -#: ../src/ui/theme.c:2038 +#: ../src/ui/theme.c:2235 #, c-format msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "কো-ওর্ডিনেট এক্সপ্রেশনের অন্তে প্রত্যাশিত অপারেন্ডের পরিবর্তে অপারেটর উপস্থিত" +msgstr "" +"কো-ওর্ডিনেট এক্সপ্রেশনের অন্তে প্রত্যাশিত অপারেন্ডের পরিবর্তে অপারেটর উপস্থিত" -#: ../src/ui/theme.c:2048 +#: ../src/ui/theme.c:2245 #, c-format msgid "" "Coordinate expression has operator \"%c\" following operator \"%c\" with no " "operand in between" msgstr "" -"কো-ওর্ডিনেট এক্সপ্রেশনের ক্ষেত্রে \"%c\" অপারেটরের পরে \"%c\" অপারেটর উপস্থিত এবং " +"কো-ওর্ডিনেট এক্সপ্রেশনের ক্ষেত্রে \"%c\" অপারেটরের পরে \"%c\" অপারেটর উপস্থিত " +"এবং " "দুটির মধ্যে কোনো অপারেন্ড উপস্থিত নেই" -#: ../src/ui/theme.c:2195 ../src/ui/theme.c:2236 +#: ../src/ui/theme.c:2396 ../src/ui/theme.c:2441 #, c-format msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে অজানা ভেরিয়েবল অথবা কনস্ট্যান্ট \"%s\" উপস্থিত" +msgstr "" +"কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে অজানা ভেরিয়েবল অথবা কনস্ট্যান্ট \"%s\" উপস্থিত" -#: ../src/ui/theme.c:2290 +#: ../src/ui/theme.c:2495 #, c-format msgid "Coordinate expression parser overflowed its buffer." msgstr "কো-ওর্ডিনেট এক্সপ্রেশনের পার্সারের বাফারের সীমা অতিক্রান্ত হয়েছে।" -#: ../src/ui/theme.c:2319 +#: ../src/ui/theme.c:2524 #, c-format msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে শেষের বন্ধনী চিহ্ন উপস্থিত, প্রারম্ভিক চিহ্ন অনুপস্থিত" +msgstr "" +"কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে শেষের বন্ধনী চিহ্ন উপস্থিত, প্রারম্ভিক চিহ্ন " +"অনুপস্থিত" -#: ../src/ui/theme.c:2383 +#: ../src/ui/theme.c:2588 #, c-format msgid "Coordinate expression had an open parenthesis with no close parenthesis" msgstr "" -"কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে প্রারম্ভিক বন্ধনী চিহ্ন উপস্থিত শেষের বন্ধনী চিহ্ন " +"কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে প্রারম্ভিক বন্ধনী চিহ্ন উপস্থিত শেষের বন্ধনী " +"চিহ্ন " "অনুপস্থিত" -#: ../src/ui/theme.c:2394 +#: ../src/ui/theme.c:2599 #, c-format msgid "Coordinate expression doesn't seem to have any operators or operands" msgstr "কো-ওর্ডিনেট এক্সপ্রেশনের মধ্যে কোনো অপারেটর অথবা অপারেন্ড উপস্থিত নেই" -#: ../src/ui/theme.c:2596 ../src/ui/theme.c:2616 ../src/ui/theme.c:2636 +#: ../src/ui/theme.c:2812 ../src/ui/theme.c:2832 ../src/ui/theme.c:2852 #, c-format -#| msgid "Theme contained an expression \"%s\" that resulted in an error: %s\n" msgid "Theme contained an expression that resulted in an error: %s\n" msgstr "থিমের মধ্যে উপস্থিত এক্সপ্রেশনের ফলে সমস্যা উৎপন্ন হয়েছে: %s\n" -#: ../src/ui/theme.c:4187 +#: ../src/ui/theme.c:4455 #, c-format msgid "" "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " @@ -1795,39 +911,44 @@ msgstr "" "চিহ্নিত ফ্রেমের বিন্যাসের জন্য <button function=\"%s\" state=\"%s\" draw_ops=" "\"whatever\"/> উল্লেখ করা আবশ্যক" -#: ../src/ui/theme.c:4695 ../src/ui/theme.c:4720 +#: ../src/ui/theme.c:4970 ../src/ui/theme.c:4995 #, c-format -msgid "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "<frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/> অনুপস্থিত" +msgid "" +"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" +msgstr "" +"<frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/> অনুপস্থিত" -#: ../src/ui/theme.c:4764 +#: ../src/ui/theme.c:5041 #, c-format msgid "Failed to load theme \"%s\": %s\n" msgstr "\"%s\" থিম লোড করতে ব্যর্থ: %s\n" -#: ../src/ui/theme.c:4894 ../src/ui/theme.c:4901 ../src/ui/theme.c:4908 -#: ../src/ui/theme.c:4915 ../src/ui/theme.c:4922 +#: ../src/ui/theme.c:5177 ../src/ui/theme.c:5184 ../src/ui/theme.c:5191 +#: ../src/ui/theme.c:5198 ../src/ui/theme.c:5205 #, c-format msgid "No <%s> set for theme \"%s\"" msgstr "<%s> নির্ধারিত হয়নি \"%s\" থিমের জন্য" -#: ../src/ui/theme.c:4930 +#: ../src/ui/theme.c:5213 #, c-format msgid "" "No frame style set for window type \"%s\" in theme \"%s\", add a <window " "type=\"%s\" style_set=\"whatever\"/> element" msgstr "" -"\"%s\" ধরনের উইন্ডোর জন্য \"%s\" থিমের মধ্যে ফ্রেমের বিন্যাস নির্ধারিত হয়নি, একটি " +"\"%s\" ধরনের উইন্ডোর জন্য \"%s\" থিমের মধ্যে ফ্রেমের বিন্যাস নির্ধারিত হয়নি, " +"একটি " "<window type=\"%s\" style_set=\"whatever\"/> স্বত্বা যোগ করুন" -#: ../src/ui/theme.c:5383 ../src/ui/theme.c:5445 ../src/ui/theme.c:5508 +#: ../src/ui/theme.c:5620 ../src/ui/theme.c:5682 ../src/ui/theme.c:5745 #, c-format -msgid "User-defined constants must begin with a capital letter; \"%s\" does not" +msgid "" +"User-defined constants must begin with a capital letter; \"%s\" does not" msgstr "" -"ব্যবহারকারী দ্বারা নির্ধারিত কনস্ট্যান্টের ক্ষেত্রে প্রারম্ভে বড় ছাঁদের হরফ উপস্থিত থাকা " +"ব্যবহারকারী দ্বারা নির্ধারিত কনস্ট্যান্টের ক্ষেত্রে প্রারম্ভে বড় ছাঁদের হরফ " +"উপস্থিত থাকা " "আবশ্যক; \"%s\"'এ ক্ষেত্রে এটি উপস্থিত নেই" -#: ../src/ui/theme.c:5391 ../src/ui/theme.c:5453 ../src/ui/theme.c:5516 +#: ../src/ui/theme.c:5628 ../src/ui/theme.c:5690 ../src/ui/theme.c:5753 #, c-format msgid "Constant \"%s\" has already been defined" msgstr "কনস্ট্যান্ট \"%s\" পূর্বে নির্ধারিত হয়েছে" @@ -1835,58 +956,70 @@ msgstr "কনস্ট্যান্ট \"%s\" পূর্বে নির্ #. Translators: This means that an attribute which should have been found #. * on an XML element was not in fact found. #. -#: ../src/ui/theme-parser.c:202 +#: ../src/ui/theme-parser.c:234 #, c-format -#| msgid "No \"x\" attribute on element <%s>" msgid "No \"%s\" attribute on element <%s>" msgstr "<%s> স্বত্বায় \"%s\" অ্যাট্রিবিউট অনুপস্থিত" -#: ../src/ui/theme-parser.c:231 ../src/ui/theme-parser.c:249 +#: ../src/ui/theme-parser.c:263 ../src/ui/theme-parser.c:281 #, c-format msgid "Line %d character %d: %s" msgstr "পংক্তি %d অক্ষর %d: %s" -#: ../src/ui/theme-parser.c:413 +#: ../src/ui/theme-parser.c:481 #, c-format msgid "Attribute \"%s\" repeated twice on the same <%s> element" msgstr "বৈশিষ্ট্য \"%s\" একই <%s> স্বত্বায় দুইবার ব্যবহৃত হয়েছে" -#: ../src/ui/theme-parser.c:437 ../src/ui/theme-parser.c:480 +#: ../src/ui/theme-parser.c:505 ../src/ui/theme-parser.c:554 #, c-format msgid "Attribute \"%s\" is invalid on <%s> element in this context" msgstr "এই প্রসঙ্গে বৈশিষ্ট্য \"%s\", <%s> স্বত্বার ক্ষেত্রে বৈধ নয়" -#: ../src/ui/theme-parser.c:541 +#: ../src/ui/theme-parser.c:596 +#, c-format +msgid "Could not parse \"%s\" as an integer" +msgstr "পূর্ণসংখ্যা রূপে \"%s\" পার্স করতে ব্যর্থ" + +#: ../src/ui/theme-parser.c:605 ../src/ui/theme-parser.c:660 +#, c-format +msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +msgstr "অন্তিম অংশের \"%s\" অক্ষরগুলি \"%s\" পংক্তির মধ্যে বোধগম্য নয়" + +#: ../src/ui/theme-parser.c:615 #, c-format msgid "Integer %ld must be positive" msgstr "পূর্ণসংখ্যা %ld অবশ্যই শণ্যের অধিক হওয়া আবশ্যক" -#: ../src/ui/theme-parser.c:549 +#: ../src/ui/theme-parser.c:623 #, c-format msgid "Integer %ld is too large, current max is %d" msgstr "পূর্ণসংখ্যা %ld অত্যাধিক বড়, বর্তমানে সর্বাধিক মান %d" -#: ../src/ui/theme-parser.c:577 ../src/ui/theme-parser.c:693 +#: ../src/ui/theme-parser.c:651 ../src/ui/theme-parser.c:767 #, c-format msgid "Could not parse \"%s\" as a floating point number" msgstr "\"%s\"কে দশমিকযুক্ত সংখ্যা রূপে পার্স করতে ব্যর্থ" -#: ../src/ui/theme-parser.c:608 ../src/ui/theme-parser.c:636 +#: ../src/ui/theme-parser.c:682 ../src/ui/theme-parser.c:710 #, c-format msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "বুলিয়ান মান \"true\" অথবা \"false\" হওয়া আবশ্যক, \"%s\" ব্যবহার করা সম্ভব নয়" +msgstr "" +"বুলিয়ান মান \"true\" অথবা \"false\" হওয়া আবশ্যক, \"%s\" ব্যবহার করা সম্ভব নয়" -#: ../src/ui/theme-parser.c:663 +#: ../src/ui/theme-parser.c:737 #, c-format msgid "Angle must be between 0.0 and 360.0, was %g\n" msgstr "কোণের মান 0.0 থেকে 360.0'র মধ্যে হওয়া আবশ্যক, %g উল্লিখিত\n" -#: ../src/ui/theme-parser.c:726 +#: ../src/ui/theme-parser.c:800 #, c-format msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "আলফার মান 0.0 (অদৃশ্য) থেকে 1.0 (সম্পূর্ণ অস্বচ্ছ)'র মধ্যে হওয়া আবশ্যক, %g উল্লিখিত\n" +msgstr "" +"আলফার মান 0.0 (অদৃশ্য) থেকে 1.0 (সম্পূর্ণ অস্বচ্ছ)'র মধ্যে হওয়া আবশ্যক, %g " +"উল্লিখিত\n" -#: ../src/ui/theme-parser.c:791 +#: ../src/ui/theme-parser.c:865 #, c-format msgid "" "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," @@ -1895,514 +1028,731 @@ msgstr "" "শিরোনামের মাত্রা \"%s\" বৈধ নয় (xx-small,x-small,small,medium,large,x-large," "xx-large মানগুলির মধ্যে যে কোনো একটি হওয়া আবশ্যক)\n" -#: ../src/ui/theme-parser.c:936 ../src/ui/theme-parser.c:999 -#: ../src/ui/theme-parser.c:1033 ../src/ui/theme-parser.c:1136 +#: ../src/ui/theme-parser.c:1021 ../src/ui/theme-parser.c:1084 +#: ../src/ui/theme-parser.c:1118 ../src/ui/theme-parser.c:1221 #, c-format msgid "<%s> name \"%s\" used a second time" msgstr "<%s> নাম \"%s\"'এ দ্বিতীয়বার ব্যবহৃত হয়েছে " -#: ../src/ui/theme-parser.c:948 ../src/ui/theme-parser.c:1045 -#: ../src/ui/theme-parser.c:1148 +#: ../src/ui/theme-parser.c:1033 ../src/ui/theme-parser.c:1130 +#: ../src/ui/theme-parser.c:1233 #, c-format msgid "<%s> parent \"%s\" has not been defined" msgstr "<%s> উর্ধ্বতন বস্তু \"%s\" নির্ধারিত হয়নি" -#: ../src/ui/theme-parser.c:1058 +#: ../src/ui/theme-parser.c:1143 #, c-format msgid "<%s> geometry \"%s\" has not been defined" msgstr "<%s> জ্যামিতি \"%s\" সুনির্দিষ্ট নয়" -#: ../src/ui/theme-parser.c:1071 +#: ../src/ui/theme-parser.c:1156 #, c-format msgid "<%s> must specify either a geometry or a parent that has a geometry" msgstr "" -"<%s> দ্বারা জ্যামিতি নির্ধারিত হওয়া আবশ্যক অথবা ঊর্ধ্বতন বস্তুর ক্ষেত্রে জ্যামিতির " +"<%s> দ্বারা জ্যামিতি নির্ধারিত হওয়া আবশ্যক অথবা ঊর্ধ্বতন বস্তুর ক্ষেত্রে " +"জ্যামিতির " "উপস্থিতি আবশ্যক" -#: ../src/ui/theme-parser.c:1113 +#: ../src/ui/theme-parser.c:1198 msgid "You must specify a background for an alpha value to be meaningful" msgstr "" +"একটি অালফা মানকে অর্থপূর্ণ করে তুলতে, অাপনাকে অবশ্যই একটি ব্যাকগ্রাউন্ডের " +"উল্লেখ করতে " +"হবে" -#: ../src/ui/theme-parser.c:1180 +#: ../src/ui/theme-parser.c:1266 #, c-format msgid "Unknown type \"%s\" on <%s> element" msgstr "অজানা প্রকার \"%s\", <%s> স্বত্বায় উপস্থিত।" -#: ../src/ui/theme-parser.c:1191 +#: ../src/ui/theme-parser.c:1277 #, c-format msgid "Unknown style_set \"%s\" on <%s> element" msgstr "অজানা style_set \"%s\", <%s> স্বত্বায় উপস্থিত" -#: ../src/ui/theme-parser.c:1199 +#: ../src/ui/theme-parser.c:1285 #, c-format msgid "Window type \"%s\" has already been assigned a style set" msgstr "\"%s\" প্রকারের উইন্ডোর জন্য একটি স্টাইল সেট নির্ধারিত হয়েছে" -#: ../src/ui/theme-parser.c:1229 ../src/ui/theme-parser.c:1293 -#: ../src/ui/theme-parser.c:1519 ../src/ui/theme-parser.c:2732 -#: ../src/ui/theme-parser.c:2778 ../src/ui/theme-parser.c:2926 -#: ../src/ui/theme-parser.c:3118 ../src/ui/theme-parser.c:3156 -#: ../src/ui/theme-parser.c:3194 ../src/ui/theme-parser.c:3232 +#: ../src/ui/theme-parser.c:1315 ../src/ui/theme-parser.c:1379 +#: ../src/ui/theme-parser.c:1605 ../src/ui/theme-parser.c:2840 +#: ../src/ui/theme-parser.c:2886 ../src/ui/theme-parser.c:3036 +#: ../src/ui/theme-parser.c:3272 ../src/ui/theme-parser.c:3310 +#: ../src/ui/theme-parser.c:3348 ../src/ui/theme-parser.c:3386 #, c-format msgid "Element <%s> is not allowed below <%s>" msgstr "<%s> স্বত্বা <%s>'র নীচে ব্যবহার করা সম্ভব নয়" -#: ../src/ui/theme-parser.c:1343 ../src/ui/theme-parser.c:1357 -#: ../src/ui/theme-parser.c:1402 -#| msgid "" -#| "Cannot specify both button_width/button_height and aspect ratio for " -#| "buttons" +#: ../src/ui/theme-parser.c:1429 ../src/ui/theme-parser.c:1443 +#: ../src/ui/theme-parser.c:1488 msgid "" "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " "for buttons" msgstr "" -"বাটনের জন্য \"button_width\"/\"button_height\" ও \"aspect_ratio\" (অ্যাস্পেক্ট অনুপাত) উভয় একসাথে উল্লেখ করা " -"সম্ভব নয়" +"বাটনের জন্য \"button_width\"/\"button_height\" ও \"aspect_ratio\" " +"(অ্যাস্পেক্ট " +"অনুপাত) উভয় একসাথে উল্লেখ করা সম্ভব নয়" -#: ../src/ui/theme-parser.c:1366 +#: ../src/ui/theme-parser.c:1452 #, c-format msgid "Distance \"%s\" is unknown" msgstr "দুরত্ব \"%s\" অজানা" -#: ../src/ui/theme-parser.c:1411 +#: ../src/ui/theme-parser.c:1497 #, c-format msgid "Aspect ratio \"%s\" is unknown" msgstr "অ্যাস্পেক্ট অনুপাত \"%s\" অজানা" -#: ../src/ui/theme-parser.c:1473 +#: ../src/ui/theme-parser.c:1559 #, c-format msgid "Border \"%s\" is unknown" msgstr "প্রান্ত \"%s\" অজানা" -#: ../src/ui/theme-parser.c:1776 +#: ../src/ui/theme-parser.c:1870 #, c-format -#| msgid "No \"start_angle\" attribute on element <%s>" msgid "No \"start_angle\" or \"from\" attribute on element <%s>" msgstr "<%s> স্বত্বায় \"start_angle\" অথবা \"from\" বৈশিষ্ট্য অনুপস্থিত" -#: ../src/ui/theme-parser.c:1783 +#: ../src/ui/theme-parser.c:1877 #, c-format -#| msgid "No \"extent_angle\" attribute on element <%s>" msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" msgstr "<%s> স্বত্বায় \"extent_angle\" অথবা \"to\" বৈশিষ্ট্য অনুপস্থিত" -#: ../src/ui/theme-parser.c:2023 +#: ../src/ui/theme-parser.c:2117 #, c-format msgid "Did not understand value \"%s\" for type of gradient" msgstr "গ্রেডিয়েন্টের জন্যে \"%s\" মান বোধগম্য হয়নি" -#: ../src/ui/theme-parser.c:2101 ../src/ui/theme-parser.c:2476 +#: ../src/ui/theme-parser.c:2195 ../src/ui/theme-parser.c:2570 #, c-format msgid "Did not understand fill type \"%s\" for <%s> element" msgstr "ভরাট করার ধরন \"%s\" <%s> স্বত্বার জন্য বোধগম্য হয়নি" -#: ../src/ui/theme-parser.c:2268 ../src/ui/theme-parser.c:2351 -#: ../src/ui/theme-parser.c:2414 +#: ../src/ui/theme-parser.c:2362 ../src/ui/theme-parser.c:2445 +#: ../src/ui/theme-parser.c:2508 #, c-format msgid "Did not understand state \"%s\" for <%s> element" msgstr "অবস্থা \"%s\", <%s> স্বত্বার জন্য বোধগম্য হয়নি" -#: ../src/ui/theme-parser.c:2278 ../src/ui/theme-parser.c:2361 +#: ../src/ui/theme-parser.c:2372 ../src/ui/theme-parser.c:2455 #, c-format msgid "Did not understand shadow \"%s\" for <%s> element" msgstr "শেডো \"%s\", <%s> স্বত্বার জন্য বোধগম্য হয়নি" -#: ../src/ui/theme-parser.c:2288 +#: ../src/ui/theme-parser.c:2382 #, c-format msgid "Did not understand arrow \"%s\" for <%s> element" msgstr "তীরচিহ্ন \"%s\", <%s> স্বত্বার জন্য বোধগম্য হয়নি" -#: ../src/ui/theme-parser.c:2588 ../src/ui/theme-parser.c:2684 +#: ../src/ui/theme-parser.c:2696 ../src/ui/theme-parser.c:2792 #, c-format msgid "No <draw_ops> called \"%s\" has been defined" msgstr "\"%s\" নামক কোনো <draw_ops> নির্ধারিত হয়নি" -#: ../src/ui/theme-parser.c:2600 ../src/ui/theme-parser.c:2696 +#: ../src/ui/theme-parser.c:2708 ../src/ui/theme-parser.c:2804 #, c-format msgid "Including draw_ops \"%s\" here would create a circular reference" msgstr "" +"এখানে draw_ops \"%s\" অন্তর্ভুক্ত করলে তা একটি বৃত্তীয় রেফারেন্স তৈরি করবে" -#: ../src/ui/theme-parser.c:2811 +#: ../src/ui/theme-parser.c:2919 #, c-format msgid "Unknown position \"%s\" for frame piece" msgstr "ফ্রেমের অংশের জন্য \"%s\" অবস্থান অজানা" -#: ../src/ui/theme-parser.c:2819 +#: ../src/ui/theme-parser.c:2927 #, c-format msgid "Frame style already has a piece at position %s" msgstr "ফ্রেমের বিন্যাসের মধ্যে %s অবস্থানে একটি অংশ উপস্থিত রয়েছে" -#: ../src/ui/theme-parser.c:2836 ../src/ui/theme-parser.c:2911 +#: ../src/ui/theme-parser.c:2944 ../src/ui/theme-parser.c:3021 #, c-format msgid "No <draw_ops> with the name \"%s\" has been defined" msgstr "\"%s\" নামের কোনো <draw_ops> নির্ধারিত হয়নি" -#: ../src/ui/theme-parser.c:2865 +#: ../src/ui/theme-parser.c:2974 #, c-format msgid "Unknown function \"%s\" for button" msgstr "বাটনের অজানা ফাংশান \"%s\"" -#: ../src/ui/theme-parser.c:2874 +#: ../src/ui/theme-parser.c:2984 #, c-format msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "" +msgstr "বাটন ফাংশন \"% s\" এই সংস্করণটি (%d, %d প্রয়োজন) মধ্যে বিদ্যমান নয়" -#: ../src/ui/theme-parser.c:2886 +#: ../src/ui/theme-parser.c:2996 #, c-format msgid "Unknown state \"%s\" for button" msgstr "বাটনের অজানা অবস্থা \"%s\"" -#: ../src/ui/theme-parser.c:2894 +#: ../src/ui/theme-parser.c:3004 #, c-format msgid "Frame style already has a button for function %s state %s" msgstr "" -"function %s state %s বৈশিষ্ট্যের মানের ক্ষেত্রে ফ্রেম বিন্যাসের মধ্যে একটি বাটন " +"function %s state %s বৈশিষ্ট্যের মানের ক্ষেত্রে ফ্রেম বিন্যাসের মধ্যে একটি " +"বাটন " "উপস্থিত রয়েছে" -#: ../src/ui/theme-parser.c:2965 +#: ../src/ui/theme-parser.c:3075 #, c-format msgid "\"%s\" is not a valid value for focus attribute" msgstr "focus বৈশিষ্ট্যর মান হিসাবে \"%s\" গ্রহণযোগ্য নয়" -#: ../src/ui/theme-parser.c:2974 +#: ../src/ui/theme-parser.c:3084 #, c-format msgid "\"%s\" is not a valid value for state attribute" msgstr "state বৈশিষ্ট্যর মান হিসাবে \"%s\" গ্রহণযোগ্য নয়" -#: ../src/ui/theme-parser.c:2984 +#: ../src/ui/theme-parser.c:3094 #, c-format msgid "A style called \"%s\" has not been defined" msgstr "\"%s\" নামক বিন্যাস নির্ধারণ করা হয়নি" -#: ../src/ui/theme-parser.c:3005 ../src/ui/theme-parser.c:3028 +#: ../src/ui/theme-parser.c:3115 ../src/ui/theme-parser.c:3138 #, c-format msgid "\"%s\" is not a valid value for resize attribute" msgstr "resize বৈশিষ্ট্যর মান হিসাবে \"%s\" গ্রহণযোগ্য নয়" -#: ../src/ui/theme-parser.c:3039 +#: ../src/ui/theme-parser.c:3149 #, c-format msgid "" "Should not have \"resize\" attribute on <%s> element for maximized/shaded " "states" msgstr "" -"সর্বোচ্চ মাপ/ছায়াবৃত অবস্থার ক্ষেত্রে <%s> স্বত্বায় \"resize\" বৈশিষ্ট্য উপস্থিত থাকা " +"সর্বোচ্চ মাপ/ছায়াবৃত অবস্থার ক্ষেত্রে <%s> স্বত্বায় \"resize\" বৈশিষ্ট্য " +"উপস্থিত থাকা " "উচিত নয়" -#: ../src/ui/theme-parser.c:3053 +#: ../src/ui/theme-parser.c:3163 #, c-format -#| msgid "" -#| "Should not have \"resize\" attribute on <%s> element for maximized/shaded " -#| "states" -msgid "Should not have \"resize\" attribute on <%s> element for maximized states" +msgid "" +"Should not have \"resize\" attribute on <%s> element for maximized states" msgstr "" -"সর্বোচ্চ মাপে ক্ষেত্রে <%s> স্বত্বায় \"resize\" বৈশিষ্ট্য উপস্থিত থাকা " -"উচিত নয়" +"সর্বোচ্চ মাপে ক্ষেত্রে <%s> স্বত্বায় \"resize\" বৈশিষ্ট্য উপস্থিত থাকা উচিত নয়" -#: ../src/ui/theme-parser.c:3067 ../src/ui/theme-parser.c:3089 +#: ../src/ui/theme-parser.c:3177 ../src/ui/theme-parser.c:3221 #, c-format msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "state %s resize %s focus %s বৈশিষ্ট্য সহ অবস্থার ক্ষেত্রে বিন্যাস নির্ধারিত হয়েছে" +msgstr "" +"state %s resize %s focus %s বৈশিষ্ট্য সহ অবস্থার ক্ষেত্রে বিন্যাস নির্ধারিত " +"হয়েছে" -#: ../src/ui/theme-parser.c:3078 ../src/ui/theme-parser.c:3100 +#: ../src/ui/theme-parser.c:3188 ../src/ui/theme-parser.c:3199 +#: ../src/ui/theme-parser.c:3210 ../src/ui/theme-parser.c:3232 +#: ../src/ui/theme-parser.c:3243 ../src/ui/theme-parser.c:3254 #, c-format msgid "Style has already been specified for state %s focus %s" msgstr "state %s focus %s অবস্থার জন্য বিন্যাস নির্ধারিত হয়েছে" -#: ../src/ui/theme-parser.c:3139 +#: ../src/ui/theme-parser.c:3293 msgid "" "Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " "attribute and also a <draw_ops> element, or specified two elements)" msgstr "" -"একটি <piece> স্বত্বার সাথে দুটি draw_ops উপস্থিত থাকা সম্ভব নয় (থিম দ্বারা একটি " +"একটি <piece> স্বত্বার সাথে দুটি draw_ops উপস্থিত থাকা সম্ভব নয় (থিম দ্বারা " +"একটি " "draw_ops বৈশিষ্ট্য ও <draw_ops> স্বত্বা অথবা দুটি স্বত্বা উল্লিখিত হয়েছে)" -#: ../src/ui/theme-parser.c:3177 +#: ../src/ui/theme-parser.c:3331 msgid "" "Can't have a two draw_ops for a <button> element (theme specified a draw_ops " "attribute and also a <draw_ops> element, or specified two elements)" msgstr "" -"একটি <button> স্বত্বার সাথে দুটি draw_ops উপস্থিত থাকা সম্ভব নয় (থিম দ্বারা একটি " +"একটি <button> স্বত্বার সাথে দুটি draw_ops উপস্থিত থাকা সম্ভব নয় (থিম দ্বারা " +"একটি " "draw_ops বৈশিষ্ট্য ও <draw_ops> স্বত্বা অথবা দুটি স্বত্বা উল্লিখিত হয়েছে)" -#: ../src/ui/theme-parser.c:3215 +#: ../src/ui/theme-parser.c:3369 msgid "" "Can't have a two draw_ops for a <menu_icon> element (theme specified a " "draw_ops attribute and also a <draw_ops> element, or specified two elements)" msgstr "" -"একটি <menu> স্বত্বার সাথে দুটি draw_ops উপস্থিত থাকা সম্ভব নয় (থিম দ্বারা একটি " +"একটি <menu> স্বত্বার সাথে দুটি draw_ops উপস্থিত থাকা সম্ভব নয় (থিম দ্বারা " +"একটি " "draw_ops বৈশিষ্ট্য ও <draw_ops> স্বত্বা অথবা দুটি স্বত্বা উল্লিখিত হয়েছে)" -#: ../src/ui/theme-parser.c:3263 +#: ../src/ui/theme-parser.c:3433 +#, c-format +msgid "Bad version specification '%s'" +msgstr "খারাপ সংস্করণ স্পেসিফিকেশন '%s'" + +#: ../src/ui/theme-parser.c:3506 +msgid "" +"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" +"theme-2.xml" +msgstr "" +"\"version\" অ্যাট্রিবিউট metacity-theme-1.xml বা metacity-থিম-2.xml এ ব্যবহার " +"করা যাবে না" + +#: ../src/ui/theme-parser.c:3529 +#, c-format +msgid "Theme requires version %s but latest supported theme version is %d.%d" +msgstr "" +"থিমের প্রয়োজনীয় সংস্করণ %s কিন্তু সর্বশেষ সমর্থিত থিম সংস্করণ সংখ্যা হল %d। %" +"d" + +#: ../src/ui/theme-parser.c:3561 #, c-format msgid "Outermost element in theme must be <metacity_theme> not <%s>" msgstr "" +"থিমের মধ্যে কেন্দ্রস্থল থেকে সবচেয়ে দূরে অবস্থিত উপাদান <%s> নয় <" +"metacity_theme> " +"হওয়া আবশ্যক" -#: ../src/ui/theme-parser.c:3283 +#: ../src/ui/theme-parser.c:3581 #, c-format -msgid "Element <%s> is not allowed inside a name/author/date/description element" -msgstr " name/author/date/description স্বত্বার মধ্যে <%s> স্বত্বার ব্যবহার অনুমোদিত নয়" +msgid "" +"Element <%s> is not allowed inside a name/author/date/description element" +msgstr "" +"name/author/date/description স্বত্বার মধ্যে <%s> স্বত্বার ব্যবহার অনুমোদিত নয়" -#: ../src/ui/theme-parser.c:3288 +#: ../src/ui/theme-parser.c:3586 #, c-format msgid "Element <%s> is not allowed inside a <constant> element" msgstr "<constant> স্বত্বার মধ্যে <%s> স্বত্বার ব্যবহার অনুমোদিত নয়" -#: ../src/ui/theme-parser.c:3300 +#: ../src/ui/theme-parser.c:3598 #, c-format -msgid "Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "distance/border/aspect_ratio স্বত্বার মধ্যে <%s> স্বত্বার ব্যবহার অনুমোদিত নয়" +msgid "" +"Element <%s> is not allowed inside a distance/border/aspect_ratio element" +msgstr "" +"distance/border/aspect_ratio স্বত্বার মধ্যে <%s> স্বত্বার ব্যবহার অনুমোদিত নয়" -#: ../src/ui/theme-parser.c:3322 +#: ../src/ui/theme-parser.c:3620 #, c-format msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "draw operation (ড্র অপারেশন) স্বত্বার মধ্যে <%s> স্বত্বার ব্যবহার অনুমোদিত নয়" +msgstr "" +"draw operation (ড্র অপারেশন) স্বত্বার মধ্যে <%s> স্বত্বার ব্যবহার অনুমোদিত নয়" -#: ../src/ui/theme-parser.c:3332 ../src/ui/theme-parser.c:3362 -#: ../src/ui/theme-parser.c:3367 ../src/ui/theme-parser.c:3372 +#: ../src/ui/theme-parser.c:3630 ../src/ui/theme-parser.c:3660 +#: ../src/ui/theme-parser.c:3665 ../src/ui/theme-parser.c:3670 #, c-format msgid "Element <%s> is not allowed inside a <%s> element" msgstr "<%s> স্বত্বার মধ্যে <%s> স্বত্বার ব্যবহার অনুমোদিত নয়" -#: ../src/ui/theme-parser.c:3594 +#: ../src/ui/theme-parser.c:3898 msgid "No draw_ops provided for frame piece" msgstr "ফ্রেমের অংশের জন্য draw_ops উপলব্ধ নেই" -#: ../src/ui/theme-parser.c:3609 +#: ../src/ui/theme-parser.c:3913 msgid "No draw_ops provided for button" msgstr "বাটনের জন্য draw_ops উপলব্ধ নেই" -#: ../src/ui/theme-parser.c:3661 +#: ../src/ui/theme-parser.c:3967 #, c-format msgid "No text is allowed inside element <%s>" msgstr "<%s> স্বত্বার মধ্যে টেক্সটের ব্যবহার অনুমোদিত নয়" -#: ../src/ui/theme-parser.c:3716 -msgid "<name> specified twice for this theme" -msgstr "এই থিমের ক্ষেত্রে <name> দুইবার নির্দিষ্ট করা হয়েছে" - -#: ../src/ui/theme-parser.c:3727 -msgid "<author> specified twice for this theme" -msgstr "এই থিমের ক্ষেত্রে <author> দুইবার নির্দিষ্ট করা হয়েছে" - -#: ../src/ui/theme-parser.c:3738 -msgid "<copyright> specified twice for this theme" -msgstr "এই থিমের ক্ষেত্রে <copyright> দুইবার নির্দিষ্ট করা হয়েছে" - -#: ../src/ui/theme-parser.c:3749 -msgid "<date> specified twice for this theme" -msgstr "এই থিমের ক্ষেত্রে <date> দুইবার নির্দিষ্ট করা হয়েছে" - -#: ../src/ui/theme-parser.c:3760 -msgid "<description> specified twice for this theme" -msgstr "এই থিমের ক্ষেত্রে <description> দুইবার নির্দিষ্ট করা হয়েছে" +#: ../src/ui/theme-parser.c:4025 ../src/ui/theme-parser.c:4037 +#: ../src/ui/theme-parser.c:4049 ../src/ui/theme-parser.c:4061 +#: ../src/ui/theme-parser.c:4073 +#, c-format +msgid "<%s> specified twice for this theme" +msgstr "এই থিমের ক্ষেত্রে <%s> দুইবার নির্দিষ্ট করা হয়েছে" -#: ../src/ui/theme-parser.c:4027 +#: ../src/ui/theme-parser.c:4335 #, c-format -#| msgid "Failed to fdopen() log file %s: %s\n" msgid "Failed to find a valid file for theme %s\n" +msgstr "থিম %s-এর বৈধ ফাইল খুঁজে পেতে ব্যর্থ \n" + +#: ../src/x11/session.c:1815 +msgid "" +"These windows do not support "save current setup" and will have to " +"be restarted manually next time you log in." msgstr "" +"এই উইন্ডোগুলির দ্বারা \"save current setup\" বৈশিষ্ট্য সমর্থিত হয় না এবং " +"পরবর্তীবার " +"লগ-ইন করা হলে ব্যবহারকারীর দ্বারা পুনরায় আরম্ভীত করা প্রয়োজন।" -#: ../src/ui/theme-parser.c:4083 +#: ../src/x11/window-props.c:558 #, c-format -msgid "Theme file %s did not contain a root <metacity_theme> element" -msgstr "%s থিম ফাইলের মধ্যে root <metacity_theme> স্বত্বা অনুপস্থিত" +msgid "%s (on %s)" +msgstr "%s (%s'র উপর)" + +#~ msgid "background texture could not be created from file" +#~ msgstr "ফাইল থেকে ব্যাকগ্রাউন্ড পরিকাঠামো তৈরি করা যায়নি" + +#~ msgid "Unknown window information request: %d" +#~ msgstr "উইন্ডোর তথ্য সম্বন্ধে অজানা অনুরোধ: %d" -#: ../src/ui/theme-viewer.c:75 -msgid "/_Windows" -msgstr "/উইন্ডো (_W)" +#~ msgid "Missing %s extension required for compositing" +#~ msgstr "কম্পোসিটিং-র জন্য আবশ্যক %s এক্সটেনশন অনুপস্থিত" -#: ../src/ui/theme-viewer.c:76 -msgid "/Windows/tearoff" -msgstr "/উইন্ডো/টিয়ার-অফ" +# " উইন্ডো অবৃহদায়ত কর" +#~ msgid "" +#~ "Some other program is already using the key %s with modifiers %x as a " +#~ "binding\n" +#~ msgstr "একটি পৃথক প্রোগ্রাম দ্বারা বর্তমানে %s-কি, %x বাইন্ডিং সহ ব্যবহৃত হচ্ছে\n" -#: ../src/ui/theme-viewer.c:77 -msgid "/Windows/_Dialog" -msgstr "/উইন্ডো/ডায়লগ (_D)" +#~ msgid "\"%s\" is not a valid accelerator\n" +#~ msgstr "\"%s\" একটি বৈধ অ্যাকসিলেটর নয়\n" -#: ../src/ui/theme-viewer.c:78 -msgid "/Windows/_Modal dialog" -msgstr "/উইন্ডো/মোডাল ডায়লগ (_M)" +#~ msgid "" +#~ "Workarounds for broken applications disabled. Some applications may not " +#~ "behave properly.\n" +#~ msgstr "" +#~ "ক্ষতিগ্রস্ত অ্যাপ্লিকেশনের ত্রুটি অগ্রাহ্য করার প্রণালী নিষ্ক্রিয় করা হয়েছে। কয়েকটি " +#~ "অ্যাপ্লিকেশন সম্ভবত সঠিকরূপে চালানো সম্ভব হবে না।\n" -#: ../src/ui/theme-viewer.c:79 -msgid "/Windows/_Utility" -msgstr "/উইন্ডো/সামগ্রী (_U)" +#~ msgid "Could not parse font description \"%s\" from GSettings key %s\n" +#~ msgstr "\"%s\" ফন্টের বিবরণ GSettings-কি %s থেকে পার্স করতে ব্যর্থ\n" -#: ../src/ui/theme-viewer.c:80 -msgid "/Windows/_Splashscreen" -msgstr "/উইন্ডো/স্প্ল্যাশ-স্ক্রিন (_S)" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" +#~ msgstr "" +#~ "কনফিগারেশন ডাটাবেসের মধ্যে উপস্থিত \"%s\" মাউস বাটন পরিবর্তকের জন্য বৈধ মান " +#~ "নয়\n" + +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for " +#~ "keybinding \"%s\"\n" +#~ msgstr "" +#~ "কনফিগারেশন ডাটাবেসের মধ্যে উপলব্ধ \"%s\", \"%s\" কি-বাইন্ডিং'র ক্ষেত্রে বৈধ " +#~ "মান নয়\n" + +#~ msgid "" +#~ "Could not acquire window manager selection on screen %d display \"%s\"\n" +#~ msgstr "" +#~ "পর্দা %d (ডিসপ্লে \"%s\")'র মধ্যে উইন্ডো পরিচালন ব্যবস্থার নির্বাচিত অংশ গ্রহণ " +#~ "করতে ব্যর্থ\n" + +#~ msgid "Could not release screen %d on display \"%s\"\n" +#~ msgstr "পর্দা %d (ডিসপ্লে \"%s\") মুক্ত করতে ব্যর্থ\n" + +#~ msgid "Could not create directory '%s': %s\n" +#~ msgstr "ডিরেক্টরি '%s' নির্মাণ করতে ব্যর্থ: %s\n" + +#~ msgid "Could not open session file '%s' for writing: %s\n" +#~ msgstr "লেখার উদ্দেশ্যে সেশান ফাইল '%s' খুলতে ব্যর্থ: %s\n" + +#~ msgid "Error writing session file '%s': %s\n" +#~ msgstr "সেশান ফাইল '%s' লিখতে ব্যর্থ: %s\n" + +#~ msgid "Error closing session file '%s': %s\n" +#~ msgstr "সেশান ফাইল '%s' বন্ধ করতে ব্যর্থ: %s\n" + +#~ msgid "Failed to parse saved session file: %s\n" +#~ msgstr "সংরক্ষিত সেশান ফাইল পার্স করতে ব্যর্থ: %s\n" + +#~ msgid "<mutter_session> attribute seen but we already have the session ID" +#~ msgstr "<mutter_session> বৈশিষ্ট্য প্রদর্শিত কিন্তু সেশান ID বর্তমানে উপস্থিত রয়েছে" + +#~ msgid "Unknown attribute %s on <%s> element" +#~ msgstr "অজানা বৈশিষ্ট্য %s, <%s> স্বত্বায় চিহ্নিত হয়েছে" + +#~ msgid "nested <window> tag" +#~ msgstr "নেস্টেড <window> ট্যাগ" + +#~ msgid "Unknown element %s" +#~ msgstr "অজানা স্বত্বা %s" + +#~ msgid "Failed to open debug log: %s\n" +#~ msgstr "ডিবাগ লগ খুলতে ব্যর্থ: %s\n" + +#~ msgid "Failed to fdopen() log file %s: %s\n" +#~ msgstr "fdopen() লগ ফাইল %s খুলতে ব্যর্থ: %s\n" + +#~ msgid "Opened log file %s\n" +#~ msgstr "লগ ফাইল %s খোলা হয়েছে\n" + +#~ msgid "Window manager: " +#~ msgstr "উইন্ডো পরিচালন ব্যবস্থা: " + +#~ msgid "Bug in window manager: " +#~ msgstr "উইন্ডো পরিচালনব্যবস্থা সংক্রান্ত সমস্যা: " + +#~ msgid "Window manager warning: " +#~ msgstr "উইন্ডো পরিচালন ব্যবস্থা সংক্রান্ত সতর্কবার্তা: " + +#~ msgid "Window manager error: " +#~ msgstr "উইন্ডো পরিচালন ব্যবস্থা সংক্রান্ত ত্রুটি: " + +#~ msgid "" +#~ "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " +#~ "window as specified in the ICCCM.\n" +#~ msgstr "" +#~ "উইন্ডো %s দ্বারা ICCCM'এ নির্ধারিত WM_CLIENT_LEADER উইন্ডোর পরিবর্তে নিজের উপর " +#~ "SM_CLIENT_ID নির্ধারিত হয়েছে।\n" + +#~ msgid "" +#~ "Window %s sets an MWM hint indicating it isn't resizable, but sets min " +#~ "size %d x %d and max size %d x %d; this doesn't make much sense.\n" +#~ msgstr "" +#~ "উইন্ডো %s একটি MWM হিন্ট করে যা সূচিত করে যে এটির মাপ পরিবর্তন করা যায় না, " +#~ "তবে সর্বনিম্ন মাপ %d x %d এবং সর্বাধিক মাপ %d x %d সেট করে; যার খুব বেশি গুরুত্ব " +#~ "নেই।\n" + +#~ msgid "Application set a bogus _NET_WM_PID %lu\n" +#~ msgstr "অ্যাপ্লিকেশন দ্বারা ভুল _NET_WM_PID %lu নির্ধারিত হয়েছে\n" + +#~ msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +#~ msgstr "অবৈধ WM_TRANSIENT_FOR উইন্ডো 0x%lx, %s'র জন্য নির্ধারিত হয়েছে।\n" + +#~ msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" +#~ msgstr "WM_TRANSIENT_FOR উইন্ডো 0x%lx %s এর জন্য লুপ তৈরি করবে।\n" -#: ../src/ui/theme-viewer.c:81 -msgid "/Windows/_Top dock" -msgstr "/উইন্ডো/উপরে আটকানো হবে (_T)" +#~ msgid "" +#~ "Window 0x%lx has property %s\n" +#~ "that was expected to have type %s format %d\n" +#~ "and actually has type %s format %d n_items %d.\n" +#~ "This is most likely an application bug, not a window manager bug.\n" +#~ "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +#~ msgstr "" +#~ "উইন্ডো 0x%lx এর বিশিষ্টতা হল %s\n" +#~ "যার প্রত্যাশিত ধরন হল %s ফর্ম্যাট %d\n" +#~ "এবং বাস্তবিক ধরন হল %s ফর্ম্যাট %d n_items %d।\n" +#~ "খুব সম্ভবতঃ এটি একটি অ্যাপ্লিকেশন বাগ, এবং উইন্ডো ম্যানেজার বাগ নয়।\n" +#~ "উইন্ডোর টাইটেল=\"%s\" ক্লাস=\"%s\" নাম=\"%s\"\n" -#: ../src/ui/theme-viewer.c:82 -msgid "/Windows/_Bottom dock" -msgstr "/উইন্ডো/নীচে আটকানো হবে (_B)" +#~ msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +#~ msgstr "" +#~ "%s বৈশিষ্ট্যটি 0x%lx উইন্ডোর উপর উপস্থিত ও এর মধ্যে অবৈধ UTF-8 অক্ষর অন্তর্ভুক্ত " +#~ "রয়েছে\n" -#: ../src/ui/theme-viewer.c:83 -msgid "/Windows/_Left dock" -msgstr "/উইন্ডো/বাঁদিকে আটকানো হবে (_L)" +# FIXME msgstr "%s বিশেষত্বটি জানালা 0x%lx -তে অন্যায্য UTF-8 আছে\n +#~ msgid "" +#~ "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the " +#~ "list\n" +#~ msgstr "" +#~ "%s বৈশিষ্ট্যটি 0x%lx উইন্ডোর উপর উপস্থিত ও এর তালিকায় %d সংখ্যক বস্তুর মধ্যে অবৈধ " +#~ "UTF-8 অক্ষর অন্তর্ভুক্ত রয়েছে\n" -#: ../src/ui/theme-viewer.c:84 -msgid "/Windows/_Right dock" -msgstr "/উইন্ডো/ডানদিকে আটকানো হবে (_R)" +#~ msgid "Usage: %s\n" +#~ msgstr "ব্যবহারপদ্ধতি: %s\n" -#: ../src/ui/theme-viewer.c:85 -msgid "/Windows/_All docks" -msgstr "/উইন্ডো/সমস্ত সংযুক্ত (_A)" +#~ msgid "Mi_nimize" +#~ msgstr "আড়াল করুন (_n)" -#: ../src/ui/theme-viewer.c:86 -msgid "/Windows/Des_ktop" -msgstr "/উইন্ডো/ডেস্কটপ (_k)" +#~ msgid "Ma_ximize" +#~ msgstr "বড় করুন (_x)" -#: ../src/ui/theme-viewer.c:135 -msgid "Open another one of these windows" -msgstr "এই ধরনের একটি নতুন উইন্ডো খুলুন" +#~ msgid "Unma_ximize" +#~ msgstr "স্বাভাবিক মাপ (_x)" -#: ../src/ui/theme-viewer.c:142 -msgid "This is a demo button with an 'open' icon" -msgstr "'খোলা' আইকন বিশিষ্ট এটি একটি নমূনা বাটন" +#~ msgid "Roll _Up" +#~ msgstr "গোটাও (_U)" -#: ../src/ui/theme-viewer.c:149 -msgid "This is a demo button with a 'quit' icon" -msgstr "'প্রস্থান' আইকন বিশিষ্ট এটি একটি নমূনা বাটন" +#~ msgid "_Unroll" +#~ msgstr "খোলো (_U)" -#: ../src/ui/theme-viewer.c:242 -msgid "This is a sample message in a sample dialog" -msgstr "এটি নমুনা ডায়লগ বক্সে একটি নমুনা বার্তা" +#~ msgid "_Move" +#~ msgstr "স্থানান্তরণ (_M)" -#: ../src/ui/theme-viewer.c:325 -#, c-format -msgid "Fake menu item %d\n" -msgstr "নকল মেনু বস্তু %d\n" +#~ msgid "_Resize" +#~ msgstr "মাপ পরিবর্তন (_R)" -#: ../src/ui/theme-viewer.c:359 -msgid "Border-only window" -msgstr "শুধুমাত্র প্রান্তবিশিষ্ট উইন্ডো" +#~ msgid "Move Titlebar On_screen" +#~ msgstr "পর্দার উপর শিরোনামের বার স্থানান্তর করুন (_s)" -#: ../src/ui/theme-viewer.c:361 -msgid "Bar" -msgstr "বার" +#~ msgid "Always on _Top" +#~ msgstr "সর্বদা উপরে (_T)" -#: ../src/ui/theme-viewer.c:378 -msgid "Normal Application Window" -msgstr "স্বাভাবিক অ্যাপ্লিকেশন উইন্ডো" +#~ msgid "_Always on Visible Workspace" +#~ msgstr "দৃশ্যমান কর্মক্ষেত্রে সর্বদা উপস্থিত (_A)" -#: ../src/ui/theme-viewer.c:382 -msgid "Dialog Box" -msgstr "ডায়লগ বক্স" +#~ msgid "_Only on This Workspace" +#~ msgstr "শুধুমাত্র বর্তমান কর্মক্ষেত্রে (_O)" -#: ../src/ui/theme-viewer.c:386 -msgid "Modal Dialog Box" -msgstr "মোডাল ডায়লগ বক্স" +#~ msgid "Move to Workspace _Left" +#~ msgstr "বাঁদিকের কর্মক্ষেত্রে স্থানান্তর করুন (_L)" -#: ../src/ui/theme-viewer.c:390 -msgid "Utility Palette" -msgstr "সরঞ্জাম সহ প্যালেট" +#~ msgid "Move to Workspace R_ight" +#~ msgstr "ডান দিকের কর্মক্ষেত্রে স্থানান্তর করুন (_i)" -#: ../src/ui/theme-viewer.c:394 -msgid "Torn-off Menu" -msgstr "পরিবর্তনশীল অবস্থানের মেনু" +#~ msgid "Move to Workspace _Up" +#~ msgstr "উপরের কর্মক্ষেত্রে স্থানান্তরণ (_U)" -#: ../src/ui/theme-viewer.c:398 -msgid "Border" -msgstr "প্রান্তরেখা" +#~ msgid "Move to Workspace _Down" +#~ msgstr "নীচের কর্মক্ষেত্রে স্থানান্তরণ (_D)" -#: ../src/ui/theme-viewer.c:726 -#, c-format -msgid "Button layout test %d" -msgstr "বাটন বিন্যাসের পরীক্ষা %d" +#~ msgid "_Close" +#~ msgstr "বন্ধ করুন (_C)" -#: ../src/ui/theme-viewer.c:755 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "একটি উইন্ডো ফ্রেম নির্মাণের জন্য %g মিলিসেকেন্ড" +#~ msgid "Workspace %d%n" +#~ msgstr "কর্মক্ষেত্র %d%n" -#: ../src/ui/theme-viewer.c:798 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "ব্যবহারপদ্ধতি: metacity-theme-viewer [THEMENAME]\n" +#~ msgid "Workspace 1_0" +#~ msgstr "কর্মক্ষেত্র ১০ (_0)" -#: ../src/ui/theme-viewer.c:805 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "থিম লোড করতে সমস্যা: %s\n" +#~ msgid "Workspace %s%d" +#~ msgstr "কর্মক্ষেত্র %s%d" -#: ../src/ui/theme-viewer.c:811 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "\"%s\" থিম %g সেকেন্ডে লোড করা হয়েছে\n" +#~ msgid "Move to Another _Workspace" +#~ msgstr "পৃথক কর্মক্ষেত্রে স্থানান্তর করুন (_W)" -#: ../src/ui/theme-viewer.c:852 -msgid "Normal Title Font" -msgstr "স্বাভাবিক মাপের শিরোনামে ব্যবহৃত ফন্ট" +#~ msgid "Shift" +#~ msgstr "Shift" -#: ../src/ui/theme-viewer.c:858 -msgid "Small Title Font" -msgstr "ছোট মাপের শিরোনামে ব্যবহৃত ফন্ট" +#~ msgid "Ctrl" +#~ msgstr "Ctrl" -#: ../src/ui/theme-viewer.c:864 -msgid "Large Title Font" -msgstr "বড় মাপের শিরোনামে ব্যবহৃত ফন্ট" +#~ msgid "Alt" +#~ msgstr "Alt" -#: ../src/ui/theme-viewer.c:869 -msgid "Button Layouts" -msgstr "বাটনের বিন্যাস" +#~ msgid "Meta" +#~ msgstr "মিটা" -#: ../src/ui/theme-viewer.c:874 -msgid "Benchmark" -msgstr "" +#~ msgid "Super" +#~ msgstr "Super" -#: ../src/ui/theme-viewer.c:921 -msgid "Window Title Goes Here" -msgstr "উইন্ডো শিরোনাম চিহ্নিত স্থানে স্থাপিত হবে" +#~ msgid "Hyper" +#~ msgstr "Hyper" -#: ../src/ui/theme-viewer.c:1025 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" +#~ msgid "Mod2" +#~ msgstr "Mod2" -#: ../src/ui/theme-viewer.c:1244 -msgid "position expression test returned TRUE but set error" -msgstr "" -"অবস্থান চিহ্নকারী এক্সপ্রেশনের পরীক্ষা দ্বারা মান TRUE উল্লিখিত হলেও ত্রুটি নির্ধারিত " -"হয়েছে" +#~ msgid "Mod3" +#~ msgstr "Mod3" -#: ../src/ui/theme-viewer.c:1246 -msgid "position expression test returned FALSE but didn't set error" -msgstr "" -"অবস্থান চিহ্নকারী এক্সপ্রেশনের পরীক্ষা দ্বারা মান FALSE উল্লিখিত হলেও ত্রুটি নির্ধারিত " -"হয়নি" +#~ msgid "Mod4" +#~ msgstr "Mod4" -#: ../src/ui/theme-viewer.c:1250 -msgid "Error was expected but none given" -msgstr "ত্রুটি প্রত্যাশিত কিন্তু উল্লিখিত হয়নি" +#~ msgid "Mod5" +#~ msgstr "Mod5" -#: ../src/ui/theme-viewer.c:1252 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "ত্রুটি %d প্রত্যাশিত %d প্রদত্ত" +#~ msgid "_Windows" +#~ msgstr "উইন্ডোগুলি (_W)" -#: ../src/ui/theme-viewer.c:1258 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "ত্রুটি প্রত্যাশিত নয় কিন্তু প্রাপ্ত: %s" +#~ msgid "_Dialog" +#~ msgstr "ডায়লগ (_D)" -#: ../src/ui/theme-viewer.c:1262 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "x'র মান %d, %d প্রত্যাশিত" +#~ msgid "_Modal dialog" +#~ msgstr "মোডাল ডায়লগ (_M)" -#: ../src/ui/theme-viewer.c:1265 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "y'র মান %d, %d প্রত্যাশিত" +#~ msgid "_Utility" +#~ msgstr "সামগ্রী (_U)" -#: ../src/ui/theme-viewer.c:1330 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "%d কো-ওর্ডিনেট এক্সপ্রেশন %g সেকেন্ডে পার্স করা হয়েছে (গড় %g সেকেন্ড)\n" +#~ msgid "_Splashscreen" +#~ msgstr "স্প্ল্যাশ-স্ক্রিন (_S)" + +#~ msgid "_Top dock" +#~ msgstr "উপরে আটকানো হবে (_T)" + +#~ msgid "_Bottom dock" +#~ msgstr "নীচে আটকানো হবে (_B)" + +#~ msgid "_Left dock" +#~ msgstr "বাঁদিকে আটকানো হবে (_L)" + +#~ msgid "_Right dock" +#~ msgstr "ডানদিকে আটকানো হবে (_R)" + +#~ msgid "_All docks" +#~ msgstr "সমস্ত সংযুক্ত (_A)" + +#~ msgid "Des_ktop" +#~ msgstr "ডেস্কটপ (_k)" + +#~ msgid "Open another one of these windows" +#~ msgstr "এই ধরনের একটি নতুন উইন্ডো খুলুন" + +#~ msgid "This is a demo button with an 'open' icon" +#~ msgstr "'খোলা' আইকন বিশিষ্ট এটি একটি নমূনা বাটন" + +#~ msgid "This is a demo button with a 'quit' icon" +#~ msgstr "'প্রস্থান' আইকন বিশিষ্ট এটি একটি নমূনা বাটন" + +#~ msgid "This is a sample message in a sample dialog" +#~ msgstr "এটি নমুনা ডায়লগ বক্সে একটি নমুনা বার্তা" + +#~ msgid "Fake menu item %d\n" +#~ msgstr "নকল মেনু বস্তু %d\n" + +#~ msgid "Border-only window" +#~ msgstr "শুধুমাত্র প্রান্তবিশিষ্ট উইন্ডো" + +#~ msgid "Bar" +#~ msgstr "বার" + +#~ msgid "Normal Application Window" +#~ msgstr "স্বাভাবিক অ্যাপ্লিকেশন উইন্ডো" + +#~ msgid "Dialog Box" +#~ msgstr "ডায়লগ বক্স" + +#~ msgid "Modal Dialog Box" +#~ msgstr "মোডাল ডায়লগ বক্স" + +#~ msgid "Utility Palette" +#~ msgstr "সরঞ্জাম সহ প্যালেট" + +#~ msgid "Torn-off Menu" +#~ msgstr "পরিবর্তনশীল অবস্থানের মেনু" + +#~ msgid "Border" +#~ msgstr "প্রান্তরেখা" + +#~ msgid "Attached Modal Dialog" +#~ msgstr "সংযুক্ত মোডাল ডায়লগ" + +#~ msgid "Button layout test %d" +#~ msgstr "বাটন বিন্যাসের পরীক্ষা %d" + +#~ msgid "%g milliseconds to draw one window frame" +#~ msgstr "একটি উইন্ডো ফ্রেম নির্মাণের জন্য %g মিলিসেকেন্ড" + +#~ msgid "Usage: metacity-theme-viewer [THEMENAME]\n" +#~ msgstr "ব্যবহারপদ্ধতি: metacity-theme-viewer [THEMENAME]\n" + +#~ msgid "Error loading theme: %s\n" +#~ msgstr "থিম লোড করতে সমস্যা: %s\n" + +#~ msgid "Loaded theme \"%s\" in %g seconds\n" +#~ msgstr "\"%s\" থিম %g সেকেন্ডে লোড করা হয়েছে\n" + +#~ msgid "Normal Title Font" +#~ msgstr "স্বাভাবিক মাপের শিরোনামে ব্যবহৃত ফন্ট" + +#~ msgid "Small Title Font" +#~ msgstr "ছোট মাপের শিরোনামে ব্যবহৃত ফন্ট" + +#~ msgid "Large Title Font" +#~ msgstr "বড় মাপের শিরোনামে ব্যবহৃত ফন্ট" + +#~ msgid "Button Layouts" +#~ msgstr "বাটনের বিন্যাস" + +#~ msgid "Benchmark" +#~ msgstr "মাত্রাবিশিষ্ট" + +#~ msgid "Window Title Goes Here" +#~ msgstr "উইন্ডো শিরোনাম চিহ্নিত স্থানে স্থাপিত হবে" + +#~ msgid "" +#~ "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and " +#~ "%g seconds wall clock time including X server resources (%g milliseconds " +#~ "per frame)\n" +#~ msgstr "" +#~ "অাঁকা হয়েছে %d ফ্রেম %g client-side সেকেন্ডে (ফ্রেম প্রতি %g মিলিসেকেন্ড) এবং " +#~ "%g সেকেন্ড দেওয়াল ঘড়ি সময় X সার্ভার রিসোর্স সমেত (ফ্রেম প্রতি %g মিলিসেকেন্ড)\n" + +#~ msgid "position expression test returned TRUE but set error" +#~ msgstr "" +#~ "অবস্থান চিহ্নকারী এক্সপ্রেশনের পরীক্ষা দ্বারা মান TRUE উল্লিখিত হলেও ত্রুটি " +#~ "নির্ধারিত হয়েছে" + +#~ msgid "position expression test returned FALSE but didn't set error" +#~ msgstr "" +#~ "অবস্থান চিহ্নকারী এক্সপ্রেশনের পরীক্ষা দ্বারা মান FALSE উল্লিখিত হলেও ত্রুটি " +#~ "নির্ধারিত হয়নি" + +#~ msgid "Error was expected but none given" +#~ msgstr "ত্রুটি প্রত্যাশিত কিন্তু উল্লিখিত হয়নি" + +#~ msgid "Error %d was expected but %d given" +#~ msgstr "ত্রুটি %d প্রত্যাশিত %d প্রদত্ত" + +#~ msgid "Error not expected but one was returned: %s" +#~ msgstr "ত্রুটি প্রত্যাশিত নয় কিন্তু প্রাপ্ত: %s" + +#~ msgid "x value was %d, %d was expected" +#~ msgstr "x'র মান %d, %d প্রত্যাশিত" + +#~ msgid "y value was %d, %d was expected" +#~ msgstr "y'র মান %d, %d প্রত্যাশিত" +#~ msgid "" +#~ "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" +#~ msgstr "%d কো-ওর্ডিনেট এক্সপ্রেশন %g সেকেন্ডে পার্স করা হয়েছে (গড় %g সেকেন্ড)\n" diff --git a/po/br.po b/po/br.po index 1a3aa7942..ce05a9e06 100644 --- a/po/br.po +++ b/po/br.po @@ -1,17 +1,18 @@ -# Breton translation for Muffin +# Breton translation for Mutter # Copyright (c) Free Software Foundation, Inc. 2009 -# This file is distributed under the same license as the muffin package. +# This file is distributed under the same license as the mutter package. # # Denis <denisarnuad@yahoo.fr>, 2009. # msgid "" msgstr "" -"Project-Id-Version: muffin\n" -"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=muffin&component=general\n" +"Project-Id-Version: mutter\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=mutter&component=general\n" "POT-Creation-Date: 2009-09-07 18:37+0000\n" "PO-Revision-Date: 2009-09-14 04:51+0100\n" "Last-Translator: Denis\n" "Language-Team: Brenux <brenux@free.fr>\n" +"Language: br\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -100,12 +101,12 @@ msgstr "N'eus bet despizet arc'had termenell ebet.\n" #: ../src/core/main.c:127 #, c-format msgid "" -"muffin %s\n" +"mutter %s\n" "Copyright (C) 2001-2008 Havoc Pennington, Red Hat, Inc., and others\n" "This is free software; see the source for copying conditions.\n" "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" msgstr "" -"muffin %s\n" +"mutter %s\n" "Copyright (C) 2001-2008 Havoc Pennington, Red Hat, Inc., hag all\n" "Digor eo ar meziant-mañ; gwelit tarzh evit an amplegadoù eilañ.\n" "N'eus gwarant EBET; na talvoud kenwerzhpe .na implij prevez ispisial.\n" @@ -115,8 +116,8 @@ msgid "Disable connection to session manager" msgstr "Diweredekaat kennask ouzh ardoer an estezioù" #: ../src/core/main.c:263 -msgid "Replace the running window manager with Muffin" -msgstr "Arverañ Muffin e lec'h an ardoer prenestroù en implij" +msgid "Replace the running window manager with Mutter" +msgstr "Arverañ Mutter e lec'h an ardoer prenestroù en implij" #: ../src/core/main.c:269 msgid "Specify session management ID" @@ -323,7 +324,7 @@ msgstr "" #: ../src/core/session.c:1195 #, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" +msgid "<mutter_session> attribute seen but we already have the session ID" msgstr "" #: ../src/core/session.c:1208 @@ -366,10 +367,10 @@ msgid "Opened log file %s\n" msgstr "" #: ../src/core/util.c:138 -#: ../src/tools/muffin-message.c:176 +#: ../src/tools/mutter-message.c:176 #, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "Savet eo bet Muffin hep ar mod displegus (verbose mode)\n" +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Savet eo bet Mutter hep ar mod displegus (verbose mode)\n" #: ../src/core/util.c:238 msgid "Window manager: " @@ -390,10 +391,10 @@ msgstr "Fazi ardoer prenestroù : " #. Translators: This is the title used on dialog boxes #. eof all-keybindings.h #: ../src/core/util.c:570 -#: ../src/muffin.desktop.in.h:1 -#: ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" +#: ../src/mutter.desktop.in.h:1 +#: ../src/mutter-wm.desktop.in.h:1 +msgid "Mutter" +msgstr "Mutter" #. first time through #: ../src/core/window.c:6086 @@ -756,31 +757,31 @@ msgstr "" msgid "Move window to center of screen" msgstr "Dilec'hiañ ar prenestr betek kreiz ar skramm" -#: ../src/muffin.schemas.in.h:1 +#: ../src/mutter.schemas.in.h:1 msgid "Clutter Plugins" msgstr "Enlugelladoù Clutter" -#: ../src/muffin.schemas.in.h:2 +#: ../src/mutter.schemas.in.h:2 msgid "Determines whether hidden windows (i.e., minimized windows and windows on other workspaces than the current one) should be kept alive." msgstr "" -#: ../src/muffin.schemas.in.h:3 +#: ../src/mutter.schemas.in.h:3 msgid "Live Hidden Windows" msgstr "" -#: ../src/muffin.schemas.in.h:4 +#: ../src/mutter.schemas.in.h:4 msgid "Modifier to use for extended window management operations" msgstr "Kemmer da implijout evit gwezhadurioù ardeiñ ar prenestroù astennet" -#: ../src/muffin.schemas.in.h:5 +#: ../src/mutter.schemas.in.h:5 msgid "Plugins to load for the Clutter-based compositing manager." msgstr "" -#: ../src/muffin.schemas.in.h:6 +#: ../src/mutter.schemas.in.h:6 msgid "This key will initiate the \"overlay\", which is a combination window overview and application launching system. The default is intended to be the \"Windows key\" on PC hardware. It's expected that this binding either the default or set to the empty string." msgstr "" -#: ../src/tools/muffin-message.c:150 +#: ../src/tools/mutter-message.c:150 #, c-format msgid "Usage: %s\n" msgstr "Arver : %s\n" diff --git a/po/bs.po b/po/bs.po index c4fa65b9d..d80bb2a8c 100644 --- a/po/bs.po +++ b/po/bs.po @@ -1,3263 +1,612 @@ -# translation of metacity.HEAD.po to Bosnian -# This file is distributed under the same license as the metacity package. -# Copyright (C) 2004 Free Software Foundation, Inc. -# Kemal Sanjta <gomez@lugzdk.ba>, 2004. +# Bosnian translation for gsettings-desktop-schemas +# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 +# This file is distributed under the same license as the gsettings-desktop-schemas package. +# FIRST AUTHOR <EMAIL@ADDRESS>, 2011. # msgid "" msgstr "" -"Project-Id-Version: metacity.HEAD\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2005-09-19 12:30+0200\n" -"PO-Revision-Date: 2004-07-30 02:16+0200\n" -"Last-Translator: Kemal Sanjta <gomez@lugzdk.ba>\n" -"Language-Team: Bosnian <+>\n" +"Project-Id-Version: gsettings-desktop-schemas\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=mutter&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2015-02-26 23:17+0000\n" +"PO-Revision-Date: 2015-03-02 14:51+0100\n" +"Last-Translator: Belma Skopljakovic <belma_skop14@hotmail.com>\n" +"Language-Team: Bosnian <bs@li.org>\n" +"Language: bs\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: KBabel 1.3.1\n" +"X-Launchpad-Export-Date: 2015-02-05 07:04+0000\n" +"X-Generator: Poedit 1.7.4\n" -#: ../src/tools/metacity-message.c:150 -#, c-format -msgid "Usage: %s\n" -msgstr "Iskorištenost: %s\n" - -#: ../src/tools/metacity-message.c:176 ../src/util.c:128 -msgid "Metacity was compiled without support for verbose mode\n" -msgstr "Metaciti je kompajliran bez podrške za preopširan način rada\n" - -#: ../src/delete.c:63 ../src/delete.c:90 ../src/metacity-dialog.c:70 -#: ../src/theme-parser.c:467 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "Nije moguće analizirati \"%s\" kao cijeli broj" - -#: ../src/delete.c:70 ../src/delete.c:97 ../src/metacity-dialog.c:77 -#: ../src/theme-parser.c:476 ../src/theme-parser.c:530 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "Ne razumijem karaktere \"%s\" u stringu \"%s\"" - -#: ../src/delete.c:128 -#, c-format -msgid "Failed to parse message \"%s\" from dialog process\n" -msgstr "Nije uspjelo analiziranje poruke \"%s\" iz dijaloškog procesa\n" - -#: ../src/delete.c:263 -#, c-format -msgid "Error reading from dialog display process: %s\n" -msgstr "Greška pri čitanju iz dijaloga procesa: %s\n" - -#: ../src/delete.c:344 -#, c-format -msgid "" -"Error launching metacity-dialog to ask about killing an application: %s\n" -msgstr "" -"Greška pri pokretanju metacity dijaloga za potvrdu o ubijanju aplikacije: %" -"s\n" - -#: ../src/delete.c:452 -#, c-format -msgid "Failed to get hostname: %s\n" -msgstr "Neuspjeh pri primanju imena računara %s\n" - -#: ../src/display.c:319 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Neuspjeh pri otvaranju X Window Sistem prikaza %s'\n" - -#: ../src/errors.c:231 -#, c-format -msgid "" -"Lost connection to the display '%s';\n" -"most likely the X server was shut down or you killed/destroyed\n" -"the window manager.\n" -msgstr "" -"Izgubljena konekcija prema prikazu '%s';\n" -"najvjerovatnije je X server ugašen ili ubijen/uništen\n" -"upravitelj przorima.\n" - -#: ../src/errors.c:238 -#, c-format -msgid "Fatal IO error %d (%s) on display '%s'.\n" -msgstr "Fatalna IO greška %d (%s) na prikazu %s'.\n" - -#: ../src/frames.c:1125 -msgid "Close Window" -msgstr "Zatvori prozor" - -#: ../src/frames.c:1128 -msgid "Window Menu" -msgstr "Izbornik prozor" - -#: ../src/frames.c:1131 -msgid "Minimize Window" -msgstr "Minimiziraj prozor" - -#: ../src/frames.c:1134 -msgid "Maximize Window" -msgstr "Maksimiziraj prozor" - -#: ../src/frames.c:1137 -msgid "Unmaximize Window" -msgstr "Poništi povećanje prozora" - -#: ../src/keybindings.c:994 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "" -"Neki drugi program već koristi kljuć %s sa modifikacijama %x kao spoj\n" - -#: ../src/keybindings.c:2620 -#, c-format -msgid "Error launching metacity-dialog to print an error about a command: %s\n" -msgstr "Greška pri pokretanju metacity dijaloga za ispis greške komande: %s\n" - -#: ../src/keybindings.c:2725 -#, c-format -msgid "No command %d has been defined.\n" -msgstr "Nijedna komanda %d nije definisana.\n" - -#: ../src/keybindings.c:3570 -#, fuzzy -msgid "No terminal command has been defined.\n" -msgstr "Nijedna komanda %d nije definisana.\n" - -#: ../src/main.c:69 -#, c-format -msgid "" -"metacity %s\n" -"Copyright (C) 2001-2002 Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" -"metacity %s\n" -"Copyright (C) 2001-2002 Havoc Pennington, Red Hat, Inc., i ostali\n" -"Ovo je slobodan softver, pogledajte uslove kopiranja.\n" - -#: ../src/main.c:257 -msgid "Disable connection to session manager" -msgstr "" - -#: ../src/main.c:263 -msgid "Replace the running window manager with Metacity" -msgstr "" - -#: ../src/main.c:269 -msgid "Specify session management ID" -msgstr "" - -#: ../src/main.c:274 -msgid "X Display to use" -msgstr "" - -#: ../src/main.c:280 -msgid "Initialize session from savefile" -msgstr "" - -#: ../src/main.c:286 -msgid "Print version" -msgstr "" - -#: ../src/main.c:440 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Neuspjeh pri skeniranju direktorija tema: %s\n" - -#: ../src/main.c:456 -#, c-format -msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes." -msgstr "" -"Ne mogu pronaći temu! Budite sigurni %s da postoji i sadrži iskoristive teme." - -#: ../src/main.c:518 -#, c-format -msgid "Failed to restart: %s\n" -msgstr "Neuspjeh pri ponovnom pokretanju: %s\n" - -#: ../src/menu.c:54 -msgid "Mi_nimize" -msgstr "_Minimiziraj" - -#: ../src/menu.c:55 -msgid "Ma_ximize" -msgstr "_Maksimiziraj" - -#: ../src/menu.c:56 -msgid "Unma_ximize" -msgstr "Vrati sa _maksimiziranog" - -#: ../src/menu.c:57 -msgid "Roll _Up" -msgstr "Smotaj _Gore" - -#: ../src/menu.c:58 -msgid "_Unroll" -msgstr "_Odomotaj" - -#: ../src/menu.c:59 ../src/menu.c:60 -msgid "On _Top" -msgstr "Na _vrhu" - -#: ../src/menu.c:61 -msgid "_Move" -msgstr "_Premjesti" - -#: ../src/menu.c:62 -msgid "_Resize" -msgstr "_Promjeni veličinu" - -#. separator -#: ../src/menu.c:64 -msgid "_Close" -msgstr "_Zatvori" - -#. separator -#: ../src/menu.c:66 -#, fuzzy -msgid "_Always on Visible Workspace" -msgstr "Samo na _Ovoj radnoj površini" - -#: ../src/menu.c:67 -#, fuzzy -msgid "_Only on This Workspace" -msgstr "Samo na _Ovoj radnoj površini" - -#: ../src/menu.c:68 -msgid "Move to Workspace _Left" -msgstr "Premjesti na radnu površinu _Lijevo" - -#: ../src/menu.c:69 -msgid "Move to Workspace R_ight" -msgstr "Premjesti na radnu površinu _desno" - -#: ../src/menu.c:70 -msgid "Move to Workspace _Up" -msgstr "Premjesti na _gornju radnu površinu" - -#: ../src/menu.c:71 -msgid "Move to Workspace _Down" -msgstr "Pomjeri na _donju radnu površinu" - -#: ../src/menu.c:162 ../src/prefs.c:2106 -#, c-format -msgid "Workspace %d" -msgstr "Radna površina %d" - -#: ../src/menu.c:171 -msgid "Workspace 1_0" -msgstr "Radna površina 1_0" - -#: ../src/menu.c:173 -#, c-format -msgid "Workspace %s%d" -msgstr "Radna površina %s%d" - -#: ../src/menu.c:368 -msgid "Move to Another _Workspace" -msgstr "Pomjeri na drugu _radnu površinu" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:105 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:111 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:117 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:123 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:129 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:135 -msgid "Hyper" -msgstr "Hiper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:141 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:147 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:153 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:159 -msgid "Mod5" -msgstr "Mod5" - -#: ../src/metacity-dialog.c:110 -#, c-format -msgid "The window \"%s\" is not responding." -msgstr "Prozor \"%s\" ne reaguje." - -#: ../src/metacity-dialog.c:118 -msgid "" -"Forcing this application to quit will cause you to lose any unsaved changes." -msgstr "" -"Prisiljavanje ove aplikacije da završi rad uzrokovati će gubitak svih ne " -"pohranjenih promjena." - -#: ../src/metacity-dialog.c:129 -msgid "_Force Quit" -msgstr "_Prisili izlazak" - -#: ../src/metacity-dialog.c:226 -msgid "Title" -msgstr "Naslov" - -#: ../src/metacity-dialog.c:238 -msgid "Class" -msgstr "Klasa" - -#: ../src/metacity-dialog.c:264 -msgid "" -"These windows do not support \"save current setup\" and will have to be " -"restarted manually next time you log in." -msgstr "" -"Ovi prozori ne podržavaju mogućnost \"snimi trenutne postavke\" i morati " -"ćete ih ručno ponovno pokrenuti sljedeći put kada se prijavite." - -#: ../src/metacity-dialog.c:330 -#, c-format -msgid "" -"There was an error running \"%s\":\n" -"%s." -msgstr "" -"Postoji greška pri pokretanju \"%s\":\n" -"%s." - -#: ../src/metacity.desktop.in.h:1 -msgid "Metacity" -msgstr "Metacity" - -#: ../src/metacity.schemas.in.h:1 -msgid "(Not implemented) Navigation works in terms of applications not windows" -msgstr "(Nije ugrađeno) Navigacija radi u smislu aplikacija, ne prozora" - -#: ../src/metacity.schemas.in.h:2 -msgid "" -"A font description string describing a font for window titlebars. The size " -"from the description will only be used if the titlebar_font_size option is " -"set to 0, however. Also, this option is disabled if the " -"titlebar_uses_desktop_font option is set to true. By default, titlebar_font " -"is unset, causing Metacity to fall back to the desktop font even if " -"titlebar_uses_desktop_font is false." -msgstr "" -"Opis niza podataka pisma koji opisuju pismo za naslovnu traku prozora. Naime " -"veličina iz opisa se samo koristi ako je titlebar_font_size opcija stavljena " -"na 0. Također ova opcija je deaktivirana ako je titlebar_uses_desktop_font " -"opcija postavljena kao true. Uobičajeno titlebar_font nije podešen, zbog " -"čega će Metacity preuzeti pismo za radnu površini čak i ako je " -"titlebar_uses_desktop_font opcija stavljena na false." - -#: ../src/metacity.schemas.in.h:3 -msgid "Action on title bar double-click" -msgstr "Akcija na naslovnom meniju dvostruki-klik" - -#: ../src/metacity.schemas.in.h:4 -msgid "Activate window menu" -msgstr "Aktiviraj prozor izbornika" - -#: ../src/metacity.schemas.in.h:5 -msgid "Arrangement of buttons on the titlebar" -msgstr "Aranžman funkcijskih dugmadi na naslovoj traci" - -#: ../src/metacity.schemas.in.h:6 -msgid "" -"Arrangement of buttons on the titlebar. The value should be a string, such " -"as \"menu:minimize,maximize,close\"; the colon separates the left corner of " -"the window from the right corner, and the button names are comma-separated. " -"Duplicate buttons are not allowed. Unknown button names are silently ignored " -"so that buttons can be added in future metacity versions without breaking " -"older versions." -msgstr "" -"Raspored dugmadi na naslovnoj traci. Vrijednost treba biti niz znakova, kao " -"na primjer „menu:minimize,maximize,close“; dvije tačke razdvajaju lijevi " -"ugao prozora od desnog, a dugmad su razdvojena tačka-zarezima. Dupliranje " -"dugmadi nije dozvoljeno. Nepoznata imena dugmadi se zanemaruju tako da se " -"dugmad koja će se dodavati u buduće verzije metacity-a bez poremećenja " -"starijih verzija." - -#: ../src/metacity.schemas.in.h:7 -msgid "Automatically raises the focused window" -msgstr "Automatski podiže prozor sa fokusom" - -#: ../src/metacity.schemas.in.h:8 -msgid "" -"Clicking a window while holding down this modifier key will move the window " -"(left click), resize the window (middle click), or show the window menu " -"(right click). Modifier is expressed as \"<Alt>\" or \"<Super>\" " -"for example." -msgstr "" -"Pritiskom na prozor za vrijeme držanja ove tipke premejestit će prozor " -"(lijeva tipka miša), podići prozor (srednja tipka miša) ili prikazati glavni " -"izbornik (desna tipka miša). Tipka može biti na primjer \"<Alr>\" ili " -"\"<Super>\"" - -#: ../src/metacity.schemas.in.h:9 -msgid "Close window" -msgstr "Zatvori prozor" - -#: ../src/metacity.schemas.in.h:10 -msgid "Commands to run in response to keybindings" -msgstr "Naredbe koje će se pokrenuti na odaziv kombinacije tipki sa tastature" - -#: ../src/metacity.schemas.in.h:11 -msgid "Current theme" -msgstr "Trenutna tema" - -#: ../src/metacity.schemas.in.h:12 -msgid "Delay in milliseconds for the auto raise option" -msgstr "Odgoda u milisekundama za opciju automatskog podizanja" - -#: ../src/metacity.schemas.in.h:13 -msgid "" -"Determines whether applications or the system can generate audible 'beeps'; " -"may be used in conjunction with 'visual bell' to allow silent 'beeps'." -msgstr "" -"Određuje hoće li aplikacije ili sistem generisati zvučne 'beepove'može se " -"koristiti u spoju sa 'vizuelnim zvonom' da se dozvoli tihi 'beep'" - -#: ../src/metacity.schemas.in.h:14 -msgid "Disable misfeatures that are required by old or broken applications" -msgstr "Isključi mogućnosti potrebne za stare ili neispravne aplikacijie" - -#: ../src/metacity.schemas.in.h:15 -msgid "Enable Visual Bell" -msgstr "Aktiviraj vidni signal" - -#: ../src/metacity.schemas.in.h:16 -msgid "Hide all windows and focus desktop" -msgstr "Sakrij sve prozore i pokaži radnu površinu" - -#: ../src/metacity.schemas.in.h:17 -msgid "" -"If true, and the focus mode is either \"sloppy\" or \"mouse\" then the " -"focused window will be automatically raised after a delay (the delay is " -"specified by the auto_raise_delay key)." -msgstr "" -"Ako je aktivirano, i način fokusiranja stavljen kao \"traljav\" ili \"miš" -"\" onda će fokusirani prozor biti automatski podignut nakod odgode (odgoda " -"je određena auto_raise_delay unosom) " - -#: ../src/metacity.schemas.in.h:18 -msgid "" -"If true, ignore the titlebar_font option, and use the standard application " -"font for window titles." -msgstr "" -"Ako je aktivirano, ignorira se titlebar_font opcija i koristi se standardno " -"aplikacijsko pismo za naslovnu traku prozora." - -#: ../src/metacity.schemas.in.h:19 -#, fuzzy -msgid "" -"If true, metacity will give the user less feedback and less sense of " -"\"direct manipulation\", by using wireframes, avoiding animations, or other " -"means. This is a significant reduction in usability for many users, but may " -"allow legacy applications and terminal servers to function when they would " -"otherwise be impractical. However, the wireframe feature is disabled when " -"accessibility is on to avoid weird desktop breakages." -msgstr "" -"Ukoliko je postavljeno, metacity će korisniku dati manje povratnih " -"informacija i manje osjećaja \"direktne manipulacije\", korištenjem žičanih " -"okvira, izbjegavanjem animacija i drugo. Ovo je značajno smanjenje " -"funkcionalnosti za mnoge korisnike, ali omogućava nasljeđivanje programa i " -"rad server terminala kada bi oni u suprotnom bili nepraktični." - -#: ../src/metacity.schemas.in.h:20 -msgid "" -"If true, then Metacity works in terms of applications rather than windows. " -"The concept is a bit abstract, but in general an application-based setup is " -"more like the Mac and less like Windows. When you focus a window in " -"application-based mode, all the windows in the application will be raised. " -"Also, in application-based mode, focus clicks are not passed through to " -"windows in other applications. The existence of this setting is somewhat " -"questionable. But it's better than having settings for all the specific " -"details of application-based vs. window-based, e.g. whether to pass through " -"clicks. Also, application-based mode is largely unimplemented at the moment." -msgstr "" -"Ako je aktivirano, onda Metacity radi u okvirima aplikacija umjesto prozora. " -"Koncept je malo apstraktan, ali u širem pogledu podešavanje na razini " -"aplikacije je više poput Mac a manje nego Windows okruženja. Kad fokusirate " -"prozor u načinu rada baziranom na aplikaciji, klikovi fokusiranja nisu " -"preusmjereni na prozore u drugim aplikacijama. Postojanje ove opcije je malo " -"upitno. Ali bolje je nego imati svojstva za sve specifične detalje u " -"aplikacijski orijentiranom protiv prozorski orijentiranom, naprimjer da li " -"preusmjeriti preko klikova. Također aplikacijski orjentiran način rada je " -"jako neupotrebljen trenutno." - -#: ../src/metacity.schemas.in.h:21 -msgid "If true, trade off usability for less resource usage" -msgstr "" -"Ako je postavljno, mijenja se iskorištenost za manje korištenje resursa" - -#: ../src/metacity.schemas.in.h:22 -msgid "Lower window below other windows" -msgstr "Spustiti prozor ispod ostalih prozora" - -#: ../src/metacity.schemas.in.h:23 -msgid "Maximize window" -msgstr "Maksimiziraj prozor" - -#: ../src/metacity.schemas.in.h:24 -msgid "Maximize window horizontally" -msgstr "Maksimiziraj prozor horizontalno" - -#: ../src/metacity.schemas.in.h:25 -msgid "Maximize window vertically" -msgstr "Maksimiziraj prozor vertikalno" - -#: ../src/metacity.schemas.in.h:26 -msgid "Minimize window" -msgstr "Minimiziraj prozor" - -#: ../src/metacity.schemas.in.h:27 -msgid "Modifier to use for modified window click actions" -msgstr "Ispravljać za korištenje prepravljenih akcija klika u prozoru" - -#: ../src/metacity.schemas.in.h:28 -msgid "Move backward between panels and the desktop immediately" -msgstr "Pomjeranje unazad između panela i radnih površina bez odlaganja" - -#: ../src/metacity.schemas.in.h:29 -msgid "Move backwards between panels and the desktop with popup" -msgstr "Pomjeranje unazad između panela i radne površine sa popup-om" - -#: ../src/metacity.schemas.in.h:30 -msgid "Move backwards between windows immediately" -msgstr "Pomjeranje unazad između prozora bez odlaganja" - -#: ../src/metacity.schemas.in.h:31 -msgid "Move between panels and the desktop immediately" -msgstr "Pomjeranje između prozora i radne površine bez odlaganja" - -#: ../src/metacity.schemas.in.h:32 -msgid "Move between panels and the desktop with popup" -msgstr "Pomjeranje između panela i radne površine sa popup-om." - -#: ../src/metacity.schemas.in.h:33 -msgid "Move between windows immediately" -msgstr "Pomjeranje između prozora bez odlaganja" - -#: ../src/metacity.schemas.in.h:34 -msgid "Move between windows with popup" -msgstr "Pomjeranje između prozora sa popupom" - -#: ../src/metacity.schemas.in.h:35 -msgid "Move focus backwards between windows using popup display" -msgstr "Pomjeranje fokusiranja unatrag između prozora koristeći popup prikaz" - -#: ../src/metacity.schemas.in.h:36 -msgid "Move window" -msgstr "Pomjeri prozor" - -#: ../src/metacity.schemas.in.h:37 -msgid "Move window one workspace down" -msgstr "Premjesti prozor za jednu radnu površinu ispod" - -#: ../src/metacity.schemas.in.h:38 -msgid "Move window one workspace to the left" -msgstr "Pomjeri prozor jedan radnu površinu ulijevo" - -#: ../src/metacity.schemas.in.h:39 -msgid "Move window one workspace to the right" -msgstr "Pomjeri prozor jedanu radnu površinu udesno" - -#: ../src/metacity.schemas.in.h:40 -msgid "Move window one workspace up" -msgstr "Pomjeri prozor jednu radnu površinu gore" - -#: ../src/metacity.schemas.in.h:41 -msgid "Move window to workspace 1" -msgstr "Premjesti prozor na radnu površinu 1" - -#: ../src/metacity.schemas.in.h:42 -msgid "Move window to workspace 10" -msgstr "Premjesti prozor na radnu površinu 10" - -#: ../src/metacity.schemas.in.h:43 -msgid "Move window to workspace 11" -msgstr "Premjesti prozor na radnu površinu 11" - -#: ../src/metacity.schemas.in.h:44 -msgid "Move window to workspace 12" -msgstr "Premjesti prozor na radnu površinu 12" - -#: ../src/metacity.schemas.in.h:45 -msgid "Move window to workspace 2" -msgstr "Premjesti prozor na radnu površinu 2" - -#: ../src/metacity.schemas.in.h:46 -msgid "Move window to workspace 3" -msgstr "Premjesti prozor na radnu površinu 3" - -#: ../src/metacity.schemas.in.h:47 -msgid "Move window to workspace 4" -msgstr "Premjesti prozor na radnu površinu 4" - -#: ../src/metacity.schemas.in.h:48 -msgid "Move window to workspace 5" -msgstr "Premjesti prozor na radnu površinu 5" - -#: ../src/metacity.schemas.in.h:49 -msgid "Move window to workspace 6" -msgstr "Premjesti prozor na radnu površinu 6" - -#: ../src/metacity.schemas.in.h:50 -msgid "Move window to workspace 7" -msgstr "Premjesti prozor na radnu površinu 7" - -#: ../src/metacity.schemas.in.h:51 -msgid "Move window to workspace 8" -msgstr "Premjesti prozor na radnu površinu 8" - -#: ../src/metacity.schemas.in.h:52 -msgid "Move window to workspace 9" -msgstr "Premjesti prozor na radnu površinu 9" - -#: ../src/metacity.schemas.in.h:53 -msgid "Name of workspace" -msgstr "Ime radne površine" - -#: ../src/metacity.schemas.in.h:54 -msgid "Number of workspaces" -msgstr "Broj radnih površina" - -#: ../src/metacity.schemas.in.h:55 -msgid "" -"Number of workspaces. Must be more than zero, and has a fixed maximum (to " -"prevent accidentally destroying your desktop by asking for 34 million " -"workspaces)." -msgstr "" -"Broj radnih površina. Mora biti više od nule i ima fiksni maksimum (da " -"spriječi slučajno uništavanje vaše radne površine ako zatražite 34 milijuna " -"radnih prostora)" - -#: ../src/metacity.schemas.in.h:56 -msgid "Raise obscured window, otherwise lower" -msgstr "Podigni nejasan prozor, inače spusti" - -#: ../src/metacity.schemas.in.h:57 -msgid "Raise window above other windows" -msgstr "Podigni prozor iznad ostalih prozora" - -#: ../src/metacity.schemas.in.h:58 -msgid "Resize window" -msgstr "Promjeni veličinu prozora" - -#: ../src/metacity.schemas.in.h:59 -msgid "Run a defined command" -msgstr "Pokreni definiranu naredbu" - -#: ../src/metacity.schemas.in.h:60 -msgid "Run a terminal" -msgstr "" - -#: ../src/metacity.schemas.in.h:61 -msgid "Show the panel menu" -msgstr "Pokažite izbornik panela" - -#: ../src/metacity.schemas.in.h:62 -msgid "Show the panel run application dialog" -msgstr "Pokažite dijalog pokretanja u panelu" - -#: ../src/metacity.schemas.in.h:63 -msgid "" -"Some applications break specifications in ways that result in window manager " -"misfeatures. For example, ideally Metacity would place all dialogs in a " -"consistent position with respect to their parent window. This requires " -"ignoring application-specified positions for dialogs. But some versions of " -"Java/Swing mark their popup menus as dialogs, so Metacity has to disable " -"dialog positioning to allow menus to work in broken Java applications. There " -"are several other examples like this. This option puts Metacity in full-on " -"Correct mode, which perhaps gives a moderately nicer UI if you don't need to " -"run any broken apps. Sadly, workarounds must be enabled by default; the real " -"world is an ugly place. Some of the workarounds are workarounds for " -"limitations in the specifications themselves, so sometimes a bug in no-" -"workarounds mode won't be fixable without amending a spec." -msgstr "" -"Neke aplikacije krše specifikacije na način koji dovodi do nepoželjnih " -"osobina upravljaća prozora.Na primjer, idealno Metacity stavlja sve dijaloge " -"u određeni položaj relativan na njihov roditeljski prozor. Ovo zahtjeva " -"ignoriranje specifičnih osobina aplikacijskih prozora za dijaloge. Ali neke " -"verzije Jave/Swinga označe svoj popup izbornik kao dijalog, pa Metacity mora " -"onemogućiti smještanje dijaloga da bi dozvolio izbornicima da rade u " -"neispravnim Java aplikacijama. Postoji još primjera za poput ovog. Ova " -"opcija stavlja Metacity u puni-on Correct način rada koji možda daje " -"umjereno jači UI ako nije potrebno koristiti neispravne aplikacije. " -"Nažalost, zaobilaženja moraju biti aktivirana uobičajeno, svijet je ružno " -"mjesto. Neke od zaobilaznica su zaobilaznice za ograničenja u samim " -"specifikacijama, pa neki put bubu u no-workarounds načinu rada neće biti " -"moguće popraviti bez detaljnijeg uvida u problem." - -#: ../src/metacity.schemas.in.h:64 -msgid "Switch to workspace 1" -msgstr "Prebaci se na radnu površinu 1" - -#: ../src/metacity.schemas.in.h:65 -msgid "Switch to workspace 10" -msgstr "Prebaci se na radnu površinu 10" - -#: ../src/metacity.schemas.in.h:66 -msgid "Switch to workspace 11" -msgstr "Prebaci se na radnu površinu 11" - -#: ../src/metacity.schemas.in.h:67 -msgid "Switch to workspace 12" -msgstr "Prebaci se na radnu površinu 12" - -#: ../src/metacity.schemas.in.h:68 -msgid "Switch to workspace 2" -msgstr "Prebaci se na radnu površinu 2" - -#: ../src/metacity.schemas.in.h:69 -msgid "Switch to workspace 3" -msgstr "Prebaci se na radnu površinu 3" - -#: ../src/metacity.schemas.in.h:70 -msgid "Switch to workspace 4" -msgstr "Prebaci se na radnu površinu 4" - -#: ../src/metacity.schemas.in.h:71 -msgid "Switch to workspace 5" -msgstr "Prebaci se na radnu površinu 5" - -#: ../src/metacity.schemas.in.h:72 -msgid "Switch to workspace 6" -msgstr "Prebaci se na radnu površinu 6" - -#: ../src/metacity.schemas.in.h:73 -msgid "Switch to workspace 7" -msgstr "Prebaci se na radnu površinu 7" - -#: ../src/metacity.schemas.in.h:74 -msgid "Switch to workspace 8" -msgstr "Prebaci se na radnu površinu 8" - -#: ../src/metacity.schemas.in.h:75 -msgid "Switch to workspace 9" -msgstr "Prebaci se na radnu površinu 9" - -#: ../src/metacity.schemas.in.h:76 -msgid "Switch to workspace above this one" -msgstr "Prebaci se na radnu površinu iznad ovog" - -#: ../src/metacity.schemas.in.h:77 -msgid "Switch to workspace below this one" -msgstr "Prebaci se na radnu površinu ispod ovog" - -#: ../src/metacity.schemas.in.h:78 -msgid "Switch to workspace on the left" -msgstr "Prebaci se na radnu površinu ulijevo" - -#: ../src/metacity.schemas.in.h:79 -msgid "Switch to workspace on the right" -msgstr "Prebaci se na radnu površinu udesno" - -#: ../src/metacity.schemas.in.h:80 -msgid "System Bell is Audible" -msgstr "Sistemsko zvono se čuje" - -#: ../src/metacity.schemas.in.h:81 -msgid "Take a screenshot" -msgstr "Uzmi sliku zaslona" - -#: ../src/metacity.schemas.in.h:82 -msgid "Take a screenshot of a window" -msgstr "Uzmi sliku prozora" - -#: ../src/metacity.schemas.in.h:83 -msgid "" -"Tells Metacity how to implement the visual indication that the system bell " -"or another application 'bell' indicator has been rung. Currently there are " -"two valid values, \"fullscreen\", which causes a fullscreen white-black " -"flash, and \"frame_flash\" which causes the titlebar of the application " -"which sent the bell signal to flash. If the application which sent the bell " -"is unknown (as is usually the case for the default \"system beep\"), the " -"currently focused window's titlebar is flashed." -msgstr "" -"Govori Metacity-u da prikaže nešto kada zazvoni sistemsko zvono ili neki " -"drugi program zazvoni. Trenutno su moguće dvije vrijednosti, „fullscreen“ " -"kojim cijeli zaslon treperi crno-bijelo, i „frame_flash“ kada treperi samo " -"naslovna linija prozora koji je zazvonio. Ukoliko nije poznat program koji " -"je zazvonio (kao što je to obično slučaj sa „sistemskim zvonom“), trepereće " -"naslovna linija prozora koji je trenutno u fokusu." - -#: ../src/metacity.schemas.in.h:84 -msgid "" -"The /apps/metacity/global_keybindings/run_command_N keys define keybindings " -"that correspond to these commands. Pressing the keybinding for run_command_N " -"will execute command_N." -msgstr "" -"Ključ /apps/metacity/global_keybindings/run_command_N definiše dugmad koja " -"odgovaraju ovim komandama. Pritiskom kombinacije dugmadi za " -"pokretanje_komandu_N će izvršiti komandu_N." - -#: ../src/metacity.schemas.in.h:85 -msgid "" -"The /apps/metacity/global_keybindings/run_command_screenshot key defines a " -"keybinding which causes the command specified by this setting to be invoked." -msgstr "" -"Ključ /apps/metacity/global_keybindings/run_command_N definiše funkciju " -"dugmadi kojim se pokreće naredba navedena pomoću njega." - -#: ../src/metacity.schemas.in.h:86 -msgid "" -"The /apps/metacity/global_keybindings/run_command_window_screenshot key " -"defines a keybinding which causes the command specified by this setting to " -"be invoked." -msgstr "" -"Ključ /apps/metacity/global_keybindings/run_command_window_screenshot " -"definiše funkciju dugmadi kojim se pokreće naredba navedena pomoću njega." - -#: ../src/metacity.schemas.in.h:87 -msgid "" -"The keybinding that runs the correspondingly-numbered command in /apps/" -"metacity/keybinding_commands The format looks like \"<Control>a\" or " -"\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -"lower or upper case, and also abbreviations such as \"<Ctl>\" and " -"\"<Ctrl>\". If you set the option to the special string \"disabled\", " -"then there will be no keybinding for this action." -msgstr "" -"Kombinacije dugmadi koja pokreću odgovarajuće označenu naredbu u /apps/" -"metacity/keybinding_commands ključu. Oblik zapisa izgleda kao \"<" -"Control>a\" ili \"<Shift><Alt>F1\". Program za obradu je " -"dosta slobodan i dozvoljava velika ili mala slova, također i skraćenice " -"poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na " -"specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:88 -msgid "" -"The keybinding that switches to the workspace above the current workspace. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"Kombinacija dugmadi koja prebacuje na radnu površinu iznad trenutne radne " -"površine. Oblik zapisa izgleda kao \"<Control>a\" ili \"<Shift>" -"<Alt>F1\". Program za obradu je dosta slobodan i dozvoljava velika ili " -"mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". " -"Ako postavite opciju na specijalni niz znakova \"disabled\", tada neće biti " -"korištena niti jedna kombinacija dugmadi za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:89 -msgid "" -"The keybinding that switches to the workspace below the current workspace. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"Kombinacija dugmadi koja prebacuje na radnu površinu ispod trenutne radne " -"površine. Oblik zapisa izgleda kao \"<Control>a\" ili \"<Shift>" -"<Alt>F1\". Program za obradu je dosta slobodan i dozvoljava velika ili " -"mala slova, također i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". " -"Ako pstavite opciju na specijalni niz znakova \"disabled\", tada neće biti " -"korištena niti jedna kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:90 -msgid "" -"The keybinding that switches to the workspace on the left of the current " -"workspace. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja prebacuje na radnu površinu lijevo od trenutnog " -"radne površine. Oblik zapisa izgleda kao \"<Control>a\" ili \"<" -"Shift><Alt>F1\". Program za obradu je dosta slobodan i dozvoljava " -"velika ili mala slova, također i skraćenice poput \"<Ctl>\" i \"< " -"Ctrl>\". Ako postavite opciju na specijalni niz znakova \"disabled\", " -"tada neće biti korištena niti jedna kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:91 -msgid "" -"The keybinding that switches to the workspace on the right of the current " -"workspace. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" -"Kombinacija digmadi koja prebacuje na radnu površinu desno od trenutne radne " -"površine. Oblik zapisa izgleda kao \"<Control>a\" ili \"<Shift>" -"<Alt>F1\". Program za obradu je dosta slobodan i dozvoljava velika ili " -"mala slova, također i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". " -"Ako postavite opciju na specijalni niz znakova \"disabled\", tada neće biti " -"korištena niti jedna kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:92 -msgid "" -"The keybinding that switches to workspace 1. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja prebacuje na radnu površinu 1. Oblik zapisa izgleda " -"kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program za " -"obradu je dosta slobodan i dozvoljava velika ili mala slova, također i " -"skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju " -"na specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:93 -msgid "" -"The keybinding that switches to workspace 10. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja prebacuje na radnu površinu 10. Oblik zapisa " -"izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program " -"za obradu je dosta slobodan i dozvoljava velika ili mala slova, također i " -"skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju " -"na specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:94 -msgid "" -"The keybinding that switches to workspace 11. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja prebacuje na radnu površinu 11. Oblik zapisa " -"izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program " -"za obradu je dosta slobodan i dozvoljava velika ili mala slova, također i " -"skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju " -"na specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:95 -msgid "" -"The keybinding that switches to workspace 12. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja prebacuje na radnu površinu 12. Oblik zapisa " -"izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program " -"za obradu je dosta slobodan i dozvoljava velika ili mala slova, također i " -"skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju " -"na specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:96 -msgid "" -"The keybinding that switches to workspace 2. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja prebacuje na radnu površinu 2. Oblik zapisa izgleda " -"kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program za " -"obradu je dosta slobodan i dozvoljava velika ili mala slova, također i " -"skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju " -"na specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:97 -msgid "" -"The keybinding that switches to workspace 3. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja prebacuje na radnu površinu 3. Oblik zapisa izgleda " -"kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program za " -"obradu je dosta slobodan i dozvoljava velika ili mala slova, također i " -"skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju " -"na specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:98 -msgid "" -"The keybinding that switches to workspace 4. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja prebacuje na radnu površinu 4. Oblik zapisa izgleda " -"kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program za " -"obradu je dosta slobodan i dozvoljava velika ili mala slova, također i " -"skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju " -"na specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:99 -msgid "" -"The keybinding that switches to workspace 5. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja prebacuje na radnu površinu 5. Oblik zapisa izgleda " -"kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program za " -"obradu je dosta slobodan i dozvoljava velika ili mala slova, također i " -"skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju " -"na specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:100 -msgid "" -"The keybinding that switches to workspace 6. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja prebacuje na radnu površinu 6. Oblik zapisa izgleda " -"kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program za " -"obradu je dosta slobodan i dozvoljava velika ili mala slova, također i " -"skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju " -"na specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:101 -msgid "" -"The keybinding that switches to workspace 7. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja prebacuje na radnu površinu 7. Oblik zapisa izgleda " -"kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program za " -"obradu je dosta slobodan i dozvoljava velika ili mala slova, također i " -"skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju " -"na specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:102 -msgid "" -"The keybinding that switches to workspace 8. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja prebacuje na radnu površinu 8. Oblik zapisa izgleda " -"kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program za " -"obradu je dosta slobodan i dozvoljava velika ili mala slova, također i " -"skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju " -"na specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:103 -msgid "" -"The keybinding that switches to workspace 9. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja prebacuje na radnu površinu 9. Oblik zapisa izgleda " -"kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program za " -"obradu je dosta slobodan i dozvoljava velika ili mala slova, također i " -"skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju " -"na specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:104 -msgid "" -"The keybinding used to activate the window menu. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja pokreće izbornik prozora. Oblik zapisa izgleda kao " -"\"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu " -"je dosta slobodan i dozvoljava velika ili mala slova, takođe i skraćenice " -"poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na " -"specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:105 -msgid "" -"The keybinding used to close a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja zatvara prozor. Oblik zapisa izgleda kao \"<" -"Control>a\" ili \"<Shift><Alt>F1\". Program za obradu je " -"dosta slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " -"\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz " -"znakova \"disabled\", tada neće biti korištena niti jedna kombinacija tipki " -"za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:106 -msgid "" -"The keybinding used to enter \"move mode\" and begin moving a window using " -"the keyboard. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" -"Kombinacijadugmadi koja postavlja prozor u način rada za pomicanje i " -"omogućava pomicanje prozora pomoću tastature. Oblik zapisa izgleda kao \"<" -"Control>a\" ili \"<Shift><Alt>F1\". Program za obradu je " -"dosta slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " -"\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz " -"znakova \"disabled\", tada neće biti korištena niti jedna kombinacija tipki " -"za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:107 -msgid "" -"The keybinding used to enter \"resize mode\" and begin resizing a window " -"using the keyboard. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja postavlja prozor u način rada za razvlačenje i " -"omogućava razvlačenje prozora pomoću tastature. Oblik zapisa izgleda kao " -"\"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu " -"je dosta slobodan i dozvoljava velika ili mala slova, takođe i skraćenice " -"poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na " -"specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:108 -msgid "" -"The keybinding used to hide all normal windows and set the focus to the " -"desktop background. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja skriva sve obične prozore i postavlja fokus na " -"pozadinu radne površine. Oblik zapisa izgleda kao \"<Control>a\" ili " -"\"<Shift><Alt>F1\". Program za obradu je dosta slobodan i " -"dozvoljava velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" " -"i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " -"\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za ovu " -"aktivnost." - -#: ../src/metacity.schemas.in.h:109 -#, fuzzy -msgid "" -"The keybinding used to maximize a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja povećava prozor. Oblik zapisa izgleda kao \"<" -"Control>a\" ili \"<Shift><Alt>F1\". Program za obradu je " -"dosta slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " -"\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz " -"znakova \"disabled\", tada neće biti korištena niti jedna kombinacija tipki " -"za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:110 -msgid "" -"The keybinding used to minimize a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja smanjuje prozor. Oblik zapisa izgleda kao \"<" -"Control>a\" ili \"<Shift><Alt>F1\". Program za obradu je " -"dosta slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " -"\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz " -"znakova \"disabled\", tada neće biti korištena niti jedna kombinacija tipki " -"za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:111 -msgid "" -"The keybinding used to move a window one workspace down. The format looks " -"like \"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -"fairly liberal and allows lower or upper case, and also abbreviations such " -"as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -"special string \"disabled\", then there will be no keybinding for this " -"action." -msgstr "" -"Kombinacija dugmadi koja premiješta prozor za jednu radnu površinu niže. " -"Oblik zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>" -"F1\". Program za obradu je dosta slobodan i dozvoljava velika ili mala " -"slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako " -"postavite opciju na specijalni niz znakova \"disabled\", tada neće biti " -"korištena niti jedna kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:112 -msgid "" -"The keybinding used to move a window one workspace to the left. The format " -"looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -"parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"Kombinacija digmadi koja premiješta prozor za jednu radnu površinu lijevo. " -"Oblik zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>" -"F1\". Program za obradu je dosta slobodan i dozvoljava velika ili mala " -"slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako " -"postavite opciju na specijalni niz znakova \"disabled\", tada neće biti " -"korištena niti jedna kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:113 -msgid "" -"The keybinding used to move a window one workspace to the right. The format " -"looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -"parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"Kombinacija dugmadi koja premiješta prozor za jednu radnu površinu desno. " -"Oblik zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>" -"F1\". Program za obradu je dosta slobodan i dozvoljava velika ili mala " -"slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako " -"postavite opciju na specijalni niz znakova \"disabled\", tada neće biti " -"korištena niti jedna kombinacija dugmadi za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:114 -msgid "" -"The keybinding used to move a window one workspace up. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja premiješta prozor za jednu radnu površinu više. " -"Oblik zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>" -"F1\". Program za obradu je dosta slobodan i dozvoljava velika ili mala " -"slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako " -"postavite opciju na specijalni niz znakova \"disabled\", tada neće biti " -"korištena niti jedna kombinacija dugmadi za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:115 -msgid "" -"The keybinding used to move a window to workspace 1. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja premiješta prozor na radnu površinu 1. Oblik zapisa " -"izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program " -"za obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " -"skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju " -"na specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija dugmadi za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:116 -msgid "" -"The keybinding used to move a window to workspace 10. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja premiješta prozor na radnu površinu 10. Oblik " -"zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". " -"Program za obradu je dosta slobodan i dozvoljava velika ili mala slova, " -"takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite " -"opciju na specijalni niz znakova \"disabled\", tada neće biti korištena niti " -"jedna kombinacija dugmadi za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:117 -msgid "" -"The keybinding used to move a window to workspace 11. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja premiješta prozor na radnu površinu 11. Oblik " -"zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". " -"Program za obradu je dosta slobodan i dozvoljava velika ili mala slova, " -"takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite " -"opciju na specijalni niz znakova \"disabled\", tada neće biti korištena niti " -"jedna kombinacija dugmadi za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:118 -msgid "" -"The keybinding used to move a window to workspace 12. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja premiješta prozor na radnu površinu 12. Oblik " -"zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". " -"Program za obradu je dosta slobodan i dozvoljava velika ili mala slova, " -"takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite " -"opciju na specijalni niz znakova \"disabled\", tada neće biti korištena niti " -"jedna kombinacija dugmadi za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:119 -msgid "" -"The keybinding used to move a window to workspace 2. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja premiješta prozor na radnu površinu 2. Oblik zapisa " -"izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program " -"za obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " -"skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju " -"na specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija dugmadi za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:120 -msgid "" -"The keybinding used to move a window to workspace 3. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja premiješta prozor na radnu površinu 3. Oblik zapisa " -"izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program " -"za obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " -"skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju " -"na specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija dugmadi za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:121 -msgid "" -"The keybinding used to move a window to workspace 4. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja premiješta prozor na radnu površinu 4. Oblik zapisa " -"izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program " -"za obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " -"skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju " -"na specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija dugmadi za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:122 -msgid "" -"The keybinding used to move a window to workspace 5. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja premiješta prozor na radnu površinu 5. Oblik zapisa " -"izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program " -"za obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " -"skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju " -"na specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija dugmadi za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:123 -msgid "" -"The keybinding used to move a window to workspace 6. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja premiješta prozor na radnu površinu 6. Oblik zapisa " -"izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program " -"za obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " -"skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju " -"na specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija dugmadi za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:124 -msgid "" -"The keybinding used to move a window to workspace 7. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja premiješta prozor na radnu površinu 7. Oblik zapisa " -"izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program " -"za obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " -"skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju " -"na specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija dugmadi za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:125 -msgid "" -"The keybinding used to move a window to workspace 8. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja premiješta prozor na radnu površinu 8. Oblik zapisa " -"izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program " -"za obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " -"skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju " -"na specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija dugmadi za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:126 -msgid "" -"The keybinding used to move a window to workspace 9. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja premiješta prozor na radnu površinu 9. Oblik zapisa " -"izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program " -"za obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " -"skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju " -"na specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija dugmadi za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:127 -msgid "" -"The keybinding used to move focus backwards between panels and the desktop, " -"using a popup window. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja premiješta fokus unazad između panela i radne " -"površine koristeći skočni prozor. Oblik zapisa izgleda kao \"<Control>a" -"\" ili \"<Shift><Alt>F1\". Program za obradu je dosta slobodan i " -"dozvoljava velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" " -"i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " -"\"disabled\", tada neće biti korištena niti jedna kombinacija dugmadi za ovu " -"aktivnost." - -#: ../src/metacity.schemas.in.h:128 -msgid "" -"The keybinding used to move focus backwards between panels and the desktop, " -"without a popup window. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja premiješta fokus unazad između panela i radne " -"površine bez skočnog prozora. Oblik zapisa izgleda kao \"<Control>a\" " -"ili \"<Shift><Alt>F1\". Program za obradu je dosta slobodan i " -"dozvoljava velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" " -"i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " -"\"disabled\", tada neće biti korištena niti jedna kombinacija dugmadi za ovu " -"aktivnost." - -#: ../src/metacity.schemas.in.h:129 -msgid "" -"The keybinding used to move focus backwards between windows without a popup " -"window. Holding \"shift\" together with this binding makes the direction go " -"forward again. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja premiješta fokus unazad između prozora bez skočnog " -"prozora. Držeći dugme \"shift\" zajedno s kombinacijom dugmadi omogućuje se " -"suprotni smijer premiještanja. Oblik zapisa izgleda kao \"<Control>a\" " -"ili \"<Shift><Alt>F1\". Program za obradu je dosta slobodan i " -"dozvoljava velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" " -"i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " -"\"disabled\", tada neće biti korištena niti jedna kombinacija dugmadi za ovu " -"aktivnost." - -#: ../src/metacity.schemas.in.h:130 -msgid "" -"The keybinding used to move focus backwards between windows, using a popup " -"window. Holding \"shift\" together with this binding makes the direction go " -"forward again. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja premiješta fokus unazad između prozora koristeći " -"skočni prozor. Držeći dugme \"shift\" zajedno s kombinacijom tipki omogućuje " -"se suprotni smijer premiještanja. Oblik zapisa izgleda kao \"<Control>a" -"\" ili \"<Shift><Alt>F1\". Program za obradu je dosta slobodan i " -"dozvoljava velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" " -"i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " -"\"disabled\", tada neće biti korištena niti jedna kombinacija dugmadi za ovu " -"aktivnost." - -#: ../src/metacity.schemas.in.h:131 -msgid "" -"The keybinding used to move focus between panels and the desktop, using a " -"popup window. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja premiješta fokus između ploče i radne površine " -"koristeći skočni prozor. Oblik zapisa izgleda kao \"<Control>a\" ili " -"\"<Shift><Alt>F1\". Program za obradu je dosta slobodan i " -"dozvoljava velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" " -"i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " -"\"disabled\", tada neće biti korištena niti jedna kombinacija dugmadi za ovu " -"aktivnost." - -#: ../src/metacity.schemas.in.h:132 -msgid "" -"The keybinding used to move focus between panels and the desktop, without a " -"popup window. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja premiještaju fokus između ploče i radne površine " -"bez skočnog prozora. Oblik zapisa izgleda kao \"<Control>a\" ili \"<" -"Shift><Alt>F1\". Program za obradu je dosta slobodan i dozvoljava " -"velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< " -"Ctrl>\". Ako postavite opciju na specijalni niz znakova \"disabled\", " -"tada neće biti korištena niti jedna kombinacija dugmadi za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:133 -msgid "" -"The keybinding used to move focus between windows without a popup window. " -"(Traditionally <Alt>Escape) Holding the \"shift\" key while using this " -"binding reverses the direction of movement. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja premiješta fokus između prozora bez skočnog prozora." -"(Uobičajeno <Alt>Escape) Držeći dugme \"shift\" zajedno s kombinacijom " -"tipki omogućuje se suprotni smijer premiještanja. Oblik zapisa izgleda kao " -"\"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu " -"je dosta slobodan i dozvoljava velika ili mala slova, također i skraćenice " -"poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na " -"specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija dugmadi za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:134 -msgid "" -"The keybinding used to move focus between windows, using a popup window. " -"(Traditionally <Alt>Tab) Holding the \"shift\" key while using this " -"binding reverses the direction of movement. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja premiješta fokus između prozora koristeći skočni " -"prozor. (Uobičajeno <Alt>Tab) Držeći dugme \"shift\" zajedno s " -"kombinacijom tipki omogućuje se suprotni smijer premiještanja. Oblik zapisa " -"izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program " -"za obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " -"skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju " -"na specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija dugmadi za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:135 -msgid "" -"The keybinding used to toggle always on top. A window that is always on top " -"will always be visible over other overlapping windows. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja uključuje ili isključuje opciju da prozor bude " -"uvijek na vrhu. Prozor koji je uvijek na vrhu videti će se preko drugih " -"preklapajućih prozora. Oblik zapisa izgleda kao \"<Control>a\" ili " -"\"<Shift><Alt>F1\". Program za obradu je dosta slobodan i " -"dozvoljava velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" " -"i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " -"\"disabled\", tada neće biti korištena niti jedna kombinacija dugmadi za ovu " -"aktivnost." - -#: ../src/metacity.schemas.in.h:136 -msgid "" -"The keybinding used to toggle fullscreen mode. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja uključuje ili isključuje prikaz preko cijelog " -"zaslona.Oblik zapisa izgleda kao \"<Control>a\" ili \"<Shift><" -"Alt>F1\". Program za obradu je dosta slobodan i dozvoljava velika ili " -"mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". " -"Ako postavite opciju na specijalni niz znakova \"disabled\", tada neće biti " -"korištena niti jedna kombinacija dugmadi za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:137 -msgid "" -"The keybinding used to toggle maximization. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja uključuje ili isključuje uvećanje prozora na " -"najveću moguću veličinu. Oblik zapisa izgleda kao \"<Control>a\" ili " -"\"<Shift><Alt>F1\". Program za obradu je dosta slobodan i " -"dozvoljava velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" " -"i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " -"\"disabled\", tada neće biti korištena niti jedna kombinacija dugmadi za ovu " -"aktivnost." - -#: ../src/metacity.schemas.in.h:138 -msgid "" -"The keybinding used to toggle shaded/unshaded state. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja uključuje ili isključuje zasjenčeno stanje. Oblik " -"zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". " -"Program za obradu je dosta slobodan i dozvoljava velika ili mala slova, " -"takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite " -"opciju na specijalni niz znakova \"disabled\", tada neće biti korištena niti " -"jedna kombinacija dugmadi za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:139 -msgid "" -"The keybinding used to toggle whether the window is on all workspaces or " -"just one. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja uključuje ili isključuje mogučnost da prozor bude " -"na svim radnim površinama. Oblik zapisa izgleda kao \"<Control>a\" ili " -"\"<Shift><Alt>F1\". Program za obradu je dosta slobodan i " -"dozvoljava velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" " -"i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " -"\"disabled\", tada neće biti korištena niti jedna kombinacija dugmadi za ovu " -"aktivnost." - -#: ../src/metacity.schemas.in.h:140 -msgid "" -"The keybinding used to unmaximize a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja poništava uvećanje prozora na najveću moguću " -"veličinu. Oblik zapisa izgleda kao \"<Control>a\" ili \"<Shift>" -"<Alt>F1\". Program za obradu je dosta slobodan i dozvoljava velika ili " -"mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". " -"Ako postavite opciju na specijalni niz znakova \"disabled\", tada neće biti " -"korištena niti jedna kombinacija dugmadi za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:141 -msgid "" -"The keybinding which display's the panel's \"Run Application\" dialog box. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"Kombinacija dugmadi koja prikazuje dijaloški okvir \"Pokreni program\". " -"Oblik zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>" -"F1\". Program za obradu je dosta slobodan i dozvoljava velika ili mala " -"slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako " -"postavite opciju na specijalni niz znakova \"disabled\", tada neće biti " -"korištena niti jedna kombinacija dugmadi za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:142 -#, fuzzy -msgid "" -"The keybinding which invokes a terminal. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja prikazuje glavni izbornik ploče. Oblik zapisa " -"izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program " -"za obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " -"skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju " -"na specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija dugmadi za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:143 -msgid "" -"The keybinding which invokes the panel's screenshot utility to take a " -"screenshot of a window. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja pokreće alat ploče za snimanje izgleda prozora. " -"Oblik zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>" -"F1\". Program za obradu je dosta slobodan i dozvoljava velika ili mala " -"slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako " -"postavite opciju na specijalni niz znakova \"disabled\", tada neće biti " -"korištena niti jedna kombinacija dugmadi za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:144 -msgid "" -"The keybinding which invokes the panel's screenshot utility. The format " -"looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -"parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"Kombinacija dugmadi koja pokreće alat ploče za snimanje izgleda zaslona. " -"Oblik zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>" -"F1\". Program za obradu je dosta slobodan i dozvoljava velika ili mala " -"slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako " -"postavite opciju na specijalni niz znakova \"disabled\", tada neće biti " -"korištena niti jedna kombinacija dugmadi za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:145 -msgid "" -"The keybinding which shows the panel's main menu. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja prikazuje glavni izbornik ploče. Oblik zapisa " -"izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program " -"za obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " -"skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju " -"na specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija dugmadi za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:146 -msgid "The name of a workspace." -msgstr "Ime radne površine." - -#: ../src/metacity.schemas.in.h:147 -msgid "The screenshot command" -msgstr "Naredba za slikanje zaslona" - -#: ../src/metacity.schemas.in.h:148 -msgid "" -"The theme determines the appearance of window borders, titlebar, and so " -"forth." -msgstr "" -"Tema utvrđuje izgled rubova prozora, naslovne linije i svega ostalog sličnog." - -#: ../src/metacity.schemas.in.h:149 -msgid "" -"The time delay before raising a window if auto_raise is set to true. The " -"delay is given in thousandths of a second." -msgstr "" -"Vremenski period prije podizanja prozora ako je opcija auto_raise " -"postavljena na „true“. Period se izražava u hiljaditim dijelovima sekunde." - -#: ../src/metacity.schemas.in.h:150 -msgid "" -"The window focus mode indicates how windows are activated. It has three " -"possible values; \"click\" means windows must be clicked in order to focus " -"them, \"sloppy\" means windows are focused when the mouse enters the window, " -"and \"mouse\" means windows are focused when the mouse enters the window and " -"unfocused when the mouse leaves the window." -msgstr "" -"Fokus prozora podešava kako će prozori biti aktivirani. Ima tri moguće " -"vrijednosti „click“ znači da prozor mora biti izabran da bi dobio fokus, " -"„sloppy“ znači da prozor dobija fokus kada pokazivač miša uđe u prozor i " -"„mouse“ što znači da će prozor biti fokusiran kada pokazivačka strelica miša " -"uđe u prozor i biti defokusiran kada strelica izađe iz prozora." - -#: ../src/metacity.schemas.in.h:151 -msgid "The window screenshot command" -msgstr "Naredba za snimanje prozora" - -#: ../src/metacity.schemas.in.h:152 -msgid "" -"This keybinding changes whether a window is above or below other windows. If " -"the window is covered by another window, it raises the window above other " -"windows. If the window is already fully visible, it lowers the window below " -"other windows. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja postavlja prozor iznad ili ispod ostalih prozora. " -"Ako je prozor prekriven drugim prozorom, on se podiže iznad njega. Ako je " -"prozor već na vrhu, on se spušta ispod ostalih prozora postavljajući drugi " -"prozor na vrh. Oblik zapisa izgleda kao \"<Control>a\" ili \"<" -"Shift><Alt>F1\". Program za obradu je dosta slobodan i dozvoljava " -"velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< " -"Ctrl>\". Ako postavite opciju na specijalni niz znakova \"disabled\", " -"tada neće biti korištena niti jedna kombinacija dugmadi za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:153 -msgid "" -"This keybinding lowers a window below other windows. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja spušta prozor ispod svih ostalih prozora. Oblik " -"zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". " -"Program za obradu je dosta slobodan i dozvoljava velika ili mala slova, " -"takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite " -"opciju na specijalni niz znakova \"disabled\", tada neće biti korištena niti " -"jedna kombinacija dugmadi za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:154 -msgid "" -"This keybinding raises the window above other windows. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija dugmadi koja podiže prozor iznad svih ostalih prozora. Oblik " -"zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". " -"Program za obradu je dosta slobodan i dozvoljava velika ili mala slova, " -"takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite " -"opciju na specijalni niz znakova \"disabled\", tada neće biti korištena niti " -"jedna kombinacija dugmadi za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:155 -msgid "" -"This keybinding resizes a window to fill available horizontal space. The " -"format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"Kombinacija dugmadi koja mijenja veličinu prozora tako da popuni čitav " -"vodoravni prostor. Oblik zapisa izgleda kao \"<Control>a\" ili \"<" -"Shift><Alt>F1\". Program za obradu je dosta slobodan i dozvoljava " -"velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< " -"Ctrl>\". Ako postavite opciju na specijalni niz znakova \"disabled\", " -"tada neće biti korištena niti jedna kombinacija dugmadi za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:156 -msgid "" -"This keybinding resizes a window to fill available vertical space. The " -"format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"Kombinacija dugmadi koja mijenja veličinu prozora tako da popuni čitav " -"okomiti prostor. Oblik zapisa izgleda kao \"<Control>a\" ili \"<" -"Shift><Alt>F1\". Program za obradu je dosta slobodan i dozvoljava " -"velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< " -"Ctrl>\". Ako postavite opciju na specijalni niz znakova \"disabled\", " -"tada neće biti korištena niti jedna kombinacija dugmadi za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:157 -msgid "" -"This option determines the effects of double-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, and 'toggle_maximize' which will maximize/unmaximize the window." -msgstr "" -"Ova opcija određuje efekt dvostrukog klika na naslovnu liniju prozora. " -"Trenutno su ispravne opcije 'toggle_shade', što će uključiti ili poništiti " -"sjenčenje prozora, i 'toggle_maximize' što će uvećati ili poništiti uvećanje " -"prozora." - -#: ../src/metacity.schemas.in.h:158 -msgid "Toggle always on top state" -msgstr "Uključi da je uvijek na vrhu" - -#: ../src/metacity.schemas.in.h:159 -msgid "Toggle fullscreen mode" -msgstr "Postavi preko cijelog ekrana" - -#: ../src/metacity.schemas.in.h:160 -msgid "Toggle maximization state" -msgstr "Promijeni stanje maksimizacije " - -#: ../src/metacity.schemas.in.h:161 -msgid "Toggle shaded state" -msgstr "Promijeni stanje zasjenčenja" - -#: ../src/metacity.schemas.in.h:162 -msgid "Toggle window on all workspaces" -msgstr "Uključi prozor na svim radnim površinama" - -#: ../src/metacity.schemas.in.h:163 -msgid "" -"Turns on a visual indication when an application or the system issues a " -"'bell' or 'beep'; useful for the hard-of-hearing and for use in noisy " -"environments, or when 'audible bell' is off." -msgstr "" -"Uključuje vizuelni prikaz kada program ili sistem 'zazvoni'; korisno u " -"bučnim situacijama, ili kada je zvučno zvonce isključeno. " - -#: ../src/metacity.schemas.in.h:164 -msgid "Unmaximize window" -msgstr "Poništi uvećanje prozora " - -#: ../src/metacity.schemas.in.h:165 -msgid "Use standard system font in window titles" -msgstr "Koristi standardni font sistema za naslov prozora" - -#: ../src/metacity.schemas.in.h:166 -msgid "Visual Bell Type" -msgstr "Vrsta vizulnog zvonca " - -#: ../src/metacity.schemas.in.h:167 -msgid "Window focus mode" -msgstr "Način fokusa prozora" - -#: ../src/metacity.schemas.in.h:168 -msgid "Window title font" -msgstr "Font naslova prozora" - -#: ../src/prefs.c:528 ../src/prefs.c:544 ../src/prefs.c:560 ../src/prefs.c:576 -#: ../src/prefs.c:592 ../src/prefs.c:612 ../src/prefs.c:628 ../src/prefs.c:644 -#: ../src/prefs.c:660 ../src/prefs.c:676 ../src/prefs.c:692 ../src/prefs.c:708 -#: ../src/prefs.c:724 ../src/prefs.c:741 ../src/prefs.c:757 ../src/prefs.c:773 -#: ../src/prefs.c:789 ../src/prefs.c:805 ../src/prefs.c:820 ../src/prefs.c:835 -#: ../src/prefs.c:850 ../src/prefs.c:866 ../src/prefs.c:882 ../src/prefs.c:898 -#, c-format -msgid "GConf key \"%s\" is set to an invalid type\n" -msgstr "GConf ključ \"%s\" je postavljen na neispravan tip\n" - -#: ../src/prefs.c:943 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"“%s“ je pronađen u bazi podešavanja što nije ispravna vrijednost za dugme " -"koje mijenja ponašanje dugmadi miša\n" - -#: ../src/prefs.c:967 ../src/prefs.c:1428 -#, c-format -msgid "GConf key '%s' is set to an invalid value\n" -msgstr "GConf ključ '%s' je postavljen na neispravnu vrijednost\n" - -#: ../src/prefs.c:1145 -#, c-format -msgid "Could not parse font description \"%s\" from GConf key %s\n" -msgstr "Nije moguće analizirati opis fonta \"%s\" iz Gconf ključa %s\n" - -#: ../src/prefs.c:1330 -#, c-format -msgid "" -"%d stored in GConf key %s is not a reasonable number of workspaces, current " -"maximum is %d\n" -msgstr "" -"%d pohranjen u GConf ključu %s nije podnošljiv broj radnih površina, " -"trenutno je maksimalan %d\n" - -#: ../src/prefs.c:1390 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"Kompromisi za loše programe su isključeni. Neki programi se mogu ponašati " -"čudno.\n" - -#: ../src/prefs.c:1455 -#, c-format -msgid "%d stored in GConf key %s is out of range 0 to %d\n" -msgstr "%d pohranjen u GConf ključu %s je izvan dometa od 0 do %d\n" - -#: ../src/prefs.c:1589 -#, c-format -msgid "Error setting number of workspaces to %d: %s\n" -msgstr "Greška prilikom podešavanja broja radnih površina na %d: %s\n" - -#: ../src/prefs.c:1833 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "" -"\"%s\" nađen u konfiguracijskoj bazi nije ispravna kombinacija dugmadi \"%s" -"\"\n" - -#: ../src/prefs.c:2187 -#, c-format -msgid "Error setting name for workspace %d to \"%s\": %s\n" -msgstr "Greška prilikom podešavanja imena radne površine %d u \"%s\": %s\n" - -#: ../src/resizepopup.c:126 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" - -#: ../src/screen.c:408 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "Ekran %d na prikazu '%s' je neispravan\n" - -#: ../src/screen.c:424 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"Ekran %d na prikazu \"%s\" već ima upravitelja prozora; pokušajte koristiti " -"--replace opciju da zamjenite trenutni upravitelj prozora.\n" - -#: ../src/screen.c:448 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "" -"Nije moguće dobiti biranje upravitelja prozora na ekranu %d prikaza \"%s\"\n" - -#: ../src/screen.c:506 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "Ekran %d na prikazu \"%s\" već ima rukovoditelja prozora\n" - -#: ../src/screen.c:716 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "Nije moguće otpustiti ekran %d na prikazu \"%s\"\n" - -#: ../src/session.c:884 ../src/session.c:891 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Nije moguće napraviti direktorij '%s': %s\n" - -#: ../src/session.c:901 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "Nije moguće otvoriti datoteku '%s' za pisanje: %s\n" - -#: ../src/session.c:1053 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Pogreška pisanja datoteke sesije '%s': %s\n" - -#: ../src/session.c:1058 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Greška pri zatvaranju datoteke sesije '%s': %s\n" - -#: ../src/session.c:1133 -#, c-format -msgid "Failed to read saved session file %s: %s\n" -msgstr "Nije uspjelo čitanje snimljene datoteke sesije %s: %s\n" - -#: ../src/session.c:1168 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Nije uspjela analiza snimljene datoteke sesije: %s\n" - -#: ../src/session.c:1217 -msgid "<metacity_session> attribute seen but we already have the session ID" -msgstr "<metacity_session> atribut opažen ali već imamo ID sesije" - -#: ../src/session.c:1230 -#, c-format -msgid "Unknown attribute %s on <metacity_session> element" -msgstr "Nepoznata osobina %s u <metacity_session> elementu" - -#: ../src/session.c:1247 -msgid "nested <window> tag" -msgstr "ugniježden <window> tag" - -#: ../src/session.c:1305 ../src/session.c:1337 -#, c-format -msgid "Unknown attribute %s on <window> element" -msgstr "Nepoznata osobina %s u <window> elementu" - -#: ../src/session.c:1409 -#, c-format -msgid "Unknown attribute %s on <maximized> element" -msgstr "Nepoznata osobina %s u <maximized> elementu" - -#: ../src/session.c:1469 -#, c-format -msgid "Unknown attribute %s on <geometry> element" -msgstr "Nepoznata osobina %s u <geometry> elementu" - -#: ../src/session.c:1489 -#, c-format -msgid "Unknown element %s" -msgstr "Nepoznati element %s" - -#: ../src/session.c:1961 -#, c-format -msgid "" -"Error launching metacity-dialog to warn about apps that don't support " -"session management: %s\n" -msgstr "" -"Greška pri pokretanju metacity-dialoga da upozori aplikacije koje ne " -"podržavaju session managment %s\n" - -#: ../src/theme-parser.c:224 ../src/theme-parser.c:242 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Linija %d karakter %d: %s" - -#: ../src/theme-parser.c:396 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "Osobina \"%s\" je ponovljena dva puta u istom elementu <%s>" - -#: ../src/theme-parser.c:414 ../src/theme-parser.c:439 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "Osobina \"%s\" je neispravana u elementu <%s> u ovom kontekstu" - -#: ../src/theme-parser.c:485 -#, c-format -msgid "Integer %ld must be positive" -msgstr "Cijeli broj %ld mora biti pozitivan" - -#: ../src/theme-parser.c:493 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "Cijeli broj %ld je prevelik ,trenutno najveći je %d" - -#: ../src/theme-parser.c:521 ../src/theme-parser.c:602 -#: ../src/theme-parser.c:626 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "Nije moguće analizirati \"%s\" kao broj sa pomičnim zarezom" - -#: ../src/theme-parser.c:552 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "Logičke vrijednosti moraju biti \"true\" ili \"false\", a ne \"%s\"" - -#: ../src/theme-parser.c:572 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "Ugao mora biti između 0.0 i 360.0, bio %g\n" - -#: ../src/theme-parser.c:638 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" -"Alfa osobina mora biti između 0.0 (nevidljivo) i 1.0 (potpuno neprozirno), " -"bila je %g\n" - -#: ../src/theme-parser.c:684 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"Neispravna veličina naslova \"%s\" (mora biti jedna od xx-mala,x-mala,mala," -"srednja,velika,x-velika,xx-velika)\n" - -#: ../src/theme-parser.c:729 ../src/theme-parser.c:737 -#: ../src/theme-parser.c:807 ../src/theme-parser.c:897 -#: ../src/theme-parser.c:935 ../src/theme-parser.c:1012 -#: ../src/theme-parser.c:1062 ../src/theme-parser.c:1070 -#: ../src/theme-parser.c:1126 ../src/theme-parser.c:1134 -#: ../src/theme-parser.c:2936 ../src/theme-parser.c:3025 -#: ../src/theme-parser.c:3032 ../src/theme-parser.c:3039 -#, c-format -msgid "No \"%s\" attribute on <%s> element" -msgstr "Nema atributa \"%s\" na <%s> elementu" - -#: ../src/theme-parser.c:837 ../src/theme-parser.c:905 -#: ../src/theme-parser.c:943 ../src/theme-parser.c:1020 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s> ime \"%s\" se već drugi put koristi" - -#: ../src/theme-parser.c:849 ../src/theme-parser.c:955 -#: ../src/theme-parser.c:1032 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "<%s> izvor \"%s\" nije definisan" - -#: ../src/theme-parser.c:968 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "<%s> geometrija \"%s\" se nije definisala" - -#: ../src/theme-parser.c:981 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "<%s> morate odrediti geometriju ili izvor koji ima geometriju" - -#: ../src/theme-parser.c:1080 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Nepoznat tip \"%s\" na elementu <%s>" - -#: ../src/theme-parser.c:1091 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "Nepoznat style_set \"%s\" na elementu <%s>" - -#: ../src/theme-parser.c:1099 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "Vrsti prozora \"%s\" je već dodijeljena grupa stilova" - -#: ../src/theme-parser.c:1143 -#, c-format -msgid "Unknown function \"%s\" for menu icon" -msgstr "Nepoznata funkcija \"%s\" za sličicu izbornika" - -#: ../src/theme-parser.c:1152 -#, c-format -msgid "Unknown state \"%s\" for menu icon" -msgstr "Nepoznato stanje \"%s\" za sličicu menija" - -#: ../src/theme-parser.c:1160 -#, c-format -msgid "Theme already has a menu icon for function %s state %s" -msgstr "Tema već posjeduje sličicu izbornika za funkciju %s stanje %s" - -#: ../src/theme-parser.c:1177 ../src/theme-parser.c:3244 -#: ../src/theme-parser.c:3323 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "Nije podešen <draw_ops>sa imenom \"%s\"" - -#: ../src/theme-parser.c:1192 ../src/theme-parser.c:1256 -#: ../src/theme-parser.c:1545 ../src/theme-parser.c:3124 -#: ../src/theme-parser.c:3178 ../src/theme-parser.c:3338 -#: ../src/theme-parser.c:3515 ../src/theme-parser.c:3553 -#: ../src/theme-parser.c:3591 ../src/theme-parser.c:3629 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "Element <%s> nije dozvoljen ispod <%s>" - -#: ../src/theme-parser.c:1282 ../src/theme-parser.c:1369 -#: ../src/theme-parser.c:1439 -#, c-format -msgid "No \"name\" attribute on element <%s>" -msgstr "Bez \"ime\" atributa na elementu <%s>" - -#: ../src/theme-parser.c:1289 ../src/theme-parser.c:1376 -#, c-format -msgid "No \"value\" attribute on element <%s>" -msgstr "Bez \"vrijednost\" atributa na elementu <%s>" - -#: ../src/theme-parser.c:1320 ../src/theme-parser.c:1334 -#: ../src/theme-parser.c:1393 -msgid "" -"Cannot specify both button_width/button_height and aspect ratio for buttons" -msgstr "" -"Nije moguće odrediti istovremeno dugme_širine/dugme_visine i omjer slike za " -"dugmad" - -#: ../src/theme-parser.c:1343 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "Udaljenost \"%s\" je nepoznata" - -#: ../src/theme-parser.c:1402 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "Odnos \"%s\" je nepoznat" - -#: ../src/theme-parser.c:1446 -#, c-format -msgid "No \"top\" attribute on element <%s>" -msgstr "Bez \"vrh\" atributa na elementu <%s>" +#: ../data/50-mutter-navigation.xml.in.h:1 +msgid "Navigation" +msgstr "Navigacija" -#: ../src/theme-parser.c:1453 -#, c-format -msgid "No \"bottom\" attribute on element <%s>" -msgstr "Bez \"dno\" atributa na elementu <%s>" - -#: ../src/theme-parser.c:1460 -#, c-format -msgid "No \"left\" attribute on element <%s>" -msgstr "Bez \"lijevo\" atributa na elementu <%s>" - -#: ../src/theme-parser.c:1467 -#, c-format -msgid "No \"right\" attribute on element <%s>" -msgstr "Bez \"desno\" atributa na elementu <%s>" - -#: ../src/theme-parser.c:1499 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "Rub „%s“ je nepoznat" - -#: ../src/theme-parser.c:1655 ../src/theme-parser.c:1765 -#: ../src/theme-parser.c:1868 ../src/theme-parser.c:2055 -#: ../src/theme-parser.c:2869 -#, c-format -msgid "No \"color\" attribute on element <%s>" -msgstr "Bez \"boja\" atributa na elementu <%s>" - -#: ../src/theme-parser.c:1662 -#, c-format -msgid "No \"x1\" attribute on element <%s>" -msgstr "Bez \"x1\" atributa na elementu <%s>" - -#: ../src/theme-parser.c:1669 ../src/theme-parser.c:2714 -#, c-format -msgid "No \"y1\" attribute on element <%s>" -msgstr "Bez \"y1\" atributa na elementu <%s>" - -#: ../src/theme-parser.c:1676 -#, c-format -msgid "No \"x2\" attribute on element <%s>" -msgstr "Bez \"x2\" atributa na elementu <%s>" - -#: ../src/theme-parser.c:1683 ../src/theme-parser.c:2721 -#, c-format -msgid "No \"y2\" attribute on element <%s>" -msgstr "Bez \"y2\" atributa na elementu <%s>" - -#: ../src/theme-parser.c:1772 ../src/theme-parser.c:1875 -#: ../src/theme-parser.c:1981 ../src/theme-parser.c:2062 -#: ../src/theme-parser.c:2168 ../src/theme-parser.c:2266 -#: ../src/theme-parser.c:2483 ../src/theme-parser.c:2609 -#: ../src/theme-parser.c:2707 ../src/theme-parser.c:2781 -#: ../src/theme-parser.c:2876 -#, c-format -msgid "No \"x\" attribute on element <%s>" -msgstr "Bez \"x\" atributa na elementu <%s>" - -#: ../src/theme-parser.c:1779 ../src/theme-parser.c:1882 -#: ../src/theme-parser.c:1988 ../src/theme-parser.c:2069 -#: ../src/theme-parser.c:2175 ../src/theme-parser.c:2273 -#: ../src/theme-parser.c:2490 ../src/theme-parser.c:2616 -#: ../src/theme-parser.c:2788 ../src/theme-parser.c:2883 -#, c-format -msgid "No \"y\" attribute on element <%s>" -msgstr "Bez \"y\" atributa na elementu <%s>" - -#: ../src/theme-parser.c:1786 ../src/theme-parser.c:1889 -#: ../src/theme-parser.c:1995 ../src/theme-parser.c:2076 -#: ../src/theme-parser.c:2182 ../src/theme-parser.c:2280 -#: ../src/theme-parser.c:2497 ../src/theme-parser.c:2623 -#: ../src/theme-parser.c:2795 -#, c-format -msgid "No \"width\" attribute on element <%s>" -msgstr "Bez \"širina\" atributa na elementu <%s>" - -#: ../src/theme-parser.c:1793 ../src/theme-parser.c:1896 -#: ../src/theme-parser.c:2002 ../src/theme-parser.c:2083 -#: ../src/theme-parser.c:2189 ../src/theme-parser.c:2287 -#: ../src/theme-parser.c:2504 ../src/theme-parser.c:2630 -#: ../src/theme-parser.c:2802 -#, c-format -msgid "No \"height\" attribute on element <%s>" -msgstr "Bez \"visina\" atributa na elementu <%s>" - -#: ../src/theme-parser.c:1903 -#, c-format -msgid "No \"start_angle\" attribute on element <%s>" -msgstr "Nema \"start_angle\" atributa na elementu <%s>" - -#: ../src/theme-parser.c:1910 -#, c-format -msgid "No \"extent_angle\" attribute on element <%s>" -msgstr "Bez \"extent_ange\" atributa na elementu <%s>" - -#: ../src/theme-parser.c:2090 -#, c-format -msgid "No \"alpha\" attribute on element <%s>" -msgstr "Bez \"alfa\" atributa na elementu <%s>" - -#: ../src/theme-parser.c:2161 -#, c-format -msgid "No \"type\" attribute on element <%s>" -msgstr "Bez \"tip\" atributa na elementu <%s> " - -#: ../src/theme-parser.c:2209 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "Nisam shvatio vrijednost \"%s\" za vrstu stepenovanja" - -#: ../src/theme-parser.c:2294 -#, c-format -msgid "No \"filename\" attribute on element <%s>" -msgstr "Bez \"imedatoteke\" atributa na elementu <%s>" - -#: ../src/theme-parser.c:2319 ../src/theme-parser.c:2827 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "Nisam shvatio vrstu popunjavanja \"%s\" za <%s> element" - -#: ../src/theme-parser.c:2462 ../src/theme-parser.c:2595 -#: ../src/theme-parser.c:2700 -#, c-format -msgid "No \"state\" attribute on element <%s>" -msgstr "Bez \"stanje\" atributa na elementu <%s> " - -#: ../src/theme-parser.c:2469 ../src/theme-parser.c:2602 -#, c-format -msgid "No \"shadow\" attribute on element <%s>" -msgstr "Bez \"sjena\" atributa na elementu <%s>" - -#: ../src/theme-parser.c:2476 -#, c-format -msgid "No \"arrow\" attribute on element <%s>" -msgstr "Bez \"strelica\" atributa na elementu <%s>" - -#: ../src/theme-parser.c:2529 ../src/theme-parser.c:2651 -#: ../src/theme-parser.c:2739 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "Nisam shvatio sjenu \"%s\" za <%s> element" - -#: ../src/theme-parser.c:2539 ../src/theme-parser.c:2661 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "Nisam shvatio sjenu \"%s\" za <%s> element" - -#: ../src/theme-parser.c:2549 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "Ne razumijmem strelicu \"%s\" za <%s> element" - -#: ../src/theme-parser.c:2962 ../src/theme-parser.c:3078 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "Nije podešen <draw_ops> imena \"%s\" " - -#: ../src/theme-parser.c:2974 ../src/theme-parser.c:3090 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "uključivanje draw_ops \"%s\" ovdje bi kreiralo kružnu napomenu" - -#: ../src/theme-parser.c:3153 -#, c-format -msgid "No \"value\" attribute on <%s> element" -msgstr "Bez \"vrijednost\" atributa na <%s> elementu " - -#: ../src/theme-parser.c:3210 -#, c-format -msgid "No \"position\" attribute on <%s> element" -msgstr "Bez \"pozicija\" atributa na elementu <%s>" - -#: ../src/theme-parser.c:3219 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Nepoznata pozicija \"%s\" za dio okvira" - -#: ../src/theme-parser.c:3227 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "Stil okvira već ima dio na poziciji %s" - -#: ../src/theme-parser.c:3272 -#, c-format -msgid "No \"function\" attribute on <%s> element" -msgstr "Bez \"funkcija\" atributa na elementu <%s>" - -#: ../src/theme-parser.c:3280 ../src/theme-parser.c:3384 -#, c-format -msgid "No \"state\" attribute on <%s> element" -msgstr "Bez \"stanje\" atributa na <%s> elementu " - -#: ../src/theme-parser.c:3289 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Nepoznata funkcija \"%s\" za dugme" - -#: ../src/theme-parser.c:3298 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Nepoznato stanje \"%s\" za dugme" - -#: ../src/theme-parser.c:3306 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "Stil okvira već ima dugme za funkciju %s stanja %s" - -#: ../src/theme-parser.c:3376 -#, c-format -msgid "No \"focus\" attribute on <%s> element" -msgstr "Bez \"usredotočenje\" atributa na elementu <%s>" - -#: ../src/theme-parser.c:3392 -#, c-format -msgid "No \"style\" attribute on <%s> element" -msgstr "Bez \"stil\" atributa na <%s> elementu " - -#: ../src/theme-parser.c:3401 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "\"%s“ nije dozvoljena vrijednost za osobinu fokusa" - -#: ../src/theme-parser.c:3410 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "\"%s\" nije dozvoljena vrijednost za osobinu state" - -#: ../src/theme-parser.c:3420 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "Stil nazvan \"%s\" nije bio određen" - -#: ../src/theme-parser.c:3430 -#, c-format -msgid "No \"resize\" attribute on <%s> element" -msgstr "Bez \"promjenaveličine\" atributa na elementu <%s>" +#: ../data/50-mutter-navigation.xml.in.h:2 +msgid "Move window to workspace 1" +msgstr "Premjesti prozor na radnu površinu 1" -#: ../src/theme-parser.c:3440 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "\"%s\" nije dozvoljena vrijednost za osobina resize" +#: ../data/50-mutter-navigation.xml.in.h:3 +msgid "Move window to workspace 2" +msgstr "Premjesti prozor na radnu površinu 2" -#: ../src/theme-parser.c:3450 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" -"Nikako ne treba imati „resize“ atribut u elementu <%s> za uvećana/zasjenčena " -"stanja" +#: ../data/50-mutter-navigation.xml.in.h:4 +msgid "Move window to workspace 3" +msgstr "Premjesti prozor na radnu površinu 3" -#: ../src/theme-parser.c:3464 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "Stil je već odabran za stanje %s promjene veličine %s fokusiranja %s" +#: ../data/50-mutter-navigation.xml.in.h:5 +msgid "Move window to workspace 4" +msgstr "Premjesti prozor na radnu površinu 4" -#: ../src/theme-parser.c:3475 ../src/theme-parser.c:3486 -#: ../src/theme-parser.c:3497 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "Stil je već odabran za stanje %s fokusiranja %s" +#: ../data/50-mutter-navigation.xml.in.h:6 +msgid "Move window to last workspace" +msgstr "Premjesti prozor na posljednji radni prostor" -#: ../src/theme-parser.c:3536 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Ne mogu postojati dva draw_ops-a za element <piece> (tema navodi svojstvo " -"draw_ops i <draw_ops> element ili navodi dva elementa)" +#: ../data/50-mutter-navigation.xml.in.h:7 +msgid "Move window one workspace to the left" +msgstr "Pomjeri prozor jedan radnu površinu ulijevo" -#: ../src/theme-parser.c:3574 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Ne mogu postojati dva draw_ops-a za element <button> (tema navodi draw_ops " -"svojstvo i <draw_ops> element ili navodi dva elementa)" +#: ../data/50-mutter-navigation.xml.in.h:8 +msgid "Move window one workspace to the right" +msgstr "Pomjeri prozor jednu radnu površinu udesno" -#: ../src/theme-parser.c:3612 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Ne mogu postojati dva draw_ops-a za element <menu_icon> (tema navodi " -"svojstvo draw_ops i <draw_ops> element ili navodi dva elementa)" +#: ../data/50-mutter-navigation.xml.in.h:9 +msgid "Move window one workspace up" +msgstr "Pomjeri prozor jednu radnu površinu gore" -#: ../src/theme-parser.c:3659 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "Najdalji element u temi mora biti <metacity_theme> a ne<%s>" +#: ../data/50-mutter-navigation.xml.in.h:10 +msgid "Move window one workspace down" +msgstr "Premjesti prozor za jednu radnu površinu ispod" -#: ../src/theme-parser.c:3679 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "Element <%s> nije dozvoljen unutar imena/autora/datuma/opisa ." +#: ../data/50-mutter-navigation.xml.in.h:11 +msgid "Move window one monitor to the left" +msgstr "Premjesti prozor monitora ulijevo" -#: ../src/theme-parser.c:3684 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "Element <%s> nije dozvoljen unutar <constant> elementa" +#: ../data/50-mutter-navigation.xml.in.h:12 +msgid "Move window one monitor to the right" +msgstr "Premjesti prozor monitora udesno" -#: ../src/theme-parser.c:3696 -#, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "" -"Element <%s> nije dozvoljen unutar udaljenost/granica/omjer_slike elementa" +#: ../data/50-mutter-navigation.xml.in.h:13 +msgid "Move window one monitor up" +msgstr "Premjesti prozor monitora gore" -#: ../src/theme-parser.c:3718 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "Element <%s> nije dozvoljen unutar operacije crtanja" +#: ../data/50-mutter-navigation.xml.in.h:14 +msgid "Move window one monitor down" +msgstr "Premjesti prozor monitora dolje" -#: ../src/theme-parser.c:3728 ../src/theme-parser.c:3758 -#: ../src/theme-parser.c:3763 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "Element <%s> nije dozvoljen unutar <%s> elementa" +#: ../data/50-mutter-navigation.xml.in.h:15 +msgid "Switch applications" +msgstr "Prebacuje programe" -#: ../src/theme-parser.c:3984 -msgid "No draw_ops provided for frame piece" -msgstr "Bez draw_ops datih komadu okvira" +#: ../data/50-mutter-navigation.xml.in.h:16 +msgid "Switch to previous application" +msgstr "Prebaci na prethodnu aplikaciju" -#: ../src/theme-parser.c:3999 -msgid "No draw_ops provided for button" -msgstr "Bez draw_ops datih dugmetu" +#: ../data/50-mutter-navigation.xml.in.h:17 +msgid "Switch windows" +msgstr "Prebaci prozore" -#: ../src/theme-parser.c:4014 -msgid "No draw_ops provided for menu icon" -msgstr "Bez draw_ops datih sličici izbornika" +#: ../data/50-mutter-navigation.xml.in.h:18 +msgid "Switch to previous window" +msgstr "Prebaci na prethodni prozor" -#: ../src/theme-parser.c:4054 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "Tekst nije dozvoljen unutar elementa<%s>" +#: ../data/50-mutter-navigation.xml.in.h:19 +msgid "Switch windows of an application" +msgstr "Prebacuje prozor programa" -#: ../src/theme-parser.c:4109 -msgid "<name> specified twice for this theme" -msgstr "<ime> naznačen dvaput za ovu temu" +#: ../data/50-mutter-navigation.xml.in.h:20 +msgid "Switch to previous window of an application" +msgstr "Prebaci na prethodni prozor aplikacije" -#: ../src/theme-parser.c:4120 -msgid "<author> specified twice for this theme" -msgstr "<autor> naznačen dvaput za ovu temu" +#: ../data/50-mutter-navigation.xml.in.h:21 +msgid "Switch system controls" +msgstr "Prebacuje kontrole sistema" -#: ../src/theme-parser.c:4131 -msgid "<copyright> specified twice for this theme" -msgstr "<autorska prava> određena dvaput za ovu temu" +#: ../data/50-mutter-navigation.xml.in.h:22 +msgid "Switch to previous system control" +msgstr "Prebaci na prethodnu kontrolu sistema" -#: ../src/theme-parser.c:4142 -msgid "<date> specified twice for this theme" -msgstr "<datum> određen dvaput za ovu temu" +#: ../data/50-mutter-navigation.xml.in.h:23 +msgid "Switch windows directly" +msgstr "Prebacuje prozore direktno" -#: ../src/theme-parser.c:4153 -msgid "<description> specified twice for this theme" -msgstr "<opis> naveden dvaput za ovu temu" +#: ../data/50-mutter-navigation.xml.in.h:24 +msgid "Switch directly to previous window" +msgstr "Prebaci direktno na prethodni prozor" -#: ../src/theme-parser.c:4348 -#, c-format -msgid "Failed to read theme from file %s: %s\n" -msgstr "Nije uspjelo čitanje teme iz datoteke %s: %s\n" +#: ../data/50-mutter-navigation.xml.in.h:25 +msgid "Switch windows of an app directly" +msgstr "Prebacuje prozore programa direktno" -#: ../src/theme-parser.c:4403 -#, c-format -msgid "Theme file %s did not contain a root <metacity_theme> element" -msgstr "Datoteka sa temom %s ne sadrži korjenski <metacity_theme> element" +#: ../data/50-mutter-navigation.xml.in.h:26 +msgid "Switch directly to previous window of an app" +msgstr "Prebaci direktno na prethodni prozor aplikacije" -#: ../src/theme-viewer.c:70 -msgid "/_Windows" -msgstr "/_Prozori" +#: ../data/50-mutter-navigation.xml.in.h:27 +msgid "Switch system controls directly" +msgstr "Prebacuje kontrole sistema direktno" -#: ../src/theme-viewer.c:71 -msgid "/Windows/tearoff" -msgstr "/Windows/otcijepi" +#: ../data/50-mutter-navigation.xml.in.h:28 +msgid "Switch directly to previous system control" +msgstr "Prebaci direktno na prethodnu kontrolu sistema" -#: ../src/theme-viewer.c:72 -msgid "/Windows/_Dialog" -msgstr "/Prozori/_Dijalog" +#: ../data/50-mutter-navigation.xml.in.h:29 +msgid "Hide all normal windows" +msgstr "Skriva sve obične prozore" -#: ../src/theme-viewer.c:73 -msgid "/Windows/_Modal dialog" -msgstr "/Prozori/_Modalni dijalog" +#: ../data/50-mutter-navigation.xml.in.h:30 +msgid "Switch to workspace 1" +msgstr "Prebaci se na radnu površinu 1" -#: ../src/theme-viewer.c:74 -msgid "/Windows/_Utility" -msgstr "/Windows/_Alat" +#: ../data/50-mutter-navigation.xml.in.h:31 +msgid "Switch to workspace 2" +msgstr "Prebaci se na radnu površinu 2" -#: ../src/theme-viewer.c:75 -msgid "/Windows/_Splashscreen" -msgstr "/Windows/_Pozdravna slika" +#: ../data/50-mutter-navigation.xml.in.h:32 +msgid "Switch to workspace 3" +msgstr "Prebaci se na radnu površinu 3" -#: ../src/theme-viewer.c:76 -msgid "/Windows/_Top dock" -msgstr "/Windows/_Gornje sidro" +#: ../data/50-mutter-navigation.xml.in.h:33 +msgid "Switch to workspace 4" +msgstr "Prebaci se na radnu površinu 4" -#: ../src/theme-viewer.c:77 -msgid "/Windows/_Bottom dock" -msgstr "/Prozori/D_onje sidro" +#: ../data/50-mutter-navigation.xml.in.h:34 +msgid "Switch to last workspace" +msgstr "Prebaci na posljednji radni prostor" -#: ../src/theme-viewer.c:78 -msgid "/Windows/_Left dock" -msgstr "/Prozori/_Lijevo sidro" +#: ../data/50-mutter-navigation.xml.in.h:35 +msgid "Move to workspace left" +msgstr "Premješta na radni prostor lijevo" -#: ../src/theme-viewer.c:79 -msgid "/Windows/_Right dock" -msgstr "/Prozori/_Desno sidro" +#: ../data/50-mutter-navigation.xml.in.h:36 +msgid "Move to workspace right" +msgstr "Premješta na radni prostor desno" -#: ../src/theme-viewer.c:80 -msgid "/Windows/_All docks" -msgstr "/Prozori/_Sva sidra" +#: ../data/50-mutter-navigation.xml.in.h:37 +msgid "Move to workspace above" +msgstr "Move to workspace above" -#: ../src/theme-viewer.c:81 -msgid "/Windows/Des_ktop" -msgstr "/Prozori/_Desktop" +#: ../data/50-mutter-navigation.xml.in.h:38 +msgid "Move to workspace below" +msgstr "Move to workspace below" -#: ../src/theme-viewer.c:131 -msgid "Open another one of these windows" -msgstr "Otvori neki drugi od ovih prozora" +#: ../data/50-mutter-system.xml.in.h:1 +msgid "System" +msgstr "Sistem" -#: ../src/theme-viewer.c:138 -msgid "This is a demo button with an 'open' icon" -msgstr "Ovo je probno dugme s sličicom 'otvori'" +#: ../data/50-mutter-system.xml.in.h:2 +msgid "Show the run command prompt" +msgstr "Prikazuje prompt za pokretanje naredbe" -#: ../src/theme-viewer.c:145 -msgid "This is a demo button with a 'quit' icon" -msgstr "Ovo je probno dugme s sličicom 'izlaz'" +#: ../data/50-mutter-system.xml.in.h:3 +msgid "Show the activities overview" +msgstr "Prikazuje pregled aktivnosti" -#: ../src/theme-viewer.c:241 -msgid "This is a sample message in a sample dialog" -msgstr "Ovo je primjer poruke u primjeru dijaloga" +#: ../data/50-mutter-windows.xml.in.h:1 +msgid "Windows" +msgstr "Windows" -#: ../src/theme-viewer.c:324 -#, c-format -msgid "Fake menu item %d\n" -msgstr "Lažna stavka izbornika %d\n" +#: ../data/50-mutter-windows.xml.in.h:2 +msgid "Activate the window menu" +msgstr "Aktiviraj meni prozora" -#: ../src/theme-viewer.c:358 -msgid "Border-only window" -msgstr "Prozor samo s okvirom" +#: ../data/50-mutter-windows.xml.in.h:3 +msgid "Toggle fullscreen mode" +msgstr "Postavi preko cijelog ekrana" -#: ../src/theme-viewer.c:360 -msgid "Bar" -msgstr "Bar" +#: ../data/50-mutter-windows.xml.in.h:4 +msgid "Toggle maximization state" +msgstr "Promijeni stanje maksimizacije" -#: ../src/theme-viewer.c:377 -msgid "Normal Application Window" -msgstr "Običan prozor programa" +#: ../data/50-mutter-windows.xml.in.h:5 +msgid "Maximize window" +msgstr "Maksimiziraj prozor" -#: ../src/theme-viewer.c:382 -msgid "Dialog Box" -msgstr "Dijaloški okvir" +#: ../data/50-mutter-windows.xml.in.h:6 +msgid "Restore window" +msgstr "Vrati veličinu prozoru" -#: ../src/theme-viewer.c:387 -msgid "Modal Dialog Box" -msgstr "Modalni dijaloški prozor" +#: ../data/50-mutter-windows.xml.in.h:7 +msgid "Toggle shaded state" +msgstr "Promijeni stanje zasjenčenja" -#: ../src/theme-viewer.c:392 -msgid "Utility Palette" -msgstr "Paleta alata" +#: ../data/50-mutter-windows.xml.in.h:8 +msgid "Close window" +msgstr "Zatvori prozor" -#: ../src/theme-viewer.c:397 -msgid "Torn-off Menu" -msgstr "Isključi izbornik" +#: ../data/50-mutter-windows.xml.in.h:9 +msgid "Hide window" +msgstr "Sakrij prozor" -#: ../src/theme-viewer.c:402 -msgid "Border" -msgstr "Rub" +#: ../data/50-mutter-windows.xml.in.h:10 +msgid "Move window" +msgstr "Pomjeri prozor" -#: ../src/theme-viewer.c:731 -#, c-format -msgid "Button layout test %d" -msgstr "Test izgleda dugmeta %d" +#: ../data/50-mutter-windows.xml.in.h:11 +msgid "Resize window" +msgstr "Promijeni veličinu prozora" -#: ../src/theme-viewer.c:760 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g milisekundi za crtanje jednog okvira prozora" +#: ../data/50-mutter-windows.xml.in.h:12 +msgid "Toggle window on all workspaces or one" +msgstr "Prikazuje prozor na svim radnim prostorima ili samo na jednom" -#: ../src/theme-viewer.c:803 -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Uptreba: metacity-theme-viewer [NAZIV_TEME]\n" +#: ../data/50-mutter-windows.xml.in.h:13 +msgid "Raise window if covered, otherwise lower it" +msgstr "Izdiže prozor ukoliko ga drugi prozor zaklanja, u protivnom ga spušta" -#: ../src/theme-viewer.c:810 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "Greška pri učitavanju teme: %s\n" +#: ../data/50-mutter-windows.xml.in.h:14 +msgid "Raise window above other windows" +msgstr "Podigni prozor iznad ostalih prozora" -#: ../src/theme-viewer.c:816 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "Tema \"%s\" je učitana za %g sekundi.\n" +#: ../data/50-mutter-windows.xml.in.h:15 +msgid "Lower window below other windows" +msgstr "Spustiti prozor ispod ostalih prozora" -#: ../src/theme-viewer.c:839 -msgid "Normal Title Font" -msgstr "Obični font naslova" +#: ../data/50-mutter-windows.xml.in.h:16 +msgid "Maximize window vertically" +msgstr "Maksimiziraj prozor vertikalno" -#: ../src/theme-viewer.c:845 -msgid "Small Title Font" -msgstr "Mali font naslova" +#: ../data/50-mutter-windows.xml.in.h:17 +msgid "Maximize window horizontally" +msgstr "Maksimiziraj prozor horizontalno" -#: ../src/theme-viewer.c:851 -msgid "Large Title Font" -msgstr "Veliki font naslova" +#: ../data/50-mutter-windows.xml.in.h:18 +msgid "View split on left" +msgstr "Vidi podijeljeno lijevo" -#: ../src/theme-viewer.c:856 -msgid "Button Layouts" -msgstr "Izgledi dugmadi" +#: ../data/50-mutter-windows.xml.in.h:19 +msgid "View split on right" +msgstr "Vidi podijeljeno desno" -#: ../src/theme-viewer.c:861 -msgid "Benchmark" -msgstr "Mjerilo" +#: ../data/mutter.desktop.in.h:1 +msgid "Mutter" +msgstr "Mutter" -#: ../src/theme-viewer.c:908 -msgid "Window Title Goes Here" -msgstr "Ovdje ide naslov prozora" +#: ../data/org.gnome.mutter.gschema.xml.in.h:1 +msgid "Modifier to use for extended window management operations" +msgstr "" +"Modifier koji će se koristiti za proširene operacije window menadžmenta" -#: ../src/theme-viewer.c:1012 -#, c-format +#: ../data/org.gnome.mutter.gschema.xml.in.h:2 msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" +"This key will initiate the \"overlay\", which is a combination window " +"overview and application launching system. The default is intended to be the " +"\"Windows key\" on PC hardware. It's expected that this binding either the " +"default or set to the empty string." msgstr "" -"Na korisničkoj strani sam nacrtao %d okvira za %g sekundi (%g milisekundi po " -"okviru) i %g sekundi ukupnog vremena uključujući resurse poslužitelja X-a (%" -"g milisekundi po okviru)\n" +"Ovaj ključ će inicirati \"prekrivanje\", koje je kombinacija pregleda " +"prozora i sistema pokretanja aplikacije. Zadata vrijednost je namjenjena da " +"bude \"Window ključ\" na PC hardware. Očekuje se da je ovo povezivanje ili " +"zadato ili postavljeno na prazan string." -#: ../src/theme-viewer.c:1227 -msgid "position expression test returned TRUE but set error" +#: ../data/org.gnome.mutter.gschema.xml.in.h:3 +msgid "Attach modal dialogs" msgstr "" -"Ispitivanje mjesta izraza je rezultiralo izrazom \"TRUE\", ali je " -"postavljena greška" +"Pridruži dijaloške prozore koji ograničavaju klikanje izvan njih (modalne)" -#: ../src/theme-viewer.c:1229 -msgid "position expression test returned FALSE but didn't set error" +#: ../data/org.gnome.mutter.gschema.xml.in.h:4 +msgid "" +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." msgstr "" -"Ispitivanje mjesta izraza je rezultiralo izrazom \"FALSE\", ali nije " -"postavljena greška" - -#: ../src/theme-viewer.c:1233 -msgid "Error was expected but none given" -msgstr "Očekivana je greška, ali nije niti jedna prijavljena" - -#: ../src/theme-viewer.c:1235 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "Očekivana je greška %d, ali je dobivena %d" - -#: ../src/theme-viewer.c:1241 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "Nije očekivana greška, ali je prijavljena: %s" - -#: ../src/theme-viewer.c:1245 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "vrijednost za x je bila %d, a očekivana je %d" +"Kada je uključeno, umjesto nezavisnih alatnih traka, modalni dijaloški " +"prozori se javljaju pored naslovne trake nadređenog prozora i mogu se " +"kretati zajedno s nadređenim prozorom." -#: ../src/theme-viewer.c:1248 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "vrijednost za y je bila %d, a očekivana je %d" +#: ../data/org.gnome.mutter.gschema.xml.in.h:5 +msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "Omogući poravnanje rubova prilikom spuštanja prozora na rubove ekrana" -#: ../src/theme-viewer.c:1310 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" +#: ../data/org.gnome.mutter.gschema.xml.in.h:6 +msgid "" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." msgstr "" -"%d koordinatni izrazi parsirani u %g sekundi (%g sekundi u prosjeku)\n" - -#: ../src/theme.c:202 -msgid "top" -msgstr "na vrh" - -#: ../src/theme.c:204 -msgid "bottom" -msgstr "na dno" +"Ako je omogućeno, padajuće prozore na vertikalnim ivicama zaslona proširi " +"vertikalno i promijeni njihovu veličinu horizontalno tako da pokriju pola " +"raspoložive oblasti. Padajuće prozore na vrhu zaslona proširi do maksimuma." -#: ../src/theme.c:206 -msgid "left" -msgstr "lijevo" +#: ../data/org.gnome.mutter.gschema.xml.in.h:7 +msgid "Workspaces are managed dynamically" +msgstr "Radni prostor je upravljan dinamički" -#: ../src/theme.c:208 -msgid "right" -msgstr "desno" - -#: ../src/theme.c:222 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "geometrija okvira ne navodi „%s“ dimenziju" - -#: ../src/theme.c:241 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "geometrija okvira ne navodi „%s“ dimenziju za rub „%s“" +#: ../data/org.gnome.mutter.gschema.xml.in.h:8 +msgid "" +"Determines whether workspaces are managed dynamically or whether there's a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." +msgstr "" +"Odredi da li su radni prostori upravljani dinamički ili da li postoji " +"konstantan broj radnih prostora (određen brojem radnih prostora ključ u org." +"gnome.desktop.wm.preferences)." -#: ../src/theme.c:278 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "Odnos dugme %g nije razuman" +#: ../data/org.gnome.mutter.gschema.xml.in.h:9 +msgid "Workspaces only on primary" +msgstr "Radni prostori samo na primarni" -#: ../src/theme.c:290 -msgid "Frame geometry does not specify size of buttons" -msgstr "Geometrija oblika nije odredila veličinu dugmadi." +#: ../data/org.gnome.mutter.gschema.xml.in.h:10 +msgid "" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." +msgstr "" +"Odrediti da li bi se trebalo desiti prebacivanje radnih prostora za prozore " +"na svim monitorima ili samo za prozore na primarnom monitoru." -#: ../src/theme.c:843 -msgid "Gradients should have at least two colors" -msgstr "Stepenovanje mora imati barem dvije boje" +#: ../data/org.gnome.mutter.gschema.xml.in.h:11 +msgid "No tab popup" +msgstr "No tab popup" -#: ../src/theme.c:969 -#, c-format +#: ../data/org.gnome.mutter.gschema.xml.in.h:12 msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." msgstr "" -"GTK specifikacija boje mora imati stanje u zagradi,naprimjer gtk:fg" -"[NORMAL] gdje je NORMAL stanje;nije moguće analizirati \"%s\"" +"Odrediti da li korištenje popup i označavanje okvira treba biti onemogućeno " +"za ciklčni prozor." -#: ../src/theme.c:983 -#, c-format -msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#: ../data/org.gnome.mutter.gschema.xml.in.h:13 +msgid "Delay focus changes until the pointer stops moving" msgstr "" -"GTK specifikacija boje mora imati zatvorenu zagradu poslije stanja," -"naprimjer gtk:fg[NORMAL] gdje je NORMAL stanje;nije moguće analizirati \"%s" -"\"" +"Fokusirati se na promjene u kašnjenju sve dok se pokazivač ne prestane " +"pomjerati" -#: ../src/theme.c:994 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "Nisam shvatio stanje \"%s\" u izboru boja" +#: ../data/org.gnome.mutter.gschema.xml.in.h:14 +msgid "" +"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " +"the focus will not be changed immediately when entering a window, but only " +"after the pointer stops moving." +msgstr "" +"Ako je označeno tačno, i fokus režim je \"neuredan\" ili \"miš\" onda fokus " +"neće biti promijenjen momentalno pri otvaranju prozora, nego samo nakon što " +"se pokazivač prestane kretati." -#: ../src/theme.c:1007 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "Ne razumijem komponentu boje \"%s\" u izboru boja" +#: ../data/org.gnome.mutter.gschema.xml.in.h:15 +msgid "Draggable border width" +msgstr "Draggable okvir širina" -#: ../src/theme.c:1037 -#, c-format +#: ../data/org.gnome.mutter.gschema.xml.in.h:16 msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" +"The amount of total draggable borders. If the theme's visible borders are " +"not enough, invisible borders will be added to meet this value." msgstr "" -"Format miješanja „blend/bg_color/fg_color/alpha“, „%s“ se ne uklapa u " -"traženi format zapisa" - -#: ../src/theme.c:1048 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "Nije moguće analizirati alfa vrijednost \"%s\" u nijansnoj boji" +"Iznos totalnog draggable okvira. Ako vidljivost okvira teme nije dovoljna, " +"nevidljivi okviri će biti dodani da ispune tu vrijednost." -#: ../src/theme.c:1058 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "Alfa vrijednost \"%s\" u nijansiranoj boji nije između 0.0 i 1.0" +#: ../data/org.gnome.mutter.gschema.xml.in.h:17 +msgid "Auto maximize nearly monitor sized windows" +msgstr "Automatsko povećavanje veličine prozora, skoro do veličine monitora" -#: ../src/theme.c:1105 -#, c-format +#: ../data/org.gnome.mutter.gschema.xml.in.h:18 msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." msgstr "" -"Format osjenčenja je \"shade/base_color/factor\", \"%s\" ne odgovara formatu" +"Ako je omogućeno, novi prozori koji su u startu veličine monitora " +"automatski povećati." -#: ../src/theme.c:1116 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "Nije moguće analizirati faktor sjenčenja \"%s\" u sjenčenim bojama" +#: ../data/org.gnome.mutter.gschema.xml.in.h:19 +msgid "Place new windows in the center" +msgstr "Smjesti nove prozore u centar" -#: ../src/theme.c:1126 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "Faktor sjenčenja \"%s\" u zasjenčenoj boji je negativan" +#: ../data/org.gnome.mutter.gschema.xml.in.h:20 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" +"Kada je tačno, novi prozori će uvijek biti stavljeni u središte aktivnog " +"zaslona monitora." -#: ../src/theme.c:1155 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Nije moguće analizirati boju \"%s\"" +#: ../data/org.gnome.mutter.gschema.xml.in.h:21 +msgid "Select window from tab popup" +msgstr "Odabrati prozor iz tab popup" -#: ../src/theme.c:1417 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "Izraz koordinacije sadrži karakter '%s' koji nije dozvoljen" +#: ../data/org.gnome.mutter.gschema.xml.in.h:22 +msgid "Cancel tab popup" +msgstr "Zatvorti tab popup" -#: ../src/theme.c:1444 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "" -"Izraz koordinacije sadrži broj sa pokretnom točkom '%s' koji nije mogao biti " -"analiziran" +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:1 +msgid "Switch to VT 1" +msgstr "Prebaci na VT 1" -#: ../src/theme.c:1458 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "" -"Izraz koordinacije sadrži cijeli broj '%s' koji nije mogao biti analiziran" +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:2 +msgid "Switch to VT 2" +msgstr "Prebaci na VT 2" -#: ../src/theme.c:1525 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "" -"Izraz koordinacije sadrži nepoznati operator na početku ovog teksta \"%s\"" +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:3 +msgid "Switch to VT 3" +msgstr "Prebaci na VT 3" -#: ../src/theme.c:1582 -msgid "Coordinate expression was empty or not understood" -msgstr "Izraz koordinacije je bio prazan ili nije shvatio" +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:4 +msgid "Switch to VT 4" +msgstr "Prebaci na VT 4" -#: ../src/theme.c:1725 ../src/theme.c:1735 ../src/theme.c:1769 -msgid "Coordinate expression results in division by zero" -msgstr "Izraz koordinata je rezultat podjele sa nulom" +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:5 +msgid "Switch to VT 5" +msgstr "Prebaci na VT 5" -#: ../src/theme.c:1777 -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "" -"Izraz koordinacije pokušava upotrijebiti mod operator na broju sa pomičnim " -"zarezom" +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:6 +msgid "Switch to VT 6" +msgstr "Prebaci na VT 6" -#: ../src/theme.c:1834 -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "Izraz koordinacije ima operator \"%s\" gdje se očekivao operant" +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:7 +msgid "Switch to VT 7" +msgstr "Prebaci na VT 7" -#: ../src/theme.c:1843 -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "Izraz koordinacije je imao operant a očekivao se operator" +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:8 +msgid "Switch to VT 8" +msgstr "Prebaci na VT 8" -#: ../src/theme.c:1851 -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "Izraz koordinacije je završio sa operatorom umjesto operanta" +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:9 +msgid "Switch to VT 9" +msgstr "Prebaci na VT 9" -#: ../src/theme.c:1861 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" -"Izraz koordinacije ima operator \"%c\" koji prati operator \"%c\" ali bez " -"operacija između" +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:10 +msgid "Switch to VT 10" +msgstr "Prebaci na VT 10" -#: ../src/theme.c:1980 -msgid "" -"Coordinate expression parser overflowed its buffer, this is really a " -"Metacity bug, but are you sure you need a huge expression like that?" -msgstr "" -"Izraz koordinacije analizom je preopteretio svoj međumemorijski prostor, ovo " -"je u stvari bug Metacity-a, ali jeste li sigurni da vam treba tako veliki " -"izraz?" +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:11 +msgid "Switch to VT 11" +msgstr "Prebaci na VT 11" -#: ../src/theme.c:2009 -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "" -"Izraz koordinacije je morao zatvoriti zagrade sa ne otvorenim zagradama." +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:12 +msgid "Switch to VT 12" +msgstr "Prebaci na VT 12" -#: ../src/theme.c:2072 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "Izraz koordinacije je imao nepoznatu varijablu ili konstantu \"%s\"" +#: ../src/backends/meta-monitor-manager.c:364 +msgid "Built-in display" +msgstr "Konstruiši na display" -#: ../src/theme.c:2129 -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "Izraz koordinacije je imao otvorene zagrade sa ne zatvorenim zagradama" +#: ../src/backends/meta-monitor-manager.c:391 +msgid "Unknown" +msgstr "Nepoznato" -#: ../src/theme.c:2140 -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "Izraz koordinacije izgleda ne sadrži operacije ili operante." +#: ../src/backends/meta-monitor-manager.c:393 +msgid "Unknown Display" +msgstr "Nepoznat ekran" -#: ../src/theme.c:2384 ../src/theme.c:2406 ../src/theme.c:2427 +#. TRANSLATORS: this is a monitor vendor nami, followed by a +#. * size in inches, liki 'Dell 15"' +#. +#: ../src/backends/meta-monitor-manager.c:401 #, c-format -msgid "Theme contained an expression \"%s\" that resulted in an error: %s\n" -msgstr "Tema sadrži izraz \"%s\" koji uzrokuje grešku: %s\n" +msgid "%s %s" +msgstr "%s %s" -#: ../src/theme.c:3913 +#. This probably means that a non-WM compositor liki xcompmgr is running; +#. * we have no way to get it to exit +#: ../src/compositor/compositor.c:456 #, c-format msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" +"Another compositing manager is already running on screen %i on display \"%s" +"\"." msgstr "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"svejedno\"/> mora biti " -"određeno za format ovog okvira" +"Drugi compositing manager je vec pokrenut na zaslonu \"%i\" na displeju \"%s" +"\"." -#: ../src/theme.c:4363 ../src/theme.c:4395 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" -"Nedostaje <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"svejedno\"/>" +#: ../src/core/bell.c:185 +msgid "Bell event" +msgstr "Zvonce" -#: ../src/theme.c:4446 +#: ../src/core/delete.c:127 #, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Nije uspjelo učitavanje teme \"%s\": %s\n" +msgid "“%s” is not responding." +msgstr "„%s“ se ne odaziva." -#: ../src/theme.c:4592 ../src/theme.c:4599 ../src/theme.c:4606 -#: ../src/theme.c:4613 ../src/theme.c:4620 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "Nije podešen <%s> za temu \"%s\"" +#: ../src/core/delete.c:129 +msgid "Application is not responding." +msgstr "Aplikacija se ne odaziva." -#: ../src/theme.c:4630 -#, c-format +#: ../src/core/delete.c:134 msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." msgstr "" -"Nije odabrana vrsta okvira za prozor tipa \"%s\" u temi \"%s\", dodajte " -"<window type=\"%s\" style_set=\"svejedno\"/> element" +"Možete odabrati pričekate malo dok se program ne nastavi ili prisiliti " +"program da si potpuno izgasi." -#: ../src/theme.c:4652 -#, c-format -msgid "" -"<menu_icon function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this theme" -msgstr "" -"<menu_icon function=\"%s\" state=\"%s\" draw_ops=\"svejedno\"/>mora biti " -"naveden za ovu temu" +#: ../src/core/delete.c:141 +msgid "_Wait" +msgstr "_Čekaj" -#: ../src/theme.c:5041 ../src/theme.c:5103 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" -"Korisnički definisane konstante moraju početi velikim slovom; \"%s\" ne " -"počinje " +#: ../src/core/delete.c:141 +msgid "_Force Quit" +msgstr "_Prisili izlaz" -#: ../src/theme.c:5049 ../src/theme.c:5111 +#: ../src/core/display.c:562 #, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "Konstanta \"%s\" je već definisana" +msgid "Failed to open X Window System display '%s'\n" +msgstr "Neuspjeh pri otvaranju X Window Sistem prikaza %s'\n" -#: ../src/util.c:93 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Nije uspjelo otvaranje zapisnika o ispravku grešaka: %s\n" +#: ../src/core/main.c:176 +msgid "Disable connection to session manager" +msgstr "Onemogućiti vezu sa upravljačem sesije" -#: ../src/util.c:103 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Nije uspjelo fdopen() datoteke zapisnika%s: %s\n" +#: ../src/core/main.c:182 +msgid "Replace the running window manager" +msgstr "Zamijeni pokretanje prozor upravljača" -#: ../src/util.c:109 -#, c-format -msgid "Opened log file %s\n" -msgstr "Otvorena zapisnička datoteka %s\n" +#: ../src/core/main.c:188 +msgid "Specify session management ID" +msgstr "Navedite ID upravljača sesije" -#: ../src/util.c:203 -msgid "Window manager: " -msgstr "Upravitelj prozora:" +#: ../src/core/main.c:193 +msgid "X Display to use" +msgstr "Željeni X ekran" -#: ../src/util.c:349 -msgid "Bug in window manager: " -msgstr "Greška u upravitelju prozora: " +#: ../src/core/main.c:199 +msgid "Initialize session from savefile" +msgstr "Koristi sesiju iz datoteke" -#: ../src/util.c:378 -msgid "Window manager warning: " -msgstr "Upozorenje upravitelja prozora: " +#: ../src/core/main.c:205 +msgid "Make X calls synchronous" +msgstr "Napravi X prozore sinhroniziranim" -#: ../src/util.c:402 -msgid "Window manager error: " -msgstr "Greška upravitelja prozora: " +#: ../src/core/main.c:212 +msgid "Run as a wayland compositor" +msgstr "Pokreni kao wayland kompozitor" -#: ../src/window-props.c:162 -#, c-format -msgid "Application set a bogus _NET_WM_PID %ld\n" -msgstr "Aplikacija je postavila prividan _NETWM_PID %ld\n" +#: ../src/core/main.c:220 +msgid "Run as a full display server, rather than nested" +msgstr "Pokreni kao puni prikaz servera, umjesto uklopljenog" -#. first time through -#: ../src/window.c:5205 +#: ../src/core/mutter.c:39 #, c-format msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" +"mutter %s\n" +"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" msgstr "" -"Prozor %s je postavio SM_CLIENT_ID na samog sebe umjesto na prozor " -"WM_CLIENT_LEADER kao što je navedeno u ICCCM.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/window.c:5876 +"mutter %s\n" +"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; seje the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" + +#: ../src/core/mutter.c:53 +msgid "Print version" +msgstr "Ispiši verziju" + +#: ../src/core/mutter.c:59 +msgid "Mutter plugin to use" +msgstr "Mutter plugin to usi" + +#: ../src/core/prefs.c:2004 #, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %" -"d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"Prozor %s je postavio MWM hint navodeći da mu se veličina ne može " -"promijeniti, ali postavlja min. veličinu %d x %d a maksimalnu %d x %d; ovo " -"nema previše smisla.\n" +msgid "Workspace %d" +msgstr "Radni prostor %d" -#: ../src/xprops.c:153 +#: ../src/core/screen.c:525 #, c-format msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +"Display \"%s\" already has a window manager; try using the --replace option " +"to replace the current window manager." msgstr "" -"Prozor 0x%lx ima osobinu %s\n" -"tako da je očekivano da ima tip %s format %d,\n" -"a zapravo ima tip %s format %d n_items %d.\n" -"Ovo je najverovatnije greška u programu, a ne u upravitelju prozora.\n" -"Prozor ima naslov=\"%s\" klasa=\"%s\" ime=\"%s\"\n" +"Ekran \"%s\" već ima upravitelja prozora; pokušajte koristiti --replace " +"opciju da zamjenite trenutni upravitelj prozora." -#: ../src/xprops.c:399 +#: ../src/core/screen.c:607 #, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "Osobina %s na prozoru 0x%lx je sadržala neispravan UTF-8\n" +msgid "Screen %d on display '%s' is invalid\n" +msgstr "Ekran %d na prikazu '%s' je neispravan\n" -#: ../src/xprops.c:482 -#, c-format +#: ../src/core/util.c:118 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter je kompajliran bez podrške verbose načina\n" + +#: ../src/x11/session.c:1815 msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" +"These windows do not support "save current setup" and will have to " +"be restarted manually next time you log in." msgstr "" -"Osobina %s na prozoru 0x%lx sadrži neispravni UTF-8 za predmet %d na popisu\n" +"Ovi prozori ne podržavaju mogućnost „snimi trenutna podešavanja“ pa ćete " +"morati da ih ručno ponovo pokrenete kada se sljedeći put prijavite." + +#: ../src/x11/window-props.c:549 +#, c-format +msgid "%s (on %s)" +msgstr "%s (na %s)" diff --git a/po/ca.po b/po/ca.po index 68ca2c529..2b67406cd 100644 --- a/po/ca.po +++ b/po/ca.po @@ -5,416 +5,266 @@ # Jesús Moreno <jmmolas@wanadoo.es>, 2002. # Jordi Mallach <jordi@sindominio.net>, 2003, 2004, 2005, 2006, 2007, 2008. # David Planella <david.planella@gmail.com>, 2008, 2009, 2011, 2012. +# Jordi Serratosa <jordis@softcatala.cat>, 2012, 2017. +# Gil Forcada <gilforcada@guifi.net>, 2012, 2013, 2014, 2016. # msgid "" msgstr "" "Project-Id-Version: metacity 2.24\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-03-15 23:16+0100\n" -"PO-Revision-Date: 2012-03-15 23:17+0100\n" -"Last-Translator: David Planella <david.planella@gmail.com>\n" -"Language-Team: Softcatalà <tradgnome@softcatala.org>\n" -"Language: \n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2019-08-06 00:49+0000\n" +"PO-Revision-Date: 2018-06-17 10:25+0200\n" +"Last-Translator: Jordi Mas <jmas@softcatala.org>\n" +"Language-Team: Catalan <tradgnome@softcatala.org>\n" +"Language: ca\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bits\n" +"Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Poedit 2.0.6\n" -#: ../src/50-muffin-windows.xml.in.h:1 -msgid "Windows" -msgstr "Finestres" - -#: ../src/50-muffin-windows.xml.in.h:2 -msgid "View split on left" -msgstr "Mostra la partició a l'esquerra" - -#: ../src/50-muffin-windows.xml.in.h:3 -msgid "View split on right" -msgstr "Mostra la partició a la dreta" - -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format -msgid "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." -msgstr "" -"Ja s'està executant un altre gestor de composició a la pantalla %i a la " -"visualització «%s»." - -#: ../src/core/bell.c:307 -msgid "Bell event" -msgstr "Esdeveniment de campana" - -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Es desconeix la informació demanada sobre la finestra: %d" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Navegació" -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> no està responent." +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Mou la finestra a l'espai de treball 1" -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "L'aplicació no està responent." +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Mou la finestra a l'espai de treball 2" -#: ../src/core/delete.c:119 -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "" -"Podeu esperar un moment perquè continuï o podeu forçar-ne la sortida " -"completa." +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Mou la finestra a l'espai de treball 3" -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "_Espera" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Mou la finestra a l'espai de treball 4" -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "_Força'n la sortida" +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Mou la finestra a l'últim espai de treball" -#: ../src/core/display.c:387 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "Manca l'extensió %s necessària per a la composició" +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "Mou la finestra un espai de treball amunt" -#: ../src/core/display.c:453 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "" -"S'ha produït un error en obrir la pantalla del sistema de finestres X «%s»\n" +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "Mou la finestra un espai de treball avall" -#: ../src/core/keybindings.c:852 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "" -"Ja hi ha algun altre programa utilitzant la clau %s amb els modificadors %x " -"com a vinculació\n" +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "Mou la finestra un monitor a l'esquerra" -#: ../src/core/main.c:206 -msgid "Disable connection to session manager" -msgstr "Inhabilita la connexió al gestor de sessions" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "Mou la finestra un monitor a la dreta" -#: ../src/core/main.c:212 -msgid "Replace the running window manager" -msgstr "Reemplaça el gestor de finestres en execució" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "Mou la finestra un monitor amunt" -#: ../src/core/main.c:218 -msgid "Specify session management ID" -msgstr "Especifica l'ID de gestió de sessió" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "Mou la finestra un monitor avall" -#: ../src/core/main.c:223 -msgid "X Display to use" -msgstr "Visualització X per usar" +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "Canvia d'aplicacions" -#: ../src/core/main.c:229 -msgid "Initialize session from savefile" -msgstr "Inicialitza la sessió des del fitxer desat" +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "Canvia a l'aplicació anterior" -#: ../src/core/main.c:235 -msgid "Make X calls synchronous" -msgstr "Fes que les crides a l'X siguin síncrones" +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "Canvia de finestres" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "No s'ha pogut analitzar el directori de temes: %s\n" +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "Canvia a la finestra anterior" -#: ../src/core/main.c:520 -#, c-format -msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "" -"No s'ha trobat cap tema. Assegureu-vos que %s existeix i conté els temes " -"habituals.\n" +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "Canvia entre les finestres d'una aplicació" -#: ../src/core/muffin.c:40 -#, c-format -msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" -"Muffin %s\n" -"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., i d'altres\n" -"Això és programari lliure; vegeu els fitxers de codi font per conèixer-ne\n" -"les condicions de còpia.\n" -"No hi ha CAP garantia; ni tan sols la garantia implícita de COMERCIABILITAT\n" -"o ADEQUACIÓ A PER UN PROPÒSIT PARTICULAR.\n" +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "Canvia a la finestra anterior d'una aplicació" -#: ../src/core/muffin.c:54 -msgid "Print version" -msgstr "Escriu versió" +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "Canvia els controls del sistema" -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "Llista separada per comes de connectors de composició" +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "Canvia al control del sistema anterior" -#: ../src/core/prefs.c:1077 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"Les solucions temporals per a aplicacions amb errors estan inhabilitades. " -"Pot ser que certes aplicacions no funcionin correctament.\n" +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "Canvia immediatament entre finestres" -#: ../src/core/prefs.c:1152 -#, c-format -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "" -"No s'ha pogut analitzar la descripció de tipus de lletra «%s» de la clau %s " -"del GSettings\n" +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "Canvia immediatament a la finestra anterior" -#: ../src/core/prefs.c:1218 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"«%s», trobat a la base de dades de la configuració, no és un valor vàlid per " -"al modificador del botó del ratolí\n" +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "Canvia immediatament entre les finestres d'una aplicació" -#: ../src/core/prefs.c:1739 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "" -"«%s» trobat a la base de dades de la configuració no és un valor vàlid per a " -"la vinculació de tecla «%s»\n" +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "Canvia immediatament a la finestra anterior d'una aplicació" -#: ../src/core/prefs.c:1836 -#, c-format -msgid "Workspace %d" -msgstr "Espai de treball %d" +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "Canvia immediatament entre els controls del sistema" -#: ../src/core/screen.c:730 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "La pantalla %d en la visualització '%s' no és vàlida\n" +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "Canvia immediatament al control del sistema anterior" -#: ../src/core/screen.c:746 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"La pantalla %d en la visualització «%s» ja té un gestor de finestres; proveu " -"l'opció --replace per reemplaçar el gestor de finestres actual.\n" +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "Oculta totes les finestres normals" -#: ../src/core/screen.c:773 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "" -"No s'ha pogut adquirir la selecció del gestor de finestres en la pantalla %d " -"visualització «%s»\n" +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "Canvia a l'espai de treball 1" -#: ../src/core/screen.c:828 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "La pantalla %d en la visualització «%s» ja té un gestor de finestres\n" +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "Canvia a l'espai de treball 2" -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "No s'ha pogut alliberar la pantalla %d en la visualització «%s»\n" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "Canvia a l'espai de treball 3" -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "No s'ha pogut crear el directori «%s»: %s\n" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "Canvia a l'espai de treball 4" -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "No s'ha pogut obrir el fitxer de sessió «%s» per a l'escriptura: %s\n" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "Canvia a l'últim espai de treball" -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "S'ha produït un error en escriure el fitxer de sessió «%s»: %s\n" +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "Mou a l'espai de treball de sobre" -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "S'ha produït un error en tancar el fitxer de sessió «%s»: %s\n" +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "Mou a l'espai de treball de sota" -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "No s'ha pogut analitzar el fitxer de sessió desat: %s\n" +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "Sistema" -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "" -"S'ha vist l'atribut <muffin_session> però encara hi ha l'identificador de " -"sessió" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Mostra l'indicador d'execució d'aplicacions" -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Atribut %s desconegut a l'element <%s>" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Mostra la vista general d'activitats" -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "etiqueta <window> imbricada" +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Restaura les dreceres de teclat" -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "Element %s desconegut" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Finestres" -#: ../src/core/session.c:1809 -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" -"Aquestes finestres no implementen «desa la configuració actual» i s'hauran " -"de reiniciar manualment la pròxima vegada que entreu." +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "Activa el menú de finestra" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "No s'ha pogut obrir el registre de depuració: %s\n" +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Canvia entre el mode a pantalla completa" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "No s'ha pogut executar fdopen() sobre el fitxer de registre %s: %s\n" +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "Canvia l'estat de maximització" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "S'ha obert el fitxer de registre %s\n" +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "Maximitza la finestra" -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "Muffin es va compilar sense compatibilitat per al mode detallat\n" +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Restaura la finestra" -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "Gestor de finestres: " +#: data/50-mutter-windows.xml:18 +msgid "Close window" +msgstr "Tanca la finestra" -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "Error en el gestor de finestres: " +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "Oculta la finestra" -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "Avís del gestor de finestres: " +#: data/50-mutter-windows.xml:22 +msgid "Move window" +msgstr "Mou la finestra" -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "Error del gestor de finestres: " +#: data/50-mutter-windows.xml:24 +msgid "Resize window" +msgstr "Redimensiona la finestra" -#. first time through -#: ../src/core/window.c:7269 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" msgstr "" -"La finestra %s estableix SM_CLIENT_ID en ella mateixa, en comptes del " -"WM_CLIENT_LEADER, tal com s'especifica a ICCCM.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7932 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size " -"%d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"La finestra %s estableix un consell MWM que indica que no és " -"redimensionable, però estableix una mida mínima %d x %d i una mida màxima %d " -"x %d; açò no té massa sentit.\n" +"Canvia la funció que fa que la finestra estigui en tots els espais de " +"treball o només en un" -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "L'aplicació ha definit un _NET_WM_PID %lu fals\n" +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "Alça la finestra si està coberta per una altra; altrament, baixa-la" -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (a %s)" +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "Alça la finestra per damunt de les altres" -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "" -"WM_TRANSIENT_FOR no vàlid per a la finestra 0x%lx especificat per a %s.\n" +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "Baixa la finestra sota les altres" -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "WM_TRANSIENT_FOR per a la finestra 0x%lx per a %s crearia un bucle.\n" +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "Maximitza la finestra verticalment" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"La finestra 0x%lx té la propietat %s\n" -"que s'esperava tingués el tipus %s format %d\n" -"i actualment té el tipus %s format %d n elements %d.\n" -"És molt possible que sigui un error en l'aplicació, no pas del gestor de " -"finestres.\n" -"La finestra té el títol=«%s» classe=«%s» nom=«%s»\n" -"\n" - -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "La propietat %s en la finestra 0x%lx contenia un UTF-8 no vàlid\n" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "Maximitza la finestra horitzontalment" -#: ../src/core/xprops.c:494 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"La propietat %s en la finestra 0x%lx contenia caràcters UTF-8 no vàlids per " -"a l'element %d en la llista\n" +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "Mostra la partició a l'esquerra" -#: ../src/muffin.desktop.in.h:1 ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "Mostra la partició a la dreta" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" + +#: data/org.gnome.mutter.gschema.xml.in:7 msgid "Modifier to use for extended window management operations" msgstr "" "Modificador que s'utilitzarà per les operacions ampliades de gestió de " "finestres" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 +#: data/org.gnome.mutter.gschema.xml.in:8 msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." msgstr "" "Aquesta tecla iniciarà l'«overlay» (superposador), el qual és una combinació " "de visualització de finestres i sistema de llançament d'aplicacions. El " @@ -422,11 +272,11 @@ msgstr "" "PC. El valor d'aquesta vinculació s'espera que sigui el predeterminat o text " "en blanc." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 +#: data/org.gnome.mutter.gschema.xml.in:20 msgid "Attach modal dialogs" msgstr "Adjunta els diàlegs modals" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 +#: data/org.gnome.mutter.gschema.xml.in:21 msgid "" "When true, instead of having independent titlebars, modal dialogs appear " "attached to the titlebar of the parent window and are moved together with " @@ -436,54 +286,42 @@ msgstr "" "diàlegs modals apareixeran adjuntats a la barra de títol de la finestra mare " "i es mouran juntament amb aquesta." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -msgid "Live Hidden Windows" -msgstr "Finestres ocultes en viu" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"Determina si les finestres ocultes (és a dir, les finestres minimitzades i " -"les finestres en altres espais de treball) s'han de mantenir en viu." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 +#: data/org.gnome.mutter.gschema.xml.in:30 msgid "Enable edge tiling when dropping windows on screen edges" msgstr "" -"Habilita la tesselització a les vores en deixar anar les finestres a les " +"Habilita la tessel·lització a les vores en deixar anar les finestres a les " "vores de la pantalla" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 +#: data/org.gnome.mutter.gschema.xml.in:31 msgid "" "If enabled, dropping windows on vertical screen edges maximizes them " "vertically and resizes them horizontally to cover half of the available " "area. Dropping windows on the top screen edge maximizes them completely." msgstr "" -"So s'habilita, es maximitzaran les finestres verticalment i es " +"Si s'habilita, es maximitzaran les finestres verticalment i es " "redimensionaran horitzontalment per cobrir la meitat de l'àrea disponible en " "deixar-les anar a les vores verticals de la pantalla. Si es deixen anar a la " "vora superior de la pantalla es maximitzaran completament." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 +#: data/org.gnome.mutter.gschema.xml.in:40 msgid "Workspaces are managed dynamically" msgstr "Els espais de treball es gestionen dinàmicament" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 +#: data/org.gnome.mutter.gschema.xml.in:41 msgid "" -"Determines whether workspaces are managed dynamically or whether there's a " +"Determines whether workspaces are managed dynamically or whether there’s a " "static number of workspaces (determined by the num-workspaces key in org." "gnome.desktop.wm.preferences)." msgstr "" "Determina si els espais de treball es gestionen dinàmicament o hi ha un " -"nombre determinat d'espais de treball (determinat per la clau num-workspaces " -"a org.cinnamon.desktop.wm.preferences)." +"nombre determinat d'espais de treball (determinat per la clau «num-" +"workspaces» a «org.gnome.desktop.wm.preferences»)." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 +#: data/org.gnome.mutter.gschema.xml.in:50 msgid "Workspaces only on primary" msgstr "Espais de treball només en el primari" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 +#: data/org.gnome.mutter.gschema.xml.in:51 msgid "" "Determines whether workspace switching should happen for windows on all " "monitors or only for windows on the primary monitor." @@ -491,11 +329,11 @@ msgstr "" "Determina si el canvi d'espai de treball hauria de ser per les finestres en " "tots els monitors o només en les finestres del monitor primari." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 +#: data/org.gnome.mutter.gschema.xml.in:59 msgid "No tab popup" msgstr "Sense finestres emergents a les pestanyes" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 +#: data/org.gnome.mutter.gschema.xml.in:60 msgid "" "Determines whether the use of popup and highlight frame should be disabled " "for window cycling." @@ -503,3423 +341,406 @@ msgstr "" "Determina si s'ha d'inhabilitar el quadre que es mostra a les finestres " "emergents i ressaltades en commutar entre finestres." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Retarda el canvi del focus fins que s'aturi el punter" + +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" +"Si és «true» (cert), i el mode del focus és «sloppy» o «mouse», no es " +"canviarà el focus immediatament quan s'entri a una finestra, només es " +"canviarà quan el punter deixi de moure's." + +#: data/org.gnome.mutter.gschema.xml.in:79 msgid "Draggable border width" msgstr "Amplada del contorn arrossegable" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 +#: data/org.gnome.mutter.gschema.xml.in:80 msgid "" -"The amount of total draggable borders. If the theme's visible borders are " +"The amount of total draggable borders. If the theme’s visible borders are " "not enough, invisible borders will be added to meet this value." msgstr "" "La quantitat total de contorn arrossegable. Si els contorns visibles del " "tema no són suficients, s'afegiran contorns invisibles per aconseguir aquest " "valor." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:17 +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "" +"Maximitza automàticament les finestres que gairebé facin la mida de la " +"pantalla" + +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" +"Si s'habilita, les finestres que inicialment gairebé fan la mida de la " +"pantalla es maximitzaran automàticament." + +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Posiciona les finestres noves al centre" + +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" +"Si és «true» (cert), les finestres noves seran posicionades al centre de la " +"pantalla activa del monitor." + +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Habilita les funcionalitats experimentals" + +#: data/org.gnome.mutter.gschema.xml.in:108 +msgid "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes " +"mutter request a low priority real-time scheduling. The executable or user " +"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — " +"initializes Xwayland lazily if there are X11 clients. Requires restart." +msgstr "" + +#: data/org.gnome.mutter.gschema.xml.in:134 +msgid "Modifier to use to locate the pointer" +msgstr "Modificar a usar per localitzar el punter" + +#: data/org.gnome.mutter.gschema.xml.in:135 +msgid "This key will initiate the “locate pointer” action." +msgstr "Aquesta clau inicialitzarà l'acció «locate pointer»." + +#: data/org.gnome.mutter.gschema.xml.in:155 msgid "Select window from tab popup" msgstr "Selecció de finestra entre les emergents d'una pestanya" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:18 +#: data/org.gnome.mutter.gschema.xml.in:160 msgid "Cancel tab popup" msgstr "Cancel·lació de les finestres emergents a les pestanyes" -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "Forma d'ús: %s\n" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "Mi_nimitza" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "Ma_ximitza" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "Desma_ximitza" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "_Enrotlla" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "Desenro_tlla" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "_Mou" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "_Redimensiona" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "Mou la _barra de títol en pantalla" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "Sempre per _damunt" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "Sempre a l'espai de treball _visible" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "Només en _aquest espai de treball" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "Mou a l'espai de treball de l'es_querra" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "Mou a l'espai de treball de la _dreta" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "Mou a l'espai de treball de _sobre" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "Mou a l'espai de treball de s_ota" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "_Tanca" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "Espai de treball %d%n" - -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "Espai de treball 1_0" +#: data/org.gnome.mutter.gschema.xml.in:165 +msgid "Switch monitor configurations" +msgstr "Canvia configuracions de monitor" -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "Espai de treball %s%d" +#: data/org.gnome.mutter.gschema.xml.in:170 +msgid "Rotates the built-in monitor configuration" +msgstr "Gira la configuració del monitor integrada" -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "Mou a un altre es_pai de treball" +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Canvia al terminal virtual 1" -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Maj" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hiper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Canvia al terminal virtual 2" -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Canvia al terminal virtual 3" -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "superior" +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Canvia al terminal virtual 4" -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "inferior" +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Canvia al terminal virtual 5" -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "esquerra" +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Canvia al terminal virtual 6" -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "dreta" +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Canvia al terminal virtual 7" -#: ../src/ui/theme.c:286 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "la geometria del marc no especifica la dimensió «%s»" +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Canvia al terminal virtual 8" -#: ../src/ui/theme.c:305 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "" -"la geometria del marc no especifica la dimensió «%s» per al contorn «%s»" +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Canvia al terminal virtual 9" -#: ../src/ui/theme.c:342 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "El ràtio d'aspecte dels botons %g no és raonable" +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Canvia al terminal virtual 10" -#: ../src/ui/theme.c:354 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "La geometria del marc no especifica la mida dels botons" +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Canvia al terminal virtual 11" -#: ../src/ui/theme.c:1067 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "Els degradats han de tenir almenys dos colors" +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Canvia al terminal virtual 12" -#: ../src/ui/theme.c:1219 -#, c-format -msgid "" -"GTK custom color specification must have color name and fallback in " -"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" -msgstr "" -"L'especificació personalitzada de color de GTK ha de tenir un nom de color i " -"un alternatiu en parèntesis, p.e. gtk:personalitzat(foo,bar); no s'ha pogut " -"analitzar «%s»" +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "Torna a habilitar les dreceres" -#: ../src/ui/theme.c:1235 -#, c-format -msgid "" -"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" -"_ are valid" -msgstr "" -"El caràcter «%c» no és vàlid en el paràmetre color_name de gtk:" -"personalitzat, només són vàlids A-Za-z0-9-_" +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow X11 grabs to lock keyboard focus with Xwayland" +msgstr "Permetre la captura amb Xwayland per bloquejar el focus del teclat amb Xwayland" -#: ../src/ui/theme.c:1249 -#, c-format +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 msgid "" -"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " -"fit the format" +"Allow all keyboard events to be routed to X11 “override redirect” windows " +"with a grab when running in Xwayland. This option is to support X11 clients " +"which map an “override redirect” window (which do not receive keyboard " +"focus) and issue a keyboard grab to force all keyboard events to that " +"window. This option is seldom used and has no effect on regular X11 windows " +"which can receive keyboard focus under normal circumstances. For a X11 grab " +"to be taken into account under Wayland, the client must also either send a " +"specific X11 ClientMessage to the root window or be among the applications " +"white-listed in key “xwayland-grab-access-rules”." msgstr "" -"El format de Gtk:personalitzat és «gtk:personalitzat(color_name," -"alternatiu)», «%s» no s'ajusta al format" -#: ../src/ui/theme.c:1294 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"L'especificació de color GTK ha de tenir l'estat entre claudàtors, p.e. gtk:" -"fg[NORMAL] on NORMAL és l'estat; no s'ha pogut analitzar \"%s\"" +#: data/org.gnome.mutter.wayland.gschema.xml.in:84 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "Les aplicacions Xwayland poden capturar el teclat" -#: ../src/ui/theme.c:1308 -#, c-format +#: data/org.gnome.mutter.wayland.gschema.xml.in:85 msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." msgstr "" -"L'especificació de color GTK ha de tenir un claudàtor de tancament després " -"de l'estat, p.e. gtk:fg[NORMAL] on NORMAL és l'estat; no s'ha pogut " -"analitzar «%s»" -#: ../src/ui/theme.c:1319 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "No s'entén l'estat «%s» en l'especificació del color" - -#: ../src/ui/theme.c:1332 +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. +#. +#: src/backends/meta-input-settings.c:2531 #, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "No s'entén l'element de color «%s» en l'especificació del color" +msgid "Mode Switch (Group %d)" +msgstr "Mode de commutació (grup %d)" -#: ../src/ui/theme.c:1361 -#, c-format -msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" -msgstr "" -"El format de barreja és «blend/bg_color/fg_color/alpha», «%s» no s'ajusta al " -"format" +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2554 +msgid "Switch monitor" +msgstr "Commuta el monitor" -#: ../src/ui/theme.c:1372 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "No s'ha pogut analitzar el valor d'opacitat «%s» en el color barrejat" +#: src/backends/meta-input-settings.c:2556 +msgid "Show on-screen help" +msgstr "Mostra l'ajuda en pantalla" -#: ../src/ui/theme.c:1382 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "El valor alfa «%s» en el color barrejat no està entre 0,0 i 1,0" +#: src/backends/meta-monitor.c:223 +msgid "Built-in display" +msgstr "Pantalla integrada" -#: ../src/ui/theme.c:1429 -#, c-format -msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "" -"El format d'ombrejat és «shade/base_color/factor», «%s» no s'ajusta al format" +#: src/backends/meta-monitor.c:252 +msgid "Unknown" +msgstr "Desconeguda" -#: ../src/ui/theme.c:1440 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "No s'ha pogut analitzar el factor d'ombrejat «%s» en el color ombrejat" +#: src/backends/meta-monitor.c:254 +msgid "Unknown Display" +msgstr "Pantalla desconeguda" -#: ../src/ui/theme.c:1450 +#: src/backends/meta-monitor.c:262 #, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "El factor d'ombrejat «%s» en el color ombrejat és negatiu" +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme.c:1479 +#: src/backends/meta-monitor.c:270 #, c-format -msgid "Could not parse color \"%s\"" -msgstr "No s'ha pogut analitzar el color «%s»" +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme.c:1790 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "L'expressió coordinada conté el caràcter '%s', el qual no és permès" +#. Translators: this string will appear in Sysprof +#: src/backends/meta-profiler.c:82 +msgid "Compositor" +msgstr "Compositor" -#: ../src/ui/theme.c:1817 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:510 #, c-format msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" +"Another compositing manager is already running on screen %i on display “%s”." msgstr "" -"L'expressió coordinada conté el número '%s' de punt flotant el qual no es " -"pot analitzar" +"Ja s'està executant un altre gestor de composició al monitor %i a la " +"pantalla «%s»." -#: ../src/ui/theme.c:1831 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "L'expressió coordinada conté l'enter '%s' el qual no es pot analitzar" - -#: ../src/ui/theme.c:1953 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "" -"L'expressió coordinada conté un operador desconegut a l'inici d'aquest text: " -"«%s»" +#: src/core/bell.c:192 +msgid "Bell event" +msgstr "Esdeveniment de campana" -#: ../src/ui/theme.c:2010 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "L'expressió coordinada estava buida o no s'ha entès" +#: src/core/main.c:185 +msgid "Disable connection to session manager" +msgstr "Inhabilita la connexió al gestor de sessions" -#: ../src/ui/theme.c:2121 ../src/ui/theme.c:2131 ../src/ui/theme.c:2165 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "L'expressió coordinada dóna una divisió per zero" +#: src/core/main.c:191 +msgid "Replace the running window manager" +msgstr "Reemplaça el gestor de finestres en execució" -#: ../src/ui/theme.c:2173 -#, c-format -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "" -"L'expressió coordinada intenta utilitzar l'operador de mode en un número de " -"punt flotant" +#: src/core/main.c:197 +msgid "Specify session management ID" +msgstr "Especifica l'ID de gestió de sessió" -#: ../src/ui/theme.c:2229 -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "" -"L'expressió coordinada té un operador «%s» on hi hauria d'anar un operand" +#: src/core/main.c:202 +msgid "X Display to use" +msgstr "Visualització X per usar" -#: ../src/ui/theme.c:2238 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "L'expressió coordinada té un operand on hi hauria d'anar un operador" +#: src/core/main.c:208 +msgid "Initialize session from savefile" +msgstr "Inicialitza la sessió des del fitxer desat" -#: ../src/ui/theme.c:2246 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "" -"L'expressió coordinada ha finalitzat amb un operador en lloc d'un operand" +#: src/core/main.c:214 +msgid "Make X calls synchronous" +msgstr "Fes que les crides a l'X siguin síncrones" -#: ../src/ui/theme.c:2256 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" -"L'expressió coordinada té un operador «%c» seguit de l'operador «%c» sense " -"cap operand enmig" +#: src/core/main.c:221 +msgid "Run as a wayland compositor" +msgstr "Funciona com a compositor de Wayland" -#: ../src/ui/theme.c:2407 ../src/ui/theme.c:2452 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "L'expressió coordinada té una variable o constant desconeguda «%s»" +# Notes: +# Afegeix una nota +# +# Camins: +# ../src/core/main.c:223 +#: src/core/main.c:227 +msgid "Run as a nested compositor" +msgstr "Funciona com a compositor imbricat" -#: ../src/ui/theme.c:2506 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "" -"L'analitzador d'expressions de coordinades ha desbordat la seva memòria " -"intermèdia." +#: src/core/main.c:233 +msgid "Run wayland compositor without starting Xwayland" +msgstr "Executa el compositor wayland sense iniciar Xwayland" -#: ../src/ui/theme.c:2535 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "L'expressió coordinada té un parèntesi de tancament i cap d'obertura" +#: src/core/main.c:241 +msgid "Run as a full display server, rather than nested" +msgstr "Funciona com a servidor de pantalla completa, en comptes d'imbricat" -#: ../src/ui/theme.c:2599 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "L'expressió coordinada té un parèntesi d'obertura i cap de tancament" +#: src/core/main.c:247 +msgid "Run with X11 backend" +msgstr "Executa amb un rerefons X11" -#: ../src/ui/theme.c:2610 +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:151 #, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "L'expressió coordinada no sembla tenir cap operador o operand" +msgid "“%s” is not responding." +msgstr "«%s» no està responent." -#: ../src/ui/theme.c:2822 ../src/ui/theme.c:2842 ../src/ui/theme.c:2862 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "El tema conté una expressió que ha provocat un error: %s\n" +#: src/core/meta-close-dialog-default.c:153 +msgid "Application is not responding." +msgstr "L'aplicació no està responent." -#: ../src/ui/theme.c:4533 -#, c-format +#: src/core/meta-close-dialog-default.c:158 msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." msgstr "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"qualsevol\"/> s'ha " -"d'especificar per a aquest estil de marc" +"Podeu esperar un moment perquè continuï o podeu forçar-ne la sortida " +"completa." -#: ../src/ui/theme.c:5066 ../src/ui/theme.c:5091 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" -"No s'ha trobat <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=" -"\"qualsevol\"/>" - -#: ../src/ui/theme.c:5139 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "No s'ha pogut carregar el tema \"%s\": %s\n" - -#: ../src/ui/theme.c:5275 ../src/ui/theme.c:5282 ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 ../src/ui/theme.c:5303 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "No s'ha definit <%s> per al tema «%s»" - -#: ../src/ui/theme.c:5311 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" -"No s'ha definit cap estil de marc per al tipus de finestra \"%s\" en el tema " -"\"%s\", afegiu un element <window type=\"%s\" style_set=\"qualsevol\"/>" - -#: ../src/ui/theme.c:5709 ../src/ui/theme.c:5771 ../src/ui/theme.c:5834 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" -"Les constants de la definició d'usuari han de començar per una majúscula; " -"«%s» no ho és" - -#: ../src/ui/theme.c:5717 ../src/ui/theme.c:5779 ../src/ui/theme.c:5842 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "La constant «%s» ja s'ha definit" - -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. -#. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "No hi ha cap atribut «%s» a l'element <%s>" - -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Línia %d caràcter %d: %s" - -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "S'ha repetit l'atribut «%s» dues vegades en el mateix element <%s>" - -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "L'atribut «%s» no és vàlid per a l'element <%s> en aquest context" - -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "No s'ha pogut analitzar «%s» com a enter" - -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "No s'entenen els caràcters finals «%s» de la cadena «%s»" - -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "L'enter %ld ha de ser positiu" - -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "L'enter %ld és massa gran, el màxim actual és %d" - -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "No s'ha pogut analitzar «%s» com a un número de coma flotant" - -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "Els valors booleans han de ser «true» (cert) o «false» (fals), no «%s»" - -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "L'angle ha d'estar entre 0.0 i 360.0, era %g\n" - -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" -"L'opacitat ha d'estar entre 0.0 (invisible) i 1.0 (totalment opac), era a " -"%g\n" - -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"Escala de títol no vàlida «%s» (ha de ser una d'aquestes: xx-small, x-small, " -"small, medium, large, x-large o xx-large)\n" - -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s> amb nom «%s» s'ha utilitzat dues vegades" - -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "el pare de <%s>, «%s», no s'ha definit" - -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "la geometria de <%s>, «%s», no s'ha definit" - -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "" -"<%s> ha d'especificar bé una geometria o un pare que tingui una geometria" - -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "El valor alfa requereix que també s'especifiqui un fons de pantalla" - -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Tipus desconegut «%s» en l'element <%s>" - -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "style_set «%s» desconegut en l'element <%s>" - -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "El tipus de finestra «%s» ja té assignat un joc d'estil" - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "No es permet l'element <%s> sota <%s>" - -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" -msgstr "" -"No es pot especificar «button_width»/«button_height» i l'«aspect_ratio» a la " -"vegada per als botons" - -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "La distància «%s» és desconeguda" - -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "La relació d'aspecte «%s» és desconeguda" - -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "El contorn «%s» és desconegut" - -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "No hi ha cap atribut de «start_angle» o «from» en l'element <%s>" - -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "No hi ha cap atribut de «extent_angle» o «to» en l'element <%s>" - -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "No s'entén el valor «%s» per al tipus de degradat" - -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "No s'entén el tipus de farciment «%s» per a l'element <%s>" - -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "No s'entén l'estat «%s» per a l'element <%s>" - -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "No s'entén l'ombra «%s» per a l'element <%s>" - -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "No s'entén la fletxa «%s» per a l'element <%s>" - -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "No s'ha definit cap <draw_ops> amb el nom «%s»" - -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "La inclusió de draw_ops «%s» aquí crearà una referència circular" - -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Posició «%s» desconeguda per a la peça del marc" - -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "L'estil del marc ja té una peça a posició %s" - -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "No s'ha definit cap <draw_ops> amb el nom «%s»" - -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Funció «%s» desconeguda per al botó" - -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "" -"La funció de botó «%s» no existeix en aquesta versió (%d, es necessita %d)" - -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Estat «%s» desconegut per al botó" - -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "L'estil del marc ja té un botó per a l'estat %s de la funció %s" - -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "«%s» no és un valor vàlid per a l'atribut del focus" - -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "«%s» no és un valor vàlid per a l'atribut de l'estat" - -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "No s'ha definit un estil amb el nom «%s»" - -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "«%s» no és un valor vàlid per a l'atribut de redimensiona" - -#: ../src/ui/theme-parser.c:3147 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" -"No hauria de tenir l'atribut «resize» en l'element <%s> per als estats " -"maximitzat/ombrejat" - -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "" -"No hauria de tenir l'atribut «resize» en l'element <%s> per als estats " -"maximitzats" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Force Quit" +msgstr "_Força'n la sortida" -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "L'estil ja s'ha especificat per a l'estat %s redimensiona %s focus %s" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Wait" +msgstr "_Espera" -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 +#: src/core/mutter.c:38 #, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "L'estil ja s'ha especificat per a l'estat %s focus %s" - -#: ../src/ui/theme-parser.c:3294 msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" msgstr "" -"No es poden tenir dos draw_ops per a un element <piece> (el tema ha " -"especificat un atribut draw_ops i també un element <draw_ops>, o ha " -"especificat ambdós elements) " +"Mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., i d'altres\n" +"Això és programari lliure; vegeu els fitxers de codi font per conèixer-ne\n" +"les condicions de còpia.\n" +"No hi ha CAP garantia; ni tan sols la garantia implícita de COMERCIABILITAT\n" +"o ADEQUACIÓ A PER UN PROPÒSIT PARTICULAR.\n" -#: ../src/ui/theme-parser.c:3332 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"No es poden tenir dos draw_ops per a un element <button> (el tema ha " -"especificat un atribut draw_ops i també un element <draw_ops>, o ha " -"especificat ambdós elements)" +#: src/core/mutter.c:52 +msgid "Print version" +msgstr "Escriu versió" -#: ../src/ui/theme-parser.c:3370 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"No es poden tenir dos draw_ops per a un element <menu_icon> (el tema ha " -"especificat un atribut draw_ops i també un element <draw_ops>, o ha " -"especificat ambdós elements)" +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "Connector del Mutter a utilitzar" -#: ../src/ui/theme-parser.c:3434 +#: src/core/prefs.c:1849 #, c-format -msgid "Bad version specification '%s'" -msgstr "Especificació de versió errònia («%s»)" - -#: ../src/ui/theme-parser.c:3507 -msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" -msgstr "" -"L'atribut «version» no es pot utilitzat als fitxers metacity-theme-1.xml o " -"metacity-theme-2.xml" +msgid "Workspace %d" +msgstr "Espai de treball %d" -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "" -"El tema requereix la versió %s, però la darrera versió compatible del tema " -"és la %d.%d" +#: src/core/util.c:121 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter es va compilar sense compatibilitat per al mode detallat\n" -#: ../src/ui/theme-parser.c:3562 +#: src/wayland/meta-wayland-tablet-pad.c:567 #, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "L'element més extern en el tema ha de ser <metacity_theme>, no <%s>" +msgid "Mode Switch: Mode %d" +msgstr "Mode de commutació: mode %d" -#: ../src/ui/theme-parser.c:3582 +#: src/x11/meta-x11-display.c:671 #, c-format msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." msgstr "" -"L'element <%s> no és permès dins d'un element name/author/date/description" +"La pantalla «%s» ja té un gestor de finestres; proveu l'opció --replace per " +"reemplaçar el gestor de finestres actual." -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "L'element <%s> no és permès dins d'un element <constant>" +#: src/x11/meta-x11-display.c:1032 +msgid "Failed to initialize GDK\n" +msgstr "S'ha produït un error en inicialitzar GDK\n" -#: ../src/ui/theme-parser.c:3599 +#: src/x11/meta-x11-display.c:1056 #, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" +msgid "Failed to open X Window System display “%s”\n" msgstr "" -"L'element <%s> no és permès dins d'un element distance/border/aspect_ratio" - -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "L'element <%s> no és permès dins d'un element d'operació igual" - -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "L'element <%s> no és permès dins d'un element <%s>" - -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "No s'ha proveït cap draw_ops per a la peça del marc" - -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "No s'ha proveït cap draw_ops per al botó" - -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "No es permet cap text dins de l'element <%s>" - -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "S'ha especificat <%s> dues vegades per a aquest tema" - -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "No s'ha trobat un fitxer vàlid per al tema %s\n" - -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "_Finestres" - -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "_Diàleg" - -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "Diàleg _modal" - -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "_Eina" - -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "_Pantalla flaix" - -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "Acoblador _superior" - -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "Acoblador _inferior" - -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "Acoblador es_querre" - -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "Acoblador d_ret" - -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "_Tots els acobladors" - -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "Escr_iptori" - -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "Obre una altra d'aquestes finestres" - -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "Aquest és un botó de prova amb una icona «obre»" - -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "Aquest és un botó de prova amb una icona de «surt»" - -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "Aquest és un exemple de missatge en un diàleg d'exemple" - -#: ../src/ui/theme-viewer.c:328 -#, c-format -msgid "Fake menu item %d\n" -msgstr "Element fals de menú %d\n" - -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "Finestra amb només contorn" - -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "Barra" - -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "Finestra d'aplicació normal" - -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "Caixa de diàleg" - -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "Caixa de diàleg modal" - -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "Paleta d'utilitat" - -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "Menú arrossegable" - -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "Contorn" - -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "Diàleg modal adjuntat" - -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "Prova de disposició de botons %d" - -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g mil·lisegons per dibuixar un marc de finestra" - -#: ../src/ui/theme-viewer.c:813 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Forma d'ús: metacity-theme-viewer [NOMDELTEMA]\n" +"S'ha produït un error en obrir la pantalla del sistema de finestres X «%s»\n" -#: ../src/ui/theme-viewer.c:820 +#: src/x11/meta-x11-display.c:1140 #, c-format -msgid "Error loading theme: %s\n" -msgstr "S'ha produït un error en carregar el tema: %s\n" +msgid "Screen %d on display “%s” is invalid\n" +msgstr "El monitor %d en la pantalla «%s»' no és vàlida\n" -#: ../src/ui/theme-viewer.c:826 +#: src/x11/meta-x11-selection-input-stream.c:445 #, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "S'ha carregat el tema «%s» en %g segons\n" - -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "Tipus de lletra per a títol normal" - -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "Tipus de lletra per a títol petit" - -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "Tipus de lletra per a títol gran" +msgid "Format %s not supported" +msgstr "El format %s no és compatible" -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "Disposicions de botons" - -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "Test de referència" - -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "El títol de la finestra va aquí" - -#: ../src/ui/theme-viewer.c:1047 -#, c-format +#: src/x11/session.c:1821 msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"S'han dibuixat %d marcs en %g segons del client (%g mil·lisegons per marc) i " -"%g segons de rellotge inclosos els recursos del servidor d'X (%g " -"mil·lisegons per marc)\n" - -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "La prova d'expressió de posició ha tornat TRUE però ha establert error" - -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." msgstr "" -"La prova d'expressió de posició ha tornat FALSE però no ha establert error" - -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "S'esperava un error però no s'ha donat cap" - -#: ../src/ui/theme-viewer.c:1274 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "S'esperava l'error %d però s'ha donat %d" - -#: ../src/ui/theme-viewer.c:1280 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "No s'esperava cap error però s'ha tornat un: %s" - -#: ../src/ui/theme-viewer.c:1284 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "El valor x ha sigut %d, i s'esperava %d" - -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "El valor y ha sigut %d, i s'esperava %d" +"Aquestes finestres no implementen «desa la configuració actual» i s'hauran " +"de reiniciar manualment la pròxima vegada que entreu." -#: ../src/ui/theme-viewer.c:1352 +#: src/x11/window-props.c:569 #, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "" -"%d expressions de coordenades analitzades en %g segons (%g segons de mitja)\n" - -#~ msgid "Close Window" -#~ msgstr "Tanca la finestra" - -#~ msgid "Window Menu" -#~ msgstr "Menú de la finestra" - -#~ msgid "Minimize Window" -#~ msgstr "Minimitza la finestra" - -#~ msgid "Maximize Window" -#~ msgstr "Maximitza la finestra" - -#~ msgid "Restore Window" -#~ msgstr "Restaura la finestra" - -#~ msgid "Roll Up Window" -#~ msgstr "Enrotlla la finestra" - -#~ msgid "Unroll Window" -#~ msgstr "Desenrotlla la finestra" - -#~ msgid "Keep Window On Top" -#~ msgstr "Mantén la finestra per damunt" - -#~ msgid "Remove Window From Top" -#~ msgstr "Treu la finestra de damunt" - -#~ msgid "Always On Visible Workspace" -#~ msgstr "Sempre a l'espai de treball visible" - -#~ msgid "Put Window On Only One Workspace" -#~ msgstr "Posa la finestra només a un espai de treball" - -#~ msgid "Switch to workspace 1" -#~ msgstr "Canvia a l'espai de treball 1" - -#~ msgid "Switch to workspace 2" -#~ msgstr "Canvia a l'espai de treball 2" - -#~ msgid "Switch to workspace 3" -#~ msgstr "Canvia a l'espai de treball 3" - -#~ msgid "Switch to workspace 4" -#~ msgstr "Canvia a l'espai de treball 4" - -#~ msgid "Switch to workspace 5" -#~ msgstr "Canvia a l'espai de treball 5" - -#~ msgid "Switch to workspace 6" -#~ msgstr "Canvia a l'espai de treball 6" - -#~ msgid "Switch to workspace 7" -#~ msgstr "Canvia a l'espai de treball 7" - -#~ msgid "Switch to workspace 8" -#~ msgstr "Canvia a l'espai de treball 8" - -#~ msgid "Switch to workspace 9" -#~ msgstr "Canvia a l'espai de treball 9" - -#~ msgid "Switch to workspace 10" -#~ msgstr "Canvia a l'espai de treball 10" - -#~ msgid "Switch to workspace 11" -#~ msgstr "Canvia a l'espai de treball 11" - -#~ msgid "Switch to workspace 12" -#~ msgstr "Canvia a l'espai de treball 12" - -#~ msgid "Switch to workspace on the left of the current workspace" -#~ msgstr "Canvia a l'espai de treball de l'esquerra de l'actual" - -#~ msgid "Switch to workspace on the right of the current workspace" -#~ msgstr "Canvia a l'espai de treball a la dreta de l'actual" - -#~ msgid "Switch to workspace above the current workspace" -#~ msgstr "Canvia a l'espai de treball damunt de l'actual" - -#~ msgid "Switch to workspace below the current workspace" -#~ msgstr "Canvia a l'espai de treball a sota de l'actual" - -#~ msgid "Move between windows of an application, using a popup window" -#~ msgstr "Mou-te entre finestres d'una aplicació amb un diàleg emergent" - -#~ msgid "" -#~ "Move backward between windows of an application, using a popup window" -#~ msgstr "" -#~ "Mou-te cap enrere entre finestres d'una aplicació amb un diàleg emergent" - -#~ msgid "Move between windows, using a popup window" -#~ msgstr "Mou-te entre finestres amb un diàleg emergent" - -#~ msgid "Move backward between windows, using a popup window" -#~ msgstr "Mou-te cap enrere entre finestres amb un diàleg emergent" - -#~ msgid "Move between panels and the desktop, using a popup window" -#~ msgstr "Mou-te entre quadres i l'escriptori amb un diàleg emergent" - -#~ msgid "Move backward between panels and the desktop, using a popup window" -#~ msgstr "" -#~ "Mou-te cap enrere entre quadres i l'escriptori amb un diàleg emergent" - -#~ msgid "Move between windows of an application immediately" -#~ msgstr "Mou-te entre les finestres d'una aplicació immediatament" - -#~ msgid "Move backward between windows of an application immediately" -#~ msgstr "Mou-te cap enrere entre les finestres d'una aplicació immediatament" - -#~ msgid "Move between windows immediately" -#~ msgstr "Mou-te entre finestres immediatament" - -#~ msgid "Move backward between windows immediately" -#~ msgstr "Mou-te cap enrere entre finestres immediatament" - -#~ msgid "Move between panels and the desktop immediately" -#~ msgstr "Mou entre quadres i l'escriptori immediatament" - -#~ msgid "Move backward between panels and the desktop immediately" -#~ msgstr "Mou cap enrere entre quadres i l'escriptori immediatament" - -#~ msgid "Hide all normal windows and set focus to the desktop" -#~ msgstr "Oculta totes les finestres normals i dóna el focus a l'escriptori" - -#~ msgid "Show the panel's main menu" -#~ msgstr "Mostra el menú principal del quadre" - -#~ msgid "Show the panel's \"Run Application\" dialog box" -#~ msgstr "Mostra el diàleg d'execució d'aplicacions del quadre" - -#~ msgid "Start or stop recording the session" -#~ msgstr "Inicia o atura l'enregistrament de la sessió" - -#~ msgid "Take a screenshot" -#~ msgstr "Fes una captura de pantalla" - -#~ msgid "Take a screenshot of a window" -#~ msgstr "Fes una captura de pantalla d'una finestra" - -#~ msgid "Run a terminal" -#~ msgstr "Executa un terminal" - -#~ msgid "Activate the window menu" -#~ msgstr "Activa el menú de finestra" - -#~ msgid "Toggle fullscreen mode" -#~ msgstr "Si s'utilitza el mode a pantalla completa" - -#~ msgid "Toggle maximization state" -#~ msgstr "Canvia l'estat de maximització" - -#~ msgid "Toggle whether a window will always be visible over other windows" -#~ msgstr "" -#~ "Commuta la funció que fa que una finestra sempre serà visible per sobre " -#~ "de les altres" - -#~ msgid "Maximize window" -#~ msgstr "Maximitza la finestra" - -#~ msgid "Restore window" -#~ msgstr "Restaura la finestra" - -#~ msgid "Toggle shaded state" -#~ msgstr "Canvia l'estat d'ombrejat" - -#~ msgid "Minimize window" -#~ msgstr "Minimitza la finestra" - -#~ msgid "Close window" -#~ msgstr "Tanca la finestra" - -#~ msgid "Move window" -#~ msgstr "Mou la finestra" - -#~ msgid "Resize window" -#~ msgstr "Redimensiona la finestra" - -#~ msgid "Toggle whether window is on all workspaces or just one" -#~ msgstr "" -#~ "Commuta la funció que fa que la finestra estigui en tots els espais de " -#~ "treball o només en un" - -#~ msgid "Move window to workspace 1" -#~ msgstr "Mou la finestra a l'espai de treball 1" - -#~ msgid "Move window to workspace 2" -#~ msgstr "Mou la finestra a l'espai de treball 2" - -#~ msgid "Move window to workspace 3" -#~ msgstr "Mou la finestra a l'espai de treball 3" - -#~ msgid "Move window to workspace 4" -#~ msgstr "Mou la finestra a l'espai de treball 4" - -#~ msgid "Move window to workspace 5" -#~ msgstr "Mou la finestra a l'espai de treball 5" - -#~ msgid "Move window to workspace 6" -#~ msgstr "Mou la finestra a l'espai de treball 6" - -#~ msgid "Move window to workspace 7" -#~ msgstr "Mou la finestra a l'espai de treball 7" - -#~ msgid "Move window to workspace 8" -#~ msgstr "Mou la finestra a l'espai de treball 8" - -#~ msgid "Move window to workspace 9" -#~ msgstr "Mou la finestra a l'espai de treball 9" - -#~ msgid "Move window to workspace 10" -#~ msgstr "Mou la finestra a l'espai de treball 10" - -#~ msgid "Move window to workspace 11" -#~ msgstr "Mou la finestra a l'espai de treball 11" - -#~ msgid "Move window to workspace 12" -#~ msgstr "Mou la finestra a l'espai de treball 12" - -#~ msgid "Move window one workspace to the left" -#~ msgstr "Mou la finestra un espai de treball a l'esquerra" - -#~ msgid "Move window one workspace to the right" -#~ msgstr "Mou la finestra un espai de treball a la dreta" - -#~ msgid "Move window one workspace up" -#~ msgstr "Mou la finestra un espai de treball amunt" - -#~ msgid "Move window one workspace down" -#~ msgstr "Mou la finestra un espai de treball avall" - -#~ msgid "Raise window if it's covered by another window, otherwise lower it" -#~ msgstr "Alça una finestra coberta per una altra, o sinó la baixa" - -#~ msgid "Raise window above other windows" -#~ msgstr "Alça una finestra per damunt de les altres" - -#~ msgid "Lower window below other windows" -#~ msgstr "Baixa la finestra sota les altres" - -#~ msgid "Maximize window vertically" -#~ msgstr "Maximitza la finestra verticalment" - -#~ msgid "Maximize window horizontally" -#~ msgstr "Maximitza la finestra horitzontalment" - -#~ msgid "Move window to north-west (top left) corner" -#~ msgstr "Mou la finestra a la cantonada nord-oest (part superior esquerra)" - -#~ msgid "Move window to north-east (top right) corner" -#~ msgstr "Mou la finestra a la cantonada nord-est (part superior dreta)" - -#~ msgid "Move window to south-west (bottom left) corner" -#~ msgstr "Mou la finestra a la cantonada sud-oest (part inferior esquerra)" - -#~ msgid "Move window to south-east (bottom right) corner" -#~ msgstr "Mou la finestra a la cantonada sud-est (part inferior dreta)" - -#~ msgid "Move window to north (top) side of screen" -#~ msgstr "Mou la finestra a la part nord (superior) de la pantalla" - -#~ msgid "Move window to south (bottom) side of screen" -#~ msgstr "Mou la finestra a la part del sud (inferior) de la pantalla" - -#~ msgid "Move window to east (right) side of screen" -#~ msgstr "Mou la finestra a la part est (dreta) de la pantalla" - -#~ msgid "Move window to west (left) side of screen" -#~ msgstr "Mou la finestra a la part oest (esquerra) de la pantalla" - -#~ msgid "Move window to center of screen" -#~ msgstr "Mou la finestra al centre de la pantalla" - -#~ msgid "" -#~ "There was an error running <tt>%s</tt>:\n" -#~ "\n" -#~ "%s" -#~ msgstr "" -#~ "S'ha produït un error en executar <tt>%s</tt>:\n" -#~ "\n" -#~ "%s." - -#~ msgid "No command %d has been defined.\n" -#~ msgstr "No s'ha definit cap ordre %d.\n" - -#~ msgid "No terminal command has been defined.\n" -#~ msgstr "No s'ha definit cap ordre de terminal.\n" - -#~ msgid "GConf key '%s' is set to an invalid value\n" -#~ msgstr "La clau «%s» del GConf està establerta a un valor no vàlid\n" - -#~ msgid "%d stored in GConf key %s is out of range %d to %d\n" -#~ msgstr "" -#~ "%d, emmagatzemat a la clau %s del GConf, està fora de l'interval de %d a " -#~ "%d\n" - -#~ msgid "GConf key \"%s\" is set to an invalid type\n" -#~ msgstr "La clau «%s» del GConf està establerta a un tipus no vàlid\n" - -#~ msgid "GConf key %s is already in use and can't be used to override %s\n" -#~ msgstr "" -#~ "La clau %s del GConf ja s'està utilitzant i no es pot fer servir per " -#~ "sobreescriure %s\n" - -#~ msgid "Can't override GConf key, %s not found\n" -#~ msgstr "No es pot sobreescriure la clau del GConf; no s'ha trobat %s\n" - -#~ msgid "Error setting number of workspaces to %d: %s\n" -#~ msgstr "" -#~ "S'ha produït un error en establir el nombre d'espais de treball a %d: %s\n" +msgid "%s (on %s)" +msgstr "%s (a %s)" -#~ msgid "Error setting name for workspace %d to \"%s\": %s\n" -#~ msgstr "" -#~ "S'ha produït un error en establir el nom de l'espai de treball %d a «%s»: " -#~ "%s\n" - -#~ msgid "Error setting live hidden windows status status: %s\n" -#~ msgstr "" -#~ "S'ha produït un error en establir l'estat de les finestres ocultes en " -#~ "viu: %s\n" - -#~ msgid "Error setting no tab popup status: %s\n" -#~ msgstr "" -#~ "S'ha produït un error en establir l'estat de les pestanyes sense finestra " -#~ "emergent: %s\n" - -#~ msgid "" -#~ "Don't make fullscreen windows that are maximized and have no decorations" -#~ msgstr "" -#~ "No creïs finestres a pantalla completa que estiguin maximitzades i no " -#~ "tinguin decoracions" - -#~ msgid "Whether window popup/frame should be shown when cycling windows." -#~ msgstr "" -#~ "Si s'hauria de mostrar una finestra emergent o el seu marc en canviar en " -#~ "cicle entre finestres" - -#~ msgid "Internal argument for GObject introspection" -#~ msgstr "Argument intern per a la introspecció basada en el GObject" - -#~ msgid "Failed to restart: %s\n" -#~ msgstr "No s'ha pogut reiniciar: %s\n" - -#~ msgid "Error setting clutter plugin list: %s\n" -#~ msgstr "" -#~ "S'ha produït un error en establir la llista de connectors del Clutter: " -#~ "%s\n" - -#~ msgid "Clutter Plugins" -#~ msgstr "Connectors del Clutter" - -#~ msgid "Plugins to load for the Clutter-based compositing manager." -#~ msgstr "" -#~ "Connectors que s'han de carregar per al gestor de composició basat en el " -#~ "Clutter." - -#~ msgid "Window Management" -#~ msgstr "Gestor de finestres" - -#~ msgid "Failed to parse message \"%s\" from dialog process\n" -#~ msgstr "No s'ha pogut analitzar el missatge «%s» des del procés de diàleg\n" - -#~ msgid "Error reading from dialog display process: %s\n" -#~ msgstr "" -#~ "S'ha produït un error en llegir del procés de la pantalla de diàleg: %s\n" - -#~ msgid "" -#~ "Error launching metacity-dialog to ask about killing an application: %s\n" -#~ msgstr "" -#~ "S'ha produït un error en executar el diàleg metacity per preguntar quant " -#~ "a la \n" -#~ "finalització d'una aplicació: %s\n" - -#~ msgid "Failed to get hostname: %s\n" -#~ msgstr "" -#~ "S'ha produït un error en obtenir el nom de l'ordinador central: %s\n" - -#~ msgid "" -#~ "Lost connection to the display '%s';\n" -#~ "most likely the X server was shut down or you killed/destroyed\n" -#~ "the window manager.\n" -#~ msgstr "" -#~ "S'ha perdut la connexió amb la pantalla «%s»;\n" -#~ "és molt probable que el servidor X s'hagi aturat o que hagueu " -#~ "finalitzat/\n" -#~ "destruït el gestor de finestres.\n" - -#~ msgid "Fatal IO error %d (%s) on display '%s'.\n" -#~ msgstr "S'ha produït un error fatal d'E/S %d (%s) a la pantalla «%s».\n" - -#~ msgid "Turn compositing on" -#~ msgstr "Habilita la composició" - -#~ msgid "Turn compositing off" -#~ msgstr "Inhabilita la composició" - -#~ msgid "" -#~ "The format looks like \"<Control>a\" or <Shift><Alt>F1\".\n" -#~ "\n" -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "El format és «<Control>a» o «<Shift><Alt>F1».\n" -#~ "\n" -#~ "L'analitzador és prou flexible i permet minúscules i majúscules, i també " -#~ "abreviacions com «<Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena " -#~ "especial «disabled» (inhabilitat), no hi haurà cap vinculació per a " -#~ "aquesta acció." - -#~ msgid "" -#~ "The format looks like \"<Control>a\" or <Shift><Alt>F1\".\n" -#~ "\n" -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action.\n" -#~ "\n" -#~ "This keybinding may be reversed by holding down the \"shift\" key; " -#~ "therefore, \"shift\" cannot be one of the keys it uses." -#~ msgstr "" -#~ "El format és «<Control>a» o «<Shift><Alt>F1».\n" -#~ "\n" -#~ "L'analitzador és prou flexible i permet minúscules i majúscules, i també " -#~ "abreviacions com «<Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena " -#~ "especial «disabled», no hi haurà cap vinculació per a aquesta acció.\n" -#~ "\n" -#~ "Aquesta vinculació es pot invertir en prémer la tecla «Shift»; de manera " -#~ "que no es podrà utilitzar la tecla «Shift»." - -#~ msgid "Failed to read saved session file %s: %s\n" -#~ msgstr "No s'ha pogut llegir el fitxer de sessió «%s» desat: %s\n" - -#~ msgid "" -#~ "Error launching metacity-dialog to warn about apps that don't support " -#~ "session management: %s\n" -#~ msgstr "" -#~ "S'ha produït un error en executar el metacity-dialog per a avisar sobre " -#~ "aplicacions que no suporten la gestió de sessions: %s\n" - -#~ msgid "Metacity" -#~ msgstr "Metacity" - -#~ msgid "" -#~ "(Not implemented) Navigation works in terms of applications not windows" -#~ msgstr "" -#~ "(No implementat) La navegació funciona en termes d'aplicacions, no " -#~ "finestres" - -#~ msgid "" -#~ "A font description string describing a font for window titlebars. The " -#~ "size from the description will only be used if the titlebar_font_size " -#~ "option is set to 0. Also, this option is disabled if the " -#~ "titlebar_uses_desktop_font option is set to true." -#~ msgstr "" -#~ "Una cadena de descripció de tipus de lletra per a les barres de títol de " -#~ "les finestres. La mida de la descripció només s'utilitzarà si l'opció " -#~ "titlebar_font_size està establerta a 0. A més a més, aquesta opció està " -#~ "inhabilitada si titlebar_uses_desktop_font està establert és cert." - -#~ msgid "Action on title bar double-click" -#~ msgstr "Acció en fer doble clic en la barra de títol" - -#~ msgid "Action on title bar middle-click" -#~ msgstr "Acció en fer clic amb el botó del mig en la barra de títol" - -#~ msgid "Action on title bar right-click" -#~ msgstr "Acció en fer clic amb el botó secundari en la barra de títol" - -#~ msgid "Arrangement of buttons on the titlebar" -#~ msgstr "Emplaçament dels botons en la barra de títol" - -#~ msgid "" -#~ "Arrangement of buttons on the titlebar. The value should be a string, " -#~ "such as \"menu:minimize,maximize,spacer,close\"; the colon separates the " -#~ "left corner of the window from the right corner, and the button names are " -#~ "comma-separated. Duplicate buttons are not allowed. Unknown button names " -#~ "are silently ignored so that buttons can be added in future metacity " -#~ "versions without breaking older versions. A special spacer tag can be " -#~ "used to insert some space between two adjacent buttons." -#~ msgstr "" -#~ "La disposició dels botons a la barra del títol. El valor ha de ser una " -#~ "cadena, com ara «menu:minimize,maximize,spacer,close»; els dos punts " -#~ "separen la cantonada esquerra de la finestra de la dreta, i els noms dels " -#~ "botons se separen amb comes. No es permeten botons duplicats. Els botons " -#~ "desconeguts es descartaran sense cap notificació, de manera que es puguin " -#~ "afegir botons en futures versions del Metacity sense trencar les versions " -#~ "antigues. Es pot afegir una etiqueta especial d'espaiament («spacer») per " -#~ "a insertar una determinada quantitat d'espai entre dos botons adjacents." - -#~ msgid "Automatically raises the focused window" -#~ msgstr "Alça automàticament la finestra amb el focus" - -#~ msgid "" -#~ "Clicking a window while holding down this modifier key will move the " -#~ "window (left click), resize the window (middle click), or show the window " -#~ "menu (right click). The left and right operations may be swapped using " -#~ "the \"mouse_button_resize\" key. Modifier is expressed as \"<Alt>\" " -#~ "or \"<Super>\" for example." -#~ msgstr "" -#~ "Si es fa clic en una finestra mentre es manté aquesta tecla modificadora " -#~ "premuda, es mourà la finestra (botó esquerre), redimensionarà la finestra " -#~ "(botó central) o mostrarà el menú de la finestra (botó dret). Les " -#~ "operacions de la dreta i de l'esquerra es poden intercanviar amb la clau " -#~ "«mouse_button_resize». El modificador s'expressa com a «<Alt;>» o " -#~ "com a «<Super>», per exemple." - -#~ msgid "Commands to run in response to keybindings" -#~ msgstr "Ordres a executar en resposta a vinculacions de tecles" - -#~ msgid "Compositing Manager" -#~ msgstr "Gestor de composició" - -#~ msgid "Control how new windows get focus" -#~ msgstr "Controla de quina manera les finestres noves reben el focus" - -#~ msgid "Current theme" -#~ msgstr "Tema actual" - -#~ msgid "Delay in milliseconds for the auto raise option" -#~ msgstr "Retard en mil·lisegons per a l'opció d'alçat automàtic" - -#~ msgid "Determines whether Metacity is a compositing manager." -#~ msgstr "Determina si el Metacity és un gestor de composició." - -#~ msgid "" -#~ "Determines whether applications or the system can generate audible " -#~ "'beeps'; may be used in conjunction with 'visual bell' to allow silent " -#~ "'beeps'." -#~ msgstr "" -#~ "Determina si les aplicacions o el sistema poden generar «sons» audibles; " -#~ "es pot utilitzar en conjunció amb «visual bell» per a permetre «sons» " -#~ "silenciosos." - -#~ msgid "Disable misfeatures that are required by old or broken applications" -#~ msgstr "" -#~ "Inhabilita funcionalitats que són requerides per aplicacions velles o amb " -#~ "errors" - -#~ msgid "Enable Visual Bell" -#~ msgstr "Habilita la campana visual" - -#~ msgid "" -#~ "If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " -#~ "the focused window will be automatically raised after a delay specified " -#~ "by the auto_raise_delay key. This is not related to clicking on a window " -#~ "to raise it, nor to entering a window during drag-and-drop." -#~ msgstr "" -#~ "Si és cert, i el mode del focus és «sloppy» o «mouse», aleshores la " -#~ "finestra amb el focus s'alçarà automàticament després d'un retard, que " -#~ "s'especifica a la clau auto_raise_delay. Això no està relacionat en " -#~ "l'acció de fer clic a una finestra per a alçar-la, ni tampoc en entrar en " -#~ "una finestra en arrossegar i deixar anar." - -#~ msgid "" -#~ "If true, ignore the titlebar_font option, and use the standard " -#~ "application font for window titles." -#~ msgstr "" -#~ "Si és veritat, ignora l'opció titlebar_font i utilitza el tipus de lletra " -#~ "de les aplicacions estàndard per als títols de les finestres." - -#~ msgid "" -#~ "If true, metacity will give the user less feedback by using wireframes, " -#~ "avoiding animations, or other means. This is a significant reduction in " -#~ "usability for many users, but may allow legacy applications to continue " -#~ "working, and may also be a useful tradeoff for terminal servers. However, " -#~ "the wireframe feature is disabled when accessibility is on." -#~ msgstr "" -#~ "Sí és cert, el metacity donarà a l'usuari menys informació utilitzant " -#~ "marcs amb fils, evitant les animacions o altres mitjans. Això implica una " -#~ "reducció significativa en usabilitat per a molts usuaris, però pot " -#~ "permetre a algunes aplicacions velles i servidors de terminal. No " -#~ "obstant, la funcionalitat dels marcs amb fils es desactiva quan " -#~ "l'accessibilitat està habilitada." - -#~ msgid "" -#~ "If true, then Metacity works in terms of applications rather than " -#~ "windows. The concept is a bit abstract, but in general an application-" -#~ "based setup is more like the Mac and less like Windows. When you focus a " -#~ "window in application-based mode, all the windows in the application will " -#~ "be raised. Also, in application-based mode, focus clicks are not passed " -#~ "through to windows in other applications. Application-based mode is, " -#~ "however, largely unimplemented at the moment." -#~ msgstr "" -#~ "Si és cert, el Metacity treballarà en termes d'aplicacions, en comptes de " -#~ "finestres. El concepte és una mica abstracte, però en general, una " -#~ "configuració basada en aplicacions és més semblant als Mac i menys com el " -#~ "Windows. Quan teniu el focus en una finestra en el mode basat en " -#~ "aplicacions, totes les finestres en l'aplicació s'alçaran. A més a més, " -#~ "en el mode basat en aplicacions, els clics de focus no es passen a les " -#~ "finestres d'altres aplicacions. Tanmateix, el mode basat en aplicacions " -#~ "encara no està massa implementat." - -#~ msgid "If true, trade off usability for less resource usage" -#~ msgstr "Si és vertader, sacrifica usabilitat per usar menys recursos" - -#~ msgid "Name of workspace" -#~ msgstr "Nom de l'espai de treball" - -#~ msgid "Number of workspaces" -#~ msgstr "Número d'espais de treball" - -#~ msgid "" -#~ "Number of workspaces. Must be more than zero, and has a fixed maximum to " -#~ "prevent making the desktop unusable by accidentally asking for too many " -#~ "workspaces." -#~ msgstr "" -#~ "El nombre d'espais de treball. Ha de ser més gran que zero, i té un màxim " -#~ "fixe per a prevenir la destrucció accidental del vostre escriptori si " -#~ "demaneu massa espais de treball." - -#~ msgid "Run a defined command" -#~ msgstr "Executa una ordre definida" - -#~ msgid "" -#~ "Set this to true to resize with the right button and show a menu with the " -#~ "middle button while holding down the key given in \"mouse_button_modifier" -#~ "\"; set it to false to make it work the opposite way around." -#~ msgstr "" -#~ "Establiu-lo a «true» (cert) per a canviar la mida amb el botó secundari i " -#~ "mostrar un menú amb el botó central mentre es premi la tecla especificada " -#~ "al paràmetre «mouse_button_modifier». Establiu-lo a «false» (fals) perquè " -#~ "funcioni a l'inversa." - -#~ msgid "" -#~ "Setting this option to false can lead to buggy behavior, so users are " -#~ "strongly discouraged from changing it from the default of true. Many " -#~ "actions (e.g. clicking in the client area, moving or resizing the window) " -#~ "normally raise the window as a side-effect. Setting this option to false, " -#~ "which is strongly discouraged, will decouple raising from other user " -#~ "actions, and ignore raise requests generated by applications. See http://" -#~ "bugzilla.gnome.org/show_bug.cgi?id=445447#c6. Even when this option is " -#~ "false, windows can still be raised by an alt-left-click anywhere on the " -#~ "window, a normal click on the window decorations, or by special messages " -#~ "from pagers, such as activation requests from tasklist applets. This " -#~ "option is currently disabled in click-to-focus mode. Note that the list " -#~ "of ways to raise windows when raise_on_click is false does not include " -#~ "programmatic requests from applications to raise windows; such requests " -#~ "will be ignored regardless of the reason for the request. If you are an " -#~ "application developer and have a user complaining that your application " -#~ "does not work with this setting disabled, tell them it is _their_ fault " -#~ "for breaking their window manager and that they need to change this " -#~ "option back to true or live with the \"bug\" they requested." -#~ msgstr "" -#~ "Si establiu aquesta opció a «false» (fals) es pot produir un comportament " -#~ "incorrecte, de manera que s'aconsella als usuaris que no canviïn el seu " -#~ "valor predeterminat: «true» (cert). Moltes accions (p.ex. fer clic a " -#~ "l'àrea del client, moure o canviar la mida de la finestra) normalment " -#~ "alcen la finestra com a efecte secundari. Si establiu aquesta opció a " -#~ "fals -cosa molt poc recomanable- se separarà l'alçament de la finestra " -#~ "d'altres accions de l'usuari i s'ignoraran les sol·licituds d'alçament " -#~ "que generin les aplicacions. Vegeu l'informe d'error http://bugzilla." -#~ "gnome.org/show_bug.cgi?id=445447#c6. Fins i tot quan aquesta opció sigui " -#~ "falsa, encara es poden alçar les finestres amb alt-clic-esquerra en " -#~ "qualsevol lloc de la finestra, amb un clic a les decoracions de la " -#~ "finestra, o amb un missatge especial dels paginadors, com ara " -#~ "sol·licituds d'activació des de les miniaplicacions de la llista de " -#~ "finestres. Aquesta opció està inhabilitada en el mode d'alçar les " -#~ "finestres amb clic. Fixeu-vos que les diverses maneres d'alçar les " -#~ "finestres quan «raise_on_click» és fals no inclouen les peticions " -#~ "programades de les aplicacions per a alçar finestres; aquestes peticions " -#~ "s'ignoraran sigui quin sigui el motiu. Si desenvolupeu aplicacions i un " -#~ "usuari es queixa que l'aplicació no funciona quan aquest paràmetre està " -#~ "inhabilitat, digueu-li que es culpa _seva_ per haver trencat el gestor de " -#~ "finestres, i que ha de tornar a canviar aquesta opció a «true» o conviure " -#~ "amb l'error." - -#~ msgid "" -#~ "Some applications disregard specifications in ways that result in window " -#~ "manager misfeatures. This option puts Metacity in a rigorously correct " -#~ "mode, which gives a more consistent user interface, provided one does not " -#~ "need to run any misbehaving applications." -#~ msgstr "" -#~ "Algunes aplicacions no fan cas de les especificacions que poden fer que " -#~ "el gestor de finestri no respongui correctament. Aquesta opció fa que el " -#~ "Metaciti es posi en un mode rogorosament correcte, que proporciona una " -#~ "interfície d'usuari més consistent, sempre que no s'hagin d'executar " -#~ "aplicacions que no actuin correctament." - -#~ msgid "System Bell is Audible" -#~ msgstr "La campana del sistema és audible" - -#~ msgid "" -#~ "Tells Metacity how to implement the visual indication that the system " -#~ "bell or another application 'bell' indicator has been rung. Currently " -#~ "there are two valid values, \"fullscreen\", which causes a fullscreen " -#~ "white-black flash, and \"frame_flash\" which causes the titlebar of the " -#~ "application which sent the bell signal to flash. If the application which " -#~ "sent the bell is unknown (as is usually the case for the default \"system " -#~ "beep\"), the currently focused window's titlebar is flashed." -#~ msgstr "" -#~ "Li diu al Metacity com implementar la indicació visual de que s'ha tocat " -#~ "la campana del sistema, o l'indicador de campana d'un altra aplicació. " -#~ "Actualment, hi ha dos valors vàlids, «fullscreen», que fa un flaix blanc " -#~ "i negre en tota la pantalla, i «frame_flash», que causa que la barra del " -#~ "títol de l'aplicació que ha enviat el senyal de campana faci un flaix. Si " -#~ "no se sap quina aplicació ha enviat el senyal de campana, com sol pasar " -#~ "per als «sons del sistema» per defecte, la barra del títol de la finestra " -#~ "que tingui el focus en aquell moment rep un flaix." - -#~ msgid "" -#~ "The /apps/metacity/global_keybindings/run_command_N keys define " -#~ "keybindings that correspond to these commands. Pressing the keybinding " -#~ "for run_command_N will execute command_N." -#~ msgstr "" -#~ "Les claus /apps/metacity/global_keybindings/run_command_N estableixen " -#~ "vinculacions de tecles que corresponen a aquestes ordres. Si es prem la " -#~ "vinculació per a run_command_N, s'executarà command_N." - -#~ msgid "" -#~ "The /apps/metacity/global_keybindings/run_command_screenshot key defines " -#~ "a keybinding which causes the command specified by this setting to be " -#~ "invoked." -#~ msgstr "" -#~ "La clau /apps/metacity/global_keybindings/run_command_screenshot " -#~ "estableix una vinculació de tecles que fa que s'invoqui l'ordre " -#~ "especificada en aquesta configuració." - -#~ msgid "" -#~ "The /apps/metacity/global_keybindings/run_command_window_screenshot key " -#~ "defines a keybinding which causes the command specified by this setting " -#~ "to be invoked." -#~ msgstr "" -#~ "La clau /apps/metacity/global_keybindings/run_command_window_screenshot " -#~ "estableix una vinculació de tecles que fa que s'invoqui l'ordre " -#~ "especificada en aquesta configuració." - -#~ msgid "" -#~ "The keybinding that runs the correspondingly-numbered command in /apps/" -#~ "metacity/keybinding_commands The format looks like \"<Control>a\" " -#~ "or \"<Shift><Alt>F1\". The parser is fairly liberal and " -#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" -#~ "\" and \"<Ctrl>\". If you set the option to the special string " -#~ "\"disabled\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles que executa l'ordre amb la numeració corresponent " -#~ "a /apps/metacity/keybinding_commands. El format és semblant a «<" -#~ "Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com ara " -#~ "«<Ctl>» o «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." - -#~ msgid "The name of a workspace." -#~ msgstr "El nom d'un espai de treball." - -#~ msgid "The screenshot command" -#~ msgstr "L'ordre de captura de pantalla" - -#~ msgid "" -#~ "The theme determines the appearance of window borders, titlebar, and so " -#~ "forth." -#~ msgstr "" -#~ "El tema determina l'aspecte dels contorns de les finestres, la barra del " -#~ "títol, etc..." - -#~ msgid "" -#~ "The time delay before raising a window if auto_raise is set to true. The " -#~ "delay is given in thousandths of a second." -#~ msgstr "" -#~ "El retard de temps abans d'alçar una finestra si auto_raise és establer a " -#~ "«true». El retard es dóna en mil·lèssimes de segon." - -#~ msgid "" -#~ "The window focus mode indicates how windows are activated. It has three " -#~ "possible values; \"click\" means windows must be clicked in order to " -#~ "focus them, \"sloppy\" means windows are focused when the mouse enters " -#~ "the window, and \"mouse\" means windows are focused when the mouse enters " -#~ "the window and unfocused when the mouse leaves the window." -#~ msgstr "" -#~ "El mode de focus de la finestra indica com s'activen les finestres. Té " -#~ "tres valors possibles; «click» vol dir que cal fer clic a les finestres " -#~ "per a donar-los el focus, «sloppy» vol dir que les finestres reben el " -#~ "focus quan el punter hi entra a dins, i «mouse» vol dir que les finestres " -#~ "s'enfoquen quan el punter hi entra a dins, i es desenfoquen quan el " -#~ "punter abandona la finestra." - -#~ msgid "The window screenshot command" -#~ msgstr "L'ordre de captura de finestra" - -#~ msgid "" -#~ "This option determines the effects of double-clicking on the title bar. " -#~ "Current valid options are 'toggle_shade', which will shade/unshade the " -#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " -#~ "will maximize/unmaximize the window in that direction only, 'minimize' " -#~ "which will minimize the window, 'shade' which will roll the window up, " -#~ "'menu' which will display the window menu, 'lower' which will put the " -#~ "window behind all the others, and 'none' which will not do anything." -#~ msgstr "" -#~ "Aquesta opció determina l'efecte de l'acció de doble clic a la barra de " -#~ "títol. Els valors permesos són «toggle_shade» (commuta l'estat de " -#~ "persiana), que commutarà l'estat d'ombrejat de la finestra, " -#~ "«toggle_maximize» (commuta la maximització), que en commutarà l'estat de " -#~ "maximització, «toggle_maximize_horizontally» (commuta la maximització " -#~ "horitzontal) i «toggle_maximize_vertically» (commuta la maximització " -#~ "vertical), que només commutaran l'estat de maximització en la direcció " -#~ "indicada, «minimize» (minimitza), que minimitzarà la finestra, " -#~ "«shade» (persiana), que enrotllarà la finestra cap amunt, «menu», que " -#~ "mostrarà el menú de la finestra, «lower» (abaixa), que situarà la " -#~ "finestra darrere de totes les altres, i «none» (res), que no farà res." - -#~ msgid "" -#~ "This option determines the effects of middle-clicking on the title bar. " -#~ "Current valid options are 'toggle_shade', which will shade/unshade the " -#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " -#~ "will maximize/unmaximize the window in that direction only, 'minimize' " -#~ "which will minimize the window, 'shade' which will roll the window up, " -#~ "'menu' which will display the window menu, 'lower' which will put the " -#~ "window behind all the others, and 'none' which will not do anything." -#~ msgstr "" -#~ "Aquesta opció determina l'efecte de l'acció de fer clic amb el botó del " -#~ "mig a la barra de títol. Els valors permesos són «toggle_shade» (commuta " -#~ "l'estat de persiana), que commutarà l'estat d'ombrejat de la finestra, " -#~ "«toggle_maximize» (commuta la maximització), que en commutarà l'estat de " -#~ "maximització, «toggle_maximize_horizontally» (commuta la maximització " -#~ "horitzontal) i «toggle_maximize_vertically» (commuta la maximització " -#~ "vertical), que només commutaran l'estat de maximització en la direcció " -#~ "indicada, «minimize» (minimitza), que minimitzarà la finestra, " -#~ "«shade» (persiana), que enrotllarà la finestra cap amunt, «menu», que " -#~ "mostrarà el menú de la finestra, «lower» (abaixa), que situarà la " -#~ "finestra darrere de totes les altres, i «none» (res), que no farà res." - -#~ msgid "" -#~ "This option determines the effects of right-clicking on the title bar. " -#~ "Current valid options are 'toggle_shade', which will shade/unshade the " -#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " -#~ "will maximize/unmaximize the window in that direction only, 'minimize' " -#~ "which will minimize the window, 'shade' which will roll the window up, " -#~ "'menu' which will display the window menu, 'lower' which will put the " -#~ "window behind all the others, and 'none' which will not do anything." -#~ msgstr "" -#~ "Aquesta opció determina l'efecte de l'acció de fer clic amb el botó " -#~ "secundari a la barra de títol. Els valors permesos són " -#~ "«toggle_shade» (commuta l'estat de persiana), que commutarà l'estat " -#~ "d'ombrejat de la finestra, «toggle_maximize» (commuta la maximització), " -#~ "que en commutarà l'estat de maximització, " -#~ "«toggle_maximize_horizontally» (commuta la maximització horitzontal) i " -#~ "«toggle_maximize_vertically» (commuta la maximització vertical), que " -#~ "només commutaran l'estat de maximització en la direcció indicada, " -#~ "«minimize» (minimitza), que minimitzarà la finestra, «shade» (persiana), " -#~ "que enrotllarà la finestra cap amunt, «menu», que mostrarà el menú de la " -#~ "finestra, «lower» (abaixa), que situarà la finestra darrere de totes les " -#~ "altres, i «none» (res), que no farà res." - -#~ msgid "" -#~ "This option provides additional control over how newly created windows " -#~ "get focus. It has two possible values; \"smart\" applies the user's " -#~ "normal focus mode, and \"strict\" results in windows started from a " -#~ "terminal not being given focus." -#~ msgstr "" -#~ "Aquesta opció proporciona control adicional sobre com les finestres noves " -#~ "obtenen el focus. Té dos valors possibles: «smart», que aplica el focus " -#~ "normal d'usuari, i «strict», que fa que no es doni el focus a les " -#~ "finestres que s'iniciïn des d'un terminal." - -#~ msgid "" -#~ "Turns on a visual indication when an application or the system issues a " -#~ "'bell' or 'beep'; useful for the hard-of-hearing and for use in noisy " -#~ "environments." -#~ msgstr "" -#~ "Activa una indicació visual quan una aplicació o el sistema envia un " -#~ "senyal de «campana» o «sons»; és útil per als durs d'orella i per a l'ús " -#~ "en ambients amb soroll." - -#~ msgid "Use standard system font in window titles" -#~ msgstr "" -#~ "Utilitza el tipus de lletra estàndard del sistema en els títols de les " -#~ "finestres" - -#~ msgid "Visual Bell Type" -#~ msgstr "Tipus de «sons» visual" - -#~ msgid "Whether raising should be a side-effect of other user interactions" -#~ msgstr "" -#~ "Si l'alçat hauria de ser un efecte secundari d'altres interaccions de " -#~ "l'usuari" - -#~ msgid "Whether to resize with the right button" -#~ msgstr "Si es canviarà la mida amb el botó secundari" - -#~ msgid "Window focus mode" -#~ msgstr "Mode de focus de les finestres" - -#~ msgid "Window title font" -#~ msgstr "Tipus de lletra del títol de les finestres" - -#~ msgid "Title" -#~ msgstr "Títol" - -#~ msgid "Class" -#~ msgstr "Classe" - -#~ msgid "" -#~ "There was an error running \"%s\":\n" -#~ "%s." -#~ msgstr "" -#~ "S'ha produït un error en executar «%s»:\n" -#~ "%s." - -#~ msgid "<author> specified twice for this theme" -#~ msgstr "S'ha especificat <author> dues vegades per a aquest tema" - -#~ msgid "<copyright> specified twice for this theme" -#~ msgstr "S'ha especificat <copyright> dues vegades per a aquest tema" - -#~ msgid "<date> specified twice for this theme" -#~ msgstr "S'ha especificat <date> dues vegades per a aquest tema" - -#~ msgid "<description> specified twice for this theme" -#~ msgstr "S'ha especificat <description> dues vegades per a aquest tema" - -#~ msgid "Theme file %s did not contain a root <metacity_theme> element" -#~ msgstr "El fitxer de tema %s no conté un element arrel <metacity_theme>" - -#~ msgid "/Windows/tearoff" -#~ msgstr "/Finestres/separador" - -#~ msgid "/Windows/_Dialog" -#~ msgstr "/Finestres/_Diàleg" - -#~ msgid "/Windows/_Modal dialog" -#~ msgstr "/Finestres/Diàleg _modal" - -#~ msgid "/Windows/Des_ktop" -#~ msgstr "/Finestres/_Escriptori" - -#~ msgid "" -#~ "Error launching metacity-dialog to print an error about a command: %s\n" -#~ msgstr "" -#~ "S'ha produït un error en executar el metacity-dialog per a mostrar un " -#~ "error quant a una ordre: %s\n" - -#~ msgid "Unknown attribute %s on <metacity_session> element" -#~ msgstr "Atribut %s desconegut a l'element <metacity_session>" - -#~ msgid "Unknown attribute %s on <maximized> element" -#~ msgstr "Atribut %s desconegut a l'element <maximized>" - -#~ msgid "Unknown attribute %s on <geometry> element" -#~ msgstr "Atribut %s desconegut a l'element <geometry>" - -#~ msgid "Toggle always on top state" -#~ msgstr "Canvia l'estat sempre per damunt" - -#~ msgid "Unmaximize window" -#~ msgstr "Desmaximitza la finestra" - -#~ msgid "" -#~ "Many actions (e.g. clicking in the client area, moving or resizing the " -#~ "window) normally raise the window as a side-effect. Setting this option " -#~ "to false, which is strongly discouraged, will decouple raising from other " -#~ "user actions, and ignore raise requests generated by applications. See " -#~ "http://bugzilla.gnome.org/show_bug.cgi?id=445447#c6." -#~ msgstr "" -#~ "Hi ha moltes accions (p.ex. fer clic a l'àrea del client, moure o canviar " -#~ "la mida de la finestra) que normalment alcen la finestra com a efecte " -#~ "secundari. Si establiu aquesta opció com a falsa (cosa gens recomanable), " -#~ "l'alçament es desvincularà de les altres accions de l'usuari i " -#~ "s'ignoraran les sol·licituds d'alçament generades per les aplicacions. " -#~ "Vegeu aquest informe d'error: http://bugzilla.gnome.org/show_bug.cgi?" -#~ "id=445447#c6." - -#~ msgid "" -#~ "The keybinding that switches to the workspace above the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles que canvia a l'espai de treball a sobre de " -#~ "l'espai de treball actual. El format és «<Control>a» o «<" -#~ "Shift><Alt>F1». L'analitzador és prou flexible i permet " -#~ "minúscules i majúscules, i també abreviacions com «<Ctl>» i «<" -#~ "Ctrl>». Si establiu l'opció a la cadena especial «disabled», no hi " -#~ "haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding that switches to the workspace below the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles que canvia a l'espai de treball sota l'espai de " -#~ "treball actual. El format és «<Control>a» o «<Shift><" -#~ "Alt>F1». L'analitzador és prou flexible i permet minúscules i " -#~ "majúscules, i també abreviacions com «<Ctl>» i «<Ctrl>». Si " -#~ "establiu l'opció a la cadena especial «disabled», no hi haurà cap " -#~ "vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding that switches to the workspace on the left of the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles que canvia a l'espai de treball a l'esquerra de " -#~ "l'espai de treball actual. El format és «<Control>a» o «<" -#~ "Shift><Alt>F1». L'analitzador és prou flexible i permet " -#~ "minúscules i majúscules, i també abreviacions com «<Ctl>» i «<" -#~ "Ctrl>». Si establiu l'opció a la cadena especial «disabled», no hi " -#~ "haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding that switches to the workspace on the right of the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles que canvia a l'espai de treball a la dreta de " -#~ "l'espai de treball actual. El format és «<Control>a» o «<" -#~ "Shift><Alt>F1». L'analitzador és prou flexible i permet " -#~ "minúscules i majúscules, i també abreviacions com «<Ctl>» i «<" -#~ "Ctrl>». Si establiu l'opció a la cadena especial «disabled», no hi " -#~ "haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding that switches to workspace 1. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "La vinculació de tecles que canvia a l'espai de treball 1. El format és " -#~ "«<Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding that switches to workspace 10. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "La vinculació de tecles que canvia a l'espai de treball 10. El format és " -#~ "«<Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding that switches to workspace 11. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "La vinculació de tecles que canvia a l'espai de treball 11. El format és " -#~ "«<Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding that switches to workspace 12. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "La vinculació de tecles que canvia a l'espai de treball 12. El format és " -#~ "«<Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding that switches to workspace 2. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "La vinculació de tecles que canvia a l'espai de treball 2. El format és " -#~ "«<Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding that switches to workspace 3. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "La vinculació de tecles que canvia a l'espai de treball 3. El format és " -#~ "«<Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding that switches to workspace 4. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "La vinculació de tecles que canvia a l'espai de treball 4. El format és " -#~ "«<Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding that switches to workspace 5. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "La vinculació de tecles que canvia a l'espai de treball 5. El format és " -#~ "«<Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding that switches to workspace 6. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "La vinculació de tecles que canvia a l'espai de treball 6. El format és " -#~ "«<Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding that switches to workspace 7. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "La vinculació de tecles que canvia a l'espai de treball 7. El format és " -#~ "«<Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding that switches to workspace 8. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "La vinculació de tecles que canvia a l'espai de treball 8. El format és " -#~ "«<Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding that switches to workspace 9. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "La vinculació de tecles que canvia a l'espai de treball 9. El format és " -#~ "«<Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding used to activate the window menu. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "La vinculació de tecles per a activar el menú de finestres. El format és " -#~ "«<Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding used to close a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "La vinculació de tecles per a tancar una finestra. El format és «<" -#~ "Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding used to enter \"move mode\" and begin moving a window " -#~ "using the keyboard. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles que activa el «mode de moviment» i permet moure " -#~ "una finestra utilitzant el teclat. El format és «<Control>a» o «<" -#~ "Shift><Alt>F1». L'analitzador és prou flexible i permet " -#~ "minúscules i majúscules, i també abreviacions com «<Ctl>» i «<" -#~ "Ctrl>». Si establiu l'opció a la cadena especial «disabled», no hi " -#~ "haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding used to enter \"resize mode\" and begin resizing a window " -#~ "using the keyboard. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles que activa el «mode de redimensió» i permet " -#~ "redimensionar una finestra utilitzant el teclat. El format és «<" -#~ "Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding used to hide all normal windows and set the focus to the " -#~ "desktop background. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles per a amagar totes les finestres normals i " -#~ "establir el focus al fons de l'escriptori. El format és «<Control>" -#~ "a» o «<Shift><Alt>F1». L'analitzador és prou flexible i " -#~ "permet minúscules i majúscules, i també abreviacions com «<Ctl>» i " -#~ "«<Ctrl>». Si establiu l'opció a la cadena especial «disabled», no " -#~ "hi haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding used to maximize a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "La vinculació de tecles per a maximitzar una finestra. El format és " -#~ "semblant a «<Control>a» o «<Shift><Alt>F1». " -#~ "L'analitzador és prou flexible i permet minúscules i majúscules, i també " -#~ "abreviacions com «<Ctl>» i «<Ctrl>». Si establiu l'opció a la " -#~ "cadena especial «disabled», no hi haurà cap vinculació per a aquesta " -#~ "acció." - -#~ msgid "" -#~ "The keybinding used to minimize a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "La vinculació de tecles per a minimitzar una finestra. El format és «<" -#~ "Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding used to move a window one workspace down. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "La vinculació de tecles per a moure una finestra un espai de treball cap " -#~ "avall. El format és «<Control>a» o «<Shift><Alt>F1». " -#~ "L'analitzador és prou flexible i permet minúscules i majúscules, i també " -#~ "abreviacions com «<Ctl>» i «<Ctrl>». Si establiu l'opció a la " -#~ "cadena especial «disabled», no hi haurà cap vinculació per a aquesta " -#~ "acció." - -#~ msgid "" -#~ "The keybinding used to move a window one workspace to the left. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles per a moure una finestra un espai de treball a " -#~ "l'esquerra. El format és semblant a «<Control>a» o «<Shift>" -#~ "<Alt>F1». L'analitzador és prou flexible i permet minúscules i " -#~ "majúscules, i també abreviacions com «<Ctl>» i «<Ctrl>». Si " -#~ "establiu l'opció a la cadena especial «disabled», no hi haurà cap " -#~ "vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding used to move a window one workspace to the right. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles per a moure una finestra un espai de treball a la " -#~ "dreta. El format és semblant a «<Control>a» o «<Shift><" -#~ "Alt>F1». L'analitzador és prou flexible i permet minúscules i " -#~ "majúscules, i també abreviacions com «<Ctl>» i «<Ctrl>». Si " -#~ "establiu l'opció a la cadena especial «disabled», no hi haurà cap " -#~ "vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding used to move a window one workspace up. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "La vinculació de tecles per a moure una finestra un espai de treball " -#~ "amunt. El format és semblant a «<Control>a» o «<Shift><" -#~ "Alt>F1». L'analitzador és prou flexible i permet minúscules i " -#~ "majúscules, i també abreviacions com «<Ctl>» i «<Ctrl>». Si " -#~ "establiu l'opció a la cadena especial «disabled», no hi haurà cap " -#~ "vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding used to move a window to workspace 1. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "La vinculació de tecles per a moure una finestra a l'espai de treball 1. " -#~ "El format és semblant a «<Control>a» o «<Shift><Alt>" -#~ "F1». L'analitzador és prou flexible i permet minúscules i majúscules, i " -#~ "també abreviacions com «<Ctl>» i «<Ctrl>». Si establiu " -#~ "l'opció a la cadena especial «disabled», no hi haurà cap vinculació per a " -#~ "aquesta acció." - -#~ msgid "" -#~ "The keybinding used to move a window to workspace 10. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "La vinculació de tecles per a moure una finestra a l'espai de treball 10. " -#~ "El format és semblant a «<Control>a» o «<Shift><Alt>" -#~ "F1». L'analitzador és prou flexible i permet minúscules i majúscules, i " -#~ "també abreviacions com «<Ctl>» i «<Ctrl>». Si establiu " -#~ "l'opció a la cadena especial «disabled», no hi haurà cap vinculació per a " -#~ "aquesta acció." - -#~ msgid "" -#~ "The keybinding used to move a window to workspace 11. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "La vinculació de tecles per a moure una finestra a l'espai de treball 11. " -#~ "El format és semblant a «<Control>a» o «<Shift><Alt>" -#~ "F1». L'analitzador és prou flexible i permet minúscules i majúscules, i " -#~ "també abreviacions com «<Ctl>» i «<Ctrl>». Si establiu " -#~ "l'opció a la cadena especial «disabled», no hi haurà cap vinculació per a " -#~ "aquesta acció." - -#~ msgid "" -#~ "The keybinding used to move a window to workspace 12. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "La vinculació de tecles per a moure una finestra a l'espai de treball 12. " -#~ "El format és semblant a «<Control>a» o «<Shift><Alt>" -#~ "F1». L'analitzador és prou flexible i permet minúscules i majúscules, i " -#~ "també abreviacions com «<Ctl>» i «<Ctrl>». Si establiu " -#~ "l'opció a la cadena especial «disabled», no hi haurà cap vinculació per a " -#~ "aquesta acció." - -#~ msgid "" -#~ "The keybinding used to move a window to workspace 2. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "La vinculació de tecles per a moure una finestra a l'espai de treball 2. " -#~ "El format és semblant a «<Control>a» o «<Shift><Alt>" -#~ "F1». L'analitzador és prou flexible i permet minúscules i majúscules, i " -#~ "també abreviacions com «<Ctl>» i «<Ctrl>». Si establiu " -#~ "l'opció a la cadena especial «disabled», no hi haurà cap vinculació per a " -#~ "aquesta acció." - -#~ msgid "" -#~ "The keybinding used to move a window to workspace 3. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "La vinculació de tecles per a moure una finestra a l'espai de treball 3. " -#~ "El format és semblant a «<Control>a» o «<Shift><Alt>" -#~ "F1». L'analitzador és prou flexible i permet minúscules i majúscules, i " -#~ "també abreviacions com «<Ctl>» i «<Ctrl>». Si establiu " -#~ "l'opció a la cadena especial «disabled», no hi haurà cap vinculació per a " -#~ "aquesta acció." - -#~ msgid "" -#~ "The keybinding used to move a window to workspace 4. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "La vinculació de tecles per a moure una finestra a l'espai de treball 4. " -#~ "El format és semblant a «<Control>a» o «<Shift><Alt>" -#~ "F1». L'analitzador és prou flexible i permet minúscules i majúscules, i " -#~ "també abreviacions com «<Ctl>» i «<Ctrl>». Si establiu " -#~ "l'opció a la cadena especial «disabled», no hi haurà cap vinculació per a " -#~ "aquesta acció." - -#~ msgid "" -#~ "The keybinding used to move a window to workspace 5. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "La vinculació de tecles per a moure una finestra a l'espai de treball 5. " -#~ "El format és semblant a «<Control>a» o «<Shift><Alt>" -#~ "F1». L'analitzador és prou flexible i permet minúscules i majúscules, i " -#~ "també abreviacions com «<Ctl>» i «<Ctrl>». Si establiu " -#~ "l'opció a la cadena especial «disabled», no hi haurà cap vinculació per a " -#~ "aquesta acció." - -#~ msgid "" -#~ "The keybinding used to move a window to workspace 6. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "La vinculació de tecles per a moure una finestra a l'espai de treball 6. " -#~ "El format és semblant a «<Control>a» o «<Shift><Alt>" -#~ "F1». L'analitzador és prou flexible i permet minúscules i majúscules, i " -#~ "també abreviacions com «<Ctl>» i «<Ctrl>». Si establiu " -#~ "l'opció a la cadena especial «disabled», no hi haurà cap vinculació per a " -#~ "aquesta acció." - -#~ msgid "" -#~ "The keybinding used to move a window to workspace 7. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "La vinculació de tecles per a moure una finestra a l'espai de treball 7. " -#~ "El format és semblant a «<Control>a» o «<Shift><Alt>" -#~ "F1». L'analitzador és prou flexible i permet minúscules i majúscules, i " -#~ "també abreviacions com «<Ctl>» i «<Ctrl>». Si establiu " -#~ "l'opció a la cadena especial «disabled», no hi haurà cap vinculació per a " -#~ "aquesta acció." - -#~ msgid "" -#~ "The keybinding used to move a window to workspace 8. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "La vinculació de tecles per a moure una finestra a l'espai de treball 8. " -#~ "El format és semblant a «<Control>a» o «<Shift><Alt>" -#~ "F1». L'analitzador és prou flexible i permet minúscules i majúscules, i " -#~ "també abreviacions com «<Ctl>» i «<Ctrl>». Si establiu " -#~ "l'opció a la cadena especial «disabled», no hi haurà cap vinculació per a " -#~ "aquesta acció." - -#~ msgid "" -#~ "The keybinding used to move a window to workspace 9. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "La vinculació de tecles per a moure una finestra a l'espai de treball 9. " -#~ "El format és semblant a «<Control>a» o «<Shift><Alt>" -#~ "F1». L'analitzador és prou flexible i permet minúscules i majúscules, i " -#~ "també abreviacions com «<Ctl>» i «<Ctrl>». Si establiu " -#~ "l'opció a la cadena especial «disabled», no hi haurà cap vinculació per a " -#~ "aquesta acció." - -#~ msgid "" -#~ "The keybinding used to move focus backwards between panels and the " -#~ "desktop, using a popup window. The format looks like \"<Control>a\" " -#~ "or \"<Shift><Alt>F1\". The parser is fairly liberal and " -#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" -#~ "\" and \"<Ctrl>\". If you set the option to the special string " -#~ "\"disabled\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles que mou el focus cap enrere entre els quadres i " -#~ "l'escriptori, utilitzant una finestra emergent. El format és semblant a " -#~ "«<Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding used to move focus backwards between panels and the " -#~ "desktop, without a popup window. The format looks like \"<Control>a" -#~ "\" or \"<Shift><Alt>F1\". The parser is fairly liberal and " -#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" -#~ "\" and \"<Ctrl>\". If you set the option to the special string " -#~ "\"disabled\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles que mou el focus cap enrere entre els quadres i " -#~ "l'escriptori, sense utilitzar una finestra emergent. El format és " -#~ "semblant a «<Control>a» o «<Shift><Alt>F1». " -#~ "L'analitzador és prou flexible i permet minúscules i majúscules, i també " -#~ "abreviacions com «<Ctl>» i «<Ctrl>». Si establiu l'opció a la " -#~ "cadena especial «disabled», no hi haurà cap vinculació per a aquesta " -#~ "acció." - -#~ msgid "" -#~ "The keybinding used to move focus backwards between windows of an " -#~ "application without a popup window. Holding \"shift\" together with this " -#~ "binding makes the direction go forward again. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "La vinculació de tecles que mou el focus cap enrere entre finestres d'una " -#~ "aplicació, sense utilitzar una finestra emergent. Mantenint premuda la " -#~ "techa de «majúscules» juntament amb aquesta convinació de tecles, fa que " -#~ "es vagi enrere. El format és semblant a «<Control>a» o «<" -#~ "Shift><Alt>F1». L'analitzador és força flexible i permet " -#~ "minúscules i majúscules, i també abreviacions com «<Ctl>» i «<" -#~ "Ctrl>». Si establiu l'opció a la cadena especial «disabled», no hi " -#~ "haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding used to move focus backwards between windows of an " -#~ "application, using a popup window. Holding \"shift\" together with this " -#~ "binding makes the direction go forward again. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "La vinculació de tecles que mou el focus cap enrere entre finestres d'una " -#~ "mateixa aplicació, utilitzant una finestra emergent. Prement la tecla de " -#~ "majúscules aquesta vinculació fa que la direcció sigui cap enrere. El " -#~ "format és semblant a «<Control>a» o «<Shift><Alt>F1». " -#~ "L'analitzador és prou flexible i permet minúscules i majúscules, i també " -#~ "abreviacions com «<Ctl>» i «<Ctrl>». Si establiu l'opció a la " -#~ "cadena especial «disabled» (inhabilitat), no hi haurà cap vinculació per " -#~ "a aquesta acció." - -#~ msgid "" -#~ "The keybinding used to move focus backwards between windows without a " -#~ "popup window. Holding \"shift\" together with this binding makes the " -#~ "direction go forward again. The format looks like \"<Control>a\" or " -#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " -#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" -#~ "\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles que mou el focus cap enrere entre finestres, " -#~ "sense utilitzar una finestra emergent. El format és semblant a «<" -#~ "Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding used to move focus backwards between windows, using a " -#~ "popup window. Holding \"shift\" together with this binding makes the " -#~ "direction go forward again. The format looks like \"<Control>a\" or " -#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " -#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" -#~ "\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles que mou el focus cap enrere entre finestres, " -#~ "utilitzant una finestra emergent. El format és semblant a «<Control>" -#~ "a» o «<Shift><Alt>F1». L'analitzador és prou flexible i " -#~ "permet minúscules i majúscules, i també abreviacions com «<Ctl>» i " -#~ "«<Ctrl>». Si establiu l'opció a la cadena especial «disabled», no " -#~ "hi haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding used to move focus between panels and the desktop, using a " -#~ "popup window. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles que mou el focus entre els quadres i " -#~ "l'escriptori, utilitzant una finestra emergent. El format és semblant a " -#~ "«<Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding used to move focus between panels and the desktop, without " -#~ "a popup window. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles que mou el focus entre els quadres i " -#~ "l'escriptori, sense utilitzar una finestra emergent. El format és " -#~ "semblant a «<Control>a» o «<Shift><Alt>F1». " -#~ "L'analitzador és prou flexible i permet minúscules i majúscules, i també " -#~ "abreviacions com «<Ctl>» i «<Ctrl>». Si establiu l'opció a la " -#~ "cadena especial «disabled», no hi haurà cap vinculació per a aquesta " -#~ "acció." - -#~ msgid "" -#~ "The keybinding used to move focus between windows of an application " -#~ "without a popup window. Holding the \"shift\" key while using this " -#~ "binding reverses the direction of movement. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "La vinculació de tecles que mou el focus entre finestres d'una aplicació, " -#~ "sense utilitzar una finestra emergent. Prement la tecla de majúscules " -#~ "aquesta vinculació fa que la direcció sigui cap enrere. El format és " -#~ "semblant a «<Control>a» o «<Shift><Alt>F1». " -#~ "L'analitzador és prou flexible i permet minúscules i majúscules, i també " -#~ "abreviacions com «<Ctl>» i «<Ctrl>». Si establiu l'opció a la " -#~ "cadena especial «disabled», no hi haurà cap vinculació per a aquesta " -#~ "acció." - -#~ msgid "" -#~ "The keybinding used to move focus between windows of an application, " -#~ "using a popup window. (Traditionally <Alt>F6) Holding the \"shift\" " -#~ "key while using this binding reverses the direction of movement. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles que mou el focus entre finestres d'una aplicació, " -#~ "utilitzant una finestra emergent. (Tradicionalment <Alt>F6) Prement " -#~ "la tecla de majúscules aquesta vinculació fa que la direcció sigui al " -#~ "revés. El format és semblant a «<Control>a» o «<Shift><" -#~ "Alt>F1». L'analitzador és prou flexible i permet minúscules i " -#~ "majúscules, i també abreviacions com «<Ctl>» i «<Ctrl>». Si " -#~ "establiu l'opció a la cadena especial «disabled», no hi haurà cap " -#~ "vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding used to move focus between windows without a popup window. " -#~ "(Traditionally <Alt>Escape) Holding the \"shift\" key while using " -#~ "this binding reverses the direction of movement. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "La vinculació de tecles que mou el focus entre finestres, sense utilitzar " -#~ "una finestra emergent. El format és semblant a «<Control>a» o «<" -#~ "Shift><Alt>F1». L'analitzador és prou flexible i permet " -#~ "minúscules i majúscules, i també abreviacions com «<Ctl>» i «<" -#~ "Ctrl>». Si establiu l'opció a la cadena especial «disabled», no hi " -#~ "haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding used to move focus between windows, using a popup window. " -#~ "(Traditionally <Alt>Tab) Holding the \"shift\" key while using this " -#~ "binding reverses the direction of movement. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "La vinculació de tecles que mou el focus entre finestres, utilitzant una " -#~ "finestra emergent. El format és semblant a «<Control>a» o «<" -#~ "Shift><Alt>F1». L'analitzador és prou flexible i permet " -#~ "minúscules i majúscules, i també abreviacions com «<Ctl>» i «<" -#~ "Ctrl>». Si establiu l'opció a la cadena especial «disabled», no hi " -#~ "haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding used to toggle always on top. A window that is always on " -#~ "top will always be visible over other overlapping windows. The format " -#~ "looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -#~ "parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles per a seleccionar si una finestra està sempre per " -#~ "damunt. Una finestra que estiga sempre per damunt serà visible per damunt " -#~ "de les altres finestres que s'interseccionen. El format és semblant a " -#~ "«<Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding used to toggle fullscreen mode. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "La vinculació de tecles que habilita o inhabilita el mode a pantalla " -#~ "sencera. El format és semblant a «<Control>a» o «<Shift><" -#~ "Alt>F1». L'analitzador és prou flexible i permet minúscules i " -#~ "majúscules, i també abreviacions com «<Ctl>» i «<Ctrl>». Si " -#~ "establiu l'opció a la cadena especial «disabled», no hi haurà cap " -#~ "vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding used to toggle maximization. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "La vinculació de tecles per a maximitzar o desmaximitzar una finestra. El " -#~ "format és semblant a «<Control>a» o «<Shift><Alt>F1». " -#~ "L'analitzador és prou flexible i permet minúscules i majúscules, i també " -#~ "abreviacions com «<Ctl>» i «<Ctrl>». Si establiu l'opció a la " -#~ "cadena especial «disabled», no hi haurà cap vinculació per a aquesta " -#~ "acció." - -#~ msgid "" -#~ "The keybinding used to toggle shaded/unshaded state. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "La vinculació de tecles per a canviar entre l'estat ombrejat i " -#~ "desombrejat. El format és «<Control>a» o «<Shift><Alt>" -#~ "F1». L'analitzador és prou flexible i permet minúscules i majúscules, i " -#~ "també abreviacions com «<Ctl>» i «<Ctrl>». Si establiu " -#~ "l'opció a la cadena especial «disabled», no hi haurà cap vinculació per a " -#~ "aquesta acció." - -#~ msgid "" -#~ "The keybinding used to toggle whether the window is on all workspaces or " -#~ "just one. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles per a seleccionar si una finestra està en tots " -#~ "els espais de treball o només en un. El format és semblant a «<" -#~ "Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding used to unmaximize a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "La vinculació de tecles per a desmaximitzar una finestra. El format és " -#~ "semblant a «<Control>a» o «<Shift><Alt>F1». " -#~ "L'analitzador és prou flexible i permet minúscules i majúscules, i també " -#~ "abreviacions com «<Ctl>» i «<Ctrl>». Si establiu l'opció a la " -#~ "cadena especial «disabled», no hi haurà cap vinculació per a aquesta " -#~ "acció." - -#~ msgid "" -#~ "The keybinding which display's the panel's \"Run Application\" dialog " -#~ "box. The format looks like \"<Control>a\" or \"<Shift><" -#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If " -#~ "you set the option to the special string \"disabled\", then there will be " -#~ "no keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles que mostra el diàleg «Executa un programa» del " -#~ "quadre. El format és semblant a «<Control>a» o «<Shift><" -#~ "Alt>F1». L'analitzador és prou flexible i permet minúscules i " -#~ "majúscules, i també abreviacions com «<Ctl>» i «<Ctrl>». Si " -#~ "establiu l'opció a la cadena especial «disabled», no hi haurà cap " -#~ "vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding which invokes a terminal. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "La vinculació de tecles que executa un terminal. El format és semblant a " -#~ "«<Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding which invokes the panel's screenshot utility to take a " -#~ "screenshot of a window. The format looks like \"<Control>a\" or " -#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " -#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" -#~ "\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles que invoca la utilitat de captures de pantalla " -#~ "del quadre per a prendre una captura d'una finestra. El format és " -#~ "semblant a «<Control>a» o «<Shift><Alt>F1». " -#~ "L'analitzador és prou flexible i permet minúscules i majúscules, i també " -#~ "abreviacions com «<Ctl>» i «<Ctrl>». Si establiu l'opció a la " -#~ "cadena especial «disabled», no hi haurà cap vinculació per a aquesta " -#~ "acció." - -#~ msgid "" -#~ "The keybinding which invokes the panel's screenshot utility. The format " -#~ "looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -#~ "parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles que invoca la utilitat de captures de pantalla " -#~ "del quadre. El format és semblant a «<Control>a» o «<Shift>" -#~ "<Alt>F1». L'analitzador és prou flexible i permet minúscules i " -#~ "majúscules, i també abreviacions com «<Ctl>» i «<Ctrl>». Si " -#~ "establiu l'opció a la cadena especial «disabled», no hi haurà cap " -#~ "vinculació per a aquesta acció." - -#~ msgid "" -#~ "The keybinding which shows the panel's main menu. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "La vinculació de tecles que mostra el menú principal del quadre. El " -#~ "format és semblant a «<Control>a» o «<Shift><Alt>F1». " -#~ "L'analitzador és prou flexible i permet minúscules i majúscules, i també " -#~ "abreviacions com «<Ctl>» i «<Ctrl>». Si establiu l'opció a la " -#~ "cadena especial «disabled», no hi haurà cap vinculació per a aquesta " -#~ "acció." - -#~ msgid "" -#~ "This keybinding changes whether a window is above or below other windows. " -#~ "If the window is covered by another one, it raises the window above all " -#~ "others, and if the window is already fully visible, it lowers it below " -#~ "all others. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Aquesta vinculació de tecles canvia si una finestra és per damunt o per " -#~ "sota d'altres finestres. Si la finestra està coberta per una altra " -#~ "finestra, s'alça la finestra per damunt de les altres, quedant totalment " -#~ "visible, i posa a sota les altres. El format és semblant a «<" -#~ "Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "This keybinding lowers a window below other windows. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Aquesta vinculació de tecles fica una finestra sota les altres. El format " -#~ "és semblant a «<Control>a» o «<Shift><Alt>F1». " -#~ "L'analitzador és prou flexible i permet minúscules i majúscules, i també " -#~ "abreviacions com «<Ctl>» i «<Ctrl>». Si establiu l'opció a la " -#~ "cadena especial «disabled», no hi haurà cap vinculació per a aquesta " -#~ "acció." - -#~ msgid "" -#~ "This keybinding moves a window against the north (top) side of the " -#~ "screen. The format looks like \"<Control>a\" or \"<Shift><" -#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If " -#~ "you set the option to the special string \"disabled\", then there will be " -#~ "no keybinding for this action." -#~ msgstr "" -#~ "Aquesta vinculació de tecles mou una finestra cap a la part nord " -#~ "(superior) de la pantalla. El format és semblant a «<Control>a» o " -#~ "«<Shift><Alt>F1». L'analitzador és prou flexible i permet " -#~ "minúscules i majúscules, i també abreviacions com «<Ctl>» i «<" -#~ "Ctrl>». Si establiu l'opció a la cadena especial «disabled», no hi " -#~ "haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "This keybinding moves a window into the east (right) side of the screen. " -#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>" -#~ "F1\". The parser is fairly liberal and allows lower or upper case, and " -#~ "also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -#~ "set the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Aquesta vinculació de tecles mou una finestra cap a la part est (dreta) " -#~ "de la pantalla. El format és semblant a «<Control>a» o «<" -#~ "Shift><Alt>F1». L'analitzador és prou flexible i permet " -#~ "minúscules i majúscules, i també abreviacions com «<Ctl>» i «<" -#~ "Ctrl>». Si establiu l'opció a la cadena especial «disabled», no hi " -#~ "haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "This keybinding moves a window into the north-east (top right) corner of " -#~ "the screen. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Aquesta vinculació de tecles mou una finestra cap a la part nord-est " -#~ "(superior a la dreta) de la pantalla. El format és semblant a «<" -#~ "Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "This keybinding moves a window into the north-west (top left) corner of " -#~ "the screen. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Aquesta vinculació de tecles mou una finestra cap a la part nord-oest " -#~ "(superior a l'esquerra) de la pantalla. El format és semblant a «<" -#~ "Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "This keybinding moves a window into the south (bottom) side of the " -#~ "screen. The format looks like \"<Control>a\" or \"<Shift><" -#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If " -#~ "you set the option to the special string \"disabled\", then there will be " -#~ "no keybinding for this action." -#~ msgstr "" -#~ "Aquesta vinculació de tecles mou una finestra cap a la part del sud " -#~ "(inferior) de la pantalla. El format és semblant a «<Control>a» o " -#~ "«<Shift><Alt>F1». L'analitzador és prou flexible i permet " -#~ "minúscules i majúscules, i també abreviacions com «<Ctl>» i «<" -#~ "Ctrl>». Si establiu l'opció a la cadena especial «disabled», no hi " -#~ "haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "This keybinding moves a window into the south-east (bottom right) corner " -#~ "of the screen. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "Aquesta vinculació de tecles mou una finestra cap a la part sud-est de la " -#~ "pantalla. El format és semblant a «<Control>a» o «<Shift><" -#~ "Alt>F1». L'analitzador és prou flexible i permet minúscules i " -#~ "majúscules, i també abreviacions com «<Ctl>» i «<Ctrl>». Si " -#~ "establiu l'opció a la cadena especial «disabled», no hi haurà cap " -#~ "vinculació per a aquesta acció." - -#~ msgid "" -#~ "This keybinding moves a window into the south-west (bottom left) corner " -#~ "of the screen. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "Aquesta vinculació de tecles mou una finestra cap a la part sud-oest " -#~ "(inferior a l'esquerra) de la pantalla. El format és semblant a «<" -#~ "Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "This keybinding moves a window into the west (left) side of the screen. " -#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>" -#~ "F1\". The parser is fairly liberal and allows lower or upper case, and " -#~ "also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -#~ "set the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Aquesta vinculació de tecles mou una finestra cap a la part l'oest " -#~ "(esquerra) de la pantalla. El format és semblant a «<Control>a» o " -#~ "«<Shift><Alt>F1». L'analitzador és prou flexible i permet " -#~ "minúscules i majúscules, i també abreviacions com «<Ctl>» i «<" -#~ "Ctrl>». Si establiu l'opció a la cadena especial «disabled», no hi " -#~ "haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "This keybinding raises the window above other windows. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Aquesta vinculació de tecles eleva la finestra per damunt de les altres. " -#~ "El format és semblant a «<Control>a» o «<Shift><Alt>" -#~ "F1». L'analitzador és prou flexible i permet minúscules i majúscules, i " -#~ "també abreviacions com «<Ctl>» i «<Ctrl>». Si establiu " -#~ "l'opció a la cadena especial «disabled», no hi haurà cap vinculació per a " -#~ "aquesta acció." - -#~ msgid "" -#~ "This keybinding resizes a window to fill available horizontal space. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Aquesta vinculació de tecles redimensiona una finestra per a que plene " -#~ "tot l'espai horitzontal disponible. El format és semblant a «<" -#~ "Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." - -#~ msgid "" -#~ "This keybinding resizes a window to fill available vertical space. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Aquesta vinculació de tecles redimensiona una finestra per a que plene " -#~ "tot l'espai vertical disponible. El format és semblant a «<Control>" -#~ "a» o «<Shift><Alt>F1». L'analitzador és prou flexible i " -#~ "permet minúscules i majúscules, i també abreviacions com «<Ctl>» i " -#~ "«<Ctrl>». Si establiu l'opció a la cadena especial «disabled», no " -#~ "hi haurà cap vinculació per a aquesta acció." - -#~ msgid "Unmaximize Window" -#~ msgstr "Desmaximitza la finestra" - -#~ msgid "No \"%s\" attribute on <%s> element" -#~ msgstr "Cap atribut «%s» a l'element <%s>" - -#~ msgid "Theme already has a fallback icon" -#~ msgstr "El tema ja té una icona alternativa" - -#~ msgid "Theme already has a fallback mini_icon" -#~ msgstr "El tema ja té una miniicona alternativa" - -#~ msgid "No \"name\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut de «nom» en l'element <%s>" - -#~ msgid "No \"value\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut de «valor» a l'element <%s>" - -#~ msgid "No \"top\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut de «top» a l'element <%s>" - -#~ msgid "No \"bottom\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut de «bottom» a l'element <%s>" - -#~ msgid "No \"left\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut de «left» a l'element <%s>" - -#~ msgid "No \"right\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut de «right» a l'element <%s>" - -#~ msgid "No \"color\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut de «color» a l'element <%s>" - -#~ msgid "No \"x1\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut de «x1» a l'element <%s>" - -#~ msgid "No \"y1\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut de «y1» a l'element <%s>" - -#~ msgid "No \"x2\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut de «x2» a l'element <%s>" - -#~ msgid "No \"y2\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut de «y2» a l'element <%s>" - -#~ msgid "No \"y\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut de «y» a l'element <%s>" - -#~ msgid "No \"width\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut de «amplada» en l'element <%s>" - -#~ msgid "No \"height\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut de «height» en l'element <%s>" - -#~ msgid "No \"start_angle\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut de «start_angle» en l'element <%s>" - -#~ msgid "No \"extent_angle\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut de «extent_angle» en l'element <%s>" - -#~ msgid "No \"alpha\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut «alpha» a l'element <%s>" - -#~ msgid "No \"type\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut «type» a l'element <%s>" - -#~ msgid "No \"filename\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut «filename» a l'element <%s>" - -#~ msgid "No \"state\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut «state» a l'element <%s>" - -#~ msgid "No \"shadow\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut «shadow» a l'element <%s>" - -#~ msgid "No \"arrow\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut «arrow» a l'element <%s>" - -#~ msgid "No \"value\" attribute on <%s> element" -#~ msgstr "No hi ha cap atribut «valor» a l'element <%s>" - -#~ msgid "No \"position\" attribute on <%s> element" -#~ msgstr "No hi ha cap atribut «posició» a l'element <%s>" - -#~ msgid "No \"function\" attribute on <%s> element" -#~ msgstr "No hi ha cap atribut de «funció» a l'element <%s>" - -#~ msgid "No \"state\" attribute on <%s> element" -#~ msgstr "No hi ha cap atribut de «estat» a l'element <%s>" - -#~ msgid "No \"focus\" attribute on <%s> element" -#~ msgstr "No hi ha cap atribut de «focus» en l'element <%s>" - -#~ msgid "No \"style\" attribute on <%s> element" -#~ msgstr "No hi ha cap atribut de «style» a l'element <%s>" - -#~ msgid "No \"resize\" attribute on <%s> element" -#~ msgstr "No hi ha cap atribut «resize» en l'element <%s>" - -#~ msgid "Type of %s was not integer" -#~ msgstr "%s no era de tipus enter" - -#~ msgid "" -#~ "%d stored in GConf key %s is not a reasonable cursor_size; must be in the " -#~ "range 1..128\n" -#~ msgstr "" -#~ "%d, emmagatzemat a la clau GConf %s, no és una mida de cursor raonable, " -#~ "ha d'estar dins del rang 1..128\n" - -#~ msgid "" -#~ "%d stored in GConf key %s is not a reasonable number of workspaces, " -#~ "current maximum is %d\n" -#~ msgstr "" -#~ "%d, emmagatzemat a la clau GConf, %s no té un nombre raonable d'espais de " -#~ "treball. El màxim actual és %d\n" - -#~ msgid "On _Top" -#~ msgstr "Per damun_t" - -#~ msgid "" -#~ "Forcing this application to quit will cause you to lose any unsaved " -#~ "changes." -#~ msgstr "" -#~ "Si forceu la sortida d'aquesta aplicació, se'n perdran els canvis que " -#~ "hagueu desat." - -#~ msgid "Unknown function \"%s\" for menu icon" -#~ msgstr "Funció «%s» desconeguda per a la icona de menú" - -#~ msgid "Unknown state \"%s\" for menu icon" -#~ msgstr "Estat «%s» desconegut per a la icona de menú" - -#~ msgid "Theme already has a menu icon for function %s state %s" -#~ msgstr "El tema ja té una icona de menú per a l'estat %s de la funció %s" - -#~ msgid "No draw_ops provided for menu icon" -#~ msgstr "No s'ha proveït cap draw_ops per a la icona de menú" - -#~ msgid "Failed to read theme from file %s: %s\n" -#~ msgstr "S'ha produït un error en llegir el tema del fitxer %s: %s\n" - -#~ msgid "" -#~ "<menu_icon function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -#~ "specified for this theme" -#~ msgstr "" -#~ "<menu_icon function=\"%s\" state=\"%s\" draw_ops=\"qualsevol\"/> s'ha " -#~ "d'especificar per a aquest tema" - -#~ msgid "" -#~ "If true, and the focus mode is either \"sloppy\" or \"mouse\" then the " -#~ "focused window will be automatically raised after a delay (the delay is " -#~ "specified by the auto_raise_delay key). This preference is poorly named, " -#~ "but kept for backwards compatibility. To try to be more clear (at least " -#~ "to the technically inclined), its meaning is \"automatically raise the " -#~ "window following a timeout which is triggered by non-grabbed mouse entry " -#~ "in sloppy or mouse focus modes\". It is unrelated to clicking behavior (i." -#~ "e. this is not related to raise-on-click/orthogonal-raise). It is " -#~ "unrelated to entering a window during drag and drop (because that results " -#~ "in the application grabbing the mouse)" -#~ msgstr "" -#~ "Si és cert, i el mode del focus és «sloppy» o «mouse», aleshores la " -#~ "finestra enfocada s'alçarà automàticament al cap d'una estona (el temps " -#~ "s'especifica a la clau auto_raise_delay). Aquesta preferència no està " -#~ "gaire ben batejada, però es manté per compatibilitat amb versions " -#~ "anteriors. Per ser més clars (per als més tècnics), significa «alça la " -#~ "finestra automàticament després d'un temps d'espera, que s'activa per una " -#~ "entrada no capturada del ratolí quan aquest està en el mode de focus " -#~ "\"sloppy\" o bé \"mouse\"». No té cap relació amb el comportament del " -#~ "clic (no té relació amb l'alçament amb un clic/alçament ortogonal). No " -#~ "està relacionat amb entrar a una finestra durant una opració d'arrossegar " -#~ "i deixar anar (perquè resulta en que l'aplicació captura el ratolí)" - -#~ msgid "" -#~ "Some applications break specifications in ways that result in window " -#~ "manager misfeatures. For example, ideally Metacity would place all " -#~ "dialogs in a consistent position with respect to their parent window. " -#~ "This requires ignoring application-specified positions for dialogs. But " -#~ "some versions of Java/Swing mark their popup menus as dialogs, so " -#~ "Metacity has to disable dialog positioning to allow menus to work in " -#~ "broken Java applications. There are several other examples like this. " -#~ "This option puts Metacity in full-on Correct mode, which perhaps gives a " -#~ "moderately nicer UI if you don't need to run any broken apps. Sadly, " -#~ "workarounds must be enabled by default; the real world is an ugly place. " -#~ "Some of the workarounds are workarounds for limitations in the " -#~ "specifications themselves, so sometimes a bug in no-workarounds mode " -#~ "won't be fixable without amending a spec." -#~ msgstr "" -#~ "Algunes aplicacions trenquen les especificacions de maneres que resulten " -#~ "en disfuncionalitats dels gestors de finestres. Per exemple, idealment el " -#~ "Metacity ficarà tots els diàlegs en una posició consistent respecte de " -#~ "les seves finestres pare. Això requereix ignorar les posicions que " -#~ "especifiquen les aplicacions per als diàlegs. Tanmateix, algunes versions " -#~ "del Java/Swing marquen els seus menús emergents com a diàlegs, i Metacity " -#~ "ha de inhabilitar el posicionament de diàlegs per a què els menús " -#~ "funcionin en les aplicacions Java amb aquests errors. Hi ha més exemples " -#~ "com aquest. Aquesta opció estableix Metacity en el mode «completament " -#~ "correcte», que potser donarà una millor interfície d'usuari si no " -#~ "necessiteu executar cap aplicació amb errors. Malauradament, aquesta " -#~ "funcionalitat s'ha d'habilitar per defecte. Algunes de les funcionalitats " -#~ "estan dirigides a limitacions en les mateixes especificacions, pel que a " -#~ "vegades un error en el mode sense correccions no es pot solucionar sense " -#~ "canviar l'especificació." - -#~ msgid "" -#~ "Coordinate expression parser overflowed its buffer, this is really a " -#~ "Metacity bug, but are you sure you need a huge expression like that?" -#~ msgstr "" -#~ "L'anàlisi de l'expressió coordinada ha sobreeixit la seva memòria " -#~ "intermèdia. Aquest és un error del Metacity, però esteu segur que " -#~ "necessiteu una expressió tan rotunda com aquesta?" diff --git a/po/ca@valencia.po b/po/ca@valencia.po index 97b11b546..0ba12ca14 100644 --- a/po/ca@valencia.po +++ b/po/ca@valencia.po @@ -5,426 +5,295 @@ # Jesús Moreno <jmmolas@wanadoo.es>, 2002. # Jordi Mallach <jordi@sindominio.net>, 2003, 2004, 2005, 2006, 2007, 2008. # David Planella <david.planella@gmail.com>, 2008, 2009, 2011, 2012. +# Jordi Serratosa <jordis@softcatala.cat>, 2012, 2017. +# Gil Forcada <gilforcada@guifi.net>, 2012, 2013, 2014, 2016. # msgid "" msgstr "" "Project-Id-Version: metacity 2.24\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-03-15 23:18+0100\n" -"PO-Revision-Date: 2012-03-15 23:17+0100\n" -"Last-Translator: David Planella <david.planella@gmail.com>\n" -"Language-Team: Softcatalà <tradgnome@softcatala.org>\n" -"Language: \n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?" +"product=mutter&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-09-29 14:36+0000\n" +"PO-Revision-Date: 2017-08-25 13:23+0200\n" +"Last-Translator: Xavi Ivars <xavi.ivars@gmail.com>\n" +"Language-Team: Catalan <tradgnome@softcatala.org>\n" +"Language: ca-valencia\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bits\n" +"Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Poedit 2.0.1\n" -#: ../src/50-muffin-windows.xml.in.h:1 -msgid "Windows" -msgstr "Finestres" - -#: ../src/50-muffin-windows.xml.in.h:2 -msgid "View split on left" -msgstr "Mostra la partició a l'esquerra" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Navegació" -#: ../src/50-muffin-windows.xml.in.h:3 -msgid "View split on right" -msgstr "Mostra la partició a la dreta" +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Mou la finestra a l'espai de treball 1" -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format -msgid "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." -msgstr "" -"Ja s'està executant un altre gestor de composició a la pantalla %i a la " -"visualització «%s»." +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Mou la finestra a l'espai de treball 2" -#: ../src/core/bell.c:307 -msgid "Bell event" -msgstr "Esdeveniment de campana" +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Mou la finestra a l'espai de treball 3" -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Es desconeix la informació demanada sobre la finestra: %d" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Mou la finestra a l'espai de treball 4" -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> no està responent." +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Mou la finestra a l'últim espai de treball" -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "L'aplicació no està responent." +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace to the left" +msgstr "Mou la finestra un espai de treball a l'esquerra" -#: ../src/core/delete.c:119 -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "" -"Podeu esperar un moment perquè continue o podeu forçar-ne l'eixida completa." +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace to the right" +msgstr "Mou la finestra un espai de treball a la dreta" -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "_Espera" +#: data/50-mutter-navigation.xml:30 +msgid "Move window one workspace up" +msgstr "Mou la finestra un espai de treball amunt" -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "_Força'n l'eixida" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one workspace down" +msgstr "Mou la finestra un espai de treball avall" -#: ../src/core/display.c:387 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "Manca l'extensió %s necessària per a la composició" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor to the left" +msgstr "Mou la finestra un monitor a l'esquerra" -#: ../src/core/display.c:453 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "" -"S'ha produït un error en obrir la pantalla del sistema de finestres X «%s»\n" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor to the right" +msgstr "Mou la finestra un monitor a la dreta" -#: ../src/core/keybindings.c:852 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "" -"Ja hi ha algun altre programa utilitzant la clau %s amb els modificadors %x " -"com a vinculació\n" +#: data/50-mutter-navigation.xml:42 +msgid "Move window one monitor up" +msgstr "Mou la finestra un monitor amunt" -#: ../src/core/main.c:206 -msgid "Disable connection to session manager" -msgstr "Inhabilita la connexió al gestor de sessions" +#: data/50-mutter-navigation.xml:45 +msgid "Move window one monitor down" +msgstr "Mou la finestra un monitor avall" -#: ../src/core/main.c:212 -msgid "Replace the running window manager" -msgstr "Reemplaça el gestor de finestres en execució" +#: data/50-mutter-navigation.xml:49 +msgid "Switch applications" +msgstr "Canvia d'aplicacions" -#: ../src/core/main.c:218 -msgid "Specify session management ID" -msgstr "Especifica l'ID de gestió de sessió" +#: data/50-mutter-navigation.xml:54 +msgid "Switch to previous application" +msgstr "Canvia a l'aplicació anterior" -#: ../src/core/main.c:223 -msgid "X Display to use" -msgstr "Visualització X per usar" +#: data/50-mutter-navigation.xml:58 +msgid "Switch windows" +msgstr "Canvia de finestres" -#: ../src/core/main.c:229 -msgid "Initialize session from savefile" -msgstr "Inicialitza la sessió des del fitxer alçat" +#: data/50-mutter-navigation.xml:63 +msgid "Switch to previous window" +msgstr "Canvia a la finestra anterior" -#: ../src/core/main.c:235 -msgid "Make X calls synchronous" -msgstr "Fes que les crides a l'X siguen síncrones" +#: data/50-mutter-navigation.xml:67 +msgid "Switch windows of an application" +msgstr "Canvia entre les finestres d'una aplicació" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "No s'ha pogut analitzar el directori de temes: %s\n" +#: data/50-mutter-navigation.xml:72 +msgid "Switch to previous window of an application" +msgstr "Canvia a la finestra anterior d'una aplicació" -#: ../src/core/main.c:520 -#, c-format -msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "" -"No s'ha trobat cap tema. Assegureu-vos que %s existeix i conté els temes " -"habituals.\n" +#: data/50-mutter-navigation.xml:76 +msgid "Switch system controls" +msgstr "Canvia els controls del sistema" -#: ../src/core/muffin.c:40 -#, c-format -msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" -"Muffin %s\n" -"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., i d'altres\n" -"Això és programari lliure; vegeu els fitxers de codi font per conèixer-ne\n" -"les condicions de còpia.\n" -"No hi ha CAP garantia; ni tan sols la garantia implícita de COMERCIABILITAT\n" -"o ADEQUACIÓ A PER UN PROPÒSIT PARTICULAR.\n" +#: data/50-mutter-navigation.xml:81 +msgid "Switch to previous system control" +msgstr "Canvia al control del sistema anterior" -#: ../src/core/muffin.c:54 -msgid "Print version" -msgstr "Escriu versió" +#: data/50-mutter-navigation.xml:85 +msgid "Switch windows directly" +msgstr "Canvia immediatament entre finestres" -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "Llista separada per comes de connectors de composició" +#: data/50-mutter-navigation.xml:90 +msgid "Switch directly to previous window" +msgstr "Canvia immediatament a la finestra anterior" -#: ../src/core/prefs.c:1077 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"Les solucions temporals per a aplicacions amb errors estan inhabilitades. " -"Pot ser que certes aplicacions no funcionen correctament.\n" +#: data/50-mutter-navigation.xml:94 +msgid "Switch windows of an app directly" +msgstr "Canvia immediatament entre les finestres d'una aplicació" -#: ../src/core/prefs.c:1152 -#, c-format -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "" -"No s'ha pogut analitzar la descripció de tipus de lletra «%s» de la clau %s " -"del GSettings\n" +#: data/50-mutter-navigation.xml:99 +msgid "Switch directly to previous window of an app" +msgstr "Canvia immediatament a la finestra anterior d'una aplicació" -#: ../src/core/prefs.c:1218 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"«%s», trobat a la base de dades de la configuració, no és un valor vàlid per " -"al modificador del botó del ratolí\n" +#: data/50-mutter-navigation.xml:103 +msgid "Switch system controls directly" +msgstr "Canvia immediatament entre els controls del sistema" -#: ../src/core/prefs.c:1739 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "" -"«%s» trobat a la base de dades de la configuració no és un valor vàlid per a " -"la vinculació de tecla «%s»\n" +#: data/50-mutter-navigation.xml:108 +msgid "Switch directly to previous system control" +msgstr "Canvia immediatament al control del sistema anterior" -#: ../src/core/prefs.c:1836 -#, c-format -msgid "Workspace %d" -msgstr "Espai de treball %d" +#: data/50-mutter-navigation.xml:111 +msgid "Hide all normal windows" +msgstr "Oculta totes les finestres normals" -#: ../src/core/screen.c:730 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "La pantalla %d en la visualització '%s' no és vàlida\n" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 1" +msgstr "Canvia a l'espai de treball 1" -#: ../src/core/screen.c:746 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"La pantalla %d en la visualització «%s» ja té un gestor de finestres; proveu " -"l'opció --replace per reemplaçar el gestor de finestres actual.\n" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 2" +msgstr "Canvia a l'espai de treball 2" -#: ../src/core/screen.c:773 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "" -"No s'ha pogut adquirir la selecció del gestor de finestres en la pantalla %d " -"visualització «%s»\n" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to workspace 3" +msgstr "Canvia a l'espai de treball 3" -#: ../src/core/screen.c:828 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "La pantalla %d en la visualització «%s» ja té un gestor de finestres\n" +#: data/50-mutter-navigation.xml:123 +msgid "Switch to workspace 4" +msgstr "Canvia a l'espai de treball 4" -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "No s'ha pogut alliberar la pantalla %d en la visualització «%s»\n" +#: data/50-mutter-navigation.xml:126 +msgid "Switch to last workspace" +msgstr "Canvia a l'últim espai de treball" -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "No s'ha pogut crear el directori «%s»: %s\n" +#: data/50-mutter-navigation.xml:129 +msgid "Move to workspace left" +msgstr "Mou a l'espai de treball de l'esquerra" -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "No s'ha pogut obrir el fitxer de sessió «%s» per a l'escriptura: %s\n" +#: data/50-mutter-navigation.xml:132 +msgid "Move to workspace right" +msgstr "Mou a l'espai de treball de la dreta" -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "S'ha produït un error en escriure el fitxer de sessió «%s»: %s\n" +#: data/50-mutter-navigation.xml:135 +msgid "Move to workspace above" +msgstr "Mou a l'espai de treball de sobre" -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "S'ha produït un error en tancar el fitxer de sessió «%s»: %s\n" +#: data/50-mutter-navigation.xml:138 +msgid "Move to workspace below" +msgstr "Mou a l'espai de treball de sota" -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "No s'ha pogut analitzar el fitxer de sessió alçat: %s\n" +#: data/50-mutter-system.xml:6 +msgid "System" +msgstr "Sistema" -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "" -"S'ha vist l'atribut <muffin_session> però encara hi ha l'identificador de " -"sessió" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Mostra l'indicador d'execució d'aplicacions" -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Atribut %s desconegut a l'element <%s>" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Mostra la vista general d'activitats" -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "etiqueta <window> imbricada" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Finestres" -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "Element %s desconegut" +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "Activa el menú de finestra" -#: ../src/core/session.c:1809 -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" -"Estes finestres no implementen «alça la configuració actual» i s'hauran de " -"reiniciar manualment la pròxima vegada que entreu." +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Canvia entre el mode a pantalla completa" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "No s'ha pogut obrir el registre de depuració: %s\n" +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "Canvia l'estat de maximització" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "No s'ha pogut executar fdopen() sobre el fitxer de registre %s: %s\n" +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "Maximitza la finestra" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "S'ha obert el fitxer de registre %s\n" +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Restaura la finestra" -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "Muffin es va compilar sense compatibilitat per al mode detallat\n" +#: data/50-mutter-windows.xml:18 +msgid "Toggle shaded state" +msgstr "Canvia l'estat d'ombrejat" -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "Gestor de finestres: " +#: data/50-mutter-windows.xml:20 +msgid "Close window" +msgstr "Tanca la finestra" -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "Error en el gestor de finestres: " +#: data/50-mutter-windows.xml:22 +msgid "Hide window" +msgstr "Oculta la finestra" -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "Avís del gestor de finestres: " +#: data/50-mutter-windows.xml:24 +msgid "Move window" +msgstr "Mou la finestra" -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "Error del gestor de finestres: " +#: data/50-mutter-windows.xml:26 +msgid "Resize window" +msgstr "Redimensiona la finestra" -#. first time through -#: ../src/core/window.c:7269 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"La finestra %s estableix SM_CLIENT_ID en ella mateixa, en comptes del " -"WM_CLIENT_LEADER, tal com s'especifica a ICCCM.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7932 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size " -"%d x %d and max size %d x %d; this doesn't make much sense.\n" +#: data/50-mutter-windows.xml:29 +msgid "Toggle window on all workspaces or one" msgstr "" -"La finestra %s estableix un consell MWM que indica que no és " -"redimensionable, però estableix una mida mínima %d x %d i una mida màxima %d " -"x %d; açò no té massa sentit.\n" +"Canvia la funció que fa que la finestra estiga en tots els espais de " +"treball o només en un" -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "L'aplicació ha definit un _NET_WM_PID %lu fals\n" +#: data/50-mutter-windows.xml:31 +msgid "Raise window if covered, otherwise lower it" +msgstr "Alça la finestra si està coberta per una altra; altrament, baixa-la" -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (a %s)" +#: data/50-mutter-windows.xml:33 +msgid "Raise window above other windows" +msgstr "Alça la finestra per damunt de les altres" -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "" -"WM_TRANSIENT_FOR no vàlid per a la finestra 0x%lx especificat per a %s.\n" +#: data/50-mutter-windows.xml:35 +msgid "Lower window below other windows" +msgstr "Baixa la finestra sota les altres" -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "WM_TRANSIENT_FOR per a la finestra 0x%lx per a %s crearia un bucle.\n" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window vertically" +msgstr "Maximitza la finestra verticalment" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"La finestra 0x%lx té la propietat %s\n" -"que s'esperava tinguera el tipus %s format %d\n" -"i actualment té el tipus %s format %d n elements %d.\n" -"És molt possible que siga un error en l'aplicació, no pas del gestor de " -"finestres.\n" -"La finestra té el títol=«%s» classe=«%s» nom=«%s»\n" -"\n" - -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "La propietat %s en la finestra 0x%lx contenia un UTF-8 no vàlid\n" +#: data/50-mutter-windows.xml:39 +msgid "Maximize window horizontally" +msgstr "Maximitza la finestra horitzontalment" -#: ../src/core/xprops.c:494 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"La propietat %s en la finestra 0x%lx contenia caràcters UTF-8 no vàlids per " -"a l'element %d en la llista\n" +#: data/50-mutter-windows.xml:43 +msgid "View split on left" +msgstr "Mostra la partició a l'esquerra" + +#: data/50-mutter-windows.xml:47 +msgid "View split on right" +msgstr "Mostra la partició a la dreta" -#: ../src/muffin.desktop.in.h:1 ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 +#: data/org.gnome.mutter.gschema.xml.in:7 msgid "Modifier to use for extended window management operations" msgstr "" "Modificador que s'utilitzarà per les operacions ampliades de gestió de " "finestres" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 +#: data/org.gnome.mutter.gschema.xml.in:8 msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." -msgstr "" -"Esta tecla iniciarà l'«overlay» (superposador), el qual és una combinació de " -"visualització de finestres i sistema de llançament d'aplicacions. El valor " -"predeterminat és la «tecla Windows» en maquinari basat en ordinadors PC. El " -"valor d'esta vinculació s'espera que siga el predeterminat o text en blanc." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." +msgstr "" +"Esta tecla iniciarà l'«overlay» (superposador), el qual és una combinació " +"de visualització de finestres i sistema de llançament d'aplicacions. El " +"valor predeterminat és la «tecla Windows» en maquinari basat en ordinadors " +"PC. El valor d'esta vinculació s'espera que siga el predeterminat o text " +"en blanc." + +#: data/org.gnome.mutter.gschema.xml.in:20 msgid "Attach modal dialogs" msgstr "Adjunta els diàlegs modals" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 +#: data/org.gnome.mutter.gschema.xml.in:21 msgid "" "When true, instead of having independent titlebars, modal dialogs appear " "attached to the titlebar of the parent window and are moved together with " @@ -434,54 +303,42 @@ msgstr "" "diàlegs modals apareixeran adjuntats a la barra de títol de la finestra mare " "i es mouran juntament amb esta." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -msgid "Live Hidden Windows" -msgstr "Finestres ocultes en viu" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"Determina si les finestres ocultes (és a dir, les finestres minimitzades i " -"les finestres en altres espais de treball) s'han de mantindre en viu." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 +#: data/org.gnome.mutter.gschema.xml.in:30 msgid "Enable edge tiling when dropping windows on screen edges" msgstr "" -"Habilita la tesselització a les vores en deixar anar les finestres a les " +"Habilita la tessel·lització a les vores en deixar anar les finestres a les " "vores de la pantalla" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 +#: data/org.gnome.mutter.gschema.xml.in:31 msgid "" "If enabled, dropping windows on vertical screen edges maximizes them " "vertically and resizes them horizontally to cover half of the available " "area. Dropping windows on the top screen edge maximizes them completely." msgstr "" -"So s'habilita, es maximitzaran les finestres verticalment i es " +"Si s'habilita, es maximitzaran les finestres verticalment i es " "redimensionaran horitzontalment per cobrir la meitat de l'àrea disponible en " "deixar-les anar a les vores verticals de la pantalla. Si es deixen anar a la " "vora superior de la pantalla es maximitzaran completament." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 +#: data/org.gnome.mutter.gschema.xml.in:40 msgid "Workspaces are managed dynamically" msgstr "Els espais de treball es gestionen dinàmicament" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 +#: data/org.gnome.mutter.gschema.xml.in:41 msgid "" -"Determines whether workspaces are managed dynamically or whether there's a " +"Determines whether workspaces are managed dynamically or whether there’s a " "static number of workspaces (determined by the num-workspaces key in org." "gnome.desktop.wm.preferences)." msgstr "" "Determina si els espais de treball es gestionen dinàmicament o hi ha un " -"nombre determinat d'espais de treball (determinat per la clau num-workspaces " -"a org.cinnamon.desktop.wm.preferences)." +"nombre determinat d'espais de treball (determinat per la clau «num-" +"workspaces» a «org.gnome.desktop.wm.preferences»)." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 +#: data/org.gnome.mutter.gschema.xml.in:50 msgid "Workspaces only on primary" msgstr "Espais de treball només en el primari" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 +#: data/org.gnome.mutter.gschema.xml.in:51 msgid "" "Determines whether workspace switching should happen for windows on all " "monitors or only for windows on the primary monitor." @@ -489,11 +346,11 @@ msgstr "" "Determina si el canvi d'espai de treball hauria de ser per les finestres en " "tots els monitors o només en les finestres del monitor primari." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 +#: data/org.gnome.mutter.gschema.xml.in:59 msgid "No tab popup" msgstr "Sense finestres emergents a les pestanyes" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 +#: data/org.gnome.mutter.gschema.xml.in:60 msgid "" "Determines whether the use of popup and highlight frame should be disabled " "for window cycling." @@ -501,3423 +358,818 @@ msgstr "" "Determina si s'ha d'inhabilitar el quadre que es mostra a les finestres " "emergents i ressaltades en commutar entre finestres." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 -msgid "Draggable border width" -msgstr "Amplada del contorn arrossegable" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 -msgid "" -"The amount of total draggable borders. If the theme's visible borders are " -"not enough, invisible borders will be added to meet this value." -msgstr "" -"La quantitat total de contorn arrossegable. Si els contorns visibles del " -"tema no són suficients, s'afegiran contorns invisibles per aconseguir este " -"valor." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:17 -msgid "Select window from tab popup" -msgstr "Selecció de finestra entre les emergents d'una pestanya" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:18 -msgid "Cancel tab popup" -msgstr "Cancel·lació de les finestres emergents a les pestanyes" - -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "Forma d'ús: %s\n" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "Mi_nimitza" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "Ma_ximitza" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "Desma_ximitza" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "_Enrotlla" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "Desenro_tlla" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "_Mou" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "_Redimensiona" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "Mou la _barra de títol en pantalla" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "Sempre per _damunt" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "Sempre a l'espai de treball _visible" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "Només en _este espai de treball" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "Mou a l'espai de treball de l'es_querra" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "Mou a l'espai de treball de la _dreta" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "Mou a l'espai de treball de _sobre" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "Mou a l'espai de treball de s_ota" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "_Tanca" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "Espai de treball %d%n" - -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "Espai de treball 1_0" - -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "Espai de treball %s%d" - -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "Mou a un altre es_pai de treball" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Maj" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hiper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" - -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" - -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "superior" - -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "inferior" - -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "esquerra" - -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "dreta" - -#: ../src/ui/theme.c:286 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "la geometria del marc no especifica la dimensió «%s»" - -#: ../src/ui/theme.c:305 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "" -"la geometria del marc no especifica la dimensió «%s» per al contorn «%s»" - -#: ../src/ui/theme.c:342 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "El ràtio d'aspecte dels botons %g no és raonable" - -#: ../src/ui/theme.c:354 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "La geometria del marc no especifica la mida dels botons" - -#: ../src/ui/theme.c:1067 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "Els degradats han de tindre almenys dos colors" - -#: ../src/ui/theme.c:1219 -#, c-format -msgid "" -"GTK custom color specification must have color name and fallback in " -"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" -msgstr "" -"L'especificació personalitzada de color de GTK ha de tindre un nom de color " -"i un alternatiu en parèntesis, p.e. gtk:personalitzat(foo,bar); no s'ha " -"pogut analitzar «%s»" - -#: ../src/ui/theme.c:1235 -#, c-format -msgid "" -"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" -"_ are valid" -msgstr "" -"El caràcter «%c» no és vàlid en el paràmetre color_name de gtk:" -"personalitzat, només són vàlids A-Za-z0-9-_" - -#: ../src/ui/theme.c:1249 -#, c-format -msgid "" -"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " -"fit the format" -msgstr "" -"El format de Gtk:personalitzat és «gtk:personalitzat(color_name," -"alternatiu)», «%s» no s'ajusta al format" - -#: ../src/ui/theme.c:1294 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"L'especificació de color GTK ha de tindre l'estat entre claudàtors, p.e. gtk:" -"fg[NORMAL] on NORMAL és l'estat; no s'ha pogut analitzar \"%s\"" - -#: ../src/ui/theme.c:1308 -#, c-format -msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"L'especificació de color GTK ha de tindre un claudàtor de tancament després " -"de l'estat, p.e. gtk:fg[NORMAL] on NORMAL és l'estat; no s'ha pogut " -"analitzar «%s»" - -#: ../src/ui/theme.c:1319 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "No s'entén l'estat «%s» en l'especificació del color" - -#: ../src/ui/theme.c:1332 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "No s'entén l'element de color «%s» en l'especificació del color" - -#: ../src/ui/theme.c:1361 -#, c-format -msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" -msgstr "" -"El format de barreja és «blend/bg_color/fg_color/alpha», «%s» no s'ajusta al " -"format" - -#: ../src/ui/theme.c:1372 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "No s'ha pogut analitzar el valor d'opacitat «%s» en el color barrejat" - -#: ../src/ui/theme.c:1382 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "El valor alfa «%s» en el color barrejat no està entre 0,0 i 1,0" - -#: ../src/ui/theme.c:1429 -#, c-format -msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "" -"El format d'ombrejat és «shade/base_color/factor», «%s» no s'ajusta al format" - -#: ../src/ui/theme.c:1440 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "No s'ha pogut analitzar el factor d'ombrejat «%s» en el color ombrejat" - -#: ../src/ui/theme.c:1450 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "El factor d'ombrejat «%s» en el color ombrejat és negatiu" - -#: ../src/ui/theme.c:1479 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "No s'ha pogut analitzar el color «%s»" - -#: ../src/ui/theme.c:1790 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "L'expressió coordinada conté el caràcter '%s', el qual no és permés" - -#: ../src/ui/theme.c:1817 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "" -"L'expressió coordinada conté el número '%s' de punt flotant el qual no es " -"pot analitzar" - -#: ../src/ui/theme.c:1831 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "L'expressió coordinada conté l'enter '%s' el qual no es pot analitzar" - -#: ../src/ui/theme.c:1953 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "" -"L'expressió coordinada conté un operador desconegut a l'inici d'este text: " -"«%s»" - -#: ../src/ui/theme.c:2010 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "L'expressió coordinada estava buida o no s'ha entés" - -#: ../src/ui/theme.c:2121 ../src/ui/theme.c:2131 ../src/ui/theme.c:2165 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "L'expressió coordinada dóna una divisió per zero" - -#: ../src/ui/theme.c:2173 -#, c-format -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "" -"L'expressió coordinada intenta utilitzar l'operador de mode en un número de " -"punt flotant" - -#: ../src/ui/theme.c:2229 -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "" -"L'expressió coordinada té un operador «%s» on hi hauria d'anar un operand" - -#: ../src/ui/theme.c:2238 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "L'expressió coordinada té un operand on hi hauria d'anar un operador" - -#: ../src/ui/theme.c:2246 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "" -"L'expressió coordinada ha finalitzat amb un operador en lloc d'un operand" - -#: ../src/ui/theme.c:2256 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" -"L'expressió coordinada té un operador «%c» seguit de l'operador «%c» sense " -"cap operand enmig" - -#: ../src/ui/theme.c:2407 ../src/ui/theme.c:2452 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "L'expressió coordinada té una variable o constant desconeguda «%s»" - -#: ../src/ui/theme.c:2506 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "" -"L'analitzador d'expressions de coordinades ha desbordat la seua memòria " -"intermèdia." - -#: ../src/ui/theme.c:2535 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "L'expressió coordinada té un parèntesi de tancament i cap d'obertura" - -#: ../src/ui/theme.c:2599 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "L'expressió coordinada té un parèntesi d'obertura i cap de tancament" - -#: ../src/ui/theme.c:2610 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "L'expressió coordinada no pareix tindre cap operador o operand" - -#: ../src/ui/theme.c:2822 ../src/ui/theme.c:2842 ../src/ui/theme.c:2862 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "El tema conté una expressió que ha provocat un error: %s\n" - -#: ../src/ui/theme.c:4533 -#, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"qualsevol\"/> s'ha " -"d'especificar per a este estil de marc" - -#: ../src/ui/theme.c:5066 ../src/ui/theme.c:5091 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" -"No s'ha trobat <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=" -"\"qualsevol\"/>" - -#: ../src/ui/theme.c:5139 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "No s'ha pogut carregar el tema \"%s\": %s\n" - -#: ../src/ui/theme.c:5275 ../src/ui/theme.c:5282 ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 ../src/ui/theme.c:5303 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "No s'ha definit <%s> per al tema «%s»" - -#: ../src/ui/theme.c:5311 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" -"No s'ha definit cap estil de marc per al tipus de finestra \"%s\" en el tema " -"\"%s\", afegiu un element <window type=\"%s\" style_set=\"qualsevol\"/>" - -#: ../src/ui/theme.c:5709 ../src/ui/theme.c:5771 ../src/ui/theme.c:5834 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" -"Les constants de la definició d'usuari han de començar per una majúscula; " -"«%s» no ho és" - -#: ../src/ui/theme.c:5717 ../src/ui/theme.c:5779 ../src/ui/theme.c:5842 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "La constant «%s» ja s'ha definit" - -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. -#. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "No hi ha cap atribut «%s» a l'element <%s>" - -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Línia %d caràcter %d: %s" - -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "S'ha repetit l'atribut «%s» dues vegades en el mateix element <%s>" - -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "L'atribut «%s» no és vàlid per a l'element <%s> en este context" - -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "No s'ha pogut analitzar «%s» com a enter" - -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "No s'entenen els caràcters finals «%s» de la cadena «%s»" - -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "L'enter %ld ha de ser positiu" - -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "L'enter %ld és massa gran, el màxim actual és %d" - -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "No s'ha pogut analitzar «%s» com a un número de coma flotant" - -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "Els valors booleans han de ser «true» (cert) o «false» (fals), no «%s»" - -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "L'angle ha d'estar entre 0.0 i 360.0, era %g\n" - -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" -"L'opacitat ha d'estar entre 0.0 (invisible) i 1.0 (totalment opac), era a " -"%g\n" - -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"Escala de títol no vàlida «%s» (ha de ser una d'estes: xx-small, x-small, " -"small, medium, large, x-large o xx-large)\n" - -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s> amb nom «%s» s'ha utilitzat dues vegades" - -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "el pare de <%s>, «%s», no s'ha definit" - -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "la geometria de <%s>, «%s», no s'ha definit" - -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "" -"<%s> ha d'especificar bé una geometria o un pare que tinga una geometria" - -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "El valor alfa requereix que també s'especifique un fons de pantalla" - -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Tipus desconegut «%s» en l'element <%s>" - -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "style_set «%s» desconegut en l'element <%s>" - -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "El tipus de finestra «%s» ja té assignat un joc d'estil" - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "No es permet l'element <%s> sota <%s>" - -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" -msgstr "" -"No es pot especificar «button_width»/«button_height» i l'«aspect_ratio» a la " -"vegada per als botons" - -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "La distància «%s» és desconeguda" - -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "La relació d'aspecte «%s» és desconeguda" - -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "El contorn «%s» és desconegut" - -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "No hi ha cap atribut de «start_angle» o «from» en l'element <%s>" - -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "No hi ha cap atribut de «extent_angle» o «to» en l'element <%s>" - -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "No s'entén el valor «%s» per al tipus de degradat" - -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "No s'entén el tipus de farciment «%s» per a l'element <%s>" - -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "No s'entén l'estat «%s» per a l'element <%s>" - -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "No s'entén l'ombra «%s» per a l'element <%s>" - -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "No s'entén la fletxa «%s» per a l'element <%s>" - -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "No s'ha definit cap <draw_ops> amb el nom «%s»" - -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "La inclusió de draw_ops «%s» ací crearà una referència circular" - -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Posició «%s» desconeguda per a la peça del marc" - -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "L'estil del marc ja té una peça a posició %s" - -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "No s'ha definit cap <draw_ops> amb el nom «%s»" - -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Funció «%s» desconeguda per al botó" - -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "" -"La funció de botó «%s» no existeix en esta versió (%d, es necessita %d)" - -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Estat «%s» desconegut per al botó" - -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "L'estil del marc ja té un botó per a l'estat %s de la funció %s" - -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "«%s» no és un valor vàlid per a l'atribut del focus" - -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "«%s» no és un valor vàlid per a l'atribut de l'estat" - -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "No s'ha definit un estil amb el nom «%s»" - -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "«%s» no és un valor vàlid per a l'atribut de redimensiona" - -#: ../src/ui/theme-parser.c:3147 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" -"No hauria de tindre l'atribut «resize» en l'element <%s> per als estats " -"maximitzat/ombrejat" - -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "" -"No hauria de tindre l'atribut «resize» en l'element <%s> per als estats " -"maximitzats" - -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "L'estil ja s'ha especificat per a l'estat %s redimensiona %s focus %s" - -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "L'estil ja s'ha especificat per a l'estat %s focus %s" - -#: ../src/ui/theme-parser.c:3294 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"No es poden tindre dos draw_ops per a un element <piece> (el tema ha " -"especificat un atribut draw_ops i també un element <draw_ops>, o ha " -"especificat ambdós elements) " - -#: ../src/ui/theme-parser.c:3332 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"No es poden tindre dos draw_ops per a un element <button> (el tema ha " -"especificat un atribut draw_ops i també un element <draw_ops>, o ha " -"especificat ambdós elements)" - -#: ../src/ui/theme-parser.c:3370 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"No es poden tindre dos draw_ops per a un element <menu_icon> (el tema ha " -"especificat un atribut draw_ops i també un element <draw_ops>, o ha " -"especificat ambdós elements)" - -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "Especificació de versió errònia («%s»)" - -#: ../src/ui/theme-parser.c:3507 -msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" -msgstr "" -"L'atribut «version» no es pot utilitzat als fitxers metacity-theme-1.xml o " -"metacity-theme-2.xml" - -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "" -"El tema requereix la versió %s, però la darrera versió compatible del tema " -"és la %d.%d" - -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "L'element més extern en el tema ha de ser <metacity_theme>, no <%s>" - -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "" -"L'element <%s> no és permés dins d'un element name/author/date/description" - -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "L'element <%s> no és permés dins d'un element <constant>" - -#: ../src/ui/theme-parser.c:3599 -#, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "" -"L'element <%s> no és permés dins d'un element distance/border/aspect_ratio" - -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "L'element <%s> no és permés dins d'un element d'operació igual" - -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "L'element <%s> no és permés dins d'un element <%s>" - -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "No s'ha proveït cap draw_ops per a la peça del marc" - -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "No s'ha proveït cap draw_ops per al botó" - -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "No es permet cap text dins de l'element <%s>" - -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "S'ha especificat <%s> dues vegades per a este tema" - -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "No s'ha trobat un fitxer vàlid per al tema %s\n" - -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "_Finestres" - -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "_Diàleg" - -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "Diàleg _modal" - -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "_Eina" - -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "_Pantalla flaix" - -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "Acoblador _superior" - -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "Acoblador _inferior" - -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "Acoblador es_querre" - -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "Acoblador d_ret" - -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "_Tots els acobladors" - -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "Escr_iptori" - -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "Obri una altra d'estes finestres" - -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "Este és un botó de prova amb una icona «obri»" - -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "Este és un botó de prova amb una icona de «ix»" - -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "Este és un exemple de missatge en un diàleg d'exemple" - -#: ../src/ui/theme-viewer.c:328 -#, c-format -msgid "Fake menu item %d\n" -msgstr "Element fals de menú %d\n" - -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "Finestra amb només contorn" - -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "Barra" - -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "Finestra d'aplicació normal" - -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "Caixa de diàleg" - -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "Caixa de diàleg modal" - -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "Paleta d'utilitat" - -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "Menú arrossegable" - -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "Contorn" - -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "Diàleg modal adjuntat" - -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "Prova de disposició de botons %d" - -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g mil·lisegons per dibuixar un marc de finestra" - -#: ../src/ui/theme-viewer.c:813 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Forma d'ús: metacity-theme-viewer [NOMDELTEMA]\n" - -#: ../src/ui/theme-viewer.c:820 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "S'ha produït un error en carregar el tema: %s\n" - -#: ../src/ui/theme-viewer.c:826 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "S'ha carregat el tema «%s» en %g segons\n" - -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "Tipus de lletra per a títol normal" - -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "Tipus de lletra per a títol petit" - -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "Tipus de lletra per a títol gran" - -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "Disposicions de botons" - -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "Test de referència" - -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "El títol de la finestra va ací" - -#: ../src/ui/theme-viewer.c:1047 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"S'han dibuixat %d marcs en %g segons del client (%g mil·lisegons per marc) i " -"%g segons de rellotge inclosos els recursos del servidor d'X (%g " -"mil·lisegons per marc)\n" - -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "La prova d'expressió de posició ha tornat TRUE però ha establit error" - -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "" -"La prova d'expressió de posició ha tornat FALSE però no ha establit error" - -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "S'esperava un error però no s'ha donat cap" - -#: ../src/ui/theme-viewer.c:1274 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "S'esperava l'error %d però s'ha donat %d" - -#: ../src/ui/theme-viewer.c:1280 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "No s'esperava cap error però s'ha tornat un: %s" - -#: ../src/ui/theme-viewer.c:1284 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "El valor x ha sigut %d, i s'esperava %d" - -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "El valor y ha sigut %d, i s'esperava %d" - -#: ../src/ui/theme-viewer.c:1352 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "" -"%d expressions de coordenades analitzades en %g segons (%g segons de mitja)\n" - -#~ msgid "Close Window" -#~ msgstr "Tanca la finestra" - -#~ msgid "Window Menu" -#~ msgstr "Menú de la finestra" - -#~ msgid "Minimize Window" -#~ msgstr "Minimitza la finestra" - -#~ msgid "Maximize Window" -#~ msgstr "Maximitza la finestra" - -#~ msgid "Restore Window" -#~ msgstr "Restaura la finestra" - -#~ msgid "Roll Up Window" -#~ msgstr "Enrotlla la finestra" - -#~ msgid "Unroll Window" -#~ msgstr "Desenrotlla la finestra" - -#~ msgid "Keep Window On Top" -#~ msgstr "Mantén la finestra per damunt" - -#~ msgid "Remove Window From Top" -#~ msgstr "Treu la finestra de damunt" - -#~ msgid "Always On Visible Workspace" -#~ msgstr "Sempre a l'espai de treball visible" - -#~ msgid "Put Window On Only One Workspace" -#~ msgstr "Posa la finestra només a un espai de treball" - -#~ msgid "Switch to workspace 1" -#~ msgstr "Canvia a l'espai de treball 1" - -#~ msgid "Switch to workspace 2" -#~ msgstr "Canvia a l'espai de treball 2" - -#~ msgid "Switch to workspace 3" -#~ msgstr "Canvia a l'espai de treball 3" - -#~ msgid "Switch to workspace 4" -#~ msgstr "Canvia a l'espai de treball 4" - -#~ msgid "Switch to workspace 5" -#~ msgstr "Canvia a l'espai de treball 5" - -#~ msgid "Switch to workspace 6" -#~ msgstr "Canvia a l'espai de treball 6" - -#~ msgid "Switch to workspace 7" -#~ msgstr "Canvia a l'espai de treball 7" - -#~ msgid "Switch to workspace 8" -#~ msgstr "Canvia a l'espai de treball 8" - -#~ msgid "Switch to workspace 9" -#~ msgstr "Canvia a l'espai de treball 9" - -#~ msgid "Switch to workspace 10" -#~ msgstr "Canvia a l'espai de treball 10" - -#~ msgid "Switch to workspace 11" -#~ msgstr "Canvia a l'espai de treball 11" - -#~ msgid "Switch to workspace 12" -#~ msgstr "Canvia a l'espai de treball 12" - -#~ msgid "Switch to workspace on the left of the current workspace" -#~ msgstr "Canvia a l'espai de treball de l'esquerra de l'actual" - -#~ msgid "Switch to workspace on the right of the current workspace" -#~ msgstr "Canvia a l'espai de treball a la dreta de l'actual" - -#~ msgid "Switch to workspace above the current workspace" -#~ msgstr "Canvia a l'espai de treball damunt de l'actual" - -#~ msgid "Switch to workspace below the current workspace" -#~ msgstr "Canvia a l'espai de treball a sota de l'actual" - -#~ msgid "Move between windows of an application, using a popup window" -#~ msgstr "Mou-te entre finestres d'una aplicació amb un diàleg emergent" - -#~ msgid "" -#~ "Move backward between windows of an application, using a popup window" -#~ msgstr "" -#~ "Mou-te cap enrere entre finestres d'una aplicació amb un diàleg emergent" - -#~ msgid "Move between windows, using a popup window" -#~ msgstr "Mou-te entre finestres amb un diàleg emergent" - -#~ msgid "Move backward between windows, using a popup window" -#~ msgstr "Mou-te cap enrere entre finestres amb un diàleg emergent" - -#~ msgid "Move between panels and the desktop, using a popup window" -#~ msgstr "Mou-te entre quadres i l'escriptori amb un diàleg emergent" - -#~ msgid "Move backward between panels and the desktop, using a popup window" -#~ msgstr "" -#~ "Mou-te cap enrere entre quadres i l'escriptori amb un diàleg emergent" - -#~ msgid "Move between windows of an application immediately" -#~ msgstr "Mou-te entre les finestres d'una aplicació immediatament" - -#~ msgid "Move backward between windows of an application immediately" -#~ msgstr "Mou-te cap enrere entre les finestres d'una aplicació immediatament" - -#~ msgid "Move between windows immediately" -#~ msgstr "Mou-te entre finestres immediatament" - -#~ msgid "Move backward between windows immediately" -#~ msgstr "Mou-te cap enrere entre finestres immediatament" - -#~ msgid "Move between panels and the desktop immediately" -#~ msgstr "Mou entre quadres i l'escriptori immediatament" - -#~ msgid "Move backward between panels and the desktop immediately" -#~ msgstr "Mou cap enrere entre quadres i l'escriptori immediatament" - -#~ msgid "Hide all normal windows and set focus to the desktop" -#~ msgstr "Oculta totes les finestres normals i dóna el focus a l'escriptori" - -#~ msgid "Show the panel's main menu" -#~ msgstr "Mostra el menú principal del quadre" - -#~ msgid "Show the panel's \"Run Application\" dialog box" -#~ msgstr "Mostra el diàleg d'execució d'aplicacions del quadre" - -#~ msgid "Start or stop recording the session" -#~ msgstr "Inicia o atura l'enregistrament de la sessió" - -#~ msgid "Take a screenshot" -#~ msgstr "Fes una captura de pantalla" - -#~ msgid "Take a screenshot of a window" -#~ msgstr "Fes una captura de pantalla d'una finestra" - -#~ msgid "Run a terminal" -#~ msgstr "Executa un terminal" - -#~ msgid "Activate the window menu" -#~ msgstr "Activa el menú de finestra" - -#~ msgid "Toggle fullscreen mode" -#~ msgstr "Si s'utilitza el mode a pantalla completa" - -#~ msgid "Toggle maximization state" -#~ msgstr "Canvia l'estat de maximització" - -#~ msgid "Toggle whether a window will always be visible over other windows" -#~ msgstr "" -#~ "Commuta la funció que fa que una finestra sempre serà visible per sobre " -#~ "de les altres" - -#~ msgid "Maximize window" -#~ msgstr "Maximitza la finestra" - -#~ msgid "Restore window" -#~ msgstr "Restaura la finestra" - -#~ msgid "Toggle shaded state" -#~ msgstr "Canvia l'estat d'ombrejat" - -#~ msgid "Minimize window" -#~ msgstr "Minimitza la finestra" - -#~ msgid "Close window" -#~ msgstr "Tanca la finestra" - -#~ msgid "Move window" -#~ msgstr "Mou la finestra" - -#~ msgid "Resize window" -#~ msgstr "Redimensiona la finestra" - -#~ msgid "Toggle whether window is on all workspaces or just one" -#~ msgstr "" -#~ "Commuta la funció que fa que la finestra estigui en tots els espais de " -#~ "treball o només en un" - -#~ msgid "Move window to workspace 1" -#~ msgstr "Mou la finestra a l'espai de treball 1" - -#~ msgid "Move window to workspace 2" -#~ msgstr "Mou la finestra a l'espai de treball 2" - -#~ msgid "Move window to workspace 3" -#~ msgstr "Mou la finestra a l'espai de treball 3" - -#~ msgid "Move window to workspace 4" -#~ msgstr "Mou la finestra a l'espai de treball 4" - -#~ msgid "Move window to workspace 5" -#~ msgstr "Mou la finestra a l'espai de treball 5" - -#~ msgid "Move window to workspace 6" -#~ msgstr "Mou la finestra a l'espai de treball 6" - -#~ msgid "Move window to workspace 7" -#~ msgstr "Mou la finestra a l'espai de treball 7" - -#~ msgid "Move window to workspace 8" -#~ msgstr "Mou la finestra a l'espai de treball 8" - -#~ msgid "Move window to workspace 9" -#~ msgstr "Mou la finestra a l'espai de treball 9" - -#~ msgid "Move window to workspace 10" -#~ msgstr "Mou la finestra a l'espai de treball 10" - -#~ msgid "Move window to workspace 11" -#~ msgstr "Mou la finestra a l'espai de treball 11" - -#~ msgid "Move window to workspace 12" -#~ msgstr "Mou la finestra a l'espai de treball 12" - -#~ msgid "Move window one workspace to the left" -#~ msgstr "Mou la finestra un espai de treball a l'esquerra" - -#~ msgid "Move window one workspace to the right" -#~ msgstr "Mou la finestra un espai de treball a la dreta" - -#~ msgid "Move window one workspace up" -#~ msgstr "Mou la finestra un espai de treball amunt" - -#~ msgid "Move window one workspace down" -#~ msgstr "Mou la finestra un espai de treball avall" - -#~ msgid "Raise window if it's covered by another window, otherwise lower it" -#~ msgstr "Alça una finestra coberta per una altra, o sinó la baixa" - -#~ msgid "Raise window above other windows" -#~ msgstr "Alça una finestra per damunt de les altres" - -#~ msgid "Lower window below other windows" -#~ msgstr "Baixa la finestra sota les altres" - -#~ msgid "Maximize window vertically" -#~ msgstr "Maximitza la finestra verticalment" - -#~ msgid "Maximize window horizontally" -#~ msgstr "Maximitza la finestra horitzontalment" - -#~ msgid "Move window to north-west (top left) corner" -#~ msgstr "Mou la finestra a la cantonada nord-oest (part superior esquerra)" - -#~ msgid "Move window to north-east (top right) corner" -#~ msgstr "Mou la finestra a la cantonada nord-est (part superior dreta)" - -#~ msgid "Move window to south-west (bottom left) corner" -#~ msgstr "Mou la finestra a la cantonada sud-oest (part inferior esquerra)" - -#~ msgid "Move window to south-east (bottom right) corner" -#~ msgstr "Mou la finestra a la cantonada sud-est (part inferior dreta)" - -#~ msgid "Move window to north (top) side of screen" -#~ msgstr "Mou la finestra a la part nord (superior) de la pantalla" - -#~ msgid "Move window to south (bottom) side of screen" -#~ msgstr "Mou la finestra a la part del sud (inferior) de la pantalla" - -#~ msgid "Move window to east (right) side of screen" -#~ msgstr "Mou la finestra a la part est (dreta) de la pantalla" - -#~ msgid "Move window to west (left) side of screen" -#~ msgstr "Mou la finestra a la part oest (esquerra) de la pantalla" - -#~ msgid "Move window to center of screen" -#~ msgstr "Mou la finestra al centre de la pantalla" - -#~ msgid "" -#~ "There was an error running <tt>%s</tt>:\n" -#~ "\n" -#~ "%s" -#~ msgstr "" -#~ "S'ha produït un error en executar <tt>%s</tt>:\n" -#~ "\n" -#~ "%s." - -#~ msgid "No command %d has been defined.\n" -#~ msgstr "No s'ha definit cap ordre %d.\n" - -#~ msgid "No terminal command has been defined.\n" -#~ msgstr "No s'ha definit cap ordre de terminal.\n" - -#~ msgid "GConf key '%s' is set to an invalid value\n" -#~ msgstr "La clau «%s» del GConf està establerta a un valor no vàlid\n" - -#~ msgid "%d stored in GConf key %s is out of range %d to %d\n" -#~ msgstr "" -#~ "%d, emmagatzemat a la clau %s del GConf, està fora de l'interval de %d a " -#~ "%d\n" - -#~ msgid "GConf key \"%s\" is set to an invalid type\n" -#~ msgstr "La clau «%s» del GConf està establerta a un tipus no vàlid\n" - -#~ msgid "GConf key %s is already in use and can't be used to override %s\n" -#~ msgstr "" -#~ "La clau %s del GConf ja s'està utilitzant i no es pot fer servir per " -#~ "sobreescriure %s\n" - -#~ msgid "Can't override GConf key, %s not found\n" -#~ msgstr "No es pot sobreescriure la clau del GConf; no s'ha trobat %s\n" - -#~ msgid "Error setting number of workspaces to %d: %s\n" -#~ msgstr "" -#~ "S'ha produït un error en establir el nombre d'espais de treball a %d: %s\n" - -#~ msgid "Error setting name for workspace %d to \"%s\": %s\n" -#~ msgstr "" -#~ "S'ha produït un error en establir el nom de l'espai de treball %d a «%s»: " -#~ "%s\n" - -#~ msgid "Error setting live hidden windows status status: %s\n" -#~ msgstr "" -#~ "S'ha produït un error en establir l'estat de les finestres ocultes en " -#~ "viu: %s\n" - -#~ msgid "Error setting no tab popup status: %s\n" -#~ msgstr "" -#~ "S'ha produït un error en establir l'estat de les pestanyes sense finestra " -#~ "emergent: %s\n" - -#~ msgid "" -#~ "Don't make fullscreen windows that are maximized and have no decorations" -#~ msgstr "" -#~ "No creïs finestres a pantalla completa que estiguin maximitzades i no " -#~ "tinguin decoracions" - -#~ msgid "Whether window popup/frame should be shown when cycling windows." -#~ msgstr "" -#~ "Si s'hauria de mostrar una finestra emergent o el seu marc en canviar en " -#~ "cicle entre finestres" - -#~ msgid "Internal argument for GObject introspection" -#~ msgstr "Argument intern per a la introspecció basada en el GObject" - -#~ msgid "Failed to restart: %s\n" -#~ msgstr "No s'ha pogut reiniciar: %s\n" - -#~ msgid "Error setting clutter plugin list: %s\n" -#~ msgstr "" -#~ "S'ha produït un error en establir la llista de connectors del Clutter: " -#~ "%s\n" - -#~ msgid "Clutter Plugins" -#~ msgstr "Connectors del Clutter" - -#~ msgid "Plugins to load for the Clutter-based compositing manager." -#~ msgstr "" -#~ "Connectors que s'han de carregar per al gestor de composició basat en el " -#~ "Clutter." - -#~ msgid "Window Management" -#~ msgstr "Gestor de finestres" - -#~ msgid "Failed to parse message \"%s\" from dialog process\n" -#~ msgstr "No s'ha pogut analitzar el missatge «%s» des del procés de diàleg\n" - -#~ msgid "Error reading from dialog display process: %s\n" -#~ msgstr "" -#~ "S'ha produït un error en llegir del procés de la pantalla de diàleg: %s\n" - -#~ msgid "" -#~ "Error launching metacity-dialog to ask about killing an application: %s\n" -#~ msgstr "" -#~ "S'ha produït un error en executar el diàleg metacity per preguntar quant " -#~ "a la \n" -#~ "finalització d'una aplicació: %s\n" - -#~ msgid "Failed to get hostname: %s\n" -#~ msgstr "" -#~ "S'ha produït un error en obtenir el nom de l'ordinador central: %s\n" - -#~ msgid "" -#~ "Lost connection to the display '%s';\n" -#~ "most likely the X server was shut down or you killed/destroyed\n" -#~ "the window manager.\n" -#~ msgstr "" -#~ "S'ha perdut la connexió amb la pantalla «%s»;\n" -#~ "és molt probable que el servidor X s'hagi aturat o que hagueu " -#~ "finalitzat/\n" -#~ "destruït el gestor de finestres.\n" - -#~ msgid "Fatal IO error %d (%s) on display '%s'.\n" -#~ msgstr "S'ha produït un error fatal d'E/S %d (%s) a la pantalla «%s».\n" - -#~ msgid "Turn compositing on" -#~ msgstr "Habilita la composició" - -#~ msgid "Turn compositing off" -#~ msgstr "Inhabilita la composició" - -#~ msgid "" -#~ "The format looks like \"<Control>a\" or <Shift><Alt>F1\".\n" -#~ "\n" -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "El format és «<Control>a» o «<Shift><Alt>F1».\n" -#~ "\n" -#~ "L'analitzador és prou flexible i permet minúscules i majúscules, i també " -#~ "abreviacions com «<Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena " -#~ "especial «disabled» (inhabilitat), no hi haurà cap vinculació per a " -#~ "aquesta acció." - -#~ msgid "" -#~ "The format looks like \"<Control>a\" or <Shift><Alt>F1\".\n" -#~ "\n" -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action.\n" -#~ "\n" -#~ "This keybinding may be reversed by holding down the \"shift\" key; " -#~ "therefore, \"shift\" cannot be one of the keys it uses." -#~ msgstr "" -#~ "El format és «<Control>a» o «<Shift><Alt>F1».\n" -#~ "\n" -#~ "L'analitzador és prou flexible i permet minúscules i majúscules, i també " -#~ "abreviacions com «<Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena " -#~ "especial «disabled», no hi haurà cap vinculació per a aquesta acció.\n" -#~ "\n" -#~ "Aquesta vinculació es pot invertir en prémer la tecla «Shift»; de manera " -#~ "que no es podrà utilitzar la tecla «Shift»." - -#~ msgid "Failed to read saved session file %s: %s\n" -#~ msgstr "No s'ha pogut llegir el fitxer de sessió «%s» desat: %s\n" - -#~ msgid "" -#~ "Error launching metacity-dialog to warn about apps that don't support " -#~ "session management: %s\n" -#~ msgstr "" -#~ "S'ha produït un error en executar el metacity-dialog per a avisar sobre " -#~ "aplicacions que no suporten la gestió de sessions: %s\n" - -#~ msgid "Metacity" -#~ msgstr "Metacity" - -#~ msgid "" -#~ "(Not implemented) Navigation works in terms of applications not windows" -#~ msgstr "" -#~ "(No implementat) La navegació funciona en termes d'aplicacions, no " -#~ "finestres" - -#~ msgid "" -#~ "A font description string describing a font for window titlebars. The " -#~ "size from the description will only be used if the titlebar_font_size " -#~ "option is set to 0. Also, this option is disabled if the " -#~ "titlebar_uses_desktop_font option is set to true." -#~ msgstr "" -#~ "Una cadena de descripció de tipus de lletra per a les barres de títol de " -#~ "les finestres. La mida de la descripció només s'utilitzarà si l'opció " -#~ "titlebar_font_size està establerta a 0. A més a més, aquesta opció està " -#~ "inhabilitada si titlebar_uses_desktop_font està establert és cert." - -#~ msgid "Action on title bar double-click" -#~ msgstr "Acció en fer doble clic en la barra de títol" - -#~ msgid "Action on title bar middle-click" -#~ msgstr "Acció en fer clic amb el botó del mig en la barra de títol" - -#~ msgid "Action on title bar right-click" -#~ msgstr "Acció en fer clic amb el botó secundari en la barra de títol" - -#~ msgid "Arrangement of buttons on the titlebar" -#~ msgstr "Emplaçament dels botons en la barra de títol" - -#~ msgid "" -#~ "Arrangement of buttons on the titlebar. The value should be a string, " -#~ "such as \"menu:minimize,maximize,spacer,close\"; the colon separates the " -#~ "left corner of the window from the right corner, and the button names are " -#~ "comma-separated. Duplicate buttons are not allowed. Unknown button names " -#~ "are silently ignored so that buttons can be added in future metacity " -#~ "versions without breaking older versions. A special spacer tag can be " -#~ "used to insert some space between two adjacent buttons." -#~ msgstr "" -#~ "La disposició dels botons a la barra del títol. El valor ha de ser una " -#~ "cadena, com ara «menu:minimize,maximize,spacer,close»; els dos punts " -#~ "separen la cantonada esquerra de la finestra de la dreta, i els noms dels " -#~ "botons se separen amb comes. No es permeten botons duplicats. Els botons " -#~ "desconeguts es descartaran sense cap notificació, de manera que es puguin " -#~ "afegir botons en futures versions del Metacity sense trencar les versions " -#~ "antigues. Es pot afegir una etiqueta especial d'espaiament («spacer») per " -#~ "a insertar una determinada quantitat d'espai entre dos botons adjacents." - -#~ msgid "Automatically raises the focused window" -#~ msgstr "Alça automàticament la finestra amb el focus" - -#~ msgid "" -#~ "Clicking a window while holding down this modifier key will move the " -#~ "window (left click), resize the window (middle click), or show the window " -#~ "menu (right click). The left and right operations may be swapped using " -#~ "the \"mouse_button_resize\" key. Modifier is expressed as \"<Alt>\" " -#~ "or \"<Super>\" for example." -#~ msgstr "" -#~ "Si es fa clic en una finestra mentre es manté aquesta tecla modificadora " -#~ "premuda, es mourà la finestra (botó esquerre), redimensionarà la finestra " -#~ "(botó central) o mostrarà el menú de la finestra (botó dret). Les " -#~ "operacions de la dreta i de l'esquerra es poden intercanviar amb la clau " -#~ "«mouse_button_resize». El modificador s'expressa com a «<Alt;>» o " -#~ "com a «<Super>», per exemple." - -#~ msgid "Commands to run in response to keybindings" -#~ msgstr "Ordres a executar en resposta a vinculacions de tecles" - -#~ msgid "Compositing Manager" -#~ msgstr "Gestor de composició" - -#~ msgid "Control how new windows get focus" -#~ msgstr "Controla de quina manera les finestres noves reben el focus" - -#~ msgid "Current theme" -#~ msgstr "Tema actual" - -#~ msgid "Delay in milliseconds for the auto raise option" -#~ msgstr "Retard en mil·lisegons per a l'opció d'alçat automàtic" +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Retarda el canvi del focus fins que s'ature el punter" -#~ msgid "Determines whether Metacity is a compositing manager." -#~ msgstr "Determina si el Metacity és un gestor de composició." +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" +"Si és «true» (cert), i el mode del focus és «sloppy» o «mouse», no es " +"canviarà el focus immediatament quan s'entri a una finestra, només es " +"canviarà quan el punter deixi de moure's." -#~ msgid "" -#~ "Determines whether applications or the system can generate audible " -#~ "'beeps'; may be used in conjunction with 'visual bell' to allow silent " -#~ "'beeps'." -#~ msgstr "" -#~ "Determina si les aplicacions o el sistema poden generar «sons» audibles; " -#~ "es pot utilitzar en conjunció amb «visual bell» per a permetre «sons» " -#~ "silenciosos." +#: data/org.gnome.mutter.gschema.xml.in:79 +msgid "Draggable border width" +msgstr "Amplària del contorn arrossegable" -#~ msgid "Disable misfeatures that are required by old or broken applications" -#~ msgstr "" -#~ "Inhabilita funcionalitats que són requerides per aplicacions velles o amb " -#~ "errors" +#: data/org.gnome.mutter.gschema.xml.in:80 +msgid "" +"The amount of total draggable borders. If the theme’s visible borders are " +"not enough, invisible borders will be added to meet this value." +msgstr "" +"La quantitat total de contorn arrossegable. Si els contorns visibles del " +"tema no són suficients, s'afegiran contorns invisibles per aconseguir este " +"valor." -#~ msgid "Enable Visual Bell" -#~ msgstr "Habilita la campana visual" +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "" +"Maximitza automàticament les finestres que gairebé facen la mida de la " +"pantalla" -#~ msgid "" -#~ "If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " -#~ "the focused window will be automatically raised after a delay specified " -#~ "by the auto_raise_delay key. This is not related to clicking on a window " -#~ "to raise it, nor to entering a window during drag-and-drop." -#~ msgstr "" -#~ "Si és cert, i el mode del focus és «sloppy» o «mouse», aleshores la " -#~ "finestra amb el focus s'alçarà automàticament després d'un retard, que " -#~ "s'especifica a la clau auto_raise_delay. Això no està relacionat en " -#~ "l'acció de fer clic a una finestra per a alçar-la, ni tampoc en entrar en " -#~ "una finestra en arrossegar i deixar anar." +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" +"Si s'habilita, les finestres que inicialment gairebé fan la mida de la " +"pantalla es maximitzaran automàticament." -#~ msgid "" -#~ "If true, ignore the titlebar_font option, and use the standard " -#~ "application font for window titles." -#~ msgstr "" -#~ "Si és veritat, ignora l'opció titlebar_font i utilitza el tipus de lletra " -#~ "de les aplicacions estàndard per als títols de les finestres." +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Posiciona les finestres noves al centre" -#~ msgid "" -#~ "If true, metacity will give the user less feedback by using wireframes, " -#~ "avoiding animations, or other means. This is a significant reduction in " -#~ "usability for many users, but may allow legacy applications to continue " -#~ "working, and may also be a useful tradeoff for terminal servers. However, " -#~ "the wireframe feature is disabled when accessibility is on." -#~ msgstr "" -#~ "Sí és cert, el metacity donarà a l'usuari menys informació utilitzant " -#~ "marcs amb fils, evitant les animacions o altres mitjans. Això implica una " -#~ "reducció significativa en usabilitat per a molts usuaris, però pot " -#~ "permetre a algunes aplicacions velles i servidors de terminal. No " -#~ "obstant, la funcionalitat dels marcs amb fils es desactiva quan " -#~ "l'accessibilitat està habilitada." +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" +"Si és «true» (cert), les finestres noves seran posicionades al centre de la " +"pantalla activa del monitor." -#~ msgid "" -#~ "If true, then Metacity works in terms of applications rather than " -#~ "windows. The concept is a bit abstract, but in general an application-" -#~ "based setup is more like the Mac and less like Windows. When you focus a " -#~ "window in application-based mode, all the windows in the application will " -#~ "be raised. Also, in application-based mode, focus clicks are not passed " -#~ "through to windows in other applications. Application-based mode is, " -#~ "however, largely unimplemented at the moment." -#~ msgstr "" -#~ "Si és cert, el Metacity treballarà en termes d'aplicacions, en comptes de " -#~ "finestres. El concepte és una mica abstracte, però en general, una " -#~ "configuració basada en aplicacions és més semblant als Mac i menys com el " -#~ "Windows. Quan teniu el focus en una finestra en el mode basat en " -#~ "aplicacions, totes les finestres en l'aplicació s'alçaran. A més a més, " -#~ "en el mode basat en aplicacions, els clics de focus no es passen a les " -#~ "finestres d'altres aplicacions. Tanmateix, el mode basat en aplicacions " -#~ "encara no està massa implementat." +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Habilita les funcionalitats experimentals" -#~ msgid "If true, trade off usability for less resource usage" -#~ msgstr "Si és vertader, sacrifica usabilitat per usar menys recursos" +#: data/org.gnome.mutter.gschema.xml.in:108 +msgid "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “remote-desktop” — " +"enables remote desktop support. To support remote desktop with screen " +"sharing, “screen-cast” must also be enabled. • “screen-cast” — enables " +"screen cast support." +msgstr "" + +#: data/org.gnome.mutter.gschema.xml.in:145 +msgid "Select window from tab popup" +msgstr "Selecció de finestra entre les emergents d'una pestanya" -#~ msgid "Name of workspace" -#~ msgstr "Nom de l'espai de treball" +#: data/org.gnome.mutter.gschema.xml.in:150 +msgid "Cancel tab popup" +msgstr "Cancel·lació de les finestres emergents a les pestanyes" -#~ msgid "Number of workspaces" -#~ msgstr "Número d'espais de treball" +#: data/org.gnome.mutter.gschema.xml.in:155 +msgid "Switch monitor configurations" +msgstr "Canvia configuracions de monitor" -#~ msgid "" -#~ "Number of workspaces. Must be more than zero, and has a fixed maximum to " -#~ "prevent making the desktop unusable by accidentally asking for too many " -#~ "workspaces." -#~ msgstr "" -#~ "El nombre d'espais de treball. Ha de ser més gran que zero, i té un màxim " -#~ "fixe per a prevenir la destrucció accidental del vostre escriptori si " -#~ "demaneu massa espais de treball." +#: data/org.gnome.mutter.gschema.xml.in:160 +msgid "Rotates the built-in monitor configuration" +msgstr "Gira la configuració del monitor integrada" -#~ msgid "Run a defined command" -#~ msgstr "Executa una ordre definida" +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Canvia al terminal virtual 1" -#~ msgid "" -#~ "Set this to true to resize with the right button and show a menu with the " -#~ "middle button while holding down the key given in \"mouse_button_modifier" -#~ "\"; set it to false to make it work the opposite way around." -#~ msgstr "" -#~ "Establiu-lo a «true» (cert) per a canviar la mida amb el botó secundari i " -#~ "mostrar un menú amb el botó central mentre es premi la tecla especificada " -#~ "al paràmetre «mouse_button_modifier». Establiu-lo a «false» (fals) perquè " -#~ "funcioni a l'inversa." +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Canvia al terminal virtual 2" -#~ msgid "" -#~ "Setting this option to false can lead to buggy behavior, so users are " -#~ "strongly discouraged from changing it from the default of true. Many " -#~ "actions (e.g. clicking in the client area, moving or resizing the window) " -#~ "normally raise the window as a side-effect. Setting this option to false, " -#~ "which is strongly discouraged, will decouple raising from other user " -#~ "actions, and ignore raise requests generated by applications. See http://" -#~ "bugzilla.gnome.org/show_bug.cgi?id=445447#c6. Even when this option is " -#~ "false, windows can still be raised by an alt-left-click anywhere on the " -#~ "window, a normal click on the window decorations, or by special messages " -#~ "from pagers, such as activation requests from tasklist applets. This " -#~ "option is currently disabled in click-to-focus mode. Note that the list " -#~ "of ways to raise windows when raise_on_click is false does not include " -#~ "programmatic requests from applications to raise windows; such requests " -#~ "will be ignored regardless of the reason for the request. If you are an " -#~ "application developer and have a user complaining that your application " -#~ "does not work with this setting disabled, tell them it is _their_ fault " -#~ "for breaking their window manager and that they need to change this " -#~ "option back to true or live with the \"bug\" they requested." -#~ msgstr "" -#~ "Si establiu aquesta opció a «false» (fals) es pot produir un comportament " -#~ "incorrecte, de manera que s'aconsella als usuaris que no canviïn el seu " -#~ "valor predeterminat: «true» (cert). Moltes accions (p.ex. fer clic a " -#~ "l'àrea del client, moure o canviar la mida de la finestra) normalment " -#~ "alcen la finestra com a efecte secundari. Si establiu aquesta opció a " -#~ "fals -cosa molt poc recomanable- se separarà l'alçament de la finestra " -#~ "d'altres accions de l'usuari i s'ignoraran les sol·licituds d'alçament " -#~ "que generin les aplicacions. Vegeu l'informe d'error http://bugzilla." -#~ "gnome.org/show_bug.cgi?id=445447#c6. Fins i tot quan aquesta opció sigui " -#~ "falsa, encara es poden alçar les finestres amb alt-clic-esquerra en " -#~ "qualsevol lloc de la finestra, amb un clic a les decoracions de la " -#~ "finestra, o amb un missatge especial dels paginadors, com ara " -#~ "sol·licituds d'activació des de les miniaplicacions de la llista de " -#~ "finestres. Aquesta opció està inhabilitada en el mode d'alçar les " -#~ "finestres amb clic. Fixeu-vos que les diverses maneres d'alçar les " -#~ "finestres quan «raise_on_click» és fals no inclouen les peticions " -#~ "programades de les aplicacions per a alçar finestres; aquestes peticions " -#~ "s'ignoraran sigui quin sigui el motiu. Si desenvolupeu aplicacions i un " -#~ "usuari es queixa que l'aplicació no funciona quan aquest paràmetre està " -#~ "inhabilitat, digueu-li que es culpa _seva_ per haver trencat el gestor de " -#~ "finestres, i que ha de tornar a canviar aquesta opció a «true» o conviure " -#~ "amb l'error." +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Canvia al terminal virtual 3" -#~ msgid "" -#~ "Some applications disregard specifications in ways that result in window " -#~ "manager misfeatures. This option puts Metacity in a rigorously correct " -#~ "mode, which gives a more consistent user interface, provided one does not " -#~ "need to run any misbehaving applications." -#~ msgstr "" -#~ "Algunes aplicacions no fan cas de les especificacions que poden fer que " -#~ "el gestor de finestri no respongui correctament. Aquesta opció fa que el " -#~ "Metaciti es posi en un mode rogorosament correcte, que proporciona una " -#~ "interfície d'usuari més consistent, sempre que no s'hagin d'executar " -#~ "aplicacions que no actuin correctament." +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Canvia al terminal virtual 4" -#~ msgid "System Bell is Audible" -#~ msgstr "La campana del sistema és audible" +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Canvia al terminal virtual 5" -#~ msgid "" -#~ "Tells Metacity how to implement the visual indication that the system " -#~ "bell or another application 'bell' indicator has been rung. Currently " -#~ "there are two valid values, \"fullscreen\", which causes a fullscreen " -#~ "white-black flash, and \"frame_flash\" which causes the titlebar of the " -#~ "application which sent the bell signal to flash. If the application which " -#~ "sent the bell is unknown (as is usually the case for the default \"system " -#~ "beep\"), the currently focused window's titlebar is flashed." -#~ msgstr "" -#~ "Li diu al Metacity com implementar la indicació visual de que s'ha tocat " -#~ "la campana del sistema, o l'indicador de campana d'un altra aplicació. " -#~ "Actualment, hi ha dos valors vàlids, «fullscreen», que fa un flaix blanc " -#~ "i negre en tota la pantalla, i «frame_flash», que causa que la barra del " -#~ "títol de l'aplicació que ha enviat el senyal de campana faci un flaix. Si " -#~ "no se sap quina aplicació ha enviat el senyal de campana, com sol pasar " -#~ "per als «sons del sistema» per defecte, la barra del títol de la finestra " -#~ "que tingui el focus en aquell moment rep un flaix." +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Canvia al terminal virtual 6" -#~ msgid "" -#~ "The /apps/metacity/global_keybindings/run_command_N keys define " -#~ "keybindings that correspond to these commands. Pressing the keybinding " -#~ "for run_command_N will execute command_N." -#~ msgstr "" -#~ "Les claus /apps/metacity/global_keybindings/run_command_N estableixen " -#~ "vinculacions de tecles que corresponen a aquestes ordres. Si es prem la " -#~ "vinculació per a run_command_N, s'executarà command_N." +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Canvia al terminal virtual 7" -#~ msgid "" -#~ "The /apps/metacity/global_keybindings/run_command_screenshot key defines " -#~ "a keybinding which causes the command specified by this setting to be " -#~ "invoked." -#~ msgstr "" -#~ "La clau /apps/metacity/global_keybindings/run_command_screenshot " -#~ "estableix una vinculació de tecles que fa que s'invoqui l'ordre " -#~ "especificada en aquesta configuració." +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Canvia al terminal virtual 8" -#~ msgid "" -#~ "The /apps/metacity/global_keybindings/run_command_window_screenshot key " -#~ "defines a keybinding which causes the command specified by this setting " -#~ "to be invoked." -#~ msgstr "" -#~ "La clau /apps/metacity/global_keybindings/run_command_window_screenshot " -#~ "estableix una vinculació de tecles que fa que s'invoqui l'ordre " -#~ "especificada en aquesta configuració." +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Canvia al terminal virtual 9" -#~ msgid "" -#~ "The keybinding that runs the correspondingly-numbered command in /apps/" -#~ "metacity/keybinding_commands The format looks like \"<Control>a\" " -#~ "or \"<Shift><Alt>F1\". The parser is fairly liberal and " -#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" -#~ "\" and \"<Ctrl>\". If you set the option to the special string " -#~ "\"disabled\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles que executa l'ordre amb la numeració corresponent " -#~ "a /apps/metacity/keybinding_commands. El format és semblant a «<" -#~ "Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com ara " -#~ "«<Ctl>» o «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Canvia al terminal virtual 10" -#~ msgid "The name of a workspace." -#~ msgstr "El nom d'un espai de treball." +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Canvia al terminal virtual 11" -#~ msgid "The screenshot command" -#~ msgstr "L'ordre de captura de pantalla" +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Canvia al terminal virtual 12" -#~ msgid "" -#~ "The theme determines the appearance of window borders, titlebar, and so " -#~ "forth." -#~ msgstr "" -#~ "El tema determina l'aspecte dels contorns de les finestres, la barra del " -#~ "títol, etc..." +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "Torna a habilitar les dreceres" -#~ msgid "" -#~ "The time delay before raising a window if auto_raise is set to true. The " -#~ "delay is given in thousandths of a second." -#~ msgstr "" -#~ "El retard de temps abans d'alçar una finestra si auto_raise és establer a " -#~ "«true». El retard es dóna en mil·lèssimes de segon." +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. +#. +#: src/backends/meta-input-settings.c:2157 +#, c-format +msgid "Mode Switch (Group %d)" +msgstr "Mode de commutació (grup %d)" -#~ msgid "" -#~ "The window focus mode indicates how windows are activated. It has three " -#~ "possible values; \"click\" means windows must be clicked in order to " -#~ "focus them, \"sloppy\" means windows are focused when the mouse enters " -#~ "the window, and \"mouse\" means windows are focused when the mouse enters " -#~ "the window and unfocused when the mouse leaves the window." -#~ msgstr "" -#~ "El mode de focus de la finestra indica com s'activen les finestres. Té " -#~ "tres valors possibles; «click» vol dir que cal fer clic a les finestres " -#~ "per a donar-los el focus, «sloppy» vol dir que les finestres reben el " -#~ "focus quan el punter hi entra a dins, i «mouse» vol dir que les finestres " -#~ "s'enfoquen quan el punter hi entra a dins, i es desenfoquen quan el " -#~ "punter abandona la finestra." +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2180 +msgid "Switch monitor" +msgstr "Commuta el monitor" -#~ msgid "The window screenshot command" -#~ msgstr "L'ordre de captura de finestra" +#: src/backends/meta-input-settings.c:2182 +msgid "Show on-screen help" +msgstr "Mostra l'ajuda en pantalla" -#~ msgid "" -#~ "This option determines the effects of double-clicking on the title bar. " -#~ "Current valid options are 'toggle_shade', which will shade/unshade the " -#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " -#~ "will maximize/unmaximize the window in that direction only, 'minimize' " -#~ "which will minimize the window, 'shade' which will roll the window up, " -#~ "'menu' which will display the window menu, 'lower' which will put the " -#~ "window behind all the others, and 'none' which will not do anything." -#~ msgstr "" -#~ "Aquesta opció determina l'efecte de l'acció de doble clic a la barra de " -#~ "títol. Els valors permesos són «toggle_shade» (commuta l'estat de " -#~ "persiana), que commutarà l'estat d'ombrejat de la finestra, " -#~ "«toggle_maximize» (commuta la maximització), que en commutarà l'estat de " -#~ "maximització, «toggle_maximize_horizontally» (commuta la maximització " -#~ "horitzontal) i «toggle_maximize_vertically» (commuta la maximització " -#~ "vertical), que només commutaran l'estat de maximització en la direcció " -#~ "indicada, «minimize» (minimitza), que minimitzarà la finestra, " -#~ "«shade» (persiana), que enrotllarà la finestra cap amunt, «menu», que " -#~ "mostrarà el menú de la finestra, «lower» (abaixa), que situarà la " -#~ "finestra darrere de totes les altres, i «none» (res), que no farà res." +#: src/backends/meta-monitor-manager.c:894 +msgid "Built-in display" +msgstr "Pantalla integrada" -#~ msgid "" -#~ "This option determines the effects of middle-clicking on the title bar. " -#~ "Current valid options are 'toggle_shade', which will shade/unshade the " -#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " -#~ "will maximize/unmaximize the window in that direction only, 'minimize' " -#~ "which will minimize the window, 'shade' which will roll the window up, " -#~ "'menu' which will display the window menu, 'lower' which will put the " -#~ "window behind all the others, and 'none' which will not do anything." -#~ msgstr "" -#~ "Aquesta opció determina l'efecte de l'acció de fer clic amb el botó del " -#~ "mig a la barra de títol. Els valors permesos són «toggle_shade» (commuta " -#~ "l'estat de persiana), que commutarà l'estat d'ombrejat de la finestra, " -#~ "«toggle_maximize» (commuta la maximització), que en commutarà l'estat de " -#~ "maximització, «toggle_maximize_horizontally» (commuta la maximització " -#~ "horitzontal) i «toggle_maximize_vertically» (commuta la maximització " -#~ "vertical), que només commutaran l'estat de maximització en la direcció " -#~ "indicada, «minimize» (minimitza), que minimitzarà la finestra, " -#~ "«shade» (persiana), que enrotllarà la finestra cap amunt, «menu», que " -#~ "mostrarà el menú de la finestra, «lower» (abaixa), que situarà la " -#~ "finestra darrere de totes les altres, i «none» (res), que no farà res." +#: src/backends/meta-monitor-manager.c:917 +msgid "Unknown" +msgstr "Desconeguda" -#~ msgid "" -#~ "This option determines the effects of right-clicking on the title bar. " -#~ "Current valid options are 'toggle_shade', which will shade/unshade the " -#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " -#~ "will maximize/unmaximize the window in that direction only, 'minimize' " -#~ "which will minimize the window, 'shade' which will roll the window up, " -#~ "'menu' which will display the window menu, 'lower' which will put the " -#~ "window behind all the others, and 'none' which will not do anything." -#~ msgstr "" -#~ "Aquesta opció determina l'efecte de l'acció de fer clic amb el botó " -#~ "secundari a la barra de títol. Els valors permesos són " -#~ "«toggle_shade» (commuta l'estat de persiana), que commutarà l'estat " -#~ "d'ombrejat de la finestra, «toggle_maximize» (commuta la maximització), " -#~ "que en commutarà l'estat de maximització, " -#~ "«toggle_maximize_horizontally» (commuta la maximització horitzontal) i " -#~ "«toggle_maximize_vertically» (commuta la maximització vertical), que " -#~ "només commutaran l'estat de maximització en la direcció indicada, " -#~ "«minimize» (minimitza), que minimitzarà la finestra, «shade» (persiana), " -#~ "que enrotllarà la finestra cap amunt, «menu», que mostrarà el menú de la " -#~ "finestra, «lower» (abaixa), que situarà la finestra darrere de totes les " -#~ "altres, i «none» (res), que no farà res." +#: src/backends/meta-monitor-manager.c:919 +msgid "Unknown Display" +msgstr "Pantalla desconeguda" -#~ msgid "" -#~ "This option provides additional control over how newly created windows " -#~ "get focus. It has two possible values; \"smart\" applies the user's " -#~ "normal focus mode, and \"strict\" results in windows started from a " -#~ "terminal not being given focus." -#~ msgstr "" -#~ "Aquesta opció proporciona control adicional sobre com les finestres noves " -#~ "obtenen el focus. Té dos valors possibles: «smart», que aplica el focus " -#~ "normal d'usuari, i «strict», que fa que no es doni el focus a les " -#~ "finestres que s'iniciïn des d'un terminal." +#. TRANSLATORS: this is a monitor vendor name, followed by a +#. * size in inches, like 'Dell 15"' +#. +#: src/backends/meta-monitor-manager.c:927 +#, c-format +msgid "%s %s" +msgstr "%s %s" -#~ msgid "" -#~ "Turns on a visual indication when an application or the system issues a " -#~ "'bell' or 'beep'; useful for the hard-of-hearing and for use in noisy " -#~ "environments." -#~ msgstr "" -#~ "Activa una indicació visual quan una aplicació o el sistema envia un " -#~ "senyal de «campana» o «sons»; és útil per als durs d'orella i per a l'ús " -#~ "en ambients amb soroll." +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:476 +#, c-format +msgid "" +"Another compositing manager is already running on screen %i on display “%s”." +msgstr "" +"Ja s'està executant un altre gestor de composició al monitor %i a la " +"pantalla «%s»." -#~ msgid "Use standard system font in window titles" -#~ msgstr "" -#~ "Utilitza el tipus de lletra estàndard del sistema en els títols de les " -#~ "finestres" +#: src/core/bell.c:194 +msgid "Bell event" +msgstr "Esdeveniment de campana" -#~ msgid "Visual Bell Type" -#~ msgstr "Tipus de «sons» visual" +#: src/core/display.c:608 +#, c-format +msgid "Failed to open X Window System display “%s”\n" +msgstr "" +"S'ha produït un error en obrir la pantalla del sistema de finestres X «%s»\n" -#~ msgid "Whether raising should be a side-effect of other user interactions" -#~ msgstr "" -#~ "Si l'alçat hauria de ser un efecte secundari d'altres interaccions de " -#~ "l'usuari" +#: src/core/main.c:189 +msgid "Disable connection to session manager" +msgstr "Inhabilita la connexió al gestor de sessions" -#~ msgid "Whether to resize with the right button" -#~ msgstr "Si es canviarà la mida amb el botó secundari" +#: src/core/main.c:195 +msgid "Replace the running window manager" +msgstr "Reemplaça el gestor de finestres en execució" -#~ msgid "Window focus mode" -#~ msgstr "Mode de focus de les finestres" +#: src/core/main.c:201 +msgid "Specify session management ID" +msgstr "Especifica l'ID de gestió de sessió" -#~ msgid "Window title font" -#~ msgstr "Tipus de lletra del títol de les finestres" +#: src/core/main.c:206 +msgid "X Display to use" +msgstr "Visualització X per usar" -#~ msgid "Title" -#~ msgstr "Títol" +#: src/core/main.c:212 +msgid "Initialize session from savefile" +msgstr "Inicialitza la sessió des del fitxer guardat" -#~ msgid "Class" -#~ msgstr "Classe" +#: src/core/main.c:218 +msgid "Make X calls synchronous" +msgstr "Fes que les crides a l'X siguen síncrones" -#~ msgid "" -#~ "There was an error running \"%s\":\n" -#~ "%s." -#~ msgstr "" -#~ "S'ha produït un error en executar «%s»:\n" -#~ "%s." +#: src/core/main.c:225 +msgid "Run as a wayland compositor" +msgstr "Funciona com a compositor de Wayland" -#~ msgid "<author> specified twice for this theme" -#~ msgstr "S'ha especificat <author> dues vegades per a aquest tema" +# Notes: +# Afegeix una nota +# +# Camins: +# ../src/core/main.c:223 +#: src/core/main.c:231 +msgid "Run as a nested compositor" +msgstr "Funciona com a compositor imbricat" -#~ msgid "<copyright> specified twice for this theme" -#~ msgstr "S'ha especificat <copyright> dues vegades per a aquest tema" +#: src/core/main.c:239 +msgid "Run as a full display server, rather than nested" +msgstr "Funciona com a servidor de pantalla completa, en comptes d'imbricat" -#~ msgid "<date> specified twice for this theme" -#~ msgstr "S'ha especificat <date> dues vegades per a aquest tema" +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:147 +#, c-format +msgid "“%s” is not responding." +msgstr "«%s» no està responent." -#~ msgid "<description> specified twice for this theme" -#~ msgstr "S'ha especificat <description> dues vegades per a aquest tema" +#: src/core/meta-close-dialog-default.c:149 +msgid "Application is not responding." +msgstr "L'aplicació no està responent." -#~ msgid "Theme file %s did not contain a root <metacity_theme> element" -#~ msgstr "El fitxer de tema %s no conté un element arrel <metacity_theme>" +#: src/core/meta-close-dialog-default.c:154 +msgid "" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." +msgstr "" +"Podeu esperar un moment perquè continue o podeu forçar-ne l'eixida " +"completa." -#~ msgid "/Windows/tearoff" -#~ msgstr "/Finestres/separador" +#: src/core/meta-close-dialog-default.c:161 +msgid "_Force Quit" +msgstr "_Força'n l'eixida" -#~ msgid "/Windows/_Dialog" -#~ msgstr "/Finestres/_Diàleg" +#: src/core/meta-close-dialog-default.c:161 +msgid "_Wait" +msgstr "_Espera" -#~ msgid "/Windows/_Modal dialog" -#~ msgstr "/Finestres/Diàleg _modal" +#: src/core/mutter.c:39 +#, c-format +msgid "" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" +msgstr "" +"Mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., i d'altres\n" +"Això és programari lliure; vegeu els fitxers de codi font per conèixer-ne\n" +"les condicions de còpia.\n" +"No hi ha CAP garantia; ni tan sols la garantia implícita de COMERCIABILITAT\n" +"o ADEQUACIÓ A PER UN PROPÒSIT PARTICULAR.\n" -#~ msgid "/Windows/Des_ktop" -#~ msgstr "/Finestres/_Escriptori" +#: src/core/mutter.c:53 +msgid "Print version" +msgstr "Escriu versió" -#~ msgid "" -#~ "Error launching metacity-dialog to print an error about a command: %s\n" -#~ msgstr "" -#~ "S'ha produït un error en executar el metacity-dialog per a mostrar un " -#~ "error quant a una ordre: %s\n" +#: src/core/mutter.c:59 +msgid "Mutter plugin to use" +msgstr "Connector del Mutter a utilitzar" -#~ msgid "Unknown attribute %s on <metacity_session> element" -#~ msgstr "Atribut %s desconegut a l'element <metacity_session>" +#: src/core/prefs.c:1997 +#, c-format +msgid "Workspace %d" +msgstr "Espai de treball %d" -#~ msgid "Unknown attribute %s on <maximized> element" -#~ msgstr "Atribut %s desconegut a l'element <maximized>" +#: src/core/screen.c:582 +#, c-format +msgid "" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." +msgstr "" +"La pantalla «%s» ja té un gestor de finestres; proveu l'opció --replace per " +"reemplaçar el gestor de finestres actual." -#~ msgid "Unknown attribute %s on <geometry> element" -#~ msgstr "Atribut %s desconegut a l'element <geometry>" +#: src/core/screen.c:667 +#, c-format +msgid "Screen %d on display “%s” is invalid\n" +msgstr "El monitor %d en la pantalla '%s' no és vàlida\n" -#~ msgid "Toggle always on top state" -#~ msgstr "Canvia l'estat sempre per damunt" +#: src/core/util.c:120 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter es va compilar sense compatibilitat per al mode detallat\n" -#~ msgid "Unmaximize window" -#~ msgstr "Desmaximitza la finestra" +#: src/wayland/meta-wayland-tablet-pad.c:563 +#, c-format +msgid "Mode Switch: Mode %d" +msgstr "Mode de commutació: mode %d" -#~ msgid "" -#~ "Many actions (e.g. clicking in the client area, moving or resizing the " -#~ "window) normally raise the window as a side-effect. Setting this option " -#~ "to false, which is strongly discouraged, will decouple raising from other " -#~ "user actions, and ignore raise requests generated by applications. See " -#~ "http://bugzilla.gnome.org/show_bug.cgi?id=445447#c6." -#~ msgstr "" -#~ "Hi ha moltes accions (p.ex. fer clic a l'àrea del client, moure o canviar " -#~ "la mida de la finestra) que normalment alcen la finestra com a efecte " -#~ "secundari. Si establiu aquesta opció com a falsa (cosa gens recomanable), " -#~ "l'alçament es desvincularà de les altres accions de l'usuari i " -#~ "s'ignoraran les sol·licituds d'alçament generades per les aplicacions. " -#~ "Vegeu aquest informe d'error: http://bugzilla.gnome.org/show_bug.cgi?" -#~ "id=445447#c6." +#: src/x11/session.c:1815 +msgid "" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." +msgstr "" +"Estes finestres no implementen «guarda la configuració actual» i s'hauran " +"de reiniciar manualment la pròxima vegada que entreu." -#~ msgid "" -#~ "The keybinding that switches to the workspace above the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles que canvia a l'espai de treball a sobre de " -#~ "l'espai de treball actual. El format és «<Control>a» o «<" -#~ "Shift><Alt>F1». L'analitzador és prou flexible i permet " -#~ "minúscules i majúscules, i també abreviacions com «<Ctl>» i «<" -#~ "Ctrl>». Si establiu l'opció a la cadena especial «disabled», no hi " -#~ "haurà cap vinculació per a aquesta acció." +#: src/x11/window-props.c:559 +#, c-format +msgid "%s (on %s)" +msgstr "%s (a %s)" -#~ msgid "" -#~ "The keybinding that switches to the workspace below the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles que canvia a l'espai de treball sota l'espai de " -#~ "treball actual. El format és «<Control>a» o «<Shift><" -#~ "Alt>F1». L'analitzador és prou flexible i permet minúscules i " -#~ "majúscules, i també abreviacions com «<Ctl>» i «<Ctrl>». Si " -#~ "establiu l'opció a la cadena especial «disabled», no hi haurà cap " -#~ "vinculació per a aquesta acció." +#~ msgid "Failed to scan themes directory: %s\n" +#~ msgstr "No s'ha pogut analitzar el directori de temes: %s\n" #~ msgid "" -#~ "The keybinding that switches to the workspace on the left of the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." +#~ "Could not find a theme! Be sure %s exists and contains the usual themes.\n" #~ msgstr "" -#~ "La vinculació de tecles que canvia a l'espai de treball a l'esquerra de " -#~ "l'espai de treball actual. El format és «<Control>a» o «<" -#~ "Shift><Alt>F1». L'analitzador és prou flexible i permet " -#~ "minúscules i majúscules, i també abreviacions com «<Ctl>» i «<" -#~ "Ctrl>». Si establiu l'opció a la cadena especial «disabled», no hi " -#~ "haurà cap vinculació per a aquesta acció." +#~ "No s'ha trobat cap tema. Assegureu-vos que %s existeix i conté els temes " +#~ "habituals.\n" -#~ msgid "" -#~ "The keybinding that switches to the workspace on the right of the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." +#~ msgid "Screen %d on display \"%s\" already has a window manager\n" #~ msgstr "" -#~ "La vinculació de tecles que canvia a l'espai de treball a la dreta de " -#~ "l'espai de treball actual. El format és «<Control>a» o «<" -#~ "Shift><Alt>F1». L'analitzador és prou flexible i permet " -#~ "minúscules i majúscules, i també abreviacions com «<Ctl>» i «<" -#~ "Ctrl>». Si establiu l'opció a la cadena especial «disabled», no hi " -#~ "haurà cap vinculació per a aquesta acció." +#~ "La pantalla %d en la visualització «%s» ja té un gestor de finestres\n" -#~ msgid "" -#~ "The keybinding that switches to workspace 1. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "La vinculació de tecles que canvia a l'espai de treball 1. El format és " -#~ "«<Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." +#~ msgid "%d x %d" +#~ msgstr "%d x %d" -#~ msgid "" -#~ "The keybinding that switches to workspace 10. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "La vinculació de tecles que canvia a l'espai de treball 10. El format és " -#~ "«<Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." +#~ msgid "top" +#~ msgstr "superior" -#~ msgid "" -#~ "The keybinding that switches to workspace 11. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "La vinculació de tecles que canvia a l'espai de treball 11. El format és " -#~ "«<Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." +#~ msgid "bottom" +#~ msgstr "inferior" -#~ msgid "" -#~ "The keybinding that switches to workspace 12. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "La vinculació de tecles que canvia a l'espai de treball 12. El format és " -#~ "«<Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." +#~ msgid "left" +#~ msgstr "esquerra" -#~ msgid "" -#~ "The keybinding that switches to workspace 2. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "La vinculació de tecles que canvia a l'espai de treball 2. El format és " -#~ "«<Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." +#~ msgid "right" +#~ msgstr "dreta" -#~ msgid "" -#~ "The keybinding that switches to workspace 3. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "La vinculació de tecles que canvia a l'espai de treball 3. El format és " -#~ "«<Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." +#~ msgid "frame geometry does not specify \"%s\" dimension" +#~ msgstr "la geometria del marc no especifica la dimensió «%s»" -#~ msgid "" -#~ "The keybinding that switches to workspace 4. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" #~ msgstr "" -#~ "La vinculació de tecles que canvia a l'espai de treball 4. El format és " -#~ "«<Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." +#~ "la geometria del marc no especifica la dimensió «%s» per al contorn «%s»" -#~ msgid "" -#~ "The keybinding that switches to workspace 5. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "La vinculació de tecles que canvia a l'espai de treball 5. El format és " -#~ "«<Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." +#~ msgid "Button aspect ratio %g is not reasonable" +#~ msgstr "El ràtio d'aspecte dels botons %g no és raonable" -#~ msgid "" -#~ "The keybinding that switches to workspace 6. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "La vinculació de tecles que canvia a l'espai de treball 6. El format és " -#~ "«<Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." +#~ msgid "Frame geometry does not specify size of buttons" +#~ msgstr "La geometria del marc no especifica la mida dels botons" -#~ msgid "" -#~ "The keybinding that switches to workspace 7. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "La vinculació de tecles que canvia a l'espai de treball 7. El format és " -#~ "«<Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." +#~ msgid "Gradients should have at least two colors" +#~ msgstr "Els degradats han de tenir almenys dos colors" #~ msgid "" -#~ "The keybinding that switches to workspace 8. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "GTK custom color specification must have color name and fallback in " +#~ "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" #~ msgstr "" -#~ "La vinculació de tecles que canvia a l'espai de treball 8. El format és " -#~ "«<Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." +#~ "L'especificació personalitzada de color de la GTK ha de tenir un nom de " +#~ "color i un alternatiu en parèntesis, p.e. gtk:custom(foo,bar); no s'ha " +#~ "pogut analitzar «%s»" #~ msgid "" -#~ "The keybinding that switches to workspace 9. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-" +#~ "z0-9-_ are valid" #~ msgstr "" -#~ "La vinculació de tecles que canvia a l'espai de treball 9. El format és " -#~ "«<Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." +#~ "El caràcter «%c» no és vàlid en el paràmetre color_name de la GTK:" +#~ "personalitzat, només són vàlids A-Za-z0-9-_" #~ msgid "" -#~ "The keybinding used to activate the window menu. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " +#~ "fit the format" #~ msgstr "" -#~ "La vinculació de tecles per a activar el menú de finestres. El format és " -#~ "«<Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." +#~ "El format de la GTK:personalitzat és «gtk:personalitzat(color_name," +#~ "alternatiu)», «%s» no s'ajusta al format" #~ msgid "" -#~ "The keybinding used to close a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "GTK color specification must have the state in brackets, e.g. gtk:" +#~ "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" #~ msgstr "" -#~ "La vinculació de tecles per a tancar una finestra. El format és «<" -#~ "Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." +#~ "L'especificació de color GTK ha de tenir l'estat entre claudàtors, p.e. " +#~ "gtk:fg[NORMAL] on NORMAL és l'estat; no s'ha pogut analitzar \"%s\"" #~ msgid "" -#~ "The keybinding used to enter \"move mode\" and begin moving a window " -#~ "using the keyboard. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." +#~ "GTK color specification must have a close bracket after the state, e.g. " +#~ "gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" #~ msgstr "" -#~ "La vinculació de tecles que activa el «mode de moviment» i permet moure " -#~ "una finestra utilitzant el teclat. El format és «<Control>a» o «<" -#~ "Shift><Alt>F1». L'analitzador és prou flexible i permet " -#~ "minúscules i majúscules, i també abreviacions com «<Ctl>» i «<" -#~ "Ctrl>». Si establiu l'opció a la cadena especial «disabled», no hi " -#~ "haurà cap vinculació per a aquesta acció." +#~ "L'especificació de color GTK ha de tenir un claudàtor de tancament " +#~ "després de l'estat, p.e. gtk:fg[NORMAL] on NORMAL és l'estat; no s'ha " +#~ "pogut analitzar «%s»" -#~ msgid "" -#~ "The keybinding used to enter \"resize mode\" and begin resizing a window " -#~ "using the keyboard. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles que activa el «mode de redimensió» i permet " -#~ "redimensionar una finestra utilitzant el teclat. El format és «<" -#~ "Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." +#~ msgid "Did not understand state \"%s\" in color specification" +#~ msgstr "No s'entén l'estat «%s» en l'especificació del color" -#~ msgid "" -#~ "The keybinding used to hide all normal windows and set the focus to the " -#~ "desktop background. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles per a amagar totes les finestres normals i " -#~ "establir el focus al fons de l'escriptori. El format és «<Control>" -#~ "a» o «<Shift><Alt>F1». L'analitzador és prou flexible i " -#~ "permet minúscules i majúscules, i també abreviacions com «<Ctl>» i " -#~ "«<Ctrl>». Si establiu l'opció a la cadena especial «disabled», no " -#~ "hi haurà cap vinculació per a aquesta acció." +#~ msgid "Did not understand color component \"%s\" in color specification" +#~ msgstr "No s'entén l'element de color «%s» en l'especificació del color" #~ msgid "" -#~ "The keybinding used to maximize a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit " +#~ "the format" #~ msgstr "" -#~ "La vinculació de tecles per a maximitzar una finestra. El format és " -#~ "semblant a «<Control>a» o «<Shift><Alt>F1». " -#~ "L'analitzador és prou flexible i permet minúscules i majúscules, i també " -#~ "abreviacions com «<Ctl>» i «<Ctrl>». Si establiu l'opció a la " -#~ "cadena especial «disabled», no hi haurà cap vinculació per a aquesta " -#~ "acció." +#~ "El format de barreja és «blend/bg_color/fg_color/alpha», «%s» no s'ajusta " +#~ "al format" -#~ msgid "" -#~ "The keybinding used to minimize a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ msgid "Could not parse alpha value \"%s\" in blended color" #~ msgstr "" -#~ "La vinculació de tecles per a minimitzar una finestra. El format és «<" -#~ "Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." +#~ "No s'ha pogut analitzar el valor d'opacitat «%s» en el color barrejat" -#~ msgid "" -#~ "The keybinding used to move a window one workspace down. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "La vinculació de tecles per a moure una finestra un espai de treball cap " -#~ "avall. El format és «<Control>a» o «<Shift><Alt>F1». " -#~ "L'analitzador és prou flexible i permet minúscules i majúscules, i també " -#~ "abreviacions com «<Ctl>» i «<Ctrl>». Si establiu l'opció a la " -#~ "cadena especial «disabled», no hi haurà cap vinculació per a aquesta " -#~ "acció." +#~ msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" +#~ msgstr "El valor alfa «%s» en el color barrejat no està entre 0,0 i 1,0" #~ msgid "" -#~ "The keybinding used to move a window one workspace to the left. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." +#~ "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the " +#~ "format" #~ msgstr "" -#~ "La vinculació de tecles per a moure una finestra un espai de treball a " -#~ "l'esquerra. El format és semblant a «<Control>a» o «<Shift>" -#~ "<Alt>F1». L'analitzador és prou flexible i permet minúscules i " -#~ "majúscules, i també abreviacions com «<Ctl>» i «<Ctrl>». Si " -#~ "establiu l'opció a la cadena especial «disabled», no hi haurà cap " -#~ "vinculació per a aquesta acció." +#~ "El format d'ombrejat és «shade/base_color/factor», «%s» no s'ajusta al " +#~ "format" -#~ msgid "" -#~ "The keybinding used to move a window one workspace to the right. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." +#~ msgid "Could not parse shade factor \"%s\" in shaded color" #~ msgstr "" -#~ "La vinculació de tecles per a moure una finestra un espai de treball a la " -#~ "dreta. El format és semblant a «<Control>a» o «<Shift><" -#~ "Alt>F1». L'analitzador és prou flexible i permet minúscules i " -#~ "majúscules, i també abreviacions com «<Ctl>» i «<Ctrl>». Si " -#~ "establiu l'opció a la cadena especial «disabled», no hi haurà cap " -#~ "vinculació per a aquesta acció." +#~ "No s'ha pogut analitzar el factor d'ombrejat «%s» en el color ombrejat" -#~ msgid "" -#~ "The keybinding used to move a window one workspace up. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "La vinculació de tecles per a moure una finestra un espai de treball " -#~ "amunt. El format és semblant a «<Control>a» o «<Shift><" -#~ "Alt>F1». L'analitzador és prou flexible i permet minúscules i " -#~ "majúscules, i també abreviacions com «<Ctl>» i «<Ctrl>». Si " -#~ "establiu l'opció a la cadena especial «disabled», no hi haurà cap " -#~ "vinculació per a aquesta acció." +#~ msgid "Shade factor \"%s\" in shaded color is negative" +#~ msgstr "El factor d'ombrejat «%s» en el color ombrejat és negatiu" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 1. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "La vinculació de tecles per a moure una finestra a l'espai de treball 1. " -#~ "El format és semblant a «<Control>a» o «<Shift><Alt>" -#~ "F1». L'analitzador és prou flexible i permet minúscules i majúscules, i " -#~ "també abreviacions com «<Ctl>» i «<Ctrl>». Si establiu " -#~ "l'opció a la cadena especial «disabled», no hi haurà cap vinculació per a " -#~ "aquesta acció." +#~ msgid "Could not parse color \"%s\"" +#~ msgstr "No s'ha pogut analitzar el color «%s»" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 10. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "La vinculació de tecles per a moure una finestra a l'espai de treball 10. " -#~ "El format és semblant a «<Control>a» o «<Shift><Alt>" -#~ "F1». L'analitzador és prou flexible i permet minúscules i majúscules, i " -#~ "també abreviacions com «<Ctl>» i «<Ctrl>». Si establiu " -#~ "l'opció a la cadena especial «disabled», no hi haurà cap vinculació per a " -#~ "aquesta acció." +#~ msgid "Coordinate expression contains character '%s' which is not allowed" +#~ msgstr "L'expressió coordinada conté el caràcter '%s', el qual no és permès" #~ msgid "" -#~ "The keybinding used to move a window to workspace 11. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "Coordinate expression contains floating point number '%s' which could not " +#~ "be parsed" #~ msgstr "" -#~ "La vinculació de tecles per a moure una finestra a l'espai de treball 11. " -#~ "El format és semblant a «<Control>a» o «<Shift><Alt>" -#~ "F1». L'analitzador és prou flexible i permet minúscules i majúscules, i " -#~ "també abreviacions com «<Ctl>» i «<Ctrl>». Si establiu " -#~ "l'opció a la cadena especial «disabled», no hi haurà cap vinculació per a " -#~ "aquesta acció." +#~ "L'expressió coordinada conté el número '%s' de punt flotant el qual no es " +#~ "pot analitzar" #~ msgid "" -#~ "The keybinding used to move a window to workspace 12. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "Coordinate expression contains integer '%s' which could not be parsed" #~ msgstr "" -#~ "La vinculació de tecles per a moure una finestra a l'espai de treball 12. " -#~ "El format és semblant a «<Control>a» o «<Shift><Alt>" -#~ "F1». L'analitzador és prou flexible i permet minúscules i majúscules, i " -#~ "també abreviacions com «<Ctl>» i «<Ctrl>». Si establiu " -#~ "l'opció a la cadena especial «disabled», no hi haurà cap vinculació per a " -#~ "aquesta acció." +#~ "L'expressió coordinada conté l'enter '%s' el qual no es pot analitzar" #~ msgid "" -#~ "The keybinding used to move a window to workspace 2. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "Coordinate expression contained unknown operator at the start of this " +#~ "text: \"%s\"" #~ msgstr "" -#~ "La vinculació de tecles per a moure una finestra a l'espai de treball 2. " -#~ "El format és semblant a «<Control>a» o «<Shift><Alt>" -#~ "F1». L'analitzador és prou flexible i permet minúscules i majúscules, i " -#~ "també abreviacions com «<Ctl>» i «<Ctrl>». Si establiu " -#~ "l'opció a la cadena especial «disabled», no hi haurà cap vinculació per a " -#~ "aquesta acció." +#~ "L'expressió coordinada conté un operador desconegut a l'inici d'aquest " +#~ "text: «%s»" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 3. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "La vinculació de tecles per a moure una finestra a l'espai de treball 3. " -#~ "El format és semblant a «<Control>a» o «<Shift><Alt>" -#~ "F1». L'analitzador és prou flexible i permet minúscules i majúscules, i " -#~ "també abreviacions com «<Ctl>» i «<Ctrl>». Si establiu " -#~ "l'opció a la cadena especial «disabled», no hi haurà cap vinculació per a " -#~ "aquesta acció." +#~ msgid "Coordinate expression was empty or not understood" +#~ msgstr "L'expressió coordinada estava buida o no s'ha entès" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 4. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "La vinculació de tecles per a moure una finestra a l'espai de treball 4. " -#~ "El format és semblant a «<Control>a» o «<Shift><Alt>" -#~ "F1». L'analitzador és prou flexible i permet minúscules i majúscules, i " -#~ "també abreviacions com «<Ctl>» i «<Ctrl>». Si establiu " -#~ "l'opció a la cadena especial «disabled», no hi haurà cap vinculació per a " -#~ "aquesta acció." +#~ msgid "Coordinate expression results in division by zero" +#~ msgstr "L'expressió coordinada dóna una divisió per zero" #~ msgid "" -#~ "The keybinding used to move a window to workspace 5. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "Coordinate expression tries to use mod operator on a floating-point number" #~ msgstr "" -#~ "La vinculació de tecles per a moure una finestra a l'espai de treball 5. " -#~ "El format és semblant a «<Control>a» o «<Shift><Alt>" -#~ "F1». L'analitzador és prou flexible i permet minúscules i majúscules, i " -#~ "també abreviacions com «<Ctl>» i «<Ctrl>». Si establiu " -#~ "l'opció a la cadena especial «disabled», no hi haurà cap vinculació per a " -#~ "aquesta acció." +#~ "L'expressió coordinada intenta utilitzar l'operador de mode en un número " +#~ "de punt flotant" #~ msgid "" -#~ "The keybinding used to move a window to workspace 6. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "Coordinate expression has an operator \"%s\" where an operand was expected" #~ msgstr "" -#~ "La vinculació de tecles per a moure una finestra a l'espai de treball 6. " -#~ "El format és semblant a «<Control>a» o «<Shift><Alt>" -#~ "F1». L'analitzador és prou flexible i permet minúscules i majúscules, i " -#~ "també abreviacions com «<Ctl>» i «<Ctrl>». Si establiu " -#~ "l'opció a la cadena especial «disabled», no hi haurà cap vinculació per a " -#~ "aquesta acció." +#~ "L'expressió coordinada té un operador «%s» on hi hauria d'anar un operand" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 7. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ msgid "Coordinate expression had an operand where an operator was expected" #~ msgstr "" -#~ "La vinculació de tecles per a moure una finestra a l'espai de treball 7. " -#~ "El format és semblant a «<Control>a» o «<Shift><Alt>" -#~ "F1». L'analitzador és prou flexible i permet minúscules i majúscules, i " -#~ "també abreviacions com «<Ctl>» i «<Ctrl>». Si establiu " -#~ "l'opció a la cadena especial «disabled», no hi haurà cap vinculació per a " -#~ "aquesta acció." +#~ "L'expressió coordinada té un operand on hi hauria d'anar un operador" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 8. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ msgid "Coordinate expression ended with an operator instead of an operand" #~ msgstr "" -#~ "La vinculació de tecles per a moure una finestra a l'espai de treball 8. " -#~ "El format és semblant a «<Control>a» o «<Shift><Alt>" -#~ "F1». L'analitzador és prou flexible i permet minúscules i majúscules, i " -#~ "també abreviacions com «<Ctl>» i «<Ctrl>». Si establiu " -#~ "l'opció a la cadena especial «disabled», no hi haurà cap vinculació per a " -#~ "aquesta acció." +#~ "L'expressió coordinada ha finalitzat amb un operador en lloc d'un operand" #~ msgid "" -#~ "The keybinding used to move a window to workspace 9. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "Coordinate expression has operator \"%c\" following operator \"%c\" with " +#~ "no operand in between" #~ msgstr "" -#~ "La vinculació de tecles per a moure una finestra a l'espai de treball 9. " -#~ "El format és semblant a «<Control>a» o «<Shift><Alt>" -#~ "F1». L'analitzador és prou flexible i permet minúscules i majúscules, i " -#~ "també abreviacions com «<Ctl>» i «<Ctrl>». Si establiu " -#~ "l'opció a la cadena especial «disabled», no hi haurà cap vinculació per a " -#~ "aquesta acció." +#~ "L'expressió coordinada té un operador «%c» seguit de l'operador «%c» " +#~ "sense cap operand enmig" -#~ msgid "" -#~ "The keybinding used to move focus backwards between panels and the " -#~ "desktop, using a popup window. The format looks like \"<Control>a\" " -#~ "or \"<Shift><Alt>F1\". The parser is fairly liberal and " -#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" -#~ "\" and \"<Ctrl>\". If you set the option to the special string " -#~ "\"disabled\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles que mou el focus cap enrere entre els quadres i " -#~ "l'escriptori, utilitzant una finestra emergent. El format és semblant a " -#~ "«<Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." +#~ msgid "Coordinate expression had unknown variable or constant \"%s\"" +#~ msgstr "L'expressió coordinada té una variable o constant desconeguda «%s»" -#~ msgid "" -#~ "The keybinding used to move focus backwards between panels and the " -#~ "desktop, without a popup window. The format looks like \"<Control>a" -#~ "\" or \"<Shift><Alt>F1\". The parser is fairly liberal and " -#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" -#~ "\" and \"<Ctrl>\". If you set the option to the special string " -#~ "\"disabled\", then there will be no keybinding for this action." +#~ msgid "Coordinate expression parser overflowed its buffer." #~ msgstr "" -#~ "La vinculació de tecles que mou el focus cap enrere entre els quadres i " -#~ "l'escriptori, sense utilitzar una finestra emergent. El format és " -#~ "semblant a «<Control>a» o «<Shift><Alt>F1». " -#~ "L'analitzador és prou flexible i permet minúscules i majúscules, i també " -#~ "abreviacions com «<Ctl>» i «<Ctrl>». Si establiu l'opció a la " -#~ "cadena especial «disabled», no hi haurà cap vinculació per a aquesta " -#~ "acció." +#~ "L'analitzador d'expressions de coordinades ha desbordat la seva memòria " +#~ "intermèdia." #~ msgid "" -#~ "The keybinding used to move focus backwards between windows of an " -#~ "application without a popup window. Holding \"shift\" together with this " -#~ "binding makes the direction go forward again. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "Coordinate expression had a close parenthesis with no open parenthesis" #~ msgstr "" -#~ "La vinculació de tecles que mou el focus cap enrere entre finestres d'una " -#~ "aplicació, sense utilitzar una finestra emergent. Mantenint premuda la " -#~ "techa de «majúscules» juntament amb aquesta convinació de tecles, fa que " -#~ "es vagi enrere. El format és semblant a «<Control>a» o «<" -#~ "Shift><Alt>F1». L'analitzador és força flexible i permet " -#~ "minúscules i majúscules, i també abreviacions com «<Ctl>» i «<" -#~ "Ctrl>». Si establiu l'opció a la cadena especial «disabled», no hi " -#~ "haurà cap vinculació per a aquesta acció." +#~ "L'expressió coordinada té un parèntesi de tancament i cap d'obertura" #~ msgid "" -#~ "The keybinding used to move focus backwards between windows of an " -#~ "application, using a popup window. Holding \"shift\" together with this " -#~ "binding makes the direction go forward again. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "Coordinate expression had an open parenthesis with no close parenthesis" #~ msgstr "" -#~ "La vinculació de tecles que mou el focus cap enrere entre finestres d'una " -#~ "mateixa aplicació, utilitzant una finestra emergent. Prement la tecla de " -#~ "majúscules aquesta vinculació fa que la direcció sigui cap enrere. El " -#~ "format és semblant a «<Control>a» o «<Shift><Alt>F1». " -#~ "L'analitzador és prou flexible i permet minúscules i majúscules, i també " -#~ "abreviacions com «<Ctl>» i «<Ctrl>». Si establiu l'opció a la " -#~ "cadena especial «disabled» (inhabilitat), no hi haurà cap vinculació per " -#~ "a aquesta acció." +#~ "L'expressió coordinada té un parèntesi d'obertura i cap de tancament" -#~ msgid "" -#~ "The keybinding used to move focus backwards between windows without a " -#~ "popup window. Holding \"shift\" together with this binding makes the " -#~ "direction go forward again. The format looks like \"<Control>a\" or " -#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " -#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" -#~ "\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles que mou el focus cap enrere entre finestres, " -#~ "sense utilitzar una finestra emergent. El format és semblant a «<" -#~ "Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." +#~ msgid "Coordinate expression doesn't seem to have any operators or operands" +#~ msgstr "L'expressió coordinada no sembla tenir cap operador o operand" -#~ msgid "" -#~ "The keybinding used to move focus backwards between windows, using a " -#~ "popup window. Holding \"shift\" together with this binding makes the " -#~ "direction go forward again. The format looks like \"<Control>a\" or " -#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " -#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" -#~ "\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles que mou el focus cap enrere entre finestres, " -#~ "utilitzant una finestra emergent. El format és semblant a «<Control>" -#~ "a» o «<Shift><Alt>F1». L'analitzador és prou flexible i " -#~ "permet minúscules i majúscules, i també abreviacions com «<Ctl>» i " -#~ "«<Ctrl>». Si establiu l'opció a la cadena especial «disabled», no " -#~ "hi haurà cap vinculació per a aquesta acció." +#~ msgid "Theme contained an expression that resulted in an error: %s\n" +#~ msgstr "El tema conté una expressió que ha provocat un error: %s\n" #~ msgid "" -#~ "The keybinding used to move focus between panels and the desktop, using a " -#~ "popup window. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " +#~ "specified for this frame style" #~ msgstr "" -#~ "La vinculació de tecles que mou el focus entre els quadres i " -#~ "l'escriptori, utilitzant una finestra emergent. El format és semblant a " -#~ "«<Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"qualsevol\"/> s'ha " +#~ "d'especificar per a aquest estil de marc" #~ msgid "" -#~ "The keybinding used to move focus between panels and the desktop, without " -#~ "a popup window. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." +#~ "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/" +#~ ">" #~ msgstr "" -#~ "La vinculació de tecles que mou el focus entre els quadres i " -#~ "l'escriptori, sense utilitzar una finestra emergent. El format és " -#~ "semblant a «<Control>a» o «<Shift><Alt>F1». " -#~ "L'analitzador és prou flexible i permet minúscules i majúscules, i també " -#~ "abreviacions com «<Ctl>» i «<Ctrl>». Si establiu l'opció a la " -#~ "cadena especial «disabled», no hi haurà cap vinculació per a aquesta " -#~ "acció." +#~ "No s'ha trobat <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=" +#~ "\"qualsevol\"/>" -#~ msgid "" -#~ "The keybinding used to move focus between windows of an application " -#~ "without a popup window. Holding the \"shift\" key while using this " -#~ "binding reverses the direction of movement. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "La vinculació de tecles que mou el focus entre finestres d'una aplicació, " -#~ "sense utilitzar una finestra emergent. Prement la tecla de majúscules " -#~ "aquesta vinculació fa que la direcció sigui cap enrere. El format és " -#~ "semblant a «<Control>a» o «<Shift><Alt>F1». " -#~ "L'analitzador és prou flexible i permet minúscules i majúscules, i també " -#~ "abreviacions com «<Ctl>» i «<Ctrl>». Si establiu l'opció a la " -#~ "cadena especial «disabled», no hi haurà cap vinculació per a aquesta " -#~ "acció." +#~ msgid "Failed to load theme \"%s\": %s\n" +#~ msgstr "No s'ha pogut carregar el tema \"%s\": %s\n" -#~ msgid "" -#~ "The keybinding used to move focus between windows of an application, " -#~ "using a popup window. (Traditionally <Alt>F6) Holding the \"shift\" " -#~ "key while using this binding reverses the direction of movement. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles que mou el focus entre finestres d'una aplicació, " -#~ "utilitzant una finestra emergent. (Tradicionalment <Alt>F6) Prement " -#~ "la tecla de majúscules aquesta vinculació fa que la direcció sigui al " -#~ "revés. El format és semblant a «<Control>a» o «<Shift><" -#~ "Alt>F1». L'analitzador és prou flexible i permet minúscules i " -#~ "majúscules, i també abreviacions com «<Ctl>» i «<Ctrl>». Si " -#~ "establiu l'opció a la cadena especial «disabled», no hi haurà cap " -#~ "vinculació per a aquesta acció." +#~ msgid "No <%s> set for theme \"%s\"" +#~ msgstr "No s'ha definit <%s> per al tema «%s»" #~ msgid "" -#~ "The keybinding used to move focus between windows without a popup window. " -#~ "(Traditionally <Alt>Escape) Holding the \"shift\" key while using " -#~ "this binding reverses the direction of movement. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "No frame style set for window type \"%s\" in theme \"%s\", add a <window " +#~ "type=\"%s\" style_set=\"whatever\"/> element" #~ msgstr "" -#~ "La vinculació de tecles que mou el focus entre finestres, sense utilitzar " -#~ "una finestra emergent. El format és semblant a «<Control>a» o «<" -#~ "Shift><Alt>F1». L'analitzador és prou flexible i permet " -#~ "minúscules i majúscules, i també abreviacions com «<Ctl>» i «<" -#~ "Ctrl>». Si establiu l'opció a la cadena especial «disabled», no hi " -#~ "haurà cap vinculació per a aquesta acció." +#~ "No s'ha definit cap estil de marc per al tipus de finestra \"%s\" en el " +#~ "tema \"%s\", afegiu un element <window type=\"%s\" style_set=\"qualsevol" +#~ "\"/>" #~ msgid "" -#~ "The keybinding used to move focus between windows, using a popup window. " -#~ "(Traditionally <Alt>Tab) Holding the \"shift\" key while using this " -#~ "binding reverses the direction of movement. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "User-defined constants must begin with a capital letter; \"%s\" does not" #~ msgstr "" -#~ "La vinculació de tecles que mou el focus entre finestres, utilitzant una " -#~ "finestra emergent. El format és semblant a «<Control>a» o «<" -#~ "Shift><Alt>F1». L'analitzador és prou flexible i permet " -#~ "minúscules i majúscules, i també abreviacions com «<Ctl>» i «<" -#~ "Ctrl>». Si establiu l'opció a la cadena especial «disabled», no hi " -#~ "haurà cap vinculació per a aquesta acció." +#~ "Les constants de la definició d'usuari han de començar per una majúscula; " +#~ "«%s» no ho és" -#~ msgid "" -#~ "The keybinding used to toggle always on top. A window that is always on " -#~ "top will always be visible over other overlapping windows. The format " -#~ "looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -#~ "parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles per a seleccionar si una finestra està sempre per " -#~ "damunt. Una finestra que estiga sempre per damunt serà visible per damunt " -#~ "de les altres finestres que s'interseccionen. El format és semblant a " -#~ "«<Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." +#~ msgid "Constant \"%s\" has already been defined" +#~ msgstr "La constant «%s» ja s'ha definit" -#~ msgid "" -#~ "The keybinding used to toggle fullscreen mode. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "La vinculació de tecles que habilita o inhabilita el mode a pantalla " -#~ "sencera. El format és semblant a «<Control>a» o «<Shift><" -#~ "Alt>F1». L'analitzador és prou flexible i permet minúscules i " -#~ "majúscules, i també abreviacions com «<Ctl>» i «<Ctrl>». Si " -#~ "establiu l'opció a la cadena especial «disabled», no hi haurà cap " -#~ "vinculació per a aquesta acció." +#~ msgid "No \"%s\" attribute on element <%s>" +#~ msgstr "No hi ha cap atribut «%s» a l'element <%s>" -#~ msgid "" -#~ "The keybinding used to toggle maximization. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "La vinculació de tecles per a maximitzar o desmaximitzar una finestra. El " -#~ "format és semblant a «<Control>a» o «<Shift><Alt>F1». " -#~ "L'analitzador és prou flexible i permet minúscules i majúscules, i també " -#~ "abreviacions com «<Ctl>» i «<Ctrl>». Si establiu l'opció a la " -#~ "cadena especial «disabled», no hi haurà cap vinculació per a aquesta " -#~ "acció." +#~ msgid "Line %d character %d: %s" +#~ msgstr "Línia %d caràcter %d: %s" -#~ msgid "" -#~ "The keybinding used to toggle shaded/unshaded state. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "La vinculació de tecles per a canviar entre l'estat ombrejat i " -#~ "desombrejat. El format és «<Control>a» o «<Shift><Alt>" -#~ "F1». L'analitzador és prou flexible i permet minúscules i majúscules, i " -#~ "també abreviacions com «<Ctl>» i «<Ctrl>». Si establiu " -#~ "l'opció a la cadena especial «disabled», no hi haurà cap vinculació per a " -#~ "aquesta acció." +#~ msgid "Attribute \"%s\" repeated twice on the same <%s> element" +#~ msgstr "S'ha repetit l'atribut «%s» dues vegades en el mateix element <%s>" -#~ msgid "" -#~ "The keybinding used to toggle whether the window is on all workspaces or " -#~ "just one. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles per a seleccionar si una finestra està en tots " -#~ "els espais de treball o només en un. El format és semblant a «<" -#~ "Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." +#~ msgid "Attribute \"%s\" is invalid on <%s> element in this context" +#~ msgstr "L'atribut «%s» no és vàlid per a l'element <%s> en aquest context" -#~ msgid "" -#~ "The keybinding used to unmaximize a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "La vinculació de tecles per a desmaximitzar una finestra. El format és " -#~ "semblant a «<Control>a» o «<Shift><Alt>F1». " -#~ "L'analitzador és prou flexible i permet minúscules i majúscules, i també " -#~ "abreviacions com «<Ctl>» i «<Ctrl>». Si establiu l'opció a la " -#~ "cadena especial «disabled», no hi haurà cap vinculació per a aquesta " -#~ "acció." +#~ msgid "Could not parse \"%s\" as an integer" +#~ msgstr "No s'ha pogut analitzar «%s» com a enter" -#~ msgid "" -#~ "The keybinding which display's the panel's \"Run Application\" dialog " -#~ "box. The format looks like \"<Control>a\" or \"<Shift><" -#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If " -#~ "you set the option to the special string \"disabled\", then there will be " -#~ "no keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles que mostra el diàleg «Executa un programa» del " -#~ "quadre. El format és semblant a «<Control>a» o «<Shift><" -#~ "Alt>F1». L'analitzador és prou flexible i permet minúscules i " -#~ "majúscules, i també abreviacions com «<Ctl>» i «<Ctrl>». Si " -#~ "establiu l'opció a la cadena especial «disabled», no hi haurà cap " -#~ "vinculació per a aquesta acció." +#~ msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +#~ msgstr "No s'entenen els caràcters finals «%s» de la cadena «%s»" -#~ msgid "" -#~ "The keybinding which invokes a terminal. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "La vinculació de tecles que executa un terminal. El format és semblant a " -#~ "«<Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." +#~ msgid "Integer %ld must be positive" +#~ msgstr "L'enter %ld ha de ser positiu" -#~ msgid "" -#~ "The keybinding which invokes the panel's screenshot utility to take a " -#~ "screenshot of a window. The format looks like \"<Control>a\" or " -#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " -#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" -#~ "\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles que invoca la utilitat de captures de pantalla " -#~ "del quadre per a prendre una captura d'una finestra. El format és " -#~ "semblant a «<Control>a» o «<Shift><Alt>F1». " -#~ "L'analitzador és prou flexible i permet minúscules i majúscules, i també " -#~ "abreviacions com «<Ctl>» i «<Ctrl>». Si establiu l'opció a la " -#~ "cadena especial «disabled», no hi haurà cap vinculació per a aquesta " -#~ "acció." +#~ msgid "Integer %ld is too large, current max is %d" +#~ msgstr "L'enter %ld és massa gran, el màxim actual és %d" -#~ msgid "" -#~ "The keybinding which invokes the panel's screenshot utility. The format " -#~ "looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -#~ "parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "La vinculació de tecles que invoca la utilitat de captures de pantalla " -#~ "del quadre. El format és semblant a «<Control>a» o «<Shift>" -#~ "<Alt>F1». L'analitzador és prou flexible i permet minúscules i " -#~ "majúscules, i també abreviacions com «<Ctl>» i «<Ctrl>». Si " -#~ "establiu l'opció a la cadena especial «disabled», no hi haurà cap " -#~ "vinculació per a aquesta acció." +#~ msgid "Could not parse \"%s\" as a floating point number" +#~ msgstr "No s'ha pogut analitzar «%s» com a un número de coma flotant" -#~ msgid "" -#~ "The keybinding which shows the panel's main menu. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" #~ msgstr "" -#~ "La vinculació de tecles que mostra el menú principal del quadre. El " -#~ "format és semblant a «<Control>a» o «<Shift><Alt>F1». " -#~ "L'analitzador és prou flexible i permet minúscules i majúscules, i també " -#~ "abreviacions com «<Ctl>» i «<Ctrl>». Si establiu l'opció a la " -#~ "cadena especial «disabled», no hi haurà cap vinculació per a aquesta " -#~ "acció." +#~ "Els valors booleans han de ser «true» (cert) o «false» (fals), no «%s»" -#~ msgid "" -#~ "This keybinding changes whether a window is above or below other windows. " -#~ "If the window is covered by another one, it raises the window above all " -#~ "others, and if the window is already fully visible, it lowers it below " -#~ "all others. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Aquesta vinculació de tecles canvia si una finestra és per damunt o per " -#~ "sota d'altres finestres. Si la finestra està coberta per una altra " -#~ "finestra, s'alça la finestra per damunt de les altres, quedant totalment " -#~ "visible, i posa a sota les altres. El format és semblant a «<" -#~ "Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." +#~ msgid "Angle must be between 0.0 and 360.0, was %g\n" +#~ msgstr "L'angle ha d'estar entre 0.0 i 360.0, era %g\n" #~ msgid "" -#~ "This keybinding lowers a window below other windows. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" #~ msgstr "" -#~ "Aquesta vinculació de tecles fica una finestra sota les altres. El format " -#~ "és semblant a «<Control>a» o «<Shift><Alt>F1». " -#~ "L'analitzador és prou flexible i permet minúscules i majúscules, i també " -#~ "abreviacions com «<Ctl>» i «<Ctrl>». Si establiu l'opció a la " -#~ "cadena especial «disabled», no hi haurà cap vinculació per a aquesta " -#~ "acció." +#~ "L'opacitat ha d'estar entre 0.0 (invisible) i 1.0 (totalment opac), era a " +#~ "%g\n" #~ msgid "" -#~ "This keybinding moves a window against the north (top) side of the " -#~ "screen. The format looks like \"<Control>a\" or \"<Shift><" -#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If " -#~ "you set the option to the special string \"disabled\", then there will be " -#~ "no keybinding for this action." +#~ "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," +#~ "large,x-large,xx-large)\n" #~ msgstr "" -#~ "Aquesta vinculació de tecles mou una finestra cap a la part nord " -#~ "(superior) de la pantalla. El format és semblant a «<Control>a» o " -#~ "«<Shift><Alt>F1». L'analitzador és prou flexible i permet " -#~ "minúscules i majúscules, i també abreviacions com «<Ctl>» i «<" -#~ "Ctrl>». Si establiu l'opció a la cadena especial «disabled», no hi " -#~ "haurà cap vinculació per a aquesta acció." +#~ "Escala de títol no vàlida «%s» (ha de ser una d'aquestes: xx-small, x-" +#~ "small, small, medium, large, x-large o xx-large)\n" -#~ msgid "" -#~ "This keybinding moves a window into the east (right) side of the screen. " -#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>" -#~ "F1\". The parser is fairly liberal and allows lower or upper case, and " -#~ "also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -#~ "set the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Aquesta vinculació de tecles mou una finestra cap a la part est (dreta) " -#~ "de la pantalla. El format és semblant a «<Control>a» o «<" -#~ "Shift><Alt>F1». L'analitzador és prou flexible i permet " -#~ "minúscules i majúscules, i també abreviacions com «<Ctl>» i «<" -#~ "Ctrl>». Si establiu l'opció a la cadena especial «disabled», no hi " -#~ "haurà cap vinculació per a aquesta acció." +#~ msgid "<%s> name \"%s\" used a second time" +#~ msgstr "<%s> amb nom «%s» s'ha utilitzat dues vegades" -#~ msgid "" -#~ "This keybinding moves a window into the north-east (top right) corner of " -#~ "the screen. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Aquesta vinculació de tecles mou una finestra cap a la part nord-est " -#~ "(superior a la dreta) de la pantalla. El format és semblant a «<" -#~ "Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." +#~ msgid "<%s> parent \"%s\" has not been defined" +#~ msgstr "el pare de <%s>, «%s», no s'ha definit" -#~ msgid "" -#~ "This keybinding moves a window into the north-west (top left) corner of " -#~ "the screen. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Aquesta vinculació de tecles mou una finestra cap a la part nord-oest " -#~ "(superior a l'esquerra) de la pantalla. El format és semblant a «<" -#~ "Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." +#~ msgid "<%s> geometry \"%s\" has not been defined" +#~ msgstr "la geometria de <%s>, «%s», no s'ha definit" -#~ msgid "" -#~ "This keybinding moves a window into the south (bottom) side of the " -#~ "screen. The format looks like \"<Control>a\" or \"<Shift><" -#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If " -#~ "you set the option to the special string \"disabled\", then there will be " -#~ "no keybinding for this action." +#~ msgid "<%s> must specify either a geometry or a parent that has a geometry" #~ msgstr "" -#~ "Aquesta vinculació de tecles mou una finestra cap a la part del sud " -#~ "(inferior) de la pantalla. El format és semblant a «<Control>a» o " -#~ "«<Shift><Alt>F1». L'analitzador és prou flexible i permet " -#~ "minúscules i majúscules, i també abreviacions com «<Ctl>» i «<" -#~ "Ctrl>». Si establiu l'opció a la cadena especial «disabled», no hi " -#~ "haurà cap vinculació per a aquesta acció." +#~ "<%s> ha d'especificar bé una geometria o un pare que tingui una geometria" -#~ msgid "" -#~ "This keybinding moves a window into the south-east (bottom right) corner " -#~ "of the screen. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "Aquesta vinculació de tecles mou una finestra cap a la part sud-est de la " -#~ "pantalla. El format és semblant a «<Control>a» o «<Shift><" -#~ "Alt>F1». L'analitzador és prou flexible i permet minúscules i " -#~ "majúscules, i també abreviacions com «<Ctl>» i «<Ctrl>». Si " -#~ "establiu l'opció a la cadena especial «disabled», no hi haurà cap " -#~ "vinculació per a aquesta acció." +#~ msgid "You must specify a background for an alpha value to be meaningful" +#~ msgstr "El valor alfa requereix que també s'especifiqui un fons de pantalla" -#~ msgid "" -#~ "This keybinding moves a window into the south-west (bottom left) corner " -#~ "of the screen. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "Aquesta vinculació de tecles mou una finestra cap a la part sud-oest " -#~ "(inferior a l'esquerra) de la pantalla. El format és semblant a «<" -#~ "Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." +#~ msgid "Unknown type \"%s\" on <%s> element" +#~ msgstr "Tipus desconegut «%s» en l'element <%s>" -#~ msgid "" -#~ "This keybinding moves a window into the west (left) side of the screen. " -#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>" -#~ "F1\". The parser is fairly liberal and allows lower or upper case, and " -#~ "also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -#~ "set the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Aquesta vinculació de tecles mou una finestra cap a la part l'oest " -#~ "(esquerra) de la pantalla. El format és semblant a «<Control>a» o " -#~ "«<Shift><Alt>F1». L'analitzador és prou flexible i permet " -#~ "minúscules i majúscules, i també abreviacions com «<Ctl>» i «<" -#~ "Ctrl>». Si establiu l'opció a la cadena especial «disabled», no hi " -#~ "haurà cap vinculació per a aquesta acció." +#~ msgid "Unknown style_set \"%s\" on <%s> element" +#~ msgstr "style_set «%s» desconegut en l'element <%s>" -#~ msgid "" -#~ "This keybinding raises the window above other windows. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Aquesta vinculació de tecles eleva la finestra per damunt de les altres. " -#~ "El format és semblant a «<Control>a» o «<Shift><Alt>" -#~ "F1». L'analitzador és prou flexible i permet minúscules i majúscules, i " -#~ "també abreviacions com «<Ctl>» i «<Ctrl>». Si establiu " -#~ "l'opció a la cadena especial «disabled», no hi haurà cap vinculació per a " -#~ "aquesta acció." +#~ msgid "Window type \"%s\" has already been assigned a style set" +#~ msgstr "El tipus de finestra «%s» ja té assignat un joc d'estil" -#~ msgid "" -#~ "This keybinding resizes a window to fill available horizontal space. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Aquesta vinculació de tecles redimensiona una finestra per a que plene " -#~ "tot l'espai horitzontal disponible. El format és semblant a «<" -#~ "Control>a» o «<Shift><Alt>F1». L'analitzador és prou " -#~ "flexible i permet minúscules i majúscules, i també abreviacions com «<" -#~ "Ctl>» i «<Ctrl>». Si establiu l'opció a la cadena especial " -#~ "«disabled», no hi haurà cap vinculació per a aquesta acció." +#~ msgid "Element <%s> is not allowed below <%s>" +#~ msgstr "No es permet l'element <%s> sota <%s>" #~ msgid "" -#~ "This keybinding resizes a window to fill available vertical space. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." +#~ "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio" +#~ "\" for buttons" #~ msgstr "" -#~ "Aquesta vinculació de tecles redimensiona una finestra per a que plene " -#~ "tot l'espai vertical disponible. El format és semblant a «<Control>" -#~ "a» o «<Shift><Alt>F1». L'analitzador és prou flexible i " -#~ "permet minúscules i majúscules, i també abreviacions com «<Ctl>» i " -#~ "«<Ctrl>». Si establiu l'opció a la cadena especial «disabled», no " -#~ "hi haurà cap vinculació per a aquesta acció." - -#~ msgid "Unmaximize Window" -#~ msgstr "Desmaximitza la finestra" +#~ "No es pot especificar «button_width»/«button_height» i l'«aspect_ratio» a " +#~ "la vegada per als botons" -#~ msgid "No \"%s\" attribute on <%s> element" -#~ msgstr "Cap atribut «%s» a l'element <%s>" +#~ msgid "Distance \"%s\" is unknown" +#~ msgstr "La distància «%s» és desconeguda" -#~ msgid "Theme already has a fallback icon" -#~ msgstr "El tema ja té una icona alternativa" +#~ msgid "Aspect ratio \"%s\" is unknown" +#~ msgstr "La relació d'aspecte «%s» és desconeguda" -#~ msgid "Theme already has a fallback mini_icon" -#~ msgstr "El tema ja té una miniicona alternativa" +#~ msgid "Border \"%s\" is unknown" +#~ msgstr "El contorn «%s» és desconegut" -#~ msgid "No \"name\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut de «nom» en l'element <%s>" +#~ msgid "No \"start_angle\" or \"from\" attribute on element <%s>" +#~ msgstr "No hi ha cap atribut de «start_angle» o «from» en l'element <%s>" -#~ msgid "No \"value\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut de «valor» a l'element <%s>" +#~ msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" +#~ msgstr "No hi ha cap atribut de «extent_angle» o «to» en l'element <%s>" -#~ msgid "No \"top\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut de «top» a l'element <%s>" +#~ msgid "Did not understand value \"%s\" for type of gradient" +#~ msgstr "No s'entén el valor «%s» per al tipus de degradat" -#~ msgid "No \"bottom\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut de «bottom» a l'element <%s>" +#~ msgid "Did not understand fill type \"%s\" for <%s> element" +#~ msgstr "No s'entén el tipus de farciment «%s» per a l'element <%s>" -#~ msgid "No \"left\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut de «left» a l'element <%s>" +#~ msgid "Did not understand state \"%s\" for <%s> element" +#~ msgstr "No s'entén l'estat «%s» per a l'element <%s>" -#~ msgid "No \"right\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut de «right» a l'element <%s>" +#~ msgid "Did not understand shadow \"%s\" for <%s> element" +#~ msgstr "No s'entén l'ombra «%s» per a l'element <%s>" -#~ msgid "No \"color\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut de «color» a l'element <%s>" +#~ msgid "Did not understand arrow \"%s\" for <%s> element" +#~ msgstr "No s'entén la fletxa «%s» per a l'element <%s>" -#~ msgid "No \"x1\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut de «x1» a l'element <%s>" +#~ msgid "No <draw_ops> called \"%s\" has been defined" +#~ msgstr "No s'ha definit cap <draw_ops> amb el nom «%s»" -#~ msgid "No \"y1\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut de «y1» a l'element <%s>" +#~ msgid "Including draw_ops \"%s\" here would create a circular reference" +#~ msgstr "La inclusió de draw_ops «%s» aquí crearà una referència circular" -#~ msgid "No \"x2\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut de «x2» a l'element <%s>" +#~ msgid "Unknown position \"%s\" for frame piece" +#~ msgstr "Posició «%s» desconeguda per a la peça del marc" -#~ msgid "No \"y2\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut de «y2» a l'element <%s>" +#~ msgid "Frame style already has a piece at position %s" +#~ msgstr "L'estil del marc ja té una peça a posició %s" -#~ msgid "No \"y\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut de «y» a l'element <%s>" +#~ msgid "No <draw_ops> with the name \"%s\" has been defined" +#~ msgstr "No s'ha definit cap <draw_ops> amb el nom «%s»" -#~ msgid "No \"width\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut de «amplada» en l'element <%s>" +#~ msgid "Unknown function \"%s\" for button" +#~ msgstr "Funció «%s» desconeguda per al botó" -#~ msgid "No \"height\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut de «height» en l'element <%s>" - -#~ msgid "No \"start_angle\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut de «start_angle» en l'element <%s>" - -#~ msgid "No \"extent_angle\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut de «extent_angle» en l'element <%s>" +#~ msgid "Button function \"%s\" does not exist in this version (%d, need %d)" +#~ msgstr "" +#~ "La funció de botó «%s» no existeix en aquesta versió (%d, es necessita %d)" -#~ msgid "No \"alpha\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut «alpha» a l'element <%s>" +#~ msgid "Unknown state \"%s\" for button" +#~ msgstr "Estat «%s» desconegut per al botó" -#~ msgid "No \"type\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut «type» a l'element <%s>" +#~ msgid "Frame style already has a button for function %s state %s" +#~ msgstr "L'estil del marc ja té un botó per a l'estat %s de la funció %s" -#~ msgid "No \"filename\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut «filename» a l'element <%s>" +#~ msgid "\"%s\" is not a valid value for focus attribute" +#~ msgstr "«%s» no és un valor vàlid per a l'atribut del focus" -#~ msgid "No \"state\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut «state» a l'element <%s>" +#~ msgid "\"%s\" is not a valid value for state attribute" +#~ msgstr "«%s» no és un valor vàlid per a l'atribut de l'estat" -#~ msgid "No \"shadow\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut «shadow» a l'element <%s>" +#~ msgid "A style called \"%s\" has not been defined" +#~ msgstr "No s'ha definit un estil amb el nom «%s»" -#~ msgid "No \"arrow\" attribute on element <%s>" -#~ msgstr "No hi ha cap atribut «arrow» a l'element <%s>" +#~ msgid "\"%s\" is not a valid value for resize attribute" +#~ msgstr "«%s» no és un valor vàlid per a l'atribut de redimensiona" -#~ msgid "No \"value\" attribute on <%s> element" -#~ msgstr "No hi ha cap atribut «valor» a l'element <%s>" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized/shaded " +#~ "states" +#~ msgstr "" +#~ "No hauria de tenir l'atribut «resize» en l'element <%s> per als estats " +#~ "maximitzat/ombrejat" -#~ msgid "No \"position\" attribute on <%s> element" -#~ msgstr "No hi ha cap atribut «posició» a l'element <%s>" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized states" +#~ msgstr "" +#~ "No hauria de tenir l'atribut «resize» en l'element <%s> per als estats " +#~ "maximitzats" -#~ msgid "No \"function\" attribute on <%s> element" -#~ msgstr "No hi ha cap atribut de «funció» a l'element <%s>" +#~ msgid "Style has already been specified for state %s resize %s focus %s" +#~ msgstr "" +#~ "L'estil ja s'ha especificat per a l'estat %s redimensiona %s focus %s" -#~ msgid "No \"state\" attribute on <%s> element" -#~ msgstr "No hi ha cap atribut de «estat» a l'element <%s>" +#~ msgid "Style has already been specified for state %s focus %s" +#~ msgstr "L'estil ja s'ha especificat per a l'estat %s focus %s" -#~ msgid "No \"focus\" attribute on <%s> element" -#~ msgstr "No hi ha cap atribut de «focus» en l'element <%s>" +#~ msgid "" +#~ "Can't have a two draw_ops for a <piece> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "No es poden tenir dos draw_ops per a un element <piece> (el tema ha " +#~ "especificat un atribut draw_ops i també un element <draw_ops>, o ha " +#~ "especificat ambdós elements) " -#~ msgid "No \"style\" attribute on <%s> element" -#~ msgstr "No hi ha cap atribut de «style» a l'element <%s>" +#~ msgid "" +#~ "Can't have a two draw_ops for a <button> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "No es poden tenir dos draw_ops per a un element <button> (el tema ha " +#~ "especificat un atribut draw_ops i també un element <draw_ops>, o ha " +#~ "especificat ambdós elements)" -#~ msgid "No \"resize\" attribute on <%s> element" -#~ msgstr "No hi ha cap atribut «resize» en l'element <%s>" +#~ msgid "" +#~ "Can't have a two draw_ops for a <menu_icon> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "No es poden tenir dos draw_ops per a un element <menu_icon> (el tema ha " +#~ "especificat un atribut draw_ops i també un element <draw_ops>, o ha " +#~ "especificat ambdós elements)" -#~ msgid "Type of %s was not integer" -#~ msgstr "%s no era de tipus enter" +#~ msgid "Bad version specification '%s'" +#~ msgstr "Especificació de versió errònia («%s»)" #~ msgid "" -#~ "%d stored in GConf key %s is not a reasonable cursor_size; must be in the " -#~ "range 1..128\n" +#~ "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" +#~ "theme-2.xml" #~ msgstr "" -#~ "%d, emmagatzemat a la clau GConf %s, no és una mida de cursor raonable, " -#~ "ha d'estar dins del rang 1..128\n" +#~ "L'atribut «version» no es pot utilitzat als fitxers metacity-theme-1.xml " +#~ "o metacity-theme-2.xml" #~ msgid "" -#~ "%d stored in GConf key %s is not a reasonable number of workspaces, " -#~ "current maximum is %d\n" +#~ "Theme requires version %s but latest supported theme version is %d.%d" #~ msgstr "" -#~ "%d, emmagatzemat a la clau GConf, %s no té un nombre raonable d'espais de " -#~ "treball. El màxim actual és %d\n" +#~ "El tema requereix la versió %s, però la darrera versió compatible del " +#~ "tema és la %d.%d" -#~ msgid "On _Top" -#~ msgstr "Per damun_t" +#~ msgid "Outermost element in theme must be <metacity_theme> not <%s>" +#~ msgstr "L'element més extern en el tema ha de ser <metacity_theme>, no <%s>" #~ msgid "" -#~ "Forcing this application to quit will cause you to lose any unsaved " -#~ "changes." +#~ "Element <%s> is not allowed inside a name/author/date/description element" #~ msgstr "" -#~ "Si forceu la sortida d'aquesta aplicació, se'n perdran els canvis que " -#~ "hagueu desat." +#~ "L'element <%s> no és permès dins d'un element name/author/date/description" -#~ msgid "Unknown function \"%s\" for menu icon" -#~ msgstr "Funció «%s» desconeguda per a la icona de menú" +#~ msgid "Element <%s> is not allowed inside a <constant> element" +#~ msgstr "L'element <%s> no és permès dins d'un element <constant>" -#~ msgid "Unknown state \"%s\" for menu icon" -#~ msgstr "Estat «%s» desconegut per a la icona de menú" +#~ msgid "" +#~ "Element <%s> is not allowed inside a distance/border/aspect_ratio element" +#~ msgstr "" +#~ "L'element <%s> no és permès dins d'un element distance/border/aspect_ratio" -#~ msgid "Theme already has a menu icon for function %s state %s" -#~ msgstr "El tema ja té una icona de menú per a l'estat %s de la funció %s" +#~ msgid "Element <%s> is not allowed inside a draw operation element" +#~ msgstr "L'element <%s> no és permès dins d'un element d'operació igual" -#~ msgid "No draw_ops provided for menu icon" -#~ msgstr "No s'ha proveït cap draw_ops per a la icona de menú" +#~ msgid "Element <%s> is not allowed inside a <%s> element" +#~ msgstr "L'element <%s> no és permès dins d'un element <%s>" -#~ msgid "Failed to read theme from file %s: %s\n" -#~ msgstr "S'ha produït un error en llegir el tema del fitxer %s: %s\n" +#~ msgid "No draw_ops provided for frame piece" +#~ msgstr "No s'ha proveït cap draw_ops per a la peça del marc" -#~ msgid "" -#~ "<menu_icon function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -#~ "specified for this theme" -#~ msgstr "" -#~ "<menu_icon function=\"%s\" state=\"%s\" draw_ops=\"qualsevol\"/> s'ha " -#~ "d'especificar per a aquest tema" +#~ msgid "No draw_ops provided for button" +#~ msgstr "No s'ha proveït cap draw_ops per al botó" -#~ msgid "" -#~ "If true, and the focus mode is either \"sloppy\" or \"mouse\" then the " -#~ "focused window will be automatically raised after a delay (the delay is " -#~ "specified by the auto_raise_delay key). This preference is poorly named, " -#~ "but kept for backwards compatibility. To try to be more clear (at least " -#~ "to the technically inclined), its meaning is \"automatically raise the " -#~ "window following a timeout which is triggered by non-grabbed mouse entry " -#~ "in sloppy or mouse focus modes\". It is unrelated to clicking behavior (i." -#~ "e. this is not related to raise-on-click/orthogonal-raise). It is " -#~ "unrelated to entering a window during drag and drop (because that results " -#~ "in the application grabbing the mouse)" -#~ msgstr "" -#~ "Si és cert, i el mode del focus és «sloppy» o «mouse», aleshores la " -#~ "finestra enfocada s'alçarà automàticament al cap d'una estona (el temps " -#~ "s'especifica a la clau auto_raise_delay). Aquesta preferència no està " -#~ "gaire ben batejada, però es manté per compatibilitat amb versions " -#~ "anteriors. Per ser més clars (per als més tècnics), significa «alça la " -#~ "finestra automàticament després d'un temps d'espera, que s'activa per una " -#~ "entrada no capturada del ratolí quan aquest està en el mode de focus " -#~ "\"sloppy\" o bé \"mouse\"». No té cap relació amb el comportament del " -#~ "clic (no té relació amb l'alçament amb un clic/alçament ortogonal). No " -#~ "està relacionat amb entrar a una finestra durant una opració d'arrossegar " -#~ "i deixar anar (perquè resulta en que l'aplicació captura el ratolí)" +#~ msgid "No text is allowed inside element <%s>" +#~ msgstr "No es permet cap text dins de l'element <%s>" -#~ msgid "" -#~ "Some applications break specifications in ways that result in window " -#~ "manager misfeatures. For example, ideally Metacity would place all " -#~ "dialogs in a consistent position with respect to their parent window. " -#~ "This requires ignoring application-specified positions for dialogs. But " -#~ "some versions of Java/Swing mark their popup menus as dialogs, so " -#~ "Metacity has to disable dialog positioning to allow menus to work in " -#~ "broken Java applications. There are several other examples like this. " -#~ "This option puts Metacity in full-on Correct mode, which perhaps gives a " -#~ "moderately nicer UI if you don't need to run any broken apps. Sadly, " -#~ "workarounds must be enabled by default; the real world is an ugly place. " -#~ "Some of the workarounds are workarounds for limitations in the " -#~ "specifications themselves, so sometimes a bug in no-workarounds mode " -#~ "won't be fixable without amending a spec." -#~ msgstr "" -#~ "Algunes aplicacions trenquen les especificacions de maneres que resulten " -#~ "en disfuncionalitats dels gestors de finestres. Per exemple, idealment el " -#~ "Metacity ficarà tots els diàlegs en una posició consistent respecte de " -#~ "les seves finestres pare. Això requereix ignorar les posicions que " -#~ "especifiquen les aplicacions per als diàlegs. Tanmateix, algunes versions " -#~ "del Java/Swing marquen els seus menús emergents com a diàlegs, i Metacity " -#~ "ha de inhabilitar el posicionament de diàlegs per a què els menús " -#~ "funcionin en les aplicacions Java amb aquests errors. Hi ha més exemples " -#~ "com aquest. Aquesta opció estableix Metacity en el mode «completament " -#~ "correcte», que potser donarà una millor interfície d'usuari si no " -#~ "necessiteu executar cap aplicació amb errors. Malauradament, aquesta " -#~ "funcionalitat s'ha d'habilitar per defecte. Algunes de les funcionalitats " -#~ "estan dirigides a limitacions en les mateixes especificacions, pel que a " -#~ "vegades un error en el mode sense correccions no es pot solucionar sense " -#~ "canviar l'especificació." +#~ msgid "<%s> specified twice for this theme" +#~ msgstr "S'ha especificat <%s> dues vegades per a aquest tema" -#~ msgid "" -#~ "Coordinate expression parser overflowed its buffer, this is really a " -#~ "Metacity bug, but are you sure you need a huge expression like that?" -#~ msgstr "" -#~ "L'anàlisi de l'expressió coordinada ha sobreeixit la seva memòria " -#~ "intermèdia. Aquest és un error del Metacity, però esteu segur que " -#~ "necessiteu una expressió tan rotunda com aquesta?" +#~ msgid "Failed to find a valid file for theme %s\n" +#~ msgstr "No s'ha trobat un fitxer vàlid per al tema %s\n" diff --git a/po/cs.po b/po/cs.po index e3c23a76f..b98775b44 100644 --- a/po/cs.po +++ b/po/cs.po @@ -1,446 +1,292 @@ -# Czech translation of muffin. -# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 the author(s) of muffin. +# Czech translation of mutter. +# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 the author(s) of mutter. # Copyright (C) 2003, 2004, 2005, 2006 Miloslav Trmac <mitr@volny.cz>. -# This file is distributed under the same license as the muffin package. +# This file is distributed under the same license as the mutter package. # Miloslav Trmac <mitr@volny.cz>, 2002, 2003, 2004, 2005, 2006. # Petr Tomeš <ptomes@gmail.com>, 2006. # Jakub Friedl <jfriedl@suse.cz>, 2006, 2007. -# Petr Kovar <pknbe@volny.cz>, 2007, 2008, 2009, 2010, 2011, 2012. -# Marek Černocký <marek@manet.cz>, 2012. +# Petr Kovar <pknbe@volny.cz>, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014. +# Marek Černocký <marek@manet.cz>, 2012, 2013, 2014, 2016, 2017, 2018, 2019, 2020. +# msgid "" msgstr "" -"Project-Id-Version: muffin\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-03-26 02:24+0200\n" -"PO-Revision-Date: 2012-03-26 02:24+0200\n" -"Last-Translator: Petr Kovar <pknbe@volny.cz>\n" -"Language-Team: Czech <gnome-cs-list@gnome.org>\n" +"Project-Id-Version: mutter\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2020-02-23 17:41+0000\n" +"PO-Revision-Date: 2020-02-26 14:10+0100\n" +"Last-Translator: Marek Černocký <marek@manet.cz>\n" +"Language-Team: čeština <gnome-cs-list@gnome.org>\n" "Language: cs\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -"X-Generator: Virtaal 0.7.1\n" +"X-Generator: Gtranslator 2.91.7\n" +"X-Project-Style: gnome\n" -#: ../src/50-muffin-windows.xml.in.h:1 -msgid "View split on left" -msgstr "Zobrazit rozdělení nalevo" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Navigace" -#: ../src/50-muffin-windows.xml.in.h:2 -msgid "View split on right" -msgstr "Zobrazit rozdělení napravo" +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Přesunout okno na pracovní plochu 1" -#: ../src/50-muffin-windows.xml.in.h:3 -msgid "Windows" -msgstr "Okna" +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Přesunout okno na pracovní plochu 2" -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format -msgid "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." -msgstr "Jiný kompozitní správce již běží na obrazovce %i displeje „%s“." +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Přesunout okno na pracovní plochu 3" -#: ../src/core/bell.c:307 -msgid "Bell event" -msgstr "Událost zvonku" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Přesunout okno na pracovní plochu 4" -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Neznámý informační požadavek okna: %d" +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Přesunout okno na poslední pracovní plochu" -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> neodpovídá." +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "Přesunout okno o jednu pracovní plochu nahoru" -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "Aplikace neodpovídá." +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "Přesunout okno o jednu pracovní plochu dolů" -#: ../src/core/delete.c:119 -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "" -"Je možné chvíli počkat, aby aplikace mohla pokračovat, nebo si vynutit úplné " -"ukončení aplikace." +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "Přesunout okno o jeden monitor doleva" -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "_Počkat" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "Přesunout okno o jeden monitor doprava" -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "_Vynutit ukončení" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "Přesunout okno o jeden monitor nahoru" -#: ../src/core/display.c:387 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "Schází rozšíření %s vyžadované funkcemi kompozitoru" - -#: ../src/core/display.c:453 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Nelze otevřít displej X Window System „%s“\n" - -#: ../src/core/keybindings.c:852 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "" -"Klávesu %s s modifikátory %x již jako zkratku používá nějaký jiný program\n" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "Přesunout okno o jeden monitor dolů" -#: ../src/core/main.c:206 -msgid "Disable connection to session manager" -msgstr "Zakáže připojení ke správci sezení" +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "Přepnout do jiné aplikace" -#: ../src/core/main.c:212 -msgid "Replace the running window manager" -msgstr "Nahradí běžícího správce oken" +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "Přepnout do předchozí aplikaci" -#: ../src/core/main.c:218 -msgid "Specify session management ID" -msgstr "Určení ID správy sezení" +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "Přepnout do jiného okna" -#: ../src/core/main.c:223 -msgid "X Display to use" -msgstr "Displej X, který použije" +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "Přepnout do minulého okna" -#: ../src/core/main.c:229 -msgid "Initialize session from savefile" -msgstr "Spustí sezení z uloženého souboru" +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "Přepnout do jiného okna aplikace" -#: ../src/core/main.c:235 -msgid "Make X calls synchronous" -msgstr "Provede volání X synchronně" +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "Přepnout do předchozího okna aplikace" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Nelze prohledat adresář motivů: %s\n" +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "Přepnout na systémový ovládací prvek" -#: ../src/core/main.c:520 -#, c-format -msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "" -"Nelze najít motiv! Ujistěte se prosím, že existuje %s a obsahuje obvyklé " -"motivy.\n" +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "Přepnout na minulý systémový ovládací prvek" -#: ../src/core/muffin.c:40 -#, c-format -msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" -"muffin %s\n" -"Copyright © 2001 – %d Havoc Pennington, Red Hat, Inc. a další.\n" -"Toto je svobodný software; podmínky kopírování a rozšiřování naleznete ve " -"zdrojových textech.\n" -"Tento software je BEZ JAKÉKOLIV ZÁRUKY; neposkytují se ani záruky " -"PRODEJNOSTI anebo VHODNOSTI PRO URČITÝ ÚČEL.\n" +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "Přepnout přímo do okna" -#: ../src/core/muffin.c:54 -msgid "Print version" -msgstr "Vypíše verzi" +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "Přepnout přímo do předchozího okna" -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "Čárkou oddělený seznam zásuvných modulů kompozitoru" +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "Přepnout přímo do jiného okna aplikace" -#: ../src/core/prefs.c:1077 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"Bylo zakázáno obcházení chyb aplikací. Některé aplikace se možná nebudou " -"chovat správně.\n" +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "Přepnout přímo do předchozího okna aplikace" -#: ../src/core/prefs.c:1152 -#, c-format -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "Nelze zpracovat popis písma „%s“ v klíči GSettings %s\n" +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "Přepnout přímo na systémový ovládací prvek" -#: ../src/core/prefs.c:1218 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"„%s“ nalezené v databázi nastavení není platnou hodnotou modifikátoru " -"tlačítka myši\n" +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "Přepnout přímo na předchozí systémový ovládací prvek" -#: ../src/core/prefs.c:1739 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "" -"„%s“ nalezené v databázi nastavení není platnou hodnotou klávesové zkratky " -"„%s“\n" +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "Skrýt všechna běžná okna" -#: ../src/core/prefs.c:1836 -#, c-format -msgid "Workspace %d" -msgstr "Plocha %d" +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "Přepnout na plochu 1" -#: ../src/core/screen.c:730 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "Obrazovka %d na displeji „%s“ je neplatná\n" +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "Přepnout na plochu 2" -#: ../src/core/screen.c:746 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"Obrazovka %d na displeji „%s“ již správce oken má; zkuste prosím nahradit " -"aktuálního správce oken pomocí přepínače --replace.\n" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "Přepnout na plochu 3" -#: ../src/core/screen.c:773 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "Nelze získat výběr správce oken na obrazovce %d displeje „%s“\n" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "Přepnout na plochu 4" -#: ../src/core/screen.c:828 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "Obrazovka %d na displeji „%s“ již má správce oken\n" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "Přepnout na poslední plochu" -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "Nelze uvolnit obrazovku %d na displeji „%s“\n" +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "Přesunout na plochu nad" -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Nelze vytvořit adresář „%s“: %s\n" +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "Přesunout na plochu pod" -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "Nelze otevřít soubor sezení „%s“ k zápisu: %s\n" +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "Systém" -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Chyba při zápisu souboru sezení „%s“: %s\n" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Zobrazit řádek ke spuštění příkazu" -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Chyba při zavírání souboru sezení „%s“: %s\n" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Zobrazit přehled činností" -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Chyba při analyzování uloženého souboru sezení: %s\n" +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Obnovit klávesové zkratky" -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "nalezen atribut <muffin_session>, ale ID sezení už k dispozici je" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Okna" -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Neznámý atribut %s prvku <%s>" +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "Aktivovat nabídku okna" -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "vnořená značka <window>" +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Přepnout režim celé obrazovky" -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "Neznámý prvek %s" +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "Přepnout stav maximalizace" -#: ../src/core/session.c:1809 -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" -"Tato okna nepodporují "ukládání aktuálního nastavení" a po vašem " -"příštím přihlášení je budete muset spustit ručně." +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "Maximalizovat okno" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Nelze otevřít ladicí záznam: %s\n" +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Obnovit velikost okna" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Nelze provést fdopen() soubor záznamu %s: %s\n" +#: data/50-mutter-windows.xml:18 +msgid "Close window" +msgstr "Zavřít okno" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "Otevřen soubor záznamu %s\n" +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "Skrýt okno" -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "Muffin bylo přeloženo bez podpory podrobného režimu\n" +#: data/50-mutter-windows.xml:22 +msgid "Move window" +msgstr "Přesunout okno" -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "Správce oken: " +#: data/50-mutter-windows.xml:24 +msgid "Resize window" +msgstr "Změnit velikost okna" -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "Chyba ve správci oken: " +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "Přepnout okno na všechny/jednu pracovní plochu" -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "Varování správce oken: " +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "Zakryté okno vynést do popředí, jinak odsunout do pozadí" -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "Chyba správce oken: " +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "Vynést okno do popředí nad ostatní okna" -#. first time through -#: ../src/core/window.c:7266 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"Okno %s nastavilo SM_CLIENT_ID samo na sebe, namísto okna WM_CLIENT_LEADER, " -"jak je definováno v ICCCM.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7931 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size " -"%d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"Okno %s nastavuje pokyn MWM, kterým naznačuje, že se nedá měnit jeho " -"velikost, ale nastavuje min. velikost %d × %d a max. velikost %d × %d; to " -"nedává smysl.\n" +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "Odsunout okno do pozadí za ostatní okna" -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "Aplikace nastavila neplatný _NET_WM_PID %lu\n" +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "Maximalizovat okno svisle" -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (na %s)" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "Maximalizovat okno vodorovně" -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "Neplatné okno WM_TRANSIENT_FOR 0x%lx specifikováno pro %s.\n" +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "Rozdělit okno přes levou půlku obrazovky" -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "Okno WM_TRANSIENT_FOR 0x%lx by vytvořilo smyčku pro %s.\n" +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "Rozdělit okno přes pravou půlku obrazovky" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"Okno 0x%lx má vlastnost %s\n" -"Ta má mít typ %s formátu %d\n" -"a ve skutečnosti má typ %s formátu %d n_items %d.\n" -"To je pravděpodobně chyba aplikace, nikoliv správce oken.\n" -"Okno má nadpis=„%s“, třída=„%s“, název=„%s“.\n" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "Vlastnost %s okna 0x%lx obsahovala neplatné UTF-8\n" +#: data/org.gnome.mutter.gschema.xml.in:7 +msgid "Modifier to use for extended window management operations" +msgstr "Modifikátor, který se má použít u operací rozšířené správy oken" -#: ../src/core/xprops.c:494 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:8 msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." msgstr "" -"Vlastnost %s okna 0x%lx obsahovala neplatné UTF-8 u položky %d seznamu\n" - -#: ../src/muffin.desktop.in.h:1 ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" +"Tato klávesa spustí „překrytí“ („overlay“), což je kombinace přehledu oken a " +"systému spouštění aplikací. Výchozí u osobních počítačů je „klávesa " +"Windows“. Předpokládá se, že tato zkratka bude výchozí, nebo nastavena na " +"prázdný řetězec." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 +#: data/org.gnome.mutter.gschema.xml.in:20 msgid "Attach modal dialogs" msgstr "Připojit modální dialogová okna" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 -msgid "Cancel tab popup" -msgstr "Zrušit překryvné okno tabulátoru" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"Určuje, zda by měla skrytá okna (tj. minimalizovaná okna a okna na jiných " -"pracovních plochách než na aktuální) zůstat aktivní." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 -msgid "" -"Determines whether the use of popup and highlight frame should be disabled " -"for window cycling." -msgstr "" -"Určuje, zda by se mělo používání překryvné nabídky se zvýrazněním vypnout " -"při procházení okny." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -msgid "" -"Determines whether workspace switching should happen for windows on all " -"monitors or only for windows on the primary monitor." -msgstr "" -"Určuje, zda by se měly pracovní plochy přepínat u všech oken na všech " -"monitorech, nebo pouze u oken na primárním monitoru." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 +#: data/org.gnome.mutter.gschema.xml.in:21 msgid "" -"Determines whether workspaces are managed dynamically or whether there's a " -"static number of workspaces (determined by the num-workspaces key in org." -"gnome.desktop.wm.preferences)." +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." msgstr "" -"Určuje, zda jsou pracovní plochy spravovány dynamicky nebo jich je pevný " -"počet (daný klíčem num-workspaces v org.cinnamon.desktop.wm.preferences)." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 -msgid "Draggable border width" -msgstr "Šířka přetažitelného okraje" +"Je-li zapnuto, pak se namísto samostatných záhlaví oken modální dialogy " +"zobrazují jako připojené k záhlaví okna rodiče a jsou přesunovány společně s " +"oknem rodiče." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 +#: data/org.gnome.mutter.gschema.xml.in:30 msgid "Enable edge tiling when dropping windows on screen edges" msgstr "Zapnout dlaždice na okrajích při upuštění oken na okrajích obrazovky" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 +#: data/org.gnome.mutter.gschema.xml.in:31 msgid "" "If enabled, dropping windows on vertical screen edges maximizes them " "vertically and resizes them horizontally to cover half of the available " @@ -451,1120 +297,477 @@ msgstr "" "dostupného prostoru. Upuštění oken na horním okraji obrazovky je " "maximalizuje úplně." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 -msgid "Live Hidden Windows" -msgstr "Aktivní skrytá okna" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 -msgid "Modifier to use for extended window management operations" -msgstr "Modifikátor, který se má použít u operací rozšířené správy oken" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 -msgid "No tab popup" -msgstr "Bez překryvné nabídky tabulátoru" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 -msgid "Select window from tab popup" -msgstr "Vybrat okno z překryvné nabídky tabulátoru" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 -msgid "" -"The amount of total draggable borders. If the theme's visible borders are " -"not enough, invisible borders will be added to meet this value." -msgstr "" -"Počet všech přetažitelných okrajů. Nestačí-li viditelné okraje motivu, budou " -"přidány neviditelné okraje, aby bylo docíleno zadané hodnoty." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 -msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." -msgstr "" -"Tato klávesa spustí „překrytí“ („overlay“), což je kombinace přehledu oken a " -"systému spouštění aplikací. Výchozí u osobních počítačů je „klávesa " -"Windows“. Předpokládá se, že tato zkratka bude výchozí, nebo nastavena na " -"prázdný řetězec." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 -msgid "" -"When true, instead of having independent titlebars, modal dialogs appear " -"attached to the titlebar of the parent window and are moved together with " -"the parent window." -msgstr "" -"Je-li zapnuto, pak se namísto samostatných záhlaví oken modální dialogy " -"zobrazují jako připojené k záhlaví okna rodiče a jsou přesunovány společně s " -"oknem rodiče." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:17 +#: data/org.gnome.mutter.gschema.xml.in:40 msgid "Workspaces are managed dynamically" msgstr "Pracovní plochy jsou spravovány dynamicky" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:18 -msgid "Workspaces only on primary" -msgstr "Pracovní plochy pouze na primárním" - -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "Použití: %s\n" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "Mi_nimalizovat" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "Ma_ximalizovat" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "Zrušit ma_ximalizaci" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "Sv_inout" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "Rozv_inout" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "_Přesunout" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "Z_měnit velikost" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "Přesunout záhlaví okna na _obrazovku" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "_Vždy navrchu" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "Vžd_y na viditelné ploše" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "_Jen na této ploše" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "Přesunout na plochu v_levo" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "Přesunout na plochu vp_ravo" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "Přesunout na plochu na_hoře" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "Přesunout na plochu _dole" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "_Zavřít" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "Plocha %d%n" - -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "Plocha 1_0" - -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "Plocha %s%d" - -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "Přes_unout na jinou plochu" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" - -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d × %d" - -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "nahoře" - -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "dole" - -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "vlevo" - -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "vpravo" - -#: ../src/ui/theme.c:286 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "geometrie rámu nedefinuje rozměr „%s“" - -#: ../src/ui/theme.c:305 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "geometrie rámu nedefinuje rozměr „%s“ okraje „%s“" - -#: ../src/ui/theme.c:342 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "Poměr stran tlačítka %g není přiměřený" - -#: ../src/ui/theme.c:354 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "Geometrie rámu nedefinuje velikost tlačítek" - -#: ../src/ui/theme.c:1067 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "Přechody by měly mít alespoň dvě barvy" - -#: ../src/ui/theme.c:1219 -#, c-format -msgid "" -"GTK custom color specification must have color name and fallback in " -"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" -msgstr "" -"Určení vlastní barvy GTK musí mít název barvy a záložní možnost v závorce, " -"např. gtk:custom(x,y); nelze analyzovat „%s“" - -#: ../src/ui/theme.c:1235 -#, c-format -msgid "" -"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" -"_ are valid" -msgstr "" -"Neplatný znak „%c“ v parametru color_name v gtk:custom, platné jsou pouze A-" -"Za-z0-9-_" - -#: ../src/ui/theme.c:1249 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:41 msgid "" -"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " -"fit the format" +"Determines whether workspaces are managed dynamically or whether there’s a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." msgstr "" -"Formát Gtk:custom má podobu „gtk:custom(název_barvy,záloha)“, „%s“ tomuto " -"formátu neodpovídá" +"Určuje, zda jsou pracovní plochy spravovány dynamicky nebo jich je pevný " +"počet (daný klíčem num-workspaces v org.gnome.desktop.wm.preferences)." -#: ../src/ui/theme.c:1294 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"Specifikace GTK barvy musí mít stav v hranatých závorkách, např. gtk:fg" -"[NORMAL], kde NORMAL je stav; nelze analyzovat „%s“" +#: data/org.gnome.mutter.gschema.xml.in:50 +msgid "Workspaces only on primary" +msgstr "Pracovní plochy pouze na primárním" -#: ../src/ui/theme.c:1308 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:51 msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." msgstr "" -"Specifikace GTK barvy musí mít za stavem hranatou závorku, např. gtk:fg" -"[NORMAL], kde NORMAL je stav; nelze analyzovat „%s“" - -#: ../src/ui/theme.c:1319 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "Nerozumí se stavu „%s“ ve specifikaci barvy" +"Určuje, zda by se měly pracovní plochy přepínat u všech oken na všech " +"monitorech, nebo pouze u oken na primárním monitoru." -#: ../src/ui/theme.c:1332 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "Nerozumí se barevné složce „%s“ ve specifikaci barvy" +#: data/org.gnome.mutter.gschema.xml.in:59 +msgid "No tab popup" +msgstr "Bez překryvné nabídky tabulátoru" -#: ../src/ui/theme.c:1361 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:60 msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." msgstr "" -"Formát prolínání má podobu „prolínání/barva_pozadí/barva_popředí/alfa“, „%s“ " -"tomuto formátu neodpovídá" - -#: ../src/ui/theme.c:1372 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "Nelze analyzovat hodnotu alfa „%s“ v prolínající barvě" +"Určuje, zda by se mělo používání překryvné nabídky se zvýrazněním vypnout " +"při procházení okny." -#: ../src/ui/theme.c:1382 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "Hodnota alfa „%s“ v prolínající barvě není mezi 0.0 a 1.0" +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Se změnou zaměření čekat na zastavení pohybu ukazatele" -#: ../src/ui/theme.c:1429 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:69 msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." msgstr "" -"Formát stínu má podobu „stín/základní_barva/faktor“, „%s“ tomuto formátu " -"neodpovídá" - -#: ../src/ui/theme.c:1440 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "Nelze analyzovat faktor stínu „%s“ ve stínované barvě" - -#: ../src/ui/theme.c:1450 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "Faktor stínu „%s“ ve stínované barvě je záporný" +"Je-li zapnuto a režim zaměření je buď „sloppy“ nebo „mouse“, pak se zaměření " +"nezmění hned, když vstoupíte do kona, ale až se přestane pohybovat ukazatel." -#: ../src/ui/theme.c:1479 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Nelze analyzovat barvu „%s“" - -#: ../src/ui/theme.c:1790 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "Souřadnicový výraz obsahuje nepovolený znak „%s“" +#: data/org.gnome.mutter.gschema.xml.in:79 +msgid "Draggable border width" +msgstr "Šířka přetažitelného okraje" -#: ../src/ui/theme.c:1817 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:80 msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" +"The amount of total draggable borders. If the theme’s visible borders are " +"not enough, invisible borders will be added to meet this value." msgstr "" -"Souřadnicový výraz obsahuje číslo s pohyblivou řádovou čárkou „%s“, které " -"nelze analyzovat" - -#: ../src/ui/theme.c:1831 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "Souřadnicový výraz obsahuje celé číslo „%s“, které nelze analyzovat" - -#: ../src/ui/theme.c:1953 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "Souřadnicový výraz obsahuje na začátku textu neznámý operátor: „%s“" - -#: ../src/ui/theme.c:2010 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "Souřadnicový výraz byl prázdný nebo mu nebylo rozuměno" - -#: ../src/ui/theme.c:2121 ../src/ui/theme.c:2131 ../src/ui/theme.c:2165 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "Souřadnicový výraz způsobil dělení nulou" +"Počet všech přetažitelných okrajů. Nestačí-li viditelné okraje motivu, budou " +"přidány neviditelné okraje, aby bylo docíleno zadané hodnoty." -#: ../src/ui/theme.c:2173 -#, c-format -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "" -"Souřadnicový výraz chce použít operátor mod na číslo s pohyblivou řádovou " -"čárkou" +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "Automaticky maximalizovat okna téměř o velikosti monitoru" -#: ../src/ui/theme.c:2229 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:90 msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." msgstr "" -"Souřadnicový výraz má na místě, kde byl očekáván operand, operátor „%s“" - -#: ../src/ui/theme.c:2238 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "Souřadnicový výraz má operand tam, kde byl očekáván operátor" +"Je-li povoleno, budou automaticky maximalizována okna, která mají počáteční " +"velikost shodnou s velikostí monitoru." -#: ../src/ui/theme.c:2246 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "Souřadnicový výraz končí operátorem místo operandu" +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Umístit nová okna do středu" -#: ../src/ui/theme.c:2256 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:99 msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." msgstr "" -"Souřadnicový výraz má operátor „%c“ za operátorem „%c“ bez operandu " -"umístěného mezi nimi" - -#: ../src/ui/theme.c:2407 ../src/ui/theme.c:2452 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "Souřadnicový výraz má neznámou proměnnou nebo konstantu „%s“" +"Je-li zapnuto, nová okna budou vždy umístěna ve středu aktivní obrazovky " +"monitoru." -#: ../src/ui/theme.c:2506 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "Analyzátor souřadnicových výrazů přeplnil svou vyrovnávací paměť." - -#: ../src/ui/theme.c:2535 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "Souřadnicový výraz má pravou závorku bez levé závorky" +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Povolit experimentální funkce" -#: ../src/ui/theme.c:2599 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "Souřadnicový výraz má levou závorku bez pravé závorky" - -#: ../src/ui/theme.c:2610 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "Souřadnicový výraz zřejmě nemá žádné operátory nebo operandy" - -#: ../src/ui/theme.c:2822 ../src/ui/theme.c:2842 ../src/ui/theme.c:2862 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "Motiv obsahoval výraz, který způsobil chybu: %s\n" - -#: ../src/ui/theme.c:4533 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:108 msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes " +"mutter request a low priority real-time scheduling. The executable or user " +"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — " +"initializes Xwayland lazily if there are X11 clients. Requires restart." msgstr "" -"U tohoto stylu rámu musí být zadáno <button function=\"%s\" state=\"%s\" " -"draw_ops=\"cokoliv\"/>" +"Chcete-li povolit experimentální funkce, přidejte klíčové slovo funkce do " +"seznamu. Zda funkce vyžaduje restartování kompozitoru, závisí na dané " +"funkci. Ne u každé experimentální funkce je vyžadováno, aby byla stále " +"dostupná nebo konfigurovatelná. Neočekávejte, že by bylo v tomto nastavení " +"přidáno něco, co by do budoucna přineslo vylepšení. V současné době jsou " +"možná tato klíčová slova: • „scale-monitor-framebuffer“ – zajistí, aby byl " +"mutter výchozí pro logické uspořádání monitorů v logickém souřadnicovém " +"prostoru pixelů, zatímco škáluje přímo v grafické vyrovnávací paměti, " +"namísto v obsahu oken, aby se postaral o správu montorů s HiDPI. Nevyžaduje " +"restart. • „rt-scheduler“ – zajistí, aby měly požadavky mutter nízkou " +"prioritu v plánování reálného času. Spustitelný soubor nebo uživatel musí " +"mít CAP_SYS_NICE. Vyžaduje restart. • „autostart-xwayland“ – inicializuje " +"Xwayland líněji v situaci, kdy existují klienti X11. Vyžaduje restart." -#: ../src/ui/theme.c:5066 ../src/ui/theme.c:5091 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" -"Chybí <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"cokoliv\"/>" +#: data/org.gnome.mutter.gschema.xml.in:134 +msgid "Modifier to use to locate the pointer" +msgstr "Modifikátor ke zjištění pozice ukazatele" -#: ../src/ui/theme.c:5139 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Nelze načíst motiv „%s“: %s\n" +#: data/org.gnome.mutter.gschema.xml.in:135 +msgid "This key will initiate the “locate pointer” action." +msgstr "Tato klávesa spustí činnost „zjisti polohu ukazatele“." -#: ../src/ui/theme.c:5275 ../src/ui/theme.c:5282 ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 ../src/ui/theme.c:5303 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "Není nastaveno <%s> motivu „%s“" +#: data/org.gnome.mutter.gschema.xml.in:142 +msgid "Timeout for check-alive ping" +msgstr "Časový limit pro pingání check-alive" -#: ../src/ui/theme.c:5311 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:143 msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" +"Number of milliseconds a client has to respond to a ping request in order to " +"not be detected as frozen. Using 0 will disable the alive check completely." msgstr "" -"U typu okna „%s“ motivu „%s“ není nastaven typ rámu, přidejte prosím prvek " -"<window type=\"%s\" style_set=\"cokoliv\"/>" +"Počet milisekund, které má klient na odpověď na na kontrolní pingnutí " +"sloužící k detekci, jestli nazatuhl. Nastavením na 0 se kontrola zcela vypne." -#: ../src/ui/theme.c:5709 ../src/ui/theme.c:5771 ../src/ui/theme.c:5834 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" -"Uživatelem definované konstanty musí začínat velkým písmenem; „%s“ toto " -"nesplňuje" +#: data/org.gnome.mutter.gschema.xml.in:165 +msgid "Select window from tab popup" +msgstr "Vybrat okno z překryvné nabídky tabulátoru" -#: ../src/ui/theme.c:5717 ../src/ui/theme.c:5779 ../src/ui/theme.c:5842 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "Konstanta „%s“ již byla definována" +#: data/org.gnome.mutter.gschema.xml.in:170 +msgid "Cancel tab popup" +msgstr "Zrušit překryvné okno tabulátoru" -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. +#: data/org.gnome.mutter.gschema.xml.in:175 +msgid "Switch monitor configurations" +msgstr "Přepnout nastavení monitoru" + +#: data/org.gnome.mutter.gschema.xml.in:180 +msgid "Rotates the built-in monitor configuration" +msgstr "Postupně mění vestavěná nastavení monitoru" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Přepnout na VT 1" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Přepnout na VT 2" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Přepnout na VT 3" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Přepnout na VT 4" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Přepnout na VT 5" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Přepnout na VT 6" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Přepnout na VT 7" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Přepnout na VT 8" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Přepnout na VT 9" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Přepnout na VT 10" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Přepnout na VT 11" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Přepnout na VT 12" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "Znovu povolit klávesové zkratky" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow X11 grabs to lock keyboard focus with Xwayland" +msgstr "" +"Povolit X11 zachytávání, aby mohl zabrat zaměření klávesnice pomocí Xwaylandu" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 +msgid "" +"Allow all keyboard events to be routed to X11 “override redirect” windows " +"with a grab when running in Xwayland. This option is to support X11 clients " +"which map an “override redirect” window (which do not receive keyboard " +"focus) and issue a keyboard grab to force all keyboard events to that " +"window. This option is seldom used and has no effect on regular X11 windows " +"which can receive keyboard focus under normal circumstances. For a X11 grab " +"to be taken into account under Wayland, the client must also either send a " +"specific X11 ClientMessage to the root window or be among the applications " +"white-listed in key “xwayland-grab-access-rules”." +msgstr "" +"Umožňujs směrovat všechny události klávesnice do oken X11 typu „přebytí " +"přesměrování“ pomocí zachytávání při běhu Xwaylandu. Tato volba je určena " +"pro podporu klientů X11, kteří mapují okna „přebytí přesměrování“ (která " +"nepřijímají zaměření klávesnice) a vynucuje zachytávání klávesnice zasílat " +"všechny události klávesnice do těchto oken. Tato volba je využívána jen " +"zřídka a nemá žádný vliv na běžná okna X11, která mohou přijímat zaměření " +"klávesnice za normálních podmínek. Aby bylo pod Waylandem zachytávání bráno " +"v úvahu, musí klient navíc buď poslat specifickou zprávu X11 ClientMessage " +"do kořenového okna, nebo být mezi aplikacemi na bílé listině v klíči " +"„xwayland-grab-access-rules“." + +#: data/org.gnome.mutter.wayland.gschema.xml.in:84 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "" +"Aplikace pod Xwaylandem mají povoleno se starat o zachytávání klávesnice" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:85 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "" +"Seznam názvů prostředků nebo tříd prostředků oken X11, které buď mají nebo " +"nemají povolené se starat o zachytávání klávesnice X11 pod Xwaylandem. Název " +"nebo třída prostředku daného okna X11 se dá zjistit pomocí příkazu „xprop " +"WM_CLASS“. V názvech jsou podporované divoké znaky „*“ a „?“. Hodnoty " +"začínající „!“ jsou na černé listině, což má přednost před bílou listinou, " +"aby se daly aplikace odvolat z výchozího systémového seznamu. Do výchozího " +"systémového seznamu patří následující aplikace: " +"„@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@“. Uživatel může přerušit existující " +"zachytávání pomocí speciální klávesové zkratky definované klíčem „restore-" +"shortcuts“." + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. #. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "Chybí atribut „%s“ v prvku <%s>" - -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Řádek %d znak %d: %s" - -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "Atribut „%s“ opakován dvakrát v jednom prvku <%s>" - -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "Atribut „%s“ je v prvku <%s> v tomto kontextu neplatný" - -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "„%s“ nelze analyzovat jako celé číslo" - -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 +#: src/backends/meta-input-settings.c:2567 #, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "Nerozuměno koncovým znakům „%s“ v řetězci „%s“" +msgid "Mode Switch (Group %d)" +msgstr "Přepínač režimu (skupina %d)" -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "Celé číslo %ld musí být kladné" - -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "Celé číslo %ld je příliš velké, aktuální maximum je %d" - -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "Nelze analyzovat „%s“ jako číslo s pohyblivou řádovou čárkou" - -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "Pravdivostní hodnoty musí být „true“ nebo „false“, nikoliv „%s“" - -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "Úhel musí být mezi 0.0 a 360.0, měl hodnotu %g\n" - -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" -"Alfa musí být mezi 0.0 (neviditelný) a 1.0 (zcela neprůhledný), měla hodnotu " -"%g\n" +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2590 +msgid "Switch monitor" +msgstr "Přepnout monitor" -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"Neplatné měřítko nadpisu „%s“ (musí být jedno z xx-small, x-small, medium, " -"large, x-large, xx-large)\n" +#: src/backends/meta-input-settings.c:2592 +msgid "Show on-screen help" +msgstr "Zobrazit nápovědu na obrazovce" -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s>: název „%s“ použit podruhé" +#: src/backends/meta-monitor.c:223 +msgid "Built-in display" +msgstr "Vestavěný displej" -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "<%s>: rodič „%s“ nebyl definován" +#: src/backends/meta-monitor.c:252 +msgid "Unknown" +msgstr "Neznámý" -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "<%s>: geometrie „%s“ nebyla definována" +#: src/backends/meta-monitor.c:254 +msgid "Unknown Display" +msgstr "Neznámý displej" -#: ../src/ui/theme-parser.c:1154 +#: src/backends/meta-monitor.c:262 #, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "<%s> musí určit buď geometrii, nebo rodiče, který má geometrii" - -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "Aby měla hodnota alfa význam, je nutné určit pozadí" +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme-parser.c:1264 +#: src/backends/meta-monitor.c:270 #, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Neznámý typ „%s“ v prvku <%s>" +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "Neznámý style_set „%s“ v prvku <%s>" +#. Translators: this string will appear in Sysprof +#: src/backends/meta-profiler.c:79 +msgid "Compositor" +msgstr "Kompozitor" -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "Typu okna „%s“ již byla přiřazena sada stylů" - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:533 #, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "Prvek <%s> není povolen pod <%s>" - -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" -msgstr "" -"U tlačítek nelze zadat „button_width“/„button_height“ a zároveň " -"„aspect_ratio“" - -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "Vzdálenost „%s“ není známa" - -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "Poměr stran „%s“ není znám" - -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "Okraj „%s“ není znám" - -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "Chybí atribut „start_angle“ nebo „from“ v prvku <%s>" - -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "Chybí atribut „extent_angle“ nebo „to“ v prvku <%s>" - -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "Nerozumí se hodnotě „%s“ typu přechodu" - -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "Nerozumí se typu výplně „%s“ prvku <%s>" - -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "Nerozumí se stavu „%s“ prvku <%s>" - -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "Nerozumí se stínu „%s“ prvku <%s>" +"Another compositing manager is already running on screen %i on display “%s”." +msgstr "Jiný kompozitní správce již běží na obrazovce %i displeje „%s“." -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "Nerozumí se šipce „%s“ prvku <%s>" +#: src/core/bell.c:192 +msgid "Bell event" +msgstr "Událost zvonku" -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "Nebyly definovány žádné <draw_ops> nazvané „%s“" +#: src/core/main.c:190 +msgid "Disable connection to session manager" +msgstr "Zakázat připojení ke správci sezení" -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "Vložení draw_ops „%s“ na tomto místě by vytvořilo zacyklený odkaz" +#: src/core/main.c:196 +msgid "Replace the running window manager" +msgstr "Nahradí běžícího správce oken" -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Neznámá pozice položky rámu „%s“" +#: src/core/main.c:202 +msgid "Specify session management ID" +msgstr "Určit ID správy sezení" -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "Styl rámu již má položku na pozici %s" +#: src/core/main.c:207 +msgid "X Display to use" +msgstr "Displej X, který se má použít" -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "Nebyly definované žádné <draw_ops> s názvem „%s“" +#: src/core/main.c:213 +msgid "Initialize session from savefile" +msgstr "Spustit sezení z uloženého souboru" -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Neznámá funkce tlačítka „%s“" +#: src/core/main.c:219 +msgid "Make X calls synchronous" +msgstr "Provádět volání X synchronně" -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "Funkce tlačítka „%s“ v této verzi neexistuje (%d, potřeba je %d)" +#: src/core/main.c:226 +msgid "Run as a wayland compositor" +msgstr "Spustit jako kompozitor protokolu Wayland" -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Neznámý stav tlačítka „%s“" +#: src/core/main.c:232 +msgid "Run as a nested compositor" +msgstr "Spustit jako podkladový kompozitor" -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "Styl rámu již má tlačítko funkce %s stavu %s" +#: src/core/main.c:238 +msgid "Run wayland compositor without starting Xwayland" +msgstr "Spustit kompozitor wayland bez spuštění Xwayland" -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "„%s“ není platná hodnota atributu focus" +#: src/core/main.c:246 +msgid "Run as a full display server, rather than nested" +msgstr "Spustit jako plnohodnotný server displeje, nikoliv vnořeně" -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "„%s“ není platná hodnota atributu state" +#: src/core/main.c:252 +msgid "Run with X11 backend" +msgstr "Spustit se serverem X11" -#: ../src/ui/theme-parser.c:3092 +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:151 #, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "Nebyl definován styl „%s“" +msgid "“%s” is not responding." +msgstr "„%s“ nereaguje." -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "„%s“ není platná hodnota atributu resize" +#: src/core/meta-close-dialog-default.c:153 +msgid "Application is not responding." +msgstr "Aplikace nereaguje." -#: ../src/ui/theme-parser.c:3147 -#, c-format +#: src/core/meta-close-dialog-default.c:158 msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." msgstr "" -"Atribut „resize“ by neměl být na prvku <%s> maximalizovaného/svinutého stavu" +"Je možné chvíli počkat, aby aplikace mohla pokračovat, nebo si vynutit úplné " +"ukončení aplikace." -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "Atribut „resize“ by neměl být na prvku <%s> maximalizovaného stavu" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Force Quit" +msgstr "_Vynutit ukončení" -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "U state %s resize %s focus %s již byl definován styl" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Wait" +msgstr "_Počkat" -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 +#: src/core/mutter.c:38 #, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "U state %s focus %s již byl definován styl" - -#: ../src/ui/theme-parser.c:3294 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Nelze mít dvě draw_ops u prvku <piece> (motiv definoval atribut draw_ops i " -"prvek <draw_ops>, nebo definoval dva prvky)" - -#: ../src/ui/theme-parser.c:3332 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Nelze mít dvě draw_ops u prvku <button> (motiv definoval atribut draw_ops i " -"prvek <draw_ops>, nebo definoval dva prvky)" - -#: ../src/ui/theme-parser.c:3370 msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" msgstr "" -"Nelze mít dvě draw_ops u prvku <menu_icon> (motiv definoval atribut draw_ops " -"i prvek <draw_ops>, nebo definoval dva prvky)" - -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "Chybné zadání verze „%s“" +"mutter %s\n" +"Copyright © 2001 – %d Havoc Pennington, Red Hat, Inc. a další.\n" +"Toto je svobodný software; podmínky kopírování a rozšiřování naleznete ve " +"zdrojových textech.\n" +"Tento software je BEZ JAKÉKOLIV ZÁRUKY; neposkytují se ani záruky " +"PRODEJNOSTI anebo VHODNOSTI PRO URČITÝ ÚČEL.\n" -#: ../src/ui/theme-parser.c:3507 -msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" -msgstr "" -"Atribut „version“ nemůže být použit v metacity-theme-1.xml or metacity-" -"theme-2.xml" +#: src/core/mutter.c:52 +msgid "Print version" +msgstr "Vypsat verzi" -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "" -"Motiv vyžaduje verzi %s, ale poslední verze podporovaného motivu je %d.%d" +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "Zásuvný modul Mutter, který se má použít" -#: ../src/ui/theme-parser.c:3562 +#: src/core/prefs.c:1911 #, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "Vnější prvek motivu musí být <metacity_theme>, nikoliv <%s>" +msgid "Workspace %d" +msgstr "Plocha %d" -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "Prvek <%s> není dovolen v prvku name/author/date/description" +#: src/core/util.c:122 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter bylo přeloženo bez podpory podrobného režimu\n" -#: ../src/ui/theme-parser.c:3587 +#: src/wayland/meta-wayland-tablet-pad.c:568 #, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "Prvek <%s> není dovolen v prvku <constant>" +msgid "Mode Switch: Mode %d" +msgstr "Přepínač režimu: režim %d" -#: ../src/ui/theme-parser.c:3599 +#: src/x11/meta-x11-display.c:676 #, c-format msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "Prvek <%s> není dovolen v prvku distance/border/aspect_ratio" - -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "Prvek <%s> není dovolen v prvku operace kreslení" - -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "Prvek <%s> není dovolen v prvku <%s>" - -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "U položky rámu neposkytnuty draw_ops" - -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "U tlačítka neposkytnuty draw_ops" - -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "V prvku <%s> není dovolen žádný text" - -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "<%s> u tohoto motivu definováno dvakrát" - -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Nelze nalézt platný soubor motivu %s\n" - -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "_Okna" - -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "_Dialogové okno" - -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "_Modální dialogové okno" - -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "_Nástroje" - -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "_Spouštěcí obrazovka" - -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "_Horní dok" - -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "Dolní do_k" - -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "_Levý dok" - -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "P_ravý dok" - -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "_Všechny doky" - -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "Pra_covní prostředí" - -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "Otevřít další takové okno" - -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "Toto je demonstrační tlačítko s ikonou „otevřít“" - -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "Toto je demonstrační tlačítko s ikonou „ukončit“" - -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "Toto je ukázková zpráva v ukázkovém dialogu" - -#: ../src/ui/theme-viewer.c:328 -#, c-format -msgid "Fake menu item %d\n" -msgstr "Falešná položka nabídky %d\n" - -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "Okno jen s okrajem" - -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "Lišta" - -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "Normální okno aplikace" - -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "Dialogové okno" - -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "Modální dialogové okno" - -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "Paleta nástrojů" - -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "Odtržení nabídky" - -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "Okraj" - -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "Připojené modální dialogové okno" - -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "Test rozložení tlačítek %d" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." +msgstr "" +"Displej „%s“ již správce oken má; zkuste prosím nahradit aktuálního správce " +"oken pomocí přepínače --replace." -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g milisekund na nakreslení jednoho rámu okna" +#: src/x11/meta-x11-display.c:1089 +msgid "Failed to initialize GDK\n" +msgstr "Selhala inicializace GDK\n" -#: ../src/ui/theme-viewer.c:813 +#: src/x11/meta-x11-display.c:1113 #, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Použití: metacity-theme-viewer [NÁZEVMOTIVU]\n" +msgid "Failed to open X Window System display “%s”\n" +msgstr "Nelze otevřít displej X Window System „%s“\n" -#: ../src/ui/theme-viewer.c:820 +#: src/x11/meta-x11-display.c:1196 #, c-format -msgid "Error loading theme: %s\n" -msgstr "Chyba při načítání motivu: %s\n" +msgid "Screen %d on display “%s” is invalid\n" +msgstr "Obrazovka %d na displeji „%s“ je neplatná\n" -#: ../src/ui/theme-viewer.c:826 +#: src/x11/meta-x11-selection-input-stream.c:460 #, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "Načten motiv „%s“ za %g sekund\n" - -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "Normální písmo nadpisu" - -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "Malé písmo nadpisu" - -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "Velké písmo nadpisu" - -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "Rozložení tlačítek" - -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "Test výkonnosti" +msgid "Format %s not supported" +msgstr "Formát %s není podporován" -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "Sem patří nadpis okna" - -#: ../src/ui/theme-viewer.c:1047 -#, c-format +#: src/x11/session.c:1821 msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." msgstr "" -"Nakresleno %d rámů za %g sekund na straně klienta (%g milisekund na rám) a " -"%g sekund reálného času včetně zdrojů serveru X (%g milisekund na rám)\n" - -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "test výrazu umístění vrátil TRUE, ale nastavil chybu" - -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "test výrazu umístění vrátil FALSE, ale nenastavil chybu" +"Tato okna nepodporují „uložení aktuálního nastavení“ a po svém příštím " +"přihlášení je budete muset spustit ručně." -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "Byla očekávána chyba, ale nebyla přijata" - -#: ../src/ui/theme-viewer.c:1274 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "Byla očekávána chyba %d, ale bylo přijato %d" - -#: ../src/ui/theme-viewer.c:1280 +#: src/x11/window-props.c:569 #, c-format -msgid "Error not expected but one was returned: %s" -msgstr "Chyba nebyla očekávána, ale byla vrácena: %s" - -#: ../src/ui/theme-viewer.c:1284 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "Hodnota x byla %d, bylo očekáváno %d" - -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "Hodnota y byla %d, bylo očekáváno %d" - -#: ../src/ui/theme-viewer.c:1352 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "Zpracováno %d výrazů souřadnic za %g sekund (průměr %g sekund)\n" +msgid "%s (on %s)" +msgstr "%s (na %s)" diff --git a/po/cy.po b/po/cy.po index 4e0d135e9..936f060bc 100644 --- a/po/cy.po +++ b/po/cy.po @@ -15,6 +15,7 @@ msgstr "" "PO-Revision-Date: 2008-02-05 21:12-0000\n" "Last-Translator: Rhys Jones <rhys@sucs.org>\n" "Language-Team: Cymraeg <gnome-cy@pengwyn.linux.org.uk>\n" +"Language: cy\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -3668,7 +3669,7 @@ msgid "" "type=\"%s\" style_set=\"whatever\"/> element" msgstr "" "Dim arddull ffrâm wedi ei osod ar gyfer y math ffenest \"%s\" yn y thema \"%s" -"\", ychwanegwch elfen <window type=\"%s\" style_set\"beth bynnag\"/>" +"\", ychwanegwch elfen <window type=\"%s\" style_set=\"beth bynnag\"/>" #: ../src/ui/theme.c:5207 ../src/ui/theme.c:5269 ../src/ui/theme.c:5332 #, c-format diff --git a/po/da.po b/po/da.po index f51495172..fb6978428 100644 --- a/po/da.po +++ b/po/da.po @@ -1,5 +1,5 @@ -# Danish translation of Muffin. -# Copyright (C) 2002-2009, 2012. +# Danish translation of Mutter. +# Copyright (C) 2002-2009, 2012-2019. # This file is distributed under the same license as the metacity package. # Kjartan Maraas <kmaraas@gnome.org>, 2002 # Keld simonsen <keld@dkuug.dk>, 2002 @@ -7,1588 +7,1639 @@ # Martin Willemoes Hansen <mwh@sysrq.dk>, 2004, 05. # Lasse Bang Mikkelsen <lbm@fatalerror.dk>, 2006. # Kenneth Nielsen <k.nielsen81@gmail.com>, 2008. -# Ask Hjorth Larsen <asklarsen@gmail.com>, 2007, 09, 10, 12. # Joe Hansen <joedalton2@yahoo.dk>, 2011. +# Ask Hjorth Larsen <asklarsen@gmail.com>, 2007, 09, 10, 12, 13, 14, 15, 16, 17, 18, 19. # -# Konventioner: +# Ordliste: +# +# display -> terminal # # Når man multitasker mellem flere vinduer, vises der (afhængigt af indstillingerne) et pop op-vindue med ikoner for de forskellige programmer. Dette vindue kaldes navigationsvinduet. # msgid "" msgstr "" -"Project-Id-Version: muffin\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-03-19 09:54+0100\n" -"PO-Revision-Date: 2012-03-19 09:48+0100\n" -"Last-Translator: Joe Hansen <joedalton2@yahoo.dk>\n" +"Project-Id-Version: mutter\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2020-02-23 17:41+0000\n" +"PO-Revision-Date: 2020-02-27 18:56+0100\n" +"Last-Translator: Alan Mortensen <alanmortensen.am@gmail.com>\n" "Language-Team: Danish <dansk@dansk-gruppen.dk>\n" "Language: da\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.0.6\n" + +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Navigation" + +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Flyt vindue til arbejdsområde 1" + +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Flyt vindue til arbejdsområde 2" + +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Flyt vindue til arbejdsområde 3" + +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Flyt vindue til arbejdsområde 4" + +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Flyt vindue til sidste arbejdsområde" + +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "Flyt vindue et arbejdsområde op" + +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "Flyt vindue et arbejdsområde ned" + +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "Flyt vindue en skærm til venstre" + +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "Flyt vindue en skærm til højre" + +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "Flyt vindue en skærm op" + +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "Flyt vindue en skærm ned" + +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "Skift mellem programmer" + +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "Skift til forrige program" + +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "Skift mellem vinduer" + +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "Skift til forrige vindue" + +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "Skift mellem vinduer i et program" + +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "Skift til forrige vindue af et program" + +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "Skift mellem systemkontroller" + +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "Skift til forrige systemkontrol" + +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "Skift direkte mellem vinduer" + +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "Skift direkte til forrige vindue" + +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "Skift direkte mellem vinduer i et program" + +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "Skift direkte til forrige vindue af et program" + +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "Skift direkte mellem systemkontroller" + +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "Skift direkte til forrige systemkontrol" + +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "Skjul alle normale vinduer" + +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "Skift til arbejdsområde 1" + +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "Skift til arbejdsområde 2" + +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "Skift til arbejdsområde 3" + +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "Skift til arbejdsområde 4" + +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "Skift til sidste arbejdsområde" + +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "Flyt til arbejdsområdet ovenover" + +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "Flyt til arbejdsområdet nedenunder" + +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "System" + +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Vis “kør kommando”-prompten" + +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Vis aktivitetsoversigten" + +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Gendan tastaturgenvejene" + +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Vinduer" + +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "Aktivér vinduesmenuen" + +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Slå fuldskærmstilstand til/fra" + +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "Slå maksimering til/fra" + +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "Maksimér vindue" + +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Gendan vindue" + +#: data/50-mutter-windows.xml:18 +msgid "Close window" +msgstr "Luk vindue" + +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "Skjul vindue" + +#: data/50-mutter-windows.xml:22 +msgid "Move window" +msgstr "Flyt vindue" + +#: data/50-mutter-windows.xml:24 +msgid "Resize window" +msgstr "Ændr vinduesstørrelse" -#: ../src/50-muffin-windows.xml.in.h:1 +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "Slå visning af vindue på alle arbejdsområder til/fra" + +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "Hæv vindue hvis det er dækket, ellers sænk det" + +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "Hæv vindue over andre vinduer" + +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "Sænk vindue under andre vinduer" + +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "Maksimér vindue lodret" + +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "Maksimér vindue vandret" + +#: data/50-mutter-windows.xml:41 msgid "View split on left" msgstr "Delt visning venstre" -#: ../src/50-muffin-windows.xml.in.h:2 +#: data/50-mutter-windows.xml:45 msgid "View split on right" msgstr "Delt visning højre" -#: ../src/50-muffin-windows.xml.in.h:3 -msgid "Windows" -msgstr "Vinduer" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:7 +msgid "Modifier to use for extended window management operations" +msgstr "Modifikationstast til brug for udvidede vindueshåndteringsoperationer" + +#: data/org.gnome.mutter.gschema.xml.in:8 msgid "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." msgstr "" -"En anden komposithåndtering kører allerede på skærm %i på terminal \"%s\"." +"Denne nøgle vil klargøre “overlay”, som er en kombineret vinduesoversigt og " +"programstartersystem. Standardværdien på PC-hardware er tiltænkt som " +"“Windows”-tasten. Det forventes, at denne binding enten har standardværdien, " +"eller er sat til den tomme streng." -#: ../src/core/bell.c:307 -msgid "Bell event" -msgstr "Bip-hændelse" +#: data/org.gnome.mutter.gschema.xml.in:20 +msgid "Attach modal dialogs" +msgstr "Fastgør modaldialoger" -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Ukendt forespørgsel efter vinduesinformation: %d" +#: data/org.gnome.mutter.gschema.xml.in:21 +msgid "" +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." +msgstr "" +"Når sand, vil modaldialoger hænge sammen med titellinjen af ophavsvinduet og " +"flyttes sammen med dette, frem for at have uafhængige titellinjer." -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> svarer ikke." +#: data/org.gnome.mutter.gschema.xml.in:30 +msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "" +"Aktivér maksimering eller halvmaksimering når vinduer slippes over " +"skærmranden" -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "Program svarer ikke." +#: data/org.gnome.mutter.gschema.xml.in:31 +msgid "" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." +msgstr "" +"Hvis slået til, vil vinduer, der slippes på en lodret skærmrand, blive " +"maksimeret lodret, og vil vandret blive tildelt halvdelen af det " +"tilgængelige område. Vinduer, der slippes på øverste skærmrand, maksimeres " +"helt." -#: ../src/core/delete.c:119 +#: data/org.gnome.mutter.gschema.xml.in:40 +msgid "Workspaces are managed dynamically" +msgstr "Arbejdsområder håndteres dynamisk" + +#: data/org.gnome.mutter.gschema.xml.in:41 msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." +"Determines whether workspaces are managed dynamically or whether there’s a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." msgstr "" -"Du kan vælge at vente et lille stykke tid på at programmet fortsætter, eller " -"du kan tvinge programmet til at afslutte fuldstændigt." +"Afgør om arbejdsområderne håndteres dynamisk, eller om der er et statisk " +"antal arbejdsområder (angivet med nøglen num-workspaces i org.gnome.desktop." +"wm.preferences)." -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "_Vent" +#: data/org.gnome.mutter.gschema.xml.in:50 +msgid "Workspaces only on primary" +msgstr "Arbejdsområder kun på primær skærm" -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "_Tving til at afslutte" +#: data/org.gnome.mutter.gschema.xml.in:51 +msgid "" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." +msgstr "" +"Angiver om skift mellem arbejdsområder skal ske for vinduer på alle skærme, " +"eller kun for vinduer på den primære skærm." + +#: data/org.gnome.mutter.gschema.xml.in:59 +msgid "No tab popup" +msgstr "Ingen tab-pop-op" + +#: data/org.gnome.mutter.gschema.xml.in:60 +msgid "" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." +msgstr "" +"Afgør om brugen af pop-op og fremhævet vinduesramme skal deaktiveres ved " +"vinduesskifte." + +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Lad fokusændringer vente indtil markøren holder op med at bevæge sig" + +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" +"Hvis sat til sand, og fokustilstanden er enten “sloppy” eller “mouse”, vil " +"fokus ikke blive ændret omgående når man går ind i et nyt vindue, men først " +"efter markøren holder op med at bevæge sig." + +#: data/org.gnome.mutter.gschema.xml.in:79 +msgid "Draggable border width" +msgstr "Bredde af den trækbare kant" + +#: data/org.gnome.mutter.gschema.xml.in:80 +msgid "" +"The amount of total draggable borders. If the theme’s visible borders are " +"not enough, invisible borders will be added to meet this value." +msgstr "" +"Samlet mængde kant der kan trækkes. Hvis temaets synlige grænser ikke er " +"nok, så vil usynlige kanter blive tilføjet for at møde denne værdi." + +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "Maksimér automatisk vinduer hvis størrelse næsten passer til skærmen" + +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" +"Hvis aktiveret vil nye vinduer, som i begyndelsen har samme størrelse som " +"skærmen, blive automatisk maksimeret." + +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Placér nye vinduer i midten" + +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" +"Når sand, vil nye vinduer altid blive placeret i midten af den aktive skærm." + +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Slå eksperimentelle funktioner til" + +#: data/org.gnome.mutter.gschema.xml.in:108 +msgid "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes " +"mutter request a low priority real-time scheduling. The executable or user " +"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — " +"initializes Xwayland lazily if there are X11 clients. Requires restart." +msgstr "" +"For at slå eksperimentelle funktioner til, skal du tilføje " +"funktionsnøgleordet til listen. Om funktionen kræver genstart af " +"kompositoren afhænger af den givne funktion. Der er ingen garanti for, at " +"eksperimentelle funktioner forbliver tilgængelige eller mulige at " +"konfigurere. Forvent ikke at noget i denne indstilling nødvendigvis fungerer " +"i fremtiden. Mulige nøgleord i øjeblikket: • “scale-monitor-framebuffer” — " +"får mutter til som standard at arrangere logiske skærme i et logisk " +"pixelkoordinatrum, mens skærmes framebuffere skaleres frem for " +"vinduesindholdet for at håndtere HiDPI-skærme. Kræver ikke genstart. • “rt-" +"scheduler” — får mutter til at anmode om en lav prioritet til realtids-" +"prioritetstildeling. Den eksekverbare fil eller brugeren skal have " +"CAP_SYS_NICE. Kræver genstart. • “autostart-xwayland” — venter med at " +"initialisere Xwayland indtil det er nødvendigt, hvis der er X11-klienter. " +"Kræver genstart." + +#: data/org.gnome.mutter.gschema.xml.in:134 +msgid "Modifier to use to locate the pointer" +msgstr "Modifikationstast til at finde markøren" + +#: data/org.gnome.mutter.gschema.xml.in:135 +msgid "This key will initiate the “locate pointer” action." +msgstr "Denne tast starter handlingen “find markør”." + +#: data/org.gnome.mutter.gschema.xml.in:142 +msgid "Timeout for check-alive ping" +msgstr "Tidsudløb for kontrolping" + +#: data/org.gnome.mutter.gschema.xml.in:143 +msgid "" +"Number of milliseconds a client has to respond to a ping request in order to " +"not be detected as frozen. Using 0 will disable the alive check completely." +msgstr "" +"Antal millisekunder en klient har til at svare på en pingforespørgsel for " +"ikke at blive registreret som frosset. Med 0 vil forespørgslen være helt " +"deaktiveret." + +#: data/org.gnome.mutter.gschema.xml.in:165 +msgid "Select window from tab popup" +msgstr "Vælg vindue fra tab-pop-op" -#: ../src/core/display.c:387 +#: data/org.gnome.mutter.gschema.xml.in:170 +msgid "Cancel tab popup" +msgstr "Annullér faneblads-pop-op" + +#: data/org.gnome.mutter.gschema.xml.in:175 +msgid "Switch monitor configurations" +msgstr "Skift skærmkonfiguration" + +# Mærkelig ting at rotere. De mener nok at skifte cyclisk mellem nogle stykker, men "built-in"? +#: data/org.gnome.mutter.gschema.xml.in:180 +msgid "Rotates the built-in monitor configuration" +msgstr "Roterer den indbyggede skærmkonfiguration" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Skift til VT 1" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Skift til VT 2" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Skift til VT 3" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Skift til VT 4" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Skift til VT 5" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Skift til VT 6" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Skift til VT 7" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Skift til VT 8" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Skift til VT 9" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Skift til VT 10" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Skift til VT 11" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Skift til VT 12" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "Genaktivér genveje" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow X11 grabs to lock keyboard focus with Xwayland" +msgstr "Tillad X11-indfangelse at låse tastaturfokus med Xwayland" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 +msgid "" +"Allow all keyboard events to be routed to X11 “override redirect” windows " +"with a grab when running in Xwayland. This option is to support X11 clients " +"which map an “override redirect” window (which do not receive keyboard " +"focus) and issue a keyboard grab to force all keyboard events to that " +"window. This option is seldom used and has no effect on regular X11 windows " +"which can receive keyboard focus under normal circumstances. For a X11 grab " +"to be taken into account under Wayland, the client must also either send a " +"specific X11 ClientMessage to the root window or be among the applications " +"white-listed in key “xwayland-grab-access-rules”." +msgstr "" +"Tillad at alle tastaturbegivenheder sendes til X11-vinduer med “override " +"redirect” via indfangelse ved kørsel i Xwayland. Denne indstilling er der " +"for at understøtte X11-klienter, som afbilder et “override redirect”-vindue " +"(som ikke modtager tastaturfokus) og udsende en tastaturindfangelse, som " +"tvinger alle tastaturbegivenheder til dét vindue. Denne indstilling bruges " +"sjældent, og har ingen virkning på normale X11-vinduer, som kan modtage " +"tastaturfokus under normale omstændigheder. For at en X11-" +"tastaturindfangelse behandles i Wayland, skal klienten også enten sende en " +"specifik X11-ClientMessage til rodvinduet eller være blandt de godkendte " +"programmer i nøglen “xwayland-grab-access-rules”." + +#: data/org.gnome.mutter.wayland.gschema.xml.in:84 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "Xwayland-programmer, som må indfange tastatur" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:85 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "" +"Anfør navne på ressourcer eller ressourceklasser for X11-vinduer som " +"tillades eller ikke tillades at udføre X11-tastaturindfangelse under " +"Xwayland. Ressourcenavnet eller ressourceklassen for et givent X11-vindue " +"kan findes med kommandoen “xprop WM_CLASS”. Værdierne understøtter " +"jokertegnene “*” og “?”. Værdier som begynder med “!” forbydes, hvilket har " +"præcedens over godkendelse, og dette tillader at fjerne programmer som " +"ellers findes i systemets standardliste. Denne liste inkluderer følgende " +"programmer: “@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@”. Brugere kan afbryde en " +"eksisterende indfangelse ved hjælp af den særlige tastaturgenvej defineret " +"ved nøglen “restore-shortcuts”." + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. +#. +#: src/backends/meta-input-settings.c:2567 #, c-format -msgid "Missing %s extension required for compositing" -msgstr "Manglende %s-udvidelse som kræves til komposition" +msgid "Mode Switch (Group %d)" +msgstr "Tilstandsskift (Gruppe %d)" + +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2590 +msgid "Switch monitor" +msgstr "Skift skærm" -#: ../src/core/display.c:453 +#: src/backends/meta-input-settings.c:2592 +msgid "Show on-screen help" +msgstr "Vis integreret hjælp" + +#: src/backends/meta-monitor.c:223 +msgid "Built-in display" +msgstr "Indbygget terminal" + +#: src/backends/meta-monitor.c:252 +msgid "Unknown" +msgstr "Ukendt" + +#: src/backends/meta-monitor.c:254 +msgid "Unknown Display" +msgstr "Ukendt terminal" + +#: src/backends/meta-monitor.c:262 #, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Kunne ikke åbne X Window System-terminalen \"%s\"\n" +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" -#: ../src/core/keybindings.c:852 +#: src/backends/meta-monitor.c:270 +#, c-format +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" + +#. Translators: this string will appear in Sysprof +#: src/backends/meta-profiler.c:79 +msgid "Compositor" +msgstr "Kompositor" + +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:533 #, c-format msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "" -"Et andet program bruger allerede nøglen %s med modifikatorer %x som binding\n" +"Another compositing manager is already running on screen %i on display “%s”." +msgstr "Der kører allerede en anden kompositor på skærm %i på terminal “%s”." + +#: src/core/bell.c:192 +msgid "Bell event" +msgstr "Bip-hændelse" -#: ../src/core/main.c:206 +#: src/core/main.c:190 msgid "Disable connection to session manager" msgstr "Deaktivér forbindelse til sessionshåndtering" -#: ../src/core/main.c:212 +#: src/core/main.c:196 msgid "Replace the running window manager" msgstr "Erstat den kørende vindueshåndtering" -#: ../src/core/main.c:218 +#: src/core/main.c:202 msgid "Specify session management ID" msgstr "Angiv sessionhåndterings-id" -#: ../src/core/main.c:223 +#: src/core/main.c:207 msgid "X Display to use" -msgstr "X-skærm som bruges" +msgstr "X-terminal som bruges" -#: ../src/core/main.c:229 +#: src/core/main.c:213 msgid "Initialize session from savefile" msgstr "Initialisér session fra gemt fil" -#: ../src/core/main.c:235 +#: src/core/main.c:219 msgid "Make X calls synchronous" msgstr "Gør kald til X synkrone" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Kunne ikke skanne temamappe: %s\n" +#: src/core/main.c:226 +msgid "Run as a wayland compositor" +msgstr "Kør som en wayland-kompositor" + +#: src/core/main.c:232 +msgid "Run as a nested compositor" +msgstr "Kør som en indlejret kompositor" + +#: src/core/main.c:238 +msgid "Run wayland compositor without starting Xwayland" +msgstr "Kør wayland-kompositoren uden at starte Xwayland" -#: ../src/core/main.c:520 +#: src/core/main.c:246 +msgid "Run as a full display server, rather than nested" +msgstr "Kør som fuld terminalserver, frem for indlejret" + +#: src/core/main.c:252 +msgid "Run with X11 backend" +msgstr "Kør med X11-motor" + +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:151 #, c-format +msgid "“%s” is not responding." +msgstr "“%s” svarer ikke." + +#: src/core/meta-close-dialog-default.c:153 +msgid "Application is not responding." +msgstr "Program svarer ikke." + +#: src/core/meta-close-dialog-default.c:158 msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." msgstr "" -"Kunne ikke finde et tema! Sikr dig at %s eksisterer og indeholder de " -"sædvanlige temaer.\n" +"Du kan vælge at vente et lille stykke tid på at programmet fortsætter, eller " +"du kan tvinge programmet til at afslutte fuldstændigt." + +#: src/core/meta-close-dialog-default.c:165 +msgid "_Force Quit" +msgstr "_Tving til at afslutte" + +#: src/core/meta-close-dialog-default.c:165 +msgid "_Wait" +msgstr "_Vent" -#: ../src/core/muffin.c:40 +#: src/core/mutter.c:38 #, c-format msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" "This is free software; see the source for copying conditions.\n" "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " "PARTICULAR PURPOSE.\n" msgstr "" -"muffin %s\n" -"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., og andre\n" +"mutter %s\n" +"Copyright © 2001–%d Havoc Pennington, Red Hat, Inc., og andre\n" "Dette er frit programmel; se kildekoden for kopieringsbetingelser.\n" "Der er INGEN garanti; ikke engang for SALGBARHED eller EGNETHED TIL ET " "BESTEMT FORMÅL.\n" -#: ../src/core/muffin.c:54 +#: src/core/mutter.c:52 msgid "Print version" msgstr "Vis version" -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "Kommaadskilt liste af komposit-udvidelsesmoduler" +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "Mutter-udvidelsesmodul der skal bruges" -#: ../src/core/prefs.c:1077 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"Omgåelser for ødelagte programmer deaktiveret. Nogle programmer opfører sig " -"måske ikke korrekt.\n" - -#: ../src/core/prefs.c:1152 +#: src/core/prefs.c:1911 #, c-format -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "" -"Kunne ikke fortolke skrifttypebeskrivelsen \"%s\" fra GSettings-nøglen %s\n" +msgid "Workspace %d" +msgstr "Arbejdsområde %d" -#: ../src/core/prefs.c:1218 +#: src/core/util.c:122 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter blev kompileret uden understøttelse for uddybende tilstand\n" + +#: src/wayland/meta-wayland-tablet-pad.c:568 #, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"\"%s\" fundet i konfigurationsdatabasen er ikke en gyldig værdi som " -"museknapsmodifikation\n" +msgid "Mode Switch: Mode %d" +msgstr "Tilstandsskift: Tilstand %d" -#: ../src/core/prefs.c:1739 +#: src/x11/meta-x11-display.c:676 #, c-format msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." msgstr "" -"\"%s\" fundet i konfigurationsdatabasen er ikke en gyldig værdi for " -"tastebindingen \"%s\"\n" +"Terminalen “%s” har allerede en vindueshåndtering; prøv tilvalget --replace " +"for at erstatte den aktuelle vindueshåndtering." -#: ../src/core/prefs.c:1836 -#, c-format -msgid "Workspace %d" -msgstr "Arbejdsområde %d" +#: src/x11/meta-x11-display.c:1089 +msgid "Failed to initialize GDK\n" +msgstr "Kunne ikke klargøre GDK\n" -#: ../src/core/screen.c:730 +#: src/x11/meta-x11-display.c:1113 #, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "Skærm %d på terminal \"%s\" er ugyldig\n" +msgid "Failed to open X Window System display “%s”\n" +msgstr "Kunne ikke åbne X Window System-terminalen “%s”\n" -#: ../src/core/screen.c:746 +#: src/x11/meta-x11-display.c:1196 #, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"Skærm %d på terminal \"%s\" har allerede en vindueshåndtering; prøv " -"tilvalget --replace for at erstatte den aktuelle vindueshåndtering.\n" +msgid "Screen %d on display “%s” is invalid\n" +msgstr "Skærm %d på terminal “%s” er ugyldig\n" -#: ../src/core/screen.c:773 +#: src/x11/meta-x11-selection-input-stream.c:460 #, c-format +msgid "Format %s not supported" +msgstr "Formatet %s understøttes ikke" + +#: src/x11/session.c:1821 msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." msgstr "" -"Kunne ikke fremskaffe vindueshåndteringvælgeren på skærm %d på terminal \"%s" -"\"\n" +"Disse vinduer understøtter ikke at gemme deres opsætning og skal genstartes " +"manuelt næste gang, du logger på." -#: ../src/core/screen.c:828 +# Lad os håbe dette er rigtigt +#: src/x11/window-props.c:569 #, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "Skærm %d på terminal \"%s\" har allerede en vindueshåndtering\n" +msgid "%s (on %s)" +msgstr "%s (på %s)" -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "Kunne ikke frigive skærm %d på terminal \"%s\"\n" +#~ msgid "Move window one workspace to the left" +#~ msgstr "Flyt vindue et arbejdsområde til venstre" -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Kunne ikke oprette mappen \"%s\": %s\n" +#~ msgid "Move window one workspace to the right" +#~ msgstr "Flyt vindue et arbejdsområde til højre" -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "Kunne ikke åbne sessionsfilen \"%s\" til skrivning: %s\n" +#~ msgid "Move to workspace left" +#~ msgstr "Flyt til arbejdsområdet til venstre" -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Fejl under skrivning af sessionsfilen \"%s\": %s\n" +#~ msgid "Move to workspace right" +#~ msgstr "Flyt til arbejdsområdet til højre" -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Fejl under lukning af sessionsfilen \"%s\": %s\n" +#~ msgid "Toggle shaded state" +#~ msgstr "Slå vinduesoprulning til/fra" -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Kunne ikke fortolke den lagrede sessionsfil: %s\n" +#~ msgid "Failed to scan themes directory: %s\n" +#~ msgstr "Kunne ikke skanne temamappe: %s\n" -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "" -"<muffin_session>-egenskaben blev fundet, men vi har allerede sessions-id'en" +#~ msgid "" +#~ "Could not find a theme! Be sure %s exists and contains the usual themes.\n" +#~ msgstr "" +#~ "Kunne ikke finde et tema! Sikr dig at %s eksisterer og indeholder de " +#~ "sædvanlige temaer.\n" -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Ukendt egenskab %s for <%s>-element" +#~ msgid "%d x %d" +#~ msgstr "%d x %d" -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "indlejret <window>-mærke" +#~ msgid "top" +#~ msgstr "top" -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "Ukendt element %s" +#~ msgid "bottom" +#~ msgstr "bund" -#: ../src/core/session.c:1809 -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" -"Disse vinduer understøtter ikke gemning af deres opsætning og skal " -"genstartes manuelt næste gang du logger på." +#~ msgid "left" +#~ msgstr "venstre" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Kunne ikke åbne fejlinformationslog: %s\n" +#~ msgid "right" +#~ msgstr "højre" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Kunne ikke udføre fdopen() på logfilen %s: %s\n" +#~ msgid "frame geometry does not specify \"%s\" dimension" +#~ msgstr "rammegeometri angiver ikke dimensionen “%s”" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "Åbnede logfilen %s\n" +#~ msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" +#~ msgstr "rammegeometri angiver ikke dimensionen “%s” for kanten “%s”" -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "Muffin blev kompileret uden understøttelse for uddybende tilstand\n" +#~ msgid "Button aspect ratio %g is not reasonable" +#~ msgstr "Knapformatforholdet %g er ikke fornuftigt" -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "Vindueshåndtering: " +#~ msgid "Frame geometry does not specify size of buttons" +#~ msgstr "Rammegeometri angiver ikke størrelsen af knapper" -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "Fejl i vindueshåndtering: " +#~ msgid "Gradients should have at least two colors" +#~ msgstr "Farveovergange skal mindst have to farver" -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "Vindueshåndteringsadvarsel: " +#~ msgid "" +#~ "GTK custom color specification must have color name and fallback in " +#~ "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" +#~ msgstr "" +#~ "Specifikation for tilpasset GTK-farve skal have et farvenavn og standard " +#~ "i parentes f.eks. gtk:custom(foo,bar); kunne ikke fortolke “%s”" -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "Vindueshåndteringsfejl: " +#~ msgid "" +#~ "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-" +#~ "z0-9-_ are valid" +#~ msgstr "" +#~ "Ugyldigt tegn “%c” i parameteren color_name for gtk:custom, kun A-Za-z0-9-" +#~ "_ er gyldig" -#. first time through -#: ../src/core/window.c:7266 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"Vinduet %s angiver SM_CLIENT_ID for det selv i stedet for WM_CLIENT_LEADER-" -"vinduet som specificeret i ICCCM.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7931 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size " -"%d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"Vinduet %s angiver et MWM-hint for at indikere at dets størrelse ikke kan " -"ændres, men angiver den mindste størrelse %d x %d og den maksimale størrelse " -"%d x %d; dette giver ikke mening.\n" +#~ msgid "" +#~ "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " +#~ "fit the format" +#~ msgstr "" +#~ "Gtk:custom-formatet er “gtk:custom(color_name,fallback)”, “%s” passer " +#~ "ikke med formatet" -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "Program angav en ugyldig _NET_WM_PID %lu\n" +#~ msgid "" +#~ "GTK color specification must have the state in brackets, e.g. gtk:" +#~ "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "GTK-farvespecifikation skal have tilstanden i firkantede klammer, f.eks. " +#~ "gtk:fg[NORMAL] hvor NORMAL er tilstanden; kunne ikke fortolke “%s”" -# Lad os håbe dette er rigtigt -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (på %s)" +#~ msgid "" +#~ "GTK color specification must have a close bracket after the state, e.g. " +#~ "gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "GTK-farvespecifikation skal have en afsluttende klamme efter tilstanden, " +#~ "f.eks. gtk:fg[NORMAL] hvor NORMAL er tilstanden; kunne ikke fortolke “%s”" -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "Ugyldig WM_TRANSIENT_FOR vindue 0x%lx specificeret for %s.\n" +#~ msgid "Did not understand state \"%s\" in color specification" +#~ msgstr "Forstod ikke tilstanden “%s” i farvespecifikationen" -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "WM_TRANSIENT_FOR vindue 0x%lx for %s vil oprette løkke.\n" +#~ msgid "Did not understand color component \"%s\" in color specification" +#~ msgstr "Forstod ikke farvekomponenten “%s” i farvespecifikationen" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"Vinduet 0x%lx har egenskaben %s\n" -"som forventedes at have typen %s format %d\n" -"og faktisk har typen %s format %d n_items %d.\n" -"Dette er sandsynligvis en fejl i programmet og ikke i vindueshåndteringen.\n" -"Vinduet har titlen \"%s\", klassen \"%s\" og navnet \"%s\"\n" +#~ msgid "" +#~ "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit " +#~ "the format" +#~ msgstr "" +#~ "Blandingsformat er “blend/bg_color/fg_color/alpha”, “%s” passer ikke med " +#~ "formatet" -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "Egenskaben %s for vinduet 0x%lx indeholdt ugyldig UTF-8\n" +#~ msgid "Could not parse alpha value \"%s\" in blended color" +#~ msgstr "Kunne ikke fortolke alfaværdien “%s” i blandet farve" -#: ../src/core/xprops.c:494 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"Egenskaben %s for vinduet 0x%lx indeholdt ugyldig UTF-8 for element %d i " -"listen\n" +#~ msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" +#~ msgstr "Alfaværdien “%s” i blandet farve er ikke mellem 0,0 og 1,0" -#: ../src/muffin.desktop.in.h:1 ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" +#~ msgid "" +#~ "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the " +#~ "format" +#~ msgstr "" +#~ "Skyggeformat er “shade/base_color/factor”, “%s” passer ikke med formatet" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 -msgid "Attach modal dialogs" -msgstr "Fastgør modaldialogvinduer" +#~ msgid "Could not parse shade factor \"%s\" in shaded color" +#~ msgstr "Kunne ikke fortolke skyggeværdien “%s” i skygget farve" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 -msgid "Cancel tab popup" -msgstr "Annullér faneblads-pop-op" +#~ msgid "Shade factor \"%s\" in shaded color is negative" +#~ msgstr "Skyggefaktoren “%s” i skygget farve er negativ" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"Angiver om skjulte vinduer (f.eks. minimerede vinduer og vinduer på andre " -"arbejdsområder end det nuværende) holdes i live." +#~ msgid "Could not parse color \"%s\"" +#~ msgstr "Kunne ikke fortolke farven “%s”" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 -msgid "" -"Determines whether the use of popup and highlight frame should be disabled " -"for window cycling." -msgstr "" -"Afgør om brugen af pop-op og fremhævet vinduesramme skal deaktiveres ved " -"vinduesskifte." +#~ msgid "Coordinate expression contains character '%s' which is not allowed" +#~ msgstr "Koordinatudtryk indeholder tegnet “%s” som ikke er tilladt" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -msgid "" -"Determines whether workspace switching should happen for windows on all " -"monitors or only for windows on the primary monitor." -msgstr "" -"Angiver om skift mellem arbejdsområder skal ske for vinduer på alle skærme, " -"eller kun for vinduer på den primære skærm." +#~ msgid "" +#~ "Coordinate expression contains floating point number '%s' which could not " +#~ "be parsed" +#~ msgstr "Koordinatudtryk indeholder kommatallet “%s” som ikke kunne tolkes" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 -msgid "" -"Determines whether workspaces are managed dynamically or whether there's a " -"static number of workspaces (determined by the num-workspaces key in org." -"gnome.desktop.wm.preferences)." -msgstr "" -"Afgør om arbejdsområderne håndteres dynamisk, eller om der er et statisk " -"antal arbejdsområder (angivet med nøglen num-workspaces i org.cinnamon.desktop." -"wm.preferences)." +#~ msgid "" +#~ "Coordinate expression contains integer '%s' which could not be parsed" +#~ msgstr "Koordinatudtryk indeholder heltallet “%s” som ikke kunne tolkes" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 -msgid "Draggable border width" -msgstr "Bredde af den trækbare kant" +#~ msgid "" +#~ "Coordinate expression contained unknown operator at the start of this " +#~ "text: \"%s\"" +#~ msgstr "" +#~ "Koordinatudtryk indeholdt en ukendt operator i begyndelsen af teksten: " +#~ "“%s”" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 -msgid "Enable edge tiling when dropping windows on screen edges" -msgstr "" -"Aktivér maksimering eller halvmaksimering når vinduer slippes over " -"skærmranden" +#~ msgid "Coordinate expression was empty or not understood" +#~ msgstr "Koordinatudtrykket var tomt eller blev ikke forstået" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 -msgid "" -"If enabled, dropping windows on vertical screen edges maximizes them " -"vertically and resizes them horizontally to cover half of the available " -"area. Dropping windows on the top screen edge maximizes them completely." -msgstr "" -"Hvis slået til, vil vinduer, der slippes på en lodret skærmrand, blive " -"maksimeret lodret, og vil vandret blive tildelt halvdelen af det " -"tilgængelige område. Vinduer, der slippes på øverste skærmrand, maksimeres " -"helt." +#~ msgid "Coordinate expression results in division by zero" +#~ msgstr "Koordinatudtrykket resulterer i division med nul" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 -msgid "Live Hidden Windows" -msgstr "Levende skjulte vinduer" +#~ msgid "" +#~ "Coordinate expression tries to use mod operator on a floating-point number" +#~ msgstr "Koordinatudtrykket prøver at bruge modulo-operator på et kommatal" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 -msgid "Modifier to use for extended window management operations" -msgstr "Modifikationstast til brug for udvidede vindueshåndteringsoperationer" +#~ msgid "" +#~ "Coordinate expression has an operator \"%s\" where an operand was expected" +#~ msgstr "Koordinatudtrykket har en operator “%s” hvor en operand var ventet" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 -msgid "No tab popup" -msgstr "Ingen tab-pop-op" +#~ msgid "Coordinate expression had an operand where an operator was expected" +#~ msgstr "Koordinatudtrykket havde en operand hvor en operator var ventet" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 -msgid "Select window from tab popup" -msgstr "Vælg vindue fra tab-pop-op" +#~ msgid "Coordinate expression ended with an operator instead of an operand" +#~ msgstr "Koordinatudtrykket sluttede med en operator i stedet for en operand" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 -msgid "" -"The amount of total draggable borders. If the theme's visible borders are " -"not enough, invisible borders will be added to meet this value." -msgstr "" -"Samlet mængde kant der kan trækkes. Hvis temaets synlige grænser ikke er " -"nok, så vil usynlige kanter blive tilføjet for at møde denne værdi." +#~ msgid "" +#~ "Coordinate expression has operator \"%c\" following operator \"%c\" with " +#~ "no operand in between" +#~ msgstr "" +#~ "Koordinatudtrykket har en operator “%c” efter en operator “%c” og ingen " +#~ "operand mellem dem" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 -msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." -msgstr "" -"Denne nøgle vil klargøre \"overlay\", som er en kombineret vinduesoversigt " -"og programstartsystem. Standardværdien på PC-hardware er tiltænkt som " -"\"Windows\"-tasten. Det forventes at denne binding enten har " -"standardværdien, eller er sat til den tomme streng." +#~ msgid "Coordinate expression had unknown variable or constant \"%s\"" +#~ msgstr "Koordinatudtrykket havde en ukendt variabel eller konstant “%s”" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 -msgid "" -"When true, instead of having independent titlebars, modal dialogs appear " -"attached to the titlebar of the parent window and are moved together with " -"the parent window." -msgstr "" -"Når sand, vil modaldialogvinduer hænge sammen med titellinjen af " -"ophavsvinduet og flyttes sammen med dette, frem for at have uafhængige " -"titellinjer." +#~ msgid "Coordinate expression parser overflowed its buffer." +#~ msgstr "Koordinatudtryksfortolkeren har fået bufferoverløb." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:17 -msgid "Workspaces are managed dynamically" -msgstr "Arbejdsområder håndteres dynamisk" +#~ msgid "" +#~ "Coordinate expression had a close parenthesis with no open parenthesis" +#~ msgstr "Koordinatudtrykket havde en slutparantes uden startparantes" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:18 -msgid "Workspaces only on primary" -msgstr "Arbejdsområder kun på primær skærm" +#~ msgid "" +#~ "Coordinate expression had an open parenthesis with no close parenthesis" +#~ msgstr "Koordinatudtrykket havde en startparantes uden en slutparantes" -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "Brug: %s\n" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "Mi_nimér" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "Ma_ksimér" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "_Gendan" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "Rul _op" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "Rul _ned" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "_Flyt" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "Ænd_re størrelse" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "Flyt titellinje til _skærm" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "Altid _øverst" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "_Altid på synligt arbejdsområde" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "_Kun på dette arbejdsområde" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "Flyt til arbejdsområde til _venstre" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "Flyt til arbejdsområde til _højre" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "Flyt til arbejdsområde _op" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "Flyt til arbejdsområde _ned" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "_Luk" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "Arbejdsområde %d%n" +#~ msgid "Coordinate expression doesn't seem to have any operators or operands" +#~ msgstr "" +#~ "Koordinatudtrykket ser ikke ud til at have nogen operatorer eller " +#~ "operander" -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "Arbejdsområde 1_0" +#~ msgid "Theme contained an expression that resulted in an error: %s\n" +#~ msgstr "Tema indeholdt et udtryk som resulterede i en fejl: %s\n" -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "Arbejdsområde %s%d" +#~ msgid "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " +#~ "specified for this frame style" +#~ msgstr "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"et-eller-andet\"/> skal " +#~ "angives for denne rammestil" -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "Flyt til andet _arbejdsområde" +#~ msgid "" +#~ "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/" +#~ ">" +#~ msgstr "" +#~ "Manglende <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"et-eller-" +#~ "andet\"/>" -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Skift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" +#~ msgid "Failed to load theme \"%s\": %s\n" +#~ msgstr "Kunne ikke indlæse temaet “%s”: %s\n" + +#~ msgid "No <%s> set for theme \"%s\"" +#~ msgstr "Ingen <%s> angivet for temaet \"%s\"" + +#~ msgid "" +#~ "No frame style set for window type \"%s\" in theme \"%s\", add a <window " +#~ "type=\"%s\" style_set=\"whatever\"/> element" +#~ msgstr "" +#~ "Ingen rammestil angivet for vinduestypen \"%s\" i temaet \"%s\", tilføj " +#~ "et <window type=\"%s\" style_set=\"et-eller-andet\"/>-element" + +#~ msgid "" +#~ "User-defined constants must begin with a capital letter; \"%s\" does not" +#~ msgstr "" +#~ "Brugerdefinerede konstanter skal begynde med et stort bogstav; det gør " +#~ "“%s” ikke" + +#~ msgid "Constant \"%s\" has already been defined" +#~ msgstr "Konstanten “%s” er allerede defineret" + +#~ msgid "No \"%s\" attribute on element <%s>" +#~ msgstr "Ingen \"%s\"-egenskab i elementet <%s>" + +#~ msgid "Line %d character %d: %s" +#~ msgstr "Linje %d tegn %d: %s" + +#~ msgid "Attribute \"%s\" repeated twice on the same <%s> element" +#~ msgstr "Egenskaben \"%s\" er gentaget to gange i det samme <%s>-element" + +#~ msgid "Attribute \"%s\" is invalid on <%s> element in this context" +#~ msgstr "Egenskaben \"%s\" er ugyldig i <%s>-elementet i denne sammenhæng" + +#~ msgid "Could not parse \"%s\" as an integer" +#~ msgstr "Kunne ikke fortolke “%s” som et heltal" + +#~ msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +#~ msgstr "Forstod ikke de afsluttende tegn “%s” i tekststrengen “%s”" + +#~ msgid "Integer %ld must be positive" +#~ msgstr "Heltallet %ld skal være positivt" + +#~ msgid "Integer %ld is too large, current max is %d" +#~ msgstr "Heltallet %ld er for stort, det nuværende maksimum er %d" + +#~ msgid "Could not parse \"%s\" as a floating point number" +#~ msgstr "Kunne ikke fortolke “%s” som et kommatal" + +#~ msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" +#~ msgstr "Booleske værdier skal være “true” eller “false” ikke “%s”" + +#~ msgid "Angle must be between 0.0 and 360.0, was %g\n" +#~ msgstr "Vinkel skal være mellem 0.0 og 360.0, var %g\n" + +#~ msgid "" +#~ "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" +#~ msgstr "" +#~ "Alfa skal være mellem 0.0 (usynlig) og 1.0 (helt ugennemsigtig), var %g\n" + +#~ msgid "" +#~ "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," +#~ "large,x-large,xx-large)\n" +#~ msgstr "" +#~ "Ugyldig titelskalering “%s” (skal være en af xx-small,x-small,small," +#~ "medium,large,x-large,xx-large)\n" + +#~ msgid "<%s> name \"%s\" used a second time" +#~ msgstr "<%s>-navnet \"%s\" brugt to gange" + +#~ msgid "<%s> parent \"%s\" has not been defined" +#~ msgstr "<%s>-ophavet \"%s\" er ikke blevet defineret" + +#~ msgid "<%s> geometry \"%s\" has not been defined" +#~ msgstr "<%s>-geometrien \"%s\" er ikke blevet defineret" + +#~ msgid "<%s> must specify either a geometry or a parent that has a geometry" +#~ msgstr "" +#~ "<%s> skal enten angive en geometri eller et ophav der har en geometri" + +#~ msgid "You must specify a background for an alpha value to be meaningful" +#~ msgstr "Du skal angive en baggrund hvis en alfaværdi skal være meningsfuld" -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" +#~ msgid "Unknown type \"%s\" on <%s> element" +#~ msgstr "Ukendt type \"%s\" i <%s>-element" -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "top" +#~ msgid "Unknown style_set \"%s\" on <%s> element" +#~ msgstr "Ukendt style_set \"%s\" i <%s>-element" -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "bund" +#~ msgid "Window type \"%s\" has already been assigned a style set" +#~ msgstr "Vinduestypen “%s” er allerede blevet tildelt et stilsæt" -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "venstre" +#~ msgid "Element <%s> is not allowed below <%s>" +#~ msgstr "Elementet <%s> er ikke tilladt under <%s>" -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "højre" +#~ msgid "" +#~ "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio" +#~ "\" for buttons" +#~ msgstr "" +#~ "Kan ikke angive både “button_width”/“button_height” og “aspect_ratio” for " +#~ "knapper" -#: ../src/ui/theme.c:286 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "rammegeometri angiver ikke dimensionen \"%s\"" +#~ msgid "Distance \"%s\" is unknown" +#~ msgstr "Afstanden “%s” er ukendt" -#: ../src/ui/theme.c:305 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "rammegeometri angiver ikke dimensionen \"%s\" for kanten \"%s\"" +#~ msgid "Aspect ratio \"%s\" is unknown" +#~ msgstr "Formatforholdet “%s” er ukendt" -#: ../src/ui/theme.c:342 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "Knapformatforholdet %g er ikke fornuftigt" +#~ msgid "Border \"%s\" is unknown" +#~ msgstr "Kanten “%s” er ukendt" -#: ../src/ui/theme.c:354 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "Rammegeometri angiver ikke størrelsen af knapper" +#~ msgid "No \"start_angle\" or \"from\" attribute on element <%s>" +#~ msgstr "Ingen \"start_angle\"- eller \"from\"-egenskab på elementet <%s>" -#: ../src/ui/theme.c:1067 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "Farveovergange skal mindst have to farver" +#~ msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" +#~ msgstr "Ingen \"extent_angle\"- eller \"to\"-egenskab på elementet <%s>" -#: ../src/ui/theme.c:1219 -#, c-format -msgid "" -"GTK custom color specification must have color name and fallback in " -"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" -msgstr "" -"Specifikation for tilpasset GTK-farve skal have et farvenavn og standard i " -"parentes f.eks. gtk:custom(foo,bar); kunne ikke fortolke \"%s\"" +#~ msgid "Did not understand value \"%s\" for type of gradient" +#~ msgstr "Forstod ikke værdien “%s” for farveovergangstypen" -#: ../src/ui/theme.c:1235 -#, c-format -msgid "" -"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" -"_ are valid" -msgstr "" -"Ugyldigt tegn \"%c\" i parameteren color_name for gtk:custom, kun A-Za-z0-9-" -"_ er gyldig" +#~ msgid "Did not understand fill type \"%s\" for <%s> element" +#~ msgstr "Forstod ikke fyldtypen \"%s\" for <%s>-elementet" -#: ../src/ui/theme.c:1249 -#, c-format -msgid "" -"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " -"fit the format" -msgstr "" -"Gtk:custom-formatet er \"gtk:custom(color_name,fallback)\", \"%s\" passer " -"ikke med formatet" +#~ msgid "Did not understand state \"%s\" for <%s> element" +#~ msgstr "Forstod ikke tilstanden \"%s\" for <%s>-elementet" -#: ../src/ui/theme.c:1294 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"GTK-farvespecifikation skal have tilstanden i firkantede klammer, f.eks. gtk:" -"fg[NORMAL] hvor NORMAL er tilstanden; kunne ikke fortolke \"%s\"" +#~ msgid "Did not understand shadow \"%s\" for <%s> element" +#~ msgstr "Forstod ikke skyggen \"%s\" for <%s>-elementet" -#: ../src/ui/theme.c:1308 -#, c-format -msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"GTK-farvespecifikation skal have en afsluttende klamme efter tilstanden, f." -"eks. gtk:fg[NORMAL] hvor NORMAL er tilstanden; kunne ikke fortolke \"%s\"" +#~ msgid "Did not understand arrow \"%s\" for <%s> element" +#~ msgstr "Forstod ikke pilen \"%s\" for <%s>-elementet" -#: ../src/ui/theme.c:1319 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "Forstod ikke tilstanden \"%s\" i farvespecifikationen" +#~ msgid "No <draw_ops> called \"%s\" has been defined" +#~ msgstr "Ingen <draw_ops> med navnet \"%s\" er blevet defineret" -#: ../src/ui/theme.c:1332 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "Forstod ikke farvekomponenten \"%s\" i farvespecifikationen" +#~ msgid "Including draw_ops \"%s\" here would create a circular reference" +#~ msgstr "Medtagelse af draw_ops “%s” ville skabe en cirkulær reference" -#: ../src/ui/theme.c:1361 -#, c-format -msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" -msgstr "" -"Blandingsformat er \"blend/bg_color/fg_color/alpha\", \"%s\" passer ikke med " -"formatet" +#~ msgid "Unknown position \"%s\" for frame piece" +#~ msgstr "Ukendt position “%s” for rammestykke" -#: ../src/ui/theme.c:1372 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "Kunne ikke fortolke alfaværdien \"%s\" i blandet farve" +#~ msgid "Frame style already has a piece at position %s" +#~ msgstr "Rammestil har allerede et stykke på position %s" -#: ../src/ui/theme.c:1382 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "Alfaværdien \"%s\" i blandet farve er ikke mellem 0,0 og 1,0" +#~ msgid "No <draw_ops> with the name \"%s\" has been defined" +#~ msgstr "Ingen <draw_ops> med navnet \"%s\" er blevet defineret" -#: ../src/ui/theme.c:1429 -#, c-format -msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "" -"Skyggeformat er \"shade/base_color/factor\", \"%s\" passer ikke med formatet" +#~ msgid "Unknown function \"%s\" for button" +#~ msgstr "Ukendt funktion “%s” for knap" -#: ../src/ui/theme.c:1440 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "Kunne ikke fortolke skyggeværdien \"%s\" i skygget farve" +#~ msgid "Button function \"%s\" does not exist in this version (%d, need %d)" +#~ msgstr "Knapfunktionen “%s” findes ikke i denne version (%d, kræver %d)" -#: ../src/ui/theme.c:1450 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "Skyggefaktoren \"%s\" i skygget farve er negativ" +#~ msgid "Unknown state \"%s\" for button" +#~ msgstr "Ukendt tilstand “%s” for knap" -#: ../src/ui/theme.c:1479 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Kunne ikke fortolke farven \"%s\"" +#~ msgid "Frame style already has a button for function %s state %s" +#~ msgstr "Rammestil har allerede en knap for funktion %s tilstand %s" -#: ../src/ui/theme.c:1790 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "Koordinatudtryk indeholder tegnet \"%s\" som ikke er tilladt" +#~ msgid "\"%s\" is not a valid value for focus attribute" +#~ msgstr "“%s” er ikke en gyldig værdi for fokusegenskaben" -#: ../src/ui/theme.c:1817 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "Koordinatudtryk indeholder kommatallet \"%s\" som ikke kunne tolkes" +#~ msgid "\"%s\" is not a valid value for state attribute" +#~ msgstr "“%s” er ikke en gyldig værdi for tilstandsegenskaben" -#: ../src/ui/theme.c:1831 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "Koordinatudtryk indeholder heltallet \"%s\" som ikke kunne tolkes" +#~ msgid "A style called \"%s\" has not been defined" +#~ msgstr "En stil ved navn “%s” er ikke blevet defineret" -#: ../src/ui/theme.c:1953 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "" -"Koordinatudtryk indeholdt en ukendt operator i begyndelsen af teksten: \"%s\"" +#~ msgid "\"%s\" is not a valid value for resize attribute" +#~ msgstr "“%s” er ikke en gyldig værdi for størrelsesændringsegenskaben" -#: ../src/ui/theme.c:2010 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "Koordinatudtrykket var tomt eller blev ikke forstået" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized/shaded " +#~ "states" +#~ msgstr "" +#~ "Skal ikke have en \"resize\"-egenskab i <%s>-elementet for maksimerede/" +#~ "oprullede tilstande" -#: ../src/ui/theme.c:2121 ../src/ui/theme.c:2131 ../src/ui/theme.c:2165 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "Koordinatudtrykket resulterer i division med nul" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized states" +#~ msgstr "" +#~ "Skal ikke have en \"resize\"-egenskab i <%s>-elementet for maksimerede " +#~ "tilstande" -#: ../src/ui/theme.c:2173 -#, c-format -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "Koordinatudtrykket prøver at bruge modulo-operator på et kommatal" +#~ msgid "Style has already been specified for state %s resize %s focus %s" +#~ msgstr "" +#~ "Stilen er allerede blevet angivet for tilstand %s størrelsesændring %s " +#~ "fokus %s" -#: ../src/ui/theme.c:2229 -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "Koordinatudtrykket har en operator \"%s\" hvor en operand var ventet" +#~ msgid "Style has already been specified for state %s focus %s" +#~ msgstr "Stilen er allerede blevet angivet for tilstand %s fokus %s" -#: ../src/ui/theme.c:2238 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "Koordinatudtrykket havde en operand hvor en operator var ventet" +#~ msgid "" +#~ "Can't have a two draw_ops for a <piece> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Kan ikke have to draw_ops for et <piece>-element (tema angav en draw_ops " +#~ "egenskab og også et <draw_ops>-element, eller angav to elementer)" -#: ../src/ui/theme.c:2246 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "Koordinatudtrykket sluttede med en operator i stedet for en operand" +#~ msgid "" +#~ "Can't have a two draw_ops for a <button> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Kan ikke have to draw_ops for et <button>-element (tema angav en draw_ops " +#~ "egenskab og også et <draw_ops>-element, eller angav to elementer)" -#: ../src/ui/theme.c:2256 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" -"Koordinatudtrykket har en operator \"%c\" efter en operator \"%c\" og ingen " -"operand mellem dem" +#~ msgid "" +#~ "Can't have a two draw_ops for a <menu_icon> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Kan ikke have to draw_ops for et <menu_icon>-element (tema angav en " +#~ "draw_ops egenskab og også et <draw_ops>-element, eller angav to elementer)" -#: ../src/ui/theme.c:2407 ../src/ui/theme.c:2452 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "Koordinatudtrykket havde en ukendt variabel eller konstant \"%s\"" +#~ msgid "Bad version specification '%s'" +#~ msgstr "Ugyldig versionsangivelse “%s”" -#: ../src/ui/theme.c:2506 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "Koordinatudtryksfortolkeren har fået bufferoverløb." +#~ msgid "" +#~ "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" +#~ "theme-2.xml" +#~ msgstr "" +#~ "Egenskaben “version” kan ikke bruges i metacity-theme-1.xml eller " +#~ "metacity-theme-2.xml" -#: ../src/ui/theme.c:2535 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "Koordinatudtrykket havde en slutparantes uden startparantes" +#~ msgid "" +#~ "Theme requires version %s but latest supported theme version is %d.%d" +#~ msgstr "" +#~ "Temaet kræver version %s, men sidste understøttede temaversion er %d.%d" -#: ../src/ui/theme.c:2599 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "Koordinatudtrykket havde en startparantes uden en slutparantes" +#~ msgid "Outermost element in theme must be <metacity_theme> not <%s>" +#~ msgstr "Det yderste element i temaet skal være <metacity_theme> ikke <%s>" -#: ../src/ui/theme.c:2610 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "" -"Koordinatudtrykket ser ikke ud til at have nogen operatorer eller operander" +#~ msgid "" +#~ "Element <%s> is not allowed inside a name/author/date/description element" +#~ msgstr "" +#~ "Elementet <%s> er ikke tilladt inde i et navne-/forfatter-/dato-/" +#~ "beskrivelseselement" -#: ../src/ui/theme.c:2822 ../src/ui/theme.c:2842 ../src/ui/theme.c:2862 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "Tema indeholdt et udtryk som resulterede i en fejl: %s\n" +#~ msgid "Element <%s> is not allowed inside a <constant> element" +#~ msgstr "Elementet <%s> er ikke tilladt inde i et <constant>-element" -#: ../src/ui/theme.c:4533 -#, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"et-eller-andet\"/> skal " -"angives for denne rammestil" +#~ msgid "" +#~ "Element <%s> is not allowed inside a distance/border/aspect_ratio element" +#~ msgstr "" +#~ "Elementet <%s> er ikke tilladt inde i et element af typen distance/border/" +#~ "aspect_ratio" -#: ../src/ui/theme.c:5066 ../src/ui/theme.c:5091 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" -"Manglende <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"et-eller-" -"andet\"/>" +#~ msgid "Element <%s> is not allowed inside a draw operation element" +#~ msgstr "Elementet <%s> er ikke tilladt inde i et tegneoperationselement" -#: ../src/ui/theme.c:5139 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Kunne ikke indlæse temaet \"%s\": %s\n" +#~ msgid "Element <%s> is not allowed inside a <%s> element" +#~ msgstr "Elementet <%s> er ikke tilladt inde i et <%s>-element" -#: ../src/ui/theme.c:5275 ../src/ui/theme.c:5282 ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 ../src/ui/theme.c:5303 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "Ingen <%s> angivet for temaet \"%s\"" +#~ msgid "No draw_ops provided for frame piece" +#~ msgstr "Ingen draw_ops angivet for rammestykke" -#: ../src/ui/theme.c:5311 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" -"Ingen rammestil angivet for vinduestypen \"%s\" i temaet \"%s\", tilføj et " -"<window type=\"%s\" style_set=\"et-eller-andet\"/>-element" +#~ msgid "No draw_ops provided for button" +#~ msgstr "Ingen draw_ops angivet for knap" -#: ../src/ui/theme.c:5709 ../src/ui/theme.c:5771 ../src/ui/theme.c:5834 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" -"Brugerdefinerede konstanter skal begynde med et stort bogstav; det gør \"%s" -"\" ikke" +#~ msgid "No text is allowed inside element <%s>" +#~ msgstr "Tekst er ikke tilladt inden i elementet <%s>" -#: ../src/ui/theme.c:5717 ../src/ui/theme.c:5779 ../src/ui/theme.c:5842 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "Konstanten \"%s\" er allerede defineret" +#~ msgid "<%s> specified twice for this theme" +#~ msgstr "<%s> angivet to gange for dette tema" -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. -#. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "Ingen \"%s\"-egenskab i elementet <%s>" +#~ msgid "Failed to find a valid file for theme %s\n" +#~ msgstr "Kunne ikke finde en gyldig fil til temaet %s\n" -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Linje %d tegn %d: %s" +#~ msgid "background texture could not be created from file" +#~ msgstr "baggrundstekstur kunne ikke oprettes fra fil" -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "Egenskaben \"%s\" er gentaget to gange i det samme <%s>-element" +#~ msgid "Unknown window information request: %d" +#~ msgstr "Ukendt forespørgsel efter vinduesinformation: %d" -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "Egenskaben \"%s\" er ugyldig i <%s>-elementet i denne sammenhæng" +#~ msgid "Missing %s extension required for compositing" +#~ msgstr "Manglende %s-udvidelse som kræves til komposition" -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "Kunne ikke fortolke \"%s\" som et heltal" +#~ msgid "" +#~ "Some other program is already using the key %s with modifiers %x as a " +#~ "binding\n" +#~ msgstr "" +#~ "Et andet program bruger allerede nøglen %s med modifikatorer %x som " +#~ "binding\n" -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "Forstod ikke de afsluttende tegn \"%s\" i tekststrengen \"%s\"" +#~ msgid "\"%s\" is not a valid accelerator\n" +#~ msgstr "“%s” er ikke en gyldig genvej\n" -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "Heltallet %ld skal være positivt" +#~ msgid "" +#~ "Workarounds for broken applications disabled. Some applications may not " +#~ "behave properly.\n" +#~ msgstr "" +#~ "Omgåelser for ødelagte programmer deaktiveret. Nogle programmer opfører " +#~ "sig måske ikke korrekt.\n" -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "Heltallet %ld er for stort, det nuværende maksimum er %d" +#~ msgid "Could not parse font description \"%s\" from GSettings key %s\n" +#~ msgstr "" +#~ "Kunne ikke fortolke skrifttypebeskrivelsen “%s” fra GSettings-nøglen %s\n" -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "Kunne ikke fortolke \"%s\" som et kommatal" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" +#~ msgstr "" +#~ "“%s” fundet i konfigurationsdatabasen er ikke en gyldig værdi som " +#~ "museknapsmodifikation\n" -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "Booleske værdier skal være \"true\" eller \"false\" ikke \"%s\"" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for " +#~ "keybinding \"%s\"\n" +#~ msgstr "" +#~ "“%s” fundet i konfigurationsdatabasen er ikke en gyldig værdi for " +#~ "tastebindingen “%s”\n" -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "Vinkel skal være mellem 0.0 og 360.0, var %g\n" +#~ msgid "Could not create directory '%s': %s\n" +#~ msgstr "Kunne ikke oprette mappen “%s”: %s\n" -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" -"Alfa skal være mellem 0.0 (usynlig) og 1.0 (helt ugennemsigtig), var %g\n" +#~ msgid "Could not open session file '%s' for writing: %s\n" +#~ msgstr "Kunne ikke åbne sessionsfilen “%s” til skrivning: %s\n" -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"Ugyldig titelskalering \"%s\" (skal være en af xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" +#~ msgid "Error writing session file '%s': %s\n" +#~ msgstr "Fejl under skrivning af sessionsfilen “%s”: %s\n" -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s>-navnet \"%s\" brugt to gange" +#~ msgid "Error closing session file '%s': %s\n" +#~ msgstr "Fejl under lukning af sessionsfilen “%s”: %s\n" -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "<%s>-ophavet \"%s\" er ikke blevet defineret" +#~ msgid "Failed to parse saved session file: %s\n" +#~ msgstr "Kunne ikke fortolke den lagrede sessionsfil: %s\n" -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "<%s>-geometrien \"%s\" er ikke blevet defineret" +#~ msgid "<mutter_session> attribute seen but we already have the session ID" +#~ msgstr "" +#~ "<mutter_session>-egenskaben blev fundet, men vi har allerede sessions-" +#~ "id'en" -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "<%s> skal enten angive en geometri eller et ophav der har en geometri" +#~ msgid "Unknown attribute %s on <%s> element" +#~ msgstr "Ukendt egenskab %s for <%s>-element" -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "Du skal angive en baggrund hvis en alfaværdi skal være meningsfuld" +#~ msgid "nested <window> tag" +#~ msgstr "indlejret <window>-mærke" -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Ukendt type \"%s\" i <%s>-element" +#~ msgid "Unknown element %s" +#~ msgstr "Ukendt element %s" -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "Ukendt style_set \"%s\" i <%s>-element" +#~ msgid "Failed to open debug log: %s\n" +#~ msgstr "Kunne ikke åbne fejlinformationslog: %s\n" -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "Vinduestypen \"%s\" er allerede blevet tildelt et stilsæt" - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "Elementet <%s> er ikke tilladt under <%s>" +#~ msgid "Failed to fdopen() log file %s: %s\n" +#~ msgstr "Kunne ikke udføre fdopen() på logfilen %s: %s\n" -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" -msgstr "" -"Kan ikke angive både \"button_width\"/\"button_height\" og \"aspect_ratio\" " -"for knapper" +#~ msgid "Opened log file %s\n" +#~ msgstr "Åbnede logfilen %s\n" -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "Afstanden \"%s\" er ukendt" +#~ msgid "Window manager: " +#~ msgstr "Vindueshåndtering: " -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "Formatforholdet \"%s\" er ukendt" +#~ msgid "Bug in window manager: " +#~ msgstr "Fejl i vindueshåndtering: " -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "Kanten \"%s\" er ukendt" +#~ msgid "Window manager warning: " +#~ msgstr "Vindueshåndteringsadvarsel: " -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "Ingen \"start_angle\"- eller \"from\"-egenskab på elementet <%s>" +#~ msgid "Window manager error: " +#~ msgstr "Vindueshåndteringsfejl: " -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "Ingen \"extent_angle\"- eller \"to\"-egenskab på elementet <%s>" +#~ msgid "" +#~ "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " +#~ "window as specified in the ICCCM.\n" +#~ msgstr "" +#~ "Vinduet %s angiver SM_CLIENT_ID for det selv i stedet for " +#~ "WM_CLIENT_LEADER-vinduet som specificeret i ICCCM.\n" -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "Forstod ikke værdien \"%s\" for farveovergangstypen" +#~ msgid "" +#~ "Window %s sets an MWM hint indicating it isn't resizable, but sets min " +#~ "size %d x %d and max size %d x %d; this doesn't make much sense.\n" +#~ msgstr "" +#~ "Vinduet %s angiver et MWM-hint for at indikere at dets størrelse ikke kan " +#~ "ændres, men angiver den mindste størrelse %d x %d og den maksimale " +#~ "størrelse %d x %d; dette giver ikke mening.\n" -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "Forstod ikke fyldtypen \"%s\" for <%s>-elementet" +#~ msgid "Application set a bogus _NET_WM_PID %lu\n" +#~ msgstr "Program angav en ugyldig _NET_WM_PID %lu\n" -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "Forstod ikke tilstanden \"%s\" for <%s>-elementet" +#~ msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +#~ msgstr "Ugyldig WM_TRANSIENT_FOR vindue 0x%lx specificeret for %s.\n" -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "Forstod ikke skyggen \"%s\" for <%s>-elementet" +#~ msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" +#~ msgstr "WM_TRANSIENT_FOR vindue 0x%lx for %s vil oprette løkke.\n" -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "Forstod ikke pilen \"%s\" for <%s>-elementet" +#~ msgid "" +#~ "Window 0x%lx has property %s\n" +#~ "that was expected to have type %s format %d\n" +#~ "and actually has type %s format %d n_items %d.\n" +#~ "This is most likely an application bug, not a window manager bug.\n" +#~ "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +#~ msgstr "" +#~ "Vinduet 0x%lx har egenskaben %s\n" +#~ "som forventedes at have typen %s format %d\n" +#~ "og faktisk har typen %s format %d n_items %d.\n" +#~ "Dette er sandsynligvis en fejl i programmet og ikke i " +#~ "vindueshåndteringen.\n" +#~ "Vinduet har titlen “%s”, klassen “%s” og navnet “%s”\n" -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "Ingen <draw_ops> med navnet \"%s\" er blevet defineret" +#~ msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +#~ msgstr "Egenskaben %s for vinduet 0x%lx indeholdt ugyldig UTF-8\n" -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "Medtagelse af draw_ops \"%s\" ville skabe en cirkulær reference" +#~ msgid "" +#~ "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the " +#~ "list\n" +#~ msgstr "" +#~ "Egenskaben %s for vinduet 0x%lx indeholdt ugyldig UTF-8 for element %d i " +#~ "listen\n" -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Ukendt position \"%s\" for rammestykke" +#~ msgid "Mi_nimize" +#~ msgstr "Mi_nimér" -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "Rammestil har allerede et stykke på position %s" +#~ msgid "Ma_ximize" +#~ msgstr "Ma_ksimér" -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "Ingen <draw_ops> med navnet \"%s\" er blevet defineret" +#~ msgid "Unma_ximize" +#~ msgstr "_Gendan" -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Ukendt funktion \"%s\" for knap" +#~ msgid "Roll _Up" +#~ msgstr "Rul _op" -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "Knapfunktionen \"%s\" findes ikke i denne version (%d, kræver %d)" +#~ msgid "_Unroll" +#~ msgstr "Rul _ned" -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Ukendt tilstand \"%s\" for knap" +#~ msgid "_Move" +#~ msgstr "_Flyt" -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "Rammestil har allerede en knap for funktion %s tilstand %s" +#~ msgid "_Resize" +#~ msgstr "Ænd_re størrelse" -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "\"%s\" er ikke en gyldig værdi for fokusegenskaben" +#~ msgid "Move Titlebar On_screen" +#~ msgstr "Flyt titellinje til _skærm" -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "\"%s\" er ikke en gyldig værdi for tilstandsegenskaben" +#~ msgid "Always on _Top" +#~ msgstr "Altid _øverst" -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "En stil ved navn \"%s\" er ikke blevet defineret" +#~ msgid "_Always on Visible Workspace" +#~ msgstr "_Altid på synligt arbejdsområde" -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "\"%s\" er ikke en gyldig værdi for størrelsesændringsegenskaben" +#~ msgid "_Only on This Workspace" +#~ msgstr "_Kun på dette arbejdsområde" -#: ../src/ui/theme-parser.c:3147 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" -"Skal ikke have en \"resize\"-egenskab i <%s>-elementet for maksimerede/" -"oprullede tilstande" +#~ msgid "Move to Workspace _Left" +#~ msgstr "Flyt til arbejdsområde til _venstre" -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "" -"Skal ikke have en \"resize\"-egenskab i <%s>-elementet for maksimerede " -"tilstande" +#~ msgid "Move to Workspace R_ight" +#~ msgstr "Flyt til arbejdsområde til _højre" -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "" -"Stilen er allerede blevet angivet for tilstand %s størrelsesændring %s fokus " -"%s" +#~ msgid "Move to Workspace _Up" +#~ msgstr "Flyt til arbejdsområde _op" -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "Stilen er allerede blevet angivet for tilstand %s fokus %s" +#~ msgid "Move to Workspace _Down" +#~ msgstr "Flyt til arbejdsområde _ned" -#: ../src/ui/theme-parser.c:3294 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Kan ikke have to draw_ops for et <piece>-element (tema angav en draw_ops " -"egenskab og også et <draw_ops>-element, eller angav to elementer)" +#~ msgid "_Close" +#~ msgstr "_Luk" -#: ../src/ui/theme-parser.c:3332 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Kan ikke have to draw_ops for et <button>-element (tema angav en draw_ops " -"egenskab og også et <draw_ops>-element, eller angav to elementer)" +#~ msgid "Workspace %d%n" +#~ msgstr "Arbejdsområde %d%n" -#: ../src/ui/theme-parser.c:3370 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Kan ikke have to draw_ops for et <menu_icon>-element (tema angav en draw_ops " -"egenskab og også et <draw_ops>-element, eller angav to elementer)" +#~ msgid "Workspace 1_0" +#~ msgstr "Arbejdsområde 1_0" -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "Ugyldig versionsangivelse \"%s\"" +#~ msgid "Workspace %s%d" +#~ msgstr "Arbejdsområde %s%d" -#: ../src/ui/theme-parser.c:3507 -msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" -msgstr "" -"Egenskaben \"version\" kan ikke bruges i metacity-theme-1.xml eller metacity-" -"theme-2.xml" +#~ msgid "Move to Another _Workspace" +#~ msgstr "Flyt til andet _arbejdsområde" -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "" -"Temaet kræver version %s, men sidste understøttede temaversion er %d.%d" +#~ msgid "Shift" +#~ msgstr "Skift" -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "Det yderste element i temaet skal være <metacity_theme> ikke <%s>" +#~ msgid "Ctrl" +#~ msgstr "Ctrl" -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "" -"Elementet <%s> er ikke tilladt inde i et navne-/forfatter-/dato-/" -"beskrivelseselement" +#~ msgid "Alt" +#~ msgstr "Alt" -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "Elementet <%s> er ikke tilladt inde i et <constant>-element" +#~ msgid "Meta" +#~ msgstr "Meta" -#: ../src/ui/theme-parser.c:3599 -#, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "" -"Elementet <%s> er ikke tilladt inde i et element af typen distance/border/" -"aspect_ratio" +#~ msgid "Super" +#~ msgstr "Super" -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "Elementet <%s> er ikke tilladt inde i et tegneoperationselement" +#~ msgid "Hyper" +#~ msgstr "Hyper" -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "Elementet <%s> er ikke tilladt inde i et <%s>-element" +#~ msgid "Mod2" +#~ msgstr "Mod2" -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "Ingen draw_ops angivet for rammestykke" +#~ msgid "Mod3" +#~ msgstr "Mod3" -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "Ingen draw_ops angivet for knap" +#~ msgid "Mod4" +#~ msgstr "Mod4" -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "Tekst er ikke tilladt inden i elementet <%s>" +#~ msgid "Mod5" +#~ msgstr "Mod5" -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "<%s> angivet to gange for dette tema" +#~ msgid "Usage: %s\n" +#~ msgstr "Brug: %s\n" -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Kunne ikke finde en gyldig fil til temaet %s\n" +#~ msgid "_Windows" +#~ msgstr "_Vinduer" -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "_Vinduer" +#~ msgid "_Dialog" +#~ msgstr "_Dialog" -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "_Dialog" +#~ msgid "_Utility" +#~ msgstr "_Værktøj" -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "_Modaldialogvindue" +#~ msgid "_Splashscreen" +#~ msgstr "_Velkomstskærm" -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "_Værktøj" +#~ msgid "_Top dock" +#~ msgstr "_Topdok" -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "_Velkomstskærm" +#~ msgid "_Bottom dock" +#~ msgstr "_Bunddok" -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "_Topdok" +#~ msgid "_Left dock" +#~ msgstr "_Venstre dok" -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "_Bunddok" +#~ msgid "_Right dock" +#~ msgstr "_Højre dok" -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "_Venstre dok" +#~ msgid "_All docks" +#~ msgstr "_Alle dokke" -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "_Højre dok" +#~ msgid "Des_ktop" +#~ msgstr "Skrive_bord" -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "_Alle dokke" +#~ msgid "Open another one of these windows" +#~ msgstr "Åbn endnu et af disse vinduer" -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "Skrive_bord" +#~ msgid "This is a demo button with an 'open' icon" +#~ msgstr "Dette er en demoknap med et “åbn”-ikon" -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "Åbn endnu et af disse vinduer" +#~ msgid "This is a demo button with a 'quit' icon" +#~ msgstr "Dette er en demoknap med et “afslut”-ikon" -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "Dette er en demoknap med et \"åbn\"-ikon" +#~ msgid "This is a sample message in a sample dialog" +#~ msgstr "Dette er en eksempelbesked i et eksempelmeddelelsevindue" -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "Dette er en demoknap med et \"afslut\"-ikon" +#~ msgid "Fake menu item %d\n" +#~ msgstr "Uægte menupunkt %d\n" -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "Dette er en eksempelbesked i et eksempelmeddelelsevindue" +#~ msgid "Border-only window" +#~ msgstr "Vindue med kun ramme" -#: ../src/ui/theme-viewer.c:328 -#, c-format -msgid "Fake menu item %d\n" -msgstr "Uægte menupunkt %d\n" +#~ msgid "Bar" +#~ msgstr "Linje" -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "Vindue med kun ramme" +#~ msgid "Normal Application Window" +#~ msgstr "Almindeligt programvindue" -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "Linje" +#~ msgid "Dialog Box" +#~ msgstr "Meddelelsevindue" -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "Almindeligt programvindue" +#~ msgid "Modal Dialog Box" +#~ msgstr "Modalt meddelelsevindue" -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "Meddelelsevindue" +#~ msgid "Utility Palette" +#~ msgstr "Værktøjspalet" -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "Modalt meddelelsevindue" +#~ msgid "Torn-off Menu" +#~ msgstr "Afrevet menu" -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "Værktøjspalet" +#~ msgid "Border" +#~ msgstr "Ramme" -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "Afrevet menu" +#~ msgid "Button layout test %d" +#~ msgstr "Knaplayouttest %d" -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "Ramme" +#~ msgid "%g milliseconds to draw one window frame" +#~ msgstr "%g millisekunder for at tegne én vinduesramme" -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "Fastgjort modaldialogvindue" +#~ msgid "Usage: metacity-theme-viewer [THEMENAME]\n" +#~ msgstr "Brug: metacity-theme-viewer [TEMANAVN]\n" -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "Knaplayouttest %d" +#~ msgid "Error loading theme: %s\n" +#~ msgstr "Fejl under indlæsning af tema: %s\n" -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g millisekunder for at tegne én vinduesramme" +#~ msgid "Loaded theme \"%s\" in %g seconds\n" +#~ msgstr "Indlæste tema “%s” på %g sekunder\n" -#: ../src/ui/theme-viewer.c:813 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Brug: metacity-theme-viewer [TEMANAVN]\n" +#~ msgid "Normal Title Font" +#~ msgstr "Normal titelskrifttype" -#: ../src/ui/theme-viewer.c:820 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "Fejl under indlæsning af tema: %s\n" +#~ msgid "Small Title Font" +#~ msgstr "Lille titelskrifttype" -#: ../src/ui/theme-viewer.c:826 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "Indlæste tema \"%s\" på %g sekunder\n" +#~ msgid "Large Title Font" +#~ msgstr "Stor titelskrifttype" -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "Normal titelskrifttype" +#~ msgid "Button Layouts" +#~ msgstr "Knaplayout" -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "Lille titelskrifttype" +#~ msgid "Benchmark" +#~ msgstr "Tidstest" -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "Stor titelskrifttype" +#~ msgid "Window Title Goes Here" +#~ msgstr "Vinduestitel er her" -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "Knaplayout" +#~ msgid "" +#~ "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and " +#~ "%g seconds wall clock time including X server resources (%g milliseconds " +#~ "per frame)\n" +#~ msgstr "" +#~ "Tegnede %d rammer på %g klientsekunder (%g millisekunder pr. ramme) og %g " +#~ "sekunders almindelig tid inkl. X-server-resurser (%g millisekunder pr. " +#~ "ramme)\n" -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "Tidstest" +#~ msgid "position expression test returned TRUE but set error" +#~ msgstr "positionsudtrykstest returnede TRUE, men sat fejl" -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "Vinduestitel er her" +#~ msgid "position expression test returned FALSE but didn't set error" +#~ msgstr "positionsudtrykstest returnede FALSE, men satte ikke fejl" -#: ../src/ui/theme-viewer.c:1047 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"Tegnede %d rammer på %g klientsekunder (%g millisekunder pr. ramme) og %g " -"sekunders almindelig tid inkl. X-server-resurser (%g millisekunder pr. " -"ramme)\n" +#~ msgid "Error was expected but none given" +#~ msgstr "Fejl var forventet, men ingen givet" -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "positionsudtrykstest returnede TRUE, men sat fejl" +#~ msgid "Error %d was expected but %d given" +#~ msgstr "Fejl %d var forventet, men %d givet" -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "positionsudtrykstest returnede FALSE, men satte ikke fejl" +#~ msgid "Error not expected but one was returned: %s" +#~ msgstr "Fejl var ikke forventet, men én blev returneret: %s" -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "Fejl var forventet, men ingen givet" +#~ msgid "x value was %d, %d was expected" +#~ msgstr "x-værdi var %d, %d var forventet" -#: ../src/ui/theme-viewer.c:1274 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "Fejl %d var forventet, men %d givet" +#~ msgid "y value was %d, %d was expected" +#~ msgstr "y-værdi var %d, %d var forventet" -#: ../src/ui/theme-viewer.c:1280 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "Fejl var ikke forventet, men én blev returneret: %s" +#~ msgid "" +#~ "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" +#~ msgstr "" +#~ "%d koordinatudtryk fortolket på %g sekunder (%g sekunder i gennemsnit)\n" -#: ../src/ui/theme-viewer.c:1284 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "x-værdi var %d, %d var forventet" +#~ msgid "Comma-separated list of compositor plugins" +#~ msgstr "Kommaadskilt liste af komposit-udvidelsesmoduler" -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "y-værdi var %d, %d var forventet" +#~ msgid "" +#~ "Determines whether hidden windows (i.e., minimized windows and windows on " +#~ "other workspaces than the current one) should be kept alive." +#~ msgstr "" +#~ "Angiver om skjulte vinduer (f.eks. minimerede vinduer og vinduer på andre " +#~ "arbejdsområder end det nuværende) holdes i live." -#: ../src/ui/theme-viewer.c:1352 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "" -"%d koordinatudtryk fortolket på %g sekunder (%g sekunder i gennemsnit)\n" +#~ msgid "Live Hidden Windows" +#~ msgstr "Levende skjulte vinduer" #~ msgid "Close Window" #~ msgstr "Luk vindue" @@ -1624,27 +1675,6 @@ msgstr "" #~ msgid "Put Window On Only One Workspace" #~ msgstr "Vis vindue på kun ét arbejdsområde" -#~ msgid "Switch to workspace 1" -#~ msgstr "Skift til arbejdsområde 1" - -#~ msgid "Switch to workspace 2" -#~ msgstr "Skift til arbejdsområde 2" - -#~ msgid "Switch to workspace 3" -#~ msgstr "Skift til arbejdsområde 3" - -#~ msgid "Switch to workspace 4" -#~ msgstr "Skift til arbejdsområde 4" - -#~ msgid "Switch to workspace 5" -#~ msgstr "Skift til arbejdsområde 5" - -#~ msgid "Switch to workspace 6" -#~ msgstr "Skift til arbejdsområde 6" - -#~ msgid "Switch to workspace 7" -#~ msgstr "Skift til arbejdsområde 7" - #~ msgid "Switch to workspace 8" #~ msgstr "Skift til arbejdsområde 8" @@ -1716,7 +1746,7 @@ msgstr "" #~ msgstr "Vis panelets hovedmenu" #~ msgid "Show the panel's \"Run Application\" dialog box" -#~ msgstr "Vis panelets \"Kør program\"-vindue" +#~ msgstr "Vis panelets “Kør program”-vindue" #~ msgid "Start or stop recording the session" #~ msgstr "Start eller stop optagelse af sessionen" @@ -1730,58 +1760,16 @@ msgstr "" #~ msgid "Run a terminal" #~ msgstr "Start en terminal" -#~ msgid "Activate the window menu" -#~ msgstr "Aktivér vinduesmenuen" - -#~ msgid "Toggle fullscreen mode" -#~ msgstr "Skift fuldskærmstilstand" - -#~ msgid "Toggle maximization state" -#~ msgstr "Skift maksimeringstilstand" - # Nogen bedre forslag? #~ msgid "Toggle whether a window will always be visible over other windows" #~ msgstr "" #~ "Slå til eller fra hvorvidt et vindue altid vil være synligt over andre " #~ "vinduer" -#~ msgid "Maximize window" -#~ msgstr "Maksimér vindue" - -#~ msgid "Restore window" -#~ msgstr "Gendan vindue" - -#~ msgid "Toggle shaded state" -#~ msgstr "Skift oprullethed" - -#~ msgid "Minimize window" -#~ msgstr "Minimér vindue" - -#~ msgid "Close window" -#~ msgstr "Luk vindue" - -#~ msgid "Move window" -#~ msgstr "Flyt vindue" - -#~ msgid "Resize window" -#~ msgstr "Ændre størrelsen på vindue" - #~ msgid "Toggle whether window is on all workspaces or just one" #~ msgstr "" #~ "Skift mellem hvorvidt vinduet vises på alle arbejdsområder eller kun et" -#~ msgid "Move window to workspace 1" -#~ msgstr "Flyt vindue til arbejdsområde 1" - -#~ msgid "Move window to workspace 2" -#~ msgstr "Flyt vindue til arbejdsområde 2" - -#~ msgid "Move window to workspace 3" -#~ msgstr "Flyt vindue til arbejdsområde 3" - -#~ msgid "Move window to workspace 4" -#~ msgstr "Flyt vindue til arbejdsområde 4" - #~ msgid "Move window to workspace 5" #~ msgstr "Flyt vindue til arbejdsområde 5" @@ -1806,33 +1794,9 @@ msgstr "" #~ msgid "Move window to workspace 12" #~ msgstr "Flyt vindue til arbejdsområde 12" -#~ msgid "Move window one workspace to the left" -#~ msgstr "Flyt vindue et arbejdsområde til venstre" - -#~ msgid "Move window one workspace to the right" -#~ msgstr "Flyt vindue et arbejdsområde til højre" - -#~ msgid "Move window one workspace up" -#~ msgstr "Flyt vindue et arbejdsområde op" - -#~ msgid "Move window one workspace down" -#~ msgstr "Flyt vindue et arbejdsområde ned" - #~ msgid "Raise window if it's covered by another window, otherwise lower it" #~ msgstr "Hæv vindue hvis det er dækket af et andet vindue, ellers sænk det" -#~ msgid "Raise window above other windows" -#~ msgstr "Hæv vindue over andre vinduer" - -#~ msgid "Lower window below other windows" -#~ msgstr "Sænk vindue under andre vinduer" - -#~ msgid "Maximize window vertically" -#~ msgstr "Maksimér et vindue lodret" - -#~ msgid "Maximize window horizontally" -#~ msgstr "Maksimér et vindue vandret" - #~ msgid "Move window to north-west (top left) corner" #~ msgstr "Flyt vindue til det nordvestlige (øverste venstre) hjørne" @@ -1876,13 +1840,13 @@ msgstr "" #~ msgstr "Ingen terminal-kommando er blevet defineret.\n" #~ msgid "GConf key '%s' is set to an invalid value\n" -#~ msgstr "GConf-nøglen \"%s\" er sat til en ugyldig værdi\n" +#~ msgstr "GConf-nøglen “%s” er sat til en ugyldig værdi\n" #~ msgid "%d stored in GConf key %s is out of range %d to %d\n" #~ msgstr "%d lagret i GConf-nøgle %s er uden for intervallet %d til %d\n" #~ msgid "GConf key \"%s\" is set to an invalid type\n" -#~ msgstr "GConf-nøglen \"%s\" er sat til en ugyldig type\n" +#~ msgstr "GConf-nøglen “%s” er sat til en ugyldig type\n" #~ msgid "GConf key %s is already in use and can't be used to override %s\n" #~ msgstr "" @@ -1896,11 +1860,11 @@ msgstr "" #~ msgstr "Fejl under sætning af antallet af arbejdsområder til %d: %s\n" #~ msgid "Error setting name for workspace %d to \"%s\": %s\n" -#~ msgstr "Fejl under sætning af navnet for arbejdsområde %d til \"%s\": %s\n" +#~ msgstr "Fejl under sætning af navnet for arbejdsområde %d til “%s”: %s\n" #~ msgid "Error setting live hidden windows status status: %s\n" #~ msgstr "Fejl ved indstilling af status for skjulte levende vinduer: %s\n" # (hvad taler de om?) #~ msgid "Error setting no tab popup status: %s\n" -#~ msgstr "Fejl ved indstilling af \"intet faneblad\"-popup-status: %s\n" +#~ msgstr "Fejl ved indstilling af “intet faneblad”-popup-status: %s\n" diff --git a/po/de.po b/po/de.po index c3a69896e..d2424c0e5 100644 --- a/po/de.po +++ b/po/de.po @@ -1,2015 +1,797 @@ -# German Muffin translation. +# German Mutter translation. # Copyright (C) 2002-2004 Free Software Foundation, Inc. # Matthias Warkus <mawarkus@gnome.org>, 2002. # Christian Neumair <chris@gnome-de.org>, 2002-2004. -# Hendrik Richter <hendrikr@gnome.org>, 2005, 2006, 2007, 2008. -# Mario Blättermann <mariobl@freenet.de>, 2010, 2011. -# Christian Kirbach <Christian.Kirbach@googlemail.com>, 2009, 2011. -# Wolfgang Stöggl <c72578@yahoo.de> 2011. +# Hendrik Richter <hendrikr@gnome.org>, 2005-2008. +# Mario Blättermann <mario.blaettermann@gmail.com>, 2010-2013, 2016-2018. +# Christian Kirbach <Christian.Kirbach@googlemail.com>, 2009, 2011-2012. +# Wolfgang Stöggl <c72578@yahoo.de> 2011, 2017. +# Tobias Endrigkeit <tobiasendrigkeit@googlemail.com>, 2012. +# Tim Sabsch <timæsabsch.com>, 2018-2019. # msgid "" msgstr "" -"Project-Id-Version: muffin master\n" -"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" -"product=muffin&keywords=I18N+L10N&component=general\n" -"POT-Creation-Date: 2011-09-23 23:22+0000\n" -"PO-Revision-Date: 2011-09-24 09:20+0200\n" -"Last-Translator: Mario Blättermann <mariobl@freenet.de>\n" +"Project-Id-Version: mutter master\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2020-03-30 20:11+0000\n" +"PO-Revision-Date: 2020-04-06 23:13+0200\n" +"Last-Translator: Christian Kirbach <christian.kirbach@gmail.com>\n" "Language-Team: Deutsch <gnome-de@gnome.org>\n" +"Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Language: de\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 2.3\n" -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format -msgid "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." -msgstr "" -"Ein weiterer Compositing-Verwalter läuft bereits auf Bildschirm %i der " -"Anzeige »%s«." +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Navigation" -#: ../src/core/all-keybindings.h:88 -msgid "Switch to workspace 1" -msgstr "Zur Arbeitsfläche 1 wechseln" +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Fenster auf Arbeitsfläche 1 verschieben" -#: ../src/core/all-keybindings.h:90 -msgid "Switch to workspace 2" -msgstr "Zur Arbeitsfläche 2 wechseln" +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Fenster auf Arbeitsfläche 2 verschieben" -#: ../src/core/all-keybindings.h:92 -msgid "Switch to workspace 3" -msgstr "Zur Arbeitsfläche 3 wechseln" +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Fenster auf Arbeitsfläche 3 verschieben" -#: ../src/core/all-keybindings.h:94 -msgid "Switch to workspace 4" -msgstr "Zur Arbeitsfläche 4 wechseln" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Fenster auf Arbeitsfläche 4 verschieben" -#: ../src/core/all-keybindings.h:96 -msgid "Switch to workspace 5" -msgstr "Zur Arbeitsfläche 5 wechseln" +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Fenster auf letzte Arbeitsfläche verschieben" -#: ../src/core/all-keybindings.h:98 -msgid "Switch to workspace 6" -msgstr "Zur Arbeitsfläche 6 wechseln" +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "Fenster eine Arbeitsfläche nach oben verschieben" -#: ../src/core/all-keybindings.h:100 -msgid "Switch to workspace 7" -msgstr "Zur Arbeitsfläche 7 wechseln" +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "Fenster eine Arbeitsfläche nach unten verschieben" -#: ../src/core/all-keybindings.h:102 -msgid "Switch to workspace 8" -msgstr "Zur Arbeitsfläche 8 wechseln" +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "Fenster einen Bildschirm nach links verschieben" -#: ../src/core/all-keybindings.h:104 -msgid "Switch to workspace 9" -msgstr "Zur Arbeitsfläche 9 wechseln" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "Fenster einen Bildschirm nach rechts verschieben" -#: ../src/core/all-keybindings.h:106 -msgid "Switch to workspace 10" -msgstr "Zur Arbeitsfläche 10 wechseln" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "Fenster einen Bildschirm nach oben verschieben" -#: ../src/core/all-keybindings.h:108 -msgid "Switch to workspace 11" -msgstr "Zur Arbeitsfläche 11 wechseln" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "Fenster einen Bildschirm nach unten verschieben" -#: ../src/core/all-keybindings.h:110 -msgid "Switch to workspace 12" -msgstr "Zur Arbeitsfläche 12 wechseln" +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "Anwendungen wechseln" -#: ../src/core/all-keybindings.h:122 -msgid "Switch to workspace on the left of the current workspace" -msgstr "Zur Arbeitsfläche links der aktuellen wechseln" +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "Zur vorherigen Anwendung wechseln" -#: ../src/core/all-keybindings.h:126 -msgid "Switch to workspace on the right of the current workspace" -msgstr "Zur Arbeitsfläche rechts der aktuellen wechseln" +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "Fenster wechseln" -#: ../src/core/all-keybindings.h:130 -msgid "Switch to workspace above the current workspace" -msgstr "Zur Arbeitsfläche oberhalb der aktuellen wechseln" +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "Zum vorherigen Fenster wechseln" -#: ../src/core/all-keybindings.h:134 -msgid "Switch to workspace below the current workspace" -msgstr "Zur Arbeitsfläche unterhalb der aktuellen wechseln" +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "Zwischen den Fenstern einer Anwendung wechseln" -#: ../src/core/all-keybindings.h:150 -msgid "Move between windows of an application, using a popup window" -msgstr "" -"Zwischen den Fenstern einer Anwendung mittels einer Fensterliste wechseln" +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "Zum vorherigen Fenster einer Anwendung wechseln" -#: ../src/core/all-keybindings.h:153 -msgid "Move backward between windows of an application, using a popup window" -msgstr "" -"Zwischen den Fenstern einer Anwendung mittels einer Fensterliste in " -"umgekehrter Reihenfolge wechseln" +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "Systemsteuerungen umschalten" -#: ../src/core/all-keybindings.h:157 -msgid "Move between windows, using a popup window" -msgstr "Zwischen den Fenstern mittels einer Fensterliste wechseln" +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "Zur vorherigen Systemsteuerungen wechseln" -#: ../src/core/all-keybindings.h:160 -msgid "Move backward between windows, using a popup window" -msgstr "" -"Zwischen den Fenstern mittels einer Fensterliste in umgekehrter Reihenfolge " -"wechseln" +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "Fenster sofort wechseln" -#: ../src/core/all-keybindings.h:163 -msgid "Move between panels and the desktop, using a popup window" -msgstr "" -"Zwischen Panels und der Arbeitsfläche mittels einer Fensterliste wechseln" +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "Direkt zum vorherigen Fenster wechseln" -#: ../src/core/all-keybindings.h:166 -msgid "Move backward between panels and the desktop, using a popup window" -msgstr "" -"Zwischen Panels und der Arbeitsfläche in umgekehrter Reihenfolge mittels " -"einer Fensterliste wechseln" +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "Sofort zwischen den Fenstern einer Anwendung wechseln" -#: ../src/core/all-keybindings.h:171 -msgid "Move between windows of an application immediately" -msgstr "Zwischen den Fenstern einer Anwendung sofort wechseln" +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "Direkt zum vorherigen Fenster einer Anwendung wechseln" -#: ../src/core/all-keybindings.h:174 -msgid "Move backward between windows of an application immediately" -msgstr "" -"Zwischen den Fenstern einer Anwendung in umgekehrter Reihenfolge sofort " -"wechseln" +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "Systemsteuerungen sofort umschalten" -#: ../src/core/all-keybindings.h:177 -msgid "Move between windows immediately" -msgstr "Zwischen Fenstern sofort wechseln" +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "Direkt zur vorherigen Systemsteuerungen wechseln" -#: ../src/core/all-keybindings.h:180 -msgid "Move backward between windows immediately" -msgstr "Zwischen Fenstern in umgekehrter Reihenfolge sofort wechseln" +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "Alle normalen Fenster verbergen" -#: ../src/core/all-keybindings.h:183 -msgid "Move between panels and the desktop immediately" -msgstr "Zwischen Panels und der Arbeitsfläche sofort wechseln" +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "Zur Arbeitsfläche 1 wechseln" -#: ../src/core/all-keybindings.h:186 -msgid "Move backward between panels and the desktop immediately" -msgstr "" -"Zwischen Panels und der Arbeitsfläche in umgekehrter Reihenfolge sofort " -"wechseln" +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "Zur Arbeitsfläche 2 wechseln" -#: ../src/core/all-keybindings.h:203 -msgid "Hide all normal windows and set focus to the desktop" -msgstr "Alle normalen Fenster verbergen und die Arbeitsfläche fokussieren" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "Zur Arbeitsfläche 3 wechseln" + +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "Zur Arbeitsfläche 4 wechseln" + +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "Zur letzten Arbeitsfläche wechseln" -#: ../src/core/all-keybindings.h:206 -msgid "Show the panel's main menu" -msgstr "Das Hauptmenü des Panels anzeigen" +# Wechsel der Arbeitsfläche. Es wird nichts verschoben. +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "Zur Arbeitsfläche darüber wechseln" -#: ../src/core/all-keybindings.h:209 -msgid "Show the panel's \"Run Application\" dialog box" -msgstr "Das Dialogfenster »Anwendung ausführen« des Panels anzeigen" +# Wechsel der Arbeitsfläche. Es wird nichts verschoben. +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "Zur Arbeitsfläche darunter wechseln" -#: ../src/core/all-keybindings.h:211 -msgid "Start or stop recording the session" -msgstr "Die Sitzungsaufzeichnung starten oder beenden" +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "System" -#: ../src/core/all-keybindings.h:252 -msgid "Take a screenshot" -msgstr "Ein Bildschirmfoto aufnehmen" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Den »Befehl ausführen«-Dialog anzeigen" -#: ../src/core/all-keybindings.h:254 -msgid "Take a screenshot of a window" -msgstr "Ein Bildschirmfoto eines Fensters aufnehmen" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Aktivitäten-Übersicht anzeigen" -#: ../src/core/all-keybindings.h:256 -msgid "Run a terminal" -msgstr "Ein Terminal starten" +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Die Tastenkombinationen wiederherstellen" -#: ../src/core/all-keybindings.h:271 +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Fenster" + +#: data/50-mutter-windows.xml:8 msgid "Activate the window menu" msgstr "Das Fenstermenü aktivieren" -#: ../src/core/all-keybindings.h:274 +#: data/50-mutter-windows.xml:10 msgid "Toggle fullscreen mode" msgstr "Vollbildmodus ein-/ausschalten" -#: ../src/core/all-keybindings.h:276 +#: data/50-mutter-windows.xml:12 msgid "Toggle maximization state" msgstr "Maximierungszustand ein-/ausschalten" -#: ../src/core/all-keybindings.h:278 -msgid "Toggle whether a window will always be visible over other windows" -msgstr "Fenster ständig im Vordergrund ein-/ausschalten" - -#: ../src/core/all-keybindings.h:280 +#: data/50-mutter-windows.xml:14 msgid "Maximize window" msgstr "Fenster maximieren" -#: ../src/core/all-keybindings.h:282 +#: data/50-mutter-windows.xml:16 msgid "Restore window" msgstr "Fenstergröße wiederherstellen" -#: ../src/core/all-keybindings.h:284 -msgid "Toggle shaded state" -msgstr "Fenster ein-/ausrollen" - -#: ../src/core/all-keybindings.h:286 -msgid "Minimize window" -msgstr "Fenster minimieren" - -#: ../src/core/all-keybindings.h:288 +#: data/50-mutter-windows.xml:18 msgid "Close window" msgstr "Fenster schließen" -#: ../src/core/all-keybindings.h:290 +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "Fenster verbergen" + +#: data/50-mutter-windows.xml:22 msgid "Move window" msgstr "Fenster verschieben" -#: ../src/core/all-keybindings.h:292 +#: data/50-mutter-windows.xml:24 msgid "Resize window" msgstr "Fenstergröße ändern" -#: ../src/core/all-keybindings.h:295 -msgid "Toggle whether window is on all workspaces or just one" -msgstr "Fenster sichtbar auf allen Arbeitsflächen ein-/ausschalten" - -#: ../src/core/all-keybindings.h:299 -msgid "Move window to workspace 1" -msgstr "Fenster auf Arbeitsfläche 1 verschieben" - -#: ../src/core/all-keybindings.h:302 -msgid "Move window to workspace 2" -msgstr "Fenster auf Arbeitsfläche 2 verschieben" - -#: ../src/core/all-keybindings.h:305 -msgid "Move window to workspace 3" -msgstr "Fenster auf Arbeitsfläche 3 verschieben" - -#: ../src/core/all-keybindings.h:308 -msgid "Move window to workspace 4" -msgstr "Fenster auf Arbeitsfläche 4 verschieben" - -#: ../src/core/all-keybindings.h:311 -msgid "Move window to workspace 5" -msgstr "Fenster auf Arbeitsfläche 5 verschieben" - -#: ../src/core/all-keybindings.h:314 -msgid "Move window to workspace 6" -msgstr "Fenster auf Arbeitsfläche 6 verschieben" - -#: ../src/core/all-keybindings.h:317 -msgid "Move window to workspace 7" -msgstr "Fenster auf Arbeitsfläche 7 verschieben" - -#: ../src/core/all-keybindings.h:320 -msgid "Move window to workspace 8" -msgstr "Fenster auf Arbeitsfläche 8 verschieben" - -#: ../src/core/all-keybindings.h:323 -msgid "Move window to workspace 9" -msgstr "Fenster auf Arbeitsfläche 9 verschieben" - -#: ../src/core/all-keybindings.h:326 -msgid "Move window to workspace 10" -msgstr "Fenster auf Arbeitsfläche 10 verschieben" - -#: ../src/core/all-keybindings.h:329 -msgid "Move window to workspace 11" -msgstr "Fenster auf Arbeitsfläche 11 verschieben" - -#: ../src/core/all-keybindings.h:332 -msgid "Move window to workspace 12" -msgstr "Fenster auf Arbeitsfläche 12 verschieben" - -#: ../src/core/all-keybindings.h:344 -msgid "Move window one workspace to the left" -msgstr "Fenster eine Arbeitsfläche nach links verschieben" - -#: ../src/core/all-keybindings.h:347 -msgid "Move window one workspace to the right" -msgstr "Fenster eine Arbeitsfläche nach rechts verschieben" - -#: ../src/core/all-keybindings.h:350 -msgid "Move window one workspace up" -msgstr "Fenster eine Arbeitsfläche nach oben verschieben" - -#: ../src/core/all-keybindings.h:353 -msgid "Move window one workspace down" -msgstr "Fenster eine Arbeitsfläche nach unten verschieben" +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "" +"Festlegen, ob das Fenster auf allen oder nur einer Arbeitsfläche sichtbar ist" -#: ../src/core/all-keybindings.h:356 -msgid "Raise window if it's covered by another window, otherwise lower it" -msgstr "Fenster anheben falls überdeckt, sonst absenken" +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "Fenster anheben, falls es verdeckt ist, andernfalls absenken" -#: ../src/core/all-keybindings.h:358 +#: data/50-mutter-windows.xml:31 msgid "Raise window above other windows" msgstr "Fenster vor die anderen Fenster anheben" -#: ../src/core/all-keybindings.h:360 +#: data/50-mutter-windows.xml:33 msgid "Lower window below other windows" msgstr "Fenster hinter die anderen Fenster absenken" -#: ../src/core/all-keybindings.h:364 +#: data/50-mutter-windows.xml:35 msgid "Maximize window vertically" msgstr "Fenster vertikal maximieren" -#: ../src/core/all-keybindings.h:368 +#: data/50-mutter-windows.xml:37 msgid "Maximize window horizontally" msgstr "Fenster horizontal maximieren" -#: ../src/core/all-keybindings.h:372 -msgid "Move window to north-west (top left) corner" -msgstr "Fenster in linke obere Ecke des Bildschirms verschieben" +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "Ansicht links teilen" -#: ../src/core/all-keybindings.h:375 -msgid "Move window to north-east (top right) corner" -msgstr "Fenster in rechte obere Ecke des Bildschirms verschieben" +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "Ansicht rechts teilen" -#: ../src/core/all-keybindings.h:378 -msgid "Move window to south-west (bottom left) corner" -msgstr "Fenster in linke untere Ecke des Bildschirms verschieben" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" -#: ../src/core/all-keybindings.h:381 -msgid "Move window to south-east (bottom right) corner" -msgstr "Fenster in rechte untere Ecke des Bildschirms verschieben" - -#: ../src/core/all-keybindings.h:385 -msgid "Move window to north (top) side of screen" -msgstr "Fenster zur oberen Seite des Bildschirms verschieben" +#: data/org.gnome.mutter.gschema.xml.in:7 +msgid "Modifier to use for extended window management operations" +msgstr "Zusatztaste für erweiterte Aktionen der Fensterverwaltung" -#: ../src/core/all-keybindings.h:388 -msgid "Move window to south (bottom) side of screen" -msgstr "Fenster zur unteren Seite des Bildschirms verschieben" +# bzw- die Apfel-Taste auf Mac-Computern +#: data/org.gnome.mutter.gschema.xml.in:8 +msgid "" +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." +msgstr "" +"Dieser Schlüssel wird die »Überlagerung« auslösen, d.h. eine kombinierte " +"Fensterübersicht und ein System zum Starten von Anwendungen. Als " +"Voreinstellung ist die Windows-Taste der Tastatur von PC-Hardware " +"vorgesehen. Man geht davon aus, dass diese Tastenverknüpfung entweder die " +"Vorgabe ist oder als leere Zeichenkette gesetzt ist." -#: ../src/core/all-keybindings.h:391 -msgid "Move window to east (right) side of screen" -msgstr "Fenster zur rechten Seite des Bildschirms verschieben" +#: data/org.gnome.mutter.gschema.xml.in:20 +msgid "Attach modal dialogs" +msgstr "Modale Dialoge anhängen" -#: ../src/core/all-keybindings.h:394 -msgid "Move window to west (left) side of screen" -msgstr "Fenster zur linken Seite des Bildschirms verschieben" +#: data/org.gnome.mutter.gschema.xml.in:21 +msgid "" +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." +msgstr "" +"Wenn auf »wahr« gesetzt, erscheinen anstelle unabhängiger Titelleisten an " +"die Titelleisten des Elternfensters angehängte modale Dialoge, welche " +"zusammen mit dem Elternfenster bewegt werden." -#: ../src/core/all-keybindings.h:397 -msgid "Move window to center of screen" -msgstr "Fenster in die Mitte des Bildschirms verschieben" +#: data/org.gnome.mutter.gschema.xml.in:30 +msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "" +"Kantenplatzierung beim Berühren der Bildschirmränder mit Fenstern aktivieren" -#: ../src/core/bell.c:310 -msgid "Bell event" -msgstr "Klangereignis" +#: data/org.gnome.mutter.gschema.xml.in:31 +msgid "" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." +msgstr "" +"Falls aktiviert, wird bei Berührung eines Fensters mit den senkrechten " +"Bildschirmrändern dieses vertikal maximiert und horizontal angepasst, um die " +"Hälfte des verfügbaren Bereiches zu belegen. Eine Berührung mit dem oberen " +"Bildschirmrand maximiert das Fenster vollständig." -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Unbekannte Fensterinformation angefordert: %d" +#: data/org.gnome.mutter.gschema.xml.in:40 +msgid "Workspaces are managed dynamically" +msgstr "Arbeitsflächen sollen dynamisch verwaltet werden" -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> antwortet nicht." +#: data/org.gnome.mutter.gschema.xml.in:41 +msgid "" +"Determines whether workspaces are managed dynamically or whether there’s a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." +msgstr "" +"Legt fest, ob Arbeitsflächen dynamisch verwaltet werden sollen, oder ob es " +"eine feste Anzahl Arbeitsflächen gibt (welche durch den Schlüssel num-" +"workspaces in org.gnome.desktop.wm.preferences festgelegt wird)." -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "Die Anwendung antwortet nicht." +#: data/org.gnome.mutter.gschema.xml.in:50 +msgid "Workspaces only on primary" +msgstr "Nur primärer Arbeitsflächenwechsel" -#: ../src/core/delete.c:119 +#: data/org.gnome.mutter.gschema.xml.in:51 msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." msgstr "" -"Sie können der Anwendung noch etwas Zeit geben oder ein sofortiges Beenden " -"erzwingen." +"Legt fest, ob Arbeitsflächenwechsel für alle Fenster auf allen Bildschirmen " +"oder nur für Fenster auf dem primären Bildschirm ausgeführt werden soll." -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "_Warten" +#: data/org.gnome.mutter.gschema.xml.in:59 +msgid "No tab popup" +msgstr "Keine Tab-Anzeige" -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "_Beenden erzwingen" +#: data/org.gnome.mutter.gschema.xml.in:60 +msgid "" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." +msgstr "" +"Legt fest, ob beim Durchblättern der Fenster die Tab-Anzeige und die " +"Hervorhebung des Rahmens deaktiviert werden soll." -#: ../src/core/display.c:365 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "Die für Compositing benötigte %s-Erweiterung wurde nicht gefunden" +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Fokus-Änderungen verzögern, bis der Zeiger aufhört sich zu bewegen" -#: ../src/core/display.c:431 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "X-Window-Systemanzeige »%s« konnte nicht geöffnet werden\n" +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" +"Falls dieser Schlüssel gesetzt ist und der Fokusmodus entweder »sloppy« oder " +"»mouse« ist, wird der Fokus nicht sofort beim Erreichen eines Fensters " +"geändert, sondern erst, wenn der Zeiger aufhört sich zu bewegen." -#: ../src/core/keybindings.c:759 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:79 +msgid "Draggable border width" +msgstr "Breite der ziehbaren Ränder" + +# Lange Beschreibung von »Draggable border width« +#: data/org.gnome.mutter.gschema.xml.in:80 msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" +"The amount of total draggable borders. If the theme’s visible borders are " +"not enough, invisible borders will be added to meet this value." msgstr "" -"Ein anderes Programm verwendet die Taste %s bereits mit den Umschaltern %x " -"als Tastenkombination\n" +"Die Gesamtbreite ziehbarer Ränder. Falls die im Thema sichtbaren Ränder " +"nicht ausreichen, werden unsichtbare Ränder hinzugefügt, um diesen Wert zu " +"erreichen." -#. Displayed when a keybinding which is -#. * supposed to launch a program fails. +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "Fenster nahe der Bildschirmgröße automatisch maximieren" + +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" +"Wenn aktiviert, werden neue Fenster, die beim Öffnen nahezu die Größe des " +"Bildschirms haben, direkt maximiert." + +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Neue Fenster in der Mitte platzieren" + +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" +"Falls wahr, so werden neue Fenster immer in der Mitte des aktiven " +"Bildschirms platziert." + +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Experimentelle Funktionsmerkmale aktivieren" + +#: data/org.gnome.mutter.gschema.xml.in:108 +msgid "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes " +"mutter request a low priority real-time scheduling. The executable or user " +"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — " +"initializes Xwayland lazily if there are X11 clients. Requires restart." +msgstr "" +"Um experimentelle Funktionsmerkmale zu aktivieren, fügen Sie das " +"entsprechende Schlüsselwort zur Liste hinzu. Möglicherweise muss der " +"Compositor neu gestartet werden, um es zu aktivieren, dies ist vom " +"Funktionsmerkmal abhängig. Für diese experimentellen Funktionsmerkmale gilt, " +"dass sie nicht unbedingt dauerhaft verfügbar sein werden, oder Einstellungen " +"möglich sind. Derzeit mögliche Schlüsselwörter: • »scale-monitor-" +"framebuffer« – weist Mutter an, in der Voreinstellung logische Bildschirme " +"in einem logischen Pixel-Koordinatensystem anzuordnen, wobei die Bildschirm-" +"Framebuffer anstelle der Fensterinhalte skaliert werden, um HiDPI-" +"Bildschirme besser versorgen zu können. Dafür ist kein Neustart " +"erforderlich. • »rt-scheduler« – weist Mutter an, ein Echtzeit-Scheduling " +"mit niedriger Priorität anzufordern. Dafür muss der Anwendung oder dem " +"Benutzer »CAP_SYS_NICE« zur Verfügung stehen. Hierfür ist ein Neustart " +"erforderlich. • “autostart-xwayland” – startet Xwayland, wenn X11-" +"Anwendungen vorhanden sind. Hierfür ist ein Neustart erforderlich." + +#: data/org.gnome.mutter.gschema.xml.in:134 +msgid "Modifier to use to locate the pointer" +msgstr "Zusatztaste zum Finden des Zeigers" + +#: data/org.gnome.mutter.gschema.xml.in:135 +msgid "This key will initiate the “locate pointer” action." +msgstr "Diese Taste wird die Aktion »Zeiger finden« auslösen." + +#: data/org.gnome.mutter.gschema.xml.in:142 +msgid "Timeout for check-alive ping" +msgstr "Reaktionsschwellwert bei Kontaktkontrolle" + +#: data/org.gnome.mutter.gschema.xml.in:143 +msgid "" +"Number of milliseconds a client has to respond to a ping request in order to " +"not be detected as frozen. Using 0 will disable the alive check completely." +msgstr "" +"Zeit in Millisekunden, innerhalb welcher ein Client auf eine " +"Kontaktkontrolle antworten muss, um nicht als abgestürzt zu gelten. »0« " +"bedeutet, dass die Kontaktkontrolle ausgeschaltet wird." + +#: data/org.gnome.mutter.gschema.xml.in:165 +msgid "Select window from tab popup" +msgstr "Fenster aus Tab-Anzeige auswählen" + +#: data/org.gnome.mutter.gschema.xml.in:170 +msgid "Cancel tab popup" +msgstr "Tab-Anzeige abbrechen" + +#: data/org.gnome.mutter.gschema.xml.in:175 +msgid "Switch monitor configurations" +msgstr "Bildschirmkonfigurationen wechseln" + +# Ich denke nicht, dass »rotate« hier die Bildschirmdrehung meint, sondern eher eine Liste aus Konfigurationen rotiert (d.h. umgewälzt) wird. +#: data/org.gnome.mutter.gschema.xml.in:180 +msgid "Rotates the built-in monitor configuration" +msgstr "Wechselt die Konfiguration des eingebauten Bildschirms" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Zum virtuellen Terminal 1 wechseln" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Zum virtuellen Terminal 2 wechseln" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Zum virtuellen Terminal 3 wechseln" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Zum virtuellen Terminal 4 wechseln" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Zum virtuellen Terminal 5 wechseln" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Zum virtuellen Terminal 6 wechseln" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Zum virtuellen Terminal 7 wechseln" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Zum virtuellen Terminal 8 wechseln" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Zum virtuellen Terminal 9 wechseln" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Zum virtuellen Terminal 10 wechseln" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Zum virtuellen Terminal 11 wechseln" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Zum virtuellen Terminal 12 wechseln" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "Tastenkombinationen erneut aktivieren" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow X11 grabs to lock keyboard focus with Xwayland" +msgstr "" +"X11-Tastatur-Kontrollübernahmen zum Festlegen des Tastaturfokus in Xwayland " +"erlauben" + +# https://tronche.com/gui/x/xlib/window/attributes/override-redirect.html +# Ich halte es nicht für sinnvoll, diesen Term zu übersetzen. +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 +msgid "" +"Allow all keyboard events to be routed to X11 “override redirect” windows " +"with a grab when running in Xwayland. This option is to support X11 clients " +"which map an “override redirect” window (which do not receive keyboard " +"focus) and issue a keyboard grab to force all keyboard events to that " +"window. This option is seldom used and has no effect on regular X11 windows " +"which can receive keyboard focus under normal circumstances. For a X11 grab " +"to be taken into account under Wayland, the client must also either send a " +"specific X11 ClientMessage to the root window or be among the applications " +"white-listed in key “xwayland-grab-access-rules”." +msgstr "" +"Erlauben, dass in Xwayland alle Tastaturevents mittels Kontrollübernahme auf " +"X11-»override redirect«-Fenster überführt werden können. Diese Einstellung " +"unterstützt X11-Clients, die »override redirect«-Fenster (Fenster ohne " +"Tastaturfokus) öffnen und dabei eine Tastatur-Kontrollübernahme anfordern, " +"um alle Tastaturevents auf dieses Fenster anzuwenden. Diese Einstellung wird " +"nur selten genutzt und hat keinen Einfluss auf normale X11-Fenster, die " +"einen Tastaturfokus erhalten können. Damit eine X11-Kontrollübernahme unter " +"Wayland durchgeführt werden kann, muss der Client auch entweder eine " +"spezifische X11-ClientMessage an das Root-Fenster senden oder in den als " +"»whitelisted« im Schlüssel »xwayland-grab-access-rules« aufgelisteten " +"Anwendungen enthalten sein." + +#: data/org.gnome.mutter.wayland.gschema.xml.in:84 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "Xwayland-Anwendungen mit Erlaubnis zur Kontrollübernahme der Tastatur" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:85 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "" +"Listet die Ressourcennamen oder -klassen von X11-Fenstern auf, die unter " +"Xwayland X11-Tastatur-Kontrollübernahmen durchführen dürfen. Ressourcenname " +"oder -klasse eines bestimmten X11-Fensters kann mit dem Befehl »xprop " +"WM_CLASS« ermittelt werden. Dabei werden »*« als Platzhalter und »?« als " +"Joker in den Wertangaben unterstützt. Mit »!« beginnende Werte gelten als " +"»blacklisted« und werden gegenüber den als »whitelisted« markierten Werten " +"bevorzugt, um in der Standardliste des Systems aufgeführte Anwendungen außer " +"Kraft zu setzen. Die Standardliste des Systems enthält die folgenden " +"Anwendungen: »@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@« Benutzer können eine " +"existierende Kontrollübernahme unterbrechen, indem sie das spezifische " +"Tastenkürzel verwenden, wie es im Schlüssel »restore-shortcuts« angegeben " +"ist." + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. #. -#: ../src/core/keybindings.c:2523 +#: src/backends/meta-input-settings.c:2631 #, c-format -msgid "" -"There was an error running <tt>%s</tt>:\n" -"\n" -"%s" -msgstr "" -"Beim Ausführen von <tt>%s</tt> ist ein Fehler aufgetreten:\n" -"\n" -"%s" +msgid "Mode Switch (Group %d)" +msgstr "Moduswechsel (Gruppe %d)" + +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2654 +msgid "Switch monitor" +msgstr "Bildschirm wechseln" + +#: src/backends/meta-input-settings.c:2656 +msgid "Show on-screen help" +msgstr "Bildschirmhilfe anzeigen" -#: ../src/core/keybindings.c:2613 +#: src/backends/meta-monitor.c:226 +msgid "Built-in display" +msgstr "Eingebaute Anzeige" + +#: src/backends/meta-monitor.c:255 +msgid "Unknown" +msgstr "Unbekannt" + +#: src/backends/meta-monitor.c:257 +msgid "Unknown Display" +msgstr "Unbekannte Anzeige" + +#: src/backends/meta-monitor.c:265 +#, c-format +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" + +#: src/backends/meta-monitor.c:273 #, c-format -msgid "No command %d has been defined.\n" -msgstr "Es wurde kein Befehl %d festgelegt.\n" +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" + +# https://de.wikipedia.org/wiki/Composition-Manager +#. Translators: this string will appear in Sysprof +#: src/backends/meta-profiler.c:79 +msgid "Compositor" +msgstr "Compositor" -#: ../src/core/keybindings.c:3625 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:533 #, c-format -msgid "No terminal command has been defined.\n" -msgstr "Es wurde kein Terminal-Befehl festgelegt.\n" +msgid "" +"Another compositing manager is already running on screen %i on display “%s”." +msgstr "" +"Ein weiterer Compositing-Verwalter läuft bereits auf Bildschirm %i der " +"Anzeige »%s«." -#: ../src/core/main.c:206 +#: src/core/bell.c:192 +msgid "Bell event" +msgstr "Klangereignis" + +#: src/core/main.c:190 msgid "Disable connection to session manager" msgstr "Verbindung zur Sitzungsverwaltung deaktivieren" -#: ../src/core/main.c:212 +#: src/core/main.c:196 msgid "Replace the running window manager" msgstr "Den aktuellen Fensterverwalter ersetzen" -#: ../src/core/main.c:218 +#: src/core/main.c:202 msgid "Specify session management ID" msgstr "Kennung der Sitzungsverwaltung angeben" -#: ../src/core/main.c:223 +#: src/core/main.c:207 msgid "X Display to use" msgstr "Zu verwendende X-Anzeige" -#: ../src/core/main.c:229 +#: src/core/main.c:213 msgid "Initialize session from savefile" msgstr "Sitzung anhand gespeicherter Datei starten" -#: ../src/core/main.c:235 +#: src/core/main.c:219 msgid "Make X calls synchronous" msgstr "X-Aufrufe abgleichen" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Der Themenordner konnte nicht eingelesen werden: %s\n" +#: src/core/main.c:226 +msgid "Run as a wayland compositor" +msgstr "Als Wayland-Compositor ausführen" -#: ../src/core/main.c:520 +#: src/core/main.c:232 +msgid "Run as a nested compositor" +msgstr "Als eingebetteten Compositor ausführen" + +#: src/core/main.c:238 +msgid "Run wayland compositor without starting Xwayland" +msgstr "Wayland-Compositor ausführen, ohne Xwayland zu starten" + +#: src/core/main.c:246 +msgid "Run as a full display server, rather than nested" +msgstr "Als vollwertigen Display-Server verwenden (nicht eingebettet)" + +#: src/core/main.c:252 +msgid "Run with X11 backend" +msgstr "Mit X11-Backend ausführen" + +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:151 #, c-format +msgid "“%s” is not responding." +msgstr "»%s« antwortet nicht." + +#: src/core/meta-close-dialog-default.c:153 +msgid "Application is not responding." +msgstr "Die Anwendung antwortet nicht." + +#: src/core/meta-close-dialog-default.c:158 msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." msgstr "" -"Es konnte kein Thema gefunden werden! Stellen Sie sicher, dass %s existiert " -"und zumindest die mitgelieferten Themen enthält.\n" +"Sie können der Anwendung noch etwas Zeit geben oder ein sofortiges Beenden " +"erzwingen." + +#: src/core/meta-close-dialog-default.c:165 +msgid "_Force Quit" +msgstr "_Beenden erzwingen" + +#: src/core/meta-close-dialog-default.c:165 +msgid "_Wait" +msgstr "_Warten" # CHECK # c-format -#: ../src/core/muffin.c:42 +#: src/core/mutter.c:38 #, c-format msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" "This is free software; see the source for copying conditions.\n" "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " "PARTICULAR PURPOSE.\n" msgstr "" -"muffin %s\n" +"mutter %s\n" "Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., und andere\n" "Dies ist freie Software; schauen Sie in den Quelltext, um weitere " "Informationen zu erhalten.\n" "Es besteht KEINE Garantie auf MARKTREIFE oder EIGNUNG für einen BESTIMMTEN " "ZWECK.\n" -#: ../src/core/muffin.c:56 +#: src/core/mutter.c:52 msgid "Print version" msgstr "Version ausgeben" -#: ../src/core/muffin.c:62 -msgid "Comma-separated list of compositor plugins" -msgstr "Eine durch Kommata getrennte Liste von Plugins für den Compositor" - -#. -#. * We found it, but it was invalid. Complain. -#. * -#. * FIXME: This replicates the original behaviour, but in the future -#. * we might consider reverting invalid keys to their original values. -#. * (We know the old value, so we can look up a suitable string in -#. * the symtab.) -#. * -#. * (Empty comment follows so the translators don't see this.) -#. -#. -#: ../src/core/prefs.c:550 ../src/core/prefs.c:711 -#, c-format -msgid "GConf key '%s' is set to an invalid value\n" -msgstr "Wert des GConf-Schlüssels »%s« unzulässig\n" - -#: ../src/core/prefs.c:637 ../src/core/prefs.c:880 -#, c-format -msgid "%d stored in GConf key %s is out of range %d to %d\n" -msgstr "" -"%d, gespeichert in GConf-Schlüssel %s, liegt außerhalb des Bereichs %d-%d\n" - -#: ../src/core/prefs.c:681 ../src/core/prefs.c:758 ../src/core/prefs.c:806 -#: ../src/core/prefs.c:870 ../src/core/prefs.c:1331 ../src/core/prefs.c:1347 -#: ../src/core/prefs.c:1364 ../src/core/prefs.c:1380 -#, c-format -msgid "GConf key \"%s\" is set to an invalid type\n" -msgstr "Typ des GConf-Schlüssels »%s« ungültig\n" - -#: ../src/core/prefs.c:1210 -#, c-format -msgid "GConf key %s is already in use and can't be used to override %s\n" -msgstr "" -"Der GConf-Schlüssel %s wird bereits benutzt und kann nicht zum Überschreiben " -"von %s verwendet werden\n" - -#: ../src/core/prefs.c:1269 -#, c-format -msgid "Can't override GConf key, %s not found\n" -msgstr "" -"GConf-Schlüssel kann nicht überschrieben werden, %s wurde nicht gefunden\n" - -#: ../src/core/prefs.c:1454 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"Provisorien (Workarounds) für defekte Anwendungen abgeschaltet. " -"Möglicherweise funktionieren manche Anwendungen nicht richtig.\n" - -#: ../src/core/prefs.c:1531 -#, c-format -msgid "Could not parse font description \"%s\" from GConf key %s\n" -msgstr "" -"Schriftbeschreibung »%s« aus GConf-Schlüssel %s konnte nicht verarbeitet " -"werden\n" +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "Zu benutzendes Mutter-Plugin" -#: ../src/core/prefs.c:1593 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"In der Konfigurationsdatenbank gefundenes »%s« ist kein zulässiger Wert für " -"den Maustastenumschalter\n" - -#: ../src/core/prefs.c:2028 -#, c-format -msgid "Error setting number of workspaces to %d: %s\n" -msgstr "Fehler beim Festlegen der Anzahl der Arbeitsflächen auf %d: %s\n" - -#: ../src/core/prefs.c:2212 ../src/core/prefs.c:2714 +#: src/core/prefs.c:1911 #, c-format msgid "Workspace %d" msgstr "Arbeitsfläche %d" -#: ../src/core/prefs.c:2244 ../src/core/prefs.c:2422 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "" -"In der Konfigurationsdatenbank gefundenes »%s« ist kein zulässiger Wert für " -"die Tastenkombination »%s«\n" - -#: ../src/core/prefs.c:2795 -#, c-format -msgid "Error setting name for workspace %d to \"%s\": %s\n" -msgstr "Fehler beim Festlegen des Namens der Arbeitsflächen %d auf »%s«: %s\n" - -#: ../src/core/prefs.c:3009 -#, c-format -msgid "Error setting live hidden windows status status: %s\n" -msgstr "Fehler beim Festlegen des Status des verborgenen Fensters: %s\n" - -#: ../src/core/prefs.c:3044 -#, c-format -msgid "Error setting no tab popup status: %s\n" -msgstr "Fehler beim Festlegen des Status des Einblendfensters: %s\n" - -#: ../src/core/screen.c:741 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "Bildschirm %d auf Anzeige »%s« ist ungültig\n" +#: src/core/util.c:122 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter wurde ohne Unterstützung für den redseligen Modus kompiliert\n" -#: ../src/core/screen.c:757 +#: src/wayland/meta-wayland-tablet-pad.c:568 #, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"Bildschirm %d auf Anzeige »%s« hat bereits einen Fensterverwalter; Geben Sie " -"die Option »--replace« an, um zu versuchen, den aktuellen Fensterverwalter zu " -"ersetzen.\n" +msgid "Mode Switch: Mode %d" +msgstr "Moduswechsel: Modus %d" -#: ../src/core/screen.c:784 +#: src/x11/meta-x11-display.c:676 #, c-format msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." msgstr "" -"Markierung des Fensterverwalters auf Bildschirm %d auf Anzeige »%s« konnte " -"nicht empfangen werden\n" - -#: ../src/core/screen.c:839 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "Bildschirm %d auf Anzeige »%s« hat bereits einen Fensterverwalter\n" - -#: ../src/core/screen.c:1024 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "Bildschirm %d auf Anzeige »%s« konnte nicht freigegeben werden\n" +"Bildschirm »%s« hat bereits einen Fensterverwalter. Versuchen Sie die Option " +"»--replace«, um den aktuellen Fensterverwalter zu ersetzen." -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Ordner »%s« konnte nicht angelegt werden: %s\n" - -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "Sitzungsdatei »%s« konnte nicht zum Schreiben geöffnet werden: %s\n" - -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Fehler beim Schreiben der Sitzungsdatei »%s«: %s\n" - -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Fehler beim Schließen der Sitzungsdatei »%s«: %s\n" - -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Gespeicherte Sitzungsdatei konnte nicht verarbeitet werden: %s\n" - -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "" -"Attribut <metacity_session> ist aufgetaucht, obwohl die Sitzungskennung " -"bereits feststeht" +#: src/x11/meta-x11-display.c:1089 +msgid "Failed to initialize GDK\n" +msgstr "GDK konnte nicht initialisiert werden\n" -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 +#: src/x11/meta-x11-display.c:1113 #, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Unbekanntes Attribut %s in Element <%s>" +msgid "Failed to open X Window System display “%s”\n" +msgstr "X-Window-Systemanzeige »%s« konnte nicht geöffnet werden\n" -#: ../src/core/session.c:1215 +#: src/x11/meta-x11-display.c:1196 #, c-format -msgid "nested <window> tag" -msgstr "verschachteltes Element <window>" +msgid "Screen %d on display “%s” is invalid\n" +msgstr "Bildschirm %d auf Anzeige »%s« ist ungültig\n" -#: ../src/core/session.c:1457 +#: src/x11/meta-x11-selection-input-stream.c:460 #, c-format -msgid "Unknown element %s" -msgstr "Unbekanntes Element %s" +msgid "Format %s not supported" +msgstr "Format %s wird nicht unterstützt" -#: ../src/core/session.c:1809 +#: src/x11/session.c:1821 msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." msgstr "" "Diese Fenster unterstützen das Speichern der aktuellen Einstellungen nicht " "und müssen bei der nächsten Anmeldung manuell neu gestartet werden." -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Diagnoseprotokoll konnte nicht geöffnet werden: %s\n" - -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Protokolldatei %s konnte nicht mit fdopen() geöffnet werden: %s\n" - -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "Protokolldatei %s geöffnet\n" - -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "Muffin wurde ohne Unterstützung für den redseligen Modus kompiliert\n" - -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "Fensterverwalter:" - -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "Fehler in Fensterverwalter:" - -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "Fensterverwalter-Warnung:" - -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "Fensterverwalter-Fehler:" - -#. first time through -#: ../src/core/window.c:7066 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"Fenster %s setzt SM_CLIENT_ID auf sich selbst, anstatt auf das " -"WM_CLIENT_LEADER-Fenster, wie im ICCCM vorgegeben.\n" - -# We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -# * authoritative source for that info. Some apps such as mplayer or -# * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -# * leads to e.g. us not fullscreening their windows. Apps that set -# * MWM but not WM_NORMAL_HINTS are basically broken. We complain -# * about these apps but make them work. -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7729 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %" -"d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"Fenster %s zeigt durch einen MWM-Hinweis an, dass die Größe nicht " -"veränderbar ist, setzt jedoch die minimale Größe auf %d x %d und die " -"maximale Größe auf %d x %d; dies ergibt keinen Sinn.\n" - -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "Anwendung hat eine unsinnige _NET_WM_PID %lu angegeben\n" - -#: ../src/core/window-props.c:426 +#: src/x11/window-props.c:569 #, c-format msgid "%s (on %s)" msgstr "%s (auf %s)" - -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "Ungültiges WM_TRANSIENT_FOR-Fenster 0x%lx festgelegt für %s.\n" - -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "" -"WM_TRANSIENT_FOR-Fenster 0x%lx für %s würde eine Endlosschleife " -"verursachen.\n" - -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"Fenster 0x%lx hat die Eigenschaft %s,\n" -"die Typ %s, Format %d sein sollte,\n" -"jedoch Typ %s, Format %d n_items %d ist.\n" -"Dies ist vermutlich ein Fehler in der Anwendung\n" -"und nicht im Fensterverwalter. Das Fenster hat den\n" -"Titel »%s«, die Klasse »%s« und den Namen »%s«\n" - -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "Eigenschaft %s von Fenster 0x%lx enthielt ungültiges UTF-8\n" - -#: ../src/core/xprops.c:494 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"Eigenschaft %s auf Fenster 0x%lx enthielt ungültiges UTF-8 für Objekt %d in " -"der Liste\n" - -#: ../src/muffin.desktop.in.h:1 ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" - -#: ../src/muffin.schemas.in.h:1 -msgid "Attach modal dialogs" -msgstr "Modale Dialoge anhängen" - -#: ../src/muffin.schemas.in.h:2 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"Legt fest, ob verborgene Fenster (d.h. minimierte Fenster und Fenster auf " -"anderen Arbeitsflächen) erhalten bleiben sollen." - -#: ../src/muffin.schemas.in.h:3 -msgid "" -"Determines whether workspace switching should happen for windows on all " -"monitors or only for windows on the primary monitor." -msgstr "" -"Legt fest, ob Arbeitsflächenwechsel für alle Fenster auf allen Bildschirmen " -"oder nur für Fenster auf dem primären Bildschirm ausgeführt werden soll." - -#: ../src/muffin.schemas.in.h:4 -msgid "Draggable border width" -msgstr "Breite der ziehbaren Ränder" - -#: ../src/muffin.schemas.in.h:5 -msgid "Live Hidden Windows" -msgstr "Verborgene Fenster erhalten" - -#: ../src/muffin.schemas.in.h:6 -msgid "Modifier to use for extended window management operations" -msgstr "Zusatztaste für erweiterte Aktionen der Fensterverwaltung" - -# Lange Beschreibung von »Draggable border width« -#: ../src/muffin.schemas.in.h:7 -msgid "" -"The amount of total draggable borders. If the theme's visible borders are " -"not enough, invisible borders will be added to meet this value." -msgstr "" -"Die Gesamtbreite ziehbarer Ränder. Falls die im Thema sichtbaren Ränder " -"nicht ausreichen, werden unsichtbare Ränder hinzugefügt, um diesen Wert zu " -"erreichen." - -#: ../src/muffin.schemas.in.h:8 -msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." -msgstr "" -"Dieser Schlüssel wird die »Überlagerung« auslösen, d.h. eine kombinierte " -"Fensterübersicht und ein System zum Starten von Anwendungen. Als " -"Voreinstellung ist die Windows-Taste der Tastatur von PC-Hardware " -"vorgesehen. Man geht davon aus, dass diese Tastenverknüpfung entweder die " -"Vorgabe ist oder als leere Zeichenkette gesetzt ist." - -#: ../src/muffin.schemas.in.h:9 -msgid "" -"When true, instead of having independent titlebars, modal dialogs appear " -"attached to the titlebar of the parent window and are moved together with " -"the parent window." -msgstr "" -"Wenn auf »wahr« gesetzt, erscheinen anstelle unabhängiger Titelleisten an die " -"Titelleisten des Elternfensters angehängte modale Dialoge, welche zusammen " -"mit dem Elternfenster bewegt werden." - -#: ../src/muffin.schemas.in.h:10 -msgid "Workspaces only on primary" -msgstr "Nur primärer Arbeitsflächenwechsel" - -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "Aufruf: %s\n" - -#: ../src/ui/frames.c:1157 -msgid "Close Window" -msgstr "Fenster schließen" - -#: ../src/ui/frames.c:1160 -msgid "Window Menu" -msgstr "Fenstermenü" - -#: ../src/ui/frames.c:1163 -msgid "Minimize Window" -msgstr "Fenster minimieren" - -#: ../src/ui/frames.c:1166 -msgid "Maximize Window" -msgstr "Fenster maximieren" - -#: ../src/ui/frames.c:1169 -msgid "Restore Window" -msgstr "Fenster wiederherstellen" - -#: ../src/ui/frames.c:1172 -msgid "Roll Up Window" -msgstr "Fenster einrollen" - -#: ../src/ui/frames.c:1175 -msgid "Unroll Window" -msgstr "Fenster abrollen" - -#: ../src/ui/frames.c:1178 -msgid "Keep Window On Top" -msgstr "Fenster immer im Vordergrund" - -#: ../src/ui/frames.c:1181 -msgid "Remove Window From Top" -msgstr "Fenster nicht immer im Vordergrund" - -#: ../src/ui/frames.c:1184 -msgid "Always On Visible Workspace" -msgstr "Immer auf der sichtbaren Arbeitsfläche" - -#: ../src/ui/frames.c:1187 -msgid "Put Window On Only One Workspace" -msgstr "Soll das Fenster auf nur einer Arbeitsfläche sichtbar sein?" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "_Minimieren" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "Ma_ximieren" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "_Wiederherstellen" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "Ein_rollen" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "Aus_rollen" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "_Verschieben" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "_Größe ändern" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "_Titelleiste auf Bildschirm verschieben" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "Im V_ordergrund" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "Immer auf der _sichtbaren Arbeitsfläche" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "Nur auf _dieser Arbeitsfläche" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "Auf Arbeitsfläche _links verschieben" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "Auf Arbeitsfläche _rechts verschieben" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "Auf Arbeitsfläche darü_ber verschieben" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "Auf Arbeitsfläche dar_unter verschieben" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "S_chließen" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "Arbeitsfläche %d%n" - -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "Arbeitsfläche 1_0" - -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "Arbeitsfläche %s%d" - -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "Auf a_ndere Arbeitsfläche verschieben" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Strg" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Umschalter2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Umschalter3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Umschalter4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Umschalter5" - -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" - -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "oben" - -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "unten" - -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "links" - -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "rechts" - -#: ../src/ui/theme.c:286 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "Die Rahmengeometrie gibt die »%s«-Abmessungen nicht an" - -#: ../src/ui/theme.c:305 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "Die Rahmengeometrie gibt die »%s«-Abmessungen für den Rand »%s« nicht an" - -#: ../src/ui/theme.c:342 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "Das Seitenverhältnis %g für einen Knopf ergibt keinen Sinn" - -#: ../src/ui/theme.c:354 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "Die Rahmengeometrie gibt die Abmessungen der Knöpfe nicht an" - -#: ../src/ui/theme.c:1065 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "Farbverläufe sollten mindestens zwei Farben enthalten" - -# (where "foo" refers to the name defined in GTK+'s CSS, and "bar" refers to an alternative color spec which is used when the color referenced by "foo" is not found) -#: ../src/ui/theme.c:1217 -#, c-format -msgid "" -"GTK custom color specification must have color name and fallback in " -"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" -msgstr "" -"Bei benutzerdefinierten GTK-Farbangaben müssen Farbname und Alternativfarbe " -"in Klammern gesetzt werden, z.B. gtk:custom(foo,bar); »%s« konnte nicht " -"verarbeitet werden" - -#: ../src/ui/theme.c:1233 -#, c-format -msgid "" -"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" -"_ are valid" -msgstr "" -"Ungültiges Zeichen »%c« im Parameter »color_name parameter« von »gtk:custom«, " -"nur A-Za-z0-9-_ sind zulässig" - -#: ../src/ui/theme.c:1247 -#, c-format -msgid "" -"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " -"fit the format" -msgstr "" -"Das Gtk:custom-Format ist »gtk:custom(Farbname,Ersetzungsanweisung)«; »%s« " -"passt nicht auf dieses Format" - -#: ../src/ui/theme.c:1292 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"Bei GTK-Farbangaben muss der Zustand in eckigen Klammern stehen, z.B. gtk:fg" -"[NORMAL], wobei NORMAL der Zustand ist; »%s« konnte nicht verarbeitet werden." - -#: ../src/ui/theme.c:1306 -#, c-format -msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"GTK-Farbangaben müssen nach dem Zustand eine schließende eckige Klammer " -"enthalten, z.B. gtk:fg[NORMAL], wobei NORMAL der Zustand ist; »%s« konnte " -"nicht verarbeitet werden" - -#: ../src/ui/theme.c:1317 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "Zustand »%s« in der Farbangabe konnte nicht verarbeitet werden" - -#: ../src/ui/theme.c:1330 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "Farbkomponente »%s« in der Farbangabe konnte nicht verarbeitet werden" - -#: ../src/ui/theme.c:1360 -#, c-format -msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" -msgstr "" -"Das Blendformat ist »blend/bg_color/fg_color/alpha«; »%s« passt nicht auf " -"dieses Format" - -#: ../src/ui/theme.c:1371 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "Der Alphawert »%s« in einer Mischfarbe konnte nicht verarbeitet werden" - -#: ../src/ui/theme.c:1381 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "Der Alphawert »%s« in einer Mischfarbe liegt nicht zwischen 0.0 und 1.0" - -#: ../src/ui/theme.c:1428 -#, c-format -msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "" -"Das Mischformat ist »Mischen/Basisfarbe/Faktor«; »%s« passt nicht auf dieses " -"Format" - -#: ../src/ui/theme.c:1439 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "" -"Der Mischfaktor »%s« in einer Mischfarbe konnte nicht verarbeitet werden" - -#: ../src/ui/theme.c:1449 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "Der Mischfaktor »%s« in einer Mischfarbe ist negativ" - -#: ../src/ui/theme.c:1478 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Die Farbe »%s« konnte nicht verarbeitet werden" - -#: ../src/ui/theme.c:1789 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "Der Koordinatenausdruck enthält das unerlaubte Zeichen »%s«" - -#: ../src/ui/theme.c:1816 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "" -"Der Koordinatenausdruck enthält die Gleitkommazahl »%s«, die nicht " -"verarbeitet werden konnte" - -#: ../src/ui/theme.c:1830 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "" -"Der Koordinatenausdruck enthält die Ganzzahl »%s«, die nicht verarbeitet " -"werden konnte" - -#: ../src/ui/theme.c:1952 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "" -"Der Koordinatenausdruck enthält einen unbekannten Operator am Anfang dieses " -"Texts: »%s«" - -#: ../src/ui/theme.c:2009 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "Der Koordinatenausdruck war leer oder unverständlich" - -#: ../src/ui/theme.c:2120 ../src/ui/theme.c:2130 ../src/ui/theme.c:2164 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "Der Koordinatenausdruck führt zu einer Division durch Null" - -#: ../src/ui/theme.c:2172 -#, c-format -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "" -"Der Koordinatenausdruck versucht, den Modulo-Operator auf eine " -"Gleitkommazahl anzuwenden" - -#: ../src/ui/theme.c:2228 -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "" -"Der Koordinatenausdruck enthält den Operator »%s«, wo ein Operand stehen " -"müsste" - -#: ../src/ui/theme.c:2237 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "" -"Der Koordinatenausdruck enthält einen Operanden, wo ein Operator stehen " -"müsste" - -#: ../src/ui/theme.c:2245 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "Der Koordinatenausdruck endet mit einem Operator statt einem Operanden" - -#: ../src/ui/theme.c:2255 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" -"Der Koordinatenausdruck enthält die beiden Operatoren »%c« und »%c«, jedoch " -"keinen Operanden dazwischen" - -#: ../src/ui/theme.c:2406 ../src/ui/theme.c:2451 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "" -"Der Koordinatenausdruck enthält die unbekannte Variable oder Konstante »%s«" - -#: ../src/ui/theme.c:2505 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "Der Koordinatenausdruck brachte seinen Puffer zum Überlaufen." - -#: ../src/ui/theme.c:2534 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "" -"Der Koordinatenausdruck enthält eine schließende Klammer, jedoch keine " -"Öffnende" - -#: ../src/ui/theme.c:2598 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "" -"Der Koordinatenausdruck enthält eine öffnende Klammer, jedoch keine " -"Schließende" - -#: ../src/ui/theme.c:2609 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "" -"Der Koordinatenausdruck scheint weder Operatoren noch Operanden zu enthalten" - -#: ../src/ui/theme.c:2821 ../src/ui/theme.c:2841 ../src/ui/theme.c:2861 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "Das Thema enthält einen Ausdruck, der zu folgendem Fehler führte: %s\n" - -#: ../src/ui/theme.c:4532 -#, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" -"Für diesen Rahmenstil muss <button function=\"%s\" state=\"%s\" draw_ops=" -"\"irgendwas\"/> angegeben werden" - -#: ../src/ui/theme.c:5065 ../src/ui/theme.c:5090 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" -"<frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"irgendwas\"/> fehlt" - -#: ../src/ui/theme.c:5138 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Thema »%s« konnte nicht geladen werden: %s\n" - -#: ../src/ui/theme.c:5274 ../src/ui/theme.c:5281 ../src/ui/theme.c:5288 -#: ../src/ui/theme.c:5295 ../src/ui/theme.c:5302 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "Kein <%s> für Thema »%s« festgelegt" - -#: ../src/ui/theme.c:5310 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" -"Kein Rahmenstil für Fenstertyp »%s« in Thema »%s« angegeben; fügen Sie ein " -"Element <window type=\"%s\" style_set=\"irgendwas\"/> hinzu" - -#: ../src/ui/theme.c:5708 ../src/ui/theme.c:5770 ../src/ui/theme.c:5833 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" -"Benutzerdefinierte Konstanten müssen mit einem Großbuchstaben beginnen; »%s« " -"jedoch nicht" - -#: ../src/ui/theme.c:5716 ../src/ui/theme.c:5778 ../src/ui/theme.c:5841 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "Konstante »%s« wurde bereits definiert" - -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. -#. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "Kein Attribut »%s« in Element <%s>" - -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Zeile %d Zeichen %d: %s" - -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "Attribut »%s« wiederholt sich im selben Element <%s>" - -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "Attribut »%s« ist in diesem Kontext in Element <%s> ungültig" - -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "»%s« konnte nicht als Ganzzahl verarbeitet werden" - -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "" -"Schließende Zeichen »%s« in Zeichenkette »%s« konnten nicht verarbeitet werden" - -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "Ganzzahl %ld muss positiv sein" - -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "Ganzzahl %ld ist zu groß, aktuelles Maximum ist %d" - -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "»%s« konnte nicht als Gleitkommazahl verarbeitet werden" - -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "Wahrheitswerte müssen »true« oder »false« sein, nicht »%s«" - -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "Der Winkel muss zwischen 0.0 und 360.0 liegen, war jedoch %g\n" - -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" -"Alpha muss zwischen 0.0 (unsichtbar) und 1.0 (vollständig deckend) liegen, " -"war jedoch %g\n" - -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"Ungültiger Titelmaßstab »%s« (muss xx-small, x-small, small, medium, large, x-" -"large oder xx-large sein)\n" - -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "Name »%s« von <%s> wurde zweimal verwendet" - -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "Elternelement »%s« von <%s> wurde nicht definiert" - -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "Geometrie »%s« für Element <%s> wurde nicht definiert" - -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "" -"<%s> muss entweder eine Geometrie oder ein Elternelement mit einer Geometrie " -"angeben" - -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "" -"Es muss ein Hintergrund festgelegt werden, damit ein Alpha-Wert sinnvoll ist." - -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Unbekannter Typ »%s« in <%s>-Element" - -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "Attribut style_set »%s« in Element <%s> hat einen unbekannten Wert" - -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "Fenstertyp »%s« wurde bereits ein Stilsatz zugeordnet" - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "Element <%s> ist nicht unter <%s> erlaubt" - -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" -msgstr "" -"Es können nicht Knopfbreite/Knopfhöhe und das Seitenverhältnis für Knöpfe " -"gleichzeitig angegeben werden" - -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "Abstand »%s« ist unbekannt" - -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "Seitenverhältnis »%s« ist unbekannt" - -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "Rahmen »%s« ist unbekannt" - -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "Kein Attribut »start_angle« oder »from« in Element <%s>" - -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "Kein Attribut »extent_angle« oder »to« in Element <%s>" - -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "Wert »%s« für Typ des Farbverlaufs konnte nicht verarbeitet werden" - -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "Fülltyp »%s« für Element <%s> konnte nicht verarbeitet werden" - -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "Zustand »%s« für Element <%s> konnte nicht verarbeitet werden" - -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "Schatten »%s« für Element <%s> konnte nicht verarbeitet werden" - -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "Pfeil »%s« für Element <%s> konnte nicht verarbeitet werden" - -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "Es wurde kein <draw_ops> namens »%s« definiert" - -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "Hier draw_ops »%s« einzufügen würde einen Ringschluss erzeugen" - -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Unbekannte Position »%s« für Rahmenteil" - -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "Rahmenstil hat bereits einen Teil bei Position %s" - -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "Es wurde kein <draw_ops> mit Namen »%s« definiert" - -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Unbekannte Knopf-Funktion »%s«" - -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "Knopf-Funktion »%s« existiert in dieser Version nicht (%d, benötigt %d)" - -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Unbekannter Knopfzustand »%s«" - -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "Rahmenstil hat bereits einen Knopf für Funktion %s, Zustand %s" - -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "»%s« ist kein zulässiger Wert für das Attribut focus" - -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "»%s« ist kein zulässiger Wert für das Attribut state" - -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "Es wurde kein Stil namens »%s« definiert" - -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "»%s« ist kein zulässiger Wert für das Attribut »resize«" - -#: ../src/ui/theme-parser.c:3147 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" -"Für die Zustände maximiert/eingerollt sollte es im Element <%s> kein " -"Attribut »resize« geben" - -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "" -"Für maximierte Zustände sollte es im Element <%s> kein Attribut »resize« geben" - -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "Stil wurde bereits für state %s, resize %s, focus %s angegeben" - -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "Stil wurde bereits für state %s, focus %s angegeben" - -#: ../src/ui/theme-parser.c:3294 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Es kann keine zwei draw_ops für ein <piece>-Element geben (das Thema gab ein " -"draw_ops-Attribut und ein <draw_ops>-Element oder zwei Elemente an)" - -#: ../src/ui/theme-parser.c:3332 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Es kann keine zwei draw_ops für ein <button>-Element geben (das Thema gab " -"ein draw_ops-Attribut und ein <draw_ops>-Element oder zwei Elemente an)" - -#: ../src/ui/theme-parser.c:3370 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Es kann keine zwei draw_ops für ein <menu_icon>-Element geben (das Thema gab " -"ein draw_ops-Attribut und ein <draw_ops>-Element oder zwei Elemente an)" - -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "Ungültige Versions-Spezifikation »%s«" - -#: ../src/ui/theme-parser.c:3507 -msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" -msgstr "" -"Das Attribut »version« kann nicht in metacity-theme-1.xml oder metacity-theme-" -"2.xml verwendet werden" - -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "" -"Das Thema benötigt Version %s, aber die neueste unterstützte Themenversion " -"ist %d.%d" - -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "Äußerstes Element im Thema muss <metacity_theme> sein, nicht <%s>" - -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "" -"Element <%s> ist einem name/author/date/description-Element nicht erlaubt" - -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "Element <%s> ist in einem <constant>-Element nicht erlaubt" - -#: ../src/ui/theme-parser.c:3599 -#, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "" -"Element <%s> ist in einem distance/border/aspect_ratio-Element nicht erlaubt" - -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "Element <%s> ist in einem draw_ops-Element nicht erlaubt" - -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "Element <%s> ist in einem <%s>-Element nicht erlaubt" - -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "Keine draw_ops für Rahmenteil angegeben" - -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "Keine draw_ops für Knopf angegeben" - -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "In Element <%s> ist kein Text erlaubt" - -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "<%s> wurde für dieses Thema zweimal angegeben" - -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Es konnte keine gültige Datei für das Thema »%s« gefunden werden\n" - -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "_Fenster" - -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "_Dialogfenster" - -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "_Modales Dialogfenster" - -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "_Werkzeug" - -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "_Begrüßungsbildschirm" - -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "_Oberes Dock" - -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "_Unteres Dock" - -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "_Linkes Dock" - -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "_Rechtes Dock" - -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "_Alle Docks" - -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "Arbeitsfl_äche" - -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "Noch eines dieser Fenster öffnen" - -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "Dies ist ein Demo-Knopf mit einem »Öffnen«-Symbol" - -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "Dies ist ein Demo-Knopf mit einem »Beenden«-Symbol" - -#: ../src/ui/theme-viewer.c:253 -msgid "This is a sample message in a sample dialog" -msgstr "Dies ist eine Beispielnachricht in einem Beispieldialog" - -#: ../src/ui/theme-viewer.c:336 -#, c-format -msgid "Fake menu item %d\n" -msgstr "Pseudo-Menüeintrag %d\n" - -#: ../src/ui/theme-viewer.c:371 -msgid "Border-only window" -msgstr "Fenster ausschließlich mit Rand" - -#: ../src/ui/theme-viewer.c:373 -msgid "Bar" -msgstr "Leiste" - -#: ../src/ui/theme-viewer.c:390 -msgid "Normal Application Window" -msgstr "Normales Anwendungsfenster" - -#: ../src/ui/theme-viewer.c:394 -msgid "Dialog Box" -msgstr "Dialogfenster" - -#: ../src/ui/theme-viewer.c:398 -msgid "Modal Dialog Box" -msgstr "Modales Dialogfenster" - -#: ../src/ui/theme-viewer.c:402 -msgid "Utility Palette" -msgstr "Werkzeugpalette" - -#: ../src/ui/theme-viewer.c:406 -msgid "Torn-off Menu" -msgstr "Abgerissenes Menü" - -#: ../src/ui/theme-viewer.c:410 -msgid "Border" -msgstr "Rand" - -#: ../src/ui/theme-viewer.c:414 -msgid "Attached Modal Dialog" -msgstr "Angehängter modaler Dialog" - -#: ../src/ui/theme-viewer.c:747 -#, c-format -msgid "Button layout test %d" -msgstr "Test der Knopfanordnung %d" - -#: ../src/ui/theme-viewer.c:776 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g Millisekunden zum Zeichnen eines Fensterrahmens" - -#: ../src/ui/theme-viewer.c:821 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Aufruf: metacity-theme-viewer [THEMENNAME]\n" - -#: ../src/ui/theme-viewer.c:828 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "Fehler beim Laden des Themas: %s\n" - -#: ../src/ui/theme-viewer.c:834 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "Thema »%s« in %g Sekunden geladen\n" - -#: ../src/ui/theme-viewer.c:878 -msgid "Normal Title Font" -msgstr "Normale Titelschrift" - -#: ../src/ui/theme-viewer.c:884 -msgid "Small Title Font" -msgstr "Kleine Titelschrift" - -#: ../src/ui/theme-viewer.c:890 -msgid "Large Title Font" -msgstr "Große Titelschrift" - -#: ../src/ui/theme-viewer.c:895 -msgid "Button Layouts" -msgstr "Anordnungen der Knöpfe" - -#: ../src/ui/theme-viewer.c:900 -msgid "Benchmark" -msgstr "Leistungserfassung" - -#: ../src/ui/theme-viewer.c:952 -msgid "Window Title Goes Here" -msgstr "Hierher kommt der Fenstertitel" - -# CHECK - wall clock -#: ../src/ui/theme-viewer.c:1055 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"%d Rahmen in %g Sekunden auf Client-Seite gezeichnet (%g Millisekunden pro " -"Rahmen) bzw. in %g Sekunden Gesamtzeit inkl. X-Server-Ressourcen (%g " -"Millisekunden pro Rahmen).\n" - -#: ../src/ui/theme-viewer.c:1274 -msgid "position expression test returned TRUE but set error" -msgstr "Positionsausdruckstest lieferte WAHR, jedoch auch einen Fehler" - -#: ../src/ui/theme-viewer.c:1276 -msgid "position expression test returned FALSE but didn't set error" -msgstr "Positionsausdruckstest lieferte FALSCH, jedoch keinen Fehler" - -#: ../src/ui/theme-viewer.c:1280 -msgid "Error was expected but none given" -msgstr "Fehler erwartet, jedoch nicht übergeben" - -#: ../src/ui/theme-viewer.c:1282 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "Fehler %d erwartet, jedoch %d übergeben" - -#: ../src/ui/theme-viewer.c:1288 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "Kein Fehler erwartet, jedoch einer übergeben: %s" - -#: ../src/ui/theme-viewer.c:1292 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "X-Wert war %d, %d erwartet" - -#: ../src/ui/theme-viewer.c:1295 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "Y-Wert war %d, %d erwartet" - -#: ../src/ui/theme-viewer.c:1360 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "" -"%d Koordinatenausdrücke in %g Sekunden verarbeitet (im Durchschnitt %g pro " -"Sekunde)\n" diff --git a/po/dz.po b/po/dz.po index 07029e6e2..7cb7cab76 100644 --- a/po/dz.po +++ b/po/dz.po @@ -10,6 +10,7 @@ msgstr "" "PO-Revision-Date: 2007-05-24 23:11+0530\n" "Last-Translator: Tshewang Norbu <bumthap2006@hotmail.com>\n" "Language-Team: DZONGKHA <pgeyleg@dit.gov.bt>\n" +"Language: dz\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" diff --git a/po/el.po b/po/el.po index a420153c9..928937d7a 100644 --- a/po/el.po +++ b/po/el.po @@ -1,4 +1,4 @@ -# Greek translation of Muffin +# Greek translation of Mutter # kostas: 17Jul2003, 412 messages, updated translation for 2.4. # kostas: 30Oct2003,459 messages updated translation for Gnome 2.6. # kostas:03Feb2004, 465 messages update. @@ -12,1998 +12,1611 @@ # kostas: 29Dec2002, updated translation # Nikos: 07Sep2003, Review translation. # Marios Zindilis <m.zindilis@dmajor.org>, 2011. +# Dimitris Spingos (Δημήτρης Σπίγγος) <dmtrs32@gmail.com>, 2013, 2014. +# Efstathios Iosifidis <iosifidis@opensuse.org>, 2015. # msgid "" msgstr "" "Project-Id-Version: metacity.gnome-2-26\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2011-01-19 18:11+0200\n" -"PO-Revision-Date: 2011-01-17 01:05+0200\n" -"Last-Translator: Marios Zindilis <m.zindilis@dmajor.org>\n" -"Language-Team: Greek <team@gnome.gr>\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?" +"product=mutter&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-02-28 06:20+0000\n" +"PO-Revision-Date: 2017-04-07 13:41+0300\n" +"Last-Translator: Tom Tryfonidis <tomtryf@gnome.org>\n" +"Language-Team: Greek, Modern (1453-) <opensuse-translation-el@opensuse.org>\n" "Language: el\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 1.8.11\n" +"X-Project-Style: gnome\n" -#: ../src/core/bell.c:302 -msgid "Bell event" -msgstr "Κουδούνι" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Περιήγηση" -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Άγνωστη αίτηση πληροφοριών παραθύρου: %d" +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Μετακίνηση παραθύρου στον χώρο εργασίας 1" -#. Translators: %s is a window title -#: ../src/core/delete.c:94 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "Το <tt>%s</tt> δεν ανταποκρίνεται." +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Μετακίνηση παραθύρου στον χώρο εργασίας 2" -#: ../src/core/delete.c:99 -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "" -"Μπορείτε να επιλέξετε να περιμένετε λίγο για να συνεχίσει, ή να εξαναγκάσετε " -"την εφαρμογή σε έξοδο." +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Μετακίνηση παραθύρου στον χώρο εργασίας 3" -#: ../src/core/delete.c:108 -msgid "_Wait" -msgstr "_Αναμονή" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Μετακίνηση παραθύρου στον χώρο εργασίας 4" -#: ../src/core/delete.c:108 -msgid "_Force Quit" -msgstr "_Εξαναγκασμός σε τερματισμό" +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Μετακίνηση παραθύρου στον τελευταίο χώρο εργασίας" -#: ../src/core/display.c:365 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "Λείπει η επέκταση %s που απαιτείται για compositing" +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace to the left" +msgstr "Μετακίνηση παραθύρου έναν χώρο εργασίας αριστερά" -# gconf/gconf-internals.c:2416 -#: ../src/core/display.c:431 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Αποτυχία ανοίγματος οθόνης του συστήματος παραθύρων Χ '%s'\n" +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace to the right" +msgstr "Μετακίνηση παραθύρου έναν χώρο εργασίας δεξιά" -#: ../src/core/keybindings.c:759 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "" -"Κάποιο άλλο πρόγραμμα χρησιμοποιεί ήδη το κλειδί %s με μετατροπείς %x ώς " -"δεσμό\n" +#: data/50-mutter-navigation.xml:30 +msgid "Move window one workspace up" +msgstr "Μετακίνηση παραθύρου έναν χώρο εργασίας πάνω" -#. Displayed when a keybinding which is -#. * supposed to launch a program fails. -#. -#: ../src/core/keybindings.c:2459 -#, c-format -msgid "" -"There was an error running <tt>%s</tt>:\n" -"\n" -"%s" -msgstr "" -"Σφάλμα κατά την εκτέλεση του <tt>%s</tt>:\n" -"\n" -"%s" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one workspace down" +msgstr "Μετακίνηση παραθύρου έναν χώρο εργασίας κάτω" -#: ../src/core/keybindings.c:2549 -#, c-format -msgid "No command %d has been defined.\n" -msgstr "Δεν έχει ορισθεί εντολή %d.\n" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor to the left" +msgstr "Μετακίνηση παραθύρου κατά μια οθόνη στα αριστερά" -#: ../src/core/keybindings.c:3561 -#, c-format -msgid "No terminal command has been defined.\n" -msgstr "Δεν έχει ορισθεί εντολή τερματικού.\n" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor to the right" +msgstr "Μετακίνηση παραθύρου κατά μια οθόνη στα δεξιά" -#: ../src/core/main.c:130 -#, c-format -msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" -"muffin %s\n" -"Πνευματικά Δικαιώματα (C) 2001-%d Havoc Pennington, Red Hat, Inc., και " -"άλλοι\n" -"Αυτό είναι ελεύθερο λογισμικό, βλ. τον πηγαίο κώδικα για όρους αντιγραφής.\n" -"ΔΕΝ παρέχεται καμία εγγύηση, ούτε ΕΜΠΟΡΕΥΣΙΜΟΤΗΤΑΣ ούτε ΚΑΤΑΛΛΗΛΟΤΗΤΑΣ ΓΙΑ " -"ΣΥΓΚΕΚΡΙΜΕΝΟΣΚΟΠΟ.\n" +#: data/50-mutter-navigation.xml:42 +msgid "Move window one monitor up" +msgstr "Μετακίνηση παραθύρου κατά μια οθόνη προς τα πάνω" -#: ../src/core/main.c:261 -msgid "Disable connection to session manager" -msgstr "Απενεργοποίηση σύνδεσης στο διαχειριστή συνεδρίας" +#: data/50-mutter-navigation.xml:45 +msgid "Move window one monitor down" +msgstr "Μετακίνηση παραθύρου κατά μια οθόνη προς τα κάτω" -#: ../src/core/main.c:267 -msgid "Replace the running window manager with Muffin" -msgstr "Αντικατάσταση του διαχειριστή παραθύρων που εκτελείται με το Muffin" +#: data/50-mutter-navigation.xml:49 +msgid "Switch applications" +msgstr "Εναλλαγή εφαρμογών" -#: ../src/core/main.c:273 -msgid "Specify session management ID" -msgstr "Καθορισμός ID διαχείρισης συνεδρίας" +#: data/50-mutter-navigation.xml:54 +msgid "Switch to previous application" +msgstr "Εναλλαγή στην προηγούμενη εφαρμογή" -#: ../src/core/main.c:278 -msgid "X Display to use" -msgstr "X Display για χρήση" +#: data/50-mutter-navigation.xml:58 +msgid "Switch windows" +msgstr "Εναλλαγή παραθύρων" -#: ../src/core/main.c:284 -msgid "Initialize session from savefile" -msgstr "Εκκίνηση συνεδρίας από savefile" +#: data/50-mutter-navigation.xml:63 +msgid "Switch to previous window" +msgstr "Εναλλαγή στο προηγούμενο παράθυρο" -#: ../src/core/main.c:290 -msgid "Print version" -msgstr "Εκτύπωση έκδοσης" +#: data/50-mutter-navigation.xml:67 +msgid "Switch windows of an application" +msgstr "Εναλλαγή παραθύρων μιας εφαρμογής" -#: ../src/core/main.c:296 -msgid "Make X calls synchronous" -msgstr "Να καταστούν σύγχρονες οι κλήσεις του X" +#: data/50-mutter-navigation.xml:72 +msgid "Switch to previous window of an application" +msgstr "Εναλλαγή στο προηγούμενο παράθυρο μιας εφαρμογής" -#: ../src/core/main.c:302 -msgid "" -"Don't make fullscreen windows that are maximized and have no decorations" -msgstr "" -"Μην κάνετε παράθυρα πλήρους οθόνης που μεγιστοποιούνται και δεν έχουν " -"διάκοσμο" +#: data/50-mutter-navigation.xml:76 +msgid "Switch system controls" +msgstr "Εναλλαγή ελέγχων συστήματος" -#: ../src/core/main.c:308 -msgid "Comma-separated list of compositor plugins" -msgstr "Λίστα προσθέτων compositor, χωρισμένων με κόμμα" - -#: ../src/core/main.c:314 -msgid "Whether window popup/frame should be shown when cycling windows." -msgstr "" -"Αν θα εμφανίζεται πλαίσιο/αναδυόμενο παράθυρο κατά την κυκλική εναλλαγή " -"παραθύρων." +#: data/50-mutter-navigation.xml:81 +msgid "Switch to previous system control" +msgstr "Εναλλαγή σε προηγούμενους ελέγχους συστήματος" -#: ../src/core/main.c:321 -msgid "Internal argument for GObject introspection" -msgstr "Εσωτερικό όρισμα για την ενδοσκόπηση του GObject" +#: data/50-mutter-navigation.xml:85 +msgid "Switch windows directly" +msgstr "Άμεση εναλλαγή παραθύρων" -#: ../src/core/main.c:648 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Αποτυχία σάρωσης καταλόγου θεμάτων: %s\n" +#: data/50-mutter-navigation.xml:90 +msgid "Switch directly to previous window" +msgstr "Άμεση εναλλαγή στο προηγούμενο παράθυρο" -#: ../src/core/main.c:664 -#, c-format -msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "" -"Δεν είναι δυνατή η εύρεση θέματος! Βεβαιωθείτε ότι το %s υπάρχει και " -"περιέχει τα συνήθη θέματα.\n" +#: data/50-mutter-navigation.xml:94 +msgid "Switch windows of an app directly" +msgstr "Άμεση εναλλαγή παραθύρων μιας εφαρμογής" -#: ../src/core/main.c:725 -#, c-format -msgid "Failed to restart: %s\n" -msgstr "Αποτυχία επανεκκίνησης: %s\n" +#: data/50-mutter-navigation.xml:99 +msgid "Switch directly to previous window of an app" +msgstr "Άμεση εναλλαγή στο προηγούμενο παράθυρο μιας εφαρμογής" -#. -#. * We found it, but it was invalid. Complain. -#. * -#. * FIXME: This replicates the original behaviour, but in the future -#. * we might consider reverting invalid keys to their original values. -#. * (We know the old value, so we can look up a suitable string in -#. * the symtab.) -#. * -#. * (Empty comment follows so the translators don't see this.) -#. -#. -#: ../src/core/prefs.c:541 ../src/core/prefs.c:702 -#, c-format -msgid "GConf key '%s' is set to an invalid value\n" -msgstr "Το GConf key '%s' έχει ορισθεί σε μια μη έγκυρη τιμή\n" +#: data/50-mutter-navigation.xml:103 +msgid "Switch system controls directly" +msgstr "Άμεση εναλλαγή ελέγχων συστήματος" -#: ../src/core/prefs.c:628 ../src/core/prefs.c:871 -#, c-format -msgid "%d stored in GConf key %s is out of range %d to %d\n" -msgstr "" -"Το %d που αποθηκεύτηκε στο κλειδί GConf %s είναι εκτός του εύρους %d έως %d\n" +#: data/50-mutter-navigation.xml:108 +msgid "Switch directly to previous system control" +msgstr "Άμεση εναλλαγή σε προηγούμενους ελέγχους συστήματος" -#: ../src/core/prefs.c:672 ../src/core/prefs.c:749 ../src/core/prefs.c:797 -#: ../src/core/prefs.c:861 ../src/core/prefs.c:1336 ../src/core/prefs.c:1352 -#: ../src/core/prefs.c:1369 ../src/core/prefs.c:1385 -#, c-format -msgid "GConf key \"%s\" is set to an invalid type\n" -msgstr "Ο τύπος που έχει οριστεί για το κλειδί GConf \"%s\" είναι μη έγκυρος\n" +#: data/50-mutter-navigation.xml:111 +msgid "Hide all normal windows" +msgstr "Απόκρυψη όλων των κανονικών παραθύρων" -#: ../src/core/prefs.c:1215 -#, c-format -msgid "GConf key %s is already in use and can't be used to override %s\n" -msgstr "" -"Το κλειδί %s του GConf χρησιμοποιείται ήδη και δεν μπορεί να χρησιμοποιηθεί " -"για παράκαμψη του %s\n" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 1" +msgstr "Εναλλαγή στον χώρο εργασίας 1" -#: ../src/core/prefs.c:1274 -#, c-format -msgid "Can't override GConf key, %s not found\n" -msgstr "Αδυναμία παράκαμψης κλειδιού GConf, δεν βρέθηκε το %s\n" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 2" +msgstr "Εναλλαγή στον χώρο εργασίας 2" -#: ../src/core/prefs.c:1476 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"Οι προσωρινές λύσεις για προβληματικές εφαρμογές έχουν απενεργοποιηθεί. " -"Μερικές εφαρμογές μπορεί να μη συμπεριφέρονται σωστά.\n" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to workspace 3" +msgstr "Εναλλαγή στον χώρο εργασίας 3" -#: ../src/core/prefs.c:1553 -#, c-format -msgid "Could not parse font description \"%s\" from GConf key %s\n" -msgstr "" -"Αδυναμία ανάλυσης περιγραφής γραμματοσειράς \"%s\" από κλειδί GConf %s\n" +#: data/50-mutter-navigation.xml:123 +msgid "Switch to workspace 4" +msgstr "Εναλλαγή στον χώρο εργασίας 4" -#: ../src/core/prefs.c:1615 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"Το \"%s\" που βρέθηκε στη βάση δεδομένων ρυθμίσεων δεν είναι μια έγκυρη τιμή " -"για μετατροπέα κουμπιού ποντικιού\n" +#: data/50-mutter-navigation.xml:126 +msgid "Switch to last workspace" +msgstr "Εναλλαγή στον τελευταίο χώρο εργασίας" -# gconf/gconfd.c:1561 -#: ../src/core/prefs.c:2045 -#, c-format -msgid "Error setting number of workspaces to %d: %s\n" -msgstr "Σφάλμα κατά τον ορισμό αριθμού χώρων εργασίας σε %d: %s\n" +#: data/50-mutter-navigation.xml:129 +msgid "Move to workspace left" +msgstr "Μετακίνηση στον χώρο εργασίας αριστερά" -#: ../src/core/prefs.c:2229 ../src/core/prefs.c:2731 -#, c-format -msgid "Workspace %d" -msgstr "Χώρος εργασίας %d" - -#: ../src/core/prefs.c:2261 ../src/core/prefs.c:2439 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "" -"Το \"%s\" που βρέθηκε στη βάση δεδομένων ρυθμίσεων δεν είναι μια έγκυρη τιμή " -"για συνδυασμό πλήκτρων\"%s\"\n" +#: data/50-mutter-navigation.xml:132 +msgid "Move to workspace right" +msgstr "Μετακίνηση στον χώρο εργασίας δεξιά" -# gconf/gconfd.c:1561 -#: ../src/core/prefs.c:2812 -#, c-format -msgid "Error setting name for workspace %d to \"%s\": %s\n" -msgstr "Σφάλμα κατά τον ορισμό ονόματος χώρου εργασίας %d σε \"%s\": %s\n" +#: data/50-mutter-navigation.xml:135 +msgid "Move to workspace above" +msgstr "Μετακίνηση στον χώρο εργασίας επάνω" -# gconf/gconfd.c:1561 -#: ../src/core/prefs.c:3028 -#, c-format -msgid "Error setting clutter plugin list: %s\n" -msgstr "Σφάλμα κατά τον ορισμό της λίστας προσθέτων του clutter: %s\n" +#: data/50-mutter-navigation.xml:138 +msgid "Move to workspace below" +msgstr "Μετακίνηση στον χώρο εργασίας κάτω" -# gconf/gconfd.c:1561 -#: ../src/core/prefs.c:3072 -#, c-format -msgid "Error setting live hidden windows status status: %s\n" -msgstr "" -"Σφάλμα κατά τον ορισμό της κατάστασης των κρυμμένων ενεργών παραθύρων: %s\n" +#: data/50-mutter-system.xml:6 +msgid "System" +msgstr "Σύστημα" -# gconf/gconfd.c:1561 -#: ../src/core/prefs.c:3100 -#, c-format -msgid "Error setting no tab popup status: %s\n" -msgstr "Σφάλμα κατά τον ορισμό της κατάστασης όχι αναδυόμενων με tab: %s\n" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Εμφάνιση της προτροπής της εντολής run" -#: ../src/core/screen.c:577 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "Η οθόνη %d στην προβολή '%s' δεν είναι έγκυρη\n" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Εμφάνιση της επισκόπησης των δραστηριοτήτων" -#: ../src/core/screen.c:593 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"Η οθόνη %d στην προβολή '%s' έχει ήδη ένα διαχειριστή παραθύρων. Προσπαθήστε " -"να χρησιμοποιήσετε την επιλογή --replace για να αντικαταστήσετε τον τρέχων " -"διαχειριστή παραθύρων.\n" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Παράθυρα" -#: ../src/core/screen.c:620 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "" -"Αδυναμία λήψης επιλογής διαχειριστή παραθύρων στην οθόνη %d προβολή \"%s\"\n" +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "Ενεργοποίηση του μενού παραθύρου" -#: ../src/core/screen.c:675 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "Η οθόνη %d στην προβολή \"%s\" έχει ήδη ένα διαχειριστή παραθύρων\n" +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Εναλλαγή κατάστασης πλήρους οθόνης" -#: ../src/core/screen.c:860 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "Αδυναμία απελευθέρωσης οθόνης %d στην προβολή \"%s\"\n" +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "Εναλλαγή κατάστασης μεγιστοποίησης" -# gconf/gconf-internals.c:2333 -#: ../src/core/session.c:856 ../src/core/session.c:863 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Αδυναμία δημιουργίας καταλόγου '%s': %s\n" +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "Μεγιστοποίηση παραθύρου" -# gconf/gconf-internals.c:789 -#: ../src/core/session.c:873 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "Αδύνατο το άνοιγμα αρχείου συνεδρίας `%s' για εγγραφή: %s\n" +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Επαναφορά παραθύρου" -#: ../src/core/session.c:1014 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Σφάλμα εγγραφής αρχείου συνεδρίας '%s': %s\n" +#: data/50-mutter-windows.xml:18 +msgid "Toggle shaded state" +msgstr "Εναλλαγή σκιασμένης κατάστασης" -# gconf/gconf-backend.c:243 -#: ../src/core/session.c:1019 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Σφάλμα κλεισίματος αρχείου συνεδρίας '%s': %s\n" +#: data/50-mutter-windows.xml:20 +msgid "Close window" +msgstr "Κλείσιμο παραθύρου" -# gconf/gconf-internals.c:2416 -#: ../src/core/session.c:1149 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Αποτυχία ανάλυσης αποθηκευμένου αρχείου συνεδρίας: %s\n" +#: data/50-mutter-windows.xml:22 +msgid "Hide window" +msgstr "Απόκρυψη παραθύρου" -#: ../src/core/session.c:1198 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "" -"βρέθηκε η ιδιότητα <muffin_session> αλλά ήδη έχουμε την ταυτότητα συνεδρίας " +#: data/50-mutter-windows.xml:24 +msgid "Move window" +msgstr "Μετακίνηση παραθύρου" -#: ../src/core/session.c:1211 ../src/core/session.c:1286 -#: ../src/core/session.c:1318 ../src/core/session.c:1390 -#: ../src/core/session.c:1450 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Άγνωστο γνώρισμα %s στο στοιχείο <%s>" +#: data/50-mutter-windows.xml:26 +msgid "Resize window" +msgstr "Αυξομείωση παραθύρου" -#: ../src/core/session.c:1228 -#, c-format -msgid "nested <window> tag" -msgstr "ενσωματωμένη ετικέτα <window>" +#: data/50-mutter-windows.xml:29 +msgid "Toggle window on all workspaces or one" +msgstr "Εναλλαγή παραθύρου σε όλες τις επιφάνειες εργασίας ή σε μία" -#: ../src/core/session.c:1470 -#, c-format -msgid "Unknown element %s" -msgstr "Άγνωστο στοιχείο %s " +#: data/50-mutter-windows.xml:31 +msgid "Raise window if covered, otherwise lower it" +msgstr "Ανύψωση παραθύρου εάν καλύπτεται, αλλιώς βύθισή του" -#: ../src/core/session.c:1822 -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" -"Αυτά τα παράθυρα δεν υποστηρίζουν «αποθήκευση τρέχουσας εγκατάστασης» και θα " -"πρέπει να επανεκκινηθούν χειροκίνητα στην επόμενη είσοδο σας." +#: data/50-mutter-windows.xml:33 +msgid "Raise window above other windows" +msgstr "Ανύψωση παραθύρου πάνω από τα άλλα παράθυρα" -# gconf/gconftool.c:1639 -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Αποτυχία ανοίγματος καταγραφής εκσφαλμάτωσης: %s\n" +#: data/50-mutter-windows.xml:35 +msgid "Lower window below other windows" +msgstr "Βύθιση παραθύρου κάτω από τα άλλα παράθυρα" -# gconf/gconf-internals.c:2416 -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Αποτυχία fdopen() αρχείου καταγραφής %s: %s\n" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window vertically" +msgstr "Μεγιστοποίηση παραθύρου κάθετα" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "Έχει ανοιχθεί το αρχείο καταγραφών %s\n" +#: data/50-mutter-windows.xml:39 +msgid "Maximize window horizontally" +msgstr "Μεγιστοποίηση παραθύρου οριζόντια" -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:179 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "Το Muffin έχει μεταγλωττιστεί χωρίς υποστήριξη για verbose mode\n" - -#: ../src/core/util.c:286 -msgid "Window manager: " -msgstr "Διαχειριστής παραθύρων: " - -#: ../src/core/util.c:434 -msgid "Bug in window manager: " -msgstr "Σφάλμα στο διαχειριστή παραθύρων: " - -#: ../src/core/util.c:467 -msgid "Window manager warning: " -msgstr "Προειδοποίηση διαχειριστή παραθύρων: " - -#: ../src/core/util.c:495 -msgid "Window manager error: " -msgstr "Σφάλμα διαχειριστή παραθύρων: " - -#. Translators: This is the title used on dialog boxes -#. eof all-keybindings.h -#: ../src/core/util.c:616 ../src/muffin.desktop.in.h:1 -#: ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" - -#. first time through -#: ../src/core/window.c:6472 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"Το παράθυρο %s όρισε SM_CLIENT_ID στον εαυτό του, αντί στο παράθυρο του " -"WM_CLIENT_LEADER όπως καθορίζεται στο ICCCM.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7135 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size " -"%d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"Το παράθυρο %s όρισε μια συμβουλή MWM ότι δεν είναι δυνατή η αλλαγή " -"μεγέθους, αλλά όρισε ελάχιστο μέγεθος %d x %d και μέγιστο μέγεθος %d x %d; " -"αυτό είναι ακατανόητο.\n" +#: data/50-mutter-windows.xml:43 +msgid "View split on left" +msgstr "Μεγιστοποίηση στα αριστερά" -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "Η εφαρμογή έθεσε ένα πλαστό _NET_WM_PID %lu\n" +#: data/50-mutter-windows.xml:47 +msgid "View split on right" +msgstr "Μεγιστοποίηση στα δεξιά" -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (σε %s)" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" -#: ../src/core/window-props.c:1478 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "Άκυρο WM_TRANSIENT_FOR παράθυρο 0x%lx που καθορίστηκε για %s.\n" +#: data/org.gnome.mutter.gschema.xml.in:7 +msgid "Modifier to use for extended window management operations" +msgstr "Μετατροπέας για χρήση στις εκτεταμένες ενέργειες διαχείρισης παραθύρων" -#: ../src/core/xprops.c:155 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:8 msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." msgstr "" -"Το παράθυρο 0x%lx έχει ιδιότητα %s\n" -"η οποία αναμενόταν να έχει τύπο %s μορφή %d\n" -"ενώ στην πραγματικότητα έχει τύπο %s μορφή %d n_items %d\n" -"Αυτό πιθανόν να είναι σφάλμα της εφαρμογής και όχι του διαχειριστή " -"παραθύρων.\n" -"Το παράθυρο έχει τίτλο=\"%s\" class=\"%s\" name=\"%s\"\n" - -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "Η ιδιότητα %s στο παράθυρο 0x%lx περιείχε μη έγκυρο UTF-8\n" +"Αυτό το πλήκτρο θα ξεκινήσει την «επικάλυψη», που είναι συνδυασμένο σύστημα " +"επισκόπησης παραθύρων και εκκίνησης εφαρμογών. Η προεπιλογή προτίθεται να " +"είναι το «πλήκτρο Windows» σε μηχανήματα PC. Αναμένεται ότι αυτή η " +"αντιστοίχιση θα είναι είτε η προεπιλογή ή θα ορίζεται στην κενή συμβολοσειρά." -#: ../src/core/xprops.c:494 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:20 +msgid "Attach modal dialogs" +msgstr "Επισύναψη σχηματικών διαλόγων" + +#: data/org.gnome.mutter.gschema.xml.in:21 msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." msgstr "" -"Η ιδιότητα %s στο παράθυρο 0x%lx περιείχε μη έγκυρο UTF-8\n" -" για το αντικείμενο %d στη λίστα\n" - -#: ../src/include/all-keybindings.h:88 -msgid "Switch to workspace 1" -msgstr "Αλλαγή στο χώρο εργασίας 1" - -#: ../src/include/all-keybindings.h:90 -msgid "Switch to workspace 2" -msgstr "Αλλαγή στο χώρο εργασίας 2" - -#: ../src/include/all-keybindings.h:92 -msgid "Switch to workspace 3" -msgstr "Αλλαγή στο χώρο εργασίας 3" - -#: ../src/include/all-keybindings.h:94 -msgid "Switch to workspace 4" -msgstr "Αλλαγή στο χώρο εργασίας 4" - -#: ../src/include/all-keybindings.h:96 -msgid "Switch to workspace 5" -msgstr "Αλλαγή στο χώρο εργασίας 5" - -#: ../src/include/all-keybindings.h:98 -msgid "Switch to workspace 6" -msgstr "Αλλαγή στο χώρο εργασίας 6" - -#: ../src/include/all-keybindings.h:100 -msgid "Switch to workspace 7" -msgstr "Αλλαγή στο χώρο εργασίας 7" - -#: ../src/include/all-keybindings.h:102 -msgid "Switch to workspace 8" -msgstr "Αλλαγή στο χώρο εργασίας 8" - -#: ../src/include/all-keybindings.h:104 -msgid "Switch to workspace 9" -msgstr "Αλλαγή στο χώρο εργασίας 9" - -#: ../src/include/all-keybindings.h:106 -msgid "Switch to workspace 10" -msgstr "Αλλαγή στο χώρο εργασίας 10" - -#: ../src/include/all-keybindings.h:108 -msgid "Switch to workspace 11" -msgstr "Αλλαγή στο χώρο εργασίας 11" - -#: ../src/include/all-keybindings.h:110 -msgid "Switch to workspace 12" -msgstr "Αλλαγή στο χώρο εργασίας 12" - -#: ../src/include/all-keybindings.h:122 -msgid "Switch to workspace on the left of the current workspace" -msgstr "Αλλαγή στο χώρο εργασίας αριστερά του τρέχοντος" - -#: ../src/include/all-keybindings.h:126 -msgid "Switch to workspace on the right of the current workspace" -msgstr "Αλλαγή στο χώρο εργασίας δεξιά του τρέχοντος" - -#: ../src/include/all-keybindings.h:130 -msgid "Switch to workspace above the current workspace" -msgstr "Αλλαγή στο χώρο εργασίας πάνω από τον τρέχοντα" - -#: ../src/include/all-keybindings.h:134 -msgid "Switch to workspace below the current workspace" -msgstr "Αλλαγή στο χώρο εργασίας κάτω από τον τρέχοντα" +"Αν είναι αληθές, αντί για ξεχωριστές μπάρες τίτλου, σχηματικοί διάλογοι " +"εμφανίζονται στην μπάρα τίτλου του γονικού παραθύρου και μετακινούνται μαζί " +"με το γονικό παράθυρο." -#: ../src/include/all-keybindings.h:150 -msgid "Move between windows of an application, using a popup window" +#: data/org.gnome.mutter.gschema.xml.in:30 +msgid "Enable edge tiling when dropping windows on screen edges" msgstr "" -"Μετακίνηση ανάμεσα σε παράθυρα μιας εφαρμογής με τη χρήση αναδυόμενου " -"παραθύρου" +"Ενεργοποίηση της παράθεσης παραθύρων όταν τα μετακινείτε στις άκρες της " +"οθόνης" -#: ../src/include/all-keybindings.h:153 -msgid "Move backward between windows of an application, using a popup window" +#: data/org.gnome.mutter.gschema.xml.in:31 +msgid "" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." msgstr "" -"Μετακίνηση προς τα πίσω ανάμεσα σε παράθυρα μιας εφαρμογής με τη χρήση " -"αναδυόμενου παραθύρου" +"Αν είναι ενεργοποιημένο, με τη μετακίνηση των παραθύρων στις κάθετες πλευρές " +"της οθόνης τα παράθυρα μεγιστοποιούνται και αλλάζουν το μέγεθος τους ώστε να " +"καλύψουν το μισό της οθόνης. Το σύρσιμο των παραθύρων στο πάνω μέρος της " +"οθόνης τα μεγιστοποιεί ολοκληρωτικά." -#: ../src/include/all-keybindings.h:157 -msgid "Move between windows, using a popup window" -msgstr "Μετακίνηση ανάμεσα σε παράθυρα με τη χρήση αναδυόμενου παραθύρου" +#: data/org.gnome.mutter.gschema.xml.in:40 +msgid "Workspaces are managed dynamically" +msgstr "Οι χώροι εργασίας διαχειρίζονται δυναμικά" -#: ../src/include/all-keybindings.h:160 -msgid "Move backward between windows, using a popup window" +#: data/org.gnome.mutter.gschema.xml.in:41 +msgid "" +"Determines whether workspaces are managed dynamically or whether there’s a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." msgstr "" -"Μετακίνηση προς τα πίσω ανάμεσα σε παράθυρα με τη χρήση αναδυόμενου παραθύρου" +"Καθορίζει εάν οι χώροι εργασίας διαχειρίζονται δυναμικά ή υπάρχει ένας " +"στατικός αριθμός χώρων εργασίας (καθορίζεται από το κλειδί num-workspaces " +"στο org.gnome.desktop.wm.preferences)." -#: ../src/include/all-keybindings.h:163 -msgid "Move between panels and the desktop, using a popup window" -msgstr "" -"Μετακίνηση ανάμεσα στους πίνακες εφαρμογών και στην επιφάνεια εργασίας με τη " -"χρήση αναδυόμενου παραθύρου" +#: data/org.gnome.mutter.gschema.xml.in:50 +msgid "Workspaces only on primary" +msgstr "Χώροι εργασίας μόνο στην κύρια" -#: ../src/include/all-keybindings.h:166 -msgid "Move backward between panels and the desktop, using a popup window" +#: data/org.gnome.mutter.gschema.xml.in:51 +msgid "" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." msgstr "" -"Μετακίνηση προς τα πίσω ανάμεσα στους πίνακες εφαρμογών και την επιφάνεια " -"εργασίας με τη χρήση αναδυόμενου παραθύρου" - -#: ../src/include/all-keybindings.h:171 -msgid "Move between windows of an application immediately" -msgstr "Άμεση μετακίνηση ανάμεσα στα παράθυρα μιας εφαρμογής" - -#: ../src/include/all-keybindings.h:174 -msgid "Move backward between windows of an application immediately" -msgstr "Άμεση μετακίνηση προς τα πίσω ανάμεσα στα παράθυρα μιας εφαρμογής" - -#: ../src/include/all-keybindings.h:177 -msgid "Move between windows immediately" -msgstr "Άμεση μετακίνηση ανάμεσα σε παράθυρα" +"Καθορίζει εάν η εναλλαγή των χώρων εργασίας θα συμβαίνει για τα παράθυρα σε " +"όλες τις οθόνες ή μόνο για τα παράθυρα της κύριας οθόνης." -#: ../src/include/all-keybindings.h:180 -msgid "Move backward between windows immediately" -msgstr "Άμεση μετακίνηση προς τα πίσω ανάμεσα σε παράθυρα" +#: data/org.gnome.mutter.gschema.xml.in:59 +msgid "No tab popup" +msgstr "Καμία αναδυόμενη καρτέλα" -#: ../src/include/all-keybindings.h:183 -msgid "Move between panels and the desktop immediately" +#: data/org.gnome.mutter.gschema.xml.in:60 +msgid "" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." msgstr "" -"Άμεση μετακίνηση ανάμεσα στους πίνακες εφαρμογών και στην επιφάνεια εργασίας" +"Καθορίζει αν πρέπει να απενεργοποιηθεί η χρήση της ανάδυσης και επισήμανσης " +"του πλαισίου για την κυκλική εναλλαγή των παραθύρων." -#: ../src/include/all-keybindings.h:186 -msgid "Move backward between panels and the desktop immediately" +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" msgstr "" -"Άμεση μετακίνηση προς τα πίσω ανάμεσα στους πίνακες εφαρμογών και στην " -"επιφάνεια εργασίας." +"Η καθυστέρηση της εστίασης αλλάζει μέχρι ο δείκτης να σταματήσει να κινείται" -#: ../src/include/all-keybindings.h:203 -msgid "Hide all normal windows and set focus to the desktop" +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." msgstr "" -"Απόκρυψη όλων των κανονικών παραθύρων και εστίαση στην επιφάνεια εργασίας" +"Αν οριστεί σε αληθής, και η λειτουργία της εστίασης είναι «sloppy» ή «mouse» " +"τότε η εστίαση δεν θα αλλάξει αμέσως όταν ανοίγετε ένα παράθυρο, αλλά μόνο " +"όταν ο δείκτης σταματήσει να κινείται." -#: ../src/include/all-keybindings.h:206 -msgid "Show the panel's main menu" -msgstr "Εμφάνιση του κύριου μενού του πίνακα εφαρμογών" +#: data/org.gnome.mutter.gschema.xml.in:79 +msgid "Draggable border width" +msgstr "Συρόμενο πλάτος περιγράμματος" -#: ../src/include/all-keybindings.h:209 -msgid "Show the panel's \"Run Application\" dialog box" -msgstr "Εμφάνιση του διαλόγου \"Εκτέλεση εφαρμογής\" του πίνακα εφαρμογών" +#: data/org.gnome.mutter.gschema.xml.in:80 +msgid "" +"The amount of total draggable borders. If the theme’s visible borders are " +"not enough, invisible borders will be added to meet this value." +msgstr "" +"Το ποσό των συνολικών συρόμενων περιγραμμάτων. Αν τα περιγράμματα του " +"θέματος δεν είναι αρκετά, θα προστεθούν αόρατα περιγράμματα για την κάλυψη " +"αυτής της τιμής." -#: ../src/include/all-keybindings.h:211 -msgid "Start or stop recording the session" -msgstr "Έναρξη ή διακοπή καταγραφής συνεδρίας" +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "" +"Αυτόματη μεγιστοποίηση των παραθύρων των οποίων το μέγεθος είναι κοντά με το " +"μέγεθος της οθόνης" -#: ../src/include/all-keybindings.h:252 -msgid "Take a screenshot" -msgstr "Λήψη στιγμιότυπου οθόνης" +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" +"Εάν ενεργοποιηθεί, τα νέα παράθυρα που είναι αρχικά στο μέγεθος της οθόνης " +"μεγιστοποιούνται αυτόματα." -#: ../src/include/all-keybindings.h:254 -msgid "Take a screenshot of a window" -msgstr "Λήψη στιγμιότυπου ενός παραθύρου" +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Τοποθέτηση νέων παραθύρων στο κέντρο" -#: ../src/include/all-keybindings.h:256 -msgid "Run a terminal" -msgstr "Εκτέλεση ενός τερματικού" +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" +"Αν είναι αληθές, τα νέα παράθυρα θα είναι πάντα τοποθετημένα στο κέντρο της " +"κύριας οθόνης." -#: ../src/include/all-keybindings.h:271 -msgid "Activate the window menu" -msgstr "Ενεργοποίηση του μενού του παραθύρου" +#: data/org.gnome.mutter.gschema.xml.in:120 +msgid "Select window from tab popup" +msgstr "Επιλογή παραθύρου από την αναδυόμενη καρτέλα" -#: ../src/include/all-keybindings.h:274 -msgid "Toggle fullscreen mode" -msgstr "Εναλλαγή κατάστασης πλήρους οθόνης" +#: data/org.gnome.mutter.gschema.xml.in:125 +msgid "Cancel tab popup" +msgstr "Ακύρωση αναδυόμενης καρτέλας" -#: ../src/include/all-keybindings.h:276 -msgid "Toggle maximization state" -msgstr "Εναλλαγή κατάστασης μεγιστοποίησης" +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Εναλλαγή στο VT 1 " -#: ../src/include/all-keybindings.h:278 -msgid "Toggle whether a window will always be visible over other windows" -msgstr "Εναλλαγή του αν το παράθυρο θα είναι πάντα ορατό πάνω από τα υπόλοιπα" +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Εναλλαγή στο VT 2" -#: ../src/include/all-keybindings.h:280 -msgid "Maximize window" -msgstr "Μεγιστοποίηση παραθύρου" +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Εναλλαγή στο VT 3" -#: ../src/include/all-keybindings.h:282 -msgid "Restore window" -msgstr "Επαναφορά παραθύρου" +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Εναλλαγή στο VT 4" -#: ../src/include/all-keybindings.h:284 -msgid "Toggle shaded state" -msgstr "Εναλλαγή σκιασμένης κατάστασης" - -#: ../src/include/all-keybindings.h:286 -msgid "Minimize window" -msgstr "Ελαχιστοποίηση παραθύρου" - -#: ../src/include/all-keybindings.h:288 -msgid "Close window" -msgstr "Κλείσιμο παραθύρου" - -#: ../src/include/all-keybindings.h:290 -msgid "Move window" -msgstr "Μετακίνηση παραθύρου" +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Εναλλαγή στο VT 5" -#: ../src/include/all-keybindings.h:292 -msgid "Resize window" -msgstr "Αλλαγή μεγέθους παραθύρου" +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Εναλλαγή στο VT 6" -#: ../src/include/all-keybindings.h:295 -msgid "Toggle whether window is on all workspaces or just one" -msgstr "" -"Εναλλαγή του αν το παράθυρο θα εμφανίζεται σε όλους τους χώρους εργασίας ή " -"μόνο σε έναν" +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Εναλλαγή στο VT 7" -#: ../src/include/all-keybindings.h:299 -msgid "Move window to workspace 1" -msgstr "Μετακίνηση παραθύρου στο χώρο εργασίας 1" +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Εναλλαγή στο VT 8" -#: ../src/include/all-keybindings.h:302 -msgid "Move window to workspace 2" -msgstr "Μετακίνηση παραθύρου στο χώρο εργασίας 2" +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Εναλλαγή στο VT 9" -#: ../src/include/all-keybindings.h:305 -msgid "Move window to workspace 3" -msgstr "Μετακίνηση παραθύρου στο χώρο εργασίας 2" +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Εναλλαγή στο VT 10" -#: ../src/include/all-keybindings.h:308 -msgid "Move window to workspace 4" -msgstr "Μετακίνηση παραθύρου στο χώρο εργασίας 4" +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Εναλλαγή στο VT 11" -#: ../src/include/all-keybindings.h:311 -msgid "Move window to workspace 5" -msgstr "Μετακίνηση παραθύρου στο χώρο εργασίας 5" +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Εναλλαγή στο VT 12" -#: ../src/include/all-keybindings.h:314 -msgid "Move window to workspace 6" -msgstr "Μετακίνηση παραθύρου στο χώρο εργασίας 6" +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. +#. +#: src/backends/meta-input-settings.c:1800 +#, c-format +msgid "Mode Switch (Group %d)" +msgstr "Λειτουργία διακόπτη (ομάδα %d)" -#: ../src/include/all-keybindings.h:317 -msgid "Move window to workspace 7" -msgstr "Μετακίνηση παραθύρου στο χώρο εργασίας 7" +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:1822 +msgid "Switch monitor" +msgstr "Εναλλαγή οθόνης" -#: ../src/include/all-keybindings.h:320 -msgid "Move window to workspace 8" -msgstr "Μετακίνηση παραθύρου στο χώρο εργασίας 8" +#: src/backends/meta-input-settings.c:1824 +msgid "Show on-screen help" +msgstr "Εμφάνιση βοήθειας στην οθόνη" -#: ../src/include/all-keybindings.h:323 -msgid "Move window to workspace 9" -msgstr "Μετακίνηση παραθύρου στο χώρο εργασίας 2" +#: src/backends/meta-monitor-manager.c:675 +msgid "Built-in display" +msgstr "Ενσωματωμένη οθόνη" -#: ../src/include/all-keybindings.h:326 -msgid "Move window to workspace 10" -msgstr "Μετακίνηση παραθύρου στο χώρο εργασίας 10" +#: src/backends/meta-monitor-manager.c:698 +msgid "Unknown" +msgstr "Άγνωστη" -#: ../src/include/all-keybindings.h:329 -msgid "Move window to workspace 11" -msgstr "Μετακίνηση παραθύρου στο χώρο εργασίας 11" +#: src/backends/meta-monitor-manager.c:700 +msgid "Unknown Display" +msgstr "Άγνωστη οθόνη" -#: ../src/include/all-keybindings.h:332 -msgid "Move window to workspace 12" -msgstr "Μετακίνηση παραθύρου στο χώρο εργασίας 12" +#. TRANSLATORS: this is a monitor vendor name, followed by a +#. * size in inches, like 'Dell 15"' +#. +#: src/backends/meta-monitor-manager.c:708 +#, c-format +msgid "%s %s" +msgstr "%s %s" -#: ../src/include/all-keybindings.h:344 -msgid "Move window one workspace to the left" -msgstr "Μετακίνηση του παραθύρου ένα χώρο εργασίας αριστερά" +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:471 +#, c-format +msgid "" +"Another compositing manager is already running on screen %i on display “%s”." +msgstr "" +"Εκτελείται ένας άλλος διαχειριστής παραθύρων στην οθόνη %i προβολή «%s»." -#: ../src/include/all-keybindings.h:347 -msgid "Move window one workspace to the right" -msgstr "Μετακίνηση του παραθύρου ένα χώρο εργασίας δεξιά" +#: src/core/bell.c:194 +msgid "Bell event" +msgstr "Ηχητικό συμβάν κουδουνιού" -#: ../src/include/all-keybindings.h:350 -msgid "Move window one workspace up" -msgstr "Μετακίνηση του παραθύρου ένα χώρο εργασίας πάνω" +#. Translators: %s is a window title +#: src/core/delete.c:127 +#, c-format +msgid "“%s” is not responding." +msgstr "Το “%s” δεν ανταποκρίνεται." -#: ../src/include/all-keybindings.h:353 -msgid "Move window one workspace down" -msgstr "Μετακίνηση του παραθύρου ένα χώρο εργασίας κάτω" +#: src/core/delete.c:129 +msgid "Application is not responding." +msgstr "Η εφαρμογή δεν ανταποκρίνεται." -#: ../src/include/all-keybindings.h:356 -msgid "Raise window if it's covered by another window, otherwise lower it" +#: src/core/delete.c:134 +msgid "" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." msgstr "" -"Ανασήκωση παραθύρου αν είναι καλυμμένο από ένα άλλο παράθυρο, αλλιώς " -"χαμήλωμα του" - -#: ../src/include/all-keybindings.h:358 -msgid "Raise window above other windows" -msgstr "Ανάδυση παραθύρου πάνω από τα άλλα παράθυρα" - -#: ../src/include/all-keybindings.h:360 -msgid "Lower window below other windows" -msgstr "Χαμήλωμα παραθύρου κάτω από τα άλλα παράθυρα" - -#: ../src/include/all-keybindings.h:364 -msgid "Maximize window vertically" -msgstr "Μεγιστοποίηση ενός παραθύρου κάθετα" +"Μπορείτε να επιλέξετε να περιμένετε λίγο για να συνεχίσει, ή να εξαναγκάσετε " +"την εφαρμογή σε έξοδο." -#: ../src/include/all-keybindings.h:368 -msgid "Maximize window horizontally" -msgstr "Μεγιστοποίηση ενός παραθύρου οριζόντια" +#: src/core/delete.c:141 +msgid "_Force Quit" +msgstr "_Εξαναγκασμός σε τερματισμό" -#: ../src/include/all-keybindings.h:372 -msgid "Move window to north-west (top left) corner" -msgstr "Μετακίνηση του παραθύρου στην πάνω αριστερή γωνία" +#: src/core/delete.c:141 +msgid "_Wait" +msgstr "_Αναμονή" -#: ../src/include/all-keybindings.h:375 -msgid "Move window to north-east (top right) corner" -msgstr "Μετακίνηση του παραθύρου στην πάνω δεξιά γωνία" +# gconf/gconf-internals.c:2416 +#: src/core/display.c:608 +#, c-format +msgid "Failed to open X Window System display “%s”\n" +msgstr "Αποτυχία ανοίγματος οθόνης του συστήματος παραθύρων Χ «%s»\n" -#: ../src/include/all-keybindings.h:378 -msgid "Move window to south-west (bottom left) corner" -msgstr "Μετακίνηση του παραθύρου στην κάτω αριστερή γωνία" +#: src/core/main.c:189 +msgid "Disable connection to session manager" +msgstr "Απενεργοποίηση σύνδεσης στο διαχειριστή συνεδρίας" -#: ../src/include/all-keybindings.h:381 -msgid "Move window to south-east (bottom right) corner" -msgstr "Μετακίνηση παραθύρου στην κάτω δεξιά γωνία" +#: src/core/main.c:195 +msgid "Replace the running window manager" +msgstr "Αντικατάσταση του τρέχοντος διαχειριστή παραθύρων" -#: ../src/include/all-keybindings.h:385 -msgid "Move window to north (top) side of screen" -msgstr "Μετακίνηση παραθύρου στην πάνω μεριά της οθόνης" +#: src/core/main.c:201 +msgid "Specify session management ID" +msgstr "Καθορισμός αναγνωριστικού διαχείρισης συνεδρίας" -#: ../src/include/all-keybindings.h:388 -msgid "Move window to south (bottom) side of screen" -msgstr "Μετακίνηση παραθύρου στην κάτω μεριά της οθόνης" +#: src/core/main.c:206 +msgid "X Display to use" +msgstr "Εμφάνιση Χ για χρήση" -#: ../src/include/all-keybindings.h:391 -msgid "Move window to east (right) side of screen" -msgstr "Μετακίνηση παραθύρου στην δεξιά μεριά της οθόνης" +#: src/core/main.c:212 +msgid "Initialize session from savefile" +msgstr "Εκκίνηση συνεδρίας από savefile" -#: ../src/include/all-keybindings.h:394 -msgid "Move window to west (left) side of screen" -msgstr "Μετακίνηση παραθύρου στην αριστερή μεριά της οθόνης" +#: src/core/main.c:218 +msgid "Make X calls synchronous" +msgstr "Να καταστούν σύγχρονες οι κλήσεις του X" -#: ../src/include/all-keybindings.h:397 -msgid "Move window to center of screen" -msgstr "Μετακίνηση παραθύρου στο κέντρο της οθόνης" +#: src/core/main.c:225 +msgid "Run as a wayland compositor" +msgstr "Εκτέλεση ως wayland compositor" -#: ../src/muffin.schemas.in.h:1 -msgid "Attach modal dialogs" -msgstr "Επισύναψη σχηματικών διαλόγων" +#: src/core/main.c:231 +msgid "Run as a nested compositor" +msgstr "Εκτέλεση ως ενσωματωμένος compositor" -#: ../src/muffin.schemas.in.h:2 -msgid "Clutter Plugins" -msgstr "Πρόσθετα του Clutter" +#: src/core/main.c:239 +msgid "Run as a full display server, rather than nested" +msgstr "Εκτέλεση ως διακομιστής πλήρους οθόνης, αντί ενσωματωμένης" -#: ../src/muffin.schemas.in.h:3 +#: src/core/mutter.c:39 +#, c-format msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" msgstr "" -"Καθορίζει αν τα κρυμμένα παράθυρα (δηλ. ελαχιστοποιημένα παράθυρα και " -"παράθυρα σε άλλους χώρους εργασίας εκτός από τον τρέχοντα) θα πρέπει να " -"μένουν ενεργά." - -#: ../src/muffin.schemas.in.h:4 -msgid "Live Hidden Windows" -msgstr "Ενεργά κρυμμένα παράθυρα" +"mutter %s\n" +"Πνευματικά Δικαιώματα © 2001-%d Havoc Pennington, Red Hat, Inc., και άλλοι\n" +"Αυτό είναι ελεύθερο λογισμικό, βλ. τον πηγαίο κώδικα για όρους αντιγραφής.\n" +"ΔΕΝ παρέχεται καμία εγγύηση, ούτε ΕΜΠΟΡΕΥΣΙΜΟΤΗΤΑΣ ούτε ΚΑΤΑΛΛΗΛΟΤΗΤΑΣ ΓΙΑ " +"ΣΥΓΚΕΚΡΙΜΕΝΟ ΣΚΟΠΟ.\n" -#: ../src/muffin.schemas.in.h:5 -msgid "Modifier to use for extended window management operations" -msgstr "Μετατροπέας για χρήση στις εκτεταμένες ενέργειες διαχείρισης παραθύρων" +#: src/core/mutter.c:53 +msgid "Print version" +msgstr "Εμφάνιση έκδοσης" -#: ../src/muffin.schemas.in.h:6 -msgid "Plugins to load for the Clutter-based compositing manager." -msgstr "" -"Πρόσθετα για φόρτωση για τον διαχειριστή σύνθεσης που βασίζεται στο Clutter." +#: src/core/mutter.c:59 +msgid "Mutter plugin to use" +msgstr "Πρόσθετα του Mutter για χρήση" -#: ../src/muffin.schemas.in.h:7 -msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." -msgstr "" -"Αυτό το πλήκτρο θα ξεκινήσει το «overlay», που είναι συνδυασμένο σύστημα " -"επισκόπησης παραθύρων και εκκίνησης εφαρμογών. Η προεπιλογή προτίθεται να " -"είναι το «πλήκτρο Windows» σε μηχανήματα PC. Αναμένεται ότι αυτή η " -"αντιστοίχιση θα είναι είτε η προεπιλογή ή θα ορίζεται στο κενό αλφαριθμητικό." +#: src/core/prefs.c:1997 +#, c-format +msgid "Workspace %d" +msgstr "Χώρος εργασίας %d" -#: ../src/muffin.schemas.in.h:8 +#: src/core/screen.c:580 +#, c-format msgid "" -"When true, instead of having independent titlebars, modal dialogs appear " -"attached to the titlebar of the parent window and are moved together with " -"the parent window." +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." msgstr "" -"Αν είναι αληθές, αντί για ξεχωριστές μπάρες τίτλου, σχηματικοί διάλογοι " -"εμφανίζονται στην μπάρα τίτλου του γονικού παραθύρου και μετακινούνται μαζί " -"με το γονικό παράθυρο." +"Η προβολή «%s» έχει ήδη ένα διαχειριστή παραθύρων· προσπαθήστε να " +"χρησιμοποιήσετε την επιλογή --replace για να αντικαταστήσετε τον τρέχων " +"διαχειριστή παραθύρων." -#: ../src/tools/muffin-message.c:151 +#: src/core/screen.c:665 #, c-format -msgid "Usage: %s\n" -msgstr "Χρήση: %s\n" - -#: ../src/ui/frames.c:1099 -msgid "Close Window" -msgstr "Κλείσιμο παραθύρου" +msgid "Screen %d on display “%s” is invalid\n" +msgstr "Η οθόνη %d στην προβολή «%s» δεν είναι έγκυρη\n" -# -#: ../src/ui/frames.c:1102 -msgid "Window Menu" -msgstr "Μενού παραθύρου" - -#: ../src/ui/frames.c:1105 -msgid "Minimize Window" -msgstr "Ελαχιστοποίηση παραθύρου" +#: src/core/util.c:120 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "" +"Το Mutter έχει μεταγλωττιστεί χωρίς υποστήριξη για λειτουργία εμφάνισης " +"λεπτομερειών\n" -#: ../src/ui/frames.c:1108 -msgid "Maximize Window" -msgstr "Μεγιστοποίηση παραθύρου" +#: src/wayland/meta-wayland-tablet-pad.c:563 +#, c-format +msgid "Mode Switch: Mode %d" +msgstr "Λειτουργία διακόπτη: Λειτουργία %d" -#: ../src/ui/frames.c:1111 -msgid "Restore Window" -msgstr "Επαναφορά παραθύρου" +#: src/x11/session.c:1815 +msgid "" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." +msgstr "" +"Αυτά τα παράθυρα δεν υποστηρίζουν «αποθήκευση της τρέχουσας εγκατάστασης» " +"και θα πρέπει να επανεκκινηθούν χειροκίνητα στην επόμενη είσοδο σας." -#: ../src/ui/frames.c:1114 -msgid "Roll Up Window" -msgstr "Τύλιγμα παραθύρου προς τα πάνω" - -#: ../src/ui/frames.c:1117 -msgid "Unroll Window" -msgstr "Ξετύλιγμα παραθύρου" - -#: ../src/ui/frames.c:1120 -msgid "Keep Window On Top" -msgstr "Διατήρηση παραθύρου σε πρώτο πλάνο" - -#: ../src/ui/frames.c:1123 -msgid "Remove Window From Top" -msgstr "Απομάκρυνση παραθύρου από το πρώτο πλάνο" - -#: ../src/ui/frames.c:1126 -msgid "Always On Visible Workspace" -msgstr "Πάντοτε σε ορατό χώρο εργασία" - -#: ../src/ui/frames.c:1129 -msgid "Put Window On Only One Workspace" -msgstr "Τοποθέτηση παράθυρου μόνο σε ένα χώρο εργασίας" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "Ελα_χιστοποίηση" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "_Μεγιστοποίηση" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "Απόμε_γιστοποίηση" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "Τύλιγμα _πάνω" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "_Ξετύλιγμα" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "_Μετακίνηση" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "Αλλαγή με_γέθους" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "Μετακίνηση μπάρας τίτλου στην ο_θόνη" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "Πάντα σε _πρώτο πλάνο" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "_Ορατό σε όλους τους χώρους εργασίας" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "Μόνο σε _αυτό το χώρο εργασίας" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "Μετακίνηση στο χώρο εργασίας αρι_στερά" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "Μετακίνηση στο χώρο εργασίας δε_ξιά" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "Μετακίνηση παραθύρου στο χώρο εργασίας πά_νω" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "Μετακίνηση στο χώρο εργασίας _κάτω" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "_Κλείσιμο" - -#: ../src/ui/menu.c:204 +#: src/x11/window-props.c:559 #, c-format -msgid "Workspace %d%n" -msgstr "Χώρος εργασίας %d%n" +msgid "%s (on %s)" +msgstr "%s (σε %s)" -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "Χώρος Εργασίας 1_0" +#~ msgid "background texture could not be created from file" +#~ msgstr "η υφή παρασκηνίου δεν μπόρεσε να δημιουργηθεί από αρχείο" -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "Χώρος Εργασίας %s%d" +#~ msgid "Failed to scan themes directory: %s\n" +#~ msgstr "Αποτυχία σάρωσης καταλόγου θεμάτων: %s\n" -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "Μετακίνηση σε άλλο _χώρο εργασίας" +#~ msgid "" +#~ "Could not find a theme! Be sure %s exists and contains the usual themes.\n" +#~ msgstr "" +#~ "Δεν είναι δυνατή η εύρεση θέματος! Βεβαιωθείτε ότι το %s υπάρχει και " +#~ "περιέχει τα συνήθη θέματα.\n" -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" +#~ msgid "Screen %d on display \"%s\" already has a window manager\n" +#~ msgstr "Η οθόνη %d στην προβολή \"%s\" έχει ήδη ένα διαχειριστή παραθύρων\n" # -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" +#~ msgid "%d x %d" +#~ msgstr "%d x %d" + +#~ msgid "top" +#~ msgstr "επάνω" + +#~ msgid "bottom" +#~ msgstr "κάτω" + +#~ msgid "left" +#~ msgstr "αριστερά" + +#~ msgid "right" +#~ msgstr "δεξιά" + +#~ msgid "frame geometry does not specify \"%s\" dimension" +#~ msgstr "η γεωμετρία πλαισίου δεν έχει καθορίσει \"%s\" διάσταση" + +#~ msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" +#~ msgstr "" +#~ "η γεωμετρία πλαισίου δεν έχει καθορίσει \"%s\" διάσταση για περίγραμμα " +#~ "\"%s\"" + +#~ msgid "Button aspect ratio %g is not reasonable" +#~ msgstr "Η αναλογία διαστάσεων κουμπιού %g δεν είναι λογική" + +#~ msgid "Frame geometry does not specify size of buttons" +#~ msgstr "Η γεωμετρία πλαισίου δεν έχει καθορίσει μέγεθος κουμπιών" + +#~ msgid "Gradients should have at least two colors" +#~ msgstr "Τα διαβαθμισμένα χρώματα θα πρέπει να έχουν δύο τουλάχιστον θέματα" + +#~ msgid "" +#~ "GTK custom color specification must have color name and fallback in " +#~ "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" +#~ msgstr "" +#~ "Ο καθορισμός προσαρμοσμένου χρώματος GTK θα πρέπει να έχει το όνομα του " +#~ "χρώματος και το υποκατάστατο σε παρενθέσεις. π.χ gtk:custom(foo,bar)· " +#~ "αδυναμία ανάλυσης \"%s\"" + +#~ msgid "" +#~ "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-" +#~ "z0-9-_ are valid" +#~ msgstr "" +#~ "Μη έγκυρος χαρακτήρας '%c' στη παράμετρο color_name του gtk:custom, μόνο " +#~ "τα A-Za-z0-9-_ είναι έγκυρα" + +#~ msgid "" +#~ "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " +#~ "fit the format" +#~ msgstr "" +#~ "Ο τύπος σκίασης είναι \"gtk:custom(color_name,fallback)\", το \"%s\" δεν " +#~ "ταιριάζει στον τύπο" + +#~ msgid "" +#~ "GTK color specification must have the state in brackets, e.g. gtk:" +#~ "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "Ο καθορισμός χρώματος GTK θα πρέπει να έχει τη κατάσταση σε αγκύλες, π.χ " +#~ "gtk:fg[NORMAL] όπου NORMAL είναι η κατάσταση· αδυναμία ανάλυσης \"%s\"" + +#~ msgid "" +#~ "GTK color specification must have a close bracket after the state, e.g. " +#~ "gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "Ο καθορισμός χρώματος GTK θα πρέπει να έχει μια αγκύλη κλεισίματος μετά " +#~ "την κατάσταση, π.χ gtk:fg[NORMAL] όπου NORMAL είναι η κατάσταση· αδυναμία " +#~ "ανάλυσης \"%s\"" + +#~ msgid "Did not understand state \"%s\" in color specification" +#~ msgstr "Δεν έγινε κατανοητή η κατάσταση \"%s\" στον ορισμό χρώματος" + +#~ msgid "Did not understand color component \"%s\" in color specification" +#~ msgstr "" +#~ "Δεν έγινε κατανοητό το συστατικό χρώματος \"%s\" στον ορισμό χρώματος" + +#~ msgid "" +#~ "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit " +#~ "the format" +#~ msgstr "" +#~ "Ο τύπος ανάμιξης που είναι \"blend/bg_color/fg_color/alpha\", \"%s\" δεν " +#~ "ταιριάζει στη διαμόρφωση" + +#~ msgid "Could not parse alpha value \"%s\" in blended color" +#~ msgstr "Αδυναμία ανάλυσης τιμής alpha \"%s\" στο αναμεμιγμένο χρώμα" + +#~ msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" +#~ msgstr "" +#~ "Η τιμή Alpha \"%s\" στο αναμεμιγμένο χρώμα δεν είναι ανάμεσα σε 0.0 και " +#~ "1.0" + +#~ msgid "" +#~ "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the " +#~ "format" +#~ msgstr "" +#~ "Ο τύπος σκίασης είναι \"shade/base_color/factor\", το \"%s\" δεν " +#~ "ταιριάζει στον τύπο" + +#~ msgid "Could not parse shade factor \"%s\" in shaded color" +#~ msgstr "Αδυναμία ανάλυσης παράγοντα σκίασης \"%s\" στο σκιασμένο χρώμα" + +#~ msgid "Shade factor \"%s\" in shaded color is negative" +#~ msgstr "Ο παράγοντας σκίασης \"%s\" στο σκιασμένο χρώμα είναι αρνητικός" + +#~ msgid "Could not parse color \"%s\"" +#~ msgstr "Αδύνατη η ανάλυση χρώματος \"%s\"" + +#~ msgid "Coordinate expression contains character '%s' which is not allowed" +#~ msgstr "" +#~ "Η συντεταγμένη έκφραση περιέχει ένα χαρακτήρα '%s' που δεν επιτρέπεται" + +#~ msgid "" +#~ "Coordinate expression contains floating point number '%s' which could not " +#~ "be parsed" +#~ msgstr "" +#~ "Η συντεταγμένη έκφραση περιέχει αριθμό κινητού σημείου '%s' που δεν " +#~ "μπορεί να αναλυθεί" + +#~ msgid "" +#~ "Coordinate expression contains integer '%s' which could not be parsed" +#~ msgstr "" +#~ "Η συντεταγμένη έκφραση περιέχει έναν ακέραιο '%s' που δεν μπορεί να " +#~ "αναλυθεί" + +#~ msgid "" +#~ "Coordinate expression contained unknown operator at the start of this " +#~ "text: \"%s\"" +#~ msgstr "" +#~ "Η συντεταγμένη έκφραση περιείχε έναν άγνωστο τελεστή στην αρχή αυτού του " +#~ "κειμένου: \"%s\"" + +#~ msgid "Coordinate expression was empty or not understood" +#~ msgstr "Η συντεταγμένη έκφραση ήταν κενή ή δεν έγινε κατανοητή" + +#~ msgid "Coordinate expression results in division by zero" +#~ msgstr "Η συντεταγμένη έκφραση έχει σαν αποτέλεσμα διαίρεση με το μηδέν" + +#~ msgid "" +#~ "Coordinate expression tries to use mod operator on a floating-point number" +#~ msgstr "" +#~ "Η συντεταγμένη έκφραση προσπαθεί να χρησιμοποίησε τελεστή mod σε αριθμό " +#~ "κινητής υποδιαστολής" + +#~ msgid "" +#~ "Coordinate expression has an operator \"%s\" where an operand was expected" +#~ msgstr "" +#~ "Η συντεταγμένη έκφραση έχει έναν τελεστή \"%s\" ενώ αναμενόταν τελεστέος" + +#~ msgid "Coordinate expression had an operand where an operator was expected" +#~ msgstr "Η συντεταγμένη έκφραση έχει ένα τελεστέο ενώ αναμενόταν τελεστής" + +#~ msgid "Coordinate expression ended with an operator instead of an operand" +#~ msgstr "Η συντεταγμένη έκφραση τέλειωσε με τελεστή αντί για τελεστέο" + +#~ msgid "" +#~ "Coordinate expression has operator \"%c\" following operator \"%c\" with " +#~ "no operand in between" +#~ msgstr "" +#~ "Η συντεταγμένη έκφραση έχει τελεστή \"%c\" που ακολουθεί έναν τελεστή \"%c" +#~ "\" χωρίς τελεστέο μεταξύ τους" + +#~ msgid "Coordinate expression had unknown variable or constant \"%s\"" +#~ msgstr "Η συντεταγμένη έκφραση έχει άγνωστη μεταβλητή ή συνεχής \"%s\"" + +#~ msgid "Coordinate expression parser overflowed its buffer." +#~ msgstr "" +#~ "Ο αναλυτής της έκφρασης συντεταγμένης υπερχείλισε την ενδιάμεση μνήμη του." + +#~ msgid "" +#~ "Coordinate expression had a close parenthesis with no open parenthesis" +#~ msgstr "" +#~ "Η συντεταγμένη έκφραση έχει μια παρένθεση κλεισίματος χωρίς να έχει " +#~ "ανοιχθεί παρένθεση" + +#~ msgid "" +#~ "Coordinate expression had an open parenthesis with no close parenthesis" +#~ msgstr "" +#~ "Η συντεταγμένη έκφραση έχει μια παρένθεση ανοίγματος χωρίς να έχει " +#~ "κλεισθεί παρένθεση" + +#~ msgid "Coordinate expression doesn't seem to have any operators or operands" +#~ msgstr "Η συντεταγμένη έκφραση δεν φαίνεται να έχει τελεστές ή τελεστέους" + +#~ msgid "Theme contained an expression that resulted in an error: %s\n" +#~ msgstr "Το θέμα περιείχε μια έκφραση που είχε σαν αποτέλεσμα σφάλμα: %s\n" + +#~ msgid "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " +#~ "specified for this frame style" +#~ msgstr "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> θα πρέπει να " +#~ "καθοριστεί σε αυτό το στυλ πλαισίου" + +#~ msgid "" +#~ "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/" +#~ ">" +#~ msgstr "" +#~ "Λείπει <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" + +#~ msgid "Failed to load theme \"%s\": %s\n" +#~ msgstr "Αποτυχία φόρτωσης θέματος \"%s\": %s\n" -#: ../src/ui/theme.c:255 -msgid "top" -msgstr "επάνω" +# gconf/gconftool.c:877 +#~ msgid "No <%s> set for theme \"%s\"" +#~ msgstr "Δεν έχει ορισθεί <%s> για θέμα \"%s\"" -#: ../src/ui/theme.c:257 -msgid "bottom" -msgstr "κάτω" +#~ msgid "" +#~ "No frame style set for window type \"%s\" in theme \"%s\", add a <window " +#~ "type=\"%s\" style_set=\"whatever\"/> element" +#~ msgstr "" +#~ "Δεν έχει ορισθεί στυλ πλαισίου για τον τύπο παραθύρου \"%s\" στο θέμα \"%s" +#~ "\", προσθέστε ένα <window type=\"%s\" style_set=\"whatever\"/> στοιχείο" -#: ../src/ui/theme.c:259 -msgid "left" -msgstr "αριστερά" +#~ msgid "" +#~ "User-defined constants must begin with a capital letter; \"%s\" does not" +#~ msgstr "" +#~ "Οι συνεχείς που ορίζονται από το χρήστη θα πρέπει να ξεκινάνε με κεφαλαίο " +#~ "γράμμα, η \"%s\" δεν έχει" -#: ../src/ui/theme.c:261 -msgid "right" -msgstr "δεξιά" +#~ msgid "Constant \"%s\" has already been defined" +#~ msgstr "Constant \"%s\" έχει ήδη καθορισθεί" -#: ../src/ui/theme.c:288 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "η γεωμετρία πλαισίου δεν έχει καθορίσει \"%s\" διάσταση" +#~ msgid "No \"%s\" attribute on element <%s>" +#~ msgstr "Δεν υπάρχει γνώρισμα \"%s\" για το στοιχείο <%s>" -#: ../src/ui/theme.c:307 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "" -"η γεωμετρία πλαισίου δεν έχει καθορίσει \"%s\" διάσταση για περίγραμμα \"%s\"" +#~ msgid "Line %d character %d: %s" +#~ msgstr "Γραμμή %d χαρακτήρας %d: %s" -#: ../src/ui/theme.c:344 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "Η αναλογία διαστάσεων κουμπιού %g δεν είναι λογική" +#~ msgid "Attribute \"%s\" repeated twice on the same <%s> element" +#~ msgstr "Το γνώρισμα \"%s\" επαναλήφθηκε δυο φορές στο ίδιο <%s> στοιχείο" -#: ../src/ui/theme.c:356 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "Η γεωμετρία πλαισίου δεν έχει καθορίσει μέγεθος κουμπιών" +#~ msgid "Attribute \"%s\" is invalid on <%s> element in this context" +#~ msgstr "" +#~ "Το γνώρισμα \"%s\" δεν είναι έγκυρο στο στοιχείο <%s> σε αυτήν την " +#~ "περίπτωση" -#: ../src/ui/theme.c:1064 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "Τα διαβαθμισμένα χρώματα θα πρέπει να έχουν δύο τουλάχιστον θέματα" +#~ msgid "Could not parse \"%s\" as an integer" +#~ msgstr "Αδύνατη η ανάλυση του \"%s\" ως ακέραιο αριθμό" -#: ../src/ui/theme.c:1202 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"Ο καθορισμός χρώματος GTK θα πρέπει να έχει τη κατάσταση σε αγκύλες, π.χ gtk:" -"fg[NORMAL] όπου NORMAL είναι η κατάσταση. Αδυναμία ανάλυσης \"%s\"" +#~ msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +#~ msgstr "" +#~ "Δεν έγινε κατανοητή η ακολουθία χαρακτήρων \"%s\" στην συμβολοσειρά \"%s\"" -#: ../src/ui/theme.c:1216 -#, c-format -msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"Ο καθορισμός χρώματος GTK θα πρέπει να έχει μια αγκύλη κλεισίματος μετά την " -"κατάσταση. π.χ gtk:fg[NORMAL] όπου NORMAL είναι η κατάσταση. Αδυναμία " -"ανάλυσης \"%s\"" +#~ msgid "Integer %ld must be positive" +#~ msgstr "Ο ακέραιος %ld θα πρέπει να είναι θετικός" -#: ../src/ui/theme.c:1227 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "Δεν έγινε κατανοητή η κατάσταση \"%s\" στον ορισμό χρώματος" +#~ msgid "Integer %ld is too large, current max is %d" +#~ msgstr "Ο ακέραιος %ld είναι πολύ μεγάλος, μέγιστος δυνατός %d" -#: ../src/ui/theme.c:1240 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "Δεν έγινε κατανοητό το συστατικό χρώματος \"%s\" στον ορισμό χρώματος" +#~ msgid "Could not parse \"%s\" as a floating point number" +#~ msgstr "Αδυναμία ανάλυσης \"%s\" ως αριθμό κινητού σημείου" -#: ../src/ui/theme.c:1270 -#, c-format -msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" -msgstr "" -"Ο τύπος ανάμιξης που είναι \"blend/bg_color/fg_color/alpha\", \"%s\" δεν " -"ταιριάζει στη διαμόρφωση" +#~ msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" +#~ msgstr "" +#~ "Οι λογικές τιμές θα πρέπει να είναι είτε \"true\" ή \"false\" όχι \"%s\"" -#: ../src/ui/theme.c:1281 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "Αδυναμία ανάλυσης τιμής alpha \"%s\" στο αναμεμιγμένο χρώμα" +#~ msgid "Angle must be between 0.0 and 360.0, was %g\n" +#~ msgstr "Η γωνία θα πρέπει να είναι ανάμεσα σε 0.0 και 360.0, ήταν %g\n" -#: ../src/ui/theme.c:1291 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "" -"Η τιμή Alpha \"%s\" στο αναμεμιγμένο χρώμα δεν είναι ανάμεσα σε 0.0 και 1.0" +#~ msgid "" +#~ "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" +#~ msgstr "" +#~ "Το Άλφα θα πρέπει να είναι ανάμεσα σε 0.0 (αόρατο) και 1.0 (πλήρης " +#~ "ορατό), ήταν %g\n" -#: ../src/ui/theme.c:1338 -#, c-format -msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "" -"Ο τύπος σκίασης είναι \"shade/base_color/factor\", το \"%s\" δεν ταιριάζει " -"στον τύπο" +#~ msgid "" +#~ "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," +#~ "large,x-large,xx-large)\n" +#~ msgstr "" +#~ "Μή έγκυρη κλίμακα τίτλου \"%s\" (θα πρέπει να είναι ενα από xx-small,x-" +#~ "small,small,medium,large,x-large,xx-large)\n" -#: ../src/ui/theme.c:1349 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "Αδυναμία ανάλυσης παράγοντα σκίασης \"%s\" στο σκιασμένο χρώμα" +#~ msgid "<%s> name \"%s\" used a second time" +#~ msgstr "Το <%s> όνομα \"%s\" χρησιμοποιήθηκε για δεύτερη φορά" -#: ../src/ui/theme.c:1359 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "Ο παράγοντας σκίασης \"%s\" στο σκιασμένο χρώμα είναι αρνητικός" +#~ msgid "<%s> parent \"%s\" has not been defined" +#~ msgstr "<%s> μητρικό \"%s\" δεν έχει ορισθεί" -#: ../src/ui/theme.c:1388 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Αδύνατη η ανάλυση χρώματος \"%s\"" +#~ msgid "<%s> geometry \"%s\" has not been defined" +#~ msgstr "<%s> γεωμετρία \"%s\" δεν έχει ορισθεί" -#: ../src/ui/theme.c:1646 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "Η συντεταγμένη έκφραση περιέχει ένα χαρακτήρα '%s που δεν επιτρέπεται" +#~ msgid "<%s> must specify either a geometry or a parent that has a geometry" +#~ msgstr "" +#~ "<%s> θα πρέπει να καθορίσετε είτε μια γεωμετρία είτε ένα μητρικό που έχει " +#~ "γεωμετρία" -#: ../src/ui/theme.c:1673 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "" -"Η συντεταγμένη έκφραση περιέχει αριθμό κινητού σημείου '%s' που δεν μπορεί " -"να αναλυθεί" +#~ msgid "You must specify a background for an alpha value to be meaningful" +#~ msgstr "Πρέπει να καθορίσετε ένα παρασκήνιο για να έχει νόημα μια τιμή άλφα" -#: ../src/ui/theme.c:1687 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "" -"Η συντεταγμένη έκφραση περιέχει έναν ακέραιο '%s που δεν μπορεί να αναλυθεί" +#~ msgid "Unknown type \"%s\" on <%s> element" +#~ msgstr "Άγνωστος τύπος \"%s\" στο στοιχείο <%s>" -#: ../src/ui/theme.c:1809 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "" -"Η συντεταγμένη έκφραση περιείχε έναν άγνωστο χειριστή στην αρχή αυτού του " -"κειμένου: \"%s\"" +#~ msgid "Unknown style_set \"%s\" on <%s> element" +#~ msgstr "Άγνωστο style_set \"%s\" στο στοιχείο <%s>" -#: ../src/ui/theme.c:1866 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "Η συντεταγμένη έκφραση ήταν κενή ή δεν έγινε κατανοητή" +#~ msgid "Window type \"%s\" has already been assigned a style set" +#~ msgstr "Έχει ορισθεί ήδη ένα στυλ για τον τύπο παραθύρου \"%s\"" -#: ../src/ui/theme.c:1977 ../src/ui/theme.c:1987 ../src/ui/theme.c:2021 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "Η συντεταγμένη έκφραση έχει σαν αποτέλεσμα διαίρεση με το μηδέν" +#~ msgid "Element <%s> is not allowed below <%s>" +#~ msgstr "Το στοιχείο <%s> δεν επιτρέπεται κάτω από <%s>" -#: ../src/ui/theme.c:2029 -#, c-format -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "" -"Η συντεταγμένη έκφραση προσπαθεί να χρησιμοποίησε ιmod operator σε αριθμό " -"κινητού σημείου" +#~ msgid "" +#~ "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio" +#~ "\" for buttons" +#~ msgstr "" +#~ "Δεν είναι δυνατός ο καθορισμός των \"button_width\"/\"button_height\" και " +#~ "\"aspect_ratio\" για τα κουμπιά" -#: ../src/ui/theme.c:2085 -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "" -"Η συντεταγμένη έκφραση έχει ένα operator \"%s\" ενώ αναμενόταν operand " +#~ msgid "Distance \"%s\" is unknown" +#~ msgstr "Η απόσταση \"%s\" είναι άγνωστη" -#: ../src/ui/theme.c:2094 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "Η συντεταγμένη έκφραση έχει ένα operand ενώ αναμενόταν operator" +#~ msgid "Aspect ratio \"%s\" is unknown" +#~ msgstr "Η αναλογία διαστάσεων \"%s\" είναι άγνωστη" -#: ../src/ui/theme.c:2102 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "Η συντεταγμένη έκφραση τέλειωσε με χειριστή αντί για operand" +#~ msgid "Border \"%s\" is unknown" +#~ msgstr "Το περίγραμμα \"%s\" είναι άγνωστο" -#: ../src/ui/theme.c:2112 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" -"Η συντεταγμένη έκφραση έχει operator \"%c\" ακολουθούμενο operator \"%c\" " -"χωρίς operand μεταξύ τους" +#~ msgid "No \"start_angle\" or \"from\" attribute on element <%s>" +#~ msgstr "" +#~ "Δεν υπάρχει γνώρισμα \"start_angle\" ή \"from\" για το στοιχείο <%s>" -#: ../src/ui/theme.c:2263 ../src/ui/theme.c:2308 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "Η συντεταγμένη έκφραση έχει άγνωστη μεταβλητή ή συνεχής \"%s\"" +#~ msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" +#~ msgstr "Δεν υπάρχει γνώρισμα \"extent_angle\" ή \"to\" για το στοιχείο <%s>" -#: ../src/ui/theme.c:2362 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "Η συντεταγμένη έκφραση ήταν κενή ή δεν έγινε κατανοητή" +#~ msgid "Did not understand value \"%s\" for type of gradient" +#~ msgstr "Δεν έγινε κατανοητή η τιμή \"%s\" για τον τύπο της διαβάθμισης" -#: ../src/ui/theme.c:2391 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "" -"Η συντεταγμένη έκφραση έχει μια παρένθεση κλεισίματος χωρίς να έχει ανοιχθεί " -"παρένθεση" +#~ msgid "Did not understand fill type \"%s\" for <%s> element" +#~ msgstr "Δεν έγινε κατανοητός ο τύπος γεμίσματος \"%s\" για <%s> στοιχείο" -#: ../src/ui/theme.c:2455 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "" -"Η συντεταγμένη έκφραση έχει μια παρένθεση ανοίγματος χωρίς να έχει κλεισθεί " -"παρένθεση" +#~ msgid "Did not understand state \"%s\" for <%s> element" +#~ msgstr "Δεν έγινε κατανοητή η κατάσταση \"%s\" για στοιχείο <%s>" -#: ../src/ui/theme.c:2466 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "Η συντεταγμένη έκφραση δεν φαίνεται να έχει operators ή operands" +#~ msgid "Did not understand shadow \"%s\" for <%s> element" +#~ msgstr "Δεν έγινε κατανοητή η σκίαση \"%s\" για στοιχείο <%s>" -#: ../src/ui/theme.c:2676 ../src/ui/theme.c:2696 ../src/ui/theme.c:2716 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "Το θέμα περιείχε μια έκφραση που είχε σαν αποτέλεσμα σφάλμα: %s\n" +#~ msgid "Did not understand arrow \"%s\" for <%s> element" +#~ msgstr "Δεν έγινε κατανοητό το βέλος \"%s\" για στοιχείο <%s>" -#: ../src/ui/theme.c:4410 -#, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> θα πρέπει να " -"καθοριστεί στο στυλ πλαισίου" +#~ msgid "No <draw_ops> called \"%s\" has been defined" +#~ msgstr "Δεν έχουν ορισθεί <draw_ops> που ονομάζονται \"%s\"" -#: ../src/ui/theme.c:4940 ../src/ui/theme.c:4965 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" -"Λείπει <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" +#~ msgid "Including draw_ops \"%s\" here would create a circular reference" +#~ msgstr "" +#~ "Αν συμπεριλάβετε εδώ λειτουργίες_σχεδίασης \"%s\" θα δημιουργήσετε μια " +#~ "κυκλική αναφορά" -#: ../src/ui/theme.c:5013 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Αποτυχία φόρτωσης θέματος \"%s\": %s\n" +#~ msgid "Unknown position \"%s\" for frame piece" +#~ msgstr "Άγνωστη θέση \"%s\" για το κομμάτι πλαισίου" -# gconf/gconftool.c:877 -#: ../src/ui/theme.c:5149 ../src/ui/theme.c:5156 ../src/ui/theme.c:5163 -#: ../src/ui/theme.c:5170 ../src/ui/theme.c:5177 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "Δεν έχει ορισθεί <%s> για θέμα \"%s\"" +#~ msgid "Frame style already has a piece at position %s" +#~ msgstr "Το στυλ πλαισίου έχει ήδη ένα κομμάτι στην θέση %s" -#: ../src/ui/theme.c:5185 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" -"Δεν έχει ορισθεί στύλ πλαισίου για τον τύπο παραθύρου \"%s\" στο θέμα \"%s" -"\", add a <window type=\"%s\" style_set=\"whatever\"/> element" +#~ msgid "No <draw_ops> with the name \"%s\" has been defined" +#~ msgstr "Δεν έχουν ορισθεί <draw_ops> με το όνομα \"%s\"" -#: ../src/ui/theme.c:5635 ../src/ui/theme.c:5697 ../src/ui/theme.c:5760 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" -"Οι συνεχείς που ορίζονται από το χρήστη θα πρέπει να ξεκινάνε με κεφαλαίο " -"γράμμα, η \"%s\" δεν έχει" +#~ msgid "Unknown function \"%s\" for button" +#~ msgstr "Άγνωστη λειτουργία \"%s\" για το κουμπί" -#: ../src/ui/theme.c:5643 ../src/ui/theme.c:5705 ../src/ui/theme.c:5768 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "Constant \"%s\" έχει ήδη καθορισθεί" +#~ msgid "Button function \"%s\" does not exist in this version (%d, need %d)" +#~ msgstr "" +#~ "Η λειτουργία \"%s\" του κουμπιού δεν υπάρχει σε αυτή την έκδοση (%d, " +#~ "χρειάζεται %d)" -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. -#. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "Δεν υπάρχει γνώρισμα \"%s\" για το στοιχείο <%s>" +# +#~ msgid "Unknown state \"%s\" for button" +#~ msgstr "Άγνωστη κατάσταση \"%s\" για το κουμπί" + +#~ msgid "Frame style already has a button for function %s state %s" +#~ msgstr "" +#~ "Το στυλ πλαισίου έχει ήδη ένα κουμπί για τη λειτουργία %s κατάσταση %s" + +#~ msgid "\"%s\" is not a valid value for focus attribute" +#~ msgstr "\"%s\" δεν είναι έγκυρη τιμή για το γνώρισμα εστίασης" + +#~ msgid "\"%s\" is not a valid value for state attribute" +#~ msgstr "\"%s\" δεν είναι έγκυρη τιμή για το γνώρισμα κατάστασης" + +#~ msgid "A style called \"%s\" has not been defined" +#~ msgstr "Το στυλ που ονομάζεται \"%s\" δεν έχει ορισθεί" + +#~ msgid "\"%s\" is not a valid value for resize attribute" +#~ msgstr "\"%s\" δεν είναι έγκυρη τιμή για το γνώρισμα αλλαγής μεγέθους" + +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized/shaded " +#~ "states" +#~ msgstr "" +#~ "Δεν πρέπει να υπάρχει γνώρισμα \"resize\" στο στοιχείο <%s> για " +#~ "μεγιστοποιημένες/σκιασμένες καταστάσεις" + +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized states" +#~ msgstr "" +#~ "Δεν πρέπει να υπάρχει γνώρισμα \"resize\" στο στοιχείο <%s> για " +#~ "μεγιστοποιημένες καταστάσεις" + +#~ msgid "Style has already been specified for state %s resize %s focus %s" +#~ msgstr "" +#~ "Το στυλ έχει ήδη καθορισθεί για κατάσταση %s αλλαγή μεγέθους %s εστίαση %s" + +#~ msgid "Style has already been specified for state %s focus %s" +#~ msgstr "Το στυλ έχει ήδη καθορισθεί για κατάσταση %s εστίαση %s" + +#~ msgid "" +#~ "Can't have a two draw_ops for a <piece> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Δεν μπορεί να υπάρχουν δυο λειτουργίες_σχεδίασης για ένα στοιχείο <piece> " +#~ "( το θέμα έχει καθορίσει ένα γνώρισμα λειτουργίας_σχεδίασης και ακόμα ένα " +#~ "στοιχείο <draw_ops> ή καθόρισε δύο στοιχεία)" + +#~ msgid "" +#~ "Can't have a two draw_ops for a <button> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Δεν μπορεί να υπάρχουν δυο λειτουργίες_σχεδίασης για ένα στοιχείο " +#~ "<button> ( το θέμα έχει καθορίσει ένα γνώρισμα λειτουργίας_σχεδίασης και " +#~ "ακόμα ένα στοιχείο <draw_ops> ή καθόρισε δύο στοιχεία)" + +#~ msgid "" +#~ "Can't have a two draw_ops for a <menu_icon> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Δεν μπορεί να υπάρχουν δυο λειτουργίες_σχεδίασης για ένα στοιχείο " +#~ "<menu_icon> (το θέμα έχει καθορίσει ένα γνώρισμα λειτουργίας_σχεδίασης " +#~ "και ακόμα ένα στοιχείο <draw_ops> ή καθόρισε δύο στοιχεία)" + +#~ msgid "Bad version specification '%s'" +#~ msgstr "Εσφαλμένη προδιαγραφή έκδοσης '%s'" + +#~ msgid "" +#~ "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" +#~ "theme-2.xml" +#~ msgstr "" +#~ "Η ιδιότητα \"version\" δεν μπορεί να χρησιμοποιηθεί στο metacity-theme-1." +#~ "xml ή στο metacity-theme-2.xml" + +#~ msgid "" +#~ "Theme requires version %s but latest supported theme version is %d.%d" +#~ msgstr "" +#~ "Το θέμα απαιτεί την έκδοση %s αλλά η πιο πρόσφατη υπστηριζόμενη έκδοση " +#~ "του θέματος είναι η %d.%d" + +#~ msgid "Outermost element in theme must be <metacity_theme> not <%s>" +#~ msgstr "" +#~ "Το εξώτατο στοιχείο στο θέμα θα πρέπει να είναι <metacity_theme> όχι <%s>" + +#~ msgid "" +#~ "Element <%s> is not allowed inside a name/author/date/description element" +#~ msgstr "" +#~ "Το στοιχείο <%s> δεν επιτρέπεται μέσα σε στοιχείο name/author/date/" +#~ "description" + +#~ msgid "Element <%s> is not allowed inside a <constant> element" +#~ msgstr "Το στοιχείο <%s> δεν επιτρέπεται μέσα σε στοιχείο <constant>" + +#~ msgid "" +#~ "Element <%s> is not allowed inside a distance/border/aspect_ratio element" +#~ msgstr "" +#~ "Το στοιχείο <%s> δεν επιτρέπεται μέσα σε στοιχείο distance/border/" +#~ "aspect_ratio" + +#~ msgid "Element <%s> is not allowed inside a draw operation element" +#~ msgstr "" +#~ "Το στοιχείο <%s> δεν επιτρέπεται μέσα σε στοιχείο λειτουργίας σχεδίασης" + +#~ msgid "Element <%s> is not allowed inside a <%s> element" +#~ msgstr "Το στοιχείο <%s> δεν επιτρέπεται μέσα σε στοιχείο <%s>" + +#~ msgid "No draw_ops provided for frame piece" +#~ msgstr "Δεν παρέχονται λειτουργίες_σχεδίασης για το κομμάτι πλαισίου" + +#~ msgid "No draw_ops provided for button" +#~ msgstr "Δεν παρέχονται λειτουργίες_σχεδίασης για το κουμπί" + +#~ msgid "No text is allowed inside element <%s>" +#~ msgstr "Δεν επιτρέπεται κείμενο μέσα στο στοιχείο <%s>" + +#~ msgid "<%s> specified twice for this theme" +#~ msgstr "<%s> έχει ορισθεί δύο φορές για αυτό το θέμα" -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Γραμμή %d χαρακτήρας %d: %s" +# gconf/gconf-internals.c:2416 +#~ msgid "Failed to find a valid file for theme %s\n" +#~ msgstr "Αποτυχία εύρεσης ενός έγκυρου αρχείου για το θέμα %s\n" + +#~ msgid "Unknown window information request: %d" +#~ msgstr "Άγνωστη αίτηση πληροφοριών παραθύρου: %d" + +#~ msgid "Missing %s extension required for compositing" +#~ msgstr "Λείπει η επέκταση %s που απαιτείται για compositing" + +#~ msgid "" +#~ "Some other program is already using the key %s with modifiers %x as a " +#~ "binding\n" +#~ msgstr "" +#~ "Κάποιο άλλο πρόγραμμα χρησιμοποιεί ήδη το κλειδί %s με μετατροπείς %x ώς " +#~ "δεσμό\n" + +#~ msgid "\"%s\" is not a valid accelerator\n" +#~ msgstr "Το \"%s\" δεν είναι έγκυρος επιταχυντής\n" + +#~ msgid "" +#~ "Workarounds for broken applications disabled. Some applications may not " +#~ "behave properly.\n" +#~ msgstr "" +#~ "Οι προσωρινές λύσεις για προβληματικές εφαρμογές έχουν απενεργοποιηθεί. " +#~ "Μερικές εφαρμογές μπορεί να μη συμπεριφέρονται σωστά.\n" + +#~ msgid "Could not parse font description \"%s\" from GSettings key %s\n" +#~ msgstr "" +#~ "Αδυναμία ανάλυσης περιγραφής γραμματοσειράς \"%s\" από κλειδί GSettings " +#~ "%s\n" + +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" +#~ msgstr "" +#~ "Το \"%s\" που βρέθηκε στη βάση δεδομένων ρυθμίσεων δεν είναι μια έγκυρη " +#~ "τιμή για μετατροπέα κουμπιού ποντικιού\n" + +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for " +#~ "keybinding \"%s\"\n" +#~ msgstr "" +#~ "Το \"%s\" που βρέθηκε στη βάση δεδομένων ρυθμίσεων δεν είναι μια έγκυρη " +#~ "τιμή για συνδυασμό πλήκτρων\"%s\"\n" + +#~ msgid "" +#~ "Could not acquire window manager selection on screen %d display \"%s\"\n" +#~ msgstr "" +#~ "Αδυναμία λήψης επιλογής διαχειριστή παραθύρων στην οθόνη %d προβολή \"%s" +#~ "\"\n" + +#~ msgid "Could not release screen %d on display \"%s\"\n" +#~ msgstr "Αδυναμία απελευθέρωσης οθόνης %d στην προβολή \"%s\"\n" -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "Το γνώρισμα \"%s\" επαναλήφθηκε δυο φορές στο ίδιο <%s> στοιχείο" +# gconf/gconf-internals.c:2333 +#~ msgid "Could not create directory '%s': %s\n" +#~ msgstr "Αδυναμία δημιουργίας καταλόγου '%s': %s\n" -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "" -"Το γνώρισμα \"%s\" δεν είναι έγκυρο στο στοιχείο <%s> σε αυτήν την περίπτωση" +# gconf/gconf-internals.c:789 +#~ msgid "Could not open session file '%s' for writing: %s\n" +#~ msgstr "Αδύνατο το άνοιγμα αρχείου συνεδρίας '%s' για εγγραφή: %s\n" -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "Αδύνατη η ανάλυση του \"%s\" ως ακεραίου αριθμού" +#~ msgid "Error writing session file '%s': %s\n" +#~ msgstr "Σφάλμα εγγραφής αρχείου συνεδρίας '%s': %s\n" -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "" -"Δεν έγινε κατανοητή η ακολουθία χαρακτήρων \"%s\" στο αλφαριθμητικό \"%s\"" +# gconf/gconf-backend.c:243 +#~ msgid "Error closing session file '%s': %s\n" +#~ msgstr "Σφάλμα κλεισίματος αρχείου συνεδρίας '%s': %s\n" -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "Ο ακέραιος %ld θα πρέπει να είναι θετικός" +# gconf/gconf-internals.c:2416 +#~ msgid "Failed to parse saved session file: %s\n" +#~ msgstr "Αποτυχία ανάλυσης αποθηκευμένου αρχείου συνεδρίας: %s\n" -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "Ο ακέραιος %ld είναι πολύ μεγάλος , μέγιστος δυνατός %d" +#~ msgid "<mutter_session> attribute seen but we already have the session ID" +#~ msgstr "" +#~ "βρέθηκε η ιδιότητα <mutter_session> αλλά ήδη έχουμε την ταυτότητα " +#~ "συνεδρίας" -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "Αδυναμία ανάλυσης \"%s\" ως αριθμό κινητού σημείου" +#~ msgid "Unknown attribute %s on <%s> element" +#~ msgstr "Άγνωστο γνώρισμα %s στο στοιχείο <%s>" -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "" -"Οι τιμές Boolean θα πρέπει να είναι είτε \"true\" ή \"false\" όχι \"%s\"" +#~ msgid "nested <window> tag" +#~ msgstr "ενσωματωμένη ετικέτα <window>" -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "Η γωνία θα πρέπει να είναι ανάμεσα σε 0.0 και 360.0, ήταν %g\n" +#~ msgid "Unknown element %s" +#~ msgstr "Άγνωστο στοιχείο %s" -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" -"Το Alpha θα πρέπει να είναι ανάμεσα σε 0.0 (αόρατο) και 1.0 (πλήρης ορατό), " -"ήταν %g\n" +# gconf/gconftool.c:1639 +#~ msgid "Failed to open debug log: %s\n" +#~ msgstr "Αποτυχία ανοίγματος καταγραφής εκσφαλμάτωσης: %s\n" -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"Μή έγκυρη κλίμακα τίτλου \"%s\" (θα πρέπει να είναι ενα από xx-small,x-small," -"small,medium,large,x-large,xx-large)\n" +# gconf/gconf-internals.c:2416 +#~ msgid "Failed to fdopen() log file %s: %s\n" +#~ msgstr "Αποτυχία ανοίγματος fdopen() αρχείου καταγραφής %s: %s\n" -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "Το <%s> όνομα \"%s\" χρησιμοποιήθηκε για δεύτερη φορά" +#~ msgid "Opened log file %s\n" +#~ msgstr "Έχει ανοιχθεί το αρχείο καταγραφών %s\n" -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "<%s> μητρικό \"%s\" δεν έχει ορισθεί" +#~ msgid "Window manager: " +#~ msgstr "Διαχειριστής παραθύρων: " -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "<%s> γεωμετρία \"%s\" δεν έχει ορισθεί" +#~ msgid "Bug in window manager: " +#~ msgstr "Σφάλμα στο διαχειριστή παραθύρων: " -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "" -"<%s> θα πρέπει να καθορίσετε είτε μια γεωμετρία είτε ένα μητρικό που έχει " -"γεωμετρία" +#~ msgid "Window manager warning: " +#~ msgstr "Προειδοποίηση διαχειριστή παραθύρων: " -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "Πρέπει να καθορίσετε ένα παρασκήνιο για να έχει νόημα μια τιμή άλφα" +#~ msgid "Window manager error: " +#~ msgstr "Σφάλμα διαχειριστή παραθύρων: " -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Άγνωστος τύπος \"%s\" στο στοιχείο <%s> " +#~ msgid "" +#~ "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " +#~ "window as specified in the ICCCM.\n" +#~ msgstr "" +#~ "Το παράθυρο %s όρισε SM_CLIENT_ID στον εαυτό του, αντί στο παράθυρο του " +#~ "WM_CLIENT_LEADER όπως καθορίζεται στο ICCCM.\n" -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "Άγνωστος ορισμός τύπου \"%s\" στο στοιχείο <%s> " +#~ msgid "" +#~ "Window %s sets an MWM hint indicating it isn't resizable, but sets min " +#~ "size %d x %d and max size %d x %d; this doesn't make much sense.\n" +#~ msgstr "" +#~ "Το παράθυρο %s όρισε μια συμβουλή MWM ότι δεν είναι δυνατή η αλλαγή " +#~ "μεγέθους, αλλά όρισε ελάχιστο μέγεθος %d x %d και μέγιστο μέγεθος %d x " +#~ "%d; αυτό είναι ακατανόητο.\n" -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "Έχει ορισθεί ήδη ένα στυλ για τον τύπο παραθύρου \"%s\"" - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "Το στοιχείο <%s> δεν επιτρέπεται κάτω από <%s>" +#~ msgid "Application set a bogus _NET_WM_PID %lu\n" +#~ msgstr "Η εφαρμογή έθεσε ένα πλαστό _NET_WM_PID %lu\n" -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" -msgstr "" -"Δεν είναι δυνατός ο καθορισμός και \"ύψους_κουμπιού\"/\"πλάτους_κουμπιού\" " -"και \"αναλογίας_διαστάσεων\" για κουμπιά" +#~ msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +#~ msgstr "Άκυρο WM_TRANSIENT_FOR παράθυρο 0x%lx που καθορίστηκε για %s.\n" -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "Η απόσταση \"%s\" είναι άγνωστη" +#~ msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" +#~ msgstr "" +#~ "Το WM_TRANSIENT_FOR του παραθύρου 0x%lx για το %s θα δημιουργήσει " +#~ "επανάληψη.\n" -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "Η αναλογία διαστάσεων \"%s\" είναι άγνωστη" +#~ msgid "" +#~ "Window 0x%lx has property %s\n" +#~ "that was expected to have type %s format %d\n" +#~ "and actually has type %s format %d n_items %d.\n" +#~ "This is most likely an application bug, not a window manager bug.\n" +#~ "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +#~ msgstr "" +#~ "Το παράθυρο 0x%lx έχει ιδιότητα %s\n" +#~ "η οποία αναμενόταν να έχει τύπο %s μορφή %d\n" +#~ "ενώ στην πραγματικότητα έχει τύπο %s μορφή %d n_items %d.\n" +#~ "Αυτό πιθανόν να είναι σφάλμα της εφαρμογής και όχι του διαχειριστή " +#~ "παραθύρων.\n" +#~ "Το παράθυρο έχει τίτλο=\"%s\" class=\"%s\" name=\"%s\"\n" -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "Περίγραμμα \"%s\" είναι άγνωστο" +#~ msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +#~ msgstr "Η ιδιότητα %s στο παράθυρο 0x%lx περιείχε μη έγκυρο UTF-8\n" -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "" -"Δεν υπάρχει γνώρισμα \"έναρξη γωνίας\" ή γνώρισμα \"από\" για το στοιχείο <" -"%s>" +#~ msgid "" +#~ "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the " +#~ "list\n" +#~ msgstr "" +#~ "Η ιδιότητα %s στο παράθυρο 0x%lx περιείχε μη έγκυρο UTF-8 για το " +#~ "αντικείμενο %d στη λίστα\n" -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "" -"Δεν υπάρχει γνώρισμα \"επέκταση_γωνίας\" ή γνώρισμα \"σε\" για το στοιχείο <" -"%s>" +#~ msgid "Mi_nimize" +#~ msgstr "Ελα_χιστοποίηση" -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "Δεν έγινε κατανοητή η τιμή \"%s\" για τον τύπο του gradient" +#~ msgid "Ma_ximize" +#~ msgstr "_Μεγιστοποίηση" -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "Δεν έγινε κατανοητός ο τύπος γεμίσματος \"%s\" για <%s> στοιχείο" +#~ msgid "Unma_ximize" +#~ msgstr "Απόμε_γιστοποίηση" -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "Δεν έγινε κατανοητή η κατάσταση \"%s\" για στοιχείο <%s> )" +#~ msgid "Roll _Up" +#~ msgstr "Τύλιγμα _πάνω" -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "Δεν έγινε κατανοητή η σκίαση \"%s\" για στοιχείο <%s> " +#~ msgid "_Unroll" +#~ msgstr "_Ξετύλιγμα" -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "Δεν έγινε κατανοητό το βέλος \"%s\" για στοιχείο <%s> " +#~ msgid "_Move" +#~ msgstr "_Μετακίνηση" -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "Δεν έχουν ορισθεί <λειτουργίες σχεδίασης> που ονομάζονται \"%s\"" +#~ msgid "_Resize" +#~ msgstr "Αλλαγή με_γέθους" -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "" -"Αν συμπεριλάβετε εδώ λειτουργίες σχεδίασης \"%s\" θα δημιουργήσετε μια " -"κυκλική αναφορά" +#~ msgid "Move Titlebar On_screen" +#~ msgstr "Μετακίνηση μπάρας τίτλου στην ο_θόνη" -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Άγνωστη θέση \"%s\" για το κομμάτι πλαισίου" +#~ msgid "Always on _Top" +#~ msgstr "Πάντα σε _πρώτο πλάνο" -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "Το στυλ πλαισίου έχει ήδη ένα κομμάτι στην θέση %s" +#~ msgid "_Always on Visible Workspace" +#~ msgstr "_Ορατό σε όλους τους χώρους εργασίας" -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "δεν έχουν ορισθεί <λειτουργίες σχεδίασης> με το όνομα \"%s\"" +#~ msgid "_Only on This Workspace" +#~ msgstr "Μόνο σε _αυτό το χώρο εργασίας" -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Άγνωστη λειτουργία \"%s\" για το κουμπί" +#~ msgid "Move to Workspace _Left" +#~ msgstr "Μετακίνηση στο χώρο εργασίας αρι_στερά" -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "" -"Η λειτουργία \"%s\" του κουμπιού δεν υπάρχει σε αυτή την έκδοση (%d, " -"χρειάζεται %d)" +#~ msgid "Move to Workspace R_ight" +#~ msgstr "Μετακίνηση στο χώρο εργασίας δε_ξιά" -# -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Άγνωστη κατάσταση \"%s\" για το κουμπί" +#~ msgid "Move to Workspace _Up" +#~ msgstr "Μετακίνηση παραθύρου στο χώρο εργασίας πά_νω" -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "" -"Το στυλ πλαισίου έχει ήδη ένα κουμπί για τη λειτουργία %s κατάσταση %s" +#~ msgid "Move to Workspace _Down" +#~ msgstr "Μετακίνηση στο χώρο εργασίας _κάτω" -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "\"%s\" δεν είναι έγκυρη τιμή για το γνώρισμα εστίασης" +#~ msgid "_Close" +#~ msgstr "_Κλείσιμο" -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "\"%s\" δεν είναι έγκυρη τιμή για το γνώρισμα κατάστασης" +#~ msgid "Workspace %d%n" +#~ msgstr "Χώρος εργασίας %d%n" -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "Ένα στυλ που ονομάζεται \"%s\" δεν έχει ορισθεί" +#~ msgid "Workspace 1_0" +#~ msgstr "Χώρος Εργασίας 1_0" -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "\"%s\" δεν είναι έγκυρη τιμή για το γνώρισμα αλλαγής μεγέθους" +#~ msgid "Workspace %s%d" +#~ msgstr "Χώρος Εργασίας %s%d" -#: ../src/ui/theme-parser.c:3147 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" -"Δεν πρέπει να υπάρχει γνώρισμα \"αλλαγή μεγέθους\" στο στοιχείο <%s> για " -"μεγιστοποιημένες/σκιασμένες καταστάσεις" +#~ msgid "Move to Another _Workspace" +#~ msgstr "Μετακίνηση σε άλλο _χώρο εργασίας" -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "" -"Δεν πρέπει να υπάρχει γνώρισμα \"αλλαγή μεγέθους\" στο στοιχείο <%s> για " -"μεγιστοποιημένες καταστάσεις" +#~ msgid "Shift" +#~ msgstr "Shift" -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "" -"Το στυλ έχει ήδη καθορισθεί για κατάσταση %s αλλαγή μεγέθους %s εστίαση %s" +#~ msgid "Ctrl" +#~ msgstr "Ctrl" -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "Το στυλ έχει ήδη καθορισθεί για κατάσταση %s εστίαση %s" +#~ msgid "Alt" +#~ msgstr "Alt" -#: ../src/ui/theme-parser.c:3294 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Δεν μπορεί να υπάρχουν δυο λειτουργίες σχεδίασης για ένα στοιχείο <κομμάτι> " -"( το θέμα έχει καθορίσει ένα γνώρισμα λειτουργίας σχεδίασης και ακόμα ένα " -"στοιχείο <λειτουργίες σχεδίασης> ή καθόρισε δύο στοιχεία)" +#~ msgid "Meta" +#~ msgstr "Meta" -#: ../src/ui/theme-parser.c:3332 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Δεν μπορεί να υπάρχουν δυο λειτουργίες σχεδίασης για ένα στοιχείο <κουμπί> " -"( το θέμα έχει καθορίσει ένα γνώρισμα λειτουργίας σχεδίασης και ακόμα ένα " -"στοιχείο <λειτουργίες σχεδίασης> ή καθόρισε δύο στοιχεία)" +#~ msgid "Super" +#~ msgstr "Super" -#: ../src/ui/theme-parser.c:3370 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Δεν μπορεί να υπάρχουν δυο λειτουργίες σχεδίασης για ένα στοιχείο <εικονίδιο " -"μενού> ( το θέμα έχει καθορίσει ένα γνώρισμα λειτουργίας σχεδίασης και ακόμα " -"ένα στοιχείο <λειτουργίες σχεδίασης> ή καθόρισε δύο στοιχεία)" +#~ msgid "Hyper" +#~ msgstr "Hyper" -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "Εσφαλμένη προδιαγραφή έκδοσης '%s'" +#~ msgid "Mod2" +#~ msgstr "Mod2" -#: ../src/ui/theme-parser.c:3507 -msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" -msgstr "" -"Η ιδιότητα \"version\" δεν μπορεί να χρησιμοποιηθεί στο metacity-theme-1.xml " -"ή στο metacity-theme-2.xml" +#~ msgid "Mod3" +#~ msgstr "Mod3" -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "" -"Το θέμα απαιτεί την έκδοση %s αλλά η πιο πρόσφατη υπστηριζόμενη έκδοση του " -"θέματος είναι η %d.%d" +#~ msgid "Mod4" +#~ msgstr "Mod4" -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "" -"Το εξώτατο στοιχείο στο θέμα θα πρέπει να είναι <metacity_theme> όχι <%s>" +#~ msgid "Mod5" +#~ msgstr "Mod5" -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "" -"Το στοιχείο <%s> δεν επιτρέπεται μέσα σε στοιχείο ονόματος/συγγραφέα/" -"ημερομηνίας/περιγραφής" +#~ msgid "Usage: %s\n" +#~ msgstr "Χρήση: %s\n" -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "Το στοιχείο <%s> δεν επιτρέπεται μέσα σε στοιχείο <constant>" +#~ msgid "_Windows" +#~ msgstr "_Παράθυρα" -#: ../src/ui/theme-parser.c:3599 -#, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "" -"Το στοιχείο <%s> δεν επιτρέπεται μέσα σε στοιχείο απόστασης/περιγράμματος/" -"aspect_ratio" +#~ msgid "_Dialog" +#~ msgstr "Παράθυρο _διαλόγου" -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "" -"Το στοιχείο <%s> δεν επιτρέπεται μέσα σε στοιχείο λειτουργίας σχεδίασης" +#~ msgid "_Modal dialog" +#~ msgstr "Παράθυρο σχη_ματικού διαλόγου" -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "Το στοιχείο <%s> δεν επιτρέπεται μέσα σε στοιχείο <%s>" +#~ msgid "_Utility" +#~ msgstr "Ε_φαρμογή" -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "Δεν παρέχονται λειτουργίες σχεδίασης για το κομμάτι πλαισίου" +#~ msgid "_Splashscreen" +#~ msgstr "Ο_θόνη έναρξης" -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "Δεν παρέχονται λειτουργίες σχεδίασης για το κουμπί" +#~ msgid "_Top dock" +#~ msgstr "Dock _κορυφής" -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "Δεν επιτρέπεται κείμενο μέσα στο στοιχείο <%s>" +#~ msgid "_Bottom dock" +#~ msgstr "Κά_τω ταμπλό" -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "<%s> έχει ορισθεί δύο φορές για αυτό το θέμα" +#~ msgid "_Left dock" +#~ msgstr "Α_ριστερό ταμπλό" -# gconf/gconf-internals.c:2416 -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Αποτυχία εύρεσης ενός έγκυρου αρχείου για το θέμα %s\n" +#~ msgid "_Right dock" +#~ msgstr "_Δεξί ταμπλό" -#: ../src/ui/theme-viewer.c:98 -msgid "_Windows" -msgstr "_Παράθυρα" +#~ msgid "_All docks" +#~ msgstr "Ό_λες οι προσαρτήσεις" -#: ../src/ui/theme-viewer.c:99 -msgid "_Dialog" -msgstr "Παράθυρο _διαλόγου" +#~ msgid "Des_ktop" +#~ msgstr "Επι_φάνεια εργασίας" -#: ../src/ui/theme-viewer.c:100 -msgid "_Modal dialog" -msgstr "Παράθυρο σχη_ματικού διαλόγου" +#~ msgid "Open another one of these windows" +#~ msgstr "Άνοιγμα ακόμα ενός από αυτά τα παράθυρα" -#: ../src/ui/theme-viewer.c:101 -msgid "_Utility" -msgstr "Ε_φαρμογή" +#~ msgid "This is a demo button with an 'open' icon" +#~ msgstr "Αυτό είναι ένα κουμπί επίδειξης με ένα εικονίδιο 'άνοιγμα'" -#: ../src/ui/theme-viewer.c:102 -msgid "_Splashscreen" -msgstr "Ο_θόνη έναρξης" +#~ msgid "This is a demo button with a 'quit' icon" +#~ msgstr "Αυτό είναι ένα κουμπί επίδειξης με ένα εικονίδιο 'έξοδος'" -#: ../src/ui/theme-viewer.c:103 -msgid "_Top dock" -msgstr "Dock _κορυφής" +#~ msgid "This is a sample message in a sample dialog" +#~ msgstr "Αυτό είναι ένα κείμενο-παράδειγμα σε ένα παραδειγματικό διάλογο" -#: ../src/ui/theme-viewer.c:104 -msgid "_Bottom dock" -msgstr "Κά_τω dock" +#~ msgid "Fake menu item %d\n" +#~ msgstr "Ψεύτικο αντικείμενο μενού %d\n" -#: ../src/ui/theme-viewer.c:105 -msgid "_Left dock" -msgstr "Α_ριστερό dock" +#~ msgid "Border-only window" +#~ msgstr "Παράθυρο μόνο με πλαίσιο" -#: ../src/ui/theme-viewer.c:106 -msgid "_Right dock" -msgstr "_Δεξί dock" +#~ msgid "Bar" +#~ msgstr "Μπάρα" -#: ../src/ui/theme-viewer.c:107 -msgid "_All docks" -msgstr "_Όλα τα dock" +#~ msgid "Normal Application Window" +#~ msgstr "Κανονικό παράθυρο εφαρμογής" -#: ../src/ui/theme-viewer.c:108 -msgid "Des_ktop" -msgstr "Επι_φάνεια εργασίας" +#~ msgid "Dialog Box" +#~ msgstr "Κουτί διαλόγου" -#: ../src/ui/theme-viewer.c:114 -msgid "Open another one of these windows" -msgstr "Άνοιγμα ακόμα ενός από αυτά τα παράθυρα" +#~ msgid "Modal Dialog Box" +#~ msgstr "Κουτί σχηματικού διαλόγου" -#: ../src/ui/theme-viewer.c:116 -msgid "This is a demo button with an 'open' icon" -msgstr "Αυτό είναι ένα κουμπί επίδειξης με ένα εικονίδιο 'άνοιγμα'" +#~ msgid "Utility Palette" +#~ msgstr "Παλέτα εφαρμογής" -#: ../src/ui/theme-viewer.c:118 -msgid "This is a demo button with a 'quit' icon" -msgstr "Αυτό είναι ένα κουμπί επίδειξης με ένα εικονίδιο 'έξοδος'" +#~ msgid "Torn-off Menu" +#~ msgstr "Αποσπώμενο μενού" -#: ../src/ui/theme-viewer.c:252 -msgid "This is a sample message in a sample dialog" -msgstr "Αυτό είναι ένα κείμενο-παράδειγμα σε ένα παραδειγματικό διάλογο" +#~ msgid "Border" +#~ msgstr "Πλαίσιο" -#: ../src/ui/theme-viewer.c:335 -#, c-format -msgid "Fake menu item %d\n" -msgstr "Ψεύτικο αντικείμενο μενού %d\n" +#~ msgid "Attached Modal Dialog" +#~ msgstr "Συνημμένο κουτί σχηματικού διαλόγου" -#: ../src/ui/theme-viewer.c:369 -msgid "Border-only window" -msgstr "Παράθυρο μόνο με πλαίσιο" +#~ msgid "Button layout test %d" +#~ msgstr "Δοκιμή διάταξης κουμπιού %d" -#: ../src/ui/theme-viewer.c:371 -msgid "Bar" -msgstr "Μπάρα" +#~ msgid "%g milliseconds to draw one window frame" +#~ msgstr "%g χιλιοστά δευτερ. για τη σχεδίαση ενός πλαισίου παραθύρου" -#: ../src/ui/theme-viewer.c:388 -msgid "Normal Application Window" -msgstr "Κανονικό παράθυρο εφαρμογής" +#~ msgid "Usage: metacity-theme-viewer [THEMENAME]\n" +#~ msgstr "Χρήση: metacity-theme-viewer [THEMENAME]\n" -#: ../src/ui/theme-viewer.c:392 -msgid "Dialog Box" -msgstr "Κουτί διαλόγου" +# gconf/gconf-backend.c:243 +#~ msgid "Error loading theme: %s\n" +#~ msgstr "Σφάλμα φόρτωσης θέματος: %s\n" -#: ../src/ui/theme-viewer.c:396 -msgid "Modal Dialog Box" -msgstr "Κουτί σχηματικού διαλόγου" +#~ msgid "Loaded theme \"%s\" in %g seconds\n" +#~ msgstr "Το θέμα \"%s\" φορτώθηκε σε %g δευτερόλεπτα\n" -#: ../src/ui/theme-viewer.c:400 -msgid "Utility Palette" -msgstr "Παλέτα εφαρμογής" +#~ msgid "Normal Title Font" +#~ msgstr "Γραμματοσειρά κανονικού τίτλου" -#: ../src/ui/theme-viewer.c:404 -msgid "Torn-off Menu" -msgstr "Αποσπώμενο μενού" +#~ msgid "Small Title Font" +#~ msgstr "Γραμματοσειρά μικρού τίτλου" -#: ../src/ui/theme-viewer.c:408 -msgid "Border" -msgstr "Πλαίσιο" +#~ msgid "Large Title Font" +#~ msgstr "Γραμματοσειρά μεγάλου τίτλου" -#: ../src/ui/theme-viewer.c:412 -msgid "Attached Modal Dialog" -msgstr "Συνημμένο κουτί σχηματικού διαλόγου" +#~ msgid "Button Layouts" +#~ msgstr "Διατάξεις κουμπιού" -#: ../src/ui/theme-viewer.c:743 -#, c-format -msgid "Button layout test %d" -msgstr "Δοκιμή διάταξης κουμπιού %d" +#~ msgid "Benchmark" +#~ msgstr "Benchmark" -#: ../src/ui/theme-viewer.c:772 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g χιλιοστά δευτερ. για τη σχεδίαση ενός πλαισίου παραθύρου" +#~ msgid "Window Title Goes Here" +#~ msgstr "Τίτλος παραθύρου εδώ" -#: ../src/ui/theme-viewer.c:817 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Χρήση: metacity-theme-viewer [THEMENAME]\n" +#~ msgid "" +#~ "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and " +#~ "%g seconds wall clock time including X server resources (%g milliseconds " +#~ "per frame)\n" +#~ msgstr "" +#~ "Σχεδιάστηκαν %d πλαίσια σε %g δευτερόλεπτα από τη μεριά του πελάτη (%g " +#~ "χιλιοστά ανά πλαίσιο) και %g δευτερόλεπτα σε πραγματικό χρόνο " +#~ "συμπεριλαμβανομένων και των πόρων του εξυπηρετητή X (%g χιλιοστά ανά " +#~ "πλαίσιο)\n" -# gconf/gconf-backend.c:243 -#: ../src/ui/theme-viewer.c:824 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "Σφάλμα φόρτωσης θέματος: %s\n" +#~ msgid "position expression test returned TRUE but set error" +#~ msgstr "" +#~ "επιστράφηκε TRUE στη θέση της δοκιμαστικής έκφρασης αλλά ορίστηκε σφάλμα" -#: ../src/ui/theme-viewer.c:830 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "Το θέμα \"%s\" φορτώθηκε σε %g δευτερόλεπτα\n" +#~ msgid "position expression test returned FALSE but didn't set error" +#~ msgstr "" +#~ "επιστράφηκε FALSE στη θέση της δοκιμαστικής έκφρασης αλλά δεν ορίστηκε " +#~ "σφάλμα" -#: ../src/ui/theme-viewer.c:874 -msgid "Normal Title Font" -msgstr "Γραμματοσειρά κανονικού τίτλου" +#~ msgid "Error was expected but none given" +#~ msgstr "Αναμένονταν σφάλμα αλλά δε δόθηκε κανένα" -#: ../src/ui/theme-viewer.c:880 -msgid "Small Title Font" -msgstr "Γραμματοσειρά μικρού τίτλου" +#~ msgid "Error %d was expected but %d given" +#~ msgstr "Αναμένονταν το σφάλμα %d αλλά δόθηκε το %d" -#: ../src/ui/theme-viewer.c:886 -msgid "Large Title Font" -msgstr "Γραμματοσειρά μεγάλου τίτλου" +#~ msgid "Error not expected but one was returned: %s" +#~ msgstr "Δεν αναμένονταν σφάλμα αλλά επιστράφηκε ένα: %s" -#: ../src/ui/theme-viewer.c:891 -msgid "Button Layouts" -msgstr "Διατάξεις κουμπιού" +#~ msgid "x value was %d, %d was expected" +#~ msgstr "η τιμή x ήταν %d, αναμενόταν %d" -#: ../src/ui/theme-viewer.c:896 -msgid "Benchmark" -msgstr "Benchmark" +#~ msgid "y value was %d, %d was expected" +#~ msgstr "η τιμή y ήταν %d, αναμενόταν %d" -#: ../src/ui/theme-viewer.c:948 -msgid "Window Title Goes Here" -msgstr "Τίτλος παραθύρου εδώ" +#~ msgid "" +#~ "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" +#~ msgstr "" +#~ "οι εκφράσεις συντεταγμένης %d αναλύθηκαν σε %g δευτερόλεπτα (%g " +#~ "δευτερόλεπτα μέσος όρος)\n" -#: ../src/ui/theme-viewer.c:1054 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"Σχεδιάστηκαν %d πλαίσια σε %g δευτερόλεπτα από τη μεριά του πελάτη (%g " -"χιλιοστά ανά πλαίσιο) και %g δευτερόλεπτα σε πραγματικό χρόνο " -"συμπεριλαμβανομένων και των πόρων του εξυπηρετητή X (%g χιλιοστά ανά " -"πλαίσιο)\n" +#, fuzzy +#~ msgid "Minimize window" +#~ msgstr "Ελαχιστοποίηση παραθύρου" -#: ../src/ui/theme-viewer.c:1273 -msgid "position expression test returned TRUE but set error" -msgstr "position expression test returned TRUE but set error" +#~ msgid "" +#~ "There was an error running <tt>%s</tt>:\n" +#~ "\n" +#~ "%s" +#~ msgstr "" +#~ "Σφάλμα κατά την εκτέλεση του <tt>%s</tt>:\n" +#~ "\n" +#~ "%s" -#: ../src/ui/theme-viewer.c:1275 -msgid "position expression test returned FALSE but didn't set error" -msgstr "position expression test returned FALSE but didn't set error" +#~ msgid "No command %d has been defined.\n" +#~ msgstr "Δεν έχει ορισθεί εντολή %d.\n" -#: ../src/ui/theme-viewer.c:1279 -msgid "Error was expected but none given" -msgstr "Error was expected but none given" +#~ msgid "No terminal command has been defined.\n" +#~ msgstr "Δεν έχει ορισθεί εντολή τερματικού.\n" -#: ../src/ui/theme-viewer.c:1281 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "Error %d was expected but %d given" +#~ msgid "" +#~ "Don't make fullscreen windows that are maximized and have no decorations" +#~ msgstr "" +#~ "Μην κάνετε παράθυρα πλήρους οθόνης που μεγιστοποιούνται και δεν έχουν " +#~ "διάκοσμο" -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "Error not expected but one was returned: %s" +#~ msgid "Comma-separated list of compositor plugins" +#~ msgstr "Λίστα προσθέτων compositor, χωρισμένων με κόμμα" -#: ../src/ui/theme-viewer.c:1291 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "x value was %d, %d was expected" +#~ msgid "Whether window popup/frame should be shown when cycling windows." +#~ msgstr "" +#~ "Αν θα εμφανίζεται πλαίσιο/αναδυόμενο παράθυρο κατά την κυκλική εναλλαγή " +#~ "παραθύρων." -#: ../src/ui/theme-viewer.c:1294 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "y value was %d, %d was expected" +#~ msgid "Internal argument for GObject introspection" +#~ msgstr "Εσωτερικό όρισμα για την ενδοσκόπηση του GObject" -#: ../src/ui/theme-viewer.c:1359 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "" -"οι εκφράσεις συντεταγμένης %d αναλύθηκαν σε %g δευτερόλεπτα (%g δευτερόλεπτα " -"μέσος όρος)\n" +#~ msgid "Failed to restart: %s\n" +#~ msgstr "Αποτυχία επανεκκίνησης: %s\n" + +#~ msgid "GConf key '%s' is set to an invalid value\n" +#~ msgstr "Το GConf key '%s' έχει ορισθεί σε μια μη έγκυρη τιμή\n" + +#~ msgid "%d stored in GConf key %s is out of range %d to %d\n" +#~ msgstr "" +#~ "Το %d που αποθηκεύτηκε στο κλειδί GConf %s είναι εκτός του εύρους %d έως " +#~ "%d\n" + +#~ msgid "GConf key \"%s\" is set to an invalid type\n" +#~ msgstr "" +#~ "Ο τύπος που έχει οριστεί για το κλειδί GConf \"%s\" είναι μη έγκυρος\n" + +#~ msgid "GConf key %s is already in use and can't be used to override %s\n" +#~ msgstr "" +#~ "Το κλειδί %s του GConf χρησιμοποιείται ήδη και δεν μπορεί να " +#~ "χρησιμοποιηθεί για παράκαμψη του %s\n" + +#~ msgid "Can't override GConf key, %s not found\n" +#~ msgstr "Αδυναμία παράκαμψης κλειδιού GConf, δεν βρέθηκε το %s\n" diff --git a/po/en_CA.po b/po/en_CA.po index 2e4a8e477..2d6f14339 100644 --- a/po/en_CA.po +++ b/po/en_CA.po @@ -12,6 +12,7 @@ msgstr "" "PO-Revision-Date: 2005-07-18 18:28-0400\n" "Last-Translator: Adam Weinberger <adamw@gnome.org>\n" "Language-Team: Canadian English <adamw@gnome.org>\n" +"Language: en_CA\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" diff --git a/po/en_GB.po b/po/en_GB.po index 113719217..79e36bf12 100644 --- a/po/en_GB.po +++ b/po/en_GB.po @@ -1,416 +1,278 @@ -# English (British) translation for muffin. +# English (British) translation for mutter. # Copyright (C) 2002 The Gnome Foundation. -# This file is distributed under the same licence as the muffin package. +# This file is distributed under the same licence as the mutter package. # Robert Brady <rwb197@ecs.soton.ac.uk>, Bastien Nocera <hadess@hadess.net>, 2002. # Gareth Owen <gowen72@yahoo.com>, 2004. # Philip Withnall <philip@tecnocode.co.uk>, 2010. -# Bruce Cowan <bruce@bcowan.me.uk>, 2011, 2012. +# Chris Leonard <cjlhomeaddress@gmail.com>, 2012. +# Bruce Cowan <bruce@bcowan.me.uk>, 2011, 2012, 2013, 2018. +# Zander Brown <zbrown@gnome.org>, 2019. +# msgid "" msgstr "" -"Project-Id-Version: muffin\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-03-13 14:30+0000\n" -"PO-Revision-Date: 2012-03-13 14:32+0100\n" -"Last-Translator: Bruce Cowan <bruce@bcowan.me.uk>\n" -"Language-Team: British English <en@li.org>\n" +"Project-Id-Version: mutter\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2019-11-22 01:35+0000\n" +"PO-Revision-Date: 2019-08-25 15:11+0100\n" +"Last-Translator: Zander Brown <zbrown@gnome.org>\n" +"Language-Team: English - United Kingdom <en_GB@li.org>\n" "Language: en_GB\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Virtaal 0.7.1\n" +"X-Generator: Gtranslator 3.32.1\n" +"X-Project-Style: gnome\n" -#: ../src/50-muffin-windows.xml.in.h:1 -msgid "Windows" -msgstr "Windows" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Navigation" -#: ../src/50-muffin-windows.xml.in.h:2 -msgid "View split on left" -msgstr "View split on left" +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Move window to workspace 1" -#: ../src/50-muffin-windows.xml.in.h:3 -msgid "View split on right" -msgstr "View split on right" +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Move window to workspace 2" -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format -msgid "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." -msgstr "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Move window to workspace 3" -#: ../src/core/bell.c:307 -msgid "Bell event" -msgstr "Bell event" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Move window to workspace 4" -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Unknown window information request: %d" +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Move window to last workspace" -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> is not responding." +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "Move window one workspace up" -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "Application is not responding." +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "Move window one workspace down" -#: ../src/core/delete.c:119 -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "Move window one monitor to the left" -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "_Wait" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "Move window one monitor to the right" -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "_Force Quit" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "Move window one monitor up" -#: ../src/core/display.c:387 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "Missing %s extension required for compositing" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "Move window one monitor down" -#: ../src/core/display.c:453 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Failed to open X Window System display '%s'\n" +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "Switch applications" -#: ../src/core/keybindings.c:852 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "Switch to previous application" -#: ../src/core/main.c:206 -msgid "Disable connection to session manager" -msgstr "Disable connection to session manager" +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "Switch windows" -#: ../src/core/main.c:212 -msgid "Replace the running window manager" -msgstr "Replace the running window manager" +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "Switch to previous window" -#: ../src/core/main.c:218 -msgid "Specify session management ID" -msgstr "Specify session management ID" +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "Switch windows of an application" -#: ../src/core/main.c:223 -msgid "X Display to use" -msgstr "X Display to use" +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "Switch to previous window of an application" -#: ../src/core/main.c:229 -msgid "Initialize session from savefile" -msgstr "Initialise session from savefile" +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "Switch system controls" -#: ../src/core/main.c:235 -msgid "Make X calls synchronous" -msgstr "Make X calls synchronous" +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "Switch to previous system control" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Failed to scan themes directory: %s\n" +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "Switch windows directly" -#: ../src/core/main.c:520 -#, c-format -msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "Switch directly to previous window" -#: ../src/core/muffin.c:40 -#, c-format -msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "Switch windows of an app directly" -#: ../src/core/muffin.c:54 -msgid "Print version" -msgstr "Print version" +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "Switch directly to previous window of an app" -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "Comma-separated list of compositor plugins" +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "Switch system controls directly" -#: ../src/core/prefs.c:1077 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "Switch directly to previous system control" -#: ../src/core/prefs.c:1152 -#, c-format -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "Could not parse font description \"%s\" from GSettings key %s\n" +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "Hide all normal windows" -#: ../src/core/prefs.c:1218 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "Switch to workspace 1" -#: ../src/core/prefs.c:1739 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "Switch to workspace 2" -#: ../src/core/prefs.c:1836 -#, c-format -msgid "Workspace %d" -msgstr "Workspace %d" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "Switch to workspace 3" -#: ../src/core/screen.c:730 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "Screen %d on display '%s' is invalid\n" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "Switch to workspace 4" -#: ../src/core/screen.c:746 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "Switch to last workspace" -#: ../src/core/screen.c:773 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "Move to workspace above" -#: ../src/core/screen.c:828 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "Screen %d on display \"%s\" already has a window manager\n" +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "Move to workspace below" -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "Could not release screen %d on display \"%s\"\n" +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "System" -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Could not create directory '%s': %s\n" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Show the run command prompt" -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "Could not open session file '%s' for writing: %s\n" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Show the activities overview" -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Error writing session file '%s': %s\n" +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Restore the keyboard shortcuts" -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Error closing session file '%s': %s\n" - -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Failed to parse saved session file: %s\n" - -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "<muffin_session> attribute seen but we already have the session ID" - -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Unknown attribute %s on <%s> element" - -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "nested <window> tag" - -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "Unknown element %s" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Windows" -#: ../src/core/session.c:1809 -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "Activate the window menu" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Failed to open debug log: %s\n" +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Toggle fullscreen mode" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Failed to fdopen() log file %s: %s\n" +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "Toggle maximisation state" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "Opened log file %s\n" +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "Maximise window" -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "Muffin was compiled without support for verbose mode\n" +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Restore window" -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "Window manager: " +#: data/50-mutter-windows.xml:18 +msgid "Close window" +msgstr "Close window" -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "Bug in window manager: " +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "Hide window" -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "Window manager warning: " +#: data/50-mutter-windows.xml:22 +msgid "Move window" +msgstr "Move window" -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "Window manager error: " +#: data/50-mutter-windows.xml:24 +msgid "Resize window" +msgstr "Resize window" -#. first time through -#: ../src/core/window.c:7224 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7887 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size " -"%d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size " -"%d x %d and max size %d x %d; this doesn't make much sense.\n" +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "Toggle window on all workspaces or one" -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "Application set a bogus _NET_WM_PID %lu\n" +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "Raise window if covered, otherwise lower it" -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (on %s)" +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "Raise window above other windows" -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "Lower window below other windows" -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "Maximise window vertically" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "Maximise window horizontally" -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "Property %s on window 0x%lx contained invalid UTF-8\n" +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "View split on left" -#: ../src/core/xprops.c:494 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "View split on right" -#: ../src/muffin.desktop.in.h:1 ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 +#: data/org.gnome.mutter.gschema.xml.in:7 msgid "Modifier to use for extended window management operations" msgstr "Modifier to use for extended window management operations" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 +#: data/org.gnome.mutter.gschema.xml.in:8 msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." msgstr "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 +#: data/org.gnome.mutter.gschema.xml.in:20 msgid "Attach modal dialogs" msgstr "Attach modal dialogues" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 +#: data/org.gnome.mutter.gschema.xml.in:21 msgid "" "When true, instead of having independent titlebars, modal dialogs appear " "attached to the titlebar of the parent window and are moved together with " @@ -420,23 +282,11 @@ msgstr "" "attached to the titlebar of the parent window and are moved together with " "the parent window." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -msgid "Live Hidden Windows" -msgstr "Live Hidden Windows" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"Determines whether hidden windows (i.e., minimised windows and windows on " -"workspaces other than the current one) should be kept alive." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 +#: data/org.gnome.mutter.gschema.xml.in:30 msgid "Enable edge tiling when dropping windows on screen edges" msgstr "Enable edge tiling when dropping windows on screen edges" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 +#: data/org.gnome.mutter.gschema.xml.in:31 msgid "" "If enabled, dropping windows on vertical screen edges maximizes them " "vertically and resizes them horizontally to cover half of the available " @@ -446,25 +296,25 @@ msgstr "" "vertically and resizes them horizontally to cover half of the available " "area. Dropping windows on the top screen edge maximises them completely." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 +#: data/org.gnome.mutter.gschema.xml.in:40 msgid "Workspaces are managed dynamically" msgstr "Workspaces are managed dynamically" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 +#: data/org.gnome.mutter.gschema.xml.in:41 msgid "" -"Determines whether workspaces are managed dynamically or whether there's a " +"Determines whether workspaces are managed dynamically or whether there’s a " "static number of workspaces (determined by the num-workspaces key in org." "gnome.desktop.wm.preferences)." msgstr "" -"Determines whether workspaces are managed dynamically or whether there's a " -"static number of workspaces (determined by the num-workspaces key in " -"org.cinnamon.desktop.wm.preferences)." +"Determines whether workspaces are managed dynamically or whether there’s a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 +#: data/org.gnome.mutter.gschema.xml.in:50 msgid "Workspaces only on primary" msgstr "Workspaces only on primary" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 +#: data/org.gnome.mutter.gschema.xml.in:51 msgid "" "Determines whether workspace switching should happen for windows on all " "monitors or only for windows on the primary monitor." @@ -472,11 +322,11 @@ msgstr "" "Determines whether workspace switching should happen for windows on all " "monitors or only for windows on the primary monitor." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 +#: data/org.gnome.mutter.gschema.xml.in:59 msgid "No tab popup" msgstr "No tab popup" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 +#: data/org.gnome.mutter.gschema.xml.in:60 msgid "" "Determines whether the use of popup and highlight frame should be disabled " "for window cycling." @@ -484,1171 +334,1338 @@ msgstr "" "Determines whether the use of popup and highlight frame should be disabled " "for window cycling." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Delay focus changes until the pointer stops moving" + +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." + +#: data/org.gnome.mutter.gschema.xml.in:79 msgid "Draggable border width" msgstr "Draggable border width" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 +#: data/org.gnome.mutter.gschema.xml.in:80 msgid "" -"The amount of total draggable borders. If the theme's visible borders are " +"The amount of total draggable borders. If the theme’s visible borders are " "not enough, invisible borders will be added to meet this value." msgstr "" -"The amount of total draggable borders. If the theme's visible borders are " +"The amount of total draggable borders. If the theme’s visible borders are " "not enough, invisible borders will be added to meet this value." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:17 +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "Auto maximise nearly monitor sized windows" + +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximised." + +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Place new windows in the centre" + +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" +"When true, the new windows will always be put in the centre of the active " +"screen of the monitor." + +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Enable experimental features" + +#: data/org.gnome.mutter.gschema.xml.in:108 +msgid "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes " +"mutter request a low priority real-time scheduling. The executable or user " +"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — " +"initializes Xwayland lazily if there are X11 clients. Requires restart." +msgstr "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes " +"mutter request a low priority real-time scheduling. The executable or user " +"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — " +"initialises Xwayland lazily if there are X11 clients. Requires restart." + +#: data/org.gnome.mutter.gschema.xml.in:134 +msgid "Modifier to use to locate the pointer" +msgstr "Modifier to use to locate the pointer" + +#: data/org.gnome.mutter.gschema.xml.in:135 +msgid "This key will initiate the “locate pointer” action." +msgstr "This key will initiate the “locate pointer” action." + +#: data/org.gnome.mutter.gschema.xml.in:155 msgid "Select window from tab popup" msgstr "Select window from tab popup" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:18 +#: data/org.gnome.mutter.gschema.xml.in:160 msgid "Cancel tab popup" msgstr "Cancel tab popup" -#: ../src/tools/muffin-message.c:123 +#: data/org.gnome.mutter.gschema.xml.in:165 +msgid "Switch monitor configurations" +msgstr "Switch monitor configurations" + +#: data/org.gnome.mutter.gschema.xml.in:170 +msgid "Rotates the built-in monitor configuration" +msgstr "Rotates the built-in monitor configuration" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Switch to VT 1" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Switch to VT 2" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Switch to VT 3" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Switch to VT 4" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Switch to VT 5" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Switch to VT 6" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Switch to VT 7" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Switch to VT 8" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Switch to VT 9" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Switch to VT 10" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Switch to VT 11" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Switch to VT 12" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "Re-enable shortcuts" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow X11 grabs to lock keyboard focus with Xwayland" +msgstr "Allow X11 grabs to lock keyboard focus with Xwayland" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 +msgid "" +"Allow all keyboard events to be routed to X11 “override redirect” windows " +"with a grab when running in Xwayland. This option is to support X11 clients " +"which map an “override redirect” window (which do not receive keyboard " +"focus) and issue a keyboard grab to force all keyboard events to that " +"window. This option is seldom used and has no effect on regular X11 windows " +"which can receive keyboard focus under normal circumstances. For a X11 grab " +"to be taken into account under Wayland, the client must also either send a " +"specific X11 ClientMessage to the root window or be among the applications " +"white-listed in key “xwayland-grab-access-rules”." +msgstr "" +"Allow all keyboard events to be routed to X11 “override redirect” windows " +"with a grab when running in Xwayland. This option is to support X11 clients " +"which map an “override redirect” window (which do not receive keyboard " +"focus) and issue a keyboard grab to force all keyboard events to that " +"window. This option is seldom used and has no effect on regular X11 windows " +"which can receive keyboard focus under normal circumstances. For a X11 grab " +"to be taken into account under Wayland, the client must also either send a " +"specific X11 ClientMessage to the root window or be among the applications " +"white-listed in key “xwayland-grab-access-rules”." + +#: data/org.gnome.mutter.wayland.gschema.xml.in:84 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "Xwayland applications allowed to issue keyboard grabs" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:85 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. +#. +#: src/backends/meta-input-settings.c:2528 #, c-format -msgid "Usage: %s\n" -msgstr "Usage: %s\n" - -#: ../src/ui/frames.c:1158 -msgid "Close Window" -msgstr "Close Window" - -#: ../src/ui/frames.c:1161 -msgid "Window Menu" -msgstr "Window Menu" - -#: ../src/ui/frames.c:1164 -msgid "Minimize Window" -msgstr "Minimise Window" - -#: ../src/ui/frames.c:1167 -msgid "Maximize Window" -msgstr "Maximise Window" - -#: ../src/ui/frames.c:1170 -msgid "Restore Window" -msgstr "Restore Window" - -#: ../src/ui/frames.c:1173 -msgid "Roll Up Window" -msgstr "Roll Up Window" - -#: ../src/ui/frames.c:1176 -msgid "Unroll Window" -msgstr "Unroll Window" - -#: ../src/ui/frames.c:1179 -msgid "Keep Window On Top" -msgstr "Keep Window On Top" - -#: ../src/ui/frames.c:1182 -msgid "Remove Window From Top" -msgstr "Remove Window From Top" - -#: ../src/ui/frames.c:1185 -msgid "Always On Visible Workspace" -msgstr "Always On Visible Workspace" - -#: ../src/ui/frames.c:1188 -msgid "Put Window On Only One Workspace" -msgstr "Put Window On Only One Workspace" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "Mi_nimise" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "Ma_ximise" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "Unma_ximise" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "Roll _Up" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "_Unroll" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "_Move" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "_Resize" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "Move Titlebar On_screen" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "Always on _Top" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "_Always on Visible Workspace" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "_Only on This Workspace" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "Move to Workspace _Left" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "Move to Workspace R_ight" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "Move to Workspace _Up" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "Move to Workspace _Down" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "_Close" - -#: ../src/ui/menu.c:204 +msgid "Mode Switch (Group %d)" +msgstr "Mode Switch (Group %d)" + +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2551 +msgid "Switch monitor" +msgstr "Switch monitor" + +#: src/backends/meta-input-settings.c:2553 +msgid "Show on-screen help" +msgstr "Show on-screen help" + +#: src/backends/meta-monitor.c:223 +msgid "Built-in display" +msgstr "Built-in display" + +#: src/backends/meta-monitor.c:252 +msgid "Unknown" +msgstr "Unknown" + +#: src/backends/meta-monitor.c:254 +msgid "Unknown Display" +msgstr "Unknown Display" + +#: src/backends/meta-monitor.c:262 #, c-format -msgid "Workspace %d%n" -msgstr "Workspace %d%n" +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/menu.c:214 +#: src/backends/meta-monitor.c:270 #, c-format -msgid "Workspace 1_0" -msgstr "Workspace 1_0" +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/menu.c:216 +#. Translators: this string will appear in Sysprof +#: src/backends/meta-profiler.c:79 +msgid "Compositor" +msgstr "Compositor" + +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:533 #, c-format -msgid "Workspace %s%d" -msgstr "Workspace %s%d" +msgid "" +"Another compositing manager is already running on screen %i on display “%s”." +msgstr "" +"Another compositing manager is already running on screen %i on display “%s”." -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "Move to Another _Workspace" +#: src/core/bell.c:192 +msgid "Bell event" +msgstr "Bell event" -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" +#: src/core/main.c:190 +msgid "Disable connection to session manager" +msgstr "Disable connection to session manager" -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" +#: src/core/main.c:196 +msgid "Replace the running window manager" +msgstr "Replace the running window manager" + +#: src/core/main.c:202 +msgid "Specify session management ID" +msgstr "Specify session management ID" -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "top" +#: src/core/main.c:207 +msgid "X Display to use" +msgstr "X Display to use" + +#: src/core/main.c:213 +msgid "Initialize session from savefile" +msgstr "Initialise session from savefile" + +#: src/core/main.c:219 +msgid "Make X calls synchronous" +msgstr "Make X calls synchronous" -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "bottom" +#: src/core/main.c:226 +msgid "Run as a wayland compositor" +msgstr "Run as a wayland compositor" -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "left" +#: src/core/main.c:232 +msgid "Run as a nested compositor" +msgstr "Run as a nested compositor" -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "right" +#: src/core/main.c:238 +msgid "Run wayland compositor without starting Xwayland" +msgstr "Run wayland compositor without starting Xwayland" -#: ../src/ui/theme.c:286 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "frame geometry does not specify \"%s\" dimension" +#: src/core/main.c:246 +msgid "Run as a full display server, rather than nested" +msgstr "Run as a full display server, rather than nested" -#: ../src/ui/theme.c:305 +#: src/core/main.c:252 +msgid "Run with X11 backend" +msgstr "Run with X11 backend" + +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:151 #, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "frame geometry does not specify dimension \"%s\" for border \"%s\"" +msgid "“%s” is not responding." +msgstr "“%s” is not responding." -#: ../src/ui/theme.c:342 +#: src/core/meta-close-dialog-default.c:153 +msgid "Application is not responding." +msgstr "Application is not responding." + +#: src/core/meta-close-dialog-default.c:158 +msgid "" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." +msgstr "" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." + +#: src/core/meta-close-dialog-default.c:165 +msgid "_Force Quit" +msgstr "_Force Quit" + +#: src/core/meta-close-dialog-default.c:165 +msgid "_Wait" +msgstr "_Wait" + +#: src/core/mutter.c:38 #, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "Button aspect ratio %g is not reasonable" +msgid "" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" +msgstr "" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" + +#: src/core/mutter.c:52 +msgid "Print version" +msgstr "Print version" + +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "Mutter plugin to use" -#: ../src/ui/theme.c:354 +#: src/core/prefs.c:1849 #, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "Frame geometry does not specify size of buttons" +msgid "Workspace %d" +msgstr "Workspace %d" + +#: src/core/util.c:122 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter was compiled without support for verbose mode\n" -#: ../src/ui/theme.c:1067 +#: src/wayland/meta-wayland-tablet-pad.c:568 #, c-format -msgid "Gradients should have at least two colors" -msgstr "Gradients should have at least two colours" +msgid "Mode Switch: Mode %d" +msgstr "Mode Switch: Mode %d" -#: ../src/ui/theme.c:1219 +#: src/x11/meta-x11-display.c:675 #, c-format msgid "" -"GTK custom color specification must have color name and fallback in " -"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." msgstr "" -"GTK custom colour specification must have colour name and fallback in " -"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." -#: ../src/ui/theme.c:1235 +#: src/x11/meta-x11-display.c:1036 +msgid "Failed to initialize GDK\n" +msgstr "Failed to initialise GDK\n" + +#: src/x11/meta-x11-display.c:1060 +#, c-format +msgid "Failed to open X Window System display “%s”\n" +msgstr "Failed to open X Window System display “%s”\n" + +#: src/x11/meta-x11-display.c:1143 #, c-format +msgid "Screen %d on display “%s” is invalid\n" +msgstr "Screen %d on display “%s” is invalid\n" + +#: src/x11/meta-x11-selection-input-stream.c:460 +#, c-format +msgid "Format %s not supported" +msgstr "Format %s not supported" + +#: src/x11/session.c:1821 msgid "" -"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" -"_ are valid" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." msgstr "" -"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" -"_ are valid" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." + +#: src/x11/window-props.c:569 +#, c-format +msgid "%s (on %s)" +msgstr "%s (on %s)" + +#~ msgid "Move window one workspace to the left" +#~ msgstr "Move window one workspace to the left" + +#~ msgid "Move window one workspace to the right" +#~ msgstr "Move window one workspace to the right" + +#~ msgid "Move to workspace left" +#~ msgstr "Move to workspace left" + +#~ msgid "Move to workspace right" +#~ msgstr "Move to workspace right" + +#~ msgid "Toggle shaded state" +#~ msgstr "Toggle shaded state" + +#~ msgid "background texture could not be created from file" +#~ msgstr "background texture could not be created from file" + +#~ msgid "Unknown window information request: %d" +#~ msgstr "Unknown window information request: %d" + +#~ msgid "Missing %s extension required for compositing" +#~ msgstr "Missing %s extension required for compositing" + +#~ msgid "" +#~ "Some other program is already using the key %s with modifiers %x as a " +#~ "binding\n" +#~ msgstr "" +#~ "Some other program is already using the key %s with modifiers %x as a " +#~ "binding\n" + +#~ msgid "\"%s\" is not a valid accelerator\n" +#~ msgstr "\"%s\" is not a valid accelerator\n" + +#~ msgid "Failed to scan themes directory: %s\n" +#~ msgstr "Failed to scan themes directory: %s\n" + +#~ msgid "" +#~ "Could not find a theme! Be sure %s exists and contains the usual themes.\n" +#~ msgstr "" +#~ "Could not find a theme! Be sure %s exists and contains the usual themes.\n" + +#~ msgid "" +#~ "Workarounds for broken applications disabled. Some applications may not " +#~ "behave properly.\n" +#~ msgstr "" +#~ "Workarounds for broken applications disabled. Some applications may not " +#~ "behave properly.\n" + +#~ msgid "Could not parse font description \"%s\" from GSettings key %s\n" +#~ msgstr "Could not parse font description \"%s\" from GSettings key %s\n" + +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" +#~ msgstr "" +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" + +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for " +#~ "keybinding \"%s\"\n" +#~ msgstr "" +#~ "\"%s\" found in configuration database is not a valid value for " +#~ "keybinding \"%s\"\n" + +#~ msgid "" +#~ "Could not acquire window manager selection on screen %d display \"%s\"\n" +#~ msgstr "" +#~ "Could not acquire window manager selection on screen %d display \"%s\"\n" + +#~ msgid "Screen %d on display \"%s\" already has a window manager\n" +#~ msgstr "Screen %d on display \"%s\" already has a window manager\n" + +#~ msgid "Could not release screen %d on display \"%s\"\n" +#~ msgstr "Could not release screen %d on display \"%s\"\n" + +#~ msgid "Could not create directory '%s': %s\n" +#~ msgstr "Could not create directory '%s': %s\n" + +#~ msgid "Could not open session file '%s' for writing: %s\n" +#~ msgstr "Could not open session file '%s' for writing: %s\n" + +#~ msgid "Error writing session file '%s': %s\n" +#~ msgstr "Error writing session file '%s': %s\n" + +#~ msgid "Error closing session file '%s': %s\n" +#~ msgstr "Error closing session file '%s': %s\n" + +#~ msgid "Failed to parse saved session file: %s\n" +#~ msgstr "Failed to parse saved session file: %s\n" + +#~ msgid "<mutter_session> attribute seen but we already have the session ID" +#~ msgstr "<mutter_session> attribute seen but we already have the session ID" + +#~ msgid "Unknown attribute %s on <%s> element" +#~ msgstr "Unknown attribute %s on <%s> element" + +#~ msgid "nested <window> tag" +#~ msgstr "nested <window> tag" + +#~ msgid "Unknown element %s" +#~ msgstr "Unknown element %s" + +#~ msgid "Failed to open debug log: %s\n" +#~ msgstr "Failed to open debug log: %s\n" + +#~ msgid "Failed to fdopen() log file %s: %s\n" +#~ msgstr "Failed to fdopen() log file %s: %s\n" + +#~ msgid "Opened log file %s\n" +#~ msgstr "Opened log file %s\n" + +#~ msgid "Window manager: " +#~ msgstr "Window manager: " + +#~ msgid "Bug in window manager: " +#~ msgstr "Bug in window manager: " + +#~ msgid "Window manager warning: " +#~ msgstr "Window manager warning: " + +#~ msgid "Window manager error: " +#~ msgstr "Window manager error: " + +#~ msgid "" +#~ "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " +#~ "window as specified in the ICCCM.\n" +#~ msgstr "" +#~ "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " +#~ "window as specified in the ICCCM.\n" + +#~ msgid "" +#~ "Window %s sets an MWM hint indicating it isn't resizable, but sets min " +#~ "size %d x %d and max size %d x %d; this doesn't make much sense.\n" +#~ msgstr "" +#~ "Window %s sets an MWM hint indicating it isn't resizable, but sets min " +#~ "size %d x %d and max size %d x %d; this doesn't make much sense.\n" + +#~ msgid "Application set a bogus _NET_WM_PID %lu\n" +#~ msgstr "Application set a bogus _NET_WM_PID %lu\n" + +#~ msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +#~ msgstr "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" + +#~ msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" +#~ msgstr "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" + +#~ msgid "" +#~ "Window 0x%lx has property %s\n" +#~ "that was expected to have type %s format %d\n" +#~ "and actually has type %s format %d n_items %d.\n" +#~ "This is most likely an application bug, not a window manager bug.\n" +#~ "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +#~ msgstr "" +#~ "Window 0x%lx has property %s\n" +#~ "that was expected to have type %s format %d\n" +#~ "and actually has type %s format %d n_items %d.\n" +#~ "This is most likely an application bug, not a window manager bug.\n" +#~ "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" + +#~ msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +#~ msgstr "Property %s on window 0x%lx contained invalid UTF-8\n" + +#~ msgid "" +#~ "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the " +#~ "list\n" +#~ msgstr "" +#~ "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the " +#~ "list\n" + +#~ msgid "Usage: %s\n" +#~ msgstr "Usage: %s\n" + +#~ msgid "Mi_nimize" +#~ msgstr "Mi_nimise" + +#~ msgid "Ma_ximize" +#~ msgstr "Ma_ximise" + +#~ msgid "Unma_ximize" +#~ msgstr "Unma_ximise" + +#~ msgid "Roll _Up" +#~ msgstr "Roll _Up" + +#~ msgid "_Unroll" +#~ msgstr "_Unroll" + +#~ msgid "_Move" +#~ msgstr "_Move" + +#~ msgid "_Resize" +#~ msgstr "_Resize" + +#~ msgid "Move Titlebar On_screen" +#~ msgstr "Move Titlebar On_screen" + +#~ msgid "Always on _Top" +#~ msgstr "Always on _Top" + +#~ msgid "_Always on Visible Workspace" +#~ msgstr "_Always on Visible Workspace" + +#~ msgid "_Only on This Workspace" +#~ msgstr "_Only on This Workspace" + +#~ msgid "Move to Workspace _Left" +#~ msgstr "Move to Workspace _Left" + +#~ msgid "Move to Workspace R_ight" +#~ msgstr "Move to Workspace R_ight" + +#~ msgid "Move to Workspace _Up" +#~ msgstr "Move to Workspace _Up" + +#~ msgid "Move to Workspace _Down" +#~ msgstr "Move to Workspace _Down" + +#~ msgid "_Close" +#~ msgstr "_Close" + +#~ msgid "Workspace %d%n" +#~ msgstr "Workspace %d%n" + +#~ msgid "Workspace 1_0" +#~ msgstr "Workspace 1_0" + +#~ msgid "Workspace %s%d" +#~ msgstr "Workspace %s%d" + +#~ msgid "Move to Another _Workspace" +#~ msgstr "Move to Another _Workspace" + +#~ msgid "Shift" +#~ msgstr "Shift" + +#~ msgid "Ctrl" +#~ msgstr "Ctrl" + +#~ msgid "Alt" +#~ msgstr "Alt" + +#~ msgid "Meta" +#~ msgstr "Meta" + +#~ msgid "Super" +#~ msgstr "Super" + +#~ msgid "Hyper" +#~ msgstr "Hyper" + +#~ msgid "Mod2" +#~ msgstr "Mod2" + +#~ msgid "Mod3" +#~ msgstr "Mod3" + +#~ msgid "Mod4" +#~ msgstr "Mod4" + +#~ msgid "Mod5" +#~ msgstr "Mod5" + +#~ msgid "%d x %d" +#~ msgstr "%d x %d" + +#~ msgid "top" +#~ msgstr "top" + +#~ msgid "bottom" +#~ msgstr "bottom" + +#~ msgid "left" +#~ msgstr "left" + +#~ msgid "right" +#~ msgstr "right" + +#~ msgid "frame geometry does not specify \"%s\" dimension" +#~ msgstr "frame geometry does not specify \"%s\" dimension" + +#~ msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" +#~ msgstr "frame geometry does not specify dimension \"%s\" for border \"%s\"" + +#~ msgid "Button aspect ratio %g is not reasonable" +#~ msgstr "Button aspect ratio %g is not reasonable" + +#~ msgid "Frame geometry does not specify size of buttons" +#~ msgstr "Frame geometry does not specify size of buttons" + +#~ msgid "Gradients should have at least two colors" +#~ msgstr "Gradients should have at least two colours" + +#~ msgid "" +#~ "GTK custom color specification must have color name and fallback in " +#~ "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" +#~ msgstr "" +#~ "GTK custom colour specification must have colour name and fallback in " +#~ "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" + +#~ msgid "" +#~ "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-" +#~ "z0-9-_ are valid" +#~ msgstr "" +#~ "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-" +#~ "z0-9-_ are valid" + +#~ msgid "" +#~ "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " +#~ "fit the format" +#~ msgstr "" +#~ "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " +#~ "fit the format" + +#~ msgid "" +#~ "GTK color specification must have the state in brackets, e.g. gtk:" +#~ "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "GTK colour specification must have the state in brackets, e.g. gtk:" +#~ "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" + +#~ msgid "" +#~ "GTK color specification must have a close bracket after the state, e.g. " +#~ "gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "GTK colour specification must have a close bracket after the state, e.g. " +#~ "gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -#: ../src/ui/theme.c:1249 -#, c-format -msgid "" -"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " -"fit the format" -msgstr "" -"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " -"fit the format" +#~ msgid "Did not understand state \"%s\" in color specification" +#~ msgstr "Did not understand state \"%s\" in colour specification" -#: ../src/ui/theme.c:1294 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"GTK colour specification must have the state in brackets, e.g. gtk:fg" -"[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgid "Did not understand color component \"%s\" in color specification" +#~ msgstr "Did not understand colour component \"%s\" in colour specification" -#: ../src/ui/theme.c:1308 -#, c-format -msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"GTK colour specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgid "" +#~ "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit " +#~ "the format" +#~ msgstr "" +#~ "Blend format is \"blend/bg_colour/fg_colour/alpha\", \"%s\" does not fit " +#~ "the format" -#: ../src/ui/theme.c:1319 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "Did not understand state \"%s\" in colour specification" +#~ msgid "Could not parse alpha value \"%s\" in blended color" +#~ msgstr "Could not parse alpha value \"%s\" in blended colour" -#: ../src/ui/theme.c:1332 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "Did not understand colour component \"%s\" in colour specification" +#~ msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" +#~ msgstr "Alpha value \"%s\" in blended colour is not between 0.0 and 1.0" -#: ../src/ui/theme.c:1361 -#, c-format -msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" -msgstr "" -"Blend format is \"blend/bg_colour/fg_colour/alpha\", \"%s\" does not fit the " -"format" +#~ msgid "" +#~ "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the " +#~ "format" +#~ msgstr "" +#~ "Shade format is \"shade/base_colour/factor\", \"%s\" does not fit the " +#~ "format" -#: ../src/ui/theme.c:1372 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "Could not parse alpha value \"%s\" in blended colour" +#~ msgid "Could not parse shade factor \"%s\" in shaded color" +#~ msgstr "Could not parse shade factor \"%s\" in shaded colour" -#: ../src/ui/theme.c:1382 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "Alpha value \"%s\" in blended colour is not between 0.0 and 1.0" +#~ msgid "Shade factor \"%s\" in shaded color is negative" +#~ msgstr "Shade factor \"%s\" in shaded colour is negative" -#: ../src/ui/theme.c:1429 -#, c-format -msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "" -"Shade format is \"shade/base_colour/factor\", \"%s\" does not fit the format" +#~ msgid "Could not parse color \"%s\"" +#~ msgstr "Could not parse colour \"%s\"" -#: ../src/ui/theme.c:1440 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "Could not parse shade factor \"%s\" in shaded colour" +#~ msgid "Coordinate expression contains character '%s' which is not allowed" +#~ msgstr "Coordinate expression contains character '%s' which is not allowed" -#: ../src/ui/theme.c:1450 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "Shade factor \"%s\" in shaded colour is negative" +#~ msgid "" +#~ "Coordinate expression contains floating point number '%s' which could not " +#~ "be parsed" +#~ msgstr "" +#~ "Coordinate expression contains floating point number '%s' which could not " +#~ "be parsed" -#: ../src/ui/theme.c:1479 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Could not parse colour \"%s\"" +#~ msgid "" +#~ "Coordinate expression contains integer '%s' which could not be parsed" +#~ msgstr "" +#~ "Coordinate expression contains integer '%s' which could not be parsed" -#: ../src/ui/theme.c:1790 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "Coordinate expression contains character '%s' which is not allowed" +#~ msgid "" +#~ "Coordinate expression contained unknown operator at the start of this " +#~ "text: \"%s\"" +#~ msgstr "" +#~ "Coordinate expression contained unknown operator at the start of this " +#~ "text: \"%s\"" -#: ../src/ui/theme.c:1817 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" +#~ msgid "Coordinate expression was empty or not understood" +#~ msgstr "Coordinate expression was empty or not understood" -#: ../src/ui/theme.c:1831 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "Coordinate expression contains integer '%s' which could not be parsed" +#~ msgid "Coordinate expression results in division by zero" +#~ msgstr "Coordinate expression results in division by zero" -#: ../src/ui/theme.c:1953 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" +#~ msgid "" +#~ "Coordinate expression tries to use mod operator on a floating-point number" +#~ msgstr "" +#~ "Coordinate expression tries to use mod operator on a floating-point number" -#: ../src/ui/theme.c:2010 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "Coordinate expression was empty or not understood" +#~ msgid "" +#~ "Coordinate expression has an operator \"%s\" where an operand was expected" +#~ msgstr "" +#~ "Coordinate expression has an operator \"%s\" where an operand was expected" -#: ../src/ui/theme.c:2121 ../src/ui/theme.c:2131 ../src/ui/theme.c:2165 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "Coordinate expression results in division by zero" +#~ msgid "Coordinate expression had an operand where an operator was expected" +#~ msgstr "Coordinate expression had an operand where an operator was expected" -#: ../src/ui/theme.c:2173 -#, c-format -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "" -"Coordinate expression tries to use mod operator on a floating-point number" +#~ msgid "Coordinate expression ended with an operator instead of an operand" +#~ msgstr "Coordinate expression ended with an operator instead of an operand" -#: ../src/ui/theme.c:2229 -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "" -"Coordinate expression has an operator \"%s\" where an operand was expected" +#~ msgid "" +#~ "Coordinate expression has operator \"%c\" following operator \"%c\" with " +#~ "no operand in between" +#~ msgstr "" +#~ "Coordinate expression has operator \"%c\" following operator \"%c\" with " +#~ "no operand in between" -#: ../src/ui/theme.c:2238 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "Coordinate expression had an operand where an operator was expected" +#~ msgid "Coordinate expression had unknown variable or constant \"%s\"" +#~ msgstr "Coordinate expression had unknown variable or constant \"%s\"" -#: ../src/ui/theme.c:2246 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "Coordinate expression ended with an operator instead of an operand" +#~ msgid "Coordinate expression parser overflowed its buffer." +#~ msgstr "Coordinate expression parser overflowed its buffer." -#: ../src/ui/theme.c:2256 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" +#~ msgid "" +#~ "Coordinate expression had a close parenthesis with no open parenthesis" +#~ msgstr "" +#~ "Coordinate expression had a close parenthesis with no open parenthesis" -#: ../src/ui/theme.c:2407 ../src/ui/theme.c:2452 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "Coordinate expression had unknown variable or constant \"%s\"" +#~ msgid "" +#~ "Coordinate expression had an open parenthesis with no close parenthesis" +#~ msgstr "" +#~ "Coordinate expression had an open parenthesis with no close parenthesis" -#: ../src/ui/theme.c:2506 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "Coordinate expression parser overflowed its buffer." +#~ msgid "Coordinate expression doesn't seem to have any operators or operands" +#~ msgstr "" +#~ "Coordinate expression doesn't seem to have any operators or operands" -#: ../src/ui/theme.c:2535 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "Coordinate expression had a close parenthesis with no open parenthesis" +#~ msgid "Theme contained an expression that resulted in an error: %s\n" +#~ msgstr "Theme contained an expression that resulted in an error: %s\n" -#: ../src/ui/theme.c:2599 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "" -"Coordinate expression had an open parenthesis with no close parenthesis" +#~ msgid "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " +#~ "specified for this frame style" +#~ msgstr "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " +#~ "specified for this frame style" -#: ../src/ui/theme.c:2610 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "Coordinate expression doesn't seem to have any operators or operands" +#~ msgid "" +#~ "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/" +#~ ">" +#~ msgstr "" +#~ "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/" +#~ ">" -#: ../src/ui/theme.c:2822 ../src/ui/theme.c:2842 ../src/ui/theme.c:2862 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "Theme contained an expression that resulted in an error: %s\n" +#~ msgid "Failed to load theme \"%s\": %s\n" +#~ msgstr "Failed to load theme \"%s\": %s\n" -#: ../src/ui/theme.c:4533 -#, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" +#~ msgid "No <%s> set for theme \"%s\"" +#~ msgstr "No <%s> set for theme \"%s\"" -#: ../src/ui/theme.c:5066 ../src/ui/theme.c:5091 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" +#~ msgid "" +#~ "No frame style set for window type \"%s\" in theme \"%s\", add a <window " +#~ "type=\"%s\" style_set=\"whatever\"/> element" +#~ msgstr "" +#~ "No frame style set for window type \"%s\" in theme \"%s\", add a <window " +#~ "type=\"%s\" style_set=\"whatever\"/> element" -#: ../src/ui/theme.c:5139 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Failed to load theme \"%s\": %s\n" +#~ msgid "" +#~ "User-defined constants must begin with a capital letter; \"%s\" does not" +#~ msgstr "" +#~ "User-defined constants must begin with a capital letter; \"%s\" does not" -#: ../src/ui/theme.c:5275 ../src/ui/theme.c:5282 ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 ../src/ui/theme.c:5303 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "No <%s> set for theme \"%s\"" +#~ msgid "Constant \"%s\" has already been defined" +#~ msgstr "Constant \"%s\" has already been defined" -#: ../src/ui/theme.c:5311 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" +#~ msgid "No \"%s\" attribute on element <%s>" +#~ msgstr "No \"%s\" attribute on element <%s>" -#: ../src/ui/theme.c:5709 ../src/ui/theme.c:5771 ../src/ui/theme.c:5834 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" -"User-defined constants must begin with a capital letter; \"%s\" does not" +#~ msgid "Line %d character %d: %s" +#~ msgstr "Line %d character %d: %s" -#: ../src/ui/theme.c:5717 ../src/ui/theme.c:5779 ../src/ui/theme.c:5842 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "Constant \"%s\" has already been defined" +#~ msgid "Attribute \"%s\" repeated twice on the same <%s> element" +#~ msgstr "Attribute \"%s\" repeated twice on the same <%s> element" -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. -#. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "No \"%s\" attribute on element <%s>" +#~ msgid "Attribute \"%s\" is invalid on <%s> element in this context" +#~ msgstr "Attribute \"%s\" is invalid on <%s> element in this context" -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Line %d character %d: %s" +#~ msgid "Could not parse \"%s\" as an integer" +#~ msgstr "Could not parse \"%s\" as an integer" -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "Attribute \"%s\" repeated twice on the same <%s> element" +#~ msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +#~ msgstr "Did not understand trailing characters \"%s\" in string \"%s\"" -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "Attribute \"%s\" is invalid on <%s> element in this context" +#~ msgid "Integer %ld must be positive" +#~ msgstr "Integer %ld must be positive" -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "Could not parse \"%s\" as an integer" +#~ msgid "Integer %ld is too large, current max is %d" +#~ msgstr "Integer %ld is too large, current max is %d" -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "Did not understand trailing characters \"%s\" in string \"%s\"" +#~ msgid "Could not parse \"%s\" as a floating point number" +#~ msgstr "Could not parse \"%s\" as a floating point number" -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "Integer %ld must be positive" +#~ msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" +#~ msgstr "Boolean values must be \"true\" or \"false\" not \"%s\"" -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "Integer %ld is too large, current max is %d" +#~ msgid "Angle must be between 0.0 and 360.0, was %g\n" +#~ msgstr "Angle must be between 0.0 and 360.0, was %g\n" -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "Could not parse \"%s\" as a floating point number" +#~ msgid "" +#~ "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" +#~ msgstr "" +#~ "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "Boolean values must be \"true\" or \"false\" not \"%s\"" +#~ msgid "" +#~ "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," +#~ "large,x-large,xx-large)\n" +#~ msgstr "" +#~ "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," +#~ "large,x-large,xx-large)\n" -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "Angle must be between 0.0 and 360.0, was %g\n" +#~ msgid "<%s> name \"%s\" used a second time" +#~ msgstr "<%s> name \"%s\" used a second time" -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" +#~ msgid "<%s> parent \"%s\" has not been defined" +#~ msgstr "<%s> parent \"%s\" has not been defined" -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" +#~ msgid "<%s> geometry \"%s\" has not been defined" +#~ msgstr "<%s> geometry \"%s\" has not been defined" -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s> name \"%s\" used a second time" +#~ msgid "<%s> must specify either a geometry or a parent that has a geometry" +#~ msgstr "<%s> must specify either a geometry or a parent that has a geometry" -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "<%s> parent \"%s\" has not been defined" +#~ msgid "You must specify a background for an alpha value to be meaningful" +#~ msgstr "You must specify a background for an alpha value to be meaningful" -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "<%s> geometry \"%s\" has not been defined" +#~ msgid "Unknown type \"%s\" on <%s> element" +#~ msgstr "Unknown type \"%s\" on <%s> element" -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "<%s> must specify either a geometry or a parent that has a geometry" +#~ msgid "Unknown style_set \"%s\" on <%s> element" +#~ msgstr "Unknown style_set \"%s\" on <%s> element" -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "You must specify a background for an alpha value to be meaningful" +#~ msgid "Window type \"%s\" has already been assigned a style set" +#~ msgstr "Window type \"%s\" has already been assigned a style set" -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Unknown type \"%s\" on <%s> element" +#~ msgid "Element <%s> is not allowed below <%s>" +#~ msgstr "Element <%s> is not allowed below <%s>" -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "Unknown style_set \"%s\" on <%s> element" +#~ msgid "" +#~ "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio" +#~ "\" for buttons" +#~ msgstr "" +#~ "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio" +#~ "\" for buttons" -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "Window type \"%s\" has already been assigned a style set" - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "Element <%s> is not allowed below <%s>" +#~ msgid "Distance \"%s\" is unknown" +#~ msgstr "Distance \"%s\" is unknown" -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" -msgstr "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" +#~ msgid "Aspect ratio \"%s\" is unknown" +#~ msgstr "Aspect ratio \"%s\" is unknown" -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "Distance \"%s\" is unknown" +#~ msgid "Border \"%s\" is unknown" +#~ msgstr "Border \"%s\" is unknown" -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "Aspect ratio \"%s\" is unknown" +#~ msgid "No \"start_angle\" or \"from\" attribute on element <%s>" +#~ msgstr "No \"start_angle\" or \"from\" attribute on element <%s>" -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "Border \"%s\" is unknown" +#~ msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" +#~ msgstr "No \"extent_angle\" or \"to\" attribute on element <%s>" -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "No \"start_angle\" or \"from\" attribute on element <%s>" +#~ msgid "Did not understand value \"%s\" for type of gradient" +#~ msgstr "Did not understand value \"%s\" for type of gradient" -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "No \"extent_angle\" or \"to\" attribute on element <%s>" +#~ msgid "Did not understand fill type \"%s\" for <%s> element" +#~ msgstr "Did not understand fill type \"%s\" for <%s> element" -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "Did not understand value \"%s\" for type of gradient" +#~ msgid "Did not understand state \"%s\" for <%s> element" +#~ msgstr "Did not understand state \"%s\" for <%s> element" -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "Did not understand fill type \"%s\" for <%s> element" +#~ msgid "Did not understand shadow \"%s\" for <%s> element" +#~ msgstr "Did not understand shadow \"%s\" for <%s> element" -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "Did not understand state \"%s\" for <%s> element" +#~ msgid "Did not understand arrow \"%s\" for <%s> element" +#~ msgstr "Did not understand arrow \"%s\" for <%s> element" -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "Did not understand shadow \"%s\" for <%s> element" +#~ msgid "No <draw_ops> called \"%s\" has been defined" +#~ msgstr "No <draw_ops> called \"%s\" has been defined" -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "Did not understand arrow \"%s\" for <%s> element" +#~ msgid "Including draw_ops \"%s\" here would create a circular reference" +#~ msgstr "Including draw_ops \"%s\" here would create a circular reference" -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "No <draw_ops> called \"%s\" has been defined" +#~ msgid "Unknown position \"%s\" for frame piece" +#~ msgstr "Unknown position \"%s\" for frame piece" -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "Including draw_ops \"%s\" here would create a circular reference" +#~ msgid "Frame style already has a piece at position %s" +#~ msgstr "Frame style already has a piece at position %s" -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Unknown position \"%s\" for frame piece" +#~ msgid "No <draw_ops> with the name \"%s\" has been defined" +#~ msgstr "No <draw_ops> with the name \"%s\" has been defined" -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "Frame style already has a piece at position %s" +#~ msgid "Unknown function \"%s\" for button" +#~ msgstr "Unknown function \"%s\" for button" -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "No <draw_ops> with the name \"%s\" has been defined" +#~ msgid "Button function \"%s\" does not exist in this version (%d, need %d)" +#~ msgstr "Button function \"%s\" does not exist in this version (%d, need %d)" -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Unknown function \"%s\" for button" +#~ msgid "Unknown state \"%s\" for button" +#~ msgstr "Unknown state \"%s\" for button" -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "Button function \"%s\" does not exist in this version (%d, need %d)" +#~ msgid "Frame style already has a button for function %s state %s" +#~ msgstr "Frame style already has a button for function %s state %s" -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Unknown state \"%s\" for button" +#~ msgid "\"%s\" is not a valid value for focus attribute" +#~ msgstr "\"%s\" is not a valid value for focus attribute" -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "Frame style already has a button for function %s state %s" +#~ msgid "\"%s\" is not a valid value for state attribute" +#~ msgstr "\"%s\" is not a valid value for state attribute" -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "\"%s\" is not a valid value for focus attribute" +#~ msgid "A style called \"%s\" has not been defined" +#~ msgstr "A style called \"%s\" has not been defined" -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "\"%s\" is not a valid value for state attribute" +#~ msgid "\"%s\" is not a valid value for resize attribute" +#~ msgstr "\"%s\" is not a valid value for resize attribute" -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "A style called \"%s\" has not been defined" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized/shaded " +#~ "states" +#~ msgstr "" +#~ "Should not have \"resize\" attribute on <%s> element for maximised/shaded " +#~ "states" -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "\"%s\" is not a valid value for resize attribute" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized states" +#~ msgstr "" +#~ "Should not have \"resize\" attribute on <%s> element for maximised states" -#: ../src/ui/theme-parser.c:3147 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" -"Should not have \"resize\" attribute on <%s> element for maximised/shaded " -"states" +#~ msgid "Style has already been specified for state %s resize %s focus %s" +#~ msgstr "Style has already been specified for state %s resize %s focus %s" -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "" -"Should not have \"resize\" attribute on <%s> element for maximised states" +#~ msgid "Style has already been specified for state %s focus %s" +#~ msgstr "Style has already been specified for state %s focus %s" -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "Style has already been specified for state %s resize %s focus %s" +#~ msgid "" +#~ "Can't have a two draw_ops for a <piece> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Can't have a two draw_ops for a <piece> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "Style has already been specified for state %s focus %s" +#~ msgid "" +#~ "Can't have a two draw_ops for a <button> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Can't have a two draw_ops for a <button> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" -#: ../src/ui/theme-parser.c:3294 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" +#~ msgid "" +#~ "Can't have a two draw_ops for a <menu_icon> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Can't have a two draw_ops for a <menu_icon> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" -#: ../src/ui/theme-parser.c:3332 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" +#~ msgid "Bad version specification '%s'" +#~ msgstr "Bad version specification '%s'" -#: ../src/ui/theme-parser.c:3370 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" +#~ msgid "" +#~ "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" +#~ "theme-2.xml" +#~ msgstr "" +#~ "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" +#~ "theme-2.xml" -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "Bad version specification '%s'" +#~ msgid "" +#~ "Theme requires version %s but latest supported theme version is %d.%d" +#~ msgstr "" +#~ "Theme requires version %s but latest supported theme version is %d.%d" -#: ../src/ui/theme-parser.c:3507 -msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" -msgstr "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" +#~ msgid "Outermost element in theme must be <metacity_theme> not <%s>" +#~ msgstr "Outermost element in theme must be <metacity_theme> not <%s>" -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "Theme requires version %s but latest supported theme version is %d.%d" +#~ msgid "" +#~ "Element <%s> is not allowed inside a name/author/date/description element" +#~ msgstr "" +#~ "Element <%s> is not allowed inside a name/author/date/description element" -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "Outermost element in theme must be <metacity_theme> not <%s>" +#~ msgid "Element <%s> is not allowed inside a <constant> element" +#~ msgstr "Element <%s> is not allowed inside a <constant> element" -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "" -"Element <%s> is not allowed inside a name/author/date/description element" +#~ msgid "" +#~ "Element <%s> is not allowed inside a distance/border/aspect_ratio element" +#~ msgstr "" +#~ "Element <%s> is not allowed inside a distance/border/aspect_ratio element" -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "Element <%s> is not allowed inside a <constant> element" +#~ msgid "Element <%s> is not allowed inside a draw operation element" +#~ msgstr "Element <%s> is not allowed inside a draw operation element" -#: ../src/ui/theme-parser.c:3599 -#, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" +#~ msgid "Element <%s> is not allowed inside a <%s> element" +#~ msgstr "Element <%s> is not allowed inside a <%s> element" -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "Element <%s> is not allowed inside a draw operation element" +#~ msgid "No draw_ops provided for frame piece" +#~ msgstr "No draw_ops provided for frame piece" -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "Element <%s> is not allowed inside a <%s> element" +#~ msgid "No draw_ops provided for button" +#~ msgstr "No draw_ops provided for button" -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "No draw_ops provided for frame piece" +#~ msgid "No text is allowed inside element <%s>" +#~ msgstr "No text is allowed inside element <%s>" -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "No draw_ops provided for button" +#~ msgid "<%s> specified twice for this theme" +#~ msgstr "<%s> specified twice for this theme" -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "No text is allowed inside element <%s>" +#~ msgid "Failed to find a valid file for theme %s\n" +#~ msgstr "Failed to find a valid file for theme %s\n" -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "<%s> specified twice for this theme" +#~ msgid "_Windows" +#~ msgstr "_Windows" -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Failed to find a valid file for theme %s\n" +#~ msgid "_Dialog" +#~ msgstr "_Dialogue" -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "_Windows" +#~ msgid "_Modal dialog" +#~ msgstr "_Modal dialogue" -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "_Dialogue" +#~ msgid "_Utility" +#~ msgstr "_Utility" -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "_Modal dialogue" +#~ msgid "_Splashscreen" +#~ msgstr "_Splashscreen" -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "_Utility" +#~ msgid "_Top dock" +#~ msgstr "_Top dock" -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "_Splashscreen" +#~ msgid "_Bottom dock" +#~ msgstr "_Bottom dock" -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "_Top dock" +#~ msgid "_Left dock" +#~ msgstr "_Left dock" -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "_Bottom dock" +#~ msgid "_Right dock" +#~ msgstr "_Right dock" -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "_Left dock" +#~ msgid "_All docks" +#~ msgstr "_All docks" -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "_Right dock" +#~ msgid "Des_ktop" +#~ msgstr "Des_ktop" -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "_All docks" +#~ msgid "Open another one of these windows" +#~ msgstr "Open another one of these windows" -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "Des_ktop" +#~ msgid "This is a demo button with an 'open' icon" +#~ msgstr "This is a demo button with an 'open' icon" -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "Open another one of these windows" +#~ msgid "This is a demo button with a 'quit' icon" +#~ msgstr "This is a demo button with a 'quit' icon" -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "This is a demo button with an 'open' icon" +#~ msgid "This is a sample message in a sample dialog" +#~ msgstr "This is a sample message in a sample dialog" -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "This is a demo button with a 'quit' icon" +#~ msgid "Fake menu item %d\n" +#~ msgstr "Fake menu item %d\n" -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "This is a sample message in a sample dialog" +#~ msgid "Border-only window" +#~ msgstr "Border-only window" -#: ../src/ui/theme-viewer.c:328 -#, c-format -msgid "Fake menu item %d\n" -msgstr "Fake menu item %d\n" +#~ msgid "Bar" +#~ msgstr "Bar" -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "Border-only window" +#~ msgid "Normal Application Window" +#~ msgstr "Normal Application Window" -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "Bar" +#~ msgid "Dialog Box" +#~ msgstr "Dialogue Box" -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "Normal Application Window" +#~ msgid "Modal Dialog Box" +#~ msgstr "Modal Dialogue Box" -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "Dialogue Box" +#~ msgid "Utility Palette" +#~ msgstr "Utility Palette" -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "Modal Dialogue Box" +#~ msgid "Torn-off Menu" +#~ msgstr "Torn-off Menu" -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "Utility Palette" +#~ msgid "Border" +#~ msgstr "Border" -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "Torn-off Menu" +#~ msgid "Attached Modal Dialog" +#~ msgstr "Attached Modal Dialogue" -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "Border" +#~ msgid "Button layout test %d" +#~ msgstr "Button layout test %d" -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "Attached Modal Dialogue" +#~ msgid "%g milliseconds to draw one window frame" +#~ msgstr "%g milliseconds to draw one window frame" -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "Button layout test %d" +#~ msgid "Usage: metacity-theme-viewer [THEMENAME]\n" +#~ msgstr "Usage: metacity-theme-viewer [THEMENAME]\n" -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g milliseconds to draw one window frame" +#~ msgid "Error loading theme: %s\n" +#~ msgstr "Error loading theme: %s\n" -#: ../src/ui/theme-viewer.c:813 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Usage: metacity-theme-viewer [THEMENAME]\n" +#~ msgid "Loaded theme \"%s\" in %g seconds\n" +#~ msgstr "Loaded theme \"%s\" in %g seconds\n" -#: ../src/ui/theme-viewer.c:820 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "Error loading theme: %s\n" +#~ msgid "Normal Title Font" +#~ msgstr "Normal Title Font" -#: ../src/ui/theme-viewer.c:826 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "Loaded theme \"%s\" in %g seconds\n" +#~ msgid "Small Title Font" +#~ msgstr "Small Title Font" -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "Normal Title Font" +#~ msgid "Large Title Font" +#~ msgstr "Large Title Font" -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "Small Title Font" +#~ msgid "Button Layouts" +#~ msgstr "Button Layouts" -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "Large Title Font" +#~ msgid "Benchmark" +#~ msgstr "Benchmark" -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "Button Layouts" +#~ msgid "Window Title Goes Here" +#~ msgstr "Window Title Goes Here" -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "Benchmark" +#~ msgid "" +#~ "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and " +#~ "%g seconds wall clock time including X server resources (%g milliseconds " +#~ "per frame)\n" +#~ msgstr "" +#~ "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and " +#~ "%g seconds wall clock time including X server resources (%g milliseconds " +#~ "per frame)\n" -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "Window Title Goes Here" +#~ msgid "position expression test returned TRUE but set error" +#~ msgstr "position expression test returned TRUE but set error" -#: ../src/ui/theme-viewer.c:1047 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" +#~ msgid "position expression test returned FALSE but didn't set error" +#~ msgstr "position expression test returned FALSE but didn't set error" -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "position expression test returned TRUE but set error" +#~ msgid "Error was expected but none given" +#~ msgstr "Error was expected but none given" -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "position expression test returned FALSE but didn't set error" +#~ msgid "Error %d was expected but %d given" +#~ msgstr "Error %d was expected but %d given" -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "Error was expected but none given" +#~ msgid "Error not expected but one was returned: %s" +#~ msgstr "Error not expected but one was returned: %s" -#: ../src/ui/theme-viewer.c:1274 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "Error %d was expected but %d given" +#~ msgid "x value was %d, %d was expected" +#~ msgstr "x value was %d, %d was expected" -#: ../src/ui/theme-viewer.c:1280 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "Error not expected but one was returned: %s" +#~ msgid "y value was %d, %d was expected" +#~ msgstr "y value was %d, %d was expected" -#: ../src/ui/theme-viewer.c:1284 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "x value was %d, %d was expected" +#~ msgid "" +#~ "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" +#~ msgstr "" +#~ "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "y value was %d, %d was expected" +#, fuzzy +#~ msgid "Minimize window" +#~ msgstr "Minimise window" -#: ../src/ui/theme-viewer.c:1352 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" +#~ msgid "Comma-separated list of compositor plugins" +#~ msgstr "Comma-separated list of compositor plugins" -#~ msgid "Switch to workspace 1" -#~ msgstr "Switch to workspace 1" +#~ msgid "Live Hidden Windows" +#~ msgstr "Live Hidden Windows" + +#~ msgid "" +#~ "Determines whether hidden windows (i.e., minimized windows and windows on " +#~ "other workspaces than the current one) should be kept alive." +#~ msgstr "" +#~ "Determines whether hidden windows (i.e., minimised windows and windows on " +#~ "workspaces other than the current one) should be kept alive." -#~ msgid "Switch to workspace 2" -#~ msgstr "Switch to workspace 2" +#~ msgid "Close Window" +#~ msgstr "Close Window" -#~ msgid "Switch to workspace 3" -#~ msgstr "Switch to workspace 3" +#~ msgid "Window Menu" +#~ msgstr "Window Menu" -#~ msgid "Switch to workspace 4" -#~ msgstr "Switch to workspace 4" +#~ msgid "Minimize Window" +#~ msgstr "Minimise Window" -#~ msgid "Switch to workspace 5" -#~ msgstr "Switch to workspace 5" +#~ msgid "Maximize Window" +#~ msgstr "Maximise Window" -#~ msgid "Switch to workspace 6" -#~ msgstr "Switch to workspace 6" +#~ msgid "Restore Window" +#~ msgstr "Restore Window" -#~ msgid "Switch to workspace 7" -#~ msgstr "Switch to workspace 7" +#~ msgid "Roll Up Window" +#~ msgstr "Roll Up Window" -#~ msgid "Switch to workspace 8" -#~ msgstr "Switch to workspace 8" +#~ msgid "Unroll Window" +#~ msgstr "Unroll Window" -#~ msgid "Switch to workspace 9" -#~ msgstr "Switch to workspace 9" +#~ msgid "Keep Window On Top" +#~ msgstr "Keep Window On Top" -#~ msgid "Switch to workspace 10" -#~ msgstr "Switch to workspace 10" +#~ msgid "Remove Window From Top" +#~ msgstr "Remove Window From Top" -#~ msgid "Switch to workspace 11" -#~ msgstr "Switch to workspace 11" +#~ msgid "Always On Visible Workspace" +#~ msgstr "Always On Visible Workspace" -#~ msgid "Switch to workspace 12" -#~ msgstr "Switch to workspace 12" +#~ msgid "Put Window On Only One Workspace" +#~ msgstr "Put Window On Only One Workspace" #~ msgid "Switch to workspace on the left of the current workspace" #~ msgstr "Switch to workspace on the left of the current workspace" @@ -1721,54 +1738,12 @@ msgstr "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" #~ msgid "Run a terminal" #~ msgstr "Run a terminal" -#~ msgid "Activate the window menu" -#~ msgstr "Activate the window menu" - -#~ msgid "Toggle fullscreen mode" -#~ msgstr "Toggle fullscreen mode" - -#~ msgid "Toggle maximization state" -#~ msgstr "Toggle maximisation state" - #~ msgid "Toggle whether a window will always be visible over other windows" #~ msgstr "Toggle whether a window will always be visible over other windows" -#~ msgid "Maximize window" -#~ msgstr "Maximise window" - -#~ msgid "Restore window" -#~ msgstr "Restore window" - -#~ msgid "Toggle shaded state" -#~ msgstr "Toggle shaded state" - -#~ msgid "Minimize window" -#~ msgstr "Minimise window" - -#~ msgid "Close window" -#~ msgstr "Close window" - -#~ msgid "Move window" -#~ msgstr "Move window" - -#~ msgid "Resize window" -#~ msgstr "Resize window" - #~ msgid "Toggle whether window is on all workspaces or just one" #~ msgstr "Toggle whether window is on all workspaces or just one" -#~ msgid "Move window to workspace 1" -#~ msgstr "Move window to workspace 1" - -#~ msgid "Move window to workspace 2" -#~ msgstr "Move window to workspace 2" - -#~ msgid "Move window to workspace 3" -#~ msgstr "Move window to workspace 3" - -#~ msgid "Move window to workspace 4" -#~ msgstr "Move window to workspace 4" - #~ msgid "Move window to workspace 5" #~ msgstr "Move window to workspace 5" @@ -1793,33 +1768,9 @@ msgstr "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" #~ msgid "Move window to workspace 12" #~ msgstr "Move window to workspace 12" -#~ msgid "Move window one workspace to the left" -#~ msgstr "Move window one workspace to the left" - -#~ msgid "Move window one workspace to the right" -#~ msgstr "Move window one workspace to the right" - -#~ msgid "Move window one workspace up" -#~ msgstr "Move window one workspace up" - -#~ msgid "Move window one workspace down" -#~ msgstr "Move window one workspace down" - #~ msgid "Raise window if it's covered by another window, otherwise lower it" #~ msgstr "Raise window if it's covered by another window, otherwise lower it" -#~ msgid "Raise window above other windows" -#~ msgstr "Raise window above other windows" - -#~ msgid "Lower window below other windows" -#~ msgstr "Lower window below other windows" - -#~ msgid "Maximize window vertically" -#~ msgstr "Maximise window vertically" - -#~ msgid "Maximize window horizontally" -#~ msgstr "Maximise window horizontally" - #~ msgid "Move window to north-west (top left) corner" #~ msgstr "Move window to north-west (top left) corner" @@ -1927,9 +1878,6 @@ msgstr "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" #~ msgid "Error setting clutter plugin list: %s\n" #~ msgstr "Error setting Clutter plugin list: %s\n" -#~ msgid "Clutter Plugins" -#~ msgstr "Clutter Plugins" - #~ msgid "Plugins to load for the Clutter-based compositing manager." #~ msgstr "Plugins to load for the Clutter-based compositing manager." @@ -2090,9 +2038,6 @@ msgstr "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" #~ msgid "Commands to run in response to keybindings" #~ msgstr "Commands to run in response to keybindings" -#~ msgid "Compositing Manager" -#~ msgstr "Compositing Manager" - #~ msgid "Control how new windows get focus" #~ msgstr "Control how new windows get focus" @@ -2120,17 +2065,6 @@ msgstr "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" #~ msgid "Enable Visual Bell" #~ msgstr "Enable Visual Bell" -#~ msgid "" -#~ "If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " -#~ "the focused window will be automatically raised after a delay specified " -#~ "by the auto_raise_delay key. This is not related to clicking on a window " -#~ "to raise it, nor to entering a window during drag-and-drop." -#~ msgstr "" -#~ "If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " -#~ "the focused window will be automatically raised after a delay specified " -#~ "by the auto_raise_delay key. This is not related to clicking on a window " -#~ "to raise it, nor to entering a window during drag-and-drop." - #~ msgid "" #~ "If true, ignore the titlebar_font option, and use the standard " #~ "application font for window titles." diff --git a/po/eo.po b/po/eo.po index 072d8d894..5afda45a6 100644 --- a/po/eo.po +++ b/po/eo.po @@ -1,1822 +1,1167 @@ -# Esperanto translation for muffin -# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 -# This file is distributed under the same license as the muffin package. +# Esperanto translation for mutter. +# Copyright (C) 2011 Free Software Foundation, Inc. +# This file is distributed under the same license as the mutter package. # Michael MORONI < >, 2011. -# Kristjan SCHMIDT <kristjan.schmidt@googlemail.com>, 2011. -# +# Kristjan SCHMIDT <kristjan.schmidt@googlemail.com>, 2011, 2012, 2015, 2018. msgid "" msgstr "" -"Project-Id-Version: muffin\n" -"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" -"product=muffin&keywords=I18N+L10N&component=general\n" -"POT-Creation-Date: 2011-04-05 06:28+0000\n" -"PO-Revision-Date: 2011-04-19 18:44+0200\n" +"Project-Id-Version: mutter\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=mutter" +"&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-12-18 16:24+0000\n" +"PO-Revision-Date: 2018-01-22 20:12+0200\n" "Last-Translator: Kristjan SCHMIDT <kristjan.schmidt@googlemail.com>\n" -"Language-Team: Esperanto <ubuntu-l10n-eo@lists.launchpad.net>\n" +"Language-Team: Esperanto <gnome-eo-list@gnome.org>\n" "Language: eo\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-04-19 16:32+0000\n" -"X-Generator: Launchpad (build 12847)\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Virtaal 0.7.1\n" +"X-Project-Style: gnome\n" -#: ../src/core/all-keybindings.h:88 -msgid "Switch to workspace 1" -msgstr "Ŝalti al laborspaco 1" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Navigado" -#: ../src/core/all-keybindings.h:90 -msgid "Switch to workspace 2" -msgstr "Ŝalti al laborspaco 2" +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Movi la fenestron al laborspaco 1" -#: ../src/core/all-keybindings.h:92 -msgid "Switch to workspace 3" -msgstr "Ŝalti al laborspaco 3" +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Movi la fenestron al laborspaco 2" -#: ../src/core/all-keybindings.h:94 -msgid "Switch to workspace 4" -msgstr "Ŝalti al laborspaco 4" +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Movi la fenestron al laborspaco 3" + +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Movi la fenestron al laborspaco 4" + +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Movi la fenestron al lasta laborspaco" + +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace to the left" +msgstr "Movi la fenestron al la maldekstra laborspaco" + +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace to the right" +msgstr "Movi la fenestron al la dekstra laborspaco" + +#: data/50-mutter-navigation.xml:30 +msgid "Move window one workspace up" +msgstr "Movi la fenestron al la supra laborspaco" + +#: data/50-mutter-navigation.xml:33 +msgid "Move window one workspace down" +msgstr "Movi la fenestron al la suba laborspaco" + +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor to the left" +msgstr "Movi la fenestron al la maldekstra ekrano" + +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor to the right" +msgstr "Movi la fenestron al la dekstra ekrano" -#: ../src/core/all-keybindings.h:96 -msgid "Switch to workspace 5" -msgstr "Ŝalti al laborspaco 5" +#: data/50-mutter-navigation.xml:42 +msgid "Move window one monitor up" +msgstr "Movi la fenestron al la supra ekrano" -#: ../src/core/all-keybindings.h:98 -msgid "Switch to workspace 6" -msgstr "Ŝalti al laborspaco 6" +#: data/50-mutter-navigation.xml:45 +msgid "Move window one monitor down" +msgstr "Movi la fenestron al la suba ekrano" -#: ../src/core/all-keybindings.h:100 -msgid "Switch to workspace 7" -msgstr "Ŝalti al laborspaco 7" +#: data/50-mutter-navigation.xml:49 +msgid "Switch applications" +msgstr "Ŝanĝi aplikaĵojn" -#: ../src/core/all-keybindings.h:102 -msgid "Switch to workspace 8" -msgstr "Ŝalti al laborspaco 8" +#: data/50-mutter-navigation.xml:54 +msgid "Switch to previous application" +msgstr "Ŝalti al antaŭa aplikaĵo" -#: ../src/core/all-keybindings.h:104 -msgid "Switch to workspace 9" -msgstr "Ŝalti al laborspaco 9" +#: data/50-mutter-navigation.xml:58 +msgid "Switch windows" +msgstr "Ŝanĝi fenestrojn" -#: ../src/core/all-keybindings.h:106 -msgid "Switch to workspace 10" -msgstr "Ŝalti al laborspaco 10" +#: data/50-mutter-navigation.xml:63 +msgid "Switch to previous window" +msgstr "Ŝalti al antaŭa fenestro" -#: ../src/core/all-keybindings.h:108 -msgid "Switch to workspace 11" -msgstr "Ŝalti al laborspaco 11" +#: data/50-mutter-navigation.xml:67 +msgid "Switch windows of an application" +msgstr "Ŝanĝi fenestrojn de aplikaĵo" -#: ../src/core/all-keybindings.h:110 -msgid "Switch to workspace 12" -msgstr "Ŝalti al laborspaco 12" +#: data/50-mutter-navigation.xml:72 +msgid "Switch to previous window of an application" +msgstr "Ŝalti al antaŭa fenestro de aplikaĵo" -#: ../src/core/all-keybindings.h:122 -msgid "Switch to workspace on the left of the current workspace" -msgstr "Ŝalti al la laborspaco maldekstre de la aktuala laborspaco" +#: data/50-mutter-navigation.xml:76 +msgid "Switch system controls" +msgstr "Ŝanĝi sistem-kontrolojn" -#: ../src/core/all-keybindings.h:126 -msgid "Switch to workspace on the right of the current workspace" -msgstr "Ŝalti al la laborspaco dekstre de la aktuala laborspaco" +#: data/50-mutter-navigation.xml:81 +msgid "Switch to previous system control" +msgstr "Ŝalti al antaŭa sistem-kontrolo" -#: ../src/core/all-keybindings.h:130 -msgid "Switch to workspace above the current workspace" -msgstr "Ŝalti al laborspaco super la aktuala laborspaco" +#: data/50-mutter-navigation.xml:85 +msgid "Switch windows directly" +msgstr "Ŝanĝi rekte fenestrojn" -#: ../src/core/all-keybindings.h:134 -msgid "Switch to workspace below the current workspace" -msgstr "Ŝalti al laborspaco sub la aktuala laborspaco" +#: data/50-mutter-navigation.xml:90 +msgid "Switch directly to previous window" +msgstr "Ŝalti rekte al antaŭa fenestro" -#: ../src/core/all-keybindings.h:150 -msgid "Move between windows of an application, using a popup window" -msgstr "Moviĝi inter fenestroj de aplikaĵo, uzante ŝprucfenestron" +#: data/50-mutter-navigation.xml:94 +msgid "Switch windows of an app directly" +msgstr "Ŝanĝi rekte fenestrojn de aplikaĵo" -#: ../src/core/all-keybindings.h:153 -msgid "Move backward between windows of an application, using a popup window" -msgstr "Moviĝi malantaŭen inter fenestroj de aplikaĵo, uzante ŝprucfenestron" +#: data/50-mutter-navigation.xml:99 +msgid "Switch directly to previous window of an app" +msgstr "Ŝalti rekte al antaŭa fenestro de aplikaĵo" -#: ../src/core/all-keybindings.h:157 -msgid "Move between windows, using a popup window" -msgstr "Moviĝi inter fenestroj, uzante ŝprucfenestron" +#: data/50-mutter-navigation.xml:103 +msgid "Switch system controls directly" +msgstr "Ŝalti rekte sistem-kontrolojn" -#: ../src/core/all-keybindings.h:160 -msgid "Move backward between windows, using a popup window" -msgstr "Moviĝi malantaŭen inter fenestroj, uzante ŝprucfenestron" +#: data/50-mutter-navigation.xml:108 +msgid "Switch directly to previous system control" +msgstr "Ŝalti rekte al antaŭa sistem-kontrolo" -#: ../src/core/all-keybindings.h:163 -msgid "Move between panels and the desktop, using a popup window" -msgstr "Moviĝi inter paneloj kaj labortablo, uzante ŝprucfenestron" +#: data/50-mutter-navigation.xml:111 +msgid "Hide all normal windows" +msgstr "Kaŝi ĉiujn normalajn fenestrojn" -#: ../src/core/all-keybindings.h:166 -msgid "Move backward between panels and the desktop, using a popup window" -msgstr "Moviĝi malantaŭen inter paneloj kaj labortablo, uzante ŝprucfenestron" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 1" +msgstr "Ŝalti al laborspaco 1" -#: ../src/core/all-keybindings.h:171 -msgid "Move between windows of an application immediately" -msgstr "Moviĝi tuj inter fenestroj de aplikaĵo" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 2" +msgstr "Ŝalti al laborspaco 2" -#: ../src/core/all-keybindings.h:174 -msgid "Move backward between windows of an application immediately" -msgstr "Moviĝi tuj malantaŭen inter fenestroj de aplikaĵo" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to workspace 3" +msgstr "Ŝalti al laborspaco 3" -#: ../src/core/all-keybindings.h:177 -msgid "Move between windows immediately" -msgstr "Moviĝi tuj inter fenestroj" +#: data/50-mutter-navigation.xml:123 +msgid "Switch to workspace 4" +msgstr "Ŝalti al laborspaco 4" -#: ../src/core/all-keybindings.h:180 -msgid "Move backward between windows immediately" -msgstr "Moviĝi tuj malantaŭen inter fenestroj" +#: data/50-mutter-navigation.xml:126 +msgid "Switch to last workspace" +msgstr "Ŝalti al lasta laborspaco" -#: ../src/core/all-keybindings.h:183 -msgid "Move between panels and the desktop immediately" -msgstr "Moviĝi tuj inter paneloj kaj labortablo" +#: data/50-mutter-navigation.xml:129 +msgid "Move to workspace left" +msgstr "Movi al la maldekstra laborspaco" -#: ../src/core/all-keybindings.h:186 -msgid "Move backward between panels and the desktop immediately" -msgstr "Moviĝi tuj malantaŭen inter paneloj kaj labortablo" +#: data/50-mutter-navigation.xml:132 +msgid "Move to workspace right" +msgstr "Movi al la dekstra laborspaco" -#: ../src/core/all-keybindings.h:203 -msgid "Hide all normal windows and set focus to the desktop" -msgstr "Kaŝi ĉiujn normalajn fenestrojn kaj enfokusigi la labortablon" +#: data/50-mutter-navigation.xml:135 +msgid "Move to workspace above" +msgstr "Movi al la supra laborspaco" -#: ../src/core/all-keybindings.h:206 -msgid "Show the panel's main menu" -msgstr "Montri la ĉefmenuon de la panelo" +#: data/50-mutter-navigation.xml:138 +msgid "Move to workspace below" +msgstr "Movi al la malsupra laborspaco" -#: ../src/core/all-keybindings.h:209 -msgid "Show the panel's \"Run Application\" dialog box" -msgstr "Montri la dialogujon \"Ruli aplikaĵon\" de la panelo" +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "Sistemo" -#: ../src/core/all-keybindings.h:211 -msgid "Start or stop recording the session" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" msgstr "" -#: ../src/core/all-keybindings.h:252 -msgid "Take a screenshot" -msgstr "Fari ekrankopion" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "" -#: ../src/core/all-keybindings.h:254 -msgid "Take a screenshot of a window" -msgstr "Ekrankopii fenestron" +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "" -#: ../src/core/all-keybindings.h:256 -msgid "Run a terminal" -msgstr "Ruli terminalon" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Fenestroj" -#: ../src/core/all-keybindings.h:271 +#: data/50-mutter-windows.xml:8 msgid "Activate the window menu" msgstr "Aktivigi la fenestromenuon" -#: ../src/core/all-keybindings.h:274 +#: data/50-mutter-windows.xml:10 msgid "Toggle fullscreen mode" msgstr "Baskuligi tutekranan reĝimon" -#: ../src/core/all-keybindings.h:276 +#: data/50-mutter-windows.xml:12 msgid "Toggle maximization state" msgstr "" -#: ../src/core/all-keybindings.h:278 -msgid "Toggle whether a window will always be visible over other windows" -msgstr "" - -#: ../src/core/all-keybindings.h:280 +#: data/50-mutter-windows.xml:14 msgid "Maximize window" msgstr "Maksimumigi la fenestron" -#: ../src/core/all-keybindings.h:282 +#: data/50-mutter-windows.xml:16 msgid "Restore window" -msgstr "Restaŭri fenestron" +msgstr "Restaŭri la fenestron" -#: ../src/core/all-keybindings.h:284 +#: data/50-mutter-windows.xml:18 msgid "Toggle shaded state" msgstr "" -#: ../src/core/all-keybindings.h:286 -msgid "Minimize window" -msgstr "Minimumigi fenestron" - -#: ../src/core/all-keybindings.h:288 +#: data/50-mutter-windows.xml:20 msgid "Close window" msgstr "Fermi la fenestron" -#: ../src/core/all-keybindings.h:290 +#: data/50-mutter-windows.xml:22 +msgid "Hide window" +msgstr "Kaŝi la fenestron" + +#: data/50-mutter-windows.xml:24 msgid "Move window" msgstr "Movi la fenestron" -#: ../src/core/all-keybindings.h:292 +#: data/50-mutter-windows.xml:26 msgid "Resize window" msgstr "Ŝanĝi la fenestrograndon" -#: ../src/core/all-keybindings.h:295 -msgid "Toggle whether window is on all workspaces or just one" +#: data/50-mutter-windows.xml:29 +msgid "Toggle window on all workspaces or one" msgstr "" -#: ../src/core/all-keybindings.h:299 -msgid "Move window to workspace 1" -msgstr "Movi la fenestron al laborspaco 1" +#: data/50-mutter-windows.xml:31 +msgid "Raise window if covered, otherwise lower it" +msgstr "" -#: ../src/core/all-keybindings.h:302 -msgid "Move window to workspace 2" -msgstr "Movi la fenestron al laborspaco 2" +#: data/50-mutter-windows.xml:33 +msgid "Raise window above other windows" +msgstr "" -#: ../src/core/all-keybindings.h:305 -msgid "Move window to workspace 3" -msgstr "Movi la fenestron al laborspaco 3" +#: data/50-mutter-windows.xml:35 +msgid "Lower window below other windows" +msgstr "" -#: ../src/core/all-keybindings.h:308 -msgid "Move window to workspace 4" -msgstr "Movi la fenestron al laborspaco 4" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window vertically" +msgstr "Vertikale maksimumigi la fenestron" -#: ../src/core/all-keybindings.h:311 -msgid "Move window to workspace 5" -msgstr "Movi la fenestron al laborspaco 5" +#: data/50-mutter-windows.xml:39 +msgid "Maximize window horizontally" +msgstr "Horizontale maksimumigi la fenestron" -#: ../src/core/all-keybindings.h:314 -msgid "Move window to workspace 6" -msgstr "Movi la fenestron al laborspaco 6" +#: data/50-mutter-windows.xml:43 +msgid "View split on left" +msgstr "" -#: ../src/core/all-keybindings.h:317 -msgid "Move window to workspace 7" -msgstr "Movi la fenestron al laborspaco 7" +#: data/50-mutter-windows.xml:47 +msgid "View split on right" +msgstr "" -#: ../src/core/all-keybindings.h:320 -msgid "Move window to workspace 8" -msgstr "Movi la fenestron al laborspaco 8" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutero" -#: ../src/core/all-keybindings.h:323 -msgid "Move window to workspace 9" -msgstr "Movi la fenestron al laborspaco 9" +#: data/org.gnome.mutter.gschema.xml.in:7 +msgid "Modifier to use for extended window management operations" +msgstr "" -#: ../src/core/all-keybindings.h:326 -msgid "Move window to workspace 10" -msgstr "Movi la fenestron al laborspaco 10" +#: data/org.gnome.mutter.gschema.xml.in:8 +msgid "" +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." +msgstr "" -#: ../src/core/all-keybindings.h:329 -msgid "Move window to workspace 11" -msgstr "Movi la fenestron al laborspaco 11" +#: data/org.gnome.mutter.gschema.xml.in:20 +msgid "Attach modal dialogs" +msgstr "" -#: ../src/core/all-keybindings.h:332 -msgid "Move window to workspace 12" -msgstr "Movi la fenestron al laborspaco 12" +#: data/org.gnome.mutter.gschema.xml.in:21 +msgid "" +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." +msgstr "" -#: ../src/core/all-keybindings.h:344 -msgid "Move window one workspace to the left" -msgstr "Movi la fenestron al la maldekstra laborspaco" +#: data/org.gnome.mutter.gschema.xml.in:30 +msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "" -#: ../src/core/all-keybindings.h:347 -msgid "Move window one workspace to the right" -msgstr "Movi la fenestron al la dekstra laborspaco" +#: data/org.gnome.mutter.gschema.xml.in:31 +msgid "" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." +msgstr "" -#: ../src/core/all-keybindings.h:350 -msgid "Move window one workspace up" -msgstr "Movi la fenestron al la supra laborspaco" +#: data/org.gnome.mutter.gschema.xml.in:40 +msgid "Workspaces are managed dynamically" +msgstr "" -#: ../src/core/all-keybindings.h:353 -msgid "Move window one workspace down" -msgstr "Movi la fenestron al la suba laborspaco" +#: data/org.gnome.mutter.gschema.xml.in:41 +msgid "" +"Determines whether workspaces are managed dynamically or whether there’s a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." +msgstr "" -#: ../src/core/all-keybindings.h:356 -msgid "Raise window if it's covered by another window, otherwise lower it" +#: data/org.gnome.mutter.gschema.xml.in:50 +msgid "Workspaces only on primary" msgstr "" -#: ../src/core/all-keybindings.h:358 -msgid "Raise window above other windows" +#: data/org.gnome.mutter.gschema.xml.in:51 +msgid "" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." msgstr "" -#: ../src/core/all-keybindings.h:360 -msgid "Lower window below other windows" +#: data/org.gnome.mutter.gschema.xml.in:59 +msgid "No tab popup" msgstr "" -#: ../src/core/all-keybindings.h:364 -msgid "Maximize window vertically" -msgstr "Vertikale maksimumigi la fenestron" +#: data/org.gnome.mutter.gschema.xml.in:60 +msgid "" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." +msgstr "" -#: ../src/core/all-keybindings.h:368 -msgid "Maximize window horizontally" -msgstr "Horizontale maksimumigi la fenestron" +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "" -#: ../src/core/all-keybindings.h:372 -msgid "Move window to north-west (top left) corner" +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." msgstr "" -#: ../src/core/all-keybindings.h:375 -msgid "Move window to north-east (top right) corner" +#: data/org.gnome.mutter.gschema.xml.in:79 +msgid "Draggable border width" msgstr "" -#: ../src/core/all-keybindings.h:378 -msgid "Move window to south-west (bottom left) corner" +#: data/org.gnome.mutter.gschema.xml.in:80 +msgid "" +"The amount of total draggable borders. If the theme’s visible borders are " +"not enough, invisible borders will be added to meet this value." msgstr "" -#: ../src/core/all-keybindings.h:381 -msgid "Move window to south-east (bottom right) corner" +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" msgstr "" -#: ../src/core/all-keybindings.h:385 -msgid "Move window to north (top) side of screen" +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." msgstr "" -#: ../src/core/all-keybindings.h:388 -msgid "Move window to south (bottom) side of screen" +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" msgstr "" -#: ../src/core/all-keybindings.h:391 -msgid "Move window to east (right) side of screen" +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." msgstr "" -#: ../src/core/all-keybindings.h:394 -msgid "Move window to west (left) side of screen" +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" msgstr "" -#: ../src/core/all-keybindings.h:397 -msgid "Move window to center of screen" +#: data/org.gnome.mutter.gschema.xml.in:108 +msgid "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “remote-desktop” — " +"enables remote desktop support. To support remote desktop with screen " +"sharing, “screen-cast” must also be enabled. • “screen-cast” — enables " +"screen cast support." msgstr "" -#: ../src/core/bell.c:310 -msgid "Bell event" -msgstr "Sonoril-evento" +#: data/org.gnome.mutter.gschema.xml.in:145 +msgid "Select window from tab popup" +msgstr "" -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Nekonata peto pri fenestra informo: %d" +#: data/org.gnome.mutter.gschema.xml.in:150 +msgid "Cancel tab popup" +msgstr "" -#. Translators: %s is a window title -#: ../src/core/delete.c:94 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> ne respondas." +#: data/org.gnome.mutter.gschema.xml.in:155 +#, fuzzy +#| msgid "Switch applications" +msgid "Switch monitor configurations" +msgstr "Ŝanĝi aplikaĵojn" -#: ../src/core/delete.c:99 -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." +#: data/org.gnome.mutter.gschema.xml.in:160 +msgid "Rotates the built-in monitor configuration" msgstr "" -#: ../src/core/delete.c:108 -msgid "_Wait" -msgstr "_Atendi" +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Ŝalti al virtuala terminalo 1" -#: ../src/core/delete.c:108 -msgid "_Force Quit" -msgstr "Per_forta eliro" +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Ŝalti al virtuala terminalo 2" -#: ../src/core/display.c:365 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "Aldonaĵo %s necesanta por kompostado mankas" +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Ŝalti al virtuala terminalo 3" -#: ../src/core/display.c:431 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Malsukcesis malfermi jenan vidigon de fenestra sistemo X: '%s'\n" +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Ŝalti al virtuala terminalo 4" -#: ../src/core/keybindings.c:759 -#, c-format +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +#| msgid "Switch to workspace 5" +msgid "Switch to VT 5" +msgstr "Ŝalti al virtuala terminalo 5" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +#| msgid "Switch to workspace 6" +msgid "Switch to VT 6" +msgstr "Ŝalti al virtuala terminalo 6" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +#| msgid "Switch to workspace 7" +msgid "Switch to VT 7" +msgstr "Ŝalti al virtuala terminalo 7" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Ŝalti al virtuala terminalo 8" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Ŝalti al virtuala terminalo 9" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Ŝalti al virtuala terminalo 10" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Ŝalti al virtuala terminalo 11" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Ŝalti al virtuala terminalo 12" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "Re-ŝalti klavkombinojn" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow grabs with Xwayland" +msgstr "" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" +"Allow keyboard grabs issued by X11 applications running in Xwayland to be " +"taken into account. For a X11 grab to be taken into account under Wayland, " +"the client must also either send a specific X11 ClientMessage to the root " +"window or be among the applications white-listed in key “xwayland-grab-" +"access-rules”." +msgstr "" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:77 +msgid "Xwayland applications allowed to issue keyboard grabs" msgstr "" -"Iu alia programo jam uzas la klavon %s kun modifiloj %x kiel bindaĵon\n" -#. Displayed when a keybinding which is -#. * supposed to launch a program fails. +#: data/org.gnome.mutter.wayland.gschema.xml.in:78 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "" + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. #. -#: ../src/core/keybindings.c:2468 +#: src/backends/meta-input-settings.c:2260 #, c-format -msgid "" -"There was an error running <tt>%s</tt>:\n" -"\n" -"%s" +msgid "Mode Switch (Group %d)" msgstr "" -"Okazis eraro lanĉante <tt>%s</tt>:\n" -"\n" -"%s" -#: ../src/core/keybindings.c:2558 -#, c-format -msgid "No command %d has been defined.\n" -msgstr "Neniu komando %d estis difinita.\n" +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2283 +#, fuzzy +#| msgid "Switch system controls" +msgid "Switch monitor" +msgstr "Ŝanĝi sistem-kontrolojn" -#: ../src/core/keybindings.c:3570 -#, c-format -msgid "No terminal command has been defined.\n" -msgstr "Neniu terminala komando estis difinita.\n" +#: src/backends/meta-input-settings.c:2285 +msgid "Show on-screen help" +msgstr "Montri ekranhelpon" -#: ../src/core/main.c:206 +#: src/backends/meta-monitor-manager.c:900 +msgid "Built-in display" +msgstr "" + +#: src/backends/meta-monitor-manager.c:923 +msgid "Unknown" +msgstr "Nekonate" + +#: src/backends/meta-monitor-manager.c:925 +msgid "Unknown Display" +msgstr "Nekonata ekrano" + +#. TRANSLATORS: this is a monitor vendor name, followed by a +#. * size in inches, like 'Dell 15"' +#. +#: src/backends/meta-monitor-manager.c:933 +#, c-format +msgid "%s %s" +msgstr "%s %s" + +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:479 +#, fuzzy, c-format +#| msgid "" +#| "Another compositing manager is already running on screen %i on display " +#| "\"%s\"." +msgid "" +"Another compositing manager is already running on screen %i on display “%s”." +msgstr "Alia kunmetanta administrilo jam rulas sur ekrano %i de montrilo “%s”." + +#: src/core/bell.c:194 +msgid "Bell event" +msgstr "Sonoril-evento" + +#: src/core/display.c:608 +#, fuzzy, c-format +#| msgid "Failed to open X Window System display '%s'\n" +msgid "Failed to open X Window System display “%s”\n" +msgstr "Malsukcesis malfermi jenan vidigon de fenestra sistemo X “%s”\n" + +#: src/core/main.c:189 msgid "Disable connection to session manager" msgstr "Elŝalti konekton al la seancoadministrilo" -#: ../src/core/main.c:212 +#: src/core/main.c:195 msgid "Replace the running window manager" -msgstr "Anstataŭigi la nun ruliĝantan fenestromastrumilon" +msgstr "Anstataŭigi la nun ruliĝantan fenestromastrumilon" -#: ../src/core/main.c:218 +#: src/core/main.c:201 msgid "Specify session management ID" msgstr "Specifi identigilon de la seancoadministrilo" -#: ../src/core/main.c:223 +#: src/core/main.c:206 +#, fuzzy msgid "X Display to use" msgstr "X-Vidigo uzenda" -#: ../src/core/main.c:229 +#: src/core/main.c:212 msgid "Initialize session from savefile" msgstr "Pravalorizi la seancon el konservita dosiero" -#: ../src/core/main.c:235 +#: src/core/main.c:218 msgid "Make X calls synchronous" msgstr "Fari X-vokojn sinkrone" -#: ../src/core/main.c:506 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Malsukcesis skani etosan dosierujon %s\n" +#: src/core/main.c:225 +msgid "Run as a wayland compositor" +msgstr "" + +#: src/core/main.c:231 +msgid "Run as a nested compositor" +msgstr "" + +#: src/core/main.c:239 +msgid "Run as a full display server, rather than nested" +msgstr "" -#: ../src/core/main.c:522 +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:147 #, c-format +msgid "“%s” is not responding." +msgstr "“%s” ne respondas." + +#: src/core/meta-close-dialog-default.c:149 +msgid "Application is not responding." +msgstr "Aplikaĵo ne respondas." + +#: src/core/meta-close-dialog-default.c:154 msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "" -"Ne eblis trovi ian etoson! Certigu, ke %s ekzistas kaj enhavas la ordinarajn " -"etosojn.\n" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." +msgstr "Vi povas elekti ĉu atendi iomete por la aplikaĵo aŭ perforte ĉesi ĝin." + +#: src/core/meta-close-dialog-default.c:161 +msgid "_Force Quit" +msgstr "Per_forta eliro" + +#: src/core/meta-close-dialog-default.c:161 +msgid "_Wait" +msgstr "_Atendi" -#: ../src/core/muffin.c:42 +#: src/core/mutter.c:39 #, c-format +#| msgid "" +#| "mutter %s\n" +#| "Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +#| "This is free software; see the source for copying conditions.\n" +#| "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +#| "PARTICULAR PURPOSE.\n" msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" "This is free software; see the source for copying conditions.\n" "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " "PARTICULAR PURPOSE.\n" msgstr "" +"Mutero %s\n" +"Kopirajto © 2001-%d Havoc PENNIGTON, Red Hat, Inc., kaj aliaj\n" +"Ĉi tio estas libera programaro; rigardu la fontkodon por kondiĉoj pri " +"kopiado.\n" +"Ekzistas NENIU garantio; nek por NEGOCEBLO nek por ADAPTADO AL IU APARTA " +"CELO.\n" -#: ../src/core/muffin.c:56 +#: src/core/mutter.c:53 msgid "Print version" -msgstr "Pres-versio" +msgstr "Motri version" -#: ../src/core/muffin.c:62 -msgid "Comma-separated list of compositor plugins" +#: src/core/mutter.c:59 +msgid "Mutter plugin to use" msgstr "" -#. -#. * We found it, but it was invalid. Complain. -#. * -#. * FIXME: This replicates the original behaviour, but in the future -#. * we might consider reverting invalid keys to their original values. -#. * (We know the old value, so we can look up a suitable string in -#. * the symtab.) -#. * -#. * (Empty comment follows so the translators don't see this.) -#. -#. -#: ../src/core/prefs.c:543 ../src/core/prefs.c:704 +#: src/core/prefs.c:1997 #, c-format -msgid "GConf key '%s' is set to an invalid value\n" -msgstr "La GConf-ŝlosilo '%s' havas ne-validan valoron.\n" +msgid "Workspace %d" +msgstr "Laborspaco %d" -#: ../src/core/prefs.c:630 ../src/core/prefs.c:873 +#: src/core/screen.c:583 #, c-format -msgid "%d stored in GConf key %s is out of range %d to %d\n" +#| msgid "" +#| "Display \"%s\" already has a window manager; try using the --replace " +#| "option to replace the current window manager." +msgid "" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." msgstr "" -"La valoro %d de la GConf-ŝlosilo %s estas ekster intervalo de %d ĝis %d\n" +"Ekrano “%s” jam havas fenestroadministrilon; provu uzi la opcion --replace " +"por anstataŭigi la nunan fenestroadministrilon." -#: ../src/core/prefs.c:674 ../src/core/prefs.c:751 ../src/core/prefs.c:799 -#: ../src/core/prefs.c:863 ../src/core/prefs.c:1324 ../src/core/prefs.c:1340 -#: ../src/core/prefs.c:1357 ../src/core/prefs.c:1373 -#, c-format -msgid "GConf key \"%s\" is set to an invalid type\n" -msgstr "La GConf-ŝlosilo \"%s\" havas nevalidan valoron.\n" +#: src/core/screen.c:668 +#, fuzzy, c-format +#| msgid "Screen %d on display '%s' is invalid\n" +msgid "Screen %d on display “%s” is invalid\n" +msgstr "Ekrano %d en vidigilo “%s” estas nevalida\n" -#: ../src/core/prefs.c:1203 -#, c-format -msgid "GConf key %s is already in use and can't be used to override %s\n" -msgstr "" +#: src/core/util.c:120 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutero estis kompilita sen subteno por eksplicita reĝimo\n" -#: ../src/core/prefs.c:1262 +#: src/wayland/meta-wayland-tablet-pad.c:563 #, c-format -msgid "Can't override GConf key, %s not found\n" -msgstr "" +msgid "Mode Switch: Mode %d" +msgstr "Reĝim-ŝaltilo: Reĝimo %d" -#: ../src/core/prefs.c:1447 +#: src/x11/session.c:1815 msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." msgstr "" -"Provizoraj solvoj por rompitaj aplikaĵoj estas elŝaltitaj. Kelkaj aplikaĵoj " -"povus ruli malkorekte.\n" -#: ../src/core/prefs.c:1524 +#: src/x11/window-props.c:559 #, c-format -msgid "Could not parse font description \"%s\" from GConf key %s\n" -msgstr "Ne eblis analizi la tiparan difinon \"%s\" de la GConf-ŝlosilo %s.\n" +msgid "%s (on %s)" +msgstr "%s (ĉe %s)" -#: ../src/core/prefs.c:1586 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"Valoro \"%s\", trovita en la agorda datenbanko, ne estas valida valoro kiel " -"mus-butona modifilo.\n" +#~ msgid "Unknown window information request: %d" +#~ msgstr "Nekonata peto pri fenestra informo: %d" -#: ../src/core/prefs.c:2016 -#, c-format -msgid "Error setting number of workspaces to %d: %s\n" -msgstr "Eraro ŝanĝante la nombron da labortabloj al %d: %s\n" +#~ msgid "Missing %s extension required for compositing" +#~ msgstr "Aldonaĵo %s necesanta por kompostado mankas" -#: ../src/core/prefs.c:2200 ../src/core/prefs.c:2702 -#, c-format -msgid "Workspace %d" -msgstr "Laborspaco %d" +#~ msgid "" +#~ "Some other program is already using the key %s with modifiers %x as a " +#~ "binding\n" +#~ msgstr "" +#~ "Iu alia programo jam uzas la klavon %s kun modifiloj %x kiel bindaĵon\n" -#: ../src/core/prefs.c:2232 ../src/core/prefs.c:2410 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "" -"%s trovita en la agordara datumbazo ne estas valida valoro por klavokombino " -"\"%s\"\n" +#~ msgid "Failed to scan themes directory: %s\n" +#~ msgstr "Malsukcesis skani etosan dosierujon %s\n" -#: ../src/core/prefs.c:2783 -#, c-format -msgid "Error setting name for workspace %d to \"%s\": %s\n" -msgstr "Eraro agordante la nomon por la laborspaco %d al \"%s\": %s\n" +#~ msgid "" +#~ "Could not find a theme! Be sure %s exists and contains the usual themes.\n" +#~ msgstr "" +#~ "Ne eblis trovi ian etoson! Certigu, ke %s ekzistas kaj enhavas la " +#~ "ordinarajn etosojn.\n" -#: ../src/core/prefs.c:2997 -#, c-format -msgid "Error setting live hidden windows status status: %s\n" -msgstr "" +#~ msgid "" +#~ "Workarounds for broken applications disabled. Some applications may not " +#~ "behave properly.\n" +#~ msgstr "" +#~ "Provizoraj solvoj por rompitaj aplikaĵoj estas elŝaltitaj. Kelkaj " +#~ "aplikaĵoj povus ruli malkorekte.\n" -#: ../src/core/prefs.c:3032 -#, c-format -msgid "Error setting no tab popup status: %s\n" -msgstr "" +#~| msgid "Could not parse font description \"%s\" from GConf key %s\n" +#~ msgid "Could not parse font description \"%s\" from GSettings key %s\n" +#~ msgstr "" +#~ "Ne eblis analizi la tiparan priskribon \"%s\" de la GSettings-ŝlosilo %s\n" -#: ../src/core/screen.c:624 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "Ekrano %d en vidigo '%s' estas nevalida\n" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" +#~ msgstr "" +#~ "Valoro \"%s\", trovita en la agorda datenbazo, ne estas valida valoro " +#~ "kiel mus-butona modifilo\n" -#: ../src/core/screen.c:640 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"Ekrano %d en montrilo \"%s\" jam havas fenestroadministrilon; provi uzi " -"opcion --replace por anstataŭigi la nunan fenestroadministrilon.\n" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for " +#~ "keybinding \"%s\"\n" +#~ msgstr "" +#~ "%s trovita en la agordara datumbazo ne estas valida valoro por " +#~ "klavokombino \"%s\"\n" -#: ../src/core/screen.c:667 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "" -"Neeblas akiri fenestroadministrilan elekton ĉe ekrano %d, montrilo “%s”\n" +#~ msgid "" +#~ "Could not acquire window manager selection on screen %d display \"%s\"\n" +#~ msgstr "" +#~ "Neeblas akiri fenestroadministrilan elekton ĉe ekrano %d, vidigilo “%s”\n" -#: ../src/core/screen.c:722 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "" +#~ msgid "Screen %d on display \"%s\" already has a window manager\n" +#~ msgstr "Ekrano %d sur vidigilo \"%s\" jam havas fenestroadministrilon\n" -#: ../src/core/screen.c:907 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "" +#~ msgid "Could not release screen %d on display \"%s\"\n" +#~ msgstr "Ne eblas liberigi ekranon %d sur ekrano \"%s\"\n" -#: ../src/core/session.c:837 ../src/core/session.c:844 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Ne eblis krei dosierujon '%s': %s\n" +#~ msgid "Could not create directory '%s': %s\n" +#~ msgstr "Ne eblis krei dosierujon '%s': %s\n" -#: ../src/core/session.c:854 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "Ne eblis malfermi sesian dosieron '%s' por skribado: %s\n" +#~ msgid "Could not open session file '%s' for writing: %s\n" +#~ msgstr "Ne eblis malfermi sesian dosieron '%s' por skribado: %s\n" -#: ../src/core/session.c:995 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Eraro dum skribado al seanca dosiero '%s': %s\n" +#~ msgid "Error writing session file '%s': %s\n" +#~ msgstr "Eraro dum skribado al seanca dosiero '%s': %s\n" -#: ../src/core/session.c:1000 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Eraro dum fermado de seanca dosiero '%s': %s\n" +#~ msgid "Error closing session file '%s': %s\n" +#~ msgstr "Eraro dum fermado de seanca dosiero '%s': %s\n" -#: ../src/core/session.c:1130 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Malsuksesis analizi konservitan seancan dosieron: %s\n" +#~ msgid "Failed to parse saved session file: %s\n" +#~ msgstr "Malsuksesis analizi konservitan seancan dosieron: %s\n" -#: ../src/core/session.c:1179 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "" +#~ msgid "<mutter_session> attribute seen but we already have the session ID" +#~ msgstr "" +#~ "Atributo <mutter_session> aperis sed ni jam havas la seancoidentigilon" -#: ../src/core/session.c:1192 ../src/core/session.c:1267 -#: ../src/core/session.c:1299 ../src/core/session.c:1371 -#: ../src/core/session.c:1431 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Nekonata atributo %s ĉe elemento <%s>" +#~ msgid "Unknown attribute %s on <%s> element" +#~ msgstr "Nekonata atributo %s ĉe elemento <%s>" -#: ../src/core/session.c:1209 -#, c-format -msgid "nested <window> tag" -msgstr "" +#~ msgid "nested <window> tag" +#~ msgstr "ingita elemento <window>" -#: ../src/core/session.c:1451 -#, c-format -msgid "Unknown element %s" -msgstr "Nekonata elemento %s" +#~ msgid "Unknown element %s" +#~ msgstr "Nekonata elemento %s" -#: ../src/core/session.c:1803 -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" +#~ msgid "Window manager: " +#~ msgstr "Fenestroadministrilo: " -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "" +#~ msgid "Bug in window manager: " +#~ msgstr "Cimo en fenestroadministrilo: " -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "" +#~ msgid "Window manager warning: " +#~ msgstr "Fenestroadministrila atentigo: " -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "" +#~ msgid "Window manager error: " +#~ msgstr "Fenestroadministrila eraro: " -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "Mutero estis kompilita sen subteno por eksplicita reĝimo\n" +#~ msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +#~ msgstr "Eco %s ĉe fenestro 0x%lx enhavis nevalidan UTF-8\n" -#: ../src/core/util.c:286 -msgid "Window manager: " -msgstr "Fenestroadministrilo: " +#~ msgid "Usage: %s\n" +#~ msgstr "Uzo: %s\n" -#: ../src/core/util.c:434 -msgid "Bug in window manager: " -msgstr "Cimo en fenestroadministrilo: " +#~ msgid "Mi_nimize" +#~ msgstr "Mi_nimumigi" -#: ../src/core/util.c:467 -msgid "Window manager warning: " -msgstr "Fenestroadministrila atentigo: " +#~ msgid "Ma_ximize" +#~ msgstr "Ma_ksimumigi" -#: ../src/core/util.c:495 -msgid "Window manager error: " -msgstr "Fenestroadministrila eraro: " +#~ msgid "Unma_ximize" +#~ msgstr "Nema_ksimumigi" -#. Translators: This is the title used on dialog boxes -#: ../src/core/util.c:615 ../src/muffin.desktop.in.h:1 -#: ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Mutero" +#~ msgid "Roll _Up" +#~ msgstr "_Volvi" -#. first time through -#: ../src/core/window.c:6849 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" +#~ msgid "_Unroll" +#~ msgstr "_Malvolvi" -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7512 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size " -"%d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" +#~ msgid "_Move" +#~ msgstr "_Movi" -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "" +#~ msgid "_Resize" +#~ msgstr "_Aligrandigi" -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (ĉe %s)" +#~ msgid "Always on _Top" +#~ msgstr "Ĉiam _malfone" -#: ../src/core/window-props.c:1482 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "" +#~ msgid "_Always on Visible Workspace" +#~ msgstr "Ĉi_am en la videbla laborspaco" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" +#~ msgid "_Only on This Workspace" +#~ msgstr "_Nur en ĉi tiu laborspaco" -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "Eco %s ĉe fenestro 0x%lx enhavis nevalidan UTF-8\n" +#~ msgid "Move to Workspace _Left" +#~ msgstr "Movi al la _maldekstra laborspaco" -#: ../src/core/xprops.c:494 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" - -#: ../src/muffin.schemas.in.h:1 -msgid "Attach modal dialogs" -msgstr "" - -#: ../src/muffin.schemas.in.h:2 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" - -#: ../src/muffin.schemas.in.h:3 -msgid "" -"Determines whether workspace switching should happen for windows on all " -"monitors or only for windows on the primary monitor." -msgstr "" - -#: ../src/muffin.schemas.in.h:4 -msgid "Live Hidden Windows" -msgstr "" - -#: ../src/muffin.schemas.in.h:5 -msgid "Modifier to use for extended window management operations" -msgstr "" - -#: ../src/muffin.schemas.in.h:6 -msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." -msgstr "" - -#: ../src/muffin.schemas.in.h:7 -msgid "" -"When true, instead of having independent titlebars, modal dialogs appear " -"attached to the titlebar of the parent window and are moved together with " -"the parent window." -msgstr "" - -#: ../src/muffin.schemas.in.h:8 -msgid "Workspaces only on primary" -msgstr "" - -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "Uzo: %s\n" - -#: ../src/ui/frames.c:1099 -msgid "Close Window" -msgstr "Fermi la fenestron" - -#: ../src/ui/frames.c:1102 -msgid "Window Menu" -msgstr "Fenestra menuo" - -#: ../src/ui/frames.c:1105 -msgid "Minimize Window" -msgstr "Minimumigi la fenestron" - -#: ../src/ui/frames.c:1108 -msgid "Maximize Window" -msgstr "Maksimumigi la fenestron" - -#: ../src/ui/frames.c:1111 -msgid "Restore Window" -msgstr "Restaŭri fenestron" - -#: ../src/ui/frames.c:1114 -msgid "Roll Up Window" -msgstr "" - -#: ../src/ui/frames.c:1117 -msgid "Unroll Window" -msgstr "" - -#: ../src/ui/frames.c:1120 -msgid "Keep Window On Top" -msgstr "Teni la fenstron malfone" - -#: ../src/ui/frames.c:1123 -msgid "Remove Window From Top" -msgstr "Forigi la fenestron de la malfono" - -#: ../src/ui/frames.c:1126 -msgid "Always On Visible Workspace" -msgstr "" - -#: ../src/ui/frames.c:1129 -msgid "Put Window On Only One Workspace" -msgstr "" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "Mi_nimumigi" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "Ma_ksimumigi" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "Nema_ksimumigi" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "_Volvi" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "_Malvolvi" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "_Movi" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "_Aligrandigi" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "Ĉiam _malfone" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "Ĉi_am en la videbla laborspaco" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "_Nur en ĉi tiu laborspaco" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "Movi al la _maldekstra laborspaco" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "Movi al la _dekstra laborspaco" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "Movi al la su_pra laborspaco" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "Movi al la su_ba laborspaco" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "_Fermi" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "Laborspaco %d%n" - -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "Laborspaco 1_0" - -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "Laborspaco %s%d" - -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "Movi al alia _laborspaco" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Majuskliga klavo" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Stirklavo" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt-klavo" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta-klavo" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super-klavo" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "" - -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" - -#: ../src/ui/theme.c:255 -msgid "top" -msgstr "supre" - -#: ../src/ui/theme.c:257 -msgid "bottom" -msgstr "malsupre" - -#: ../src/ui/theme.c:259 -msgid "left" -msgstr "maldekstre" - -#: ../src/ui/theme.c:261 -msgid "right" -msgstr "dekstre" - -#: ../src/ui/theme.c:288 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "" - -#: ../src/ui/theme.c:307 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "" - -#: ../src/ui/theme.c:344 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "" - -#: ../src/ui/theme.c:356 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "" - -#: ../src/ui/theme.c:1064 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "" - -#: ../src/ui/theme.c:1202 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" - -#: ../src/ui/theme.c:1216 -#, c-format -msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "" - -#: ../src/ui/theme.c:1227 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "" - -#: ../src/ui/theme.c:1240 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "" - -#: ../src/ui/theme.c:1270 -#, c-format -msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" -msgstr "" - -#: ../src/ui/theme.c:1281 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "" - -#: ../src/ui/theme.c:1291 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "" - -#: ../src/ui/theme.c:1338 -#, c-format -msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "" - -#: ../src/ui/theme.c:1349 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "" - -#: ../src/ui/theme.c:1359 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "" - -#: ../src/ui/theme.c:1388 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Ne eblis analizi koloron \"%s\"" - -#: ../src/ui/theme.c:1646 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "" - -#: ../src/ui/theme.c:1673 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "" - -#: ../src/ui/theme.c:1687 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "" - -#: ../src/ui/theme.c:1809 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "" - -#: ../src/ui/theme.c:1866 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "" - -#: ../src/ui/theme.c:1977 ../src/ui/theme.c:1987 ../src/ui/theme.c:2021 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "" - -#: ../src/ui/theme.c:2029 -#, c-format -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "" - -#: ../src/ui/theme.c:2085 -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "" - -#: ../src/ui/theme.c:2094 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "" - -#: ../src/ui/theme.c:2102 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "" - -#: ../src/ui/theme.c:2112 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" - -#: ../src/ui/theme.c:2263 ../src/ui/theme.c:2308 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "" - -#: ../src/ui/theme.c:2362 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "" - -#: ../src/ui/theme.c:2391 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "" - -#: ../src/ui/theme.c:2455 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "" - -#: ../src/ui/theme.c:2466 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "" - -#: ../src/ui/theme.c:2676 ../src/ui/theme.c:2696 ../src/ui/theme.c:2716 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "" - -#: ../src/ui/theme.c:4410 -#, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" - -#: ../src/ui/theme.c:4940 ../src/ui/theme.c:4965 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" - -#: ../src/ui/theme.c:5013 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Ŝargo de la etoso \"%s\" fiaskis: %s\n" +#~ msgid "Move to Workspace R_ight" +#~ msgstr "Movi al la _dekstra laborspaco" -#: ../src/ui/theme.c:5149 ../src/ui/theme.c:5156 ../src/ui/theme.c:5163 -#: ../src/ui/theme.c:5170 ../src/ui/theme.c:5177 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "" +#~ msgid "Move to Workspace _Up" +#~ msgstr "Movi al la su_pra laborspaco" -#: ../src/ui/theme.c:5185 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" +#~ msgid "Move to Workspace _Down" +#~ msgstr "Movi al la su_ba laborspaco" -#: ../src/ui/theme.c:5635 ../src/ui/theme.c:5697 ../src/ui/theme.c:5760 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" +#~ msgid "_Close" +#~ msgstr "_Fermi" -#: ../src/ui/theme.c:5643 ../src/ui/theme.c:5705 ../src/ui/theme.c:5768 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "" +#~ msgid "Workspace %d%n" +#~ msgstr "Laborspaco %d%n" -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. -#. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "" +#~ msgid "Workspace 1_0" +#~ msgstr "Laborspaco 1_0" -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "" +#~ msgid "Workspace %s%d" +#~ msgstr "Laborspaco %s%d" -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "Atributo \"%s\" ripetas duoble en la sama elemento <%s>" +#~ msgid "Move to Another _Workspace" +#~ msgstr "Movi al alia _laborspaco" -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "Atributo \"%s\" ne estas valida en elemento <%s> en tiu ĉi kunteksto" +#~ msgid "Shift" +#~ msgstr "Majuskliga klavo" -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "Ne eblis analizi \"%s\" kiel entjeron" +#~ msgid "Ctrl" +#~ msgstr "Stirklavo" -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "Ne komprenis vostajn signojn \"%s\" en ĉeno \"%s\"" +#~ msgid "Alt" +#~ msgstr "Alt-klavo" -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "" +#~ msgid "Meta" +#~ msgstr "Meta-klavo" -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "" +#~ msgid "Super" +#~ msgstr "Super-klavo" -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "" +#~ msgid "%d x %d" +#~ msgstr "%d x %d" -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "" +#~ msgid "top" +#~ msgstr "supre" -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "" +#~ msgid "bottom" +#~ msgstr "malsupre" -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" +#~ msgid "left" +#~ msgstr "maldekstre" -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" +#~ msgid "right" +#~ msgstr "dekstre" -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "" +#~ msgid "Gradients should have at least two colors" +#~ msgstr "Gradientoj havu minimume du kolorojn" -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "" +#~ msgid "Could not parse color \"%s\"" +#~ msgstr "Ne eblis analizi koloron \"%s\"" -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "" +#~ msgid "Failed to load theme \"%s\": %s\n" +#~ msgstr "Ŝargo de la etoso \"%s\" malsukcesis: %s\n" -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "" +#~ msgid "Attribute \"%s\" repeated twice on the same <%s> element" +#~ msgstr "Atributo \"%s\" ripetas duoble en la sama elemento <%s>" -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "" +#~ msgid "Attribute \"%s\" is invalid on <%s> element in this context" +#~ msgstr "" +#~ "Atributo \"%s\" ne estas valida en elemento <%s> en tiu ĉi kunteksto" -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Nekonata tipo \"%s\" ĉe elemento <%s>" +#~ msgid "Could not parse \"%s\" as an integer" +#~ msgstr "Ne eblis analizi \"%s\" kiel entjeron" -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "" +#~ msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +#~ msgstr "Ne komprenis vostajn signojn \"%s\" en ĉeno \"%s\"" -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "" +#~ msgid "Unknown type \"%s\" on <%s> element" +#~ msgstr "Nekonata tipo \"%s\" ĉe elemento <%s>" -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "Elemento <%s> ne estas permesita sub <%s>" +#~ msgid "Element <%s> is not allowed below <%s>" +#~ msgstr "Elemento <%s> ne estas permesita sub <%s>" -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" -msgstr "" +#~ msgid "Distance \"%s\" is unknown" +#~ msgstr "Distanco \"%s\" estas nekonata" -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "" +#~ msgid "Aspect ratio \"%s\" is unknown" +#~ msgstr "Proporcio \"%s\" estas nekonata" -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "" +#~ msgid "Border \"%s\" is unknown" +#~ msgstr "Bordero \"%s\" estas nekonata" -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "" +#~ msgid "Unknown function \"%s\" for button" +#~ msgstr "Nekonata buton-funkcio \"%s\"" -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "" +#~ msgid "Unknown state \"%s\" for button" +#~ msgstr "Nekonata buton-stato \"%s\"" -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "" +#~ msgid "\"%s\" is not a valid value for focus attribute" +#~ msgstr "»%s« ne estas valida valoro por la atributo »focus«" -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "" +#~ msgid "\"%s\" is not a valid value for state attribute" +#~ msgstr "»%s« ne estas valida valoro por la atributo »state«" -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "" +#~ msgid "\"%s\" is not a valid value for resize attribute" +#~ msgstr "»%s« ne estas valida valoro por la atributo »resize«" -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "" +#~ msgid "_Windows" +#~ msgstr "_Fenestroj" -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "" +#~ msgid "_Dialog" +#~ msgstr "_Dialogo" -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "" +#~ msgid "_Utility" +#~ msgstr "_Ilo" -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "" +#~ msgid "_Splashscreen" +#~ msgstr "_Salutŝildo" -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "" +#~ msgid "Des_ktop" +#~ msgstr "_Labortablo" -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "" +#~ msgid "This is a sample message in a sample dialog" +#~ msgstr "Ĉi tio estas ekzempla mesaĝo en ekzempla dialogo" -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "" +#~ msgid "Bar" +#~ msgstr "Breto" -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "" +#~ msgid "Dialog Box" +#~ msgstr "Dialogujo" -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "" +#~ msgid "Utility Palette" +#~ msgstr "Ilar-palatro" -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "" +#~ msgid "Border" +#~ msgstr "Bordero" -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "" +#~ msgid "Error loading theme: %s\n" +#~ msgstr "Eraro dum ŝargado de etoso: %s\n" -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "" +#~ msgid "Loaded theme \"%s\" in %g seconds\n" +#~ msgstr "Ŝargis etoson \"%s\" post %g sekundoj\n" -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "" +#~ msgid "Normal Title Font" +#~ msgstr "Normala titoltiparo" -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "" +#~ msgid "Small Title Font" +#~ msgstr "Malgranda titoltiparo" -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "" +#~ msgid "Large Title Font" +#~ msgstr "Alta titoltiparo" -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "" +#~ msgid "Button Layouts" +#~ msgstr "Aranĝo de la butonoj" -#: ../src/ui/theme-parser.c:3147 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" +#~ msgid "Benchmark" +#~ msgstr "Taksotestado" -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "" +#~ msgid "Window Title Goes Here" +#~ msgstr "Ĉi tie aperos la fenstrotitolo" -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "" +#~ msgid "Error was expected but none given" +#~ msgstr "Eraro %d estas atendita, sed ne estas transdonita" -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "" +#~ msgid "Error %d was expected but %d given" +#~ msgstr "Eraro %d estas atendita, sed %d estas donita" -#: ../src/ui/theme-parser.c:3294 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" +#~ msgid "x value was %d, %d was expected" +#~ msgstr "X-valoro estis %d, %d estis atendita" -#: ../src/ui/theme-parser.c:3332 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" +#~ msgid "y value was %d, %d was expected" +#~ msgstr "Y-valoro estis %d, %d estis atendita" -#: ../src/ui/theme-parser.c:3370 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" +#, fuzzy +#~ msgid "Minimize window" +#~ msgstr "Minimumigi fenestron" -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "" +#~ msgid "Switch to workspace 8" +#~ msgstr "Ŝalti al laborspaco 8" -#: ../src/ui/theme-parser.c:3507 -msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" -msgstr "" +#~ msgid "Switch to workspace 9" +#~ msgstr "Ŝalti al laborspaco 9" -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "" +#~ msgid "Switch to workspace 10" +#~ msgstr "Ŝalti al laborspaco 10" -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "" +#~ msgid "Switch to workspace 11" +#~ msgstr "Ŝalti al laborspaco 11" -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "" +#~ msgid "Switch to workspace 12" +#~ msgstr "Ŝalti al laborspaco 12" -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "" +#~ msgid "Switch to workspace on the left of the current workspace" +#~ msgstr "Ŝalti al la laborspaco maldekstre de la aktuala laborspaco" -#: ../src/ui/theme-parser.c:3599 -#, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "" +#~ msgid "Switch to workspace on the right of the current workspace" +#~ msgstr "Ŝalti al la laborspaco dekstre de la aktuala laborspaco" -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "" +#~ msgid "Switch to workspace above the current workspace" +#~ msgstr "Ŝalti al laborspaco super la aktuala laborspaco" -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "" +#~ msgid "Switch to workspace below the current workspace" +#~ msgstr "Ŝalti al laborspaco sub la aktuala laborspaco" -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "" +#~ msgid "Move between windows of an application, using a popup window" +#~ msgstr "Moviĝi inter fenestroj de aplikaĵo, uzante ŝprucfenestron" -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "" - -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "" - -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "" - -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "_Fenestroj" - -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "_Dialogo" - -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "" - -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "_Ilo" - -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "" - -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "" +#~ msgid "" +#~ "Move backward between windows of an application, using a popup window" +#~ msgstr "" +#~ "Moviĝi malantaŭen inter fenestroj de aplikaĵo, uzante ŝprucfenestron" -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "" +#~ msgid "Move between windows, using a popup window" +#~ msgstr "Moviĝi inter fenestroj, uzante ŝprucfenestron" -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "" +#~ msgid "Move backward between windows, using a popup window" +#~ msgstr "Moviĝi malantaŭen inter fenestroj, uzante ŝprucfenestron" -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "" +#~ msgid "Move between panels and the desktop, using a popup window" +#~ msgstr "Moviĝi inter paneloj kaj labortablo, uzante ŝprucfenestron" -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "" +#~ msgid "Move backward between panels and the desktop, using a popup window" +#~ msgstr "" +#~ "Moviĝi malantaŭen inter paneloj kaj labortablo, uzante ŝprucfenestron" -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "" +#~ msgid "Move between windows of an application immediately" +#~ msgstr "Moviĝi tuj inter fenestroj de aplikaĵo" -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "" +#~ msgid "Move backward between windows of an application immediately" +#~ msgstr "Moviĝi tuj malantaŭen inter fenestroj de aplikaĵo" -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "" +#~ msgid "Move between windows immediately" +#~ msgstr "Moviĝi tuj inter fenestroj" -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "" +#~ msgid "Move backward between windows immediately" +#~ msgstr "Moviĝi tuj malantaŭen inter fenestroj" -#: ../src/ui/theme-viewer.c:253 -msgid "This is a sample message in a sample dialog" -msgstr "" +#~ msgid "Move between panels and the desktop immediately" +#~ msgstr "Moviĝi tuj inter paneloj kaj labortablo" -#: ../src/ui/theme-viewer.c:336 -#, c-format -msgid "Fake menu item %d\n" -msgstr "" +#~ msgid "Move backward between panels and the desktop immediately" +#~ msgstr "Moviĝi tuj malantaŭen inter paneloj kaj labortablo" -#: ../src/ui/theme-viewer.c:370 -msgid "Border-only window" -msgstr "" +#~ msgid "Hide all normal windows and set focus to the desktop" +#~ msgstr "Kaŝi ĉiujn normalajn fenestrojn kaj enfokusigi la labortablon" -#: ../src/ui/theme-viewer.c:372 -msgid "Bar" -msgstr "Breto" +#~ msgid "Show the panel's main menu" +#~ msgstr "Montri la ĉefmenuon de la panelo" -#: ../src/ui/theme-viewer.c:389 -msgid "Normal Application Window" -msgstr "" - -#: ../src/ui/theme-viewer.c:393 -msgid "Dialog Box" -msgstr "Dialogujo" +#~ msgid "Show the panel's \"Run Application\" dialog box" +#~ msgstr "Montri la dialogujon \"Ruli aplikaĵon\" de la panelo" -#: ../src/ui/theme-viewer.c:397 -msgid "Modal Dialog Box" -msgstr "" +#~ msgid "Take a screenshot" +#~ msgstr "Fari ekrankopion" -#: ../src/ui/theme-viewer.c:401 -msgid "Utility Palette" -msgstr "" +#~ msgid "Take a screenshot of a window" +#~ msgstr "Ekrankopii fenestron" -#: ../src/ui/theme-viewer.c:405 -msgid "Torn-off Menu" -msgstr "" +#~ msgid "Run a terminal" +#~ msgstr "Ruli terminalon" -#: ../src/ui/theme-viewer.c:409 -msgid "Border" -msgstr "Bordero" +#~ msgid "Move window to workspace 5" +#~ msgstr "Movi la fenestron al laborspaco 5" -#: ../src/ui/theme-viewer.c:413 -msgid "Attached Modal Dialog" -msgstr "" +#~ msgid "Move window to workspace 6" +#~ msgstr "Movi la fenestron al laborspaco 6" -#: ../src/ui/theme-viewer.c:744 -#, c-format -msgid "Button layout test %d" -msgstr "" +#~ msgid "Move window to workspace 7" +#~ msgstr "Movi la fenestron al laborspaco 7" -#: ../src/ui/theme-viewer.c:773 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "" +#~ msgid "Move window to workspace 8" +#~ msgstr "Movi la fenestron al laborspaco 8" -#: ../src/ui/theme-viewer.c:818 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "" +#~ msgid "Move window to workspace 9" +#~ msgstr "Movi la fenestron al laborspaco 9" -#: ../src/ui/theme-viewer.c:825 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "Eraro dum ŝargado de etoso: %s\n" +#~ msgid "Move window to workspace 10" +#~ msgstr "Movi la fenestron al laborspaco 10" -#: ../src/ui/theme-viewer.c:831 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "" +#~ msgid "Move window to workspace 11" +#~ msgstr "Movi la fenestron al laborspaco 11" -#: ../src/ui/theme-viewer.c:875 -msgid "Normal Title Font" -msgstr "" +#~ msgid "Move window to workspace 12" +#~ msgstr "Movi la fenestron al laborspaco 12" -#: ../src/ui/theme-viewer.c:881 -msgid "Small Title Font" -msgstr "" +#~ msgid "" +#~ "There was an error running <tt>%s</tt>:\n" +#~ "\n" +#~ "%s" +#~ msgstr "" +#~ "Okazis eraro lanĉante <tt>%s</tt>:\n" +#~ "\n" +#~ "%s" -#: ../src/ui/theme-viewer.c:887 -msgid "Large Title Font" -msgstr "" +#~ msgid "No command %d has been defined.\n" +#~ msgstr "Neniu komando %d estis difinita.\n" -#: ../src/ui/theme-viewer.c:892 -msgid "Button Layouts" -msgstr "" +#~ msgid "No terminal command has been defined.\n" +#~ msgstr "Neniu terminala komando estis difinita.\n" -#: ../src/ui/theme-viewer.c:897 -msgid "Benchmark" -msgstr "Taksotestado" +#~ msgid "GConf key '%s' is set to an invalid value\n" +#~ msgstr "La GConf-ŝlosilo '%s' havas ne-validan valoron.\n" -#: ../src/ui/theme-viewer.c:949 -msgid "Window Title Goes Here" -msgstr "" +#~ msgid "%d stored in GConf key %s is out of range %d to %d\n" +#~ msgstr "" +#~ "La valoro %d de la GConf-ŝlosilo %s estas ekster intervalo de %d ĝis %d\n" -#: ../src/ui/theme-viewer.c:1055 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" +#~ msgid "GConf key \"%s\" is set to an invalid type\n" +#~ msgstr "La GConf-ŝlosilo \"%s\" havas nevalidan valoron.\n" -#: ../src/ui/theme-viewer.c:1274 -msgid "position expression test returned TRUE but set error" -msgstr "" +#~ msgid "Error setting number of workspaces to %d: %s\n" +#~ msgstr "Eraro ŝanĝante la nombron da labortabloj al %d: %s\n" -#: ../src/ui/theme-viewer.c:1276 -msgid "position expression test returned FALSE but didn't set error" -msgstr "" +#~ msgid "Error setting name for workspace %d to \"%s\": %s\n" +#~ msgstr "Eraro agordante la nomon por la laborspaco %d al \"%s\": %s\n" -#: ../src/ui/theme-viewer.c:1280 -msgid "Error was expected but none given" -msgstr "" +#~ msgid "Close Window" +#~ msgstr "Fermi la fenestron" -#: ../src/ui/theme-viewer.c:1282 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "" +#~ msgid "Window Menu" +#~ msgstr "Fenestra menuo" -#: ../src/ui/theme-viewer.c:1288 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "" +#~ msgid "Minimize Window" +#~ msgstr "Minimumigi la fenestron" -#: ../src/ui/theme-viewer.c:1292 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "" +#~ msgid "Maximize Window" +#~ msgstr "Maksimumigi la fenestron" -#: ../src/ui/theme-viewer.c:1295 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "" +#~ msgid "Restore Window" +#~ msgstr "Restaŭri fenestron" -#: ../src/ui/theme-viewer.c:1360 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "" +#~ msgid "Keep Window On Top" +#~ msgstr "Teni la fenstron malfone" #~ msgid "" #~ "Don't make fullscreen windows that are maximized and have no decorations" diff --git a/po/es.po b/po/es.po index 0aea6f80c..6540101b1 100644 --- a/po/es.po +++ b/po/es.po @@ -1,4 +1,4 @@ -# translation of muffin.master.po to Español +# translation of mutter.master.po to Español # Spanish trasnlation for Metacity # Copyright © 2001,2002,2003, 2006, 2007, 2008 Free Software Foundation, Inc. # This file is distributed under the same license as the metacity package. @@ -7,424 +7,274 @@ # Pablo Gonzalo del Campo <pablodc@bigfoot.com>,2002,2003. # Francisco Javier F. Serrador <serrador@cvs.gnome.org>, 2004, 2005, 2006. # Jorge González <jorgegonz@svn.gnome.org>, 2007, 2008, 2009, 2010, 2011. -# Daniel Mustieles <daniel.mustieles@gmail.com>, 2011, 2012. +# Daniel Mustieles <daniel.mustieles@gmail.com>, 2011-2020. # msgid "" msgstr "" -"Project-Id-Version: muffin.master\n" -"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" -"product=muffin&keywords=I18N+L10N&component=general\n" -"POT-Creation-Date: 2012-03-11 21:56+0000\n" -"PO-Revision-Date: 2012-03-12 14:17+0100\n" +"Project-Id-Version: mutter.master\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2020-02-23 17:41+0000\n" +"PO-Revision-Date: 2020-02-24 13:15+0100\n" "Last-Translator: Daniel Mustieles <daniel.mustieles@gmail.com>\n" -"Language-Team: Español <gnome-es-list@gnome.org>\n" +"Language-Team: Spanish - Spain <gnome-es-list@gnome.org>\n" +"Language: es_ES\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Gtranslator 3.34.0\n" -#: ../src/50-muffin-windows.xml.in.h:1 -msgid "Windows" -msgstr "Ventanas" - -#: ../src/50-muffin-windows.xml.in.h:2 -msgid "View split on left" -msgstr "Ver división a la izquierda" - -#: ../src/50-muffin-windows.xml.in.h:3 -msgid "View split on right" -msgstr "Ver división a la derecha" - -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format -msgid "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." -msgstr "" -"Ya existe un gestor de composición ejecutándose en la monitor %i, pantalla «%" -"s»." - -#: ../src/core/bell.c:307 -msgid "Bell event" -msgstr "Evento de campana" - -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Petición de información de ventana desconocida: %d" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Navegación" -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> no está respondiendo." +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Mover la ventana al área de trabajo 1" -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "La aplicación no está respondiendo." +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Mover la ventana al área de trabajo 2" -#: ../src/core/delete.c:119 -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "" -"Puede elegir esperar un rato para ver si continua o forzar la aplicación " -"para cerrarla completamente." +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Mover la ventana al área de trabajo 3" -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "_Esperar" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Mover la ventana al área de trabajo 4" -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "_Forzar la salida" +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Mover la ventana a la última área de trabajo" -#: ../src/core/display.c:361 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "Falta la extensión %s requerida para la composición" +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "Subir la ventana un área de trabajo" -#: ../src/core/display.c:427 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Ocurrió un error al abrir la pantalla de X Window System «%s»\n" +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "Bajar la ventana un área de trabajo" -#: ../src/core/keybindings.c:852 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "" -"Algún otro programa ya está usando la clave %s con el modificador %x como " -"una vinculación\n" +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "Mover la ventana una pantalla a la izquierda" -#: ../src/core/main.c:206 -msgid "Disable connection to session manager" -msgstr "Desactivar conexión al gestor de sesión" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "Mover la ventana una pantalla a la derecha" -#: ../src/core/main.c:212 -msgid "Replace the running window manager" -msgstr "Reemplazar el gestor de ventanas en ejecución" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "Subir la ventana una pantalla" -#: ../src/core/main.c:218 -msgid "Specify session management ID" -msgstr "Especificar el ID se gestión de sesión" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "Bajar la ventana una pantalla" -#: ../src/core/main.c:223 -msgid "X Display to use" -msgstr "Pantalla X que usar" +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "Cambiar entre aplicaciones" -#: ../src/core/main.c:229 -msgid "Initialize session from savefile" -msgstr "Inicializar sesión desde el archivo de salvaguarda" +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "Cambiar a la aplicación anterior" -#: ../src/core/main.c:235 -msgid "Make X calls synchronous" -msgstr "Hacer que las llamadas a las X sean síncronas" +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "Cambiar entre ventanas" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Falló al inspeccionar la carpeta de temas: %s\n" +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "Cambiar a la ventana anterior" -#: ../src/core/main.c:520 -#, c-format -msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "" -"No se ha podido encontrar un tema. Asegúrese de que %s existe y contiene los " -"temas usuales.\n" +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "Cambiar entre ventanas de una aplicación" -#: ../src/core/muffin.c:40 -#, c-format -msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" -"muffiny %s\n" -"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., y otros\n" -"Este programa es software libre; vea el código fuente para obtener las\n" -"condiciones de copia. NO se proporciona ninguna garantía; ni de\n" -"MERCANTILIDAD O DE IDONEIDAD PARA UN PROPÓSITO PARTICULAR.\n" +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "Cambiar a la ventana anterior de una aplicación" -#: ../src/core/muffin.c:54 -msgid "Print version" -msgstr "Imprimir versión" +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "Cambiar entre controles del sistema" -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "Lista de complementos del compositor separados por comas" +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "Cambiar al control del sistema anterior" -#: ../src/core/prefs.c:1077 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"Los arreglos para aplicaciones rotas se han deshabilitado. Algunas " -"aplicaciones podrían no comportarse correctamente.\n" +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "Cambiar entre ventanas directamente" -#: ../src/core/prefs.c:1152 -#, c-format -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "" -"No se pudo analizar la descripción de la tipografía «%s» de la clave " -"GSettings %s\n" +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "Cambiar directamente a la ventana anterior" -#: ../src/core/prefs.c:1218 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"«%s» encontrado en la base de datos de configuración no es un valor válido " -"para el modificador del botón del ratón\n" +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "Cambiar entre ventanas de una aplicación directamente" -#: ../src/core/prefs.c:1736 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "" -"«%s» encontrado en la base de datos de configuración no es un valor válido " -"para la combinación de teclas «%s»\n" +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "Cambiar directamente a la ventana anterior de una aplicación" -#: ../src/core/prefs.c:1833 -#, c-format -msgid "Workspace %d" -msgstr "Área de trabajo %d" +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "Cambiar entre controles del sistema directamente" -#: ../src/core/screen.c:730 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "La ventana %d en la pantalla «%s» no es válida\n" +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "Cambiar directamente al control del sistema anterior" -#: ../src/core/screen.c:746 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"La ventana %d en la pantalla «%s» ya tiene un gestor de ventanas, intente " -"usar la opción «--replace» para reemplazar el gestor de ventanas activo.\n" +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "Ocultar todas las ventanas normales" -#: ../src/core/screen.c:773 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "" -"No se ha podido obtener la selección del gestor de ventanas en la ventana %d " -"en la pantalla «%s»\n" +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "Cambiar al área de trabajo 1" -#: ../src/core/screen.c:828 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "La ventana %d en la pantalla «%s» ya tiene un gestor de ventanas\n" +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "Cambiar al área de trabajo 2" -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "No se ha podido liberar el monitor %d en la pantalla «%s»\n" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "Cambiar al área de trabajo 3" -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "No se ha podido crear la carpeta «%s»: %s\n" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "Cambiar al área de trabajo 4" -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "No se ha podido abrir para escritura el archivo de sesión «%s»: %s\n" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "Cambiar a la útima área de trabajo" -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Ocurrió un error al escribir en el archivo de sesión «%s»: %s\n" +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "Mover al área de trabajo de arriba" -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Ocurrió un error al cerrar el archivo de sesión «%s»: %s\n" +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "Mover al área de trabajo de abajo" -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Ocurrió un error al interpretar el archivo de sesión guardado: %s\n" +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "Sistema" -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "" -"Se ha visto el atributo <muffin_session> pero ya tenemos el ID de la sesión" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Mostrar el elemento «ejecutar comando»" -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Atributo desconocido %s en el elemento <%s>" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Mostrar la vista de actividades" -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "etiqueta <window> anidada" +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Restaurar los atajos de teclado" -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "Elemento desconocido %s" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Ventanas" -#: ../src/core/session.c:1809 -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" -"Estas ventanas no soportan «guardar la configuración actual» y tendrán que " -"reiniciarse manualmente la próxima vez que inicie una sesión." +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "Activar el menú de la ventana" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Ocurrió un error al abrir el registro de errores: %s\n" +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Cambiar el modo a pantalla completa" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Ocurrió un error al hacer fdopen() en el archivo de registro %s: %s\n" +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "Cambiar el estado de maximización" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "Archivo de registro %s abierto\n" +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "Maximizar la ventana" -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "Muffin fue compilado sin soporte para modo prolijo\n" +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Restaurar la ventana" -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "Administrador de ventanas: " +#: data/50-mutter-windows.xml:18 +msgid "Close window" +msgstr "Cerrar la ventana" -# Diferenciar de eRRor en el gestor de ventanas, más abajo -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "Error en el gestor de ventanas: " +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "Ocultar la ventana" -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "Advertencia del gestor de ventanas: " +#: data/50-mutter-windows.xml:22 +msgid "Move window" +msgstr "Mover la ventana" -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "Error del gestor de ventanas: " +#: data/50-mutter-windows.xml:24 +msgid "Resize window" +msgstr "Redimensionar la ventana" -#. first time through -#: ../src/core/window.c:7224 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"La ventana %s ha establecido SM_CLIENT_ID sobre sí misma en vez de hacerlo " -"en la ventana WM_CLIENT_LEADER como está especificado en el ICCCM.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7887 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %" -"d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"La ventana %s ha establecido la propiedad MWM indicando que no es " -"redimensionable, pero configuró el tamaño mínimo a %d x %d y el tamaño " -"máximo a %d x %d ; esto no tiene mucho sentido.\n" +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "Conmutar la ventana en todas las áreas de trabajo o sólo en una" -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "La aplicación establecio un _NET_WM_PID %lu erróneo\n" +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "Elevar la ventana si está cubierta, de lo contrario, bajarla" -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (on %s)" +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "Elevar la ventana sobre las otras ventanas" -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "" -"WM_TRANSIENT_FOR inválido para la ventana 0x%lx especificada para %s.\n" +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "Bajar la ventana por debajo de otras ventanas" -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "WM_TRANSIENT_FOR ventana 0x%lx para %s crearía un bucle.\n" +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "Maximizar la ventana verticalmente" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"La ventana 0x%lx tiene la propiedad %s \n" -"que se esperaba tuviese el tipo %s con el formato %d\n" -"y actualmente tiene un tipo %s con el formato %d y n_items %d\n" -"Esto no parece ser un error de la aplicación ni del gestor de ventanas.\n" -"La ventana tiene título=«%s» la clase=«%s» y el nombre=«%s»\n" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "Maximizar la ventana horizontalmente" -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "La propiedad %s en la ventana 0x%lx contiene UTF-8 inválido\n" +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "Ver división a la izquierda" -#: ../src/core/xprops.c:494 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"La propiedad %s en la ventana 0x%lx contiene UTF-8 inválido para el elemento " -"%d de la lista\n" +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "Ver división a la derecha" -#: ../src/muffin.desktop.in.h:1 ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 +#: data/org.gnome.mutter.gschema.xml.in:7 msgid "Modifier to use for extended window management operations" msgstr "" "Modificador que usar para extender las operaciones de gestión sobre ventanas" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 +#: data/org.gnome.mutter.gschema.xml.in:8 msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." -msgstr "" -"Esta clave iniciará el «revestimiento» («overlay»), que es una combinación de " -"vista general de la ventana y el sistema de lanzamiento de aplicaciones. Lo " -"predeterminado está pensado para la «tecla de Windows». Se espera que esta " -"combinación de tecla sea la predeterminada o se establezca a una cadena " +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." +msgstr "" +"Esta clave iniciará el «revestimiento» («overlay»), que es una combinación " +"de vista general de la ventana y el sistema de lanzamiento de aplicaciones. " +"Lo predeterminado está pensado para la «tecla de Windows». Se espera que " +"esta combinación de tecla sea la predeterminada o se establezca a una cadena " "vacía." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 +#: data/org.gnome.mutter.gschema.xml.in:20 msgid "Attach modal dialogs" msgstr "Adjuntar diálogos modales" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 +#: data/org.gnome.mutter.gschema.xml.in:21 msgid "" "When true, instead of having independent titlebars, modal dialogs appear " "attached to the titlebar of the parent window and are moved together with " @@ -434,25 +284,13 @@ msgstr "" "aparecen diálogos modales adjuntos a la barra de título de la ventana padre " "y se mueven junto con la ventana padre." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -msgid "Live Hidden Windows" -msgstr "Ventanas activas ocultas" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"Determina si las ventanas ocultas (e.g., ventanas minimizadas y ventanas en " -"otros escritorios distintos del actual) deberían mantenerse activas." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 +#: data/org.gnome.mutter.gschema.xml.in:30 msgid "Enable edge tiling when dropping windows on screen edges" msgstr "" "Activar el mosaico en los bordes al arrastrar ventanas a los bordes de la " "ventana" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 +#: data/org.gnome.mutter.gschema.xml.in:31 msgid "" "If enabled, dropping windows on vertical screen edges maximizes them " "vertically and resizes them horizontally to cover half of the available " @@ -463,25 +301,25 @@ msgstr "" "mitad del área disponible. Arrastrar ventanas al borde superior de la " "pantalla las maximiza por completo." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 +#: data/org.gnome.mutter.gschema.xml.in:40 msgid "Workspaces are managed dynamically" msgstr "Las áreas de trabajo se gestionan dinámicamente" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 +#: data/org.gnome.mutter.gschema.xml.in:41 msgid "" -"Determines whether workspaces are managed dynamically or whether there's a " +"Determines whether workspaces are managed dynamically or whether there’s a " "static number of workspaces (determined by the num-workspaces key in org." "gnome.desktop.wm.preferences)." msgstr "" "Determina si las áreas de trabajo se gestionan dinámicamente o si ha un " "número estático de áreas de trabajo (determinado por la clave «num-" -"workspaces» en «org.cinnamon.desktop.wm.preferences»)." +"workspaces» en «org.gnome.desktop.wm.preferences»)." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 +#: data/org.gnome.mutter.gschema.xml.in:50 msgid "Workspaces only on primary" msgstr "Áreas de trabajo sólo en el primario" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 +#: data/org.gnome.mutter.gschema.xml.in:51 msgid "" "Determines whether workspace switching should happen for windows on all " "monitors or only for windows on the primary monitor." @@ -489,11 +327,11 @@ msgstr "" "Determina si el cambio entre áreas de trabajo debería suceder para las " "ventanas en todos los monitores o sólo para ventanas en el monitor primario." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 +#: data/org.gnome.mutter.gschema.xml.in:59 msgid "No tab popup" msgstr "No hay pestaña emergente" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 +#: data/org.gnome.mutter.gschema.xml.in:60 msgid "" "Determines whether the use of popup and highlight frame should be disabled " "for window cycling." @@ -501,1194 +339,1407 @@ msgstr "" "Determina si el uso de ventanas emergentes y marcos resaltados se debe " "desactivar al cambiar entre ventanas." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Retrasar el cambio de foco hasta detener el puntero" + +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" +"Si está establecido a «true» y el modo del foco es «sloppy» o «mouse» " +"entonces el foco no se cambiará inmediatamente al entrar en una ventana, " +"pero sí después de dejar quieto el puntero." + +#: data/org.gnome.mutter.gschema.xml.in:79 msgid "Draggable border width" msgstr "Anchura arrastrable del borde" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 +#: data/org.gnome.mutter.gschema.xml.in:80 msgid "" -"The amount of total draggable borders. If the theme's visible borders are " +"The amount of total draggable borders. If the theme’s visible borders are " "not enough, invisible borders will be added to meet this value." msgstr "" -"La cantidad total de borde arrastrable. Si los bordes visibles del tema no " -"son suficientes, se añadirán bordes invisibles para satisfacer este valor." +"La cantidad total de borde que se puede arrastrar. Si los bordes visibles " +"del tema no son suficientes, se añadirán bordes invisibles para satisfacer " +"este valor." + +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "" +"Maximizar automáticamente las ventanas que casi tengan el tamaño de la " +"pantalla" + +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" +"Si está activada, las ventanas nuevas que inicialmente tienen el tamaño de " +"la pantalla, se maximizan." + +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Colocar las ventanas nuevas en el centro" + +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" +"Cuando es cierto, las ventanas nuevas se colocarán siempre en el centro de " +"la pantalla activa del monitor." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:17 +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Activar las características experimentales" + +#: data/org.gnome.mutter.gschema.xml.in:108 +msgid "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes " +"mutter request a low priority real-time scheduling. The executable or user " +"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — " +"initializes Xwayland lazily if there are X11 clients. Requires restart." +msgstr "" +"Para activar las características experimentales, añada la palabra clave de " +"la característica a la lista. Depende de la característica que se deba " +"reiniciar o no el compositor. Cualquier característica experimental puede no " +"estar disponible o ser configurable. No espere que lo que se añada en este " +"escenario sirva como prueba futura. Las palabras clave actualmente " +"disponibles son: • \"scale-monitor-framebuffer\" - convierte a mutter en la " +"manera predeterminada de disponer monitores lógicos en un espacio lógico de " +"coordenadas de píxeles, al escalar framebuffers de monitores framebuffers en " +"lugar del contenido de ventana, para administrar monitores HiDPI. No " +"requiere un reinicio. • “rt-scheduler” — hace que mutter pida una " +"planificación en tiempo real con prioridad baja. El ejecutable o el usuario " +"deben tener CAP_SYS_NICE. Requiere reniciar. • “autostart-xwayland” — inicia " +"Xwayland vagamente si hay clientes X11. Requiere reiniciar." + +#: data/org.gnome.mutter.gschema.xml.in:134 +msgid "Modifier to use to locate the pointer" +msgstr "Modificador que usar para encontrar el puntero" + +#: data/org.gnome.mutter.gschema.xml.in:135 +msgid "This key will initiate the “locate pointer” action." +msgstr "Esta tecla iniciará la acción de encontrar el puntero." + +#: data/org.gnome.mutter.gschema.xml.in:142 +msgid "Timeout for check-alive ping" +msgstr "Tiempo de espera para la comprobación de ping" + +#: data/org.gnome.mutter.gschema.xml.in:143 +msgid "" +"Number of milliseconds a client has to respond to a ping request in order to " +"not be detected as frozen. Using 0 will disable the alive check completely." +msgstr "" +"Número de milisegundos que tiene un cliente para responder a ping y que no " +"se le detecte como caído. Usar 0 desactivará esta comprobación." + +#: data/org.gnome.mutter.gschema.xml.in:165 msgid "Select window from tab popup" msgstr "Seleccionar ventana de la pestaña emergente" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:18 +#: data/org.gnome.mutter.gschema.xml.in:170 msgid "Cancel tab popup" msgstr "Cancelar pestaña emergente" -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "Uso: %s\n" - -#: ../src/ui/frames.c:1158 -msgid "Close Window" -msgstr "Cerrar la ventana" +#: data/org.gnome.mutter.gschema.xml.in:175 +msgid "Switch monitor configurations" +msgstr "Cambiar la configuración del monitor" -#: ../src/ui/frames.c:1161 -msgid "Window Menu" -msgstr "Menú de la ventana" +#: data/org.gnome.mutter.gschema.xml.in:180 +msgid "Rotates the built-in monitor configuration" +msgstr "Rota la configuración del monitor empotrado" -#: ../src/ui/frames.c:1164 -msgid "Minimize Window" -msgstr "Minimizar la ventana" +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Cambiar al VT 1" -#: ../src/ui/frames.c:1167 -msgid "Maximize Window" -msgstr "Maximizar la ventana" +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Cambiar al VT 2" -#: ../src/ui/frames.c:1170 -msgid "Restore Window" -msgstr "Restablecer la ventana" - -#: ../src/ui/frames.c:1173 -msgid "Roll Up Window" -msgstr "Enrollar ventana" - -#: ../src/ui/frames.c:1176 -msgid "Unroll Window" -msgstr "Desenrollar ventana" - -#: ../src/ui/frames.c:1179 -msgid "Keep Window On Top" -msgstr "Mantener la ventana encima" - -#: ../src/ui/frames.c:1182 -msgid "Remove Window From Top" -msgstr "Quitar ventana de encima" - -#: ../src/ui/frames.c:1185 -msgid "Always On Visible Workspace" -msgstr "Siempre en el área de trabajo visible" - -#: ../src/ui/frames.c:1188 -msgid "Put Window On Only One Workspace" -msgstr "Poner la ventana sólo en un área de trabajo" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "Mi_nimizar" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "Ma_ximizar" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "Desma_ximizar" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "Enro_llar" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "De_senrollar" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "_Mover" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "_Redimensionar" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "Mover la barra de título a la _pantalla" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "Siempre _encima" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "Siempre en el área de trabajo _visible" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "_Sólo en este área de trabajo" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "Mover al área de trabajo de la _izquierda" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "Mover al área de trabajo de la _derecha" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "Mover al área de trabajo de _arriba" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "Mover al área de trabajo de a_bajo" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "_Cerrar" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "Área de trabajo %d%n" +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Cambiar al VT 3" -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "Área de trabajo 1_0" +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Cambiar al VT 4" -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "Área de trabajo %s%d" +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Cambiar al VT 5" -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "Mover a _otro área de trabajo" +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Cambiar al VT 6" -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Mayús." - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hiper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Cambiar al VT 7" -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Cambiar al VT 8" -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "superior" +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Cambiar al VT 9" -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "inferior" +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Cambiar al VT 10" -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "izquierda" +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Cambiar al VT 11" -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "derecha" +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Cambiar al VT 12" -#: ../src/ui/theme.c:286 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "La geometría del marco no especifica la dimensión «%s»" +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "Volver a activar los atajos" -#: ../src/ui/theme.c:305 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow X11 grabs to lock keyboard focus with Xwayland" msgstr "" -"La geometría del marco no especifica la dimensión «%s» para el borde «%s»" +"Permitir capturas con X11 para bloquear el foco del teclado con Xwayland" -#: ../src/ui/theme.c:342 +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 +msgid "" +"Allow all keyboard events to be routed to X11 “override redirect” windows " +"with a grab when running in Xwayland. This option is to support X11 clients " +"which map an “override redirect” window (which do not receive keyboard " +"focus) and issue a keyboard grab to force all keyboard events to that " +"window. This option is seldom used and has no effect on regular X11 windows " +"which can receive keyboard focus under normal circumstances. For a X11 grab " +"to be taken into account under Wayland, the client must also either send a " +"specific X11 ClientMessage to the root window or be among the applications " +"white-listed in key “xwayland-grab-access-rules”." +msgstr "" +"Permitir que los eventos del teclado se dirijan a ventanas X11 “override " +"redirect” con una pulsación cuando se ejecutan en Xwayland. Esta opción es " +"para soportar clientes X11 que mapean una ventana “override redirect” (que " +"no recibe el foco del teclado) y recoge una pulsación del teclado para " +"forzar todos los eventos del teclado en esa ventana. Esta opción se usa " +"raramente y no tiene efecto en ventanas X11 normales que pueden recibir el " +"foco del teclado en circunstancias normales. Para que una pulsación X11 se " +"tenga en cuenta en Wayland el cliente debe o bien enviar un ClientMessage " +"específico de X11 a la ventana raíz o estar en la lista blanca de " +"aplicaciones en la clave “xwayland-grab-access-rules”." + +#: data/org.gnome.mutter.wayland.gschema.xml.in:84 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "Aplicaciones de Xwayland que pueden capturar el teclado" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:85 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "" +"Lista los nombres o las clases de recursos de ventanas X11 permitidas o no " +"para emitir pulsaciones de teclado X11 en XWayland. El nombre o la clase del " +"recurso de una ventana X11 dada se puede obtener usando el comando “xprop " +"WM_CLASS”. Se soportan los comodines «*» y «?». Los valores que empiecen por " +"«!» están en lista negra, que tiene prioridad sobre la lista blanca, para " +"revocar aplicaciones de la lista predeterminada del sistema. Esta lista " +"incluye las siguientes aplicaciones: “@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@”. " +"Los usuarios pueden romper una pulsación existente usando el atajo " +"específico del teclado definido por la clave “restore-shortcuts”." + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. +#. +#: src/backends/meta-input-settings.c:2567 #, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "La proporción del botón %g no es razonable" +msgid "Mode Switch (Group %d)" +msgstr "Cambiar modo (grupo %d)" -#: ../src/ui/theme.c:354 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "La geometría del marco no especifica el tamaño de los botones" +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2590 +msgid "Switch monitor" +msgstr "Cambiar monitor" -#: ../src/ui/theme.c:1067 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "Los degradados deben tener al menos dos colores" +#: src/backends/meta-input-settings.c:2592 +msgid "Show on-screen help" +msgstr "Mostrar la ayuda en pantalla" -#: ../src/ui/theme.c:1219 -#, c-format -msgid "" -"GTK custom color specification must have color name and fallback in " -"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" -msgstr "" -"La especificación de color GTK debe tener un nombre de color y nombre " -"alternativo entre paréntesis, ejemplo: gtk:custom(foo,bar); no se pudo " -"analizar «%s»" +#: src/backends/meta-monitor.c:223 +msgid "Built-in display" +msgstr "Pantalla integrada" + +#: src/backends/meta-monitor.c:252 +msgid "Unknown" +msgstr "Desconocida" -#: ../src/ui/theme.c:1235 +#: src/backends/meta-monitor.c:254 +msgid "Unknown Display" +msgstr "Pantalla desconocida" + +#: src/backends/meta-monitor.c:262 #, c-format -msgid "" -"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" -"_ are valid" -msgstr "" -"Caracter «%c» no válido en el parámetro «color_name» de «gtk:custom», sólo «A-Za-" -"z0-9-_» son válidos" +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme.c:1249 +#: src/backends/meta-monitor.c:270 #, c-format -msgid "" -"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " -"fit the format" -msgstr "" -"El formato de «gtk:custom» es «gtk:custom(nombre_de_color," -"nombre_alternativo)», «%s» no respeta el formato" +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" + +#. Translators: this string will appear in Sysprof +#: src/backends/meta-profiler.c:79 +msgid "Compositor" +msgstr "Compositor" -#: ../src/ui/theme.c:1294 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:533 #, c-format msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" +"Another compositing manager is already running on screen %i on display “%s”." msgstr "" -"La especificación de color GTK debe tener el estado entre corchetes, " -"ejemplo. gtk:fg[NORMAL] donde NORMAL es el estado ; no se ha podido " -"interpretar «%s»" +"Ya existe un gestor de composición ejecutándose en la monitor %i, pantalla " +"«%s»." + +#: src/core/bell.c:192 +msgid "Bell event" +msgstr "Evento de campana" + +#: src/core/main.c:190 +msgid "Disable connection to session manager" +msgstr "Desactivar conexión al gestor de sesión" + +#: src/core/main.c:196 +msgid "Replace the running window manager" +msgstr "Reemplazar el gestor de ventanas en ejecución" + +#: src/core/main.c:202 +msgid "Specify session management ID" +msgstr "Especificar el ID se gestión de sesión" -#: ../src/ui/theme.c:1308 +#: src/core/main.c:207 +msgid "X Display to use" +msgstr "Pantalla X que usar" + +#: src/core/main.c:213 +msgid "Initialize session from savefile" +msgstr "Inicializar sesión desde el archivo de salvaguarda" + +#: src/core/main.c:219 +msgid "Make X calls synchronous" +msgstr "Hacer que las llamadas a las X sean síncronas" + +#: src/core/main.c:226 +msgid "Run as a wayland compositor" +msgstr "Ejecutar como compositor Wayland" + +#: src/core/main.c:232 +msgid "Run as a nested compositor" +msgstr "Ejecutar como compositor anidado" + +#: src/core/main.c:238 +msgid "Run wayland compositor without starting Xwayland" +msgstr "Ejecutar el compositor wayland sin iniciar Xwayland" + +#: src/core/main.c:246 +msgid "Run as a full display server, rather than nested" +msgstr "Ejecutar como servidor completo, en lugar de anidado" + +#: src/core/main.c:252 +msgid "Run with X11 backend" +msgstr "Ejecutar con «backend» de X11" + +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:151 #, c-format +msgid "“%s” is not responding." +msgstr "«%s» no está respondiendo." + +#: src/core/meta-close-dialog-default.c:153 +msgid "Application is not responding." +msgstr "La aplicación no está respondiendo." + +#: src/core/meta-close-dialog-default.c:158 msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." msgstr "" -"La especificación de color GTK debe tener un corchete cerrado después del " -"estado, ejemplo. gtk:fg[NORMAL] donde NORMAL es el estado ; no se ha podido " -"interpretar «%s»" +"Puede elegir esperar un rato para ver si continua o forzar la aplicación " +"para cerrarla completamente." -#: ../src/ui/theme.c:1319 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "No se entiende el estado «%s» en la especificación del color" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Force Quit" +msgstr "_Forzar la salida" -#: ../src/ui/theme.c:1332 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "" -"No se entiende el componente de color «%s» en la especificación del color" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Wait" +msgstr "_Esperar" -#: ../src/ui/theme.c:1361 +#: src/core/mutter.c:38 #, c-format msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" msgstr "" -"El formato de blend es «blend/bg_color/fg_color/alfa», «%s» no cumple con el " -"formato" +"muttery %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., y otros\n" +"Este programa es software libre; vea el código fuente para obtener las " +"condiciones de copia.\n" +"NO se proporciona ninguna garantía; ni de MERCANTILIDAD O DE IDONEIDAD PARA " +"UN PROPÓSITO PARTICULAR.\n" + +#: src/core/mutter.c:52 +msgid "Print version" +msgstr "Imprimir versión" -#: ../src/ui/theme.c:1372 +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "Complemento de mutter que usar" + +#: src/core/prefs.c:1911 #, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "No se ha podido interpretar el valor alfa «%s» en el color mezclado" +msgid "Workspace %d" +msgstr "Área de trabajo %d" + +#: src/core/util.c:122 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter fue compilado sin soporte para modo prolijo\n" -#: ../src/ui/theme.c:1382 +#: src/wayland/meta-wayland-tablet-pad.c:568 #, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "El valor alfa «%s» en el color mezclado no está entre 0.0 y 1.0" +msgid "Mode Switch: Mode %d" +msgstr "Cambiar modo: modo %d" -#: ../src/ui/theme.c:1429 +#: src/x11/meta-x11-display.c:676 #, c-format msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." msgstr "" -"El formato de sombreado es «shade/base_color/factor», «%s» no coincide con el " -"formato" +"La pantalla «%s» ya tiene un gestor de ventanas; pruebe a usar la opción «--" +"replace» para reemplazar el gestor de ventanas activo." -#: ../src/ui/theme.c:1440 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "" -"No se ha podido interpretar el factor de sombreado «%s» en el color del " -"sombreado" +#: src/x11/meta-x11-display.c:1089 +msgid "Failed to initialize GDK\n" +msgstr "Falló al inicializar GDK\n" -#: ../src/ui/theme.c:1450 +#: src/x11/meta-x11-display.c:1113 #, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "El factor de sombreado «%s» en el color sombreado es negativo" +msgid "Failed to open X Window System display “%s”\n" +msgstr "Ocurrió un error al abrir la pantalla de X Window System «%s»\n" -#: ../src/ui/theme.c:1479 +#: src/x11/meta-x11-display.c:1196 #, c-format -msgid "Could not parse color \"%s\"" -msgstr "No se ha podido interpretar el color «%s»" +msgid "Screen %d on display “%s” is invalid\n" +msgstr "La ventana %d en la pantalla «%s» no es válida\n" -#: ../src/ui/theme.c:1790 +#: src/x11/meta-x11-selection-input-stream.c:460 #, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "" -"La expresión de coordenadas contenía un carácter «%s» en cual no está " -"permitido" +msgid "Format %s not supported" +msgstr "Formato %s no soportado" -#: ../src/ui/theme.c:1817 -#, c-format +#: src/x11/session.c:1821 msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." msgstr "" -"La expresión de coordenadas contenía un número de coma flotante «%s» en cual " -"no pudo ser analizado" +"Estas ventanas no soportan «guardar la configuración actual» y tendrán que " +"reiniciarse manualmente la próxima vez que inicie una sesión." -#: ../src/ui/theme.c:1831 +#: src/x11/window-props.c:569 #, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "" -"La expresión de coordenadas contenía un entero «%s» que no pudo ser analizado" +msgid "%s (on %s)" +msgstr "%s (on %s)" -#: ../src/ui/theme.c:1953 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "" -"La expresión de coordenadas contenía un operador inválido al inicio de su " -"texto: «%s»" +#~ msgid "Move window one workspace to the left" +#~ msgstr "Mover la ventana un área de trabajo a la izquierda" -#: ../src/ui/theme.c:2010 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "La expresión de coordenadas estaba vacía o no fue entendida" +#~ msgid "Move window one workspace to the right" +#~ msgstr "Mover la ventana un área de trabajo a la derecha" -#: ../src/ui/theme.c:2121 ../src/ui/theme.c:2131 ../src/ui/theme.c:2165 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "La expresión de coordenadas resultó en un error de división por cero" +#~ msgid "Move to workspace left" +#~ msgstr "Mover al área de trabajo de la izquierda" -#: ../src/ui/theme.c:2173 -#, c-format -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "" -"La expresión de coordenadas intentó usar un operador mod con un número de " -"coma flotante" +#~ msgid "Move to workspace right" +#~ msgstr "Mover al área de trabajo de la derecha" -#: ../src/ui/theme.c:2229 -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "" -"La expresión de coordenadas tiene un operador «%s» donde se esperaba un " -"operando" +#~ msgid "Toggle shaded state" +#~ msgstr "Cambiar el estado de enrollado" -#: ../src/ui/theme.c:2238 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "" -"La expresión de coordenadas tiene un operando donde se esperaba un operador" +#~ msgid "background texture could not be created from file" +#~ msgstr "no se pudo crear la textura de fondo a partir de archivo" -#: ../src/ui/theme.c:2246 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "" -"La expresión de coordenadas termina con una operador en vez de un operando" +#~ msgid "Failed to scan themes directory: %s\n" +#~ msgstr "Falló al inspeccionar la carpeta de temas: %s\n" -#: ../src/ui/theme.c:2256 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" -"La expresión de coordenadas tiene el operador «%c» seguido del operador «%c» " -"sin un operando entre ellos" +#~ msgid "" +#~ "Could not find a theme! Be sure %s exists and contains the usual themes.\n" +#~ msgstr "" +#~ "No se ha podido encontrar un tema. Asegúrese de que %s existe y contiene " +#~ "los temas usuales.\n" -#: ../src/ui/theme.c:2407 ../src/ui/theme.c:2452 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "" -"La expresión de coordenadas tenía una variable o constante desconocida «%s»" +#~ msgid "Screen %d on display \"%s\" already has a window manager\n" +#~ msgstr "La ventana %d en la pantalla «%s» ya tiene un gestor de ventanas\n" -#: ../src/ui/theme.c:2506 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "El parser de la expresión de coordenadas desbordó su búfer." +#~ msgid "%d x %d" +#~ msgstr "%d x %d" -#: ../src/ui/theme.c:2535 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "" -"La expresión de coordenadas tenía un paréntesis cerrado sin un paréntesis " -"abierto" +#~ msgid "top" +#~ msgstr "superior" -#: ../src/ui/theme.c:2599 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "" -"La expresión de coordenadas tenía un paréntesis abierto sin un paréntesis " -"cerrado" +#~ msgid "bottom" +#~ msgstr "inferior" -#: ../src/ui/theme.c:2610 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "La expresión de coordenadas no parece tener ni operadores ni operandos" +#~ msgid "left" +#~ msgstr "izquierda" -#: ../src/ui/theme.c:2822 ../src/ui/theme.c:2842 ../src/ui/theme.c:2862 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "El tema contenía una expresión que ha resultado en un error: %s\n" +#~ msgid "right" +#~ msgstr "derecha" -#: ../src/ui/theme.c:4533 -#, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> debe ser " -"especificado para este estilo de marco" +#~ msgid "frame geometry does not specify \"%s\" dimension" +#~ msgstr "La geometría del marco no especifica la dimensión «%s»" -#: ../src/ui/theme.c:5066 ../src/ui/theme.c:5091 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" -"Falta <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" +#~ msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" +#~ msgstr "" +#~ "La geometría del marco no especifica la dimensión «%s» para el borde «%s»" -#: ../src/ui/theme.c:5139 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Ocurrió un error al cargar el tema «%s»: %s\n" +#~ msgid "Button aspect ratio %g is not reasonable" +#~ msgstr "La proporción del botón %g no es razonable" -#: ../src/ui/theme.c:5275 ../src/ui/theme.c:5282 ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 ../src/ui/theme.c:5303 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "No se configuró <%s> para el tema «%s»" +#~ msgid "Frame geometry does not specify size of buttons" +#~ msgstr "La geometría del marco no especifica el tamaño de los botones" -#: ../src/ui/theme.c:5311 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" -"No hay un estilo de marco para el tipo de ventana «%s» en el tema «%s», añada " -"un elemento <window type=\"%s\" style_set=\"whatever\"/>" +#~ msgid "Gradients should have at least two colors" +#~ msgstr "Los degradados deben tener al menos dos colores" -#: ../src/ui/theme.c:5709 ../src/ui/theme.c:5771 ../src/ui/theme.c:5834 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" -"Las constantes definidas por el usuario deben comenzar con una letra " -"mayúscula; «%s» no lo hace" +#~ msgid "" +#~ "GTK custom color specification must have color name and fallback in " +#~ "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" +#~ msgstr "" +#~ "La especificación de color GTK debe tener un nombre de color y nombre " +#~ "alternativo entre paréntesis, ejemplo: gtk:custom(foo,bar); no se pudo " +#~ "analizar «%s»" -#: ../src/ui/theme.c:5717 ../src/ui/theme.c:5779 ../src/ui/theme.c:5842 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "La constante «%s» ya ha sido definida" +#~ msgid "" +#~ "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-" +#~ "z0-9-_ are valid" +#~ msgstr "" +#~ "Caracter «%c» no válido en el parámetro «color_name» de «gtk:custom», " +#~ "sólo «A-Za-z0-9-_» son válidos" -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. -#. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "El atributo «%s» no está definido en el elemento <%s>" +#~ msgid "" +#~ "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " +#~ "fit the format" +#~ msgstr "" +#~ "El formato de «gtk:custom» es «gtk:custom(nombre_de_color," +#~ "nombre_alternativo)», «%s» no respeta el formato" -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Línea %d carácter %d: %s" +#~ msgid "" +#~ "GTK color specification must have the state in brackets, e.g. gtk:" +#~ "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "La especificación de color GTK debe tener el estado entre corchetes, " +#~ "ejemplo. gtk:fg[NORMAL] donde NORMAL es el estado ; no se ha podido " +#~ "interpretar «%s»" -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "El atributo «%s» se ha repetido dos veces en el mismo elemento <%s>" +#~ msgid "" +#~ "GTK color specification must have a close bracket after the state, e.g. " +#~ "gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "La especificación de color GTK debe tener un corchete cerrado después del " +#~ "estado, ejemplo. gtk:fg[NORMAL] donde NORMAL es el estado ; no se ha " +#~ "podido interpretar «%s»" -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "El atributo «%s» es inválido en el elemento <%s> en este contexto" +#~ msgid "Did not understand state \"%s\" in color specification" +#~ msgstr "No se entiende el estado «%s» en la especificación del color" -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "No se ha podido interpretar «%s» como un entero" +#~ msgid "Did not understand color component \"%s\" in color specification" +#~ msgstr "" +#~ "No se entiende el componente de color «%s» en la especificación del color" -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "No se comprenden los caracteres sobrantes «%s» en la cadena «%s»" +#~ msgid "" +#~ "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit " +#~ "the format" +#~ msgstr "" +#~ "El formato de blend es «blend/bg_color/fg_color/alfa», «%s» no cumple con " +#~ "el formato" -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "El entero %ld debe ser positivo" +#~ msgid "Could not parse alpha value \"%s\" in blended color" +#~ msgstr "No se ha podido interpretar el valor alfa «%s» en el color mezclado" -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "El entero %ld es demasiado grande, el máximo actual es %d" +#~ msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" +#~ msgstr "El valor alfa «%s» en el color mezclado no está entre 0.0 y 1.0" -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "No se ha podido interpretar «%s» como un número de coma flotante" +#~ msgid "" +#~ "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the " +#~ "format" +#~ msgstr "" +#~ "El formato de sombreado es «shade/base_color/factor», «%s» no coincide " +#~ "con el formato" -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "Los valores booleanos deben ser «true» o «false» no «%s»" +#~ msgid "Could not parse shade factor \"%s\" in shaded color" +#~ msgstr "" +#~ "No se ha podido interpretar el factor de sombreado «%s» en el color del " +#~ "sombreado" -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "El ángulo debe estar entre 0.0 y 360.0, fue %g\n" +#~ msgid "Shade factor \"%s\" in shaded color is negative" +#~ msgstr "El factor de sombreado «%s» en el color sombreado es negativo" -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" -"El valor de alfa debe estar entre 0.0 (invisible) y 1.0 (completamente " -"opaco), fue %g\n" +#~ msgid "Could not parse color \"%s\"" +#~ msgstr "No se ha podido interpretar el color «%s»" -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"Escala de título inválida «%s» (debe ser una de xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" +#~ msgid "Coordinate expression contains character '%s' which is not allowed" +#~ msgstr "" +#~ "La expresión de coordenadas contenía un carácter «%s» en cual no está " +#~ "permitido" -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s> nombre «%s» usado una segunda vez" +#~ msgid "" +#~ "Coordinate expression contains floating point number '%s' which could not " +#~ "be parsed" +#~ msgstr "" +#~ "La expresión de coordenadas contenía un número de coma flotante «%s» en " +#~ "cual no pudo ser analizado" -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "El <%s> padre «%s» no ha sido definido" +#~ msgid "" +#~ "Coordinate expression contains integer '%s' which could not be parsed" +#~ msgstr "" +#~ "La expresión de coordenadas contenía un entero «%s» que no pudo ser " +#~ "analizado" -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "La <%s> geometría «%s» no ha sido definida" +#~ msgid "" +#~ "Coordinate expression contained unknown operator at the start of this " +#~ "text: \"%s\"" +#~ msgstr "" +#~ "La expresión de coordenadas contenía un operador no válido al inicio de " +#~ "su texto: «%s»" -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "" -"<%s> debe especificar o una geometría o un padre para tenga una geometría" +#~ msgid "Coordinate expression was empty or not understood" +#~ msgstr "La expresión de coordenadas estaba vacía o no fue entendida" -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "Debe especificar un fondo para un valor alfa para que tenga sentido" +#~ msgid "Coordinate expression results in division by zero" +#~ msgstr "" +#~ "La expresión de coordenadas resultó en un error de división por cero" -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Tipo «%s» desconocido en el elemento <%s>" +#~ msgid "" +#~ "Coordinate expression tries to use mod operator on a floating-point number" +#~ msgstr "" +#~ "La expresión de coordenadas intentó usar un operador mod con un número de " +#~ "coma flotante" -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "style_set «%s» desconocido en el elemento <%s>" +#~ msgid "" +#~ "Coordinate expression has an operator \"%s\" where an operand was expected" +#~ msgstr "" +#~ "La expresión de coordenadas tiene un operador «%s» donde se esperaba un " +#~ "operando" -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "El tipo de ventana «%s» ya ha sido asignado a un conjunto de estilo" - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "El elemento <%s> no está permitido debajo de <%s>" +#~ msgid "Coordinate expression had an operand where an operator was expected" +#~ msgstr "" +#~ "La expresión de coordenadas tiene un operando donde se esperaba un " +#~ "operador" -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" -msgstr "" -"No se puede especificar ambos «button_width»/«button_height» y «aspect ratio» " -"para los botones" +#~ msgid "Coordinate expression ended with an operator instead of an operand" +#~ msgstr "" +#~ "La expresión de coordenadas termina con una operador en vez de un operando" -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "La distancia «%s» es desconocida" +#~ msgid "" +#~ "Coordinate expression has operator \"%c\" following operator \"%c\" with " +#~ "no operand in between" +#~ msgstr "" +#~ "La expresión de coordenadas tiene el operador «%c» seguido del operador " +#~ "«%c» sin un operando entre ellos" -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "La proporción «%s» es desconocido" +#~ msgid "Coordinate expression had unknown variable or constant \"%s\"" +#~ msgstr "" +#~ "La expresión de coordenadas tenía una variable o constante desconocida " +#~ "«%s»" -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "El borde «%s» es desconocido" +#~ msgid "Coordinate expression parser overflowed its buffer." +#~ msgstr "El parser de la expresión de coordenadas desbordó su búfer." -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "No hay atributo «start_angle» o «from» en el elemento <%s>" +#~ msgid "" +#~ "Coordinate expression had a close parenthesis with no open parenthesis" +#~ msgstr "" +#~ "La expresión de coordenadas tenía un paréntesis cerrado sin un paréntesis " +#~ "abierto" -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "No hay atributo «extent_angle» o «to» en el elemento <%s>" +#~ msgid "" +#~ "Coordinate expression had an open parenthesis with no close parenthesis" +#~ msgstr "" +#~ "La expresión de coordenadas tenía un paréntesis abierto sin un paréntesis " +#~ "cerrado" -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "No se entendió el valor «%s» para el tipo de degradado" +#~ msgid "Coordinate expression doesn't seem to have any operators or operands" +#~ msgstr "" +#~ "La expresión de coordenadas no parece tener ni operadores ni operandos" -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "No se entendió en tipo de relleno «%s» para el elemento <%s>" +#~ msgid "Theme contained an expression that resulted in an error: %s\n" +#~ msgstr "El tema contenía una expresión que ha resultado en un error: %s\n" -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "No se entendió estado «%s» para el elemento <%s>" +#~ msgid "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " +#~ "specified for this frame style" +#~ msgstr "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> debe ser " +#~ "especificado para este estilo de marco" -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "No se entendió enrollar «%s» para el elemento <%s>" +#~ msgid "" +#~ "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/" +#~ ">" +#~ msgstr "" +#~ "Falta <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "No se entendió la flecha «%s» para el elemento <%s>" +#~ msgid "Failed to load theme \"%s\": %s\n" +#~ msgstr "Ocurrió un error al cargar el tema «%s»: %s\n" -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "No se ha definido una <draw_ops> llamada «%s»" +#~ msgid "No <%s> set for theme \"%s\"" +#~ msgstr "No se configuró <%s> para el tema «%s»" -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "Incluir el draw_ops «%s» aquí podría crear una referencia circular" +#~ msgid "" +#~ "No frame style set for window type \"%s\" in theme \"%s\", add a <window " +#~ "type=\"%s\" style_set=\"whatever\"/> element" +#~ msgstr "" +#~ "No hay un estilo de marco para el tipo de ventana «%s» en el tema «%s», " +#~ "añada un elemento <window type=\"%s\" style_set=\"whatever\"/>" -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Posición desconocida «%s» para la pieza del marco" +#~ msgid "" +#~ "User-defined constants must begin with a capital letter; \"%s\" does not" +#~ msgstr "" +#~ "Las constantes definidas por el usuario deben comenzar con una letra " +#~ "mayúscula; «%s» no lo hace" -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "El estilo del marco ya tiene una pieza en la posición %s" +#~ msgid "Constant \"%s\" has already been defined" +#~ msgstr "La constante «%s» ya ha sido definida" -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "No se ha definido ninguna <draw_ops> con el nombre «%s»" +#~ msgid "No \"%s\" attribute on element <%s>" +#~ msgstr "El atributo «%s» no está definido en el elemento <%s>" -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Función desconocida «%s» para el botón" +#~ msgid "Line %d character %d: %s" +#~ msgstr "Línea %d carácter %d: %s" -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "La función del botón «%s» no existe en esta versión (%d, necesita %d)" +#~ msgid "Attribute \"%s\" repeated twice on the same <%s> element" +#~ msgstr "El atributo «%s» se ha repetido dos veces en el mismo elemento <%s>" -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Estado desconocido «%s» para el botón" +#~ msgid "Attribute \"%s\" is invalid on <%s> element in this context" +#~ msgstr "El atributo «%s» es no válido en el elemento <%s> en este contexto" -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "El estilo del marcos ya tiene un botón para la función %s estado %s" +#~ msgid "Could not parse \"%s\" as an integer" +#~ msgstr "No se ha podido interpretar «%s» como un entero" -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "«%s» no es valor válido para el atributo foco" +#~ msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +#~ msgstr "No se comprenden los caracteres sobrantes «%s» en la cadena «%s»" -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "«%s» no es un valor válido para el atributo estado" +#~ msgid "Integer %ld must be positive" +#~ msgstr "El entero %ld debe ser positivo" -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "No se ha definido ningún estilo llamado «%s»" +#~ msgid "Integer %ld is too large, current max is %d" +#~ msgstr "El entero %ld es demasiado grande, el máximo actual es %d" -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "«%s» no es un estado válido para el atributo resize" +#~ msgid "Could not parse \"%s\" as a floating point number" +#~ msgstr "No se ha podido interpretar «%s» como un número de coma flotante" -#: ../src/ui/theme-parser.c:3147 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" -"No debería tener un atributo «resize» en el elemento <%s> para los estados " -"maximizado/enrollado" +#~ msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" +#~ msgstr "Los valores booleanos deben ser «true» o «false» no «%s»" -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "" -"No debería tener un atributo «resize» en el elemento <%s> para los estados " -"maximizados." +#~ msgid "Angle must be between 0.0 and 360.0, was %g\n" +#~ msgstr "El ángulo debe estar entre 0.0 y 360.0, fue %g\n" -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "" -"El estilo ya ha sido especificado para estado %s redimensionado %s foco %s" +#~ msgid "" +#~ "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" +#~ msgstr "" +#~ "El valor de alfa debe estar entre 0.0 (invisible) y 1.0 (completamente " +#~ "opaco), fue %g\n" -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "El estilo ya ha sido especificado para estado %s foco %s" +#~ msgid "" +#~ "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," +#~ "large,x-large,xx-large)\n" +#~ msgstr "" +#~ "Escala de título no válida «%s» (debe ser una de xx-small,x-small,small," +#~ "medium,large,x-large,xx-large)\n" -#: ../src/ui/theme-parser.c:3294 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"No puede tener dos draw_ops para un elemento <piece> (el tema ha " -"especificado un atributo draw_ops y también un elemento <draw_ops> o ha " -"especificado los dos elementos)" +#~ msgid "<%s> name \"%s\" used a second time" +#~ msgstr "<%s> nombre «%s» usado una segunda vez" -#: ../src/ui/theme-parser.c:3332 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"No puede tener dos draw_ops para un elemento <button> (el tema ha " -"especificado un atributo draw_ops y también un elemento <draw_ops> o ha " -"especificado los dos elementos)" +#~ msgid "<%s> parent \"%s\" has not been defined" +#~ msgstr "El <%s> padre «%s» no ha sido definido" -#: ../src/ui/theme-parser.c:3370 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"No puede tener dos draw_ops para un elemento <menu_icon> (el tema ha " -"especificado un atributo draw_ops y también un elemento <draw_ops> o ha " -"especificado los dos elementos)" +#~ msgid "<%s> geometry \"%s\" has not been defined" +#~ msgstr "La <%s> geometría «%s» no ha sido definida" -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "Especificación de versión «%s» errónea" +#~ msgid "<%s> must specify either a geometry or a parent that has a geometry" +#~ msgstr "" +#~ "<%s> debe especificar o una geometría o un padre para tenga una geometría" -#: ../src/ui/theme-parser.c:3507 -msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" -msgstr "" -"No se puede usar el atributo «version» con metacity-theme-1.xml o metacity-" -"theme-2.xml" +#~ msgid "You must specify a background for an alpha value to be meaningful" +#~ msgstr "Debe especificar un fondo para un valor alfa para que tenga sentido" -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "" -"El tema requiere la versión %s pero la última versión soportada del tema es " -"la %d.%d" +#~ msgid "Unknown type \"%s\" on <%s> element" +#~ msgstr "Tipo «%s» desconocido en el elemento <%s>" -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "El elemento mas externo en un tema debe ser <metacity_theme> no <%s>" +#~ msgid "Unknown style_set \"%s\" on <%s> element" +#~ msgstr "style_set «%s» desconocido en el elemento <%s>" -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "" -"El elemento <%s> no esta permitido dentro de un elemento name/author/date/" -"description" +#~ msgid "Window type \"%s\" has already been assigned a style set" +#~ msgstr "El tipo de ventana «%s» ya ha sido asignado a un conjunto de estilo" + +#~ msgid "Element <%s> is not allowed below <%s>" +#~ msgstr "El elemento <%s> no está permitido debajo de <%s>" + +#~ msgid "" +#~ "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio" +#~ "\" for buttons" +#~ msgstr "" +#~ "No se puede especificar ambos «button_width»/«button_height» y «aspect " +#~ "ratio» para los botones" + +#~ msgid "Distance \"%s\" is unknown" +#~ msgstr "La distancia «%s» es desconocida" + +#~ msgid "Aspect ratio \"%s\" is unknown" +#~ msgstr "La proporción «%s» es desconocido" + +#~ msgid "Border \"%s\" is unknown" +#~ msgstr "El borde «%s» es desconocido" + +#~ msgid "No \"start_angle\" or \"from\" attribute on element <%s>" +#~ msgstr "No hay atributo «start_angle» o «from» en el elemento <%s>" + +#~ msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" +#~ msgstr "No hay atributo «extent_angle» o «to» en el elemento <%s>" + +#~ msgid "Did not understand value \"%s\" for type of gradient" +#~ msgstr "No se entendió el valor «%s» para el tipo de degradado" + +#~ msgid "Did not understand fill type \"%s\" for <%s> element" +#~ msgstr "No se entendió en tipo de relleno «%s» para el elemento <%s>" + +#~ msgid "Did not understand state \"%s\" for <%s> element" +#~ msgstr "No se entendió estado «%s» para el elemento <%s>" + +#~ msgid "Did not understand shadow \"%s\" for <%s> element" +#~ msgstr "No se entendió enrollar «%s» para el elemento <%s>" + +#~ msgid "Did not understand arrow \"%s\" for <%s> element" +#~ msgstr "No se entendió la flecha «%s» para el elemento <%s>" + +#~ msgid "No <draw_ops> called \"%s\" has been defined" +#~ msgstr "No se ha definido una <draw_ops> llamada «%s»" + +#~ msgid "Including draw_ops \"%s\" here would create a circular reference" +#~ msgstr "Incluir el draw_ops «%s» aquí podría crear una referencia circular" + +#~ msgid "Unknown position \"%s\" for frame piece" +#~ msgstr "Posición desconocida «%s» para la pieza del marco" + +#~ msgid "Frame style already has a piece at position %s" +#~ msgstr "El estilo del marco ya tiene una pieza en la posición %s" + +#~ msgid "No <draw_ops> with the name \"%s\" has been defined" +#~ msgstr "No se ha definido ninguna <draw_ops> con el nombre «%s»" + +#~ msgid "Unknown function \"%s\" for button" +#~ msgstr "Función desconocida «%s» para el botón" + +#~ msgid "Button function \"%s\" does not exist in this version (%d, need %d)" +#~ msgstr "" +#~ "La función del botón «%s» no existe en esta versión (%d, necesita %d)" + +#~ msgid "Unknown state \"%s\" for button" +#~ msgstr "Estado desconocido «%s» para el botón" + +#~ msgid "Frame style already has a button for function %s state %s" +#~ msgstr "El estilo del marcos ya tiene un botón para la función %s estado %s" + +#~ msgid "\"%s\" is not a valid value for focus attribute" +#~ msgstr "«%s» no es valor válido para el atributo foco" + +#~ msgid "\"%s\" is not a valid value for state attribute" +#~ msgstr "«%s» no es un valor válido para el atributo estado" + +#~ msgid "A style called \"%s\" has not been defined" +#~ msgstr "No se ha definido ningún estilo llamado «%s»" + +#~ msgid "\"%s\" is not a valid value for resize attribute" +#~ msgstr "«%s» no es un estado válido para el atributo resize" + +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized/shaded " +#~ "states" +#~ msgstr "" +#~ "No debería tener un atributo «resize» en el elemento <%s> para los " +#~ "estados maximizado/enrollado" + +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized states" +#~ msgstr "" +#~ "No debería tener un atributo «resize» en el elemento <%s> para los " +#~ "estados maximizados." + +#~ msgid "Style has already been specified for state %s resize %s focus %s" +#~ msgstr "" +#~ "El estilo ya ha sido especificado para estado %s redimensionado %s foco %s" + +#~ msgid "Style has already been specified for state %s focus %s" +#~ msgstr "El estilo ya ha sido especificado para estado %s foco %s" + +#~ msgid "" +#~ "Can't have a two draw_ops for a <piece> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "No puede tener dos draw_ops para un elemento <piece> (el tema ha " +#~ "especificado un atributo draw_ops y también un elemento <draw_ops> o ha " +#~ "especificado los dos elementos)" + +#~ msgid "" +#~ "Can't have a two draw_ops for a <button> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "No puede tener dos draw_ops para un elemento <button> (el tema ha " +#~ "especificado un atributo draw_ops y también un elemento <draw_ops> o ha " +#~ "especificado los dos elementos)" + +#~ msgid "" +#~ "Can't have a two draw_ops for a <menu_icon> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "No puede tener dos draw_ops para un elemento <menu_icon> (el tema ha " +#~ "especificado un atributo draw_ops y también un elemento <draw_ops> o ha " +#~ "especificado los dos elementos)" + +#~ msgid "Bad version specification '%s'" +#~ msgstr "Especificación de versión «%s» errónea" + +#~ msgid "" +#~ "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" +#~ "theme-2.xml" +#~ msgstr "" +#~ "No se puede usar el atributo «version» con metacity-theme-1.xml o " +#~ "metacity-theme-2.xml" + +#~ msgid "" +#~ "Theme requires version %s but latest supported theme version is %d.%d" +#~ msgstr "" +#~ "El tema requiere la versión %s pero la última versión soportada del tema " +#~ "es la %d.%d" + +#~ msgid "Outermost element in theme must be <metacity_theme> not <%s>" +#~ msgstr "" +#~ "El elemento mas externo en un tema debe ser <metacity_theme> no <%s>" + +#~ msgid "" +#~ "Element <%s> is not allowed inside a name/author/date/description element" +#~ msgstr "" +#~ "El elemento <%s> no esta permitido dentro de un elemento name/author/date/" +#~ "description" + +#~ msgid "Element <%s> is not allowed inside a <constant> element" +#~ msgstr "El elemento <%s> no esta permitido dentro de un elemento <constant>" + +#~ msgid "" +#~ "Element <%s> is not allowed inside a distance/border/aspect_ratio element" +#~ msgstr "" +#~ "El elemento <%s> no esta permitido dentro de un elemento distance/border/" +#~ "aspect_ratio" + +#~ msgid "Element <%s> is not allowed inside a draw operation element" +#~ msgstr "" +#~ "El elemento <%s> no esta permitido dentro de un elemento de operación de " +#~ "dibujo" + +#~ msgid "Element <%s> is not allowed inside a <%s> element" +#~ msgstr "El elemento <%s> no esta permitido dentro del elemento <%s>" + +#~ msgid "No draw_ops provided for frame piece" +#~ msgstr "No se dio draw_ops para la pieza del cuadro" + +#~ msgid "No draw_ops provided for button" +#~ msgstr "No se dio draw_ops para botón" + +#~ msgid "No text is allowed inside element <%s>" +#~ msgstr "No se permite texto dentro del elemento <%s>" + +#~ msgid "<%s> specified twice for this theme" +#~ msgstr "<%s> especificado dos veces para este tema" + +#~ msgid "Failed to find a valid file for theme %s\n" +#~ msgstr "Falló al encontrar un archivo válido para el tema%s\n" + +#~ msgid "Mi_nimize" +#~ msgstr "Mi_nimizar" + +#~ msgid "Ma_ximize" +#~ msgstr "Ma_ximizar" + +#~ msgid "Unma_ximize" +#~ msgstr "Desma_ximizar" + +#~ msgid "Roll _Up" +#~ msgstr "Enro_llar" + +#~ msgid "_Unroll" +#~ msgstr "De_senrollar" + +#~ msgid "_Move" +#~ msgstr "_Mover" + +#~ msgid "_Resize" +#~ msgstr "_Redimensionar" + +#~ msgid "Move Titlebar On_screen" +#~ msgstr "Mover la barra de título a la _pantalla" + +#~ msgid "Always on _Top" +#~ msgstr "Siempre _encima" + +#~ msgid "_Always on Visible Workspace" +#~ msgstr "Siempre en el área de trabajo _visible" + +#~ msgid "_Only on This Workspace" +#~ msgstr "_Sólo en este área de trabajo" + +#~ msgid "Move to Workspace _Left" +#~ msgstr "Mover al área de trabajo de la _izquierda" + +#~ msgid "Move to Workspace R_ight" +#~ msgstr "Mover al área de trabajo de la _derecha" + +#~ msgid "Move to Workspace _Up" +#~ msgstr "Mover al área de trabajo de _arriba" + +#~ msgid "Move to Workspace _Down" +#~ msgstr "Mover al área de trabajo de a_bajo" + +#~ msgid "_Close" +#~ msgstr "_Cerrar" + +#~ msgid "Workspace %d%n" +#~ msgstr "Área de trabajo %d%n" + +#~ msgid "Workspace 1_0" +#~ msgstr "Área de trabajo 1_0" + +#~ msgid "Workspace %s%d" +#~ msgstr "Área de trabajo %s%d" + +#~ msgid "Move to Another _Workspace" +#~ msgstr "Mover a _otro área de trabajo" + +#~ msgid "Shift" +#~ msgstr "Mayús." + +#~ msgid "Ctrl" +#~ msgstr "Ctrl" + +#~ msgid "Alt" +#~ msgstr "Alt" + +#~ msgid "Meta" +#~ msgstr "Meta" + +#~ msgid "Super" +#~ msgstr "Super" + +#~ msgid "Hyper" +#~ msgstr "Hiper" + +#~ msgid "Mod2" +#~ msgstr "Mod2" + +#~ msgid "Mod3" +#~ msgstr "Mod3" + +#~ msgid "Mod4" +#~ msgstr "Mod4" + +#~ msgid "Mod5" +#~ msgstr "Mod5" + +#~ msgid "Mutter (wayland compositor)" +#~ msgstr "Mutter (compositor Wayland)" + +#~ msgid "Unknown window information request: %d" +#~ msgstr "Petición de información de ventana desconocida: %d" + +#~ msgid "Missing %s extension required for compositing" +#~ msgstr "Falta la extensión %s requerida para la composición" + +#~ msgid "" +#~ "Some other program is already using the key %s with modifiers %x as a " +#~ "binding\n" +#~ msgstr "" +#~ "Algún otro programa ya está usando la clave %s con el modificador %x como " +#~ "una vinculación\n" + +#~ msgid "\"%s\" is not a valid accelerator\n" +#~ msgstr "«%s» no es un acelerador válido\n" + +#~ msgid "" +#~ "Workarounds for broken applications disabled. Some applications may not " +#~ "behave properly.\n" +#~ msgstr "" +#~ "Los arreglos para aplicaciones rotas se han deshabilitado. Algunas " +#~ "aplicaciones podrían no comportarse correctamente.\n" + +#~ msgid "Could not parse font description \"%s\" from GSettings key %s\n" +#~ msgstr "" +#~ "No se pudo analizar la descripción de la tipografía «%s» de la clave " +#~ "GSettings %s\n" + +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" +#~ msgstr "" +#~ "«%s» encontrado en la base de datos de configuración no es un valor " +#~ "válido para el modificador del botón del ratón\n" + +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for " +#~ "keybinding \"%s\"\n" +#~ msgstr "" +#~ "«%s» encontrado en la base de datos de configuración no es un valor " +#~ "válido para la combinación de teclas «%s»\n" + +#~ msgid "" +#~ "Could not acquire window manager selection on screen %d display \"%s\"\n" +#~ msgstr "" +#~ "No se ha podido obtener la selección del gestor de ventanas en la ventana " +#~ "%d en la pantalla «%s»\n" + +#~ msgid "Could not release screen %d on display \"%s\"\n" +#~ msgstr "No se ha podido liberar el monitor %d en la pantalla «%s»\n" + +#~ msgid "Could not create directory '%s': %s\n" +#~ msgstr "No se ha podido crear la carpeta «%s»: %s\n" + +#~ msgid "Could not open session file '%s' for writing: %s\n" +#~ msgstr "" +#~ "No se ha podido abrir para escritura el archivo de sesión «%s»: %s\n" + +#~ msgid "Error writing session file '%s': %s\n" +#~ msgstr "Ocurrió un error al escribir en el archivo de sesión «%s»: %s\n" + +#~ msgid "Error closing session file '%s': %s\n" +#~ msgstr "Ocurrió un error al cerrar el archivo de sesión «%s»: %s\n" + +#~ msgid "Failed to parse saved session file: %s\n" +#~ msgstr "Ocurrió un error al interpretar el archivo de sesión guardado: %s\n" + +#~ msgid "<mutter_session> attribute seen but we already have the session ID" +#~ msgstr "" +#~ "Se ha visto el atributo <mutter_session> pero ya tenemos el ID de la " +#~ "sesión" + +#~ msgid "Unknown attribute %s on <%s> element" +#~ msgstr "Atributo desconocido %s en el elemento <%s>" + +#~ msgid "nested <window> tag" +#~ msgstr "etiqueta <window> anidada" + +#~ msgid "Unknown element %s" +#~ msgstr "Elemento desconocido %s" + +#~ msgid "Failed to open debug log: %s\n" +#~ msgstr "Ocurrió un error al abrir el registro de errores: %s\n" + +#~ msgid "Failed to fdopen() log file %s: %s\n" +#~ msgstr "" +#~ "Ocurrió un error al hacer fdopen() en el archivo de registro %s: %s\n" + +#~ msgid "Opened log file %s\n" +#~ msgstr "Archivo de registro %s abierto\n" + +#~ msgid "Window manager: " +#~ msgstr "Administrador de ventanas: " + +# Diferenciar de eRRor en el gestor de ventanas, más abajo +#~ msgid "Bug in window manager: " +#~ msgstr "Error en el gestor de ventanas: " + +#~ msgid "Window manager warning: " +#~ msgstr "Advertencia del gestor de ventanas: " + +#~ msgid "Window manager error: " +#~ msgstr "Error del gestor de ventanas: " + +#~ msgid "" +#~ "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " +#~ "window as specified in the ICCCM.\n" +#~ msgstr "" +#~ "La ventana %s ha establecido SM_CLIENT_ID sobre sí misma en vez de " +#~ "hacerlo en la ventana WM_CLIENT_LEADER como está especificado en el " +#~ "ICCCM.\n" + +#~ msgid "" +#~ "Window %s sets an MWM hint indicating it isn't resizable, but sets min " +#~ "size %d x %d and max size %d x %d; this doesn't make much sense.\n" +#~ msgstr "" +#~ "La ventana %s ha establecido la propiedad MWM indicando que no es " +#~ "redimensionable, pero configuró el tamaño mínimo a %d x %d y el tamaño " +#~ "máximo a %d x %d ; esto no tiene mucho sentido.\n" + +#~ msgid "Application set a bogus _NET_WM_PID %lu\n" +#~ msgstr "La aplicación establecio un _NET_WM_PID %lu erróneo\n" + +#~ msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +#~ msgstr "" +#~ "WM_TRANSIENT_FOR no válido para la ventana 0x%lx especificada para %s.\n" + +#~ msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" +#~ msgstr "WM_TRANSIENT_FOR ventana 0x%lx para %s crearía un bucle.\n" + +#~ msgid "" +#~ "Window 0x%lx has property %s\n" +#~ "that was expected to have type %s format %d\n" +#~ "and actually has type %s format %d n_items %d.\n" +#~ "This is most likely an application bug, not a window manager bug.\n" +#~ "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +#~ msgstr "" +#~ "La ventana 0x%lx tiene la propiedad %s \n" +#~ "que se esperaba tuviese el tipo %s con el formato %d\n" +#~ "y actualmente tiene un tipo %s con el formato %d y n_items %d\n" +#~ "Esto no parece ser un error de la aplicación ni del gestor de ventanas.\n" +#~ "La ventana tiene título=«%s» la clase=«%s» y el nombre=«%s»\n" -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "El elemento <%s> no esta permitido dentro de un elemento <constant>" +#~ msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +#~ msgstr "La propiedad %s en la ventana 0x%lx contiene UTF-8 no válido\n" -#: ../src/ui/theme-parser.c:3599 -#, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "" -"El elemento <%s> no esta permitido dentro de un elemento distance/border/" -"aspect_ratio" +#~ msgid "" +#~ "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the " +#~ "list\n" +#~ msgstr "" +#~ "La propiedad %s en la ventana 0x%lx contiene UTF-8 no válido para el " +#~ "elemento %d de la lista\n" -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "" -"El elemento <%s> no esta permitido dentro de un elemento de operación de " -"dibujo" +#~ msgid "Usage: %s\n" +#~ msgstr "Uso: %s\n" -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "El elemento <%s> no esta permitido dentro del elemento <%s>" +#~ msgid "_Windows" +#~ msgstr "_Ventanas" -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "No se dio draw_ops para la pieza del cuadro" +#~ msgid "_Dialog" +#~ msgstr "_Diálogo" -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "No se dio draw_ops para botón" +#~ msgid "_Modal dialog" +#~ msgstr "Diálogo _modal" -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "No se permite texto dentro del elemento <%s>" +#~ msgid "_Utility" +#~ msgstr "_Utilidades" -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "<%s> especificado dos veces para este tema" +#~ msgid "_Splashscreen" +#~ msgstr "_Pantalla de inicio" -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Falló al encontrar un archivo válido para el tema%s\n" +#~ msgid "_Top dock" +#~ msgstr "Empotrable _superior" -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "_Ventanas" +#~ msgid "_Bottom dock" +#~ msgstr "Empotrable _inferior" -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "_Diálogo" +#~ msgid "_Left dock" +#~ msgstr "Empotrable i_zquierdo" -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "Diálogo _modal" +#~ msgid "_Right dock" +#~ msgstr "Empotrable de_recho" -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "_Utilidades" +#~ msgid "_All docks" +#~ msgstr "_Todos los empotrables" -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "_Pantalla de inicio" +#~ msgid "Des_ktop" +#~ msgstr "_Escritorio" -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "Empotrable _superior" +#~ msgid "Open another one of these windows" +#~ msgstr "Abrir otra de estas ventanas" -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "Empotrable _inferior" +#~ msgid "This is a demo button with an 'open' icon" +#~ msgstr "Esto es un botón de demostración con un icono de apertura" -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "Empotrable i_zquierdo" +#~ msgid "This is a demo button with a 'quit' icon" +#~ msgstr "Esto es un botón de demostración con un icono de salida" -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "Empotrable de_recho" +#~ msgid "This is a sample message in a sample dialog" +#~ msgstr "Esto es un mensaje de ejemplo en un diálogo de ejemplo" -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "_Todos los empotrables" +#~ msgid "Fake menu item %d\n" +#~ msgstr "Elemento de menú de pega %d\n" -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "_Escritorio" +#~ msgid "Border-only window" +#~ msgstr "Ventana con sólo borde" -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "Abrir otra de estas ventanas" +#~ msgid "Bar" +#~ msgstr "Barra" -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "Esto es un botón de demostración con un icono de apertura" +#~ msgid "Normal Application Window" +#~ msgstr "Ventana de aplicación normal" -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "Esto es un botón de demostración con un icono de salida" +#~ msgid "Dialog Box" +#~ msgstr "Caja de diálogo" -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "Esto es un mensaje de ejemplo en un diálogo de ejemplo" +#~ msgid "Modal Dialog Box" +#~ msgstr "Caja de diálogo modal" -#: ../src/ui/theme-viewer.c:328 -#, c-format -msgid "Fake menu item %d\n" -msgstr "Elemento de menú de pega %d\n" +#~ msgid "Utility Palette" +#~ msgstr "Paleta de utilidades" -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "Ventana con sólo borde" +#~ msgid "Torn-off Menu" +#~ msgstr "Menú apagado" -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "Barra" +#~ msgid "Border" +#~ msgstr "Borde" -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "Ventana de aplicación normal" +#~ msgid "Attached Modal Dialog" +#~ msgstr "Diálogo modal adjunto" -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "Caja de diálogo" +#~ msgid "Button layout test %d" +#~ msgstr "Test de distribución de botones %d" -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "Caja de diálogo modal" +#~ msgid "%g milliseconds to draw one window frame" +#~ msgstr "%g milisegundos para dibujar un marco de ventana" -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "Paleta de utilidades" +#~ msgid "Usage: metacity-theme-viewer [THEMENAME]\n" +#~ msgstr "Uso: metacity-theme-viewer [NOMBRETEMA]\n" -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "Menú apagado" +#~ msgid "Error loading theme: %s\n" +#~ msgstr "Ocurrió un error al cargar el tema:«%s»\n" -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "Borde" +#~ msgid "Loaded theme \"%s\" in %g seconds\n" +#~ msgstr "Se cargó el tema «%s» en %g segundos\n" -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "Diálogo modal adjunto" +#~ msgid "Normal Title Font" +#~ msgstr "Tipografía de título normal" -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "Test de distribución de botones %d" +#~ msgid "Small Title Font" +#~ msgstr "Tipografía de título pequeña" -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g milisegundos para dibujar un marco de ventana" +#~ msgid "Large Title Font" +#~ msgstr "Tipografía de título grande" -#: ../src/ui/theme-viewer.c:813 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Uso: metacity-theme-viewer [NOMBRETEMA]\n" +#~ msgid "Button Layouts" +#~ msgstr "Distribución de botones" -#: ../src/ui/theme-viewer.c:820 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "Ocurrió un error al cargar el tema:«%s»\n" +#~ msgid "Benchmark" +#~ msgstr "Banco de pruebas" -#: ../src/ui/theme-viewer.c:826 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "Se cargó el tema «%s» en %g segundos\n" +#~ msgid "Window Title Goes Here" +#~ msgstr "El título de la ventana va aquí" -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "Tipografía de título normal" +#~ msgid "" +#~ "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and " +#~ "%g seconds wall clock time including X server resources (%g milliseconds " +#~ "per frame)\n" +#~ msgstr "" +#~ "Dibujó %d marcos en %g segundos del lado del cliente (%g milisegundos por " +#~ "marco) y %g segundos de tiempo estándar incluyendo recursos del servidor " +#~ "X (%g milisegundos por marco)\n" -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "Tipografía de título pequeña" +#~ msgid "position expression test returned TRUE but set error" +#~ msgstr "" +#~ "prueba de expresión de la posición devolvió TRUE pero estableció un error" -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "Tipografía de título grande" +#~ msgid "position expression test returned FALSE but didn't set error" +#~ msgstr "" +#~ "prueba de expresión de la posición devolvió FASE pero no estableció un " +#~ "error" -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "Distribución de botones" +#~ msgid "Error was expected but none given" +#~ msgstr "Se esperaba un error, pero no se dio ninguno" -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "Banco de pruebas" +#~ msgid "Error %d was expected but %d given" +#~ msgstr "Se esperaba el error %d pero se dio el %d" -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "El título de la ventana va aquí" +#~ msgid "Error not expected but one was returned: %s" +#~ msgstr "No se esperaba un error pero se devolvió uno: %s" -#: ../src/ui/theme-viewer.c:1047 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"Dibujó %d marcos en %g segundos del lado del cliente (%g milisegundos por " -"marco) y %g segundos de tiempo estándar incluyendo recursos del servidor X (%" -"g milisegundos por marco)\n" +#~ msgid "x value was %d, %d was expected" +#~ msgstr "el valor x era %d, se esperaba %d" -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "" -"prueba de expresión de la posición devolvió TRUE pero estableció un error" +#~ msgid "y value was %d, %d was expected" +#~ msgstr "el valor y era %d, se esperaba %d" -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "" -"prueba de expresión de la posición devolvió FASE pero no estableció un error" +#~ msgid "" +#~ "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" +#~ msgstr "" +#~ "%d expresiones de coordenadas interpretadas en %g segundos (%g segundos " +#~ "de media)\n" -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "Se esperaba un error, pero no se dio ninguno" +#~ msgid "Minimize window" +#~ msgstr "Minimizar la ventana" -#: ../src/ui/theme-viewer.c:1274 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "Se esperaba el error %d pero se dio el %d" +#~ msgid "Comma-separated list of compositor plugins" +#~ msgstr "Lista de complementos del compositor separados por comas" -#: ../src/ui/theme-viewer.c:1280 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "No se esperaba un error pero se devolvió uno: %s" +#~ msgid "Live Hidden Windows" +#~ msgstr "Ventanas activas ocultas" -#: ../src/ui/theme-viewer.c:1284 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "el valor x era %d, se esperaba %d" +#~ msgid "" +#~ "Determines whether hidden windows (i.e., minimized windows and windows on " +#~ "other workspaces than the current one) should be kept alive." +#~ msgstr "" +#~ "Determina si las ventanas ocultas (e.g., ventanas minimizadas y ventanas " +#~ "en otros escritorios distintos del actual) deberían mantenerse activas." -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "el valor y era %d, se esperaba %d" +#~ msgid "Close Window" +#~ msgstr "Cerrar la ventana" -#: ../src/ui/theme-viewer.c:1352 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "" -"%d expresiones de coordenadas interpretadas en %g segundos (%g segundos de " -"media)\n" +#~ msgid "Window Menu" +#~ msgstr "Menú de la ventana" -#~ msgid "Switch to workspace 1" -#~ msgstr "Cambiar al área de trabajo 1" +#~ msgid "Minimize Window" +#~ msgstr "Minimizar la ventana" + +#~ msgid "Maximize Window" +#~ msgstr "Maximizar la ventana" + +#~ msgid "Restore Window" +#~ msgstr "Restablecer la ventana" -#~ msgid "Switch to workspace 2" -#~ msgstr "Cambiar al área de trabajo 2" +#~ msgid "Roll Up Window" +#~ msgstr "Enrollar ventana" -#~ msgid "Switch to workspace 3" -#~ msgstr "Cambiar al área de trabajo 3" +#~ msgid "Unroll Window" +#~ msgstr "Desenrollar ventana" -#~ msgid "Switch to workspace 4" -#~ msgstr "Cambiar al área de trabajo 4" +#~ msgid "Keep Window On Top" +#~ msgstr "Mantener la ventana encima" -#~ msgid "Switch to workspace 5" -#~ msgstr "Cambiar al área de trabajo 5" +#~ msgid "Remove Window From Top" +#~ msgstr "Quitar ventana de encima" -#~ msgid "Switch to workspace 6" -#~ msgstr "Cambiar al área de trabajo 6" +#~ msgid "Always On Visible Workspace" +#~ msgstr "Siempre en el área de trabajo visible" -#~ msgid "Switch to workspace 7" -#~ msgstr "Cambiar al área de trabajo 7" +#~ msgid "Put Window On Only One Workspace" +#~ msgstr "Poner la ventana sólo en un área de trabajo" #~ msgid "Switch to workspace 8" #~ msgstr "Cambiar al área de trabajo 8" @@ -1781,55 +1832,13 @@ msgstr "" #~ msgid "Run a terminal" #~ msgstr "Ejecutar en un terminal" -#~ msgid "Activate the window menu" -#~ msgstr "Activar el menú de la ventana" - -#~ msgid "Toggle fullscreen mode" -#~ msgstr "Cambiar a modo de pantalla completa" - -#~ msgid "Toggle maximization state" -#~ msgstr "Cambiar el estado de maximización" - #~ msgid "Toggle whether a window will always be visible over other windows" #~ msgstr "Conmutar si una ventana siempre se verá encima de otras ventanas" -#~ msgid "Maximize window" -#~ msgstr "Maximizar la ventana" - -#~ msgid "Restore window" -#~ msgstr "Restablecer la ventana" - -#~ msgid "Toggle shaded state" -#~ msgstr "Cambiar el estado de enrollado" - -#~ msgid "Minimize window" -#~ msgstr "Minimizar la ventana" - -#~ msgid "Close window" -#~ msgstr "Cerrar la ventana" - -#~ msgid "Move window" -#~ msgstr "Mover la ventana" - -#~ msgid "Resize window" -#~ msgstr "Redimensiona la ventana" - #~ msgid "Toggle whether window is on all workspaces or just one" #~ msgstr "" #~ "Conmutar si la ventana aparece en todas las áreas de trabajo o sólo en una" -#~ msgid "Move window to workspace 1" -#~ msgstr "Mover la ventana al área de trabajo 1" - -#~ msgid "Move window to workspace 2" -#~ msgstr "Mover la ventana al área de trabajo 2" - -#~ msgid "Move window to workspace 3" -#~ msgstr "Mover la ventana al área de trabajo 3" - -#~ msgid "Move window to workspace 4" -#~ msgstr "Mover la ventana al área de trabajo 4" - #~ msgid "Move window to workspace 5" #~ msgstr "Mover la ventana al área de trabajo 5" @@ -1854,35 +1863,11 @@ msgstr "" #~ msgid "Move window to workspace 12" #~ msgstr "Mover la ventana al área de trabajo 12" -#~ msgid "Move window one workspace to the left" -#~ msgstr "Mover la ventana un área de trabajo a la izquierda" - -#~ msgid "Move window one workspace to the right" -#~ msgstr "Mover la ventana un área de trabajo a la derecha" - -#~ msgid "Move window one workspace up" -#~ msgstr "Subir la ventana un área de trabajo" - -#~ msgid "Move window one workspace down" -#~ msgstr "Bajar la ventana un área de trabajo" - #~ msgid "Raise window if it's covered by another window, otherwise lower it" #~ msgstr "" #~ "Levantar la ventana si está cubierta por otra ventana, minimizarla en " #~ "otro caso" -#~ msgid "Raise window above other windows" -#~ msgstr "Levanta la ventana por encima de otras ventanas" - -#~ msgid "Lower window below other windows" -#~ msgstr "Bajar la ventana por debajo de otras ventanas" - -#~ msgid "Maximize window vertically" -#~ msgstr "Maximizar la ventana verticalmente" - -#~ msgid "Maximize window horizontally" -#~ msgstr "Maximizar la ventana horizontalmente" - #~ msgid "Move window to north-west (top left) corner" #~ msgstr "Mover la ventana a la esquina noroeste (arriba a la izquierda)" @@ -1937,21 +1922,21 @@ msgstr "" #~ msgid "GConf key %s is already in use and can't be used to override %s\n" #~ msgstr "" -#~ "La clave de GConf %s ya está en uso y no se puede usar para sobreescribir " +#~ "La clave de GConf %s ya está en uso y no se puede usar para sobrescribir " #~ "%s\n" #~ msgid "Can't override GConf key, %s not found\n" -#~ msgstr "No se puede sobreescribir la clave de GConf, no se encontró %s\n" +#~ msgstr "No se puede sobrescribir la clave de GConf, no se encontró %s\n" #~ msgid "Error setting number of workspaces to %d: %s\n" #~ msgstr "" -#~ "Ocurrió un error configurando la número de espacios de trabajo para %d: %" -#~ "s\n" +#~ "Ocurrió un error configurando la número de espacios de trabajo para %d: " +#~ "%s\n" #~ msgid "Error setting name for workspace %d to \"%s\": %s\n" #~ msgstr "" -#~ "Ocurrió un error al establecer el nombre del área de trabajo %d como «%s»: " -#~ "%s \n" +#~ "Ocurrió un error al establecer el nombre del área de trabajo %d como " +#~ "«%s»: %s \n" #~ msgid "Error setting live hidden windows status status: %s\n" #~ msgstr "Error al establecer el estado de vida de las ventanas ocultas: %s\n" @@ -1983,12 +1968,10 @@ msgstr "" #~ msgid "Error setting clutter plugin list: %s\n" #~ msgstr "Error al establecer la lista de complementos de «Clutter»: %s\n" -#~ msgid "Clutter Plugins" -#~ msgstr "Complementos de «Clutter»" - #~ msgid "Plugins to load for the Clutter-based compositing manager." #~ msgstr "" -#~ "Complementos que cargar para la gestión de composición basada en «Clutter»." +#~ "Complementos que cargar para la gestión de composición basada en " +#~ "«Clutter»." #~ msgid "Turn compositing on" #~ msgstr "Activar la composición" @@ -2096,7 +2079,8 @@ msgstr "" #~ "combinación de teclas para esta acción.\n" #~ "\n" #~ "Esta combinación de teclas puede invertirse manteniendo pulsada la tecla " -#~ "«Mayús»; por ello «Mayús» no puede ser una de las teclas de la combinación." +#~ "«Mayús»; por ello «Mayús» no puede ser una de las teclas de la " +#~ "combinación." #~ msgid "" #~ "Error launching metacity-dialog to warn about apps that don't support " @@ -2177,9 +2161,6 @@ msgstr "" #~ msgid "Commands to run in response to keybindings" #~ msgstr "Comandos a ejecutar en respuesta a combinaciones de teclas" -#~ msgid "Compositing Manager" -#~ msgstr "Gestor de composición" - #~ msgid "Control how new windows get focus" #~ msgstr "Controla cómo obtienen el foco las ventanas nuevas" @@ -2197,9 +2178,9 @@ msgstr "" #~ "'beeps'; may be used in conjunction with 'visual bell' to allow silent " #~ "'beeps'." #~ msgstr "" -#~ "Determina si las aplicaciones o el sistema pueden generar «bips» audibles; " -#~ "podría usarse en conjunto con «la campana visual» para permitir «bips» " -#~ "silenciosos." +#~ "Determina si las aplicaciones o el sistema pueden generar «bips» " +#~ "audibles; podría usarse en conjunto con «la campana visual» para permitir " +#~ "«bips» silenciosos." #~ msgid "Disable misfeatures that are required by old or broken applications" #~ msgstr "" @@ -2209,18 +2190,6 @@ msgstr "" #~ msgid "Enable Visual Bell" #~ msgstr "Activar la campana visual" -#~ msgid "" -#~ "If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " -#~ "the focused window will be automatically raised after a delay specified " -#~ "by the auto_raise_delay key. This is not related to clicking on a window " -#~ "to raise it, nor to entering a window during drag-and-drop." -#~ msgstr "" -#~ "Si está establecido a «true» y el modo del foco es «sloppy» o «mouse» " -#~ "entonces la ventana con el foco será elevada automáticamente tras un " -#~ "retardo especificado en la clave auto_raise_delay. Esto no está " -#~ "relacionado con pulsar en una ventana para elevarla, no con entrar en una " -#~ "ventana durante una operación de arrastrar y soltar." - #~ msgid "" #~ "If true, ignore the titlebar_font option, and use the standard " #~ "application font for window titles." @@ -2235,13 +2204,13 @@ msgstr "" #~ "working, and may also be a useful tradeoff for terminal servers. However, " #~ "the wireframe feature is disabled when accessibility is on." #~ msgstr "" -#~ "Si es «true», metacity dará al usuario menos información y menos sensación " -#~ "de «manipulación directa», usando marcos de alambre, evitando animaciones, " -#~ "u otros medios. Esto es una reducción significante en usabilidad para " -#~ "muchos usuarios, pero puede permitir funcionar a las aplicaciones " -#~ "heredadas y servidores de terminal cuando de otra forma sería " -#~ "impracticable. Sin embargo, la característica de marcos de alambre se " -#~ "desactiva cuando la accesibilidad está activada." +#~ "Si es «true», metacity dará al usuario menos información y menos " +#~ "sensación de «manipulación directa», usando marcos de alambre, evitando " +#~ "animaciones, u otros medios. Esto es una reducción significante en " +#~ "usabilidad para muchos usuarios, pero puede permitir funcionar a las " +#~ "aplicaciones heredadas y servidores de terminal cuando de otra forma " +#~ "sería impracticable. Sin embargo, la característica de marcos de alambre " +#~ "se desactiva cuando la accesibilidad está activada." #~ msgid "" #~ "If true, then Metacity works in terms of applications rather than " @@ -2289,8 +2258,8 @@ msgstr "" #~ msgstr "" #~ "Establezca esto a «verdadero» para redimensionar con el botón derecho y " #~ "mostrar un menú con el botón del medio mientras se mantiene pulsada la " -#~ "tecla dada en \"mouse_button_modifier\"; establézcalo a «falso» para hacer " -#~ "que se comporte de forma contraria." +#~ "tecla dada en \"mouse_button_modifier\"; establézcalo a «falso» para " +#~ "hacer que se comporte de forma contraria." #~ msgid "" #~ "Setting this option to false can lead to buggy behavior, so users are " @@ -2312,8 +2281,8 @@ msgstr "" #~ "for breaking their window manager and that they need to change this " #~ "option back to true or live with the \"bug\" they requested." #~ msgstr "" -#~ "Ajustar esta opción a «false» puede llevar a un comportamiento erróneo, de " -#~ "tal forma que se recomienda encarecidamente a los usuarios que no la " +#~ "Ajustar esta opción a «false» puede llevar a un comportamiento erróneo, " +#~ "de tal forma que se recomienda encarecidamente a los usuarios que no la " #~ "cambien del valor «true». Muchas acciones (ej. pulsar en el área del " #~ "cliente, mover o redimensionar la ventana) generalmente levantan la " #~ "ventana como efecto colateral. Ajustar este valor a «false», algo que se " @@ -2462,8 +2431,8 @@ msgstr "" #~ "Esta opción determina los efectos de la pulsación doble en la barra de " #~ "títulos. Las opciones válidas actualmente son «toggle_shade», que enrolla/" #~ "desenrolla la ventana, «toggle_maximized» que maximiza/desmaximiza la " -#~ "ventana, «toggle_maximize_horizontally» y «toggle_maximize_vertically» que " -#~ "maximiza/desmaximiza la ventana sólo en esa dirección, «minimize» que " +#~ "ventana, «toggle_maximize_horizontally» y «toggle_maximize_vertically» " +#~ "que maximiza/desmaximiza la ventana sólo en esa dirección, «minimize» que " #~ "minimiza la ventana, «shade» que enrolla la ventana hacia arriba, «menu» " #~ "que muestra la ventana de menú, «lower» que pone la ventana detrás de " #~ "todas las demás y «none» que no hará nada." @@ -2523,8 +2492,8 @@ msgstr "" #~ "environments." #~ msgstr "" #~ "Activa una indicación visual cuando una aplicación o el sistema emite una " -#~ "«campanada» o un «bip» ; es muy útil para los ambientes ruidosos y para las " -#~ "personas con dificultades auditivas." +#~ "«campanada» o un «bip» ; es muy útil para los ambientes ruidosos y para " +#~ "las personas con dificultades auditivas." #~ msgid "Use standard system font in window titles" #~ msgstr "Usar tipografía estándar del sistema en los títulos de la ventana" @@ -2603,11 +2572,11 @@ msgstr "" #~ "will be no keybinding for this action." #~ msgstr "" #~ "La combinación de teclas que cambia al área de trabajo por encima de la " -#~ "actual. El formato se ve como «<Control>a» o «<Mayús><Alt>" -#~ "F1». El intérprete es bastante liberal y permite tanto mayúsculas como " -#~ "minúsculas además de abreviaturas como por ejemplo «<Ctl>» y «<" -#~ "Ctrl>». Si configura esta opción con la cadena especial «disabled» " -#~ "entonces no habrá combinación de teclas para esta acción." +#~ "actual. El formato se ve como «<Control>a» o «<Mayús><" +#~ "Alt>F1». El intérprete es bastante liberal y permite tanto mayúsculas " +#~ "como minúsculas además de abreviaturas como por ejemplo «<Ctl>» y " +#~ "«<Ctrl>». Si configura esta opción con la cadena especial " +#~ "«disabled» entonces no habrá combinación de teclas para esta acción." #~ msgid "" #~ "The keybinding that switches to the workspace below the current " @@ -2618,11 +2587,11 @@ msgstr "" #~ "will be no keybinding for this action." #~ msgstr "" #~ "La combinación de teclas que cambia al área de trabajo por debajo de la " -#~ "actual. El formato se ve como «<Control>a» o «<Mayús><Alt>" -#~ "F1». El intérprete es bastante liberal y permite tanto mayúsculas como " -#~ "minúsculas además de abreviaturas como por ejemplo «<Ctl>» y «<" -#~ "Ctrl>». Si configura esta opción con la cadena especial «disabled» " -#~ "entonces no habrá combinación de teclas para esta acción." +#~ "actual. El formato se ve como «<Control>a» o «<Mayús><" +#~ "Alt>F1». El intérprete es bastante liberal y permite tanto mayúsculas " +#~ "como minúsculas además de abreviaturas como por ejemplo «<Ctl>» y " +#~ "«<Ctrl>». Si configura esta opción con la cadena especial " +#~ "«disabled» entonces no habrá combinación de teclas para esta acción." #~ msgid "" #~ "The keybinding that switches to the workspace on the left of the current " @@ -2633,11 +2602,12 @@ msgstr "" #~ "will be no keybinding for this action." #~ msgstr "" #~ "La combinación de teclas que cambia al área de trabajo hacia la izquierda " -#~ "de la actual. El formato se ve como «<Control>a» o «<Mayús><" -#~ "Alt>F1». El intérprete es bastante liberal y permite tanto mayúsculas " -#~ "como minúsculas además de abreviaturas como por ejemplo «<Ctl>» y " -#~ "«<Ctrl>». Si configura esta opción con la cadena especial «disabled» " -#~ "entonces no habrá combinación de teclas para esta acción." +#~ "de la actual. El formato se ve como «<Control>a» o «<Mayús>" +#~ "<Alt>F1». El intérprete es bastante liberal y permite tanto " +#~ "mayúsculas como minúsculas además de abreviaturas como por ejemplo «<" +#~ "Ctl>» y «<Ctrl>». Si configura esta opción con la cadena " +#~ "especial «disabled» entonces no habrá combinación de teclas para esta " +#~ "acción." #~ msgid "" #~ "The keybinding that switches to the workspace on the right of the current " @@ -2648,11 +2618,12 @@ msgstr "" #~ "will be no keybinding for this action." #~ msgstr "" #~ "La combinación de teclas que cambia al área de trabajo hacia la derecha " -#~ "de la actual. El formato se ve como «<Control>a» o «<Mayús><" -#~ "Alt>F1». El intérprete es bastante liberal y permite tanto mayúsculas " -#~ "como minúsculas además de abreviaturas como por ejemplo «<Ctl>» y " -#~ "«<Ctrl>». Si configura esta opción con la cadena especial «disabled» " -#~ "entonces no habrá combinación de teclas para esta acción." +#~ "de la actual. El formato se ve como «<Control>a» o «<Mayús>" +#~ "<Alt>F1». El intérprete es bastante liberal y permite tanto " +#~ "mayúsculas como minúsculas además de abreviaturas como por ejemplo «<" +#~ "Ctl>» y «<Ctrl>». Si configura esta opción con la cadena " +#~ "especial «disabled» entonces no habrá combinación de teclas para esta " +#~ "acción." #~ msgid "" #~ "The keybinding that switches to workspace 1. The format looks like \"<" @@ -2663,10 +2634,10 @@ msgstr "" #~ "action." #~ msgstr "" #~ "La combinación de teclas que cambia al área de trabajo 1. El formato se " -#~ "ve como «<Control>a» o «<Mayús><Alt>F1». El intérprete es " -#~ "bastante liberal y permite tanto mayúsculas como minúsculas además de " -#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si configura " -#~ "esta opción con la cadena especial «disabled» entonces no habrá " +#~ "ve como «<Control>a» o «<Mayús><Alt>F1». El intérprete " +#~ "es bastante liberal y permite tanto mayúsculas como minúsculas además de " +#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si " +#~ "configura esta opción con la cadena especial «disabled» entonces no habrá " #~ "combinación de teclas para esta acción." #~ msgid "" @@ -2678,10 +2649,10 @@ msgstr "" #~ "action." #~ msgstr "" #~ "La combinación de teclas que cambia al área de trabajo 10. El formato se " -#~ "ve como «<Control>a» o «<Mayús><Alt>F1». El intérprete es " -#~ "bastante liberal y permite tanto mayúsculas como minúsculas además de " -#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si configura " -#~ "esta opción con la cadena especial «disabled» entonces no habrá " +#~ "ve como «<Control>a» o «<Mayús><Alt>F1». El intérprete " +#~ "es bastante liberal y permite tanto mayúsculas como minúsculas además de " +#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si " +#~ "configura esta opción con la cadena especial «disabled» entonces no habrá " #~ "combinación de teclas para esta acción." #~ msgid "" @@ -2693,10 +2664,10 @@ msgstr "" #~ "action." #~ msgstr "" #~ "La combinación de teclas que cambia al área de trabajo 11. El formato se " -#~ "ve como «<Control>a» o «<Mayús><Alt>F1». El intérprete es " -#~ "bastante liberal y permite tanto mayúsculas como minúsculas además de " -#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si configura " -#~ "esta opción con la cadena especial «disabled» entonces no habrá " +#~ "ve como «<Control>a» o «<Mayús><Alt>F1». El intérprete " +#~ "es bastante liberal y permite tanto mayúsculas como minúsculas además de " +#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si " +#~ "configura esta opción con la cadena especial «disabled» entonces no habrá " #~ "combinación de teclas para esta acción." #~ msgid "" @@ -2708,10 +2679,10 @@ msgstr "" #~ "action." #~ msgstr "" #~ "La combinación de teclas que cambia al área de trabajo 12. El formato se " -#~ "ve como «<Control>a» o «<Mayús><Alt>F1». El intérprete es " -#~ "bastante liberal y permite tanto mayúsculas como minúsculas además de " -#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si configura " -#~ "esta opción con la cadena especial «disabled» entonces no habrá " +#~ "ve como «<Control>a» o «<Mayús><Alt>F1». El intérprete " +#~ "es bastante liberal y permite tanto mayúsculas como minúsculas además de " +#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si " +#~ "configura esta opción con la cadena especial «disabled» entonces no habrá " #~ "combinación de teclas para esta acción." #~ msgid "" @@ -2723,10 +2694,10 @@ msgstr "" #~ "action." #~ msgstr "" #~ "La combinación de teclas que cambia al área de trabajo 2. El formato se " -#~ "ve como «<Control>a» o «<Mayús><Alt>F1». El intérprete es " -#~ "bastante liberal y permite tanto mayúsculas como minúsculas además de " -#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si configura " -#~ "esta opción con la cadena especial «disabled» entonces no habrá " +#~ "ve como «<Control>a» o «<Mayús><Alt>F1». El intérprete " +#~ "es bastante liberal y permite tanto mayúsculas como minúsculas además de " +#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si " +#~ "configura esta opción con la cadena especial «disabled» entonces no habrá " #~ "combinación de teclas para esta acción." #~ msgid "" @@ -2738,10 +2709,10 @@ msgstr "" #~ "action." #~ msgstr "" #~ "La combinación de teclas que cambia al área de trabajo 3. El formato se " -#~ "ve como «<Control>a» o «<Mayús><Alt>F1». El intérprete es " -#~ "bastante liberal y permite tanto mayúsculas como minúsculas además de " -#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si configura " -#~ "esta opción con la cadena especial «disabled» entonces no habrá " +#~ "ve como «<Control>a» o «<Mayús><Alt>F1». El intérprete " +#~ "es bastante liberal y permite tanto mayúsculas como minúsculas además de " +#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si " +#~ "configura esta opción con la cadena especial «disabled» entonces no habrá " #~ "combinación de teclas para esta acción." #~ msgid "" @@ -2755,8 +2726,8 @@ msgstr "" #~ "La combinación de teclas que cambia al área de trabajo 4. El formato se " #~ "ve como «<Control>a» o «<Mayús><Alt>F1». El intérprete " #~ "es bastante liberal y permite tanto mayúsculas como minúsculas además de " -#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si configura " -#~ "esta opción con la cadena especial «disabled» entonces no habrá " +#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si " +#~ "configura esta opción con la cadena especial «disabled» entonces no habrá " #~ "combinación de teclas para esta acción." #~ msgid "" @@ -2770,8 +2741,8 @@ msgstr "" #~ "La combinación de teclas que cambia al área de trabajo 5. El formato se " #~ "ve como «<Control>a» o «<Mayús><Alt>F1». El intérprete " #~ "es bastante liberal y permite tanto mayúsculas como minúsculas además de " -#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si configura " -#~ "esta opción con la cadena especial «disabled» entonces no habrá " +#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si " +#~ "configura esta opción con la cadena especial «disabled» entonces no habrá " #~ "combinación de teclas para esta acción." #~ msgid "" @@ -2785,8 +2756,8 @@ msgstr "" #~ "La combinación de teclas que cambia al área de trabajo 6. El formato se " #~ "ve como «<Control>a» o «<Mayús><Alt>F1». El intérprete " #~ "es bastante liberal y permite tanto mayúsculas como minúsculas además de " -#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si configura " -#~ "esta opción con la cadena especial «disabled» entonces no habrá " +#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si " +#~ "configura esta opción con la cadena especial «disabled» entonces no habrá " #~ "combinación de teclas para esta acción." #~ msgid "" @@ -2800,8 +2771,8 @@ msgstr "" #~ "La combinación de teclas que cambia al área de trabajo 7. El formato se " #~ "ve como «<Control>a» o «<Mayús><Alt>F1». El intérprete " #~ "es bastante liberal y permite tanto mayúsculas como minúsculas además de " -#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si configura " -#~ "esta opción con la cadena especial «disabled» entonces no habrá " +#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si " +#~ "configura esta opción con la cadena especial «disabled» entonces no habrá " #~ "combinación de teclas para esta acción." #~ msgid "" @@ -2815,8 +2786,8 @@ msgstr "" #~ "La combinación de teclas que cambia al área de trabajo 8. El formato se " #~ "ve como «<Control>a» o «<Mayús><Alt>F1». El intérprete " #~ "es bastante liberal y permite tanto mayúsculas como minúsculas además de " -#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si configura " -#~ "esta opción con la cadena especial «disabled» entonces no habrá " +#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si " +#~ "configura esta opción con la cadena especial «disabled» entonces no habrá " #~ "combinación de teclas para esta acción." #~ msgid "" @@ -2830,8 +2801,8 @@ msgstr "" #~ "La combinación de teclas que cambia al área de trabajo 9. El formato se " #~ "ve como «<Control>a» o «<Mayús><Alt>F1». El intérprete " #~ "es bastante liberal y permite tanto mayúsculas como minúsculas además de " -#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si configura " -#~ "esta opción con la cadena especial «disabled» entonces no habrá " +#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si " +#~ "configura esta opción con la cadena especial «disabled» entonces no habrá " #~ "combinación de teclas para esta acción." #~ msgid "" @@ -2877,8 +2848,8 @@ msgstr "" #~ "poder redimensionar una ventana utilizando el teclado. El formato se ve " #~ "como «<Control>a» o «<Mayús><Alt>F1». El analizador es " #~ "bastante liberal y permite tanto mayúsculas como minúsculas además de " -#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si configura " -#~ "esta opción con la cadena especial «disabled» entonces no habrá " +#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si " +#~ "configura esta opción con la cadena especial «disabled» entonces no habrá " #~ "combinación de teclas para esta acción." #~ msgid "" @@ -2906,10 +2877,10 @@ msgstr "" #~ "action." #~ msgstr "" #~ "La combinación de teclas usada para maximizar una ventana. El formato se " -#~ "ve como «<Control>a» o «<Mayús><Alt>F1». El analizador es " -#~ "bastante liberal y permite tanto mayúsculas como minúsculas además de " -#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si configura " -#~ "esta opción con la cadena especial «disabled» entonces no habrá " +#~ "ve como «<Control>a» o «<Mayús><Alt>F1». El analizador " +#~ "es bastante liberal y permite tanto mayúsculas como minúsculas además de " +#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si " +#~ "configura esta opción con la cadena especial «disabled» entonces no habrá " #~ "combinación de teclas para esta acción." #~ msgid "" @@ -2921,10 +2892,10 @@ msgstr "" #~ "action." #~ msgstr "" #~ "La combinación de teclas usada para minimizar una ventana. El formato se " -#~ "ve como «<Control>a» o «<Mayús><Alt>F1». El analizador es " -#~ "bastante liberal y permite tanto mayúsculas como minúsculas además de " -#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si configura " -#~ "esta opción con la cadena especial «disabled» entonces no habrá " +#~ "ve como «<Control>a» o «<Mayús><Alt>F1». El analizador " +#~ "es bastante liberal y permite tanto mayúsculas como minúsculas además de " +#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si " +#~ "configura esta opción con la cadena especial «disabled» entonces no habrá " #~ "combinación de teclas para esta acción." #~ msgid "" @@ -2939,8 +2910,8 @@ msgstr "" #~ "hacia abajo. El formato se ve como «<Control>a» o «<Mayús><" #~ "Alt>F1». El intérprete es bastante liberal y permite tanto mayúsculas " #~ "como minúsculas además de abreviaturas como por ejemplo «<Ctl>» y " -#~ "«<Ctrl>». Si configura esta opción con la cadena especial «disabled» " -#~ "entonces no habrá combinación de teclas para esta acción." +#~ "«<Ctrl>». Si configura esta opción con la cadena especial " +#~ "«disabled» entonces no habrá combinación de teclas para esta acción." #~ msgid "" #~ "The keybinding used to move a window one workspace to the left. The " @@ -2967,11 +2938,12 @@ msgstr "" #~ "keybinding for this action." #~ msgstr "" #~ "La combinación de teclas usada para mover una ventana un área de trabajo " -#~ "hacia la derecha. El formato se ve como «<Control>a» o «<Mayús>" -#~ "<Alt>F1». El intérprete es bastante liberal y permite tanto " -#~ "mayúsculas como minúsculas además de abreviaturas como por ejemplo «<" -#~ "Ctl>» y «<Ctrl>». Si configura esta opción con la cadena especial " -#~ "«disabled» entonces no habrá combinación de teclas para esta acción." +#~ "hacia la derecha. El formato se ve como «<Control>a» o «<" +#~ "Mayús><Alt>F1». El intérprete es bastante liberal y permite " +#~ "tanto mayúsculas como minúsculas además de abreviaturas como por ejemplo " +#~ "«<Ctl>» y «<Ctrl>». Si configura esta opción con la cadena " +#~ "especial «disabled» entonces no habrá combinación de teclas para esta " +#~ "acción." #~ msgid "" #~ "The keybinding used to move a window one workspace up. The format looks " @@ -2982,11 +2954,12 @@ msgstr "" #~ "this action." #~ msgstr "" #~ "La combinación de teclas usada para mover una ventana un área de trabajo " -#~ "hacia arriba. El formato se ve como «<Control>a» o «<Mayús><" -#~ "Alt>F1». El intérprete es bastante liberal y permite tanto mayúsculas " -#~ "como minúsculas además de abreviaturas como por ejemplo «<Ctl>» y " -#~ "«<Ctrl>». Si configura esta opción con la cadena especial «disabled» " -#~ "entonces no habrá combinación de teclas para esta acción." +#~ "hacia arriba. El formato se ve como «<Control>a» o «<Mayús>" +#~ "<Alt>F1». El intérprete es bastante liberal y permite tanto " +#~ "mayúsculas como minúsculas además de abreviaturas como por ejemplo «<" +#~ "Ctl>» y «<Ctrl>». Si configura esta opción con la cadena " +#~ "especial «disabled» entonces no habrá combinación de teclas para esta " +#~ "acción." #~ msgid "" #~ "The keybinding used to move a window to workspace 1. The format looks " @@ -3000,8 +2973,8 @@ msgstr "" #~ "trabajo 1. El formato se ve como «<Control>a» o «<Mayús><" #~ "Alt>F1». El intérprete es bastante liberal y permite tanto mayúsculas " #~ "como minúsculas además de abreviaturas como por ejemplo «<Ctl>» y " -#~ "«<Ctrl>». Si configura esta opción con la cadena especial «disabled» " -#~ "entonces no habrá combinación de teclas para esta acción." +#~ "«<Ctrl>». Si configura esta opción con la cadena especial " +#~ "«disabled» entonces no habrá combinación de teclas para esta acción." #~ msgid "" #~ "The keybinding used to move a window to workspace 10. The format looks " @@ -3015,8 +2988,8 @@ msgstr "" #~ "trabajo 10. El formato se ve como «<Control>a» o «<Mayús><" #~ "Alt>F1». El intérprete es bastante liberal y permite tanto mayúsculas " #~ "como minúsculas además de abreviaturas como por ejemplo «<Ctl>» y " -#~ "«<Ctrl>». Si configura esta opción con la cadena especial «disabled» " -#~ "entonces no habrá combinación de teclas para esta acción." +#~ "«<Ctrl>». Si configura esta opción con la cadena especial " +#~ "«disabled» entonces no habrá combinación de teclas para esta acción." #~ msgid "" #~ "The keybinding used to move a window to workspace 11. The format looks " @@ -3030,8 +3003,8 @@ msgstr "" #~ "trabajo 11. El formato se ve como «<Control>a» o «<Mayús><" #~ "Alt>F1». El intérprete es bastante liberal y permite tanto mayúsculas " #~ "como minúsculas además de abreviaturas como por ejemplo «<Ctl>» y " -#~ "«<Ctrl>». Si configura esta opción con la cadena especial «disabled» " -#~ "entonces no habrá combinación de teclas para esta acción." +#~ "«<Ctrl>». Si configura esta opción con la cadena especial " +#~ "«disabled» entonces no habrá combinación de teclas para esta acción." #~ msgid "" #~ "The keybinding used to move a window to workspace 12. The format looks " @@ -3045,8 +3018,8 @@ msgstr "" #~ "trabajo 12. El formato se ve como «<Control>a» o «<Mayús><" #~ "Alt>F1». El intérprete es bastante liberal y permite tanto mayúsculas " #~ "como minúsculas además de abreviaturas como por ejemplo «<Ctl>» y " -#~ "»<Ctrl>». Si configura esta opción con la cadena especial «disabled» " -#~ "entonces no habrá combinación de teclas para esta acción." +#~ "»<Ctrl>». Si configura esta opción con la cadena especial " +#~ "«disabled» entonces no habrá combinación de teclas para esta acción." #~ msgid "" #~ "The keybinding used to move a window to workspace 2. The format looks " @@ -3060,8 +3033,8 @@ msgstr "" #~ "trabajo 2. El formato se ve como «<Control>a» o «<Mayús><" #~ "Alt>F1». El intérprete es bastante liberal y permite tanto mayúsculas " #~ "como minúsculas además de abreviaturas como por ejemplo «<Ctl>» y " -#~ "»<Ctrl>». Si configura esta opción con la cadena especial «disabled» " -#~ "entonces no habrá combinación de teclas para esta acción." +#~ "»<Ctrl>». Si configura esta opción con la cadena especial " +#~ "«disabled» entonces no habrá combinación de teclas para esta acción." #~ msgid "" #~ "The keybinding used to move a window to workspace 3. The format looks " @@ -3075,8 +3048,8 @@ msgstr "" #~ "trabajo 3. El formato se ve como «<Control>a» o «<Mayús><" #~ "Alt>F1». El intérprete es bastante liberal y permite tanto mayúsculas " #~ "como minúsculas además de abreviaturas como por ejemplo «<Ctl>» y " -#~ "«<Ctrl>». Si configura esta opción con la cadena especial «disabled» " -#~ "entonces no habrá combinación de teclas para esta acción." +#~ "«<Ctrl>». Si configura esta opción con la cadena especial " +#~ "«disabled» entonces no habrá combinación de teclas para esta acción." #~ msgid "" #~ "The keybinding used to move a window to workspace 4. The format looks " @@ -3090,8 +3063,8 @@ msgstr "" #~ "trabajo 4. El formato se ve como «<Control>a» o «<Mayús><" #~ "Alt>F1». El intérprete es bastante liberal y permite tanto mayúsculas " #~ "como minúsculas además de abreviaturas como por ejemplo «<Ctl>» y " -#~ "«<Ctrl>». Si configura esta opción con la cadena especial «disabled» " -#~ "entonces no habrá combinación de teclas para esta acción." +#~ "«<Ctrl>». Si configura esta opción con la cadena especial " +#~ "«disabled» entonces no habrá combinación de teclas para esta acción." #~ msgid "" #~ "The keybinding used to move a window to workspace 5. The format looks " @@ -3105,8 +3078,8 @@ msgstr "" #~ "trabajo 5. El formato se ve como «<Control>a» o »<Mayús><" #~ "Alt>F1». El intérprete es bastante liberal y permite tanto mayúsculas " #~ "como minúsculas además de abreviaturas como por ejemplo «<Ctl>» y " -#~ "»<Ctrl>». Si configura esta opción con la cadena especial «disabled» " -#~ "entonces no habrá combinación de teclas para esta acción." +#~ "»<Ctrl>». Si configura esta opción con la cadena especial " +#~ "«disabled» entonces no habrá combinación de teclas para esta acción." #~ msgid "" #~ "The keybinding used to move a window to workspace 6. The format looks " @@ -3120,8 +3093,8 @@ msgstr "" #~ "trabajo 6. El formato se ve como «<Control>a» o »<Mayús><" #~ "Alt>F1». El intérprete es bastante liberal y permite tanto mayúsculas " #~ "como minúsculas además de abreviaturas como por ejemplo «<Ctl>» y " -#~ "»<Ctrl>». Si configura esta opción con la cadena especial «disabled» " -#~ "entonces no habrá combinación de teclas para esta acción." +#~ "»<Ctrl>». Si configura esta opción con la cadena especial " +#~ "«disabled» entonces no habrá combinación de teclas para esta acción." #~ msgid "" #~ "The keybinding used to move a window to workspace 7. The format looks " @@ -3135,8 +3108,8 @@ msgstr "" #~ "trabajo 7. El formato se ve como «<Control>a» o »<Mayús><" #~ "Alt>F1». El intérprete es bastante liberal y permite tanto mayúsculas " #~ "como minúsculas además de abreviaturas como por ejemplo «<Ctl>» y " -#~ "»<Ctrl>». Si configura esta opción con la cadena especial «disabled» " -#~ "entonces no habrá combinación de teclas para esta acción." +#~ "»<Ctrl>». Si configura esta opción con la cadena especial " +#~ "«disabled» entonces no habrá combinación de teclas para esta acción." #~ msgid "" #~ "The keybinding used to move a window to workspace 8. The format looks " @@ -3150,8 +3123,8 @@ msgstr "" #~ "trabajo 8. El formato se ve como «<Control>a» o »<Mayús><" #~ "Alt>F1». El intérprete es bastante liberal y permite tanto mayúsculas " #~ "como minúsculas además de abreviaturas como por ejemplo «<Ctl>» y " -#~ "»<Ctrl>». Si configura esta opción con la cadena especial «disabled» " -#~ "entonces no habrá combinación de teclas para esta acción." +#~ "»<Ctrl>». Si configura esta opción con la cadena especial " +#~ "«disabled» entonces no habrá combinación de teclas para esta acción." #~ msgid "" #~ "The keybinding used to move a window to workspace 9. The format looks " @@ -3165,8 +3138,8 @@ msgstr "" #~ "trabajo 9. El formato se ve como «<Control>a» o «<Mayús><" #~ "Alt>F1». El intérprete es bastante liberal y permite tanto mayúsculas " #~ "como minúsculas además de abreviaturas como por ejemplo «<Ctl>» y " -#~ "»<Ctrl>». Si configura esta opción con la cadena especial «disabled» " -#~ "entonces no habrá combinación de teclas para esta acción." +#~ "»<Ctrl>». Si configura esta opción con la cadena especial " +#~ "«disabled» entonces no habrá combinación de teclas para esta acción." #~ msgid "" #~ "The keybinding used to move focus backwards between panels and the " @@ -3213,11 +3186,12 @@ msgstr "" #~ "La combinación de teclas usada para retroceder el foco entre las ventanas " #~ "de una aplicación sin una ventana emergente. Manteniendo pulsada la tecla " #~ "«Mayús.» junto con esta combinación hace que la dirección vaya hacia " -#~ "adelante de nuevo. El formato se ve como «<Control>a» o «<Mayús>" -#~ "<Alt>F1». El analizador es bastante liberal y permite tanto " -#~ "mayúsculas como minúsculas además de abreviaturas como por ejemplo «<" -#~ "Ctl>» y «<Ctrl>». Si configura esta opción con la cadena especial " -#~ "«disabled» entonces no habrá combinación de teclas para esta acción." +#~ "adelante de nuevo. El formato se ve como «<Control>a» o «<" +#~ "Mayús><Alt>F1». El analizador es bastante liberal y permite " +#~ "tanto mayúsculas como minúsculas además de abreviaturas como por ejemplo " +#~ "«<Ctl>» y «<Ctrl>». Si configura esta opción con la cadena " +#~ "especial «disabled» entonces no habrá combinación de teclas para esta " +#~ "acción." #~ msgid "" #~ "The keybinding used to move focus backwards between windows of an " @@ -3231,12 +3205,13 @@ msgstr "" #~ msgstr "" #~ "La combinación de teclas usada para retroceder el foco entre las ventanas " #~ "de una aplicación, usando una ventana emergente. Manteniendo pulsada la " -#~ "tecla «Mayús.» junto con esta combinación hace que la dirección vaya hacia " -#~ "adelante de nuevo. El formato se ve como «<Control>a» o «<Mayús>" -#~ "<Alt>F1». El intérprete es bastante liberal y permite tanto " -#~ "mayúsculas como minúsculas además de abreviaturas como por ejemplo «<" -#~ "Ctl>» y «<Ctrl>». Si configura esta opción con la cadena especial " -#~ "«disabled» entonces no habrá combinación de teclas para esta acción." +#~ "tecla «Mayús.» junto con esta combinación hace que la dirección vaya " +#~ "hacia adelante de nuevo. El formato se ve como «<Control>a» o «<" +#~ "Mayús><Alt>F1». El intérprete es bastante liberal y permite " +#~ "tanto mayúsculas como minúsculas además de abreviaturas como por ejemplo " +#~ "«<Ctl>» y «<Ctrl>». Si configura esta opción con la cadena " +#~ "especial «disabled» entonces no habrá combinación de teclas para esta " +#~ "acción." #~ msgid "" #~ "The keybinding used to move focus backwards between windows without a " @@ -3252,9 +3227,9 @@ msgstr "" #~ "combinación hace que la dirección vaya hacia adelante de nuevo. El " #~ "formato se ve como «<Control>a» o «<Mayús><Alt>F1». El " #~ "analizador es bastante liberal y permite tanto mayúsculas como minúsculas " -#~ "además de abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si " -#~ "configura esta opción con la cadena especial «disabled» entonces no habrá " -#~ "combinación de teclas para esta acción." +#~ "además de abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». " +#~ "Si configura esta opción con la cadena especial «disabled» entonces no " +#~ "habrá combinación de teclas para esta acción." #~ msgid "" #~ "The keybinding used to move focus backwards between windows, using a " @@ -3322,8 +3297,8 @@ msgstr "" #~ "movimiento. El formato se ve como «<Control>a» o «<Mayús><" #~ "Alt>F1». El analizador es bastante liberal y permite tanto mayúsculas " #~ "como minúsculas además de abreviaturas como por ejemplo «<Ctl>» y " -#~ "«<Ctrl>». Si configura esta opción con la cadena especial «disabled» " -#~ "entonces no habrá combinación de teclas para esta acción." +#~ "«<Ctrl>». Si configura esta opción con la cadena especial " +#~ "«disabled» entonces no habrá combinación de teclas para esta acción." #~ msgid "" #~ "The keybinding used to move focus between windows of an application, " @@ -3340,8 +3315,8 @@ msgstr "" #~ "Alt>F6). El formato se ve como «<Control>a» o «<Mayús><" #~ "Alt>F1». El intérprete es bastante liberal y permite tanto mayúsculas " #~ "como minúsculas además de abreviaturas como por ejemplo «<Ctl>» y " -#~ "«<Ctrl>». Si configura esta opción con la cadena especial «disabled» " -#~ "entonces no habrá combinación de teclas para esta acción." +#~ "«<Ctrl>». Si configura esta opción con la cadena especial " +#~ "«disabled» entonces no habrá combinación de teclas para esta acción." #~ msgid "" #~ "The keybinding used to move focus between windows without a popup window. " @@ -3375,10 +3350,10 @@ msgstr "" #~ msgstr "" #~ "La combinación de teclas usada para mover el foco entre ventanas, usando " #~ "una ventana emergente. (Tradicionalmente <Alt>Tab). El formato se " -#~ "ve como «<Control>a» o «<Mayús><Alt>F1». El intérprete es " -#~ "bastante liberal y permite tanto mayúsculas como minúsculas además de " -#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si configura " -#~ "esta opción con la cadena especial «disabled» entonces no habrá " +#~ "ve como «<Control>a» o «<Mayús><Alt>F1». El intérprete " +#~ "es bastante liberal y permite tanto mayúsculas como minúsculas además de " +#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si " +#~ "configura esta opción con la cadena especial «disabled» entonces no habrá " #~ "combinación de teclas para esta acción." #~ msgid "" @@ -3391,10 +3366,10 @@ msgstr "" #~ "keybinding for this action." #~ msgstr "" #~ "La combinación de teclas usada para activar siempre encima. El formato se " -#~ "ve como «<Control>a» o «<Mayús><Alt>F1». El analizador es " -#~ "bastante liberal y permite tanto mayúsculas como minúsculas además de " -#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si configura " -#~ "esta opción con la cadena especial «disabled» entonces no habrá " +#~ "ve como «<Control>a» o «<Mayús><Alt>F1». El analizador " +#~ "es bastante liberal y permite tanto mayúsculas como minúsculas además de " +#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si " +#~ "configura esta opción con la cadena especial «disabled» entonces no habrá " #~ "combinación de teclas para esta acción." #~ msgid "" @@ -3406,11 +3381,11 @@ msgstr "" #~ "this action." #~ msgstr "" #~ "La combinación de teclas usada para activar el modo de pantalla completa. " -#~ "El formato se ve como «<Control>a» o «<Mayús><Alt>F1». El " -#~ "analizador es bastante liberal y permite tanto mayúsculas como minúsculas " -#~ "además de abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si " -#~ "configura esta opción con la cadena especial «disabled» entonces no habrá " -#~ "combinación de teclas para esta acción." +#~ "El formato se ve como «<Control>a» o «<Mayús><Alt>F1». " +#~ "El analizador es bastante liberal y permite tanto mayúsculas como " +#~ "minúsculas además de abreviaturas como por ejemplo «<Ctl>» y «<" +#~ "Ctrl>». Si configura esta opción con la cadena especial «disabled» " +#~ "entonces no habrá combinación de teclas para esta acción." #~ msgid "" #~ "The keybinding used to toggle maximization. The format looks like \"<" @@ -3423,8 +3398,8 @@ msgstr "" #~ "La combinación de teclas usada para maximizar la ventana. El formato se " #~ "ve como «<Control>a» o «<Mayús><Alt>F1». El intérprete " #~ "es bastante liberal y permite tanto mayúsculas como minúsculas además de " -#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si configura " -#~ "esta opción con la cadena especial «disabled» entonces no habrá " +#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si " +#~ "configura esta opción con la cadena especial «disabled» entonces no habrá " #~ "combinación de teclas para esta acción." #~ msgid "" @@ -3438,9 +3413,9 @@ msgstr "" #~ "La combinación de teclas usada para enrollar o desenrollar la ventana. El " #~ "formato se ve como «<Control>a» o «<Mayús><Alt>F1». El " #~ "intérprete es bastante liberal y permite tanto mayúsculas como minúsculas " -#~ "además de abreviaturas como por ejemplo «<Ctl>» y »<Ctrl>». Si " -#~ "configura esta opción con la cadena especial «disabled» entonces no habrá " -#~ "combinación de teclas para esta acción." +#~ "además de abreviaturas como por ejemplo «<Ctl>» y »<Ctrl>». " +#~ "Si configura esta opción con la cadena especial «disabled» entonces no " +#~ "habrá combinación de teclas para esta acción." #~ msgid "" #~ "The keybinding used to toggle whether the window is on all workspaces or " @@ -3485,8 +3460,8 @@ msgstr "" #~ "aplicación». El formato se ve como «<Control>a» o «<Mayús><" #~ "Alt>F1». El intérprete es bastante liberal y permite tanto mayúsculas " #~ "como minúsculas además de abreviaturas como por ejemplo «<Ctl>» y " -#~ "«<Ctrl>». Si configura esta opción con la cadena especial «disabled» " -#~ "entonces no habrá combinación de teclas para esta acción." +#~ "«<Ctrl>». Si configura esta opción con la cadena especial " +#~ "«disabled» entonces no habrá combinación de teclas para esta acción." #~ msgid "" #~ "The keybinding which invokes a terminal. The format looks like \"<" @@ -3531,8 +3506,8 @@ msgstr "" #~ "del panel. El formato se ve como «<Control>a» o «<Mayús><" #~ "Alt>F1». El intérprete es bastante liberal y permite tanto mayúsculas " #~ "como minúsculas además de abreviaturas como por ejemplo «<Ctl>» y " -#~ "«<Ctrl>». Si configura esta opción con la cadena especial «disabled» " -#~ "entonces no habrá combinación de teclas para esta acción." +#~ "«<Ctrl>». Si configura esta opción con la cadena especial " +#~ "«disabled» entonces no habrá combinación de teclas para esta acción." #~ msgid "" #~ "The keybinding which shows the panel's main menu. The format looks like " @@ -3566,8 +3541,8 @@ msgstr "" #~ "ventanas. El formato se ve como «<Control>a» o «<Mayús><" #~ "Alt>F1». El intérprete es bastante liberal y permite tanto mayúsculas " #~ "como minúsculas además de abreviaturas como por ejemplo «<Ctl>» y " -#~ "»<Ctrl>». Si configura esta opción con la cadena especial «disabled» " -#~ "entonces no habrá combinación de teclas para esta acción." +#~ "»<Ctrl>». Si configura esta opción con la cadena especial " +#~ "«disabled» entonces no habrá combinación de teclas para esta acción." #~ msgid "" #~ "This keybinding lowers a window below other windows. The format looks " @@ -3578,11 +3553,11 @@ msgstr "" #~ "this action." #~ msgstr "" #~ "Esta combinación de teclas coloca una ventana detrás de otras. El formato " -#~ "se ve como «<Control>a» o «<Mayús><Alt>F1». El analizador " -#~ "es bastante liberal y permite tanto mayúsculas como minúsculas además de " -#~ "abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si configura " -#~ "esta opción con la cadena especial «disabled» entonces no habrá " -#~ "combinación de teclas para esta acción." +#~ "se ve como «<Control>a» o «<Mayús><Alt>F1». El " +#~ "analizador es bastante liberal y permite tanto mayúsculas como minúsculas " +#~ "además de abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». " +#~ "Si configura esta opción con la cadena especial «disabled» entonces no " +#~ "habrá combinación de teclas para esta acción." #~ msgid "" #~ "This keybinding moves a window against the north (top) side of the " @@ -3596,23 +3571,23 @@ msgstr "" #~ "pantalla. El formato se ve como «<Control>a» o «<Mayús><" #~ "Alt>F1». El analizador es bastante liberal y permite tanto mayúsculas " #~ "como minúsculas además de abreviaturas como por ejemplo «<Ctl>» y " -#~ "«<Ctrl>». Si configura esta opción con la cadena especial «disabled» " -#~ "entonces no habrá combinación de teclas para esta acción." +#~ "«<Ctrl>». Si configura esta opción con la cadena especial " +#~ "«disabled» entonces no habrá combinación de teclas para esta acción." #~ msgid "" #~ "This keybinding moves a window into the east (right) side of the screen. " -#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -#~ "\". The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " +#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>" +#~ "F1\". The parser is fairly liberal and allows lower or upper case, and " +#~ "also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " +#~ "set the option to the special string \"disabled\", then there will be no " #~ "keybinding for this action." #~ msgstr "" #~ "Esta combinación de teclas coloca una ventana al este (derecha) de la " #~ "pantalla. El formato se ve como «<Control>a» o «<Mayús><" #~ "Alt>F1». El analizador es bastante liberal y permite tanto mayúsculas " #~ "como minúsculas además de abreviaturas como por ejemplo «<Ctl>» y " -#~ "«<Ctrl>». Si configura esta opción con la cadena especial «disabled» " -#~ "entonces no habrá combinación de teclas para esta acción." +#~ "«<Ctrl>». Si configura esta opción con la cadena especial " +#~ "«disabled» entonces no habrá combinación de teclas para esta acción." #~ msgid "" #~ "This keybinding moves a window into the north-east (top right) corner of " @@ -3658,8 +3633,8 @@ msgstr "" #~ "pantalla. El formato se ve como «<Control>a» o «<Mayús><" #~ "Alt>F1». El analizador es bastante liberal y permite tanto mayúsculas " #~ "como minúsculas además de abreviaturas como por ejemplo «<Ctl>» y " -#~ "«<Ctrl>». Si configura esta opción con la cadena especial «disabled» " -#~ "entonces no habrá combinación de teclas para esta acción." +#~ "«<Ctrl>». Si configura esta opción con la cadena especial " +#~ "«disabled» entonces no habrá combinación de teclas para esta acción." #~ msgid "" #~ "This keybinding moves a window into the south-east (bottom right) corner " @@ -3686,27 +3661,27 @@ msgstr "" #~ "then there will be no keybinding for this action." #~ msgstr "" #~ "Esta combinación de teclas mueve una ventana a la esquina suroeste (abajo " -#~ "a la izquierda) de la pantalla. El formato se ve como «<Control>a» o " -#~ "«<Mayús><Alt>F1». El analizador es bastante liberal y permite " -#~ "tanto mayúsculas como minúsculas además de abreviaturas como por ejemplo " -#~ "«<Ctl>» y «<Ctrl>». Si configura esta opción con la cadena " -#~ "especial «disabled» entonces no habrá combinación de teclas para esta " -#~ "acción." +#~ "a la izquierda) de la pantalla. El formato se ve como «<Control>a» " +#~ "o «<Mayús><Alt>F1». El analizador es bastante liberal y " +#~ "permite tanto mayúsculas como minúsculas además de abreviaturas como por " +#~ "ejemplo «<Ctl>» y «<Ctrl>». Si configura esta opción con la " +#~ "cadena especial «disabled» entonces no habrá combinación de teclas para " +#~ "esta acción." #~ msgid "" #~ "This keybinding moves a window into the west (left) side of the screen. " -#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -#~ "\". The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " +#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>" +#~ "F1\". The parser is fairly liberal and allows lower or upper case, and " +#~ "also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " +#~ "set the option to the special string \"disabled\", then there will be no " #~ "keybinding for this action." #~ msgstr "" #~ "Esta combinación de teclas mueve una ventana al lado oeste (izquierdo) de " #~ "la pantalla. El formato se ve como «<Control>a» o «<Mayús><" #~ "Alt>F1». El analizador es bastante liberal y permite tanto mayúsculas " #~ "como minúsculas además de abreviaturas como por ejemplo «<Ctl>» y " -#~ "«<Ctrl>». Si configura esta opción con la cadena especial «disabled» " -#~ "entonces no habrá combinación de teclas para esta acción." +#~ "«<Ctrl>». Si configura esta opción con la cadena especial " +#~ "«disabled» entonces no habrá combinación de teclas para esta acción." #~ msgid "" #~ "This keybinding raises the window above other windows. The format looks " @@ -3719,9 +3694,9 @@ msgstr "" #~ "Esta combinación de teclas eleva una ventana por encima de otras. El " #~ "formato se ve como «<Control>a» o «<Mayús><Alt>F1». El " #~ "analizador es bastante liberal y permite tanto mayúsculas como minúsculas " -#~ "además de abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». Si " -#~ "configura esta opción con la cadena especial «disabled» entonces no habrá " -#~ "combinación de teclas para esta acción." +#~ "además de abreviaturas como por ejemplo «<Ctl>» y «<Ctrl>». " +#~ "Si configura esta opción con la cadena especial «disabled» entonces no " +#~ "habrá combinación de teclas para esta acción." #~ msgid "" #~ "This keybinding resizes a window to fill available horizontal space. The " @@ -3732,8 +3707,8 @@ msgstr "" #~ "keybinding for this action." #~ msgstr "" #~ "Esta combinación de teclas redimensiona una ventana para que rellene todo " -#~ "el espacio horizontal disponible. El formato se ve como «<Control>a» " -#~ "o «<Mayús><Alt>F1». El intérprete es bastante liberal y " +#~ "el espacio horizontal disponible. El formato se ve como «<Control>" +#~ "a» o «<Mayús><Alt>F1». El intérprete es bastante liberal y " #~ "permite tanto mayúsculas como minúsculas además de abreviaturas como por " #~ "ejemplo «<Ctl>» y «<Ctrl>». Si configura esta opción con la " #~ "cadena especial «disabled» entonces no habrá combinación de teclas para " @@ -3748,12 +3723,12 @@ msgstr "" #~ "keybinding for this action." #~ msgstr "" #~ "Esta combinación de teclas redimensiona una ventana para que rellene todo " -#~ "el espacio vertical disponible. El formato se ve como «<Control>a» o " -#~ "»<Mayús><Alt>F1». El intérprete es bastante liberal y permite " -#~ "tanto mayúsculas como minúsculas además de abreviaturas como por ejemplo " -#~ "»<Ctl>» y «<Ctrl>». Si configura esta opción con la cadena " -#~ "especial «disabled» entonces no habrá combinación de teclas para esta " -#~ "acción." +#~ "el espacio vertical disponible. El formato se ve como «<Control>a» " +#~ "o »<Mayús><Alt>F1». El intérprete es bastante liberal y " +#~ "permite tanto mayúsculas como minúsculas además de abreviaturas como por " +#~ "ejemplo »<Ctl>» y «<Ctrl>». Si configura esta opción con la " +#~ "cadena especial «disabled» entonces no habrá combinación de teclas para " +#~ "esta acción." #~ msgid "Toggle always on top state" #~ msgstr "Cambiar el estado de siempre encima" diff --git a/po/et.po b/po/et.po index 16573410c..63d51cd0c 100644 --- a/po/et.po +++ b/po/et.po @@ -1,350 +1,292 @@ -# Akhahalduri 'Muffin' eesti tõlge. -# Estonian translation of Muffin. +# Akhahalduri 'Mutter' eesti tõlge. +# Estonian translation of Mutter. # # Copyright (C) 2004–2005 The Free Software Foundation # Copyright (C) 2007–2011 The GNOME Project. -# This file is distributed under the same license as the muffin package. +# This file is distributed under the same license as the mutter package. # # Tõivo Leedjärv <toivo linux ee>, 2004. # Ivar Smolin <okul linux ee>, 2005, 2006, 2009–2011. -# Mattias Põldaru <mahfiaz@gmail.com>, 2008–2011, 2012. +# Mattias Põldaru <mahfiaz@gmail.com>, 2008–2011, 2012, 2013. +# Mart Raudsepp <leio@gentoo.org>, 2018. # msgid "" msgstr "" -"Project-Id-Version: muffin MASTER\n" -"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" -"product=muffin&keywords=I18N+L10N&component=general\n" -"POT-Creation-Date: 2012-03-11 22:19+0000\n" -"PO-Revision-Date: 2012-03-12 00:47+0200\n" -"Last-Translator: Mattias Põldaru <mahfiaz@gmail.com>\n" +"Project-Id-Version: mutter MASTER\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2018-02-06 04:14+0000\n" +"PO-Revision-Date: 2018-03-12 19:27+0200\n" +"Last-Translator: Mart Raudsepp <leio@gentoo.org>\n" "Language-Team: Estonian <>\n" "Language: et\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Generator: Poedit 2.0.6\n" -msgid "Windows" -msgstr "Aknad" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Navigeerimine" -msgid "View split on left" -msgstr "Vaade poolitatakse vasakult" +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Akna liigutamine 1. tööalale" -msgid "View split on right" -msgstr "Vaade poolitatakse paremalt" +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Akna liigutamine 2. tööalale" -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#, c-format -msgid "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." -msgstr "Teine komposiithaldur juba töötab ekraani %i kuval \"%s\"." +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Akna liigutamine 3. tööalale" -msgid "Bell event" -msgstr "Helina sündmus" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Akna liigutamine 4. tööalale" -#, c-format -msgid "Unknown window information request: %d" -msgstr "Tundmatu aknateabe päring: %d" +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Akna liigutamine viimasele tööalale" -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> ei vasta." +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "Akna liigutamine ülemisele tööalale" -msgid "Application is not responding." -msgstr "Rakendus ei vasta." +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "Akna liigutamine alumisele tööalale" -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "Sa võid natukene selle järel oodata või sundida rakenduse lõpetama." +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "Akna liigutamine vasakpoolsele monitorile" -msgid "_Wait" -msgstr "_Oota" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "Akna liigutamine parempoolsele monitorile" -msgid "_Force Quit" -msgstr "_Sulge jõuga" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "Akna liigutamine ülemisele monitorile" -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "Puuduv laiendus %s on vajalik komposiitmontaaži jaoks" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "Akna liigutamine alumisele monitorile" -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Tõrge X Window System'i kuva '%s' avamisel\n" +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "Rakenduste vahetamine" -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "" -"Mõni teine programm juba kasutab klahvi %s koos muuteklahvidega %x " -"kiirklahvina\n" +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "Eelmisele rakendusele vahetamine" -msgid "Disable connection to session manager" -msgstr "Seansihalduriga ühendumise keelamine" +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "Akende vahetamine" -msgid "Replace the running window manager" -msgstr "Töötava aknahalduri asendamine" +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "Eelmisele aknale vahetamine" -msgid "Specify session management ID" -msgstr "Seansihalduse ID kirjeldamine" +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "Rakenduse akende vahetamine" -msgid "X Display to use" -msgstr "X-kuva, mida kasutada" +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "Rakenduse eelmisele aknale vahetamine" -msgid "Initialize session from savefile" -msgstr "Seansi lähtestamine salvestatud failist" +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "Süsteemi juhtalade vahetamine" -msgid "Make X calls synchronous" -msgstr "Tee X-väljakutsed sünkroonseks" +#: data/50-mutter-navigation.xml:75 +#, fuzzy +#| msgid "Switch system controls" +msgid "Switch to previous system control" +msgstr "Süsteemi juhtalade vahetamine" -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Tõrge teemadekataloogi skannimisel: %s\n" +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "Akende kohene vahetamine" -#, c-format -msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" msgstr "" -"Teemat ei leitud! Veendu, et %s on olemas ja sisaldab harilikke teemasid.\n" -#, c-format -msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" -"muffin %s\n" -"Autoriõigused (C) 2001-%d Havoc Pennington, Red Hat, Inc., ja teised\n" -"See programm on vaba tarkvara; kopeerimistingimuste kohta vaata\n" -"programmi lähteteksti. Sellel programmil pole MINGISUGUST GARANTIID;\n" -"isegi MITTE KOMMERTSGARANTIID EGA GARANTIID SOBIVUSELE\n" -"TEATUD KINDLAKS EESMÄRGIKS.\n" +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "Rakenduse akende kohene vahetamine" -msgid "Print version" -msgstr "Versiooni printimine" +#: data/50-mutter-navigation.xml:93 +#, fuzzy +#| msgid "Switch windows of an application" +msgid "Switch directly to previous window of an app" +msgstr "Rakenduse akende vahetamine" -msgid "Comma-separated list of compositor plugins" -msgstr "Komaga eraldatud nimekiri komposiitmontaaži pluginatest" +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "Süsteemi juhtalade kohene vahetamine" -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"Ümbernurga parandused vigastele rakendustele on keelatud. Mõned rakendused " -"ei pruugi õigesti käituda.\n" - -#, c-format -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "Fondi kirjeldust \"%s\" GSettings võtmest %s pole võimalik töödelda\n" - -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"Seadistuste andmebaasist leitud \"%s\" ei ole sobiv väärtus hiireklahvi " -"modifikaatoriks\n" +#: data/50-mutter-navigation.xml:102 +#, fuzzy +#| msgid "Switch system controls" +msgid "Switch directly to previous system control" +msgstr "Süsteemi juhtalade vahetamine" -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "" -"Seadistuste andmebaasist leitud \"%s\" ei ole sobiv väärtus kiirklahvile \"%s" -"\"\n" - -#, c-format -msgid "Workspace %d" -msgstr "Tööala %d" +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "Kõigi tavaliste akende peitmine" -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "Ekraan %d kuval '%s' on vigane\n" +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "1. tööalale liikumine" -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"Ekraan %d kuval '%s' on juba aknahalduri poolt hallatav. Olemasoleva " -"aknahalduri asendamiseks proovi --replace võtit \n" +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "2. tööalale liikumine" -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "Aknahalduri valikut ei saa hankida ekraani %d kuval \"%s\"\n" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "3. tööalale liikumine" -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "Ekraan %d kuval '%s' on juba aknahalduri poolt hallatav\n" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "4. tööalale liikumine" -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "Ekraani %d kuval \"%s\" ei saa vabastada\n" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "Viimasele tööalale liikumine" -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Kataloogi '%s' pole võimalik luua: %s\n" +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "Ülemisele tööalale liikumine" -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "Seansifaili '%s' pole võimalik kirjutamiseks avada: %s\n" +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "Alumisele tööalale liikumine" -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Viga seansifaili '%s' kirjutamisel: %s\n" +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "Süsteem" -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Viga seansifaili '%s' sulgemisel: %s\n" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Käsuviiba kuvamine" -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Viga salvestatud seansifaili analüüsimisel: %s\n" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Tegevuste ülevaate avamine" -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "Nähti <muffin_session> atribuuti, aga sessiooni ID on juba määratud" +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "" -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Tundmatu atribuut %s <%s> elemendil" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Aknad" -#, c-format -msgid "nested <window> tag" -msgstr "pesastatud <window>" +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "Aknamenüü avamine" -#, c-format -msgid "Unknown element %s" -msgstr "Tundmatu element %s" +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Täisekraanoleku vahetamine" -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" -"Need aknad ei toeta "praeguse paigutuse salvestamist" ja tuleb " -"järgmisel sisselogimisel käsitsi taaskäivitada." +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "Maksimeeritud oleku vahetamine" -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Tõrge silumislogi avamisel: %s\n" +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "Akna maksimeerimine" -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Tõrge logifaili %s avamisel funktsiooniga fdopen(): %s\n" +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Akna taastamine" -#, c-format -msgid "Opened log file %s\n" -msgstr "Avati logifail %s\n" +#: data/50-mutter-windows.xml:18 +msgid "Close window" +msgstr "Akna sulgemine" -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "Muffin kompileeriti ilma jutuka režiimi toeta\n" +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "Peida aken" -msgid "Window manager: " -msgstr "Aknahaldur: " +#: data/50-mutter-windows.xml:22 +msgid "Move window" +msgstr "Akna liigutamine" -msgid "Bug in window manager: " -msgstr "Viga aknahalduris: " +#: data/50-mutter-windows.xml:24 +msgid "Resize window" +msgstr "Akna suuruse muutmine" -msgid "Window manager warning: " -msgstr "Aknahalduri hoiatus: " +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "Akna kõigil või ühel tööalal olemise vahetamine" -msgid "Window manager error: " -msgstr "Aknahalduri viga: " +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "Akna tõstmine, kui see on kaetud, muul juhul langetamine" -#. first time through -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"Aken %s määrab SM_CLIENT_ID endale, selle asemel et määrata see " -"WM_CLIENT_LEADER aknale, nagu seda kirjeldab ICCCM.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size " -"%d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"Aken %s määrab MWM vihje, näidates, et see pole muudetava suurusega, aga " -"määrab vähimaks suuruseks %d x %d ja suurimaks suuruseks %d x %d; sel pole " -"tähendust.\n" +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "Akna tõstmine teiste kohale" -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "Rakendus määras võltsitud _NET_WM_PID %lu\n" +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "Akna langetamine teiste taha" -#, c-format -msgid "%s (on %s)" -msgstr "%s (masinas %s)" +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "Akna vertikaalne maksimeerimine" -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "Vigane WM_TRANSIENT_FOR aknale 0x%lx määratud %s jaoks.\n" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "Akna horisontaalne maksimeerimine" -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "" -"WM_TRANSIENT_FOR aknale 0x%lx määratud %s jaoks tekitaks tsüklilise " -"korduse.\n" - -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"Aknal 0x%lx on omadus %s,\n" -"mis oleks pidanud olema %s tüüpi %d vormingus,\n" -"aga tegelikult oli %s tüüpi %d vormingus n_items %d.\n" -"See on kõige tõenäolisemalt rakenduse, mitte aknahalduri viga.\n" -"Aknal on title=\"%s\" class=\"%s\" name=\"%s\"\n" - -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "Omadus %s aknal 0x%lx sisaldab vigast UTF-8\n" +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "Vaade poolitatakse vasakult" -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "Omadus %s aknal 0x%lx sisaldab vigast UTF-8 %d kirjele nimekirjas\n" +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "Vaade poolitatakse paremalt" -msgid "Muffin" -msgstr "Muffin" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" +#: data/org.gnome.mutter.gschema.xml.in:7 msgid "Modifier to use for extended window management operations" msgstr "Laiendatud aknaoperatsioonide korral kasutatav muuteklahv" # millalgi võiks selle kohta vearaporti kirjutada +#: data/org.gnome.mutter.gschema.xml.in:8 +#, fuzzy +#| msgid "" +#| "This key will initiate the \"overlay\", which is a combination window " +#| "overview and application launching system. The default is intended to be " +#| "the \"Windows key\" on PC hardware. It's expected that this binding " +#| "either the default or set to the empty string." msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." msgstr "" "See klahv näitab \"pealiskihti\", milles on koos akende ülevaade ja " "rakenduste käivitamise süsteem. PC-arvutitel on see vaikimisi \"Windowsi " "klahv\". Eeldatavasti määratakse selle seose väärtuseks vaikimisi või tühi " "sõne." +#: data/org.gnome.mutter.gschema.xml.in:20 msgid "Attach modal dialogs" msgstr "Modaaldialoogide kinnistamine" +#: data/org.gnome.mutter.gschema.xml.in:21 msgid "" "When true, instead of having independent titlebars, modal dialogs appear " "attached to the titlebar of the parent window and are moved together with " @@ -353,19 +295,11 @@ msgstr "" "Kui märgitud, siis eraldi tiitliribade asemel on moodaalsed dialoogid " "emaakna tiitliribade küljes ning liiguvad koos emaaknaga." -msgid "Live Hidden Windows" -msgstr "Varjatud akende aktiivsus" - -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"Määrab, kas varjatud aknaid (nt minimeeritud ja teistel tööaladel aknad) " -"hoitakse elus." - +#: data/org.gnome.mutter.gschema.xml.in:30 msgid "Enable edge tiling when dropping windows on screen edges" msgstr "Akna ümberpaigutamine selle lohistamisel ekraani serva" +#: data/org.gnome.mutter.gschema.xml.in:31 msgid "" "If enabled, dropping windows on vertical screen edges maximizes them " "vertically and resizes them horizontally to cover half of the available " @@ -375,20 +309,24 @@ msgstr "" "vertikaalselt ja laius katab pool saadaolevast laiusest. Akna lohistamine " "ekraani ülaserva maksimeerib akna täielikult." +#: data/org.gnome.mutter.gschema.xml.in:40 msgid "Workspaces are managed dynamically" msgstr "Tööalade dünaamiline haldus" +#: data/org.gnome.mutter.gschema.xml.in:41 msgid "" -"Determines whether workspaces are managed dynamically or whether there's a " +"Determines whether workspaces are managed dynamically or whether there’s a " "static number of workspaces (determined by the num-workspaces key in org." "gnome.desktop.wm.preferences)." msgstr "" "Määrab, kas tööalasid hallatakse dünaamiliselt või on nende arv staatiline " -"(arvu määrab org.cinnamon.desktop.wm.preferences all võti num-workspaces)." +"(arvu määrab org.gnome.desktop.wm.preferences all võti num-workspaces)." +#: data/org.gnome.mutter.gschema.xml.in:50 msgid "Workspaces only on primary" msgstr "Tööalad ainult peamisel" +#: data/org.gnome.mutter.gschema.xml.in:51 msgid "" "Determines whether workspace switching should happen for windows on all " "monitors or only for windows on the primary monitor." @@ -396,9 +334,11 @@ msgstr "" "Määrab, kas tööalade vahetamine mõjutab kõiki aknaid kõigil monitoridel või " "ainult aknaid peamisel monitoril." +#: data/org.gnome.mutter.gschema.xml.in:59 msgid "No tab popup" msgstr "Tabulaatoril pole hüpikakent" +#: data/org.gnome.mutter.gschema.xml.in:60 msgid "" "Determines whether the use of popup and highlight frame should be disabled " "for window cycling." @@ -406,914 +346,1244 @@ msgstr "" "Kui märgitud, siis on hüpikaken ja esiletõstmise raam keelatud akende " "vahetamisel." +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Fookusemuutused lükatakse edasi kuni kursor peatub" + +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" +"Kui tõene ning fookusrežiim on kas „sloppy“ või „mouse“, siis fookust ei " +"vahetata kohe, kui kursor aknale liigub, vaid alles pärast kursori peatumist." + +#: data/org.gnome.mutter.gschema.xml.in:79 msgid "Draggable border width" -msgstr "Lohistatava äärise laius." +msgstr "Lohistatava äärise laius" +#: data/org.gnome.mutter.gschema.xml.in:80 msgid "" -"The amount of total draggable borders. If the theme's visible borders are " +"The amount of total draggable borders. If the theme’s visible borders are " "not enough, invisible borders will be added to meet this value." msgstr "" "Lohistatava äärise laius. Kui kujunduse nähtavatest ääristest ei piisa, " "lisatakse puuduoleva osa jaoks nähtamatu ääris." +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "Peaaegu monitori suurused ekraanid maksimeeritakse automaatselt" + +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" +"Kui lubatud, maksimeeritakse automaatselt aknad, mis on avanedes monitori " +"suurused." + +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "" + +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" + +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "" + +#: data/org.gnome.mutter.gschema.xml.in:108 +msgid "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “remote-desktop” — " +"enables remote desktop support. To support remote desktop with screen " +"sharing, “screen-cast” must also be enabled. • “screen-cast” — enables " +"screen cast support." +msgstr "" + +#: data/org.gnome.mutter.gschema.xml.in:145 msgid "Select window from tab popup" msgstr "Akna valimine tabulaatori hüpikaknalt" +#: data/org.gnome.mutter.gschema.xml.in:150 msgid "Cancel tab popup" msgstr "Tabulaatori hüpikakna katkestamine" +#: data/org.gnome.mutter.gschema.xml.in:155 +#, fuzzy +#| msgid "Switch applications" +msgid "Switch monitor configurations" +msgstr "Rakenduste vahetamine" + +#: data/org.gnome.mutter.gschema.xml.in:160 +msgid "Rotates the built-in monitor configuration" +msgstr "" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +#, fuzzy +#| msgid "Switch to workspace 1" +msgid "Switch to VT 1" +msgstr "1. tööalale liikumine" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +#, fuzzy +#| msgid "Switch to workspace 2" +msgid "Switch to VT 2" +msgstr "2. tööalale liikumine" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +#, fuzzy +#| msgid "Switch to workspace 3" +msgid "Switch to VT 3" +msgstr "3. tööalale liikumine" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +#, fuzzy +#| msgid "Switch to workspace 4" +msgid "Switch to VT 4" +msgstr "4. tööalale liikumine" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +#, fuzzy +#| msgid "Switch to workspace 1" +msgid "Switch to VT 5" +msgstr "1. tööalale liikumine" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +#, fuzzy +#| msgid "Switch to workspace 1" +msgid "Switch to VT 6" +msgstr "1. tööalale liikumine" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +#, fuzzy +#| msgid "Switch to workspace 1" +msgid "Switch to VT 7" +msgstr "1. tööalale liikumine" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +#, fuzzy +#| msgid "Switch to workspace 1" +msgid "Switch to VT 8" +msgstr "1. tööalale liikumine" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +#, fuzzy +#| msgid "Switch to workspace 1" +msgid "Switch to VT 9" +msgstr "1. tööalale liikumine" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +#, fuzzy +#| msgid "Switch to workspace 1" +msgid "Switch to VT 10" +msgstr "1. tööalale liikumine" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +#, fuzzy +#| msgid "Switch to workspace 1" +msgid "Switch to VT 11" +msgstr "1. tööalale liikumine" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +#, fuzzy +#| msgid "Switch to workspace 1" +msgid "Switch to VT 12" +msgstr "1. tööalale liikumine" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow grabs with Xwayland" +msgstr "" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 +msgid "" +"Allow keyboard grabs issued by X11 applications running in Xwayland to be " +"taken into account. For a X11 grab to be taken into account under Wayland, " +"the client must also either send a specific X11 ClientMessage to the root " +"window or be among the applications white-listed in key “xwayland-grab-" +"access-rules”." +msgstr "" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:77 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:78 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "" + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. +#. +#: src/backends/meta-input-settings.c:2260 #, c-format -msgid "Usage: %s\n" -msgstr "Kasutamine: %s\n" +msgid "Mode Switch (Group %d)" +msgstr "" -msgid "Close Window" -msgstr "Sulge aken" +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2283 +#, fuzzy +#| msgid "Switch system controls" +msgid "Switch monitor" +msgstr "Süsteemi juhtalade vahetamine" + +#: src/backends/meta-input-settings.c:2285 +msgid "Show on-screen help" +msgstr "" -msgid "Window Menu" -msgstr "Aknamenüü" +#: src/backends/meta-monitor-manager.c:900 +msgid "Built-in display" +msgstr "Sisseehitatud kuva" -msgid "Minimize Window" -msgstr "Akna minimeerimine" +#: src/backends/meta-monitor-manager.c:923 +#, fuzzy +#| msgid "Unknown %s" +msgid "Unknown" +msgstr "Tundmatu %s" -msgid "Maximize Window" -msgstr "Akna maksimeerimine" +#: src/backends/meta-monitor-manager.c:925 +#, fuzzy +#| msgid "Unknown %s" +msgid "Unknown Display" +msgstr "Tundmatu %s" -msgid "Restore Window" -msgstr "Akna taastamine" +#. TRANSLATORS: this is a monitor vendor name, followed by a +#. * size in inches, like 'Dell 15"' +#. +#: src/backends/meta-monitor-manager.c:933 +#, c-format +msgid "%s %s" +msgstr "%s %s" -msgid "Roll Up Window" -msgstr "Akna kokkukerimine" +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:481 +#, c-format +msgid "" +"Another compositing manager is already running on screen %i on display “%s”." +msgstr "Teine komposiithaldur juba töötab ekraani %i kuval „%s“." + +#: src/core/bell.c:194 +msgid "Bell event" +msgstr "Helina sündmus" -msgid "Unroll Window" -msgstr "Akna lahtikerimine" +#: src/core/display.c:608 +#, c-format +msgid "Failed to open X Window System display “%s”\n" +msgstr "Tõrge X Window System’i kuva „%s“ avamisel\n" -msgid "Keep Window On Top" -msgstr "Akna kõige pealmiseks määramine" +#: src/core/main.c:190 +msgid "Disable connection to session manager" +msgstr "Seansihalduriga ühendumise keelamine" -msgid "Remove Window From Top" -msgstr "Eemalda aken kõige pealmise kohalt" +#: src/core/main.c:196 +msgid "Replace the running window manager" +msgstr "Töötava aknahalduri asendamine" -msgid "Always On Visible Workspace" -msgstr "Alati nähtaval tööalal" +#: src/core/main.c:202 +msgid "Specify session management ID" +msgstr "Seansihalduse ID kirjeldamine" -msgid "Put Window On Only One Workspace" -msgstr "Tõsta aken ainult ühele tööalale" +#: src/core/main.c:207 +msgid "X Display to use" +msgstr "X-kuva, mida kasutada" -#. Translators: Translate this string the same way as you do in libwnck! -msgid "Mi_nimize" -msgstr "_Minimeeri" +#: src/core/main.c:213 +msgid "Initialize session from savefile" +msgstr "Seansi lähtestamine salvestatud failist" -#. Translators: Translate this string the same way as you do in libwnck! -msgid "Ma_ximize" -msgstr "Ma_ksimeeri" +#: src/core/main.c:219 +msgid "Make X calls synchronous" +msgstr "Tee X-väljakutsed sünkroonseks" -#. Translators: Translate this string the same way as you do in libwnck! -msgid "Unma_ximize" -msgstr "T_aasta suurus" +#: src/core/main.c:226 +msgid "Run as a wayland compositor" +msgstr "" -#. Translators: Translate this string the same way as you do in libwnck! -msgid "Roll _Up" -msgstr "K_eri kokku" +#: src/core/main.c:232 +msgid "Run as a nested compositor" +msgstr "" -#. Translators: Translate this string the same way as you do in libwnck! -msgid "_Unroll" -msgstr "K_eri lahti" +#: src/core/main.c:240 +msgid "Run as a full display server, rather than nested" +msgstr "" -#. Translators: Translate this string the same way as you do in libwnck! -msgid "_Move" -msgstr "_Liiguta" +#: src/core/main.c:246 +msgid "Run with X11 backend" +msgstr "" -#. Translators: Translate this string the same way as you do in libwnck! -msgid "_Resize" -msgstr "Muuda s_uurust" +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:147 +#, c-format +msgid "“%s” is not responding." +msgstr "„%s“ ei vasta." -#. Translators: Translate this string the same way as you do in libwnck! -msgid "Move Titlebar On_screen" -msgstr "Liiguta tiitliriba mööda _ekraani" +#: src/core/meta-close-dialog-default.c:149 +msgid "Application is not responding." +msgstr "Rakendus ei vasta." -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -msgid "Always on _Top" -msgstr "Alati _pealmine" +#: src/core/meta-close-dialog-default.c:154 +msgid "" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." +msgstr "Sa võid natukene selle järel oodata või sundida rakenduse lõpetama." -#. Translators: Translate this string the same way as you do in libwnck! -msgid "_Always on Visible Workspace" -msgstr "_Alati nähtaval tööalal" +#: src/core/meta-close-dialog-default.c:161 +msgid "_Force Quit" +msgstr "_Sulge jõuga" -#. Translators: Translate this string the same way as you do in libwnck! -msgid "_Only on This Workspace" -msgstr "Ainu_lt sellel tööalal" +#: src/core/meta-close-dialog-default.c:161 +msgid "_Wait" +msgstr "_Oota" -#. Translators: Translate this string the same way as you do in libwnck! -msgid "Move to Workspace _Left" -msgstr "Tõsta _vasakpoolsele tööalale" +#: src/core/mutter.c:39 +#, c-format +msgid "" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" +msgstr "" +"mutter %s\n" +"Autoriõigused © 2001-%d Havoc Pennington, Red Hat, Inc., ja teised\n" +"See programm on vaba tarkvara; kopeerimistingimuste kohta vaata\n" +"programmi lähteteksti. Sellel programmil pole MINGISUGUST GARANTIID;\n" +"isegi MITTE KOMMERTSGARANTIID EGA GARANTIID SOBIVUSELE\n" +"TEATUD KINDLAKS EESMÄRGIKS.\n" -#. Translators: Translate this string the same way as you do in libwnck! -msgid "Move to Workspace R_ight" -msgstr "Tõsta pa_rempoolsele tööalale" +#: src/core/mutter.c:53 +msgid "Print version" +msgstr "Versiooni printimine" -#. Translators: Translate this string the same way as you do in libwnck! -msgid "Move to Workspace _Up" -msgstr "Tõsta _ülemisele tööalale" +#: src/core/mutter.c:59 +msgid "Mutter plugin to use" +msgstr "Millist Mutteri pluginat kasutada" -#. Translators: Translate this string the same way as you do in libwnck! -msgid "Move to Workspace _Down" -msgstr "T_õsta alumisele tööalale" +#: src/core/prefs.c:1997 +#, c-format +msgid "Workspace %d" +msgstr "Tööala %d" -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -msgid "_Close" -msgstr "_Sulge" +#: src/core/screen.c:583 +#, c-format +msgid "" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." +msgstr "" +"Kuva „%s“ on juba aknahalduri poolt hallatav. Olemasoleva aknahalduri " +"asendamiseks proovi --replace võtit." +#: src/core/screen.c:668 #, c-format -msgid "Workspace %d%n" -msgstr "Tööala %d%n" +msgid "Screen %d on display “%s” is invalid\n" +msgstr "Ekraan %d kuval „%s“ on vigane\n" + +#: src/core/util.c:120 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter kompileeriti ilma jutuka režiimi toeta\n" +#: src/wayland/meta-wayland-tablet-pad.c:563 #, c-format -msgid "Workspace 1_0" -msgstr "Tööala 1_0" +msgid "Mode Switch: Mode %d" +msgstr "" +#: src/x11/session.c:1818 +msgid "" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." +msgstr "" +"Need aknad ei toeta „praeguse paigutuse salvestamist“ ja tuleb järgmisel " +"sisselogimisel käsitsi taaskäivitada." + +#: src/x11/window-props.c:559 #, c-format -msgid "Workspace %s%d" -msgstr "Tööala %s%d" +msgid "%s (on %s)" +msgstr "%s (masinas %s)" -msgid "Move to Another _Workspace" -msgstr "Tõsta muule _tööalale" +#~ msgid "Move to workspace left" +#~ msgstr "Vasakpoolsele tööalale liikumine" -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -msgid "Shift" -msgstr "Shift" +#~ msgid "Move to workspace right" +#~ msgstr "Parempoolsele tööalale liikumine" -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -msgid "Ctrl" -msgstr "Ctrl" +#~ msgid "Toggle shaded state" +#~ msgstr "Varjatud oleku vahetamine" -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -msgid "Alt" -msgstr "Alt" +#~ msgid "background texture could not be created from file" +#~ msgstr "failist polnud võimalik taustatekstuuri luua" -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -msgid "Meta" -msgstr "Meta" +#~ msgid "Unknown window information request: %d" +#~ msgstr "Tundmatu aknateabe päring: %d" -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -msgid "Super" -msgstr "Super" +#~ msgid "Missing %s extension required for compositing" +#~ msgstr "Puuduv laiendus %s on vajalik komposiitmontaaži jaoks" -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -msgid "Hyper" -msgstr "Hyper" +#~ msgid "" +#~ "Some other program is already using the key %s with modifiers %x as a " +#~ "binding\n" +#~ msgstr "" +#~ "Mõni teine programm juba kasutab klahvi %s koos muuteklahvidega %x " +#~ "kiirklahvina\n" -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -msgid "Mod2" -msgstr "Mod2" +#~ msgid "\"%s\" is not a valid accelerator\n" +#~ msgstr "\"%s\" pole sobiv kiirklahv\n" -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -msgid "Mod3" -msgstr "Mod3" +#~ msgid "Failed to scan themes directory: %s\n" +#~ msgstr "Tõrge teemadekataloogi skannimisel: %s\n" -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -msgid "Mod4" -msgstr "Mod4" +#~ msgid "" +#~ "Could not find a theme! Be sure %s exists and contains the usual themes.\n" +#~ msgstr "" +#~ "Teemat ei leitud! Veendu, et %s on olemas ja sisaldab harilikke " +#~ "teemasid.\n" -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -msgid "Mod5" -msgstr "Mod5" +#~ msgid "" +#~ "Workarounds for broken applications disabled. Some applications may not " +#~ "behave properly.\n" +#~ msgstr "" +#~ "Ümbernurga parandused vigastele rakendustele on keelatud. Mõned " +#~ "rakendused ei pruugi õigesti käituda.\n" -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#, c-format -msgid "%d x %d" -msgstr "%d x %d" +#~ msgid "Could not parse font description \"%s\" from GSettings key %s\n" +#~ msgstr "" +#~ "Fondi kirjeldust \"%s\" GSettings võtmest %s pole võimalik töödelda\n" -msgid "top" -msgstr "ülemine" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" +#~ msgstr "" +#~ "Seadistuste andmebaasist leitud \"%s\" ei ole sobiv väärtus hiireklahvi " +#~ "modifikaatoriks\n" -msgid "bottom" -msgstr "alumine" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for " +#~ "keybinding \"%s\"\n" +#~ msgstr "" +#~ "Seadistuste andmebaasist leitud \"%s\" ei ole sobiv väärtus kiirklahvile " +#~ "\"%s\"\n" -msgid "left" -msgstr "vasak" +#~ msgid "" +#~ "Could not acquire window manager selection on screen %d display \"%s\"\n" +#~ msgstr "Aknahalduri valikut ei saa hankida ekraani %d kuval \"%s\"\n" -msgid "right" -msgstr "parem" +#~ msgid "Screen %d on display \"%s\" already has a window manager\n" +#~ msgstr "Ekraan %d kuval '%s' on juba aknahalduri poolt hallatav\n" -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "raami asukoht ei määra \"%s\" dimensiooni" +#~ msgid "Could not release screen %d on display \"%s\"\n" +#~ msgstr "Ekraani %d kuval \"%s\" ei saa vabastada\n" -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "raami asukoht ei määra dimensiooni \"%s\" servale \"%s\"" +#~ msgid "Could not create directory '%s': %s\n" +#~ msgstr "Kataloogi '%s' pole võimalik luua: %s\n" -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "Nupu külgede suhe %g ei ole mõistlik" +#~ msgid "Could not open session file '%s' for writing: %s\n" +#~ msgstr "Seansifaili '%s' pole võimalik kirjutamiseks avada: %s\n" -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "Raami geomeetria ei määra nuppude suurust" +#~ msgid "Error writing session file '%s': %s\n" +#~ msgstr "Viga seansifaili '%s' kirjutamisel: %s\n" -#, c-format -msgid "Gradients should have at least two colors" -msgstr "Värviüleminekus peaks olema vähemalt kaks värvi" +#~ msgid "Error closing session file '%s': %s\n" +#~ msgstr "Viga seansifaili '%s' sulgemisel: %s\n" -#, c-format -msgid "" -"GTK custom color specification must have color name and fallback in " -"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" -msgstr "" -"GTK kohandatud värvi määrang peab sisaldama sulgudes värvi nimetust ning " -"varuvärvi, nt gtk:custom(foo,bar); väärtust \"%s\" pole võimalik töödelda" +#~ msgid "Failed to parse saved session file: %s\n" +#~ msgstr "Viga salvestatud seansifaili analüüsimisel: %s\n" -#, c-format -msgid "" -"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" -"_ are valid" -msgstr "" -"gtk:custom color_name parameetris sobimatu märk '%c', lubatud on ainult A-Za-" -"z0-9-_" +#~ msgid "<mutter_session> attribute seen but we already have the session ID" +#~ msgstr "Nähti <mutter_session> atribuuti, aga sessiooni ID on juba määratud" -#, c-format -msgid "" -"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " -"fit the format" -msgstr "" -"Gtk:custom vorming on \"gtk:custom(värvi_nimi,varuvärv)\", \"%s\" ei sobi " -"selle vorminguga" +#~ msgid "Unknown attribute %s on <%s> element" +#~ msgstr "Tundmatu atribuut %s <%s> elemendil" -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"GTK värvispetsifikatsioonil peab olek olema määratud nurksulgudes, nt. gtk:fg" -"[NORMAL], kus NORMAL on olek; väärtust \"%s\" ei saa töödelda" +#~ msgid "nested <window> tag" +#~ msgstr "pesastatud <window>" -#, c-format -msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"GTK värvispetsifikatsioon peab lõppema nurksuluga, nt. gtk:fg[NORMAL], kus " -"NORMAL on olek; väärtust \"%s\" ei saa töödelda" +#~ msgid "Unknown element %s" +#~ msgstr "Tundmatu element %s" -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "Ei mõistnud värvispetsifikatsiooni olekut \"%s\"" +#~ msgid "Failed to open debug log: %s\n" +#~ msgstr "Tõrge silumislogi avamisel: %s\n" -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "Mõistetamatu värvikomponent \"%s\" värvispetsifikatsioonis" +#~ msgid "Failed to fdopen() log file %s: %s\n" +#~ msgstr "Tõrge logifaili %s avamisel funktsiooniga fdopen(): %s\n" -#, c-format -msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" -msgstr "" -"Segatud värvi vorming on \"segamine/taustavärv/värv/katvus\", \"%s\" ei sobi " -"vorminguga" +#~ msgid "Opened log file %s\n" +#~ msgstr "Avati logifail %s\n" -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "Segatud värvi katvuse väärtus \"%s\" ei ole töödeldav" +#~ msgid "Window manager: " +#~ msgstr "Aknahaldur: " -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "Segatud värvi katvuse väärtus \"%s\" ei ole 0.0 ja 1.0 vahel" +#~ msgid "Bug in window manager: " +#~ msgstr "Viga aknahalduris: " -#, c-format -msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "" -"Varjundamise vorming on \"varjundus/alusvärv/tegur\", \"%s\" ei sobi " -"vorminguga" +#~ msgid "Window manager warning: " +#~ msgstr "Aknahalduri hoiatus: " -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "Varjundatud värvi varjundamise tegur \"%s\" ei ole töödeldav" +#~ msgid "Window manager error: " +#~ msgstr "Aknahalduri viga: " -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "Varjundatud värvi varjundamise tegur \"%s\" on negatiivne" +#~ msgid "" +#~ "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " +#~ "window as specified in the ICCCM.\n" +#~ msgstr "" +#~ "Aken %s määrab SM_CLIENT_ID endale, selle asemel et määrata see " +#~ "WM_CLIENT_LEADER aknale, nagu seda kirjeldab ICCCM.\n" -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Värvust \"%s\" pole võimalik analüüsida" +#~ msgid "" +#~ "Window %s sets an MWM hint indicating it isn't resizable, but sets min " +#~ "size %d x %d and max size %d x %d; this doesn't make much sense.\n" +#~ msgstr "" +#~ "Aken %s määrab MWM vihje, näidates, et see pole muudetava suurusega, aga " +#~ "määrab vähimaks suuruseks %d x %d ja suurimaks suuruseks %d x %d; sel " +#~ "pole tähendust.\n" -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "Koordinaatide avaldis sisaldab lubamatut märki '%s'" +#~ msgid "Application set a bogus _NET_WM_PID %lu\n" +#~ msgstr "Rakendus määras võltsitud _NET_WM_PID %lu\n" -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "" -"Koordinaatide avaldis sisaldab ujukomaarvu '%s', seda aga pole võimalik " -"analüüsida" +#~ msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +#~ msgstr "Vigane WM_TRANSIENT_FOR aknale 0x%lx määratud %s jaoks.\n" -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "" -"Koordinaatide avaldis sisaldab täisarvu '%s', seda aga pole võimalik " -"analüüsida" +#~ msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" +#~ msgstr "" +#~ "WM_TRANSIENT_FOR aknale 0x%lx määratud %s jaoks tekitaks tsüklilise " +#~ "korduse.\n" -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "" -"Koordinaatide avaldis sisaldab teksti alguses tundmatut operaatorit: \"%s\"" +#~ msgid "" +#~ "Window 0x%lx has property %s\n" +#~ "that was expected to have type %s format %d\n" +#~ "and actually has type %s format %d n_items %d.\n" +#~ "This is most likely an application bug, not a window manager bug.\n" +#~ "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +#~ msgstr "" +#~ "Aknal 0x%lx on omadus %s,\n" +#~ "mis oleks pidanud olema %s tüüpi %d vormingus,\n" +#~ "aga tegelikult oli %s tüüpi %d vormingus n_items %d.\n" +#~ "See on kõige tõenäolisemalt rakenduse, mitte aknahalduri viga.\n" +#~ "Aknal on title=\"%s\" class=\"%s\" name=\"%s\"\n" -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "Koordinaatide avaldis on tühi või arusaamatult koostatud" +#~ msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +#~ msgstr "Omadus %s aknal 0x%lx sisaldab vigast UTF-8\n" -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "Koordinaatide avaldise tulemuseks on nulliga jagamine" +#~ msgid "" +#~ "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the " +#~ "list\n" +#~ msgstr "Omadus %s aknal 0x%lx sisaldab vigast UTF-8 %d kirjele nimekirjas\n" -#, c-format -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "" -"Koordinaatide avaldis püüab ujukomaarvul kasutada jagamise jäägi (mod) " -"operaatorit" +#~ msgid "Mi_nimize" +#~ msgstr "_Minimeeri" -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "Koordinaatide avaldis sisaldab operandi kohal operaatorit \"%s\"" +#~ msgid "Ma_ximize" +#~ msgstr "Ma_ksimeeri" -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "Koordinaatide avaldis sisaldab operandi seal, kus oodati operaatorit" +#~ msgid "Unma_ximize" +#~ msgstr "T_aasta suurus" -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "Koordinaatide avaldis lõppes operandi asemel operaatoriga" +#~ msgid "Roll _Up" +#~ msgstr "K_eri kokku" -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" -"Koordinaatide avaldis sisaldab operaatoreid \"%c\" ja \"%c\" ilma " -"nendevahelise operandita" +#~ msgid "_Unroll" +#~ msgstr "K_eri lahti" -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "Koordinaatide avaldis sisaldab tundmatut muutujat või konstanti \"%s\"" +#~ msgid "_Move" +#~ msgstr "_Liiguta" -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "Koordinaatide avaldise analüsaatoril tekkis puhvri ületäitumine." +#~ msgid "_Resize" +#~ msgstr "Muuda s_uurust" -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "Koordinaatide avaldises on sulgevad sulud ilma avavate sulgudeta" +#~ msgid "Move Titlebar On_screen" +#~ msgstr "Liiguta tiitliriba mööda _ekraani" -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "Koordinaatide avaldises on avavad sulud ilma sulgevate sulgudeta" +#~ msgid "Always on _Top" +#~ msgstr "Alati _pealmine" -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "" -"Tundub, et koordinaatide avaldis ei sisalda ei operaatoreid ega operande" +#~ msgid "_Always on Visible Workspace" +#~ msgstr "_Alati nähtaval tööalal" -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "Teema sisaldas avaldist, mis põhjustas vea: %s\n" +#~ msgid "_Only on This Workspace" +#~ msgstr "Ainu_lt sellel tööalal" -#, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"misiganes\"/> peab selles " -"raamistiilis olema määratud" +#~ msgid "Move to Workspace _Left" +#~ msgstr "Tõsta _vasakpoolsele tööalale" -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" -"Puuduv <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"misiganes\"/>" +#~ msgid "Move to Workspace R_ight" +#~ msgstr "Tõsta pa_rempoolsele tööalale" -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Tõrge teema \"%s\" laadimisel: %s\n" +#~ msgid "Move to Workspace _Up" +#~ msgstr "Tõsta _ülemisele tööalale" -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "Teemas \"%2$s\" pole määratud ühtki <%1$s>" +#~ msgid "Move to Workspace _Down" +#~ msgstr "T_õsta alumisele tööalale" -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" -"Teemas \"%2$s\" pole \"%1$s\" tüüpi aknale määratud raamistiili, lisa " -"<window type=\"%3$s\" style_set=\"misiganes\"/> element" +#~ msgid "_Close" +#~ msgstr "_Sulge" -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" -"Kasutajadefineeritud konstandid peavad algama suurtähega; \"%s\" ei alga" +#~ msgid "Workspace %d%n" +#~ msgstr "Tööala %d%n" -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "Konstant \"%s\" on juba defineeritud" +#~ msgid "Workspace 1_0" +#~ msgstr "Tööala 1_0" -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. -#. -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "Elemendil <%2s> pole \"%1s\" atribuuti" +#~ msgid "Workspace %s%d" +#~ msgstr "Tööala %s%d" -#, c-format -msgid "Line %d character %d: %s" -msgstr "Rida %d, märk %d: %s" +#~ msgid "Move to Another _Workspace" +#~ msgstr "Tõsta muule _tööalale" -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "Atribuuti \"%s\" korratakse kaks korda samas elemendis <%s>" +#~ msgid "Shift" +#~ msgstr "Shift" -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "Atribuudi \"%s\" esinemine selles kontekstis elemendil <%s> on viga" +#~ msgid "Ctrl" +#~ msgstr "Ctrl" -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "\"%s\" pole täisarvuna võimalik analüüsida" +#~ msgid "Alt" +#~ msgstr "Alt" -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "Lõpumärgid \"%s\" sõnes \"%s\" on arusaamatud" +#~ msgid "Meta" +#~ msgstr "Meta" -#, c-format -msgid "Integer %ld must be positive" -msgstr "Täisarv %ld peab olema positiivne" +#~ msgid "Super" +#~ msgstr "Super" -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "Täisarv %ld on liiga suur, praegu on suurim lubatud väärtus %d" +#~ msgid "Hyper" +#~ msgstr "Hyper" -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "Väärtust \"%s\" ei saa töödelda ujukomaarvuna" +#~ msgid "Mod2" +#~ msgstr "Mod2" -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "Tõeväärtused peavad olema kas \"true\" või \"false\", aga mitte \"%s\"" +#~ msgid "Mod3" +#~ msgstr "Mod3" -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "Nurk peab olema 0.0 ja 360.0 vahel, oli aga %g\n" +#~ msgid "Mod4" +#~ msgstr "Mod4" -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" -"Läbipaistvus peab olema 0.0 (nähtamatu) ja 1.0 (täiskattev) vahel, oli %g\n" +#~ msgid "Mod5" +#~ msgstr "Mod5" -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"Tiitli suurus \"%s\" on sobimatu (peab olema üks valikust: xx-small,x-small," -"small,medium,large,x-large,xx-large)\n" +#~ msgid "%d x %d" +#~ msgstr "%d x %d" -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s> kasutab teist korda nime \"%s\"" +#~ msgid "top" +#~ msgstr "ülemine" -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "<%s> vanem \"%s\" pole määratud" +#~ msgid "bottom" +#~ msgstr "alumine" -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "<%s> asukoht \"%s\" pole määratud" +#~ msgid "left" +#~ msgstr "vasak" -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "<%s> või selle vanema jaoks peab olema asukoht määratud" +#~ msgid "right" +#~ msgstr "parem" -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "Et alfa väärtusel oleks tähendus, peab taust olema määratud" +#~ msgid "frame geometry does not specify \"%s\" dimension" +#~ msgstr "raami asukoht ei määra \"%s\" dimensiooni" -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Elemendi <%2$s> tüüp \"%1$s\" on tundmatu" +#~ msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" +#~ msgstr "raami asukoht ei määra dimensiooni \"%s\" servale \"%s\"" -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "Tundmatu stiilikomplekt style_set \"%s\" elemendil <%s>" +#~ msgid "Button aspect ratio %g is not reasonable" +#~ msgstr "Nupu külgede suhe %g ei ole mõistlik" -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "Aknatüübile \"%s\" on stiilikomplekt juba määratud" +#~ msgid "Frame geometry does not specify size of buttons" +#~ msgstr "Raami geomeetria ei määra nuppude suurust" -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "Element <%s> pole lubatud <%s> sees" +#~ msgid "Gradients should have at least two colors" +#~ msgstr "Värviüleminekus peaks olema vähemalt kaks värvi" -msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" -msgstr "" -"Nuppudele ei saa korraga määrata \"button_width\"/\"button_height\" ja " -"\"aspect_ratio\" atribuute" +#~ msgid "" +#~ "GTK custom color specification must have color name and fallback in " +#~ "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" +#~ msgstr "" +#~ "GTK kohandatud värvi määrang peab sisaldama sulgudes värvi nimetust ning " +#~ "varuvärvi, nt gtk:custom(foo,bar); väärtust \"%s\" pole võimalik töödelda" -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "Vahemaa \"%s\" on tundmatu" +#~ msgid "" +#~ "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-" +#~ "z0-9-_ are valid" +#~ msgstr "" +#~ "gtk:custom color_name parameetris sobimatu märk '%c', lubatud on ainult A-" +#~ "Za-z0-9-_" -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "Proportsioon \"%s\" on tundmatu" +#~ msgid "" +#~ "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " +#~ "fit the format" +#~ msgstr "" +#~ "Gtk:custom vorming on \"gtk:custom(värvi_nimi,varuvärv)\", \"%s\" ei sobi " +#~ "selle vorminguga" -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "Raam \"%s\" on tundmatu" +#~ msgid "" +#~ "GTK color specification must have the state in brackets, e.g. gtk:" +#~ "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "GTK värvispetsifikatsioonil peab olek olema määratud nurksulgudes, nt. " +#~ "gtk:fg[NORMAL], kus NORMAL on olek; väärtust \"%s\" ei saa töödelda" -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "Elemendil <%s> pole \"start_angle\" ega \"from\" atribuute" +#~ msgid "" +#~ "GTK color specification must have a close bracket after the state, e.g. " +#~ "gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "GTK värvispetsifikatsioon peab lõppema nurksuluga, nt. gtk:fg[NORMAL], " +#~ "kus NORMAL on olek; väärtust \"%s\" ei saa töödelda" -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "Elemendil <%s> pole \"extent_angle\" ega \"to\" atribuute" +#~ msgid "Did not understand state \"%s\" in color specification" +#~ msgstr "Ei mõistnud värvispetsifikatsiooni olekut \"%s\"" -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "Väärtust \"%s\" ei saa mõista värviülemineku tüübina" +#~ msgid "Did not understand color component \"%s\" in color specification" +#~ msgstr "Mõistetamatu värvikomponent \"%s\" värvispetsifikatsioonis" + +#~ msgid "" +#~ "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit " +#~ "the format" +#~ msgstr "" +#~ "Segatud värvi vorming on \"segamine/taustavärv/värv/katvus\", \"%s\" ei " +#~ "sobi vorminguga" + +#~ msgid "Could not parse alpha value \"%s\" in blended color" +#~ msgstr "Segatud värvi katvuse väärtus \"%s\" ei ole töödeldav" + +#~ msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" +#~ msgstr "Segatud värvi katvuse väärtus \"%s\" ei ole 0.0 ja 1.0 vahel" + +#~ msgid "" +#~ "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the " +#~ "format" +#~ msgstr "" +#~ "Varjundamise vorming on \"varjundus/alusvärv/tegur\", \"%s\" ei sobi " +#~ "vorminguga" + +#~ msgid "Could not parse shade factor \"%s\" in shaded color" +#~ msgstr "Varjundatud värvi varjundamise tegur \"%s\" ei ole töödeldav" + +#~ msgid "Shade factor \"%s\" in shaded color is negative" +#~ msgstr "Varjundatud värvi varjundamise tegur \"%s\" on negatiivne" + +#~ msgid "Could not parse color \"%s\"" +#~ msgstr "Värvust \"%s\" pole võimalik analüüsida" + +#~ msgid "Coordinate expression contains character '%s' which is not allowed" +#~ msgstr "Koordinaatide avaldis sisaldab lubamatut märki '%s'" + +#~ msgid "" +#~ "Coordinate expression contains floating point number '%s' which could not " +#~ "be parsed" +#~ msgstr "" +#~ "Koordinaatide avaldis sisaldab ujukomaarvu '%s', seda aga pole võimalik " +#~ "analüüsida" + +#~ msgid "" +#~ "Coordinate expression contains integer '%s' which could not be parsed" +#~ msgstr "" +#~ "Koordinaatide avaldis sisaldab täisarvu '%s', seda aga pole võimalik " +#~ "analüüsida" + +#~ msgid "" +#~ "Coordinate expression contained unknown operator at the start of this " +#~ "text: \"%s\"" +#~ msgstr "" +#~ "Koordinaatide avaldis sisaldab teksti alguses tundmatut operaatorit: \"%s" +#~ "\"" + +#~ msgid "Coordinate expression was empty or not understood" +#~ msgstr "Koordinaatide avaldis on tühi või arusaamatult koostatud" + +#~ msgid "Coordinate expression results in division by zero" +#~ msgstr "Koordinaatide avaldise tulemuseks on nulliga jagamine" + +#~ msgid "" +#~ "Coordinate expression tries to use mod operator on a floating-point number" +#~ msgstr "" +#~ "Koordinaatide avaldis püüab ujukomaarvul kasutada jagamise jäägi (mod) " +#~ "operaatorit" + +#~ msgid "" +#~ "Coordinate expression has an operator \"%s\" where an operand was expected" +#~ msgstr "Koordinaatide avaldis sisaldab operandi kohal operaatorit \"%s\"" + +#~ msgid "Coordinate expression had an operand where an operator was expected" +#~ msgstr "" +#~ "Koordinaatide avaldis sisaldab operandi seal, kus oodati operaatorit" + +#~ msgid "Coordinate expression ended with an operator instead of an operand" +#~ msgstr "Koordinaatide avaldis lõppes operandi asemel operaatoriga" + +#~ msgid "" +#~ "Coordinate expression has operator \"%c\" following operator \"%c\" with " +#~ "no operand in between" +#~ msgstr "" +#~ "Koordinaatide avaldis sisaldab operaatoreid \"%c\" ja \"%c\" ilma " +#~ "nendevahelise operandita" + +#~ msgid "Coordinate expression had unknown variable or constant \"%s\"" +#~ msgstr "" +#~ "Koordinaatide avaldis sisaldab tundmatut muutujat või konstanti \"%s\"" + +#~ msgid "Coordinate expression parser overflowed its buffer." +#~ msgstr "Koordinaatide avaldise analüsaatoril tekkis puhvri ületäitumine." + +#~ msgid "" +#~ "Coordinate expression had a close parenthesis with no open parenthesis" +#~ msgstr "Koordinaatide avaldises on sulgevad sulud ilma avavate sulgudeta" + +#~ msgid "" +#~ "Coordinate expression had an open parenthesis with no close parenthesis" +#~ msgstr "Koordinaatide avaldises on avavad sulud ilma sulgevate sulgudeta" + +#~ msgid "Coordinate expression doesn't seem to have any operators or operands" +#~ msgstr "" +#~ "Tundub, et koordinaatide avaldis ei sisalda ei operaatoreid ega operande" + +#~ msgid "Theme contained an expression that resulted in an error: %s\n" +#~ msgstr "Teema sisaldas avaldist, mis põhjustas vea: %s\n" -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "Väärtust \"%s\" ei saa mõista täitetüübina elemendile <%s>" +#~ msgid "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " +#~ "specified for this frame style" +#~ msgstr "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"misiganes\"/> peab selles " +#~ "raamistiilis olema määratud" -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "Väärtust \"%s\" ei saa mõista olekuna elemendile <%s>" +#~ msgid "" +#~ "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/" +#~ ">" +#~ msgstr "" +#~ "Puuduv <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"misiganes\"/" +#~ ">" -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "Väärtus \"%s\" ei saa mõista varjuna elemendile <%s>" +#~ msgid "Failed to load theme \"%s\": %s\n" +#~ msgstr "Tõrge teema \"%s\" laadimisel: %s\n" -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "Väärtust \"%s\" ei saa mõista noolena elemendile <%s>" +#~ msgid "No <%s> set for theme \"%s\"" +#~ msgstr "Teemas \"%2$s\" pole määratud ühtki <%1$s>" -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "Ühtki <draw_ops> poolt kutsutud \"%s\" ei ole määratud" +#~ msgid "" +#~ "No frame style set for window type \"%s\" in theme \"%s\", add a <window " +#~ "type=\"%s\" style_set=\"whatever\"/> element" +#~ msgstr "" +#~ "Teemas \"%2$s\" pole \"%1$s\" tüüpi aknale määratud raamistiili, lisa " +#~ "<window type=\"%3$s\" style_set=\"misiganes\"/> element" -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "draw_ops \"%s\" lisamine siia põhjustaks ringviitamise" +#~ msgid "" +#~ "User-defined constants must begin with a capital letter; \"%s\" does not" +#~ msgstr "" +#~ "Kasutajadefineeritud konstandid peavad algama suurtähega; \"%s\" ei alga" -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Raamitükile on asukoht \"%s\" tundmatu" +#~ msgid "Constant \"%s\" has already been defined" +#~ msgstr "Konstant \"%s\" on juba defineeritud" -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "Raamistiilil juba on tükk asukohas %s" +#~ msgid "No \"%s\" attribute on element <%s>" +#~ msgstr "Elemendil <%2s> pole \"%1s\" atribuuti" -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "Ühtki \"%s\" nimelist <draw_ops> pole määratud" +#~ msgid "Line %d character %d: %s" +#~ msgstr "Rida %d, märk %d: %s" -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Nupule on funktsioon \"%s\" tundmatu" +#~ msgid "Attribute \"%s\" repeated twice on the same <%s> element" +#~ msgstr "Atribuuti \"%s\" korratakse kaks korda samas elemendis <%s>" -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "Nupu funktsiooni \"%s\" selles versioonis pole (%d, vaja on %d)" +#~ msgid "Attribute \"%s\" is invalid on <%s> element in this context" +#~ msgstr "Atribuudi \"%s\" esinemine selles kontekstis elemendil <%s> on viga" -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Nupule on olek \"%s\" tundmatu" +#~ msgid "Could not parse \"%s\" as an integer" +#~ msgstr "\"%s\" pole täisarvuna võimalik analüüsida" -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "Raami stiilil juba on nupp funktsiooni %s olekule %s" +#~ msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +#~ msgstr "Lõpumärgid \"%s\" sõnes \"%s\" on arusaamatud" -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "\"%s\" pole sobiv väärtus focus atribuudile" +#~ msgid "Integer %ld must be positive" +#~ msgstr "Täisarv %ld peab olema positiivne" -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "\"%s\" pole sobiv väärtus state atribuudile" +#~ msgid "Integer %ld is too large, current max is %d" +#~ msgstr "Täisarv %ld on liiga suur, praegu on suurim lubatud väärtus %d" -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "\"%s\" nimeline stiil pole määratud" +#~ msgid "Could not parse \"%s\" as a floating point number" +#~ msgstr "Väärtust \"%s\" ei saa töödelda ujukomaarvuna" -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "\"%s\" pole sobiv väärtus resize atribuudile" +#~ msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" +#~ msgstr "" +#~ "Tõeväärtused peavad olema kas \"true\" või \"false\", aga mitte \"%s\"" -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" -"Elemendil <%s> ei peaks olema \"resize\" atribuuti maximized/shaded olekute " -"jaoks" +#~ msgid "Angle must be between 0.0 and 360.0, was %g\n" +#~ msgstr "Nurk peab olema 0.0 ja 360.0 vahel, oli aga %g\n" -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "" -"Elemendil <%s> ei peaks olema \"resize\" atribuuti maximized oleku jaoks" +#~ msgid "" +#~ "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" +#~ msgstr "" +#~ "Läbipaistvus peab olema 0.0 (nähtamatu) ja 1.0 (täiskattev) vahel, oli " +#~ "%g\n" -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "Olekule %s suurusele %s ja fookusele %s on stiil juba määratud" +#~ msgid "" +#~ "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," +#~ "large,x-large,xx-large)\n" +#~ msgstr "" +#~ "Tiitli suurus \"%s\" on sobimatu (peab olema üks valikust: xx-small,x-" +#~ "small,small,medium,large,x-large,xx-large)\n" -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "Olekule %s ja fookusele %s on stiil juba määratud" +#~ msgid "<%s> name \"%s\" used a second time" +#~ msgstr "<%s> kasutab teist korda nime \"%s\"" -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Elemendil <piece> ei saa olla kaks draw_ops'i (teema määras draw_ops " -"atribuudi ja <draw_ops> elemendi või kaks elementi)" +#~ msgid "<%s> parent \"%s\" has not been defined" +#~ msgstr "<%s> vanem \"%s\" pole määratud" -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Elemendil <button> ei saa olla kaks draw_ops'i (teema määras draw_ops " -"atribuudi ja <draw_ops> elemendi või kaks elementi)" +#~ msgid "<%s> geometry \"%s\" has not been defined" +#~ msgstr "<%s> asukoht \"%s\" pole määratud" -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Elemendil <menu_icon> ei saa olla kaks draw_ops'i (teema määras draw_ops " -"atribuudi ja <draw_ops> elemendi või kaks elementi)" +#~ msgid "<%s> must specify either a geometry or a parent that has a geometry" +#~ msgstr "<%s> või selle vanema jaoks peab olema asukoht määratud" -#, c-format -msgid "Bad version specification '%s'" -msgstr "Vigane versioonikirjeldus '%s'" +#~ msgid "You must specify a background for an alpha value to be meaningful" +#~ msgstr "Et alfa väärtusel oleks tähendus, peab taust olema määratud" -msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" -msgstr "" -"\"version\" rekvisiiti pole võimalik kasutada ei failis metacity-theme-1.xml " -"ega metacity-theme-2.xml" +#~ msgid "Unknown type \"%s\" on <%s> element" +#~ msgstr "Elemendi <%2$s> tüüp \"%1$s\" on tundmatu" -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "Teema nõuab versiooni %s, kuid viimane toetatud teemaversioon on %d.%d" +#~ msgid "Unknown style_set \"%s\" on <%s> element" +#~ msgstr "Tundmatu stiilikomplekt style_set \"%s\" elemendil <%s>" -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "Teema kõige välimine element peab olema <metacity_theme> mitte <%s>" +#~ msgid "Window type \"%s\" has already been assigned a style set" +#~ msgstr "Aknatüübile \"%s\" on stiilikomplekt juba määratud" -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "Element <%s> pole elementide name/author/date/description sees lubatud" +#~ msgid "Element <%s> is not allowed below <%s>" +#~ msgstr "Element <%s> pole lubatud <%s> sees" -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "Element <%s> pole elemendi <constant> sees lubatud" +#~ msgid "" +#~ "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio" +#~ "\" for buttons" +#~ msgstr "" +#~ "Nuppudele ei saa korraga määrata \"button_width\"/\"button_height\" ja " +#~ "\"aspect_ratio\" atribuute" -#, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "Element <%s> pole elementide distance/border/aspect_ratio sees lubatud" +#~ msgid "Distance \"%s\" is unknown" +#~ msgstr "Vahemaa \"%s\" on tundmatu" -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "Element <%s> pole joonistusoperatsiooni elemendi sees lubatud" +#~ msgid "Aspect ratio \"%s\" is unknown" +#~ msgstr "Proportsioon \"%s\" on tundmatu" -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "Element <%s> pole elemendi <%s> sees lubatud" +#~ msgid "Border \"%s\" is unknown" +#~ msgstr "Raam \"%s\" on tundmatu" -msgid "No draw_ops provided for frame piece" -msgstr "Raamitükile pole määratud draw_ops" +#~ msgid "No \"start_angle\" or \"from\" attribute on element <%s>" +#~ msgstr "Elemendil <%s> pole \"start_angle\" ega \"from\" atribuute" -msgid "No draw_ops provided for button" -msgstr "Nupule pole määratud draw_ops" +#~ msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" +#~ msgstr "Elemendil <%s> pole \"extent_angle\" ega \"to\" atribuute" -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "Elemendi <%s> sees pole tekst lubatud" +#~ msgid "Did not understand value \"%s\" for type of gradient" +#~ msgstr "Väärtust \"%s\" ei saa mõista värviülemineku tüübina" -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "Selle teema jaoks on <%s> määratud kaks korda" +#~ msgid "Did not understand fill type \"%s\" for <%s> element" +#~ msgstr "Väärtust \"%s\" ei saa mõista täitetüübina elemendile <%s>" -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Tõrge %s teema jaoks korrektse faili leidmisel\n" +#~ msgid "Did not understand state \"%s\" for <%s> element" +#~ msgstr "Väärtust \"%s\" ei saa mõista olekuna elemendile <%s>" -msgid "_Windows" -msgstr "_Aknad" +#~ msgid "Did not understand shadow \"%s\" for <%s> element" +#~ msgstr "Väärtus \"%s\" ei saa mõista varjuna elemendile <%s>" -msgid "_Dialog" -msgstr "_Dialoog" +#~ msgid "Did not understand arrow \"%s\" for <%s> element" +#~ msgstr "Väärtust \"%s\" ei saa mõista noolena elemendile <%s>" -msgid "_Modal dialog" -msgstr "_Modaaldialoog" +#~ msgid "No <draw_ops> called \"%s\" has been defined" +#~ msgstr "Ühtki <draw_ops> poolt kutsutud \"%s\" ei ole määratud" -msgid "_Utility" -msgstr "_Utiliit" +#~ msgid "Including draw_ops \"%s\" here would create a circular reference" +#~ msgstr "draw_ops \"%s\" lisamine siia põhjustaks ringviitamise" -msgid "_Splashscreen" -msgstr "_Käivitusekraan" +#~ msgid "Unknown position \"%s\" for frame piece" +#~ msgstr "Raamitükile on asukoht \"%s\" tundmatu" -msgid "_Top dock" -msgstr "Ü_lemine dokk" +#~ msgid "Frame style already has a piece at position %s" +#~ msgstr "Raamistiilil juba on tükk asukohas %s" -msgid "_Bottom dock" -msgstr "_Alumine dokk" +#~ msgid "No <draw_ops> with the name \"%s\" has been defined" +#~ msgstr "Ühtki \"%s\" nimelist <draw_ops> pole määratud" -msgid "_Left dock" -msgstr "_Vasak dokk" +#~ msgid "Unknown function \"%s\" for button" +#~ msgstr "Nupule on funktsioon \"%s\" tundmatu" -msgid "_Right dock" -msgstr "_Parem dokk" +#~ msgid "Button function \"%s\" does not exist in this version (%d, need %d)" +#~ msgstr "Nupu funktsiooni \"%s\" selles versioonis pole (%d, vaja on %d)" -msgid "_All docks" -msgstr "_Kõik dokid" +#~ msgid "Unknown state \"%s\" for button" +#~ msgstr "Nupule on olek \"%s\" tundmatu" -msgid "Des_ktop" -msgstr "_Töölaud" +#~ msgid "Frame style already has a button for function %s state %s" +#~ msgstr "Raami stiilil juba on nupp funktsiooni %s olekule %s" -msgid "Open another one of these windows" -msgstr "Ava neist akendest järgmine" +#~ msgid "\"%s\" is not a valid value for focus attribute" +#~ msgstr "\"%s\" pole sobiv väärtus focus atribuudile" -msgid "This is a demo button with an 'open' icon" -msgstr "See on näidisnupp koos 'ava' ikooniga" +#~ msgid "\"%s\" is not a valid value for state attribute" +#~ msgstr "\"%s\" pole sobiv väärtus state atribuudile" -msgid "This is a demo button with a 'quit' icon" -msgstr "See on näidisnupp koos 'lõpeta' ikooniga" +#~ msgid "A style called \"%s\" has not been defined" +#~ msgstr "\"%s\" nimeline stiil pole määratud" -msgid "This is a sample message in a sample dialog" -msgstr "See on näidisteade näidisdialoogis" +#~ msgid "\"%s\" is not a valid value for resize attribute" +#~ msgstr "\"%s\" pole sobiv väärtus resize atribuudile" -#, c-format -msgid "Fake menu item %d\n" -msgstr "Võltsitud menüüpunkt %d\n" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized/shaded " +#~ "states" +#~ msgstr "" +#~ "Elemendil <%s> ei peaks olema \"resize\" atribuuti maximized/shaded " +#~ "olekute jaoks" -msgid "Border-only window" -msgstr "Ainult raamiga aken" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized states" +#~ msgstr "" +#~ "Elemendil <%s> ei peaks olema \"resize\" atribuuti maximized oleku jaoks" -msgid "Bar" -msgstr "Riba" +#~ msgid "Style has already been specified for state %s resize %s focus %s" +#~ msgstr "Olekule %s suurusele %s ja fookusele %s on stiil juba määratud" -msgid "Normal Application Window" -msgstr "Tavaline rakenduseaken" +#~ msgid "Style has already been specified for state %s focus %s" +#~ msgstr "Olekule %s ja fookusele %s on stiil juba määratud" -msgid "Dialog Box" -msgstr "Dialoogikast" +#~ msgid "" +#~ "Can't have a two draw_ops for a <piece> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Elemendil <piece> ei saa olla kaks draw_ops'i (teema määras draw_ops " +#~ "atribuudi ja <draw_ops> elemendi või kaks elementi)" -msgid "Modal Dialog Box" -msgstr "Modaalne dialoogikast" +#~ msgid "" +#~ "Can't have a two draw_ops for a <button> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Elemendil <button> ei saa olla kaks draw_ops'i (teema määras draw_ops " +#~ "atribuudi ja <draw_ops> elemendi või kaks elementi)" -msgid "Utility Palette" -msgstr "Rakendite palett" +#~ msgid "" +#~ "Can't have a two draw_ops for a <menu_icon> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Elemendil <menu_icon> ei saa olla kaks draw_ops'i (teema määras draw_ops " +#~ "atribuudi ja <draw_ops> elemendi või kaks elementi)" -msgid "Torn-off Menu" -msgstr "Ärarebitav menüü" +#~ msgid "Bad version specification '%s'" +#~ msgstr "Vigane versioonikirjeldus '%s'" -msgid "Border" -msgstr "Raam" +#~ msgid "" +#~ "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" +#~ "theme-2.xml" +#~ msgstr "" +#~ "\"version\" rekvisiiti pole võimalik kasutada ei failis metacity-theme-1." +#~ "xml ega metacity-theme-2.xml" -msgid "Attached Modal Dialog" -msgstr "Kinnistatud modaaldialoog" +#~ msgid "" +#~ "Theme requires version %s but latest supported theme version is %d.%d" +#~ msgstr "" +#~ "Teema nõuab versiooni %s, kuid viimane toetatud teemaversioon on %d.%d" -#, c-format -msgid "Button layout test %d" -msgstr "Nuppude paigutuse test %d" +#~ msgid "Outermost element in theme must be <metacity_theme> not <%s>" +#~ msgstr "Teema kõige välimine element peab olema <metacity_theme> mitte <%s>" -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g millisekundit kulub ühe akna raami joonistamiseks" +#~ msgid "" +#~ "Element <%s> is not allowed inside a name/author/date/description element" +#~ msgstr "" +#~ "Element <%s> pole elementide name/author/date/description sees lubatud" -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Kasutamine: metacity-theme-viewer [TEEMANIMI]\n" +#~ msgid "Element <%s> is not allowed inside a <constant> element" +#~ msgstr "Element <%s> pole elemendi <constant> sees lubatud" -#, c-format -msgid "Error loading theme: %s\n" -msgstr "Viga teema laadimisel: %s\n" +#~ msgid "" +#~ "Element <%s> is not allowed inside a distance/border/aspect_ratio element" +#~ msgstr "" +#~ "Element <%s> pole elementide distance/border/aspect_ratio sees lubatud" -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "Teema \"%s\" laaditi %g sekundiga\n" +#~ msgid "Element <%s> is not allowed inside a draw operation element" +#~ msgstr "Element <%s> pole joonistusoperatsiooni elemendi sees lubatud" -msgid "Normal Title Font" -msgstr "Tiitli tavasuurusega kirjatüüp" +#~ msgid "Element <%s> is not allowed inside a <%s> element" +#~ msgstr "Element <%s> pole elemendi <%s> sees lubatud" -msgid "Small Title Font" -msgstr "Tiitli väike kirjatüüp" +#~ msgid "No draw_ops provided for frame piece" +#~ msgstr "Raamitükile pole määratud draw_ops" -msgid "Large Title Font" -msgstr "Tiitli suur kirjatüüp" +#~ msgid "No draw_ops provided for button" +#~ msgstr "Nupule pole määratud draw_ops" -msgid "Button Layouts" -msgstr "Nuppude paigutus" +#~ msgid "No text is allowed inside element <%s>" +#~ msgstr "Elemendi <%s> sees pole tekst lubatud" -msgid "Benchmark" -msgstr "Jõudlus" +#~ msgid "<%s> specified twice for this theme" +#~ msgstr "Selle teema jaoks on <%s> määratud kaks korda" -msgid "Window Title Goes Here" -msgstr "Siia tuleb akna pealkiri" +#~ msgid "Failed to find a valid file for theme %s\n" +#~ msgstr "Tõrge %s teema jaoks korrektse faili leidmisel\n" -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"Joonistati %d kaadrit %g kliendi-kella sekundiga (%g millisekundit kaadrile) " -"ja %g sekundiga seinakella järgi, millesse on kaasatud X-serveri " -"ressursikasutus (%g millisekundit kaadrile)\n" +#~ msgid "Usage: %s\n" +#~ msgstr "Kasutamine: %s\n" -msgid "position expression test returned TRUE but set error" -msgstr "asukoha avaldise kontroll tagastas TÕENE, aga määras vea" +#~ msgid "_Windows" +#~ msgstr "_Aknad" -msgid "position expression test returned FALSE but didn't set error" -msgstr "asukoha avaldise kontroll tagastas VÄÄR, aga ei määranud viga" +#~ msgid "_Dialog" +#~ msgstr "_Dialoog" -msgid "Error was expected but none given" -msgstr "Oodati viga, aga ühtegi ei edastatud" +#~ msgid "_Modal dialog" +#~ msgstr "_Modaaldialoog" -#, c-format -msgid "Error %d was expected but %d given" -msgstr "Oodati viga %d, aga edastati viga %d" +#~ msgid "_Utility" +#~ msgstr "_Utiliit" -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "Viga ei oodatud, aga üks edastati: %s" +#~ msgid "_Splashscreen" +#~ msgstr "_Käivitusekraan" -#, c-format -msgid "x value was %d, %d was expected" -msgstr "x väärtus oli %d, oodati väärtust %d" +#~ msgid "_Top dock" +#~ msgstr "Ü_lemine dokk" -#, c-format -msgid "y value was %d, %d was expected" -msgstr "y väärtus oli %d, oodati väärtust %d" +#~ msgid "_Bottom dock" +#~ msgstr "_Alumine dokk" -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "" -"%d koordinaatide avaldis töödeldi %g sekundiga (keskmine %g sekundit)\n" +#~ msgid "_Left dock" +#~ msgstr "_Vasak dokk" + +#~ msgid "_Right dock" +#~ msgstr "_Parem dokk" + +#~ msgid "_All docks" +#~ msgstr "_Kõik dokid" + +#~ msgid "Des_ktop" +#~ msgstr "_Töölaud" + +#~ msgid "Open another one of these windows" +#~ msgstr "Ava neist akendest järgmine" + +#~ msgid "This is a demo button with an 'open' icon" +#~ msgstr "See on näidisnupp koos 'ava' ikooniga" + +#~ msgid "This is a demo button with a 'quit' icon" +#~ msgstr "See on näidisnupp koos 'lõpeta' ikooniga" + +#~ msgid "This is a sample message in a sample dialog" +#~ msgstr "See on näidisteade näidisdialoogis" + +#~ msgid "Fake menu item %d\n" +#~ msgstr "Võltsitud menüüpunkt %d\n" + +#~ msgid "Border-only window" +#~ msgstr "Ainult raamiga aken" + +#~ msgid "Bar" +#~ msgstr "Riba" + +#~ msgid "Normal Application Window" +#~ msgstr "Tavaline rakenduseaken" + +#~ msgid "Dialog Box" +#~ msgstr "Dialoogikast" + +#~ msgid "Modal Dialog Box" +#~ msgstr "Modaalne dialoogikast" + +#~ msgid "Utility Palette" +#~ msgstr "Rakendite palett" + +#~ msgid "Torn-off Menu" +#~ msgstr "Ärarebitav menüü" + +#~ msgid "Border" +#~ msgstr "Raam" + +#~ msgid "Attached Modal Dialog" +#~ msgstr "Kinnistatud modaaldialoog" + +#~ msgid "Button layout test %d" +#~ msgstr "Nuppude paigutuse test %d" + +#~ msgid "%g milliseconds to draw one window frame" +#~ msgstr "%g millisekundit kulub ühe akna raami joonistamiseks" + +#~ msgid "Usage: metacity-theme-viewer [THEMENAME]\n" +#~ msgstr "Kasutamine: metacity-theme-viewer [TEEMANIMI]\n" + +#~ msgid "Error loading theme: %s\n" +#~ msgstr "Viga teema laadimisel: %s\n" + +#~ msgid "Loaded theme \"%s\" in %g seconds\n" +#~ msgstr "Teema \"%s\" laaditi %g sekundiga\n" + +#~ msgid "Normal Title Font" +#~ msgstr "Tiitli tavasuurusega kirjatüüp" + +#~ msgid "Small Title Font" +#~ msgstr "Tiitli väike kirjatüüp" + +#~ msgid "Large Title Font" +#~ msgstr "Tiitli suur kirjatüüp" + +#~ msgid "Button Layouts" +#~ msgstr "Nuppude paigutus" + +#~ msgid "Benchmark" +#~ msgstr "Jõudlus" + +#~ msgid "Window Title Goes Here" +#~ msgstr "Siia tuleb akna pealkiri" + +#~ msgid "" +#~ "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and " +#~ "%g seconds wall clock time including X server resources (%g milliseconds " +#~ "per frame)\n" +#~ msgstr "" +#~ "Joonistati %d kaadrit %g kliendi-kella sekundiga (%g millisekundit " +#~ "kaadrile) ja %g sekundiga seinakella järgi, millesse on kaasatud X-" +#~ "serveri ressursikasutus (%g millisekundit kaadrile)\n" + +#~ msgid "position expression test returned TRUE but set error" +#~ msgstr "asukoha avaldise kontroll tagastas TÕENE, aga määras vea" + +#~ msgid "position expression test returned FALSE but didn't set error" +#~ msgstr "asukoha avaldise kontroll tagastas VÄÄR, aga ei määranud viga" + +#~ msgid "Error was expected but none given" +#~ msgstr "Oodati viga, aga ühtegi ei edastatud" + +#~ msgid "Error %d was expected but %d given" +#~ msgstr "Oodati viga %d, aga edastati viga %d" + +#~ msgid "Error not expected but one was returned: %s" +#~ msgstr "Viga ei oodatud, aga üks edastati: %s" + +#~ msgid "x value was %d, %d was expected" +#~ msgstr "x väärtus oli %d, oodati väärtust %d" + +#~ msgid "y value was %d, %d was expected" +#~ msgstr "y väärtus oli %d, oodati väärtust %d" + +#~ msgid "" +#~ "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" +#~ msgstr "" +#~ "%d koordinaatide avaldis töödeldi %g sekundiga (keskmine %g sekundit)\n" + +#~ msgid "Minimize window" +#~ msgstr "Akna minimeerimine" diff --git a/po/eu.po b/po/eu.po index f226c594b..bd8f3b356 100644 --- a/po/eu.po +++ b/po/eu.po @@ -1,1910 +1,698 @@ -# translation of eu.po to Basque +# Basque translation of mutter. # This file is distributed under the same license as the PACKAGE package. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER. # # Hizkuntza Politikarako Sailburuordetza <hizpol@ej-gv.es>, 2004. -# Iñaki Larrañaga Murgoitio <dooteo@euskalgnu.org>, 2004, 2005, 2006, 2008, 2009, 2010, 2011, 2012. -# Iñaki Larrañaga Murgoitio <dooteo@zundan.com>, 2007. +# Iñaki Larrañaga Murgoitio <dooteo@zundan.com>, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011. +# Iñaki Larrañaga Murgoitio <dooteo@zundan.com>, 2012, 2013, 2014, 2015, 2016, 2017. +# Asier Sarasua Garmendia <asier.sarasua@gmail.com>, 2019, 2020. +# msgid "" -msgstr "" -"Project-Id-Version: eu\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-03-06 12:02+0100\n" -"PO-Revision-Date: 2012-03-06 12:44+0100\n" -"Last-Translator: Iñaki Larrañaga Murgoitio <dooteo@euskalgnu.org>\n" -"Language-Team: American English <itzulpena@euskalgnu.org>\n" -"Language: \n" +msgstr "Project-Id-Version: mutter master\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2020-02-23 17:41+0000\n" +"PO-Revision-Date: 2020-02-24 10:00+0100\n" +"Last-Translator: Asier Sarasua Garmendia <asier.sarasua@gmail.com>\n" +"Language-Team: Basque <librezale@librezale.eus>\n" +"Language: eu\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Lokalize 1.0\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -"\n" -"\n" -"\n" -#: ../src/50-muffin-windows.xml.in.h:1 -msgid "View split on left" -msgstr "Ikusi zatia ezkerrean" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Nabigazioa" -#: ../src/50-muffin-windows.xml.in.h:2 -msgid "View split on right" -msgstr "Ikusi zatia eskuinean" +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Eraman leihoa 1. laneko areara" -#: ../src/50-muffin-windows.xml.in.h:3 -msgid "Windows" -msgstr "Leihoak" +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Eraman leihoa 2. laneko areara" -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format -msgid "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." -msgstr "" -"Dagoeneko beste konposatze-kudeatzailea ari da exekutatzen \"%2$s\" " -"pantailako %1$i. monitorean \"." +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Eraman leihoa 3. laneko areara" -#: ../src/core/bell.c:307 -msgid "Bell event" -msgstr "Soinuaren gertaera" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Eraman leihoa 4. laneko areara" -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Leihoaren informazio eskaera ezezaguna: %d" +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Eraman leihoa azkeneko laneko areara" -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt>(e)k ez du erantzuten." +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "Eraman leihoa laneko area bat gora" -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "Aplikazioak ez du erantzuten." +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "Eraman leihoa laneko area bat behera" -#: ../src/core/delete.c:119 -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "" -"Aukeratu piskatean zai egotea aplikazioak jarraitzeko edo derrigortu " -"aplikazioa erabat ixtea." +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "Eraman leihoa monitore bat ezkerrera" -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "_Itxaron" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "Eraman leihoa monitore bat eskuinera" -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "_Behartu ixtera" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "Eraman leihoa monitore bat gora" -#: ../src/core/display.c:361 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "Konposaketa lantzeko beharrezkoa den %s hedapena falta da" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "Eraman leihoa monitore bat behera" -#: ../src/core/display.c:427 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Huts egin du X Window sistemaren '%s' pantaila irekitzean\n" +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "Aldatu aplikazioz" -#: ../src/core/keybindings.c:852 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "" -"Beste programaren batek erabiltzen du %s gakoa %x aldatzaileekin lotura " -"gisa\n" +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "Aldatu aurreko aplikaziora" -#: ../src/core/main.c:206 -msgid "Disable connection to session manager" -msgstr "Desgaitu saio-kudeatzailearen konexioa" +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "Aldatu leihoz" -#: ../src/core/main.c:212 -msgid "Replace the running window manager" -msgstr "Ordeztu exekutatzen dagoen leiho-kudeatzailea" +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "Aldatu aurreko leihora" -#: ../src/core/main.c:218 -msgid "Specify session management ID" -msgstr "Zehaztu saio-kudeatzailearen IDa" +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "Aldatu aplikazio baten leihoen artean" -#: ../src/core/main.c:223 -msgid "X Display to use" -msgstr "X pantaila erabiltzeko" +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "Aldatu aplikazio baten aurreko leihora" -#: ../src/core/main.c:229 -msgid "Initialize session from savefile" -msgstr "Hasieratu saioa babes-fitxategitik" +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "Aldatu sistemaren kontrolak" -#: ../src/core/main.c:235 -msgid "Make X calls synchronous" -msgstr "Egin X deiak sinkronoak izatea" +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "Aldatu aurreko sistemaren kontrolera" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Huts egin du gaien direktorioa aztertzean: %s\n" +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "Aldatu leihoa zuzenean" -#: ../src/core/main.c:520 -#, c-format -msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "" -"Gai bat ezin izan da aurkitu. Ziurtatu %s badagoela eta ohiko gaiak " -"dituela.\n" +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "Aldatu zuzenean aurreko leihora" -#: ../src/core/muffin.c:40 -#, c-format -msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" -"muffin %s\n" -"Copyright-a (C) 2001-%d Havoc Pennington, Red Hat, Inc., eta beste batzuk\n" -"Hau software librea da; ikus kopiatzeko baldintzak iturburu-kodean.\n" -"EZ du bermerik; ezta MERKATURATZEKO edo XEDE JAKIN BATERAKO EGOKITASUNAREN " -"BERMERIK ERE.\n" +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "Aldatu aplikazio baten leihoa zuzenean" -#: ../src/core/muffin.c:54 -msgid "Print version" -msgstr "Erakutsi bertsioa" +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "Aldatu zuzenean aplik. baten aurreko leihora" -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "Konpositoreen pluginen komaz bereiztutako zerrenda" +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "Aldatu sistemaren kontrolak zuzenean" -#: ../src/core/prefs.c:1069 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"Aplikazio hautsien konponbidea desgaituta. Aplikazio batzuk ez dira behar " -"den bezala ibiliko.\n" +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "Aldatu zuzenean aurreko sistemaren kontrolera" -#: ../src/core/prefs.c:1144 -#, c-format -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "" -"Ezin izan da \"%s\" letra-tipoaren deskribapena analizatu GSettings-eko %s " -"gakoan\n" +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "Ezkutatu leiho arrunt guztiak" -#: ../src/core/prefs.c:1210 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"Konfigurazioaren datu-basean aurkitutako \"%s\" balioa ez da baliozkoa sagu-" -"botoiaren aldatzailearentzat\n" +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "Aldatu 1. laneko areara" -#: ../src/core/prefs.c:1722 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "" -"Konfigurazioaren datu-basean aurkitutako \"%s\" balioa ez da baliozkoa \"%s" -"\" laster-teklarentzat.\n" +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "Aldatu 2. laneko areara" -#: ../src/core/prefs.c:1819 -#, c-format -msgid "Workspace %d" -msgstr "%d. laneko area" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "Aldatu 3. laneko areara" -#: ../src/core/screen.c:730 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "'%2$s' bistaratzeko %1$d pantaila ez da baliozkoa\n" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "Aldatu 4. laneko areara" -#: ../src/core/screen.c:746 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"\"%2$s\" bistaratzeko %1$d pantailak badu leiho-kudeatzailea; leiho-" -"kudeatzaile hori ordeztu nahi baduzu, saiatu --replace aukerarekin.\n" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "Aldatu azkeneko laneko areara" -#: ../src/core/screen.c:773 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "" -"Ezin izan da eskuratu leiho-kudeatzailearen hautapena \"%2$s\" bistaratzeko " -"%1$d pantailan\n" +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "Eraman gaineko laneko areara" -#: ../src/core/screen.c:828 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "\"%2$s\" bistaratzeko %1$d pantailak badu leiho-kudeatzailea\n" +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "Eraman azpiko laneko areara" -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "Ezin izan da askatu \"%2$s\" bistaratzeko %1$d pantaila\n" +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "Sistema" -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Ezin izan da '%s' direktorioa sortu: %s\n" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Erakutsi gonbitea komandoa exekutatzeko" -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "Ezin izan da '%s' saio-fitxategia idazteko ireki: %s\n" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Erakutsi jardueren aurkezpen orokorra" -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Errorea '%s' saio-fitxategia idaztean: %s\n" +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Leheneratu laster-teklak" -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Errorea '%s' saio-fitxategia ixtean: %s\n" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Leihoak" -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Huts egin du gordetako saio-fitxategia analizatzean: %s\n" +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "Aktibatu leiho-menua" -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "<muffin_session> atributua ikusi da baina dagoeneko badugu saio-IDa" +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Txandakatu pantaila osoaren modua" -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "%s atributu ezezaguna <%s> elementuan" +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "Txandakatu maximizatze-egoera" -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "<window> etiketa habiaratua" +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "Maximizatu leihoa" -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "%s elementu ezezaguna" +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Leheneratu leihoa" -#: ../src/core/session.c:1809 -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" -"Leiho hauek ez dute onartzen "gorde uneko konfigurazioa" eta eskuz " -"berrabiarazi beharko dituzu hurrengo saioa hasten duzunean." +#: data/50-mutter-windows.xml:18 +msgid "Close window" +msgstr "Itxi leihoa" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Huts egin du arazketako egunkaria irekitzean: %s\n" +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "Ezkutatu leihoa" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Huts egin du %s egunkari-fitxategian fdopen() egitean: %s\n" +#: data/50-mutter-windows.xml:22 +msgid "Move window" +msgstr "Aldatu leihoa lekuz" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "%s egunkari-fitxategia irekita\n" +#: data/50-mutter-windows.xml:24 +msgid "Resize window" +msgstr "Aldatu leihoaren tamaina" -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "Muffin modu xehatuaren euskarririk gabe konpilatu da\n" +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "Txandakatu leihoa laneko area guztietan edo bakar batean egotea" -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "Leiho-kudeatzailea: " +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "Goratu leihoa beste leiho batek estaltzen badu, bestela beheratu" -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "Akatsa leiho-kudeatzailean: " +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "Goratu leihoa beste leihoen gainera" -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "Leiho-kudeatzailearen abisua: " +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "Beheratu leihoa beste leihoen azpira" -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "Leiho-kudeatzailearen errorea: " +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "Maximizatu leihoa bertikalean" -#. first time through -#: ../src/core/window.c:7224 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"%s leihoak bere buruari ezartzen dio SM_CLIENT_ID, WM_CLIENT_LEADER leihoari " -"ezarri beharren, ICCCMan zehaztuta dagoen moduan.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7887 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size " -"%d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"%s leihoak MWM aholkua ezartzen du, tamainarik ezin zaiola aldatu " -"adierazteko, baina aldi berean gutxieneko tamaina (%d x %d) eta gehienezkoa " -"(%d x %d) ezartzen ditu, eta horrek ez du zentzu handirik.\n" - -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "Aplikazioak _NET_WM_PID %lu faltsua ezarri du\n" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "Maximizatu leihoa horizontalean" -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (%s)" +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "Ikusi zatia ezkerrean" -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "%2$s(e)n baliogabeko WM_TRANSIENT_FOR 0x%1$lx leihoa zehaztu da.\n" +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "Ikusi zatia eskuinean" -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "%2$s(e)n WM_TRANSIENT_FOR 0x%1$lx leihoak begizta sor dezake.\n" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"0x%lx leihoak %s propietatea du\n" -"horrek %s mota %d formatua izatea espero zen\n" -"baina %s mota %d formatua %d n_items du.\n" -"Gehiago ematen du aplikazioaren akatsa leiho-kudeatzailearena baino.\n" -"Leihoak title=\"%s\" class=\"%s\" name=\"%s\" du\n" - -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "0x%2$lx leihoko %1$s propietateak UTF-8 baliogabea du\n" +#: data/org.gnome.mutter.gschema.xml.in:7 +msgid "Modifier to use for extended window management operations" +msgstr "Aldatzailea leihoak kudeatzeko eragiketa hedatuetan erabiltzeko" -#: ../src/core/xprops.c:494 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:8 msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"0x%2$lx leihoko %1$s propietateak UTF-8 baliogabea du zerrendako %3$d. " -"elementuan\n" - -#: ../src/muffin.desktop.in.h:1 ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." +msgstr "Gako honek “overlay” (gainjarria) hasieratuko du: hau leihoaren ikuspegi orokorraren eta aplikazioa abiarazteko sistemaren arteko konbinazioa da. Lehenetsi gisa, PC ordenagailuko “Windows tekla” da. Tekla konbinazio hau lehenetsia izatea edo kate huts gisa ezartzea da." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 +#: data/org.gnome.mutter.gschema.xml.in:20 msgid "Attach modal dialogs" msgstr "Erantsi elkarrizketa-koadro modala" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 -msgid "Cancel tab popup" -msgstr "Utzi laster-fitxa" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"Ezkutuko leihoak (adib. ikonotutakoak, beste laneko arekoak) bizirik iraungo " -"diren edo ez zehazten du." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 -msgid "" -"Determines whether the use of popup and highlight frame should be disabled " -"for window cycling." -msgstr "" -"Leihoen artean aldatzean laster-leiho eta nabarmentzeko markoen " -"erabilpena desgaitu behar den edo ez zehazten du." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 +#: data/org.gnome.mutter.gschema.xml.in:21 msgid "" -"Determines whether workspace switching should happen for windows on all " -"monitors or only for windows on the primary monitor." -msgstr "" -"Laneko areaz aldatzean pantaila guztietako leihoei eragingo dien edo " -"pantaila nagusiko leihoei soilik zehazten du." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 -msgid "Draggable border width" -msgstr "Ertz arrastragarriaren zabalera" +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." +msgstr "True (egia) bada, titulu-barra independenteak eduki ordez, elkarrizketa-koadro modalak agertuko dira leiho gurasoko titulu-barrari erantsita eta leiho gurasoarekin batera mugituko dira." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 +#: data/org.gnome.mutter.gschema.xml.in:30 msgid "Enable edge tiling when dropping windows on screen edges" -msgstr "Ertzeko lauza gaitzea pantailaren ertzetan leihoak jaregitean " +msgstr "Gaitu lauzatzea leihoak pantailaren ertzetan jaregitean" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 +#: data/org.gnome.mutter.gschema.xml.in:31 msgid "" "If enabled, dropping windows on vertical screen edges maximizes them " "vertically and resizes them horizontally to cover half of the available " "area. Dropping windows on the top screen edge maximizes them completely." -msgstr "" -"Gaituta egonez gero, pantailaren ertz bertikaletan leihoak jaregiteak hauek " -"bertikalki maximizatuko dira, eta horizontalki tamainaz aldatuko dira " -"area erabilgarriaren erdia estaltzeko. Pantailaren goiko ertzean leihoak " -"jaregitean, hauek erabat maximizatuko dira." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 -msgid "Live Hidden Windows" -msgstr "Ezkutuko leihoak bizirik" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 -msgid "Modifier to use for extended window management operations" -msgstr "Aldatzailea leihoak kudeatzeko eragiketa hedatuetan erabiltzeko" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 -msgid "No tab popup" -msgstr "Laster-fitxarik ez" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 -msgid "Select window from tab popup" -msgstr "Hautatu leihoa laster-fitxatik" +msgstr "Gaituta egonez gero, pantailaren ertz bertikaletan leihoak jaregiteak hauek bertikalean maximizatuko dira, eta horizontalean tamainaz aldatuko dira area erabilgarriaren erdia estaltzeko. Pantailaren goiko ertzean leihoak jaregitean, hauek erabat maximizatuko dira." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 -msgid "" -"The amount of total draggable borders. If the theme's visible borders are " -"not enough, invisible borders will be added to meet this value." -msgstr "" -"Ertz arrastragarri guztien kopurua. Gaiaren ertz ikusgaiak ez badira " -"nahikoak, ertz ikusezinak gehituko dira balio honekin bat etortzeko." +#: data/org.gnome.mutter.gschema.xml.in:40 +msgid "Workspaces are managed dynamically" +msgstr "Laneko areak dinamikoki kudeatzen dira" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 -msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." -msgstr "" -"Gako honek \"overlay\" (gainjarria) hasieratuko du: hau leihoaren ikuspegi " -"orokorraren eta aplikazioa abiarazteko sistemaren arteko konbinazioa da. " -"Lehenetsi gisa, PC ordenagailuko \"Windows tekla\" da. Tekla konbinazio hau " -"lehenetsia izatea edo kate hutz gisa ezartzea da." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 +#: data/org.gnome.mutter.gschema.xml.in:41 msgid "" -"When true, instead of having independent titlebars, modal dialogs appear " -"attached to the titlebar of the parent window and are moved together with " -"the parent window." -msgstr "" -"True (egia) bada, titulu-barra independenteak eduki ordez, elkarrizketa-" -"koadro modalak agertuko dira leiho gurasoko titulu-barrari erantsita eta " -"leiho gurasoarekin batera mugituko dira." +"Determines whether workspaces are managed dynamically or whether there’s a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." +msgstr "Laneko areak dinamikoki kudeatzen diren edo laneko areak kopuru estatikoa (“org.gnome.desktop.wm.preferences“-eko “num-workspaces” gakoak zehazten du) daukan zehazten du ." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 +#: data/org.gnome.mutter.gschema.xml.in:50 msgid "Workspaces only on primary" msgstr "Laneko areak soilik nagusian" -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "Erabilera: %s\n" +#: data/org.gnome.mutter.gschema.xml.in:51 +msgid "" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." +msgstr "Laneko areaz aldatzean pantaila guztietako leihoei eragingo dien edo pantaila nagusiko leihoei soilik zehazten du." -#: ../src/ui/frames.c:1157 -msgid "Close Window" -msgstr "Itxi leihoa" +#: data/org.gnome.mutter.gschema.xml.in:59 +msgid "No tab popup" +msgstr "Laster-fitxarik ez" -#: ../src/ui/frames.c:1160 -msgid "Window Menu" -msgstr "Leiho-menua" +#: data/org.gnome.mutter.gschema.xml.in:60 +msgid "" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." +msgstr "Leihoen artean aldatzean laster-leiho eta nabarmentzeko markoen erabilpena desgaitu behar den edo ez zehazten du." -#: ../src/ui/frames.c:1163 -msgid "Minimize Window" -msgstr "Ikonotu leihoa" +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Atzeratu fokuaren aldaketa erakuslea mugitzeari utzi arte" -#: ../src/ui/frames.c:1166 -msgid "Maximize Window" -msgstr "Maximizatu leihoa" +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "TRUE (egia) gisa ezartzen bada, eta fokuaren modua “sloppy” edo “mouse” bada, fokua ez da berehala aldatuko leiho batean sartzean baizik eta soilik erakuslea gelditzean." -#: ../src/ui/frames.c:1169 -msgid "Restore Window" -msgstr "Leheneratu leihoa" +#: data/org.gnome.mutter.gschema.xml.in:79 +msgid "Draggable border width" +msgstr "Ertz arrastragarriaren zabalera" -#: ../src/ui/frames.c:1172 -msgid "Roll Up Window" -msgstr "Bildu leihoa" - -#: ../src/ui/frames.c:1175 -msgid "Unroll Window" -msgstr "Zabaldu leihoa" - -#: ../src/ui/frames.c:1178 -msgid "Keep Window On Top" -msgstr "Mantendu leihoa gainean" - -#: ../src/ui/frames.c:1181 -msgid "Remove Window From Top" -msgstr "Kendu leihoa gainetik" - -#: ../src/ui/frames.c:1184 -msgid "Always On Visible Workspace" -msgstr "Beti laneko area ikusgaian" - -#: ../src/ui/frames.c:1187 -msgid "Put Window On Only One Workspace" -msgstr "Jarri leihoa laneko area bakar batean" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "_Ikonotu" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "_Maximizatu" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "Desma_ximizatu" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "_Bildu" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "_Zabaldu" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "Aldatu _lekuz" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "Aldatu _tamaina" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "Eraman titulu-barra p_antailara" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "Beti _goian" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "Laneko area ikusgaian _beti" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "Laneko area _honetan bakarrik" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "Eraman e_zkerreko laneko areara" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "Eraman e_skuineko laneko areara" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "Eraman _gaineko laneko areara" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "Eraman _azpiko laneko areara" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "It_xi" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "%d.%n laneko area" +#: data/org.gnome.mutter.gschema.xml.in:80 +msgid "" +"The amount of total draggable borders. If the theme’s visible borders are " +"not enough, invisible borders will be added to meet this value." +msgstr "Ertz arrastragarri guztien kopurua. Gaiaren ertz ikusgaiak ez badira nahikoak, ertz ikusezinak gehituko dira balio honekin bat etortzeko." -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "1_0 laneko area" +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "Maximizatu automatikoki monitorearen tamainaren gertuko leihoak" -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "%s%d laneko area" +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "Gaituta badago, ia monitorearen tamainara iristen diren leiho berriak automatikoki maximizatuko ditu." -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "Eraman beste laneko areara" +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Jarri leiho berriak zentroan" -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Maius" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ktrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hiper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Ald2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Ald3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Ald4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Ald5" +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "TRUE (egia) denean, leiho berriak beti jarriko dira monitorearen pantaila aktiboaren zentroan." -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Gaitu eginbide esperimentalak" -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "goian" +#: data/org.gnome.mutter.gschema.xml.in:108 +msgid "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes " +"mutter request a low priority real-time scheduling. The executable or user " +"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — " +"initializes Xwayland lazily if there are X11 clients. Requires restart." +msgstr "Eginbide esperimentalak gaitzeko, gehitu eginbidearen gako-hitza zerrendari. Eginbideak konposatzailea berrabiaraztea behar duen edo ez, emandako eginbidearen araberakoa da. Ez da derrigorrezkoa edozein eginbide esperimental eskuragarri edo konfiguragarri egotea. Ez uste ezarpen honetan edozer gehitzeak etorkizuneko proba izango denik. Uneko gako erabilgarriak: • “scale-monitor-framebuffer” — honek mutterrek monitore logikoak espazioaren koordenatuko pixel logikoetan diseina dezan eragiten du, leihoaren edukiaren ordez monitorearen framebufferra eskalatuta, HiDPI monitoreak kudeatzeko. Ez du berrabiaraztea eskatzen. • “rt-scheduler” — muterrek lehentasun baxuko denbora errealeko programazioa eska dezan eragiten du. Exekutagarriak edo erabiltzaileak CAP_SYS_NICE izan behar du. Sistema berrabiarazi behar da. • “autostart-xwayland” — Xwayland modu alferrean hasieratzen du X11 bezeroak badaude. Sistema berrabiarazi behar da." -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "behean" +#: data/org.gnome.mutter.gschema.xml.in:134 +msgid "Modifier to use to locate the pointer" +msgstr "Erakuslea kokatzeko erabiliko den aldatzailea" -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "ezkerrean" +#: data/org.gnome.mutter.gschema.xml.in:135 +msgid "This key will initiate the “locate pointer” action." +msgstr "Gako honek “kokatu erakuslea” ekintza abiarazten du." -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "eskuinean" +#: data/org.gnome.mutter.gschema.xml.in:142 +msgid "Timeout for check-alive ping" +msgstr "Bizirik egotearen ping-aren denbora-muga" -#: ../src/ui/theme.c:286 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "marko-geometriak ez du zehazten \"%s\" neurririk" +#: data/org.gnome.mutter.gschema.xml.in:143 +msgid "" +"Number of milliseconds a client has to respond to a ping request in order to " +"not be detected as frozen. Using 0 will disable the alive check completely." +msgstr "Bezero batek ping eskari bati erantzuteko duen milisegundo kopurua, izoztutzat hartu baino lehen. Erabiltzen den balioa 0 bada, bizirik egotearen egiaztatzea erabat desgaituko da." -#: ../src/ui/theme.c:305 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "marko-geometriak ez du zehazten \"%s\" neurririk \"%s\" ertzerako" +#: data/org.gnome.mutter.gschema.xml.in:165 +msgid "Select window from tab popup" +msgstr "Hautatu leihoa laster-fitxatik" -#: ../src/ui/theme.c:342 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "Botoiaren %g aspektu-erlazioa ez da arrazoizkoa" +#: data/org.gnome.mutter.gschema.xml.in:170 +msgid "Cancel tab popup" +msgstr "Utzi laster-fitxa" -#: ../src/ui/theme.c:354 +#: data/org.gnome.mutter.gschema.xml.in:175 +msgid "Switch monitor configurations" +msgstr "Aldatu monitorearen konfigurazioak" + +#: data/org.gnome.mutter.gschema.xml.in:180 +msgid "Rotates the built-in monitor configuration" +msgstr "Biratu barneko monitorearen konfigurazioa" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Aldatu 1. TBra" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Aldatu 2. TBra" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Aldatu 3. TBra" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Aldatu 4. TBra" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Aldatu 5. TBra" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Aldatu 6. TBra" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Aldatu 7. TBra" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Aldatu 8. TBra" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Aldatu 9. TBra" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Aldatu 10. TBra" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Aldatu 11. TBra" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Aldatu 12. TBra" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "Gaitu berriro laster-teklak" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow X11 grabs to lock keyboard focus with Xwayland" +msgstr "Baimendu X11 kapturak teklatu-fokua blokeatzeko Xwayland-ekin" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 +msgid "" +"Allow all keyboard events to be routed to X11 “override redirect” windows " +"with a grab when running in Xwayland. This option is to support X11 clients " +"which map an “override redirect” window (which do not receive keyboard " +"focus) and issue a keyboard grab to force all keyboard events to that " +"window. This option is seldom used and has no effect on regular X11 windows " +"which can receive keyboard focus under normal circumstances. For a X11 grab " +"to be taken into account under Wayland, the client must also either send a " +"specific X11 ClientMessage to the root window or be among the applications " +"white-listed in key “xwayland-grab-access-rules”." +msgstr "Onartu teklatu-gertaera guztiak X11 “override redirect” leihoetara bidera daitezen Xwayland-en exekutatzean. Aukera honek “override redirect” leiho bat (teklatu-fokua jasotzen ez duena) mapatzen duten eta teklatu-gertaera guztiak leiho horretara behartzen dituen teklatu-harrapatze bat bidaltzen duten X11 bezeroei euskarria emateko da. Aukera hori gutxitan erabiltzen da eta ez du eraginik X11 leiho arruntetan, horiek teklatuaren fokua modu normalean jasotzen baitute. X11 harrapatze bat Wayland pean kontuan har dadin, bezeroak ere X11 ClientMessage mezu espezifiko bat bidali behar dio erro-leihoari edo “xwayland-grab-access-rules” gakoaren zerrenda zurian dauden aplikazioen artean egon behar du." + +#: data/org.gnome.mutter.wayland.gschema.xml.in:84 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "Teklatu-kapturak bidaltzeko baimena duten Xwayland aplikazioak" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:85 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "Zerrendatu Xwayland pean X11 teklatu-kapturak bidaltzea onartuta duten edo ez duten X11 leihoen baliabide-izenak edo baliabide-klaseak. X11 leiho baten baliabide-izena edo baliabide-klasea “xprop WM_CLASS” komandoa erabilita eskuratu daiteke. “*” eta “?” komodinak onartzen diren balioetan. Hasieran “!” duten balioak zerrenda beltzean sartuta daude, eta horrek lehentasuna du zerrenda zuriaren aurretik sistema-zerrenda lehenetsiko aplikazioak bertan behera uzteko. Sistema-zerrenda lehenetsiak honako aplikazioak ditu: “@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Erabiltzaileek edozein kaptura hautsi dezakete “restore-shortcuts” lotura-teklan definitutako lasterbideak erabilita." + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. +#. +#: src/backends/meta-input-settings.c:2567 #, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "Marko-geometriak ez du zehazten botoien tamainarik" +msgid "Mode Switch (Group %d)" +msgstr "Modu aldaketa (%d taldea)" -#: ../src/ui/theme.c:1067 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "Gradienteek bi kolore izan behar dituzte gutxienez" +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2590 +msgid "Switch monitor" +msgstr "Aldatu monitorea" -#: ../src/ui/theme.c:1219 -#, c-format -msgid "" -"GTK custom color specification must have color name and fallback in " -"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" -msgstr "" -"GTK kolore-zehaztapen pertsonalizatuak kolore-izena eduki behar du " -"atzeradeia kortxeteetan, adib. gtk:custom[foo.bar]; \"%s\" ezin da analizatu" +#: src/backends/meta-input-settings.c:2592 +msgid "Show on-screen help" +msgstr "Erakutsi pantailako laguntzan" -#: ../src/ui/theme.c:1235 -#, c-format -msgid "" -"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" -"_ are valid" -msgstr "" -"'%c' karaktere baliogabea gtk:custom-en kolore-izena parametroan. Soilik A-" -"Za-z0-9-_ dira baliozkoak" +#: src/backends/meta-monitor.c:223 +msgid "Built-in display" +msgstr "Bertako pantaila" -#: ../src/ui/theme.c:1249 -#, c-format -msgid "" -"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " -"fit the format" -msgstr "" -"Gtk:custom-en formatua \"gtk:custom(kolore-izena, atzeradeia)\" da. \"%s\" " -"ez dator bat formatuarekin" +#: src/backends/meta-monitor.c:252 +msgid "Unknown" +msgstr "Ezezaguna" -#: ../src/ui/theme.c:1294 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"GTK kolore-zehaztapenak egoera kortxete artean izan behar du, adib. gtk:fg" -"[NORMAL], NORMAL egoera izanik; \"%s\" ezin da analizatu" +#: src/backends/meta-monitor.c:254 +msgid "Unknown Display" +msgstr "Pantaila ezezaguna" -#: ../src/ui/theme.c:1308 +#: src/backends/meta-monitor.c:262 #, c-format -msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"GTK kolore-zehaztapenak ixteko kortxetea izan behar egoeraren ondoren, adib. " -"gtk:fg[NORMAL], NORMAL egoera izanik; \"%s\" ezin da analizatu" +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme.c:1319 +#: src/backends/meta-monitor.c:270 #, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "Ez da ulertu \"%s\" egoera kolore-zehaztapenean" +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme.c:1332 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "Ez da ulertu \"%s\" kolore-osagaia kolore-zehaztapenean" +#. Translators: this string will appear in Sysprof +#: src/backends/meta-profiler.c:79 +msgid "Compositor" +msgstr "Konposatzailea" -#: ../src/ui/theme.c:1361 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:533 #, c-format msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" -msgstr "" -"Nahaste-formatua \"blend/bg_color/fg_color/alpha\" da, \"%s\" ez dator bat " -"formatuarekin" +"Another compositing manager is already running on screen %i on display “%s”." +msgstr "Dagoeneko beste konposatze-kudeatzailea ari da exekutatzen “%2$s” pantailako %1$i. monitorean." -#: ../src/ui/theme.c:1372 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "Ezin da analizatu \"%s\" alfa balioa kolore nahastuan" +#: src/core/bell.c:192 +msgid "Bell event" +msgstr "Soinuaren gertaera" -#: ../src/ui/theme.c:1382 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "Kolore nahastuko \"%s\" alfa balioa ez dago 0,0 eta 1,0 artean" +#: src/core/main.c:190 +msgid "Disable connection to session manager" +msgstr "Desgaitu saio-kudeatzailearen konexioa" -#: ../src/ui/theme.c:1429 -#, c-format -msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "" -"Itzal-faktorea \"shade/base_color/factor\" da, \"%s\" ez dator bat " -"formatuarekin" +#: src/core/main.c:196 +msgid "Replace the running window manager" +msgstr "Ordeztu exekutatzen dagoen leiho-kudeatzailea" -#: ../src/ui/theme.c:1440 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "Ezin da analizatu \"%s\" itzal-faktorea itzaldun kolorean" +#: src/core/main.c:202 +msgid "Specify session management ID" +msgstr "Zehaztu saio-kudeatzailearen IDa" -#: ../src/ui/theme.c:1450 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "Itzaldun koloreko \"%s\" itzal-faktorea negatiboa da" +#: src/core/main.c:207 +msgid "X Display to use" +msgstr "X pantaila erabiltzeko" -#: ../src/ui/theme.c:1479 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Ezin izan da \"%s\" kolorea analizatu" +#: src/core/main.c:213 +msgid "Initialize session from savefile" +msgstr "Hasieratu saioa babes-fitxategitik" -#: ../src/ui/theme.c:1790 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "" -"Koordenatuen adierazpenak '%s' karakterea dauka, eta hori ez da onartzen" +#: src/core/main.c:219 +msgid "Make X calls synchronous" +msgstr "Bihurtu X dei sinkroniko" -#: ../src/ui/theme.c:1817 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "" -"Koordenatuen adierazpenak '%s' koma mugikorreko zenbakia dauka, eta ezin da " -"analizatu" +#: src/core/main.c:226 +msgid "Run as a wayland compositor" +msgstr "Exekutatu wayland konposatzaile gisa" -#: ../src/ui/theme.c:1831 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "" -"Koordenatuen adierazpenak '%s' osoko zenbakia dauka, eta ezin da analizatu" +#: src/core/main.c:232 +msgid "Run as a nested compositor" +msgstr "Exekutatu habiaratutako konposatzaile gisa" -#: ../src/ui/theme.c:1953 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "" -"Koordenatuen adierazpenak eragile ezezaguna dauka testu honen hasieran: \"%s" -"\"" +#: src/core/main.c:238 +msgid "Run wayland compositor without starting Xwayland" +msgstr "Exekutatu waylan konposatzailea Xwayland abiarazi gabe" -#: ../src/ui/theme.c:2010 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "Koordenatuen adierazpena hutsik dago edo ez da ulertu" +#: src/core/main.c:246 +msgid "Run as a full display server, rather than nested" +msgstr "Exekutatu pantaila-zerbitzari oso bezala, habiaratuta baino" -#: ../src/ui/theme.c:2121 ../src/ui/theme.c:2131 ../src/ui/theme.c:2165 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "Koordenatuen adierazpenak zero zatitzaileko zatiketa ematen du" +#: src/core/main.c:252 +msgid "Run with X11 backend" +msgstr "Exekutatu X11 motorra erabilita" -#: ../src/ui/theme.c:2173 +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:151 #, c-format -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "" -"Koordenatuen adierazpena mod eragilea erabiltzen saiatzen da koma " -"mugikorreko zenbaki batean" +msgid "“%s” is not responding." +msgstr "“%s”(e)k ez du erantzuten." -#: ../src/ui/theme.c:2229 -#, c-format +#: src/core/meta-close-dialog-default.c:153 +msgid "Application is not responding." +msgstr "Aplikazioak ez du erantzuten." + +#: src/core/meta-close-dialog-default.c:158 msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "" -"Koordenatuen adierazpenak \"%s\" eragilea du eragigai bat espero zen lekuan" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." +msgstr "Pixka bat itxoitearen edo aplikazioa irtetera derrigortzearen artean aukera dezakezu." -#: ../src/ui/theme.c:2238 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "" -"Koordenatuen adierazpenak eragigai bat du eragile bat espero zen lekuan" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Force Quit" +msgstr "_Behartu ixtera" -#: ../src/ui/theme.c:2246 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "" -"Koordenatuen adierazpena eragile batez amaitzen da, eragigai batez amaitu " -"beharrean" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Wait" +msgstr "_Itxaron" -#: ../src/ui/theme.c:2256 +#: src/core/mutter.c:38 #, c-format msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" -"Koordenatuen adierazpenak \"%c\" eragilea du \"%c\" eragilearen ondoren, " -"tartean eragigairik gabe" - -#: ../src/ui/theme.c:2407 ../src/ui/theme.c:2452 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "Koordenatuen adierazpenak \"%s\" aldagai edo konstante ezezaguna du" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" +msgstr "mutter %s\n" +"Copyright-a © 2001-%d Havoc Pennington, Red Hat, Inc., eta beste batzuk\n" +"Hau software librea da; ikus kopiatzeko baldintzak iturburu-kodean.\n" +"EZ du bermerik; ezta MERKATURATZEKO edo XEDE JAKIN BATERAKO EGOKITASUNAREN BERMERIK ERE.\n" -#: ../src/ui/theme.c:2506 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "" -"Koordenatuen adierazpenaren analizatzaileak bere bufferra gainezkatu du" +#: src/core/mutter.c:52 +msgid "Print version" +msgstr "Bistaratu bertsioa" -#: ../src/ui/theme.c:2535 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "" -"Koordenatuen adierazpenak ixteko parentesi bat du, baina irekitzekoa falta da" +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "Mutter-en osagaia erabiltzeko" -#: ../src/ui/theme.c:2599 +#: src/core/prefs.c:1911 #, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "" -"Koordenatuen adierazpenak irekitzeko parentesi bat du, baina ixtekoa falta da" +msgid "Workspace %d" +msgstr "%d. laneko area" -#: ../src/ui/theme.c:2610 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "Koordenatuen adierazpenak ez dirudi eragilerik edo eragigairik duenik" +#: src/core/util.c:122 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter modu xehearen euskarririk gabe konpilatu da\n" -#: ../src/ui/theme.c:2822 ../src/ui/theme.c:2842 ../src/ui/theme.c:2862 +#: src/wayland/meta-wayland-tablet-pad.c:568 #, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "Gaiak errorea ematen duen adierazpen bat dauka: %s\n" +msgid "Mode Switch: Mode %d" +msgstr "Modu aldaketa: %d modua" -#: ../src/ui/theme.c:4533 +#: src/x11/meta-x11-display.c:676 #, c-format msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> zehaztu behar " -"da marko-estilo honetan" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." +msgstr "“%s” pantailak badu leiho-kudeatzailea; erabili --replace aukera uneko leiho-kudeatzailea ordezteko." -#: ../src/ui/theme.c:5066 ../src/ui/theme.c:5091 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" -"<frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/> falta da" +#: src/x11/meta-x11-display.c:1089 +msgid "Failed to initialize GDK\n" +msgstr "Huts egin du GDK hasieratzeak\n" -#: ../src/ui/theme.c:5139 +#: src/x11/meta-x11-display.c:1113 #, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Huts egin du \"%s\" gaia kargatzean: %s\n" +msgid "Failed to open X Window System display “%s”\n" +msgstr "Huts egin du X Window sistemaren “%s” pantaila irekitzean\n" -#: ../src/ui/theme.c:5275 ../src/ui/theme.c:5282 ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 ../src/ui/theme.c:5303 +#: src/x11/meta-x11-display.c:1196 #, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "<%s> ez da ezarri \"%s\" gaian" +msgid "Screen %d on display “%s” is invalid\n" +msgstr "“%2$s” bistaratzeko %1$d pantaila ez da baliozkoa\n" -#: ../src/ui/theme.c:5311 +#: src/x11/meta-x11-selection-input-stream.c:460 #, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" -"Ez da marko-estilorik ezarri set \"%s\" leiho-motarentzat \"%s\" gaian, " -"gehitu <window type=\"%s\" style_set=\"whatever\"/> elementu bat" +msgid "Format %s not supported" +msgstr "%s formatua ez da onartzen" -#: ../src/ui/theme.c:5709 ../src/ui/theme.c:5771 ../src/ui/theme.c:5834 -#, c-format +#: src/x11/session.c:1821 msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" -"Erabiltzaileak definitutako konstanteak maiuskulaz hasi behar du; \"%s\" ez " -"da maiuskulaz hasten" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." +msgstr "Leiho hauek ez dute onartzen “gorde uneko konfigurazioa“; eta eskuz berrabiarazi beharko dituzu hurrengo saioa hasten duzunean." -#: ../src/ui/theme.c:5717 ../src/ui/theme.c:5779 ../src/ui/theme.c:5842 +#: src/x11/window-props.c:569 #, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "\"%s\" konstantea lehendik definituta dago" - -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. -#. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "Ez dago \"%s\" atributurik <%s> elementuan" - -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "%d. lerroa %d. karakterea: %s" - -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "\"%s\" atributua birritan errepikatuta <%s> elementu berean" - -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "\"%s\" atributua ez da baliozkoa <%s> elementuaren testuinguru honetan" - -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "Ezin da \"%s\" analizatu osoko gisa" - -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "Ez dira ulertzen amaierako \"%s\" karaktereak \"%s\" katean" - -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "%ld osokoak positiboa izan behar du" - -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "%ld osokoa handiegia da, uneko gehienezkoa %d da" - -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "\"%s\" ezin da analizatu koma mugikorreko zenbaki gisa" - -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "" -"Balio boolearrak \"egiazkoak\" edo \"faltsuak\" izan daitezke, ez \"%s\"" - -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "Angeluak 0.0 eta 360.0 bitartekoa behar du, %g\n" - -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" -"Alfak 0.0 (ikusezina) eta 1.0 (erabat opakoa) artekoa izan behar du, %g\n" - -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"\"%s\" titulu-eskala baliogabea (xx-small,x-small,small,medium,large,x-large," -"xx-large izan behar du)\n" - -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s> \"%s\" izena bigarren aldiz erabili da" - -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "<%s> \"%s\" gurasoa ez da definitu" - -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "<%s> \"%s\" geometria ez da definitu" - -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "<%s>(e)k geometria bat edo geometria duen guraso bat zehaztu behar du" - -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "Atzeko planoa zehaztu alfa balioarekin esanguratsua izateko" - -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "\"%s\" mota ezezaguna <%s> elementuan" - -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "\"%s\" style_set ezezaguna <%s> elementuan" - -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "\"%s\" leiho-motak dagoeneko esleituta du estilo-multzoa" - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "Ez da onartzen <%s> elementua <%s>(r)en azpian jartzea" - -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" -msgstr "" -"\"button_width\"/\"button_height\" (botoi-zabalera/botoi-altuera) eta " -"\"aspect_ratio\" (aspektu-erlazioa) ezin dira batera zehaztu botoietan" - -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "\"%s\" distantzia ezezaguna da" - -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "\"%s\" aspektu-erlazioa ezezaguna da" - -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "\"%s\" ertza ezezaguna da" - -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "Ez dago \"start_angle\" edo \"from\" atributurik <%s> elementuan" - -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "Ez dago \"extent_angle\" edo \"to\" atributurik <%s> elementuan" - -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "Gradiente-motan ez da ulertu \"%s\" balioa" - -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "Ez da ulertu \"%s\" betetze-mota <%s> elementuan" - -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "Ez da ulertu \"%s\" egoera <%s> elementuan" - -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "Ez da ulertu \"%s\" itzala <%s> elementuan" - -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "Ez da ulertu \"%s\" gezia <%s> elementuan" - -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "Ez da \"%s\" izeneko <draw_ops> bat ere definitu" - -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "" -"Hemen \"%s\" draw_ops sartzen bada, erreferentzia zirkularra sortuko da" - -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "\"%s\" kokaleku ezezaguna markoarentzat" - -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "Marko-estiloak badu zati bat %s posizioan" - -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "Ez da \"%s\" izeneko <draw_ops> bat ere definitu" - -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "\"%s\" funtzioa ezezaguna botoiarentzat" - -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "" -"\"%s\" botoi-funtzioa ez da existitzen bertsio honetan (%d, %d behar du)" - -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "\"%s\" egoera ezezaguna botoiarentzat" - -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "Marko-estiloak badu botoi bat %s funtzioan %s egoeran" - -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "\"%s\" ez da baliozko balioa foku-atributuarentzat" - -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "\"%s\" ez da baliozko balioa egoera-atributuarentzat" - -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "\"%s\" izeneko estiloa ez da definitu" - -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "\"%s\" ez da baliozko balioa tamainaz aldatzeko atributuarentzat" - -#: ../src/ui/theme-parser.c:3147 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" -"Ez luke izan behar \"resize\" atributurik <%s> elementuan maximizatutako/" -"bildutako egoerentzat" - -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "" -"Ez luke izan behar \"resize\" atributurik <%s> elementuan maximizatutako " -"egoerentzat" - -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "Estiloa dagoeneko zehaztu da %s egoeran %s tamaina-aldatzean %s fokuan" - -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "Estiloa dagoeneko zehaztu da %s egoeran %s fokuan" - -#: ../src/ui/theme-parser.c:3294 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Ezin dira bi draw_ops izan <piece> elementu batean (gaiak draw_ops atributu " -"bat eta <draw_ops> elementu bat zehaztu ditu, edo bi elementu zehaztu ditu)" - -#: ../src/ui/theme-parser.c:3332 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Ezin dira bi draw_ops izan <button> elementu batean (gaiak draw_ops atributu " -"bat eta <draw_ops> elementu bat zehaztu ditu, edo bi elementu zehaztu ditu)" - -#: ../src/ui/theme-parser.c:3370 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Ezin dira bi draw_ops izan <menu_icon> elementu batean (gaiak draw_ops " -"atributu bat eta <draw_ops> elementu bat zehaztu ditu, edo bi elementu " -"zehaztu ditu)" - -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "'%s' bertsioaren okerreko zehaztapena" - -#: ../src/ui/theme-parser.c:3507 -msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" -msgstr "" -"\"version\" atributua ezin da erabili metacity-theme-1.xml edo metacity-" -"theme-2.xml fitxategietan" - -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "" -"Gaiak %s bertsioa behar du, baina onartutako gaiaren azken bertsioa %d.%d da." - -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "" -"Gaian kanporen dagoen elementuak <metacity_theme> izan behar du, ez <%s>" - -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "<%s> elementua ez da onartzen name/author/date/description elementuan" - -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "<%s> elementua ez da onartzen <constant> elementuaren barnean" - -#: ../src/ui/theme-parser.c:3599 -#, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "<%s> elementua ez da onartzen distance/border/aspect_ratio elementuan" - -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "" -"<%s> elementua ez da onartzen marrazteko eragiketaren elementuaren barnean" - -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "<%s> elementua ez da onartzen <%s> elementuaren barnean" - -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "Ez da draw_ops-ik eman marko-zatiarentzat" - -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "Ez da draw_ops-ik eman botoiarentzat" - -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "Ez da testurik onartzen <%s> elementuaren barnean" - -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "<%s> birritan zehaztu da gai honetan" - -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Huts egin du %s gaiaren fitxategi egokia bilatzean\n" - -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "_Leihoak" - -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "_Elkarrizketa-koadroa" - -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "Elkarrizketa-koadro _modala" - -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "_Utilitatea" - -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "_Harrerako pantaila" - -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "_Goiko atrakea" - -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "_Azpiko atrakea" - -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "E_zkerreko atrakea" - -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "E_skuineko atrakea" - -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "Atrake _guztiak" - -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "_Mahaigaina" - -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "Ireki beste leiho hauetariko bat" - -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "Hau probako botoia da, 'ireki' ikonoarekin" - -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "Hau probako botoia da, 'itxi' ikonoarekin" - -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "Hau mezu adibide bat da, adibidezko elkarizketa-koadro batekin" - -#: ../src/ui/theme-viewer.c:328 -#, c-format -msgid "Fake menu item %d\n" -msgstr "Menuko %d elementu faltsua\n" - -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "Ertz-soileko leihoa" - -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "Barra" - -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "Aplikazio normalaren leihoa" - -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "Elkarrizketa-koadroko kutxa" - -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "Elkarrizketa-koadroko kutxa modala" - -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "Paleta utilitatea" - -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "Menua itzalita" - -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "Ertza" - -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "Erantsitako elkarrizketa-koadro modala" - -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "Botoi diseinuen %d. proba" - -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g milisegundo leiho-markoa marrazteko" - -#: ../src/ui/theme-viewer.c:813 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Erabilera: metacity-theme-viewer [GAIA]\n" - -#: ../src/ui/theme-viewer.c:820 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "Errorea gaia kargatzean: %s\n" - -#: ../src/ui/theme-viewer.c:826 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "\"%s\" gaia %g segundotan kargatua\n" - -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "Tituluko letra-tipo normala" - -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "Tituluko letra-tipo txikia" - -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "Tituluko letra-tipo handia" - -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "Botoien diseinua" - -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "Proba-lekua" - -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "Leihoaren titulua hemen doa" - -#: ../src/ui/theme-viewer.c:1047 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"%d marko %g bezero-aldeko segundotan (%g milisegundo/markoko) marraztua eta " -"denbora estandarreko %g segundo X zerbitzariko errekurtsoak barne (%g " -"milisegundo/markoko)\n" - -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "" -"adierazpenaren posizioko probak TRUE itzuli du, baina errore bat ezarri du" - -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "" -"adierazpenaren posizioko probak FALSE itzuli du, baina ez du errorerik ezarri" - -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "Errorea espero zen, baina ez da gertatu" - -#: ../src/ui/theme-viewer.c:1274 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "%d errorea espero zen, baina %d gertatu da" - -#: ../src/ui/theme-viewer.c:1280 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "Errorerik ez zen espero, baina bat itzuli du: %s" - -#: ../src/ui/theme-viewer.c:1284 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "x balioa %d zen, %d espero zenean" - -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "y balioa %d zen, %d espero zenean" - -#: ../src/ui/theme-viewer.c:1352 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "" -"%d koordenada adierazpen analizatua %g segundotan (%g segundo batazbesteko)\n" - -#~ msgid "Switch to workspace 1" -#~ msgstr "Aldatu 1. laneko areara" - -#~ msgid "Switch to workspace 2" -#~ msgstr "Aldatu 2. laneko areara" - -#~ msgid "Switch to workspace 3" -#~ msgstr "Aldatu 3. laneko areara" - -#~ msgid "Switch to workspace 4" -#~ msgstr "Aldatu 4. laneko areara" - -#~ msgid "Switch to workspace 5" -#~ msgstr "Aldatu 5. laneko areara" - -#~ msgid "Switch to workspace 6" -#~ msgstr "Aldatu 6. laneko areara" - -#~ msgid "Switch to workspace 7" -#~ msgstr "Aldatu 7. laneko areara" - -#~ msgid "Switch to workspace 8" -#~ msgstr "Aldatu 8. laneko areara" - -#~ msgid "Switch to workspace 9" -#~ msgstr "Aldatu 9. laneko areara" - -#~ msgid "Switch to workspace 10" -#~ msgstr "Aldatu 10. laneko areara" - -#~ msgid "Switch to workspace 11" -#~ msgstr "Aldatu 11. laneko areara" - -#~ msgid "Switch to workspace 12" -#~ msgstr "Aldatu 12. laneko areara" - -#~ msgid "Switch to workspace on the left of the current workspace" -#~ msgstr "Aldatu uneko laneko arearen ezkerreko laneko areara" - -#~ msgid "Switch to workspace on the right of the current workspace" -#~ msgstr "Aldatu uneko laneko arearen eskuineko laneko areara" - -#~ msgid "Switch to workspace above the current workspace" -#~ msgstr "Aldatu uneko laneko arearen gaineko laneko areara" - -#~ msgid "Switch to workspace below the current workspace" -#~ msgstr "Aldatu uneko laneko arearen azpiko laneko areara" - -#~ msgid "Move between windows of an application, using a popup window" -#~ msgstr "Mugitu aplikazioaren leihoen artean, laster-leiho bat erabiliz" - -#~ msgid "" -#~ "Move backward between windows of an application, using a popup window" -#~ msgstr "" -#~ "Atzerantz joan aplikazioaren leihoen artean, laster-leiho bat erabiliz" - -#~ msgid "Move between windows, using a popup window" -#~ msgstr "Mugitu leihoen artean, laster-leiho bat erabiliz" - -#~ msgid "Move backward between windows, using a popup window" -#~ msgstr "Atzerantz joan leihoen artean, laster-leiho bat erabiliz" - -#~ msgid "Move between panels and the desktop, using a popup window" -#~ msgstr "Mugitu panelen eta mahaigainaren artean laster-leihoarekin" - -#~ msgid "Move backward between panels and the desktop, using a popup window" -#~ msgstr "" -#~ "Atzerantz joan panelen eta mahaigainaren artean, laster-leiho bat erabiliz" - -#~ msgid "Move between windows of an application immediately" -#~ msgstr "Mugitu aplikazio baten leihoen artean berehala" - -#~ msgid "Move backward between windows of an application immediately" -#~ msgstr "Atzerantz joan aplikazio baten leihoen artean berehala" - -#~ msgid "Move between windows immediately" -#~ msgstr "Mugitu leihoen artean berehala" - -#~ msgid "Move backward between windows immediately" -#~ msgstr "Atzerantz joan leihoen artean berehala" - -#~ msgid "Move between panels and the desktop immediately" -#~ msgstr "Mugitu panelen eta mahaigainaren artean berehala" - -#~ msgid "Move backward between panels and the desktop immediately" -#~ msgstr "Atzerantz joan panelen eta mahaigainaren artean berehala" - -#~ msgid "Hide all normal windows and set focus to the desktop" -#~ msgstr "Ezkutatu leiho normal guztiak eta eman fokua mahaigainari" - -#~ msgid "Show the panel's main menu" -#~ msgstr "Erakutsi paneleko menu nagusia" - -#~ msgid "Show the panel's \"Run Application\" dialog box" -#~ msgstr "Erakutsi panelaren \"Exekutatu aplikazioa\" elkarrizketa-koadroa" - -#~ msgid "Start or stop recording the session" -#~ msgstr "Hasi edo gelditu saioa grabatzea" - -#~ msgid "Take a screenshot" -#~ msgstr "Egin pantaila-argazki bat" - -#~ msgid "Take a screenshot of a window" -#~ msgstr "Egin leiho baten pantaila-argazkia" - -#~ msgid "Run a terminal" -#~ msgstr "Exekutatu terminala" - -#~ msgid "Activate the window menu" -#~ msgstr "Aktibatu leiho-menua" - -#~ msgid "Toggle fullscreen mode" -#~ msgstr "Txandakatu pantaila osoaren modua" - -#~ msgid "Toggle maximization state" -#~ msgstr "Txandakatu maximizatze-egoera" - -#~ msgid "Toggle whether a window will always be visible over other windows" -#~ msgstr "" -#~ "Txandakatu leiho bat beste leiho guztien gainean ikusgai egongo den edo ez" - -#~ msgid "Maximize window" -#~ msgstr "Maximizatu leihoa" - -#~ msgid "Restore window" -#~ msgstr "Leheneratu leihoa" - -#~ msgid "Toggle shaded state" -#~ msgstr "Txandakatu bildutako egoera" - -#~ msgid "Minimize window" -#~ msgstr "Ikonotu leihoa" - -#~ msgid "Close window" -#~ msgstr "Itxi leihoa" - -#~ msgid "Move window" -#~ msgstr "Lekuz aldatu leihoa" - -#~ msgid "Resize window" -#~ msgstr "Aldatu leihoaren tamaina" - -#~ msgid "Toggle whether window is on all workspaces or just one" -#~ msgstr "Txandakatu leihoa laneko area guztietan edo bakar batean egotea" - -#~ msgid "Move window to workspace 1" -#~ msgstr "Eraman leihoa 1. laneko areara" - -#~ msgid "Move window to workspace 2" -#~ msgstr "Eraman leihoa 2. laneko areara" - -#~ msgid "Move window to workspace 3" -#~ msgstr "Eraman leihoa 3. laneko areara" - -#~ msgid "Move window to workspace 4" -#~ msgstr "Eraman leihoa 4. laneko areara" - -#~ msgid "Move window to workspace 5" -#~ msgstr "Eraman leihoa 5. laneko areara" - -#~ msgid "Move window to workspace 6" -#~ msgstr "Eraman leihoa 6. laneko areara" - -#~ msgid "Move window to workspace 7" -#~ msgstr "Eraman leihoa 7. laneko areara" - -#~ msgid "Move window to workspace 8" -#~ msgstr "Eraman leihoa 8. laneko areara" - -#~ msgid "Move window to workspace 9" -#~ msgstr "Eraman leihoa 9. laneko areara" - -#~ msgid "Move window to workspace 10" -#~ msgstr "Eraman leihoa 10. laneko areara" - -#~ msgid "Move window to workspace 11" -#~ msgstr "Eraman leihoa 11. laneko areara" - -#~ msgid "Move window to workspace 12" -#~ msgstr "Eraman leihoa 12. laneko areara" - -#~ msgid "Move window one workspace to the left" -#~ msgstr "Eraman leihoa laneko area bat ezkerrera" - -#~ msgid "Move window one workspace to the right" -#~ msgstr "Eraman leihoa laneko area bat eskuinera" - -#~ msgid "Move window one workspace up" -#~ msgstr "Eraman leihoa laneko area bat gora" - -#~ msgid "Move window one workspace down" -#~ msgstr "Eraman leihoa laneko area bat behera" - -#~ msgid "Raise window if it's covered by another window, otherwise lower it" -#~ msgstr "Goratu leihoa beste leiho batek estaltzen badu, bestela beheratu" - -#~ msgid "Raise window above other windows" -#~ msgstr "Goratu leihoa beste leihoen gainera" - -#~ msgid "Lower window below other windows" -#~ msgstr "Beheratu leihoa beste leihoen azpira" - -#~ msgid "Maximize window vertically" -#~ msgstr "Maximizatu leihoa bertikalki" - -#~ msgid "Maximize window horizontally" -#~ msgstr "Maximizatu leihoa horizontalki" - -#~ msgid "Move window to north-west (top left) corner" -#~ msgstr "Eraman leihoa ipar-mendebaldeko (goi-ezkerreko) ertzera" - -#~ msgid "Move window to north-east (top right) corner" -#~ msgstr "Eraman leihoa ipar-ekialdeko (goi-eskuineko) ertzera" - -#~ msgid "Move window to south-west (bottom left) corner" -#~ msgstr "Eraman leihoa hego-mendebaldeko (ezker-beheko) ertzera" - -#~ msgid "Move window to south-east (bottom right) corner" -#~ msgstr "Eraman leihoa hego-ekialdeko (eskuin-beheko) ertzera" - -#~ msgid "Move window to north (top) side of screen" -#~ msgstr "Eraman leihoa pantailaren iparraldeko (goiko) aldera" - -#~ msgid "Move window to south (bottom) side of screen" -#~ msgstr "Eraman leihoa pantailaren hegoaldeko (beheko) aldera" - -#~ msgid "Move window to east (right) side of screen" -#~ msgstr "Eraman leihoa pantailaren ekialdeko (eskuineko) aldera" - -#~ msgid "Move window to west (left) side of screen" -#~ msgstr "Eraman leihoa pantailaren mendebaldeko (ezkerreko) aldera" - -#~ msgid "Move window to center of screen" -#~ msgstr "Eraman leihoa pantailaren zentruko aldera" - -#~ msgid "" -#~ "There was an error running <tt>%s</tt>:\n" -#~ "\n" -#~ "%s" -#~ msgstr "" -#~ "Errorea gertatu da <tt>%s</tt> exekutatzean:\n" -#~ "\n" -#~ "%s" - -#~ msgid "No command %d has been defined.\n" -#~ msgstr "%d komandoa ez dago definituta.\n" - -#~ msgid "No terminal command has been defined.\n" -#~ msgstr "Ez da terminalaren komandoa definitu.\n" - -#~ msgid "GConf key '%s' is set to an invalid value\n" -#~ msgstr "\"%s\" GConf gakoa balio baliogabean ezarrita dago\n" - -#~ msgid "%d stored in GConf key %s is out of range %d to %d\n" -#~ msgstr "%2$s GConf gakoko %1$d balioa %3$d - %4$d barrutitik kanpo dago\n" - -#~ msgid "GConf key \"%s\" is set to an invalid type\n" -#~ msgstr "\"%s\" GConf gakoa mota baliogabean ezarrita dago\n" - -#~ msgid "GConf key %s is already in use and can't be used to override %s\n" -#~ msgstr "" -#~ "GConf-eko %s gakoa jadanik erabilita dago eta ezin da %s gainidazteko " -#~ "erabili\n" - -#~ msgid "Can't override GConf key, %s not found\n" -#~ msgstr "Ezin da GConf-eko gakoa gainidatzi, %s ez da aurkitu\n" - -#~ msgid "Error setting number of workspaces to %d: %s\n" -#~ msgstr "Errorea laneko %d area ezartzean: %s\n" - -#~ msgid "Error setting name for workspace %d to \"%s\": %s\n" -#~ msgstr "Errorea %d. laneko areari \"%s\" izena ezartzean: %s\n" - -#~ msgid "Error setting live hidden windows status status: %s\n" -#~ msgstr "Errorea ezkutuko leihoen bizitzen egoera ezartzean: %s\n" - -#~ msgid "Error setting no tab popup status: %s\n" -#~ msgstr "Errorea fitxarik gabeko laster-leihoen egoera ezartzean: %s\n" +msgid "%s (on %s)" +msgstr "%s (%s)" diff --git a/po/fa.po b/po/fa.po index 92053a1e0..169de0a67 100644 --- a/po/fa.po +++ b/po/fa.po @@ -8,258 +8,549 @@ msgid "" msgstr "" "Project-Id-Version: metacity HEAD\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2006-02-16 09:13+0100\n" -"PO-Revision-Date: 2006-02-18 16:19+0330\n" -"Last-Translator: Farzaneh Sarafraz <farzaneh@farsiweb.info>\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=mutter&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2012-03-15 21:29+0000\n" +"PO-Revision-Date: 2012-04-01 00:10+0330\n" +"Last-Translator: Arash Mousavi <mousavi.arash@gmail.com>\n" "Language-Team: Persian\n" +"Language: fa\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: Persian\n" +"X-Poedit-Country: IRAN, ISLAMIC REPUBLIC OF\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: ../src/50-mutter-windows.xml.in.h:1 ../src/50-mutter-windows.xml.in.h:17 +msgid "Windows" +msgstr "پنجره‌ها" + +#: ../src/50-mutter-windows.xml.in.h:2 +msgid "View split on left" +msgstr "نمایش انشعاب در سمت راست" + +#: ../src/50-mutter-windows.xml.in.h:3 +msgid "View split on right" +msgstr "نمایش انشعاب در سمت راست" + +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: ../src/compositor/compositor.c:492 +#, fuzzy, c-format +#| msgid "" +#| "Could not acquire window manager selection on screen %d display \"%s\"\n" +msgid "Another compositing manager is already running on screen %i on display \"%s\"." +msgstr "انتخاب مدیر پنجره‌ها روی صفحه‌ی %Id نمایش «%s»\n" + +#: ../src/core/bell.c:307 +msgid "Bell event" +msgstr "رویداد زنگ" -#: ../src/tools/metacity-message.c:150 +#: ../src/core/core.c:157 #, c-format -msgid "Usage: %s\n" -msgstr "کاربرد: %s\n" +msgid "Unknown window information request: %d" +msgstr "درخواست ناشناس برای اطلاعات پنجره: %Id" + +#: ../src/core/delete.c:111 +#, c-format +#| msgid "The window \"%s\" is not responding." +msgid "<tt>%s</tt> is not responding." +msgstr "<tt>%s</tt> پاسخی نمی‌دهد." + +#: ../src/core/delete.c:114 +#| msgid "The window \"%s\" is not responding." +msgid "Application is not responding." +msgstr "برنامه پاسخی نمی‌دهد." + +#: ../src/core/delete.c:119 +msgid "You may choose to wait a short while for it to continue or force the application to quit entirely." +msgstr "ممکن است بخواهید کمی صبر کنید تا ادامه بدهد یا برنامه را با اجبار ببندید." -#: ../src/tools/metacity-message.c:176 ../src/util.c:131 -msgid "Metacity was compiled without support for verbose mode\n" -msgstr "متاسیتی بدون پشتیبانی حالت مفصل ترجمه شده است\n" +#: ../src/core/delete.c:126 +msgid "_Wait" +msgstr "_صبر کردن" -#: ../src/delete.c:64 ../src/delete.c:91 ../src/metacity-dialog.c:71 -#: ../src/theme-parser.c:467 +#: ../src/core/delete.c:126 +msgid "_Force Quit" +msgstr "ترک _اجباری" + +#: ../src/core/display.c:387 #, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "«%s»به عنوان عدد صحیح قابل تجزیه نیست " +msgid "Missing %s extension required for compositing" +msgstr "" -#: ../src/delete.c:71 ../src/delete.c:98 ../src/metacity-dialog.c:78 -#: ../src/theme-parser.c:476 ../src/theme-parser.c:530 +#: ../src/core/display.c:453 #, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "نویسه‌ی «%s» در رشته‌ی «%s» قابل درک نیست" +msgid "Failed to open X Window System display '%s'\n" +msgstr "شکست در باز کردن نمایش «%s» سیستم پنجره‌ی X\n" + +#: ../src/core/keybindings.c:852 +#, c-format +msgid "Some other program is already using the key %s with modifiers %x as a binding\n" +msgstr "برنامه‌ی دیگری کلید %s را با تغییردهنده‌های %x برای مقیدسازی به کار می‌برد\n" + +#: ../src/core/main.c:206 +msgid "Disable connection to session manager" +msgstr "غیرفعال کردن اتصال به مدیر نشست" + +#: ../src/core/main.c:212 +#| msgid "Bug in window manager: " +msgid "Replace the running window manager" +msgstr "جای‌گزینی مدیر پنجره‌ی درحال اجرا" + +#: ../src/core/main.c:218 +msgid "Specify session management ID" +msgstr "مشخص کردن شناسه‌ی مدیر نشست" -#: ../src/delete.c:129 +#: ../src/core/main.c:223 +msgid "X Display to use" +msgstr "نمایشگر X جهت استفاده" + +#: ../src/core/main.c:229 +msgid "Initialize session from savefile" +msgstr "مقداردهی اولیه‌ی نشست از پرونده ذخیره" + +#: ../src/core/main.c:235 +msgid "Make X calls synchronous" +msgstr "" + +#: ../src/core/main.c:504 #, c-format -msgid "Failed to parse message \"%s\" from dialog process\n" -msgstr "شکست در تجزیه پیغام «%s» از پردازش محاوره\n" +msgid "Failed to scan themes directory: %s\n" +msgstr "شکست در پویش شاخه‌ی تم‌ها: %s\n" -#: ../src/delete.c:264 +#: ../src/core/main.c:520 #, c-format -msgid "Error reading from dialog display process: %s\n" -msgstr "خطا در خواندن از پردازش نمایش محاوره: %s\n" +#| msgid "" +#| "Could not find a theme! Be sure %s exists and contains the usual themes." +msgid "Could not find a theme! Be sure %s exists and contains the usual themes.\n" +msgstr "تم پیدا نشد! مطمئن شوید %s وجود دارد و شامل تم‌های معمول است.\n" -#: ../src/delete.c:345 +#: ../src/core/mutter.c:40 #, c-format +#| msgid "" +#| "metacity %s\n" +#| "Copyright (C) 2001-2002 Havoc Pennington, Red Hat, Inc., and others\n" +#| "This is free software; see the source for copying conditions.\n" +#| "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +#| "PARTICULAR PURPOSE.\n" msgid "" -"Error launching metacity-dialog to ask about killing an application: %s\n" +"mutter %s\n" +"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" +msgstr "" +"ماتر %s\n" +"حق‌رونشوت (C) ۲۰۰۱-%Id هاووک پنینگتون، سازمان Red Hat و دیگران\n" +"این نرم‌افزار آزاد است؛ برای دیدن شرایط نسخه‌برداری متن برنامه را ببینید.\n" +"هیچ تضمینی وجود ندارد؛ حتی در مورد قابلیت تجاری یا مناسبت برای\n" +" یک هدف به خصوص.\n" + +#: ../src/core/mutter.c:54 +msgid "Print version" +msgstr "نسخه چاپی" + +#: ../src/core/mutter.c:60 +msgid "Comma-separated list of compositor plugins" msgstr "" -"خطا در راه‌اندازی metacity-dialog برای پرسش درباره کشتن یک برنامه‌ی کاربردی: %" -"s\n" -#: ../src/delete.c:453 +#: ../src/core/prefs.c:1077 +msgid "Workarounds for broken applications disabled. Some applications may not behave properly.\n" +msgstr "دور زدن برنامه‌های از کار افتاده، از کار انداخته شده است. بعضی از برنامه‌ها ممکن است رفتار مناسبی نداشته باشند.\n" + +#: ../src/core/prefs.c:1152 +#, fuzzy, c-format +#| msgid "Could not parse font description \"%s\" from GConf key %s\n" +msgid "Could not parse font description \"%s\" from GSettings key %s\n" +msgstr "تجزیه‌ی شرح قلم «%s» از کلید GConf %s ممکن نیست\n" + +#: ../src/core/prefs.c:1218 #, c-format -msgid "Failed to get hostname: %s\n" -msgstr "شکست در گرفتن نام میزبان: %s\n" +msgid "\"%s\" found in configuration database is not a valid value for mouse button modifier\n" +msgstr "«%s» پیدا شده در پایگاه‌داده‌ی پیکربندی مقدار معتبری برای تغییردهنده‌ی دکمه‌ی موشی نیست\n" -#: ../src/display.c:308 +#: ../src/core/prefs.c:1739 #, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "شکست در باز کردن نمایش «%s» سیستم پنجره‌ی X\n" +msgid "\"%s\" found in configuration database is not a valid value for keybinding \"%s\"\n" +msgstr "«%s» که در پایگاه داده‌ی پیکربندی پیدا شده مقدار معتبری برای کلید مقید «%s» نیست\n" -#: ../src/errors.c:233 +#: ../src/core/prefs.c:1836 #, c-format -msgid "" -"Lost connection to the display '%s';\n" -"most likely the X server was shut down or you killed/destroyed\n" -"the window manager.\n" -msgstr "" -"از دست دادن اتصال برای نمایش «%s»؛\n" -"به احتمال زیاد کارگزار X خاموش شده است یا شما مدیر پنجره‌ها را\n" -"تخریب کرده‌اید یا کشته‌اید.\n" +msgid "Workspace %d" +msgstr "فضای کاری %Id" -#: ../src/errors.c:240 +#: ../src/core/screen.c:730 #, c-format -msgid "Fatal IO error %d (%s) on display '%s'.\n" -msgstr "خطای مهلک ورودی/خروجی %Id (%s) هنگام نمایش «%s».\n" +msgid "Screen %d on display '%s' is invalid\n" +msgstr "صفحه‌ی %Id روی نمایشگر «%s» نامعتبر است\n" -#: ../src/frames.c:1097 -msgid "Close Window" -msgstr "بستن پنجره" +#: ../src/core/screen.c:746 +#, c-format +msgid "Screen %d on display \"%s\" already has a window manager; try using the --replace option to replace the current window manager.\n" +msgstr "صفحه‌ی %Id روی نمایشگر «%s» مدیر پنجره‌ها دارد. برای جایگزین کردنمدیر پنجره‌های فعلی از گزینه‌ی --replace استفاده کنید.\n" + +#: ../src/core/screen.c:773 +#, c-format +msgid "Could not acquire window manager selection on screen %d display \"%s\"\n" +msgstr "انتخاب مدیر پنجره‌ها روی صفحه‌ی %Id نمایش «%s»\n" + +#: ../src/core/screen.c:828 +#, c-format +msgid "Screen %d on display \"%s\" already has a window manager\n" +msgstr "صفحه‌ی %Id روی نمایشگر «%s» مدیر پنجره دارد\n" + +#: ../src/core/screen.c:1013 +#, c-format +msgid "Could not release screen %d on display \"%s\"\n" +msgstr "آزاد کردن صفحه‌ی %Id روی نمایشگر «%s» ممکن نیست\n" -#: ../src/frames.c:1100 -msgid "Window Menu" -msgstr "منوی پنجره" +#: ../src/core/session.c:843 +#: ../src/core/session.c:850 +#, c-format +msgid "Could not create directory '%s': %s\n" +msgstr "ایجاد شاخه‌ی «%s» ممکن نیست: %s\n" -#: ../src/frames.c:1103 -msgid "Minimize Window" -msgstr "حداقل کردن پنجره" +#: ../src/core/session.c:860 +#, c-format +msgid "Could not open session file '%s' for writing: %s\n" +msgstr "باز کردن پرونده‌ی نشست «%s» برای نوشتن ممکن نیست: %s\n" -#: ../src/frames.c:1106 -msgid "Maximize Window" -msgstr "حداکثر کردن پنجره" +#: ../src/core/session.c:1001 +#, c-format +msgid "Error writing session file '%s': %s\n" +msgstr "خطا در نوشتن پرونده‌ی نشست «%s»: %s\n" -#: ../src/frames.c:1109 -msgid "Unmaximize Window" -msgstr "ناحداکثر کردن پنجره" +#: ../src/core/session.c:1006 +#, c-format +msgid "Error closing session file '%s': %s\n" +msgstr "خطا در بستن پرونده‌ی نشست «%s»: %s\n" -#: ../src/keybindings.c:996 +#: ../src/core/session.c:1136 #, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "" -"برنامه‌ی دیگری کلید %s را با تغییردهنده‌های %x برای مقیدسازی به کار می‌برد\n" +msgid "Failed to parse saved session file: %s\n" +msgstr "شکست در تجزیه‌ی پرونده‌ی نشست ذخیره شده: %s\n" + +#: ../src/core/session.c:1185 +#, fuzzy, c-format +#| msgid "<metacity_session> attribute seen but we already have the session ID" +msgid "<mutter_session> attribute seen but we already have the session ID" +msgstr "مشخصه‌ی <metacity_session> دیده شد اما شناسه‌ی نشست از قبل موجود بود" + +#: ../src/core/session.c:1198 +#: ../src/core/session.c:1273 +#: ../src/core/session.c:1305 +#: ../src/core/session.c:1377 +#: ../src/core/session.c:1437 +#, fuzzy, c-format +#| msgid "Unknown attribute %s on <window> element" +msgid "Unknown attribute %s on <%s> element" +msgstr "مشخصه‌ی ‌%s روی عنصر <window> نامعلوم است" + +#: ../src/core/session.c:1215 +#, c-format +msgid "nested <window> tag" +msgstr "برچسب <window> تودرتو است" + +#: ../src/core/session.c:1457 +#, c-format +msgid "Unknown element %s" +msgstr "عنصر %s نامعلوم است" + +#: ../src/core/session.c:1809 +#, fuzzy +#| msgid "" +#| "These windows do not support \"save current setup\" and will have to be " +#| "restarted manually next time you log in." +msgid "These windows do not support "save current setup" and will have to be restarted manually next time you log in." +msgstr "این پنجره‌ها «ذخیره‌ی برپاسازی فعلی» را پشتیبانی نمی‌کنند و باید در ورود بعدی به سیستم به صورت دستی راه‌اندازی مجدد شوند. " + +#: ../src/core/util.c:111 +#, c-format +msgid "Failed to open debug log: %s\n" +msgstr "شکست در بازکردن ثبت وقایع اشکال‌زدایی: %s\n" + +#: ../src/core/util.c:121 +#, c-format +msgid "Failed to fdopen() log file %s: %s\n" +msgstr "شکست در انجام fdopen() پرونده‌ی ثبتی %s: %s\n" + +#: ../src/core/util.c:127 +#, c-format +msgid "Opened log file %s\n" +msgstr "پرونده‌ی ثبتی %s باز شد\n" + +#: ../src/core/util.c:146 +#: ../src/tools/mutter-message.c:149 +#, c-format +#| msgid "Metacity was compiled without support for verbose mode\n" +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "ماتر بدون پشتیبانی حالت مفصل ترجمه شده است\n" + +#: ../src/core/util.c:290 +msgid "Window manager: " +msgstr "مدیر پنجره‌ها: " + +#: ../src/core/util.c:438 +msgid "Bug in window manager: " +msgstr "اشکال در مدیر پنجره‌ها: " + +#: ../src/core/util.c:471 +msgid "Window manager warning: " +msgstr "هشدار مدیر پنجره‌ها: " + +#: ../src/core/util.c:499 +msgid "Window manager error: " +msgstr "خطای مدیر پنجره‌ها: " + +#. first time through +#: ../src/core/window.c:7269 +#, c-format +msgid "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER window as specified in the ICCCM.\n" +msgstr "پنجره %s به جای تنظیم SM_CLIENT_ID روی پنجره‌ی WM_CLIENT_LEADER طبق ICCCM آن را روی خودش تنظیم کرده است.\n" + +#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the +#. * authoritative source for that info. Some apps such as mplayer or +#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that +#. * leads to e.g. us not fullscreening their windows. Apps that set +#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain +#. * about these apps but make them work. +#. +#: ../src/core/window.c:7932 +#, c-format +msgid "Window %s sets an MWM hint indicating it isn't resizable, but sets min size %d x %d and max size %d x %d; this doesn't make much sense.\n" +msgstr "پنجره‌ی %s یک راهنمای MWM تنظیم می‌کند که نشان می‌دهد امکان تغییر اندازه ندارد، اما اندازه‌ی حداقل را %Id × %Id و اندازه‌ی حداکثر را %Id × %Id تنظیم می‌کند؛ این منطقی نیست.\n" + +#: ../src/core/window-props.c:309 +#, c-format +msgid "Application set a bogus _NET_WM_PID %lu\n" +msgstr "برنامه _NET_WM_PID %Ilu جعلی تنظیم کرده است\n" -#: ../src/keybindings.c:2534 +#: ../src/core/window-props.c:426 #, c-format -msgid "Error launching metacity-dialog to print an error about a command: %s\n" -msgstr "خطا در راه‌اندازی metacity-dialog برای چاپ خطا درباره‌ی یک فرمان: %s\n" +msgid "%s (on %s)" +msgstr "%s (بر روی %s)" -#: ../src/keybindings.c:2639 +#: ../src/core/window-props.c:1481 #, c-format -msgid "No command %d has been defined.\n" -msgstr " فرمان %Id تعریف نشده است.\n" +msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +msgstr "" -#: ../src/keybindings.c:3501 -msgid "No terminal command has been defined.\n" -msgstr "هیچ فرمان پایانه‌ای تعریف نشده است.\n" +#: ../src/core/window-props.c:1492 +#, c-format +msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" +msgstr "" -#: ../src/main.c:70 +#: ../src/core/xprops.c:155 #, c-format msgid "" -"metacity %s\n" -"Copyright (C) 2001-2002 Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" +"Window 0x%lx has property %s\n" +"that was expected to have type %s format %d\n" +"and actually has type %s format %d n_items %d.\n" +"This is most likely an application bug, not a window manager bug.\n" +"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" msgstr "" -"metacity %s\n" -"Copyright (C) 2001-2002 Havoc Pennington, Red Hat, Inc., and others\n" -"این نرم‌افزار آزاد است؛ برای دیدن شرایط نسخه‌برداری متن برنامه را ببینید.\n" -"هیچ تضمینی وجود ندارد؛ حتی در مورد قابلیت تجاری یا مناسبت برای\n" -" یک هدف به خصوص.\n" +"پنجره‌ی 0x%lx ویژگی %s را دارد که \n" +"انتظار می‌رفت از نوع %s قالب %Id باشد\n" +"اما از نوع %s قالب %Id n_items %Id بود.\n" +"این به احتمال زیاد اشکال برنامه است نه اشکال مدیر پنجره‌ها.\n" +"در این پنجره title=«%s» class=«%s» name=«%s» است\n" -#: ../src/main.c:258 -msgid "Disable connection to session manager" +#: ../src/core/xprops.c:411 +#, c-format +msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +msgstr "ویژگی %s روی پنجره‌ی 0x%lx UTf-8 نامعتبر دارد\n" + +#: ../src/core/xprops.c:494 +#, c-format +msgid "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" +msgstr "ویژگی %s روی پنجره‌ی 0x%lx برای مورد %Id در فهرست، UTf-8 نامعتبر دارد\n" + +#: ../src/mutter.desktop.in.h:1 +#: ../src/mutter-wm.desktop.in.h:1 +msgid "Mutter" +msgstr "ماتر" + +#: ../src/org.gnome.mutter.gschema.xml.in.h:1 +#, fuzzy +#| msgid "Modifier to use for modified window click actions" +msgid "Modifier to use for extended window management operations" +msgstr "تغییردهنده‌ای که برای کنش‌های کلیک روی پنجره‌ی تغییر داده شده به کار می‌رود" + +#: ../src/org.gnome.mutter.gschema.xml.in.h:2 +msgid "This key will initiate the \"overlay\", which is a combination window overview and application launching system. The default is intended to be the \"Windows key\" on PC hardware. It's expected that this binding either the default or set to the empty string." msgstr "" -#: ../src/main.c:264 -msgid "Replace the running window manager with Metacity" +#: ../src/org.gnome.mutter.gschema.xml.in.h:3 +msgid "Attach modal dialogs" +msgstr "ضمیمه‌کردن محاوره‌های معین" + +#: ../src/org.gnome.mutter.gschema.xml.in.h:4 +msgid "When true, instead of having independent titlebars, modal dialogs appear attached to the titlebar of the parent window and are moved together with the parent window." msgstr "" -#: ../src/main.c:270 -msgid "Specify session management ID" +#: ../src/org.gnome.mutter.gschema.xml.in.h:5 +msgid "Live Hidden Windows" +msgstr "پنجره‌های مخفی زنده" + +#: ../src/org.gnome.mutter.gschema.xml.in.h:6 +msgid "Determines whether hidden windows (i.e., minimized windows and windows on other workspaces than the current one) should be kept alive." msgstr "" -#: ../src/main.c:275 -msgid "X Display to use" +#: ../src/org.gnome.mutter.gschema.xml.in.h:7 +msgid "Enable edge tiling when dropping windows on screen edges" msgstr "" -#: ../src/main.c:281 -msgid "Initialize session from savefile" +#: ../src/org.gnome.mutter.gschema.xml.in.h:8 +msgid "If enabled, dropping windows on vertical screen edges maximizes them vertically and resizes them horizontally to cover half of the available area. Dropping windows on the top screen edge maximizes them completely." msgstr "" -#: ../src/main.c:287 -msgid "Print version" +#: ../src/org.gnome.mutter.gschema.xml.in.h:9 +msgid "Workspaces are managed dynamically" +msgstr "فضاهای‌کاری بصورت پویا مدیریت می‌شوند" + +#: ../src/org.gnome.mutter.gschema.xml.in.h:10 +msgid "Determines whether workspaces are managed dynamically or whether there's a static number of workspaces (determined by the num-workspaces key in org.gnome.desktop.wm.preferences)." msgstr "" -#: ../src/main.c:439 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "شکست در پویش شاخه‌ی تم‌ها: %s\n" +#: ../src/org.gnome.mutter.gschema.xml.in.h:11 +msgid "Workspaces only on primary" +msgstr "" -#: ../src/main.c:455 -#, c-format -msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes." -msgstr "تم پیدا نشد! مطمئن شوید %s .وجود دارد و شامل تم‌های معمول است" +#: ../src/org.gnome.mutter.gschema.xml.in.h:12 +msgid "Determines whether workspace switching should happen for windows on all monitors or only for windows on the primary monitor." +msgstr "" -#: ../src/main.c:527 +#: ../src/org.gnome.mutter.gschema.xml.in.h:13 +msgid "No tab popup" +msgstr "" + +#: ../src/org.gnome.mutter.gschema.xml.in.h:14 +msgid "Determines whether the use of popup and highlight frame should be disabled for window cycling." +msgstr "" + +#: ../src/org.gnome.mutter.gschema.xml.in.h:15 +msgid "Draggable border width" +msgstr "" + +#: ../src/org.gnome.mutter.gschema.xml.in.h:16 +msgid "The amount of total draggable borders. If the theme's visible borders are not enough, invisible borders will be added to meet this value." +msgstr "" + +#: ../src/org.gnome.mutter.gschema.xml.in.h:17 +#, fuzzy +#| msgid "Move between windows with popup" +msgid "Select window from tab popup" +msgstr "جابه‌جایی بین پنجره‌ها با واشو" + +#: ../src/org.gnome.mutter.gschema.xml.in.h:18 +msgid "Cancel tab popup" +msgstr "" + +#: ../src/tools/mutter-message.c:123 #, c-format -msgid "Failed to restart: %s\n" -msgstr "شکست در راه‌اندازی مجدد: %s\n" +msgid "Usage: %s\n" +msgstr "کاربرد: %s\n" -#: ../src/menu.c:55 +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:69 msgid "Mi_nimize" msgstr "حداقل کردن" -#: ../src/menu.c:56 +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:71 msgid "Ma_ximize" msgstr "حداکثر کردن" -#: ../src/menu.c:57 +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:73 msgid "Unma_ximize" msgstr "ناحداکثر کردن" -#: ../src/menu.c:58 +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:75 msgid "Roll _Up" msgstr "جمع کردن" -#: ../src/menu.c:59 +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:77 msgid "_Unroll" msgstr "پهن کردن" -#: ../src/menu.c:60 ../src/menu.c:61 -msgid "On _Top" -msgstr "همیشه رو" - -#: ../src/menu.c:62 +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:79 msgid "_Move" msgstr "جابه‌جایی" -#: ../src/menu.c:63 +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:81 msgid "_Resize" msgstr "تغییر اندازه" -#: ../src/menu.c:64 +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:83 msgid "Move Titlebar On_screen" msgstr "" #. separator -#: ../src/menu.c:66 -msgid "_Close" -msgstr "بستن" - -#. separator -#: ../src/menu.c:68 +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:86 +#: ../src/ui/menu.c:88 +msgid "Always on _Top" +msgstr "همیشه در _بالا" + +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:90 msgid "_Always on Visible Workspace" msgstr "_همیشه در فضای کاری قابل مشاهده" -#: ../src/menu.c:69 +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:92 msgid "_Only on This Workspace" msgstr "_فقط در این فضای کاری" -#: ../src/menu.c:70 +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:94 msgid "Move to Workspace _Left" msgstr "نقل‌مکان به فضای کاری _چپ" -#: ../src/menu.c:71 +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:96 msgid "Move to Workspace R_ight" msgstr "نقل‌مکان به فضای کاری _راست" -#: ../src/menu.c:72 +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:98 msgid "Move to Workspace _Up" msgstr "نقل‌مکان به فضای کاری _بالا " -#: ../src/menu.c:73 +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:100 msgid "Move to Workspace _Down" msgstr "نقل‌مکان به فضای کاری _پایین" -#: ../src/menu.c:164 ../src/prefs.c:1978 ../src/prefs.c:2279 +#. separator +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:104 +msgid "_Close" +msgstr "بستن" + +#: ../src/ui/menu.c:204 #, c-format -msgid "Workspace %d" -msgstr "فضای کاری %Id" +#| msgid "Workspace %d" +msgid "Workspace %d%n" +msgstr "فضای‌کاری %Id%n" -#: ../src/menu.c:173 +#: ../src/ui/menu.c:214 +#, c-format msgid "Workspace 1_0" msgstr "فضای کاری ۱_۰" -#: ../src/menu.c:175 +#: ../src/ui/menu.c:216 #, c-format msgid "Workspace %s%d" msgstr "فضای کاری %s%Id" -#: ../src/menu.c:370 +#: ../src/ui/menu.c:397 msgid "Move to Another _Workspace" msgstr "نقل‌مکان به فضای کاری دیگر" @@ -268,7 +559,7 @@ msgstr "نقل‌مکان به فضای کاری دیگر" #. * translated on keyboards used for your language, don't translate #. * this. #. -#: ../src/metaaccellabel.c:103 +#: ../src/ui/metaaccellabel.c:77 msgid "Shift" msgstr "تبدیل" @@ -277,7 +568,7 @@ msgstr "تبدیل" #. * translated on keyboards used for your language, don't translate #. * this. #. -#: ../src/metaaccellabel.c:109 +#: ../src/ui/metaaccellabel.c:83 msgid "Ctrl" msgstr "مهار" @@ -286,7 +577,7 @@ msgstr "مهار" #. * translated on keyboards used for your language, don't translate #. * this. #. -#: ../src/metaaccellabel.c:115 +#: ../src/ui/metaaccellabel.c:89 msgid "Alt" msgstr "دگرساز" @@ -295,7 +586,7 @@ msgstr "دگرساز" #. * translated on keyboards used for your language, don't translate #. * this. #. -#: ../src/metaaccellabel.c:121 +#: ../src/ui/metaaccellabel.c:95 msgid "Meta" msgstr "Meta" @@ -304,7 +595,7 @@ msgstr "Meta" #. * translated on keyboards used for your language, don't translate #. * this. #. -#: ../src/metaaccellabel.c:127 +#: ../src/ui/metaaccellabel.c:101 msgid "Super" msgstr "Super" @@ -313,7 +604,7 @@ msgstr "Super" #. * translated on keyboards used for your language, don't translate #. * this. #. -#: ../src/metaaccellabel.c:133 +#: ../src/ui/metaaccellabel.c:107 msgid "Hyper" msgstr "Hyper" @@ -322,7 +613,7 @@ msgstr "Hyper" #. * translated on keyboards used for your language, don't translate #. * this. #. -#: ../src/metaaccellabel.c:139 +#: ../src/ui/metaaccellabel.c:113 msgid "Mod2" msgstr "Mod2" @@ -331,7 +622,7 @@ msgstr "Mod2" #. * translated on keyboards used for your language, don't translate #. * this. #. -#: ../src/metaaccellabel.c:145 +#: ../src/ui/metaaccellabel.c:119 msgid "Mod3" msgstr "Mod3" @@ -340,7 +631,7 @@ msgstr "Mod3" #. * translated on keyboards used for your language, don't translate #. * this. #. -#: ../src/metaaccellabel.c:151 +#: ../src/ui/metaaccellabel.c:125 msgid "Mod4" msgstr "Mod4" @@ -349,2864 +640,2727 @@ msgstr "Mod4" #. * translated on keyboards used for your language, don't translate #. * this. #. -#: ../src/metaaccellabel.c:157 +#: ../src/ui/metaaccellabel.c:131 msgid "Mod5" msgstr "Mod5" -#: ../src/metacity-dialog.c:111 +#. Translators: This represents the size of a window. The first number is +#. * the width of the window and the second is the height. +#. +#: ../src/ui/resizepopup.c:113 #, c-format -msgid "The window \"%s\" is not responding." -msgstr "پنجره‌ی «%s» پاسخ نمی‌دهد." +msgid "%d x %d" +msgstr "%Id × %Id" -#: ../src/metacity-dialog.c:119 -msgid "" -"Forcing this application to quit will cause you to lose any unsaved changes." -msgstr "اجبار این برنامه به ترک باعث از دست رفتن تغییرات ذخیره نشده می‌شود." +#: ../src/ui/theme.c:253 +msgid "top" +msgstr "بالا" -#: ../src/metacity-dialog.c:130 -msgid "_Force Quit" -msgstr "ترک اجباری" +#: ../src/ui/theme.c:255 +msgid "bottom" +msgstr "پایین" -#: ../src/metacity-dialog.c:227 -msgid "Title" -msgstr "عنوان" +#: ../src/ui/theme.c:257 +msgid "left" +msgstr "چپ" -#: ../src/metacity-dialog.c:239 -msgid "Class" -msgstr "رده" +#: ../src/ui/theme.c:259 +msgid "right" +msgstr "راست" -#: ../src/metacity-dialog.c:265 -msgid "" -"These windows do not support \"save current setup\" and will have to be " -"restarted manually next time you log in." -msgstr "" -"این پنجره‌ها «ذخیره‌ی برپاسازی فعلی» را پشتیبانی نمی‌کنند و باید در ورود بعدی " -"به سیستم به صورت دستی راه‌اندازی مجدد شوند. " +#: ../src/ui/theme.c:286 +#, c-format +msgid "frame geometry does not specify \"%s\" dimension" +msgstr "پیکربندی ظاهری چارچوب بعد «%s» را مشخص نمی‌کند" -#: ../src/metacity-dialog.c:331 +#: ../src/ui/theme.c:305 #, c-format -msgid "" -"There was an error running \"%s\":\n" -"%s." -msgstr "" -"شکست هنگام اجرای «%s»:\n" -"%s." +msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" +msgstr "پیکربندی ظاهری چارچوب بعد «%s» را برای کناره‌ی «%s» مشخص نمی‌کند" -#: ../src/metacity.desktop.in.h:1 -msgid "Metacity" -msgstr "متاسیتی" +#: ../src/ui/theme.c:342 +#, c-format +msgid "Button aspect ratio %g is not reasonable" +msgstr "%Ig به عنوان نسبت طول به عرض دکمه معقول نیست" -#: ../src/metacity.schemas.in.h:1 -msgid "(Not implemented) Navigation works in terms of applications not windows" -msgstr "(پیاده‌سازی نشده) ناوش در میان برنامه‌ها کار می‌کند نه پنجره‌ها" +#: ../src/ui/theme.c:354 +#, c-format +msgid "Frame geometry does not specify size of buttons" +msgstr "پیکربندی ظاهری چارچوب اندازه‌ی دکمه‌ها را مشخص نمی‌کند" -#: ../src/metacity.schemas.in.h:2 -msgid "" -"A font description string describing a font for window titlebars. The size " -"from the description will only be used if the titlebar_font_size option is " -"set to 0, however. Also, this option is disabled if the " -"titlebar_uses_desktop_font option is set to true. By default, titlebar_font " -"is unset, causing Metacity to fall back to the desktop font even if " -"titlebar_uses_desktop_font is false." -msgstr "" -"رشته‌ی شرح قلم که قلم نوارهای عنوان پنجره را شرح می‌دهد. اما تنها زمانیکه " -"گزینه‌ی titlebar_font_size، 0 تنظیم شده باشد، اندازه‌ی شرح استفاده می‌شود. به " -"علاوه در صورتی که گزینه‌ی titlebar_uses_desktop_font درست تنظیم شده باشداین " -"گزینه از کار انداخته می‌شود. طبق پیش فرض، titlebar_font تنظیم نشدهاست که باعث " -"می‌شود متاسیتی از قلم رومیزی استفاده کند حتی اگر " -"titlebar_uses_desktop_fontنادرست باشد." - -#: ../src/metacity.schemas.in.h:3 -msgid "Action on title bar double-click" -msgstr "کنشی که با دوبار کلیک روی نوار عنوان انجام می‌شود" - -#: ../src/metacity.schemas.in.h:4 -msgid "Activate window menu" -msgstr "فعال کردن منوی پنجره" +#: ../src/ui/theme.c:1067 +#, c-format +msgid "Gradients should have at least two colors" +msgstr "شیب‌ها باید حداقل دو رنگ داشته باشند" -#: ../src/metacity.schemas.in.h:5 -msgid "Arrangement of buttons on the titlebar" -msgstr "آرایش دکمه‌ها روی نوار عنوان" +#: ../src/ui/theme.c:1219 +#, fuzzy, c-format +#| msgid "" +#| "GTK color specification must have a close bracket after the state, e.g. " +#| "gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +msgid "GTK custom color specification must have color name and fallback in parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" +msgstr "در مشخصه‌ی رنگ GTK باید بعد از وضعیت، قلاب بسته داشته باشد، به طور مثال gtk:fg[NORMAL] که NORMAL وضعیت است: »%s» قابل تجزیه نیست" -#: ../src/metacity.schemas.in.h:6 -msgid "" -"Arrangement of buttons on the titlebar. The value should be a string, such " -"as \"menu:minimize,maximize,close\"; the colon separates the left corner of " -"the window from the right corner, and the button names are comma-separated. " -"Duplicate buttons are not allowed. Unknown button names are silently ignored " -"so that buttons can be added in future metacity versions without breaking " -"older versions." +#: ../src/ui/theme.c:1235 +#, c-format +msgid "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-_ are valid" msgstr "" -"آرایش دکمه‌ها روی نوار عنوان. مقدار باید یک رشته باشد. مثلاً «menu:minimize," -"maximize,close»؛ دونقطه، گوشه‌ی چپ پنجره را ازگوشه‌ی راست جدا می‌کند و نام " -"دکمه‌ها با ویرگول از هم جدا می‌شوند.دکمه تکراری مجاز نیست. دکمه‌های ناشناس در " -"سکوت نادیده گرفته می‌شوند تا دکمه‌های جدید بدون از کار انداختن نسخه‌های قدیمی‌تر " -"به نسخه‌های آینده‌ی متاسیتی اضافه شوند." -#: ../src/metacity.schemas.in.h:7 -msgid "Automatically raises the focused window" -msgstr "پنجره مورد تمرکز را به طور خودکار پیش‌بکشد." - -#: ../src/metacity.schemas.in.h:8 -msgid "" -"Clicking a window while holding down this modifier key will move the window " -"(left click), resize the window (middle click), or show the window menu " -"(right click). Modifier is expressed as \"<Alt>\" or \"<Super>\" " -"for example." -msgstr "" -"کلیک کردن روی یک پنجره در حین پایین نگه داشتن این کلید تغییردهنده، باعث حرکت " -"پنجره (کلیک چپ)، تغییر اندازه‌ی پنجره (کلیک وسط) یا نمایش منوی پنجره (کلیک " -"راست) می‌شود. تغییردهنده به صورت مثلاً«<Alt>» یا «<Super>» نمایش " -"داده می‌شود." +#: ../src/ui/theme.c:1249 +#, fuzzy, c-format +#| msgid "" +#| "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the " +#| "format" +msgid "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not fit the format" +msgstr "قالب سایه «shade/base_color/factor» است، «%s» در قالب اندازه نمی‌شود" -#: ../src/metacity.schemas.in.h:9 -msgid "Close window" -msgstr "بستن پنجره" +#: ../src/ui/theme.c:1294 +#, c-format +msgid "GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +msgstr "وضعیت در مشخصه‌ی رنگ GTK باید داخل قلاب نوشته شود، به طور مثال gtk:fg[NORMAL] که NORMAL وضعیت است: »%s» قابل تجزیه نیست" -#: ../src/metacity.schemas.in.h:10 -msgid "Commands to run in response to keybindings" -msgstr "فرمان‌هایی که در پاسخ به کلیدهای مقید اجرا می‌شوند" +#: ../src/ui/theme.c:1308 +#, c-format +msgid "GTK color specification must have a close bracket after the state, e.g. gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +msgstr "در مشخصه‌ی رنگ GTK باید بعد از وضعیت، قلاب بسته داشته باشد، به طور مثال gtk:fg[NORMAL] که NORMAL وضعیت است: »%s» قابل تجزیه نیست" -#: ../src/metacity.schemas.in.h:11 -msgid "Current theme" -msgstr "تم فعلی" +#: ../src/ui/theme.c:1319 +#, c-format +msgid "Did not understand state \"%s\" in color specification" +msgstr "وضعیت «%s» در مشخصه‌ی رنگ قابل درک نیست" -#: ../src/metacity.schemas.in.h:12 -msgid "Delay in milliseconds for the auto raise option" -msgstr "تأخیر به میلی ثانیه برای گزینه‌ی پیش آوردن خودکار " +#: ../src/ui/theme.c:1332 +#, c-format +msgid "Did not understand color component \"%s\" in color specification" +msgstr "مؤلفه‌ی «%s» در مشخصه‌ی رنگ قابل درک نیست" -#: ../src/metacity.schemas.in.h:13 -msgid "" -"Determines whether applications or the system can generate audible 'beeps'; " -"may be used in conjunction with 'visual bell' to allow silent 'beeps'." -msgstr "" -"مشخص می‌کند که برنامه‌ها یا سیستم می‌توانند «بوق» قابل شنیدن تولید کنند یا نه: " -"ممکن است همزمان با «زنگ دیداری» به کار رود تا «بوق» بی‌صدا امکان پذیر شود." +#: ../src/ui/theme.c:1361 +#, c-format +msgid "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the format" +msgstr "قالب ترکیب «blend/bg_color/fg_color/alpha» است، «%s» در قالب اندازه نمی‌شود" -#: ../src/metacity.schemas.in.h:14 -msgid "Disable misfeatures that are required by old or broken applications" -msgstr "" -"از کار انداختن امکانات معیوبی که مورد نیاز برنامه‌های قدمی یا از کارافتاده‌اند " - -#: ../src/metacity.schemas.in.h:15 -msgid "Enable Visual Bell" -msgstr "به کار انداختن زنگ دیداری" +#: ../src/ui/theme.c:1372 +#, c-format +msgid "Could not parse alpha value \"%s\" in blended color" +msgstr "ارزش آلفای «%s» در رنگ ترکیب شده قابل تجزیه نیست" -#: ../src/metacity.schemas.in.h:16 -msgid "Hide all windows and focus desktop" -msgstr "مخفی کردن همه‌ی پنجره‌ها و تمرکز روی رومیزی" +#: ../src/ui/theme.c:1382 +#, c-format +msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" +msgstr "ارزش آلفای «%s» در رنگ ترکیب شده بین ۰٫۰ و ۱٫۰ نیست" -#: ../src/metacity.schemas.in.h:17 -msgid "" -"If true, and the focus mode is either \"sloppy\" or \"mouse\" then the " -"focused window will be automatically raised after a delay (the delay is " -"specified by the auto_raise_delay key). This preference is poorly named, but " -"kept for backwards compatibility. To try to be more clear (at least to the " -"technically inclined), its meaning is \"automatically raise the window " -"following a timeout which is triggered by non-grabbed mouse entry in sloppy " -"or mouse focus modes\". It is unrelated to clicking behavior (i.e. this is " -"not related to raise-on-click/orthogonal-raise). It is unrelated to entering " -"a window during drag and drop (because that results in the application " -"grabbing the mouse)" -msgstr "" +#: ../src/ui/theme.c:1429 +#, c-format +msgid "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" +msgstr "قالب سایه «shade/base_color/factor» است، «%s» در قالب اندازه نمی‌شود" -#: ../src/metacity.schemas.in.h:18 -msgid "" -"If true, ignore the titlebar_font option, and use the standard application " -"font for window titles." -msgstr "" -"اگر درست باشد گزینه‌ی titlebar_font نادیده گرفته شده و برای عنوان پنجره‌ها از " -"قلم استاندارد برنامه استفاده می‌شود." +#: ../src/ui/theme.c:1440 +#, c-format +msgid "Could not parse shade factor \"%s\" in shaded color" +msgstr "‌عامل سایه‌ی «%s» در رنگ سایه خورده قابل تجزیه نیست" -#: ../src/metacity.schemas.in.h:19 -msgid "" -"If true, metacity will give the user less feedback and less sense of " -"\"direct manipulation\", by using wireframes, avoiding animations, or other " -"means. This is a significant reduction in usability for many users, but may " -"allow legacy applications and terminal servers to function when they would " -"otherwise be impractical. However, the wireframe feature is disabled when " -"accessibility is on to avoid weird desktop breakages." -msgstr "" -"اگر درست باشد، متاسیتی با استفاده از چارچوب‌های سیمی، نشان ندادن پویانمایی‌ها " -"یا به طرق دیگر، بازخوردهای کمتر و حس «دستکاری مستقیم» کمتری به کاربر می‌دهد. " -"این کار باعث تقلیل محسوس قابلیت کاربری برای بسیاری از کاربران می‌شود، ولی " -"شاید برنامه‌ها و کارگزارهای پایانه‌ی قدیمی را قادر سازد در شرایطی کار کنند که " -"در غیر این صورت کار نمی‌کردند. به هر حال هنگامی که دسترسی‌پذیری روشن است برای " -"جلوگیری از خرابی‌های غیرعادی رومیزی، امکانات چارچوب‌های سیمی از کار انداخته " -"می‌شود." - -#: ../src/metacity.schemas.in.h:20 -msgid "" -"If true, then Metacity works in terms of applications rather than windows. " -"The concept is a bit abstract, but in general an application-based setup is " -"more like the Mac and less like Windows. When you focus a window in " -"application-based mode, all the windows in the application will be raised. " -"Also, in application-based mode, focus clicks are not passed through to " -"windows in other applications. The existence of this setting is somewhat " -"questionable. But it's better than having settings for all the specific " -"details of application-based vs. window-based, e.g. whether to pass through " -"clicks. Also, application-based mode is largely unimplemented at the moment." -msgstr "" -"اگر درست باشد، متاسیتی بر مبنای برنامه‌ها کار می‌کند نه پنجره‌ها. این مفهوم کمی " -"مجرد است، ولی عموماً برپاسازی بر پایه‌ی برنامه بیشتر شبیه مکینتاش و کمتر شبیه " -"ویندوز است. در حالت بر پایه‌ی برنامه وقتی روی یک پنجره تمرکز می‌کنید، همه‌ی " -"پنجره‌های برنامه پیش می‌آیند. همچنین، در حالت بر پایه‌ی برنامه، کلیک‌های تمرکز " -"به پنجره‌های برنامه‌های دیگر رد نمی‌شوند. وجود این تنظیمات تا حدودی سؤال " -"برانگیز است. ولی بهتر از داشتن تنظیمات برای همه‌ی جزئیات خاص بر پایه‌ی برنامه " -"در برابر بر پایه‌ی پنجره است، مثلاً این که کلیک ‌ها رد بشوند یا نه. در ضمن، " -"حالت بر پایه‌ی برنامه در حال حاضر تا حدود زیادی پیاده‌سازی نشده است." - -#: ../src/metacity.schemas.in.h:21 -msgid "If true, trade off usability for less resource usage" -msgstr "" -"اگر درست بود از قابلیت کاربری در قبال استفاده‌ی کمتر از منابع صرف نظر شود" +#: ../src/ui/theme.c:1450 +#, c-format +msgid "Shade factor \"%s\" in shaded color is negative" +msgstr "عامل سایه‌ی «%s» در رنگ سایه خورده منفی است" -#: ../src/metacity.schemas.in.h:22 -msgid "Lower window below other windows" -msgstr "پایین بردن پنجره زیر پنجره‌های دیگر" +#: ../src/ui/theme.c:1479 +#, c-format +msgid "Could not parse color \"%s\"" +msgstr "رنگ «%s» قابل تجزیه نیست" -#: ../src/metacity.schemas.in.h:23 -msgid "" -"Many actions (e.g. clicking in the client area, moving or resizing the " -"window) normally raise the window as a side-effect. Set this option to false " -"to decouple raising from other user interactions. When false, windows can " -"still be raised by an alt-left-click anywhere on the window or a normal " -"click on the window decorations (assuming such clicks aren't used to start a " -"move or resize operation). Special messages, such as activation requests " -"from pagers, may also raise windows when this option is false. This option " -"is currently disabled in click-to-focus mode." -msgstr "" +#: ../src/ui/theme.c:1790 +#, c-format +msgid "Coordinate expression contains character '%s' which is not allowed" +msgstr "عبارت مختصاتی شامل نویسه‌ی «%s» است که جایز نیست" -#: ../src/metacity.schemas.in.h:24 -msgid "Maximize window" -msgstr "حداکثر کردن پنجره" +#: ../src/ui/theme.c:1817 +#, c-format +msgid "Coordinate expression contains floating point number '%s' which could not be parsed" +msgstr "عبارت مختصاتی شامل عدد اعشار ممیز شناور «%s» است که قابل تجزیه نیست" -#: ../src/metacity.schemas.in.h:25 -msgid "Maximize window horizontally" -msgstr "حداکثر کردن افقی پنجره" +#: ../src/ui/theme.c:1831 +#, c-format +msgid "Coordinate expression contains integer '%s' which could not be parsed" +msgstr "عبارت مختصاتی شامل عددصحیح «%s» است که قابل تجزیه نیست" -#: ../src/metacity.schemas.in.h:26 -msgid "Maximize window vertically" -msgstr "حداکثر کردن عمودی پنجره" +#: ../src/ui/theme.c:1953 +#, c-format +msgid "Coordinate expression contained unknown operator at the start of this text: \"%s\"" +msgstr "عبارت مختصاتی شامل عملگر نامعلومی در ابتدای متن است: «%s»" -#: ../src/metacity.schemas.in.h:27 -msgid "Minimize window" -msgstr "حداقل کردن پنجره" +#: ../src/ui/theme.c:2010 +#, c-format +msgid "Coordinate expression was empty or not understood" +msgstr "عبارت مختصاتی خالی بود یا قابل درک نبود" -#: ../src/metacity.schemas.in.h:28 -msgid "Modifier to use for modified window click actions" -msgstr "" -"تغییردهنده‌ای که برای کنش‌های کلیک روی پنجره‌ی تغییر داده شده به کار می‌رود" +#: ../src/ui/theme.c:2121 +#: ../src/ui/theme.c:2131 +#: ../src/ui/theme.c:2165 +#, c-format +msgid "Coordinate expression results in division by zero" +msgstr "عبارت مختصاتی موجب تقسیم به صفر می‌شود" -#: ../src/metacity.schemas.in.h:29 -msgid "Move backward between panels and the desktop immediately" -msgstr "جابه‌جایی آنی به عقب بین تابلو و رومیزی" +#: ../src/ui/theme.c:2173 +#, c-format +msgid "Coordinate expression tries to use mod operator on a floating-point number" +msgstr "عبارت مختصاتی سعی دارد از عملگر باقی مانده روی عدد اعشاری ممیز شناوری استفاد کند" -#: ../src/metacity.schemas.in.h:30 -msgid "Move backwards between panels and the desktop with popup" -msgstr "جابه‌جایی به عقب بین تابلوها و رومیزی با واشو" +#: ../src/ui/theme.c:2229 +#, c-format +msgid "Coordinate expression has an operator \"%s\" where an operand was expected" +msgstr " عبارت مختصاتی در جایی که انتظار عملوند می‌رفت، عملگر«%s» داشت" -#: ../src/metacity.schemas.in.h:31 -msgid "Move backwards between windows immediately" -msgstr "جابه‌جایی آنی به عقب بین پنجره‌ها" +#: ../src/ui/theme.c:2238 +#, c-format +msgid "Coordinate expression had an operand where an operator was expected" +msgstr "عبارت مختصاتی در جایی که انتظار عملگر " -#: ../src/metacity.schemas.in.h:32 -msgid "Move between panels and the desktop immediately" -msgstr "جابه‌جایی آنی بین تابلو و رومیزی" +#: ../src/ui/theme.c:2246 +#, c-format +msgid "Coordinate expression ended with an operator instead of an operand" +msgstr "عبارت مختصاتی به جای عملوند با عملگر تمام می‌شود" -#: ../src/metacity.schemas.in.h:33 -msgid "Move between panels and the desktop with popup" -msgstr "جابه‌جایی بین تابلوها و رومیزی با واشو" +#: ../src/ui/theme.c:2256 +#, c-format +msgid "Coordinate expression has operator \"%c\" following operator \"%c\" with no operand in between" +msgstr "در عبارت مختصاتی، عملگر «%c» بدون هیچ عملوندی به دنبال عملگر «%c» آمده است" -#: ../src/metacity.schemas.in.h:34 -msgid "Move between windows immediately" -msgstr "جابه‌جایی آنی بین پنجره‌ها" +#: ../src/ui/theme.c:2407 +#: ../src/ui/theme.c:2452 +#, c-format +msgid "Coordinate expression had unknown variable or constant \"%s\"" +msgstr "عبارت مختصاتی متغییر یا ثابت «%s» نامعلوم دارد" -#: ../src/metacity.schemas.in.h:35 -msgid "Move between windows with popup" -msgstr "جابه‌جایی بین پنجره‌ها با واشو" +#: ../src/ui/theme.c:2506 +#, fuzzy, c-format +#| msgid "Coordinate expression was empty or not understood" +msgid "Coordinate expression parser overflowed its buffer." +msgstr "عبارت مختصاتی خالی بود یا قابل درک نبود" -#: ../src/metacity.schemas.in.h:36 -msgid "Move focus backwards between windows using popup display" -msgstr "انتقال تمرکز به عقب بین پنجره‌ها با نمایش واشو" +#: ../src/ui/theme.c:2535 +#, c-format +msgid "Coordinate expression had a close parenthesis with no open parenthesis" +msgstr "عبارت مختصاتی پرانتر بسته‌ای دارد که پرانتز باز ندارد" -#: ../src/metacity.schemas.in.h:37 -msgid "Move window" -msgstr "جابه‌جایی پنجره" +#: ../src/ui/theme.c:2599 +#, c-format +msgid "Coordinate expression had an open parenthesis with no close parenthesis" +msgstr "عبارت مختصاتی پرانتر بازی دارد که پرانتز بسته ندارد" -#: ../src/metacity.schemas.in.h:38 -msgid "Move window one workspace down" -msgstr "جابه‌جایی پنجره به فضای کاری پایینی" +#: ../src/ui/theme.c:2610 +#, c-format +msgid "Coordinate expression doesn't seem to have any operators or operands" +msgstr "به نظر نمی‌رسد که عبارت مختصاتی عملگر یا عملوندی داشته باشد" -#: ../src/metacity.schemas.in.h:39 -msgid "Move window one workspace to the left" -msgstr "جابه‌جایی پنجره به فضای کاری چپ " +#: ../src/ui/theme.c:2822 +#: ../src/ui/theme.c:2842 +#: ../src/ui/theme.c:2862 +#, fuzzy, c-format +#| msgid "Theme contained an expression \"%s\" that resulted in an error: %s\n" +msgid "Theme contained an expression that resulted in an error: %s\n" +msgstr "تم شامل عبارت «%s» است که منجر به خطا می‌شود: %s\n" -#: ../src/metacity.schemas.in.h:40 -msgid "Move window one workspace to the right" -msgstr "جابه‌جایی پنجره به فضای کاری راست" +#: ../src/ui/theme.c:4533 +#, c-format +msgid "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be specified for this frame style" +msgstr "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/>باید برای این سبک چارچوب مشخص شود" -#: ../src/metacity.schemas.in.h:41 -msgid "Move window one workspace up" -msgstr "جابه‌جایی پنجره به فضای کاری بالایی" +#: ../src/ui/theme.c:5066 +#: ../src/ui/theme.c:5091 +#, c-format +msgid "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" +msgstr "<frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/> نبود" -#: ../src/metacity.schemas.in.h:42 -msgid "Move window to workspace 1" -msgstr "جابه‌جایی پنجره به فضای کاری ۱" +#: ../src/ui/theme.c:5139 +#, c-format +msgid "Failed to load theme \"%s\": %s\n" +msgstr "شکست در بارکردن تم «%s»: %s\n" -#: ../src/metacity.schemas.in.h:43 -msgid "Move window to workspace 10" -msgstr "جابه‌جایی پنجره به فضای کاری ۱۰" +#: ../src/ui/theme.c:5275 +#: ../src/ui/theme.c:5282 +#: ../src/ui/theme.c:5289 +#: ../src/ui/theme.c:5296 +#: ../src/ui/theme.c:5303 +#, c-format +msgid "No <%s> set for theme \"%s\"" +msgstr "<%s> برای تم «%s» تنظیم نشده است" -#: ../src/metacity.schemas.in.h:44 -msgid "Move window to workspace 11" -msgstr "جابه‌جایی پنجره به فضای کاری ۱۱" +#: ../src/ui/theme.c:5311 +#, c-format +msgid "No frame style set for window type \"%s\" in theme \"%s\", add a <window type=\"%s\" style_set=\"whatever\"/> element" +msgstr "سبک جارچوب برای نوع پنجره «%s» در تم «%s» تنظیم نشده است، یک عنصر <window type=\"%s\" style_set=\"whatever\"/> اضافه کنید" -#: ../src/metacity.schemas.in.h:45 -msgid "Move window to workspace 12" -msgstr "جابه‌جایی پنجره به فضای کاری ۱۲" +#: ../src/ui/theme.c:5709 +#: ../src/ui/theme.c:5771 +#: ../src/ui/theme.c:5834 +#, c-format +msgid "User-defined constants must begin with a capital letter; \"%s\" does not" +msgstr "ثابت‌هایی که کاربر تعریف کرده اسن باید با حروف بزرگ شروع شوند؛ «%s» این طور نیست " -#: ../src/metacity.schemas.in.h:46 -msgid "Move window to workspace 2" -msgstr "جابه‌جایی پنجره به فضای کاری ۲" +#: ../src/ui/theme.c:5717 +#: ../src/ui/theme.c:5779 +#: ../src/ui/theme.c:5842 +#, c-format +msgid "Constant \"%s\" has already been defined" +msgstr "ثابت «%s» قبلاً تعریف شده است" -#: ../src/metacity.schemas.in.h:47 -msgid "Move window to workspace 3" -msgstr "نقل‌مکان پنجره به فضای کاری ۳" +#. Translators: This means that an attribute which should have been found +#. * on an XML element was not in fact found. +#. +#: ../src/ui/theme-parser.c:236 +#, c-format +msgid "No \"%s\" attribute on element <%s>" +msgstr "عنصر <%2$s> مشخصه‌ی «%1$s» ندارد" -#: ../src/metacity.schemas.in.h:48 -msgid "Move window to workspace 4" -msgstr "جابه‌جایی پنجره به فضای کاری ۴" +#: ../src/ui/theme-parser.c:265 +#: ../src/ui/theme-parser.c:283 +#, c-format +msgid "Line %d character %d: %s" +msgstr "خط %Id نویسه‌ی %Id: %s" -#: ../src/metacity.schemas.in.h:49 -msgid "Move window to workspace 5" -msgstr "جابه‌جایی پنجره به فضای کاری ۵" +#: ../src/ui/theme-parser.c:479 +#, c-format +msgid "Attribute \"%s\" repeated twice on the same <%s> element" +msgstr "مشخصه‌ی «%s» در عنصر <%s> دو بار تکرار شده است" -#: ../src/metacity.schemas.in.h:50 -msgid "Move window to workspace 6" -msgstr "جابه‌جایی پنجره به فضای کاری ۶" +#: ../src/ui/theme-parser.c:503 +#: ../src/ui/theme-parser.c:552 +#, c-format +msgid "Attribute \"%s\" is invalid on <%s> element in this context" +msgstr "مشخصه‌ی «%s» در این موقعیت روی عنصر <%s> نامعتبر است" -#: ../src/metacity.schemas.in.h:51 -msgid "Move window to workspace 7" -msgstr "جابه‌جایی پنجره به فضای کاری ۷" +#: ../src/ui/theme-parser.c:594 +#, c-format +msgid "Could not parse \"%s\" as an integer" +msgstr "«%s»به عنوان عدد صحیح قابل تجزیه نیست " -#: ../src/metacity.schemas.in.h:52 -msgid "Move window to workspace 8" -msgstr "جابه‌جایی پنجره به فضای کاری ۸" +#: ../src/ui/theme-parser.c:603 +#: ../src/ui/theme-parser.c:658 +#, c-format +msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +msgstr "نویسه‌ی «%s» در رشته‌ی «%s» قابل درک نیست" -#: ../src/metacity.schemas.in.h:53 -msgid "Move window to workspace 9" -msgstr "جابه‌جایی پنجره به فضای کاری ۹" +#: ../src/ui/theme-parser.c:613 +#, c-format +msgid "Integer %ld must be positive" +msgstr "عدد صحیح %ld باید مثبت باشد" -#: ../src/metacity.schemas.in.h:54 -msgid "Name of workspace" -msgstr "نام فضای کاری" +#: ../src/ui/theme-parser.c:621 +#, c-format +msgid "Integer %ld is too large, current max is %d" +msgstr "عدد صحیح %ld خیلی بزرگ است، حداکثر فعلی %d است" -#: ../src/metacity.schemas.in.h:55 -msgid "Number of workspaces" -msgstr "تعداد فضاهای کاری" +#: ../src/ui/theme-parser.c:649 +#: ../src/ui/theme-parser.c:765 +#, c-format +msgid "Could not parse \"%s\" as a floating point number" +msgstr "«%s» به عنوان عدد اعشاری ممیز شناور قابل تجزیه نیست" -#: ../src/metacity.schemas.in.h:56 -msgid "" -"Number of workspaces. Must be more than zero, and has a fixed maximum (to " -"prevent accidentally destroying your desktop by asking for 34 million " -"workspaces)." -msgstr "" -"تعداد فضاهای کاری. باید بیش از صفر باشد و حداکثر مشخصی دارد (برای این که " -"اتفاقی رومیزی‌تان را با درخواست ۳۴ میلیون فضای کاری از بین نبرید)." +#: ../src/ui/theme-parser.c:680 +#: ../src/ui/theme-parser.c:708 +#, c-format +msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" +msgstr "مقدار بولی باید «درست» یا «نادرست» باشد نه «%s»" -#: ../src/metacity.schemas.in.h:57 -msgid "Raise obscured window, otherwise lower" -msgstr "" +#: ../src/ui/theme-parser.c:735 +#, c-format +msgid "Angle must be between 0.0 and 360.0, was %g\n" +msgstr "زاویه %Ig بود، باید بین ۰٫۰ و ۳۶۰٫۰ باشد\n" -#: ../src/metacity.schemas.in.h:58 -msgid "Raise window above other windows" -msgstr "پیش آوردن پنجره روی همه‌ی پنجره‌ها" +#: ../src/ui/theme-parser.c:798 +#, c-format +msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" +msgstr "آلفا %Ig بود، باید بین ۰٫۰ (نامرئی) و ۱٫۰ (به تمامی تیره) باشد\n" -#: ../src/metacity.schemas.in.h:59 -msgid "Resize window" -msgstr "تغییر اندازه‌ی پنجره" +#: ../src/ui/theme-parser.c:863 +#, c-format +msgid "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium,large,x-large,xx-large)\n" +msgstr "مقیاس عنوان «%s» نامعتبر است (باید xx-small یا x-small یا small یا medium یا large یا x-large یا xx-large باشد)\n" -#: ../src/metacity.schemas.in.h:60 -msgid "Run a defined command" -msgstr "اجرای یک فرمان تعریف شده" +#: ../src/ui/theme-parser.c:1019 +#: ../src/ui/theme-parser.c:1082 +#: ../src/ui/theme-parser.c:1116 +#: ../src/ui/theme-parser.c:1219 +#, c-format +msgid "<%s> name \"%s\" used a second time" +msgstr "<%s> نام «%s» برای بار دوم استفاده شده است" -#: ../src/metacity.schemas.in.h:61 -msgid "Run a terminal" -msgstr "اجرای پایانه" +#: ../src/ui/theme-parser.c:1031 +#: ../src/ui/theme-parser.c:1128 +#: ../src/ui/theme-parser.c:1231 +#, c-format +msgid "<%s> parent \"%s\" has not been defined" +msgstr "<%s> والد «%s» تعریف نشده است" -#: ../src/metacity.schemas.in.h:62 -msgid "Show the panel menu" -msgstr "نشان دادن منوی تابلو" +#: ../src/ui/theme-parser.c:1141 +#, c-format +msgid "<%s> geometry \"%s\" has not been defined" +msgstr "<%s> پیکربندی ظاهری «%s» تعریف نشده است" -#: ../src/metacity.schemas.in.h:63 -msgid "Show the panel run application dialog" -msgstr "نشان دادن محاوره‌ی اجرای برنامه‌ی تابلو" +#: ../src/ui/theme-parser.c:1154 +#, c-format +msgid "<%s> must specify either a geometry or a parent that has a geometry" +msgstr "<%s> باید پیکربندی ظاهری یا والدی که پیکربندی ظاهری داشته باشد مشخص شود" -#: ../src/metacity.schemas.in.h:64 -msgid "" -"Some applications break specifications in ways that result in window manager " -"misfeatures. For example, ideally Metacity would place all dialogs in a " -"consistent position with respect to their parent window. This requires " -"ignoring application-specified positions for dialogs. But some versions of " -"Java/Swing mark their popup menus as dialogs, so Metacity has to disable " -"dialog positioning to allow menus to work in broken Java applications. There " -"are several other examples like this. This option puts Metacity in full-on " -"Correct mode, which perhaps gives a moderately nicer UI if you don't need to " -"run any broken apps. Sadly, workarounds must be enabled by default; the real " -"world is an ugly place. Some of the workarounds are workarounds for " -"limitations in the specifications themselves, so sometimes a bug in no-" -"workarounds mode won't be fixable without amending a spec." +#: ../src/ui/theme-parser.c:1196 +msgid "You must specify a background for an alpha value to be meaningful" msgstr "" -"بعضی از برنامه‌ها قواعد جزئی را طوری نقض می‌کنند که به بد کار کردن مدیر " -"پنجره‌ها منجر می‌شود. به عنوان مثال، متاسیتی در وضع مطلوب تمام محاوره‌ها را در " -"وضعیت سازگار با پنجره‌ی والد آن‌ها قرار می‌دهد. این مسأله نیازمند نادیده گرفتن " -"مشخصات برنامه‌ها برای وضعیت محاوره‌ها است. اما بعضی از نسخه‌های Java/Swing " -"منوهای واشو را به عنوان محاوره ثبت می‌کنند و متاسیتی مجبور است برای کار کردن " -"منوها در برنامه‌های خراب جاوا جاگذاری محاوره را از کار بیاندازد. مثال‌های " -"مختلف دیگری نیز از این دست وجود دارند. این گزینه متاسیتی را در حالت درست با " -"همه‌ی گزینه‌ها قرار می‌دهد که احتمالاً اگر نیاز به اجرای برنامه‌های خراب نداشته " -"باشید، واسط کاربر بهتری خواهد داشت. متأسفانه دور زدن‌ها را باید به طور پیش " -"فرض به کار انداخت؛ دنیای واقعی جای زشتی است. بعضی از دور زدن‌ها دورزدن " -"کمبودهای خود قواعد جزئی هستند، بنابراین بعضی وقت‌ها اشکال در حالت دور زدن " -"بدون دستکاری قواعد قبل رفع نیست." - -#: ../src/metacity.schemas.in.h:65 -msgid "Switch to workspace 1" -msgstr "تعویض به فضای کاری ۱" -#: ../src/metacity.schemas.in.h:66 -msgid "Switch to workspace 10" -msgstr "تعویض به فضای کاری ۱۰" +#: ../src/ui/theme-parser.c:1264 +#, c-format +msgid "Unknown type \"%s\" on <%s> element" +msgstr "نوع «%s» روی عنصر <%s> نامعلوم است" -#: ../src/metacity.schemas.in.h:67 -msgid "Switch to workspace 11" -msgstr "تعویض به فضای کاری ۱۱" +#: ../src/ui/theme-parser.c:1275 +#, c-format +msgid "Unknown style_set \"%s\" on <%s> element" +msgstr "style_set «%s» روی عنصر <%s> نامعلوم است" -#: ../src/metacity.schemas.in.h:68 -msgid "Switch to workspace 12" -msgstr "تعویض به فضای کاری ۱۲" +#: ../src/ui/theme-parser.c:1283 +#, c-format +msgid "Window type \"%s\" has already been assigned a style set" +msgstr " نوع پنجره‌ی «%s» قبلاً به یک مجموعه‌ی سبک تخصیص داد شده است" -#: ../src/metacity.schemas.in.h:69 -msgid "Switch to workspace 2" -msgstr "تعویض به فضای کاری ۲" +#: ../src/ui/theme-parser.c:1313 +#: ../src/ui/theme-parser.c:1377 +#: ../src/ui/theme-parser.c:1603 +#: ../src/ui/theme-parser.c:2838 +#: ../src/ui/theme-parser.c:2884 +#: ../src/ui/theme-parser.c:3034 +#: ../src/ui/theme-parser.c:3273 +#: ../src/ui/theme-parser.c:3311 +#: ../src/ui/theme-parser.c:3349 +#: ../src/ui/theme-parser.c:3387 +#, c-format +msgid "Element <%s> is not allowed below <%s>" +msgstr "عنصر <%s> زیر <%s> مجاز نیست" -#: ../src/metacity.schemas.in.h:70 -msgid "Switch to workspace 3" -msgstr "تعویض به فضای کاری ۳" +#: ../src/ui/theme-parser.c:1427 +#: ../src/ui/theme-parser.c:1441 +#: ../src/ui/theme-parser.c:1486 +#, fuzzy +#| msgid "" +#| "Cannot specify both button_width/button_height and aspect ratio for " +#| "buttons" +msgid "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" for buttons" +msgstr "button_width/button_height و نسبت عرض به ارتفاع دکمه‌ها هم زمان مشخص نمی‌شوند " -#: ../src/metacity.schemas.in.h:71 -msgid "Switch to workspace 4" -msgstr "تعویض به فضای کاری ۴" +#: ../src/ui/theme-parser.c:1450 +#, c-format +msgid "Distance \"%s\" is unknown" +msgstr "فاصله‌ی «%s» نامعلوم است" -#: ../src/metacity.schemas.in.h:72 -msgid "Switch to workspace 5" -msgstr "تعویض به فضای کاری ۵" +#: ../src/ui/theme-parser.c:1495 +#, c-format +msgid "Aspect ratio \"%s\" is unknown" +msgstr "نسبت عرض به ارتفاع «%s» نامعلوم است" -#: ../src/metacity.schemas.in.h:73 -msgid "Switch to workspace 6" -msgstr "تعویض به فضای کاری ۶" +#: ../src/ui/theme-parser.c:1557 +#, c-format +msgid "Border \"%s\" is unknown" +msgstr "کناره‌ی «%s» نامعلوم است" -#: ../src/metacity.schemas.in.h:74 -msgid "Switch to workspace 7" -msgstr "تعویض به فضای کاری ۷" +#: ../src/ui/theme-parser.c:1868 +#, fuzzy, c-format +#| msgid "No \"start_angle\" attribute on element <%s>" +msgid "No \"start_angle\" or \"from\" attribute on element <%s>" +msgstr "عنصر <%s> مشخصه‌ی «start_angle» ندارد" -#: ../src/metacity.schemas.in.h:75 -msgid "Switch to workspace 8" -msgstr "تعویض به فضای کاری ۸" +#: ../src/ui/theme-parser.c:1875 +#, fuzzy, c-format +#| msgid "No \"extent_angle\" attribute on element <%s>" +msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" +msgstr "عنصر <%s> مشخصه‌ی «extent_angle» ندارد" -#: ../src/metacity.schemas.in.h:76 -msgid "Switch to workspace 9" -msgstr "تعویض به فضای کاری ۹" +#: ../src/ui/theme-parser.c:2115 +#, c-format +msgid "Did not understand value \"%s\" for type of gradient" +msgstr "مقدار «%s» برای نوع شیب قابل درک نیست" -#: ../src/metacity.schemas.in.h:77 -msgid "Switch to workspace above this one" -msgstr "تعویض به فضای کاری بالایی" +#: ../src/ui/theme-parser.c:2193 +#: ../src/ui/theme-parser.c:2568 +#, c-format +msgid "Did not understand fill type \"%s\" for <%s> element" +msgstr "" -#: ../src/metacity.schemas.in.h:78 -msgid "Switch to workspace below this one" -msgstr "تعویض به فضای کاری پایینی" +#: ../src/ui/theme-parser.c:2360 +#: ../src/ui/theme-parser.c:2443 +#: ../src/ui/theme-parser.c:2506 +#, c-format +msgid "Did not understand state \"%s\" for <%s> element" +msgstr "وضعیت «%s» برای عنصر <%s> قابل درک نیست" -#: ../src/metacity.schemas.in.h:79 -msgid "Switch to workspace on the left" -msgstr "تعویض به فضای کاری چپ" +#: ../src/ui/theme-parser.c:2370 +#: ../src/ui/theme-parser.c:2453 +#, c-format +msgid "Did not understand shadow \"%s\" for <%s> element" +msgstr "سایه‌ی «%s» برای عنصر <%s> قابل درک نیست" -#: ../src/metacity.schemas.in.h:80 -msgid "Switch to workspace on the right" -msgstr "تعویض به فضای کاری راست" +#: ../src/ui/theme-parser.c:2380 +#, c-format +msgid "Did not understand arrow \"%s\" for <%s> element" +msgstr "پیکان «%s» برای عنصر <%s> قابل درک نیست" -#: ../src/metacity.schemas.in.h:81 -msgid "System Bell is Audible" -msgstr "زنگ سیستم قابل شنیدن است" +#: ../src/ui/theme-parser.c:2694 +#: ../src/ui/theme-parser.c:2790 +#, c-format +msgid "No <draw_ops> called \"%s\" has been defined" +msgstr "<draw_ops> با نام «%s» تعریف نشده است" -#: ../src/metacity.schemas.in.h:82 -msgid "Take a screenshot" -msgstr "عکس گرفتن از صفحه" +#: ../src/ui/theme-parser.c:2706 +#: ../src/ui/theme-parser.c:2802 +#, c-format +msgid "Including draw_ops \"%s\" here would create a circular reference" +msgstr "گنجاندن draw_ops «%s» در اینجا، مرجع دوری ایجاد می‌کند" -#: ../src/metacity.schemas.in.h:83 -msgid "Take a screenshot of a window" -msgstr "عکس گرفتن از پنجره " +#: ../src/ui/theme-parser.c:2917 +#, c-format +msgid "Unknown position \"%s\" for frame piece" +msgstr "موقعیت «%s» برای قطعه‌ی چارچوب نامعلوم است" -#: ../src/metacity.schemas.in.h:84 -msgid "" -"Tells Metacity how to implement the visual indication that the system bell " -"or another application 'bell' indicator has been rung. Currently there are " -"two valid values, \"fullscreen\", which causes a fullscreen white-black " -"flash, and \"frame_flash\" which causes the titlebar of the application " -"which sent the bell signal to flash. If the application which sent the bell " -"is unknown (as is usually the case for the default \"system beep\"), the " -"currently focused window's titlebar is flashed." -msgstr "" -"به متاسیتی می‌گوید چطور شاخص تصویری‌ای که زنگ سیستم یا برنامه‌ی شاخص «زنگ» " -"دیگری به صدا در آمده است را پیاده‌سازی کند. در حال حاضر دو مقدار معتبر وجود " -"دارند، «fullscreen» که سبب یک جرقه‌ی سیاه و سفید تمام‌صفحه می‌شود، و " -"«frame_flsh» که سبب می‌شود نوار عنوان برنامه‌ای که سیگنال زنگ را ارسال کرده " -"جرقه بزند. اگر برنامه‌ای که سیگنال زنگ را فرستاده نامعلوم باشد (که معمولاً در " -"مورد برای «بوق سیستم» پیش‌فرض این طور است)، نوار عنوان پنجره‌ای که فعلاً مورد " -"تمرکز است جرقه می‌زند." - -#: ../src/metacity.schemas.in.h:85 -msgid "" -"The /apps/metacity/global_keybindings/run_command_N keys define keybindings " -"that correspond to these commands. Pressing the keybinding for run_command_N " -"will execute command_N." -msgstr "" -"کلیدهای /apps/metacity/global_keybindings/run_command_N کلیدهای مقیدی تعریف " -"می‌کنند که متناظر با این فرمان‌ها هستند. فشار دادن کلید مقید برای " -"run_command_N، command_N را اجرا خواهد کرد." +#: ../src/ui/theme-parser.c:2925 +#, c-format +msgid "Frame style already has a piece at position %s" +msgstr "سبک چارچوب در حال حاضر قطعه‌ای در موقعیت %s دارد" -#: ../src/metacity.schemas.in.h:86 -msgid "" -"The /apps/metacity/global_keybindings/run_command_screenshot key defines a " -"keybinding which causes the command specified by this setting to be invoked." -msgstr "" -"کلید /apps/metacity/global_keybindings/run_command_screenshot کلید مقیدی " -"تعریف می‌کند که سبب می‌شود فرمان مشخص شده با این تنظیم احضار شود." +#: ../src/ui/theme-parser.c:2942 +#: ../src/ui/theme-parser.c:3019 +#, c-format +msgid "No <draw_ops> with the name \"%s\" has been defined" +msgstr "<draw_ops> با نام «%s» تعریف نشده است" -#: ../src/metacity.schemas.in.h:87 -msgid "" -"The /apps/metacity/global_keybindings/run_command_window_screenshot key " -"defines a keybinding which causes the command specified by this setting to " -"be invoked." -msgstr "" -"کلید /apps/metacity/global_keybindings/run_command_window_screenshot کلید " -"مقیدی تعریف می‌کند که سبب می‌شود فرمان مشخص شده با این تنظیم احضار شود." +#: ../src/ui/theme-parser.c:2972 +#, c-format +msgid "Unknown function \"%s\" for button" +msgstr "تابع «%s» برای دکمه نامعلوم است" -#: ../src/metacity.schemas.in.h:88 -msgid "" -"The keybinding that runs the correspondingly-numbered command in /apps/" -"metacity/keybinding_commands The format looks like \"<Control>a\" or " -"\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -"lower or upper case, and also abbreviations such as \"<Ctl>\" and " -"\"<Ctrl>\". If you set the option to the special string \"disabled\", " -"then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلیدی که فرمان correspondingly-numbered را در/appsmetacity/" -"keybinding_commands اجرا می‌کند: قالب آن به شکل«<Control>a» یا «<" -"Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا " -"کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول می‌کند. اگر " -"این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این " -"کنش وجود نخواهد داشت." - -#: ../src/metacity.schemas.in.h:89 -msgid "" -"The keybinding that switches to the workspace above the current workspace. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." +#: ../src/ui/theme-parser.c:2982 +#, c-format +msgid "Button function \"%s\" does not exist in this version (%d, need %d)" msgstr "" -"مقیدسازی کلیدی که فضای کاری فعلی را با فضای کاری بالایی تعویض می‌کند؛ قالب آن " -"به شکل«<Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر به " -"نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و " -"«<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی " -"«disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/metacity.schemas.in.h:90 -msgid "" -"The keybinding that switches to the workspace below the current workspace. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"مقیدسازی کلیدی که فضای کاری فعلی را با فضای کاری پایینی تعویض می‌کند؛ قالب آن " -"به شکل «<Control>a» یا «<Shift><Alt>F1»است. این تجزیه‌گر به " -"نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و " -"«<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی " -"«disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-parser.c:2994 +#, c-format +msgid "Unknown state \"%s\" for button" +msgstr "وضعیت «%s» برای دکمه نامعلوم است" -#: ../src/metacity.schemas.in.h:91 -msgid "" -"The keybinding that switches to the workspace on the left of the current " -"workspace. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" -"مقیدسازی کلیدی که فضای کاری فعلی را با فضای کاری چپش تعویض می‌کند؛ قالب آن به " -"شکل «<Control>a» یا «<Shift><Alt>F1»است. این تجزیه‌گر به " -"نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و " -"«<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی " -"«disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-parser.c:3002 +#, c-format +msgid "Frame style already has a button for function %s state %s" +msgstr "سبک چارچوب در حال حاضر برای تابع %s وضعیت %s دکمه دارد" -#: ../src/metacity.schemas.in.h:92 -msgid "" -"The keybinding that switches to the workspace on the right of the current " -"workspace. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" -"مقیدسازی کلیدی که فضای کاری فعلی را با فضای کاری راستش تعویض می‌کند؛ قالب آن " -"به شکل «<Control>a» یا «<Shift><Alt>F1»است. این تجزیه‌گر به " -"نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و " -"«<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی " -"«disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-parser.c:3073 +#, c-format +msgid "\"%s\" is not a valid value for focus attribute" +msgstr "«%s» مقدار معتبری برای مشخصه‌ی تمرکز نیست" -#: ../src/metacity.schemas.in.h:93 -msgid "" -"The keybinding that switches to workspace 1. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلید برای تعویض به فضای کاری ۱. قالب آن به شکل «<Control>a» " -"یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف " -"بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول " -"می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید " -"مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-parser.c:3082 +#, c-format +msgid "\"%s\" is not a valid value for state attribute" +msgstr "«%s» مقدار معتبری برای مشخصه‌ی وضعیت نیست" -#: ../src/metacity.schemas.in.h:94 -msgid "" -"The keybinding that switches to workspace 10. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلید برای تعویض به فضای کاری ۱۰. قالب آن به شکل «<Control>a» " -"یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف " -"بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول " -"می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید " -"مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-parser.c:3092 +#, c-format +msgid "A style called \"%s\" has not been defined" +msgstr "سبکی با نام «%s» تعریف نشده است" -#: ../src/metacity.schemas.in.h:95 -msgid "" -"The keybinding that switches to workspace 11. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلید برای تعویض به فضای کاری ۱۱. قالب آن به شکل «<Control>a» " -"یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف " -"بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول " -"می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید " -"مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-parser.c:3113 +#: ../src/ui/theme-parser.c:3136 +#, c-format +msgid "\"%s\" is not a valid value for resize attribute" +msgstr "«%s» مقدار معتبری برای مشخصه‌ی تغییر اندازه نیست" -#: ../src/metacity.schemas.in.h:96 -msgid "" -"The keybinding that switches to workspace 12. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلید برای تعویض به فضای کاری ۱۲. قالب آن به شکل «<Control>a» " -"یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف " -"بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول " -"می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید " -"مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-parser.c:3147 +#, c-format +msgid "Should not have \"resize\" attribute on <%s> element for maximized/shaded states" +msgstr "عنصر <%s> در وضعیت‌های حداکثر و سایه خورده مشخصه‌ی «resize» نباید داشته باشد" -#: ../src/metacity.schemas.in.h:97 -msgid "" -"The keybinding that switches to workspace 2. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلید برای تعویض به فضای کاری ۲. قالب آن به شکل «<Control>a» " -"یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف " -"بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول " -"می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید " -"مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-parser.c:3161 +#, fuzzy, c-format +#| msgid "" +#| "Should not have \"resize\" attribute on <%s> element for maximized/shaded " +#| "states" +msgid "Should not have \"resize\" attribute on <%s> element for maximized states" +msgstr "عنصر <%s> در وضعیت‌های حداکثر و سایه خورده مشخصه‌ی «resize» نباید داشته باشد" -#: ../src/metacity.schemas.in.h:98 -msgid "" -"The keybinding that switches to workspace 3. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلید برای تعویض به فضای کاری ۳. قالب آن به شکل «<Control>a» " -"یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف " -"بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول " -"می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید " -"مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-parser.c:3175 +#: ../src/ui/theme-parser.c:3222 +#, c-format +msgid "Style has already been specified for state %s resize %s focus %s" +msgstr "سبک، در حال حاضر، برای وضعیت %s تغییر اندازه %s تمرکز %s مشخص شده است" -#: ../src/metacity.schemas.in.h:99 -msgid "" -"The keybinding that switches to workspace 4. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلید برای تعویض به فضای کاری ۴. قالب آن به شکل «<Control>a» " -"یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف " -"بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول " -"می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید " -"مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-parser.c:3186 +#: ../src/ui/theme-parser.c:3197 +#: ../src/ui/theme-parser.c:3208 +#: ../src/ui/theme-parser.c:3233 +#: ../src/ui/theme-parser.c:3244 +#: ../src/ui/theme-parser.c:3255 +#, c-format +msgid "Style has already been specified for state %s focus %s" +msgstr "سبک، در حال حاضر، برای وضعیت %s تمرکز %s مشخص شده است" -#: ../src/metacity.schemas.in.h:100 -msgid "" -"The keybinding that switches to workspace 5. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلید برای تعویض به فضای کاری ۵. قالب آن به شکل «<Control>a» " -"یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف " -"بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول " -"می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید " -"مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-parser.c:3294 +msgid "Can't have a two draw_ops for a <piece> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)" +msgstr "عنصر <piece> نمی‌تواند دو draw_ops داشته باشد. (تم یک مشخصه‌ی draw_ops و یک عنصر <draw_ops> یا دو عنصر مشخص کرده است) " -#: ../src/metacity.schemas.in.h:101 -msgid "" -"The keybinding that switches to workspace 6. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلید برای تعویض به فضای کاری۶. قالب آن به شکل «<Control>a» یا " -"«<Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف " -"بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول " -"می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید " -"مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-parser.c:3332 +msgid "Can't have a two draw_ops for a <button> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)" +msgstr "عنصر <button> نمی‌تواند دو draw_ops داشته باشد. (تم یک مشخصه‌ی draw_ops و یک عنصر <draw_ops> یا دو عنصر مشخص کرده است) " -#: ../src/metacity.schemas.in.h:102 -msgid "" -"The keybinding that switches to workspace 7. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلید برای تعویض به فضای کاری ۷. قالب آن به شکل «<Control>a» " -"یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف " -"بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول " -"می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید " -"مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-parser.c:3370 +msgid "Can't have a two draw_ops for a <menu_icon> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)" +msgstr "عنصر <menu_icon> نمی‌تواند دو draw_ops داشته باشد. (تم یک مشخصه‌ی draw_ops و یک عنصر <draw_ops> یا دو عنصر مشخص کرده است) " -#: ../src/metacity.schemas.in.h:103 -msgid "" -"The keybinding that switches to workspace 8. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." +#: ../src/ui/theme-parser.c:3434 +#, c-format +msgid "Bad version specification '%s'" msgstr "" -"مقیدسازی کلید برای تعویض به فضای کاری ۸. قالب آن به شکل «<Control>a» " -"یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف " -"بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول " -"می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید " -"مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/metacity.schemas.in.h:104 -msgid "" -"The keybinding that switches to workspace 9. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." +#: ../src/ui/theme-parser.c:3507 +msgid "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-theme-2.xml" msgstr "" -"مقیدسازی کلید برای تعویض به فضای کاری ۹. قالب آن به شکل «<Control>a» " -"یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبتآسان‌گیر است و حروف " -"بزرگ یا کوچک و خلاصه کردن به شکل«<Ctl>» و «<Ctrl>» را قبول " -"می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی«disabled» قرار دهید، کلید مقیدی " -"برای این کنش وجود نخواهد داشت." -#: ../src/metacity.schemas.in.h:105 -msgid "" -"The keybinding used to activate the window menu. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." +#: ../src/ui/theme-parser.c:3530 +#, c-format +msgid "Theme requires version %s but latest supported theme version is %d.%d" msgstr "" -"مقیدسازی کلیدی که برای فعال‌سازی منوی پنجره به کار می‌رود؛ قالب آن به شکل «<" -"Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت " -"آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<" -"Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» " -"قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/metacity.schemas.in.h:106 -msgid "" -"The keybinding used to close a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلیدی که برای بستن پنجره به کار می‌رود؛ قالب آن به شکل «<" -"Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت " -"آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<" -"Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» " -"قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-parser.c:3562 +#, c-format +msgid "Outermost element in theme must be <metacity_theme> not <%s>" +msgstr "بیرونی‌ترین عنصر تم باید <metacity_theme> باشد نه <%s>" -#: ../src/metacity.schemas.in.h:107 -msgid "" -"The keybinding used to enter \"move mode\" and begin moving a window using " -"the keyboard. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" -"مقیدسازی کلیدی که برای وارد شدن به «حالت جابه‌جایی» و شروع جابه‌جایی پنجره با " -"استفاده از صفحه‌کلید به کار می‌رود؛ قالب آن به شکل «<Control>a» یا «<" -"Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا " -"کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول می‌کند. اگر " -"این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این " -"کنش وجود نخواهد داشت." - -#: ../src/metacity.schemas.in.h:108 -msgid "" -"The keybinding used to enter \"resize mode\" and begin resizing a window " -"using the keyboard. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" -"مقیدسازی کلیدی که برای وارد شدن به «حالت تغییر اندازه» و شروع تغییر اندازه‌ی " -"پنجره با استفاده از صفحه‌کلید به کار می‌رود؛ قالب آن به شکل «<Control>a» " -"یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف " -"بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول " -"می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید " -"مقیدی برای این کنش وجود نخواهد داشت." - -#: ../src/metacity.schemas.in.h:109 -msgid "" -"The keybinding used to hide all normal windows and set the focus to the " -"desktop background. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" -"مقیدسازی کلیدی که برای پنهان کردن تمام پنجره‌های عادی و قرار دادن تمرکز بر " -"پس‌زمینه‌ی رومیزی به کار می‌رود؛ قالب آن به شکل «<Control>a» یا «<" -"Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا " -"کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول می‌کند. اگر " -"این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این " -"کنش وجود نخواهد داشت." - -#: ../src/metacity.schemas.in.h:110 -msgid "" -"The keybinding used to maximize a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلیدی که برای حداکثر کردن پنجره به کار می‌رود؛ قالب آن به شکل «<" -"Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت " -"آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<" -"Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» " -"قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-parser.c:3582 +#, c-format +msgid "Element <%s> is not allowed inside a name/author/date/description element" +msgstr "عنصر <%s> درون عنصرهای name یا author یا date یا description جایز نیست" -#: ../src/metacity.schemas.in.h:111 -msgid "" -"The keybinding used to minimize a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلیدی که برای حداقل کردن پنجره به کار می‌رود؛ قالب آن به شکل «<" -"Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت " -"آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<" -"Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» " -"قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-parser.c:3587 +#, c-format +msgid "Element <%s> is not allowed inside a <constant> element" +msgstr "عنصر <%s> درون عنصر <constant> جایز نیست" -#: ../src/metacity.schemas.in.h:112 -msgid "" -"The keybinding used to move a window one workspace down. The format looks " -"like \"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -"fairly liberal and allows lower or upper case, and also abbreviations such " -"as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -"special string \"disabled\", then there will be no keybinding for this " -"action." -msgstr "" -"مقیدسازی کلیدی که برای جابه‌جایی پنجره به یک فضای کاری پایین‌تر به کار می‌رود؛ " -"قالب آن به شکل «<Control>a» یا «<Shift><Alt>F1» است. این " -"تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<" -"Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی " -"ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-parser.c:3599 +#, c-format +msgid "Element <%s> is not allowed inside a distance/border/aspect_ratio element" +msgstr "عنصر <%s> درون عنصرهای disanceیا border یا aspect_ratio جایز نیست" -#: ../src/metacity.schemas.in.h:113 -msgid "" -"The keybinding used to move a window one workspace to the left. The format " -"looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -"parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"مقیدسازی کلیدی که برای جابه‌جایی پنجره به فضای کاری چپش به کار می‌رود؛ قالب آن " -"به شکل «<Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر " -"به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» " -"و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی " -"«disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-parser.c:3621 +#, c-format +msgid "Element <%s> is not allowed inside a draw operation element" +msgstr "عنصر <%s> داخل عنصر عملیات رسم مجاز نیست" -#: ../src/metacity.schemas.in.h:114 -msgid "" -"The keybinding used to move a window one workspace to the right. The format " -"looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -"parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"مقیدسازی کلیدی که برای جابه‌جایی پنجره به فضای کاری راستش به کار می‌رود؛ قالب " -"آن به شکل «<Control>a» یا «<Shift><Alt>F1» است. این " -"تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<" -"Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی " -"ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-parser.c:3631 +#: ../src/ui/theme-parser.c:3661 +#: ../src/ui/theme-parser.c:3666 +#: ../src/ui/theme-parser.c:3671 +#, c-format +msgid "Element <%s> is not allowed inside a <%s> element" +msgstr "عنصر <%s> درون یک عنصر <%s> جایز نیست" -#: ../src/metacity.schemas.in.h:115 -msgid "" -"The keybinding used to move a window one workspace up. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلیدی که برای جابه‌جایی پنجره به یک فضای کاری بالاتر به کار می‌رود؛ " -"قالب آن به شکل «<Control>a» یا «<Shift><Alt>F1» است. این " -"تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<" -"Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی " -"ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-parser.c:3899 +msgid "No draw_ops provided for frame piece" +msgstr "draw_ops برای قطعه‌ی چارچوب منظور نشده است" -#: ../src/metacity.schemas.in.h:116 -msgid "" -"The keybinding used to move a window to workspace 1. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلیدی که برای جابه‌جایی پنجره به فضای کاری ۱ به کار می‌رود؛ قالب آن " -"به شکل «<Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر " -"به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» " -"و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی " -"«disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-parser.c:3914 +msgid "No draw_ops provided for button" +msgstr "draw_ops برای دکمه منظور نشده است" -#: ../src/metacity.schemas.in.h:117 -msgid "" -"The keybinding used to move a window to workspace 10. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلیدی که برای جابه‌جایی پنجره به فضای کاری ۱۰ به کار می‌رود؛ قالب آن " -"به شکل «<Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر " -"به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» " -"و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی " -"«disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-parser.c:3968 +#, c-format +msgid "No text is allowed inside element <%s>" +msgstr "هیچ متنی درون عنصر <%s> جایز نیست" -#: ../src/metacity.schemas.in.h:118 -msgid "" -"The keybinding used to move a window to workspace 11. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلیدی که برای جابه‌جایی پنجره به فضای کاری ۱۱ به کار می‌رود؛ قالب آن " -"به شکل «<Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر " -"به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» " -"و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی " -"«disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-parser.c:4026 +#: ../src/ui/theme-parser.c:4038 +#: ../src/ui/theme-parser.c:4050 +#: ../src/ui/theme-parser.c:4062 +#: ../src/ui/theme-parser.c:4074 +#, fuzzy, c-format +#| msgid "<name> specified twice for this theme" +msgid "<%s> specified twice for this theme" +msgstr "<name> دو بار برای این تم مشخص شده است" -#: ../src/metacity.schemas.in.h:119 -msgid "" -"The keybinding used to move a window to workspace 12. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلیدی که برای جابه‌جایی پنجره به فضای کاری ۱۲ به کار می‌رود؛ قالب آن " -"به شکل «<Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر " -"به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» " -"و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی " -"«disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-parser.c:4348 +#, fuzzy, c-format +#| msgid "Failed to fdopen() log file %s: %s\n" +msgid "Failed to find a valid file for theme %s\n" +msgstr "شکست در انجام fdopen() پرونده‌ی ثبتی %s: %s\n" -#: ../src/metacity.schemas.in.h:120 -msgid "" -"The keybinding used to move a window to workspace 2. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلیدی که برای جابه‌جایی پنجره به فضای کاری ۲ به کار می‌رود؛ قالب آن " -"به شکل «<Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر " -"به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» " -"و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی " -"«disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-viewer.c:99 +#| msgid "/_Windows" +msgid "_Windows" +msgstr "_پنجره‌ها" -#: ../src/metacity.schemas.in.h:121 -msgid "" -"The keybinding used to move a window to workspace 3. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلیدی که برای جابه‌جایی پنجره به فضای کاری ۳ به کار می‌رود؛ قالب آن " -"به شکل «<Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر " -"به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» " -"و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی " -"«disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-viewer.c:100 +#| msgid "Dialog Box" +msgid "_Dialog" +msgstr "_محاوره" -#: ../src/metacity.schemas.in.h:122 -msgid "" -"The keybinding used to move a window to workspace 4. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلیدی که برای جابه‌جایی پنجره به فضای کاری ۴ به کار می‌رود؛ قالب آن " -"به شکل «<Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر " -"به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» " -"و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی " -"«disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-viewer.c:101 +#| msgid "Modal Dialog Box" +msgid "_Modal dialog" +msgstr "_محاوره‌ی معین" -#: ../src/metacity.schemas.in.h:123 -msgid "" -"The keybinding used to move a window to workspace 5. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلیدی که برای جابه‌جایی پنجره به فضای کاری ۵ به کار می‌رود؛ قالب آن " -"به شکل «<Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر " -"به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» " -"و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی " -"«disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-viewer.c:102 +#| msgid "/Windows/_Utility" +msgid "_Utility" +msgstr "_لوازم" -#: ../src/metacity.schemas.in.h:124 -msgid "" -"The keybinding used to move a window to workspace 6. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلیدی که برای جابه‌جایی پنجره به فضای کاری ۶ به کار می‌رود؛ قالب آن " -"به شکل «<Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر " -"به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» " -"و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی " -"«disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-viewer.c:103 +msgid "_Splashscreen" +msgstr "_صفحه‌ورود" -#: ../src/metacity.schemas.in.h:125 -msgid "" -"The keybinding used to move a window to workspace 7. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلیدی که برای جابه‌جایی پنجره به فضای کاری ۷ به کار می‌رود؛ قالب آن " -"به شکل «<Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر " -"به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» " -"و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی " -"«disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-viewer.c:104 +msgid "_Top dock" +msgstr "قاب _بالا" -#: ../src/metacity.schemas.in.h:126 -msgid "" -"The keybinding used to move a window to workspace 8. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلیدی که برای جابه‌جایی پنجره به فضای کاری ۸ به کار می‌رود؛ قالب آن " -"به شکل «<Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر " -"به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» " -"و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی " -"«disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-viewer.c:105 +msgid "_Bottom dock" +msgstr "قاب _پایین" -#: ../src/metacity.schemas.in.h:127 -msgid "" -"The keybinding used to move a window to workspace 9. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلیدی که برای جابه‌جایی پنجره به فضای کاری ۹ به کار می‌رود؛ قالب آن " -"به شکل «<Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر " -"به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» " -"و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی " -"«disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-viewer.c:106 +msgid "_Left dock" +msgstr "قاب _چپ" -#: ../src/metacity.schemas.in.h:128 -msgid "" -"The keybinding used to move focus backwards between panels and the desktop, " -"using a popup window. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" -"مقیدسازی کلیدی که برای جابه‌جایی تمرکز به عقب بین تابلوها و رومیزی، با " -"استفاده از یک پنجره‌ی واشو به کار می‌رود؛ قالب آن به شکل «<Control>a» یا " -"«<Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف " -"بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول " -"می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید " -"مقیدی برای این کنش وجود نخواهد داشت." - -#: ../src/metacity.schemas.in.h:129 -msgid "" -"The keybinding used to move focus backwards between panels and the desktop, " -"without a popup window. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" -"مقیدسازی کلیدی که برای جابه‌جایی تمرکز به عقب بین تابلوها و رومیزی، بدون " -"استفاده از پنجره‌ی واشو به کار می‌رود؛ قالب آن به شکل «<Control>a» یا " -"«<Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف " -"بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول " -"می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید " -"مقیدی برای این کنش وجود نخواهد داشت." - -#: ../src/metacity.schemas.in.h:130 -msgid "" -"The keybinding used to move focus backwards between windows without a popup " -"window. Holding \"shift\" together with this binding makes the direction go " -"forward again. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" -"مقیدسازی کلیدی که برای جابه‌جایی تمرکز به عقب بین پنجره‌ها بدون استفاده از " -"پنجره‌ی واشو به کار می‌رود؛ نگه داشتن «تبدیل» همراه با این کلید مقید سبب رو به " -"جلو شدن جهت می‌شود. قالب آن به شکل «<Control>a» یا «<Shift><" -"Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه " -"کردن به شکل «<Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه را " -"برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود " -"نخواهد داشت." - -#: ../src/metacity.schemas.in.h:131 -msgid "" -"The keybinding used to move focus backwards between windows, using a popup " -"window. Holding \"shift\" together with this binding makes the direction go " -"forward again. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" -"مقیدسازی کلیدی که برای جابه‌جایی تمرکز به عقب بین پنجره‌ها، با استفاده از یک " -"پنجره‌ی واشو به کار می‌رود؛ نگه داشتن «تبدیل» همراه با این کلید مقید سبب رو به " -"جلو شدن جهت می‌شود. قالب آن به شکل «<Control>a» یا «<Shift><" -"Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه " -"کردن به شکل «<Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه را " -"برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود " -"نخواهد داشت." - -#: ../src/metacity.schemas.in.h:132 -msgid "" -"The keybinding used to move focus between panels and the desktop, using a " -"popup window. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" -"مقیدسازی کلیدی که برای جابه‌جایی تمرکز بین تابلوها و رومیزی، با استفاده از یک " -"پنجره‌ی واشو به کار می‌رود؛ قالب آن به شکل «<Control>a» یا «<Shift>" -"<Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و " -"خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این " -"گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش " -"وجود نخواهد داشت." - -#: ../src/metacity.schemas.in.h:133 -msgid "" -"The keybinding used to move focus between panels and the desktop, without a " -"popup window. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" -"مقیدسازی کلیدی که برای جابه‌جایی تمرکز بین تابلوها و رومیزی، بدون استفاده از " -"پنجره‌ی واشو به کار می‌رود؛ قالب آن به شکل «<Control>a» یا «<Shift>" -"<Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و " -"خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این " -"گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش " -"وجود نخواهد داشت." - -#: ../src/metacity.schemas.in.h:134 -msgid "" -"The keybinding used to move focus between windows without a popup window. " -"(Traditionally <Alt>Escape) Holding the \"shift\" key while using this " -"binding reverses the direction of movement. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلیدی که برای جابه‌جایی تمرکز بین پنجره‌ها بدون استفاده از پنجره‌ی " -"واشو به کار می‌رود؛ قالب آن به شکل «<Control>a» یا «<Shift><" -"Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه " -"کردن به شکل «<Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه را " -"برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود " -"نخواهد داشت." - -#: ../src/metacity.schemas.in.h:135 -msgid "" -"The keybinding used to move focus between windows, using a popup window. " -"(Traditionally <Alt>Tab) Holding the \"shift\" key while using this " -"binding reverses the direction of movement. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلیدی که برای جابه‌جایی تمرکز بین پنجره‌ها با استفاده از پنجره‌ی واشو " -"به کار می‌رود؛ (<Alt>Tab طبق سنت) نگهداشتن کلید «تبدیل» هنگام استفاده " -"از این کلید مقید جهت حرکت را برعکس می‌کند.قالب آن به شکل «<Control>a» " -"یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف " -"بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول " -"می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید " -"مقیدی برای این کنش وجود نخواهد داشت." - -#: ../src/metacity.schemas.in.h:136 -msgid "" -"The keybinding used to toggle always on top. A window that is always on top " -"will always be visible over other overlapping windows. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلید ضامن همیشه بالا. پنجره‌ای که همیشه بالا است، روی تمام پنجره‌هایی " -"که هم‌پوشانی دارند دیده خواهد شد؛ قالب آن به شکل «<Control>a» یا «<" -"Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا " -"کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول می‌کند. اگر " -"این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این " -"کنش وجود نخواهد داشت." - -#: ../src/metacity.schemas.in.h:137 -msgid "" -"The keybinding used to toggle fullscreen mode. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلید ضامن حالت تمام صفحه. قالب آن به شکل «<Control>a» یا «<" -"Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا " -"کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول می‌کند. اگر " -"این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این " -"کنش وجود نخواهد داشت." +#: ../src/ui/theme-viewer.c:107 +msgid "_Right dock" +msgstr "قاب _راست" -#: ../src/metacity.schemas.in.h:138 -msgid "" -"The keybinding used to toggle maximization. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلید ضامن حداکثر کردن. قالب آن به شکل «<Control>a» یا «<" -"Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا " -"کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول می‌کند. اگر " -"این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این " -"کنش وجود نخواهد داشت." +#: ../src/ui/theme-viewer.c:108 +msgid "_All docks" +msgstr "تمام _قاب‌ها" -#: ../src/metacity.schemas.in.h:139 -msgid "" -"The keybinding used to toggle shaded/unshaded state. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلید ضامن وضعیت سایه‌دار با بدون سایه. قالب آن به شکل «<" -"Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت " -"آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<" -"Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» " -"قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-viewer.c:109 +#| msgid "/Windows/Des_ktop" +msgid "Des_ktop" +msgstr "_رومیزی" -#: ../src/metacity.schemas.in.h:140 -msgid "" -"The keybinding used to toggle whether the window is on all workspaces or " -"just one. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" -"مقیدسازی کلید ضامن وجود پنجره در تمام فضاهای کاری یا فقط یک فضای کاری. قالب " -"آن به شکل «<Control>a» یا «<Shift><Alt>F1» است. این " -"تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<" -"Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی " -"ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-viewer.c:115 +msgid "Open another one of these windows" +msgstr "یکی دیگر از این پنجره‌ها بازشود" -#: ../src/metacity.schemas.in.h:141 -msgid "" -"The keybinding used to unmaximize a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلیدی که برای ناحداکثر کردن پنجره به کار می‌رود. قالب آن به شکل «<" -"Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت " -"آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<" -"Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» " -"قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-viewer.c:117 +msgid "This is a demo button with an 'open' icon" +msgstr "این یک دکمه‌ی نمایشی با شمایل «بازکردن» است" -#: ../src/metacity.schemas.in.h:142 -msgid "" -"The keybinding which display's the panel's \"Run Application\" dialog box. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"مقیدسازی کلیدی که جعبه‌ی محاوره‌ی «اجرای برنامه»ی تابلو را نمایش می‌دهد؛ قالب " -"آن به شکل «<Control>a» یا «<Shift><Alt>F1» است. این " -"تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<" -"Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی " -"ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-viewer.c:119 +msgid "This is a demo button with a 'quit' icon" +msgstr "این یک دکمه‌ی نمایشی با شمایل «ترک» است" -#: ../src/metacity.schemas.in.h:143 -msgid "" -"The keybinding which invokes a terminal. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلیدی که یک پایانه احضار می‌کند؛ قالب آن به شکل «<Control>a» " -"یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف " -"بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول " -"می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید " -"مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-viewer.c:248 +msgid "This is a sample message in a sample dialog" +msgstr "این یک پیغام نمونه در یک محاوره‌ی نمونه است" -#: ../src/metacity.schemas.in.h:144 -msgid "" -"The keybinding which invokes the panel's screenshot utility to take a " -"screenshot of a window. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" -"مقیدسازی کلیدی که برنامه‌ی عکس از صفحه را احضار می‌کند تا یک عکس از صفحه‌ی " -"پنجره بگیرد؛ قالب آن به شکل «<Control>a» یا «<Shift><Alt>" -"F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن " -"به شکل «<Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر " -"با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد " -"داشت." - -#: ../src/metacity.schemas.in.h:145 -msgid "" -"The keybinding which invokes the panel's screenshot utility. The format " -"looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -"parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"مقیدسازی کلیدی که برنامه‌ی عکس از صفحه را احضار می‌کند؛ قالب آن به شکل «<" -"Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت " -"آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<" -"Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» " -"قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-viewer.c:328 +#, c-format +msgid "Fake menu item %d\n" +msgstr "مورد %Id منوی جعلی\n" -#: ../src/metacity.schemas.in.h:146 -msgid "" -"The keybinding which shows the panel's main menu. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"مقیدسازی کلیدی که منوی اصلی تابلو را نشان می‌دهد؛ قالب آن به شکل «<" -"Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت " -"آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<" -"Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» " -"قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-viewer.c:363 +msgid "Border-only window" +msgstr "پنجره‌ی فقط کناره‌دار" -#: ../src/metacity.schemas.in.h:147 -msgid "The name of a workspace." -msgstr "نام فضای کاری." +#: ../src/ui/theme-viewer.c:365 +msgid "Bar" +msgstr "نوار" -#: ../src/metacity.schemas.in.h:148 -msgid "The screenshot command" -msgstr "فرمان عکس از صفحه" +#: ../src/ui/theme-viewer.c:382 +msgid "Normal Application Window" +msgstr "پنجره‌ی عادی برنامه" -#: ../src/metacity.schemas.in.h:149 -msgid "" -"The theme determines the appearance of window borders, titlebar, and so " -"forth." -msgstr "" -"تم، قیافه‌ی کناره‌ی پنجره‌ها، نوار عنوان و چیزهایی از این دست را تعیین می‌کند." +#: ../src/ui/theme-viewer.c:386 +msgid "Dialog Box" +msgstr "جعبه‌ی محاوره" -#: ../src/metacity.schemas.in.h:150 -msgid "" -"The time delay before raising a window if auto_raise is set to true. The " -"delay is given in thousandths of a second." -msgstr "" -"تأخیر زمانی قبل از پیش کشیدن پنجره در صورتی که auto_raise روی درست تنظیم شده " -"باشد. تأخیر به هزارم ثانیه داده شده است." +#: ../src/ui/theme-viewer.c:390 +msgid "Modal Dialog Box" +msgstr "جعبه‌ی محاوره‌ی چند حالتی" -#: ../src/metacity.schemas.in.h:151 -msgid "" -"The window focus mode indicates how windows are activated. It has three " -"possible values; \"click\" means windows must be clicked in order to focus " -"them, \"sloppy\" means windows are focused when the mouse enters the window, " -"and \"mouse\" means windows are focused when the mouse enters the window and " -"unfocused when the mouse leaves the window." -msgstr "" -"حالت تمرکز پنجره نحوه‌ی فعال‌سازی پنجره‌ها را نشان می‌دهد. سه مقدار می‌تواند " -"بگیرد؛ «click» یعنی برای تمرکز روی پنجره‌ها رویشان کلیک شود، «sloppy» یعنی " -"وقتی موشی وارد پنجره‌ای شد تمرکز روی آن پنجره قرار بگیرد و «mouse» یعنی وقتی " -"موشی وارد پنجره‌ای شد تمرکز روی آن قرار بگیرد و وقتی خارج شد تمرکز از روی آن " -"برداشته شود." +#: ../src/ui/theme-viewer.c:394 +msgid "Utility Palette" +msgstr "تخته‌رنگ برنامه‌" -#: ../src/metacity.schemas.in.h:152 -msgid "The window screenshot command" -msgstr "فرمان عکس از صفحه‌ی پنجره" +#: ../src/ui/theme-viewer.c:398 +msgid "Torn-off Menu" +msgstr "منوی کنده شدنی" -#: ../src/metacity.schemas.in.h:153 -msgid "" -"This keybinding changes whether a window is above or below other windows. If " -"the window is covered by another window, it raises the window above other " -"windows. If the window is already fully visible, it lowers the window below " -"other windows. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" -"این کلید مقید زیر یا رو بودن یک پنجره را نسبت به بقیه پنجره‌ها تغییر می‌دهد. " -"اگر پنجره با پنجره‌ی دیگری پوشیده شده باشد، آن را پیش می‌آورد. اگر پنجره به " -"طور کامل دیده شود، آن را زیر پنجره‌های دیگر قرار می‌دهد. قالب آن به شکل «<" -"Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت " -"آسان‌گیر است و حروف بزرگ یا کوچک یا خلاصه کردن به شکل «<Ctl>» و «<" -"Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» " -"قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." - -#: ../src/metacity.schemas.in.h:154 -msgid "" -"This keybinding lowers a window below other windows. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"این کلید مقید یک پنجره را زیر پنجره‌های دیگر قرار می‌دهد. قالب آن به شکل «<" -"Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت " -"آسان‌گیر است و حروف بزرگ یا کوچک یا خلاصه کردن به شکل «<Ctl>» و «<" -"Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» " -"قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-viewer.c:402 +msgid "Border" +msgstr "کناره" -#: ../src/metacity.schemas.in.h:155 -msgid "" -"This keybinding raises the window above other windows. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"این کلید مقید یک پنجره را روی پنجره‌های دیگر پیش می‌آورد. قالب آن به شکل «<" -"Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت " -"آسان‌گیر است و حروف بزرگ یا کوچک یا خلاصه کردن به شکل «<Ctl>» و «<" -"Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» " -"قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-viewer.c:406 +#| msgid "Modal Dialog Box" +msgid "Attached Modal Dialog" +msgstr "محاوره‌ی معین متصل شده" -#: ../src/metacity.schemas.in.h:156 -msgid "" -"This keybinding resizes a window to fill available horizontal space. The " -"format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"این کلید مقید اندازه‌ی یک پنجره را تغییر می‌دهد تا فضای افقی موجود را پر کند. " -"قالب آن به شکل «<Control>a» یا «<Shift><Alt>F1» است. این " -"تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک یا خلاصه کردن به شکل «<" -"Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی " -"ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-viewer.c:739 +#, c-format +msgid "Button layout test %d" +msgstr "آزمایش %Id چیدمان دکمه‌ها" -#: ../src/metacity.schemas.in.h:157 -msgid "" -"This keybinding resizes a window to fill available vertical space. The " -"format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"این کلید مقید اندازه‌ی یک پنجره را تغییر می‌دهد تا فضای عمودی موجود را پر کند. " -"قالب آن به شکل «<Control>a» یا «<Shift><Alt>F1» است. این " -"تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک یا خلاصه کردن به شکل «<" -"Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی " -"ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." +#: ../src/ui/theme-viewer.c:768 +#, c-format +msgid "%g milliseconds to draw one window frame" +msgstr "%Ig میلی ثانیه برای کشیدن چارچوب یک پنجره" -#: ../src/metacity.schemas.in.h:158 -msgid "" -"This option determines the effects of double-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, 'toggle_maximize' which will maximize/unmaximize the window, " -"'minimize' which will minimize the window, and 'none' which will not do " -"anything." -msgstr "" -"این گزینه تأثیر دوبار کلیک روی نوار عنوان را تعیین می‌کند. گزینه‌های معتبر " -"فعلی عبارتند از «toggle_shade» که پنجره را سایه خورده یا بدون سایه می‌کند، " -"«toggle_maximize» که پنجره را حداکثر یا ناحداکثر می‌کند، «minimize»که پنجره " -"را حداقل می‌کند، و «none» که کاری انجام نمی‌دهد." +#: ../src/ui/theme-viewer.c:813 +#, c-format +msgid "Usage: metacity-theme-viewer [THEMENAME]\n" +msgstr "کاربرد: metacity-theme-viewer [THEMENAME]\n" -#: ../src/metacity.schemas.in.h:159 -msgid "Toggle always on top state" -msgstr "ضامن همیشه در وضعیت بالایی" +#: ../src/ui/theme-viewer.c:820 +#, c-format +msgid "Error loading theme: %s\n" +msgstr "خطا در بارگذاری تم : %s\n" -#: ../src/metacity.schemas.in.h:160 -msgid "Toggle fullscreen mode" -msgstr "ضامن حالت تمام صفحه" +#: ../src/ui/theme-viewer.c:826 +#, c-format +msgid "Loaded theme \"%s\" in %g seconds\n" +msgstr "تم‌ «%s» در %Ig ثانیه بارشد\n" -#: ../src/metacity.schemas.in.h:161 -msgid "Toggle maximization state" -msgstr "ضامن همیشه در وضیعت حداکثر" +#: ../src/ui/theme-viewer.c:870 +msgid "Normal Title Font" +msgstr "قلم عنوان عادی" -#: ../src/metacity.schemas.in.h:162 -msgid "Toggle shaded state" -msgstr "ضامن وضعیت سایه خورده" +#: ../src/ui/theme-viewer.c:876 +msgid "Small Title Font" +msgstr "قلم عنوان ریز" -#: ../src/metacity.schemas.in.h:163 -msgid "Toggle window on all workspaces" -msgstr "ضامن پنجره در تمام فضاهای کاری" +#: ../src/ui/theme-viewer.c:882 +msgid "Large Title Font" +msgstr "قلم عنوان درشت" -#: ../src/metacity.schemas.in.h:164 -msgid "" -"Turns on a visual indication when an application or the system issues a " -"'bell' or 'beep'; useful for the hard-of-hearing and for use in noisy " -"environments, or when 'audible bell' is off." -msgstr "" -"هنگامی که یک برنامه یا سیستم «زنگ»‌ یا «بوق» می‌زند، یک شاخص تصویری را روشن " -"می‌کند: مفید برای گوش‌های سنگین و برای استفاده در محیط‌های پر سر و صدا یا زمانی " -"که «زنگ شنیداری» خاموش است." +#: ../src/ui/theme-viewer.c:887 +msgid "Button Layouts" +msgstr "چیدمان‌های دکمه‌ها" -#: ../src/metacity.schemas.in.h:165 -msgid "Unmaximize window" -msgstr "ناحداکثر کردن پنجره" +#: ../src/ui/theme-viewer.c:892 +msgid "Benchmark" +msgstr "آزمایش محک" -#: ../src/metacity.schemas.in.h:166 -msgid "Use standard system font in window titles" -msgstr "استفاده از قلم استاندارد سیستم در عنوان پنجره‌ها" +#: ../src/ui/theme-viewer.c:944 +msgid "Window Title Goes Here" +msgstr "عنوان پنجره اینجا قرار می‌گیرد" -#: ../src/metacity.schemas.in.h:167 -msgid "Visual Bell Type" -msgstr "نوع زنگ دیداری" +#: ../src/ui/theme-viewer.c:1047 +#, c-format +msgid "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g seconds wall clock time including X server resources (%g milliseconds per frame)\n" +msgstr "%Id چارچوب در %Ig ثانیه‌ی سمت مخدوم (%Ig میلی ثانیه برای هر چارچوب) و %Ig ثانیه‌ی ساعت دیواری شامل منابع خادم X (%Ig میلی ثانیه برای هر چارچوب)\n" -#: ../src/metacity.schemas.in.h:168 -msgid "Whether raising should be a side-effect of other user interactions" -msgstr "" +#: ../src/ui/theme-viewer.c:1266 +msgid "position expression test returned TRUE but set error" +msgstr "آزمایش عبارت وضعیت، درست بازگرداند ولی خطا تنظیم کرد" -#: ../src/metacity.schemas.in.h:169 -msgid "Window focus mode" -msgstr "حالت تمرکز پنجره" +#: ../src/ui/theme-viewer.c:1268 +msgid "position expression test returned FALSE but didn't set error" +msgstr "آزمایش عبارت وضعیت، نادرست بازگرداند ولی خطایی تنظیم نکرد" -#: ../src/metacity.schemas.in.h:170 -msgid "Window title font" -msgstr "قلم عنوان پنجره" +#: ../src/ui/theme-viewer.c:1272 +msgid "Error was expected but none given" +msgstr "انتظار خطا می‌رفت ولی خطایی مشاهده نشد" -#: ../src/prefs.c:560 ../src/prefs.c:576 ../src/prefs.c:592 ../src/prefs.c:608 -#: ../src/prefs.c:624 ../src/prefs.c:640 ../src/prefs.c:660 ../src/prefs.c:676 -#: ../src/prefs.c:692 ../src/prefs.c:708 ../src/prefs.c:724 ../src/prefs.c:740 -#: ../src/prefs.c:756 ../src/prefs.c:772 ../src/prefs.c:789 ../src/prefs.c:805 -#: ../src/prefs.c:821 ../src/prefs.c:837 ../src/prefs.c:853 ../src/prefs.c:868 -#: ../src/prefs.c:883 ../src/prefs.c:898 ../src/prefs.c:914 ../src/prefs.c:930 -#: ../src/prefs.c:946 +#: ../src/ui/theme-viewer.c:1274 #, c-format -msgid "GConf key \"%s\" is set to an invalid type\n" -msgstr "کلید «%s» GConf از نوع نامعتبری تنظیم شده است\n" +msgid "Error %d was expected but %d given" +msgstr "انتظار خطای %Id می‌رفت ولی خطای %Id مشاهده شد" -#: ../src/prefs.c:991 +#: ../src/ui/theme-viewer.c:1280 #, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"«%s» پیدا شده در پایگاه‌داده‌ی پیکربندی مقدار معتبری برای تغییردهنده‌ی دکمه‌ی " -"موشی نیست\n" +msgid "Error not expected but one was returned: %s" +msgstr "انتظار خطا نمی‌رفت ولی خطایی برگردانده شد: %s" -#: ../src/prefs.c:1015 ../src/prefs.c:1505 +#: ../src/ui/theme-viewer.c:1284 #, c-format -msgid "GConf key '%s' is set to an invalid value\n" -msgstr "کلید «%s» GCon به مقدار نامعتبری تنظیم شده است\n" +msgid "x value was %d, %d was expected" +msgstr "مقدار x %Id بود، %Id انتظار می‌رفت" -#: ../src/prefs.c:1138 +#: ../src/ui/theme-viewer.c:1287 #, c-format -msgid "" -"%d stored in GConf key %s is not a reasonable cursor_size; must be in the " -"range 1..128\n" -msgstr "" -"%Id ذخیره شده در کلید %s GConf عدد معقولی برای اندازه‌ی مکان‌نما نیست؛ باید در " -"محدوده‌ی ۱ تا ۱۲۸ باشد\n" +msgid "y value was %d, %d was expected" +msgstr "مقدار y %Id بود، %Id انتظار می‌رفت" -#: ../src/prefs.c:1218 +#: ../src/ui/theme-viewer.c:1352 #, c-format -msgid "Could not parse font description \"%s\" from GConf key %s\n" -msgstr "تجزیه‌ی شرح قلم «%s» از کلید GConf %s ممکن نیست\n" +msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" +msgstr "%Id عبارت مختصاتی در %Ig ثانیه تجزیه شد (متوسط %Ig ثانیه)\n" -#: ../src/prefs.c:1403 -#, c-format -msgid "" -"%d stored in GConf key %s is not a reasonable number of workspaces, current " -"maximum is %d\n" -msgstr "" -"%Id ذخیره شده در کلید %s GConf عدد معقولی برای تعداد فضاهای کاری نیست، " -"حداکثر فعلی %Id است\n" +#: ../src/50-mutter-windows.xml.in.h:2 +#, fuzzy +msgid "Close window" +msgstr "بستن پنجره" -#: ../src/prefs.c:1463 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" +#: ../src/50-mutter-windows.xml.in.h:3 +#, fuzzy +msgid "Lower window below other windows" +msgstr "پایین بردن پنجره زیر پنجره‌های دیگر" + +#: ../src/50-mutter-windows.xml.in.h:4 +#, fuzzy +msgid "Maximize window" msgstr "" -"دور زدن برنامه‌های از کار افتاده، از کار انداخته شده است. بعضی از برنامه‌ها " -"ممکن است رفتار مناسبی نداشته باشند.\n" +"#-#-#-#-# fa.po (metacity HEAD) #-#-#-#-#\n" +"حداکثر کردن پنجره\n" +"#-#-#-#-# fa.po (metacity HEAD) #-#-#-#-#\n" +"بیشینه کردن پنجره" -#: ../src/prefs.c:1532 -#, c-format -msgid "%d stored in GConf key %s is out of range 0 to %d\n" -msgstr "%Id ذخیره شده در کلید GConf %s خارج از محدوده‌ی ۰ تا %Id است\n" +#: ../src/50-mutter-windows.xml.in.h:5 +#, fuzzy +msgid "Maximize window horizontally" +msgstr "حداکثر کردن افقی پنجره" -#: ../src/prefs.c:1669 -#, c-format -msgid "Error setting number of workspaces to %d: %s\n" -msgstr "خطای تنظیم تعداد فضاهای کاری به %Id: %s\n" +#: ../src/50-mutter-windows.xml.in.h:6 +#, fuzzy +msgid "Maximize window vertically" +msgstr "حداکثر کردن عمودی پنجره" -#: ../src/prefs.c:2005 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" +#: ../src/50-mutter-windows.xml.in.h:7 +#, fuzzy +msgid "Minimize window" msgstr "" -"«%s» که در پایگاه داده‌ی پیکربندی پیدا شده مقدار معتبری برای کلید مقید «%s» " -"نیست\n" +"#-#-#-#-# fa.po (metacity HEAD) #-#-#-#-#\n" +"حداقل کردن پنجره\n" +"#-#-#-#-# fa.po (metacity HEAD) #-#-#-#-#\n" +"کمینه کردن پنجره" -#: ../src/prefs.c:2360 -#, c-format -msgid "Error setting name for workspace %d to \"%s\": %s\n" -msgstr "خطای تنظیم نام فضای کاری %Id به \"%s\": %s\n" +#: ../src/50-mutter-windows.xml.in.h:8 +#, fuzzy +msgid "Move window" +msgstr "جابه‌جایی پنجره" -#: ../src/resizepopup.c:126 -#, c-format -msgid "%d x %d" -msgstr "%Id × %Id" +#: ../src/50-mutter-navigation.xml.in.h:6 +#, fuzzy +msgid "Move window one workspace down" +msgstr "" +"#-#-#-#-# fa.po (metacity HEAD) #-#-#-#-#\n" +"جابه‌جایی پنجره به فضای کاری پایینی\n" +"#-#-#-#-# fa.po (metacity HEAD) #-#-#-#-#\n" +"جابه‌جایی پنجره به فضای‌کاری پایینی" -#: ../src/screen.c:403 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "صفحه‌ی %Id روی نمایشگر «%s» نامعتبر است\n" +#: ../src/50-mutter-navigation.xml.in.h:7 +#, fuzzy +msgid "Move window one workspace to the left" +msgstr "" +"#-#-#-#-# fa.po (metacity HEAD) #-#-#-#-#\n" +"جابه‌جایی پنجره به فضای کاری چپ \n" +"#-#-#-#-# fa.po (metacity HEAD) #-#-#-#-#\n" +"جابه‌جایی پنجره به فضای‌کاری چپ " -#: ../src/screen.c:419 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" +#: ../src/50-mutter-navigation.xml.in.h:8 +#, fuzzy +msgid "Move window one workspace to the right" msgstr "" -"صفحه‌ی %Id روی نمایشگر «%s» مدیر پنجره‌ها دارد. برای جایگزین کردنمدیر پنجره‌های " -"فعلی از گزینه‌ی --replace استفاده کنید.\n" +"#-#-#-#-# fa.po (metacity HEAD) #-#-#-#-#\n" +"جابه‌جایی پنجره به فضای کاری راست\n" +"#-#-#-#-# fa.po (metacity HEAD) #-#-#-#-#\n" +"جابه‌جایی پنجره به فضای‌کاری راست" -#: ../src/screen.c:443 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "انتخاب مدیر پنجره‌ها روی صفحه‌ی %Id نمایش «%s»\n" +#: ../src/50-mutter-navigation.xml.in.h:9 +#, fuzzy +msgid "Move window one workspace up" +msgstr "" +"#-#-#-#-# fa.po (metacity HEAD) #-#-#-#-#\n" +"جابه‌جایی پنجره به فضای کاری بالایی\n" +"#-#-#-#-# fa.po (metacity HEAD) #-#-#-#-#\n" +"جابه‌جایی پنجره به فضای‌کاری بالایی" -#: ../src/screen.c:501 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "صفحه‌ی %Id روی نمایشگر «%s» مدیر پنجره دارد\n" +#: ../src/50-mutter-navigation.xml.in.h:10 +#, fuzzy +msgid "Move window to workspace 1" +msgstr "" +"#-#-#-#-# fa.po (metacity HEAD) #-#-#-#-#\n" +"جابه‌جایی پنجره به فضای کاری ۱\n" +"#-#-#-#-# fa.po (metacity HEAD) #-#-#-#-#\n" +"جابه‌جایی پنجره به فضای‌کاری ۱" -#: ../src/screen.c:702 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "آزاد کردن صفحه‌ی %Id روی نمایشگر «%s» ممکن نیست\n" +#: ../src/50-mutter-navigation.xml.in.h:11 +#, fuzzy +msgid "Move window to workspace 2" +msgstr "" +"#-#-#-#-# fa.po (metacity HEAD) #-#-#-#-#\n" +"جابه‌جایی پنجره به فضای کاری ۲\n" +"#-#-#-#-# fa.po (metacity HEAD) #-#-#-#-#\n" +"جابه‌جایی پنجره به فضای‌کاری ۲" -#: ../src/session.c:835 ../src/session.c:842 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "ایجاد شاخه‌ی «%s» ممکن نیست: %s\n" +#: ../src/50-mutter-navigation.xml.in.h:12 +#, fuzzy +msgid "Move window to workspace 3" +msgstr "" +"#-#-#-#-# fa.po (metacity HEAD) #-#-#-#-#\n" +"نقل‌مکان پنجره به فضای کاری ۳\n" +"#-#-#-#-# fa.po (metacity HEAD) #-#-#-#-#\n" +"جابه‌جایی پنجره به فضای‌کاری ۳" -#: ../src/session.c:852 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "باز کردن پرونده‌ی نشست «%s» برای نوشتن ممکن نیست: %s\n" +#: ../src/50-mutter-navigation.xml.in.h:13 +#, fuzzy +msgid "Move window to workspace 4" +msgstr "" +"#-#-#-#-# fa.po (metacity HEAD) #-#-#-#-#\n" +"جابه‌جایی پنجره به فضای کاری ۴\n" +"#-#-#-#-# fa.po (metacity HEAD) #-#-#-#-#\n" +"جابه‌جایی پنجره به فضای‌کاری ۴" -#: ../src/session.c:1004 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "خطا در نوشتن پرونده‌ی نشست «%s»: %s\n" +#: ../src/50-mutter-windows.xml.in.h:9 +#, fuzzy +msgid "Raise window above other windows" +msgstr "پیش آوردن پنجره روی همه‌ی پنجره‌ها" -#: ../src/session.c:1009 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "خطا در بستن پرونده‌ی نشست «%s»: %s\n" +#: ../src/50-mutter-windows.xml.in.h:11 +#, fuzzy +msgid "Resize window" +msgstr "تغییر اندازه‌ی پنجره" -#: ../src/session.c:1084 -#, c-format -msgid "Failed to read saved session file %s: %s\n" -msgstr "شکست در خواندن پرونده‌ی نشست ذخیره شده %s: %s\n" +#: ../src/50-mutter-navigation.xml.in.h:18 +#, fuzzy +msgid "Switch to workspace 1" +msgstr "" +"#-#-#-#-# fa.po (metacity HEAD) #-#-#-#-#\n" +"تعویض به فضای کاری ۱\n" +"#-#-#-#-# fa.po (metacity HEAD) #-#-#-#-#\n" +"رفتن به فضای‌کاری ۱" -#: ../src/session.c:1119 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "شکست در تجزیه‌ی پرونده‌ی نشست ذخیره شده: %s\n" +#: ../src/50-mutter-navigation.xml.in.h:19 +#, fuzzy +msgid "Switch to workspace 2" +msgstr "" +"#-#-#-#-# fa.po (metacity HEAD) #-#-#-#-#\n" +"تعویض به فضای کاری ۲\n" +"#-#-#-#-# fa.po (metacity HEAD) #-#-#-#-#\n" +"رفتن به فضای‌کاری ۲" -#: ../src/session.c:1168 -msgid "<metacity_session> attribute seen but we already have the session ID" -msgstr "مشخصه‌ی <metacity_session> دیده شد اما شناسه‌ی نشست از قبل موجود بود" +#: ../src/50-mutter-navigation.xml.in.h:20 +#, fuzzy +msgid "Switch to workspace 3" +msgstr "" +"#-#-#-#-# fa.po (metacity HEAD) #-#-#-#-#\n" +"تعویض به فضای کاری ۳\n" +"#-#-#-#-# fa.po (metacity HEAD) #-#-#-#-#\n" +"رفتن به فضای‌کاری ۳" -#: ../src/session.c:1181 -#, c-format -msgid "Unknown attribute %s on <metacity_session> element" -msgstr "مشخصه‌ی %s روی عنصر <metacity_session> نامعلوم است" +#: ../src/50-mutter-navigation.xml.in.h:21 +#, fuzzy +msgid "Switch to workspace 4" +msgstr "" +"#-#-#-#-# fa.po (metacity HEAD) #-#-#-#-#\n" +"تعویض به فضای کاری ۴\n" +"#-#-#-#-# fa.po (metacity HEAD) #-#-#-#-#\n" +"رفتن به فضای‌کاری ۴" -#: ../src/session.c:1198 -msgid "nested <window> tag" -msgstr "برچسب <window> تودرتو است" +#: ../src/50-mutter-windows.xml.in.h:13 +#, fuzzy +msgid "Toggle fullscreen mode" +msgstr "ضامن حالت تمام صفحه" -#: ../src/session.c:1256 ../src/session.c:1288 -#, c-format -msgid "Unknown attribute %s on <window> element" -msgstr "مشخصه‌ی ‌%s روی عنصر <window> نامعلوم است" +#: ../src/50-mutter-windows.xml.in.h:14 +#, fuzzy +msgid "Toggle maximization state" +msgstr "" +"#-#-#-#-# fa.po (metacity HEAD) #-#-#-#-#\n" +"ضامن همیشه در وضیعت حداکثر\n" +"#-#-#-#-# fa.po (metacity HEAD) #-#-#-#-#\n" +"ضامن همیشه در وضعیت حداکثر" -#: ../src/session.c:1360 -#, c-format -msgid "Unknown attribute %s on <maximized> element" -msgstr "مشخصه‌ی ‌%s روی عنصر <maximized> نامعلوم است" +#: ../src/50-mutter-windows.xml.in.h:15 +#, fuzzy +msgid "Toggle shaded state" +msgstr "ضامن وضعیت سایه خورده" -#: ../src/session.c:1420 -#, c-format -msgid "Unknown attribute %s on <geometry> element" -msgstr "مشخصه‌ی ‌%s روی عنصر <geometry> نامعلوم است" +#: ../src/50-mutter-navigation.xml.in.h:1 +#, fuzzy +#| msgid "Hide all normal windows and set focus to the desktop" +msgid "Hide all normal windows" +msgstr "مخفی کردن همه‌ی پنجره‌های معمول" + +#: ../src/50-mutter-navigation.xml.in.h:2 +#, fuzzy +#| msgid "Move to Workspace _Left" +msgid "Move to workspace above" +msgstr "جابه‌جایی به فضای‌کاری _چپ" + +#: ../src/50-mutter-navigation.xml.in.h:3 +#, fuzzy +#| msgid "Move to Workspace _Down" +msgid "Move to workspace below" +msgstr "جابه‌جایی به فضای‌کاری پایین" + +#: ../src/50-mutter-navigation.xml.in.h:4 +#, fuzzy +#| msgid "Move to Workspace _Left" +msgid "Move to workspace left" +msgstr "جابه‌جایی به فضای‌کاری سمت چپ" + +#: ../src/50-mutter-navigation.xml.in.h:5 +#, fuzzy +#| msgid "Move to Workspace R_ight" +msgid "Move to workspace right" +msgstr "جابه‌جایی به فضای‌کاری سمت راست" + +#: ../src/50-mutter-navigation.xml.in.h:14 +#, fuzzy +msgid "Navigation" +msgstr "جابه‌جایی" -#: ../src/session.c:1440 -#, c-format -msgid "Unknown element %s" -msgstr "عنصر %s نامعلوم است" +#: ../src/50-mutter-navigation.xml.in.h:15 +#, fuzzy +msgid "Switch applications" +msgstr "تعویض برنامه‌ها" + +#: ../src/50-mutter-navigation.xml.in.h:16 +#, fuzzy +msgid "Switch system controls" +msgstr "تعویض کنترل‌های سیستم" + +#: ../src/50-mutter-navigation.xml.in.h:17 +#, fuzzy +msgid "Switch system controls directly" +msgstr "تعویض مستقیمِ کنترل‌های سیستم" + +#: ../src/50-mutter-navigation.xml.in.h:22 +#, fuzzy +msgid "Switch windows directly" +msgstr "تعویض مستیقیم پنجره‌ها" + +#: ../src/50-mutter-navigation.xml.in.h:23 +#, fuzzy +#| msgid "Move between windows of an application immediately" +msgid "Switch windows of an app directly" +msgstr "تعویض مستقیمِ پنجره‌های یک برنامه" + +#: ../src/50-mutter-navigation.xml.in.h:24 +#, fuzzy +#| msgid "Move between windows of an application immediately" +msgid "Switch windows of an application" +msgstr "تعویض پنجره‌های یک برنامه" + +#: ../src/50-mutter-system.xml.in.h:1 +#, fuzzy +msgid "Show the activities overview" +msgstr "نمایش نمای‌کلی فعالیت‌ها" + +#: ../src/50-mutter-system.xml.in.h:2 +#, fuzzy +#| msgid "Show the panel's main menu" +msgid "Show the run command prompt" +msgstr "نمایش خط فرمان اجرا" + +#: ../src/50-mutter-system.xml.in.h:3 +#, fuzzy +msgid "System" +msgstr "سیستم" + +#: ../src/50-mutter-windows.xml.in.h:1 +#, fuzzy +msgid "Activate the window menu" +msgstr "فعال کردن منوی پنجره" -#: ../src/session.c:1906 -#, c-format -msgid "" -"Error launching metacity-dialog to warn about apps that don't support " -"session management: %s\n" -msgstr "" -"خطا در راه‌اندازی metacity-dialog برای هشدار در مورد برنامه‌هایی که مدیریت " -"نشست را پشتیبانی نمی‌کنند: %s\n" +#: ../src/50-mutter-windows.xml.in.h:10 +#, fuzzy +#| msgid "Raise window if it's covered by another window, otherwise lower it" +msgid "Raise window if covered, otherwise lower it" +msgstr "بالا آوردن پنجره در صورتی که پوشیده شده است، در غیر اینصورت پایین برود" -#: ../src/theme-parser.c:224 ../src/theme-parser.c:242 -#, c-format -msgid "Line %d character %d: %s" -msgstr "خط %Id نویسه‌ی %Id: %s" +#: ../src/50-mutter-windows.xml.in.h:12 +#, fuzzy +msgid "Restore window" +msgstr "بازگرداندن پنجره" -#: ../src/theme-parser.c:396 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "مشخصه‌ی «%s» در عنصر <%s> دو بار تکرار شده است" +#: ../src/50-mutter-windows.xml.in.h:16 +#, fuzzy +#| msgid "Toggle whether window is on all workspaces or just one" +msgid "Toggle window on all workspaces or one" +msgstr "تغییر حالت پنجره در یک یا تمام فضاهای‌کاری" -#: ../src/theme-parser.c:414 ../src/theme-parser.c:439 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "مشخصه‌ی «%s» در این موقعیت روی عنصر <%s> نامعتبر است" +#~ msgid "Failed to parse message \"%s\" from dialog process\n" +#~ msgstr "شکست در تجزیه پیغام «%s» از پردازش محاوره\n" -#: ../src/theme-parser.c:485 -#, c-format -msgid "Integer %ld must be positive" -msgstr "عدد صحیح %ld باید مثبت باشد" +#~ msgid "Error reading from dialog display process: %s\n" +#~ msgstr "خطا در خواندن از پردازش نمایش محاوره: %s\n" -#: ../src/theme-parser.c:493 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "عدد صحیح %ld خیلی بزرگ است، حداکثر فعلی %d است" +#~ msgid "" +#~ "Error launching metacity-dialog to ask about killing an application: %s\n" +#~ msgstr "" +#~ "خطا در راه‌اندازی metacity-dialog برای پرسش درباره کشتن یک برنامه‌ی " +#~ "کاربردی: %s\n" -#: ../src/theme-parser.c:521 ../src/theme-parser.c:602 -#: ../src/theme-parser.c:626 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "«%s» به عنوان عدد اعشاری ممیز شناور قابل تجزیه نیست" +#~ msgid "Failed to get hostname: %s\n" +#~ msgstr "شکست در گرفتن نام میزبان: %s\n" -#: ../src/theme-parser.c:552 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "مقدار بولی باید «درست» یا «نادرست» باشد نه «%s»" +#~ msgid "" +#~ "Lost connection to the display '%s';\n" +#~ "most likely the X server was shut down or you killed/destroyed\n" +#~ "the window manager.\n" +#~ msgstr "" +#~ "از دست دادن اتصال برای نمایش «%s»؛\n" +#~ "به احتمال زیاد کارگزار X خاموش شده است یا شما مدیر پنجره‌ها را\n" +#~ "تخریب کرده‌اید یا کشته‌اید.\n" -#: ../src/theme-parser.c:572 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "زاویه %Ig بود، باید بین ۰٫۰ و ۳۶۰٫۰ باشد\n" +#~ msgid "Fatal IO error %d (%s) on display '%s'.\n" +#~ msgstr "خطای مهلک ورودی/خروجی %Id (%s) هنگام نمایش «%s».\n" -#: ../src/theme-parser.c:638 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "آلفا %Ig بود، باید بین ۰٫۰ (نامرئی) و ۱٫۰ (به تمامی تیره) باشد\n" +#~ msgid "Close Window" +#~ msgstr "بستن پنجره" -#: ../src/theme-parser.c:684 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"مقیاس عنوان «%s» نامعتبر است (باید xx-small یا x-small یا small یا medium یا " -"large یا x-large یا xx-large باشد)\n" - -#: ../src/theme-parser.c:729 ../src/theme-parser.c:737 -#: ../src/theme-parser.c:807 ../src/theme-parser.c:897 -#: ../src/theme-parser.c:935 ../src/theme-parser.c:1012 -#: ../src/theme-parser.c:1062 ../src/theme-parser.c:1070 -#: ../src/theme-parser.c:1126 ../src/theme-parser.c:1134 -#: ../src/theme-parser.c:2936 ../src/theme-parser.c:3025 -#: ../src/theme-parser.c:3032 ../src/theme-parser.c:3039 -#, c-format -msgid "No \"%s\" attribute on <%s> element" -msgstr "عنصر <%2$s> مشخصه‌ی «%1$s» ندارد" +#~ msgid "Window Menu" +#~ msgstr "منوی پنجره" -#: ../src/theme-parser.c:837 ../src/theme-parser.c:905 -#: ../src/theme-parser.c:943 ../src/theme-parser.c:1020 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s> نام «%s» برای بار دوم استفاده شده است" +#~ msgid "Minimize Window" +#~ msgstr "حداقل کردن پنجره" -#: ../src/theme-parser.c:849 ../src/theme-parser.c:955 -#: ../src/theme-parser.c:1032 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "<%s> والد «%s» تعریف نشده است" +#~ msgid "Maximize Window" +#~ msgstr "حداکثر کردن پنجره" -#: ../src/theme-parser.c:968 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "<%s> پیکربندی ظاهری «%s» تعریف نشده است" +#~ msgid "Unmaximize Window" +#~ msgstr "ناحداکثر کردن پنجره" -#: ../src/theme-parser.c:981 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "" -"<%s> باید پیکربندی ظاهری یا والدی که پیکربندی ظاهری داشته باشد مشخص شود" +#~ msgid "" +#~ "Error launching metacity-dialog to print an error about a command: %s\n" +#~ msgstr "" +#~ "خطا در راه‌اندازی metacity-dialog برای چاپ خطا درباره‌ی یک فرمان: %s\n" -#: ../src/theme-parser.c:1080 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "نوع «%s» روی عنصر <%s> نامعلوم است" +#~ msgid "No command %d has been defined.\n" +#~ msgstr " فرمان %Id تعریف نشده است.\n" -#: ../src/theme-parser.c:1091 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "style_set «%s» روی عنصر <%s> نامعلوم است" +#~ msgid "No terminal command has been defined.\n" +#~ msgstr "هیچ فرمان پایانه‌ای تعریف نشده است.\n" -#: ../src/theme-parser.c:1099 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr " نوع پنجره‌ی «%s» قبلاً به یک مجموعه‌ی سبک تخصیص داد شده است" +#~ msgid "Failed to restart: %s\n" +#~ msgstr "شکست در راه‌اندازی مجدد: %s\n" -#: ../src/theme-parser.c:1143 -#, c-format -msgid "Unknown function \"%s\" for menu icon" -msgstr "تابع «%s» برای شمایل منو نامعلوم است" +#~ msgid "On _Top" +#~ msgstr "همیشه رو" -#: ../src/theme-parser.c:1152 -#, c-format -msgid "Unknown state \"%s\" for menu icon" -msgstr "وضعیت «%s» برای شمایل منو نامعلوم است" +#~ msgid "" +#~ "Forcing this application to quit will cause you to lose any unsaved " +#~ "changes." +#~ msgstr "اجبار این برنامه به ترک باعث از دست رفتن تغییرات ذخیره نشده می‌شود." -#: ../src/theme-parser.c:1160 -#, c-format -msgid "Theme already has a menu icon for function %s state %s" -msgstr "تم در حال حاضر برای تابع %s وضعیت %s شمایل منو دارد" +#~ msgid "Title" +#~ msgstr "عنوان" -#: ../src/theme-parser.c:1177 ../src/theme-parser.c:3244 -#: ../src/theme-parser.c:3323 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "<draw_ops> با نام «%s» تعریف نشده است" +#~ msgid "Class" +#~ msgstr "رده" -#: ../src/theme-parser.c:1192 ../src/theme-parser.c:1256 -#: ../src/theme-parser.c:1545 ../src/theme-parser.c:3124 -#: ../src/theme-parser.c:3178 ../src/theme-parser.c:3338 -#: ../src/theme-parser.c:3515 ../src/theme-parser.c:3553 -#: ../src/theme-parser.c:3591 ../src/theme-parser.c:3629 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "عنصر <%s> زیر <%s> مجاز نیست" +#~ msgid "" +#~ "There was an error running \"%s\":\n" +#~ "%s." +#~ msgstr "" +#~ "شکست هنگام اجرای «%s»:\n" +#~ "%s." -#: ../src/theme-parser.c:1282 ../src/theme-parser.c:1369 -#: ../src/theme-parser.c:1439 -#, c-format -msgid "No \"name\" attribute on element <%s>" -msgstr "عنصر <%s> مشخصه‌ی «name» ندارد" +#~ msgid "Metacity" +#~ msgstr "متاسیتی" -#: ../src/theme-parser.c:1289 ../src/theme-parser.c:1376 -#, c-format -msgid "No \"value\" attribute on element <%s>" -msgstr "عنصر <%s> مشخصه‌ی «value» ندارد" +#~ msgid "" +#~ "(Not implemented) Navigation works in terms of applications not windows" +#~ msgstr "(پیاده‌سازی نشده) ناوش در میان برنامه‌ها کار می‌کند نه پنجره‌ها" -#: ../src/theme-parser.c:1320 ../src/theme-parser.c:1334 -#: ../src/theme-parser.c:1393 -msgid "" -"Cannot specify both button_width/button_height and aspect ratio for buttons" -msgstr "" -"button_width/button_height و نسبت عرض به ارتفاع دکمه‌ها هم زمان مشخص " -"نمی‌شوند " +#~ msgid "" +#~ "A font description string describing a font for window titlebars. The " +#~ "size from the description will only be used if the titlebar_font_size " +#~ "option is set to 0, however. Also, this option is disabled if the " +#~ "titlebar_uses_desktop_font option is set to true. By default, " +#~ "titlebar_font is unset, causing Metacity to fall back to the desktop font " +#~ "even if titlebar_uses_desktop_font is false." +#~ msgstr "" +#~ "رشته‌ی شرح قلم که قلم نوارهای عنوان پنجره را شرح می‌دهد. اما تنها زمانیکه " +#~ "گزینه‌ی titlebar_font_size، 0 تنظیم شده باشد، اندازه‌ی شرح استفاده می‌شود. " +#~ "به علاوه در صورتی که گزینه‌ی titlebar_uses_desktop_font درست تنظیم شده " +#~ "باشداین گزینه از کار انداخته می‌شود. طبق پیش فرض، titlebar_font تنظیم " +#~ "نشدهاست که باعث می‌شود متاسیتی از قلم رومیزی استفاده کند حتی اگر " +#~ "titlebar_uses_desktop_fontنادرست باشد." -#: ../src/theme-parser.c:1343 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "فاصله‌ی «%s» نامعلوم است" +#~ msgid "Action on title bar double-click" +#~ msgstr "کنشی که با دوبار کلیک روی نوار عنوان انجام می‌شود" -#: ../src/theme-parser.c:1402 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "نسبت عرض به ارتفاع «%s» نامعلوم است" +#~ msgid "Activate window menu" +#~ msgstr "فعال کردن منوی پنجره" -#: ../src/theme-parser.c:1446 -#, c-format -msgid "No \"top\" attribute on element <%s>" -msgstr "عنصر <%s> مشخصه‌ی «top» ندارد" +#~ msgid "Arrangement of buttons on the titlebar" +#~ msgstr "آرایش دکمه‌ها روی نوار عنوان" -#: ../src/theme-parser.c:1453 -#, c-format -msgid "No \"bottom\" attribute on element <%s>" -msgstr "عنصر <%s> مشخصه‌ی «bottom» ندارد" +#~ msgid "" +#~ "Arrangement of buttons on the titlebar. The value should be a string, " +#~ "such as \"menu:minimize,maximize,close\"; the colon separates the left " +#~ "corner of the window from the right corner, and the button names are " +#~ "comma-separated. Duplicate buttons are not allowed. Unknown button names " +#~ "are silently ignored so that buttons can be added in future metacity " +#~ "versions without breaking older versions." +#~ msgstr "" +#~ "آرایش دکمه‌ها روی نوار عنوان. مقدار باید یک رشته باشد. مثلاً «menu:minimize," +#~ "maximize,close»؛ دونقطه، گوشه‌ی چپ پنجره را ازگوشه‌ی راست جدا می‌کند و نام " +#~ "دکمه‌ها با ویرگول از هم جدا می‌شوند.دکمه تکراری مجاز نیست. دکمه‌های ناشناس " +#~ "در سکوت نادیده گرفته می‌شوند تا دکمه‌های جدید بدون از کار انداختن نسخه‌های " +#~ "قدیمی‌تر به نسخه‌های آینده‌ی متاسیتی اضافه شوند." -#: ../src/theme-parser.c:1460 -#, c-format -msgid "No \"left\" attribute on element <%s>" -msgstr "عنصر <%s> مشخصه‌ی «left» ندارد" +#~ msgid "Automatically raises the focused window" +#~ msgstr "پنجره مورد تمرکز را به طور خودکار پیش‌بکشد." -#: ../src/theme-parser.c:1467 -#, c-format -msgid "No \"right\" attribute on element <%s>" -msgstr "عنصر <%s> مشخصه‌ی «right» ندارد" +#~ msgid "" +#~ "Clicking a window while holding down this modifier key will move the " +#~ "window (left click), resize the window (middle click), or show the window " +#~ "menu (right click). Modifier is expressed as \"<Alt>\" or \"<" +#~ "Super>\" for example." +#~ msgstr "" +#~ "کلیک کردن روی یک پنجره در حین پایین نگه داشتن این کلید تغییردهنده، باعث " +#~ "حرکت پنجره (کلیک چپ)، تغییر اندازه‌ی پنجره (کلیک وسط) یا نمایش منوی پنجره " +#~ "(کلیک راست) می‌شود. تغییردهنده به صورت مثلاً«<Alt>» یا «<Super>» " +#~ "نمایش داده می‌شود." -#: ../src/theme-parser.c:1499 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "کناره‌ی «%s» نامعلوم است" +#~ msgid "Commands to run in response to keybindings" +#~ msgstr "فرمان‌هایی که در پاسخ به کلیدهای مقید اجرا می‌شوند" -#: ../src/theme-parser.c:1655 ../src/theme-parser.c:1765 -#: ../src/theme-parser.c:1868 ../src/theme-parser.c:2055 -#: ../src/theme-parser.c:2869 -#, c-format -msgid "No \"color\" attribute on element <%s>" -msgstr "عنصر <%s> مشخصه‌ی «color» ندارد" +#~ msgid "Current theme" +#~ msgstr "تم فعلی" -#: ../src/theme-parser.c:1662 -#, c-format -msgid "No \"x1\" attribute on element <%s>" -msgstr "عنصر <%s> مشخصه‌ی «x1» ندارد" +#~ msgid "Delay in milliseconds for the auto raise option" +#~ msgstr "تأخیر به میلی ثانیه برای گزینه‌ی پیش آوردن خودکار " -#: ../src/theme-parser.c:1669 ../src/theme-parser.c:2714 -#, c-format -msgid "No \"y1\" attribute on element <%s>" -msgstr "عنصر <%s> مشخصه‌ی «y1» ندارد" +#~ msgid "" +#~ "Determines whether applications or the system can generate audible " +#~ "'beeps'; may be used in conjunction with 'visual bell' to allow silent " +#~ "'beeps'." +#~ msgstr "" +#~ "مشخص می‌کند که برنامه‌ها یا سیستم می‌توانند «بوق» قابل شنیدن تولید کنند یا " +#~ "نه: ممکن است همزمان با «زنگ دیداری» به کار رود تا «بوق» بی‌صدا امکان پذیر " +#~ "شود." -#: ../src/theme-parser.c:1676 -#, c-format -msgid "No \"x2\" attribute on element <%s>" -msgstr "عنصر <%s> مشخصه‌ی «x2» ندارد" +#~ msgid "Disable misfeatures that are required by old or broken applications" +#~ msgstr "" +#~ "از کار انداختن امکانات معیوبی که مورد نیاز برنامه‌های قدمی یا از " +#~ "کارافتاده‌اند " -#: ../src/theme-parser.c:1683 ../src/theme-parser.c:2721 -#, c-format -msgid "No \"y2\" attribute on element <%s>" -msgstr "عنصر <%s> مشخصه‌ی «y2» ندارد" +#~ msgid "Enable Visual Bell" +#~ msgstr "به کار انداختن زنگ دیداری" -#: ../src/theme-parser.c:1772 ../src/theme-parser.c:1875 -#: ../src/theme-parser.c:1981 ../src/theme-parser.c:2062 -#: ../src/theme-parser.c:2168 ../src/theme-parser.c:2266 -#: ../src/theme-parser.c:2483 ../src/theme-parser.c:2609 -#: ../src/theme-parser.c:2707 ../src/theme-parser.c:2781 -#: ../src/theme-parser.c:2876 -#, c-format -msgid "No \"x\" attribute on element <%s>" -msgstr "عنصر <%s> مشخصه‌ی «x» ندارد" +#~ msgid "Hide all windows and focus desktop" +#~ msgstr "مخفی کردن همه‌ی پنجره‌ها و تمرکز روی رومیزی" -#: ../src/theme-parser.c:1779 ../src/theme-parser.c:1882 -#: ../src/theme-parser.c:1988 ../src/theme-parser.c:2069 -#: ../src/theme-parser.c:2175 ../src/theme-parser.c:2273 -#: ../src/theme-parser.c:2490 ../src/theme-parser.c:2616 -#: ../src/theme-parser.c:2788 ../src/theme-parser.c:2883 -#, c-format -msgid "No \"y\" attribute on element <%s>" -msgstr "عنصر <%s> مشخصه‌ی «y» ندارد" +#~ msgid "" +#~ "If true, ignore the titlebar_font option, and use the standard " +#~ "application font for window titles." +#~ msgstr "" +#~ "اگر درست باشد گزینه‌ی titlebar_font نادیده گرفته شده و برای عنوان پنجره‌ها " +#~ "از قلم استاندارد برنامه استفاده می‌شود." -#: ../src/theme-parser.c:1786 ../src/theme-parser.c:1889 -#: ../src/theme-parser.c:1995 ../src/theme-parser.c:2076 -#: ../src/theme-parser.c:2182 ../src/theme-parser.c:2280 -#: ../src/theme-parser.c:2497 ../src/theme-parser.c:2623 -#: ../src/theme-parser.c:2795 -#, c-format -msgid "No \"width\" attribute on element <%s>" -msgstr "عنصر <%s> مشخصه‌ی «width» ندارد" +#~ msgid "" +#~ "If true, metacity will give the user less feedback and less sense of " +#~ "\"direct manipulation\", by using wireframes, avoiding animations, or " +#~ "other means. This is a significant reduction in usability for many users, " +#~ "but may allow legacy applications and terminal servers to function when " +#~ "they would otherwise be impractical. However, the wireframe feature is " +#~ "disabled when accessibility is on to avoid weird desktop breakages." +#~ msgstr "" +#~ "اگر درست باشد، متاسیتی با استفاده از چارچوب‌های سیمی، نشان ندادن " +#~ "پویانمایی‌ها یا به طرق دیگر، بازخوردهای کمتر و حس «دستکاری مستقیم» کمتری به " +#~ "کاربر می‌دهد. این کار باعث تقلیل محسوس قابلیت کاربری برای بسیاری از " +#~ "کاربران می‌شود، ولی شاید برنامه‌ها و کارگزارهای پایانه‌ی قدیمی را قادر سازد " +#~ "در شرایطی کار کنند که در غیر این صورت کار نمی‌کردند. به هر حال هنگامی که " +#~ "دسترسی‌پذیری روشن است برای جلوگیری از خرابی‌های غیرعادی رومیزی، امکانات " +#~ "چارچوب‌های سیمی از کار انداخته می‌شود." -#: ../src/theme-parser.c:1793 ../src/theme-parser.c:1896 -#: ../src/theme-parser.c:2002 ../src/theme-parser.c:2083 -#: ../src/theme-parser.c:2189 ../src/theme-parser.c:2287 -#: ../src/theme-parser.c:2504 ../src/theme-parser.c:2630 -#: ../src/theme-parser.c:2802 -#, c-format -msgid "No \"height\" attribute on element <%s>" -msgstr "عنصر <%s> مشخصه‌ی «height» ندارد" +#~ msgid "" +#~ "If true, then Metacity works in terms of applications rather than " +#~ "windows. The concept is a bit abstract, but in general an application-" +#~ "based setup is more like the Mac and less like Windows. When you focus a " +#~ "window in application-based mode, all the windows in the application will " +#~ "be raised. Also, in application-based mode, focus clicks are not passed " +#~ "through to windows in other applications. The existence of this setting " +#~ "is somewhat questionable. But it's better than having settings for all " +#~ "the specific details of application-based vs. window-based, e.g. whether " +#~ "to pass through clicks. Also, application-based mode is largely " +#~ "unimplemented at the moment." +#~ msgstr "" +#~ "اگر درست باشد، متاسیتی بر مبنای برنامه‌ها کار می‌کند نه پنجره‌ها. این مفهوم " +#~ "کمی مجرد است، ولی عموماً برپاسازی بر پایه‌ی برنامه بیشتر شبیه مکینتاش و " +#~ "کمتر شبیه ویندوز است. در حالت بر پایه‌ی برنامه وقتی روی یک پنجره تمرکز " +#~ "می‌کنید، همه‌ی پنجره‌های برنامه پیش می‌آیند. همچنین، در حالت بر پایه‌ی برنامه، " +#~ "کلیک‌های تمرکز به پنجره‌های برنامه‌های دیگر رد نمی‌شوند. وجود این تنظیمات تا " +#~ "حدودی سؤال برانگیز است. ولی بهتر از داشتن تنظیمات برای همه‌ی جزئیات خاص بر " +#~ "پایه‌ی برنامه در برابر بر پایه‌ی پنجره است، مثلاً این که کلیک ‌ها رد بشوند یا " +#~ "نه. در ضمن، حالت بر پایه‌ی برنامه در حال حاضر تا حدود زیادی پیاده‌سازی نشده " +#~ "است." + +#~ msgid "If true, trade off usability for less resource usage" +#~ msgstr "" +#~ "اگر درست بود از قابلیت کاربری در قبال استفاده‌ی کمتر از منابع صرف نظر شود" -#: ../src/theme-parser.c:1903 -#, c-format -msgid "No \"start_angle\" attribute on element <%s>" -msgstr "عنصر <%s> مشخصه‌ی «start_angle» ندارد" +#~ msgid "Move backward between panels and the desktop immediately" +#~ msgstr "جابه‌جایی آنی به عقب بین تابلو و رومیزی" -#: ../src/theme-parser.c:1910 -#, c-format -msgid "No \"extent_angle\" attribute on element <%s>" -msgstr "عنصر <%s> مشخصه‌ی «extent_angle» ندارد" +#~ msgid "Move backwards between panels and the desktop with popup" +#~ msgstr "جابه‌جایی به عقب بین تابلوها و رومیزی با واشو" -#: ../src/theme-parser.c:2090 -#, c-format -msgid "No \"alpha\" attribute on element <%s>" -msgstr "عنصر <%s> مشخصه‌ی «alpha» ندارد" +#~ msgid "Move backwards between windows immediately" +#~ msgstr "جابه‌جایی آنی به عقب بین پنجره‌ها" -#: ../src/theme-parser.c:2161 -#, c-format -msgid "No \"type\" attribute on element <%s>" -msgstr "عنصر <%s> مشخصه‌ی «type» ندارد" +#~ msgid "Move between panels and the desktop immediately" +#~ msgstr "جابه‌جایی آنی بین تابلو و رومیزی" -#: ../src/theme-parser.c:2209 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "مقدار «%s» برای نوع شیب قابل درک نیست" +#~ msgid "Move between panels and the desktop with popup" +#~ msgstr "جابه‌جایی بین تابلوها و رومیزی با واشو" -#: ../src/theme-parser.c:2294 -#, c-format -msgid "No \"filename\" attribute on element <%s>" -msgstr "عنصر <%s> مشخصه‌ی «filename» ندارد" +#~ msgid "Move between windows immediately" +#~ msgstr "جابه‌جایی آنی بین پنجره‌ها" -#: ../src/theme-parser.c:2319 ../src/theme-parser.c:2827 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "" +#~ msgid "Move focus backwards between windows using popup display" +#~ msgstr "انتقال تمرکز به عقب بین پنجره‌ها با نمایش واشو" -#: ../src/theme-parser.c:2462 ../src/theme-parser.c:2595 -#: ../src/theme-parser.c:2700 -#, c-format -msgid "No \"state\" attribute on element <%s>" -msgstr "عنصر <%s> مشخصه‌ی «state» ندارد" +#~ msgid "Move window to workspace 10" +#~ msgstr "جابه‌جایی پنجره به فضای کاری ۱۰" -#: ../src/theme-parser.c:2469 ../src/theme-parser.c:2602 -#, c-format -msgid "No \"shadow\" attribute on element <%s>" -msgstr "عنصر <%s> مشخصه‌ی «shadow» ندارد" +#~ msgid "Move window to workspace 11" +#~ msgstr "جابه‌جایی پنجره به فضای کاری ۱۱" -#: ../src/theme-parser.c:2476 -#, c-format -msgid "No \"arrow\" attribute on element <%s>" -msgstr "عنصر <%s> مشخصه‌ی «arrow» ندارد" +#~ msgid "Move window to workspace 12" +#~ msgstr "جابه‌جایی پنجره به فضای کاری ۱۲" -#: ../src/theme-parser.c:2529 ../src/theme-parser.c:2651 -#: ../src/theme-parser.c:2739 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "وضعیت «%s» برای عنصر <%s> قابل درک نیست" +#~ msgid "Move window to workspace 5" +#~ msgstr "جابه‌جایی پنجره به فضای کاری ۵" -#: ../src/theme-parser.c:2539 ../src/theme-parser.c:2661 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "سایه‌ی «%s» برای عنصر <%s> قابل درک نیست" +#~ msgid "Move window to workspace 6" +#~ msgstr "جابه‌جایی پنجره به فضای کاری ۶" -#: ../src/theme-parser.c:2549 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "پیکان «%s» برای عنصر <%s> قابل درک نیست" +#~ msgid "Move window to workspace 7" +#~ msgstr "جابه‌جایی پنجره به فضای کاری ۷" -#: ../src/theme-parser.c:2962 ../src/theme-parser.c:3078 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "<draw_ops> با نام «%s» تعریف نشده است" +#~ msgid "Move window to workspace 8" +#~ msgstr "جابه‌جایی پنجره به فضای کاری ۸" -#: ../src/theme-parser.c:2974 ../src/theme-parser.c:3090 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "گنجاندن draw_ops «%s» در اینجا، مرجع دوری ایجاد می‌کند" +#~ msgid "Move window to workspace 9" +#~ msgstr "جابه‌جایی پنجره به فضای کاری ۹" -#: ../src/theme-parser.c:3153 -#, c-format -msgid "No \"value\" attribute on <%s> element" -msgstr "عنصر <%s> مشخصه‌ی «value» ندارد" +#~ msgid "Name of workspace" +#~ msgstr "نام فضای کاری" -#: ../src/theme-parser.c:3210 -#, c-format -msgid "No \"position\" attribute on <%s> element" -msgstr "عنصر <%s> مشخصه‌ی «position» ندارد" +#~ msgid "Number of workspaces" +#~ msgstr "تعداد فضاهای کاری" -#: ../src/theme-parser.c:3219 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "موقعیت «%s» برای قطعه‌ی چارچوب نامعلوم است" +#~ msgid "" +#~ "Number of workspaces. Must be more than zero, and has a fixed maximum (to " +#~ "prevent accidentally destroying your desktop by asking for 34 million " +#~ "workspaces)." +#~ msgstr "" +#~ "تعداد فضاهای کاری. باید بیش از صفر باشد و حداکثر مشخصی دارد (برای این که " +#~ "اتفاقی رومیزی‌تان را با درخواست ۳۴ میلیون فضای کاری از بین نبرید)." -#: ../src/theme-parser.c:3227 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "سبک چارچوب در حال حاضر قطعه‌ای در موقعیت %s دارد" +#~ msgid "Run a defined command" +#~ msgstr "اجرای یک فرمان تعریف شده" -#: ../src/theme-parser.c:3272 -#, c-format -msgid "No \"function\" attribute on <%s> element" -msgstr "عنصر <%s> مشخصه‌ی «function» ندارد" +#~ msgid "Run a terminal" +#~ msgstr "اجرای پایانه" -#: ../src/theme-parser.c:3280 ../src/theme-parser.c:3384 -#, c-format -msgid "No \"state\" attribute on <%s> element" -msgstr "عنصر <%s> مشخصه‌ی «state» ندارد" +#~ msgid "Show the panel menu" +#~ msgstr "نشان دادن منوی تابلو" -#: ../src/theme-parser.c:3289 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "تابع «%s» برای دکمه نامعلوم است" +#~ msgid "Show the panel run application dialog" +#~ msgstr "نشان دادن محاوره‌ی اجرای برنامه‌ی تابلو" -#: ../src/theme-parser.c:3298 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "وضعیت «%s» برای دکمه نامعلوم است" +#~ msgid "" +#~ "Some applications break specifications in ways that result in window " +#~ "manager misfeatures. For example, ideally Metacity would place all " +#~ "dialogs in a consistent position with respect to their parent window. " +#~ "This requires ignoring application-specified positions for dialogs. But " +#~ "some versions of Java/Swing mark their popup menus as dialogs, so " +#~ "Metacity has to disable dialog positioning to allow menus to work in " +#~ "broken Java applications. There are several other examples like this. " +#~ "This option puts Metacity in full-on Correct mode, which perhaps gives a " +#~ "moderately nicer UI if you don't need to run any broken apps. Sadly, " +#~ "workarounds must be enabled by default; the real world is an ugly place. " +#~ "Some of the workarounds are workarounds for limitations in the " +#~ "specifications themselves, so sometimes a bug in no-workarounds mode " +#~ "won't be fixable without amending a spec." +#~ msgstr "" +#~ "بعضی از برنامه‌ها قواعد جزئی را طوری نقض می‌کنند که به بد کار کردن مدیر " +#~ "پنجره‌ها منجر می‌شود. به عنوان مثال، متاسیتی در وضع مطلوب تمام محاوره‌ها را " +#~ "در وضعیت سازگار با پنجره‌ی والد آن‌ها قرار می‌دهد. این مسأله نیازمند نادیده " +#~ "گرفتن مشخصات برنامه‌ها برای وضعیت محاوره‌ها است. اما بعضی از نسخه‌های Java/" +#~ "Swing منوهای واشو را به عنوان محاوره ثبت می‌کنند و متاسیتی مجبور است برای " +#~ "کار کردن منوها در برنامه‌های خراب جاوا جاگذاری محاوره را از کار بیاندازد. " +#~ "مثال‌های مختلف دیگری نیز از این دست وجود دارند. این گزینه متاسیتی را در " +#~ "حالت درست با همه‌ی گزینه‌ها قرار می‌دهد که احتمالاً اگر نیاز به اجرای " +#~ "برنامه‌های خراب نداشته باشید، واسط کاربر بهتری خواهد داشت. متأسفانه دور " +#~ "زدن‌ها را باید به طور پیش فرض به کار انداخت؛ دنیای واقعی جای زشتی است. " +#~ "بعضی از دور زدن‌ها دورزدن کمبودهای خود قواعد جزئی هستند، بنابراین بعضی " +#~ "وقت‌ها اشکال در حالت دور زدن بدون دستکاری قواعد قبل رفع نیست." -#: ../src/theme-parser.c:3306 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "سبک چارچوب در حال حاضر برای تابع %s وضعیت %s دکمه دارد" +#~ msgid "Switch to workspace 10" +#~ msgstr "تعویض به فضای کاری ۱۰" -#: ../src/theme-parser.c:3376 -#, c-format -msgid "No \"focus\" attribute on <%s> element" -msgstr "عنصر <%s> مشخصه‌ی «focus» ندارد" +#~ msgid "Switch to workspace 11" +#~ msgstr "تعویض به فضای کاری ۱۱" -#: ../src/theme-parser.c:3392 -#, c-format -msgid "No \"style\" attribute on <%s> element" -msgstr "عنصر <%s> مشخصه‌ی «style» ندارد" +#~ msgid "Switch to workspace 12" +#~ msgstr "تعویض به فضای کاری ۱۲" -#: ../src/theme-parser.c:3401 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "«%s» مقدار معتبری برای مشخصه‌ی تمرکز نیست" +#~ msgid "Switch to workspace 5" +#~ msgstr "تعویض به فضای کاری ۵" -#: ../src/theme-parser.c:3410 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "«%s» مقدار معتبری برای مشخصه‌ی وضعیت نیست" +#~ msgid "Switch to workspace 6" +#~ msgstr "تعویض به فضای کاری ۶" -#: ../src/theme-parser.c:3420 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "سبکی با نام «%s» تعریف نشده است" +#~ msgid "Switch to workspace 7" +#~ msgstr "تعویض به فضای کاری ۷" -#: ../src/theme-parser.c:3430 -#, c-format -msgid "No \"resize\" attribute on <%s> element" -msgstr "عنصر <%s> مشخصه‌ی «resize» ندارد" +#~ msgid "Switch to workspace 8" +#~ msgstr "تعویض به فضای کاری ۸" -#: ../src/theme-parser.c:3440 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "«%s» مقدار معتبری برای مشخصه‌ی تغییر اندازه نیست" +#~ msgid "Switch to workspace 9" +#~ msgstr "تعویض به فضای کاری ۹" -#: ../src/theme-parser.c:3450 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" -"عنصر <%s> در وضعیت‌های حداکثر و سایه خورده مشخصه‌ی «resize» نباید داشته باشد" +#~ msgid "Switch to workspace above this one" +#~ msgstr "تعویض به فضای کاری بالایی" -#: ../src/theme-parser.c:3464 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "سبک، در حال حاضر، برای وضعیت %s تغییر اندازه %s تمرکز %s مشخص شده است" +#~ msgid "Switch to workspace below this one" +#~ msgstr "تعویض به فضای کاری پایینی" -#: ../src/theme-parser.c:3475 ../src/theme-parser.c:3486 -#: ../src/theme-parser.c:3497 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "سبک، در حال حاضر، برای وضعیت %s تمرکز %s مشخص شده است" +#~ msgid "Switch to workspace on the left" +#~ msgstr "تعویض به فضای کاری چپ" -#: ../src/theme-parser.c:3536 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"عنصر <piece> نمی‌تواند دو draw_ops داشته باشد. (تم یک مشخصه‌ی draw_ops و یک " -"عنصر <draw_ops> یا دو عنصر مشخص کرده است) " +#~ msgid "Switch to workspace on the right" +#~ msgstr "تعویض به فضای کاری راست" -#: ../src/theme-parser.c:3574 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"عنصر <button> نمی‌تواند دو draw_ops داشته باشد. (تم یک مشخصه‌ی draw_ops و یک " -"عنصر <draw_ops> یا دو عنصر مشخص کرده است) " +#~ msgid "System Bell is Audible" +#~ msgstr "زنگ سیستم قابل شنیدن است" -#: ../src/theme-parser.c:3612 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"عنصر <menu_icon> نمی‌تواند دو draw_ops داشته باشد. (تم یک مشخصه‌ی draw_ops و " -"یک عنصر <draw_ops> یا دو عنصر مشخص کرده است) " +#~ msgid "Take a screenshot" +#~ msgstr "عکس گرفتن از صفحه" -#: ../src/theme-parser.c:3659 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "بیرونی‌ترین عنصر تم باید <metacity_theme> باشد نه <%s>" +#~ msgid "Take a screenshot of a window" +#~ msgstr "عکس گرفتن از پنجره " -#: ../src/theme-parser.c:3679 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "" -"عنصر <%s> درون عنصرهای name یا author یا date یا description جایز نیست" +#~ msgid "" +#~ "Tells Metacity how to implement the visual indication that the system " +#~ "bell or another application 'bell' indicator has been rung. Currently " +#~ "there are two valid values, \"fullscreen\", which causes a fullscreen " +#~ "white-black flash, and \"frame_flash\" which causes the titlebar of the " +#~ "application which sent the bell signal to flash. If the application which " +#~ "sent the bell is unknown (as is usually the case for the default \"system " +#~ "beep\"), the currently focused window's titlebar is flashed." +#~ msgstr "" +#~ "به متاسیتی می‌گوید چطور شاخص تصویری‌ای که زنگ سیستم یا برنامه‌ی شاخص «زنگ» " +#~ "دیگری به صدا در آمده است را پیاده‌سازی کند. در حال حاضر دو مقدار معتبر " +#~ "وجود دارند، «fullscreen» که سبب یک جرقه‌ی سیاه و سفید تمام‌صفحه می‌شود، و " +#~ "«frame_flsh» که سبب می‌شود نوار عنوان برنامه‌ای که سیگنال زنگ را ارسال کرده " +#~ "جرقه بزند. اگر برنامه‌ای که سیگنال زنگ را فرستاده نامعلوم باشد (که معمولاً " +#~ "در مورد برای «بوق سیستم» پیش‌فرض این طور است)، نوار عنوان پنجره‌ای که فعلاً " +#~ "مورد تمرکز است جرقه می‌زند." -#: ../src/theme-parser.c:3684 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "عنصر <%s> درون عنصر <constant> جایز نیست" +#~ msgid "" +#~ "The /apps/metacity/global_keybindings/run_command_N keys define " +#~ "keybindings that correspond to these commands. Pressing the keybinding " +#~ "for run_command_N will execute command_N." +#~ msgstr "" +#~ "کلیدهای /apps/metacity/global_keybindings/run_command_N کلیدهای مقیدی " +#~ "تعریف می‌کنند که متناظر با این فرمان‌ها هستند. فشار دادن کلید مقید برای " +#~ "run_command_N، command_N را اجرا خواهد کرد." -#: ../src/theme-parser.c:3696 -#, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "عنصر <%s> درون عنصرهای disanceیا border یا aspect_ratio جایز نیست" +#~ msgid "" +#~ "The /apps/metacity/global_keybindings/run_command_screenshot key defines " +#~ "a keybinding which causes the command specified by this setting to be " +#~ "invoked." +#~ msgstr "" +#~ "کلید /apps/metacity/global_keybindings/run_command_screenshot کلید مقیدی " +#~ "تعریف می‌کند که سبب می‌شود فرمان مشخص شده با این تنظیم احضار شود." -#: ../src/theme-parser.c:3718 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "عنصر <%s> داخل عنصر عملیات رسم مجاز نیست" +#~ msgid "" +#~ "The /apps/metacity/global_keybindings/run_command_window_screenshot key " +#~ "defines a keybinding which causes the command specified by this setting " +#~ "to be invoked." +#~ msgstr "" +#~ "کلید /apps/metacity/global_keybindings/run_command_window_screenshot کلید " +#~ "مقیدی تعریف می‌کند که سبب می‌شود فرمان مشخص شده با این تنظیم احضار شود." -#: ../src/theme-parser.c:3728 ../src/theme-parser.c:3758 -#: ../src/theme-parser.c:3763 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "عنصر <%s> درون یک عنصر <%s> جایز نیست" +#~ msgid "" +#~ "The keybinding that runs the correspondingly-numbered command in /apps/" +#~ "metacity/keybinding_commands The format looks like \"<Control>a\" " +#~ "or \"<Shift><Alt>F1\". The parser is fairly liberal and " +#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" +#~ "\" and \"<Ctrl>\". If you set the option to the special string " +#~ "\"disabled\", then there will be no keybinding for this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که فرمان correspondingly-numbered را در/appsmetacity/" +#~ "keybinding_commands اجرا می‌کند: قالب آن به شکل«<Control>a» یا «<" +#~ "Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ " +#~ "یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول می‌کند. " +#~ "اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید مقیدی " +#~ "برای این کنش وجود نخواهد داشت." -#: ../src/theme-parser.c:3984 -msgid "No draw_ops provided for frame piece" -msgstr "draw_ops برای قطعه‌ی چارچوب منظور نشده است" +#~ msgid "" +#~ "The keybinding that switches to the workspace above the current " +#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" +#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " +#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" +#~ "\". If you set the option to the special string \"disabled\", then there " +#~ "will be no keybinding for this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که فضای کاری فعلی را با فضای کاری بالایی تعویض می‌کند؛ قالب " +#~ "آن به شکل«<Control>a» یا «<Shift><Alt>F1» است. این " +#~ "تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<" +#~ "Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی " +#~ "ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-parser.c:3999 -msgid "No draw_ops provided for button" -msgstr "draw_ops برای دکمه منظور نشده است" +#~ msgid "" +#~ "The keybinding that switches to the workspace below the current " +#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" +#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " +#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" +#~ "\". If you set the option to the special string \"disabled\", then there " +#~ "will be no keybinding for this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که فضای کاری فعلی را با فضای کاری پایینی تعویض می‌کند؛ قالب " +#~ "آن به شکل «<Control>a» یا «<Shift><Alt>F1»است. این " +#~ "تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<" +#~ "Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی " +#~ "ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-parser.c:4014 -msgid "No draw_ops provided for menu icon" -msgstr "draw_ops برای شمایل منو منظور نشده است" +#~ msgid "" +#~ "The keybinding that switches to the workspace on the left of the current " +#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" +#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " +#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" +#~ "\". If you set the option to the special string \"disabled\", then there " +#~ "will be no keybinding for this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که فضای کاری فعلی را با فضای کاری چپش تعویض می‌کند؛ قالب آن " +#~ "به شکل «<Control>a» یا «<Shift><Alt>F1»است. این تجزیه‌گر " +#~ "به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<" +#~ "Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی " +#~ "ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-parser.c:4054 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "هیچ متنی درون عنصر <%s> جایز نیست" +#~ msgid "" +#~ "The keybinding that switches to the workspace on the right of the current " +#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" +#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " +#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" +#~ "\". If you set the option to the special string \"disabled\", then there " +#~ "will be no keybinding for this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که فضای کاری فعلی را با فضای کاری راستش تعویض می‌کند؛ قالب " +#~ "آن به شکل «<Control>a» یا «<Shift><Alt>F1»است. این " +#~ "تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<" +#~ "Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی " +#~ "ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-parser.c:4109 -msgid "<name> specified twice for this theme" -msgstr "<name> دو بار برای این تم مشخص شده است" +#~ msgid "" +#~ "The keybinding that switches to workspace 1. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "مقیدسازی کلید برای تعویض به فضای کاری ۱. قالب آن به شکل «<Control>a» " +#~ "یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و " +#~ "حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را " +#~ "قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، " +#~ "کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-parser.c:4120 -msgid "<author> specified twice for this theme" -msgstr "<author> دو بار برای این تم مشخص شده است" +#~ msgid "" +#~ "The keybinding that switches to workspace 10. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "مقیدسازی کلید برای تعویض به فضای کاری ۱۰. قالب آن به شکل «<Control>" +#~ "a» یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و " +#~ "حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را " +#~ "قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، " +#~ "کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-parser.c:4131 -msgid "<copyright> specified twice for this theme" -msgstr "<copyright> دو بار برای این تم مشخص شده است" +#~ msgid "" +#~ "The keybinding that switches to workspace 11. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "مقیدسازی کلید برای تعویض به فضای کاری ۱۱. قالب آن به شکل «<Control>" +#~ "a» یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و " +#~ "حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را " +#~ "قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، " +#~ "کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-parser.c:4142 -msgid "<date> specified twice for this theme" -msgstr "<date> دو بار برای این تم مشخص شده است" +#~ msgid "" +#~ "The keybinding that switches to workspace 12. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "مقیدسازی کلید برای تعویض به فضای کاری ۱۲. قالب آن به شکل «<Control>" +#~ "a» یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و " +#~ "حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را " +#~ "قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، " +#~ "کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-parser.c:4153 -msgid "<description> specified twice for this theme" -msgstr "<description> دو بار برای این تم مشخص شده است" +#~ msgid "" +#~ "The keybinding that switches to workspace 2. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "مقیدسازی کلید برای تعویض به فضای کاری ۲. قالب آن به شکل «<Control>a» " +#~ "یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و " +#~ "حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را " +#~ "قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، " +#~ "کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-parser.c:4348 -#, c-format -msgid "Failed to read theme from file %s: %s\n" -msgstr "شکست در خواندن تم از پرونده‌ی %s: %s\n" +#~ msgid "" +#~ "The keybinding that switches to workspace 3. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "مقیدسازی کلید برای تعویض به فضای کاری ۳. قالب آن به شکل «<Control>a» " +#~ "یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و " +#~ "حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را " +#~ "قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، " +#~ "کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-parser.c:4403 -#, c-format -msgid "Theme file %s did not contain a root <metacity_theme> element" -msgstr "پرونده‌ی تم %s شامل یک عنصر <metacity_theme> شاخه نیست" +#~ msgid "" +#~ "The keybinding that switches to workspace 4. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "مقیدسازی کلید برای تعویض به فضای کاری ۴. قالب آن به شکل «<Control>a» " +#~ "یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و " +#~ "حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را " +#~ "قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، " +#~ "کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-viewer.c:72 -msgid "/_Windows" -msgstr "/پنجره‌ها" +#~ msgid "" +#~ "The keybinding that switches to workspace 5. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "مقیدسازی کلید برای تعویض به فضای کاری ۵. قالب آن به شکل «<Control>a» " +#~ "یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و " +#~ "حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را " +#~ "قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، " +#~ "کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-viewer.c:73 -msgid "/Windows/tearoff" -msgstr "پنجره‌ها/کنده‌شدنی" +#~ msgid "" +#~ "The keybinding that switches to workspace 6. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "مقیدسازی کلید برای تعویض به فضای کاری۶. قالب آن به شکل «<Control>a» " +#~ "یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و " +#~ "حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را " +#~ "قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، " +#~ "کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-viewer.c:74 -msgid "/Windows/_Dialog" -msgstr "/پنجره‌ها/محاوره" +#~ msgid "" +#~ "The keybinding that switches to workspace 7. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "مقیدسازی کلید برای تعویض به فضای کاری ۷. قالب آن به شکل «<Control>a» " +#~ "یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و " +#~ "حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را " +#~ "قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، " +#~ "کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-viewer.c:75 -msgid "/Windows/_Modal dialog" -msgstr "پنجره‌ها/محاوره‌ی وجهی" +#~ msgid "" +#~ "The keybinding that switches to workspace 8. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "مقیدسازی کلید برای تعویض به فضای کاری ۸. قالب آن به شکل «<Control>a» " +#~ "یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و " +#~ "حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را " +#~ "قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، " +#~ "کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-viewer.c:76 -msgid "/Windows/_Utility" -msgstr "پنجره‌ها/برنامه" +#~ msgid "" +#~ "The keybinding that switches to workspace 9. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "مقیدسازی کلید برای تعویض به فضای کاری ۹. قالب آن به شکل «<Control>a» " +#~ "یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبتآسان‌گیر است و حروف " +#~ "بزرگ یا کوچک و خلاصه کردن به شکل«<Ctl>» و «<Ctrl>» را قبول " +#~ "می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی«disabled» قرار دهید، کلید " +#~ "مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-viewer.c:77 -msgid "/Windows/_Splashscreen" -msgstr "" +#~ msgid "" +#~ "The keybinding used to activate the window menu. The format looks like " +#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " +#~ "fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که برای فعال‌سازی منوی پنجره به کار می‌رود؛ قالب آن به شکل " +#~ "«<Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت " +#~ "آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<" +#~ "Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» " +#~ "قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-viewer.c:78 -msgid "/Windows/_Top dock" -msgstr "" +#~ msgid "" +#~ "The keybinding used to close a window. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که برای بستن پنجره به کار می‌رود؛ قالب آن به شکل «<" +#~ "Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت " +#~ "آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<" +#~ "Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» " +#~ "قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-viewer.c:79 -msgid "/Windows/_Bottom dock" -msgstr "" +#~ msgid "" +#~ "The keybinding used to enter \"move mode\" and begin moving a window " +#~ "using the keyboard. The format looks like \"<Control>a\" or \"<" +#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " +#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" +#~ "Ctrl>\". If you set the option to the special string \"disabled\", " +#~ "then there will be no keybinding for this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که برای وارد شدن به «حالت جابه‌جایی» و شروع جابه‌جایی پنجره " +#~ "با استفاده از صفحه‌کلید به کار می‌رود؛ قالب آن به شکل «<Control>a» یا " +#~ "«<Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف " +#~ "بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول " +#~ "می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید " +#~ "مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-viewer.c:80 -msgid "/Windows/_Left dock" -msgstr "" +#~ msgid "" +#~ "The keybinding used to enter \"resize mode\" and begin resizing a window " +#~ "using the keyboard. The format looks like \"<Control>a\" or \"<" +#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " +#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" +#~ "Ctrl>\". If you set the option to the special string \"disabled\", " +#~ "then there will be no keybinding for this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که برای وارد شدن به «حالت تغییر اندازه» و شروع تغییر " +#~ "اندازه‌ی پنجره با استفاده از صفحه‌کلید به کار می‌رود؛ قالب آن به شکل «<" +#~ "Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت " +#~ "آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<" +#~ "Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» " +#~ "قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-viewer.c:81 -msgid "/Windows/_Right dock" -msgstr "" +#~ msgid "" +#~ "The keybinding used to hide all normal windows and set the focus to the " +#~ "desktop background. The format looks like \"<Control>a\" or \"<" +#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " +#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" +#~ "Ctrl>\". If you set the option to the special string \"disabled\", " +#~ "then there will be no keybinding for this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که برای پنهان کردن تمام پنجره‌های عادی و قرار دادن تمرکز بر " +#~ "پس‌زمینه‌ی رومیزی به کار می‌رود؛ قالب آن به شکل «<Control>a» یا «<" +#~ "Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ " +#~ "یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول می‌کند. " +#~ "اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید مقیدی " +#~ "برای این کنش وجود نخواهد داشت." -#: ../src/theme-viewer.c:82 -msgid "/Windows/_All docks" -msgstr "" +#~ msgid "" +#~ "The keybinding used to maximize a window. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که برای حداکثر کردن پنجره به کار می‌رود؛ قالب آن به شکل «<" +#~ "Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت " +#~ "آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<" +#~ "Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» " +#~ "قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-viewer.c:83 -msgid "/Windows/Des_ktop" -msgstr "/پنجره‌ها/رومیزی" +#~ msgid "" +#~ "The keybinding used to minimize a window. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که برای حداقل کردن پنجره به کار می‌رود؛ قالب آن به شکل «<" +#~ "Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت " +#~ "آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<" +#~ "Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» " +#~ "قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-viewer.c:132 -msgid "Open another one of these windows" -msgstr "یکی دیگر از این پنجره‌ها بازشود" +#~ msgid "" +#~ "The keybinding used to move a window one workspace down. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " +#~ "is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که برای جابه‌جایی پنجره به یک فضای کاری پایین‌تر به کار " +#~ "می‌رود؛ قالب آن به شکل «<Control>a» یا «<Shift><Alt>F1» " +#~ "است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به " +#~ "شکل «<Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر " +#~ "با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد " +#~ "داشت." -#: ../src/theme-viewer.c:139 -msgid "This is a demo button with an 'open' icon" -msgstr "این یک دکمه‌ی نمایشی با شمایل «بازکردن» است" +#~ msgid "" +#~ "The keybinding used to move a window one workspace to the left. The " +#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " +#~ "The parser is fairly liberal and allows lower or upper case, and also " +#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " +#~ "the option to the special string \"disabled\", then there will be no " +#~ "keybinding for this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که برای جابه‌جایی پنجره به فضای کاری چپش به کار می‌رود؛ قالب " +#~ "آن به شکل «<Control>a» یا «<Shift><Alt>F1» است. این " +#~ "تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<" +#~ "Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی " +#~ "ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-viewer.c:146 -msgid "This is a demo button with a 'quit' icon" -msgstr "این یک دکمه‌ی نمایشی با شمایل «ترک» است" +#~ msgid "" +#~ "The keybinding used to move a window one workspace to the right. The " +#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " +#~ "The parser is fairly liberal and allows lower or upper case, and also " +#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " +#~ "the option to the special string \"disabled\", then there will be no " +#~ "keybinding for this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که برای جابه‌جایی پنجره به فضای کاری راستش به کار می‌رود؛ " +#~ "قالب آن به شکل «<Control>a» یا «<Shift><Alt>F1» است. این " +#~ "تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<" +#~ "Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی " +#~ "ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-viewer.c:239 -msgid "This is a sample message in a sample dialog" -msgstr "این یک پیغام نمونه در یک محاوره‌ی نمونه است" +#~ msgid "" +#~ "The keybinding used to move a window one workspace up. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " +#~ "is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که برای جابه‌جایی پنجره به یک فضای کاری بالاتر به کار " +#~ "می‌رود؛ قالب آن به شکل «<Control>a» یا «<Shift><Alt>F1» " +#~ "است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به " +#~ "شکل «<Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر " +#~ "با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد " +#~ "داشت." -#: ../src/theme-viewer.c:322 -#, c-format -msgid "Fake menu item %d\n" -msgstr "مورد %Id منوی جعلی\n" +#~ msgid "" +#~ "The keybinding used to move a window to workspace 1. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " +#~ "is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که برای جابه‌جایی پنجره به فضای کاری ۱ به کار می‌رود؛ قالب " +#~ "آن به شکل «<Control>a» یا «<Shift><Alt>F1» است. این " +#~ "تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<" +#~ "Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی " +#~ "ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-viewer.c:356 -msgid "Border-only window" -msgstr "پنجره‌ی فقط کناره‌دار" +#~ msgid "" +#~ "The keybinding used to move a window to workspace 10. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " +#~ "is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که برای جابه‌جایی پنجره به فضای کاری ۱۰ به کار می‌رود؛ قالب " +#~ "آن به شکل «<Control>a» یا «<Shift><Alt>F1» است. این " +#~ "تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<" +#~ "Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی " +#~ "ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-viewer.c:358 -msgid "Bar" -msgstr "نوار" +#~ msgid "" +#~ "The keybinding used to move a window to workspace 11. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " +#~ "is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که برای جابه‌جایی پنجره به فضای کاری ۱۱ به کار می‌رود؛ قالب " +#~ "آن به شکل «<Control>a» یا «<Shift><Alt>F1» است. این " +#~ "تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<" +#~ "Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی " +#~ "ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-viewer.c:375 -msgid "Normal Application Window" -msgstr "پنجره‌ی عادی برنامه" +#~ msgid "" +#~ "The keybinding used to move a window to workspace 12. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " +#~ "is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که برای جابه‌جایی پنجره به فضای کاری ۱۲ به کار می‌رود؛ قالب " +#~ "آن به شکل «<Control>a» یا «<Shift><Alt>F1» است. این " +#~ "تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<" +#~ "Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی " +#~ "ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-viewer.c:379 -msgid "Dialog Box" -msgstr "جعبه‌ی محاوره" +#~ msgid "" +#~ "The keybinding used to move a window to workspace 2. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " +#~ "is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که برای جابه‌جایی پنجره به فضای کاری ۲ به کار می‌رود؛ قالب " +#~ "آن به شکل «<Control>a» یا «<Shift><Alt>F1» است. این " +#~ "تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<" +#~ "Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی " +#~ "ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-viewer.c:383 -msgid "Modal Dialog Box" -msgstr "جعبه‌ی محاوره‌ی چند حالتی" +#~ msgid "" +#~ "The keybinding used to move a window to workspace 3. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " +#~ "is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که برای جابه‌جایی پنجره به فضای کاری ۳ به کار می‌رود؛ قالب " +#~ "آن به شکل «<Control>a» یا «<Shift><Alt>F1» است. این " +#~ "تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<" +#~ "Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی " +#~ "ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-viewer.c:387 -msgid "Utility Palette" -msgstr "تخته‌رنگ برنامه‌" +#~ msgid "" +#~ "The keybinding used to move a window to workspace 4. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " +#~ "is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که برای جابه‌جایی پنجره به فضای کاری ۴ به کار می‌رود؛ قالب " +#~ "آن به شکل «<Control>a» یا «<Shift><Alt>F1» است. این " +#~ "تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<" +#~ "Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی " +#~ "ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-viewer.c:391 -msgid "Torn-off Menu" -msgstr "منوی کنده شدنی" +#~ msgid "" +#~ "The keybinding used to move a window to workspace 5. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " +#~ "is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که برای جابه‌جایی پنجره به فضای کاری ۵ به کار می‌رود؛ قالب " +#~ "آن به شکل «<Control>a» یا «<Shift><Alt>F1» است. این " +#~ "تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<" +#~ "Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی " +#~ "ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-viewer.c:395 -msgid "Border" -msgstr "کناره" +#~ msgid "" +#~ "The keybinding used to move a window to workspace 6. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " +#~ "is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که برای جابه‌جایی پنجره به فضای کاری ۶ به کار می‌رود؛ قالب " +#~ "آن به شکل «<Control>a» یا «<Shift><Alt>F1» است. این " +#~ "تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<" +#~ "Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی " +#~ "ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-viewer.c:723 -#, c-format -msgid "Button layout test %d" -msgstr "آزمایش %Id چیدمان دکمه‌ها" +#~ msgid "" +#~ "The keybinding used to move a window to workspace 7. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " +#~ "is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که برای جابه‌جایی پنجره به فضای کاری ۷ به کار می‌رود؛ قالب " +#~ "آن به شکل «<Control>a» یا «<Shift><Alt>F1» است. این " +#~ "تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<" +#~ "Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی " +#~ "ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-viewer.c:752 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%Ig میلی ثانیه برای کشیدن چارچوب یک پنجره" +#~ msgid "" +#~ "The keybinding used to move a window to workspace 8. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " +#~ "is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که برای جابه‌جایی پنجره به فضای کاری ۸ به کار می‌رود؛ قالب " +#~ "آن به شکل «<Control>a» یا «<Shift><Alt>F1» است. این " +#~ "تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<" +#~ "Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی " +#~ "ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." + +#~ msgid "" +#~ "The keybinding used to move a window to workspace 9. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " +#~ "is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که برای جابه‌جایی پنجره به فضای کاری ۹ به کار می‌رود؛ قالب " +#~ "آن به شکل «<Control>a» یا «<Shift><Alt>F1» است. این " +#~ "تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<" +#~ "Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی " +#~ "ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." + +#~ msgid "" +#~ "The keybinding used to move focus backwards between panels and the " +#~ "desktop, using a popup window. The format looks like \"<Control>a\" " +#~ "or \"<Shift><Alt>F1\". The parser is fairly liberal and " +#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" +#~ "\" and \"<Ctrl>\". If you set the option to the special string " +#~ "\"disabled\", then there will be no keybinding for this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که برای جابه‌جایی تمرکز به عقب بین تابلوها و رومیزی، با " +#~ "استفاده از یک پنجره‌ی واشو به کار می‌رود؛ قالب آن به شکل «<Control>a» " +#~ "یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و " +#~ "حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را " +#~ "قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، " +#~ "کلید مقیدی برای این کنش وجود نخواهد داشت." + +#~ msgid "" +#~ "The keybinding used to move focus backwards between panels and the " +#~ "desktop, without a popup window. The format looks like \"<Control>a" +#~ "\" or \"<Shift><Alt>F1\". The parser is fairly liberal and " +#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" +#~ "\" and \"<Ctrl>\". If you set the option to the special string " +#~ "\"disabled\", then there will be no keybinding for this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که برای جابه‌جایی تمرکز به عقب بین تابلوها و رومیزی، بدون " +#~ "استفاده از پنجره‌ی واشو به کار می‌رود؛ قالب آن به شکل «<Control>a» یا " +#~ "«<Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف " +#~ "بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول " +#~ "می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید " +#~ "مقیدی برای این کنش وجود نخواهد داشت." + +#~ msgid "" +#~ "The keybinding used to move focus backwards between windows without a " +#~ "popup window. Holding \"shift\" together with this binding makes the " +#~ "direction go forward again. The format looks like \"<Control>a\" or " +#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " +#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " +#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" +#~ "\", then there will be no keybinding for this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که برای جابه‌جایی تمرکز به عقب بین پنجره‌ها بدون استفاده از " +#~ "پنجره‌ی واشو به کار می‌رود؛ نگه داشتن «تبدیل» همراه با این کلید مقید سبب رو " +#~ "به جلو شدن جهت می‌شود. قالب آن به شکل «<Control>a» یا «<Shift>" +#~ "<Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و " +#~ "خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این " +#~ "گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این " +#~ "کنش وجود نخواهد داشت." + +#~ msgid "" +#~ "The keybinding used to move focus backwards between windows, using a " +#~ "popup window. Holding \"shift\" together with this binding makes the " +#~ "direction go forward again. The format looks like \"<Control>a\" or " +#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " +#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " +#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" +#~ "\", then there will be no keybinding for this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که برای جابه‌جایی تمرکز به عقب بین پنجره‌ها، با استفاده از " +#~ "یک پنجره‌ی واشو به کار می‌رود؛ نگه داشتن «تبدیل» همراه با این کلید مقید سبب " +#~ "رو به جلو شدن جهت می‌شود. قالب آن به شکل «<Control>a» یا «<Shift>" +#~ "<Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و " +#~ "خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این " +#~ "گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این " +#~ "کنش وجود نخواهد داشت." + +#~ msgid "" +#~ "The keybinding used to move focus between panels and the desktop, using a " +#~ "popup window. The format looks like \"<Control>a\" or \"<" +#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " +#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" +#~ "Ctrl>\". If you set the option to the special string \"disabled\", " +#~ "then there will be no keybinding for this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که برای جابه‌جایی تمرکز بین تابلوها و رومیزی، با استفاده از " +#~ "یک پنجره‌ی واشو به کار می‌رود؛ قالب آن به شکل «<Control>a» یا «<" +#~ "Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ " +#~ "یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول می‌کند. " +#~ "اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید مقیدی " +#~ "برای این کنش وجود نخواهد داشت." + +#~ msgid "" +#~ "The keybinding used to move focus between panels and the desktop, without " +#~ "a popup window. The format looks like \"<Control>a\" or \"<" +#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " +#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" +#~ "Ctrl>\". If you set the option to the special string \"disabled\", " +#~ "then there will be no keybinding for this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که برای جابه‌جایی تمرکز بین تابلوها و رومیزی، بدون استفاده " +#~ "از پنجره‌ی واشو به کار می‌رود؛ قالب آن به شکل «<Control>a» یا «<" +#~ "Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ " +#~ "یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول می‌کند. " +#~ "اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید مقیدی " +#~ "برای این کنش وجود نخواهد داشت." + +#~ msgid "" +#~ "The keybinding used to move focus between windows without a popup window. " +#~ "(Traditionally <Alt>Escape) Holding the \"shift\" key while using " +#~ "this binding reverses the direction of movement. The format looks like " +#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " +#~ "fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که برای جابه‌جایی تمرکز بین پنجره‌ها بدون استفاده از پنجره‌ی " +#~ "واشو به کار می‌رود؛ قالب آن به شکل «<Control>a» یا «<Shift><" +#~ "Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و " +#~ "خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این " +#~ "گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این " +#~ "کنش وجود نخواهد داشت." + +#~ msgid "" +#~ "The keybinding used to move focus between windows, using a popup window. " +#~ "(Traditionally <Alt>Tab) Holding the \"shift\" key while using this " +#~ "binding reverses the direction of movement. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که برای جابه‌جایی تمرکز بین پنجره‌ها با استفاده از پنجره‌ی " +#~ "واشو به کار می‌رود؛ (<Alt>Tab طبق سنت) نگهداشتن کلید «تبدیل» هنگام " +#~ "استفاده از این کلید مقید جهت حرکت را برعکس می‌کند.قالب آن به شکل «<" +#~ "Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت " +#~ "آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<" +#~ "Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» " +#~ "قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." + +#~ msgid "" +#~ "The keybinding used to toggle always on top. A window that is always on " +#~ "top will always be visible over other overlapping windows. The format " +#~ "looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " +#~ "parser is fairly liberal and allows lower or upper case, and also " +#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " +#~ "the option to the special string \"disabled\", then there will be no " +#~ "keybinding for this action." +#~ msgstr "" +#~ "مقیدسازی کلید ضامن همیشه بالا. پنجره‌ای که همیشه بالا است، روی تمام " +#~ "پنجره‌هایی که هم‌پوشانی دارند دیده خواهد شد؛ قالب آن به شکل «<Control>" +#~ "a» یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و " +#~ "حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را " +#~ "قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، " +#~ "کلید مقیدی برای این کنش وجود نخواهد داشت." + +#~ msgid "" +#~ "The keybinding used to toggle fullscreen mode. The format looks like " +#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " +#~ "fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "مقیدسازی کلید ضامن حالت تمام صفحه. قالب آن به شکل «<Control>a» یا " +#~ "«<Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف " +#~ "بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول " +#~ "می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید " +#~ "مقیدی برای این کنش وجود نخواهد داشت." + +#~ msgid "" +#~ "The keybinding used to toggle maximization. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "مقیدسازی کلید ضامن حداکثر کردن. قالب آن به شکل «<Control>a» یا «<" +#~ "Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ " +#~ "یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول می‌کند. " +#~ "اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید مقیدی " +#~ "برای این کنش وجود نخواهد داشت." + +#~ msgid "" +#~ "The keybinding used to toggle shaded/unshaded state. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " +#~ "is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "مقیدسازی کلید ضامن وضعیت سایه‌دار با بدون سایه. قالب آن به شکل «<" +#~ "Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت " +#~ "آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<" +#~ "Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» " +#~ "قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." + +#~ msgid "" +#~ "The keybinding used to toggle whether the window is on all workspaces or " +#~ "just one. The format looks like \"<Control>a\" or \"<Shift>" +#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " +#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" +#~ "\". If you set the option to the special string \"disabled\", then there " +#~ "will be no keybinding for this action." +#~ msgstr "" +#~ "مقیدسازی کلید ضامن وجود پنجره در تمام فضاهای کاری یا فقط یک فضای کاری. " +#~ "قالب آن به شکل «<Control>a» یا «<Shift><Alt>F1» است. این " +#~ "تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<" +#~ "Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی " +#~ "ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." + +#~ msgid "" +#~ "The keybinding used to unmaximize a window. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که برای ناحداکثر کردن پنجره به کار می‌رود. قالب آن به شکل " +#~ "«<Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت " +#~ "آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<" +#~ "Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» " +#~ "قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." + +#~ msgid "" +#~ "The keybinding which display's the panel's \"Run Application\" dialog " +#~ "box. The format looks like \"<Control>a\" or \"<Shift><" +#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, " +#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If " +#~ "you set the option to the special string \"disabled\", then there will be " +#~ "no keybinding for this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که جعبه‌ی محاوره‌ی «اجرای برنامه»ی تابلو را نمایش می‌دهد؛ قالب " +#~ "آن به شکل «<Control>a» یا «<Shift><Alt>F1» است. این " +#~ "تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<" +#~ "Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی " +#~ "ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." + +#~ msgid "" +#~ "The keybinding which invokes a terminal. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که یک پایانه احضار می‌کند؛ قالب آن به شکل «<Control>a» " +#~ "یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و " +#~ "حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را " +#~ "قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، " +#~ "کلید مقیدی برای این کنش وجود نخواهد داشت." + +#~ msgid "" +#~ "The keybinding which invokes the panel's screenshot utility to take a " +#~ "screenshot of a window. The format looks like \"<Control>a\" or " +#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " +#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " +#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" +#~ "\", then there will be no keybinding for this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که برنامه‌ی عکس از صفحه را احضار می‌کند تا یک عکس از صفحه‌ی " +#~ "پنجره بگیرد؛ قالب آن به شکل «<Control>a» یا «<Shift><Alt>" +#~ "F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه " +#~ "کردن به شکل «<Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه " +#~ "را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود " +#~ "نخواهد داشت." + +#~ msgid "" +#~ "The keybinding which invokes the panel's screenshot utility. The format " +#~ "looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " +#~ "parser is fairly liberal and allows lower or upper case, and also " +#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " +#~ "the option to the special string \"disabled\", then there will be no " +#~ "keybinding for this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که برنامه‌ی عکس از صفحه را احضار می‌کند؛ قالب آن به شکل «<" +#~ "Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت " +#~ "آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<" +#~ "Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» " +#~ "قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." + +#~ msgid "" +#~ "The keybinding which shows the panel's main menu. The format looks like " +#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " +#~ "fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "مقیدسازی کلیدی که منوی اصلی تابلو را نشان می‌دهد؛ قالب آن به شکل «<" +#~ "Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت " +#~ "آسان‌گیر است و حروف بزرگ یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<" +#~ "Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» " +#~ "قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-viewer.c:795 -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "کاربرد: metacity-theme-viewer [THEMENAME]\n" +#~ msgid "The name of a workspace." +#~ msgstr "نام فضای کاری." -#: ../src/theme-viewer.c:802 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "خطا در بارگذاری تم : %s\n" +#~ msgid "The screenshot command" +#~ msgstr "فرمان عکس از صفحه" -#: ../src/theme-viewer.c:808 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "تم‌ «%s» در %Ig ثانیه بارشد\n" +#~ msgid "" +#~ "The theme determines the appearance of window borders, titlebar, and so " +#~ "forth." +#~ msgstr "" +#~ "تم، قیافه‌ی کناره‌ی پنجره‌ها، نوار عنوان و چیزهایی از این دست را تعیین می‌کند." -#: ../src/theme-viewer.c:831 -msgid "Normal Title Font" -msgstr "قلم عنوان عادی" +#~ msgid "" +#~ "The time delay before raising a window if auto_raise is set to true. The " +#~ "delay is given in thousandths of a second." +#~ msgstr "" +#~ "تأخیر زمانی قبل از پیش کشیدن پنجره در صورتی که auto_raise روی درست تنظیم " +#~ "شده باشد. تأخیر به هزارم ثانیه داده شده است." -#: ../src/theme-viewer.c:837 -msgid "Small Title Font" -msgstr "قلم عنوان ریز" +#~ msgid "" +#~ "The window focus mode indicates how windows are activated. It has three " +#~ "possible values; \"click\" means windows must be clicked in order to " +#~ "focus them, \"sloppy\" means windows are focused when the mouse enters " +#~ "the window, and \"mouse\" means windows are focused when the mouse enters " +#~ "the window and unfocused when the mouse leaves the window." +#~ msgstr "" +#~ "حالت تمرکز پنجره نحوه‌ی فعال‌سازی پنجره‌ها را نشان می‌دهد. سه مقدار می‌تواند " +#~ "بگیرد؛ «click» یعنی برای تمرکز روی پنجره‌ها رویشان کلیک شود، «sloppy» یعنی " +#~ "وقتی موشی وارد پنجره‌ای شد تمرکز روی آن پنجره قرار بگیرد و «mouse» یعنی " +#~ "وقتی موشی وارد پنجره‌ای شد تمرکز روی آن قرار بگیرد و وقتی خارج شد تمرکز از " +#~ "روی آن برداشته شود." -#: ../src/theme-viewer.c:843 -msgid "Large Title Font" -msgstr "قلم عنوان درشت" +#~ msgid "The window screenshot command" +#~ msgstr "فرمان عکس از صفحه‌ی پنجره" -#: ../src/theme-viewer.c:848 -msgid "Button Layouts" -msgstr "چیدمان‌های دکمه‌ها" +#~ msgid "" +#~ "This keybinding changes whether a window is above or below other windows. " +#~ "If the window is covered by another window, it raises the window above " +#~ "other windows. If the window is already fully visible, it lowers the " +#~ "window below other windows. The format looks like \"<Control>a\" or " +#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " +#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " +#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" +#~ "\", then there will be no keybinding for this action." +#~ msgstr "" +#~ "این کلید مقید زیر یا رو بودن یک پنجره را نسبت به بقیه پنجره‌ها تغییر " +#~ "می‌دهد. اگر پنجره با پنجره‌ی دیگری پوشیده شده باشد، آن را پیش می‌آورد. اگر " +#~ "پنجره به طور کامل دیده شود، آن را زیر پنجره‌های دیگر قرار می‌دهد. قالب آن " +#~ "به شکل «<Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر " +#~ "به نسبت آسان‌گیر است و حروف بزرگ یا کوچک یا خلاصه کردن به شکل «<Ctl>» " +#~ "و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی " +#~ "«disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-viewer.c:853 -msgid "Benchmark" -msgstr "آزمایش محک" +#~ msgid "" +#~ "This keybinding lowers a window below other windows. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " +#~ "is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "این کلید مقید یک پنجره را زیر پنجره‌های دیگر قرار می‌دهد. قالب آن به شکل " +#~ "«<Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت " +#~ "آسان‌گیر است و حروف بزرگ یا کوچک یا خلاصه کردن به شکل «<Ctl>» و «<" +#~ "Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» " +#~ "قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-viewer.c:900 -msgid "Window Title Goes Here" -msgstr "عنوان پنجره اینجا قرار می‌گیرد" +#~ msgid "" +#~ "This keybinding raises the window above other windows. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " +#~ "is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "این کلید مقید یک پنجره را روی پنجره‌های دیگر پیش می‌آورد. قالب آن به شکل " +#~ "«<Control>a» یا «<Shift><Alt>F1» است. این تجزیه‌گر به نسبت " +#~ "آسان‌گیر است و حروف بزرگ یا کوچک یا خلاصه کردن به شکل «<Ctl>» و «<" +#~ "Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» " +#~ "قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-viewer.c:1004 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"%Id چارچوب در %Ig ثانیه‌ی سمت مخدوم (%Ig میلی ثانیه برای هر چارچوب) و %Ig " -"ثانیه‌ی ساعت دیواری شامل منابع خادم X (%Ig میلی ثانیه برای هر چارچوب)\n" +#~ msgid "" +#~ "This keybinding resizes a window to fill available horizontal space. The " +#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " +#~ "The parser is fairly liberal and allows lower or upper case, and also " +#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " +#~ "the option to the special string \"disabled\", then there will be no " +#~ "keybinding for this action." +#~ msgstr "" +#~ "این کلید مقید اندازه‌ی یک پنجره را تغییر می‌دهد تا فضای افقی موجود را پر " +#~ "کند. قالب آن به شکل «<Control>a» یا «<Shift><Alt>F1» است. " +#~ "این تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک یا خلاصه کردن به شکل " +#~ "«<Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با " +#~ "رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-viewer.c:1219 -msgid "position expression test returned TRUE but set error" -msgstr "آزمایش عبارت وضعیت، درست بازگرداند ولی خطا تنظیم کرد" +#~ msgid "" +#~ "This keybinding resizes a window to fill available vertical space. The " +#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " +#~ "The parser is fairly liberal and allows lower or upper case, and also " +#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " +#~ "the option to the special string \"disabled\", then there will be no " +#~ "keybinding for this action." +#~ msgstr "" +#~ "این کلید مقید اندازه‌ی یک پنجره را تغییر می‌دهد تا فضای عمودی موجود را پر " +#~ "کند. قالب آن به شکل «<Control>a» یا «<Shift><Alt>F1» است. " +#~ "این تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ یا کوچک یا خلاصه کردن به شکل " +#~ "«<Ctl>» و «<Ctrl>» را قبول می‌کند. اگر این گزینه را برابر با " +#~ "رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید مقیدی برای این کنش وجود نخواهد داشت." -#: ../src/theme-viewer.c:1221 -msgid "position expression test returned FALSE but didn't set error" -msgstr "آزمایش عبارت وضعیت، نادرست بازگرداند ولی خطایی تنظیم نکرد" +#~ msgid "" +#~ "This option determines the effects of double-clicking on the title bar. " +#~ "Current valid options are 'toggle_shade', which will shade/unshade the " +#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " +#~ "'minimize' which will minimize the window, and 'none' which will not do " +#~ "anything." +#~ msgstr "" +#~ "این گزینه تأثیر دوبار کلیک روی نوار عنوان را تعیین می‌کند. گزینه‌های معتبر " +#~ "فعلی عبارتند از «toggle_shade» که پنجره را سایه خورده یا بدون سایه می‌کند، " +#~ "«toggle_maximize» که پنجره را حداکثر یا ناحداکثر می‌کند، «minimize»که پنجره " +#~ "را حداقل می‌کند، و «none» که کاری انجام نمی‌دهد." -#: ../src/theme-viewer.c:1225 -msgid "Error was expected but none given" -msgstr "انتظار خطا می‌رفت ولی خطایی مشاهده نشد" +#~ msgid "Toggle always on top state" +#~ msgstr "ضامن همیشه در وضعیت بالایی" -#: ../src/theme-viewer.c:1227 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "انتظار خطای %Id می‌رفت ولی خطای %Id مشاهده شد" +#~ msgid "Toggle window on all workspaces" +#~ msgstr "ضامن پنجره در تمام فضاهای کاری" -#: ../src/theme-viewer.c:1233 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "انتظار خطا نمی‌رفت ولی خطایی برگردانده شد: %s" +#~ msgid "" +#~ "Turns on a visual indication when an application or the system issues a " +#~ "'bell' or 'beep'; useful for the hard-of-hearing and for use in noisy " +#~ "environments, or when 'audible bell' is off." +#~ msgstr "" +#~ "هنگامی که یک برنامه یا سیستم «زنگ»‌ یا «بوق» می‌زند، یک شاخص تصویری را روشن " +#~ "می‌کند: مفید برای گوش‌های سنگین و برای استفاده در محیط‌های پر سر و صدا یا " +#~ "زمانی که «زنگ شنیداری» خاموش است." -#: ../src/theme-viewer.c:1237 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "مقدار x %Id بود، %Id انتظار می‌رفت" +#~ msgid "Unmaximize window" +#~ msgstr "ناحداکثر کردن پنجره" -#: ../src/theme-viewer.c:1240 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "مقدار y %Id بود، %Id انتظار می‌رفت" +#~ msgid "Use standard system font in window titles" +#~ msgstr "استفاده از قلم استاندارد سیستم در عنوان پنجره‌ها" -#: ../src/theme-viewer.c:1303 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "%Id عبارت مختصاتی در %Ig ثانیه تجزیه شد (متوسط %Ig ثانیه)\n" +#~ msgid "Visual Bell Type" +#~ msgstr "نوع زنگ دیداری" -#: ../src/theme.c:202 -msgid "top" -msgstr "بالا" +#~ msgid "Window focus mode" +#~ msgstr "حالت تمرکز پنجره" -#: ../src/theme.c:204 -msgid "bottom" -msgstr "پایین" +#~ msgid "Window title font" +#~ msgstr "قلم عنوان پنجره" -#: ../src/theme.c:206 -msgid "left" -msgstr "چپ" +#~ msgid "GConf key \"%s\" is set to an invalid type\n" +#~ msgstr "کلید «%s» GConf از نوع نامعتبری تنظیم شده است\n" -#: ../src/theme.c:208 -msgid "right" -msgstr "راست" +#~ msgid "GConf key '%s' is set to an invalid value\n" +#~ msgstr "کلید «%s» GCon به مقدار نامعتبری تنظیم شده است\n" -#: ../src/theme.c:222 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "پیکربندی ظاهری چارچوب بعد «%s» را مشخص نمی‌کند" +#~ msgid "" +#~ "%d stored in GConf key %s is not a reasonable cursor_size; must be in the " +#~ "range 1..128\n" +#~ msgstr "" +#~ "%Id ذخیره شده در کلید %s GConf عدد معقولی برای اندازه‌ی مکان‌نما نیست؛ باید " +#~ "در محدوده‌ی ۱ تا ۱۲۸ باشد\n" -#: ../src/theme.c:241 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "پیکربندی ظاهری چارچوب بعد «%s» را برای کناره‌ی «%s» مشخص نمی‌کند" +#~ msgid "" +#~ "%d stored in GConf key %s is not a reasonable number of workspaces, " +#~ "current maximum is %d\n" +#~ msgstr "" +#~ "%Id ذخیره شده در کلید %s GConf عدد معقولی برای تعداد فضاهای کاری نیست، " +#~ "حداکثر فعلی %Id است\n" -#: ../src/theme.c:278 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "%Ig به عنوان نسبت طول به عرض دکمه معقول نیست" +#~ msgid "%d stored in GConf key %s is out of range 0 to %d\n" +#~ msgstr "%Id ذخیره شده در کلید GConf %s خارج از محدوده‌ی ۰ تا %Id است\n" -#: ../src/theme.c:290 -msgid "Frame geometry does not specify size of buttons" -msgstr "پیکربندی ظاهری چارچوب اندازه‌ی دکمه‌ها را مشخص نمی‌کند" +#~ msgid "Error setting number of workspaces to %d: %s\n" +#~ msgstr "خطای تنظیم تعداد فضاهای کاری به %Id: %s\n" -#: ../src/theme.c:842 -msgid "Gradients should have at least two colors" -msgstr "شیب‌ها باید حداقل دو رنگ داشته باشند" +#~ msgid "Error setting name for workspace %d to \"%s\": %s\n" +#~ msgstr "خطای تنظیم نام فضای کاری %Id به \"%s\": %s\n" -#: ../src/theme.c:968 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"وضعیت در مشخصه‌ی رنگ GTK باید داخل قلاب نوشته شود، به طور مثال gtk:fg[NORMAL] " -"که NORMAL وضعیت است: »%s» قابل تجزیه نیست" +#~ msgid "Failed to read saved session file %s: %s\n" +#~ msgstr "شکست در خواندن پرونده‌ی نشست ذخیره شده %s: %s\n" -#: ../src/theme.c:982 -#, c-format -msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"در مشخصه‌ی رنگ GTK باید بعد از وضعیت، قلاب بسته داشته باشد، به طور مثال gtk:fg" -"[NORMAL] که NORMAL وضعیت است: »%s» قابل تجزیه نیست" +#~ msgid "Unknown attribute %s on <metacity_session> element" +#~ msgstr "مشخصه‌ی %s روی عنصر <metacity_session> نامعلوم است" -#: ../src/theme.c:993 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "وضعیت «%s» در مشخصه‌ی رنگ قابل درک نیست" +#~ msgid "Unknown attribute %s on <maximized> element" +#~ msgstr "مشخصه‌ی ‌%s روی عنصر <maximized> نامعلوم است" -#: ../src/theme.c:1006 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "مؤلفه‌ی «%s» در مشخصه‌ی رنگ قابل درک نیست" +#~ msgid "Unknown attribute %s on <geometry> element" +#~ msgstr "مشخصه‌ی ‌%s روی عنصر <geometry> نامعلوم است" -#: ../src/theme.c:1036 -#, c-format -msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" -msgstr "" -"قالب ترکیب «blend/bg_color/fg_color/alpha» است، «%s» در قالب اندازه نمی‌شود" +#~ msgid "" +#~ "Error launching metacity-dialog to warn about apps that don't support " +#~ "session management: %s\n" +#~ msgstr "" +#~ "خطا در راه‌اندازی metacity-dialog برای هشدار در مورد برنامه‌هایی که مدیریت " +#~ "نشست را پشتیبانی نمی‌کنند: %s\n" -#: ../src/theme.c:1047 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "ارزش آلفای «%s» در رنگ ترکیب شده قابل تجزیه نیست" +#~ msgid "No \"%s\" attribute on <%s> element" +#~ msgstr "عنصر <%2$s> مشخصه‌ی «%1$s» ندارد" -#: ../src/theme.c:1057 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "ارزش آلفای «%s» در رنگ ترکیب شده بین ۰٫۰ و ۱٫۰ نیست" +#~ msgid "Unknown function \"%s\" for menu icon" +#~ msgstr "تابع «%s» برای شمایل منو نامعلوم است" -#: ../src/theme.c:1104 -#, c-format -msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "قالب سایه «shade/base_color/factor» است، «%s» در قالب اندازه نمی‌شود" +#~ msgid "Unknown state \"%s\" for menu icon" +#~ msgstr "وضعیت «%s» برای شمایل منو نامعلوم است" -#: ../src/theme.c:1115 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "‌عامل سایه‌ی «%s» در رنگ سایه خورده قابل تجزیه نیست" +#~ msgid "Theme already has a menu icon for function %s state %s" +#~ msgstr "تم در حال حاضر برای تابع %s وضعیت %s شمایل منو دارد" -#: ../src/theme.c:1125 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "عامل سایه‌ی «%s» در رنگ سایه خورده منفی است" +#~ msgid "No \"name\" attribute on element <%s>" +#~ msgstr "عنصر <%s> مشخصه‌ی «name» ندارد" -#: ../src/theme.c:1154 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "رنگ «%s» قابل تجزیه نیست" +#~ msgid "No \"value\" attribute on element <%s>" +#~ msgstr "عنصر <%s> مشخصه‌ی «value» ندارد" -#: ../src/theme.c:1416 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "عبارت مختصاتی شامل نویسه‌ی «%s» است که جایز نیست" +#~ msgid "No \"top\" attribute on element <%s>" +#~ msgstr "عنصر <%s> مشخصه‌ی «top» ندارد" -#: ../src/theme.c:1443 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "عبارت مختصاتی شامل عدد اعشار ممیز شناور «%s» است که قابل تجزیه نیست" +#~ msgid "No \"bottom\" attribute on element <%s>" +#~ msgstr "عنصر <%s> مشخصه‌ی «bottom» ندارد" -#: ../src/theme.c:1457 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "عبارت مختصاتی شامل عددصحیح «%s» است که قابل تجزیه نیست" +#~ msgid "No \"left\" attribute on element <%s>" +#~ msgstr "عنصر <%s> مشخصه‌ی «left» ندارد" -#: ../src/theme.c:1524 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "عبارت مختصاتی شامل عملگر نامعلومی در ابتدای متن است: «%s»" +#~ msgid "No \"right\" attribute on element <%s>" +#~ msgstr "عنصر <%s> مشخصه‌ی «right» ندارد" -#: ../src/theme.c:1581 -msgid "Coordinate expression was empty or not understood" -msgstr "عبارت مختصاتی خالی بود یا قابل درک نبود" +#~ msgid "No \"color\" attribute on element <%s>" +#~ msgstr "عنصر <%s> مشخصه‌ی «color» ندارد" -#: ../src/theme.c:1724 ../src/theme.c:1734 ../src/theme.c:1768 -msgid "Coordinate expression results in division by zero" -msgstr "عبارت مختصاتی موجب تقسیم به صفر می‌شود" +#~ msgid "No \"x1\" attribute on element <%s>" +#~ msgstr "عنصر <%s> مشخصه‌ی «x1» ندارد" -#: ../src/theme.c:1776 -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "" -"عبارت مختصاتی سعی دارد از عملگر باقی مانده روی عدد اعشاری ممیز شناوری استفاد " -"کند" +#~ msgid "No \"y1\" attribute on element <%s>" +#~ msgstr "عنصر <%s> مشخصه‌ی «y1» ندارد" -#: ../src/theme.c:1832 -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr " عبارت مختصاتی در جایی که انتظار عملوند می‌رفت، عملگر«%s» داشت" +#~ msgid "No \"x2\" attribute on element <%s>" +#~ msgstr "عنصر <%s> مشخصه‌ی «x2» ندارد" -#: ../src/theme.c:1841 -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "عبارت مختصاتی در جایی که انتظار عملگر " +#~ msgid "No \"y2\" attribute on element <%s>" +#~ msgstr "عنصر <%s> مشخصه‌ی «y2» ندارد" -#: ../src/theme.c:1849 -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "عبارت مختصاتی به جای عملوند با عملگر تمام می‌شود" +#~ msgid "No \"x\" attribute on element <%s>" +#~ msgstr "عنصر <%s> مشخصه‌ی «x» ندارد" -#: ../src/theme.c:1859 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" -"در عبارت مختصاتی، عملگر «%c» بدون هیچ عملوندی به دنبال عملگر «%c» آمده است" +#~ msgid "No \"y\" attribute on element <%s>" +#~ msgstr "عنصر <%s> مشخصه‌ی «y» ندارد" -#: ../src/theme.c:1978 -msgid "" -"Coordinate expression parser overflowed its buffer, this is really a " -"Metacity bug, but are you sure you need a huge expression like that?" -msgstr "" -"تجزیه‌گر عبارت مختصاتی میانگیرش را سریز کرد، این واقعاً اشکال متاسیتی است، اما " -"شما مطمئنید که به چنین عبارت بزرگی نیاز دارید؟" +#~ msgid "No \"width\" attribute on element <%s>" +#~ msgstr "عنصر <%s> مشخصه‌ی «width» ندارد" -#: ../src/theme.c:2007 -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "عبارت مختصاتی پرانتر بسته‌ای دارد که پرانتز باز ندارد" +#~ msgid "No \"height\" attribute on element <%s>" +#~ msgstr "عنصر <%s> مشخصه‌ی «height» ندارد" -#: ../src/theme.c:2069 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "عبارت مختصاتی متغییر یا ثابت «%s» نامعلوم دارد" +#~ msgid "No \"alpha\" attribute on element <%s>" +#~ msgstr "عنصر <%s> مشخصه‌ی «alpha» ندارد" -#: ../src/theme.c:2126 -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "عبارت مختصاتی پرانتر بازی دارد که پرانتز بسته ندارد" +#~ msgid "No \"type\" attribute on element <%s>" +#~ msgstr "عنصر <%s> مشخصه‌ی «type» ندارد" -#: ../src/theme.c:2137 -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "به نظر نمی‌رسد که عبارت مختصاتی عملگر یا عملوندی داشته باشد" +#~ msgid "No \"filename\" attribute on element <%s>" +#~ msgstr "عنصر <%s> مشخصه‌ی «filename» ندارد" -#: ../src/theme.c:2381 ../src/theme.c:2403 ../src/theme.c:2424 -#, c-format -msgid "Theme contained an expression \"%s\" that resulted in an error: %s\n" -msgstr "تم شامل عبارت «%s» است که منجر به خطا می‌شود: %s\n" +#~ msgid "No \"state\" attribute on element <%s>" +#~ msgstr "عنصر <%s> مشخصه‌ی «state» ندارد" -#: ../src/theme.c:3910 -#, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/>باید برای این " -"سبک چارچوب مشخص شود" +#~ msgid "No \"shadow\" attribute on element <%s>" +#~ msgstr "عنصر <%s> مشخصه‌ی «shadow» ندارد" -#: ../src/theme.c:4360 ../src/theme.c:4392 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" -"<frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/> نبود" +#~ msgid "No \"arrow\" attribute on element <%s>" +#~ msgstr "عنصر <%s> مشخصه‌ی «arrow» ندارد" -#: ../src/theme.c:4443 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "شکست در بارکردن تم «%s»: %s\n" +#~ msgid "No \"value\" attribute on <%s> element" +#~ msgstr "عنصر <%s> مشخصه‌ی «value» ندارد" -#: ../src/theme.c:4597 ../src/theme.c:4604 ../src/theme.c:4611 -#: ../src/theme.c:4618 ../src/theme.c:4625 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "<%s> برای تم «%s» تنظیم نشده است" +#~ msgid "No \"position\" attribute on <%s> element" +#~ msgstr "عنصر <%s> مشخصه‌ی «position» ندارد" -#: ../src/theme.c:4635 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" -"سبک جارچوب برای نوع پنجره «%s» در تم «%s» تنظیم نشده است، یک عنصر <window " -"type=\"%s\" style_set=\"whatever\"/> اضافه کنید" +#~ msgid "No \"function\" attribute on <%s> element" +#~ msgstr "عنصر <%s> مشخصه‌ی «function» ندارد" -#: ../src/theme.c:4657 -#, c-format -msgid "" -"<menu_icon function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this theme" -msgstr "" -"<menu_icon function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> باید برای " -"این تم مشخص شود " +#~ msgid "No \"state\" attribute on <%s> element" +#~ msgstr "عنصر <%s> مشخصه‌ی «state» ندارد" -#: ../src/theme.c:5046 ../src/theme.c:5108 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" -"ثابت‌هایی که کاربر تعریف کرده اسن باید با حروف بزرگ شروع شوند؛ «%s» این طور " -"نیست " +#~ msgid "No \"focus\" attribute on <%s> element" +#~ msgstr "عنصر <%s> مشخصه‌ی «focus» ندارد" -#: ../src/theme.c:5054 ../src/theme.c:5116 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "ثابت «%s» قبلاً تعریف شده است" +#~ msgid "No \"style\" attribute on <%s> element" +#~ msgstr "عنصر <%s> مشخصه‌ی «style» ندارد" -#: ../src/util.c:96 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "شکست در بازکردن ثبت وقایع اشکال‌زدایی: %s\n" +#~ msgid "No \"resize\" attribute on <%s> element" +#~ msgstr "عنصر <%s> مشخصه‌ی «resize» ندارد" -#: ../src/util.c:106 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "شکست در انجام fdopen() پرونده‌ی ثبتی %s: %s\n" +#~ msgid "No draw_ops provided for menu icon" +#~ msgstr "draw_ops برای شمایل منو منظور نشده است" -#: ../src/util.c:112 -#, c-format -msgid "Opened log file %s\n" -msgstr "پرونده‌ی ثبتی %s باز شد\n" +#~ msgid "<author> specified twice for this theme" +#~ msgstr "<author> دو بار برای این تم مشخص شده است" -#: ../src/util.c:220 -msgid "Window manager: " -msgstr "مدیر پنجره‌ها: " +#~ msgid "<copyright> specified twice for this theme" +#~ msgstr "<copyright> دو بار برای این تم مشخص شده است" -#: ../src/util.c:366 -msgid "Bug in window manager: " -msgstr "اشکال در مدیر پنجره‌ها: " +#~ msgid "<date> specified twice for this theme" +#~ msgstr "<date> دو بار برای این تم مشخص شده است" -#: ../src/util.c:395 -msgid "Window manager warning: " -msgstr "هشدار مدیر پنجره‌ها: " +#~ msgid "<description> specified twice for this theme" +#~ msgstr "<description> دو بار برای این تم مشخص شده است" -#: ../src/util.c:419 -msgid "Window manager error: " -msgstr "خطای مدیر پنجره‌ها: " +#~ msgid "Failed to read theme from file %s: %s\n" +#~ msgstr "شکست در خواندن تم از پرونده‌ی %s: %s\n" -#: ../src/window-props.c:169 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "برنامه _NET_WM_PID %Ilu جعلی تنظیم کرده است\n" +#~ msgid "Theme file %s did not contain a root <metacity_theme> element" +#~ msgstr "پرونده‌ی تم %s شامل یک عنصر <metacity_theme> شاخه نیست" -#. first time through -#: ../src/window.c:5409 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"پنجره %s به جای تنظیم SM_CLIENT_ID روی پنجره‌ی WM_CLIENT_LEADER طبق ICCCM " -"آن را روی خودش تنظیم کرده است.\n" +#~ msgid "/Windows/tearoff" +#~ msgstr "پنجره‌ها/کنده‌شدنی" -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/window.c:6028 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %" -"d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"پنجره‌ی %s یک راهنمای MWM تنظیم می‌کند که نشان می‌دهد امکان تغییر اندازه ندارد، " -"اما اندازه‌ی حداقل را %Id × %Id و اندازه‌ی حداکثر را %Id × %Id تنظیم می‌کند؛ " -"این منطقی نیست.\n" +#~ msgid "/Windows/_Dialog" +#~ msgstr "/پنجره‌ها/محاوره" -#: ../src/xprops.c:153 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"پنجره‌ی 0x%lx ویژگی %s را دارد که \n" -"انتظار می‌رفت از نوع %s قالب %Id باشد\n" -"اما از نوع %s قالب %Id n_items %Id بود.\n" -"این به احتمال زیاد اشکال برنامه است نه اشکال مدیر پنجره‌ها.\n" -"در این پنجره title=«%s» class=«%s» name=«%s» است\n" +#~ msgid "/Windows/_Modal dialog" +#~ msgstr "پنجره‌ها/محاوره‌ی وجهی" -#: ../src/xprops.c:399 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "ویژگی %s روی پنجره‌ی 0x%lx UTf-8 نامعتبر دارد\n" +#~ msgid "" +#~ "Coordinate expression parser overflowed its buffer, this is really a " +#~ "Metacity bug, but are you sure you need a huge expression like that?" +#~ msgstr "" +#~ "تجزیه‌گر عبارت مختصاتی میانگیرش را سریز کرد، این واقعاً اشکال متاسیتی است، " +#~ "اما شما مطمئنید که به چنین عبارت بزرگی نیاز دارید؟" -#: ../src/xprops.c:482 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "ویژگی %s روی پنجره‌ی 0x%lx برای مورد %Id در فهرست، UTf-8 نامعتبر دارد\n" +#~ msgid "" +#~ "<menu_icon function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " +#~ "specified for this theme" +#~ msgstr "" +#~ "<menu_icon function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> باید برای " +#~ "این تم مشخص شود " #~ msgid "" #~ "If true, and the focus mode is either \"sloppy\" or \"mouse\" then the " @@ -3228,9 +3382,6 @@ msgstr "ویژگی %s روی پنجره‌ی 0x%lx برای مورد %Id در ف #~ "مقیدسازی کلیدی که فرمان correspondingly-numbered را در ‎/appsmetacity/" #~ "keybinding_commands اجرا می‌کند: قالب آن به شکل«<Control>a» یا «<" #~ "Shift><Alt>F1» است. این تجزیه‌گر به نسبت آسان‌گیر است و حروف بزرگ " -#~ "یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول " -#~ "می‌کند. اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید " -#~ "مقیدی برای این کنش وجود نخواهد داشت." - -#~ msgid "No \"%s\" attribute on element <%s>" -#~ msgstr "عنصر <%2$s> مشخصه‌ی «%1$s» ندارد" +#~ "یا کوچک و خلاصه کردن به شکل «<Ctl>» و «<Ctrl>» را قبول می‌کند. " +#~ "اگر این گزینه را برابر با رشته‌ی ویژه‌ی «disabled» قرار دهید، کلید مقیدی " +#~ "برای این کنش وجود نخواهد داشت." diff --git a/po/fi.po b/po/fi.po index b5f0aa7cd..142234d12 100644 --- a/po/fi.po +++ b/po/fi.po @@ -2,1397 +2,1199 @@ # Suomennos: http://gnome-fi.sourceforge.net/ # # Copyright (C) 2003 Free Software Foundation, Inc. -# Pauli Virtanen <pauli.virtanen@hut.fi>, 2003-2005. # Ilkka Tuohela <hile@iki.fi> 2005-2008. -# Tommi Vainikainen <thv@iki.fi>, 2011. # # Gnome 2012-03 Finnish translation sprint participants: -# Jiri Grönroos +# Pauli Virtanen <pauli.virtanen@hut.fi>, 2003-2005. +# Tommi Vainikainen <thv@iki.fi>, 2011. +# Jiri Grönroos <jiri.gronroos+l10n@iki.fi>, 2012, 2013, 2014, 2015. +# msgid "" msgstr "" -"" -"Project-Id-Version: muffin\n" -"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=muffin&keywords=I18N+L10N&component=general\n" -"POT-Creation-Date: 2011-12-13 13:41+0000\n" -"PO-Revision-Date: 2012-03-12 09:05:10+0000\n" -"Last-Translator: Tommi Vainikainen <thv@iki.fi>\n" -"Language-Team: Finnish <gnome-fi-laatu@lists.sourceforge.net>\n" +"Project-Id-Version: mutter\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2019-02-04 17:52+0000\n" +"PO-Revision-Date: 2019-02-09 11:02+0200\n" +"Last-Translator: Jiri Grönroos <jiri.gronroos+l10n@iki.fi>\n" +"Language-Team: suomi <gnome-fi-laatu@lists.sourceforge.net>\n" +"Language: fi\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Language: fi\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-POT-Import-Date: 2012-02-19 15:25:23+0000\n" -"X-Generator: MediaWiki 1.20alpha (r113129); Translate 2012-03-02\n" - -#: ../src/50-muffin-windows.xml.in.h:1 -msgid "Windows" -msgstr "Ikkunat" - -#: ../src/50-muffin-windows.xml.in.h:2 -msgid "View split on left" -msgstr "" - -#: ../src/50-muffin-windows.xml.in.h:3 -msgid "View split on right" -msgstr "" - -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format -msgid "Another compositing manager is already running on screen %i on display \"%s\"." -msgstr "Näytön ”%2$s” ruudullä %1$d on jo käynnissä toinen ikkunoidenladontaohjelman." - -#: ../src/core/bell.c:307 -msgid "Bell event" -msgstr "Äänimerkki" +"X-Generator: Poedit 2.0.6\n" -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Tuntematon ikkunatietojen pyyntö: %d" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Navigointi" -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> ei vastaa." +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Siirrä ikkuna työtilaan 1" -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "Sovellus ei vastaa." +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Siirrä ikkuna työtilaan 2" -#: ../src/core/delete.c:119 -msgid "You may choose to wait a short while for it to continue or force the application to quit entirely." -msgstr "Voit odottaa sovellusta vielä hetken tai sulkea sovelluksen väkisin heti." +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Siirrä ikkuna työtilaan 3" -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "_Odota" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Siirrä ikkuna työtilaan 4" -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "Sulje _väkisin" +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Siirrä ikkuna viimeiseen työtilaan" -#: ../src/core/display.c:361 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "Kerrostukseen vaadittava laajennos %s puuttuu" +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "Siirrä ikkunaa yksi työtila ylös" -#: ../src/core/display.c:427 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "X-ikkunointijärjestelmän näytön ”%s” avaaminen epäonnistui\n" +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "Siirrä ikkunaa yksi työtila alas" -#: ../src/core/keybindings.c:852 -#, c-format -msgid "Some other program is already using the key %s with modifiers %x as a binding\n" -msgstr "Jokin muu ohjelma käyttää jo näppäintä %s muunnoksin %x pikanäppäimenään\n" +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "Siirrä ikkuna yhden näytön verran vasemmalle" -#: ../src/core/main.c:206 -msgid "Disable connection to session manager" -msgstr "Estä yhteys sessionhallintaan" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "Siirrä ikkuna yhden näytön verran oikealle" -#: ../src/core/main.c:212 -msgid "Replace the running window manager" -msgstr "Vaihda käytössä oleva ikkunanhallinta" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "Siirrä ikkuna yhden näytön verran ylös" -#: ../src/core/main.c:218 -msgid "Specify session management ID" -msgstr "Anna sessionhallinnan ID" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "Siirrä ikkuna yhden näytön verran alas" -#: ../src/core/main.c:223 -msgid "X Display to use" -msgstr "Käytettävä X-näyttö" +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "Vaihda sovelluksia" -#: ../src/core/main.c:229 -msgid "Initialize session from savefile" -msgstr "Alusta sessio tiedostosta" +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "Vaihda edelliseen sovellukseen" -#: ../src/core/main.c:235 -msgid "Make X calls synchronous" -msgstr "Käytä synkronisia X-kutsuja" +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "Vaihda ikkunoita" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Teemakansion lukeminen epäonnistui: %s\n" +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "Vaihda edelliseen ikkunaan" -#: ../src/core/main.c:520 -#, c-format -msgid "Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "Teemaa ei löydy! Varmista, että %s on olemassa, ja sisältää tavalliset teemat.\n" +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "Vaihda sovelluksen ikkunoiden välillä" -#: ../src/core/muffin.c:40 -#, c-format -msgid "muffin %s\nCopyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\nThis is free software; see the source for copying conditions.\nThere is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" -msgstr "muffin %s\nTekijänoikeudet © 2001-%d Havoc Pennington, Red Hat, Inc., ja muut.\nTämä on vapaata ohjelmistoa: katso kopiointiehdot lähdekoodista.\nEi MINKÄÄNLAISTA takuuta: ei edes takuuta MYYNTIKELPOISUUDESTA tai\nSOPIVUUDESTA JOHONKIN KÄYTTÖÖN.\n" +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "Vaihda sovelluksen edelliseen ikkunaan" -#: ../src/core/muffin.c:54 -msgid "Print version" -msgstr "Näytä versio" +#: data/50-mutter-navigation.xml:70 +#, fuzzy +msgid "Switch system controls" +msgstr "Vaihda järjestelmän kontrolleja" -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "Pilkuilla eroteltu luettelo ladontaohjelman liitännäisistä" +#: data/50-mutter-navigation.xml:75 +#, fuzzy +msgid "Switch to previous system control" +msgstr "Vaihda järjestelmän kontrolleja" -#: ../src/core/prefs.c:1069 -msgid "Workarounds for broken applications disabled. Some applications may not behave properly.\n" -msgstr "Rikkinäisten sovellusten kiertotiet eivät ole käytössä. Jotkin sovellukset eivät välttämättä käyttäydy kunnolla.\n" +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "Vaihda ikkunoita suoraan" -#: ../src/core/prefs.c:1144 -#, c-format, fuzzy -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "GConf-avaimesta %2$s saatu kirjasinkuvaus ”%1$s” ei jäsenny\n" +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "Vaihda suoraan edelliseen ikkunaan" -#: ../src/core/prefs.c:1210 -#, c-format -msgid "\"%s\" found in configuration database is not a valid value for mouse button modifier\n" -msgstr "Asetustietokannassa oleva ”%s” ei ole kelvollinen hiiren muunnosnäppäin\n" +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "Vaihda sovelluksen ikkunoiden välillä suoraan" -#: ../src/core/prefs.c:1722 -#, c-format -msgid "\"%s\" found in configuration database is not a valid value for keybinding \"%s\"\n" -msgstr "”%s”, joka on asetustietokannassa, ei ole kelvollinen näppäinsidonnan ”%s” arvo\n" +#: data/50-mutter-navigation.xml:93 +#, fuzzy +#| msgid "Switch windows of an application" +msgid "Switch directly to previous window of an app" +msgstr "Vaihda sovelluksen ikkunoiden välillä" -#: ../src/core/prefs.c:1819 -#, c-format -msgid "Workspace %d" -msgstr "Työtila %d" +#: data/50-mutter-navigation.xml:97 +#, fuzzy +msgid "Switch system controls directly" +msgstr "Vaihda järjestelmän kontrolleja suoraan" -#: ../src/core/screen.c:730 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "Näytön ”%2$s” ruutu %1$d ei ole kelvollinen\n" +#: data/50-mutter-navigation.xml:102 +#, fuzzy +msgid "Switch directly to previous system control" +msgstr "Vaihda järjestelmän kontrolleja" -#: ../src/core/screen.c:746 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager; try using the --replace option to replace the current window manager.\n" -msgstr "Näytön ”%2$s” ruudulla %1$d on jo ikkunointiohjelma: kokeile valitsinta --replace, jos haluat korvata nykyisen ikkunointiohjelman.\n" +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "Piilota kaikki tavalliset ikkunat" -#: ../src/core/screen.c:773 -#, c-format -msgid "Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "Näytön \"%2$s\" ruudun %1$d ikkunointiohjelman valinnan hankkiminen epäonnistui\n" +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "Siirry työtilaan 1" -#: ../src/core/screen.c:828 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "Näytön ”%2$s” ruudulla %1$d on jo ikkunointiohjelma\n" +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "Siirry työtilaan 2" -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "Näytön ”%2$s” ruudun %1$d vapauttaminen ei onnistunut\n" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "Siirry työtilaan 3" -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Kansion ”%s” luominen ei onnistunut: %s\n" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "Siirry työtilaan 4" -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "Istuntotiedoston ”%s” avaaminen kirjoittamista varten ei onnistunut: %s\n" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "Siirry viimeiseen työtilaan" -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Virhe istuntotiedoston ”%s” kirjoittamisessa: %s\n" +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "Siirrä yllä olevaan työtilaan" -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Virhe istuntotiedoston ”%s” sulkemisessa: %s\n" +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "Siirrä alla olevaan työtilaan" -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Tallennetun istuntotiedoston jäsennys epäonnistui: %s\n" +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "Järjestelmä" -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "<muffin_session>-määre havaittu, mutta istunnon ID on jo selvinnyt" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Näytä komennonsuorituskehote" -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Tuntematon määre %s elementissä <%s>" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Näytä toimintojen yleisnäkymä" -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "sisäkkäiset <window>-laput" +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Palauta pikanäppäimet" -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "Tuntematon elementti %s" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Ikkunat" -#: ../src/core/session.c:1809 -msgid "These windows do not support "save current setup" and will have to be restarted manually next time you log in." -msgstr "Nämä ikkunat eivät ymmärrä ”tallenna nykyinen tila”-komentoa, ja ne täytyy käynnistää käsin uudelleen kun kirjaudut seuraavan kerran sisään." +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "Aktivoi ikkunavalikko" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Vianetsintälokin avaaminen epäonnistui: %s\n" +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Vaihda koko näytön tilaan tai pois" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Lokitiedoston ”%s” fdopen() epäonnistui: %s\n" +#: data/50-mutter-windows.xml:12 +#, fuzzy +msgid "Toggle maximization state" +msgstr "Vaihda suurennustilaa" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "Lokitiedosto %s avattu\n" +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "Suurenna ikkuna" -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "Muffin on käännetty ilman tukea monisanaisille ilmoituksille\n" +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Palauta ikkunan koko" -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "Ikkunointiohjelma:" +#: data/50-mutter-windows.xml:18 +msgid "Close window" +msgstr "Sulje ikkuna" -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "Vika ikkunointiohjelmassa." +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "Piilota ikkuna" -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "Ikkunointiohjelman varoitus:" +#: data/50-mutter-windows.xml:22 +msgid "Move window" +msgstr "Siirrä ikkunaa" -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "Ikkunointiohjelmavirhe:" +#: data/50-mutter-windows.xml:24 +msgid "Resize window" +msgstr "Muuta ikkunan kokoa" -#. first time through -#: ../src/core/window.c:7224 -#, c-format -msgid "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER window as specified in the ICCCM.\n" -msgstr "Ikkuna %s asetti SM_CLIENT_ID:n itselleen, ei WM_CLIENT_LEADERia, kuten sen ICCCM:n mukaan olisi pitänyt tehdä.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#: ../src/core/window.c:7887 -#, c-format -msgid "Window %s sets an MWM hint indicating it isn't resizable, but sets min size %d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "Ikkuna %s asetti MWM-vihjeen ilmoittaakseen, ettei sen kokoa voi muuttaa, mutta asetti myös minimikoon %d × %d ja maksimikoon %d × %d, mikä ei ole järkevää.\n" +#: data/50-mutter-windows.xml:27 +#, fuzzy +msgid "Toggle window on all workspaces or one" +msgstr "Valitse onko ikkuna yhdessä vai kaikissa työtiloissa" -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "Sovellus asetti ylimääräisen _NET_WM_PIDin %lu\n" +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "Nosta ikkuna, jos se on peittynyt, muuten laske se" -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s @ %s" +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "Nosta ikkuna muiden päälle" -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "Virheellinen WM_TRANSIENT_FOR ikkuna 0x%lx kohteelle %s.\n" +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "Laske ikkuna muiden alle" -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "WM_TRANSIENT_FOR ikkuna 0x%lx kohteelle %s loisi silmukan.\n" +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "Suurenna ikkuna pystysuunnassa" -#: ../src/core/xprops.c:155 -#, c-format -msgid "Window 0x%lx has property %s\nthat was expected to have type %s format %d\nand actually has type %s format %d n_items %d.\nThis is most likely an application bug, not a window manager bug.\nThe window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "Ikkunalla 0x%lx on ominaisuus %s\njonka odotettu tyyppi on %s ja muoto %d,\nmutta on todella tyyppi %s, muoto %d, n_items %d.\nVika on todennäköisesti sovelluksessa, ei ikkunointiohjelmassa.\nIkkunan otsikko on ”%s”, luokka ”%s” ja nimi ”%s”\n" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "Suurenna ikkuna vaakasuunnassa" -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "Ikkunan 0x%2$lx ominaisuus %1$s sisälsi virheellistä UTF-8:aa\n" +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "" -#: ../src/core/xprops.c:494 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "Ikkunan 0x%2$lx ominaisuus %1$s sisälsi virheellistä UTF-8:aa luettelon kohdassa %3$d\n" +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "" -#: ../src/muffin.desktop.in.h:1 ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 +#: data/org.gnome.mutter.gschema.xml.in:7 msgid "Modifier to use for extended window management operations" msgstr "Muunnosnäppäin laajennettuja ikkunoidenhallintatoimintoja varten" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 -msgid "This key will initiate the \"overlay\", which is a combination window overview and application launching system. The default is intended to be the \"Windows key\" on PC hardware. It's expected that this binding either the default or set to the empty string." -msgstr "Tämä avain asettaa ”overlay”-tilan (peite), joka on yhdistelmä ikkunoidenhallintaa ja sovellusten käynnistämisjärjestelmää. Oletuksena käytetään ”Windows”-näppäintä PC-tietokoneissa. Odotuksena on, että tämä näppäinsidos on joko oletus tai sen arvona on tyhjä." +#: data/org.gnome.mutter.gschema.xml.in:8 +#, fuzzy +#| msgid "" +#| "This key will initiate the \"overlay\", which is a combination window " +#| "overview and application launching system. The default is intended to be " +#| "the \"Windows key\" on PC hardware. It's expected that this binding " +#| "either the default or set to the empty string." +msgid "" +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." +msgstr "" +"Tämä avain asettaa ”overlay”-tilan (peite), joka on yhdistelmä " +"ikkunoidenhallintaa ja sovellusten käynnistämisjärjestelmää. Oletuksena " +"käytetään ”Windows”-näppäintä PC-tietokoneissa. Odotuksena on, että tämä " +"näppäinsidos on joko oletus tai sen arvona on tyhjä." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 +#: data/org.gnome.mutter.gschema.xml.in:20 msgid "Attach modal dialogs" msgstr "Liitä modaalisia valintaikkunoita" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 -msgid "When true, instead of having independent titlebars, modal dialogs appear attached to the titlebar of the parent window and are moved together with the parent window." -msgstr "Jos tosi, niin itsenäisten otsikkopalkkien sijaan modaaliset valintaikkunan liitetään pääikkunan otsikkopalkkiin ja niitä siirretään yhdessä pääikkunan kanssa." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -msgid "Live Hidden Windows" -msgstr "Elävät piilotetut ikkunat" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 -msgid "Determines whether hidden windows (i.e., minimized windows and windows on other workspaces than the current one) should be kept alive." -msgstr "Määrittää pidetäänkö piilotetut ikkunat (eli pienennetyt ikkunat sekä ikkunat muilla kuin nykyisellä työpöydällä) elossa." +#: data/org.gnome.mutter.gschema.xml.in:21 +msgid "" +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." +msgstr "" +"Jos tosi, niin itsenäisten otsikkopalkkien sijaan modaaliset valintaikkunan " +"liitetään pääikkunan otsikkopalkkiin ja niitä siirretään yhdessä pääikkunan " +"kanssa." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 +#: data/org.gnome.mutter.gschema.xml.in:30 msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "Ota käyttöön reunalaatoitus kun ikkunoita pudotetaan näytön reunoille" + +#: data/org.gnome.mutter.gschema.xml.in:31 +msgid "" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." msgstr "" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 -msgid "If enabled, dropping windows on vertical screen edges maximizes them vertically and resizes them horizontally to cover half of the available area. Dropping windows on the top screen edge maximizes them completely." +#: data/org.gnome.mutter.gschema.xml.in:40 +msgid "Workspaces are managed dynamically" +msgstr "Työtilat hallitaan dynaamisesti" + +#: data/org.gnome.mutter.gschema.xml.in:41 +msgid "" +"Determines whether workspaces are managed dynamically or whether there’s a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." msgstr "" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 +#: data/org.gnome.mutter.gschema.xml.in:50 msgid "Workspaces only on primary" msgstr "Työtilat vain ensisijaisella" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 -msgid "Determines whether workspace switching should happen for windows on all monitors or only for windows on the primary monitor." -msgstr "Määrittää tapahtuuko työtilan vaihto ikkunoille kaikilla näytöillä vaiko vain ikkunoille ensisijaisella näytöllä." +#: data/org.gnome.mutter.gschema.xml.in:51 +msgid "" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." +msgstr "" +"Määrittää tapahtuuko työtilan vaihto ikkunoille kaikilla näytöillä vaiko " +"vain ikkunoille ensisijaisella näytöllä." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 +#: data/org.gnome.mutter.gschema.xml.in:59 msgid "No tab popup" msgstr "" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 -msgid "Determines whether the use of popup and highlight frame should be disabled for window cycling." +#: data/org.gnome.mutter.gschema.xml.in:60 +msgid "" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." msgstr "" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "" +"Viivästytä kohdistuksen vaihtumista, kunnes osoitin lopettaa liikkumisen" + +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" + +#: data/org.gnome.mutter.gschema.xml.in:79 msgid "Draggable border width" msgstr "Raahattava reunaleveys" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 -msgid "The amount of total draggable borders. If the theme's visible borders are not enough, invisible borders will be added to meet this value." -msgstr "Raahattavien reunojen määrä yhteensä. Mikäli teeman näkyvät reunat eivät riitä, näkymätöntä reunaa lisätään täyttämään tämä arvo." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 +#: data/org.gnome.mutter.gschema.xml.in:80 #, fuzzy -msgid "Select window from tab popup" -msgstr "Poista ikkuna päältä" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 -msgid "Cancel tab popup" +#| msgid "" +#| "The amount of total draggable borders. If the theme's visible borders are " +#| "not enough, invisible borders will be added to meet this value." +msgid "" +"The amount of total draggable borders. If the theme’s visible borders are " +"not enough, invisible borders will be added to meet this value." msgstr "" +"Raahattavien reunojen määrä yhteensä. Mikäli teeman näkyvät reunat eivät " +"riitä, näkymätöntä reunaa lisätään täyttämään tämä arvo." -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "Käyttö: %s\n" - -#: ../src/ui/frames.c:1157 -msgid "Close Window" -msgstr "Sulje ikkuna" - -#: ../src/ui/frames.c:1160 -msgid "Window Menu" -msgstr "Ikkunavalikko" - -#: ../src/ui/frames.c:1163 -msgid "Minimize Window" -msgstr "Pienennä ikkuna" +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "" -#: ../src/ui/frames.c:1166 -msgid "Maximize Window" -msgstr "Suurenna ikkuna" +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" -#: ../src/ui/frames.c:1169 -msgid "Restore Window" -msgstr "Palauta ikkuna" +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Aseta uudet ikkunat keskelle näyttöä" -#: ../src/ui/frames.c:1172 -msgid "Roll Up Window" -msgstr "_Rullaa ikkuna ylös" +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" -#: ../src/ui/frames.c:1175 -msgid "Unroll Window" -msgstr "Avaa rullattu ikkuna" +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Ota käyttöön kokeelliset ominaisuudet" -#: ../src/ui/frames.c:1178 -msgid "Keep Window On Top" -msgstr "Pidä ikkuna päällimmäisenä" +#: data/org.gnome.mutter.gschema.xml.in:108 +msgid "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart." +msgstr "" -#: ../src/ui/frames.c:1181 -msgid "Remove Window From Top" +#: data/org.gnome.mutter.gschema.xml.in:141 +#, fuzzy +msgid "Select window from tab popup" msgstr "Poista ikkuna päältä" -#: ../src/ui/frames.c:1184 -msgid "Always On Visible Workspace" -msgstr "Näytä aina näkyvässä työtilassa" - -#: ../src/ui/frames.c:1187 -msgid "Put Window On Only One Workspace" -msgstr "Näytä ikkuna vain yhdessä työtilassa" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "_Pienennä" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "S_uurenna" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "_Palauta koko" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "_Rullaa ylös" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "_Rullaa alas" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "S_iirrä" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "_Muuta kokoa" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "Siirrä otsikkopalkkia _näytöllä" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "Aina _päällimmäisenä" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "Näytä _aina tässä työtilassa" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "Näytä vain _tässä työtilassa" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "Siirrä _vasempaan työtilaan" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "Siirrä _oikeaan työtilaan" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "Siirry _yllä olevaan työtilaan" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "Siirrä _alla olevaan työtilaan" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "_Sulje" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "Työtila %d%n" - -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "Työtila 1_0" - -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "Työtila %s%d" - -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "Siirrä toiseen t_yötilaan" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Vaihto" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" - -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d × %d" - -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "ylä" - -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "ala" - -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "vasen" - -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "oikea" - -#: ../src/ui/theme.c:286 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "kehyksen mitat eivät määrittele ”%s”-kokoa" - -#: ../src/ui/theme.c:305 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "kehyksen mitat eivät määrittele ”%2$s”-reunan ”%1$s”-kokoa" - -#: ../src/ui/theme.c:342 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "Painikkeen sivusuhde %g ei ole järkevä" - -#: ../src/ui/theme.c:354 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "Kehyksen mitat eivät määrittele painikkeiden kokoa" - -#: ../src/ui/theme.c:1067 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "Väriliu'uissa täytyy olla vähintään kaksi väriä" - -#: ../src/ui/theme.c:1219 -#, c-format -msgid "GTK custom color specification must have color name and fallback in parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" -msgstr "GTK-värimääritteessä täytyy olla värin nimi ja vara-arvo suluissa, esim. gtk:custom(foo,bar). ”%s” ei jäsenny" - -#: ../src/ui/theme.c:1235 -#, c-format -msgid "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-_ are valid" -msgstr "Virheellinen merkki ”%c” gtk:custom-osan värinimi-parametrissa: ainoastaan A-Za-z0-9_ ovat sallittuja" - -#: ../src/ui/theme.c:1249 -#, c-format -msgid "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not fit the format" -msgstr "Gtk:custom-muoto on ”gtk:custom(värinimi,vara-arvo)”. ”%s” ei ole tämän muotoinen" - -#: ../src/ui/theme.c:1294 -#, c-format -msgid "GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "GTK-värimääritteessä täytyy olla tila hakasuluissa, esim. gtk:fg[NORMAL], jossa NORMAL on tila. ”%s” ei jäsenny" - -#: ../src/ui/theme.c:1308 -#, c-format -msgid "GTK color specification must have a close bracket after the state, e.g. gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "GTK-värimääritteessä täytyy olla loppuhakasulku tilan jälkeen. Esimerkiksi gtk:fg[NORMAL], jossa NORMAL on tila. ”%s” ei jäsenny" - -#: ../src/ui/theme.c:1319 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "Tila ”%s” ei ole värimääritteessä järkevä" - -#: ../src/ui/theme.c:1332 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "Värikomponentti ”%s” ei ole värimääritteessä järkevä" - -#: ../src/ui/theme.c:1361 -#, c-format -msgid "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the format" -msgstr "Sekoitusmuoto on ”blend/taustaväri/edustaväri/alfa”. ”%s” ei ole tätä muotoa." - -#: ../src/ui/theme.c:1372 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "Alfa-arvo ”%s” sekoitusvärissä ei jäsenny" - -#: ../src/ui/theme.c:1382 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "Alfa-arvo ”%s” sekoitusvärissä ei ole välillä 0.0 - 1.0" - -#: ../src/ui/theme.c:1429 -#, c-format -msgid "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "Varjostusmuoto on ”shade/perusväri/kerroin”. ”%s” ei ole tämän muotoinen." - -#: ../src/ui/theme.c:1440 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "Varjostuskerroin ”%s” varjostetussa värissä ei jäsenny" - -#: ../src/ui/theme.c:1450 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "Varjostuskerroin ”%s” varjostetussa värissä on negatiivinen" - -#: ../src/ui/theme.c:1479 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Värin ”%s” jäsentäminen ei onnistunut" +#: data/org.gnome.mutter.gschema.xml.in:146 +msgid "Cancel tab popup" +msgstr "" -#: ../src/ui/theme.c:1790 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "Koordinaattilauseke sisältää merkin ”%s”, joka ei ole sallittu" +#: data/org.gnome.mutter.gschema.xml.in:151 +msgid "Switch monitor configurations" +msgstr "Vaihda näyttöasetuksia" -#: ../src/ui/theme.c:1817 -#, c-format -msgid "Coordinate expression contains floating point number '%s' which could not be parsed" -msgstr "Koordinaattilauseke sisältää liukuluvun ”%s”, joka ei jäsentynyt" +#: data/org.gnome.mutter.gschema.xml.in:156 +msgid "Rotates the built-in monitor configuration" +msgstr "" -#: ../src/ui/theme.c:1831 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "Koordinaattilauseke sisältää kokonaisluvun ”%s”, joka ei jäsentynyt" +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Siirry virtuaalikonsoliin 1" -#: ../src/ui/theme.c:1953 -#, c-format -msgid "Coordinate expression contained unknown operator at the start of this text: \"%s\"" -msgstr "Koordinaattilauseke sisälsi tuntemattoman operaattorin seuraavan tekstin alussa: ”%s”" +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Siirry virtuaalikonsoliin 2" -#: ../src/ui/theme.c:2010 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "Koordinaattilauseke oli tyhjä tai ei järkevä" +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Siirry virtuaalikonsoliin 3" -#: ../src/ui/theme.c:2121 ../src/ui/theme.c:2131 ../src/ui/theme.c:2165 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "Koordinaattilauseke johtaa nollalla jakamiseen" +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Siirry virtuaalikonsoliin 4" -#: ../src/ui/theme.c:2173 -#, c-format -msgid "Coordinate expression tries to use mod operator on a floating-point number" -msgstr "Koordinaattilauseke yrittää soveltaa mod-operaattoria liukulukuun" +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Siirry virtuaalikonsoliin 5" -#: ../src/ui/theme.c:2229 -#, c-format -msgid "Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "Koordinaattilausekkeessa on operaattori ”%s”, jonka paikalla pitäisi olla operandi" +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Siirry virtuaalikonsoliin 6" -#: ../src/ui/theme.c:2238 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "Koordinaattilauseke sisälsi operandin kohdassa, johon kuuluisi operaattori" +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Siirry virtuaalikonsoliin 7" -#: ../src/ui/theme.c:2246 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "Koordinaattilauseke päättyi operaattoriin, ei operandiin" +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Siirry virtuaalikonsoliin 8" -#: ../src/ui/theme.c:2256 -#, c-format -msgid "Coordinate expression has operator \"%c\" following operator \"%c\" with no operand in between" -msgstr "Koordinaattilausekkeessa on operaattori ”%c” operaattorin ”%c” perässä ilman operandia välissä" +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Siirry virtuaalikonsoliin 9" -#: ../src/ui/theme.c:2407 ../src/ui/theme.c:2452 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "Koordinaattilausekkeessa oli tuntematon muuttuja tai vakio ”%s”" +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Siirry virtuaalikonsoliin 10" -#: ../src/ui/theme.c:2506 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "Koordinaattilausekkeen tulkitsijan puskuri ylitettiin." +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Siirry virtuaalikonsoliin 11" -#: ../src/ui/theme.c:2535 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "Koordinaattilausekkeessa oli lopetussulje ilman vastaavaa aloitussuljetta" +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Siirry virtuaalikonsoliin 12" -#: ../src/ui/theme.c:2599 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "Koordinaattilauseke oli aloitussulje ilman vastaavaa lopetussuljetta" +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "" -#: ../src/ui/theme.c:2610 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "Koordinaattilausekkeessa ei vaikuta olevan operaattoreita eikä operandeja" +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow grabs with Xwayland" +msgstr "" -#: ../src/ui/theme.c:2822 ../src/ui/theme.c:2842 ../src/ui/theme.c:2862 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "Teema sisälsi lausekkeen, josta seurasi virhe: %s\n" +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 +msgid "" +"Allow keyboard grabs issued by X11 applications running in Xwayland to be " +"taken into account. For a X11 grab to be taken into account under Wayland, " +"the client must also either send a specific X11 ClientMessage to the root " +"window or be among the applications white-listed in key “xwayland-grab-" +"access-rules”." +msgstr "" -#: ../src/ui/theme.c:4533 -#, c-format -msgid "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be specified for this frame style" -msgstr "<button function=\"%s\" state=\"%s\" draw_ops=\"mikä lienee\"/> täytyy olla määritelty tätä kehystyyliä varten" +#: data/org.gnome.mutter.wayland.gschema.xml.in:77 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "" -#: ../src/ui/theme.c:5066 ../src/ui/theme.c:5091 -#, c-format -msgid "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "<frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"mikä lienee\"/> puuttuu" +#: data/org.gnome.mutter.wayland.gschema.xml.in:78 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "" -#: ../src/ui/theme.c:5139 +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. +#. +#: src/backends/meta-input-settings.c:2423 #, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Teeman ”%s” lataaminen epäonnistui: %s\n" +msgid "Mode Switch (Group %d)" +msgstr "" -#: ../src/ui/theme.c:5275 ../src/ui/theme.c:5282 ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 ../src/ui/theme.c:5303 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "<%s> ei ole asetettu teemaa ”%s” varten" +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2446 +msgid "Switch monitor" +msgstr "Vaihda näyttöä" -#: ../src/ui/theme.c:5311 -#, c-format -msgid "No frame style set for window type \"%s\" in theme \"%s\", add a <window type=\"%s\" style_set=\"whatever\"/> element" -msgstr "Ikkunatyypille \"%s\" ei ole asetettu kehystyyliä teemassa \"%s\". Lisää <window type=\"%s\" style_set=\"mikä lienee\"/>-elementti." +#: src/backends/meta-input-settings.c:2448 +msgid "Show on-screen help" +msgstr "" -#: ../src/ui/theme.c:5709 ../src/ui/theme.c:5771 ../src/ui/theme.c:5834 -#, c-format -msgid "User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "Käyttäjän määrittelemien vakioiden täytyy alkaa isolla kirjaimella; ”%s” ei ala" +#: src/backends/meta-monitor-manager.c:954 +msgid "Built-in display" +msgstr "Sisäänrakennettu näyttö" -#: ../src/ui/theme.c:5717 ../src/ui/theme.c:5779 ../src/ui/theme.c:5842 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "Vakio ”%s” on jo määritelty" +#: src/backends/meta-monitor-manager.c:986 +msgid "Unknown" +msgstr "Tuntematon" -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "Attribuuttia ”%s” ei löydy elementistä <%s>" +#: src/backends/meta-monitor-manager.c:988 +msgid "Unknown Display" +msgstr "Tuntematon näyttö" -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 +#: src/backends/meta-monitor-manager.c:996 #, c-format -msgid "Line %d character %d: %s" -msgstr "Rivi %d, merkki %d: %s" +#| msgid "%s %s" +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme-parser.c:479 +#: src/backends/meta-monitor-manager.c:1004 #, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "Määre ”%s” on toistettu kahdesti samassa <%s>-elementissä" +#| msgid "%s %s" +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "Määre ”%s” ei ole kelvollinen <%s>-elementissä tässä yhteydessä" +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:482 +#, fuzzy, c-format +#| msgid "" +#| "Another compositing manager is already running on screen %i on display " +#| "\"%s\"." +msgid "" +"Another compositing manager is already running on screen %i on display “%s”." +msgstr "" +"Näytön ”%2$s” ruudullä %1$d on jo käynnissä toinen ikkunoidenladontaohjelman." -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "”%s” ei jäsentynyt kokonaisluvuksi" +#: src/core/bell.c:252 +msgid "Bell event" +msgstr "Äänimerkki" -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "Perässä olevat merkit ”%s” merkkijonossa ”%s” eivät ole järkeviä" +#: src/core/main.c:185 +msgid "Disable connection to session manager" +msgstr "Estä yhteys sessionhallintaan" -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "Kokonaisluvun %ld täytyy olla positiivinen" +#: src/core/main.c:191 +msgid "Replace the running window manager" +msgstr "Vaihda käytössä oleva ikkunanhallinta" -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "Kokonaisluku %ld on liian suuri, nykyinen maksimi on %d" +#: src/core/main.c:197 +msgid "Specify session management ID" +msgstr "Anna sessionhallinnan ID" -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "”%s” ei jäsentynyt liukuluvuksi" +#: src/core/main.c:202 +msgid "X Display to use" +msgstr "Käytettävä X-näyttö" -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "Totuusarvojen täytyy olla ”true” tai ”false”, ei ”%s”" +#: src/core/main.c:208 +msgid "Initialize session from savefile" +msgstr "Alusta sessio tiedostosta" -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "Kulman pitäisi olla välillä 0.0 - 360.0, mutta se oli %g\n" +#: src/core/main.c:214 +msgid "Make X calls synchronous" +msgstr "Käytä synkronisia X-kutsuja" -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "Alfan täytyy olla välillä 0.0 (näkymätön) - 1.0 (täysin peittävä). Se oli %g\n" +#: src/core/main.c:221 +msgid "Run as a wayland compositor" +msgstr "Suorita wayland-koostajana" -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium,large,x-large,xx-large)\n" -msgstr "Epäkelpo otsikon skaala ”%s” (täytyy olla joko xx-small,x-small,small,medium,large,x-large tai xx-large)\n" +#: src/core/main.c:227 +#, fuzzy +#| msgid "Run as a wayland compositor" +msgid "Run as a nested compositor" +msgstr "Suorita wayland-koostajana" -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s>-elementin nimeä ”%s” käytetty toisenkin kerran" +#: src/core/main.c:233 +msgid "Run wayland compositor without starting Xwayland" +msgstr "" -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "<%s>-elementin emo ”%s” ei ole määritelty" +#: src/core/main.c:241 +msgid "Run as a full display server, rather than nested" +msgstr "" -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "<%s>-elementin mitat ”%s” eivät ole määriteltyjä" +#: src/core/main.c:247 +msgid "Run with X11 backend" +msgstr "Suorita X11-taustaosalla" -#: ../src/ui/theme-parser.c:1154 +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:150 #, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "<%s>:n täytyy joko määritellä mitat, tai emo, jolla on jo mitat" +msgid "“%s” is not responding." +msgstr "\"%s\" ei vastaa." -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "Tausta täytyy määritellä, jotta alfa-arvo olisi mielekäs" - -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Tuntematon tyyppi ”%s” elementissä <%s>" +#: src/core/meta-close-dialog-default.c:152 +msgid "Application is not responding." +msgstr "Sovellus ei vastaa." -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "Tuntematon style_set ”%s” elementissä <%s>" +#: src/core/meta-close-dialog-default.c:157 +msgid "" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." +msgstr "" +"Voit odottaa sovellusta vielä hetken tai sulkea sovelluksen väkisin heti." -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "Ikkunatyyppiin ”%s” on jo liitetty tyylijoukko" - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "Elementti <%s> ei ole mahdollinen elementin <%s> alla" +#: src/core/meta-close-dialog-default.c:164 +msgid "_Force Quit" +msgstr "Sulje _väkisin" -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" for buttons" -msgstr "Arvoja ”button_width”/”button_height” ja ”aspect_ratio” ei voi määritellä samalle painikkeille" +#: src/core/meta-close-dialog-default.c:164 +msgid "_Wait" +msgstr "_Odota" -#: ../src/ui/theme-parser.c:1450 +#: src/core/mutter.c:38 #, c-format -msgid "Distance \"%s\" is unknown" -msgstr "Etäisyys ”%s” on tuntematon" +msgid "" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" +msgstr "" +"mutter %s\n" +"Tekijänoikeudet © 2001-%d Havoc Pennington, Red Hat, Inc., ja muut.\n" +"Tämä on vapaa ohjelmisto: katso kopiointiehdot lähdekoodista.\n" +"Ei MINKÄÄNLAISTA takuuta: ei edes takuuta MYYNTIKELPOISUUDESTA tai " +"SOPIVUUDESTA JOHONKIN KÄYTTÖÖN.\n" -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "Sivusuhde ”%s” on tuntematon" +#: src/core/mutter.c:52 +msgid "Print version" +msgstr "Näytä versio" -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "Reuna ”%s” on tuntematon" +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "Käytettävä Mutter-liitännäinen" -#: ../src/ui/theme-parser.c:1868 +#: src/core/prefs.c:1786 #, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "Elementissä <%s> ei ole ”start_angle”- tai ”from” -määrettä" +msgid "Workspace %d" +msgstr "Työtila %d" -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "Elementissä <%s> ei ole ”extent_angle”- tai ”to” -määrettä" +#: src/core/util.c:121 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter on käännetty ilman tukea monisanaisille ilmoituksille\n" -#: ../src/ui/theme-parser.c:2115 +#: src/wayland/meta-wayland-tablet-pad.c:567 #, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "Väriliu'un arvo ”%s” ei ole järkevä" +msgid "Mode Switch: Mode %d" +msgstr "" -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 +#: src/x11/meta-x11-display.c:666 #, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "Täyttötyyppi ”%s” ei ole järkevä elementissä <%s>" +msgid "" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." +msgstr "" +"Näytöllä “%s” on jo ikkunointiohjelma: kokeile valitsinta --replace, jos " +"haluat korvata nykyisen ikkunointiohjelman." -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "Tila ”%s” ei ole järkevä elementissä <%s>" +#: src/x11/meta-x11-display.c:1008 +msgid "Failed to initialize GDK\n" +msgstr "" -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 +#: src/x11/meta-x11-display.c:1032 #, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "Varjo ”%s” ei ole järkevä elementissä <%s>" +msgid "Failed to open X Window System display “%s”\n" +msgstr "X-ikkunointijärjestelmän näytön “%s” avaaminen epäonnistui\n" -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "Nuoli ”%s” ei ole järkevä elementissä <%s>" +#: src/x11/meta-x11-display.c:1115 +#, fuzzy, c-format +#| msgid "Screen %d on display '%s' is invalid\n" +msgid "Screen %d on display “%s” is invalid\n" +msgstr "Näytön ”%2$s” ruutu %1$d ei ole kelvollinen\n" -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "<draw_ops> ”%s” ei ole määritelty" +#: src/x11/session.c:1821 +#, fuzzy +#| msgid "" +#| "These windows do not support "save current setup" and will have " +#| "to be restarted manually next time you log in." +msgid "" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." +msgstr "" +"Nämä ikkunat eivät ymmärrä ”tallenna nykyinen tila”-komentoa, ja ne täytyy " +"käynnistää käsin uudelleen kun kirjaudut seuraavan kerran sisään." -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 +#: src/x11/window-props.c:568 #, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "Draw_opsin ”%s” sisällyttäminen tähän aiheuttaisi kehäviitteen" +msgid "%s (on %s)" +msgstr "%s @ %s" -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Tuntematon kehyksen palan sijainti ”%s”" +#~ msgid "Move window one workspace to the left" +#~ msgstr "Siirrä ikkunaa yksi työtila vasemmalle" -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "Kehystyylissä on jo pala sijainnissa %s" +#~ msgid "Move window one workspace to the right" +#~ msgstr "Siirrä ikkunaa yksi työtila oikealle" -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "”%s”-nimistä <draw_ops>:ia ei ole määritelty" +#~ msgid "Move to workspace left" +#~ msgstr "Siirrä vasemmalla olevaan työtilaan" -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Tuntematon painikkeen toiminto ”%s”" +#~ msgid "Move to workspace right" +#~ msgstr "Siirrä oikealla olevaan työtilaan" -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "Nappifunktiota ”%s” ei ole tässä versiossa (%d, tarvitaan %d)" +#, fuzzy +#~ msgid "Toggle shaded state" +#~ msgstr "Vaihda rullaustilaa" + +#~ msgid "Failed to scan themes directory: %s\n" +#~ msgstr "Teemakansion lukeminen epäonnistui: %s\n" + +#~ msgid "" +#~ "Could not find a theme! Be sure %s exists and contains the usual themes.\n" +#~ msgstr "" +#~ "Teemaa ei löydy! Varmista, että %s on olemassa, ja sisältää tavalliset " +#~ "teemat.\n" + +#~ msgid "Screen %d on display \"%s\" already has a window manager\n" +#~ msgstr "Näytön ”%2$s” ruudulla %1$d on jo ikkunointiohjelma\n" -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Tuntematon painikkeen tila ”%s”" +#~ msgid "%d x %d" +#~ msgstr "%d × %d" -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "Kehystyylillä on jo painike funktiota %s, tilaa %s varten" +#~ msgid "top" +#~ msgstr "ylä" + +#~ msgid "bottom" +#~ msgstr "ala" + +#~ msgid "left" +#~ msgstr "vasen" -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "”%s” ei ole kelvollinen kohdistusmääreen arvo" +#~ msgid "right" +#~ msgstr "oikea" + +#~ msgid "frame geometry does not specify \"%s\" dimension" +#~ msgstr "kehyksen mitat eivät määrittele ”%s”-kokoa" + +#~ msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" +#~ msgstr "kehyksen mitat eivät määrittele ”%2$s”-reunan ”%1$s”-kokoa" + +#~ msgid "Button aspect ratio %g is not reasonable" +#~ msgstr "Painikkeen sivusuhde %g ei ole järkevä" -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "”%s” ei ole kelvollinen tilamääreen arvo" +#~ msgid "Frame geometry does not specify size of buttons" +#~ msgstr "Kehyksen mitat eivät määrittele painikkeiden kokoa" + +#~ msgid "Gradients should have at least two colors" +#~ msgstr "Väriliu'uissa täytyy olla vähintään kaksi väriä" + +#~ msgid "" +#~ "GTK custom color specification must have color name and fallback in " +#~ "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" +#~ msgstr "" +#~ "GTK-värimääritteessä täytyy olla värin nimi ja vara-arvo suluissa, esim. " +#~ "gtk:custom(foo,bar). ”%s” ei jäsenny" + +#~ msgid "" +#~ "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-" +#~ "z0-9-_ are valid" +#~ msgstr "" +#~ "Virheellinen merkki ”%c” gtk:custom-osan värinimi-parametrissa: " +#~ "ainoastaan A-Za-z0-9_ ovat sallittuja" + +#~ msgid "" +#~ "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " +#~ "fit the format" +#~ msgstr "" +#~ "Gtk:custom-muoto on ”gtk:custom(värinimi,vara-arvo)”. ”%s” ei ole tämän " +#~ "muotoinen" + +#~ msgid "" +#~ "GTK color specification must have the state in brackets, e.g. gtk:" +#~ "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "GTK-värimääritteessä täytyy olla tila hakasuluissa, esim. gtk:fg[NORMAL], " +#~ "jossa NORMAL on tila. ”%s” ei jäsenny" + +#~ msgid "" +#~ "GTK color specification must have a close bracket after the state, e.g. " +#~ "gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "GTK-värimääritteessä täytyy olla loppuhakasulku tilan jälkeen. " +#~ "Esimerkiksi gtk:fg[NORMAL], jossa NORMAL on tila. ”%s” ei jäsenny" + +#~ msgid "Did not understand state \"%s\" in color specification" +#~ msgstr "Tila ”%s” ei ole värimääritteessä järkevä" + +#~ msgid "Did not understand color component \"%s\" in color specification" +#~ msgstr "Värikomponentti ”%s” ei ole värimääritteessä järkevä" + +#~ msgid "" +#~ "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit " +#~ "the format" +#~ msgstr "" +#~ "Sekoitusmuoto on ”blend/taustaväri/edustaväri/alfa”. ”%s” ei ole tätä " +#~ "muotoa." + +#~ msgid "Could not parse alpha value \"%s\" in blended color" +#~ msgstr "Alfa-arvo ”%s” sekoitusvärissä ei jäsenny" + +#~ msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" +#~ msgstr "Alfa-arvo ”%s” sekoitusvärissä ei ole välillä 0.0 - 1.0" + +#~ msgid "" +#~ "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the " +#~ "format" +#~ msgstr "" +#~ "Varjostusmuoto on ”shade/perusväri/kerroin”. ”%s” ei ole tämän muotoinen." + +#~ msgid "Could not parse shade factor \"%s\" in shaded color" +#~ msgstr "Varjostuskerroin ”%s” varjostetussa värissä ei jäsenny" + +#~ msgid "Shade factor \"%s\" in shaded color is negative" +#~ msgstr "Varjostuskerroin ”%s” varjostetussa värissä on negatiivinen" + +#~ msgid "Could not parse color \"%s\"" +#~ msgstr "Värin ”%s” jäsentäminen ei onnistunut" + +#~ msgid "Coordinate expression contains character '%s' which is not allowed" +#~ msgstr "Koordinaattilauseke sisältää merkin ”%s”, joka ei ole sallittu" + +#~ msgid "" +#~ "Coordinate expression contains floating point number '%s' which could not " +#~ "be parsed" +#~ msgstr "Koordinaattilauseke sisältää liukuluvun ”%s”, joka ei jäsentynyt" + +#~ msgid "" +#~ "Coordinate expression contains integer '%s' which could not be parsed" +#~ msgstr "Koordinaattilauseke sisältää kokonaisluvun ”%s”, joka ei jäsentynyt" + +#~ msgid "" +#~ "Coordinate expression contained unknown operator at the start of this " +#~ "text: \"%s\"" +#~ msgstr "" +#~ "Koordinaattilauseke sisälsi tuntemattoman operaattorin seuraavan tekstin " +#~ "alussa: ”%s”" + +#~ msgid "Coordinate expression was empty or not understood" +#~ msgstr "Koordinaattilauseke oli tyhjä tai ei järkevä" + +#~ msgid "Coordinate expression results in division by zero" +#~ msgstr "Koordinaattilauseke johtaa nollalla jakamiseen" + +#~ msgid "" +#~ "Coordinate expression tries to use mod operator on a floating-point number" +#~ msgstr "Koordinaattilauseke yrittää soveltaa mod-operaattoria liukulukuun" + +#~ msgid "" +#~ "Coordinate expression has an operator \"%s\" where an operand was expected" +#~ msgstr "" +#~ "Koordinaattilausekkeessa on operaattori ”%s”, jonka paikalla pitäisi olla " +#~ "operandi" + +#~ msgid "Coordinate expression had an operand where an operator was expected" +#~ msgstr "" +#~ "Koordinaattilauseke sisälsi operandin kohdassa, johon kuuluisi operaattori" + +#~ msgid "Coordinate expression ended with an operator instead of an operand" +#~ msgstr "Koordinaattilauseke päättyi operaattoriin, ei operandiin" + +#~ msgid "" +#~ "Coordinate expression has operator \"%c\" following operator \"%c\" with " +#~ "no operand in between" +#~ msgstr "" +#~ "Koordinaattilausekkeessa on operaattori ”%c” operaattorin ”%c” perässä " +#~ "ilman operandia välissä" + +#~ msgid "Coordinate expression had unknown variable or constant \"%s\"" +#~ msgstr "Koordinaattilausekkeessa oli tuntematon muuttuja tai vakio ”%s”" + +#~ msgid "Coordinate expression parser overflowed its buffer." +#~ msgstr "Koordinaattilausekkeen tulkitsijan puskuri ylitettiin." + +#~ msgid "" +#~ "Coordinate expression had a close parenthesis with no open parenthesis" +#~ msgstr "" +#~ "Koordinaattilausekkeessa oli lopetussulje ilman vastaavaa aloitussuljetta" + +#~ msgid "" +#~ "Coordinate expression had an open parenthesis with no close parenthesis" +#~ msgstr "" +#~ "Koordinaattilauseke oli aloitussulje ilman vastaavaa lopetussuljetta" -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "”%s”-nimistä tyyliä ei ole määritelty" +#~ msgid "Coordinate expression doesn't seem to have any operators or operands" +#~ msgstr "" +#~ "Koordinaattilausekkeessa ei vaikuta olevan operaattoreita eikä operandeja" -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "”%s” ei ole kelvollinen koonmuutosmääreen arvo" +#~ msgid "Theme contained an expression that resulted in an error: %s\n" +#~ msgstr "Teema sisälsi lausekkeen, josta seurasi virhe: %s\n" -#: ../src/ui/theme-parser.c:3147 -#, c-format -msgid "Should not have \"resize\" attribute on <%s> element for maximized/shaded states" -msgstr "Elementissä <%s> pitäisi olla ”resize”-määre suurennettua ja rullattua tilaa varten" +#~ msgid "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " +#~ "specified for this frame style" +#~ msgstr "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"mikä lienee\"/> täytyy " +#~ "olla määritelty tätä kehystyyliä varten" -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "Elementissä <%s> ei pitäisi olla ”resize”-määrettä suurennetuilla tiloilla" +#~ msgid "" +#~ "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/" +#~ ">" +#~ msgstr "" +#~ "<frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"mikä lienee\"/> " +#~ "puuttuu" -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "Tyyli on jo määritelty tilaa %s, koonmuutosta %s, kohdistusta %s varten" +#~ msgid "Failed to load theme \"%s\": %s\n" +#~ msgstr "Teeman ”%s” lataaminen epäonnistui: %s\n" -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "Tyyli on jo määritelty tilaa %s, kohdistusta %s varten" +#~ msgid "No <%s> set for theme \"%s\"" +#~ msgstr "<%s> ei ole asetettu teemaa ”%s” varten" -#: ../src/ui/theme-parser.c:3294 -msgid "Can't have a two draw_ops for a <piece> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "<piece>-elementissä ei voi olla kahta draw_opsia (teema määritteli joko draw_ops-määreen sekä <draw_ops>-elementin tai kaksi elementtiä)" +#~ msgid "" +#~ "No frame style set for window type \"%s\" in theme \"%s\", add a <window " +#~ "type=\"%s\" style_set=\"whatever\"/> element" +#~ msgstr "" +#~ "Ikkunatyypille \"%s\" ei ole asetettu kehystyyliä teemassa \"%s\". Lisää " +#~ "<window type=\"%s\" style_set=\"mikä lienee\"/>-elementti." -#: ../src/ui/theme-parser.c:3332 -msgid "Can't have a two draw_ops for a <button> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "<button>-elementissä ei voi olla kahta draw_opsia (teema määritteli joko draw_ops-määreen sekä <draw_ops>-elementin tai kaksi elementtiä)" +#~ msgid "" +#~ "User-defined constants must begin with a capital letter; \"%s\" does not" +#~ msgstr "" +#~ "Käyttäjän määrittelemien vakioiden täytyy alkaa isolla kirjaimella; ”%s” " +#~ "ei ala" -#: ../src/ui/theme-parser.c:3370 -msgid "Can't have a two draw_ops for a <menu_icon> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "<menu_icon>-elementissä ei voi olla kahta draw_opsia (teema määritteli joko draw_ops-määreen sekä <draw_ops>-elementin tai kaksi elementtiä)" +#~ msgid "Constant \"%s\" has already been defined" +#~ msgstr "Vakio ”%s” on jo määritelty" -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "Väärä versiomäärittely ”%s”" +#~ msgid "No \"%s\" attribute on element <%s>" +#~ msgstr "Attribuuttia ”%s” ei löydy elementistä <%s>" -#: ../src/ui/theme-parser.c:3507 -msgid "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-theme-2.xml" -msgstr "”version”-määrettä ei voi käyttäää tiedostoissa metacity-theme-1.xml tai metacity-theme-2.xml" +#~ msgid "Line %d character %d: %s" +#~ msgstr "Rivi %d, merkki %d: %s" -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "Teema vaatii version %s mutta viimeisin tuettu teeman version on %d.%d" +#~ msgid "Attribute \"%s\" repeated twice on the same <%s> element" +#~ msgstr "Määre ”%s” on toistettu kahdesti samassa <%s>-elementissä" -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "Uloin elementti täytyy olla <metacity_theme>, ei <%s>" +#~ msgid "Attribute \"%s\" is invalid on <%s> element in this context" +#~ msgstr "Määre ”%s” ei ole kelvollinen <%s>-elementissä tässä yhteydessä" -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "Element <%s> is not allowed inside a name/author/date/description element" -msgstr "Elementti <%s> ei voi olla nimi-, tekijä-, päiväys- tai kuvauselementin sisällä" +#~ msgid "Could not parse \"%s\" as an integer" +#~ msgstr "”%s” ei jäsentynyt kokonaisluvuksi" -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "Elementti <%s> ei voi olla <constant>-elementin sisällä" +#~ msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +#~ msgstr "Perässä olevat merkit ”%s” merkkijonossa ”%s” eivät ole järkeviä" -#: ../src/ui/theme-parser.c:3599 -#, c-format -msgid "Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "Elementti <%s> ei voi olla etäisyys-, reuna- tai sivusuhde-elementin sisällä" +#~ msgid "Integer %ld must be positive" +#~ msgstr "Kokonaisluvun %ld täytyy olla positiivinen" -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "Elementti <%s> ei voi olla piirto-operaatioelementin sisällä" +#~ msgid "Integer %ld is too large, current max is %d" +#~ msgstr "Kokonaisluku %ld on liian suuri, nykyinen maksimi on %d" -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "Elementti <%s> ei voi olla elementin <%s> sisällä" +#~ msgid "Could not parse \"%s\" as a floating point number" +#~ msgstr "”%s” ei jäsentynyt liukuluvuksi" -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "Kehyksen palaa varten ei ole draw_opsia" +#~ msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" +#~ msgstr "Totuusarvojen täytyy olla ”true” tai ”false”, ei ”%s”" -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "Painiketta varten ei ole draw_opsia" +#~ msgid "Angle must be between 0.0 and 360.0, was %g\n" +#~ msgstr "Kulman pitäisi olla välillä 0.0 - 360.0, mutta se oli %g\n" -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "Elementin <%s> sisällä ei voi olla tekstiä" +#~ msgid "" +#~ "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" +#~ msgstr "" +#~ "Alfan täytyy olla välillä 0.0 (näkymätön) - 1.0 (täysin peittävä). Se oli " +#~ "%g\n" -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "<%s> määritelty kahdesti tälle teemalle" +#~ msgid "" +#~ "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," +#~ "large,x-large,xx-large)\n" +#~ msgstr "" +#~ "Epäkelpo otsikon skaala ”%s” (täytyy olla joko xx-small,x-small,small," +#~ "medium,large,x-large tai xx-large)\n" -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Teemalle %s ei löytynyt kelvollista tiedostoa\n" +#~ msgid "<%s> name \"%s\" used a second time" +#~ msgstr "<%s>-elementin nimeä ”%s” käytetty toisenkin kerran" -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "_Ikkunat" +#~ msgid "<%s> parent \"%s\" has not been defined" +#~ msgstr "<%s>-elementin emo ”%s” ei ole määritelty" -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "Valinta_ikkuna" +#~ msgid "<%s> geometry \"%s\" has not been defined" +#~ msgstr "<%s>-elementin mitat ”%s” eivät ole määriteltyjä" -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "_Modaalinen valintaikkuna" +#~ msgid "<%s> must specify either a geometry or a parent that has a geometry" +#~ msgstr "<%s>:n täytyy joko määritellä mitat, tai emo, jolla on jo mitat" -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "_Työkalu" +#~ msgid "You must specify a background for an alpha value to be meaningful" +#~ msgstr "Tausta täytyy määritellä, jotta alfa-arvo olisi mielekäs" -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "_Käynnistysikkuna" +#~ msgid "Unknown type \"%s\" on <%s> element" +#~ msgstr "Tuntematon tyyppi ”%s” elementissä <%s>" -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "_Ylätelakka" +#~ msgid "Unknown style_set \"%s\" on <%s> element" +#~ msgstr "Tuntematon style_set ”%s” elementissä <%s>" -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "_Alatelakka" +#~ msgid "Window type \"%s\" has already been assigned a style set" +#~ msgstr "Ikkunatyyppiin ”%s” on jo liitetty tyylijoukko" -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "_Vasen telakka" +#~ msgid "Element <%s> is not allowed below <%s>" +#~ msgstr "Elementti <%s> ei ole mahdollinen elementin <%s> alla" -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "_Oikea telakka" +#~ msgid "" +#~ "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio" +#~ "\" for buttons" +#~ msgstr "" +#~ "Arvoja ”button_width”/”button_height” ja ”aspect_ratio” ei voi määritellä " +#~ "samalle painikkeille" -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "_Kaikki telakat" +#~ msgid "Distance \"%s\" is unknown" +#~ msgstr "Etäisyys ”%s” on tuntematon" -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "_Työpöytä" +#~ msgid "Aspect ratio \"%s\" is unknown" +#~ msgstr "Sivusuhde ”%s” on tuntematon" -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "Avaa uusi tällainen ikkuna" +#~ msgid "Border \"%s\" is unknown" +#~ msgstr "Reuna ”%s” on tuntematon" -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "Tämä on testipainike, jossa on ”avaa”-kuvake" +#~ msgid "No \"start_angle\" or \"from\" attribute on element <%s>" +#~ msgstr "Elementissä <%s> ei ole ”start_angle”- tai ”from” -määrettä" -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "Tämä on testipainike, jossa on ”lopeta”-kuvake" +#~ msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" +#~ msgstr "Elementissä <%s> ei ole ”extent_angle”- tai ”to” -määrettä" -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "Tämä on esimerkkiviesti esimerkkivalintaikkunassa" +#~ msgid "Did not understand value \"%s\" for type of gradient" +#~ msgstr "Väriliu'un arvo ”%s” ei ole järkevä" -#: ../src/ui/theme-viewer.c:328 -#, c-format -msgid "Fake menu item %d\n" -msgstr "Valikon kohta %d\n" +#~ msgid "Did not understand fill type \"%s\" for <%s> element" +#~ msgstr "Täyttötyyppi ”%s” ei ole järkevä elementissä <%s>" -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "Ikkuna, jossa on vain reunat" +#~ msgid "Did not understand state \"%s\" for <%s> element" +#~ msgstr "Tila ”%s” ei ole järkevä elementissä <%s>" -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "Palkki" +#~ msgid "Did not understand shadow \"%s\" for <%s> element" +#~ msgstr "Varjo ”%s” ei ole järkevä elementissä <%s>" -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "Tavallisen sovelluksen ikkuna" +#~ msgid "Did not understand arrow \"%s\" for <%s> element" +#~ msgstr "Nuoli ”%s” ei ole järkevä elementissä <%s>" -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "Valintaikkuna" +#~ msgid "No <draw_ops> called \"%s\" has been defined" +#~ msgstr "<draw_ops> ”%s” ei ole määritelty" -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "Modaalinen valintaikkuna" +#~ msgid "Including draw_ops \"%s\" here would create a circular reference" +#~ msgstr "Draw_opsin ”%s” sisällyttäminen tähän aiheuttaisi kehäviitteen" -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "Palettityökalu" +#~ msgid "Unknown position \"%s\" for frame piece" +#~ msgstr "Tuntematon kehyksen palan sijainti ”%s”" -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "Irrotettu valikko" +#~ msgid "Frame style already has a piece at position %s" +#~ msgstr "Kehystyylissä on jo pala sijainnissa %s" -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "Reuna" +#~ msgid "No <draw_ops> with the name \"%s\" has been defined" +#~ msgstr "”%s”-nimistä <draw_ops>:ia ei ole määritelty" -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "Liitetty modaalinen valintaikkuna" +#~ msgid "Unknown function \"%s\" for button" +#~ msgstr "Tuntematon painikkeen toiminto ”%s”" -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "Painikkeiden asettelutesti %d" +#~ msgid "Button function \"%s\" does not exist in this version (%d, need %d)" +#~ msgstr "Nappifunktiota ”%s” ei ole tässä versiossa (%d, tarvitaan %d)" -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g millisekuntia yhden ikkunan kehyksen piirtämiseen" +#~ msgid "Unknown state \"%s\" for button" +#~ msgstr "Tuntematon painikkeen tila ”%s”" -#: ../src/ui/theme-viewer.c:813 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Käyttö: metacity-theme-viewer [TEEMANIMI]\n" +#~ msgid "Frame style already has a button for function %s state %s" +#~ msgstr "Kehystyylillä on jo painike funktiota %s, tilaa %s varten" -#: ../src/ui/theme-viewer.c:820 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "Virhe teeman lataamisessa: %s\n" +#~ msgid "\"%s\" is not a valid value for focus attribute" +#~ msgstr "”%s” ei ole kelvollinen kohdistusmääreen arvo" -#: ../src/ui/theme-viewer.c:826 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "Teema ”%s” latautui %g sekunnissa\n" +#~ msgid "\"%s\" is not a valid value for state attribute" +#~ msgstr "”%s” ei ole kelvollinen tilamääreen arvo" -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "Tavallinen otsikon kirjasin" +#~ msgid "A style called \"%s\" has not been defined" +#~ msgstr "”%s”-nimistä tyyliä ei ole määritelty" -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "Pieni otsikon kirjasin" +#~ msgid "\"%s\" is not a valid value for resize attribute" +#~ msgstr "”%s” ei ole kelvollinen koonmuutosmääreen arvo" -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "Suuri otsikon kirjasin" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized/shaded " +#~ "states" +#~ msgstr "" +#~ "Elementissä <%s> pitäisi olla ”resize”-määre suurennettua ja rullattua " +#~ "tilaa varten" -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "Painikkeiden asettelu" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized states" +#~ msgstr "" +#~ "Elementissä <%s> ei pitäisi olla ”resize”-määrettä suurennetuilla tiloilla" -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "Koesta" +#~ msgid "Style has already been specified for state %s resize %s focus %s" +#~ msgstr "" +#~ "Tyyli on jo määritelty tilaa %s, koonmuutosta %s, kohdistusta %s varten" -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "Ikkunan otsikko tähän" +#~ msgid "Style has already been specified for state %s focus %s" +#~ msgstr "Tyyli on jo määritelty tilaa %s, kohdistusta %s varten" -#: ../src/ui/theme-viewer.c:1047 -#, c-format -msgid "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g seconds wall clock time including X server resources (%g milliseconds per frame)\n" -msgstr "%d kehystä piirtyi %g asiakaspuolen sekunnissa (%g millisekuntia per kehys) ja %g todellisessa sekunnissa, ottaen mukaan X-palvelimen resurssit (%g millisekuntia per kehys)\n" +#~ msgid "" +#~ "Can't have a two draw_ops for a <piece> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "<piece>-elementissä ei voi olla kahta draw_opsia (teema määritteli joko " +#~ "draw_ops-määreen sekä <draw_ops>-elementin tai kaksi elementtiä)" -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "sijaintilausekkeen testi palautti TOSI, mutta asetti virheen" +#~ msgid "" +#~ "Can't have a two draw_ops for a <button> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "<button>-elementissä ei voi olla kahta draw_opsia (teema määritteli joko " +#~ "draw_ops-määreen sekä <draw_ops>-elementin tai kaksi elementtiä)" -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "sijaintilausekkeen testi palautti EPÄTOSI, mutta ei asettanut virhettä" +#~ msgid "" +#~ "Can't have a two draw_ops for a <menu_icon> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "<menu_icon>-elementissä ei voi olla kahta draw_opsia (teema määritteli " +#~ "joko draw_ops-määreen sekä <draw_ops>-elementin tai kaksi elementtiä)" -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "Virhe odotettu, mutta mitään ei ilmennyt" +#~ msgid "Bad version specification '%s'" +#~ msgstr "Väärä versiomäärittely ”%s”" -#: ../src/ui/theme-viewer.c:1274 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "Virhe %d odotettu, mutta %d ilmeni" +#~ msgid "" +#~ "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" +#~ "theme-2.xml" +#~ msgstr "" +#~ "”version”-määrettä ei voi käyttäää tiedostoissa metacity-theme-1.xml tai " +#~ "metacity-theme-2.xml" -#: ../src/ui/theme-viewer.c:1280 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "Virhettä ei odotettu, mutta eräs ilmeni: %s" +#~ msgid "" +#~ "Theme requires version %s but latest supported theme version is %d.%d" +#~ msgstr "" +#~ "Teema vaatii version %s mutta viimeisin tuettu teeman version on %d.%d" -#: ../src/ui/theme-viewer.c:1284 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "x-arvo oli %d, %d oli odotettu" +#~ msgid "Outermost element in theme must be <metacity_theme> not <%s>" +#~ msgstr "Uloin elementti täytyy olla <metacity_theme>, ei <%s>" -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "y-arvo oli %d, %d oli odotettu" +#~ msgid "" +#~ "Element <%s> is not allowed inside a name/author/date/description element" +#~ msgstr "" +#~ "Elementti <%s> ei voi olla nimi-, tekijä-, päiväys- tai kuvauselementin " +#~ "sisällä" -#: ../src/ui/theme-viewer.c:1352 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "%d-sijaintilauseketta jäsentyi %g sekunnissa (%g sekuntia keksimäärin)\n" +#~ msgid "Element <%s> is not allowed inside a <constant> element" +#~ msgstr "Elementti <%s> ei voi olla <constant>-elementin sisällä" +#~ msgid "" +#~ "Element <%s> is not allowed inside a distance/border/aspect_ratio element" +#~ msgstr "" +#~ "Elementti <%s> ei voi olla etäisyys-, reuna- tai sivusuhde-elementin " +#~ "sisällä" + +#~ msgid "Element <%s> is not allowed inside a draw operation element" +#~ msgstr "Elementti <%s> ei voi olla piirto-operaatioelementin sisällä" + +#~ msgid "Element <%s> is not allowed inside a <%s> element" +#~ msgstr "Elementti <%s> ei voi olla elementin <%s> sisällä" + +#~ msgid "No draw_ops provided for frame piece" +#~ msgstr "Kehyksen palaa varten ei ole draw_opsia" + +#~ msgid "No draw_ops provided for button" +#~ msgstr "Painiketta varten ei ole draw_opsia" + +#~ msgid "No text is allowed inside element <%s>" +#~ msgstr "Elementin <%s> sisällä ei voi olla tekstiä" + +#~ msgid "<%s> specified twice for this theme" +#~ msgstr "<%s> määritelty kahdesti tälle teemalle" + +#~ msgid "Failed to find a valid file for theme %s\n" +#~ msgstr "Teemalle %s ei löytynyt kelvollista tiedostoa\n" diff --git a/po/fr.po b/po/fr.po index f9608ca7c..615965070 100644 --- a/po/fr.po +++ b/po/fr.po @@ -1,5 +1,5 @@ -# French translation of muffin. -# Copyright (C) 2002-2012 Free Software Foundation, Inc. +# French translation of mutter. +# Copyright (C) 2002-2019 Free Software Foundation, Inc. # This file is distributed under the same license as the metacity package. # # Christophe Fergeau <teuf@users.sourceforge.net>, 2002. @@ -9,1639 +9,786 @@ # Baptiste Mille-Mathias <baptiste@mille-mathias.info>, 2004. # Jonathan Ernst <jonathan@ernstfamily.ch>, 2006. # Cyprien Le Pannérer <cyplp@free.fr>, 2006. -# Robert-André Mauchin <zebob.m@gmail.com>, 2007. +# Robert-André Mauchin <zebob.m@gmail.com>, 2007. # Stéphane Raimbault <stephane.raimbault@gmail.com>, 2007. -# Claude Paroz <claude@2xlibre.net>, 2008-2011. # Bruno Brouard <annoa.b@gmail.com>, 2011-12. +# Jean-Baptiste Holcroft <jean-baptiste@holcroft.fr>, 2017. +# Charles Monzat <charles.monzat@numericable.fr>, 2016-2018. +# Claude Paroz <claude@2xlibre.net>, 2008-2019. # msgid "" msgstr "" -"Project-Id-Version: muffin masterReport-Msgid-Bugs-To: http://bugzilla.gnome." -"org/enter_bug.cgi?product=muffin&component=general\n" -"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" -"product=muffin&keywords=I18N+L10N&component=general\n" -"POT-Creation-Date: 2012-03-22 03:46+0000\n" -"PO-Revision-Date: 2012-03-23 20:30+0100\n" -"Last-Translator: Alain Lojewski <allomervan@gmail.com>\n" +"Project-Id-Version: mutter master\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2020-02-23 17:41+0000\n" +"PO-Revision-Date: 2020-03-01 13:19+0100\n" +"Last-Translator: Guillaume Bernard <associations@guillaume-bernard.fr>\n" "Language-Team: GNOME French Team <gnomefr@traduc.org>\n" +"Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Poedit 2.3\n" -#: ../src/50-muffin-windows.xml.in.h:1 -msgid "Windows" -msgstr "Fenêtres" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Navigation" -#: ../src/50-muffin-windows.xml.in.h:2 -msgid "View split on left" -msgstr "Vue divisée sur la gauche" +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Déplacer la fenêtre vers l’espace de travail 1" -#: ../src/50-muffin-windows.xml.in.h:3 -msgid "View split on right" -msgstr "Vue divisée sur la droite" +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Déplacer la fenêtre vers l’espace de travail 2" -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format -msgid "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." -msgstr "" -"Un autre gestionnaire de composition est déjà lancé sur l'écran %i de " -"l'affichage « %s »." +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Déplacer la fenêtre vers l’espace de travail 3" -#: ../src/core/bell.c:307 -msgid "Bell event" -msgstr "Évènement sonore" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Déplacer la fenêtre vers l’espace de travail 4" -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Requête d'information de fenêtre inconnue : %d" +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Déplacer la fenêtre vers le dernier espace de travail" -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> ne répond pas." +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "Déplacer la fenêtre d’un espace de travail vers le haut" -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "L'application ne répond pas." +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "Déplacer la fenêtre d’un espace de travail vers le bas" -#: ../src/core/delete.c:119 -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "" -"Vous pouvez patienter un instant pour continuer ou forcer l'application à " -"quitter définitivement." +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "Déplacer la fenêtre d’un écran vers la gauche" -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "_Attendre" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "Déplacer la fenêtre d’un écran vers la droite" -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "_Forcer à quitter" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "Déplacer la fenêtre d’un écran vers le haut" -#: ../src/core/display.c:387 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "Il manque l'extension %s nécessaire à la composition" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "Déplacer la fenêtre d’un écran vers le bas" -#: ../src/core/display.c:453 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Impossible d'ouvrir le visuel « %s » du système X Window\n" +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "Changer d’application" -#: ../src/core/keybindings.c:852 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "" -"Un autre programme utilise déjà la clé %s avec les modificateurs %x comme " -"liaison\n" +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "Passer à l’application précédente" -#: ../src/core/main.c:206 -msgid "Disable connection to session manager" -msgstr "Désactiver la connexion au gestionnaire de sessions" +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "Changer de fenêtre" -#: ../src/core/main.c:212 -msgid "Replace the running window manager" -msgstr "Remplacer le gestionnaire de fenêtres en cours de fonctionnement" +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "Passer à la fenêtre précédente" -#: ../src/core/main.c:218 -msgid "Specify session management ID" -msgstr "Indiquer l'ID de gestion de sessions" +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "Changer de fenêtre d’une application" -#: ../src/core/main.c:223 -msgid "X Display to use" -msgstr "Visuel X à utiliser" +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "Passer à la fenêtre précédente d’une application" -#: ../src/core/main.c:229 -msgid "Initialize session from savefile" -msgstr "Initialiser la session depuis le fichier de sauvegarde" +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "Changer les contrôles système" -#: ../src/core/main.c:235 -msgid "Make X calls synchronous" -msgstr "Rendre synchrones les appels à X" +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "Passer au contrôle système précédent" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Le parcours du répertoire de thèmes a échoué : %s\n" +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "Changer de fenêtre directement" -#: ../src/core/main.c:520 -#, c-format -msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "" -"Impossible de trouver un thème ! Assurez-vous que %s existe et contient les " -"thèmes habituels.\n" +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "Passer directement à la fenêtre précédente" -#: ../src/core/muffin.c:40 -#, c-format -msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" -"muffin %s\n" -"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., et autres.\n" -"Ceci est un logiciel libre ; consultez le code source pour les\n" -"conditions de copie.\n" -"Il n'y a AUCUNE garantie ; même pas de VALEUR MARCHANDE ou\n" -"d'ADÉQUATION À UN USAGE PARTICULIER.\n" +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "Changer de fenêtre d’une application directement" -#: ../src/core/muffin.c:54 -msgid "Print version" -msgstr "Afficher la version" +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "Passer directement à la fenêtre précédente d’une application" -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "Liste de greffons de composition, séparés par des virgules" +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "Changer les contrôles système directement" -#: ../src/core/prefs.c:1077 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"Solutions de rechange désactivées pour les applications endommagées. " -"Certaines applications peuvent ne pas se comporter correctement.\n" +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "Passer directement au contrôle système précédent" -#: ../src/core/prefs.c:1152 -#, c-format -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "" -"Impossible d'analyser la description de police « %s » depuis la clé GSettings " -"%s\n" +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "Masquer toutes les fenêtres normales" -#: ../src/core/prefs.c:1218 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"« %s » trouvée dans la base de données de configuration n'est pas une valeur " -"correcte pour le bouton de souris\n" +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "Passer à l’espace de travail 1" -#: ../src/core/prefs.c:1739 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "" -"« %s » trouvé dans la base de données de configuration n'est pas une valeur " -"correcte pour la combinaison de touches « %s »\n" +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "Passer à l’espace de travail 2" -#: ../src/core/prefs.c:1836 -#, c-format -msgid "Workspace %d" -msgstr "Espace de travail %d" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "Passer à l’espace de travail 3" -#: ../src/core/screen.c:730 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "L'écran %d sur le visuel « %s » n'est pas valide\n" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "Passer à l’espace de travail 4" -#: ../src/core/screen.c:746 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"L'écran %d sur le visuel « %s » a déjà un gestionnaire de fenêtres ; essayez " -"d'utiliser l'option --replace pour remplacer le gestionnaire de fenêtres " -"actuel.\n" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "Passer au dernier espace de travail" -#: ../src/core/screen.c:773 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "" -"Impossible d'avoir la sélection du gestionnaire de fenêtres sur l'écran %d " -"du visuel « %s »\n" - -#: ../src/core/screen.c:828 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "L'écran %d sur le visuel « %s » a déjà un gestionnaire de fenêtres\n" - -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "Impossible de libérer l'écran %d sur le visuel « %s »\n" - -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Impossible de créer le répertoire « %s » : %s\n" +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "Déplacer vers l’espace de travail du dessus" -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "Impossible d'ouvrir le fichier de session « %s » en écriture : %s\n" +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "Déplacer vers l’espace de travail du dessous" -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Erreur lors de l'écriture du fichier de session « %s » : %s\n" +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "Système" -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Erreur lors de la fermeture du fichier de session « %s » : %s\n" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Afficher la fenêtre pour lancer une commande" -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "L'analyse du fichier de session enregistré a échoué : %s\n" - -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "" -"L'attribut <muffin_session> a été trouvé, mais nous possédons déjà l'ID de " -"session" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Afficher la vue d’ensemble des activités" -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Attribut %s inconnu sur l'élément <%s>" +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Restaurer les raccourcis clavier" -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "balise <window> imbriquée" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Fenêtres" -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "Élément %s inconnu" +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "Activer le menu fenêtre" -#: ../src/core/session.c:1809 -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" -"Ces fenêtres ne prennent pas en charge « l'enregistrement de la configuration " -"actuelle » et devront être redémarrées manuellement à la prochaine connexion." +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Basculer le mode plein écran" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "L'ouverture du journal de débogage a échoué : %s\n" +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "Basculer l’état d’agrandissement" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "" -"L'exécution de la commande fdopen() sur le fichier journal %s a échoué : %s\n" +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "Maximiser la fenêtre" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "Ouverture du fichier journal %s\n" +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Restaurer la fenêtre" -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "Muffin a été compilé sans la prise en charge du mode bavard\n" +#: data/50-mutter-windows.xml:18 +msgid "Close window" +msgstr "Fermer la fenêtre" -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "Gestionnaire de fenêtres : " +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "Masquer la fenêtre" -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "Anomalie dans le gestionnaire de fenêtres : " +#: data/50-mutter-windows.xml:22 +msgid "Move window" +msgstr "Déplacer la fenêtre" -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "Avertissement du gestionnaire de fenêtres : " +#: data/50-mutter-windows.xml:24 +msgid "Resize window" +msgstr "Redimensionner la fenêtre" -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "Erreur du gestionnaire de fenêtres : " +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "Placer la fenêtre sur tous les espaces de travail, ou sur un seul" -#. first time through -#: ../src/core/window.c:7266 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" msgstr "" -"La fenêtre %s positionne SM_CLIENT_ID sur elle-même, au lieu de le " -"positionner sur la fenêtre WM_CLIENT_LEADER tel qu'indiqué dans l'ICCCM.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7931 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %" -"d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"La fenêtre %s positionne un indice MWM indiquant qu'elle n'est pas " -"redimensionnable, mais positionne une taille minimale de %d x %d et une " -"taille maximale de %d x %d ; ceci n'a pas beaucoup de sens.\n" +"Mettre la fenêtre au premier plan si elle est cachée, sinon à l’arrière-plan" -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "L'application a défini un _NET_WM_PID %lu erroné\n" +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "Mettre la fenêtre au premier plan" -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (sur %s)" +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "Mettre la fenêtre sous les autres fenêtres" -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "Fenêtre WM_TRANSIENT_FOR 0x%lx non valide indiquée pour %s.\n" +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "Maximiser la fenêtre verticalement" -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "Fenêtre WM_TRANSIENT_FOR 0x%lx pour %s créerait une boucle.\n" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "Maximiser la fenêtre horizontalement" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"La fenêtre 0x%lx a la propriété %s\n" -"qui devrait avoir le type %s et le format %d\n" -"et a en fait le type %s et le format %d n_items %d\n" -"C'est probablement un bogue de l'application, et non du gestionnaire\n" -"de fenêtres.\n" -"Le titre de la fenêtre est=\"%s\" sa classe=\"%s\" et son nom=\"%s\"\n" - -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "" -"La propriété %s de la fenêtre 0x%lx contient un code UTF-8 non valide\n" +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "Vue divisée sur la gauche" -#: ../src/core/xprops.c:494 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"La propriété %s de la fenêtre 0x%lx contient un code UTF-8 non valide pour " -"l'élément %d dans la liste\n" +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "Vue divisée sur la droite" -#: ../src/muffin.desktop.in.h:1 ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 +#: data/org.gnome.mutter.gschema.xml.in:7 msgid "Modifier to use for extended window management operations" msgstr "Touche à utiliser pour les opérations étendues de gestion des fenêtres" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 +#: data/org.gnome.mutter.gschema.xml.in:8 msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." msgstr "" -"Cette touche initie l'« overlay », une combinaison d'aperçu des fenêtres et " -"d'un système de lancement d'applications. La touche par défaut sur le " +"Cette touche initie l’« overlay », une combinaison d’aperçu des fenêtres et " +"d’un système de lancement d’applications. La touche par défaut sur le " "matériel PC est la touche Windows. En principe, ce raccourci est configuré " "sur le réglage par défaut ou sur la chaîne vide." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 +#: data/org.gnome.mutter.gschema.xml.in:20 msgid "Attach modal dialogs" msgstr "Attacher les boîtes de dialogue modale" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 +#: data/org.gnome.mutter.gschema.xml.in:21 msgid "" "When true, instead of having independent titlebars, modal dialogs appear " "attached to the titlebar of the parent window and are moved together with " "the parent window." msgstr "" -"Si vrai, au lieu d'avoir des barres de titre indépendantes, les boîtes de " +"Si vrai, au lieu d’avoir des barres de titre indépendantes, les boîtes de " "dialogue apparaissent attachées à la barre de titre de la fenêtre parente et " "sont déplacées ensembles avec elle." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -msgid "Live Hidden Windows" -msgstr "Fenêtres masquées vivantes" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"Détermine si les fenêtres masquées (fenêtres réduites ou sur d'autres " -"espaces de travail) sont conservées « vivantes »." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 +#: data/org.gnome.mutter.gschema.xml.in:30 msgid "Enable edge tiling when dropping windows on screen edges" -msgstr "Activer l'empilage des fenêtres déposées sur les bords de l'écran" +msgstr "Activer l’empilage des fenêtres déposées sur les bords de l’écran" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 +#: data/org.gnome.mutter.gschema.xml.in:31 msgid "" "If enabled, dropping windows on vertical screen edges maximizes them " "vertically and resizes them horizontally to cover half of the available " "area. Dropping windows on the top screen edge maximizes them completely." msgstr "" -"Si activé, le dépôt des fenêtres sur les bords verticaux de l'écran les " +"Si activé, le dépôt des fenêtres sur les bords verticaux de l’écran les " "maximise verticalement et les redimensionne horizontalement pour recouvrir " "la moitié de la zone disponible. Le dépôt des fenêtres sur le bord supérieur " -"de l'écran les maximise complètement." +"de l’écran les maximise complètement." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 +#: data/org.gnome.mutter.gschema.xml.in:40 msgid "Workspaces are managed dynamically" msgstr "Les espaces de travail sont gérés de manière dynamique" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 +#: data/org.gnome.mutter.gschema.xml.in:41 msgid "" -"Determines whether workspaces are managed dynamically or whether there's a " +"Determines whether workspaces are managed dynamically or whether there’s a " "static number of workspaces (determined by the num-workspaces key in org." "gnome.desktop.wm.preferences)." msgstr "" "Détermine si les espaces de travail sont gérés de manière dynamique ou si le " -"nombre d'espaces de travail est fixe (déterminé par la clé num-workspaces " -"dans org.cinnamon.desktop.wm.preferences)." +"nombre d’espaces de travail est fixe (déterminé par la clé num-workspaces " +"dans org.gnome.desktop.wm.preferences)." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 +#: data/org.gnome.mutter.gschema.xml.in:50 msgid "Workspaces only on primary" -msgstr "Espaces de travail seulement sur l'écran principal" +msgstr "Espaces de travail seulement sur l’écran principal" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 +#: data/org.gnome.mutter.gschema.xml.in:51 msgid "" "Determines whether workspace switching should happen for windows on all " "monitors or only for windows on the primary monitor." msgstr "" -"Détermine si le changement d'espace de travail doit se produire pour les " -"fenêtres de tous les écrans ou seulement pour les fenêtres de l'écran " +"Détermine si le changement d’espace de travail doit se produire pour les " +"fenêtres de tous les écrans ou seulement pour les fenêtres de l’écran " "principal." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 +#: data/org.gnome.mutter.gschema.xml.in:59 msgid "No tab popup" msgstr "Aucune apparition suite à un appui sur la touche tab" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 +#: data/org.gnome.mutter.gschema.xml.in:60 msgid "" "Determines whether the use of popup and highlight frame should be disabled " "for window cycling." msgstr "" -"Détermine si l'utilisation de fenêtres surgissantes et de mise en valeur " +"Détermine si l’utilisation de fenêtres surgissantes et de mise en valeur " "doit être désactivée pour la consultation des fenêtres." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Attend l’arrêt du pointeur avant le changement de focus" + +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" +"Si défini à true et que le mode de focus est soit « sloppy » ou « souris », " +"alors le focus ne sera pas changé immédiatement en passant sur une fenêtre, " +"mais seulement après que le pointeur s’arrête." + +#: data/org.gnome.mutter.gschema.xml.in:79 msgid "Draggable border width" msgstr "Largeur de bordure ajustable" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 +#: data/org.gnome.mutter.gschema.xml.in:80 msgid "" -"The amount of total draggable borders. If the theme's visible borders are " +"The amount of total draggable borders. If the theme’s visible borders are " "not enough, invisible borders will be added to meet this value." msgstr "" -"La taille totale des bordures que l'on peut déplacer. Si les bordures " +"La taille totale des bordures que l’on peut déplacer. Si les bordures " "visibles du thème ne sont pas suffisantes, des bordures invisibles sont " "ajoutées pour arriver à cette valeur." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:17 -msgid "Select window from tab popup" -msgstr "" -"Sélectionner la fenêtre dans la vue qui apparaît suite à un appui sur la " -"touche tab" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:18 -msgid "Cancel tab popup" -msgstr "Fermer la vue qui apparaît suite à un appui sur la touche tab" - -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "Utilisation : %s\n" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "Réd_uire" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "Ma_ximiser" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "R_estaurer" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "Repl_ier" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "_Déplier" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "Dé_placer" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "_Redimensionner" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "Déplacer la barre de titre sur l'é_cran" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "Au premier _plan" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "_Toujours sur l'espace de travail visible" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "_Seulement sur cet espace de travail" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "Déplacer vers l'espace de travail de _gauche" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "Déplacer vers l'espace de travail de _droite" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "Déplacer vers l'espace de travail du dess_us" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "Déplacer vers l'espace de travail du dess_ous" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "_Fermer" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "Espace de travail %d%n" - -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "Espace de travail 1_0" - -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "Espace de travail %s%d" - -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "Déplacer vers un _autre espace de travail" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" - -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" - -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "haut" - -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "bas" - -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "gauche" - -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "droite" - -#: ../src/ui/theme.c:286 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "la géométrie du cadre n'indique pas la dimension « %s »" - -#: ../src/ui/theme.c:305 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "" -"la géométrie du cadre n'indique pas la dimension « %s » pour la bordure « %s »" - -#: ../src/ui/theme.c:342 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "La proportion du bouton %g n'est pas raisonnable" - -#: ../src/ui/theme.c:354 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "La géométrie du cadre n'indique pas la taille des boutons" - -#: ../src/ui/theme.c:1067 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "Les dégradés doivent comporter au moins deux couleurs" - -#: ../src/ui/theme.c:1219 -#, c-format -msgid "" -"GTK custom color specification must have color name and fallback in " -"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" -msgstr "" -"Une spécification de couleur personnalisée GTK doit comporter un nom de " -"couleur et un substitut entre parenthèses, par ex. gtk:custom(foo,bar) ; " -"impossible d'analyser « %s »" - -#: ../src/ui/theme.c:1235 -#, c-format -msgid "" -"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" -"_ are valid" -msgstr "" -"Caractère « %c » non valide dans le paramètre color_name de gtk:custom, seuls " -"A-Za-z0-9-_ sont acceptés" - -#: ../src/ui/theme.c:1249 -#, c-format -msgid "" -"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " -"fit the format" -msgstr "" -"Le format de gtk:custom est « gtk:custom(nom_couleur,substitut) », « %s » ne " -"correspond pas à ce format" - -#: ../src/ui/theme.c:1294 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"La spécification de couleur GTK doit présenter l'état entre crochets, p. ex. " -"gtk:fg[NORMAL] où NORMAL est l'état ; impossible d'analyser « %s »" - -#: ../src/ui/theme.c:1308 -#, c-format -msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"La spécification de couleur GTK doit comporter un crochet de fermeture après " -"l'état, p. ex. gtk:fg[NORMAL] où NORMAL est l'état ; impossible d'analyser « %" -"s »" - -#: ../src/ui/theme.c:1319 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "Impossible de comprendre l'état « %s » dans la spécification de couleur" - -#: ../src/ui/theme.c:1332 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "" -"Impossible de comprendre le composant de couleur « %s » dans la spécification " -"de couleur" - -#: ../src/ui/theme.c:1361 -#, c-format -msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" -msgstr "" -"Le format de mélange est « blend/bg_color/fg_color/alpha », « %s » ne " -"correspond pas à ce format ." - -#: ../src/ui/theme.c:1372 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "Impossible d'analyser la valeur alpha « %s » en couleur mélangée" - -#: ../src/ui/theme.c:1382 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "" -"La valeur alpha « %s » en couleur mélangée n'est pas comprise entre 0,0 et 1,0" - -#: ../src/ui/theme.c:1429 -#, c-format -msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "" -"Le format d'ombre est « shade/base_color/factor », « %s » ne correspond pas au " -"format" - -#: ../src/ui/theme.c:1440 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "Impossible d'analyser le facteur d'ombre « %s » en couleur ombrée" - -#: ../src/ui/theme.c:1450 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "Le facteur d'ombre « %s » en couleur ombrée est négatif" - -#: ../src/ui/theme.c:1479 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Impossible d'analyser la couleur « %s »" - -#: ../src/ui/theme.c:1790 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "" -"L'expression de la coordonnée contient le caractère « %s » qui n'est pas " -"autorisé" - -#: ../src/ui/theme.c:1817 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "" -"L'expression de la coordonnée contient la valeur en virgule flottante « %s » " -"qui ne peut pas être analysée" - -#: ../src/ui/theme.c:1831 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "" -"L'expression de la coordonnée contient l'entier « %s » qui n'a pas pu être " -"analysé" - -#: ../src/ui/theme.c:1953 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "" -"L'expression de la coordonnée contenait un opérateur inconnu au début de ce " -"texte : « %s »" - -#: ../src/ui/theme.c:2010 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "L'expression de la coordonnée était vide ou incomprise" - -#: ../src/ui/theme.c:2121 ../src/ui/theme.c:2131 ../src/ui/theme.c:2165 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "L'expression de la coordonnée entraîne une division par zéro" - -#: ../src/ui/theme.c:2173 -#, c-format -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" msgstr "" -"L'expression de la coordonnée tente d'utiliser l'opérateur mod sur une " -"valeur en virgule flottante" +"Maximiser automatiquement les fenêtres dont la taille est proche de celle de " +"l’écran" -#: ../src/ui/theme.c:2229 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:90 msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." msgstr "" -"L'expression de la coordonnée a un opérateur « %s » là où un opérande était " -"attendu" +"Si activé, les nouvelles fenêtres qui ont presque la taille de l’écran à " +"l’ouverture seront maximisées automatiquement." -#: ../src/ui/theme.c:2238 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "" -"L'expression de la coordonnée a un opérande là où un opérateur était attendu" +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Placer les nouvelles fenêtres au centre" -#: ../src/ui/theme.c:2246 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "" -"L'expression de la coordonnée était terminée par un opérateur au lieu d'un " -"opérande" - -#: ../src/ui/theme.c:2256 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:99 msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" -"L'expression de la coordonnée a un opérateur « %c » suivant l'opérateur « %c » " -"sans opérande entre eux" - -#: ../src/ui/theme.c:2407 ../src/ui/theme.c:2452 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "" -"L'expression de la coordonnée possède une variable ou constante inconnue « %" -"s »" - -#: ../src/ui/theme.c:2506 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "" -"L'analyseur d'expression de coordonnées a dépassé la capacité de son tampon." - -#: ../src/ui/theme.c:2535 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." msgstr "" -"L'expression de la coordonnée comporte une parenthèse de fermeture, mais pas " -"de parenthèse d'ouverture" +"Si true (vrai), les nouvelles fenêtres seront toujours placées au centre de " +"l’écran actif du moniteur." -#: ../src/ui/theme.c:2599 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "" -"L'expression de la coordonnée comporte une parenthèse d'ouverture, mais pas " -"de parenthèse de fermeture" - -#: ../src/ui/theme.c:2610 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "" -"L'expression de la coordonnée ne semble pas comprendre d'opérateur ni " -"d'opérande" - -#: ../src/ui/theme.c:2822 ../src/ui/theme.c:2842 ../src/ui/theme.c:2862 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "Le thème contient une expression qui a entraîné une erreur : %s\n" +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Activer les fonctionnalités expérimentales" -#: ../src/ui/theme.c:4533 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:108 msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes " +"mutter request a low priority real-time scheduling. The executable or user " +"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — " +"initializes Xwayland lazily if there are X11 clients. Requires restart." msgstr "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> doit être " -"indiqué pour ce style de cadre" +"Pour activer les fonctionnalités expérimentales, ajoutez le mot-clé de la " +"fonctionnalité dans la liste. Selon la fonctionnalité, il peut être " +"nécessaire de redémarrer le compositeur. Chaque fonctionnalité expérimentale " +"peut disparaître ou ne plus être configurable. Ne vous attendez pas à ce que " +"le contenu de ce réglage soit stable dans le temps. Les mots-clés " +"actuellement possibles sont : • « scale-monitor-framebuffer » — demande à " +"mutter d’utiliser par défaut une disposition par moniteur logique dans un " +"espace de coordonnées de pixels logique, tout en mettant à l’échelle les " +"« framebuffers » de moniteur au lieu des contenus de fenêtre pour pouvoir " +"gérer les moniteurs à haute densité. Cela ne nécessite pas de redémarrage. • " +"« rt-scheduler » — indique à mutter de demander un ordonnancement temps réel " +"à faible priorité. L’exécutable ou l’utilisateur doit avoir CAP_SYS_NICE. " +"Nécessite un redémarrage. • « autostart-xwayland » — initialise Xwayland de " +"manière différée s’il y a des clients X11. Nécessite un redémarrage." -#: ../src/ui/theme.c:5066 ../src/ui/theme.c:5091 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" -"<frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/> manquant" +#: data/org.gnome.mutter.gschema.xml.in:134 +msgid "Modifier to use to locate the pointer" +msgstr "Touche à utiliser pour situer le pointeur" -#: ../src/ui/theme.c:5139 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Impossible de charger le thème « %s » : %s\n" +#: data/org.gnome.mutter.gschema.xml.in:135 +msgid "This key will initiate the “locate pointer” action." +msgstr "Cette clé initie l’action « situer le pointeur »." -#: ../src/ui/theme.c:5275 ../src/ui/theme.c:5282 ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 ../src/ui/theme.c:5303 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "Aucun <%s> défini pour le thème « %s »" +#: data/org.gnome.mutter.gschema.xml.in:142 +msgid "Timeout for check-alive ping" +msgstr "Temps d’attente du ping de vérification d’activité" -#: ../src/ui/theme.c:5311 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:143 msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" +"Number of milliseconds a client has to respond to a ping request in order to " +"not be detected as frozen. Using 0 will disable the alive check completely." msgstr "" -"Aucun style de cadre défini pour le type de fenêtre « %s » dans le thème « %" -"s », ajoutez un élément <window type=\"%s\" style_set=\"whatever\"/>" +"Nombre de millisecondes dont dispose un client pour répondre à une requête " +"ping et ne pas être considéré comme figé. Utiliser 0 désactivera " +"complètement la vérification d’activité." -#: ../src/ui/theme.c:5709 ../src/ui/theme.c:5771 ../src/ui/theme.c:5834 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" +#: data/org.gnome.mutter.gschema.xml.in:165 +msgid "Select window from tab popup" msgstr "" -"Les constantes définies par l'utilisateur doivent commencer par une " -"majuscule ; « %s » commence par une minuscule" +"Sélectionner la fenêtre dans la vue qui apparaît suite à un appui sur la " +"touche tab" -#: ../src/ui/theme.c:5717 ../src/ui/theme.c:5779 ../src/ui/theme.c:5842 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "La constante « %s » a déjà été définie" +#: data/org.gnome.mutter.gschema.xml.in:170 +msgid "Cancel tab popup" +msgstr "Fermer la vue qui apparaît suite à un appui sur la touche tab" -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. +#: data/org.gnome.mutter.gschema.xml.in:175 +msgid "Switch monitor configurations" +msgstr "Changer de configuration de moniteur" + +#: data/org.gnome.mutter.gschema.xml.in:180 +msgid "Rotates the built-in monitor configuration" +msgstr "Passe à la prochaine configuration intégrée de moniteur" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Passer à l’émulateur de terminal 1" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Passer à l’émulateur de terminal 2" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Passer à l’émulateur de terminal 3" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Passer à l’émulateur de terminal 4" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Passer à l’émulateur de terminal 5" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Passer à l’émulateur de terminal 6" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Passer à l’émulateur de terminal 7" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Passer à l’émulateur de terminal 8" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Passer à l’émulateur de terminal 9" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Passer à l’émulateur de terminal 10" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Passer à l’émulateur de terminal 11" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Passer à l’émulateur de terminal 12" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "Réactiver les raccourcis" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow X11 grabs to lock keyboard focus with Xwayland" +msgstr "" +"Autoriser les captures X11 à verrouiller le focus du clavier avec Xwayland" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 +msgid "" +"Allow all keyboard events to be routed to X11 “override redirect” windows " +"with a grab when running in Xwayland. This option is to support X11 clients " +"which map an “override redirect” window (which do not receive keyboard " +"focus) and issue a keyboard grab to force all keyboard events to that " +"window. This option is seldom used and has no effect on regular X11 windows " +"which can receive keyboard focus under normal circumstances. For a X11 grab " +"to be taken into account under Wayland, the client must also either send a " +"specific X11 ClientMessage to the root window or be among the applications " +"white-listed in key “xwayland-grab-access-rules”." +msgstr "" +"Permettre à tous les évènements clavier d’être routés vers les fenêtres X11 " +"« override redirect » avec capture lors du fonctionnement avec Xwayland. " +"Cette option permet de prendre en charge les clients X11 qui gèrent une " +"fenêtre « override redirect » (qui ne reçoit pas de focus clavier) et " +"produisent une capture clavier pour forcer tous les évènements clavier vers " +"cette fenêtre. Cette option est rarement utilisée et n’a aucun effet sur les " +"fenêtres X11 normales qui peuvent recevoir le focus du clavier dans des " +"circonstances normales. Pour qu’une capture X11 soit prise en compte sous " +"Wayland, le client doit aussi soit envoyer un ClientMessage X11 spécifique à " +"la fenêtre racine, soit figurer parmi la liste blanche des applications dans " +"la clé « xwayland-grab-access-rules »." + +#: data/org.gnome.mutter.wayland.gschema.xml.in:84 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "Applications Xwayland autorisées à émettre des captures clavier" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:85 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "" +"Liste de noms de ressources ou de classes de ressources de fenêtres X11 " +"autorisées ou non à émettre des captures clavier sous Xwayland. Le nom ou la " +"classe de ressource d’une fenêtre X11 donnée peut être obtenue à l’aide de " +"la commande « xprop WM_CLASS ». Les caractères joker « * » et « ? » sont " +"acceptées dans les valeurs. Les valeurs commençant par « ! » sont en liste " +"noire, qui a priorité sur la liste blanche, pour révoquer les applications " +"de la liste système par défaut. Celle-ci contient les applications " +"suivantes : « @XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@ ». Les utilisateurs " +"peuvent casser une capture existante en utilisant le raccourci clavier " +"spécifique défini par la combinaison de touches « restore-shortcuts »." + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. #. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "Aucun attribut « %s » sur l'élément <%s>" - -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Ligne %d caractère %d: %s" - -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "Attribut « %s » répété deux fois sur le même élément <%s>" - -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "Attribut « %s » non valide sur l'élément <%s> dans ce contexte" - -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "Impossible d'analyser « %s » en tant qu'entier" - -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "Caractères de fin « %s » non compris dans la chaîne « %s »" - -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "L'entier %ld doit être positif" - -#: ../src/ui/theme-parser.c:621 +#: src/backends/meta-input-settings.c:2567 #, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "L'entier %ld est trop élevé, le max. actuel est %d" +msgid "Mode Switch (Group %d)" +msgstr "Changement de mode (groupe %d)" -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "Impossible d'analyser « %s » en tant que valeur en virgule flottante" +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2590 +msgid "Switch monitor" +msgstr "Changer de moniteur" -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "Les valeurs booléennes doivent être « true » ou « false » et non « %s »" +#: src/backends/meta-input-settings.c:2592 +msgid "Show on-screen help" +msgstr "Afficher l’aide à l’écran" -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "L'angle doit être compris entre 0,0 et 360,0. Il était de %g\n" +#: src/backends/meta-monitor.c:223 +msgid "Built-in display" +msgstr "Affichage intégré" -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" -"La valeur alpha doit être comprise entre 0,0 (invisible) et 1,0 (entièrement " -"opaque). Elle était de %g\n" +#: src/backends/meta-monitor.c:252 +msgid "Unknown" +msgstr "Inconnu" -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"Échelle de titre non valide « %s » (elle doit avoir l'une des valeurs " -"suivantes : xx-small, x-small, small, medium,large, x-large, xx-large)\n" - -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s> - nom « %s » utilisé une deuxième fois" +#: src/backends/meta-monitor.c:254 +msgid "Unknown Display" +msgstr "Affichage inconnu" -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 +#: src/backends/meta-monitor.c:262 #, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "<%s> - parent « %s » non défini" +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme-parser.c:1141 +#: src/backends/meta-monitor.c:270 #, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "<%s> - géométrie « %s » non définie" +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "<%s> doit indiquer une géométrie ou un parent qui en possède une" - -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "Vous devez indiquer une valeur pour le paramètre alpha." - -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Type inconnu « %s » sur l'élément <%s>" +#. Translators: this string will appear in Sysprof +#: src/backends/meta-profiler.c:79 +msgid "Compositor" +msgstr "Compositeur" -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "style_set inconnu « %s » sur l'élément <%s>" - -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "Le type de fenêtre « %s » s'est déjà vu attribuer un jeu de styles" - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:533 #, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "L'élément <%s> n'est pas autorisé sous <%s>" - -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" -msgstr "" -"Impossible d'indiquer à la fois « button_width » / « button_height » (largeur/" -"hauteur) et « aspect_ratio » (proportion) pour les boutons" - -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "Distance « %s » inconnue" - -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "Proportion « %s » inconnue" - -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "Bordure « %s » inconnue" - -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "" -"Aucun attribut « start_angle » (« début d'angle ») ou « from » (« depuis ») sur " -"l'élément <%s>" - -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" +"Another compositing manager is already running on screen %i on display “%s”." msgstr "" -"Aucun attribut « extent_angle » (« extension d'angle ») ou « to » (« vers ») sur " -"l'élément <%s>" +"Un autre gestionnaire de composition est déjà lancé sur l’écran %i de " +"l’affichage « %s »." -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "Impossible de comprendre la valeur « %s » pour le type de dégradé" - -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "" -"Impossible de comprendre le type de remplissage « %s » pour l'élément <%s>" - -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "Impossible de comprendre l'état « %s » pour l'élément <%s>" - -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "Impossible de comprendre l'ombre « %s » pour l'élément <%s>" - -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "Impossible de comprendre la flèche « %s » pour l'élément <%s>" +#: src/core/bell.c:192 +msgid "Bell event" +msgstr "Évènement sonore" -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "Aucun <draw_ops> appelé « %s » n'a été défini" +#: src/core/main.c:190 +msgid "Disable connection to session manager" +msgstr "Désactiver la connexion au gestionnaire de sessions" -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "L'inclusion du draw_ops « %s » ici créerait une référence circulaire" +#: src/core/main.c:196 +msgid "Replace the running window manager" +msgstr "Remplacer le gestionnaire de fenêtres en cours de fonctionnement" -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Position inconnue « %s » de la pièce du cadre" +#: src/core/main.c:202 +msgid "Specify session management ID" +msgstr "Indiquer l’ID de gestion de sessions" -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "Le style de cadre a déjà une pièce à la position %s" +#: src/core/main.c:207 +msgid "X Display to use" +msgstr "Affichage X à utiliser" -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "Aucun <draw_ops> avec le nom « %s » n'a été défini" +#: src/core/main.c:213 +msgid "Initialize session from savefile" +msgstr "Initialiser la session depuis le fichier de sauvegarde" -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Fonction inconnue « %s » pour le bouton" +#: src/core/main.c:219 +msgid "Make X calls synchronous" +msgstr "Rendre synchrones les appels à X" -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "" -"La fonction « %s » du bouton n'existe pas dans la version (%d, a besoin de %d)" +#: src/core/main.c:226 +msgid "Run as a wayland compositor" +msgstr "Lancer comme un compositeur wayland" -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "État inconnu « %s » pour le bouton" +#: src/core/main.c:232 +msgid "Run as a nested compositor" +msgstr "Lancer comme un compositeur imbriqué" -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "Le style de cadre a déjà un bouton pour la fonction %s, état %s" +#: src/core/main.c:238 +msgid "Run wayland compositor without starting Xwayland" +msgstr "Lancer le compositeur wayland sans démarrer Xwayland" -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "« %s » n'est pas une valeur valide pour l'attribut de focus" +#: src/core/main.c:246 +msgid "Run as a full display server, rather than nested" +msgstr "Lancer comme un serveur d’affichage complet, plutôt qu’imbriqué" -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "« %s » n'est pas une valeur valide pour l'attribut d'état" +#: src/core/main.c:252 +msgid "Run with X11 backend" +msgstr "Lancer avec le moteur X11" -#: ../src/ui/theme-parser.c:3092 +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:151 #, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "Aucun style appelé « %s » n'a été défini" +msgid "“%s” is not responding." +msgstr "« %s » ne répond pas." -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "« %s » n'est pas une valeur valide pour l'attribut de redimensionnement" +#: src/core/meta-close-dialog-default.c:153 +msgid "Application is not responding." +msgstr "L’application ne répond pas." -#: ../src/ui/theme-parser.c:3147 -#, c-format +#: src/core/meta-close-dialog-default.c:158 msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." msgstr "" -"L'attribut « resize » (« redimensionnement ») ne devrait pas figurer sur " -"l'élément <%s> pour les états maximisé/réduit dans la barre de titre" +"Vous pouvez patienter un instant pour continuer ou forcer l’application à " +"quitter définitivement." -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "" -"L'attribut « resize » (« redimensionnement ») ne devrait pas figurer sur " -"l'élément <%s> pour l'état maximisé" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Force Quit" +msgstr "_Forcer à quitter" -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "" -"Le style a déjà été indiqué pour l'état %s, redimensionnement %s, focus %s" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Wait" +msgstr "_Attendre" -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 +#: src/core/mutter.c:38 #, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "Le style a déjà été indiqué pour l'état %s, focus %s" - -#: ../src/ui/theme-parser.c:3294 msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Impossible d'avoir deux attributs draw_ops pour un élément <piece> (le thème " -"indiquait un attribut draw_ops et un élément <draw_ops> ou deux éléments)" - -#: ../src/ui/theme-parser.c:3332 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Impossible d'avoir deux attributs draw_ops pour un élément <button> (le " -"thème indiquait un attribut draw_ops et un élément <draw_ops> ou deux " -"éléments)" - -#: ../src/ui/theme-parser.c:3370 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" msgstr "" -"Impossible d'avoir deux attributs draw_ops pour un élément <menu_icon> (le " -"thème indiquait un attribut draw_ops et un élément <draw_ops> ou deux " -"éléments)" - -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "Mauvaise spécification de version « %s »" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., et autres.\n" +"Ceci est un logiciel libre ; consultez le code source pour les\n" +"conditions de copie.\n" +"Il n’y a AUCUNE garantie ; même pas de VALEUR MARCHANDE ou\n" +"d’ADÉQUATION À UN USAGE PARTICULIER.\n" -#: ../src/ui/theme-parser.c:3507 -msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" -msgstr "" -"L'attribut « version » ne peut pas être utilisé dans metacity-theme-1.xml or " -"metacity-theme-2.xml" +#: src/core/mutter.c:52 +msgid "Print version" +msgstr "Afficher la version" -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "" -"Le thème nécessite la version %s mais la version de thème la plus récente " -"prise en charge est %d.%d" +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "Greffon de Mutter à utiliser" -#: ../src/ui/theme-parser.c:3562 +#: src/core/prefs.c:1911 #, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "" -"L'élément le plus extérieur dans le thème doit être <metacity_theme> et non <" -"%s>" +msgid "Workspace %d" +msgstr "Espace de travail %d" -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "" -"L'élément <%s> n'est pas autorisé dans un élément name/author/date/" -"description" +#: src/core/util.c:122 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter a été compilé sans la prise en charge du mode bavard\n" -#: ../src/ui/theme-parser.c:3587 +#: src/wayland/meta-wayland-tablet-pad.c:568 #, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "L'élément <%s> n'est pas autorisé dans un élément <constant>" +msgid "Mode Switch: Mode %d" +msgstr "Changement de mode : mode %d" -#: ../src/ui/theme-parser.c:3599 +#: src/x11/meta-x11-display.c:676 #, c-format msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "" -"L'élément <%s> n'est pas autorisé dans un élément distance/border/" -"aspect_ratio" - -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." msgstr "" -"L'élément <%s> n'est pas autorisé dans un élément d'opération de dessin" - -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "L'élément <%s> n'est pas autorisé dans un élément <%s>" +"L’affichage « %s » a déjà un gestionnaire de fenêtres ; essayez d’utiliser " +"l’option --replace pour remplacer le gestionnaire de fenêtres actuel." -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "Aucun attribut draw_ops fourni pour la pièce du cadre" +#: src/x11/meta-x11-display.c:1089 +msgid "Failed to initialize GDK\n" +msgstr "L’initialisation de GDK a échoué\n" -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "Aucun attribut draw_ops fourni pour le bouton" - -#: ../src/ui/theme-parser.c:3968 +#: src/x11/meta-x11-display.c:1113 #, c-format -msgid "No text is allowed inside element <%s>" -msgstr "Aucun texte autorisé dans l'élément <%s>" +msgid "Failed to open X Window System display “%s”\n" +msgstr "Impossible d’ouvrir l’affichage « %s » du système X Window\n" -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 +#: src/x11/meta-x11-display.c:1196 #, c-format -msgid "<%s> specified twice for this theme" -msgstr "<%s> indiqué deux fois pour ce thème" +msgid "Screen %d on display “%s” is invalid\n" +msgstr "L’écran %d sur l’affichage « %s » n’est pas valide\n" -#: ../src/ui/theme-parser.c:4348 +#: src/x11/meta-x11-selection-input-stream.c:460 #, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Impossible de trouver un fichier valide pour le thème %s\n" - -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "_Fenêtres" - -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "_Boîte de dialogue" +msgid "Format %s not supported" +msgstr "Le format %s n’est pas pris en charge" -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "Boîte de dialogue _modale" - -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "_Utilitaire" - -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "Écr_an de démarrage" - -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "Panneau du _haut" - -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "Panneau du _bas" - -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "Panneau de _gauche" - -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "Panneau de _droite" - -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "_Tous les panneaux" - -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "_Bureau" - -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "Ouvrir une autre de ces fenêtres" - -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "C'est un bouton de démonstration avec une icône « Ouvrir »" - -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "C'est un bouton de démonstration avec une icône « Quitter »" - -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "C'est un message d'exemple dans une boîte de dialogue d'exemple" - -#: ../src/ui/theme-viewer.c:328 -#, c-format -msgid "Fake menu item %d\n" -msgstr "Élément de menu factice %d\n" - -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "Fenêtre avec seulement des bordures" - -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "Barre" - -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "Fenêtre d'application normale" - -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "Boîte de dialogue" - -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "Boîte de dialogue modale" - -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "Palette utilitaire" - -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "Menu détaché" - -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "Bordure" - -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "Boîte de dialogue modale liée" - -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "Test d'agencement de boutons %d" - -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g millisecondes pour dessiner un cadre de fenêtre" - -#: ../src/ui/theme-viewer.c:813 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Usage : metacity-theme-viewer [NOMDUTHEME]\n" - -#: ../src/ui/theme-viewer.c:820 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "Erreur lors du chargement du thème : %s\n" - -#: ../src/ui/theme-viewer.c:826 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "Thème « %s » chargé en %g secondes\n" - -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "Police de titre normal" - -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "Petite police de titre" - -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "Grande police de titre" - -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "Agencements des boutons" - -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "Performance" - -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "Le titre des fenêtres se trouve ici" - -#: ../src/ui/theme-viewer.c:1047 -#, c-format +#: src/x11/session.c:1821 msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." msgstr "" -"%d cadres furent dessinés en %g secondes du côté client (%g millisecondes " -"par cadre) et %g secondes passées dans les ressources du serveur X (%g " -"millisecondes par cadre)\n" +"Ces fenêtres ne prennent pas en charge « l’enregistrement de la " +"configuration actuelle » et devront être redémarrées manuellement à la " +"prochaine connexion." -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "" -"le test d'expression de position a retourné TRUE mais a signalé une erreur" - -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "" -"le test d'expression de position a retourné FALSE mais n'a pas signalé " -"d'erreur" - -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "Une erreur était attendue mais aucune n'a été retournée" - -#: ../src/ui/theme-viewer.c:1274 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "L'erreur %d était attendue mais %d est arrivée" - -#: ../src/ui/theme-viewer.c:1280 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "Aucune erreur n'était attendue mais une a été retournée : %s" - -#: ../src/ui/theme-viewer.c:1284 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "la valeur x était %d, %d était attendu" - -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "la valeur y était %d, %d était attendu" - -#: ../src/ui/theme-viewer.c:1352 +#: src/x11/window-props.c:569 #, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "" -"%d expressions de coordonnées analysées en %g secondes (%g secondes en " -"moyenne)\n" - +msgid "%s (on %s)" +msgstr "%s (sur %s)" diff --git a/po/fur.po b/po/fur.po new file mode 100644 index 000000000..eeab19428 --- /dev/null +++ b/po/fur.po @@ -0,0 +1,772 @@ +# Friulian translation for mutter. +# Copyright (C) 2016 mutter's COPYRIGHT HOLDER +# This file is distributed under the same license as the mutter package. +# Fabio Tomat <f.t.public@gmail.com>, 2016. +# +msgid "" +msgstr "" +"Project-Id-Version: mutter master\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2019-08-06 00:49+0000\n" +"PO-Revision-Date: 2019-09-03 09:53+0200\n" +"Last-Translator: Fabio Tomat <f.t.public@gmail.com>\n" +"Language-Team: Friulian <fur@li.org>\n" +"Language: fur\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.2.3\n" + +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Navigazion" + +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Sposte barcon tal spazi di lavôr 1" + +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Sposte barcon tal spazi di lavôr 2" + +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Sposte barcon tal spazi di lavôr 3" + +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Sposte barcon tal spazi di lavôr 4" + +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Sposte barcon tal ultin spazi di lavôr" + +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "Sposte barcon tal spazi di lavôr parsore" + +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "Sposte barcon tal spazi di lavôr sot" + +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "Sposte barcon tal visôr a çampe" + +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "Sposte barcon tal visôr a drete" + +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "Sposte barcon tal visôr parsore" + +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "Sposte barcon tal visôr sot" + +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "Passâ di une aplicazion in chê altre" + +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "Passe ae aplicazion prime" + +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "Passâ di un barcon in chel altri" + +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "Passe al barcon prime" + +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "Passâ di un barcon in chel altri di une aplicazion" + +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "Passe al barcon prime di une aplicazion" + +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "Passâ di un control di sisteme in chel altri" + +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "Passe al control di sisteme precedent" + +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "Passe dret ai barcons" + +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "Passe dret al barcon precedent" + +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "Passe dret a un barcon di une aplicazion" + +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "Passe dret al barcon precedent di une aplicazion" + +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "Passe dret ai controi dal sisteme" + +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "Passe dret al control precedent dal sisteme" + +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "Plate ducj i barcons normâi" + +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "Passe al spazi di lavôr 1" + +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "Passe al spazi di lavôr 2" + +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "Passe al spazi di lavôr 3" + +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "Passe al spazi di lavôr 4" + +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "Passe al ultin spazi di lavôr" + +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "Sposte il spazi di lavôr parsore" + +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "Sposte il spazi di lavôr sot" + +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "Sisteme" + +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Mostre la richieste “eseguìs comant”" + +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Mostre la panoramiche ativitâts" + +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Ripristine lis scurtis di tastiere" + +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Barcons" + +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "Ative il menù dal barcon" + +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Ative/Disative modalitât plen visôr" + +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "Ative/Disative il stât slargjât" + +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "Slargje il barcon" + +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Ripristine barcon" + +#: data/50-mutter-windows.xml:18 +msgid "Close window" +msgstr "Siere il barcon" + +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "Plate il barcon" + +#: data/50-mutter-windows.xml:22 +msgid "Move window" +msgstr "Sposte il barcon" + +#: data/50-mutter-windows.xml:24 +msgid "Resize window" +msgstr "Ridimensione barcon" + +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "Ative/Disative barcon su ducj i spazis di lavôr o nome un" + +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "Tire sù il barcon se al è cuviert, se no sbassilu" + +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "Met il barcon parsore di chei altris" + +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "Bute il barcon sot di chei altris" + +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "Slargje il barcon par verticâl" + +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "Slargje il barcon par orizontâl" + +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "Slargje dividint ae çampe" + +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "Slargje dividint ae drete" + +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" + +#: data/org.gnome.mutter.gschema.xml.in:7 +msgid "Modifier to use for extended window management operations" +msgstr "Modificadôr di doprâ pes operazions estesis di gjestion barcons" + +#: data/org.gnome.mutter.gschema.xml.in:8 +msgid "" +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." +msgstr "" +"Cheste clâf e tache il “overlay”, che e je une cumbinazion tra la " +"panoramiche dai barcons e il sisteme par inviâ lis aplicazions. Il valôr " +"predefinît al è pensât par jessi il “tast Windows” su hardware PC. Si spiete " +"che cheste scurte e sedi il valôr predefinît o une stringhe vueide." + +#: data/org.gnome.mutter.gschema.xml.in:20 +msgid "Attach modal dialogs" +msgstr "Dialics modâi tacâts" + +#: data/org.gnome.mutter.gschema.xml.in:21 +msgid "" +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." +msgstr "" +"Se metût a VÊR, invezit di vê sbaris di titul indipendentis, i dialics modâi " +"a semein tacâts ae sbare dal titul dal barcon gjenitôr e si spostin cun lui." + +#: data/org.gnome.mutter.gschema.xml.in:30 +msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "" +"Abilite il piastrelâ tal ôr cuant che si strissine i barcons tal ôr dal visôr" + +#: data/org.gnome.mutter.gschema.xml.in:31 +msgid "" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." +msgstr "" +"Se abilitade, strissinant i barcons sui ôrs verticâi dal schermi, i barcons " +"a vegnin slargjâts in verticâl e ridimensionâts in orizontâl, in mût di " +"cuvierzi metât dal spazi disponibil. Strissinant sul ôr superiôr dal schermi " +"al slargje i barcons dal dut." + +#: data/org.gnome.mutter.gschema.xml.in:40 +msgid "Workspaces are managed dynamically" +msgstr "I spazis di vore a son ministrât in maniere dinamiche" + +#: data/org.gnome.mutter.gschema.xml.in:41 +msgid "" +"Determines whether workspaces are managed dynamically or whether there’s a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." +msgstr "" +"Al determine se i spazis di lavôr a son gjestîts in maniere dinamiche o se " +"il lôr numar al è fis (determinât de clâf num-workspaces in org.gnome." +"desktop.wm.preferences)." + +#: data/org.gnome.mutter.gschema.xml.in:50 +msgid "Workspaces only on primary" +msgstr "Spazis di vore nome tal visôr primari" + +#: data/org.gnome.mutter.gschema.xml.in:51 +msgid "" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." +msgstr "" +"Determine se il cambi di spazi di lavôr al à di vignî pai barcons su ducj i " +"visôrs o nome pai barcons sul visôr primari." + +#: data/org.gnome.mutter.gschema.xml.in:59 +msgid "No tab popup" +msgstr "Nissun tab popup" + +#: data/org.gnome.mutter.gschema.xml.in:60 +msgid "" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." +msgstr "" +"Determine se disabilitâ l'ûs di popup e di curnîs di evidenziadure tal passâ " +"di un barcon a chel altri." + +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Tarde il cambiament dal focus fintremai che il puntadôr si ferme" + +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" +"Se metût a VÊR e la modalitât di focus e je metude a “sloppy” o “mouse” " +"alore il focus nol ven spostât subite cuant che si passe suntun barcon, ma " +"nome cuant che il puntadôr si ferme." + +#: data/org.gnome.mutter.gschema.xml.in:79 +msgid "Draggable border width" +msgstr "Largjece dal ôr che si pues strissinâ" + +#: data/org.gnome.mutter.gschema.xml.in:80 +msgid "" +"The amount of total draggable borders. If the theme’s visible borders are " +"not enough, invisible borders will be added to meet this value." +msgstr "" +"Il spessôr totâl pai ôrs che si puedin strissinâ. Se i ôrs visibii dal teme " +"no bastin, a vegnin zontâts dai ôrs invisibii par rivâ a chest valôr." + +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "Slargje in automatic i barcons grancj su par ju come il visôr" + +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" +"Se abilitât, i gnûfs barcons che a an al inizi la stesse dimension dal visôr " +"a vegnin slargjâts in automatic." + +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Place i gnûfs barcons tal mieç" + +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" +"Se metût a VÊR, i gnûfs barcons a vegnaran plaçâts simpri tal mieç dal " +"schermi atîf dal visôr." + +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Abilite funzionalitâts sperimentâls" + +#: data/org.gnome.mutter.gschema.xml.in:108 +msgid "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes " +"mutter request a low priority real-time scheduling. The executable or user " +"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — " +"initializes Xwayland lazily if there are X11 clients. Requires restart." +msgstr "" +"Par abilitâ lis funzionalitâts sperimentâls, zonte la peraule clâf de " +"funzionalitât ae liste. Il fat che la funzionalitât e vedi bisugne di tornâ " +"a inviâ il compositôr al dipent de funzionalitât dade. Cualsisei " +"funzionalitât sperimentâl no je necessarie che e sedi disponibile o " +"configurabile. No sta spietâti di zontâ alc in cheste impostazion e pensâ " +"che e duredi tal timp. Atualmentri lis peraulis clâf pussibilis a son: • " +"“scale-monitor-framebuffer” — al rint come predefinît par mutter, la " +"disposizion logjiche dai visôrs intun spazi logjic di coordenadis di pixel, " +"in plui si fâs il scjalâ dai framebuffer dai visôrs invezit che il contignût " +"dal barcon; dut chest par gjestî i visôrs HiDPI. Nol covente tornâ a inviâ. " +"• “rt-scheduler” — al fâs in mût che mutter al domandi une programazion in " +"timp reâl a prioritât basse. L'eseguibil o l'utent a scugnin vê " +"CAP_SYS_NICE. Al covente tornâ a inviâ. • “autostart-xwayland” — al " +"inizialize Xwayland in maniere sflacjose se a son presints clients X11. Al " +"covente tornâ a inviâ." + +#: data/org.gnome.mutter.gschema.xml.in:134 +msgid "Modifier to use to locate the pointer" +msgstr "Modificadôr di doprâ par localizâ il pontadôr" + +#: data/org.gnome.mutter.gschema.xml.in:135 +msgid "This key will initiate the “locate pointer” action." +msgstr "Cheste clâf e inizializerâ la azion “localize pontadôr”." + +#: data/org.gnome.mutter.gschema.xml.in:155 +msgid "Select window from tab popup" +msgstr "Selezione barcon dal tab popup" + +#: data/org.gnome.mutter.gschema.xml.in:160 +msgid "Cancel tab popup" +msgstr "Anule tab popup" + +#: data/org.gnome.mutter.gschema.xml.in:165 +msgid "Switch monitor configurations" +msgstr "Cambie configurazions visôr" + +#: data/org.gnome.mutter.gschema.xml.in:170 +msgid "Rotates the built-in monitor configuration" +msgstr "Al volte la configurazion dal visôr integrât" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Passe al VT 1" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Passe al VT 2" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Passe al VT 3" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Passe al VT 4" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Passe al VT 5" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Passe al VT 6" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Passe al VT 7" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Passe al VT 8" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Passe al VT 9" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Passe al VT 10" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Passe al VT 11" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Passe al VT 12" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "Torne abilite lis scurtis" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow X11 grabs to lock keyboard focus with Xwayland" +msgstr "" +"Permet aes cjapadis di control cun X11 di blocâ la focalizazion de tastiere " +"cun Xwayland" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 +msgid "" +"Allow all keyboard events to be routed to X11 “override redirect” windows " +"with a grab when running in Xwayland. This option is to support X11 clients " +"which map an “override redirect” window (which do not receive keyboard " +"focus) and issue a keyboard grab to force all keyboard events to that " +"window. This option is seldom used and has no effect on regular X11 windows " +"which can receive keyboard focus under normal circumstances. For a X11 grab " +"to be taken into account under Wayland, the client must also either send a " +"specific X11 ClientMessage to the root window or be among the applications " +"white-listed in key “xwayland-grab-access-rules”." +msgstr "" +"Cuant che a zire sot Xwayland, permet a ducj i events di tastiere di jessi " +"indreçâts sui barcons X11 “override redirect” cjapant il control de " +"tastiere. Cheste opzion e ven doprade di râr e no à efiets sui barcons " +"normâi di X11 che a puedin ricevi la concentrazion dai segnai de tastiere " +"sot circostancis normâls. Par une cjapade di control di X11, par che e sedi " +"tignude in considerazion sot Wayland, il client al scugne ancje o inviâ un " +"specific messaç (X11 ClientMessage) al barcon lidrîs o jessi tra lis " +"aplicazions metudis te liste blancje inte clâf “xwayland-grab-access-rules”." + +#: data/org.gnome.mutter.wayland.gschema.xml.in:84 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "Aplicazions Xwayland che a puedin cjapâ la tastiere" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:85 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "" +"Liste di nons di risorsis o classis di risorsis di barcons X11 che a puedin " +"o no puedin cjapâ i segnâi di tastiere X11 sot di Xwayland. Il non de " +"risorse o la classe de risorse di un dât barcon X11 al pues jessi otignût " +"doprant il comant “xprop WM_CLASS”. I caratars “*” e “?” tai valôrs a son " +"supuartâts. I valôrs che a tachin cun “!” a son metûts te liste nere, che e " +"à precedence su la liste blancje, par revocâ lis aplicazions de liste di " +"sisteme predefinide. La liste di sisteme predefinide e inclût lis " +"aplicazions chi daurman: “@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” I utents a " +"puedin interompi il control cjapât doprant la specifiche scurte di tastiere " +"definide de clâf di associazion tast “restore-shortcuts”." + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. +#. +#: src/backends/meta-input-settings.c:2531 +#, c-format +msgid "Mode Switch (Group %d)" +msgstr "Cambie mût (Grup %d)" + +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2554 +msgid "Switch monitor" +msgstr "Cambie visôr" + +#: src/backends/meta-input-settings.c:2556 +msgid "Show on-screen help" +msgstr "Mostre jutori a schermi" + +#: src/backends/meta-monitor.c:223 +msgid "Built-in display" +msgstr "Display integrât" + +#: src/backends/meta-monitor.c:252 +msgid "Unknown" +msgstr "No cognossût" + +#: src/backends/meta-monitor.c:254 +msgid "Unknown Display" +msgstr "Display no cognossût" + +#: src/backends/meta-monitor.c:262 +#, c-format +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" + +#: src/backends/meta-monitor.c:270 +#, c-format +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" + +#. Translators: this string will appear in Sysprof +#: src/backends/meta-profiler.c:82 +msgid "Compositor" +msgstr "Composidôr" + +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:510 +#, c-format +msgid "" +"Another compositing manager is already running on screen %i on display “%s”." +msgstr "" +"Un altri compositing manager al è za in esecuzion sul schermi %i sul display " +"“%s”." + +#: src/core/bell.c:192 +msgid "Bell event" +msgstr "Event cjampane" + +#: src/core/main.c:185 +msgid "Disable connection to session manager" +msgstr "Disabilite la conession al gjestôr de session" + +#: src/core/main.c:191 +msgid "Replace the running window manager" +msgstr "Rimplace il window manager in vore" + +#: src/core/main.c:197 +msgid "Specify session management ID" +msgstr "Specifiche il ID di gjestion session" + +#: src/core/main.c:202 +msgid "X Display to use" +msgstr "Display X di doprâ" + +#: src/core/main.c:208 +msgid "Initialize session from savefile" +msgstr "Inizialize session da file salvât" + +#: src/core/main.c:214 +msgid "Make X calls synchronous" +msgstr "Fâs lis clamadis X sincronis" + +#: src/core/main.c:221 +msgid "Run as a wayland compositor" +msgstr "Eseguìs come compositor wayland" + +#: src/core/main.c:227 +msgid "Run as a nested compositor" +msgstr "Eseguìs come compositor nidiât" + +#: src/core/main.c:233 +msgid "Run wayland compositor without starting Xwayland" +msgstr "Eseguìs il compositôr di wayland cence inviâ Xwayland" + +#: src/core/main.c:241 +msgid "Run as a full display server, rather than nested" +msgstr "Eseguìs come servidôr display complet, invezit che nidiât" + +#: src/core/main.c:247 +msgid "Run with X11 backend" +msgstr "Eseguìs cul backend X11" + +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:151 +#, c-format +msgid "“%s” is not responding." +msgstr "“%s” nol rispuint." + +#: src/core/meta-close-dialog-default.c:153 +msgid "Application is not responding." +msgstr "La aplicazion no rispuint." + +#: src/core/meta-close-dialog-default.c:158 +msgid "" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." +msgstr "" +"Al è pussibil sielzi di spietâ un pôc lassant che la aplicazion e continui o " +"sfuarçâ la aplicazion par sierâle dal dut." + +#: src/core/meta-close-dialog-default.c:165 +msgid "_Force Quit" +msgstr "Sfuarce _Jessude" + +#: src/core/meta-close-dialog-default.c:165 +msgid "_Wait" +msgstr "_Spiete" + +#: src/core/mutter.c:38 +#, c-format +msgid "" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" +msgstr "" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., e altris\n" +"Chest al è software libar; viodi i sorzints pes condizions di copie.\n" +"No je NISSUNE garanzie; nancje di CUMIERÇABILITÂT o IDONEITÂT A UNE " +"FINALITÂT PARTICOLÂR.\n" + +#: src/core/mutter.c:52 +msgid "Print version" +msgstr "Stampe version" + +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "Plugin Mutter di doprâ" + +#: src/core/prefs.c:1849 +#, c-format +msgid "Workspace %d" +msgstr "Spazi di lavôr %d" + +#: src/core/util.c:121 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter al è stât compilât cence supuart pe modalitât fetose\n" + +#: src/wayland/meta-wayland-tablet-pad.c:567 +#, c-format +msgid "Mode Switch: Mode %d" +msgstr "Cambie mût: mût %d" + +#: src/x11/meta-x11-display.c:671 +#, c-format +msgid "" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." +msgstr "" +"Il display “%s” al à za un window manager; prove dopre la opzion --replace " +"par rimplaçâ chel atuâl." + +#: src/x11/meta-x11-display.c:1032 +msgid "Failed to initialize GDK\n" +msgstr "No si è rivâts a inizializâ GDK\n" + +#: src/x11/meta-x11-display.c:1056 +#, c-format +msgid "Failed to open X Window System display “%s”\n" +msgstr "Impussibil vierzi il display “%s” di X Window System\n" + +#: src/x11/meta-x11-display.c:1140 +#, c-format +msgid "Screen %d on display “%s” is invalid\n" +msgstr "Schermi %d su display “%s” no valit\n" + +#: src/x11/meta-x11-selection-input-stream.c:445 +#, c-format +msgid "Format %s not supported" +msgstr "Il formât %s nol è supuartât" + +#: src/x11/session.c:1821 +msgid "" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." +msgstr "" +"Chescj barcons no supuartin la funzion “salve impostazions atuâls” e si " +"scugnarà tornâ a inviâlis a man tal prossim acès." + +#: src/x11/window-props.c:569 +#, c-format +msgid "%s (on %s)" +msgstr "%s (su %s)" + +#~ msgid "Move window one workspace to the left" +#~ msgstr "Sposte barcon tal spazi di lavôr a çampe" + +#~ msgid "Move window one workspace to the right" +#~ msgstr "Sposte barcon tal spazi di lavôr a drete" + +#~ msgid "Move to workspace left" +#~ msgstr "Sposte il spazi di lavôr a çampe" + +#~ msgid "Move to workspace right" +#~ msgstr "Sposte il spazi di lavôr a drete" + +#~ msgid "Toggle shaded state" +#~ msgstr "Ative/Disative stât inrodolât" diff --git a/po/ga.po b/po/ga.po index 73c56a7c9..d4e677dfe 100644 --- a/po/ga.po +++ b/po/ga.po @@ -1,403 +1,494 @@ # Irish translations for metacity package. -# Copyright (C) 2003-2008 Free Software Foundation Inc. +# Copyright (C) 2003-2013 Free Software Foundation Inc. # This file is distributed under the same license as the metacity package. # Paul Duffy <dubhthach@zion.nuigalway.ie>, 2003. # Alastair McKinstry <mckinstry@debian.org>, 2004. -# Seán de Búrca <leftmostcat@gmail.com>, 2007-2008. +# Seán de Búrca <leftmostcat@gmail.com>, 2007-2013. # msgid "" msgstr "" -"Project-Id-Version: metacity HEAD\n" +"Project-Id-Version: mutter.master\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-09-06 22:24-0400\n" -"PO-Revision-Date: 2008-09-06 22:24-0500\n" +"POT-Creation-Date: 2013-08-26 04:19-0600\n" +"PO-Revision-Date: 2013-08-26 04:30-0600\n" "Last-Translator: Seán de Búrca <leftmostcat@gmail.com>\n" "Language-Team: Irish <gaeilge-gnulinux@lists.sourceforge.net>\n" +"Language: ga\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=5; plural=n==1 ? 0 : (n%10==1 || n%10==2) ? 1 : (n%" -"10>=3 && n%10<= 6) ? 2 : ((n%10>=7 && n%10<=9) || n==10) ? 3 : 4;\n" +"Plural-Forms: nplurals=5; plural=n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n<11 ? 3 : " +"4;\n" -#: ../src/50-metacity-desktop-key.xml.in.h:1 -msgid "Desktop" -msgstr "Deasc" +#: ../src/50-mutter-navigation.xml.in.h:1 +msgid "Navigation" +msgstr "" -#: ../src/50-metacity-key.xml.in.h:1 -msgid "Window Management" -msgstr "Bainisteoireacht Fuinneog" +#: ../src/50-mutter-navigation.xml.in.h:2 +msgid "Move window to workspace 1" +msgstr "Bog fuinneog go spás oibre 1" -#: ../src/core/core.c:206 -#, c-format -msgid "Unknown window information request: %d" +#: ../src/50-mutter-navigation.xml.in.h:3 +msgid "Move window to workspace 2" +msgstr "Bog fuinneog go spás oibre 2" + +#: ../src/50-mutter-navigation.xml.in.h:4 +msgid "Move window to workspace 3" +msgstr "Bog fuinneog go spás oibre 3" + +#: ../src/50-mutter-navigation.xml.in.h:5 +msgid "Move window to workspace 4" +msgstr "Bog fuinneog go spás oibre 4" + +#: ../src/50-mutter-navigation.xml.in.h:6 +msgid "Move window one workspace to the left" +msgstr "Bog fuinneog spás oibre ar chlé" + +#: ../src/50-mutter-navigation.xml.in.h:7 +msgid "Move window one workspace to the right" +msgstr "Bog fuinneog spás oibre ar dheis" + +#: ../src/50-mutter-navigation.xml.in.h:8 +msgid "Move window one workspace up" +msgstr "Bog fuinneog spás oibre suas" + +#: ../src/50-mutter-navigation.xml.in.h:9 +msgid "Move window one workspace down" +msgstr "Bog fuinneog spás oibre síos" + +#: ../src/50-mutter-navigation.xml.in.h:10 +msgid "Switch applications" +msgstr "Athraigh feidhmchlár" + +#: ../src/50-mutter-navigation.xml.in.h:11 +msgid "Switch windows" +msgstr "Athraigh fuinneog" + +#: ../src/50-mutter-navigation.xml.in.h:12 +msgid "Switch windows of an application" +msgstr "Athraigh fuinneog fheidhmchláir" + +#: ../src/50-mutter-navigation.xml.in.h:13 +msgid "Switch system controls" msgstr "" -#: ../src/core/delete.c:70 ../src/core/delete.c:97 -#: ../src/ui/metacity-dialog.c:50 ../src/ui/theme-parser.c:481 -#, c-format -msgid "Could not parse \"%s\" as an integer" +#: ../src/50-mutter-navigation.xml.in.h:14 +msgid "Switch windows directly" msgstr "" -#: ../src/core/delete.c:77 ../src/core/delete.c:104 -#: ../src/ui/metacity-dialog.c:57 ../src/ui/theme-parser.c:490 -#: ../src/ui/theme-parser.c:545 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +#: ../src/50-mutter-navigation.xml.in.h:15 +msgid "Switch windows of an app directly" msgstr "" -#: ../src/core/delete.c:135 -#, c-format -msgid "Failed to parse message \"%s\" from dialog process\n" +#: ../src/50-mutter-navigation.xml.in.h:16 +msgid "Switch system controls directly" msgstr "" -#: ../src/core/delete.c:253 -#, c-format -msgid "Error reading from dialog display process: %s\n" +#: ../src/50-mutter-navigation.xml.in.h:17 +msgid "Hide all normal windows" msgstr "" -#: ../src/core/delete.c:336 -#, c-format -msgid "" -"Error launching metacity-dialog to ask about killing an application: %s\n" +#: ../src/50-mutter-navigation.xml.in.h:18 +msgid "Switch to workspace 1" +msgstr "Athraigh go spás oibre 1" + +#: ../src/50-mutter-navigation.xml.in.h:19 +msgid "Switch to workspace 2" +msgstr "Athraigh go spás oibre 2" + +#: ../src/50-mutter-navigation.xml.in.h:20 +msgid "Switch to workspace 3" +msgstr "Athraigh go spás oibre 3" + +#: ../src/50-mutter-navigation.xml.in.h:21 +msgid "Switch to workspace 4" +msgstr "Athraigh go spás oibre 4" + +#: ../src/50-mutter-navigation.xml.in.h:22 +msgid "Move to workspace left" +msgstr "Bog go spás oibre ar chlé" + +#: ../src/50-mutter-navigation.xml.in.h:23 +msgid "Move to workspace right" +msgstr "Bog go spás oibre ar dheis" + +#: ../src/50-mutter-navigation.xml.in.h:24 +msgid "Move to workspace above" +msgstr "Bog go spás oibre os cionn" + +#: ../src/50-mutter-navigation.xml.in.h:25 +msgid "Move to workspace below" +msgstr "Bog go spás oibre faoi bhun" + +#: ../src/50-mutter-system.xml.in.h:1 +msgid "System" +msgstr "Córas" + +#: ../src/50-mutter-system.xml.in.h:2 +msgid "Show the run command prompt" msgstr "" -#: ../src/core/delete.c:445 -#, c-format -msgid "Failed to get hostname: %s\n" -msgstr "Teip ag leámh óstainm: %s\n" +#: ../src/50-mutter-system.xml.in.h:3 +msgid "Show the activities overview" +msgstr "" -#: ../src/core/display.c:256 -#, c-format -msgid "Missing %s extension required for compositing" +#: ../src/50-mutter-windows.xml.in.h:1 +msgid "Windows" +msgstr "Fuinneoga" + +#: ../src/50-mutter-windows.xml.in.h:2 +msgid "Activate the window menu" msgstr "" -#: ../src/core/display.c:334 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Teipeadh ag oscailt scathán Corás Fhunneoga X '%s'\n" +#: ../src/50-mutter-windows.xml.in.h:3 +msgid "Toggle fullscreen mode" +msgstr "" -#: ../src/core/errors.c:272 +#: ../src/50-mutter-windows.xml.in.h:4 +msgid "Toggle maximization state" +msgstr "" + +#: ../src/50-mutter-windows.xml.in.h:5 +msgid "Maximize window" +msgstr "Uasmhéadaigh fuinneog" + +#: ../src/50-mutter-windows.xml.in.h:6 +msgid "Restore window" +msgstr "Athchóirigh fuinneog" + +#: ../src/50-mutter-windows.xml.in.h:7 +msgid "Toggle shaded state" +msgstr "" + +#: ../src/50-mutter-windows.xml.in.h:8 +msgid "Close window" +msgstr "Dún fuinneog" + +#: ../src/50-mutter-windows.xml.in.h:9 +msgid "Hide window" +msgstr "Folaigh fuinneog" + +#: ../src/50-mutter-windows.xml.in.h:10 +msgid "Move window" +msgstr "Bog fuinneog" + +#: ../src/50-mutter-windows.xml.in.h:11 +msgid "Resize window" +msgstr "Athmhéadaigh fuinneog" + +#: ../src/50-mutter-windows.xml.in.h:12 +msgid "Toggle window on all workspaces or one" +msgstr "Scoránaigh fuinneog ar gach spás oibre nó ceann amháin" + +#: ../src/50-mutter-windows.xml.in.h:13 +msgid "Raise window if covered, otherwise lower it" +msgstr "" + +#: ../src/50-mutter-windows.xml.in.h:14 +msgid "Raise window above other windows" +msgstr "" + +#: ../src/50-mutter-windows.xml.in.h:15 +msgid "Lower window below other windows" +msgstr "" + +#: ../src/50-mutter-windows.xml.in.h:16 +msgid "Maximize window vertically" +msgstr "" + +#: ../src/50-mutter-windows.xml.in.h:17 +msgid "Maximize window horizontally" +msgstr "" + +#: ../src/50-mutter-windows.xml.in.h:18 +msgid "View split on left" +msgstr "" + +#: ../src/50-mutter-windows.xml.in.h:19 +msgid "View split on right" +msgstr "" + +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: ../src/compositor/compositor.c:596 #, c-format msgid "" -"Lost connection to the display '%s';\n" -"most likely the X server was shut down or you killed/destroyed\n" -"the window manager.\n" +"Another compositing manager is already running on screen %i on display \"%s" +"\"." +msgstr "" + +#: ../src/compositor/meta-background.c:1076 +msgid "background texture could not be created from file" msgstr "" -#: ../src/core/errors.c:279 +#: ../src/core/bell.c:322 +msgid "Bell event" +msgstr "" + +#: ../src/core/core.c:157 #, c-format -msgid "Fatal IO error %d (%s) on display '%s'.\n" +msgid "Unknown window information request: %d" msgstr "" -#: ../src/core/keybindings.c:924 +#: ../src/core/delete.c:111 #, c-format +msgid "“%s” is not responding." +msgstr "" + +#: ../src/core/delete.c:113 +msgid "Application is not responding." +msgstr "" + +#: ../src/core/delete.c:118 msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." msgstr "" -#: ../src/core/keybindings.c:2563 +#: ../src/core/delete.c:125 +msgid "_Wait" +msgstr "_Fan" + +#: ../src/core/delete.c:125 +msgid "_Force Quit" +msgstr "Éignigh _Scor" + +#: ../src/core/display.c:422 #, c-format -msgid "Error launching metacity-dialog to print an error about a command: %s\n" +msgid "Missing %s extension required for compositing" msgstr "" -#: ../src/core/keybindings.c:2668 +#: ../src/core/display.c:514 #, c-format -msgid "No command %d has been defined.\n" -msgstr "" +msgid "Failed to open X Window System display '%s'\n" +msgstr "Teipeadh ag oscailt scathán Corás Fhunneoga X '%s'\n" -#: ../src/core/keybindings.c:3705 +#: ../src/core/keybindings.c:1136 #, c-format -msgid "No terminal command has been defined.\n" +msgid "" +"Some other program is already using the key %s with modifiers %x as a " +"binding\n" msgstr "" -#: ../src/core/main.c:116 +#: ../src/core/keybindings.c:1333 #, c-format -msgid "" -"metacity %s\n" -"Copyright (C) 2001-2008 Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" +msgid "\"%s\" is not a valid accelerator\n" msgstr "" -#: ../src/core/main.c:253 +#: ../src/core/main.c:197 msgid "Disable connection to session manager" msgstr "" -#: ../src/core/main.c:259 -msgid "Replace the running window manager with Metacity" +#: ../src/core/main.c:203 +msgid "Replace the running window manager" msgstr "" -#: ../src/core/main.c:265 +#: ../src/core/main.c:209 msgid "Specify session management ID" msgstr "" -#: ../src/core/main.c:270 +#: ../src/core/main.c:214 msgid "X Display to use" msgstr "Taispeáint X le húsáid" -#: ../src/core/main.c:276 +#: ../src/core/main.c:220 msgid "Initialize session from savefile" msgstr "" -#: ../src/core/main.c:282 -msgid "Print version" -msgstr "Priontáil leagan" - -#: ../src/core/main.c:288 +#: ../src/core/main.c:226 msgid "Make X calls synchronous" msgstr "Déan sioncronach glaonna X" -#: ../src/core/main.c:294 -msgid "Turn compositing on" -msgstr "" - -#: ../src/core/main.c:300 -msgid "Turn compositing off" -msgstr "" - -#: ../src/core/main.c:451 +#: ../src/core/main.c:534 #, c-format msgid "Failed to scan themes directory: %s\n" msgstr "Theip ar scanadh na comhadlainne théamaí: %s\n" -#: ../src/core/main.c:467 +#: ../src/core/main.c:550 #, c-format msgid "" "Could not find a theme! Be sure %s exists and contains the usual themes.\n" msgstr "" -#: ../src/core/main.c:526 -#, c-format -msgid "Failed to restart: %s\n" -msgstr "" +#: ../src/core/monitor.c:702 +msgid "Built-in display" +msgstr "Taispeáint ionsuite" +#. TRANSLATORS: this is a monitor name (in case we don't know +#. the vendor), it's Unknown followed by a size in inches, +#. like 'Unknown 15"' #. -#. * We found it, but it was invalid. Complain. -#. * -#. * FIXME: This replicates the original behaviour, but in the future -#. * we might consider reverting invalid keys to their original values. -#. * (We know the old value, so we can look up a suitable string in -#. * the symtab.) -#. -#: ../src/core/prefs.c:503 ../src/core/prefs.c:655 +#: ../src/core/monitor.c:730 #, c-format -msgid "GConf key '%s' is set to an invalid value\n" -msgstr "" +msgid "Unknown %s" +msgstr "Anaithnid %s" -#: ../src/core/prefs.c:584 ../src/core/prefs.c:824 +#: ../src/core/mutter.c:40 #, c-format -msgid "%d stored in GConf key %s is out of range %d to %d\n" +msgid "" +"mutter %s\n" +"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" msgstr "" -#: ../src/core/prefs.c:628 ../src/core/prefs.c:702 ../src/core/prefs.c:750 -#: ../src/core/prefs.c:814 ../src/core/prefs.c:1109 ../src/core/prefs.c:1125 -#: ../src/core/prefs.c:1144 ../src/core/prefs.c:1160 ../src/core/prefs.c:1177 -#: ../src/core/prefs.c:1193 -#, c-format -msgid "GConf key \"%s\" is set to an invalid type\n" +#: ../src/core/mutter.c:54 +msgid "Print version" +msgstr "Priontáil leagan" + +#: ../src/core/mutter.c:60 +msgid "Mutter plugin to use" msgstr "" -#: ../src/core/prefs.c:1263 +#: ../src/core/prefs.c:1202 msgid "" "Workarounds for broken applications disabled. Some applications may not " "behave properly.\n" msgstr "" -#: ../src/core/prefs.c:1333 +#: ../src/core/prefs.c:1277 #, c-format -msgid "Could not parse font description \"%s\" from GConf key %s\n" +msgid "Could not parse font description \"%s\" from GSettings key %s\n" msgstr "" -#: ../src/core/prefs.c:1393 +#: ../src/core/prefs.c:1343 #, c-format msgid "" "\"%s\" found in configuration database is not a valid value for mouse button " "modifier\n" msgstr "" -#: ../src/core/prefs.c:1810 -#, c-format -msgid "Error setting number of workspaces to %d: %s\n" -msgstr "" - -#: ../src/core/prefs.c:2131 ../src/core/prefs.c:2643 -#, c-format -msgid "Workspace %d" -msgstr "Spás Oibre %d" - -#: ../src/core/prefs.c:2161 ../src/core/prefs.c:2334 +#: ../src/core/prefs.c:1909 #, c-format msgid "" "\"%s\" found in configuration database is not a valid value for keybinding " "\"%s\"\n" msgstr "" -#: ../src/core/prefs.c:2724 -#, c-format -msgid "Error setting name for workspace %d to \"%s\": %s\n" -msgstr "" - -#: ../src/core/prefs.c:2917 +#: ../src/core/prefs.c:1999 #, c-format -msgid "Error setting compositor status: %s\n" -msgstr "" +msgid "Workspace %d" +msgstr "Spás Oibre %d" -#: ../src/core/screen.c:350 +#: ../src/core/screen.c:537 #, c-format msgid "Screen %d on display '%s' is invalid\n" msgstr "" -#: ../src/core/screen.c:366 +#: ../src/core/screen.c:553 #, c-format msgid "" "Screen %d on display \"%s\" already has a window manager; try using the --" "replace option to replace the current window manager.\n" msgstr "" -#: ../src/core/screen.c:393 +#: ../src/core/screen.c:580 #, c-format msgid "" "Could not acquire window manager selection on screen %d display \"%s\"\n" msgstr "" -#: ../src/core/screen.c:451 +#: ../src/core/screen.c:658 #, c-format msgid "Screen %d on display \"%s\" already has a window manager\n" msgstr "" -#: ../src/core/screen.c:661 +#: ../src/core/screen.c:850 #, c-format msgid "Could not release screen %d on display \"%s\"\n" msgstr "" -#: ../src/core/session.c:837 ../src/core/session.c:844 +#: ../src/core/session.c:843 ../src/core/session.c:850 #, c-format msgid "Could not create directory '%s': %s\n" msgstr "" -#: ../src/core/session.c:854 +#: ../src/core/session.c:860 #, c-format msgid "Could not open session file '%s' for writing: %s\n" msgstr "" -#: ../src/core/session.c:995 +#: ../src/core/session.c:1001 #, c-format msgid "Error writing session file '%s': %s\n" msgstr "" -#: ../src/core/session.c:1000 +#: ../src/core/session.c:1006 #, c-format msgid "Error closing session file '%s': %s\n" msgstr "" -#. oh, just give up -#: ../src/core/session.c:1093 -#, c-format -msgid "Failed to read saved session file %s: %s\n" -msgstr "" - -#: ../src/core/session.c:1132 +#: ../src/core/session.c:1136 #, c-format msgid "Failed to parse saved session file: %s\n" msgstr "" -#: ../src/core/session.c:1181 +#: ../src/core/session.c:1185 #, c-format -msgid "<metacity_session> attribute seen but we already have the session ID" +msgid "<mutter_session> attribute seen but we already have the session ID" msgstr "" -#: ../src/core/session.c:1194 +#: ../src/core/session.c:1198 ../src/core/session.c:1273 +#: ../src/core/session.c:1305 ../src/core/session.c:1377 +#: ../src/core/session.c:1437 #, c-format -msgid "Unknown attribute %s on <metacity_session> element" +msgid "Unknown attribute %s on <%s> element" msgstr "" -#: ../src/core/session.c:1211 +#: ../src/core/session.c:1215 #, c-format msgid "nested <window> tag" msgstr "" -#: ../src/core/session.c:1269 ../src/core/session.c:1301 -#, c-format -msgid "Unknown attribute %s on <window> element" -msgstr "" - -#: ../src/core/session.c:1373 -#, c-format -msgid "Unknown attribute %s on <maximized> element" -msgstr "" - -#: ../src/core/session.c:1433 -#, c-format -msgid "Unknown attribute %s on <geometry> element" -msgstr "" - -#: ../src/core/session.c:1453 +#: ../src/core/session.c:1457 #, c-format msgid "Unknown element %s" msgstr "" -#: ../src/core/session.c:1879 -#, c-format +#: ../src/core/session.c:1809 msgid "" -"Error launching metacity-dialog to warn about apps that don't support " -"session management: %s\n" +"These windows do not support "save current setup" and will have to " +"be restarted manually next time you log in." msgstr "" -#: ../src/core/util.c:101 +#: ../src/core/util.c:84 #, c-format msgid "Failed to open debug log: %s\n" msgstr "" -#: ../src/core/util.c:111 +#: ../src/core/util.c:94 #, c-format msgid "Failed to fdopen() log file %s: %s\n" msgstr "" -#: ../src/core/util.c:117 +#: ../src/core/util.c:100 #, c-format msgid "Opened log file %s\n" msgstr "D'oscail comhad loga %s\n" -#: ../src/core/util.c:136 ../src/tools/metacity-message.c:176 -#, c-format -msgid "Metacity was compiled without support for verbose mode\n" +#: ../src/core/util.c:119 +msgid "Mutter was compiled without support for verbose mode\n" msgstr "" -#: ../src/core/util.c:236 +#: ../src/core/util.c:264 msgid "Window manager: " -msgstr "Bainisteoir fuinneog:" +msgstr "Bainisteoir fuinneog: " -#: ../src/core/util.c:388 +#: ../src/core/util.c:414 msgid "Bug in window manager: " msgstr "" -#: ../src/core/util.c:421 +#: ../src/core/util.c:445 msgid "Window manager warning: " msgstr "" -#: ../src/core/util.c:449 +#: ../src/core/util.c:473 msgid "Window manager error: " msgstr "" -#: ../src/core/window-props.c:206 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "" - -#: ../src/core/window-props.c:338 -#, c-format -msgid "%s (on %s)" -msgstr "%s (ar %s)" - -#: ../src/core/window-props.c:1420 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "" - #. first time through -#: ../src/core/window.c:5643 +#: ../src/core/window.c:7533 #, c-format msgid "" "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " @@ -411,11 +502,31 @@ msgstr "" #. * MWM but not WM_NORMAL_HINTS are basically broken. We complain #. * about these apps but make them work. #. -#: ../src/core/window.c:6208 +#: ../src/core/window.c:8257 #, c-format msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %" -"d x %d and max size %d x %d; this doesn't make much sense.\n" +"Window %s sets an MWM hint indicating it isn't resizable, but sets min size " +"%d x %d and max size %d x %d; this doesn't make much sense.\n" +msgstr "" + +#: ../src/core/window-props.c:347 +#, c-format +msgid "Application set a bogus _NET_WM_PID %lu\n" +msgstr "" + +#: ../src/core/window-props.c:463 +#, c-format +msgid "%s (on %s)" +msgstr "%s (ar %s)" + +#: ../src/core/window-props.c:1546 +#, c-format +msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +msgstr "" + +#: ../src/core/window-props.c:1557 +#, c-format +msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" msgstr "" #: ../src/core/xprops.c:155 @@ -428,2620 +539,939 @@ msgid "" "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" msgstr "" -#: ../src/core/xprops.c:401 +#: ../src/core/xprops.c:411 #, c-format msgid "Property %s on window 0x%lx contained invalid UTF-8\n" msgstr "" -#: ../src/core/xprops.c:484 +#: ../src/core/xprops.c:494 #, c-format msgid "" "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" msgstr "" -#: ../src/metacity.desktop.in.h:1 -msgid "Metacity" -msgstr "Metacity" +#: ../src/mutter.desktop.in.h:1 ../src/mutter-wm.desktop.in.h:1 +msgid "Mutter" +msgstr "Mutter" -#: ../src/metacity.schemas.in.h:1 -msgid "(Not implemented) Navigation works in terms of applications not windows" +#: ../src/org.gnome.mutter.gschema.xml.in.h:1 +msgid "Modifier to use for extended window management operations" msgstr "" -#: ../src/metacity.schemas.in.h:2 +#: ../src/org.gnome.mutter.gschema.xml.in.h:2 msgid "" -"A font description string describing a font for window titlebars. The size " -"from the description will only be used if the titlebar_font_size option is " -"set to 0. Also, this option is disabled if the titlebar_uses_desktop_font " -"option is set to true." -msgstr "" - -#: ../src/metacity.schemas.in.h:3 -msgid "Action on title bar double-click" -msgstr "" - -#: ../src/metacity.schemas.in.h:4 -msgid "Action on title bar middle-click" -msgstr "" - -#: ../src/metacity.schemas.in.h:5 -msgid "Action on title bar right-click" -msgstr "" - -#: ../src/metacity.schemas.in.h:6 -msgid "Activate window menu" +"This key will initiate the \"overlay\", which is a combination window " +"overview and application launching system. The default is intended to be the " +"\"Windows key\" on PC hardware. It's expected that this binding either the " +"default or set to the empty string." msgstr "" -#: ../src/metacity.schemas.in.h:7 -msgid "Arrangement of buttons on the titlebar" +#: ../src/org.gnome.mutter.gschema.xml.in.h:3 +msgid "Attach modal dialogs" msgstr "" -#: ../src/metacity.schemas.in.h:8 +#: ../src/org.gnome.mutter.gschema.xml.in.h:4 msgid "" -"Arrangement of buttons on the titlebar. The value should be a string, such " -"as \"menu:minimize,maximize,spacer,close\"; the colon separates the left " -"corner of the window from the right corner, and the button names are comma-" -"separated. Duplicate buttons are not allowed. Unknown button names are " -"silently ignored so that buttons can be added in future metacity versions " -"without breaking older versions. A special spacer tag can be used to insert " -"some space between two adjacent buttons." +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." msgstr "" -#: ../src/metacity.schemas.in.h:9 -msgid "Automatically raises the focused window" +#: ../src/org.gnome.mutter.gschema.xml.in.h:5 +msgid "Enable edge tiling when dropping windows on screen edges" msgstr "" -#: ../src/metacity.schemas.in.h:10 +#: ../src/org.gnome.mutter.gschema.xml.in.h:6 msgid "" -"Clicking a window while holding down this modifier key will move the window " -"(left click), resize the window (middle click), or show the window menu " -"(right click). Modifier is expressed as \"<Alt>\" or \"<Super>\" " -"for example." -msgstr "" - -#: ../src/metacity.schemas.in.h:11 -msgid "Close window" -msgstr "Dún fuinneog" - -#: ../src/metacity.schemas.in.h:12 -msgid "Commands to run in response to keybindings" -msgstr "" - -#: ../src/metacity.schemas.in.h:13 -msgid "Compositing Manager" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." msgstr "" -#: ../src/metacity.schemas.in.h:14 -msgid "Control how new windows get focus" +#: ../src/org.gnome.mutter.gschema.xml.in.h:7 +msgid "Workspaces are managed dynamically" msgstr "" -#: ../src/metacity.schemas.in.h:15 -msgid "Current theme" -msgstr "" - -#: ../src/metacity.schemas.in.h:16 -msgid "Delay in milliseconds for the auto raise option" +#: ../src/org.gnome.mutter.gschema.xml.in.h:8 +msgid "" +"Determines whether workspaces are managed dynamically or whether there's a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." msgstr "" -#: ../src/metacity.schemas.in.h:17 -msgid "Determines whether Metacity is a compositing manager." +#: ../src/org.gnome.mutter.gschema.xml.in.h:9 +msgid "Workspaces only on primary" msgstr "" -#: ../src/metacity.schemas.in.h:18 +#: ../src/org.gnome.mutter.gschema.xml.in.h:10 msgid "" -"Determines whether applications or the system can generate audible 'beeps'; " -"may be used in conjunction with 'visual bell' to allow silent 'beeps'." +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." msgstr "" -#: ../src/metacity.schemas.in.h:19 -msgid "Disable misfeatures that are required by old or broken applications" +#: ../src/org.gnome.mutter.gschema.xml.in.h:11 +msgid "No tab popup" msgstr "" -#: ../src/metacity.schemas.in.h:20 -msgid "Enable Visual Bell" +#: ../src/org.gnome.mutter.gschema.xml.in.h:12 +msgid "" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." msgstr "" -#: ../src/metacity.schemas.in.h:21 -msgid "Hide all windows and focus desktop" +#: ../src/org.gnome.mutter.gschema.xml.in.h:13 +msgid "Delay focus changes until the pointer stops moving" msgstr "" -#: ../src/metacity.schemas.in.h:22 +#: ../src/org.gnome.mutter.gschema.xml.in.h:14 msgid "" "If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " -"the focused window will be automatically raised after a delay specified by " -"the auto_raise_delay key. This is not related to clicking on a window to " -"raise it, nor to entering a window during drag-and-drop." +"the focus will not be changed immediately when entering a window, but only " +"after the pointer stops moving." msgstr "" -#: ../src/metacity.schemas.in.h:23 -msgid "" -"If true, ignore the titlebar_font option, and use the standard application " -"font for window titles." -msgstr "" - -#: ../src/metacity.schemas.in.h:24 -msgid "" -"If true, metacity will give the user less feedback by using wireframes, " -"avoiding animations, or other means. This is a significant reduction in " -"usability for many users, but may allow legacy applications to continue " -"working, and may also be a useful tradeoff for terminal servers. However, " -"the wireframe feature is disabled when accessibility is on." +#: ../src/org.gnome.mutter.gschema.xml.in.h:15 +msgid "Draggable border width" msgstr "" -#: ../src/metacity.schemas.in.h:25 +#: ../src/org.gnome.mutter.gschema.xml.in.h:16 msgid "" -"If true, then Metacity works in terms of applications rather than windows. " -"The concept is a bit abstract, but in general an application-based setup is " -"more like the Mac and less like Windows. When you focus a window in " -"application-based mode, all the windows in the application will be raised. " -"Also, in application-based mode, focus clicks are not passed through to " -"windows in other applications. Application-based mode is, however, largely " -"unimplemented at the moment." +"The amount of total draggable borders. If the theme's visible borders are " +"not enough, invisible borders will be added to meet this value." msgstr "" -#: ../src/metacity.schemas.in.h:26 -msgid "If true, trade off usability for less resource usage" +#: ../src/org.gnome.mutter.gschema.xml.in.h:17 +msgid "Auto maximize nearly monitor sized windows" msgstr "" -#: ../src/metacity.schemas.in.h:27 -msgid "Lower window below other windows" -msgstr "" - -#: ../src/metacity.schemas.in.h:28 +#: ../src/org.gnome.mutter.gschema.xml.in.h:18 msgid "" -"Many actions (e.g. clicking in the client area, moving or resizing the " -"window) normally raise the window as a side-effect. Setting this option to " -"false, which is strongly discouraged, will decouple raising from other user " -"actions, and ignore raise requests generated by applications. See http://" -"bugzilla.gnome.org/show_bug.cgi?id=445447#c6." -msgstr "" - -#: ../src/metacity.schemas.in.h:29 -msgid "Maximize window" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." msgstr "" -#: ../src/metacity.schemas.in.h:30 -msgid "Maximize window horizontally" +#: ../src/org.gnome.mutter.gschema.xml.in.h:19 +msgid "Select window from tab popup" msgstr "" -#: ../src/metacity.schemas.in.h:31 -msgid "Maximize window vertically" +#: ../src/org.gnome.mutter.gschema.xml.in.h:20 +msgid "Cancel tab popup" msgstr "" -#: ../src/metacity.schemas.in.h:32 -msgid "Minimize window" -msgstr "" +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:67 +msgid "Mi_nimize" +msgstr "Íos_laghdaigh" -#: ../src/metacity.schemas.in.h:33 -msgid "Modifier to use for modified window click actions" -msgstr "" +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:69 +msgid "Ma_ximize" +msgstr "_Uasmhéadaigh" -#: ../src/metacity.schemas.in.h:34 -msgid "Move backward between panels and the desktop immediately" -msgstr "" +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:71 +msgid "Unma_ximize" +msgstr "Dí-uas_mhéadaigh" -#: ../src/metacity.schemas.in.h:35 -msgid "Move backwards between panels and the desktop with popup" -msgstr "" +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:73 +msgid "Roll _Up" +msgstr "Roll _Isteach" -#: ../src/metacity.schemas.in.h:36 -msgid "Move backwards between windows immediately" -msgstr "" +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:75 +msgid "_Unroll" +msgstr "Roll _Amach" -#: ../src/metacity.schemas.in.h:37 -msgid "Move backwards between windows of an application immediately" -msgstr "" - -#: ../src/metacity.schemas.in.h:38 -msgid "Move backwards between windows of an application with popup" -msgstr "" - -#: ../src/metacity.schemas.in.h:39 -msgid "Move between panels and the desktop immediately" -msgstr "" - -#: ../src/metacity.schemas.in.h:40 -msgid "Move between panels and the desktop with popup" -msgstr "" - -#: ../src/metacity.schemas.in.h:41 -msgid "Move between windows immediately" -msgstr "" - -#: ../src/metacity.schemas.in.h:42 -msgid "Move between windows of an application immediately" -msgstr "" - -#: ../src/metacity.schemas.in.h:43 -msgid "Move between windows of an application with popup" -msgstr "" - -#: ../src/metacity.schemas.in.h:44 -msgid "Move between windows with popup" -msgstr "" - -#: ../src/metacity.schemas.in.h:45 -msgid "Move focus backwards between windows using popup display" -msgstr "" - -#: ../src/metacity.schemas.in.h:46 -msgid "Move window" -msgstr "Bog fuinneog" - -#: ../src/metacity.schemas.in.h:47 -msgid "Move window one workspace down" -msgstr "Bog fuinneog spás oibre síos" - -#: ../src/metacity.schemas.in.h:48 -msgid "Move window one workspace to the left" -msgstr "Bog fuinneog spás oibre ar chlé" - -#: ../src/metacity.schemas.in.h:49 -msgid "Move window one workspace to the right" -msgstr "Bog fuinneog spás oibre ar dheis" - -#: ../src/metacity.schemas.in.h:50 -msgid "Move window one workspace up" -msgstr "Bog fuinneog spás oibre suas" - -#: ../src/metacity.schemas.in.h:51 -msgid "Move window to center of screen" -msgstr "Bog fuinneog go lár an scáileáin" - -#: ../src/metacity.schemas.in.h:52 -msgid "Move window to east side of screen" -msgstr "Bog fuinneog go taobh oirthear an scáileáin" - -#: ../src/metacity.schemas.in.h:53 -msgid "Move window to north side of screen" -msgstr "Bog fuinneog go taobh thuaisceart an scáileáin" - -#: ../src/metacity.schemas.in.h:54 -msgid "Move window to north-east corner" -msgstr "Bog fuinneog go cúinne oirthuaiscirt" - -#: ../src/metacity.schemas.in.h:55 -msgid "Move window to north-west corner" -msgstr "Bog fuinneog go cúinne iarthuaiscirt" - -#: ../src/metacity.schemas.in.h:56 -msgid "Move window to south side of screen" -msgstr "Bog fuinneog go taobh dheisceart an scáileáin" - -#: ../src/metacity.schemas.in.h:57 -msgid "Move window to south-east corner" -msgstr "Bog fuinneog go cúinne oirdheiscirt" - -#: ../src/metacity.schemas.in.h:58 -msgid "Move window to south-west corner" -msgstr "Bog fuinneog go cúinne iardheiscirt" - -#: ../src/metacity.schemas.in.h:59 -msgid "Move window to west side of screen" -msgstr "Bog fuinneog go taobh iarthar an scáileáin" - -#: ../src/metacity.schemas.in.h:60 -msgid "Move window to workspace 1" -msgstr "Bog fuinneog go spás oibre 1" - -#: ../src/metacity.schemas.in.h:61 -msgid "Move window to workspace 10" -msgstr "Bog fuinneog go spás oibre 10" - -#: ../src/metacity.schemas.in.h:62 -msgid "Move window to workspace 11" -msgstr "Bog fuinneog go spás oibre 11" - -#: ../src/metacity.schemas.in.h:63 -msgid "Move window to workspace 12" -msgstr "Bog fuinneog go spás oibre 12" - -#: ../src/metacity.schemas.in.h:64 -msgid "Move window to workspace 2" -msgstr "Bog fuinneog go spás oibre 2" - -#: ../src/metacity.schemas.in.h:65 -msgid "Move window to workspace 3" -msgstr "Bog fuinneog go spás oibre 3" - -#: ../src/metacity.schemas.in.h:66 -msgid "Move window to workspace 4" -msgstr "Bog fuinneog go spás oibre 4" - -#: ../src/metacity.schemas.in.h:67 -msgid "Move window to workspace 5" -msgstr "Bog fuinneog go spás oibre 5" - -#: ../src/metacity.schemas.in.h:68 -msgid "Move window to workspace 6" -msgstr "Bog fuinneog go spás oibre 6" - -#: ../src/metacity.schemas.in.h:69 -msgid "Move window to workspace 7" -msgstr "Bog fuinneog go spás oibre 7" - -#: ../src/metacity.schemas.in.h:70 -msgid "Move window to workspace 8" -msgstr "Bog fuinneog go spás oibre 8" - -#: ../src/metacity.schemas.in.h:71 -msgid "Move window to workspace 9" -msgstr "Bog fuinneog go spás oibre 9" - -#: ../src/metacity.schemas.in.h:72 -msgid "Name of workspace" -msgstr "Ainm spás oibre" - -#: ../src/metacity.schemas.in.h:73 -msgid "Number of workspaces" -msgstr "Líon spásanna oibre" - -#: ../src/metacity.schemas.in.h:74 -msgid "" -"Number of workspaces. Must be more than zero, and has a fixed maximum to " -"prevent making the desktop unusable by accidentally asking for too many " -"workspaces." -msgstr "" - -#: ../src/metacity.schemas.in.h:75 -msgid "Raise obscured window, otherwise lower" -msgstr "" - -#: ../src/metacity.schemas.in.h:76 -msgid "Raise window above other windows" -msgstr "" - -#: ../src/metacity.schemas.in.h:77 -msgid "Resize window" -msgstr "Athmhéadaigh fuinneog" - -#: ../src/metacity.schemas.in.h:78 -msgid "Run a defined command" -msgstr "" - -#: ../src/metacity.schemas.in.h:79 -msgid "Run a terminal" -msgstr "Rith teirminéal" - -#: ../src/metacity.schemas.in.h:80 -msgid "Show the panel menu" -msgstr "" - -#: ../src/metacity.schemas.in.h:81 -msgid "Show the panel run application dialog" -msgstr "" - -#: ../src/metacity.schemas.in.h:82 -msgid "" -"Some applications disregard specifications in ways that result in window " -"manager misfeatures. This option puts Metacity in a rigorously correct mode, " -"which gives a more consistent user interface, provided one does not need to " -"run any misbehaving applications." -msgstr "" - -#: ../src/metacity.schemas.in.h:83 -msgid "Switch to workspace 1" -msgstr "Athraigh go spás oibre 1" - -#: ../src/metacity.schemas.in.h:84 -msgid "Switch to workspace 10" -msgstr "Athraigh go spás oibre 10" - -#: ../src/metacity.schemas.in.h:85 -msgid "Switch to workspace 11" -msgstr "Athraigh go spás oibre 11" - -#: ../src/metacity.schemas.in.h:86 -msgid "Switch to workspace 12" -msgstr "Athraigh go spás oibre 12" - -#: ../src/metacity.schemas.in.h:87 -msgid "Switch to workspace 2" -msgstr "Athraigh go spás oibre 2" - -#: ../src/metacity.schemas.in.h:88 -msgid "Switch to workspace 3" -msgstr "Athraigh go spás oibre 3" - -#: ../src/metacity.schemas.in.h:89 -msgid "Switch to workspace 4" -msgstr "Athraigh go spás oibre 4" - -#: ../src/metacity.schemas.in.h:90 -msgid "Switch to workspace 5" -msgstr "Athraigh go spás oibre 5" - -#: ../src/metacity.schemas.in.h:91 -msgid "Switch to workspace 6" -msgstr "Athraigh go spás oibre 6" - -#: ../src/metacity.schemas.in.h:92 -msgid "Switch to workspace 7" -msgstr "Athraigh go spás oibre 7" - -#: ../src/metacity.schemas.in.h:93 -msgid "Switch to workspace 8" -msgstr "Athraigh go spás oibre 8" - -#: ../src/metacity.schemas.in.h:94 -msgid "Switch to workspace 9" -msgstr "Athraigh go spás oibre 9" - -#: ../src/metacity.schemas.in.h:95 -msgid "Switch to workspace above this one" -msgstr "" - -#: ../src/metacity.schemas.in.h:96 -msgid "Switch to workspace below this one" -msgstr "" - -#: ../src/metacity.schemas.in.h:97 -msgid "Switch to workspace on the left" -msgstr "Athraigh go spás oibre ar chlé" - -#: ../src/metacity.schemas.in.h:98 -msgid "Switch to workspace on the right" -msgstr "Athraigh go spás oibre ar dheis" - -#: ../src/metacity.schemas.in.h:99 -msgid "System Bell is Audible" -msgstr "" - -#: ../src/metacity.schemas.in.h:100 -msgid "Take a screenshot" -msgstr "Tóg scáilghraf" - -#: ../src/metacity.schemas.in.h:101 -msgid "Take a screenshot of a window" -msgstr "" - -#: ../src/metacity.schemas.in.h:102 -msgid "" -"Tells Metacity how to implement the visual indication that the system bell " -"or another application 'bell' indicator has been rung. Currently there are " -"two valid values, \"fullscreen\", which causes a fullscreen white-black " -"flash, and \"frame_flash\" which causes the titlebar of the application " -"which sent the bell signal to flash. If the application which sent the bell " -"is unknown (as is usually the case for the default \"system beep\"), the " -"currently focused window's titlebar is flashed." -msgstr "" - -#: ../src/metacity.schemas.in.h:103 -msgid "" -"The /apps/metacity/global_keybindings/run_command_N keys define keybindings " -"that correspond to these commands. Pressing the keybinding for run_command_N " -"will execute command_N." -msgstr "" - -#: ../src/metacity.schemas.in.h:104 -msgid "" -"The /apps/metacity/global_keybindings/run_command_screenshot key defines a " -"keybinding which causes the command specified by this setting to be invoked." -msgstr "" - -#: ../src/metacity.schemas.in.h:105 -msgid "" -"The /apps/metacity/global_keybindings/run_command_window_screenshot key " -"defines a keybinding which causes the command specified by this setting to " -"be invoked." -msgstr "" - -#: ../src/metacity.schemas.in.h:106 -msgid "" -"The keybinding that runs the correspondingly-numbered command in /apps/" -"metacity/keybinding_commands The format looks like \"<Control>a\" or " -"\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -"lower or upper case, and also abbreviations such as \"<Ctl>\" and " -"\"<Ctrl>\". If you set the option to the special string \"disabled\", " -"then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:107 -msgid "" -"The keybinding that switches to the workspace above the current workspace. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:108 -msgid "" -"The keybinding that switches to the workspace below the current workspace. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:109 -msgid "" -"The keybinding that switches to the workspace on the left of the current " -"workspace. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:110 -msgid "" -"The keybinding that switches to the workspace on the right of the current " -"workspace. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:111 -msgid "" -"The keybinding that switches to workspace 1. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:112 -msgid "" -"The keybinding that switches to workspace 10. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:113 -msgid "" -"The keybinding that switches to workspace 11. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:114 -msgid "" -"The keybinding that switches to workspace 12. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:115 -msgid "" -"The keybinding that switches to workspace 2. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:116 -msgid "" -"The keybinding that switches to workspace 3. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:117 -msgid "" -"The keybinding that switches to workspace 4. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:118 -msgid "" -"The keybinding that switches to workspace 5. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:119 -msgid "" -"The keybinding that switches to workspace 6. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:120 -msgid "" -"The keybinding that switches to workspace 7. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:121 -msgid "" -"The keybinding that switches to workspace 8. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:122 -msgid "" -"The keybinding that switches to workspace 9. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:123 -msgid "" -"The keybinding used to activate the window menu. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:124 -msgid "" -"The keybinding used to close a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:125 -msgid "" -"The keybinding used to enter \"move mode\" and begin moving a window using " -"the keyboard. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:126 -msgid "" -"The keybinding used to enter \"resize mode\" and begin resizing a window " -"using the keyboard. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:127 -msgid "" -"The keybinding used to hide all normal windows and set the focus to the " -"desktop background. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:128 -msgid "" -"The keybinding used to maximize a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:129 -msgid "" -"The keybinding used to minimize a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:130 -msgid "" -"The keybinding used to move a window one workspace down. The format looks " -"like \"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -"fairly liberal and allows lower or upper case, and also abbreviations such " -"as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -"special string \"disabled\", then there will be no keybinding for this " -"action." -msgstr "" - -#: ../src/metacity.schemas.in.h:131 -msgid "" -"The keybinding used to move a window one workspace to the left. The format " -"looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -"parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:132 -msgid "" -"The keybinding used to move a window one workspace to the right. The format " -"looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -"parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:133 -msgid "" -"The keybinding used to move a window one workspace up. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:134 -msgid "" -"The keybinding used to move a window to workspace 1. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:135 -msgid "" -"The keybinding used to move a window to workspace 10. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:136 -msgid "" -"The keybinding used to move a window to workspace 11. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:137 -msgid "" -"The keybinding used to move a window to workspace 12. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:138 -msgid "" -"The keybinding used to move a window to workspace 2. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:139 -msgid "" -"The keybinding used to move a window to workspace 3. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:140 -msgid "" -"The keybinding used to move a window to workspace 4. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:141 -msgid "" -"The keybinding used to move a window to workspace 5. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:142 -msgid "" -"The keybinding used to move a window to workspace 6. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:143 -msgid "" -"The keybinding used to move a window to workspace 7. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:144 -msgid "" -"The keybinding used to move a window to workspace 8. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:145 -msgid "" -"The keybinding used to move a window to workspace 9. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:146 -msgid "" -"The keybinding used to move focus backwards between panels and the desktop, " -"using a popup window. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:147 -msgid "" -"The keybinding used to move focus backwards between panels and the desktop, " -"without a popup window. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:148 -msgid "" -"The keybinding used to move focus backwards between windows of an " -"application without a popup window. Holding \"shift\" together with this " -"binding makes the direction go forward again. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:149 -msgid "" -"The keybinding used to move focus backwards between windows of an " -"application, using a popup window. Holding \"shift\" together with this " -"binding makes the direction go forward again. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:150 -msgid "" -"The keybinding used to move focus backwards between windows without a popup " -"window. Holding \"shift\" together with this binding makes the direction go " -"forward again. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:151 -msgid "" -"The keybinding used to move focus backwards between windows, using a popup " -"window. Holding \"shift\" together with this binding makes the direction go " -"forward again. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:152 -msgid "" -"The keybinding used to move focus between panels and the desktop, using a " -"popup window. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:153 -msgid "" -"The keybinding used to move focus between panels and the desktop, without a " -"popup window. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:154 -msgid "" -"The keybinding used to move focus between windows of an application without " -"a popup window. Holding the \"shift\" key while using this binding reverses " -"the direction of movement. The format looks like \"<Control>a\" or " -"\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -"lower or upper case, and also abbreviations such as \"<Ctl>\" and " -"\"<Ctrl>\". If you set the option to the special string \"disabled\", " -"then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:155 -msgid "" -"The keybinding used to move focus between windows of an application, using a " -"popup window. (Traditionally <Alt>F6) Holding the \"shift\" key while " -"using this binding reverses the direction of movement. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:156 -msgid "" -"The keybinding used to move focus between windows without a popup window. " -"(Traditionally <Alt>Escape) Holding the \"shift\" key while using this " -"binding reverses the direction of movement. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:157 -msgid "" -"The keybinding used to move focus between windows, using a popup window. " -"(Traditionally <Alt>Tab) Holding the \"shift\" key while using this " -"binding reverses the direction of movement. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:158 -msgid "" -"The keybinding used to toggle always on top. A window that is always on top " -"will always be visible over other overlapping windows. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:159 -msgid "" -"The keybinding used to toggle fullscreen mode. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:160 -msgid "" -"The keybinding used to toggle maximization. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:161 -msgid "" -"The keybinding used to toggle shaded/unshaded state. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:162 -msgid "" -"The keybinding used to toggle whether the window is on all workspaces or " -"just one. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:163 -msgid "" -"The keybinding used to unmaximize a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:164 -msgid "" -"The keybinding which display's the panel's \"Run Application\" dialog box. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:165 -msgid "" -"The keybinding which invokes a terminal. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:166 -msgid "" -"The keybinding which invokes the panel's screenshot utility to take a " -"screenshot of a window. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:167 -msgid "" -"The keybinding which invokes the panel's screenshot utility. The format " -"looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -"parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:168 -msgid "" -"The keybinding which shows the panel's main menu. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:169 -msgid "The name of a workspace." -msgstr "An t-ainm spás oibre." - -#: ../src/metacity.schemas.in.h:170 -msgid "The screenshot command" -msgstr "" - -#: ../src/metacity.schemas.in.h:171 -msgid "" -"The theme determines the appearance of window borders, titlebar, and so " -"forth." -msgstr "" - -#: ../src/metacity.schemas.in.h:172 -msgid "" -"The time delay before raising a window if auto_raise is set to true. The " -"delay is given in thousandths of a second." -msgstr "" - -#: ../src/metacity.schemas.in.h:173 -msgid "" -"The window focus mode indicates how windows are activated. It has three " -"possible values; \"click\" means windows must be clicked in order to focus " -"them, \"sloppy\" means windows are focused when the mouse enters the window, " -"and \"mouse\" means windows are focused when the mouse enters the window and " -"unfocused when the mouse leaves the window." -msgstr "" - -#: ../src/metacity.schemas.in.h:174 -msgid "The window screenshot command" -msgstr "" - -#: ../src/metacity.schemas.in.h:175 -msgid "" -"This keybinding changes whether a window is above or below other windows. If " -"the window is covered by another one, it raises the window above all others, " -"and if the window is already fully visible, it lowers it below all others. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:176 -msgid "" -"This keybinding lowers a window below other windows. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:177 -msgid "" -"This keybinding moves a window against the north (top) side of the screen. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:178 -msgid "" -"This keybinding moves a window into the center of the screen. The format " -"looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -"parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:179 -msgid "" -"This keybinding moves a window into the east (right) side of the screen. The " -"format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:180 -msgid "" -"This keybinding moves a window into the north-east (top right) corner of the " -"screen. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:181 -msgid "" -"This keybinding moves a window into the north-west (top left) corner of the " -"screen. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:182 -msgid "" -"This keybinding moves a window into the south (bottom) side of the screen. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:183 -msgid "" -"This keybinding moves a window into the south-east (bottom right) corner of " -"the screen. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:184 -msgid "" -"This keybinding moves a window into the south-west (bottom left) corner of " -"the screen. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:185 -msgid "" -"This keybinding moves a window into the west (left) side of the screen. The " -"format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:186 -msgid "" -"This keybinding raises the window above other windows. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:187 -msgid "" -"This keybinding resizes a window to fill available horizontal space. The " -"format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:188 -msgid "" -"This keybinding resizes a window to fill available vertical space. The " -"format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:189 -msgid "" -"This option determines the effects of double-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, 'toggle_maximize' which will maximize/unmaximize the window, " -"'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which will " -"maximize/unmaximize the window in that direction only, 'minimize' which will " -"minimize the window, 'shade' which will roll the window up, 'menu' which " -"will display the window menu, 'lower' which will put the window behind all " -"the others, and 'none' which will not do anything." -msgstr "" - -#: ../src/metacity.schemas.in.h:190 -msgid "" -"This option determines the effects of middle-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, 'toggle_maximize' which will maximize/unmaximize the window, " -"'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which will " -"maximize/unmaximize the window in that direction only, 'minimize' which will " -"minimize the window, 'shade' which will roll the window up, 'menu' which " -"will display the window menu, 'lower' which will put the window behind all " -"the others, and 'none' which will not do anything." -msgstr "" - -#: ../src/metacity.schemas.in.h:191 -msgid "" -"This option determines the effects of right-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, 'toggle_maximize' which will maximize/unmaximize the window, " -"'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which will " -"maximize/unmaximize the window in that direction only, 'minimize' which will " -"minimize the window, 'shade' which will roll the window up, 'menu' which " -"will display the window menu, 'lower' which will put the window behind all " -"the others, and 'none' which will not do anything." -msgstr "" - -#: ../src/metacity.schemas.in.h:192 -msgid "" -"This option provides additional control over how newly created windows get " -"focus. It has two possible values; \"smart\" applies the user's normal focus " -"mode, and \"strict\" results in windows started from a terminal not being " -"given focus." -msgstr "" - -#: ../src/metacity.schemas.in.h:193 -msgid "Toggle always on top state" -msgstr "" - -#: ../src/metacity.schemas.in.h:194 -msgid "Toggle fullscreen mode" -msgstr "" - -#: ../src/metacity.schemas.in.h:195 -msgid "Toggle maximization state" -msgstr "" - -#: ../src/metacity.schemas.in.h:196 -msgid "Toggle shaded state" -msgstr "" - -#: ../src/metacity.schemas.in.h:197 -msgid "Toggle window on all workspaces" -msgstr "" - -#: ../src/metacity.schemas.in.h:198 -msgid "" -"Turns on a visual indication when an application or the system issues a " -"'bell' or 'beep'; useful for the hard-of-hearing and for use in noisy " -"environments." -msgstr "" - -#: ../src/metacity.schemas.in.h:199 -msgid "Unmaximize window" -msgstr "" - -#: ../src/metacity.schemas.in.h:200 -msgid "Use standard system font in window titles" -msgstr "" - -#: ../src/metacity.schemas.in.h:201 -msgid "Visual Bell Type" -msgstr "" - -#: ../src/metacity.schemas.in.h:202 -msgid "Whether raising should be a side-effect of other user interactions" -msgstr "" - -#: ../src/metacity.schemas.in.h:203 -msgid "Window focus mode" -msgstr "" - -#: ../src/metacity.schemas.in.h:204 -msgid "Window title font" -msgstr "" - -#: ../src/ui/frames.c:1077 -msgid "Close Window" -msgstr "Dún Fuinneog" - -#: ../src/ui/frames.c:1080 -msgid "Window Menu" -msgstr "Roghchlár Fuinneoige" - -#: ../src/ui/frames.c:1083 -msgid "Minimize Window" -msgstr "Íoslaghdaigh Fuinneog" - -#: ../src/ui/frames.c:1086 -msgid "Maximize Window" -msgstr "Uasmhéadaigh Fuinneog" - -#: ../src/ui/frames.c:1089 -msgid "Unmaximize Window" -msgstr "Díhuasmhéadaigh Fuinneog" - -#: ../src/ui/frames.c:1092 -msgid "Roll Up Window" -msgstr "Roll Fuinneog Isteach" - -#: ../src/ui/frames.c:1095 -msgid "Unroll Window" -msgstr "Roll Fuinneog Amach" - -#: ../src/ui/frames.c:1098 -msgid "Keep Window On Top" -msgstr "" - -#: ../src/ui/frames.c:1101 -msgid "Remove Window From Top" -msgstr "" - -#: ../src/ui/frames.c:1104 -msgid "Always On Visible Workspace" -msgstr "Ar Spás Oibre Infheicthe i gCónaí" - -#: ../src/ui/frames.c:1107 -msgid "Put Window On Only One Workspace" -msgstr "Cuir Fuinneog ar Aon Spás Oibre Amháin" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:70 -msgid "Mi_nimize" -msgstr "Íos_laghdaigh" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:72 -msgid "Ma_ximize" -msgstr "_Uasmhéadaigh" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:74 -msgid "Unma_ximize" -msgstr "Díhuas_mhéadaigh" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:76 -msgid "Roll _Up" -msgstr "Roll _Isteach" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:78 -msgid "_Unroll" -msgstr "Roll _Amach" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:80 -msgid "_Move" -msgstr "_Bog" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:82 -msgid "_Resize" -msgstr "_Athmhéadaigh" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:84 -msgid "Move Titlebar On_screen" -msgstr "" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:87 ../src/ui/menu.c:89 -msgid "Always on _Top" -msgstr "Ar Barr i gCónaí" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:91 -msgid "_Always on Visible Workspace" -msgstr "Ar Spás Oibre Infheicthe i _gCónaí" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:93 -msgid "_Only on This Workspace" -msgstr "Ar an Spás _Oibre Seo Amháin" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:95 -msgid "Move to Workspace _Left" -msgstr "Bog go Spás Oibre ar _Chlé" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:97 -msgid "Move to Workspace R_ight" -msgstr "Bog go Spás Oibre ar _Dheis" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:99 -msgid "Move to Workspace _Up" -msgstr "Bog go Spás Oibre Os C_ionn" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:101 -msgid "Move to Workspace _Down" -msgstr "Bog go Spás Oibre _Faoi Bhun" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:105 -msgid "_Close" -msgstr "_Dún" - -#: ../src/ui/menu.c:203 -#, c-format -msgid "Workspace %d%n" -msgstr "Spás Oibre %d%n" - -#: ../src/ui/menu.c:213 -#, c-format -msgid "Workspace 1_0" -msgstr "Spás Oibre 1_0" - -#: ../src/ui/menu.c:215 -#, c-format -msgid "Workspace %s%d" -msgstr "Spás Oibre %s%d" - -#: ../src/ui/menu.c:395 -msgid "Move to Another _Workspace" -msgstr "Bog go _Spás Oibre Eile" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:105 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:111 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:117 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:123 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:129 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:135 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:141 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:147 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:153 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:159 -msgid "Mod5" -msgstr "Mod5" - -#: ../src/ui/metacity-dialog.c:90 -#, c-format -msgid "\"%s\" is not responding." -msgstr "" - -#: ../src/ui/metacity-dialog.c:97 -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "" - -#: ../src/ui/metacity-dialog.c:107 -msgid "_Wait" -msgstr "_Fan" - -#: ../src/ui/metacity-dialog.c:109 -msgid "_Force Quit" -msgstr "Éignigh _Scor" - -#: ../src/ui/metacity-dialog.c:206 -msgid "Title" -msgstr "Teideal" - -#: ../src/ui/metacity-dialog.c:218 -msgid "Class" -msgstr "Aicme" - -#: ../src/ui/metacity-dialog.c:244 -msgid "" -"These windows do not support \"save current setup\" and will have to be " -"restarted manually next time you log in." -msgstr "" - -#: ../src/ui/metacity-dialog.c:310 -#, c-format -msgid "" -"There was an error running \"%s\":\n" -"%s." -msgstr "" -"Tharla earráid ag rith \"%s\":\n" -"%s." - -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" - -#: ../src/ui/theme-parser.c:227 ../src/ui/theme-parser.c:245 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Líne %d carachtar %d: %s" - -#: ../src/ui/theme-parser.c:396 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "" - -#: ../src/ui/theme-parser.c:414 ../src/ui/theme-parser.c:439 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "" - -#: ../src/ui/theme-parser.c:500 -#, c-format -msgid "Integer %ld must be positive" -msgstr "" - -#: ../src/ui/theme-parser.c:508 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "" - -#: ../src/ui/theme-parser.c:536 ../src/ui/theme-parser.c:652 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "" - -#: ../src/ui/theme-parser.c:567 ../src/ui/theme-parser.c:595 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "" - -#: ../src/ui/theme-parser.c:622 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "" - -#: ../src/ui/theme-parser.c:685 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" - -#: ../src/ui/theme-parser.c:750 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" - -#: ../src/ui/theme-parser.c:795 ../src/ui/theme-parser.c:803 -#: ../src/ui/theme-parser.c:885 ../src/ui/theme-parser.c:982 -#: ../src/ui/theme-parser.c:1024 ../src/ui/theme-parser.c:1135 -#: ../src/ui/theme-parser.c:1185 ../src/ui/theme-parser.c:1193 -#: ../src/ui/theme-parser.c:3093 ../src/ui/theme-parser.c:3184 -#: ../src/ui/theme-parser.c:3191 ../src/ui/theme-parser.c:3198 -#, c-format -msgid "No \"%s\" attribute on <%s> element" -msgstr "" - -#: ../src/ui/theme-parser.c:919 ../src/ui/theme-parser.c:990 -#: ../src/ui/theme-parser.c:1032 ../src/ui/theme-parser.c:1143 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "" - -#: ../src/ui/theme-parser.c:931 ../src/ui/theme-parser.c:1044 -#: ../src/ui/theme-parser.c:1155 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "" - -#: ../src/ui/theme-parser.c:1057 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "" - -#: ../src/ui/theme-parser.c:1070 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "" - -#: ../src/ui/theme-parser.c:1112 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "" - -#: ../src/ui/theme-parser.c:1203 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "" - -#: ../src/ui/theme-parser.c:1214 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "" - -#: ../src/ui/theme-parser.c:1222 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "" - -#: ../src/ui/theme-parser.c:1258 -msgid "Theme already has a fallback icon" -msgstr "" - -#: ../src/ui/theme-parser.c:1270 -msgid "Theme already has a fallback mini_icon" -msgstr "" - -#: ../src/ui/theme-parser.c:1283 ../src/ui/theme-parser.c:1347 -#: ../src/ui/theme-parser.c:1636 ../src/ui/theme-parser.c:3285 -#: ../src/ui/theme-parser.c:3339 ../src/ui/theme-parser.c:3511 -#: ../src/ui/theme-parser.c:3727 ../src/ui/theme-parser.c:3765 -#: ../src/ui/theme-parser.c:3803 ../src/ui/theme-parser.c:3841 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:1373 ../src/ui/theme-parser.c:1460 -#: ../src/ui/theme-parser.c:1530 -#, c-format -msgid "No \"name\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:1380 ../src/ui/theme-parser.c:1467 -#, c-format -msgid "No \"value\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:1411 ../src/ui/theme-parser.c:1425 -#: ../src/ui/theme-parser.c:1484 -msgid "" -"Cannot specify both button_width/button_height and aspect ratio for buttons" -msgstr "" - -#: ../src/ui/theme-parser.c:1434 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "" - -#: ../src/ui/theme-parser.c:1493 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "" - -#: ../src/ui/theme-parser.c:1537 -#, c-format -msgid "No \"top\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:1544 -#, c-format -msgid "No \"bottom\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:1551 -#, c-format -msgid "No \"left\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:1558 -#, c-format -msgid "No \"right\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:1590 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "" - -#: ../src/ui/theme-parser.c:1736 ../src/ui/theme-parser.c:1850 -#: ../src/ui/theme-parser.c:1961 ../src/ui/theme-parser.c:2192 -#: ../src/ui/theme-parser.c:3023 -#, c-format -msgid "No \"color\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:1743 -#, c-format -msgid "No \"x1\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:1750 ../src/ui/theme-parser.c:2864 -#, c-format -msgid "No \"y1\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:1757 -#, c-format -msgid "No \"x2\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:1764 ../src/ui/theme-parser.c:2871 -#, c-format -msgid "No \"y2\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:1857 ../src/ui/theme-parser.c:1968 -#: ../src/ui/theme-parser.c:2117 ../src/ui/theme-parser.c:2199 -#: ../src/ui/theme-parser.c:2306 ../src/ui/theme-parser.c:2408 -#: ../src/ui/theme-parser.c:2630 ../src/ui/theme-parser.c:2758 -#: ../src/ui/theme-parser.c:2857 ../src/ui/theme-parser.c:2934 -#: ../src/ui/theme-parser.c:3030 -#, c-format -msgid "No \"x\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:1864 ../src/ui/theme-parser.c:1975 -#: ../src/ui/theme-parser.c:2124 ../src/ui/theme-parser.c:2206 -#: ../src/ui/theme-parser.c:2313 ../src/ui/theme-parser.c:2415 -#: ../src/ui/theme-parser.c:2637 ../src/ui/theme-parser.c:2765 -#: ../src/ui/theme-parser.c:2941 ../src/ui/theme-parser.c:3037 -#, c-format -msgid "No \"y\" attribute on element <%s>" -msgstr "" +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:77 +msgid "_Move" +msgstr "_Bog" -#: ../src/ui/theme-parser.c:1871 ../src/ui/theme-parser.c:1982 -#: ../src/ui/theme-parser.c:2131 ../src/ui/theme-parser.c:2213 -#: ../src/ui/theme-parser.c:2320 ../src/ui/theme-parser.c:2422 -#: ../src/ui/theme-parser.c:2644 ../src/ui/theme-parser.c:2772 -#: ../src/ui/theme-parser.c:2948 -#, c-format -msgid "No \"width\" attribute on element <%s>" -msgstr "" +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:79 +msgid "_Resize" +msgstr "_Athmhéadaigh" -#: ../src/ui/theme-parser.c:1878 ../src/ui/theme-parser.c:1989 -#: ../src/ui/theme-parser.c:2138 ../src/ui/theme-parser.c:2220 -#: ../src/ui/theme-parser.c:2327 ../src/ui/theme-parser.c:2429 -#: ../src/ui/theme-parser.c:2651 ../src/ui/theme-parser.c:2779 -#: ../src/ui/theme-parser.c:2955 -#, c-format -msgid "No \"height\" attribute on element <%s>" -msgstr "" +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:81 +msgid "Move Titlebar On_screen" +msgstr "Bog Barra Teidil ar _Scáileán" -#: ../src/ui/theme-parser.c:1998 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "" +#. separator +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:84 ../src/ui/menu.c:86 +msgid "Always on _Top" +msgstr "Ar Barr i gCónaí" -#: ../src/ui/theme-parser.c:2005 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "" +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:88 +msgid "_Always on Visible Workspace" +msgstr "Ar Spás Oibre Infheicthe i _gCónaí" -#: ../src/ui/theme-parser.c:2014 -#, c-format -msgid "No \"start_angle\" attribute on element <%s>" -msgstr "" +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:90 +msgid "_Only on This Workspace" +msgstr "Ar an Spás _Oibre Seo Amháin" -#: ../src/ui/theme-parser.c:2021 -#, c-format -msgid "No \"extent_angle\" attribute on element <%s>" -msgstr "" +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:92 +msgid "Move to Workspace _Left" +msgstr "Bog go Spás Oibre ar _Chlé" -#: ../src/ui/theme-parser.c:2227 -#, c-format -msgid "No \"alpha\" attribute on element <%s>" -msgstr "" +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:94 +msgid "Move to Workspace R_ight" +msgstr "Bog go Spás Oibre ar _Dheis" -#: ../src/ui/theme-parser.c:2299 -#, c-format -msgid "No \"type\" attribute on element <%s>" -msgstr "" +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:96 +msgid "Move to Workspace _Up" +msgstr "Bog go Spás Oibre Os C_ionn" -#: ../src/ui/theme-parser.c:2349 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "" +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:98 +msgid "Move to Workspace _Down" +msgstr "Bog go Spás Oibre _Faoi Bhun" -#: ../src/ui/theme-parser.c:2436 -#, c-format -msgid "No \"filename\" attribute on element <%s>" -msgstr "" +#. separator +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:102 +msgid "_Close" +msgstr "_Dún" -#: ../src/ui/theme-parser.c:2461 ../src/ui/theme-parser.c:2980 +#: ../src/ui/menu.c:202 #, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "" +msgid "Workspace %d%n" +msgstr "Spás Oibre %d%n" -#: ../src/ui/theme-parser.c:2609 ../src/ui/theme-parser.c:2744 -#: ../src/ui/theme-parser.c:2850 +#: ../src/ui/menu.c:212 #, c-format -msgid "No \"state\" attribute on element <%s>" -msgstr "" +msgid "Workspace 1_0" +msgstr "Spás Oibre 1_0" -#: ../src/ui/theme-parser.c:2616 ../src/ui/theme-parser.c:2751 +#: ../src/ui/menu.c:214 #, c-format -msgid "No \"shadow\" attribute on element <%s>" -msgstr "" +msgid "Workspace %s%d" +msgstr "Spás Oibre %s%d" -#: ../src/ui/theme-parser.c:2623 -#, c-format -msgid "No \"arrow\" attribute on element <%s>" -msgstr "" +#: ../src/ui/menu.c:384 +msgid "Move to Another _Workspace" +msgstr "Bog go _Spás Oibre Eile" -#: ../src/ui/theme-parser.c:2676 ../src/ui/theme-parser.c:2800 -#: ../src/ui/theme-parser.c:2891 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "" +#. This is the text that should appear next to menu accelerators +#. * that use the shift key. If the text on this key isn't typically +#. * translated on keyboards used for your language, don't translate +#. * this. +#. +#: ../src/ui/metaaccellabel.c:77 +msgid "Shift" +msgstr "Shift" -#: ../src/ui/theme-parser.c:2686 ../src/ui/theme-parser.c:2810 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "" +#. This is the text that should appear next to menu accelerators +#. * that use the control key. If the text on this key isn't typically +#. * translated on keyboards used for your language, don't translate +#. * this. +#. +#: ../src/ui/metaaccellabel.c:83 +msgid "Ctrl" +msgstr "Ctrl" -#: ../src/ui/theme-parser.c:2696 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "" +#. This is the text that should appear next to menu accelerators +#. * that use the alt key. If the text on this key isn't typically +#. * translated on keyboards used for your language, don't translate +#. * this. +#. +#: ../src/ui/metaaccellabel.c:89 +msgid "Alt" +msgstr "Alt" -#: ../src/ui/theme-parser.c:3120 ../src/ui/theme-parser.c:3237 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "" +#. This is the text that should appear next to menu accelerators +#. * that use the meta key. If the text on this key isn't typically +#. * translated on keyboards used for your language, don't translate +#. * this. +#. +#: ../src/ui/metaaccellabel.c:95 +msgid "Meta" +msgstr "Meta" -#: ../src/ui/theme-parser.c:3132 ../src/ui/theme-parser.c:3249 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "" +#. This is the text that should appear next to menu accelerators +#. * that use the super key. If the text on this key isn't typically +#. * translated on keyboards used for your language, don't translate +#. * this. +#. +#: ../src/ui/metaaccellabel.c:101 +msgid "Super" +msgstr "Super" -#: ../src/ui/theme-parser.c:3314 -#, c-format -msgid "No \"value\" attribute on <%s> element" -msgstr "" +#. This is the text that should appear next to menu accelerators +#. * that use the hyper key. If the text on this key isn't typically +#. * translated on keyboards used for your language, don't translate +#. * this. +#. +#: ../src/ui/metaaccellabel.c:107 +msgid "Hyper" +msgstr "Hyper" -#: ../src/ui/theme-parser.c:3371 -#, c-format -msgid "No \"position\" attribute on <%s> element" -msgstr "" +#. This is the text that should appear next to menu accelerators +#. * that use the mod2 key. If the text on this key isn't typically +#. * translated on keyboards used for your language, don't translate +#. * this. +#. +#: ../src/ui/metaaccellabel.c:113 +msgid "Mod2" +msgstr "Mod2" -#: ../src/ui/theme-parser.c:3380 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "" +#. This is the text that should appear next to menu accelerators +#. * that use the mod3 key. If the text on this key isn't typically +#. * translated on keyboards used for your language, don't translate +#. * this. +#. +#: ../src/ui/metaaccellabel.c:119 +msgid "Mod3" +msgstr "Mod3" -#: ../src/ui/theme-parser.c:3388 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "" +#. This is the text that should appear next to menu accelerators +#. * that use the mod4 key. If the text on this key isn't typically +#. * translated on keyboards used for your language, don't translate +#. * this. +#. +#: ../src/ui/metaaccellabel.c:125 +msgid "Mod4" +msgstr "Mod4" -#: ../src/ui/theme-parser.c:3405 ../src/ui/theme-parser.c:3496 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "" +#. This is the text that should appear next to menu accelerators +#. * that use the mod5 key. If the text on this key isn't typically +#. * translated on keyboards used for your language, don't translate +#. * this. +#. +#: ../src/ui/metaaccellabel.c:131 +msgid "Mod5" +msgstr "Mod5" -#: ../src/ui/theme-parser.c:3433 +#. Translators: This represents the size of a window. The first number is +#. * the width of the window and the second is the height. +#. +#: ../src/ui/resizepopup.c:136 #, c-format -msgid "No \"function\" attribute on <%s> element" -msgstr "" +msgid "%d x %d" +msgstr "%d x %d" -#: ../src/ui/theme-parser.c:3441 ../src/ui/theme-parser.c:3557 -#, c-format -msgid "No \"state\" attribute on <%s> element" -msgstr "" +#: ../src/ui/theme.c:236 +msgid "top" +msgstr "barr" -#: ../src/ui/theme-parser.c:3450 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "" +#: ../src/ui/theme.c:238 +msgid "bottom" +msgstr "bun" -#: ../src/ui/theme-parser.c:3459 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "" +#: ../src/ui/theme.c:240 +msgid "left" +msgstr "ar chlé" -#: ../src/ui/theme-parser.c:3471 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "" +#: ../src/ui/theme.c:242 +msgid "right" +msgstr "ar dheis" -#: ../src/ui/theme-parser.c:3479 +#: ../src/ui/theme.c:270 #, c-format -msgid "Frame style already has a button for function %s state %s" +msgid "frame geometry does not specify \"%s\" dimension" msgstr "" -#: ../src/ui/theme-parser.c:3549 +#: ../src/ui/theme.c:289 #, c-format -msgid "No \"focus\" attribute on <%s> element" +msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" msgstr "" -#: ../src/ui/theme-parser.c:3565 +#: ../src/ui/theme.c:326 #, c-format -msgid "No \"style\" attribute on <%s> element" +msgid "Button aspect ratio %g is not reasonable" msgstr "" -#: ../src/ui/theme-parser.c:3574 +#: ../src/ui/theme.c:338 #, c-format -msgid "\"%s\" is not a valid value for focus attribute" +msgid "Frame geometry does not specify size of buttons" msgstr "" -#: ../src/ui/theme-parser.c:3583 +#: ../src/ui/theme.c:1051 #, c-format -msgid "\"%s\" is not a valid value for state attribute" +msgid "Gradients should have at least two colors" msgstr "" -#: ../src/ui/theme-parser.c:3593 +#: ../src/ui/theme.c:1203 #, c-format -msgid "A style called \"%s\" has not been defined" +msgid "" +"GTK custom color specification must have color name and fallback in " +"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" msgstr "" -#: ../src/ui/theme-parser.c:3604 +#: ../src/ui/theme.c:1219 #, c-format -msgid "No \"resize\" attribute on <%s> element" +msgid "" +"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" +"_ are valid" msgstr "" -#: ../src/ui/theme-parser.c:3614 ../src/ui/theme-parser.c:3637 +#: ../src/ui/theme.c:1233 #, c-format -msgid "\"%s\" is not a valid value for resize attribute" +msgid "" +"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " +"fit the format" msgstr "" -#: ../src/ui/theme-parser.c:3648 +#: ../src/ui/theme.c:1278 #, c-format msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" +"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " +"where NORMAL is the state; could not parse \"%s\"" msgstr "" -#: ../src/ui/theme-parser.c:3662 +#: ../src/ui/theme.c:1292 #, c-format msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" +"GTK color specification must have a close bracket after the state, e.g. gtk:" +"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" msgstr "" -#: ../src/ui/theme-parser.c:3676 ../src/ui/theme-parser.c:3698 +#: ../src/ui/theme.c:1303 #, c-format -msgid "Style has already been specified for state %s resize %s focus %s" +msgid "Did not understand state \"%s\" in color specification" msgstr "" -#: ../src/ui/theme-parser.c:3687 ../src/ui/theme-parser.c:3709 +#: ../src/ui/theme.c:1316 #, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "" - -#: ../src/ui/theme-parser.c:3748 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" - -#: ../src/ui/theme-parser.c:3786 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" - -#: ../src/ui/theme-parser.c:3824 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" +msgid "Did not understand color component \"%s\" in color specification" msgstr "" -#: ../src/ui/theme-parser.c:3872 +#: ../src/ui/theme.c:1345 #, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" +msgid "" +"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " +"format" msgstr "" -#: ../src/ui/theme-parser.c:3892 +#: ../src/ui/theme.c:1356 #, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" +msgid "Could not parse alpha value \"%s\" in blended color" msgstr "" -#: ../src/ui/theme-parser.c:3897 +#: ../src/ui/theme.c:1366 #, c-format -msgid "Element <%s> is not allowed inside a <constant> element" +msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" msgstr "" -#: ../src/ui/theme-parser.c:3909 +#: ../src/ui/theme.c:1413 #, c-format msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" +"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" msgstr "" -#: ../src/ui/theme-parser.c:3931 +#: ../src/ui/theme.c:1424 #, c-format -msgid "Element <%s> is not allowed inside a draw operation element" +msgid "Could not parse shade factor \"%s\" in shaded color" msgstr "" -#: ../src/ui/theme-parser.c:3941 ../src/ui/theme-parser.c:3971 -#: ../src/ui/theme-parser.c:3976 ../src/ui/theme-parser.c:3981 +#: ../src/ui/theme.c:1434 #, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "" - -#: ../src/ui/theme-parser.c:4203 -msgid "No draw_ops provided for frame piece" +msgid "Shade factor \"%s\" in shaded color is negative" msgstr "" -#: ../src/ui/theme-parser.c:4218 -msgid "No draw_ops provided for button" +#: ../src/ui/theme.c:1463 +#, c-format +msgid "Could not parse color \"%s\"" msgstr "" -#: ../src/ui/theme-parser.c:4270 +#: ../src/ui/theme.c:1780 #, c-format -msgid "No text is allowed inside element <%s>" +msgid "Coordinate expression contains character '%s' which is not allowed" msgstr "" -#: ../src/ui/theme-parser.c:4325 -msgid "<name> specified twice for this theme" +#: ../src/ui/theme.c:1807 +#, c-format +msgid "" +"Coordinate expression contains floating point number '%s' which could not be " +"parsed" msgstr "" -#: ../src/ui/theme-parser.c:4336 -msgid "<author> specified twice for this theme" +#: ../src/ui/theme.c:1821 +#, c-format +msgid "Coordinate expression contains integer '%s' which could not be parsed" msgstr "" -#: ../src/ui/theme-parser.c:4347 -msgid "<copyright> specified twice for this theme" +#: ../src/ui/theme.c:1942 +#, c-format +msgid "" +"Coordinate expression contained unknown operator at the start of this text: " +"\"%s\"" msgstr "" -#: ../src/ui/theme-parser.c:4358 -msgid "<date> specified twice for this theme" +#: ../src/ui/theme.c:1999 +#, c-format +msgid "Coordinate expression was empty or not understood" msgstr "" -#: ../src/ui/theme-parser.c:4369 -msgid "<description> specified twice for this theme" +#: ../src/ui/theme.c:2112 ../src/ui/theme.c:2122 ../src/ui/theme.c:2156 +#, c-format +msgid "Coordinate expression results in division by zero" msgstr "" -#: ../src/ui/theme-parser.c:4636 +#: ../src/ui/theme.c:2164 #, c-format -msgid "Failed to find a valid file for theme %s\n" +msgid "" +"Coordinate expression tries to use mod operator on a floating-point number" msgstr "" -#: ../src/ui/theme-parser.c:4692 +#: ../src/ui/theme.c:2220 #, c-format -msgid "Theme file %s did not contain a root <metacity_theme> element" +msgid "" +"Coordinate expression has an operator \"%s\" where an operand was expected" msgstr "" -#: ../src/ui/theme-viewer.c:75 -msgid "/_Windows" -msgstr "/_Fuinneoga" - -#: ../src/ui/theme-viewer.c:76 -msgid "/Windows/tearoff" +#: ../src/ui/theme.c:2229 +#, c-format +msgid "Coordinate expression had an operand where an operator was expected" msgstr "" -#: ../src/ui/theme-viewer.c:77 -msgid "/Windows/_Dialog" +#: ../src/ui/theme.c:2237 +#, c-format +msgid "Coordinate expression ended with an operator instead of an operand" msgstr "" -#: ../src/ui/theme-viewer.c:78 -msgid "/Windows/_Modal dialog" +#: ../src/ui/theme.c:2247 +#, c-format +msgid "" +"Coordinate expression has operator \"%c\" following operator \"%c\" with no " +"operand in between" msgstr "" -#: ../src/ui/theme-viewer.c:79 -msgid "/Windows/_Utility" +#: ../src/ui/theme.c:2398 ../src/ui/theme.c:2443 +#, c-format +msgid "Coordinate expression had unknown variable or constant \"%s\"" msgstr "" -#: ../src/ui/theme-viewer.c:80 -msgid "/Windows/_Splashscreen" +#: ../src/ui/theme.c:2497 +#, c-format +msgid "Coordinate expression parser overflowed its buffer." msgstr "" -#: ../src/ui/theme-viewer.c:81 -msgid "/Windows/_Top dock" +#: ../src/ui/theme.c:2526 +#, c-format +msgid "Coordinate expression had a close parenthesis with no open parenthesis" msgstr "" -#: ../src/ui/theme-viewer.c:82 -msgid "/Windows/_Bottom dock" +#: ../src/ui/theme.c:2590 +#, c-format +msgid "Coordinate expression had an open parenthesis with no close parenthesis" msgstr "" -#: ../src/ui/theme-viewer.c:83 -msgid "/Windows/_Left dock" +#: ../src/ui/theme.c:2601 +#, c-format +msgid "Coordinate expression doesn't seem to have any operators or operands" msgstr "" -#: ../src/ui/theme-viewer.c:84 -msgid "/Windows/_Right dock" +#: ../src/ui/theme.c:2814 ../src/ui/theme.c:2834 ../src/ui/theme.c:2854 +#, c-format +msgid "Theme contained an expression that resulted in an error: %s\n" msgstr "" -#: ../src/ui/theme-viewer.c:85 -msgid "/Windows/_All docks" +#: ../src/ui/theme.c:4500 +#, c-format +msgid "" +"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " +"specified for this frame style" msgstr "" -#: ../src/ui/theme-viewer.c:86 -msgid "/Windows/Des_ktop" +#: ../src/ui/theme.c:5011 ../src/ui/theme.c:5036 +#, c-format +msgid "" +"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" msgstr "" -#: ../src/ui/theme-viewer.c:135 -msgid "Open another one of these windows" -msgstr "" +#: ../src/ui/theme.c:5082 +#, c-format +msgid "Failed to load theme \"%s\": %s\n" +msgstr "Theip ar luchtú téama \"%s\": %s\n" -#: ../src/ui/theme-viewer.c:142 -msgid "This is a demo button with an 'open' icon" -msgstr "" +#: ../src/ui/theme.c:5218 ../src/ui/theme.c:5225 ../src/ui/theme.c:5232 +#: ../src/ui/theme.c:5239 ../src/ui/theme.c:5246 +#, c-format +msgid "No <%s> set for theme \"%s\"" +msgstr "Gan <%s> socraithe don téama \"%s\"" -#: ../src/ui/theme-viewer.c:149 -msgid "This is a demo button with a 'quit' icon" +#: ../src/ui/theme.c:5254 +#, c-format +msgid "" +"No frame style set for window type \"%s\" in theme \"%s\", add a <window " +"type=\"%s\" style_set=\"whatever\"/> element" msgstr "" -#: ../src/ui/theme-viewer.c:242 -msgid "This is a sample message in a sample dialog" +#: ../src/ui/theme.c:5661 ../src/ui/theme.c:5723 ../src/ui/theme.c:5786 +#, c-format +msgid "" +"User-defined constants must begin with a capital letter; \"%s\" does not" msgstr "" -#: ../src/ui/theme-viewer.c:325 +#: ../src/ui/theme.c:5669 ../src/ui/theme.c:5731 ../src/ui/theme.c:5794 #, c-format -msgid "Fake menu item %d\n" +msgid "Constant \"%s\" has already been defined" msgstr "" -#: ../src/ui/theme-viewer.c:359 -msgid "Border-only window" +#. Translators: This means that an attribute which should have been found +#. * on an XML element was not in fact found. +#. +#: ../src/ui/theme-parser.c:236 +#, c-format +msgid "No \"%s\" attribute on element <%s>" msgstr "" -#: ../src/ui/theme-viewer.c:361 -msgid "Bar" -msgstr "Barra" +#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 +#, c-format +msgid "Line %d character %d: %s" +msgstr "Líne %d carachtar %d: %s" -#: ../src/ui/theme-viewer.c:378 -msgid "Normal Application Window" +#: ../src/ui/theme-parser.c:479 +#, c-format +msgid "Attribute \"%s\" repeated twice on the same <%s> element" msgstr "" -#: ../src/ui/theme-viewer.c:382 -msgid "Dialog Box" +#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 +#, c-format +msgid "Attribute \"%s\" is invalid on <%s> element in this context" msgstr "" -#: ../src/ui/theme-viewer.c:386 -msgid "Modal Dialog Box" +#: ../src/ui/theme-parser.c:594 +#, c-format +msgid "Could not parse \"%s\" as an integer" msgstr "" -#: ../src/ui/theme-viewer.c:390 -msgid "Utility Palette" +#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 +#, c-format +msgid "Did not understand trailing characters \"%s\" in string \"%s\"" msgstr "" -#: ../src/ui/theme-viewer.c:394 -msgid "Torn-off Menu" +#: ../src/ui/theme-parser.c:613 +#, c-format +msgid "Integer %ld must be positive" msgstr "" -#: ../src/ui/theme-viewer.c:398 -msgid "Border" -msgstr "Imlíne" +#: ../src/ui/theme-parser.c:621 +#, c-format +msgid "Integer %ld is too large, current max is %d" +msgstr "" -#: ../src/ui/theme-viewer.c:726 +#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 #, c-format -msgid "Button layout test %d" +msgid "Could not parse \"%s\" as a floating point number" msgstr "" -#: ../src/ui/theme-viewer.c:755 +#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 #, c-format -msgid "%g milliseconds to draw one window frame" +msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" msgstr "" -#: ../src/ui/theme-viewer.c:798 +#: ../src/ui/theme-parser.c:735 #, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Úsáid: metacity-theme-viewer [AINMTÉAMA]\n" +msgid "Angle must be between 0.0 and 360.0, was %g\n" +msgstr "" -#: ../src/ui/theme-viewer.c:805 +#: ../src/ui/theme-parser.c:798 #, c-format -msgid "Error loading theme: %s\n" -msgstr "Earráid agus téama á luchtú: %s\n" +msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" +msgstr "" -#: ../src/ui/theme-viewer.c:811 +#: ../src/ui/theme-parser.c:863 #, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "Luchtaigh téama \"%s\" i %g soicind\n" +msgid "" +"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," +"large,x-large,xx-large)\n" +msgstr "" -#: ../src/ui/theme-viewer.c:852 -msgid "Normal Title Font" +#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 +#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 +#, c-format +msgid "<%s> name \"%s\" used a second time" msgstr "" -#: ../src/ui/theme-viewer.c:858 -msgid "Small Title Font" +#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 +#: ../src/ui/theme-parser.c:1231 +#, c-format +msgid "<%s> parent \"%s\" has not been defined" msgstr "" -#: ../src/ui/theme-viewer.c:864 -msgid "Large Title Font" +#: ../src/ui/theme-parser.c:1141 +#, c-format +msgid "<%s> geometry \"%s\" has not been defined" msgstr "" -#: ../src/ui/theme-viewer.c:869 -msgid "Button Layouts" +#: ../src/ui/theme-parser.c:1154 +#, c-format +msgid "<%s> must specify either a geometry or a parent that has a geometry" msgstr "" -#: ../src/ui/theme-viewer.c:874 -msgid "Benchmark" +#: ../src/ui/theme-parser.c:1196 +msgid "You must specify a background for an alpha value to be meaningful" msgstr "" -#: ../src/ui/theme-viewer.c:921 -msgid "Window Title Goes Here" +#: ../src/ui/theme-parser.c:1264 +#, c-format +msgid "Unknown type \"%s\" on <%s> element" msgstr "" -#: ../src/ui/theme-viewer.c:1025 +#: ../src/ui/theme-parser.c:1275 #, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" +msgid "Unknown style_set \"%s\" on <%s> element" msgstr "" -#: ../src/ui/theme-viewer.c:1244 -msgid "position expression test returned TRUE but set error" +#: ../src/ui/theme-parser.c:1283 +#, c-format +msgid "Window type \"%s\" has already been assigned a style set" msgstr "" -#: ../src/ui/theme-viewer.c:1246 -msgid "position expression test returned FALSE but didn't set error" +#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 +#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 +#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 +#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 +#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 +#, c-format +msgid "Element <%s> is not allowed below <%s>" msgstr "" -#: ../src/ui/theme-viewer.c:1250 -msgid "Error was expected but none given" +#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 +#: ../src/ui/theme-parser.c:1486 +msgid "" +"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " +"for buttons" msgstr "" -#: ../src/ui/theme-viewer.c:1252 +#: ../src/ui/theme-parser.c:1450 #, c-format -msgid "Error %d was expected but %d given" +msgid "Distance \"%s\" is unknown" msgstr "" -#: ../src/ui/theme-viewer.c:1258 +#: ../src/ui/theme-parser.c:1495 #, c-format -msgid "Error not expected but one was returned: %s" +msgid "Aspect ratio \"%s\" is unknown" msgstr "" -#: ../src/ui/theme-viewer.c:1262 +#: ../src/ui/theme-parser.c:1557 #, c-format -msgid "x value was %d, %d was expected" +msgid "Border \"%s\" is unknown" msgstr "" -#: ../src/ui/theme-viewer.c:1265 +#: ../src/ui/theme-parser.c:1868 #, c-format -msgid "y value was %d, %d was expected" +msgid "No \"start_angle\" or \"from\" attribute on element <%s>" msgstr "" -#: ../src/ui/theme-viewer.c:1330 +#: ../src/ui/theme-parser.c:1875 #, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" +msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" msgstr "" -#: ../src/ui/theme.c:256 -msgid "top" -msgstr "barr" - -#: ../src/ui/theme.c:258 -msgid "bottom" -msgstr "bun" - -#: ../src/ui/theme.c:260 -msgid "left" -msgstr "ar chlé" - -#: ../src/ui/theme.c:262 -msgid "right" -msgstr "ar dheis" - -#: ../src/ui/theme.c:289 +#: ../src/ui/theme-parser.c:2115 #, c-format -msgid "frame geometry does not specify \"%s\" dimension" +msgid "Did not understand value \"%s\" for type of gradient" msgstr "" -#: ../src/ui/theme.c:308 +#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 #, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" +msgid "Did not understand fill type \"%s\" for <%s> element" msgstr "" -#: ../src/ui/theme.c:345 +#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 +#: ../src/ui/theme-parser.c:2506 #, c-format -msgid "Button aspect ratio %g is not reasonable" +msgid "Did not understand state \"%s\" for <%s> element" msgstr "" -#: ../src/ui/theme.c:357 +#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 #, c-format -msgid "Frame geometry does not specify size of buttons" +msgid "Did not understand shadow \"%s\" for <%s> element" msgstr "" -#: ../src/ui/theme.c:1022 +#: ../src/ui/theme-parser.c:2380 #, c-format -msgid "Gradients should have at least two colors" +msgid "Did not understand arrow \"%s\" for <%s> element" msgstr "" -#: ../src/ui/theme.c:1148 +#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 #, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" +msgid "No <draw_ops> called \"%s\" has been defined" msgstr "" -#: ../src/ui/theme.c:1162 +#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 #, c-format -msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +msgid "Including draw_ops \"%s\" here would create a circular reference" msgstr "" -#: ../src/ui/theme.c:1173 +#: ../src/ui/theme-parser.c:2917 #, c-format -msgid "Did not understand state \"%s\" in color specification" +msgid "Unknown position \"%s\" for frame piece" msgstr "" -#: ../src/ui/theme.c:1186 +#: ../src/ui/theme-parser.c:2925 #, c-format -msgid "Did not understand color component \"%s\" in color specification" +msgid "Frame style already has a piece at position %s" msgstr "" -#: ../src/ui/theme.c:1216 +#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 #, c-format -msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" +msgid "No <draw_ops> with the name \"%s\" has been defined" msgstr "" -#: ../src/ui/theme.c:1227 +#: ../src/ui/theme-parser.c:2972 #, c-format -msgid "Could not parse alpha value \"%s\" in blended color" +msgid "Unknown function \"%s\" for button" msgstr "" -#: ../src/ui/theme.c:1237 +#: ../src/ui/theme-parser.c:2982 #, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" +msgid "Button function \"%s\" does not exist in this version (%d, need %d)" msgstr "" -#: ../src/ui/theme.c:1284 +#: ../src/ui/theme-parser.c:2994 #, c-format -msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" +msgid "Unknown state \"%s\" for button" msgstr "" -#: ../src/ui/theme.c:1295 +#: ../src/ui/theme-parser.c:3002 #, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" +msgid "Frame style already has a button for function %s state %s" msgstr "" -#: ../src/ui/theme.c:1305 +#: ../src/ui/theme-parser.c:3073 #, c-format -msgid "Shade factor \"%s\" in shaded color is negative" +msgid "\"%s\" is not a valid value for focus attribute" msgstr "" -#: ../src/ui/theme.c:1334 +#: ../src/ui/theme-parser.c:3082 #, c-format -msgid "Could not parse color \"%s\"" +msgid "\"%s\" is not a valid value for state attribute" msgstr "" -#: ../src/ui/theme.c:1584 +#: ../src/ui/theme-parser.c:3092 #, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" +msgid "A style called \"%s\" has not been defined" msgstr "" -#: ../src/ui/theme.c:1611 +#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 #, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" +msgid "\"%s\" is not a valid value for resize attribute" msgstr "" -#: ../src/ui/theme.c:1625 +#: ../src/ui/theme-parser.c:3147 #, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" +msgid "" +"Should not have \"resize\" attribute on <%s> element for maximized/shaded " +"states" msgstr "" -#: ../src/ui/theme.c:1747 +#: ../src/ui/theme-parser.c:3161 #, c-format msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" +"Should not have \"resize\" attribute on <%s> element for maximized states" msgstr "" -#: ../src/ui/theme.c:1804 +#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 #, c-format -msgid "Coordinate expression was empty or not understood" +msgid "Style has already been specified for state %s resize %s focus %s" msgstr "" -#: ../src/ui/theme.c:1915 ../src/ui/theme.c:1925 ../src/ui/theme.c:1959 +#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 +#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 +#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 #, c-format -msgid "Coordinate expression results in division by zero" +msgid "Style has already been specified for state %s focus %s" msgstr "" -#: ../src/ui/theme.c:1967 -#, c-format +#: ../src/ui/theme-parser.c:3294 msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" +"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " +"attribute and also a <draw_ops> element, or specified two elements)" msgstr "" -#: ../src/ui/theme.c:2023 -#, c-format +#: ../src/ui/theme-parser.c:3332 msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" +"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " +"attribute and also a <draw_ops> element, or specified two elements)" msgstr "" -#: ../src/ui/theme.c:2032 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" +#: ../src/ui/theme-parser.c:3370 +msgid "" +"Can't have a two draw_ops for a <menu_icon> element (theme specified a " +"draw_ops attribute and also a <draw_ops> element, or specified two elements)" msgstr "" -#: ../src/ui/theme.c:2040 +#: ../src/ui/theme-parser.c:3434 #, c-format -msgid "Coordinate expression ended with an operator instead of an operand" +msgid "Bad version specification '%s'" msgstr "" -#: ../src/ui/theme.c:2050 -#, c-format +#: ../src/ui/theme-parser.c:3507 msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" +"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" +"theme-2.xml" msgstr "" -#: ../src/ui/theme.c:2197 ../src/ui/theme.c:2238 +#: ../src/ui/theme-parser.c:3530 #, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" +msgid "Theme requires version %s but latest supported theme version is %d.%d" msgstr "" -#: ../src/ui/theme.c:2292 +#: ../src/ui/theme-parser.c:3562 #, c-format -msgid "Coordinate expression parser overflowed its buffer." +msgid "Outermost element in theme must be <metacity_theme> not <%s>" msgstr "" -#: ../src/ui/theme.c:2321 +#: ../src/ui/theme-parser.c:3582 #, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" +msgid "" +"Element <%s> is not allowed inside a name/author/date/description element" msgstr "" -#: ../src/ui/theme.c:2385 +#: ../src/ui/theme-parser.c:3587 #, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" +msgid "Element <%s> is not allowed inside a <constant> element" msgstr "" -#: ../src/ui/theme.c:2396 +#: ../src/ui/theme-parser.c:3599 #, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" +msgid "" +"Element <%s> is not allowed inside a distance/border/aspect_ratio element" msgstr "" -#: ../src/ui/theme.c:2598 ../src/ui/theme.c:2618 ../src/ui/theme.c:2638 +#: ../src/ui/theme-parser.c:3621 #, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" +msgid "Element <%s> is not allowed inside a draw operation element" msgstr "" -#: ../src/ui/theme.c:4157 +#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 +#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 #, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" +msgid "Element <%s> is not allowed inside a <%s> element" msgstr "" -#: ../src/ui/theme.c:4633 ../src/ui/theme.c:4658 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" +#: ../src/ui/theme-parser.c:3899 +msgid "No draw_ops provided for frame piece" msgstr "" -#: ../src/ui/theme.c:4702 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Theip ar luchtú téama \"%s\": %s\n" - -#: ../src/ui/theme.c:4828 ../src/ui/theme.c:4835 ../src/ui/theme.c:4842 -#: ../src/ui/theme.c:4849 ../src/ui/theme.c:4856 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "Gan <%s> socraithe don téama \"%s\"" - -#: ../src/ui/theme.c:4864 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" +#: ../src/ui/theme-parser.c:3914 +msgid "No draw_ops provided for button" msgstr "" -#: ../src/ui/theme.c:5231 ../src/ui/theme.c:5293 ../src/ui/theme.c:5356 +#: ../src/ui/theme-parser.c:3968 #, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" +msgid "No text is allowed inside element <%s>" msgstr "" -#: ../src/ui/theme.c:5239 ../src/ui/theme.c:5301 ../src/ui/theme.c:5364 +#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 +#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 +#: ../src/ui/theme-parser.c:4074 #, c-format -msgid "Constant \"%s\" has already been defined" +msgid "<%s> specified twice for this theme" msgstr "" -#: ../src/tools/metacity-message.c:150 +#: ../src/ui/theme-parser.c:4336 #, c-format -msgid "Usage: %s\n" -msgstr "Úsáid: %s\n" +msgid "Failed to find a valid file for theme %s\n" +msgstr "" diff --git a/po/gd.po b/po/gd.po new file mode 100644 index 000000000..f56ded49e --- /dev/null +++ b/po/gd.po @@ -0,0 +1,446 @@ +# Scottish Gaelic translation for mutter. +# Copyright (C) 2016 mutter's COPYRIGHT HOLDER +# This file is distributed under the same license as the mutter package. +# GunChleoc <fios@foramnagaidhlig.net>, 2016, 2017, 2018. +msgid "" +msgstr "" +"Project-Id-Version: mutter master\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2018-01-27 08:02+0000\n" +"PO-Revision-Date: 2018-03-01 10:45+0100\n" +"Last-Translator: GunChleoc <fios@foramnagaidhlig.net>\n" +"Language-Team: Fòram na Gàidhlig\n" +"Language: gd\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : " +"(n > 2 && n < 20) ? 2 : 3;\n" +"X-Generator: Virtaal 0.7.1\n" +"(n > 2 && n < 20) ? 2: 3;\n" +"X-Project-Style: gnome\n" + +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Seòladaireachd" + +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Gluais an uinneag gu rum-obrach 1" + +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Gluais an uinneag gu rum-obrach 2" + +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Gluais an uinneag gu rum-obrach 3" + +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Gluais an uinneag gu rum-obrach 4" + +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Gluais an uinneag gun rum-obrach mu dheireadh" + +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace to the left" +msgstr "Gluais an uinneag gun rum-obrach ris an taobh chlì" + +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace to the right" +msgstr "Gluais an uinneag gun rum-obrach ris an taobh deas" + +#: data/50-mutter-navigation.xml:30 +msgid "Move window one workspace up" +msgstr "Gluais an uinneag gun rum-obrach os a chionn" + +#: data/50-mutter-navigation.xml:33 +msgid "Move window one workspace down" +msgstr "Gluais an uinneag gun rum-obrach foidhe" + +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor to the left" +msgstr "Gluais an uinneag gun sgrìn aig an taobh chlì" + +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor to the right" +msgstr "Gluais an uinneag gun sgrìn aig an taobh deas" + +#: data/50-mutter-navigation.xml:42 +msgid "Move window one monitor up" +msgstr "Gluais an uinneag gun sgrìn os a chionn" + +#: data/50-mutter-navigation.xml:45 +msgid "Move window one monitor down" +msgstr "Gluais an uinneag gun sgrìn foidhe" + +#: data/50-mutter-navigation.xml:49 +msgid "Switch applications" +msgstr "Gearr leum gu aplacaid eile" + +#: data/50-mutter-navigation.xml:54 +msgid "Switch to previous application" +msgstr "Gearr leum gun aplacaid roimhpe" + +#: data/50-mutter-navigation.xml:58 +msgid "Switch windows" +msgstr "Gearr leum gu uinneag eile" + +#: data/50-mutter-navigation.xml:63 +msgid "Switch to previous window" +msgstr "Gearr leum gun uinneag roimhpe" + +#: data/50-mutter-navigation.xml:67 +msgid "Switch windows of an application" +msgstr "Gearr leum gu uinneag eile na h-aplacaid" + +#: data/50-mutter-navigation.xml:72 +msgid "Switch to previous window of an application" +msgstr "Gearr leum gu uinneag roimhpe na h-aplacaid" + +#: data/50-mutter-navigation.xml:76 +msgid "Switch system controls" +msgstr "Gearr leum gu inneal-smachd siostaim eile" + +#: data/50-mutter-navigation.xml:81 +msgid "Switch to previous system control" +msgstr "Gearr leum gun inneal-smachd siostaim roimhe" + +#: data/50-mutter-navigation.xml:85 +msgid "Switch windows directly" +msgstr "Gearr leum gu uinneag eile sa bhad" + +#: data/50-mutter-navigation.xml:90 +msgid "Switch directly to previous window" +msgstr "Gearr leum gun uinneag roimhpe sa bhad" + +#: data/50-mutter-navigation.xml:94 +msgid "Switch windows of an app directly" +msgstr "Gearr leum gu uinneag eile na h-aplacaid sa bhad" + +#: data/50-mutter-navigation.xml:99 +msgid "Switch directly to previous window of an app" +msgstr "Gearr leum gu uinneag roimphe na h-aplacaid sa bhad" + +#: data/50-mutter-navigation.xml:103 +msgid "Switch system controls directly" +msgstr "Gearr leum gu inneal-smachd siostaim eile sa bhad" + +#: data/50-mutter-navigation.xml:108 +msgid "Switch directly to previous system control" +msgstr "Gearr leum gun inneal-smachd siostaim roimhe sa bhad" + +#: data/50-mutter-navigation.xml:111 +msgid "Hide all normal windows" +msgstr "Cuir gach uinneag àbhaisteach am falach" + +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 1" +msgstr "Gearr leum gu rum-obrach 1" + +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 2" +msgstr "Gearr leum gu rum-obrach 2" + +#: data/50-mutter-navigation.xml:120 +msgid "Switch to workspace 3" +msgstr "Gearr leum gu rum-obrach 3" + +#: data/50-mutter-navigation.xml:123 +msgid "Switch to workspace 4" +msgstr "Gearr leum gu rum-obrach 4" + +#: data/50-mutter-navigation.xml:126 +msgid "Switch to last workspace" +msgstr "Gearr leum gun rum-obrach mu dheireadh" + +#: data/50-mutter-navigation.xml:129 +msgid "Move to workspace left" +msgstr "Gluais dhan rum-obrach air an taobh chlì" + +#: data/50-mutter-navigation.xml:132 +msgid "Move to workspace right" +msgstr "Gluais dhan rum-obrach air an taobh deas" + +#: data/50-mutter-navigation.xml:135 +msgid "Move to workspace above" +msgstr "Gluais dhan rum-obrach aig a’ bharr" + +#: data/50-mutter-navigation.xml:138 +msgid "Move to workspace below" +msgstr "Gluais dhan rum-obrach aig a’ bhonn" + +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "An siostam" + +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "" + +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Foir-shealladh air na gnìomhachdan" + +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Aisig ath-ghoiridean a’ mheur-chlàir" + +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Uinneagan" + +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "Gnìomhaich clàr-taice na h-uinneige" + +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Toglaich am modh làn-sgrìn" + +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "Toglaich staid an làn-mheudachaidh" + +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "Làn-mheudaich an uinneag" + +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Aisig an uinneag" + +#: data/50-mutter-windows.xml:18 +msgid "Toggle shaded state" +msgstr "Toglaich staid an sgàileachaidh" + +#: data/50-mutter-windows.xml:20 +msgid "Close window" +msgstr "Dùin an uinneag" + +#: data/50-mutter-windows.xml:22 +msgid "Hide window" +msgstr "Cuir an uinneag am falach" + +#: data/50-mutter-windows.xml:24 +msgid "Move window" +msgstr "Gluais an uinneag" + +#: data/50-mutter-windows.xml:26 +msgid "Resize window" +msgstr "Atharraich meud na h-uinneige" + +#: data/50-mutter-windows.xml:29 +msgid "Toggle window on all workspaces or one" +msgstr "Toglaich an uinneag air a h-uile rum-obrach no aonan" + +#: data/50-mutter-windows.xml:31 +msgid "Raise window if covered, otherwise lower it" +msgstr "Tog an uinneag nuair a thèid a còmhdachadh air neo ìslich i" + +#: data/50-mutter-windows.xml:33 +msgid "Raise window above other windows" +msgstr "Tog an uinneag os cionn càich" + +#: data/50-mutter-windows.xml:35 +msgid "Lower window below other windows" +msgstr "Ìslich an uinneag fo na h-uinneagan eile" + +#: data/50-mutter-windows.xml:37 +msgid "Maximize window vertically" +msgstr "Làn-mheudaich an uinneag gu h-ingearach" + +#: data/50-mutter-windows.xml:39 +msgid "Maximize window horizontally" +msgstr "Làn-mheudaich an uinneag air a’ chòmhnard" + +#: data/50-mutter-windows.xml:43 +msgid "View split on left" +msgstr "Sgoilt an t-sealladh air an taobh chì" + +#: data/50-mutter-windows.xml:47 +msgid "View split on right" +msgstr "Sgoilt an t-sealladh air an taobh deas" + +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" + +#: data/org.gnome.mutter.gschema.xml.in:155 +#| msgid "Switch monitor" +msgid "Switch monitor configurations" +msgstr "Gearr leum eadar rèiteachaidhean monatair" + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. +#. +#: src/backends/meta-input-settings.c:2167 +#, c-format +#| msgid "Mode Switch: Mode %d" +msgid "Mode Switch (Group %d)" +msgstr "Suidse nam modh (Buidheann %d)" + +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2190 +msgid "Switch monitor" +msgstr "Gearr leum gu monatair eile" + +#: src/backends/meta-input-settings.c:2192 +msgid "Show on-screen help" +msgstr "Seall a’ chobhair air an sgrìn" + +#: src/backends/meta-monitor-manager.c:908 +msgid "Built-in display" +msgstr "Uidheam-taisbeanaidh ’na broinn" + +#: src/backends/meta-monitor-manager.c:931 +msgid "Unknown" +msgstr "Chan eil fhios" + +#: src/backends/meta-monitor-manager.c:933 +msgid "Unknown Display" +msgstr "Uidheam-taisbeanaidh nach aithne dhuinn" + +#. TRANSLATORS: this is a monitor vendor name, followed by a +#. * size in inches, like 'Dell 15"' +#. +#: src/backends/meta-monitor-manager.c:941 +#, c-format +msgid "%s %s" +msgstr "%s %s" + +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:479 +#, c-format +msgid "" +"Another compositing manager is already running on screen %i on display “%s”." +msgstr "" + +#: src/core/bell.c:194 +msgid "Bell event" +msgstr "" + +#: src/core/display.c:608 +#, c-format +msgid "Failed to open X Window System display “%s”\n" +msgstr "" + +#: src/core/main.c:189 +msgid "Disable connection to session manager" +msgstr "" + +#: src/core/main.c:195 +msgid "Replace the running window manager" +msgstr "" + +#: src/core/main.c:201 +msgid "Specify session management ID" +msgstr "" + +#: src/core/main.c:206 +msgid "X Display to use" +msgstr "" + +#: src/core/main.c:212 +msgid "Initialize session from savefile" +msgstr "" + +#: src/core/main.c:218 +msgid "Make X calls synchronous" +msgstr "" + +#: src/core/main.c:225 +msgid "Run as a wayland compositor" +msgstr "" + +#: src/core/main.c:231 +msgid "Run as a nested compositor" +msgstr "" + +#: src/core/main.c:239 +msgid "Run as a full display server, rather than nested" +msgstr "" + +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:147 +#, c-format +msgid "“%s” is not responding." +msgstr "" + +#: src/core/meta-close-dialog-default.c:149 +msgid "Application is not responding." +msgstr "" + +#: src/core/meta-close-dialog-default.c:154 +msgid "" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." +msgstr "" + +#: src/core/meta-close-dialog-default.c:161 +msgid "_Force Quit" +msgstr "Sparr _fàgail air" + +#: src/core/meta-close-dialog-default.c:161 +msgid "_Wait" +msgstr "_Fuirich" + +#: src/core/mutter.c:39 +#, c-format +msgid "" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" +msgstr "" + +#: src/core/mutter.c:53 +msgid "Print version" +msgstr "" + +#: src/core/mutter.c:59 +msgid "Mutter plugin to use" +msgstr "" + +#: src/core/prefs.c:1997 +#, c-format +msgid "Workspace %d" +msgstr "Rum-obrach %d" + +#: src/core/screen.c:583 +#, c-format +msgid "" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." +msgstr "" + +#: src/core/screen.c:668 +#, c-format +msgid "Screen %d on display “%s” is invalid\n" +msgstr "" + +#: src/core/util.c:120 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "" + +#: src/wayland/meta-wayland-tablet-pad.c:563 +#, c-format +msgid "Mode Switch: Mode %d" +msgstr "Suidse nam modh: Modh %d" + +#: src/x11/session.c:1815 +msgid "" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." +msgstr "" + +#: src/x11/window-props.c:559 +#, c-format +msgid "%s (on %s)" +msgstr "%s (air %s)" diff --git a/po/gl.po b/po/gl.po index 614e901a8..3a556ee8f 100644 --- a/po/gl.po +++ b/po/gl.po @@ -1,429 +1,281 @@ -# translation of metacity.HEAD.gl.po to +# Galician translation of mutter. # Copyright (C) 2001, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. -# -# +# Proxecto Trasno - Adaptación do software libre á lingua galega: Se desexas +# colaborar connosco, podes atopar máis información en http://www.trasno.net # Manuel A. Fernández Montecelo <manuel@sindominio.net>, 2001, 2005. # Ignacio Casal Quinteiro <nacho.resa@gmail.com>, 2005, 2006. # Ignacio Casal Quinteiro <icq@cvs.gnome.org>, 2007. # Ignacio Casal Quinteiro <icq@svn.gnome.org>, 2007, 2008. # Mancomún - Centro de Referencia e Servizos de Software Libre <g11n@mancomun.org>, 2009. -# Fran Diéguez <frandieguez@gnome.org>, 2010, 2011. -# Fran Dieguez <frandieguez@gnome.org>, 2009, 2011, 2012. -# +# Fran Diéguez <frandieguez@gnome.org>, 2009, 2010, 2011, 2012. +# Leandro Regueiro <leandro.regueiro@gmail.com>, 2012. +# Fran Dieguez <frandieguez@gnome.org>, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019. msgid "" msgstr "" "Project-Id-Version: gl\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-03-14 23:08+0100\n" -"PO-Revision-Date: 2012-03-14 23:09+0100\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2020-02-23 17:41+0000\n" +"PO-Revision-Date: 2020-02-26 21:56+0100\n" "Last-Translator: Fran Dieguez <frandieguez@gnome.org>\n" -"Language-Team: Galician <gnome-l10n-gl@gnome.org>\n" +"Language-Team: Galician\n" "Language: gl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n!=1);\n" -"X-Generator: Lokalize 1.2\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 2.3\n" +"X-Project-Style: gnome\n" -#: ../src/50-muffin-windows.xml.in.h:1 -msgid "Windows" -msgstr "Xanelas" - -#: ../src/50-muffin-windows.xml.in.h:2 -msgid "View split on left" -msgstr "Ver división á esquerda" - -#: ../src/50-muffin-windows.xml.in.h:3 -msgid "View split on right" -msgstr "Ver división á dereita" - -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format -msgid "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." -msgstr "" -"Non foi posíbel obter a selección do xestor de xanelas na pantalla %i na " -"visualización «%s»" - -#: ../src/core/bell.c:307 -msgid "Bell event" -msgstr "Evento de campá" - -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Petición de información de xanela descoñecida: %d" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Navegación" -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> non está respondendo." +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Mover xanela ao espazo de traballo 1" -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "O Aplicativo non está respondendo." +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Mover xanela ao espazo de traballo 2" -#: ../src/core/delete.c:119 -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "" -"Pode elixir esperar un momento para ver se continúa ou forzar ao aplicativo " -"a pechar completamente." +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Mover xanela ao espazo de traballo 3" -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "Espe_rar" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Mover xanela ao espazo de traballo 4" -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "_Forzar a saída" +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Mover xanela ao último espazo de traballo" -#: ../src/core/display.c:387 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "Falta a extensión %s que se require para a composición" +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "Mover xanela un espazo de traballo cara a arriba" -#: ../src/core/display.c:453 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Produciuse un fallo ao abrir a pantalla do X Window System «%s»\n" +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "Mover xanela un espazo de traballo cara a abaixo" -#: ../src/core/keybindings.c:852 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "" -"Algún outro programa xa está usando a tecla %s cos modificadores %x como " -"combinación\n" +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "Mover xanela un monitor á esquerda" -#: ../src/core/main.c:206 -msgid "Disable connection to session manager" -msgstr "Desactivar a conexión ao xestor de sesión" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "Mover xanela un monitor á dereita" -#: ../src/core/main.c:212 -msgid "Replace the running window manager" -msgstr "Substituír o xestor de xanelas en execución" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "Mover xanela un monitor arriba" -#: ../src/core/main.c:218 -msgid "Specify session management ID" -msgstr "Especificar o ID de xestión de sesión" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "Mover xanela un espazo de traballo abaixo" -#: ../src/core/main.c:223 -msgid "X Display to use" -msgstr "Pantalla X que se vai usar" +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "Cambiar entre aplicacións" -#: ../src/core/main.c:229 -msgid "Initialize session from savefile" -msgstr "Iniciar sesión desde o ficheiro de salvagarda" +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "Cambiar á anterior aplicación" -#: ../src/core/main.c:235 -msgid "Make X calls synchronous" -msgstr "Facer que as chamadas a X sexan sincrónicas" +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "Cambiar xanelas" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Fallou ao dixitalizar o directorio de temas: %s\n" +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "Cambiar á xanela anterior" -#: ../src/core/main.c:520 -#, c-format -msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "" -"Non foi posíbel atopar ningún tema! Asegúrese de que %s existe e de que " -"contén os temas habituais.\n" +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "Cambiar entre as xanelas dunha aplicación" -#: ../src/core/muffin.c:40 -#, c-format -msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "Cambia á xanela anterior dunha aplicación" -#: ../src/core/muffin.c:54 -msgid "Print version" -msgstr "Imprimir versión" +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "Cambiar entre os controis do sistema" -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "Lista de separadas por comas dos complementos do compositor" +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "Cambia ao control do sistema anterior" -#: ../src/core/prefs.c:1077 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"Desactiváronse os arranxos para aplicativos danados. Pode que algúns " -"aplicativos non se comporten correctamente.\n" +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "Cambiar xanelas directamente" -#: ../src/core/prefs.c:1152 -#, c-format -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "" -"Non foi posíbel analizar a descrición do tipo de letra «%s» da chave " -"GSettings %s\n" +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "Cambia directamente á xanela anterior" -#: ../src/core/prefs.c:1218 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"«%s» atopados na base de datos de configuración non é un valor válido para o " -"modificador do botón do rato\n" +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "Cambiar entre as xanelas dunha aplicación directamente" -#: ../src/core/prefs.c:1739 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "" -"«%s» atopados na base de datos de configuración non é un valor válido para a " -"combinación de teclas «%s»\n" +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "Cambia directamente á xanela anterior dunha aplicación" -#: ../src/core/prefs.c:1836 -#, c-format -msgid "Workspace %d" -msgstr "Espazo de traballo %d" +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "Cambiar entre os controis do sistema directamente" -#: ../src/core/screen.c:730 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "A pantalla %d na visualización «%s» non é válida\n" +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "Cambiar directamente ao control do sistema anterior" -#: ../src/core/screen.c:746 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"A visualización %d na pantalla «%s» ten xa un xestor de xanelas, tente usar " -"a opción --replace para substituír o xestor de xanelas.\n" +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "Ocultar todas as xanelas normais" -#: ../src/core/screen.c:773 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "" -"Non foi posíbel obter a selección do xestor de xanelas na pantalla %d na " -"visualización «%s»\n" +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "Cambiar ao espazo de traballo 1" -#: ../src/core/screen.c:828 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "A visualización %d na pantalla «%s» ten xa un xestor de xanelas\n" +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "Cambiar ao espazo de traballo 2" -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "Non foi posíbel liberar a visualización %d na pantalla «%s»\n" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "Cambiar ao espazo de traballo 3" -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Non foi posíbel crear o directorio «%s»: %s\n" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "Cambiar ao espazo de traballo 4" -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "Non foi posíbel abrir o ficheiro de sesión «%s» para escritura: %s\n" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "Cambiar ao último espazo de traballo" -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Erro ao escribir o ficheiro de sesión «%s»: %s\n" +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "Mover ao espazo de arriba" -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Erro ao pechar o ficheiro de sesión «%s»: %s\n" +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "Mover ao espazo de traballo de abaixo" -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Produciuse un fallo ao analizar o ficheiro de sesión gardado: %s\n" +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "Sistema" -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "O atributo <muffin_session> foi visto pero xa temos o ID de sesión" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Mostrar o diálogo de executar orde" -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Atributo descoñecido %s no elemento <%s>" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Mostrar a vista xeral de actividades" -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "etiqueta <window> aniñada" +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Restaurar os atallos de teclado" -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "Elemento descoñecido %s" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Xanelas" -#: ../src/core/session.c:1809 -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" -"Estas xanelas non soportan "save current setup" e terán que " -"reiniciarse manualmente a próxima vez que inicie a sesión." +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "Activar o menú da xanela" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Produciuse un fallo ao abrir o rexistro de depuración: %s\n" +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Trocar modo de pantalla completa" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Produciuse un fallo ao facer fdopen() no ficheiro de rexistro %s: %s\n" +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "Trocar o estado maximizado" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "Ficheiro de rexistro %s aberto\n" +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "Maximizar xanela" -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "Muffin foi compilado sen compatibilidade para o modo detallado\n" +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Restaurar xanela" -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "Xestor de xanelas: " +#: data/50-mutter-windows.xml:18 +msgid "Close window" +msgstr "Pechar xanela" -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "Erro no xestor de xanelas: " +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "Ocultar xanela" -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "Aviso do xestor de xanelas: " +#: data/50-mutter-windows.xml:22 +msgid "Move window" +msgstr "Mover xanela" -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "Erro do xestor de xanelas: " +#: data/50-mutter-windows.xml:24 +msgid "Resize window" +msgstr "Redimensionar xanela" -#. first time through -#: ../src/core/window.c:7224 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"A xanela %s estabelece SM_CLIENT_ID sobre si mesma en vez de facelo na " -"xanela WM_CLIENT_LEADER como está especificado no ICCCM.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7887 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size " -"%d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"A xanela %s estabeleceu a propiedade MWM indicando que non é redimensionábel " -"mais configurou o tamaño mínimo a %d x %d e o tamaño máximo a %d x %d, isto " -"non ten moito sentido.\n" +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "Trocar que a xanela apareza en tódolos espazos de traballo ou nun" -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "O aplicativo configurou un _NET_WM_PID %lu falso\n" +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "Elevar a xanela se está cuberta por outra, en caso contrario baixala" -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (en %s)" +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "Subir a xanela por enriba doutras xanelas" -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "" -"WM_TRANSIENT_FOR non válido para a xanela 0x%lx especificada para %s.\n" +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "Baixar xanela debaixo doutras xanelas" -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "WM_TRANSIENT_FOR xanela 0x%lx para %s crearía un bucle.\n" +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "Maximizar xanela verticalmente" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"A xanela 0x%lx ten a propiedade %s\n" -"que se esperaba que tivese o tipo %s co formato %d\n" -"e actualmente ten un tipo %s co formato %d e n_items %d.\n" -"Isto non parece ser un erro do aplicativo nin do xestor de xanelas.\n" -"A xanela ten título=«%s» a clase=«%s» e o nome=«%s»\n" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "Maximizar xanela horizontalmente" -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "A propiedade %s na xanela 0x%lx contén UTF-8 non válido\n" +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "Dividir vista á esquerda" -#: ../src/core/xprops.c:494 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"A propiedade %s na xanela 0x%lx contén UTF-8 non válido para o elemento da " -"lista %d\n" +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "Dividir vista á dereita" -#: ../src/muffin.desktop.in.h:1 ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 +#: data/org.gnome.mutter.gschema.xml.in:7 msgid "Modifier to use for extended window management operations" msgstr "" "Modificador que se vai usar para as accións modificadas de xestión de xanela" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 +#: data/org.gnome.mutter.gschema.xml.in:8 msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." msgstr "" "Esta tecla iniciará o «overlay», que é unha combinación da vista previa da " -"xanela e o sistema de inicialización de aplicativos. O valor predeterminado " +"xanela e o sistema de inicialización de aplicación. O valor predeterminado " "nun PC é a «Tecla Windows». Espérase que este enlace sexa configurado ao " "valor predeterminado ou á cadena baleira." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 +#: data/org.gnome.mutter.gschema.xml.in:20 msgid "Attach modal dialogs" msgstr "Anexar os diálogos modais" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 +#: data/org.gnome.mutter.gschema.xml.in:21 msgid "" "When true, instead of having independent titlebars, modal dialogs appear " "attached to the titlebar of the parent window and are moved together with " @@ -433,23 +285,11 @@ msgstr "" "diálogos modais aparecerán anexados á barra de título da xanela pai e " "moveranse de forma conxunta á xanela pai." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -msgid "Live Hidden Windows" -msgstr "Xanelas agochadas en vivo" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"Determina se as xanelas agochadas (p.ex., xanelas minimizadas ou xanelas " -"noutros espazos de traballo) deben manterse activas." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 +#: data/org.gnome.mutter.gschema.xml.in:30 msgid "Enable edge tiling when dropping windows on screen edges" msgstr "Activar o mosaico nos bordos ao arrastrar xanelas aos bordos da xanela" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 +#: data/org.gnome.mutter.gschema.xml.in:31 msgid "" "If enabled, dropping windows on vertical screen edges maximizes them " "vertically and resizes them horizontally to cover half of the available " @@ -460,25 +300,25 @@ msgstr "" "metade da área dispoñíbel. Arrastrar xanelas ao bordo superior da pantalla " "maximízaas por completo." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 +#: data/org.gnome.mutter.gschema.xml.in:40 msgid "Workspaces are managed dynamically" msgstr "Os espazos de traballo xestiónanse dinamicamente" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 +#: data/org.gnome.mutter.gschema.xml.in:41 msgid "" -"Determines whether workspaces are managed dynamically or whether there's a " +"Determines whether workspaces are managed dynamically or whether there’s a " "static number of workspaces (determined by the num-workspaces key in org." "gnome.desktop.wm.preferences)." msgstr "" -"Determina se os espazos de traballo se xestionan dinamicamente ou se hai un " +"Determina se os espazos de traballo se xestionan dinámicamente ou se hai un " "número estático de áreas de traballo (determinado pola chave «num-" -"workspaces» en «org.cinnamon.desktop.wm.preferences»)." +"workspaces» en «org.gnome.desktop.wm.preferences»)." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 +#: data/org.gnome.mutter.gschema.xml.in:50 msgid "Workspaces only on primary" msgstr "Espazos de traballo só no principal" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 +#: data/org.gnome.mutter.gschema.xml.in:51 msgid "" "Determines whether workspace switching should happen for windows on all " "monitors or only for windows on the primary monitor." @@ -486,11 +326,11 @@ msgstr "" "Determina se o troco de espazo de traballo debe facerse para as xanelas de " "todos os monitores ou só para o monitor principal." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 +#: data/org.gnome.mutter.gschema.xml.in:59 msgid "No tab popup" msgstr "No hai lapela emerxente" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 +#: data/org.gnome.mutter.gschema.xml.in:60 msgid "" "Determines whether the use of popup and highlight frame should be disabled " "for window cycling." @@ -498,1496 +338,441 @@ msgstr "" "Determina se se debe desactivar o uso de xanelas emerxentes e marcos " "realzados ao cambiar entre xanelas." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Retrasar o cambio de enfoque até que o punteiro se deteña ao moverse" + +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" +"Se está estabelecido a verdadeiro e o modo de enfoque é «sloopy» ou «mouse» " +"entón o enfoque non se cambiará de forma inmediata ao entrar nunha xanela, " +"só cando o punteiro se deteña sobre ela." + +#: data/org.gnome.mutter.gschema.xml.in:79 msgid "Draggable border width" msgstr "Anchura arrastrábel do bordo" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 +#: data/org.gnome.mutter.gschema.xml.in:80 msgid "" -"The amount of total draggable borders. If the theme's visible borders are " +"The amount of total draggable borders. If the theme’s visible borders are " "not enough, invisible borders will be added to meet this value." msgstr "" "A cantidade total de bordo arrastrábel. Se os bordos visíbeis do tema non " "son suficientes, engadiranse bordos invisíbeis para satisfacer este valor." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:17 -msgid "Select window from tab popup" -msgstr "Seleccionar xanela da lapela emerxente" +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "" +"Maximizar automaticamente as xanelas que case teñan o tamaño da pantalla" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:18 -msgid "Cancel tab popup" -msgstr "Cancelar lapela emerxente" +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" +"Se está activada, as xanelas novas que inicialmente teñan o tamaño da " +"pantalla maximizaranse automaticamente." -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "Uso: %s\n" - -#: ../src/ui/frames.c:1158 -msgid "Close Window" -msgstr "Pechar a xanela" - -#: ../src/ui/frames.c:1161 -msgid "Window Menu" -msgstr "Menú da xanela" - -#: ../src/ui/frames.c:1164 -msgid "Minimize Window" -msgstr "Minimizar a xanela" - -#: ../src/ui/frames.c:1167 -msgid "Maximize Window" -msgstr "Maximizar a xanela" - -#: ../src/ui/frames.c:1170 -msgid "Restore Window" -msgstr "Restaurar a xanela" - -#: ../src/ui/frames.c:1173 -msgid "Roll Up Window" -msgstr "Pregar a xanela" - -#: ../src/ui/frames.c:1176 -msgid "Unroll Window" -msgstr "Despregar a xanela" - -#: ../src/ui/frames.c:1179 -msgid "Keep Window On Top" -msgstr "Manter a xanela na parte superior" - -#: ../src/ui/frames.c:1182 -msgid "Remove Window From Top" -msgstr "Quitar a xanela da parte superior" - -#: ../src/ui/frames.c:1185 -msgid "Always On Visible Workspace" -msgstr "Sempre no espazo de traballo visíbel" - -#: ../src/ui/frames.c:1188 -msgid "Put Window On Only One Workspace" -msgstr "Pór a xanela nun só espazo de traballo" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "Mi_nimizar" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "Ma_ximizar" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "Resta_urar" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "P_regar" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "_Despregar" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "_Mover" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "_Redimensionar" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "Mover a barra de título na _pantalla" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "Sempre na parte _superior" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "Se_mpre no espazo de traballo visíbel" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "_Só neste espazo de traballo" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "Mover ao espazo da _esquerda" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "Mover ao espazo da dere_ita" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "Mover ao espazo de _arriba" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "Mover ao espazo de a_baixo" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "_Pechar" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "Espazo de traballo %d%n" +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Dispor as novas xanelas no centro" -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "Espazo de traballo 1_0" +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" +"Cando está verdadeiro, as novas xanelas sempre se porán no centro da " +"pantalla activa." -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "Espazo de traballo %s%d" +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Activar as características experimentais" -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "Mover a outro _espazo de traballo" +#: data/org.gnome.mutter.gschema.xml.in:108 +msgid "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes " +"mutter request a low priority real-time scheduling. The executable or user " +"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — " +"initializes Xwayland lazily if there are X11 clients. Requires restart." +msgstr "" +"Para activar as características experimentais, engada a palabra chave da " +"característica á lista. Depende da característica que se deba reiniciar ou " +"non o compositor. Calquera característica experimental pode non estar " +"dispoñíbel ou ser configurábel. Non agarde que o que se engada neste " +"escenario sirva como proba futura. As palabras chave actualmente dispoñíbeis " +"son: «scale-monitor-framebuffer» — fai que mutter de maneira predeterminada " +"dispoña os monitores lóxicos nun espacio lóxico de coordenadas de píxeles, " +"mentres escala framebuffers de monitores no lugar do contido de xanela, para " +"administrar monitores HiDPI. Non require un reinicio. • “rt-scheduler” — fai " +"que mutter solicite unha prioritización de tempo real de baixa prioridade. O " +"executábel ou usuario debe ter CAP_SYS_NICE. Require reiniciar. “autostart-" +"xwayland” — Inicia Xwayland só se hai clientes X11. Require reiniciar." -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Maiús" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hiper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" +#: data/org.gnome.mutter.gschema.xml.in:134 +msgid "Modifier to use to locate the pointer" +msgstr "Modificador a usar para localizar o punteiro" -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" +#: data/org.gnome.mutter.gschema.xml.in:135 +msgid "This key will initiate the “locate pointer” action." +msgstr "Esta tecla iniciará a acción «localizar punteiro»." -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "superior" +#: data/org.gnome.mutter.gschema.xml.in:142 +msgid "Timeout for check-alive ping" +msgstr "Tempo de espera para comprobación de ping" -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "inferior" +#: data/org.gnome.mutter.gschema.xml.in:143 +msgid "" +"Number of milliseconds a client has to respond to a ping request in order to " +"not be detected as frozen. Using 0 will disable the alive check completely." +msgstr "" +"Número de milisegundos que ten un cliente para responder a ping e que non se " +"lle detecte como caído. Usar 0 desactivará esta comprobación." -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "esquerda" +#: data/org.gnome.mutter.gschema.xml.in:165 +msgid "Select window from tab popup" +msgstr "Seleccionar xanela da lapela emerxente" -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "dereita" +#: data/org.gnome.mutter.gschema.xml.in:170 +msgid "Cancel tab popup" +msgstr "Cancelar lapela emerxente" -#: ../src/ui/theme.c:286 +#: data/org.gnome.mutter.gschema.xml.in:175 +msgid "Switch monitor configurations" +msgstr "Cambiar preferencias do monitor" + +#: data/org.gnome.mutter.gschema.xml.in:180 +msgid "Rotates the built-in monitor configuration" +msgstr "Rota a configuración do monitor embebido" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Cambiar á VT 1" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Cambiar á VT 2" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Cambiar á VT 3" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Cambiar á VT 4" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Cambiar á VT 5" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Cambiar á VT 6" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Cambiar á VT 7" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Cambiar á VT 8" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Cambiar á VT 9" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Cambiar á VT 10" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Cambiar á VT 11" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Cambiar á VT 12" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "Reactivar os atallos" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow X11 grabs to lock keyboard focus with Xwayland" +msgstr "" +"Permitir os capturadores de X11 bloquear o foco do teclado con Xwayland" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 +msgid "" +"Allow all keyboard events to be routed to X11 “override redirect” windows " +"with a grab when running in Xwayland. This option is to support X11 clients " +"which map an “override redirect” window (which do not receive keyboard " +"focus) and issue a keyboard grab to force all keyboard events to that " +"window. This option is seldom used and has no effect on regular X11 windows " +"which can receive keyboard focus under normal circumstances. For a X11 grab " +"to be taken into account under Wayland, the client must also either send a " +"specific X11 ClientMessage to the root window or be among the applications " +"white-listed in key “xwayland-grab-access-rules”." +msgstr "" +"Permite que todos os eventos de teclado se redirixan a xanelas X11 " +"«invalidar redirección» con un capturador ao executarse en Xwayland. Esta " +"opción é para darlle compatibilidade a clientes X11 que asignan unha xanela " +"de «invalidación de redirección» (que non recibe o foco do teclado) e facer " +"unha captura do teclado para forzar que todos os eventos de teclado vaia a " +"esta xanela. Esta opción é rara vez usada e non ten efecto en xanelas X11 " +"normais que poden recibir o foco do teclado baixo circunstancias normais. " +"Para que a captura de X11 se leve a cabo baixo Wayland, o cliente debe " +"enviar un ClienteMessage de X11 específico á xanela pai ou estar na lista " +"branca de aplicacións na chave «xwayland-grab-access-rules»." + +#: data/org.gnome.mutter.wayland.gschema.xml.in:84 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "Aplicaciones de Xwayland que poden capturar o teclado" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:85 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "" +"Lista de nomes de recursos ou clases de recursos para as xanelas X11 tanto " +"permitidas como non permitidas para a captura do teclado en X11 baixo " +"Xwayland. O nome do recurso ou a clase do recurso da xanela X11 dada pode " +"obterse usando a orde «xprop WM_CLASS». Admítense os comodíns «*» e os " +"jokers \"?\" nos valores. Os valores comezando con «!» incluiranse na lista " +"negra, que ten precedencia sobre a lista branca, para revogar aplicacións " +"desde a lista por omisión do sistema. A lista por omisión do sistema inclúe " +"as seguintes aplicacións: “@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Os usuarios " +"poden romper unha captura existente usando un atallo de teclado específico " +"definido na chave de atallo «restore-shortcuts»." + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. +#. +#: src/backends/meta-input-settings.c:2567 #, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "a xeometría do marco non especifica a dimensión «%s»" +msgid "Mode Switch (Group %d)" +msgstr "Modo conmutador (Grupo %d)" -#: ../src/ui/theme.c:305 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "a xeometría do marco non especifica a dimensión «%s» para o bordo «%s»" +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2590 +msgid "Switch monitor" +msgstr "Cambiar monitor" -#: ../src/ui/theme.c:342 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "A proporción de aspecto do botón %g non é razoábel" +#: src/backends/meta-input-settings.c:2592 +msgid "Show on-screen help" +msgstr "Mostrar axuda en pantalla" -#: ../src/ui/theme.c:354 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "A xeometría do marco non especifica o tamaño dos botóns" +#: src/backends/meta-monitor.c:223 +msgid "Built-in display" +msgstr "Pantalla embebida" -#: ../src/ui/theme.c:1067 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "Os degradados deben ter polo menos dúas cores" +#: src/backends/meta-monitor.c:252 +msgid "Unknown" +msgstr "Descoñecido" -#: ../src/ui/theme.c:1219 -#, c-format -msgid "" -"GTK custom color specification must have color name and fallback in " -"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" -msgstr "" -"A especificación de cor do GTK debe ter un nome de cor e nome alternativo " -"entre parénteses, por exemplo: gtk:custom(foo,bar); non foi posíbel analizar " -"«%s»." +#: src/backends/meta-monitor.c:254 +msgid "Unknown Display" +msgstr "Pantalla descoñecida" -#: ../src/ui/theme.c:1235 +#: src/backends/meta-monitor.c:262 #, c-format -msgid "" -"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" -"_ are valid" -msgstr "" -"O carácter «%c» non é válido no parámetro «color_name» de «gtk:custom», só " -"«A-Za-z0-9» son válidos" +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme.c:1249 +#: src/backends/meta-monitor.c:270 #, c-format -msgid "" -"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " -"fit the format" -msgstr "" -"O formato de «gtk:custom» é «gtk:custom(nome_de_cor,nome_alternativo», «%s» " -"non respecta o formato" +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme.c:1294 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"A especificación de cor do GTK debe ter o estado entre parénteses, exemplo. " -"gtk:fg[NORMAL] onde NORMAL é o estado; non foi posíbel analizar «%s»" +#. Translators: this string will appear in Sysprof +#: src/backends/meta-profiler.c:79 +msgid "Compositor" +msgstr "Compositor" -#: ../src/ui/theme.c:1308 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:533 #, c-format msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +"Another compositing manager is already running on screen %i on display “%s”." msgstr "" -"A especificación de cor do GTK debe ter unha paréntese pechada despois do " -"estado, exemplo. gtk:fg[NORMAL] onde NORMAL é o estado; non foi posíbel " -"analizar «%s»" - -#: ../src/ui/theme.c:1319 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "Non se entende o estado «%s» na especificación da cor" +"Xa se está a executar outro xestor de composición na pantalla %i na " +"visualización «%s»." -#: ../src/ui/theme.c:1332 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "Non se entende o compoñente de cor «%s» na especificación da cor" +#: src/core/bell.c:192 +msgid "Bell event" +msgstr "Evento de campá" -#: ../src/ui/theme.c:1361 -#, c-format -msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" -msgstr "" -"O formato de blend é «blend/bg_color/fg_color/alpha», «%s»non coincide co " -"formato" +#: src/core/main.c:190 +msgid "Disable connection to session manager" +msgstr "Desactivar a conexión ao xestor de sesión" -#: ../src/ui/theme.c:1372 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "Non foi posíbel analizar o valor alfa «%s» na cor mesturada" +#: src/core/main.c:196 +msgid "Replace the running window manager" +msgstr "Substituír o xestor de xanelas en execución" -#: ../src/ui/theme.c:1382 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "O valor alfa «%s» na cor mesturada non está entre 0.0 e 1.0" +#: src/core/main.c:202 +msgid "Specify session management ID" +msgstr "Especificar o ID de xestión de sesión" -#: ../src/ui/theme.c:1429 -#, c-format -msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "" -"O formato de sombreado é \"shade/base_color/factor\", «%s» non coincide co " -"formato" +#: src/core/main.c:207 +msgid "X Display to use" +msgstr "Pantalla X que se vai usar" -#: ../src/ui/theme.c:1440 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "Non foi posíbel o factor de sombreado «%s» na cor sombreada" +#: src/core/main.c:213 +msgid "Initialize session from savefile" +msgstr "Inicializar sesión desde o ficheiro de salvagarda" -#: ../src/ui/theme.c:1450 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "O factor de sombreado «%s» na cor sombreada é negativo" +#: src/core/main.c:219 +msgid "Make X calls synchronous" +msgstr "Facer que as chamadas a X sexan sincrónicas" -#: ../src/ui/theme.c:1479 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Non foi posíbel analizar a cor «%s»" +#: src/core/main.c:226 +msgid "Run as a wayland compositor" +msgstr "Executar como compositor de wayland" -#: ../src/ui/theme.c:1790 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "" -"A expresión de coordenadas contén un carácter «%s» que non está permitido" +#: src/core/main.c:232 +msgid "Run as a nested compositor" +msgstr "Executar como compositor anidado" -#: ../src/ui/theme.c:1817 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "" -"A expresión de coordenadas contén un número de coma flotante «%s» que non " -"foi posíbel analizar" +#: src/core/main.c:238 +msgid "Run wayland compositor without starting Xwayland" +msgstr "Executar o compositor de wayland sen iniciar Xwayland" -#: ../src/ui/theme.c:1831 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "" -"A expresión de coordenadas contén un enteiro «%s» que non foi posíbel " -"analizar" +#: src/core/main.c:246 +msgid "Run as a full display server, rather than nested" +msgstr "Executar como un servidor de pantalla completo, fronte a un aniñado" -#: ../src/ui/theme.c:1953 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "" -"A expresión de coordenadas contén un operador non válido ao inicio do seu " -"texto: «%s»" +#: src/core/main.c:252 +msgid "Run with X11 backend" +msgstr "Executar coa infraestructura de X11" -#: ../src/ui/theme.c:2010 +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:151 #, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "A expresión de coordenadas está baleira ou non se entendeu" +msgid "“%s” is not responding." +msgstr "«%s» non está respondendo." -#: ../src/ui/theme.c:2121 ../src/ui/theme.c:2131 ../src/ui/theme.c:2165 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "A expresión de coordenadas resultou nun erro de división por cero" +#: src/core/meta-close-dialog-default.c:153 +msgid "Application is not responding." +msgstr "A aplicación non está respondendo." -#: ../src/ui/theme.c:2173 -#, c-format +#: src/core/meta-close-dialog-default.c:158 msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." msgstr "" -"A expresión de coordenadas tentou usar un operador mod cun número de coma " -"flotante" +"Pode elixir esperar un momento para ver se continúa ou forzar á aplicación a " +"pechar completamente." -#: ../src/ui/theme.c:2229 +#: src/core/meta-close-dialog-default.c:165 +msgid "_Force Quit" +msgstr "_Forzar a saída" + +#: src/core/meta-close-dialog-default.c:165 +msgid "_Wait" +msgstr "Espe_rar" + +#: src/core/mutter.c:38 #, c-format msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" msgstr "" -"A expresión de coordenadas ten un operador «%s» onde se esperaba un operando" +"mutter %s\n" +"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" -#: ../src/ui/theme.c:2238 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "" -"A expresión de coordenadas ten un operando onde se esperaba un operador" +#: src/core/mutter.c:52 +msgid "Print version" +msgstr "Imprimir versión" -#: ../src/ui/theme.c:2246 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "A expresión de coordenadas remata cun operador en vez dun operando" +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "Engadido de mutter que usar" -#: ../src/ui/theme.c:2256 +#: src/core/prefs.c:1911 #, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" -"A expresión de coordenadas ten un operador \"%c\" seguido do operador \"%c\" " -"sen un operando entre eles" +msgid "Workspace %d" +msgstr "Espazo de traballo %d" -#: ../src/ui/theme.c:2407 ../src/ui/theme.c:2452 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "" -"A expresión de coordenadas ten unha variábel ou constante descoñecida «%s»" +#: src/core/util.c:122 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter foi compilado sen compatibilidade para o modo detallado\n" -#: ../src/ui/theme.c:2506 +#: src/wayland/meta-wayland-tablet-pad.c:568 #, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "O analizador da expresión de coordenadas desbordou o seu búfer." +msgid "Mode Switch: Mode %d" +msgstr "Modo conmutador: Modo %d" -#: ../src/ui/theme.c:2535 +#: src/x11/meta-x11-display.c:676 #, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" +msgid "" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." msgstr "" -"A expresión de coordenadas ten unha paréntese pechada sen unha paréntese " -"aberta" +"A pantalla «%s» ten xa un xestor de xanelas, tente usar a opción --replace " +"para substituír o xestor de xanelas." -#: ../src/ui/theme.c:2599 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "" -"A expresión de coordenadas ten unha paréntese aberta sen unha paréntese " -"pechada" +#: src/x11/meta-x11-display.c:1089 +msgid "Failed to initialize GDK\n" +msgstr "Procuciuse un fallo ao inicializar GDK\n" -#: ../src/ui/theme.c:2610 +#: src/x11/meta-x11-display.c:1113 #, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "A expresión de coordenadas non parece ter nin operadores nin operandos" +msgid "Failed to open X Window System display “%s”\n" +msgstr "Produciuse un erro ao abrir a visualización do X Window System «%s»\n" -#: ../src/ui/theme.c:2822 ../src/ui/theme.c:2842 ../src/ui/theme.c:2862 +#: src/x11/meta-x11-display.c:1196 #, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "O tema contiña unha expresión que resultou ser un erro: %s\n" +msgid "Screen %d on display “%s” is invalid\n" +msgstr "A pantalla %d na visualización «%s» non é válida\n" -#: ../src/ui/theme.c:4533 +#: src/x11/meta-x11-selection-input-stream.c:460 #, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" -"<button function=«%s» state=«%s» draw_ops=\"whatever\"/> débese especificar " -"para este estilo de marco" +msgid "Format %s not supported" +msgstr "O formato %s non se admite" -#: ../src/ui/theme.c:5066 ../src/ui/theme.c:5091 -#, c-format +#: src/x11/session.c:1821 msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "Falta <frame state=«%s» resize=«%s» focus=«%s» style=\"whatever\"/>" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." +msgstr "" +"Estas xanelas non soportan «save current setup» e terán que reiniciarse " +"manualmente a próxima vez que inicie a sesión." -#: ../src/ui/theme.c:5139 +#: src/x11/window-props.c:569 #, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Produciuse un fallo ao cargar o tema «%s»: %s\n" - -#: ../src/ui/theme.c:5275 ../src/ui/theme.c:5282 ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 ../src/ui/theme.c:5303 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "Non se configurou <%s> para o tema «%s»" - -#: ../src/ui/theme.c:5311 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" -"Non hai un estilo de marco para o tipo de xanela «%s» no tema «%s», engada " -"un elemento <window type=«%s» style_set=\"whatever\"/>" - -#: ../src/ui/theme.c:5709 ../src/ui/theme.c:5771 ../src/ui/theme.c:5834 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" -"As constantes definidas polo usuario deben comezar cunha letra maiúscula; " -"«%s» non o fai" - -#: ../src/ui/theme.c:5717 ../src/ui/theme.c:5779 ../src/ui/theme.c:5842 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "A constante «%s» xa foi definida" - -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. -#. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "Non está definido o atributo «%s» no elemento <%s>" - -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Liña %d carácter %d: %s" - -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "O atributo «%s» repetiuse dúas veces no mesmo elemento <%s>" - -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "O atributo «%s» non é válido no elemento <%s> neste contexto" - -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "Non foi posíbel analizar «%s» como un enteiro" - -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "Non se comprenden os caracteres sobrantes «%s» na cadea «%s»" - -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "O enteiro %ld debe ser positivo" - -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "O enteiro %ld é demasiado grande. O máximo actual é %d" - -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "Non foi posíbel analizar «%s» como un número de coma flotante" - -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "Os valores booleanos deben ser «true» ou «false», non «%s»" - -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "O ángulo debe estar entre 0.0 e 360.0, foi %g\n" - -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" -"Alfa debe estar entre 0.0 (invisíbel) e 1.0 (completamente opaco), foi %g\n" - -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"A escala de título non é válida «%s» (debe ser de xx-small,x-small,small," -"medium,large,x-large,xx-large)\n" - -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s> nome «%s» usado unha segunda vez" - -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "O <%s> pai «%s» non se definiu" - -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "A <%s> xeometría «%s» non se definiu" - -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "" -"<%s> debe especificar ou unha xeometría ou un pai que teña unha xeometría" - -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "Especifique un fondo para un valor alfa para que teña sentido" - -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Descoñécese o tipo «%s» no elemento <%s>" - -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "Descoñécese o style_set «%s» no elemento <%s>" - -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "O tipo de xanela «%s» xa se asignou a un conxunto de estilo" - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "Non se permite o elemento <%s> por baixo de <%s>" - -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" -msgstr "" -"Non é posíbel especificar \"button_width\"/\"button_height\" e \"aspect_ratio" -"\" ao mesmo tempo para os botóns" - -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "Descoñécese a distancia «%s»" - -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "Descoñécese a proporción de aspecto «%s»" - -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "Descoñécese o bordo «%s»" - -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "Non hai ningún atributo \"start_angle\" nin \"from\" no elemento <%s>" - -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "Non hai ningún atributo \"extent_angle\" nin \"to\" no elemento <%s>" - -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "Non se entendeu o valor «%s» para o tipo de degradado" - -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "Non se entendeu o tipo de recheo «%s» para o elemento <%s>" - -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "Non se entendeu o estado «%s» para o elemento <%s>" - -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "Non se entendeu a sombra «%s» para o elemento <%s>" - -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "Non se entendeu a frecha «%s» para o elemento <%s>" - -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "Non se definiu unha <draw_ops> chamada «%s»" - -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "Incluír o draw_ops «%s» aquí poderá crear unha referencia circular" - -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Descoñécese a posición «%s» para a peza do marco" - -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "O estilo do marco xa ten unha peza na posición %s" - -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "Non se definiu ningunha <draw_ops> co nome «%s»" - -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Descoñécese a función «%s» para o botón" - -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "A función «%s» do botón non existe nesta versión (%d, necesítase %d)" - -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Descoñécese o estado descoñecido «%s» para o botón" - -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "O estilo do marco xa ten un botón para a función %s estado %s" - -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "«%s» non é un valor válido para o atributo foco" - -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "«%s» non é un valor válido para o atributo estado" - -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "Non se definiu ningún estilo chamado «%s»" - -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "«%s» non é un valor válido para o atributo redimensionar" - -#: ../src/ui/theme-parser.c:3147 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" -"Non debería ter o atributo \"resize\" no elemento <%s> para os estados " -"maximizado/ensombrecido" - -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "" -"Non debería ter o atributo \"resize\" no elemento <%s> para os estados " -"maximizados" - -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "" -"O estilo xa foi especificado para o estado %s redimensionado %s foco %s" - -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "O estilo xa foi especificado para estado %s foco %s" - -#: ../src/ui/theme-parser.c:3294 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Non pode ter dous draw_ops para un elemento <piece> (o tema especificou un " -"atributo draw_ops e tamén un elemento <draw_ops> ou especificou os dous " -"elementos)" - -#: ../src/ui/theme-parser.c:3332 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Non pode ter dous draw_ops para un elemento <button> (o tema especificou un " -"atributo draw_ops e tamén un elemento <draw_ops> ou especificou os dous " -"elementos)" - -#: ../src/ui/theme-parser.c:3370 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Non pode ter dous draw_ops para un elemento <menu_icon> (o tema especificou " -"un atributo draw_ops e tamén un elemento <draw_ops> ou especificou os dous " -"elementos)" - -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "Especificación de versión «%s» errónea" - -#: ../src/ui/theme-parser.c:3507 -msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" -msgstr "" -"Non é posíbel usar o atributo «version» con metacity-theme-1.xml ou metacity-" -"theme-2.xml" - -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "" -"O tema require a versión %s pero a última versión admitida do tema é a %d.%d" - -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "O elemento máis externo no tema debe ser <metacity_theme> non <%s>" - -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "" -"Non se permite o elemento <%s> dentro dun elemento name/author/date/" -"description" - -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "Non se permite o elemento <%s> dentro dun elemento <constant>" - -#: ../src/ui/theme-parser.c:3599 -#, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "" -"Non se permite o elemento <%s> dentro dun elemento distance/border/" -"aspect_ratio" - -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "Non se permite o elemento <%s> dentro dun elemento de operación debuxo" - -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "Non se permite o elemento <%s> dentro dun elemento <%s>" - -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "Non se proporcionou draw_ops para a peza do marco" - -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "Non se proporcionou draw_ops para botón" - -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "Non se permite texto dentro do elemento <%s>" - -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "<%s> especificada dúas veces para este tema" - -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Non se atopou ningún ficheiro válido para o tema %s\n" - -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "_Xanelas" - -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "_Diálogo" - -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "_Diálogo modal" - -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "_Utilidade" - -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "_Pantalla de inicio" - -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "Doca _superior" - -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "Doca _inferior" - -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "Doca _esquerda" - -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "Doca _dereita" - -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "_Todas as docas" - -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "Es_critorio" - -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "Abrir outra destas xanelas" - -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "Este é un botón de demostración cunha icona 'abrir'" - -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "Este é un botón de demostración cunha icona 'saír'" - -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "Esta é unha mensaxe de mostra no diálogo de mostra" - -#: ../src/ui/theme-viewer.c:328 -#, c-format -msgid "Fake menu item %d\n" -msgstr "Elemento de menú falso %d\n" - -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "Xanela só con bordo" - -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "Barra" - -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "Xanela de aplicativo normal" - -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "Caixa de diálogo" - -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "Caixa de diálogo modal" - -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "Paleta de utilidades" - -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "Menú desprazado" - -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "Bordo" - -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "Diálogo modal adxunto" - -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "Proba de disposición de botóns %d" - -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g milisegundos para debuxar un marco de xanela" - -#: ../src/ui/theme-viewer.c:813 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Uso: metacity-theme-viewer [NOMETEMA]\n" - -#: ../src/ui/theme-viewer.c:820 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "Erro ao cargar o tema: %s\n" - -#: ../src/ui/theme-viewer.c:826 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "Cargouse o tema «%s» en %g segundos\n" - -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "Tipo de letra de título normal" - -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "Tipo de letra de título pequena" - -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "Tipo de letra de título grande" - -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "Disposición dos botóns" - -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "Banco de probas" - -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "O título da xanela vai aquí" - -#: ../src/ui/theme-viewer.c:1047 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"Debuxou %d marcos en %g segundos do lado do cliente (%g milisegundos por " -"marco) e %g segundos de tempo estándar incluíndo recursos do servidor X (%g " -"milisegundos por marco)\n" - -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "" -"a proba de expresión da posición devolveu TRUE mais estabeleceu un erro" - -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "" -"a proba de expresión da posición devolveu FALSE mais estabeleceu un erro" - -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "Esperábase un erro, mais non se deu ningún" - -#: ../src/ui/theme-viewer.c:1274 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "Esperábase un erro %d mais deuse %d" - -#: ../src/ui/theme-viewer.c:1280 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "Non se esperaba ningún erro mais devolveuse un: %s" - -#: ../src/ui/theme-viewer.c:1284 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "o valor x era %d, esperábase %d" - -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "o valor y era %d, esperábase %d" - -#: ../src/ui/theme-viewer.c:1352 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "" -"%d expresións de coordenadas interpretadas en %g segundos (%g segundos de " -"media)\n" - -#~ msgid "Switch to workspace 1" -#~ msgstr "Cambiar ao espazo de traballo 1" - -#~ msgid "Switch to workspace 2" -#~ msgstr "Cambiar ao espazo de traballo 2" - -#~ msgid "Switch to workspace 3" -#~ msgstr "Cambiar ao espazo de traballo 3" - -#~ msgid "Switch to workspace 4" -#~ msgstr "Cambiar ao espazo de traballo 4" - -#~ msgid "Switch to workspace 5" -#~ msgstr "Cambiar ao espazo de traballo 5" - -#~ msgid "Switch to workspace 6" -#~ msgstr "Cambiar ao espazo de traballo 6" - -#~ msgid "Switch to workspace 7" -#~ msgstr "Cambiar ao espazo de traballo 7" - -#~ msgid "Switch to workspace 8" -#~ msgstr "Cambiar ao espazo de traballo 8" - -#~ msgid "Switch to workspace 9" -#~ msgstr "Cambiar ao espazo de traballo 9" - -#~ msgid "Switch to workspace 10" -#~ msgstr "Cambiar ao espazo de traballo 10" - -#~ msgid "Switch to workspace 11" -#~ msgstr "Cambiar ao espazo de traballo 11" - -#~ msgid "Switch to workspace 12" -#~ msgstr "Cambiar ao espazo de traballo 12" - -#~ msgid "Switch to workspace on the left of the current workspace" -#~ msgstr "Cambiar ao espazo de traballo á esquerda do espazo actual" - -#~ msgid "Switch to workspace on the right of the current workspace" -#~ msgstr "Cambiar ao espazo de traballo á dereita do espazo actual" - -#~ msgid "Switch to workspace above the current workspace" -#~ msgstr "Cambiar ao espazo de traballo sobre o espazo actual" - -#~ msgid "Switch to workspace below the current workspace" -#~ msgstr "Cambiar ao espazo de traballo baixo o espazo actual" - -#~ msgid "Move between windows of an application, using a popup window" -#~ msgstr "Moverse entre xanelas dun aplicativo usando unha xanela emerxente" - -#~ msgid "" -#~ "Move backward between windows of an application, using a popup window" -#~ msgstr "" -#~ "Moverse cara a atrás entre xanelas dun aplicativo usando unha xanela " -#~ "emerxente" - -#~ msgid "Move between windows, using a popup window" -#~ msgstr "Moverse entre xanelas usando unha xanela emerxente" - -#~ msgid "Move backward between windows, using a popup window" -#~ msgstr "Moverse cara a atrás entre xanelas usando unha xanela emerxente" - -#~ msgid "Move between panels and the desktop, using a popup window" -#~ msgstr "Moverse entre os paneis e o escritorio usando unha xanela emerxente" - -#~ msgid "Move backward between panels and the desktop, using a popup window" -#~ msgstr "" -#~ "Moverse cara a atrás entre os paneis e o escritorio usando unha xanela " -#~ "emerxente" - -#~ msgid "Move between windows of an application immediately" -#~ msgstr "Moverse inmediatamente entre xanelas dun aplicativo" - -#~ msgid "Move backward between windows of an application immediately" -#~ msgstr "Moverse cara a atrás entre xanelas dun aplicativo inmediatamente" - -#~ msgid "Move between windows immediately" -#~ msgstr "Moverse inmediatamente entre xanelas" - -#~ msgid "Move backward between windows immediately" -#~ msgstr "Moverse cara a atrás entre xanelas inmediatamente" - -#~ msgid "Move between panels and the desktop immediately" -#~ msgstr "Moverse inmediatamente entre os paneis e o escritorio" - -#~ msgid "Move backward between panels and the desktop immediately" -#~ msgstr "Moverse inmediatamente cara a atrás entre os paneis e o escritorio" - -#~ msgid "Hide all normal windows and set focus to the desktop" -#~ msgstr "Agochar todas as xanelas normais e cambiar o foco ao escritorio" - -#~ msgid "Show the panel's main menu" -#~ msgstr "Mostrar o menú principal do panel" - -#~ msgid "Show the panel's \"Run Application\" dialog box" -#~ msgstr "Mostrar a caixa de diálogo \"Executar un aplicativo\" do panel" - -#~ msgid "Start or stop recording the session" -#~ msgstr "Iniciar ou deter a grabación da sesión" - -#~ msgid "Take a screenshot" -#~ msgstr "Coller unha captura de pantalla" - -#~ msgid "Take a screenshot of a window" -#~ msgstr "Coller unha captura de pantalla dunha xanela" - -#~ msgid "Run a terminal" -#~ msgstr "Executar nun terminal" - -#~ msgid "Activate the window menu" -#~ msgstr "Activar o menú da xanela" - -#~ msgid "Toggle fullscreen mode" -#~ msgstr "Alternar o modo de pantalla completa" - -#~ msgid "Toggle maximization state" -#~ msgstr "Alternar o estado maximizado" - -#~ msgid "Toggle whether a window will always be visible over other windows" -#~ msgstr "" -#~ "Alternar entre se unha xanela será visíbel sempre sobre outras xanelas ou " -#~ "non" - -#~ msgid "Maximize window" -#~ msgstr "Maximizar a xanela" - -#~ msgid "Restore window" -#~ msgstr "Restaurar a xanela" - -#~ msgid "Toggle shaded state" -#~ msgstr "Alternar o estado ensombrecido" - -#~ msgid "Minimize window" -#~ msgstr "Minimizar a xanela" - -#~ msgid "Close window" -#~ msgstr "Pechar a xanela" - -#~ msgid "Move window" -#~ msgstr "Mover a xanela" - -#~ msgid "Resize window" -#~ msgstr "Redimensionar a xanela" - -#~ msgid "Toggle whether window is on all workspaces or just one" -#~ msgstr "" -#~ "Alternar entre se unha xanela está en todos os espazos de traballo ou só " -#~ "nun" - -#~ msgid "Move window to workspace 1" -#~ msgstr "Mover a xanela ao espazo de traballo 1" - -#~ msgid "Move window to workspace 2" -#~ msgstr "Mover a xanela ao espazo de traballo 2" - -#~ msgid "Move window to workspace 3" -#~ msgstr "Mover a xanela ao espazo de traballo 3" - -#~ msgid "Move window to workspace 4" -#~ msgstr "Mover a xanela ao espazo de traballo 4" - -#~ msgid "Move window to workspace 5" -#~ msgstr "Mover a xanela ao espazo de traballo 5" - -#~ msgid "Move window to workspace 6" -#~ msgstr "Mover a xanela ao espazo de traballo 6" - -#~ msgid "Move window to workspace 7" -#~ msgstr "Mover a xanela ao espazo de traballo 7" - -#~ msgid "Move window to workspace 8" -#~ msgstr "Mover a xanela ao espazo de traballo 8" - -#~ msgid "Move window to workspace 9" -#~ msgstr "Mover a xanela ao espazo de traballo 9" - -#~ msgid "Move window to workspace 10" -#~ msgstr "Mover a xanela ao espazo de traballo 10" - -#~ msgid "Move window to workspace 11" -#~ msgstr "Mover a xanela ao espazo de traballo 11" - -#~ msgid "Move window to workspace 12" -#~ msgstr "Mover a xanela ao espazo de traballo 12" - -#~ msgid "Move window one workspace to the left" -#~ msgstr "Mover a xanela un espazo de traballo cara á esquerda" - -#~ msgid "Move window one workspace to the right" -#~ msgstr "Mover a xanela un espazo de traballo cara á dereita" - -#~ msgid "Move window one workspace up" -#~ msgstr "Mover a xanela un espazo de traballo cara a arriba" - -#~ msgid "Move window one workspace down" -#~ msgstr "Mover a xanela un espazo de traballo cara a abaixo" - -#~ msgid "Raise window if it's covered by another window, otherwise lower it" -#~ msgstr "" -#~ "Elevar unha xanela se está cuberta por outra, en caso contrario baixala" - -#~ msgid "Raise window above other windows" -#~ msgstr "Subir a xanela por enriba doutras xanelas" - -#~ msgid "Lower window below other windows" -#~ msgstr "Baixar unha xanela debaixo doutras xanelas" - -#~ msgid "Maximize window vertically" -#~ msgstr "Maximizar a xanela verticalmente" - -#~ msgid "Maximize window horizontally" -#~ msgstr "Maximizar a xanela horizontalmente" - -#~ msgid "Move window to north-west (top left) corner" -#~ msgstr "Mover a xanela á esquina noroeste (arriba á esquerda)" - -#~ msgid "Move window to north-east (top right) corner" -#~ msgstr "Mover a xanela á esquina nordeste (arriba á dereita)" - -#~ msgid "Move window to south-west (bottom left) corner" -#~ msgstr "Mover a xanela á esquina sudoeste (abaixo á esquerda)" - -#~ msgid "Move window to south-east (bottom right) corner" -#~ msgstr "Mover a xanela á esquina sueste (abaixo á dereita)" - -#~ msgid "Move window to north (top) side of screen" -#~ msgstr "Mover a xanela ao lado norte (arriba) da pantalla" - -#~ msgid "Move window to south (bottom) side of screen" -#~ msgstr "Mover a xanela ao lado sur (abaixo) da pantalla" - -#~ msgid "Move window to east (right) side of screen" -#~ msgstr "Mover a xanela ao lado leste (dereita) da pantalla" - -#~ msgid "Move window to west (left) side of screen" -#~ msgstr "Mover a xanela ao lado oeste (esquerda) da pantalla" - -#~ msgid "Move window to center of screen" -#~ msgstr "Mover a xanela ao centro da pantalla" - -#~ msgid "" -#~ "There was an error running <tt>%s</tt>:\n" -#~ "\n" -#~ "%s" -#~ msgstr "" -#~ "Produciuse un erro ao executar <tt>%s</tt>:\n" -#~ "\n" -#~ "%s" - -#~ msgid "No command %d has been defined.\n" -#~ msgstr "Non se definiu ningunha orde %d.\n" - -#~ msgid "No terminal command has been defined.\n" -#~ msgstr "Non se definiu ningunha orde de terminal.\n" - -#~ msgid "GConf key '%s' is set to an invalid value\n" -#~ msgstr "A chave GConf «%s» está configurada cun valor non válido\n" - -#~ msgid "%d stored in GConf key %s is out of range %d to %d\n" -#~ msgstr "%d almacenado na chave GConf %s está fóra do intervalo %d a %d\n" - -#~ msgid "GConf key \"%s\" is set to an invalid type\n" -#~ msgstr "A chave GConf «%s» está configurada cun tipo non válido\n" - -#~ msgid "GConf key %s is already in use and can't be used to override %s\n" -#~ msgstr "" -#~ "A chave de GConf %s xa está en uso e non é posíbel usala para " -#~ "sobrescribir %s\n" - -#~ msgid "Can't override GConf key, %s not found\n" -#~ msgstr "Non é posíbel sobrescribir a chave de GConf, non se atopou %s\n" - -#~ msgid "Error setting number of workspaces to %d: %s\n" -#~ msgstr "Erro ao definir o número de espazos de traballo en %d: %s\n" - -#~ msgid "Error setting name for workspace %d to \"%s\": %s\n" -#~ msgstr "Erro ao definir o nome do espazo de traballo %d como «%s»: %s\n" - -#~ msgid "Error setting live hidden windows status status: %s\n" -#~ msgstr "" -#~ "Produciuse un erro ao estabelecer o estado da vida das xanelas ocultas " -#~ "%s\n" - -#~ msgid "Error setting no tab popup status: %s\n" -#~ msgstr "" -#~ "Produciuse un erro ao estabelecer o estado das lapelas en xanelas " -#~ "emerxentes %s\n" - -#~ msgid "Failed to retrieve color %s[%s] from GTK+ theme.\n" -#~ msgstr "Produciuse un fallo ao obter a cor %s[%s] desde o tema de GTK+.\n" - -#~ msgid "" -#~ "Don't make fullscreen windows that are maximized and have no decorations" -#~ msgstr "" -#~ "Non poñer a pantalla completa as xanelas maximizadas e que non teñen " -#~ "decoración" - -#~ msgid "Whether window popup/frame should be shown when cycling windows." -#~ msgstr "Se se debe mostrar a xanela emerxente/marco ao rotar nas xanelas." - -#~ msgid "Internal argument for GObject introspection" -#~ msgstr "Argumento interno para a introspección de GObject" - -#~ msgid "Failed to restart: %s\n" -#~ msgstr "Produciuse un fallo ao reiniciar: %s\n" - -#~ msgid "Error setting clutter plugin list: %s\n" -#~ msgstr "Erro ao definir a lista de complementos de clutter: %s\n" - -#~ msgid "Clutter Plugins" -#~ msgstr "Complementos de Clutter" - -#~ msgid "Plugins to load for the Clutter-based compositing manager." -#~ msgstr "" -#~ "Complementos a cargar polo xestor de composición baseado en Clutter." - -#~ msgid "Turn compositing on" -#~ msgstr "Activar a composición" - -#~ msgid "Turn compositing off" -#~ msgstr "Desactivar a composición" - -#~ msgid "Error setting compositor status: %s\n" -#~ msgstr "Erro ao definir o estado do compositor: %s\n" - -#~ msgid "" -#~ "Lost connection to the display '%s';\n" -#~ "most likely the X server was shut down or you killed/destroyed\n" -#~ "the window manager.\n" -#~ msgstr "" -#~ "Perdeuse a conexión coa pantalla '%s';\n" -#~ "probabelmente saíu do servidor X ou \n" -#~ "matou/destruíu o xestor de xanelas.\n" - -#~ msgid "Fatal IO error %d (%s) on display '%s'.\n" -#~ msgstr "Erro moi grave de E/S %d (%s) na pantalla '%s'.\n" +msgid "%s (on %s)" +msgstr "%s (en %s)" diff --git a/po/gu.po b/po/gu.po index 0d36bd370..b4c66ce4c 100644 --- a/po/gu.po +++ b/po/gu.po @@ -1,16 +1,17 @@ # translation of gu.po to Gujarati # Ankit Patel <ankit644@yahoo.com>, 2005, 2006. # Ankit Patel <ankit@redhat.com>, 2007, 2009. -# Sweta Kothari <swkothar@redhat.com>, 2011, 2012. +# Sweta Kothari <swkothar@redhat.com>, 2011, 2012, 2013, 2014. msgid "" msgstr "" "Project-Id-Version: gu\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug." -"cgi?product=muffin&keywords=I18N+L10N&component=general\n" -"POT-Creation-Date: 2012-03-15 21:29+0000\n" -"PO-Revision-Date: 2012-03-26 14:08+0530\n" +"cgi?product=mutter&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2014-09-11 21:49+0000\n" +"PO-Revision-Date: 2014-09-12 11:50+0530\n" "Last-Translator: \n" -"Language-Team: gu_IN <kde-i18n-doc@kde.org>\n" +"Language-Team: American English <kde-i18n-doc@kde.org>\n" +"Language: gu\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -29,50 +30,473 @@ msgstr "" "\n" "\n" -#: ../src/50-muffin-windows.xml.in.h:1 -#| msgid "_Windows" +#: ../data/50-mutter-navigation.xml.in.h:1 +msgid "Navigation" +msgstr "શોધખોળ" + +#: ../data/50-mutter-navigation.xml.in.h:2 +msgid "Move window to workspace 1" +msgstr "વિન્ડોને કામ કરવાની જગ્યા ૧ માં લઈ જાઓ" + +#: ../data/50-mutter-navigation.xml.in.h:3 +msgid "Move window to workspace 2" +msgstr "વિન્ડોને કામ કરવાની જગ્યા ૨ માં લઈ જાઓ" + +#: ../data/50-mutter-navigation.xml.in.h:4 +msgid "Move window to workspace 3" +msgstr "વિન્ડોને કામ કરવાની જગ્યા ૩ માં લઈ જાઓ" + +#: ../data/50-mutter-navigation.xml.in.h:5 +msgid "Move window to workspace 4" +msgstr "વિન્ડોને કામ કરવાની જગ્યા ૪ માં લઈ જાઓ" + +#: ../data/50-mutter-navigation.xml.in.h:6 +#| msgid "Move window to workspace 1" +msgid "Move window to last workspace" +msgstr "છેલ્લે કામ કરવાની જગ્યામાં વિન્ડોને ખસેડો" + +#: ../data/50-mutter-navigation.xml.in.h:7 +msgid "Move window one workspace to the left" +msgstr "વિન્ડોને ડાબી બાજુની કામ કરવાની જગ્યામાં લાવો" + +#: ../data/50-mutter-navigation.xml.in.h:8 +msgid "Move window one workspace to the right" +msgstr "વિન્ડોને જમણી બાજુની કામ કરવાની જગ્યામાં લાવો" + +#: ../data/50-mutter-navigation.xml.in.h:9 +msgid "Move window one workspace up" +msgstr "વિન્ડોને ઉપરની બાજુની કામ કરવાની જગ્યામાં લાવો" + +#: ../data/50-mutter-navigation.xml.in.h:10 +msgid "Move window one workspace down" +msgstr "વિન્ડોને નીચેની કામ કરવાની જગ્ચામાં લાવો" + +#: ../data/50-mutter-navigation.xml.in.h:11 +#| msgid "Move window one workspace to the left" +msgid "Move window one monitor to the left" +msgstr "વિન્ડોને એક મોનિટરની ડાબે ખસેડો" + +#: ../data/50-mutter-navigation.xml.in.h:12 +#| msgid "Move window one workspace to the right" +msgid "Move window one monitor to the right" +msgstr "વિન્ડોને એક મોનિટરની જમણે ખસેડો" + +#: ../data/50-mutter-navigation.xml.in.h:13 +#| msgid "Move window one workspace up" +msgid "Move window one monitor up" +msgstr "વિન્ડોને એક મોનિટરની ઉપર ખસેડો" + +#: ../data/50-mutter-navigation.xml.in.h:14 +#| msgid "Move window one workspace down" +msgid "Move window one monitor down" +msgstr "વિન્ડોને એક મોનિટરની નીચે ખસેડો" + +#: ../data/50-mutter-navigation.xml.in.h:15 +msgid "Switch applications" +msgstr "કાર્યક્રમો બદલો" + +#: ../data/50-mutter-navigation.xml.in.h:16 +#| msgid "Switch applications" +msgid "Switch to previous application" +msgstr "પહેલાંના કાર્યક્રમમાં જાઓ" + +#: ../data/50-mutter-navigation.xml.in.h:17 +msgid "Switch windows" +msgstr "વિન્ડો બદલો" + +#: ../data/50-mutter-navigation.xml.in.h:18 +#| msgid "Switch windows" +msgid "Switch to previous window" +msgstr "પહેલાંની વિન્ડોમાં જાઓ" + +#: ../data/50-mutter-navigation.xml.in.h:19 +msgid "Switch windows of an application" +msgstr "કાર્યક્રમની વિન્ડો બદલો" + +#: ../data/50-mutter-navigation.xml.in.h:20 +#| msgid "Switch windows of an application" +msgid "Switch to previous window of an application" +msgstr "કાર્યક્રમની પહેલાંની વિન્ડોમાં જાઓ" + +#: ../data/50-mutter-navigation.xml.in.h:21 +msgid "Switch system controls" +msgstr "સિસ્ટમ નિયંત્રણો બદલો" + +#: ../data/50-mutter-navigation.xml.in.h:22 +#| msgid "Switch system controls" +msgid "Switch to previous system control" +msgstr "પહેલાંની સિસ્ટમ નિયંત્રણમાં જાઓ" + +#: ../data/50-mutter-navigation.xml.in.h:23 +msgid "Switch windows directly" +msgstr "સીધી વિન્ડોને બદલો" + +#: ../data/50-mutter-navigation.xml.in.h:24 +msgid "Switch directly to previous window" +msgstr "પહેલાંની વિન્ડોમાં સીધુ બદલો" + +#: ../data/50-mutter-navigation.xml.in.h:25 +msgid "Switch windows of an app directly" +msgstr "સીધી કાર્યક્રમની વિન્ડોને બદલો" + +#: ../data/50-mutter-navigation.xml.in.h:26 +#| msgid "Switch windows of an application" +msgid "Switch directly to previous window of an app" +msgstr "કાર્યક્રમની પહેલાંની વિન્ડોમાં સીધુજ જાઓ" + +#: ../data/50-mutter-navigation.xml.in.h:27 +msgid "Switch system controls directly" +msgstr "સીધા સિસ્ટમ નિયંત્રણોને બદલો" + +#: ../data/50-mutter-navigation.xml.in.h:28 +#| msgid "Switch system controls" +msgid "Switch directly to previous system control" +msgstr "પહેલાંની સિસ્ટમ નિયંત્રણમાં સીધુ જ જાઓ" + +#: ../data/50-mutter-navigation.xml.in.h:29 +msgid "Hide all normal windows" +msgstr "બધી સામાન્ય વિન્ડોને છુપાડો" + +#: ../data/50-mutter-navigation.xml.in.h:30 +msgid "Switch to workspace 1" +msgstr "કામ કરવાની જગ્યા ૧ માં જાઓ" + +#: ../data/50-mutter-navigation.xml.in.h:31 +msgid "Switch to workspace 2" +msgstr "કામ કરવાની જગ્યા ૨ માં જાઓ" + +#: ../data/50-mutter-navigation.xml.in.h:32 +msgid "Switch to workspace 3" +msgstr "કામ કરવાની જગ્યા ૩ માં જાઓ" + +#: ../data/50-mutter-navigation.xml.in.h:33 +msgid "Switch to workspace 4" +msgstr "કામ કરવાની જગ્યા ૪ માં જાઓ" + +#: ../data/50-mutter-navigation.xml.in.h:34 +#| msgid "Switch to workspace 1" +msgid "Switch to last workspace" +msgstr "છેલ્લી કામ કરવાની જગ્યામાં જાઓ" + +#: ../data/50-mutter-navigation.xml.in.h:35 +msgid "Move to workspace left" +msgstr "ડાબી કામ કરવાની જગ્યામાં ખસો" + +#: ../data/50-mutter-navigation.xml.in.h:36 +msgid "Move to workspace right" +msgstr "જમણી કામ કરવાની જગ્યામાં ખસો" + +#: ../data/50-mutter-navigation.xml.in.h:37 +msgid "Move to workspace above" +msgstr "ઉપરની કામ કરવાની જગ્યામાં ખસો (_L)" + +#: ../data/50-mutter-navigation.xml.in.h:38 +msgid "Move to workspace below" +msgstr "નીચેની કામ કરવાની જગ્યામાં ખસો (_D)" + +#: ../data/50-mutter-system.xml.in.h:1 +msgid "System" +msgstr "સિસ્ટમ" + +#: ../data/50-mutter-system.xml.in.h:2 +msgid "Show the run command prompt" +msgstr "ચાલતા આદેશ પ્રોમ્પ્ટને બતાવો" + +#: ../data/50-mutter-system.xml.in.h:3 +msgid "Show the activities overview" +msgstr "પ્રવૃત્તિઓની ઝાંખીને બતાવો" + +#: ../data/50-mutter-windows.xml.in.h:1 msgid "Windows" msgstr "વિન્ડો" -#: ../src/50-muffin-windows.xml.in.h:2 +#: ../data/50-mutter-windows.xml.in.h:2 +msgid "Activate the window menu" +msgstr "વિન્ડો મેનુ સક્રિય કરો" + +#: ../data/50-mutter-windows.xml.in.h:3 +msgid "Toggle fullscreen mode" +msgstr "આખી સ્ક્રીન કરવાની સ્થિતિમાં ફેરબદલી" + +#: ../data/50-mutter-windows.xml.in.h:4 +msgid "Toggle maximization state" +msgstr "મહત્તમ કરવાની સ્થિતિમાં ફેરબદલી" + +#: ../data/50-mutter-windows.xml.in.h:5 +msgid "Maximize window" +msgstr "વિન્ડોને મહત્તમ સ્થિતિમાં લાવો" + +#: ../data/50-mutter-windows.xml.in.h:6 +msgid "Restore window" +msgstr "વિન્ડો પુનઃસંગ્રહિત કરો" + +#: ../data/50-mutter-windows.xml.in.h:7 +msgid "Toggle shaded state" +msgstr "છાયાંકિત કરવાની સ્થિતિમાં ફેરબદલી" + +#: ../data/50-mutter-windows.xml.in.h:8 +msgid "Close window" +msgstr "વિન્ડો બંધ કરો" + +#: ../data/50-mutter-windows.xml.in.h:9 +msgid "Hide window" +msgstr "વિન્ડો છુપાડો" + +#: ../data/50-mutter-windows.xml.in.h:10 +msgid "Move window" +msgstr "વિન્ડોને ખસાડો" + +#: ../data/50-mutter-windows.xml.in.h:11 +msgid "Resize window" +msgstr "વિન્ડોનુ માપ બદલો" + +#: ../data/50-mutter-windows.xml.in.h:12 +msgid "Toggle window on all workspaces or one" +msgstr "બધી કામ કરવાની જગ્યાઓ ઉપર છે કે ખાલી એક પર ટૉગલ વિન્ડો" + +#: ../data/50-mutter-windows.xml.in.h:13 +msgid "Raise window if covered, otherwise lower it" +msgstr "જો વિન્ડો આવરાયેલ હોય, અથવા તેની નીચે હોય તો તેને વધારો" + +#: ../data/50-mutter-windows.xml.in.h:14 +msgid "Raise window above other windows" +msgstr "વિન્ડોને બીજી બધી વિન્ડોની ઉપર લાવો" + +#: ../data/50-mutter-windows.xml.in.h:15 +msgid "Lower window below other windows" +msgstr "બીજી વિન્ડો નીચેની વિન્ડોને નાની કરો" + +#: ../data/50-mutter-windows.xml.in.h:16 +msgid "Maximize window vertically" +msgstr "વિન્ડોને ઉભી દિશામાં મોટી કરો" + +#: ../data/50-mutter-windows.xml.in.h:17 +msgid "Maximize window horizontally" +msgstr "વિન્ડોને આડી દિશામાં મોટી કરો" + +#: ../data/50-mutter-windows.xml.in.h:18 msgid "View split on left" -msgstr "" +msgstr "ડાબી બાજુએ અલગ કરેલ દૃશ્ય" -#: ../src/50-muffin-windows.xml.in.h:3 +#: ../data/50-mutter-windows.xml.in.h:19 msgid "View split on right" +msgstr "જમણી બાજુએ અલગ કરેલ દૃશ્ય" + +#: ../data/mutter.desktop.in.h:1 +msgid "Mutter" +msgstr "Mutter" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:1 +msgid "Modifier to use for extended window management operations" +msgstr "વિસ્તરેલ વિન્ડો સંચાલન ક્રિયાઓ માટે વપરાતુ સંશોધક" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:2 +msgid "" +"This key will initiate the \"overlay\", which is a combination window " +"overview and application launching system. The default is intended to be the " +"\"Windows key\" on PC hardware. It's expected that this binding either the " +"default or set to the empty string." +msgstr "" +"આ કી \"overlay\" ને શરૂ કરશે, કે જે વિન્ડો ઝાંખી અને કાર્યક્રમ શરૂઆત સિસ્ટમનું સંયોજન છે. " +"મૂળભૂત PC હાર્ડવેર પર \"Windows key\" ને લગતુ છે. તેને ઇચ્છા રાખેલ થે કે આ ક્યાંતો મૂળભૂત છે " +"અથવા ખાલી શબ્દમાળામાં સુયોજિત છે." + +#: ../data/org.gnome.mutter.gschema.xml.in.h:3 +msgid "Attach modal dialogs" +msgstr "નમુના સંવાદોને જોડો" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:4 +msgid "" +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." msgstr "" +"જ્યારે true હોય, સ્વતંત્ર શીર્ષકપટ્ટીને લીધા કરતા, મોડલ સંવાદ મુખ્ય વિન્ડોની શીર્ષકપટ્ટી " +"સાથે જોડાયેલ છે તેવુ દેખાય છે અને મુખ્ય વિન્ડો સાથે એકસાથે ખસેડેલ છે." + +#: ../data/org.gnome.mutter.gschema.xml.in.h:5 +msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "જ્યારે સ્ક્રીન બાજુ પર વિન્ડોને પડતી મૂકી રહ્યા હોય ત્યારે ટાઇલીંગ સક્રિય કરો" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:6 +msgid "" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." +msgstr "" +"જો સક્રિય હોય તો, ઊભી સ્ક્રીન બાજુ પર પડતી વિન્ડો તેઓને ઊભી રીતે મહત્તમ કરે છે અને ઉપલબ્ધ " +"વિસ્તારમાં આડી રીતે આવરવા માટે આડી રીતે તેઓનું માપ બદલે છે. ટોચ સ્ક્રીન પર પડતી બાજુ પર " +"પડતી વિન્ડોને તેઓને સંપૂર્ણપણે મહત્તમ કરે છે." + +#: ../data/org.gnome.mutter.gschema.xml.in.h:7 +msgid "Workspaces are managed dynamically" +msgstr "કામ કરવાની જગ્યા ગતિશીલ રીતે સંચાલિત થયેલ છે" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:8 +msgid "" +"Determines whether workspaces are managed dynamically or whether there's a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." +msgstr "" +"શું કામકરવાની જગ્યા ગતિશીલ રીતે સંચાલિત થયેલ છે તે નક્કી કરે છે અથવા શું ત્યા કામ કરવાની " +"જગ્યાની સ્થિર સંખ્યા છે (org.gnome.desktop.wm.preferences માં કામ કરવાની જગ્યા " +"દ્દારા નક્કી થયેલ છે)." + +#: ../data/org.gnome.mutter.gschema.xml.in.h:9 +msgid "Workspaces only on primary" +msgstr "ફક્ત પ્રાથમિક પર કામ કરવાની જગ્યા" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:10 +msgid "" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." +msgstr "" +"શું કામ કરવાની જગ્યાને બધા મોનિટર પર વિન્ડો માટે અદલાબદલી થવી જોઇએ અથવા પ્રાથમિક " +"મોનિટર પર ફક્ત વિન્ડો માટે." + +#: ../data/org.gnome.mutter.gschema.xml.in.h:11 +msgid "No tab popup" +msgstr "ટૅબ પોપઅપ નથી" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:12 +msgid "" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." +msgstr "" +"શું પોપઅપ અને પ્રકાશિત ફ્રેમનો વપરાશ વિન્ડો સાયકલીંગ માટે નિષ્ક્રિય થવુ જોઇએ તે નક્કી કરે છે." + +#: ../data/org.gnome.mutter.gschema.xml.in.h:13 +msgid "Delay focus changes until the pointer stops moving" +msgstr "ફૉકસ ફેરફારો કરવામાં વિલંબ જ્યારે પોઇંટર ખસેડવાનું બંધ કરે તો" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:14 +msgid "" +"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " +"the focus will not be changed immediately when entering a window, but only " +"after the pointer stops moving." +msgstr "" +"જો true તરીકે સુયોજિત કરો તો, અને ફૉકસ સ્થિતિ ક્યાંતો \"sloppy\" અથવા \"mouse\" છે " +"પછી ફૉકસ તરત જ બદલાશે નહિં જ્યારે વિન્ડોને દાખલ કરી રહ્યા હોય, પરંતુ પોઇંટરને ખસેડવાનું બંધ " +"કરો પછી." + +#: ../data/org.gnome.mutter.gschema.xml.in.h:15 +msgid "Draggable border width" +msgstr "ખેંચી શકાય તેવી સીમા પહોળાઇ" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:16 +msgid "" +"The amount of total draggable borders. If the theme's visible borders are " +"not enough, invisible borders will be added to meet this value." +msgstr "" +"કુલ ખેંચી શકાય તેવી સીમાઓની સંખ્યા. જો થીમની દૃશ્યમાન સીમાઓ પૂરતી નથી, અદૃશ્ય સીમાઓ આ " +"કિંમતને મેળવવા માટે ઉમેરાશે." + +#: ../data/org.gnome.mutter.gschema.xml.in.h:17 +msgid "Auto maximize nearly monitor sized windows" +msgstr "મોનિટર માપની વિન્ડોને આપમેળે મહત્તમ કરો" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:18 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "જો સક્રિય હોય તો, નવી વિન્ડો કે જે મોનિટરનું પ્રારંભિક માપ આપમેળે મહત્તમ થયેલ છે." + +#: ../data/org.gnome.mutter.gschema.xml.in.h:19 +msgid "Place new windows in the center" +msgstr "કેન્દ્રમાં નવી વિન્ડોને સ્થિત કરો" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:20 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "જ્યારે true હોય ત્યારે, નવી વિન્ડો મોનિટરની સક્રિય સ્ક્રીનની કેન્દ્દમાં હંમેશા મૂકશે." + +#: ../data/org.gnome.mutter.gschema.xml.in.h:21 +msgid "Select window from tab popup" +msgstr "ટૅબ પોપઅપમાંથી વિન્ડોને પસંદ કરો" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:22 +msgid "Cancel tab popup" +msgstr "ટૅબ પોપઅપને રદ કરો" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:1 +#| msgid "Switch to workspace 1" +msgid "Switch to VT 1" +msgstr "VT 1 માં જાઓ" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:2 +#| msgid "Switch to workspace 2" +msgid "Switch to VT 2" +msgstr "VT 2 માં જાઓ" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:3 +#| msgid "Switch to workspace 3" +msgid "Switch to VT 3" +msgstr "VT 3 માં જાઓ" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:4 +#| msgid "Switch to workspace 4" +msgid "Switch to VT 4" +msgstr "VT 4 માં જાઓ" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:5 +#| msgid "Switch to workspace 5" +msgid "Switch to VT 5" +msgstr "VT 5 માં જાઓ" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:6 +#| msgid "Switch to workspace 6" +msgid "Switch to VT 6" +msgstr "VT 6 માં જાઓ" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:7 +#| msgid "Switch to workspace 7" +msgid "Switch to VT 7" +msgstr "VT 7 માં જાઓ" + +#: ../src/backends/meta-monitor-manager.c:412 +msgid "Built-in display" +msgstr "બિલ્ટ-ઇન દર્શાવ" + +#: ../src/backends/meta-monitor-manager.c:437 +msgid "Unknown" +msgstr "અજ્ઞાત" + +#: ../src/backends/meta-monitor-manager.c:439 +msgid "Unknown Display" +msgstr "અજ્ઞાત દર્શાવ" + +#. TRANSLATORS: this is a monitor vendor name, followed by a +#. * size in inches, like 'Dell 15"' +#. +#: ../src/backends/meta-monitor-manager.c:447 +#, c-format +msgid "%s %s" +msgstr "%s %s" #. This probably means that a non-WM compositor like xcompmgr is running; #. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, fuzzy, c-format -#| msgid "" -#| "Could not acquire window manager selection on screen %d display \"%s\"\n" +#: ../src/compositor/compositor.c:443 +#, c-format msgid "" "Another compositing manager is already running on screen %i on display \"%s" "\"." -msgstr "સ્ક્રીન %d કે જે ડિસ્પ્લે \"%s\" પર છે તે વિન્ડો વ્યવસ્થાપકની પસંદગીને મેળવી શકાતી નથી\n" +msgstr "સ્ક્રીન %i કે જે દર્શાવ \"%s\" પર છે તે બીજુ બનતુ સંચાલક પહેલેથી ચાલી રહ્યુ છે." -#: ../src/core/bell.c:307 +#: ../src/core/bell.c:185 msgid "Bell event" -msgstr "" - -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "અજ્ઞાત વિન્ડો જાણકારી અરજી: %d" +msgstr "બેલ ઘટના" -#: ../src/core/delete.c:111 +#: ../src/core/delete.c:127 #, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> જવાબ આપતું નથી." +msgid "“%s” is not responding." +msgstr "“%s” જવાબ આપી રહ્યુ નથી." -#: ../src/core/delete.c:114 -#| msgid "<tt>%s</tt> is not responding." +#: ../src/core/delete.c:129 msgid "Application is not responding." msgstr "કાર્યક્રમ જવાબ આપતું નથી." -#: ../src/core/delete.c:119 +#: ../src/core/delete.c:134 msgid "" "You may choose to wait a short while for it to continue or force the " "application to quit entirely." @@ -80,128 +504,95 @@ msgstr "" "તેને ચાલુ રાખવા માટે અથવા કાર્યક્રમને સંપૂર્ણપણે બંધ થઈ જવા માટે તમે થોડો સમય રાહ જોવાનું " "પસંદ કરી શકશો." -#: ../src/core/delete.c:126 +#: ../src/core/delete.c:141 msgid "_Wait" msgstr "રાહ જુઓ (_W)" -#: ../src/core/delete.c:126 +#: ../src/core/delete.c:141 msgid "_Force Quit" msgstr "જબરદસ્તી બહાર કાઢો (_F)" -#: ../src/core/display.c:387 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "કમ્પોઝીટીંગ માટે ગુમ થયેલ %s એક્સટેન્સન જરૂરી" - -#: ../src/core/display.c:453 +#: ../src/core/display.c:547 #, c-format msgid "Failed to open X Window System display '%s'\n" msgstr "X વિન્ડો સિસ્ટમ ડિસ્પ્લે '%s' ને ખોલવામાં નિષ્ફળ\n" -#: ../src/core/keybindings.c:852 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "કોઈ બીજો કાર્યક્રમ પહેલેથીજ કી %s ને બદલનાર %x સાથે જોડાણ તરીકે વાપરી રહ્યુ છે\n" - -#: ../src/core/main.c:206 +#: ../src/core/main.c:176 msgid "Disable connection to session manager" msgstr "સત્ર વ્યવસ્થાપકનું જોડાણ નિષ્ક્રિય કરો" -#: ../src/core/main.c:212 -#| msgid "Replace the running window manager with Muffin" +#: ../src/core/main.c:182 msgid "Replace the running window manager" msgstr "ચાલતા વિન્ડો સંચાલકને બદલો" -#: ../src/core/main.c:218 +#: ../src/core/main.c:188 msgid "Specify session management ID" msgstr "સત્ર વ્યવસ્થાપન ID સ્પષ્ટ કરો" -#: ../src/core/main.c:223 +#: ../src/core/main.c:193 msgid "X Display to use" msgstr "વાપરવા માટેનું X ડિસ્પ્લે" -#: ../src/core/main.c:229 +#: ../src/core/main.c:199 msgid "Initialize session from savefile" msgstr "સંગ્રહાયેલ ફાઈલમાંથી સત્રનો પ્રારંભ કરો" -#: ../src/core/main.c:235 +#: ../src/core/main.c:205 msgid "Make X calls synchronous" msgstr "X કોલ સુમેળ રીતે કરો" -#: ../src/core/main.c:504 +#: ../src/core/main.c:212 +msgid "Run as a wayland compositor" +msgstr "wayland કંપોઝીટર તરીકે ચલાવો" + +#: ../src/core/main.c:220 +msgid "Run as a full display server, rather than nested" +msgstr "સંપૂર્ણ દર્શાવ સર્વર તરીકે ચલાવો, નેસ્ટ બદલે" + +#: ../src/core/main.c:451 #, c-format msgid "Failed to scan themes directory: %s\n" msgstr "થીમની ડિરેક્ટરી જોવામાં નિષ્ફળ: %s\n" -#: ../src/core/main.c:520 +#: ../src/core/main.c:467 #, c-format msgid "Could not find a theme! Be sure %s exists and contains the usual themes.\n" msgstr "થીમ શોધી શકાઈ નહિં! ખાતરી કરો કે %s અસ્તિત્વ ધરાવે છે અને તેમાં સામાન્ય થીમ છે.\n" -#: ../src/core/muffin.c:40 +#: ../src/core/mutter.c:39 #, c-format msgid "" -"muffin %s\n" +"mutter %s\n" "Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" "This is free software; see the source for copying conditions.\n" "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " "PARTICULAR PURPOSE.\n" msgstr "" -"muffin %s\n" +"mutter %s\n" "Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" "This is free software; see the source for copying conditions.\n" "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " "PARTICULAR PURPOSE.\n" -#: ../src/core/muffin.c:54 +#: ../src/core/mutter.c:53 msgid "Print version" msgstr "છાપન આવૃત્તિ" -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "" - -#: ../src/core/prefs.c:1077 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"બગડેલા કાર્યક્રમો માટે આસપાસના કાર્યો નિષ્ક્રિય કરેલા છે. કદાચ કેટલાક કાર્યક્રમો યોગ્ય " -"રીતે નહિ વર્તતા હોય.\n" - -#: ../src/core/prefs.c:1152 -#, fuzzy, c-format -#| msgid "Could not parse font description \"%s\" from GConf key %s\n" -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "\"%s\" ફોન્ટના વર્ણનને જીકોન્ફ કી %s માંથી પદચ્છેદ કરી શકાતા નથી\n" - -#: ../src/core/prefs.c:1218 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "માઉસ બટનની કિંમત બદલવા માટે રુપરેખાના ડેટાબેઝમાંથી મળેલ કિંમત \"%s\" એ યોગ્ય નથી\n" - -#: ../src/core/prefs.c:1739 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "કી જોડાણ \"%s\" માટે રુપરેખાના ડેટાબેઝ \"%s\" માં મળેલ કિંમત યોગ્ય નથી\n" +#: ../src/core/mutter.c:59 +msgid "Mutter plugin to use" +msgstr "વાપરવા માટે Mutter પ્લગઇન" -#: ../src/core/prefs.c:1836 +#: ../src/core/prefs.c:2101 #, c-format msgid "Workspace %d" msgstr "કામ કરવાની જગ્યા %d" -#: ../src/core/screen.c:730 +#: ../src/core/screen.c:548 #, c-format msgid "Screen %d on display '%s' is invalid\n" msgstr "સ્ક્રીન %d કે જે ડિસ્પ્લે '%s' પર છે એ અયોગ્ય છે\n" -#: ../src/core/screen.c:746 +#: ../src/core/screen.c:564 #, c-format msgid "" "Screen %d on display \"%s\" already has a window manager; try using the --" @@ -210,565 +601,90 @@ msgstr "" "સ્ક્રીન %d કે જે ડિસ્પ્લે \"%s\" પર છે ત્યાં પહેલેથીજ વિન્ડો વ્યવસ્થાપક છે, --replace " "વિક્લ્પનો ઉપયોગ કરીને વિન્ડો વ્યવસ્થાપકને બદલવાનો પ્રયત્ન કરો.\n" -#: ../src/core/screen.c:773 -#, c-format -msgid "Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "સ્ક્રીન %d કે જે ડિસ્પ્લે \"%s\" પર છે તે વિન્ડો વ્યવસ્થાપકની પસંદગીને મેળવી શકાતી નથી\n" - -#: ../src/core/screen.c:828 +#: ../src/core/screen.c:657 #, c-format msgid "Screen %d on display \"%s\" already has a window manager\n" msgstr "સ્ક્રીન %d કે જે ડિસ્પ્લે \"%s\" પર છે ત્યાં પહેલેથીજ વિન્ડો વ્યવસ્થાપક છે\n" -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "સ્ક્રીન %d કે જે ડિસ્પ્લે \"%s\" પર છે તેને દૂર કરી શકાતી નથી\n" - -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "ડિરેક્ટરી '%s' બનાવી શકાતી નથી: %s\n" - -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "સત્રની ફાઈલ '%s' ને લખવા માટે ખોલી શકાતી નથી: %s\n" - -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "સત્રની ફાઈલ '%s' ને લખવામાં ભૂલ: %s\n" - -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "સત્રની ફાઈલ '%s' ને બંધ કરવામાં ભૂલ: %s\n" - -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "સંગ્રહિત સત્રની ફાઈલ ને પદચ્છેદ કરવામાં ભૂલ: %s\n" - -#: ../src/core/session.c:1185 -#, fuzzy, c-format -#| msgid "<metacity_session> attribute seen but we already have the session ID" -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "<metacity_session> લક્ષણ દેખાય છે પરંતુ આપણી પાસે પહેલેથી જ સત્ર ID છે" - -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "અજ્ઞાત લક્ષણ %s એ ઘટક <%s> પર" - -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "પુનરાવર્તિત <window> નિશાની" - -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "અજાણી વસ્તુ %s" - -#: ../src/core/session.c:1809 -#, fuzzy -#| msgid "" -#| "These windows do not support \"save current setup\" and will have to be " -#| "restarted manually next time you log in." -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" -"આ બધી વિન્ડો \"વર્તમાન સુયોજનનો સંગ્રહ કરો\" ને આધાર આપતી નથી અને બીજી વખત તમે પ્રવેશ " -"કરો ત્યારે જાતે જ ફરી શરુ કરવું પડશે." - -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "ભૂલ શોધવા માટેનું નોંધપત્ર ખોલવામાં નિષ્ફળ: %s\n" - -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "fdopen() નોંધપત્ર ફાઈલ %s ખોલવામાં નિષ્ફળ: %s\n" - -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "પ્રવેશ ફાઈલ %s ખૂલેલી છે\n" - -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, fuzzy, c-format -#| msgid "Metacity was compiled without support for verbose mode\n" -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "મેટાસીટીને વર્ણનિય પદ્ધતિના આધાર વગર કમ્પાઈલ કરાયુ હતુ\n" - -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "વિન્ડો વ્યવસ્થાપક: " - -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "વિન્ડો વ્યવસ્થાપકમાં ભૂલ: " - -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "વિન્ડો વ્યવસ્થાપકની ચેતવણી: " - -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "વિન્ડો વ્યવસ્થાપકની ભૂલ: " - -#. first time through -#: ../src/core/window.c:7269 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"ICCCM માં સ્પષ્ટ કરેલ WM_CLIENT_LEADER વિન્ડોની %s જગ્યાએ વિન્ડોએ તેની જાતે જ " -"SM_CLIENT_ID ગોઠવ્યું.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7932 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %" -"d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"વિન્ડો %s એ MWM સંકેત ગોઠવ્યો કે જે તેનું માપ બદલી શકાતુ નથી એમ સૂચવે છે, પરંતુ ન્યૂનત્તમ માપ %" -"d x %d અને મહત્તમ માપ %d x %d ગોઠવાયેલુ છે; તેનો કોઈ ખાસ અર્થ નીકળતો નથી.\n" - -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "કાર્યક્રમ એ ખોટું _NET_WM_PID %lu સુયોજિત કર્યું છે\n" - -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (%s પર)" - -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "અયોગ્ય WM_TRANSIENT_FOR વિન્ડો 0x%lx એ %s માટે સ્પષ્ટ થયેલ છે.\n" - -#: ../src/core/window-props.c:1492 -#, fuzzy, c-format -#| msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "અયોગ્ય WM_TRANSIENT_FOR વિન્ડો 0x%lx એ %s માટે સ્પષ્ટ થયેલ છે.\n" - -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"વિન્ડો 0x%lx પાસે ગુણધર્મ %s છે\n" -"જેના માટે પ્રકાર %s માળખું %d હોવુ જોઈએ\n" -"અને વાસ્તવમાં તેને પ્રકાર %s માળખું %d n_items %d છે.\n" -"આ મોટે ભાગે કાર્યક્રમની ભૂલ હોવી જોઈએ, નહિ કે વિન્ડો વ્યવસ્થાપકની ભૂલ.\n" -"વિન્ડોને શીર્ષક=\"%s\" વર્ગ=\"%s\" નામ=\"%s\"\n" - -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "ગુણધર્મ %s વિન્ડો 0x%lx પર અયોગ્ય UTF-8 ધરાવે છે\n" - -#: ../src/core/xprops.c:494 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "ગુણધર્મ %s વિન્ડો 0x%lx પર યાદીમાં %d વસ્તુ પર અયોગ્ય UTF-8 ધરાવે છે\n" - -#: ../src/muffin.desktop.in.h:1 ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 -#, fuzzy -#| msgid "Modifier to use for modified window click actions" -msgid "Modifier to use for extended window management operations" -msgstr "બદલેલી વિન્ડોની ક્લિક ક્રિયાઓ માટે વાપરવાનું બદલનાર" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 -msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." -msgstr "" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 -msgid "Attach modal dialogs" -msgstr "નમુના સંવાદોને જોડો" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 -msgid "" -"When true, instead of having independent titlebars, modal dialogs appear " -"attached to the titlebar of the parent window and are moved together with " -"the parent window." -msgstr "" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -msgid "Live Hidden Windows" -msgstr "છુપાયેલ વિન્ડોને જીવંત કરો" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 -msgid "Enable edge tiling when dropping windows on screen edges" -msgstr "" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 -msgid "" -"If enabled, dropping windows on vertical screen edges maximizes them " -"vertically and resizes them horizontally to cover half of the available " -"area. Dropping windows on the top screen edge maximizes them completely." -msgstr "" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 -msgid "Workspaces are managed dynamically" -msgstr "કામ કરવાની જગ્યા ગતિશીલ રીતે સંચાલિત થયેલ છે" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 -msgid "" -"Determines whether workspaces are managed dynamically or whether there's a " -"static number of workspaces (determined by the num-workspaces key in org." -"gnome.desktop.wm.preferences)." -msgstr "" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 -msgid "Workspaces only on primary" -msgstr "ફક્ત પ્રાથમિક પર કામ કરવાની જગ્યા" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 -msgid "" -"Determines whether workspace switching should happen for windows on all " -"monitors or only for windows on the primary monitor." -msgstr "" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 -msgid "No tab popup" -msgstr "ટૅબ પોપઅપ નથી" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 -msgid "" -"Determines whether the use of popup and highlight frame should be disabled " -"for window cycling." -msgstr "" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 -msgid "Draggable border width" -msgstr "" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 -msgid "" -"The amount of total draggable borders. If the theme's visible borders are " -"not enough, invisible borders will be added to meet this value." -msgstr "" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:17 -#| msgid "Remove Window From Top" -msgid "Select window from tab popup" -msgstr "ટૅબ પોપઅપમાંથી વિન્ડોને પસંદ કરો" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:18 -msgid "Cancel tab popup" -msgstr "ટૅબ પોપઅપને રદ કરો" - -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "વપરાશ: %s\n" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "ન્યૂનત્તમ કરો (_n)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "મહત્તમ કરો (_x)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "મહત્તમમાંથી પાછુ લાવો (_x)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "વીંટી લો (_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "ખોલી કાઢો (_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "ખસેડો (_M)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "માપ બદલો (_R)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "શીર્ષકપટ્ટી સ્ક્રીન પર ખસેડો (_s)" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "હંમેશા ટોચ પર (_T)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "હંમેશા દ્રશ્ય કામ કરવાની જગ્યા પર (_A)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "માત્ર આ કામ કરવાની જગ્યા પર (_O)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "ડાબી કામ કરવાની જગ્યામાં ખસો (_L)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "જમણી કામ કરવાની જગ્યામાં ખસો (_i)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "ઉપરની કામ કરવાની જગ્યામાં ખસો (_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "ઉપરની કામ કરવાની જગ્યામાં ખસો (_D)" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "બંધ કરો (_C)" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "કામ કરવાની જગ્યા %d%n" - -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "કામ કરવાની જગ્યા ૧_૦" - -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "કામ કરવાની જગ્યા %s%d" - -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "બીજી કામ કરવાની જગ્યામાં ખસેડો" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" +#: ../src/core/util.c:118 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "વર્બોસ સ્થિતિ માટે આધાર વગર Mutter કમ્પાઇલ થયેલ હતુ\n" #. Translators: This represents the size of a window. The first number is #. * the width of the window and the second is the height. #. -#: ../src/ui/resizepopup.c:113 +#: ../src/ui/resizepopup.c:134 #, c-format msgid "%d x %d" msgstr "%d x %d" -#: ../src/ui/theme.c:253 +#: ../src/ui/theme.c:233 msgid "top" msgstr "ઉપર" -#: ../src/ui/theme.c:255 +#: ../src/ui/theme.c:235 msgid "bottom" msgstr "નીચે" -#: ../src/ui/theme.c:257 +#: ../src/ui/theme.c:237 msgid "left" msgstr "ડાબે" -#: ../src/ui/theme.c:259 +#: ../src/ui/theme.c:239 msgid "right" msgstr "જમણે" -#: ../src/ui/theme.c:286 +#: ../src/ui/theme.c:267 #, c-format msgid "frame geometry does not specify \"%s\" dimension" msgstr "ચોકઠાની ભૂમિતિ માપ \"%s\" સ્પષ્ટ કરતી નથી" -#: ../src/ui/theme.c:305 +#: ../src/ui/theme.c:286 #, c-format msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" msgstr "ચોકઠાની ભૂમિતિ કિનારી \"%s\" માટે માપ \"%s\" સ્પષ્ટ કરતી નથી" -#: ../src/ui/theme.c:342 +#: ../src/ui/theme.c:323 #, c-format msgid "Button aspect ratio %g is not reasonable" msgstr "બટન માટે ધારેલુ પ્રમાણ %g એ વ્યવસ્થિત નથી" -#: ../src/ui/theme.c:354 +#: ../src/ui/theme.c:335 #, c-format msgid "Frame geometry does not specify size of buttons" msgstr "ચોકઠાની ભૂમિતિ બટનોનું માપ સ્પષ્ટ કરતી નથી" -#: ../src/ui/theme.c:1067 +#: ../src/ui/theme.c:1061 #, c-format msgid "Gradients should have at least two colors" msgstr "ઢાળમાં ઓછામાં ઓછા બે રંગ હોવા જોઈએ" -#: ../src/ui/theme.c:1219 -#, fuzzy, c-format -#| msgid "" -#| "GTK color specification must have a close bracket after the state, e.g. " -#| "gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#: ../src/ui/theme.c:1211 +#, c-format msgid "" "GTK custom color specification must have color name and fallback in " "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" msgstr "" -"GTK રંગના સ્પષ્ટીકરણમાં સ્થિતિ પછી કૌંસ બંધ થવો જોઈએ દા.ત. gtk:fg[NORMAL] જ્યાં " -"NORMAL સ્થિતિ છે; \"%s\" નો પદચ્છેદ કરી શકાય નહિં" +"GTK વૈવિધ્ય રંગના સ્પષ્ટીકરણનું રંગ નામ હોવુ જ જોઇએ અને સ્થિતિ પછી કૌંસ બંધ થવો જોઈએ દા." +"ત. gtk:custom(foo,bar); \"%s\" નું પદચ્છેદ કરી શકાય નહિં" -#: ../src/ui/theme.c:1235 +#: ../src/ui/theme.c:1227 #, c-format msgid "" "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" "_ are valid" -msgstr "" +msgstr "gtk:custom નાં color_name પરિમાણમાં અમાન્ય અક્ષર '%c', ફક્ત A-Za-z0-9-_ માન્ય છે" -#: ../src/ui/theme.c:1249 -#, fuzzy, c-format -#| msgid "" -#| "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the " -#| "format" +#: ../src/ui/theme.c:1241 +#, c-format msgid "" "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " "fit the format" -msgstr "છાયાનું માળખું \"shade/base_color/factor\" છે, \"%s\" માળખામાં બેસતુ નથી" +msgstr "" +"Gtk:custom બંધારણ એ \"gtk:custom(color_name,fallback)\" છે, \"%s\" એ બંધારણમાં " +"બંધબેસતા નથી" -#: ../src/ui/theme.c:1294 +#: ../src/ui/theme.c:1286 #, c-format msgid "" "GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " @@ -777,7 +693,7 @@ msgstr "" "GTK રંગના સ્પષ્ટીકરણમાં કૌંસમાં સ્થિતિ હોવી જોઈએ દા.ત. gtk:fg[NORMAL] જ્યાં NORMAL " "સ્થિતિ છે; \"%s\" નો પદચ્છેદ કરી શકાય નહિં" -#: ../src/ui/theme.c:1308 +#: ../src/ui/theme.c:1300 #, c-format msgid "" "GTK color specification must have a close bracket after the state, e.g. gtk:" @@ -786,145 +702,145 @@ msgstr "" "GTK રંગના સ્પષ્ટીકરણમાં સ્થિતિ પછી કૌંસ બંધ થવો જોઈએ દા.ત. gtk:fg[NORMAL] જ્યાં " "NORMAL સ્થિતિ છે; \"%s\" નો પદચ્છેદ કરી શકાય નહિં" -#: ../src/ui/theme.c:1319 +#: ../src/ui/theme.c:1311 #, c-format msgid "Did not understand state \"%s\" in color specification" msgstr "રંગના સ્પષ્ટીકરણમાં સ્થિતિ \"%s\" સમજી શકાઈ નહિં" -#: ../src/ui/theme.c:1332 +#: ../src/ui/theme.c:1324 #, c-format msgid "Did not understand color component \"%s\" in color specification" msgstr "રંગના સ્પષ્ટીકરણમાં રંગની વસ્તુ \"%s\" સમજી શકાયો નહિં" -#: ../src/ui/theme.c:1361 +#: ../src/ui/theme.c:1352 #, c-format msgid "" "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " "format" msgstr "\"blend/bg_color/fg_color/alpha\" એ મિશ્રિત માળખું છે, \"%s\" માળખામાં બેસતું નથી " -#: ../src/ui/theme.c:1372 +#: ../src/ui/theme.c:1363 #, c-format msgid "Could not parse alpha value \"%s\" in blended color" msgstr "મિશ્રિત રંગમાં આલ્ફાની કિંમત \"%s\" નું પદચ્છેદ કરી શકાતુ નથી" -#: ../src/ui/theme.c:1382 +#: ../src/ui/theme.c:1373 #, c-format msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" msgstr "મિશ્રિત રંગમાં આલ્ફાની કિંમત \"%s\" ૦.૦ અને ૧.૦ ની વચ્ચે નથી" -#: ../src/ui/theme.c:1429 +#: ../src/ui/theme.c:1419 #, c-format msgid "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" msgstr "છાયાનું માળખું \"shade/base_color/factor\" છે, \"%s\" માળખામાં બેસતુ નથી" -#: ../src/ui/theme.c:1440 +#: ../src/ui/theme.c:1430 #, c-format msgid "Could not parse shade factor \"%s\" in shaded color" msgstr "છાયાંકિત રંગમાં છાયાનો અવયવ \"%s\" નું પદચ્છેદ કરી શકાતુ નથી" -#: ../src/ui/theme.c:1450 +#: ../src/ui/theme.c:1440 #, c-format msgid "Shade factor \"%s\" in shaded color is negative" msgstr "છાયાનો અવયવ \"%s\" છાયાના રંગમાં ઋણ છે" -#: ../src/ui/theme.c:1479 +#: ../src/ui/theme.c:1469 #, c-format msgid "Could not parse color \"%s\"" msgstr "રંગ \"%s\" નુ પદચ્છેદ કરી શકાતુ નથી" -#: ../src/ui/theme.c:1790 +#: ../src/ui/theme.c:1778 #, c-format msgid "Coordinate expression contains character '%s' which is not allowed" msgstr "યામાક્ષ સમીકરણ અક્ષર '%s' ધરાવે છે જે સ્વીકાર્ય નથી" -#: ../src/ui/theme.c:1817 +#: ../src/ui/theme.c:1805 #, c-format msgid "" "Coordinate expression contains floating point number '%s' which could not be " "parsed" msgstr "યામાક્ષ સમીકરણ અપૂર્ણાંક સંખ્યા '%s' ધરાવે છે જેનું પદચ્છેદ કરી શકાતું નથી" -#: ../src/ui/theme.c:1831 +#: ../src/ui/theme.c:1819 #, c-format msgid "Coordinate expression contains integer '%s' which could not be parsed" msgstr "યામાક્ષ સમીકરણ પૂર્ણાંક સંખ્યા '%s' ધરાવે છે જેનું પદચ્છેદ કરી શકાતું નથી" -#: ../src/ui/theme.c:1953 +#: ../src/ui/theme.c:1940 #, c-format msgid "" "Coordinate expression contained unknown operator at the start of this text: " "\"%s\"" msgstr "યામાક્ષ સમીકરણમાં આ લખાણની શરુઆતમાં અજાણ્યા કારકો ધરાવે છે: \"%s\"" -#: ../src/ui/theme.c:2010 +#: ../src/ui/theme.c:1997 #, c-format msgid "Coordinate expression was empty or not understood" msgstr "યામાક્ષ સમીકરણ ખાલી છે અથવા સમજી શકાય એવું નથી" -#: ../src/ui/theme.c:2121 ../src/ui/theme.c:2131 ../src/ui/theme.c:2165 +#: ../src/ui/theme.c:2110 ../src/ui/theme.c:2120 ../src/ui/theme.c:2154 #, c-format msgid "Coordinate expression results in division by zero" msgstr "યામાક્ષ સમીકરણ શૂન્ય વડે ભાગાકારમાં પરિણમશે" -#: ../src/ui/theme.c:2173 +#: ../src/ui/theme.c:2162 #, c-format msgid "Coordinate expression tries to use mod operator on a floating-point number" msgstr "યામાક્ષ સમીકરણ અપૂર્ણાંક સંખ્યાની ઉપર શેષ કારકનો ઉપયોગ કરવાનો પ્રયત્ન કરે છે" -#: ../src/ui/theme.c:2229 +#: ../src/ui/theme.c:2218 #, c-format msgid "Coordinate expression has an operator \"%s\" where an operand was expected" msgstr "યામાક્ષ સમીકરણ માટે \"%s\" કારક છે જેના માટે ઓપરન્ડ હોવા જોઈએ" -#: ../src/ui/theme.c:2238 +#: ../src/ui/theme.c:2227 #, c-format msgid "Coordinate expression had an operand where an operator was expected" msgstr "યામાક્ષ સમીકરણમાં ઓપરન્ડ છે જ્યાં કારક હોવુ જોઈતું હતું" -#: ../src/ui/theme.c:2246 +#: ../src/ui/theme.c:2235 #, c-format msgid "Coordinate expression ended with an operator instead of an operand" msgstr "યામાક્ષ સમીકરણનો અંત ઓપરન્ડની જગ્યાએ કારકથી થાય છે" -#: ../src/ui/theme.c:2256 +#: ../src/ui/theme.c:2245 #, c-format msgid "" "Coordinate expression has operator \"%c\" following operator \"%c\" with no " "operand in between" msgstr "યામાક્ષ સમીકરણમાં \"%c\" કારક પછી તરત જ \"%c\" કારક છે જેમની વચ્ચે કોઈ ઓપરન્ડ નથી" -#: ../src/ui/theme.c:2407 ../src/ui/theme.c:2452 +#: ../src/ui/theme.c:2396 ../src/ui/theme.c:2441 #, c-format msgid "Coordinate expression had unknown variable or constant \"%s\"" msgstr "યામાક્ષ સમીકરણમાં અજાણ્યો ચલ કે અચલ \"%s\" છે" -#: ../src/ui/theme.c:2506 +#: ../src/ui/theme.c:2495 #, c-format msgid "Coordinate expression parser overflowed its buffer." msgstr "યામાક્ષ સમીકરણ પદચ્છેદકે તેનું બફર ઓવરફ્લો કરી નાંખ્યું." -#: ../src/ui/theme.c:2535 +#: ../src/ui/theme.c:2524 #, c-format msgid "Coordinate expression had a close parenthesis with no open parenthesis" msgstr "યામાક્ષ સમીકરણ પાસે ખુલ્લા કૌંસની વગર જ બંધ કૌંસ છે" -#: ../src/ui/theme.c:2599 +#: ../src/ui/theme.c:2588 #, c-format msgid "Coordinate expression had an open parenthesis with no close parenthesis" msgstr "યામાક્ષ સમીકરણ પાસે બંધ કૌંસની વગર જ ખુલ્લો કૌંસ હતો" -#: ../src/ui/theme.c:2610 +#: ../src/ui/theme.c:2599 #, c-format msgid "Coordinate expression doesn't seem to have any operators or operands" msgstr "યામાક્ષ સમીકરણમાં કોઈ કારક કે ઓપરન્ડ હોય તેવુ લાગતુ નથી" -#: ../src/ui/theme.c:2822 ../src/ui/theme.c:2842 ../src/ui/theme.c:2862 +#: ../src/ui/theme.c:2812 ../src/ui/theme.c:2832 ../src/ui/theme.c:2852 #, c-format msgid "Theme contained an expression that resulted in an error: %s\n" msgstr "થીમે સમાવેલ સમીકરણને કારણે ભૂલમાં પરિણમ્યું: %s\n" -#: ../src/ui/theme.c:4533 +#: ../src/ui/theme.c:4455 #, c-format msgid "" "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " @@ -933,23 +849,23 @@ msgstr "" "આ માળખાની શૈલી માટે <button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/" "> સ્પષ્ટ કરેલી હોવી જરુરી છે" -#: ../src/ui/theme.c:5066 ../src/ui/theme.c:5091 +#: ../src/ui/theme.c:4970 ../src/ui/theme.c:4995 #, c-format msgid "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" msgstr "<frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/> ખોવાય છે" -#: ../src/ui/theme.c:5139 +#: ../src/ui/theme.c:5041 #, c-format msgid "Failed to load theme \"%s\": %s\n" msgstr "થીમ \"%s\" લાવવામાં નિષ્ફળ: %s\n" -#: ../src/ui/theme.c:5275 ../src/ui/theme.c:5282 ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 ../src/ui/theme.c:5303 +#: ../src/ui/theme.c:5177 ../src/ui/theme.c:5184 ../src/ui/theme.c:5191 +#: ../src/ui/theme.c:5198 ../src/ui/theme.c:5205 #, c-format msgid "No <%s> set for theme \"%s\"" msgstr "કોઈ <%s> ગોઠવણ થીમ \"%s\" માટે નથી" -#: ../src/ui/theme.c:5311 +#: ../src/ui/theme.c:5213 #, c-format msgid "" "No frame style set for window type \"%s\" in theme \"%s\", add a <window " @@ -958,12 +874,12 @@ msgstr "" "થીમ \"%s\" માં વિન્ડોના પ્રકાર \"%s\" માટે કોઈ માળખાની શૈલી ગોઠવાયેલી નથી, <window " "type=\"%s\" style_set=\"whatever\"/> વસ્તુ ઊમેરો" -#: ../src/ui/theme.c:5709 ../src/ui/theme.c:5771 ../src/ui/theme.c:5834 +#: ../src/ui/theme.c:5620 ../src/ui/theme.c:5682 ../src/ui/theme.c:5745 #, c-format msgid "User-defined constants must begin with a capital letter; \"%s\" does not" msgstr "વપરાશકર્તા દ્વારા વ્યાખ્યાયિત અચલો મોટા અક્ષરથી જ શરુ થવા જોઈએ; \"%s\" નહિં" -#: ../src/ui/theme.c:5717 ../src/ui/theme.c:5779 ../src/ui/theme.c:5842 +#: ../src/ui/theme.c:5628 ../src/ui/theme.c:5690 ../src/ui/theme.c:5753 #, c-format msgid "Constant \"%s\" has already been defined" msgstr "અચલ \"%s\" પહેલેથી જ વ્યાખ્યાયિત છે" @@ -971,67 +887,67 @@ msgstr "અચલ \"%s\" પહેલેથી જ વ્યાખ્યાય #. Translators: This means that an attribute which should have been found #. * on an XML element was not in fact found. #. -#: ../src/ui/theme-parser.c:236 +#: ../src/ui/theme-parser.c:234 #, c-format msgid "No \"%s\" attribute on element <%s>" msgstr "કોઈ \"%s\" લક્ષણ ઘટક <%s> પર નથી" -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 +#: ../src/ui/theme-parser.c:263 ../src/ui/theme-parser.c:281 #, c-format msgid "Line %d character %d: %s" msgstr "લીટી %d અક્ષર %d: %s" -#: ../src/ui/theme-parser.c:479 +#: ../src/ui/theme-parser.c:481 #, c-format msgid "Attribute \"%s\" repeated twice on the same <%s> element" msgstr "લક્ષણ \"%s\" સરખી <%s> વસ્તુઓ પર બે વખત પુનરાવરર્તિત થાય છે" -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 +#: ../src/ui/theme-parser.c:505 ../src/ui/theme-parser.c:554 #, c-format msgid "Attribute \"%s\" is invalid on <%s> element in this context" msgstr "લક્ષણ \"%s\" આ સંદર્ભ માટે <%s> વસ્તુ પર અયોગ્ય છે" -#: ../src/ui/theme-parser.c:594 +#: ../src/ui/theme-parser.c:596 #, c-format msgid "Could not parse \"%s\" as an integer" msgstr "\"%s\" ને પૂર્ણાંક તરીકે પદચ્છેદ કરી શકાયુ નહિ" -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 +#: ../src/ui/theme-parser.c:605 ../src/ui/theme-parser.c:660 #, c-format msgid "Did not understand trailing characters \"%s\" in string \"%s\"" msgstr "શબ્દમાળા \"%s\" માં પૂંછડિયા અક્ષરો \"%s\" સમજી શકાયા નહિં" -#: ../src/ui/theme-parser.c:613 +#: ../src/ui/theme-parser.c:615 #, c-format msgid "Integer %ld must be positive" msgstr "પૂર્ણાંક %ld ધન હોવું જોઈએ" -#: ../src/ui/theme-parser.c:621 +#: ../src/ui/theme-parser.c:623 #, c-format msgid "Integer %ld is too large, current max is %d" msgstr "પૂર્ણાંક %ld બહુ મોટો છે, વર્તમાન મહત્તમ %d છે" -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 +#: ../src/ui/theme-parser.c:651 ../src/ui/theme-parser.c:767 #, c-format msgid "Could not parse \"%s\" as a floating point number" msgstr "\"%s\" ને અપૂર્ણાંક સંખ્યા તરીકે પદચ્છેદ કરી શકાયો નહિં" -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 +#: ../src/ui/theme-parser.c:682 ../src/ui/theme-parser.c:710 #, c-format msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" msgstr "બુલિયન કિંમતો \"ખરુ\" અથવા \"ખોટુ\" હોવી જોઈએ નહિં કે \"%s\"" -#: ../src/ui/theme-parser.c:735 +#: ../src/ui/theme-parser.c:737 #, c-format msgid "Angle must be between 0.0 and 360.0, was %g\n" msgstr "ખૂણો ૦.૦ અને ૩૬૦.૦ ની વચ્ચે હોવો જોઈએ, જે %g હતો\n" -#: ../src/ui/theme-parser.c:798 +#: ../src/ui/theme-parser.c:800 #, c-format msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" msgstr "ખૂણો ૦.૦ (અદ્રશ્ય) અને ૧.૦ (પૂર્ણ અપારદર્શક) ની વચ્ચે હોવો જોઈએ, જે %g હતો\n" -#: ../src/ui/theme-parser.c:863 +#: ../src/ui/theme-parser.c:865 #, c-format msgid "" "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," @@ -1040,58 +956,58 @@ msgstr "" "શીર્ષક \"%s\" નું અયોગ્ય માપ (આમાંથી જ એક હોવું જોઈએ- xx-small,x-small,small,medium," "large,x-large,xx-large)\n" -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 +#: ../src/ui/theme-parser.c:1021 ../src/ui/theme-parser.c:1084 +#: ../src/ui/theme-parser.c:1118 ../src/ui/theme-parser.c:1221 #, c-format msgid "<%s> name \"%s\" used a second time" msgstr "<%s> નામ \"%s\" નો બીજી વાર ઉપયોગ થયો" -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 +#: ../src/ui/theme-parser.c:1033 ../src/ui/theme-parser.c:1130 +#: ../src/ui/theme-parser.c:1233 #, c-format msgid "<%s> parent \"%s\" has not been defined" msgstr "<%s> પિતૃ \"%s\" વ્યાખ્યાયિત નથી" -#: ../src/ui/theme-parser.c:1141 +#: ../src/ui/theme-parser.c:1143 #, c-format msgid "<%s> geometry \"%s\" has not been defined" msgstr "<%s> ભૂમિતિ \"%s\" વ્યાખ્યાયિત નથી" -#: ../src/ui/theme-parser.c:1154 +#: ../src/ui/theme-parser.c:1156 #, c-format msgid "<%s> must specify either a geometry or a parent that has a geometry" msgstr "<%s> ને ભૂમિતિ અથવા પિતૃ કે જેની પાસે ભૂમિતિ હોય તે સ્પષ્ટ કરવો જ પડે છે" -#: ../src/ui/theme-parser.c:1196 +#: ../src/ui/theme-parser.c:1198 msgid "You must specify a background for an alpha value to be meaningful" msgstr "આલ્ફા કિંમત ઉપયોગી હોય તે માટે તમારે પાશ્વભાગ સ્પષ્ટ કરવો જ પડશે" -#: ../src/ui/theme-parser.c:1264 +#: ../src/ui/theme-parser.c:1266 #, c-format msgid "Unknown type \"%s\" on <%s> element" msgstr "<%s> વસ્તુ પર અજાણ્યો પ્રકાર \"%s\"" -#: ../src/ui/theme-parser.c:1275 +#: ../src/ui/theme-parser.c:1277 #, c-format msgid "Unknown style_set \"%s\" on <%s> element" msgstr "<%s> વસ્તુ પર અજાણી શૈલીની ગોઠવણી \"%s\"" -#: ../src/ui/theme-parser.c:1283 +#: ../src/ui/theme-parser.c:1285 #, c-format msgid "Window type \"%s\" has already been assigned a style set" msgstr "વિન્ડોના પ્રકાર \"%s\" માટે પહેલેથી જ શૈલીની ગોઠવણીની નિમણૂક કરેલી છે" -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 +#: ../src/ui/theme-parser.c:1315 ../src/ui/theme-parser.c:1379 +#: ../src/ui/theme-parser.c:1605 ../src/ui/theme-parser.c:2840 +#: ../src/ui/theme-parser.c:2886 ../src/ui/theme-parser.c:3036 +#: ../src/ui/theme-parser.c:3272 ../src/ui/theme-parser.c:3310 +#: ../src/ui/theme-parser.c:3348 ../src/ui/theme-parser.c:3386 #, c-format msgid "Element <%s> is not allowed below <%s>" msgstr "વસ્તુ <%s> એ <%s> ની નીચે સ્વીકૃત નથી" -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 +#: ../src/ui/theme-parser.c:1429 ../src/ui/theme-parser.c:1443 +#: ../src/ui/theme-parser.c:1488 msgid "" "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " "for buttons" @@ -1099,147 +1015,147 @@ msgstr "" "બટનો માટે \"button_width\"/\"button_height\" અને \"aspect_ratio\" બંને સ્પષ્ટ કરી " "શકતા નથી" -#: ../src/ui/theme-parser.c:1450 +#: ../src/ui/theme-parser.c:1452 #, c-format msgid "Distance \"%s\" is unknown" msgstr "અંતર \"%s\" અજાણ છે" -#: ../src/ui/theme-parser.c:1495 +#: ../src/ui/theme-parser.c:1497 #, c-format msgid "Aspect ratio \"%s\" is unknown" msgstr "ધારેલુ પ્રમાણ \"%s\" અજાણ છે" -#: ../src/ui/theme-parser.c:1557 +#: ../src/ui/theme-parser.c:1559 #, c-format msgid "Border \"%s\" is unknown" msgstr "કિનારી \"%s\" અજાણી છે" -#: ../src/ui/theme-parser.c:1868 +#: ../src/ui/theme-parser.c:1870 #, c-format msgid "No \"start_angle\" or \"from\" attribute on element <%s>" msgstr "ઘટક <%s> પર કોઈ \"start_angle\" અથવા \"from\" લક્ષણ નથી" -#: ../src/ui/theme-parser.c:1875 +#: ../src/ui/theme-parser.c:1877 #, c-format msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" msgstr "ઘટક <%s> પર કોઈ \"extent_angle\" અથવા \"to\" લક્ષણ નથી" -#: ../src/ui/theme-parser.c:2115 +#: ../src/ui/theme-parser.c:2117 #, c-format msgid "Did not understand value \"%s\" for type of gradient" msgstr "ઢાળના પ્રકાર માટે કિંમત \"%s\" ને સમજી શકાતી નથી" -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 +#: ../src/ui/theme-parser.c:2195 ../src/ui/theme-parser.c:2570 #, c-format msgid "Did not understand fill type \"%s\" for <%s> element" msgstr "વસ્તુ <%s> માટે ફિલનો પ્રકાર \"%s\" સમજી શકાતો નથી" -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 +#: ../src/ui/theme-parser.c:2362 ../src/ui/theme-parser.c:2445 +#: ../src/ui/theme-parser.c:2508 #, c-format msgid "Did not understand state \"%s\" for <%s> element" msgstr "સ્થિતિ \"%s\" વસ્તુ <%s> માટે સમજી શકાતી નથી" -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 +#: ../src/ui/theme-parser.c:2372 ../src/ui/theme-parser.c:2455 #, c-format msgid "Did not understand shadow \"%s\" for <%s> element" msgstr "છાયા \"%s\" વસ્તુ <%s> માટે સમજી શકાતી નથી" -#: ../src/ui/theme-parser.c:2380 +#: ../src/ui/theme-parser.c:2382 #, c-format msgid "Did not understand arrow \"%s\" for <%s> element" msgstr "તીર \"%s\" વસ્તુ <%s> માટે સમજી શકાતુ નથી" -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 +#: ../src/ui/theme-parser.c:2696 ../src/ui/theme-parser.c:2792 #, c-format msgid "No <draw_ops> called \"%s\" has been defined" msgstr "કોઈ <draw_ops> બોલાવાયેલ \"%s\" વ્યાખ્યાયિત નથી" -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 +#: ../src/ui/theme-parser.c:2708 ../src/ui/theme-parser.c:2804 #, c-format msgid "Including draw_ops \"%s\" here would create a circular reference" msgstr "draw_ops ની સાથે \"%s\" વર્તુળાકાર નિર્દેશ બની જશે" -#: ../src/ui/theme-parser.c:2917 +#: ../src/ui/theme-parser.c:2919 #, c-format msgid "Unknown position \"%s\" for frame piece" msgstr "તકતીના ટુકડા માટે અજાણી સ્થિતિ \"%s\" છે" -#: ../src/ui/theme-parser.c:2925 +#: ../src/ui/theme-parser.c:2927 #, c-format msgid "Frame style already has a piece at position %s" msgstr "તકતીની શૈલી પાસે પહેલેથી જ સ્થિતિ %s પાસે ટુકડો છે" -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 +#: ../src/ui/theme-parser.c:2944 ../src/ui/theme-parser.c:3021 #, c-format msgid "No <draw_ops> with the name \"%s\" has been defined" msgstr "કોઈ પણ <draw_ops> નામ \"%s\" સાથે વ્યાખ્યાયિત નથી" -#: ../src/ui/theme-parser.c:2972 +#: ../src/ui/theme-parser.c:2974 #, c-format msgid "Unknown function \"%s\" for button" msgstr "\"%s\" એ બટન માટે અજાણ્યું વિધેય છે" -#: ../src/ui/theme-parser.c:2982 +#: ../src/ui/theme-parser.c:2984 #, c-format msgid "Button function \"%s\" does not exist in this version (%d, need %d)" msgstr "બટન વિધેય \"%s\" આ આવૃત્તિમાં અસ્તિત્વમાં નથી (%d, %d જરૂર)" -#: ../src/ui/theme-parser.c:2994 +#: ../src/ui/theme-parser.c:2996 #, c-format msgid "Unknown state \"%s\" for button" msgstr "\"%s\" એ બટન માટે અજાણી સ્થિતિ છે" -#: ../src/ui/theme-parser.c:3002 +#: ../src/ui/theme-parser.c:3004 #, c-format msgid "Frame style already has a button for function %s state %s" msgstr "વિધેય %s ની સ્થિતિ %s માટેના ચોકઠાની શૈલી પાસે પહેલેથી જ બટન છે" -#: ../src/ui/theme-parser.c:3073 +#: ../src/ui/theme-parser.c:3075 #, c-format msgid "\"%s\" is not a valid value for focus attribute" msgstr "પ્રકાશન લક્ષણ માટે \"%s\" એ યોગ્ય કિંમત નથી" -#: ../src/ui/theme-parser.c:3082 +#: ../src/ui/theme-parser.c:3084 #, c-format msgid "\"%s\" is not a valid value for state attribute" msgstr "સ્થિતિ લક્ષણ માટે \"%s\" એ યોગ્ય કિંમત નથી" -#: ../src/ui/theme-parser.c:3092 +#: ../src/ui/theme-parser.c:3094 #, c-format msgid "A style called \"%s\" has not been defined" msgstr "શૈલી જે \"%s\" તરીકે ઓળખાય છે તે હજુ સુધી વ્યાખ્યાયિત થઈ નથી" -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 +#: ../src/ui/theme-parser.c:3115 ../src/ui/theme-parser.c:3138 #, c-format msgid "\"%s\" is not a valid value for resize attribute" msgstr "માપ બદલવાના લક્ષણ માટે \"%s\" એ યોગ્ય કિંમત નથી" -#: ../src/ui/theme-parser.c:3147 +#: ../src/ui/theme-parser.c:3149 #, c-format msgid "" "Should not have \"resize\" attribute on <%s> element for maximized/shaded " "states" msgstr "મહત્તમ/છાયાંકિત સ્થિતિઓ માટે <%s> વસ્તુ પર \"માપ બદલો\" એવું કોઈ લક્ષણ નથી" -#: ../src/ui/theme-parser.c:3161 +#: ../src/ui/theme-parser.c:3163 #, c-format msgid "Should not have \"resize\" attribute on <%s> element for maximized states" msgstr "મહત્તમ સ્થિતિઓ માટે ઘટક <%s> પર \"resize\" એવું કોઈ લક્ષણ નથી" -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 +#: ../src/ui/theme-parser.c:3177 ../src/ui/theme-parser.c:3221 #, c-format msgid "Style has already been specified for state %s resize %s focus %s" msgstr "સ્થિતિ %s માપ બદલનાર %s પ્રકાશન %s માટે પહેલેથી જ શૈલી સ્પષ્ટ કરાયેલી છે" -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 +#: ../src/ui/theme-parser.c:3188 ../src/ui/theme-parser.c:3199 +#: ../src/ui/theme-parser.c:3210 ../src/ui/theme-parser.c:3232 +#: ../src/ui/theme-parser.c:3243 ../src/ui/theme-parser.c:3254 #, c-format msgid "Style has already been specified for state %s focus %s" msgstr "સ્થિતિ %s પ્રકાશન %s માટે પહેલેથી જ શૈલી સ્પષ્ટ કરાયેલી છે" -#: ../src/ui/theme-parser.c:3294 +#: ../src/ui/theme-parser.c:3293 msgid "" "Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " "attribute and also a <draw_ops> element, or specified two elements)" @@ -1247,7 +1163,7 @@ msgstr "" "<piece> વસ્તુ માટે બે draw_ops ના હોઈ શકે (થીમે draw_ops લક્ષણ તથા <draw_ops> વસ્તુ " "પણ સ્પષ્ટ કર્યો, અથવા બંને વસ્તુઓ સ્પષ્ટ કર્યા)" -#: ../src/ui/theme-parser.c:3332 +#: ../src/ui/theme-parser.c:3331 msgid "" "Can't have a two draw_ops for a <button> element (theme specified a draw_ops " "attribute and also a <draw_ops> element, or specified two elements)" @@ -1255,7 +1171,7 @@ msgstr "" "<button> વસ્તુ માટે બે draw_ops ના હોઈ શકે (થીમે draw_ops લક્ષણ તથા <draw_ops> વસ્તુ " "પણ સ્પષ્ટ કર્યો, અથવા બંને વસ્તુઓ સ્પષ્ટ કર્યા)" -#: ../src/ui/theme-parser.c:3370 +#: ../src/ui/theme-parser.c:3369 msgid "" "Can't have a two draw_ops for a <menu_icon> element (theme specified a " "draw_ops attribute and also a <draw_ops> element, or specified two elements)" @@ -1263,275 +1179,475 @@ msgstr "" "<menu_icon> વસ્તુ માટે બે draw_ops ના હોઈ શકે (થીમે draw_ops લક્ષણ તથા <draw_ops> " "વસ્તુ પણ સ્પષ્ટ કર્યો, અથવા બંને વસ્તુઓ સ્પષ્ટ કર્યા)" -#: ../src/ui/theme-parser.c:3434 +#: ../src/ui/theme-parser.c:3433 #, c-format msgid "Bad version specification '%s'" msgstr "ખરાબ આવૃત્તિ સ્પષ્ટીકરણ '%s'" -#: ../src/ui/theme-parser.c:3507 +#: ../src/ui/theme-parser.c:3506 msgid "" "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" "theme-2.xml" msgstr "" +"\"version\" ગુણધર્મ metacity-theme-1.xml અથવા metacity-theme-2.xml માં વાપરી " +"શકાતુ નથી" -#: ../src/ui/theme-parser.c:3530 +#: ../src/ui/theme-parser.c:3529 #, c-format msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "" +msgstr "થીમને આવૃત્તિ %s ની જરૂર છે પરંતુ તાજેતરની આધારભૂત થીમ આવૃત્તિ %d છે.%d" -#: ../src/ui/theme-parser.c:3562 +#: ../src/ui/theme-parser.c:3561 #, c-format msgid "Outermost element in theme must be <metacity_theme> not <%s>" msgstr "થીમની સૌથી બહારની વસ્તુ <metacity_theme> જ હોવો જોઈએ નહિં કે <%s>" -#: ../src/ui/theme-parser.c:3582 +#: ../src/ui/theme-parser.c:3581 #, c-format msgid "Element <%s> is not allowed inside a name/author/date/description element" msgstr "વસ્તુ <%s> name/author/date/description ની અંદર સ્વીકાર્ય નથી" -#: ../src/ui/theme-parser.c:3587 +#: ../src/ui/theme-parser.c:3586 #, c-format msgid "Element <%s> is not allowed inside a <constant> element" msgstr "વસ્તુ <%s> એ <constant> વસ્તુની અંદર સ્વીકાર્ય નથી" -#: ../src/ui/theme-parser.c:3599 +#: ../src/ui/theme-parser.c:3598 #, c-format msgid "Element <%s> is not allowed inside a distance/border/aspect_ratio element" msgstr "વસ્તુ <%s> એ distance/border/aspect_ratio વસ્તુની અંદર સ્વીકાર્ય નથી" -#: ../src/ui/theme-parser.c:3621 +#: ../src/ui/theme-parser.c:3620 #, c-format msgid "Element <%s> is not allowed inside a draw operation element" msgstr "વસ્તુ <%s> એ દોરવાની પ્રક્રિયાના વસ્તુની અંદર સ્વીકાર્ય નથી" -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 +#: ../src/ui/theme-parser.c:3630 ../src/ui/theme-parser.c:3660 +#: ../src/ui/theme-parser.c:3665 ../src/ui/theme-parser.c:3670 #, c-format msgid "Element <%s> is not allowed inside a <%s> element" msgstr "વસ્તુ <%s> એ <%s> વસ્તુની અંદર સ્વીકાર્ય નથી" -#: ../src/ui/theme-parser.c:3899 +#: ../src/ui/theme-parser.c:3898 msgid "No draw_ops provided for frame piece" msgstr "ચોકઠાના ટુકડા માટે કોઈ draw_ops આપેલ નથી" -#: ../src/ui/theme-parser.c:3914 +#: ../src/ui/theme-parser.c:3913 msgid "No draw_ops provided for button" msgstr "બટન માટે કોઈ draw_ops આપેલ નથી" -#: ../src/ui/theme-parser.c:3968 +#: ../src/ui/theme-parser.c:3967 #, c-format msgid "No text is allowed inside element <%s>" msgstr "કોઈ લખાણ વસ્તુ <%s> ની અંદર સ્વીકાર્ય નથી" -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 +#: ../src/ui/theme-parser.c:4025 ../src/ui/theme-parser.c:4037 +#: ../src/ui/theme-parser.c:4049 ../src/ui/theme-parser.c:4061 +#: ../src/ui/theme-parser.c:4073 #, c-format -#| msgid "<name> specified twice for this theme" msgid "<%s> specified twice for this theme" msgstr "આ થીમ માટે <%s> બે વખત સ્પષ્ટ કરેલ છે" -#: ../src/ui/theme-parser.c:4348 +#: ../src/ui/theme-parser.c:4335 #, c-format msgid "Failed to find a valid file for theme %s\n" msgstr "થીમ %s માટે માન્ય ફાઈલ શોધવામાં નિષ્ફળ\n" -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "વિન્ડો (_W)" +#: ../src/x11/session.c:1815 +msgid "" +"These windows do not support "save current setup" and will have to " +"be restarted manually next time you log in." +msgstr "" +"આ બધી વિન્ડો "વર્તમાન સુયોજનનો સંગ્રહ કરો" ને આધાર આપતી નથી અને બીજી વખત " +"તમે પ્રવેશ કરો ત્યારે જાતે જ ફરી શરુ કરવું પડશે." -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "સંવાદ (_D)" +#: ../src/x11/window-props.c:515 +#, c-format +msgid "%s (on %s)" +msgstr "%s (%s પર)" -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "નમુના સંવાદ (_M)" +#~ msgid "background texture could not be created from file" +#~ msgstr "પાશ્ર્વભાગનું બંધારણ ફાઇલમાંથી બનાવી શક્યા નહિં" -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "ઉપયોગિતા (_U)" +#~ msgid "Unknown window information request: %d" +#~ msgstr "અજ્ઞાત વિન્ડો જાણકારી અરજી: %d" -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "ઝબૂક સ્ક્રીન (_S)" +#~ msgid "Missing %s extension required for compositing" +#~ msgstr "કમ્પોઝીટીંગ માટે ગુમ થયેલ %s એક્સટેન્સન જરૂરી" -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "ઉપરનો ડોક (_T)" +#~ msgid "" +#~ "Some other program is already using the key %s with modifiers %x as a " +#~ "binding\n" +#~ msgstr "" +#~ "કોઈ બીજો કાર્યક્રમ પહેલેથીજ કી %s ને બદલનાર %x સાથે જોડાણ તરીકે વાપરી રહ્યુ છે\n" -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "નીચલો ડોક (_B)" +#~| msgid "\"%s\" is not a valid value for focus attribute" +#~ msgid "\"%s\" is not a valid accelerator\n" +#~ msgstr "\"%s\" એ માન્ય પ્રવેગક નથી\n" -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "ડાબુ ડોક (_L)" +#~ msgid "" +#~ "Workarounds for broken applications disabled. Some applications may not " +#~ "behave properly.\n" +#~ msgstr "" +#~ "બગડેલા કાર્યક્રમો માટે આસપાસના કાર્યો નિષ્ક્રિય કરેલા છે. કદાચ કેટલાક કાર્યક્રમો યોગ્ય " +#~ "રીતે નહિ વર્તતા હોય.\n" -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "જમણું ડોક (_R)" +#~ msgid "Could not parse font description \"%s\" from GSettings key %s\n" +#~ msgstr "ફોન્ટ વર્ણન \"%s\" GSettings કી %s માંથી નું પદચ્છેદન કરી શક્યા નહિં\n" -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "બધા ડોક (_A)" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" +#~ msgstr "" +#~ "માઉસ બટનની કિંમત બદલવા માટે રુપરેખાના ડેટાબેઝમાંથી મળેલ કિંમત \"%s\" એ યોગ્ય નથી\n" -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "ડેસ્કટોપ (_k)" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for " +#~ "keybinding \"%s\"\n" +#~ msgstr "કી જોડાણ \"%s\" માટે રુપરેખાના ડેટાબેઝ \"%s\" માં મળેલ કિંમત યોગ્ય નથી\n" -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "આ બધી વિન્ડોમાંથી બીજી વિન્ડો ખોલો" +#~ msgid "" +#~ "Could not acquire window manager selection on screen %d display \"%s\"\n" +#~ msgstr "" +#~ "સ્ક્રીન %d કે જે ડિસ્પ્લે \"%s\" પર છે તે વિન્ડો વ્યવસ્થાપકની પસંદગીને મેળવી શકાતી નથી\n" -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "આ ડેમો બટન 'ખોલો' ચિહ્ન સાથે છે" +#~ msgid "Could not release screen %d on display \"%s\"\n" +#~ msgstr "સ્ક્રીન %d કે જે ડિસ્પ્લે \"%s\" પર છે તેને દૂર કરી શકાતી નથી\n" -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "આ ડેમો બટન 'બહાર નીકળો' ચિહ્ન સાથે છે" +#~ msgid "Could not create directory '%s': %s\n" +#~ msgstr "ડિરેક્ટરી '%s' બનાવી શકાતી નથી: %s\n" -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "આ નમબના સંવાદમાં સરળ સંદેશો છે" +#~ msgid "Could not open session file '%s' for writing: %s\n" +#~ msgstr "સત્રની ફાઈલ '%s' ને લખવા માટે ખોલી શકાતી નથી: %s\n" -#: ../src/ui/theme-viewer.c:328 -#, c-format -msgid "Fake menu item %d\n" -msgstr "ખોટી મેનુ વસ્તુ %d\n" +#~ msgid "Error writing session file '%s': %s\n" +#~ msgstr "સત્રની ફાઈલ '%s' ને લખવામાં ભૂલ: %s\n" -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "વિન્ડો માટે માત્ર કિનારી" +#~ msgid "Error closing session file '%s': %s\n" +#~ msgstr "સત્રની ફાઈલ '%s' ને બંધ કરવામાં ભૂલ: %s\n" -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "પટ્ટી" +#~ msgid "Failed to parse saved session file: %s\n" +#~ msgstr "સંગ્રહિત સત્રની ફાઈલ ને પદચ્છેદ કરવામાં ભૂલ: %s\n" -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "કાર્યક્રમની સામાન્ય વિન્ડો" +#~ msgid "<mutter_session> attribute seen but we already have the session ID" +#~ msgstr "<mutter_session> લક્ષણ દેખાય છે પરંતુ આપણી પાસે પહેલેથી જ સત્ર ID છે" -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "સંવાદ પેટી" +#~ msgid "Unknown attribute %s on <%s> element" +#~ msgstr "અજ્ઞાત લક્ષણ %s એ ઘટક <%s> પર" -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "નમુના સંવાદ પેટી" +#~ msgid "nested <window> tag" +#~ msgstr "પુનરાવર્તિત <window> નિશાની" -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "ઉપયોગિતા પેલેટ" +#~ msgid "Unknown element %s" +#~ msgstr "અજાણી વસ્તુ %s" -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "કાઢી નાખેલ મેનુ" +#~ msgid "Failed to open debug log: %s\n" +#~ msgstr "ભૂલ શોધવા માટેનું નોંધપત્ર ખોલવામાં નિષ્ફળ: %s\n" -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "કિનારી" +#~ msgid "Failed to fdopen() log file %s: %s\n" +#~ msgstr "fdopen() નોંધપત્ર ફાઈલ %s ખોલવામાં નિષ્ફળ: %s\n" -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "જોડાયેલ નમુના સંવાદ" +#~ msgid "Opened log file %s\n" +#~ msgstr "પ્રવેશ ફાઈલ %s ખૂલેલી છે\n" -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "બટનના દેખાવની ચકાસણી %d" +#~ msgid "Window manager: " +#~ msgstr "વિન્ડો વ્યવસ્થાપક: " -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "એક વિન્ડોનું ચોકઠુ દોરવા માટે %g મિલિસેકન્ડો" +#~ msgid "Bug in window manager: " +#~ msgstr "વિન્ડો વ્યવસ્થાપકમાં ભૂલ: " -#: ../src/ui/theme-viewer.c:813 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "વપરાશઃ મેટાસીટી-થીમ-દર્શક [થીમનુ નામ]\n" +#~ msgid "Window manager warning: " +#~ msgstr "વિન્ડો વ્યવસ્થાપકની ચેતવણી: " -#: ../src/ui/theme-viewer.c:820 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "થીમ લાવવામાં ભૂલ: %s\n" +#~ msgid "Window manager error: " +#~ msgstr "વિન્ડો વ્યવસ્થાપકની ભૂલ: " -#: ../src/ui/theme-viewer.c:826 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "લવાયેલ થીમ \"%s\" %g સેકન્ડોમાં\n" +#~ msgid "" +#~ "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " +#~ "window as specified in the ICCCM.\n" +#~ msgstr "" +#~ "ICCCM માં સ્પષ્ટ કરેલ WM_CLIENT_LEADER વિન્ડોની %s જગ્યાએ વિન્ડોએ તેની જાતે જ " +#~ "SM_CLIENT_ID ગોઠવ્યું.\n" + +#~ msgid "" +#~ "Window %s sets an MWM hint indicating it isn't resizable, but sets min " +#~ "size %d x %d and max size %d x %d; this doesn't make much sense.\n" +#~ msgstr "" +#~ "વિન્ડો %s એ MWM સંકેત ગોઠવ્યો કે જે તેનું માપ બદલી શકાતુ નથી એમ સૂચવે છે, પરંતુ ન્યૂનત્તમ " +#~ "માપ %d x %d અને મહત્તમ માપ %d x %d ગોઠવાયેલુ છે; તેનો કોઈ ખાસ અર્થ નીકળતો નથી.\n" + +#~ msgid "Application set a bogus _NET_WM_PID %lu\n" +#~ msgstr "કાર્યક્રમ એ ખોટું _NET_WM_PID %lu સુયોજિત કર્યું છે\n" -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "સામાન્ય શીર્ષક ફોન્ટ" +#~ msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +#~ msgstr "અયોગ્ય WM_TRANSIENT_FOR વિન્ડો 0x%lx એ %s માટે સ્પષ્ટ થયેલ છે.\n" -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "નાના શીર્ષક ફોન્ટ" +#~ msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" +#~ msgstr "WM_TRANSIENT_FOR વિન્ડો 0x%lx એ %s માટે લુપ બનાવશે.\n" -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "મોટા શીર્ષક ફોન્ટ" +#~ msgid "" +#~ "Window 0x%lx has property %s\n" +#~ "that was expected to have type %s format %d\n" +#~ "and actually has type %s format %d n_items %d.\n" +#~ "This is most likely an application bug, not a window manager bug.\n" +#~ "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +#~ msgstr "" +#~ "વિન્ડો 0x%lx પાસે ગુણધર્મ %s છે\n" +#~ "જેના માટે પ્રકાર %s માળખું %d હોવુ જોઈએ\n" +#~ "અને વાસ્તવમાં તેને પ્રકાર %s માળખું %d n_items %d છે.\n" +#~ "આ મોટે ભાગે કાર્યક્રમની ભૂલ હોવી જોઈએ, નહિ કે વિન્ડો વ્યવસ્થાપકની ભૂલ.\n" +#~ "વિન્ડોને શીર્ષક=\"%s\" વર્ગ=\"%s\" નામ=\"%s\"\n" -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "બટનના દેખાવો" +#~ msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +#~ msgstr "ગુણધર્મ %s વિન્ડો 0x%lx પર અયોગ્ય UTF-8 ધરાવે છે\n" -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "બેન્ચમાર્ક" +#~ msgid "" +#~ "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the " +#~ "list\n" +#~ msgstr "ગુણધર્મ %s વિન્ડો 0x%lx પર યાદીમાં %d વસ્તુ પર અયોગ્ય UTF-8 ધરાવે છે\n" -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "વિન્ડોનુ શીર્ષક અંહિ જાય છે" +#~ msgid "Usage: %s\n" +#~ msgstr "વપરાશ: %s\n" -#: ../src/ui/theme-viewer.c:1047 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"ડ્રિયુ %d ચોકઠાંઓ %g ક્લાઈન્ટ બાજુની સેકન્ડો (%g મિલિસેકન્ડો પ્રતિ ચોકઠાએ) અને %g દિવાલ " -"ઘડિયાળના સમયની સેકન્ડો X સર્વર સ્રોતોને સમાવીને (%g મિલિસેકન્ડો પ્રતિ ચોકઠાએ)\n" +#~ msgid "Mi_nimize" +#~ msgstr "ન્યૂનત્તમ કરો (_n)" -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "જગ્યા સમીકરણ ચકાસણી સાચુ મોકલશે પરંતુ ભૂલ સુયોજિત કરશે" +#~ msgid "Ma_ximize" +#~ msgstr "મહત્તમ કરો (_x)" -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "જગ્યા સમીકરણ ચકાસણી બૂલ મોકલશે પરંતુ ભૂલ સુયોજિત કરતું નથી" +#~ msgid "Unma_ximize" +#~ msgstr "મહત્તમમાંથી પાછુ લાવો (_x)" -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "ભૂલ થવાની સંભાવના હતી પરંતુ કંઈ અપાયુ નથી" +#~ msgid "Roll _Up" +#~ msgstr "વીંટી લો (_U)" -#: ../src/ui/theme-viewer.c:1274 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "ભૂલ %d થવાની સંભાવના હતી પરંતુ %d અપાયુ" +#~ msgid "_Unroll" +#~ msgstr "ખોલી કાઢો (_U)" -#: ../src/ui/theme-viewer.c:1280 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "ભૂલ થવાની સંભાવના હતી પરંતુ એક મોકલાયુ હતું: %s" +#~ msgid "_Move" +#~ msgstr "ખસેડો (_M)" -#: ../src/ui/theme-viewer.c:1284 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "x કિંમત %d હતી, %d ની ઈચ્છા હતી" +#~ msgid "_Resize" +#~ msgstr "માપ બદલો (_R)" -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "y કિંમત %d હતી, %d ની ઈચ્છા હતી" +#~ msgid "Move Titlebar On_screen" +#~ msgstr "શીર્ષકપટ્ટી સ્ક્રીન પર ખસેડો (_s)" -#: ../src/ui/theme-viewer.c:1352 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "%d યામાક્ષ સમીકરણ %g સેકન્ડોમાં પદચ્છેદ થયુ (સરેરાશ %g સેકન્ડો)\n" +#~ msgid "Always on _Top" +#~ msgstr "હંમેશા ટોચ પર (_T)" + +#~ msgid "_Always on Visible Workspace" +#~ msgstr "હંમેશા દ્રશ્ય કામ કરવાની જગ્યા પર (_A)" + +#~ msgid "_Only on This Workspace" +#~ msgstr "માત્ર આ કામ કરવાની જગ્યા પર (_O)" + +#~ msgid "Move to Workspace _Left" +#~ msgstr "ડાબી કામ કરવાની જગ્યામાં ખસો (_L)" + +#~ msgid "Move to Workspace R_ight" +#~ msgstr "જમણી કામ કરવાની જગ્યામાં ખસો (_i)" + +#~ msgid "Move to Workspace _Up" +#~ msgstr "ઉપરની કામ કરવાની જગ્યામાં ખસો (_U)" + +#~ msgid "Move to Workspace _Down" +#~ msgstr "ઉપરની કામ કરવાની જગ્યામાં ખસો (_D)" + +#~ msgid "_Close" +#~ msgstr "બંધ કરો (_C)" + +#~ msgid "Workspace %d%n" +#~ msgstr "કામ કરવાની જગ્યા %d%n" + +#~ msgid "Workspace 1_0" +#~ msgstr "કામ કરવાની જગ્યા ૧_૦" + +#~ msgid "Workspace %s%d" +#~ msgstr "કામ કરવાની જગ્યા %s%d" + +#~ msgid "Move to Another _Workspace" +#~ msgstr "બીજી કામ કરવાની જગ્યામાં ખસેડો" + +#~ msgid "Shift" +#~ msgstr "Shift" + +#~ msgid "Ctrl" +#~ msgstr "Ctrl" + +#~ msgid "Alt" +#~ msgstr "Alt" + +#~ msgid "Meta" +#~ msgstr "Meta" + +#~ msgid "Super" +#~ msgstr "Super" + +#~ msgid "Hyper" +#~ msgstr "Hyper" + +#~ msgid "Mod2" +#~ msgstr "Mod2" + +#~ msgid "Mod3" +#~ msgstr "Mod3" + +#~ msgid "Mod4" +#~ msgstr "Mod4" + +#~ msgid "Mod5" +#~ msgstr "Mod5" + +#~ msgid "_Windows" +#~ msgstr "વિન્ડો (_W)" + +#~ msgid "_Dialog" +#~ msgstr "સંવાદ (_D)" + +#~ msgid "_Modal dialog" +#~ msgstr "નમુના સંવાદ (_M)" + +#~ msgid "_Utility" +#~ msgstr "ઉપયોગિતા (_U)" + +#~ msgid "_Splashscreen" +#~ msgstr "ઝબૂક સ્ક્રીન (_S)" + +#~ msgid "_Top dock" +#~ msgstr "ઉપરનો ડોક (_T)" + +#~ msgid "_Bottom dock" +#~ msgstr "નીચલો ડોક (_B)" + +#~ msgid "_Left dock" +#~ msgstr "ડાબુ ડોક (_L)" + +#~ msgid "_Right dock" +#~ msgstr "જમણું ડોક (_R)" + +#~ msgid "_All docks" +#~ msgstr "બધા ડોક (_A)" + +#~ msgid "Des_ktop" +#~ msgstr "ડેસ્કટોપ (_k)" + +#~ msgid "Open another one of these windows" +#~ msgstr "આ બધી વિન્ડોમાંથી બીજી વિન્ડો ખોલો" + +#~ msgid "This is a demo button with an 'open' icon" +#~ msgstr "આ ડેમો બટન 'ખોલો' ચિહ્ન સાથે છે" + +#~ msgid "This is a demo button with a 'quit' icon" +#~ msgstr "આ ડેમો બટન 'બહાર નીકળો' ચિહ્ન સાથે છે" + +#~ msgid "This is a sample message in a sample dialog" +#~ msgstr "આ નમબના સંવાદમાં સરળ સંદેશો છે" + +#~ msgid "Fake menu item %d\n" +#~ msgstr "ખોટી મેનુ વસ્તુ %d\n" + +#~ msgid "Border-only window" +#~ msgstr "વિન્ડો માટે માત્ર કિનારી" + +#~ msgid "Bar" +#~ msgstr "પટ્ટી" + +#~ msgid "Normal Application Window" +#~ msgstr "કાર્યક્રમની સામાન્ય વિન્ડો" + +#~ msgid "Dialog Box" +#~ msgstr "સંવાદ પેટી" + +#~ msgid "Modal Dialog Box" +#~ msgstr "નમુના સંવાદ પેટી" + +#~ msgid "Utility Palette" +#~ msgstr "ઉપયોગિતા પેલેટ" + +#~ msgid "Torn-off Menu" +#~ msgstr "કાઢી નાખેલ મેનુ" + +#~ msgid "Border" +#~ msgstr "કિનારી" + +#~ msgid "Attached Modal Dialog" +#~ msgstr "જોડાયેલ નમુના સંવાદ" + +#~ msgid "Button layout test %d" +#~ msgstr "બટનના દેખાવની ચકાસણી %d" + +#~ msgid "%g milliseconds to draw one window frame" +#~ msgstr "એક વિન્ડોનું ચોકઠુ દોરવા માટે %g મિલિસેકન્ડો" + +#~ msgid "Usage: metacity-theme-viewer [THEMENAME]\n" +#~ msgstr "વપરાશઃ મેટાસીટી-થીમ-દર્શક [થીમનુ નામ]\n" + +#~ msgid "Error loading theme: %s\n" +#~ msgstr "થીમ લાવવામાં ભૂલ: %s\n" + +#~ msgid "Loaded theme \"%s\" in %g seconds\n" +#~ msgstr "લવાયેલ થીમ \"%s\" %g સેકન્ડોમાં\n" + +#~ msgid "Normal Title Font" +#~ msgstr "સામાન્ય શીર્ષક ફોન્ટ" + +#~ msgid "Small Title Font" +#~ msgstr "નાના શીર્ષક ફોન્ટ" + +#~ msgid "Large Title Font" +#~ msgstr "મોટા શીર્ષક ફોન્ટ" + +#~ msgid "Button Layouts" +#~ msgstr "બટનના દેખાવો" + +#~ msgid "Benchmark" +#~ msgstr "બેન્ચમાર્ક" + +#~ msgid "Window Title Goes Here" +#~ msgstr "વિન્ડોનુ શીર્ષક અંહિ જાય છે" + +#~ msgid "" +#~ "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and " +#~ "%g seconds wall clock time including X server resources (%g milliseconds " +#~ "per frame)\n" +#~ msgstr "" +#~ "ડ્રિયુ %d ચોકઠાંઓ %g ક્લાઈન્ટ બાજુની સેકન્ડો (%g મિલિસેકન્ડો પ્રતિ ચોકઠાએ) અને %g " +#~ "દિવાલ ઘડિયાળના સમયની સેકન્ડો X સર્વર સ્રોતોને સમાવીને (%g મિલિસેકન્ડો પ્રતિ " +#~ "ચોકઠાએ)\n" + +#~ msgid "position expression test returned TRUE but set error" +#~ msgstr "જગ્યા સમીકરણ ચકાસણી સાચુ મોકલશે પરંતુ ભૂલ સુયોજિત કરશે" + +#~ msgid "position expression test returned FALSE but didn't set error" +#~ msgstr "જગ્યા સમીકરણ ચકાસણી બૂલ મોકલશે પરંતુ ભૂલ સુયોજિત કરતું નથી" + +#~ msgid "Error was expected but none given" +#~ msgstr "ભૂલ થવાની સંભાવના હતી પરંતુ કંઈ અપાયુ નથી" + +#~ msgid "Error %d was expected but %d given" +#~ msgstr "ભૂલ %d થવાની સંભાવના હતી પરંતુ %d અપાયુ" + +#~ msgid "Error not expected but one was returned: %s" +#~ msgstr "ભૂલ થવાની સંભાવના હતી પરંતુ એક મોકલાયુ હતું: %s" + +#~ msgid "x value was %d, %d was expected" +#~ msgstr "x કિંમત %d હતી, %d ની ઈચ્છા હતી" + +#~ msgid "y value was %d, %d was expected" +#~ msgstr "y કિંમત %d હતી, %d ની ઈચ્છા હતી" + +#~ msgid "" +#~ "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" +#~ msgstr "%d યામાક્ષ સમીકરણ %g સેકન્ડોમાં પદચ્છેદ થયુ (સરેરાશ %g સેકન્ડો)\n" + +#, fuzzy +#~| msgid "Take a screenshot" +#~ msgid "Screenshots" +#~ msgstr "સ્ક્રીનશોટ" + +#~ msgid "Live Hidden Windows" +#~ msgstr "છુપાયેલ વિન્ડોને જીવંત કરો" #~ msgid "" #~ "There was an error running <tt>%s</tt>:\n" @@ -1580,27 +1696,6 @@ msgstr "%d યામાક્ષ સમીકરણ %g સેકન્ડોમ #~ msgid "Error setting no tab popup status: %s\n" #~ msgstr "કમ્પોઝીટર પરિસ્થિતિ સુયોજીત કરવામાં ભૂલ: %s\n" -#~ msgid "Switch to workspace 1" -#~ msgstr "કામ કરવાની જગ્યા ૧ માં જાઓ" - -#~ msgid "Switch to workspace 2" -#~ msgstr "કામ કરવાની જગ્યા ૨ માં જાઓ" - -#~ msgid "Switch to workspace 3" -#~ msgstr "કામ કરવાની જગ્યા ૩ માં જાઓ" - -#~ msgid "Switch to workspace 4" -#~ msgstr "કામ કરવાની જગ્યા ૪ માં જાઓ" - -#~ msgid "Switch to workspace 5" -#~ msgstr "કામ કરવાની જગ્યા ૫ માં જાઓ" - -#~ msgid "Switch to workspace 6" -#~ msgstr "કામ કરવાની જગ્યા ૬ માં જાઓ" - -#~ msgid "Switch to workspace 7" -#~ msgstr "કામ કરવાની જગ્યા ૭ માં જાઓ" - #~ msgid "Switch to workspace 8" #~ msgstr "કામ કરવાની જગ્યા ૮ માં જાઓ" @@ -1647,9 +1742,6 @@ msgstr "%d યામાક્ષ સમીકરણ %g સેકન્ડોમ #~ msgid "Move backward between panels and the desktop, using a popup window" #~ msgstr "પેનલો અને ડેસ્કટોપ વચ્ચે પાછળ ખસો, પોપઅપ વિન્ડોની મદદથી" -#~ msgid "Move between windows of an application immediately" -#~ msgstr "કાર્યક્રમની વિન્ડો વચ્ચે તુરંત જ ખસેડો" - #~ msgid "Move backward between windows of an application immediately" #~ msgstr "કાર્યક્રમની વિન્ડો વચ્ચે તુરંત જ પાછળ ખસો" @@ -1665,12 +1757,6 @@ msgstr "%d યામાક્ષ સમીકરણ %g સેકન્ડોમ #~ msgid "Move backward between panels and the desktop immediately" #~ msgstr "તરત જ પેનલ તથા ડેસ્કટોપ વચ્ચે પાછા ફરો" -#~ msgid "Hide all normal windows and set focus to the desktop" -#~ msgstr "બધી સામાન્ય વિન્ડો છુપાવો અને ડેસ્કટોપને ફોકસ સુયોજીત કરો" - -#~ msgid "Show the panel's main menu" -#~ msgstr "પેનલનું મુખ્ય મેનુ બતાવો" - #~ msgid "Show the panel's \"Run Application\" dialog box" #~ msgstr "પેનલનો \"કાર્યક્રમ ચલાવો\" સંવાદ બોક્સ બતાવો" @@ -1686,54 +1772,12 @@ msgstr "%d યામાક્ષ સમીકરણ %g સેકન્ડોમ #~ msgid "Run a terminal" #~ msgstr "ટર્મિનલમાં ચલાવો" -#~ msgid "Activate the window menu" -#~ msgstr "વિન્ડો મેનુ સક્રિય કરો" - -#~ msgid "Toggle fullscreen mode" -#~ msgstr "આખી સ્ક્રીન કરવાની સ્થિતિમાં ફેરબદલી" - -#~ msgid "Toggle maximization state" -#~ msgstr "મહત્તમ કરવાની સ્થિતિમાં ફેરબદલી" - #~ msgid "Toggle whether a window will always be visible over other windows" #~ msgstr "શું વિન્ડો હંમેશા અન્ય વિન્ડો ઉપર દેખાતી રહેશે તે બદલો" -#~ msgid "Maximize window" -#~ msgstr "વિન્ડોને મહત્તમ સ્થિતિમાં લાવો" - -#~ msgid "Restore window" -#~ msgstr "વિન્ડો પુનઃસંગ્રહિત કરો" - -#~ msgid "Toggle shaded state" -#~ msgstr "છાયાંકિત કરવાની સ્થિતિમાં ફેરબદલી" - #~ msgid "Minimize window" #~ msgstr "વિન્ડોને ન્યૂનત્તમ સ્થિતિમાં લાવો" -#~ msgid "Close window" -#~ msgstr "વિન્ડો બંધ કરો" - -#~ msgid "Move window" -#~ msgstr "વિન્ડોને ખસાડો" - -#~ msgid "Resize window" -#~ msgstr "વિન્ડોનુ માપ બદલો" - -#~ msgid "Toggle whether window is on all workspaces or just one" -#~ msgstr "શું વિન્ડો એ બધી કામ કરવાની જગ્યાઓ ઉપર છે કે ખાલી એક પર છે તે બદલો" - -#~ msgid "Move window to workspace 1" -#~ msgstr "વિન્ડોને કામ કરવાની જગ્યા ૧ માં લઈ જાઓ" - -#~ msgid "Move window to workspace 2" -#~ msgstr "વિન્ડોને કામ કરવાની જગ્યા ૨ માં લઈ જાઓ" - -#~ msgid "Move window to workspace 3" -#~ msgstr "વિન્ડોને કામ કરવાની જગ્યા ૩ માં લઈ જાઓ" - -#~ msgid "Move window to workspace 4" -#~ msgstr "વિન્ડોને કામ કરવાની જગ્યા ૪ માં લઈ જાઓ" - #~ msgid "Move window to workspace 5" #~ msgstr "વિન્ડોને કામ કરવાની જગ્યા ૫ માં લઈ જાઓ" @@ -1758,33 +1802,6 @@ msgstr "%d યામાક્ષ સમીકરણ %g સેકન્ડોમ #~ msgid "Move window to workspace 12" #~ msgstr "વિન્ડોને કામ કરવાની જગ્યા ૧૨ માં લઈ જાઓ" -#~ msgid "Move window one workspace to the left" -#~ msgstr "વિન્ડોને ડાબી બાજુની કામ કરવાની જગ્યામાં લાવો" - -#~ msgid "Move window one workspace to the right" -#~ msgstr "વિન્ડોને જમણી બાજુની કામ કરવાની જગ્યામાં લાવો" - -#~ msgid "Move window one workspace up" -#~ msgstr "વિન્ડોને ઉપરની બાજુની કામ કરવાની જગ્યામાં લાવો" - -#~ msgid "Move window one workspace down" -#~ msgstr "વિન્ડોને નીચેની કામ કરવાની જગ્ચામાં લાવો" - -#~ msgid "Raise window if it's covered by another window, otherwise lower it" -#~ msgstr "જો વિન્ડો અન્ય વિન્ડો દ્વારા આવરાયેલ હોય, અથવા તેની નીચે હોય તો તેને વધારો" - -#~ msgid "Raise window above other windows" -#~ msgstr "વિન્ડોને બીજી બધી વિન્ડોની ઉપર લાવો" - -#~ msgid "Lower window below other windows" -#~ msgstr "બીજી વિન્ડો નીચેની વિન્ડોને નાની કરો" - -#~ msgid "Maximize window vertically" -#~ msgstr "વિન્ડોને ઉભી દિશામાં મોટી કરો" - -#~ msgid "Maximize window horizontally" -#~ msgstr "વિન્ડોને આડી દિશામાં મોટી કરો" - #~ msgid "Move window to north-west (top left) corner" #~ msgstr "વિન્ડોને ઉત્તર-પશ્ચિમ (ટોચે ડાબે) ખૂણે ખસેડો" @@ -1812,9 +1829,6 @@ msgstr "%d યામાક્ષ સમીકરણ %g સેકન્ડોમ #~ msgid "Move window to center of screen" #~ msgstr "વિન્ડોને સ્ક્રીનના કેન્દ્રમાં ખસેડો" -#~ msgid "Clutter Plugins" -#~ msgstr "ક્લટર પ્લગઇન" - #~ msgid "Close Window" #~ msgstr "વિન્ડો બંધ કરો" diff --git a/po/ha.po b/po/ha.po index 8c0990961..b14a35569 100644 --- a/po/ha.po +++ b/po/ha.po @@ -7,6 +7,7 @@ msgstr "" "PO-Revision-Date: 2006-05-11 13:30+0100\n" "Last-Translator: saudat mohammed <saudat@wazobialinux>\n" "Language-Team: hausa\n" +"Language: ha\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" diff --git a/po/he.po b/po/he.po index 4907fe8e1..716be5982 100644 --- a/po/he.po +++ b/po/he.po @@ -4,1433 +4,1546 @@ # Copyright (C) 2005 THE PACKAGE'S COPYRIGHT HOLDER # Gil 'Dolfin' Osher <dolfin@rpg.org.il>, 2002,2003. # Yuval Tanny, 2005. +# Yosef Or Boczko <yoseforb@gnome.org>, 2013, 2014. # msgid "" msgstr "" "Project-Id-Version: metacity.HEAD.he\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-03-24 19:08+0200\n" -"PO-Revision-Date: 2012-03-24 19:08+0200\n" -"Last-Translator: Yaron Shahrabani <sh.yaron@gmail.com>\n" -"Language-Team: Hebrew <he@li.org>\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=mutter&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-11-26 17:12+0200\n" +"PO-Revision-Date: 2017-11-26 17:14+0200\n" +"Last-Translator: Yosef Or Boczko <yoseforb@gmail.com>\n" +"Language-Team: עברית <>\n" "Language: he\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: KBabel 1.10.2\n" +"X-Generator: Gtranslator 2.91.6\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ../src/50-muffin-windows.xml.in.h:1 +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "ניווט" + +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "העברת החלון למרחב עבודה 1" + +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "העברת החלון למרחב עבודה 2" + +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "העברה החלון למרחב עבודה 3" + +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "העברה החלון למרחב עבודה 4" + +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "העברת החלון למרחב העבודה האחרון" + +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace to the left" +msgstr "העברת החלון למרחב העבודה שמשמאל" + +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace to the right" +msgstr "העברת החלון למרחב העבודה שמימין" + +#: data/50-mutter-navigation.xml:30 +msgid "Move window one workspace up" +msgstr "העברת החלון למרחב העבודה שמלמעלה" + +#: data/50-mutter-navigation.xml:33 +msgid "Move window one workspace down" +msgstr "העברת החלון למרחב העבודה שמלמטה" + +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor to the left" +msgstr "העברת החלון לצג שמשמאל" + +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor to the right" +msgstr "העברת החלון לצג שמימין" + +#: data/50-mutter-navigation.xml:42 +msgid "Move window one monitor up" +msgstr "העברת החלון לצג שמלמעלה" + +#: data/50-mutter-navigation.xml:45 +msgid "Move window one monitor down" +msgstr "העברת החלון לצג שמלמטה" + +#: data/50-mutter-navigation.xml:49 +msgid "Switch applications" +msgstr "החלפה בין יישומים" + +#: data/50-mutter-navigation.xml:54 +msgid "Switch to previous application" +msgstr "החלפה ליישום הקודם" + +#: data/50-mutter-navigation.xml:58 +msgid "Switch windows" +msgstr "החלפת חלונות" + +#: data/50-mutter-navigation.xml:63 +msgid "Switch to previous window" +msgstr "החלפה לחלון הקודם" + +#: data/50-mutter-navigation.xml:67 +msgid "Switch windows of an application" +msgstr "החלפה בין חלונות של יישום" + +#: data/50-mutter-navigation.xml:72 +msgid "Switch to previous window of an application" +msgstr "החלפה לחלון הקודם של היישום" + +#: data/50-mutter-navigation.xml:76 +msgid "Switch system controls" +msgstr "החלפה בין פקדי המערכת" + +#: data/50-mutter-navigation.xml:81 +msgid "Switch to previous system control" +msgstr "החלפה לפקד המערכת הקודם" + +#: data/50-mutter-navigation.xml:85 +msgid "Switch windows directly" +msgstr "החלפת החלונות באופן ישיר" + +#: data/50-mutter-navigation.xml:90 +msgid "Switch directly to previous window" +msgstr "החלפה לחלון הקודם באופן ישיר" + +#: data/50-mutter-navigation.xml:94 +msgid "Switch windows of an app directly" +msgstr "החלפת חלונות של יישום באופן ישיר" + +#: data/50-mutter-navigation.xml:99 +msgid "Switch directly to previous window of an app" +msgstr "החלפה לחלון הקודם של היישום באופן ישיר" + +#: data/50-mutter-navigation.xml:103 +msgid "Switch system controls directly" +msgstr "החלפת פקדי המערכת באופן ישיר" + +#: data/50-mutter-navigation.xml:108 +msgid "Switch directly to previous system control" +msgstr "החלפה לפקד המערכת הקודם באופן ישיר" + +#: data/50-mutter-navigation.xml:111 +msgid "Hide all normal windows" +msgstr "הסתרת כל החלונות הרגילים" + +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 1" +msgstr "מעבר למרחב עבודה 1" + +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 2" +msgstr "מעבר למרחב עבודה 2" + +#: data/50-mutter-navigation.xml:120 +msgid "Switch to workspace 3" +msgstr "מעבר למרחב עבודה 3" + +#: data/50-mutter-navigation.xml:123 +msgid "Switch to workspace 4" +msgstr "מעבר למרחב עבודה 4" + +#: data/50-mutter-navigation.xml:126 +msgid "Switch to last workspace" +msgstr "מעבר למרחב העבודה האחרון" + +#: data/50-mutter-navigation.xml:129 +msgid "Move to workspace left" +msgstr "העברה למרחב העבודה לשמאל" + +#: data/50-mutter-navigation.xml:132 +msgid "Move to workspace right" +msgstr "העברה למרחב העבודה לימין" + +#: data/50-mutter-navigation.xml:135 +msgid "Move to workspace above" +msgstr "העברה למרחב העבודה שמלמעלה" + +#: data/50-mutter-navigation.xml:138 +msgid "Move to workspace below" +msgstr "העברה למרחב העבודה שמלמטה" + +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "מערכת" + +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "הצגת החלונית להרצת פקודה" + +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "הצגת סקירת הפעילויות" + +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "שחזור צירופי מקשים" + +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "חלונות" + +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "הפעלת תפריט החלון" + +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "הפעלה/כיבוי מצב מסך מלא" + +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "הפעלה/כיבוי מצב הגדלה" + +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "הגדלת חלון" + +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "שחזור חלון" + +#: data/50-mutter-windows.xml:18 +msgid "Toggle shaded state" +msgstr "החלפת מצב ההצללה" + +#: data/50-mutter-windows.xml:20 +msgid "Close window" +msgstr "סגירת חלון" + +#: data/50-mutter-windows.xml:22 +msgid "Hide window" +msgstr "הסתרת החלון" + +#: data/50-mutter-windows.xml:24 +msgid "Move window" +msgstr "הזזת חלון" + +#: data/50-mutter-windows.xml:26 +msgid "Resize window" +msgstr "שינוי גודל חלון" + +#: data/50-mutter-windows.xml:29 +msgid "Toggle window on all workspaces or one" +msgstr "החלפת המצב בין האם החלון מופיע במרחב עבודה אחד או בכולם" + +#: data/50-mutter-windows.xml:31 +msgid "Raise window if covered, otherwise lower it" +msgstr "הגבהת החלון אם הוא מכוסה, אחרת יש להנמיכו" + +#: data/50-mutter-windows.xml:33 +msgid "Raise window above other windows" +msgstr "הגבהת החלון מעל לחלונות אחרים" + +#: data/50-mutter-windows.xml:35 +msgid "Lower window below other windows" +msgstr "הנמכת החלון מתחת לחלונות אחרים" + +#: data/50-mutter-windows.xml:37 +msgid "Maximize window vertically" +msgstr "הגדלת החלון אנכית" + +#: data/50-mutter-windows.xml:39 +msgid "Maximize window horizontally" +msgstr "הגדלת החלון אופקית" + +#: data/50-mutter-windows.xml:43 msgid "View split on left" msgstr "פיצול הצפייה משמאל" -#: ../src/50-muffin-windows.xml.in.h:2 +#: data/50-mutter-windows.xml:47 msgid "View split on right" msgstr "פיצול הצפייה מימין" -#: ../src/50-muffin-windows.xml.in.h:3 -msgid "Windows" -msgstr "חלונות" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format -msgid "Another compositing manager is already running on screen %i on display \"%s\"." -msgstr "מנהל תצוגת חלונות אחר כבר פועל במסך %i בתצוגה \"%s\"." +#: data/org.gnome.mutter.gschema.xml.in:7 +msgid "Modifier to use for extended window management operations" +msgstr "Modifier to use for extended window management operations" -#: ../src/core/bell.c:307 -msgid "Bell event" -msgstr "אירוע פעמון" +#: data/org.gnome.mutter.gschema.xml.in:8 +msgid "" +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." +msgstr "" +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Unknown window information request: %d" +#: data/org.gnome.mutter.gschema.xml.in:20 +msgid "Attach modal dialogs" +msgstr "Attach modal dialogs" + +#: data/org.gnome.mutter.gschema.xml.in:21 +msgid "" +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." +msgstr "" +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." + +#: data/org.gnome.mutter.gschema.xml.in:30 +msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "Enable edge tiling when dropping windows on screen edges" + +#: data/org.gnome.mutter.gschema.xml.in:31 +msgid "" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." +msgstr "" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." + +#: data/org.gnome.mutter.gschema.xml.in:40 +msgid "Workspaces are managed dynamically" +msgstr "Workspaces are managed dynamically" + +#: data/org.gnome.mutter.gschema.xml.in:41 +msgid "" +"Determines whether workspaces are managed dynamically or whether there’s a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." +msgstr "" +"Determines whether workspaces are managed dynamically or whether there’s a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." + +#: data/org.gnome.mutter.gschema.xml.in:50 +msgid "Workspaces only on primary" +msgstr "Workspaces only on primary" + +#: data/org.gnome.mutter.gschema.xml.in:51 +msgid "" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." +msgstr "" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." + +#: data/org.gnome.mutter.gschema.xml.in:59 +msgid "No tab popup" +msgstr "No tab popup" + +#: data/org.gnome.mutter.gschema.xml.in:60 +msgid "" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." +msgstr "" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." + +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Delay focus changes until the pointer stops moving" + +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." + +#: data/org.gnome.mutter.gschema.xml.in:79 +msgid "Draggable border width" +msgstr "Draggable border width" + +#: data/org.gnome.mutter.gschema.xml.in:80 +msgid "" +"The amount of total draggable borders. If the theme’s visible borders are " +"not enough, invisible borders will be added to meet this value." +msgstr "" +"The amount of total draggable borders. If the theme’s visible borders are " +"not enough, invisible borders will be added to meet this value." + +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "Auto maximize nearly monitor sized windows" + +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." + +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Place new windows in the center" + +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." + +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Enable experimental features" + +#: data/org.gnome.mutter.gschema.xml.in:108 +msgid "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “remote-desktop” — " +"enables remote desktop support. To support remote desktop with screen " +"sharing, “screen-cast” must also be enabled. • “screen-cast” — enables " +"screen cast support." +msgstr "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “remote-desktop” — " +"enables remote desktop support. To support remote desktop with screen " +"sharing, “screen-cast” must also be enabled. • “screen-cast” — enables " +"screen cast support." + +#: data/org.gnome.mutter.gschema.xml.in:145 +msgid "Select window from tab popup" +msgstr "Select window from tab popup" + +#: data/org.gnome.mutter.gschema.xml.in:150 +msgid "Cancel tab popup" +msgstr "Cancel tab popup" + +#: data/org.gnome.mutter.gschema.xml.in:155 +msgid "Switch monitor configurations" +msgstr "החלפה בין תצורות צגים" + +#: data/org.gnome.mutter.gschema.xml.in:160 +msgid "Rotates the built-in monitor configuration" +msgstr "Rotates the built-in monitor configuration" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "מעבר ל־VT ‏1" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "מעבר ל־VT ‏2" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "מעבר ל־VT ‏3" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "מעבר ל־VT ‏4" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "מעבר ל־VT ‏5" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "מעבר ל־VT ‏6" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "מעבר ל־VT ‏7" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "מעבר ל־VT ‏8" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "מעבר ל־VT ‏9" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "מעבר ל־VT ‏10" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "מעבר ל־VT ‏11" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "מעבר ל־VT ‏12" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "לאפשר מחדש צירופי מקשים" -#: ../src/core/delete.c:111 +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. +#. +#: src/backends/meta-input-settings.c:2260 #, c-format -msgid "<tt>%s</tt> is not responding." -msgstr " <tt>%s</tt> אינו מגיב" +msgid "Mode Switch (Group %d)" +msgstr "מצב העברה (קבוצה %d)" -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "היישום אינו מגיב." +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2283 +msgid "Switch monitor" +msgstr "החלפה בין צגים" -#: ../src/core/delete.c:119 -msgid "You may choose to wait a short while for it to continue or force the application to quit entirely." -msgstr "באפשרותך להמתין זמן קצר ולתת ליישום להמשיך או להכריח את היישום להסתיים." +#: src/backends/meta-input-settings.c:2285 +msgid "Show on-screen help" +msgstr "הצגת עזרה על המסך" -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "ה_מתנה" +#: src/backends/meta-monitor-manager.c:900 +msgid "Built-in display" +msgstr "תצוגה מובנית" -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "_אילוץ סגירה" +#: src/backends/meta-monitor-manager.c:923 +msgid "Unknown" +msgstr "לא ידוע" -#: ../src/core/display.c:387 +#: src/backends/meta-monitor-manager.c:925 +msgid "Unknown Display" +msgstr "תצוגה לא ידועה" + +#. TRANSLATORS: this is a monitor vendor name, followed by a +#. * size in inches, like 'Dell 15"' +#. +#: src/backends/meta-monitor-manager.c:933 #, c-format -msgid "Missing %s extension required for compositing" -msgstr "Missing %s extension required for compositing" +msgid "%s %s" +msgstr "%s %s" -#: ../src/core/display.c:453 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:479 #, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Failed to open X Window System display '%s'\n" +msgid "" +"Another compositing manager is already running on screen %i on display “%s”." +msgstr "מנהל תצוגת חלונות אחר כבר פועל במסך %i בתצוגה „%s“." + +#: src/core/bell.c:194 +msgid "Bell event" +msgstr "אירוע פעמון" -#: ../src/core/keybindings.c:852 +#: src/core/display.c:608 #, c-format -msgid "Some other program is already using the key %s with modifiers %x as a binding\n" -msgstr "תוכנית אחרת כבר משתמשת במקש %s עם המקש %x כצירוף\n" +msgid "Failed to open X Window System display “%s”\n" +msgstr "Failed to open X Window System display “%s”\n" -#: ../src/core/main.c:206 +#: src/core/main.c:189 msgid "Disable connection to session manager" msgstr "Disable connection to session manager" -#: ../src/core/main.c:212 +#: src/core/main.c:195 msgid "Replace the running window manager" msgstr "Replace the running window manager" -#: ../src/core/main.c:218 +#: src/core/main.c:201 msgid "Specify session management ID" msgstr "Specify session management ID" -#: ../src/core/main.c:223 +#: src/core/main.c:206 msgid "X Display to use" msgstr "X Display to use" -#: ../src/core/main.c:229 +#: src/core/main.c:212 msgid "Initialize session from savefile" msgstr "Initialize session from savefile" -#: ../src/core/main.c:235 +#: src/core/main.c:218 msgid "Make X calls synchronous" msgstr "Make X calls synchronous" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Failed to scan themes directory: %s\n" +#: src/core/main.c:225 +msgid "Run as a wayland compositor" +msgstr "Run as a wayland compositor" + +#: src/core/main.c:231 +msgid "Run as a nested compositor" +msgstr "Run as a nested compositor" -#: ../src/core/main.c:520 +#: src/core/main.c:239 +msgid "Run as a full display server, rather than nested" +msgstr "Run as a full display server, rather than nested" + +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:147 #, c-format -msgid "Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "Could not find a theme! Be sure %s exists and contains the usual themes.\n" +msgid "“%s” is not responding." +msgstr "„%s“ אינו מגיב." + +#: src/core/meta-close-dialog-default.c:149 +msgid "Application is not responding." +msgstr "היישום אינו מגיב." + +#: src/core/meta-close-dialog-default.c:154 +msgid "" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." +msgstr "" +"באפשרותך להמתין זמן קצר ולתת ליישום להמשיך או להכריח את היישום להסתיים." + +#: src/core/meta-close-dialog-default.c:161 +msgid "_Force Quit" +msgstr "_אילוץ סגירה" -#: ../src/core/muffin.c:40 +#: src/core/meta-close-dialog-default.c:161 +msgid "_Wait" +msgstr "ה_מתנה" + +#: src/core/mutter.c:39 #, c-format msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" "This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" msgstr "" -"muffin %s\n" +"mutter %s\n" "כל הזכויות שמורות (C)‏ %d-2001‏ Havoc Pennington,‏ Red Hat, Inc‎.‎, ואחרים\n" "זוהי תכנה חופשית; יש לעיין במקור כדי לקבל מידע אודות תנאי ההעתקה.\n" "לא קיימת שום אחריות; אפילו לא עבור סחר או התאמה לצרכים מסוימים.\n" -#: ../src/core/muffin.c:54 +#: src/core/mutter.c:53 msgid "Print version" msgstr "Print version" -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "Comma-separated list of compositor plugins" - -#: ../src/core/prefs.c:1077 -msgid "Workarounds for broken applications disabled. Some applications may not behave properly.\n" -msgstr "Workarounds for broken applications disabled. Some applications may not behave properly.\n" +#: src/core/mutter.c:59 +msgid "Mutter plugin to use" +msgstr "תוסף ה־mutter לשימוש" -#: ../src/core/prefs.c:1152 +#: src/core/prefs.c:1997 #, c-format -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "Could not parse font description \"%s\" from GSettings key %s\n" +msgid "Workspace %d" +msgstr "מרחב עבודה %d" -#: ../src/core/prefs.c:1218 +#: src/core/screen.c:583 #, c-format -msgid "\"%s\" found in configuration database is not a valid value for mouse button modifier\n" -msgstr "\"%s\" found in configuration database is not a valid value for mouse button modifier\n" +msgid "" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." +msgstr "" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." -#: ../src/core/prefs.c:1739 +#: src/core/screen.c:668 #, c-format -msgid "\"%s\" found in configuration database is not a valid value for keybinding \"%s\"\n" -msgstr "\"%s\" found in configuration database is not a valid value for keybinding \"%s\"\n" +msgid "Screen %d on display “%s” is invalid\n" +msgstr "Screen %d on display “%s” is invalid\n" -#: ../src/core/prefs.c:1836 -#, c-format -msgid "Workspace %d" -msgstr "סביבת עבודה %d" +#: src/core/util.c:120 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter הודר ללא תמיכה במצב פירוט\n" -#: ../src/core/screen.c:730 +#: src/wayland/meta-wayland-tablet-pad.c:563 #, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "Screen %d on display '%s' is invalid\n" +msgid "Mode Switch: Mode %d" +msgstr "מצב העברה: מצב %d" -#: ../src/core/screen.c:746 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager; try using the --replace option to replace the current window manager.\n" -msgstr "Screen %d on display \"%s\" already has a window manager; try using the --replace option to replace the current window manager.\n" +#: src/x11/session.c:1815 +msgid "" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." +msgstr "" +"חלונות אלו אינם תומכים ב„שמירת ההגדרות הנוכחיות”, ויהיה צורך באתחול ידני " +"בכניסה הבאה שלך." -#: ../src/core/screen.c:773 +#: src/x11/window-props.c:559 #, c-format -msgid "Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "Could not acquire window manager selection on screen %d display \"%s\"\n" +msgid "%s (on %s)" +msgstr "%s (מעל %s)" -#: ../src/core/screen.c:828 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "Screen %d on display \"%s\" already has a window manager\n" +#~ msgid "background texture could not be created from file" +#~ msgstr "לא ניתן ליצור מרקם רקע מקובץ" -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "Could not release screen %d on display \"%s\"\n" +#~ msgid "Failed to scan themes directory: %s\n" +#~ msgstr "Failed to scan themes directory: %s\n" -#: ../src/core/session.c:843 -#: ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Could not create directory '%s': %s\n" +#~ msgid "" +#~ "Could not find a theme! Be sure %s exists and contains the usual themes.\n" +#~ msgstr "" +#~ "Could not find a theme! Be sure %s exists and contains the usual themes.\n" -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "Could not open session file '%s' for writing: %s\n" +#~ msgid "Screen %d on display \"%s\" already has a window manager\n" +#~ msgstr "Screen %d on display \"%s\" already has a window manager\n" -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Error writing session file '%s': %s\n" +#~ msgid "%d x %d" +#~ msgstr "%d x %d" -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Error closing session file '%s': %s\n" +#~ msgid "top" +#~ msgstr "top" -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Failed to parse saved session file: %s\n" +#~ msgid "bottom" +#~ msgstr "bottom" -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "התכונה <muffin_session> מופיעה אך כבר יש בידינו את מספר זיהוי ההפעלה" - -#: ../src/core/session.c:1198 -#: ../src/core/session.c:1273 -#: ../src/core/session.c:1305 -#: ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Unknown attribute %s on <%s> element" +#~ msgid "left" +#~ msgstr "left" -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "nested <window> tag" +#~ msgid "right" +#~ msgstr "right" -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "Unknown element %s" +#~ msgid "frame geometry does not specify \"%s\" dimension" +#~ msgstr "frame geometry does not specify \"%s\" dimension" -#: ../src/core/session.c:1809 -msgid "These windows do not support "save current setup" and will have to be restarted manually next time you log in." -msgstr "חלונות אלו אינם תומכים ב"שמירת ההגדרות הנוכחיות", ויהיה צורך באתחול ידני בכניסה הבאה שלך." +#~ msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" +#~ msgstr "frame geometry does not specify dimension \"%s\" for border \"%s\"" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Failed to open debug log: %s\n" +#~ msgid "Button aspect ratio %g is not reasonable" +#~ msgstr "Button aspect ratio %g is not reasonable" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Failed to fdopen() log file %s: %s\n" +#~ msgid "Frame geometry does not specify size of buttons" +#~ msgstr "Frame geometry does not specify size of buttons" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "Opened log file %s\n" +#~ msgid "Gradients should have at least two colors" +#~ msgstr "Gradients should have at least two colors" -#: ../src/core/util.c:146 -#: ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "Muffin הודר ללא תמיכה במצב פירוט\n" +#~ msgid "" +#~ "GTK custom color specification must have color name and fallback in " +#~ "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" +#~ msgstr "" +#~ "GTK custom color specification must have color name and fallback in " +#~ "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "Window manager: " +#~ msgid "" +#~ "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-" +#~ "z0-9-_ are valid" +#~ msgstr "" +#~ "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-" +#~ "z0-9-_ are valid" -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "Bug in window manager: " +#~ msgid "" +#~ "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " +#~ "fit the format" +#~ msgstr "" +#~ "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " +#~ "fit the format" -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "Window manager warning: " +#~ msgid "" +#~ "GTK color specification must have the state in brackets, e.g. gtk:" +#~ "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "GTK color specification must have the state in brackets, e.g. gtk:" +#~ "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "Window manager error: " +#~ msgid "" +#~ "GTK color specification must have a close bracket after the state, e.g. " +#~ "gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "GTK color specification must have a close bracket after the state, e.g. " +#~ "gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -#. first time through -#: ../src/core/window.c:7266 -#, c-format -msgid "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER window as specified in the ICCCM.\n" -msgstr "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER window as specified in the ICCCM.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7931 -#, c-format -msgid "Window %s sets an MWM hint indicating it isn't resizable, but sets min size %d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "Window %s sets an MWM hint indicating it isn't resizable, but sets min size %d x %d and max size %d x %d; this doesn't make much sense.\n" +#~ msgid "Did not understand state \"%s\" in color specification" +#~ msgstr "Did not understand state \"%s\" in color specification" -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "Application set a bogus _NET_WM_PID %lu\n" +#~ msgid "Did not understand color component \"%s\" in color specification" +#~ msgstr "Did not understand color component \"%s\" in color specification" -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (מעל %s)" +#~ msgid "" +#~ "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit " +#~ "the format" +#~ msgstr "" +#~ "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit " +#~ "the format" -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +#~ msgid "Could not parse alpha value \"%s\" in blended color" +#~ msgstr "Could not parse alpha value \"%s\" in blended color" -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" +#~ msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" +#~ msgstr "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +#~ msgid "" +#~ "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the " +#~ "format" +#~ msgstr "" +#~ "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the " +#~ "format" -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "Property %s on window 0x%lx contained invalid UTF-8\n" +#~ msgid "Could not parse shade factor \"%s\" in shaded color" +#~ msgstr "Could not parse shade factor \"%s\" in shaded color" -#: ../src/core/xprops.c:494 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" +#~ msgid "Shade factor \"%s\" in shaded color is negative" +#~ msgstr "Shade factor \"%s\" in shaded color is negative" -#: ../src/muffin.desktop.in.h:1 -#: ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" +#~ msgid "Could not parse color \"%s\"" +#~ msgstr "Could not parse color \"%s\"" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 -msgid "Attach modal dialogs" -msgstr "Attach modal dialogs" +#~ msgid "Coordinate expression contains character '%s' which is not allowed" +#~ msgstr "Coordinate expression contains character '%s' which is not allowed" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 -msgid "Cancel tab popup" -msgstr "Cancel tab popup" +#~ msgid "" +#~ "Coordinate expression contains floating point number '%s' which could not " +#~ "be parsed" +#~ msgstr "" +#~ "Coordinate expression contains floating point number '%s' which could not " +#~ "be parsed" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 -msgid "Determines whether hidden windows (i.e., minimized windows and windows on other workspaces than the current one) should be kept alive." -msgstr "Determines whether hidden windows (i.e., minimized windows and windows on other workspaces than the current one) should be kept alive." +#~ msgid "" +#~ "Coordinate expression contains integer '%s' which could not be parsed" +#~ msgstr "" +#~ "Coordinate expression contains integer '%s' which could not be parsed" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 -msgid "Determines whether the use of popup and highlight frame should be disabled for window cycling." -msgstr "Determines whether the use of popup and highlight frame should be disabled for window cycling." +#~ msgid "" +#~ "Coordinate expression contained unknown operator at the start of this " +#~ "text: \"%s\"" +#~ msgstr "" +#~ "Coordinate expression contained unknown operator at the start of this " +#~ "text: \"%s\"" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -msgid "Determines whether workspace switching should happen for windows on all monitors or only for windows on the primary monitor." -msgstr "Determines whether workspace switching should happen for windows on all monitors or only for windows on the primary monitor." +#~ msgid "Coordinate expression was empty or not understood" +#~ msgstr "Coordinate expression was empty or not understood" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 -msgid "Determines whether workspaces are managed dynamically or whether there's a static number of workspaces (determined by the num-workspaces key in org.cinnamon.desktop.wm.preferences)." -msgstr "Determines whether workspaces are managed dynamically or whether there's a static number of workspaces (determined by the num-workspaces key in org.cinnamon.desktop.wm.preferences)." +#~ msgid "Coordinate expression results in division by zero" +#~ msgstr "Coordinate expression results in division by zero" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 -msgid "Draggable border width" -msgstr "Draggable border width" +#~ msgid "" +#~ "Coordinate expression tries to use mod operator on a floating-point number" +#~ msgstr "" +#~ "Coordinate expression tries to use mod operator on a floating-point number" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 -msgid "Enable edge tiling when dropping windows on screen edges" -msgstr "Enable edge tiling when dropping windows on screen edges" +#~ msgid "" +#~ "Coordinate expression has an operator \"%s\" where an operand was expected" +#~ msgstr "" +#~ "Coordinate expression has an operator \"%s\" where an operand was expected" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 -msgid "If enabled, dropping windows on vertical screen edges maximizes them vertically and resizes them horizontally to cover half of the available area. Dropping windows on the top screen edge maximizes them completely." -msgstr "If enabled, dropping windows on vertical screen edges maximizes them vertically and resizes them horizontally to cover half of the available area. Dropping windows on the top screen edge maximizes them completely." +#~ msgid "Coordinate expression had an operand where an operator was expected" +#~ msgstr "Coordinate expression had an operand where an operator was expected" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 -msgid "Live Hidden Windows" -msgstr "Live Hidden Windows" +#~ msgid "Coordinate expression ended with an operator instead of an operand" +#~ msgstr "Coordinate expression ended with an operator instead of an operand" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 -msgid "Modifier to use for extended window management operations" -msgstr "Modifier to use for extended window management operations" +#~ msgid "" +#~ "Coordinate expression has operator \"%c\" following operator \"%c\" with " +#~ "no operand in between" +#~ msgstr "" +#~ "Coordinate expression has operator \"%c\" following operator \"%c\" with " +#~ "no operand in between" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 -msgid "No tab popup" -msgstr "No tab popup" +#~ msgid "Coordinate expression had unknown variable or constant \"%s\"" +#~ msgstr "Coordinate expression had unknown variable or constant \"%s\"" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 -msgid "Select window from tab popup" -msgstr "Select window from tab popup" +#~ msgid "Coordinate expression parser overflowed its buffer." +#~ msgstr "Coordinate expression parser overflowed its buffer." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 -msgid "The amount of total draggable borders. If the theme's visible borders are not enough, invisible borders will be added to meet this value." -msgstr "The amount of total draggable borders. If the theme's visible borders are not enough, invisible borders will be added to meet this value." +#~ msgid "" +#~ "Coordinate expression had a close parenthesis with no open parenthesis" +#~ msgstr "" +#~ "Coordinate expression had a close parenthesis with no open parenthesis" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 -msgid "This key will initiate the \"overlay\", which is a combination window overview and application launching system. The default is intended to be the \"Windows key\" on PC hardware. It's expected that this binding either the default or set to the empty string." -msgstr "This key will initiate the \"overlay\", which is a combination window overview and application launching system. The default is intended to be the \"Windows key\" on PC hardware. It's expected that this binding either the default or set to the empty string." +#~ msgid "" +#~ "Coordinate expression had an open parenthesis with no close parenthesis" +#~ msgstr "" +#~ "Coordinate expression had an open parenthesis with no close parenthesis" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 -msgid "When true, instead of having independent titlebars, modal dialogs appear attached to the titlebar of the parent window and are moved together with the parent window." -msgstr "When true, instead of having independent titlebars, modal dialogs appear attached to the titlebar of the parent window and are moved together with the parent window." +#~ msgid "Coordinate expression doesn't seem to have any operators or operands" +#~ msgstr "" +#~ "Coordinate expression doesn't seem to have any operators or operands" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:17 -msgid "Workspaces are managed dynamically" -msgstr "Workspaces are managed dynamically" +#~ msgid "Theme contained an expression that resulted in an error: %s\n" +#~ msgstr "Theme contained an expression that resulted in an error: %s\n" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:18 -msgid "Workspaces only on primary" -msgstr "Workspaces only on primary" +#~ msgid "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " +#~ "specified for this frame style" +#~ msgstr "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " +#~ "specified for this frame style" -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "שימוש: %s\n" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "_מזער" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "ה_גדל" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "_שחזר" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "גלול _מעלה" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "גלול _חזרה" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "_הזז" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "_שנה גודל" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "הזז את שורת הכותרת אל ה_מסך" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 -#: ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "תמיד מ_למעלה" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "_הראה בכל סביבות העבודה" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "רק בסביבת עבודה _זו" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "הזז חלון לסביבת העבודה ה_שמאלית" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "הזז חלון לסביבת העבודה ה_ימנית" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "הזז חלון לסביבת העבודה למעלה" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "הזז חלון לסביבת העבודה למטה" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "_סגור" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "סביבת עבודה %d%n" +#~ msgid "" +#~ "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/" +#~ ">" +#~ msgstr "" +#~ "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/" +#~ ">" -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "סביבת עבודה 1_0" +#~ msgid "Failed to load theme \"%s\": %s\n" +#~ msgstr "Failed to load theme \"%s\": %s\n" -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "סביבת עבודה %s%d" +#~ msgid "No <%s> set for theme \"%s\"" +#~ msgstr "No <%s> set for theme \"%s\"" -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "הזז חלון לסביבת עבודה אחרת" +#~ msgid "" +#~ "No frame style set for window type \"%s\" in theme \"%s\", add a <window " +#~ "type=\"%s\" style_set=\"whatever\"/> element" +#~ msgstr "" +#~ "No frame style set for window type \"%s\" in theme \"%s\", add a <window " +#~ "type=\"%s\" style_set=\"whatever\"/> element" -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "מטה" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" +#~ msgid "" +#~ "User-defined constants must begin with a capital letter; \"%s\" does not" +#~ msgstr "" +#~ "User-defined constants must begin with a capital letter; \"%s\" does not" -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" +#~ msgid "Constant \"%s\" has already been defined" +#~ msgstr "Constant \"%s\" has already been defined" -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "top" +#~ msgid "No \"%s\" attribute on element <%s>" +#~ msgstr "No \"%s\" attribute on element <%s>" -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "bottom" +#~ msgid "Line %d character %d: %s" +#~ msgstr "Line %d character %d: %s" -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "left" +#~ msgid "Attribute \"%s\" repeated twice on the same <%s> element" +#~ msgstr "Attribute \"%s\" repeated twice on the same <%s> element" -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "right" +#~ msgid "Attribute \"%s\" is invalid on <%s> element in this context" +#~ msgstr "Attribute \"%s\" is invalid on <%s> element in this context" -#: ../src/ui/theme.c:286 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "frame geometry does not specify \"%s\" dimension" +#~ msgid "Could not parse \"%s\" as an integer" +#~ msgstr "לא ניתן להעביר את „%s“ כמספר שלם" -#: ../src/ui/theme.c:305 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "frame geometry does not specify dimension \"%s\" for border \"%s\"" +#~ msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +#~ msgstr "לא ניתן להבין את התווים „%s“ במחרוזת „%s“" -#: ../src/ui/theme.c:342 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "Button aspect ratio %g is not reasonable" +#~ msgid "Integer %ld must be positive" +#~ msgstr "Integer %ld must be positive" -#: ../src/ui/theme.c:354 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "Frame geometry does not specify size of buttons" +#~ msgid "Integer %ld is too large, current max is %d" +#~ msgstr "Integer %ld is too large, current max is %d" -#: ../src/ui/theme.c:1067 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "Gradients should have at least two colors" +#~ msgid "Could not parse \"%s\" as a floating point number" +#~ msgstr "Could not parse \"%s\" as a floating point number" -#: ../src/ui/theme.c:1219 -#, c-format -msgid "GTK custom color specification must have color name and fallback in parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" -msgstr "GTK custom color specification must have color name and fallback in parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" +#~ msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" +#~ msgstr "Boolean values must be \"true\" or \"false\" not \"%s\"" -#: ../src/ui/theme.c:1235 -#, c-format -msgid "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-_ are valid" -msgstr "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-_ are valid" +#~ msgid "Angle must be between 0.0 and 360.0, was %g\n" +#~ msgstr "Angle must be between 0.0 and 360.0, was %g\n" -#: ../src/ui/theme.c:1249 -#, c-format -msgid "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not fit the format" -msgstr "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not fit the format" +#~ msgid "" +#~ "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" +#~ msgstr "" +#~ "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -#: ../src/ui/theme.c:1294 -#, c-format -msgid "GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgid "" +#~ "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," +#~ "large,x-large,xx-large)\n" +#~ msgstr "" +#~ "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," +#~ "large,x-large,xx-large)\n" -#: ../src/ui/theme.c:1308 -#, c-format -msgid "GTK color specification must have a close bracket after the state, e.g. gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "GTK color specification must have a close bracket after the state, e.g. gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgid "<%s> name \"%s\" used a second time" +#~ msgstr "<%s> name \"%s\" used a second time" -#: ../src/ui/theme.c:1319 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "Did not understand state \"%s\" in color specification" +#~ msgid "<%s> parent \"%s\" has not been defined" +#~ msgstr "<%s> parent \"%s\" has not been defined" -#: ../src/ui/theme.c:1332 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "Did not understand color component \"%s\" in color specification" +#~ msgid "<%s> geometry \"%s\" has not been defined" +#~ msgstr "<%s> geometry \"%s\" has not been defined" -#: ../src/ui/theme.c:1361 -#, c-format -msgid "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the format" -msgstr "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the format" +#~ msgid "<%s> must specify either a geometry or a parent that has a geometry" +#~ msgstr "<%s> must specify either a geometry or a parent that has a geometry" -#: ../src/ui/theme.c:1372 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "Could not parse alpha value \"%s\" in blended color" +#~ msgid "You must specify a background for an alpha value to be meaningful" +#~ msgstr "You must specify a background for an alpha value to be meaningful" -#: ../src/ui/theme.c:1382 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" +#~ msgid "Unknown type \"%s\" on <%s> element" +#~ msgstr "Unknown type \"%s\" on <%s> element" -#: ../src/ui/theme.c:1429 -#, c-format -msgid "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" +#~ msgid "Unknown style_set \"%s\" on <%s> element" +#~ msgstr "Unknown style_set \"%s\" on <%s> element" -#: ../src/ui/theme.c:1440 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "Could not parse shade factor \"%s\" in shaded color" +#~ msgid "Window type \"%s\" has already been assigned a style set" +#~ msgstr "Window type \"%s\" has already been assigned a style set" -#: ../src/ui/theme.c:1450 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "Shade factor \"%s\" in shaded color is negative" +#~ msgid "Element <%s> is not allowed below <%s>" +#~ msgstr "Element <%s> is not allowed below <%s>" -#: ../src/ui/theme.c:1479 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Could not parse color \"%s\"" +#~ msgid "" +#~ "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio" +#~ "\" for buttons" +#~ msgstr "" +#~ "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio" +#~ "\" for buttons" -#: ../src/ui/theme.c:1790 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "Coordinate expression contains character '%s' which is not allowed" +#~ msgid "Distance \"%s\" is unknown" +#~ msgstr "Distance \"%s\" is unknown" -#: ../src/ui/theme.c:1817 -#, c-format -msgid "Coordinate expression contains floating point number '%s' which could not be parsed" -msgstr "Coordinate expression contains floating point number '%s' which could not be parsed" +#~ msgid "Aspect ratio \"%s\" is unknown" +#~ msgstr "Aspect ratio \"%s\" is unknown" -#: ../src/ui/theme.c:1831 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "Coordinate expression contains integer '%s' which could not be parsed" +#~ msgid "Border \"%s\" is unknown" +#~ msgstr "Border \"%s\" is unknown" -#: ../src/ui/theme.c:1953 -#, c-format -msgid "Coordinate expression contained unknown operator at the start of this text: \"%s\"" -msgstr "Coordinate expression contained unknown operator at the start of this text: \"%s\"" +#~ msgid "No \"start_angle\" or \"from\" attribute on element <%s>" +#~ msgstr "No \"start_angle\" or \"from\" attribute on element <%s>" -#: ../src/ui/theme.c:2010 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "Coordinate expression was empty or not understood" +#~ msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" +#~ msgstr "No \"extent_angle\" or \"to\" attribute on element <%s>" -#: ../src/ui/theme.c:2121 -#: ../src/ui/theme.c:2131 -#: ../src/ui/theme.c:2165 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "Coordinate expression results in division by zero" +#~ msgid "Did not understand value \"%s\" for type of gradient" +#~ msgstr "Did not understand value \"%s\" for type of gradient" -#: ../src/ui/theme.c:2173 -#, c-format -msgid "Coordinate expression tries to use mod operator on a floating-point number" -msgstr "Coordinate expression tries to use mod operator on a floating-point number" +#~ msgid "Did not understand fill type \"%s\" for <%s> element" +#~ msgstr "Did not understand fill type \"%s\" for <%s> element" -#: ../src/ui/theme.c:2229 -#, c-format -msgid "Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "Coordinate expression has an operator \"%s\" where an operand was expected" +#~ msgid "Did not understand state \"%s\" for <%s> element" +#~ msgstr "Did not understand state \"%s\" for <%s> element" -#: ../src/ui/theme.c:2238 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "Coordinate expression had an operand where an operator was expected" +#~ msgid "Did not understand shadow \"%s\" for <%s> element" +#~ msgstr "Did not understand shadow \"%s\" for <%s> element" -#: ../src/ui/theme.c:2246 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "Coordinate expression ended with an operator instead of an operand" +#~ msgid "Did not understand arrow \"%s\" for <%s> element" +#~ msgstr "Did not understand arrow \"%s\" for <%s> element" -#: ../src/ui/theme.c:2256 -#, c-format -msgid "Coordinate expression has operator \"%c\" following operator \"%c\" with no operand in between" -msgstr "Coordinate expression has operator \"%c\" following operator \"%c\" with no operand in between" +#~ msgid "No <draw_ops> called \"%s\" has been defined" +#~ msgstr "No <draw_ops> called \"%s\" has been defined" -#: ../src/ui/theme.c:2407 -#: ../src/ui/theme.c:2452 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "Coordinate expression had unknown variable or constant \"%s\"" +#~ msgid "Including draw_ops \"%s\" here would create a circular reference" +#~ msgstr "Including draw_ops \"%s\" here would create a circular reference" -#: ../src/ui/theme.c:2506 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "Coordinate expression parser overflowed its buffer." +#~ msgid "Unknown position \"%s\" for frame piece" +#~ msgstr "Unknown position \"%s\" for frame piece" -#: ../src/ui/theme.c:2535 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "Coordinate expression had a close parenthesis with no open parenthesis" +#~ msgid "Frame style already has a piece at position %s" +#~ msgstr "Frame style already has a piece at position %s" -#: ../src/ui/theme.c:2599 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "Coordinate expression had an open parenthesis with no close parenthesis" +#~ msgid "No <draw_ops> with the name \"%s\" has been defined" +#~ msgstr "No <draw_ops> with the name \"%s\" has been defined" -#: ../src/ui/theme.c:2610 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "Coordinate expression doesn't seem to have any operators or operands" +#~ msgid "Unknown function \"%s\" for button" +#~ msgstr "Unknown function \"%s\" for button" -#: ../src/ui/theme.c:2822 -#: ../src/ui/theme.c:2842 -#: ../src/ui/theme.c:2862 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "Theme contained an expression that resulted in an error: %s\n" +#~ msgid "Button function \"%s\" does not exist in this version (%d, need %d)" +#~ msgstr "Button function \"%s\" does not exist in this version (%d, need %d)" -#: ../src/ui/theme.c:4533 -#, c-format -msgid "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be specified for this frame style" -msgstr "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be specified for this frame style" +#~ msgid "Unknown state \"%s\" for button" +#~ msgstr "Unknown state \"%s\" for button" -#: ../src/ui/theme.c:5066 -#: ../src/ui/theme.c:5091 -#, c-format -msgid "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" +#~ msgid "Frame style already has a button for function %s state %s" +#~ msgstr "Frame style already has a button for function %s state %s" -#: ../src/ui/theme.c:5139 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Failed to load theme \"%s\": %s\n" - -#: ../src/ui/theme.c:5275 -#: ../src/ui/theme.c:5282 -#: ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 -#: ../src/ui/theme.c:5303 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "No <%s> set for theme \"%s\"" +#~ msgid "\"%s\" is not a valid value for focus attribute" +#~ msgstr "\"%s\" is not a valid value for focus attribute" -#: ../src/ui/theme.c:5311 -#, c-format -msgid "No frame style set for window type \"%s\" in theme \"%s\", add a <window type=\"%s\" style_set=\"whatever\"/> element" -msgstr "No frame style set for window type \"%s\" in theme \"%s\", add a <window type=\"%s\" style_set=\"whatever\"/> element" +#~ msgid "\"%s\" is not a valid value for state attribute" +#~ msgstr "\"%s\" is not a valid value for state attribute" -#: ../src/ui/theme.c:5709 -#: ../src/ui/theme.c:5771 -#: ../src/ui/theme.c:5834 -#, c-format -msgid "User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "User-defined constants must begin with a capital letter; \"%s\" does not" +#~ msgid "A style called \"%s\" has not been defined" +#~ msgstr "A style called \"%s\" has not been defined" -#: ../src/ui/theme.c:5717 -#: ../src/ui/theme.c:5779 -#: ../src/ui/theme.c:5842 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "Constant \"%s\" has already been defined" +#~ msgid "\"%s\" is not a valid value for resize attribute" +#~ msgstr "\"%s\" is not a valid value for resize attribute" -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. -#. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "No \"%s\" attribute on element <%s>" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized/shaded " +#~ "states" +#~ msgstr "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized/shaded " +#~ "states" -#: ../src/ui/theme-parser.c:265 -#: ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Line %d character %d: %s" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized states" +#~ msgstr "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized states" -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "Attribute \"%s\" repeated twice on the same <%s> element" +#~ msgid "Style has already been specified for state %s resize %s focus %s" +#~ msgstr "Style has already been specified for state %s resize %s focus %s" -#: ../src/ui/theme-parser.c:503 -#: ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "Attribute \"%s\" is invalid on <%s> element in this context" +#~ msgid "Style has already been specified for state %s focus %s" +#~ msgstr "Style has already been specified for state %s focus %s" -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "לא ניתן להעביר את \"%s\" כמספר שלם" +#~ msgid "" +#~ "Can't have a two draw_ops for a <piece> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Can't have a two draw_ops for a <piece> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" -#: ../src/ui/theme-parser.c:603 -#: ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "לא ניתן להבין את התוים \"%s\" במחרוזת \"%s\"" +#~ msgid "" +#~ "Can't have a two draw_ops for a <button> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Can't have a two draw_ops for a <button> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "Integer %ld must be positive" +#~ msgid "" +#~ "Can't have a two draw_ops for a <menu_icon> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Can't have a two draw_ops for a <menu_icon> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "Integer %ld is too large, current max is %d" +#~ msgid "Bad version specification '%s'" +#~ msgstr "ציון הגרסה שגוי '%s'" -#: ../src/ui/theme-parser.c:649 -#: ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "Could not parse \"%s\" as a floating point number" +#~ msgid "" +#~ "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" +#~ "theme-2.xml" +#~ msgstr "" +#~ "לא ניתן להשתמש בתכונה \"version\" בקבצים metacity-theme-1.xml או metacity-" +#~ "theme-2.xml" -#: ../src/ui/theme-parser.c:680 -#: ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "Boolean values must be \"true\" or \"false\" not \"%s\"" +#~ msgid "" +#~ "Theme requires version %s but latest supported theme version is %d.%d" +#~ msgstr "" +#~ "ערכת הנושא דורשת את הגרסה %s אך הגרסה העדכנית ביותר של ערכת הנושא היא %d." +#~ "%d" -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "Angle must be between 0.0 and 360.0, was %g\n" +#~ msgid "Outermost element in theme must be <metacity_theme> not <%s>" +#~ msgstr "Outermost element in theme must be <metacity_theme> not <%s>" -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" +#~ msgid "" +#~ "Element <%s> is not allowed inside a name/author/date/description element" +#~ msgstr "" +#~ "Element <%s> is not allowed inside a name/author/date/description element" -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium,large,x-large,xx-large)\n" -msgstr "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium,large,x-large,xx-large)\n" +#~ msgid "Element <%s> is not allowed inside a <constant> element" +#~ msgstr "Element <%s> is not allowed inside a <constant> element" -#: ../src/ui/theme-parser.c:1019 -#: ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 -#: ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s> name \"%s\" used a second time" +#~ msgid "" +#~ "Element <%s> is not allowed inside a distance/border/aspect_ratio element" +#~ msgstr "" +#~ "Element <%s> is not allowed inside a distance/border/aspect_ratio element" -#: ../src/ui/theme-parser.c:1031 -#: ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "<%s> parent \"%s\" has not been defined" +#~ msgid "Element <%s> is not allowed inside a draw operation element" +#~ msgstr "Element <%s> is not allowed inside a draw operation element" -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "<%s> geometry \"%s\" has not been defined" +#~ msgid "Element <%s> is not allowed inside a <%s> element" +#~ msgstr "Element <%s> is not allowed inside a <%s> element" -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "<%s> must specify either a geometry or a parent that has a geometry" +#~ msgid "No draw_ops provided for frame piece" +#~ msgstr "No draw_ops provided for frame piece" -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "You must specify a background for an alpha value to be meaningful" +#~ msgid "No draw_ops provided for button" +#~ msgstr "No draw_ops provided for button" -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Unknown type \"%s\" on <%s> element" +#~ msgid "No text is allowed inside element <%s>" +#~ msgstr "מלל לא מורשה בתג <%s>" -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "Unknown style_set \"%s\" on <%s> element" +#~ msgid "<%s> specified twice for this theme" +#~ msgstr "<%s> צוין פעמיים עבור ערכת נושא זו" -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "Window type \"%s\" has already been assigned a style set" - -#: ../src/ui/theme-parser.c:1313 -#: ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 -#: ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 -#: ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 -#: ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 -#: ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "Element <%s> is not allowed below <%s>" +#~ msgid "Failed to find a valid file for theme %s\n" +#~ msgstr "Failed to find a valid file for theme %s\n" -#: ../src/ui/theme-parser.c:1427 -#: ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" for buttons" -msgstr "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" for buttons" +#~ msgid "Mutter (wayland compositor)" +#~ msgstr "Mutter (wayland מסדר)" -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "Distance \"%s\" is unknown" +#~ msgid "Mi_nimize" +#~ msgstr "מז_עור" -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "Aspect ratio \"%s\" is unknown" +#~ msgid "Ma_ximize" +#~ msgstr "ה_גדלה" -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "Border \"%s\" is unknown" +#~ msgid "Unma_ximize" +#~ msgstr "_שחזור" -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "No \"start_angle\" or \"from\" attribute on element <%s>" +#~ msgid "Roll _Up" +#~ msgstr "גלילה למע_לה" -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "No \"extent_angle\" or \"to\" attribute on element <%s>" +#~ msgid "_Unroll" +#~ msgstr "גלילה ב_חזרה" -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "Did not understand value \"%s\" for type of gradient" +#~ msgid "_Move" +#~ msgstr "ה_זזה" -#: ../src/ui/theme-parser.c:2193 -#: ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "Did not understand fill type \"%s\" for <%s> element" +#~ msgid "_Resize" +#~ msgstr "_שינוי גודל" -#: ../src/ui/theme-parser.c:2360 -#: ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "Did not understand state \"%s\" for <%s> element" +#~ msgid "Move Titlebar On_screen" +#~ msgstr "הזזת שורת הכותרת אל המ_סך" -#: ../src/ui/theme-parser.c:2370 -#: ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "Did not understand shadow \"%s\" for <%s> element" +#~ msgid "Always on _Top" +#~ msgstr "_תמיד עליון" -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "Did not understand arrow \"%s\" for <%s> element" +#~ msgid "_Always on Visible Workspace" +#~ msgstr "ה_צגה בכל מרחבי העבודה" -#: ../src/ui/theme-parser.c:2694 -#: ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "No <draw_ops> called \"%s\" has been defined" +#~ msgid "_Only on This Workspace" +#~ msgstr "_רק במרחב עבודה זה" -#: ../src/ui/theme-parser.c:2706 -#: ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "Including draw_ops \"%s\" here would create a circular reference" +#~ msgid "Move to Workspace _Left" +#~ msgstr "הזזת החלון למרחב העבודה ה_שמאלי" -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Unknown position \"%s\" for frame piece" +#~ msgid "Move to Workspace R_ight" +#~ msgstr "הזזת החלון למרחב העבודה ה_ימני" -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "Frame style already has a piece at position %s" +#~ msgid "Move to Workspace _Up" +#~ msgstr "הזזת החלון למרחב העבודה ש_למעלה" -#: ../src/ui/theme-parser.c:2942 -#: ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "No <draw_ops> with the name \"%s\" has been defined" +#~ msgid "Move to Workspace _Down" +#~ msgstr "הזזת החלון למרחב העבודה שלמ_טה" -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Unknown function \"%s\" for button" +#~ msgid "_Close" +#~ msgstr "_סגור" -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "Button function \"%s\" does not exist in this version (%d, need %d)" +#~ msgid "Workspace %d%n" +#~ msgstr "מרחב עבודה %d%n" -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Unknown state \"%s\" for button" +#~ msgid "Workspace 1_0" +#~ msgstr "מרחב עבודה 1_0" -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "Frame style already has a button for function %s state %s" +#~ msgid "Workspace %s%d" +#~ msgstr "מרחב עבודה %s%d" -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "\"%s\" is not a valid value for focus attribute" +#~ msgid "Move to Another _Workspace" +#~ msgstr "הזז_ת החלון למרחב עבודה אחר" -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "\"%s\" is not a valid value for state attribute" +#~ msgid "Shift" +#~ msgstr "Shift" -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "A style called \"%s\" has not been defined" +#~ msgid "Ctrl" +#~ msgstr "Ctrl" -#: ../src/ui/theme-parser.c:3113 -#: ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "\"%s\" is not a valid value for resize attribute" +#~ msgid "Alt" +#~ msgstr "Alt" -#: ../src/ui/theme-parser.c:3147 -#, c-format -msgid "Should not have \"resize\" attribute on <%s> element for maximized/shaded states" -msgstr "Should not have \"resize\" attribute on <%s> element for maximized/shaded states" +#~ msgid "Meta" +#~ msgstr "מטה" -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "Should not have \"resize\" attribute on <%s> element for maximized states" +#~ msgid "Super" +#~ msgstr "Super" -#: ../src/ui/theme-parser.c:3175 -#: ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "Style has already been specified for state %s resize %s focus %s" - -#: ../src/ui/theme-parser.c:3186 -#: ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 -#: ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 -#: ../src/ui/theme-parser.c:3255 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "Style has already been specified for state %s focus %s" +#~ msgid "Hyper" +#~ msgstr "Hyper" -#: ../src/ui/theme-parser.c:3294 -msgid "Can't have a two draw_ops for a <piece> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "Can't have a two draw_ops for a <piece> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)" +#~ msgid "Mod2" +#~ msgstr "Mod2" -#: ../src/ui/theme-parser.c:3332 -msgid "Can't have a two draw_ops for a <button> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "Can't have a two draw_ops for a <button> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)" +#~ msgid "Mod3" +#~ msgstr "Mod3" -#: ../src/ui/theme-parser.c:3370 -msgid "Can't have a two draw_ops for a <menu_icon> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "Can't have a two draw_ops for a <menu_icon> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)" +#~ msgid "Mod4" +#~ msgstr "Mod4" -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "ציון הגרסה שגוי '%s'" +#~ msgid "Mod5" +#~ msgstr "Mod5" -#: ../src/ui/theme-parser.c:3507 -msgid "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-theme-2.xml" -msgstr "לא ניתן להשתמש בתכונה \"version\" בקבצים metacity-theme-1.xml או metacity-theme-2.xml" +#~ msgid "Unknown window information request: %d" +#~ msgstr "Unknown window information request: %d" -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "ערכת הנושא דורשת את הגרסה %s אך הגרסה העדכנית ביותר של ערכת הנושא היא %d.%d" +#~ msgid "Missing %s extension required for compositing" +#~ msgstr "Missing %s extension required for compositing" -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "Outermost element in theme must be <metacity_theme> not <%s>" +#~ msgid "" +#~ "Some other program is already using the key %s with modifiers %x as a " +#~ "binding\n" +#~ msgstr "תכנית אחרת כבר משתמשת במקש %s עם המקש %x כצירוף\n" -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "Element <%s> is not allowed inside a name/author/date/description element" -msgstr "Element <%s> is not allowed inside a name/author/date/description element" +#~ msgid "\"%s\" is not a valid accelerator\n" +#~ msgstr "\"%s\" אינו מקש האצה תקני\n" -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "Element <%s> is not allowed inside a <constant> element" +#~ msgid "" +#~ "Workarounds for broken applications disabled. Some applications may not " +#~ "behave properly.\n" +#~ msgstr "" +#~ "Workarounds for broken applications disabled. Some applications may not " +#~ "behave properly.\n" -#: ../src/ui/theme-parser.c:3599 -#, c-format -msgid "Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "Element <%s> is not allowed inside a distance/border/aspect_ratio element" +#~ msgid "Could not parse font description \"%s\" from GSettings key %s\n" +#~ msgstr "Could not parse font description \"%s\" from GSettings key %s\n" -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "Element <%s> is not allowed inside a draw operation element" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" +#~ msgstr "" +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" -#: ../src/ui/theme-parser.c:3631 -#: ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 -#: ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "Element <%s> is not allowed inside a <%s> element" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for " +#~ "keybinding \"%s\"\n" +#~ msgstr "" +#~ "\"%s\" found in configuration database is not a valid value for " +#~ "keybinding \"%s\"\n" -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "No draw_ops provided for frame piece" +#~ msgid "" +#~ "Could not acquire window manager selection on screen %d display \"%s\"\n" +#~ msgstr "" +#~ "Could not acquire window manager selection on screen %d display \"%s\"\n" -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "No draw_ops provided for button" +#~ msgid "Could not release screen %d on display \"%s\"\n" +#~ msgstr "Could not release screen %d on display \"%s\"\n" -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "מלל לא מורשה בתג <%s>" - -#: ../src/ui/theme-parser.c:4026 -#: ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 -#: ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "<%s> צוין פעמיים עבור ערכת נושא זו" +#~ msgid "Could not create directory '%s': %s\n" +#~ msgstr "Could not create directory '%s': %s\n" -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Failed to find a valid file for theme %s\n" +#~ msgid "Could not open session file '%s' for writing: %s\n" +#~ msgstr "Could not open session file '%s' for writing: %s\n" -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "ח_לונות" +#~ msgid "Error writing session file '%s': %s\n" +#~ msgstr "Error writing session file '%s': %s\n" -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "_דו־שיח" +#~ msgid "Error closing session file '%s': %s\n" +#~ msgstr "Error closing session file '%s': %s\n" -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "דו־שיח _חוסם" +#~ msgid "Failed to parse saved session file: %s\n" +#~ msgstr "Failed to parse saved session file: %s\n" -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "_כלי" +#~ msgid "<mutter_session> attribute seen but we already have the session ID" +#~ msgstr "" +#~ "התכונה <mutter_session> מופיעה אך כבר יש בידינו את מספר זיהוי ההפעלה" -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "מסך _פתיחה" +#~ msgid "Unknown attribute %s on <%s> element" +#~ msgstr "Unknown attribute %s on <%s> element" -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "המעגן ה_עליון" +#~ msgid "nested <window> tag" +#~ msgstr "nested <window> tag" -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "המעגן ה_תחתון" +#~ msgid "Unknown element %s" +#~ msgstr "Unknown element %s" -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "המעגן ה_שמאלי" +#~ msgid "Failed to open debug log: %s\n" +#~ msgstr "Failed to open debug log: %s\n" -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "המעגן ה_ימני" +#~ msgid "Failed to fdopen() log file %s: %s\n" +#~ msgstr "Failed to fdopen() log file %s: %s\n" -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "כל ה_מעגנים" +#~ msgid "Opened log file %s\n" +#~ msgstr "Opened log file %s\n" -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "ש_ולחן עבודה" +#~ msgid "Window manager: " +#~ msgstr "Window manager: " -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "Open another one of these windows" +#~ msgid "Bug in window manager: " +#~ msgstr "Bug in window manager: " -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "This is a demo button with an 'open' icon" +#~ msgid "Window manager warning: " +#~ msgstr "Window manager warning: " -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "This is a demo button with a 'quit' icon" +#~ msgid "Window manager error: " +#~ msgstr "Window manager error: " -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "This is a sample message in a sample dialog" +#~ msgid "" +#~ "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " +#~ "window as specified in the ICCCM.\n" +#~ msgstr "" +#~ "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " +#~ "window as specified in the ICCCM.\n" -#: ../src/ui/theme-viewer.c:328 -#, c-format -msgid "Fake menu item %d\n" -msgstr "Fake menu item %d\n" +#~ msgid "" +#~ "Window %s sets an MWM hint indicating it isn't resizable, but sets min " +#~ "size %d x %d and max size %d x %d; this doesn't make much sense.\n" +#~ msgstr "" +#~ "Window %s sets an MWM hint indicating it isn't resizable, but sets min " +#~ "size %d x %d and max size %d x %d; this doesn't make much sense.\n" -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "Border-only window" +#~ msgid "Application set a bogus _NET_WM_PID %lu\n" +#~ msgstr "Application set a bogus _NET_WM_PID %lu\n" -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "Bar" +#~ msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +#~ msgstr "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "Normal Application Window" +#~ msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" +#~ msgstr "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "Dialog Box" +#~ msgid "" +#~ "Window 0x%lx has property %s\n" +#~ "that was expected to have type %s format %d\n" +#~ "and actually has type %s format %d n_items %d.\n" +#~ "This is most likely an application bug, not a window manager bug.\n" +#~ "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +#~ msgstr "" +#~ "Window 0x%lx has property %s\n" +#~ "that was expected to have type %s format %d\n" +#~ "and actually has type %s format %d n_items %d.\n" +#~ "This is most likely an application bug, not a window manager bug.\n" +#~ "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "Modal Dialog Box" +#~ msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +#~ msgstr "Property %s on window 0x%lx contained invalid UTF-8\n" -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "Utility Palette" +#~ msgid "" +#~ "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the " +#~ "list\n" +#~ msgstr "" +#~ "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the " +#~ "list\n" -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "Torn-off Menu" +#~ msgid "Usage: %s\n" +#~ msgstr "שימוש: %s\n" -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "Border" +#~ msgid "_Windows" +#~ msgstr "ח_לונות" -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "Attached Modal Dialog" +#~ msgid "_Dialog" +#~ msgstr "_דו־שיח" -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "Button layout test %d" +#~ msgid "_Modal dialog" +#~ msgstr "דו־שיח _חוסם" -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g milliseconds to draw one window frame" +#~ msgid "_Utility" +#~ msgstr "_כלי" -#: ../src/ui/theme-viewer.c:813 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Usage: metacity-theme-viewer [THEMENAME]\n" +#~ msgid "_Splashscreen" +#~ msgstr "מסך _פתיחה" -#: ../src/ui/theme-viewer.c:820 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "Error loading theme: %s\n" +#~ msgid "_Top dock" +#~ msgstr "המעגן ה_עליון" -#: ../src/ui/theme-viewer.c:826 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "Loaded theme \"%s\" in %g seconds\n" +#~ msgid "_Bottom dock" +#~ msgstr "המעגן ה_תחתון" -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "Normal Title Font" +#~ msgid "_Left dock" +#~ msgstr "המעגן ה_שמאלי" -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "Small Title Font" +#~ msgid "_Right dock" +#~ msgstr "המעגן ה_ימני" -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "Large Title Font" +#~ msgid "_All docks" +#~ msgstr "כל ה_מעגנים" -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "Button Layouts" +#~ msgid "Des_ktop" +#~ msgstr "_שולחן עבודה" -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "Benchmark" +#~ msgid "Open another one of these windows" +#~ msgstr "פתיחת חלון נוסף מהסגנון הזה" -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "Window Title Goes Here" +#~ msgid "This is a demo button with an 'open' icon" +#~ msgstr "זהו לחצן הדגמה עם סמל של „פתיחה“" -#: ../src/ui/theme-viewer.c:1047 -#, c-format -msgid "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g seconds wall clock time including X server resources (%g milliseconds per frame)\n" -msgstr "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g seconds wall clock time including X server resources (%g milliseconds per frame)\n" +#~ msgid "This is a demo button with a 'quit' icon" +#~ msgstr "זהו לחצן הדגמה עם סמל של „יציאה“" -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "position expression test returned TRUE but set error" +#~ msgid "This is a sample message in a sample dialog" +#~ msgstr "זוהי הודעת הדגמה בתיבת דו־שיח מדומה" -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "position expression test returned FALSE but didn't set error" +#~ msgid "Fake menu item %d\n" +#~ msgstr "פריט תפריט מדומה %d\n" -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "Error was expected but none given" +#~ msgid "Border-only window" +#~ msgstr "חלון עם מסגרת בלבד" -#: ../src/ui/theme-viewer.c:1274 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "Error %d was expected but %d given" +#~ msgid "Bar" +#~ msgstr "סרגל" -#: ../src/ui/theme-viewer.c:1280 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "Error not expected but one was returned: %s" +#~ msgid "Normal Application Window" +#~ msgstr "חלון יישום רגיל" -#: ../src/ui/theme-viewer.c:1284 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "x value was %d, %d was expected" +#~ msgid "Dialog Box" +#~ msgstr "תיבת דו־שיח" -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "y value was %d, %d was expected" +#~ msgid "Modal Dialog Box" +#~ msgstr "תיבת דו־שיח חוסמת" -#: ../src/ui/theme-viewer.c:1352 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" +#~ msgid "Utility Palette" +#~ msgstr "פלטת כלי" + +#~ msgid "Torn-off Menu" +#~ msgstr "תפריט נתלש" + +#~ msgid "Border" +#~ msgstr "מסגרת" + +#~ msgid "Attached Modal Dialog" +#~ msgstr "חלון חוסם מוצמד" + +#~ msgid "Button layout test %d" +#~ msgstr "בדיקת פריסת לחצנים %d" + +#~ msgid "%g milliseconds to draw one window frame" +#~ msgstr "%g מילישניות לציור של מסגרת חלון אחת" + +#~ msgid "Usage: metacity-theme-viewer [THEMENAME]\n" +#~ msgstr "Usage: metacity-theme-viewer [THEMENAME]\n" + +#~ msgid "Error loading theme: %s\n" +#~ msgstr "Error loading theme: %s\n" + +#~ msgid "Loaded theme \"%s\" in %g seconds\n" +#~ msgstr "Loaded theme \"%s\" in %g seconds\n" + +#~ msgid "Normal Title Font" +#~ msgstr "גופן כותרת רגילה" + +#~ msgid "Small Title Font" +#~ msgstr "גופן כותרת קטנה" + +#~ msgid "Large Title Font" +#~ msgstr "גופן כותרת גדולה" + +#~ msgid "Button Layouts" +#~ msgstr "פריסת לחצנים" + +#~ msgid "Benchmark" +#~ msgstr "מדידת ביצועים" + +#~ msgid "Window Title Goes Here" +#~ msgstr "כותרת החלון מופיעה כאן" + +#~ msgid "" +#~ "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and " +#~ "%g seconds wall clock time including X server resources (%g milliseconds " +#~ "per frame)\n" +#~ msgstr "" +#~ "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and " +#~ "%g seconds wall clock time including X server resources (%g milliseconds " +#~ "per frame)\n" + +#~ msgid "position expression test returned TRUE but set error" +#~ msgstr "position expression test returned TRUE but set error" + +#~ msgid "position expression test returned FALSE but didn't set error" +#~ msgstr "position expression test returned FALSE but didn't set error" + +#~ msgid "Error was expected but none given" +#~ msgstr "Error was expected but none given" + +#~ msgid "Error %d was expected but %d given" +#~ msgstr "Error %d was expected but %d given" + +#~ msgid "Error not expected but one was returned: %s" +#~ msgstr "Error not expected but one was returned: %s" + +#~ msgid "x value was %d, %d was expected" +#~ msgstr "x value was %d, %d was expected" + +#~ msgid "y value was %d, %d was expected" +#~ msgstr "y value was %d, %d was expected" + +#~ msgid "" +#~ "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" +#~ msgstr "" +#~ "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" + +#~ msgid "Minimize window" +#~ msgstr "מזעור חלון" + +#~ msgid "Comma-separated list of compositor plugins" +#~ msgstr "Comma-separated list of compositor plugins" + +#~ msgid "" +#~ "Determines whether hidden windows (i.e., minimized windows and windows on " +#~ "other workspaces than the current one) should be kept alive." +#~ msgstr "" +#~ "Determines whether hidden windows (i.e., minimized windows and windows on " +#~ "other workspaces than the current one) should be kept alive." + +#~ msgid "Live Hidden Windows" +#~ msgstr "Live Hidden Windows" #~ msgid "Close Window" #~ msgstr "סגור חלון" @@ -1465,27 +1578,6 @@ msgstr "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" #~ msgid "Put Window On Only One Workspace" #~ msgstr "הראה את החלון על סביבת עבודה אחת בלבד" -#~ msgid "Switch to workspace 1" -#~ msgstr "מעבר למרחב עבודה 1" - -#~ msgid "Switch to workspace 2" -#~ msgstr "מעבר למרחב עבודה 2" - -#~ msgid "Switch to workspace 3" -#~ msgstr "מעבר למרחב עבודה 3" - -#~ msgid "Switch to workspace 4" -#~ msgstr "מעבר למרחב עבודה 4" - -#~ msgid "Switch to workspace 5" -#~ msgstr "מעבר למרחב עבודה 5" - -#~ msgid "Switch to workspace 6" -#~ msgstr "מעבר למרחב עבודה 6" - -#~ msgid "Switch to workspace 7" -#~ msgstr "מעבר למרחב עבודה 7" - #~ msgid "Switch to workspace 8" #~ msgstr "מעבר למרחב עבודה 8" @@ -1572,54 +1664,12 @@ msgstr "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" #~ msgid "Run a terminal" #~ msgstr "הפעלת מסוף" -#~ msgid "Activate the window menu" -#~ msgstr "הפעלת תפריט החלון" - -#~ msgid "Toggle fullscreen mode" -#~ msgstr "כניסה למצב מסך מלא" - -#~ msgid "Toggle maximization state" -#~ msgstr "הפעלה/כיבוי מצב הגדלה" - #~ msgid "Toggle whether a window will always be visible over other windows" #~ msgstr "Toggle whether a window will always be visible over other windows" -#~ msgid "Maximize window" -#~ msgstr "Maximize window" - -#~ msgid "Restore window" -#~ msgstr "Restore window" - -#~ msgid "Toggle shaded state" -#~ msgstr "Toggle shaded state" - -#~ msgid "Minimize window" -#~ msgstr "Minimize window" - -#~ msgid "Close window" -#~ msgstr "Close window" - -#~ msgid "Move window" -#~ msgstr "Move window" - -#~ msgid "Resize window" -#~ msgstr "Resize window" - #~ msgid "Toggle whether window is on all workspaces or just one" #~ msgstr "Toggle whether window is on all workspaces or just one" -#~ msgid "Move window to workspace 1" -#~ msgstr "Move window to workspace 1" - -#~ msgid "Move window to workspace 2" -#~ msgstr "Move window to workspace 2" - -#~ msgid "Move window to workspace 3" -#~ msgstr "Move window to workspace 3" - -#~ msgid "Move window to workspace 4" -#~ msgstr "Move window to workspace 4" - #~ msgid "Move window to workspace 5" #~ msgstr "Move window to workspace 5" @@ -1644,33 +1694,9 @@ msgstr "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" #~ msgid "Move window to workspace 12" #~ msgstr "Move window to workspace 12" -#~ msgid "Move window one workspace to the left" -#~ msgstr "Move window one workspace to the left" - -#~ msgid "Move window one workspace to the right" -#~ msgstr "Move window one workspace to the right" - -#~ msgid "Move window one workspace up" -#~ msgstr "Move window one workspace up" - -#~ msgid "Move window one workspace down" -#~ msgstr "Move window one workspace down" - #~ msgid "Raise window if it's covered by another window, otherwise lower it" #~ msgstr "Raise window if it's covered by another window, otherwise lower it" -#~ msgid "Raise window above other windows" -#~ msgstr "Raise window above other windows" - -#~ msgid "Lower window below other windows" -#~ msgstr "Lower window below other windows" - -#~ msgid "Maximize window vertically" -#~ msgstr "Maximize window vertically" - -#~ msgid "Maximize window horizontally" -#~ msgstr "Maximize window horizontally" - #~ msgid "Move window to north-west (top left) corner" #~ msgstr "Move window to north-west (top left) corner" @@ -1768,9 +1794,6 @@ msgstr "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" #~ msgid "Error setting clutter plugin list: %s\n" #~ msgstr "ארעה שגיאה בהגדרת רשימת התוספים של clutter:‏ %s\n" -#~ msgid "Clutter Plugins" -#~ msgstr "תוספי Clutter" - #~ msgid "Plugins to load for the Clutter-based compositing manager." #~ msgstr "Plugins to load for the Clutter-based compositing manager." diff --git a/po/hi.po b/po/hi.po index 0c7534dd2..ebe32b2ae 100644 --- a/po/hi.po +++ b/po/hi.po @@ -5,19 +5,24 @@ # G Karunakar <karunakar@freedomink.org>, 2003. # Ravishankar Shrivastava <raviratlami@yahoo.com>, 2004. # Rajesh Ranjan <rranjan@redhat.com>, 2005, 2006, 2009. +# chandankumar <chandankumar.093047@gmail.com>, 2012. +# raj <raj>, 2013. +# rajesh <rajesh>, 2014. msgid "" msgstr "" "Project-Id-Version: metacity.gnome-2-26.hi\n" -"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=metacity&component=general\n" -"POT-Creation-Date: 2009-02-05 16:08+0000\n" -"PO-Revision-Date: 2009-03-14 10:43+0530\n" -"Last-Translator: Rajesh Ranjan <rranjan@redhat.com>\n" -"Language-Team: Hindi <hindi.sf.net>\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=mutter&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2014-09-19 22:00+0000\n" +"PO-Revision-Date: 2014-09-22 18:49+0630\n" +"Last-Translator: rajesh <rajesh>\n" +"Language-Team: Hindi <kde-i18n-doc@kde.org>\n" +"Language: hi\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: KBabel 1.11.4\n" -"Plural-Forms: nplurals=2; plural=(n!=1);\n\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" "\n" "\n" "\n" @@ -25,1915 +30,911 @@ msgstr "" "\n" "\n" "\n" - -#: ../src/50-metacity-desktop-key.xml.in.h:1 -#| msgid "top" -msgid "Desktop" -msgstr "डेस्कटॉप" - -#: ../src/50-metacity-key.xml.in.h:1 -#| msgid "Window manager: " -msgid "Window Management" -msgstr "विंडो प्रबंधन" - -#: ../src/core/core.c:206 -#, c-format -msgid "Unknown window information request: %d" -msgstr "अज्ञात विंडो सूचना आग्रह: %d" - -#: ../src/core/delete.c:70 ../src/core/delete.c:97 -#: ../src/ui/metacity-dialog.c:50 ../src/ui/theme-parser.c:522 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "\"%s\" को पूर्णांक की तरह व्याख्या नहीं कर सका" - -#: ../src/core/delete.c:77 ../src/core/delete.c:104 -#: ../src/ui/metacity-dialog.c:57 ../src/ui/theme-parser.c:531 -#: ../src/ui/theme-parser.c:586 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "पुछल्ले अक्षरों \"%s\" को स्ट्रिंग \"%s\" में समझ नहीं सका" - -#: ../src/core/delete.c:135 -#, c-format -msgid "Failed to parse message \"%s\" from dialog process\n" -msgstr "संदेश \"%s\" की व्याख्या संवाद प्रक्रिया से नहीं कर सका\n" - -#: ../src/core/delete.c:253 -#, c-format -msgid "Error reading from dialog display process: %s\n" -msgstr "संवाद प्रदर्शक प्रक्रिया: %s से पढ़ने में त्रुटि\n" - -#: ../src/core/delete.c:336 -#, c-format -msgid "Error launching metacity-dialog to ask about killing an application: %s\n" -msgstr "किसी अनुप्रयोग को खत्म करने के लिए पूछने हेतु मेटासिटी-संवाद प्रारंभ करने में त्रुटि: %s\n" - -#: ../src/core/delete.c:445 -#, c-format -msgid "Failed to get hostname: %s\n" -msgstr "होस्टनाम पाने में असफल: %s\n" - -#: ../src/core/display.c:256 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "अनुपस्थित %s विस्तार कंपोजिटिंग के लिए जरूरी है" - -#: ../src/core/display.c:334 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "X विंडो तंत्र प्रदर्शक '%s' खोलने में असफल\n" - -#: ../src/core/errors.c:272 -#, c-format -msgid "" -"Lost connection to the display '%s';\n" -"most likely the X server was shut down or you killed/destroyed\n" -"the window manager.\n" -msgstr "" -"प्रदर्शक '%s' से कनेक्शन छूट गया;\n" -"बहुत संभावना है कि या तो एक्स सर्वर बन्द कर दिया गया या आपने विंडो प्रबंधक को \n" -"खत्म/समाप्त कर दिया है.\n" - -#: ../src/core/errors.c:279 -#, c-format -msgid "Fatal IO error %d (%s) on display '%s'.\n" -msgstr "गंभीर आईओ त्रुटि %d (%s), प्रदर्शक '%s' में.\n" - -#: ../src/core/keybindings.c:680 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "कोई अन्य प्रोग्राम पहले से ही कुंजी %s उपयोग में ले रहा है, परिवर्धक %x बाइंडिंग के रूप में \n" - -#. Displayed when a keybinding which is -#. * supposed to launch a program fails. -#. -#: ../src/core/keybindings.c:2294 -#, c-format -#| msgid "" -#| "There was an error running \"%s\":\n" -#| "%s." -msgid "" -"There was an error running <tt>%s</tt>:\n" -"\n" -"%s" -msgstr "" -"<tt>%s</tt> चलाने में त्रुटि थी:\n" "\n" -"%s" - -#: ../src/core/keybindings.c:2381 -#, c-format -msgid "No command %d has been defined.\n" -msgstr "कोई कमांड %d पारिभाषित नहीं है.\n" - -#: ../src/core/keybindings.c:3335 -#, c-format -msgid "No terminal command has been defined.\n" -msgstr "कोई टर्मिनल कमांड पारिभाषित नहीं है.\n" - -#: ../src/core/main.c:116 -#, c-format -#| msgid "" -#| "metacity %s\n" -#| "Copyright (C) 2001-2002 Havoc Pennington, Red Hat, Inc., and others\n" -#| "This is free software; see the source for copying conditions.\n" -#| "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -#| "PARTICULAR PURPOSE.\n" -msgid "" -"metacity %s\n" -"Copyright (C) 2001-2008 Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" -"metacity %s\n" -"Copyright (C) 2001-2008 Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" - -#: ../src/core/main.c:253 -msgid "Disable connection to session manager" -msgstr "सत्र प्रबंधक में संबंधन निष्क्रिय करें" -#: ../src/core/main.c:259 -msgid "Replace the running window manager with Metacity" -msgstr "मेटासिटी के सात कार्यशील विंडो प्रबंधक बदलें" +#: ../data/50-mutter-navigation.xml.in.h:1 +msgid "Navigation" +msgstr "संचरण" -#: ../src/core/main.c:265 -msgid "Specify session management ID" -msgstr "सत्र प्रबंधन ID निर्दिष्ट करें" - -#: ../src/core/main.c:270 -msgid "X Display to use" -msgstr "प्रयोग के लिये X प्रदर्शन" - -#: ../src/core/main.c:276 -msgid "Initialize session from savefile" -msgstr "सेवफाइल के लिये सत्र आरंभीकृत करें" - -#: ../src/core/main.c:282 -msgid "Print version" -msgstr "मुद्रण संस्करण" - -#: ../src/core/main.c:288 -msgid "Make X calls synchronous" -msgstr "X कॉल तुल्यकालित करें" - -#: ../src/core/main.c:294 -#| msgid "Compositing Manager" -msgid "Turn compositing on" -msgstr "कंपोजिटिंग चालू करें" - -#: ../src/core/main.c:300 -msgid "Turn compositing off" -msgstr "कंपोजिटिंग बंद करें" - -#: ../src/core/main.c:478 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "प्रसंग डिरेक्ट्री स्कैन करने में असफल: %s\n" - -#: ../src/core/main.c:494 -#, c-format -#| msgid "" -#| "Could not find a theme! Be sure %s exists and contains the usual themes." -msgid "Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "प्रसंग नहीं ढूंढ सका! सुनिश्चित करें कि %s मौज़ूद है, तथा इसमें सामान्य प्रसंग हैं.\n" - -#: ../src/core/main.c:550 -#, c-format -msgid "Failed to restart: %s\n" -msgstr "पुनः प्रारंभ करने में असफल: %s\n" - -#. -#. * We found it, but it was invalid. Complain. -#. * -#. * FIXME: This replicates the original behaviour, but in the future -#. * we might consider reverting invalid keys to their original values. -#. * (We know the old value, so we can look up a suitable string in -#. * the symtab.) -#. * -#. * (Empty comment follows so the translators don't see this.) -#. -#. -#: ../src/core/prefs.c:505 ../src/core/prefs.c:660 -#, c-format -msgid "GConf key '%s' is set to an invalid value\n" -msgstr "जी-कॉन्फ़ कुंजी '%s' एक अवैध प्रकार में नियत है\n" - -#: ../src/core/prefs.c:586 ../src/core/prefs.c:829 -#, c-format -#| msgid "%d stored in GConf key %s is out of range 0 to %d\n" -msgid "%d stored in GConf key %s is out of range %d to %d\n" -msgstr "%d जो जी-कॉन्फ़ कुंजी %s में भंडारित है वह सीमा %d से %d सीमा से बाहर है\n" - -#: ../src/core/prefs.c:630 ../src/core/prefs.c:707 ../src/core/prefs.c:755 -#: ../src/core/prefs.c:819 ../src/core/prefs.c:1112 ../src/core/prefs.c:1128 -#: ../src/core/prefs.c:1145 ../src/core/prefs.c:1161 -#, c-format -msgid "GConf key \"%s\" is set to an invalid type\n" -msgstr "जी-कॉन्फ़ कुंजी \"%s\" एक अवैध प्रकार में नियत है\n" - -#: ../src/core/prefs.c:1231 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"टूटे अनुप्रयोगों हेतु वर्कअराउन्ड अक्षम किया हुआ है. हो सकता है कुछ अनुप्रयोग उचित प्रकार " -"व्यवहार न करें.\n" - -#: ../src/core/prefs.c:1302 -#, c-format -msgid "Could not parse font description \"%s\" from GConf key %s\n" -msgstr "फ़ॉन्ट विवरण \"%s\" की व्याख्या जी-कॉन्फ़ कुंजी %s से नहीं कर सका\n" - -#: ../src/core/prefs.c:1364 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "कॉन्फ़िगरेशन डेटाबेस में प्राप्त \"%s\" माउस बटन मॉडीफ़ायर वैध मूल्य नहीं है\n" - -#: ../src/core/prefs.c:1782 -#, c-format -msgid "Error setting number of workspaces to %d: %s\n" -msgstr "कार्यस्थान संख्या %d पर तय करने में त्रुटि: %s हुई.\n" - -#: ../src/core/prefs.c:1971 ../src/core/prefs.c:2474 -#, c-format -msgid "Workspace %d" -msgstr "कार्यस्थान %d" - -#: ../src/core/prefs.c:2001 ../src/core/prefs.c:2179 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "कॉन्फ़िगरेशन डेटाबेस में प्राप्त \"%s\" कीबाइंडिंग \"%s\" हेतु वैध मूल्य नहीं है\n" - -#: ../src/core/prefs.c:2555 -#, c-format -msgid "Error setting name for workspace %d to \"%s\": %s\n" -msgstr "कार्यस्थान नाम %d को \"%s\" से में बदलने में त्रुटि: %s हुई\n" - -#: ../src/core/prefs.c:2753 -#, c-format -#| msgid "Error setting name for workspace %d to \"%s\": %s\n" -msgid "Error setting compositor status: %s\n" -msgstr "कंपोजिटर स्थिति सेटिंग में त्रुटि: %s\n" - -#: ../src/core/screen.c:350 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "स्क्रीन %d जो प्रदर्शक '%s' पर है वह अवैध है\n" - -#: ../src/core/screen.c:366 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"स्क्रीन %d जो प्रदर्शक \"%s\" पर है वहां पहले ही विंडो प्रबंधक है, --replace विकल्प का " -"प्रयोग कर वर्तमान विंडो प्रबंधक को बदलने की कोशिश करें.\n" - -#: ../src/core/screen.c:393 -#, c-format -msgid "Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "स्क्रीन %d प्रदर्शक \"%s\" पर विंडो प्रबंधक चयन प्राप्त नहीं कर सका\n" - -#: ../src/core/screen.c:451 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "स्क्रीन %d जो प्रदर्शक \"%s\" पर है वहां पहले ही विंडो प्रबंधक है\n" - -#: ../src/core/screen.c:661 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "स्क्रीन %d जो प्रदर्शक \"%s\" पर है को मुक्त नहीं कर सका\n" - -#. Translators: Please don't translate "Control", "Shift", etc, since these -#. * are hardcoded (in gtk/gtkaccelgroup.c; it's not metacity's fault). -#. * "disabled" must also stay as it is. -#. -#: ../src/core/schema-bindings.c:169 -#| msgid "" -#| "The keybinding used to close a window. The format looks like \"<" -#| "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#| "liberal and allows lower or upper case, and also abbreviations such as " -#| "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#| "special string \"disabled\", then there will be no keybinding for this " -#| "action." -msgid "" -"The format looks like \"<Control>a\" or <Shift><Alt>F1\".\n" -"\n" -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -"special string \"disabled\", then there will be no keybinding for this " -"action." -msgstr "" -"फ़ॉर्मेट इस तरह दिखेंगे \"<Control>a\" या <Shift><Alt>F1\".\n" -"यह पारसर पूरी तरह लिबरल है और बड़े या छोटे अक्षर दोनों " -"स्वीकार करता है, तथा संक्षिप्ताक्षर भी जैसे- \"<Ctl>\" और \"<Ctl>\". " -"यदि आपने विकल्प विशेष स्ट्रिंग में तय किया है \"disabled\", तब वहाँ इस क्रिया हेतु कोई " -"कीबाइंडिंग नहीं होगा." - -#: ../src/core/schema-bindings.c:177 -#| msgid "" -#| "The keybinding used to close a window. The format looks like \"<" -#| "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#| "liberal and allows lower or upper case, and also abbreviations such as " -#| "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#| "special string \"disabled\", then there will be no keybinding for this " -#| "action." -msgid "" -"The format looks like \"<Control>a\" or <Shift><Alt>F1\".\n" -"\n" -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -"special string \"disabled\", then there will be no keybinding for this " -"action.\n" -"\n" -"This keybinding may be reversed by holding down the \"shift\" key; " -"therefore, \"shift\" cannot be one of the keys it uses." -msgstr "" -"फ़ॉर्मेट इस तरह दिखेंगे \"<Control>a\" or <Shift><Alt>F1\".\n" -"यह पारसर पूरी तरह लिबरल है और बड़े या छोटे अक्षर दोनों स्वीकार करता है, तथा संक्षिप्ताक्षर भी जैसे- \"<Ctl>\" और \"<Ctl>\". यदि आपने विकल्प विशेष स्ट्रिंग में तय किया है \"disabled\", तब वहाँ इस क्रिया हेतु कोई " -"कीबाइंडिंग नहीं होगा." - -#: ../src/core/session.c:837 ../src/core/session.c:844 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "डिरेक्ट्री '%s' बना नहीं पाया: %s\n" - -#: ../src/core/session.c:854 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "सत्र फ़ाइल '%s' लिखने हेतु नही खोल पाया: %s\n" - -#: ../src/core/session.c:995 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "स्त्र फ़ाइल लिखने में त्रुटि '%s': %s\n" - -#: ../src/core/session.c:1000 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "सत्र फ़ाइल बंद करने में त्रुटि '%s': %s\n" - -#. oh, just give up -#: ../src/core/session.c:1093 -#, c-format -msgid "Failed to read saved session file %s: %s\n" -msgstr "सहेजी गई सत्र फ़ाइल %s पढ़ने में असफल: %s\n" - -#: ../src/core/session.c:1132 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "सहेजी गई सत्र फ़ाइल: %s की व्याख्या करने में असफल\n" - -#: ../src/core/session.c:1181 -#, c-format -msgid "<metacity_session> attribute seen but we already have the session ID" -msgstr "<मेटासिटी_सत्र> गुण देखा पर हमारे पास पहले ही सत्र आईडी है" - -#: ../src/core/session.c:1194 ../src/core/session.c:1269 -#: ../src/core/session.c:1301 ../src/core/session.c:1373 -#: ../src/core/session.c:1433 -#, c-format -#| msgid "Unknown attribute %s on <window> element" -msgid "Unknown attribute %s on <%s> element" -msgstr "अज्ञात विशेषता %s <%s> तत्व पर" +#: ../data/50-mutter-navigation.xml.in.h:2 +msgid "Move window to workspace 1" +msgstr "विंडो को कार्यस्थान 1 पर ले जाएँ" -#: ../src/core/session.c:1211 -#, c-format -msgid "nested <window> tag" -msgstr "नेस्टेड <विंडो> टैग" +#: ../data/50-mutter-navigation.xml.in.h:3 +msgid "Move window to workspace 2" +msgstr "विंडो को कार्यस्थान 2 पर ले जाएँ" -#: ../src/core/session.c:1453 -#, c-format -msgid "Unknown element %s" -msgstr "अज्ञात तत्व %s" +#: ../data/50-mutter-navigation.xml.in.h:4 +msgid "Move window to workspace 3" +msgstr "विंडो को कार्यस्थान 3 पर ले जाएँ" -#: ../src/core/session.c:1879 -#, c-format -msgid "" -"Error launching metacity-dialog to warn about apps that don't support " -"session management: %s\n" -msgstr "" -"अनुप्रयोग जो सत्र प्रबंधन समर्थन: %s नहीं रखते हैं उनकी चेतावनी बताने हेतु मेटासिटी संवाद " -"प्रारंभ करने में त्रुटि\n" +#: ../data/50-mutter-navigation.xml.in.h:5 +msgid "Move window to workspace 4" +msgstr "विंडो को कार्यस्थान 4 पर ले जाएँ" -#: ../src/core/util.c:101 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "डिबग लॉग: %s खोलने में असफल\n" +#: ../data/50-mutter-navigation.xml.in.h:6 +#| msgid "Move window to workspace 1" +msgid "Move window to last workspace" +msgstr "विंडो को कार्यस्थान अंतिम पर ले जाएँ" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "लॉग फ़ाइल %s: fdopen() में असफल %s\n" +#: ../data/50-mutter-navigation.xml.in.h:7 +msgid "Move window one workspace to the left" +msgstr "विंडो को एक कार्यस्थान बाएँ लाएँ" -#: ../src/core/util.c:117 -#, c-format -msgid "Opened log file %s\n" -msgstr "लॉग फ़ाइल %s खोला\n" +#: ../data/50-mutter-navigation.xml.in.h:8 +msgid "Move window one workspace to the right" +msgstr "विंडो को एक कार्यस्थान दाएँ लाएँ" -#: ../src/core/util.c:136 ../src/tools/metacity-message.c:176 -#, c-format -msgid "Metacity was compiled without support for verbose mode\n" -msgstr "मेटासिटी को वाचाल विधि के बगैर कम्पाइल किया गया है\n" +#: ../data/50-mutter-navigation.xml.in.h:9 +msgid "Move window one workspace up" +msgstr "विंडो को एक कार्यस्थान ऊपर लाएँ" -#: ../src/core/util.c:236 -msgid "Window manager: " -msgstr "विंडो प्रबंधक:" +#: ../data/50-mutter-navigation.xml.in.h:10 +msgid "Move window one workspace down" +msgstr "विंडो को एक कार्यस्थान नीचे लाएँ" -#: ../src/core/util.c:388 -msgid "Bug in window manager: " -msgstr "विंडो प्रबंधक में बग:" +#: ../data/50-mutter-navigation.xml.in.h:11 +#| msgid "Move window one workspace to the left" +msgid "Move window one monitor to the left" +msgstr "विंडो को एक मॉनिटर बाएँ ले जाएँ" -#: ../src/core/util.c:421 -msgid "Window manager warning: " -msgstr "विंडो प्रबंधक चेतावनी" +#: ../data/50-mutter-navigation.xml.in.h:12 +#| msgid "Move window one workspace to the right" +msgid "Move window one monitor to the right" +msgstr "विंडो को एक मॉनिटर दाहिने ले जाएँ" -#: ../src/core/util.c:449 -msgid "Window manager error: " -msgstr "विंडो प्रबंधक त्रुटिः" +#: ../data/50-mutter-navigation.xml.in.h:13 +#| msgid "Move window one workspace up" +msgid "Move window one monitor up" +msgstr "विंडो को एक मॉनिटर ऊपर ले जाएँ" -#. Translators: This is the title used on dialog boxes -#. eof all-keybindings.h -#: ../src/core/util.c:577 ../src/metacity.desktop.in.h:1 -#: ../src/metacity-wm.desktop.in.h:1 -msgid "Metacity" -msgstr "मेटासिटी" +#: ../data/50-mutter-navigation.xml.in.h:14 +#| msgid "Move window one workspace down" +msgid "Move window one monitor down" +msgstr "विंडो को एक मॉनिटर नीचे ले जाएँ" + +#: ../data/50-mutter-navigation.xml.in.h:15 +msgid "Switch applications" +msgstr "अनुप्रयोगों के बीच स्विच करें" + +#: ../data/50-mutter-navigation.xml.in.h:16 +#| msgid "Switch applications" +msgid "Switch to previous application" +msgstr "पिछले अनुप्रयोगों के बीच स्विच करें" + +#: ../data/50-mutter-navigation.xml.in.h:17 +msgid "Switch windows" +msgstr "विंडोज़ स्विच करें " + +#: ../data/50-mutter-navigation.xml.in.h:18 +#| msgid "Switch windows" +msgid "Switch to previous window" +msgstr "पिछले विंडो में जाएँ" + +#: ../data/50-mutter-navigation.xml.in.h:19 +msgid "Switch windows of an application" +msgstr "अनुप्रयोग के विंडो के बीच जायें" + +#: ../data/50-mutter-navigation.xml.in.h:20 +#| msgid "Switch windows of an application" +msgid "Switch to previous window of an application" +msgstr "अनुप्रयोग के पिछले विंडो बीच स्विच करें" + +#: ../data/50-mutter-navigation.xml.in.h:21 +msgid "Switch system controls" +msgstr "नियंत्रण प्रणाली को स्विच करें" + +#: ../data/50-mutter-navigation.xml.in.h:22 +#| msgid "Switch system controls" +msgid "Switch to previous system control" +msgstr "पिछले तंत्र नियंत्रण में स्विच करें" + +#: ../data/50-mutter-navigation.xml.in.h:23 +msgid "Switch windows directly" +msgstr "सीधे विंडोज़ को स्विच करें " + +#: ../data/50-mutter-navigation.xml.in.h:24 +msgid "Switch directly to previous window" +msgstr "पिछले विंडो में सीधे जाएँ" + +#: ../data/50-mutter-navigation.xml.in.h:25 +msgid "Switch windows of an app directly" +msgstr "तत्काल अनुप्रयोग के विंडो के बीच स्विच करें " + +#: ../data/50-mutter-navigation.xml.in.h:26 +#| msgid "Switch windows of an application" +msgid "Switch directly to previous window of an app" +msgstr "एप्प के पिछले विंडो में सीधे जाएँ" + +#: ../data/50-mutter-navigation.xml.in.h:27 +msgid "Switch system controls directly" +msgstr "सीधे नियंत्रण प्रणाली को स्विच करें " + +#: ../data/50-mutter-navigation.xml.in.h:28 +#| msgid "Switch system controls" +msgid "Switch directly to previous system control" +msgstr "पिछले तंत्र नियंत्रण में सीधे स्विच करें" + +#: ../data/50-mutter-navigation.xml.in.h:29 +msgid "Hide all normal windows" +msgstr "सभी सामान्य विंडो को छुपाएँ " + +#: ../data/50-mutter-navigation.xml.in.h:30 +msgid "Switch to workspace 1" +msgstr "कार्यस्थान 1 पर जाएँ" -# first time through -#. first time through -#: ../src/core/window.c:5626 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"विंडो %s नियत करता है SM_CLIENT_ID अपने आप ही, बजाए WM_CLIENT_LEADER विंडो के जैसा " -"कि ICCCM में उल्लेखित किया गया है.\n" +#: ../data/50-mutter-navigation.xml.in.h:31 +msgid "Switch to workspace 2" +msgstr "कार्यस्थान 2 पर जाएँ" -# We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -# * authoritative source for that info. Some apps such as mplayer or -# * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -# * leads to e.g. us not fullscreening their windows. Apps that set -# * MWM but not WM_NORMAL_HINTS are basically broken. We complain -# * about these apps but make them work. -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:6191 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %" -"d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"विंडो %s ने एक एमडबल्यूएम संकेत नियत किया यह दिखाते हुए कि यह आकार बदलने लायक नहीं है, " -"परंतु न्यूनतम आकार नियत किया %d x %d तथा अधिकतम आकार %d x %d; इसका कोई खास अर्थ " -"नहीं निकलता.\n" +#: ../data/50-mutter-navigation.xml.in.h:32 +msgid "Switch to workspace 3" +msgstr "कार्यस्थान 3 पर जाएँ" -#: ../src/core/window-props.c:260 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "अनुप्रयोग ने नियत किया एक bogus _NET_WM_PID %lu\n" +#: ../data/50-mutter-navigation.xml.in.h:33 +msgid "Switch to workspace 4" +msgstr "कार्यस्थान 4 पर जाएँ" -#: ../src/core/window-props.c:377 -#, c-format -msgid "%s (on %s)" -msgstr "%s (%s पर)" +#: ../data/50-mutter-navigation.xml.in.h:34 +#| msgid "Switch to workspace 1" +msgid "Switch to last workspace" +msgstr "अंतिम कार्यस्थान पर जाएँ" -#: ../src/core/window-props.c:1358 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "अवैध WM_TRANSIENT_FOR window 0x%lx %s के लिये निर्दिष्ट.\n" +#: ../data/50-mutter-navigation.xml.in.h:35 +msgid "Move to workspace left" +msgstr "बाएँ कार्यस्थान में ले जाएँ" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"विंडो 0x%lx में गुण %s है \n" -"जिसमें वांछित है प्रकार %s फ़ॉर्मेट %d \n" -"तथा वास्तव में है प्रकार %s फ़ॉर्मेट %d एन_वस्तुएँ %d.\n" -" इस बात की पूरी संभावना है कि यह एक अनुप्रयोग बग है, विंडो प्रबंधक बग नहीं.\n" -" विंडो का शीर्षक है=\"%s\" क्लास=\"%s\" नाम=\"%s\"\n" +#: ../data/50-mutter-navigation.xml.in.h:36 +msgid "Move to workspace right" +msgstr "दाएँ कार्यस्थान में ले जाएँ" -#: ../src/core/xprops.c:401 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "गुण %s विंडो 0x%lx में अवैध यूटीएफ़-8 है \n" +#: ../data/50-mutter-navigation.xml.in.h:37 +msgid "Move to workspace above" +msgstr "ऊपर कार्यस्थान में ले जाएँ" -#: ../src/core/xprops.c:484 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "गुण %s विंडो 0x%lx पर %d वस्तुओं हेतु सूची में अवैध यूटीएफ़-8 है\n" +#: ../data/50-mutter-navigation.xml.in.h:38 +msgid "Move to workspace below" +msgstr "नीचे कार्यस्थान में ले जाएँ" -#: ../src/include/all-keybindings.h:88 -msgid "Switch to workspace 1" -msgstr "कार्यस्थान 1 पर जाएँ" +#: ../data/50-mutter-system.xml.in.h:1 +msgid "System" +msgstr "तंत्र" -#: ../src/include/all-keybindings.h:90 -msgid "Switch to workspace 2" -msgstr "कार्यस्थान 2 पर जाएँ" +#: ../data/50-mutter-system.xml.in.h:2 +msgid "Show the run command prompt" +msgstr "चलाए जाने वाले कमांड फ़लक को दिखाएँ" -#: ../src/include/all-keybindings.h:92 -msgid "Switch to workspace 3" -msgstr "कार्यस्थान 3 पर जाएँ" +#: ../data/50-mutter-system.xml.in.h:3 +msgid "Show the activities overview" +msgstr "गतिविधियों के अवलोकन दिखाएँ" -#: ../src/include/all-keybindings.h:94 -msgid "Switch to workspace 4" -msgstr "कार्यस्थान 4 पर जाएँ" +#: ../data/50-mutter-windows.xml.in.h:1 +msgid "Windows" +msgstr "विंडोज़" -#: ../src/include/all-keybindings.h:96 -msgid "Switch to workspace 5" -msgstr "कार्यस्थान 5 पर जाएँ" - -#: ../src/include/all-keybindings.h:98 -msgid "Switch to workspace 6" -msgstr "कार्यस्थान 6 पर जाएँ" - -#: ../src/include/all-keybindings.h:100 -msgid "Switch to workspace 7" -msgstr "कार्यस्थान 7 पर जाएँ" - -#: ../src/include/all-keybindings.h:102 -msgid "Switch to workspace 8" -msgstr "कार्यस्थान 8 पर जाएँ" - -#: ../src/include/all-keybindings.h:104 -msgid "Switch to workspace 9" -msgstr "कार्यस्थान 9 पर जाएँ" - -#: ../src/include/all-keybindings.h:106 -msgid "Switch to workspace 10" -msgstr "कार्यस्थान 10 पर जाएँ" - -#: ../src/include/all-keybindings.h:108 -msgid "Switch to workspace 11" -msgstr "कार्यस्थान 11 पर जाएँ" - -#: ../src/include/all-keybindings.h:110 -msgid "Switch to workspace 12" -msgstr "कार्यस्थान 12 पर जाएँ" - -#: ../src/include/all-keybindings.h:122 -#| msgid "Switch to workspace on the left" -msgid "Switch to workspace on the left of the current workspace" -msgstr "मौजूदा कार्यस्थान के बाएँ कार्यस्थान पर जाएँ" - -#: ../src/include/all-keybindings.h:126 -#| msgid "Switch to workspace on the right" -msgid "Switch to workspace on the right of the current workspace" -msgstr "मौजूदा कार्यस्थान के दाहिने कार्यस्थान पर जाएँ" - -#: ../src/include/all-keybindings.h:130 -#| msgid "Switch to workspace above this one" -msgid "Switch to workspace above the current workspace" -msgstr "मौजूदा कार्यस्थान के ऊपर कार्यस्थान पर जाएँ" - -#: ../src/include/all-keybindings.h:134 -#| msgid "Switch to workspace below this one" -msgid "Switch to workspace below the current workspace" -msgstr "मौजूदा कार्यस्थान के नीचे कार्यस्थान पर जाएँ" - -#: ../src/include/all-keybindings.h:150 -#| msgid "Move between windows of an application with popup" -msgid "Move between windows of an application, using a popup window" -msgstr "पॉपअप के साथ अनुप्रयोग के विंडो के बीच जायें" - -#: ../src/include/all-keybindings.h:153 -#| msgid "Move backwards between windows of an application with popup" -msgid "Move backward between windows of an application, using a popup window" -msgstr "पॉपअप के साथ तत्काल अनुप्रयोग के विंडो के बीच पीछे जायें" - -#: ../src/include/all-keybindings.h:157 -#| msgid "Move between windows with popup" -msgid "Move between windows, using a popup window" -msgstr "विंडोज़ के बीच पॉपअप के प्रयोग से खिसकाएँ" - -#: ../src/include/all-keybindings.h:160 -#| msgid "Move focus backwards between windows using popup display" -msgid "Move backward between windows, using a popup window" -msgstr "पॉपअप प्रदर्शक के द्वारा विंडो के बीच पीछे ले जाएँ" - -#: ../src/include/all-keybindings.h:163 -#| msgid "Move between panels and the desktop with popup" -msgid "Move between panels and the desktop, using a popup window" -msgstr "पटल तथा डेस्कटॉप के बीच पॉपअप के प्रयोग से खिसकाएँ" - -#: ../src/include/all-keybindings.h:166 -#| msgid "Move backwards between panels and the desktop with popup" -msgid "Move backward between panels and the desktop, using a popup window" -msgstr "पटल तथा डेस्कटॉप के बीच पॉपअप के प्रयोग से पीछे जाएँ" - -#: ../src/include/all-keybindings.h:171 -msgid "Move between windows of an application immediately" -msgstr "तत्काल अनुप्रयोग के विंडो के बीच जायें" - -#: ../src/include/all-keybindings.h:174 -#| msgid "Move backwards between windows of an application immediately" -msgid "Move backward between windows of an application immediately" -msgstr "तत्काल अनुप्रयोग के विंडो के बीच पीछे जायें" - -#: ../src/include/all-keybindings.h:177 -msgid "Move between windows immediately" -msgstr "विंडोज़ के बीच तत्काल खिसकाएँ" - -#: ../src/include/all-keybindings.h:180 -#| msgid "Move backwards between windows immediately" -msgid "Move backward between windows immediately" -msgstr "विंडोज़ के बीच तत्काल पीछे जाएँ" - -#: ../src/include/all-keybindings.h:183 -msgid "Move between panels and the desktop immediately" -msgstr "पटल तथा डेस्कटॉप के बीच तत्काल खिसकाएँ" - -#: ../src/include/all-keybindings.h:186 -msgid "Move backward between panels and the desktop immediately" -msgstr "पटल तथा डेस्कटॉप के बीच तत्काल पीछे जाएँ" - -#: ../src/include/all-keybindings.h:191 -#| msgid "Hide all windows and focus desktop" -msgid "Hide all normal windows and set focus to the desktop" -msgstr "सभी सामान्य विंडो को छुपाएँ और डेस्कटॉप पर फ़ोकस करें" - -#: ../src/include/all-keybindings.h:194 -#| msgid "Show the panel menu" -msgid "Show the panel's main menu" -msgstr "पटल मुख्य मेन्यू दिखाएँ" - -#: ../src/include/all-keybindings.h:197 -#| msgid "Show the panel run application dialog" -msgid "Show the panel's \"Run Application\" dialog box" -msgstr "पटल के \"अनुप्रयोग चलाएँ\" संवाद दिखाएँ" - -#: ../src/include/all-keybindings.h:238 -msgid "Take a screenshot" -msgstr "स्क्रीन का चित्र लें" - -#: ../src/include/all-keybindings.h:240 -msgid "Take a screenshot of a window" -msgstr "विंडो का चित्र लें" - -#: ../src/include/all-keybindings.h:242 -msgid "Run a terminal" -msgstr "एक टर्मिनल चलायें" - -#: ../src/include/all-keybindings.h:257 -#| msgid "Activate window menu" +#: ../data/50-mutter-windows.xml.in.h:2 msgid "Activate the window menu" msgstr "विंडो मेन्यू सक्रिय करें" -#: ../src/include/all-keybindings.h:260 +#: ../data/50-mutter-windows.xml.in.h:3 msgid "Toggle fullscreen mode" msgstr "पूरा स्क्रीन मोड टॉगल करें" -#: ../src/include/all-keybindings.h:262 +#: ../data/50-mutter-windows.xml.in.h:4 msgid "Toggle maximization state" msgstr "अधिकतम स्थिति टॉगल करें" -#: ../src/include/all-keybindings.h:264 -#| msgid "Lower window below other windows" -msgid "Toggle whether a window will always be visible over other windows" -msgstr "टॉगल करें कि क्या दूसरे विंडो के बीच एक विंडो हमेशा दृश्य रहेगा" - -#: ../src/include/all-keybindings.h:266 +#: ../data/50-mutter-windows.xml.in.h:5 msgid "Maximize window" msgstr "विंडो अधिकतम करें" -#: ../src/include/all-keybindings.h:268 -#| msgid "Resize window" +#: ../data/50-mutter-windows.xml.in.h:6 msgid "Restore window" msgstr "विंडो फिर बहाल करें" -#: ../src/include/all-keybindings.h:270 +#: ../data/50-mutter-windows.xml.in.h:7 msgid "Toggle shaded state" -msgstr "आभायुक्त स्थिति टॉगल करें" - -#: ../src/include/all-keybindings.h:272 -msgid "Minimize window" -msgstr "विंडो को न्यूनतम करें" +msgstr "छायांकित स्थिति टॉगल करें" -#: ../src/include/all-keybindings.h:274 +#: ../data/50-mutter-windows.xml.in.h:8 msgid "Close window" msgstr "विंडो बंद करें" -#: ../src/include/all-keybindings.h:276 +#: ../data/50-mutter-windows.xml.in.h:9 +msgid "Hide window" +msgstr "विंडो छिपाएँ" + +#: ../data/50-mutter-windows.xml.in.h:10 msgid "Move window" msgstr "विंडो खिसकाएँ" -#: ../src/include/all-keybindings.h:278 +#: ../data/50-mutter-windows.xml.in.h:11 msgid "Resize window" msgstr "विंडो का आकार बदलें" -#: ../src/include/all-keybindings.h:281 -#| msgid "Toggle window on all workspaces" -msgid "Toggle whether window is on all workspaces or just one" -msgstr "टॉगल करें कि विंडो सभी कार्यस्थान पर है या केवल एक पर" +#: ../data/50-mutter-windows.xml.in.h:12 +msgid "Toggle window on all workspaces or one" +msgstr "टॉगल करें कि विंडो सभी कार्यस्थान पर है या केवल एक" -#: ../src/include/all-keybindings.h:285 -msgid "Move window to workspace 1" -msgstr "विंडो को कार्यस्थान 1 पर ले जाएँ" +#: ../data/50-mutter-windows.xml.in.h:13 +msgid "Raise window if covered, otherwise lower it" +msgstr "विंडो ऊपर करें यदि यह ढ़ंका है अन्यथा नीचे रखें" -#: ../src/include/all-keybindings.h:288 -msgid "Move window to workspace 2" -msgstr "विंडो को कार्यस्थान 2 पर ले जाएँ" - -#: ../src/include/all-keybindings.h:291 -msgid "Move window to workspace 3" -msgstr "विंडो को कार्यस्थान 3 पर ले जाएँ" - -#: ../src/include/all-keybindings.h:294 -msgid "Move window to workspace 4" -msgstr "विंडो को कार्यस्थान 4 पर ले जाएँ" - -#: ../src/include/all-keybindings.h:297 -msgid "Move window to workspace 5" -msgstr "विंडो को कार्यस्थान 5 पर ले जाएँ" - -#: ../src/include/all-keybindings.h:300 -msgid "Move window to workspace 6" -msgstr "विंडो को कार्यस्थान 6 पर ले जाएँ" - -#: ../src/include/all-keybindings.h:303 -msgid "Move window to workspace 7" -msgstr "विंडो को कार्यस्थान 7 पर ले जाएँ" - -#: ../src/include/all-keybindings.h:306 -msgid "Move window to workspace 8" -msgstr "विंडो को कार्यस्थान 8 पर ले जाएँ" - -#: ../src/include/all-keybindings.h:309 -msgid "Move window to workspace 9" -msgstr "विंडो को कार्यस्थान 9 पर ले जाएँ" - -#: ../src/include/all-keybindings.h:312 -msgid "Move window to workspace 10" -msgstr "विंडो को कार्यस्थान 10 पर ले जाएँ" - -#: ../src/include/all-keybindings.h:315 -msgid "Move window to workspace 11" -msgstr "विंडो को कार्यस्थान 11 पर ले जाएँ" - -#: ../src/include/all-keybindings.h:318 -msgid "Move window to workspace 12" -msgstr "विंडो को कार्यस्थान 12 पर ले जाएँ" - -#: ../src/include/all-keybindings.h:330 -msgid "Move window one workspace to the left" -msgstr "विंडो को एक कार्यस्थान बाएँ लाएँ" - -#: ../src/include/all-keybindings.h:333 -msgid "Move window one workspace to the right" -msgstr "विंडो को एक कार्यस्थान दाएँ लाएँ" - -#: ../src/include/all-keybindings.h:336 -msgid "Move window one workspace up" -msgstr "विंडो को एक कार्यस्थान ऊपर लाएँ" - -#: ../src/include/all-keybindings.h:339 -msgid "Move window one workspace down" -msgstr "विंडो को एक कार्यस्थान नीचे लाएँ" - -#: ../src/include/all-keybindings.h:342 -#| msgid "Raise obscured window, otherwise lower" -msgid "Raise window if it's covered by another window, otherwise lower it" -msgstr "विंडो बढ़ाएँ कि क्या यह दूसरे विंडो द्वारा आच्छादित है, अन्यथा इसे नीचे करें" - -#: ../src/include/all-keybindings.h:344 +#: ../data/50-mutter-windows.xml.in.h:14 msgid "Raise window above other windows" msgstr "विंडो को अन्य विंडो के ऊपर रखें" -#: ../src/include/all-keybindings.h:346 +#: ../data/50-mutter-windows.xml.in.h:15 msgid "Lower window below other windows" msgstr "विंडो को अन्य विंडो के नीचे रखें" -#: ../src/include/all-keybindings.h:350 +#: ../data/50-mutter-windows.xml.in.h:16 msgid "Maximize window vertically" msgstr "विंडो खड़ा अधिकतम करें" -#: ../src/include/all-keybindings.h:354 +#: ../data/50-mutter-windows.xml.in.h:17 msgid "Maximize window horizontally" msgstr "विंडो आड़ा अधिकतम करें" -#: ../src/include/all-keybindings.h:358 -#| msgid "Move window one workspace to the left" -msgid "Move window to north-west (top left) corner" -msgstr "विंडो को उत्तर-पश्चिमी (उपरी बाएँ) कोने में ले जाएँ" - -#: ../src/include/all-keybindings.h:361 -#| msgid "Move window one workspace to the right" -msgid "Move window to north-east (top right) corner" -msgstr "विंडो को उत्तर-पूर्वी (उपरी दाहिने) कोने में ले जाएँ" - -#: ../src/include/all-keybindings.h:364 -msgid "Move window to south-west (bottom left) corner" -msgstr "विंडो को दक्षिणी-पश्चिमी (उपरी बाएँ) कोने में ले जाएँ" - -#: ../src/include/all-keybindings.h:367 -msgid "Move window to south-east (bottom right) corner" -msgstr "विंडो को दक्षिणी-पूर्वी (तल के दाहिने) कोने में ले जाएँ" - -#: ../src/include/all-keybindings.h:371 -msgid "Move window to north (top) side of screen" -msgstr "विंडो को स्क्रीन के किनारे उत्तरी (शीर्ष) कोने में ले जाएँ" +#: ../data/50-mutter-windows.xml.in.h:18 +msgid "View split on left" +msgstr "बाईं तरफ विभाजन देखें" -#: ../src/include/all-keybindings.h:374 -msgid "Move window to south (bottom) side of screen" -msgstr "विंडो को स्क्रीन के किनारे दक्षिणी (तल) कोने में ले जाएँ" +#: ../data/50-mutter-windows.xml.in.h:19 +msgid "View split on right" +msgstr "दाईं तरफ विभाजन देखें" -#: ../src/include/all-keybindings.h:377 -msgid "Move window to east (right) side of screen" -msgstr "विंडो को स्क्रीन के किनारे पूर्वी (दाहिने) कोने में ले जाएँ" +#: ../data/mutter.desktop.in.h:1 +msgid "Mutter" +msgstr "Mutter" -#: ../src/include/all-keybindings.h:380 -msgid "Move window to west (left) side of screen" -msgstr "विंडो को स्क्रीन के किनारे पश्चिमी (बाएँ) कोने में ले जाएँ" +#: ../data/org.gnome.mutter.gschema.xml.in.h:1 +msgid "Modifier to use for extended window management operations" +msgstr "विस्तारित विंडो प्रबंधन संचालन का उपयोग के लिए संशोधक" -#: ../src/include/all-keybindings.h:383 -#| msgid "Move window one workspace down" -msgid "Move window to center of screen" -msgstr "विंडो को स्क्रीन के केंद्र में खिसकाएँ" - -#: ../src/metacity.schemas.in.in.h:1 -msgid "(Not implemented) Navigation works in terms of applications not windows" -msgstr "(कार्यान्वित नहीं) संचलन अनुप्रयोगों के अनुसार चलता है, विंडोज़ से नहीं" - -#: ../src/metacity.schemas.in.in.h:2 -msgid "" -"A font description string describing a font for window titlebars. The size " -"from the description will only be used if the titlebar_font_size option is " -"set to 0. Also, this option is disabled if the titlebar_uses_desktop_font " -"option is set to true." -msgstr "" -"एक फंट विवरण स्ट्रिंग विंडो शीर्षक पट्टी के लिये फंट के बारे में बता रहा है. विवरण से आकार " -"प्रयुक्त होगा अगर titlebar_font_size विकल्प 0 में सेट किया जाता है, साथ ही, यह विकल्प " -"निष्क्रिय किया जाता है अगर titlebar_uses_desktop_font विकल्प को सही पर सेट किया " -"जाता है." - -#: ../src/metacity.schemas.in.in.h:3 -msgid "Action on title bar double-click" -msgstr "शीर्षक पट्टी में दोहरा-क्लिक करने पर क्रिया" - -#: ../src/metacity.schemas.in.in.h:4 -#| msgid "Action on title bar double-click" -msgid "Action on title bar middle-click" -msgstr "शीर्षक पट्टी में मध्य-क्लिक पर क्रिया" - -#: ../src/metacity.schemas.in.in.h:5 -#| msgid "Action on title bar double-click" -msgid "Action on title bar right-click" -msgstr "शीर्षक पट्टी में दाहिना-क्लिक पर क्रिया" - -#: ../src/metacity.schemas.in.in.h:6 -msgid "Arrangement of buttons on the titlebar" -msgstr "शीर्षक-पट्टी में बटनों का विन्यास" - -#: ../src/metacity.schemas.in.in.h:7 -#| msgid "" -#| "Arrangement of buttons on the titlebar. The value should be a string, " -#| "such as \"menu:minimize,maximize,close\"; the colon separates the left " -#| "corner of the window from the right corner, and the button names are " -#| "comma-separated. Duplicate buttons are not allowed. Unknown button names " -#| "are silently ignored so that buttons can be added in future metacity " -#| "versions without breaking older versions." -msgid "" -"Arrangement of buttons on the titlebar. The value should be a string, such " -"as \"menu:minimize,maximize,spacer,close\"; the colon separates the left " -"corner of the window from the right corner, and the button names are comma-" -"separated. Duplicate buttons are not allowed. Unknown button names are " -"silently ignored so that buttons can be added in future metacity versions " -"without breaking older versions. A special spacer tag can be used to insert " -"some space between two adjacent buttons." -msgstr "" -"शीर्षक-पट्टी में बटनों का विन्यास. मूल्य स्ट्रिंग होने चाहिएँ, जैसे \"menu:minimize,maximize,spacer,close\"; कॉलन विंडो के बाएँ कोने को दांए कोने से अलग करता है तथा बटन के नाम " -"कॉमा से अलग हैं. दोहरे बटन स्वीकार्य नहीं हैं. अज्ञात बटन नामों को शांति से अनदेखा कर दिया गया है ताकि " -"भविष्य के मेटासिटी संस्करण में, पुराने संस्करण को तोड़े बगैर ये जोड़े जा सकें." - -#: ../src/metacity.schemas.in.in.h:8 -msgid "Automatically raises the focused window" -msgstr "फ़ोकस किए विंडो को स्वचालित उठाएँ" - -#: ../src/metacity.schemas.in.in.h:9 -#| msgid "" -#| "Clicking a window while holding down this modifier key will move the " -#| "window (left click), resize the window (middle click), or show the window " -#| "menu (right click). Modifier is expressed as \"<Alt>\" or \"<" -#| "Super>\" for example." +#: ../data/org.gnome.mutter.gschema.xml.in.h:2 msgid "" -"Clicking a window while holding down this modifier key will move the window " -"(left click), resize the window (middle click), or show the window menu " -"(right click). The left and right operations may be swapped using the " -"\"mouse_button_resize\" key. Modifier is expressed as \"<Alt>\" or " -"\"<Super>\" for example." +"This key will initiate the \"overlay\", which is a combination window " +"overview and application launching system. The default is intended to be the " +"\"Windows key\" on PC hardware. It's expected that this binding either the " +"default or set to the empty string." msgstr "" -"Clicking a window while holding down this modifier key will move the window " -"(left click), resize the window (middle click), or show the window menu " -"(right click). The left and right operations may be swapped using the " -"\"mouse_button_resize\" key. Modifier is expressed as \"<Alt>\" or " -"\"<Super>\" for example." +"इस कुंजी से \"उपरिशायी\" आरंभ हो जाएगा, जो विंडो अवलोकन और अनुप्रयोग को " +"प्रारंभ करने " +"वाली प्रणाली का संयोजन हैं. पीसी हार्डवेयर पर \"विंडोज कुंजी\" डिफ़ॉल्ट होता " +"हैं. यह " +"उम्मीद है कि यह बाध्यकारी या तो डिफ़ॉल्ट या खाली स्ट्रिंग पर सेट हैं." -#: ../src/metacity.schemas.in.in.h:10 -msgid "Commands to run in response to keybindings" -msgstr "कीबाइंडिंग के प्रत्युत्तर में चलाया जाने वाला कमांड" +#: ../data/org.gnome.mutter.gschema.xml.in.h:3 +msgid "Attach modal dialogs" +msgstr "मोडल संवाद अनुलग्न करें" -#: ../src/metacity.schemas.in.in.h:11 -msgid "Compositing Manager" -msgstr "कंपोजिटिंग प्रबंधक" - -#: ../src/metacity.schemas.in.in.h:12 -msgid "Control how new windows get focus" -msgstr "नियंत्रित करें कि कैसे नया विंडो फोकस पाता है" - -#: ../src/metacity.schemas.in.in.h:13 -msgid "Current theme" -msgstr "वर्तमान प्रसंग" - -#: ../src/metacity.schemas.in.in.h:14 -msgid "Delay in milliseconds for the auto raise option" -msgstr "आटो रेस विकल्प हेतु मिलीसेकण्ड्स में देरी" - -#: ../src/metacity.schemas.in.in.h:15 -msgid "Determines whether Metacity is a compositing manager." -msgstr "निर्धारित करें कि Metacity एक कंपोजिटिंग प्रबंधक है." - -#: ../src/metacity.schemas.in.in.h:16 +#: ../data/org.gnome.mutter.gschema.xml.in.h:4 msgid "" -"Determines whether applications or the system can generate audible 'beeps'; " -"may be used in conjunction with 'visual bell' to allow silent 'beeps'." +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." msgstr "" -"निर्धारित करता है कि क्या अनुप्रयोग या तंत्र सुनने योग्य बीप पैदा कर सकता है, शायद " -"दृष्टिगोच़र घंटी के साथ उपयोग किया जाकर शांति मय बीप स्वीकारे." - -#: ../src/metacity.schemas.in.in.h:17 -msgid "Disable misfeatures that are required by old or broken applications" -msgstr "मिसफीचर्स असमर्थ करें जो कि पुराने या टूटे अनुप्रयोगों द्वारा वांछित होते हैं" - -#: ../src/metacity.schemas.in.in.h:18 -msgid "Enable Visual Bell" -msgstr "दृष्टिगोच़र घंटी सक्षम करें" +"यदि सही हैं तो, स्वतंत्र शीर्षक पट्टी होने के बजाय, मोडल संवाद मूल विंडो के " +"शीर्षक पट्टी में " +"संलग्न दिखाई देते हैं और मूल विंडोज के साथ साथ घूमते नज़र आते हैं." -#: ../src/metacity.schemas.in.in.h:19 -msgid "" -"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " -"the focused window will be automatically raised after a delay specified by " -"the auto_raise_delay key. This is not related to clicking on a window to " -"raise it, nor to entering a window during drag-and-drop." -msgstr "" -"अगर सही पर सेट किया जाता है, और फोकस मोड या तो \"स्लोपी\" या \"माउस\" हो तब " -"फोकस किया विंडो तब auto_raise_delay कुंजी से निर्दिष्ट विलंब से फोकस किया विंडो उठाया " -"जायेगा. यह विंडो पर क्लिक किये जाने से संबंधित नहीं है, न तो खींचे व छोड़ें पर दाखिल होकर." +#: ../data/org.gnome.mutter.gschema.xml.in.h:5 +msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "जब स्क्रीन किनारे पर विंडोज़ को छोड़ने बढ़त टाइलिंग सक्षम करें" -#: ../src/metacity.schemas.in.in.h:20 +#: ../data/org.gnome.mutter.gschema.xml.in.h:6 msgid "" -"If true, ignore the titlebar_font option, and use the standard application " -"font for window titles." +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." msgstr "" -"यदि सही है, शीर्षक पट्टी फ़ॉन्ट विकल्प का अनदेखा करें तथा विंडो शीर्षकों हेतु मानक अनुप्रयोग " -"फ़ॉन्ट का प्रयोग करें" +"यदि सक्रिय है, ऊर्ध्वाधर स्क्रीन किनारों पर विंडोज़ को छोड़ने से वे खड़ी में " +"अधिकतम हो जाते हैं " +"और क्षैतिज में आकार बदलता है उपलब्ध क्षेत्र के आधे भाग को छेकने के लिए. शीर्ष " +"स्क्रीन किनारे " +"पर विंडोज़ छोड़ने से वे पूरी तरह से अधिकतम हो जाते हैं" -#: ../src/metacity.schemas.in.in.h:21 -msgid "" -"If true, metacity will give the user less feedback by using wireframes, " -"avoiding animations, or other means. This is a significant reduction in " -"usability for many users, but may allow legacy applications to continue " -"working, and may also be a useful tradeoff for terminal servers. However, " -"the wireframe feature is disabled when accessibility is on." -msgstr "" -"अगर सही है, metacity उपयोक्ता को कम फीडबेक और सीधा हस्तक्षेप का कम सेंस देगा, " -"वायरफ्रेम, एनीमेशन अनदेखा करते हुये, या अन्य साधन. यह महत्वपूर्ण कमी है कई उपयोक्ता के " -"प्रयोग में, लेकिन कई पुरातन अनुप्रयोग व टर्मिनल सर्वर की अनुमति देते हैं कि वे कब अन्यथा रूप " -"से अप्रायोगिक होगें. हालांकि, वायरफ्रेम फीचर को निष्क्रिय किया जाता है जब पहुंच वीयर्ड " -"डेस्कटॉप खंडन को अनदेखा करने के लिये हो." +#: ../data/org.gnome.mutter.gschema.xml.in.h:7 +msgid "Workspaces are managed dynamically" +msgstr "कार्यस्थान गतिशील रूप से प्रबंधित की जाती हैं" -#: ../src/metacity.schemas.in.in.h:22 +#: ../data/org.gnome.mutter.gschema.xml.in.h:8 msgid "" -"If true, then Metacity works in terms of applications rather than windows. " -"The concept is a bit abstract, but in general an application-based setup is " -"more like the Mac and less like Windows. When you focus a window in " -"application-based mode, all the windows in the application will be raised. " -"Also, in application-based mode, focus clicks are not passed through to " -"windows in other applications. Application-based mode is, however, largely " -"unimplemented at the moment." +"Determines whether workspaces are managed dynamically or whether there's a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." msgstr "" -"यदि सही है तो मेटासिटी विंडो के बजाए अनुप्रयोग जैसे कार्य करेगा. परिकल्पना थोड़ी संक्षिप्त " -"है परंतु आमतौर पर अनुप्रयोग आधारित सेटअप मैक जैसा ज्यादा होगा विंडोज़ की तरह कम. यदि आप " -"किसी विंडो को अनुप्रयोग आधारित मोड पर फ़ोकस करेंगे तो अनुप्रयोग में के सभी विंडो ऊपर हो " -"जाएंगे. यह भी कि अनुप्रयोग आधारित मोड में फ़ोकस क्लिक अन्य अनुप्रयोग के विंडो से होकर नहीं " -"जाता. अनुप्रयोग आधारित मोड विस्तृत रूप से इस समय कार्यान्वित नहीं है." - -#: ../src/metacity.schemas.in.in.h:23 -msgid "If true, trade off usability for less resource usage" -msgstr "यदि सही है, उपयोगिता को कम साधन उपयोग के साथ बदलें" +"यह निर्धारित करता है कि कार्यस्थानों को गतिशील रूप से प्रबंधित की जाती हैं या " +"कि क्या " +"वहाँ कार्यस्थानों के एक स्थिर संख्या हैं (org.gnome.desktop.wm.preferences " +"में कुंजी संख्या " +"कार्यस्थानों द्वारा निर्धारित की जाती है)." -#: ../src/metacity.schemas.in.in.h:24 -msgid "Modifier to use for modified window click actions" -msgstr "विंडो क्लिक क्रिया परिवर्तन हेतु उपयोग में परिवर्धक" +#: ../data/org.gnome.mutter.gschema.xml.in.h:9 +msgid "Workspaces only on primary" +msgstr "केवल प्राथमिक पर कार्यस्थान" -#: ../src/metacity.schemas.in.in.h:25 -msgid "Name of workspace" -msgstr "कार्यस्थान का नाम" - -#: ../src/metacity.schemas.in.in.h:26 -msgid "Number of workspaces" -msgstr "कार्यस्थान की संख्या" - -#: ../src/metacity.schemas.in.in.h:27 +#: ../data/org.gnome.mutter.gschema.xml.in.h:10 msgid "" -"Number of workspaces. Must be more than zero, and has a fixed maximum to " -"prevent making the desktop unusable by accidentally asking for too many " -"workspaces." +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." msgstr "" -"कार्यस्थान की संख्या. यह शून्य से अधिक होना चाहिए तथा इसे एक अधिकतम पर निर्धारित करना " -"चाहिये ज्यादा कार्यस्थान की मांग करने पर आपके डेस्कटॉप को दुर्धटनावश नष्ट होने से बचाने हेतु." +" निर्धारित करता है कि क्या कार्यस्थान को स्विच करना सभी मॉनिटर पर विंडोज़ के " +"लिए संभव " +"हैं या केवल प्राथमिक मॉनीटर पर विंडोज के लिए." -#: ../src/metacity.schemas.in.in.h:28 -msgid "Run a defined command" -msgstr "पारिभाषित कमांड चलाएँ" +#: ../data/org.gnome.mutter.gschema.xml.in.h:11 +msgid "No tab popup" +msgstr "कोई टैब पॉपअप नहीं" -#: ../src/metacity.schemas.in.in.h:29 +#: ../data/org.gnome.mutter.gschema.xml.in.h:12 msgid "" -"Set this to true to resize with the right button and show a menu with the " -"middle button while holding down the key given in \"mouse_button_modifier\"; " -"set it to false to make it work the opposite way around." +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." msgstr "" -"Set this to true to resize with the right button and show a menu with the " -"middle button while holding down the key given in \"mouse_button_modifier\"; " -"set it to false to make it work the opposite way around." +"निर्धारित करता है कि क्या पॉपअप और उजागर फ्रेम के उपयोग विंडो साइकिल चालन के " +"लिए " +"निष्क्रिय किया जाना चाहिए." -#: ../src/metacity.schemas.in.in.h:30 -msgid "" -"Setting this option to false can lead to buggy behavior, so users are " -"strongly discouraged from changing it from the default of true. Many actions " -"(e.g. clicking in the client area, moving or resizing the window) normally " -"raise the window as a side-effect. Setting this option to false, which is " -"strongly discouraged, will decouple raising from other user actions, and " -"ignore raise requests generated by applications. See http://bugzilla.gnome." -"org/show_bug.cgi?id=445447#c6. Even when this option is false, windows can " -"still be raised by an alt-left-click anywhere on the window, a normal click " -"on the window decorations, or by special messages from pagers, such as " -"activation requests from tasklist applets. This option is currently disabled " -"in click-to-focus mode. Note that the list of ways to raise windows when " -"raise_on_click is false does not include programmatic requests from " -"applications to raise windows; such requests will be ignored regardless of " -"the reason for the request. If you are an application developer and have a " -"user complaining that your application does not work with this setting " -"disabled, tell them it is _their_ fault for breaking their window manager " -"and that they need to change this option back to true or live with the \"bug" -"\" they requested." -msgstr "" -"Setting this option to false can lead to buggy behavior, so users are " -"strongly discouraged from changing it from the default of true. Many actions " -"(e.g. clicking in the client area, moving or resizing the window) normally " -"raise the window as a side-effect. Setting this option to false, which is " -"strongly discouraged, will decouple raising from other user actions, and " -"ignore raise requests generated by applications. See http://bugzilla.gnome." -"org/show_bug.cgi?id=445447#c6. Even when this option is false, windows can " -"still be raised by an alt-left-click anywhere on the window, a normal click " -"on the window decorations, or by special messages from pagers, such as " -"activation requests from tasklist applets. This option is currently disabled " -"in click-to-focus mode. Note that the list of ways to raise windows when " -"raise_on_click is false does not include programmatic requests from " -"applications to raise windows; such requests will be ignored regardless of " -"the reason for the request. If you are an application developer and have a " -"user complaining that your application does not work with this setting " -"disabled, tell them it is _their_ fault for breaking their window manager " -"and that they need to change this option back to true or live with the \"bug" -"\" they requested." - -#: ../src/metacity.schemas.in.in.h:31 +#: ../data/org.gnome.mutter.gschema.xml.in.h:13 +msgid "Delay focus changes until the pointer stops moving" +msgstr "पॉइंटर के चलने के रूकने तक फोकस परिवर्तन को विलंबित करें" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:14 msgid "" -"Some applications disregard specifications in ways that result in window " -"manager misfeatures. This option puts Metacity in a rigorously correct mode, " -"which gives a more consistent user interface, provided one does not need to " -"run any misbehaving applications." +"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " +"the focus will not be changed immediately when entering a window, but only " +"after the pointer stops moving." msgstr "" -"कुछ अनुप्रयोग विशेषता को महत्व नहीं देते हैं जो कि विंडो प्रबंधक मिसफीचर में परिणाम लाता है. " -"यह विकल्प Metacity को काफी सही मोड में रखता है, जो कि ज्यादा संगत उपयोक्ता अंतरफलक " -"देता है, अगर कोई गलत अनुप्रयोग नहीं चला रहा है." +"अगर सही पर सेट किया जाता है, और फोकस मोड या तो \"स्लोपी\" या \"माउस\" हो तब " +"फोकस विंडो में दाखिल होने वक्त तत्काल नहीं बदलेगा बल्कि केवल पॉइंटर के रुक " +"जाने पर ही." -#: ../src/metacity.schemas.in.in.h:32 -msgid "System Bell is Audible" -msgstr "तंत्र घंटी सुनने योग्य है" +#: ../data/org.gnome.mutter.gschema.xml.in.h:15 +msgid "Draggable border width" +msgstr "ड्रैग करने योग्य सीमा चौड़ाई" -#: ../src/metacity.schemas.in.in.h:33 +#: ../data/org.gnome.mutter.gschema.xml.in.h:16 msgid "" -"Tells Metacity how to implement the visual indication that the system bell " -"or another application 'bell' indicator has been rung. Currently there are " -"two valid values, \"fullscreen\", which causes a fullscreen white-black " -"flash, and \"frame_flash\" which causes the titlebar of the application " -"which sent the bell signal to flash. If the application which sent the bell " -"is unknown (as is usually the case for the default \"system beep\"), the " -"currently focused window's titlebar is flashed." +"The amount of total draggable borders. If the theme's visible borders are " +"not enough, invisible borders will be added to meet this value." msgstr "" -"मेटासिटी को बताता है कि कैसे दृश्य संकेत काम में लिया जाए कि तंत्र घंटी या अन्य अनुप्रयोग " -"घंटी बजाना है. वर्तमान में दो मान्य मूल्य हैं, \"पूरा स्क्रीन\", जो फुलस्क्रीन काला-सफेद फ्लेश " -"करता है तथा \"फ्रेम-फ्लैश\" जो संबंधित अनुप्रयोग के टाइटलबार को फ्लेश करने हेतु संकेत करता " -"है, जिसको घंटी संकेत भेजता है. यदि अनुप्रयोग जिसने घंटी संकेत भेजा है. अज्ञात है तो ( जैसा कि " -"आमतौर पर डिफ़ॉल्ट \"तंत्र बीप\" में होता है), वर्तमान फ़ोकस विंडो का शीर्षक पट्टी फ्लैश " -"करेगा. " - -#: ../src/metacity.schemas.in.in.h:34 -msgid "" -"The /apps/metacity/global_keybindings/run_command_N keys define keybindings " -"that correspond to these commands. Pressing the keybinding for run_command_N " -"will execute command_N." -msgstr "" -"कुंजियाँ /apps/metacity/global_keybindings/run_command_N इन कमांड के तदनुरूप " -"कीबाइंडिंग पारिभाषित करती हैं. run_command_N का कीबाइंडिंग दबाने पर यह command_N " -"को चलाएगा. " +"कुल ड्रैग करने योग्य सीमाओं की मात्रा. यदि विषय दृश्यमान सीमाओं के लिए " +"पर्याप्त नहीं हैं, " +"अदृश्य सीमाओं इस मान को पूरा करने के लिए जोड़ दिया जाएगा." -#: ../src/metacity.schemas.in.in.h:35 -msgid "" -"The /apps/metacity/global_keybindings/run_command_screenshot key defines a " -"keybinding which causes the command specified by this setting to be invoked." -msgstr "" -"कुंजी /apps/metacity/global_keybindings/run_command_screenshot वह कीबाइंडिंग " -"पारिभाषित करती है जो इस विन्यास से उल्लेखित कमांड को प्रारंभ करती है." +#: ../data/org.gnome.mutter.gschema.xml.in.h:17 +msgid "Auto maximize nearly monitor sized windows" +msgstr "मॉनीटर आकार के विंडो में क़रीब स्वतः अधिकतम करें" -#: ../src/metacity.schemas.in.in.h:36 +#: ../data/org.gnome.mutter.gschema.xml.in.h:18 msgid "" -"The /apps/metacity/global_keybindings/run_command_window_screenshot key " -"defines a keybinding which causes the command specified by this setting to " -"be invoked." +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." msgstr "" -"कुंजी /apps/metacity/global_keybindings/run_command_window_screenshot वह " -"कीबाइंडिंग पारिभाषित करती है जो इस विन्यास से उल्लेखित कमांड को प्रारंभ करती है." +"यदि सक्रिय किया जाता है, नया विंडो मॉनीटर के आकार का आरंभ में है जो स्वतः " +"अधिकतम रूप से " +"हो जाता है." -#: ../src/metacity.schemas.in.in.h:37 -msgid "" -"The keybinding that runs the correspondingly-numbered command in /apps/" -"metacity/keybinding_commands The format looks like \"<Control>a\" or " -"\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -"lower or upper case, and also abbreviations such as \"<Ctl>\" and " -"\"<Ctrl>\". If you set the option to the special string \"disabled\", " -"then there will be no keybinding for this action." -msgstr "" -"कीबाइंडिंग जो कि /apps/metacity/keybinding_commands के तदनुरूप नम्बर वाले कमांड को " -"चलाता है . फ़ॉर्मेट इस तरह दिखेंगे \"<Control>a\" या \"<Shift><" -"Alt>F1. यह पारसर पूरी तरह लिबरल है और बड़े या छोटे अक्षर दोनों स्वीकार करता है, " -"तथा संक्षिप्ताक्षर भी जैसे- \"<Ctl>\" और \"<Ctrl>\". यदि आपने विकल्प " -"विशेष स्ट्रिंग में तय किया है \"disabled\", तब वहाँ इस क्रिया हेतु कोई कीबाइंडिंग नहीं " -"होगा." - -#: ../src/metacity.schemas.in.in.h:38 -msgid "The name of a workspace." -msgstr "कार्यस्थान का नाम" - -#: ../src/metacity.schemas.in.in.h:39 -msgid "The screenshot command" -msgstr "स्क्रीन-शॉट कमांड " - -#: ../src/metacity.schemas.in.in.h:40 -msgid "" -"The theme determines the appearance of window borders, titlebar, and so " -"forth." -msgstr "प्रसंग, विंडो किनारा, शीर्षक पट्टी इत्यादि के रंग-रूप को निर्धारित करता है." +#: ../data/org.gnome.mutter.gschema.xml.in.h:19 +msgid "Place new windows in the center" +msgstr "सेंटर में नया विंडो रखें" -#: ../src/metacity.schemas.in.in.h:41 +#: ../data/org.gnome.mutter.gschema.xml.in.h:20 msgid "" -"The time delay before raising a window if auto_raise is set to true. The " -"delay is given in thousandths of a second." -msgstr "" -"यदि auto_raise सही पर नियत है तो विंडो ऊपर उठाने से पहले विलम्ब समय. यह विलम्ब " -"सेकण्ड के हजारवें हिस्से में दिया जाता है." +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "जब सही, नया विंडो मॉनिटर के सक्रिय स्क्रीन के केंद्र में रखा जाएगा." + +#: ../data/org.gnome.mutter.gschema.xml.in.h:21 +msgid "Select window from tab popup" +msgstr "पॉपअप टैब से विंडो का चयन करें" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:22 +msgid "Cancel tab popup" +msgstr "टैब पॉपअप रद्द करें" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:1 +#| msgid "Switch to workspace 1" +msgid "Switch to VT 1" +msgstr "VT 1 पर जाएँ" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:2 +#| msgid "Switch to workspace 2" +msgid "Switch to VT 2" +msgstr "VT 2 पर जाएँ" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:3 +#| msgid "Switch to workspace 3" +msgid "Switch to VT 3" +msgstr "VT 3 पर जाएँ" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:4 +#| msgid "Switch to workspace 4" +msgid "Switch to VT 4" +msgstr "VT 4 पर जाएँ" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:5 +#| msgid "Switch to workspace 5" +msgid "Switch to VT 5" +msgstr "VT 5 पर जाएँ" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:6 +#| msgid "Switch to workspace 6" +msgid "Switch to VT 6" +msgstr "VT 6 पर जाएँ" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:7 +#| msgid "Switch to workspace 7" +msgid "Switch to VT 7" +msgstr "VT 7 पर जाएँ" + +#: ../src/backends/meta-monitor-manager.c:412 +msgid "Built-in display" +msgstr "अंतर्निमित प्रदर्शन" + +#: ../src/backends/meta-monitor-manager.c:437 +msgid "Unknown" +msgstr "अज्ञात" + +#: ../src/backends/meta-monitor-manager.c:439 +msgid "Unknown Display" +msgstr "अज्ञात प्रदर्शन" + +#. TRANSLATORS: this is a monitor vendor name, followed by a +#. * size in inches, like 'Dell 15"' +#. +#: ../src/backends/meta-monitor-manager.c:447 +#, c-format +msgid "%s %s" +msgstr "%s %s" -#: ../src/metacity.schemas.in.in.h:42 -msgid "" -"The window focus mode indicates how windows are activated. It has three " -"possible values; \"click\" means windows must be clicked in order to focus " -"them, \"sloppy\" means windows are focused when the mouse enters the window, " -"and \"mouse\" means windows are focused when the mouse enters the window and " -"unfocused when the mouse leaves the window." -msgstr "" -"विंडो फ़ोकस मोड जो संकेत करता है कि विंडोज़ कैसे सक्रिय हों. इसके तीन संभावित मूल्य हैं, क्लिक " -"\"क्लिक\" मतलब विंडो को फ़ोकस करने हेतु उनमें क्लिक करना होगा, \"स्लॉपी\" मतलब विंडो तब " -"फ़ोकस होंगे जब माउस विंडो में प्रवेश करेगा, तथा \"माउस\" मतलब विंडो तब फ़ोकस होंगे जब " -"माउस विंडो में प्रवेश करेगा तथा फ़ोकस से बाहर होगा जब माउस विंडो से बाहर होगा." - -#: ../src/metacity.schemas.in.in.h:43 -msgid "The window screenshot command" -msgstr "विंडो स्क्रीन-शॉट कमांड " - -#: ../src/metacity.schemas.in.in.h:44 -#| msgid "" -#| "This option determines the effects of double-clicking on the title bar. " -#| "Current valid options are 'toggle_shade', which will shade/unshade the " -#| "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#| "'minimize' which will minimize the window, and 'none' which will not do " -#| "anything." -msgid "" -"This option determines the effects of double-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, 'toggle_maximize' which will maximize/unmaximize the window, " -"'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which will " -"maximize/unmaximize the window in that direction only, 'minimize' which will " -"minimize the window, 'shade' which will roll the window up, 'menu' which " -"will display the window menu, 'lower' which will put the window behind all " -"the others, and 'none' which will not do anything." -msgstr "" -"This option determines the effects of double-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, 'toggle_maximize' which will maximize/unmaximize the window, " -"'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which will " -"maximize/unmaximize the window in that direction only, 'minimize' which will " -"minimize the window, 'shade' which will roll the window up, 'menu' which " -"will display the window menu, 'lower' which will put the window behind all " -"the others, and 'none' which will not do anything." - -#: ../src/metacity.schemas.in.in.h:45 -#| msgid "" -#| "This option determines the effects of double-clicking on the title bar. " -#| "Current valid options are 'toggle_shade', which will shade/unshade the " -#| "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#| "'minimize' which will minimize the window, and 'none' which will not do " -#| "anything." -msgid "" -"This option determines the effects of middle-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, 'toggle_maximize' which will maximize/unmaximize the window, " -"'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which will " -"maximize/unmaximize the window in that direction only, 'minimize' which will " -"minimize the window, 'shade' which will roll the window up, 'menu' which " -"will display the window menu, 'lower' which will put the window behind all " -"the others, and 'none' which will not do anything." -msgstr "" -"This option determines the effects of middle-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, 'toggle_maximize' which will maximize/unmaximize the window, " -"'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which will " -"maximize/unmaximize the window in that direction only, 'minimize' which will " -"minimize the window, 'shade' which will roll the window up, 'menu' which " -"will display the window menu, 'lower' which will put the window behind all " -"the others, and 'none' which will not do anything." - -#: ../src/metacity.schemas.in.in.h:46 -#| msgid "" -#| "This option determines the effects of double-clicking on the title bar. " -#| "Current valid options are 'toggle_shade', which will shade/unshade the " -#| "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#| "'minimize' which will minimize the window, and 'none' which will not do " -#| "anything." -msgid "" -"This option determines the effects of right-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, 'toggle_maximize' which will maximize/unmaximize the window, " -"'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which will " -"maximize/unmaximize the window in that direction only, 'minimize' which will " -"minimize the window, 'shade' which will roll the window up, 'menu' which " -"will display the window menu, 'lower' which will put the window behind all " -"the others, and 'none' which will not do anything." -msgstr "" -"This option determines the effects of right-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, 'toggle_maximize' which will maximize/unmaximize the window, " -"'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which will " -"maximize/unmaximize the window in that direction only, 'minimize' which will " -"minimize the window, 'shade' which will roll the window up, 'menu' which " -"will display the window menu, 'lower' which will put the window behind all " -"the others, and 'none' which will not do anything." - -#: ../src/metacity.schemas.in.in.h:47 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: ../src/compositor/compositor.c:443 +#, c-format msgid "" -"This option provides additional control over how newly created windows get " -"focus. It has two possible values; \"smart\" applies the user's normal focus " -"mode, and \"strict\" results in windows started from a terminal not being " -"given focus." -msgstr "" -"यह विकल्प अतिरिक्त नियंत्रण देता है कि कैसे नया बनाया विंडो फोकस पाता है. इसके दो " -"संभावित मान हैं; \"smart\" उपयोक्ता के सामान्य फोकस मोड पर लागू होता है और \"strict" -"\" ऐसे विंडो के रूप में आता है जो टर्मिनल से फोकस नहीं किये गये रूप में आता है." +"Another compositing manager is already running on screen %i on display \"%s" +"\"." +msgstr "स्क्रीन %i प्रदर्शक \"%s\" पर विंडो प्रबंधक चयन प्राप्त नहीं कर सका." -#: ../src/metacity.schemas.in.in.h:48 -msgid "" -"Turns on a visual indication when an application or the system issues a " -"'bell' or 'beep'; useful for the hard-of-hearing and for use in noisy " -"environments." -msgstr "" -"दृश्य संकेत चालू करना जब कोई अनुप्रयोग या तंत्र घंटी या बीप जारी करते हैं तो, शोरयुक्त " -"वातावरण- जहाँ सुनने में कठिनाई हो या उंचा सुनने वाले के लिये उपयोगी होता है." +#: ../src/core/bell.c:185 +msgid "Bell event" +msgstr "बेल इवेंट" -#: ../src/metacity.schemas.in.in.h:49 -msgid "Use standard system font in window titles" -msgstr "विंडो शीर्षकों में मानक तंत्र फ़ॉन्ट प्रयोग करें" - -#: ../src/metacity.schemas.in.in.h:50 -msgid "Visual Bell Type" -msgstr "दृष्टिगोच़र घंटी प्रकार" +#: ../src/core/delete.c:127 +#, c-format +msgid "“%s” is not responding." +msgstr "“%s” जबाव नहीं दे रहा है." -#: ../src/metacity.schemas.in.in.h:51 -msgid "Whether raising should be a side-effect of other user interactions" -msgstr "अन्य उपयोक्ता अंतःक्रिया के प्रभाव को क्या उठाया जाना चाहिये" +#: ../src/core/delete.c:129 +msgid "Application is not responding." +msgstr "अनुप्रयोग प्रतिक्रिया नहीं दे रहा है." -#: ../src/metacity.schemas.in.in.h:52 -msgid "Whether to resize with the right button" -msgstr "क्या दाहिना बटन फिर आकार दिया जाना है" +#: ../src/core/delete.c:134 +msgid "" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." +msgstr "" +"आप थोड़ी देर के लिए इसकी प्रतीक्षा के लिए चयन कर सकते हैं पूरी तरह से " +"अनुप्रयोग के जारी " +"रखने व छोड़ने के लिए दबाव दे सकते हैं." -#: ../src/metacity.schemas.in.in.h:53 -msgid "Window focus mode" -msgstr "विंडो फ़ोकस मोड" +#: ../src/core/delete.c:141 +msgid "_Wait" +msgstr "प्रतीक्षा करें (_W)" -#: ../src/metacity.schemas.in.in.h:54 -msgid "Window title font" -msgstr "विंडो शीर्षक फ़ॉन्ट" +#: ../src/core/delete.c:141 +msgid "_Force Quit" +msgstr "जबर्दस्ती बाहर (_F)" -#: ../src/tools/metacity-message.c:150 +#: ../src/core/display.c:547 #, c-format -msgid "Usage: %s\n" -msgstr "उपयोग: %s\n" +msgid "Failed to open X Window System display '%s'\n" +msgstr "X विंडो तंत्र प्रदर्शक '%s' खोलने में असफल\n" -#: ../src/ui/frames.c:1118 -msgid "Close Window" -msgstr "विंडो बंद करें" +#: ../src/core/main.c:176 +msgid "Disable connection to session manager" +msgstr "सत्र प्रबंधक में संबंधन निष्क्रिय करें" -#: ../src/ui/frames.c:1121 -msgid "Window Menu" -msgstr "विंडो मेनू" +#: ../src/core/main.c:182 +msgid "Replace the running window manager" +msgstr "कार्यशील विंडो प्रबंधक बदलें" -#: ../src/ui/frames.c:1124 -msgid "Minimize Window" -msgstr "विंडो न्यूनतम करें" +#: ../src/core/main.c:188 +msgid "Specify session management ID" +msgstr "सत्र प्रबंधन ID निर्दिष्ट करें" -#: ../src/ui/frames.c:1127 -msgid "Maximize Window" -msgstr "विंडो अधिकतम करें" +#: ../src/core/main.c:193 +msgid "X Display to use" +msgstr "प्रयोग के लिये X प्रदर्शन" -#: ../src/ui/frames.c:1130 -#| msgid "Resize window" -msgid "Restore Window" -msgstr "विंडो फिर बहाल करें" +#: ../src/core/main.c:199 +msgid "Initialize session from savefile" +msgstr "सेवफाइल के लिये सत्र आरंभीकृत करें" -#: ../src/ui/frames.c:1133 -#| msgid "Roll _Up" -msgid "Roll Up Window" -msgstr "विंडो रॉल अप करें" - -#: ../src/ui/frames.c:1136 -#| msgid "Close Window" -msgid "Unroll Window" -msgstr "विंडो खोलें" - -#: ../src/ui/frames.c:1139 -msgid "Keep Window On Top" -msgstr "विंडो को सबसे ऊपर रखें" - -#: ../src/ui/frames.c:1142 -msgid "Remove Window From Top" -msgstr "ऊपर से विंडो हटाएं" - -#: ../src/ui/frames.c:1145 -#| msgid "_Always on Visible Workspace" -msgid "Always On Visible Workspace" -msgstr "हमेशा दृश्य कार्यस्थान पर" - -#: ../src/ui/frames.c:1148 -#| msgid "Toggle window on all workspaces" -msgid "Put Window On Only One Workspace" -msgstr "सिर्फ एक कार्यस्थान पर विंडो रखें" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:70 -msgid "Mi_nimize" -msgstr "न्यूनतम (_n)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:72 -msgid "Ma_ximize" -msgstr "अधिकतम (_x)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:74 -msgid "Unma_ximize" -msgstr "बड़े से छोटा करें (_x)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:76 -msgid "Roll _Up" -msgstr "उपर समेटें (_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:78 -msgid "_Unroll" -msgstr "वापस खोलें (_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:80 -msgid "_Move" -msgstr "खिसकाएँ (_M)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:82 -msgid "_Resize" -msgstr "आकार बदलें (_R)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:84 -msgid "Move Titlebar On_screen" -msgstr "ऑनस्क्रीन शीर्षकबार खिसकायें (_s)" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:87 ../src/ui/menu.c:89 -msgid "Always on _Top" -msgstr "हमेशा शीर्ष पर (_T)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:91 -msgid "_Always on Visible Workspace" -msgstr "हमेशा दृश्य कार्यस्थान पर (_A)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:93 -msgid "_Only on This Workspace" -msgstr "सिर्फ इसी कार्यस्थान पर (_O)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:95 -msgid "Move to Workspace _Left" -msgstr "बाएँ कार्यस्थान में ले जाएँ (_i)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:97 -msgid "Move to Workspace R_ight" -msgstr "दाएँ कार्यस्थान में ले जाएँ (_i)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:99 -msgid "Move to Workspace _Up" -msgstr "ऊपर कार्यस्थान में ले जाएँ (_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:101 -msgid "Move to Workspace _Down" -msgstr "नीचे कार्यस्थान में ले जाएँ (_D)" +#: ../src/core/main.c:205 +msgid "Make X calls synchronous" +msgstr "X कॉल तुल्यकालित करें" -# separator -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:105 -msgid "_Close" -msgstr "बंद करें (_C)" +#: ../src/core/main.c:212 +msgid "Run as a wayland compositor" +msgstr "वेलैंड कंपोजिटर के रूप में चलाएँ" -#: ../src/ui/menu.c:203 -#, c-format -#| msgid "Workspace %d" -msgid "Workspace %d%n" -msgstr "कार्यस्थान %d%n" +#: ../src/core/main.c:220 +msgid "Run as a full display server, rather than nested" +msgstr "पूर्ण डिस्प्ले सर्वर चलाएँ, संजालित के बनिस्बत" -#: ../src/ui/menu.c:213 +#: ../src/core/main.c:451 #, c-format -msgid "Workspace 1_0" -msgstr "कार्यस्थान 1_0" +msgid "Failed to scan themes directory: %s\n" +msgstr "प्रसंग डिरेक्ट्री स्कैन करने में असफल: %s\n" -#: ../src/ui/menu.c:215 +#: ../src/core/main.c:467 #, c-format -msgid "Workspace %s%d" -msgstr "कार्यस्थान %s%d" - -#: ../src/ui/menu.c:395 -msgid "Move to Another _Workspace" -msgstr "अन्य कार्यस्थान में ले जाएँ (_W)" - -# This is the text that should appear next to menu accelerators -# * that use the shift key. If the text on this key isn't typically -# * translated on keyboards used for your language, don't translate -# * this. -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:104 -msgid "Shift" -msgstr "शिफ़्ट" - -# This is the text that should appear next to menu accelerators -# * that use the control key. If the text on this key isn't typically -# * translated on keyboards used for your language, don't translate -# * this. -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:110 -msgid "Ctrl" -msgstr "कंट्रोल" - -# This is the text that should appear next to menu accelerators -# * that use the alt key. If the text on this key isn't typically -# * translated on keyboards used for your language, don't translate -# * this. -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:116 -msgid "Alt" -msgstr "आल्ट" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:122 -msgid "Meta" -msgstr "मेटा" - -# This is the text that should appear next to menu accelerators -# * that use the super key. If the text on this key isn't typically -# * translated on keyboards used for your language, don't translate -# * this. -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:128 -msgid "Super" -msgstr "सुपर" - -# This is the text that should appear next to menu accelerators -# * that use the hyper key. If the text on this key isn't typically -# * translated on keyboards used for your language, don't translate -# * this. -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:134 -msgid "Hyper" -msgstr "हाइपर" - -# This is the text that should appear next to menu accelerators -# * that use the mod2 key. If the text on this key isn't typically -# * translated on keyboards used for your language, don't translate -# * this. -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:140 -msgid "Mod2" -msgstr "परि.2" - -# This is the text that should appear next to menu accelerators -# * that use the mod3 key. If the text on this key isn't typically -# * translated on keyboards used for your language, don't translate -# * this. -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:146 -msgid "Mod3" -msgstr "परि.3" - -# This is the text that should appear next to menu accelerators -# * that use the mod4 key. If the text on this key isn't typically -# * translated on keyboards used for your language, don't translate -# * this. -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:152 -msgid "Mod4" -msgstr "परि.4" - -# This is the text that should appear next to menu accelerators -# * that use the mod5 key. If the text on this key isn't typically -# * translated on keyboards used for your language, don't translate -# * this. -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:158 -msgid "Mod5" -msgstr "परि.5" +msgid "" +"Could not find a theme! Be sure %s exists and contains the usual themes.\n" +msgstr "" +"प्रसंग नहीं ढूंढ सका! सुनिश्चित करें कि %s मौज़ूद है, तथा इसमें सामान्य " +"प्रसंग हैं.\n" -#: ../src/ui/metacity-dialog.c:90 +#: ../src/core/mutter.c:39 #, c-format -#| msgid "The window \"%s\" is not responding." -msgid "\"%s\" is not responding." -msgstr "\"%s\" प्रतिक्रिया नहीं दे रहा है." - -#: ../src/ui/metacity-dialog.c:97 msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "आप थोड़ी देर के लिए इसकी प्रतीक्षा के लिए चयन कर सकते हैं पूरी तरह से अनुप्रयोग के जारी रखने व छोड़ने के लिए दबाव दे सकते हैं." +"mutter %s\n" +"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" +msgstr "" +"mutter %s\n" +"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"यह मुफ्त सॉफ्टवेयर है; नकल की शर्ते के लिए स्रोत देखें.\n" +"यहाँ किसी प्रकार की वारंटी नहीं है; या किसी विशेष प्रयोजन के लिए " +"व्यापारिकता और " +"फिटनेस के लिए भी नहीं.\n" + +#: ../src/core/mutter.c:53 +msgid "Print version" +msgstr "मुद्रण संस्करण" -#: ../src/ui/metacity-dialog.c:107 -msgid "_Wait" -msgstr "प्रतीक्षा करें (_W)" +#: ../src/core/mutter.c:59 +msgid "Mutter plugin to use" +msgstr " उपयोग करने के लिए Mutter प्लगइन" -#: ../src/ui/metacity-dialog.c:109 -msgid "_Force Quit" -msgstr "जबर्दस्ती बाहर (_F)" - -# #-#-#-#-# libgnomeui.HEAD.hi.po (libgnomeui-2.0.hi) #-#-#-#-# -# libgnomeui/gnome-druid-page-standard.c:121 -# libgnomeui/gnome-font-picker.c:155 -#: ../src/ui/metacity-dialog.c:206 -msgid "Title" -msgstr "शीर्षक" +#: ../src/core/prefs.c:2065 +#, c-format +msgid "Workspace %d" +msgstr "कार्यस्थान %d" -#: ../src/ui/metacity-dialog.c:218 -msgid "Class" -msgstr "वर्ग" +#: ../src/core/screen.c:543 +#, c-format +msgid "Screen %d on display '%s' is invalid\n" +msgstr "स्क्रीन %d जो प्रदर्शक '%s' पर है वह अवैध है\n" -#: ../src/ui/metacity-dialog.c:244 +#: ../src/core/screen.c:559 +#, c-format msgid "" -"These windows do not support \"save current setup\" and will have to be " -"restarted manually next time you log in." +"Screen %d on display \"%s\" already has a window manager; try using the --" +"replace option to replace the current window manager.\n" msgstr "" -"ये विंडो \"वर्तमान सेटअप सहेजें\" समर्थन नहीं करते अतः इन्हें अगली बार जब आप लॉगइन करेंगे तब " -"पुनः प्रारंभ करना होगा." +"स्क्रीन %d जो प्रदर्शक \"%s\" पर है वहां पहले ही विंडो प्रबंधक है, --replace " +"विकल्प का " +"प्रयोग कर वर्तमान विंडो प्रबंधक को बदलने की कोशिश करें.\n" -#: ../src/ui/metacity-dialog.c:310 +#: ../src/core/screen.c:652 #, c-format -msgid "" -"There was an error running \"%s\":\n" -"%s." -msgstr "" -"\"%s\" को चलाने में त्रुटि थी:\n" -"%s." +msgid "Screen %d on display \"%s\" already has a window manager\n" +msgstr "स्क्रीन %d जो प्रदर्शक \"%s\" पर है वहां पहले ही विंडो प्रबंधक है\n" + +#: ../src/core/util.c:118 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter को वाचाल विधि के बगैर कम्पाइल किया गया है\n" #. Translators: This represents the size of a window. The first number is #. * the width of the window and the second is the height. #. -#: ../src/ui/resizepopup.c:113 +#: ../src/ui/resizepopup.c:134 #, c-format msgid "%d x %d" msgstr "%d x %d" -#: ../src/ui/theme.c:254 +#: ../src/ui/theme.c:233 msgid "top" msgstr "उपर" -#: ../src/ui/theme.c:256 +#: ../src/ui/theme.c:235 msgid "bottom" msgstr "नीचे" -#: ../src/ui/theme.c:258 +#: ../src/ui/theme.c:237 msgid "left" msgstr "बाएँ" -#: ../src/ui/theme.c:260 +#: ../src/ui/theme.c:239 msgid "right" msgstr "दाएँ" -#: ../src/ui/theme.c:287 +#: ../src/ui/theme.c:267 #, c-format msgid "frame geometry does not specify \"%s\" dimension" msgstr "फ्रेम ज्यामिती \"%s\" आयाम को उल्लेखित नहीं करता" -#: ../src/ui/theme.c:306 +#: ../src/ui/theme.c:286 #, c-format msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" msgstr "फ्रेम ज्यामिती आयाम \"%s\" को किनारा \"%s\" हेतु उल्लेखित नहीं करता" -#: ../src/ui/theme.c:343 +#: ../src/ui/theme.c:323 #, c-format msgid "Button aspect ratio %g is not reasonable" msgstr "बटन आस्पेक्ट रेशो %g यथोचित नहीं है" -#: ../src/ui/theme.c:355 +#: ../src/ui/theme.c:335 #, c-format msgid "Frame geometry does not specify size of buttons" msgstr "फ्रेम ज्यामिती बटनों के आकार को उल्लेखित नहीं करता" -#: ../src/ui/theme.c:1020 +#: ../src/ui/theme.c:1061 #, c-format msgid "Gradients should have at least two colors" msgstr "अनुपात में कम से कम दो रंग होने चाहिएँ" -#: ../src/ui/theme.c:1146 +#: ../src/ui/theme.c:1211 +#, c-format +msgid "" +"GTK custom color specification must have color name and fallback in " +"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" +msgstr "" +"कोष्ठक में जीटीके कस्टम रंग विनिर्देशन के लिए रंग का नाम और फ़ॉलबैक होना " +"चाहिए, जैसे gtk:" +"custom(foo,bar); \"%s\" विश्लेषित नहीं कर सका." + +#: ../src/ui/theme.c:1227 +#, c-format +msgid "" +"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" +"_ are valid" +msgstr "" +"जीटीके: कस्टम के color_name पैरामीटर में अमान्य वर्ण '%c', केवल A-za-Z0-9-_ " +"मान्य हैं" + +#: ../src/ui/theme.c:1241 +#, c-format +msgid "" +"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " +"fit the format" +msgstr "" +"Gtk:custom फॉर्मेट है \"\"gtk:custom(color_name,fallback)\", \"%s\" जो " +"फॉर्मेट के " +"अनुरूप नहीं होता" + +#: ../src/ui/theme.c:1286 #, c-format msgid "" "GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " "where NORMAL is the state; could not parse \"%s\"" msgstr "" -"जीटीके रंग लक्षण कोष्ठक में स्थिति (स्टेट) होने चाहिएँ जैसे- gtk:fg[NORMAL] यहाँ NORMAL " +"जीटीके रंग लक्षण कोष्ठक में स्थिति (स्टेट) होने चाहिएँ जैसे- gtk:fg[NORMAL] " +"यहाँ NORMAL " "स्थिति है; \"%s\" की व्याख्या नहीं कर सका" -#: ../src/ui/theme.c:1160 +#: ../src/ui/theme.c:1300 #, c-format msgid "" "GTK color specification must have a close bracket after the state, e.g. gtk:" "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" msgstr "" -"जीटीके रंग लक्षण स्थिति के बाद बंद कोष्ठक में होने चाहिएँ जैसे- gtk:fg[NORMAL] यहाँ " +"जीटीके रंग लक्षण स्थिति के बाद बंद कोष्ठक में होने चाहिएँ जैसे- " +"gtk:fg[NORMAL] यहाँ " "NORMAL स्थिति है; \"%s\" की व्याख्या नहीं कर सका" -#: ../src/ui/theme.c:1171 +#: ../src/ui/theme.c:1311 #, c-format msgid "Did not understand state \"%s\" in color specification" msgstr "स्थिति \"%s\" रंग लक्षण में समझ नहीं सका" -#: ../src/ui/theme.c:1184 +#: ../src/ui/theme.c:1324 #, c-format msgid "Did not understand color component \"%s\" in color specification" msgstr "रंग अवयव \"%s\" रंग लक्षण में समझ नहीं सका" -#: ../src/ui/theme.c:1214 +#: ../src/ui/theme.c:1352 #, c-format msgid "" "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " "format" msgstr "" -"ब्लेंड फ़ॉर्मेट है \"blend/bg_color/fg_color/alpha\", \"%s\" जो फ़ॉर्मेट के अनुरूप नहीं " +"ब्लेंड फ़ॉर्मेट है \"blend/bg_color/fg_color/alpha\", \"%s\" जो फ़ॉर्मेट के " +"अनुरूप नहीं " "होता" -#: ../src/ui/theme.c:1225 +#: ../src/ui/theme.c:1363 #, c-format msgid "Could not parse alpha value \"%s\" in blended color" msgstr "अल्फा मूल्य \"%s\" की ब्लेंडेड रंग में व्याख्या नहीं कर सका" -#: ../src/ui/theme.c:1235 +#: ../src/ui/theme.c:1373 #, c-format msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" msgstr "अल्फा मूल्य \"%s\" ब्लेंडेड रंग में 0.0 और 1.0 के बीच नहीं है" -#: ../src/ui/theme.c:1282 +#: ../src/ui/theme.c:1419 #, c-format -msgid "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "शेड फॉर्मेट है \"shade/base_color/factor\", \"%s\" जो फॉर्मेट के अनुरूप नहीं होता" +msgid "" +"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" +msgstr "" +"शेड फॉर्मेट है \"shade/base_color/factor\", \"%s\" जो फॉर्मेट के अनुरूप नहीं " +"होता" -#: ../src/ui/theme.c:1293 +#: ../src/ui/theme.c:1430 #, c-format msgid "Could not parse shade factor \"%s\" in shaded color" msgstr "शेड फैक्टर \"%s\" की आभायुक्त रंग में व्याख्या नहीं कर सका" -#: ../src/ui/theme.c:1303 +#: ../src/ui/theme.c:1440 #, c-format msgid "Shade factor \"%s\" in shaded color is negative" msgstr "शेड फैक्टर \"%s\" आभायुक्त रंग में ऋणात्मक है" -#: ../src/ui/theme.c:1332 +#: ../src/ui/theme.c:1469 #, c-format msgid "Could not parse color \"%s\"" msgstr "\"%s\" रंग की व्याख्या नहीं कर सका" -#: ../src/ui/theme.c:1582 +#: ../src/ui/theme.c:1778 #, c-format msgid "Coordinate expression contains character '%s' which is not allowed" msgstr "कोआर्डिनेट एक्सप्रेशन मे अक्षर '%s' है जो स्वीकार्य नहीं है" -#: ../src/ui/theme.c:1609 +#: ../src/ui/theme.c:1805 #, c-format msgid "" "Coordinate expression contains floating point number '%s' which could not be " "parsed" -msgstr "कोआर्डिनेट एक्सप्रेशन मे फ्लोटिंग पाइंट नम्बर '%s' है जिसकी व्याख्या नहीं की जा सकी" +msgstr "" +"कोआर्डिनेट एक्सप्रेशन मे फ्लोटिंग पाइंट नम्बर '%s' है जिसकी व्याख्या नहीं की " +"जा सकी" -#: ../src/ui/theme.c:1623 +#: ../src/ui/theme.c:1819 #, c-format msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "कोआर्डिनेट एक्सप्रेशन मे पूर्णांक '%s' है जिसकी व्याख्या नहीं की जा सकी" +msgstr "" +"कोआर्डिनेट एक्सप्रेशन मे पूर्णांक '%s' है जिसकी व्याख्या नहीं की जा सकी" -#: ../src/ui/theme.c:1745 +#: ../src/ui/theme.c:1940 #, c-format msgid "" "Coordinate expression contained unknown operator at the start of this text: " "\"%s\"" -msgstr "कोआर्डिनेट एक्सप्रेशन मे इस पाठ: \"%s\" के आरंभ में ही अज्ञात आपरेटर है " +msgstr "" +"कोआर्डिनेट एक्सप्रेशन मे इस पाठ: \"%s\" के आरंभ में ही अज्ञात आपरेटर है " -#: ../src/ui/theme.c:1802 +#: ../src/ui/theme.c:1997 #, c-format msgid "Coordinate expression was empty or not understood" msgstr "कोआर्डिनेट एक्सप्रेशन या खाली है या समझा नहीं जा सका" -#: ../src/ui/theme.c:1913 ../src/ui/theme.c:1923 ../src/ui/theme.c:1957 +#: ../src/ui/theme.c:2110 ../src/ui/theme.c:2120 ../src/ui/theme.c:2154 #, c-format msgid "Coordinate expression results in division by zero" msgstr "कोआर्डिनेट एक्सप्रेशन परिणाम शून्य से भाजक के रूप में मिला" -#: ../src/ui/theme.c:1965 +#: ../src/ui/theme.c:2162 #, c-format -msgid "Coordinate expression tries to use mod operator on a floating-point number" -msgstr "कोआर्डिनेट एक्सप्रेशन, फ्लोटिंग पाइंट नम्बर पर माड आपरेटर के उपयोग की कोशिश में" +msgid "" +"Coordinate expression tries to use mod operator on a floating-point number" +msgstr "" +"कोआर्डिनेट एक्सप्रेशन, फ्लोटिंग पाइंट नम्बर पर माड आपरेटर के उपयोग की कोशिश " +"में" -#: ../src/ui/theme.c:2021 +#: ../src/ui/theme.c:2218 #, c-format -msgid "Coordinate expression has an operator \"%s\" where an operand was expected" +msgid "" +"Coordinate expression has an operator \"%s\" where an operand was expected" msgstr "कोआर्डिनेट एक्सप्रेशन में एक आपरेटर \"%s\" है जबकि आपरेंड वांछित है" -#: ../src/ui/theme.c:2030 +#: ../src/ui/theme.c:2227 #, c-format msgid "Coordinate expression had an operand where an operator was expected" msgstr "कोआर्डिनेट एक्सप्रेशन में एक आपरेंड है जबकि आपरेटर वांछित है" -#: ../src/ui/theme.c:2038 +#: ../src/ui/theme.c:2235 #, c-format msgid "Coordinate expression ended with an operator instead of an operand" msgstr "कोआर्डिनेट एक्सप्रेशन एक आपरेटर से अंत हो रहा है एक आपरेंड के बदले" -#: ../src/ui/theme.c:2048 +#: ../src/ui/theme.c:2245 #, c-format msgid "" "Coordinate expression has operator \"%c\" following operator \"%c\" with no " "operand in between" -msgstr "कोआर्डिनेट एक्सप्रेशन में आपरेटर \"%c\" के बाद आपरेटर \"%c\" है बीच में कोई आपरेण्ड नहीं है" +msgstr "" +"कोआर्डिनेट एक्सप्रेशन में आपरेटर \"%c\" के बाद आपरेटर \"%c\" है बीच में कोई " +"आपरेण्ड नहीं है" -#: ../src/ui/theme.c:2195 ../src/ui/theme.c:2236 +#: ../src/ui/theme.c:2396 ../src/ui/theme.c:2441 #, c-format msgid "Coordinate expression had unknown variable or constant \"%s\"" msgstr "कोआर्डिनेट एक्सप्रेशन में अज्ञात चर या अचर \"%s\" है" -#: ../src/ui/theme.c:2290 +#: ../src/ui/theme.c:2495 #, c-format msgid "Coordinate expression parser overflowed its buffer." msgstr "कोआर्डिनेट एक्सप्रेशन विश्लेषक इसके बफर को ओवरफ्लो कर गया है." -#: ../src/ui/theme.c:2319 +#: ../src/ui/theme.c:2524 #, c-format msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "कोआर्डिनेट एक्सप्रेशन में बन्द लघुकोष्ठक है जिसमें कोई खुला कोष्ठक नहीं है" +msgstr "" +"कोआर्डिनेट एक्सप्रेशन में बन्द लघुकोष्ठक है जिसमें कोई खुला कोष्ठक नहीं है" -#: ../src/ui/theme.c:2383 +#: ../src/ui/theme.c:2588 #, c-format msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "कोआर्डिनेट एक्सप्रेशन में खुला लघुकोष्ठक है जिसमें कोई बंद कोष्ठक नहीं है" +msgstr "" +"कोआर्डिनेट एक्सप्रेशन में खुला लघुकोष्ठक है जिसमें कोई बंद कोष्ठक नहीं है" -#: ../src/ui/theme.c:2394 +#: ../src/ui/theme.c:2599 #, c-format msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "प्रतीत होता है कि कोआर्डिनेट एक्सप्रेशन में कोई आपरेटर या आपरेंड नहीं है" +msgstr "" +"प्रतीत होता है कि कोआर्डिनेट एक्सप्रेशन में कोई आपरेटर या आपरेंड नहीं है" -#: ../src/ui/theme.c:2596 ../src/ui/theme.c:2616 ../src/ui/theme.c:2636 +#: ../src/ui/theme.c:2812 ../src/ui/theme.c:2832 ../src/ui/theme.c:2852 #, c-format -#| msgid "Theme contained an expression \"%s\" that resulted in an error: %s\n" msgid "Theme contained an expression that resulted in an error: %s\n" msgstr "प्रसंग में एक अभिव्यक्ति है जिसके प्रतिफल में त्रुटि हुई: %s\n" -#: ../src/ui/theme.c:4187 +#: ../src/ui/theme.c:4455 #, c-format msgid "" "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " "specified for this frame style" msgstr "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> इस फ्रेम शैली हेतु " +"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> इस फ्रेम शैली " +"हेतु " "निर्दिष्ट किया जाना अनिवार्य है" -#: ../src/ui/theme.c:4695 ../src/ui/theme.c:4720 +#: ../src/ui/theme.c:4970 ../src/ui/theme.c:4995 #, c-format -msgid "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "नहीं है <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" +msgid "" +"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" +msgstr "" +"नहीं है <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -#: ../src/ui/theme.c:4764 +#: ../src/ui/theme.c:5041 #, c-format msgid "Failed to load theme \"%s\": %s\n" msgstr "प्रसंग \"%s\" लोड करने में असफल: %s\n" -#: ../src/ui/theme.c:4894 ../src/ui/theme.c:4901 ../src/ui/theme.c:4908 -#: ../src/ui/theme.c:4915 ../src/ui/theme.c:4922 +#: ../src/ui/theme.c:5177 ../src/ui/theme.c:5184 ../src/ui/theme.c:5191 +#: ../src/ui/theme.c:5198 ../src/ui/theme.c:5205 #, c-format msgid "No <%s> set for theme \"%s\"" msgstr "कोई <%s> सेट प्रसंग \"%s\" हेतु नहीं है" -#: ../src/ui/theme.c:4930 +#: ../src/ui/theme.c:5213 #, c-format msgid "" "No frame style set for window type \"%s\" in theme \"%s\", add a <window " "type=\"%s\" style_set=\"whatever\"/> element" msgstr "" -"विंडो प्रकार \"%s\" में प्रसंग \"%s\" में कोई फ्रेम स्टाइल नियत नहीं है, जोड़ें <window " +"विंडो प्रकार \"%s\" में प्रसंग \"%s\" में कोई फ्रेम स्टाइल नियत नहीं है, " +"जोड़ें <window " "type=\"%s\" style_set=\"whatever\"/> तत्व " -#: ../src/ui/theme.c:5383 ../src/ui/theme.c:5445 ../src/ui/theme.c:5508 +#: ../src/ui/theme.c:5620 ../src/ui/theme.c:5682 ../src/ui/theme.c:5745 #, c-format -msgid "User-defined constants must begin with a capital letter; \"%s\" does not" +msgid "" +"User-defined constants must begin with a capital letter; \"%s\" does not" msgstr "" -"उपयोगकर्ता द्वारा पारिभाषित स्थिरांक बड़े अक्षर से शुरू होने चाहिएँ, जो \"%s\" नहीं हो " +"उपयोगकर्ता द्वारा पारिभाषित स्थिरांक बड़े अक्षर से शुरू होने चाहिएँ, जो \"%" +"s\" नहीं हो " "रहा है" -#: ../src/ui/theme.c:5391 ../src/ui/theme.c:5453 ../src/ui/theme.c:5516 +#: ../src/ui/theme.c:5628 ../src/ui/theme.c:5690 ../src/ui/theme.c:5753 #, c-format msgid "Constant \"%s\" has already been defined" msgstr "स्थिरांक \"%s\" पहले ही पारिभाषित है" @@ -1941,562 +942,1538 @@ msgstr "स्थिरांक \"%s\" पहले ही पारिभा #. Translators: This means that an attribute which should have been found #. * on an XML element was not in fact found. #. -#: ../src/ui/theme-parser.c:202 +#: ../src/ui/theme-parser.c:234 #, c-format -#| msgid "No \"x\" attribute on element <%s>" msgid "No \"%s\" attribute on element <%s>" msgstr "कोई \"%s\" गुण तत्व <%s> पर नहीं " -#: ../src/ui/theme-parser.c:231 ../src/ui/theme-parser.c:249 +#: ../src/ui/theme-parser.c:263 ../src/ui/theme-parser.c:281 #, c-format msgid "Line %d character %d: %s" msgstr "पंक्ति %d अक्षर %d: %s" -#: ../src/ui/theme-parser.c:413 +#: ../src/ui/theme-parser.c:481 #, c-format msgid "Attribute \"%s\" repeated twice on the same <%s> element" msgstr "गुण \"%s\" दो बार इसी <%s> तत्व पर दोहराया गया" -#: ../src/ui/theme-parser.c:437 ../src/ui/theme-parser.c:480 +#: ../src/ui/theme-parser.c:505 ../src/ui/theme-parser.c:554 #, c-format msgid "Attribute \"%s\" is invalid on <%s> element in this context" msgstr "गुण \"%s\", <%s> तत्व इस संदर्भ में अवैध है " -#: ../src/ui/theme-parser.c:541 +#: ../src/ui/theme-parser.c:596 +#, c-format +msgid "Could not parse \"%s\" as an integer" +msgstr "\"%s\" को पूर्णांक की तरह व्याख्या नहीं कर सका" + +#: ../src/ui/theme-parser.c:605 ../src/ui/theme-parser.c:660 +#, c-format +msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +msgstr "पुछल्ले अक्षरों \"%s\" को स्ट्रिंग \"%s\" में समझ नहीं सका" + +#: ../src/ui/theme-parser.c:615 #, c-format msgid "Integer %ld must be positive" msgstr "पूर्णांक %ld धनात्मक होना ही चाहिए" -#: ../src/ui/theme-parser.c:549 +#: ../src/ui/theme-parser.c:623 #, c-format msgid "Integer %ld is too large, current max is %d" msgstr "पूर्णांक %ld बहुत बड़ा है, वर्तमान अधिकतम है %d" -#: ../src/ui/theme-parser.c:577 ../src/ui/theme-parser.c:693 +#: ../src/ui/theme-parser.c:651 ../src/ui/theme-parser.c:767 #, c-format msgid "Could not parse \"%s\" as a floating point number" msgstr "\"%s\" की फ्लोटिंग पाइंट संख्या की तरह व्याख्या नहीं कर सका" -#: ../src/ui/theme-parser.c:608 ../src/ui/theme-parser.c:636 +#: ../src/ui/theme-parser.c:682 ../src/ui/theme-parser.c:710 #, c-format msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" msgstr "बूलियन मूल्य होने चाहिएँ - \"सही\" या \"गलत\" न कि \"%s\"" -#: ../src/ui/theme-parser.c:663 +#: ../src/ui/theme-parser.c:737 #, c-format msgid "Angle must be between 0.0 and 360.0, was %g\n" msgstr "कोण 0.0 और 360.0, के बीच होना चाहिए, जो था %g\n" -#: ../src/ui/theme-parser.c:726 +#: ../src/ui/theme-parser.c:800 #, c-format msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "अल्फा 0.0 (अदृश्य) और 1.0 (पूर्ण अपारदर्शी), के बीच होना चाहिए, जो था %g\n" +msgstr "" +"अल्फा 0.0 (अदृश्य) और 1.0 (पूर्ण अपारदर्शी), के बीच होना चाहिए, जो था %g\n" -#: ../src/ui/theme-parser.c:791 +#: ../src/ui/theme-parser.c:865 #, c-format msgid "" "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," "large,x-large,xx-large)\n" msgstr "" -"अवैध शीर्षक स्केल \"%s\" (इसमें से एक होना चाहिएः xx-small,x-small,small,medium," +"अवैध शीर्षक स्केल \"%s\" (इसमें से एक होना चाहिएः " +"xx-small,x-small,small,medium," "large,x-large,xx-large)\n" -#: ../src/ui/theme-parser.c:936 ../src/ui/theme-parser.c:999 -#: ../src/ui/theme-parser.c:1033 ../src/ui/theme-parser.c:1136 +#: ../src/ui/theme-parser.c:1021 ../src/ui/theme-parser.c:1084 +#: ../src/ui/theme-parser.c:1118 ../src/ui/theme-parser.c:1221 #, c-format msgid "<%s> name \"%s\" used a second time" msgstr "<%s> नाम \"%s\" दूसरी बार उपयोग में" -#: ../src/ui/theme-parser.c:948 ../src/ui/theme-parser.c:1045 -#: ../src/ui/theme-parser.c:1148 +#: ../src/ui/theme-parser.c:1033 ../src/ui/theme-parser.c:1130 +#: ../src/ui/theme-parser.c:1233 #, c-format msgid "<%s> parent \"%s\" has not been defined" msgstr "<%s> मूल \"%s\" पारिभाषित नहीं है." -#: ../src/ui/theme-parser.c:1058 +#: ../src/ui/theme-parser.c:1143 #, c-format msgid "<%s> geometry \"%s\" has not been defined" msgstr "<%s>ज्यामिती \"%s\" पारिभाषित नहीं है." -#: ../src/ui/theme-parser.c:1071 +#: ../src/ui/theme-parser.c:1156 #, c-format msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "<%s> को या तो ज्यामिती या मूल जिसमें ज्यामिती हो, को निर्दिष्ट करना होगा" +msgstr "" +"<%s> को या तो ज्यामिती या मूल जिसमें ज्यामिती हो, को निर्दिष्ट करना होगा" -#: ../src/ui/theme-parser.c:1113 +#: ../src/ui/theme-parser.c:1198 msgid "You must specify a background for an alpha value to be meaningful" -msgstr "आप अल्फा मान के लिए अर्थपूर्ण होने के लिए जरूर पृष्ठभूमि निर्दिष्ट करें" +msgstr "" +"आप अल्फा मान के लिए अर्थपूर्ण होने के लिए जरूर पृष्ठभूमि निर्दिष्ट करें" -#: ../src/ui/theme-parser.c:1180 +#: ../src/ui/theme-parser.c:1266 #, c-format msgid "Unknown type \"%s\" on <%s> element" msgstr "अज्ञात प्रकार \"%s\" तत्व <%s> पर नहीं " -#: ../src/ui/theme-parser.c:1191 +#: ../src/ui/theme-parser.c:1277 #, c-format msgid "Unknown style_set \"%s\" on <%s> element" msgstr "अज्ञात स्टाइल-सेट \"%s\" तत्व <%s> पर नहीं " -#: ../src/ui/theme-parser.c:1199 +#: ../src/ui/theme-parser.c:1285 #, c-format msgid "Window type \"%s\" has already been assigned a style set" msgstr "विंडो प्रकार \"%s\" को पहले ही एक स्टाइल सेट आबंटित है" -#: ../src/ui/theme-parser.c:1229 ../src/ui/theme-parser.c:1293 -#: ../src/ui/theme-parser.c:1519 ../src/ui/theme-parser.c:2732 -#: ../src/ui/theme-parser.c:2778 ../src/ui/theme-parser.c:2926 -#: ../src/ui/theme-parser.c:3118 ../src/ui/theme-parser.c:3156 -#: ../src/ui/theme-parser.c:3194 ../src/ui/theme-parser.c:3232 +#: ../src/ui/theme-parser.c:1315 ../src/ui/theme-parser.c:1379 +#: ../src/ui/theme-parser.c:1605 ../src/ui/theme-parser.c:2840 +#: ../src/ui/theme-parser.c:2886 ../src/ui/theme-parser.c:3036 +#: ../src/ui/theme-parser.c:3272 ../src/ui/theme-parser.c:3310 +#: ../src/ui/theme-parser.c:3348 ../src/ui/theme-parser.c:3386 #, c-format msgid "Element <%s> is not allowed below <%s>" msgstr "तत्व <%s>, <%s>से नीचे स्वीकार्य नहीं है" -#: ../src/ui/theme-parser.c:1343 ../src/ui/theme-parser.c:1357 -#: ../src/ui/theme-parser.c:1402 -#| msgid "" -#| "Cannot specify both button_width/button_height and aspect ratio for " -#| "buttons" +#: ../src/ui/theme-parser.c:1429 ../src/ui/theme-parser.c:1443 +#: ../src/ui/theme-parser.c:1488 msgid "" "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " "for buttons" -msgstr "बटनों हेतु \"button_width\"/\"button_height\" और \"aspect_ratio\" निर्दिष्ट नहीं कर सका" +msgstr "" +"बटनों हेतु \"button_width\"/\"button_height\" और \"aspect_ratio\" निर्दिष्ट " +"नहीं " +"कर सका" -#: ../src/ui/theme-parser.c:1366 +#: ../src/ui/theme-parser.c:1452 #, c-format msgid "Distance \"%s\" is unknown" msgstr "दूरी \"%s\" अज्ञात है" -#: ../src/ui/theme-parser.c:1411 +#: ../src/ui/theme-parser.c:1497 #, c-format msgid "Aspect ratio \"%s\" is unknown" msgstr "आकृति अनुपात \"%s\" अज्ञात है" -#: ../src/ui/theme-parser.c:1473 +#: ../src/ui/theme-parser.c:1559 #, c-format msgid "Border \"%s\" is unknown" msgstr "किनारा \"%s\" अज्ञात है" -#: ../src/ui/theme-parser.c:1776 +#: ../src/ui/theme-parser.c:1870 #, c-format -#| msgid "No \"start_angle\" attribute on element <%s>" msgid "No \"start_angle\" or \"from\" attribute on element <%s>" msgstr "कोई \"start_angle\" या \"from\" गुण तत्व <%s> पर नहीं " -#: ../src/ui/theme-parser.c:1783 +#: ../src/ui/theme-parser.c:1877 #, c-format -#| msgid "No \"extent_angle\" attribute on element <%s>" msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" msgstr "कोई \"extent_angle\" या \"to\" गुण तत्व <%s> पर नहीं " -#: ../src/ui/theme-parser.c:2023 +#: ../src/ui/theme-parser.c:2117 #, c-format msgid "Did not understand value \"%s\" for type of gradient" msgstr "ग्रेडिएंट प्रकार हेतु मान \"%s\" समझ नहीं पाया" -#: ../src/ui/theme-parser.c:2101 ../src/ui/theme-parser.c:2476 +#: ../src/ui/theme-parser.c:2195 ../src/ui/theme-parser.c:2570 #, c-format msgid "Did not understand fill type \"%s\" for <%s> element" msgstr "तत्व <%s> हेतु भराव प्रकार \"%s\" समझ नहीं पाया" -#: ../src/ui/theme-parser.c:2268 ../src/ui/theme-parser.c:2351 -#: ../src/ui/theme-parser.c:2414 +#: ../src/ui/theme-parser.c:2362 ../src/ui/theme-parser.c:2445 +#: ../src/ui/theme-parser.c:2508 #, c-format msgid "Did not understand state \"%s\" for <%s> element" msgstr "तत्व <%s> हेतु स्थिति \"%s\" समझ नहीं पाया" -#: ../src/ui/theme-parser.c:2278 ../src/ui/theme-parser.c:2361 +#: ../src/ui/theme-parser.c:2372 ../src/ui/theme-parser.c:2455 #, c-format msgid "Did not understand shadow \"%s\" for <%s> element" msgstr "तत्व <%s> हेतु छाया \"%s\" समझ नहीं पाया" -#: ../src/ui/theme-parser.c:2288 +#: ../src/ui/theme-parser.c:2382 #, c-format msgid "Did not understand arrow \"%s\" for <%s> element" msgstr "तत्व <%s> हेतु एरो \"%s\" समझ नहीं पाया" -#: ../src/ui/theme-parser.c:2588 ../src/ui/theme-parser.c:2684 +#: ../src/ui/theme-parser.c:2696 ../src/ui/theme-parser.c:2792 #, c-format msgid "No <draw_ops> called \"%s\" has been defined" msgstr "कोई <draw_ops> \"%s\" नाम से पारिभाषित नहीं है" -#: ../src/ui/theme-parser.c:2600 ../src/ui/theme-parser.c:2696 +#: ../src/ui/theme-parser.c:2708 ../src/ui/theme-parser.c:2804 #, c-format msgid "Including draw_ops \"%s\" here would create a circular reference" msgstr "draw_ops यहाँ: \"%s\" जोड़ने से सर्कुलर रेफरेंस बन जाएगा" -#: ../src/ui/theme-parser.c:2811 +#: ../src/ui/theme-parser.c:2919 #, c-format msgid "Unknown position \"%s\" for frame piece" msgstr "अज्ञात स्थिति \"%s\" फ्रेम पीस हेतु" -#: ../src/ui/theme-parser.c:2819 +#: ../src/ui/theme-parser.c:2927 #, c-format msgid "Frame style already has a piece at position %s" msgstr "स्थिति %s पर फ्रेम शैली के पास पहले ही एक पीस है" -#: ../src/ui/theme-parser.c:2836 ../src/ui/theme-parser.c:2911 +#: ../src/ui/theme-parser.c:2944 ../src/ui/theme-parser.c:3021 #, c-format msgid "No <draw_ops> with the name \"%s\" has been defined" msgstr "कोई भी <draw_ops> नाम \"%s\" के साथ पारिभाषित नहीं है" -#: ../src/ui/theme-parser.c:2865 +#: ../src/ui/theme-parser.c:2974 #, c-format msgid "Unknown function \"%s\" for button" msgstr "अज्ञात फंक्शन बटन \"%s\" हेतु" -#: ../src/ui/theme-parser.c:2874 +#: ../src/ui/theme-parser.c:2984 #, c-format msgid "Button function \"%s\" does not exist in this version (%d, need %d)" msgstr "बटन फंक्शन \"%s\" इस संस्करण (%d, need %d) में मौजूद नहीं है" -#: ../src/ui/theme-parser.c:2886 +#: ../src/ui/theme-parser.c:2996 #, c-format msgid "Unknown state \"%s\" for button" msgstr "अज्ञात स्थिति बटन \"%s\" हेतु" -#: ../src/ui/theme-parser.c:2894 +#: ../src/ui/theme-parser.c:3004 #, c-format msgid "Frame style already has a button for function %s state %s" msgstr "फंक्शन %s स्थिति %s हेतु फ्रेम शैली में पहले ही एक बटन है" -#: ../src/ui/theme-parser.c:2965 +#: ../src/ui/theme-parser.c:3075 #, c-format msgid "\"%s\" is not a valid value for focus attribute" msgstr "\"%s\" फ़ोकस गुण हेतु वैध मूल्य नहीं है" -#: ../src/ui/theme-parser.c:2974 +#: ../src/ui/theme-parser.c:3084 #, c-format msgid "\"%s\" is not a valid value for state attribute" msgstr "\"%s\" स्थिति गुण हेतु वैध मूल्य नहीं है" -#: ../src/ui/theme-parser.c:2984 +#: ../src/ui/theme-parser.c:3094 #, c-format msgid "A style called \"%s\" has not been defined" msgstr "शैली \"%s\" पारिभाषित नहीं है" -#: ../src/ui/theme-parser.c:3005 ../src/ui/theme-parser.c:3028 +#: ../src/ui/theme-parser.c:3115 ../src/ui/theme-parser.c:3138 #, c-format msgid "\"%s\" is not a valid value for resize attribute" msgstr "\"%s\" नया आकार गुण हेतु वैध मूल्य नहीं है" -#: ../src/ui/theme-parser.c:3039 +#: ../src/ui/theme-parser.c:3149 #, c-format msgid "" "Should not have \"resize\" attribute on <%s> element for maximized/shaded " "states" msgstr "\"नया-आकार\" गुण <%s> तत्व पर अधिकतम/आभायुक्त स्थिति हेतु नहीं है " -#: ../src/ui/theme-parser.c:3053 +#: ../src/ui/theme-parser.c:3163 #, c-format -#| msgid "" -#| "Should not have \"resize\" attribute on <%s> element for maximized/shaded " -#| "states" -msgid "Should not have \"resize\" attribute on <%s> element for maximized states" +msgid "" +"Should not have \"resize\" attribute on <%s> element for maximized states" msgstr "\"resize\" गुण को अधिकतम स्थिति के लिए <%s> तत्व पर नहीं रखना चाहिए" -#: ../src/ui/theme-parser.c:3067 ../src/ui/theme-parser.c:3089 +#: ../src/ui/theme-parser.c:3177 ../src/ui/theme-parser.c:3221 #, c-format msgid "Style has already been specified for state %s resize %s focus %s" msgstr "शैली पहले ही स्थिति %s नया-आकार %s फ़ोकस %s हेतु निर्दिष्ट है" -#: ../src/ui/theme-parser.c:3078 ../src/ui/theme-parser.c:3100 +#: ../src/ui/theme-parser.c:3188 ../src/ui/theme-parser.c:3199 +#: ../src/ui/theme-parser.c:3210 ../src/ui/theme-parser.c:3232 +#: ../src/ui/theme-parser.c:3243 ../src/ui/theme-parser.c:3254 #, c-format msgid "Style has already been specified for state %s focus %s" msgstr "शैली पहले ही स्थिति %s फ़ोकस %s हेतु निर्दिष्ट है" -#: ../src/ui/theme-parser.c:3139 +#: ../src/ui/theme-parser.c:3293 msgid "" "Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " "attribute and also a <draw_ops> element, or specified two elements)" msgstr "" -"दो draw_ops नहीं हो सकते एक <पीस> तत्व हेतु (प्रसंग ने बटन किया एक draw_ops एट्रिब्यूट " +"दो draw_ops नहीं हो सकते एक <पीस> तत्व हेतु (प्रसंग ने बटन किया एक draw_ops " +"एट्रिब्यूट " "तथा एक और <draw_ops> तत्व, या बटन किया दो तत्व )" -#: ../src/ui/theme-parser.c:3177 +#: ../src/ui/theme-parser.c:3331 msgid "" "Can't have a two draw_ops for a <button> element (theme specified a draw_ops " "attribute and also a <draw_ops> element, or specified two elements)" msgstr "" -"दो draw_ops नहीं हो सकते एक <बटन> तत्व हेतु (प्रसंग ने निर्दिष्ट किया एक draw_ops " +"दो draw_ops नहीं हो सकते एक <बटन> तत्व हेतु (प्रसंग ने निर्दिष्ट किया एक " +"draw_ops " "एट्रिब्यूट तथा एक और <draw_ops> तत्व, या निर्दिष्ट किया दो तत्व)" -#: ../src/ui/theme-parser.c:3215 +#: ../src/ui/theme-parser.c:3369 msgid "" "Can't have a two draw_ops for a <menu_icon> element (theme specified a " "draw_ops attribute and also a <draw_ops> element, or specified two elements)" msgstr "" -"दो draw_ops नहीं हो सकते एक <मेनू-चिह्न> तत्व हेतु (प्रसंग ने निर्दिष्ट किया एक draw_ops " +"दो draw_ops नहीं हो सकते एक <मेनू-चिह्न> तत्व हेतु (प्रसंग ने निर्दिष्ट किया " +"एक draw_ops " "एट्रिब्यूट तथा एक और <draw_ops> तत्व, या निर्दिष्ट किया दो तत्व)" -#: ../src/ui/theme-parser.c:3263 +#: ../src/ui/theme-parser.c:3433 +#, c-format +msgid "Bad version specification '%s'" +msgstr "गलत संस्करण विनिर्देशन '%s'पोर्ट" + +#: ../src/ui/theme-parser.c:3506 +msgid "" +"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" +"theme-2.xml" +msgstr "" +"\"संस्करण\" विशेषता मेटासिटी विषय 1.xml या मेटासिटी विषय 2.xml में उपयोग नहीं " +"किया " +"जा सकता है." + +#: ../src/ui/theme-parser.c:3529 +#, c-format +msgid "Theme requires version %s but latest supported theme version is %d.%d" +msgstr "" +"विषय को संस्करण %s की आवश्यकता है लेकिन नवीनतम समर्थित विषय संस्करण%d.%d है." + +#: ../src/ui/theme-parser.c:3561 #, c-format msgid "Outermost element in theme must be <metacity_theme> not <%s>" msgstr "प्रसंग का सबसे बाहरी तत्व <मेटासिटी-प्रसंग> होना चाहिए न कि <%s>" -#: ../src/ui/theme-parser.c:3283 +#: ../src/ui/theme-parser.c:3581 #, c-format -msgid "Element <%s> is not allowed inside a name/author/date/description element" -msgstr "तत्व <%s>, एक name/author/date/description तत्व के भीतर स्वीकार्य नहीं है" +msgid "" +"Element <%s> is not allowed inside a name/author/date/description element" +msgstr "" +"तत्व <%s>, एक name/author/date/description तत्व के भीतर स्वीकार्य नहीं है" -#: ../src/ui/theme-parser.c:3288 +#: ../src/ui/theme-parser.c:3586 #, c-format msgid "Element <%s> is not allowed inside a <constant> element" msgstr "तत्व <%s> <स्थिरांक> तत्व के भीतर स्वीकार्य नहीं है" -#: ../src/ui/theme-parser.c:3300 +#: ../src/ui/theme-parser.c:3598 #, c-format -msgid "Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "तत्व <%s>, distance/border/aspect_ratio तत्व के भीतर स्वीकार्य नहीं है" +msgid "" +"Element <%s> is not allowed inside a distance/border/aspect_ratio element" +msgstr "" +"तत्व <%s>, distance/border/aspect_ratio तत्व के भीतर स्वीकार्य नहीं है" -#: ../src/ui/theme-parser.c:3322 +#: ../src/ui/theme-parser.c:3620 #, c-format msgid "Element <%s> is not allowed inside a draw operation element" msgstr "तत्व <%s>, ड्रा ऑपरेशन तत्व के भीतर स्वीकार्य नहीं है" -#: ../src/ui/theme-parser.c:3332 ../src/ui/theme-parser.c:3362 -#: ../src/ui/theme-parser.c:3367 ../src/ui/theme-parser.c:3372 +#: ../src/ui/theme-parser.c:3630 ../src/ui/theme-parser.c:3660 +#: ../src/ui/theme-parser.c:3665 ../src/ui/theme-parser.c:3670 #, c-format msgid "Element <%s> is not allowed inside a <%s> element" msgstr "तत्व <%s>, एक <%s> तत्व के भीतर स्वीकार्य नहीं है" -#: ../src/ui/theme-parser.c:3594 +#: ../src/ui/theme-parser.c:3898 msgid "No draw_ops provided for frame piece" msgstr "फ्रेम पीस हेतु कोई draw_ops नहीं दिया गया है" -#: ../src/ui/theme-parser.c:3609 +#: ../src/ui/theme-parser.c:3913 msgid "No draw_ops provided for button" msgstr "बटन हेतु कोई draw_ops नहीं दिया गया है" -#: ../src/ui/theme-parser.c:3661 +#: ../src/ui/theme-parser.c:3967 #, c-format msgid "No text is allowed inside element <%s>" msgstr "कोई पाठ तत्व <%s> के भीतर स्वीकार्य नहीं है" -#: ../src/ui/theme-parser.c:3716 -msgid "<name> specified twice for this theme" -msgstr "<नाम> इस प्रसंग हेतु दोबार उल्लेखित किया गया है" - -#: ../src/ui/theme-parser.c:3727 -msgid "<author> specified twice for this theme" -msgstr "<लेखक> इस प्रसंग हेतु दोबार उल्लेखित किया गया है" - -#: ../src/ui/theme-parser.c:3738 -msgid "<copyright> specified twice for this theme" -msgstr " <सर्वाधिकार सुरक्षित> इस प्रसंग हेतु दोबार उल्लेखित किया गया है" - -#: ../src/ui/theme-parser.c:3749 -msgid "<date> specified twice for this theme" -msgstr "<तिथि> इस प्रसंग हेतु दोबार उल्लेखित किया गया है" - -#: ../src/ui/theme-parser.c:3760 -msgid "<description> specified twice for this theme" -msgstr " <विवरण> इस प्रसंग हेतु दोबार उल्लेखित किया गया है" +#: ../src/ui/theme-parser.c:4025 ../src/ui/theme-parser.c:4037 +#: ../src/ui/theme-parser.c:4049 ../src/ui/theme-parser.c:4061 +#: ../src/ui/theme-parser.c:4073 +#, c-format +msgid "<%s> specified twice for this theme" +msgstr "<%s> ने इस प्रसंग के लिए दो बार निर्दिष्ट किया है" -#: ../src/ui/theme-parser.c:4027 +#: ../src/ui/theme-parser.c:4335 #, c-format -#| msgid "Failed to fdopen() log file %s: %s\n" msgid "Failed to find a valid file for theme %s\n" msgstr "%s प्रसंग के लिए वैध फाइल पाने में विफल\n" -#: ../src/ui/theme-parser.c:4083 +#: ../src/x11/session.c:1815 +msgid "" +"These windows do not support "save current setup" and will have to " +"be restarted manually next time you log in." +msgstr "" +"ये विंडो "save current setup" समर्थन नहीं करते अतः इन्हें अगली बार " +"जब आप " +"लॉगइन करेंगे तब पुनः प्रारंभ करना होगा." + +#: ../src/x11/window-props.c:515 #, c-format -msgid "Theme file %s did not contain a root <metacity_theme> element" -msgstr "प्रसंग फ़ाइल %s में रूट <मेटासिटी-प्रसंग> तत्व सम्मिलित नहीं है" +msgid "%s (on %s)" +msgstr "%s (%s पर)" -#: ../src/ui/theme-viewer.c:75 -msgid "/_Windows" -msgstr "/विंडोज़ (_W)" +#~ msgid "background texture could not be created from file" +#~ msgstr "फ़ाइल से पृष्ठभूमि टेक्चर नहीं बनाया जा सकता है" -#: ../src/ui/theme-viewer.c:76 -msgid "/Windows/tearoff" -msgstr "/विंडोज़/टीयरऑफ़" +#~ msgid "Unknown window information request: %d" +#~ msgstr "अज्ञात विंडो सूचना आग्रह: %d" -#: ../src/ui/theme-viewer.c:77 -msgid "/Windows/_Dialog" -msgstr "/विंडोज़/संवाद (_D)" +#~ msgid "Missing %s extension required for compositing" +#~ msgstr "अनुपस्थित %s विस्तार कंपोजिटिंग के लिए जरूरी है" -#: ../src/ui/theme-viewer.c:78 -msgid "/Windows/_Modal dialog" -msgstr "/विंडोज़/मॉडल संवाद (_M)" +#~ msgid "" +#~ "Some other program is already using the key %s with modifiers %x as a " +#~ "binding\n" +#~ msgstr "" +#~ "कोई अन्य प्रोग्राम पहले से ही कुंजी %s उपयोग में ले रहा है, परिवर्धक %x बाइंडिंग के रूप " +#~ "में \n" -#: ../src/ui/theme-viewer.c:79 -msgid "/Windows/_Utility" -msgstr "/विंडोज़/यूटिलिटी (_U)" +#~| msgid "\"%s\" is not a valid value for focus attribute" +#~ msgid "\"%s\" is not a valid accelerator\n" +#~ msgstr "\"%s\" एक मान्य त्वरक नहीं है\n" -#: ../src/ui/theme-viewer.c:80 -msgid "/Windows/_Splashscreen" -msgstr "/विंडोज़/स्प्लैशस्क्रीन (_S)" +#~ msgid "" +#~ "Workarounds for broken applications disabled. Some applications may not " +#~ "behave properly.\n" +#~ msgstr "" +#~ "टूटे अनुप्रयोगों हेतु वर्कअराउन्ड अक्षम किया हुआ है. हो सकता है कुछ अनुप्रयोग उचित प्रकार " +#~ "व्यवहार न करें.\n" -#: ../src/ui/theme-viewer.c:81 -msgid "/Windows/_Top dock" -msgstr "/विंडोज़/शीर्ष डॉक (_T)" +#~ msgid "Could not parse font description \"%s\" from GSettings key %s\n" +#~ msgstr "GSettings कुंजी %s से वर्णन फ़ॉन्ट \"%s\" का व्याख्या नहीं कर सका.\n" -#: ../src/ui/theme-viewer.c:82 -msgid "/Windows/_Bottom dock" -msgstr "/विंडोज़/निचला डॉक (_B)" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" +#~ msgstr "कॉन्फ़िगरेशन डेटाबेस में प्राप्त \"%s\" माउस बटन मॉडीफ़ायर वैध मूल्य नहीं है\n" -#: ../src/ui/theme-viewer.c:83 -msgid "/Windows/_Left dock" -msgstr "/विंडोज़/बायाँ डॉक (_L)" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for " +#~ "keybinding \"%s\"\n" +#~ msgstr "कॉन्फ़िगरेशन डेटाबेस में प्राप्त \"%s\" कीबाइंडिंग \"%s\" हेतु वैध मूल्य नहीं है\n" -#: ../src/ui/theme-viewer.c:84 -msgid "/Windows/_Right dock" -msgstr "/विंडोज़/दायाँ डॉक (_R)" +#~ msgid "" +#~ "Could not acquire window manager selection on screen %d display \"%s\"\n" +#~ msgstr "स्क्रीन %d प्रदर्शक \"%s\" पर विंडो प्रबंधक चयन प्राप्त नहीं कर सका\n" -#: ../src/ui/theme-viewer.c:85 -msgid "/Windows/_All docks" -msgstr "/विंडोज़/सभी डॉक्स (_A)" +#~ msgid "Could not release screen %d on display \"%s\"\n" +#~ msgstr "स्क्रीन %d जो प्रदर्शक \"%s\" पर है को मुक्त नहीं कर सका\n" -#: ../src/ui/theme-viewer.c:86 -msgid "/Windows/Des_ktop" -msgstr "/विंडोज़/डेस्कटॉप (_k)" +#~ msgid "Could not create directory '%s': %s\n" +#~ msgstr "डिरेक्ट्री '%s' बना नहीं पाया: %s\n" -#: ../src/ui/theme-viewer.c:135 -msgid "Open another one of these windows" -msgstr "इनमें से एक अन्य विंडो खोलें" +#~ msgid "Could not open session file '%s' for writing: %s\n" +#~ msgstr "सत्र फ़ाइल '%s' लिखने हेतु नही खोल पाया: %s\n" -#: ../src/ui/theme-viewer.c:142 -msgid "This is a demo button with an 'open' icon" -msgstr "यह 'खोलें' चिह्न युक्त एक डेमो बटन है" +#~ msgid "Error writing session file '%s': %s\n" +#~ msgstr "स्त्र फ़ाइल लिखने में त्रुटि '%s': %s\n" -#: ../src/ui/theme-viewer.c:149 -msgid "This is a demo button with a 'quit' icon" -msgstr "यह एक डेमो बटन है 'बाहर' चिह्न के साथ" +#~ msgid "Error closing session file '%s': %s\n" +#~ msgstr "सत्र फ़ाइल बंद करने में त्रुटि '%s': %s\n" -#: ../src/ui/theme-viewer.c:242 -msgid "This is a sample message in a sample dialog" -msgstr "यह नमूना संवाद में नमूना संदेश था" +#~ msgid "Failed to parse saved session file: %s\n" +#~ msgstr "सहेजी गई सत्र फ़ाइल: %s की व्याख्या करने में असफल\n" -#: ../src/ui/theme-viewer.c:325 -#, c-format -msgid "Fake menu item %d\n" -msgstr "नकली मेनू वस्तु %d\n" +#~ msgid "<mutter_session> attribute seen but we already have the session ID" +#~ msgstr "<mutter_session> गुण देखा पर हमारे पास पहले ही सत्र आईडी है" -#: ../src/ui/theme-viewer.c:359 -msgid "Border-only window" -msgstr "सिर्फ-किनारा विंडो" +#~ msgid "Unknown attribute %s on <%s> element" +#~ msgstr "अज्ञात विशेषता %s <%s> तत्व पर" -#: ../src/ui/theme-viewer.c:361 -msgid "Bar" -msgstr "पट्टी" +#~ msgid "nested <window> tag" +#~ msgstr "नेस्टेड <window> टैग" -#: ../src/ui/theme-viewer.c:378 -msgid "Normal Application Window" -msgstr "सामान्य अनुप्रयोग विंडो" +#~ msgid "Unknown element %s" +#~ msgstr "अज्ञात तत्व %s" -#: ../src/ui/theme-viewer.c:382 -msgid "Dialog Box" -msgstr "संवाद बक्सा" +#~ msgid "Failed to open debug log: %s\n" +#~ msgstr "डिबग लॉग: %s खोलने में असफल\n" -#: ../src/ui/theme-viewer.c:386 -msgid "Modal Dialog Box" -msgstr "मॉडल संवाद बक्सा" +#~ msgid "Failed to fdopen() log file %s: %s\n" +#~ msgstr "लॉग फ़ाइल %s: fdopen() में असफल %s\n" -#: ../src/ui/theme-viewer.c:390 -msgid "Utility Palette" -msgstr "यूटिलिटी पट्टिका" +#~ msgid "Opened log file %s\n" +#~ msgstr "लॉग फ़ाइल %s खोला\n" -#: ../src/ui/theme-viewer.c:394 -msgid "Torn-off Menu" -msgstr "टॉर्न-ऑफ मेनू" +#~ msgid "Window manager: " +#~ msgstr "विंडो प्रबंधक:" -#: ../src/ui/theme-viewer.c:398 -msgid "Border" -msgstr "किनारा" +#~ msgid "Bug in window manager: " +#~ msgstr "विंडो प्रबंधक में बग:" -#: ../src/ui/theme-viewer.c:726 -#, c-format -msgid "Button layout test %d" -msgstr "बटन अभिन्यास जाँच %d" +#~ msgid "Window manager warning: " +#~ msgstr "विंडो प्रबंधक चेतावनी" -#: ../src/ui/theme-viewer.c:755 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g मिलीसेकण्ड एक विंडो फ्रेम ड्रॉ करने में" +#~ msgid "Window manager error: " +#~ msgstr "विंडो प्रबंधक त्रुटिः" -#: ../src/ui/theme-viewer.c:798 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "उपयोग: metacity-theme-viewer [THEMENAME]\n" +# first time through +#~ msgid "" +#~ "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " +#~ "window as specified in the ICCCM.\n" +#~ msgstr "" +#~ "विंडो %s नियत करता है SM_CLIENT_ID अपने आप ही, बजाए WM_CLIENT_LEADER विंडो के " +#~ "जैसा कि ICCCM में उल्लेखित किया गया है.\n" -#: ../src/ui/theme-viewer.c:805 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "प्रसंग लोड करने में त्रुटि: %s\n" +# We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the +# * authoritative source for that info. Some apps such as mplayer or +# * xine disable resize via MWM but not WM_NORMAL_HINTS, but that +# * leads to e.g. us not fullscreening their windows. Apps that set +# * MWM but not WM_NORMAL_HINTS are basically broken. We complain +# * about these apps but make them work. +#~ msgid "" +#~ "Window %s sets an MWM hint indicating it isn't resizable, but sets min " +#~ "size %d x %d and max size %d x %d; this doesn't make much sense.\n" +#~ msgstr "" +#~ "विंडो %s ने एक एमडबल्यूएम संकेत नियत किया यह दिखाते हुए कि यह आकार बदलने लायक नहीं " +#~ "है, परंतु न्यूनतम आकार नियत किया %d x %d तथा अधिकतम आकार %d x %d; इसका कोई " +#~ "खास अर्थ नहीं निकलता.\n" -#: ../src/ui/theme-viewer.c:811 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "प्रसंग \"%s\" लोड किया %g सेकण्ड्स में\n" +#~ msgid "Application set a bogus _NET_WM_PID %lu\n" +#~ msgstr "अनुप्रयोग ने नियत किया एक bogus _NET_WM_PID %lu\n" -#: ../src/ui/theme-viewer.c:852 -msgid "Normal Title Font" -msgstr "सामान्य शीर्षक फ़ॉन्ट" +#~ msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +#~ msgstr "अवैध WM_TRANSIENT_FOR window 0x%lx %s के लिये निर्दिष्ट.\n" -#: ../src/ui/theme-viewer.c:858 -msgid "Small Title Font" -msgstr "छोटा शीर्षक फ़ॉन्ट" +#~ msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" +#~ msgstr "WM_TRANSIENT_FOR विंडो 0x%lx %s के लिए लूप का निर्माण नहीं कर सका.\n" -#: ../src/ui/theme-viewer.c:864 -msgid "Large Title Font" -msgstr "बड़ा शीर्षक फ़ॉन्ट" +#~ msgid "" +#~ "Window 0x%lx has property %s\n" +#~ "that was expected to have type %s format %d\n" +#~ "and actually has type %s format %d n_items %d.\n" +#~ "This is most likely an application bug, not a window manager bug.\n" +#~ "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +#~ msgstr "" +#~ "विंडो 0x%lx में गुण %s है \n" +#~ "जिसमें वांछित है प्रकार %s फ़ॉर्मेट %d \n" +#~ "तथा वास्तव में है प्रकार %s फ़ॉर्मेट %d एन_वस्तुएँ %d.\n" +#~ " इस बात की पूरी संभावना है कि यह एक अनुप्रयोग बग है, विंडो प्रबंधक बग नहीं.\n" +#~ " विंडो का शीर्षक है=\"%s\" क्लास=\"%s\" नाम=\"%s\"\n" -#: ../src/ui/theme-viewer.c:869 -msgid "Button Layouts" -msgstr "बटन अभिन्यास" +#~ msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +#~ msgstr "गुण %s विंडो 0x%lx में अवैध यूटीएफ़-8 है \n" -#: ../src/ui/theme-viewer.c:874 -msgid "Benchmark" -msgstr "बेंचमार्क" +#~ msgid "" +#~ "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the " +#~ "list\n" +#~ msgstr "गुण %s विंडो 0x%lx पर %d वस्तुओं हेतु सूची में अवैध यूटीएफ़-8 है\n" -#: ../src/ui/theme-viewer.c:921 -msgid "Window Title Goes Here" -msgstr "विंडो शीर्षक यहाँ जाएगा" +#~ msgid "Usage: %s\n" +#~ msgstr "उपयोग: %s\n" -#: ../src/ui/theme-viewer.c:1025 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"%d frames को %g क्लाइंट पक्ष सेकेंड में खींचा (%g milliseconds per frame) और %g X " -"सर्वर संसाधन को समाहित करता सेकेंड वाल घड़ी (%g विविध प्रति फ्रेम)\n" +#~ msgid "Mi_nimize" +#~ msgstr "न्यूनतम (_n)" -#: ../src/ui/theme-viewer.c:1244 -msgid "position expression test returned TRUE but set error" -msgstr "स्थिति एक्सप्रेशन जाँच ने सही लौटाया परंतु त्रुटि नियत नहीं किया" +#~ msgid "Ma_ximize" +#~ msgstr "अधिकतम (_x)" -#: ../src/ui/theme-viewer.c:1246 -msgid "position expression test returned FALSE but didn't set error" -msgstr "स्थिति एक्सप्रेशन जाँच ने ग़लत लौटाया परंतु त्रुटि नियत नहीं किया" +#~ msgid "Unma_ximize" +#~ msgstr "बड़े से छोटा करें (_x)" -#: ../src/ui/theme-viewer.c:1250 -msgid "Error was expected but none given" -msgstr "त्रुटि प्रत्याशित था, परन्तु दिया नहीं गया" +#~ msgid "Roll _Up" +#~ msgstr "उपर समेटें (_U)" -#: ../src/ui/theme-viewer.c:1252 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "त्रुटि %d वांछित था परन्तु %d दिया गया" +#~ msgid "_Unroll" +#~ msgstr "वापस खोलें (_U)" -#: ../src/ui/theme-viewer.c:1258 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "त्रुटि की प्रत्याशा नहीं थी परन्तु एक लौटाया गया: %s" +#~ msgid "_Move" +#~ msgstr "खिसकाएँ (_M)" -#: ../src/ui/theme-viewer.c:1262 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "एक्स मूल्य था %d, %d वांछित था" +#~ msgid "_Resize" +#~ msgstr "आकार बदलें (_R)" -#: ../src/ui/theme-viewer.c:1265 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "वाई मूल्य था %d, %d वांछित था" +#~ msgid "Move Titlebar On_screen" +#~ msgstr "ऑनस्क्रीन शीर्षकबार खिसकायें (_s)" -#: ../src/ui/theme-viewer.c:1330 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "%d निर्देशांक एक्सप्रेशन्स पार्स किया %g सेकण्ड्स में (औसतन %g सेकण्ड्स)\n" +#~ msgid "Always on _Top" +#~ msgstr "हमेशा शीर्ष पर (_T)" + +#~ msgid "_Always on Visible Workspace" +#~ msgstr "हमेशा दृश्य कार्यस्थान पर (_A)" + +#~ msgid "_Only on This Workspace" +#~ msgstr "सिर्फ इसी कार्यस्थान पर (_O)" + +#~ msgid "Move to Workspace _Left" +#~ msgstr "बाएँ कार्यस्थान में ले जाएँ (_i)" + +#~ msgid "Move to Workspace R_ight" +#~ msgstr "दाएँ कार्यस्थान में ले जाएँ (_i)" + +#~ msgid "Move to Workspace _Up" +#~ msgstr "ऊपर कार्यस्थान में ले जाएँ (_U)" + +#~ msgid "Move to Workspace _Down" +#~ msgstr "नीचे कार्यस्थान में ले जाएँ (_D)" + +# separator +#~ msgid "_Close" +#~ msgstr "बंद करें (_C)" + +#~ msgid "Workspace %d%n" +#~ msgstr "कार्यस्थान %d%n" + +#~ msgid "Workspace 1_0" +#~ msgstr "कार्यस्थान 1_0" + +#~ msgid "Workspace %s%d" +#~ msgstr "कार्यस्थान %s%d" + +#~ msgid "Move to Another _Workspace" +#~ msgstr "अन्य कार्यस्थान में ले जाएँ (_W)" + +# This is the text that should appear next to menu accelerators +# * that use the shift key. If the text on this key isn't typically +# * translated on keyboards used for your language, don't translate +# * this. +#~ msgid "Shift" +#~ msgstr "शिफ़्ट" + +# This is the text that should appear next to menu accelerators +# * that use the control key. If the text on this key isn't typically +# * translated on keyboards used for your language, don't translate +# * this. +#~ msgid "Ctrl" +#~ msgstr "कंट्रोल" + +# This is the text that should appear next to menu accelerators +# * that use the alt key. If the text on this key isn't typically +# * translated on keyboards used for your language, don't translate +# * this. +#~ msgid "Alt" +#~ msgstr "आल्ट" + +#~ msgid "Meta" +#~ msgstr "मेटा" + +# This is the text that should appear next to menu accelerators +# * that use the super key. If the text on this key isn't typically +# * translated on keyboards used for your language, don't translate +# * this. +#~ msgid "Super" +#~ msgstr "सुपर" + +# This is the text that should appear next to menu accelerators +# * that use the hyper key. If the text on this key isn't typically +# * translated on keyboards used for your language, don't translate +# * this. +#~ msgid "Hyper" +#~ msgstr "हाइपर" + +# This is the text that should appear next to menu accelerators +# * that use the mod2 key. If the text on this key isn't typically +# * translated on keyboards used for your language, don't translate +# * this. +#~ msgid "Mod2" +#~ msgstr "परि.2" + +# This is the text that should appear next to menu accelerators +# * that use the mod3 key. If the text on this key isn't typically +# * translated on keyboards used for your language, don't translate +# * this. +#~ msgid "Mod3" +#~ msgstr "परि.3" + +# This is the text that should appear next to menu accelerators +# * that use the mod4 key. If the text on this key isn't typically +# * translated on keyboards used for your language, don't translate +# * this. +#~ msgid "Mod4" +#~ msgstr "परि.4" + +# This is the text that should appear next to menu accelerators +# * that use the mod5 key. If the text on this key isn't typically +# * translated on keyboards used for your language, don't translate +# * this. +#~ msgid "Mod5" +#~ msgstr "परि.5" + +#~ msgid "_Windows" +#~ msgstr "विंडो (_W)" + +#~ msgid "_Dialog" +#~ msgstr "संवाद (_D)" + +#~ msgid "_Modal dialog" +#~ msgstr "मॉडल संवाद (_M)" + +#~ msgid "_Utility" +#~ msgstr "यूटिलिटी (_U)" + +#~ msgid "_Splashscreen" +#~ msgstr "स्प्लैशस्क्रीन (_S)" + +#~ msgid "_Top dock" +#~ msgstr "शीर्ष डॉक (_T)" + +#~ msgid "_Bottom dock" +#~ msgstr "निचला डॉक (_B)" + +#~ msgid "_Left dock" +#~ msgstr "बायाँ डॉक (_L)" + +#~ msgid "_Right dock" +#~ msgstr "दायाँ डॉक (_R)" + +#~ msgid "_All docks" +#~ msgstr "सभी डॉक्स (_A)" + +#~ msgid "Des_ktop" +#~ msgstr "डेस्कटॉप (_k)" + +#~ msgid "Open another one of these windows" +#~ msgstr "इनमें से एक अन्य विंडो खोलें" + +#~ msgid "This is a demo button with an 'open' icon" +#~ msgstr "यह 'खोलें' चिह्न युक्त एक डेमो बटन है" + +#~ msgid "This is a demo button with a 'quit' icon" +#~ msgstr "यह एक डेमो बटन है 'बाहर' चिह्न के साथ" + +#~ msgid "This is a sample message in a sample dialog" +#~ msgstr "यह नमूना संवाद में नमूना संदेश था" + +#~ msgid "Fake menu item %d\n" +#~ msgstr "नकली मेनू वस्तु %d\n" + +#~ msgid "Border-only window" +#~ msgstr "सिर्फ-किनारा विंडो" + +#~ msgid "Bar" +#~ msgstr "पट्टी" + +#~ msgid "Normal Application Window" +#~ msgstr "सामान्य अनुप्रयोग विंडो" + +#~ msgid "Dialog Box" +#~ msgstr "संवाद बक्सा" + +#~ msgid "Modal Dialog Box" +#~ msgstr "मॉडल संवाद बक्सा" + +#~ msgid "Utility Palette" +#~ msgstr "यूटिलिटी पट्टिका" + +#~ msgid "Torn-off Menu" +#~ msgstr "टॉर्न-ऑफ मेनू" + +#~ msgid "Border" +#~ msgstr "किनारा" + +#~ msgid "Attached Modal Dialog" +#~ msgstr "मॉडल संवाद संलग्न है" + +#~ msgid "Button layout test %d" +#~ msgstr "बटन अभिन्यास जाँच %d" + +#~ msgid "%g milliseconds to draw one window frame" +#~ msgstr "%g मिलीसेकण्ड एक विंडो फ्रेम ड्रॉ करने में" + +#~ msgid "Usage: metacity-theme-viewer [THEMENAME]\n" +#~ msgstr "उपयोग: metacity-theme-viewer [THEMENAME]\n" + +#~ msgid "Error loading theme: %s\n" +#~ msgstr "प्रसंग लोड करने में त्रुटि: %s\n" + +#~ msgid "Loaded theme \"%s\" in %g seconds\n" +#~ msgstr "प्रसंग \"%s\" लोड किया %g सेकण्ड्स में\n" + +#~ msgid "Normal Title Font" +#~ msgstr "सामान्य शीर्षक फ़ॉन्ट" + +#~ msgid "Small Title Font" +#~ msgstr "छोटा शीर्षक फ़ॉन्ट" + +#~ msgid "Large Title Font" +#~ msgstr "बड़ा शीर्षक फ़ॉन्ट" + +#~ msgid "Button Layouts" +#~ msgstr "बटन अभिन्यास" + +#~ msgid "Benchmark" +#~ msgstr "बेंचमार्क" + +#~ msgid "Window Title Goes Here" +#~ msgstr "विंडो शीर्षक यहाँ जाएगा" + +#~ msgid "" +#~ "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and " +#~ "%g seconds wall clock time including X server resources (%g milliseconds " +#~ "per frame)\n" +#~ msgstr "" +#~ "%d frames को %g क्लाइंट पक्ष सेकेंड में खींचा (%g milliseconds per frame) और %g X " +#~ "सर्वर संसाधन को समाहित करता सेकेंड वाल घड़ी (%g विविध प्रति फ्रेम)\n" + +#~ msgid "position expression test returned TRUE but set error" +#~ msgstr "स्थिति एक्सप्रेशन जाँच ने सही लौटाया परंतु त्रुटि नियत नहीं किया" + +#~ msgid "position expression test returned FALSE but didn't set error" +#~ msgstr "स्थिति एक्सप्रेशन जाँच ने ग़लत लौटाया परंतु त्रुटि नियत नहीं किया" + +#~ msgid "Error was expected but none given" +#~ msgstr "त्रुटि प्रत्याशित था, परन्तु दिया नहीं गया" + +#~ msgid "Error %d was expected but %d given" +#~ msgstr "त्रुटि %d वांछित था परन्तु %d दिया गया" + +#~ msgid "Error not expected but one was returned: %s" +#~ msgstr "त्रुटि की प्रत्याशा नहीं थी परन्तु एक लौटाया गया: %s" + +#~ msgid "x value was %d, %d was expected" +#~ msgstr "एक्स मूल्य था %d, %d वांछित था" + +#~ msgid "y value was %d, %d was expected" +#~ msgstr "वाई मूल्य था %d, %d वांछित था" + +#~ msgid "" +#~ "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" +#~ msgstr "%d निर्देशांक एक्सप्रेशन्स पार्स किया %g सेकण्ड्स में (औसतन %g सेकण्ड्स)\n" + +#, fuzzy +#~ msgid "Minimize window" +#~ msgstr "विंडो को न्यूनतम करें" + +#~ msgid "Window Management" +#~ msgstr "विंडो प्रबंधन" + +#~ msgid "Failed to parse message \"%s\" from dialog process\n" +#~ msgstr "संदेश \"%s\" की व्याख्या संवाद प्रक्रिया से नहीं कर सका\n" + +#~ msgid "Error reading from dialog display process: %s\n" +#~ msgstr "संवाद प्रदर्शक प्रक्रिया: %s से पढ़ने में त्रुटि\n" + +#~ msgid "" +#~ "Error launching metacity-dialog to ask about killing an application: %s\n" +#~ msgstr "" +#~ "किसी अनुप्रयोग को खत्म करने के लिए पूछने हेतु मेटासिटी-संवाद प्रारंभ करने में त्रुटि: %s\n" + +#~ msgid "Failed to get hostname: %s\n" +#~ msgstr "होस्टनाम पाने में असफल: %s\n" + +#~ msgid "" +#~ "Lost connection to the display '%s';\n" +#~ "most likely the X server was shut down or you killed/destroyed\n" +#~ "the window manager.\n" +#~ msgstr "" +#~ "प्रदर्शक '%s' से कनेक्शन छूट गया;\n" +#~ "बहुत संभावना है कि या तो एक्स सर्वर बन्द कर दिया गया या आपने विंडो प्रबंधक को \n" +#~ "खत्म/समाप्त कर दिया है.\n" + +#~ msgid "Fatal IO error %d (%s) on display '%s'.\n" +#~ msgstr "गंभीर आईओ त्रुटि %d (%s), प्रदर्शक '%s' में.\n" + +#~ msgid "" +#~ "There was an error running <tt>%s</tt>:\n" +#~ "\n" +#~ "%s" +#~ msgstr "" +#~ "<tt>%s</tt> चलाने में त्रुटि थी:\n" +#~ "\n" +#~ "%s" + +#~ msgid "No command %d has been defined.\n" +#~ msgstr "कोई कमांड %d पारिभाषित नहीं है.\n" + +#~ msgid "No terminal command has been defined.\n" +#~ msgstr "कोई टर्मिनल कमांड पारिभाषित नहीं है.\n" + +#~ msgid "Turn compositing on" +#~ msgstr "कंपोजिटिंग चालू करें" + +#~ msgid "Turn compositing off" +#~ msgstr "कंपोजिटिंग बंद करें" + +#~ msgid "Failed to restart: %s\n" +#~ msgstr "पुनः प्रारंभ करने में असफल: %s\n" + +#~ msgid "GConf key '%s' is set to an invalid value\n" +#~ msgstr "जी-कॉन्फ़ कुंजी '%s' एक अवैध प्रकार में नियत है\n" + +#~ msgid "%d stored in GConf key %s is out of range %d to %d\n" +#~ msgstr "%d जो जी-कॉन्फ़ कुंजी %s में भंडारित है वह सीमा %d से %d सीमा से बाहर है\n" + +#~ msgid "GConf key \"%s\" is set to an invalid type\n" +#~ msgstr "जी-कॉन्फ़ कुंजी \"%s\" एक अवैध प्रकार में नियत है\n" + +#~ msgid "Error setting number of workspaces to %d: %s\n" +#~ msgstr "कार्यस्थान संख्या %d पर तय करने में त्रुटि: %s हुई.\n" + +#~ msgid "Error setting name for workspace %d to \"%s\": %s\n" +#~ msgstr "कार्यस्थान नाम %d को \"%s\" से में बदलने में त्रुटि: %s हुई\n" + +#~ msgid "Error setting compositor status: %s\n" +#~ msgstr "कंपोजिटर स्थिति सेटिंग में त्रुटि: %s\n" + +#~ msgid "" +#~ "The format looks like \"<Control>a\" or <Shift><Alt>F1\".\n" +#~ "\n" +#~ "The parser is fairly liberal and allows lower or upper case, and also " +#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "फ़ॉर्मेट इस तरह दिखेंगे \"<Control>a\" या <Shift><Alt>F1\".\n" +#~ "यह पारसर पूरी तरह लिबरल है और बड़े या छोटे अक्षर दोनों स्वीकार करता है, तथा " +#~ "संक्षिप्ताक्षर भी जैसे- \"<Ctl>\" और \"<Ctl>\". यदि आपने विकल्प विशेष स्ट्रिंग में तय " +#~ "किया है \"disabled\", तब वहाँ इस क्रिया हेतु कोई कीबाइंडिंग नहीं होगा." + +#~ msgid "" +#~ "The format looks like \"<Control>a\" or <Shift><Alt>F1\".\n" +#~ "\n" +#~ "The parser is fairly liberal and allows lower or upper case, and also " +#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action.\n" +#~ "\n" +#~ "This keybinding may be reversed by holding down the \"shift\" key; " +#~ "therefore, \"shift\" cannot be one of the keys it uses." +#~ msgstr "" +#~ "फ़ॉर्मेट इस तरह दिखेंगे \"<Control>a\" or <Shift><Alt>F1\".\n" +#~ "यह पारसर पूरी तरह लिबरल है और बड़े या छोटे अक्षर दोनों स्वीकार करता है, तथा " +#~ "संक्षिप्ताक्षर भी जैसे- \"<Ctl>\" और \"<Ctl>\". यदि आपने विकल्प विशेष स्ट्रिंग में तय " +#~ "किया है \"disabled\", तब वहाँ इस क्रिया हेतु कोई कीबाइंडिंग नहीं होगा." + +#~ msgid "Failed to read saved session file %s: %s\n" +#~ msgstr "सहेजी गई सत्र फ़ाइल %s पढ़ने में असफल: %s\n" + +#~ msgid "" +#~ "Error launching metacity-dialog to warn about apps that don't support " +#~ "session management: %s\n" +#~ msgstr "" +#~ "अनुप्रयोग जो सत्र प्रबंधन समर्थन: %s नहीं रखते हैं उनकी चेतावनी बताने हेतु मेटासिटी " +#~ "संवाद प्रारंभ करने में त्रुटि\n" + +#~ msgid "Metacity" +#~ msgstr "मेटासिटी" + +#~ msgid "Switch to workspace 8" +#~ msgstr "कार्यस्थान 8 पर जाएँ" + +#~ msgid "Switch to workspace 9" +#~ msgstr "कार्यस्थान 9 पर जाएँ" + +#~ msgid "Switch to workspace 10" +#~ msgstr "कार्यस्थान 10 पर जाएँ" + +#~ msgid "Switch to workspace 11" +#~ msgstr "कार्यस्थान 11 पर जाएँ" + +#~ msgid "Switch to workspace 12" +#~ msgstr "कार्यस्थान 12 पर जाएँ" + +#~ msgid "Switch to workspace on the left of the current workspace" +#~ msgstr "मौजूदा कार्यस्थान के बाएँ कार्यस्थान पर जाएँ" + +#~ msgid "Switch to workspace on the right of the current workspace" +#~ msgstr "मौजूदा कार्यस्थान के दाहिने कार्यस्थान पर जाएँ" + +#~ msgid "Switch to workspace above the current workspace" +#~ msgstr "मौजूदा कार्यस्थान के ऊपर कार्यस्थान पर जाएँ" + +#~ msgid "Switch to workspace below the current workspace" +#~ msgstr "मौजूदा कार्यस्थान के नीचे कार्यस्थान पर जाएँ" + +#~ msgid "Move between windows of an application, using a popup window" +#~ msgstr "पॉपअप के साथ अनुप्रयोग के विंडो के बीच जायें" + +#~ msgid "" +#~ "Move backward between windows of an application, using a popup window" +#~ msgstr "पॉपअप के साथ तत्काल अनुप्रयोग के विंडो के बीच पीछे जायें" + +#~ msgid "Move between windows, using a popup window" +#~ msgstr "विंडोज़ के बीच पॉपअप के प्रयोग से खिसकाएँ" + +#~ msgid "Move backward between windows, using a popup window" +#~ msgstr "पॉपअप प्रदर्शक के द्वारा विंडो के बीच पीछे ले जाएँ" + +#~ msgid "Move between panels and the desktop, using a popup window" +#~ msgstr "पटल तथा डेस्कटॉप के बीच पॉपअप के प्रयोग से खिसकाएँ" + +#~ msgid "Move backward between panels and the desktop, using a popup window" +#~ msgstr "पटल तथा डेस्कटॉप के बीच पॉपअप के प्रयोग से पीछे जाएँ" + +#~ msgid "Move between windows of an application immediately" +#~ msgstr "तत्काल अनुप्रयोग के विंडो के बीच जायें" + +#~ msgid "Move backward between windows of an application immediately" +#~ msgstr "तत्काल अनुप्रयोग के विंडो के बीच पीछे जायें" + +#~ msgid "Move between windows immediately" +#~ msgstr "विंडोज़ के बीच तत्काल खिसकाएँ" + +#~ msgid "Move backward between windows immediately" +#~ msgstr "विंडोज़ के बीच तत्काल पीछे जाएँ" + +#~ msgid "Move between panels and the desktop immediately" +#~ msgstr "पटल तथा डेस्कटॉप के बीच तत्काल खिसकाएँ" + +#~ msgid "Move backward between panels and the desktop immediately" +#~ msgstr "पटल तथा डेस्कटॉप के बीच तत्काल पीछे जाएँ" + +#~ msgid "Hide all normal windows and set focus to the desktop" +#~ msgstr "सभी सामान्य विंडो को छुपाएँ और डेस्कटॉप पर फ़ोकस करें" + +#~ msgid "Show the panel's main menu" +#~ msgstr "पटल मुख्य मेन्यू दिखाएँ" + +#~ msgid "Show the panel's \"Run Application\" dialog box" +#~ msgstr "पटल के \"अनुप्रयोग चलाएँ\" संवाद दिखाएँ" + +#~ msgid "Take a screenshot" +#~ msgstr "स्क्रीन का चित्र लें" + +#~ msgid "Take a screenshot of a window" +#~ msgstr "विंडो का चित्र लें" + +#~ msgid "Run a terminal" +#~ msgstr "एक टर्मिनल चलायें" + +#~ msgid "Toggle whether a window will always be visible over other windows" +#~ msgstr "टॉगल करें कि क्या दूसरे विंडो के बीच एक विंडो हमेशा दृश्य रहेगा" + +#~ msgid "Toggle whether window is on all workspaces or just one" +#~ msgstr "टॉगल करें कि विंडो सभी कार्यस्थान पर है या केवल एक पर" + +#~ msgid "Move window to workspace 5" +#~ msgstr "विंडो को कार्यस्थान 5 पर ले जाएँ" + +#~ msgid "Move window to workspace 6" +#~ msgstr "विंडो को कार्यस्थान 6 पर ले जाएँ" + +#~ msgid "Move window to workspace 7" +#~ msgstr "विंडो को कार्यस्थान 7 पर ले जाएँ" + +#~ msgid "Move window to workspace 8" +#~ msgstr "विंडो को कार्यस्थान 8 पर ले जाएँ" + +#~ msgid "Move window to workspace 9" +#~ msgstr "विंडो को कार्यस्थान 9 पर ले जाएँ" + +#~ msgid "Move window to workspace 10" +#~ msgstr "विंडो को कार्यस्थान 10 पर ले जाएँ" + +#~ msgid "Move window to workspace 11" +#~ msgstr "विंडो को कार्यस्थान 11 पर ले जाएँ" + +#~ msgid "Move window to workspace 12" +#~ msgstr "विंडो को कार्यस्थान 12 पर ले जाएँ" + +#~ msgid "Raise window if it's covered by another window, otherwise lower it" +#~ msgstr "विंडो बढ़ाएँ कि क्या यह दूसरे विंडो द्वारा आच्छादित है, अन्यथा इसे नीचे करें" + +#~ msgid "Move window to north-west (top left) corner" +#~ msgstr "विंडो को उत्तर-पश्चिमी (उपरी बाएँ) कोने में ले जाएँ" + +#~ msgid "Move window to north-east (top right) corner" +#~ msgstr "विंडो को उत्तर-पूर्वी (उपरी दाहिने) कोने में ले जाएँ" + +#~ msgid "Move window to south-west (bottom left) corner" +#~ msgstr "विंडो को दक्षिणी-पश्चिमी (उपरी बाएँ) कोने में ले जाएँ" + +#~ msgid "Move window to south-east (bottom right) corner" +#~ msgstr "विंडो को दक्षिणी-पूर्वी (तल के दाहिने) कोने में ले जाएँ" + +#~ msgid "Move window to north (top) side of screen" +#~ msgstr "विंडो को स्क्रीन के किनारे उत्तरी (शीर्ष) कोने में ले जाएँ" + +#~ msgid "Move window to south (bottom) side of screen" +#~ msgstr "विंडो को स्क्रीन के किनारे दक्षिणी (तल) कोने में ले जाएँ" + +#~ msgid "Move window to east (right) side of screen" +#~ msgstr "विंडो को स्क्रीन के किनारे पूर्वी (दाहिने) कोने में ले जाएँ" + +#~ msgid "Move window to west (left) side of screen" +#~ msgstr "विंडो को स्क्रीन के किनारे पश्चिमी (बाएँ) कोने में ले जाएँ" + +#~ msgid "Move window to center of screen" +#~ msgstr "विंडो को स्क्रीन के केंद्र में खिसकाएँ" + +#~ msgid "" +#~ "(Not implemented) Navigation works in terms of applications not windows" +#~ msgstr "(कार्यान्वित नहीं) संचलन अनुप्रयोगों के अनुसार चलता है, विंडोज़ से नहीं" + +#~ msgid "" +#~ "A font description string describing a font for window titlebars. The " +#~ "size from the description will only be used if the titlebar_font_size " +#~ "option is set to 0. Also, this option is disabled if the " +#~ "titlebar_uses_desktop_font option is set to true." +#~ msgstr "" +#~ "एक फंट विवरण स्ट्रिंग विंडो शीर्षक पट्टी के लिये फंट के बारे में बता रहा है. विवरण से " +#~ "आकार प्रयुक्त होगा अगर titlebar_font_size विकल्प 0 में सेट किया जाता है, साथ ही, " +#~ "यह विकल्प निष्क्रिय किया जाता है अगर titlebar_uses_desktop_font विकल्प को सही " +#~ "पर सेट किया जाता है." + +#~ msgid "Action on title bar double-click" +#~ msgstr "शीर्षक पट्टी में दोहरा-क्लिक करने पर क्रिया" + +#~ msgid "Action on title bar middle-click" +#~ msgstr "शीर्षक पट्टी में मध्य-क्लिक पर क्रिया" + +#~ msgid "Action on title bar right-click" +#~ msgstr "शीर्षक पट्टी में दाहिना-क्लिक पर क्रिया" + +#~ msgid "Arrangement of buttons on the titlebar" +#~ msgstr "शीर्षक-पट्टी में बटनों का विन्यास" + +#~ msgid "" +#~ "Arrangement of buttons on the titlebar. The value should be a string, " +#~ "such as \"menu:minimize,maximize,spacer,close\"; the colon separates the " +#~ "left corner of the window from the right corner, and the button names are " +#~ "comma-separated. Duplicate buttons are not allowed. Unknown button names " +#~ "are silently ignored so that buttons can be added in future metacity " +#~ "versions without breaking older versions. A special spacer tag can be " +#~ "used to insert some space between two adjacent buttons." +#~ msgstr "" +#~ "शीर्षक-पट्टी में बटनों का विन्यास. मूल्य स्ट्रिंग होने चाहिएँ, जैसे \"menu:minimize," +#~ "maximize,spacer,close\"; कॉलन विंडो के बाएँ कोने को दांए कोने से अलग करता है तथा " +#~ "बटन के नाम कॉमा से अलग हैं. दोहरे बटन स्वीकार्य नहीं हैं. अज्ञात बटन नामों को शांति से " +#~ "अनदेखा कर दिया गया है ताकि भविष्य के मेटासिटी संस्करण में, पुराने संस्करण को तोड़े बगैर ये " +#~ "जोड़े जा सकें." + +#~ msgid "Automatically raises the focused window" +#~ msgstr "फ़ोकस किए विंडो को स्वचालित उठाएँ" + +#~ msgid "" +#~ "Clicking a window while holding down this modifier key will move the " +#~ "window (left click), resize the window (middle click), or show the window " +#~ "menu (right click). The left and right operations may be swapped using " +#~ "the \"mouse_button_resize\" key. Modifier is expressed as \"<Alt>\" " +#~ "or \"<Super>\" for example." +#~ msgstr "" +#~ "Clicking a window while holding down this modifier key will move the " +#~ "window (left click), resize the window (middle click), or show the window " +#~ "menu (right click). The left and right operations may be swapped using " +#~ "the \"mouse_button_resize\" key. Modifier is expressed as \"<Alt>\" " +#~ "or \"<Super>\" for example." + +#~ msgid "Commands to run in response to keybindings" +#~ msgstr "कीबाइंडिंग के प्रत्युत्तर में चलाया जाने वाला कमांड" + +#~ msgid "Compositing Manager" +#~ msgstr "कंपोजिटिंग प्रबंधक" + +#~ msgid "Control how new windows get focus" +#~ msgstr "नियंत्रित करें कि कैसे नया विंडो फोकस पाता है" + +#~ msgid "Current theme" +#~ msgstr "वर्तमान प्रसंग" + +#~ msgid "Delay in milliseconds for the auto raise option" +#~ msgstr "आटो रेस विकल्प हेतु मिलीसेकण्ड्स में देरी" + +#~ msgid "Determines whether Metacity is a compositing manager." +#~ msgstr "निर्धारित करें कि Metacity एक कंपोजिटिंग प्रबंधक है." + +#~ msgid "" +#~ "Determines whether applications or the system can generate audible " +#~ "'beeps'; may be used in conjunction with 'visual bell' to allow silent " +#~ "'beeps'." +#~ msgstr "" +#~ "निर्धारित करता है कि क्या अनुप्रयोग या तंत्र सुनने योग्य बीप पैदा कर सकता है, शायद " +#~ "दृष्टिगोच़र घंटी के साथ उपयोग किया जाकर शांति मय बीप स्वीकारे." + +#~ msgid "Disable misfeatures that are required by old or broken applications" +#~ msgstr "मिसफीचर्स असमर्थ करें जो कि पुराने या टूटे अनुप्रयोगों द्वारा वांछित होते हैं" + +#~ msgid "Enable Visual Bell" +#~ msgstr "दृष्टिगोच़र घंटी सक्षम करें" + +#~ msgid "" +#~ "If true, ignore the titlebar_font option, and use the standard " +#~ "application font for window titles." +#~ msgstr "" +#~ "यदि सही है, शीर्षक पट्टी फ़ॉन्ट विकल्प का अनदेखा करें तथा विंडो शीर्षकों हेतु मानक " +#~ "अनुप्रयोग फ़ॉन्ट का प्रयोग करें" + +#~ msgid "" +#~ "If true, metacity will give the user less feedback by using wireframes, " +#~ "avoiding animations, or other means. This is a significant reduction in " +#~ "usability for many users, but may allow legacy applications to continue " +#~ "working, and may also be a useful tradeoff for terminal servers. However, " +#~ "the wireframe feature is disabled when accessibility is on." +#~ msgstr "" +#~ "अगर सही है, metacity उपयोक्ता को कम फीडबेक और सीधा हस्तक्षेप का कम सेंस देगा, " +#~ "वायरफ्रेम, एनीमेशन अनदेखा करते हुये, या अन्य साधन. यह महत्वपूर्ण कमी है कई उपयोक्ता के " +#~ "प्रयोग में, लेकिन कई पुरातन अनुप्रयोग व टर्मिनल सर्वर की अनुमति देते हैं कि वे कब अन्यथा " +#~ "रूप से अप्रायोगिक होगें. हालांकि, वायरफ्रेम फीचर को निष्क्रिय किया जाता है जब पहुंच " +#~ "वीयर्ड डेस्कटॉप खंडन को अनदेखा करने के लिये हो." + +#~ msgid "" +#~ "If true, then Metacity works in terms of applications rather than " +#~ "windows. The concept is a bit abstract, but in general an application-" +#~ "based setup is more like the Mac and less like Windows. When you focus a " +#~ "window in application-based mode, all the windows in the application will " +#~ "be raised. Also, in application-based mode, focus clicks are not passed " +#~ "through to windows in other applications. Application-based mode is, " +#~ "however, largely unimplemented at the moment." +#~ msgstr "" +#~ "यदि सही है तो मेटासिटी विंडो के बजाए अनुप्रयोग जैसे कार्य करेगा. परिकल्पना थोड़ी " +#~ "संक्षिप्त है परंतु आमतौर पर अनुप्रयोग आधारित सेटअप मैक जैसा ज्यादा होगा विंडोज़ की तरह " +#~ "कम. यदि आप किसी विंडो को अनुप्रयोग आधारित मोड पर फ़ोकस करेंगे तो अनुप्रयोग में के सभी " +#~ "विंडो ऊपर हो जाएंगे. यह भी कि अनुप्रयोग आधारित मोड में फ़ोकस क्लिक अन्य अनुप्रयोग के " +#~ "विंडो से होकर नहीं जाता. अनुप्रयोग आधारित मोड विस्तृत रूप से इस समय कार्यान्वित नहीं " +#~ "है." + +#~ msgid "If true, trade off usability for less resource usage" +#~ msgstr "यदि सही है, उपयोगिता को कम साधन उपयोग के साथ बदलें" + +#~ msgid "Name of workspace" +#~ msgstr "कार्यस्थान का नाम" + +#~ msgid "Number of workspaces" +#~ msgstr "कार्यस्थान की संख्या" + +#~ msgid "" +#~ "Number of workspaces. Must be more than zero, and has a fixed maximum to " +#~ "prevent making the desktop unusable by accidentally asking for too many " +#~ "workspaces." +#~ msgstr "" +#~ "कार्यस्थान की संख्या. यह शून्य से अधिक होना चाहिए तथा इसे एक अधिकतम पर निर्धारित " +#~ "करना चाहिये ज्यादा कार्यस्थान की मांग करने पर आपके डेस्कटॉप को दुर्धटनावश नष्ट होने से " +#~ "बचाने हेतु." + +#~ msgid "Run a defined command" +#~ msgstr "पारिभाषित कमांड चलाएँ" + +#~ msgid "" +#~ "Set this to true to resize with the right button and show a menu with the " +#~ "middle button while holding down the key given in \"mouse_button_modifier" +#~ "\"; set it to false to make it work the opposite way around." +#~ msgstr "" +#~ "Set this to true to resize with the right button and show a menu with the " +#~ "middle button while holding down the key given in \"mouse_button_modifier" +#~ "\"; set it to false to make it work the opposite way around." + +#~ msgid "" +#~ "Setting this option to false can lead to buggy behavior, so users are " +#~ "strongly discouraged from changing it from the default of true. Many " +#~ "actions (e.g. clicking in the client area, moving or resizing the window) " +#~ "normally raise the window as a side-effect. Setting this option to false, " +#~ "which is strongly discouraged, will decouple raising from other user " +#~ "actions, and ignore raise requests generated by applications. See http://" +#~ "bugzilla.gnome.org/show_bug.cgi?id=445447#c6. Even when this option is " +#~ "false, windows can still be raised by an alt-left-click anywhere on the " +#~ "window, a normal click on the window decorations, or by special messages " +#~ "from pagers, such as activation requests from tasklist applets. This " +#~ "option is currently disabled in click-to-focus mode. Note that the list " +#~ "of ways to raise windows when raise_on_click is false does not include " +#~ "programmatic requests from applications to raise windows; such requests " +#~ "will be ignored regardless of the reason for the request. If you are an " +#~ "application developer and have a user complaining that your application " +#~ "does not work with this setting disabled, tell them it is _their_ fault " +#~ "for breaking their window manager and that they need to change this " +#~ "option back to true or live with the \"bug\" they requested." +#~ msgstr "" +#~ "Setting this option to false can lead to buggy behavior, so users are " +#~ "strongly discouraged from changing it from the default of true. Many " +#~ "actions (e.g. clicking in the client area, moving or resizing the window) " +#~ "normally raise the window as a side-effect. Setting this option to false, " +#~ "which is strongly discouraged, will decouple raising from other user " +#~ "actions, and ignore raise requests generated by applications. See http://" +#~ "bugzilla.gnome.org/show_bug.cgi?id=445447#c6. Even when this option is " +#~ "false, windows can still be raised by an alt-left-click anywhere on the " +#~ "window, a normal click on the window decorations, or by special messages " +#~ "from pagers, such as activation requests from tasklist applets. This " +#~ "option is currently disabled in click-to-focus mode. Note that the list " +#~ "of ways to raise windows when raise_on_click is false does not include " +#~ "programmatic requests from applications to raise windows; such requests " +#~ "will be ignored regardless of the reason for the request. If you are an " +#~ "application developer and have a user complaining that your application " +#~ "does not work with this setting disabled, tell them it is _their_ fault " +#~ "for breaking their window manager and that they need to change this " +#~ "option back to true or live with the \"bug\" they requested." + +#~ msgid "" +#~ "Some applications disregard specifications in ways that result in window " +#~ "manager misfeatures. This option puts Metacity in a rigorously correct " +#~ "mode, which gives a more consistent user interface, provided one does not " +#~ "need to run any misbehaving applications." +#~ msgstr "" +#~ "कुछ अनुप्रयोग विशेषता को महत्व नहीं देते हैं जो कि विंडो प्रबंधक मिसफीचर में परिणाम लाता " +#~ "है. यह विकल्प Metacity को काफी सही मोड में रखता है, जो कि ज्यादा संगत उपयोक्ता " +#~ "अंतरफलक देता है, अगर कोई गलत अनुप्रयोग नहीं चला रहा है." + +#~ msgid "System Bell is Audible" +#~ msgstr "तंत्र घंटी सुनने योग्य है" + +#~ msgid "" +#~ "Tells Metacity how to implement the visual indication that the system " +#~ "bell or another application 'bell' indicator has been rung. Currently " +#~ "there are two valid values, \"fullscreen\", which causes a fullscreen " +#~ "white-black flash, and \"frame_flash\" which causes the titlebar of the " +#~ "application which sent the bell signal to flash. If the application which " +#~ "sent the bell is unknown (as is usually the case for the default \"system " +#~ "beep\"), the currently focused window's titlebar is flashed." +#~ msgstr "" +#~ "मेटासिटी को बताता है कि कैसे दृश्य संकेत काम में लिया जाए कि तंत्र घंटी या अन्य अनुप्रयोग " +#~ "घंटी बजाना है. वर्तमान में दो मान्य मूल्य हैं, \"पूरा स्क्रीन\", जो फुलस्क्रीन काला-सफेद " +#~ "फ्लेश करता है तथा \"फ्रेम-फ्लैश\" जो संबंधित अनुप्रयोग के टाइटलबार को फ्लेश करने हेतु संकेत " +#~ "करता है, जिसको घंटी संकेत भेजता है. यदि अनुप्रयोग जिसने घंटी संकेत भेजा है. अज्ञात है तो " +#~ "( जैसा कि आमतौर पर डिफ़ॉल्ट \"तंत्र बीप\" में होता है), वर्तमान फ़ोकस विंडो का शीर्षक " +#~ "पट्टी फ्लैश करेगा. " + +#~ msgid "" +#~ "The /apps/metacity/global_keybindings/run_command_N keys define " +#~ "keybindings that correspond to these commands. Pressing the keybinding " +#~ "for run_command_N will execute command_N." +#~ msgstr "" +#~ "कुंजियाँ /apps/metacity/global_keybindings/run_command_N इन कमांड के तदनुरूप " +#~ "कीबाइंडिंग पारिभाषित करती हैं. run_command_N का कीबाइंडिंग दबाने पर यह " +#~ "command_N को चलाएगा. " + +#~ msgid "" +#~ "The /apps/metacity/global_keybindings/run_command_screenshot key defines " +#~ "a keybinding which causes the command specified by this setting to be " +#~ "invoked." +#~ msgstr "" +#~ "कुंजी /apps/metacity/global_keybindings/run_command_screenshot वह कीबाइंडिंग " +#~ "पारिभाषित करती है जो इस विन्यास से उल्लेखित कमांड को प्रारंभ करती है." + +#~ msgid "" +#~ "The /apps/metacity/global_keybindings/run_command_window_screenshot key " +#~ "defines a keybinding which causes the command specified by this setting " +#~ "to be invoked." +#~ msgstr "" +#~ "कुंजी /apps/metacity/global_keybindings/run_command_window_screenshot वह " +#~ "कीबाइंडिंग पारिभाषित करती है जो इस विन्यास से उल्लेखित कमांड को प्रारंभ करती है." + +#~ msgid "" +#~ "The keybinding that runs the correspondingly-numbered command in /apps/" +#~ "metacity/keybinding_commands The format looks like \"<Control>a\" " +#~ "or \"<Shift><Alt>F1\". The parser is fairly liberal and " +#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" +#~ "\" and \"<Ctrl>\". If you set the option to the special string " +#~ "\"disabled\", then there will be no keybinding for this action." +#~ msgstr "" +#~ "कीबाइंडिंग जो कि /apps/metacity/keybinding_commands के तदनुरूप नम्बर वाले कमांड " +#~ "को चलाता है . फ़ॉर्मेट इस तरह दिखेंगे \"<Control>a\" या \"<Shift><" +#~ "Alt>F1. यह पारसर पूरी तरह लिबरल है और बड़े या छोटे अक्षर दोनों स्वीकार करता है, " +#~ "तथा संक्षिप्ताक्षर भी जैसे- \"<Ctl>\" और \"<Ctrl>\". यदि आपने विकल्प " +#~ "विशेष स्ट्रिंग में तय किया है \"disabled\", तब वहाँ इस क्रिया हेतु कोई कीबाइंडिंग नहीं " +#~ "होगा." + +#~ msgid "The name of a workspace." +#~ msgstr "कार्यस्थान का नाम" + +#~ msgid "The screenshot command" +#~ msgstr "स्क्रीन-शॉट कमांड " + +#~ msgid "" +#~ "The theme determines the appearance of window borders, titlebar, and so " +#~ "forth." +#~ msgstr "प्रसंग, विंडो किनारा, शीर्षक पट्टी इत्यादि के रंग-रूप को निर्धारित करता है." + +#~ msgid "" +#~ "The time delay before raising a window if auto_raise is set to true. The " +#~ "delay is given in thousandths of a second." +#~ msgstr "" +#~ "यदि auto_raise सही पर नियत है तो विंडो ऊपर उठाने से पहले विलम्ब समय. यह विलम्ब " +#~ "सेकण्ड के हजारवें हिस्से में दिया जाता है." + +#~ msgid "" +#~ "The window focus mode indicates how windows are activated. It has three " +#~ "possible values; \"click\" means windows must be clicked in order to " +#~ "focus them, \"sloppy\" means windows are focused when the mouse enters " +#~ "the window, and \"mouse\" means windows are focused when the mouse enters " +#~ "the window and unfocused when the mouse leaves the window." +#~ msgstr "" +#~ "विंडो फ़ोकस मोड जो संकेत करता है कि विंडोज़ कैसे सक्रिय हों. इसके तीन संभावित मूल्य हैं, " +#~ "क्लिक \"क्लिक\" मतलब विंडो को फ़ोकस करने हेतु उनमें क्लिक करना होगा, \"स्लॉपी\" मतलब " +#~ "विंडो तब फ़ोकस होंगे जब माउस विंडो में प्रवेश करेगा, तथा \"माउस\" मतलब विंडो तब फ़ोकस " +#~ "होंगे जब माउस विंडो में प्रवेश करेगा तथा फ़ोकस से बाहर होगा जब माउस विंडो से बाहर " +#~ "होगा." + +#~ msgid "The window screenshot command" +#~ msgstr "विंडो स्क्रीन-शॉट कमांड " + +#~ msgid "" +#~ "This option determines the effects of double-clicking on the title bar. " +#~ "Current valid options are 'toggle_shade', which will shade/unshade the " +#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " +#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " +#~ "will maximize/unmaximize the window in that direction only, 'minimize' " +#~ "which will minimize the window, 'shade' which will roll the window up, " +#~ "'menu' which will display the window menu, 'lower' which will put the " +#~ "window behind all the others, and 'none' which will not do anything." +#~ msgstr "" +#~ "This option determines the effects of double-clicking on the title bar. " +#~ "Current valid options are 'toggle_shade', which will shade/unshade the " +#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " +#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " +#~ "will maximize/unmaximize the window in that direction only, 'minimize' " +#~ "which will minimize the window, 'shade' which will roll the window up, " +#~ "'menu' which will display the window menu, 'lower' which will put the " +#~ "window behind all the others, and 'none' which will not do anything." + +#~ msgid "" +#~ "This option determines the effects of middle-clicking on the title bar. " +#~ "Current valid options are 'toggle_shade', which will shade/unshade the " +#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " +#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " +#~ "will maximize/unmaximize the window in that direction only, 'minimize' " +#~ "which will minimize the window, 'shade' which will roll the window up, " +#~ "'menu' which will display the window menu, 'lower' which will put the " +#~ "window behind all the others, and 'none' which will not do anything." +#~ msgstr "" +#~ "This option determines the effects of middle-clicking on the title bar. " +#~ "Current valid options are 'toggle_shade', which will shade/unshade the " +#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " +#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " +#~ "will maximize/unmaximize the window in that direction only, 'minimize' " +#~ "which will minimize the window, 'shade' which will roll the window up, " +#~ "'menu' which will display the window menu, 'lower' which will put the " +#~ "window behind all the others, and 'none' which will not do anything." + +#~ msgid "" +#~ "This option determines the effects of right-clicking on the title bar. " +#~ "Current valid options are 'toggle_shade', which will shade/unshade the " +#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " +#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " +#~ "will maximize/unmaximize the window in that direction only, 'minimize' " +#~ "which will minimize the window, 'shade' which will roll the window up, " +#~ "'menu' which will display the window menu, 'lower' which will put the " +#~ "window behind all the others, and 'none' which will not do anything." +#~ msgstr "" +#~ "This option determines the effects of right-clicking on the title bar. " +#~ "Current valid options are 'toggle_shade', which will shade/unshade the " +#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " +#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " +#~ "will maximize/unmaximize the window in that direction only, 'minimize' " +#~ "which will minimize the window, 'shade' which will roll the window up, " +#~ "'menu' which will display the window menu, 'lower' which will put the " +#~ "window behind all the others, and 'none' which will not do anything." + +#~ msgid "" +#~ "This option provides additional control over how newly created windows " +#~ "get focus. It has two possible values; \"smart\" applies the user's " +#~ "normal focus mode, and \"strict\" results in windows started from a " +#~ "terminal not being given focus." +#~ msgstr "" +#~ "यह विकल्प अतिरिक्त नियंत्रण देता है कि कैसे नया बनाया विंडो फोकस पाता है. इसके दो " +#~ "संभावित मान हैं; \"smart\" उपयोक्ता के सामान्य फोकस मोड पर लागू होता है और " +#~ "\"strict\" ऐसे विंडो के रूप में आता है जो टर्मिनल से फोकस नहीं किये गये रूप में आता है." + +#~ msgid "" +#~ "Turns on a visual indication when an application or the system issues a " +#~ "'bell' or 'beep'; useful for the hard-of-hearing and for use in noisy " +#~ "environments." +#~ msgstr "" +#~ "दृश्य संकेत चालू करना जब कोई अनुप्रयोग या तंत्र घंटी या बीप जारी करते हैं तो, शोरयुक्त " +#~ "वातावरण- जहाँ सुनने में कठिनाई हो या उंचा सुनने वाले के लिये उपयोगी होता है." + +#~ msgid "Use standard system font in window titles" +#~ msgstr "विंडो शीर्षकों में मानक तंत्र फ़ॉन्ट प्रयोग करें" + +#~ msgid "Visual Bell Type" +#~ msgstr "दृष्टिगोच़र घंटी प्रकार" + +#~ msgid "Whether raising should be a side-effect of other user interactions" +#~ msgstr "अन्य उपयोक्ता अंतःक्रिया के प्रभाव को क्या उठाया जाना चाहिये" + +#~ msgid "Whether to resize with the right button" +#~ msgstr "क्या दाहिना बटन फिर आकार दिया जाना है" + +#~ msgid "Window focus mode" +#~ msgstr "विंडो फ़ोकस मोड" + +#~ msgid "Window title font" +#~ msgstr "विंडो शीर्षक फ़ॉन्ट" + +#~ msgid "Close Window" +#~ msgstr "विंडो बंद करें" + +#~ msgid "Window Menu" +#~ msgstr "विंडो मेनू" + +#~ msgid "Minimize Window" +#~ msgstr "विंडो न्यूनतम करें" + +#~ msgid "Maximize Window" +#~ msgstr "विंडो अधिकतम करें" + +#~ msgid "Restore Window" +#~ msgstr "विंडो फिर बहाल करें" + +#~ msgid "Roll Up Window" +#~ msgstr "विंडो रॉल अप करें" + +#~ msgid "Unroll Window" +#~ msgstr "विंडो खोलें" + +#~ msgid "Keep Window On Top" +#~ msgstr "विंडो को सबसे ऊपर रखें" + +#~ msgid "Always On Visible Workspace" +#~ msgstr "हमेशा दृश्य कार्यस्थान पर" + +#~ msgid "Put Window On Only One Workspace" +#~ msgstr "सिर्फ एक कार्यस्थान पर विंडो रखें" + +# #-#-#-#-# libgnomeui.HEAD.hi.po (libgnomeui-2.0.hi) #-#-#-#-# +# libgnomeui/gnome-druid-page-standard.c:121 +# libgnomeui/gnome-font-picker.c:155 +#~ msgid "Title" +#~ msgstr "शीर्षक" + +#~ msgid "Class" +#~ msgstr "वर्ग" + +#~ msgid "" +#~ "There was an error running \"%s\":\n" +#~ "%s." +#~ msgstr "" +#~ "\"%s\" को चलाने में त्रुटि थी:\n" +#~ "%s." + +#~ msgid "<author> specified twice for this theme" +#~ msgstr "<लेखक> इस प्रसंग हेतु दोबार उल्लेखित किया गया है" + +#~ msgid "<copyright> specified twice for this theme" +#~ msgstr " <सर्वाधिकार सुरक्षित> इस प्रसंग हेतु दोबार उल्लेखित किया गया है" + +#~ msgid "<date> specified twice for this theme" +#~ msgstr "<तिथि> इस प्रसंग हेतु दोबार उल्लेखित किया गया है" + +#~ msgid "<description> specified twice for this theme" +#~ msgstr " <विवरण> इस प्रसंग हेतु दोबार उल्लेखित किया गया है" + +#~ msgid "Theme file %s did not contain a root <metacity_theme> element" +#~ msgstr "प्रसंग फ़ाइल %s में रूट <मेटासिटी-प्रसंग> तत्व सम्मिलित नहीं है" + +#~ msgid "/Windows/tearoff" +#~ msgstr "/विंडोज़/टीयरऑफ़" + +#~ msgid "/Windows/_Dialog" +#~ msgstr "/विंडोज़/संवाद (_D)" + +#~ msgid "/Windows/_Modal dialog" +#~ msgstr "/विंडोज़/मॉडल संवाद (_M)" +#~ msgid "/Windows/Des_ktop" +#~ msgstr "/विंडोज़/डेस्कटॉप (_k)" diff --git a/po/hr.po b/po/hr.po index f4c7ef2c1..10afdefcf 100644 --- a/po/hr.po +++ b/po/hr.po @@ -4,3656 +4,3429 @@ msgid "" msgstr "" "Project-Id-Version: metacity 0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-09-09 17:59+0200\n" -"PO-Revision-Date: 2008-04-11 03:22+0000\n" -"Last-Translator: Launchpad Translations Administrators <rosetta@launchpad." -"net>\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2020-02-23 17:41+0000\n" +"PO-Revision-Date: 2020-03-01 16:54+0100\n" +"Last-Translator: gogo <linux.hr@protonmail.com>\n" "Language-Team: Croatian <lokalizacija@linux.hr>\n" +"Language: hr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%" -"10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "X-Launchpad-Export-Date: 2008-05-28 13:28+0000\n" -"X-Generator: Launchpad (build Unknown)\n" +"X-Generator: Poedit 2.0.6\n" -#: ../src/50-metacity-desktop-key.xml.in.h:1 -msgid "Desktop" -msgstr "Radna površina" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Navigacija" -#: ../src/50-metacity-key.xml.in.h:1 -msgid "Window Management" -msgstr "Upravitelj prozorima" +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Premjesti prozor na radni prostor 1" -#: ../src/core/core.c:206 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Nepoznati zahtijev informacija o prozoru: %d" +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Premjesti prozor na radni prostor 2" -#: ../src/core/delete.c:70 ../src/core/delete.c:97 -#: ../src/ui/metacity-dialog.c:50 ../src/ui/theme-parser.c:481 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "Nije moguće analizirati \"%s\" kao cijeli broj" +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Premjesti prozor na radni prostor 3" -#: ../src/core/delete.c:77 ../src/core/delete.c:104 -#: ../src/ui/metacity-dialog.c:57 ../src/ui/theme-parser.c:490 -#: ../src/ui/theme-parser.c:545 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "Nisam shvatio slijedece znakove \"%s\" u nizu podataka \"%s\"" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Premjesti prozor na radni prostor 4" -#: ../src/core/delete.c:135 -#, c-format -msgid "Failed to parse message \"%s\" from dialog process\n" -msgstr "Nije uspjelo analiziranje poruke \"%s\" iz dijaloškog procesa\n" +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Premjesti prozor posljednji radni prostor" -#: ../src/core/delete.c:253 -#, c-format -msgid "Error reading from dialog display process: %s\n" -msgstr "Pogreška pri čitanju kod procesa ekrana dijaloga: %s\n" +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "Premjesti prozor jedan radni prostor gore" -#: ../src/core/delete.c:336 -#, c-format -msgid "" -"Error launching metacity-dialog to ask about killing an application: %s\n" -msgstr "" -"Greška pri pokretanju metacity-dialoga za potvrdu o zatvaranju aplikacije %" -"s\n" +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "Premjesti prozor jedan radni prostor dolje" -#: ../src/core/delete.c:445 -#, c-format -msgid "Failed to get hostname: %s\n" -msgstr "Nije uspjelo dobivanje imena računala: %s\n" +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "Premjesti prozor jedan zaslon nalijevo" -#: ../src/core/display.c:256 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "Nedostaje ekstenzija %s potrebna za stvaranje kompozicije" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "Premjesti prozor jedan zaslon udesno" -#: ../src/core/display.c:334 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Nije uspjelo otvaranje X Window System prikaza'%s'\n" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "Premjesti prozor jedan zaslon gore" -#: ../src/core/errors.c:272 -#, c-format -msgid "" -"Lost connection to the display '%s';\n" -"most likely the X server was shut down or you killed/destroyed\n" -"the window manager.\n" -msgstr "" -"Izubljen spoj sa prikazom '%s';\n" -"najvjerojatnije je X server ugašen, ili ste ubili/ubištili\n" -"rukovoditelja prozora.\n" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "Premjesti prozor jedan zaslon dolje" -#: ../src/core/errors.c:279 -#, c-format -msgid "Fatal IO error %d (%s) on display '%s'.\n" -msgstr "Kobna IO greška %d (%s) na prikazu '%s'.\n" +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "Prebacivanje aplikacija" -#: ../src/core/keybindings.c:924 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "" -"Neki drugi prograk već koristi kljuć %s sa modifikacijama %x kao spoj\n" +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "Prebaci na prijašnju aplikaciju" -#: ../src/core/keybindings.c:2563 -#, c-format -msgid "Error launching metacity-dialog to print an error about a command: %s\n" -msgstr "" -"Greška pri pokretanju metacity-dialoga za ispisom greške o komandi %s\n" +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "Prebacivanje prozora" -#: ../src/core/keybindings.c:2668 -#, c-format -msgid "No command %d has been defined.\n" -msgstr "Naredba %d nije definirana.\n" +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "Prebaci na prijašnji prozor" -#: ../src/core/keybindings.c:3705 -msgid "No terminal command has been defined.\n" -msgstr "Niti jedna konzolna naredba nije definirana\n" +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "Prebacivanje prozora aplikacija" -#: ../src/core/main.c:116 -#, c-format -msgid "" -"metacity %s\n" -"Copyright (C) 2001-2008 Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "Prebaci na prijašnji prozor aplikacije" -#: ../src/core/main.c:253 -msgid "Disable connection to session manager" -msgstr "Isključi vezu prema upravitelju sesija" +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "Prebacivanje upravljanja sustavom" -#: ../src/core/main.c:259 -msgid "Replace the running window manager with Metacity" -msgstr "Zamjeni tekući upravitelj porozorima sa Metacity" +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "Prebaci na prijašnje upravljanje sustavom" -#: ../src/core/main.c:265 -msgid "Specify session management ID" -msgstr "Odredite ID upravljanja sesijama" +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "Prebacivanje izravno na prozor" -#: ../src/core/main.c:270 -msgid "X Display to use" -msgstr "Koji X Display da koristim" +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "Prebaci izravno na prijašnji prozor" -#: ../src/core/main.c:276 -msgid "Initialize session from savefile" -msgstr "Inicijaliziraj sesiju iz spremljene datoteke" +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "Prebacivanje prozora aplikacije izravno" -#: ../src/core/main.c:282 -msgid "Print version" -msgstr "Inačica za ispis" +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "Prebaci izravno na prijašnji prozor aplikacije" -#: ../src/core/main.c:288 -msgid "Make X calls synchronous" -msgstr "" +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "Prebacivanje upravljanja sustavom izravno" -#: ../src/core/main.c:294 -msgid "Turn compositing on" -msgstr "Uključi kompoziciju" +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "Prebaci izravno na prijašnje upravljanje sustavom" -#: ../src/core/main.c:300 -msgid "Turn compositing off" -msgstr "Isključi kompoziciju" +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "Sakrij sve normalne prozore" -#: ../src/core/main.c:451 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Nisam uspio pretražiti mapu tema: %s\n" +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "Prebaci se na radni prostor 1" -#: ../src/core/main.c:467 -#, c-format -msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "" -"Nije moguće naći temu! Provjerite postoji li %s i sadrži li uobičajene " -"teme.\n" +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "Prebaci se na radni prostor 2" -#: ../src/core/main.c:526 -#, c-format -msgid "Failed to restart: %s\n" -msgstr "Nije uspjelo ponovno pokretanje: %s\n" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "Prebaci se na radni prostor 3" -#. -#. * We found it, but it was invalid. Complain. -#. * -#. * FIXME: This replicates the original behaviour, but in the future -#. * we might consider reverting invalid keys to their original values. -#. * (We know the old value, so we can look up a suitable string in -#. * the symtab.) -#. -#: ../src/core/prefs.c:503 ../src/core/prefs.c:655 -#, c-format -msgid "GConf key '%s' is set to an invalid value\n" -msgstr "GConf ključ '%s' je postavljen na neispravnu vrijednost\n" - -#: ../src/core/prefs.c:584 ../src/core/prefs.c:824 -#, fuzzy, c-format -msgid "%d stored in GConf key %s is out of range %d to %d\n" -msgstr "%d pohranjen u GConf ključu %s je izvan dometa od 0 do %d\n" - -#: ../src/core/prefs.c:628 ../src/core/prefs.c:702 ../src/core/prefs.c:750 -#: ../src/core/prefs.c:814 ../src/core/prefs.c:1109 ../src/core/prefs.c:1125 -#: ../src/core/prefs.c:1144 ../src/core/prefs.c:1160 ../src/core/prefs.c:1177 -#: ../src/core/prefs.c:1193 -#, c-format -msgid "GConf key \"%s\" is set to an invalid type\n" -msgstr "GConf ključ \"%s\" je postavljen na neispravan tip\n" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "Prebaci se na radni prostor 4" -#: ../src/core/prefs.c:1263 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"Kompromisi za loše programe su isključeni. Neki programi se mogu ponašati " -"čudno.\n" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "Prebaci na prijašnji radni prostor" -#: ../src/core/prefs.c:1333 -#, c-format -msgid "Could not parse font description \"%s\" from GConf key %s\n" -msgstr "Nije moguće analizirati opis pisma \"%s\" iz Gconf ključa %s\n" +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "Premjesti na gornji radni prostor" -#: ../src/core/prefs.c:1393 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"“%s“ je pronađen u bazi podešavanja što nije ispravna vrijednost za tipku " -"koja mijenja ponašanje tipki miša\n" +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "Premjesti na donji radni prostor" -#: ../src/core/prefs.c:1810 -#, c-format -msgid "Error setting number of workspaces to %d: %s\n" -msgstr "Pogreška prilikom podešavanja broja radnih površina na %d: %s\n" +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "Sustav" -#: ../src/core/prefs.c:2131 ../src/core/prefs.c:2643 -#, fuzzy, c-format -msgid "Workspace %d" -msgstr "Pomakni na _gornju radnu površinu" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Prikaži dijalog pokretanja naredbe" -#: ../src/core/prefs.c:2161 ../src/core/prefs.c:2334 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "\"%s\" nađen u bazi postavki nije ispravna kombinacija tipki \"%s\"\n" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Prikaži pregled aktivnosti" -#: ../src/core/prefs.c:2724 -#, c-format -msgid "Error setting name for workspace %d to \"%s\": %s\n" -msgstr "Pogreška prilikom podešavanja imena radne površine %d u \"%s\": %s\n" +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Vrati izvorne prečace tipkovnice" -#: ../src/core/prefs.c:2917 -#, fuzzy, c-format -msgid "Error setting compositor status: %s\n" -msgstr "Pogreška prilikom podešavanja imena radne površine %d u \"%s\": %s\n" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Prozori" -#: ../src/core/screen.c:350 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "Ekran %d na prikazu '%s' je neispravan\n" +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "Aktiviraj izbornik prozora" -#: ../src/core/screen.c:366 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"Ekran %d na prikazu \"%s\" već ima rkovoditelja prozora; pokušajte koristiti " -"--replace opciju da zamjenite trenutni rukovoditelj prozora.\n" +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Uklj/Isklj cjelozaslonski prikaz" -#: ../src/core/screen.c:393 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "" -"Nije moguće dobiti biranje upravitelja prozora na ekranu %d prikaza \"%s\"\n" +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "Uklj/Isklj uvećanje prozora" -#: ../src/core/screen.c:451 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "Ekran %d na prikazu \"%s\" već ima rukovoditelj prozora\n" +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "Uvećaj prozor" -#: ../src/core/screen.c:661 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "Nije moguće izbaciti otpustiti ekran %d na prikazu \"%s\"\n" +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Vrati prozor" -#: ../src/core/session.c:837 ../src/core/session.c:844 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Nije moguće napraviti mapu '%s': %s\n" +#: data/50-mutter-windows.xml:18 +msgid "Close window" +msgstr "Zatvori prozor" -#: ../src/core/session.c:854 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "Nije moguće otvoriti datoteku '%s' za zapis: %s\n" +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "Sakrij prozor" -#: ../src/core/session.c:995 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Pogreška zapisivanja datoteke sesije '%s': %s\n" +#: data/50-mutter-windows.xml:22 +msgid "Move window" +msgstr "Premjesti prozor" -#: ../src/core/session.c:1000 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Greška pri zatvaranju session datoteke '%s': %s\n" +#: data/50-mutter-windows.xml:24 +msgid "Resize window" +msgstr "Promijeni veličinu prozora" -#. oh, just give up -#: ../src/core/session.c:1093 -#, c-format -msgid "Failed to read saved session file %s: %s\n" -msgstr "Nije uspjelo čitanje snimljene datoteke sesije %s: %s\n" +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "Uklj/Isklj prozor na svim radnim prostorima" -#: ../src/core/session.c:1132 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Nije uspjela analiza snimljene datoteke sesije: %s\n" +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "Podigni prekriven prozor, u suprotnome smanji" -#: ../src/core/session.c:1181 -msgid "<metacity_session> attribute seen but we already have the session ID" -msgstr "<metacity_session> atribut opažen ali već imamo ID sesije" +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "Podigni prozor iznad ostalih prozora" -#: ../src/core/session.c:1194 -#, c-format -msgid "Unknown attribute %s on <metacity_session> element" -msgstr "Nepoznato svojstvo %s u <metacity_session> elementu" +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "Spusti prozor ispod ostalih prozora" -#: ../src/core/session.c:1211 -msgid "nested <window> tag" -msgstr "ugniježden <window> tag" +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "Uvećaj prozor okomito" -#: ../src/core/session.c:1269 ../src/core/session.c:1301 -#, c-format -msgid "Unknown attribute %s on <window> element" -msgstr "Nepoznato svojstvo %s u <window> elementu" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "Uvećaj prozor vodoravno" -#: ../src/core/session.c:1373 -#, c-format -msgid "Unknown attribute %s on <maximized> element" -msgstr "Nepoznato svojstvo %s u <maximized> elementu" +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "Podijeli pogled ulijevo" -#: ../src/core/session.c:1433 -#, c-format -msgid "Unknown attribute %s on <geometry> element" -msgstr "Nepoznato svojstvo %s u <geometry> elementu" +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "Podijeli pogled udesno" -#: ../src/core/session.c:1453 -#, c-format -msgid "Unknown element %s" -msgstr "Nepoznati element %s" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" -#: ../src/core/session.c:1879 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:7 +msgid "Modifier to use for extended window management operations" +msgstr "Izmjenjivač za korištenje radnji proširenog upravljanja prozorom" + +#: data/org.gnome.mutter.gschema.xml.in:8 msgid "" -"Error launching metacity-dialog to warn about apps that don't support " -"session management: %s\n" +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." msgstr "" -"Greška pri pokretanju metacity-dialoga da upozori aplikacije koje ne " -"podržavaju session managment %s\n" +"Ova tipka će pokrenuti \"pregled\", što je kombinacija prikaza prozora i " +"sustava pokretanja aplikacije. Zadana namjena je \"Super tipka\" na PC " +"tipkovnici. Očekivano je da je ova kombinacija zadana ili postavljena na " +"prazan niz." -#: ../src/core/util.c:101 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Nije uspjelo otvaranje zapisnika o ispravku grešaka: %s\n" +#: data/org.gnome.mutter.gschema.xml.in:20 +msgid "Attach modal dialogs" +msgstr "Pričvrsti prozore dijaloga" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Nije uspjelo fdopen() datoteke zapisnika%s: %s\n" +#: data/org.gnome.mutter.gschema.xml.in:21 +msgid "" +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." +msgstr "" +"Ako je odabrano, umjesto zasebnih naslovnih traka, dijalozi su pričvršćeni " +"na naslovnu traku sadržajnog prozora i pomiču se zajedno sa sadržajnim " +"prozorom." -#: ../src/core/util.c:117 -#, c-format -msgid "Opened log file %s\n" -msgstr "Otvorena zapisnička datoteka %s\n" +#: data/org.gnome.mutter.gschema.xml.in:30 +msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "Omogući rubno popločavanje pri ispuštanju prozora na rubovima zaslona" -#: ../src/core/util.c:136 ../src/tools/metacity-message.c:176 -msgid "Metacity was compiled without support for verbose mode\n" -msgstr "Metaciti je kompajliran bez podrške za preopširan način rada\n" +#: data/org.gnome.mutter.gschema.xml.in:31 +msgid "" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." +msgstr "" +"Ako je omogućeno, ispuštanje prozora na okomite rubove zaslona uvećava ih " +"okomito i prilagođava veličinu vodoravno da prekrije polovicu dostupnog " +"područja. Ispuštanje prozora na gornji rub zaslona uvećava ih u potpunosti." -#: ../src/core/util.c:236 -msgid "Window manager: " -msgstr "Upravitelj prozora: " +#: data/org.gnome.mutter.gschema.xml.in:40 +msgid "Workspaces are managed dynamically" +msgstr "Radni prostori su upravljani promjenjivo" -#: ../src/core/util.c:388 -msgid "Bug in window manager: " -msgstr "Greška u upravitelju prozora: " +#: data/org.gnome.mutter.gschema.xml.in:41 +msgid "" +"Determines whether workspaces are managed dynamically or whether there’s a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." +msgstr "" +"Određuje jesu li radni prostori upravljani promjenjivo ili postoji određeni " +"broj radnih prostora (određeno brojem ključa radnih prostora u org.gnome." +"desktop.wm.preferences)." -#: ../src/core/util.c:421 -msgid "Window manager warning: " -msgstr "Upozorenje upravitelja prozora: " +#: data/org.gnome.mutter.gschema.xml.in:50 +msgid "Workspaces only on primary" +msgstr "Radni prostori samo na glavnom zaslonu" -#: ../src/core/util.c:449 -msgid "Window manager error: " -msgstr "Greška upravitelja prozora: " +#: data/org.gnome.mutter.gschema.xml.in:51 +msgid "" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." +msgstr "" +"Određuje treba li se prebacivanje radnog prostora pokrenuti za prozore na " +"svim zaslonima ili samo za prozore na glavnom zaslonu." -#: ../src/core/window-props.c:206 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "Program je postavio neispravan NET_WM_PID %lu\n" +#: data/org.gnome.mutter.gschema.xml.in:59 +msgid "No tab popup" +msgstr "Bez skočnih prozora" -#: ../src/core/window-props.c:338 -#, c-format -msgid "%s (on %s)" -msgstr "%s (na %s)" +#: data/org.gnome.mutter.gschema.xml.in:60 +msgid "" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." +msgstr "" +"Određuje treba li onemogućiti korištenje skočnog prozora i naglašavanje " +"okvira za kruženje prozora." -#: ../src/core/window-props.c:1420 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "Neispravan WM_TRANSIENT_FOR prozor 0x%lx specificiran za %s.\n" +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Odgoda promjene fokusa dok se pokazivač prestane pomicati" -#. first time through -#: ../src/core/window.c:5643 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:69 msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." msgstr "" -"Prozor %s je postavio SM_CLIENT_ID na samog sebe umjesto na prozor " -"WM_CLIENT_LEADER kao što je navedeno u ICCCM.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:6208 -#, c-format +"Ako je odabrano, a način fokusa je \"sloppy\" ili \"mouse\", tada se fokus " +"neće odmah promijeniti kada se prebaci na prozor, nego nakon što se " +"pokazivač prestane pomicati." + +#: data/org.gnome.mutter.gschema.xml.in:79 +msgid "Draggable border width" +msgstr "Širina granice povlačenja" + +#: data/org.gnome.mutter.gschema.xml.in:80 msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %" -"d x %d and max size %d x %d; this doesn't make much sense.\n" +"The amount of total draggable borders. If the theme’s visible borders are " +"not enough, invisible borders will be added to meet this value." msgstr "" -"Prozor %s je postavio MWM što nagovještava da nije promjenjljive veličine, " -"ali je postavio minimalnu veličinu %d x %d i maksimalnu veličinu %d x %d što " -"nema mnogo smisla.\n" +"Količina ukupne granice povlačenja. Ako vidljiva granica teme nije dovoljna, " +"nevidljiva granica će biti dodana kako bi se zadovoljila ova vrijednost." -#: ../src/core/xprops.c:155 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "Automatski uvećaj prozore veličine približne zaslonu" + +#: data/org.gnome.mutter.gschema.xml.in:90 msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." msgstr "" -"Prozor 0x%lx ima osobinu %s\n" -"tako da je očekivano da ima tip %s format %d,\n" -"a zapravo ima tip %s format %d n_items %d.\n" -"Ovo je najverovatnije greška u programu, a ne u menadžeru prozora.\n" -"Prozor ima naslov=\"%s\" klasa=\"%s\" ime=\"%s\"\n" +"Ako je odabrano novi prozori koju su približno veličine zaslona automatski " +"se uvečavaju." -#: ../src/core/xprops.c:401 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "Svojstvo %s na prozoru 0x%lx je sadržalo neispravni UTF-8\n" +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Smjesti novi prozor u sredinu" -#: ../src/core/xprops.c:484 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:99 msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." msgstr "" -"Svojstvo %s na prozoru 0x%lx sadrži neispravni UTF-8 za predmet %d na " -"popisu\n" - -#: ../src/metacity.desktop.in.h:1 -msgid "Metacity" -msgstr "Metacity" +"Ako je odabrano, novi prozor će uvijek biti u sredini aktivnog zaslona." -#: ../src/metacity.schemas.in.h:1 -msgid "(Not implemented) Navigation works in terms of applications not windows" -msgstr "(Nije ugrađeno) Navigacija radi u smislu aplikacija, ne prozora" +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Omogući eksperimentalne značajke" -#: ../src/metacity.schemas.in.h:2 +#: data/org.gnome.mutter.gschema.xml.in:108 msgid "" -"A font description string describing a font for window titlebars. The size " -"from the description will only be used if the titlebar_font_size option is " -"set to 0. Also, this option is disabled if the titlebar_uses_desktop_font " -"option is set to true." +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes " +"mutter request a low priority real-time scheduling. The executable or user " +"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — " +"initializes Xwayland lazily if there are X11 clients. Requires restart." msgstr "" -"Znakovni niz koji opisuje font za naslovnu traku prozora. Veličina će iz " -"opisa biti upotrebljena samo ako je titlebar_font_size opcija postavljena na " -"0. Također, ova opcija je onemogućena ako je titlebar_uses_desktop_font " -"postavljena." +"Za omogućavanje eksperimentalnih značajki, dodajte ključnu riječ značajke na " +"popis. Zahtijeva li značajka ponovno pokretanje kompozitora ovisi o zadanoj " +"značajki. Bilo koja eksperimentalna značajka nije potrebna da još uvijek " +"bude dostupna ili podesiva. Nemojte očekivati da možete dodavati bilo što u " +"ovu postavku za budući dokaz. Trenutne dostupne ključne riječi: • “scale-" +"monitor-framebuffer” — čini mutter zadanim izlazu logičkih zaslona u " +"logičnom koordinatnom prostoru piksela, dok međuspremnik okvira mijenja " +"veličinu zaslona umjesto sadržaja prozora, kako bi upravljao (HiDPI) " +"zaslonima visoke razlučivosti. Ne zahtijeva ponovno pokretanje. • “rt-" +"scheduler” — čini zahtjeve muttera zakazanima u niskom prioritetu i " +"stvaranom vremenu. Izvršitelj ili korisnik mora imati CAP_SYS_NICE. " +"Zahtijeva ponovno pokretanje. • “autostart-xwayland” — pokreće Xwayland " +"lijeno ako je dostupan X11 klijent. Zahtijeva ponovno pokretanje." -#: ../src/metacity.schemas.in.h:3 -msgid "Action on title bar double-click" -msgstr "Akcija na naslovnom meniju dvostruki-klik" +#: data/org.gnome.mutter.gschema.xml.in:134 +msgid "Modifier to use to locate the pointer" +msgstr "Izmjenjivač za korištenje lociranja pokazivača" -#: ../src/metacity.schemas.in.h:4 -msgid "Action on title bar middle-click" -msgstr "" +#: data/org.gnome.mutter.gschema.xml.in:135 +msgid "This key will initiate the “locate pointer” action." +msgstr "Ova tipka će pokrenuti “lociraj pokazivač” radnju." -#: ../src/metacity.schemas.in.h:5 -msgid "Action on title bar right-click" -msgstr "" +#: data/org.gnome.mutter.gschema.xml.in:142 +msgid "Timeout for check-alive ping" +msgstr "Vrijeme isteka provjere odgovora pinga" + +#: data/org.gnome.mutter.gschema.xml.in:143 +msgid "" +"Number of milliseconds a client has to respond to a ping request in order to " +"not be detected as frozen. Using 0 will disable the alive check completely." +msgstr "" +"Broj milisekundi za koje klijent treba odgovoriti na zahtjev pinga kako ne " +"bi bio otkriven kao smrznut. Korištenje 0 će u potpunosti onemogućiti " +"provjeru odgovora pinga." + +#: data/org.gnome.mutter.gschema.xml.in:165 +msgid "Select window from tab popup" +msgstr "Odaberi prozor iz skočnog prozora" + +#: data/org.gnome.mutter.gschema.xml.in:170 +msgid "Cancel tab popup" +msgstr "Prekini skočni prozor" + +#: data/org.gnome.mutter.gschema.xml.in:175 +msgid "Switch monitor configurations" +msgstr "Prebacivanje podešavanja zaslona" + +#: data/org.gnome.mutter.gschema.xml.in:180 +msgid "Rotates the built-in monitor configuration" +msgstr "Rotiraj ugrađeno podešavanje zaslona" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Prebaci na VT 1" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Prebaci na VT 2" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Prebaci na VT 3" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Prebaci na VT 4" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Prebaci na VT 5" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Prebaci na VT 6" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Prebaci na VT 7" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Prebaci na VT 8" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Prebaci na VT 9" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Prebaci na VT 10" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Prebaci na VT 11" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Prebaci na VT 12" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "Ponovno omogući prečace" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow X11 grabs to lock keyboard focus with Xwayland" +msgstr "Dopusti da X11 hvatanje zaključa fokus tipkovnice sa Xwaylandom" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 +msgid "" +"Allow all keyboard events to be routed to X11 “override redirect” windows " +"with a grab when running in Xwayland. This option is to support X11 clients " +"which map an “override redirect” window (which do not receive keyboard " +"focus) and issue a keyboard grab to force all keyboard events to that " +"window. This option is seldom used and has no effect on regular X11 windows " +"which can receive keyboard focus under normal circumstances. For a X11 grab " +"to be taken into account under Wayland, the client must also either send a " +"specific X11 ClientMessage to the root window or be among the applications " +"white-listed in key “xwayland-grab-access-rules”." +msgstr "" +"Dopusti svim događajima tipkovnice da budu usmjereni u X11 “override " +"redirect” prozore i obuhvaćeni kada su pokrenuti u Xwaylandu. Ova mogućnost " +"podržava X11 klijente koji mapiraju “override redirect” prozor (koji nije u " +"fokusu tipkovnice) i pokreće obuhvatanje tipkovnice i prisiljuje sve " +"događaje tipkovnice na taj prozor. Ova mogućnost rijetko se koristi i nema " +"učinka na uobičajene X11 prozore koji mogu primiti fokus tipkovnice u " +"normalnim okolnostima. Kako bi X11 hvatanje bilo obuhvaćeno računom u " +"Waylandu, klijent mora poslati ili određenu X11 poruku klijenta u korijenski " +"prozor ili mora biti naveden među aplikacijama dopuštenim u ključu “xwayland-" +"grab-access-rules”." + +#: data/org.gnome.mutter.wayland.gschema.xml.in:84 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "Xwayland aplikacije dopuštene za izdavanje hvatanja tipkovnice" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:85 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "" +"Popis naziva ili razreda resursa X11 prozora koji dopuštaju ili nedopuštaju " +"izdavanje X11 hvatanja tipkovnice u Xwaylandu. Popis naziva ili razreda " +"resursa danog X11 prozora može se omogućiti naredbom “xprop WM_CLASS”. " +"Zvjezdice “*” i upitnici “?” u vrijednostima su podržani. Vrijednosti koje " +"počinju sa “!” nisu dopuštene, a imaju prednost nad dopuštenim, kako bi " +"opozvali aplikaciju iz zadanog popisa sustavom. Zadani popis sustava " +"uključuje sljedeće aplikacije: “@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” " +"Korisnici mogu prekinuti postojeće hvatanje koristeći određeni prečac " +"tipkovnice određen ključem prečaca tipkovnice “restore-shortcuts”." + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. +#. +#: src/backends/meta-input-settings.c:2567 +#, c-format +msgid "Mode Switch (Group %d)" +msgstr "Način prebacivanja (Grupa %d)" -#: ../src/metacity.schemas.in.h:6 -msgid "Activate window menu" -msgstr "Aktiviraj prozor izbornika" +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2590 +msgid "Switch monitor" +msgstr "Prebaci zaslon" -#: ../src/metacity.schemas.in.h:7 -msgid "Arrangement of buttons on the titlebar" -msgstr "Aranžman funkcijskih tipki na naslovoj traci" +#: src/backends/meta-input-settings.c:2592 +msgid "Show on-screen help" +msgstr "Prikaži zaslonsku pomoć" -#: ../src/metacity.schemas.in.h:8 -#, fuzzy -msgid "" -"Arrangement of buttons on the titlebar. The value should be a string, such " -"as \"menu:minimize,maximize,spacer,close\"; the colon separates the left " -"corner of the window from the right corner, and the button names are comma-" -"separated. Duplicate buttons are not allowed. Unknown button names are " -"silently ignored so that buttons can be added in future metacity versions " -"without breaking older versions. A special spacer tag can be used to insert " -"some space between two adjacent buttons." -msgstr "" -"Raspored gumba na naslovnoj traci. Vrijednost treba biti niz znakova, kao na " -"primjer „menu:minimize,maximize,close“; dvije točke razdvaju lijevi kut " -"prozora od desnog, a gumbi su razdvojeni točka-zarezima. Dupliranje gumba " -"nije dozvoljeno. Nepoznata imena gumba se zanemaruju tako da se gumbi koji " -"će se dodavati u buduće inačice metacitya bez poremećenja starijih inačica." +#: src/backends/meta-monitor.c:223 +msgid "Built-in display" +msgstr "Ugrađeni zaslon" -#: ../src/metacity.schemas.in.h:9 -msgid "Automatically raises the focused window" -msgstr "Automatski podiže prozor sa fokusom" +#: src/backends/meta-monitor.c:252 +msgid "Unknown" +msgstr "Nepoznat" -#: ../src/metacity.schemas.in.h:10 +#: src/backends/meta-monitor.c:254 +msgid "Unknown Display" +msgstr "Nepoznat zaslon" + +#: src/backends/meta-monitor.c:262 +#, c-format +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" + +#: src/backends/meta-monitor.c:270 +#, c-format +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" + +#. Translators: this string will appear in Sysprof +#: src/backends/meta-profiler.c:79 +msgid "Compositor" +msgstr "Kompozitor" + +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:533 +#, c-format msgid "" -"Clicking a window while holding down this modifier key will move the window " -"(left click), resize the window (middle click), or show the window menu " -"(right click). Modifier is expressed as \"<Alt>\" or \"<Super>\" " -"for example." +"Another compositing manager is already running on screen %i on display “%s”." msgstr "" -"Pritiskom na prozor za vrijeme držanja ove tipke premejestiti će prozor " -"(lijeva tipka miša), podići prozor (srednja tipka miša) ili prikazati glavni " -"izbornik (desna tipka miša). Tipka može biti na primjer \"<Alr>\" ili " -"\"<Super>\"" +"Drugi upravitelja kompoziranja već je pokrenut na zaslonu %i prikaza \"%s\"." -#: ../src/metacity.schemas.in.h:11 -msgid "Close window" -msgstr "Zatvori prozor" +#: src/core/bell.c:192 +msgid "Bell event" +msgstr "Događaj zvona" -#: ../src/metacity.schemas.in.h:12 -msgid "Commands to run in response to keybindings" -msgstr "Naredbe koje će se pokrenuti na odaziv kombinacije tipki sa tipkovnice" +#: src/core/main.c:190 +msgid "Disable connection to session manager" +msgstr "Onemogući povezivanje sa upraviteljem sesija" -#: ../src/metacity.schemas.in.h:13 -msgid "Compositing Manager" -msgstr "Kompozitni upravitelj" +#: src/core/main.c:196 +msgid "Replace the running window manager" +msgstr "Zamijeni pokrenutoga upravitelja porozora" -#: ../src/metacity.schemas.in.h:14 -msgid "Control how new windows get focus" -msgstr "Kontrola fokusiranja novih prozora" +#: src/core/main.c:202 +msgid "Specify session management ID" +msgstr "Odredite ID upravljanja sesijama" -#: ../src/metacity.schemas.in.h:15 -msgid "Current theme" -msgstr "Trenutna tema" +#: src/core/main.c:207 +msgid "X Display to use" +msgstr "X Prikaz za korištenje" -#: ../src/metacity.schemas.in.h:16 -msgid "Delay in milliseconds for the auto raise option" -msgstr "Odgoda u milisekundama za opciju automatskog podizanja" +#: src/core/main.c:213 +msgid "Initialize session from savefile" +msgstr "Pokreni sesiju iz spremljene datoteke" -#: ../src/metacity.schemas.in.h:17 -msgid "Determines whether Metacity is a compositing manager." -msgstr "Određuje li je Metacity kompozitni upravitelj." +#: src/core/main.c:219 +msgid "Make X calls synchronous" +msgstr "Napravi X pozive usklađenim" -#: ../src/metacity.schemas.in.h:18 -msgid "" -"Determines whether applications or the system can generate audible 'beeps'; " -"may be used in conjunction with 'visual bell' to allow silent 'beeps'." -msgstr "" -"Određuje hoće li aplikacije ili sistem generirati zvučne 'beepove'može se " -"koristiti u spoju sa 'vizualnim zvonom' da se dozvoli tihi 'beep'" +#: src/core/main.c:226 +msgid "Run as a wayland compositor" +msgstr "Pokreni wayland kompozitor" -#: ../src/metacity.schemas.in.h:19 -msgid "Disable misfeatures that are required by old or broken applications" -msgstr "Isključi mogućnosti potrebne za stare ili neispravne aplikacijie" +#: src/core/main.c:232 +msgid "Run as a nested compositor" +msgstr "Pokreni kao ugrađeni kompozitor" -#: ../src/metacity.schemas.in.h:20 -msgid "Enable Visual Bell" -msgstr "Aktiviraj vidni signal" +#: src/core/main.c:238 +msgid "Run wayland compositor without starting Xwayland" +msgstr "Pokreni wayland kompozitor bez pokretanja Xwaylanda" -#: ../src/metacity.schemas.in.h:21 -msgid "Hide all windows and focus desktop" -msgstr "Sakrij sve prozore i pokaži radnu površinu" +#: src/core/main.c:246 +msgid "Run as a full display server, rather than nested" +msgstr "Pokreni kao potpuni poslužitelj zaslona, radije nego ugrađeni" -#: ../src/metacity.schemas.in.h:22 -msgid "" -"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " -"the focused window will be automatically raised after a delay specified by " -"the auto_raise_delay key. This is not related to clicking on a window to " -"raise it, nor to entering a window during drag-and-drop." -msgstr "" -"Ako je uključeno, a način fokusa je \"sloppy\" ili \"mouse\", tada će " -"fokusirani prozor biti automatski podignut nakon vremena određenog s " -"auto_raise_delay ključem. Ovo se ne odnosi na podizanje prozora klikom, niti " -"sa fokusiranjem tokom povuci-pusti metode." +#: src/core/main.c:252 +msgid "Run with X11 backend" +msgstr "Pokreni s X11 pozadinskim programom" -#: ../src/metacity.schemas.in.h:23 -msgid "" -"If true, ignore the titlebar_font option, and use the standard application " -"font for window titles." -msgstr "" -"Ako je aktivirano, ignorira se titlebar_font opcija i koristi se standardno " -"aplikacijsko pismo za naslovnu traku prozora." +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:151 +#, c-format +msgid "“%s” is not responding." +msgstr "“%s” ne odgovara." -#: ../src/metacity.schemas.in.h:24 -msgid "" -"If true, metacity will give the user less feedback by using wireframes, " -"avoiding animations, or other means. This is a significant reduction in " -"usability for many users, but may allow legacy applications to continue " -"working, and may also be a useful tradeoff for terminal servers. However, " -"the wireframe feature is disabled when accessibility is on." -msgstr "" -"Ako je uključeno, metacity če korisnicima davati manje povratnih informacija " -"koristeći žičane modele, isključivajući animacije ili nekako drukčije. Ovo " -"ozbiljno reducira korisnost za mnoge korisnike, ali zato omogućuje " -"izvršavanje starijih programa, a također može biti korisno kod terminalskih " -"poslužitelja. Usprkos tome žičani modeli su isključeni kada je ukjučen " -"sustava za dostupnost." - -#: ../src/metacity.schemas.in.h:25 +#: src/core/meta-close-dialog-default.c:153 +msgid "Application is not responding." +msgstr "Aplikacija ne odgovara." + +#: src/core/meta-close-dialog-default.c:158 msgid "" -"If true, then Metacity works in terms of applications rather than windows. " -"The concept is a bit abstract, but in general an application-based setup is " -"more like the Mac and less like Windows. When you focus a window in " -"application-based mode, all the windows in the application will be raised. " -"Also, in application-based mode, focus clicks are not passed through to " -"windows in other applications. Application-based mode is, however, largely " -"unimplemented at the moment." +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." msgstr "" -"Ako je uključeno, Metacity će raditi u aplikativnom, a ne prozorskom načinu. " -"Koncept je malo apstraktan, ali općenito aplikativni način rada je sličniji " -"Mac-u nego Windowsima. Kad prozor dobije fokus, svi prozori od te aplikacije " -"će biti podignuti. Također klikovi se ne prosljeđuju do prozora u drugim " -"aplikacijama. Trenutno ovaj naćin rada još nije potpuno implementiran." +"Možete pričekati neko vrijeme da aplikacija nastavi s radom ili možete " +"prisiliti prekid rada aplikacije." -#: ../src/metacity.schemas.in.h:26 -msgid "If true, trade off usability for less resource usage" -msgstr "Ako je postavljno, mijenja se korisnost za manje korištenje resursa" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Force Quit" +msgstr "_Prisili izlaženje" -#: ../src/metacity.schemas.in.h:27 -msgid "Lower window below other windows" -msgstr "Spustiti prozor ispod ostalih prozora" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Wait" +msgstr "_Čekaj" -#: ../src/metacity.schemas.in.h:28 +#: src/core/mutter.c:38 +#, c-format msgid "" -"Many actions (e.g. clicking in the client area, moving or resizing the " -"window) normally raise the window as a side-effect. Setting this option to " -"false, which is strongly discouraged, will decouple raising from other user " -"actions, and ignore raise requests generated by applications. See http://" -"bugzilla.gnome.org/show_bug.cgi?id=445447#c6." +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" msgstr "" +"mutter %s\n" +"Autorsko pravo © 2001-%d Havoc Pennington, Red Hat, Inc., i ostali\n" +"Ovo je slobodan softver; pogledajte izvor za uvjete kopiranja.\n" +"NE postoji jamstvo; čak i bez podrazumijevanih jamstava UPORABLJIVOSTI ZA " +"ODREĐENU SVRHU.\n" -#: ../src/metacity.schemas.in.h:29 -msgid "Maximize window" -msgstr "Maksimiziraj prozor" +#: src/core/mutter.c:52 +msgid "Print version" +msgstr "Inačica za ispis" -#: ../src/metacity.schemas.in.h:30 -msgid "Maximize window horizontally" -msgstr "Maksimiziranje prozora horizontalno" +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "Mutter priključak koji se koristi" -#: ../src/metacity.schemas.in.h:31 -msgid "Maximize window vertically" -msgstr "Maksimiziranje prozora okomito" +#: src/core/prefs.c:1911 +#, c-format +msgid "Workspace %d" +msgstr "Radni prostor %d" -#: ../src/metacity.schemas.in.h:32 -msgid "Minimize window" -msgstr "Minimiziraj prozor" +#: src/core/util.c:122 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter je kompiliran bez podrške za opširan način rada\n" -#: ../src/metacity.schemas.in.h:33 -msgid "Modifier to use for modified window click actions" -msgstr "Preinake za korištenje prepravljenih akcija klika u prozoru" +#: src/wayland/meta-wayland-tablet-pad.c:568 +#, c-format +msgid "Mode Switch: Mode %d" +msgstr "Način prebacivanja: Način %d" -#: ../src/metacity.schemas.in.h:34 -msgid "Move backward between panels and the desktop immediately" -msgstr "Pomicanje unatrag između panela i radnih površina bez odlaganja" +#: src/x11/meta-x11-display.c:676 +#, c-format +msgid "" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." +msgstr "" +"Prikaz \"%s\" već ima upravitelja prozora; pokušajte koristiti --replace " +"mogućnost za zamjenu trenutnog upravitelja prozora." -#: ../src/metacity.schemas.in.h:35 -msgid "Move backwards between panels and the desktop with popup" -msgstr "Pomicanje untrag između panela i radne površine sa popup-om" +#: src/x11/meta-x11-display.c:1089 +msgid "Failed to initialize GDK\n" +msgstr "Neuspjelo GDK pokretanje\n" -#: ../src/metacity.schemas.in.h:36 -msgid "Move backwards between windows immediately" -msgstr "Pomicanje unatrag između prozora bez odlaganja" +#: src/x11/meta-x11-display.c:1113 +#, c-format +msgid "Failed to open X Window System display “%s”\n" +msgstr "Neuspjelo otvaranje sustava prikaza X prozora \"%s\"\n" -#: ../src/metacity.schemas.in.h:37 -msgid "Move backwards between windows of an application immediately" -msgstr "Pomakni se trenutno između prozora programa unatrag" +#: src/x11/meta-x11-display.c:1196 +#, c-format +msgid "Screen %d on display “%s” is invalid\n" +msgstr "Zaslon %d na prikazu '%s' je neispravan\n" -#: ../src/metacity.schemas.in.h:38 -msgid "Move backwards between windows of an application with popup" -msgstr "Pomakni se trenutno između prozora programa unatrag sa pop-upom" +#: src/x11/meta-x11-selection-input-stream.c:460 +#, c-format +msgid "Format %s not supported" +msgstr "Format %s nije podržan" -#: ../src/metacity.schemas.in.h:39 -msgid "Move between panels and the desktop immediately" -msgstr "Pomicanje između prozora i radne površine bez odlaganja" +#: src/x11/session.c:1821 +msgid "" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." +msgstr "" +"Ovi prozori ne podržavaju mogućnost \"spremi trenutne postavke\" i moraju se " +"ručno ponovno pokrenuti sljedeći puta kada se prijavite." -#: ../src/metacity.schemas.in.h:40 -msgid "Move between panels and the desktop with popup" -msgstr "Pomicanje između panela i radne površine sa popup-om." +#: src/x11/window-props.c:569 +#, c-format +msgid "%s (on %s)" +msgstr "%s (na %s)" -#: ../src/metacity.schemas.in.h:41 -msgid "Move between windows immediately" -msgstr "Pomicanje između prozora bez odlaganja" +#~ msgid "Move window one workspace to the left" +#~ msgstr "Premjesti prozor jedan radni prostor nalijevo" -#: ../src/metacity.schemas.in.h:42 -msgid "Move between windows of an application immediately" -msgstr "Pomakni se trenutno između prozora programa" +#~ msgid "Move window one workspace to the right" +#~ msgstr "Premjesti prozor jedan radni prostor udesno" -#: ../src/metacity.schemas.in.h:43 -msgid "Move between windows of an application with popup" -msgstr "Prebacivanje između prozroza programa uz pop-up" +#~ msgid "Move to workspace left" +#~ msgstr "Premjesti na lijevi radni prostor" -#: ../src/metacity.schemas.in.h:44 -msgid "Move between windows with popup" -msgstr "Pomicanje između prozora sa popupom" +#~ msgid "Move to workspace right" +#~ msgstr "Premjesti na desni radni prostor" -#: ../src/metacity.schemas.in.h:45 -msgid "Move focus backwards between windows using popup display" -msgstr "Pomicanje usredotočenja unatrag između prozora koristeći popup prikaz" +#~ msgid "Toggle shaded state" +#~ msgstr "Uklj/Isklj stanje zasjenjenosti" -#: ../src/metacity.schemas.in.h:46 -msgid "Move window" -msgstr "Pomakni prozor" +#~ msgid "Desktop" +#~ msgstr "Radna površina" -#: ../src/metacity.schemas.in.h:47 -msgid "Move window one workspace down" -msgstr "Pomakni prozor jedan radni prostor dolje" +#~ msgid "Window Management" +#~ msgstr "Upravitelj prozorima" -#: ../src/metacity.schemas.in.h:48 -msgid "Move window one workspace to the left" -msgstr "Pomakni prozor jedan radni prostor nalijevo" +#~ msgid "Unknown window information request: %d" +#~ msgstr "Nepoznati zahtijev informacija o prozoru: %d" -#: ../src/metacity.schemas.in.h:49 -msgid "Move window one workspace to the right" -msgstr "Pomakni prozor jedan radni prostor udesno" +#~ msgid "Could not parse \"%s\" as an integer" +#~ msgstr "Nije moguće analizirati \"%s\" kao cijeli broj" -#: ../src/metacity.schemas.in.h:50 -msgid "Move window one workspace up" -msgstr "Pomakni prozor jedan radni prostor gore" +#~ msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +#~ msgstr "Nisam shvatio slijedece znakove \"%s\" u nizu podataka \"%s\"" -#: ../src/metacity.schemas.in.h:51 -#, fuzzy -msgid "Move window to center of screen" -msgstr "Premjesti prozor na istočnu stranu zaslona" +#~ msgid "Failed to parse message \"%s\" from dialog process\n" +#~ msgstr "Nije uspjelo analiziranje poruke \"%s\" iz dijaloškog procesa\n" -#: ../src/metacity.schemas.in.h:52 -msgid "Move window to east side of screen" -msgstr "Premjesti prozor na istočnu stranu zaslona" +#~ msgid "Error reading from dialog display process: %s\n" +#~ msgstr "Pogreška pri čitanju kod procesa ekrana dijaloga: %s\n" -#: ../src/metacity.schemas.in.h:53 -msgid "Move window to north side of screen" -msgstr "Premjesti prozor na sjevernu stranu zaslona" +#~ msgid "" +#~ "Error launching metacity-dialog to ask about killing an application: %s\n" +#~ msgstr "" +#~ "Greška pri pokretanju metacity-dialoga za potvrdu o zatvaranju aplikacije " +#~ "%s\n" -#: ../src/metacity.schemas.in.h:54 -msgid "Move window to north-east corner" -msgstr "Premjesti prozor na sjevero-istočnu stranu zaslona" +#~ msgid "Failed to get hostname: %s\n" +#~ msgstr "Nije uspjelo dobivanje imena računala: %s\n" -#: ../src/metacity.schemas.in.h:55 -msgid "Move window to north-west corner" -msgstr "Premjesti prozor na sjevero-zapadnu stranu zaslona" +#~ msgid "Missing %s extension required for compositing" +#~ msgstr "Nedostaje ekstenzija %s potrebna za stvaranje kompozicije" -#: ../src/metacity.schemas.in.h:56 -msgid "Move window to south side of screen" -msgstr "Premjesti prozor na južnu stranu zaslona" +#~ msgid "" +#~ "Lost connection to the display '%s';\n" +#~ "most likely the X server was shut down or you killed/destroyed\n" +#~ "the window manager.\n" +#~ msgstr "" +#~ "Izubljen spoj sa prikazom '%s';\n" +#~ "najvjerojatnije je X server ugašen, ili ste ubili/ubištili\n" +#~ "rukovoditelja prozora.\n" -#: ../src/metacity.schemas.in.h:57 -msgid "Move window to south-east corner" -msgstr "Premjesti prozor na jugo-istočnu stranu zaslona" +#~ msgid "Fatal IO error %d (%s) on display '%s'.\n" +#~ msgstr "Kobna IO greška %d (%s) na prikazu '%s'.\n" -#: ../src/metacity.schemas.in.h:58 -msgid "Move window to south-west corner" -msgstr "Premjesti prozor na jugo-zapadnu stranu zaslona" +#~ msgid "" +#~ "Some other program is already using the key %s with modifiers %x as a " +#~ "binding\n" +#~ msgstr "" +#~ "Neki drugi prograk već koristi kljuć %s sa modifikacijama %x kao spoj\n" -#: ../src/metacity.schemas.in.h:59 -msgid "Move window to west side of screen" -msgstr "Premjesti prozor na zapadnu stranu zaslona" +#~ msgid "" +#~ "Error launching metacity-dialog to print an error about a command: %s\n" +#~ msgstr "" +#~ "Greška pri pokretanju metacity-dialoga za ispisom greške o komandi %s\n" -#: ../src/metacity.schemas.in.h:60 -msgid "Move window to workspace 1" -msgstr "Pomakni prozor na radni prostor 1" +#~ msgid "No command %d has been defined.\n" +#~ msgstr "Naredba %d nije definirana.\n" -#: ../src/metacity.schemas.in.h:61 -msgid "Move window to workspace 10" -msgstr "Premjesti prozor na radni prostor 10" +#~ msgid "No terminal command has been defined.\n" +#~ msgstr "Niti jedna konzolna naredba nije definirana\n" -#: ../src/metacity.schemas.in.h:62 -msgid "Move window to workspace 11" -msgstr "Premjesti prozor na radni prostor 11" +#~ msgid "Turn compositing on" +#~ msgstr "Uključi kompoziciju" -#: ../src/metacity.schemas.in.h:63 -msgid "Move window to workspace 12" -msgstr "Premjesti prozor na radni prostor 12" +#~ msgid "Turn compositing off" +#~ msgstr "Isključi kompoziciju" -#: ../src/metacity.schemas.in.h:64 -msgid "Move window to workspace 2" -msgstr "Premjesti prozor na radni prostor 2" +#~ msgid "Failed to scan themes directory: %s\n" +#~ msgstr "Nisam uspio pretražiti mapu tema: %s\n" -#: ../src/metacity.schemas.in.h:65 -msgid "Move window to workspace 3" -msgstr "Premjesti prozor na radni prostor 3" +#~ msgid "" +#~ "Could not find a theme! Be sure %s exists and contains the usual themes.\n" +#~ msgstr "" +#~ "Nije moguće naći temu! Provjerite postoji li %s i sadrži li uobičajene " +#~ "teme.\n" -#: ../src/metacity.schemas.in.h:66 -msgid "Move window to workspace 4" -msgstr "Premjesti prozor na radni prostor 4" +#~ msgid "Failed to restart: %s\n" +#~ msgstr "Nije uspjelo ponovno pokretanje: %s\n" -#: ../src/metacity.schemas.in.h:67 -msgid "Move window to workspace 5" -msgstr "Premjesti prozor na radni prostor 5" +#~ msgid "GConf key '%s' is set to an invalid value\n" +#~ msgstr "GConf ključ '%s' je postavljen na neispravnu vrijednost\n" -#: ../src/metacity.schemas.in.h:68 -msgid "Move window to workspace 6" -msgstr "Premjesti prozor na radni prostor 6" +#, fuzzy +#~ msgid "%d stored in GConf key %s is out of range %d to %d\n" +#~ msgstr "%d pohranjen u GConf ključu %s je izvan dometa od 0 do %d\n" -#: ../src/metacity.schemas.in.h:69 -msgid "Move window to workspace 7" -msgstr "Premjesti prozor na radni prostor 7" +#~ msgid "GConf key \"%s\" is set to an invalid type\n" +#~ msgstr "GConf ključ \"%s\" je postavljen na neispravan tip\n" -#: ../src/metacity.schemas.in.h:70 -msgid "Move window to workspace 8" -msgstr "Premjesti prozor na radni prostor 8" +#~ msgid "" +#~ "Workarounds for broken applications disabled. Some applications may not " +#~ "behave properly.\n" +#~ msgstr "" +#~ "Kompromisi za loše programe su isključeni. Neki programi se mogu ponašati " +#~ "čudno.\n" -#: ../src/metacity.schemas.in.h:71 -msgid "Move window to workspace 9" -msgstr "Premjesti prozor na radni prostor 9" +#~ msgid "Could not parse font description \"%s\" from GConf key %s\n" +#~ msgstr "Nije moguće analizirati opis pisma \"%s\" iz Gconf ključa %s\n" -#: ../src/metacity.schemas.in.h:72 -msgid "Name of workspace" -msgstr "Ime radnog prostora" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" +#~ msgstr "" +#~ "“%s“ je pronađen u bazi podešavanja što nije ispravna vrijednost za tipku " +#~ "koja mijenja ponašanje tipki miša\n" -#: ../src/metacity.schemas.in.h:73 -msgid "Number of workspaces" -msgstr "Broj radnih prostora" +#~ msgid "Error setting number of workspaces to %d: %s\n" +#~ msgstr "Pogreška prilikom podešavanja broja radnih površina na %d: %s\n" -#: ../src/metacity.schemas.in.h:74 -msgid "" -"Number of workspaces. Must be more than zero, and has a fixed maximum to " -"prevent making the desktop unusable by accidentally asking for too many " -"workspaces." -msgstr "" -"Broj radnih površina. Mora biti veći od 0, a ima fiksni maksimalan broj kako " -"bi se spriječila neupotrebljivost zbog slučajnog odabira prevelikog broja." +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for " +#~ "keybinding \"%s\"\n" +#~ msgstr "" +#~ "\"%s\" nađen u bazi postavki nije ispravna kombinacija tipki \"%s\"\n" -#: ../src/metacity.schemas.in.h:75 -msgid "Raise obscured window, otherwise lower" -msgstr "Podigni nejasan prozor, inače spusti" +#~ msgid "Error setting name for workspace %d to \"%s\": %s\n" +#~ msgstr "" +#~ "Pogreška prilikom podešavanja imena radne površine %d u \"%s\": %s\n" -#: ../src/metacity.schemas.in.h:76 -msgid "Raise window above other windows" -msgstr "Podigni prozor iznad ostalih prozora" +#, fuzzy +#~ msgid "Error setting compositor status: %s\n" +#~ msgstr "" +#~ "Pogreška prilikom podešavanja imena radne površine %d u \"%s\": %s\n" -#: ../src/metacity.schemas.in.h:77 -msgid "Resize window" -msgstr "Promijeni veličinu prozora" +#~ msgid "Screen %d on display \"%s\" already has a window manager\n" +#~ msgstr "Ekran %d na prikazu \"%s\" već ima rukovoditelj prozora\n" -#: ../src/metacity.schemas.in.h:78 -msgid "Run a defined command" -msgstr "Pokreni definiranu naredbu" +#~ msgid "Could not release screen %d on display \"%s\"\n" +#~ msgstr "Nije moguće izbaciti otpustiti ekran %d na prikazu \"%s\"\n" -#: ../src/metacity.schemas.in.h:79 -msgid "Run a terminal" -msgstr "Pokreni u terminalu" +#~ msgid "Could not create directory '%s': %s\n" +#~ msgstr "Nije moguće napraviti mapu '%s': %s\n" -#: ../src/metacity.schemas.in.h:80 -msgid "Show the panel menu" -msgstr "Pokažite izbornik panela" +#~ msgid "Could not open session file '%s' for writing: %s\n" +#~ msgstr "Nije moguće otvoriti datoteku '%s' za zapis: %s\n" -#: ../src/metacity.schemas.in.h:81 -msgid "Show the panel run application dialog" -msgstr "Pokaži dijalog pokretanja programa u panelu" +#~ msgid "Error writing session file '%s': %s\n" +#~ msgstr "Pogreška zapisivanja datoteke sesije '%s': %s\n" -#: ../src/metacity.schemas.in.h:82 -msgid "" -"Some applications disregard specifications in ways that result in window " -"manager misfeatures. This option puts Metacity in a rigorously correct mode, " -"which gives a more consistent user interface, provided one does not need to " -"run any misbehaving applications." -msgstr "" -"Neke aplikacije zanemaruju specifikacije upravitelja prozorima te stoga isti " -"mogu imati problema s odreženim funkcionalnostima. Ova opcija stavlja " -"Metacity u rigorozno ispravan način rada, te daje mnogo koenzistnije " -"korisniko sučelje, ali samo u slučaju da ne pokrećete aplikacije koje se ne " -"ponašaju u skladu s specifikacijama." +#~ msgid "Error closing session file '%s': %s\n" +#~ msgstr "Greška pri zatvaranju session datoteke '%s': %s\n" -#: ../src/metacity.schemas.in.h:83 -msgid "Switch to workspace 1" -msgstr "Prebaci se na radni prostor 1" +#~ msgid "Failed to read saved session file %s: %s\n" +#~ msgstr "Nije uspjelo čitanje snimljene datoteke sesije %s: %s\n" -#: ../src/metacity.schemas.in.h:84 -msgid "Switch to workspace 10" -msgstr "Prebaci se na radni prostor 10" +#~ msgid "Failed to parse saved session file: %s\n" +#~ msgstr "Nije uspjela analiza snimljene datoteke sesije: %s\n" -#: ../src/metacity.schemas.in.h:85 -msgid "Switch to workspace 11" -msgstr "Prebaci se na radni prostor 11" +#~ msgid "<metacity_session> attribute seen but we already have the session ID" +#~ msgstr "<metacity_session> atribut opažen ali već imamo ID sesije" -#: ../src/metacity.schemas.in.h:86 -msgid "Switch to workspace 12" -msgstr "Prebaci se na radni prostor 12" +#~ msgid "Unknown attribute %s on <metacity_session> element" +#~ msgstr "Nepoznato svojstvo %s u <metacity_session> elementu" -#: ../src/metacity.schemas.in.h:87 -msgid "Switch to workspace 2" -msgstr "Prebaci se na radni prostor 2" +#~ msgid "nested <window> tag" +#~ msgstr "ugniježden <window> tag" -#: ../src/metacity.schemas.in.h:88 -msgid "Switch to workspace 3" -msgstr "Prebaci se na radni prostor 3" +#~ msgid "Unknown attribute %s on <window> element" +#~ msgstr "Nepoznato svojstvo %s u <window> elementu" -#: ../src/metacity.schemas.in.h:89 -msgid "Switch to workspace 4" -msgstr "Prebaci se na radni prostor 4" +#~ msgid "Unknown attribute %s on <maximized> element" +#~ msgstr "Nepoznato svojstvo %s u <maximized> elementu" -#: ../src/metacity.schemas.in.h:90 -msgid "Switch to workspace 5" -msgstr "Prebaci se na radni prostor 5" +#~ msgid "Unknown attribute %s on <geometry> element" +#~ msgstr "Nepoznato svojstvo %s u <geometry> elementu" -#: ../src/metacity.schemas.in.h:91 -msgid "Switch to workspace 6" -msgstr "Prebaci se na radni prostor 6" +#~ msgid "Unknown element %s" +#~ msgstr "Nepoznati element %s" -#: ../src/metacity.schemas.in.h:92 -msgid "Switch to workspace 7" -msgstr "Prebaci se na radni prostor 7" +#~ msgid "" +#~ "Error launching metacity-dialog to warn about apps that don't support " +#~ "session management: %s\n" +#~ msgstr "" +#~ "Greška pri pokretanju metacity-dialoga da upozori aplikacije koje ne " +#~ "podržavaju session managment %s\n" -#: ../src/metacity.schemas.in.h:93 -msgid "Switch to workspace 8" -msgstr "Prebaci se na radni prostor 8" +#~ msgid "Failed to open debug log: %s\n" +#~ msgstr "Nije uspjelo otvaranje zapisnika o ispravku grešaka: %s\n" -#: ../src/metacity.schemas.in.h:94 -msgid "Switch to workspace 9" -msgstr "Prijeđi na radni prostor 9" +#~ msgid "Failed to fdopen() log file %s: %s\n" +#~ msgstr "Nije uspjelo fdopen() datoteke zapisnika%s: %s\n" -#: ../src/metacity.schemas.in.h:95 -msgid "Switch to workspace above this one" -msgstr "Prijeđi na na radni prostor iznad ovog" +#~ msgid "Opened log file %s\n" +#~ msgstr "Otvorena zapisnička datoteka %s\n" -#: ../src/metacity.schemas.in.h:96 -msgid "Switch to workspace below this one" -msgstr "Prijeđi na radni prostor ispod ovog" +#~ msgid "Window manager: " +#~ msgstr "Upravitelj prozora: " -#: ../src/metacity.schemas.in.h:97 -msgid "Switch to workspace on the left" -msgstr "Prebaci se na radni prostor na ljevo" +#~ msgid "Bug in window manager: " +#~ msgstr "Greška u upravitelju prozora: " -#: ../src/metacity.schemas.in.h:98 -msgid "Switch to workspace on the right" -msgstr "Prijeđi se na radni prostor na desno" +#~ msgid "Window manager warning: " +#~ msgstr "Upozorenje upravitelja prozora: " -#: ../src/metacity.schemas.in.h:99 -msgid "System Bell is Audible" -msgstr "Sistemsko zvono se čuje" +#~ msgid "Window manager error: " +#~ msgstr "Greška upravitelja prozora: " -#: ../src/metacity.schemas.in.h:100 -msgid "Take a screenshot" -msgstr "Uzmi sliku zaslona" +#~ msgid "Application set a bogus _NET_WM_PID %lu\n" +#~ msgstr "Program je postavio neispravan NET_WM_PID %lu\n" -#: ../src/metacity.schemas.in.h:101 -msgid "Take a screenshot of a window" -msgstr "Uzmi sliku prozora" +#~ msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +#~ msgstr "Neispravan WM_TRANSIENT_FOR prozor 0x%lx specificiran za %s.\n" -#: ../src/metacity.schemas.in.h:102 -msgid "" -"Tells Metacity how to implement the visual indication that the system bell " -"or another application 'bell' indicator has been rung. Currently there are " -"two valid values, \"fullscreen\", which causes a fullscreen white-black " -"flash, and \"frame_flash\" which causes the titlebar of the application " -"which sent the bell signal to flash. If the application which sent the bell " -"is unknown (as is usually the case for the default \"system beep\"), the " -"currently focused window's titlebar is flashed." -msgstr "" -"Naređuje Metasitiju da prikaže nešto kada zazvoni sistemsko zvono ili neki " -"drugi program zazvoni. Trenutno su moguće dve vrijednosti, „fullscreen“ " -"kojim cijeli zaslon treperi crno-bijelo, i „frame_flash“ kada treperi samo " -"naslovna linija prozora koji je zazvonio. Ukoliko nije poznat program koji " -"je zazvonio (kao što je to obično slučaj sa „sistemskim zvonom“), trepereće " -"naslovna linija prozora koji je trenutno u fokusu." - -#: ../src/metacity.schemas.in.h:103 -msgid "" -"The /apps/metacity/global_keybindings/run_command_N keys define keybindings " -"that correspond to these commands. Pressing the keybinding for run_command_N " -"will execute command_N." -msgstr "" -"Ključ /apps/metacity/global_keybindings/run_command_N definira tiipke koji " -"odgovaraju ovim komandama. Pritiskom kombinacije tipki za pokreni_komadu_N " -"će izvršiti komandu_N." +#~ msgid "" +#~ "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " +#~ "window as specified in the ICCCM.\n" +#~ msgstr "" +#~ "Prozor %s je postavio SM_CLIENT_ID na samog sebe umjesto na prozor " +#~ "WM_CLIENT_LEADER kao što je navedeno u ICCCM.\n" -#: ../src/metacity.schemas.in.h:104 -msgid "" -"The /apps/metacity/global_keybindings/run_command_screenshot key defines a " -"keybinding which causes the command specified by this setting to be invoked." -msgstr "" -"Ključ /apps/metacity/global_keybindings/run_command_N definira funkciju " -"tipki kojim se pokreće naredba navedena pomoću njega." +#~ msgid "" +#~ "Window %s sets an MWM hint indicating it isn't resizable, but sets min " +#~ "size %d x %d and max size %d x %d; this doesn't make much sense.\n" +#~ msgstr "" +#~ "Prozor %s je postavio MWM što nagovještava da nije promjenjljive " +#~ "veličine, ali je postavio minimalnu veličinu %d x %d i maksimalnu " +#~ "veličinu %d x %d što nema mnogo smisla.\n" -#: ../src/metacity.schemas.in.h:105 -msgid "" -"The /apps/metacity/global_keybindings/run_command_window_screenshot key " -"defines a keybinding which causes the command specified by this setting to " -"be invoked." -msgstr "" -"Ključ /apps/metacity/global_keybindings/run_command_window_screenshot " -"definira funkciju tipki kojim se pokreće naredba navedena pomoću njega." +#~ msgid "" +#~ "Window 0x%lx has property %s\n" +#~ "that was expected to have type %s format %d\n" +#~ "and actually has type %s format %d n_items %d.\n" +#~ "This is most likely an application bug, not a window manager bug.\n" +#~ "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +#~ msgstr "" +#~ "Prozor 0x%lx ima osobinu %s\n" +#~ "tako da je očekivano da ima tip %s format %d,\n" +#~ "a zapravo ima tip %s format %d n_items %d.\n" +#~ "Ovo je najverovatnije greška u programu, a ne u menadžeru prozora.\n" +#~ "Prozor ima naslov=\"%s\" klasa=\"%s\" ime=\"%s\"\n" -#: ../src/metacity.schemas.in.h:106 -msgid "" -"The keybinding that runs the correspondingly-numbered command in /apps/" -"metacity/keybinding_commands The format looks like \"<Control>a\" or " -"\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -"lower or upper case, and also abbreviations such as \"<Ctl>\" and " -"\"<Ctrl>\". If you set the option to the special string \"disabled\", " -"then there will be no keybinding for this action." -msgstr "" -"Kombinacije tipki koji pokreću odgovarajuće označenu naredbu u /apps/" -"metacity/keybinding_commands ključu. Oblik zapisa izgleda kao \"<Control>a\" " -"ili \"<Shift><Alt>F1\". Program za obradu je dosta slobodan i dozvoljava " -"velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". " -"Ako postavite opciju na specijalni niz znakova \"disabled\", tada neće biti " -"korištena niti jedna kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:107 -msgid "" -"The keybinding that switches to the workspace above the current workspace. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"Kombinacija tipki koja prebacuje na radni prostor iznad trenutnog radnog " -"prostora. Oblik zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". " -"Program za obradu je dosta slobodan i dozvoljava velika ili mala slova, " -"takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na " -"specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:108 -msgid "" -"The keybinding that switches to the workspace below the current workspace. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"Kombinacija tipki koja prebacuje na radni prostor ispod trenutnog radnog " -"prostora. Oblik zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". " -"Program za obradu je dosta slobodan i dozvoljava velika ili mala slova, " -"takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako pstavite opciju na " -"specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:109 -msgid "" -"The keybinding that switches to the workspace on the left of the current " -"workspace. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" -"Kombinacija tipki koja prebacuje na radni prostor lijevo od trenutnog radnog " -"prostora. Oblik zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". " -"Program za obradu je dosta slobodan i dozvoljava velika ili mala slova, " -"takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na " -"specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:110 -msgid "" -"The keybinding that switches to the workspace on the right of the current " -"workspace. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" -"Kombinacija tipki koja prebacuje na radni prostor desno od trenutnog " -"radnogprostora. Oblik zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1" -"\". Program za obradu je dosta slobodan i dozvoljava velika ili mala slova, " -"takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na " -"specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:111 -msgid "" -"The keybinding that switches to workspace 1. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja prebacuje na radni prostor 1. Oblik zapisa izgleda " -"kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program za obradu je dosta " -"slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " -"\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " -"\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za ovu " -"aktivnost." - -#: ../src/metacity.schemas.in.h:112 -msgid "" -"The keybinding that switches to workspace 10. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja prebacuje na radni prostor 10. Oblik zapisa izgleda " -"kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program za obradu je dosta " -"slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " -"\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " -"\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za ovu " -"aktivnost." - -#: ../src/metacity.schemas.in.h:113 -msgid "" -"The keybinding that switches to workspace 11. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja prebacuje na radni prostor 11. Oblik zapisa izgleda " -"kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program za obradu je dosta " -"slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " -"\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " -"\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za ovu " -"aktivnost." - -#: ../src/metacity.schemas.in.h:114 -msgid "" -"The keybinding that switches to workspace 12. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja prebacuje na radni prostor 12. Oblik zapisa izgleda " -"kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program za obradu je dosta " -"slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " -"\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " -"\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za ovu " -"aktivnost." - -#: ../src/metacity.schemas.in.h:115 -msgid "" -"The keybinding that switches to workspace 2. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja prebacuje na radni prostor 2. Oblik zapisa izgleda " -"kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program za obradu je dosta " -"slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " -"\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " -"\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za ovu " -"aktivnost." - -#: ../src/metacity.schemas.in.h:116 -msgid "" -"The keybinding that switches to workspace 3. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja prebacuje na radni prostor 3. Oblik zapisa izgleda " -"kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program za obradu je dosta " -"slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " -"\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " -"\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za ovu " -"aktivnost." - -#: ../src/metacity.schemas.in.h:117 -msgid "" -"The keybinding that switches to workspace 4. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja prebacuje na radni prostor 4. Oblik zapisa izgleda " -"kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program za obradu je dosta " -"slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " -"\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " -"\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za ovu " -"aktivnost." - -#: ../src/metacity.schemas.in.h:118 -msgid "" -"The keybinding that switches to workspace 5. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja prebacuje na radni prostor 5. Oblik zapisa izgleda " -"kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program za obradu je dosta " -"slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " -"\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " -"\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za ovu " -"aktivnost." - -#: ../src/metacity.schemas.in.h:119 -msgid "" -"The keybinding that switches to workspace 6. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja prebacuje na radni prostor 6. Oblik zapisa izgleda " -"kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program za obradu je dosta " -"slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " -"\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " -"\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za ovu " -"aktivnost." - -#: ../src/metacity.schemas.in.h:120 -msgid "" -"The keybinding that switches to workspace 7. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja prebacuje na radni prostor 7. Oblik zapisa izgleda " -"kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program za obradu je dosta " -"slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " -"\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " -"\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za ovu " -"aktivnost." - -#: ../src/metacity.schemas.in.h:121 -msgid "" -"The keybinding that switches to workspace 8. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja prebacuje na radni prostor 8. Oblik zapisa izgleda " -"kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program za obradu je dosta " -"slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " -"\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " -"\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za ovu " -"aktivnost." - -#: ../src/metacity.schemas.in.h:122 -msgid "" -"The keybinding that switches to workspace 9. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja prebacuje na radni prostor 9. Oblik zapisa izgleda " -"kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program za obradu je dosta " -"slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " -"\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " -"\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za ovu " -"aktivnost." - -#: ../src/metacity.schemas.in.h:123 -msgid "" -"The keybinding used to activate the window menu. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja pokreće izbornik prozora. Oblik zapisa izgleda kao " -"\"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu je dosta slobodan i " -"dozvoljava velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< " -"Ctrl>\". Ako postavite opciju na specijalni niz znakova \"disabled\", tada " -"neće biti korištena niti jedna kombinacija tipki za ovu aktivnost." +#~ msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +#~ msgstr "Svojstvo %s na prozoru 0x%lx je sadržalo neispravni UTF-8\n" + +#~ msgid "" +#~ "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the " +#~ "list\n" +#~ msgstr "" +#~ "Svojstvo %s na prozoru 0x%lx sadrži neispravni UTF-8 za predmet %d na " +#~ "popisu\n" + +#~ msgid "Metacity" +#~ msgstr "Metacity" + +#~ msgid "" +#~ "(Not implemented) Navigation works in terms of applications not windows" +#~ msgstr "(Nije ugrađeno) Navigacija radi u smislu aplikacija, ne prozora" + +#~ msgid "" +#~ "A font description string describing a font for window titlebars. The " +#~ "size from the description will only be used if the titlebar_font_size " +#~ "option is set to 0. Also, this option is disabled if the " +#~ "titlebar_uses_desktop_font option is set to true." +#~ msgstr "" +#~ "Znakovni niz koji opisuje font za naslovnu traku prozora. Veličina će iz " +#~ "opisa biti upotrebljena samo ako je titlebar_font_size opcija postavljena " +#~ "na 0. Također, ova opcija je onemogućena ako je " +#~ "titlebar_uses_desktop_font postavljena." + +#~ msgid "Action on title bar double-click" +#~ msgstr "Akcija na naslovnom meniju dvostruki-klik" + +#~ msgid "Arrangement of buttons on the titlebar" +#~ msgstr "Aranžman funkcijskih tipki na naslovoj traci" + +#, fuzzy +#~ msgid "" +#~ "Arrangement of buttons on the titlebar. The value should be a string, " +#~ "such as \"menu:minimize,maximize,spacer,close\"; the colon separates the " +#~ "left corner of the window from the right corner, and the button names are " +#~ "comma-separated. Duplicate buttons are not allowed. Unknown button names " +#~ "are silently ignored so that buttons can be added in future metacity " +#~ "versions without breaking older versions. A special spacer tag can be " +#~ "used to insert some space between two adjacent buttons." +#~ msgstr "" +#~ "Raspored gumba na naslovnoj traci. Vrijednost treba biti niz znakova, kao " +#~ "na primjer „menu:minimize,maximize,close“; dvije točke razdvaju lijevi " +#~ "kut prozora od desnog, a gumbi su razdvojeni točka-zarezima. Dupliranje " +#~ "gumba nije dozvoljeno. Nepoznata imena gumba se zanemaruju tako da se " +#~ "gumbi koji će se dodavati u buduće inačice metacitya bez poremećenja " +#~ "starijih inačica." + +#~ msgid "Automatically raises the focused window" +#~ msgstr "Automatski podiže prozor sa fokusom" + +#~ msgid "" +#~ "Clicking a window while holding down this modifier key will move the " +#~ "window (left click), resize the window (middle click), or show the window " +#~ "menu (right click). Modifier is expressed as \"<Alt>\" or \"<" +#~ "Super>\" for example." +#~ msgstr "" +#~ "Pritiskom na prozor za vrijeme držanja ove tipke premejestiti će prozor " +#~ "(lijeva tipka miša), podići prozor (srednja tipka miša) ili prikazati " +#~ "glavni izbornik (desna tipka miša). Tipka može biti na primjer \"<" +#~ "Alr>\" ili \"<Super>\"" + +#~ msgid "Commands to run in response to keybindings" +#~ msgstr "" +#~ "Naredbe koje će se pokrenuti na odaziv kombinacije tipki sa tipkovnice" + +#~ msgid "Control how new windows get focus" +#~ msgstr "Kontrola fokusiranja novih prozora" + +#~ msgid "Current theme" +#~ msgstr "Trenutna tema" + +#~ msgid "Delay in milliseconds for the auto raise option" +#~ msgstr "Odgoda u milisekundama za opciju automatskog podizanja" + +#~ msgid "Determines whether Metacity is a compositing manager." +#~ msgstr "Određuje li je Metacity kompozitni upravitelj." + +#~ msgid "" +#~ "Determines whether applications or the system can generate audible " +#~ "'beeps'; may be used in conjunction with 'visual bell' to allow silent " +#~ "'beeps'." +#~ msgstr "" +#~ "Određuje hoće li aplikacije ili sistem generirati zvučne 'beepove'može se " +#~ "koristiti u spoju sa 'vizualnim zvonom' da se dozvoli tihi 'beep'" + +#~ msgid "Disable misfeatures that are required by old or broken applications" +#~ msgstr "Isključi mogućnosti potrebne za stare ili neispravne aplikacijie" + +#~ msgid "Enable Visual Bell" +#~ msgstr "Aktiviraj vidni signal" + +#~ msgid "Hide all windows and focus desktop" +#~ msgstr "Sakrij sve prozore i pokaži radnu površinu" + +#~ msgid "" +#~ "If true, ignore the titlebar_font option, and use the standard " +#~ "application font for window titles." +#~ msgstr "" +#~ "Ako je aktivirano, ignorira se titlebar_font opcija i koristi se " +#~ "standardno aplikacijsko pismo za naslovnu traku prozora." + +#~ msgid "" +#~ "If true, metacity will give the user less feedback by using wireframes, " +#~ "avoiding animations, or other means. This is a significant reduction in " +#~ "usability for many users, but may allow legacy applications to continue " +#~ "working, and may also be a useful tradeoff for terminal servers. However, " +#~ "the wireframe feature is disabled when accessibility is on." +#~ msgstr "" +#~ "Ako je uključeno, metacity če korisnicima davati manje povratnih " +#~ "informacija koristeći žičane modele, isključivajući animacije ili nekako " +#~ "drukčije. Ovo ozbiljno reducira korisnost za mnoge korisnike, ali zato " +#~ "omogućuje izvršavanje starijih programa, a također može biti korisno kod " +#~ "terminalskih poslužitelja. Usprkos tome žičani modeli su isključeni kada " +#~ "je ukjučen sustava za dostupnost." + +#~ msgid "" +#~ "If true, then Metacity works in terms of applications rather than " +#~ "windows. The concept is a bit abstract, but in general an application-" +#~ "based setup is more like the Mac and less like Windows. When you focus a " +#~ "window in application-based mode, all the windows in the application will " +#~ "be raised. Also, in application-based mode, focus clicks are not passed " +#~ "through to windows in other applications. Application-based mode is, " +#~ "however, largely unimplemented at the moment." +#~ msgstr "" +#~ "Ako je uključeno, Metacity će raditi u aplikativnom, a ne prozorskom " +#~ "načinu. Koncept je malo apstraktan, ali općenito aplikativni način rada " +#~ "je sličniji Mac-u nego Windowsima. Kad prozor dobije fokus, svi prozori " +#~ "od te aplikacije će biti podignuti. Također klikovi se ne prosljeđuju do " +#~ "prozora u drugim aplikacijama. Trenutno ovaj naćin rada još nije potpuno " +#~ "implementiran." + +#~ msgid "If true, trade off usability for less resource usage" +#~ msgstr "Ako je postavljno, mijenja se korisnost za manje korištenje resursa" + +#~ msgid "Minimize window" +#~ msgstr "Minimiziraj prozor" + +#~ msgid "Move backward between panels and the desktop immediately" +#~ msgstr "Pomicanje unatrag između panela i radnih površina bez odlaganja" + +#~ msgid "Move backwards between panels and the desktop with popup" +#~ msgstr "Pomicanje untrag između panela i radne površine sa popup-om" + +#~ msgid "Move backwards between windows immediately" +#~ msgstr "Pomicanje unatrag između prozora bez odlaganja" + +#~ msgid "Move backwards between windows of an application immediately" +#~ msgstr "Pomakni se trenutno između prozora programa unatrag" + +#~ msgid "Move backwards between windows of an application with popup" +#~ msgstr "Pomakni se trenutno između prozora programa unatrag sa pop-upom" + +#~ msgid "Move between panels and the desktop immediately" +#~ msgstr "Pomicanje između prozora i radne površine bez odlaganja" + +#~ msgid "Move between panels and the desktop with popup" +#~ msgstr "Pomicanje između panela i radne površine sa popup-om." + +#~ msgid "Move between windows immediately" +#~ msgstr "Pomicanje između prozora bez odlaganja" + +#~ msgid "Move focus backwards between windows using popup display" +#~ msgstr "" +#~ "Pomicanje usredotočenja unatrag između prozora koristeći popup prikaz" + +#, fuzzy +#~ msgid "Move window to center of screen" +#~ msgstr "Premjesti prozor na istočnu stranu zaslona" + +#~ msgid "Move window to east side of screen" +#~ msgstr "Premjesti prozor na istočnu stranu zaslona" + +#~ msgid "Move window to north side of screen" +#~ msgstr "Premjesti prozor na sjevernu stranu zaslona" + +#~ msgid "Move window to north-east corner" +#~ msgstr "Premjesti prozor na sjevero-istočnu stranu zaslona" + +#~ msgid "Move window to north-west corner" +#~ msgstr "Premjesti prozor na sjevero-zapadnu stranu zaslona" + +#~ msgid "Move window to south side of screen" +#~ msgstr "Premjesti prozor na južnu stranu zaslona" + +#~ msgid "Move window to south-east corner" +#~ msgstr "Premjesti prozor na jugo-istočnu stranu zaslona" + +#~ msgid "Move window to south-west corner" +#~ msgstr "Premjesti prozor na jugo-zapadnu stranu zaslona" + +#~ msgid "Move window to west side of screen" +#~ msgstr "Premjesti prozor na zapadnu stranu zaslona" + +#~ msgid "Move window to workspace 10" +#~ msgstr "Premjesti prozor na radni prostor 10" + +#~ msgid "Move window to workspace 11" +#~ msgstr "Premjesti prozor na radni prostor 11" + +#~ msgid "Move window to workspace 12" +#~ msgstr "Premjesti prozor na radni prostor 12" + +#~ msgid "Move window to workspace 5" +#~ msgstr "Premjesti prozor na radni prostor 5" + +#~ msgid "Move window to workspace 6" +#~ msgstr "Premjesti prozor na radni prostor 6" + +#~ msgid "Move window to workspace 7" +#~ msgstr "Premjesti prozor na radni prostor 7" + +#~ msgid "Move window to workspace 8" +#~ msgstr "Premjesti prozor na radni prostor 8" + +#~ msgid "Move window to workspace 9" +#~ msgstr "Premjesti prozor na radni prostor 9" + +#~ msgid "Name of workspace" +#~ msgstr "Ime radnog prostora" + +#~ msgid "Number of workspaces" +#~ msgstr "Broj radnih prostora" + +#~ msgid "" +#~ "Number of workspaces. Must be more than zero, and has a fixed maximum to " +#~ "prevent making the desktop unusable by accidentally asking for too many " +#~ "workspaces." +#~ msgstr "" +#~ "Broj radnih površina. Mora biti veći od 0, a ima fiksni maksimalan broj " +#~ "kako bi se spriječila neupotrebljivost zbog slučajnog odabira prevelikog " +#~ "broja." + +#~ msgid "Run a defined command" +#~ msgstr "Pokreni definiranu naredbu" + +#~ msgid "Run a terminal" +#~ msgstr "Pokreni u terminalu" + +#~ msgid "Show the panel menu" +#~ msgstr "Pokažite izbornik panela" + +#~ msgid "Show the panel run application dialog" +#~ msgstr "Pokaži dijalog pokretanja programa u panelu" + +#~ msgid "" +#~ "Some applications disregard specifications in ways that result in window " +#~ "manager misfeatures. This option puts Metacity in a rigorously correct " +#~ "mode, which gives a more consistent user interface, provided one does not " +#~ "need to run any misbehaving applications." +#~ msgstr "" +#~ "Neke aplikacije zanemaruju specifikacije upravitelja prozorima te stoga " +#~ "isti mogu imati problema s odreženim funkcionalnostima. Ova opcija " +#~ "stavlja Metacity u rigorozno ispravan način rada, te daje mnogo " +#~ "koenzistnije korisniko sučelje, ali samo u slučaju da ne pokrećete " +#~ "aplikacije koje se ne ponašaju u skladu s specifikacijama." + +#~ msgid "Switch to workspace above this one" +#~ msgstr "Prijeđi na na radni prostor iznad ovog" + +#~ msgid "Switch to workspace below this one" +#~ msgstr "Prijeđi na radni prostor ispod ovog" + +#~ msgid "Switch to workspace on the left" +#~ msgstr "Prebaci se na radni prostor na ljevo" + +#~ msgid "Switch to workspace on the right" +#~ msgstr "Prijeđi se na radni prostor na desno" + +#~ msgid "System Bell is Audible" +#~ msgstr "Sistemsko zvono se čuje" + +#~ msgid "Take a screenshot" +#~ msgstr "Uzmi sliku zaslona" + +#~ msgid "Take a screenshot of a window" +#~ msgstr "Uzmi sliku prozora" + +#~ msgid "" +#~ "Tells Metacity how to implement the visual indication that the system " +#~ "bell or another application 'bell' indicator has been rung. Currently " +#~ "there are two valid values, \"fullscreen\", which causes a fullscreen " +#~ "white-black flash, and \"frame_flash\" which causes the titlebar of the " +#~ "application which sent the bell signal to flash. If the application which " +#~ "sent the bell is unknown (as is usually the case for the default \"system " +#~ "beep\"), the currently focused window's titlebar is flashed." +#~ msgstr "" +#~ "Naređuje Metasitiju da prikaže nešto kada zazvoni sistemsko zvono ili " +#~ "neki drugi program zazvoni. Trenutno su moguće dve vrijednosti, " +#~ "„fullscreen“ kojim cijeli zaslon treperi crno-bijelo, i „frame_flash“ " +#~ "kada treperi samo naslovna linija prozora koji je zazvonio. Ukoliko nije " +#~ "poznat program koji je zazvonio (kao što je to obično slučaj sa " +#~ "„sistemskim zvonom“), trepereće naslovna linija prozora koji je trenutno " +#~ "u fokusu." + +#~ msgid "" +#~ "The /apps/metacity/global_keybindings/run_command_N keys define " +#~ "keybindings that correspond to these commands. Pressing the keybinding " +#~ "for run_command_N will execute command_N." +#~ msgstr "" +#~ "Ključ /apps/metacity/global_keybindings/run_command_N definira tiipke " +#~ "koji odgovaraju ovim komandama. Pritiskom kombinacije tipki za " +#~ "pokreni_komadu_N će izvršiti komandu_N." + +#~ msgid "" +#~ "The /apps/metacity/global_keybindings/run_command_screenshot key defines " +#~ "a keybinding which causes the command specified by this setting to be " +#~ "invoked." +#~ msgstr "" +#~ "Ključ /apps/metacity/global_keybindings/run_command_N definira funkciju " +#~ "tipki kojim se pokreće naredba navedena pomoću njega." + +#~ msgid "" +#~ "The /apps/metacity/global_keybindings/run_command_window_screenshot key " +#~ "defines a keybinding which causes the command specified by this setting " +#~ "to be invoked." +#~ msgstr "" +#~ "Ključ /apps/metacity/global_keybindings/run_command_window_screenshot " +#~ "definira funkciju tipki kojim se pokreće naredba navedena pomoću njega." + +#~ msgid "" +#~ "The keybinding that runs the correspondingly-numbered command in /apps/" +#~ "metacity/keybinding_commands The format looks like \"<Control>a\" " +#~ "or \"<Shift><Alt>F1\". The parser is fairly liberal and " +#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" +#~ "\" and \"<Ctrl>\". If you set the option to the special string " +#~ "\"disabled\", then there will be no keybinding for this action." +#~ msgstr "" +#~ "Kombinacije tipki koji pokreću odgovarajuće označenu naredbu u /apps/" +#~ "metacity/keybinding_commands ključu. Oblik zapisa izgleda kao \"<Control>a" +#~ "\" ili \"<Shift><Alt>F1\". Program za obradu je dosta slobodan i " +#~ "dozvoljava velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" i " +#~ "\"< Ctrl>\". Ako postavite opciju na specijalni niz znakova \"disabled\", " +#~ "tada neće biti korištena niti jedna kombinacija tipki za ovu aktivnost." + +#~ msgid "" +#~ "The keybinding that switches to the workspace above the current " +#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" +#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " +#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" +#~ "\". If you set the option to the special string \"disabled\", then there " +#~ "will be no keybinding for this action." +#~ msgstr "" +#~ "Kombinacija tipki koja prebacuje na radni prostor iznad trenutnog radnog " +#~ "prostora. Oblik zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". " +#~ "Program za obradu je dosta slobodan i dozvoljava velika ili mala slova, " +#~ "takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju " +#~ "na specijalni niz znakova \"disabled\", tada neće biti korištena niti " +#~ "jedna kombinacija tipki za ovu aktivnost." + +#~ msgid "" +#~ "The keybinding that switches to the workspace below the current " +#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" +#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " +#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" +#~ "\". If you set the option to the special string \"disabled\", then there " +#~ "will be no keybinding for this action." +#~ msgstr "" +#~ "Kombinacija tipki koja prebacuje na radni prostor ispod trenutnog radnog " +#~ "prostora. Oblik zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". " +#~ "Program za obradu je dosta slobodan i dozvoljava velika ili mala slova, " +#~ "takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako pstavite opciju na " +#~ "specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " +#~ "kombinacija tipki za ovu aktivnost." + +#~ msgid "" +#~ "The keybinding that switches to the workspace on the left of the current " +#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" +#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " +#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" +#~ "\". If you set the option to the special string \"disabled\", then there " +#~ "will be no keybinding for this action." +#~ msgstr "" +#~ "Kombinacija tipki koja prebacuje na radni prostor lijevo od trenutnog " +#~ "radnog prostora. Oblik zapisa izgleda kao \"<Control>a\" ili " +#~ "\"<Shift><Alt>F1\". Program za obradu je dosta slobodan i dozvoljava " +#~ "velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". " +#~ "Ako postavite opciju na specijalni niz znakova \"disabled\", tada neće " +#~ "biti korištena niti jedna kombinacija tipki za ovu aktivnost." + +#~ msgid "" +#~ "The keybinding that switches to the workspace on the right of the current " +#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" +#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " +#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" +#~ "\". If you set the option to the special string \"disabled\", then there " +#~ "will be no keybinding for this action." +#~ msgstr "" +#~ "Kombinacija tipki koja prebacuje na radni prostor desno od trenutnog " +#~ "radnogprostora. Oblik zapisa izgleda kao \"<Control>a\" ili " +#~ "\"<Shift><Alt>F1\". Program za obradu je dosta slobodan i dozvoljava " +#~ "velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". " +#~ "Ako postavite opciju na specijalni niz znakova \"disabled\", tada neće " +#~ "biti korištena niti jedna kombinacija tipki za ovu aktivnost." + +#~ msgid "" +#~ "The keybinding that switches to workspace 1. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "Kombinacija tipki koja prebacuje na radni prostor 1. Oblik zapisa izgleda " +#~ "kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program za obradu je dosta " +#~ "slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " +#~ "\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " +#~ "\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za " +#~ "ovu aktivnost." + +#~ msgid "" +#~ "The keybinding that switches to workspace 10. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "Kombinacija tipki koja prebacuje na radni prostor 10. Oblik zapisa " +#~ "izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program za obradu je " +#~ "dosta slobodan i dozvoljava velika ili mala slova, takođe i skraćenice " +#~ "poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz " +#~ "znakova \"disabled\", tada neće biti korištena niti jedna kombinacija " +#~ "tipki za ovu aktivnost." + +#~ msgid "" +#~ "The keybinding that switches to workspace 11. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "Kombinacija tipki koja prebacuje na radni prostor 11. Oblik zapisa " +#~ "izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program za obradu je " +#~ "dosta slobodan i dozvoljava velika ili mala slova, takođe i skraćenice " +#~ "poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz " +#~ "znakova \"disabled\", tada neće biti korištena niti jedna kombinacija " +#~ "tipki za ovu aktivnost." + +#~ msgid "" +#~ "The keybinding that switches to workspace 12. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "Kombinacija tipki koja prebacuje na radni prostor 12. Oblik zapisa " +#~ "izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program za obradu je " +#~ "dosta slobodan i dozvoljava velika ili mala slova, takođe i skraćenice " +#~ "poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz " +#~ "znakova \"disabled\", tada neće biti korištena niti jedna kombinacija " +#~ "tipki za ovu aktivnost." + +#~ msgid "" +#~ "The keybinding that switches to workspace 2. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "Kombinacija tipki koja prebacuje na radni prostor 2. Oblik zapisa izgleda " +#~ "kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program za obradu je dosta " +#~ "slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " +#~ "\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " +#~ "\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za " +#~ "ovu aktivnost." + +#~ msgid "" +#~ "The keybinding that switches to workspace 3. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "Kombinacija tipki koja prebacuje na radni prostor 3. Oblik zapisa izgleda " +#~ "kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program za obradu je dosta " +#~ "slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " +#~ "\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " +#~ "\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za " +#~ "ovu aktivnost." + +#~ msgid "" +#~ "The keybinding that switches to workspace 4. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "Kombinacija tipki koja prebacuje na radni prostor 4. Oblik zapisa izgleda " +#~ "kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program za obradu je dosta " +#~ "slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " +#~ "\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " +#~ "\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za " +#~ "ovu aktivnost." + +#~ msgid "" +#~ "The keybinding that switches to workspace 5. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "Kombinacija tipki koja prebacuje na radni prostor 5. Oblik zapisa izgleda " +#~ "kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program za obradu je dosta " +#~ "slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " +#~ "\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " +#~ "\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za " +#~ "ovu aktivnost." + +#~ msgid "" +#~ "The keybinding that switches to workspace 6. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "Kombinacija tipki koja prebacuje na radni prostor 6. Oblik zapisa izgleda " +#~ "kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program za obradu je dosta " +#~ "slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " +#~ "\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " +#~ "\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za " +#~ "ovu aktivnost." + +#~ msgid "" +#~ "The keybinding that switches to workspace 7. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "Kombinacija tipki koja prebacuje na radni prostor 7. Oblik zapisa izgleda " +#~ "kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program za obradu je dosta " +#~ "slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " +#~ "\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " +#~ "\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za " +#~ "ovu aktivnost." + +#~ msgid "" +#~ "The keybinding that switches to workspace 8. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "Kombinacija tipki koja prebacuje na radni prostor 8. Oblik zapisa izgleda " +#~ "kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program za obradu je dosta " +#~ "slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " +#~ "\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " +#~ "\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za " +#~ "ovu aktivnost." + +#~ msgid "" +#~ "The keybinding that switches to workspace 9. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "Kombinacija tipki koja prebacuje na radni prostor 9. Oblik zapisa izgleda " +#~ "kao \"<Control>a\" ili \"<Shift><Alt>F1\".Program za obradu je dosta " +#~ "slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " +#~ "\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " +#~ "\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za " +#~ "ovu aktivnost." + +#~ msgid "" +#~ "The keybinding used to activate the window menu. The format looks like " +#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " +#~ "fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "Kombinacija tipki koja pokreće izbornik prozora. Oblik zapisa izgleda kao " +#~ "\"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu je dosta " +#~ "slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " +#~ "\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " +#~ "\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za " +#~ "ovu aktivnost." + +#~ msgid "" +#~ "The keybinding used to close a window. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "Kombinacija tipki koja zatvara prozor. Oblik zapisa izgleda kao " +#~ "\"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu je dosta " +#~ "slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " +#~ "\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " +#~ "\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za " +#~ "ovu aktivnost." + +#~ msgid "" +#~ "The keybinding used to enter \"move mode\" and begin moving a window " +#~ "using the keyboard. The format looks like \"<Control>a\" or \"<" +#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " +#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" +#~ "Ctrl>\". If you set the option to the special string \"disabled\", " +#~ "then there will be no keybinding for this action." +#~ msgstr "" +#~ "Kombinacija tipki koja postavlja prozor u način rada za pomicanje i " +#~ "omogućava pomicanje prozora pomoću tipkovnice. Oblik zapisa izgleda kao " +#~ "\"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu je dosta " +#~ "slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " +#~ "\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " +#~ "\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za " +#~ "ovu aktivnost." + +#~ msgid "" +#~ "The keybinding used to enter \"resize mode\" and begin resizing a window " +#~ "using the keyboard. The format looks like \"<Control>a\" or \"<" +#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " +#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" +#~ "Ctrl>\". If you set the option to the special string \"disabled\", " +#~ "then there will be no keybinding for this action." +#~ msgstr "" +#~ "Kombinacija tipki koja postavlja prozor u način rada za razvlačenje i " +#~ "omogućava razvlačenje prozora pomoću tipkovnice. Oblik zapisa izgleda kao " +#~ "\"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu je dosta " +#~ "slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " +#~ "\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " +#~ "\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za " +#~ "ovu aktivnost." + +#~ msgid "" +#~ "The keybinding used to hide all normal windows and set the focus to the " +#~ "desktop background. The format looks like \"<Control>a\" or \"<" +#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " +#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" +#~ "Ctrl>\". If you set the option to the special string \"disabled\", " +#~ "then there will be no keybinding for this action." +#~ msgstr "" +#~ "Kombinacija tipki koja skriva sve obične prozore i postavlja fokus na " +#~ "pozadinu radne površine. Oblik zapisa izgleda kao \"<Control>a\" ili " +#~ "\"<Shift><Alt>F1\". Program za obradu je dosta slobodan i dozvoljava " +#~ "velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". " +#~ "Ako postavite opciju na specijalni niz znakova \"disabled\", tada neće " +#~ "biti korištena niti jedna kombinacija tipki za ovu aktivnost." + +#~ msgid "" +#~ "The keybinding used to maximize a window. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "Kombinacija tipki koja povećava prozor. Oblik zapisa izgleda kao " +#~ "\"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu je dosta " +#~ "slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " +#~ "\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " +#~ "\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za " +#~ "ovu aktivnost." + +#~ msgid "" +#~ "The keybinding used to minimize a window. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "Kombinacija tipki koja smanjuje prozor. Oblik zapisa izgleda kao " +#~ "\"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu je dosta " +#~ "slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " +#~ "\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " +#~ "\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za " +#~ "ovu aktivnost." + +#~ msgid "" +#~ "The keybinding used to move a window one workspace down. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " +#~ "is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "Kombinacija tipki koja premiješta prozor za jednu radnu površinu niže. " +#~ "Oblik zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program " +#~ "za obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " +#~ "skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na " +#~ "specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " +#~ "kombinacija tipki za ovu aktivnost." + +#~ msgid "" +#~ "The keybinding used to move a window one workspace to the left. The " +#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " +#~ "The parser is fairly liberal and allows lower or upper case, and also " +#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " +#~ "the option to the special string \"disabled\", then there will be no " +#~ "keybinding for this action." +#~ msgstr "" +#~ "Kombinacija tipki koja premiješta prozor za jednu radnu površinu lijevo. " +#~ "Oblik zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program " +#~ "za obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " +#~ "skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na " +#~ "specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " +#~ "kombinacija tipki za ovu aktivnost." + +#~ msgid "" +#~ "The keybinding used to move a window one workspace to the right. The " +#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " +#~ "The parser is fairly liberal and allows lower or upper case, and also " +#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " +#~ "the option to the special string \"disabled\", then there will be no " +#~ "keybinding for this action." +#~ msgstr "" +#~ "Kombinacija tipki koja premiješta prozor za jednu radnu površinu desno." +#~ "Oblik zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program " +#~ "za obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " +#~ "skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na " +#~ "specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " +#~ "kombinacija tipki za ovu aktivnost." + +#~ msgid "" +#~ "The keybinding used to move a window one workspace up. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " +#~ "is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "Kombinacija tipki koja premiješta prozor za jednu radnu površinu više. " +#~ "Oblik zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program " +#~ "za obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " +#~ "skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na " +#~ "specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " +#~ "kombinacija tipki za ovu aktivnost." + +#~ msgid "" +#~ "The keybinding used to move a window to workspace 1. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " +#~ "is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "Kombinacija tipki koja premiješta prozor na radnu površinu 1. Oblik " +#~ "zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za " +#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " +#~ "skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na " +#~ "specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " +#~ "kombinacija tipki za ovu aktivnost." + +#~ msgid "" +#~ "The keybinding used to move a window to workspace 10. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " +#~ "is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "Kombinacija tipki koja premiješta prozor na radnu površinu 1. Oblik " +#~ "zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za " +#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " +#~ "skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na " +#~ "specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " +#~ "kombinacija tipki za ovu aktivnost." + +#~ msgid "" +#~ "The keybinding used to move a window to workspace 11. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " +#~ "is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "Kombinacija tipki koja premiješta prozor na radnu površinu 11. Oblik " +#~ "zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za " +#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " +#~ "skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na " +#~ "specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " +#~ "kombinacija tipki za ovu aktivnost." + +#~ msgid "" +#~ "The keybinding used to move a window to workspace 12. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " +#~ "is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "Kombinacija tipki koja premiješta prozor na radnu površinu 12. Oblik " +#~ "zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za " +#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " +#~ "skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na " +#~ "specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " +#~ "kombinacija tipki za ovu aktivnost." + +#~ msgid "" +#~ "The keybinding used to move a window to workspace 2. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " +#~ "is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "Kombinacija tipki koja premiješta prozor na radnu površinu 2. Oblik " +#~ "zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za " +#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " +#~ "skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na " +#~ "specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " +#~ "kombinacija tipki za ovu aktivnost." + +#~ msgid "" +#~ "The keybinding used to move a window to workspace 3. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " +#~ "is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "Kombinacija tipki koja premiješta prozor na radnu površinu 3. Oblik " +#~ "zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za " +#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " +#~ "skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na " +#~ "specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " +#~ "kombinacija tipki za ovu aktivnost." + +#~ msgid "" +#~ "The keybinding used to move a window to workspace 4. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " +#~ "is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "Kombinacija tipki koja premiješta prozor na radnu površinu 4. Oblik " +#~ "zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za " +#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " +#~ "skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na " +#~ "specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " +#~ "kombinacija tipki za ovu aktivnost." + +#~ msgid "" +#~ "The keybinding used to move a window to workspace 5. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " +#~ "is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "Kombinacija tipki koja premiješta prozor na radnu površinu 5. Oblik " +#~ "zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za " +#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " +#~ "skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na " +#~ "specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " +#~ "kombinacija tipki za ovu aktivnost." + +#~ msgid "" +#~ "The keybinding used to move a window to workspace 6. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " +#~ "is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "Kombinacija tipki koja premiješta prozor na radnu površinu 6. Oblik " +#~ "zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za " +#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " +#~ "skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na " +#~ "specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " +#~ "kombinacija tipki za ovu aktivnost." + +#~ msgid "" +#~ "The keybinding used to move a window to workspace 7. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " +#~ "is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "Kombinacija tipki koja premiješta prozor na radnu površinu 7. Oblik " +#~ "zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za " +#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " +#~ "skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na " +#~ "specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " +#~ "kombinacija tipki za ovu aktivnost." + +#~ msgid "" +#~ "The keybinding used to move a window to workspace 8. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " +#~ "is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "Kombinacija tipki koja premiješta prozor na radnu površinu 8. Oblik " +#~ "zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za " +#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " +#~ "skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na " +#~ "specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " +#~ "kombinacija tipki za ovu aktivnost." + +#~ msgid "" +#~ "The keybinding used to move a window to workspace 9. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " +#~ "is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "Kombinacija tipki koja premiješta prozor na radnu površinu 9. Oblik " +#~ "zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za " +#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " +#~ "skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na " +#~ "specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " +#~ "kombinacija tipki za ovu aktivnost." + +#~ msgid "" +#~ "The keybinding used to move focus backwards between panels and the " +#~ "desktop, using a popup window. The format looks like \"<Control>a\" " +#~ "or \"<Shift><Alt>F1\". The parser is fairly liberal and " +#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" +#~ "\" and \"<Ctrl>\". If you set the option to the special string " +#~ "\"disabled\", then there will be no keybinding for this action." +#~ msgstr "" +#~ "Kombinacija tipki koja premiješta fokus unazad između panela i radne " +#~ "površine koristeći popup prozor. Oblik zapisa izgleda kao \"<Control>a\" " +#~ "ili \"<Shift><Alt>F1\". Program za obradu je dosta slobodan i dozvoljava " +#~ "velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". " +#~ "Ako postavite opciju na specijalni niz znakova \"disabled\", tada neće " +#~ "biti korištena niti jedna kombinacija tipki za ovu aktivnost." + +#~ msgid "" +#~ "The keybinding used to move focus backwards between panels and the " +#~ "desktop, without a popup window. The format looks like \"<Control>a" +#~ "\" or \"<Shift><Alt>F1\". The parser is fairly liberal and " +#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" +#~ "\" and \"<Ctrl>\". If you set the option to the special string " +#~ "\"disabled\", then there will be no keybinding for this action." +#~ msgstr "" +#~ "Kombinacija tipki koja premiješta fokus unazad između panela i radne " +#~ "površine bez popup prozora. Oblik zapisa izgleda kao \"<Control>a\" ili " +#~ "\"<Shift><Alt>F1\". Program za obradu je dosta slobodan i dozvoljava " +#~ "velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". " +#~ "Ako postavite opciju na specijalni niz znakova \"disabled\", tada neće " +#~ "biti korištena niti jedna kombinacija tipki za ovu aktivnost." + +#~ msgid "" +#~ "The keybinding used to move focus backwards between windows of an " +#~ "application without a popup window. Holding \"shift\" together with this " +#~ "binding makes the direction go forward again. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "Ova kombinacija tipki se koristi kako bi prebacivali fokus unatrag između " +#~ "prozora aplikacije bez popup prozora. Držeći \"shift\" zajedno s ovom " +#~ "kombinacijom fokus se mjenja naprijed. Format izgleda kao \"<" +#~ "Control>a\" ili \"<Shift><Alt>F1\", te je prilično " +#~ "fleksibilan te dozvoljava mala ili velika slova te kratice poput \"<" +#~ "Ctl>\" i \"<Ctrl>\". Ako unesete posebnu riječ \"disabled\", " +#~ "neće biti kombinacije tipki za ovu akciju." + +#~ msgid "" +#~ "The keybinding used to move focus backwards between windows of an " +#~ "application, using a popup window. Holding \"shift\" together with this " +#~ "binding makes the direction go forward again. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "Ova kombinacija tipki se koristi kako bi prebacivali fokus unatrag između " +#~ "prozora aplikacije sa popup prozorom.Držeći \"shift\" zajedno s ovom " +#~ "kombinacijom fokus se mjenja naprijed. Format izgleda kao \"<" +#~ "Control>a\" ili \"<Shift><Alt>F1\", te je prilično " +#~ "fleksibilan te dozvoljava mala ili velika slova te kratice poput \"<" +#~ "Ctl>\" i \"<Ctrl>\". Ako unesete posebnu riječ \"disabled\", " +#~ "neće biti kombinacije tipki za ovu akciju." + +#~ msgid "" +#~ "The keybinding used to move focus backwards between windows without a " +#~ "popup window. Holding \"shift\" together with this binding makes the " +#~ "direction go forward again. The format looks like \"<Control>a\" or " +#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " +#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " +#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" +#~ "\", then there will be no keybinding for this action." +#~ msgstr "" +#~ "Kombinacija tipki koja premiješta fokus unazad između prozora bez popup " +#~ "prozora. Držeći tipku \"shift\" zajedno s kombinacijom tipki omogućuje se " +#~ "suprotni smijer premiještanja. Oblik zapisa izgleda kao \"<Control>a\" " +#~ "ili \"<Shift><Alt>F1\". Program za obradu je dosta slobodan i dozvoljava " +#~ "velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". " +#~ "Ako postavite opciju na specijalni niz znakova \"disabled\", tada neće " +#~ "biti korištena niti jedna kombinacija tipki za ovu aktivnost." + +#~ msgid "" +#~ "The keybinding used to move focus backwards between windows, using a " +#~ "popup window. Holding \"shift\" together with this binding makes the " +#~ "direction go forward again. The format looks like \"<Control>a\" or " +#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " +#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " +#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" +#~ "\", then there will be no keybinding for this action." +#~ msgstr "" +#~ "Kombinacija tipki koja premiješta fokus unazad između prozora koristeći " +#~ "popup prozor. Držeći tipku \"shift\" zajedno s kombinacijom tipki " +#~ "omogućuje se suprotni smijer premiještanja. Oblik zapisa izgleda kao " +#~ "\"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu je dosta " +#~ "slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " +#~ "\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " +#~ "\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za " +#~ "ovu aktivnost." + +#~ msgid "" +#~ "The keybinding used to move focus between panels and the desktop, using a " +#~ "popup window. The format looks like \"<Control>a\" or \"<" +#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " +#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" +#~ "Ctrl>\". If you set the option to the special string \"disabled\", " +#~ "then there will be no keybinding for this action." +#~ msgstr "" +#~ "Kombinacija tipki koja premiješta fokus između ploče i radne površine " +#~ "koristeći popup prozor. Oblik zapisa izgleda kao \"<Control>a\" ili " +#~ "\"<Shift><Alt>F1\". Program za obradu je dosta slobodan i dozvoljava " +#~ "velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". " +#~ "Ako postavite opciju na specijalni niz znakova \"disabled\", tada neće " +#~ "biti korištena niti jedna kombinacija tipki za ovu aktivnost." + +#~ msgid "" +#~ "The keybinding used to move focus between panels and the desktop, without " +#~ "a popup window. The format looks like \"<Control>a\" or \"<" +#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " +#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" +#~ "Ctrl>\". If you set the option to the special string \"disabled\", " +#~ "then there will be no keybinding for this action." +#~ msgstr "" +#~ "Kombinacija tipki koja premiješta fokus između ploče i radne površine bez " +#~ "popup prozora. Oblik zapisa izgleda kao \"<Control>a\" ili " +#~ "\"<Shift><Alt>F1\". Program za obradu je dosta slobodan i dozvoljava " +#~ "velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". " +#~ "Ako postavite opciju na specijalni niz znakova \"disabled\", tada neće " +#~ "biti korištena niti jedna kombinacija tipki za ovu aktivnost." + +#~ msgid "" +#~ "The keybinding used to move focus between windows of an application " +#~ "without a popup window. Holding the \"shift\" key while using this " +#~ "binding reverses the direction of movement. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "Ova kombinacija tipki se koristi kako bi prebacivali fokus unatrag između " +#~ "prozora aplikacije bez popup prozora. Držeći \"shift\" zajedno s ovom " +#~ "kombinacijom fokus se mjenja naprijed. Format izgleda kao \"<" +#~ "Control>a\" ili \"<Shift><Alt>F1\", te je prilično " +#~ "fleksibilan te dozvoljava mala ili velika slova te kratice poput \"<" +#~ "Ctl>\" i \"<Ctrl>\". Ako unesete posebnu riječ \"disabled\", " +#~ "neće biti kombinacije tipki za ovu akciju." + +#~ msgid "" +#~ "The keybinding used to move focus between windows of an application, " +#~ "using a popup window. (Traditionally <Alt>F6) Holding the \"shift\" " +#~ "key while using this binding reverses the direction of movement. The " +#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " +#~ "The parser is fairly liberal and allows lower or upper case, and also " +#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " +#~ "the option to the special string \"disabled\", then there will be no " +#~ "keybinding for this action." +#~ msgstr "" +#~ "Ova kombinacija tipki se koristi kako bi prebacivali fokus unatrag između " +#~ "prozora aplikacije sa popup prozorom. Držeći \"shift\" zajedno s ovom " +#~ "kombinacijom fokus se mjenja naprijed. Format izgleda kao \"<" +#~ "Control>a\" ili \"<Shift><Alt>F1\", te je prilično " +#~ "fleksibilan te dozvoljava mala ili velika slova te kratice poput \"<" +#~ "Ctl>\" i \"<Ctrl>\". Ako unesete posebnu riječ \"disabled\", " +#~ "neće biti kombinacije tipki za ovu akciju." + +#~ msgid "" +#~ "The keybinding used to move focus between windows without a popup window. " +#~ "(Traditionally <Alt>Escape) Holding the \"shift\" key while using " +#~ "this binding reverses the direction of movement. The format looks like " +#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " +#~ "fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "Kombinacija tipki koja premiješta fokus između prozora bez popup prozora." +#~ "(Uobičajeno <Alt>Escape) Držeći tipku \"shift\" zajedno s kombinacijom " +#~ "tipki omogućuje se suprotni smijer premiještanja. Oblik zapisa izgleda " +#~ "kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu je dosta " +#~ "slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " +#~ "\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " +#~ "\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za " +#~ "ovu aktivnost." + +#~ msgid "" +#~ "The keybinding used to move focus between windows, using a popup window. " +#~ "(Traditionally <Alt>Tab) Holding the \"shift\" key while using this " +#~ "binding reverses the direction of movement. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "Kombinacija tipki koja premiješta fokus između prozora koristeći popup " +#~ "prozor. (Uobičajeno <Alt>Tab) Držeći tipku \"shift\" zajedno s " +#~ "kombinacijom tipki omogućuje se suprotni smijer premiještanja. Oblik " +#~ "zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za " +#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " +#~ "skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na " +#~ "specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " +#~ "kombinacija tipki za ovu aktivnost." -#: ../src/metacity.schemas.in.h:124 -msgid "" -"The keybinding used to close a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja zatvara prozor. Oblik zapisa izgleda kao \"<Control>a" -"\" ili \"<Shift><Alt>F1\". Program za obradu je dosta slobodan i dozvoljava " -"velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". " -"Ako postavite opciju na specijalni niz znakova \"disabled\", tada neće biti " -"korištena niti jedna kombinacija tipki za ovu aktivnost." +#~ msgid "" +#~ "The keybinding used to toggle always on top. A window that is always on " +#~ "top will always be visible over other overlapping windows. The format " +#~ "looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " +#~ "parser is fairly liberal and allows lower or upper case, and also " +#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " +#~ "the option to the special string \"disabled\", then there will be no " +#~ "keybinding for this action." +#~ msgstr "" +#~ "Kombinacija tipki koja uključuje ili isključuje opciju da prozor bude " +#~ "uvijek na vrhu. Prozor koji je uvijek na vrhu videti će se preko drugih " +#~ "preklapajućih prozora. Oblik zapisa izgleda kao \"<Control>a\" ili " +#~ "\"<Shift><Alt>F1\". Program za obradu je dosta slobodan i dozvoljava " +#~ "velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". " +#~ "Ako postavite opciju na specijalni niz znakova \"disabled\", tada neće " +#~ "biti korištena niti jedna kombinacija tipki za ovu aktivnost." -#: ../src/metacity.schemas.in.h:125 -msgid "" -"The keybinding used to enter \"move mode\" and begin moving a window using " -"the keyboard. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" -"Kombinacija tipki koja postavlja prozor u način rada za pomicanje i " -"omogućava pomicanje prozora pomoću tipkovnice. Oblik zapisa izgleda kao " -"\"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu je dosta slobodan i " -"dozvoljava velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< " -"Ctrl>\". Ako postavite opciju na specijalni niz znakova \"disabled\", tada " -"neće biti korištena niti jedna kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:126 -msgid "" -"The keybinding used to enter \"resize mode\" and begin resizing a window " -"using the keyboard. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja postavlja prozor u način rada za razvlačenje i " -"omogućava razvlačenje prozora pomoću tipkovnice. Oblik zapisa izgleda kao " -"\"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu je dosta slobodan i " -"dozvoljava velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< " -"Ctrl>\". Ako postavite opciju na specijalni niz znakova \"disabled\", tada " -"neće biti korištena niti jedna kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:127 -msgid "" -"The keybinding used to hide all normal windows and set the focus to the " -"desktop background. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja skriva sve obične prozore i postavlja fokus na " -"pozadinu radne površine. Oblik zapisa izgleda kao \"<Control>a\" ili " -"\"<Shift><Alt>F1\". Program za obradu je dosta slobodan i dozvoljava velika " -"ili mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako " -"postavite opciju na specijalni niz znakova \"disabled\", tada neće biti " -"korištena niti jedna kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:128 -msgid "" -"The keybinding used to maximize a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja povećava prozor. Oblik zapisa izgleda kao \"<Control>a" -"\" ili \"<Shift><Alt>F1\". Program za obradu je dosta slobodan i dozvoljava " -"velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". " -"Ako postavite opciju na specijalni niz znakova \"disabled\", tada neće biti " -"korištena niti jedna kombinacija tipki za ovu aktivnost." +#~ msgid "" +#~ "The keybinding used to toggle fullscreen mode. The format looks like " +#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " +#~ "fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "Kombinacija tipki koja uključuje ili isključuje prikaz preko cijelog " +#~ "zaslona.Oblik zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". " +#~ "Program za obradu je dosta slobodan i dozvoljava velika ili mala slova, " +#~ "takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju " +#~ "na specijalni niz znakova \"disabled\", tada neće biti korištena niti " +#~ "jedna kombinacija tipki za ovu aktivnost." -#: ../src/metacity.schemas.in.h:129 -msgid "" -"The keybinding used to minimize a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja smanjuje prozor. Oblik zapisa izgleda kao \"<Control>a" -"\" ili \"<Shift><Alt>F1\". Program za obradu je dosta slobodan i dozvoljava " -"velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". " -"Ako postavite opciju na specijalni niz znakova \"disabled\", tada neće biti " -"korištena niti jedna kombinacija tipki za ovu aktivnost." +#~ msgid "" +#~ "The keybinding used to toggle maximization. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "Kombinacija tipki koja uključuje ili isključuje uvećanje prozora na " +#~ "najveću moguću veličinu. Oblik zapisa izgleda kao \"<Control>a\" ili " +#~ "\"<Shift><Alt>F1\". Program za obradu je dosta slobodan i dozvoljava " +#~ "velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". " +#~ "Ako postavite opciju na specijalni niz znakova \"disabled\", tada neće " +#~ "biti korištena niti jedna kombinacija tipki za ovu aktivnost." -#: ../src/metacity.schemas.in.h:130 -msgid "" -"The keybinding used to move a window one workspace down. The format looks " -"like \"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -"fairly liberal and allows lower or upper case, and also abbreviations such " -"as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -"special string \"disabled\", then there will be no keybinding for this " -"action." -msgstr "" -"Kombinacija tipki koja premiješta prozor za jednu radnu površinu niže. Oblik " -"zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu " -"je dosta slobodan i dozvoljava velika ili mala slova, takođe i skraćenice " -"poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz " -"znakova \"disabled\", tada neće biti korištena niti jedna kombinacija tipki " -"za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:131 -msgid "" -"The keybinding used to move a window one workspace to the left. The format " -"looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -"parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"Kombinacija tipki koja premiješta prozor za jednu radnu površinu lijevo. " -"Oblik zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za " -"obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " -"skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni " -"niz znakova \"disabled\", tada neće biti korištena niti jedna kombinacija " -"tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:132 -msgid "" -"The keybinding used to move a window one workspace to the right. The format " -"looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -"parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"Kombinacija tipki koja premiješta prozor za jednu radnu površinu desno.Oblik " -"zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu " -"je dosta slobodan i dozvoljava velika ili mala slova, takođe i skraćenice " -"poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz " -"znakova \"disabled\", tada neće biti korištena niti jedna kombinacija tipki " -"za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:133 -msgid "" -"The keybinding used to move a window one workspace up. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja premiješta prozor za jednu radnu površinu više. Oblik " -"zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu " -"je dosta slobodan i dozvoljava velika ili mala slova, takođe i skraćenice " -"poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz " -"znakova \"disabled\", tada neće biti korištena niti jedna kombinacija tipki " -"za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:134 -msgid "" -"The keybinding used to move a window to workspace 1. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja premiješta prozor na radnu površinu 1. Oblik zapisa " -"izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu je " -"dosta slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " -"\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " -"\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za ovu " -"aktivnost." - -#: ../src/metacity.schemas.in.h:135 -msgid "" -"The keybinding used to move a window to workspace 10. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja premiješta prozor na radnu površinu 1. Oblik zapisa " -"izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu je " -"dosta slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " -"\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " -"\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za ovu " -"aktivnost." - -#: ../src/metacity.schemas.in.h:136 -msgid "" -"The keybinding used to move a window to workspace 11. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja premiješta prozor na radnu površinu 11. Oblik zapisa " -"izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu je " -"dosta slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " -"\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " -"\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za ovu " -"aktivnost." - -#: ../src/metacity.schemas.in.h:137 -msgid "" -"The keybinding used to move a window to workspace 12. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja premiješta prozor na radnu površinu 12. Oblik zapisa " -"izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu je " -"dosta slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " -"\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " -"\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za ovu " -"aktivnost." - -#: ../src/metacity.schemas.in.h:138 -msgid "" -"The keybinding used to move a window to workspace 2. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja premiješta prozor na radnu površinu 2. Oblik zapisa " -"izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu je " -"dosta slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " -"\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " -"\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za ovu " -"aktivnost." - -#: ../src/metacity.schemas.in.h:139 -msgid "" -"The keybinding used to move a window to workspace 3. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja premiješta prozor na radnu površinu 3. Oblik zapisa " -"izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu je " -"dosta slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " -"\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " -"\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za ovu " -"aktivnost." - -#: ../src/metacity.schemas.in.h:140 -msgid "" -"The keybinding used to move a window to workspace 4. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja premiješta prozor na radnu površinu 4. Oblik zapisa " -"izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu je " -"dosta slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " -"\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " -"\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za ovu " -"aktivnost." - -#: ../src/metacity.schemas.in.h:141 -msgid "" -"The keybinding used to move a window to workspace 5. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja premiješta prozor na radnu površinu 5. Oblik zapisa " -"izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu je " -"dosta slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " -"\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " -"\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za ovu " -"aktivnost." - -#: ../src/metacity.schemas.in.h:142 -msgid "" -"The keybinding used to move a window to workspace 6. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja premiješta prozor na radnu površinu 6. Oblik zapisa " -"izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu je " -"dosta slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " -"\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " -"\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za ovu " -"aktivnost." - -#: ../src/metacity.schemas.in.h:143 -msgid "" -"The keybinding used to move a window to workspace 7. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja premiješta prozor na radnu površinu 7. Oblik zapisa " -"izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu je " -"dosta slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " -"\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " -"\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za ovu " -"aktivnost." - -#: ../src/metacity.schemas.in.h:144 -msgid "" -"The keybinding used to move a window to workspace 8. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja premiješta prozor na radnu površinu 8. Oblik zapisa " -"izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu je " -"dosta slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " -"\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " -"\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za ovu " -"aktivnost." - -#: ../src/metacity.schemas.in.h:145 -msgid "" -"The keybinding used to move a window to workspace 9. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja premiješta prozor na radnu površinu 9. Oblik zapisa " -"izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu je " -"dosta slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " -"\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " -"\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za ovu " -"aktivnost." - -#: ../src/metacity.schemas.in.h:146 -msgid "" -"The keybinding used to move focus backwards between panels and the desktop, " -"using a popup window. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja premiješta fokus unazad između panela i radne " -"površine koristeći popup prozor. Oblik zapisa izgleda kao \"<Control>a\" ili " -"\"<Shift><Alt>F1\". Program za obradu je dosta slobodan i dozvoljava velika " -"ili mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako " -"postavite opciju na specijalni niz znakova \"disabled\", tada neće biti " -"korištena niti jedna kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:147 -msgid "" -"The keybinding used to move focus backwards between panels and the desktop, " -"without a popup window. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja premiješta fokus unazad između panela i radne " -"površine bez popup prozora. Oblik zapisa izgleda kao \"<Control>a\" ili " -"\"<Shift><Alt>F1\". Program za obradu je dosta slobodan i dozvoljava velika " -"ili mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako " -"postavite opciju na specijalni niz znakova \"disabled\", tada neće biti " -"korištena niti jedna kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:148 -msgid "" -"The keybinding used to move focus backwards between windows of an " -"application without a popup window. Holding \"shift\" together with this " -"binding makes the direction go forward again. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Ova kombinacija tipki se koristi kako bi prebacivali fokus unatrag između " -"prozora aplikacije bez popup prozora. Držeći \"shift\" zajedno s ovom " -"kombinacijom fokus se mjenja naprijed. Format izgleda kao \"<Control>a" -"\" ili \"<Shift><Alt>F1\", te je prilično fleksibilan te " -"dozvoljava mala ili velika slova te kratice poput \"<Ctl>\" i \"<" -"Ctrl>\". Ako unesete posebnu riječ \"disabled\", neće biti kombinacije " -"tipki za ovu akciju." - -#: ../src/metacity.schemas.in.h:149 -msgid "" -"The keybinding used to move focus backwards between windows of an " -"application, using a popup window. Holding \"shift\" together with this " -"binding makes the direction go forward again. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Ova kombinacija tipki se koristi kako bi prebacivali fokus unatrag između " -"prozora aplikacije sa popup prozorom.Držeći \"shift\" zajedno s ovom " -"kombinacijom fokus se mjenja naprijed. Format izgleda kao \"<Control>a" -"\" ili \"<Shift><Alt>F1\", te je prilično fleksibilan te " -"dozvoljava mala ili velika slova te kratice poput \"<Ctl>\" i \"<" -"Ctrl>\". Ako unesete posebnu riječ \"disabled\", neće biti kombinacije " -"tipki za ovu akciju." - -#: ../src/metacity.schemas.in.h:150 -msgid "" -"The keybinding used to move focus backwards between windows without a popup " -"window. Holding \"shift\" together with this binding makes the direction go " -"forward again. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" -"Kombinacija tipki koja premiješta fokus unazad između prozora bez popup " -"prozora. Držeći tipku \"shift\" zajedno s kombinacijom tipki omogućuje se " -"suprotni smijer premiještanja. Oblik zapisa izgleda kao \"<Control>a\" ili " -"\"<Shift><Alt>F1\". Program za obradu je dosta slobodan i dozvoljava velika " -"ili mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako " -"postavite opciju na specijalni niz znakova \"disabled\", tada neće biti " -"korištena niti jedna kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:151 -msgid "" -"The keybinding used to move focus backwards between windows, using a popup " -"window. Holding \"shift\" together with this binding makes the direction go " -"forward again. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" -"Kombinacija tipki koja premiješta fokus unazad između prozora koristeći " -"popup prozor. Držeći tipku \"shift\" zajedno s kombinacijom tipki omogućuje " -"se suprotni smijer premiještanja. Oblik zapisa izgleda kao \"<Control>a\" " -"ili \"<Shift><Alt>F1\". Program za obradu je dosta slobodan i dozvoljava " -"velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". " -"Ako postavite opciju na specijalni niz znakova \"disabled\", tada neće biti " -"korištena niti jedna kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:152 -msgid "" -"The keybinding used to move focus between panels and the desktop, using a " -"popup window. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" -"Kombinacija tipki koja premiješta fokus između ploče i radne površine " -"koristeći popup prozor. Oblik zapisa izgleda kao \"<Control>a\" ili " -"\"<Shift><Alt>F1\". Program za obradu je dosta slobodan i dozvoljava velika " -"ili mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako " -"postavite opciju na specijalni niz znakova \"disabled\", tada neće biti " -"korištena niti jedna kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:153 -msgid "" -"The keybinding used to move focus between panels and the desktop, without a " -"popup window. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" -"Kombinacija tipki koja premiješta fokus između ploče i radne površine bez " -"popup prozora. Oblik zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1" -"\". Program za obradu je dosta slobodan i dozvoljava velika ili mala slova, " -"takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na " -"specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:154 -msgid "" -"The keybinding used to move focus between windows of an application without " -"a popup window. Holding the \"shift\" key while using this binding reverses " -"the direction of movement. The format looks like \"<Control>a\" or " -"\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -"lower or upper case, and also abbreviations such as \"<Ctl>\" and " -"\"<Ctrl>\". If you set the option to the special string \"disabled\", " -"then there will be no keybinding for this action." -msgstr "" -"Ova kombinacija tipki se koristi kako bi prebacivali fokus unatrag između " -"prozora aplikacije bez popup prozora. Držeći \"shift\" zajedno s ovom " -"kombinacijom fokus se mjenja naprijed. Format izgleda kao \"<Control>a" -"\" ili \"<Shift><Alt>F1\", te je prilično fleksibilan te " -"dozvoljava mala ili velika slova te kratice poput \"<Ctl>\" i \"<" -"Ctrl>\". Ako unesete posebnu riječ \"disabled\", neće biti kombinacije " -"tipki za ovu akciju." - -#: ../src/metacity.schemas.in.h:155 -msgid "" -"The keybinding used to move focus between windows of an application, using a " -"popup window. (Traditionally <Alt>F6) Holding the \"shift\" key while " -"using this binding reverses the direction of movement. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Ova kombinacija tipki se koristi kako bi prebacivali fokus unatrag između " -"prozora aplikacije sa popup prozorom. Držeći \"shift\" zajedno s ovom " -"kombinacijom fokus se mjenja naprijed. Format izgleda kao \"<Control>a" -"\" ili \"<Shift><Alt>F1\", te je prilično fleksibilan te " -"dozvoljava mala ili velika slova te kratice poput \"<Ctl>\" i \"<" -"Ctrl>\". Ako unesete posebnu riječ \"disabled\", neće biti kombinacije " -"tipki za ovu akciju." - -#: ../src/metacity.schemas.in.h:156 -msgid "" -"The keybinding used to move focus between windows without a popup window. " -"(Traditionally <Alt>Escape) Holding the \"shift\" key while using this " -"binding reverses the direction of movement. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja premiješta fokus između prozora bez popup prozora." -"(Uobičajeno <Alt>Escape) Držeći tipku \"shift\" zajedno s kombinacijom tipki " -"omogućuje se suprotni smijer premiještanja. Oblik zapisa izgleda kao " -"\"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu je dosta slobodan i " -"dozvoljava velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< " -"Ctrl>\". Ako postavite opciju na specijalni niz znakova \"disabled\", tada " -"neće biti korištena niti jedna kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:157 -msgid "" -"The keybinding used to move focus between windows, using a popup window. " -"(Traditionally <Alt>Tab) Holding the \"shift\" key while using this " -"binding reverses the direction of movement. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja premiješta fokus između prozora koristeći popup " -"prozor. (Uobičajeno <Alt>Tab) Držeći tipku \"shift\" zajedno s kombinacijom " -"tipki omogućuje se suprotni smijer premiještanja. Oblik zapisa izgleda kao " -"\"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu je dosta slobodan i " -"dozvoljava velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< " -"Ctrl>\". Ako postavite opciju na specijalni niz znakova \"disabled\", tada " -"neće biti korištena niti jedna kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:158 -msgid "" -"The keybinding used to toggle always on top. A window that is always on top " -"will always be visible over other overlapping windows. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja uključuje ili isključuje opciju da prozor bude uvijek " -"na vrhu. Prozor koji je uvijek na vrhu videti će se preko drugih " -"preklapajućih prozora. Oblik zapisa izgleda kao \"<Control>a\" ili " -"\"<Shift><Alt>F1\". Program za obradu je dosta slobodan i dozvoljava velika " -"ili mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako " -"postavite opciju na specijalni niz znakova \"disabled\", tada neće biti " -"korištena niti jedna kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:159 -msgid "" -"The keybinding used to toggle fullscreen mode. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja uključuje ili isključuje prikaz preko cijelog zaslona." -"Oblik zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za " -"obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " -"skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni " -"niz znakova \"disabled\", tada neće biti korištena niti jedna kombinacija " -"tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:160 -msgid "" -"The keybinding used to toggle maximization. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja uključuje ili isključuje uvećanje prozora na najveću " -"moguću veličinu. Oblik zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1" -"\". Program za obradu je dosta slobodan i dozvoljava velika ili mala slova, " -"takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na " -"specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:161 -msgid "" -"The keybinding used to toggle shaded/unshaded state. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja uključuje ili isključuje zasjenčano stanje. Oblik " -"zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu " -"je dosta slobodan i dozvoljava velika ili mala slova, takođe i skraćenice " -"poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz " -"znakova \"disabled\", tada neće biti korištena niti jedna kombinacija tipki " -"za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:162 -msgid "" -"The keybinding used to toggle whether the window is on all workspaces or " -"just one. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" -"Kombinacija tipki koja uključuje ili isključuje mogučnost da prozor bude na " -"svim radnim površinama. Oblik zapisa izgleda kao \"<Control>a\" ili " -"\"<Shift><Alt>F1\". Program za obradu je dosta slobodan i dozvoljava velika " -"ili mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako " -"postavite opciju na specijalni niz znakova \"disabled\", tada neće biti " -"korištena niti jedna kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:163 -msgid "" -"The keybinding used to unmaximize a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja poništava uvećanje prozora na najveću moguću " -"veličinu. Oblik zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". " -"Program za obradu je dosta slobodan i dozvoljava velika ili mala slova, " -"takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na " -"specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:164 -msgid "" -"The keybinding which display's the panel's \"Run Application\" dialog box. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"Kombinacija tipki koja prikazuje dijaloški okvir \"Pokreni program\". Oblik " -"zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu " -"je dosta slobodan i dozvoljava velika ili mala slova, takođe i skraćenice " -"poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz " -"znakova \"disabled\", tada neće biti korištena niti jedna kombinacija tipki " -"za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:165 -msgid "" -"The keybinding which invokes a terminal. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja prikazuje glavni izbornik ploče. Oblik zapisa izgleda " -"kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu je dosta " -"slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " -"\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " -"\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za ovu " -"aktivnost." - -#: ../src/metacity.schemas.in.h:166 -msgid "" -"The keybinding which invokes the panel's screenshot utility to take a " -"screenshot of a window. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja pokreće alat ploče za snimanje izgleda prozora. Oblik " -"zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu " -"je dosta slobodan i dozvoljava velika ili mala slova, takođe i skraćenice " -"poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz " -"znakova \"disabled\", tada neće biti korištena niti jedna kombinacija tipki " -"za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:167 -msgid "" -"The keybinding which invokes the panel's screenshot utility. The format " -"looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -"parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"Kombinacija tipki koja pokreće alat ploče za snimanje izgleda zaslone. Oblik " -"zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu " -"je dosta slobodan i dozvoljava velika ili mala slova, takođe i skraćenice " -"poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz " -"znakova \"disabled\", tada neće biti korištena niti jedna kombinacija tipki " -"za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:168 -msgid "" -"The keybinding which shows the panel's main menu. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja prikazuje glavni izbornik ploče. Oblik zapisa izgleda " -"kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu je dosta " -"slobodan i dozvoljava velika ili mala slova, takođe i skraćenice poput " -"\"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz znakova " -"\"disabled\", tada neće biti korištena niti jedna kombinacija tipki za ovu " -"aktivnost." - -#: ../src/metacity.schemas.in.h:169 -msgid "The name of a workspace." -msgstr "Ime radne površine." - -#: ../src/metacity.schemas.in.h:170 -msgid "The screenshot command" -msgstr "Naredba za slikanje zaslona" - -#: ../src/metacity.schemas.in.h:171 -msgid "" -"The theme determines the appearance of window borders, titlebar, and so " -"forth." -msgstr "" -"Tema utvrđuje izgled rubova prozora, naslovne linije i svega ostalog sličnog." +#~ msgid "" +#~ "The keybinding used to toggle shaded/unshaded state. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " +#~ "is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "Kombinacija tipki koja uključuje ili isključuje zasjenčano stanje. Oblik " +#~ "zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za " +#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " +#~ "skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na " +#~ "specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " +#~ "kombinacija tipki za ovu aktivnost." -#: ../src/metacity.schemas.in.h:172 -msgid "" -"The time delay before raising a window if auto_raise is set to true. The " -"delay is given in thousandths of a second." -msgstr "" -"Vremenski period prije podizanja prozora ako je opcija auto_raise " -"postavljena na „true“. Period se izražava u tisućinkama sekunde." +#~ msgid "" +#~ "The keybinding used to toggle whether the window is on all workspaces or " +#~ "just one. The format looks like \"<Control>a\" or \"<Shift>" +#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " +#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" +#~ "\". If you set the option to the special string \"disabled\", then there " +#~ "will be no keybinding for this action." +#~ msgstr "" +#~ "Kombinacija tipki koja uključuje ili isključuje mogučnost da prozor bude " +#~ "na svim radnim površinama. Oblik zapisa izgleda kao \"<Control>a\" ili " +#~ "\"<Shift><Alt>F1\". Program za obradu je dosta slobodan i dozvoljava " +#~ "velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". " +#~ "Ako postavite opciju na specijalni niz znakova \"disabled\", tada neće " +#~ "biti korištena niti jedna kombinacija tipki za ovu aktivnost." -#: ../src/metacity.schemas.in.h:173 -msgid "" -"The window focus mode indicates how windows are activated. It has three " -"possible values; \"click\" means windows must be clicked in order to focus " -"them, \"sloppy\" means windows are focused when the mouse enters the window, " -"and \"mouse\" means windows are focused when the mouse enters the window and " -"unfocused when the mouse leaves the window." -msgstr "" -"Fokus prozora podešava kako će prozori biti aktivirani. Ima tri moguće " -"vrijednosti „click“ znači da prozor mora biti selektiran da bi dobio fokus, " -"„sloppy“ znači da prozor dobija fokus kada pokazivač miša uđe u prozor i " -"„mouse“ što znači da će prozor biti fokusiran kada pokazivačka strelica miša " -"uđe u prozor i biti defokusiran kada strelica izađe iz prozora." +#~ msgid "" +#~ "The keybinding used to unmaximize a window. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "Kombinacija tipki koja poništava uvećanje prozora na najveću moguću " +#~ "veličinu. Oblik zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". " +#~ "Program za obradu je dosta slobodan i dozvoljava velika ili mala slova, " +#~ "takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju " +#~ "na specijalni niz znakova \"disabled\", tada neće biti korištena niti " +#~ "jedna kombinacija tipki za ovu aktivnost." -#: ../src/metacity.schemas.in.h:174 -msgid "The window screenshot command" -msgstr "Naredba za snimanje prozora" +#~ msgid "" +#~ "The keybinding which display's the panel's \"Run Application\" dialog " +#~ "box. The format looks like \"<Control>a\" or \"<Shift><" +#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, " +#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If " +#~ "you set the option to the special string \"disabled\", then there will be " +#~ "no keybinding for this action." +#~ msgstr "" +#~ "Kombinacija tipki koja prikazuje dijaloški okvir \"Pokreni program\". " +#~ "Oblik zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program " +#~ "za obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " +#~ "skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na " +#~ "specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " +#~ "kombinacija tipki za ovu aktivnost." -#: ../src/metacity.schemas.in.h:175 -msgid "" -"This keybinding changes whether a window is above or below other windows. If " -"the window is covered by another one, it raises the window above all others, " -"and if the window is already fully visible, it lowers it below all others. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"Ova kombinacija tipki stavlja prozor iznad ili ispod ostalih prozora. Ako je " -"prozor pokriven drugim prozorom, podiže aktivni prozor iznad svih ostalih, a " -"ako je prozor već iznad svih, stavlja ga ispod. Format izgleda kao \"<" -"Control>a\" ili \"<Shift><Alt>F1\", te je prilično " -"fleksibilan te dozvoljava mala ili velika slova te kratice poput \"<" -"Ctl>\" i \"<Ctrl>\". Ako unesete posebnu riječ \"disabled\", neće " -"biti kombinacije tipki za ovu akciju." - -#: ../src/metacity.schemas.in.h:176 -msgid "" -"This keybinding lowers a window below other windows. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja spušta prozor ispod svih ostalih prozora. Oblik " -"zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu " -"je dosta slobodan i dozvoljava velika ili mala slova, takođe i skraćenice " -"poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz " -"znakova \"disabled\", tada neće biti korištena niti jedna kombinacija tipki " -"za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:177 -msgid "" -"This keybinding moves a window against the north (top) side of the screen. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"Ova kombinacija tipki pomiće prozor na sjevernu (gornju) stranu ekrana. " -"Format izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\", " -"te je prilično fleksibilan te dozvoljava mala ili velika slova te kratice " -"poput \"<Ctl>\" i \"<Ctrl>\". Ako unesete posebnu riječ " -"\"disabled\", neće biti kombinacije tipki za ovu akciju." +#~ msgid "" +#~ "The keybinding which invokes a terminal. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~ "liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~ "special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "Kombinacija tipki koja prikazuje glavni izbornik ploče. Oblik zapisa " +#~ "izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu je " +#~ "dosta slobodan i dozvoljava velika ili mala slova, takođe i skraćenice " +#~ "poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz " +#~ "znakova \"disabled\", tada neće biti korištena niti jedna kombinacija " +#~ "tipki za ovu aktivnost." + +#~ msgid "" +#~ "The keybinding which invokes the panel's screenshot utility to take a " +#~ "screenshot of a window. The format looks like \"<Control>a\" or " +#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " +#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " +#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" +#~ "\", then there will be no keybinding for this action." +#~ msgstr "" +#~ "Kombinacija tipki koja pokreće alat ploče za snimanje izgleda prozora. " +#~ "Oblik zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program " +#~ "za obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " +#~ "skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na " +#~ "specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " +#~ "kombinacija tipki za ovu aktivnost." + +#~ msgid "" +#~ "The keybinding which invokes the panel's screenshot utility. The format " +#~ "looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " +#~ "parser is fairly liberal and allows lower or upper case, and also " +#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " +#~ "the option to the special string \"disabled\", then there will be no " +#~ "keybinding for this action." +#~ msgstr "" +#~ "Kombinacija tipki koja pokreće alat ploče za snimanje izgleda zaslone. " +#~ "Oblik zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program " +#~ "za obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " +#~ "skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na " +#~ "specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " +#~ "kombinacija tipki za ovu aktivnost." + +#~ msgid "" +#~ "The keybinding which shows the panel's main menu. The format looks like " +#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " +#~ "fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "Kombinacija tipki koja prikazuje glavni izbornik ploče. Oblik zapisa " +#~ "izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu je " +#~ "dosta slobodan i dozvoljava velika ili mala slova, takođe i skraćenice " +#~ "poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz " +#~ "znakova \"disabled\", tada neće biti korištena niti jedna kombinacija " +#~ "tipki za ovu aktivnost." + +#~ msgid "The name of a workspace." +#~ msgstr "Ime radne površine." + +#~ msgid "The screenshot command" +#~ msgstr "Naredba za slikanje zaslona" + +#~ msgid "" +#~ "The theme determines the appearance of window borders, titlebar, and so " +#~ "forth." +#~ msgstr "" +#~ "Tema utvrđuje izgled rubova prozora, naslovne linije i svega ostalog " +#~ "sličnog." + +#~ msgid "" +#~ "The time delay before raising a window if auto_raise is set to true. The " +#~ "delay is given in thousandths of a second." +#~ msgstr "" +#~ "Vremenski period prije podizanja prozora ako je opcija auto_raise " +#~ "postavljena na „true“. Period se izražava u tisućinkama sekunde." + +#~ msgid "" +#~ "The window focus mode indicates how windows are activated. It has three " +#~ "possible values; \"click\" means windows must be clicked in order to " +#~ "focus them, \"sloppy\" means windows are focused when the mouse enters " +#~ "the window, and \"mouse\" means windows are focused when the mouse enters " +#~ "the window and unfocused when the mouse leaves the window." +#~ msgstr "" +#~ "Fokus prozora podešava kako će prozori biti aktivirani. Ima tri moguće " +#~ "vrijednosti „click“ znači da prozor mora biti selektiran da bi dobio " +#~ "fokus, „sloppy“ znači da prozor dobija fokus kada pokazivač miša uđe u " +#~ "prozor i „mouse“ što znači da će prozor biti fokusiran kada pokazivačka " +#~ "strelica miša uđe u prozor i biti defokusiran kada strelica izađe iz " +#~ "prozora." + +#~ msgid "The window screenshot command" +#~ msgstr "Naredba za snimanje prozora" + +#~ msgid "" +#~ "This keybinding changes whether a window is above or below other windows. " +#~ "If the window is covered by another one, it raises the window above all " +#~ "others, and if the window is already fully visible, it lowers it below " +#~ "all others. The format looks like \"<Control>a\" or \"<Shift>" +#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " +#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" +#~ "\". If you set the option to the special string \"disabled\", then there " +#~ "will be no keybinding for this action." +#~ msgstr "" +#~ "Ova kombinacija tipki stavlja prozor iznad ili ispod ostalih prozora. Ako " +#~ "je prozor pokriven drugim prozorom, podiže aktivni prozor iznad svih " +#~ "ostalih, a ako je prozor već iznad svih, stavlja ga ispod. Format izgleda " +#~ "kao \"<Control>a\" ili \"<Shift><Alt>F1\", te je " +#~ "prilično fleksibilan te dozvoljava mala ili velika slova te kratice poput " +#~ "\"<Ctl>\" i \"<Ctrl>\". Ako unesete posebnu riječ \"disabled" +#~ "\", neće biti kombinacije tipki za ovu akciju." + +#~ msgid "" +#~ "This keybinding lowers a window below other windows. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " +#~ "is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "Kombinacija tipki koja spušta prozor ispod svih ostalih prozora. Oblik " +#~ "zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za " +#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " +#~ "skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na " +#~ "specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " +#~ "kombinacija tipki za ovu aktivnost." + +#~ msgid "" +#~ "This keybinding moves a window against the north (top) side of the " +#~ "screen. The format looks like \"<Control>a\" or \"<Shift><" +#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, " +#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If " +#~ "you set the option to the special string \"disabled\", then there will be " +#~ "no keybinding for this action." +#~ msgstr "" +#~ "Ova kombinacija tipki pomiće prozor na sjevernu (gornju) stranu ekrana. " +#~ "Format izgleda kao \"<Control>a\" ili \"<Shift><Alt>" +#~ "F1\", te je prilično fleksibilan te dozvoljava mala ili velika slova te " +#~ "kratice poput \"<Ctl>\" i \"<Ctrl>\". Ako unesete posebnu " +#~ "riječ \"disabled\", neće biti kombinacije tipki za ovu akciju." -#: ../src/metacity.schemas.in.h:178 #, fuzzy -msgid "" -"This keybinding moves a window into the center of the screen. The format " -"looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -"parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"Ova kombinacija tipki pomiće prozor na zapadnu (lijevo) stranu ekrana. " -"Format izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\", " -"te je prilično fleksibilan te dozvoljava mala ili velika slova te kratice " -"poput \"<Ctl>\" i \"<Ctrl>\". Ako unesete posebnu riječ " -"\"disabled\", neće biti kombinacije tipki za ovu akciju." +#~ msgid "" +#~ "This keybinding moves a window into the center of the screen. The format " +#~ "looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " +#~ "parser is fairly liberal and allows lower or upper case, and also " +#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " +#~ "the option to the special string \"disabled\", then there will be no " +#~ "keybinding for this action." +#~ msgstr "" +#~ "Ova kombinacija tipki pomiće prozor na zapadnu (lijevo) stranu ekrana. " +#~ "Format izgleda kao \"<Control>a\" ili \"<Shift><Alt>" +#~ "F1\", te je prilično fleksibilan te dozvoljava mala ili velika slova te " +#~ "kratice poput \"<Ctl>\" i \"<Ctrl>\". Ako unesete posebnu " +#~ "riječ \"disabled\", neće biti kombinacije tipki za ovu akciju." -#: ../src/metacity.schemas.in.h:179 -msgid "" -"This keybinding moves a window into the east (right) side of the screen. The " -"format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"Ova kombinacija tipki pomiće prozor na istočnu (desnu) stranu ekrana.Format " -"izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\", te je " -"prilično fleksibilan te dozvoljava mala ili velika slova te kratice poput " -"\"<Ctl>\" i \"<Ctrl>\". Ako unesete posebnu riječ \"disabled\", " -"neće biti kombinacije tipki za ovu akciju." +#~ msgid "" +#~ "This keybinding moves a window into the east (right) side of the screen. " +#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>" +#~ "F1\". The parser is fairly liberal and allows lower or upper case, and " +#~ "also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " +#~ "set the option to the special string \"disabled\", then there will be no " +#~ "keybinding for this action." +#~ msgstr "" +#~ "Ova kombinacija tipki pomiće prozor na istočnu (desnu) stranu ekrana." +#~ "Format izgleda kao \"<Control>a\" ili \"<Shift><Alt>" +#~ "F1\", te je prilično fleksibilan te dozvoljava mala ili velika slova te " +#~ "kratice poput \"<Ctl>\" i \"<Ctrl>\". Ako unesete posebnu " +#~ "riječ \"disabled\", neće biti kombinacije tipki za ovu akciju." -#: ../src/metacity.schemas.in.h:180 -msgid "" -"This keybinding moves a window into the north-east (top right) corner of the " -"screen. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" -"Ova kombinacija tipki pomiće prozor na sjeveroistočnu (gore desno) stranu " -"ekrana. Format izgleda kao \"<Control>a\" ili \"<Shift><" -"Alt>F1\", te je prilično fleksibilan te dozvoljava mala ili velika slova " -"te kratice poput \"<Ctl>\" i \"<Ctrl>\". Ako unesete posebnu " -"riječ \"disabled\", neće biti kombinacije tipki za ovu akciju." +#~ msgid "" +#~ "This keybinding moves a window into the north-east (top right) corner of " +#~ "the screen. The format looks like \"<Control>a\" or \"<Shift>" +#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " +#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" +#~ "\". If you set the option to the special string \"disabled\", then there " +#~ "will be no keybinding for this action." +#~ msgstr "" +#~ "Ova kombinacija tipki pomiće prozor na sjeveroistočnu (gore desno) stranu " +#~ "ekrana. Format izgleda kao \"<Control>a\" ili \"<Shift><" +#~ "Alt>F1\", te je prilično fleksibilan te dozvoljava mala ili velika " +#~ "slova te kratice poput \"<Ctl>\" i \"<Ctrl>\". Ako unesete " +#~ "posebnu riječ \"disabled\", neće biti kombinacije tipki za ovu akciju." -#: ../src/metacity.schemas.in.h:181 -msgid "" -"This keybinding moves a window into the north-west (top left) corner of the " -"screen. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" -"Ova kombinacija tipki pomiće prozor na sjeverozapadnu (gore lijevo) stranu " -"ekrana. Format izgleda kao \"<Control>a\" ili \"<Shift><" -"Alt>F1\", te je prilično fleksibilan te dozvoljava mala ili velika slova " -"te kratice poput \"<Ctl>\" i \"<Ctrl>\". Ako unesete posebnu " -"riječ \"disabled\", neće biti kombinacije tipki za ovu akciju." +#~ msgid "" +#~ "This keybinding moves a window into the north-west (top left) corner of " +#~ "the screen. The format looks like \"<Control>a\" or \"<Shift>" +#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " +#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" +#~ "\". If you set the option to the special string \"disabled\", then there " +#~ "will be no keybinding for this action." +#~ msgstr "" +#~ "Ova kombinacija tipki pomiće prozor na sjeverozapadnu (gore lijevo) " +#~ "stranu ekrana. Format izgleda kao \"<Control>a\" ili \"<Shift>" +#~ "<Alt>F1\", te je prilično fleksibilan te dozvoljava mala ili velika " +#~ "slova te kratice poput \"<Ctl>\" i \"<Ctrl>\". Ako unesete " +#~ "posebnu riječ \"disabled\", neće biti kombinacije tipki za ovu akciju." -#: ../src/metacity.schemas.in.h:182 -msgid "" -"This keybinding moves a window into the south (bottom) side of the screen. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"Ova kombinacija tipki pomiće prozor na južnu (dolje) stranu ekrana. Format " -"izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\", te je " -"prilično fleksibilan te dozvoljava mala ili velika slova te kratice poput " -"\"<Ctl>\" i \"<Ctrl>\". Ako unesete posebnu riječ \"disabled\", " -"neće biti kombinacije tipki za ovu akciju." +#~ msgid "" +#~ "This keybinding moves a window into the south (bottom) side of the " +#~ "screen. The format looks like \"<Control>a\" or \"<Shift><" +#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, " +#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If " +#~ "you set the option to the special string \"disabled\", then there will be " +#~ "no keybinding for this action." +#~ msgstr "" +#~ "Ova kombinacija tipki pomiće prozor na južnu (dolje) stranu ekrana. " +#~ "Format izgleda kao \"<Control>a\" ili \"<Shift><Alt>" +#~ "F1\", te je prilično fleksibilan te dozvoljava mala ili velika slova te " +#~ "kratice poput \"<Ctl>\" i \"<Ctrl>\". Ako unesete posebnu " +#~ "riječ \"disabled\", neće biti kombinacije tipki za ovu akciju." -#: ../src/metacity.schemas.in.h:183 -msgid "" -"This keybinding moves a window into the south-east (bottom right) corner of " -"the screen. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" -"Ova kombinacija tipki pomiće prozor najugoistočnu (dolje desno) stranu " -"ekrana. Format izgleda kao \"<Control>a\" ili \"<Shift><" -"Alt>F1\", te je prilično fleksibilan te dozvoljava mala ili velika slova " -"te kratice poput \"<Ctl>\" i \"<Ctrl>\". Ako unesete posebnu " -"riječ \"disabled\", neće biti kombinacije tipki za ovu akciju." +#~ msgid "" +#~ "This keybinding moves a window into the south-east (bottom right) corner " +#~ "of the screen. The format looks like \"<Control>a\" or \"<" +#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " +#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" +#~ "Ctrl>\". If you set the option to the special string \"disabled\", " +#~ "then there will be no keybinding for this action." +#~ msgstr "" +#~ "Ova kombinacija tipki pomiće prozor najugoistočnu (dolje desno) stranu " +#~ "ekrana. Format izgleda kao \"<Control>a\" ili \"<Shift><" +#~ "Alt>F1\", te je prilično fleksibilan te dozvoljava mala ili velika " +#~ "slova te kratice poput \"<Ctl>\" i \"<Ctrl>\". Ako unesete " +#~ "posebnu riječ \"disabled\", neće biti kombinacije tipki za ovu akciju." -#: ../src/metacity.schemas.in.h:184 -msgid "" -"This keybinding moves a window into the south-west (bottom left) corner of " -"the screen. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" -"Ova kombinacija tipki pomiće prozor na jugozapadnu (dolje lijevo) stranu " -"ekrana. Format izgleda kao \"<Control>a\" ili \"<Shift><" -"Alt>F1\", te je prilično fleksibilan te dozvoljava mala ili velika slova " -"te kratice poput \"<Ctl>\" i \"<Ctrl>\". Ako unesete posebnu " -"riječ \"disabled\", neće biti kombinacije tipki za ovu akciju." +#~ msgid "" +#~ "This keybinding moves a window into the south-west (bottom left) corner " +#~ "of the screen. The format looks like \"<Control>a\" or \"<" +#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " +#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" +#~ "Ctrl>\". If you set the option to the special string \"disabled\", " +#~ "then there will be no keybinding for this action." +#~ msgstr "" +#~ "Ova kombinacija tipki pomiće prozor na jugozapadnu (dolje lijevo) stranu " +#~ "ekrana. Format izgleda kao \"<Control>a\" ili \"<Shift><" +#~ "Alt>F1\", te je prilično fleksibilan te dozvoljava mala ili velika " +#~ "slova te kratice poput \"<Ctl>\" i \"<Ctrl>\". Ako unesete " +#~ "posebnu riječ \"disabled\", neće biti kombinacije tipki za ovu akciju." -#: ../src/metacity.schemas.in.h:185 -msgid "" -"This keybinding moves a window into the west (left) side of the screen. The " -"format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"Ova kombinacija tipki pomiće prozor na zapadnu (lijevo) stranu ekrana. " -"Format izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\", " -"te je prilično fleksibilan te dozvoljava mala ili velika slova te kratice " -"poput \"<Ctl>\" i \"<Ctrl>\". Ako unesete posebnu riječ " -"\"disabled\", neće biti kombinacije tipki za ovu akciju." +#~ msgid "" +#~ "This keybinding moves a window into the west (left) side of the screen. " +#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>" +#~ "F1\". The parser is fairly liberal and allows lower or upper case, and " +#~ "also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " +#~ "set the option to the special string \"disabled\", then there will be no " +#~ "keybinding for this action." +#~ msgstr "" +#~ "Ova kombinacija tipki pomiće prozor na zapadnu (lijevo) stranu ekrana. " +#~ "Format izgleda kao \"<Control>a\" ili \"<Shift><Alt>" +#~ "F1\", te je prilično fleksibilan te dozvoljava mala ili velika slova te " +#~ "kratice poput \"<Ctl>\" i \"<Ctrl>\". Ako unesete posebnu " +#~ "riječ \"disabled\", neće biti kombinacije tipki za ovu akciju." + +#~ msgid "" +#~ "This keybinding raises the window above other windows. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " +#~ "is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "Kombinacija tipki koja podiže prozor iznad svih ostalih prozora. Oblik " +#~ "zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za " +#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, takođe i " +#~ "skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na " +#~ "specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " +#~ "kombinacija tipki za ovu aktivnost." + +#~ msgid "" +#~ "This keybinding resizes a window to fill available horizontal space. The " +#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " +#~ "The parser is fairly liberal and allows lower or upper case, and also " +#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " +#~ "the option to the special string \"disabled\", then there will be no " +#~ "keybinding for this action." +#~ msgstr "" +#~ "Kombinacija tipki koja mijenja veličinu prozora tako da popuni čitav " +#~ "vodoravni prostor. Oblik zapisa izgleda kao \"<Control>a\" ili " +#~ "\"<Shift><Alt>F1\". Program za obradu je dosta slobodan i dozvoljava " +#~ "velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". " +#~ "Ako postavite opciju na specijalni niz znakova \"disabled\", tada neće " +#~ "biti korištena niti jedna kombinacija tipki za ovu aktivnost." + +#~ msgid "" +#~ "This keybinding resizes a window to fill available vertical space. The " +#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " +#~ "The parser is fairly liberal and allows lower or upper case, and also " +#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " +#~ "the option to the special string \"disabled\", then there will be no " +#~ "keybinding for this action." +#~ msgstr "" +#~ "Kombinacija tipki koja mijenja veličinu prozora tako da popuni čitav " +#~ "okomiti prostor. Oblik zapisa izgleda kao \"<Control>a\" ili " +#~ "\"<Shift><Alt>F1\". Program za obradu je dosta slobodan i dozvoljava " +#~ "velika ili mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". " +#~ "Ako postavite opciju na specijalni niz znakova \"disabled\", tada neće " +#~ "biti korištena niti jedna kombinacija tipki za ovu aktivnost." -#: ../src/metacity.schemas.in.h:186 -msgid "" -"This keybinding raises the window above other windows. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"Kombinacija tipki koja podiže prozor iznad svih ostalih prozora. Oblik " -"zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". Program za obradu " -"je dosta slobodan i dozvoljava velika ili mala slova, takođe i skraćenice " -"poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na specijalni niz " -"znakova \"disabled\", tada neće biti korištena niti jedna kombinacija tipki " -"za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:187 -msgid "" -"This keybinding resizes a window to fill available horizontal space. The " -"format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"Kombinacija tipki koja mijenja veličinu prozora tako da popuni čitav " -"vodoravni prostor. Oblik zapisa izgleda kao \"<Control>a\" ili " -"\"<Shift><Alt>F1\". Program za obradu je dosta slobodan i dozvoljava velika " -"ili mala slova, takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako " -"postavite opciju na specijalni niz znakova \"disabled\", tada neće biti " -"korištena niti jedna kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:188 -msgid "" -"This keybinding resizes a window to fill available vertical space. The " -"format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"Kombinacija tipki koja mijenja veličinu prozora tako da popuni čitav okomiti " -"prostor. Oblik zapisa izgleda kao \"<Control>a\" ili \"<Shift><Alt>F1\". " -"Program za obradu je dosta slobodan i dozvoljava velika ili mala slova, " -"takođe i skraćenice poput \"<Ctl>\" i \"< Ctrl>\". Ako postavite opciju na " -"specijalni niz znakova \"disabled\", tada neće biti korištena niti jedna " -"kombinacija tipki za ovu aktivnost." - -#: ../src/metacity.schemas.in.h:189 #, fuzzy -msgid "" -"This option determines the effects of double-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, 'toggle_maximize' which will maximize/unmaximize the window, " -"'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which will " -"maximize/unmaximize the window in that direction only, 'minimize' which will " -"minimize the window, 'shade' which will roll the window up, 'menu' which " -"will display the window menu, 'lower' which will put the window behind all " -"the others, and 'none' which will not do anything." -msgstr "" -"Ova opciaj opsije efekte duplog klika na traku prozora. Mogućnosti su " -"'smotaj', što za posljedicu ima skupljanje prozora, 'maksimiziraj', što za " -"posljedicu ima razvlačenje prozora preko cijelog ekrana, 'minimiziraj', što " -"za posljedicu ima spuštanje prozora u traku i 'ništa', što neće učiniti " -"ništa." +#~ msgid "" +#~ "This option determines the effects of double-clicking on the title bar. " +#~ "Current valid options are 'toggle_shade', which will shade/unshade the " +#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " +#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " +#~ "will maximize/unmaximize the window in that direction only, 'minimize' " +#~ "which will minimize the window, 'shade' which will roll the window up, " +#~ "'menu' which will display the window menu, 'lower' which will put the " +#~ "window behind all the others, and 'none' which will not do anything." +#~ msgstr "" +#~ "Ova opciaj opsije efekte duplog klika na traku prozora. Mogućnosti su " +#~ "'smotaj', što za posljedicu ima skupljanje prozora, 'maksimiziraj', što " +#~ "za posljedicu ima razvlačenje prozora preko cijelog ekrana, " +#~ "'minimiziraj', što za posljedicu ima spuštanje prozora u traku i 'ništa', " +#~ "što neće učiniti ništa." -#: ../src/metacity.schemas.in.h:190 #, fuzzy -msgid "" -"This option determines the effects of middle-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, 'toggle_maximize' which will maximize/unmaximize the window, " -"'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which will " -"maximize/unmaximize the window in that direction only, 'minimize' which will " -"minimize the window, 'shade' which will roll the window up, 'menu' which " -"will display the window menu, 'lower' which will put the window behind all " -"the others, and 'none' which will not do anything." -msgstr "" -"Ova opciaj opsije efekte duplog klika na traku prozora. Mogućnosti su " -"'smotaj', što za posljedicu ima skupljanje prozora, 'maksimiziraj', što za " -"posljedicu ima razvlačenje prozora preko cijelog ekrana, 'minimiziraj', što " -"za posljedicu ima spuštanje prozora u traku i 'ništa', što neće učiniti " -"ništa." +#~ msgid "" +#~ "This option determines the effects of middle-clicking on the title bar. " +#~ "Current valid options are 'toggle_shade', which will shade/unshade the " +#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " +#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " +#~ "will maximize/unmaximize the window in that direction only, 'minimize' " +#~ "which will minimize the window, 'shade' which will roll the window up, " +#~ "'menu' which will display the window menu, 'lower' which will put the " +#~ "window behind all the others, and 'none' which will not do anything." +#~ msgstr "" +#~ "Ova opciaj opsije efekte duplog klika na traku prozora. Mogućnosti su " +#~ "'smotaj', što za posljedicu ima skupljanje prozora, 'maksimiziraj', što " +#~ "za posljedicu ima razvlačenje prozora preko cijelog ekrana, " +#~ "'minimiziraj', što za posljedicu ima spuštanje prozora u traku i 'ništa', " +#~ "što neće učiniti ništa." -#: ../src/metacity.schemas.in.h:191 #, fuzzy -msgid "" -"This option determines the effects of right-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, 'toggle_maximize' which will maximize/unmaximize the window, " -"'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which will " -"maximize/unmaximize the window in that direction only, 'minimize' which will " -"minimize the window, 'shade' which will roll the window up, 'menu' which " -"will display the window menu, 'lower' which will put the window behind all " -"the others, and 'none' which will not do anything." -msgstr "" -"Ova opciaj opsije efekte duplog klika na traku prozora. Mogućnosti su " -"'smotaj', što za posljedicu ima skupljanje prozora, 'maksimiziraj', što za " -"posljedicu ima razvlačenje prozora preko cijelog ekrana, 'minimiziraj', što " -"za posljedicu ima spuštanje prozora u traku i 'ništa', što neće učiniti " -"ništa." +#~ msgid "" +#~ "This option determines the effects of right-clicking on the title bar. " +#~ "Current valid options are 'toggle_shade', which will shade/unshade the " +#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " +#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " +#~ "will maximize/unmaximize the window in that direction only, 'minimize' " +#~ "which will minimize the window, 'shade' which will roll the window up, " +#~ "'menu' which will display the window menu, 'lower' which will put the " +#~ "window behind all the others, and 'none' which will not do anything." +#~ msgstr "" +#~ "Ova opciaj opsije efekte duplog klika na traku prozora. Mogućnosti su " +#~ "'smotaj', što za posljedicu ima skupljanje prozora, 'maksimiziraj', što " +#~ "za posljedicu ima razvlačenje prozora preko cijelog ekrana, " +#~ "'minimiziraj', što za posljedicu ima spuštanje prozora u traku i 'ništa', " +#~ "što neće učiniti ništa." -#: ../src/metacity.schemas.in.h:192 -msgid "" -"This option provides additional control over how newly created windows get " -"focus. It has two possible values; \"smart\" applies the user's normal focus " -"mode, and \"strict\" results in windows started from a terminal not being " -"given focus." -msgstr "" -"Ova opcija nudi dodatnu kontrolu nad fokusom za novokreirane prozore. Ima " -"dvije vrijednosti: \"pametna\", koja postavlja uobičajeni fokus i \"stroga" -"\", koja programima pokrenutima iz terminala ne daje fokus." +#~ msgid "" +#~ "This option provides additional control over how newly created windows " +#~ "get focus. It has two possible values; \"smart\" applies the user's " +#~ "normal focus mode, and \"strict\" results in windows started from a " +#~ "terminal not being given focus." +#~ msgstr "" +#~ "Ova opcija nudi dodatnu kontrolu nad fokusom za novokreirane prozore. Ima " +#~ "dvije vrijednosti: \"pametna\", koja postavlja uobičajeni fokus i \"stroga" +#~ "\", koja programima pokrenutima iz terminala ne daje fokus." -#: ../src/metacity.schemas.in.h:193 -msgid "Toggle always on top state" -msgstr "Uključi da je uvijek na vrhu" +#~ msgid "Toggle always on top state" +#~ msgstr "Uključi da je uvijek na vrhu" -#: ../src/metacity.schemas.in.h:194 -msgid "Toggle fullscreen mode" -msgstr "Postavi preko cijelog zaslona" +#~ msgid "" +#~ "Turns on a visual indication when an application or the system issues a " +#~ "'bell' or 'beep'; useful for the hard-of-hearing and for use in noisy " +#~ "environments." +#~ msgstr "" +#~ "Uključuje vizualnu obavijest kada program pozove 'bell' ili 'beep' " +#~ "signale; korisno za one sa slabim sluhom ili za uporabu u bučnom okružju." -#: ../src/metacity.schemas.in.h:195 -msgid "Toggle maximization state" -msgstr "Promijeni stanje maksimizacije" +#~ msgid "Unmaximize window" +#~ msgstr "Reduciraj veličinu prozora" -#: ../src/metacity.schemas.in.h:196 -msgid "Toggle shaded state" -msgstr "Promijeni stanje zasjenjenosti" +#~ msgid "Use standard system font in window titles" +#~ msgstr "Koristi standardni font sustava za naslov prozora" -#: ../src/metacity.schemas.in.h:197 -msgid "Toggle window on all workspaces" -msgstr "Uključi prozor na svim radnim površinama" +#~ msgid "Visual Bell Type" +#~ msgstr "Vrsta vizulnog zvonca" -#: ../src/metacity.schemas.in.h:198 -msgid "" -"Turns on a visual indication when an application or the system issues a " -"'bell' or 'beep'; useful for the hard-of-hearing and for use in noisy " -"environments." -msgstr "" -"Uključuje vizualnu obavijest kada program pozove 'bell' ili 'beep' signale; " -"korisno za one sa slabim sluhom ili za uporabu u bučnom okružju." +#~ msgid "Whether raising should be a side-effect of other user interactions" +#~ msgstr "" +#~ "Hoće li podizanje prozora biti posljedica drugih intervencija korisnika" -#: ../src/metacity.schemas.in.h:199 -msgid "Unmaximize window" -msgstr "Reduciraj veličinu prozora" +#~ msgid "Window focus mode" +#~ msgstr "Način fokusa prozora" -#: ../src/metacity.schemas.in.h:200 -msgid "Use standard system font in window titles" -msgstr "Koristi standardni font sustava za naslov prozora" +#~ msgid "Window title font" +#~ msgstr "Pismo naslova prozora" -#: ../src/metacity.schemas.in.h:201 -msgid "Visual Bell Type" -msgstr "Vrsta vizulnog zvonca" +#~ msgid "Close Window" +#~ msgstr "Zatvori prozor" -#: ../src/metacity.schemas.in.h:202 -msgid "Whether raising should be a side-effect of other user interactions" -msgstr "" -"Hoće li podizanje prozora biti posljedica drugih intervencija korisnika" +#~ msgid "Window Menu" +#~ msgstr "Izbornik Prozor" -#: ../src/metacity.schemas.in.h:203 -msgid "Window focus mode" -msgstr "Način fokusa prozora" +#~ msgid "Minimize Window" +#~ msgstr "Minimiziraj prozor" -#: ../src/metacity.schemas.in.h:204 -msgid "Window title font" -msgstr "Pismo naslova prozora" +#~ msgid "Maximize Window" +#~ msgstr "Maksimiziraj prozor" -#: ../src/ui/frames.c:1077 -msgid "Close Window" -msgstr "Zatvori prozor" +#~ msgid "Unmaximize Window" +#~ msgstr "Poništi uvećanje prozora" -#: ../src/ui/frames.c:1080 -msgid "Window Menu" -msgstr "Izbornik Prozor" - -#: ../src/ui/frames.c:1083 -msgid "Minimize Window" -msgstr "Minimiziraj prozor" - -#: ../src/ui/frames.c:1086 -msgid "Maximize Window" -msgstr "Maksimiziraj prozor" - -#: ../src/ui/frames.c:1089 -msgid "Unmaximize Window" -msgstr "Poništi uvećanje prozora" - -#: ../src/ui/frames.c:1092 -msgid "Roll Up Window" -msgstr "Namotaj prozor" - -#: ../src/ui/frames.c:1095 -msgid "Unroll Window" -msgstr "Odmotaj prozor" - -#: ../src/ui/frames.c:1098 -msgid "Keep Window On Top" -msgstr "Drži prozor na vrhu" - -#: ../src/ui/frames.c:1101 -msgid "Remove Window From Top" -msgstr "Ukloni prozor s vrha" - -#: ../src/ui/frames.c:1104 -msgid "Always On Visible Workspace" -msgstr "Uvijek na vidljivoj radnoj površini" - -#: ../src/ui/frames.c:1107 -msgid "Put Window On Only One Workspace" -msgstr "Postavi prozor na samo jednu radnu površinu" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:70 -msgid "Mi_nimize" -msgstr "Mi_nimiziraj" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:72 -msgid "Ma_ximize" -msgstr "_Maksimiziraj" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:74 -msgid "Unma_ximize" -msgstr "_Vrati sa maksimiziranog" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:76 -msgid "Roll _Up" -msgstr "Za_rolaj" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:78 -msgid "_Unroll" -msgstr "_Odrolaj" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:80 -msgid "_Move" -msgstr "Pom_akni" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:82 -msgid "_Resize" -msgstr "Promjena ve_ličine" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:84 -msgid "Move Titlebar On_screen" -msgstr "Premjesti traku naslova na _zaslon" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:87 ../src/ui/menu.c:89 -msgid "Always on _Top" -msgstr "_Uvijek na vrhu" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:91 -msgid "_Always on Visible Workspace" -msgstr "_Uvijek na vidljivom radnom prostoru" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:93 -msgid "_Only on This Workspace" -msgstr "Samo na _ovoj radnoj površini" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:95 -msgid "Move to Workspace _Left" -msgstr "Pomakni na lij_evu radnu površinu" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:97 -msgid "Move to Workspace R_ight" -msgstr "Pomakn_i na desnu radnu površinu" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:99 -msgid "Move to Workspace _Up" -msgstr "Pomakni na _gornju radnu površinu" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:101 -msgid "Move to Workspace _Down" -msgstr "Pomakni na _donju radnu površinu" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:105 -msgid "_Close" -msgstr "_Zatvori" - -#: ../src/ui/menu.c:203 -#, c-format -msgid "Workspace %d%n" -msgstr "" +#~ msgid "Roll Up Window" +#~ msgstr "Namotaj prozor" + +#~ msgid "Unroll Window" +#~ msgstr "Odmotaj prozor" + +#~ msgid "Keep Window On Top" +#~ msgstr "Drži prozor na vrhu" + +#~ msgid "Remove Window From Top" +#~ msgstr "Ukloni prozor s vrha" + +#~ msgid "Always On Visible Workspace" +#~ msgstr "Uvijek na vidljivoj radnoj površini" + +#~ msgid "Put Window On Only One Workspace" +#~ msgstr "Postavi prozor na samo jednu radnu površinu" + +#~ msgid "Mi_nimize" +#~ msgstr "Mi_nimiziraj" + +#~ msgid "Ma_ximize" +#~ msgstr "_Maksimiziraj" + +#~ msgid "Unma_ximize" +#~ msgstr "_Vrati sa maksimiziranog" + +#~ msgid "Roll _Up" +#~ msgstr "Za_rolaj" + +#~ msgid "_Unroll" +#~ msgstr "_Odrolaj" + +#~ msgid "_Move" +#~ msgstr "Pom_akni" + +#~ msgid "_Resize" +#~ msgstr "Promjena ve_ličine" + +#~ msgid "Move Titlebar On_screen" +#~ msgstr "Premjesti traku naslova na _zaslon" + +#~ msgid "Always on _Top" +#~ msgstr "_Uvijek na vrhu" + +#~ msgid "_Always on Visible Workspace" +#~ msgstr "_Uvijek na vidljivom radnom prostoru" + +#~ msgid "_Only on This Workspace" +#~ msgstr "Samo na _ovoj radnoj površini" + +#~ msgid "Move to Workspace _Up" +#~ msgstr "Pomakni na _gornju radnu površinu" + +#~ msgid "_Close" +#~ msgstr "_Zatvori" -#: ../src/ui/menu.c:213 #, fuzzy -msgid "Workspace 1_0" -msgstr "Pomakni na _gornju radnu površinu" +#~ msgid "Workspace 1_0" +#~ msgstr "Pomakni na _gornju radnu površinu" -#: ../src/ui/menu.c:215 -#, c-format -msgid "Workspace %s%d" -msgstr "" +#~ msgid "Move to Another _Workspace" +#~ msgstr "Pomakni na drugu _radnu površinu" -#: ../src/ui/menu.c:395 -msgid "Move to Another _Workspace" -msgstr "Pomakni na drugu _radnu površinu" +#~ msgid "Shift" +#~ msgstr "Shift" -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:105 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:111 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:117 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:123 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:129 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:135 -msgid "Hyper" -msgstr "Hiper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:141 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:147 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:153 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:159 -msgid "Mod5" -msgstr "Mod5" +#~ msgid "Ctrl" +#~ msgstr "Ctrl" + +#~ msgid "Alt" +#~ msgstr "Alt" + +#~ msgid "Meta" +#~ msgstr "Meta" + +#~ msgid "Super" +#~ msgstr "Super" -#: ../src/ui/metacity-dialog.c:90 -#, c-format -msgid "\"%s\" is not responding." -msgstr "\"%s\" ne odgovara." +#~ msgid "Hyper" +#~ msgstr "Hiper" -#: ../src/ui/metacity-dialog.c:97 -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "" -"Možete pričekati neko vrijeme da program nastavi s radom ili možete " -"prisiliti prekid rada programa." +#~ msgid "Mod2" +#~ msgstr "Mod2" -#: ../src/ui/metacity-dialog.c:107 -msgid "_Wait" -msgstr "_Čekaj" +#~ msgid "Mod3" +#~ msgstr "Mod3" -#: ../src/ui/metacity-dialog.c:109 -msgid "_Force Quit" -msgstr "_Prisili izlaženje" +#~ msgid "Mod4" +#~ msgstr "Mod4" -#: ../src/ui/metacity-dialog.c:206 -msgid "Title" -msgstr "Naslov" +#~ msgid "Mod5" +#~ msgstr "Mod5" -#: ../src/ui/metacity-dialog.c:218 -msgid "Class" -msgstr "Klasa" +#~ msgid "Title" +#~ msgstr "Naslov" -#: ../src/ui/metacity-dialog.c:244 -msgid "" -"These windows do not support \"save current setup\" and will have to be " -"restarted manually next time you log in." -msgstr "" -"Ovi prozori ne podržavaju mogućnost \"snimi trenutne postavke\" i morati " -"ćete ih ručno ponovno pokrenuti sljedeći put kada se prijavite.." +#~ msgid "Class" +#~ msgstr "Klasa" -#: ../src/ui/metacity-dialog.c:310 -#, c-format -msgid "" -"There was an error running \"%s\":\n" -"%s." -msgstr "" -"Dogodila se greška prilikom pokretanja „%s“:\n" -"%s." +#~ msgid "" +#~ "There was an error running \"%s\":\n" +#~ "%s." +#~ msgstr "" +#~ "Dogodila se greška prilikom pokretanja „%s“:\n" +#~ "%s." -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" +#~ msgid "%d x %d" +#~ msgstr "%d x %d" -#: ../src/ui/theme-parser.c:227 ../src/ui/theme-parser.c:245 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Linija %d karakter %d: %s" +#~ msgid "Line %d character %d: %s" +#~ msgstr "Linija %d karakter %d: %s" -#: ../src/ui/theme-parser.c:396 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "Svojstvo \"%s\" je ponovljeno dva puta u istom elementu <%s>" +#~ msgid "Attribute \"%s\" repeated twice on the same <%s> element" +#~ msgstr "Svojstvo \"%s\" je ponovljeno dva puta u istom elementu <%s>" -#: ../src/ui/theme-parser.c:414 ../src/ui/theme-parser.c:439 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "Svojstvo \"%s\" je neispravano u elementu <%s> u ovom kontekstu" +#~ msgid "Attribute \"%s\" is invalid on <%s> element in this context" +#~ msgstr "Svojstvo \"%s\" je neispravano u elementu <%s> u ovom kontekstu" -#: ../src/ui/theme-parser.c:500 -#, c-format -msgid "Integer %ld must be positive" -msgstr "Cijeli broj %ld mora biti pozitivan" +#~ msgid "Integer %ld must be positive" +#~ msgstr "Cijeli broj %ld mora biti pozitivan" -#: ../src/ui/theme-parser.c:508 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "Cijeli broj %ld je prevelik ,trenutno najveći je %d" +#~ msgid "Integer %ld is too large, current max is %d" +#~ msgstr "Cijeli broj %ld je prevelik ,trenutno najveći je %d" -#: ../src/ui/theme-parser.c:536 ../src/ui/theme-parser.c:652 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "Nije moguće analizirati \"%s\" kao broj sa pomičnim zarezom" +#~ msgid "Could not parse \"%s\" as a floating point number" +#~ msgstr "Nije moguće analizirati \"%s\" kao broj sa pomičnim zarezom" -#: ../src/ui/theme-parser.c:567 ../src/ui/theme-parser.c:595 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "Logičke vrijednosti moraju biti \"true\" ili \"false\", a ne \"%s\"" +#~ msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" +#~ msgstr "Logičke vrijednosti moraju biti \"true\" ili \"false\", a ne \"%s\"" -#: ../src/ui/theme-parser.c:622 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "Kut mora biti između 0.0 i 360.0, was %g\n" +#~ msgid "Angle must be between 0.0 and 360.0, was %g\n" +#~ msgstr "Kut mora biti između 0.0 i 360.0, was %g\n" -#: ../src/ui/theme-parser.c:685 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" -"Alfa postavka mora biti između 0.0 (nevidljivo) i 1.0 (potpuno neprozirno), " -"bila je %g\n" +#~ msgid "" +#~ "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" +#~ msgstr "" +#~ "Alfa postavka mora biti između 0.0 (nevidljivo) i 1.0 (potpuno " +#~ "neprozirno), bila je %g\n" -#: ../src/ui/theme-parser.c:750 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"Neispravna veličina naslova \"%s\" (mora biti jedna od xx-mala,x-mala,mala," -"srednja,velika,x-velika,xx-velika)\n" - -#: ../src/ui/theme-parser.c:795 ../src/ui/theme-parser.c:803 -#: ../src/ui/theme-parser.c:885 ../src/ui/theme-parser.c:982 -#: ../src/ui/theme-parser.c:1024 ../src/ui/theme-parser.c:1135 -#: ../src/ui/theme-parser.c:1185 ../src/ui/theme-parser.c:1193 -#: ../src/ui/theme-parser.c:3093 ../src/ui/theme-parser.c:3184 -#: ../src/ui/theme-parser.c:3191 ../src/ui/theme-parser.c:3198 -#, c-format -msgid "No \"%s\" attribute on <%s> element" -msgstr "Nije podešen atribut \"%s\" na <%s> elementu" +#~ msgid "" +#~ "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," +#~ "large,x-large,xx-large)\n" +#~ msgstr "" +#~ "Neispravna veličina naslova \"%s\" (mora biti jedna od xx-mala,x-mala," +#~ "mala,srednja,velika,x-velika,xx-velika)\n" -#: ../src/ui/theme-parser.c:919 ../src/ui/theme-parser.c:990 -#: ../src/ui/theme-parser.c:1032 ../src/ui/theme-parser.c:1143 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s> ime \"%s\" se već drugi put koristi" +#~ msgid "No \"%s\" attribute on <%s> element" +#~ msgstr "Nije podešen atribut \"%s\" na <%s> elementu" -#: ../src/ui/theme-parser.c:931 ../src/ui/theme-parser.c:1044 -#: ../src/ui/theme-parser.c:1155 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "<%s> izvor \"%s\" nije definiran" +#~ msgid "<%s> name \"%s\" used a second time" +#~ msgstr "<%s> ime \"%s\" se već drugi put koristi" -#: ../src/ui/theme-parser.c:1057 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "<%s> geometrija \"%s\" se nije definirala" +#~ msgid "<%s> parent \"%s\" has not been defined" +#~ msgstr "<%s> izvor \"%s\" nije definiran" -#: ../src/ui/theme-parser.c:1070 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "<%s> morate odrediti geometriju ili izvor koji ima geometriju" +#~ msgid "<%s> geometry \"%s\" has not been defined" +#~ msgstr "<%s> geometrija \"%s\" se nije definirala" -#: ../src/ui/theme-parser.c:1112 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "Morate odrediti pozadinu kako bi alfa vrijednost imala smisla." +#~ msgid "<%s> must specify either a geometry or a parent that has a geometry" +#~ msgstr "<%s> morate odrediti geometriju ili izvor koji ima geometriju" -#: ../src/ui/theme-parser.c:1203 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Nepoznat tip \"%s\" u elementu <%s>" +#~ msgid "You must specify a background for an alpha value to be meaningful" +#~ msgstr "Morate odrediti pozadinu kako bi alfa vrijednost imala smisla." -#: ../src/ui/theme-parser.c:1214 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "Nepoznat style_set \"%s\" u elementu <%s>" +#~ msgid "Unknown type \"%s\" on <%s> element" +#~ msgstr "Nepoznat tip \"%s\" u elementu <%s>" -#: ../src/ui/theme-parser.c:1222 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "Vrsti prozora \"%s\" je već dodijeljena grupa stilova" - -#: ../src/ui/theme-parser.c:1258 -msgid "Theme already has a fallback icon" -msgstr "Tema već ima pomoćnu ikonu" - -#: ../src/ui/theme-parser.c:1270 -msgid "Theme already has a fallback mini_icon" -msgstr "Tema već ima pomoćnu mini_ikonu" - -#: ../src/ui/theme-parser.c:1283 ../src/ui/theme-parser.c:1347 -#: ../src/ui/theme-parser.c:1636 ../src/ui/theme-parser.c:3285 -#: ../src/ui/theme-parser.c:3339 ../src/ui/theme-parser.c:3511 -#: ../src/ui/theme-parser.c:3727 ../src/ui/theme-parser.c:3765 -#: ../src/ui/theme-parser.c:3803 ../src/ui/theme-parser.c:3841 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "Element <%s> nije dozvoljen ispod <%s>" +#~ msgid "Unknown style_set \"%s\" on <%s> element" +#~ msgstr "Nepoznat style_set \"%s\" u elementu <%s>" -#: ../src/ui/theme-parser.c:1373 ../src/ui/theme-parser.c:1460 -#: ../src/ui/theme-parser.c:1530 -#, c-format -msgid "No \"name\" attribute on element <%s>" -msgstr "Bez \"ime\" atributa na elementu <%s>" +#~ msgid "Window type \"%s\" has already been assigned a style set" +#~ msgstr "Vrsti prozora \"%s\" je već dodijeljena grupa stilova" -#: ../src/ui/theme-parser.c:1380 ../src/ui/theme-parser.c:1467 -#, c-format -msgid "No \"value\" attribute on element <%s>" -msgstr "Bez \"vrijednost\" atributa na elementu <%s>" +#~ msgid "Theme already has a fallback icon" +#~ msgstr "Tema već ima pomoćnu ikonu" -#: ../src/ui/theme-parser.c:1411 ../src/ui/theme-parser.c:1425 -#: ../src/ui/theme-parser.c:1484 -msgid "" -"Cannot specify both button_width/button_height and aspect ratio for buttons" -msgstr "" -"Nije moguće odrediti istovremeno gumb_širine/gumb_visine i omjer slike za " -"gumbe" +#~ msgid "Theme already has a fallback mini_icon" +#~ msgstr "Tema već ima pomoćnu mini_ikonu" -#: ../src/ui/theme-parser.c:1434 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "Udaljenost \"%s\" je nepoznata" +#~ msgid "Element <%s> is not allowed below <%s>" +#~ msgstr "Element <%s> nije dozvoljen ispod <%s>" -#: ../src/ui/theme-parser.c:1493 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "Odnos \"%s\" je nepoznat" +#~ msgid "No \"name\" attribute on element <%s>" +#~ msgstr "Bez \"ime\" atributa na elementu <%s>" -#: ../src/ui/theme-parser.c:1537 -#, c-format -msgid "No \"top\" attribute on element <%s>" -msgstr "Bez \"vrh\" atributa na elementu <%s>" +#~ msgid "No \"value\" attribute on element <%s>" +#~ msgstr "Bez \"vrijednost\" atributa na elementu <%s>" -#: ../src/ui/theme-parser.c:1544 -#, c-format -msgid "No \"bottom\" attribute on element <%s>" -msgstr "Bez \"dno\" atributa na elementu <%s>" +#~ msgid "" +#~ "Cannot specify both button_width/button_height and aspect ratio for " +#~ "buttons" +#~ msgstr "" +#~ "Nije moguće odrediti istovremeno gumb_širine/gumb_visine i omjer slike za " +#~ "gumbe" -#: ../src/ui/theme-parser.c:1551 -#, c-format -msgid "No \"left\" attribute on element <%s>" -msgstr "Bez \"lijevo\" atributa na elementu <%s>" +#~ msgid "Distance \"%s\" is unknown" +#~ msgstr "Udaljenost \"%s\" je nepoznata" -#: ../src/ui/theme-parser.c:1558 -#, c-format -msgid "No \"right\" attribute on element <%s>" -msgstr "Bez \"desno\" atributa na elementu <%s>" +#~ msgid "Aspect ratio \"%s\" is unknown" +#~ msgstr "Odnos \"%s\" je nepoznat" -#: ../src/ui/theme-parser.c:1590 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "Rub „%s“ je nepoznat" +#~ msgid "No \"top\" attribute on element <%s>" +#~ msgstr "Bez \"vrh\" atributa na elementu <%s>" -#: ../src/ui/theme-parser.c:1736 ../src/ui/theme-parser.c:1850 -#: ../src/ui/theme-parser.c:1961 ../src/ui/theme-parser.c:2192 -#: ../src/ui/theme-parser.c:3023 -#, c-format -msgid "No \"color\" attribute on element <%s>" -msgstr "Bez \"boja\" atributa na elementu <%s>" +#~ msgid "No \"bottom\" attribute on element <%s>" +#~ msgstr "Bez \"dno\" atributa na elementu <%s>" -#: ../src/ui/theme-parser.c:1743 -#, c-format -msgid "No \"x1\" attribute on element <%s>" -msgstr "Bez \"x1\" atributa na elementu <%s>" +#~ msgid "No \"left\" attribute on element <%s>" +#~ msgstr "Bez \"lijevo\" atributa na elementu <%s>" -#: ../src/ui/theme-parser.c:1750 ../src/ui/theme-parser.c:2864 -#, c-format -msgid "No \"y1\" attribute on element <%s>" -msgstr "Bez \"y1\" atributa na elementu <%s>" +#~ msgid "No \"right\" attribute on element <%s>" +#~ msgstr "Bez \"desno\" atributa na elementu <%s>" -#: ../src/ui/theme-parser.c:1757 -#, c-format -msgid "No \"x2\" attribute on element <%s>" -msgstr "Bez \"x2\" atributa na elementu <%s>" +#~ msgid "Border \"%s\" is unknown" +#~ msgstr "Rub „%s“ je nepoznat" -#: ../src/ui/theme-parser.c:1764 ../src/ui/theme-parser.c:2871 -#, c-format -msgid "No \"y2\" attribute on element <%s>" -msgstr "Bez \"y2\" atributa na elementu <%s>" - -#: ../src/ui/theme-parser.c:1857 ../src/ui/theme-parser.c:1968 -#: ../src/ui/theme-parser.c:2117 ../src/ui/theme-parser.c:2199 -#: ../src/ui/theme-parser.c:2306 ../src/ui/theme-parser.c:2408 -#: ../src/ui/theme-parser.c:2630 ../src/ui/theme-parser.c:2758 -#: ../src/ui/theme-parser.c:2857 ../src/ui/theme-parser.c:2934 -#: ../src/ui/theme-parser.c:3030 -#, c-format -msgid "No \"x\" attribute on element <%s>" -msgstr "Bez \"x\" atributa na elementu <%s>" - -#: ../src/ui/theme-parser.c:1864 ../src/ui/theme-parser.c:1975 -#: ../src/ui/theme-parser.c:2124 ../src/ui/theme-parser.c:2206 -#: ../src/ui/theme-parser.c:2313 ../src/ui/theme-parser.c:2415 -#: ../src/ui/theme-parser.c:2637 ../src/ui/theme-parser.c:2765 -#: ../src/ui/theme-parser.c:2941 ../src/ui/theme-parser.c:3037 -#, c-format -msgid "No \"y\" attribute on element <%s>" -msgstr "Bez \"y\" atributa na elementu <%s>" - -#: ../src/ui/theme-parser.c:1871 ../src/ui/theme-parser.c:1982 -#: ../src/ui/theme-parser.c:2131 ../src/ui/theme-parser.c:2213 -#: ../src/ui/theme-parser.c:2320 ../src/ui/theme-parser.c:2422 -#: ../src/ui/theme-parser.c:2644 ../src/ui/theme-parser.c:2772 -#: ../src/ui/theme-parser.c:2948 -#, c-format -msgid "No \"width\" attribute on element <%s>" -msgstr "Bez \"širina\" atributa na elementu <%s>" - -#: ../src/ui/theme-parser.c:1878 ../src/ui/theme-parser.c:1989 -#: ../src/ui/theme-parser.c:2138 ../src/ui/theme-parser.c:2220 -#: ../src/ui/theme-parser.c:2327 ../src/ui/theme-parser.c:2429 -#: ../src/ui/theme-parser.c:2651 ../src/ui/theme-parser.c:2779 -#: ../src/ui/theme-parser.c:2955 -#, c-format -msgid "No \"height\" attribute on element <%s>" -msgstr "Bez \"visina\" atributa na elementu <%s>" +#~ msgid "No \"color\" attribute on element <%s>" +#~ msgstr "Bez \"boja\" atributa na elementu <%s>" -#: ../src/ui/theme-parser.c:1998 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "Nema \"start_angle\" ili \"from\" atributa na elementu <%s>" +#~ msgid "No \"x1\" attribute on element <%s>" +#~ msgstr "Bez \"x1\" atributa na elementu <%s>" -#: ../src/ui/theme-parser.c:2005 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "Nema \"extent_angle\" ili \"to\" atributa na elementu <%s>" +#~ msgid "No \"y1\" attribute on element <%s>" +#~ msgstr "Bez \"y1\" atributa na elementu <%s>" -#: ../src/ui/theme-parser.c:2014 -#, c-format -msgid "No \"start_angle\" attribute on element <%s>" -msgstr "Nema \"start_angle\" atributa na elementu <%s>" +#~ msgid "No \"x2\" attribute on element <%s>" +#~ msgstr "Bez \"x2\" atributa na elementu <%s>" -#: ../src/ui/theme-parser.c:2021 -#, c-format -msgid "No \"extent_angle\" attribute on element <%s>" -msgstr "Bez \"extent_ange\" atributa na elementu <%s>" +#~ msgid "No \"y2\" attribute on element <%s>" +#~ msgstr "Bez \"y2\" atributa na elementu <%s>" -#: ../src/ui/theme-parser.c:2227 -#, c-format -msgid "No \"alpha\" attribute on element <%s>" -msgstr "Bez \"alfa\" atributa na elementu <%s>" +#~ msgid "No \"x\" attribute on element <%s>" +#~ msgstr "Bez \"x\" atributa na elementu <%s>" -#: ../src/ui/theme-parser.c:2299 -#, c-format -msgid "No \"type\" attribute on element <%s>" -msgstr "Bez \"tip\" atributa na elementu <%s>" +#~ msgid "No \"y\" attribute on element <%s>" +#~ msgstr "Bez \"y\" atributa na elementu <%s>" -#: ../src/ui/theme-parser.c:2349 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "Nisam shvatio vrijednost \"%s\" za vrstu stupnjevanja" +#~ msgid "No \"width\" attribute on element <%s>" +#~ msgstr "Bez \"širina\" atributa na elementu <%s>" -#: ../src/ui/theme-parser.c:2436 -#, c-format -msgid "No \"filename\" attribute on element <%s>" -msgstr "Bez \"imedatoteke\" atributa na elementu <%s>" +#~ msgid "No \"height\" attribute on element <%s>" +#~ msgstr "Bez \"visina\" atributa na elementu <%s>" -#: ../src/ui/theme-parser.c:2461 ../src/ui/theme-parser.c:2980 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "Nisam shvatio vrstu popunjavanja \"%s\" za <%s> element" +#~ msgid "No \"start_angle\" or \"from\" attribute on element <%s>" +#~ msgstr "Nema \"start_angle\" ili \"from\" atributa na elementu <%s>" -#: ../src/ui/theme-parser.c:2609 ../src/ui/theme-parser.c:2744 -#: ../src/ui/theme-parser.c:2850 -#, c-format -msgid "No \"state\" attribute on element <%s>" -msgstr "Bez \"stanje\" atributa na elementu <%s>" +#~ msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" +#~ msgstr "Nema \"extent_angle\" ili \"to\" atributa na elementu <%s>" -#: ../src/ui/theme-parser.c:2616 ../src/ui/theme-parser.c:2751 -#, c-format -msgid "No \"shadow\" attribute on element <%s>" -msgstr "Bez \"sjena\" atributa na elementu <%s>" +#~ msgid "No \"start_angle\" attribute on element <%s>" +#~ msgstr "Nema \"start_angle\" atributa na elementu <%s>" -#: ../src/ui/theme-parser.c:2623 -#, c-format -msgid "No \"arrow\" attribute on element <%s>" -msgstr "Bez \"strelica\" atributa na elementu <%s>" +#~ msgid "No \"extent_angle\" attribute on element <%s>" +#~ msgstr "Bez \"extent_ange\" atributa na elementu <%s>" -#: ../src/ui/theme-parser.c:2676 ../src/ui/theme-parser.c:2800 -#: ../src/ui/theme-parser.c:2891 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "Nisam shvatio sjenu \"%s\" za <%s> element" +#~ msgid "No \"alpha\" attribute on element <%s>" +#~ msgstr "Bez \"alfa\" atributa na elementu <%s>" -#: ../src/ui/theme-parser.c:2686 ../src/ui/theme-parser.c:2810 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "Nisam shvatio sjenu \"%s\" za <%s> element" +#~ msgid "No \"type\" attribute on element <%s>" +#~ msgstr "Bez \"tip\" atributa na elementu <%s>" -#: ../src/ui/theme-parser.c:2696 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "Ne razumijmem strelicu \"%s\" za <%s> element" +#~ msgid "Did not understand value \"%s\" for type of gradient" +#~ msgstr "Nisam shvatio vrijednost \"%s\" za vrstu stupnjevanja" -#: ../src/ui/theme-parser.c:3120 ../src/ui/theme-parser.c:3237 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "Nije podešen <draw_ops> imena \"%s\"" +#~ msgid "No \"filename\" attribute on element <%s>" +#~ msgstr "Bez \"imedatoteke\" atributa na elementu <%s>" -#: ../src/ui/theme-parser.c:3132 ../src/ui/theme-parser.c:3249 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "uključivanje draw_ops \"%s\" ovdje bi kreiralo kružnu napomenu" +#~ msgid "Did not understand fill type \"%s\" for <%s> element" +#~ msgstr "Nisam shvatio vrstu popunjavanja \"%s\" za <%s> element" -#: ../src/ui/theme-parser.c:3314 -#, c-format -msgid "No \"value\" attribute on <%s> element" -msgstr "Bez \"vrijednost\" atributa na <%s> elementu" +#~ msgid "No \"state\" attribute on element <%s>" +#~ msgstr "Bez \"stanje\" atributa na elementu <%s>" -#: ../src/ui/theme-parser.c:3371 -#, c-format -msgid "No \"position\" attribute on <%s> element" -msgstr "Bez \"pozicija\" atributa na elementu <%s>" +#~ msgid "No \"shadow\" attribute on element <%s>" +#~ msgstr "Bez \"sjena\" atributa na elementu <%s>" -#: ../src/ui/theme-parser.c:3380 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Nepoznata pozicija \"%s\" za dio okvira" +#~ msgid "No \"arrow\" attribute on element <%s>" +#~ msgstr "Bez \"strelica\" atributa na elementu <%s>" -#: ../src/ui/theme-parser.c:3388 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "Stil okvira već ima dio na poziciji %s" +#~ msgid "Did not understand state \"%s\" for <%s> element" +#~ msgstr "Nisam shvatio sjenu \"%s\" za <%s> element" -#: ../src/ui/theme-parser.c:3405 ../src/ui/theme-parser.c:3496 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "Nije podešen <draw_ops>sa imenom \"%s\"" +#~ msgid "Did not understand shadow \"%s\" for <%s> element" +#~ msgstr "Nisam shvatio sjenu \"%s\" za <%s> element" -#: ../src/ui/theme-parser.c:3433 -#, c-format -msgid "No \"function\" attribute on <%s> element" -msgstr "Bez \"funkcija\" atributa na elementu <%s>" +#~ msgid "Did not understand arrow \"%s\" for <%s> element" +#~ msgstr "Ne razumijmem strelicu \"%s\" za <%s> element" -#: ../src/ui/theme-parser.c:3441 ../src/ui/theme-parser.c:3557 -#, c-format -msgid "No \"state\" attribute on <%s> element" -msgstr "Bez \"stanje\" atributa na <%s> elementu" +#~ msgid "No <draw_ops> called \"%s\" has been defined" +#~ msgstr "Nije podešen <draw_ops> imena \"%s\"" -#: ../src/ui/theme-parser.c:3450 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Nepoznata funkcija \"%s\" za gumb" +#~ msgid "Including draw_ops \"%s\" here would create a circular reference" +#~ msgstr "uključivanje draw_ops \"%s\" ovdje bi kreiralo kružnu napomenu" -#: ../src/ui/theme-parser.c:3459 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "Funkcija tipke \"%s\" ne postoji u ovoj verziji (%d, treba %d)" +#~ msgid "No \"value\" attribute on <%s> element" +#~ msgstr "Bez \"vrijednost\" atributa na <%s> elementu" -#: ../src/ui/theme-parser.c:3471 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Nepoznato stanje \"%s\" za gumb" +#~ msgid "No \"position\" attribute on <%s> element" +#~ msgstr "Bez \"pozicija\" atributa na elementu <%s>" -#: ../src/ui/theme-parser.c:3479 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "Stil okvira već ima dugme za funkciju %s stanja %s" +#~ msgid "Unknown position \"%s\" for frame piece" +#~ msgstr "Nepoznata pozicija \"%s\" za dio okvira" -#: ../src/ui/theme-parser.c:3549 -#, c-format -msgid "No \"focus\" attribute on <%s> element" -msgstr "Bez \"usredotočenje\" atributa na elementu <%s>" +#~ msgid "Frame style already has a piece at position %s" +#~ msgstr "Stil okvira već ima dio na poziciji %s" -#: ../src/ui/theme-parser.c:3565 -#, c-format -msgid "No \"style\" attribute on <%s> element" -msgstr "Bez \"stil\" atributa na <%s> elementu" +#~ msgid "No <draw_ops> with the name \"%s\" has been defined" +#~ msgstr "Nije podešen <draw_ops>sa imenom \"%s\"" -#: ../src/ui/theme-parser.c:3574 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "\"%s“ nije dozvoljena vrijednost za svojstvo focus" +#~ msgid "No \"function\" attribute on <%s> element" +#~ msgstr "Bez \"funkcija\" atributa na elementu <%s>" -#: ../src/ui/theme-parser.c:3583 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "\"%s\" nije dozvoljena vrijednost za svojstvo state" +#~ msgid "No \"state\" attribute on <%s> element" +#~ msgstr "Bez \"stanje\" atributa na <%s> elementu" -#: ../src/ui/theme-parser.c:3593 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "Stil nazvan \"%s\" nije bio određen" +#~ msgid "Unknown function \"%s\" for button" +#~ msgstr "Nepoznata funkcija \"%s\" za gumb" -#: ../src/ui/theme-parser.c:3604 -#, c-format -msgid "No \"resize\" attribute on <%s> element" -msgstr "Bez \"promjenaveličine\" atributa na elementu <%s>" +#~ msgid "Button function \"%s\" does not exist in this version (%d, need %d)" +#~ msgstr "Funkcija tipke \"%s\" ne postoji u ovoj verziji (%d, treba %d)" -#: ../src/ui/theme-parser.c:3614 ../src/ui/theme-parser.c:3637 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "\"%s\" nije dozvoljena vrijednost za svojstvo resize" +#~ msgid "Unknown state \"%s\" for button" +#~ msgstr "Nepoznato stanje \"%s\" za gumb" -#: ../src/ui/theme-parser.c:3648 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" -"Nikako ne treba imati „resize“ atribut u elementu <%s> za uvećana/zasjenčena " -"stanja" +#~ msgid "Frame style already has a button for function %s state %s" +#~ msgstr "Stil okvira već ima dugme za funkciju %s stanja %s" -#: ../src/ui/theme-parser.c:3662 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "Atribut <%s> elementa ne bi smio imati \"resize\" za maximized stanje" +#~ msgid "No \"focus\" attribute on <%s> element" +#~ msgstr "Bez \"usredotočenje\" atributa na elementu <%s>" -#: ../src/ui/theme-parser.c:3676 ../src/ui/theme-parser.c:3698 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "Stil je već odabran za stanje %s promjene veličine %s usredotočenja %s" +#~ msgid "No \"style\" attribute on <%s> element" +#~ msgstr "Bez \"stil\" atributa na <%s> elementu" -#: ../src/ui/theme-parser.c:3687 ../src/ui/theme-parser.c:3709 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "Stil je već odabran za stanje %s usredotočenja %s" +#~ msgid "\"%s\" is not a valid value for focus attribute" +#~ msgstr "\"%s“ nije dozvoljena vrijednost za svojstvo focus" -#: ../src/ui/theme-parser.c:3748 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Ne mogu postojati dva draw_ops-a za element <piece> (tema navodi svojstvo " -"draw_ops i <draw_ops> element ili navodi dva elementa)" +#~ msgid "\"%s\" is not a valid value for state attribute" +#~ msgstr "\"%s\" nije dozvoljena vrijednost za svojstvo state" -#: ../src/ui/theme-parser.c:3786 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Ne mogu postojati dva draw_ops-a za element <button> (tema navodi draw_ops " -"svojstvo i <draw_ops> element ili navodi dva elementa)" +#~ msgid "A style called \"%s\" has not been defined" +#~ msgstr "Stil nazvan \"%s\" nije bio određen" -#: ../src/ui/theme-parser.c:3824 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Ne mogu postojati dva draw_ops-a za element <menu_icon> (tema navodi " -"svojstvo draw_ops i <draw_ops> element ili navodi dva elementa)" +#~ msgid "No \"resize\" attribute on <%s> element" +#~ msgstr "Bez \"promjenaveličine\" atributa na elementu <%s>" -#: ../src/ui/theme-parser.c:3872 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "Najdalji element u temi mora biti <metacity_theme> a ne<%s>" +#~ msgid "\"%s\" is not a valid value for resize attribute" +#~ msgstr "\"%s\" nije dozvoljena vrijednost za svojstvo resize" -#: ../src/ui/theme-parser.c:3892 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "Element <%s> nije dozvoljen unutar imena/autora/datuma/opisa ." +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized/shaded " +#~ "states" +#~ msgstr "" +#~ "Nikako ne treba imati „resize“ atribut u elementu <%s> za uvećana/" +#~ "zasjenčena stanja" -#: ../src/ui/theme-parser.c:3897 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "Element <%s> nije dozvoljen unutar <constant> elementa" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized states" +#~ msgstr "" +#~ "Atribut <%s> elementa ne bi smio imati \"resize\" za maximized stanje" -#: ../src/ui/theme-parser.c:3909 -#, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "" -"Element <%s> nije dozvoljen unutar udaljenost/granica/omjer_slike elementa" +#~ msgid "Style has already been specified for state %s resize %s focus %s" +#~ msgstr "" +#~ "Stil je već odabran za stanje %s promjene veličine %s usredotočenja %s" -#: ../src/ui/theme-parser.c:3931 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "Element <%s> nije dozvoljen unutar operacije crtanja" +#~ msgid "Style has already been specified for state %s focus %s" +#~ msgstr "Stil je već odabran za stanje %s usredotočenja %s" -#: ../src/ui/theme-parser.c:3941 ../src/ui/theme-parser.c:3971 -#: ../src/ui/theme-parser.c:3976 ../src/ui/theme-parser.c:3981 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "Element <%s> nije dozvoljen unutar <%s> elementa" +#~ msgid "" +#~ "Can't have a two draw_ops for a <piece> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Ne mogu postojati dva draw_ops-a za element <piece> (tema navodi svojstvo " +#~ "draw_ops i <draw_ops> element ili navodi dva elementa)" -#: ../src/ui/theme-parser.c:4203 -msgid "No draw_ops provided for frame piece" -msgstr "Bez draw_ops datih komadu okvira" +#~ msgid "" +#~ "Can't have a two draw_ops for a <button> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Ne mogu postojati dva draw_ops-a za element <button> (tema navodi " +#~ "draw_ops svojstvo i <draw_ops> element ili navodi dva elementa)" -#: ../src/ui/theme-parser.c:4218 -msgid "No draw_ops provided for button" -msgstr "Bez draw_ops datih dugmetu" +#~ msgid "" +#~ "Can't have a two draw_ops for a <menu_icon> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Ne mogu postojati dva draw_ops-a za element <menu_icon> (tema navodi " +#~ "svojstvo draw_ops i <draw_ops> element ili navodi dva elementa)" -#: ../src/ui/theme-parser.c:4270 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "Tekst nije dozvoljen unutar elementa<%s>" +#~ msgid "Outermost element in theme must be <metacity_theme> not <%s>" +#~ msgstr "Najdalji element u temi mora biti <metacity_theme> a ne<%s>" -#: ../src/ui/theme-parser.c:4325 -msgid "<name> specified twice for this theme" -msgstr "<ime> naznačen dvaput za ovu temu" +#~ msgid "" +#~ "Element <%s> is not allowed inside a name/author/date/description element" +#~ msgstr "Element <%s> nije dozvoljen unutar imena/autora/datuma/opisa ." -#: ../src/ui/theme-parser.c:4336 -msgid "<author> specified twice for this theme" -msgstr "<autor> naznačen dvaput za ovu temu" +#~ msgid "Element <%s> is not allowed inside a <constant> element" +#~ msgstr "Element <%s> nije dozvoljen unutar <constant> elementa" -#: ../src/ui/theme-parser.c:4347 -msgid "<copyright> specified twice for this theme" -msgstr "<autorska prava> određena dvaput za ovu temu" +#~ msgid "" +#~ "Element <%s> is not allowed inside a distance/border/aspect_ratio element" +#~ msgstr "" +#~ "Element <%s> nije dozvoljen unutar udaljenost/granica/omjer_slike elementa" -#: ../src/ui/theme-parser.c:4358 -msgid "<date> specified twice for this theme" -msgstr "<datum> određen dvaput za ovu temu" +#~ msgid "Element <%s> is not allowed inside a draw operation element" +#~ msgstr "Element <%s> nije dozvoljen unutar operacije crtanja" -#: ../src/ui/theme-parser.c:4369 -msgid "<description> specified twice for this theme" -msgstr "<opis> naveden dvaput za ovu temu" +#~ msgid "Element <%s> is not allowed inside a <%s> element" +#~ msgstr "Element <%s> nije dozvoljen unutar <%s> elementa" -#: ../src/ui/theme-parser.c:4636 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Neuspjeh pri traženju ispravne datoteke za temu %s\n" +#~ msgid "No draw_ops provided for frame piece" +#~ msgstr "Bez draw_ops datih komadu okvira" -#: ../src/ui/theme-parser.c:4692 -#, c-format -msgid "Theme file %s did not contain a root <metacity_theme> element" -msgstr "Datoteka sa temom %s ne sadrži korjenski <metacity_theme> element" +#~ msgid "No draw_ops provided for button" +#~ msgstr "Bez draw_ops datih dugmetu" -#: ../src/ui/theme-viewer.c:75 -msgid "/_Windows" -msgstr "/_Prozori" +#~ msgid "No text is allowed inside element <%s>" +#~ msgstr "Tekst nije dozvoljen unutar elementa<%s>" -#: ../src/ui/theme-viewer.c:76 -msgid "/Windows/tearoff" -msgstr "/Windows/otcijepi" +#~ msgid "<name> specified twice for this theme" +#~ msgstr "<ime> naznačen dvaput za ovu temu" -#: ../src/ui/theme-viewer.c:77 -msgid "/Windows/_Dialog" -msgstr "/Prozori/_Dijalog" +#~ msgid "<author> specified twice for this theme" +#~ msgstr "<autor> naznačen dvaput za ovu temu" -#: ../src/ui/theme-viewer.c:78 -msgid "/Windows/_Modal dialog" -msgstr "/Prozori/_Modalni dijalog" +#~ msgid "<copyright> specified twice for this theme" +#~ msgstr "<autorska prava> određena dvaput za ovu temu" -#: ../src/ui/theme-viewer.c:79 -msgid "/Windows/_Utility" -msgstr "/Windows/_Alat" +#~ msgid "<date> specified twice for this theme" +#~ msgstr "<datum> određen dvaput za ovu temu" -#: ../src/ui/theme-viewer.c:80 -msgid "/Windows/_Splashscreen" -msgstr "/Windows/_Pozdravni zaslon" +#~ msgid "<description> specified twice for this theme" +#~ msgstr "<opis> naveden dvaput za ovu temu" -#: ../src/ui/theme-viewer.c:81 -msgid "/Windows/_Top dock" -msgstr "/Windows/_Gornje sidro" +#~ msgid "Failed to find a valid file for theme %s\n" +#~ msgstr "Neuspjeh pri traženju ispravne datoteke za temu %s\n" -#: ../src/ui/theme-viewer.c:82 -msgid "/Windows/_Bottom dock" -msgstr "/Prozori/D_onje sidro" +#~ msgid "Theme file %s did not contain a root <metacity_theme> element" +#~ msgstr "Datoteka sa temom %s ne sadrži korjenski <metacity_theme> element" -#: ../src/ui/theme-viewer.c:83 -msgid "/Windows/_Left dock" -msgstr "/Prozori/_Lijevo sidro" +#~ msgid "/Windows/tearoff" +#~ msgstr "/Windows/otcijepi" -#: ../src/ui/theme-viewer.c:84 -msgid "/Windows/_Right dock" -msgstr "/Prozori/_Desno sidro" +#~ msgid "/Windows/_Dialog" +#~ msgstr "/Prozori/_Dijalog" -#: ../src/ui/theme-viewer.c:85 -msgid "/Windows/_All docks" -msgstr "/Prozori/_Sva sidra" +#~ msgid "/Windows/_Modal dialog" +#~ msgstr "/Prozori/_Modalni dijalog" -#: ../src/ui/theme-viewer.c:86 -msgid "/Windows/Des_ktop" -msgstr "/Prozori/_Radna površina" +#~ msgid "/Windows/_Utility" +#~ msgstr "/Windows/_Alat" -#: ../src/ui/theme-viewer.c:135 -msgid "Open another one of these windows" -msgstr "Otvori neki drugi od ovih prozora" +#~ msgid "/Windows/_Splashscreen" +#~ msgstr "/Windows/_Pozdravni zaslon" -#: ../src/ui/theme-viewer.c:142 -msgid "This is a demo button with an 'open' icon" -msgstr "Ovo je demonstracijski gumb s sličicom 'otvori'" +#~ msgid "/Windows/_Top dock" +#~ msgstr "/Windows/_Gornje sidro" -#: ../src/ui/theme-viewer.c:149 -msgid "This is a demo button with a 'quit' icon" -msgstr "Ovo je demonstacijski gumb s sličicom 'izlaz'" +#~ msgid "/Windows/_Bottom dock" +#~ msgstr "/Prozori/D_onje sidro" -#: ../src/ui/theme-viewer.c:242 -msgid "This is a sample message in a sample dialog" -msgstr "Ovo je primjer poruke u primjeru dijaloga" +#~ msgid "/Windows/_Left dock" +#~ msgstr "/Prozori/_Lijevo sidro" -#: ../src/ui/theme-viewer.c:325 -#, c-format -msgid "Fake menu item %d\n" -msgstr "Lažna stavka izbornika %d\n" +#~ msgid "/Windows/_Right dock" +#~ msgstr "/Prozori/_Desno sidro" -#: ../src/ui/theme-viewer.c:359 -msgid "Border-only window" -msgstr "Prozor samo s okvirom" +#~ msgid "/Windows/_All docks" +#~ msgstr "/Prozori/_Sva sidra" -#: ../src/ui/theme-viewer.c:361 -msgid "Bar" -msgstr "Položeni stup." +#~ msgid "/Windows/Des_ktop" +#~ msgstr "/Prozori/_Radna površina" -#: ../src/ui/theme-viewer.c:378 -msgid "Normal Application Window" -msgstr "Običan prozor programa" +#~ msgid "Open another one of these windows" +#~ msgstr "Otvori neki drugi od ovih prozora" -#: ../src/ui/theme-viewer.c:382 -msgid "Dialog Box" -msgstr "Dijaloški okvir" +#~ msgid "This is a demo button with an 'open' icon" +#~ msgstr "Ovo je demonstracijski gumb s sličicom 'otvori'" -#: ../src/ui/theme-viewer.c:386 -msgid "Modal Dialog Box" -msgstr "Modalni dijaloški prozor" +#~ msgid "This is a demo button with a 'quit' icon" +#~ msgstr "Ovo je demonstacijski gumb s sličicom 'izlaz'" -#: ../src/ui/theme-viewer.c:390 -msgid "Utility Palette" -msgstr "Paleta alata" +#~ msgid "This is a sample message in a sample dialog" +#~ msgstr "Ovo je primjer poruke u primjeru dijaloga" -#: ../src/ui/theme-viewer.c:394 -msgid "Torn-off Menu" -msgstr "Isključi izbornik" +#~ msgid "Fake menu item %d\n" +#~ msgstr "Lažna stavka izbornika %d\n" -#: ../src/ui/theme-viewer.c:398 -msgid "Border" -msgstr "Rub" +#~ msgid "Border-only window" +#~ msgstr "Prozor samo s okvirom" -#: ../src/ui/theme-viewer.c:726 -#, c-format -msgid "Button layout test %d" -msgstr "Test izgleda gumba %d" +#~ msgid "Bar" +#~ msgstr "Položeni stup." -#: ../src/ui/theme-viewer.c:755 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g milisekundi za crtanje jednog okvira okna" +#~ msgid "Normal Application Window" +#~ msgstr "Običan prozor programa" -#: ../src/ui/theme-viewer.c:798 -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Uporaba: metacity-theme-viewer [NAZIV_TEME]\n" +#~ msgid "Dialog Box" +#~ msgstr "Dijaloški okvir" -#: ../src/ui/theme-viewer.c:805 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "Greška tijekom učitavanja teme: %s\n" +#~ msgid "Modal Dialog Box" +#~ msgstr "Modalni dijaloški prozor" -#: ../src/ui/theme-viewer.c:811 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "Tema \"%s\" je učitana za %g sekundi.\n" +#~ msgid "Utility Palette" +#~ msgstr "Paleta alata" -#: ../src/ui/theme-viewer.c:852 -msgid "Normal Title Font" -msgstr "Obično pismo naslova" +#~ msgid "Torn-off Menu" +#~ msgstr "Isključi izbornik" -#: ../src/ui/theme-viewer.c:858 -msgid "Small Title Font" -msgstr "Malo pismo naslova" +#~ msgid "Border" +#~ msgstr "Rub" -#: ../src/ui/theme-viewer.c:864 -msgid "Large Title Font" -msgstr "Veliko pismo naslova" +#~ msgid "Button layout test %d" +#~ msgstr "Test izgleda gumba %d" -#: ../src/ui/theme-viewer.c:869 -msgid "Button Layouts" -msgstr "Izgled gumba" +#~ msgid "%g milliseconds to draw one window frame" +#~ msgstr "%g milisekundi za crtanje jednog okvira okna" -#: ../src/ui/theme-viewer.c:874 -msgid "Benchmark" -msgstr "Mjerilo" +#~ msgid "Usage: metacity-theme-viewer [THEMENAME]\n" +#~ msgstr "Uporaba: metacity-theme-viewer [NAZIV_TEME]\n" -#: ../src/ui/theme-viewer.c:921 -msgid "Window Title Goes Here" -msgstr "Ovdje ide naziv prozora" +#~ msgid "Error loading theme: %s\n" +#~ msgstr "Greška tijekom učitavanja teme: %s\n" -#: ../src/ui/theme-viewer.c:1025 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"Na korisničkoj strani sam nacrtao %d okvira za %g sekundi (%g milisekundi po " -"okviru) i %g sekundi ukupnog vremena uključujući resurse poslužitelja X-a (%" -"g milisekundi po okviru)\n" +#~ msgid "Loaded theme \"%s\" in %g seconds\n" +#~ msgstr "Tema \"%s\" je učitana za %g sekundi.\n" -#: ../src/ui/theme-viewer.c:1244 -msgid "position expression test returned TRUE but set error" -msgstr "" -"Ispitivanje mjesta izraza je rezultiralo izrazom \"TRUE\", ali je " -"postavljena greška" +#~ msgid "Normal Title Font" +#~ msgstr "Obično pismo naslova" -#: ../src/ui/theme-viewer.c:1246 -msgid "position expression test returned FALSE but didn't set error" -msgstr "" -"Ispitivanje mjesta izraza je rezultiralo izrazom \"FALSE\", ali nije " -"postavljena greška" +#~ msgid "Small Title Font" +#~ msgstr "Malo pismo naslova" -#: ../src/ui/theme-viewer.c:1250 -msgid "Error was expected but none given" -msgstr "Očekivana je greška, ali nije niti jedna prijavljena" +#~ msgid "Large Title Font" +#~ msgstr "Veliko pismo naslova" -#: ../src/ui/theme-viewer.c:1252 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "Očekivana je greška %d, ali je dobivena %d" +#~ msgid "Button Layouts" +#~ msgstr "Izgled gumba" -#: ../src/ui/theme-viewer.c:1258 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "Nije očekivana greška, ali je prijavljena: %s" +#~ msgid "Benchmark" +#~ msgstr "Mjerilo" -#: ../src/ui/theme-viewer.c:1262 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "vrijednost za x je bila %d, a očekivana je %d" +#~ msgid "Window Title Goes Here" +#~ msgstr "Ovdje ide naziv prozora" -#: ../src/ui/theme-viewer.c:1265 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "vrijednost za y je bila %d, a očekivana je %d" +#~ msgid "" +#~ "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and " +#~ "%g seconds wall clock time including X server resources (%g milliseconds " +#~ "per frame)\n" +#~ msgstr "" +#~ "Na korisničkoj strani sam nacrtao %d okvira za %g sekundi (%g milisekundi " +#~ "po okviru) i %g sekundi ukupnog vremena uključujući resurse poslužitelja " +#~ "X-a (%g milisekundi po okviru)\n" -#: ../src/ui/theme-viewer.c:1330 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "%d koordinatni izrazi parsirani u %g sekundi (%g sekundi u prosjeku)\n" +#~ msgid "position expression test returned TRUE but set error" +#~ msgstr "" +#~ "Ispitivanje mjesta izraza je rezultiralo izrazom \"TRUE\", ali je " +#~ "postavljena greška" -#: ../src/ui/theme.c:256 -msgid "top" -msgstr "na vrh" +#~ msgid "position expression test returned FALSE but didn't set error" +#~ msgstr "" +#~ "Ispitivanje mjesta izraza je rezultiralo izrazom \"FALSE\", ali nije " +#~ "postavljena greška" -#: ../src/ui/theme.c:258 -msgid "bottom" -msgstr "na dno" +#~ msgid "Error was expected but none given" +#~ msgstr "Očekivana je greška, ali nije niti jedna prijavljena" -#: ../src/ui/theme.c:260 -msgid "left" -msgstr "lijevo" +#~ msgid "Error %d was expected but %d given" +#~ msgstr "Očekivana je greška %d, ali je dobivena %d" -#: ../src/ui/theme.c:262 -msgid "right" -msgstr "desno" +#~ msgid "Error not expected but one was returned: %s" +#~ msgstr "Nije očekivana greška, ali je prijavljena: %s" -#: ../src/ui/theme.c:289 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "geometrija okvira ne navodi „%s“ dimenziju" +#~ msgid "x value was %d, %d was expected" +#~ msgstr "vrijednost za x je bila %d, a očekivana je %d" -#: ../src/ui/theme.c:308 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "geometrija okvira ne navodi „%s“ dimenziju za rub „%s“" +#~ msgid "y value was %d, %d was expected" +#~ msgstr "vrijednost za y je bila %d, a očekivana je %d" -#: ../src/ui/theme.c:345 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "Odnos gumb %g nije razuman" +#~ msgid "" +#~ "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" +#~ msgstr "" +#~ "%d koordinatni izrazi parsirani u %g sekundi (%g sekundi u prosjeku)\n" -#: ../src/ui/theme.c:357 -msgid "Frame geometry does not specify size of buttons" -msgstr "Geometrija oblika nije odredila veličinu dugmadi." +#~ msgid "top" +#~ msgstr "na vrh" -#: ../src/ui/theme.c:1022 -msgid "Gradients should have at least two colors" -msgstr "Stupnjevanje mora imati barem dvije boje" +#~ msgid "bottom" +#~ msgstr "na dno" -#: ../src/ui/theme.c:1148 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"GTK specifikacija boje mora imati stanje u zagradi,naprimjer gtk:fg[NORMAL] " -"gdje je NORMAL stanje;nije moguće analizirati \"%s\"" +#~ msgid "left" +#~ msgstr "lijevo" -#: ../src/ui/theme.c:1162 -#, c-format -msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"GTK specifikacija boje mora imati zatvorenu zagradu poslije stanja," -"naprimjer gtk:fg[NORMAL] gdje je NORMAL stanje;nije moguće analizirati \"%s" -"\"" +#~ msgid "right" +#~ msgstr "desno" -#: ../src/ui/theme.c:1173 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "Nisam shvatio stanje \"%s\" u odredbama boja" +#~ msgid "frame geometry does not specify \"%s\" dimension" +#~ msgstr "geometrija okvira ne navodi „%s“ dimenziju" -#: ../src/ui/theme.c:1186 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "Ne razumijem komponentu boje \"%s\" u specifikaciji boja" +#~ msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" +#~ msgstr "geometrija okvira ne navodi „%s“ dimenziju za rub „%s“" -#: ../src/ui/theme.c:1216 -#, c-format -msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" -msgstr "" -"Format miješanja „blend/bg_color/fg_color/alpha“, „%s“ se ne uklapa u " -"traženi format zapisa" +#~ msgid "Button aspect ratio %g is not reasonable" +#~ msgstr "Odnos gumb %g nije razuman" -#: ../src/ui/theme.c:1227 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "Nije moguće analizirati alfa vrijednost \"%s\" u nijansnoj boji" +#~ msgid "Frame geometry does not specify size of buttons" +#~ msgstr "Geometrija oblika nije odredila veličinu dugmadi." -#: ../src/ui/theme.c:1237 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "Alfa vrijednost \"%s\" u nijansiranoj boji nije između 0.0 i 1.0" +#~ msgid "Gradients should have at least two colors" +#~ msgstr "Stupnjevanje mora imati barem dvije boje" -#: ../src/ui/theme.c:1284 -#, c-format -msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "" -"Format osjenčenja je \"shade/base_color/factor\", \"%s\" ne odgovara formatu" +#~ msgid "" +#~ "GTK color specification must have the state in brackets, e.g. gtk:" +#~ "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "GTK specifikacija boje mora imati stanje u zagradi,naprimjer gtk:" +#~ "fg[NORMAL] gdje je NORMAL stanje;nije moguće analizirati \"%s\"" -#: ../src/ui/theme.c:1295 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "Nije moguće analizirati faktor sjenčanja \"%s\" u sjenčanim bojama" +#~ msgid "" +#~ "GTK color specification must have a close bracket after the state, e.g. " +#~ "gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "GTK specifikacija boje mora imati zatvorenu zagradu poslije stanja," +#~ "naprimjer gtk:fg[NORMAL] gdje je NORMAL stanje;nije moguće analizirati " +#~ "\"%s\"" -#: ../src/ui/theme.c:1305 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "Faktor sjenčanja \"%s\" u zasjenjenoj boji je negativan" +#~ msgid "Did not understand state \"%s\" in color specification" +#~ msgstr "Nisam shvatio stanje \"%s\" u odredbama boja" -#: ../src/ui/theme.c:1334 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Nije moguće analizirati boju \"%s\"" +#~ msgid "Did not understand color component \"%s\" in color specification" +#~ msgstr "Ne razumijem komponentu boje \"%s\" u specifikaciji boja" -#: ../src/ui/theme.c:1584 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "Izraz koordinacije sadrži karakter '%s' koji nije dozvoljen" +#~ msgid "" +#~ "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit " +#~ "the format" +#~ msgstr "" +#~ "Format miješanja „blend/bg_color/fg_color/alpha“, „%s“ se ne uklapa u " +#~ "traženi format zapisa" -#: ../src/ui/theme.c:1611 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "" -"Izraz koordinacije sadrži broj sa pokretnom točkom '%s' koji nije mogao biti " -"analiziran" +#~ msgid "Could not parse alpha value \"%s\" in blended color" +#~ msgstr "Nije moguće analizirati alfa vrijednost \"%s\" u nijansnoj boji" -#: ../src/ui/theme.c:1625 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "" -"Izraz koordinacije sadrži cijeli broj '%s' koji neje mogao biti analiziran" +#~ msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" +#~ msgstr "Alfa vrijednost \"%s\" u nijansiranoj boji nije između 0.0 i 1.0" -#: ../src/ui/theme.c:1747 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "" -"Izraz koordinacije sadrži nepoznati operator na početku ovog teksta \"%s\"" +#~ msgid "" +#~ "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the " +#~ "format" +#~ msgstr "" +#~ "Format osjenčenja je \"shade/base_color/factor\", \"%s\" ne odgovara " +#~ "formatu" -#: ../src/ui/theme.c:1804 -msgid "Coordinate expression was empty or not understood" -msgstr "Izraz koordinacije je bio prazan ili nije shvatio" +#~ msgid "Could not parse shade factor \"%s\" in shaded color" +#~ msgstr "Nije moguće analizirati faktor sjenčanja \"%s\" u sjenčanim bojama" -#: ../src/ui/theme.c:1915 ../src/ui/theme.c:1925 ../src/ui/theme.c:1959 -msgid "Coordinate expression results in division by zero" -msgstr "Izraz koordinata je rezultat podjele sa nulom" +#~ msgid "Shade factor \"%s\" in shaded color is negative" +#~ msgstr "Faktor sjenčanja \"%s\" u zasjenjenoj boji je negativan" -#: ../src/ui/theme.c:1967 -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "" -"Izraz koordinacije pokušava upotrijebiti mod operator na broju sa pomičnim " -"zarezom" +#~ msgid "Could not parse color \"%s\"" +#~ msgstr "Nije moguće analizirati boju \"%s\"" -#: ../src/ui/theme.c:2023 -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "Izraz koordinacije ima operator \"%s\" gdje se očekivao operand" +#~ msgid "Coordinate expression contains character '%s' which is not allowed" +#~ msgstr "Izraz koordinacije sadrži karakter '%s' koji nije dozvoljen" -#: ../src/ui/theme.c:2032 -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "Izraz koordinacije je imao operand a očekivao se operator" +#~ msgid "" +#~ "Coordinate expression contains floating point number '%s' which could not " +#~ "be parsed" +#~ msgstr "" +#~ "Izraz koordinacije sadrži broj sa pokretnom točkom '%s' koji nije mogao " +#~ "biti analiziran" -#: ../src/ui/theme.c:2040 -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "Izraz koordinacije je završio sa operatorom umjesto operanda" +#~ msgid "" +#~ "Coordinate expression contains integer '%s' which could not be parsed" +#~ msgstr "" +#~ "Izraz koordinacije sadrži cijeli broj '%s' koji neje mogao biti analiziran" -#: ../src/ui/theme.c:2050 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" -"Izraz koordinacije ima operator \"%c\" koji prati operator \"%c\" ali bez " -"operacija između" +#~ msgid "" +#~ "Coordinate expression contained unknown operator at the start of this " +#~ "text: \"%s\"" +#~ msgstr "" +#~ "Izraz koordinacije sadrži nepoznati operator na početku ovog teksta \"%s\"" -#: ../src/ui/theme.c:2197 ../src/ui/theme.c:2238 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "Izraz koordinacije je imao nepoznatu varijablu ili konstantu \"%s\"" +#~ msgid "Coordinate expression was empty or not understood" +#~ msgstr "Izraz koordinacije je bio prazan ili nije shvatio" -#: ../src/ui/theme.c:2292 -msgid "Coordinate expression parser overflowed its buffer." -msgstr "Kod pregledavanja koordinata došlo je do prekoračenja spremnika" +#~ msgid "Coordinate expression results in division by zero" +#~ msgstr "Izraz koordinata je rezultat podjele sa nulom" -#: ../src/ui/theme.c:2321 -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "" -"Izraz koordinacije je morao zatvoriti zagrade sa ne otvorenim zagradama." +#~ msgid "" +#~ "Coordinate expression tries to use mod operator on a floating-point number" +#~ msgstr "" +#~ "Izraz koordinacije pokušava upotrijebiti mod operator na broju sa " +#~ "pomičnim zarezom" -#: ../src/ui/theme.c:2385 -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "Izraz koordinacije je imao otvorene zagrade sa ne zatvorenim zagradama" +#~ msgid "" +#~ "Coordinate expression has an operator \"%s\" where an operand was expected" +#~ msgstr "Izraz koordinacije ima operator \"%s\" gdje se očekivao operand" -#: ../src/ui/theme.c:2396 -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "Izraz koordinacije izgleda ne sadrži operacije ili operande." +#~ msgid "Coordinate expression had an operand where an operator was expected" +#~ msgstr "Izraz koordinacije je imao operand a očekivao se operator" -#: ../src/ui/theme.c:2598 ../src/ui/theme.c:2618 ../src/ui/theme.c:2638 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "" +#~ msgid "Coordinate expression ended with an operator instead of an operand" +#~ msgstr "Izraz koordinacije je završio sa operatorom umjesto operanda" -#: ../src/ui/theme.c:4157 -#, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"svejedno\"/> mora biti " -"određeno za format ovog okvira" +#~ msgid "" +#~ "Coordinate expression has operator \"%c\" following operator \"%c\" with " +#~ "no operand in between" +#~ msgstr "" +#~ "Izraz koordinacije ima operator \"%c\" koji prati operator \"%c\" ali bez " +#~ "operacija između" -#: ../src/ui/theme.c:4633 ../src/ui/theme.c:4658 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" -"Nedostaje <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"svejedno\"/>" +#~ msgid "Coordinate expression had unknown variable or constant \"%s\"" +#~ msgstr "Izraz koordinacije je imao nepoznatu varijablu ili konstantu \"%s\"" -#: ../src/ui/theme.c:4702 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Nije uspjelo učitavanje teme \"%s\": %s\n" +#~ msgid "Coordinate expression parser overflowed its buffer." +#~ msgstr "Kod pregledavanja koordinata došlo je do prekoračenja spremnika" -#: ../src/ui/theme.c:4828 ../src/ui/theme.c:4835 ../src/ui/theme.c:4842 -#: ../src/ui/theme.c:4849 ../src/ui/theme.c:4856 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "Nije podešen <%s> za temu \"%s\"" +#~ msgid "" +#~ "Coordinate expression had a close parenthesis with no open parenthesis" +#~ msgstr "" +#~ "Izraz koordinacije je morao zatvoriti zagrade sa ne otvorenim zagradama." -#: ../src/ui/theme.c:4864 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" -"Nije odabrana vrsta okvira za prozor tipa \"%s\" u temi \"%s\", dodajte " -"<window type=\"%s\" style_set=\"svejedno\"/> element" +#~ msgid "" +#~ "Coordinate expression had an open parenthesis with no close parenthesis" +#~ msgstr "" +#~ "Izraz koordinacije je imao otvorene zagrade sa ne zatvorenim zagradama" -#: ../src/ui/theme.c:5231 ../src/ui/theme.c:5293 ../src/ui/theme.c:5356 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" -"Korisnički definirane konstante moraju početi velikim slovom; \"%s\" ne " -"počinje" +#~ msgid "Coordinate expression doesn't seem to have any operators or operands" +#~ msgstr "Izraz koordinacije izgleda ne sadrži operacije ili operande." -#: ../src/ui/theme.c:5239 ../src/ui/theme.c:5301 ../src/ui/theme.c:5364 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "Konstanta \"%s\" je već definirana" +#~ msgid "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " +#~ "specified for this frame style" +#~ msgstr "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"svejedno\"/> mora biti " +#~ "određeno za format ovog okvira" -#: ../src/tools/metacity-message.c:150 -#, c-format -msgid "Usage: %s\n" -msgstr "Uporaba: %s\n" +#~ msgid "" +#~ "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/" +#~ ">" +#~ msgstr "" +#~ "Nedostaje <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"svejedno" +#~ "\"/>" + +#~ msgid "Failed to load theme \"%s\": %s\n" +#~ msgstr "Nije uspjelo učitavanje teme \"%s\": %s\n" + +#~ msgid "No <%s> set for theme \"%s\"" +#~ msgstr "Nije podešen <%s> za temu \"%s\"" + +#~ msgid "" +#~ "No frame style set for window type \"%s\" in theme \"%s\", add a <window " +#~ "type=\"%s\" style_set=\"whatever\"/> element" +#~ msgstr "" +#~ "Nije odabrana vrsta okvira za prozor tipa \"%s\" u temi \"%s\", dodajte " +#~ "<window type=\"%s\" style_set=\"svejedno\"/> element" + +#~ msgid "" +#~ "User-defined constants must begin with a capital letter; \"%s\" does not" +#~ msgstr "" +#~ "Korisnički definirane konstante moraju početi velikim slovom; \"%s\" ne " +#~ "počinje" + +#~ msgid "Constant \"%s\" has already been defined" +#~ msgstr "Konstanta \"%s\" je već definirana" + +#~ msgid "Usage: %s\n" +#~ msgstr "Uporaba: %s\n" #~ msgid "" #~ "%d stored in GConf key %s is not a reasonable cursor_size; must be in the " diff --git a/po/hu.po b/po/hu.po index 396fcc0c0..647b55799 100644 --- a/po/hu.po +++ b/po/hu.po @@ -1,1889 +1,778 @@ -# Hungarian translation of muffin -# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. -# This file is distributed under the same license as the muffin package. +# Hungarian translation for mutter. +# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Free Software Foundation, Inc. +# This file is distributed under the same license as the mutter package. # # Andras Timar <timar at gnome dot hu>, 2002, 2003. # Gabor Sari <saga at externet dot hu>, 2003. # Laszlo Dvornik <dvornik at gnome dot hu>, 2004. -# Gabor Kelemen <kelemeng at gnome dot hu>, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012. +# Gabor Kelemen <kelemeng at gnome dot hu>, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013. +# Balázs Úr <ur.balazs at fsf dot hu>, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020. msgid "" msgstr "" -"Project-Id-Version: muffin master\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-03-16 16:42+0100\n" -"PO-Revision-Date: 2012-03-16 16:43+0100\n" -"Last-Translator: Gabor Kelemen <kelemeng at gnome dot hu>\n" +"Project-Id-Version: mutter master\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2020-02-23 17:41+0000\n" +"PO-Revision-Date: 2020-02-25 07:30+0100\n" +"Last-Translator: Balázs Úr <ur.balazs at fsf dot hu>\n" "Language-Team: Hungarian <gnome-hu-list at gnome dot org>\n" -"Language: \n" +"Language: hu\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: KBabel 1.11.4\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 19.04.3\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ../src/50-muffin-windows.xml.in.h:1 -msgid "View split on left" -msgstr "Bal oldali felosztás megjelenítése" - -#: ../src/50-muffin-windows.xml.in.h:2 -msgid "View split on right" -msgstr "Jobb oldali felosztás megjelenítése" - -#: ../src/50-muffin-windows.xml.in.h:3 -msgid "Windows" -msgstr "Ablakok" - -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format -msgid "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." -msgstr "" -"Már fut egy másik kompozitáláskezelő a(z) %i képernyőn a(z) „%s” " -"megjelenítőn." - -#: ../src/core/bell.c:307 -msgid "Bell event" -msgstr "Csengetés esemény" - -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Ismeretlen ablakinformáció-kérés: %d" - -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> nem válaszol." - -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "Az alkalmazás nem válaszol." - -#: ../src/core/delete.c:119 -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "" -"Várhat egy kicsit a folytatódására, vagy kikényszerítheti az alkalmazás " -"teljes kilépését." - -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "Vá_rakozás" - -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "_Erőltetett kilépés" - -#: ../src/core/display.c:387 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "Hiányzik a kompozit ablakkezeléshez szükséges %s kiterjesztés" - -#: ../src/core/display.c:453 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Nem sikerült megnyitni a(z) „%s” X Window rendszer képernyőt\n" - -#: ../src/core/keybindings.c:852 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "" -"Valamely másik program már használja a(z) %s billentyűt %x módosítókkal " -"összekötve\n" - -#: ../src/core/main.c:206 -msgid "Disable connection to session manager" -msgstr "A munkamenet-kezelőhöz való csatlakozás tiltása" - -#: ../src/core/main.c:212 -msgid "Replace the running window manager" -msgstr "A futó ablakkezelő helyettesítése" - -#: ../src/core/main.c:218 -msgid "Specify session management ID" -msgstr "A munkamenet-kezelő azonosítójának megadása" - -#: ../src/core/main.c:223 -msgid "X Display to use" -msgstr "A használandó X megjelenítő" - -#: ../src/core/main.c:229 -msgid "Initialize session from savefile" -msgstr "A munkamenet előkészítése a mentési fájlból" - -#: ../src/core/main.c:235 -msgid "Make X calls synchronous" -msgstr "Az X-hívások szinkronná tétele" - -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Témakönyvtár beolvasása sikertelen: %s\n" - -#: ../src/core/main.c:520 -#, c-format -msgid "Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "" -"Nem található téma! Bizonyosodjon meg róla hogy a(z) %s létezik és " -"tartalmazza a szokásos témákat.\n" - -#: ../src/core/muffin.c:40 -#, c-format -msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., és mások\n" -"Ez egy szabad szoftver; lásd a forrást a másolás feltételeiről.\n" -"NINCS garancia; még az ELADHATÓSÁGRA vagy EGY ADOTT CÉLRA VALÓ ALKALMASSÁGRA " -"vonatkozólag sem.\n" - -#: ../src/core/muffin.c:54 -msgid "Print version" -msgstr "Verzió kinyomtatása" - -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "Kompozitáló bővítmények vesszőkkel elválasztott listája" - -#: ../src/core/prefs.c:1077 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"A hibás alkalmazások hibáinak megkerülése nincs engedélyezve. Néhány " -"alkalmazás lehet, hogy nem fog helyesen működni.\n" - -#: ../src/core/prefs.c:1152 -#, c-format -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "" -"Nem sikerült feldolgozni a(z) „%s” betűkészlet leírását a(z) „%s” GSettings " -"kulcsból\n" - -#: ../src/core/prefs.c:1218 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"A konfigurációs adatbázisban talált „%s” érvénytelen érték az egérgomb " -"módosítóhoz\n" - -#: ../src/core/prefs.c:1739 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "" -"A konfigurációs adatbázisban talált „%s” nem érvényes érték a következő " -"billentyűkombinációhoz: „%s”\n" - -#: ../src/core/prefs.c:1836 -#, c-format -msgid "Workspace %d" -msgstr "%d. munkaterület" - -#: ../src/core/screen.c:730 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "A(z) %d képernyő a(z) „%s” megjelenítőn érvénytelen\n" - -#: ../src/core/screen.c:746 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"A(z) %d képernyő a(z) „%s” megjelenítőn már rendelkezik egy ablakkezelővel; " -"próbálja a --replace opcióval helyettesíteni a jelenlegi ablakkezelőt.\n" - -#: ../src/core/screen.c:773 -#, c-format -msgid "Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "" -"Nem sikerült beolvasni az ablakkezelő kiválasztását a(z) %d képernyőn a(z) " -"„%s” megjelenítőn\n" - -#: ../src/core/screen.c:828 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "A(z) %d képernyőnek a(z) „%s” megjelenítőn már van ablakkezelője\n" - -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "Nem sikerült elengedni a(z) %d képernyőt a(z) „%s” kijelzőn\n" - -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Nem lehet létrehozni a(z) „%s” könyvtárat: %s\n" - -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "Nem sikerült a(z) „%s” munkamenet fájlt írásra megnyitni: %s\n" - -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Hiba történt a(z) „%s” munkamenet fájl írása közben: %s\n" - -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Hiba történt a(z) „%s” munkamenet fájl lezárása közben: %s\n" - -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Nem sikerült feldolgozni a mentett munkamenet fájlt: %s\n" - -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "A <muffin_session> attribútum megjelent, de már van munkamenet-azonosító" - -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Ismeretlen %s attribútum a(z) <%s> elemen" - -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "beágyazott <window> tag" - -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "Ismeretlen elem: %s" - -#: ../src/core/session.c:1809 -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" -"Az alábbi ablakok nem támogatják az "aktuális beállítások " -"mentését", emiatt ezeket a legközelebbi bejelentkezéskor manuálisan " -"újra kell indítania." - -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Nem sikerült megnyitni a hibakeresési naplót: %s\n" - -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Nem sikerült megnyitni az fdopen()-nel a(z) „%s” naplófájlt: %s\n" - -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "%s naplófájl megnyitva\n" - -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "A Muffin ablakkezelőt a részletes mód támogatása nélkül fordították\n" - -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "Ablakkezelő: " - -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "Hiba az ablakkezelőben: " - -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "Figyelmeztetés az ablakkezelőtől: " - -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "Hibaüzenet az ablakkezelőtől: " - -#. first time through -#: ../src/core/window.c:7269 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"%s ablak az ICCCM specifikációval ellentétben a SM_CLIENT_ID-t magára " -"állította be, a WM_CLIENT_LEADER helyett.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7932 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size " -"%d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"A(z) %s ablak egy MWM javaslatot állít be, ami szerint nem méretezhető át, " -"de mégis %d x %d minimális és %d x %d maximális értéket ad meg, amelynek így " -"nincs értelme.\n" - -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "Az alkalmazás hibás _NET_WM_PID-értéket állított be: %lu\n" - -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (ezen: %s)" - -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "" -"Érvénytelen WM_TRANSIENT_FOR ablak (0x%lx) került megadásra a következőhöz: " -"%s.\n" - -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "A WM_TRANSIENT_FOR ablak (0x%lx) ciklust hozna létre a következőhöz: %s.\n" - -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"A 0x%lx ablak %s tulajdonsággal rendelkezik\n" -"ennek %s típusúnak és %d formátumúnak kellett volna lennie, de\n" -"jelenleg %s típusú és %d formátumú a %d n_items.\n" -"Ez valószínűleg az alkalmazás hibája, nem pedig az ablakkezelőé.\n" -"Az ablak címe=„%s” osztálya=„%s” neve=„%s”\n" - -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "A(z) %s tulajdonság a 0x%lx ablakon érvénytelen UTF-8 adatot tartalmazott\n" - -#: ../src/core/xprops.c:494 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"A(z) %s tulajdonság a 0x%lx ablakon érvénytelen UTF-8 adatot tartalmazott a " -"lista %d. elemében\n" - -#: ../src/muffin.desktop.in.h:1 ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 -msgid "Attach modal dialogs" -msgstr "Kizárólagos párbeszédablakok csatolása" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 -msgid "Cancel tab popup" -msgstr "Tab felugró kikapcsolása" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"Megadja, hogy a rejtett ablakok (minimalizált ablakok és a más " -"munkaterületeken lévő ablakok) életben maradjanak-e." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 -msgid "" -"Determines whether the use of popup and highlight frame should be disabled " -"for window cycling." -msgstr "" -"Megadja, hogy a felugró ablak és a kiemelő keret letiltandó-e az ablakok " -"közti lépkedéskor." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -msgid "" -"Determines whether workspace switching should happen for windows on all " -"monitors or only for windows on the primary monitor." -msgstr "" -"A munkaterület-váltás minden monitor ablakaihoz, vagy csak az elsődleges " -"monitor ablakaihoz történjen meg." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 -msgid "" -"Determines whether workspaces are managed dynamically or whether there's a " -"static number of workspaces (determined by the num-workspaces key in org." -"gnome.desktop.wm.preferences)." -msgstr "A munkaterületek dinamikusan vannak-e kezelve, vagy a számuk rögzített (ezt a num-workspaces kulcs adja meg az org.cinnamon.desktop.wm.preferences fájlban)." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 -msgid "Draggable border width" -msgstr "Húzható szegély szélessége" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 -msgid "Enable edge tiling when dropping windows on screen edges" -msgstr "Szélek csempézésének engedélyezése ablakok képernyőszélekre ejtésekor" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 -msgid "" -"If enabled, dropping windows on vertical screen edges maximizes them " -"vertically and resizes them horizontally to cover half of the available " -"area. Dropping windows on the top screen edge maximizes them completely." -msgstr "" -"Ha engedélyezett, akkor a függőleges képernyőélekre ejtett ablakok " -"függőlegesen maximalizálva lesznek, vízszintesen pedig az elérhető terület " -"felét fogják elfoglalni. Az ablakok felső képernyőszélre ejtése teljesen " -"maximalizálja azokat." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 -msgid "Live Hidden Windows" -msgstr "Élő rejtett ablakok" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 -msgid "Modifier to use for extended window management operations" -msgstr "A kiterjesztett ablakkezelési műveletekhez használandó módosító" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 -msgid "No tab popup" -msgstr "Nincs tab felugró" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 -msgid "Select window from tab popup" -msgstr "Ablakok kiválasztása tab billentyűre felugró ablakból" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 -msgid "" -"The amount of total draggable borders. If the theme's visible borders are " -"not enough, invisible borders will be added to meet this value." -msgstr "" -"A húzható szegélyek teljes mennyisége. Ha a téma látható szegélyei nem " -"elegendők, akkor láthatatlan szegélyek kerülnek hozzáadásra ezen érték " -"eléréséhez." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 -msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." -msgstr "" -"Ez a kulcs indítja az „átfedést”, amely egy kombinációs ablakáttekintés és " -"alkalmazásindító rendszer. Az alapértelmezés a „Windows” billentyű PC " -"hardver esetén. Ezt vagy az alapértelmezetten, vagy üresen kell hagyni." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 -msgid "" -"When true, instead of having independent titlebars, modal dialogs appear " -"attached to the titlebar of the parent window and are moved together with " -"the parent window." -msgstr "" -"Ha igazra van állítva, akkor a kizárólagos ablakok nem önálló címsorral, " -"hanem a szülőablak címsorához csatolva jelennek meg, és a szülőablakkal " -"együtt kerülnek mozgatásra." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:17 -msgid "Workspaces are managed dynamically" -msgstr "Munkaterületek dinamikus kezelése" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:18 -msgid "Workspaces only on primary" -msgstr "Munkaterületek csak az elsődlegese" - -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "Használat: %s\n" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "Mi_nimalizálás" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "Ma_ximalizálás" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "_Eredeti méret" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "_Felgördítés" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "_Legördítés" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "Át_helyezés" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "Át_méretezés" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "_Címsor mozgatása a képernyőn" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "Mindig _felül" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "Mindig a látható m_unkaterületen" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "_Csak ezen a munkaterületen" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "Áthelyezés a bal ol_dali munkaterületre" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "Áthelyezés a j_obb oldali munkaterületre" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "Áthelyezés a fel_ső munkaterületre" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "Áthelyezés az _alsó munkaterületre" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "_Bezárás" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "%d%n. munkaterület" - -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "1_0. munkaterület" - -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "%s%d. munkaterület" - -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "Áthelyezés mási_k munkaterületre" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" - -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" - -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "fent" - -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "lent" - -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "bal" - -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "jobb" - -#: ../src/ui/theme.c:286 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "a keretgeometria nem határoz meg „%s” dimenziót" - -#: ../src/ui/theme.c:305 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "a keretgeometria nem határoz meg „%s” dimenziót „%s” szegélynek" - -#: ../src/ui/theme.c:342 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "%g gomb méretaránya nem fogadható el" - -#: ../src/ui/theme.c:354 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "A keretgeometria nem határozza meg a gombok méretét" - -#: ../src/ui/theme.c:1067 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "A színátmenetnek legalább két színűnek kell lennie" - -#: ../src/ui/theme.c:1219 -#, c-format -msgid "" -"GTK custom color specification must have color name and fallback in " -"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" -msgstr "" -"Az egyéni GTK színmeghatározásnál kötelező zárójelbe tenni a szín nevét és a " -"tartalékot, például gtk:custom(foo,bar); nem sikerült értelmezni a " -"következőt: „%s”" - -#: ../src/ui/theme.c:1235 -#, c-format -msgid "" -"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" -"_ are valid" -msgstr "" -"Érvénytelen karakter („%c”) a gtk:custom color_name paraméterében, csak az A-" -"Za-z0-9-_ érvényes" - -#: ../src/ui/theme.c:1249 -#, c-format -msgid "" -"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " -"fit the format" -msgstr "" -"A Gtk:custom formátuma: „gtk:custom(színnév,tartalék)”, „%s” nem felel meg " -"ennek" - -#: ../src/ui/theme.c:1294 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"GTK szín meghatározásnál az állapotnak szögletes zárójelben kell lennie, pl." -"gtk:fg[NORMAL] ahol NORMAL az állapot; nem lehetett feldolgozni a " -"következőt: „%s”" - -#: ../src/ui/theme.c:1308 -#, c-format -msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"A GTK színmeghatározásnál kötelező záró szögletes zárójelet tenni az állapot " -"után, például gtk:fg[NORMAL], ahol NORMAL az állapot; nem sikerült " -"értelmezni a következőt: „%s”" - -#: ../src/ui/theme.c:1319 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "Nem sikerült a(z) „%s” állapotot értelmezni a szín meghatározásban" - -#: ../src/ui/theme.c:1332 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "Nem sikerült értelmezni „%s” színösszetevőt a színmeghatározásban" - -#: ../src/ui/theme.c:1361 -#, c-format -msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" -msgstr "" -"A keverés formátuma: „blend/bg_color/fg_color/alpha”, „%s” nem felel meg " -"ennek" - -#: ../src/ui/theme.c:1372 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "Nem sikerült értelmezni a(z) „%s” alfa értéket a kevert színben" - -#: ../src/ui/theme.c:1382 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "A(z) „%s” alfa érték a kevert színben nem 0.0 és 1.0 között van" - -#: ../src/ui/theme.c:1429 -#, c-format -msgid "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "Az árnyék formátuma: „shade/base_color/factor”, „%s” nem felel meg ennek" - -#: ../src/ui/theme.c:1440 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "Nem sikerült a(z) „%s” árnyéktényezőt feldolgozni az árnyékolt színben" - -#: ../src/ui/theme.c:1450 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "„%s” árnyéktényező az árnyékolt színben negatív" - -#: ../src/ui/theme.c:1479 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Nem sikerült feldolgozni a(z) „%s” színt" - -#: ../src/ui/theme.c:1790 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "A koordinátakifejezés „%s” karaktert tartalmaz, ami nem megengedett" - -#: ../src/ui/theme.c:1817 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "" -"A koordinátakifejezés „%s” lebegőpontos számot tartalmaz, amit nem sikerült " -"feldolgozni" - -#: ../src/ui/theme.c:1831 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "" -"A koordinátakifejezés „%s” egész számot tartalmaz, amit nem sikerült " -"feldolgozni" - -#: ../src/ui/theme.c:1953 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "" -"A koordinátakifejezés ismeretlen operátort tartalmaz ennek a szövegnek az " -"elején: „%s”" - -#: ../src/ui/theme.c:2010 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "A koordinátakifejezés üres vagy értelmezhetetlen volt" - -#: ../src/ui/theme.c:2121 ../src/ui/theme.c:2131 ../src/ui/theme.c:2165 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "A koordinátakifejezés nullával való osztást okozott" - -#: ../src/ui/theme.c:2173 -#, c-format -msgid "Coordinate expression tries to use mod operator on a floating-point number" -msgstr "A koordinátakifejezés mod operátort próbált használni lebegőpontos számon" - -#: ../src/ui/theme.c:2229 -#, c-format -msgid "Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "A koordinátakifejezésben egy operandus helyén „%s” operátor volt" - -#: ../src/ui/theme.c:2238 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "A koordinátakifejezésben a várt operátor helyett operandus szerepelt" - -#: ../src/ui/theme.c:2246 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "A koordinátakifejezés operátorral végződött, nem operandussal" - -#: ../src/ui/theme.c:2256 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" -"A koordinátakifejezésben „%c” operátort „%c” operátor követi úgy, hogy nincs " -"köztük operandus" - -#: ../src/ui/theme.c:2407 ../src/ui/theme.c:2452 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "A koordinátakifejezésben „%s” változó vagy állandó ismeretlen volt" - -#: ../src/ui/theme.c:2506 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "A koordinátakifejezés-elemző túlcsordította a pufferét." - -#: ../src/ui/theme.c:2535 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "A koordinátakifejezésben záró zárójel szerepelt kezdő nélkül" - -#: ../src/ui/theme.c:2599 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "A koordinátakifejezésben kezdő zárójel szerepelt záró nélkül" - -#: ../src/ui/theme.c:2610 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "A koordinátakifejezésben úgy tűnik nincsenek sem operátorok, sem operandusok" - -#: ../src/ui/theme.c:2822 ../src/ui/theme.c:2842 ../src/ui/theme.c:2862 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "A téma által tartalmazott kifejezés hibát okozott: %s\n" - -#: ../src/ui/theme.c:4533 -#, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" -"Ehhez a keretstílushoz meg kell határozni a következő elemet: <button " -"function=\"%s\" state=\"%s\" draw_ops=\"bármi\"/>" - -#: ../src/ui/theme.c:5066 ../src/ui/theme.c:5091 -#, c-format -msgid "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "Hiányzó <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"bármi\"/> elem" - -#: ../src/ui/theme.c:5139 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Hiba a(z) „%s” téma betöltése közben: %s\n" - -#: ../src/ui/theme.c:5275 ../src/ui/theme.c:5282 ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 ../src/ui/theme.c:5303 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "Nincs <%s> beállítva a(z) „%s” témához" - -#: ../src/ui/theme.c:5311 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" -"Nincs keretstílus beállítva a(z) „%s” ablaktípushoz a(z) „%s” témában, adjon " -"hozzá egy <window type=\"%s\" style_set=\"bármi\"/> elemet" - -#: ../src/ui/theme.c:5709 ../src/ui/theme.c:5771 ../src/ui/theme.c:5834 -#, c-format -msgid "User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" -"A felhasználó által meghatározott konstansoknak nagybetűvel kell kezdődniük, " -"a(z) „%s” nem ilyen" - -#: ../src/ui/theme.c:5717 ../src/ui/theme.c:5779 ../src/ui/theme.c:5842 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "A(z) „%s” konstans már definiálva van" - -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. -#. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "Nincs „%s” attribútuma a(z) <%s> elemnek" - -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "%d. sor %d. karakter: %s" - -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "„%s” attribútum kétszer lett megismételve ugyanazon a(z) <%s> elemen" - -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "„%s” attribútum <%s> elemen érvénytelen ebben a szövegkörnyezetben" - -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "„%s” nem értelmezhető egész számként" - -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "Nem lehetett „%s” zárókaraktereket értelmezni a(z) „%s” karakterláncban" - -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "%ld egész számnak pozitívnak kell lennie" - -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "%ld egész szám túl nagy, a jelenlegi maximum %d" - -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "„%s” nem dolgozható fel lebegőpontos számként" - -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "A logikai értékek „true” vagy „false” kell legyenek, nem pedig „%s”" - -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "Szögnek 0.0 és 360.0 között kell lennie, %g volt\n" - -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" -"Az alfának 0.0 (átlátszó) és 1.0 (teljesen átlátszatlan) között kell lennie, " -"%g volt\n" - -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -" „%s” érvénytelen címméret (lehetséges értékek: xx-small,x-small,small," -"medium,large,x-large,xx-large)\n" - -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s> „%s” név másodszor lett használva" - -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "<%s> „%s” szülő nincs meghatározva" - -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "<%s> „%s” geometria nincs meghatározva" - -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "" -"<%s> vagy meg kell határozni a geometriát vagy szükség van egy szülőre " -"aminek van geometriája" - -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "Meg kell adnia egy hátteret, hogy az alfa értéknek értelme legyen" - -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "„%s” típus ismeretlen a(z) <%s> elemen" - -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "„%s” ismeretlen style_set a(z) <%s> elemen" - -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "„%s” ablak típushoz már hozzá van rendelve egy stílus beállítás" - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "<%s> elem nem engedélyezett <%s> alatt" - -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" -msgstr "" -"Nem lehet egyszerre megadni a gombok „button_width” vagy „button_height” és " -"az „aspect_ratio” paraméterét" - -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "„%s” távolság ismeretlen" - -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "„%s” méretarány ismeretlen" - -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "„%s” határ ismeretlen" - -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "A(z) <%s> elemnek nincs „start_angle” vagy „from” attribútuma" - -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "A(z) <%s> elemnek nincs „extent_angle” vagy „to” attribútuma" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Navigáció" -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "Nem sikerült „%s” értéket értelmezni színátmenet típusaként" - -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "Nem sikerült a(z) „%s” fájltípust értelmezni a(z) <%s> elem számára" +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Ablak áthelyezése az 1. munkaterületre" -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "Nem sikerült értelmezni a(z) „%s” állapotot a(z) <%s> elem számára" +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Ablak áthelyezése a 2. munkaterületre" -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "Nem sikerült „%s” árnyékot értelmezni a(z) <%s> elem számára" +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Ablak áthelyezése a 3. munkaterületre" -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "Nem sikerült értelmezni a(z) „%s” nyilat a(z) <%s> elem számára" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Ablak áthelyezése a 4. munkaterületre" -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "Nincsen „%s” nevű <draw_ops> meghatározva" +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Ablak áthelyezése az utolsó munkaterületre" -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "„%s” draw_ops ide beépítésével körkörös hivatkozás alakulna ki" +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "Ablak áthelyezése egy munkaterülettel feljebb" -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "„%s” pozíció ismeretlen a keretdarabhoz" +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "Ablak áthelyezése egy munkaterülettel lejjebb" -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "A keretstílusnak már van egy darabja a(z) „%s” pozícióban" +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "Ablak áthelyezése a balra lévő monitorra" -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "Nincs „%s” nevű <draw_ops> meghatározva" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "Ablak áthelyezése a jobbra lévő monitorra" -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "„%s” funkció ismeretlen a gombhoz" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "Ablak áthelyezése egy monitorral feljebb" -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "A(z) „%s” gombfunkció nem létezik ebben a verzióban (%d, szükséges: %d)" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "Ablak áthelyezése egy monitorral lejjebb" -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "„%s” állapot ismeretlen a gombhoz" +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "Alkalmazásváltás" -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "A keretstílusnak már van gombja a(z) „%s” funkcióra a(z) „%s” állapotban" +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "Váltás az előző alkalmazásra" -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "„%s” érték érvénytelen a fókusz attribútumhoz" +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "Ablakváltás" -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "„%s” érték érvénytelen az állapot attribútumhoz" +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "Váltás az előző ablakra" -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "„%s” nevű stílus nincs meghatározva" +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "Váltás egy alkalmazás ablakai között" -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "„%s” érték érvénytelen az átméretezés attribútumhoz" +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "Váltás egy alkalmazás előző ablakára" -#: ../src/ui/theme-parser.c:3147 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" -"A(z) <%s> elemnek nem szabadna „resize” attribútummal rendelkeznie a teljes " -"méretű/felgördített állapothoz" +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "Váltás a rendszer vezérlői közt" -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "" -"A(z) <%s> elemnek nem szabadna „resize” attribútummal rendelkeznie a teljes " -"méretű állapothoz" +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "Váltás az előző rendszervezérlőre" -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "%s állapothoz, %s átméretezéshez és %s fókuszhoz már meg van határozva stílus" +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "Váltás az ablakok közt közvetlenül" -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "%s állapothoz és %s fókuszhoz már meg van határozva stílus" +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "Váltás közvetlenül az előző ablakra" -#: ../src/ui/theme-parser.c:3294 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Nem lehet két draw_ops-a egy <piece> elemnek (a téma meghatározott egy " -"draw_ops attribútumot és egy <draw_ops> elemet, vagy két elemet határozott " -"meg)" +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "Váltás egy alkalmazás ablakai között közvetlenül" -#: ../src/ui/theme-parser.c:3332 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Nem lehet két draw_ops-a egy <button> elemnek (a téma meghatározott egy " -"draw_ops attribútumot és egy <draw_ops> elemet, vagy két elemet)" +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "Váltás közvetlenül egy alkalmazás előző ablakára" -#: ../src/ui/theme-parser.c:3370 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Nem lehet két draw_ops-a egy <menu_icon> elemnek (a téma meghatározott egy " -"draw_ops attribútumot és egy <draw_ops> elemet, vagy két elemet)" +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "Váltás a rendszer vezérlői közt közvetlenül" -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "Hibás verziómeghatározás: „%s”" +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "Váltás közvetlenül az előző rendszervezérlőre" -#: ../src/ui/theme-parser.c:3507 -msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" -msgstr "" -"A „version” attribútum nem használható a metacity-theme-1.xml vagy metacity-" -"theme-2.xml fájlban" +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "Minden normál ablak elrejtése" -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "A téma a(z) %s verziót igényli, de az utolsó támogatott témaverzió %d.%d" +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "Váltás az 1. munkaterületre" -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "A téma legkülső eleme <metacity_theme> kell legyen, nem pedig <%s>" +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "Váltás a 2. munkaterületre" -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "Element <%s> is not allowed inside a name/author/date/description element" -msgstr "A(z) <%s> elem nem megengedett egy name/author/date/description elemen belül" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "Váltás a 3. munkaterületre" -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "A(z) <%s> elem nem megengedett egy <constant> elemen belül" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "Váltás a 4. munkaterületre" -#: ../src/ui/theme-parser.c:3599 -#, c-format -msgid "Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "<%s> elem nem megengedett egy distance/border/aspect_ratio elemen belül" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "Váltás az utolsó munkaterületre" -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "<%s> elem nem megengedett egy rajzoló művelet elemen belül" +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "Áthelyezés a felső munkaterületre" -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "<%s> elem nem megengedett egy <%s> elemen belül" +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "Áthelyezés az alsó munkaterületre" -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "Nincsen draw_ops a keretdarabhoz" +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "Rendszer" -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "Nincs draw_ops megadva a gombhoz" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "A parancs futtatása ablak megjelenítése" -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "Nincs szöveg engedélyezve a(z) <%s> elemen belül" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "A tevékenységek áttekintés megjelenítése" -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "<%s> kétszer lett megadva ehhez a témához" +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Gyorsbillentyűk helyreállítása" -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Nem található érvényes fájl a következő témához: %s\n" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Ablakok" -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "_Ablakok" +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "Ablakmenü aktiválása" -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "_Párbeszédablak" +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Teljes képernyős üzemmód" -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "_Kizárólagos párbeszédablak" +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "Maximalizált állapot átváltása" -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "_Segédprogram" +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "Ablak maximalizálása" -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "_Indítóképernyő" +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Ablak visszaállítása" -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "_Felső dokk" +#: data/50-mutter-windows.xml:18 +msgid "Close window" +msgstr "Ablak bezárása" -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "_Alsó dokk" +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "Ablak elrejtése" -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "_Bal dokk" +#: data/50-mutter-windows.xml:22 +msgid "Move window" +msgstr "Ablak áthelyezése" -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "_Jobb dokk" +#: data/50-mutter-windows.xml:24 +msgid "Resize window" +msgstr "Ablak átméretezése" -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "Össz_es dokk" +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "Ablak megjelenítése minden munkaterületen vagy csak az egyiken" -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "_Asztal" +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "Fedett ablak előtérbe hozása, egyébként háttérbe küldése" -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "Egy újabb példány megnyitása ezekből az ablakokból" +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "Ablak más ablakok elé hozása" -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "Ez egy mintagomb a „Megnyitás” ikonnal" +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "Ablak más ablakok mögé küldése" -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "Ez egy mintagomb a „Kilépés” ikonnal" +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "Ablak függőleges maximalizálása" -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "Ez egy mintaüzenet egy minta párbeszédben" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "Ablak vízszintes maximalizálása" -#: ../src/ui/theme-viewer.c:328 -#, c-format -msgid "Fake menu item %d\n" -msgstr "%d. hamis menüelem\n" +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "Bal oldali felosztás megjelenítése" -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "Csak keretes ablak" +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "Jobb oldali felosztás megjelenítése" -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "Sáv" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "Normál alkalmazásablak" +#: data/org.gnome.mutter.gschema.xml.in:7 +msgid "Modifier to use for extended window management operations" +msgstr "A kiterjesztett ablakkezelési műveletekhez használandó módosító" -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "Párbeszédablak" +#: data/org.gnome.mutter.gschema.xml.in:8 +msgid "" +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." +msgstr "" +"Ez a kulcs indítja az „átfedést”, amely egy kombinációs ablakáttekintés és " +"alkalmazásindító rendszer. Az alapértelmezés a „Windows” billentyű PC " +"hardver esetén. Ezt vagy az alapértelmezetten, vagy üresen kell hagyni." -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "Kizárólagos párbeszéd doboz" +#: data/org.gnome.mutter.gschema.xml.in:20 +msgid "Attach modal dialogs" +msgstr "Kizárólagos párbeszédablakok csatolása" -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "Eszközpaletta" +#: data/org.gnome.mutter.gschema.xml.in:21 +msgid "" +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." +msgstr "" +"Ha igazra van állítva, akkor a kizárólagos ablakok nem önálló címsorral, " +"hanem a szülőablak címsorához csatolva jelennek meg, és a szülőablakkal " +"együtt kerülnek mozgatásra." -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "Leválasztott menü" +#: data/org.gnome.mutter.gschema.xml.in:30 +msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "Szélek csempézésének engedélyezése ablakok képernyőszélekre ejtésekor" -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "Szegély" +#: data/org.gnome.mutter.gschema.xml.in:31 +msgid "" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." +msgstr "" +"Ha engedélyezett, akkor a függőleges képernyőélekre ejtett ablakok " +"függőlegesen maximalizálva lesznek, vízszintesen pedig az elérhető terület " +"felét fogják elfoglalni. Az ablakok felső képernyőszélre ejtése teljesen " +"maximalizálja azokat." -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "Csatolt kizárólagos párbeszédablak" +#: data/org.gnome.mutter.gschema.xml.in:40 +msgid "Workspaces are managed dynamically" +msgstr "Munkaterületek dinamikus kezelése" -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "Gombelrendezés teszt %d" +#: data/org.gnome.mutter.gschema.xml.in:41 +msgid "" +"Determines whether workspaces are managed dynamically or whether there’s a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." +msgstr "" +"A munkaterületek dinamikusan vannak-e kezelve, vagy a számuk rögzített (ezt " +"a num-workspaces kulcs adja meg az org.gnome.desktop.wm.preferences fájlban)." -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g ezredmásodpercig tartott egy ablakkeret kirajzolása" +#: data/org.gnome.mutter.gschema.xml.in:50 +msgid "Workspaces only on primary" +msgstr "Munkaterületek csak az elsődlegesen" -#: ../src/ui/theme-viewer.c:813 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Használat: metacity-theme-viewer [TÉMANÉV]\n" +#: data/org.gnome.mutter.gschema.xml.in:51 +msgid "" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." +msgstr "" +"A munkaterület-váltás minden monitor ablakaihoz, vagy csak az elsődleges " +"monitor ablakaihoz történjen meg." -#: ../src/ui/theme-viewer.c:820 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "Hiba történt a téma betöltése közben: %s\n" +#: data/org.gnome.mutter.gschema.xml.in:59 +msgid "No tab popup" +msgstr "Nincs tab felugró" -#: ../src/ui/theme-viewer.c:826 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "A(z) „%s” téma %g másodperc alatt betöltve\n" +#: data/org.gnome.mutter.gschema.xml.in:60 +msgid "" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." +msgstr "" +"Megadja, hogy a felugró ablak és a kiemelő keret letiltandó-e az ablakok " +"közti lépkedéskor." -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "Normál cím betűtípus" +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Fókuszváltozások késleltetése a mutató mozgásának megállásáig" -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "Kicsi cím betűtípus" +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" +"Ha igazra van állítva, és a fókuszmód a „sloppy” vagy „mouse”, akkor a " +"fókusz nem változik meg azonnal egy ablakra mutatáskor, hanem csak a mutató " +"megállása után." -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "Nagy cím betűtípus" +#: data/org.gnome.mutter.gschema.xml.in:79 +msgid "Draggable border width" +msgstr "Húzható szegély szélessége" -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "Gombelrendezések" +#: data/org.gnome.mutter.gschema.xml.in:80 +msgid "" +"The amount of total draggable borders. If the theme’s visible borders are " +"not enough, invisible borders will be added to meet this value." +msgstr "" +"A húzható szegélyek teljes mennyisége. Ha a téma látható szegélyei nem " +"elegendők, akkor láthatatlan szegélyek kerülnek hozzáadásra ezen érték " +"eléréséhez." -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "Teljesítményteszt" +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "Közel monitorméretű ablakok automatikus maximalizálása" + +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" +"Ha engedélyezve van, akkor a monitor méretével egyező méretű új ablakok " +"automatikusan maximalizálva lesznek." + +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Az új ablakok középre helyezése" + +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" +"Ha igaz, az új ablakok mindig a monitor aktív képernyőjének közepére lesznek " +"helyezve." + +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Kísérleti funkciók engedélyezése" + +#: data/org.gnome.mutter.gschema.xml.in:108 +msgid "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes " +"mutter request a low priority real-time scheduling. The executable or user " +"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — " +"initializes Xwayland lazily if there are X11 clients. Requires restart." +msgstr "" +"A kísérleti funkciók engedélyezéséhez adja hozzá a funkció kulcsszavát a " +"listához. A funkció a betűszedő újraindítását igényelheti az adott " +"funkciótól függően. Egyik kísérleti funkciónál sem szükséges, hogy továbbra " +"is elérhető vagy beállítható legyen. Ne várja el azt, hogy ha bármit hozzáad " +"ehhez a beállításhoz, akkor az a jövőben is elérhető lesz. Jelenleg " +"lehetséges kulcsszavak: • „scale-monitor-framebuffer” — alapértelmezetté " +"teszi a mutter programot a logikai monitorok elrendezéséhez egy logikai " +"képpontkoordináta-térben, miközben átméretezi a monitor keretpufferét az " +"ablaktartalom helyett azért, hogy kezelje a HiDPI monitorokat. Nem igényel " +"újraindítást. • „rt-scheduler” — alacsony prioritású, valós idejű ütemezésre " +"kéri a mutter programot. A programnak vagy a felhasználónak CAP_SYS_NICE " +"értékkel kell rendelkeznie. Újraindítást igényel. • „autostart-xwayland” — " +"előkészíti az Xwayland kiszolgálót lustán, ha vannak X11 kliensek. " +"Újraindítást igényel." + +#: data/org.gnome.mutter.gschema.xml.in:134 +msgid "Modifier to use to locate the pointer" +msgstr "Használandó módosító a mutató elhelyezéséhez" + +#: data/org.gnome.mutter.gschema.xml.in:135 +msgid "This key will initiate the “locate pointer” action." +msgstr "Ez a kulcs el fogja indítani a „mutató elhelyezése” műveletet." + +#: data/org.gnome.mutter.gschema.xml.in:142 +msgid "Timeout for check-alive ping" +msgstr "Elérhetőség-ellenőrzés pingelésének időkorlátja" + +#: data/org.gnome.mutter.gschema.xml.in:143 +msgid "" +"Number of milliseconds a client has to respond to a ping request in order to " +"not be detected as frozen. Using 0 will disable the alive check completely." +msgstr "" +"Ezredmásodpercek száma, amely alatt az ügyfélnek válaszolnia kell egy ping" +" kérésre, hogy ne lefagyottként legyen azonosítva. A 0 használata teljesen" +" letiltja annak ellenőrzését, hogy életben van-e." + +#: data/org.gnome.mutter.gschema.xml.in:165 +msgid "Select window from tab popup" +msgstr "Ablakok kiválasztása tab billentyűre felugró ablakból" -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "Ide kerül az ablak címe" +#: data/org.gnome.mutter.gschema.xml.in:170 +msgid "Cancel tab popup" +msgstr "Tab felugró kikapcsolása" -#: ../src/ui/theme-viewer.c:1047 +#: data/org.gnome.mutter.gschema.xml.in:175 +msgid "Switch monitor configurations" +msgstr "Monitorkonfiguráció átváltása" + +#: data/org.gnome.mutter.gschema.xml.in:180 +msgid "Rotates the built-in monitor configuration" +msgstr "Cserélgeti a beépített monitorkonfigurációkat" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Váltás az 1. VT-re" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Váltás a 2. VT-re" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Váltás a 3. VT-re" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Váltás a 4. VT-re" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Váltás az 5. VT-re" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Váltás a 6. VT-re" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Váltás a 7. VT-re" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Váltás a 8. VT-re" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Váltás a 9. VT-re" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Váltás a 10. VT-re" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Váltás a 11. VT-re" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Váltás a 12. VT-re" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "Gyorsbillentyűk újraengedélyezése" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow X11 grabs to lock keyboard focus with Xwayland" +msgstr "" +"X11 megragadások lehetővé tétele a billentyűzetfókusz zárolásához az " +"Xwayland használatával" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 +msgid "" +"Allow all keyboard events to be routed to X11 “override redirect” windows " +"with a grab when running in Xwayland. This option is to support X11 clients " +"which map an “override redirect” window (which do not receive keyboard " +"focus) and issue a keyboard grab to force all keyboard events to that " +"window. This option is seldom used and has no effect on regular X11 windows " +"which can receive keyboard focus under normal circumstances. For a X11 grab " +"to be taken into account under Wayland, the client must also either send a " +"specific X11 ClientMessage to the root window or be among the applications " +"white-listed in key “xwayland-grab-access-rules”." +msgstr "" +"Lehetővé teszi az összes billentyűzeteseménynek, hogy át legyenek irányítva " +"az X11 „felülbírálási átirányítás” ablakokhoz egy megragadással, ha az " +"Xwaylandben fut. Ez a beállítás azért van, hogy támogassa azokat az X11 " +"klienseket, amelyek egy „felülbírálási átirányítás” ablakot képeznek le " +"(amely nem kap billentyűzetfókuszt), és kibocsátson egy " +"billentyűzetelfogást, hogy kényszerítse az összes billentyűzeteseményt ahhoz " +"az ablakhoz. Ez a beállítás ritkán használt, és nincs hatása azoknál a " +"szabályos X11 ablakoknál, amelyek fogadhatnak billentyűzetfókuszt normál " +"körülmények között. Ahhoz, hogy Wayland alatt figyelembe legyenek véve az " +"X11 megragadások, a kliensnek vagy küldenie kell egy meghatározott X11 " +"ClientMessage üzenetet a gyökérablaknak, vagy az „xwayland-grab-access-" +"rules” kulcsban megadott fehérlistában kell szerepelnie." + +#: data/org.gnome.mutter.wayland.gschema.xml.in:84 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "Xwayland alkalmazások, amelyek kérhetnek billentyűzet megragadást" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:85 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "" +"Felsorolja azokat az X11 ablak erőforrásneveket vagy erőforrásosztályokat, " +"amelyek Xwayland alatt vagy kiadhatnak X11 billentyűzet megragadásokat, vagy " +"sem. A megadott X11 ablak erőforrásneve vagy erőforrásosztálya az „xprop " +"WM_CLASS” paranccsal kérhető le. Az értékekben a „*” vagy „?” helyettesítő " +"karakterek támogatottak. A „!” karakterrel kezdődő értékek feketelistára " +"kerülnek, és a fehérlista előtt lesznek figyelembe véve, így felülbírálva az " +"alapértelmezett rendszerlistát. Az alapértelmezett rendszerlistán a " +"következő alkalmazások szerepelnek: „@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@”. " +"A felhasználók megszakíthatják a létező megragadásokat a „restore-shortcuts” " +"kulcsban megadott gyorsbillentyűvel." + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. +#. +#: src/backends/meta-input-settings.c:2567 #, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"%d keret kirajzolása %g kliens-oldali másodperc alatt (%g ezredmásodperc " -"képkeretenként) és %g összes idő beleértve az X szerver erőforrásokat (%g " -"ezredmásodperc képkeretenként)\n" +msgid "Mode Switch (Group %d)" +msgstr "Módkapcsoló (%d. csoport)" + +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2590 +msgid "Switch monitor" +msgstr "Monitorváltás" -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "a pozíció kifejezés teszt IGAZ értéket adott vissza, de hiba történt" +#: src/backends/meta-input-settings.c:2592 +msgid "Show on-screen help" +msgstr "Képernyősúgó megjelenítése" -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "a pozíció kifejezés teszt HAMIS értéket adott vissza, de nem történt hiba" +#: src/backends/meta-monitor.c:223 +msgid "Built-in display" +msgstr "Beépített kijelző" -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "Hibát vártunk, de nem történt egy sem" +#: src/backends/meta-monitor.c:252 +msgid "Unknown" +msgstr "Ismeretlen" -#: ../src/ui/theme-viewer.c:1274 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "A(z) %d hibát vártuk, de a(z) %d hiba következett be" +#: src/backends/meta-monitor.c:254 +msgid "Unknown Display" +msgstr "Ismeretlen kijelző" -#: ../src/ui/theme-viewer.c:1280 +#: src/backends/meta-monitor.c:262 #, c-format -msgid "Error not expected but one was returned: %s" -msgstr "Nem várt hiba következett be: %s" +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme-viewer.c:1284 +#: src/backends/meta-monitor.c:270 #, c-format -msgid "x value was %d, %d was expected" -msgstr "x értéke %d volt, de a várt érték %d volt" +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "y értéke %d volt, de a várt érték %d volt" +#. Translators: this string will appear in Sysprof +#: src/backends/meta-profiler.c:79 +msgid "Compositor" +msgstr "Betűszedő" -#: ../src/ui/theme-viewer.c:1352 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:533 #, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" +msgid "" +"Another compositing manager is already running on screen %i on display “%s”." msgstr "" -"A %d koordináta kifejezések %g másodperc alatt lettek feldolgozva (átlagosan " -"%g másodperc)\n" - -#~ msgid "Close Window" -#~ msgstr "Ablak bezárása" - -#~ msgid "Window Menu" -#~ msgstr "Ablak menü" - -#~ msgid "Minimize Window" -#~ msgstr "Ablak minimalizálása" - -#~ msgid "Maximize Window" -#~ msgstr "Ablak maximalizálása" - -#~ msgid "Restore Window" -#~ msgstr "Ablak visszaállítása" - -#~ msgid "Roll Up Window" -#~ msgstr "Ablak felgördítése" - -#~ msgid "Unroll Window" -#~ msgstr "Ablak lenyitása" - -#~ msgid "Keep Window On Top" -#~ msgstr "Ablak legfelül tartása" - -#~ msgid "Remove Window From Top" -#~ msgstr "Ablak eltávolítása legfelülről" - -#~ msgid "Always On Visible Workspace" -#~ msgstr "Mindig a látható munkaterületen" - -#~ msgid "Put Window On Only One Workspace" -#~ msgstr "Ablak kirakása csak egy munkaterületre" - -#~ msgid "Switch to workspace 1" -#~ msgstr "Átváltás az 1. munkaterületre" - -#~ msgid "Switch to workspace 2" -#~ msgstr "Átváltás a 2. munkaterületre" - -#~ msgid "Switch to workspace 3" -#~ msgstr "Átváltás a 3. munkaterületre" - -#~ msgid "Switch to workspace 4" -#~ msgstr "Átváltás a 4. munkaterületre" - -#~ msgid "Switch to workspace 5" -#~ msgstr "Átváltás az 5. munkaterületre" - -#~ msgid "Switch to workspace 6" -#~ msgstr "Átváltás a 6. munkaterületre" - -#~ msgid "Switch to workspace 7" -#~ msgstr "Átváltás a 7. munkaterületre" - -#~ msgid "Switch to workspace 8" -#~ msgstr "Átváltás a 8. munkaterületre" - -#~ msgid "Switch to workspace 9" -#~ msgstr "Átváltás a 9. munkaterületre" - -#~ msgid "Switch to workspace 10" -#~ msgstr "Átváltás a 10. munkaterületre" - -#~ msgid "Switch to workspace 11" -#~ msgstr "Átváltás a 11. munkaterületre" - -#~ msgid "Switch to workspace 12" -#~ msgstr "Átváltás a 12. munkaterületre" - -#~ msgid "Switch to workspace on the left of the current workspace" -#~ msgstr "Átváltás a jelenlegitől balra lévő munkaterületre" - -#~ msgid "Switch to workspace on the right of the current workspace" -#~ msgstr "Átváltás a jelenlegitől jobbra lévő munkaterületre" - -#~ msgid "Switch to workspace above the current workspace" -#~ msgstr "Átváltás a jelenlegi feletti munkaterületre" - -#~ msgid "Switch to workspace below the current workspace" -#~ msgstr "Átváltás a jelenlegi alatti munkaterületre" - -#~ msgid "Move between windows of an application, using a popup window" -#~ msgstr "Váltás egy alkalmazás ablakai között felugró ablakkal" - -#~ msgid "" -#~ "Move backward between windows of an application, using a popup window" -#~ msgstr "Váltás hátrafelé egy alkalmazás ablakai között felugró ablakkal" - -#~ msgid "Move between windows, using a popup window" -#~ msgstr "Váltás ablakok között felugró ablakkal" - -#~ msgid "Move backward between windows, using a popup window" -#~ msgstr "Váltás hátrafelé ablakok között felugró ablakkal" - -#~ msgid "Move between panels and the desktop, using a popup window" -#~ msgstr "Váltás a panelek és az asztal között felugró ablakkal" - -#~ msgid "Move backward between panels and the desktop, using a popup window" -#~ msgstr "Váltás hátrafelé a panelek és az asztal között felugró ablakkal" - -#~ msgid "Move between windows of an application immediately" -#~ msgstr "Váltás egy alkalmazás ablakai között azonnal" - -#~ msgid "Move backward between windows of an application immediately" -#~ msgstr "Váltás hátrafelé egy alkalmazás ablakai között azonnal" - -#~ msgid "Move between windows immediately" -#~ msgstr "Váltás az ablakok között azonnal" - -#~ msgid "Move backward between windows immediately" -#~ msgstr "Váltás hátrafelé az ablakok között azonnal" - -#~ msgid "Move between panels and the desktop immediately" -#~ msgstr "Váltás a panelek és az asztal között azonnal" - -#~ msgid "Move backward between panels and the desktop immediately" -#~ msgstr "Váltás hátrafelé a panelek és az asztal között azonnal" - -#~ msgid "Hide all normal windows and set focus to the desktop" -#~ msgstr "Minden normál ablak elrejtése és fókusz átvitele az asztalra" - -#~ msgid "Show the panel's main menu" -#~ msgstr "A panel főmenüjének megjelenítése" - -#~ msgid "Show the panel's \"Run Application\" dialog box" -#~ msgstr "A panel „Alkalmazás futtatása” párbeszédablakának megjelenítése" - -#~ msgid "Start or stop recording the session" -#~ msgstr "A munkamenet felvételének indítása vagy leállítása" - -#~ msgid "Take a screenshot" -#~ msgstr "Képernyőkép készítése" - -#~ msgid "Take a screenshot of a window" -#~ msgstr "Képernyőkép készítése egy ablakról" - -#~ msgid "Run a terminal" -#~ msgstr "Terminál nyitása" - -#~ msgid "Activate the window menu" -#~ msgstr "Ablakmenü aktiválása" - -#~ msgid "Toggle fullscreen mode" -#~ msgstr "Teljes képernyős üzemmód" - -#~ msgid "Toggle maximization state" -#~ msgstr "Maximalizált állapot átváltása" - -#~ msgid "Toggle whether a window will always be visible over other windows" -#~ msgstr "Az ablak mindig látható lesz más ablakok fölött" - -#~ msgid "Maximize window" -#~ msgstr "Ablak maximalizálása" - -#~ msgid "Restore window" -#~ msgstr "Ablak visszaállítása" - -#~ msgid "Toggle shaded state" -#~ msgstr "Felgördített állapot átváltása" - -#~ msgid "Minimize window" -#~ msgstr "Ablak minimalizálása" - -#~ msgid "Close window" -#~ msgstr "Ablak bezárása" - -#~ msgid "Move window" -#~ msgstr "Ablak áthelyezése" - -#~ msgid "Resize window" -#~ msgstr "Ablak átméretezése" - -#~ msgid "Toggle whether window is on all workspaces or just one" -#~ msgstr "Ablak megjelenítése minden munkaterületen vagy csak az egyiken" - -#~ msgid "Move window to workspace 1" -#~ msgstr "Ablak áthelyezése az 1. munkaterületre" - -#~ msgid "Move window to workspace 2" -#~ msgstr "Ablak áthelyezése a 2. munkaterületre" - -#~ msgid "Move window to workspace 3" -#~ msgstr "Ablak áthelyezése a 3. munkaterületre" - -#~ msgid "Move window to workspace 4" -#~ msgstr "Ablak áthelyezése a 4. munkaterületre" - -#~ msgid "Move window to workspace 5" -#~ msgstr "Ablak áthelyezése az 5. munkaterületre" - -#~ msgid "Move window to workspace 6" -#~ msgstr "Ablak áthelyezése a 6. munkaterületre" - -#~ msgid "Move window to workspace 7" -#~ msgstr "Ablak áthelyezése a 7. munkaterületre" - -#~ msgid "Move window to workspace 8" -#~ msgstr "Ablak áthelyezése a 8. munkaterületre" - -#~ msgid "Move window to workspace 9" -#~ msgstr "Ablak áthelyezése a 9. munkaterületre" - -#~ msgid "Move window to workspace 10" -#~ msgstr "Ablak áthelyezése a 10. munkaterületre" - -#~ msgid "Move window to workspace 11" -#~ msgstr "Ablak áthelyezése a 11. munkaterületre" - -#~ msgid "Move window to workspace 12" -#~ msgstr "Ablak áthelyezése a 12. munkaterületre" - -#~ msgid "Move window one workspace to the left" -#~ msgstr "Ablak áthelyezése a balra lévő munkaterületre" +"Már fut egy másik kompozitálás-kezelő a(z) %i. képernyőn a(z) „%s” " +"megjelenítőn." -#~ msgid "Move window one workspace to the right" -#~ msgstr "Ablak áthelyezése a jobbra lévő munkaterületre" +#: src/core/bell.c:192 +msgid "Bell event" +msgstr "Csengetés esemény" -#~ msgid "Move window one workspace up" -#~ msgstr "Ablak áthelyezése egy munkaterülettel feljebb" +#: src/core/main.c:190 +msgid "Disable connection to session manager" +msgstr "A munkamenet-kezelőhöz való csatlakozás tiltása" -#~ msgid "Move window one workspace down" -#~ msgstr "Ablak áthelyezése egy munkaterülettel lejjebb" +#: src/core/main.c:196 +msgid "Replace the running window manager" +msgstr "A futó ablakkezelő helyettesítése" -#~ msgid "Raise window if it's covered by another window, otherwise lower it" -#~ msgstr "Fedett ablak előtérbe hozása, egyébként háttérbe küldése" +#: src/core/main.c:202 +msgid "Specify session management ID" +msgstr "A munkamenet-kezelő azonosítójának megadása" -#~ msgid "Raise window above other windows" -#~ msgstr "Ablak más ablakok elé hozása" +#: src/core/main.c:207 +msgid "X Display to use" +msgstr "A használandó X megjelenítő" -#~ msgid "Lower window below other windows" -#~ msgstr "Ablak más ablakok mögé küldése" +#: src/core/main.c:213 +msgid "Initialize session from savefile" +msgstr "A munkamenet előkészítése a mentési fájlból" -#~ msgid "Maximize window vertically" -#~ msgstr "Ablak függőleges maximalizálása" +#: src/core/main.c:219 +msgid "Make X calls synchronous" +msgstr "Az X-hívások szinkronná tétele" -#~ msgid "Maximize window horizontally" -#~ msgstr "Ablak vízszintes maximalizálása" +#: src/core/main.c:226 +msgid "Run as a wayland compositor" +msgstr "Futtatás wayland betűszedőként" -#~ msgid "Move window to north-west (top left) corner" -#~ msgstr "Ablak áthelyezése az északnyugati (bal felső) sarokba" +#: src/core/main.c:232 +msgid "Run as a nested compositor" +msgstr "Futtatás beágyazott betűszedőként" -#~ msgid "Move window to north-east (top right) corner" -#~ msgstr "Ablak áthelyezése az északkeleti (jobb felső) sarokba" +#: src/core/main.c:238 +msgid "Run wayland compositor without starting Xwayland" +msgstr "Wayland kompozitáló futtatása az Xwayland elíntása nélkül" -#~ msgid "Move window to south-west (bottom left) corner" -#~ msgstr "Ablak áthelyezése a délnyugati (bal alsó) sarokba" +#: src/core/main.c:246 +msgid "Run as a full display server, rather than nested" +msgstr "" +"Futtatás teljes megjelenítő kiszolgálóként az egymásba ágyazott helyett" -#~ msgid "Move window to south-east (bottom right) corner" -#~ msgstr "Ablak áthelyezése a délkeleti (jobb alsó) sarokba" +#: src/core/main.c:252 +msgid "Run with X11 backend" +msgstr "Futtatás X11 háttérprogrammal" -#~ msgid "Move window to north (top) side of screen" -#~ msgstr "Ablak áthelyezése a képernyő északi (felső) oldalához" +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:151 +#, c-format +msgid "“%s” is not responding." +msgstr "„%s” nem válaszol." -#~ msgid "Move window to south (bottom) side of screen" -#~ msgstr "Ablak áthelyezése a képernyő déli (alsó) oldalához" +#: src/core/meta-close-dialog-default.c:153 +msgid "Application is not responding." +msgstr "Az alkalmazás nem válaszol." -#~ msgid "Move window to east (right) side of screen" -#~ msgstr "Ablak áthelyezése a képernyő keleti (jobb) oldalához" +#: src/core/meta-close-dialog-default.c:158 +msgid "" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." +msgstr "" +"Várhat egy kicsit a folytatódására, vagy kikényszerítheti az alkalmazás " +"teljes kilépését." -#~ msgid "Move window to west (left) side of screen" -#~ msgstr "Ablak áthelyezése a képernyő nyugati (bal) oldalához" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Force Quit" +msgstr "_Erőltetett kilépés" -#~ msgid "Move window to center of screen" -#~ msgstr "Ablak áthelyezése a képernyő közepére" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Wait" +msgstr "Vá_rakozás" -#~ msgid "" -#~ "There was an error running <tt>%s</tt>:\n" -#~ "\n" -#~ "%s" -#~ msgstr "" -#~ "Hiba történt a(z) <tt>%s</tt> futtatása közben:\n" -#~ "\n" -#~ "%s" +#: src/core/mutter.c:38 +#, c-format +msgid "" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" +msgstr "" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., és mások\n" +"Ez egy szabad szoftver; lásd a forrást a másolás feltételeiről.\n" +"NINCS garancia; még az ELADHATÓSÁGRA vagy EGY ADOTT CÉLRA VALÓ ALKALMASSÁGRA " +"vonatkozólag sem.\n" -#~ msgid "No command %d has been defined.\n" -#~ msgstr "Nincs %d parancs meghatározva.\n" +#: src/core/mutter.c:52 +msgid "Print version" +msgstr "Verzió kiírása" -#~ msgid "No terminal command has been defined.\n" -#~ msgstr "Nincs terminálparancs meghatározva.\n" +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "Használandó Mutter bővítmény" -#~ msgid "GConf key '%s' is set to an invalid value\n" -#~ msgstr "„%s” GConf kulcs érvénytelen értékre van állítva\n" +#: src/core/prefs.c:1911 +#, c-format +msgid "Workspace %d" +msgstr "%d. munkaterület" -#~ msgid "%d stored in GConf key %s is out of range %d to %d\n" -#~ msgstr "" -#~ "%d, ami a(z) %s GConf kulcsban van tárolva, a tartományon (%d - %d) kívül " -#~ "van\n" +#: src/core/util.c:122 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "A Mutter ablakkezelőt a részletes mód támogatása nélkül fordították\n" -#~ msgid "GConf key \"%s\" is set to an invalid type\n" -#~ msgstr "„%s” GConf kulcs érvénytelen típusú\n" +#: src/wayland/meta-wayland-tablet-pad.c:568 +#, c-format +msgid "Mode Switch: Mode %d" +msgstr "Módkapcsoló: %d. mód" -#~ msgid "GConf key %s is already in use and can't be used to override %s\n" -#~ msgstr "" -#~ "A(z) %s GConf-kulcs már használatban van, és nem használható %s " -#~ "felülbírálására\n" +#: src/x11/meta-x11-display.c:676 +#, c-format +msgid "" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." +msgstr "" +"A(z) „%s” kijelző már rendelkezik ablakkezelővel; próbálja a --replace " +"kapcsolóval helyettesíteni a jelenlegi ablakkezelőt." -#~ msgid "Can't override GConf key, %s not found\n" -#~ msgstr "A GConf-kulcs nem bírálható felül, %s nem található\n" +#: src/x11/meta-x11-display.c:1089 +msgid "Failed to initialize GDK\n" +msgstr "A GDK előkészítése meghiúsult\n" -#~ msgid "Error setting number of workspaces to %d: %s\n" -#~ msgstr "" -#~ "Hiba a munkaterületek számának beállításánál a következőre: %d: %s\n" +#: src/x11/meta-x11-display.c:1113 +#, c-format +msgid "Failed to open X Window System display “%s”\n" +msgstr "Nem sikerült megnyitni a(z) „%s” X Window rendszer képernyőt\n" -#~ msgid "Error setting name for workspace %d to \"%s\": %s\n" -#~ msgstr "" -#~ "Hiba a(z) %d. munkaterület nevének beállításánál a következőre: „%s”: %s\n" +#: src/x11/meta-x11-display.c:1196 +#, c-format +msgid "Screen %d on display “%s” is invalid\n" +msgstr "A(z) %d. képernyő a(z) „%s” megjelenítőn érvénytelen\n" -#~ msgid "Error setting live hidden windows status status: %s\n" -#~ msgstr "Hiba az élő rejtett ablakok állapot beállításakor: %s\n" +#: src/x11/meta-x11-selection-input-stream.c:460 +#, c-format +msgid "Format %s not supported" +msgstr "A(z) %s formátum nem támogatott" -#~ msgid "Error setting no tab popup status: %s\n" -#~ msgstr "Hiba a nincs tab felugró állapot beállításakor: %s\n" +#: src/x11/session.c:1821 +msgid "" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." +msgstr "" +"Az alábbi ablakok nem támogatják az „aktuális beállítások mentését”, emiatt " +"ezeket a legközelebbi bejelentkezéskor manuálisan újra kell indítania." +#: src/x11/window-props.c:569 +#, c-format +msgid "%s (on %s)" +msgstr "%s (ezen: %s)" diff --git a/po/hy.po b/po/hy.po index 295c67bee..8d20c1228 100644 --- a/po/hy.po +++ b/po/hy.po @@ -9,6 +9,7 @@ msgstr "" "PO-Revision-Date: 2005-09-04 18:18+0200\n" "Last-Translator: \n" "Language-Team: <en@li.org>\n" +"Language: hy\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" diff --git a/po/id.po b/po/id.po index a257950b3..1e32e0e26 100644 --- a/po/id.po +++ b/po/id.po @@ -1,1789 +1,789 @@ -# Indonesian translation of muffin. -# Copyright (C) 2003 THE muffin'S COPYRIGHT HOLDER -# This file is distributed under the same license as the muffin package. +# Indonesian translation of mutter. +# Copyright (C) 2003 THE mutter'S COPYRIGHT HOLDER +# This file is distributed under the same license as the mutter package. # # Mohammad DAMT <mdamt@bisnisweb.com>, 2003-2005. # Ahmad Riza H Nst <rizahnst@eriagempita.co.id>, 2006. -# Dirgita <dirgitadevina@yahoo.co.id>, 2011. -# Andika Triwidada <andika@gmail.com>, 2011. +# Dirgita <dirgitadevina@yahoo.co.id>, 2011, 2012, 2014. +# Andika Triwidada <andika@gmail.com>, 2011-2015. +# Kukuh Syafaat <kukuhsyafaat@gnome.org>, 2017-2020. msgid "" msgstr "" -"Project-Id-Version: metacity HEAD\n" -"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=muffin&keywords=I18N+L10N&component=general\n" -"POT-Creation-Date: 2011-08-10 12:42+0000\n" -"PO-Revision-Date: 2011-09-06 13:48+0700\n" -"Last-Translator: Andika Triwidada <andika@gmail.com>\n" -"Language-Team: Indonesian <gnome@i15n.org>\n" +"Project-Id-Version: mutter master\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2020-02-23 17:44+0000\n" +"PO-Revision-Date: 2020-02-25 17:48+0700\n" +"Last-Translator: Kukuh Syafaat <kukuhsyafaat@gnome.org>\n" +"Language-Team: Indonesian <gnome-l10n-id@googlegroups.com>\n" +"Language: id\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Language: id\n" -"X-Generator: Lokalize 1.1\n" -"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 2.3\n" +"Plural-Forms: nplurals=2; plural= n!=1;\n" -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:487 -#, c-format -#| msgid "" -#| "Could not acquire window manager selection on screen %d display \"%s\"\n" -msgid "Another compositing manager is already running on screen %i on display \"%s\"." -msgstr "Manajer komposit lain telah berjalan pada layar %i pada tampilan \"%s\"." +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Navigasi" -#: ../src/core/all-keybindings.h:88 -msgid "Switch to workspace 1" -msgstr "Pindah ke area kerja 1" +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Pindahkan jendela ke ruang kerja 1" -#: ../src/core/all-keybindings.h:90 -msgid "Switch to workspace 2" -msgstr "Pindah ke area kerja 2" +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Pindahkan jendela ke ruang kerja 2" -#: ../src/core/all-keybindings.h:92 -msgid "Switch to workspace 3" -msgstr "Pindah ke area kerja 3" +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Pindahkan jendela ke ruang kerja 3" -#: ../src/core/all-keybindings.h:94 -msgid "Switch to workspace 4" -msgstr "Pindah ke area kerja 4" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Pindahkan jendela ke ruang kerja 4" -#: ../src/core/all-keybindings.h:96 -msgid "Switch to workspace 5" -msgstr "Pindah ke area kerja 5" +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Pindahkan jendela ke ruang kerja terakhir" -#: ../src/core/all-keybindings.h:98 -msgid "Switch to workspace 6" -msgstr "Pindah ke area kerja 6" +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "Pindahkan jendela satu ruang kerja ke atas" -#: ../src/core/all-keybindings.h:100 -msgid "Switch to workspace 7" -msgstr "Pindah ke area kerja 7" +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "Pindahkan jendela satu ruang kerja ke bawah" -#: ../src/core/all-keybindings.h:102 -msgid "Switch to workspace 8" -msgstr "Pindah ke area kerja 8" +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "Pindahkan jendela satu monitor ke kiri" -#: ../src/core/all-keybindings.h:104 -msgid "Switch to workspace 9" -msgstr "Pindah ke area kerja 9" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "Pindahkan jendela satu monitor ke kanan" -#: ../src/core/all-keybindings.h:106 -msgid "Switch to workspace 10" -msgstr "Pindah ke area kerja 10" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "Pindahkan jendela satu monitor ke atas" -#: ../src/core/all-keybindings.h:108 -msgid "Switch to workspace 11" -msgstr "Pindah ke area kerja 11" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "Pindahkan jendela satu monitor ke bawah" -#: ../src/core/all-keybindings.h:110 -msgid "Switch to workspace 12" -msgstr "Pindah ke area kerja 12" +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "Bertukar aplikasi" -#: ../src/core/all-keybindings.h:122 -msgid "Switch to workspace on the left of the current workspace" -msgstr "Pindah ke area kerja kiri" +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "Bertukar ke aplikasi sebelumnya" -#: ../src/core/all-keybindings.h:126 -msgid "Switch to workspace on the right of the current workspace" -msgstr "Pindah ke area kerja kanan" +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "Bertukar jendela" -#: ../src/core/all-keybindings.h:130 -msgid "Switch to workspace above the current workspace" -msgstr "Pindah ke area kerja atas" +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "Bertukar ke jendela sebelumnya" -#: ../src/core/all-keybindings.h:134 -msgid "Switch to workspace below the current workspace" -msgstr "Pindah ke area kerja bawah" +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "Bertukar jendela dari suatu aplikasi" -#: ../src/core/all-keybindings.h:150 -msgid "Move between windows of an application, using a popup window" -msgstr "Pindah antara jendela aplikasi, menggunakan jendela popup" +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "Bertukar ke jendela aplikasi sebelumnya" -#: ../src/core/all-keybindings.h:153 -msgid "Move backward between windows of an application, using a popup window" -msgstr "Pindah antara jendela aplikasi dengan arah sebaliknya, menggunakan jendela popup" +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "Bertukar kendali sistem" -#: ../src/core/all-keybindings.h:157 -msgid "Move between windows, using a popup window" -msgstr "Pindah antara jendela, menggunakan jendela popup" +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "Bertukar ke kendali sistem sebelumnya" -#: ../src/core/all-keybindings.h:160 -msgid "Move backward between windows, using a popup window" -msgstr "Pindah antara jendela dengan arah sebaliknya, menggunakan jendela popup" +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "Bertukar jendela secara langsung" -#: ../src/core/all-keybindings.h:163 -msgid "Move between panels and the desktop, using a popup window" -msgstr "Pindah antara panel dan desktop, menggunakan jendela popup" +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "Bertukar secara langsung ke jendela sebelumnya" -#: ../src/core/all-keybindings.h:166 -msgid "Move backward between panels and the desktop, using a popup window" -msgstr "Pindah antara panel dan desktop dengan arah sebaliknya, menggunakan jendela popup" +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "Bertukar jendela dari suatu app secara langsung" -#: ../src/core/all-keybindings.h:171 -msgid "Move between windows of an application immediately" -msgstr "Pindah langsung antara jendela aplikasi" +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "Bertukar secara langsung ke jendela sebelumnya dari suatu app" -#: ../src/core/all-keybindings.h:174 -msgid "Move backward between windows of an application immediately" -msgstr "Pindah langsung antara jendela aplikasi dengan arah sebaliknya" +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "Bertukar kendali sistem secara langsung" -#: ../src/core/all-keybindings.h:177 -msgid "Move between windows immediately" -msgstr "Pindah langsung antara jendela" +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "Bertukar secara langsung ke kendali sistem sebelumnya" -#: ../src/core/all-keybindings.h:180 -msgid "Move backward between windows immediately" -msgstr "Pindah langsung antara jendela dengan arah sebaliknya" +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "Sembunyikan semua jendela normal" -#: ../src/core/all-keybindings.h:183 -msgid "Move between panels and the desktop immediately" -msgstr "Pindah langsung antara panel dan desktop" +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "Bertukar ke ruang kerja 1" -#: ../src/core/all-keybindings.h:186 -msgid "Move backward between panels and the desktop immediately" -msgstr "Pindah langsung antara panel dan desktop dengan arah sebaliknya" +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "Bertukar ke ruang kerja 2" + +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "Bertukar ke ruang kerja 3" + +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "Bertukar ke ruang kerja 4" + +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "Bertukar ke ruang kerja terakhir" -#: ../src/core/all-keybindings.h:203 -msgid "Hide all normal windows and set focus to the desktop" -msgstr "Menyembunyikan semua jendela serta berfokus pada desktop" +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "Pindahkan ke ruang kerja di atas" -#: ../src/core/all-keybindings.h:206 -msgid "Show the panel's main menu" -msgstr "Menampilkan panel menu utama" +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "Pindahkan ke ruang kerja di bawah" -#: ../src/core/all-keybindings.h:209 -msgid "Show the panel's \"Run Application\" dialog box" -msgstr "Menampilkan kotak dialog panel \"Jalankan Aplikasi\"" +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "Sistem" -#: ../src/core/all-keybindings.h:211 -msgid "Start or stop recording the session" -msgstr "Mulai atau berhenti merekam sesi" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Tampilkan sapaan jalankan perintah" -#: ../src/core/all-keybindings.h:252 -msgid "Take a screenshot" -msgstr "Mengambil cuplikan layar" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Tampilkan ringkasan aktivitas" -#: ../src/core/all-keybindings.h:254 -msgid "Take a screenshot of a window" -msgstr "Mengambil cuplikan layar sebuah jendela" +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Pulihkan pintasan papan tik" -#: ../src/core/all-keybindings.h:256 -msgid "Run a terminal" -msgstr "Menjalankan terminal" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Jendela" -#: ../src/core/all-keybindings.h:271 +#: data/50-mutter-windows.xml:8 msgid "Activate the window menu" msgstr "Mengaktifkan menu jendela" -#: ../src/core/all-keybindings.h:274 +#: data/50-mutter-windows.xml:10 msgid "Toggle fullscreen mode" -msgstr "Ubah mode layar penuh" +msgstr "Jungkitkan mode layar penuh" -#: ../src/core/all-keybindings.h:276 +#: data/50-mutter-windows.xml:12 msgid "Toggle maximization state" -msgstr "Ubah kondisi maksimal" +msgstr "Jungkitkan keadaan termaksimalkan" -#: ../src/core/all-keybindings.h:278 -msgid "Toggle whether a window will always be visible over other windows" -msgstr "Membuat apakah jendela selalu terlihat di antara jendela yang lain" - -#: ../src/core/all-keybindings.h:280 +#: data/50-mutter-windows.xml:14 msgid "Maximize window" -msgstr "Maksimalkan ukuran jendela" +msgstr "Maksimalkan jendela" -#: ../src/core/all-keybindings.h:282 +#: data/50-mutter-windows.xml:16 msgid "Restore window" -msgstr "Kembalikan ukuran jendela" - -#: ../src/core/all-keybindings.h:284 -msgid "Toggle shaded state" -msgstr "Ubah kondisi berbayang" +msgstr "Pulihkan jendela" -#: ../src/core/all-keybindings.h:286 -msgid "Minimize window" -msgstr "Minimalkan ukuran jendela" - -#: ../src/core/all-keybindings.h:288 +#: data/50-mutter-windows.xml:18 msgid "Close window" msgstr "Tutup jendela" -#: ../src/core/all-keybindings.h:290 +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "Sembunyikan jendela" + +#: data/50-mutter-windows.xml:22 msgid "Move window" msgstr "Pindahkan jendela" -#: ../src/core/all-keybindings.h:292 +#: data/50-mutter-windows.xml:24 msgid "Resize window" -msgstr "Rubah ukuran jendela" +msgstr "Ubah ukuran jendela" -#: ../src/core/all-keybindings.h:295 -msgid "Toggle whether window is on all workspaces or just one" -msgstr "Membuat apakah jendela hanya ada di satu atau semua area kerja" - -#: ../src/core/all-keybindings.h:299 -msgid "Move window to workspace 1" -msgstr "Pindahkan jendela ke area kerja 1" +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "Jungkitkan jendela pada semua atau satu area kerja" -#: ../src/core/all-keybindings.h:302 -msgid "Move window to workspace 2" -msgstr "Pindahkan jendela ke area kerja 2" - -#: ../src/core/all-keybindings.h:305 -msgid "Move window to workspace 3" -msgstr "Pindahkan jendela ke area kerja 3" +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "Naikkan jendela bila tertutup jendela lain, sebaliknya turunkan" -#: ../src/core/all-keybindings.h:308 -msgid "Move window to workspace 4" -msgstr "Pindahkan jendela ke area kerja 4" - -#: ../src/core/all-keybindings.h:311 -msgid "Move window to workspace 5" -msgstr "Pindahkan jendela ke area kerja 5" - -#: ../src/core/all-keybindings.h:314 -msgid "Move window to workspace 6" -msgstr "Pindahkan jendela ke area kerja 6" - -#: ../src/core/all-keybindings.h:317 -msgid "Move window to workspace 7" -msgstr "Pindahkan jendela ke area kerja 7" - -#: ../src/core/all-keybindings.h:320 -msgid "Move window to workspace 8" -msgstr "Pindahkan jendela ke area kerja 8" - -#: ../src/core/all-keybindings.h:323 -msgid "Move window to workspace 9" -msgstr "Pindahkan jendela ke area kerja 9" - -#: ../src/core/all-keybindings.h:326 -msgid "Move window to workspace 10" -msgstr "Pindahkan jendela ke area kerja 10" - -#: ../src/core/all-keybindings.h:329 -msgid "Move window to workspace 11" -msgstr "Pindahkan jendela ke area kerja 11" - -#: ../src/core/all-keybindings.h:332 -msgid "Move window to workspace 12" -msgstr "Pindahkan jendela ke area kerja 12" - -#: ../src/core/all-keybindings.h:344 -msgid "Move window one workspace to the left" -msgstr "Pindahkan jendela ke area kerja kiri" - -#: ../src/core/all-keybindings.h:347 -msgid "Move window one workspace to the right" -msgstr "Pindahkan jendela ke area kerja kanan" - -#: ../src/core/all-keybindings.h:350 -msgid "Move window one workspace up" -msgstr "Pindahkan jendela ke area kerja atas" - -#: ../src/core/all-keybindings.h:353 -msgid "Move window one workspace down" -msgstr "Pindahkan jendela ke area kerja bawah" - -#: ../src/core/all-keybindings.h:356 -msgid "Raise window if it's covered by another window, otherwise lower it" -msgstr "Naikkan jendela bila tertutup jendela lain, sebaliknya diturunkan" - -#: ../src/core/all-keybindings.h:358 +#: data/50-mutter-windows.xml:31 msgid "Raise window above other windows" msgstr "Naikkan jendela di atas jendela-jendela lain" -#: ../src/core/all-keybindings.h:360 +#: data/50-mutter-windows.xml:33 msgid "Lower window below other windows" -msgstr "Turunkan jendela di bawah jendela lain" +msgstr "Turunkan jendela di bawah jendela-jendela lain" -#: ../src/core/all-keybindings.h:364 +#: data/50-mutter-windows.xml:35 msgid "Maximize window vertically" msgstr "Maksimalkan ukuran jendela secara vertikal" -#: ../src/core/all-keybindings.h:368 +#: data/50-mutter-windows.xml:37 msgid "Maximize window horizontally" msgstr "Maksimalkan ukuran jendela secara horisontal" -#: ../src/core/all-keybindings.h:372 -msgid "Move window to north-west (top left) corner" -msgstr "Pindahkan jendela ke sudut kiri atas" - -#: ../src/core/all-keybindings.h:375 -msgid "Move window to north-east (top right) corner" -msgstr "Pindahkan jendela ke sudut kanan atas" - -#: ../src/core/all-keybindings.h:378 -msgid "Move window to south-west (bottom left) corner" -msgstr "Pindahkan jendela ke sudut kiri bawah" - -#: ../src/core/all-keybindings.h:381 -msgid "Move window to south-east (bottom right) corner" -msgstr "Pindahkan jendela ke sudut kanan bawah" - -#: ../src/core/all-keybindings.h:385 -msgid "Move window to north (top) side of screen" -msgstr "Pindahkan jendela ke sisi atas layar" - -#: ../src/core/all-keybindings.h:388 -msgid "Move window to south (bottom) side of screen" -msgstr "Pindahkan jendela ke sisi bawah layar" - -#: ../src/core/all-keybindings.h:391 -msgid "Move window to east (right) side of screen" -msgstr "Pindahkan jendela ke sisi kanan layar" - -#: ../src/core/all-keybindings.h:394 -msgid "Move window to west (left) side of screen" -msgstr "Pindahkan jendela ke sisi kiri layar" - -#: ../src/core/all-keybindings.h:397 -msgid "Move window to center of screen" -msgstr "Pindahkan jendela ke tengah layar" - -#: ../src/core/bell.c:310 -msgid "Bell event" -msgstr "Bel peristiwa" - -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Permintaan informasi jendela tak dikenal: %d" - -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> tidak merespon." - -#: ../src/core/delete.c:114 -#| msgid "<tt>%s</tt> is not responding." -msgid "Application is not responding." -msgstr "Aplikasi tidak merespon." - -#: ../src/core/delete.c:119 -msgid "You may choose to wait a short while for it to continue or force the application to quit entirely." -msgstr "Anda bisa memilih untuk menunggu sebentar atau memaksa aplikasi keluar." - -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "_Tunggu" - -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "_Matikan Paksa" +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "Tilik belah di kiri" -#: ../src/core/display.c:365 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "Kehilangan ekstensi %s yang diperlukan untuk pengkomposisian" +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "Tilik belah di kanan" -#: ../src/core/display.c:431 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Gagal membuka tampilan X Window System '%s'\n" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" -#: ../src/core/keybindings.c:759 -#, c-format -msgid "Some other program is already using the key %s with modifiers %x as a binding\n" -msgstr "Ada program lain yang menggunakan tombol %s dengan kombinasi %x\n" +#: data/org.gnome.mutter.gschema.xml.in:7 +msgid "Modifier to use for extended window management operations" +msgstr "Tombol yang digunakan untuk memperluas operasi manajemen jendela" -#. Displayed when a keybinding which is -#. * supposed to launch a program fails. -#. -#: ../src/core/keybindings.c:2523 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:8 msgid "" -"There was an error running <tt>%s</tt>:\n" -"\n" -"%s" +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." msgstr "" -"Ada galat saat menjalankan <tt>%s</tt>:\n" -"\n" -"%s." - -#: ../src/core/keybindings.c:2613 -#, c-format -msgid "No command %d has been defined.\n" -msgstr "Tidak ada perintah %d.\n" - -#: ../src/core/keybindings.c:3625 -#, c-format -msgid "No terminal command has been defined.\n" -msgstr "Tidak ada perintah untuk menjalankan terminal.\n" - -#: ../src/core/main.c:206 -msgid "Disable connection to session manager" -msgstr "Menonaktifkan koneksi ke manajer sesi" - -#: ../src/core/main.c:212 -msgid "Replace the running window manager" -msgstr "Mengganti manajer jendela yang tengah berjalan" - -#: ../src/core/main.c:218 -msgid "Specify session management ID" -msgstr "Tentukan kode pengaturan sesi" +"Kunci ini akan mengawali \"overlay\", yang merupakan kombinasi ringkasan " +"jendela dan sistem peluncuran aplikasi. Nilai baku ditujukan agar menjadi " +"\"tombol Windows\" pada perangkat keras PC. Diharapkan agar pengikatan ini " +"berupa baku atau diisi dengan kalimat kosong." -#: ../src/core/main.c:223 -msgid "X Display to use" -msgstr "Tampilan X yang digunakna" - -#: ../src/core/main.c:229 -msgid "Initialize session from savefile" -msgstr "Aktifkan sesi dari berkas simpanan" - -#: ../src/core/main.c:235 -msgid "Make X calls synchronous" -msgstr "Buat panggilan X selaras" - -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Gagal memeriksa direktori tema: %s\n" - -#: ../src/core/main.c:520 -#, c-format -msgid "Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "Tak menemukan tema! Pastikan %s ada dan berisi tema yang biasa.\n" +#: data/org.gnome.mutter.gschema.xml.in:20 +msgid "Attach modal dialogs" +msgstr "Lampirkan dialog modal" -#: ../src/core/muffin.c:42 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:21 msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." msgstr "" -"muffin %s\n" -"Hak cipta (C) 2001-%d Havoc Pennington, Red Hat, Inc., dan lain-lain.\n" -"Ini adalah perangkat lunak bebas; lihatlah kode sumbernya untuk kondisi penyalinan.\n" -"TIDAK ADA jaminan, bahkan untuk KELAYAKAN JUAL atau KELAYAKAN UNTUK KEGUNAAN TERTENTU.\n" - -#: ../src/core/muffin.c:56 -msgid "Print version" -msgstr "Cetak versi" - -#: ../src/core/muffin.c:62 -msgid "Comma-separated list of compositor plugins" -msgstr "Daftar kompositor pengaya yang dipisahkan koma" - -#. -#. * We found it, but it was invalid. Complain. -#. * -#. * FIXME: This replicates the original behaviour, but in the future -#. * we might consider reverting invalid keys to their original values. -#. * (We know the old value, so we can look up a suitable string in -#. * the symtab.) -#. * -#. * (Empty comment follows so the translators don't see this.) -#. -#. -#: ../src/core/prefs.c:550 ../src/core/prefs.c:711 -#, c-format -msgid "GConf key '%s' is set to an invalid value\n" -msgstr "Key GConf '%s' bernilai salah\n" - -#: ../src/core/prefs.c:637 ../src/core/prefs.c:880 -#, c-format -msgid "%d stored in GConf key %s is out of range %d to %d\n" -msgstr "%d yang disimpan pada kunci GConf %s berada di luar jangkauan %d hingga %d\n" - -#: ../src/core/prefs.c:681 ../src/core/prefs.c:758 ../src/core/prefs.c:806 -#: ../src/core/prefs.c:870 ../src/core/prefs.c:1331 ../src/core/prefs.c:1347 -#: ../src/core/prefs.c:1364 ../src/core/prefs.c:1380 -#, c-format -msgid "GConf key \"%s\" is set to an invalid type\n" -msgstr "Key \"%s\" GConf tipenya salah\n" - -#: ../src/core/prefs.c:1210 -#, c-format -msgid "GConf key %s is already in use and can't be used to override %s\n" -msgstr "Kunci GConf %s sudah dipakai dan tidak bisa digunakan lagi untuk menimpa %s\n" - -#: ../src/core/prefs.c:1269 -#, c-format -msgid "Can't override GConf key, %s not found\n" -msgstr "Tidak dapat menimpa kunci GConf, %s tidak ditemukan\n" - -#: ../src/core/prefs.c:1454 -msgid "Workarounds for broken applications disabled. Some applications may not behave properly.\n" -msgstr "Pencegahan kesalahan bagi aplikasi yang rusak sedang dinonaktifkan. Mungkin nanti ada beberapa aplikasi yang akan bertingkah aneh.\n" - -#: ../src/core/prefs.c:1531 -#, c-format -msgid "Could not parse font description \"%s\" from GConf key %s\n" -msgstr "Tidak dapat membaca deskripsi fonta \"%s\" dari key GConf %s\n" - -#: ../src/core/prefs.c:1593 -#, c-format -msgid "\"%s\" found in configuration database is not a valid value for mouse button modifier\n" -msgstr "\"%s\" yang ada pada database konfigurasi bukanlah nilai yang benar untuk tombol mouse.\n" - -#: ../src/core/prefs.c:2028 -#, c-format -msgid "Error setting number of workspaces to %d: %s\n" -msgstr "Ada error saat mengeset jumlah area kerja menjadi %d: %s\n" - -#: ../src/core/prefs.c:2212 ../src/core/prefs.c:2714 -#, c-format -msgid "Workspace %d" -msgstr "Area kerja %d" - -#: ../src/core/prefs.c:2244 ../src/core/prefs.c:2422 -#, c-format -msgid "\"%s\" found in configuration database is not a valid value for keybinding \"%s\"\n" -msgstr "\"%s\" yang ada pada database konfigurasi bernilai tidak benar untuk kombinasi tombol \"%s\"\n" - -#: ../src/core/prefs.c:2795 -#, c-format -msgid "Error setting name for workspace %d to \"%s\": %s\n" -msgstr "Ada error saat melakukan seting nama workspace %d ke \"%s\": %s\n" - -#: ../src/core/prefs.c:3009 -#, c-format -msgid "Error setting live hidden windows status status: %s\n" -msgstr "Galat ketika menyetel status jendela tersembunyi: %s\n" - -#: ../src/core/prefs.c:3044 -#, c-format -msgid "Error setting no tab popup status: %s\n" -msgstr "Galat ketika menyetel status popup tanpa tab: %s\n" - -#: ../src/core/screen.c:663 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "Layar %d pada tampilan '%s' tidak benar\n" - -#: ../src/core/screen.c:679 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager; try using the --replace option to replace the current window manager.\n" -msgstr "Layar %d pada tampilan \"%s\" sudah memiliki pengatur jendela. Cobalah gunakan pilihan --replace untuk mengganti pengatur jendela yang aktif.\n" - -#: ../src/core/screen.c:706 -#, c-format -msgid "Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "Tidak dapat mendapatkan pilihan pengatur jendela pada layar %d tampilan \"%s\"\n" - -#: ../src/core/screen.c:761 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "Layar %d pada tampilan \"%s\" sudah ada pengatur jendelanya\n" - -#: ../src/core/screen.c:946 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "Layar %d pada tampilan \"%s\" tidak dapat dilepas\n" - -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Tidak dapat membuat direktori '%s': %s\n" - -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "Tidak dapat menulis ke dalam berkas sesi '%s': %s\n" - -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Ada error saat menulisi berkas sesi '%s': %s\n" - -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Ada error saat menutup berkas sesi '%s': %s\n" - -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Gagal membaca berkas sesi simpanan: %s\n" - -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "Atribut <muffin_session> terlihat tapi kode sesi sudah ada sebelumnya" - -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Atribut %s tidak dikenal pada elemen <%s>" - -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "Ada tag <window> bersarang" - -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "Elemen %s tidak dikenal" - -#: ../src/core/session.c:1809 -msgid "These windows do not support "save current setup" and will have to be restarted manually next time you log in." -msgstr "Jendela ini tidak bisa "menyimpan setelan aktif saat ini" dan bila log masuk kali lain Anda harus menjalankannya ulang." - -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Gagal membuka log debug: %s\n" - -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Gagal melakukan fdopen pada berkas log %s: %s\n" - -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "Berkas log yang dibuka %s\n" - -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "Muter dikompilasi tanpa dukungan mode riuh\n" - -#: ../src/core/util.c:286 -msgid "Window manager: " -msgstr "Pengatur jendela: " +"Jika bernilai \"true\", maka dialog modal akan muncul menempel pada baris " +"judul jendela utama dan bergerak seiring perpindahan jendela utama tersebut." -#: ../src/core/util.c:434 -msgid "Bug in window manager: " -msgstr "Bug pada pengatur jendela: " +#: data/org.gnome.mutter.gschema.xml.in:30 +msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "Fungsikan pengubinan tepi ketika menjatuhkan jendela ke tepi layar" -#: ../src/core/util.c:467 -msgid "Window manager warning: " -msgstr "Peringatan pengatur jendela: " - -#: ../src/core/util.c:495 -msgid "Window manager error: " -msgstr "Eror pengatur jendela: " - -#. Translators: This is the title used on dialog boxes -#: ../src/core/util.c:632 ../src/muffin.desktop.in.h:1 -#: ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" - -#. first time through -#: ../src/core/window.c:6959 -#, c-format -msgid "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER window as specified in the ICCCM.\n" -msgstr "Jendela %s menyetel SM_CLIENT_ID pada dirinya sendiri, padahal seharusnya disetel pada jendela WM_CLIENT_LEADER sesuai aturan ICCCM.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7622 -#, c-format -msgid "Window %s sets an MWM hint indicating it isn't resizable, but sets min size %d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "Jendela %s menyetel hint MWM yang menandakan bahwa ia tidak dapat dirubah ukurannya, sedangkan ukuran minimalnya adalah %d x %d dan maksimal %d x %d yang tidak masuk di akal.\n" - -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "Aplikasi telah membuat _NET_WM_PID %lu bohongan\n" - -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (pada %s)" - -#: ../src/core/window-props.c:1488 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "WM_TRANSIENT_FOR salah jendela 0x%lx ditentukan untuk %s.\n" - -#: ../src/core/window-props.c:1500 -#, c-format -#| msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "Jendela WM_TRANSIENT_FOR 0x%lx untuk %s akan membuat loop.\n" - -#: ../src/core/xprops.c:155 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:31 msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." msgstr "" -"Jendela 0x%lx memiliki properti %s\n" -"yang seharusnya memiliki tipe %s format %d.\n" -"Sekarang dia memiliki tipe %s format %d n_items %d.\n" -"Sepertinya ini adalah bug aplikasinya, bukan bug pengatur jendela.\n" -"Judul jendelanya adalah \"%s\" class=\"%s\" dan bernama=\"%s\"\n" - -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "Properti %s pada jendela 0x%lx berisi karakter UTF-8 yang salah\n" +"Bila difungsikan, menjatuhkan jendela pada tepi vertikal layar akan " +"memaksimalkan mereka pada arah vertikal dan mengubah ukuran horisontalnya " +"menutupi separuh dari area yang tersedia. Menjatuhkan jendela pada tepi atas " +"layar akan memaksimalkan mereka sepenuhnya." -#: ../src/core/xprops.c:494 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "Properti %s pada jendela 0x%lx di obyek %d berisi karakter UTF-8 yang salah\n" - -#: ../src/muffin.schemas.in.h:1 -msgid "Attach modal dialogs" -msgstr "Lampirkan dialog modal" +#: data/org.gnome.mutter.gschema.xml.in:40 +msgid "Workspaces are managed dynamically" +msgstr "Ruang kerja dikelola secara dinamis" -#: ../src/muffin.schemas.in.h:2 -msgid "Determines whether hidden windows (i.e., minimized windows and windows on other workspaces than the current one) should be kept alive." -msgstr "Menentukan apakah jendela yang tersembunyi (cth. jendela yang dikecilkan dan jendela pada area kerja lain) tetap hidup/dipertahankan." - -#: ../src/muffin.schemas.in.h:3 -msgid "Determines whether workspace switching should happen for windows on all monitors or only for windows on the primary monitor." -msgstr "Menentukan apakah perpindahan area kerja hanya terjadi pada jendela aplikasi di semua monitor atau hanya untuk jendela pada monitor utama." - -#: ../src/muffin.schemas.in.h:4 -msgid "Draggable border width" -msgstr "Lebar batas yang dapat diseret" - -#: ../src/muffin.schemas.in.h:5 -msgid "Live Hidden Windows" -msgstr "Kelangsungan Jendela Tersembunyi" - -#: ../src/muffin.schemas.in.h:6 -msgid "Modifier to use for extended window management operations" -msgstr "Tombol yang digunakan untuk memperluas operasi manajemen jendela" - -#: ../src/muffin.schemas.in.h:7 -msgid "The amount of total draggable borders. If the theme's visible borders are not enough, invisible borders will be added to meet this value." -msgstr "Total banyaknya tepi yang dapat diseret. Bila tepi tema yang nampak tak cukup, tepi tak nampak akan ditambahkan untuk memenuhi nilai ini." - -#: ../src/muffin.schemas.in.h:8 -msgid "This key will initiate the \"overlay\", which is a combination window overview and application launching system. The default is intended to be the \"Windows key\" on PC hardware. It's expected that this binding either the default or set to the empty string." -msgstr "Kunci ini akan mengawali \"overlay\", yang merupakan kombinasi ringkasan jendela dan sistem peluncuran aplikasi. Nilai baku ditujukan agar menjadi \"Windows key\" pada perangkat keras PC. Diharapkan agar pengikatan ini berupa baku atau diisi dengan kalimat kosong." - -#: ../src/muffin.schemas.in.h:9 -msgid "When true, instead of having independent titlebars, modal dialogs appear attached to the titlebar of the parent window and are moved together with the parent window." -msgstr "Jika bernilai \"true\", maka dialog modal akan muncul menempel pada baris judul jendela utama dan bergerak seiring perpindahan jendela utama tersebut." +#: data/org.gnome.mutter.gschema.xml.in:41 +msgid "" +"Determines whether workspaces are managed dynamically or whether there’s a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." +msgstr "" +"Menentukan apakah ruang kerja dikelola secara dinamis atau apakah ada " +"sejumlah tetap ruang kerja (ditentukan oleh kunci num-workspaces dalam org." +"gnome.desktop.wm.preferences)." -#: ../src/muffin.schemas.in.h:10 +#: data/org.gnome.mutter.gschema.xml.in:50 msgid "Workspaces only on primary" msgstr "Ruang kerja hanya pada primer" -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "Cara pakai: %s\n" - -#: ../src/ui/frames.c:1123 -msgid "Close Window" -msgstr "Tutup Jendela" - -#: ../src/ui/frames.c:1126 -msgid "Window Menu" -msgstr "Menu Jendela" - -#: ../src/ui/frames.c:1129 -msgid "Minimize Window" -msgstr "Kecilkan Jendela" - -#: ../src/ui/frames.c:1132 -msgid "Maximize Window" -msgstr "Maksimalkan Ukuran Jendela" - -#: ../src/ui/frames.c:1135 -msgid "Restore Window" -msgstr "Kembalikan Ukuran jendela" - -#: ../src/ui/frames.c:1138 -msgid "Roll Up Window" -msgstr "Menggulung Jendela" - -#: ../src/ui/frames.c:1141 -msgid "Unroll Window" -msgstr "Tidak Menggulung Jendela" - -#: ../src/ui/frames.c:1144 -msgid "Keep Window On Top" -msgstr "Jaga Jendela Di Atas" - -#: ../src/ui/frames.c:1147 -msgid "Remove Window From Top" -msgstr "Hapus Jendela Dari Atas" - -#: ../src/ui/frames.c:1150 -msgid "Always On Visible Workspace" -msgstr "Selalu di Area Kerja Tampak" - -#: ../src/ui/frames.c:1153 -msgid "Put Window On Only One Workspace" -msgstr "Menempatkan Jendela Hanya di Satu Area Kerja" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "Kecilka_n" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "Pe_rbesar" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "Kem_balikan" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "G_ulung" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "B_uka" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "_Pindahkan" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "Ganti·Uku_ran" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "Pindahkan Judul Pada _layar" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "Selalu di A_tas" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "T_ampak pada Area Kerja Aktif" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "_Tampak pada Area Kerja Ini Saja" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "Pindahkan ke Area Kerja _Kiri" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "Pindahkan ke A_rea Kerja Kanan" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "Pindahkan ke Area Kerja Ata_s" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "Pindahkan ke Area Kerja _Bawah" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "_Tutup" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "Area Kerja %d%n" - -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "Area Kerja 1_0" - -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "Area Kerja %s%d" - -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "Pindahkan ke Area Kerja _Lain" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hiper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" - -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" - -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "atas" - -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "bawah" - -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "kiri" - -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "kanan" - -#: ../src/ui/theme.c:286 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "ukuran frame tidak menyebutkan dimensi \"%s\"" - -#: ../src/ui/theme.c:305 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "ukuran frame tidak menyebutkan dimensi \"%s\" untuk batas \"%s\"" - -#: ../src/ui/theme.c:342 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "Aspek rasio tombol %g tidak wajar" - -#: ../src/ui/theme.c:354 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "Ukuran frame tidak menyebutkan ukuran tombol" - -#: ../src/ui/theme.c:1060 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "Gradien harus paling tidak ada dua warna" - -#: ../src/ui/theme.c:1205 -#, c-format -#| msgid "" -#| "GTK color specification must have a close bracket after the state, e.g. " -#| "gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgid "GTK custom color specification must have color name and fallback in parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" -msgstr "Spesifikasi warna ubahan GTK mesti memiliki nama warna dan cadangan dalam kurung, mis. gtk:custom(foo,bar); tak bisa mengurai \"%s\"" - -#: ../src/ui/theme.c:1221 -#, c-format -msgid "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-_ are valid" -msgstr "Karakter tak valid '%c' dalam parameter color_name dari gtk:custom, hanya A-Za-z0-9-_ yang valid" - -#: ../src/ui/theme.c:1235 -#, c-format -#| msgid "" -#| "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the " -#| "format" -msgid "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not fit the format" -msgstr "Format Gtk:custom adalah \"gtk:custom(color_name,fallback)\", \"%s\" tak memenuhi format" - -#: ../src/ui/theme.c:1271 -#, c-format -msgid "GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "Spesifikasi warna GTK harus memiliki kondisi pada kurung, misal gtk:fg[NORMAL] dengan NORMAL adalah jenis kondisinya, tidak dapat membaca \"%s\"" - -#: ../src/ui/theme.c:1285 -#, c-format -msgid "GTK color specification must have a close bracket after the state, e.g. gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "Spesifikasi warna GTK harus memiliki kurung tutup pada kondisinya, misal gtk:fg[NORMAL] dengan NORMAL adalah jenis kondisinya, tidak dapat membaca \"%s\"" - -#: ../src/ui/theme.c:1296 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "Kondisi \"%s\" tidak benar pada spesifikasi warna" +#: data/org.gnome.mutter.gschema.xml.in:51 +msgid "" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." +msgstr "" +"Menentukan apakah perpindahan area kerja hanya terjadi pada jendela aplikasi " +"di semua monitor atau hanya untuk jendela pada monitor utama." -#: ../src/ui/theme.c:1309 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "Komponen warna \"%s\" tidak benar pada spesifikasi warna" +#: data/org.gnome.mutter.gschema.xml.in:59 +msgid "No tab popup" +msgstr "Tak ada popup tab" -#: ../src/ui/theme.c:1339 -#, c-format -msgid "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the format" -msgstr "Format pencampuran adalah \"blend/bg_color/fg_color/alpha\", \"%s\" bukan ditulis dalam format yang benar" +#: data/org.gnome.mutter.gschema.xml.in:60 +msgid "" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." +msgstr "" +"Menentukan apakah penggunaan popup dan rangka penyorot mesti dimatikan bagi " +"perputaran jendela." -#: ../src/ui/theme.c:1350 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "Tidak dapat membaca nilai alpha \"%s\" pada pencampuran warna" +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Tunda perubahan fokus sampai penunjuk berhenti bergerak" -#: ../src/ui/theme.c:1360 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "Nilai alpha \"%s\" pada warna yang dicampur tidak ada dalam rentang 0.0 dan 1.0" - -#: ../src/ui/theme.c:1407 -#, c-format -msgid "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "Format bayangan adalah \"shade/base_color/factor\", \"%s\" ditulis dalam format yang keliru" +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" +"Bila diisi dengan true, dan mode fokus adalah \"sloppy\" atau \"mouse\" maka " +"fokus tak akan berubah seketika saat memasuki suatu jendela, tapi hanya " +"setelah penunjuk berhenti bergerak." -#: ../src/ui/theme.c:1418 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "Tidak dapat membaca faktor bayangan \"%s\" pada warna berbayang" +#: data/org.gnome.mutter.gschema.xml.in:79 +msgid "Draggable border width" +msgstr "Lebar batas yang dapat diseret" -#: ../src/ui/theme.c:1428 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "Faktor bayangan \"%s\" pada warna berbayang bernilai negatif" +#: data/org.gnome.mutter.gschema.xml.in:80 +msgid "" +"The amount of total draggable borders. If the theme’s visible borders are " +"not enough, invisible borders will be added to meet this value." +msgstr "" +"Total banyaknya tepi yang dapat diseret. Bila tepi tema yang nampak tak " +"cukup, tepi tak nampak akan ditambahkan untuk memenuhi nilai ini." -#: ../src/ui/theme.c:1457 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Tidak dapat membaca warna \"%s\"" +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "Memaksimalkan otomatis hampir memantau jendela yang ditata ukurannya" -#: ../src/ui/theme.c:1768 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "Ekspresi koordinat berisi karakter '%s' yang tidak diperbolehkan" +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" +"Bila difungsikan, jendela baru yang awalnya seukuran monitor secara otomatis " +"dimaksimalkan." -#: ../src/ui/theme.c:1795 -#, c-format -msgid "Coordinate expression contains floating point number '%s' which could not be parsed" -msgstr "Ekspresi koordinat berisi angka floating point '%s' yang tidak dapat dibaca" +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Tempatkan jendela baru di tengah" -#: ../src/ui/theme.c:1809 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "Ekspresi koordinat berisi integer '%s' yang tidak dapat dibaca" +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" +"Ketika berisi true, jendela baru akan selalu diletakkan di tengah dari layar " +"aktif dari monitor." -#: ../src/ui/theme.c:1931 -#, c-format -msgid "Coordinate expression contained unknown operator at the start of this text: \"%s\"" -msgstr "Ekspresi koordinat berisi operator tak dikenal pada awal teks berikut: \"%s\"" +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Aktifkan fitur eksperimental" -#: ../src/ui/theme.c:1988 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "Ekspresi koordinat kosong atau tidak dapat dimengerti" +#: data/org.gnome.mutter.gschema.xml.in:108 +msgid "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes " +"mutter request a low priority real-time scheduling. The executable or user " +"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — " +"initializes Xwayland lazily if there are X11 clients. Requires restart." +msgstr "" +"Untuk mengaktifkan fitur eksperimental, tambahkan kata kunci fitur ke dalam " +"daftar. Apakah fitur memerlukan nyala ulang kompositor tergantung pada fitur " +"yang diberikan. Setiap fitur eksperimental tidak diharuskan tetap tersedia, " +"atau dapat dikonfigurasi. Jangan berharap menambahkan apapun dalam " +"pengaturan ini kebal perubahan di masa depan. Saat ini kata kunci yang " +"mungkin: • “scale-monitor-framebuffer” — membuat bawaan mutter untuk tata " +"letak monitor logikal dalam ruang koordinat pixel logikal, sambil " +"menskalakan framebuffer monitor alih-alih konten jendela, untuk mengelola " +"monitor HiDPI. Tidak perlu nyala ulang. • \"rt-scheduler\" — membuat mutter " +"meminta jadwal waktu sebenarnya prioritas rendah. Yang dapat dieksekusi atau " +"pengguna harus memiliki CAP_SYS_NICE. Membutuhkan nyala ulang. • “autostart-" +"xwayland” — menginisialisasi Xwayland dengan malas jika ada klien X11. " +"Membutuhkan nyala ulang." + +#: data/org.gnome.mutter.gschema.xml.in:134 +msgid "Modifier to use to locate the pointer" +msgstr "Pengubah yang digunakan untuk menemukan penunjuk" + +#: data/org.gnome.mutter.gschema.xml.in:135 +msgid "This key will initiate the “locate pointer” action." +msgstr "Kunci ini akan memulai aksi \"penunjuk lokasi\"." + +#: data/org.gnome.mutter.gschema.xml.in:142 +msgid "Timeout for check-alive ping" +msgstr "Batas waktu untuk ping pemeriksaan hidup" + +#: data/org.gnome.mutter.gschema.xml.in:143 +msgid "" +"Number of milliseconds a client has to respond to a ping request in order to " +"not be detected as frozen. Using 0 will disable the alive check completely." +msgstr "" +"Banyaknya milidetik yang harus diselesaikan klien terhadap permintaan ping " +"agar tidak terdeteksi sebagai beku. Menggunakan 0 akan menonaktifkan " +"pemeriksaan hidup sepenuhnya." -#: ../src/ui/theme.c:2099 ../src/ui/theme.c:2109 ../src/ui/theme.c:2143 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "Ekspresi koordinat menghasilkan pembagian dengan nol" +#: data/org.gnome.mutter.gschema.xml.in:165 +msgid "Select window from tab popup" +msgstr "Pilih jendela dari popup tab" -#: ../src/ui/theme.c:2151 -#, c-format -msgid "Coordinate expression tries to use mod operator on a floating-point number" -msgstr "Ekspresi koordinat menggunakan operator mod pada angka bilangan nyata" +#: data/org.gnome.mutter.gschema.xml.in:170 +msgid "Cancel tab popup" +msgstr "Batalkan popup tab" -#: ../src/ui/theme.c:2207 -#, c-format -msgid "Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "Ekspresi koordinat menggunakan operator \"%s\" tanpa adanya operan" +#: data/org.gnome.mutter.gschema.xml.in:175 +msgid "Switch monitor configurations" +msgstr "Tukar konfigurasi monitor bawaan" -#: ../src/ui/theme.c:2216 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "Ekspresi koordinat menggunakan operand tanpa operator" +#: data/org.gnome.mutter.gschema.xml.in:180 +msgid "Rotates the built-in monitor configuration" +msgstr "Memutar konfigurasi monitor bawaan" -#: ../src/ui/theme.c:2224 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "Ekspresi koordinat diakhiri dengan operator, seharusnya diakhiri dengan operand" +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Bertukar ke VT 1" -#: ../src/ui/theme.c:2234 -#, c-format -msgid "Coordinate expression has operator \"%c\" following operator \"%c\" with no operand in between" -msgstr "Ekspresi koordinat memiliki operator \"%c\" diikuti operator \"%c\" tanpa adanya operand di antarany" +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Bertukar ke VT 2" -#: ../src/ui/theme.c:2385 ../src/ui/theme.c:2430 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "Ada variabel atau konstanta \"%s\" tidak diketahui pada ekspresi koordinat" +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Bertukar ke VT 3" -#: ../src/ui/theme.c:2484 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "Ekspresi koordinat melampaui batasannya." +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Bertukar ke VT 4" -#: ../src/ui/theme.c:2513 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "Terdapat kurung tutup tanpa kurung buka pada ekspresi koordinat" +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Bertukar ke VT 5" -#: ../src/ui/theme.c:2577 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "Terdapat kurung buka tanpa kurung tutup pada ekspresi koordinat " +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Bertukar ke VT 6" -#: ../src/ui/theme.c:2588 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "Ekspresi koordinat sepertinya tidak memiliki operator atau operan" +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Bertukar ke VT 7" -#: ../src/ui/theme.c:2800 ../src/ui/theme.c:2820 ../src/ui/theme.c:2840 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "Tema mengandung ekspresi yang menghasilkan galat: %s\n" +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Bertukar ke VT 8" -#: ../src/ui/theme.c:4511 -#, c-format -msgid "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be specified for this frame style" -msgstr "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> tidak disebutkan pada gaya frame ini" +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Bertukar ke VT 9" -#: ../src/ui/theme.c:5044 ../src/ui/theme.c:5069 -#, c-format -msgid "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "<frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/> tidak ada" +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Bertukar ke VT 10" -#: ../src/ui/theme.c:5117 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Gagal membuka tema \"%s\": %s\n" +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Bertukar ke VT 11" -#: ../src/ui/theme.c:5253 ../src/ui/theme.c:5260 ../src/ui/theme.c:5267 -#: ../src/ui/theme.c:5274 ../src/ui/theme.c:5281 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "Tidak ada <%s> yang ditentukan untuk tema \"%s\"" +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Bertukar ke VT 12" -#: ../src/ui/theme.c:5289 -#, c-format -msgid "No frame style set for window type \"%s\" in theme \"%s\", add a <window type=\"%s\" style_set=\"whatever\"/> element" -msgstr "Tidak ada gaya frame untuk tipe window \"%s\" pada tema \"%s\". Tambah dulu elemen <window type=\"%s\" style_set=\"whatever\"/>" +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "Aktifkan kembali pintasan" -#: ../src/ui/theme.c:5728 ../src/ui/theme.c:5790 ../src/ui/theme.c:5853 -#, c-format -msgid "User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "Konstanta buatan pengguna harus dimulai dengan huruf besar: \"%s\" tidak" +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow X11 grabs to lock keyboard focus with Xwayland" +msgstr "Izinkan X11 menggenggam untuk mengunci fokus papan tik dengan Xwayland" -#: ../src/ui/theme.c:5736 ../src/ui/theme.c:5798 ../src/ui/theme.c:5861 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "Konstanta \"%s\" telah didefinisikan sebelumnya" +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 +msgid "" +"Allow all keyboard events to be routed to X11 “override redirect” windows " +"with a grab when running in Xwayland. This option is to support X11 clients " +"which map an “override redirect” window (which do not receive keyboard " +"focus) and issue a keyboard grab to force all keyboard events to that " +"window. This option is seldom used and has no effect on regular X11 windows " +"which can receive keyboard focus under normal circumstances. For a X11 grab " +"to be taken into account under Wayland, the client must also either send a " +"specific X11 ClientMessage to the root window or be among the applications " +"white-listed in key “xwayland-grab-access-rules”." +msgstr "" +"Izinkan semua peristiwa papan tik dialihkan ke jendela X11 \"override " +"redirect\" dengan perambanan saat berjalan di Xwayland. Opsi ini adalah " +"untuk mendukung klien X11 yang memetakan jendela \"override redirect\" (yang " +"tidak menerima fokus papan tik) dan mengeluarkan pegangan papan tik untuk " +"memaksa semua peristiwa papan tik ke jendela itu. Opsi ini jarang digunakan " +"dan tidak berpengaruh pada jendela X11 biasa yang dapat menerima fokus papan " +"tik dalam keadaan normal. Agar pengambilan X11 diperhitungkan di bawah " +"Wayland, klien juga harus mengirim PesanKlien X11 tertentu ke jendela root " +"atau di antara aplikasi yang masuk dalam daftar putih “xwayland-grab-access-" +"rules”." + +#: data/org.gnome.mutter.wayland.gschema.xml.in:84 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "" +"Aplikasi Xwayland yang diizinkan untuk mengeluarkan pengambilalihan papan " +"ketik" -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. +#: data/org.gnome.mutter.wayland.gschema.xml.in:85 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "" +"Buat daftar nama sumber daya atau kelas sumber daya dari jendela X11 yang " +"diizinkan atau tidak diizinkan untuk melakukan pengambilalihan papan ketik " +"X11 di bawah Xwayland. Nama sumber daya atau kelas sumber daya dari jendela " +"X11 yang diberikan dapat diperoleh memakai perintah \"xprop WM_CLASS\". " +"Wildcard \"*\" dan joker \"?\" dalam nilai didukung. Nilai yang dimulai " +"dengan \"!\" masuk daftar hitam, yang punya preseden atas daftar putih, " +"untuk mencabut aplikasi dari daftar sistem bawaan. Daftar sistem bawaan " +"termasuk aplikasi-aplikasi berikut: \"@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@" +"\". Pengguna dapat memutus pengambilalihan yang ada dengan memakai pintasan " +"papan ketik spesifik yang didefinisikan oleh tombol pengikatan \"restore-" +"shortcuts\"." + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. #. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "Tidak ada atribut \"%s\" pada elemen <%s>" - -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Baris %d karakter %d: %s" - -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "Atribut \"%s\" diulangi dua kali pada elemen <%s> yang sama" - -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "Atribut \"%s\" tidak diperkenankan pada elemen <%s> pada konteks ini" - -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "Tidak dapat menguraikan \"%s\" sebagai integer" - -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "Tidak mengerti karakter \"%s\" kenapa ada dibuntut string \"%s\"" - -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "Integer %ld harus bernilai positif" - -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "Integer %ld terlalu besar, maksimal %d" - -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "Tidak dapat membaca \"%s\" sebagai angka floating point" - -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "Nilai boolean harus \"true\" atau \"false\" dan bukannya \"%s\"" - -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "Sudut harus ada dalam rentang 0.0 dan 360.0, dalam berkas didapat %g\n" - -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "Alpha harus ada dalam rentang 0.0 (tidak kelihatan) dan 1.0 (nampak semua, dalam berkas didapat %g\n" - -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium,large,x-large,xx-large)\n" -msgstr "Skala judul \"%s\" tidak benar (harusnya bernilai xx-small, x-small, small, medium, large, x-large, xx-large)\n" - -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "Nama <%s> \"%s\" digunakan kedua kali" - -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "Induk <%s> \"%s\" belum didefinisikan" - -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "Geometri <%s> \"%s\" belum didefinisikan" - -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "<%s> harus menentukan geometri atau induk yang ada geometrinya" - -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "Anda mesti menyatakan suatu latar belakang bagi nilai alfa agar berarti" - -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Tipe \"%s\" tidak dikenal pada elemen <%s>" - -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "style_set \"%s\" tidak dikenali pada elemen <%s>" - -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "Tipe jendela \"%s\" sudah memiliki set gaya" - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "Elemen <%s> tidak diperkenankan ada di bawah <%s>" - -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" for buttons" -msgstr "Tidak dapat menyatakan \"button_width\"/\"button_height\" dan \"aspect_ratio\" sekaligus untuk tombol" - -#: ../src/ui/theme-parser.c:1450 +#: src/backends/meta-input-settings.c:2567 #, c-format -msgid "Distance \"%s\" is unknown" -msgstr "Jarak \"%s\" tidak dikenal" +msgid "Mode Switch (Group %d)" +msgstr "Tukar Mode: (Grup %d)" -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "Rasio aspek \"%s\" tidak dikenal" - -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "Batas \"%s\" tidak dikenal" - -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "Tidak ada atribut \"start_angle\" atau \"from\" pada elemen <%s>" - -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "Tidak ada atribut \"extent_angle\" atau \"to\" pada elemen <%s>" - -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "Nilai \"%s\" bukan nilai yang sah untuk tipe gradien" - -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "Tipe isian \"%s\" tidak dikenal untuk elemen <%s>" - -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "Kondisi \"%s\" tidak dikenal untuk elemen <%s>" - -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "Bayangan \"%s\" tidak dikenal untuk elemen <%s>" - -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "Panah \"%s\" tidak dikenal untuk elemen <%s>" - -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "Tidak ada <draw_ops> bernama \"%s\" yang telah didefinisikan" - -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "Menyertakan draw_ops \"%s\" di sini akan membuat referensi tak berujung" - -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Posisi \"%s\" tidak dikenal untuk bagian frame" - -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "Gaya frame sudah memiliki bagian pada posisi %s" +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2590 +msgid "Switch monitor" +msgstr "Berpindah monitor" -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "Tidak ada <draw_ops> dengan nama \"%s\" yang didefinisikan" +#: src/backends/meta-input-settings.c:2592 +msgid "Show on-screen help" +msgstr "Tampilkan bantuan pada layar" -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Fungsi \"%s\" tidak dikenal untuk tombol" +#: src/backends/meta-monitor.c:223 +msgid "Built-in display" +msgstr "Tampilan bawaan" -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "Tombol fungsi \"%s\" tidak tersedia untuk versi ini (%d, memerlukan %d)" +#: src/backends/meta-monitor.c:252 +msgid "Unknown" +msgstr "Tak Dikenal" -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Kondisi \"%s\" tidak dikenal untuk tombol" +#: src/backends/meta-monitor.c:254 +msgid "Unknown Display" +msgstr "Tampilan Tak Dikenal" -#: ../src/ui/theme-parser.c:3002 +#: src/backends/meta-monitor.c:262 #, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "Gaya bingkai sudah memiliki tombol untuk fungsi %s kondisi %s" +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme-parser.c:3073 +#: src/backends/meta-monitor.c:270 #, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "\"%s\" bukan nilai yang benar untuk atribut focus" +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "\"%s\" bukan nilai yang benar untuk atribut state" +#. Translators: this string will appear in Sysprof +#: src/backends/meta-profiler.c:79 +msgid "Compositor" +msgstr "Kompositor" -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "Gaya bernama \"%s\" belum didefinisikan" - -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "\"%s\" bukan nilai yang benar untuk atribut resize" - -#: ../src/ui/theme-parser.c:3147 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:533 #, c-format -msgid "Should not have \"resize\" attribute on <%s> element for maximized/shaded states" -msgstr "Atribut \"resize\" tidak boleh ada pada elemen <%s> untuk kondisi ukuran window maksimum/tergulung" +msgid "" +"Another compositing manager is already running on screen %i on display “%s”." +msgstr "" +"Manajer komposit lain telah berjalan pada layar %i pada tampilan \"%s\"." -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "Atribut \"resize\" tidak boleh ada pada elemen <%s> untuk kondisi ukuran jendela maksimal" +#: src/core/bell.c:192 +msgid "Bell event" +msgstr "Bel peristiwa" -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "Gaya sudah menjelaskan kondisi %s resize %s focus %s" +#: src/core/main.c:190 +msgid "Disable connection to session manager" +msgstr "Menonaktifkan koneksi ke manajer sesi" -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "Gaya sudah menjelaskan kondisi %s focus %s" +#: src/core/main.c:196 +msgid "Replace the running window manager" +msgstr "Mengganti manajer jendela yang tengah berjalan" -#: ../src/ui/theme-parser.c:3294 -msgid "Can't have a two draw_ops for a <piece> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "Tidak boleh ada dua draw_ops untuk elemen <piece> (tema menyebutkan atribut draw_ops dan juga elemen <draw_ops> atau meyebutkan dua elemen tersebut " +#: src/core/main.c:202 +msgid "Specify session management ID" +msgstr "Tentukan kode pengaturan sesi" -#: ../src/ui/theme-parser.c:3332 -msgid "Can't have a two draw_ops for a <button> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "Tidak boleh ada dua draw_ops untuk elemen <button> (tema menyebutkan atribut draw_ops dan juga elemen <draw_ops> atau meyebutkan dua elemen tersebut " +#: src/core/main.c:207 +msgid "X Display to use" +msgstr "Tampilan X yang digunakna" -#: ../src/ui/theme-parser.c:3370 -msgid "Can't have a two draw_ops for a <menu_icon> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "Tidak boleh ada dua draw_ops untuk elemen <menu_icon> (tema menyebutkan atribut draw_ops dan juga elemen <draw_ops> atau meyebutkan dua elemen tersebut " +#: src/core/main.c:213 +msgid "Initialize session from savefile" +msgstr "Aktifkan sesi dari berkas simpanan" -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "Spesifikasi versi '%s' jelek" +#: src/core/main.c:219 +msgid "Make X calls synchronous" +msgstr "Buat panggilan X selaras" -#: ../src/ui/theme-parser.c:3507 -msgid "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-theme-2.xml" -msgstr "Atribut \"version\" tidak dapat dipakai dalam metacity-theme-1.xml atau metacity-theme-2.xml" +#: src/core/main.c:226 +msgid "Run as a wayland compositor" +msgstr "Jalankan sebagai kompositor wayland" -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "Tema memerlukan versi %s tetapi versi yang didukung adalah %d.%d" +#: src/core/main.c:232 +msgid "Run as a nested compositor" +msgstr "Jalankan sebagai kompositor bersarang" -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "Elemen tema paling luar haruslah <metacity_theme> dan bukan <%s>" +#: src/core/main.c:238 +msgid "Run wayland compositor without starting Xwayland" +msgstr "Jalankan kompositor wayland tanpa memmulai Xwayland" -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "Element <%s> is not allowed inside a name/author/date/description element" -msgstr "Elemen <%s> tidak diperbolehkan berada elemen name/author/date/description" +#: src/core/main.c:246 +msgid "Run as a full display server, rather than nested" +msgstr "Jalankan sebagai server tampilan penuh, ketimbang tampilan bersarang" -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "Elemen <%s> tidak boleh ada dalam elemen <constat>" +#: src/core/main.c:252 +msgid "Run with X11 backend" +msgstr "Jalankan dengan backend X11" -#: ../src/ui/theme-parser.c:3599 +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:151 #, c-format -msgid "Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "Elemen <%s> tidak boleh ada di dalam elemen distance/border/aspec_ratio" +msgid "“%s” is not responding." +msgstr "\"%s\" tak merespon." -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "Elemen <%s> tidak boleh ada di dalam elemen operasi gambar" +#: src/core/meta-close-dialog-default.c:153 +msgid "Application is not responding." +msgstr "Aplikasi tak merespon." -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "Elemen <%s> tidak boleh ada di dalam elemen <%s>" +#: src/core/meta-close-dialog-default.c:158 +msgid "" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." +msgstr "" +"Anda bisa memilih untuk menunggu sebentar atau memaksa aplikasi keluar." -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "Tidak ada draw_ops yang disediakan untuk bagian frame" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Force Quit" +msgstr "_Matikan Paksa" -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "Tidak ada draw_ops yang disediakan untuk tombol" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Wait" +msgstr "_Tunggu" -#: ../src/ui/theme-parser.c:3968 +#: src/core/mutter.c:38 #, c-format -msgid "No text is allowed inside element <%s>" -msgstr "Tidak boleh ada teks di dalam elemen <%s>" +msgid "" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" +msgstr "" +"mutter %s\n" +"Hak Cipta (C) 2001-%d Havoc Pennington, Red Hat, Inc., dan lain-lain.\n" +"Ini adalah perangkat lunak bebas; lihat kode asalnya untuk kondisi " +"penyalinan.\n" +"TIDAK ADA jaminan, bahkan untuk KELAYAKAN JUAL atau KELAYAKAN UNTUK KEGUNAAN " +"TERTENTU.\n" + +#: src/core/mutter.c:52 +msgid "Print version" +msgstr "Cetak versi" -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "<%s> disebutkan dua kali pada tema ini" +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "Pengaya Mutter yang dipakai" -#: ../src/ui/theme-parser.c:4348 +#: src/core/prefs.c:1911 #, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Gagal menemukan berkas yang sah untuk tema %s\n" - -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "_Jendela" - -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "_Dialog" - -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "Dialog _modal" - -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "_Utilitas" - -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "Layar _pembuka" - -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "Dok a_tas" - -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "Dok _bawah" - -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "Dok k_iri" - -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "Dok kana_n" - -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "Semu_a dok" - -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "Des_ktop" - -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "Buka lagi jendela semacam ini" - -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "Ini contoh tombol dengan ikon 'open'" - -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "Ini contoh tombol dengan ikon 'quit'" +msgid "Workspace %d" +msgstr "Area kerja %d" -#: ../src/ui/theme-viewer.c:253 -msgid "This is a sample message in a sample dialog" -msgstr "Ini contoh pesan pada suatu dialog" +#: src/core/util.c:122 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Muter dikompilasi tanpa dukungan mode riuh\n" -#: ../src/ui/theme-viewer.c:336 +#: src/wayland/meta-wayland-tablet-pad.c:568 #, c-format -msgid "Fake menu item %d\n" -msgstr "Item menu %d\n" - -#: ../src/ui/theme-viewer.c:371 -msgid "Border-only window" -msgstr "Jendela dengan garis pembatas" - -#: ../src/ui/theme-viewer.c:373 -msgid "Bar" -msgstr "Kotak" - -#: ../src/ui/theme-viewer.c:390 -msgid "Normal Application Window" -msgstr "Jendela Aplikasi Normal" - -#: ../src/ui/theme-viewer.c:394 -msgid "Dialog Box" -msgstr "Kotak Dialog" - -#: ../src/ui/theme-viewer.c:398 -msgid "Modal Dialog Box" -msgstr "Kotak Dialog Modal" - -#: ../src/ui/theme-viewer.c:402 -msgid "Utility Palette" -msgstr "Kotak Perkakas" - -#: ../src/ui/theme-viewer.c:406 -msgid "Torn-off Menu" -msgstr "Menu Dapat Dilepas" +msgid "Mode Switch: Mode %d" +msgstr "Tukar Mode: Mode %d" -#: ../src/ui/theme-viewer.c:410 -msgid "Border" -msgstr "Batas" - -#: ../src/ui/theme-viewer.c:414 -msgid "Attached Modal Dialog" -msgstr "Dialog Modal yang Dilampirkan" - -#: ../src/ui/theme-viewer.c:747 +#: src/x11/meta-x11-display.c:676 #, c-format -msgid "Button layout test %d" -msgstr "Tes komposisi tombol %d" +msgid "" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." +msgstr "" +"Tampilan \"%s\" sudah memiliki manajer jendela; cobalah gunakan pilihan --" +"replace untuk mengganti manajer jendela saat ini." -#: ../src/ui/theme-viewer.c:776 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "lama waktu menggambar satu bingkai jendela %g milidetik" +#: src/x11/meta-x11-display.c:1089 +msgid "Failed to initialize GDK\n" +msgstr "Gagal menginisialisasi GDK\n" -#: ../src/ui/theme-viewer.c:821 +#: src/x11/meta-x11-display.c:1113 #, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Cara pakai: metacity-theme-viewer [NAMA TEMA]\n" +msgid "Failed to open X Window System display “%s”\n" +msgstr "Gagal membuka tampilan X Window System \"%s\"\n" -#: ../src/ui/theme-viewer.c:828 +#: src/x11/meta-x11-display.c:1196 #, c-format -msgid "Error loading theme: %s\n" -msgstr "Ada error saat membaca tema: %s\n" +msgid "Screen %d on display “%s” is invalid\n" +msgstr "Layar %d pada tampilan \"%s\" tidak valid\n" -#: ../src/ui/theme-viewer.c:834 +#: src/x11/meta-x11-selection-input-stream.c:460 #, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "Tema \"%s\" dibuka dalam %g detik\n" - -#: ../src/ui/theme-viewer.c:878 -msgid "Normal Title Font" -msgstr "Judul dengan huruf normal" - -#: ../src/ui/theme-viewer.c:884 -msgid "Small Title Font" -msgstr "Judul dengan huruf ukuran kecil" +msgid "Format %s not supported" +msgstr "Format %s tidak didukung" -#: ../src/ui/theme-viewer.c:890 -msgid "Large Title Font" -msgstr "Judul Raksasa" - -#: ../src/ui/theme-viewer.c:895 -msgid "Button Layouts" -msgstr "Komposisi Tombol" - -#: ../src/ui/theme-viewer.c:900 -msgid "Benchmark" -msgstr "Pengukuran" - -#: ../src/ui/theme-viewer.c:952 -msgid "Window Title Goes Here" -msgstr "Ini tempat judul jendela" +#: src/x11/session.c:1821 +msgid "" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." +msgstr "" +"Jendela ini tidak mendukung \"menyimpan setelan aktif saat ini\" dan mesti " +"dijalankan ulang secara manual kala berikut Anda log masuk." -#: ../src/ui/theme-viewer.c:1055 +#: src/x11/window-props.c:569 #, c-format -msgid "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g seconds wall clock time including X server resources (%g milliseconds per frame)\n" -msgstr "%d frame dibuat dalam %g detik dalam waktu klien (%g milidetik per frame) dan %g detik dalam waktu sebenarnya (%g milidetik per frame)\n" - -#: ../src/ui/theme-viewer.c:1274 -msgid "position expression test returned TRUE but set error" -msgstr "tes ekspresi posisi berakhir TRUE tapi justru ada error" - -#: ../src/ui/theme-viewer.c:1276 -msgid "position expression test returned FALSE but didn't set error" -msgstr "tes ekspresi posisi berakhir FALSE tapi tidak ada error" - -#: ../src/ui/theme-viewer.c:1280 -msgid "Error was expected but none given" -msgstr "Seharusnya ada error, tapi ini kok tidak ada" +msgid "%s (on %s)" +msgstr "%s (pada %s)" -#: ../src/ui/theme-viewer.c:1282 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "Seharunya ada error %d, tapi yang terjadi %d" +#~ msgid "Move window one workspace to the left" +#~ msgstr "Pindahkan jendela satu ruang kerja ke kiri" -#: ../src/ui/theme-viewer.c:1288 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "Seharusnya tidak ada error, tapi ini tiba-tiba ada error: %s" +#~ msgid "Move window one workspace to the right" +#~ msgstr "Pindahkan jendela satu ruang kerja ke kanan" -#: ../src/ui/theme-viewer.c:1292 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "nilai x sebelumnya %d, padahal seharusnya %d" +#~ msgid "Move to workspace left" +#~ msgstr "Pindahkan ke ruang kerja kiri" -#: ../src/ui/theme-viewer.c:1295 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "nilai y sebelumnya %d, padahal seharusnya %d" +#~ msgid "Move to workspace right" +#~ msgstr "Pindahkan ke ruang kerja kanan" -#: ../src/ui/theme-viewer.c:1360 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "ekspresi koordinat %d diambil dalam %g detik (rata-rata %g detik)\n" +#~ msgid "Toggle shaded state" +#~ msgstr "Jungkitkan keadaan berbayang" diff --git a/po/ig.po b/po/ig.po index a41f47f88..d4a10ea63 100644 --- a/po/ig.po +++ b/po/ig.po @@ -7,6 +7,7 @@ msgstr "" "PO-Revision-Date: 2006-07-07 10:49+0100\n" "Last-Translator: Onye, Sylvester <sylvester@wazobialinux.com>\n" "Language-Team: Igbo\n" +"Language: ig\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" diff --git a/po/is.po b/po/is.po index be8360b13..7f0d5cfcc 100644 --- a/po/is.po +++ b/po/is.po @@ -1,2720 +1,1013 @@ -# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR Samúel Jón Gunnarsson <sammi@techattack.nu>, 2003. # +# FIRST AUTHOR Samúel Jón Gunnarsson <sammi@techattack.nu>, 2003. +# Sveinn í Felli <sv1@fellsnet.is>, 2017. msgid "" msgstr "" "Project-Id-Version: metacity\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2005-09-19 12:30+0200\n" -"PO-Revision-Date: 2003-06-22 17:16--100\n" -"Last-Translator: Samuel Jon Gunnarsson <sammi@techattack.nu>\n" -"Language-Team: Icelandic <gnome@techattack.nu>\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=mutter&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2016-10-29 18:34+0000\n" +"PO-Revision-Date: 2017-03-02 11:35+0000\n" +"Last-Translator: Sveinn í Felli <sv1@fellsnet.is>\n" +"Language-Team: Icelandic <translation-team-is@lists.sourceforge.org>\n" +"Language: is\n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" +"Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 1.5\n" -#: ../src/tools/metacity-message.c:150 -#, c-format -msgid "Usage: %s\n" -msgstr "Notkun: %s\n" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Flakk" -#: ../src/tools/metacity-message.c:176 ../src/util.c:128 -msgid "Metacity was compiled without support for verbose mode\n" -msgstr "Metacity var vistþýtt án stuðnings við aukin villuleitarham\n" +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Flytja glugga yfir á vinnusvæði 1" -#: ../src/delete.c:63 ../src/delete.c:90 ../src/metacity-dialog.c:70 -#: ../src/theme-parser.c:467 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "Ekki tókst að greina \"%s\" sem heiltölu" +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Flytja glugga yfir á vinnusvæði 2" -#: ../src/delete.c:70 ../src/delete.c:97 ../src/metacity-dialog.c:77 -#: ../src/theme-parser.c:476 ../src/theme-parser.c:530 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "" +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Flytja glugga yfir á vinnusvæði 3" -#: ../src/delete.c:128 -#, c-format -msgid "Failed to parse message \"%s\" from dialog process\n" -msgstr "" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Flytja glugga yfir á vinnusvæði 4" -#: ../src/delete.c:263 -#, c-format -msgid "Error reading from dialog display process: %s\n" -msgstr "" +#: data/50-mutter-navigation.xml:21 +#| msgid "Move window to workspace 1" +msgid "Move window to last workspace" +msgstr "Flytja glugga yfir á síðasta vinnusvæði" -#: ../src/delete.c:344 -#, c-format -msgid "" -"Error launching metacity-dialog to ask about killing an application: %s\n" -msgstr "" -"Villa átti sér stað við ræsingu á metalog-glugga með spurningu um aflífun á " -"forriti: %s\n" +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace to the left" +msgstr "Flytja glugga til vinstri um eitt vinnusvæði" -#: ../src/delete.c:452 -#, c-format -msgid "Failed to get hostname: %s\n" -msgstr "Ekki tókst að ná í nafn hýsils: %s\n" +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace to the right" +msgstr "Flytja glugga til hægri um eitt vinnusvæði" -#: ../src/display.c:319 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "" +#: data/50-mutter-navigation.xml:30 +msgid "Move window one workspace up" +msgstr "Flytja glugga upp um eitt vinnusvæði" -#: ../src/errors.c:231 -#, c-format -msgid "" -"Lost connection to the display '%s';\n" -"most likely the X server was shut down or you killed/destroyed\n" -"the window manager.\n" -msgstr "" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one workspace down" +msgstr "Flytja glugga niður um eitt vinnusvæði" -#: ../src/errors.c:238 -#, c-format -msgid "Fatal IO error %d (%s) on display '%s'.\n" -msgstr "Banvæn IO villa %d (%s) á skjá '%s'.\n" +#: data/50-mutter-navigation.xml:36 +#| msgid "Move window one workspace to the left" +msgid "Move window one monitor to the left" +msgstr "Flytja glugga á skjá til vinstri" -#: ../src/frames.c:1125 -msgid "Close Window" -msgstr "Loka glugga" +#: data/50-mutter-navigation.xml:39 +#| msgid "Move window one workspace to the right" +msgid "Move window one monitor to the right" +msgstr "Flytja glugga á skjá til hægri" -#: ../src/frames.c:1128 -msgid "Window Menu" -msgstr "Gluggavalmynd" +#: data/50-mutter-navigation.xml:42 +#| msgid "Move window one workspace up" +msgid "Move window one monitor up" +msgstr "Flytja glugga á skjá fyrir ofan" -#: ../src/frames.c:1131 -msgid "Minimize Window" -msgstr "Lágmarka glugga" +#: data/50-mutter-navigation.xml:45 +#| msgid "Move window one workspace down" +msgid "Move window one monitor down" +msgstr "Flytja glugga á skjá fyrir neðan" -#: ../src/frames.c:1134 -msgid "Maximize Window" -msgstr "Hámarka glugga" +#: data/50-mutter-navigation.xml:49 +msgid "Switch applications" +msgstr "Skipta á milli forrita" -#: ../src/frames.c:1137 -msgid "Unmaximize Window" -msgstr "Minnka glugga" +#: data/50-mutter-navigation.xml:54 +msgid "Switch to previous application" +msgstr "Skipta í fyrra forrit" -#: ../src/keybindings.c:994 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "" +#: data/50-mutter-navigation.xml:58 +msgid "Switch windows" +msgstr "Skipta á milli glugga" -#: ../src/keybindings.c:2620 -#, c-format -msgid "Error launching metacity-dialog to print an error about a command: %s\n" -msgstr "" +#: data/50-mutter-navigation.xml:63 +msgid "Switch to previous window" +msgstr "Skipta yfir í fyrri glugga" -#: ../src/keybindings.c:2725 -#, c-format -msgid "No command %d has been defined.\n" -msgstr "Engin skipun %d hefur verið skilgreind.\n" +#: data/50-mutter-navigation.xml:67 +msgid "Switch windows of an application" +msgstr "Skipta um forritsglugga" -#: ../src/keybindings.c:3570 -#, fuzzy -msgid "No terminal command has been defined.\n" -msgstr "Engin skipun %d hefur verið skilgreind.\n" +#: data/50-mutter-navigation.xml:72 +msgid "Switch to previous window of an application" +msgstr "Skipta í fyrri glugga forrits" -#: ../src/main.c:69 -#, c-format -msgid "" -"metacity %s\n" -"Copyright (C) 2001-2002 Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" -"metacity %s\n" -"Höfundarréttur áskilin (C) 2001-2002 Havoc Pennington, Red Hat, Inc., og " -"fleiri\n" -"Þetta er frír hugbúnaður; sjá kóðan fyrir afritunarskilyrði.\n" -"Það er ENGINN ábyrgð; ekki einu sinni fyrir MERCHANTABILITY eða FITNESS FOR " -"A PARTICULAR PURPOSE.\n" - -#: ../src/main.c:257 -msgid "Disable connection to session manager" +#: data/50-mutter-navigation.xml:76 +msgid "Switch system controls" msgstr "" -#: ../src/main.c:263 -msgid "Replace the running window manager with Metacity" +#: data/50-mutter-navigation.xml:81 +msgid "Switch to previous system control" msgstr "" -#: ../src/main.c:269 -msgid "Specify session management ID" +#: data/50-mutter-navigation.xml:85 +msgid "Switch windows directly" +msgstr "Skipta beint á milli glugga" + +#: data/50-mutter-navigation.xml:90 +msgid "Switch directly to previous window" +msgstr "Skipta beint yfir í fyrri glugga" + +#: data/50-mutter-navigation.xml:94 +msgid "Switch windows of an app directly" msgstr "" -#: ../src/main.c:274 -msgid "X Display to use" +#: data/50-mutter-navigation.xml:99 +msgid "Switch directly to previous window of an app" msgstr "" -#: ../src/main.c:280 -msgid "Initialize session from savefile" +#: data/50-mutter-navigation.xml:103 +msgid "Switch system controls directly" msgstr "" -#: ../src/main.c:286 -msgid "Print version" +#: data/50-mutter-navigation.xml:108 +msgid "Switch directly to previous system control" msgstr "" -#: ../src/main.c:440 -#, fuzzy, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Ekki tókst að hlaða inn þema \"%s\": %s\n" +#: data/50-mutter-navigation.xml:111 +msgid "Hide all normal windows" +msgstr "Fela alla venjulega glugga" -#: ../src/main.c:456 -#, c-format -msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes." -msgstr "" -"Ekki tókst að finna þema! Fullvissaðu þig um að %s finnist og innihaldi " -"venjuleg þema." +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 1" +msgstr "Skipta yfir á vinnusvæði 1" -#: ../src/main.c:518 -#, c-format -msgid "Failed to restart: %s\n" -msgstr "Ekki tókst að endurræsa: %s\n" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 2" +msgstr "Skipta yfir á vinnusvæði 2" -#: ../src/menu.c:54 -msgid "Mi_nimize" -msgstr "Lág_marka" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to workspace 3" +msgstr "Skipta yfir á vinnusvæði 3" -#: ../src/menu.c:55 -msgid "Ma_ximize" -msgstr "_Hámarka" +#: data/50-mutter-navigation.xml:123 +msgid "Switch to workspace 4" +msgstr "Skipta yfir á vinnusvæði 4" -#: ../src/menu.c:56 -msgid "Unma_ximize" -msgstr "Minn_ka glugga" +#: data/50-mutter-navigation.xml:126 +#| msgid "Switch to workspace 1" +msgid "Switch to last workspace" +msgstr "Skipta yfir á síðasta vinnusvæði" -#: ../src/menu.c:57 -msgid "Roll _Up" -msgstr "Rúlla _Upp" +#: data/50-mutter-navigation.xml:129 +msgid "Move to workspace left" +msgstr "Flytja á vinnusvæðið til vinstri" -#: ../src/menu.c:58 -msgid "_Unroll" -msgstr "_Rúlla Niður" +#: data/50-mutter-navigation.xml:132 +msgid "Move to workspace right" +msgstr "Flytja á vinnusvæðið til hægri" -#: ../src/menu.c:59 ../src/menu.c:60 -msgid "On _Top" -msgstr "" +#: data/50-mutter-navigation.xml:135 +msgid "Move to workspace above" +msgstr "Flytja á vinnusvæðið fyrir ofan" -#: ../src/menu.c:61 -msgid "_Move" -msgstr "_Flytja" +#: data/50-mutter-navigation.xml:138 +msgid "Move to workspace below" +msgstr "Flytja á vinnusvæðið fyrir neðan" -#: ../src/menu.c:62 -msgid "_Resize" -msgstr "_Endurstækka" +#: data/50-mutter-system.xml:6 +msgid "System" +msgstr "Kerfið" -#. separator -#: ../src/menu.c:64 -msgid "_Close" -msgstr "_Loka" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Birta skipanalínuna" -#. separator -#: ../src/menu.c:66 -#, fuzzy -msgid "_Always on Visible Workspace" -msgstr "Einungis á _þessu vinnusvæði" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Birta virkniyfirlit" -#: ../src/menu.c:67 -#, fuzzy -msgid "_Only on This Workspace" -msgstr "Einungis á _þessu vinnusvæði" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Gluggar" -#: ../src/menu.c:68 -#, fuzzy -msgid "Move to Workspace _Left" -msgstr "Flytja yfir á vinnusvæði 9" +#: data/50-mutter-windows.xml:8 +#| msgid "Activate window menu" +msgid "Activate the window menu" +msgstr "Virkja gluggavalmynd" -#: ../src/menu.c:69 -#, fuzzy -msgid "Move to Workspace R_ight" -msgstr "Flytja glugga yfir á vinnusvæði 1" +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Víxla heilskjáham af/á" -#: ../src/menu.c:70 -#, fuzzy -msgid "Move to Workspace _Up" -msgstr "Flytja glugga yfir á vinnusvæði 1" +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "Víxla hámörkunarstöðu af/á" -#: ../src/menu.c:71 -#, fuzzy -msgid "Move to Workspace _Down" -msgstr "Flytja glugga niður um eitt vinnusvæði" +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "Hámarka glugga" -#: ../src/menu.c:162 ../src/prefs.c:2106 -#, c-format -msgid "Workspace %d" -msgstr "Vinnusvæði %d" +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Endurheimta glugga" -#: ../src/menu.c:171 -#, fuzzy -msgid "Workspace 1_0" -msgstr "Vinnusvæði %d" +#: data/50-mutter-windows.xml:18 +msgid "Toggle shaded state" +msgstr "Víxla skyggingarstöðu af/á" -#: ../src/menu.c:173 -#, c-format -msgid "Workspace %s%d" -msgstr "Vinnusvæði %s%d" +#: data/50-mutter-windows.xml:20 +msgid "Close window" +msgstr "Loka glugga" -#: ../src/menu.c:368 -#, fuzzy -msgid "Move to Another _Workspace" -msgstr "Flytja glugga upp um eitt vinnusvæði" +#: data/50-mutter-windows.xml:22 +msgid "Hide window" +msgstr "Fela glugga" -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:105 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:111 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:117 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:123 -msgid "Meta" -msgstr "Meta" +#: data/50-mutter-windows.xml:24 +msgid "Move window" +msgstr "Flytja glugga" -# This is the text that should appear next to menu accelerators -# * that use the super key. If the text on this key isn't typically -# * translated on keyboards used for your language, don't translate -# * this. -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:129 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:135 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:141 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:147 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:153 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:159 -msgid "Mod5" -msgstr "Mod5" +#: data/50-mutter-windows.xml:26 +msgid "Resize window" +msgstr "Breyta stærð glugga" -#: ../src/metacity-dialog.c:110 -#, c-format -msgid "The window \"%s\" is not responding." +#: data/50-mutter-windows.xml:29 +#| msgid "Move window one workspace down" +msgid "Toggle window on all workspaces or one" msgstr "" +"Skipta á milli þess hvort glugginn sé á öllum vinnusvæðum eða bara einu" -#: ../src/metacity-dialog.c:118 -msgid "" -"Forcing this application to quit will cause you to lose any unsaved changes." -msgstr "" +#: data/50-mutter-windows.xml:31 +#| msgid "Raise window above other windows" +msgid "Raise window if covered, otherwise lower it" +msgstr "Hækka glugga ef annar gluggi hylur hann, annars skal lækka hann" -#: ../src/metacity-dialog.c:129 -msgid "_Force Quit" -msgstr "_þvinga til að hætta" +#: data/50-mutter-windows.xml:33 +msgid "Raise window above other windows" +msgstr "Hækka glugga upp fyrir aðra glugga" -#: ../src/metacity-dialog.c:226 -msgid "Title" -msgstr "Titill" +#: data/50-mutter-windows.xml:35 +msgid "Lower window below other windows" +msgstr "Lækka glugga niður fyrir aðra glugga" -#: ../src/metacity-dialog.c:238 -msgid "Class" -msgstr "Klassi" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window vertically" +msgstr "Hámarka glugga lóðrétt" -#: ../src/metacity-dialog.c:264 -msgid "" -"These windows do not support \"save current setup\" and will have to be " -"restarted manually next time you log in." -msgstr "" +#: data/50-mutter-windows.xml:39 +msgid "Maximize window horizontally" +msgstr "Hámarka glugga lárétt" -#: ../src/metacity-dialog.c:330 -#, c-format -msgid "" -"There was an error running \"%s\":\n" -"%s." -msgstr "" -"Villa átti sér stað við keyrslu \"%s\":\n" -"%s." +#: data/50-mutter-windows.xml:43 +msgid "View split on left" +msgstr "Kljúfa sýn til vinstri" -#: ../src/metacity.desktop.in.h:1 -msgid "Metacity" -msgstr "Metacity" +#: data/50-mutter-windows.xml:47 +msgid "View split on right" +msgstr "Kljúfa sýn til hægri" -#: ../src/metacity.schemas.in.h:1 -msgid "(Not implemented) Navigation works in terms of applications not windows" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" + +#: data/org.gnome.mutter.gschema.xml.in:7 +msgid "Modifier to use for extended window management operations" msgstr "" -"(Ekki ennþá innfært) Vöfrun virkar innan einungis í samhengi við forrit en " -"ekki glugga" -#: ../src/metacity.schemas.in.h:2 +#: data/org.gnome.mutter.gschema.xml.in:8 msgid "" -"A font description string describing a font for window titlebars. The size " -"from the description will only be used if the titlebar_font_size option is " -"set to 0, however. Also, this option is disabled if the " -"titlebar_uses_desktop_font option is set to true. By default, titlebar_font " -"is unset, causing Metacity to fall back to the desktop font even if " -"titlebar_uses_desktop_font is false." +"This key will initiate the \"overlay\", which is a combination window " +"overview and application launching system. The default is intended to be the " +"\"Windows key\" on PC hardware. It's expected that this binding either the " +"default or set to the empty string." msgstr "" -#: ../src/metacity.schemas.in.h:3 -msgid "Action on title bar double-click" -msgstr "Aðgerð við tvíklikk á titilrönd" +#: data/org.gnome.mutter.gschema.xml.in:20 +msgid "Attach modal dialogs" +msgstr "Tengja kvaðningarglugga" -#: ../src/metacity.schemas.in.h:4 -msgid "Activate window menu" -msgstr "Virkja gluggavalmynd" +#: data/org.gnome.mutter.gschema.xml.in:21 +msgid "" +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." +msgstr "" -#: ../src/metacity.schemas.in.h:5 -msgid "Arrangement of buttons on the titlebar" -msgstr "Staðsetning takka á tiltilrönd" +#: data/org.gnome.mutter.gschema.xml.in:30 +msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "Virkja flísalögn við jaðra þegar gluggum er sleppt á skjájaðra" -#: ../src/metacity.schemas.in.h:6 +#: data/org.gnome.mutter.gschema.xml.in:31 msgid "" -"Arrangement of buttons on the titlebar. The value should be a string, such " -"as \"menu:minimize,maximize,close\"; the colon separates the left corner of " -"the window from the right corner, and the button names are comma-separated. " -"Duplicate buttons are not allowed. Unknown button names are silently ignored " -"so that buttons can be added in future metacity versions without breaking " -"older versions." +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." msgstr "" -#: ../src/metacity.schemas.in.h:7 -msgid "Automatically raises the focused window" -msgstr "" +#: data/org.gnome.mutter.gschema.xml.in:40 +msgid "Workspaces are managed dynamically" +msgstr "Vinnusvæðum er stýrt eftir þörfum" -#: ../src/metacity.schemas.in.h:8 +#: data/org.gnome.mutter.gschema.xml.in:41 msgid "" -"Clicking a window while holding down this modifier key will move the window " -"(left click), resize the window (middle click), or show the window menu " -"(right click). Modifier is expressed as \"<Alt>\" or \"<Super>\" " -"for example." +"Determines whether workspaces are managed dynamically or whether there's a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." msgstr "" -#: ../src/metacity.schemas.in.h:9 -#, fuzzy -msgid "Close window" -msgstr "Loka glugga" +#: data/org.gnome.mutter.gschema.xml.in:50 +msgid "Workspaces only on primary" +msgstr "Vinnusvæði einungis á aðalskjá" -#: ../src/metacity.schemas.in.h:10 -msgid "Commands to run in response to keybindings" +#: data/org.gnome.mutter.gschema.xml.in:51 +msgid "" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." msgstr "" -#: ../src/metacity.schemas.in.h:11 -msgid "Current theme" -msgstr "Núverandi þema" - -#: ../src/metacity.schemas.in.h:12 -msgid "Delay in milliseconds for the auto raise option" -msgstr "Seinkun í millisekúndum fyrir sjálfvirka hækkun valmöguleikan" +#: data/org.gnome.mutter.gschema.xml.in:59 +msgid "No tab popup" +msgstr "" -#: ../src/metacity.schemas.in.h:13 +#: data/org.gnome.mutter.gschema.xml.in:60 msgid "" -"Determines whether applications or the system can generate audible 'beeps'; " -"may be used in conjunction with 'visual bell' to allow silent 'beeps'." +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." msgstr "" -"Ákvarðar hvort forrit eða kerfið geti búið til heyranlegt 'bíbb'. Er hægt að " -"nýta í samhengi með 'sýnilegri bjöllu' þegar leyfa á hljóðlaus 'bíbb'" -#: ../src/metacity.schemas.in.h:14 -msgid "Disable misfeatures that are required by old or broken applications" +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" msgstr "" -#: ../src/metacity.schemas.in.h:15 -msgid "Enable Visual Bell" -msgstr "Virkja sýnilega bjöllu" +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " +"the focus will not be changed immediately when entering a window, but only " +"after the pointer stops moving." +msgstr "" -#: ../src/metacity.schemas.in.h:16 -msgid "Hide all windows and focus desktop" -msgstr "Fela alla glugga og gefa skjáborði fókus" +#: data/org.gnome.mutter.gschema.xml.in:79 +msgid "Draggable border width" +msgstr "" -#: ../src/metacity.schemas.in.h:17 +#: data/org.gnome.mutter.gschema.xml.in:80 msgid "" -"If true, and the focus mode is either \"sloppy\" or \"mouse\" then the " -"focused window will be automatically raised after a delay (the delay is " -"specified by the auto_raise_delay key)." +"The amount of total draggable borders. If the theme's visible borders are " +"not enough, invisible borders will be added to meet this value." msgstr "" -#: ../src/metacity.schemas.in.h:18 -msgid "" -"If true, ignore the titlebar_font option, and use the standard application " -"font for window titles." +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" msgstr "" -#: ../src/metacity.schemas.in.h:19 +#: data/org.gnome.mutter.gschema.xml.in:90 msgid "" -"If true, metacity will give the user less feedback and less sense of " -"\"direct manipulation\", by using wireframes, avoiding animations, or other " -"means. This is a significant reduction in usability for many users, but may " -"allow legacy applications and terminal servers to function when they would " -"otherwise be impractical. However, the wireframe feature is disabled when " -"accessibility is on to avoid weird desktop breakages." +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." msgstr "" -#: ../src/metacity.schemas.in.h:20 +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Setja nýja glugga á miðjuna" + +#: data/org.gnome.mutter.gschema.xml.in:99 msgid "" -"If true, then Metacity works in terms of applications rather than windows. " -"The concept is a bit abstract, but in general an application-based setup is " -"more like the Mac and less like Windows. When you focus a window in " -"application-based mode, all the windows in the application will be raised. " -"Also, in application-based mode, focus clicks are not passed through to " -"windows in other applications. The existence of this setting is somewhat " -"questionable. But it's better than having settings for all the specific " -"details of application-based vs. window-based, e.g. whether to pass through " -"clicks. Also, application-based mode is largely unimplemented at the moment." +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." msgstr "" -#: ../src/metacity.schemas.in.h:21 -msgid "If true, trade off usability for less resource usage" +#: data/org.gnome.mutter.gschema.xml.in:120 +msgid "Select window from tab popup" msgstr "" -#: ../src/metacity.schemas.in.h:22 -msgid "Lower window below other windows" -msgstr "Lækka glugga niður fyrir aðra glugga" +#: data/org.gnome.mutter.gschema.xml.in:125 +msgid "Cancel tab popup" +msgstr "" -#: ../src/metacity.schemas.in.h:23 -#, fuzzy -msgid "Maximize window" -msgstr "Hámarka glugga" +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +#| msgid "Switch to workspace 1" +msgid "Switch to VT 1" +msgstr "Skipta yfir á vinnusvæði 1" -#: ../src/metacity.schemas.in.h:24 -msgid "Maximize window horizontally" -msgstr "Hámarka glugga lárétt" +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +#| msgid "Switch to workspace 2" +msgid "Switch to VT 2" +msgstr "Skipta yfir á vinnusvæði 2" -#: ../src/metacity.schemas.in.h:25 -msgid "Maximize window vertically" -msgstr "Hámarka glugga lóðrétt" +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +#| msgid "Switch to workspace 3" +msgid "Switch to VT 3" +msgstr "Skipta yfir á vinnusvæði 3" -#: ../src/metacity.schemas.in.h:26 -#, fuzzy -msgid "Minimize window" -msgstr "Lágmarka glugga" +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +#| msgid "Switch to workspace 4" +msgid "Switch to VT 4" +msgstr "Skipta yfir á vinnusvæði 4" -#: ../src/metacity.schemas.in.h:27 -msgid "Modifier to use for modified window click actions" -msgstr "" +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +#| msgid "Switch to workspace 5" +msgid "Switch to VT 5" +msgstr "Skipta yfir á vinnusvæði 5" -#: ../src/metacity.schemas.in.h:28 -msgid "Move backward between panels and the desktop immediately" -msgstr "" +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +#| msgid "Switch to workspace 6" +msgid "Switch to VT 6" +msgstr "Skipta yfir á vinnusvæði 6" -#: ../src/metacity.schemas.in.h:29 -msgid "Move backwards between panels and the desktop with popup" -msgstr "" +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +#| msgid "Switch to workspace 7" +msgid "Switch to VT 7" +msgstr "Skipta yfir á vinnusvæði 7" -#: ../src/metacity.schemas.in.h:30 -msgid "Move backwards between windows immediately" -msgstr "" +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +#| msgid "Switch to workspace 8" +msgid "Switch to VT 8" +msgstr "Skipta yfir á vinnusvæði 8" -#: ../src/metacity.schemas.in.h:31 -msgid "Move between panels and the desktop immediately" -msgstr "" +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +#| msgid "Switch to workspace 9" +msgid "Switch to VT 9" +msgstr "Skipta yfir á vinnusvæði 9" -#: ../src/metacity.schemas.in.h:32 -msgid "Move between panels and the desktop with popup" -msgstr "" +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +#| msgid "Switch to workspace 10" +msgid "Switch to VT 10" +msgstr "Skipta yfir á vinnusvæði 10" -#: ../src/metacity.schemas.in.h:33 -msgid "Move between windows immediately" -msgstr "Flytja á milli glugga án seinkunar" +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +#| msgid "Switch to workspace 11" +msgid "Switch to VT 11" +msgstr "Skipta yfir á vinnusvæði 11" -#: ../src/metacity.schemas.in.h:34 -msgid "Move between windows with popup" -msgstr "" +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +#| msgid "Switch to workspace 12" +msgid "Switch to VT 12" +msgstr "Skipta yfir á vinnusvæði 12" -#: ../src/metacity.schemas.in.h:35 -msgid "Move focus backwards between windows using popup display" -msgstr "" +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:1847 +msgid "Switch monitor" +msgstr "Skipta um skjá" -#: ../src/metacity.schemas.in.h:36 -#, fuzzy -msgid "Move window" -msgstr "Flytja glugga" +#: src/backends/meta-input-settings.c:1849 +msgid "Show on-screen help" +msgstr "Birta upplýsingar á skjá" -#: ../src/metacity.schemas.in.h:37 -msgid "Move window one workspace down" -msgstr "Flytja glugga niður um eitt vinnusvæði" +#: src/backends/meta-monitor-manager.c:514 +msgid "Built-in display" +msgstr "Innbyggður skjár" -#: ../src/metacity.schemas.in.h:38 -msgid "Move window one workspace to the left" -msgstr "Flytja glugga til vinstri um eitt vinnusvæði" +#: src/backends/meta-monitor-manager.c:537 +msgid "Unknown" +msgstr "Óþekkt" -#: ../src/metacity.schemas.in.h:39 -msgid "Move window one workspace to the right" -msgstr "Flytja glugga til hægri um eitt vinnusvæði" +#: src/backends/meta-monitor-manager.c:539 +msgid "Unknown Display" +msgstr "Óþekktur skjár" -#: ../src/metacity.schemas.in.h:40 -msgid "Move window one workspace up" -msgstr "Flytja glugga upp um eitt vinnusvæði" +#. TRANSLATORS: this is a monitor vendor name, followed by a +#. * size in inches, like 'Dell 15"' +#. +#: src/backends/meta-monitor-manager.c:547 +#, c-format +msgid "%s %s" +msgstr "%s %s" -#: ../src/metacity.schemas.in.h:41 -msgid "Move window to workspace 1" -msgstr "Flytja glugga yfir á vinnusvæði 1" +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:463 +#, c-format +msgid "" +"Another compositing manager is already running on screen %i on display \"%s" +"\"." +msgstr "" +"Annar skjásamsetningarstjóri er þegar í keyrslu í sýndarskjá %i á skjánum " +"\"%s\"." -#: ../src/metacity.schemas.in.h:42 -msgid "Move window to workspace 10" -msgstr "Flytja yfir á vinnusvæði 10" +#: src/core/bell.c:194 +msgid "Bell event" +msgstr "Hljóðatburður" -#: ../src/metacity.schemas.in.h:43 -msgid "Move window to workspace 11" -msgstr "Flytja yfir á vinnusvæði 11" +#: src/core/delete.c:127 +#, c-format +msgid "“%s” is not responding." +msgstr "“%s” svarar ekki." -#: ../src/metacity.schemas.in.h:44 -msgid "Move window to workspace 12" -msgstr "Flytja yfir á vinnusvæði 12" +#: src/core/delete.c:129 +msgid "Application is not responding." +msgstr "Forritið svarar ekki." -#: ../src/metacity.schemas.in.h:45 -msgid "Move window to workspace 2" -msgstr "Flytja yfir á vinnusvæði 2" +#: src/core/delete.c:134 +msgid "" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." +msgstr "" +"Þú getur annað hvort hinkrað augnablik og leyft forritinu að halda áfram eða " +"þú getur þvingað forritið til að slökkva algjörlega á sér." -#: ../src/metacity.schemas.in.h:46 -msgid "Move window to workspace 3" -msgstr "Flytja yfir á vinnusvæði 3" +#: src/core/delete.c:141 +msgid "_Wait" +msgstr "_Bíða" -#: ../src/metacity.schemas.in.h:47 -msgid "Move window to workspace 4" -msgstr "Flytja yfir á vinnusvæði 4" +#: src/core/delete.c:141 +msgid "_Force Quit" +msgstr "_Þvinga til að hætta" -#: ../src/metacity.schemas.in.h:48 -msgid "Move window to workspace 5" -msgstr "Flytja yfir á vinnusvæði 5" +#: src/core/display.c:590 +#, c-format +msgid "Failed to open X Window System display '%s'\n" +msgstr "Mistókst að opna X-gluggakerfis-skjá ‚%s‘\n" -#: ../src/metacity.schemas.in.h:49 -msgid "Move window to workspace 6" -msgstr "Flytja yfir á vinnusvæði 6" +#: src/core/main.c:182 +msgid "Disable connection to session manager" +msgstr "Slökkva á tengingu við setustjóra" -#: ../src/metacity.schemas.in.h:50 -msgid "Move window to workspace 7" -msgstr "Flytja yfir á vinnusvæði 7" +#: src/core/main.c:188 +#| msgid "Bug in window manager: " +msgid "Replace the running window manager" +msgstr "Skipta út gluggastjóranum sem er í notkun" -#: ../src/metacity.schemas.in.h:51 -msgid "Move window to workspace 8" -msgstr "Flytja yfir á vinnusvæði 8" +#: src/core/main.c:194 +msgid "Specify session management ID" +msgstr "Tilgreindu auðkenni (ID) setustjórnunar" -#: ../src/metacity.schemas.in.h:52 -msgid "Move window to workspace 9" -msgstr "Flytja yfir á vinnusvæði 9" +#: src/core/main.c:199 +msgid "X Display to use" +msgstr "X-skjár sem á að nota" -#: ../src/metacity.schemas.in.h:53 -msgid "Name of workspace" -msgstr "Nafn vinnusvæðis" +#: src/core/main.c:205 +msgid "Initialize session from savefile" +msgstr "Frumstilla setu frá vistaðri skrá" -#: ../src/metacity.schemas.in.h:54 -msgid "Number of workspaces" -msgstr "Fjöldi vinnusvæða" +#: src/core/main.c:211 +msgid "Make X calls synchronous" +msgstr "Gera X köllin samhæfð" -#: ../src/metacity.schemas.in.h:55 -msgid "" -"Number of workspaces. Must be more than zero, and has a fixed maximum (to " -"prevent accidentally destroying your desktop by asking for 34 million " -"workspaces)." -msgstr "" -"Fjöldi vinnsvæða. Verðu að vera fleiri en núll, og með fast hámark ( til að " -"koma í veg fyrir að rústa skjáborðinu með beiðni um 34 milljónir vinnusvæða)." +#: src/core/main.c:218 +msgid "Run as a wayland compositor" +msgstr "Keyra sem wayland-skjásamsetningu" -#: ../src/metacity.schemas.in.h:56 -msgid "Raise obscured window, otherwise lower" +#: src/core/main.c:224 +msgid "Run as a nested compositor" msgstr "" -#: ../src/metacity.schemas.in.h:57 -msgid "Raise window above other windows" -msgstr "Hækka glugga upp fyrir aðra glugga" +#: src/core/main.c:232 +msgid "Run as a full display server, rather than nested" +msgstr "" -#: ../src/metacity.schemas.in.h:58 -#, fuzzy -msgid "Resize window" -msgstr "Endurstækka glugga" +#: src/core/mutter.c:39 +#, c-format +#| msgid "" +#| "metacity %s\n" +#| "Copyright (C) 2001-2002 Havoc Pennington, Red Hat, Inc., and others\n" +#| "This is free software; see the source for copying conditions.\n" +#| "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +#| "PARTICULAR PURPOSE.\n" +msgid "" +"mutter %s\n" +"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" +msgstr "" +"mutter %s\n" +"Höfundarréttur (C) 2001-%d Havoc Pennington, Red Hat, Inc., og fleiri\n" +"Þetta er frjáls hugbúnaður; skoðaðu grunnkóða til að sjá afritunarskilyrði.\n" +"Hugbúnaðnum er dreift í þeirri von að hann geti verið gagnlegur, en ÁN " +"ALLRAR ÁBYRGÐAR; einnig án þeirrar ábyrgðar sem gefin er í skyn með " +"SELJANLEIKA eða EGINLEIKUM TIL TILTEKINNA NOTA. Sjá almenna GNU GPL " +"notkunarleyfið fyrir nánari upplýsingar.\n" -#: ../src/metacity.schemas.in.h:59 -msgid "Run a defined command" -msgstr "Keyra tiltekna skipun" +#: src/core/mutter.c:53 +msgid "Print version" +msgstr "Prenta útgáfunúmer" -#: ../src/metacity.schemas.in.h:60 -msgid "Run a terminal" +#: src/core/mutter.c:59 +msgid "Mutter plugin to use" msgstr "" -#: ../src/metacity.schemas.in.h:61 -msgid "Show the panel menu" -msgstr "Sýna stikuvalmynd" +#: src/core/prefs.c:1997 +#, c-format +msgid "Workspace %d" +msgstr "Vinnusvæði %d" -#: ../src/metacity.schemas.in.h:62 -msgid "Show the panel run application dialog" +#: src/core/screen.c:521 +#, c-format +msgid "" +"Display \"%s\" already has a window manager; try using the --replace option " +"to replace the current window manager." msgstr "" +"Skjárinn \"%s\" er þegar með gluggastjóra; reyndu að nota --replace rofann " +"til að skipta út núverandi gluggastjóra." + +#: src/core/screen.c:606 +#, c-format +msgid "Screen %d on display '%s' is invalid\n" +msgstr "Sýndarskjár %d á skjánum '%s‛ er ógildur\n" + +#: src/core/util.c:120 +#| msgid "Metacity was compiled without support for verbose mode\n" +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter var vistþýtt án stuðnings við aukinn villuleitarham\n" + +#: src/wayland/meta-wayland-tablet-pad.c:595 +#, c-format +msgid "Mode Switch: Mode %d" +msgstr "Hamskipti: %d hamur" -#: ../src/metacity.schemas.in.h:63 +#: src/x11/session.c:1815 msgid "" -"Some applications break specifications in ways that result in window manager " -"misfeatures. For example, ideally Metacity would place all dialogs in a " -"consistent position with respect to their parent window. This requires " -"ignoring application-specified positions for dialogs. But some versions of " -"Java/Swing mark their popup menus as dialogs, so Metacity has to disable " -"dialog positioning to allow menus to work in broken Java applications. There " -"are several other examples like this. This option puts Metacity in full-on " -"Correct mode, which perhaps gives a moderately nicer UI if you don't need to " -"run any broken apps. Sadly, workarounds must be enabled by default; the real " -"world is an ugly place. Some of the workarounds are workarounds for " -"limitations in the specifications themselves, so sometimes a bug in no-" -"workarounds mode won't be fixable without amending a spec." +"These windows do not support "save current setup" and will have to " +"be restarted manually next time you log in." msgstr "" -#: ../src/metacity.schemas.in.h:64 -msgid "Switch to workspace 1" -msgstr "Skipta yfir á vinnusvæði 1" +#: src/x11/window-props.c:548 +#, c-format +msgid "%s (on %s)" +msgstr "%s (á %s)" -#: ../src/metacity.schemas.in.h:65 -msgid "Switch to workspace 10" -msgstr "Skipta yfir á vinnusvæði 10" +#~ msgid "Usage: %s\n" +#~ msgstr "Notkun: %s\n" -#: ../src/metacity.schemas.in.h:66 -msgid "Switch to workspace 11" -msgstr "Skipta yfir á vinnusvæði 11" +#~ msgid "Could not parse \"%s\" as an integer" +#~ msgstr "Ekki tókst að greina \"%s\" sem heiltölu" -#: ../src/metacity.schemas.in.h:67 -msgid "Switch to workspace 12" -msgstr "Skipta yfir á vinnusvæði 12" +#~ msgid "" +#~ "Error launching metacity-dialog to ask about killing an application: %s\n" +#~ msgstr "" +#~ "Villa átti sér stað við ræsingu á metalog-glugga með spurningu um aflífun " +#~ "á forriti: %s\n" -#: ../src/metacity.schemas.in.h:68 -msgid "Switch to workspace 2" -msgstr "Skipta yfir á vinnusvæði 2" +#~ msgid "Failed to get hostname: %s\n" +#~ msgstr "Ekki tókst að ná í nafn hýsils: %s\n" -#: ../src/metacity.schemas.in.h:69 -msgid "Switch to workspace 3" -msgstr "Skipta yfir á vinnusvæði 3" +#~ msgid "Fatal IO error %d (%s) on display '%s'.\n" +#~ msgstr "Banvæn IO villa %d (%s) á skjá '%s'.\n" -#: ../src/metacity.schemas.in.h:70 -msgid "Switch to workspace 4" -msgstr "Skipta yfir á vinnusvæði 4" +#~ msgid "Close Window" +#~ msgstr "Loka glugga" -#: ../src/metacity.schemas.in.h:71 -msgid "Switch to workspace 5" -msgstr "Skipta yfir á vinnusvæði 5" +#~ msgid "Window Menu" +#~ msgstr "Gluggavalmynd" -#: ../src/metacity.schemas.in.h:72 -msgid "Switch to workspace 6" -msgstr "Skipta yfir á vinnusvæði 6" +#~ msgid "Minimize Window" +#~ msgstr "Lágmarka glugga" -#: ../src/metacity.schemas.in.h:73 -msgid "Switch to workspace 7" -msgstr "Skipta yfir á vinnusvæði 7" +#~ msgid "Maximize Window" +#~ msgstr "Hámarka glugga" -#: ../src/metacity.schemas.in.h:74 -msgid "Switch to workspace 8" -msgstr "Skipta yfir á vinnusvæði 8" +#~ msgid "Unmaximize Window" +#~ msgstr "Minnka glugga" -#: ../src/metacity.schemas.in.h:75 -msgid "Switch to workspace 9" -msgstr "Skipta yfir á vinnusvæði 9" +#~ msgid "No command %d has been defined.\n" +#~ msgstr "Engin skipun %d hefur verið skilgreind.\n" -#: ../src/metacity.schemas.in.h:76 -msgid "Switch to workspace above this one" -msgstr "Skipta yfir á vinnusvæði fyrir ofan þetta" +#, fuzzy +#~ msgid "No terminal command has been defined.\n" +#~ msgstr "Engin skipun %d hefur verið skilgreind.\n" -#: ../src/metacity.schemas.in.h:77 -msgid "Switch to workspace below this one" -msgstr "Skipta yfir á vinnusvæði fyrir neðan þetta" +#, fuzzy +#~ msgid "Failed to scan themes directory: %s\n" +#~ msgstr "Ekki tókst að hlaða inn þema \"%s\": %s\n" -#: ../src/metacity.schemas.in.h:78 -msgid "Switch to workspace on the left" -msgstr "Skipta yfir á vinnusvæði á vinstri hönd" +#~ msgid "" +#~ "Could not find a theme! Be sure %s exists and contains the usual themes." +#~ msgstr "" +#~ "Ekki tókst að finna þema! Fullvissaðu þig um að %s finnist og innihaldi " +#~ "venjuleg þema." -#: ../src/metacity.schemas.in.h:79 -msgid "Switch to workspace on the right" -msgstr "Skipta yfir á vinnusvæði á hægri hönd" +#~ msgid "Failed to restart: %s\n" +#~ msgstr "Ekki tókst að endurræsa: %s\n" -#: ../src/metacity.schemas.in.h:80 -msgid "System Bell is Audible" -msgstr "Kerfisbjalla er heyranleg" +#~ msgid "Mi_nimize" +#~ msgstr "Lág_marka" -#: ../src/metacity.schemas.in.h:81 -msgid "Take a screenshot" -msgstr "Taka skjámynd" +#~ msgid "Ma_ximize" +#~ msgstr "_Hámarka" -#: ../src/metacity.schemas.in.h:82 -msgid "Take a screenshot of a window" -msgstr "Taka skjámynd af glugga" +#~ msgid "Unma_ximize" +#~ msgstr "Minn_ka glugga" -#: ../src/metacity.schemas.in.h:83 -msgid "" -"Tells Metacity how to implement the visual indication that the system bell " -"or another application 'bell' indicator has been rung. Currently there are " -"two valid values, \"fullscreen\", which causes a fullscreen white-black " -"flash, and \"frame_flash\" which causes the titlebar of the application " -"which sent the bell signal to flash. If the application which sent the bell " -"is unknown (as is usually the case for the default \"system beep\"), the " -"currently focused window's titlebar is flashed." -msgstr "" +#~ msgid "Roll _Up" +#~ msgstr "Rúlla _Upp" -#: ../src/metacity.schemas.in.h:84 -msgid "" -"The /apps/metacity/global_keybindings/run_command_N keys define keybindings " -"that correspond to these commands. Pressing the keybinding for run_command_N " -"will execute command_N." -msgstr "" +#~ msgid "_Unroll" +#~ msgstr "_Rúlla Niður" -#: ../src/metacity.schemas.in.h:85 -msgid "" -"The /apps/metacity/global_keybindings/run_command_screenshot key defines a " -"keybinding which causes the command specified by this setting to be invoked." -msgstr "" - -#: ../src/metacity.schemas.in.h:86 -msgid "" -"The /apps/metacity/global_keybindings/run_command_window_screenshot key " -"defines a keybinding which causes the command specified by this setting to " -"be invoked." -msgstr "" - -#: ../src/metacity.schemas.in.h:87 -msgid "" -"The keybinding that runs the correspondingly-numbered command in /apps/" -"metacity/keybinding_commands The format looks like \"<Control>a\" or " -"\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -"lower or upper case, and also abbreviations such as \"<Ctl>\" and " -"\"<Ctrl>\". If you set the option to the special string \"disabled\", " -"then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:88 -msgid "" -"The keybinding that switches to the workspace above the current workspace. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:89 -msgid "" -"The keybinding that switches to the workspace below the current workspace. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:90 -msgid "" -"The keybinding that switches to the workspace on the left of the current " -"workspace. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:91 -msgid "" -"The keybinding that switches to the workspace on the right of the current " -"workspace. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:92 -msgid "" -"The keybinding that switches to workspace 1. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:93 -msgid "" -"The keybinding that switches to workspace 10. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:94 -msgid "" -"The keybinding that switches to workspace 11. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:95 -msgid "" -"The keybinding that switches to workspace 12. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:96 -msgid "" -"The keybinding that switches to workspace 2. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:97 -msgid "" -"The keybinding that switches to workspace 3. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:98 -msgid "" -"The keybinding that switches to workspace 4. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:99 -msgid "" -"The keybinding that switches to workspace 5. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:100 -msgid "" -"The keybinding that switches to workspace 6. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:101 -msgid "" -"The keybinding that switches to workspace 7. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:102 -msgid "" -"The keybinding that switches to workspace 8. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:103 -msgid "" -"The keybinding that switches to workspace 9. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:104 -msgid "" -"The keybinding used to activate the window menu. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:105 -msgid "" -"The keybinding used to close a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:106 -msgid "" -"The keybinding used to enter \"move mode\" and begin moving a window using " -"the keyboard. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:107 -msgid "" -"The keybinding used to enter \"resize mode\" and begin resizing a window " -"using the keyboard. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:108 -msgid "" -"The keybinding used to hide all normal windows and set the focus to the " -"desktop background. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:109 -msgid "" -"The keybinding used to maximize a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:110 -msgid "" -"The keybinding used to minimize a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:111 -msgid "" -"The keybinding used to move a window one workspace down. The format looks " -"like \"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -"fairly liberal and allows lower or upper case, and also abbreviations such " -"as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -"special string \"disabled\", then there will be no keybinding for this " -"action." -msgstr "" - -#: ../src/metacity.schemas.in.h:112 -msgid "" -"The keybinding used to move a window one workspace to the left. The format " -"looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -"parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:113 -msgid "" -"The keybinding used to move a window one workspace to the right. The format " -"looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -"parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:114 -msgid "" -"The keybinding used to move a window one workspace up. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:115 -msgid "" -"The keybinding used to move a window to workspace 1. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:116 -msgid "" -"The keybinding used to move a window to workspace 10. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:117 -msgid "" -"The keybinding used to move a window to workspace 11. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:118 -msgid "" -"The keybinding used to move a window to workspace 12. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:119 -msgid "" -"The keybinding used to move a window to workspace 2. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:120 -msgid "" -"The keybinding used to move a window to workspace 3. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:121 -msgid "" -"The keybinding used to move a window to workspace 4. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:122 -msgid "" -"The keybinding used to move a window to workspace 5. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:123 -msgid "" -"The keybinding used to move a window to workspace 6. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:124 -msgid "" -"The keybinding used to move a window to workspace 7. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:125 -msgid "" -"The keybinding used to move a window to workspace 8. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:126 -msgid "" -"The keybinding used to move a window to workspace 9. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:127 -msgid "" -"The keybinding used to move focus backwards between panels and the desktop, " -"using a popup window. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:128 -msgid "" -"The keybinding used to move focus backwards between panels and the desktop, " -"without a popup window. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:129 -msgid "" -"The keybinding used to move focus backwards between windows without a popup " -"window. Holding \"shift\" together with this binding makes the direction go " -"forward again. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:130 -msgid "" -"The keybinding used to move focus backwards between windows, using a popup " -"window. Holding \"shift\" together with this binding makes the direction go " -"forward again. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:131 -msgid "" -"The keybinding used to move focus between panels and the desktop, using a " -"popup window. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:132 -msgid "" -"The keybinding used to move focus between panels and the desktop, without a " -"popup window. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:133 -msgid "" -"The keybinding used to move focus between windows without a popup window. " -"(Traditionally <Alt>Escape) Holding the \"shift\" key while using this " -"binding reverses the direction of movement. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:134 -msgid "" -"The keybinding used to move focus between windows, using a popup window. " -"(Traditionally <Alt>Tab) Holding the \"shift\" key while using this " -"binding reverses the direction of movement. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:135 -msgid "" -"The keybinding used to toggle always on top. A window that is always on top " -"will always be visible over other overlapping windows. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:136 -msgid "" -"The keybinding used to toggle fullscreen mode. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:137 -msgid "" -"The keybinding used to toggle maximization. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:138 -msgid "" -"The keybinding used to toggle shaded/unshaded state. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:139 -msgid "" -"The keybinding used to toggle whether the window is on all workspaces or " -"just one. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:140 -msgid "" -"The keybinding used to unmaximize a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:141 -msgid "" -"The keybinding which display's the panel's \"Run Application\" dialog box. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:142 -msgid "" -"The keybinding which invokes a terminal. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:143 -msgid "" -"The keybinding which invokes the panel's screenshot utility to take a " -"screenshot of a window. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:144 -msgid "" -"The keybinding which invokes the panel's screenshot utility. The format " -"looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -"parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:145 -msgid "" -"The keybinding which shows the panel's main menu. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:146 -msgid "The name of a workspace." -msgstr "Nafn vinnusvæði." - -#: ../src/metacity.schemas.in.h:147 -msgid "The screenshot command" -msgstr "" - -#: ../src/metacity.schemas.in.h:148 -msgid "" -"The theme determines the appearance of window borders, titlebar, and so " -"forth." -msgstr "" - -#: ../src/metacity.schemas.in.h:149 -msgid "" -"The time delay before raising a window if auto_raise is set to true. The " -"delay is given in thousandths of a second." -msgstr "" - -#: ../src/metacity.schemas.in.h:150 -msgid "" -"The window focus mode indicates how windows are activated. It has three " -"possible values; \"click\" means windows must be clicked in order to focus " -"them, \"sloppy\" means windows are focused when the mouse enters the window, " -"and \"mouse\" means windows are focused when the mouse enters the window and " -"unfocused when the mouse leaves the window." -msgstr "" - -#: ../src/metacity.schemas.in.h:151 -msgid "The window screenshot command" -msgstr "" - -#: ../src/metacity.schemas.in.h:152 -msgid "" -"This keybinding changes whether a window is above or below other windows. If " -"the window is covered by another window, it raises the window above other " -"windows. If the window is already fully visible, it lowers the window below " -"other windows. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:153 -msgid "" -"This keybinding lowers a window below other windows. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:154 -msgid "" -"This keybinding raises the window above other windows. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:155 -msgid "" -"This keybinding resizes a window to fill available horizontal space. The " -"format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:156 -msgid "" -"This keybinding resizes a window to fill available vertical space. The " -"format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:157 -msgid "" -"This option determines the effects of double-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, and 'toggle_maximize' which will maximize/unmaximize the window." -msgstr "" - -#: ../src/metacity.schemas.in.h:158 -msgid "Toggle always on top state" -msgstr "" - -#: ../src/metacity.schemas.in.h:159 -msgid "Toggle fullscreen mode" -msgstr "Fletta heilskjáham" - -#: ../src/metacity.schemas.in.h:160 -msgid "Toggle maximization state" -msgstr "" - -#: ../src/metacity.schemas.in.h:161 -msgid "Toggle shaded state" -msgstr "" - -#: ../src/metacity.schemas.in.h:162 -msgid "Toggle window on all workspaces" -msgstr "" - -#: ../src/metacity.schemas.in.h:163 -msgid "" -"Turns on a visual indication when an application or the system issues a " -"'bell' or 'beep'; useful for the hard-of-hearing and for use in noisy " -"environments, or when 'audible bell' is off." -msgstr "" - -#: ../src/metacity.schemas.in.h:164 -#, fuzzy -msgid "Unmaximize window" -msgstr "Minnka glugga" - -#: ../src/metacity.schemas.in.h:165 -msgid "Use standard system font in window titles" -msgstr "" - -#: ../src/metacity.schemas.in.h:166 -msgid "Visual Bell Type" -msgstr "Gerð sýnilegrar bjöllu" - -#: ../src/metacity.schemas.in.h:167 -msgid "Window focus mode" -msgstr "Fókusgerð glugga" - -#: ../src/metacity.schemas.in.h:168 -msgid "Window title font" -msgstr "Leturgerð gluggatitils" - -#: ../src/prefs.c:528 ../src/prefs.c:544 ../src/prefs.c:560 ../src/prefs.c:576 -#: ../src/prefs.c:592 ../src/prefs.c:612 ../src/prefs.c:628 ../src/prefs.c:644 -#: ../src/prefs.c:660 ../src/prefs.c:676 ../src/prefs.c:692 ../src/prefs.c:708 -#: ../src/prefs.c:724 ../src/prefs.c:741 ../src/prefs.c:757 ../src/prefs.c:773 -#: ../src/prefs.c:789 ../src/prefs.c:805 ../src/prefs.c:820 ../src/prefs.c:835 -#: ../src/prefs.c:850 ../src/prefs.c:866 ../src/prefs.c:882 ../src/prefs.c:898 -#, c-format -msgid "GConf key \"%s\" is set to an invalid type\n" -msgstr "" - -#: ../src/prefs.c:943 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" - -#: ../src/prefs.c:967 ../src/prefs.c:1428 -#, c-format -msgid "GConf key '%s' is set to an invalid value\n" -msgstr "" - -#: ../src/prefs.c:1145 -#, c-format -msgid "Could not parse font description \"%s\" from GConf key %s\n" -msgstr "" - -#: ../src/prefs.c:1330 -#, c-format -msgid "" -"%d stored in GConf key %s is not a reasonable number of workspaces, current " -"maximum is %d\n" -msgstr "" - -#: ../src/prefs.c:1390 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" - -#: ../src/prefs.c:1455 -#, c-format -msgid "%d stored in GConf key %s is out of range 0 to %d\n" -msgstr "" - -#: ../src/prefs.c:1589 -#, c-format -msgid "Error setting number of workspaces to %d: %s\n" -msgstr "" - -#: ../src/prefs.c:1833 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "" - -#: ../src/prefs.c:2187 -#, c-format -msgid "Error setting name for workspace %d to \"%s\": %s\n" -msgstr "" - -#: ../src/resizepopup.c:126 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" - -#: ../src/screen.c:408 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "" - -#: ../src/screen.c:424 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" - -#: ../src/screen.c:448 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "" - -#: ../src/screen.c:506 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "" - -#: ../src/screen.c:716 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "" - -#: ../src/session.c:884 ../src/session.c:891 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Ekki tókst að búa til möppu '%s': %s\n" - -#: ../src/session.c:901 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "" - -#: ../src/session.c:1053 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "" - -#: ../src/session.c:1058 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "" - -#: ../src/session.c:1133 -#, c-format -msgid "Failed to read saved session file %s: %s\n" -msgstr "" - -#: ../src/session.c:1168 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "" - -#: ../src/session.c:1217 -msgid "<metacity_session> attribute seen but we already have the session ID" -msgstr "" - -#: ../src/session.c:1230 -#, c-format -msgid "Unknown attribute %s on <metacity_session> element" -msgstr "" - -#: ../src/session.c:1247 -msgid "nested <window> tag" -msgstr "hreiðraður <window> tag" - -#: ../src/session.c:1305 ../src/session.c:1337 -#, c-format -msgid "Unknown attribute %s on <window> element" -msgstr "" - -#: ../src/session.c:1409 -#, c-format -msgid "Unknown attribute %s on <maximized> element" -msgstr "" - -#: ../src/session.c:1469 -#, c-format -msgid "Unknown attribute %s on <geometry> element" -msgstr "" - -#: ../src/session.c:1489 -#, c-format -msgid "Unknown element %s" -msgstr "" - -#: ../src/session.c:1961 -#, c-format -msgid "" -"Error launching metacity-dialog to warn about apps that don't support " -"session management: %s\n" -msgstr "" - -#: ../src/theme-parser.c:224 ../src/theme-parser.c:242 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Lína %d tákn %d: %s" - -#: ../src/theme-parser.c:396 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "" - -#: ../src/theme-parser.c:414 ../src/theme-parser.c:439 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "" - -#: ../src/theme-parser.c:485 -#, c-format -msgid "Integer %ld must be positive" -msgstr "Heiltalan %ld verður að vera jákvæð" - -#: ../src/theme-parser.c:493 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "Heiltalan %ld er of stór. Núverandi hámark er %d" - -#: ../src/theme-parser.c:521 ../src/theme-parser.c:602 -#: ../src/theme-parser.c:626 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "Ekki tókst að greina \"%s\" sem floating point tölu" - -#: ../src/theme-parser.c:552 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "" - -#: ../src/theme-parser.c:572 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "" - -#: ../src/theme-parser.c:638 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" - -#: ../src/theme-parser.c:684 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" - -#: ../src/theme-parser.c:729 ../src/theme-parser.c:737 -#: ../src/theme-parser.c:807 ../src/theme-parser.c:897 -#: ../src/theme-parser.c:935 ../src/theme-parser.c:1012 -#: ../src/theme-parser.c:1062 ../src/theme-parser.c:1070 -#: ../src/theme-parser.c:1126 ../src/theme-parser.c:1134 -#: ../src/theme-parser.c:2936 ../src/theme-parser.c:3025 -#: ../src/theme-parser.c:3032 ../src/theme-parser.c:3039 -#, c-format -msgid "No \"%s\" attribute on <%s> element" -msgstr "" - -#: ../src/theme-parser.c:837 ../src/theme-parser.c:905 -#: ../src/theme-parser.c:943 ../src/theme-parser.c:1020 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "" - -#: ../src/theme-parser.c:849 ../src/theme-parser.c:955 -#: ../src/theme-parser.c:1032 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "" - -#: ../src/theme-parser.c:968 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "" - -#: ../src/theme-parser.c:981 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "" - -#: ../src/theme-parser.c:1080 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "" - -#: ../src/theme-parser.c:1091 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "" - -#: ../src/theme-parser.c:1099 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "" - -#: ../src/theme-parser.c:1143 -#, c-format -msgid "Unknown function \"%s\" for menu icon" -msgstr "" - -#: ../src/theme-parser.c:1152 -#, c-format -msgid "Unknown state \"%s\" for menu icon" -msgstr "" - -#: ../src/theme-parser.c:1160 -#, c-format -msgid "Theme already has a menu icon for function %s state %s" -msgstr "" - -#: ../src/theme-parser.c:1177 ../src/theme-parser.c:3244 -#: ../src/theme-parser.c:3323 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "" - -#: ../src/theme-parser.c:1192 ../src/theme-parser.c:1256 -#: ../src/theme-parser.c:1545 ../src/theme-parser.c:3124 -#: ../src/theme-parser.c:3178 ../src/theme-parser.c:3338 -#: ../src/theme-parser.c:3515 ../src/theme-parser.c:3553 -#: ../src/theme-parser.c:3591 ../src/theme-parser.c:3629 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "" - -#: ../src/theme-parser.c:1282 ../src/theme-parser.c:1369 -#: ../src/theme-parser.c:1439 -#, c-format -msgid "No \"name\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:1289 ../src/theme-parser.c:1376 -#, c-format -msgid "No \"value\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:1320 ../src/theme-parser.c:1334 -#: ../src/theme-parser.c:1393 -msgid "" -"Cannot specify both button_width/button_height and aspect ratio for buttons" -msgstr "" - -#: ../src/theme-parser.c:1343 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "Fjarlægð \"%s\" er óþekkt" - -#: ../src/theme-parser.c:1402 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "Stærðarhlutföll \"%s\" eru óþekkt" - -#: ../src/theme-parser.c:1446 -#, c-format -msgid "No \"top\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:1453 -#, c-format -msgid "No \"bottom\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:1460 -#, c-format -msgid "No \"left\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:1467 -#, c-format -msgid "No \"right\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:1499 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "" - -#: ../src/theme-parser.c:1655 ../src/theme-parser.c:1765 -#: ../src/theme-parser.c:1868 ../src/theme-parser.c:2055 -#: ../src/theme-parser.c:2869 -#, c-format -msgid "No \"color\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:1662 -#, c-format -msgid "No \"x1\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:1669 ../src/theme-parser.c:2714 -#, c-format -msgid "No \"y1\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:1676 -#, c-format -msgid "No \"x2\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:1683 ../src/theme-parser.c:2721 -#, c-format -msgid "No \"y2\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:1772 ../src/theme-parser.c:1875 -#: ../src/theme-parser.c:1981 ../src/theme-parser.c:2062 -#: ../src/theme-parser.c:2168 ../src/theme-parser.c:2266 -#: ../src/theme-parser.c:2483 ../src/theme-parser.c:2609 -#: ../src/theme-parser.c:2707 ../src/theme-parser.c:2781 -#: ../src/theme-parser.c:2876 -#, c-format -msgid "No \"x\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:1779 ../src/theme-parser.c:1882 -#: ../src/theme-parser.c:1988 ../src/theme-parser.c:2069 -#: ../src/theme-parser.c:2175 ../src/theme-parser.c:2273 -#: ../src/theme-parser.c:2490 ../src/theme-parser.c:2616 -#: ../src/theme-parser.c:2788 ../src/theme-parser.c:2883 -#, c-format -msgid "No \"y\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:1786 ../src/theme-parser.c:1889 -#: ../src/theme-parser.c:1995 ../src/theme-parser.c:2076 -#: ../src/theme-parser.c:2182 ../src/theme-parser.c:2280 -#: ../src/theme-parser.c:2497 ../src/theme-parser.c:2623 -#: ../src/theme-parser.c:2795 -#, c-format -msgid "No \"width\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:1793 ../src/theme-parser.c:1896 -#: ../src/theme-parser.c:2002 ../src/theme-parser.c:2083 -#: ../src/theme-parser.c:2189 ../src/theme-parser.c:2287 -#: ../src/theme-parser.c:2504 ../src/theme-parser.c:2630 -#: ../src/theme-parser.c:2802 -#, c-format -msgid "No \"height\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:1903 -#, c-format -msgid "No \"start_angle\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:1910 -#, c-format -msgid "No \"extent_angle\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:2090 -#, c-format -msgid "No \"alpha\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:2161 -#, c-format -msgid "No \"type\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:2209 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "" - -#: ../src/theme-parser.c:2294 -#, c-format -msgid "No \"filename\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:2319 ../src/theme-parser.c:2827 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "" - -#: ../src/theme-parser.c:2462 ../src/theme-parser.c:2595 -#: ../src/theme-parser.c:2700 -#, c-format -msgid "No \"state\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:2469 ../src/theme-parser.c:2602 -#, c-format -msgid "No \"shadow\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:2476 -#, c-format -msgid "No \"arrow\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:2529 ../src/theme-parser.c:2651 -#: ../src/theme-parser.c:2739 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "" - -#: ../src/theme-parser.c:2539 ../src/theme-parser.c:2661 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "" - -#: ../src/theme-parser.c:2549 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "" - -#: ../src/theme-parser.c:2962 ../src/theme-parser.c:3078 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "" - -#: ../src/theme-parser.c:2974 ../src/theme-parser.c:3090 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "" - -#: ../src/theme-parser.c:3153 -#, c-format -msgid "No \"value\" attribute on <%s> element" -msgstr "" - -#: ../src/theme-parser.c:3210 -#, c-format -msgid "No \"position\" attribute on <%s> element" -msgstr "" - -#: ../src/theme-parser.c:3219 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "" - -#: ../src/theme-parser.c:3227 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "" - -#: ../src/theme-parser.c:3272 -#, c-format -msgid "No \"function\" attribute on <%s> element" -msgstr "" - -#: ../src/theme-parser.c:3280 ../src/theme-parser.c:3384 -#, c-format -msgid "No \"state\" attribute on <%s> element" -msgstr "" - -#: ../src/theme-parser.c:3289 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Óþekkt fall \"%s\" fyrir hnapp" - -#: ../src/theme-parser.c:3298 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Óþekkt staða \"%s\" fyrir hnapp" - -#: ../src/theme-parser.c:3306 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "" - -#: ../src/theme-parser.c:3376 -#, c-format -msgid "No \"focus\" attribute on <%s> element" -msgstr "" - -#: ../src/theme-parser.c:3392 -#, c-format -msgid "No \"style\" attribute on <%s> element" -msgstr "" - -#: ../src/theme-parser.c:3401 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "" - -#: ../src/theme-parser.c:3410 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "" - -#: ../src/theme-parser.c:3420 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "" - -#: ../src/theme-parser.c:3430 -#, c-format -msgid "No \"resize\" attribute on <%s> element" -msgstr "" - -#: ../src/theme-parser.c:3440 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "" - -#: ../src/theme-parser.c:3450 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" - -#: ../src/theme-parser.c:3464 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "" - -#: ../src/theme-parser.c:3475 ../src/theme-parser.c:3486 -#: ../src/theme-parser.c:3497 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "" - -#: ../src/theme-parser.c:3536 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" - -#: ../src/theme-parser.c:3574 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" - -#: ../src/theme-parser.c:3612 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" - -#: ../src/theme-parser.c:3659 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "" - -#: ../src/theme-parser.c:3679 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "" - -#: ../src/theme-parser.c:3684 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "" - -#: ../src/theme-parser.c:3696 -#, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "" - -#: ../src/theme-parser.c:3718 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "" - -#: ../src/theme-parser.c:3728 ../src/theme-parser.c:3758 -#: ../src/theme-parser.c:3763 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "" - -#: ../src/theme-parser.c:3984 -msgid "No draw_ops provided for frame piece" -msgstr "" - -#: ../src/theme-parser.c:3999 -msgid "No draw_ops provided for button" -msgstr "" - -#: ../src/theme-parser.c:4014 -msgid "No draw_ops provided for menu icon" -msgstr "" - -#: ../src/theme-parser.c:4054 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "" - -#: ../src/theme-parser.c:4109 -msgid "<name> specified twice for this theme" -msgstr "<name> uppgefið í tvígang fyrir þetta þema" - -#: ../src/theme-parser.c:4120 -msgid "<author> specified twice for this theme" -msgstr "<author> uppgefið í tvígang fyrir þetta þema" +#~ msgid "_Move" +#~ msgstr "_Flytja" -#: ../src/theme-parser.c:4131 -msgid "<copyright> specified twice for this theme" -msgstr "<copyright> uppgefið í tvígang fyrir þetta þema" +#~ msgid "_Resize" +#~ msgstr "_Endurstækka" -#: ../src/theme-parser.c:4142 -msgid "<date> specified twice for this theme" -msgstr "<date> uppgefið í tvígang fyrir þetta þema" +#~ msgid "_Close" +#~ msgstr "_Loka" -#: ../src/theme-parser.c:4153 -msgid "<description> specified twice for this theme" -msgstr "<description> uppgefið í tvígang fyrir þetta þema" - -#: ../src/theme-parser.c:4348 -#, c-format -msgid "Failed to read theme from file %s: %s\n" -msgstr "Ekki tókst að lesa þema frá skrá %s: %s\n" - -#: ../src/theme-parser.c:4403 -#, c-format -msgid "Theme file %s did not contain a root <metacity_theme> element" -msgstr "Þemaskrá %s innihélt ekki rótar <metacity_theme> einingu" - -#: ../src/theme-viewer.c:70 #, fuzzy -msgid "/_Windows" -msgstr "Gluggi í fókus" - -#: ../src/theme-viewer.c:71 -msgid "/Windows/tearoff" -msgstr "" - -#: ../src/theme-viewer.c:72 -msgid "/Windows/_Dialog" -msgstr "" - -#: ../src/theme-viewer.c:73 -msgid "/Windows/_Modal dialog" -msgstr "" - -#: ../src/theme-viewer.c:74 -msgid "/Windows/_Utility" -msgstr "" - -#: ../src/theme-viewer.c:75 -msgid "/Windows/_Splashscreen" -msgstr "" +#~ msgid "_Always on Visible Workspace" +#~ msgstr "Einungis á _þessu vinnusvæði" -#: ../src/theme-viewer.c:76 #, fuzzy -msgid "/Windows/_Top dock" -msgstr "Gluggi í fókus" - -#: ../src/theme-viewer.c:77 -msgid "/Windows/_Bottom dock" -msgstr "" - -#: ../src/theme-viewer.c:78 -msgid "/Windows/_Left dock" -msgstr "" +#~ msgid "_Only on This Workspace" +#~ msgstr "Einungis á _þessu vinnusvæði" -#: ../src/theme-viewer.c:79 -msgid "/Windows/_Right dock" -msgstr "" +#, fuzzy +#~ msgid "Move to Workspace _Up" +#~ msgstr "Flytja glugga yfir á vinnusvæði 1" -#: ../src/theme-viewer.c:80 #, fuzzy -msgid "/Windows/_All docks" -msgstr "Gluggi í fókus" +#~ msgid "Workspace 1_0" +#~ msgstr "Vinnusvæði %d" -#: ../src/theme-viewer.c:81 -msgid "/Windows/Des_ktop" -msgstr "" +#~ msgid "Workspace %s%d" +#~ msgstr "Vinnusvæði %s%d" -#: ../src/theme-viewer.c:131 #, fuzzy -msgid "Open another one of these windows" -msgstr "Hækka glugga upp fyrir aðra glugga" +#~ msgid "Move to Another _Workspace" +#~ msgstr "Flytja glugga upp um eitt vinnusvæði" -#: ../src/theme-viewer.c:138 -msgid "This is a demo button with an 'open' icon" -msgstr "" +#~ msgid "Shift" +#~ msgstr "Shift" -#: ../src/theme-viewer.c:145 -msgid "This is a demo button with a 'quit' icon" -msgstr "" +#~ msgid "Ctrl" +#~ msgstr "Ctrl" -#: ../src/theme-viewer.c:241 -msgid "This is a sample message in a sample dialog" -msgstr "" +#~ msgid "Alt" +#~ msgstr "Alt" -#: ../src/theme-viewer.c:324 -#, c-format -msgid "Fake menu item %d\n" -msgstr "" +#~ msgid "Meta" +#~ msgstr "Meta" -#: ../src/theme-viewer.c:358 -msgid "Border-only window" -msgstr "" +# This is the text that should appear next to menu accelerators +# * that use the super key. If the text on this key isn't typically +# * translated on keyboards used for your language, don't translate +# * this. +#~ msgid "Super" +#~ msgstr "Super" -#: ../src/theme-viewer.c:360 -msgid "Bar" -msgstr "" +#~ msgid "Hyper" +#~ msgstr "Hyper" -#: ../src/theme-viewer.c:377 -msgid "Normal Application Window" -msgstr "" +#~ msgid "Mod2" +#~ msgstr "Mod2" -#: ../src/theme-viewer.c:382 -msgid "Dialog Box" -msgstr "" +#~ msgid "Mod3" +#~ msgstr "Mod3" -#: ../src/theme-viewer.c:387 -msgid "Modal Dialog Box" -msgstr "" +#~ msgid "Mod4" +#~ msgstr "Mod4" -#: ../src/theme-viewer.c:392 -msgid "Utility Palette" -msgstr "" +#~ msgid "Mod5" +#~ msgstr "Mod5" -#: ../src/theme-viewer.c:397 -msgid "Torn-off Menu" -msgstr "" +#~ msgid "Title" +#~ msgstr "Titill" -#: ../src/theme-viewer.c:402 -msgid "Border" -msgstr "" +#~ msgid "Class" +#~ msgstr "Klassi" -#: ../src/theme-viewer.c:731 -#, c-format -msgid "Button layout test %d" -msgstr "" +#~ msgid "" +#~ "There was an error running \"%s\":\n" +#~ "%s." +#~ msgstr "" +#~ "Villa átti sér stað við keyrslu \"%s\":\n" +#~ "%s." -#: ../src/theme-viewer.c:760 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "" +#~ msgid "Metacity" +#~ msgstr "Metacity" -#: ../src/theme-viewer.c:803 -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "" +#~ msgid "" +#~ "(Not implemented) Navigation works in terms of applications not windows" +#~ msgstr "" +#~ "(Ekki ennþá innfært) Vöfrun virkar innan einungis í samhengi við forrit " +#~ "en ekki glugga" -#: ../src/theme-viewer.c:810 -#, fuzzy, c-format -msgid "Error loading theme: %s\n" -msgstr "Ekki tókst að hlaða inn þema \"%s\": %s\n" +#~ msgid "Action on title bar double-click" +#~ msgstr "Aðgerð við tvíklikk á titilrönd" -#: ../src/theme-viewer.c:816 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "" +#~ msgid "Arrangement of buttons on the titlebar" +#~ msgstr "Staðsetning takka á tiltilrönd" -#: ../src/theme-viewer.c:839 -msgid "Normal Title Font" -msgstr "" +#~ msgid "Current theme" +#~ msgstr "Núverandi þema" -#: ../src/theme-viewer.c:845 -msgid "Small Title Font" -msgstr "" +#~ msgid "Delay in milliseconds for the auto raise option" +#~ msgstr "Seinkun í millisekúndum fyrir sjálfvirka hækkun valmöguleikan" -#: ../src/theme-viewer.c:851 -msgid "Large Title Font" -msgstr "" +#~ msgid "" +#~ "Determines whether applications or the system can generate audible " +#~ "'beeps'; may be used in conjunction with 'visual bell' to allow silent " +#~ "'beeps'." +#~ msgstr "" +#~ "Ákvarðar hvort forrit eða kerfið geti búið til heyranlegt 'bíbb'. Er hægt " +#~ "að nýta í samhengi með 'sýnilegri bjöllu' þegar leyfa á hljóðlaus 'bíbb'" -#: ../src/theme-viewer.c:856 -msgid "Button Layouts" -msgstr "" +#~ msgid "Enable Visual Bell" +#~ msgstr "Virkja sýnilega bjöllu" -#: ../src/theme-viewer.c:861 -msgid "Benchmark" -msgstr "" +#~ msgid "Hide all windows and focus desktop" +#~ msgstr "Fela alla glugga og gefa skjáborði fókus" -#: ../src/theme-viewer.c:908 #, fuzzy -msgid "Window Title Goes Here" -msgstr "Leturgerð gluggatitils" - -#: ../src/theme-viewer.c:1012 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" +#~ msgid "Minimize window" +#~ msgstr "Lágmarka glugga" -#: ../src/theme-viewer.c:1227 -msgid "position expression test returned TRUE but set error" -msgstr "" - -#: ../src/theme-viewer.c:1229 -msgid "position expression test returned FALSE but didn't set error" -msgstr "" - -#: ../src/theme-viewer.c:1233 -msgid "Error was expected but none given" -msgstr "" - -#: ../src/theme-viewer.c:1235 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "" +#~ msgid "Move between windows immediately" +#~ msgstr "Flytja á milli glugga án seinkunar" -#: ../src/theme-viewer.c:1241 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "" - -#: ../src/theme-viewer.c:1245 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "" - -#: ../src/theme-viewer.c:1248 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "" +#~ msgid "Move window to workspace 10" +#~ msgstr "Flytja yfir á vinnusvæði 10" -#: ../src/theme-viewer.c:1310 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "" +#~ msgid "Move window to workspace 11" +#~ msgstr "Flytja yfir á vinnusvæði 11" -#: ../src/theme.c:202 -msgid "top" -msgstr "toppur" +#~ msgid "Move window to workspace 12" +#~ msgstr "Flytja yfir á vinnusvæði 12" -#: ../src/theme.c:204 -msgid "bottom" -msgstr "botn" +#~ msgid "Move window to workspace 5" +#~ msgstr "Flytja yfir á vinnusvæði 5" -#: ../src/theme.c:206 -msgid "left" -msgstr "vinstri" +#~ msgid "Move window to workspace 6" +#~ msgstr "Flytja yfir á vinnusvæði 6" -#: ../src/theme.c:208 -msgid "right" -msgstr "hægri" +#~ msgid "Move window to workspace 7" +#~ msgstr "Flytja yfir á vinnusvæði 7" -#: ../src/theme.c:222 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "" +#~ msgid "Move window to workspace 8" +#~ msgstr "Flytja yfir á vinnusvæði 8" -#: ../src/theme.c:241 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "" +#~ msgid "Move window to workspace 9" +#~ msgstr "Flytja yfir á vinnusvæði 9" -#: ../src/theme.c:278 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "" +#~ msgid "Name of workspace" +#~ msgstr "Nafn vinnusvæðis" -#: ../src/theme.c:290 -msgid "Frame geometry does not specify size of buttons" -msgstr "" +#~ msgid "Number of workspaces" +#~ msgstr "Fjöldi vinnusvæða" -#: ../src/theme.c:843 -msgid "Gradients should have at least two colors" -msgstr "" +#~ msgid "" +#~ "Number of workspaces. Must be more than zero, and has a fixed maximum (to " +#~ "prevent accidentally destroying your desktop by asking for 34 million " +#~ "workspaces)." +#~ msgstr "" +#~ "Fjöldi vinnsvæða. Verðu að vera fleiri en núll, og með fast hámark ( til " +#~ "að koma í veg fyrir að rústa skjáborðinu með beiðni um 34 milljónir " +#~ "vinnusvæða)." -#: ../src/theme.c:969 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" +#~ msgid "Run a defined command" +#~ msgstr "Keyra tiltekna skipun" -#: ../src/theme.c:983 -#, c-format -msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "" +#~ msgid "Show the panel menu" +#~ msgstr "Sýna stikuvalmynd" -#: ../src/theme.c:994 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "" +#~ msgid "Switch to workspace above this one" +#~ msgstr "Skipta yfir á vinnusvæði fyrir ofan þetta" -#: ../src/theme.c:1007 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "" +#~ msgid "Switch to workspace below this one" +#~ msgstr "Skipta yfir á vinnusvæði fyrir neðan þetta" -#: ../src/theme.c:1037 -#, c-format -msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" -msgstr "" +#~ msgid "Switch to workspace on the left" +#~ msgstr "Skipta yfir á vinnusvæði á vinstri hönd" -#: ../src/theme.c:1048 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "" +#~ msgid "Switch to workspace on the right" +#~ msgstr "Skipta yfir á vinnusvæði á hægri hönd" -#: ../src/theme.c:1058 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "" +#~ msgid "System Bell is Audible" +#~ msgstr "Kerfisbjalla er heyranleg" -#: ../src/theme.c:1105 -#, c-format -msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "" +#~ msgid "Take a screenshot" +#~ msgstr "Taka skjámynd" -#: ../src/theme.c:1116 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "" +#~ msgid "Take a screenshot of a window" +#~ msgstr "Taka skjámynd af glugga" -#: ../src/theme.c:1126 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "" +#~ msgid "The name of a workspace." +#~ msgstr "Nafn vinnusvæði." -#: ../src/theme.c:1155 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Ekki tókst að greina lit \"%s\"" +#, fuzzy +#~ msgid "Unmaximize window" +#~ msgstr "Minnka glugga" -#: ../src/theme.c:1417 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "" +#~ msgid "Visual Bell Type" +#~ msgstr "Gerð sýnilegrar bjöllu" -#: ../src/theme.c:1444 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "" +#~ msgid "Window focus mode" +#~ msgstr "Fókusgerð glugga" -#: ../src/theme.c:1458 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "" +#~ msgid "Window title font" +#~ msgstr "Leturgerð gluggatitils" -#: ../src/theme.c:1525 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "" +#~ msgid "%d x %d" +#~ msgstr "%d x %d" -#: ../src/theme.c:1582 -msgid "Coordinate expression was empty or not understood" -msgstr "" +#~ msgid "Could not create directory '%s': %s\n" +#~ msgstr "Ekki tókst að búa til möppu '%s': %s\n" -#: ../src/theme.c:1725 ../src/theme.c:1735 ../src/theme.c:1769 -msgid "Coordinate expression results in division by zero" -msgstr "" +#~ msgid "nested <window> tag" +#~ msgstr "hreiðraður <window> tag" -#: ../src/theme.c:1777 -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "" +#~ msgid "Line %d character %d: %s" +#~ msgstr "Lína %d tákn %d: %s" -#: ../src/theme.c:1834 -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "" +#~ msgid "Integer %ld must be positive" +#~ msgstr "Heiltalan %ld verður að vera jákvæð" -#: ../src/theme.c:1843 -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "" +#~ msgid "Integer %ld is too large, current max is %d" +#~ msgstr "Heiltalan %ld er of stór. Núverandi hámark er %d" -#: ../src/theme.c:1851 -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "" +#~ msgid "Could not parse \"%s\" as a floating point number" +#~ msgstr "Ekki tókst að greina \"%s\" sem floating point tölu" -#: ../src/theme.c:1861 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" +#~ msgid "Distance \"%s\" is unknown" +#~ msgstr "Fjarlægð \"%s\" er óþekkt" -#: ../src/theme.c:1980 -msgid "" -"Coordinate expression parser overflowed its buffer, this is really a " -"Metacity bug, but are you sure you need a huge expression like that?" -msgstr "" +#~ msgid "Aspect ratio \"%s\" is unknown" +#~ msgstr "Stærðarhlutföll \"%s\" eru óþekkt" -#: ../src/theme.c:2009 -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "" +#~ msgid "Unknown function \"%s\" for button" +#~ msgstr "Óþekkt fall \"%s\" fyrir hnapp" -#: ../src/theme.c:2072 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "" +#~ msgid "Unknown state \"%s\" for button" +#~ msgstr "Óþekkt staða \"%s\" fyrir hnapp" -#: ../src/theme.c:2129 -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "" +#~ msgid "<name> specified twice for this theme" +#~ msgstr "<name> uppgefið í tvígang fyrir þetta þema" -#: ../src/theme.c:2140 -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "" +#~ msgid "<author> specified twice for this theme" +#~ msgstr "<author> uppgefið í tvígang fyrir þetta þema" -#: ../src/theme.c:2384 ../src/theme.c:2406 ../src/theme.c:2427 -#, c-format -msgid "Theme contained an expression \"%s\" that resulted in an error: %s\n" -msgstr "" +#~ msgid "<copyright> specified twice for this theme" +#~ msgstr "<copyright> uppgefið í tvígang fyrir þetta þema" -#: ../src/theme.c:3913 -#, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" +#~ msgid "<date> specified twice for this theme" +#~ msgstr "<date> uppgefið í tvígang fyrir þetta þema" -#: ../src/theme.c:4363 ../src/theme.c:4395 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" +#~ msgid "<description> specified twice for this theme" +#~ msgstr "<description> uppgefið í tvígang fyrir þetta þema" -#: ../src/theme.c:4446 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Ekki tókst að hlaða inn þema \"%s\": %s\n" +#~ msgid "Failed to read theme from file %s: %s\n" +#~ msgstr "Ekki tókst að lesa þema frá skrá %s: %s\n" -#: ../src/theme.c:4592 ../src/theme.c:4599 ../src/theme.c:4606 -#: ../src/theme.c:4613 ../src/theme.c:4620 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "" +#~ msgid "Theme file %s did not contain a root <metacity_theme> element" +#~ msgstr "Þemaskrá %s innihélt ekki rótar <metacity_theme> einingu" -#: ../src/theme.c:4630 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" +#, fuzzy +#~ msgid "/Windows/_Top dock" +#~ msgstr "Gluggi í fókus" -#: ../src/theme.c:4652 -#, c-format -msgid "" -"<menu_icon function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this theme" -msgstr "" +#, fuzzy +#~ msgid "/Windows/_All docks" +#~ msgstr "Gluggi í fókus" -#: ../src/theme.c:5041 ../src/theme.c:5103 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" +#, fuzzy +#~ msgid "Open another one of these windows" +#~ msgstr "Hækka glugga upp fyrir aðra glugga" -#: ../src/theme.c:5049 ../src/theme.c:5111 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "" +#, fuzzy +#~ msgid "Error loading theme: %s\n" +#~ msgstr "Ekki tókst að hlaða inn þema \"%s\": %s\n" -#: ../src/util.c:93 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Ekki tókst að opna aflúsunarskrá: %s\n" +#, fuzzy +#~ msgid "Window Title Goes Here" +#~ msgstr "Leturgerð gluggatitils" -#: ../src/util.c:103 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Ekki tókst að fdopen() log skrá %s: %s\n" +#~ msgid "top" +#~ msgstr "toppur" -#: ../src/util.c:109 -#, c-format -msgid "Opened log file %s\n" -msgstr "Opnaði log skrá %s\n" +#~ msgid "bottom" +#~ msgstr "botn" -#: ../src/util.c:203 -msgid "Window manager: " -msgstr "Gluggastjóri:" +#~ msgid "left" +#~ msgstr "vinstri" -#: ../src/util.c:349 -msgid "Bug in window manager: " -msgstr "Lús í gluggastjóra:" +#~ msgid "right" +#~ msgstr "hægri" -#: ../src/util.c:378 -msgid "Window manager warning: " -msgstr "Viðvörun gluggastjóra:" +#~ msgid "Could not parse color \"%s\"" +#~ msgstr "Ekki tókst að greina lit \"%s\"" -#: ../src/util.c:402 -msgid "Window manager error: " -msgstr "Villa gluggastjóra:" +#~ msgid "Failed to load theme \"%s\": %s\n" +#~ msgstr "Ekki tókst að hlaða inn þema \"%s\": %s\n" -#: ../src/window-props.c:162 -#, c-format -msgid "Application set a bogus _NET_WM_PID %ld\n" -msgstr "" +#~ msgid "Failed to open debug log: %s\n" +#~ msgstr "Ekki tókst að opna aflúsunarskrá: %s\n" -#. first time through -#: ../src/window.c:5205 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" +#~ msgid "Failed to fdopen() log file %s: %s\n" +#~ msgstr "Ekki tókst að fdopen() log skrá %s: %s\n" -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/window.c:5876 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %" -"d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" +#~ msgid "Opened log file %s\n" +#~ msgstr "Opnaði log skrá %s\n" -#: ../src/xprops.c:153 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" +#~ msgid "Window manager: " +#~ msgstr "Gluggastjóri:" -#: ../src/xprops.c:399 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "" +#~ msgid "Window manager warning: " +#~ msgstr "Viðvörun gluggastjóra:" -#: ../src/xprops.c:482 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" +#~ msgid "Window manager error: " +#~ msgstr "Villa gluggastjóra:" diff --git a/po/it.po b/po/it.po index 238840f40..b8ed1198e 100644 --- a/po/it.po +++ b/po/it.po @@ -1,2627 +1,787 @@ -# Italian translation for Muffin. +# Italian translation for Mutter. # Based on Italian translation for Metacity # This file is distributed under the same license as metacity package -# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. +# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 Free Software Foundation, Inc. +# Copyright (C) 2018, 2019, 2020 Free Software Foundation, Inc. # Pier Luigi Fiorini <plfiorini@libero.it>, 2002. # Lapo Calamandrei <lapo.calamandrei@virgilio.it>, 2003. -# Luca Ferretti <lferrett@gnome.org>, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011. +# Luca Ferretti <lferrett@gnome.org>, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012. +# Milo Casagrande <milo@milo.name>, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020. # msgid "" msgstr "" -"Project-Id-Version: muffin 2.9x\n" -"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" -"product=muffin&keywords=I18N+L10N&component=general\n" -"POT-Creation-Date: 2011-09-06 16:52+0000\n" -"PO-Revision-Date: 2011-09-08 21:56+0200\n" -"Last-Translator: Luca Ferretti <lferrett@gnome.org>\n" -"Language-Team: Italiano <tp@lists.linux.it>\n" +"Project-Id-Version: mutter\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2020-02-23 17:41+0000\n" +"PO-Revision-Date: 2020-03-03 11:42+0100\n" +"Last-Translator: Milo Casagrande <milo@milo.name>\n" +"Language-Team: Italian <tp@lists.linux.it>\n" +"Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bits\n" -"Language: it\n" +"Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Generator: Poedit 2.2.4\n" -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:486 -#, c-format -msgid "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." -msgstr "" -"Un altro compositing manager è già in esecuzione sullo schermo %i sul " -"display «%s»." +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Navigazione" -# questo e i successivi presi dallo stesso -# file vanno a comparire in -# Preferenze -> Scorciatoie da tastiera -#: ../src/core/all-keybindings.h:88 -msgid "Switch to workspace 1" -msgstr "Passa allo spazio di lavoro 1" +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Sposta la finestra sullo spazio di lavoro 1" -#: ../src/core/all-keybindings.h:90 -msgid "Switch to workspace 2" -msgstr "Passa allo spazio di lavoro 2" +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Sposta la finestra sullo spazio di lavoro 2" -#: ../src/core/all-keybindings.h:92 -msgid "Switch to workspace 3" -msgstr "Passa allo spazio di lavoro 3" +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Sposta la finestra sullo spazio di lavoro 3" -#: ../src/core/all-keybindings.h:94 -msgid "Switch to workspace 4" -msgstr "Passa allo spazio di lavoro 4" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Sposta la finestra sullo spazio di lavoro 4" + +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Sposta la finestra sull'ultimo spazio di lavoro" -#: ../src/core/all-keybindings.h:96 -msgid "Switch to workspace 5" -msgstr "Passa allo spazio di lavoro 5" +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "Sposta la finestra sullo spazio di lavoro in alto" -#: ../src/core/all-keybindings.h:98 -msgid "Switch to workspace 6" -msgstr "Passa allo spazio di lavoro 6" +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "Sposta la finestra sullo spazio di lavoro in basso" -#: ../src/core/all-keybindings.h:100 -msgid "Switch to workspace 7" -msgstr "Passa allo spazio di lavoro 7" +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "Sposta la finestra un monitor a sinistra" -#: ../src/core/all-keybindings.h:102 -msgid "Switch to workspace 8" -msgstr "Passa allo spazio di lavoro 8" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "Sposta la finestra un monitor a destra" -#: ../src/core/all-keybindings.h:104 -msgid "Switch to workspace 9" -msgstr "Passa allo spazio di lavoro 9" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "Sposta la finestra un monitor in su" -#: ../src/core/all-keybindings.h:106 -msgid "Switch to workspace 10" -msgstr "Passa allo spazio di lavoro 10" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "Sposta la finestra un monitor in giù" -#: ../src/core/all-keybindings.h:108 -msgid "Switch to workspace 11" -msgstr "Passa allo spazio di lavoro 11" +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "Evidenzia le applicazioni" -#: ../src/core/all-keybindings.h:110 -msgid "Switch to workspace 12" -msgstr "Passa allo spazio di lavoro 12" +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "Evidenzia l'applicazione precedente" -#: ../src/core/all-keybindings.h:122 -msgid "Switch to workspace on the left of the current workspace" -msgstr "Passa allo spazio di lavoro a sinistra di quello attuale" +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "Evidenzia le finestre" -#: ../src/core/all-keybindings.h:126 -msgid "Switch to workspace on the right of the current workspace" -msgstr "Passa allo spazio di lavoro a destra di quello attuale" +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "Evidenzia la finestra precedente" -#: ../src/core/all-keybindings.h:130 -msgid "Switch to workspace above the current workspace" -msgstr "Passa allo spazio di lavoro sopra quello attuale" +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "Evidenzia le finestre di un'applicazione" -#: ../src/core/all-keybindings.h:134 -msgid "Switch to workspace below the current workspace" -msgstr "Passa allo spazio di lavoro sotto quello attuale" +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "Evidenzia la finestra precedente di un'applicazione" -#: ../src/core/all-keybindings.h:150 -msgid "Move between windows of an application, using a popup window" -msgstr "Sposta tra le finestre di un'applicazione, usando una finestra" +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "Evidenzia i controlli di sistema" -#: ../src/core/all-keybindings.h:153 -msgid "Move backward between windows of an application, using a popup window" -msgstr "" -"Sposta al contrario tra le finestre di un'applicazione, usando una finestra " -"a comparsa" +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "Evidenzia i controlli di sistema precedenti" -#: ../src/core/all-keybindings.h:157 -msgid "Move between windows, using a popup window" -msgstr "Sposta tra le finestra, usando una finestra a comparsa" +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "Evidenzia direttamente le finestre" -#: ../src/core/all-keybindings.h:160 -msgid "Move backward between windows, using a popup window" -msgstr "Sposta al contrario tra le finestra, usando una finestra a comparsa" +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "Evidenzia direttamente la finestra precedente" -#: ../src/core/all-keybindings.h:163 -msgid "Move between panels and the desktop, using a popup window" -msgstr "Sposta tra i pannelli e la scrivania, usando una finestra a comparsa" +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "Evidenzia direttamente le finestre di un'applicazione" -#: ../src/core/all-keybindings.h:166 -msgid "Move backward between panels and the desktop, using a popup window" -msgstr "" -"Sposta al contrario tra i pannelli e la scrivania, usando una finestra a " -"comparsa" +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "Evidenzia direttamente la finestra precedente di un'applicazione" -#: ../src/core/all-keybindings.h:171 -msgid "Move between windows of an application immediately" -msgstr "Sposta immediatamente tra le finestre di una applicazione" +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "Evidenzia direttamente i controlli di sistema" -#: ../src/core/all-keybindings.h:174 -msgid "Move backward between windows of an application immediately" -msgstr "Sposta immediatamente al contrario tra le finestre di una applicazione" +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "Evidenzia direttamente i controlli di sistema precedenti" -#: ../src/core/all-keybindings.h:177 -msgid "Move between windows immediately" -msgstr "Sposta immediatamente tra le finestre" +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "Nasconde tutte le finestre normali" -#: ../src/core/all-keybindings.h:180 -msgid "Move backward between windows immediately" -msgstr "Sposta immediatamente al contrario tra le finestre" +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "Passa allo spazio di lavoro 1" + +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "Passa allo spazio di lavoro 2" + +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "Passa allo spazio di lavoro 3" -#: ../src/core/all-keybindings.h:183 -msgid "Move between panels and the desktop immediately" -msgstr "Sposta immediatamente tra i pannelli e la scrivania" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "Passa allo spazio di lavoro 4" -#: ../src/core/all-keybindings.h:186 -msgid "Move backward between panels and the desktop immediately" -msgstr "Sposta immediatamente al contrario tra i pannelli e la scrivania" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "Passa all'ultimo spazio di lavoro" -#: ../src/core/all-keybindings.h:203 -msgid "Hide all normal windows and set focus to the desktop" -msgstr "Nascondi tutte le finestre normali e imposta il focus sulla scrivania" +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "Sposta su spazio di lavoro in alto" -#: ../src/core/all-keybindings.h:206 -msgid "Show the panel's main menu" -msgstr "Mostra il menù principale del pannello" +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "Sposta su spazio di lavoro in basso" -#: ../src/core/all-keybindings.h:209 -msgid "Show the panel's \"Run Application\" dialog box" -msgstr "Mostra la casella di dialogo \"Esegui applicazione\" del pannello" +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "Sistema" -#: ../src/core/all-keybindings.h:211 -msgid "Start or stop recording the session" -msgstr "Avvia o interrompe la registrazione della sessione" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Mostra il prompt esegui comando" -#: ../src/core/all-keybindings.h:252 -msgid "Take a screenshot" -msgstr "Cattura una schermata" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Mostra la panoramica delle attività" -#: ../src/core/all-keybindings.h:254 -msgid "Take a screenshot of a window" -msgstr "Cattura una schermata di una finestra" +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Ripristina le scorciatoie da tastiera" -#: ../src/core/all-keybindings.h:256 -msgid "Run a terminal" -msgstr "Esegui un terminale" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Finestre" -#: ../src/core/all-keybindings.h:271 +#: data/50-mutter-windows.xml:8 msgid "Activate the window menu" msgstr "Attiva il menù della finestra" -#: ../src/core/all-keybindings.h:274 +#: data/50-mutter-windows.xml:10 msgid "Toggle fullscreen mode" -msgstr "Commuta la modalità schermo intero" +msgstr "Attiva/Disattiva la modalità schermo intero" -#: ../src/core/all-keybindings.h:276 +#: data/50-mutter-windows.xml:12 msgid "Toggle maximization state" -msgstr "Commuta lo stato massimizzazione" +msgstr "Attiva/Disattiva lo stato massimizzazione" -# uuuuufffff -#: ../src/core/all-keybindings.h:278 -msgid "Toggle whether a window will always be visible over other windows" -msgstr "Commuta la visibilità permanente di una finestra sopra le altre" - -#: ../src/core/all-keybindings.h:280 +#: data/50-mutter-windows.xml:14 msgid "Maximize window" msgstr "Massimizza la finestra" -#: ../src/core/all-keybindings.h:282 +#: data/50-mutter-windows.xml:16 msgid "Restore window" msgstr "Ripristina la finestra" -#: ../src/core/all-keybindings.h:284 -msgid "Toggle shaded state" -msgstr "Commuta lo stato arrotolato" - -#: ../src/core/all-keybindings.h:286 -msgid "Minimize window" -msgstr "Minimizza la finestra" - -#: ../src/core/all-keybindings.h:288 +#: data/50-mutter-windows.xml:18 msgid "Close window" msgstr "Chiudi la finestra" -#: ../src/core/all-keybindings.h:290 +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "Nascondi la finestra" + +#: data/50-mutter-windows.xml:22 msgid "Move window" msgstr "Muovi la finestra" -#: ../src/core/all-keybindings.h:292 +#: data/50-mutter-windows.xml:24 msgid "Resize window" msgstr "Ridimensiona la finestra" -# uuuuuuufff -#: ../src/core/all-keybindings.h:295 -msgid "Toggle whether window is on all workspaces or just one" -msgstr "" -"Commuta la presenza della finestra in tutti gli spazi di lavoro o solo in uno" - -# Nota: pur essendo il verbo originale "move" come poco sopra, è stato scelto di -# usare "Muovi" per l'azione "clic e trascina sulla barra del titolo" e -# "Sposta" per questa azione -#: ../src/core/all-keybindings.h:299 -msgid "Move window to workspace 1" -msgstr "Sposta la finestra sullo spazio di lavoro 1" - -#: ../src/core/all-keybindings.h:302 -msgid "Move window to workspace 2" -msgstr "Sposta la finestra sullo spazio di lavoro 2" - -#: ../src/core/all-keybindings.h:305 -msgid "Move window to workspace 3" -msgstr "Sposta la finestra sullo spazio di lavoro 3" +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "Attiva/Disattiva la finestra su uno o su tutti gli spazi di lavoro" -#: ../src/core/all-keybindings.h:308 -msgid "Move window to workspace 4" -msgstr "Sposta la finestra sullo spazio di lavoro 4" - -#: ../src/core/all-keybindings.h:311 -msgid "Move window to workspace 5" -msgstr "Sposta la finestra sullo spazio di lavoro 5" - -#: ../src/core/all-keybindings.h:314 -msgid "Move window to workspace 6" -msgstr "Sposta la finestra sullo spazio di lavoro 6" +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "Solleva la finestra se è coperta, in caso contrario l'abbassa" -#: ../src/core/all-keybindings.h:317 -msgid "Move window to workspace 7" -msgstr "Sposta la finestra sullo spazio di lavoro 7" +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "Solleva la finestra sopra le altre" -#: ../src/core/all-keybindings.h:320 -msgid "Move window to workspace 8" -msgstr "Sposta la finestra sullo spazio di lavoro 8" +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "Abbassa la finestra sotto le altre" -#: ../src/core/all-keybindings.h:323 -msgid "Move window to workspace 9" -msgstr "Sposta la finestra sullo spazio di lavoro 9" +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "Massimizza verticalmente la finestra" -#: ../src/core/all-keybindings.h:326 -msgid "Move window to workspace 10" -msgstr "Sposta la finestra sullo spazio di lavoro 10" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "Massimizza orizzontalmente la finestra" -#: ../src/core/all-keybindings.h:329 -msgid "Move window to workspace 11" -msgstr "Sposta la finestra sullo spazio di lavoro 11" +# scorciatoia per mettere la finestra a mezzo schermo intero sulla sinistra +# +# traduzione infedele, ma "frazionamento della vista a sn/ds" mi pare peggio +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "Massimizza a sinistra" -#: ../src/core/all-keybindings.h:332 -msgid "Move window to workspace 12" -msgstr "Sposta la finestra sullo spazio di lavoro 12" +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "Massimizza a destra" -#: ../src/core/all-keybindings.h:344 -msgid "Move window one workspace to the left" -msgstr "Sposta la finestra sullo spazio di lavoro a sinistra" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" -#: ../src/core/all-keybindings.h:347 -msgid "Move window one workspace to the right" -msgstr "Sposta la finestra sullo spazio di lavoro a destra" +#: data/org.gnome.mutter.gschema.xml.in:7 +msgid "Modifier to use for extended window management operations" +msgstr "Modificatore da utilizzare per le azioni di gestione finestre estese" -#: ../src/core/all-keybindings.h:350 -msgid "Move window one workspace up" -msgstr "Sposta la finestra sullo spazio di lavoro in alto" +#: data/org.gnome.mutter.gschema.xml.in:8 +msgid "" +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." +msgstr "" +"Questa chiave inizializza l'\"overlay\", cioè una combinazione tra la " +"panoramica delle finestre e il sistema di lancio delle applicazioni. Il " +"valore predefinito è il \"tasto Windows\" su hardware PC. È atteso che " +"questa scorciatoia sia o il valore predefinito oppure che sia impostata alla " +"stringa vuota." -#: ../src/core/all-keybindings.h:353 -msgid "Move window one workspace down" -msgstr "Sposta la finestra sullo spazio di lavoro in basso" +#: data/org.gnome.mutter.gschema.xml.in:20 +msgid "Attach modal dialogs" +msgstr "Dialoghi modali attaccati" -#: ../src/core/all-keybindings.h:356 -msgid "Raise window if it's covered by another window, otherwise lower it" +#: data/org.gnome.mutter.gschema.xml.in:21 +msgid "" +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." msgstr "" -"Solleva la finestra se è coperta da un'altra finestra, in caso contrario " -"l'abbassa" - -#: ../src/core/all-keybindings.h:358 -msgid "Raise window above other windows" -msgstr "Solleva la finestra sopra le altre finestre" +"Se impostata a VERO, invece di avere barre di titolo indipendenti, i " +"dialoghi modali appaiono attaccati alla barra del titolo della finestra " +"genitore, muovendosi assieme ad essa." -#: ../src/core/all-keybindings.h:360 -msgid "Lower window below other windows" -msgstr "Abbassa la finestra sotto le altre" +#: data/org.gnome.mutter.gschema.xml.in:30 +msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "" +"Abilita il tiling di bordo quando si trascinano le finestre sui bordi dello " +"schermo" -#: ../src/core/all-keybindings.h:364 -msgid "Maximize window vertically" -msgstr "Massimizza verticalmente la finestra" +#: data/org.gnome.mutter.gschema.xml.in:31 +msgid "" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." +msgstr "" +"Se abilitata, trascinando le finestre sui bordi verticali dello schermo, " +"queste vengono massimizzate verticalmente e ridimensionate orizzontalmente " +"in modo da coprire metà dell'area disponibile. Trascinandole sul bordo " +"superiore dello schermo le massimizza completamente." -#: ../src/core/all-keybindings.h:368 -msgid "Maximize window horizontally" -msgstr "Massimizza orizzontalmente la finestra" +#: data/org.gnome.mutter.gschema.xml.in:40 +msgid "Workspaces are managed dynamically" +msgstr "Spazi di lavoro gestiti dinamicamente" -#: ../src/core/all-keybindings.h:372 -msgid "Move window to north-west (top left) corner" -msgstr "Muovi la finestra nell'angolo nord-ovest (sinistra in alto)" +#: data/org.gnome.mutter.gschema.xml.in:41 +msgid "" +"Determines whether workspaces are managed dynamically or whether there’s a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." +msgstr "" +"Determina se gli spazi di lavoro sono gestiti dinamicamente oppure se il " +"loro numero è fisso (determinato dalla chiave num-workspaces in org.gnome." +"desktop.wm.preferences)." -#: ../src/core/all-keybindings.h:375 -msgid "Move window to north-east (top right) corner" -msgstr "Muovi la finestra nell'angolo nord-est (destra in alto)" +#: data/org.gnome.mutter.gschema.xml.in:50 +msgid "Workspaces only on primary" +msgstr "Spazi di lavoro solo sul primario" -#: ../src/core/all-keybindings.h:378 -msgid "Move window to south-west (bottom left) corner" -msgstr "Muovi la finestra nell'angolo sud-ovest (sinistra in basso)" +# mica ho capito cosa fa... +#: data/org.gnome.mutter.gschema.xml.in:51 +msgid "" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." +msgstr "" +"Determina se il cambio di spazio di lavoro debba avvenire per le finestre su " +"tutti i monitor oppure solo per le finestre sul monitor primario." -#: ../src/core/all-keybindings.h:381 -msgid "Move window to south-east (bottom right) corner" -msgstr "Muovi la finestra nell'angolo sud-est (destra in basso)" +# mah... sarebbe "popup quando si fa alt-tab", credo +#: data/org.gnome.mutter.gschema.xml.in:59 +msgid "No tab popup" +msgstr "Nessun tab popup" -#: ../src/core/all-keybindings.h:385 -msgid "Move window to north (top) side of screen" -msgstr "Muovi la finestra sul lato nord (in alto) dello schermo" +#: data/org.gnome.mutter.gschema.xml.in:60 +msgid "" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." +msgstr "" +"Determina se disabilitare l'uso di popup e cornici di evidenziatura nel " +"passare da una finestra all'altra." -#: ../src/core/all-keybindings.h:388 -msgid "Move window to south (bottom) side of screen" -msgstr "Muovi la finestra sul lato sud (in basso) dello schermo" +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Ritarda il cambio del focus fino a quando il puntatore si ferma" -#: ../src/core/all-keybindings.h:391 -msgid "Move window to east (right) side of screen" -msgstr "Muovi la finestra sul lato est (desta) dello schermo" +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" +"Se impostato a VERO, e la modalità di focus è impostata a \"sloppy\" o " +"\"mouse\", il focus non viene spostato immediatamente quando si passa su una " +"finestra, ma solo quando il puntatore si ferma." -#: ../src/core/all-keybindings.h:394 -msgid "Move window to west (left) side of screen" -msgstr "Muovi la finestra sul lato ovest (sinistra) dello schermo" +#: data/org.gnome.mutter.gschema.xml.in:79 +msgid "Draggable border width" +msgstr "Larghezza bordo trascinabile" -#: ../src/core/all-keybindings.h:397 -msgid "Move window to center of screen" -msgstr "Muovi la finestra al centro dello schermo" +#: data/org.gnome.mutter.gschema.xml.in:80 +msgid "" +"The amount of total draggable borders. If the theme’s visible borders are " +"not enough, invisible borders will be added to meet this value." +msgstr "" +"Lo spessore effettivo totale per i bordi trascinabili. Se i bordi visibili " +"del tema non sono sufficienti, vengono aggiunti dei bordi invisibili per " +"raggiungere questo valore." -#: ../src/core/bell.c:310 -msgid "Bell event" -msgstr "Evento campanella" +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "Massimizza automaticamente finestre grandi quasi quanto lo schermo" + +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" +"Se abilitato, le nuove finestre che hanno inizialmente la stessa dimensione " +"del monitor vengono massimizzate automaticamente." + +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Posiziona le nuove finestre al centro" + +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" +"Se impostata a VERO, le nuove finestre verranno sempre posizionate al centro " +"dello schermo attivo." + +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Abilita funzionalità sperimentali" + +#: data/org.gnome.mutter.gschema.xml.in:108 +msgid "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes " +"mutter request a low priority real-time scheduling. The executable or user " +"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — " +"initializes Xwayland lazily if there are X11 clients. Requires restart." +msgstr "" +"Per abilitare le funzionalità sperimentali, aggiungere la parola chiave di " +"tale funzionalità nella lista. Se la funzionalità desiderata richiede il " +"riavvio del compositor, dipende dalla funzionalità stessa. Una qualsiasi " +"funzionalità sperimentale non è richiesta, ma può essere disponibile e " +"configurabile. Le funzionalità offerte potrebbero rendere il sistema " +"instabile. I possibili valori sono: • \"scale-monitor-framebuffer\" — Fa in " +"modo che mutter disponga gli schermi logici secondo uno spazio logico di " +"coordinate pixel, applicando il ridimensionamento ai framebuffer invece che " +"al contenuto della finestra, per gestire schermi HiDPI (non richiede il " +"riavvio). • “rt-scheduler” — Richiede uno scheduling real-time a bassa " +"priorità. L'eseguibile o l'utente deve avere la proprietà CAP_SYS_NICE " +"(richiede il riavvio). • “autostart-xwayland” — Avvia Xwayland passivamente " +"se ci sono client X11 (richiede il riavvio)." -# notare l'abilità con cui nella traduzione non si capisce -# se sconosciuta è la finestra o la richiesta :-) --Luca -#: ../src/core/core.c:157 +#: data/org.gnome.mutter.gschema.xml.in:134 +msgid "Modifier to use to locate the pointer" +msgstr "Modificatore da usare per trovare il puntatore" + +#: data/org.gnome.mutter.gschema.xml.in:135 +msgid "This key will initiate the “locate pointer” action." +msgstr "Questa chiave avvia l'azione di localizzazione del puntatore." + +#: data/org.gnome.mutter.gschema.xml.in:142 +msgid "Timeout for check-alive ping" +msgstr "Timeout per il ping di controllo" + +#: data/org.gnome.mutter.gschema.xml.in:143 +msgid "" +"Number of milliseconds a client has to respond to a ping request in order to " +"not be detected as frozen. Using 0 will disable the alive check completely." +msgstr "" +"Numero di millisecondi entro cui un client deve rispondere a una richiesta " +"di ping per non essere rilevato come bloccato. Utilizzando 0 si disattiva " +"completamente il controllo." + +#: data/org.gnome.mutter.gschema.xml.in:165 +msgid "Select window from tab popup" +msgstr "Seleziona finestra dal tab popup" + +#: data/org.gnome.mutter.gschema.xml.in:170 +msgid "Cancel tab popup" +msgstr "Annulla tab popup" + +#: data/org.gnome.mutter.gschema.xml.in:175 +msgid "Switch monitor configurations" +msgstr "Cambia le configurazioni del monitor" + +#: data/org.gnome.mutter.gschema.xml.in:180 +msgid "Rotates the built-in monitor configuration" +msgstr "Passa da una configurazione integrata all'altra del monitor" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Passa al VT 1" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Passa al VT 2" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Passa al VT 3" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Passa al VT 4" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Passa al VT 5" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Passa al VT 6" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Passa al VT 7" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Passa al VT 8" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Passa al VT 9" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Passa al VT 10" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Passa al VT 11" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Passa al VT 12" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "Riabilita scorciatoie" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow X11 grabs to lock keyboard focus with Xwayland" +msgstr "" +"Consente alle catture X11 di bloccare il focus della tastiera con Xwayland" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 +msgid "" +"Allow all keyboard events to be routed to X11 “override redirect” windows " +"with a grab when running in Xwayland. This option is to support X11 clients " +"which map an “override redirect” window (which do not receive keyboard " +"focus) and issue a keyboard grab to force all keyboard events to that " +"window. This option is seldom used and has no effect on regular X11 windows " +"which can receive keyboard focus under normal circumstances. For a X11 grab " +"to be taken into account under Wayland, the client must also either send a " +"specific X11 ClientMessage to the root window or be among the applications " +"white-listed in key “xwayland-grab-access-rules”." +msgstr "" +"Consente a tutti gli eventi della tastiera di essere instradati verso " +"finestre \"override redirect\" di X11 con cattura quando in esecuzione in " +"Xwayland. Questa opzione serve per supportare i client X11 che mappano una " +"finestra \"override redirect\" (che non riceve il focus da tastiera) ed " +"emette una cattura della tastiera per forzare tutti gli eventi da tastiera " +"verso quella finestra. Questa opzione non viene usata raramente e non ha " +"alcun effetto sulle finestra X11 normali in grado di ricevere, in " +"circostanze normali, il focus da tastiera. Affinché la cattura X11 venga " +"considerata da Wayland, il client deve inviare uno specifico messaggio " +"ClientMessage X11 alla finestra principale o essere nell'elenco di " +"applicazioni autorizzate tramite la chiave \"xwayland-grab-access-rules\"." + +#: data/org.gnome.mutter.wayland.gschema.xml.in:84 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "" +"Applicazioni Xwayland autorizzare a inizializzare catture della tastiera" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:85 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "" +"Lista di nomi o classi delle risorse di finestre X11 autorizzate o meno a " +"inizializzare la cattura della tastiera X11 su Xwayland. Per ottenere i nomi " +"o le classi delle risorse di una finestra X11 è possibile utilizzare il " +"comando \"xprop WM_CLASS\". Sono consentiti i caratteri \"*\" e \"?" +"\" (asterisco e punto di domanda) nei valori. Valori che iniziano con \"!\" " +"indicano una risorsa da escludere che ha priorità più alta rispetto alle " +"applicazioni autorizzate. La lista predefinita di sistema include le " +"seguenti applicazioni: \"@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@\" Gli utenti " +"possono interrompere una cattura esistente utilizzando la scorciatoia " +"definita nella chiave \"restore-shortcuts\"." + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. +#. +#: src/backends/meta-input-settings.c:2567 #, c-format -msgid "Unknown window information request: %d" -msgstr "Richiesta informazioni finestra sconosciuta: %d" +msgid "Mode Switch (Group %d)" +msgstr "Cambio modalità (gruppo %d)" -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "Nessuna risposta da <tt>%s</tt>." +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2590 +msgid "Switch monitor" +msgstr "Cambia monitor" -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "L'applicazione non risponde." +#: src/backends/meta-input-settings.c:2592 +msgid "Show on-screen help" +msgstr "Mostra aiuto sullo schermo" -#: ../src/core/delete.c:119 -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "" -"È possibile scegliere di attendere un po' lasciando che l'applicazione " -"continui, oppure forzare la terminazione dell'applicazione." +#: src/backends/meta-monitor.c:223 +msgid "Built-in display" +msgstr "Display integrato" -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "_Attendi" +#: src/backends/meta-monitor.c:252 +msgid "Unknown" +msgstr "Sconosciuto" -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "_Forza uscita" +#: src/backends/meta-monitor.c:254 +msgid "Unknown Display" +msgstr "Display sconosciuto" -#: ../src/core/display.c:365 +#: src/backends/meta-monitor.c:262 #, c-format -msgid "Missing %s extension required for compositing" -msgstr "Estensione %s richiesta per il compositing mancante" +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" -#: ../src/core/display.c:431 +#: src/backends/meta-monitor.c:270 #, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Apertura del display «%s» di X Window System non riuscita\n" +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" -#: ../src/core/keybindings.c:759 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "" -"Qualche altro programma sta già usando il tasto %s con i modificatori %x " -"come una associazione di tasti\n" +#. Translators: this string will appear in Sysprof +#: src/backends/meta-profiler.c:79 +msgid "Compositor" +msgstr "Compositor" -#. Displayed when a keybinding which is -#. * supposed to launch a program fails. -#. -#: ../src/core/keybindings.c:2523 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:533 #, c-format msgid "" -"There was an error running <tt>%s</tt>:\n" -"\n" -"%s" +"Another compositing manager is already running on screen %i on display “%s”." msgstr "" -"Si è verificato un errore nell'eseguire <tt>%s</tt>:\n" -"\n" -"%s." - -#: ../src/core/keybindings.c:2613 -#, c-format -msgid "No command %d has been defined.\n" -msgstr "Non è stato definito alcuno comando %d.\n" +"Un altro compositing manager è già in esecuzione sullo schermo %i sul " +"display «%s»." -# "comando di terminale" o "comando «terminal»" ??? -#: ../src/core/keybindings.c:3625 -#, c-format -msgid "No terminal command has been defined.\n" -msgstr "Non è stato definito alcun comando di terminale.\n" +#: src/core/bell.c:192 +msgid "Bell event" +msgstr "Evento campanella" -#: ../src/core/main.c:206 +#: src/core/main.c:190 msgid "Disable connection to session manager" msgstr "Disabilita la connessione al gestore di sessione" -#: ../src/core/main.c:212 +#: src/core/main.c:196 msgid "Replace the running window manager" msgstr "Sostituisce il window manager in esecuzione" -#: ../src/core/main.c:218 +#: src/core/main.c:202 msgid "Specify session management ID" msgstr "Specifica l'ID di gestione sessione" -#: ../src/core/main.c:223 +#: src/core/main.c:207 msgid "X Display to use" msgstr "Display X da usare" -#: ../src/core/main.c:229 +#: src/core/main.c:213 msgid "Initialize session from savefile" msgstr "Inizializza la sessione da file salvato" -#: ../src/core/main.c:235 +#: src/core/main.c:219 msgid "Make X calls synchronous" msgstr "Rende le chiamate X sincrone" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Scansione della directory dei temi non riuscita: %s\n" +#: src/core/main.c:226 +msgid "Run as a wayland compositor" +msgstr "Esegui come compositor Wayland" + +#: src/core/main.c:232 +msgid "Run as a nested compositor" +msgstr "Esegui come compositor annidato" -#: ../src/core/main.c:520 +#: src/core/main.c:238 +msgid "Run wayland compositor without starting Xwayland" +msgstr "Esegui il compositor Wayland senza avviare Xwayland" + +#: src/core/main.c:246 +msgid "Run as a full display server, rather than nested" +msgstr "Esegui come display server invece che annidato" + +#: src/core/main.c:252 +msgid "Run with X11 backend" +msgstr "Esegui con sistema X11" + +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:151 #, c-format +msgid "“%s” is not responding." +msgstr "Nessuna risposta da %s." + +#: src/core/meta-close-dialog-default.c:153 +msgid "Application is not responding." +msgstr "L'applicazione non risponde." + +#: src/core/meta-close-dialog-default.c:158 msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." msgstr "" -"Non è stato trovato alcun tema. Assicurarsi che %s esista e contenga i temi " -"standard.\n" +"È possibile scegliere di attendere un po' lasciando che l'applicazione " +"continui, oppure forzare la terminazione dell'applicazione." + +#: src/core/meta-close-dialog-default.c:165 +msgid "_Force Quit" +msgstr "_Forza uscita" + +#: src/core/meta-close-dialog-default.c:165 +msgid "_Wait" +msgstr "_Attendi" -#: ../src/core/muffin.c:42 +#: src/core/mutter.c:38 #, c-format msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" "This is free software; see the source for copying conditions.\n" "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " "PARTICULAR PURPOSE.\n" msgstr "" -"muffin %s\n" +"mutter %s\n" "Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., e altri\n" "Questo è software libero; si vedano i sorgenti per le condizioni di copia.\n" "NON è fornita alcuna garanzia; neanche di COMMERCIABILITÀ o\n" "APPLICABILITÀ PER UNO SCOPO PARTICOLARE.\n" -#: ../src/core/muffin.c:56 +#: src/core/mutter.c:52 msgid "Print version" msgstr "Stampa la versione" -#: ../src/core/muffin.c:62 -msgid "Comma-separated list of compositor plugins" -msgstr "Elenco separato da virgole dei plugin del compositor" - -#. -#. * We found it, but it was invalid. Complain. -#. * -#. * FIXME: This replicates the original behaviour, but in the future -#. * we might consider reverting invalid keys to their original values. -#. * (We know the old value, so we can look up a suitable string in -#. * the symtab.) -#. * -#. * (Empty comment follows so the translators don't see this.) -#. -#. -#: ../src/core/prefs.c:550 ../src/core/prefs.c:711 -#, c-format -msgid "GConf key '%s' is set to an invalid value\n" -msgstr "La chiave GConf «%s» è impostata ad un valore non valido\n" - -# lasciato "Il valore" iniziale che c'era in precendeza -#: ../src/core/prefs.c:637 ../src/core/prefs.c:880 -#, c-format -msgid "%d stored in GConf key %s is out of range %d to %d\n" -msgstr "" -"Il valore %d memorizzato nella chiave GConf %s è fuori dall'intervallo da %d " -"a %d\n" - -#: ../src/core/prefs.c:681 ../src/core/prefs.c:758 ../src/core/prefs.c:806 -#: ../src/core/prefs.c:870 ../src/core/prefs.c:1331 ../src/core/prefs.c:1347 -#: ../src/core/prefs.c:1364 ../src/core/prefs.c:1380 -#, c-format -msgid "GConf key \"%s\" is set to an invalid type\n" -msgstr "La chiave GConf «%s» è impostata ad un tipo non valido\n" - -#: ../src/core/prefs.c:1210 -#, c-format -msgid "GConf key %s is already in use and can't be used to override %s\n" -msgstr "" -"La chiave GConf %s è già in uso e non può essere usata per scavalcare %s\n" - -#: ../src/core/prefs.c:1269 -#, c-format -msgid "Can't override GConf key, %s not found\n" -msgstr "Impossibile scavalcare la chiave GConf, %s non trovato\n" - -#: ../src/core/prefs.c:1454 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"Disabilitate le funzionalità palliative per la applicazioni difettose. " -"Alcune applicazioni potrebbero avere comportamenti errati.\n" - -#: ../src/core/prefs.c:1531 -#, c-format -msgid "Could not parse font description \"%s\" from GConf key %s\n" -msgstr "" -"Impossibile analizzare la descrizione del tipo di carattere «%s» dalla chiave " -"GConf %s\n" - -#: ../src/core/prefs.c:1593 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"Il valore «%s» trovato nel database di configurazione non è valido per il " -"modificatore del tasto del mouse\n" - -#: ../src/core/prefs.c:2028 -#, c-format -msgid "Error setting number of workspaces to %d: %s\n" -msgstr "Errore nell'impostare il numero di spazi di lavoro a %d: %s\n" +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "Plugin Mutter da usare" -#: ../src/core/prefs.c:2212 ../src/core/prefs.c:2714 +#: src/core/prefs.c:1911 #, c-format msgid "Workspace %d" msgstr "Spazio di lavoro %d" -#: ../src/core/prefs.c:2244 ../src/core/prefs.c:2422 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "" -"Il valore «%s» nel database di configurazione non è valido per l'associazione " -"di tasti «%s»\n" - -#: ../src/core/prefs.c:2795 -#, c-format -msgid "Error setting name for workspace %d to \"%s\": %s\n" -msgstr "Errore nell'impostare il nome dello spazio di lavoro %d a «%s»: %s\n" - -# eeeehhh???? -#: ../src/core/prefs.c:3009 -#, c-format -msgid "Error setting live hidden windows status status: %s\n" -msgstr "Errore nell'impostare lo stato \"stato finestre live nascoste\": %s\n" - -# eeeehhh???? -#: ../src/core/prefs.c:3044 -#, c-format -msgid "Error setting no tab popup status: %s\n" -msgstr "Errore nell'impostare lo stato \"niente tab popup\": %s\n" - -#: ../src/core/screen.c:663 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "Lo schermo %d nel display «%s» non è valido\n" - -#: ../src/core/screen.c:679 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"Lo schermo %d sul display «%s» ha già un window manager; provare a utilizzare " -"l'opzione --replace per sostituirlo.\n" - -#: ../src/core/screen.c:706 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "" -"Impossibile acquisire la selezione del window manager per lo schermo %d nel " -"display «%s»\n" - -#: ../src/core/screen.c:761 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "Lo schermo %d sul display «%s» ha già un window manager\n" - -#: ../src/core/screen.c:946 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "Impossibile rilasciare lo schermo %d sul display «%s»\n" - -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Impossibile creare la directory «%s»: %s\n" - -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "Impossibile aprire il file di sessione «%s» in scrittura: %s\n" - -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Errore nello scrivere il file di sessione «%s»: %s\n" - -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Errore nel chiudere il file di sessione «%s»: %s\n" - -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Analisi del file della sessione salvato non riuscita: %s\n" - -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" +#: src/core/util.c:122 +msgid "Mutter was compiled without support for verbose mode\n" msgstr "" -"Attributo <muffin_session> individuato, ma è già presente un ID della " -"sessione" - -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Attributo %s sconosciuto per l'elemento <%s>" +"Mutter è stato compilato escludendo il supporto per la modalità prolissa\n" -#: ../src/core/session.c:1215 +#: src/wayland/meta-wayland-tablet-pad.c:568 #, c-format -msgid "nested <window> tag" -msgstr "tag <window> annidato" +msgid "Mode Switch: Mode %d" +msgstr "Cambio modalità: modalità %d" -#: ../src/core/session.c:1457 +#: src/x11/meta-x11-display.c:676 #, c-format -msgid "Unknown element %s" -msgstr "Elemento %s sconosciuto" - -#: ../src/core/session.c:1809 msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." msgstr "" -"Queste finestre non supportano la funzione "salva impostazioni " -"attuali" e dovranno essere riavviate manualmente al prossimo accesso." +"Il display «%s» ha già un window manager; provare a utilizzare l'opzione --" +"replace per sostituirlo." -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Apertura nel file di registro di debug non riuscita: %s\n" +#: src/x11/meta-x11-display.c:1089 +msgid "Failed to initialize GDK\n" +msgstr "Inizializzazione GDK non riuscita\n" -#: ../src/core/util.c:121 +#: src/x11/meta-x11-display.c:1113 #, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Esecuzione di fdopen() sul file di registro %s non riuscita: %s\n" +msgid "Failed to open X Window System display “%s”\n" +msgstr "Apertura del display «%s» di X Window System non riuscita\n" -#: ../src/core/util.c:127 +#: src/x11/meta-x11-display.c:1196 #, c-format -msgid "Opened log file %s\n" -msgstr "File di registro %s aperto\n" +msgid "Screen %d on display “%s” is invalid\n" +msgstr "Lo schermo %d sul display «%s» non è valido\n" -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 +#: src/x11/meta-x11-selection-input-stream.c:460 #, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "" -"Muffin è stato compilato escludendo il supporto per la modalità prolissa\n" - -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "Window manager: " - -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "Bug nel window manager: " - -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "Avviso del window manager: " +msgid "Format %s not supported" +msgstr "Formato %s non supportato" -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "Errore del window manager: " - -#. first time through -#: ../src/core/window.c:7019 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"La finestra %s ha impostato SM_CLIENT_ID su se stessa, invece che sulla " -"finestra WM_CLIENT_LEADER come da specifiche ICCCM.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7682 -#, c-format +#: src/x11/session.c:1821 msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %" -"d x %d and max size %d x %d; this doesn't make much sense.\n" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." msgstr "" -"La finestra %s ha impostato un hint MWM indicando che non è " -"ridimensionabile, ma ha impostato la dimensione minima %d x %d e la " -"dimensione massima %d x %d; ciò non ha senso.\n" - -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "L'applicazione ha impostato un _NET_WM_PID errato %lu\n" +"Queste finestre non supportano la funzione «salva impostazioni attuali» e " +"dovranno essere riavviate manualmente al prossimo accesso." -#: ../src/core/window-props.c:426 +#: src/x11/window-props.c:569 #, c-format msgid "%s (on %s)" msgstr "%s (su %s)" - -# Sì, direi che è oscuro -Luca -# -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "Specificato un WM_TRANSIENT_FOR finestra 0x%lx non valido per %s.\n" - -# Sì, direi che è oscuro -Luca -# -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "WM_TRANSIENT_FOR finestra 0x%lx per %s potrebbe creare un loop.\n" - -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"La finestra 0x%lx ha la proprietà %s\n" -"che era attesa avere tipo %s formato %d\n" -"e in realtà ha tipo %s formato %d n_items %d.\n" -"Molto probabilmente è un bug dell'applicazione, non del window manager.\n" -"La finestra presenta titolo=\"%s\" classe=\"%s\" nome=\"%s\"\n" - -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "La proprietà %s sulla finestra 0x%lx contiene UTF-8 non valido\n" - -#: ../src/core/xprops.c:494 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"La proprietà %s sulla finestra 0x%lx contiene UTF-8 non valido per " -"l'elemento %d nella lista\n" - -#: ../src/muffin.desktop.in.h:1 ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" - -#: ../src/muffin.schemas.in.h:1 -msgid "Attach modal dialogs" -msgstr "Dialoghi modali attaccati" - -# FIXME alive????!??!??!??! -#: ../src/muffin.schemas.in.h:2 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"Determina se le finestre nascoste (cioè le finestre minimizzate e quelle " -"sugli spazi di lavoro diversi da quello corrente) debbano essere tenute " -"alive." - -# mica ho capito cosa fa... -#: ../src/muffin.schemas.in.h:3 -msgid "" -"Determines whether workspace switching should happen for windows on all " -"monitors or only for windows on the primary monitor." -msgstr "" -"Determina se il cambio di spazio di lavoro debba avvenire per le finestre su " -"tutti i monitor oppure solo per le finestre sul monitor primario." - -#: ../src/muffin.schemas.in.h:4 -msgid "Draggable border width" -msgstr "Larghezza bordo trascinabile" - -#: ../src/muffin.schemas.in.h:5 -msgid "Live Hidden Windows" -msgstr "Finestre nascoste live" - -#: ../src/muffin.schemas.in.h:6 -msgid "Modifier to use for extended window management operations" -msgstr "Modificatore da utilizzare per le azioni di gestione finestre estese" - -#: ../src/muffin.schemas.in.h:7 -msgid "" -"The amount of total draggable borders. If the theme's visible borders are " -"not enough, invisible borders will be added to meet this value." -msgstr "" -"Lo spessore effettivo totale per i bordi trascinabili. Se i bordi visibili " -"del tema non sono sufficienti, vengono aggiunti dei bordi invisibili per " -"raggiungere questo valore." - -#: ../src/muffin.schemas.in.h:8 -msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." -msgstr "" -"Questa chiave pone inizio alla \"overlay\", cioè una combinazione tra la " -"panoramica delle finestre e il sistema di lancio delle applicazioni. Il " -"valore predefinito è il \"tasto Windows\" su hardware PC. È atteso che " -"questa scorciatoia sia o il valore predefinito, oppure che sia impostata " -"alla stringa vuota." - -#: ../src/muffin.schemas.in.h:9 -msgid "" -"When true, instead of having independent titlebars, modal dialogs appear " -"attached to the titlebar of the parent window and are moved together with " -"the parent window." -msgstr "" -"Se impostata a VERO, invece di avere barre di titolo indipendenti, i " -"dialoghi modali appaiono attaccati alla barra del titolo della finestra " -"genitore, muovendosi assieme ad essa." - -#: ../src/muffin.schemas.in.h:10 -msgid "Workspaces only on primary" -msgstr "Spazi di lavoro solo sul primario" - -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "Uso: %s\n" - -# Questo e i successivi simili sono tooltip -# per i pulsanti della cornice. -#: ../src/ui/frames.c:1157 -msgid "Close Window" -msgstr "Chiude la finestra" - -#: ../src/ui/frames.c:1160 -msgid "Window Menu" -msgstr "Menù finestra" - -#: ../src/ui/frames.c:1163 -msgid "Minimize Window" -msgstr "Minimizza la finestra" - -#: ../src/ui/frames.c:1166 -msgid "Maximize Window" -msgstr "Massimizza la finestra" - -# ==demassimizza -#: ../src/ui/frames.c:1169 -msgid "Restore Window" -msgstr "Ripristina la finestra" - -#: ../src/ui/frames.c:1172 -msgid "Roll Up Window" -msgstr "Arrotola la finestra" - -#: ../src/ui/frames.c:1175 -msgid "Unroll Window" -msgstr "Srotola la finestra" - -#: ../src/ui/frames.c:1178 -msgid "Keep Window On Top" -msgstr "Tiene la finestra in primo piano" - -#: ../src/ui/frames.c:1181 -msgid "Remove Window From Top" -msgstr "Rimuove la finestra dalla primo piano" - -#: ../src/ui/frames.c:1184 -msgid "Always On Visible Workspace" -msgstr "Sempre sullo spazio di lavoro visibile" - -#: ../src/ui/frames.c:1187 -msgid "Put Window On Only One Workspace" -msgstr "Pone la finestra su un solo spazio di lavoro" - -# mantenere in sync con libwnck -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "_Minimizza" - -# mantenere in sync con libwnck -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "Ma_ssimizza" - -# mantenere in sync con libwnck -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "Dema_ssimizza" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "Arr_otola" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "Sr_otola" - -# mantenere in sync con libwnck -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "M_uovi" - -# mantenere in sync con libwnck -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "_Ridimensiona" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "Muovi barra del titolo su _schermo" - -# mantenere in sync con libwnck -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "Sempre in _primo piano" - -# mantenere in sync con libwnck -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "Sempre su spazio di lavoro _visibile" - -# mantenere in sync con libwnck -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "Solo su _questo spazio di lavoro" - -# mantenere in sync con libwnck -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "Sposta su spazio di lavoro a s_inistra" - -# mantenere in sync con libwnck -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "Sposta su spazio di lavoro a d_estra" - -# mantenere in sync con libwnck -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "Sposta su spazio di lavoro in alt_o" - -# mantenere in sync con libwnck -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "Sposta su spazio di lavoro in _basso" - -# mantenere in sync con libwnck -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "_Chiudi" - -# mantenere in sync con libwnck -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "Spazio di lavoro %d%n" - -# mantenere in sync con libwnck -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "Spazio di lavoro 1_0" - -# mantenere in sync con libwnck -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "Spazio di lavoro %s%d" - -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "Sposta su _altro spazio di lavoro" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Maiusc" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" - -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d × %d" - -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "alto" - -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "basso" - -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "sinistra" - -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "destra" - -#: ../src/ui/theme.c:286 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "la geometria della cornice non specifica la dimensione «%s»" - -#: ../src/ui/theme.c:305 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "" -"la geometria della cornice non specifica la dimensione «%s» per il bordo «%s»" - -#: ../src/ui/theme.c:342 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "Le proporzioni %g del pulsante non sono ragionevoli" - -#: ../src/ui/theme.c:354 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "La geometria della cornice non specifica la dimensione dei pulsanti" - -#: ../src/ui/theme.c:1060 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "I gradienti dovrebbero avere almeno due colori" - -#: ../src/ui/theme.c:1212 -#, c-format -msgid "" -"GTK custom color specification must have color name and fallback in " -"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" -msgstr "" -"La specificazione dei colori personalizzati GTK deve presentare un nome di " -"colore e un ripiego tra parentesi, per es. gtk:custom(foo,bar); impossibile " -"analizzare \"%s\"" - -#: ../src/ui/theme.c:1228 -#, c-format -msgid "" -"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" -"_ are valid" -msgstr "" -"Carattere \"%c\" non valido nel parametro color_name di gtk:custom, sono " -"validi solo A-Za-z0-9-_" - -#: ../src/ui/theme.c:1242 -#, c-format -msgid "" -"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " -"fit the format" -msgstr "" -"Il formato per Gtk:custom è \"gtk:custom(color_name,fallback)\", «%s» non è " -"adatto a tale formato" - -#: ../src/ui/theme.c:1287 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"La specificazione del colore GTK deve avere lo stato fra parentesi, per es. " -"gtk:fg[NORMAL] dove NORMAL è lo stato; impossibile analizzare \"%s\"" - -#: ../src/ui/theme.c:1301 -#, c-format -msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"La specificazione del colore GTK deve avere una parentesi di chiusura dopo " -"lo stato, per es. gtk:fg[NORMAL] dove NORMAL è lo stato; impossibile " -"analizzare \"%s\"" - -#: ../src/ui/theme.c:1312 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "Stato «%s» incomprensibile nella specificazione del colore" - -#: ../src/ui/theme.c:1325 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "" -"Componente di colore «%s» incomprensibile nella specificazione del colore" - -#: ../src/ui/theme.c:1355 -#, c-format -msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" -msgstr "" -"Il formato della sfumature è «blend/bg_color/fg_color/alpha», «%s» non è " -"adatto a tale formato" - -#: ../src/ui/theme.c:1366 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "Impossibile analizzare il valore alpha «%s» nel colore sfumato" - -#: ../src/ui/theme.c:1376 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "Il valore alpha «%s» nel colore sfumato non è compreso tra 0.0 e 1.0" - -#: ../src/ui/theme.c:1423 -#, c-format -msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "" -"Il formato dell'ombreggiatura è «shade/base_color/factor», «%s» non è adatto a " -"tale formato" - -#: ../src/ui/theme.c:1434 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "" -"Impossibile analizzare il fattore di ombreggiatura «%s» nel colore ombreggiato" - -#: ../src/ui/theme.c:1444 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "Il fattore di ombreggiatura «%s» nel colore ombreggiato è negativo" - -#: ../src/ui/theme.c:1473 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Impossibile analizzare il colore «%s»" - -#: ../src/ui/theme.c:1784 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "" -"L'espressione delle coordinate contiene il carattere «%s» che non è consentito" - -#: ../src/ui/theme.c:1811 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "" -"L'espressione delle coordinate contiene il numero in virgola mobile «%s» che " -"non può essere analizzato" - -#: ../src/ui/theme.c:1825 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "" -"L'espressione delle coordinate contiene l'intero «%s» che non può essere " -"analizzato" - -#: ../src/ui/theme.c:1947 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "" -"L'espressione delle coordinate contiene un operatore sconosciuto all'inizio " -"di questo testo: \"%s\"" - -#: ../src/ui/theme.c:2004 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "L'espressione delle coordinate è vuota o incomprensibile" - -#: ../src/ui/theme.c:2115 ../src/ui/theme.c:2125 ../src/ui/theme.c:2159 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "" -"L'espressione delle coordinate ha come risultato una divisione per zero" - -#: ../src/ui/theme.c:2167 -#, c-format -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "" -"L'espressione delle coordinate tenta di usare un operatore mod su un numero " -"in virgola mobile" - -#: ../src/ui/theme.c:2223 -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "" -"L'espressione delle coordinate ha un operatore «%s» dove è atteso un operando" - -#: ../src/ui/theme.c:2232 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "" -"L'espressione delle coordinate ha un operando dove è atteso un operatore" - -#: ../src/ui/theme.c:2240 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "" -"L'espressione delle coordinate finisce con un operatore invece che un " -"operando" - -#: ../src/ui/theme.c:2250 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" -"L'espressione delle coordinate ha l'operatore «%c» seguito dall'operatore «%c» " -"senza un operando fra i due" - -#: ../src/ui/theme.c:2401 ../src/ui/theme.c:2446 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "" -"L'espressione delle coordinate ha la variabile o la costante «%s» sconosciuta" - -#: ../src/ui/theme.c:2500 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "" -"L'analizzatore dell'espressione delle coordinate ha superato il proprio " -"buffer." - -#: ../src/ui/theme.c:2529 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "" -"L'espressione delle coordinate ha una parentesi di chiusura senza la " -"relativa di apertura" - -#: ../src/ui/theme.c:2593 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "" -"L'espressione delle coordinate ha una parentesi di apertura senza la " -"relativa di chiusura" - -#: ../src/ui/theme.c:2604 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "" -"L'espressione delle coordinate non sembra avere né operatori né operandi" - -#: ../src/ui/theme.c:2816 ../src/ui/theme.c:2836 ../src/ui/theme.c:2856 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "Il tema contiene un'espressione che ha come risultato un errore: %s\n" - -#: ../src/ui/theme.c:4527 -#, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" -"È necessario specificare <button function=\"%s\" state=\"%s\" draw_ops=" -"\"whatever\"/> per questo stile di cornice" - -#: ../src/ui/theme.c:5060 ../src/ui/theme.c:5085 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" -"Risulta mancante <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=" -"\"whatever\"/>" - -#: ../src/ui/theme.c:5133 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Caricamento del tema «%s» non riuscito: %s\n" - -#: ../src/ui/theme.c:5269 ../src/ui/theme.c:5276 ../src/ui/theme.c:5283 -#: ../src/ui/theme.c:5290 ../src/ui/theme.c:5297 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "Nessun <%s> impostato per il tema «%s»" - -#: ../src/ui/theme.c:5305 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" -"Nessuno stile di cornice impostato per il tipo di finestra «%s» nel tema «%s», " -"aggiungere un elemento <window type=\"%s\" style_set=\"whatever\"/>" - -#: ../src/ui/theme.c:5744 ../src/ui/theme.c:5806 ../src/ui/theme.c:5869 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" -"Le costanti definite dall'utente devono iniziare con una lettera maiuscola, «%" -"s» non lo fa" - -#: ../src/ui/theme.c:5752 ../src/ui/theme.c:5814 ../src/ui/theme.c:5877 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "La costante «%s» è già definita" - -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. -#. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "Nessun attributo «%s» nell'elemento <%s>" - -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Riga %d carattere %d: %s" - -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "L'attributo «%s» è ripetuto due volte nello stesso elemento <%s>" - -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "L'attributo «%s» non è valido nell'elemento <%s> in questo contesto" - -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "Impossibile analizzare «%s» come un intero" - -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "Non sono stati compresi i caratteri di chiusura «%s» nella stringa «%s»" - -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "L'intero %ld deve essere positivo" - -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "L'intero %ld è troppo grande, il massimo corrente è %d" - -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "Impossibile analizzare «%s» come numero in virgola mobile" - -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "I valori booleani devono essere «true» o «false», non «%s»" - -# cambiato il finale, ma se è errore, vuol dire che %g è sbagliato.. -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "L'angolo deve essere tra 0.0 e 360.0, non %g\n" - -# come sopra -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "Alpha deve essere tra 0.0 (trasparente) e 1.0 (opaco), non %g\n" - -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"Taglia del titolo «%s» non valida (deve essere xx-small, x-small, small, " -"medium,large, x-large, o xx-large)\n" - -# element_name, name -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "Nome «%2$s» di <%1$s> usato una seconda volta" - -# element_name, parent -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "Il genitore «%2$s» di <%1$s> non è stato definito" - -# element_name, geometry -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "La geometria «%2$s» di <%1$s> non è stata definita" - -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "<%s> deve specificare una geometria o un genitore che ha una geometria" - -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "" -"È necessario specificare uno sfondo per un valore alpha affinché sia " -"significativo" - -# in base al successivo, type dovrebbe essere parola chiave.... -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "type «%s» sconosciuto nell'elemento <%s>" - -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "style_set «%s» sconosciuto nell'elemento <%s>" - -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "" -"Al tipo di finestra «%s» è stata già assegnata una impostazione di stile" - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "L'elemento <%s> non è consentito all'interno di <%s>" - -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" -msgstr "" -"Non è possibile specificare sia \"button_width\"/\"button_height\" che " -"\"aspect_ratio\" per i pulsanti" - -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "La distanza «%s» è sconosciuta" - -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "Le proporzioni «%s» sono sconosciute" - -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "Il bordo «%s» è sconosciuto" - -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "Nessun attributo «start_angle» o «from» nell'elemento <%s>" - -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "Nessun attributo «extent_angle» o «to» nell'elemento <%s>" - -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "Valore «%s» incomprensibile per il tipo di gradiente" - -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "Tipo di riempimento «%s» incomprensibile per l'elemento <%s>" - -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "Stato «%s» incomprensibile per l'elemento <%s>" - -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "Ombra «%s» incomprensibile per l'elemento <%s>" - -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "Freccia «%s» incomprensibile per l'elemento <%s>" - -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "Non è stato definito alcun <draw_ops> di nome «%s»" - -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "" -"Includendo draw_ops «%s» qui si potrebbe creare un riferimento circolare" - -# piece dovrebbe essere parola chiave -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Posizione «%s» sconosciuta per il piece di cornice" - -# piece dovrebbe essere parola chiave -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "Lo stile della cornice ha già una piece alla posizione %s" - -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "Non è stato definito alcun <draw_ops> con il nome «%s»" - -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Funzione «%s» sconosciuta per il pulsante" - -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "" -"La funzione di pulsante «%s» non esiste in questa versione (%d, necessaria %d)" - -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Stato «%s» sconosciuto per il pulsate" - -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "Lo stile della cornice ha già un pulsante per la funzione %s stato %s" - -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "«%s» non è un valore valido per l'attributo focus" - -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "«%s» non è un valore valido per l'attributo state" - -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "Uno stile chiamato «%s» non è stato definito" - -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "«%s» non è un valore valido per l'attributo resize" - -#: ../src/ui/theme-parser.c:3147 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" -"Non si dovrebbe avere l'attributo «resize» nell'elemento <%s> per gli stati " -"maximized/shaded" - -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "" -"Non si dovrebbe avere l'attributo «resize» nell'elemento <%s> per gli stati " -"maximized" - -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "Lo stile è stato già specificato per lo stato %s resize %s focus %s" - -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "Lo stile è stato già specificato per lo stato %s focus %s" - -#: ../src/ui/theme-parser.c:3294 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Impossibile avere due draw_ops per un elemento <piece> (il tema ha " -"specificato un attributo draw_ops e anche un elemento <draw_ops>, o ha " -"specificato due elementi)" - -#: ../src/ui/theme-parser.c:3332 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Impossibile avere due draw_ops per un elemento <button> (il tema ha " -"specificato un attributo draw_ops e anche un elemento <draw_ops>, o ha " -"specificato due elementi)" - -#: ../src/ui/theme-parser.c:3370 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Impossibile avere due draw_ops per un elemento <menu_icon> (il tema ha " -"specificato un attributo draw_ops e anche un elemento <draw_ops>, o ha " -"specificato due elementi)" - -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "Specificazione di versione «%s» errata" - -#: ../src/ui/theme-parser.c:3507 -msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" -msgstr "" -"L'attributo «version» non può essere usato in metacity-theme-1.xml o metacity-" -"theme-2.xml" - -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "" -"Il tema richiede la versione %s, ma la versione di tema supportata più " -"recente è la %d.%d" - -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "L'elemento più esterno nel tema deve essere <metacity_theme> not <%s>" - -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "" -"L'elemento <%s> non è consentito all'interno di un elemento name/author/date/" -"description" - -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "L'elemento <%s> non è consentito all'interno di un elemento <constant>" - -#: ../src/ui/theme-parser.c:3599 -#, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "" -"L'elemento <%s> non è consentito all'interno di un elemento distance/border/" -"aspect_ratio" - -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "" -"L'elemento <%s> non è consentito all'interno di un elemento relativo " -"un'operazione di disegno" - -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "L'elemento <%s> non è consentito all'interno di un elemento <%s>" - -# piece dovrebbe essere parola chiave -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "Nessun draw_ops fornito per il piece di cornice" - -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "Nessun draw_ops fornito per il pulsante" - -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "Il testo non è consentito all'interno dell'elemento <%s>" - -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "<%s> specificato due volte per questo tema" - -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Ricerca di un file valido per il tema «%s» non riuscita\n" - -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "_Finestre" - -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "_Dialogo" - -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "Dialogo _modale" - -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "_Utilità" - -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "_Schermata d'avvio" - -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "Dock superi_ore" - -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "Dock in_feriore" - -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "Dock _sinistro" - -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "Dock _destro" - -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "Tutti i doc_k" - -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "Scri_vania" - -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "Apre un'altra di queste finestre" - -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "Questo è un pulsante di prova con un'icona «Apri»" - -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "Questo è un pulsante di prova con un'icona «Esci»" - -#: ../src/ui/theme-viewer.c:253 -msgid "This is a sample message in a sample dialog" -msgstr "Questo è un messaggio d'esempio in una finestra di dialogo d'esempio" - -#: ../src/ui/theme-viewer.c:336 -#, c-format -msgid "Fake menu item %d\n" -msgstr "Voce di menu finta n.%d\n" - -#: ../src/ui/theme-viewer.c:371 -msgid "Border-only window" -msgstr "Finestra solo-bordo" - -#: ../src/ui/theme-viewer.c:373 -msgid "Bar" -msgstr "Barra" - -#: ../src/ui/theme-viewer.c:390 -msgid "Normal Application Window" -msgstr "Finestra applicazione normale" - -#: ../src/ui/theme-viewer.c:394 -msgid "Dialog Box" -msgstr "Casella di dialogo" - -#: ../src/ui/theme-viewer.c:398 -msgid "Modal Dialog Box" -msgstr "Casella di dialogo modale" - -#: ../src/ui/theme-viewer.c:402 -msgid "Utility Palette" -msgstr "Tavolozza di utilità" - -#: ../src/ui/theme-viewer.c:406 -msgid "Torn-off Menu" -msgstr "Menù staccato" - -#: ../src/ui/theme-viewer.c:410 -msgid "Border" -msgstr "Bordo" - -#: ../src/ui/theme-viewer.c:414 -msgid "Attached Modal Dialog" -msgstr "Dialogo modale attaccato" - -#: ../src/ui/theme-viewer.c:747 -#, c-format -msgid "Button layout test %d" -msgstr "Test n.%d disposizione pulsanti" - -#: ../src/ui/theme-viewer.c:776 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g millisecondi per disegnare una cornice di finestra" - -#: ../src/ui/theme-viewer.c:821 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Uso: metacity-theme-viewer [NOME_TEMA]\n" - -#: ../src/ui/theme-viewer.c:828 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "Errore nel caricare il tema: %s\n" - -#: ../src/ui/theme-viewer.c:834 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "Tema «%s» caricato in %g secondi\n" - -#: ../src/ui/theme-viewer.c:878 -msgid "Normal Title Font" -msgstr "Carattere titolo normale" - -#: ../src/ui/theme-viewer.c:884 -msgid "Small Title Font" -msgstr "Carattere titolo piccolo" - -#: ../src/ui/theme-viewer.c:890 -msgid "Large Title Font" -msgstr "Carattere titolo grande" - -#: ../src/ui/theme-viewer.c:895 -msgid "Button Layouts" -msgstr "Disposizione pulsanti" - -#: ../src/ui/theme-viewer.c:900 -msgid "Benchmark" -msgstr "Prestazioni" - -#: ../src/ui/theme-viewer.c:952 -msgid "Window Title Goes Here" -msgstr "Qui va il titolo della finestra" - -#: ../src/ui/theme-viewer.c:1055 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"Disegnate %d cornici in %g secondi lato client (%g millisecondi per cornice) " -"e %g secondi di wall clock time, incluse le risorse del server X (%g " -"millisecondi per cornice)\n" - -#: ../src/ui/theme-viewer.c:1274 -msgid "position expression test returned TRUE but set error" -msgstr "test espressione posizione ha restituito TRUE, ma impostato errore" - -#: ../src/ui/theme-viewer.c:1276 -msgid "position expression test returned FALSE but didn't set error" -msgstr "" -"test espressione posizione ha restituito FALSE, ma non ha impostato errore" - -#: ../src/ui/theme-viewer.c:1280 -msgid "Error was expected but none given" -msgstr "Errore atteso, ma non fornito" - -#: ../src/ui/theme-viewer.c:1282 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "Atteso errore %d, ma fornito %d" - -#: ../src/ui/theme-viewer.c:1288 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "Errore non atteso, ma è stato restituito: %s" - -#: ../src/ui/theme-viewer.c:1292 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "valore x era %d, era atteso %d" - -#: ../src/ui/theme-viewer.c:1295 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "valore y era %d, era atteso %d" - -#: ../src/ui/theme-viewer.c:1360 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "" -"%d espressioni di coordinate analizzate in %g secondi (%g secondi in media)\n" - -#~ msgid "" -#~ "Don't make fullscreen windows that are maximized and have no decorations" -#~ msgstr "" -#~ "Non rende a schermo intero le finestre che sono massimizzate e che non " -#~ "hanno decorazioni" - -#~ msgid "Whether window popup/frame should be shown when cycling windows." -#~ msgstr "" -#~ "Indica se mostrare il popup/cornice delle finestre quando si passa " -#~ "ciclicamente tra le stesse." - -#~ msgid "Internal argument for GObject introspection" -#~ msgstr "Argomento interno per GObject introspection" - -#~ msgid "Failed to restart: %s\n" -#~ msgstr "Riavvio non riuscito: %s\n" - -#~ msgid "Error setting clutter plugin list: %s\n" -#~ msgstr "Errore nell'impostare l'elenco dei plugin di clutter: %s\n" - -#~ msgid "Clutter Plugins" -#~ msgstr "Plugin Clutter" - -#~ msgid "Plugins to load for the Clutter-based compositing manager." -#~ msgstr "Plugin da caricare per il compositing manager basato su Clutter." - -#~ msgid "" -#~ "Lost connection to the display '%s';\n" -#~ "most likely the X server was shut down or you killed/destroyed\n" -#~ "the window manager.\n" -#~ msgstr "" -#~ "Connessione al display «%s» persa;\n" -#~ "molto probabilmente il server X è stato arrestato oppure\n" -#~ "si è terminato o distrutto il window manager.\n" - -#~ msgid "Fatal IO error %d (%s) on display '%s'.\n" -#~ msgstr "Errore fatale di IO %d (%s) relativo al display «%s».\n" - -#~ msgid "Turn compositing on" -#~ msgstr "Attiva il compositing" - -#~ msgid "Turn compositing off" -#~ msgstr "Disattiva il compositing" - -#~ msgid "Error setting compositor status: %s\n" -#~ msgstr "Errore nell'impostare lo stato del compositor: %s\n" - -#~ msgid "Failed to get hostname: %s\n" -#~ msgstr "Recupero del nome host non riuscito: %s\n" - -#~ msgid "Theme file %s did not contain a root <metacity_theme> element" -#~ msgstr "" -#~ "Il file di tema «%s» non contiene un elemento radice <metacity_theme>" - -#~ msgid "/Windows/tearoff" -#~ msgstr "/Finestre/staccatore" - -#~ msgid "/Windows/_Dialog" -#~ msgstr "/Finestre/_Dialogo" - -#~ msgid "/Windows/_Modal dialog" -#~ msgstr "/Finestre/Dialogo _modale" - -#~ msgid "/Windows/Des_ktop" -#~ msgstr "/Finestre/D_esktop" - -#~ msgid "Window Management" -#~ msgstr "Gestione finestre" - -#~ msgid "" -#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>F1\".\n" -#~ "\n" -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Il formato è tipo \"<Control>a\" o \"<Shift><Alt>F1\".\n" -#~ "\n" -#~ "Senza particolari restrizioni, è consentito l'utilizzo di lettere " -#~ "maiuscole e minuscole, così come abbreviazioni come \"<Ctl>\" o \"<Ctrl>" -#~ "\". Se l'opzione è impostata alla stringa speciale \"disabled\", allora " -#~ "non c'è alcuna associazione di tasti per questa azione." - -#~ msgid "" -#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>F1\".\n" -#~ "\n" -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action.\n" -#~ "\n" -#~ "This keybinding may be reversed by holding down the \"shift\" key; " -#~ "therefore, \"shift\" cannot be one of the keys it uses." -#~ msgstr "" -#~ "Il formato è tipo \"<Control>a\" o \"<Shift><Alt>F1\".\n" -#~ "\n" -#~ "Senza particolari restrizioni, è consentito l'utilizzo di lettere " -#~ "maiuscole e minuscole, così come abbreviazioni come \"<Ctl>\" o \"<Ctrl>" -#~ "\". Se l'opzione è impostata alla stringa speciale \"disabled\", allora " -#~ "non c'è alcuna associazione di tasti per questa azione.\n" -#~ "\n" -#~ "Questa associazioni di tasti può essere invertita tenendo premuto il " -#~ "tasto \"Maiusc\"; per questo motivo \"<Shift>\" non può essere incluso " -#~ "nei tasti da usare." - -#~ msgid "Failed to read saved session file %s: %s\n" -#~ msgstr "Lettura del file della sessione %s non riuscita: %s\n" - -#~ msgid "Metacity" -#~ msgstr "Metacity" - -#~ msgid "%s (as superuser)" -#~ msgstr "%s (come superutente)" - -#~ msgid "%s (as %s)" -#~ msgstr "%s (come %s)" - -#~ msgid "%s (as another user)" -#~ msgstr "%s (come altro utente)" - -#~ msgid "" -#~ "(Not implemented) Navigation works in terms of applications not windows" -#~ msgstr "" -#~ "(Non implementato) La navigazione funziona a livello applicazione, non a " -#~ "livello finestra" - -# GNOME-2-26 -# allungata un po' rispetto all'originale -#~ msgid "" -#~ "A font description string describing a font for window titlebars. The " -#~ "size from the description will only be used if the titlebar_font_size " -#~ "option is set to 0. Also, this option is disabled if the " -#~ "titlebar_uses_desktop_font option is set to true." -#~ msgstr "" -#~ "Una stringa di descrizione del tipo di carattere che descrive un tipo di " -#~ "carattere per la barra del titolo della finestra. La dimensione " -#~ "specificata nella descrizione è usata solo se l'opzione " -#~ "\"titlebar_font_size\" è impostata a 0. Inoltre, questa opzione è " -#~ "disabilitata se l'opzione \"titlebar_uses_desktop_font\" è impostata a " -#~ "VERO." - -#~ msgid "Action on title bar double-click" -#~ msgstr "Azione per doppio-clic su barra del titolo" - -#~ msgid "Action on title bar middle-click" -#~ msgstr "Azione per clic-centrale su barra del titolo" - -#~ msgid "Action on title bar right-click" -#~ msgstr "Azione per clic-destro su barra del titolo" - -#~ msgid "Arrangement of buttons on the titlebar" -#~ msgstr "Disposizione pulsanti su barra del titolo" - -#~ msgid "" -#~ "Arrangement of buttons on the titlebar. The value should be a string, " -#~ "such as \"menu:minimize,maximize,spacer,close\"; the colon separates the " -#~ "left corner of the window from the right corner, and the button names are " -#~ "comma-separated. Duplicate buttons are not allowed. Unknown button names " -#~ "are silently ignored so that buttons can be added in future metacity " -#~ "versions without breaking older versions. A special spacer tag can be " -#~ "used to insert some space between two adjacent buttons." -#~ msgstr "" -#~ "Disposizione dei pulsanti sulla barra del titolo. Il valore deve essere " -#~ "una stringa, tipo \"menu:minimize,maximize,spacer,close\". I due punti " -#~ "separano l'angolo sinistro della finestra dal destro, i nomi dei pulsanti " -#~ "sono separati da virgole. Non sono ammessi pulsanti duplicati. I nomi di " -#~ "pulsanti sconosciuti sono ignorati in silenzio in modo da poter " -#~ "aggiungere nuovi pulsanti nelle versioni future di metacity, senza " -#~ "precludere la compatibilità con le versioni più vecchie. Un tag speciale " -#~ "\"spacer\" può essere usato per inserire dello spazio tra due pulsanti " -#~ "adiacenti." - -#~ msgid "Automatically raises the focused window" -#~ msgstr "Solleva automaticamente la finestra col focus" - -# Mi sa che l'originale è sbagliato aperto un bug -#~ msgid "" -#~ "Clicking a window while holding down this modifier key will move the " -#~ "window (left click), resize the window (middle click), or show the window " -#~ "menu (right click). The middle and right click operations may be swapped " -#~ "using the \"resize_with_right_button\" key. Modifier is expressed as " -#~ "\"<Alt>\" or \"<Super>\" for example." -#~ msgstr "" -#~ "Facendo clic su una finestra mentre viene tenuto premuto questo tasto " -#~ "modificatore è possibile muovere la finestra (clic sinistro), " -#~ "ridimensionare la finestra (clic centrale) o visualizzare il menù " -#~ "finestra (clic destro). Le operazioni con il clic centrale e destro " -#~ "possono essere invertite usando la chiave \"resize_with_right_button\". " -#~ "Il modificatore è espresso come \"<Alt>\" o \"<Super>\"." - -#~ msgid "Commands to run in response to keybindings" -#~ msgstr "Comandi da eseguire in risposta alle associazioni di tasti" - -#~ msgid "Compositing Manager" -#~ msgstr "Manager di composizione" - -#~ msgid "Control how new windows get focus" -#~ msgstr "Controlla come le nuove finestre ottengono il focus" - -#~ msgid "Current theme" -#~ msgstr "Tema corrente" - -#~ msgid "Delay in milliseconds for the auto raise option" -#~ msgstr "Ritardo in millisecondi per l'opzione sollevamento automatico" - -#~ msgid "Determines whether Metacity is a compositing manager." -#~ msgstr "Determina se Metacity opera come un manager di composizione." - -#~ msgid "" -#~ "Determines whether applications or the system can generate audible " -#~ "'beeps'; may be used in conjunction with 'visual bell' to allow silent " -#~ "'beeps'." -#~ msgstr "" -#~ "Determina se le applicazioni o il sistema possono generare dei bip " -#~ "udibili; può essere usato in congiunzione con \"visual_bell\" per " -#~ "consentire dei bip silenziosi." - -# inadeguate: see http://catb.org/jargon/html/M/misfeature.html -#~ msgid "Disable misfeatures that are required by old or broken applications" -#~ msgstr "" -#~ "Disabilita le funzioni inadeguate richieste da applicazioni vecchie o non " -#~ "funzionanti" - -#~ msgid "Enable Visual Bell" -#~ msgstr "Abilita campanella visiva" - -# enter messo in modo un po' libero -#~ msgid "" -#~ "If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " -#~ "the focused window will be automatically raised after a delay specified " -#~ "by the auto_raise_delay key. This is not related to clicking on a window " -#~ "to raise it, nor to entering a window during drag-and-drop." -#~ msgstr "" -#~ "Se impostata a VERO e la modalità di focus è \"sloppy\" o \"mouse\", " -#~ "allora la finestra con il focus è sollevata automaticamente dopo un " -#~ "ritardo specificato nella chiave \"auto_raise_delay\". Ciò non ha " -#~ "relazioni con il fare clic su una finestra per sollevarla, né con il " -#~ "passare sopra una finestra durante un'operazione di trascinamento." - -#~ msgid "" -#~ "If true, ignore the titlebar_font option, and use the standard " -#~ "application font for window titles." -#~ msgstr "" -#~ "Se impostata a VERO, l'opzione \"titlebar_font\" è ignorata e per i " -#~ "titoli delle finestre viene usato il tipo di carattere predefinito per le " -#~ "applicazioni." - -#~ msgid "" -#~ "If true, metacity will give the user less feedback by using wireframes, " -#~ "avoiding animations, or other means. This is a significant reduction in " -#~ "usability for many users, but may allow legacy applications to continue " -#~ "working, and may also be a useful tradeoff for terminal servers. However, " -#~ "the wireframe feature is disabled when accessibility is on." -#~ msgstr "" -#~ "Se impostata a VERO, metacity fornisce all'utente un minore riscontro " -#~ "usando wireframe, evitando le animazioni e altro. Questo comporta una " -#~ "significativa riduzione in termini di facilità d'uso per molti utenti, ma " -#~ "potrebbe consentire ad applicazioni legacy di continuare a funzionare, " -#~ "così come potrebbe essere un buon compromesso per i terminal server. " -#~ "Comunque, la funzionalità wireframe è disabilitata quando l'accessibilità " -#~ "è in funzione." - -#~ msgid "" -#~ "If true, then Metacity works in terms of applications rather than " -#~ "windows. The concept is a bit abstract, but in general an application-" -#~ "based setup is more like the Mac and less like Windows. When you focus a " -#~ "window in application-based mode, all the windows in the application will " -#~ "be raised. Also, in application-based mode, focus clicks are not passed " -#~ "through to windows in other applications. Application-based mode is, " -#~ "however, largely unimplemented at the moment." -#~ msgstr "" -#~ "Se impostata a VERO, Metacity funziona in termini di applicazioni invece " -#~ "che di finestre. Il concetto è un po' astratto, ma in generale una " -#~ "configurazione basata sulle applicazioni è più simile al Mac che a " -#~ "Windows. Quando si da il focus a una finestra nella modalità basata sulle " -#~ "applicazioni, tutte le finestre dell'applicazione vengono sollevate. " -#~ "Inoltre in questa modalità i clic per l'assegnazione del focus non " -#~ "vengono passati attraverso le finestre verso altre applicazioni. Al " -#~ "momento però, la modalità in base alle applicazioni è ampliamente non " -#~ "implementata." - -#~ msgid "If true, trade off usability for less resource usage" -#~ msgstr "Se impostata a VERO, riduce l'usabilità per un minor uso di risorse" - -#~ msgid "Name of workspace" -#~ msgstr "Nome dello spazio di lavoro" - -#~ msgid "Number of workspaces" -#~ msgstr "Numero di spazi di lavoro" - -#~ msgid "" -#~ "Number of workspaces. Must be more than zero, and has a fixed maximum to " -#~ "prevent making the desktop unusable by accidentally asking for too many " -#~ "workspaces." -#~ msgstr "" -#~ "Numero degli spazi di lavoro. Deve essere maggiore di zero e presenta un " -#~ "limite massimo prefissato per evitare di rendere l'ambiente grafico " -#~ "inutilizzabile qualora si richiedano accidentalmente troppi spazi di " -#~ "lavoro." - -#~ msgid "Run a defined command" -#~ msgstr "Esegui un comando stabilito" - -#~ msgid "" -#~ "Set this to true to resize with the right button and show a menu with the " -#~ "middle button while holding down the key given in \"mouse_button_modifier" -#~ "\"; set it to false to make it work the opposite way around." -#~ msgstr "" -#~ "Impostare questa opzione a VERO per ridimensionare con il pulsante destro " -#~ "e mostrare un menù con il pulsante centrale mentre si tiene premuto il " -#~ "tasto indicato in \"mouse_button_modifier\": impostare a FALSO per farli " -#~ "funzionare nel modo opposto." - -#~ msgid "" -#~ "Setting this option to false can lead to buggy behavior, so users are " -#~ "strongly discouraged from changing it from the default of true. Many " -#~ "actions (e.g. clicking in the client area, moving or resizing the window) " -#~ "normally raise the window as a side-effect. Setting this option to false, " -#~ "which is strongly discouraged, will decouple raising from other user " -#~ "actions, and ignore raise requests generated by applications. See http://" -#~ "bugzilla.gnome.org/show_bug.cgi?id=445447#c6. Even when this option is " -#~ "false, windows can still be raised by an alt-left-click anywhere on the " -#~ "window, a normal click on the window decorations, or by special messages " -#~ "from pagers, such as activation requests from tasklist applets. This " -#~ "option is currently disabled in click-to-focus mode. Note that the list " -#~ "of ways to raise windows when raise_on_click is false does not include " -#~ "programmatic requests from applications to raise windows; such requests " -#~ "will be ignored regardless of the reason for the request. If you are an " -#~ "application developer and have a user complaining that your application " -#~ "does not work with this setting disabled, tell them it is _their_ fault " -#~ "for breaking their window manager and that they need to change this " -#~ "option back to true or live with the \"bug\" they requested." -#~ msgstr "" -#~ "Impostando questa opzione a FALSO può condurre a comportamenti " -#~ "inadeguati, perciò è fortemente sconsigliato cambiare il valore VERO " -#~ "predefinito. Molte azioni (per esempio fare clic nell'area client, " -#~ "muovere o ridimensionare la finestra) hanno come effetto collaterale " -#~ "quello di sollevale la finestra. Impostando questa opzione a FALSO, cosa " -#~ "fortemente sconsigliata, verrà disaccoppiato il sollevamento dalle altre " -#~ "azioni utente e verranno ignorate le richieste di sollevamento generate " -#~ "delle applicazioni. Consultare http://bugzilla.gnome.org/show_bug.cgi?" -#~ "id=445447#c6. Anche quando questa opzione è FALSO, le finestre possono " -#~ "ancora essere sollevate da un clic+Alt_sinistro in un punto qualsiasi " -#~ "della finestra, da un clic normale sulle decorazioni delle finestre, o da " -#~ "speciali messaggi dai pager, come una richiesta di attivazione " -#~ "dall'applet Elenco finestre. Questa opzione è attualmente disabilitata " -#~ "nella modalità clic-per-focus. Notare che l'elenco di modalità di " -#~ "sollevamento delle finestre quando la chiave \"raise_on_click\" è FALSO " -#~ "non include le richieste programmatiche da parte delle applicazioni. Se " -#~ "siete gli sviluppatori di un'applicazione e qualche utente si lamenta che " -#~ "la vostra applicazione non funziona con questa impostazione disabilitata, " -#~ "fate loro notare che è un _loro_ difetto causato dall'aver rovinato il " -#~ "loro window manager e che dovrebbero riportare il valore di questa " -#~ "opzione a VERO oppure convivere con il \"bug\" che hanno richiesto." - -#~ msgid "" -#~ "Some applications disregard specifications in ways that result in window " -#~ "manager misfeatures. This option puts Metacity in a rigorously correct " -#~ "mode, which gives a more consistent user interface, provided one does not " -#~ "need to run any misbehaving applications." -#~ msgstr "" -#~ "Alcune applicazioni non rispettano le specifiche a tal punto da avere " -#~ "come risultato funzionalità inadeguate nel window manager. Questa opzione " -#~ "pone Metacity in una modalità rigorosamente corretta, che fornisce una " -#~ "interfaccia utente più coerente, a meno che non si debba eseguire una " -#~ "qualche applicazione mal funzionante." - -#~ msgid "System Bell is Audible" -#~ msgstr "Campanella di sistema udibile" - -#~ msgid "" -#~ "Tells Metacity how to implement the visual indication that the system " -#~ "bell or another application 'bell' indicator has been rung. Currently " -#~ "there are two valid values, \"fullscreen\", which causes a fullscreen " -#~ "white-black flash, and \"frame_flash\" which causes the titlebar of the " -#~ "application which sent the bell signal to flash. If the application which " -#~ "sent the bell is unknown (as is usually the case for the default \"system " -#~ "beep\"), the currently focused window's titlebar is flashed." -#~ msgstr "" -#~ "Indica a Metacity come implementare l'indicazione visiva che la " -#~ "campanella di sistema o un altro indicatore \"campanella\" di " -#~ "applicazione sta suonando. Al momento sono ammessi due valori: " -#~ "\"fullscreen\", che causa un lampeggio bianco-nero a schermo intero, e " -#~ "\"frame_flash\", che causa il lampeggio della barra del titolo " -#~ "dell'applicazione che ha inviato il segnale della campanella. Se " -#~ "l'applicazione che ha inviato la campanella è sconosciuta (come accade di " -#~ "solito nel caso della campanella di sistema), il lampeggio avviene sulla " -#~ "finestra che al momento ha il focus." - -#~ msgid "" -#~ "The /apps/metacity/global_keybindings/run_command_N keys define " -#~ "keybindings that correspond to these commands. Pressing the keybinding " -#~ "for run_command_N will execute command_N." -#~ msgstr "" -#~ "Le chiavi /apps/metacity/global_keybindings/run_command_N definiscono le " -#~ "associazioni di tasti che corrispondono a questi comandi. Premendo " -#~ "l'associazione di tasti per la chiave \"run_command_N\", viene eseguito " -#~ "il comando della chiave \"command_N\"." - -#~ msgid "" -#~ "The /apps/metacity/global_keybindings/run_command_screenshot key defines " -#~ "a keybinding which causes the command specified by this setting to be " -#~ "invoked." -#~ msgstr "" -#~ "La chiave /apps/metacity/global_keybindings/run_command_screenshot " -#~ "definisce una associazione di tasti che causa l'invocazione del comando " -#~ "specificato da questa impostazione." - -#~ msgid "" -#~ "The /apps/metacity/global_keybindings/run_command_window_screenshot key " -#~ "defines a keybinding which causes the command specified by this setting " -#~ "to be invoked." -#~ msgstr "" -#~ "La chiave /apps/metacity/global_keybindings/run_command_window_screenshot " -#~ "definisce una associazione di tasti che causa l'invocazione del comando " -#~ "specificato da questa impostazione." - -#~ msgid "" -#~ "The keybinding that runs the correspondingly-numbered command in /apps/" -#~ "metacity/keybinding_commands The format looks like \"<Control>a\" " -#~ "or \"<Shift><Alt>F1\". The parser is fairly liberal and " -#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" -#~ "\" and \"<Ctrl>\". If you set the option to the special string " -#~ "\"disabled\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "L'associazione di tasti che esegue il comando con numero corrispondente " -#~ "in /apps/metacity/keybinding_commands. Il formato è \"<Control$gt;a\" " -#~ "oppure \"<Shift><Alt>F1\". È consentito l'utilizzo di lettere " -#~ "maiuscole, minuscole e anche di abbreviazioni tipo \"<Ctl>\" o " -#~ "\"<Ctrl>\". Se l'opzione è impostata alla stringa speciale " -#~ "\"disabled\", allora non c'è alcuna associazione di tasti per questa " -#~ "azione." - -#~ msgid "The name of a workspace." -#~ msgstr "Il nome di uno spazio di lavoro." - -#~ msgid "The screenshot command" -#~ msgstr "Il comando per schermate" - -#~ msgid "" -#~ "The theme determines the appearance of window borders, titlebar, and so " -#~ "forth." -#~ msgstr "" -#~ "Il tema determina l'aspetto dei bordi delle finestre, della barra del " -#~ "titolo e così via." - -#~ msgid "" -#~ "The time delay before raising a window if auto_raise is set to true. The " -#~ "delay is given in thousandths of a second." -#~ msgstr "" -#~ "L'intervallo di tempo in millisecondi prima che la finestra venga " -#~ "sollevata quando auto_raise è impostato a VERO." - -#~ msgid "" -#~ "The window focus mode indicates how windows are activated. It has three " -#~ "possible values; \"click\" means windows must be clicked in order to " -#~ "focus them, \"sloppy\" means windows are focused when the mouse enters " -#~ "the window, and \"mouse\" means windows are focused when the mouse enters " -#~ "the window and unfocused when the mouse leaves the window." -#~ msgstr "" -#~ "La modalità di focus delle finestre indica come vengono attivate le " -#~ "finestre. I possibili valori sono tre: \"click\" indica che è necessario " -#~ "fare clic sulle finestre al fine di dare loro il focus, \"sloppy\" indica " -#~ "che le finestre ottengono il focus quando il puntatore entra nella loro " -#~ "area, \"mouse\" indica che le finestre ottengono il focus quando il " -#~ "puntatore entra nella loro area e lo perdono quando abbandona tale area." - -#~ msgid "The window screenshot command" -#~ msgstr "Il comando per schermate di finestre" - -#~ msgid "" -#~ "This option determines the effects of double-clicking on the title bar. " -#~ "Current valid options are 'toggle_shade', which will shade/unshade the " -#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " -#~ "will maximize/unmaximize the window in that direction only, 'minimize' " -#~ "which will minimize the window, 'shade' which will roll the window up, " -#~ "'menu' which will display the window menu, 'lower' which will put the " -#~ "window behind all the others, and 'none' which will not do anything." -#~ msgstr "" -#~ "Questa opzione determina gli effetti del doppio-clic sulla barra del " -#~ "titolo. Le opzioni attualmente valide sono \"toggle_shade\" per " -#~ "arrotolare/srotolare la finestra, \"toggle_maximize\" per massimizzare/" -#~ "demassimizzare la finestra, \"toggle_maximize_horizontally\" e " -#~ "\"toggle_maximize_vertically\" per massimizzare/demassimizzare la " -#~ "finestra solo in una prefissata direzione, \"minimize\" per minimizzare " -#~ "la finestra, \"shade\" per arrotolare la finestra, \"menu\" per mostrare " -#~ "il menù finestra, \"lower\" per collocare la finestra sotto tutte le " -#~ "altre e \"none\" per non compiere alcuna azione." - -#~ msgid "" -#~ "This option determines the effects of middle-clicking on the title bar. " -#~ "Current valid options are 'toggle_shade', which will shade/unshade the " -#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " -#~ "will maximize/unmaximize the window in that direction only, 'minimize' " -#~ "which will minimize the window, 'shade' which will roll the window up, " -#~ "'menu' which will display the window menu, 'lower' which will put the " -#~ "window behind all the others, and 'none' which will not do anything." -#~ msgstr "" -#~ "Questa opzione determina gli effetti del clic-centrale sulla barra del " -#~ "titolo. Le opzioni attualmente valide sono \"toggle_shade\" per " -#~ "arrotolare/srotolare la finestra, \"toggle_maximize\" per massimizzare/" -#~ "demassimizzare la finestra, \"toggle_maximize_horizontally\" e " -#~ "\"toggle_maximize_vertically\" per massimizzare/demassimizzare la " -#~ "finestra solo in una prefissata direzione, \"minimize\" per minimizzare " -#~ "la finestra, \"shade\" per arrotolare la finestra, \"menu\" per mostrare " -#~ "il menù finestra, \"lower\" per collocare la finestra sotto tutte le " -#~ "altre e \"none\" per non compiere alcuna azione." - -#~ msgid "" -#~ "This option determines the effects of right-clicking on the title bar. " -#~ "Current valid options are 'toggle_shade', which will shade/unshade the " -#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " -#~ "will maximize/unmaximize the window in that direction only, 'minimize' " -#~ "which will minimize the window, 'shade' which will roll the window up, " -#~ "'menu' which will display the window menu, 'lower' which will put the " -#~ "window behind all the others, and 'none' which will not do anything." -#~ msgstr "" -#~ "Questa opzione determina gli effetti del clic-destro sulla barra del " -#~ "titolo. Le opzioni attualmente valide sono \"toggle_shade\" per " -#~ "arrotolare/srotolare la finestra, \"toggle_maximize\" per massimizzare/" -#~ "demassimizzare la finestra, \"toggle_maximize_horizontally\" e " -#~ "\"toggle_maximize_vertically\" per massimizzare/demassimizzare la " -#~ "finestra solo in una prefissata direzione, \"minimize\" per minimizzare " -#~ "la finestra, \"shade\" per arrotolare la finestra, \"menu\" per mostrare " -#~ "il menù finestra, \"lower\" per collocare la finestra sotto tutte le " -#~ "altre e \"none\" per non compiere alcuna azione." - -#~ msgid "" -#~ "This option provides additional control over how newly created windows " -#~ "get focus. It has two possible values; \"smart\" applies the user's " -#~ "normal focus mode, and \"strict\" results in windows started from a " -#~ "terminal not being given focus." -#~ msgstr "" -#~ "Questa opzione fornisce un controllo aggiuntivo sul modo in cui le " -#~ "finestre appena create ottengono il focus. Sono ammessi due valori: " -#~ "\"smart\" per applicare la normale modalità di focus dell'utente e " -#~ "\"strict\" per non dare il focus a finestre avviate da un terminale." - -#~ msgid "" -#~ "Turns on a visual indication when an application or the system issues a " -#~ "'bell' or 'beep'; useful for the hard-of-hearing and for use in noisy " -#~ "environments." -#~ msgstr "" -#~ "Attiva un'indicazione visiva quando un'applicazione o il sistema emette " -#~ "un \"bip\" o \"suona una campanella\"; utile per chi ha problemi d'udito " -#~ "o per l'uso in ambienti rumorosi." - -#~ msgid "Use standard system font in window titles" -#~ msgstr "Usare il carattere di sistema nei titoli delle finestre" - -#~ msgid "Visual Bell Type" -#~ msgstr "Tipo campanella visiva" - -#~ msgid "Whether raising should be a side-effect of other user interactions" -#~ msgstr "" -#~ "Indica se sollevare la finestra è un effetto secondario di altre " -#~ "interazioni utente" - -#~ msgid "Whether to resize with the right button" -#~ msgstr "Indica se ridimensionare con il pulsante destro" - -#~ msgid "Window focus mode" -#~ msgstr "Modalità di focus delle finestre" - -#~ msgid "Window title font" -#~ msgstr "Carattere per il titolo della finestra" diff --git a/po/ja.po b/po/ja.po index a4238cdad..fab3a8a0e 100644 --- a/po/ja.po +++ b/po/ja.po @@ -1,1981 +1,1818 @@ -# muffin ja.po. -# Copyright (C) 2002-2011 Free Software Foundation, Inc. +# mutter ja.po. +# Copyright (C) 2002-2020 Free Software Foundation, Inc. # Akira TAGOH <tagoh@gnome.gr.jp>, 2002. # KAMAGASAKO Masatoshi <emerald@gnome.gr.jp>, 2003. -# Takeshi AIHANA <takeshi.aihana@gmail.com>, 2003-2011. # Yukihiro Nakai <nakai@gnome.gr.jp>, 2003. +# Takeshi AIHANA <takeshi.aihana@gmail.com>, 2003-2011. # Satoru SATOH <ss@gnome.gr.jp>, 2006. +# Noriko Mizumoto <noriko@fedoraproject.org>, 2012. +# Jiro Matsuzawa <jmatsuzawa@gnome.org>, 2012, 2013. +# sujiniku <sujinikusityuu@gmail.com>, 2016. +# sicklylife <translation@sicklylife.jp>, 2019-2020. +# Masanori Kamayama <>, 2020. # msgid "" msgstr "" -"Project-Id-Version: muffin master\n" -"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" -"product=muffin&keywords=I18N+L10N&component=general\n" -"POT-Creation-Date: 2011-09-25 11:31+0000\n" -"PO-Revision-Date: 2011-09-25 23:38+0900\n" -"Last-Translator: OKANO Takayoshi <kano@na.rim.or.jp>\n" +"Project-Id-Version: mutter master\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2020-02-23 17:41+0000\n" +"PO-Revision-Date: 2020-03-01 00:25+0900\n" +"Last-Translator: sicklylife <translation@sicklylife.jp>\n" "Language-Team: Japanese <gnome-translation@gnome.gr.jp>\n" +"Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Language: ja\n" +"Plural-Forms: nplurals=1; plural=0;\n" -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format -msgid "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." -msgstr "" -"既に別の合成マネージャーがディスプレイ \"%2$s\" 上のスクリーン %1$i で起動中" -"です" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "ナビゲーション" -# 「キーボード・ショートカット」のアプレット (gnome-control-center) で表示するメッセージ -#: ../src/core/all-keybindings.h:88 -msgid "Switch to workspace 1" -msgstr "ワークスペース 1 へ切り替える" +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "ウィンドウをワークスペース 1 へ移動する" -#: ../src/core/all-keybindings.h:90 -msgid "Switch to workspace 2" -msgstr "ワークスペース 2 へ切り替える" +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "ウィンドウをワークスペース 2 へ移動する" -#: ../src/core/all-keybindings.h:92 -msgid "Switch to workspace 3" -msgstr "ワークスペース 3 へ切り替える" +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "ウィンドウをワークスペース 3 へ移動する" -#: ../src/core/all-keybindings.h:94 -msgid "Switch to workspace 4" -msgstr "ワークスペース 4 へ切り替える" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "ウィンドウをワークスペース 4 へ移動する" + +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "ウィンドウを最後のワークスペースへ移動する" + +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "ウィンドウを上側のワークスペースへ移動する" -#: ../src/core/all-keybindings.h:96 -msgid "Switch to workspace 5" -msgstr "ワークスペース 5 へ切り替える" +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "ウィンドウを下側のワークスペースへ移動する" -#: ../src/core/all-keybindings.h:98 -msgid "Switch to workspace 6" -msgstr "ワークスペース 6 へ切り替える" +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "ウィンドウを左側のモニターへ移動する" -#: ../src/core/all-keybindings.h:100 -msgid "Switch to workspace 7" -msgstr "ワークスペース 7 へ切り替える" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "ウィンドウを右側のモニターへ移動する" -#: ../src/core/all-keybindings.h:102 -msgid "Switch to workspace 8" -msgstr "ワークスペース 8 へ切り替える" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "ウィンドウを上側のモニターへ移動する" -#: ../src/core/all-keybindings.h:104 -msgid "Switch to workspace 9" -msgstr "ワークスペース 9 へ切り替える" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "ウィンドウを下側のモニターへ移動する" -#: ../src/core/all-keybindings.h:106 -msgid "Switch to workspace 10" -msgstr "ワークスペース 10 へ切り替える" +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "アプリケーションを切り替える" -#: ../src/core/all-keybindings.h:108 -msgid "Switch to workspace 11" -msgstr "ワークスペース 11 へ切り替える" +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "前のアプリケーションに切り替える" -#: ../src/core/all-keybindings.h:110 -msgid "Switch to workspace 12" -msgstr "ワークスペース 12 へ切り替える" +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "ウィンドウを切り替える" -#: ../src/core/all-keybindings.h:122 -msgid "Switch to workspace on the left of the current workspace" -msgstr "左側のワークスペースへ切り替える" +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "前のウィンドウに切り替える" -#: ../src/core/all-keybindings.h:126 -msgid "Switch to workspace on the right of the current workspace" -msgstr "右側のワークスペースへ切り替える" +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "一つのアプリケーション内のウィンドウを切り替える" -#: ../src/core/all-keybindings.h:130 -msgid "Switch to workspace above the current workspace" -msgstr "上側のワークスペースへ切り替える" +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "一つのアプリケーション内の前のウィンドウに切り替える" -#: ../src/core/all-keybindings.h:134 -msgid "Switch to workspace below the current workspace" -msgstr "下側のワークスペースへ切り替える" +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "システムコントロールを切り替える" -#: ../src/core/all-keybindings.h:150 -msgid "Move between windows of an application, using a popup window" -msgstr "ポップアップ・ウィンドウを使って複数のウィンドウの間を移動する" +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "前のシステムコントロールに切り替える" -#: ../src/core/all-keybindings.h:153 -msgid "Move backward between windows of an application, using a popup window" -msgstr "ポップアップ・ウィンドウを使って複数のウィンドウの間を降順で移動する" +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "ウィンドウを直接切り替える" -#: ../src/core/all-keybindings.h:157 -msgid "Move between windows, using a popup window" -msgstr "ポップアップ・ウィンドウを使ってウィンドウ間のフォーカスを切り替える" +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "前のウィンドウに直接切り替える" -#: ../src/core/all-keybindings.h:160 -msgid "Move backward between windows, using a popup window" -msgstr "" -"ポップアップ・ウィンドウを使ってウィンドウ間のフォーカスを降順で切り替える" +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "一つのアプリケーション内のウィンドウを直接切り替える" -#: ../src/core/all-keybindings.h:163 -msgid "Move between panels and the desktop, using a popup window" -msgstr "" -"ポップアップ・ウィンドウを使ってパネルとデスクトップの間のフォーカスを切り替" -"える" +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "一つのアプリケーション内の前のウィンドウに直接切り替える" -#: ../src/core/all-keybindings.h:166 -msgid "Move backward between panels and the desktop, using a popup window" -msgstr "" -"ポップアップ・ウィンドウを使ってパネルとデスクトップの間のフォーカスを降順で" -"切り替える" +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "システムコントロールを直接切り替える" -#: ../src/core/all-keybindings.h:171 -msgid "Move between windows of an application immediately" -msgstr "アプリケーションが持つ複数のウィンドウの間を移動する" +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "前のシステムコントロールに直接切り替える" -#: ../src/core/all-keybindings.h:174 -msgid "Move backward between windows of an application immediately" -msgstr "アプリケーションが持つ複数のウィンドウを降順で移動する" +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "すべての通常のウィンドウを隠す" + +# 「キーボードショートカット」のアプレット (gnome-control-center) で表示するメッセージ +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "ワークスペース 1 へ切り替える" -#: ../src/core/all-keybindings.h:177 -msgid "Move between windows immediately" -msgstr "ウィンドウ間のフォーカスを切り替える" +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "ワークスペース 2 へ切り替える" -#: ../src/core/all-keybindings.h:180 -msgid "Move backward between windows immediately" -msgstr "ウィンドウ間のフォーカスを降順で切り替える" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "ワークスペース 3 へ切り替える" -#: ../src/core/all-keybindings.h:183 -msgid "Move between panels and the desktop immediately" -msgstr "パネルとデスクトップとのフォーカスを切り替える" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "ワークスペース 4 へ切り替える" -#: ../src/core/all-keybindings.h:186 -msgid "Move backward between panels and the desktop immediately" -msgstr "後方のパネルとデスクトップとの間を切り替える" +# 「キーボードショートカット」のアプレット (gnome-control-center) で表示するメッセージ +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "最後のワークスペースへ切り替える" -#: ../src/core/all-keybindings.h:203 -msgid "Hide all normal windows and set focus to the desktop" -msgstr "全てのウィンドウを隠してデスクトップにフォーカスを移す" +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "上側のワークスペースへ移動する" -#: ../src/core/all-keybindings.h:206 -msgid "Show the panel's main menu" -msgstr "パネルにあるメイン・メニューを開く" +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "下側のワークスペースへ移動する" -#: ../src/core/all-keybindings.h:209 -msgid "Show the panel's \"Run Application\" dialog box" -msgstr "アプリケーションの実行ダイアログを開く" +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "システム" -#: ../src/core/all-keybindings.h:211 -msgid "Start or stop recording the session" -msgstr "セッションの録画を開始/停止する" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "コマンド実行プロンプトを表示する" -#: ../src/core/all-keybindings.h:252 -msgid "Take a screenshot" -msgstr "スクリーンショットを撮る" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "アクティビティ画面を表示する" -#: ../src/core/all-keybindings.h:254 -msgid "Take a screenshot of a window" -msgstr "ウィンドウのスクリーンショットを撮る" +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "キーボードショートカットを復元する" -#: ../src/core/all-keybindings.h:256 -msgid "Run a terminal" -msgstr "端末を起動する" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "ウィンドウ" -#: ../src/core/all-keybindings.h:271 +#: data/50-mutter-windows.xml:8 msgid "Activate the window menu" -msgstr "ウィンドウ・メニューを開く" +msgstr "ウィンドウメニューを開く" -#: ../src/core/all-keybindings.h:274 +#: data/50-mutter-windows.xml:10 msgid "Toggle fullscreen mode" -msgstr "フル・スクリーン表示を切り替える" +msgstr "フルスクリーンモードを切り替える" -#: ../src/core/all-keybindings.h:276 +#: data/50-mutter-windows.xml:12 msgid "Toggle maximization state" msgstr "最大化/最小化の状態を切り替える" -#: ../src/core/all-keybindings.h:278 -msgid "Toggle whether a window will always be visible over other windows" -msgstr "ウィンドウを常に前面に表示するかどうかの設定を切り替える" - -#: ../src/core/all-keybindings.h:280 +#: data/50-mutter-windows.xml:14 msgid "Maximize window" msgstr "ウィンドウを最大化する" -#: ../src/core/all-keybindings.h:282 +#: data/50-mutter-windows.xml:16 msgid "Restore window" -msgstr "ウィンドウの状態を元に戻す" - -#: ../src/core/all-keybindings.h:284 -msgid "Toggle shaded state" -msgstr "シェードの状態を切り替える" +msgstr "ウィンドウを戻す" -#: ../src/core/all-keybindings.h:286 -msgid "Minimize window" -msgstr "ウィンドウを最小化する" - -#: ../src/core/all-keybindings.h:288 +#: data/50-mutter-windows.xml:18 msgid "Close window" msgstr "ウィンドウを閉じる" -#: ../src/core/all-keybindings.h:290 +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "ウィンドウを非表示にする" + +#: data/50-mutter-windows.xml:22 msgid "Move window" msgstr "ウィンドウを移動する" -#: ../src/core/all-keybindings.h:292 +#: data/50-mutter-windows.xml:24 msgid "Resize window" -msgstr "ウィンドウ・サイズを変更する" +msgstr "ウィンドウサイズを変更する" -#: ../src/core/all-keybindings.h:295 -msgid "Toggle whether window is on all workspaces or just one" -msgstr "ウィンドウを全てのワークスペースに配置するか切り替える" +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "ウィンドウをすべてのワークスペースに固定するかどうかを切り替える" -#: ../src/core/all-keybindings.h:299 -msgid "Move window to workspace 1" -msgstr "ウィンドウをワークスペース 1 へ移動する" +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "ウィンドウが覆われていれば最前面に、そうでなければ最背面に移動する" -#: ../src/core/all-keybindings.h:302 -msgid "Move window to workspace 2" -msgstr "ウィンドウをワークスペース 2 へ移動する" +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "ウィンドウを最前面に移動する" -#: ../src/core/all-keybindings.h:305 -msgid "Move window to workspace 3" -msgstr "ウィンドウをワークスペース 3 へ移動する" +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "ウィンドウを最背面に移動する" -#: ../src/core/all-keybindings.h:308 -msgid "Move window to workspace 4" -msgstr "ウィンドウをワークスペース 4 へ移動する" +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "ウィンドウを垂直方向に最大化する" + +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "ウィンドウを水平方向に最大化する" + +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "画面左半分に表示する" + +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "画面右半分に表示する" + +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" + +#: data/org.gnome.mutter.gschema.xml.in:7 +msgid "Modifier to use for extended window management operations" +msgstr "ウィンドウの拡張管理の操作で使用する修飾キー" + +#: data/org.gnome.mutter.gschema.xml.in:8 +msgid "" +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." +msgstr "" +"ここに指定したキーで「オーバーレイの機能」を起動します。この機能は GNOME " +"Shell などが提供するウィンドウの全体表示やアプリの起動システムと連携します。" +"デフォルトのキーは PC のキーボードにある [Windows キー] です。指定可能な値: " +"デフォルトのキー、または空の文字列" -#: ../src/core/all-keybindings.h:311 -msgid "Move window to workspace 5" -msgstr "ウィンドウをワークスペース 5 へ移動する" +#: data/org.gnome.mutter.gschema.xml.in:20 +msgid "Attach modal dialogs" +msgstr "モーダルなダイアログを統合するかどうか" + +#: data/org.gnome.mutter.gschema.xml.in:21 +msgid "" +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." +msgstr "" +"TRUE にすると、タイトルバーを持つ通常のモーダルなダイアログを表示する代わり" +"に、親ウィンドウのタイトルバーに統合したダイアログを表示します (親ウィンドウ" +"を移動すると一緒にモーダルなダイアログも移動します)。" -#: ../src/core/all-keybindings.h:314 -msgid "Move window to workspace 6" -msgstr "ウィンドウをワークスペース 6 へ移動する" +#: data/org.gnome.mutter.gschema.xml.in:30 +msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "" -#: ../src/core/all-keybindings.h:317 -msgid "Move window to workspace 7" -msgstr "ウィンドウをワークスペース 7 へ移動する" +#: data/org.gnome.mutter.gschema.xml.in:31 +msgid "" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." +msgstr "" -#: ../src/core/all-keybindings.h:320 -msgid "Move window to workspace 8" -msgstr "ウィンドウをワークスペース 8 へ移動する" +#: data/org.gnome.mutter.gschema.xml.in:40 +msgid "Workspaces are managed dynamically" +msgstr "" -#: ../src/core/all-keybindings.h:323 -msgid "Move window to workspace 9" -msgstr "ウィンドウをワークスペース 9 へ移動する" +#: data/org.gnome.mutter.gschema.xml.in:41 +msgid "" +"Determines whether workspaces are managed dynamically or whether there’s a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." +msgstr "" -#: ../src/core/all-keybindings.h:326 -msgid "Move window to workspace 10" -msgstr "ウィンドウをワークスペース 10 へ移動する" +#: data/org.gnome.mutter.gschema.xml.in:50 +msgid "Workspaces only on primary" +msgstr "プライマリモニターのみワークスペースを切り替えるかどうか" -#: ../src/core/all-keybindings.h:329 -msgid "Move window to workspace 11" -msgstr "ウィンドウをワークスペース 11 へ移動する" +#: data/org.gnome.mutter.gschema.xml.in:51 +msgid "" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." +msgstr "" +"すべてのモニターにあるウィンドウに対してワークスペースの切り替えを可能にする" +"か、またはプライマリモニターにあるウィンドウに対してのみワークスペースの切り" +"替えを提供するかどうかです。" -#: ../src/core/all-keybindings.h:332 -msgid "Move window to workspace 12" -msgstr "ウィンドウをワークスペース 12 へ移動する" +#: data/org.gnome.mutter.gschema.xml.in:59 +msgid "No tab popup" +msgstr "" -#: ../src/core/all-keybindings.h:344 -msgid "Move window one workspace to the left" -msgstr "ウィンドウを左側のワークスペースへ移動する" +#: data/org.gnome.mutter.gschema.xml.in:60 +msgid "" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." +msgstr "" -#: ../src/core/all-keybindings.h:347 -msgid "Move window one workspace to the right" -msgstr "ウィンドウを右側のワークスペースへ移動する" +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "" -#: ../src/core/all-keybindings.h:350 -msgid "Move window one workspace up" -msgstr "ウィンドウを上側のワークスペースへ移動する" +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" -#: ../src/core/all-keybindings.h:353 -msgid "Move window one workspace down" -msgstr "ウィンドウを下側のワークスペースへ移動する" +#: data/org.gnome.mutter.gschema.xml.in:79 +msgid "Draggable border width" +msgstr "ドラッグが可能になる境界線の幅" -#: ../src/core/all-keybindings.h:356 -msgid "Raise window if it's covered by another window, otherwise lower it" -msgstr "隠れているウィンドウを前面に表示する" +#: data/org.gnome.mutter.gschema.xml.in:80 +msgid "" +"The amount of total draggable borders. If the theme’s visible borders are " +"not enough, invisible borders will be added to meet this value." +msgstr "" +"ドラッグができるようになる境界線の幅です。テーマで表示している境界線がこの値" +"よりも小さい場合は、表示できない境界線がこの値になるように追加されます。" -#: ../src/core/all-keybindings.h:358 -msgid "Raise window above other windows" -msgstr "ウィンドウを前面に表示する" +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "" -#: ../src/core/all-keybindings.h:360 -msgid "Lower window below other windows" -msgstr "ウィンドウを一番奥に移動する" +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" -#: ../src/core/all-keybindings.h:364 -msgid "Maximize window vertically" -msgstr "ウィンドウを垂直方向に最大化する" +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "" -#: ../src/core/all-keybindings.h:368 -msgid "Maximize window horizontally" -msgstr "ウィンドウを水平方向に最大化する" +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" -#: ../src/core/all-keybindings.h:372 -msgid "Move window to north-west (top left) corner" -msgstr "ウィンドウを画面の左上隅へ移動する" +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "" -#: ../src/core/all-keybindings.h:375 -msgid "Move window to north-east (top right) corner" -msgstr "ウィンドウを画面の右上隅へ移動する" +#: data/org.gnome.mutter.gschema.xml.in:108 +msgid "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes " +"mutter request a low priority real-time scheduling. The executable or user " +"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — " +"initializes Xwayland lazily if there are X11 clients. Requires restart." +msgstr "" -#: ../src/core/all-keybindings.h:378 -msgid "Move window to south-west (bottom left) corner" -msgstr "ウィンドウを画面の左下隅へ移動する" +#: data/org.gnome.mutter.gschema.xml.in:134 +msgid "Modifier to use to locate the pointer" +msgstr "" -#: ../src/core/all-keybindings.h:381 -msgid "Move window to south-east (bottom right) corner" -msgstr "ウィンドウを画面の右下隅へ移動する" +#: data/org.gnome.mutter.gschema.xml.in:135 +msgid "This key will initiate the “locate pointer” action." +msgstr "" + +#: data/org.gnome.mutter.gschema.xml.in:142 +msgid "Timeout for check-alive ping" +msgstr "" + +#: data/org.gnome.mutter.gschema.xml.in:143 +msgid "" +"Number of milliseconds a client has to respond to a ping request in order to " +"not be detected as frozen. Using 0 will disable the alive check completely." +msgstr "" -#: ../src/core/all-keybindings.h:385 -msgid "Move window to north (top) side of screen" -msgstr "ウィンドウを画面の上側へ移動する" +#: data/org.gnome.mutter.gschema.xml.in:165 +msgid "Select window from tab popup" +msgstr "タブのポップアップでウィンドウを選択します" -#: ../src/core/all-keybindings.h:388 -msgid "Move window to south (bottom) side of screen" -msgstr "ウィンドウを画面の下側へ移動する" +#: data/org.gnome.mutter.gschema.xml.in:170 +msgid "Cancel tab popup" +msgstr "" -#: ../src/core/all-keybindings.h:391 -msgid "Move window to east (right) side of screen" -msgstr "ウィンドウを画面の右側へ移動する" +#: data/org.gnome.mutter.gschema.xml.in:175 +msgid "Switch monitor configurations" +msgstr "" -#: ../src/core/all-keybindings.h:394 -msgid "Move window to west (left) side of screen" -msgstr "ウィンドウを画面の左側へ移動する" +#: data/org.gnome.mutter.gschema.xml.in:180 +msgid "Rotates the built-in monitor configuration" +msgstr "" -#: ../src/core/all-keybindings.h:397 -msgid "Move window to center of screen" -msgstr "ウィンドウを画面の中央へ移動する" +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "VT 1 へ切り替える" -#: ../src/core/bell.c:310 -msgid "Bell event" -msgstr "ベルのイベント" +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "VT 2 へ切り替える" -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "ウィンドウ情報の要求が不明です: %d" +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "VT 3 へ切り替える" -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> から応答がありません" +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "VT 4 へ切り替える" -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "アプリケーションから応答がありません" +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "VT 5 へ切り替える" -#: ../src/core/delete.c:119 +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "VT 6 へ切り替える" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "VT 7 へ切り替える" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "VT 8 へ切り替える" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "VT 9 へ切り替える" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "VT 10 へ切り替える" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "VT 11 へ切り替える" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "VT 12 へ切り替える" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow X11 grabs to lock keyboard focus with Xwayland" +msgstr "" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." +"Allow all keyboard events to be routed to X11 “override redirect” windows " +"with a grab when running in Xwayland. This option is to support X11 clients " +"which map an “override redirect” window (which do not receive keyboard " +"focus) and issue a keyboard grab to force all keyboard events to that " +"window. This option is seldom used and has no effect on regular X11 windows " +"which can receive keyboard focus under normal circumstances. For a X11 grab " +"to be taken into account under Wayland, the client must also either send a " +"specific X11 ClientMessage to the root window or be among the applications " +"white-listed in key “xwayland-grab-access-rules”." msgstr "" -"応答があるまでしばらく待機するか、今すぐにアプリケーションを強制終了するかを" -"選択して下さい。" -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "待機する(_W)" +#: data/org.gnome.mutter.wayland.gschema.xml.in:84 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "" -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "強制終了する(_F)" +#: data/org.gnome.mutter.wayland.gschema.xml.in:85 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "" -#: ../src/core/display.c:365 +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. +#. +#: src/backends/meta-input-settings.c:2567 #, c-format -msgid "Missing %s extension required for compositing" -msgstr "ウィンドウの合成に必要な %s という拡張モジュールが存在しません" +msgid "Mode Switch (Group %d)" +msgstr "モードを切り替え (グループ %d)" + +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2590 +msgid "Switch monitor" +msgstr "モニターを切り替え" + +#: src/backends/meta-input-settings.c:2592 +msgid "Show on-screen help" +msgstr "オンスクリーンヘルプを表示" + +#: src/backends/meta-monitor.c:223 +msgid "Built-in display" +msgstr "ビルトインディスプレイ" + +#: src/backends/meta-monitor.c:252 +msgid "Unknown" +msgstr "不明" + +#: src/backends/meta-monitor.c:254 +msgid "Unknown Display" +msgstr "不明なディスプレイ" -#: ../src/core/display.c:431 +#: src/backends/meta-monitor.c:262 #, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Xウィンドウ・システムのディスプレイ '%s' のオープンに失敗しました\n" +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" -#: ../src/core/keybindings.c:759 +#: src/backends/meta-monitor.c:270 #, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" + +#. Translators: this string will appear in Sysprof +#: src/backends/meta-profiler.c:79 +msgid "Compositor" msgstr "" -"既にバインディングとして別のプログラムでキー %s (修飾キー %x) を使っていま" -"す\n" -#. Displayed when a keybinding which is -#. * supposed to launch a program fails. -#. -#: ../src/core/keybindings.c:2523 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:533 #, c-format msgid "" -"There was an error running <tt>%s</tt>:\n" -"\n" -"%s" +"Another compositing manager is already running on screen %i on display “%s”." msgstr "" -"<tt>%s</tt>の動作中にエラーが発生しました:\n" -"\n" -"%s" +"すでに別の合成マネージャーがディスプレイ“%2$s”上のスクリーン %1$i で起動中で" +"す" -#: ../src/core/keybindings.c:2613 -#, c-format -msgid "No command %d has been defined.\n" -msgstr "コマンド %d は定義されていません。\n" - -#: ../src/core/keybindings.c:3625 -#, c-format -msgid "No terminal command has been defined.\n" -msgstr "端末を起動するコマンドが定義されていません。\n" +#: src/core/bell.c:192 +msgid "Bell event" +msgstr "ベルイベント" -#: ../src/core/main.c:206 +#: src/core/main.c:190 msgid "Disable connection to session manager" -msgstr "セッション・マネージャーに接続しない" +msgstr "セッションマネージャーに接続しない" -#: ../src/core/main.c:212 +#: src/core/main.c:196 msgid "Replace the running window manager" -msgstr "実行中のウィンドウ・マネージャーを置き換える" +msgstr "実行中のウィンドウマネージャーを置き換える" -#: ../src/core/main.c:218 +#: src/core/main.c:202 msgid "Specify session management ID" -msgstr "セッション管理の ID を指定する" +msgstr "セッション管理 ID を指定する" -#: ../src/core/main.c:223 +#: src/core/main.c:207 msgid "X Display to use" -msgstr "使用するXディスプレイを指定する" +msgstr "使用する X ディスプレイを指定する" -#: ../src/core/main.c:229 +#: src/core/main.c:213 msgid "Initialize session from savefile" msgstr "保存ファイルからセッションを初期化する" # 'X' という1文字は固有名詞のため大文字にする -#: ../src/core/main.c:235 +#: src/core/main.c:219 msgid "Make X calls synchronous" -msgstr "Xの呼び出しを同期させる" +msgstr "X の呼び出しを同期する" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "テーマ・フォルダーのスキャンに失敗しました: %s\n" +#: src/core/main.c:226 +msgid "Run as a wayland compositor" +msgstr "Wayland のコンポジターとして実行する" + +#: src/core/main.c:232 +msgid "Run as a nested compositor" +msgstr "" + +#: src/core/main.c:238 +msgid "Run wayland compositor without starting Xwayland" +msgstr "" + +#: src/core/main.c:246 +msgid "Run as a full display server, rather than nested" +msgstr "" + +#: src/core/main.c:252 +msgid "Run with X11 backend" +msgstr "" -#: ../src/core/main.c:520 +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:151 #, c-format +msgid "“%s” is not responding." +msgstr "“%s”から応答がありません" + +#: src/core/meta-close-dialog-default.c:153 +msgid "Application is not responding." +msgstr "アプリケーションから応答がありません" + +#: src/core/meta-close-dialog-default.c:158 msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." msgstr "" -"テーマが見つかりませんでした! %s の存在と通常のテーマが含まれていることを確" -"認して下さい。\n" +"応答があるまで少し待つか、または強制的にアプリケーションを終了するか選択して" +"ください。" + +#: src/core/meta-close-dialog-default.c:165 +msgid "_Force Quit" +msgstr "強制終了する(_F)" -#: ../src/core/muffin.c:42 +#: src/core/meta-close-dialog-default.c:165 +msgid "_Wait" +msgstr "待機する(_W)" + +#: src/core/mutter.c:38 #, c-format msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" "This is free software; see the source for copying conditions.\n" "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " "PARTICULAR PURPOSE.\n" msgstr "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., とその他の貢献者\n" -"これはフリーソフトウェアです; 複製する際の条件はソース・ファイルを参照して下" -"さい。\n" -"このソフトウェアは無保証です; 商用での利用や特定の目的に対する利用についても" -"保証しません。\n" - -#: ../src/core/muffin.c:56 +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" + +#: src/core/mutter.c:52 msgid "Print version" msgstr "バージョンを表示する" -#: ../src/core/muffin.c:62 -msgid "Comma-separated list of compositor plugins" -msgstr "画像の合成プラグインを指定する (複数ある時はカンマ ',' で区切る)" - -#. -#. * We found it, but it was invalid. Complain. -#. * -#. * FIXME: This replicates the original behaviour, but in the future -#. * we might consider reverting invalid keys to their original values. -#. * (We know the old value, so we can look up a suitable string in -#. * the symtab.) -#. * -#. * (Empty comment follows so the translators don't see this.) -#. -#. -#: ../src/core/prefs.c:550 ../src/core/prefs.c:711 -#, c-format -msgid "GConf key '%s' is set to an invalid value\n" -msgstr "GConf の '%s' キーには無効な値が格納されています\n" +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "使用する Mutter のプラグイン" -#: ../src/core/prefs.c:637 ../src/core/prefs.c:880 +#: src/core/prefs.c:1911 #, c-format -msgid "%d stored in GConf key %s is out of range %d to %d\n" -msgstr "GConf の %2$s キーの値 %1$d は %3$d〜%4$d の範囲内にありません\n" +msgid "Workspace %d" +msgstr "ワークスペース %d" -#: ../src/core/prefs.c:681 ../src/core/prefs.c:758 ../src/core/prefs.c:806 -#: ../src/core/prefs.c:870 ../src/core/prefs.c:1331 ../src/core/prefs.c:1347 -#: ../src/core/prefs.c:1364 ../src/core/prefs.c:1380 -#, c-format -msgid "GConf key \"%s\" is set to an invalid type\n" -msgstr "GConf の \"%s\" キーには無効な型が格納されています\n" +#: src/core/util.c:122 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "この mutter は詳細ログモードをサポートしていません\n" -#: ../src/core/prefs.c:1210 +#: src/wayland/meta-wayland-tablet-pad.c:568 #, c-format -msgid "GConf key %s is already in use and can't be used to override %s\n" -msgstr "GConf キーの %s は既に使用中なので %s をオーバーライドできません\n" +msgid "Mode Switch: Mode %d" +msgstr "モード切り替え: モード %d" -#: ../src/core/prefs.c:1269 +#: src/x11/meta-x11-display.c:676 #, c-format -msgid "Can't override GConf key, %s not found\n" -msgstr "GConf キーをオーバーライドできません (%s が見つかりませんでした)\n" - -#: ../src/core/prefs.c:1454 msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." msgstr "" -"仕様に準拠していないアプリケーションに対する次善策は無効になっています.一部" -"のアプリケーションは正常に動作しない可能性があります\n" +"ディスプレイ“%s”はすでにウィンドウマネージャーを持っています。現在のウィンド" +"ウマネージャーを上書きするために --replace オプションの使用を試してください。" -#: ../src/core/prefs.c:1531 -#, c-format -msgid "Could not parse font description \"%s\" from GConf key %s\n" -msgstr "GConf の %2$s キーからフォント名 \"%1$s\" を解析できませんでした\n" +#: src/x11/meta-x11-display.c:1089 +msgid "Failed to initialize GDK\n" +msgstr "GDK の初期化に失敗しました\n" -#: ../src/core/prefs.c:1593 +#: src/x11/meta-x11-display.c:1113 #, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"GConf の \"%s\" はマウス・ボタンの修飾キーとして妥当な値ではありません\n" +msgid "Failed to open X Window System display “%s”\n" +msgstr "X Window System のディスプレイ“%s”のオープンに失敗しました\n" -#: ../src/core/prefs.c:2028 +#: src/x11/meta-x11-display.c:1196 #, c-format -msgid "Error setting number of workspaces to %d: %s\n" -msgstr "ワークスペース数を %d に設定中にエラーが発生しました: %s\n" +msgid "Screen %d on display “%s” is invalid\n" +msgstr "ディスプレイ“%2$s”上のスクリーン %1$d は無効です\n" -#: ../src/core/prefs.c:2212 ../src/core/prefs.c:2714 +#: src/x11/meta-x11-selection-input-stream.c:460 #, c-format -msgid "Workspace %d" -msgstr "ワークスペース %d" +msgid "Format %s not supported" +msgstr "フォーマット %s はサポートしていません" -#: ../src/core/prefs.c:2244 ../src/core/prefs.c:2422 -#, c-format +#: src/x11/session.c:1821 msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." msgstr "" -"設定データベースで発見した \"%s\" はキーバインド \"%s\" に有効な値ではありま" -"せん\n" +"これらのウィンドウは“現在の設定を保存する”機能をサポートしません。次回ログイ" +"ンする時に手動で再起動してください。" -#: ../src/core/prefs.c:2795 +#: src/x11/window-props.c:569 #, c-format -msgid "Error setting name for workspace %d to \"%s\": %s\n" -msgstr "" -"ワークスペース %d の名前を \"%s\" に設定するときにエラーが発生しました: %s\n" +msgid "%s (on %s)" +msgstr "%s (%s)" -#: ../src/core/prefs.c:3009 -#, c-format -msgid "Error setting live hidden windows status status: %s\n" -msgstr "" -"表示されていないが動作中のウィンドウに対するステータスの設定エラー: %s\n" +#~ msgid "Move window one workspace to the left" +#~ msgstr "ウィンドウを左側のワークスペースへ移動する" -#: ../src/core/prefs.c:3044 -#, c-format -msgid "Error setting no tab popup status: %s\n" -msgstr "タブなしのポップアップ・ステータスの設定エラー: %s\n" +#~ msgid "Move window one workspace to the right" +#~ msgstr "ウィンドウを右側のワークスペースへ移動する" -#: ../src/core/screen.c:741 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "ディスプレイ '%2$s' 上のスクリーン %1$d は無効です\n" +#~ msgid "Move to workspace left" +#~ msgstr "左側のワークスペースへ移動する" -#: ../src/core/screen.c:757 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"ディスプレイ \"%2$s\" 上のスクリーン %1$d はすでにウィンドウマネージャーを" -"持っています; 現在のウィンドウマネージャーを上書きするために --replace という" -"オプションの使用を試してみて下さい。\n" +#~ msgid "Move to workspace right" +#~ msgstr "右側のワークスペースへ移動する" -#: ../src/core/screen.c:784 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "" -"ディスプレイ \"%2$s\" 上のスクリーン %1$d でウィンドウマネージャーの選択を取" -"得できませんでした\n" +#~ msgid "Toggle shaded state" +#~ msgstr "シェードの状態を切り替える" -#: ../src/core/screen.c:839 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "" -"ディスプレイ \"%2$s\" 上のスクリーン %1$d はすでにウィンドウマネージャーを" -"持っています\n" +#~ msgid "Unknown window information request: %d" +#~ msgstr "ウィンドウ情報の要求が不明です: %d" -#: ../src/core/screen.c:1024 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "ディスプレイ \"%2$s\" 上のスクリーン %1$d を解放できませんでした\n" +#~ msgid "Missing %s extension required for compositing" +#~ msgstr "ウィンドウの合成に必要な %s という拡張モジュールが存在しません" -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "ディレクトリを作成できませんでした: '%s': %s\n" +#~ msgid "" +#~ "Some other program is already using the key %s with modifiers %x as a " +#~ "binding\n" +#~ msgstr "" +#~ "既にバインディングとして別のプログラムでキー %s (修飾キー %x) を使っていま" +#~ "す\n" -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "" -"セッション・ファイルを書き込みモードでオープンできませんでした: '%s': %s\n" +#, fuzzy +#~ msgid "\"%s\" is not a valid accelerator\n" +#~ msgstr "\"%s\" はフォーカス属性のためには有効な値ではありません" + +#~ msgid "Failed to scan themes directory: %s\n" +#~ msgstr "テーマフォルダーのスキャンに失敗しました: %s\n" + +#~ msgid "" +#~ "Could not find a theme! Be sure %s exists and contains the usual themes.\n" +#~ msgstr "" +#~ "テーマが見つかりませんでした! %s の存在と通常のテーマが含まれていることを" +#~ "確認してください。\n" + +#~ msgid "" +#~ "Workarounds for broken applications disabled. Some applications may not " +#~ "behave properly.\n" +#~ msgstr "" +#~ "仕様に準拠していないアプリケーションに対する次善策は無効になっています。一" +#~ "部のアプリケーションは正常に動作しない可能性があります\n" + +#~ msgid "Could not parse font description \"%s\" from GSettings key %s\n" +#~ msgstr "" +#~ "GSettings の %2$s キーからフォント名 \"%1$s\" を解析できませんでした\n" + +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" +#~ msgstr "" +#~ "設定データベース中の \"%s\" はマウスボタンの修飾キーとして妥当な値ではあり" +#~ "ません\n" + +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for " +#~ "keybinding \"%s\"\n" +#~ msgstr "" +#~ "設定データベース中の \"%s\" はキーバインド \"%s\" に有効な値ではありませ" +#~ "ん\n" + +#~ msgid "" +#~ "Could not acquire window manager selection on screen %d display \"%s\"\n" +#~ msgstr "" +#~ "ディスプレイ \"%2$s\" 上のスクリーン %1$d でウィンドウマネージャーの選択を" +#~ "取得できませんでした\n" + +#~ msgid "Screen %d on display \"%s\" already has a window manager\n" +#~ msgstr "" +#~ "ディスプレイ \"%2$s\" 上のスクリーン %1$d はすでにウィンドウマネージャーを" +#~ "持っています\n" + +#~ msgid "Could not release screen %d on display \"%s\"\n" +#~ msgstr "ディスプレイ \"%2$s\" 上のスクリーン %1$d を解放できませんでした\n" + +#~ msgid "Could not create directory '%s': %s\n" +#~ msgstr "ディレクトリ '%s' を作成できませんでした : %s\n" + +#~ msgid "Could not open session file '%s' for writing: %s\n" +#~ msgstr "" +#~ "セッションファイル '%s' に書きこもうとオープンしましたが失敗しました: %s\n" + +#~ msgid "Error writing session file '%s': %s\n" +#~ msgstr "セッションファイル '%s' を書き込み中にエラーが発生しました: %s\n" + +#~ msgid "Error closing session file '%s': %s\n" +#~ msgstr "セッションファイル '%s' のクローズ中にエラーが発生しました: %s\n" + +#~ msgid "Failed to parse saved session file: %s\n" +#~ msgstr "保存されたセッションファイルの解析に失敗しました: %s\n" + +#~ msgid "<mutter_session> attribute seen but we already have the session ID" +#~ msgstr "" +#~ "<mutter_session> 属性はありますが、既にセッション ID を所有しています" + +#~ msgid "Unknown attribute %s on <%s> element" +#~ msgstr "<%2$s> エレメントに不明な属性 %1$s があります" + +#~ msgid "nested <window> tag" +#~ msgstr "<window> タグがネストされています" + +#~ msgid "Unknown element %s" +#~ msgstr "不明なエレメント %s があります" + +#~ msgid "Failed to open debug log: %s\n" +#~ msgstr "デバッグログのオープンに失敗しました: %s\n" + +#~ msgid "Failed to fdopen() log file %s: %s\n" +#~ msgstr "ログファイル %s の fdopen() に失敗しました: %s\n" + +#~ msgid "Opened log file %s\n" +#~ msgstr "ログファイル %s をオープンしました\n" + +#~ msgid "Window manager: " +#~ msgstr "ウィンドウマネージャー: " + +#~ msgid "Bug in window manager: " +#~ msgstr "ウィンドウマネージャーのバグ: " + +#~ msgid "Window manager warning: " +#~ msgstr "ウィンドウマネージャーの警告: " + +#~ msgid "Window manager error: " +#~ msgstr "ウィンドウマネージャーのエラー: " + +#~ msgid "" +#~ "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " +#~ "window as specified in the ICCCM.\n" +#~ msgstr "" +#~ "ウィンドウ %s は ICCCM で指定されていたような WM_CLIENT_LEADER ウィンドウ" +#~ "の代わりに自分自身で SM_CLIENT_ID を設定しています\n" + +#~ msgid "" +#~ "Window %s sets an MWM hint indicating it isn't resizable, but sets min " +#~ "size %d x %d and max size %d x %d; this doesn't make much sense.\n" +#~ msgstr "" +#~ "ウィンドウ %s はリサイズ可能ではない MWM ヒント指示を設定していますが、最" +#~ "小サイズ %d x %d と最大サイズ %d x %dも設定しています。これはあまり意味が" +#~ "ありません\n" + +#~ msgid "Application set a bogus _NET_WM_PID %lu\n" +#~ msgstr "アプリケーションが間違った _NET_WM_PID %lu を設定しました\n" + +#~ msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +#~ msgstr "" +#~ "%2$s で指定したウィンドウ 0x%1$lx の WM_TRANSIENT_FOR が間違っています\n" + +#~ msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" +#~ msgstr "" +#~ "%2$s で指定したウィンドウ 0x%1$lx の WM_TRANSIENT_FOR は無限ループになりま" +#~ "す\n" + +#~ msgid "" +#~ "Window 0x%lx has property %s\n" +#~ "that was expected to have type %s format %d\n" +#~ "and actually has type %s format %d n_items %d.\n" +#~ "This is most likely an application bug, not a window manager bug.\n" +#~ "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +#~ msgstr "" +#~ "ウィンドウ 0x%1$lx には type %5$s format %6$d n_items %7$d のプロパティ\n" +#~ "%2$s が指定されていますが、実際には type %3$s format %4$d であることを\n" +#~ "期待されています。これは、ほとんどの場合、アプリケーションのバグであり、\n" +#~ "ウィンドウマネージャーのバグではありません。\n" +#~ "ウィンドウの属性は title=\"%8$s\" class=\"%9$s\" name=\"%10$s\"です。\n" + +#~ msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +#~ msgstr "" +#~ "ウィンドウ 0x%2$lx 上のプロパティ %1$s は無効なUTF-8を含んでいました\n" + +#~ msgid "" +#~ "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the " +#~ "list\n" +#~ msgstr "" +#~ "ウィンドウ 0x%2$lx 上のプロパティ %1$s はリスト内のアイテム %3$d で無効な " +#~ "UTF-8を含んでいました\n" + +#~ msgid "Usage: %s\n" +#~ msgstr "用法: %s\n" + +#~ msgid "Mi_nimize" +#~ msgstr "最小化(_N)" + +#~ msgid "Ma_ximize" +#~ msgstr "最大化(_X)" + +#~ msgid "Unma_ximize" +#~ msgstr "元のサイズに戻す(_X)" + +#~ msgid "Roll _Up" +#~ msgstr "巻き上げる(_U)" + +#~ msgid "_Unroll" +#~ msgstr "展開する(_U)" + +#~ msgid "_Move" +#~ msgstr "移動(_M)" + +#~ msgid "_Resize" +#~ msgstr "サイズの変更(_R)" + +#~ msgid "Move Titlebar On_screen" +#~ msgstr "画面上でタイトルバーを移動する(_S)" + +#~ msgid "Always on _Top" +#~ msgstr "最前面へ(_T)" + +#~ msgid "_Always on Visible Workspace" +#~ msgstr "すべてのワークスペースに配置する(_A)" + +#~ msgid "_Only on This Workspace" +#~ msgstr "現在のワークスペースのみ(_O)" + +#~ msgid "Move to Workspace _Left" +#~ msgstr "左側のワークスペースへ移動する(_L)" + +#~ msgid "Move to Workspace R_ight" +#~ msgstr "右側のワークスペースへ移動する(_I)" + +#~ msgid "Move to Workspace _Up" +#~ msgstr "上側のワークスペースへ移動する(_U)" + +#~ msgid "Move to Workspace _Down" +#~ msgstr "下側のワークスペースへ移動する(_D)" + +#~ msgid "_Close" +#~ msgstr "閉じる(_C)" + +#~ msgid "Workspace %d%n" +#~ msgstr "ワークスペース %d%n" + +#~ msgid "Workspace 1_0" +#~ msgstr "ワークスペース 1_0" + +#~ msgid "Workspace %s%d" +#~ msgstr "ワークスペース %s%d" + +#~ msgid "Move to Another _Workspace" +#~ msgstr "別のワークスペースへ移動する(_W)" + +#~ msgid "Shift" +#~ msgstr "Shift" + +#~ msgid "Ctrl" +#~ msgstr "Ctrl" + +#~ msgid "Alt" +#~ msgstr "Alt" + +#~ msgid "Meta" +#~ msgstr "Meta" + +#~ msgid "Super" +#~ msgstr "Super" + +#~ msgid "Hyper" +#~ msgstr "Hyper" + +#~ msgid "Mod2" +#~ msgstr "Mod2" + +#~ msgid "Mod3" +#~ msgstr "Mod3" + +#~ msgid "Mod4" +#~ msgstr "Mod4" + +#~ msgid "Mod5" +#~ msgstr "Mod5" + +#~ msgid "%d x %d" +#~ msgstr "%d x %d" + +#~ msgid "top" +#~ msgstr "上" -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "セッション・ファイルに書き込む際にエラーが発生しました: '%s': %s\n" +#~ msgid "bottom" +#~ msgstr "下" -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "セッションファイルをクローズする際にエラーが発生しました: '%s': %s\n" +#~ msgid "left" +#~ msgstr "左" -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "保存したセッション・ファイルの解析に失敗しました: %s\n" +#~ msgid "right" +#~ msgstr "右" -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "<muffin_session> 属性はありますが、既にセッション ID を所有しています" +#~ msgid "frame geometry does not specify \"%s\" dimension" +#~ msgstr "フレームジオメトリは \"%s\" のサイズを指定しません" -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "<%2$s> の要素にある %1$s は不明な属性です" +#~ msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" +#~ msgstr "" +#~ "境界 \"%2$s\" 用のフレームジオメトリは大きさ \"%1$s\" を指定しません" -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "<window> タグがネストされています" +#~ msgid "Button aspect ratio %g is not reasonable" +#~ msgstr "ボタンのアスペクト比 %g は妥当ではありません" -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "不明なエレメント %s があります" +#~ msgid "Frame geometry does not specify size of buttons" +#~ msgstr "フレームジオメトリはボタンのサイズを指定しません" -#: ../src/core/session.c:1809 -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" -"これらのウィンドウは "現在の設定を保存する" という機能をサポートし" -"ていません。必要であれば、次回ログインする際に手動で起動して下さい。" +#~ msgid "Gradients should have at least two colors" +#~ msgstr "階調度は少なくとも2つの色をもつべきです" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "デバッグ・ログのオープンに失敗しました: %s\n" +#~ msgid "" +#~ "GTK custom color specification must have color name and fallback in " +#~ "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" +#~ msgstr "" +#~ "\"%s\" を解析できませんでした; GTK の色指定では gtk:custom(foo,bar); のよ" +#~ "うに括弧の中に色の名前とそれと代替えになる色の名前を指定してください" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "ログ・ファイル %s の fdopen() に失敗しました: %s\n" +#~ msgid "" +#~ "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-" +#~ "z0-9-_ are valid" +#~ msgstr "" +#~ "gtk:custom の color_name で指定した文字が間違っています (使用できる文字は " +#~ "A-Za-z0-9-_): '%c'" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "ログ・ファイル %s をオープンしました\n" +#~ msgid "" +#~ "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " +#~ "fit the format" +#~ msgstr "" +#~ "Gtk:custom の書式は \"gtk:custom(color_name,fallback)\" です (\"%s\" はこ" +#~ "の書式に合っていません)" -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "この muffin は詳細ログ・モードをサポートしていません\n" +#~ msgid "" +#~ "GTK color specification must have the state in brackets, e.g. gtk:" +#~ "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "\"%s\" を解析できませんでした; GTK の色指定では gtk:fg[NORMAL] のように状" +#~ "態を大括弧で囲み指定する必要があります (NORMAL は状態を示す)" -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "ウィンドウ・マネージャー: " +#~ msgid "" +#~ "GTK color specification must have a close bracket after the state, e.g. " +#~ "gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "\"%s\" を解析できませんでした; GTK の色指定では gtk:fg[NORMAL] のように状" +#~ "態の後に右大括弧をつける必要があります (NORMAL は状態を示す)" -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "ウィンドウ・マネージャーのバグ: " +#~ msgid "Did not understand state \"%s\" in color specification" +#~ msgstr "色指定で状態 \"%s\" は理解しませんでした" -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "ウィンドウ・マネージャーの警告: " +#~ msgid "Did not understand color component \"%s\" in color specification" +#~ msgstr "色指定でカラーコンポーネント \"%s\" は理解しませんでした" -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "ウィンドウ・マネージャーのエラー: " +#~ msgid "" +#~ "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit " +#~ "the format" +#~ msgstr "" +#~ "混合色のフォーマットは \"blend/bg_color/fg_color/alpha\" で、\"%s\" はこの" +#~ "フォーマットに適合していません" -#. first time through -#: ../src/core/window.c:7069 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"ウィンドウ %s は ICCCM で指定されてたような WM_CLIENT_LEADER ウィンドウの代わ" -"りに自分自身で SM_CLIENT_ID を設定しています\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7732 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %" -"d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"ウィンドウ %s はリサイズ可能ではない MWM ヒント指示を設定していますが,最小サ" -"イズ %d x %d と最大サイズ %d x %dも設定しています.これはあまり意味がありませ" -"ん\n" +#~ msgid "Could not parse alpha value \"%s\" in blended color" +#~ msgstr "混合色のアルファ値 \"%s\" を解析できませんでした" -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "アプリケーションが間違った _NET_WM_PID %lu を設定しました\n" +#~ msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" +#~ msgstr "混合色のアルファ値 \"%s\" は 0.0 から 1.0 の間ではありません" -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (%s)" +#~ msgid "" +#~ "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the " +#~ "format" +#~ msgstr "" +#~ "シェードのフォーマットは \"shade/base_color/factor\" で、\"%s\" はこの" +#~ "フォーマットに適合していません" + +#~ msgid "Could not parse shade factor \"%s\" in shaded color" +#~ msgstr "シェードカラーのシェード係数 \"%s\" を解析できませんでした" + +#~ msgid "Shade factor \"%s\" in shaded color is negative" +#~ msgstr "シェードカラーのシェード係数 \"%s\" が負の値です" + +#~ msgid "Could not parse color \"%s\"" +#~ msgstr "色 \"%s\" を解析できませんでした" + +#~ msgid "Coordinate expression contains character '%s' which is not allowed" +#~ msgstr "許可されていない文字 '%s' が座標式に含まれています" + +#~ msgid "" +#~ "Coordinate expression contains floating point number '%s' which could not " +#~ "be parsed" +#~ msgstr "解析できない浮動小数点数 '%s' が座標式に含まれています" + +#~ msgid "" +#~ "Coordinate expression contains integer '%s' which could not be parsed" +#~ msgstr "解析できない整数 '%s' が座標式に含まれています" + +#~ msgid "" +#~ "Coordinate expression contained unknown operator at the start of this " +#~ "text: \"%s\"" +#~ msgstr "座標式は次のテキストの先頭に無効な演算子を含んでいました: \"%s\"" + +#~ msgid "Coordinate expression was empty or not understood" +#~ msgstr "座標式が空か解析不能です" + +#~ msgid "Coordinate expression results in division by zero" +#~ msgstr "座標式はゼロで除算しました" + +#~ msgid "" +#~ "Coordinate expression tries to use mod operator on a floating-point number" +#~ msgstr "座標式は浮動小数点で mod 演算子を使用しようとしています" + +#~ msgid "" +#~ "Coordinate expression has an operator \"%s\" where an operand was expected" +#~ msgstr "座標式はオペランドが必要な場所に演算子 \"%s\" を使用しています" + +#~ msgid "Coordinate expression had an operand where an operator was expected" +#~ msgstr "座標式は演算子が必要な場所でオペランドを使用しています" + +#~ msgid "Coordinate expression ended with an operator instead of an operand" +#~ msgstr "座標式はオペランドの代わりに演算子で終わっています" + +#~ msgid "" +#~ "Coordinate expression has operator \"%c\" following operator \"%c\" with " +#~ "no operand in between" +#~ msgstr "" +#~ "座標式は演算子 \"%2$c\" の後に演算子 \"%1$c\" が続いており、これらの間にオ" +#~ "ペランドがありません" + +#~ msgid "Coordinate expression had unknown variable or constant \"%s\"" +#~ msgstr "座標式は無効な値または定数 \"%s\" が使用されていました" + +#~ msgid "Coordinate expression parser overflowed its buffer." +#~ msgstr "座標式を解析する際にオーバーフローが発生しました" + +#~ msgid "" +#~ "Coordinate expression had a close parenthesis with no open parenthesis" +#~ msgstr "座標式は左括弧がなしに右括弧が指定されています" -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "" -"%2$s で指定したウィンドウ 0x%1$lx の WM_TRANSIENT_FOR が間違っています\n" +#~ msgid "" +#~ "Coordinate expression had an open parenthesis with no close parenthesis" +#~ msgstr "座標式は左括弧が指定されていますが、右括弧がありません" -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "" -"%2$s で指定したウィンドウ 0x%1$lx の WM_TRANSIENT_FOR は無限ループになりま" -"す\n" +#~ msgid "Coordinate expression doesn't seem to have any operators or operands" +#~ msgstr "座標式は演算子もオペランドも使用していないようです" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"ウィンドウ 0x%1$lx には type %5$s format %6$d n_items %7$d のプロパティ\n" -"%2$s が指定されていますが,実際には type %3$s format %4$d であることを\n" -"期待されています.これは,ほとんどの場合,アプリケーションのバグであり,\n" -"ウィンドウマネージャーのバグではありません.\n" -"ウィンドウの属性は title=\"%8$s\" class=\"%9$s\" name=\"%10$s\"です.\n" +#~ msgid "Theme contained an expression that resulted in an error: %s\n" +#~ msgstr "テーマにエラーを引き起こす式が含まれていました: %s\n" -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "ウィンドウ 0x%2$lx 上のプロパティ %1$s は無効なUTF-8を含んでいました\n" +#~ msgid "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " +#~ "specified for this frame style" +#~ msgstr "" +#~ "このフレームスタイルは <button function=\"%s\" state=\"%s\" draw_ops=" +#~ "\"whatever\"/> を指定する必要があります" -#: ../src/core/xprops.c:494 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"ウィンドウ 0x%2$lx 上のプロパティ %1$s はリスト内のアイテム %3$d で無効な " -"UTF-8を含んでいました\n" +#~ msgid "" +#~ "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/" +#~ ">" +#~ msgstr "" +#~ "<frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>があり" +#~ "ません" -#: ../src/muffin.desktop.in.h:1 ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" +#~ msgid "Failed to load theme \"%s\": %s\n" +#~ msgstr "テーマ \"%s\" の読み込みに失敗しました: %s\n" -#: ../src/muffin.schemas.in.h:1 -msgid "Attach modal dialogs" -msgstr "モーダルなダイアログを統合するかどうか" +#~ msgid "No <%s> set for theme \"%s\"" +#~ msgstr "テーマ \"%1$s\" の <%2$s> が設定されていません" -#: ../src/muffin.schemas.in.h:2 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"現在表示されていないウィンドウ (すなわち、最小化したウィンドウや現在のワーク" -"スペースにはないウィンドウなど) を (表示させずに) そのままの状態にしておくか" -"どうかです。" +#~ msgid "" +#~ "No frame style set for window type \"%s\" in theme \"%s\", add a <window " +#~ "type=\"%s\" style_set=\"whatever\"/> element" +#~ msgstr "" +#~ "テーマ \"%2$s\" にウィンドウタイプ \"%1$s\" のフレームスタイルが設定されて" +#~ "いません。<window type=\"%3$s\" style_set=\"whatever\"/> エレメントを追加" +#~ "してください" -#: ../src/muffin.schemas.in.h:3 -msgid "" -"Determines whether workspace switching should happen for windows on all " -"monitors or only for windows on the primary monitor." -msgstr "" -"全てのモニターにあるウィンドウに対してワークスペースの切り替えを可能にする" -"か、またはプライマリ・モニターにあるウィンドウに対してのみワークスペースの切" -"り替えを提供するかどうかです。" +#~ msgid "" +#~ "User-defined constants must begin with a capital letter; \"%s\" does not" +#~ msgstr "" +#~ "ユーザー定義の定数は大文字で始まらなければなりません; \"%s\" は違います" -#: ../src/muffin.schemas.in.h:4 -msgid "Draggable border width" -msgstr "ドラッグが可能になる境界線の幅" +#~ msgid "Constant \"%s\" has already been defined" +#~ msgstr "定数 \"%s\" は既に定義されています" -#: ../src/muffin.schemas.in.h:5 -msgid "Live Hidden Windows" -msgstr "表示されていないウィンドウをそのままにしておくかどうか" +#~ msgid "No \"%s\" attribute on element <%s>" +#~ msgstr "エレメント <%2$s> に \"%1$s\" 属性がありません" -#: ../src/muffin.schemas.in.h:6 -msgid "Modifier to use for extended window management operations" -msgstr "ウィンドウの拡張管理の操作で使用する修飾キー" +#~ msgid "Line %d character %d: %s" +#~ msgstr "%d 行目 %d 文字目: %s" -#: ../src/muffin.schemas.in.h:7 -msgid "" -"The amount of total draggable borders. If the theme's visible borders are " -"not enough, invisible borders will be added to meet this value." -msgstr "" -"ドラッグができるようになる境界線の幅です。テーマで表示している境界線がこの値" -"よりも小さい場合は、表示できない境界線がこの値になるように追加されます。" +#~ msgid "Attribute \"%s\" repeated twice on the same <%s> element" +#~ msgstr "同じ <%2$s> エレメント上で属性 \"%1$s\" が 2 度繰り返されました" -#: ../src/muffin.schemas.in.h:8 -msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." -msgstr "" -"ここに指定したキーで「オーバーレイの機能」を起動します。この機能は GNOME " -"Shell などが提供するウィンドウの全体表示やアプリの起動システムと連携します。" -"デフォルトのキーは PC のキーボードにある [Windows キー] です。指定可能な値: " -"デフォルトのキー、または空の文字列" +#~ msgid "Attribute \"%s\" is invalid on <%s> element in this context" +#~ msgstr "" +#~ "このコンテキスト内では <%2$s> エレメント上の属性 \"%1$s\" は無効です" -#: ../src/muffin.schemas.in.h:9 -msgid "" -"When true, instead of having independent titlebars, modal dialogs appear " -"attached to the titlebar of the parent window and are moved together with " -"the parent window." -msgstr "" -"TRUE にすると、タイトルバーを持つ通常のモーダルなダイアログを表示する代わり" -"に、親ウィンドウのタイトルバーに統合したダイアログを表示します (親ウィンドウ" -"を移動すると一緒にモーダルなダイアログも移動します)。" +#~ msgid "Could not parse \"%s\" as an integer" +#~ msgstr "\"%s\"を整数として構文解釈できませんでした" -#: ../src/muffin.schemas.in.h:10 -msgid "Workspaces only on primary" -msgstr "プライマリ・モニターのみワークスペースを切り替えるかどうか" +#~ msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +#~ msgstr "末尾の文字列 \"%s\" (文字列 \"%s\") を理解できませんでした" -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "用法: %s\n" - -#: ../src/ui/frames.c:1157 -msgid "Close Window" -msgstr "ウィンドウを閉じます" - -#: ../src/ui/frames.c:1160 -msgid "Window Menu" -msgstr "ウィンドウ・メニューを表示します" - -#: ../src/ui/frames.c:1163 -msgid "Minimize Window" -msgstr "ウィンドウを最小化します" - -#: ../src/ui/frames.c:1166 -msgid "Maximize Window" -msgstr "ウィンドウを最大化します" - -#: ../src/ui/frames.c:1169 -msgid "Restore Window" -msgstr "ウィンドウの状態を元に戻します" - -#: ../src/ui/frames.c:1172 -msgid "Roll Up Window" -msgstr "ウィンドウを巻き上げます" - -#: ../src/ui/frames.c:1175 -msgid "Unroll Window" -msgstr "ウィンドウの巻き上げを解除します" - -#: ../src/ui/frames.c:1178 -msgid "Keep Window On Top" -msgstr "ウィンドウを最前面に維持します" - -#: ../src/ui/frames.c:1181 -msgid "Remove Window From Top" -msgstr "ウィンドウを最前面の維持から解除します" - -#: ../src/ui/frames.c:1184 -msgid "Always On Visible Workspace" -msgstr "全てのワークスペースに配置します" - -#: ../src/ui/frames.c:1187 -msgid "Put Window On Only One Workspace" -msgstr "現在のワークスペースにのみ配置します" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "最小化(_N)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "最大化(_X)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "元のサイズに戻す(_X)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "巻き上げる(_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "展開する(_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "移動(_M)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "サイズの変更(_R)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "画面上でタイトルバーを移動する(_S)" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "最前面へ(_T)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "全てのワークスペースに配置する(_A)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "現在のワークスペースのみ(_O)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "左側のワークスペースへ移動する(_L)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "右側のワークスペースへ移動する(_I)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "上側のワークスペースへ移動する(_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "下側のワークスペースへ移動する(_D)" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "閉じる(_C)" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "ワークスペース %d%n" +#~ msgid "Integer %ld must be positive" +#~ msgstr "整数 %ld は正数でなければなりません" -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "ワークスペース 1_0" +#~ msgid "Integer %ld is too large, current max is %d" +#~ msgstr "整数 %ld は大きすぎます、現在の最大は %d です" -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "ワークスペース %s%d" +#~ msgid "Could not parse \"%s\" as a floating point number" +#~ msgstr "浮動小数点として \"%s\" を解析できませんでした" -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "別のワークスペースへ移動する(_W)" +#~ msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" +#~ msgstr "" +#~ "ブール値は \"true\" か \"false\" でなければならず \"%s\" ではありません" -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" +#~ msgid "Angle must be between 0.0 and 360.0, was %g\n" +#~ msgstr "角度は 0.0 から 360.0 の間でなければなりませんが、%g でした\n" -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" +#~ msgid "" +#~ "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" +#~ msgstr "" +#~ "アルファ値は 0.0 (不可視)と 1.0 (完全に不透明) の間でなければなりません" +#~ "が、%g でした\n" -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "上" +#~ msgid "" +#~ "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," +#~ "large,x-large,xx-large)\n" +#~ msgstr "" +#~ "無効なタイトルスケール \"%s\" です (xx-small,x-small,small,medium,large,x-" +#~ "large,xx-large のひとつでなければなりません)\n" -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "下" +#~ msgid "<%s> name \"%s\" used a second time" +#~ msgstr "<%s> の名前 \"%s\"が2回使われています" -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "左" +#~ msgid "<%s> parent \"%s\" has not been defined" +#~ msgstr "<%s> の親 \"%s\" は定義されていません" -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "右" +#~ msgid "<%s> geometry \"%s\" has not been defined" +#~ msgstr "<%s> のジオメトリ \"%s\" は定義されていません" -#: ../src/ui/theme.c:286 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "フレームジオメトリは \"%s\" のサイズを指定しません" +#~ msgid "<%s> must specify either a geometry or a parent that has a geometry" +#~ msgstr "" +#~ "<%s> はジオメトリ、またはジオメトリを持つ親のどちらかを指定しなければなり" +#~ "ません" -#: ../src/ui/theme.c:305 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "境界 \"%2$s\" 用のフレームジオメトリは大きさ \"%1$s\" を指定しません" +#~ msgid "You must specify a background for an alpha value to be meaningful" +#~ msgstr "背景色の妥当なアルファ値を指定してください" -#: ../src/ui/theme.c:342 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "ボタンのアスペクト比 %g は妥当ではありません" +#~ msgid "Unknown type \"%s\" on <%s> element" +#~ msgstr "<%2$s> エレメント上に不明なタイプ \"%1$s\" があります" -#: ../src/ui/theme.c:354 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "フレームジオメトリはボタンのサイズを指定しません" +#~ msgid "Unknown style_set \"%s\" on <%s> element" +#~ msgstr "<%2$s> エレメント上に不明な style_set \"%1$s\" があります" -#: ../src/ui/theme.c:1065 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "階調度は少なくとも2つの色をもつべきです" +#~ msgid "Window type \"%s\" has already been assigned a style set" +#~ msgstr "ウィンドウタイプ \"%s\" はすでにスタイル設定に割り当てられています" -#: ../src/ui/theme.c:1217 -#, c-format -msgid "" -"GTK custom color specification must have color name and fallback in " -"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" -msgstr "" -"\"%s\" を解析できませんでした; GTK の色指定では gtk:custom(foo,bar); のように" -"括弧の中に色の名前とそれと代替えになる色の名前を指定して下さい" +#~ msgid "Element <%s> is not allowed below <%s>" +#~ msgstr "エレメント <%s> は <%s> の下では許可されていません" -#: ../src/ui/theme.c:1233 -#, c-format -msgid "" -"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" -"_ are valid" -msgstr "" -"gtk:custom の color_name で指定した文字が間違っています (使用できる文字は A-" -"Za-z0-9-_): '%c'" +#~ msgid "" +#~ "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio" +#~ "\" for buttons" +#~ msgstr "" +#~ "\"button_width\"/\"button_height\" と \"aspect_ratio\" の両方のプロパティ" +#~ "を指定することはできません" -#: ../src/ui/theme.c:1247 -#, c-format -msgid "" -"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " -"fit the format" -msgstr "" -"Gtk:custom の書式は \"gtk:custom(color_name,fallback)\" です (\"%s\" はこの書" -"式に合っていません)" +#~ msgid "Distance \"%s\" is unknown" +#~ msgstr "間隔 \"%s\" は不明です" -#: ../src/ui/theme.c:1292 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"\"%s\" を解析できませんでした; GTK の色指定では gtk:fg[NORMAL] のように状態を" -"大括弧で囲み指定する必要があります (NORMAL は状態を示す)" +#~ msgid "Aspect ratio \"%s\" is unknown" +#~ msgstr "アスペクト比\"%s\"は不明です" -#: ../src/ui/theme.c:1306 -#, c-format -msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"\"%s\" を解析できませんでした; GTK の色指定では gtk:fg[NORMAL] のように状態の" -"後に右大括弧をつける必要があります (NORMAL は状態を示す)" +#~ msgid "Border \"%s\" is unknown" +#~ msgstr "境界 \"%s\" は不明です" -#: ../src/ui/theme.c:1317 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "色指定で状態 \"%s\" は理解しませんでした" +#~ msgid "No \"start_angle\" or \"from\" attribute on element <%s>" +#~ msgstr "エレメント <%s> に \"start_angle\" または \"from\" 属性はありません" -#: ../src/ui/theme.c:1330 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "色指定でカラーコンポーネント \"%s\" は理解しませんでした" +#~ msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" +#~ msgstr "" +#~ "エレメント <%s> に \"extent_angle\" または \"to\" 属性はありません\n" +#~ " " -#: ../src/ui/theme.c:1360 -#, c-format -msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" -msgstr "" -"混合色のフォーマットは \"blend/bg_color/fg_color/alpha\" で,\"%s\" はこの" -"フォーマットに適合していません" +#~ msgid "Did not understand value \"%s\" for type of gradient" +#~ msgstr "階調度のタイプの値 \"%s\" は解釈されませんでした" -#: ../src/ui/theme.c:1371 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "混合色のアルファ値 \"%s\" を解析できませんでした" +#~ msgid "Did not understand fill type \"%s\" for <%s> element" +#~ msgstr "<%2$s>エレメント用のフィルタイプ \"%1$s\"は解釈されませんでした" -#: ../src/ui/theme.c:1381 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "混合色のアルファ値 \"%s\" は 0.0 から 1.0 の間ではありません" +#~ msgid "Did not understand state \"%s\" for <%s> element" +#~ msgstr "<%2$s> エレメント用の状態 \"%1$s\" は解釈されませんでした" -#: ../src/ui/theme.c:1428 -#, c-format -msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "" -"シェードのフォーマットは \"shade/base_color/factor\" で,\"%s\" はこのフォー" -"マットに適合していません" +#~ msgid "Did not understand shadow \"%s\" for <%s> element" +#~ msgstr "<%2$s> エレメント用の影 \"%1$s\" は解釈されませんでした" -#: ../src/ui/theme.c:1439 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "シェードカラーのシェード係数 \"%s\" をパスできませんでした" +#~ msgid "Did not understand arrow \"%s\" for <%s> element" +#~ msgstr "<%2$s> エレメント用の矢印 \"%1$s\" は解釈されませんでした" -#: ../src/ui/theme.c:1449 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "シェードカラーのシェード係数 \"%s\" が負の値です" +#~ msgid "No <draw_ops> called \"%s\" has been defined" +#~ msgstr "\"%s\"を呼ぶ <draw_ops> は定義されていません" -#: ../src/ui/theme.c:1478 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "次の色を解析できませんでした: \"%s\"" +#~ msgid "Including draw_ops \"%s\" here would create a circular reference" +#~ msgstr "ここに draw_ops \"%s\" を含めると循環参照が生成されます" -#: ../src/ui/theme.c:1789 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "許可されていない文字が座標式に含まれています: '%s'" +#~ msgid "Unknown position \"%s\" for frame piece" +#~ msgstr "フレーム要素の場所 \"%s\" は不明です" -#: ../src/ui/theme.c:1816 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "解析できない浮動小数点数が座標式に含まれています: '%s'" +#~ msgid "Frame style already has a piece at position %s" +#~ msgstr "フレームスタイルはすでに場所 %s に要素を持っています" + +#~ msgid "No <draw_ops> with the name \"%s\" has been defined" +#~ msgstr "名前 \"%s\" で <draw_ops>が定義されていません" + +#~ msgid "Unknown function \"%s\" for button" +#~ msgstr "ボタンのための機能 \"%s\" は不明です" + +#~ msgid "Button function \"%s\" does not exist in this version (%d, need %d)" +#~ msgstr "" +#~ "このバージョンでは \"%s\" というボタンの機能は提供していません (現 %d, 要 " +#~ "%d)" + +#~ msgid "Unknown state \"%s\" for button" +#~ msgstr "ボタンのための状態 \"%s\" は不明です" + +#~ msgid "Frame style already has a button for function %s state %s" +#~ msgstr "フレームスタイルはすでに機能 %s 状態 %s のボタンを持っています" -#: ../src/ui/theme.c:1830 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "解析できない整数が座標式に含まれています: '%s'" +#~ msgid "\"%s\" is not a valid value for focus attribute" +#~ msgstr "\"%s\" はフォーカス属性のためには有効な値ではありません" -#: ../src/ui/theme.c:1952 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "次のテキストの先頭に無効な演算子が座標式の中に含まれていました: \"%s\"" +#~ msgid "\"%s\" is not a valid value for state attribute" +#~ msgstr "\"%s\" は状態の属性のためには有効な値ではありません" -#: ../src/ui/theme.c:2009 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "座標式が空か解析不能です" +#~ msgid "A style called \"%s\" has not been defined" +#~ msgstr "\"%s\" に呼ばれるスタイルは定義されていません" -#: ../src/ui/theme.c:2120 ../src/ui/theme.c:2130 ../src/ui/theme.c:2164 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "座標式はゼロで除算しました" +#~ msgid "\"%s\" is not a valid value for resize attribute" +#~ msgstr "\"%s\" はリサイズ属性のためには有効な値ではありません" -#: ../src/ui/theme.c:2172 -#, c-format -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "座標式は浮動小数点で mod 演算子を使用しようとしています" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized/shaded " +#~ "states" +#~ msgstr "" +#~ "最大化/シェード化のための <%s> エレメントには \"resize\" 属性を指定できま" +#~ "せん" -#: ../src/ui/theme.c:2228 -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "座標式はオペランドが必要な場所に演算子 \"%s\" を使用しています" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized states" +#~ msgstr "最大化のための <%s> エレメントには \"resize\" 属性を指定できません" -#: ../src/ui/theme.c:2237 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "座標式は演算子が必要な場所でオペランドを使用しています" +#~ msgid "Style has already been specified for state %s resize %s focus %s" +#~ msgstr "" +#~ "状態 %s リサイズ %s フォーカス %s のためのスタイルはすでに指定されています" -#: ../src/ui/theme.c:2245 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "座標式はオペランドの代わりに演算子で終わっています" +#~ msgid "Style has already been specified for state %s focus %s" +#~ msgstr "状態 %s フォーカス %s のためのスタイルはすでに指定されています" -#: ../src/ui/theme.c:2255 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" -"座標式は演算子 \"%2$c\" の後に演算子 \"%1$c\" が続いており,これらの間にオペ" -"ランドがありません" +#~ msgid "" +#~ "Can't have a two draw_ops for a <piece> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "<piece> エレメントは2つの draw_ops を持つことができません (テーマで " +#~ "draw_ops 属性と <draw_ops> エレメントが指定されたか、あるいは 2 つのエレメ" +#~ "ントが指定されました)" -#: ../src/ui/theme.c:2406 ../src/ui/theme.c:2451 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "座標式は無効な値または定数 \"%s\" が使用されていました" +#~ msgid "" +#~ "Can't have a two draw_ops for a <button> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "<button> エレメントは 2 つの draw_ops を持つことができません (テーマで " +#~ "draw_ops 属性と <draw_ops> エレメントが指定されたか、あるいは 2 つのエレメ" +#~ "ントが指定されました)" -#: ../src/ui/theme.c:2505 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "座標式を解析する際にオーバーフローが発生しました" +#~ msgid "" +#~ "Can't have a two draw_ops for a <menu_icon> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "<menu_icon> エレメントは 2 つの draw_ops を持つことができません (テーマで " +#~ "draw_ops 属性と <draw_ops> エレメントが指定されたか、あるいは 2 つのエレメ" +#~ "ントが指定されました)" -#: ../src/ui/theme.c:2534 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "座標式は左括弧がなしに右括弧が指定されています" +#~ msgid "Bad version specification '%s'" +#~ msgstr "バージョン '%s' の仕様はサポートしていません" -#: ../src/ui/theme.c:2598 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "座標式は左括弧が指定されていますが,右括弧がありません" +#~ msgid "" +#~ "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" +#~ "theme-2.xml" +#~ msgstr "" +#~ "\"version\" 属性は metacity-theme-1.xml や metacity-theme-2.xml では指定で" +#~ "きません" -#: ../src/ui/theme.c:2609 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "座標式は演算子もオペランドも使用していないようです" +#~ msgid "" +#~ "Theme requires version %s but latest supported theme version is %d.%d" +#~ msgstr "" +#~ "バージョン %s のテーマが必要ですが、サポートしている最新のバージョンは %d." +#~ "%d です" -#: ../src/ui/theme.c:2821 ../src/ui/theme.c:2841 ../src/ui/theme.c:2861 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "テーマにエラーを引き起こす式が含まれていました: %s\n" +#~ msgid "Outermost element in theme must be <metacity_theme> not <%s>" +#~ msgstr "" +#~ "テーマの最も外側のエレメントは <metacity_theme> でなければならず、<%s>では" +#~ "ありません" -#: ../src/ui/theme.c:4532 -#, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" -"このフレームスタイルは <button function=\"%s\" state=\"%s\" draw_ops=" -"\"whatever\"/> を指定する必要があります" +#~ msgid "" +#~ "Element <%s> is not allowed inside a name/author/date/description element" +#~ msgstr "" +#~ "エレメント <%s> は name/author/date/description エレメントの内側に許可され" +#~ "ていません" -#: ../src/ui/theme.c:5065 ../src/ui/theme.c:5090 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" -"<frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>がありませ" -"ん" +#~ msgid "Element <%s> is not allowed inside a <constant> element" +#~ msgstr "エレメント <%s> は <constant> エレメントの内側に許可されていません" -#: ../src/ui/theme.c:5138 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "テーマ \"%s\" の読み込みに失敗しました: %s\n" +#~ msgid "" +#~ "Element <%s> is not allowed inside a distance/border/aspect_ratio element" +#~ msgstr "" +#~ "エレメント <%s> はdistance/border/aspect_ratioエレメントの内側に許可されて" +#~ "いません" -#: ../src/ui/theme.c:5274 ../src/ui/theme.c:5281 ../src/ui/theme.c:5288 -#: ../src/ui/theme.c:5295 ../src/ui/theme.c:5302 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "テーマ \"%1$s\" の <%2$s> が設定されていません" +#~ msgid "Element <%s> is not allowed inside a draw operation element" +#~ msgstr "エレメント <%s> は描画処理エレメントの内側に許可されていません" -#: ../src/ui/theme.c:5310 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" -"テーマ \"%2$s\" にウィンドウタイプ \"%1$s\" のフレームスタイルが設定されてい" -"ません.<window type=\"%3$s\" style_set=\"whatever\"/> エレメントを追加してく" -"ださい" +#~ msgid "Element <%s> is not allowed inside a <%s> element" +#~ msgstr "エレメント <%s> は <%s> エレメントの内側に許可されていません" -#: ../src/ui/theme.c:5708 ../src/ui/theme.c:5770 ../src/ui/theme.c:5833 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" -"ユーザー定義の定数は大文字で始まらなければなりません; \"%s\" は違います" +#~ msgid "No draw_ops provided for frame piece" +#~ msgstr "フレームのための draw_ops は提供されていません" -#: ../src/ui/theme.c:5716 ../src/ui/theme.c:5778 ../src/ui/theme.c:5841 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "定数 \"%s\" は既に定義されています" +#~ msgid "No draw_ops provided for button" +#~ msgstr "ボタンのための draw_ops は提供されていません" -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. -#. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "<%2$s> の要素には \"%1$s\" という属性はありません" +#~ msgid "No text is allowed inside element <%s>" +#~ msgstr "エレメント <%s> の内側にテキストは許可されません" -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "%d 行目 %d 文字目: %s" +#~ msgid "<%s> specified twice for this theme" +#~ msgstr "このテーマで <%s> を二回指定しました" -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "同じ <%2$s> エレメント上で属性 \"%1$s\" が 2 度繰り返されました" +#~ msgid "Failed to find a valid file for theme %s\n" +#~ msgstr "%s というテーマの妥当なファイルが見つかりませんでした\n" -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "このコンテキスト内では <%2$s> エレメント上の属性 \"%1$s\" は無効です" +#~ msgid "_Windows" +#~ msgstr "ウィンドウ(_W)" -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "\"%s\"を整数として構文解釈できませんでした" +#~ msgid "_Dialog" +#~ msgstr "ダイアログ(_D)" -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "末尾の文字列 \"%s\" (文字列 \"%s\") を理解できませんでした" +#~ msgid "_Modal dialog" +#~ msgstr "モーダルダイアログ(_M)" -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "整数 %ld は正数でなければなりません" +#~ msgid "_Utility" +#~ msgstr "ユーティリティ(_U)" -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "整数 %ld は大きすぎます,現在の最大は %d です" +#~ msgid "_Splashscreen" +#~ msgstr "スプラッシュスクリーン(_S)" -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "浮動小数点として \"%s\" を解析できませんでした" +#~ msgid "_Top dock" +#~ msgstr "上ドック(_T)" -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "" -"ブール値は \"true\" か \"false\" でなければならず \"%s\" ではありません" +#~ msgid "_Bottom dock" +#~ msgstr "下ドック(_B)" -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "角度は 0.0 から 360.0 の間でなければなりませんが,%g でした\n" +#~ msgid "_Left dock" +#~ msgstr "左ドック(_L)" -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" -"アルファ値は 0.0 (不可視)と 1.0 (完全に不透明) の間でなければなりませんが,%" -"g でした\n" +#~ msgid "_Right dock" +#~ msgstr "右ドック(_R)" -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"無効なタイトルスケール \"%s\" です (xx-small,x-small,small,medium,large,x-" -"large,xx-large のひとつでなければなりません)\n" +#~ msgid "_All docks" +#~ msgstr "すべてのドック(_A)" -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s> の名前 \"%s\"が2回使われています" +#~ msgid "Des_ktop" +#~ msgstr "デスクトップ(_K)" -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "<%s> の親 \"%s\" は定義されていません" +#~ msgid "Open another one of these windows" +#~ msgstr "これらのウィンドウをもう一つ別に表示" -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "<%s> のジオメトリ \"%s\" は定義されていません" +#~ msgid "This is a demo button with an 'open' icon" +#~ msgstr "これは'開く'アイコンが付いたデモボタンです" -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "" -"<%s> はジオメトリ,またはジオメトリを持つ親のどちらかを指定しなければなりませ" -"ん" +#~ msgid "This is a demo button with a 'quit' icon" +#~ msgstr "これは'終了'アイコンが付いたデモボタンです" -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "背景色の妥当なアルファ値を指定して下さい" +#~ msgid "This is a sample message in a sample dialog" +#~ msgstr "これはサンプルダイアログの中のサンプルメッセージです" -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "<%2$s> エレメント上に不明なタイプ \"%1$s\" があります" +#~ msgid "Fake menu item %d\n" +#~ msgstr "見せかけのメニューアイテム %d\n" -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "<%2$s> エレメント上に不明な style_set \"%1$s\" があります" +#~ msgid "Border-only window" +#~ msgstr "ボーダーのみのウィンドウ" -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "ウィンドウタイプ \"%s\" はすでにスタイル設定に割り当てられています" - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "エレメント <%s> は <%s> の下では許可されていません" +#~ msgid "Bar" +#~ msgstr "バー" -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" -msgstr "" -"複数のボタンに \"button_width\"/\"button_height\" と \"aspect_ratio\" の両方" -"の属性を指定できません" +#~ msgid "Normal Application Window" +#~ msgstr "通常のアプリケーションウィンドウ" -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "間隔 \"%s\" は不明です" +#~ msgid "Dialog Box" +#~ msgstr "ダイアログボックス" -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "アスペクト比 \"%s\"は不明です" +#~ msgid "Modal Dialog Box" +#~ msgstr "モーダルダイアログボックス" -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "境界 \"%s\" は不明です" +#~ msgid "Utility Palette" +#~ msgstr "ユーティリティパレット" -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "エレメント <%s> に \"start_angle\" または \"from\" 属性はありません" +#~ msgid "Torn-off Menu" +#~ msgstr "トーンオフ メニュー" -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "" -"エレメント <%s> に \"extent_angle\" または \"to\" 属性はありません\n" -" " +#~ msgid "Border" +#~ msgstr "ボーダー" -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "階調度のタイプの値 \"%s\" は解釈されませんでした" +#~ msgid "Attached Modal Dialog" +#~ msgstr "埋め込んだモーダルなダイアログ" -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "<%2$s>エレメント用のフィルタイプ \"%1$s\"は解釈されませんでした" +#~ msgid "Button layout test %d" +#~ msgstr "ボタンレイアウトのテスト %d" -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "<%2$s> エレメント用の状態 \"%1$s\" は解釈されませんでした" +#~ msgid "%g milliseconds to draw one window frame" +#~ msgstr "一つのウィンドウフレームの描画時間: %g ミリ秒" -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "<%2$s> エレメント用の影 \"%1$s\" は解釈されませんでした" +#~ msgid "Usage: metacity-theme-viewer [THEMENAME]\n" +#~ msgstr "用法: metacity-theme-viewer [テーマ名]\n" -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "<%2$s> エレメント用の矢印 \"%1$s\" は解釈されませんでした" +#~ msgid "Error loading theme: %s\n" +#~ msgstr "テーマのロードでエラーが発生しました: %s\n" -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "\"%s\"を呼ぶ <draw_ops> は定義されていません" +#~ msgid "Loaded theme \"%s\" in %g seconds\n" +#~ msgstr "\"%s\" というテーマを %g秒で読み込みました\n" -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "ここに draw_ops \"%s\" を含めると循環参照が生成されます" +#~ msgid "Normal Title Font" +#~ msgstr "通常のタイトルフォント" -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "フレーム要素の場所 \"%s\" は不明です" +#~ msgid "Small Title Font" +#~ msgstr "小さいタイトルフォント" -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "フレームスタイルはすでに場所 %s に要素を持っています" +#~ msgid "Large Title Font" +#~ msgstr "大きいタイトルフォント" -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "名前 \"%s\" で <draw_ops>が定義されていません" +#~ msgid "Button Layouts" +#~ msgstr "ボタンレイアウト" -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "ボタンのための機能 \"%s\" は不明です" +#~ msgid "Benchmark" +#~ msgstr "ベンチマーク" -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "" -"このバージョンでは \"%s\" というボタンの機能は提供していません (現 %d, 要 %d)" +#~ msgid "Window Title Goes Here" +#~ msgstr "ここにウィンドウのタイトルが表示されます" -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "ボタンのための状態 \"%s\" は不明です" +#~ msgid "" +#~ "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and " +#~ "%g seconds wall clock time including X server resources (%g milliseconds " +#~ "per frame)\n" +#~ msgstr "" +#~ "%d フレームをクライアント側で %g秒 (1フレームにつき %gミリ秒)、実時間ではX" +#~ "サーバーのリソースを含めて %g秒 (1フレームにつき %gミリ秒)で描画しました\n" -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "フレームスタイルはすでに機能 %s 状態 %s のボタンを持っています" +#~ msgid "position expression test returned TRUE but set error" +#~ msgstr "位置式テストはTRUEを返しましたがエラーがセットされています" -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "\"%s\" はフォーカス属性のためには有効な値ではありません" +#~ msgid "position expression test returned FALSE but didn't set error" +#~ msgstr "位置式テストはFALSEを返しましたがエラーをセットしていません" -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "\"%s\" は状態の属性のためには有効な値ではありません" +#~ msgid "Error was expected but none given" +#~ msgstr "エラーが起きるはずですが何も起こりませんでした" -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "\"%s\" に呼ばれるスタイルは定義されていません" +#~ msgid "Error %d was expected but %d given" +#~ msgstr "エラー %d が起きるはずですが %d が起こりました" -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "\"%s\" はリサイズ属性のためには有効な値ではありません" +#~ msgid "Error not expected but one was returned: %s" +#~ msgstr "エラーは起きないはずですが一つ発生しました: %s" -#: ../src/ui/theme-parser.c:3147 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" -"最大化/シェード化のための <%s> エレメントには \"resize\" 属性を指定できません" +#~ msgid "x value was %d, %d was expected" +#~ msgstr "xの値が %d でした (期待値: %d)" -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "最大化のための <%s> エレメントには \"resize\" 属性を指定できません" +#~ msgid "y value was %d, %d was expected" +#~ msgstr "yの値は %d でした (期待値: %d)" -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "" -"状態 %s リサイズ %s フォーカス %s のためのスタイルはすでに指定されています" +#~ msgid "" +#~ "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" +#~ msgstr "%d個の座標式を %g秒 (平均 %g秒) で解析しました\n" -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "状態 %s フォーカス %s のためのスタイルはすでに指定されています" +#~ msgid "Comma-separated list of compositor plugins" +#~ msgstr "画像の合成プラグインを指定する (複数ある時はカンマ ',' で区切る)" -#: ../src/ui/theme-parser.c:3294 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"<piece> エレメントは2つの draw_ops を持つことができません (テーマで draw_ops " -"属性と <draw_ops> エレメントが指定されたか,あるいは 2 つのエレメントが指定さ" -"れました)" +#~ msgid "Live Hidden Windows" +#~ msgstr "表示されていないウィンドウをそのままにしておくかどうか" -#: ../src/ui/theme-parser.c:3332 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"<button> エレメントは 2 つの draw_ops を持つことができません (テーマで " -"draw_ops 属性と <draw_ops> エレメントが指定されたか,あるいは 2 つのエレメン" -"トが指定されました)" +#~ msgid "" +#~ "Determines whether hidden windows (i.e., minimized windows and windows on " +#~ "other workspaces than the current one) should be kept alive." +#~ msgstr "" +#~ "現在表示されていないウィンドウ (すなわち、最小化したウィンドウや現在のワー" +#~ "クスペースにはないウィンドウなど) を (表示させずに) そのままの状態にしてお" +#~ "くかどうかです。" -#: ../src/ui/theme-parser.c:3370 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"<menu_icon> エレメントは 2 つの draw_ops を持つことができません (テーマで " -"draw_ops 属性と <draw_ops> エレメントが指定されたか,あるいは 2 つのエレメン" -"トが指定されました)" +#~ msgid "Switch to workspace on the left of the current workspace" +#~ msgstr "左側のワークスペースへ切り替える" -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "バージョン '%s' の仕様はサポートしていません" +#~ msgid "Switch to workspace on the right of the current workspace" +#~ msgstr "右側のワークスペースへ切り替える" -#: ../src/ui/theme-parser.c:3507 -msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" -msgstr "" -"\"version\" 属性は metacity-theme-1.xml や metacity-theme-2.xml では指定でき" -"ません" +#~ msgid "Switch to workspace above the current workspace" +#~ msgstr "上側のワークスペースへ切り替える" -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "" -"バージョン %s のテーマが必要ですが、サポートしている最新のバージョンは %d.%d " -"です" +#~ msgid "Switch to workspace below the current workspace" +#~ msgstr "下側のワークスペースへ切り替える" -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "" -"テーマの最も外側のエレメントは <metacity_theme> でなければならず,<%s>ではあ" -"りません" +#~ msgid "Move between windows of an application, using a popup window" +#~ msgstr "ポップアップウィンドウを使って複数のウィンドウの間を移動する" -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "" -"エレメント <%s> は name/author/date/description エレメントの内側に許可されて" -"いません" +#~ msgid "" +#~ "Move backward between windows of an application, using a popup window" +#~ msgstr "ポップアップウィンドウを使って複数のウィンドウの間を降順で移動する" -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "エレメント <%s> は <constant> エレメントの内側に許可されていません" +#~ msgid "Move between windows, using a popup window" +#~ msgstr "ポップアップウィンドウを使ってウィンドウ間のフォーカスを切り替える" -#: ../src/ui/theme-parser.c:3599 -#, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "" -"エレメント <%s> はdistance/border/aspect_ratioエレメントの内側に許可されてい" -"ません" +#~ msgid "Move backward between windows, using a popup window" +#~ msgstr "" +#~ "ポップアップウィンドウを使ってウィンドウ間のフォーカスを降順で切り替える" -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "エレメント <%s> は描画処理エレメントの内側に許可されていません" +#~ msgid "Move between panels and the desktop, using a popup window" +#~ msgstr "" +#~ "ポップアップウィンドウを使ってパネルとデスクトップの間のフォーカスを切り替" +#~ "える" -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "エレメント <%s> は <%s> エレメントの内側に許可されていません" +#~ msgid "Move backward between panels and the desktop, using a popup window" +#~ msgstr "" +#~ "ポップアップウィンドウを使ってパネルとデスクトップの間のフォーカスを降順で" +#~ "切り替える" -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "フレームのための draw_ops は提供されていません" +#~ msgid "Move backward between windows of an application immediately" +#~ msgstr "アプリケーションが持つ複数のウィンドウを降順で移動する" -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "ボタンのための draw_ops は提供されていません" +#~ msgid "Move between windows immediately" +#~ msgstr "ウィンドウ間のフォーカスを切り替える" -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "エレメント <%s> の内側にテキストは許可されません" +#~ msgid "Move backward between windows immediately" +#~ msgstr "ウィンドウ間のフォーカスを降順で切り替える" -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "このテーマでは <%s> という要素を2回指定しています" +#~ msgid "Move between panels and the desktop immediately" +#~ msgstr "パネルとデスクトップとのフォーカスを切り替える" -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "%s というテーマの妥当なファイルが見つかりませんでした\n" +#~ msgid "Move backward between panels and the desktop immediately" +#~ msgstr "後方のパネルとデスクトップとの間を切り替える" -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "ウィンドウ(_W)" +#~ msgid "Show the panel's \"Run Application\" dialog box" +#~ msgstr "アプリケーションの実行ダイアログを開く" -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "ダイアログ(_D)" +#~ msgid "Start or stop recording the session" +#~ msgstr "セッションの録画を開始/停止する" -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "モーダルなダイアログ(_M)" +#~ msgid "Take a screenshot" +#~ msgstr "スクリーンショットを撮る" -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "ユーティリティ(_U)" +#~ msgid "Take a screenshot of a window" +#~ msgstr "ウィンドウのスクリーンショットを撮る" -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "スプラッシュスクリーン(_S)" +#~ msgid "Run a terminal" +#~ msgstr "端末を起動する" -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "上側のドック(_T)" +#~ msgid "Toggle whether a window will always be visible over other windows" +#~ msgstr "ウィンドウを常に前面に表示するかどうかの設定を切り替える" -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "下側のドック(_B)" +#~ msgid "Minimize window" +#~ msgstr "ウィンドウを最小化する" -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "左側のドック(_L)" +#~ msgid "Move window to workspace 5" +#~ msgstr "ウィンドウをワークスペース 5 へ移動する" -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "右側のドック(_R)" +#~ msgid "Move window to workspace 6" +#~ msgstr "ウィンドウをワークスペース 6 へ移動する" -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "全てのドック(_A)" +#~ msgid "Move window to workspace 7" +#~ msgstr "ウィンドウをワークスペース 7 へ移動する" -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "デスクトップ(_K)" +#~ msgid "Move window to workspace 8" +#~ msgstr "ウィンドウをワークスペース 8 へ移動する" -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "複数あるウィンドウの別のウィンドウを開きます" +#~ msgid "Move window to workspace 9" +#~ msgstr "ウィンドウをワークスペース 9 へ移動する" -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "これは '開く' のアイコンを持つボタンの例です" +#~ msgid "Move window to workspace 10" +#~ msgstr "ウィンドウをワークスペース 10 へ移動する" -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "これは '終了' のアイコンを持つボタンの例です" +#~ msgid "Move window to workspace 11" +#~ msgstr "ウィンドウをワークスペース 11 へ移動する" -#: ../src/ui/theme-viewer.c:253 -msgid "This is a sample message in a sample dialog" -msgstr "これはサンプル・ダイアログの中に表示したサンプル・メッセージです" +#~ msgid "Move window to workspace 12" +#~ msgstr "ウィンドウをワークスペース 12 へ移動する" -#: ../src/ui/theme-viewer.c:336 -#, c-format -msgid "Fake menu item %d\n" -msgstr "メニュー・アイテムの例%d\n" +#~ msgid "Move window to north-west (top left) corner" +#~ msgstr "ウィンドウを画面の左上隅へ移動する" -#: ../src/ui/theme-viewer.c:371 -msgid "Border-only window" -msgstr "境界線だけのウィンドウ" +#~ msgid "Move window to north-east (top right) corner" +#~ msgstr "ウィンドウを画面の右上隅へ移動する" -#: ../src/ui/theme-viewer.c:373 -msgid "Bar" -msgstr "バー" +#~ msgid "Move window to south-west (bottom left) corner" +#~ msgstr "ウィンドウを画面の左下隅へ移動する" -#: ../src/ui/theme-viewer.c:390 -msgid "Normal Application Window" -msgstr "通常のアプリケーション・ウィンドウ" +#~ msgid "Move window to south-east (bottom right) corner" +#~ msgstr "ウィンドウを画面の右下隅へ移動する" -#: ../src/ui/theme-viewer.c:394 -msgid "Dialog Box" -msgstr "ダイアログ・ボックス" +#~ msgid "Move window to north (top) side of screen" +#~ msgstr "ウィンドウを画面の上側へ移動する" -#: ../src/ui/theme-viewer.c:398 -msgid "Modal Dialog Box" -msgstr "モーダルなダイアログ・ボックス" +#~ msgid "Move window to south (bottom) side of screen" +#~ msgstr "ウィンドウを画面の下側へ移動する" -#: ../src/ui/theme-viewer.c:402 -msgid "Utility Palette" -msgstr "ユーティリティ・パレット" +#~ msgid "Move window to east (right) side of screen" +#~ msgstr "ウィンドウを画面の右側へ移動する" -#: ../src/ui/theme-viewer.c:406 -msgid "Torn-off Menu" -msgstr "取り外したメニュー" +#~ msgid "Move window to west (left) side of screen" +#~ msgstr "ウィンドウを画面の左側へ移動する" -#: ../src/ui/theme-viewer.c:410 -msgid "Border" -msgstr "境界線" +#~ msgid "Move window to center of screen" +#~ msgstr "ウィンドウを画面の中央へ移動する" -#: ../src/ui/theme-viewer.c:414 -msgid "Attached Modal Dialog" -msgstr "埋め込んだモーダルなダイアログ" +#~ msgid "" +#~ "There was an error running <tt>%s</tt>:\n" +#~ "\n" +#~ "%s" +#~ msgstr "" +#~ "<tt>%s</tt>の動作中にエラーが発生しました:\n" +#~ "\n" +#~ "%s" -#: ../src/ui/theme-viewer.c:747 -#, c-format -msgid "Button layout test %d" -msgstr "ボタンの配置テスト %d" +#~ msgid "No command %d has been defined.\n" +#~ msgstr "コマンド %d は定義されていません。\n" -#: ../src/ui/theme-viewer.c:776 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "1個のウィンドウ・フレームの描画時間: %gミリ秒" +#~ msgid "No terminal command has been defined.\n" +#~ msgstr "端末を起動するコマンドが定義されていません。\n" -#: ../src/ui/theme-viewer.c:821 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "用法: metacity-theme-viewer [テーマ名]\n" +#~ msgid "GConf key '%s' is set to an invalid value\n" +#~ msgstr "GConf の '%s' キーには無効な値が格納されています\n" -#: ../src/ui/theme-viewer.c:828 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "テーマのロードでエラーが発生しました: %s\n" +#~ msgid "%d stored in GConf key %s is out of range %d to %d\n" +#~ msgstr "GConf の %2$s キーの値 %1$d は %3$d〜%4$d の範囲内にありません\n" -#: ../src/ui/theme-viewer.c:834 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "\"%s\" というテーマを%g秒で読み込みました\n" +#~ msgid "GConf key \"%s\" is set to an invalid type\n" +#~ msgstr "GConf の \"%s\" キーには無効な型が格納されています\n" -#: ../src/ui/theme-viewer.c:878 -msgid "Normal Title Font" -msgstr "標準的なフォントのタイトル" +#~ msgid "GConf key %s is already in use and can't be used to override %s\n" +#~ msgstr "GConf キーの %s は既に使用中なので %s をオーバーライドできません\n" -#: ../src/ui/theme-viewer.c:884 -msgid "Small Title Font" -msgstr "小さなフォントのタイトル" +#~ msgid "Can't override GConf key, %s not found\n" +#~ msgstr "GConf キーをオーバーライドできません (%s が見つかりませんでした)\n" -#: ../src/ui/theme-viewer.c:890 -msgid "Large Title Font" -msgstr "大きなフォントのタイトル" +#~ msgid "Error setting number of workspaces to %d: %s\n" +#~ msgstr "ワークスペース数を %d に設定中にエラーが発生しました: %s\n" -#: ../src/ui/theme-viewer.c:895 -msgid "Button Layouts" -msgstr "ボタンの配置" +#~ msgid "Error setting name for workspace %d to \"%s\": %s\n" +#~ msgstr "" +#~ "ワークスペース %d の名前を \"%s\" に設定するときにエラーが発生しました: " +#~ "%s\n" -#: ../src/ui/theme-viewer.c:900 -msgid "Benchmark" -msgstr "ベンチマーク" +#~ msgid "Error setting live hidden windows status status: %s\n" +#~ msgstr "" +#~ "表示されていないが動作中のウィンドウに対するステータスの設定エラー: %s\n" -#: ../src/ui/theme-viewer.c:952 -msgid "Window Title Goes Here" -msgstr "ここにウィンドウのタイトルが表示されます" +#~ msgid "Error setting no tab popup status: %s\n" +#~ msgstr "タブなしのポップアップステータスの設定エラー: %s\n" -#: ../src/ui/theme-viewer.c:1055 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"%d 個のフレームをクライアント側で%g秒 (1フレームにつき%gミリ秒)、実時間ではX" -"サーバーのリソースを含めて%g秒 (1フレームにつき %gミリ秒)で描画しました\n" +#~ msgid "Close Window" +#~ msgstr "ウィンドウを閉じます" -#: ../src/ui/theme-viewer.c:1274 -msgid "position expression test returned TRUE but set error" -msgstr "位置式テストはTRUEを返しましたがエラーがセットされています" +#~ msgid "Window Menu" +#~ msgstr "ウィンドウメニューを表示します" -#: ../src/ui/theme-viewer.c:1276 -msgid "position expression test returned FALSE but didn't set error" -msgstr "位置式テストはFALSEを返しましたがエラーをセットしていません" +#~ msgid "Minimize Window" +#~ msgstr "ウィンドウを最小化します" -#: ../src/ui/theme-viewer.c:1280 -msgid "Error was expected but none given" -msgstr "エラーが起きるはずですが何も起こりませんでした" +#~ msgid "Maximize Window" +#~ msgstr "ウィンドウを最大化します" -#: ../src/ui/theme-viewer.c:1282 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "エラー %d が起きるはずですが %d が起こりました" +#~ msgid "Restore Window" +#~ msgstr "ウィンドウの状態を元に戻します" -#: ../src/ui/theme-viewer.c:1288 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "エラーは起きないはずですが一つ発生しました: %s" +#~ msgid "Roll Up Window" +#~ msgstr "ウィンドウを巻き上げます" -#: ../src/ui/theme-viewer.c:1292 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "xの値が %d でした (期待値: %d)" +#~ msgid "Unroll Window" +#~ msgstr "ウィンドウの巻き上げを解除します" -#: ../src/ui/theme-viewer.c:1295 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "yの値は %d でした (期待値: %d)" +#~ msgid "Keep Window On Top" +#~ msgstr "ウィンドウを最前面に維持します" -#: ../src/ui/theme-viewer.c:1360 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "%d個の座標式を %g秒 (平均 %g秒) で解析しました\n" +#~ msgid "Always On Visible Workspace" +#~ msgstr "全てのワークスペースに配置します" + +#~ msgid "Put Window On Only One Workspace" +#~ msgstr "現在のワークスペースにのみ配置します" #~ msgid "Failed to retrieve color %s[%s] from GTK+ theme.\n" #~ msgstr "GTK+ のテーマから色を取得できませんでした: %s[%s]\n" diff --git a/po/ka.po b/po/ka.po index b4a8ac38b..2cc435c36 100644 --- a/po/ka.po +++ b/po/ka.po @@ -15,6 +15,7 @@ msgstr "" "PO-Revision-Date: 2007-09-07 14:18+0200\n" "Last-Translator: Vladimer Sichinava ვლადიმერ სიჭინავა <vsichi@gnome.org>\n" "Language-Team: Georgian <http://mail.gnome.org/mailman/listinfo/gnome-ge-list>\n" +"Language: ka\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" diff --git a/po/kk.po b/po/kk.po new file mode 100644 index 000000000..27d0fa6d4 --- /dev/null +++ b/po/kk.po @@ -0,0 +1,755 @@ +# Kazakh translation for mutter. +# Copyright (C) 2013 mutter's COPYRIGHT HOLDER +# This file is distributed under the same license as the mutter package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: mutter master\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2019-02-04 17:52+0000\n" +"PO-Revision-Date: 2019-02-17 12:39+0500\n" +"Last-Translator: Baurzhan Muftakhidinov <baurthefirst@gmail.com>\n" +"Language-Team: Kazakh <kk@li.org>\n" +"Language: kk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.2.1\n" + +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Навигация" + +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Терезені 1-ші жұмыс орнына жылжыту" + +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Терезені 2-ші жұмыс орнына жылжыту" + +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Терезені 3-ші жұмыс орнына жылжыту" + +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Терезені 4-ші жұмыс орнына жылжыту" + +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Терезені соңғы жұмыс орнына жылжыту" + +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "Терезені бір жұмыс орнына жоғары жылжыту" + +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "Терезені бір жұмыс орнына төмен жылжыту" + +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "Терезені бір мониторға солға жылжыту" + +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "Терезені бір мониторға оңға жылжыту" + +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "Терезені бір мониторға жоғары жылжыту" + +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "Терезені бір мониторға төмен жылжыту" + +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "Қолданбаларды ауыстыру" + +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "Алдыңғы қолданбаға ауысу" + +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "Терезелерді ауыстыру" + +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "Алдыңғы терезеге ауысу" + +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "Қолданба терезелерін ауыстыру" + +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "Қолданбаның алдыңғы терезесіне ауысу" + +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "Жүйелік басқару элементтерін ауыстыру" + +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "Алдыңғы жүйелік басқару элементіне ауысу" + +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "Терезелерді тікелей ауыстыру" + +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "Тікелей алдыңғы терезеге ауысу" + +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "Қолданба терезелерін тікелей ауыстыру" + +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "Тікелей қолданбаның алдыңғы терезесіне ауысу" + +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "Жүйелік басқару элементтерін тікелей ауыстыру" + +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "Тікелей алдыңғы жүйелік басқару элементіне ауысу" + +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "Барлық қалыпты терезелерді жасыру" + +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "1-ші жұмыс орнына ауысу" + +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "2-ші жұмыс орнына ауысу" + +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "3-ші жұмыс орнына ауысу" + +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "4-ші жұмыс орнына ауысу" + +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "Соңғы жұмыс орнына ауысу" + +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "Жоғарыдағы жұмыс орнына ауысу" + +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "Төмендегі жұмыс орнына ауысу" + +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "Жүйе" + +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Команданы жөнелту сұхбатын көрсету" + +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Шолуды көрсету" + +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Пернетақта жарлықтарын қалпына келтіру" + +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Терезелер" + +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "Терезе мәзірін белсендіру" + +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Толық экран режимін ауыстыру" + +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "Жазық күйін ауыстыру" + +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "Терезені жазық қылу" + +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Терезені қалпына келтіру" + +#: data/50-mutter-windows.xml:18 +msgid "Close window" +msgstr "Терезені жабу" + +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "Терезені жасыру" + +#: data/50-mutter-windows.xml:22 +msgid "Move window" +msgstr "Терезені жылжыту" + +#: data/50-mutter-windows.xml:24 +msgid "Resize window" +msgstr "Терезе өлшемдерін өзгерту" + +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "Терезені барлық жұмыс орындарында көрсетуді іске қосу/сөндіру" + +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "" +"Терезе басқалармен үстінен жабылған болса, алдына көтеру, болмаса, " +"басқалардың артына апару" + +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "Терезені басқа терезелердің алдына көтеру" + +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "Терезені басқа терезелердің артына апару" + +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "Терезені вертикалды жазық қылу" + +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "Терезені горизонталды жазық қылу" + +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "" + +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "" + +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" + +#: data/org.gnome.mutter.gschema.xml.in:7 +msgid "Modifier to use for extended window management operations" +msgstr "" + +#: data/org.gnome.mutter.gschema.xml.in:8 +msgid "" +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." +msgstr "" + +#: data/org.gnome.mutter.gschema.xml.in:20 +msgid "Attach modal dialogs" +msgstr "" + +#: data/org.gnome.mutter.gschema.xml.in:21 +msgid "" +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." +msgstr "" + +#: data/org.gnome.mutter.gschema.xml.in:30 +msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "" +"Терезелерді экран шеттеріне апарған кезде олардың өлшемдерін өзгертуді іске " +"қосу" + +#: data/org.gnome.mutter.gschema.xml.in:31 +msgid "" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." +msgstr "" + +#: data/org.gnome.mutter.gschema.xml.in:40 +msgid "Workspaces are managed dynamically" +msgstr "Жұмыс орындары динамикалы түрде басқарылады" + +#: data/org.gnome.mutter.gschema.xml.in:41 +msgid "" +"Determines whether workspaces are managed dynamically or whether there’s a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." +msgstr "" + +#: data/org.gnome.mutter.gschema.xml.in:50 +msgid "Workspaces only on primary" +msgstr "" + +#: data/org.gnome.mutter.gschema.xml.in:51 +msgid "" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." +msgstr "" + +#: data/org.gnome.mutter.gschema.xml.in:59 +msgid "No tab popup" +msgstr "" + +#: data/org.gnome.mutter.gschema.xml.in:60 +msgid "" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." +msgstr "" + +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "" + +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" + +#: data/org.gnome.mutter.gschema.xml.in:79 +msgid "Draggable border width" +msgstr "" + +#: data/org.gnome.mutter.gschema.xml.in:80 +msgid "" +"The amount of total draggable borders. If the theme’s visible borders are " +"not enough, invisible borders will be added to meet this value." +msgstr "" + +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "" + +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" + +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "" + +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" + +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "" + +#: data/org.gnome.mutter.gschema.xml.in:108 +msgid "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart." +msgstr "" + +#: data/org.gnome.mutter.gschema.xml.in:141 +msgid "Select window from tab popup" +msgstr "" + +#: data/org.gnome.mutter.gschema.xml.in:146 +msgid "Cancel tab popup" +msgstr "" + +#: data/org.gnome.mutter.gschema.xml.in:151 +msgid "Switch monitor configurations" +msgstr "Монитор баптауларын ауыстыру" + +#: data/org.gnome.mutter.gschema.xml.in:156 +msgid "Rotates the built-in monitor configuration" +msgstr "" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Бірінші виртуалды терминалына ауысу" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Екінші виртуалды терминалына ауысу" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Үшінші виртуалды терминалына ауысу" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Төртінші виртуалды терминалына ауысу" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Бесінші виртуалды терминалына ауысу" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Алтыншы виртуалды терминалына ауысу" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Жетінші виртуалды терминалына ауысу" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Сегізінші виртуалды терминалына ауысу" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Тоғызыншы виртуалды терминалына ауысу" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Оныншы виртуалды терминалына ауысу" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Он бірінші виртуалды терминалына ауысу" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Он екінші виртуалды терминалына ауысу" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow grabs with Xwayland" +msgstr "" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 +msgid "" +"Allow keyboard grabs issued by X11 applications running in Xwayland to be " +"taken into account. For a X11 grab to be taken into account under Wayland, " +"the client must also either send a specific X11 ClientMessage to the root " +"window or be among the applications white-listed in key “xwayland-grab-" +"access-rules”." +msgstr "" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:77 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:78 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "" + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. +#. +#: src/backends/meta-input-settings.c:2423 +#, c-format +msgid "Mode Switch (Group %d)" +msgstr "" + +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2446 +msgid "Switch monitor" +msgstr "Мониторды ауыстыру" + +#: src/backends/meta-input-settings.c:2448 +msgid "Show on-screen help" +msgstr "Экрандағы көмекті көрсету" + +#: src/backends/meta-monitor-manager.c:954 +msgid "Built-in display" +msgstr "Құрамындағы экран" + +#: src/backends/meta-monitor-manager.c:986 +msgid "Unknown" +msgstr "Белгісіз" + +#: src/backends/meta-monitor-manager.c:988 +msgid "Unknown Display" +msgstr "Белгісіз дисплей" + +#: src/backends/meta-monitor-manager.c:996 +#, c-format +#| msgid "%s %s" +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" + +#: src/backends/meta-monitor-manager.c:1004 +#, c-format +#| msgid "%s %s" +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" + +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:482 +#, c-format +msgid "" +"Another compositing manager is already running on screen %i on display “%s”." +msgstr "" + +#: src/core/bell.c:252 +msgid "Bell event" +msgstr "" + +#: src/core/main.c:185 +msgid "Disable connection to session manager" +msgstr "Сессиялар менеджеріне байланыстарды сөндіру" + +#: src/core/main.c:191 +msgid "Replace the running window manager" +msgstr "" + +#: src/core/main.c:197 +msgid "Specify session management ID" +msgstr "Сессия менеджментінің ID-ін көрсету" + +#: src/core/main.c:202 +msgid "X Display to use" +msgstr "Қолданылатын X дисплейі" + +#: src/core/main.c:208 +msgid "Initialize session from savefile" +msgstr "" + +#: src/core/main.c:214 +msgid "Make X calls synchronous" +msgstr "X сервер шақыруларын синхронды қылу" + +#: src/core/main.c:221 +msgid "Run as a wayland compositor" +msgstr "" + +#: src/core/main.c:227 +msgid "Run as a nested compositor" +msgstr "" + +#: src/core/main.c:233 +msgid "Run wayland compositor without starting Xwayland" +msgstr "" + +#: src/core/main.c:241 +msgid "Run as a full display server, rather than nested" +msgstr "" + +#: src/core/main.c:247 +msgid "Run with X11 backend" +msgstr "" + +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:150 +#, c-format +msgid "“%s” is not responding." +msgstr "“%s” жауап бермейді." + +#: src/core/meta-close-dialog-default.c:152 +msgid "Application is not responding." +msgstr "Қолданба жауап бермейді." + +#: src/core/meta-close-dialog-default.c:157 +msgid "" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." +msgstr "" +"Сіз қолданба өз жұмысын жалғастырғанды күтіп, немесе оны мәжбүрлетіп жаба " +"аласыз." + +#: src/core/meta-close-dialog-default.c:164 +msgid "_Force Quit" +msgstr "_Мәжбүрлі шығу" + +#: src/core/meta-close-dialog-default.c:164 +msgid "_Wait" +msgstr "_Күту" + +#: src/core/mutter.c:38 +#, c-format +msgid "" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" +msgstr "" + +#: src/core/mutter.c:52 +msgid "Print version" +msgstr "Нұсқа ақпаратын шығару" + +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "" + +#: src/core/prefs.c:1786 +#, c-format +msgid "Workspace %d" +msgstr "Жұмыс орны %d" + +#: src/core/util.c:121 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "" + +#: src/wayland/meta-wayland-tablet-pad.c:567 +#, c-format +msgid "Mode Switch: Mode %d" +msgstr "" + +#: src/x11/meta-x11-display.c:666 +#, c-format +msgid "" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." +msgstr "" + +#: src/x11/meta-x11-display.c:1008 +msgid "Failed to initialize GDK\n" +msgstr "" + +#: src/x11/meta-x11-display.c:1032 +#, c-format +msgid "Failed to open X Window System display “%s”\n" +msgstr "" + +#: src/x11/meta-x11-display.c:1115 +#, c-format +msgid "Screen %d on display “%s” is invalid\n" +msgstr "" + +#: src/x11/session.c:1821 +msgid "" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." +msgstr "" + +#: src/x11/window-props.c:568 +#, c-format +msgid "%s (on %s)" +msgstr "%s (%s жерінде)" + +#~ msgid "Move window one workspace to the left" +#~ msgstr "Терезені бір жұмыс орнына солға жылжыту" + +#~ msgid "Move window one workspace to the right" +#~ msgstr "Терезені бір жұмыс орнына оңға жылжыту" + +#~ msgid "Move to workspace left" +#~ msgstr "Сол жақтағы жұмыс орнына ауысу" + +#~ msgid "Move to workspace right" +#~ msgstr "Оң жақтағы жұмыс орнына ауысу" + +#~ msgid "Toggle shaded state" +#~ msgstr "Көлеңкелі күйін ауыстыру" + +#~ msgid "Window manager: " +#~ msgstr "Терезелер басқарушысы:" + +#~ msgid "Mi_nimize" +#~ msgstr "Қа_йыру" + +#~ msgid "Ma_ximize" +#~ msgstr "Ж_азық қылу" + +#~ msgid "Unma_ximize" +#~ msgstr "Жа_зық емес қылу" + +#~ msgid "Roll _Up" +#~ msgstr "Атауға ж_инау" + +#~ msgid "_Unroll" +#~ msgstr "Жи_наудан қайтару" + +#~ msgid "_Move" +#~ msgstr "Жы_лжыту" + +#~ msgid "_Resize" +#~ msgstr "Ө_лшемін өзгерту" + +#~ msgid "Always on _Top" +#~ msgstr "Әрқа_шан үстінде" + +#~ msgid "_Always on Visible Workspace" +#~ msgstr "Әрқашан кө_рініп тұрған жұмыс орнында" + +#~ msgid "_Only on This Workspace" +#~ msgstr "Тек ос_ы жұмыс орнында" + +#~ msgid "Move to Workspace _Left" +#~ msgstr "_Сол жақтағы жұмыс орнына ауыстыру" + +#~ msgid "Move to Workspace R_ight" +#~ msgstr "Оң _жақтағы жұмыс орнына ауыстыру" + +#~ msgid "Move to Workspace _Up" +#~ msgstr "Жоға_рыдағы жұмыс орнына ауыстыру" + +#~ msgid "Move to Workspace _Down" +#~ msgstr "Тө_мендегі жұмыс орнына ауыстыру" + +#~ msgid "_Close" +#~ msgstr "Жа_бу" + +#~ msgid "Workspace %d%n" +#~ msgstr "Жұмыс орны %d%n" + +#~ msgid "Workspace 1_0" +#~ msgstr "Жұмыс орны 1_0" + +#~ msgid "Workspace %s%d" +#~ msgstr "Жұмыс орны %s%d" + +#~ msgid "Move to Another _Workspace" +#~ msgstr "Басқа жұмыс орнына ж_ылжыту" + +#~ msgid "Shift" +#~ msgstr "Shift" + +#~ msgid "Ctrl" +#~ msgstr "Ctrl" + +#~ msgid "Alt" +#~ msgstr "Alt" + +#~ msgid "Meta" +#~ msgstr "Meta" + +#~ msgid "%d x %d" +#~ msgstr "%d x %d" diff --git a/po/kn.po b/po/kn.po index f827a7091..19e87f5ac 100644 --- a/po/kn.po +++ b/po/kn.po @@ -2,1287 +2,952 @@ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # -# Shankar Prasad <svenkate@redhat.com>, 2008, 2011. +# Shankar Prasad <svenkate@redhat.com>, 2008, 2011, 2012, 2013, 2014. msgid "" msgstr "" "Project-Id-Version: metacity.HEAD\n" -"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug." -"cgi?product=muffin&keywords=I18N+L10N&component=general\n" -"POT-Creation-Date: 2011-03-21 19:31+0000\n" -"PO-Revision-Date: 2011-04-02 20:59+0530\n" -"Last-Translator: Shankar Prasad <svenkate@redhat.com>\n" -"Language-Team: Kannada <en@li.org>\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=mutter&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2014-09-02 09:56+0000\n" +"PO-Revision-Date: 2014-09-22 10:44+0530\n" +"Last-Translator: Shankar Prasad <svenkate AT redhat Dot com>\n" +"Language-Team: Kannada <kde-i18n-doc@kde.org>\n" +"Language: kn\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Lokalize 1.1\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 1.5\n" -#: ../src/core/all-keybindings.h:88 -msgid "Switch to workspace 1" -msgstr "ಕಾರ್ಯಕ್ಷೇತ್ರ 1 ಕ್ಕೆ ಬದಲಾಯಿಸು" - -#: ../src/core/all-keybindings.h:90 -msgid "Switch to workspace 2" -msgstr "ಕಾರ್ಯಕ್ಷೇತ್ರ 2 ಕ್ಕೆ ಬದಲಾಯಿಸು" - -#: ../src/core/all-keybindings.h:92 -msgid "Switch to workspace 3" -msgstr "ಕಾರ್ಯಕ್ಷೇತ್ರ 3 ಕ್ಕೆ ಬದಲಾಯಿಸು" +#: ../data/50-mutter-navigation.xml.in.h:1 +msgid "Navigation" +msgstr "ನೇವಿಗೇಶನ್" -#: ../src/core/all-keybindings.h:94 -msgid "Switch to workspace 4" -msgstr "ಕಾರ್ಯಕ್ಷೇತ್ರ 4 ಕ್ಕೆ ಬದಲಾಯಿಸು" - -#: ../src/core/all-keybindings.h:96 -msgid "Switch to workspace 5" -msgstr "ಕಾರ್ಯಕ್ಷೇತ್ರ 5 ಕ್ಕೆ ಬದಲಾಯಿಸು" - -#: ../src/core/all-keybindings.h:98 -msgid "Switch to workspace 6" -msgstr "ಕಾರ್ಯಕ್ಷೇತ್ರ 6 ಕ್ಕೆ ಬದಲಾಯಿಸು" +#: ../data/50-mutter-navigation.xml.in.h:2 +msgid "Move window to workspace 1" +msgstr "ಕಿಟಕಿಯನ್ನು ಕಾರ್ಯಕ್ಷೇತ್ರ 1 ಕ್ಕೆ ಸ್ಥಳಾಂತರಿಸು" -#: ../src/core/all-keybindings.h:100 -msgid "Switch to workspace 7" -msgstr "ಕಾರ್ಯಕ್ಷೇತ್ರ 7 ಕ್ಕೆ ಬದಲಾಯಿಸು" +#: ../data/50-mutter-navigation.xml.in.h:3 +msgid "Move window to workspace 2" +msgstr "ಕಿಟಕಿಯನ್ನು ಕಾರ್ಯಕ್ಷೇತ್ರ 2 ಕ್ಕೆ ಸ್ಥಳಾಂತರಿಸು" -#: ../src/core/all-keybindings.h:102 -msgid "Switch to workspace 8" -msgstr "ಕಾರ್ಯಕ್ಷೇತ್ರ 8 ಕ್ಕೆ ಬದಲಾಯಿಸು" +#: ../data/50-mutter-navigation.xml.in.h:4 +msgid "Move window to workspace 3" +msgstr "ಕಿಟಕಿಯನ್ನು ಕಾರ್ಯಕ್ಷೇತ್ರ 3 ಕ್ಕೆ ಸ್ಥಳಾಂತರಿಸು" -#: ../src/core/all-keybindings.h:104 -msgid "Switch to workspace 9" -msgstr "ಕಾರ್ಯಕ್ಷೇತ್ರ 9 ಕ್ಕೆ ಬದಲಾಯಿಸು" +#: ../data/50-mutter-navigation.xml.in.h:5 +msgid "Move window to workspace 4" +msgstr "ಕಿಟಕಿಯನ್ನು ಕಾರ್ಯಕ್ಷೇತ್ರ 4 ಕ್ಕೆ ಸ್ಥಳಾಂತರಿಸು" -#: ../src/core/all-keybindings.h:106 -msgid "Switch to workspace 10" -msgstr "ಕಾರ್ಯಕ್ಷೇತ್ರ 10 ಕ್ಕೆ ಬದಲಾಯಿಸು" +#: ../data/50-mutter-navigation.xml.in.h:6 +#| msgid "Move window to workspace 1" +msgid "Move window to last workspace" +msgstr "ಕಿಟಕಿಯನ್ನು ಕೊನೆಯ ಕಾರ್ಯಕ್ಷೇತ್ರಕ್ಕೆ ಸ್ಥಳಾಂತರಿಸು" -#: ../src/core/all-keybindings.h:108 -msgid "Switch to workspace 11" -msgstr "ಕಾರ್ಯಕ್ಷೇತ್ರ 11 ಕ್ಕೆ ಬದಲಾಯಿಸು" +#: ../data/50-mutter-navigation.xml.in.h:7 +msgid "Move window one workspace to the left" +msgstr "ಕಿಟಕಿಯನ್ನು ಒಂದು ಕಾರ್ಯಕ್ಷೇತ್ರದ ಎಡಕ್ಕೆ ಜರುಗಿಸು" -#: ../src/core/all-keybindings.h:110 -msgid "Switch to workspace 12" -msgstr "ಕಾರ್ಯಕ್ಷೇತ್ರ 12 ಕ್ಕೆ ಬದಲಾಯಿಸು" +#: ../data/50-mutter-navigation.xml.in.h:8 +msgid "Move window one workspace to the right" +msgstr "ಕಿಟಕಿಯನ್ನು ಒಂದು ಕಾರ್ಯಕ್ಷೇತ್ರದ ಬಲಕ್ಕೆ ಜರುಗಿಸು" -#: ../src/core/all-keybindings.h:122 -#| msgid "Switch to workspace on the left" -msgid "Switch to workspace on the left of the current workspace" -msgstr "ಪ್ರಸಕ್ತ ಕಾರ್ಯಕ್ಷೇತ್ರದ ಎಡಭಾಗದಲ್ಲಿನ ಕಾರ್ಯಕ್ಷೇತ್ರಕ್ಕೆ ವರ್ಗಾಯಿಸು" +#: ../data/50-mutter-navigation.xml.in.h:9 +msgid "Move window one workspace up" +msgstr "ಕಿಟಕಿಯನ್ನು ಒಂದು ಕಾರ್ಯಕ್ಷೇತ್ರದ ಮೇಲಕ್ಕೆ ಜರುಗಿಸು" -#: ../src/core/all-keybindings.h:126 -#| msgid "Switch to workspace on the right" -msgid "Switch to workspace on the right of the current workspace" -msgstr "ಪ್ರಸಕ್ತ ಕಾರ್ಯಕ್ಷೇತ್ರದ ಬಲಭಾಗದಲ್ಲಿನ ಕಾರ್ಯಕ್ಷೇತ್ರಕ್ಕೆ ವರ್ಗಾಯಿಸು" +#: ../data/50-mutter-navigation.xml.in.h:10 +msgid "Move window one workspace down" +msgstr "ಕಿಟಕಿಯನ್ನು ಒಂದು ಕಾರ್ಯಕ್ಷೇತ್ರದ ಕೆಳಗೆ ಜರುಗಿಸು" + +#: ../data/50-mutter-navigation.xml.in.h:11 +#| msgid "Move window one workspace to the left" +msgid "Move window one monitor to the left" +msgstr "ಕಿಟಕಿಯನ್ನು ಒಂದು ಪರದೆ ಎಡಕ್ಕೆ ಜರುಗಿಸು" + +#: ../data/50-mutter-navigation.xml.in.h:12 +#| msgid "Move window one workspace to the right" +msgid "Move window one monitor to the right" +msgstr "ಕಿಟಕಿಯನ್ನು ಒಂದು ಪರದೆ ಬಲಕ್ಕೆ ಜರುಗಿಸು" + +#: ../data/50-mutter-navigation.xml.in.h:13 +#| msgid "Move window one workspace up" +msgid "Move window one monitor up" +msgstr "ಕಿಟಕಿಯನ್ನು ಒಂದು ಪರದೆ ಮೇಲಕ್ಕೆ ಜರುಗಿಸು" + +#: ../data/50-mutter-navigation.xml.in.h:14 +#| msgid "Move window one workspace down" +msgid "Move window one monitor down" +msgstr "ಕಿಟಕಿಯನ್ನು ಒಂದು ಪರದೆ ಕೆಳಕ್ಕೆ ಜರುಗಿಸು" + +#: ../data/50-mutter-navigation.xml.in.h:15 +msgid "Switch applications" +msgstr "ಅನ್ವಯಗಳನ್ನು ಬದಲಿಸು" + +#: ../data/50-mutter-navigation.xml.in.h:16 +#| msgid "Switch applications" +msgid "Switch to previous application" +msgstr "ಹಿಂದಿನ ಅನ್ವಯಕ್ಕೆ ಬದಲಿಸು" + +#: ../data/50-mutter-navigation.xml.in.h:17 +msgid "Switch windows" +msgstr "ಕಿಟಕಿಗಳನ್ನು ಬದಲಿಸು" + +#: ../data/50-mutter-navigation.xml.in.h:18 +#| msgid "Switch windows" +msgid "Switch to previous window" +msgstr "ಹಿಂದಿನ ಕಿಟಕಿಗೆ ಬದಲಿಸು" + +#: ../data/50-mutter-navigation.xml.in.h:19 +msgid "Switch windows of an application" +msgstr "ಒಂದು ಅನ್ವಯದ ಕಿಟಕಿಗಳನ್ನು ಬದಲಾಯಿಸು" + +#: ../data/50-mutter-navigation.xml.in.h:20 +#| msgid "Switch windows of an application" +msgid "Switch to previous window of an application" +msgstr "ಒಂದು ಅನ್ವಯದ ಹಿಂದಿನ ಕಿಟಕಿಗೆ ಬದಲಾಯಿಸು" + +#: ../data/50-mutter-navigation.xml.in.h:21 +msgid "Switch system controls" +msgstr "ವ್ಯವಸ್ಥೆಯ ನಿಯಂತ್ರಣಗಳನ್ನು ಬದಲಾಯಿಸು" + +#: ../data/50-mutter-navigation.xml.in.h:22 +#| msgid "Switch system controls" +msgid "Switch to previous system control" +msgstr "ಹಿಂದಿನ ವ್ಯವಸ್ಥೆಯ ನಿಯಂತ್ರಣಗಳಿಗೆ ಬದಲಾಯಿಸು" + +#: ../data/50-mutter-navigation.xml.in.h:23 +msgid "Switch windows directly" +msgstr "ಕಿಟಿಕಿಗಳನ್ನು ನೇರವಾಗಿ ಬದಲಾಯಿಸು" + +#: ../data/50-mutter-navigation.xml.in.h:24 +msgid "Switch directly to previous window" +msgstr "ಹಿಂದಿನ ಕಿಟಕಿಗೆ ನೇರವಾಗಿ ಬದಲಾಯಿಸು" + +#: ../data/50-mutter-navigation.xml.in.h:25 +msgid "Switch windows of an app directly" +msgstr "ಒಂದು ಅನ್ವಯದ ಕಿಟಕಿಗಳನ್ನು ನೇರವಾಗಿ ಬದಲಾಯಿಸು" + +#: ../data/50-mutter-navigation.xml.in.h:26 +#| msgid "Switch windows of an application" +msgid "Switch directly to previous window of an app" +msgstr "ಒಂದು ಅನ್ವಯದ ಹಿಂದಿನ ಕಿಟಕಿಗೆ ನೇರವಾಗಿ ಬದಲಾಯಿಸು" + +#: ../data/50-mutter-navigation.xml.in.h:27 +msgid "Switch system controls directly" +msgstr "ವ್ಯವಸ್ಥೆಯ ನಿಯಂತ್ರಣಗಳನ್ನು ನೇರವಾಗಿ ಬದಲಾಯಿಸು" + +#: ../data/50-mutter-navigation.xml.in.h:28 +#| msgid "Switch system controls" +msgid "Switch directly to previous system control" +msgstr "ನೇರವಾಗಿ ಹಿಂದಿನ ವ್ಯವಸ್ಥೆಯ ನಿಯಂತ್ರಣಗಳಿಗೆ ಬದಲಾಯಿಸು" + +#: ../data/50-mutter-navigation.xml.in.h:29 +msgid "Hide all normal windows" +msgstr "ಎಲ್ಲಾ ಸಾಮಾನ್ಯ ಕಿಟಕಿಗಳನ್ನು ಅಡಗಿಸು" + +#: ../data/50-mutter-navigation.xml.in.h:30 +msgid "Switch to workspace 1" +msgstr "ಕಾರ್ಯಕ್ಷೇತ್ರ 1 ಕ್ಕೆ ಬದಲಾಯಿಸು" -#: ../src/core/all-keybindings.h:130 -#| msgid "Switch to workspace above this one" -msgid "Switch to workspace above the current workspace" -msgstr "ಪ್ರಸಕ್ತ ಕಾರ್ಯಕ್ಷೇತ್ರದ ಮೇಲ್ಭಾಗದಲ್ಲಿನ ಕಾರ್ಯಕ್ಷೇತ್ರಕ್ಕೆ ವರ್ಗಾಯಿಸು" +#: ../data/50-mutter-navigation.xml.in.h:31 +msgid "Switch to workspace 2" +msgstr "ಕಾರ್ಯಕ್ಷೇತ್ರ 2 ಕ್ಕೆ ಬದಲಾಯಿಸು" -#: ../src/core/all-keybindings.h:134 -#| msgid "Switch to workspace below this one" -msgid "Switch to workspace below the current workspace" -msgstr "ಪ್ರಸಕ್ತ ಕಾರ್ಯಕ್ಷೇತ್ರದ ಕೆಳಭಾಗದಲ್ಲಿನ ಕಾರ್ಯಕ್ಷೇತ್ರಕ್ಕೆ ವರ್ಗಾಯಿಸು" +#: ../data/50-mutter-navigation.xml.in.h:32 +msgid "Switch to workspace 3" +msgstr "ಕಾರ್ಯಕ್ಷೇತ್ರ 3 ಕ್ಕೆ ಬದಲಾಯಿಸು" -#: ../src/core/all-keybindings.h:150 -msgid "Move between windows of an application, using a popup window" -msgstr "ಪುಟಿಕೆ (ಪಾಪ್ಅಪ್) ವಿಂಡೊವನ್ನು ಬಳಸಿಕೊಂಡು ಒಂದು ಅನ್ವಯದ ವಿಂಡೋಗಳ ನಡುವೆ ಸ್ಥಳಾಂತರಿಸು" +#: ../data/50-mutter-navigation.xml.in.h:33 +msgid "Switch to workspace 4" +msgstr "ಕಾರ್ಯಕ್ಷೇತ್ರ 4 ಕ್ಕೆ ಬದಲಾಯಿಸು" -#: ../src/core/all-keybindings.h:153 -msgid "Move backward between windows of an application, using a popup window" -msgstr "" -"ಪುಟಿಕೆ (ಪಾಪ್ಅಪ್) ವಿಂಡೊವನ್ನು ಬಳಸಿಕೊಂಡು ಒಂದು ಅನ್ವಯದ ವಿಂಡೋಗಳ ನಡುವೆ ಹಿಂದಕ್ಕೆ ಸ್ಥಳಾಂತರಿಸು" +#: ../data/50-mutter-navigation.xml.in.h:34 +#| msgid "Switch to workspace 1" +msgid "Switch to last workspace" +msgstr "ಕೊನೆಯ ಕಾರ್ಯಕ್ಷೇತ್ರಕ್ಕೆ ಬದಲಾಯಿಸು" -#: ../src/core/all-keybindings.h:157 -#| msgid "Move between windows of an application immediately" -msgid "Move between windows, using a popup window" -msgstr "ಪುಟಿಕೆ (ಪಾಪ್ಅಪ್) ವಿಂಡೊವನ್ನು ಬಳಸಿಕೊಂಡು ವಿಂಡೋಗಳ ನಡುವೆ ಸ್ಥಳಾಂತರಿಸು" +#: ../data/50-mutter-navigation.xml.in.h:35 +msgid "Move to workspace left" +msgstr "ಎಡಭಾಗದ ಕಾರ್ಯಕ್ಷೇತ್ರಕ್ಕೆ ವರ್ಗಾಯಿಸು" -#: ../src/core/all-keybindings.h:160 -msgid "Move backward between windows, using a popup window" -msgstr "ಪುಟಿಕೆ (ಪಾಪ್ಅಪ್) ವಿಂಡೊವನ್ನು ಬಳಸಿಕೊಂಡು ವಿಂಡೋಗಳ ನಡುವೆ ಹಿಂದಕ್ಕೆ ಸ್ಥಳಾಂತರಿಸು" +#: ../data/50-mutter-navigation.xml.in.h:36 +msgid "Move to workspace right" +msgstr "ಬಲಭಾಗದ ಕಾರ್ಯಕ್ಷೇತ್ರಕ್ಕೆ ವರ್ಗಾಯಿಸು" -#: ../src/core/all-keybindings.h:163 -msgid "Move between panels and the desktop, using a popup window" -msgstr "ಪುಟಿಕೆ (ಪಾಪ್ಅಪ್) ವಿಂಡೊವನ್ನು ಬಳಸಿಕೊಂಡು ಫಲಕಗಳು ಹಾಗು ಗಣಕತೆರೆಯ ನಡುವೆ ಸ್ಥಳಾಂತರಿಸು" +#: ../data/50-mutter-navigation.xml.in.h:37 +msgid "Move to workspace above" +msgstr "ಮೇಲ್ಭಾಗದ ಕಾರ್ಯಕ್ಷೇತ್ರಕ್ಕೆ ವರ್ಗಾಯಿಸು" -#: ../src/core/all-keybindings.h:166 -msgid "Move backward between panels and the desktop, using a popup window" -msgstr "" -"ಪುಟಿಕೆ (ಪಾಪ್ಅಪ್) ವಿಂಡೊವನ್ನು ಬಳಸಿಕೊಂಡು ಫಲಕಗಳು ಹಾಗು ಗಣಕತೆರೆಯ ನಡುವೆ ಹಿಂದಕ್ಕೆ " -"ಸ್ಥಳಾಂತರಿಸು" - -#: ../src/core/all-keybindings.h:171 -msgid "Move between windows of an application immediately" -msgstr "ಒಂದು ಅನ್ವಯದ ವಿಂಡೋಗಳ ನಡುವೆ ತಕ್ಷಣ ಜರುಗಿಸು" - -#: ../src/core/all-keybindings.h:174 -#| msgid "Move between windows of an application immediately" -msgid "Move backward between windows of an application immediately" -msgstr "ಒಂದು ಅನ್ವಯದ ವಿಂಡೋಗಳ ನಡುವೆ ತಕ್ಷಣ ಹಿಂದಕ್ಕೆ ಜರುಗಿಸು" - -#: ../src/core/all-keybindings.h:177 -msgid "Move between windows immediately" -msgstr "ವಿಂಡೋಗಳ ನಡುವೆ ತಕ್ಷಣ ಜರುಗಿಸು" - -#: ../src/core/all-keybindings.h:180 -#| msgid "Move backwards between windows immediately" -msgid "Move backward between windows immediately" -msgstr "ವಿಂಡೋಗಳ ನಡುವೆ ತಕ್ಷಣ ಹಿಂದಕ್ಕೆ ಜರುಗಿಸು" - -#: ../src/core/all-keybindings.h:183 -msgid "Move between panels and the desktop immediately" -msgstr "ಫಲಕ ಹಾಗು ಗಣಕತೆರೆಗಳ ನಡುವೆ ತಕ್ಷಣ ಜರುಗಿಸು" - -#: ../src/core/all-keybindings.h:186 -msgid "Move backward between panels and the desktop immediately" -msgstr "ಫಲಕ ಹಾಗು ಗಣಕತೆರೆಗಳ ನಡುವೆ ತಕ್ಷಣ ಹಿಂದಕ್ಕೆ ಜರುಗಿಸು" - -#: ../src/core/all-keybindings.h:203 -msgid "Hide all normal windows and set focus to the desktop" -msgstr "ಎಲ್ಲಾ ಸಾಮಾನ್ಯ ವಿಂಡೊಗಳನ್ನು ಅಡಗಿಸು ಹಾಗು ಗಣಕತೆರೆಯ ಮೇಲೆ ಗಮನವನ್ನು ಕೇಂದ್ರೀಕರಿಸು" - -#: ../src/core/all-keybindings.h:206 -#| msgid "Show the panel menu" -msgid "Show the panel's main menu" -msgstr "ಫಲಕದ ಮುಖ್ಯ ಮೆನುವನ್ನು ತೋರಿಸು" - -#: ../src/core/all-keybindings.h:209 -msgid "Show the panel's \"Run Application\" dialog box" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:38 +msgid "Move to workspace below" +msgstr "ಕೆಳಗಿನ ಕಾರ್ಯಕ್ಷೇತ್ರಕ್ಕೆ ವರ್ಗಾಯಿಸು" -#: ../src/core/all-keybindings.h:211 -msgid "Start or stop recording the session" -msgstr "ಅಧಿವೇಶನವನ್ನು ರೆಕಾರ್ಡಿಂಗ್ ಮಾಡುವುದನ್ನು ಆರಂಭಿಸು ಅಥವ ನಿಲ್ಲಿಸು" +#: ../data/50-mutter-system.xml.in.h:1 +msgid "System" +msgstr "ವ್ಯವಸ್ಥೆ" -#: ../src/core/all-keybindings.h:252 -msgid "Take a screenshot" -msgstr "ಒಂದು ತೆರೆಚಿತ್ರವನ್ನು ತೆಗೆ" +#: ../data/50-mutter-system.xml.in.h:2 +msgid "Show the run command prompt" +msgstr "ಚಲಾಯಿಸುವ ಆದೇಶ ಪ್ರಾಂಪ್ಟನ್ನು ತೋರಿಸು" -#: ../src/core/all-keybindings.h:254 -msgid "Take a screenshot of a window" -msgstr "ಒಂದು ವಿಂಡೊದ ತೆರೆಚಿತ್ರವನ್ನು ತೆಗೆ" +#: ../data/50-mutter-system.xml.in.h:3 +msgid "Show the activities overview" +msgstr "ಚಟುವಟಿಕೆಗಳ ಅವಲೋಕನವನ್ನು ತೋರಿಸು" -#: ../src/core/all-keybindings.h:256 -msgid "Run a terminal" -msgstr "ಟರ್ಮಿನಲ್‍ನಲ್ಲಿ ಚಲಾಯಿಸು" +#: ../data/50-mutter-windows.xml.in.h:1 +msgid "Windows" +msgstr "ಕಿಟಕಿಗಳು" -#: ../src/core/all-keybindings.h:271 -#| msgid "Activate window menu" +#: ../data/50-mutter-windows.xml.in.h:2 msgid "Activate the window menu" -msgstr "ವಿಂಡೊ ಮೆನುವನ್ನು ಸಕ್ರಿಯಗೊಳಿಸು" +msgstr "ಕಿಟಕಿ ಮೆನುವನ್ನು ಸಕ್ರಿಯಗೊಳಿಸು" -#: ../src/core/all-keybindings.h:274 +#: ../data/50-mutter-windows.xml.in.h:3 msgid "Toggle fullscreen mode" msgstr "ಪೂರ್ಣತೆರೆಯ ಕ್ರಮಕ್ಕೆ ಟಾಗಲ್ ಮಾಡು" -#: ../src/core/all-keybindings.h:276 +#: ../data/50-mutter-windows.xml.in.h:4 msgid "Toggle maximization state" -msgstr "" +msgstr "ಗರಿಷ್ಟಗೊಳಿಸುವ ಸ್ಥಿತಿಯನ್ನು ಟಾಗಲ್ ಮಾಡು" -#: ../src/core/all-keybindings.h:278 -msgid "Toggle whether a window will always be visible over other windows" -msgstr "" - -#: ../src/core/all-keybindings.h:280 +#: ../data/50-mutter-windows.xml.in.h:5 msgid "Maximize window" -msgstr "ವಿಂಡೊವನು ಹಿಗ್ಗಿಸು" +msgstr "ಕಿಟಕಿಯನ್ನು ಹಿಗ್ಗಿಸು" -#: ../src/core/all-keybindings.h:282 -#| msgid "Resize window" +#: ../data/50-mutter-windows.xml.in.h:6 msgid "Restore window" -msgstr "ವಿಂಡೊವನ್ನು ಮರಳಿ ಸ್ಥಾಪಿಸು" +msgstr "ಕಿಟಕಿಯನ್ನು ಮರಳಿ ಸ್ಥಾಪಿಸು" -#: ../src/core/all-keybindings.h:284 +#: ../data/50-mutter-windows.xml.in.h:7 msgid "Toggle shaded state" -msgstr "" - -#: ../src/core/all-keybindings.h:286 -msgid "Minimize window" -msgstr "ವಿಂಡೊವನು ಕುಗ್ಗಿಸು" +msgstr "ನೆರಳಿನ ಸ್ಥಿತಿಯನ್ನು ಟಾಗಲ್‌ ಮಾಡು" -#: ../src/core/all-keybindings.h:288 +#: ../data/50-mutter-windows.xml.in.h:8 msgid "Close window" -msgstr "ವಿಂಡೊವನ್ನು ಮುಚ್ಚು" +msgstr "ಕಿಟಕಿಯನ್ನು ಮುಚ್ಚು" -#: ../src/core/all-keybindings.h:290 +#: ../data/50-mutter-windows.xml.in.h:9 +msgid "Hide window" +msgstr "ಕಿಟಕಿಯನ್ನು ಅಡಗಿಸು" + +#: ../data/50-mutter-windows.xml.in.h:10 msgid "Move window" -msgstr "ವಿಂಡೊವನ್ನು ಜರುಗಿಸು" +msgstr "ಕಿಟಕಿಯನ್ನು ಜರುಗಿಸು" -#: ../src/core/all-keybindings.h:292 +#: ../data/50-mutter-windows.xml.in.h:11 msgid "Resize window" -msgstr "ವಿಂಡೊವನ್ನು ಮರುಗಾತ್ರಿಸು" - -#: ../src/core/all-keybindings.h:295 -msgid "Toggle whether window is on all workspaces or just one" -msgstr "" +msgstr "ಕಿಟಕಿಯನ್ನು ಮರುಗಾತ್ರಿಸು" -#: ../src/core/all-keybindings.h:299 -msgid "Move window to workspace 1" -msgstr "ವಿಂಡೊವನ್ನು ಕಾರ್ಯಕ್ಷೇತ್ರ 1 ಕ್ಕೆ ಸ್ಥಳಾಂತರಿಸು" +#: ../data/50-mutter-windows.xml.in.h:12 +msgid "Toggle window on all workspaces or one" +msgstr "ಎಲ್ಲಾ ಕಾರ್ಯಸ್ಥಳಗಳಲ್ಲಿ ಅಥವ ಒಂದು ಕಿಟಕಿಯಲ್ಲಿ ಹೊರಳಿಸು" -#: ../src/core/all-keybindings.h:302 -msgid "Move window to workspace 2" -msgstr "ವಿಂಡೊವನ್ನು ಕಾರ್ಯಕ್ಷೇತ್ರ 2 ಕ್ಕೆ ಸ್ಥಳಾಂತರಿಸು" +#: ../data/50-mutter-windows.xml.in.h:13 +msgid "Raise window if covered, otherwise lower it" +msgstr "ಕಿಟಕಿಯನ್ನು ಆವರಿಸಲಾಗಿದ್ದರೆ ಎತ್ತರಿಸು, ಇಲ್ಲದೆ ಹೋದಲ್ಲಿ ಕೆಳಕ್ಕಿಳಿಸು" -#: ../src/core/all-keybindings.h:305 -msgid "Move window to workspace 3" -msgstr "ವಿಂಡೊವನ್ನು ಕಾರ್ಯಕ್ಷೇತ್ರ 3 ಕ್ಕೆ ಸ್ಥಳಾಂತರಿಸು" +#: ../data/50-mutter-windows.xml.in.h:14 +msgid "Raise window above other windows" +msgstr "ಕಿಟಕಿಯನ್ನು ಇತರೆ ಕಿಟಕಿಗಳಿಗಿಂತ ಎತ್ತರಿಸು" -#: ../src/core/all-keybindings.h:308 -msgid "Move window to workspace 4" -msgstr "ವಿಂಡೊವನ್ನು ಕಾರ್ಯಕ್ಷೇತ್ರ 4 ಕ್ಕೆ ಸ್ಥಳಾಂತರಿಸು" +#: ../data/50-mutter-windows.xml.in.h:15 +msgid "Lower window below other windows" +msgstr "ಇತರೆ ಕಿಟಕಿಗಳ ಅಡಿಯಲ್ಲಿರುವ ಕಿಟಕಿ" -#: ../src/core/all-keybindings.h:311 -msgid "Move window to workspace 5" -msgstr "ವಿಂಡೊವನ್ನು ಕಾರ್ಯಕ್ಷೇತ್ರ 5 ಕ್ಕೆ ಸ್ಥಳಾಂತರಿಸು" +#: ../data/50-mutter-windows.xml.in.h:16 +msgid "Maximize window vertically" +msgstr "ಕಿಟಕಿಯನ್ನು ಲಂಬವಾಗಿ ಹಿಗ್ಗಿಸು" -#: ../src/core/all-keybindings.h:314 -msgid "Move window to workspace 6" -msgstr "ವಿಂಡೊವನ್ನು ಕಾರ್ಯಕ್ಷೇತ್ರ 6 ಕ್ಕೆ ಸ್ಥಳಾಂತರಿಸು" +#: ../data/50-mutter-windows.xml.in.h:17 +msgid "Maximize window horizontally" +msgstr "ಕಿಟಕಿಯನ್ನು ಸಮತಲವಾಗಿ ಹಿಗ್ಗಿಸು" -#: ../src/core/all-keybindings.h:317 -msgid "Move window to workspace 7" -msgstr "ವಿಂಡೊವನ್ನು ಕಾರ್ಯಕ್ಷೇತ್ರ 7 ಕ್ಕೆ ಸ್ಥಳಾಂತರಿಸು" +#: ../data/50-mutter-windows.xml.in.h:18 +msgid "View split on left" +msgstr "ಎಡಭಾಗದಲ್ಲಿ ಸೀಳನ್ನು ನೋಡು" -#: ../src/core/all-keybindings.h:320 -msgid "Move window to workspace 8" -msgstr "ವಿಂಡೊವನ್ನು ಕಾರ್ಯಕ್ಷೇತ್ರ 8 ಕ್ಕೆ ಸ್ಥಳಾಂತರಿಸು" +#: ../data/50-mutter-windows.xml.in.h:19 +msgid "View split on right" +msgstr "ಬಲಭಾಗದಲ್ಲಿ ಸೀಳನ್ನು ನೋಡು" -#: ../src/core/all-keybindings.h:323 -msgid "Move window to workspace 9" -msgstr "ವಿಂಡೊವನ್ನು ಕಾರ್ಯಕ್ಷೇತ್ರ 9 ಕ್ಕೆ ಸ್ಥಳಾಂತರಿಸು" +#: ../data/mutter.desktop.in.h:1 +msgid "Mutter" +msgstr "Mutter" -#: ../src/core/all-keybindings.h:326 -msgid "Move window to workspace 10" -msgstr "ವಿಂಡೊವನ್ನು ಕಾರ್ಯಕ್ಷೇತ್ರ 10 ಕ್ಕೆ ಸ್ಥಳಾಂತರಿಸು" +#: ../data/org.gnome.mutter.gschema.xml.in.h:1 +msgid "Modifier to use for extended window management operations" +msgstr "ವಿಸ್ತರಿಸಲಾದ ಕಿಟಕಿ ವ್ಯವಸ್ಥಾಪನಾ ಕಾರ್ಯಗಳಲ್ಲಿ ಬಳಸಬೇಕಿರುವ ಮಾರ್ಪಡಕ" -#: ../src/core/all-keybindings.h:329 -msgid "Move window to workspace 11" -msgstr "ವಿಂಡೊವನ್ನು ಕಾರ್ಯಕ್ಷೇತ್ರ 11 ಕ್ಕೆ ಸ್ಥಳಾಂತರಿಸು" +#: ../data/org.gnome.mutter.gschema.xml.in.h:2 +msgid "" +"This key will initiate the \"overlay\", which is a combination window " +"overview and application launching system. The default is intended to be the " +"\"Windows key\" on PC hardware. It's expected that this binding either the " +"default or set to the empty string." +msgstr "" +"ಈ ಕೀಲಿಯು \"ಓವರ್ಲೇ\" ಅನ್ನು ಆರಂಭಿಸುತ್ತದೆ, ಈ ಸಂಯೋಜನಾ ಕಿಟಕಿಯ ಅವಲೋಕನ ಮತ್ತು ಅನ್ವಯ " +"ಆರಂಭಿಸುವ ವ್ಯವಸ್ಥೆಯಾಗಿರುತ್ತದೆ. ಪೂರ್ವನಿಯೋಜಿತವು PC ಯ ಯಂತ್ರಾಂಶದಲ್ಲಿನ \"ವಿಂಡೋಸ್ " +"ಕೀಲಿ\" " +"ಆಗಿರುತ್ತದೆ. ಈ ಬೈಂಡಿಂಗ್ ಒಂದು ಪೂರ್ವನಿಯೋಜಿತವಾಗಿರಬೇಕು ಅಥವ ಖಾಲಿ ವಾಕ್ಯಾಂಶಕ್ಕೆ " +"ಸೂಚಿತಗೊಂಡಿರಬೇಕು ಎಂದು ನಿರೀಕ್ಷಿಸಲಾಗುತ್ತದೆ." -#: ../src/core/all-keybindings.h:332 -msgid "Move window to workspace 12" -msgstr "ವಿಂಡೊವನ್ನು ಕಾರ್ಯಕ್ಷೇತ್ರ 12 ಕ್ಕೆ ಸ್ಥಳಾಂತರಿಸು" +#: ../data/org.gnome.mutter.gschema.xml.in.h:3 +msgid "Attach modal dialogs" +msgstr "ಮೋಡಲ್ ಸಂವಾದಗಳನ್ನು ಲಗತ್ತಿಸು" -#: ../src/core/all-keybindings.h:344 -msgid "Move window one workspace to the left" -msgstr "ವಿಂಡೋವನ್ನು ಒಂದು ಕಾರ್ಯಕ್ಷೇತ್ರದ ಎಡಕ್ಕೆ ಜರುಗಿಸು" +#: ../data/org.gnome.mutter.gschema.xml.in.h:4 +msgid "" +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." +msgstr "" +"true ಆಗಿದಲ್ಲಿ, ಪ್ರತ್ಯೇಕ ಶೀರ್ಷಿಕೆಪಟ್ಟಿಗಳ ಬದಲು ಮೂಲ ಕಿಟಕಿಗೆ ಮೋಡಲ್ ಸಂವಾದಗಳು " +"ಶೀರ್ಷಿಕೆಪಟ್ಟಿಗೆ ಲಗತ್ತಿಸಲಾದಂತೆ ಕಾಣಿಸುತ್ತದೆ ಮತ್ತು ಮೂಲ ಕಿಟಕಿಯ ಜೊತೆಗೆ ಅವೂ ಸಹ " +"ಚಲಿಸುತ್ತವೆ." -#: ../src/core/all-keybindings.h:347 -msgid "Move window one workspace to the right" -msgstr "ವಿಂಡೋವನ್ನು ಒಂದು ಕಾರ್ಯಕ್ಷೇತ್ರದ ಬಲಕ್ಕೆ ಜರುಗಿಸು" +#: ../data/org.gnome.mutter.gschema.xml.in.h:5 +msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "ಕಿಟಕಿಗಳನ್ನು ತೆರೆಯ ಅಂಚಿನಲ್ಲಿ ಬೀಳಿಸುವಾಗ ಅಂಚಿನ ಟೈಲಿಂಗ್ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸು" -#: ../src/core/all-keybindings.h:350 -msgid "Move window one workspace up" -msgstr "ವಿಂಡೋವನ್ನು ಒಂದು ಕಾರ್ಯಕ್ಷೇತ್ರದ ಮೇಲಕ್ಕೆ ಜರುಗಿಸು" +#: ../data/org.gnome.mutter.gschema.xml.in.h:6 +msgid "" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." +msgstr "" +"ಸಕ್ರಿಯಗೊಳಿಸಿದಲ್ಲಿ, ಲಂಬ ತೆರೆಯ ಅಂಚುಗಳಲ್ಲಿ ಕಿಟಕಿಗಳನ್ನು ಬೀಳಿಸಿದಾಗ ಅವುಗಳನ್ನು " +"ಲಂಬವಾಗಿ " +"ಹಿಗ್ಗಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಲಭ್ಯವಿರುವ ಜಾಗದ ಅರ್ಧ ಭಾಗವನ್ನು ಆವರಿಸುವಂತೆ ಅಡ್ಡಲಾಗಿ ಗಾತ್ರ " +"ಬದಲಿಸಲಾಗುತ್ತದೆ. ಕಿಟಕಿಗಳನ್ನು ಮೇಲಿನ ತೆರೆಯ ಅಂಚಿನ ಮೇಲೆ ಬೀಳಿಸಿದಾಗ ಅವುಗಳನ್ನು " +"ಸಂಪೂರ್ಣವಾಗಿ ಹಿಗ್ಗಿಸುವಂತೆ ಮಾಡಲಾಗುತ್ತದೆ." -#: ../src/core/all-keybindings.h:353 -msgid "Move window one workspace down" -msgstr "ವಿಂಡೋವನ್ನು ಒಂದು ಕಾರ್ಯಕ್ಷೇತ್ರದ ಕೆಳಗೆ ಜರುಗಿಸು" +#: ../data/org.gnome.mutter.gschema.xml.in.h:7 +msgid "Workspaces are managed dynamically" +msgstr "ಕಾರ್ಯಸ್ಥಳಗಳನ್ನು ಕ್ರಿಯಾತ್ಮಕವಾಗಿ ನಿರ್ವಹಿಸಲಾಗುತ್ತದೆ" -#: ../src/core/all-keybindings.h:356 -msgid "Raise window if it's covered by another window, otherwise lower it" +#: ../data/org.gnome.mutter.gschema.xml.in.h:8 +msgid "" +"Determines whether workspaces are managed dynamically or whether there's a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." msgstr "" +"ಕಾರ್ಯಸ್ಥಳಗಳನ್ನು ಕ್ರಿಯಾತ್ಮಕವಾಗಿ ನಿರ್ವಹಿಸಲಾಗುತ್ತದೆಯೆ ಅಥವ ಒಂದು ಸ್ಥಿರ ಸಂಖ್ಯೆಯ " +"ಕಾರ್ಯಸ್ಥಳಗಳು " +"ಇರುತ್ತವೆಯೆ ಎನ್ನುವುದನ್ನು ನಿರ್ಧರಿಸುತ್ತದೆ (org.gnome.desktop.wm.preferences " +"ನಲ್ಲಿನ " +"num-workspaces ಕೀಲಿಯಿಂದ ನಿರ್ಧರಿತಗೊಳ್ಳುತ್ತದೆ)." -#: ../src/core/all-keybindings.h:358 -msgid "Raise window above other windows" -msgstr "ವಿಂಡೊವನ್ನು ಇತರೆ ವಿಂಡೋಗಳಿಗಿಂತ ಎತ್ತರಿಸು" +#: ../data/org.gnome.mutter.gschema.xml.in.h:9 +msgid "Workspaces only on primary" +msgstr "ಪ್ರಾಥಮಿಕದಲ್ಲಿ ಇರುವ ಕಾರ್ಯಕ್ಷೇತ್ರಗಳು ಮಾತ್ರ" -#: ../src/core/all-keybindings.h:360 -msgid "Lower window below other windows" -msgstr "ಇತರೆ ವಿಂಡೊಗಳ ಅಡಿಯಲ್ಲಿರುವ ವಿಂಡೊ" +#: ../data/org.gnome.mutter.gschema.xml.in.h:10 +msgid "" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." +msgstr "" +"ಕಾರ್ಯಸ್ಥಳಗಳನ್ನು ಬದಲಾಯಿಸುವಿಕೆಯು ಎಲ್ಲಾ ಪರದೆಗಳಲ್ಲಿನ ಕಿಟಕಿಗಳ ಮೇಲೆ ನಡೆಯಬೇಕೆ ಅಥವ " +"ಪ್ರಾಥಮಿಕ ಪರದೆಯ ಮೇಲಿನ ಕಿಟಕಿಗಳಲ್ಲಿ ಮಾತ್ರ ನಡೆಯಬೇಕೆ ಎನ್ನುವುದನ್ನು ನಿರ್ಧರಿಸುತ್ತದೆ." -#: ../src/core/all-keybindings.h:364 -msgid "Maximize window vertically" -msgstr "ವಿಂಡೊವನ್ನು ಲಂಬವಾಗಿ ಹಿಗ್ಗಿಸು" +#: ../data/org.gnome.mutter.gschema.xml.in.h:11 +msgid "No tab popup" +msgstr "ಟ್ಯಾಬ್ ಪುಟಿಕೆ ಇಲ್ಲ" -#: ../src/core/all-keybindings.h:368 -msgid "Maximize window horizontally" -msgstr "ವಿಂಡೊವನ್ನು ಸಮತಲವಾಗಿ ಹಿಗ್ಗಿಸು" - -#: ../src/core/all-keybindings.h:372 -#| msgid "Move window to north-west corner" -msgid "Move window to north-west (top left) corner" -msgstr "ವಿಂಡೋವನ್ನು ತೆರೆಯ ಉತ್ತರ-ಪಶ್ಚಿಮ (ಮೇಲಿನ ಎಡಭಾಗ) ಮೂಲೆಗೆ ಜರುಗಿಸು" - -#: ../src/core/all-keybindings.h:375 -#| msgid "Move window to north-east corner" -msgid "Move window to north-east (top right) corner" -msgstr "ವಿಂಡೋವನ್ನು ತೆರೆಯ ಉತ್ತರ-ಪೂರ್ವ (ಮೇಲಿನ ಬಲಭಾಗ) ಮೂಲೆಗೆ ಜರುಗಿಸು" - -#: ../src/core/all-keybindings.h:378 -#| msgid "Move window to south-west corner" -msgid "Move window to south-west (bottom left) corner" -msgstr "ವಿಂಡೋವನ್ನು ತೆರೆಯ ದಕ್ಷಿಣ-ಪಶ್ಚಿಮ (ಕೆಳಗಿನ ಎಡಭಾಗ) ಮೂಲೆಗೆ ಜರುಗಿಸು" - -#: ../src/core/all-keybindings.h:381 -#| msgid "Move window to south-east corner" -msgid "Move window to south-east (bottom right) corner" -msgstr "ವಿಂಡೋವನ್ನು ತೆರೆಯ ದಕ್ಷಿಣ-ಪೂರ್ವ (ಕೆಳಗಿನ ಬಲಭಾಗ) ಮೂಲೆಗೆ ಜರುಗಿಸು" - -#: ../src/core/all-keybindings.h:385 -#| msgid "Move window to north side of screen" -msgid "Move window to north (top) side of screen" -msgstr "ವಿಂಡೋವನ್ನು ತೆರೆಯ ಉತ್ತರ (ಮೇಲೆ) ಭಾಗಕ್ಕೆ ಜರುಗಿಸು" - -#: ../src/core/all-keybindings.h:388 -#| msgid "Move window to south side of screen" -msgid "Move window to south (bottom) side of screen" -msgstr "ವಿಂಡೋವನ್ನು ತೆರೆಯ ದಕ್ಷಿಣ (ಕೆಳಗೆ) ಭಾಗಕ್ಕೆ ಜರುಗಿಸು" - -#: ../src/core/all-keybindings.h:391 -#| msgid "Move window to east side of screen" -msgid "Move window to east (right) side of screen" -msgstr "ವಿಂಡೋವನ್ನು ತೆರೆಯ ಪೂರ್ವ (ಬಲ) ಭಾಗಕ್ಕೆ ಜರುಗಿಸು" - -#: ../src/core/all-keybindings.h:394 -#| msgid "Move window to west side of screen" -msgid "Move window to west (left) side of screen" -msgstr "ವಿಂಡೋವನ್ನು ತೆರೆಯ ಪಶ್ಚಿಮ (ಎಡ) ಭಾಗಕ್ಕೆ ಜರುಗಿಸು" - -#: ../src/core/all-keybindings.h:397 -#| msgid "Move window to east side of screen" -msgid "Move window to center of screen" -msgstr "ವಿಂಡೋವನ್ನು ತೆರೆಯ ಮಧ್ಯ ಭಾಗಕ್ಕೆ ಜರುಗಿಸು" - -#: ../src/core/bell.c:310 -msgid "Bell event" +#: ../data/org.gnome.mutter.gschema.xml.in.h:12 +msgid "" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." msgstr "" +"ಕಿಟಕಿಯ ಆವರ್ತನೆಗಾಗಿ ಪುಟಿಕೆ (ಪಾಪಪ್) ಮತ್ತು ಹೈಲೈಟ್ ಚೌಕಟ್ಟನ್ನು ಬಳಸುವುದನ್ನು " +"ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಬೇಕೆ ಅಥವ ಬೇಡವೆ ಎನ್ನುವುದನ್ನು ನಿರ್ಧರಿಸುತ್ತದೆ." -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "ಗೊತ್ತಿರದ ವಿಂಡೊ ಮಾಹಿತಿಯ ಮನವಿ: %d" - -#. Translators: %s is a window title -#: ../src/core/delete.c:94 -#, c-format -#| msgid "\"%s\" is not responding." -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> ಪ್ರತಿಕ್ರಿಯಿಸುತ್ತಿಲ್ಲ." +#: ../data/org.gnome.mutter.gschema.xml.in.h:13 +msgid "Delay focus changes until the pointer stops moving" +msgstr "ಸೂಚಕವು ಚಲಿಸುವುದನ್ನು ನಿಲ್ಲಿಸುವವರೆಗೂ ಗಮನದ ಬದಲಾವಣೆಯು ವಿಳಂಬಗೊಳ್ಳುತ್ತದೆ" -#: ../src/core/delete.c:99 +#: ../data/org.gnome.mutter.gschema.xml.in.h:14 msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." +"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " +"the focus will not be changed immediately when entering a window, but only " +"after the pointer stops moving." msgstr "" +"true ಗೆ ಹೊಂದಿಸಲಾಗಿದ್ದಲ್ಲಿ, ಮತ್ತು ಗಮನದ ಸ್ಥಿತಿಯು \"sloppy\" ಅಥವ \"mouse\" " +"ಆಗಿದ್ದಲ್ಲಿ, ಒಂದು ಕಿಟಕಿಗೆ ಪ್ರವೇಶಿಸುವಾಗ ಗಮನವು ಕೂಡಲೆ ಬದಲಾಗುವುದಿಲ್ಲ, ಆದರೆ ಸೂಚಕವು " +"ಚಲಿಸುವುದನ್ನು ನಿಲ್ಲಿಸಿದ ನಂತರ ಬದಲಾಗುತ್ತದೆ." -#: ../src/core/delete.c:108 -msgid "_Wait" -msgstr "ನಿರೀಕ್ಷಿಸು(_W)" +#: ../data/org.gnome.mutter.gschema.xml.in.h:15 +msgid "Draggable border width" +msgstr "ಎಳೆಯಬಹುದಾದ ಅಂಚಿನ ಅಗಲ" -#: ../src/core/delete.c:108 -msgid "_Force Quit" -msgstr "ಬಲವಂತವಾಗಿ ಮುಚ್ಚು(_F)" +#: ../data/org.gnome.mutter.gschema.xml.in.h:16 +msgid "" +"The amount of total draggable borders. If the theme's visible borders are " +"not enough, invisible borders will be added to meet this value." +msgstr "" +"ಎಳೆಯಬಹುದಾದ ಅಂಚುಗಳ ಒಟ್ಟು ಮೊತ್ತ. ಸಿದ್ಧವಿನ್ಯಾಸದ ಗೋಚರಿಸುವ ಅಂಚುಗಳು ಸಾಕಷ್ಟು ಇಲ್ಲದೆ " +"ಇದ್ದಲ್ಲಿ, ಈ ಮೌಲ್ಯಕ್ಕೆ ಹೊಂದಿಕೆಯಾಗುವಂತೆ ಅಗೋಚರವಾದ ಅಂಚುಗಳನ್ನು ಸೇರಿಸಲಾಗುತ್ತದೆ." -#: ../src/core/display.c:365 -#, c-format -msgid "Missing %s extension required for compositing" +#: ../data/org.gnome.mutter.gschema.xml.in.h:17 +msgid "Auto maximize nearly monitor sized windows" +msgstr "ತೆರೆಯ ಗಾತ್ರದ ಕಿಟಕಿಗಳನ್ನು ಸ್ವಯಂ ಹಿಗ್ಗಿಸು" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:18 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." msgstr "" +"ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದ್ದರೆ, ಆರಂಭದಲ್ಲಿ ತೆರೆಯ ಗಾತ್ರದಲ್ಲಿರುವ ಹೊಸ ಕಿಟಕಿಗಳು " +"ಸ್ವಯಂಚಾಲಿತವಾಗಿ " +"ಹಿಗ್ಗಿಸಲಾಗುತ್ತದೆ." + +#: ../data/org.gnome.mutter.gschema.xml.in.h:19 +msgid "Place new windows in the center" +msgstr "ಹೊಸ ಕಿಟಕಿಗಳನ್ನು ಮಧ್ಯದಲ್ಲಿ ಇರಿಸು" -#: ../src/core/display.c:431 +#: ../data/org.gnome.mutter.gschema.xml.in.h:20 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" +"ಟ್ರೂ ಆಗಿದ್ದಾಗ, ಹೊಸ ಕಿಟಕಿಗಳನ್ನು ಯಾವಾಗಲೂ ಸಹ ಪರದೆಯ ಸಕ್ರಿಯ ತೆರೆಯ ಮೇಲೆ " +"ಇರಿಸಲಾಗುತ್ತದೆ." + +#: ../data/org.gnome.mutter.gschema.xml.in.h:21 +msgid "Select window from tab popup" +msgstr "ಟ್ಯಾಬ್ ಪುಟಿಕೆಯಿಂದ ಕಿಟಕಿಯನ್ನು ಆರಿಸು" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:22 +msgid "Cancel tab popup" +msgstr "ಟ್ಯಾಬ್ ಪುಟಿಕೆಯನ್ನು ರದ್ದುಗೊಳಿಸು" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:1 +#| msgid "Switch to workspace 1" +msgid "Switch to VT 1" +msgstr "VT 1 ಕ್ಕೆ ಬದಲಾಯಿಸು" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:2 +#| msgid "Switch to workspace 2" +msgid "Switch to VT 2" +msgstr "VT 2 ಕ್ಕೆ ಬದಲಾಯಿಸು" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:3 +#| msgid "Switch to workspace 3" +msgid "Switch to VT 3" +msgstr "VT 3 ಕ್ಕೆ ಬದಲಾಯಿಸು" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:4 +#| msgid "Switch to workspace 4" +msgid "Switch to VT 4" +msgstr "VT 4 ಕ್ಕೆ ಬದಲಾಯಿಸು" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:5 +#| msgid "Switch to workspace 1" +msgid "Switch to VT 5" +msgstr "VT 5 ಕ್ಕೆ ಬದಲಾಯಿಸು" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:6 +#| msgid "Switch to workspace 1" +msgid "Switch to VT 6" +msgstr "VT 6 ಕ್ಕೆ ಬದಲಾಯಿಸು" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:7 +#| msgid "Switch to workspace 1" +msgid "Switch to VT 7" +msgstr "VT 7 ಕ್ಕೆ ಬದಲಾಯಿಸು" + +#: ../src/backends/meta-monitor-manager.c:412 +msgid "Built-in display" +msgstr "ಒಳನಿರ್ಮಿತ ಪ್ರದರ್ಶಕ" + +#: ../src/backends/meta-monitor-manager.c:437 +msgid "Unknown" +msgstr "ಗೊತ್ತಿರದ" + +#: ../src/backends/meta-monitor-manager.c:439 +msgid "Unknown Display" +msgstr "ಗೊತ್ತಿರದ ಪ್ರದರ್ಶಕ" + +#. TRANSLATORS: this is a monitor vendor name, followed by a +#. * size in inches, like 'Dell 15"' +#. +#: ../src/backends/meta-monitor-manager.c:447 #, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "X ವಿಂಡೊ ಗಣಕ ಪ್ರದರ್ಶಕ '%s' ಅನ್ನು ತೆರೆಯುವಲ್ಲಿ ವಿಫಲತೆ\n" +msgid "%s %s" +msgstr "%s %s" -#: ../src/core/keybindings.c:759 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: ../src/compositor/compositor.c:443 #, c-format msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" +"Another compositing manager is already running on screen %i on display \"%s" +"\"." msgstr "" +"ಬೇರೊಂದು ಕಂಪೋಸಿಟಿಂಗ್ ವ್ಯವಸ್ಥಾಪಕವು ಈಗಾಗಲೆ %i ತೆರೆಯಲ್ಲಿನ \"%s \" ಪ್ರದರ್ಶಕದಲ್ಲಿ " +"ಚಾಲನೆಯಲ್ಲಿದೆ." -#. Displayed when a keybinding which is -#. * supposed to launch a program fails. -#. -#: ../src/core/keybindings.c:2468 +#: ../src/compositor/meta-background.c:1044 +msgid "background texture could not be created from file" +msgstr "ಹಿನ್ನಲೆಯ ರಚನೆಯನ್ನು ಕಡತದಿಂದ ರಚಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ" + +#: ../src/core/bell.c:185 +msgid "Bell event" +msgstr "ಘಂಟೆಯ ಶಬ್ಧ" + +#: ../src/core/delete.c:127 #, c-format -#| msgid "" -#| "There was an error running \"%s\":\n" -#| "%s." +msgid "“%s” is not responding." +msgstr "“%s“ ಪ್ರತಿಕ್ರಿಯಿಸುತ್ತಿಲ್ಲ." + +#: ../src/core/delete.c:129 +msgid "Application is not responding." +msgstr "ಅನ್ವಯವು ಪ್ರತಿಕ್ರಿಯಿಸುತ್ತಿಲ್ಲ." + +#: ../src/core/delete.c:134 msgid "" -"There was an error running <tt>%s</tt>:\n" -"\n" -"%s" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." msgstr "" -"<tt>%s</tt> ಅನ್ನು ಚಲಾಯಿಸುವಲ್ಲಿ ದೋಷ ಎದುರಾಗಿದೆ:\n" -"\n" -"%s" +"ಅನ್ವಯವು ಮುಂದುವರೆಯುವ ವರೆಗೆ ಕೊಂಚ ಸಮಯ ನೀವು ಕಾಯಬಹುದು ಅಥವ ಅದು ಸಂಪೂರ್ಣವಾಗಿ ಮುಚ್ಚಿ " +"ಹೋಗುವಂತೆ ಒತ್ತಾಯಿಸಬಹುದು." -#: ../src/core/keybindings.c:2558 -#, c-format -msgid "No command %d has been defined.\n" -msgstr "ಯಾವುದೆ %d ಆಜ್ಞೆಯು ಸೂಚಿತಗೊಂಡಿಲ್ಲ.\n" +#: ../src/core/delete.c:141 +msgid "_Wait" +msgstr "ನಿರೀಕ್ಷಿಸು (_W)" + +#: ../src/core/delete.c:141 +msgid "_Force Quit" +msgstr "ಬಲವಂತವಾಗಿ ಮುಚ್ಚು (_F)" -#: ../src/core/keybindings.c:3570 +#: ../src/core/display.c:547 #, c-format -msgid "No terminal command has been defined.\n" -msgstr "ಯಾವುದೆ ಟರ್ಮಿನಲ್ ಆಜ್ಞೆಯು ಸೂಚಿತಗೊಂಡಿಲ್ಲ.\n" +msgid "Failed to open X Window System display '%s'\n" +msgstr "X ಕಿಟಕಿ ಗಣಕ ಪ್ರದರ್ಶಕ '%s' ಅನ್ನು ತೆರೆಯುವಲ್ಲಿ ವಿಫಲತೆ\n" -#: ../src/core/main.c:206 +#: ../src/core/main.c:176 msgid "Disable connection to session manager" msgstr "ಅಧಿವೇಶನ ನಿರ್ವಾಹಕದೊಂದಿಗೆ ಸಂಪರ್ಕವನ್ನು ಅಶಕ್ತಗೊಳಿಸು" -#: ../src/core/main.c:212 +#: ../src/core/main.c:182 msgid "Replace the running window manager" -msgstr "ಚಲಾಯಿತಗೊಳ್ಳುತ್ತಿರುವ ವಿಂಡೊ ವ್ಯವಸ್ಥಾಪಕವನ್ನು ಬದಲಾಯಿಸಿ" +msgstr "ಚಲಾಯಿತಗೊಳ್ಳುತ್ತಿರುವ ಕಿಟಕಿ ವ್ಯವಸ್ಥಾಪಕವನ್ನು ಬದಲಾಯಿಸಿ" -#: ../src/core/main.c:218 +#: ../src/core/main.c:188 msgid "Specify session management ID" msgstr "ಅಧಿವೇಶನ ನಿರ್ವಹಣಾ ಐಡಿಯನ್ನು ಸೂಚಿಸಿ" -#: ../src/core/main.c:223 +#: ../src/core/main.c:193 msgid "X Display to use" msgstr "ಬಳಕೆಗಾಗಿ X ಪ್ರದರ್ಶಕ" -#: ../src/core/main.c:229 +#: ../src/core/main.c:199 msgid "Initialize session from savefile" msgstr "ಉಳಿಸಿದ ಕಡತದಿಂದ ಅಧಿವೇಶನವನ್ನು ಆರಂಭಿಸಿ" -#: ../src/core/main.c:235 +#: ../src/core/main.c:205 msgid "Make X calls synchronous" msgstr "X ಕರೆಗಳನ್ನು ಮೇಳೈಸುವಂತೆ ಮಾಡಿ" -#: ../src/core/main.c:506 +#: ../src/core/main.c:212 +msgid "Run as a wayland compositor" +msgstr "ವೇಲ್ಯಾಂಡ್ ಸಮ್ಮಿಶ್ರಕವಾಗಿ ಚಲಾಯಿಸು" + +#: ../src/core/main.c:220 +msgid "Run as a full display server, rather than nested" +msgstr "ನೆಸ್ಟೆಡ್ ಆಗಿರಿಸುವ ಬದಲಿಗೆ, ಒಂದು ಸಂಪೂರ್ಣ ಪ್ರದರ್ಶಕ ಪೂರೈಕೆಗಣಕವಾಗಿ ಚಲಾಯಿಸು" + +#: ../src/core/main.c:459 #, c-format msgid "Failed to scan themes directory: %s\n" msgstr "ಥೀಮ್‍ಗಳನ್ನು ಶೋಧಿಸುವಲ್ಲಿ ಕೋಶವನ್ನು ವಿಫಲಗೊಂಡಿದೆ: %s\n" -#: ../src/core/main.c:522 +#: ../src/core/main.c:475 #, c-format -msgid "Could not find a theme! Be sure %s exists and contains the usual themes.\n" +msgid "" +"Could not find a theme! Be sure %s exists and contains the usual themes.\n" msgstr "" -"ಥೀಮ್‍ಗಳನ್ನು ಪತ್ತೆ ಮಾಡಲಾಗಲಿಲ್ಲ! %s ವು ಅಸ್ತಿತ್ವದಲ್ಲಿದೆ ಹಾಗು ರೂಢಿಯ ಥೀಮ್‍ಗಳನ್ನು ಹೊಂದಿದೆ " +"ಥೀಮ್‍ಗಳನ್ನು ಪತ್ತೆ ಮಾಡಲಾಗಲಿಲ್ಲ! %s ವು ಅಸ್ತಿತ್ವದಲ್ಲಿದೆ ಹಾಗು ರೂಢಿಯ ಥೀಮ್‍ಗಳನ್ನು " +"ಹೊಂದಿದೆ " "ಎಂದು ಖಚಿತ ಪಡಿಸಿಕೊಳ್ಳಿ.\n" -#: ../src/core/muffin.c:42 +#: ../src/core/mutter.c:39 #, c-format -#| msgid "" -#| "metacity %s\n" -#| "Copyright (C) 2001-2008 Havoc Pennington, Red Hat, Inc., and others\n" -#| "This is free software; see the source for copying conditions.\n" -#| "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -#| "PARTICULAR PURPOSE.\n" msgid "" -"muffin %s\n" +"mutter %s\n" "Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" "This is free software; see the source for copying conditions.\n" "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " "PARTICULAR PURPOSE.\n" msgstr "" -"muffin %s\n" +"mutter %s\n" "Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" "This is free software; see the source for copying conditions.\n" "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " "PARTICULAR PURPOSE.\n" -#: ../src/core/muffin.c:56 +#: ../src/core/mutter.c:53 msgid "Print version" msgstr "ಮುದ್ರಿಸಬಹುದಾದ ಆವೃತ್ತಿ" -#: ../src/core/muffin.c:62 -msgid "Comma-separated list of compositor plugins" -msgstr "" +#: ../src/core/mutter.c:59 +msgid "Mutter plugin to use" +msgstr "ಬಳಸಬೇಕಿರುವ Mutter ಪ್ಲಗ್ಇನ್" -#. -#. * We found it, but it was invalid. Complain. -#. * -#. * FIXME: This replicates the original behaviour, but in the future -#. * we might consider reverting invalid keys to their original values. -#. * (We know the old value, so we can look up a suitable string in -#. * the symtab.) -#. * -#. * (Empty comment follows so the translators don't see this.) -#. -#. -#: ../src/core/prefs.c:543 ../src/core/prefs.c:704 +#: ../src/core/prefs.c:2101 #, c-format -msgid "GConf key '%s' is set to an invalid value\n" -msgstr "GConf ಕೀಲಿ \"%s\" ಯು ಒಂದು ಮಾನ್ಯವಾದ ಮೌಲ್ಯಕ್ಕೆ ಹೊಂದಿಸಲ್ಪಟ್ಟಿಲ್ಲ\n" +msgid "Workspace %d" +msgstr "ಕಾರ್ಯಕ್ಷೇತ್ರ %d" -#: ../src/core/prefs.c:630 ../src/core/prefs.c:873 +#: ../src/core/screen.c:548 #, c-format -msgid "%d stored in GConf key %s is out of range %d to %d\n" -msgstr "" +msgid "Screen %d on display '%s' is invalid\n" +msgstr "%d ತೆರೆಯು ಅಮಾನ್ಯವಾಗಿದೆ ( '%s' ಪ್ರದರ್ಶಕದಲ್ಲಿನ)\n" -#: ../src/core/prefs.c:674 ../src/core/prefs.c:751 ../src/core/prefs.c:799 -#: ../src/core/prefs.c:863 ../src/core/prefs.c:1324 ../src/core/prefs.c:1340 -#: ../src/core/prefs.c:1357 ../src/core/prefs.c:1373 +#: ../src/core/screen.c:564 #, c-format -msgid "GConf key \"%s\" is set to an invalid type\n" -msgstr "GConf ಕೀಲಿ \"%s\" ಯು ಒಂದು ಮಾನ್ಯವಾದ ಬಗೆಗೆ ಹೊಂದಿಸಲ್ಪಟ್ಟಿಲ್ಲ\n" +msgid "" +"Screen %d on display \"%s\" already has a window manager; try using the --" +"replace option to replace the current window manager.\n" +msgstr "" +"ತೆರೆ %d ಯು (ಪ್ರದರ್ಶಕ \"%s\" ದಲ್ಲಿನ) ಈಗಾಗಲೆ ಒಂದು ಕಿಟಕಿ ವ್ಯವಸ್ಥಾಪಕವನ್ನು " +"ಹೊಂದಿದೆ; --" +"replace ಅನ್ನು ಬಳಸಿಕೊಂಡು ಪ್ರಸಕ್ತ ಕಿಟಕಿ ವ್ಯವಸ್ಥಾಪಕವನ್ನು ಬದಲಾಯಿಸಿ.\n" -#: ../src/core/prefs.c:1203 +#: ../src/core/screen.c:657 #, c-format -msgid "GConf key %s is already in use and can't be used to override %s\n" +msgid "Screen %d on display \"%s\" already has a window manager\n" msgstr "" -"%s ಎಂಬ GConf ಕೀಲಿಯು ಈಗಾಗಲೆ ಬಳಕೆಯಲ್ಲಿದೆ ಹಾಗು ಅದನ್ನು %s ಅನ್ನು ಅತಿಕ್ರಮಿಸಲು ಬಳಸಲು " -"ಸಾಧ್ಯವಿಲ್ಲ\n" +"ತೆರೆ %d ಯು (ಪ್ರದರ್ಶಕ \"%s\" ದಲ್ಲಿನ) ಈಗಾಗಲೆ ಒಂದು ಕಿಟಕಿ ವ್ಯವಸ್ಥಾಪಕವನ್ನು " +"ಹೊಂದಿದೆ\n" -#: ../src/core/prefs.c:1262 +#: ../src/core/util.c:118 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "ವರ್ಬೋಸ್ ಕ್ರಮಕ್ಕಾಗಿನ ಬೆಂಬಲವಿಲ್ಲದೆ Mutter ಅನ್ನು ಕಂಪೈಲ್ ಮಾಡಲಾಗಿದೆ\n" + +#. Translators: This represents the size of a window. The first number is +#. * the width of the window and the second is the height. +#. +#: ../src/ui/resizepopup.c:134 #, c-format -msgid "Can't override GConf key, %s not found\n" -msgstr "GConf ಕೀಲಿಯನ್ನು ಅತಿಕ್ರಮಿಸಲು ಸಾಧ್ಯವಾಗಿಲ್ಲ, %s ಕಂಡುಬಂದಿಲ್ಲ\n" +msgid "%d x %d" +msgstr "%d x %d" -#: ../src/core/prefs.c:1447 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" +#: ../src/ui/theme.c:233 +msgid "top" +msgstr "ಮೇಲ್ಭಾಗ" + +#: ../src/ui/theme.c:235 +msgid "bottom" +msgstr "ಕೆಳಭಾಗ" + +#: ../src/ui/theme.c:237 +msgid "left" +msgstr "ಎಡಭಾಗ" + +#: ../src/ui/theme.c:239 +msgid "right" +msgstr "ಬಲಭಾಗ" -#: ../src/core/prefs.c:1524 +#: ../src/ui/theme.c:267 #, c-format -msgid "Could not parse font description \"%s\" from GConf key %s\n" -msgstr "ಅಕ್ಷರಶೈಲಿ ವಿವರಣೆ \"%s\" ಅನ್ನು GConf ಕೀಲಿ %s ಇಂದ ಪಾರ್ಸ್ ಮಾಡಲಾಗಿಲ್ಲ\n" +msgid "frame geometry does not specify \"%s\" dimension" +msgstr "ಚೌಕಟ್ಟಿನ ಜ್ಯಾಮಿತಿಯು \"%s\" ಆಯಾಮವನ್ನು ಸೂಚಿಸುವುದಿಲ್ಲ" -#: ../src/core/prefs.c:1586 +#: ../src/ui/theme.c:286 #, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" +msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" +msgstr "ಚೌಕಟ್ಟಿನ ಜ್ಯಾಮಿತಿಯು \"%s\" ಆಯಾಮವನ್ನು \"%s\" ಅಂಚಿಗಾಗಿ ಸೂಚಿಸುವುದಿಲ್ಲ" -#: ../src/core/prefs.c:2016 +#: ../src/ui/theme.c:323 #, c-format -msgid "Error setting number of workspaces to %d: %s\n" -msgstr "ಕಾರ್ಯಕ್ಷೇತ್ರಗಳ ಸಂಖ್ಯೆಯನ್ನು %d ಗೆ ಹೊಂದಿಸುವಲ್ಲಿ ದೋಷ ಉಂಟಾಗಿದೆ: %s\n" +msgid "Button aspect ratio %g is not reasonable" +msgstr "ಗುಂಡಿಯ ಆಕಾರ ಅನುಪಾತ %g ಯು ಸೂಕ್ತವಾಗಿಲ್ಲ" -#: ../src/core/prefs.c:2200 ../src/core/prefs.c:2702 +#: ../src/ui/theme.c:335 #, c-format -msgid "Workspace %d" -msgstr "ಕಾರ್ಯಕ್ಷೇತ್ರ %d" +msgid "Frame geometry does not specify size of buttons" +msgstr "ಚೌಕಟ್ಟಿನ ಜ್ಯಾಮಿತಿಯು ಗುಂಡಿಗಳ ಗಾತ್ರವನ್ನು ಸೂಚಿಸುವುದಿಲ್ಲ" -#: ../src/core/prefs.c:2232 ../src/core/prefs.c:2410 +#: ../src/ui/theme.c:1061 #, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "" +msgid "Gradients should have at least two colors" +msgstr "ಏರಿಳಿತ ಪ್ರಮಾಣಗಳನ್ನು ಕನಿಷ್ಟ ಎರಡು ಬಣ್ಣಗಳನ್ನು ಹೊಂದಿರಬೇಕು" -#: ../src/core/prefs.c:2783 +#: ../src/ui/theme.c:1211 #, c-format -msgid "Error setting name for workspace %d to \"%s\": %s\n" +msgid "" +"GTK custom color specification must have color name and fallback in " +"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" msgstr "" +"GTK ಬಣ್ಣವನ್ನು ಸೂಚಿಸುವಿಕೆಗಾಗಿ ಸ್ಥಿತಿಯಲ್ಲಿ ಬಣ್ಣದ ಹೆಸರು ಮತ್ತು ಆವರಣ ಚಿಹ್ನೆಯ ಒಳಗೆ " +"ಹಿಮ್ಮರಳಿಕೆಯ ಮಾಹಿತಿ ಇರಬೇಕು, ಉದಾ. gtk:custom(foo,bar); \"%s\" ಅನ್ನು ಪಾರ್ಸ್ " +"ಮಾಡಲಾಗಿಲ್ಲ" -#: ../src/core/prefs.c:2997 +#: ../src/ui/theme.c:1227 #, c-format -msgid "Error setting live hidden windows status status: %s\n" +msgid "" +"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" +"_ are valid" msgstr "" +"gtk:custom ನಲ್ಲಿನ color_name ನಲ್ಲಿ ಅಮಾನ್ಯವಾದ ಅಕ್ಷರ '%c' ಕಂಡುಬಂದಿದೆ, ಕೇವಲ A-Za-" +"z0-9-_ ಮಾತ್ರ ಮಾನ್ಯವಾದವುಗಳಾಗಿರುತ್ತವೆ" -#: ../src/core/prefs.c:3032 +#: ../src/ui/theme.c:1241 #, c-format -msgid "Error setting no tab popup status: %s\n" +msgid "" +"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " +"fit the format" msgstr "" +"Gtk:ಅಗತ್ಯಾನುಗುಣ ವಿನ್ಯಾಸವು \"gtk:custom(color_name,fallback)\" ಆಗಿರುತ್ತದೆ, \"%s" +"\" ಎನ್ನುವುದು ವಿನ್ಯಾಸಕ್ಕೆ ಹೊಂದಿಕೆಯಾಗುವುದಿಲ್ಲ" -#: ../src/core/screen.c:623 +#: ../src/ui/theme.c:1286 #, c-format -msgid "Screen %d on display '%s' is invalid\n" +msgid "" +"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " +"where NORMAL is the state; could not parse \"%s\"" msgstr "" +"GTK ಬಣ್ಣವನ್ನು ಸೂಚಿಸುವಿಕೆಗಾಗಿ ಸ್ಥಿತಿಯಲ್ಲಿ ಆವರಣ ಚಿಹ್ನೆಯು ಇರಬೇಕು, ಉದಾ. gtk:" +"fg[NORMAL] ಆಗಿರುತ್ತದೆ, ಇಲ್ಲಿ NORMAL ಸ್ಥಿತಿಯನ್ನು ಸೂಚಿಸುತ್ತದೆ; \"%s\" ಅನ್ನು " +"ಪಾರ್ಸ್ " +"ಮಾಡಲು ಸಾಧ್ಯವಾಗಿಲ್ಲ" -#: ../src/core/screen.c:639 +#: ../src/ui/theme.c:1300 #, c-format msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" +"GTK color specification must have a close bracket after the state, e.g. gtk:" +"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" msgstr "" +"GTK ಬಣ್ಣವನ್ನು ಸೂಚಿಸುವಿಕೆಗಾಗಿ ಸ್ಥಿತಿಯ ನಂತರ ಮುಚ್ಚಲಾದ ಒಂದು ಆವರಣ ಚಿಹ್ನೆಯನ್ನು " +"ಸೂಚಿಸಬೇಕು, ಉದಾ. gtk:fg[NORMAL] ಆಗಿರುತ್ತದೆ, ಇಲ್ಲಿ NORMAL ಸ್ಥಿತಿಯನ್ನು " +"ಸೂಚಿಸುತ್ತದೆ; " +"\"%s\" ಅನ್ನು ಪಾರ್ಸ್ ಮಾಡಲು ಸಾಧ್ಯವಾಗಿಲ್ಲ" -#: ../src/core/screen.c:666 +#: ../src/ui/theme.c:1311 #, c-format -msgid "Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "" +msgid "Did not understand state \"%s\" in color specification" +msgstr "ಬಣ್ಣ ವಿವರಣೆಯಲ್ಲಿನ ಸ್ಥಿತಿ \"%s\" ಅನ್ನು ಅರ್ಥ ಮಾಡಿಕೊಳ್ಳಲು ಸಾಧ್ಯವಾಗಿಲ್ಲ" -#: ../src/core/screen.c:721 +#: ../src/ui/theme.c:1324 #, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" +msgid "Did not understand color component \"%s\" in color specification" +msgstr "ಬಣ್ಣ ವಿವರಣೆಯಲ್ಲಿನ ಬಣ್ಣದ ಘಟಕ \"%s\" ಅನ್ನು ಅರ್ಥ ಮಾಡಿಕೊಳ್ಳಲು ಸಾಧ್ಯವಾಗಿಲ್ಲ" + +#: ../src/ui/theme.c:1352 +#, c-format +msgid "" +"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " +"format" msgstr "" +"ಮಿಶ್ರಗೊಳಿಕಾ ವಿನ್ಯಾಸ \"blend/bg_color/fg_color/alpha\", \"%s\" ವಿನ್ಯಾಸಕ್ಕೆ " +"ಹೊಂದಿಕೆಯಾಗುತ್ತಿಲ್ಲ" -#: ../src/core/screen.c:906 +#: ../src/ui/theme.c:1363 #, c-format -msgid "Could not release screen %d on display \"%s\"\n" +msgid "Could not parse alpha value \"%s\" in blended color" msgstr "" +"ಮಿಶ್ರಗೊಳಿಸಲಾದ ಬಣ್ಣದಲ್ಲಿ ಆಲ್ಫಾ ಮೌಲ್ಯ \"%s\" ಅನ್ನು ಪಾರ್ಸ್ ಮಾಡಲು ಸಾಧ್ಯವಾಗಿಲ್ಲ" -#: ../src/core/session.c:837 ../src/core/session.c:844 +#: ../src/ui/theme.c:1373 #, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "ಕೋಶ '%s' ಅನ್ನು ಸೃಜಿಸಲಾಗಲಿಲ್ಲ: %s\n" +msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" +msgstr "" +"ಮಿಶ್ರ ಮಾಡಲಾದ ಬಣ್ಣದ ಆಲ್ಫಾ ಮೌಲ್ಯವು \"%s\" ವು 0.0 ಹಾಗು 1.0 ಯ ನಡುವಿನಲ್ಲಿ ಇಲ್ಲ" -#: ../src/core/session.c:854 +#: ../src/ui/theme.c:1419 #, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "ಅಧಿವೇಶನ ಕಡತ '%s' ಅನ್ನು ಬರೆಯಲು ತೆಗೆಯಲಾಗಿಲ್ಲ: %s\n" +msgid "" +"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" +msgstr "" +"ಮಬ್ಬು ವಿನ್ಯಾಸ \"shade/base_color/factor\", \"%s\" ವಿನ್ಯಾಸಕ್ಕೆ ಸರಿಹೊಂದುತ್ತಿಲ್ಲ" -#: ../src/core/session.c:995 +#: ../src/ui/theme.c:1430 #, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "ಅಧಿವೇಶನ ಕಡತ '%s' ಅನ್ನು ಬರೆಯುವಲ್ಲಿ ದೋಷ: %s\n" +msgid "Could not parse shade factor \"%s\" in shaded color" +msgstr "ಮಬ್ಬುಗೊಳಿಸಲಾದ ಬಣ್ಣದ ಮಬ್ಬುಗೊಳಿಕಾ ಅಂಶ \"%s\" ಅನ್ನು ಪಾರ್ಸ್ ಮಾಡಲಾಗಿಲ್ಲ" -#: ../src/core/session.c:1000 +#: ../src/ui/theme.c:1440 #, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "ಅಧಿವೇಶನ ಕಡತ '%s' ಅನ್ನು ಮುಚ್ಚುವಲ್ಲಿ ದೋಷ: %s\n" +msgid "Shade factor \"%s\" in shaded color is negative" +msgstr "ಮಬ್ಬುಗೊಳಿಸಲಾದ ಬಣ್ಣದಲ್ಲಿನ ಮಬ್ಬುಗೊಳಿಸುವ ಅಂಶ \"%s\" ಋಣಾತ್ಮಕವಾಗಿದೆ" -#: ../src/core/session.c:1130 +#: ../src/ui/theme.c:1469 #, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "ಉಳಿಸಲಾದ ಅಧಿವೇಶನ ಕಡತವನ್ನು ಪಾರ್ಸ್ ಮಾಡುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ: %s\n" +msgid "Could not parse color \"%s\"" +msgstr "\"%s\" ಬಣ್ಣವನ್ನು ಪಾರ್ಸ್ ಮಾಡಲಾಗಿಲ್ಲ" -#: ../src/core/session.c:1179 +#: ../src/ui/theme.c:1778 #, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" +msgid "Coordinate expression contains character '%s' which is not allowed" msgstr "" +"ಅನುಮತಿ ಇರದೆ ಇರುವಂತಹ ಅಕ್ಷರವನ್ನು '%s' ಅನ್ನು ಅಕ್ಷಾಂಶ ಎಕ್ಸ್‌ಪ್ರೆಶನ್‌ ಹೊಂದಿದೆ" -#: ../src/core/session.c:1192 ../src/core/session.c:1267 -#: ../src/core/session.c:1299 ../src/core/session.c:1371 -#: ../src/core/session.c:1431 +#: ../src/ui/theme.c:1805 #, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "ಗೊತ್ತಿರದ ಗುಣವಿಶೇಷ %s, <%s> ಘಟಕದಲ್ಲಿ" +msgid "" +"Coordinate expression contains floating point number '%s' which could not be " +"parsed" +msgstr "" +"ಪಾರ್ಸ್ ಮಾಡಲು ಸಾಧ್ಯವಾಗದೆ ಇರುವಂತಹ ತೇಲುವ ಬಿಂದು (ಫ್ಲೋಟಿಂಗ್ ಪಾಯಿಂಟ್‌) ಸಂಖ್ಯೆ '%s' " +"ಅನ್ನು " +"ಅಕ್ಷಾಂಶ ಎಕ್ಸ್‌ಪ್ರೆಶನ್‌ ಹೊಂದಿದೆ" -#: ../src/core/session.c:1209 +#: ../src/ui/theme.c:1819 #, c-format -msgid "nested <window> tag" +msgid "Coordinate expression contains integer '%s' which could not be parsed" msgstr "" +"ಪಾರ್ಸ್ ಮಾಡಲು ಸಾಧ್ಯವಾಗದೆ ಇರುವಂತಹ ಪೂರ್ಣಾಂಕ '%s' ಅನ್ನು ಅಕ್ಷಾಂಶ ಎಕ್ಸ್‌ಪ್ರೆಶನ್‌ " +"ಹೊಂದಿದೆ" -#: ../src/core/session.c:1451 +#: ../src/ui/theme.c:1940 #, c-format -msgid "Unknown element %s" -msgstr "ಗೊತ್ತಿರದ %s ಘಟಕ" - -#: ../src/core/session.c:1803 msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." +"Coordinate expression contained unknown operator at the start of this text: " +"\"%s\"" msgstr "" +"ಅಕ್ಷಾಂಶ ಎಕ್ಸ್‌ಪ್ರೆಶನ್‌ನಲ್ಲಿನ ಪಠ್ಯದ ಆರಂಭದಲ್ಲಿ ಗೊತ್ತಿರದ ಆಪರೇಟರ್ ಅನ್ನು ಹೊಂದಿದೆ: " +"\"%s\"" -#: ../src/core/util.c:111 +#: ../src/ui/theme.c:1997 #, c-format -msgid "Failed to open debug log: %s\n" -msgstr "ದೋಷ ನಿವಾರಣಾ ದಾಖಲೆಯನ್ನು ತೆರೆಯಲು ವಿಫಲಗೊಂಡಿದೆ: %s\n" +msgid "Coordinate expression was empty or not understood" +msgstr "ಅಕ್ಷಾಂಶ ಎಕ್ಸ್‌ಪ್ರೆಶನ್‌ ಖಾಲಿ ಇದೆ ಅಥವ ಅರ್ಥ ಮಾಡಿಕೊಳ್ಳಲು ಸಾಧ್ಯವಾಗಿಲ್ಲ" -#: ../src/core/util.c:121 +#: ../src/ui/theme.c:2110 ../src/ui/theme.c:2120 ../src/ui/theme.c:2154 #, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "ದಾಖಲೆ ಕಡತವನ್ನು %s fdopen() ಮಾಡುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ: %s\n" +msgid "Coordinate expression results in division by zero" +msgstr "ಅಕ್ಷಾಂಶ ಎಕ್ಸ್‌ಪ್ರೆಶನ್ ಶೂನ್ಯದಿಂದ ಭಾಗಾಕಾರಕ್ಕೆ ಕಾರಣವಾಗಿದೆ" -#: ../src/core/util.c:127 +#: ../src/ui/theme.c:2162 #, c-format -msgid "Opened log file %s\n" -msgstr "ದಾಖಲೆ ಕಡತ %s ಅನ್ನು ತೆರೆಯಲಾಗಿದೆ\n" +msgid "" +"Coordinate expression tries to use mod operator on a floating-point number" +msgstr "" +"ಅಕ್ಷಾಂಶ ಎಕ್ಸ್‌ಪ್ರೆಶನ್‌ ಒಂದು ತೇಲುವ-ಬಿಂದು ಸಂಖ್ಯೆಯಲ್ಲಿ mod ಆಪರೇಟರ್ ಅನ್ನು ಬಳಸಲು " +"ಪ್ರಯತ್ನಿಸಿದೆ" -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 +#: ../src/ui/theme.c:2218 #, c-format -msgid "Muffin was compiled without support for verbose mode\n" +msgid "" +"Coordinate expression has an operator \"%s\" where an operand was expected" msgstr "" +"ಅಕ್ಷಾಂಶ ಎಕ್ಸ್‌ಪ್ರೆಶನ್‌ನಲ್ಲಿ ಎಲ್ಲಿ operand ಅನ್ನು ನಿರೀಕ್ಷಿಸಲಾಗಿತ್ತೊ ಅಲ್ಲಿ ಒಂದು " +"ಆಪರೇಟರ್ \"%s" +"\" ಇದೆ" -#: ../src/core/util.c:286 -msgid "Window manager: " -msgstr "ವಿಂಡೊ ವ್ಯವಸ್ಥಾಪಕ: " - -#: ../src/core/util.c:434 -msgid "Bug in window manager: " -msgstr "ವಿಂಡೊ ವ್ಯವಸ್ಥಾಪಕದಲ್ಲಿ ಒಂದು ತೊಂದರೆ: " - -#: ../src/core/util.c:467 -msgid "Window manager warning: " -msgstr "ವಿಂಡೊ ವ್ಯವಸ್ಥಾಪಕ ಎಚ್ಚರಿಕೆ: " - -#: ../src/core/util.c:495 -msgid "Window manager error: " -msgstr "ವಿಂಡೊ ವ್ಯವಸ್ಥಾಪಕ ದೋಷ: " - -#. Translators: This is the title used on dialog boxes -#: ../src/core/util.c:615 ../src/muffin.desktop.in.h:1 -#: ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" - -#. first time through -#: ../src/core/window.c:6752 +#: ../src/ui/theme.c:2227 #, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" +msgid "Coordinate expression had an operand where an operator was expected" msgstr "" +"ಅಕ್ಷಾಂಶ ಎಕ್ಸ್‌ಪ್ರೆಶನ್‌ನಲ್ಲಿ ಎಲ್ಲಿ ಆಪರೇಟರ್ ಅನ್ನು ನಿರೀಕ್ಷಿಸಲಾಗಿತ್ತೊ ಅಲ್ಲಿ ಒಂದು " +"operand ಇದೆ" -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7415 +#: ../src/ui/theme.c:2235 +#, c-format +msgid "Coordinate expression ended with an operator instead of an operand" +msgstr "ಅಕ್ಷಾಂಶ ಎಕ್ಸ್‌ಪ್ರೆಶನ್ ಒಂದು operand ಬದಲಿಗೆ ಆಪರೇಟರಿನೊಂದಿಗೆ ಅಂತ್ಯಗೊಂಡಿದೆ" + +#: ../src/ui/theme.c:2245 #, c-format msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %" -"d x %d and max size %d x %d; this doesn't make much sense.\n" +"Coordinate expression has operator \"%c\" following operator \"%c\" with no " +"operand in between" msgstr "" +"ಅಕ್ಷಾಂಶ ಎಕ್ಸ್‌ಪ್ರೆಶನ್‌ ಆಪೇರೇಟರ್ \"%c\" ಹಾಗು ಅಪರೇಟರ್ \"%c\" ಅನ್ನು ಹೊಂದಿದೆ ಆದರೆ " +"ನಡುವೆ " +"ಯಾವುದೆ operand ಅನ್ನು ಹೊಂದಿಲ್ಲ" -#: ../src/core/window-props.c:309 +#: ../src/ui/theme.c:2396 ../src/ui/theme.c:2441 #, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" +msgid "Coordinate expression had unknown variable or constant \"%s\"" msgstr "" +"ಅಕ್ಷಾಂಶ ಎಕ್ಸ್‌ಪ್ರೆಶನ್ ಯಾವುದೆ ಗೊತ್ತಿರದ ಚರ ಮೌಲ್ಯ ಅಥವ ಸ್ಥಿರ ಮೌಲ್ಯ \"%s\" ಅನ್ನು " +"ಹೊಂದಿದೆ" -#: ../src/core/window-props.c:426 +#: ../src/ui/theme.c:2495 #, c-format -msgid "%s (on %s)" -msgstr "%s (%s ನಲ್ಲಿ)" +msgid "Coordinate expression parser overflowed its buffer." +msgstr "ಅಕ್ಷಾಂಶ ಎಕ್ಸ್‌ಪ್ರೆಶನ್ ಪಾರ್ಸರ್ ತನ್ನ ಬಫರಿನ ಮಿತಿಯನ್ನು ಮೀರಿದೆ." -#: ../src/core/window-props.c:1479 +#: ../src/ui/theme.c:2524 #, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +msgid "Coordinate expression had a close parenthesis with no open parenthesis" msgstr "" +"ಅಕ್ಷಾಂಶ ಎಕ್ಸ್‌ಪ್ರೆಶನ್‌ ಯಾವುದೆ ತೆರೆದ ಆವರಣ ಚಿಹ್ನೆ ಇರದೆ ಕೇವಲ ಮುಚ್ಚಲ್ಪಟ್ಟ ಆವರಣ " +"ಚಿಹ್ನೆಯನ್ನು " +"ಹೊಂದಿದೆ" -#: ../src/core/xprops.c:155 +#: ../src/ui/theme.c:2588 #, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +msgid "Coordinate expression had an open parenthesis with no close parenthesis" msgstr "" +"ಅಕ್ಷಾಂಶ ಎಕ್ಸ್‌ಪ್ರೆಶನ್‌ ಯಾವುದೆ ಮುಚ್ಚಲ್ಪಟ್ಟ ಆವರಣ ಚಿಹ್ನೆ ಇರದೆ ಕೇವಲ ತೆರೆದ ಆವರಣ " +"ಚಿಹ್ನೆಯನ್ನು " +"ಹೊಂದಿದೆ" -#: ../src/core/xprops.c:411 +#: ../src/ui/theme.c:2599 #, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +msgid "Coordinate expression doesn't seem to have any operators or operands" msgstr "" +"ಅಕ್ಷಾಂಶ ಎಕ್ಸ್‌ಪ್ರೆಶನ್‌ ಯಾವುದೆ ಬಗೆಯ ಆಪರೇಟರುಗಳನ್ನು ಅಥವ ಆಪರಾಂಡ್‌ಗಳನ್ನು " +"(operands) " +"ಹೊಂದಿರುವಂತೆ ತೋರುತ್ತಿಲ್ಲ" -#: ../src/core/xprops.c:494 +#: ../src/ui/theme.c:2812 ../src/ui/theme.c:2832 ../src/ui/theme.c:2852 #, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" - -#: ../src/muffin.schemas.in.h:1 -msgid "Attach modal dialogs" +msgid "Theme contained an expression that resulted in an error: %s\n" msgstr "" +"ಒಂದು ದೋಷಕ್ಕೆ ಕಾರಣವಾದಂತಹ ಒಂದು ಎಕ್ಸ್‌ಪ್ರೆಶನ್‌ ಪರಿಸರವಿನ್ಯಾಸದಲ್ಲಿ ಕಂಡುಬಂದಿದೆ: %s\n" -#: ../src/muffin.schemas.in.h:2 +#: ../src/ui/theme.c:4455 +#, c-format msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." +"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " +"specified for this frame style" msgstr "" +"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> ವು ಈ ಚೌಕಟ್ಟಿನ " +"ಶೈಲಿಗೆ ಸೂಚಿತಗೊಳ್ಳಬೇಕು" -#: ../src/muffin.schemas.in.h:3 +#: ../src/ui/theme.c:4970 ../src/ui/theme.c:4995 +#, c-format msgid "" -"Determines whether workspace switching should happen for windows on all " -"monitors or only for windows on the primary monitor." +"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" msgstr "" +"<frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/> " +"ಕಾಣುತ್ತಿಲ್ಲ" -#: ../src/muffin.schemas.in.h:4 -msgid "Live Hidden Windows" -msgstr "" +#: ../src/ui/theme.c:5041 +#, c-format +msgid "Failed to load theme \"%s\": %s\n" +msgstr "\"%s\" ಥೀಮನ್ನು ಲೋಡ್‍ ಮಾಡಲು ವಿಫಲಗೊಂಡಿದೆ: %s\n" -#: ../src/muffin.schemas.in.h:5 -msgid "Modifier to use for extended window management operations" -msgstr "" +#: ../src/ui/theme.c:5177 ../src/ui/theme.c:5184 ../src/ui/theme.c:5191 +#: ../src/ui/theme.c:5198 ../src/ui/theme.c:5205 +#, c-format +msgid "No <%s> set for theme \"%s\"" +msgstr "ಯಾವುದೆ <%s> ಅನ್ನು ಹೊಂದಿಸಲಾಗಿಲ್ಲ (ಪರಿಸರವಿನ್ಯಾಸ \"%s\" ಕ್ಕಾಗಿ)" -#: ../src/muffin.schemas.in.h:6 +#: ../src/ui/theme.c:5213 +#, c-format msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." +"No frame style set for window type \"%s\" in theme \"%s\", add a <window " +"type=\"%s\" style_set=\"whatever\"/> element" msgstr "" +"ಬಗೆ \"%s\" ಗಾಗಿ \"%s\" ಪರಿಸರವಿನ್ಯಾಸದಲ್ಲಿ ಯಾವುದೆ ಚೌಕಟ್ಟು ಶೈಲಿ ಇಲ್ಲ, ಒಂದು <" +"window " +"type=\"%s\" style_set=\"whatever\"/> ಘಟಕವನ್ನು ಸೇರಿಸಿ" -#: ../src/muffin.schemas.in.h:7 +#: ../src/ui/theme.c:5620 ../src/ui/theme.c:5682 ../src/ui/theme.c:5745 +#, c-format msgid "" -"When true, instead of having independent titlebars, modal dialogs appear " -"attached to the titlebar of the parent window and are moved together with " -"the parent window." -msgstr "" - -#: ../src/muffin.schemas.in.h:8 -msgid "Workspaces only on primary" -msgstr "ಪ್ರಾಥಮಿಕದಲ್ಲಿ ಇರುವ ಕಾರ್ಯಕ್ಷೇತ್ರಗಳು ಮಾತ್ರ" - -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "ಬಳಕೆ: %s\n" - -#: ../src/ui/frames.c:1099 -msgid "Close Window" -msgstr "ವಿಂಡೊವನ್ನು ಮುಚ್ಚು" - -#: ../src/ui/frames.c:1102 -msgid "Window Menu" -msgstr "ವಿಂಡೊ ಮೆನು" - -#: ../src/ui/frames.c:1105 -msgid "Minimize Window" -msgstr "ವಿಂಡೊವನ್ನು ಕುಗ್ಗಿಸು" - -#: ../src/ui/frames.c:1108 -msgid "Maximize Window" -msgstr "ವಿಂಡೊವನ್ನು ಹಿಗ್ಗಿಸು" - -#: ../src/ui/frames.c:1111 -#| msgid "Resize window" -msgid "Restore Window" -msgstr "ವಿಂಡೊವನ್ನು ಮರಳಿ ಸ್ಥಾಪಿಸು" - -#: ../src/ui/frames.c:1114 -msgid "Roll Up Window" -msgstr "ವಿಂಡೊವನ್ನು ಉರುಳಿಸಿ" - -#: ../src/ui/frames.c:1117 -msgid "Unroll Window" -msgstr "ವಿಂಡೊವನ್ನು ಸುತ್ತಿ" - -#: ../src/ui/frames.c:1120 -msgid "Keep Window On Top" -msgstr "ವಿಂಡೊ ಅನ್ನು ಮೇಲ್ಭಾಗದಲ್ಲಿ ಇರಿಸು" - -#: ../src/ui/frames.c:1123 -msgid "Remove Window From Top" -msgstr "ವಿಂಡೊ ಅನ್ನು ಮೇಲ್ಭಾಗದಿಂದ ತೆಗೆದು ಹಾಕು" - -#: ../src/ui/frames.c:1126 -msgid "Always On Visible Workspace" -msgstr "ಯಾವಾಗಲೂ ಕಾಣಿಸುವ ಕಾರ್ಯಕ್ಷೇತ್ರದಲ್ಲಿ" - -#: ../src/ui/frames.c:1129 -msgid "Put Window On Only One Workspace" -msgstr "ವಿಂಡೊವನ್ನು ಕೇವಲ ಒಂದು ಕಾರ್ಯಕ್ಷೇತ್ರದಲ್ಲಿ ಇರಿಸು" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "ಕುಗ್ಗಿಸು(_n)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "ಹಿಗ್ಗಿಸು(_x)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "ಹಿಗ್ಗಿಸಬೇಡ(_x)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "ಉರುಳಿಸು (_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "ಸುತ್ತಿ (_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "ಜರುಗಿಸು(_M)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "ಗಾತ್ರ ಬದಲಾಯಿಸು(_R)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "ಶೀರ್ಷಿಕೆಪಟ್ಟಿಯನ್ನು ತೆರೆಯ ಮೇಲೆ ಸ್ಥಳಾಂತರಿಸು (_s)" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "ಯಾವಾಗಲೂ ಮೇಲ್ಭಾಗದಲ್ಲಿ(_T)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "ಯಾವಾಗಲೂ ಕಾಣಿಸುವ ಕಾರ್ಯಕ್ಷೇತ್ರದಲ್ಲಿ(_A)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "ಕೇವಲ ಈ ಕಾರ್ಯಕ್ಷೇತ್ರದಲ್ಲಿ (_O)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "ಎಡಭಾಗದ ಕಾರ್ಯಕ್ಷೇತ್ರಕ್ಕೆ ವರ್ಗಾಯಿಸು(_L)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "ಬಲಭಾಗದ ಕಾರ್ಯಕ್ಷೇತ್ರಕ್ಕೆ ವರ್ಗಾಯಿಸು(_i)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "ಮೇಲಿನ ಕಾರ್ಯಕ್ಷೇತ್ರಕ್ಕೆ ವರ್ಗಾಯಿಸು(_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "ಕೆಳಗಿನ ಕಾರ್ಯಕ್ಷೇತ್ರಕ್ಕೆ ವರ್ಗಾಯಿಸು(_D)" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "ಮುಚ್ಚು(_C)" - -#: ../src/ui/menu.c:204 -#, c-format -#| msgid "Workspace %d" -msgid "Workspace %d%n" -msgstr "ಕಾರ್ಯಕ್ಷೇತ್ರ %d%n" - -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "ಕಾರ್ಯಕ್ಷೇತ್ರ 1_0" - -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "ಕಾರ್ಯಕ್ಷೇತ್ರ %s%d" - -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "ಇನ್ನೊಂದು ಕಾರ್ಯಕ್ಷೇತ್ರಕ್ಕೆ ವರ್ಗಾಯಿಸು(_W)" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "ಮೆಟಾ" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "ಸೂಪರ್" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "ಹೈಪರ್" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" - -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" - -#: ../src/ui/theme.c:255 -msgid "top" -msgstr "ಮೇಲ್ಭಾಗ" - -#: ../src/ui/theme.c:257 -msgid "bottom" -msgstr "ಕೆಳಭಾಗ" - -#: ../src/ui/theme.c:259 -msgid "left" -msgstr "ಎಡಭಾಗ" - -#: ../src/ui/theme.c:261 -msgid "right" -msgstr "ಬಲಭಾಗ" - -#: ../src/ui/theme.c:288 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "ಚೌಕಟ್ಟಿನ ಜ್ಯಾಮಿತಿಯು \"%s\" ಆಯಾಮವನ್ನು ಸೂಚಿಸುವುದಿಲ್ಲ" - -#: ../src/ui/theme.c:307 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "ಚೌಕಟ್ಟಿನ ಜ್ಯಾಮಿತಿಯು \"%s\" ಆಯಾಮವನ್ನು \"%s\" ಅಂಚಿಗಾಗಿ ಸೂಚಿಸುವುದಿಲ್ಲ" - -#: ../src/ui/theme.c:344 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "" - -#: ../src/ui/theme.c:356 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "ಚೌಕಟ್ಟಿನ ಜ್ಯಾಮಿತಿಯು ಗುಂಡಿಗಳ ಗಾತ್ರವನ್ನು ಸೂಚಿಸುವುದಿಲ್ಲ" - -#: ../src/ui/theme.c:1064 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "" - -#: ../src/ui/theme.c:1202 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" - -#: ../src/ui/theme.c:1216 -#, c-format -msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "" - -#: ../src/ui/theme.c:1227 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "" - -#: ../src/ui/theme.c:1240 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "" - -#: ../src/ui/theme.c:1270 -#, c-format -msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" -msgstr "" - -#: ../src/ui/theme.c:1281 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "" - -#: ../src/ui/theme.c:1291 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "" - -#: ../src/ui/theme.c:1338 -#, c-format -msgid "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "" - -#: ../src/ui/theme.c:1349 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "" - -#: ../src/ui/theme.c:1359 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "" - -#: ../src/ui/theme.c:1388 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "" - -#: ../src/ui/theme.c:1646 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "" - -#: ../src/ui/theme.c:1673 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "" - -#: ../src/ui/theme.c:1687 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "" - -#: ../src/ui/theme.c:1809 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "" - -#: ../src/ui/theme.c:1866 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "" - -#: ../src/ui/theme.c:1977 ../src/ui/theme.c:1987 ../src/ui/theme.c:2021 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "" - -#: ../src/ui/theme.c:2029 -#, c-format -msgid "Coordinate expression tries to use mod operator on a floating-point number" -msgstr "" - -#: ../src/ui/theme.c:2085 -#, c-format -msgid "Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "" - -#: ../src/ui/theme.c:2094 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "" - -#: ../src/ui/theme.c:2102 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "" - -#: ../src/ui/theme.c:2112 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" - -#: ../src/ui/theme.c:2263 ../src/ui/theme.c:2308 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "" - -#: ../src/ui/theme.c:2362 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "" - -#: ../src/ui/theme.c:2391 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "" - -#: ../src/ui/theme.c:2455 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "" - -#: ../src/ui/theme.c:2466 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "" - -#: ../src/ui/theme.c:2676 ../src/ui/theme.c:2696 ../src/ui/theme.c:2716 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "" - -#: ../src/ui/theme.c:4410 -#, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> ವು ಈ ಚೌಕಟ್ಟಿನ " -"ಶೈಲಿಗೆ ಸೂಚಿತಗೊಳ್ಳಬೇಕು" - -#: ../src/ui/theme.c:4940 ../src/ui/theme.c:4965 -#, c-format -msgid "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" +"User-defined constants must begin with a capital letter; \"%s\" does not" msgstr "" -"<frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/> ಕಾಣುತ್ತಿಲ್ಲ" - -#: ../src/ui/theme.c:5013 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "\"%s\" ಥೀಮನ್ನು ಲೋಡ್‍ ಮಾಡಲು ವಿಫಲಗೊಂಡಿದೆ: %s\n" - -#: ../src/ui/theme.c:5149 ../src/ui/theme.c:5156 ../src/ui/theme.c:5163 -#: ../src/ui/theme.c:5170 ../src/ui/theme.c:5177 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "" - -#: ../src/ui/theme.c:5185 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" - -#: ../src/ui/theme.c:5635 ../src/ui/theme.c:5697 ../src/ui/theme.c:5760 -#, c-format -msgid "User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" -"ಬಳಕೆದಾರರಿಂದ ಸೂಚಿತಗೊಂಡ ಸ್ಥಿರಾಂಕಗಳು ಕ್ಯಾಪಿಟಲ್ ಅಕ್ಷರಗಳಿಂದ ಆರಂಭಗೊಳ್ಳಬೇಕು; ಆದರೆ \"%s\" " +"ಬಳಕೆದಾರರಿಂದ ಸೂಚಿತಗೊಂಡ ಸ್ಥಿರಾಂಕಗಳು ಕ್ಯಾಪಿಟಲ್ ಅಕ್ಷರಗಳಿಂದ ಆರಂಭಗೊಳ್ಳಬೇಕು; ಆದರೆ \"%" +"s\" " "ಹೊಂದಿಲ್ಲ" -#: ../src/ui/theme.c:5643 ../src/ui/theme.c:5705 ../src/ui/theme.c:5768 +#: ../src/ui/theme.c:5628 ../src/ui/theme.c:5690 ../src/ui/theme.c:5753 #, c-format msgid "Constant \"%s\" has already been defined" msgstr "\"%s\" ಸ್ತಿರಾಂಕವು ಈಗಾಗಲೆ ಸೂಚಿತಗೊಂಡಿದೆ" @@ -1290,2009 +955,791 @@ msgstr "\"%s\" ಸ್ತಿರಾಂಕವು ಈಗಾಗಲೆ ಸೂಚಿತ #. Translators: This means that an attribute which should have been found #. * on an XML element was not in fact found. #. -#: ../src/ui/theme-parser.c:236 +#: ../src/ui/theme-parser.c:234 #, c-format -#| msgid "No \"x\" attribute on element <%s>" msgid "No \"%s\" attribute on element <%s>" msgstr "\"%s\" ಗುಣ ವಿಶೇಷವು <%s> ಘಟಕದಲ್ಲಿ ಇಲ್ಲ" -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 +#: ../src/ui/theme-parser.c:263 ../src/ui/theme-parser.c:281 #, c-format msgid "Line %d character %d: %s" msgstr "ಸಾಲು %d ಅಕ್ಷರ %d: %s" -#: ../src/ui/theme-parser.c:479 +#: ../src/ui/theme-parser.c:481 #, c-format msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "" +msgstr "ವೈಶಿಷ್ಟ್ಯ \"%s\" ವು <%s> ಘಟಕದಲ್ಲಿ ಎರಡು ಬಾರಿ ಪುನರಾವರ್ತಿತವಾಗಿದೆ" -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 +#: ../src/ui/theme-parser.c:505 ../src/ui/theme-parser.c:554 #, c-format msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "" +msgstr "ಗುಣವಿಶೇಷ \"%s\" ವು ಈ ಸನ್ನಿವೇಶದಲ್ಲಿನ <%s> ಅಂಶದಲ್ಲಿ ಅಮಾನ್ಯವಾಗಿದೆ" -#: ../src/ui/theme-parser.c:594 +#: ../src/ui/theme-parser.c:596 #, c-format msgid "Could not parse \"%s\" as an integer" msgstr "\"%s\" ಅನ್ನು ಒಂದು ಪೂರ್ಣಾಂಕವಾಗಿ ಪಾರ್ಸ್ ಮಾಡಲಾಗಿಲ್ಲ" -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 +#: ../src/ui/theme-parser.c:605 ../src/ui/theme-parser.c:660 #, c-format msgid "Did not understand trailing characters \"%s\" in string \"%s\"" msgstr "" +"\"%s\" ಹಿಂದಿರುವ ಅಕ್ಷರಗಳನ್ನು (ವಾಕ್ಯ \"%s\" ದಲ್ಲಿ) ಅರ್ಥ ಮಾಡಿಕೊಳ್ಳಲು ಸಾಧ್ಯವಾಗಿಲ್ಲ" -#: ../src/ui/theme-parser.c:613 +#: ../src/ui/theme-parser.c:615 #, c-format msgid "Integer %ld must be positive" msgstr "%ld ಪೂರ್ಣಾಂಕವು ಧನವಾಗಿರಬೇಕು" -#: ../src/ui/theme-parser.c:621 +#: ../src/ui/theme-parser.c:623 #, c-format msgid "Integer %ld is too large, current max is %d" msgstr "%ld ಪೂರ್ಣಾಂಕವು ಬಹಳ ದೊಡ್ಡದಾಗಿದೆ, ಈಗಿನ ಗರಿಷ್ಟವು %d ಆಗಿದೆ" -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 +#: ../src/ui/theme-parser.c:651 ../src/ui/theme-parser.c:767 #, c-format msgid "Could not parse \"%s\" as a floating point number" msgstr "" +"\"%s\" ಅನ್ನು ಒಂದು ತೇಲುವ ಬಿಂದು (ಫ್ಲೋಟಿಂಗ್ ಪಾಯಿಂಟ್‌) ಸಂಖ್ಯೆಯಾಗಿ ಪಾರ್ಸ್ ಮಾಡಲು " +"ಸಾಧ್ಯವಾಗಿಲ್ಲ" -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 +#: ../src/ui/theme-parser.c:682 ../src/ui/theme-parser.c:710 #, c-format msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "" +msgstr "ಬೂಲಿಯನ್ ಮೌಲ್ಯಗಳು \"true\" ಅಥವ \"false\" ಆಗಿರಬೇಕೆ ಹೊರತು \"%s\" ಅಲ್ಲ" -#: ../src/ui/theme-parser.c:735 +#: ../src/ui/theme-parser.c:737 #, c-format msgid "Angle must be between 0.0 and 360.0, was %g\n" msgstr "ಕೋನವು 0.0 ಹಾಗು 360.0 ನಡುವೆ ಇರಬೇಕು, %g ಆಗಿದೆ\n" -#: ../src/ui/theme-parser.c:798 +#: ../src/ui/theme-parser.c:800 #, c-format msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" +msgstr "ಆಲ್ಫಾವು 0.0 (ಅಗೋಚರ) ಹಾಗು 1.0 (ಸಂಪೂರ್ಣ ಅಪಾರದರ್ಶಕ), %g ಆಗಿಲ್ಲ\n" -#: ../src/ui/theme-parser.c:863 +#: ../src/ui/theme-parser.c:865 #, c-format msgid "" "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," "large,x-large,xx-large)\n" msgstr "" +"ಅಮಾನ್ಯವಾದ ಶೀರ್ಷಿಕೆ ಅಳತೆ \"%s\" (ಇದು xx-small,x-small,small,medium,large,x-" +"large,xx-large ಗಳಲ್ಲಿ ಒಂದನ್ನು ಹೊಂದಿರಬೇಕು)\n" -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 +#: ../src/ui/theme-parser.c:1021 ../src/ui/theme-parser.c:1084 +#: ../src/ui/theme-parser.c:1118 ../src/ui/theme-parser.c:1221 #, c-format msgid "<%s> name \"%s\" used a second time" msgstr "<%s> ಹೆಸರು \"%s\" ಎರಡನೆಯ ಬಾರಿಗೆ ಬಳಸಲಾಗಿದೆ" -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 +#: ../src/ui/theme-parser.c:1033 ../src/ui/theme-parser.c:1130 +#: ../src/ui/theme-parser.c:1233 #, c-format msgid "<%s> parent \"%s\" has not been defined" msgstr "<%s> ಮೂಲ \"%s\" ಅನ್ನು ಸೂಚಿಸಲಾಗಿಲ್ಲ" -#: ../src/ui/theme-parser.c:1141 +#: ../src/ui/theme-parser.c:1143 #, c-format msgid "<%s> geometry \"%s\" has not been defined" msgstr "<%s> ಜ್ಯಾಮಿತಿಯು \"%s\" ಸೂಚಿತಗೊಂಡಿಲ್ಲ" -#: ../src/ui/theme-parser.c:1154 +#: ../src/ui/theme-parser.c:1156 #, c-format msgid "<%s> must specify either a geometry or a parent that has a geometry" msgstr "" +"<%s> ಯು ಒಂದೋ ಜ್ಯಾಮಿತಿಯನ್ನು ಅಥವ ಒಂದು ಜ್ಯಾಮಿತಿಯನ್ನು ಹೊಂದಿರುವ ಮೂಲವನ್ನು ಸೂಚಿಸಬೇಕು" -#: ../src/ui/theme-parser.c:1196 +#: ../src/ui/theme-parser.c:1198 msgid "You must specify a background for an alpha value to be meaningful" msgstr "" +"ಒಂದು ಆಲ್ಫಾ ಮೌಲ್ಯವು ಅರ್ಥಬದ್ಧವಾಗಿರಬೇಕೆಂದರೆ ನೀವು ಅದಕ್ಕಾಗಿ ಒಂದು ಹಿನ್ನಲೆಯನ್ನು " +"ಸೂಚಿಸಬೇಕು" -#: ../src/ui/theme-parser.c:1264 +#: ../src/ui/theme-parser.c:1266 #, c-format msgid "Unknown type \"%s\" on <%s> element" msgstr "ಗೊತ್ತಿರದ ಬಗೆ \"%s\", <%s> ಘಟಕದಲ್ಲಿ" -#: ../src/ui/theme-parser.c:1275 +#: ../src/ui/theme-parser.c:1277 #, c-format msgid "Unknown style_set \"%s\" on <%s> element" msgstr "ಗೊತ್ತಿರದ style_set \"%s\", <%s> ಘಟಕದಲ್ಲಿ" -#: ../src/ui/theme-parser.c:1283 +#: ../src/ui/theme-parser.c:1285 #, c-format msgid "Window type \"%s\" has already been assigned a style set" -msgstr "" +msgstr "ಕಿಟಕಿ ಬಗೆ \"%s\" ಈಗಾಗಲೆ ಶೈಲಿ ಜೋಡಿಯನ್ನು ನಿಯೋಜಿಸಿದೆ" -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 +#: ../src/ui/theme-parser.c:1315 ../src/ui/theme-parser.c:1379 +#: ../src/ui/theme-parser.c:1605 ../src/ui/theme-parser.c:2840 +#: ../src/ui/theme-parser.c:2886 ../src/ui/theme-parser.c:3036 +#: ../src/ui/theme-parser.c:3272 ../src/ui/theme-parser.c:3310 +#: ../src/ui/theme-parser.c:3348 ../src/ui/theme-parser.c:3386 #, c-format msgid "Element <%s> is not allowed below <%s>" -msgstr "" +msgstr "ಅಂಶ <%s> ವು <%s> ನ ಕೆಳಗೆ ಅನುಮತಿ ಇಲ್ಲ" -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 +#: ../src/ui/theme-parser.c:1429 ../src/ui/theme-parser.c:1443 +#: ../src/ui/theme-parser.c:1488 msgid "" "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " "for buttons" msgstr "" +"ಗುಂಡಿಗಳಿಗಾಗಿ \"button_width\"/\"button_height\" ಹಾಗು \"aspect_ratio\" " +"ಇವೆರಡನ್ನೂ ಸೂಚಿಸಲಾಗಿಲ್ಲ" -#: ../src/ui/theme-parser.c:1450 +#: ../src/ui/theme-parser.c:1452 #, c-format msgid "Distance \"%s\" is unknown" msgstr "ದೂರ \"%s\" ವು ತಿಳಿದಿಲ್ಲ" -#: ../src/ui/theme-parser.c:1495 +#: ../src/ui/theme-parser.c:1497 #, c-format msgid "Aspect ratio \"%s\" is unknown" msgstr "ಆಕಾರ ಅನುಪಾತ \"%s\" ಅಜ್ಞಾತವಾಗಿದೆ" -#: ../src/ui/theme-parser.c:1557 +#: ../src/ui/theme-parser.c:1559 #, c-format msgid "Border \"%s\" is unknown" msgstr "ಗೊತ್ತಿರದ \"%s\" ಅಂಚು" -#: ../src/ui/theme-parser.c:1868 +#: ../src/ui/theme-parser.c:1870 #, c-format msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "" +msgstr "<%s> ಘಟಕದಲ್ಲಿ ಯಾವುದೆ \"start_angle\" ಅಥವ \"from\" ಗುಣವಿಶೇಷವು ಇಲ್ಲ" -#: ../src/ui/theme-parser.c:1875 +#: ../src/ui/theme-parser.c:1877 #, c-format msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "" +msgstr "<%s> ಘಟಕದಲ್ಲಿ ಯಾವುದೆ \"extent_angle\" ಅಥವ \"to\" ಗುಣವಿಶೇಷವು ಇಲ್ಲ" -#: ../src/ui/theme-parser.c:2115 +#: ../src/ui/theme-parser.c:2117 #, c-format msgid "Did not understand value \"%s\" for type of gradient" -msgstr "" +msgstr "ಗ್ರೇಡಿಯಂಟ್‌ನ ಬಗೆಗೆ ಮೌಲ್ಯ \"%s\" ವು ಅರ್ಥವಾಗಿಲ್ಲ" -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 +#: ../src/ui/theme-parser.c:2195 ../src/ui/theme-parser.c:2570 #, c-format msgid "Did not understand fill type \"%s\" for <%s> element" msgstr "\"%s\" ತುಂಬಿಸುವ ಬಗೆಯನ್ನು <%s> ಘಟಕಕ್ಕಾಗಿ ಅರ್ಥಮಾಡಿಕೊಳ್ಳಲಾಗಲಿಲ್ಲ" -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 +#: ../src/ui/theme-parser.c:2362 ../src/ui/theme-parser.c:2445 +#: ../src/ui/theme-parser.c:2508 #, c-format msgid "Did not understand state \"%s\" for <%s> element" msgstr "\"%s\" ಸ್ಥಿತಿಯನ್ನು <%s> ಘಟಕಕ್ಕಾಗಿ ಅರ್ಥಮಾಡಿಕೊಳ್ಳಲಾಗಲಿಲ್ಲ" -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 +#: ../src/ui/theme-parser.c:2372 ../src/ui/theme-parser.c:2455 #, c-format msgid "Did not understand shadow \"%s\" for <%s> element" msgstr "\"%s\" ಛಾಯೆಯನ್ನು <%s> ಘಟಕಕ್ಕಾಗಿ ಅರ್ಥಮಾಡಿಕೊಳ್ಳಲಾಗಲಿಲ್ಲ" -#: ../src/ui/theme-parser.c:2380 +#: ../src/ui/theme-parser.c:2382 #, c-format msgid "Did not understand arrow \"%s\" for <%s> element" msgstr "\"%s\" ಬಾಣದ ಗುರುತನ್ನು <%s> ಘಟಕಕ್ಕಾಗಿ ಅರ್ಥಮಾಡಿಕೊಳ್ಳಲಾಗಲಿಲ್ಲ" -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 +#: ../src/ui/theme-parser.c:2696 ../src/ui/theme-parser.c:2792 #, c-format msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "" +msgstr "ಯಾವುದೆ <draw_ops> ಕರೆ \"%s\" ಅನ್ನು ಸೂಚಿಸಲಾಗಿಲ್ಲ" -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 +#: ../src/ui/theme-parser.c:2708 ../src/ui/theme-parser.c:2804 #, c-format msgid "Including draw_ops \"%s\" here would create a circular reference" msgstr "" +"ಇಲ್ಲಿ draw_ops \"%s\" ಅನ್ನು ಸೇರಿಸುವುದರಿಂದ ಒಂದು ವೃತ್ತಾಕಾರದ ಉಲ್ಲೇಖವನ್ನು " +"ನಿರ್ಮಿಸುತ್ತದೆ" -#: ../src/ui/theme-parser.c:2917 +#: ../src/ui/theme-parser.c:2919 #, c-format msgid "Unknown position \"%s\" for frame piece" -msgstr "" +msgstr "ಚೌಕಟ್ಟು ಅಂಶಕ್ಕಾಗಿ ತಿಳಿಯದ ಸ್ಥಾನ \"%s\"" -#: ../src/ui/theme-parser.c:2925 +#: ../src/ui/theme-parser.c:2927 #, c-format msgid "Frame style already has a piece at position %s" -msgstr "" +msgstr "%s ಸ್ಥಾನದಲ್ಲಿ ಚೌಕಟ್ಟು ಶೈಲಿಯು ಈಗಾಗಲೆ ಅಸ್ತಿತ್ವದಲ್ಲಿದೆ" -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 +#: ../src/ui/theme-parser.c:2944 ../src/ui/theme-parser.c:3021 #, c-format msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "" +msgstr "\"%s\" ಹೆಸರಿನ ಯಾವುದೆ <draw_ops> ಆಯ್ಕೆಯನ್ನು ಸೂಚಿಸಲಾಗಿಲ್ಲ" -#: ../src/ui/theme-parser.c:2972 +#: ../src/ui/theme-parser.c:2974 #, c-format msgid "Unknown function \"%s\" for button" msgstr "\"%s\" ಗುಂಡಿಗಾಗಿ ಅಜ್ಞಾತ ಕ್ರಿಯೆ" -#: ../src/ui/theme-parser.c:2982 +#: ../src/ui/theme-parser.c:2984 #, c-format msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "" +msgstr "ಈ ಆವೃತ್ತಿಯಲ್ಲಿ ಗುಂಡಿ ಕ್ರಿಯೆ \"%s\" ಯು ಲಭ್ಯವಿಲ್ಲ (%d, %d ಅಗತ್ಯವಿದೆ)" -#: ../src/ui/theme-parser.c:2994 +#: ../src/ui/theme-parser.c:2996 #, c-format msgid "Unknown state \"%s\" for button" msgstr "\"%s\" ಗುಂಡಿಗಾಗಿ ಗೊತ್ತಿರದ ಸ್ಥಿತಿ" -#: ../src/ui/theme-parser.c:3002 +#: ../src/ui/theme-parser.c:3004 #, c-format msgid "Frame style already has a button for function %s state %s" msgstr "" +"ಸ್ಥಿತಿ %s ಗಮನ %s ಕ್ಕಾಗಿ ಚೌಕಟ್ಟು ಶೈಲಿಯಲ್ಲಿ ಒಂದು ಗುಂಡಿಯನ್ನು ಈಗಾಗಲೆ ಸೂಚಿಸಲಾಗಿದೆ" -#: ../src/ui/theme-parser.c:3073 +#: ../src/ui/theme-parser.c:3075 #, c-format msgid "\"%s\" is not a valid value for focus attribute" -msgstr "" +msgstr "\"%s\" ಯು ಗಮನ ಗುಣ ವಿಶೇಷಕ್ಕೆ ಒಂದು ಮಾನ್ಯವಾದ ಮೌಲ್ಯವಲ್ಲ" -#: ../src/ui/theme-parser.c:3082 +#: ../src/ui/theme-parser.c:3084 #, c-format msgid "\"%s\" is not a valid value for state attribute" -msgstr "" +msgstr "\"%s\" ಯು ಸ್ಥಿತಿ ಗುಣ ವಿಶೇಷಕ್ಕೆ ಒಂದು ಮಾನ್ಯವಾದ ಮೌಲ್ಯವಲ್ಲ" -#: ../src/ui/theme-parser.c:3092 +#: ../src/ui/theme-parser.c:3094 #, c-format msgid "A style called \"%s\" has not been defined" msgstr "\"%s\" ಎಂದು ಕರೆಯಲ್ಪಡುವ ಒಂದು ಶೈಲಿಯು ಸೂಚಿತಗೊಂಡಿಲ್ಲ" -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 +#: ../src/ui/theme-parser.c:3115 ../src/ui/theme-parser.c:3138 #, c-format msgid "\"%s\" is not a valid value for resize attribute" -msgstr "" +msgstr "\"%s\" ಯು ಗಾತ್ರ ಬದಲಾವಣೆ ಗುಣ ವಿಶೇಷಕ್ಕೆ ಒಂದು ಮಾನ್ಯವಾದ ಮೌಲ್ಯವಲ್ಲ" -#: ../src/ui/theme-parser.c:3147 +#: ../src/ui/theme-parser.c:3149 #, c-format msgid "" "Should not have \"resize\" attribute on <%s> element for maximized/shaded " "states" msgstr "" +"ಗರಿಷ್ಟಗೊಳಿಸಲಾದ/ಮಬ್ಬುಗೊಳಿಸಲಾದ ಸ್ಥಿತಿಗಳಿಗಾಗಿ <%s> ಅಂಶದಲ್ಲಿ \"resize\" " +"ಗುಣವಿಶೇಷವು " +"ಇರುವಂತಿಲ್ಲ" -#: ../src/ui/theme-parser.c:3161 +#: ../src/ui/theme-parser.c:3163 #, c-format -msgid "Should not have \"resize\" attribute on <%s> element for maximized states" +msgid "" +"Should not have \"resize\" attribute on <%s> element for maximized states" msgstr "" +"ಗರಿಷ್ಟಗೊಳಿಸಲಾದ ಸ್ಥಿತಿಗಳಿಗಾಗಿ <%s> ಅಂಶದಲ್ಲಿ \"resize\" ಗುಣವಿಶೇಷವು ಇರುವಂತಿಲ್ಲ" -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 +#: ../src/ui/theme-parser.c:3177 ../src/ui/theme-parser.c:3221 #, c-format msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "" +msgstr "ಸ್ಥಿತಿ %s ಗಾತ್ರ ಬದಲಾವಣೆ %s ಗಮನ %s ಕ್ಕಾಗಿ ಶೈಲಿಯನ್ನು ಈಗಾಗಲೆ ಸೂಚಿಸಲಾಗಿದೆ" -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 +#: ../src/ui/theme-parser.c:3188 ../src/ui/theme-parser.c:3199 +#: ../src/ui/theme-parser.c:3210 ../src/ui/theme-parser.c:3232 +#: ../src/ui/theme-parser.c:3243 ../src/ui/theme-parser.c:3254 #, c-format msgid "Style has already been specified for state %s focus %s" -msgstr "" +msgstr "ಸ್ಥಿತಿ %s ಗಮನ %s ಕ್ಕಾಗಿ ಶೈಲಿಯನ್ನು ಈಗಾಗಲೆ ಸೂಚಿಸಲಾಗಿದೆ" -#: ../src/ui/theme-parser.c:3294 +#: ../src/ui/theme-parser.c:3293 msgid "" "Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " "attribute and also a <draw_ops> element, or specified two elements)" msgstr "" +"ಒಂದು <piece> ಘಟಕದಲ್ಲಿ ಎರಡು draw_ops ಇರುವಂತಿಲ್ಲ (ಪರಿಸರವಿನ್ಯಾಸವು ಒಂದು draw_ops " +"ಗುಣವಿಶೇಷವನ್ನು ಹಾಗು ಒಂದು <draw_ops> ಘಟಕವನ್ನೂ ಸಹ ಸೂಚಿಸಿದೆ, ಅಥವ ಎರಡು ಘಟಕಗಳನ್ನು " +"ಸೂಚಿಸಿದೆ)" -#: ../src/ui/theme-parser.c:3332 +#: ../src/ui/theme-parser.c:3331 msgid "" "Can't have a two draw_ops for a <button> element (theme specified a draw_ops " "attribute and also a <draw_ops> element, or specified two elements)" msgstr "" +"ಒಂದು <button> ಘಟಕದಲ್ಲಿ ಎರಡು draw_ops ಇರುವಂತಿಲ್ಲ (ಪರಿಸರವಿನ್ಯಾಸವು ಒಂದು draw_ops " +"ಗುಣವಿಶೇಷವನ್ನು ಹಾಗು ಒಂದು <draw_ops> ಘಟಕವನ್ನೂ ಸಹ ಸೂಚಿಸಿದೆ, ಅಥವ ಎರಡು ಘಟಕಗಳನ್ನು " +"ಸೂಚಿಸಿದೆ)" -#: ../src/ui/theme-parser.c:3370 +#: ../src/ui/theme-parser.c:3369 msgid "" "Can't have a two draw_ops for a <menu_icon> element (theme specified a " "draw_ops attribute and also a <draw_ops> element, or specified two elements)" msgstr "" +"ಒಂದು <menu_icon> ಘಟಕದಲ್ಲಿ ಎರಡು draw_ops ಇರುವಂತಿಲ್ಲ (ಪರಿಸರವಿನ್ಯಾಸವು ಒಂದು " +"draw_ops ಗುಣವಿಶೇಷವನ್ನು ಹಾಗು ಒಂದು <draw_ops> ಘಟಕವನ್ನೂ ಸಹ ಸೂಚಿಸಿದೆ, ಅಥವ ಎರಡು " +"ಘಟಕಗಳನ್ನು ಸೂಚಿಸಿದೆ)" -#: ../src/ui/theme-parser.c:3434 +#: ../src/ui/theme-parser.c:3433 #, c-format msgid "Bad version specification '%s'" msgstr "ತಪ್ಪು ಆವೃತ್ತಿ ವಿವರಣೆ '%s'" -#: ../src/ui/theme-parser.c:3507 +#: ../src/ui/theme-parser.c:3506 msgid "" "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" "theme-2.xml" msgstr "" +"\"version\" ಗುಣವಿಶೇಷವನ್ನು metacity-theme-1.xml ಅಥವ metacity-theme-2.xml ನಲ್ಲಿ " +"ಬಳಸಲು ಸಾಧ್ಯವಿರುವುದಿಲ್ಲ" -#: ../src/ui/theme-parser.c:3530 +#: ../src/ui/theme-parser.c:3529 #, c-format msgid "Theme requires version %s but latest supported theme version is %d.%d" msgstr "" +"ಪರಿಸರ ವಿನ್ಯಾಸಕ್ಕಾಗಿ ಆವೃತ್ತಿ %s ಅಗತ್ಯವಿದೆ ಆದರೆ ಇತ್ತೀಚಿನ ಬೆಂಬಲಿತ ಪರಿಸರವಿನ್ಯಾಸ " +"ಆವೃತ್ತಿಯು %d.%d ಆಗಿದೆ" -#: ../src/ui/theme-parser.c:3562 +#: ../src/ui/theme-parser.c:3561 #, c-format msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "" +msgstr "ಅತ್ಯಂತ ಹೊರಗಿನ ಪರಿಸರವಿನ್ಯಾಸವು <metacity_theme> ಆಗಿರಬೇಕೆ ಹೊರತು <%s> ಅಲ್ಲ" -#: ../src/ui/theme-parser.c:3582 +#: ../src/ui/theme-parser.c:3581 #, c-format -msgid "Element <%s> is not allowed inside a name/author/date/description element" +msgid "" +"Element <%s> is not allowed inside a name/author/date/description element" msgstr "<%s> ಘಟಕಕ್ಕೆ ಒಂದು ಹೆಸರು/ಲೇಖಕ/ದಿನಾಂಕ/ವಿವರಣೆಯ ಒಳಗೆ ಇರಲು ಅನುಮತಿ ಇಲ್ಲ" -#: ../src/ui/theme-parser.c:3587 +#: ../src/ui/theme-parser.c:3586 #, c-format msgid "Element <%s> is not allowed inside a <constant> element" msgstr "<%s> ಘಟಕಕ್ಕೆ ಒಂದು <constant> ಘಟಕದ ಒಳಗೆ ಇರಲು ಅನುಮತಿ ಇಲ್ಲ" -#: ../src/ui/theme-parser.c:3599 +#: ../src/ui/theme-parser.c:3598 #, c-format -msgid "Element <%s> is not allowed inside a distance/border/aspect_ratio element" +msgid "" +"Element <%s> is not allowed inside a distance/border/aspect_ratio element" msgstr "" +"ಒಂದು ದೂರ/ಅಂಚು/ಆಕಾರ ಅನುಪಾತ(aspect_ratio) ಘಟಕದ ಒಳಗೆ ಘಟಕ <%s> ಕ್ಕೆ ಅನುಮತಿ ಇಲ್ಲ" -#: ../src/ui/theme-parser.c:3621 +#: ../src/ui/theme-parser.c:3620 #, c-format msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "" +msgstr "ಒಂದು ಎಳೆಯುವಿಕೆ ಕಾರ್ಯದ ಒಳಗೆ ಘಟಕ <%s> ಕ್ಕೆ ಅನುಮತಿ ಇಲ್ಲ" -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 +#: ../src/ui/theme-parser.c:3630 ../src/ui/theme-parser.c:3660 +#: ../src/ui/theme-parser.c:3665 ../src/ui/theme-parser.c:3670 #, c-format msgid "Element <%s> is not allowed inside a <%s> element" msgstr "<%s> ಘಟಕಕ್ಕೆ ಒಂದು <%s> ಘಟಕದ ಒಳಗೆ ಇರಲು ಅನುಮತಿ ಇಲ್ಲ" -#: ../src/ui/theme-parser.c:3899 +#: ../src/ui/theme-parser.c:3898 msgid "No draw_ops provided for frame piece" -msgstr "" +msgstr "ಚೌಕಟ್ಟಿನ ಅಂಶಕ್ಕಾಗಿ ಯಾವುದೆ draw_ops ಅನ್ನು ಒದಗಿಸಲಾಗಿಲ್ಲ" -#: ../src/ui/theme-parser.c:3914 +#: ../src/ui/theme-parser.c:3913 msgid "No draw_ops provided for button" msgstr "ಗುಂಡಿಗಾಗಿ draw_ops ಅನ್ನು ಒದಗಿಸಲಾಗಿಲ್ಲ" -#: ../src/ui/theme-parser.c:3968 +#: ../src/ui/theme-parser.c:3967 #, c-format msgid "No text is allowed inside element <%s>" msgstr "<%s> ಘಟಕದ ಒಳಗೆ ಯಾವುದೆ ಪಠ್ಯಕ್ಕೆ ಅನುಮತಿ ಇಲ್ಲ" -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 +#: ../src/ui/theme-parser.c:4025 ../src/ui/theme-parser.c:4037 +#: ../src/ui/theme-parser.c:4049 ../src/ui/theme-parser.c:4061 +#: ../src/ui/theme-parser.c:4073 #, c-format -#| msgid "<name> specified twice for this theme" msgid "<%s> specified twice for this theme" msgstr "<%s> ಈ ಪರಿಸರವಿನ್ಯಾಸ ಎರಡು ಬಾರಿ ಸೂಚಿಸಲ್ಪಟ್ಟಿದೆ" -#: ../src/ui/theme-parser.c:4348 +#: ../src/ui/theme-parser.c:4335 #, c-format msgid "Failed to find a valid file for theme %s\n" msgstr "%s ಥೀಮ್‍ಗೆ ಒಂದು ಮಾನ್ಯವಾದ ಕಡತವನ್ನು ಪತ್ತೆ ಮಾಡುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ\n" -#: ../src/ui/theme-viewer.c:99 -#| msgid "/_Windows" -msgid "_Windows" -msgstr "ವಿಂಡೋಗಳು (_W)" - -#: ../src/ui/theme-viewer.c:100 -#| msgid "Dialog Box" -msgid "_Dialog" -msgstr "ಸಂವಾದ (_D)" - -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "ಮೋಡಲ್ ಸಂವಾದ (_M)" - -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "ಸವಲತ್ತು (_U)" - -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "ಎರಚುತೆರೆ (_S)" - -#: ../src/ui/theme-viewer.c:104 -#| msgid "/Windows/_Top dock" -msgid "_Top dock" -msgstr "ಮೇಲ್ಭಾಗ ಡಾಕ್ (_T)" - -#: ../src/ui/theme-viewer.c:105 -#| msgid "/Windows/_Bottom dock" -msgid "_Bottom dock" -msgstr "ಕೆಳಭಾಗದ ಡಾಕ್ (_B)" - -#: ../src/ui/theme-viewer.c:106 -#| msgid "/Windows/_Left dock" -msgid "_Left dock" -msgstr "ಎಡಬದಿಯ ಡಾಕ್ (_L)" - -#: ../src/ui/theme-viewer.c:107 -#| msgid "/Windows/_Right dock" -msgid "_Right dock" -msgstr "ಬಲಬದಿಯ ಡಾಕ್ (_R)" - -#: ../src/ui/theme-viewer.c:108 -#| msgid "/Windows/_All docks" -msgid "_All docks" -msgstr "ಎಲ್ಲಾ ಡಾಕ್‌ಗಳು (_A)" - -#: ../src/ui/theme-viewer.c:109 -#| msgid "Desktop" -msgid "Des_ktop" -msgstr "ಗಣಕತೆರೆ (_k)" - -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "ಈ ವಿಂಡೋಗಳಲ್ಲಿ ಬೇರೊಂದನ್ನು ತೆರೆ" - -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "'ತೆರೆ' ಚಿಹ್ನೆಯನ್ನು ಹೊಂದಿರುವ ಒಂದು ಪ್ರಾಯೋಗಿಕ ಗುಂಡಿ" - -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "'ತ್ಯಜಿಸು' ಚಿಹ್ನೆಯನ್ನು ಹೊಂದಿರುವ ಒಂದು ಪ್ರಾಯೋಗಿಕ ಗುಂಡಿ" - -#: ../src/ui/theme-viewer.c:253 -msgid "This is a sample message in a sample dialog" -msgstr "ಇದು ಒಂದು ಸಂವಾದದ ನಮೂನೆಯಲ್ಲಿರುವ ಒಂದು ಸಂದೇಶದ ನಮೂನೆ" - -#: ../src/ui/theme-viewer.c:336 -#, c-format -msgid "Fake menu item %d\n" -msgstr "ನಕಲಿ ಮೆನು ಅಂಶ %d\n" - -#: ../src/ui/theme-viewer.c:370 -msgid "Border-only window" -msgstr "ಅಂಚು ಮಾತ್ರ ಇರುವ ವಿಂಡೊ" - -#: ../src/ui/theme-viewer.c:372 -msgid "Bar" -msgstr "ಪಟ್ಟಿ" - -#: ../src/ui/theme-viewer.c:389 -msgid "Normal Application Window" -msgstr "ಸಾಮಾನ್ಯ ಅನ್ವಯ ವಿಂಡೊ" - -#: ../src/ui/theme-viewer.c:393 -msgid "Dialog Box" -msgstr "ಸಂವಾದ ಪೆಟ್ಟಿಗೆ" - -#: ../src/ui/theme-viewer.c:397 -msgid "Modal Dialog Box" -msgstr "ಮೋಡಲ್ ಸಂವಾದ ಚೌಕ" - -#: ../src/ui/theme-viewer.c:401 -msgid "Utility Palette" -msgstr "ಸವಲತ್ತು ಫಲಕ" - -#: ../src/ui/theme-viewer.c:405 -msgid "Torn-off Menu" -msgstr "ಹರಿಯಲ್ಪಟ್ಟ ಮೆನು" - -#: ../src/ui/theme-viewer.c:409 -msgid "Border" -msgstr "ಅಂಚು" - -#: ../src/ui/theme-viewer.c:413 -msgid "Attached Modal Dialog" -msgstr "ಲಗತ್ತಿಸಲಾದ ಮೋಡಲ್ ಸಂವಾದ" - -#: ../src/ui/theme-viewer.c:744 -#, c-format -msgid "Button layout test %d" -msgstr "ಗುಂಡಿ ಲೇಔಟ್ ಪರೀಕ್ಷೆ %d" - -#: ../src/ui/theme-viewer.c:773 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "" - -#: ../src/ui/theme-viewer.c:818 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "ಬಳಕೆ: metacity-theme-viewer [THEMENAME]\n" - -#: ../src/ui/theme-viewer.c:825 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "ಥೀಮ್ ಅನ್ನು ಲೋಡ್ ಮಾಡುವಲ್ಲಿ ದೋಷ: %s\n" - -#: ../src/ui/theme-viewer.c:831 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "\"%s\" ಥೀಮ್ %g ಸೆಕೆಂಡ್‍ಗಳಲ್ಲಿ ಲೋಡ್ ಆಗಿದೆ\n" - -#: ../src/ui/theme-viewer.c:875 -msgid "Normal Title Font" -msgstr "ಸಾಮಾನ್ಯ ಶೀರ್ಷಿಕೆ ಅಕ್ಷರಶೈಲಿ" - -#: ../src/ui/theme-viewer.c:881 -msgid "Small Title Font" -msgstr "ಚಿಕ್ಕದಾದ ಶೀರ್ಷಿಕೆ ಅಕ್ಷರಶೈಲಿ" - -#: ../src/ui/theme-viewer.c:887 -msgid "Large Title Font" -msgstr "ದೊಡ್ಡದಾದ ಶೀರ್ಷಿಕೆ ಅಕ್ಷರಶೈಲಿ" - -#: ../src/ui/theme-viewer.c:892 -msgid "Button Layouts" -msgstr "ಗುಂಡಿಗಳ ಲೇಔಟ್" - -#: ../src/ui/theme-viewer.c:897 -msgid "Benchmark" -msgstr "ಮೈಲಿಗಲ್ಲು" - -#: ../src/ui/theme-viewer.c:949 -msgid "Window Title Goes Here" -msgstr "ವಿಂಡೊ ಶೀರ್ಷಿಕೆಯು ಹೀಗೆ ಇರುತ್ತದೆ" - -#: ../src/ui/theme-viewer.c:1055 -#, c-format +#: ../src/x11/session.c:1815 msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" - -#: ../src/ui/theme-viewer.c:1274 -msgid "position expression test returned TRUE but set error" -msgstr "" - -#: ../src/ui/theme-viewer.c:1276 -msgid "position expression test returned FALSE but didn't set error" -msgstr "" - -#: ../src/ui/theme-viewer.c:1280 -msgid "Error was expected but none given" -msgstr "ದೋಷವನ್ನು ನಿರೀಕ್ಷಿಸಲಾಗಿತ್ತು ಆದರೆ ಯಾವುದೂ ಕಂಡು ಬಂದಿಲ್ಲ" - -#: ../src/ui/theme-viewer.c:1282 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "ದೋಷ %d ಅನ್ನು ನಿರೀಕ್ಷಿಸಲಾಗಿತ್ತು ಆದರೆ %d ಅನ್ನು ನೀಡಲಾಗಿದೆ" - -#: ../src/ui/theme-viewer.c:1288 -#, c-format -msgid "Error not expected but one was returned: %s" +"These windows do not support "save current setup" and will have to " +"be restarted manually next time you log in." msgstr "" +"ಈ ಕಿಟಕಿಗಳು "ಪ್ರಸಕ್ತ ಸಿದ್ಧತೆಗಳನ್ನು ಉಳಿಸು"ವುದನ್ನು ಬೆಂಬಲಿಸುವುದಿಲ್ಲ " +"ಹಾಗು " +"ನೀವು ಮುಂದಿನ ಬಾರಿ ಪ್ರವೇಶಿಸಿದಾಗ ಕೈಯಾರೆ ಅದನ್ನು ಮರಳಿ ಆರಂಭಿಸಬೇಕಾಗುತ್ತದೆ." -#: ../src/ui/theme-viewer.c:1292 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "x ಮೌಲ್ಯವು %d ಆಗಿದೆ, %d ಅನ್ನು ನಿರೀಕ್ಷಿಸಲಾಗಿತ್ತು" - -#: ../src/ui/theme-viewer.c:1295 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "y ಮೌಲ್ಯವು %d ಆಗಿದೆ, %d ಅನ್ನು ನಿರೀಕ್ಷಿಸಲಾಗಿತ್ತು" - -#: ../src/ui/theme-viewer.c:1360 +#: ../src/x11/window-props.c:515 #, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "" - -#~ msgid "Window Management" -#~ msgstr "ವಿಂಡೊ ನಿರ್ವಹಣೆ" - -#, fuzzy -#~ msgid "Failed to parse message \"%s\" from dialog process\n" -#~ msgstr "ವಿಫಲಗೊಂಡ ಸಂದೇಶ n" - -#~ msgid "Error reading from dialog display process: %s\n" -#~ msgstr "ಸಂವಾದ ಪ್ರದರ್ಶಕ ಪ್ರಕ್ರಿಯೆ ಇಂದ ಓದುವಲ್ಲಿ ದೋಷ: %s\n" - -#, fuzzy -#~ msgid "" -#~ "Error launching metacity-dialog to ask about killing an application: %s\n" -#~ msgstr "ದೋಷ ಅನ್ವಯ n" - -#~ msgid "Failed to get hostname: %s\n" -#~ msgstr "ಅತಿಥೇಯದ ಹೆಸರನ್ನು ಪಡೆಯುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ: %s\n" - -#, fuzzy -#~ msgid "Fatal IO error %d (%s) on display '%s'.\n" -#~ msgstr "ನಲ್ಲಿ n" - -#, fuzzy -#~ msgid "" -#~ "Error launching metacity-dialog to print an error about a command: %s\n" -#~ msgstr "ದೋಷ n" - -#~ msgid "Failed to restart: %s\n" -#~ msgstr "ಪುನರ್ ಆರಂಭಿಸುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ: %s\n" - -#~ msgid "Type of %s was not integer" -#~ msgstr "%s ನ ಬಗೆಯು ಪೂರ್ಣಾಂಕವಾಗಿಲ್ಲ" - -#, fuzzy -#~ msgid "" -#~ "%d stored in GConf key %s is not a reasonable cursor_size; must be in the " -#~ "range 1..128\n" -#~ msgstr "GConf n" - -#, fuzzy -#~ msgid "" -#~ "%d stored in GConf key %s is not a reasonable number of workspaces, " -#~ "current maximum is %d\n" -#~ msgstr "GConf ಸಂಖ್ಯೆ n" - -#~ msgid "Failed to read saved session file %s: %s\n" -#~ msgstr "ಉಳಿಸಲಾದ ಅಧಿವೇಶನ ಕಡತ %s ಅನ್ನು ಓದಲು ವಿಫಲಗೊಂಡಿದೆ: %s\n" - -#, fuzzy -#~ msgid "Unknown attribute %s on <metacity_session> element" -#~ msgstr "ಗೊತ್ತಿರದ ಗುಣ ವಿಶೇಷ ನಲ್ಲಿ<metacity_session>" - -#, fuzzy -#~ msgid "Unknown attribute %s on <maximized> element" -#~ msgstr "ಗೊತ್ತಿರದ ಗುಣ ವಿಶೇಷ ನಲ್ಲಿ<maximized>" - -#, fuzzy -#~ msgid "Unknown attribute %s on <geometry> element" -#~ msgstr "ಗೊತ್ತಿರದ ಗುಣ ವಿಶೇಷ ನಲ್ಲಿ<geometry>" - -#~ msgid "Metacity" -#~ msgstr "ಮೆಟಾಸಿಟಿ" - -#, fuzzy -#~ msgid "" -#~ "A font description string describing a font for window titlebars. The " -#~ "size from the description will only be used if the titlebar_font_size " -#~ "option is set to 0. Also, this option is disabled if the " -#~ "titlebar_uses_desktop_font option is set to true." -#~ msgstr "A ವಿವರಣೆ ವಾಕ್ಯ ಗೆ ವಿಂಡೊ ವಿವರಣೆ ಆಯ್ಕೆ ಆಯ್ಕೆ ಅಶಕ್ತಗೊಂಡ ಆಯ್ಕೆ ." - -#~ msgid "Arrangement of buttons on the titlebar" -#~ msgstr "ಶೀರ್ಷಿಕೆಯ ಪಟ್ಟಿಯಲ್ಲಿ ಗುಂಡಿಗಳ ವ್ಯವಸ್ಥೆಗೊಳಿಕೆ" - -#~ msgid "Commands to run in response to keybindings" -#~ msgstr "ಕೀಬೈಂಡೀಗ್‍ಗಳಿಗೆ ಪ್ರತ್ಯುತ್ತರವಾಗಿ ಚಲಾಯಿಸಬೇಕಿರುವ ಆಜ್ಞೆಗಳು" - -#, fuzzy -#~ msgid "Compositing Manager" -#~ msgstr "ಮ್ಯಾನೇಜರ್" - -#, fuzzy -#~ msgid "Control how new windows get focus" -#~ msgstr "ನಿಯಂತ್ರಣ" - -#~ msgid "Current theme" -#~ msgstr "ಈಗಿರುವ ಥೀಮ್" - -#, fuzzy -#~ msgid "Delay in milliseconds for the auto raise option" -#~ msgstr "ಗೆ auto ಆಯ್ಕೆ" - -#, fuzzy -#~ msgid "Determines whether Metacity is a compositing manager." -#~ msgstr " ." - -#, fuzzy -#~ msgid "" -#~ "Determines whether applications or the system can generate audible " -#~ "'beeps'; may be used in conjunction with 'visual bell' to allow silent " -#~ "'beeps'." -#~ msgstr "ನೊಂದಿಗೆ." - -#~ msgid "Enable Visual Bell" -#~ msgstr "ಗೋಚರ ಗಂಟೆಯನ್ನು ಶಕ್ತಗೊಳಿಸು" - -#, fuzzy -#~ msgid "" -#~ "If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " -#~ "the focused window will be automatically raised after a delay specified " -#~ "by the auto_raise_delay key. This is not related to clicking on a window " -#~ "to raise it, nor to entering a window during drag-and-drop." -#~ msgstr " ವಿಂಡೊ ನಂತರ auto ನಲ್ಲಿ ವಿಂಡೊ ವಿಂಡೊ." - -#, fuzzy -#~ msgid "" -#~ "If true, ignore the titlebar_font option, and use the standard " -#~ "application font for window titles." -#~ msgstr "ಆಯ್ಕೆ ಅನ್ವಯ ಗೆ ವಿಂಡೊ." - -#, fuzzy -#~ msgid "" -#~ "If true, metacity will give the user less feedback by using wireframes, " -#~ "avoiding animations, or other means. This is a significant reduction in " -#~ "usability for many users, but may allow legacy applications to continue " -#~ "working, and may also be a useful tradeoff for terminal servers. However, " -#~ "the wireframe feature is disabled when accessibility is on." -#~ msgstr "ಫೀಡ್-ಬ್ಯಾಕ್ ಗೆ ಗೆ ಟರ್ಮಿನಲ್ ಅಶಕ್ತಗೊಂಡ ನಲ್ಲಿ." - -#, fuzzy -#~ msgid "" -#~ "If true, then Metacity works in terms of applications rather than " -#~ "windows. The concept is a bit abstract, but in general an application-" -#~ "based setup is more like the Mac and less like Windows. When you focus a " -#~ "window in application-based mode, all the windows in the application will " -#~ "be raised. Also, in application-based mode, focus clicks are not passed " -#~ "through to windows in other applications. Application-based mode is, " -#~ "however, largely unimplemented at the moment." -#~ msgstr " ಅನ್ವಯ ವಿಂಡೋಗಳು ವಿಂಡೊ ಅನ್ವಯ ಅನ್ವಯ ಅನ್ವಯ ಅನ್ವಯ ." - -#, fuzzy -#~ msgid "If true, trade off usability for less resource usage" -#~ msgstr "ಆಫ್ ಗೆ" - -#~ msgid "Name of workspace" -#~ msgstr "ಕಾರ್ಯಕ್ಷೇತ್ರದ ಹೆಸರು" - -#~ msgid "Number of workspaces" -#~ msgstr "ಕಾರ್ಯಕ್ಷೇತ್ರಗಳ ಸಂಖ್ಯೆ" - -#, fuzzy -#~ msgid "" -#~ "Number of workspaces. Must be more than zero, and has a fixed maximum to " -#~ "prevent making the desktop unusable by accidentally asking for too many " -#~ "workspaces." -#~ msgstr "ಗೆ." - -#~ msgid "Run a defined command" -#~ msgstr "ಸೂಚಿತವಾದ ಒಂದು ಆಜ್ಞೆಯನ್ನು ಚಲಾಯಿಸು" - -#, fuzzy -#~ msgid "" -#~ "Some applications disregard specifications in ways that result in window " -#~ "manager misfeatures. This option puts Metacity in a rigorously correct " -#~ "mode, which gives a more consistent user interface, provided one does not " -#~ "need to run any misbehaving applications." -#~ msgstr "ವಿಂಡೊ ಆಯ್ಕೆ." - -#~ msgid "System Bell is Audible" -#~ msgstr "ಗಣಕಗ ಗಂಟೆಯು ಕೇಳಿಸಬಲ್ಲದು" - -#, fuzzy -#~ msgid "" -#~ "Tells Metacity how to implement the visual indication that the system " -#~ "bell or another application 'bell' indicator has been rung. Currently " -#~ "there are two valid values, \"fullscreen\", which causes a fullscreen " -#~ "white-black flash, and \"frame_flash\" which causes the titlebar of the " -#~ "application which sent the bell signal to flash. If the application which " -#~ "sent the bell is unknown (as is usually the case for the default \"system " -#~ "beep\"), the currently focused window's titlebar is flashed." -#~ msgstr "ಅನ್ವಯ ಎರಡು ಚೌಕಟ್ಟು ಅನ್ವಯ ಅನ್ವಯ ಗೊತ್ತಿರದ ಗೆ ಪೂರ್ವನಿಯೋಜಿತ ವಿಂಡೊ ." - -#, fuzzy -#~ msgid "" -#~ "The /apps/metacity/global_keybindings/run_command_N keys define " -#~ "keybindings that correspond to these commands. Pressing the keybinding " -#~ "for run_command_N will execute command_N." -#~ msgstr "N ಗೆ N N." - -#, fuzzy -#~ msgid "" -#~ "The /apps/metacity/global_keybindings/run_command_window_screenshot key " -#~ "defines a keybinding which causes the command specified by this setting " -#~ "to be invoked." -#~ msgstr "ವಿಂಡೊ." - -#, fuzzy -#~ msgid "" -#~ "The keybinding that runs the correspondingly-numbered command in /apps/" -#~ "metacity/keybinding_commands The format looks like \"<Control>a\" " -#~ "or \"<Shift><Alt>F1\". The parser is fairly liberal and " -#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" -#~ "\" and \"<Ctrl>\". If you set the option to the special string " -#~ "\"disabled\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "< ನಿಯಂತ್ರಣ>< Shift>< Alt> F1 <>< Ctrl> ಆಯ್ಕೆ " -#~ "ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." - -#~ msgid "" -#~ "The keybinding that switches to the workspace above the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "ಈಗಿರುವ ಕಾರ್ಯಕ್ಷೇತ್ರದ ಮೇಲ್ಭಾಗಕ್ಕೆ ಸ್ಥಳಾಂತರಿಸುವ ಕೀಬೈಂಡಿಂಗ್. ಇದರ ವಿನ್ಯಾಸವು ಹೀಗೆ " -#~ "ಕಾಣಿಸುತ್ತದೆ\"<Control>a\" ಅಥವ \"<Shift><Alt>F1\". ಪಾರ್ಸರ್ " -#~ "ಬಹಳ ಉದಾರಿ ಹಾಗು ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>" -#~ "\" ಮತ್ತು \"<Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು " -#~ "ವಿಶೇಷ ವಾಕ್ಯದ ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ " -#~ "ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." - -#~ msgid "" -#~ "The keybinding that switches to the workspace below the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "ಈಗಿರುವ ಕಾರ್ಯಕ್ಷೇತ್ರದ ಕೆಳಭಾಗಕ್ಕೆ ಸ್ಥಳಾಂತರಿಸುವ ಕೀಬೈಂಡಿಂಗ್. ಇದರ ವಿನ್ಯಾಸವು ಹೀಗೆ " -#~ "ಕಾಣಿಸುತ್ತದೆ\"<Control>a\" ಅಥವ \"<Shift><Alt>F1\". ಪಾರ್ಸರ್ " -#~ "ಬಹಳ ಉದಾರಿ ಹಾಗು ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>" -#~ "\" ಮತ್ತು \"<Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು " -#~ "ವಿಶೇಷ ವಾಕ್ಯದ ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ " -#~ "ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." - -#~ msgid "" -#~ "The keybinding that switches to the workspace on the left of the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "ಈಗಿರುವ ಕಾರ್ಯಕ್ಷೇತ್ರದ ಎಡಭಾಗಕ್ಕೆ ಸ್ಥಳಾಂತರಿಸುವ ಕೀಬೈಂಡಿಂಗ್. ಇದರ ವಿನ್ಯಾಸವು ಹೀಗೆ " -#~ "ಕಾಣಿಸುತ್ತದೆ\"<Control>a\" ಅಥವ \"<Shift><Alt>F1\". ಪಾರ್ಸರ್ " -#~ "ಬಹಳ ಉದಾರಿ ಹಾಗು ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>" -#~ "\" ಮತ್ತು \"<Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು " -#~ "ವಿಶೇಷ ವಾಕ್ಯದ ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ " -#~ "ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." - -#~ msgid "" -#~ "The keybinding that switches to the workspace on the right of the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "ಈಗಿರುವ ಕಾರ್ಯಕ್ಷೇತ್ರದ ಬಲಭಾಗಕ್ಕೆ ಸ್ಥಳಾಂತರಿಸುವ ಕೀಬೈಂಡಿಂಗ್. ಇದರ ವಿನ್ಯಾಸವು ಹೀಗೆ " -#~ "ಕಾಣಿಸುತ್ತದೆ\"<Control>a\" ಅಥವ \"<Shift><Alt>F1\". ಪಾರ್ಸರ್ " -#~ "ಬಹಳ ಉದಾರಿ ಹಾಗು ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>" -#~ "\" ಮತ್ತು \"<Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು " -#~ "ವಿಶೇಷ ವಾಕ್ಯದ ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ " -#~ "ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." - -#~ msgid "" -#~ "The keybinding that switches to workspace 1. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ಕಾರ್ಯಕ್ಷೇತ್ರ 1 ಕ್ಕೆ ಬದಲಾಯಿಸುವ ಕೀಬೈಂಡಿಂಗ್. ಇದರ ವಿನ್ಯಾಸವು ಹೀಗೆ ಕಾಣಿಸುತ್ತದೆ\"<" -#~ "Control>a\" ಅಥವ \"<Shift><Alt>F1\". ಪಾರ್ಸರ್ ಬಹಳ ಉದಾರಿ ಹಾಗು " -#~ "ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>\" ಮತ್ತು \"<" -#~ "Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು ವಿಶೇಷ ವಾಕ್ಯದ " -#~ "ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." - -#~ msgid "" -#~ "The keybinding that switches to workspace 10. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ಕಾರ್ಯಕ್ಷೇತ್ರ 10 ಕ್ಕೆ ಬದಲಾಯಿಸುವ ಕೀಬೈಂಡಿಂಗ್. ಇದರ ವಿನ್ಯಾಸವು ಹೀಗೆ ಕಾಣಿಸುತ್ತದೆ\"<" -#~ "Control>a\" ಅಥವ \"<Shift><Alt>F1\". ಪಾರ್ಸರ್ ಬಹಳ ಉದಾರಿ ಹಾಗು " -#~ "ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>\" ಮತ್ತು \"<" -#~ "Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು ವಿಶೇಷ ವಾಕ್ಯದ " -#~ "ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." - -#~ msgid "" -#~ "The keybinding that switches to workspace 11. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ಕಾರ್ಯಕ್ಷೇತ್ರ 11 ಕ್ಕೆ ಬದಲಾಯಿಸುವ ಕೀಬೈಂಡಿಂಗ್. ಇದರ ವಿನ್ಯಾಸವು ಹೀಗೆ ಕಾಣಿಸುತ್ತದೆ\"<" -#~ "Control>a\" ಅಥವ \"<Shift><Alt>F1\". ಪಾರ್ಸರ್ ಬಹಳ ಉದಾರಿ ಹಾಗು " -#~ "ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>\" ಮತ್ತು \"<" -#~ "Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು ವಿಶೇಷ ವಾಕ್ಯದ " -#~ "ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." - -#~ msgid "" -#~ "The keybinding that switches to workspace 12. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ಕಾರ್ಯಕ್ಷೇತ್ರ 12 ಕ್ಕೆ ಬದಲಾಯಿಸುವ ಕೀಬೈಂಡಿಂಗ್. ಇದರ ವಿನ್ಯಾಸವು ಹೀಗೆ ಕಾಣಿಸುತ್ತದೆ\"<" -#~ "Control>a\" ಅಥವ \"<Shift><Alt>F1\". ಪಾರ್ಸರ್ ಬಹಳ ಉದಾರಿ ಹಾಗು " -#~ "ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>\" ಮತ್ತು \"<" -#~ "Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು ವಿಶೇಷ ವಾಕ್ಯದ " -#~ "ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." - -#~ msgid "" -#~ "The keybinding that switches to workspace 2. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ಕಾರ್ಯಕ್ಷೇತ್ರ 2 ಕ್ಕೆ ಬದಲಾಯಿಸುವ ಕೀಬೈಂಡಿಂಗ್. ಇದರ ವಿನ್ಯಾಸವು ಹೀಗೆ ಕಾಣಿಸುತ್ತದೆ\"<" -#~ "Control>a\" ಅಥವ \"<Shift><Alt>F1\". ಪಾರ್ಸರ್ ಬಹಳ ಉದಾರಿ ಹಾಗು " -#~ "ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>\" ಮತ್ತು \"<" -#~ "Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು ವಿಶೇಷ ವಾಕ್ಯದ " -#~ "ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." - -#~ msgid "" -#~ "The keybinding that switches to workspace 3. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ಕಾರ್ಯಕ್ಷೇತ್ರ 3 ಕ್ಕೆ ಬದಲಾಯಿಸುವ ಕೀಬೈಂಡಿಂಗ್. ಇದರ ವಿನ್ಯಾಸವು ಹೀಗೆ ಕಾಣಿಸುತ್ತದೆ\"<" -#~ "Control>a\" ಅಥವ \"<Shift><Alt>F1\". ಪಾರ್ಸರ್ ಬಹಳ ಉದಾರಿ ಹಾಗು " -#~ "ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>\" ಮತ್ತು \"<" -#~ "Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು ವಿಶೇಷ ವಾಕ್ಯದ " -#~ "ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." - -#~ msgid "" -#~ "The keybinding that switches to workspace 4. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ಕಾರ್ಯಕ್ಷೇತ್ರ 4 ಕ್ಕೆ ಬದಲಾಯಿಸುವ ಕೀಬೈಂಡಿಂಗ್. ಇದರ ವಿನ್ಯಾಸವು ಹೀಗೆ ಕಾಣಿಸುತ್ತದೆ\"<" -#~ "Control>a\" ಅಥವ \"<Shift><Alt>F1\". ಪಾರ್ಸರ್ ಬಹಳ ಉದಾರಿ ಹಾಗು " -#~ "ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>\" ಮತ್ತು \"<" -#~ "Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು ವಿಶೇಷ ವಾಕ್ಯದ " -#~ "ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." - -#~ msgid "" -#~ "The keybinding that switches to workspace 5. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ಕಾರ್ಯಕ್ಷೇತ್ರ 5 ಕ್ಕೆ ಬದಲಾಯಿಸುವ ಕೀಬೈಂಡಿಂಗ್. ಇದರ ವಿನ್ಯಾಸವು ಹೀಗೆ ಕಾಣಿಸುತ್ತದೆ\"<" -#~ "Control>a\" ಅಥವ \"<Shift><Alt>F1\". ಪಾರ್ಸರ್ ಬಹಳ ಉದಾರಿ ಹಾಗು " -#~ "ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>\" ಮತ್ತು \"<" -#~ "Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು ವಿಶೇಷ ವಾಕ್ಯದ " -#~ "ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." - -#~ msgid "" -#~ "The keybinding that switches to workspace 6. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ಕಾರ್ಯಕ್ಷೇತ್ರ 6 ಕ್ಕೆ ಬದಲಾಯಿಸುವ ಕೀಬೈಂಡಿಂಗ್. ಇದರ ವಿನ್ಯಾಸವು ಹೀಗೆ ಕಾಣಿಸುತ್ತದೆ\"<" -#~ "Control>a\" ಅಥವ \"<Shift><Alt>F1\". ಪಾರ್ಸರ್ ಬಹಳ ಉದಾರಿ ಹಾಗು " -#~ "ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>\" ಮತ್ತು \"<" -#~ "Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು ವಿಶೇಷ ವಾಕ್ಯದ " -#~ "ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." +msgid "%s (on %s)" +msgstr "%s (%s ನಲ್ಲಿ)" -#~ msgid "" -#~ "The keybinding that switches to workspace 7. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ಕಾರ್ಯಕ್ಷೇತ್ರ 7 ಕ್ಕೆ ಬದಲಾಯಿಸುವ ಕೀಬೈಂಡಿಂಗ್. ಇದರ ವಿನ್ಯಾಸವು ಹೀಗೆ ಕಾಣಿಸುತ್ತದೆ\"<" -#~ "Control>a\" ಅಥವ \"<Shift><Alt>F1\". ಪಾರ್ಸರ್ ಬಹಳ ಉದಾರಿ ಹಾಗು " -#~ "ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>\" ಮತ್ತು \"<" -#~ "Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು ವಿಶೇಷ ವಾಕ್ಯದ " -#~ "ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." +#~ msgid "Unknown window information request: %d" +#~ msgstr "ಗೊತ್ತಿರದ ಕಿಟಕಿಯ ಮಾಹಿತಿಯ ಮನವಿ: %d" -#~ msgid "" -#~ "The keybinding that switches to workspace 8. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ಕಾರ್ಯಕ್ಷೇತ್ರ 8 ಕ್ಕೆ ಬದಲಾಯಿಸುವ ಕೀಬೈಂಡಿಂಗ್. ಇದರ ವಿನ್ಯಾಸವು ಹೀಗೆ ಕಾಣಿಸುತ್ತದೆ\"<" -#~ "Control>a\" ಅಥವ \"<Shift><Alt>F1\". ಪಾರ್ಸರ್ ಬಹಳ ಉದಾರಿ ಹಾಗು " -#~ "ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>\" ಮತ್ತು \"<" -#~ "Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು ವಿಶೇಷ ವಾಕ್ಯದ " -#~ "ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." +#~ msgid "Missing %s extension required for compositing" +#~ msgstr "ಕಂಪೋಸಿಟಿಂಗ್ ಮಾಡಲು ಅಗತ್ಯವಿರುವ %s ವಿಸ್ತರಣೆಯು ಕಾಣಿಸುತ್ತಿಲ್ಲ" #~ msgid "" -#~ "The keybinding that switches to workspace 9. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "Some other program is already using the key %s with modifiers %x as a " +#~ "binding\n" #~ msgstr "" -#~ "ಕಾರ್ಯಕ್ಷೇತ್ರ 9 ಕ್ಕೆ ಬದಲಾಯಿಸುವ ಕೀಬೈಂಡಿಂಗ್. ಇದರ ವಿನ್ಯಾಸವು ಹೀಗೆ ಕಾಣಿಸುತ್ತದೆ\"<" -#~ "Control>a\" ಅಥವ \"<Shift><Alt>F1\". ಪಾರ್ಸರ್ ಬಹಳ ಉದಾರಿ ಹಾಗು " -#~ "ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>\" ಮತ್ತು \"<" -#~ "Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು ವಿಶೇಷ ವಾಕ್ಯದ " -#~ "ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." +#~ "ಬೇರೊಂದಿ ಪ್ರೊಗ್ರಾಂ, ಕೀಲಿ %s ಅನ್ನು ಮಾರ್ಪಡಕಗಳಾದ %x ದೊಂದಿಗೆ ಬೈಂಡಿಂಗ್ ಆಗಿ ಈಗಾಗಲೆ " +#~ "ಬಳಸುತ್ತಿದೆ\n" -#~ msgid "" -#~ "The keybinding used to activate the window menu. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "ವಿಂಡೋ ಮೆನು ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲು ಬಳಸಲಾಗುವ ಕೀಬೈಂಡಿಂಗ್. ಇದರ ವಿನ್ಯಾಸವು ಹೀಗೆ " -#~ "ಕಾಣಿಸುತ್ತದೆ\"<Control>a\" ಅಥವ \"<Shift><Alt>F1\". ಪಾರ್ಸರ್ " -#~ "ಬಹಳ ಉದಾರಿ ಹಾಗು ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>" -#~ "\" ಮತ್ತು \"<Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು " -#~ "ವಿಶೇಷ ವಾಕ್ಯದ ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ " -#~ "ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ. ಗೆ." +#~ msgid "\"%s\" is not a valid accelerator\n" +#~ msgstr "\"%s\" ಯು ಒಂದು ಮಾನ್ಯವಾದ ವೇಗವರ್ಧಕವಲ್ಲ\n" #~ msgid "" -#~ "The keybinding used to close a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "Workarounds for broken applications disabled. Some applications may not " +#~ "behave properly.\n" #~ msgstr "" -#~ "ವಿಂಡೋ ಅನ್ನು ಮುಚ್ಚಲು ಬಳಸಲಾಗುವ ಕೀಬೈಂಡಿಂಗ್. ಇದರ ವಿನ್ಯಾಸವು ಹೀಗೆ ಕಾಣಿಸುತ್ತದೆ\"<" -#~ "Control>a\" ಅಥವ \"<Shift><Alt>F1\". ಪಾರ್ಸರ್ ಬಹಳ ಉದಾರಿ ಹಾಗು " -#~ "ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>\" ಮತ್ತು \"<" -#~ "Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು ವಿಶೇಷ ವಾಕ್ಯದ " -#~ "ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." +#~ "ಹಾಳಾದ ಅನ್ವಯಗಳಿಗಾಗಿನ ಪರ್ಯಾಯ ಮಾರ್ಗಗಳನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ. ಕೆಲವು ಅನ್ವಯಗಳು " +#~ "ಸರಿಯಾಗಿ ಕೆಲಸ ಮಾಡದೆ ಇರಬಹುದು.\n" -#~ msgid "" -#~ "The keybinding used to enter \"move mode\" and begin moving a window " -#~ "using the keyboard. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." +#~ msgid "Could not parse font description \"%s\" from GSettings key %s\n" #~ msgstr "" -#~ "\"ಸ್ಥಳಾಂತರಿಸುವ ಕ್ರಮ\"ಕ್ಕೆ ದಾಖಲಿಸಲು ಹಾಗು ಕೀಲಿ ಮಣೆಯನ್ನು ಬಳಸಿಕೊಂಡು ಒಂದು " -#~ "ವಿಂಡೋವನ್ನು ಸ್ಥಳಾಂತರಿಸಲು ಬಳಸಲಾಗುವ ಕೀಬೈಂಡಿಂಗ್. ಇದರ ವಿನ್ಯಾಸವು ಹೀಗೆ ಕಾಣಿಸುತ್ತದೆ " -#~ "\"<Control>a\" ಅಥವ \"<Shift><Alt>F1\". ಪಾರ್ಸರ್ ಬಹಳ ಉದಾರಿ " -#~ "ಹಾಗು ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>\" ಮತ್ತು " -#~ "\"<Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು ವಿಶೇಷ ವಾಕ್ಯದ " -#~ "ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." +#~ "\"%s\" ಎಂಬ ಅಕ್ಷರಶೈಲಿ ವಿವರಣೆಯನ್ನು %s ಎಂಬ GSettings ಕೀಲಿಯಿಂದ ಇಂದ ಪಾರ್ಸ್ " +#~ "ಮಾಡಲಾಗಿಲ್ಲ\n" #~ msgid "" -#~ "The keybinding used to enter \"resize mode\" and begin resizing a window " -#~ "using the keyboard. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" #~ msgstr "" -#~ "\"ಮರುಗಾತ್ರಿಸುವ ಕ್ರಮ\"ಕ್ಕೆ ದಾಖಲಿಸಲು ಹಾಗು ಕೀಲಿ ಮಣೆಯನ್ನು ಬಳಸಿಕೊಂಡು ಒಂದು " -#~ "ವಿಂಡೋವನ್ನು ಮರುಗಾತ್ರಿಸಲು ಬಳಸಲಾಗುವ ಕೀಬೈಂಡಿಂಗ್. ಇದರ ವಿನ್ಯಾಸವು ಹೀಗೆ ಕಾಣಿಸುತ್ತದೆ " -#~ "\"<Control>a\" ಅಥವ \"<Shift><Alt>F1\". ಪಾರ್ಸರ್ ಬಹಳ ಉದಾರಿ " -#~ "ಹಾಗು ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>\" ಮತ್ತು " -#~ "\"<Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು ವಿಶೇಷ ವಾಕ್ಯದ " -#~ "ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." +#~ "ಸಂರಚನಾ ದತ್ತಸಂಚಯದಲ್ಲಿ ಕಂಡುಬಂದಂತಹ \"%s\" ಮೌಸ್ ಗುಂಡಿಯ ಮಾರ್ಪಡಕಕ್ಕಾಗಿ ಒಂದು ಮಾನ್ಯವಾದ " +#~ "ಮೌಲ್ಯವಲ್ಲ\n" #~ msgid "" -#~ "The keybinding used to hide all normal windows and set the focus to the " -#~ "desktop background. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." +#~ "\"%s\" found in configuration database is not a valid value for " +#~ "keybinding \"%s\"\n" #~ msgstr "" -#~ "ಎಲ್ಲಾ ಸಾಮಾನ್ಯ ವಿಂಡೋಗಳನ್ನು ಅನ್ನು ಅಡಗಿಸಲು ಹಾಗು ಎಲ್ಲಾ ಕೇಂದ್ರೀಕರಣವನ್ನು ಗಣಕತೆರೆಯ " -#~ "ಹಿನ್ನಲೆಯತ್ತ ಇರಿಸಲು ಬಳಸಲಾಗುವ ಕೀಬೈಂಡ್. ಇದರ ವಿನ್ಯಾಸವು ಹೀಗೆ ಕಾಣಿಸುತ್ತದೆ \"<" -#~ "Control>a\" ಅಥವ \"<Shift><Alt>F1\". ಪಾರ್ಸರ್ ಬಹಳ ಉದಾರಿ ಹಾಗು " -#~ "ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>\" ಮತ್ತು \"<" -#~ "Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು ವಿಶೇಷ ವಾಕ್ಯದ " -#~ "ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." +#~ "ಸಂರಚನಾ ದತ್ತಸಂಚಯದಲ್ಲಿ ಕಂಡುಬಂದಂತಹ \"%s\" ಕೀಲಿಬೈಂಡಿಂಗ್ \"%s\" ಗೆ ಒಂದು ಮಾನ್ಯವಾದ " +#~ "ಮೌಲ್ಯವಲ್ಲ\n" #~ msgid "" -#~ "The keybinding used to maximize a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "Could not acquire window manager selection on screen %d display \"%s\"\n" #~ msgstr "" -#~ "ಒಂದು ವಿಂಡೋ ಅನ್ನು ಹಿಗ್ಗಿಸಲು ಬಳಸಲಾಗುವ ಕೀಬೈಂಡಿಂಗ್. ಇದರ ವಿನ್ಯಾಸವು ಹೀಗೆ ಕಾಣಿಸುತ್ತದೆ" -#~ "\"<Control>a\" ಅಥವ \"<Shift><Alt>F1\". ಪಾರ್ಸರ್ ಬಹಳ ಉದಾರಿ " -#~ "ಹಾಗು ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>\" ಮತ್ತು " -#~ "\"<Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು ವಿಶೇಷ ವಾಕ್ಯದ " -#~ "ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." +#~ "ತೆರೆ %d ಯಲ್ಲಿನ ಪ್ರದರ್ಶಕ \"%s\" ದಲ್ಲಿನ ಕಿಟಕಿ ವ್ಯವಸ್ಥಾಪಕದ ಆಯ್ಕೆಯನ್ನು ಪಡೆಯಲಾಗಲಿಲ್ಲ\n" -#~ msgid "" -#~ "The keybinding used to minimize a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ಒಂದು ವಿಂಡೋ ಅನ್ನು ಕುಗ್ಗಿಸಲು ಬಳಸಲಾಗುವ ಕೀಬೈಂಡಿಂಗ್. ಇದರ ವಿನ್ಯಾಸವು ಹೀಗೆ ಕಾಣಿಸುತ್ತದೆ" -#~ "\"<Control>a\" ಅಥವ \"<Shift><Alt>F1\". ಪಾರ್ಸರ್ ಬಹಳ ಉದಾರಿ " -#~ "ಹಾಗು ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>\" ಮತ್ತು " -#~ "\"<Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು ವಿಶೇಷ ವಾಕ್ಯದ " -#~ "ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." +#~ msgid "Could not release screen %d on display \"%s\"\n" +#~ msgstr "ತೆರೆ %d ಯನ್ನು (ಪ್ರದರ್ಶಕ \"%s\" ದಲ್ಲಿನ) ಬಿಡುಗಡೆಗೊಳಿಸಲು ಸಾಧ್ಯವಾಗಿಲ್ಲ\n" -#~ msgid "" -#~ "The keybinding used to move a window one workspace down. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "ಒಂದು ಕಾರ್ಯಕ್ಷೇತ್ರದಿಂದ ಕೆಳಗೆ ಒಂದು ವಿಂಡೋ ಅನ್ನು ವರ್ಗಾಯಿಸಲು ಬಳಸಲಾಗುವ ಕೀಬೈಂಡಿಂಗ್. " -#~ "ಇದರ ವಿನ್ಯಾಸವು ಹೀಗೆ ಕಾಣಿಸುತ್ತದೆ\"<Control>a\" ಅಥವ \"<Shift><" -#~ "Alt>F1\". ಪಾರ್ಸರ್ ಬಹಳ ಉದಾರಿ ಹಾಗು ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು " -#~ "ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>\" ಮತ್ತು \"<Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ " -#~ "ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು ವಿಶೇಷ ವಾಕ್ಯದ ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ " -#~ "ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." +#~ msgid "Could not create directory '%s': %s\n" +#~ msgstr "ಕೋಶ '%s' ಅನ್ನು ಸೃಜಿಸಲಾಗಲಿಲ್ಲ: %s\n" -#~ msgid "" -#~ "The keybinding used to move a window one workspace to the left. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "ಒಂದು ಕಾರ್ಯಕ್ಷೇತ್ರದಿಂದ ಎಡಭಾಗಕ್ಕೆ ಒಂದು ವಿಂಡೋ ಅನ್ನು ವರ್ಗಾಯಿಸಲು ಬಳಸಲಾಗುವ ಕೀಬೈಂಡಿಂಗ್. " -#~ "ಇದರ ವಿನ್ಯಾಸವು ಹೀಗೆ ಕಾಣಿಸುತ್ತದೆ\"<Control>a\" ಅಥವ \"<Shift><" -#~ "Alt>F1\". ಪಾರ್ಸರ್ ಬಹಳ ಉದಾರಿ ಹಾಗು ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು " -#~ "ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>\" ಮತ್ತು \"<Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ " -#~ "ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು ವಿಶೇಷ ವಾಕ್ಯದ ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ " -#~ "ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." +#~ msgid "Could not open session file '%s' for writing: %s\n" +#~ msgstr "ಅಧಿವೇಶನ ಕಡತ '%s' ಅನ್ನು ಬರೆಯಲು ತೆಗೆಯಲಾಗಿಲ್ಲ: %s\n" -#~ msgid "" -#~ "The keybinding used to move a window one workspace to the right. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "ಒಂದು ಕಾರ್ಯಕ್ಷೇತ್ರದಿಂದ ಬಲಭಾಗಕ್ಕೆ ಒಂದು ವಿಂಡೋ ಅನ್ನು ವರ್ಗಾಯಿಸಲು ಬಳಸಲಾಗುವ ಕೀಬೈಂಡಿಂಗ್. " -#~ "ಇದರ ವಿನ್ಯಾಸವು ಹೀಗೆ ಕಾಣಿಸುತ್ತದೆ\"<Control>a\" ಅಥವ \"<Shift><" -#~ "Alt>F1\". ಪಾರ್ಸರ್ ಬಹಳ ಉದಾರಿ ಹಾಗು ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು " -#~ "ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>\" ಮತ್ತು \"<Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ " -#~ "ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು ವಿಶೇಷ ವಾಕ್ಯದ ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ " -#~ "ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." +#~ msgid "Error writing session file '%s': %s\n" +#~ msgstr "ಅಧಿವೇಶನ ಕಡತ '%s' ಅನ್ನು ಬರೆಯುವಲ್ಲಿ ದೋಷ: %s\n" -#~ msgid "" -#~ "The keybinding used to move a window one workspace up. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "ಒಂದು ಕಾರ್ಯಕ್ಷೇತ್ರದಿಂದ ಮೇಲಕ್ಕೆ ಒಂದು ವಿಂಡೋ ಅನ್ನು ವರ್ಗಾಯಿಸಲು ಬಳಸಲಾಗುವ ಕೀಬೈಂಡಿಂಗ್. " -#~ "ಇದರ ವಿನ್ಯಾಸವು ಹೀಗೆ ಕಾಣಿಸುತ್ತದೆ\"<Control>a\" ಅಥವ \"<Shift><" -#~ "Alt>F1\". ಪಾರ್ಸರ್ ಬಹಳ ಉದಾರಿ ಹಾಗು ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು " -#~ "ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>\" ಮತ್ತು \"<Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ " -#~ "ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು ವಿಶೇಷ ವಾಕ್ಯದ ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ " -#~ "ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." +#~ msgid "Error closing session file '%s': %s\n" +#~ msgstr "ಅಧಿವೇಶನ ಕಡತ '%s' ಅನ್ನು ಮುಚ್ಚುವಲ್ಲಿ ದೋಷ: %s\n" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 1. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "ಕಾರ್ಯಕ್ಷೇತ್ರ 1 ಕ್ಕೆ ಒಂದು ವಿಂಡೋ ಅನ್ನು ವರ್ಗಾಯಿಸಲು ಬಳಸಲಾಗುವ ಕೀಬೈಂಡಿಂಗ್. ಇದರ " -#~ "ವಿನ್ಯಾಸವು ಹೀಗೆ ಕಾಣಿಸುತ್ತದೆ\"<Control>a\" ಅಥವ \"<Shift><" -#~ "Alt>F1\". ಪಾರ್ಸರ್ ಬಹಳ ಉದಾರಿ ಹಾಗು ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು " -#~ "ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>\" ಮತ್ತು \"<Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ " -#~ "ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು ವಿಶೇಷ ವಾಕ್ಯದ ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ " -#~ "ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." +#~ msgid "Failed to parse saved session file: %s\n" +#~ msgstr "ಉಳಿಸಲಾದ ಅಧಿವೇಶನ ಕಡತವನ್ನು ಪಾರ್ಸ್ ಮಾಡುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ: %s\n" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 10. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ msgid "<mutter_session> attribute seen but we already have the session ID" #~ msgstr "" -#~ "ಕಾರ್ಯಕ್ಷೇತ್ರ 10 ಕ್ಕೆ ಒಂದು ವಿಂಡೋ ಅನ್ನು ವರ್ಗಾಯಿಸಲು ಬಳಸಲಾಗುವ ಕೀಬೈಂಡಿಂಗ್. ಇದರ " -#~ "ವಿನ್ಯಾಸವು ಹೀಗೆ ಕಾಣಿಸುತ್ತದೆ\"<Control>a\" ಅಥವ \"<Shift><" -#~ "Alt>F1\". ಪಾರ್ಸರ್ ಬಹಳ ಉದಾರಿ ಹಾಗು ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು " -#~ "ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>\" ಮತ್ತು \"<Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ " -#~ "ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು ವಿಶೇಷ ವಾಕ್ಯದ ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ " -#~ "ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." +#~ "<mutter_session> ಗುಣ ವಿಶೇಷವು ಕಾಣಿಸಿಕೊಂಡಿದೆ ಆದರೆ ನಾವು ಅಧಿವೇಶನ ID ಅನ್ನು " +#~ "ಹೊಂದಿದ್ದೇನೆ" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 11. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "ಕಾರ್ಯಕ್ಷೇತ್ರ 11 ಕ್ಕೆ ಒಂದು ವಿಂಡೋ ಅನ್ನು ವರ್ಗಾಯಿಸಲು ಬಳಸಲಾಗುವ ಕೀಬೈಂಡಿಂಗ್. ಇದರ " -#~ "ವಿನ್ಯಾಸವು ಹೀಗೆ ಕಾಣಿಸುತ್ತದೆ\"<Control>a\" ಅಥವ \"<Shift><" -#~ "Alt>F1\". ಪಾರ್ಸರ್ ಬಹಳ ಉದಾರಿ ಹಾಗು ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು " -#~ "ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>\" ಮತ್ತು \"<Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ " -#~ "ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು ವಿಶೇಷ ವಾಕ್ಯದ ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ " -#~ "ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." +#~ msgid "Unknown attribute %s on <%s> element" +#~ msgstr "ಗೊತ್ತಿರದ ಗುಣವಿಶೇಷ %s, <%s> ಘಟಕದಲ್ಲಿ" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 12. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "ಕಾರ್ಯಕ್ಷೇತ್ರ 12 ಕ್ಕೆ ಒಂದು ವಿಂಡೋ ಅನ್ನು ವರ್ಗಾಯಿಸಲು ಬಳಸಲಾಗುವ ಕೀಬೈಂಡಿಂಗ್. ಇದರ " -#~ "ವಿನ್ಯಾಸವು ಹೀಗೆ ಕಾಣಿಸುತ್ತದೆ\"<Control>a\" ಅಥವ \"<Shift><" -#~ "Alt>F1\". ಪಾರ್ಸರ್ ಬಹಳ ಉದಾರಿ ಹಾಗು ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು " -#~ "ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>\" ಮತ್ತು \"<Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ " -#~ "ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು ವಿಶೇಷ ವಾಕ್ಯದ ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ " -#~ "ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." +#~ msgid "nested <window> tag" +#~ msgstr "ನೆಸ್ಟ್ ಮಾಡಲಾದ <window> ಟ್ಯಾಗ್" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 2. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "ಕಾರ್ಯಕ್ಷೇತ್ರ 2 ಕ್ಕೆ ಒಂದು ವಿಂಡೋ ಅನ್ನು ವರ್ಗಾಯಿಸಲು ಬಳಸಲಾಗುವ ಕೀಬೈಂಡಿಂಗ್. ಇದರ " -#~ "ವಿನ್ಯಾಸವು ಹೀಗೆ ಕಾಣಿಸುತ್ತದೆ\"<Control>a\" ಅಥವ \"<Shift><" -#~ "Alt>F1\". ಪಾರ್ಸರ್ ಬಹಳ ಉದಾರಿ ಹಾಗು ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು " -#~ "ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>\" ಮತ್ತು \"<Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ " -#~ "ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು ವಿಶೇಷ ವಾಕ್ಯದ ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ " -#~ "ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." +#~ msgid "Unknown element %s" +#~ msgstr "ಗೊತ್ತಿರದ %s ಘಟಕ" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 3. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "ಕಾರ್ಯಕ್ಷೇತ್ರ 3 ಕ್ಕೆ ಒಂದು ವಿಂಡೋ ಅನ್ನು ವರ್ಗಾಯಿಸಲು ಬಳಸಲಾಗುವ ಕೀಬೈಂಡಿಂಗ್. ಇದರ " -#~ "ವಿನ್ಯಾಸವು ಹೀಗೆ ಕಾಣಿಸುತ್ತದೆ\"<Control>a\" ಅಥವ \"<Shift><" -#~ "Alt>F1\". ಪಾರ್ಸರ್ ಬಹಳ ಉದಾರಿ ಹಾಗು ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು " -#~ "ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>\" ಮತ್ತು \"<Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ " -#~ "ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು ವಿಶೇಷ ವಾಕ್ಯದ ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ " -#~ "ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." +#~ msgid "Failed to open debug log: %s\n" +#~ msgstr "ದೋಷ ನಿವಾರಣಾ ದಾಖಲೆಯನ್ನು ತೆರೆಯಲು ವಿಫಲಗೊಂಡಿದೆ: %s\n" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 4. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "ಕಾರ್ಯಕ್ಷೇತ್ರ 4 ಕ್ಕೆ ಒಂದು ವಿಂಡೋ ಅನ್ನು ವರ್ಗಾಯಿಸಲು ಬಳಸಲಾಗುವ ಕೀಬೈಂಡಿಂಗ್. ಇದರ " -#~ "ವಿನ್ಯಾಸವು ಹೀಗೆ ಕಾಣಿಸುತ್ತದೆ\"<Control>a\" ಅಥವ \"<Shift><" -#~ "Alt>F1\". ಪಾರ್ಸರ್ ಬಹಳ ಉದಾರಿ ಹಾಗು ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು " -#~ "ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>\" ಮತ್ತು \"<Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ " -#~ "ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು ವಿಶೇಷ ವಾಕ್ಯದ ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ " -#~ "ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." +#~ msgid "Failed to fdopen() log file %s: %s\n" +#~ msgstr "ದಾಖಲೆ ಕಡತವನ್ನು %s fdopen() ಮಾಡುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ: %s\n" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 5. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "ಕಾರ್ಯಕ್ಷೇತ್ರ 5 ಕ್ಕೆ ಒಂದು ವಿಂಡೋ ಅನ್ನು ವರ್ಗಾಯಿಸಲು ಬಳಸಲಾಗುವ ಕೀಬೈಂಡಿಂಗ್. ಇದರ " -#~ "ವಿನ್ಯಾಸವು ಹೀಗೆ ಕಾಣಿಸುತ್ತದೆ\"<Control>a\" ಅಥವ \"<Shift><" -#~ "Alt>F1\". ಪಾರ್ಸರ್ ಬಹಳ ಉದಾರಿ ಹಾಗು ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು " -#~ "ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>\" ಮತ್ತು \"<Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ " -#~ "ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು ವಿಶೇಷ ವಾಕ್ಯದ ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ " -#~ "ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." - -#~ msgid "" -#~ "The keybinding used to move a window to workspace 6. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "ಕಾರ್ಯಕ್ಷೇತ್ರ 6 ಕ್ಕೆ ಒಂದು ವಿಂಡೋ ಅನ್ನು ವರ್ಗಾಯಿಸಲು ಬಳಸಲಾಗುವ ಕೀಬೈಂಡಿಂಗ್. ಇದರ " -#~ "ವಿನ್ಯಾಸವು ಹೀಗೆ ಕಾಣಿಸುತ್ತದೆ\"<Control>a\" ಅಥವ \"<Shift><" -#~ "Alt>F1\". ಪಾರ್ಸರ್ ಬಹಳ ಉದಾರಿ ಹಾಗು ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು " -#~ "ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>\" ಮತ್ತು \"<Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ " -#~ "ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು ವಿಶೇಷ ವಾಕ್ಯದ ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ " -#~ "ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." - -#~ msgid "" -#~ "The keybinding used to move a window to workspace 7. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "ಕಾರ್ಯಕ್ಷೇತ್ರ 7 ಕ್ಕೆ ಒಂದು ವಿಂಡೋ ಅನ್ನು ವರ್ಗಾಯಿಸಲು ಬಳಸಲಾಗುವ ಕೀಬೈಂಡಿಂಗ್. ಇದರ " -#~ "ವಿನ್ಯಾಸವು ಹೀಗೆ ಕಾಣಿಸುತ್ತದೆ\"<Control>a\" ಅಥವ \"<Shift><" -#~ "Alt>F1\". ಪಾರ್ಸರ್ ಬಹಳ ಉದಾರಿ ಹಾಗು ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು " -#~ "ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>\" ಮತ್ತು \"<Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ " -#~ "ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು ವಿಶೇಷ ವಾಕ್ಯದ ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ " -#~ "ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." +#~ msgid "Opened log file %s\n" +#~ msgstr "ದಾಖಲೆ ಕಡತ %s ಅನ್ನು ತೆರೆಯಲಾಗಿದೆ\n" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 8. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "ಕಾರ್ಯಕ್ಷೇತ್ರ 8 ಕ್ಕೆ ಒಂದು ವಿಂಡೋ ಅನ್ನು ವರ್ಗಾಯಿಸಲು ಬಳಸಲಾಗುವ ಕೀಬೈಂಡಿಂಗ್. ಇದರ " -#~ "ವಿನ್ಯಾಸವು ಹೀಗೆ ಕಾಣಿಸುತ್ತದೆ\"<Control>a\" ಅಥವ \"<Shift><" -#~ "Alt>F1\". ಪಾರ್ಸರ್ ಬಹಳ ಉದಾರಿ ಹಾಗು ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು " -#~ "ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>\" ಮತ್ತು \"<Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ " -#~ "ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು ವಿಶೇಷ ವಾಕ್ಯದ ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ " -#~ "ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." +#~ msgid "Window manager: " +#~ msgstr "ಕಿಟಕಿ ವ್ಯವಸ್ಥಾಪಕ: " -#~ msgid "" -#~ "The keybinding used to move a window to workspace 9. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "ಕಾರ್ಯಕ್ಷೇತ್ರ 9 ಕ್ಕೆ ಒಂದು ವಿಂಡೋ ಅನ್ನು ವರ್ಗಾಯಿಸಲು ಬಳಸಲಾಗುವ ಕೀಬೈಂಡಿಂಗ್. ಇದರ " -#~ "ವಿನ್ಯಾಸವು ಹೀಗೆ ಕಾಣಿಸುತ್ತದೆ\"<Control>a\" ಅಥವ \"<Shift><" -#~ "Alt>F1\". ಪಾರ್ಸರ್ ಬಹಳ ಉದಾರಿ ಹಾಗು ಕೆಳಗಿನ ಹಾಗು ಮೇಲಿನ ಕೇಸ್‍ಗಳನ್ನು " -#~ "ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗು \"<Ctl>\" ಮತ್ತು \"<Ctrl>\" ನಂತಹ ಸಂಕ್ಷಿಪ್ತ " -#~ "ರೂಪಗಳನ್ನೂ ಸಹ ಅನುಮತಿಸುತ್ತದೆ. ನೀವು ವಿಶೇಷ ವಾಕ್ಯದ ಆಯ್ಕೆಯನ್ನು \"ಅಶಕ್ತಗೊಂಡ\" ಕ್ಕೆ " -#~ "ಹೊಂದಿಸಿದಲ್ಲಿ, ಯಾವುದೆ ಕೀಬೈಂಡಿಂಗ್ ಕ್ರಿಯೆಯು ಇರುವುದಿಲ್ಲ." - -#, fuzzy -#~ msgid "" -#~ "The keybinding used to move focus backwards between panels and the " -#~ "desktop, using a popup window. The format looks like \"<Control>a\" " -#~ "or \"<Shift><Alt>F1\". The parser is fairly liberal and " -#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" -#~ "\" and \"<Ctrl>\". If you set the option to the special string " -#~ "\"disabled\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "ಪುಟಿಕೆ(ಪಾಪ್ಅಪ್) ವಿಂಡೊ< ನಿಯಂತ್ರಣ>< Shift>< Alt> F1 <>" -#~ "< Ctrl> ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." +#~ msgid "Bug in window manager: " +#~ msgstr "ಕಿಟಕಿ ವ್ಯವಸ್ಥಾಪಕದಲ್ಲಿ ಒಂದು ತೊಂದರೆ: " -#, fuzzy -#~ msgid "" -#~ "The keybinding used to move focus backwards between panels and the " -#~ "desktop, without a popup window. The format looks like \"<Control>a" -#~ "\" or \"<Shift><Alt>F1\". The parser is fairly liberal and " -#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" -#~ "\" and \"<Ctrl>\". If you set the option to the special string " -#~ "\"disabled\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "ಪುಟಿಕೆ(ಪಾಪ್ಅಪ್) ವಿಂಡೊ< ನಿಯಂತ್ರಣ>< Shift>< Alt> F1 <>" -#~ "< Ctrl> ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." - -#, fuzzy -#~ msgid "" -#~ "The keybinding used to move focus backwards between windows of an " -#~ "application without a popup window. Holding \"shift\" together with this " -#~ "binding makes the direction go forward again. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ಅನ್ವಯ ಪುಟಿಕೆ(ಪಾಪ್ಅಪ್) ವಿಂಡೊ ಶಿಫ್ಟ್‍ ನೊಂದಿಗೆ< ನಿಯಂತ್ರಣ>< Shift>< " -#~ "Alt> F1 <>< Ctrl> ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." - -#, fuzzy -#~ msgid "" -#~ "The keybinding used to move focus backwards between windows of an " -#~ "application, using a popup window. Holding \"shift\" together with this " -#~ "binding makes the direction go forward again. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ಅನ್ವಯ ಪುಟಿಕೆ(ಪಾಪ್ಅಪ್) ವಿಂಡೊ ಶಿಫ್ಟ್‍ ನೊಂದಿಗೆ< ನಿಯಂತ್ರಣ>< Shift>< " -#~ "Alt> F1 <>< Ctrl> ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." - -#, fuzzy -#~ msgid "" -#~ "The keybinding used to move focus backwards between windows without a " -#~ "popup window. Holding \"shift\" together with this binding makes the " -#~ "direction go forward again. The format looks like \"<Control>a\" or " -#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " -#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" -#~ "\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "ಪುಟಿಕೆ(ಪಾಪ್ಅಪ್) ವಿಂಡೊ ಶಿಫ್ಟ್‍ ನೊಂದಿಗೆ< ನಿಯಂತ್ರಣ>< Shift>< " -#~ "Alt> F1 <>< Ctrl> ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." - -#, fuzzy -#~ msgid "" -#~ "The keybinding used to move focus backwards between windows, using a " -#~ "popup window. Holding \"shift\" together with this binding makes the " -#~ "direction go forward again. The format looks like \"<Control>a\" or " -#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " -#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" -#~ "\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "ಪುಟಿಕೆ(ಪಾಪ್ಅಪ್) ವಿಂಡೊ ಶಿಫ್ಟ್‍ ನೊಂದಿಗೆ< ನಿಯಂತ್ರಣ>< Shift>< " -#~ "Alt> F1 <>< Ctrl> ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." - -#, fuzzy -#~ msgid "" -#~ "The keybinding used to move focus between panels and the desktop, using a " -#~ "popup window. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "ಪುಟಿಕೆ(ಪಾಪ್ಅಪ್) ವಿಂಡೊ< ನಿಯಂತ್ರಣ>< Shift>< Alt> F1 <>" -#~ "< Ctrl> ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." +#~ msgid "Window manager warning: " +#~ msgstr "ಕಿಟಕಿ ವ್ಯವಸ್ಥಾಪಕ ಎಚ್ಚರಿಕೆ: " -#, fuzzy -#~ msgid "" -#~ "The keybinding used to move focus between panels and the desktop, without " -#~ "a popup window. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "ಪುಟಿಕೆ(ಪಾಪ್ಅಪ್) ವಿಂಡೊ< ನಿಯಂತ್ರಣ>< Shift>< Alt> F1 <>" -#~ "< Ctrl> ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." +#~ msgid "Window manager error: " +#~ msgstr "ಕಿಟಕಿ ವ್ಯವಸ್ಥಾಪಕ ದೋಷ: " -#, fuzzy #~ msgid "" -#~ "The keybinding used to move focus between windows of an application " -#~ "without a popup window. Holding the \"shift\" key while using this " -#~ "binding reverses the direction of movement. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " +#~ "window as specified in the ICCCM.\n" #~ msgstr "" -#~ "ಅನ್ವಯ ಪುಟಿಕೆ(ಪಾಪ್ಅಪ್) ವಿಂಡೊ ಶಿಫ್ಟ್‍< ನಿಯಂತ್ರಣ>< Shift>< Alt> " -#~ "F1 <>< Ctrl> ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." +#~ "ICCCM ಇಂದ ಸೂಚಿಸಲಾದ WM_CLIENT_LEADER ಕಿಟಕಿದ ಬದಲಿಗೆ ಕಿಟಕಿ %s ತಾನೆ ಸ್ವತಃ " +#~ "SM_CLIENT_ID ಅನ್ನು ಸಿದ್ಧಗೊಳಿಸುತ್ತದೆ.\n" -#, fuzzy #~ msgid "" -#~ "The keybinding used to move focus between windows of an application, " -#~ "using a popup window. (Traditionally <Alt>F6) Holding the \"shift\" " -#~ "key while using this binding reverses the direction of movement. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." +#~ "Window %s sets an MWM hint indicating it isn't resizable, but sets min " +#~ "size %d x %d and max size %d x %d; this doesn't make much sense.\n" #~ msgstr "" -#~ "ಅನ್ವಯ ಪುಟಿಕೆ(ಪಾಪ್ಅಪ್) ವಿಂಡೊ< Alt> F6 ಶಿಫ್ಟ್‍< ನಿಯಂತ್ರಣ>< Shift>" -#~ "< Alt> F1 <>< Ctrl> ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." +#~ "ಕಿಟಕಿ %s ಗಾತ್ರವನ್ನು ಬದಲಾಯಿಸಲಾಗುವುದಿಲ್ಲ ಎಂದು ಸೂಚಿಸಲು ಒಂದು MWM ಸುಳಿವನ್ನು " +#~ "ನೀಡುತ್ತದೆ, ಆದರೆ ಕನಿಷ್ಟ ಗಾತ್ರ %d x %d ಹಾಗು ಗರಿಷ್ಟ ಗಾತ್ರ %d x %d ಅನ್ನು " +#~ "ಹೊಂದಿಸುತ್ತದೆ; ಇದಕ್ಕೆ ಯಾವುದೆ ಅರ್ಥವಿರುವುದಿಲ್ಲ.\n" -#, fuzzy -#~ msgid "" -#~ "The keybinding used to move focus between windows without a popup window. " -#~ "(Traditionally <Alt>Escape) Holding the \"shift\" key while using " -#~ "this binding reverses the direction of movement. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "ಪುಟಿಕೆ(ಪಾಪ್ಅಪ್) ವಿಂಡೊ< Alt> ಎಸ್ಕೇಪ್ ಶಿಫ್ಟ್‍< ನಿಯಂತ್ರಣ>< Shift>" -#~ "< Alt> F1 <>< Ctrl> ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." +#~ msgid "Application set a bogus _NET_WM_PID %lu\n" +#~ msgstr "ಅನ್ವಯವು ಒಂದು ಬೋಗಸ್ _NET_WM_PID %lu ಅನ್ನು ಸಿದ್ಧಗೊಳಿಸಿದೆ\n" -#, fuzzy -#~ msgid "" -#~ "The keybinding used to move focus between windows, using a popup window. " -#~ "(Traditionally <Alt>Tab) Holding the \"shift\" key while using this " -#~ "binding reverses the direction of movement. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ಪುಟಿಕೆ(ಪಾಪ್ಅಪ್) ವಿಂಡೊ< Alt> ಶಿಫ್ಟ್‍< ನಿಯಂತ್ರಣ>< Shift>< " -#~ "Alt> F1 <>< Ctrl> ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." +#~ msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +#~ msgstr "ಅಮಾನ್ಯವಾದ WM_TRANSIENT_FOR ಕಿಟಕಿ 0x%lx ಅನ್ನು %s ಗಾಗಿ ಸೂಚಿಸಲಾಗಿದೆ.\n" -#, fuzzy -#~ msgid "" -#~ "The keybinding used to toggle always on top. A window that is always on " -#~ "top will always be visible over other overlapping windows. The format " -#~ "looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -#~ "parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "ಹೊರಳಿಸು ನಲ್ಲಿ A ವಿಂಡೊ ನಲ್ಲಿ< ನಿಯಂತ್ರಣ>< Shift>< Alt> F1 " -#~ "<>< Ctrl> ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." +#~ msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" +#~ msgstr "WM_TRANSIENT_FOR ಕಿಟಕಿ 0x%lx ಎನ್ನುವುದು %s ಗಾಗಿ ಲೂಪ್ ಅನ್ನು ರಚಿಸುತ್ತದೆ.\n" -#, fuzzy #~ msgid "" -#~ "The keybinding used to toggle fullscreen mode. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "Window 0x%lx has property %s\n" +#~ "that was expected to have type %s format %d\n" +#~ "and actually has type %s format %d n_items %d.\n" +#~ "This is most likely an application bug, not a window manager bug.\n" +#~ "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" #~ msgstr "" -#~ "ಹೊರಳಿಸು< ನಿಯಂತ್ರಣ>< Shift>< Alt> F1 <>< " -#~ "Ctrl> ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." +#~ "ಕಿಟಕಿ 0x%lx ವು %s ಗುಣವನ್ನು ಹೊಂದಿದೆ\n" +#~ "ಅದು ಬಗೆ %s ವಿನ್ಯಾಸ %d ಅನ್ನು ಹೊಂದಿರಬೇಕು ಎಂದು ನಿರೀಕ್ಷಿಸಲಾಗಿತ್ತು\n" +#~ "ಹಾಗು ಬಗೆ %s ಬಗೆ %d n_items %d ಅನ್ನು ಹೊಂದಿದೆ.\n" +#~ "ಇದಕ್ಕೆ ಕಾರಣ ಬಹುಷಃ ಅನ್ವಯದಲ್ಲಿನ ಒಂದು ದೋಷವಾಗಿರಬಹುದೆ ಹೊರತು ಕಿಟಕಿ ವ್ಯವಸ್ಥಾಪಕದ " +#~ "ದೋಷವಲ್ಲ.\n" +#~ "ಕಿಟಕಿ ಶೀರ್ಷಿಕೆ=\"%s\" ವರ್ಗ=\"%s\" ಹೆಸರು=\"%s\"\n" -#, fuzzy -#~ msgid "" -#~ "The keybinding used to toggle maximization. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ಹೊರಳಿಸು< ನಿಯಂತ್ರಣ>< Shift>< Alt> F1 <>< " -#~ "Ctrl> ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." +#~ msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +#~ msgstr "ಗುಣ %s ವು (ಕಿಟಕಿ 0x%lx ದಲ್ಲಿನ) ಅಮಾನ್ಯವಾದ UTF-8 ಅನ್ನು ಹೊಂದಿದೆ\n" -#, fuzzy #~ msgid "" -#~ "The keybinding used to toggle shaded/unshaded state. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the " +#~ "list\n" #~ msgstr "" -#~ "ಹೊರಳಿಸು< ನಿಯಂತ್ರಣ>< Shift>< Alt> F1 <>< " -#~ "Ctrl> ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." +#~ "ಗುಣ %s ವು (ಕಿಟಕಿ 0x%lx ದಲ್ಲಿನ) ಪಟ್ಟಿಯಲ್ಲಿನ ಅಂಶ %d ಕ್ಕಾಗಿ ಅಮಾನ್ಯವಾದ UTF-8 ಅನ್ನು " +#~ "ಹೊಂದಿದೆ\n" -#, fuzzy -#~ msgid "" -#~ "The keybinding used to toggle whether the window is on all workspaces or " -#~ "just one. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "ಹೊರಳಿಸು ವಿಂಡೊ ನಲ್ಲಿ< ನಿಯಂತ್ರಣ>< Shift>< Alt> F1 <" -#~ ">< Ctrl> ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." +#~ msgid "Usage: %s\n" +#~ msgstr "ಬಳಕೆ: %s\n" -#, fuzzy -#~ msgid "" -#~ "The keybinding used to unmaximize a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ವಿಂಡೊ< ನಿಯಂತ್ರಣ>< Shift>< Alt> F1 <>< Ctrl> " -#~ "ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." +#~ msgid "Mi_nimize" +#~ msgstr "ಕುಗ್ಗಿಸು (_n)" -#, fuzzy -#~ msgid "" -#~ "The keybinding which display's the panel's \"Run Application\" dialog " -#~ "box. The format looks like \"<Control>a\" or \"<Shift><" -#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If " -#~ "you set the option to the special string \"disabled\", then there will be " -#~ "no keybinding for this action." -#~ msgstr "" -#~ "ಫಲಕ ಚಲಾಯಿಸು ಅನ್ವಯ< ನಿಯಂತ್ರಣ>< Shift>< Alt> F1 <>" -#~ "< Ctrl> ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." +#~ msgid "Ma_ximize" +#~ msgstr "ಹಿಗ್ಗಿಸು (_x)" -#, fuzzy -#~ msgid "" -#~ "The keybinding which invokes a terminal. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ಟರ್ಮಿನಲ್< ನಿಯಂತ್ರಣ>< Shift>< Alt> F1 <>< " -#~ "Ctrl> ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." +#~ msgid "Unma_ximize" +#~ msgstr "ಹಿಗ್ಗಿಸಬೇಡ (_x)" -#, fuzzy -#~ msgid "" -#~ "The keybinding which invokes the panel's screenshot utility to take a " -#~ "screenshot of a window. The format looks like \"<Control>a\" or " -#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " -#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" -#~ "\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "ಫಲಕ ವಿಂಡೊ< ನಿಯಂತ್ರಣ>< Shift>< Alt> F1 <>< " -#~ "Ctrl> ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." +#~ msgid "Roll _Up" +#~ msgstr "ಉರುಳಿಸು (_U)" -#, fuzzy -#~ msgid "" -#~ "The keybinding which invokes the panel's screenshot utility. The format " -#~ "looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -#~ "parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "ಫಲಕ< ನಿಯಂತ್ರಣ>< Shift>< Alt> F1 <>< Ctrl> " -#~ "ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." +#~ msgid "_Unroll" +#~ msgstr "ಸುತ್ತು (_U)" -#, fuzzy -#~ msgid "" -#~ "The keybinding which shows the panel's main menu. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "ಫಲಕ ಮೆನು< ನಿಯಂತ್ರಣ>< Shift>< Alt> F1 <>< " -#~ "Ctrl> ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." +#~ msgid "_Move" +#~ msgstr "ಜರುಗಿಸು (_M)" -#~ msgid "The name of a workspace." -#~ msgstr "ಒಂದು ಕಾರ್ಯಕ್ಷೇತ್ರದ ಹೆಸರು." +#~ msgid "_Resize" +#~ msgstr "ಗಾತ್ರ ಬದಲಾಯಿಸು (_R)" -#~ msgid "The screenshot command" -#~ msgstr "ತೆರೆಚಿತ್ರದ ಆಜ್ಞೆ" +#~ msgid "Move Titlebar On_screen" +#~ msgstr "ಶೀರ್ಷಿಕೆಪಟ್ಟಿಯನ್ನು ತೆರೆಯ ಮೇಲೆ ಸ್ಥಳಾಂತರಿಸು (_s)" -#, fuzzy -#~ msgid "" -#~ "The theme determines the appearance of window borders, titlebar, and so " -#~ "forth." -#~ msgstr "ವಿಂಡೊ." +#~ msgid "Always on _Top" +#~ msgstr "ಯಾವಾಗಲೂ ಮೇಲ್ಭಾಗದಲ್ಲಿ (_T)" -#, fuzzy -#~ msgid "" -#~ "The time delay before raising a window if auto_raise is set to true. The " -#~ "delay is given in thousandths of a second." -#~ msgstr "ಮೊದಲು ವಿಂಡೊ auto ಎರಡನೆಯ." +#~ msgid "_Always on Visible Workspace" +#~ msgstr "ಯಾವಾಗಲೂ ಕಾಣಿಸುವ ಕಾರ್ಯಕ್ಷೇತ್ರದಲ್ಲಿ (_A)" -#, fuzzy -#~ msgid "" -#~ "The window focus mode indicates how windows are activated. It has three " -#~ "possible values; \"click\" means windows must be clicked in order to " -#~ "focus them, \"sloppy\" means windows are focused when the mouse enters " -#~ "the window, and \"mouse\" means windows are focused when the mouse enters " -#~ "the window and unfocused when the mouse leaves the window." -#~ msgstr "ವಿಂಡೊ ಮೂರು ಕ್ಲಿಕ್ ವಿಂಡೊ ವಿಂಡೊ ವಿಂಡೊ." +#~ msgid "_Only on This Workspace" +#~ msgstr "ಕೇವಲ ಈ ಕಾರ್ಯಕ್ಷೇತ್ರದಲ್ಲಿ (_O)" -#~ msgid "The window screenshot command" -#~ msgstr "ವಿಂಡೊ ತೆರೆಚಿತ್ರದ ಆಜ್ಞೆ" +#~ msgid "Move to Workspace _Left" +#~ msgstr "ಎಡಭಾಗದ ಕಾರ್ಯಕ್ಷೇತ್ರಕ್ಕೆ ವರ್ಗಾಯಿಸು (_L)" -#, fuzzy -#~ msgid "" -#~ "This keybinding changes whether a window is above or below other windows. " -#~ "If the window is covered by another one, it raises the window above all " -#~ "others, and if the window is already fully visible, it lowers it below " -#~ "all others. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "ವಿಂಡೊ ವಿಂಡೊ ವಿಂಡೊ ವಿಂಡೊ < ನಿಯಂತ್ರಣ>< Shift>< Alt> " -#~ "F1 <>< Ctrl> ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." +#~ msgid "Move to Workspace R_ight" +#~ msgstr "ಬಲಭಾಗದ ಕಾರ್ಯಕ್ಷೇತ್ರಕ್ಕೆ ವರ್ಗಾಯಿಸು (_i)" -#, fuzzy -#~ msgid "" -#~ "This keybinding lowers a window below other windows. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "ವಿಂಡೊ< ನಿಯಂತ್ರಣ>< Shift>< Alt> F1 <>< Ctrl> " -#~ "ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." +#~ msgid "Move to Workspace _Up" +#~ msgstr "ಮೇಲಿನ ಕಾರ್ಯಕ್ಷೇತ್ರಕ್ಕೆ ವರ್ಗಾಯಿಸು (_U)" -#, fuzzy -#~ msgid "" -#~ "This keybinding moves a window against the north (top) side of the " -#~ "screen. The format looks like \"<Control>a\" or \"<Shift><" -#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If " -#~ "you set the option to the special string \"disabled\", then there will be " -#~ "no keybinding for this action." -#~ msgstr "" -#~ "ವಿಂಡೊ< ನಿಯಂತ್ರಣ>< Shift>< Alt> F1 <>< Ctrl> " -#~ "ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." +#~ msgid "Move to Workspace _Down" +#~ msgstr "ಕೆಳಗಿನ ಕಾರ್ಯಕ್ಷೇತ್ರಕ್ಕೆ ವರ್ಗಾಯಿಸು (_D)" -#, fuzzy -#~ msgid "" -#~ "This keybinding moves a window into the east (right) side of the screen. " -#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -#~ "\". The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "ವಿಂಡೊ ರೈಟ್< ನಿಯಂತ್ರಣ>< Shift>< Alt> F1 <>< " -#~ "Ctrl> ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." +#~ msgid "_Close" +#~ msgstr "ಮುಚ್ಚು (_C)" -#, fuzzy -#~ msgid "" -#~ "This keybinding moves a window into the north-east (top right) corner of " -#~ "the screen. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "ವಿಂಡೊ ರೈಟ್< ನಿಯಂತ್ರಣ>< Shift>< Alt> F1 <>< " -#~ "Ctrl> ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." +#~ msgid "Workspace %d%n" +#~ msgstr "ಕಾರ್ಯಕ್ಷೇತ್ರ %d%n" -#, fuzzy -#~ msgid "" -#~ "This keybinding moves a window into the north-west (top left) corner of " -#~ "the screen. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "ವಿಂಡೊ ಲೆಫ್ಟ್‍< ನಿಯಂತ್ರಣ>< Shift>< Alt> F1 <>< " -#~ "Ctrl> ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." +#~ msgid "Workspace 1_0" +#~ msgstr "ಕಾರ್ಯಕ್ಷೇತ್ರ 1_0" -#, fuzzy -#~ msgid "" -#~ "This keybinding moves a window into the south (bottom) side of the " -#~ "screen. The format looks like \"<Control>a\" or \"<Shift><" -#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If " -#~ "you set the option to the special string \"disabled\", then there will be " -#~ "no keybinding for this action." -#~ msgstr "" -#~ "ವಿಂಡೊ< ನಿಯಂತ್ರಣ>< Shift>< Alt> F1 <>< Ctrl> " -#~ "ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." +#~ msgid "Workspace %s%d" +#~ msgstr "ಕಾರ್ಯಕ್ಷೇತ್ರ %s%d" -#, fuzzy -#~ msgid "" -#~ "This keybinding moves a window into the south-east (bottom right) corner " -#~ "of the screen. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "ವಿಂಡೊ ರೈಟ್< ನಿಯಂತ್ರಣ>< Shift>< Alt> F1 <>< " -#~ "Ctrl> ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." +#~ msgid "Move to Another _Workspace" +#~ msgstr "ಇನ್ನೊಂದು ಕಾರ್ಯಕ್ಷೇತ್ರಕ್ಕೆ ವರ್ಗಾಯಿಸು (_W)" -#, fuzzy -#~ msgid "" -#~ "This keybinding moves a window into the south-west (bottom left) corner " -#~ "of the screen. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "ವಿಂಡೊ ಲೆಫ್ಟ್‍< ನಿಯಂತ್ರಣ>< Shift>< Alt> F1 <>< " -#~ "Ctrl> ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." +#~ msgid "Shift" +#~ msgstr "Shift" -#, fuzzy -#~ msgid "" -#~ "This keybinding moves a window into the west (left) side of the screen. " -#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -#~ "\". The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "ವಿಂಡೊ ಲೆಫ್ಟ್‍< ನಿಯಂತ್ರಣ>< Shift>< Alt> F1 <>< " -#~ "Ctrl> ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." +#~ msgid "Ctrl" +#~ msgstr "Ctrl" -#, fuzzy -#~ msgid "" -#~ "This keybinding raises the window above other windows. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "ವಿಂಡೊ< ನಿಯಂತ್ರಣ>< Shift>< Alt> F1 <>< Ctrl> " -#~ "ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." +#~ msgid "Alt" +#~ msgstr "Alt" -#, fuzzy -#~ msgid "" -#~ "This keybinding resizes a window to fill available horizontal space. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "ವಿಂಡೊ ಲಭ್ಯವಿರುವ ಖಾಲಿ ಜಾಗ< ನಿಯಂತ್ರಣ>< Shift>< Alt> F1 <" -#~ ">< Ctrl> ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." +#~ msgid "Meta" +#~ msgstr "ಮೆಟಾ" -#, fuzzy -#~ msgid "" -#~ "This keybinding resizes a window to fill available vertical space. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "ವಿಂಡೊ ಲಭ್ಯವಿರುವ ಖಾಲಿ ಜಾಗ< ನಿಯಂತ್ರಣ>< Shift>< Alt> F1 <" -#~ ">< Ctrl> ಆಯ್ಕೆ ವಾಕ್ಯ ಅಶಕ್ತಗೊಂಡ ಗೆ." +#~ msgid "Super" +#~ msgstr "ಸೂಪರ್" -#, fuzzy -#~ msgid "" -#~ "This option determines the effects of middle-clicking on the title bar. " -#~ "Current valid options are 'toggle_shade', which will shade/unshade the " -#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#~ "'minimize' which will minimize the window, and 'none' which will not do " -#~ "anything." -#~ msgstr "ಆಯ್ಕೆ ನಲ್ಲಿ ಆಯ್ಕೆಗಳು ಹೊರಳಿಸು ವಿಂಡೊ ಹೊರಳಿಸು ವಿಂಡೊ ವಿಂಡೊ ಯಾವುದೂ ಇಲ್ಲ." - -#, fuzzy -#~ msgid "" -#~ "This option determines the effects of right-clicking on the title bar. " -#~ "Current valid options are 'toggle_shade', which will shade/unshade the " -#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#~ "'minimize' which will minimize the window, and 'none' which will not do " -#~ "anything." -#~ msgstr "ಆಯ್ಕೆ ರೈಟ್ ನಲ್ಲಿ ಆಯ್ಕೆಗಳು ಹೊರಳಿಸು ವಿಂಡೊ ಹೊರಳಿಸು ವಿಂಡೊ ವಿಂಡೊ ಯಾವುದೂ ಇಲ್ಲ." - -#, fuzzy -#~ msgid "" -#~ "This option provides additional control over how newly created windows " -#~ "get focus. It has two possible values; \"smart\" applies the user's " -#~ "normal focus mode, and \"strict\" results in windows started from a " -#~ "terminal not being given focus." -#~ msgstr "ಆಯ್ಕೆ ಕಂಟ್ರೋಲ್ ಎರಡು ಸಾಮಾನ್ಯ ಟರ್ಮಿನಲ್." +#~ msgid "Hyper" +#~ msgstr "ಹೈಪರ್" -#, fuzzy -#~ msgid "Toggle always on top state" -#~ msgstr "ನಲ್ಲಿ" +#~ msgid "Mod2" +#~ msgstr "Mod2" -#, fuzzy -#~ msgid "" -#~ "Turns on a visual indication when an application or the system issues a " -#~ "'bell' or 'beep'; useful for the hard-of-hearing and for use in noisy " -#~ "environments." -#~ msgstr "ನಲ್ಲಿ ಅನ್ವಯ ಗೆ ಗೆ." +#~ msgid "Mod3" +#~ msgstr "Mod3" -#~ msgid "Unmaximize window" -#~ msgstr "ವಿಂಡೊವನ್ನು ಹಿಗ್ಗಿಸಬೇಡ" +#~ msgid "Mod4" +#~ msgstr "Mod4" -#~ msgid "Use standard system font in window titles" -#~ msgstr "ವಿಂಡೊ ಶೀರ್ಷಿಕೆಗಳಲ್ಲಿ ಗಣಕದ ಅಕ್ಷರಶೈಲಿಯನ್ನು ಬಳಸು" +#~ msgid "Mod5" +#~ msgstr "Mod5" -#~ msgid "Visual Bell Type" -#~ msgstr "ಗೋಚರಿಸು ಗಂಟೆಯ ಬಗೆ" +#~ msgid "_Windows" +#~ msgstr "ಕಿಟಕಿಗಳು (_W)" -#, fuzzy -#~ msgid "Window focus mode" -#~ msgstr "ವಿಂಡೊ" +#~ msgid "_Dialog" +#~ msgstr "ಸಂವಾದ (_D)" -#~ msgid "Window title font" -#~ msgstr "ವಿಂಡೊದ ಶೀರ್ಷಿಕೆಯ ಅಕ್ಷರಶೈಲಿ" +#~ msgid "_Modal dialog" +#~ msgstr "ಮೋಡಲ್ ಸಂವಾದ (_M)" -#~ msgid "Unmaximize Window" -#~ msgstr "ವಿಂಡೊವನ್ನು ಹಿಗ್ಗಿಸಬೇಡ" +#~ msgid "_Utility" +#~ msgstr "ಸವಲತ್ತು (_U)" -#~ msgid "Title" -#~ msgstr "ಶೀರ್ಷಿಕೆ" +#~ msgid "_Splashscreen" +#~ msgstr "ಎರಚುತೆರೆ (_S)" -#~ msgid "Class" -#~ msgstr "ವರ್ಗ" +#~ msgid "_Top dock" +#~ msgstr "ಮೇಲ್ಭಾಗ ಡಾಕ್ (_T)" -#, fuzzy -#~ msgid "No \"%s\" attribute on <%s> element" -#~ msgstr "ಇಲ್ಲ ಗುಣ ವಿಶೇಷ ನಲ್ಲಿ" +#~ msgid "_Bottom dock" +#~ msgstr "ಕೆಳಭಾಗದ ಡಾಕ್ (_B)" -#~ msgid "Theme already has a fallback icon" -#~ msgstr "ಥೀಮ್ ಈಗಾಗಲೆ ಫಾಲ್‍ಬ್ಯಾಕ್ ಚಿಹ್ನೆಯನ್ನು ಹೊಂದಿದೆ" +#~ msgid "_Left dock" +#~ msgstr "ಎಡಬದಿಯ ಡಾಕ್ (_L)" -#, fuzzy -#~ msgid "No \"name\" attribute on element <%s>" -#~ msgstr "ಇಲ್ಲ ಹೆಸರು ಗುಣ ವಿಶೇಷ ನಲ್ಲಿ" +#~ msgid "_Right dock" +#~ msgstr "ಬಲಬದಿಯ ಡಾಕ್ (_R)" -#, fuzzy -#~ msgid "No \"value\" attribute on element <%s>" -#~ msgstr "ಇಲ್ಲ ಮೌಲ್ಯ ಗುಣ ವಿಶೇಷ ನಲ್ಲಿ" +#~ msgid "_All docks" +#~ msgstr "ಎಲ್ಲಾ ಡಾಕ್‌ಗಳು (_A)" -#~ msgid "No \"top\" attribute on element <%s>" -#~ msgstr "<%s> ಘಟಕದಲ್ಲಿ \"ಮೇಲ್ಭಾಗ\" ಗುಣ ವಿಶೇಷವು ಇಲ್ಲ" +#~ msgid "Des_ktop" +#~ msgstr "ಗಣಕತೆರೆ (_k)" -#~ msgid "No \"bottom\" attribute on element <%s>" -#~ msgstr "<%s> ಘಟಕದಲ್ಲಿ \"ಕೆಳಭಾಗ\" ಗುಣ ವಿಶೇಷವು ಇಲ್ಲ" +#~ msgid "Open another one of these windows" +#~ msgstr "ಈ ಕಿಟಕಿಗಳಲ್ಲಿ ಬೇರೊಂದನ್ನು ತೆರೆ" -#~ msgid "No \"left\" attribute on element <%s>" -#~ msgstr "<%s> ಘಟಕದಲ್ಲಿ \"ಎಡಭಾಗ\" ಗುಣ ವಿಶೇಷವು ಇಲ್ಲ" +#~ msgid "This is a demo button with an 'open' icon" +#~ msgstr "'ತೆರೆ' ಚಿಹ್ನೆಯನ್ನು ಹೊಂದಿರುವ ಒಂದು ಪ್ರಾಯೋಗಿಕ ಗುಂಡಿ" -#~ msgid "No \"right\" attribute on element <%s>" -#~ msgstr "<%s> ಘಟಕದಲ್ಲಿ \"ಬಲಭಾಗ\" ಗುಣ ವಿಶೇಷವು ಇಲ್ಲ" +#~ msgid "This is a demo button with a 'quit' icon" +#~ msgstr "'ತ್ಯಜಿಸು' ಚಿಹ್ನೆಯನ್ನು ಹೊಂದಿರುವ ಒಂದು ಪ್ರಾಯೋಗಿಕ ಗುಂಡಿ" -#~ msgid "No \"color\" attribute on element <%s>" -#~ msgstr "<%s> ಘಟಕದಲ್ಲಿ \"ಬಣ್ಣ\" ಗುಣ ವಿಶೇಷವು ಇಲ್ಲ" +#~ msgid "This is a sample message in a sample dialog" +#~ msgstr "ಇದು ಒಂದು ಸಂವಾದದ ನಮೂನೆಯಲ್ಲಿರುವ ಒಂದು ಸಂದೇಶದ ನಮೂನೆ" -#~ msgid "No \"x1\" attribute on element <%s>" -#~ msgstr "<%s> ಘಟಕದಲ್ಲಿ \"x1\" ಗುಣ ವಿಶೇಷವು ಇಲ್ಲ" +#~ msgid "Fake menu item %d\n" +#~ msgstr "ನಕಲಿ ಮೆನು ಅಂಶ %d\n" -#~ msgid "No \"y1\" attribute on element <%s>" -#~ msgstr "<%s> ಘಟಕದಲ್ಲಿ \"y1\" ಗುಣ ವಿಶೇಷವು ಇಲ್ಲ" +#~ msgid "Border-only window" +#~ msgstr "ಅಂಚು ಮಾತ್ರ ಇರುವ ಕಿಟಕಿ" -#~ msgid "No \"x2\" attribute on element <%s>" -#~ msgstr "<%s> ಘಟಕದಲ್ಲಿ \"x2\" ಗುಣ ವಿಶೇಷವು ಇಲ್ಲ" +#~ msgid "Bar" +#~ msgstr "ಪಟ್ಟಿ" -#~ msgid "No \"y2\" attribute on element <%s>" -#~ msgstr "<%s> ಘಟಕದಲ್ಲಿ \"y2\" ಗುಣ ವಿಶೇಷವು ಇಲ್ಲ" +#~ msgid "Normal Application Window" +#~ msgstr "ಸಾಮಾನ್ಯ ಅನ್ವಯ ಕಿಟಕಿ" -#~ msgid "No \"y\" attribute on element <%s>" -#~ msgstr "<%s> ಘಟಕದಲ್ಲಿ \"y\" ಗುಣ ವಿಶೇಷವು ಇಲ್ಲ" +#~ msgid "Dialog Box" +#~ msgstr "ಸಂವಾದ ಪೆಟ್ಟಿಗೆ" -#~ msgid "No \"width\" attribute on element <%s>" -#~ msgstr "<%s> ಘಟಕದಲ್ಲಿ \"ಅಗಲ\" ಗುಣ ವಿಶೇಷವು ಇಲ್ಲ" +#~ msgid "Modal Dialog Box" +#~ msgstr "ಮೋಡಲ್ ಸಂವಾದ ಚೌಕ" -#~ msgid "No \"height\" attribute on element <%s>" -#~ msgstr "<%s> ಘಟಕದಲ್ಲಿ \"ಎತ್ತರ\" ಗುಣ ವಿಶೇಷವು ಇಲ್ಲ" +#~ msgid "Utility Palette" +#~ msgstr "ಸವಲತ್ತು ಫಲಕ" -#~ msgid "No \"start_angle\" attribute on element <%s>" -#~ msgstr "<%s> ಘಟಕದಲ್ಲಿ \"ಆರಂಭದ ಕೋನ(_a\" ಗುಣ ವಿಶೇಷವು ಇಲ್ಲ" +#~ msgid "Torn-off Menu" +#~ msgstr "ಹರಿಯಲ್ಪಟ್ಟ ಮೆನು" -#, fuzzy -#~ msgid "No \"extent_angle\" attribute on element <%s>" -#~ msgstr "ಇಲ್ಲ ಗುಣ ವಿಶೇಷ ನಲ್ಲಿ" +#~ msgid "Border" +#~ msgstr "ಅಂಚು" -#~ msgid "No \"alpha\" attribute on element <%s>" -#~ msgstr "<%s> ಘಟಕದಲ್ಲಿ \"ಆಲ್ಫಾ\" ಗುಣ ವಿಶೇಷವು ಇಲ್ಲ" +#~ msgid "Attached Modal Dialog" +#~ msgstr "ಲಗತ್ತಿಸಲಾದ ಮೋಡಲ್ ಸಂವಾದ" -#~ msgid "No \"type\" attribute on element <%s>" -#~ msgstr "<%s> ಘಟಕದಲ್ಲಿ \"ಪ್ರಕಾರ\" ಗುಣ ವಿಶೇಷವು ಇಲ್ಲ" +#~ msgid "Button layout test %d" +#~ msgstr "ಗುಂಡಿ ಲೇಔಟ್ ಪರೀಕ್ಷೆ %d" -#, fuzzy -#~ msgid "No \"filename\" attribute on element <%s>" -#~ msgstr "ಇಲ್ಲ ಗುಣ ವಿಶೇಷ ನಲ್ಲಿ" +#~ msgid "%g milliseconds to draw one window frame" +#~ msgstr "ಒಂದು ಕಿಟಕಿ ಚೌಕಟ್ಟನ್ನು ಚಿತ್ರಿಸಲು ಸಮಯ %g ಮಿಲಿಸೆಕೆಂಡುಗಳು" -#~ msgid "No \"state\" attribute on element <%s>" -#~ msgstr "<%s> ಘಟಕದಲ್ಲಿ \"ಸ್ಥಿತಿ\" ಗುಣ ವಿಶೇಷವು ಇಲ್ಲ" +#~ msgid "Usage: metacity-theme-viewer [THEMENAME]\n" +#~ msgstr "ಬಳಕೆ: metacity-theme-viewer [THEMENAME]\n" -#~ msgid "No \"shadow\" attribute on element <%s>" -#~ msgstr "<%s> ಘಟಕದಲ್ಲಿ \"ಛಾಯೆ\" ಗುಣ ವಿಶೇಷವು ಇಲ್ಲ" +#~ msgid "Error loading theme: %s\n" +#~ msgstr "ಥೀಮ್ ಅನ್ನು ಲೋಡ್ ಮಾಡುವಲ್ಲಿ ದೋಷ: %s\n" -#~ msgid "No \"arrow\" attribute on element <%s>" -#~ msgstr "<%s> ಘಟಕದಲ್ಲಿ \"ಬಾಣದ ಗುರುತು\" ಗುಣ ವಿಶೇಷವು ಇಲ್ಲ" +#~ msgid "Loaded theme \"%s\" in %g seconds\n" +#~ msgstr "\"%s\" ಥೀಮ್ %g ಸೆಕೆಂಡ್‍ಗಳಲ್ಲಿ ಲೋಡ್ ಆಗಿದೆ\n" -#, fuzzy -#~ msgid "No \"value\" attribute on <%s> element" -#~ msgstr "ಇಲ್ಲ ಮೌಲ್ಯ ಗುಣ ವಿಶೇಷ ನಲ್ಲಿ" +#~ msgid "Normal Title Font" +#~ msgstr "ಸಾಮಾನ್ಯ ಶೀರ್ಷಿಕೆ ಅಕ್ಷರಶೈಲಿ" -#, fuzzy -#~ msgid "No \"position\" attribute on <%s> element" -#~ msgstr "ಇಲ್ಲ ಗುಣ ವಿಶೇಷ ನಲ್ಲಿ" +#~ msgid "Small Title Font" +#~ msgstr "ಚಿಕ್ಕದಾದ ಶೀರ್ಷಿಕೆ ಅಕ್ಷರಶೈಲಿ" -#, fuzzy -#~ msgid "No \"function\" attribute on <%s> element" -#~ msgstr "ಇಲ್ಲ ಕ್ರಿಯೆ ಗುಣ ವಿಶೇಷ ನಲ್ಲಿ" +#~ msgid "Large Title Font" +#~ msgstr "ದೊಡ್ಡದಾದ ಶೀರ್ಷಿಕೆ ಅಕ್ಷರಶೈಲಿ" -#, fuzzy -#~ msgid "No \"state\" attribute on <%s> element" -#~ msgstr "ಇಲ್ಲ ಗುಣ ವಿಶೇಷ ನಲ್ಲಿ" +#~ msgid "Button Layouts" +#~ msgstr "ಗುಂಡಿಗಳ ಲೇಔಟ್" -#, fuzzy -#~ msgid "No \"focus\" attribute on <%s> element" -#~ msgstr "ಇಲ್ಲ ಗುಣ ವಿಶೇಷ ನಲ್ಲಿ" +#~ msgid "Benchmark" +#~ msgstr "ಮೈಲಿಗಲ್ಲು" -#, fuzzy -#~ msgid "No \"style\" attribute on <%s> element" -#~ msgstr "ಇಲ್ಲ ಗುಣ ವಿಶೇಷ ನಲ್ಲಿ" +#~ msgid "Window Title Goes Here" +#~ msgstr "ಕಿಟಕಿ ಶೀರ್ಷಿಕೆಯು ಹೀಗೆ ಇರುತ್ತದೆ" -#, fuzzy -#~ msgid "No \"resize\" attribute on <%s> element" -#~ msgstr "ಇಲ್ಲ ಗುಣ ವಿಶೇಷ ನಲ್ಲಿ" +#~ msgid "" +#~ "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and " +#~ "%g seconds wall clock time including X server resources (%g milliseconds " +#~ "per frame)\n" +#~ msgstr "" +#~ "%d ಚೌಕಟ್ಟುಗಳನ್ನು %g ಕ್ಲೈಟ್‌-ಬದಿಯ ಸೆಕೆಂಡುಗಳಲ್ಲಿ (ಪ್ರತಿ ಚೌಕಟ್ಟಿಗೂ %g ಮಿಲಿಸೆಕೆಂಡುಗಳು) " +#~ "ಹಾಗು X ಪರಿಚಾರಕ ಸಂಪನ್ಮೂನಗಳನ್ನೂ ಸಹ ಒಳಗೊಂಡು %g ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಗೋಡೆ ಗಡಿಯಾರದ " +#~ "ಸಮಯದಲ್ಲಿ (ಪ್ರತಿ ಚೌಕಟ್ಟಿಗೂ %g ಮಿಲಿಸೆಕೆಂಡುಗಳು)\n" -#~ msgid "<author> specified twice for this theme" -#~ msgstr "<author> ಈ ಥೀಮ್‍ಗೆ ಎರಡು ಬಾರಿ ಸೂಚಿಸಲ್ಪಟ್ಟಿದೆ" +#~ msgid "position expression test returned TRUE but set error" +#~ msgstr "" +#~ "ಸ್ಥಾನದ ಎಕ್ಸ್‌ಪ್ರೆಶನ್‌ ಪರೀಕ್ಷೆಯು TRUE ಅನ್ನು ಮರಳಿಸಿದೆ ಆದರೆ ಅದು ದೋಷವನ್ನು ಸೂಚಿಸಿಲ್ಲ" -#~ msgid "<copyright> specified twice for this theme" -#~ msgstr "<copyright> ಈ ಥೀಮ್‍ಗೆ ಎರಡು ಬಾರಿ ಸೂಚಿಸಲ್ಪಟ್ಟಿದೆ" +#~ msgid "position expression test returned FALSE but didn't set error" +#~ msgstr "" +#~ "ಸ್ಥಾನದ ಎಕ್ಸ್‌ಪ್ರೆಶನ್‌ ಪರೀಕ್ಷೆಯು FALSE ಅನ್ನು ಮರಳಿಸಿದೆ ಆದರೆ ಅದು ದೋಷವನ್ನು ಸೂಚಿಸಿಲ್ಲ" -#~ msgid "<date> specified twice for this theme" -#~ msgstr "<date> ಈ ಥೀಮ್‍ಗೆ ಎರಡು ಬಾರಿ ಸೂಚಿಸಲ್ಪಟ್ಟಿದೆ" +#~ msgid "Error was expected but none given" +#~ msgstr "ದೋಷವನ್ನು ನಿರೀಕ್ಷಿಸಲಾಗಿತ್ತು ಆದರೆ ಯಾವುದೂ ಕಂಡು ಬಂದಿಲ್ಲ" -#~ msgid "<description> specified twice for this theme" -#~ msgstr "<description> ಈ ಥೀಮ್‍ಗೆ ಎರಡು ಬಾರಿ ಸೂಚಿಸಲ್ಪಟ್ಟಿದೆ" +#~ msgid "Error %d was expected but %d given" +#~ msgstr "ದೋಷ %d ಅನ್ನು ನಿರೀಕ್ಷಿಸಲಾಗಿತ್ತು ಆದರೆ %d ಅನ್ನು ನೀಡಲಾಗಿದೆ" -#~ msgid "Theme file %s did not contain a root <metacity_theme> element" -#~ msgstr "%s ಥೀಮ್ ಕಡತವು ಒಂದು ಮೂಲ<metacity_theme> ಘಟಕವನ್ನು ಹೊಂದಿಲ್ಲ" +#~ msgid "Error not expected but one was returned: %s" +#~ msgstr "ದೋಷವನ್ನು ನಿರೀಕ್ಷಿಸಿರಲಿಲ್ಲ ಆದರೆ ಒಂದು ದೋಷವು ಕಂಡು ಬಂದಿದೆ: %s" -#~ msgid "/Windows/tearoff" -#~ msgstr "/ವಿಂಡೋಗಳು/ಹರಿದು ಹಾಕು" +#~ msgid "x value was %d, %d was expected" +#~ msgstr "x ಮೌಲ್ಯವು %d ಆಗಿದೆ, %d ಅನ್ನು ನಿರೀಕ್ಷಿಸಲಾಗಿತ್ತು" -#~ msgid "/Windows/_Dialog" -#~ msgstr "/ವಿಂಡೋಗಳು/ಸಂವಾದ(_D)" +#~ msgid "y value was %d, %d was expected" +#~ msgstr "y ಮೌಲ್ಯವು %d ಆಗಿದೆ, %d ಅನ್ನು ನಿರೀಕ್ಷಿಸಲಾಗಿತ್ತು" -#~ msgid "/Windows/Des_ktop" -#~ msgstr "/ವಿಂಡೋಗಳು/ಗಣಕತೆರೆ(_k)" +#~ msgid "" +#~ "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" +#~ msgstr "" +#~ "%d ಅಕ್ಷಾಂಶ ಎಕ್ಸ್‌ಪ್ರೆಶನ್‌ಗಳನ್ನು %g ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಪಾರ್ಸ್ ಮಾಡಲಾಗಿದೆ (ಸರಾಸರಿ %g " +#~ "ಸೆಕೆಂಡುಗಳು)\n" diff --git a/po/ko.po b/po/ko.po index 5beb838a8..2a392fd3b 100644 --- a/po/ko.po +++ b/po/ko.po @@ -1,425 +1,283 @@ -# muffin korean translation -# This file is distributed under the same license as the muffin package. +# mutter korean translation +# This file is distributed under the same license as the mutter package. # # Based on metacity translation: # Young-Ho, Cha <ganadist@chollian.net>, 2002, 2006. # Changwoo Ryu <cwryu@debian.org>, 2003, 2004, 2005, 2006, 2007, 2008, 2009. # -# Updated in muffin: -# Changwoo Ryu <cwryu@debian.org>, 2011-2012. +# Updated in mutter: +# Changwoo Ryu <cwryu@debian.org>, 2011-2017. +# Gwan-gyeong Mun <elongbug@gmail.com>, 2018-2019. # # # 주의: -# - 이 프로그램의 이름인 Muffin는 "머터"로 음역. +# - 이 프로그램의 이름인 Mutter는 "머터"로 음역. # - Clutter는 "클러터"로 음역. # msgid "" msgstr "" -"Project-Id-Version: muffin\n" -"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" -"product=muffin&keywords=I18N+L10N&component=general\n" -"POT-Creation-Date: 2012-03-15 21:29+0000\n" -"PO-Revision-Date: 2012-03-27 01:25+0900\n" -"Last-Translator: Changwoo Ryu <cwryu@debian.org>\n" +"Project-Id-Version: mutter\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2020-02-23 17:41+0000\n" +"PO-Revision-Date: 2020-02-24 14:09+0200\n" +"Last-Translator: Gwan-gyeong Mun <elongbug@gmail.com>\n" "Language-Team: GNOME Korea <gnome-kr@googlegroups.com>\n" +"Language: ko\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Language: Korean\n" "Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 2.2.4\n" -#: ../src/50-muffin-windows.xml.in.h:1 -msgid "Windows" -msgstr "창" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "조종" -#: ../src/50-muffin-windows.xml.in.h:2 -msgid "View split on left" -msgstr "왼쪽 절반 뷰" +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "창을 작업 공간 1로 옮기기" -#: ../src/50-muffin-windows.xml.in.h:3 -msgid "View split on right" -msgstr "오른쪽 절반 뷰" +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "창을 작업 공간 2로 옮기기" -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format -msgid "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." -msgstr "" -"다른 창 구성 관리 프로그램이 이미 디스플레이 \"%2$s\" 화면 %1$i번에서 실행 중" -"입니다." +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "창을 작업 공간 3으로 옮기기" -#: ../src/core/bell.c:307 -msgid "Bell event" -msgstr "삑소리 이벤트" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "창을 작업 공간 4로 옮기기" -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "알 수 없는 창 정보 요청: %d" +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "창을 최근 작업 공간으로 옮기기" -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> 창이 반응하지 않습니다." +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "창을 한칸 위 작업 공간으로 옮기기" -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "프로그램이 반응하지 않습니다." +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "창을 한칸 아래 작업 공간으로 옮기기" -#: ../src/core/delete.c:119 -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "좀 더 기다리거나 해당 프로그램을 강제로 끝낼 수 있습니다." +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "창을 한칸 왼쪽 모니터로 옮기기" -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "기다리기(_W)" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "창을 한칸 오른쪽 모니터로 옮기기" -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "강제로 끝내기(_F)" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "창을 한칸 위 모니터로 옮기기" -#: ../src/core/display.c:387 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "콤포짓에 필요한 %s 확장 기능이 없습니다" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "창을 한칸 아래 모니터로 옮기기" -#: ../src/core/display.c:453 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "X 윈도 시스템 디스플레이 '%s'을(를) 여는데 실패하였습니다\n" +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "프로그램 전환" -#: ../src/core/keybindings.c:852 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "" -"다른 프로그램에서 이미 단축키로 변경 키 %2$x와(과) 키 %1$s을(를) 사용하고 있" -"습니다\n" +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "이전 프로그램으로 전환" -#: ../src/core/main.c:206 -msgid "Disable connection to session manager" -msgstr "세션 관리자와 연결 하지 않습니다" - -#: ../src/core/main.c:212 -msgid "Replace the running window manager" -msgstr "실행 중인 창 관리자를 바꿉니다" - -#: ../src/core/main.c:218 -msgid "Specify session management ID" -msgstr "세션 관리 ID를 지정합니다" +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "창 전환" -#: ../src/core/main.c:223 -msgid "X Display to use" -msgstr "사용할 X 디스플레이" - -#: ../src/core/main.c:229 -msgid "Initialize session from savefile" -msgstr "저장 파일에서 세션을 초기화 합니다" - -#: ../src/core/main.c:235 -msgid "Make X calls synchronous" -msgstr "동기 X 호출을 합니다" +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "이전 창으로 전환" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "테마 디렉터리를 읽는 데 실패했습니다: %s\n" +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "한 프로그램의 창 전환" -#: ../src/core/main.c:520 -#, c-format -msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "" -"테마를 찾을 수 없습니다! %s이(가) 있고 올바른 테마가 들어 있는지 확인하십시" -"오.\n" +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "한 프로그램의 이전 창으로 전환" -#: ../src/core/muffin.c:40 -#, c-format -msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "시스템 조작 전환" -#: ../src/core/muffin.c:54 -msgid "Print version" -msgstr "버전을 출력합니다" +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "이전 시스템 조작으로 전환" -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "컴포짓 플러그인의 목록, 쉼표로 구분" +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "직접 창 전환" -#: ../src/core/prefs.c:1077 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"응용 프로그램에 대한 임시 방편을 막았습니다. 몇몇 응용프로그램들이 제대로 동" -"작하지 않을것입니다.\n" +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "직접 이전 창으로 전환" -#: ../src/core/prefs.c:1152 -#, c-format -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "GSettings 키 %2$s에서 글꼴 지정 \"%1$s\"을(를) 분석할 수 없습니다\n" +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "직접 한 앱의 창 전환" -#: ../src/core/prefs.c:1218 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"설정 데이터베이스에서 찾은 \"%s\"이(가) 마우스 단추 변경 키의 올바른 값이 아" -"닙니다\n" +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "직접 한 앱의 이전 창으로 전환" -#: ../src/core/prefs.c:1739 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "" -"설정 데이터베이스에서 찾은 \"%s\"이(가) 단축키 \"%s\"에 대한 올바른 값이 아닙" -"니다\n" +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "직접 시스템 조작 전환" -#: ../src/core/prefs.c:1836 -#, c-format -msgid "Workspace %d" -msgstr "작업 공간 %d" +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "직접 이전 시스템 조작으로 전환" -#: ../src/core/screen.c:730 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "디스플레이 '%2$s'의 화면 %1$d은(는) 잘못되었습니다\n" +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "모든 일반 창 감추기" -#: ../src/core/screen.c:746 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"디스플레이 \"%2$s\"의 화면 %1$d에 이미 창 관리자가 실행되고 있습니다. 현재 " -"창 관리자를 무시하는 --replace 옵션을 써보십시오.\n" +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "작업 공간 1로 이동" -#: ../src/core/screen.c:773 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "디스플레이 \"%2$s\"의 화면 %1$d에 창 관리 선택을 가질 수 없습니다\n" +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "작업 공간 2로 이동" -#: ../src/core/screen.c:828 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "" -"디스플레이 \"%2$s\"의 화면 %1$d은(는) 이미 창 관리자가 실행되고 있습니다\n" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "작업 공간 3으로 이동" -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "디스플레이 \"%2$s\"의 화면 %1$d을(를) 떼어 놓을수 없습니다\n" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "작업 공간 4로 이동" -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "디렉터리 '%s'을(를) 만들 수 없습니다: %s\n" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "최근 작업 공간으로 이동" -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "세션 파일 '%s'을(를) 쓰기위해 열 수 없습니다: %s\n" +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "위 작업 공간으로 옮기기" -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "세션 파일 '%s'을(를) 쓰는 중 오류: %s\n" +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "아래 작업 공간으로 옮기기" -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "세션 파일 '%s'을(를) 닫는 중 오류: %s\n" +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "시스템" -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "저장된 세션파일을 분석하기 실패: %s\n" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "실행 명령 프롬프트 보이기" -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "이미 세션 ID를 가지고 있는데 <muffin_session> 속성이 나왔습니다." +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "현재 활동 보이기" -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "<%2$s> 엘리먼트에 알 수 없는 속성 %1$s" +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "키보드 바로 가기 복구" -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "포함된 <window> 태그" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "창" -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "알 수 없는 속성 %s" +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "창 메뉴 활성화" -#: ../src/core/session.c:1809 -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" -"이 창은 "현재 설정 저장"을 지원하지 않기 때문에 다음 번에 로그인 " -"할 때 수동으로 다시 시작해야 합니다." +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "전체 화면 모드 토글" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "디버그 로그 열기 실패: %s\n" +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "최대화 상태 토글" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "로그 파일 %s을(를) fdopen()하기 실패: %s\n" +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "창 최대화" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "로그 파일 %s을(를) 엽니다\n" +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "창 복구" -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "머터가 자세한 모드 지원 없이 컴파일 되었습니다\n" +#: data/50-mutter-windows.xml:18 +msgid "Close window" +msgstr "창 닫기" -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "창 관리자: " +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "창 감추기" -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "창 관리자의 벌레: " +#: data/50-mutter-windows.xml:22 +msgid "Move window" +msgstr "창 옮기기" -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "창 관리자 주의: " +#: data/50-mutter-windows.xml:24 +msgid "Resize window" +msgstr "창 크기 조정" -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "장 관리자 오류: " +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "창을 모든/하나의 작업 공간에 두기 토글" -#. first time through -#: ../src/core/window.c:7269 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"창 %s(이)가 자신에게 ICCCM에 저정한대로 WM_CLIENT_LEADER창 대신에 자신에게 " -"SM_CLIENT_ID를 지정했습니다.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7932 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %" -"d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"%s 창에서 크기 변경이 불가능하다는 MWM 힌트를 설정했지만, 최소 크기 %d x %d " -"및 최대 크기 %d x %d(으)로 설정했습니다. 앞뒤가 맞지 않습니다.\n" +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "창이 가려 있으면 올리고 아니면 내리기" -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "응용 프로그램이 가짜 _NET_WM_PID %lu을(를) 설정하였습니다\n" +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "창을 다른 창 위로 올리기" -# <창제목> (on <기계>) -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (%s에서)" +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "창을 다른 창 아래로 내리기" -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "%2$s에 대해 WM_TRANSIENT_FOR 0x%1$lx 창이 잘못되었습니다.\n" +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "창을 세로 방향으로 최대화" -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "%2$s에 대해 WM_TRANSIENT_FOR 0x%1$lx 창은 무한 반복입니다.\n" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "창을 가로 방향으로 최대화" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"창 0x%lx의 등록 정보 %s\n" -"형식 %s %d이(가) 들어있어야 하는데\n" -"실제로는 형식 %s %d n_items %d이(가) 들어있습니다\n" -"대부분은 창 관리자 버그가 아니라 응용 프로그램 버그입니다.\n" -"창의 정보: title=\"%s\" class=\"%s\" name=\"%s\"\n" - -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "창 0x%2$lx의 등록 정보 %1$s은(는) 잘못된 UTF-8이 들어 있습니다\n" +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "왼쪽 나눔창 보기" -#: ../src/core/xprops.c:494 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"창 0x%2$lx의 등록 정보 %1$s은(는) 목록안의 항목 %3$d에 잘못된 UTF-8을 포함하" -"고 있습니다\n" +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "오른쪽 나눔창 보기" -#: ../src/muffin.desktop.in.h:1 ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" +#: data/mutter.desktop.in:4 +msgid "Mutter" msgstr "머터" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 +#: data/org.gnome.mutter.gschema.xml.in:7 msgid "Modifier to use for extended window management operations" msgstr "창 관리 작업을 할 때 사용할 변경 키" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 +#: data/org.gnome.mutter.gschema.xml.in:8 msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." msgstr "" -"다음 창으로 이동할 때 창 팝업 및 프레임을 표시할지 여부. 이 키는 \"오버레이" -"\"를 시작합니다. 오버레이는 창 상태 보기 및 프로그램 실행 환경입니다. PC에서 " -"기본값은 \"윈도우 키\"입니다. 보통 이 키 바인딩은 기본값이거나 빈 문자열입니" +"다음 창으로 이동할 때 창 팝업 및 프레임을 표시할지 여부. 이 키는 “오버레" +"이”를 시작합니다. 오버레이는 창 상태 보기 및 프로그램 실행 환경입니다. PC에" +"서 기본값은 “윈도우 키”입니다. 보통 이 키 바인딩은 기본값이거나 빈 문자열입니" "다." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 +#: data/org.gnome.mutter.gschema.xml.in:20 msgid "Attach modal dialogs" msgstr "모달 대화 상자 부착" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 +#: data/org.gnome.mutter.gschema.xml.in:21 msgid "" "When true, instead of having independent titlebars, modal dialogs appear " "attached to the titlebar of the parent window and are moved together with " @@ -428,23 +286,11 @@ msgstr "" "참이면 모달 대화 상자에서 별도의 제목 표시줄을 표시하지 않고 상위 창의 제목 " "표시줄에 붙어서 상위 창과 함께 움직입니다." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -msgid "Live Hidden Windows" -msgstr "실행 중인 숨긴 창" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"숨긴 창을 (예를 들어 최소화한 창과 현재가 아닌 다른 작업 공간의 창) 실행 상태" -"로 두어야 할지 지정합니다." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 +#: data/org.gnome.mutter.gschema.xml.in:30 msgid "Enable edge tiling when dropping windows on screen edges" msgstr "창을 화면 가장자리에 끌어 놓을 때 가장자리에 맞춰 격자로 만들기" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 +#: data/org.gnome.mutter.gschema.xml.in:31 msgid "" "If enabled, dropping windows on vertical screen edges maximizes them " "vertically and resizes them horizontally to cover half of the available " @@ -454,22 +300,25 @@ msgstr "" "로 방향으로 화면을 절반을 차지하도록 크기를 바꿉니다. 화면 위 가장자리에 창" "을 놓으면 전체 화면으로 만듭니다." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 +#: data/org.gnome.mutter.gschema.xml.in:40 msgid "Workspaces are managed dynamically" msgstr "작업 공간을 동적으로 관리" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 +#: data/org.gnome.mutter.gschema.xml.in:41 msgid "" -"Determines whether workspaces are managed dynamically or whether there's a " +"Determines whether workspaces are managed dynamically or whether there’s a " "static number of workspaces (determined by the num-workspaces key in org." "gnome.desktop.wm.preferences)." -msgstr "작업 공간을 동적으로 관리할지 아니면 작업 공간이 고정된 개수인지 지정합니다. (고정된 개수는 org.cinnamon.desktop.wm.preferences의 num-workspaces 키로 지정합니다.)" +msgstr "" +"작업 공간을 동적으로 관리할지 아니면 작업 공간이 고정된 개수인지 지정합니다. " +"(고정된 개수는 org.gnome.desktop.wm.preferences의 num-workspaces 키로 지정합" +"니다.)" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 +#: data/org.gnome.mutter.gschema.xml.in:50 msgid "Workspaces only on primary" msgstr "주 모니터에서만 작업 공간" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 +#: data/org.gnome.mutter.gschema.xml.in:51 msgid "" "Determines whether workspace switching should happen for windows on all " "monitors or only for windows on the primary monitor." @@ -477,1133 +326,452 @@ msgstr "" "작업 공간을 전환할 때 모든 모니터의 창에 대해 할지 주 모니터의 창에서만 할지 " "결정합니다." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 +#: data/org.gnome.mutter.gschema.xml.in:59 msgid "No tab popup" msgstr "탭 팝업 없음" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 +#: data/org.gnome.mutter.gschema.xml.in:60 msgid "" "Determines whether the use of popup and highlight frame should be disabled " "for window cycling." msgstr "" "팝업 및 강조 프레임을 창 전환 목록에 사용하지 않게 만들지 여부를 결정합니다." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "포인터가 움직임을 멈출 때까지 포커스 전환 미루기" + +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" +"참이고 포커스 모드가 “sloppy”나 “mouse”인 경우, 창 안에 포인터를 옮겼을 때 즉" +"시 포커스를 전환하지 않고, 포인터가 움직임을 멈추었을 때 전환합니다." + +#: data/org.gnome.mutter.gschema.xml.in:79 msgid "Draggable border width" msgstr "마우스로 끌 수 있는 가장자리의 너비" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 +#: data/org.gnome.mutter.gschema.xml.in:80 msgid "" -"The amount of total draggable borders. If the theme's visible borders are " +"The amount of total draggable borders. If the theme’s visible borders are " "not enough, invisible borders will be added to meet this value." msgstr "" "마우스로 끌 수 있는 가장자리의 너비. 테마의 가장자리가 이보다 작은 경우, 투명" "한 가장자리가 부족한 양만큼 추가됩니다." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:17 -msgid "Select window from tab popup" -msgstr "탭 팝업에서 창 선택" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:18 -msgid "Cancel tab popup" -msgstr "탭 팝업 취소" - -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "사용법: %s\n" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "최소화(_N)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "최대화(_X)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "최대화 취소(_X)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "말아올리기(_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "펼치기(_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "옮기기(_M)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "크기 조정(_R)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "창 제목막대 화면에 표시(_S)" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "항상 위(_T)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "항상 현재 작업 공간에 놓기(_A)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "이 작업 공간에만 놓기(_O)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "왼쪽 작업 공간으로 옮기기(_L)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "오른쪽 작업 공간으로 옮기기(_I)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "위쪽 작업 공간으로 옮기기(_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "아래쪽 작업 공간으로 옮기기(_D)" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "닫기(_C)" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "작업 공간 %d%n" - -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "작업 공간 1_0" - -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "작업 공간 %s%d" - -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "다른 작업 공간으로 옮기기(_W)" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" - -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" - -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "맨 위" - -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "맨 아래" - -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "왼쪽" - -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "오른쪽" - -#: ../src/ui/theme.c:286 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "프레임 위치가 \"%s\"차원으로 지정되지 않았습니다" - -#: ../src/ui/theme.c:305 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "" -"프레임 위치가 가장자리 \"%2$s\" 가장자리의 \"%1$s\"차원으로 지정되지 않았습니" -"다." - -#: ../src/ui/theme.c:342 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "단추의 가로세로 비 %g이(가) 적당하지 않습니다" - -#: ../src/ui/theme.c:354 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "프레임 위치가 단추의 크기로 지정되지 않았습니다" - -#: ../src/ui/theme.c:1067 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "서서히 변하는 색으로 지정하려면 최소 2색이 필요합니다" - -#: ../src/ui/theme.c:1219 -#, c-format -msgid "" -"GTK custom color specification must have color name and fallback in " -"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" -msgstr "" -"GTK 사용자 지정 색상 지정은 색 이름과 대체할 색을 괄호 안에 써야 합니다. 예" -"를 들어: gtk:custom(foo,bar). \"%s\"을(를) 분석할 수 없습니다" - -#: ../src/ui/theme.c:1235 -#, c-format -msgid "" -"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" -"_ are valid" -msgstr "" -"gtk:custom의 color_name 파라미터 안에 잘못된 문자 '%c'. A-Za-z0-9-_ 문자만 허" -"용합니다." - -#: ../src/ui/theme.c:1249 -#, c-format -msgid "" -"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " -"fit the format" -msgstr "" -"gtk:custom 형식은 \"gtk:custom(색이름,대체색)\"입니다, \"%s\"(은)는 형식에 맞" -"지 않습니다" - -#: ../src/ui/theme.c:1294 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"GTK 색상 지정은 중괄호안에 있어야 합니다. 예를 들어: gtk:fg[NORMAL], 여기서 " -"NORMAL이 값입니다. \"%s\"을(를) 분석할 수 없습니다." - -#: ../src/ui/theme.c:1308 -#, c-format -msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"GTK 색상 지정은 값 뒤에 중괄호로 닫혀 있어야 합니다. 예를 들어: gtk:fg" -"[NORMAL], 여기서 NORMAL은 값입니다. \"%s\"을(를) 분석할 수 없습니다." - -#: ../src/ui/theme.c:1319 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "색상 지정의 \"%s\" 값을 이해할 수 없습니다" - -#: ../src/ui/theme.c:1332 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "색상 지정의 색상 구성요소 \"%s\"을(를) 이해할 수 없습니다" - -#: ../src/ui/theme.c:1361 -#, c-format -msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" -msgstr "" -"섞기 형식은 \"blend/bg_color/fg_color/alpha\"입니다, \"%s\"은(는) 형식에 맞" -"지 않습니다" - -#: ../src/ui/theme.c:1372 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "색상 섞기에서 알파 값 \"%s\"을(를) 분석할 수 없습니다" - -#: ../src/ui/theme.c:1382 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "색상 섞기에서 알파 값 \"%s\"은(는) 0.0 과 1.0사이의 값이 아닙니다" - -#: ../src/ui/theme.c:1429 -#, c-format -msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "" -"그림자 형식은 \"shade/base_color/format\"입니다, \"%s\"(은)는 형식에 맞지 않" -"습니다" - -#: ../src/ui/theme.c:1440 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "그림자색에서 그림자 인자 \"%s\"(을)를 해석할 수 없습니다" - -#: ../src/ui/theme.c:1450 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "그림자색에서 그림자 인자 \"%s\"(은)는 음수입니다" - -#: ../src/ui/theme.c:1479 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "색상 \"%s\"을(를) 해석할 수 없습니다" - -#: ../src/ui/theme.c:1790 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "좌표식에 허용되지 않는 문자 '%s'(이)가 포함되어 있습니다" - -#: ../src/ui/theme.c:1817 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "좌표식에 분석할 수 없는 부동소수점 숫자 '%s'이(가) 포함되어 있습니다" - -#: ../src/ui/theme.c:1831 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "좌표식에 분석할 수 없는 정수 '%s'이(가) 포함되어 있습니다" - -#: ../src/ui/theme.c:1953 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "" -"좌표식에 이 글자 시작부분에 알 수 없는 연산자가 포함되어 있습니다: \"%s\"" - -#: ../src/ui/theme.c:2010 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "좌표식이 비어있거나 이해할 수 없습니다" - -#: ../src/ui/theme.c:2121 ../src/ui/theme.c:2131 ../src/ui/theme.c:2165 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "좌표식의 결과 값이 0로 나누었습니다" +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "모니터 크기와 가까운 창 자동 최대화" -#: ../src/ui/theme.c:2173 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:90 msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "좌표식에서 부동소수점 수에 나머지 연산을 하려 합니다" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "참이면 처음에 크기가 모니터 크기인 새 창은 최대화됩니다." -#: ../src/ui/theme.c:2229 -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "좌표식에서 피연산자가 들어갈 곳에 연산자 \"%s\"이(가) 있습니다" +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "새 창을 중앙에 놓기" -#: ../src/ui/theme.c:2238 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "좌표식에서 연산자가 들어갈 곳에 피연산자가 있습니다" - -#: ../src/ui/theme.c:2246 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "좌표식에서 피연산자 대신에 연산자로 끝나있습니다" - -#: ../src/ui/theme.c:2256 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:99 msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" -"좌표식에서 피연산자가 없는 연산자 \"%2$c\"다음에 연산자 \"%1$c\"이(가) 있습니" -"다" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "참이면, 새로운 창은 항상 사용 중인 모니터 화면의 중앙에 놓습니다." -#: ../src/ui/theme.c:2407 ../src/ui/theme.c:2452 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "좌표식에 알 수 없는 변수나 상수 \"%s\"이(가) 있습니다" +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "실험적인 기능 사용" -#: ../src/ui/theme.c:2506 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "좌표 계산 파서의 버퍼가 크기를 넘어갔습니다." - -#: ../src/ui/theme.c:2535 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "좌표식에 닫는 괄호는 있지만 여는 괄호가 없습니다" - -#: ../src/ui/theme.c:2599 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "좌표식에 여는 괄호는 있지만 닫는 괄호가 없습니다" - -#: ../src/ui/theme.c:2610 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "좌표식에 어떠한 연산자나 피연산자가 없습니다" - -#: ../src/ui/theme.c:2822 ../src/ui/theme.c:2842 ../src/ui/theme.c:2862 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "테마가 오류 값을 내는 표현식이 들어 있습니다: %s\n" - -#: ../src/ui/theme.c:4533 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:108 msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes " +"mutter request a low priority real-time scheduling. The executable or user " +"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — " +"initializes Xwayland lazily if there are X11 clients. Requires restart." msgstr "" -"이 프레임 스타일에는 <button function=\"%s\" style=\"%s\" draw_ops=\"whatever" -"\"/>가 지정되어야 합니다" +"실험적인 기능을 사용하려면, 해당 기능 키워드를 목록에 추가하십시오. 기능에 따" +"라 컴포지터를 다시 시작해야 할 수도 있습니다. 실험적인 기능은 사용할 수 없을 " +"수도 있고, 설정할 수 없을 수도 있습니다. 이 설정에 추가한 사항이 앞으로 버전" +"에서도 동작할 거라고 기대하지 마십시오. 현재 가능한 값은: • “scale-monitor-" +"framebuffer” — 머터는 기본적으로 논리 픽셀 좌표 공간에서 논리 모니터를 배치하" +"고, HiDPI 모니터를 관리하기 위해 창 내용 대신 모니터 프레임 버퍼를 스케일링합" +"니다. 재시작은 필요하지 않습니다. • “rt-scheduler” — 머터 요청을 우선순위가 " +"낮은 실시간 스케줄링으로 만듭니다. 실행 파일 또는 사용자는 CAP_SYS_NICE가 있" +"어야 합니다. 재시작이 필요합니다. • “autostart-xwayland” — X11 클라이언트가 " +"있는 경우 X웨일랜드 초기화를 늦게 합니다. 재시작이 필요합니다." -#: ../src/ui/theme.c:5066 ../src/ui/theme.c:5091 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" -"<frame state=\"%s\" resize=\"%s\" focus=\"%s\" state=\"whatever\"/> 가 없습니" -"다" +#: data/org.gnome.mutter.gschema.xml.in:134 +msgid "Modifier to use to locate the pointer" +msgstr "포인터 위치 찾기에 사용할 키" -#: ../src/ui/theme.c:5139 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "테마 \"%s\"을(를) 읽을 수 없습니다: %s\n" +#: data/org.gnome.mutter.gschema.xml.in:135 +msgid "This key will initiate the “locate pointer” action." +msgstr "이 키는 “포인터 위치 찾기” 동작을 합니다." -#: ../src/ui/theme.c:5275 ../src/ui/theme.c:5282 ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 ../src/ui/theme.c:5303 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "테마 \"%2$s\"의 <%1$s>(이)가 설정되지 않았습니다" +#: data/org.gnome.mutter.gschema.xml.in:142 +msgid "Timeout for check-alive ping" +msgstr "활성 확인 핑 시간 초과" -#: ../src/ui/theme.c:5311 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:143 msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" +"Number of milliseconds a client has to respond to a ping request in order to " +"not be detected as frozen. Using 0 will disable the alive check completely." msgstr "" -"테마 \"%2$s\"의 창 형식 \"%1$s\"에 대한 프레임 스타일이 없습니다,<window " -"type=\"%3$s\" style_set=\"whatever\"/> 엘리먼트를 추가하십시오" +"중지된 것으로 감지되지 않도록 클라이언트가 핑 요청에 응답해야 하는 시간 (밀리" +"초). 0을 사용하면 활성 확인이 완전히 비활성화됩니다." -#: ../src/ui/theme.c:5709 ../src/ui/theme.c:5771 ../src/ui/theme.c:5834 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" -"사용자 정의 상수는 대문자로 시작되어야 합니다. \"%s\"은(는) 그렇지 않습니다." +#: data/org.gnome.mutter.gschema.xml.in:165 +msgid "Select window from tab popup" +msgstr "탭 팝업에서 창 선택" -#: ../src/ui/theme.c:5717 ../src/ui/theme.c:5779 ../src/ui/theme.c:5842 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "상수 \"%s\"은(는) 이미 지정되어 있습니다" +#: data/org.gnome.mutter.gschema.xml.in:170 +msgid "Cancel tab popup" +msgstr "탭 팝업 취소" -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. +#: data/org.gnome.mutter.gschema.xml.in:175 +msgid "Switch monitor configurations" +msgstr "모니터 설정 전환" + +#: data/org.gnome.mutter.gschema.xml.in:180 +msgid "Rotates the built-in monitor configuration" +msgstr "내장된 모니터 설정을 돌아가면서 전환합니다" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "가상 터미널 1로 이동" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "가상 터미널 2로 이동" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "가상 터미널 3으로 이동" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "가상 터미널 4로 이동" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "가상 터미널 5로 이동" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "가상 터미널 6으로 이동" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "가상 터미널 7로 이동" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "가상 터미널 8로 이동" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "가상 터미널 9로 이동" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "가상 터미널 10으로 이동" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "가상 터미널 11로 이동" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "가상 터미널 12로 이동" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "바로 가기 다시 사용하기" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow X11 grabs to lock keyboard focus with Xwayland" +msgstr "키보드 포커스를 고정하는 X11 잡기를 X웨일랜드에서 허용" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 +msgid "" +"Allow all keyboard events to be routed to X11 “override redirect” windows " +"with a grab when running in Xwayland. This option is to support X11 clients " +"which map an “override redirect” window (which do not receive keyboard " +"focus) and issue a keyboard grab to force all keyboard events to that " +"window. This option is seldom used and has no effect on regular X11 windows " +"which can receive keyboard focus under normal circumstances. For a X11 grab " +"to be taken into account under Wayland, the client must also either send a " +"specific X11 ClientMessage to the root window or be among the applications " +"white-listed in key “xwayland-grab-access-rules”." +msgstr "" +"X웨일랜드 환경에서 X11 “override redirect” 창이 잡기를 할 때 모든 키보드 이벤" +"트가 전달되도록 허용합니다. 이 옵션은 X11 클라이언트의 “override redirect”(키" +"보드 포커스를 받지 않는) 창에 모든 키보드 이벤트를 강제로 적용하는 키보드 잡" +"기를 지원합니다. 이 옵션은 거의 사용되지 않으며 일반적인 상황에서 키보드 포커" +"스를 받을 수 있는 일반 X11 창에는 영향을 미치지 않습니다. 웨일랜드에서 X11 잡" +"기를 고려하려면, 클라이언트는 특정 X11 클라이언트메시지를 루트 창에 보내거나 " +"“xwayland-grab-access-rules”의 허용 목록에 있는 프로그램 중 하나여야 합니다." + +#: data/org.gnome.mutter.wayland.gschema.xml.in:84 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "X웨일랜드 프로그램에서 키보드 잡기 허용" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:85 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "" +"X웨일랜드에서 X11 키보드 잡기를 허용하거나 허용하지 않는 X11 창의 리소스 이" +"름 또는 리소스 클래스를 나열하세요. X11 창의 리소스 이름 또는 리소스 클래스" +"는 “xprop WM_CLASS\" 명령을 사용하여 얻을 수 있습니다. 와일드카드 \"*\"와 \"?" +"\"를 값에서 사용할 수 있습니다. \"!\"로 시작하는 값은 허용 목록보다 높은 우선" +"순위로 블랙리스트 처리되어, 프로그램이 기본 시스템 목록에서 빠지게 됩니다. 기" +"본 시스템 목록에 포함된 프로그램: “@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” 사용" +"자는 “restore-shortcuts” 키 바인딩에 정의된 특정 키보드 바로 가기를 사용하여 " +"기존 잡기를 중단할 수 있습니다." + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. #. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "\"%s\" 속성이 <%s> 엘리먼트에 없습니다" - -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "%d 줄 %d 문자: %s" - -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "같은 <%2$s> 엘리먼트에 \"%1$s\"속성이 두번 겹쳐져 있습니다" - -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "이 문맥의 <%2$s> 엘리먼트에 속성 \"%1$s\"은(는) 올바르지 않습니다" - -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "정수값 \"%s\"을(를) 분석할 수 없습니다" - -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "문자열 \"%2$s\"에서 이어진 문자 \"%1$s\"을(를) 이해할 수 없습니다" - -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "정수 %ld은(는) 양수여야 합니다" - -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "정수 %ld이(가) 너무 큽니다, 현재 최대값은 %d 입니다" - -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "부동소수점 수 \"%s\"(으)로 분석할 수 없습니다" - -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 +#: src/backends/meta-input-settings.c:2567 #, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "Boolean 값은 \"true\"이거나 \"false\"만 됩니다 \"%s\"은(는) 안됩니다" +msgid "Mode Switch (Group %d)" +msgstr "모드 전환 (그룹 %d)" -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "각도 값은 0.0과 360.0 사이여야 합니다, %g(으)로 되어 있습니다\n" +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2590 +msgid "Switch monitor" +msgstr "모니터 전환" -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" -"알파 값은 0.0(보이지 않음)과 1.0(완전 불투명)사이여야 합니다, %g(으)로 되어있" -"습니다\n" +#: src/backends/meta-input-settings.c:2592 +msgid "Show on-screen help" +msgstr "화면 도움말 표시" -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"잘못된 제목 확대 \"%s\" (xx-small, x-small, small, medium, large, x-large, " -"xx-large중에 하나여야 합니다)\n" +#: src/backends/meta-monitor.c:223 +msgid "Built-in display" +msgstr "내장 디스플레이" -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s> 이름 \"%s\"이(가) 두번 쓰였습니다" +#: src/backends/meta-monitor.c:252 +msgid "Unknown" +msgstr "알 수 없음" -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "<%s> 부모 \"%s\"이(가) 아직 지정되지 않았습니다" +#: src/backends/meta-monitor.c:254 +msgid "Unknown Display" +msgstr "알 수 없는 디스플레이" -#: ../src/ui/theme-parser.c:1141 +#: src/backends/meta-monitor.c:262 #, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "<%s> 위치 \"%s\"이(가) 아직 지정되지 않았습니다" +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme-parser.c:1154 +#: src/backends/meta-monitor.c:270 #, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "<%s> 는 위치나 위치를 가지는 부모를 지정하여야 합니다" - -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "배경의 알파값을 의미있는 값으로 지정해야 합니다" +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "<%2$s> 엘리먼트에 알 수 없는 형식 \"%1$s\"" +#. Translators: this string will appear in Sysprof +#: src/backends/meta-profiler.c:79 +msgid "Compositor" +msgstr "컴포지터" -# 접근키 아님 -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "<%2$s> 엘리먼트에 알 수 없는 스타일 셋 \"%1$s\"" - -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "창 형식 \"%s\"은(는) 이미 스타일 셋으로 지정되어 있습니다" - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:533 #, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "<%s> 엘리먼트는 <%s> 아래에 허용되지 않습니다" - -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" +"Another compositing manager is already running on screen %i on display “%s”." msgstr "" -"단추의 button_width/button_height 와 \"aspect_ratio\"를 한꺼번에 지정할 수 없" -"습니다" - -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "거리 \"%s\"을(를) 알 수 없습니다" - -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "가로세로비 \"%s\"을(를) 알 수 없습니다" - -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "가장자리 \"%s\"을(를) 알 수 없습니다" - -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "<%s> 엘리먼트에 \"start_angle\"이나 \"from\" 속성이 없습니다" - -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "<%s> 엘리먼트에 \"extent_angle\"이나 \"to\" 속성이 없습니다" - -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "서서히 변하는 색 형식 값 \"%s\"을(를) 이해할 수 없습니다" +"다른 창 구성 관리 프로그램이 이미 디스플레이 “%2$s” 화면 %1$i번에서 실행 중입" +"니다." -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "<%2$s> 엘리먼트의 채우기 형식 \"%1$s\"을(를) 이해할 수 없습니다" - -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "<%2$s> 엘리먼트의 state \"%1$s\"을(를) 이해할 수 없습니다" +#: src/core/bell.c:192 +msgid "Bell event" +msgstr "삑소리 이벤트" -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "<%2$s> 엘리먼트의 shadow \"%1$s\"을(를) 이해할 수 없습니다" +#: src/core/main.c:190 +msgid "Disable connection to session manager" +msgstr "세션 관리자와 연결 하지 않습니다" -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "<%2$s> 엘리먼트의 arrow \"%1$s\"을(를) 이해할 수 없습니다" +#: src/core/main.c:196 +msgid "Replace the running window manager" +msgstr "실행 중인 창 관리자를 바꿉니다" -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "\"%s\"라 불리는 <draw_ops>는 정의되지 않았습니다" +#: src/core/main.c:202 +msgid "Specify session management ID" +msgstr "세션 관리 ID를 지정합니다" -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "draw_ops를 포함하는 \"%s\"이(가) 자기 자신을 참조하고 있습니다" +#: src/core/main.c:207 +msgid "X Display to use" +msgstr "사용할 X 디스플레이" -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "프레임 조각에 대한 알 수 없는 위치 \"%s\"" +#: src/core/main.c:213 +msgid "Initialize session from savefile" +msgstr "저장 파일에서 세션을 초기화 합니다" -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "프레임 스타일은 이미 %s 위치에 조각이 있습니다" +#: src/core/main.c:219 +msgid "Make X calls synchronous" +msgstr "동기 X 호출을 합니다" -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "이름 \"%s\"을(를) 가지는 <draw_ops>가 지정되지 않았습니다" +#: src/core/main.c:226 +msgid "Run as a wayland compositor" +msgstr "웨일랜드 컴포지터로 실행합니다" -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "단추에 알 수 없는 기능 \"%s\"" +#: src/core/main.c:232 +msgid "Run as a nested compositor" +msgstr "중첩 컴포지터로 실행합니다" -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "이 버전에는 \"%s\" 단추 함수가 없습니다 (버전은 %d, 버전 %d 필요)" +#: src/core/main.c:238 +msgid "Run wayland compositor without starting Xwayland" +msgstr "웨일랜드 컴포지터를 X웨일랜드 시작없이 실행합니다" -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "단추에 알 수 없는 상태 \"%s\"" +#: src/core/main.c:246 +msgid "Run as a full display server, rather than nested" +msgstr "전체 디스플레이 서버로 실행, 중첩 컴포지터가 아님" -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "프레임 스타일에 단추의 기능 %s 상태 %s이(가) 이미 있습니다" +#: src/core/main.c:252 +msgid "Run with X11 backend" +msgstr "X11 백 엔드로 실행 합니다" -#: ../src/ui/theme-parser.c:3073 +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:151 #, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "\"%s\"은(는) focus 속성에 대한 올바른 값이 아닙니다" +msgid "“%s” is not responding." +msgstr "“%s” 창이 반응하지 않습니다." -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "\"%s\"은(는) state 속성에 대한 올바른 값이 아닙니다" - -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "\"%s\"(이)라는 스타일은 정의되지 않았습니다" - -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "resize 속성에 \"%s\"은(는) 올바른 값이 아닙니다" +#: src/core/meta-close-dialog-default.c:153 +msgid "Application is not responding." +msgstr "프로그램이 반응하지 않습니다." -#: ../src/ui/theme-parser.c:3147 -#, c-format +#: src/core/meta-close-dialog-default.c:158 msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" -"최대화/그림자 상태에서 <%s> 엘리먼트는 \"resize\" 속성을 가지지 않습니다" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." +msgstr "좀 더 기다리거나 해당 프로그램을 강제로 끝낼 수 있습니다." -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "최대화한 상태에서 <%s> 엘리먼트는 \"resize\" 속성을 가지지 않습니다" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Force Quit" +msgstr "강제로 끝내기(_F)" -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "스타일에 상태 %s 크기 조절 %s 포커스 %s에 대해 이미 지정되어 있습니다" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Wait" +msgstr "기다리기(_W)" -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 +#: src/core/mutter.c:38 #, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "스타일에 상태 %s 포커스 %s에 대해 이미 지정되어 있습니다" - -#: ../src/ui/theme-parser.c:3294 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"<piece> 엘리먼트에 두개의 draw_ops를 가질수 없습니다 (테마에 draw_ops 속성과 " -"<draw_ops> 엘리먼트를 지정했거나 두 엘리먼트를 지정했습니다" - -#: ../src/ui/theme-parser.c:3332 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"<button> 엘리먼트에 두개의 draw_ops를 가질수 없습니다 (테마에 draw_ops 속성" -"과 <draw_ops> 엘리먼트를 지정했거나 두 엘리먼트를 지정했습니다" - -#: ../src/ui/theme-parser.c:3370 msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" msgstr "" -"<menu_icon> 엘리먼트에 두개의 draw_ops를 가질수 없습니다 (테마에 draw_ops 속" -"성과 <draw_ops> 엘리먼트를 지정했거나 두 엘리먼트를 지정했습니다" - -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "잘못된 형식의 버전 '%s'" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" -#: ../src/ui/theme-parser.c:3507 -msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" -msgstr "" -"metacity-theme-1.xml 혹은 metacity-theme-2.xml 파일에서는 \"version\" 속성을 " -"사용할 수 없습니다" +#: src/core/mutter.c:52 +msgid "Print version" +msgstr "버전을 출력합니다" -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "테마에 %s 버전이 필요하지만 지원하는 테마의 최신 버전은 %d.%d입니다." +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "사용할 머터 플러그인" -#: ../src/ui/theme-parser.c:3562 +#: src/core/prefs.c:1911 #, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "테마의 최상위는 <%s> 엘리먼트가 아니라 <metacity_theme>여야 합니다" +msgid "Workspace %d" +msgstr "작업 공간 %d" -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "" -"name/author/date/description 엘리먼트 안에서 <%s> 엘리먼트가 허용되지 않습니" -"다" +#: src/core/util.c:122 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "머터가 자세한 모드 지원 없이 컴파일 되었습니다\n" -#: ../src/ui/theme-parser.c:3587 +#: src/wayland/meta-wayland-tablet-pad.c:568 #, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "<constant> 엘리먼트 안에서 <%s> 엘리먼트는 허용되지 않습니다" +msgid "Mode Switch: Mode %d" +msgstr "모드 전환: 모드 %d" -#: ../src/ui/theme-parser.c:3599 +#: src/x11/meta-x11-display.c:676 #, c-format msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." msgstr "" -"distance/border/aspect_ratio 엘리먼트 안에서 <%s> 엘리먼트가 허용되지 않습니" -"다" - -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "draw operation 엘리먼트 안에서 <%s> 엘리먼트가 허용되지 않습니다" - -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "<%2$s> 엘리먼트 안에서 <%1$s> 엘리먼트가 허용되지 않습니다" - -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "프레임 조각에 draw_ops가 제공하지 않습니다" +"디스플레이 “%s”에 이미 창 관리자가 있습니다. 현재 창 관리자를 바꾸려면 --" +"replace 옵션을 써보십시오." -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "단추에 draw_ops가 제공되지 않습니다" +#: src/x11/meta-x11-display.c:1089 +msgid "Failed to initialize GDK\n" +msgstr "GDK 초기화에 실패했습니다\n" -#: ../src/ui/theme-parser.c:3968 +#: src/x11/meta-x11-display.c:1113 #, c-format -msgid "No text is allowed inside element <%s>" -msgstr "<%s> 엘리먼트 안에 텍스트가 허용되지 않습니다" +msgid "Failed to open X Window System display “%s”\n" +msgstr "X 윈도 시스템 디스플레이 “%s”을(를) 여는데 실패하였습니다\n" -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 +#: src/x11/meta-x11-display.c:1196 #, c-format -msgid "<%s> specified twice for this theme" -msgstr "이 테마에서 <%s> 태그가 두 번 지정되었습니다" +msgid "Screen %d on display “%s” is invalid\n" +msgstr "디스플레이 “%2$s”의 화면 %1$d은(는) 잘못되었습니다\n" -#: ../src/ui/theme-parser.c:4348 +#: src/x11/meta-x11-selection-input-stream.c:460 #, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "%s 테마의 올바른 파일을 찾는 데 실패했습니다\n" - -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "창(_W)" - -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "대화 상자(_D)" - -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "모달 대화 상자(_M)" - -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "도구(_U)" - -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "스플래시 화면(_S)" - -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "위 도크(_T)" - -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "아래 도크(_B)" +msgid "Format %s not supported" +msgstr "%s 형식은 지원하지 않습니다" -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "왼쪽 도크(_L)" - -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "오른쪽 도크(_R)" - -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "모든 도크(_A)" - -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "데스크톱(_K)" - -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "이 창을 하나 더 엽니다" - -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "'열기' 아이콘이 들어 있는 데모 단추입니다" - -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "'끝내기' 아이콘이 들어 있는 데모 단추입니다" - -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "예제 대화 상자의 예제 메시지입니다" - -#: ../src/ui/theme-viewer.c:328 -#, c-format -msgid "Fake menu item %d\n" -msgstr "가짜 메뉴 항목 %d\n" - -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "테두리만 있는 창" - -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "모음" - -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "보통 프로그램 창" - -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "대화 상자" - -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "모달 대화 상자" - -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "도구 팔레트" - -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "떼어내기 메뉴" - -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "테두리" - -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "부착한 모달 대화 상자" - -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "단추 배치 테스트 %d" - -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "창 프레임 하나를 그리는 데 %g ms" - -#: ../src/ui/theme-viewer.c:813 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "사용법: metacity-theme-viewer [테마이름]\n" - -#: ../src/ui/theme-viewer.c:820 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "테마를 읽어들이는 데 오류가 발생했습니다: %s\n" - -#: ../src/ui/theme-viewer.c:826 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "\"%s\" 테마를 읽어들이는 데 %g초\n" - -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "보통 제목 글꼴" - -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "작은 제목 글꼴" - -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "큰 제목 글꼴" - -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "단추 배치" - -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "벤치마크" - -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "창 제목이 여기에 들어갑니다" - -#: ../src/ui/theme-viewer.c:1047 -#, c-format +#: src/x11/session.c:1821 msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." msgstr "" -"%d개 프레임을 그리는 데 클라이언트 입장에서 %g초가 걸렸습니다 (한 프레임에 %" -"g ms). 그리고 X 서버 리소스까지 포함해 실제 시간으로 %g 초가 걸렸습니다 (한 " -"프레임에 %g ms).\n" - -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "위치 표현식 테스트가 참을 리턴했지만 오류가 발생했습니다" - -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "위치 표현식 테스트가 거짓을 리턴했지만 오류가 발생하지 않았습니다" - -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "오류가 발생해야 하지만 발생하지 않았습니다" - -#: ../src/ui/theme-viewer.c:1274 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "오류 %d번이 발생해야 하지만 오류 %d번이 발생했습니다" - -#: ../src/ui/theme-viewer.c:1280 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "오류가 발생하면 안 되지만 오류 한 개가 발생했습니다: %s" - -#: ../src/ui/theme-viewer.c:1284 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "가로값이 %d입니다. 와야 하는 값은 %d입니다" +"이 창은 “현재 설정 저장”을 지원하지 않기 때문에 다음 번에 로그인 할 때 수동으" +"로 다시 시작해야 합니다." -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "세로값이 %d입니다. 와야 하는 값은 %d입니다" - -#: ../src/ui/theme-viewer.c:1352 +# <창제목> (on <기계>) +#: src/x11/window-props.c:569 #, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "%d개의 좌표 표현식을 %g초에 파싱했습니다 (평균 %g초)\n" - -#~ msgid "Close Window" -#~ msgstr "창 닫기" - -#~ msgid "Window Menu" -#~ msgstr "창 메뉴" - -#~ msgid "Minimize Window" -#~ msgstr "창 최소화" - -#~ msgid "Maximize Window" -#~ msgstr "창 최대화" - -#~ msgid "Restore Window" -#~ msgstr "창 복귀" - -#~ msgid "Roll Up Window" -#~ msgstr "창 말아올리기" +msgid "%s (on %s)" +msgstr "%s (%s에서)" -#~ msgid "Unroll Window" -#~ msgstr "창 펼치기" +#~ msgid "Move window one workspace to the left" +#~ msgstr "창을 한칸 왼쪽 작업 공간으로 옮기기" -#~ msgid "Keep Window On Top" -#~ msgstr "창을 맨 위에 두기" +#~ msgid "Move window one workspace to the right" +#~ msgstr "창을 한칸 오른쪽 작업 공간으로 옮기기" -#~ msgid "Remove Window From Top" -#~ msgstr "창을 맨 위에서 빼기" +#~ msgid "Move to workspace left" +#~ msgstr "왼쪽 작업 공간으로 옮기기" -#~ msgid "Always On Visible Workspace" -#~ msgstr "항상 현재 작업 공간에 놓기" +#~ msgid "Move to workspace right" +#~ msgstr "오른쪽 작업 공간으로 옮기기" -#~ msgid "Put Window On Only One Workspace" -#~ msgstr "창을 한 개 작업 공간에만 두기" +#~ msgid "Toggle shaded state" +#~ msgstr "그림자 상태 토글" diff --git a/po/ku.po b/po/ku.po index d4d93dc33..d4981e942 100644 --- a/po/ku.po +++ b/po/ku.po @@ -11,6 +11,7 @@ msgstr "" "PO-Revision-Date: 2007-03-04 21:37+0100\n" "Last-Translator: Erdal Ronahi <erdal.ronahi@gmail.com>\n" "Language-Team: Kurdish <gnu-ku-wergerandin@lists.sourceforge.net>\n" +"Language: ku\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" diff --git a/po/la.po b/po/la.po index 05bb0fc7c..f18a16160 100644 --- a/po/la.po +++ b/po/la.po @@ -11,6 +11,7 @@ msgstr "" "PO-Revision-Date: 2008-10-17 22:07-0400\n" "Last-Translator: Thomas Thurman <tthurman@gnome.org>\n" "Language-Team: Latin <la@li.org>\n" +"Language: la\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" diff --git a/po/lt.po b/po/lt.po index 6667ecee3..0d681b5c1 100644 --- a/po/lt.po +++ b/po/lt.po @@ -6,3934 +6,1262 @@ # Tomas Kuliavas <tokul@users.sourceforge.net>, 2003. # Žygimantas Beručka <zygis@gnome.org>, 2004-2007. # Gintautas Miliauskas <gintautas@miliauskas.lt>, 2007-2009, 2010. +# Aurimas Černius <aurisc4@gmail.com>, 2013-2020. +# msgid "" msgstr "" "Project-Id-Version: lt\n" -"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=muffin&keywords=I18N+L10N&component=general\n" -"POT-Creation-Date: 2011-08-10 12:42+0000\n" -"PO-Revision-Date: 2011-08-27 16:09+0300\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2020-02-23 17:41+0000\n" +"PO-Revision-Date: 2020-03-01 14:47+0200\n" "Last-Translator: Aurimas Černius <aurisc4@gmail.com>\n" -"Language-Team: Lithuanian <gnome-lt@lists.akl.lt>\n" +"Language-Team: Lietuvių <gnome-lt@lists.akl.lt>\n" +"Language: lt\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n" +"%100<10 || n%100>=20) ? 1 : 2)\n" +"X-Generator: Gtranslator 3.34.0\n" -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:487 -#, c-format -#| msgid "" -#| "Could not acquire window manager selection on screen %d display \"%s\"\n" -msgid "Another compositing manager is already running on screen %i on display \"%s\"." -msgstr "Kita kompozicijos valdyklė jau veikia ekrane %i vaizduoklyje „%s“." +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Navigacija" -#: ../src/core/all-keybindings.h:88 -msgid "Switch to workspace 1" -msgstr "Perjungti į darbalaukį Nr.1" +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Perkelti langą į darbo sritį Nr.1" -#: ../src/core/all-keybindings.h:90 -msgid "Switch to workspace 2" -msgstr "Perjungti į darbalaukį Nr.2" +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Perkelti langą į darbo sritį Nr.2" -#: ../src/core/all-keybindings.h:92 -msgid "Switch to workspace 3" -msgstr "Perjungti į darbalaukį Nr.3" +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Perkelti langą į darbo sritį Nr.3" -#: ../src/core/all-keybindings.h:94 -msgid "Switch to workspace 4" -msgstr "Perjungti į darbalaukį Nr.4" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Perkelti langą į darbo sritį Nr.4" + +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Perkelti langą į pastarąją darbo sritį" + +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "Perkelti langą į aukščiau esančią darbo sritį" + +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "Perkelti langą į žemiau esančią darbo sritį" -#: ../src/core/all-keybindings.h:96 -msgid "Switch to workspace 5" -msgstr "Perjungti į darbalaukį Nr.5" +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "Perkelti langą į kairiau esantį monitorių" -#: ../src/core/all-keybindings.h:98 -msgid "Switch to workspace 6" -msgstr "Perjungti į darbalaukį Nr.6" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "Perkelti langą į dešiniau esantį monitorių" -#: ../src/core/all-keybindings.h:100 -msgid "Switch to workspace 7" -msgstr "Perjungti į darbalaukį Nr.7" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "Perkelti langą į aukščiau esantį monitorių" -#: ../src/core/all-keybindings.h:102 -msgid "Switch to workspace 8" -msgstr "Perjungti į darbalaukį Nr.8" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "Perkelti langą į žemiau esantį monitorių" -#: ../src/core/all-keybindings.h:104 -msgid "Switch to workspace 9" -msgstr "Perjungti į darbalaukį Nr.9" +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "Pereiti tarp programų" -#: ../src/core/all-keybindings.h:106 -msgid "Switch to workspace 10" -msgstr "Perjungti į darbalaukį Nr.10" +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "Pereiti į ankstesnę programą" -#: ../src/core/all-keybindings.h:108 -msgid "Switch to workspace 11" -msgstr "Perjungti į darbalaukį Nr.11" +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "Pereiti tarp langų" -#: ../src/core/all-keybindings.h:110 -msgid "Switch to workspace 12" -msgstr "Perjungti į darbalaukį Nr.12" +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "Pereiti į ankstesnį langą" -#: ../src/core/all-keybindings.h:122 -msgid "Switch to workspace on the left of the current workspace" -msgstr "Perjungti į kairiau esantį darbalaukį" +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "Pereiti tarp programos langų" -#: ../src/core/all-keybindings.h:126 -msgid "Switch to workspace on the right of the current workspace" -msgstr "Perjungti į dešiniau esantį darbalaukį" +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "Pereiti į ankstesnį programos langą" -#: ../src/core/all-keybindings.h:130 -msgid "Switch to workspace above the current workspace" -msgstr "Perjungti į aukščiau esantį darbalaukį" +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "Pereiti tarp sistemos valdiklių" -#: ../src/core/all-keybindings.h:134 -msgid "Switch to workspace below the current workspace" -msgstr "Perjungti į žemiau esantį darbalaukį" +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "Pereiti prie ankstesnio sistemos valdiklio" -#: ../src/core/all-keybindings.h:150 -msgid "Move between windows of an application, using a popup window" -msgstr "Perjungti tarp programos langų su iššokančiu langu" +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "Tiesiogiai pereiti tarp langų" -#: ../src/core/all-keybindings.h:153 -msgid "Move backward between windows of an application, using a popup window" -msgstr "Perjungti atgal tarp programos langų su iššokančiu langu" +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "Tiesiogiai pereiti į ankstesnį langą" -#: ../src/core/all-keybindings.h:157 -msgid "Move between windows, using a popup window" -msgstr "Persijunginėti tarp langų su iššokančiu langu" +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "Tiesiogiai pereiti tarp programos langų" -#: ../src/core/all-keybindings.h:160 -msgid "Move backward between windows, using a popup window" -msgstr "Perjungti tarp langų atgal kartu su iššokančiu langu" +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "Tiesiogiai pereiti prie ankstesnio programos lango" -#: ../src/core/all-keybindings.h:163 -msgid "Move between panels and the desktop, using a popup window" -msgstr "Judėti tarp skydelių ir darbastalio su iššokančiu langu" +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "Tiesiogiai pereiti tarp sistemos valdiklių" -#: ../src/core/all-keybindings.h:166 -msgid "Move backward between panels and the desktop, using a popup window" -msgstr "Judėti atgal tarp skydelių ir darbastalio su iššokančiu langu" +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "Tiesiogiai pereiti prie ankstesnio sistemos valdiklio" -#: ../src/core/all-keybindings.h:171 -msgid "Move between windows of an application immediately" -msgstr "Greitai persijungti tarp programos langų" +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "Paslėpti visus įprastinius langus" -#: ../src/core/all-keybindings.h:174 -msgid "Move backward between windows of an application immediately" -msgstr "Iškart judėti atgal tarp programos langų" +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "Persijungti į darbo sritį Nr.1" -#: ../src/core/all-keybindings.h:177 -msgid "Move between windows immediately" -msgstr "Iškart persijungti tarp langų" +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "Persijungti į darbo sritį Nr.2" -#: ../src/core/all-keybindings.h:180 -msgid "Move backward between windows immediately" -msgstr "Iškart judėti atgal tarp langų" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "Persijungti į darbo sritį Nr.3" -#: ../src/core/all-keybindings.h:183 -msgid "Move between panels and the desktop immediately" -msgstr "Greitai judėti tarp skydelių ir darbastalio" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "Persijungti į darbo sritį Nr.4" -#: ../src/core/all-keybindings.h:186 -msgid "Move backward between panels and the desktop immediately" -msgstr "Greitas judėjimas atgal tarp skydelių ir darbastalio" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "Persijungti į pastarąją darbo sritį" -#: ../src/core/all-keybindings.h:203 -msgid "Hide all normal windows and set focus to the desktop" -msgstr "Paslėpti visus langus ir suaktyvinti darbastalį" +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "Perkelti į darbo sritį viršuje" -#: ../src/core/all-keybindings.h:206 -msgid "Show the panel's main menu" -msgstr "Rodyti skydelio pagrindinį meniu" +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "Perkelti į darbo sritį apačioje" -#: ../src/core/all-keybindings.h:209 -msgid "Show the panel's \"Run Application\" dialog box" -msgstr "Rodyti skydelio programų paleidimo langą" +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "Sistema" -#: ../src/core/all-keybindings.h:211 -msgid "Start or stop recording the session" -msgstr "Pradėti arba baigti sesijos įrašymą" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Rodyti komandų paleidimo langelį" -#: ../src/core/all-keybindings.h:252 -msgid "Take a screenshot" -msgstr "Padaryti ekrano nuotrauką" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Rodyti veiklų apžvalgą" -#: ../src/core/all-keybindings.h:254 -msgid "Take a screenshot of a window" -msgstr "Padaryti lango nuotrauką" +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Atkurti klaviatūros trumpinius" -#: ../src/core/all-keybindings.h:256 -msgid "Run a terminal" -msgstr "Paleisti terminalą" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Langai" -#: ../src/core/all-keybindings.h:271 +#: data/50-mutter-windows.xml:8 msgid "Activate the window menu" msgstr "Parodyti lango meniu" -#: ../src/core/all-keybindings.h:274 +#: data/50-mutter-windows.xml:10 msgid "Toggle fullscreen mode" msgstr "Perjungti viso ekrano veikseną" -#: ../src/core/all-keybindings.h:276 +#: data/50-mutter-windows.xml:12 msgid "Toggle maximization state" -msgstr "Perjungti lango išdidinimo veikseną" - -#: ../src/core/all-keybindings.h:278 -msgid "Toggle whether a window will always be visible over other windows" -msgstr "Nurodyti, ar langas visada matomas virš kitų langų" +msgstr "Perjungti lango išdidinimo būseną" -#: ../src/core/all-keybindings.h:280 +#: data/50-mutter-windows.xml:14 msgid "Maximize window" msgstr "Išdidinti langą" -#: ../src/core/all-keybindings.h:282 +#: data/50-mutter-windows.xml:16 msgid "Restore window" msgstr "Atkurti lango dydį" -#: ../src/core/all-keybindings.h:284 -msgid "Toggle shaded state" -msgstr "Perjungti lango sutraukimo būseną" - -#: ../src/core/all-keybindings.h:286 -msgid "Minimize window" -msgstr "Sumažinti langą" - -#: ../src/core/all-keybindings.h:288 +#: data/50-mutter-windows.xml:18 msgid "Close window" msgstr "Užverti langą" -#: ../src/core/all-keybindings.h:290 +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "Slėpti langą" + +#: data/50-mutter-windows.xml:22 msgid "Move window" msgstr "Perkelti langą" -#: ../src/core/all-keybindings.h:292 +#: data/50-mutter-windows.xml:24 msgid "Resize window" msgstr "Keisti lango dydį" -#: ../src/core/all-keybindings.h:295 -msgid "Toggle whether window is on all workspaces or just one" -msgstr "Keisti lango matomumą visuose darbalaukiuose" - -#: ../src/core/all-keybindings.h:299 -msgid "Move window to workspace 1" -msgstr "Perkelti langą į darbalaukį Nr.1" - -#: ../src/core/all-keybindings.h:302 -msgid "Move window to workspace 2" -msgstr "Perkelti langą į darbalaukį Nr.2" - -#: ../src/core/all-keybindings.h:305 -msgid "Move window to workspace 3" -msgstr "Perkelti langą į darbalaukį Nr.3" - -#: ../src/core/all-keybindings.h:308 -msgid "Move window to workspace 4" -msgstr "Perkelti langą į darbalaukį Nr.4" - -#: ../src/core/all-keybindings.h:311 -msgid "Move window to workspace 5" -msgstr "Perkelti langą į darbalaukį Nr.5" - -#: ../src/core/all-keybindings.h:314 -msgid "Move window to workspace 6" -msgstr "Perkelti langą į darbalaukį Nr.6" - -#: ../src/core/all-keybindings.h:317 -msgid "Move window to workspace 7" -msgstr "Perkelti langą į darbalaukį Nr.7" - -#: ../src/core/all-keybindings.h:320 -msgid "Move window to workspace 8" -msgstr "Perkelti langą į darbalaukį Nr.8" - -#: ../src/core/all-keybindings.h:323 -msgid "Move window to workspace 9" -msgstr "Perkelti langą į darbalaukį Nr.9" - -#: ../src/core/all-keybindings.h:326 -msgid "Move window to workspace 10" -msgstr "Perkelti langą į darbalaukį Nr.10" - -#: ../src/core/all-keybindings.h:329 -msgid "Move window to workspace 11" -msgstr "Perkelti langą į darbalaukį Nr.11" +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "Perjungti lango buvimo visose darbo srityse būseną" -#: ../src/core/all-keybindings.h:332 -msgid "Move window to workspace 12" -msgstr "Perkelti langą į darbalaukį Nr.12" - -#: ../src/core/all-keybindings.h:344 -msgid "Move window one workspace to the left" -msgstr "Perkelti langą į kairiau esantį darbalaukį" - -#: ../src/core/all-keybindings.h:347 -msgid "Move window one workspace to the right" -msgstr "Perkelti langą į dešiniau esantį darbalaukį" - -#: ../src/core/all-keybindings.h:350 -msgid "Move window one workspace up" -msgstr "Perkelti langą į aukščiau esantį darbalaukį" - -#: ../src/core/all-keybindings.h:353 -msgid "Move window one workspace down" -msgstr "Perkelti langą į žemiau esantį darbalaukį" - -#: ../src/core/all-keybindings.h:356 -msgid "Raise window if it's covered by another window, otherwise lower it" -msgstr "Iškelti neaktyvų langą, jei jis uždengtas kito lango, kitu atveju – paslėpti jį" +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "" +"Iškelti langą, jei jis uždengtas kito lango, priešingu atveju jį nuleisti" -#: ../src/core/all-keybindings.h:358 +#: data/50-mutter-windows.xml:31 msgid "Raise window above other windows" msgstr "Iškelti langą virš kitų langų" -#: ../src/core/all-keybindings.h:360 +#: data/50-mutter-windows.xml:33 msgid "Lower window below other windows" msgstr "Nuleisti langą žemiau kitų langų" -#: ../src/core/all-keybindings.h:364 +#: data/50-mutter-windows.xml:35 msgid "Maximize window vertically" msgstr "Išdidinti langą vertikaliai" -#: ../src/core/all-keybindings.h:368 +#: data/50-mutter-windows.xml:37 msgid "Maximize window horizontally" msgstr "Išdidinti langą horizontaliai" -#: ../src/core/all-keybindings.h:372 -msgid "Move window to north-west (top left) corner" -msgstr "Perkelti langą į ekrano viršutinį kairįjį kampą" - -#: ../src/core/all-keybindings.h:375 -msgid "Move window to north-east (top right) corner" -msgstr "Perkelti langą į ekrano viršutinį dešinįjį kampą" - -#: ../src/core/all-keybindings.h:378 -msgid "Move window to south-west (bottom left) corner" -msgstr "Perkelti langą į ekrano apatinį kairįjį kampą" - -#: ../src/core/all-keybindings.h:381 -msgid "Move window to south-east (bottom right) corner" -msgstr "Perkelti langą į ekrano apatinį dešinįjį kampą" - -#: ../src/core/all-keybindings.h:385 -msgid "Move window to north (top) side of screen" -msgstr "Perkelti langą į viršutinę ekrano dalį" - -#: ../src/core/all-keybindings.h:388 -msgid "Move window to south (bottom) side of screen" -msgstr "Perkelti langą į apatinę ekrano pusę" - -#: ../src/core/all-keybindings.h:391 -msgid "Move window to east (right) side of screen" -msgstr "Perkelti langą į dešinę ekrano pusę" - -#: ../src/core/all-keybindings.h:394 -msgid "Move window to west (left) side of screen" -msgstr "Perkelti langą į kairę ekrano pusę" - -#: ../src/core/all-keybindings.h:397 -msgid "Move window to center of screen" -msgstr "Perkelti langą į ekrano vidurį" - -#: ../src/core/bell.c:310 -msgid "Bell event" -msgstr "Skambučio įvykis" - -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Nežinoma langų informacijos užklausa: %d" - -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> neatsiliepia į komandas." - -#: ../src/core/delete.c:114 -#| msgid "<tt>%s</tt> is not responding." -msgid "Application is not responding." -msgstr "Programa neatsiliepia į komandas." - -#: ../src/core/delete.c:119 -msgid "You may choose to wait a short while for it to continue or force the application to quit entirely." -msgstr "Galite šiek tiek palaukti arba priverstinai uždaryti programą." - -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "_Laukti" - -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "_Priverstinai išeiti" - -#: ../src/core/display.c:365 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "Trūksta %s priedo, reikalingo komponavimui" - -#: ../src/core/display.c:431 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Nepavyko atverti X Window sistemos ekrano „%s“\n" - -#: ../src/core/keybindings.c:759 -#, c-format -msgid "Some other program is already using the key %s with modifiers %x as a binding\n" -msgstr "Kažkokia kita programa jau naudoja %s klavišą su modifikatoriais %x kaip susiejimą\n" - -#. Displayed when a keybinding which is -#. * supposed to launch a program fails. -#. -#: ../src/core/keybindings.c:2523 -#, c-format -msgid "" -"There was an error running <tt>%s</tt>:\n" -"\n" -"%s" -msgstr "" -"Įvyko klaida bandant paleisti <tt>%s</tt>:\n" -"\n" -"%s." - -#: ../src/core/keybindings.c:2613 -#, c-format -msgid "No command %d has been defined.\n" -msgstr "Komanda %d neaprašyta.\n" - -#: ../src/core/keybindings.c:3625 -#, c-format -msgid "No terminal command has been defined.\n" -msgstr "Terminalo komanda nebuvo nurodyta.\n" - -#: ../src/core/main.c:206 -msgid "Disable connection to session manager" -msgstr "Išjungti susijungimą su sesijos valdykle" - -#: ../src/core/main.c:212 -#| msgid "Replace the running window manager with Muffin" -msgid "Replace the running window manager" -msgstr "Pakeisti veikiančią langų valdyklę" - -#: ../src/core/main.c:218 -msgid "Specify session management ID" -msgstr "Nurodyti sesijos valdymo ID" - -#: ../src/core/main.c:223 -msgid "X Display to use" -msgstr "Naudotinas X ekranas" - -#: ../src/core/main.c:229 -msgid "Initialize session from savefile" -msgstr "Inicializuoti sesiją iš išsaugojimo failo" - -#: ../src/core/main.c:235 -msgid "Make X calls synchronous" -msgstr "Sinchronizuoti X iškvietimus" - -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Nepavyko nuskanuoti temų aplanko: %s\n" - -#: ../src/core/main.c:520 -#, c-format -msgid "Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "Nepavyko rasti temos! Įsitikinkite, kad %s egzistuoja ir kad ten yra įprastos temos.\n" - -#: ../src/core/muffin.c:42 -#, c-format -msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" -msgstr "" -"muffin %s\n" -"Autorinės teisės (C) priklauso 2001-%d Havoc Pennington, Red Hat, Inc.\n" -"ir kitiems.\n" -"Tai yra laisva programinė įranga; platinimo sąlygos yra aprašytos \n" -"programos pradiniuose tekstuose.\n" -"Nėra JOKIOS garantijos; net dėl PREKIAVIMO ar TAM TIKRO PANAUDOJIMO TIKSLO ATITIKIMO.\n" - -#: ../src/core/muffin.c:56 -msgid "Print version" -msgstr "Parodyti versiją" - -#: ../src/core/muffin.c:62 -msgid "Comma-separated list of compositor plugins" -msgstr "Kableliais skiriami komponuotojo įskiepiai" - -#. -#. * We found it, but it was invalid. Complain. -#. * -#. * FIXME: This replicates the original behaviour, but in the future -#. * we might consider reverting invalid keys to their original values. -#. * (We know the old value, so we can look up a suitable string in -#. * the symtab.) -#. * -#. * (Empty comment follows so the translators don't see this.) -#. -#. -#: ../src/core/prefs.c:550 -#: ../src/core/prefs.c:711 -#, c-format -msgid "GConf key '%s' is set to an invalid value\n" -msgstr "GConf rakte „%s“ nurodyta netinkama reikšmė\n" - -#: ../src/core/prefs.c:637 -#: ../src/core/prefs.c:880 -#, c-format -msgid "%d stored in GConf key %s is out of range %d to %d\n" -msgstr "%d reikšmė, saugoma GConf rakte %s, netelpa tarp %d ir %d\n" - -#: ../src/core/prefs.c:681 -#: ../src/core/prefs.c:758 -#: ../src/core/prefs.c:806 -#: ../src/core/prefs.c:870 -#: ../src/core/prefs.c:1331 -#: ../src/core/prefs.c:1347 -#: ../src/core/prefs.c:1364 -#: ../src/core/prefs.c:1380 -#, c-format -msgid "GConf key \"%s\" is set to an invalid type\n" -msgstr "GConf raktui „%s“ nustatytas neteisingas tipas\n" - -#: ../src/core/prefs.c:1210 -#, c-format -msgid "GConf key %s is already in use and can't be used to override %s\n" -msgstr "GConf raktas %s jau naudojamas ir negali būti naudojamas %s pakeitimui\n" - -#: ../src/core/prefs.c:1269 -#, c-format -msgid "Can't override GConf key, %s not found\n" -msgstr "Negalima pakeisti GConf rakto, %s nerastas\n" - -#: ../src/core/prefs.c:1454 -msgid "Workarounds for broken applications disabled. Some applications may not behave properly.\n" -msgstr "Apsauga nuo sugadintų programų atjungta. Kai kurios programos gali pradėti keistai elgtis.\n" - -#: ../src/core/prefs.c:1531 -#, c-format -msgid "Could not parse font description \"%s\" from GConf key %s\n" -msgstr "Nepavyko apdoroti šrifto aprašymo „%s“ saugomo GConf rakte %s\n" - -#: ../src/core/prefs.c:1593 -#, c-format -msgid "\"%s\" found in configuration database is not a valid value for mouse button modifier\n" -msgstr "„%s“ reikšmė rasta nustatymų duomenų bazėje yra netinkama pelės mygtuko keitiklio aprašymui\n" - -#: ../src/core/prefs.c:2028 -#, c-format -msgid "Error setting number of workspaces to %d: %s\n" -msgstr "Įvyko klaida nustatant darbalaukų skaičių į %d: %s\n" - -#: ../src/core/prefs.c:2212 -#: ../src/core/prefs.c:2714 -#, c-format -msgid "Workspace %d" -msgstr "Darbalaukis %d" - -#: ../src/core/prefs.c:2244 -#: ../src/core/prefs.c:2422 -#, c-format -msgid "\"%s\" found in configuration database is not a valid value for keybinding \"%s\"\n" -msgstr "„%s“ reikšmė rasta konfiguracijos duomenų bazė yra netinkama klavišų kombinacijai „%s“\n" - -#: ../src/core/prefs.c:2795 -#, c-format -msgid "Error setting name for workspace %d to \"%s\": %s\n" -msgstr "Įvyko klaida pervadinant darbalaukį %d į „%s“: %s\n" - -#: ../src/core/prefs.c:3009 -#, c-format -msgid "Error setting live hidden windows status status: %s\n" -msgstr "Įvyko klaida nustatant „gyvo“ paslėpto lango būsenos būseną: %s\n" - -#: ../src/core/prefs.c:3044 -#, c-format -msgid "Error setting no tab popup status: %s\n" -msgstr "Įvyko klaida nustatant iššokimo be kortelių būseną: %s\n" - -#: ../src/core/screen.c:663 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "Ekranas %d vaizduoklyje „%s“ netinkamas\n" - -#: ../src/core/screen.c:679 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager; try using the --replace option to replace the current window manager.\n" -msgstr "Ekranas %d vaizduoklyje „%s“ jau turi langų valdyklę; pabandykite pasinaudoti parinktimi --replace, jei norite pakeisti esamą langų valdyklę.\n" - -#: ../src/core/screen.c:706 -#, c-format -msgid "Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "Nepavyko aptikti langų valdyklės pasirinkimo ekrano %d vaizduoklyje „%s“\n" - -#: ../src/core/screen.c:761 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "Ekranas %d vaizduoklyje „%s“ jau turi langų valdyklę\n" - -#: ../src/core/screen.c:946 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "Nepavyko pasitraukti iš ekrano %d vaizduoklyje „%s“\n" - -#: ../src/core/session.c:843 -#: ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Nepavyko sukurti aplanko „%s“: %s\n" - -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "Nepavyko rašymui atverti seanso failo „%s“: %s\n" - -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Klaida rašant į seanso failą „%s“: %s\n" - -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Klaida uždarant seanso failą „%s“: %s\n" - -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Nepavyko apdoroti išsaugoto seanso failo: %s\n" - -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "Aptiktas <muffin_session> požymis, bet sistema jau nustatė sesijos ID" - -#: ../src/core/session.c:1198 -#: ../src/core/session.c:1273 -#: ../src/core/session.c:1305 -#: ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Nežinomas požymis %s <%s> elemente" - -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "įterpta <window> žyma" - -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "Nežinomas elementas %s" - -#: ../src/core/session.c:1809 -msgid "These windows do not support "save current setup" and will have to be restarted manually next time you log in." -msgstr "Šie langai nepalaiko "išsaugoti esamus nustatymus" komandos ir turi būti paleisti rankiniu būdu, kai prisijungsite kitą kartą." - -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Nepavyko atverti derinimo žurnalo: %s\n" - -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Funkcija fdopen() su žurnalo failu %s nesėkminga: %s\n" - -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "Atvertas žurnalo failas %s\n" - -#: ../src/core/util.c:146 -#: ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "Muffin buvo sukompiliuota be išsamaus veikimo veiksenos\n" - -#: ../src/core/util.c:286 -msgid "Window manager: " -msgstr "Langų valdyklė:" - -#: ../src/core/util.c:434 -msgid "Bug in window manager: " -msgstr "Klaida langų valdyklėje:" - -#: ../src/core/util.c:467 -msgid "Window manager warning: " -msgstr "Langų valdyklės perspėjimas:" - -#: ../src/core/util.c:495 -msgid "Window manager error: " -msgstr "Langų valdyklės klaida:" - -#. Translators: This is the title used on dialog boxes -#: ../src/core/util.c:632 -#: ../src/muffin.desktop.in.h:1 -#: ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" - -#. first time through -#: ../src/core/window.c:6959 -#, c-format -msgid "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER window as specified in the ICCCM.\n" -msgstr "Langas %s nustatė SM_CLIENT_ID kintamajį į save patį vietoj to, kad nustatytų jį į WM_CLIENT_LEADER langą kaip nurodo ICCCM..\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7622 -#, c-format -msgid "Window %s sets an MWM hint indicating it isn't resizable, but sets min size %d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "Langas %s nustatė MWM požymį teigdamas, kad jo dydis nėra kintamas, tačiau tuo pat metu nustatė ir leistinas mažiausio dydžio %d x %d bei didžiausio dydžio %d x %d reikšmes; tai yra beprasmiška.\n" - -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "Programa nustatė netinkamą _NET_WM_PID %lu\n" +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "Rodyti skyrimą kairėje" -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (kompiuteryje %s)" +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "Rodyti skyrimą dešinėje" -#: ../src/core/window-props.c:1488 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "Nekorektiškas WM_TRANSIENT_FOR langas 0x%lx nurodytas %s.\n" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" -#: ../src/core/window-props.c:1500 -#, c-format -#| msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "WM_TRANSIENT_FOR langas 0x%lx nurodytas %s sukurtų ciklą.\n" +#: data/org.gnome.mutter.gschema.xml.in:7 +msgid "Modifier to use for extended window management operations" +msgstr "Klavišas, naudojamas kartu su specialiomis lango tvarkymo operacijomis" -#: ../src/core/xprops.c:155 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:8 msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." msgstr "" -"Langas 0x%lx turi požymį %s\n" -"kuris turėtų turėti type %s format %d atributus\n" -"tačiau jis turi type %s format %d n_items %d atributus.\n" -"Greičiausiai tai yra programos, o ne langų valdyklės klaida.\n" -"Langas turi požymius title=\"%s\" class=\"%s\" name=\"%s\"\n" - -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "Požymis %s lange 0x%lx saugo nepriimtinus UTF-8 simbolius\n" +"Šis klavišas inicijuos „perdangą“, kuri yra langų apžvalgos ir programų " +"paleidimo sistemos kombinacija. Numatytasis nustatymas – „Windows klavišas“. " +"Tikimasi, kad šis susiejimas bus arba numatytasis, arba nustatytas į tuščią." -#: ../src/core/xprops.c:494 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "Požymis %s lange 0x%lx naudoja nepriimtinus UTF-8 simbolius sąrašo punkte %d\n" - -#: ../src/muffin.schemas.in.h:1 +#: data/org.gnome.mutter.gschema.xml.in:20 msgid "Attach modal dialogs" msgstr "Prikabinti modalinius dialogus" -#: ../src/muffin.schemas.in.h:2 -msgid "Determines whether hidden windows (i.e., minimized windows and windows on other workspaces than the current one) should be kept alive." -msgstr "Nusako, ar paslėpti langai (pvz. sumažinti langai ir langai kituose darbalaukiuose) turėtų būti laikomi „gyvi“." - -#: ../src/muffin.schemas.in.h:3 -msgid "Determines whether workspace switching should happen for windows on all monitors or only for windows on the primary monitor." -msgstr "Nusako, ar darbalaukių perjungimas turi įvykti langams viusose monitoriuose, ar tik langams pagrindiniame monitoriuje." - -#: ../src/muffin.schemas.in.h:4 -msgid "Draggable border width" -msgstr "Tempiamos paraštės prolis" - -#: ../src/muffin.schemas.in.h:5 -msgid "Live Hidden Windows" -msgstr "„Gyvi“ paslėpti langai" - -#: ../src/muffin.schemas.in.h:6 -msgid "Modifier to use for extended window management operations" -msgstr "Klavišas, naudojamas kartu su specialiais lango valdymo veiksmais" - -#: ../src/muffin.schemas.in.h:7 -msgid "The amount of total draggable borders. If the theme's visible borders are not enough, invisible borders will be added to meet this value." -msgstr "Bendros tempiamos paraštės dydis. Jei temos matomos paraštės yra nepakankamos, bus pridėtos nematomos paraštės." - -#: ../src/muffin.schemas.in.h:8 -msgid "This key will initiate the \"overlay\", which is a combination window overview and application launching system. The default is intended to be the \"Windows key\" on PC hardware. It's expected that this binding either the default or set to the empty string." -msgstr "Šis klavišas inicijuos „padengimą“, kuris yra langų apžvalgos ir programų paleidimo sistemos kombinacija. Numatytasis nustatymas – „Windows klavišas“. Tikimasi, kad šis susiejimas bus arba numatytasis, arba nustatytas į tuščią." - -#: ../src/muffin.schemas.in.h:9 -msgid "When true, instead of having independent titlebars, modal dialogs appear attached to the titlebar of the parent window and are moved together with the parent window." -msgstr "Kai teigiama, užuot turėje nepriklausomas antraštes, modaliniai dialogai pasirodys prikabinti prie tėvinio lango antraštės ir yra perkialiami kartu su tėviniu langu." - -#: ../src/muffin.schemas.in.h:10 -msgid "Workspaces only on primary" -msgstr "Darbalaukiai tik pagrindiniame" - -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "Naudojimas: %s\n" - -#: ../src/ui/frames.c:1123 -msgid "Close Window" -msgstr "Užverti langą" - -#: ../src/ui/frames.c:1126 -msgid "Window Menu" -msgstr "Lango meniu" - -#: ../src/ui/frames.c:1129 -msgid "Minimize Window" -msgstr "Sumažinti langą" - -#: ../src/ui/frames.c:1132 -msgid "Maximize Window" -msgstr "Išdidinti langą" - -#: ../src/ui/frames.c:1135 -msgid "Restore Window" -msgstr "Atkurti lango dydį" - -#: ../src/ui/frames.c:1138 -msgid "Roll Up Window" -msgstr "Suvynioti langą" - -#: ../src/ui/frames.c:1141 -msgid "Unroll Window" -msgstr "Išvynioti langą" - -#: ../src/ui/frames.c:1144 -msgid "Keep Window On Top" -msgstr "Langas visada viršuje" - -#: ../src/ui/frames.c:1147 -msgid "Remove Window From Top" -msgstr "Langas nebūtinai viršuje" - -#: ../src/ui/frames.c:1150 -msgid "Always On Visible Workspace" -msgstr "Visada matomame darbalaukyje" - -#: ../src/ui/frames.c:1153 -msgid "Put Window On Only One Workspace" -msgstr "Langas tik viename darbalaukyje" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "Sumaži_nti" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "Iš_didinti" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "_Grąžinti iš išdidinimo" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "Su_vynioti" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "_Išvynioti" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "Pe_rkelti" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "_Keisti dydį" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "Perkelti lango juostą ant _ekrano" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 -#: ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "Visada _viršuje" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "_Visada matomame darbalaukyje" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "_Tik šiame darbalaukyje" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "Perkelti _langą į kairįjį darbalaukį" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "Pe_rkelti langą į dešinįjį darbalaukį" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "Perkelti langą į a_ukštesnįjį darbalaukį" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "Perkelti langą į ž_emesnįjį darbalaukį" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "_Užverti" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "Darbalaukis %d%n" - -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "1_0-tas darbalaukis" - -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "Darbalaukis %s%d" - -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "Perkelti langą į kitą _darbalaukį" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" - -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" - -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "viršus" - -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "apačia" - -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "kairė" - -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "dešinė" - -#: ../src/ui/theme.c:286 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "rėmelio aprašyme nenurodytas „%s“ matmuo" - -#: ../src/ui/theme.c:305 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "rėmelio aprašyme nenurodytas paraštės „%2$s“ „%1$s“ matmuo" - -#: ../src/ui/theme.c:342 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "Mygtuko dydžio santykis %g yra nenuosaikus" - -#: ../src/ui/theme.c:354 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "Rėmelio aprašyme nenurodytas mygtukų dydis" - -#: ../src/ui/theme.c:1060 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "Aprašant persiliejančias spalvas reikia nurodyti bent dvi spalvas" - -#: ../src/ui/theme.c:1205 -#, c-format -#| msgid "" -#| "GTK color specification must have a close bracket after the state, e.g. " -#| "gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgid "GTK custom color specification must have color name and fallback in parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" -msgstr "GTK spalvų aprašymas po būsenos turi turėti spalvos pavadinimą ir uždarančius laužtinius skliaustus, pvz.: gtk:custom(foo,bar); nepavyko perskaityti „%s“" - -#: ../src/ui/theme.c:1221 -#, c-format -msgid "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-_ are valid" -msgstr "Netinkamas simbolis „%c“ gtk:custom parametre color_name, leidžiama tik A-Za-z0-9_" - -#: ../src/ui/theme.c:1235 -#, c-format -#| msgid "" -#| "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the " -#| "format" -msgid "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not fit the format" -msgstr "Gtk:custom formatas yra „gtk:custom(color_name,fallback)“, „%s“ neatitinka šio formato" - -#: ../src/ui/theme.c:1271 -#, c-format -msgid "GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "GTK spalvų aprašymas turi turėti būsenos aprašymą patalpintą tarp laužtinių skliaustų, pvz.: gtk:fg[NORMAL], kur NORMAL yra būsena; nepavyko apdoroti \"%s\"" - -#: ../src/ui/theme.c:1285 -#, c-format -msgid "GTK color specification must have a close bracket after the state, e.g. gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "GTK spalvų aprašymas po būsenos turi turėti uždarančius laužtinius skliaustus, pvz.: gtk:fg[NORMAL], kur NORMAL yra būsena; nepavyko apdoroti \"%s\"" - -#: ../src/ui/theme.c:1296 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "Nesuprantama spalvų aprašymo būsena \"%s\"" - -#: ../src/ui/theme.c:1309 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "Spalvų aprašyme nurodytas nesuprantamas spalvos komponentas \"%s\"" - -#: ../src/ui/theme.c:1339 -#, c-format -msgid "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the format" -msgstr "Išplaukimo formatas yra \"blend/bg_color/fg_color/alpha\", \"%s\" neatitinka šio formato" - -#: ../src/ui/theme.c:1350 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "Nepavyko aprodoti skaidrumo reikšmės \"%s\" priskirtos išplaukiančiai spalva" - -#: ../src/ui/theme.c:1360 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "Skaidrumo reikšmė \"%s\" tarp išplaukiančios spalvos yra ne tarp 0.0 ir 1.0" - -#: ../src/ui/theme.c:1407 -#, c-format -msgid "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "Šešėlio formatas yra \"shade/base_color/factor\", \"%s\" neatitinka šio formato" - -#: ../src/ui/theme.c:1418 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "Nepavyko apdoroti šešėlinės spalvos šešėlių rodiklio \"%s\"" - -#: ../src/ui/theme.c:1428 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "Šešėlio rodiklis \"%s\" tarp šešėlinės spalvos yra neigiamas" - -#: ../src/ui/theme.c:1457 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Nepavyko apdoroti spalvos \"%s\"" - -#: ../src/ui/theme.c:1768 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "Koordinačių išraiška turi neleistiną simbolį '%s'" - -#: ../src/ui/theme.c:1795 -#, c-format -msgid "Coordinate expression contains floating point number '%s' which could not be parsed" -msgstr "Koordinačių išraiška turi skaičių su slankiu kableliu '%s', kuris negali būti apdorotas" - -#: ../src/ui/theme.c:1809 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "Koordinačių išraiška turi sveiką skaičių '%s', kuris negali būti apdorotas" - -#: ../src/ui/theme.c:1931 -#, c-format -msgid "Coordinate expression contained unknown operator at the start of this text: \"%s\"" -msgstr "Koordinačių išraiškoje nurodytas nežinomas operatorius šio teksto pradžioje: \"%s\"" - -#: ../src/ui/theme.c:1988 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "Koordinačių išraiška tuščia arba nesuprantama" - -#: ../src/ui/theme.c:2099 -#: ../src/ui/theme.c:2109 -#: ../src/ui/theme.c:2143 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "Koordinačių išraiška sukelia dalybą iš nulio" - -#: ../src/ui/theme.c:2151 -#, c-format -msgid "Coordinate expression tries to use mod operator on a floating-point number" -msgstr "Koordinačių išraiška bando panaudoti liekanos operatorių (mod) slankaus kablelio skaičiui" - -#: ../src/ui/theme.c:2207 -#, c-format -msgid "Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "Koordinačių išraiškoje įvestas operatorius \"%s\" ten, kur turi būti vedamas operandas" - -#: ../src/ui/theme.c:2216 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "Koordinačių išraiškoje operandas įrašytas operatoriaus vietoje" - -#: ../src/ui/theme.c:2224 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "Koordinačių išraiška pasibaigė operatoriumi, o ne operandu" - -#: ../src/ui/theme.c:2234 -#, c-format -msgid "Coordinate expression has operator \"%c\" following operator \"%c\" with no operand in between" -msgstr "Koordinačių išraiškoje operatorius \"%c\" eina po operatoriaus \"%c\" be tarpinio operando" - -#: ../src/ui/theme.c:2385 -#: ../src/ui/theme.c:2430 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "Koordinačių išraiška saugo nežinomą kintamąjį arba konstantą \"%s\"" - -#: ../src/ui/theme.c:2484 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "Koordinačių išraiškų skaitytuvas perpildė buferį." - -#: ../src/ui/theme.c:2513 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "Koordinačių išraiškoje įvesti uždarantys skliaustai, nors atidarančių skliaustų nerasta" - -#: ../src/ui/theme.c:2577 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "Koordinačių išraiškoje po atidarančių skliaustų neįvesti uždarantys skliaustai" - -#: ../src/ui/theme.c:2588 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "Koordinačių išraiška neturi jokių operatorių ar operandų" - -#: ../src/ui/theme.c:2800 -#: ../src/ui/theme.c:2820 -#: ../src/ui/theme.c:2840 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "Temoje esanti išraiška sukėlė klaidą: %s\n" - -#: ../src/ui/theme.c:4511 -#, c-format -msgid "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be specified for this frame style" -msgstr "Šiam rėmelio stiliui turi būti nurodytas <button function=\"%s\" state=\"%s\" draw_ops=\"kažkokswhatever\"/> požymis" - -#: ../src/ui/theme.c:5044 -#: ../src/ui/theme.c:5069 -#, c-format -msgid "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "Trūksta <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"kažkoks\"/>" - -#: ../src/ui/theme.c:5117 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Nepavyko paleisti temos \"%s\": %s\n" - -#: ../src/ui/theme.c:5253 -#: ../src/ui/theme.c:5260 -#: ../src/ui/theme.c:5267 -#: ../src/ui/theme.c:5274 -#: ../src/ui/theme.c:5281 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "Temoje \"%2$s\" trūksta <%1$s> nustatymų" - -#: ../src/ui/theme.c:5289 -#, c-format -msgid "No frame style set for window type \"%s\" in theme \"%s\", add a <window type=\"%s\" style_set=\"whatever\"/> element" -msgstr "Rėmelio stilius nenurodytas lango tipui \"%s\" temoje \"%s\", pridėkite <window type=\"%s\" style_set=\"kažkoks\"/> elementą" - -#: ../src/ui/theme.c:5728 -#: ../src/ui/theme.c:5790 -#: ../src/ui/theme.c:5853 -#, c-format -msgid "User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "Naudotojo nustatytos konstantos turi prasidėti didžiąja raide; „%s“ nėra didžioji" - -#: ../src/ui/theme.c:5736 -#: ../src/ui/theme.c:5798 -#: ../src/ui/theme.c:5861 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "Konstanta „%s“ jau aprašyta" - -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. -#. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "Trūksta „%s“ požymio elemente <%s>" - -#: ../src/ui/theme-parser.c:265 -#: ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "%d eilutės simbolis %d: %s" - -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "Požymis „%s“ pasikartoja tame pačiame <%s> elemente" - -#: ../src/ui/theme-parser.c:503 -#: ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "Šiame kontekste požymis „%s“ yra netinkamas elemente <%s>" - -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "Nepavyko apdoroti „%s“ kaip sveiko skaičiaus" - -#: ../src/ui/theme-parser.c:603 -#: ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "Nesuprantami simbolių seką „%2$s“ užbaigiantys simboliai „%1$s“" - -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "Sveikas skaičius %ld turi būti teigiamas" - -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "Sveikas skaičius %ld yra per didelis, didžiausia galima reikšmė šiuo metu yra %d" - -#: ../src/ui/theme-parser.c:649 -#: ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "Nepavyko aprodyti „%s“ kaip skaičiaus su slankiu kableliu" - -#: ../src/ui/theme-parser.c:680 -#: ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "Loginės reikšmės turi būti \"true\" arba \"false\", o ne \"%s\"" - -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "Kampas turi būti tarp 0.0 ir 360.0, o buvo nurodyta %g\n" - -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "Skaidrumo reikšmė turi būti tarp 0.0 (nematomas) ir 1.0 (visiškai neskaidrus), o buvo nurodyta %g\n" - -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium,large,x-large,xx-large)\n" -msgstr "Netinkamas antraštės mastelis \"%s\" (turi būti viena iš xx-small,x-small,small,medium,large,x-large,xx-large reikšmių)\n" - -#: ../src/ui/theme-parser.c:1019 -#: ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 -#: ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s> požymis name \"%s\" panaudotas antrą kartą" - -#: ../src/ui/theme-parser.c:1031 -#: ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "Nenurodytas <%s> požymis parent \"%s\"" - -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "Nenurodytas <%s> požymis geometry \"%s\"" - -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "<%s> turi nurodyti dydžio (geometrijos) nustatymus arba viršesnį elementą, jau turinti tokius nustatymus" - -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "Turite nustatyti foną, kad alfa reikšmė būtų prasminga" - -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Nežinomas type \"%s\" požymis elemente <%s>" - -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "Nežinomas style_set \"%s\" požymis elemente <%s>" - -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "Lango type \"%s\" požymis jau turi nurodytą stiliaus aprašymą" - -#: ../src/ui/theme-parser.c:1313 -#: ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 -#: ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 -#: ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 -#: ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 -#: ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "Elementas <%s> neleistinas žemiau <%s>" - -#: ../src/ui/theme-parser.c:1427 -#: ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" for buttons" -msgstr "Negalima tuo pačiu metu nurodyti „button_width“/„button_height“ ir „aspect_ratio“" - -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "Atstumas \"%s\" yra nežinomas" - -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "Dydžio santykis \"%s\" yra nežinomas" - -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "Paraštė \"%s\" nežinoma" - -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "Elemente <%s> trūksta \"start_angle\" ar \"from\" požymio" - -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "Elemente <%s> trūksta \"extent_angle\" ar \"to\" požymio" - -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "Nesuprantama reikšmė \"%s\" persiliejančio elemento tipo aprašyme" - -#: ../src/ui/theme-parser.c:2193 -#: ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "Nežinoma fill type požymio reikšmė \"%s\" elemente <%s>" - -#: ../src/ui/theme-parser.c:2360 -#: ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "Nežinoma state požymio reikšmė \"%s\" elemente <%s>" - -#: ../src/ui/theme-parser.c:2370 -#: ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "Nežinoma shadow požymio reikšmė \"%s\" elemente <%s>" - -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "Nežinoma arrow požymio reikšmė \"%s\" elemente <%s>" - -#: ../src/ui/theme-parser.c:2694 -#: ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "Neaprašyti jokie <draw_ops> požymiai pavadinti \"%s\"" - -#: ../src/ui/theme-parser.c:2706 -#: ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "Čia įvesdami draw_ops \"%s\" požymius jūs sukuriate žiedinį aprašymą" - -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Nežinoma rėmelio elemento padėtis \"%s\"" - -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "Rėmelio stiliaus aprašyme padėtis %s jau aprašyta" - -#: ../src/ui/theme-parser.c:2942 -#: ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "Vardui \"%s\" nenurodyti jokie <draw_ops> požymiai" - -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Mygtukui priskirta nežinoma funkcija \"%s\"" - -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "Mygtuko funkcija \"%s\" neegzistuoja šioje versijoje (%d, reikia %d)" - -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Mygtukui priskirta nežinoma būsena \"%s\"" - -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "Rėmelio stiliaus aprašyme jau yra nurodytas mygtukas aprašantis funkcijos %s būseną %s" - -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "Reikšmė „%s“ nepriimtina aktyvinimo požymyje" - -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "Reikšmė „%s“ nepriimtina būsenos požymyje" - -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "Stilius pavadinimu „%s“ neaprašytas" - -#: ../src/ui/theme-parser.c:3113 -#: ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "Reikšmė „%s“ nepriimtina dydžio keitimo požymyje" - -#: ../src/ui/theme-parser.c:3147 -#, c-format -msgid "Should not have \"resize\" attribute on <%s> element for maximized/shaded states" -msgstr "Negalima naudoti \"resize\" požymio elemente <%s>, skirtame išplėtimo/šešėlių būsenų aprašymui" - -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "Negalima naudoti \"resize\" požymio elemente <%s>, skirtame išplėtimo būsenų aprašymui" - -#: ../src/ui/theme-parser.c:3175 -#: ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "state %s resize %s focus %s požymiai jau turi stiliaus aprašymą" - -#: ../src/ui/theme-parser.c:3186 -#: ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 -#: ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 -#: ../src/ui/theme-parser.c:3255 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "Aktyvinimo %2$s būsena %1$s jau turi stiliaus aprašymą" - -#: ../src/ui/theme-parser.c:3294 -msgid "Can't have a two draw_ops for a <piece> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "Negalima naudoti dviejų draw_ops požymių <piece> elemente (tema nustatė draw_ops požymį ir <draw_ops> elementą, arba nurodė du elementus)" - -#: ../src/ui/theme-parser.c:3332 -msgid "Can't have a two draw_ops for a <button> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "Negalima naudoti dviejų draw_ops požymių <button> elemente (tema nustatė draw_ops požymį ir <draw_ops> elementą, arba nurodė du elementus)" - -#: ../src/ui/theme-parser.c:3370 -msgid "Can't have a two draw_ops for a <menu_icon> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "Negalima naudoti dviejų draw_ops požymių <menu_icon> elemente (tema nustatė draw_ops požymį ir <draw_ops> elementą, arba nurodė du elementus)" - -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "Bloga versijos specifikacija „%s“" - -#: ../src/ui/theme-parser.c:3507 -msgid "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-theme-2.xml" -msgstr "„version“ požymis negali būti naudojamas metacity-theme-1.xml arba metacity-theme-2.xml" - -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "Tema reikalauja versijos %s, bet paskutinė palaikoma versija yra %d.%d" - -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "Pradinis temos elementas turi būti <metacity_theme>, o ne <%s>" - -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "Element <%s> is not allowed inside a name/author/date/description element" -msgstr "Elementas <%s> nepriimtinas tarp name/author/date/description elementų" - -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "Elementas <%s> nepriimtinas tarp <constant> elemento" - -#: ../src/ui/theme-parser.c:3599 -#, c-format -msgid "Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "Elementas <%s> nepriimtinas tarp distance/border/aspect_ratio elementų" - -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "Elementas <%s> piešimo operacijos elemente neleidžiamas" - -#: ../src/ui/theme-parser.c:3631 -#: ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 -#: ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "Elementas <%s> elemente <%s> yra neleidžiamas" - -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "Rėmelio elementui nepriskirta draw_ops funkcija" - -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "Mygtukui nepriskirta draw_ops funkcija" - -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "Elemente <%s> tekstas negalimas" - -#: ../src/ui/theme-parser.c:4026 -#: ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 -#: ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "<%s> elementas temos aprašyme nurodytas du kartus" - -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Nepavyko rasti tinkamo temos %s failo\n" - -#: ../src/ui/theme-viewer.c:99 -#| msgid "/_Windows" -msgid "_Windows" -msgstr "_Langai" - -#: ../src/ui/theme-viewer.c:100 -#| msgid "Dialog Box" -msgid "_Dialog" -msgstr "_Dialogas" - -#: ../src/ui/theme-viewer.c:101 -#| msgid "Modal Dialog Box" -msgid "_Modal dialog" -msgstr "_Modalinis dialogas" - -#: ../src/ui/theme-viewer.c:102 -#| msgid "/Windows/_Utility" -msgid "_Utility" -msgstr "_Įrankis" - -#: ../src/ui/theme-viewer.c:103 -#| msgid "/Windows/_Splashscreen" -msgid "_Splashscreen" -msgstr "_Pristatymo langas" - -#: ../src/ui/theme-viewer.c:104 -#| msgid "/Windows/_Top dock" -msgid "_Top dock" -msgstr "_Viršutinis dokas" - -#: ../src/ui/theme-viewer.c:105 -#| msgid "/Windows/_Bottom dock" -msgid "_Bottom dock" -msgstr "_Apatinis dokas" - -#: ../src/ui/theme-viewer.c:106 -#| msgid "/Windows/_Left dock" -msgid "_Left dock" -msgstr "_Kairysis dokas" - -#: ../src/ui/theme-viewer.c:107 -#| msgid "/Windows/_Right dock" -msgid "_Right dock" -msgstr "_Kairysis dokas" - -#: ../src/ui/theme-viewer.c:108 -#| msgid "/Windows/_All docks" -msgid "_All docks" -msgstr "Visi dok_ai" - -#: ../src/ui/theme-viewer.c:109 -#| msgid "Desktop" -msgid "Des_ktop" -msgstr "Dar_bastalis" - -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "Atverti dar vieną tokį langą" - -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "Tai yra bandomasis mygtukas su „atverti“ piktograma" - -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "Tai yra bandomasis mygtukas su „uždaryti“ piktograma" - -#: ../src/ui/theme-viewer.c:253 -msgid "This is a sample message in a sample dialog" -msgstr "Tai yra pavydžio pranešimas pavyzdžio dialoge" - -#: ../src/ui/theme-viewer.c:336 -#, c-format -msgid "Fake menu item %d\n" -msgstr "Netikras meniu punktas %d\n" - -#: ../src/ui/theme-viewer.c:371 -msgid "Border-only window" -msgstr "Tik rėmelį turintis langas" - -#: ../src/ui/theme-viewer.c:373 -msgid "Bar" -msgstr "Juosta" - -#: ../src/ui/theme-viewer.c:390 -msgid "Normal Application Window" -msgstr "Normalus programos langas" - -#: ../src/ui/theme-viewer.c:394 -msgid "Dialog Box" -msgstr "Dialogo langas" - -#: ../src/ui/theme-viewer.c:398 -msgid "Modal Dialog Box" -msgstr "Modalinis dialogo langas" - -#: ../src/ui/theme-viewer.c:402 -msgid "Utility Palette" -msgstr "Įrankių paletė" - -#: ../src/ui/theme-viewer.c:406 -msgid "Torn-off Menu" -msgstr "Atkabinamas meniu" - -#: ../src/ui/theme-viewer.c:410 -msgid "Border" -msgstr "Paraštė" - -#: ../src/ui/theme-viewer.c:414 -#| msgid "Modal Dialog Box" -msgid "Attached Modal Dialog" -msgstr "Prikabintas modalinis dialogas" - -#: ../src/ui/theme-viewer.c:747 -#, c-format -msgid "Button layout test %d" -msgstr "Mygtukų išdėstymo testas %d" - -#: ../src/ui/theme-viewer.c:776 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "vienam lango kadrui išvesti yra skirta %g milisekundžių" - -#: ../src/ui/theme-viewer.c:821 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Panaudojimas: metacity-theme-viewer [TEMOS PAVADINIMAS]\n" - -#: ../src/ui/theme-viewer.c:828 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "Klaida įkeliant temą: %s\n" - -#: ../src/ui/theme-viewer.c:834 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "Tema „%s“ įkelta per %g sekundžių\n" - -#: ../src/ui/theme-viewer.c:878 -msgid "Normal Title Font" -msgstr "Normalus antraštės šriftas" - -#: ../src/ui/theme-viewer.c:884 -msgid "Small Title Font" -msgstr "Smulkus antraštės šriftas" - -#: ../src/ui/theme-viewer.c:890 -msgid "Large Title Font" -msgstr "Didelis antraštės šriftas" - -#: ../src/ui/theme-viewer.c:895 -msgid "Button Layouts" -msgstr "Mygtukų išdėstymai" - -#: ../src/ui/theme-viewer.c:900 -msgid "Benchmark" -msgstr "Greičio testas" - -#: ../src/ui/theme-viewer.c:952 -msgid "Window Title Goes Here" -msgstr "Čia rodomo lango antraštė" - -#: ../src/ui/theme-viewer.c:1055 -#, c-format -msgid "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g seconds wall clock time including X server resources (%g milliseconds per frame)\n" -msgstr "%d kadrai buvo išvesti per %g klientines sekundes (%g milisekunčių kadrui) ir per %g bendrinio laiko sekundes įskaitant X serverio resursus (%g milisekundžių kadrui)\n" - -#: ../src/ui/theme-viewer.c:1274 -msgid "position expression test returned TRUE but set error" -msgstr "padėties išraiškos testas grąžino teigiamą reikšmę, bet kartu nustatė klaidos pranešimą" - -#: ../src/ui/theme-viewer.c:1276 -msgid "position expression test returned FALSE but didn't set error" -msgstr "padėties išraiškos testas grąžino neigiamą reikšmę, bet nenustatė klaidos pranešimo" - -#: ../src/ui/theme-viewer.c:1280 -msgid "Error was expected but none given" -msgstr "Tikėtasi sulaukti klaidos pranešimo, tačiau nieko nesulaukta" - -#: ../src/ui/theme-viewer.c:1282 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "Tikėtasi klaidos %d, tačiau gauta %d" - -#: ../src/ui/theme-viewer.c:1288 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "Klaidos nesitikėta, tačiau grąžinta klaida: %s" - -#: ../src/ui/theme-viewer.c:1292 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "x reikšmė buvo %d, tikėtasi %d" - -#: ../src/ui/theme-viewer.c:1295 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "y reikšmė buvo %d, tikėtasi %d" - -#: ../src/ui/theme-viewer.c:1360 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "Koordinačių %d išraiška apdorota per %g sekundžių (%g sekundžių vidurkis)\n" - -#~ msgid "Failed to get hostname: %s\n" -#~ msgstr "Nepavyko gauti kompiuterio vardo: %s\n" - -#~ msgid "" -#~ "Lost connection to the display '%s';\n" -#~ "most likely the X server was shut down or you killed/destroyed\n" -#~ "the window manager.\n" -#~ msgstr "" -#~ "Prarastas ryšys su ekranu „%s“;\n" -#~ "greičiausiai X serveris buvo išjungtas arba jūs priverstinai\n" -#~ "išjungėte langų valdyklę.\n" - -#~ msgid "Fatal IO error %d (%s) on display '%s'.\n" -#~ msgstr "Kritinė IO klaida %d (%s) ekrane „%s“.\n" - -#~ msgid "Turn compositing on" -#~ msgstr "Įjungti komponavimą" - -#~ msgid "Turn compositing off" -#~ msgstr "Išjungti komponavimą" - -#~ msgid "" -#~ "Don't make fullscreen windows that are maximized and have no decorations" -#~ msgstr "" -#~ "Nepaversti langų per visą ekraną, jei jie išdidinti ir neturi dekoracijų" - -#~ msgid "Whether window popup/frame should be shown when cycling windows." -#~ msgstr "Ar lango iškilimas/rėmelis turi būti rodomas sukant langus ratu." - -#~ msgid "Internal argument for GObject introspection" -#~ msgstr "Vidinis argumentas GObject introspekcijai" - -#~ msgid "Failed to restart: %s\n" -#~ msgstr "Nepavyko perleisti: %s\n" - -#~ msgid "Error setting compositor status: %s\n" -#~ msgstr "Įvyko klaida nustatant komponavimo posistemės būseną: %s\n" - -#~ msgid "Error setting clutter plugin list: %s\n" -#~ msgstr "Įvyko klaida nustatant clutter įskiepių sąrašą: %s\n" - -#~ msgid "Clutter Plugins" -#~ msgstr "Clutter įskiepiai" - -#~ msgid "Plugins to load for the Clutter-based compositing manager." -#~ msgstr "Pakraunami įskiepiai clutter pagrindo komponavimo valdyklei." - -#~ msgid "Theme file %s did not contain a root <metacity_theme> element" -#~ msgstr "Temos faile %s trūksta pagrindinio <metacity_theme> elemento" - -#~ msgid "/Windows/tearoff" -#~ msgstr "/Langai/atkabinimas" - -#~ msgid "/Windows/_Dialog" -#~ msgstr "/Langai/_Dialogas" - -#~ msgid "/Windows/_Modal dialog" -#~ msgstr "/Langai/_Modalinis dialogas" - -#~ msgid "/Windows/Des_ktop" -#~ msgstr "/Langai/_Darbastalis" - -#~ msgid "Window Management" -#~ msgstr "Langų valdymas" - -#~ msgid "Failed to parse message \"%s\" from dialog process\n" -#~ msgstr "Nepavyko apdoroti dialogo proceso pranešimo „%s“\n" - -#~ msgid "Error reading from dialog display process: %s\n" -#~ msgstr "Įvyko klaida skaitant duomenis iš dialogo išvedimo proceso: %s\n" - -#~ msgid "" -#~ "Error launching metacity-dialog to ask about killing an application: %s\n" -#~ msgstr "" -#~ "Įvyko klaida paleidžiant metacity-dialog, klausiantį apie programos " -#~ "veikimo sustabdymą: %s\n" - -#~ msgid "" -#~ "The format looks like \"<Control>a\" or <Shift><Alt>F1\".\n" -#~ "\n" -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Formatas maždaug toks: „<Control>a“ arba „<Shift><Alt>F1“.\n" -#~ "\n" -#~ "Sistema apdorojanti aprašymą yra gana laisva ir leidžia maišyti " -#~ "didžiąsias bei mažąsias raides ir naudoti tokius sutrumpinimus kaip " -#~ "„<Ctl>“ ir „<Ctrl>“. Nustačius specialų požymį „disabled“, su šiuo " -#~ "veiksmu nebus susieta jokia klavišų kombinacija." - -#~ msgid "" -#~ "The format looks like \"<Control>a\" or <Shift><Alt>F1\".\n" -#~ "\n" -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action.\n" -#~ "\n" -#~ "This keybinding may be reversed by holding down the \"shift\" key; " -#~ "therefore, \"shift\" cannot be one of the keys it uses." -#~ msgstr "" -#~ "Formatas maždaug toks: „<Control>a“ arba „<Shift><Alt>F1“.\n" -#~ "\n" -#~ "Sistema, apdorojanti aprašymą, yra gana laisva ir leidžia maišyti " -#~ "didžiąsias bei mažąsias raides ir naudoti tokius sutrumpinimus kaip " -#~ "„<Ctl>“ ir „<Ctrl>“. Nustačius specialų požymį „disabled“, su šiuo " -#~ "veiksmu nebus susieta jokia klavišų kombinacija.\n" -#~ "\n" -#~ "Šis klavišų susiejimas gali būti apsuktas nuspaudus „Shift“ klavišą, " -#~ "taigi jame negalima naudoti „Shift“." - -#~ msgid "Failed to read saved session file %s: %s\n" -#~ msgstr "Nepavyko perskaityti išsaugoto seanso failo %s: %s\n" - -#~ msgid "" -#~ "Error launching metacity-dialog to warn about apps that don't support " -#~ "session management: %s\n" -#~ msgstr "" -#~ "Įvyko klaida paleidžiant langų valdyklės dialogo langą, perspėjantį apie " -#~ "programas, kurios nepalaiko sesijos valdymo: %s\n" - -#~ msgid "Metacity" -#~ msgstr "Metacity" - -#~ msgid "" -#~ "(Not implemented) Navigation works in terms of applications not windows" -#~ msgstr "" -#~ "(Neįgyvendinta) Persijungimas galimas tarp programų, o ne tarp programos " -#~ "langų" - -#~ msgid "" -#~ "A font description string describing a font for window titlebars. The " -#~ "size from the description will only be used if the titlebar_font_size " -#~ "option is set to 0. Also, this option is disabled if the " -#~ "titlebar_uses_desktop_font option is set to true." -#~ msgstr "" -#~ "Šrifto aprašymo seka, nurodanti šriftą, naudojamą langų antraštėms. " -#~ "Šrifto dydis, esantis aprašyme, naudojamas tik tuo atveju, jei " -#~ "titlebar_font_size požymis yra lygus 0. Be to, šis požymis atjungiamas, " -#~ "jei titlebar_uses_desktop_font požymis yra teigiamas true." - -#~ msgid "Action on title bar double-click" -#~ msgstr "Veiksmas du kartus spustelėjus antraštės juostą" - -#~ msgid "Action on title bar middle-click" -#~ msgstr "Veiksmas spustelėjus antraštės juostą viduriniuoju pelės mygtuku" - -#~ msgid "Action on title bar right-click" -#~ msgstr "Veiksmas spustelėjus antraštės juostą dešiniuoju pelės mygtuku" - -#~ msgid "Arrangement of buttons on the titlebar" -#~ msgstr "Mygtukų išdėstymas antraštėje" - -#~ msgid "" -#~ "Arrangement of buttons on the titlebar. The value should be a string, " -#~ "such as \"menu:minimize,maximize,spacer,close\"; the colon separates the " -#~ "left corner of the window from the right corner, and the button names are " -#~ "comma-separated. Duplicate buttons are not allowed. Unknown button names " -#~ "are silently ignored so that buttons can be added in future metacity " -#~ "versions without breaking older versions. A special spacer tag can be " -#~ "used to insert some space between two adjacent buttons." -#~ msgstr "" -#~ "Mygtukų išdėstymas antraštės juostoje. Požymio reikšmė turi būti simbolių " -#~ "seka, pvz., „menu:minimize,maximize,close“; dvitaškis skiria kairįjį " -#~ "lango kampą nuo dešiniojo, o mygtukų vardai atskiriami kableliais. " -#~ "Mygtukų vardai neturi pasikartoti. Nežinomi mygtukai yra ignoruojami, jei " -#~ "juos kada nors panaudotų būsimos metacity laidos. Speciali tarpo žymė " -#~ "palieka šiek tiek vietos tarp gretimų mygtukų." - -#~ msgid "Automatically raises the focused window" -#~ msgstr "Automatiškai iškelia suaktyvintą langą" - -#~ msgid "" -#~ "Clicking a window while holding down this modifier key will move the " -#~ "window (left click), resize the window (middle click), or show the window " -#~ "menu (right click). The left and right operations may be swapped using " -#~ "the \"mouse_button_resize\" key. Modifier is expressed as \"<Alt>\" " -#~ "or \"<Super>\" for example." -#~ msgstr "" -#~ "Spustelėjus ant lango, kai yra paspaustas šis specialusis klavišas, " -#~ "langas bus perkeltas (kairysis spustelėjimas), keičiamas jo dydį " -#~ "(vidurinis spustelėjimas), arba rodomas lango meniu (dešinysis " -#~ "spustelėjimas). Kairiojo ir dešiniojo mygtuko operacijos gali būti " -#~ "sukeistos naudojantis „mouse_button_resize“ nustatymu. Specialus klavišas " -#~ "gali būti nustatytas kaip, pavyzdžiui, \"<Alt>\" arba \"<" -#~ "Super>\"." - -#~ msgid "Commands to run in response to keybindings" -#~ msgstr "" -#~ "Komandos, kurios turi būti paleistos, suveikus nustatytoms klavišų " -#~ "kombinacijoms" - -#~ msgid "Compositing Manager" -#~ msgstr "Kompozicijos valdyklė" - -#~ msgid "Control how new windows get focus" -#~ msgstr "Nustatyti, kada nauji langai suaktyvinami" - -#~ msgid "Current theme" -#~ msgstr "Esama tema" - -#~ msgid "Delay in milliseconds for the auto raise option" -#~ msgstr "" -#~ "Uždelsimas milisekundėmis prieš suveikiant automatinio lango iškėlimui." - -#~ msgid "Determines whether Metacity is a compositing manager." -#~ msgstr "Nurodo ar Metacity yra komponuojanti valdyklė." - -#~ msgid "" -#~ "Determines whether applications or the system can generate audible " -#~ "'beeps'; may be used in conjunction with 'visual bell' to allow silent " -#~ "'beeps'." -#~ msgstr "" -#~ "Nustato, ar programos arba sistema gali generuoti garsinius " -#~ "„pyptelėjimus“; gali būti naudojamas kartu su „vaizdiniu audio signalu“ " -#~ "norint generuoti tylius „pyptelėjimus“." - -#~ msgid "Disable misfeatures that are required by old or broken applications" -#~ msgstr "" -#~ "Atjungti savybes, kurias gali naudoti senos arba sugadintos programos" - -#~ msgid "Enable Visual Bell" -#~ msgstr "Įjungti vaizdinį signalą" +#: data/org.gnome.mutter.gschema.xml.in:21 +msgid "" +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." +msgstr "" +"Kai teigiama, užuot turėje nepriklausomas antraštes, modaliniai dialogai " +"pasirodys prikabinti prie tėvinio lango antraštės ir yra perkialiami kartu " +"su tėviniu langu." -#~ msgid "" -#~ "If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " -#~ "the focused window will be automatically raised after a delay specified " -#~ "by the auto_raise_delay key. This is not related to clicking on a window " -#~ "to raise it, nor to entering a window during drag-and-drop." -#~ msgstr "" -#~ "Jei reikšmė teigiama ir aktyvinimo veiksena yra „sloppy“ arba „mouse“, " -#~ "tada suaktyvintas langas po rakte „auto_raise_delay“ nurodyto laiko tarpo " -#~ "bus automatiškai iškeltas. Tai nesusiję su lango spustelėjimu norint jį " -#~ "pakelti arba užvedimo ant lango objekto vilkimo metu." +#: data/org.gnome.mutter.gschema.xml.in:30 +msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "Įjungti kraštų uždengimą numetant langus ekrano kraštuose" -#~ msgid "" -#~ "If true, ignore the titlebar_font option, and use the standard " -#~ "application font for window titles." -#~ msgstr "" -#~ "Jei reikšmė teigiama, nepaisyti titlebar_font parinkties ir langų " -#~ "antraštėms naudoti standartinį programų šriftą." +#: data/org.gnome.mutter.gschema.xml.in:31 +msgid "" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." +msgstr "" +"Jei įjungta, langų numetimas vertikaliuose kraštuose juos išdidina " +"vertikaliai ir pakeičia dydį horizontaliai taip, kad užimtų pusę esamos " +"vietos. Langų numetimas ekrano viršuje juos visiškai išdidina." -#~ msgid "" -#~ "If true, metacity will give the user less feedback by using wireframes, " -#~ "avoiding animations, or other means. This is a significant reduction in " -#~ "usability for many users, but may allow legacy applications to continue " -#~ "working, and may also be a useful tradeoff for terminal servers. However, " -#~ "the wireframe feature is disabled when accessibility is on." -#~ msgstr "" -#~ "Jei reikšmė teigiama, metacity, naudodama langų rėmelius, vengdama " -#~ "animacijų ar kitų efektų, pateiks naudotojui mažiau reakcijų ir bus " -#~ "mažiau jaučiama „tiesioginė manipuliacija“. Tai smarkiai suprastina " -#~ "sąsajos išraiškingumą, bet leidžia normaliai veikti senesnėms programoms " -#~ "bei terminalų serveriams. Kai įjungtos prieinamumo funkcijos, rėmelių " -#~ "naudojimas išjungiamas." +#: data/org.gnome.mutter.gschema.xml.in:40 +msgid "Workspaces are managed dynamically" +msgstr "Darbo sritys tvarkomos dinamiškai" -#~ msgid "" -#~ "If true, then Metacity works in terms of applications rather than " -#~ "windows. The concept is a bit abstract, but in general an application-" -#~ "based setup is more like the Mac and less like Windows. When you focus a " -#~ "window in application-based mode, all the windows in the application will " -#~ "be raised. Also, in application-based mode, focus clicks are not passed " -#~ "through to windows in other applications. Application-based mode is, " -#~ "however, largely unimplemented at the moment." -#~ msgstr "" -#~ "Esant teigiamai reikšmei, langų valdyklės darbas yra artimesnis darbui su " -#~ "programomis nei su langais. Sąvoka gana neapibrėžta, bet apskritai " -#~ "programų veiksena yra artimesnė Macintosh operacinei sistemai nei " -#~ "Windows. Kai suaktyvinate langą programų veiksenoje, visi programos " -#~ "langai bus iškelti. Be to, programų veiksenoje langų aktyvinimo " -#~ "spustelėjimai neveikia langų, priklausančių kitoms programoms. Kol kas " -#~ "programų veiksenos realizacija dar ankstyvoje stadijoje." - -#~ msgid "If true, trade off usability for less resource usage" -#~ msgstr "" -#~ "Jei reikšmė teigiama, atsisakyti dalies galimybių vardan efektyvesnio " -#~ "resursų panaudojimo" +#: data/org.gnome.mutter.gschema.xml.in:41 +msgid "" +"Determines whether workspaces are managed dynamically or whether there’s a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." +msgstr "" +"Nusako, ar darbo sritys yra tvarkomos dinamiškai, ar yra pastovus darbo " +"sričių skaičius (nusakomas raktu num-workspaces schemoje org.gnome.desktop." +"wm.preferences)." -#~ msgid "Name of workspace" -#~ msgstr "Darbalaukio vardas" +#: data/org.gnome.mutter.gschema.xml.in:50 +msgid "Workspaces only on primary" +msgstr "Darbo sritys tik pagrindiniame" -#~ msgid "Number of workspaces" -#~ msgstr "Darbalaukų kiekis" +#: data/org.gnome.mutter.gschema.xml.in:51 +msgid "" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." +msgstr "" +"Nusako, ar darbo sričių perjungimas turi įvykti langams visuose " +"monitoriuose, ar tik langams pagrindiniame monitoriuje." -#~ msgid "" -#~ "Number of workspaces. Must be more than zero, and has a fixed maximum to " -#~ "prevent making the desktop unusable by accidentally asking for too many " -#~ "workspaces." -#~ msgstr "" -#~ "Darbalaukių kiekis. Turi būti didesnis už nulį. Be to, nustatyta " -#~ "maksimali reikšmė, kad netyčia nesunaikintumėte savo darbo aplinkos įvedę " -#~ "labai didelio skaičių." +#: data/org.gnome.mutter.gschema.xml.in:59 +msgid "No tab popup" +msgstr "Nėra tab iššokimo" -#~ msgid "Run a defined command" -#~ msgstr "Paleisti nurodytą komandą" +#: data/org.gnome.mutter.gschema.xml.in:60 +msgid "" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." +msgstr "" +"Nusako, ar iššokančio lango ir rėmelio paryškinimo naudojimas turėtų būti " +"išjungtas langų perėjime." -#~ msgid "" -#~ "Set this to true to resize with the right button and show a menu with the " -#~ "middle button while holding down the key given in \"mouse_button_modifier" -#~ "\"; set it to false to make it work the opposite way around." -#~ msgstr "" -#~ "Nustatykite į teisingą, jei norite keisti dydį dešiniuoju mygtuku ir " -#~ "rodyti meniu viduriniuoju mygtuku nuspaudus klavišą, nurodytą " -#~ "„mouse_button_modifier“; nustatykite į klaidingą, jei norite, kad veiktų " -#~ "priešingai." +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Atidėti aktyvavimo pakeitimus iki žymiklis nustaja judėti" -#~ msgid "" -#~ "Setting this option to false can lead to buggy behavior, so users are " -#~ "strongly discouraged from changing it from the default of true. Many " -#~ "actions (e.g. clicking in the client area, moving or resizing the window) " -#~ "normally raise the window as a side-effect. Setting this option to false, " -#~ "which is strongly discouraged, will decouple raising from other user " -#~ "actions, and ignore raise requests generated by applications. See http://" -#~ "bugzilla.gnome.org/show_bug.cgi?id=445447#c6. Even when this option is " -#~ "false, windows can still be raised by an alt-left-click anywhere on the " -#~ "window, a normal click on the window decorations, or by special messages " -#~ "from pagers, such as activation requests from tasklist applets. This " -#~ "option is currently disabled in click-to-focus mode. Note that the list " -#~ "of ways to raise windows when raise_on_click is false does not include " -#~ "programmatic requests from applications to raise windows; such requests " -#~ "will be ignored regardless of the reason for the request. If you are an " -#~ "application developer and have a user complaining that your application " -#~ "does not work with this setting disabled, tell them it is _their_ fault " -#~ "for breaking their window manager and that they need to change this " -#~ "option back to true or live with the \"bug\" they requested." -#~ msgstr "" -#~ "Nustačius šią parinktį į neigiamą reikšmę, programa gali veikti " -#~ "nekorektiškai, todėl labai rekomenduojama nekeisti jos numatytosios " -#~ "teigiamos reikšmės. Daugelio veiksmų (pvz., spustelėjimo kliento srityje, " -#~ "lango perkėlimo arba dydžio keitimo) pašalinis efektas paprastai bus " -#~ "lango iškėlimas. Nustatykite šią parinktį į neigiamą, kad atskirtumėte " -#~ "iškėlimą nuo kitų naudotojo veiksmų. Žr. http://bugzilla.gnome.org/" -#~ "show_bug.cgi?id=445447#c6. Netgi jeigu ši parinktis neigiama, langus vis " -#~ "tiek galima iškelti laikant Alt ir spustelėjus kairiuoju mygtuku bet " -#~ "kurią lango vietą, paprastai spustelėjus lango dekoracijas, arba " -#~ "specialiais pranešimais, pvz., aktyvavimo užklausomis iš užduočių sąrašo " -#~ "įtaisų. Šiuo metu ši parinktis yra išjungta aktyvinimo spustelint " -#~ "veiksenoje. Atminkite, kad tarp langų iškėlimo būdų, kai raise_on_click " -#~ "reikšmė yra neigiama, nėra programinių užklausų iškelti langą iš " -#~ "programų; tokių užklausų bus nepaisoma, nepaisant jų priežasties. Jeigu " -#~ "esate programos kūrėjas ir jūsų naudotojai skundžiasi, kad jūsų programa " -#~ "neveikia, kai šis parametras išjungtas, pasakykite jiems, kad tai _jų_ " -#~ "kaltė, kad sugadino savo langų valdyklę ir, kad jie turi atkurti šią " -#~ "parinktį atgal į teigiamą arba ir toliau gyventi su klaida, dėl kurios " -#~ "skundžiasi." +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" +"Jei nustatytas teigiamai ir aktyvavimo veiksena yra „sloppy“ arba „mouse“, " +"tuomet aktyvavimas nebus pakeistas nedelsiant įėjus į langą, bet tik pelės " +"žymikliui nustojus judėti." -#~ msgid "" -#~ "Some applications disregard specifications in ways that result in window " -#~ "manager misfeatures. This option puts Metacity in a rigorously correct " -#~ "mode, which gives a more consistent user interface, provided one does not " -#~ "need to run any misbehaving applications." -#~ msgstr "" -#~ "Kai kurios programos nevykdo nurodymų specifikacijose, todėl kyla smulkių " -#~ "nesklandumų. Ši parinktis įjungia griežtą veikseną, kuri padaro aplinką " -#~ "vienalytiškesnę, jei nenaudojate nekorektiškų programų." +#: data/org.gnome.mutter.gschema.xml.in:79 +msgid "Draggable border width" +msgstr "Tempiamos paraštės prolis" -#~ msgid "System Bell is Audible" -#~ msgstr "Sisteminis signalas yra garsinis" +#: data/org.gnome.mutter.gschema.xml.in:80 +msgid "" +"The amount of total draggable borders. If the theme’s visible borders are " +"not enough, invisible borders will be added to meet this value." +msgstr "" +"Bendros tempiamos paraštės dydis. Jei temos matomos paraštės yra " +"nepakankamos, bus pridėtos nematomos paraštės." -#~ msgid "" -#~ "Tells Metacity how to implement the visual indication that the system " -#~ "bell or another application 'bell' indicator has been rung. Currently " -#~ "there are two valid values, \"fullscreen\", which causes a fullscreen " -#~ "white-black flash, and \"frame_flash\" which causes the titlebar of the " -#~ "application which sent the bell signal to flash. If the application which " -#~ "sent the bell is unknown (as is usually the case for the default \"system " -#~ "beep\"), the currently focused window's titlebar is flashed." -#~ msgstr "" -#~ "Nustato kaip langų valdyklė vykdo vaizdinį signalą suveikus sisteminiam " -#~ "pyptelėjimui arba kokios nors programos pyptelėjimo signalui. Šiuo metu " -#~ "galimos dvi reikšmės - „fullscreen“, kuris sukuria viso ekrano vaizdo " -#~ "juodai baltą blykstelėjimą, bei „frame_flash“, kuris sukuria programos, " -#~ "pasiuntusios signalą, antraštės mirgėjimą. Jei programa pasiuntusi " -#~ "signalą yra nežinoma (paprastai tai būna kai suveikia standartinis " -#~ "sisteminis pyptelėjimas), mirga tuo momentu naudojamo lango antraštė." +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "Automatiškai išdidinti beveik monitoriaus dydžio langus" -#~ msgid "" -#~ "The /apps/metacity/global_keybindings/run_command_N keys define " -#~ "keybindings that correspond to these commands. Pressing the keybinding " -#~ "for run_command_N will execute command_N." -#~ msgstr "" -#~ "/apps/metacity/global_keybindings/run_command_N raktai nustato specialias " -#~ "klavišų kombinacijas, kurios atitinka nurodytas komanda. Paspaudus " -#~ "klavišo kombinaciją priskirtą run_command_N bus įvykdyta komanda " -#~ "command_N." +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" +"Jei įjungta, nauji langai, kurių pradinis dydis yra monitoriaus dydžio yra " +"automatiškai išdidinami." -#~ msgid "" -#~ "The /apps/metacity/global_keybindings/run_command_screenshot key defines " -#~ "a keybinding which causes the command specified by this setting to be " -#~ "invoked." -#~ msgstr "" -#~ "/apps/metacity/global_keybindings/run_command_screenshot raktas nustato " -#~ "klavišų kombinaciją, kuri iškviečia šiame nustatyme nurodytą komandą." +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Patalpinti naujus langus centre" -#~ msgid "" -#~ "The /apps/metacity/global_keybindings/run_command_window_screenshot key " -#~ "defines a keybinding which causes the command specified by this setting " -#~ "to be invoked." -#~ msgstr "" -#~ "/apps/metacity/global_keybindings/run_command_window_screenshot raktas " -#~ "nustato klavišų kombinaciją, kuri iškviečia šiame nustatyme nurodytą " -#~ "komandą." +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" +"Kai teigiama, nauji langai bus visada patalpinti aktyvaus monitoriaus ekrano " +"viduryje." -#~ msgid "" -#~ "The keybinding that runs the correspondingly-numbered command in /apps/" -#~ "metacity/keybinding_commands The format looks like \"<Control>a\" " -#~ "or \"<Shift><Alt>F1\". The parser is fairly liberal and " -#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" -#~ "\" and \"<Ctrl>\". If you set the option to the special string " -#~ "\"disabled\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri paleidžia atitinkamą sunumeruotą komandą iš /" -#~ "apps/metacity/keybinding_commands raktų. Klavišų kombinacijos formatas " -#~ "gali būti panašus į \"<Control>a\" arba \"<Shift><Alt>" -#~ "F1. Sistema apdorojanti aprašymą yra gana laisva ir leidžia maišyti " -#~ "didžiąsias bei mažąsias raides ir naudoti tokius sutrumpinimus kaip \"<" -#~ "Ctl>\" ir \"<Ctrl>\". Nustačius specialų požymį \"disabled\", su " -#~ "šiuo veiksmu nebus susieta jokia klavišų kombinacija." +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Įjungti eksperimentines savybes" -#~ msgid "The name of a workspace." -#~ msgstr "Darbalaukio vardas" +#: data/org.gnome.mutter.gschema.xml.in:108 +msgid "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes " +"mutter request a low priority real-time scheduling. The executable or user " +"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — " +"initializes Xwayland lazily if there are X11 clients. Requires restart." +msgstr "" +"Norėdami įjungti eksperimentines savybes, pridėkite į sąrašą raktinį žodį. " +"Ar savybė reikalauja kompozitoriaus paleidimo iš naujo priklauso nuo " +"konkrečios savybės. Nei viena eksperimentinė savybė neprivalo būti prieinama " +"ar konfigūruojama. Nesitikėkite, kad ką nors pridėjus į šį sąrašą, tai " +"išliks ir ateityje. Šiuo metu galimi raktažodžiai: • „scale-monitor-" +"framebuffer“ — mutter numatytai išdėsto loginius monitorius loginėje " +"pikselių koordinačių erdvėje, tuo pat ištempiant monitorių kadrų buferius " +"vietoje langų turinio, tokiu būdu valdant didelio tankio monitorius. " +"Nereikalauja paleisti iš naujo. • “rt-scheduler” — priverčia mutter prašyti " +"žemo prioriteto realaus laiko planavimo. Programa arba naudotojas turi " +"turėti CAP_SYS_NICE. Reikalauja paleisti iš naujo. • “autostart-xwayland” — " +"paleidžia Xwayland prireikus, kai yra X11 klientų. Reikalauja paleisti iš " +"naujo." + +#: data/org.gnome.mutter.gschema.xml.in:134 +msgid "Modifier to use to locate the pointer" +msgstr "Pakaitos klavišas, naudojamas žymękliui surasti" + +#: data/org.gnome.mutter.gschema.xml.in:135 +msgid "This key will initiate the “locate pointer” action." +msgstr "Šis klavišas paleisti veiksmą „surasti žymeklį“." + +#: data/org.gnome.mutter.gschema.xml.in:142 +msgid "Timeout for check-alive ping" +msgstr "check-alive ping laiko limitas" + +#: data/org.gnome.mutter.gschema.xml.in:143 +msgid "" +"Number of milliseconds a client has to respond to a ping request in order to " +"not be detected as frozen. Using 0 will disable the alive check completely." +msgstr "" +"Per kiek milisekundžių klientas turi atsakyti į ping užklausą, kad nebūtų " +"aptiktas kaip pakibęs. 0 išjungtas šį tikrinimą." -#~ msgid "The screenshot command" -#~ msgstr "Ekrano fotografavimo komanda" +#: data/org.gnome.mutter.gschema.xml.in:165 +msgid "Select window from tab popup" +msgstr "Pasirinkti langą iš tab iššokimo" -#~ msgid "" -#~ "The theme determines the appearance of window borders, titlebar, and so " -#~ "forth." -#~ msgstr "Tema nurodo langų rėmelių, antraščių ir kitų elementų išvaizdą." +#: data/org.gnome.mutter.gschema.xml.in:170 +msgid "Cancel tab popup" +msgstr "Atšaukti tab iššokimą" -#~ msgid "" -#~ "The time delay before raising a window if auto_raise is set to true. The " -#~ "delay is given in thousandths of a second." -#~ msgstr "" -#~ "Uždelsimo laikas prieš pakeliant langą, jei auto_raise požymis yra " -#~ "teigiamas. Laikas nurodomas tūkstantosiomis sekundės dalimis." +#: data/org.gnome.mutter.gschema.xml.in:175 +msgid "Switch monitor configurations" +msgstr "Perjungti monitorių konfigūracijas" -#~ msgid "" -#~ "The window focus mode indicates how windows are activated. It has three " -#~ "possible values; \"click\" means windows must be clicked in order to " -#~ "focus them, \"sloppy\" means windows are focused when the mouse enters " -#~ "the window, and \"mouse\" means windows are focused when the mouse enters " -#~ "the window and unfocused when the mouse leaves the window." -#~ msgstr "" -#~ "Lango aktyvinimo veiksena nustato kaip bus aktyvuojami langai. Yra trys " -#~ "galimos reikšmės; \"click\" reiškia, kad reikia spustelėti ant lango " -#~ "norint jį aktyvuoti, \"sloppy\" aktyvuoja langus kai ant jų užvedamas " -#~ "pelės kursorius, o \"mouse\" reiškia, kad langai bus aktyvuojami kai ant " -#~ "jų bus užvestas kursorius ir aktyvacija bus atšaukta kursoriui " -#~ "pasitraukus." +#: data/org.gnome.mutter.gschema.xml.in:180 +msgid "Rotates the built-in monitor configuration" +msgstr "Suka integruotas monitorių konfigūracijas" -#~ msgid "The window screenshot command" -#~ msgstr "Langų fotografavimo komanda" +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Persijungti į VT 1" -#~ msgid "" -#~ "This option determines the effects of double-clicking on the title bar. " -#~ "Current valid options are 'toggle_shade', which will shade/unshade the " -#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " -#~ "will maximize/unmaximize the window in that direction only, 'minimize' " -#~ "which will minimize the window, 'shade' which will roll the window up, " -#~ "'menu' which will display the window menu, 'lower' which will put the " -#~ "window behind all the others, and 'none' which will not do anything." -#~ msgstr "" -#~ "Ši parinktis nurodo dvigubo antraštės spustelėjimo veiksmą. Galimos " -#~ "reikšmės: „toggle_shade“ – suvynioti / išvynioti langą, „toggle_maximize“ " -#~ "– išdidinti / sumažinti langą, „toggle_maximize_horizontally“ ir " -#~ "„toggle_maximize_vertically“ – išdidinti langą nurodyta " -#~ "kryptimi, „minimize“ – paslėpti langą, „shade“ – suvynioti langą, „menu“ " -#~ "– parodyti lango meniu, „lower“ – nukelti langą už kitų langų ir „none“ – " -#~ "nedaryti nieko." +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Persijungti į VT 2" -#~ msgid "" -#~ "This option determines the effects of middle-clicking on the title bar. " -#~ "Current valid options are 'toggle_shade', which will shade/unshade the " -#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " -#~ "will maximize/unmaximize the window in that direction only, 'minimize' " -#~ "which will minimize the window, 'shade' which will roll the window up, " -#~ "'menu' which will display the window menu, 'lower' which will put the " -#~ "window behind all the others, and 'none' which will not do anything." -#~ msgstr "" -#~ "Ši parinktis nurodo antraštės spustelėjimo viduriniuoju mygtuku veiksmą. " -#~ "Galimos reikšmės: „toggle_shade“ – suvynioti / išvynioti langą, " -#~ "„toggle_maximize“ – išdidinti / sumažinti langą, " -#~ "„toggle_maximize_horizontally“ ir „toggle_maximize_vertically“ – " -#~ "išdidinti langą nurodyta kryptimi, „minimize“ – paslėpti langą, „shade“ – " -#~ "suvynioti langą, „menu“ – parodyti lango meniu, „lower“ – nukelti langą " -#~ "už kitų langų ir „none“ – nedaryti nieko." +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Persijungti į VT 3" -#~ msgid "" -#~ "This option determines the effects of right-clicking on the title bar. " -#~ "Current valid options are 'toggle_shade', which will shade/unshade the " -#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " -#~ "will maximize/unmaximize the window in that direction only, 'minimize' " -#~ "which will minimize the window, 'shade' which will roll the window up, " -#~ "'menu' which will display the window menu, 'lower' which will put the " -#~ "window behind all the others, and 'none' which will not do anything." -#~ msgstr "" -#~ "Ši parinktis nurodo antraštės spustelėjimo dešiniuoju mygtuku veiksmą. " -#~ "Galimos reikšmės: „toggle_shade“ – suvynioti / išvynioti langą, " -#~ "„toggle_maximize“ – išdidinti / sumažinti langą, " -#~ "„toggle_maximize_horizontally“ ir „toggle_maximize_vertically“ – " -#~ "išdidinti langą nurodyta kryptimi, „minimize“ – paslėpti langą, „shade“ – " -#~ "suvynioti langą, „menu“ – parodyti lango meniu, „lower“ – nukelti langą " -#~ "už kitų langų ir „none“ – nedaryti nieko." +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Persijungti į VT 4" -#~ msgid "" -#~ "This option provides additional control over how newly created windows " -#~ "get focus. It has two possible values; \"smart\" applies the user's " -#~ "normal focus mode, and \"strict\" results in windows started from a " -#~ "terminal not being given focus." -#~ msgstr "" -#~ "Ši parinktis leidžia tiksliau valdyti naujų langų aktyvinimą. Leidžiamos " -#~ "dvi reikšmės: „smart“ įjungia normalią veikseną, o „strict“ neaktyvina " -#~ "langų, paleistų iš terminalo." +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Persijungti į VT 5" -#~ msgid "" -#~ "Turns on a visual indication when an application or the system issues a " -#~ "'bell' or 'beep'; useful for the hard-of-hearing and for use in noisy " -#~ "environments." -#~ msgstr "" -#~ "Įjungia vaizdinius indikatorius, kai programa arba sistema perduoda " -#~ "standartinius garsinius perspėjimo signalus; naudinga esant klausos " -#~ "sutrikimams, triukšmingoje aplinkoje arba kai garsinis signalas yra " -#~ "išjungtas." +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Persijungti į VT 6" -#~ msgid "Use standard system font in window titles" -#~ msgstr "Langų antraštėse naudoti standartinį sistemos šriftą" +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Persijungti į VT 7" -#~ msgid "Visual Bell Type" -#~ msgstr "Vaizdinio signalo tipas" +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Persijungti į VT 8" -#~ msgid "Whether raising should be a side-effect of other user interactions" -#~ msgstr "Ar pakėlimas turėtų būti pašalinis kitų naudotojo veiksmų efektas" +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Persijungti į VT 9" -#~ msgid "Whether to resize with the right button" -#~ msgstr "Ar keisti dydį dešiniuoju mygtuku" +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Persijungti į VT 10" -#~ msgid "Window focus mode" -#~ msgstr "Langų aktyvinimo veiksena" +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Persijungti į VT 11" -#~ msgid "Window title font" -#~ msgstr "Lango antraštės šriftas" +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Persijungti į VT 12" -#~ msgid "Title" -#~ msgstr "Antraštė" +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "Iš naujo įjungti trumpinius" -#~ msgid "Class" -#~ msgstr "Klasė" +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow X11 grabs to lock keyboard focus with Xwayland" +msgstr "Leisti X11 pagriebimams užrakinti klaviatūros fokusą su XWayland" -#~ msgid "" -#~ "There was an error running \"%s\":\n" -#~ "%s." -#~ msgstr "" -#~ "Įvyko klaida bandant paleisti „%s“:\n" -#~ "%s." +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 +msgid "" +"Allow all keyboard events to be routed to X11 “override redirect” windows " +"with a grab when running in Xwayland. This option is to support X11 clients " +"which map an “override redirect” window (which do not receive keyboard " +"focus) and issue a keyboard grab to force all keyboard events to that " +"window. This option is seldom used and has no effect on regular X11 windows " +"which can receive keyboard focus under normal circumstances. For a X11 grab " +"to be taken into account under Wayland, the client must also either send a " +"specific X11 ClientMessage to the root window or be among the applications " +"white-listed in key “xwayland-grab-access-rules”." +msgstr "" +"Leisti visus klaviatūros įvykius nukreipti į X11 „override redirect“ langus " +"su pagriebimu naudojant Xwayland. Šis parametras yra skirtas X11 klientams, " +"kurie rodo „override redirect“ langą (kuris negauna klaviatūros fokuso) ir " +"įvykdo klaviatūros pagriebimą, kad visi klaviatūros įvykiai priverstinai " +"keliautų į tą langą. Šis parametras yra retai naudojamas ir neturi poveikio " +"X11 langams, kurie gali įprastai gayti klaviatūros fokusą. Kad X11 " +"pagriebimas būtų įvertintas Wayland aplinkoje, klientas taip pat turi arba " +"atsiųsti specialią ClientMessage į šakninį langą, arba būti tarp programų, " +"kurioms tai yra leidžiama rakte „xwayland-grab-access-rules“." + +#: data/org.gnome.mutter.wayland.gschema.xml.in:84 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "Xwayland programos, kurioms leidžiama išduoti klaviatūros pagriebimus" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:85 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "" +"Išvardyti X11 langų, kuriems naudojant Wayland leidžiama ar neleidžiama " +"išduoti X11 klaviatūros pagriebimus, išteklių pavadinimus ar išteklių " +"klases. Nurodyto lango ištekliaus pavadinimas ar ištekliaus klasė gali būti " +"gauta naudojant komandą „xprop WM_CLASS“. Reikšmėse yra palaikomi pakaitos " +"simboliai „*“ ir „?“. Reikšmės prasidedančios „!“ yra įtraukiamos į juodąjį " +"sąrašą (tam, kad būtų panaikintos iš numatytojo sistemos sąrašo) ir turi " +"pirmumo teisę baltojo sąrašo atžvilgiu. Į numatytąjį sistemos sąrašą įeina " +"šios programos: „@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@“. Naudotojai gali " +"panaikinti esamą pagriebimą, naudodami tam tikrą klaviatūros trumpinį, kuris " +"apibrėžtas rakto susiejimo raktu „restore-shortcuts“." + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. +#. +#: src/backends/meta-input-settings.c:2567 +#, c-format +msgid "Mode Switch (Group %d)" +msgstr "Veiksenos perjungimas (Grupė %d)" -#~ msgid "<author> specified twice for this theme" -#~ msgstr "<author> elementas temos aprašyme nurodytas du kartus" +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2590 +msgid "Switch monitor" +msgstr "Perjungti monitorių" -#~ msgid "<copyright> specified twice for this theme" -#~ msgstr "<copyright> elementas temos aprašyme nurodytas du kartus" +#: src/backends/meta-input-settings.c:2592 +msgid "Show on-screen help" +msgstr "Rodyti pagalbą ekrane" -#~ msgid "<date> specified twice for this theme" -#~ msgstr "<date> elementas temos aprašyme nurodytas du kartus" +#: src/backends/meta-monitor.c:223 +msgid "Built-in display" +msgstr "Integruotas vaizduoklis" -#~ msgid "<description> specified twice for this theme" -#~ msgstr "<description> elementas temos aprašyme nurodytas du kartus" +#: src/backends/meta-monitor.c:252 +msgid "Unknown" +msgstr "Nežinomas" -#~ msgid "" -#~ "Error launching metacity-dialog to print an error about a command: %s\n" -#~ msgstr "" -#~ "Įvyko klaida paleidžiant metacity-dialog, išvedantį informaciją apie " -#~ "komandos klaidą: %s\n" +#: src/backends/meta-monitor.c:254 +msgid "Unknown Display" +msgstr "Nežinomas vaizduoklis" -#~ msgid "Unknown attribute %s on <metacity_session> element" -#~ msgstr "Nežinomas požymis %s <metacity_session> elemente" +#: src/backends/meta-monitor.c:262 +#, c-format +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" -#~ msgid "Unknown attribute %s on <maximized> element" -#~ msgstr "Nežinomas požymis %s <maximized> elemente" +#: src/backends/meta-monitor.c:270 +#, c-format +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" -#~ msgid "Unknown attribute %s on <geometry> element" -#~ msgstr "Nežinomas požymis %s <geometry> elemente" +#. Translators: this string will appear in Sysprof +#: src/backends/meta-profiler.c:79 +msgid "Compositor" +msgstr "Komponuotojas" -#~ msgid "The keybinding used to activate the window menu." -#~ msgstr "Klavišų susiejimas lango meniu aktyvuoti" +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:533 +#, c-format +msgid "" +"Another compositing manager is already running on screen %i on display “%s”." +msgstr "Kita kompozicijos tvarkytuvė jau veikia ekrane %i vaizduoklyje „%s“." -#, fuzzy -#~ msgid "The keybinding used to toggle fullscreen mode." -#~ msgstr "Perjungti viso ekrano veikseną" +#: src/core/bell.c:192 +msgid "Bell event" +msgstr "Skambučio įvykis" -#~ msgid "The keybinding used to toggle maximization." -#~ msgstr "Klavišų susiejimas lango išdidinimo veiksenai keisti" +#: src/core/main.c:190 +msgid "Disable connection to session manager" +msgstr "Išjungti susijungimą su sesijos tvarkytuve" -#~ msgid "Toggle always on top state" -#~ msgstr "Perjungti visada viršuje būseną" +#: src/core/main.c:196 +msgid "Replace the running window manager" +msgstr "Pakeisti veikiančią langų tvarkytuvę" -#~ msgid "" -#~ "The keybinding used to toggle always on top. A window that is always on " -#~ "top will always be visible over other overlapping windows." -#~ msgstr "" -#~ "Klavišų susiejimas, keičiantis „visada viršuje“ būseną. Langas, esantis " -#~ "visada viršuje bus matomas virš kitų jį dengiančių langų." +#: src/core/main.c:202 +msgid "Specify session management ID" +msgstr "Nurodyti sesijos tvarkymo ID" -#~ msgid "The keybinding used to maximize a window." -#~ msgstr "Klavišų susiejimas langui išdidinti." +#: src/core/main.c:207 +msgid "X Display to use" +msgstr "Naudotinas X ekranas" -#~ msgid "Unmaximize window" -#~ msgstr "Atšaukti lango išdidinimą" +#: src/core/main.c:213 +msgid "Initialize session from savefile" +msgstr "Inicializuoti sesiją iš išsaugojimo failo" -#~ msgid "The keybinding used to unmaximize a window." -#~ msgstr "Klavišų susiejimas lango išdidinimui atšaukti" +#: src/core/main.c:219 +msgid "Make X calls synchronous" +msgstr "Sinchronizuoti X iškvietimus" -#~ msgid "The keybinding used to toggle shaded/unshaded state." -#~ msgstr "Klavišų susiejimas lango sutraukimo būsenai keisti" +#: src/core/main.c:226 +msgid "Run as a wayland compositor" +msgstr "Vykdyti kaip wayland kompozitorių" -#~ msgid "The keybinding used to minimize a window." -#~ msgstr "Klavišų susiejimas langui sumažinti" +#: src/core/main.c:232 +msgid "Run as a nested compositor" +msgstr "Vykdyti kaip įdėtinį kompozitorių" -#~ msgid "The keybinding used to close a window." -#~ msgstr "Klavišų susiejimas langui užverti" +#: src/core/main.c:238 +msgid "Run wayland compositor without starting Xwayland" +msgstr "Paleisti wayland kompozitorių nepaleidžiant Xwayland" -#~ msgid "" -#~ "The keybinding used to enter \"move mode\" and begin moving a window " -#~ "using the keyboard." -#~ msgstr "" -#~ "Klavišų susiejimas įėjimui į „perkėlimo veikseną“ ir pradėjimui stumdyti " -#~ "langą naudojantis klaviatūra." +#: src/core/main.c:246 +msgid "Run as a full display server, rather than nested" +msgstr "Vykdyti kaip visą vaizduoklio serverį, o ne įdėtinį" -#~ msgid "Toggle window on all workspaces" -#~ msgstr "Perjungti lango buvimo visuose darbalaukiuose būseną" +#: src/core/main.c:252 +msgid "Run with X11 backend" +msgstr "Paleisti su X11 realizacija" -#, fuzzy -#~ msgid "The keybinding used to move a window to workspace 1." -#~ msgstr "Perkelti langą į darbalaukį Nr.1" +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:151 +#, c-format +msgid "“%s” is not responding." +msgstr "%s neatsiliepia į komandas." -#, fuzzy -#~ msgid "The keybinding used to move a window to workspace 2." -#~ msgstr "Perkelti langą į darbalaukį Nr.2" +#: src/core/meta-close-dialog-default.c:153 +msgid "Application is not responding." +msgstr "Programa neatsiliepia į komandas." -#, fuzzy -#~ msgid "The keybinding used to move a window to workspace 3." -#~ msgstr "Perkelti langą į darbalaukį Nr.3" +#: src/core/meta-close-dialog-default.c:158 +msgid "" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." +msgstr "Galite šiek tiek palaukti arba priverstinai uždaryti programą." -#, fuzzy -#~ msgid "The keybinding used to move a window to workspace 4." -#~ msgstr "Perkelti langą į darbalaukį Nr.4" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Force Quit" +msgstr "_Priverstinai išeiti" -#, fuzzy -#~ msgid "The keybinding used to move a window to workspace 5." -#~ msgstr "Perkelti langą į darbalaukį Nr.5" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Wait" +msgstr "_Laukti" -#, fuzzy -#~ msgid "The keybinding used to move a window to workspace 6." -#~ msgstr "Perkelti langą į darbalaukį Nr.6" +#: src/core/mutter.c:38 +#, c-format +msgid "" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" +msgstr "" +"mutter %s\n" +"Autorių teisės © 2001-%d Havoc Pennington, Red Hat, Inc., ir kiti\n" +"Tai yra laisva programinė įranga; kopijavimo sąlygos yra aprašytos " +"pirminiuose koduose.\n" +"Nėra JOKIOS garantijos; netgi PARDAVIMO ar TINKAMUMO TAM TIKRAM TIKSLUI " +"garantijos.\n" + +#: src/core/mutter.c:52 +msgid "Print version" +msgstr "Parodyti versiją" -#, fuzzy -#~ msgid "The keybinding used to move a window to workspace 7." -#~ msgstr "Perkelti langą į darbalaukį Nr.7" +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "Naudojamas Mutter įskiepis" -#, fuzzy -#~ msgid "The keybinding used to move a window to workspace 8." -#~ msgstr "Perkelti langą į darbalaukį Nr.8" +#: src/core/prefs.c:1911 +#, c-format +msgid "Workspace %d" +msgstr "Darbo sritis %d" -#, fuzzy -#~ msgid "The keybinding used to move a window to workspace 9." -#~ msgstr "Perkelti langą į darbalaukį Nr.9" +#: src/core/util.c:122 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter buvo sukompiliuota be išsamaus veikimo veiksenos\n" -#, fuzzy -#~ msgid "The keybinding used to move a window to workspace 10." -#~ msgstr "Perkelti langą į darbalaukį Nr.10" +#: src/wayland/meta-wayland-tablet-pad.c:568 +#, c-format +msgid "Mode Switch: Mode %d" +msgstr "Veiksenos perjungimas: veiksena %d" -#, fuzzy -#~ msgid "The keybinding used to move a window to workspace 11." -#~ msgstr "Perkelti langą į darbalaukį Nr.11" +#: src/x11/meta-x11-display.c:676 +#, c-format +msgid "" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." +msgstr "" +"Vaizduoklis „%s“ jau turi langų tvarkytuvę; pabandykite pakeisti esamą langų " +"tvarkytuvę, naudodami parametrą --replace." -#, fuzzy -#~ msgid "The keybinding used to move a window to workspace 12." -#~ msgstr "Perkelti langą į darbalaukį Nr.12" +#: src/x11/meta-x11-display.c:1089 +msgid "Failed to initialize GDK\n" +msgstr "Nepavyko inicializuoti GDK\n" -#, fuzzy -#~ msgid "The keybinding used to move a window one workspace to the left." -#~ msgstr "Perkelti langą į kairiau esantį darbalaukį" +#: src/x11/meta-x11-display.c:1113 +#, c-format +msgid "Failed to open X Window System display “%s”\n" +msgstr "Nepavyko atverti X Window sistemos vaizduoklio „%s“\n" -#, fuzzy -#~ msgid "The keybinding used to move a window one workspace to the right." -#~ msgstr "Perkelti langą į dešiniau esantį darbalaukį" +#: src/x11/meta-x11-display.c:1196 +#, c-format +msgid "Screen %d on display “%s” is invalid\n" +msgstr "Ekranas %d vaizduoklyje „%s“ yra netinkamas\n" -#, fuzzy -#~ msgid "The keybinding used to move a window one workspace up." -#~ msgstr "Perkelti langą į aukščiau esantį darbalaukį" +#: src/x11/meta-x11-selection-input-stream.c:460 +#, c-format +msgid "Format %s not supported" +msgstr "Formatas %s nepalaikomas" -#, fuzzy -#~ msgid "The keybinding used to move a window one workspace down." -#~ msgstr "Perkelti langą į žemiau esantį darbalaukį" +#: src/x11/session.c:1821 +msgid "" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." +msgstr "" +"Šie langai nepalaiko „išsaugoti esamus nustatymus“ komandos ir, kai kitą " +"kartą prisijungsite, turės būti paleisti rankiniu būdu." -#, fuzzy -#~ msgid "This keybinding raises the window above other windows." -#~ msgstr "Iškelti langą virš kitų langų" +#: src/x11/window-props.c:569 +#, c-format +msgid "%s (on %s)" +msgstr "%s (kompiuteryje %s)" -#, fuzzy -#~ msgid "This keybinding lowers a window below other windows." -#~ msgstr "Nuleisti langą žemiau kitų langų" +#~ msgid "Move window one workspace to the left" +#~ msgstr "Perkelti langą į kairiau esančią darbo sritį" -#, fuzzy -#~ msgid "" -#~ "This keybinding moves a window against the north (top) side of the screen." -#~ msgstr "Perkelti langą į viršutinę ekrano dalį" +#~ msgid "Move window one workspace to the right" +#~ msgstr "Perkelti langą į dešiniau esančią darbo sritį" -#, fuzzy -#~ msgid "This keybinding moves a window into the center of the screen." -#~ msgstr "Perkelti langą į kairę ekrano pusę" +#~ msgid "Move to workspace left" +#~ msgstr "Perkelti į darbo sritį kairėje" -#~ msgid "" -#~ "Many actions (e.g. clicking in the client area, moving or resizing the " -#~ "window) normally raise the window as a side-effect. Setting this option " -#~ "to false, which is strongly discouraged, will decouple raising from other " -#~ "user actions, and ignore raise requests generated by applications. See " -#~ "http://bugzilla.gnome.org/show_bug.cgi?id=445447#c6." -#~ msgstr "" -#~ "Daug veiksmų (pvz., spustelėjimas kliento srityje, lango stūmimas ar " -#~ "dydžio keitimas) paprastai langą pakelia į viršų. Jei ši parinktis " -#~ "išjungta (nerekomenduojama), pakėlimas bus atsietas nuo kitų veiksmų ir " -#~ "programų užklausos pakelti langą bus ignoruojamos. Žr. http://bugzilla." -#~ "gnome.org/show_bug.cgi?id=445447#c6." +#~ msgid "Move to workspace right" +#~ msgstr "Perkelti į darbo sritį dešinėje" -#~ msgid "" -#~ "The keybinding that switches to the workspace above the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri perjungia darbalaukį į aukščiau esantį. Klavišų " -#~ "kombinacijos formatas gali būti panašus į \"<Control>a\" arba \"<" -#~ "Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir " -#~ "leidžia maišyti didžiąsias bei mažąsias raides ir naudoti tokius " -#~ "sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "Toggle shaded state" +#~ msgstr "Perjungti lango sutraukimo būseną" -#~ msgid "" -#~ "The keybinding that switches to the workspace below the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri perjungia darbalaukį į žemiau esantį. Klavišų " -#~ "kombinacijos formatas gali būti panašus į \"<Control>a\" arba \"<" -#~ "Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir " -#~ "leidžia maišyti didžiąsias bei mažąsias raides ir naudoti tokius " -#~ "sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "Failed to scan themes directory: %s\n" +#~ msgstr "Nepavyko nuskanuoti temų aplanko: %s\n" #~ msgid "" -#~ "The keybinding that switches to the workspace on the left of the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." +#~ "Could not find a theme! Be sure %s exists and contains the usual themes.\n" #~ msgstr "" -#~ "Klavišų kombinacija, kuri perjungia darbalaukį į kairiau esantį. Klavišų " -#~ "kombinacijos formatas gali būti panašus į \"<Control>a\" arba \"<" -#~ "Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir " -#~ "leidžia maišyti didžiąsias bei mažąsias raides ir naudoti tokius " -#~ "sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ "Nepavyko rasti temos! Įsitikinkite, kad %s egzistuoja ir kad ten yra " +#~ "įprastos temos.\n" -#~ msgid "" -#~ "The keybinding that switches to the workspace on the right of the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri perjungia darbalaukį į dešiniau esantį. Klavišų " -#~ "kombinacijos formatas gali būti panašus į \"<Control>a\" arba \"<" -#~ "Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir " -#~ "leidžia maišyti didžiąsias bei mažąsias raides ir naudoti tokius " -#~ "sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "Screen %d on display \"%s\" already has a window manager\n" +#~ msgstr "Ekranas %d vaizduoklyje „%s“ jau turi langų valdyklę\n" -#~ msgid "" -#~ "The keybinding that switches to workspace 1. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri perjungia darbalaukį į darbalaukį nr.1. Klavišų " -#~ "kombinacijos formatas gali būti panašus į \"<Control>a\" arba \"<" -#~ "Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir " -#~ "leidžia maišyti didžiąsias bei mažąsias raides ir naudoti tokius " -#~ "sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "%d x %d" +#~ msgstr "%d x %d" -#~ msgid "" -#~ "The keybinding that switches to workspace 10. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri perjungia darbalaukį į darbalaukį nr.10. " -#~ "Klavišų kombinacijos formatas gali būti panašus į \"<Control>a\" " -#~ "arba \"<Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana " -#~ "laisva ir leidžia maišyti didžiąsias bei mažąsias raides ir naudoti " -#~ "tokius sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "top" +#~ msgstr "viršus" -#~ msgid "" -#~ "The keybinding that switches to workspace 11. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri perjungia darbalaukį į darbalaukį nr.11. " -#~ "Klavišų kombinacijos formatas gali būti panašus į \"<Control>a\" " -#~ "arba \"<Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana " -#~ "laisva ir leidžia maišyti didžiąsias bei mažąsias raides ir naudoti " -#~ "tokius sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "bottom" +#~ msgstr "apačia" -#~ msgid "" -#~ "The keybinding that switches to workspace 12. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri perjungia darbalaukį į darbalaukį nr.12. " -#~ "Klavišų kombinacijos formatas gali būti panašus į \"<Control>a\" " -#~ "arba \"<Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana " -#~ "laisva ir leidžia maišyti didžiąsias bei mažąsias raides ir naudoti " -#~ "tokius sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "left" +#~ msgstr "kairė" -#~ msgid "" -#~ "The keybinding that switches to workspace 2. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri perjungia darbalaukį į darbalaukį nr.2. Klavišų " -#~ "kombinacijos formatas gali būti panašus į \"<Control>a\" arba \"<" -#~ "Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir " -#~ "leidžia maišyti didžiąsias bei mažąsias raides ir naudoti tokius " -#~ "sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "right" +#~ msgstr "dešinė" -#~ msgid "" -#~ "The keybinding that switches to workspace 3. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri perjungia darbalaukį į darbalaukį nr.3. Klavišų " -#~ "kombinacijos formatas gali būti panašus į \"<Control>a\" arba \"<" -#~ "Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir " -#~ "leidžia maišyti didžiąsias bei mažąsias raides ir naudoti tokius " -#~ "sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "frame geometry does not specify \"%s\" dimension" +#~ msgstr "rėmelio aprašyme nenurodytas „%s“ matmuo" -#~ msgid "" -#~ "The keybinding that switches to workspace 4. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri perjungia darbalaukį į darbalaukį nr.4. Klavišų " -#~ "kombinacijos formatas gali būti panašus į \"<Control>a\" arba \"<" -#~ "Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir " -#~ "leidžia maišyti didžiąsias bei mažąsias raides ir naudoti tokius " -#~ "sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" +#~ msgstr "rėmelio aprašyme nenurodytas paraštės „%2$s“ „%1$s“ matmuo" -#~ msgid "" -#~ "The keybinding that switches to workspace 5. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri perjungia darbalaukį į darbalaukį nr.5. Klavišų " -#~ "kombinacijos formatas gali būti panašus į \"<Control>a\" arba \"<" -#~ "Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir " -#~ "leidžia maišyti didžiąsias bei mažąsias raides ir naudoti tokius " -#~ "sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "Button aspect ratio %g is not reasonable" +#~ msgstr "Mygtuko dydžio santykis %g yra nenuosaikus" -#~ msgid "" -#~ "The keybinding that switches to workspace 6. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri perjungia darbalaukį į darbalaukį nr.6. Klavišų " -#~ "kombinacijos formatas gali būti panašus į \"<Control>a\" arba \"<" -#~ "Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir " -#~ "leidžia maišyti didžiąsias bei mažąsias raides ir naudoti tokius " -#~ "sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "Frame geometry does not specify size of buttons" +#~ msgstr "Rėmelio aprašyme nenurodytas mygtukų dydis" -#~ msgid "" -#~ "The keybinding that switches to workspace 7. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri perjungia darbalaukį į darbalaukį nr.7. Klavišų " -#~ "kombinacijos formatas gali būti panašus į \"<Control>a\" arba \"<" -#~ "Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir " -#~ "leidžia maišyti didžiąsias bei mažąsias raides ir naudoti tokius " -#~ "sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "Gradients should have at least two colors" +#~ msgstr "Aprašant persiliejančias spalvas reikia nurodyti bent dvi spalvas" #~ msgid "" -#~ "The keybinding that switches to workspace 8. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "GTK custom color specification must have color name and fallback in " +#~ "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" #~ msgstr "" -#~ "Klavišų kombinacija, kuri perjungia darbalaukį į darbalaukį nr.8. Klavišų " -#~ "kombinacijos formatas gali būti panašus į \"<Control>a\" arba \"<" -#~ "Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir " -#~ "leidžia maišyti didžiąsias bei mažąsias raides ir naudoti tokius " -#~ "sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ "GTK spalvų aprašymas po būsenos turi turėti spalvos pavadinimą ir " +#~ "uždarančius laužtinius skliaustus, pvz.: gtk:custom(foo,bar); nepavyko " +#~ "perskaityti „%s“" #~ msgid "" -#~ "The keybinding that switches to workspace 9. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-" +#~ "z0-9-_ are valid" #~ msgstr "" -#~ "Klavišų kombinacija, kuri perjungia darbalaukį į darbalaukį nr.9. Klavišų " -#~ "kombinacijos formatas gali būti panašus į \"<Control>a\" arba \"<" -#~ "Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir " -#~ "leidžia maišyti didžiąsias bei mažąsias raides ir naudoti tokius " -#~ "sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ "Netinkamas simbolis „%c“ gtk:custom parametre color_name, leidžiama tik A-" +#~ "Za-z0-9_" #~ msgid "" -#~ "The keybinding used to activate the window menu. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " +#~ "fit the format" #~ msgstr "" -#~ "Klavišų kombinacija, aktyvuojanti lango meniu. Klavišų kombinacijos " -#~ "formatas gali būti panašus į „<Control>a“ arba „<Shift><" -#~ "Alt>F1“. Sistema apdorojanti aprašymą yra gana laisva ir leidžia " -#~ "maišyti didžiąsias bei mažąsias raides ir naudoti tokius sutrumpinimus " -#~ "kaip „<Ctl>“ ir „<Ctrl>“. Nustačius specialų požymį " -#~ "„disabled“, su šiuo veiksmu nebus susieta jokia klavišų kombinacija." +#~ "Gtk:custom formatas yra „gtk:custom(color_name,fallback)“, „%s“ " +#~ "neatitinka šio formato" #~ msgid "" -#~ "The keybinding used to close a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "GTK color specification must have the state in brackets, e.g. gtk:" +#~ "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" #~ msgstr "" -#~ "Klavišų kombinacija, kuri uždaro langą. Klavišų kombinacijos formatas " -#~ "gali būti panašus į \"<Control>a\" arba \"<Shift><Alt>" -#~ "F1. Sistema apdorojanti aprašymą yra gana laisva ir leidžia maišyti " -#~ "didžiąsias bei mažąsias raides ir naudoti tokius sutrumpinimus kaip \"<" -#~ "Ctl>\" ir \"<Ctrl>\". Nustačius specialų požymį \"disabled\", su " -#~ "šiuo veiksmu nebus susieta jokia klavišų kombinacija." +#~ "GTK spalvų aprašymas turi turėti būsenos aprašymą patalpintą tarp " +#~ "laužtinių skliaustų, pvz.: gtk:fg[NORMAL], kur NORMAL yra būsena; " +#~ "nepavyko apdoroti \"%s\"" #~ msgid "" -#~ "The keybinding used to enter \"move mode\" and begin moving a window " -#~ "using the keyboard. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." +#~ "GTK color specification must have a close bracket after the state, e.g. " +#~ "gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" #~ msgstr "" -#~ "Klavišų kombinacija, kuri perjungia langą į \"judėjimo veikseną\" ir " -#~ "leidžia po to judinti langą klaviatūros pagalba. Klavišų kombinacijos " -#~ "formatas gali būti panašus į \"<Control>a\" arba \"<Shift><" -#~ "Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir leidžia " -#~ "maišyti didžiąsias bei mažąsias raides ir naudoti tokius sutrumpinimus " -#~ "kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius specialų požymį " -#~ "\"disabled\", su šiuo veiksmu nebus susieta jokia klavišų kombinacija." +#~ "GTK spalvų aprašymas po būsenos turi turėti uždarančius laužtinius " +#~ "skliaustus, pvz.: gtk:fg[NORMAL], kur NORMAL yra būsena; nepavyko " +#~ "apdoroti \"%s\"" -#~ msgid "" -#~ "The keybinding used to enter \"resize mode\" and begin resizing a window " -#~ "using the keyboard. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "Klavišų kombinacija, perjungianti langą į „dydžio keitimo“ veikseną ir po " -#~ "to leidžianti keisti lango dydį klaviatūros pagalba. Klavišų kombinacijos " -#~ "formatas gali būti panašus į „<Control>a“ arba „<Shift><" -#~ "Alt>F1“. Sistema apdorojanti aprašymą yra gana laisva ir leidžia " -#~ "maišyti didžiąsias bei mažąsias raides ir naudoti tokius sutrumpinimus " -#~ "kaip „<Ctl>“ ir „<Ctrl>“. Nustačius specialų požymį " -#~ "„disabled“, su šiuo veiksmu nebus susieta jokia klavišų kombinacija." +#~ msgid "Did not understand state \"%s\" in color specification" +#~ msgstr "Nesuprantama spalvų aprašymo būsena \"%s\"" -#~ msgid "" -#~ "The keybinding used to hide all normal windows and set the focus to the " -#~ "desktop background. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri paslepia visus langus ir aktyvuoja darbalaukį. " -#~ "Klavišų kombinacijos formatas gali būti panašus į \"<Control>a\" " -#~ "arba \"<Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana " -#~ "laisva ir leidžia maišyti didžiąsias bei mažąsias raides ir naudoti " -#~ "tokius sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "Did not understand color component \"%s\" in color specification" +#~ msgstr "Spalvų aprašyme nurodytas nesuprantamas spalvos komponentas \"%s\"" #~ msgid "" -#~ "The keybinding used to maximize a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit " +#~ "the format" #~ msgstr "" -#~ "Klavišų kombinacija, naudojama išplėsti langui. Klavišų kombinacijos " -#~ "formatas gali būti panašus į „<Control>a“ arba „<Shift><" -#~ "Alt>F1“. Sistema apdorojanti aprašymą yra gana laisva ir leidžia " -#~ "maišyti didžiąsias bei mažąsias raides ir naudoti tokius sutrumpinimus " -#~ "kaip „<Ctl>“ ir „<Ctrl>“. Nustačius specialų požymį " -#~ "„disabled“, su šiuo veiksmu nebus susieta jokia klavišų kombinacija." +#~ "Išplaukimo formatas yra \"blend/bg_color/fg_color/alpha\", \"%s\" " +#~ "neatitinka šio formato" -#~ msgid "" -#~ "The keybinding used to minimize a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ msgid "Could not parse alpha value \"%s\" in blended color" #~ msgstr "" -#~ "Klavišų kombinacija, kuri sumažina langą. Klavišų kombinacijos formatas " -#~ "gali būti panašus į \"<Control>a\" arba \"<Shift><Alt>" -#~ "F1. Sistema apdorojanti aprašymą yra gana laisva ir leidžia maišyti " -#~ "didžiąsias bei mažąsias raides ir naudoti tokius sutrumpinimus kaip \"<" -#~ "Ctl>\" ir \"<Ctrl>\". Nustačius specialų požymį \"disabled\", su " -#~ "šiuo veiksmu nebus susieta jokia klavišų kombinacija." +#~ "Nepavyko aprodoti skaidrumo reikšmės \"%s\" priskirtos išplaukiančiai " +#~ "spalva" -#~ msgid "" -#~ "The keybinding used to move a window one workspace down. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" #~ msgstr "" -#~ "Klavišų kombinacija, kuri perkelia langą į žemiau esantį darbalaukį. " -#~ "Klavišų kombinacijos formatas gali būti panašus į \"<Control>a\" " -#~ "arba \"<Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana " -#~ "laisva ir leidžia maišyti didžiąsias bei mažąsias raides ir naudoti " -#~ "tokius sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ "Skaidrumo reikšmė \"%s\" tarp išplaukiančios spalvos yra ne tarp 0.0 ir " +#~ "1.0" #~ msgid "" -#~ "The keybinding used to move a window one workspace to the left. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." +#~ "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the " +#~ "format" #~ msgstr "" -#~ "Klavišų kombinacija, kuri perkelia langą į kairiau esantį darbalaukį. " -#~ "Klavišų kombinacijos formatas gali būti panašus į \"<Control>a\" " -#~ "arba \"<Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana " -#~ "laisva ir leidžia maišyti didžiąsias bei mažąsias raides ir naudoti " -#~ "tokius sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ "Šešėlio formatas yra \"shade/base_color/factor\", \"%s\" neatitinka šio " +#~ "formato" -#~ msgid "" -#~ "The keybinding used to move a window one workspace to the right. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri perkelia langą į dešiniau esantį darbalaukį. " -#~ "Klavišų kombinacijos formatas gali būti panašus į \"<Control>a\" " -#~ "arba \"<Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana " -#~ "laisva ir leidžia maišyti didžiąsias bei mažąsias raides ir naudoti " -#~ "tokius sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "Could not parse shade factor \"%s\" in shaded color" +#~ msgstr "Nepavyko apdoroti šešėlinės spalvos šešėlių rodiklio \"%s\"" -#~ msgid "" -#~ "The keybinding used to move a window one workspace up. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri perkelia langą į aukščiau esantį darbalaukį. " -#~ "Klavišų kombinacijos formatas gali būti panašus į \"<Control>a\" " -#~ "arba \"<Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana " -#~ "laisva ir leidžia maišyti didžiąsias bei mažąsias raides ir naudoti " -#~ "tokius sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "Shade factor \"%s\" in shaded color is negative" +#~ msgstr "Šešėlio rodiklis \"%s\" tarp šešėlinės spalvos yra neigiamas" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 1. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri perkelia langą į darbalaukį nr.1. Klavišų " -#~ "kombinacijos formatas gali būti panašus į \"<Control>a\" arba \"<" -#~ "Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir " -#~ "leidžia maišyti didžiąsias bei mažąsias raides ir naudoti tokius " -#~ "sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "Could not parse color \"%s\"" +#~ msgstr "Nepavyko apdoroti spalvos \"%s\"" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 10. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri perkelia langą į darbalaukį nr.10. Klavišų " -#~ "kombinacijos formatas gali būti panašus į \"<Control>a\" arba \"<" -#~ "Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir " -#~ "leidžia maišyti didžiąsias bei mažąsias raides ir naudoti tokius " -#~ "sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "Coordinate expression contains character '%s' which is not allowed" +#~ msgstr "Koordinačių išraiška turi neleistiną simbolį '%s'" #~ msgid "" -#~ "The keybinding used to move a window to workspace 11. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "Coordinate expression contains floating point number '%s' which could not " +#~ "be parsed" #~ msgstr "" -#~ "Klavišų kombinacija, kuri perkelia langą į darbalaukį nr.11. Klavišų " -#~ "kombinacijos formatas gali būti panašus į \"<Control>a\" arba \"<" -#~ "Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir " -#~ "leidžia maišyti didžiąsias bei mažąsias raides ir naudoti tokius " -#~ "sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ "Koordinačių išraiška turi skaičių su slankiu kableliu '%s', kuris negali " +#~ "būti apdorotas" #~ msgid "" -#~ "The keybinding used to move a window to workspace 12. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "Coordinate expression contains integer '%s' which could not be parsed" #~ msgstr "" -#~ "Klavišų kombinacija, kuri perkelia langą į darbalaukį nr.12. Klavišų " -#~ "kombinacijos formatas gali būti panašus į \"<Control>a\" arba \"<" -#~ "Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir " -#~ "leidžia maišyti didžiąsias bei mažąsias raides ir naudoti tokius " -#~ "sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ "Koordinačių išraiška turi sveiką skaičių '%s', kuris negali būti apdorotas" #~ msgid "" -#~ "The keybinding used to move a window to workspace 2. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "Coordinate expression contained unknown operator at the start of this " +#~ "text: \"%s\"" #~ msgstr "" -#~ "Klavišų kombinacija, kuri perkelia langą į darbalaukį nr.2. Klavišų " -#~ "kombinacijos formatas gali būti panašus į \"<Control>a\" arba \"<" -#~ "Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir " -#~ "leidžia maišyti didžiąsias bei mažąsias raides ir naudoti tokius " -#~ "sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ "Koordinačių išraiškoje nurodytas nežinomas operatorius šio teksto " +#~ "pradžioje: \"%s\"" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 3. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri perkelia langą į darbalaukį nr.3. Klavišų " -#~ "kombinacijos formatas gali būti panašus į \"<Control>a\" arba \"<" -#~ "Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir " -#~ "leidžia maišyti didžiąsias bei mažąsias raides ir naudoti tokius " -#~ "sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "Coordinate expression was empty or not understood" +#~ msgstr "Koordinačių išraiška tuščia arba nesuprantama" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 4. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri perkelia langą į darbalaukį nr.4. Klavišų " -#~ "kombinacijos formatas gali būti panašus į \"<Control>a\" arba \"<" -#~ "Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir " -#~ "leidžia maišyti didžiąsias bei mažąsias raides ir naudoti tokius " -#~ "sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "Coordinate expression results in division by zero" +#~ msgstr "Koordinačių išraiška sukelia dalybą iš nulio" #~ msgid "" -#~ "The keybinding used to move a window to workspace 5. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "Coordinate expression tries to use mod operator on a floating-point number" #~ msgstr "" -#~ "Klavišų kombinacija, kuri perkelia langą į darbalaukį nr.5. Klavišų " -#~ "kombinacijos formatas gali būti panašus į \"<Control>a\" arba \"<" -#~ "Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir " -#~ "leidžia maišyti didžiąsias bei mažąsias raides ir naudoti tokius " -#~ "sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ "Koordinačių išraiška bando panaudoti liekanos operatorių (mod) slankaus " +#~ "kablelio skaičiui" #~ msgid "" -#~ "The keybinding used to move a window to workspace 6. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "Coordinate expression has an operator \"%s\" where an operand was expected" #~ msgstr "" -#~ "Klavišų kombinacija, kuri perkelia langą į darbalaukį nr.6. Klavišų " -#~ "kombinacijos formatas gali būti panašus į \"<Control>a\" arba \"<" -#~ "Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir " -#~ "leidžia maišyti didžiąsias bei mažąsias raides ir naudoti tokius " -#~ "sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ "Koordinačių išraiškoje įvestas operatorius \"%s\" ten, kur turi būti " +#~ "vedamas operandas" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 7. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri perkelia langą į darbalaukį nr.7. Klavišų " -#~ "kombinacijos formatas gali būti panašus į \"<Control>a\" arba \"<" -#~ "Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir " -#~ "leidžia maišyti didžiąsias bei mažąsias raides ir naudoti tokius " -#~ "sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "Coordinate expression had an operand where an operator was expected" +#~ msgstr "Koordinačių išraiškoje operandas įrašytas operatoriaus vietoje" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 8. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri perkelia langą į darbalaukį nr.8. Klavišų " -#~ "kombinacijos formatas gali būti panašus į \"<Control>a\" arba \"<" -#~ "Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir " -#~ "leidžia maišyti didžiąsias bei mažąsias raides ir naudoti tokius " -#~ "sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "Coordinate expression ended with an operator instead of an operand" +#~ msgstr "Koordinačių išraiška pasibaigė operatoriumi, o ne operandu" #~ msgid "" -#~ "The keybinding used to move a window to workspace 9. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "Coordinate expression has operator \"%c\" following operator \"%c\" with " +#~ "no operand in between" #~ msgstr "" -#~ "Klavišų kombinacija, kuri perkelia langą į darbalaukį nr.9. Klavišų " -#~ "kombinacijos formatas gali būti panašus į \"<Control>a\" arba \"<" -#~ "Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir " -#~ "leidžia maišyti didžiąsias bei mažąsias raides ir naudoti tokius " -#~ "sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ "Koordinačių išraiškoje operatorius \"%c\" eina po operatoriaus \"%c\" be " +#~ "tarpinio operando" -#~ msgid "" -#~ "The keybinding used to move focus backwards between panels and the " -#~ "desktop, using a popup window. The format looks like \"<Control>a\" " -#~ "or \"<Shift><Alt>F1\". The parser is fairly liberal and " -#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" -#~ "\" and \"<Ctrl>\". If you set the option to the special string " -#~ "\"disabled\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri judina aktyvinimo požymius atgal tarp skydelių " -#~ "ir darbalaukio kartu su iššokančiu langu. Klavišų kombinacijos formatas " -#~ "gali būti panašus į \"<Control>a\" arba \"<Shift><Alt>" -#~ "F1. Sistema apdorojanti aprašymą yra gana laisva ir leidžia maišyti " -#~ "didžiąsias bei mažąsias raides ir naudoti tokius sutrumpinimus kaip \"<" -#~ "Ctl>\" ir \"<Ctrl>\". Nustačius specialų požymį \"disabled\", su " -#~ "šiuo veiksmu nebus susieta jokia klavišų kombinacija." +#~ msgid "Coordinate expression had unknown variable or constant \"%s\"" +#~ msgstr "Koordinačių išraiška saugo nežinomą kintamąjį arba konstantą \"%s\"" -#~ msgid "" -#~ "The keybinding used to move focus backwards between panels and the " -#~ "desktop, without a popup window. The format looks like \"<Control>a" -#~ "\" or \"<Shift><Alt>F1\". The parser is fairly liberal and " -#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" -#~ "\" and \"<Ctrl>\". If you set the option to the special string " -#~ "\"disabled\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri judina aktyvinimo požymius atgal tarp skydelių " -#~ "ir darbalaukio be iššokančio lango. Klavišų kombinacijos formatas gali " -#~ "būti panašus į \"<Control>a\" arba \"<Shift><Alt>F1. " -#~ "Sistema apdorojanti aprašymą yra gana laisva ir leidžia maišyti " -#~ "didžiąsias bei mažąsias raides ir naudoti tokius sutrumpinimus kaip \"<" -#~ "Ctl>\" ir \"<Ctrl>\". Nustačius specialų požymį \"disabled\", su " -#~ "šiuo veiksmu nebus susieta jokia klavišų kombinacija." +#~ msgid "Coordinate expression parser overflowed its buffer." +#~ msgstr "Koordinačių išraiškų skaitytuvas perpildė buferį." #~ msgid "" -#~ "The keybinding used to move focus backwards between windows of an " -#~ "application without a popup window. Holding \"shift\" together with this " -#~ "binding makes the direction go forward again. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "Coordinate expression had a close parenthesis with no open parenthesis" #~ msgstr "" -#~ "Klavišų kombinacija, kuri judina aktyvinimo požymius atgal tarp langų be " -#~ "iššokančio lango. Nuspaudus „Lyg2“ bus vėl judama į priekį. Klavišų " -#~ "kombinacijos formatas panašus į \"<Control>a\" arba \"<Shift>" -#~ "<Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir leidžia " -#~ "maišyti didžiąsias bei mažąsias raides ir naudoti tokius sutrumpinimus " -#~ "kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius specialų požymį " -#~ "\"disabled\", su šiuo veiksmu nebus susieta jokia klavišų kombinacija." +#~ "Koordinačių išraiškoje įvesti uždarantys skliaustai, nors atidarančių " +#~ "skliaustų nerasta" #~ msgid "" -#~ "The keybinding used to move focus backwards between windows of an " -#~ "application, using a popup window. Holding \"shift\" together with this " -#~ "binding makes the direction go forward again. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "Coordinate expression had an open parenthesis with no close parenthesis" #~ msgstr "" -#~ "Klavišų kombinacija, kuri judina aktyvinimo požymius atgal tarp langų " -#~ "kartu su iššokančiu langu. Nuspaudus „Lyg2“ bus vėl judama į priekį. " -#~ "Klavišų kombinacijos formatas panašus į \"<Control>a\" arba \"<" -#~ "Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir " -#~ "leidžia maišyti didžiąsias bei mažąsias raides ir naudoti tokius " -#~ "sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ "Koordinačių išraiškoje po atidarančių skliaustų neįvesti uždarantys " +#~ "skliaustai" -#~ msgid "" -#~ "The keybinding used to move focus backwards between windows without a " -#~ "popup window. Holding \"shift\" together with this binding makes the " -#~ "direction go forward again. The format looks like \"<Control>a\" or " -#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " -#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" -#~ "\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri judina aktyvinimo požymius atgal tarp langų be " -#~ "iššokančio lango. Klavišų kombinacijos formatas gali būti panašus į \"<" -#~ "Control>a\" arba \"<Shift><Alt>F1. Sistema apdorojanti " -#~ "aprašymą yra gana laisva ir leidžia maišyti didžiąsias bei mažąsias " -#~ "raides ir naudoti tokius sutrumpinimus kaip \"<Ctl>\" ir \"<" -#~ "Ctrl>\". Nustačius specialų požymį \"disabled\", su šiuo veiksmu nebus " -#~ "susieta jokia klavišų kombinacija." +#~ msgid "Coordinate expression doesn't seem to have any operators or operands" +#~ msgstr "Koordinačių išraiška neturi jokių operatorių ar operandų" -#~ msgid "" -#~ "The keybinding used to move focus backwards between windows, using a " -#~ "popup window. Holding \"shift\" together with this binding makes the " -#~ "direction go forward again. The format looks like \"<Control>a\" or " -#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " -#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" -#~ "\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri judina aktyvinimo požymius atgal tarp langų " -#~ "kartu su iššokančiu langu. Klavišų kombinacijos formatas gali būti " -#~ "panašus į \"<Control>a\" arba \"<Shift><Alt>F1. Sistema " -#~ "apdorojanti aprašymą yra gana laisva ir leidžia maišyti didžiąsias bei " -#~ "mažąsias raides ir naudoti tokius sutrumpinimus kaip \"<Ctl>\" ir " -#~ "\"<Ctrl>\". Nustačius specialų požymį \"disabled\", su šiuo veiksmu " -#~ "nebus susieta jokia klavišų kombinacija." +#~ msgid "Theme contained an expression that resulted in an error: %s\n" +#~ msgstr "Temoje esanti išraiška sukėlė klaidą: %s\n" #~ msgid "" -#~ "The keybinding used to move focus between panels and the desktop, using a " -#~ "popup window. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " +#~ "specified for this frame style" #~ msgstr "" -#~ "Klavišų kombinacija, kuri judina aktyvinimo požymius tarp skydelių ir " -#~ "darbalaukio kartu su iššokančiu langu. Klavišų kombinacijos formatas gali " -#~ "būti panašus į \"<Control>a\" arba \"<Shift><Alt>F1. " -#~ "Sistema apdorojanti aprašymą yra gana laisva ir leidžia maišyti " -#~ "didžiąsias bei mažąsias raides ir naudoti tokius sutrumpinimus kaip \"<" -#~ "Ctl>\" ir \"<Ctrl>\". Nustačius specialų požymį \"disabled\", su " -#~ "šiuo veiksmu nebus susieta jokia klavišų kombinacija." +#~ "Šiam rėmelio stiliui turi būti nurodytas <button function=\"%s\" state=" +#~ "\"%s\" draw_ops=\"kažkokswhatever\"/> požymis" #~ msgid "" -#~ "The keybinding used to move focus between panels and the desktop, without " -#~ "a popup window. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." +#~ "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/" +#~ ">" #~ msgstr "" -#~ "Klavišų kombinacija, kuri judina aktyvinimo požymius tarp skydelių ir " -#~ "darbalaukio be iššokančio lango. Klavišų kombinacijos formatas gali būti " -#~ "panašus į \"<Control>a\" arba \"<Shift><Alt>F1. Sistema " -#~ "apdorojanti aprašymą yra gana laisva ir leidžia maišyti didžiąsias bei " -#~ "mažąsias raides ir naudoti tokius sutrumpinimus kaip \"<Ctl>\" ir " -#~ "\"<Ctrl>\". Nustačius specialų požymį \"disabled\", su šiuo veiksmu " -#~ "nebus susieta jokia klavišų kombinacija." +#~ "Trūksta <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"kažkoks\"/>" -#~ msgid "" -#~ "The keybinding used to move focus between windows of an application " -#~ "without a popup window. Holding the \"shift\" key while using this " -#~ "binding reverses the direction of movement. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri judina aktyvinimo požymius tarp langų be " -#~ "iššokančio lango. \"Lyg2\" klavišas keičia judėjimo kryptį. Klavišų " -#~ "kombinacijos formatas panašus į \"<Control>a\" arba \"<Shift>" -#~ "<Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir leidžia " -#~ "maišyti didžiąsias bei mažąsias raides ir naudoti tokius sutrumpinimus " -#~ "kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius specialų požymį " -#~ "\"disabled\", su šiuo veiksmu nebus susieta jokia klavišų kombinacija." +#~ msgid "Failed to load theme \"%s\": %s\n" +#~ msgstr "Nepavyko paleisti temos \"%s\": %s\n" -#~ msgid "" -#~ "The keybinding used to move focus between windows of an application, " -#~ "using a popup window. (Traditionally <Alt>F6) Holding the \"shift\" " -#~ "key while using this binding reverses the direction of movement. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri judina aktyvinimo požymius tarp programos langų " -#~ "su iššokančiu langu. (Paprastai <Alt>F6) \"lyg2\" klavišas keičia " -#~ "judėjimo kryptį. Klavišų kombinacijos formatas gali būti panašus į \"<" -#~ "Control>a\" arba \"<Shift><Alt>F1. Sistema apdorojanti " -#~ "aprašymą yra gana laisva ir leidžia maišyti didžiąsias bei mažąsias " -#~ "raides ir naudoti tokius sutrumpinimus kaip \"<Ctl>\" ir \"<" -#~ "Ctrl>\". Nustačius specialų požymį \"disabled\", su šiuo veiksmu nebus " -#~ "susieta jokia klavišų kombinacija." +#~ msgid "No <%s> set for theme \"%s\"" +#~ msgstr "Temoje \"%2$s\" trūksta <%1$s> nustatymų" #~ msgid "" -#~ "The keybinding used to move focus between windows without a popup window. " -#~ "(Traditionally <Alt>Escape) Holding the \"shift\" key while using " -#~ "this binding reverses the direction of movement. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "No frame style set for window type \"%s\" in theme \"%s\", add a <window " +#~ "type=\"%s\" style_set=\"whatever\"/> element" #~ msgstr "" -#~ "Klavišų kombinacija, kuri judina aktyvinimo požymius tarp langų be " -#~ "iššokančio lango. (Paprastai <Alt>Escape) \"lyg2\" klavišas keičia " -#~ "judėjimo kryptį. Klavišų kombinacijos formatas gali būti panašus į \"<" -#~ "Control>a\" arba \"<Shift><Alt>F1. Sistema apdorojanti " -#~ "aprašymą yra gana laisva ir leidžia maišyti didžiąsias bei mažąsias " -#~ "raides ir naudoti tokius sutrumpinimus kaip \"<Ctl>\" ir \"<" -#~ "Ctrl>\". Nustačius specialų požymį \"disabled\", su šiuo veiksmu nebus " -#~ "susieta jokia klavišų kombinacija." +#~ "Rėmelio stilius nenurodytas lango tipui \"%s\" temoje \"%s\", pridėkite " +#~ "<window type=\"%s\" style_set=\"kažkoks\"/> elementą" #~ msgid "" -#~ "The keybinding used to move focus between windows, using a popup window. " -#~ "(Traditionally <Alt>Tab) Holding the \"shift\" key while using this " -#~ "binding reverses the direction of movement. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "User-defined constants must begin with a capital letter; \"%s\" does not" #~ msgstr "" -#~ "Klavišų kombinacija, kuri judina aktyvinimo požymius tarp langų kartu su " -#~ "iššokančiu langu. (Paprastai <Alt>Tab) \"lyg2\" klavišas keičia " -#~ "judėjimo kryptį. Klavišų kombinacijos formatas gali būti panašus į \"<" -#~ "Control>a\" arba \"<Shift><Alt>F1. Sistema apdorojanti " -#~ "aprašymą yra gana laisva ir leidžia maišyti didžiąsias bei mažąsias " -#~ "raides ir naudoti tokius sutrumpinimus kaip \"<Ctl>\" ir \"<" -#~ "Ctrl>\". Nustačius specialų požymį \"disabled\", su šiuo veiksmu nebus " -#~ "susieta jokia klavišų kombinacija." +#~ "Naudotojo nustatytos konstantos turi prasidėti didžiąja raide; „%s“ nėra " +#~ "didžioji" -#~ msgid "" -#~ "The keybinding used to toggle always on top. A window that is always on " -#~ "top will always be visible over other overlapping windows. The format " -#~ "looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -#~ "parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Klavišų kombinacija, įjungianti veikseną „visada viršuje. Įjungus šią " -#~ "veikseną langas visada bus aukščiau kitų persidengiančių langų. Klavišų " -#~ "kombinacijos formatas gali būti panašus į „<Control>a“ arba „<" -#~ "Shift><Alt>F1“. Sistema apdorojanti aprašymą yra gana laisva ir " -#~ "leidžia maišyti didžiąsias bei mažąsias raides ir naudoti tokius " -#~ "sutrumpinimus kaip „<Ctl>“ ir „<Ctrl>“. Nustačius specialų " -#~ "požymį „disabled“, su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "Constant \"%s\" has already been defined" +#~ msgstr "Konstanta „%s“ jau aprašyta" -#~ msgid "" -#~ "The keybinding used to toggle fullscreen mode. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Klavišų kombinacija, perjungianti viso ekrano veikseną. Klavišų " -#~ "kombinacijos formatas gali būti panašus į „<Control>a“ arba „<" -#~ "Shift><Alt>F1“. Sistema apdorojanti aprašymą yra gana liberali " -#~ "ir leidžia maišyti didžiąsias bei mažąsias raides ir naudoti tokius " -#~ "sutrumpinimus kaip „<Ctl>“ ir „<Ctrl>“. Nustačius specialų " -#~ "požymį „disabled“, su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "No \"%s\" attribute on element <%s>" +#~ msgstr "Trūksta „%s“ požymio elemente <%s>" -#~ msgid "" -#~ "The keybinding used to toggle maximization. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri įjungia arba išjungia lango išdidinimą. Klavišų " -#~ "kombinacijos formatas gali būti panašus į \"<Control>a\" arba \"<" -#~ "Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir " -#~ "leidžia maišyti didžiąsias bei mažąsias raides ir naudoti tokius " -#~ "sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "Line %d character %d: %s" +#~ msgstr "%d eilutės simbolis %d: %s" -#~ msgid "" -#~ "The keybinding used to toggle shaded/unshaded state. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri keičia lango šešėlinę/ne šešėlinę būseną. " -#~ "Klavišų kombinacijos formatas gali būti panašus į \"<Control>a\" " -#~ "arba \"<Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana " -#~ "laisva ir leidžia maišyti didžiąsias bei mažąsias raides ir naudoti " -#~ "tokius sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "Attribute \"%s\" repeated twice on the same <%s> element" +#~ msgstr "Požymis „%s“ pasikartoja tame pačiame <%s> elemente" -#~ msgid "" -#~ "The keybinding used to toggle whether the window is on all workspaces or " -#~ "just one. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri nustato ar langas bus tik viename darbalauke, " -#~ "ar visuose. Klavišų kombinacijos formatas gali būti panašus į \"<" -#~ "Control>a\" arba \"<Shift><Alt>F1. Sistema apdorojanti " -#~ "aprašymą yra gana laisva ir leidžia maišyti didžiąsias bei mažąsias " -#~ "raides ir naudoti tokius sutrumpinimus kaip \"<Ctl>\" ir \"<" -#~ "Ctrl>\". Nustačius specialų požymį \"disabled\", su šiuo veiksmu nebus " -#~ "susieta jokia klavišų kombinacija." +#~ msgid "Attribute \"%s\" is invalid on <%s> element in this context" +#~ msgstr "Šiame kontekste požymis „%s“ yra netinkamas elemente <%s>" -#~ msgid "" -#~ "The keybinding used to unmaximize a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri sutraukia langą. Klavišų kombinacijos formatas " -#~ "gali būti panašus į \"<Control>a\" arba \"<Shift><Alt>" -#~ "F1. Sistema apdorojanti aprašymą yra gana laisva ir leidžia maišyti " -#~ "didžiąsias bei mažąsias raides ir naudoti tokius sutrumpinimus kaip \"<" -#~ "Ctl>\" ir \"<Ctrl>\". Nustačius specialų požymį \"disabled\", su " -#~ "šiuo veiksmu nebus susieta jokia klavišų kombinacija." +#~ msgid "Could not parse \"%s\" as an integer" +#~ msgstr "Nepavyko apdoroti „%s“ kaip sveiko skaičiaus" -#~ msgid "" -#~ "The keybinding which display's the panel's \"Run Application\" dialog " -#~ "box. The format looks like \"<Control>a\" or \"<Shift><" -#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If " -#~ "you set the option to the special string \"disabled\", then there will be " -#~ "no keybinding for this action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri iškviečia skydelio programos paleidimo dialogo " -#~ "langą. Klavišų kombinacijos formatas gali būti panašus į \"<Control>" -#~ "a\" arba \"<Shift><Alt>F1. Sistema apdorojanti aprašymą yra " -#~ "gana laisva ir leidžia maišyti didžiąsias bei mažąsias raides ir naudoti " -#~ "tokius sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +#~ msgstr "Nesuprantami simbolių seką „%2$s“ užbaigiantys simboliai „%1$s“" -#~ msgid "" -#~ "The keybinding which invokes a terminal. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri iškviečia terminalą. Klavišų kombinacijos " -#~ "formatas gali būti panašus į \"<Control>a\" arba \"<Shift><" -#~ "Alt>F1. Sistema, apdorojanti aprašymą, yra gana laisva ir leidžia " -#~ "maišyti didžiąsias bei mažąsias raides ir naudoti tokius sutrumpinimus " -#~ "kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius specialų požymį " -#~ "\"disabled\", su šiuo veiksmu nebus susieta jokia klavišų kombinacija." +#~ msgid "Integer %ld must be positive" +#~ msgstr "Sveikas skaičius %ld turi būti teigiamas" -#~ msgid "" -#~ "The keybinding which invokes the panel's screenshot utility to take a " -#~ "screenshot of a window. The format looks like \"<Control>a\" or " -#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " -#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" -#~ "\", then there will be no keybinding for this action." +#~ msgid "Integer %ld is too large, current max is %d" #~ msgstr "" -#~ "Klavišų kombinacija, kuri paleidžia skydelio ekrano vaizdo kopijų darymo " -#~ "programą tam, kad toji padarytų lango vaizdo kopiją. Klavišų kombinacijos " -#~ "formatas gali būti panašus į \"<Control>a\" arba \"<Shift><" -#~ "Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir leidžia " -#~ "maišyti didžiąsias bei mažąsias raides ir naudoti tokius sutrumpinimus " -#~ "kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius specialų požymį " -#~ "\"disabled\", su šiuo veiksmu nebus susieta jokia klavišų kombinacija." +#~ "Sveikas skaičius %ld yra per didelis, didžiausia galima reikšmė šiuo metu " +#~ "yra %d" -#~ msgid "" -#~ "The keybinding which invokes the panel's screenshot utility. The format " -#~ "looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -#~ "parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri skydelio ekrano vaizdo kopijų darymo progamą. " -#~ "Klavišų kombinacijos formatas gali būti panašus į \"<Control>a\" " -#~ "arba \"<Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana " -#~ "laisva ir leidžia maišyti didžiąsias bei mažąsias raides ir naudoti " -#~ "tokius sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "Could not parse \"%s\" as a floating point number" +#~ msgstr "Nepavyko aprodyti „%s“ kaip skaičiaus su slankiu kableliu" -#~ msgid "" -#~ "The keybinding which shows the panel's main menu. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri iškviečia skydelio pagrindinį meniu. Klavišų " -#~ "kombinacijos formatas gali būti panašus į \"<Control>a\" arba \"<" -#~ "Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir " -#~ "leidžia maišyti didžiąsias bei mažąsias raides ir naudoti tokius " -#~ "sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" +#~ msgstr "Loginės reikšmės turi būti \"true\" arba \"false\", o ne \"%s\"" -#~ msgid "" -#~ "This keybinding changes whether a window is above or below other windows. " -#~ "If the window is covered by another one, it raises the window above all " -#~ "others, and if the window is already fully visible, it lowers it below " -#~ "all others. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri keičia lango buvimo žemiau/aukščiau kitų langų " -#~ "būklę. Jei langas yra paslėptas po kitu langu, jis bus iškeltas aukščiau " -#~ "kitų. Jei langas yra pilnai matomas, jis atsidurs žemiau kitų langų. " -#~ "Klavišų kombinacijos formatas panašus į \"<Control>a\" arba \"<" -#~ "Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir " -#~ "leidžia maišyti didžiąsias bei mažąsias raides ir naudoti tokius " -#~ "sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "Angle must be between 0.0 and 360.0, was %g\n" +#~ msgstr "Kampas turi būti tarp 0.0 ir 360.0, o buvo nurodyta %g\n" #~ msgid "" -#~ "This keybinding lowers a window below other windows. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" #~ msgstr "" -#~ "Klavišų kombinacija, kuri paslepia langą po kitais langais. Klavišų " -#~ "kombinacijos formatas gali būti panašus į \"<Control>a\" arba \"<" -#~ "Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir " -#~ "leidžia maišyti didžiąsias bei mažąsias raides ir naudoti tokius " -#~ "sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ "Skaidrumo reikšmė turi būti tarp 0.0 (nematomas) ir 1.0 (visiškai " +#~ "neskaidrus), o buvo nurodyta %g\n" #~ msgid "" -#~ "This keybinding moves a window against the north (top) side of the " -#~ "screen. The format looks like \"<Control>a\" or \"<Shift><" -#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If " -#~ "you set the option to the special string \"disabled\", then there will be " -#~ "no keybinding for this action." +#~ "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," +#~ "large,x-large,xx-large)\n" #~ msgstr "" -#~ "Ši klavišų kombinacija priglaudžia langą prie viršutinio ekrano krašto. " -#~ "Klavišų kombinacijos formatas gali būti panašus į \"<Control>a\" " -#~ "arba \"<Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana " -#~ "laisva ir leidžia maišyti didžiąsias bei mažąsias raides ir naudoti " -#~ "tokius sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." - -#, fuzzy -#~ msgid "" -#~ "This keybinding moves a window into the center of the screen. The format " -#~ "looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -#~ "parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Ši klavišų kombinacija priglaudžia langą prie kairiojo ekrano krašto. " -#~ "Klavišų kombinacijos formatas gali būti panašus į \"<Control>a\" " -#~ "arba \"<Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana " -#~ "laisva ir leidžia maišyti didžiąsias bei mažąsias raides ir naudoti " -#~ "tokius sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ "Netinkamas antraštės mastelis \"%s\" (turi būti viena iš xx-small,x-small," +#~ "small,medium,large,x-large,xx-large reikšmių)\n" -#~ msgid "" -#~ "This keybinding moves a window into the east (right) side of the screen. " -#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -#~ "\". The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Ši klavišų kombinacija priglaudžia langą prie dešiniojo ekrano krašto. " -#~ "Klavišų kombinacijos formatas gali būti panašus į \"<Control>a\" " -#~ "arba \"<Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana " -#~ "laisva ir leidžia maišyti didžiąsias bei mažąsias raides ir naudoti " -#~ "tokius sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "<%s> name \"%s\" used a second time" +#~ msgstr "<%s> požymis name \"%s\" panaudotas antrą kartą" -#~ msgid "" -#~ "This keybinding moves a window into the north-east (top right) corner of " -#~ "the screen. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Ši klavišų kombinacija priglaudžia langą prie ekrano viršutinio kairiojo " -#~ "kampo. Klavišų kombinacijos formatas gali būti panašus į \"<Control>" -#~ "a\" arba \"<Shift><Alt>F1. Sistema apdorojanti aprašymą yra " -#~ "gana laisva ir leidžia maišyti didžiąsias bei mažąsias raides ir naudoti " -#~ "tokius sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "<%s> parent \"%s\" has not been defined" +#~ msgstr "Nenurodytas <%s> požymis parent \"%s\"" -#~ msgid "" -#~ "This keybinding moves a window into the north-west (top left) corner of " -#~ "the screen. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Ši klavišų kombinacija priglaudžia langą prie ekrano viršutinio dešiniojo " -#~ "kampo. Klavišų kombinacijos formatas gali būti panašus į \"<Control>" -#~ "a\" arba \"<Shift><Alt>F1. Sistema apdorojanti aprašymą yra " -#~ "gana laisva ir leidžia maišyti didžiąsias bei mažąsias raides ir naudoti " -#~ "tokius sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "<%s> geometry \"%s\" has not been defined" +#~ msgstr "Nenurodytas <%s> požymis geometry \"%s\"" -#~ msgid "" -#~ "This keybinding moves a window into the south (bottom) side of the " -#~ "screen. The format looks like \"<Control>a\" or \"<Shift><" -#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If " -#~ "you set the option to the special string \"disabled\", then there will be " -#~ "no keybinding for this action." +#~ msgid "<%s> must specify either a geometry or a parent that has a geometry" #~ msgstr "" -#~ "Ši klavišų kombinacija priglaudžia langą prie apatinio ekrano krašto. " -#~ "Klavišų kombinacijos formatas gali būti panašus į \"<Control>a\" " -#~ "arba \"<Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana " -#~ "laisva ir leidžia maišyti didžiąsias bei mažąsias raides ir naudoti " -#~ "tokius sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ "<%s> turi nurodyti dydžio (geometrijos) nustatymus arba viršesnį " +#~ "elementą, jau turinti tokius nustatymus" -#~ msgid "" -#~ "This keybinding moves a window into the south-east (bottom right) corner " -#~ "of the screen. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "Ši klavišų kombinacija priglaudžia langą prie ekrano apatinio dešiniojo " -#~ "kampo. Klavišų kombinacijos formatas gali būti panašus į \"<Control>" -#~ "a\" arba \"<Shift><Alt>F1. Sistema apdorojanti aprašymą yra " -#~ "gana laisva ir leidžia maišyti didžiąsias bei mažąsias raides ir naudoti " -#~ "tokius sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "You must specify a background for an alpha value to be meaningful" +#~ msgstr "Turite nustatyti foną, kad alfa reikšmė būtų prasminga" -#~ msgid "" -#~ "This keybinding moves a window into the south-west (bottom left) corner " -#~ "of the screen. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "Ši klavišų kombinacija priglaudžia langą prie ekrano apatinio kairiojo " -#~ "kampo. Klavišų kombinacijos formatas gali būti panašus į \"<Control>" -#~ "a\" arba \"<Shift><Alt>F1. Sistema apdorojanti aprašymą yra " -#~ "gana laisva ir leidžia maišyti didžiąsias bei mažąsias raides ir naudoti " -#~ "tokius sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "Unknown type \"%s\" on <%s> element" +#~ msgstr "Nežinomas type \"%s\" požymis elemente <%s>" -#~ msgid "" -#~ "This keybinding moves a window into the west (left) side of the screen. " -#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -#~ "\". The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Ši klavišų kombinacija priglaudžia langą prie kairiojo ekrano krašto. " -#~ "Klavišų kombinacijos formatas gali būti panašus į \"<Control>a\" " -#~ "arba \"<Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana " -#~ "laisva ir leidžia maišyti didžiąsias bei mažąsias raides ir naudoti " -#~ "tokius sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "Unknown style_set \"%s\" on <%s> element" +#~ msgstr "Nežinomas style_set \"%s\" požymis elemente <%s>" -#~ msgid "" -#~ "This keybinding raises the window above other windows. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri iškelia langą virš kitų langų. Klavišų " -#~ "kombinacijos formatas gali būti panašus į \"<Control>a\" arba \"<" -#~ "Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir " -#~ "leidžia maišyti didžiąsias bei mažąsias raides ir naudoti tokius " -#~ "sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "Window type \"%s\" has already been assigned a style set" +#~ msgstr "Lango type \"%s\" požymis jau turi nurodytą stiliaus aprašymą" -#~ msgid "" -#~ "This keybinding resizes a window to fill available horizontal space. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Klavišų kombinacija, kuri išplečia langą horizontaliai. Klavišų " -#~ "kombinacijos formatas gali būti panašus į \"<Control>a\" arba \"<" -#~ "Shift><Alt>F1. Sistema apdorojanti aprašymą yra gana laisva ir " -#~ "leidžia maišyti didžiąsias bei mažąsias raides ir naudoti tokius " -#~ "sutrumpinimus kaip \"<Ctl>\" ir \"<Ctrl>\". Nustačius " -#~ "specialų požymį \"disabled\", su šiuo veiksmu nebus susieta jokia klavišų " -#~ "kombinacija." +#~ msgid "Element <%s> is not allowed below <%s>" +#~ msgstr "Elementas <%s> neleistinas žemiau <%s>" #~ msgid "" -#~ "This keybinding resizes a window to fill available vertical space. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." +#~ "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio" +#~ "\" for buttons" #~ msgstr "" -#~ "Klavišų kombinacija, išdidinanti langą vertikaliai. Klavišų kombinacijos " -#~ "formatas gali būti panašus į „<Control>a“ arba „<Shift><" -#~ "Alt>F1“. Sistema apdorojanti aprašymą yra gana laisva ir leidžia " -#~ "maišyti didžiąsias bei mažąsias raides ir naudoti tokius sutrumpinimus " -#~ "kaip „<Ctl>“ ir „<Ctrl>“. Nustačius specialų požymį " -#~ "„disabled“, su šiuo veiksmu nebus susieta jokia klavišų kombinacija." +#~ "Negalima tuo pačiu metu nurodyti „button_width“/„button_height“ ir " +#~ "„aspect_ratio“" -#~ msgid "Unmaximize Window" -#~ msgstr "Sutraukti langą" +#~ msgid "Distance \"%s\" is unknown" +#~ msgstr "Atstumas \"%s\" yra nežinomas" -#~ msgid "No \"%s\" attribute on <%s> element" -#~ msgstr "Elemente <%2$s> trūksta požymio \"%1$s\"" +#~ msgid "Aspect ratio \"%s\" is unknown" +#~ msgstr "Dydžio santykis \"%s\" yra nežinomas" -#~ msgid "Theme already has a fallback icon" -#~ msgstr "Tema jau turi atsarginę piktogramą" +#~ msgid "Border \"%s\" is unknown" +#~ msgstr "Paraštė \"%s\" nežinoma" -#~ msgid "Theme already has a fallback mini_icon" -#~ msgstr "Tema jau turi atsarginę mini piktogramą" +#~ msgid "No \"start_angle\" or \"from\" attribute on element <%s>" +#~ msgstr "Elemente <%s> trūksta \"start_angle\" ar \"from\" požymio" -#~ msgid "No \"name\" attribute on element <%s>" -#~ msgstr "Elemente <%s> trūksta \"name\" požymio" +#~ msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" +#~ msgstr "Elemente <%s> trūksta \"extent_angle\" ar \"to\" požymio" -#~ msgid "No \"value\" attribute on element <%s>" -#~ msgstr "Elemente <%s> trūksta \"value\" požymio" +#~ msgid "Did not understand value \"%s\" for type of gradient" +#~ msgstr "Nesuprantama reikšmė \"%s\" persiliejančio elemento tipo aprašyme" -#~ msgid "No \"top\" attribute on element <%s>" -#~ msgstr "Elemente <%s> trūksta \"top\" požymio" +#~ msgid "Did not understand fill type \"%s\" for <%s> element" +#~ msgstr "Nežinoma fill type požymio reikšmė \"%s\" elemente <%s>" -#~ msgid "No \"bottom\" attribute on element <%s>" -#~ msgstr "Elemente <%s> trūksta \"bottom\" požymio" +#~ msgid "Did not understand state \"%s\" for <%s> element" +#~ msgstr "Nežinoma state požymio reikšmė \"%s\" elemente <%s>" -#~ msgid "No \"left\" attribute on element <%s>" -#~ msgstr "Elemente <%s> trūksta \"left\" požymio" +#~ msgid "Did not understand shadow \"%s\" for <%s> element" +#~ msgstr "Nežinoma shadow požymio reikšmė \"%s\" elemente <%s>" -#~ msgid "No \"right\" attribute on element <%s>" -#~ msgstr "Elemente <%s> trūksta \"right\" požymio" +#~ msgid "Did not understand arrow \"%s\" for <%s> element" +#~ msgstr "Nežinoma arrow požymio reikšmė \"%s\" elemente <%s>" -#~ msgid "No \"color\" attribute on element <%s>" -#~ msgstr "Elemente <%s> trūksta \"color\" požymio" +#~ msgid "No <draw_ops> called \"%s\" has been defined" +#~ msgstr "Neaprašyti jokie <draw_ops> požymiai pavadinti \"%s\"" -#~ msgid "No \"x1\" attribute on element <%s>" -#~ msgstr "Elemente <%s> trūksta \"x1\" požymio" +#~ msgid "Including draw_ops \"%s\" here would create a circular reference" +#~ msgstr "" +#~ "Čia įvesdami draw_ops \"%s\" požymius jūs sukuriate žiedinį aprašymą" -#~ msgid "No \"y1\" attribute on element <%s>" -#~ msgstr "Elemente <%s> trūksta \"y1\" požymio" +#~ msgid "Unknown position \"%s\" for frame piece" +#~ msgstr "Nežinoma rėmelio elemento padėtis \"%s\"" -#~ msgid "No \"x2\" attribute on element <%s>" -#~ msgstr "Elemente <%s> trūksta \"x2\" požymio" +#~ msgid "Frame style already has a piece at position %s" +#~ msgstr "Rėmelio stiliaus aprašyme padėtis %s jau aprašyta" -#~ msgid "No \"y2\" attribute on element <%s>" -#~ msgstr "Elemente <%s> trūksta \"y2\" požymio" +#~ msgid "No <draw_ops> with the name \"%s\" has been defined" +#~ msgstr "Vardui \"%s\" nenurodyti jokie <draw_ops> požymiai" -#~ msgid "No \"y\" attribute on element <%s>" -#~ msgstr "Elemente <%s> trūksta \"y\" požymio" +#~ msgid "Unknown function \"%s\" for button" +#~ msgstr "Mygtukui priskirta nežinoma funkcija \"%s\"" -#~ msgid "No \"width\" attribute on element <%s>" -#~ msgstr "Elemente <%s> trūksta \"width\" požymio" +#~ msgid "Button function \"%s\" does not exist in this version (%d, need %d)" +#~ msgstr "" +#~ "Mygtuko funkcija \"%s\" neegzistuoja šioje versijoje (%d, reikia %d)" -#~ msgid "No \"height\" attribute on element <%s>" -#~ msgstr "Elemente <%s> trūksta \"height\" požymio" +#~ msgid "Unknown state \"%s\" for button" +#~ msgstr "Mygtukui priskirta nežinoma būsena \"%s\"" -#~ msgid "No \"start_angle\" attribute on element <%s>" -#~ msgstr "Elemente <%s> trūksta \"start_angle\" požymio" +#~ msgid "Frame style already has a button for function %s state %s" +#~ msgstr "" +#~ "Rėmelio stiliaus aprašyme jau yra nurodytas mygtukas aprašantis funkcijos " +#~ "%s būseną %s" -#~ msgid "No \"extent_angle\" attribute on element <%s>" -#~ msgstr "Elemente <%s> trūksta \"extent_angle\" požymio" +#~ msgid "\"%s\" is not a valid value for focus attribute" +#~ msgstr "Reikšmė „%s“ nepriimtina aktyvinimo požymyje" -#~ msgid "No \"alpha\" attribute on element <%s>" -#~ msgstr "Elemente <%s> trūksta \"alpha\" požymio" +#~ msgid "\"%s\" is not a valid value for state attribute" +#~ msgstr "Reikšmė „%s“ nepriimtina būsenos požymyje" -#~ msgid "No \"type\" attribute on element <%s>" -#~ msgstr "Elemente <%s> trūksta \"type\" požymio" +#~ msgid "A style called \"%s\" has not been defined" +#~ msgstr "Stilius pavadinimu „%s“ neaprašytas" -#~ msgid "No \"filename\" attribute on element <%s>" -#~ msgstr "Elemente <%s> trūksta \"filename\" požymio" +#~ msgid "\"%s\" is not a valid value for resize attribute" +#~ msgstr "Reikšmė „%s“ nepriimtina dydžio keitimo požymyje" -#~ msgid "No \"state\" attribute on element <%s>" -#~ msgstr "Elemente <%s> trūksta \"state\" požymio" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized/shaded " +#~ "states" +#~ msgstr "" +#~ "Negalima naudoti \"resize\" požymio elemente <%s>, skirtame išplėtimo/" +#~ "šešėlių būsenų aprašymui" -#~ msgid "No \"shadow\" attribute on element <%s>" -#~ msgstr "Elemente <%s> trūksta \"shadow\" požymio" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized states" +#~ msgstr "" +#~ "Negalima naudoti \"resize\" požymio elemente <%s>, skirtame išplėtimo " +#~ "būsenų aprašymui" -#~ msgid "No \"arrow\" attribute on element <%s>" -#~ msgstr "Elemente <%s> trūksta \"arror\" požymio" +#~ msgid "Style has already been specified for state %s resize %s focus %s" +#~ msgstr "state %s resize %s focus %s požymiai jau turi stiliaus aprašymą" -#~ msgid "No \"value\" attribute on <%s> element" -#~ msgstr "Elemente <%s> trūksta \"value\" požymio" +#~ msgid "Style has already been specified for state %s focus %s" +#~ msgstr "Aktyvinimo %2$s būsena %1$s jau turi stiliaus aprašymą" -#~ msgid "No \"position\" attribute on <%s> element" -#~ msgstr "Elemente <%s> trūksta \"position\" požymio" +#~ msgid "" +#~ "Can't have a two draw_ops for a <piece> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Negalima naudoti dviejų draw_ops požymių <piece> elemente (tema nustatė " +#~ "draw_ops požymį ir <draw_ops> elementą, arba nurodė du elementus)" -#~ msgid "No \"function\" attribute on <%s> element" -#~ msgstr "Elemente <%s> trūksta \"function\" požymio" +#~ msgid "" +#~ "Can't have a two draw_ops for a <button> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Negalima naudoti dviejų draw_ops požymių <button> elemente (tema nustatė " +#~ "draw_ops požymį ir <draw_ops> elementą, arba nurodė du elementus)" -#~ msgid "No \"state\" attribute on <%s> element" -#~ msgstr "Elemente <%s> trūksta \"state\" požymio" +#~ msgid "" +#~ "Can't have a two draw_ops for a <menu_icon> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Negalima naudoti dviejų draw_ops požymių <menu_icon> elemente (tema " +#~ "nustatė draw_ops požymį ir <draw_ops> elementą, arba nurodė du elementus)" -#~ msgid "No \"focus\" attribute on <%s> element" -#~ msgstr "Elemente <%s> trūksta požymio „focus“" +#~ msgid "Bad version specification '%s'" +#~ msgstr "Bloga versijos specifikacija „%s“" -#~ msgid "No \"style\" attribute on <%s> element" -#~ msgstr "Elemente <%s> trūksta požymio „style“" +#~ msgid "" +#~ "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" +#~ "theme-2.xml" +#~ msgstr "" +#~ "„version“ požymis negali būti naudojamas metacity-theme-1.xml arba " +#~ "metacity-theme-2.xml" -#~ msgid "No \"resize\" attribute on <%s> element" -#~ msgstr "Elemente <%s> trūksta požymio „resize“" +#~ msgid "" +#~ "Theme requires version %s but latest supported theme version is %d.%d" +#~ msgstr "" +#~ "Tema reikalauja versijos %s, bet paskutinė palaikoma versija yra %d.%d" -#~ msgid "Type of %s was not integer" -#~ msgstr "%s tipas buvo ne sveikasis skaičius" +#~ msgid "Outermost element in theme must be <metacity_theme> not <%s>" +#~ msgstr "Pradinis temos elementas turi būti <metacity_theme>, o ne <%s>" #~ msgid "" -#~ "%d stored in GConf key %s is not a reasonable cursor_size; must be in the " -#~ "range 1..128\n" +#~ "Element <%s> is not allowed inside a name/author/date/description element" #~ msgstr "" -#~ "%d saugoma GConf rakte %s yra nenuosaikus cursor_size; turi būti nuo 1 " -#~ "iki 128\n" +#~ "Elementas <%s> nepriimtinas tarp name/author/date/description elementų" + +#~ msgid "Element <%s> is not allowed inside a <constant> element" +#~ msgstr "Elementas <%s> nepriimtinas tarp <constant> elemento" #~ msgid "" -#~ "%d stored in GConf key %s is not a reasonable number of workspaces, " -#~ "current maximum is %d\n" +#~ "Element <%s> is not allowed inside a distance/border/aspect_ratio element" #~ msgstr "" -#~ "%d reikšmė saugoma GConf rakte %s nurodo nepriimtina darbalaukų skaičių, " -#~ "šiuo metu maksimali reikšmė yra %d\n" +#~ "Elementas <%s> nepriimtinas tarp distance/border/aspect_ratio elementų" + +#~ msgid "Element <%s> is not allowed inside a draw operation element" +#~ msgstr "Elementas <%s> piešimo operacijos elemente neleidžiamas" + +#~ msgid "Element <%s> is not allowed inside a <%s> element" +#~ msgstr "Elementas <%s> elemente <%s> yra neleidžiamas" + +#~ msgid "No draw_ops provided for frame piece" +#~ msgstr "Rėmelio elementui nepriskirta draw_ops funkcija" + +#~ msgid "No draw_ops provided for button" +#~ msgstr "Mygtukui nepriskirta draw_ops funkcija" + +#~ msgid "No text is allowed inside element <%s>" +#~ msgstr "Elemente <%s> tekstas negalimas" + +#~ msgid "<%s> specified twice for this theme" +#~ msgstr "<%s> elementas temos aprašyme nurodytas du kartus" + +#~ msgid "Failed to find a valid file for theme %s\n" +#~ msgstr "Nepavyko rasti tinkamo temos %s failo\n" diff --git a/po/lv.po b/po/lv.po index 69834b90f..cb9ea9ad4 100644 --- a/po/lv.po +++ b/po/lv.po @@ -2,500 +2,319 @@ # metaciy for Latvian. # Copyright (C) 2002, 2006, 2007, 2009 Free Software Foundation, Inc. # +# # Peteris Krisjanis <pecisk@inbox.lv>, 2002. # Raivis Dejus <orvils@gmail.com>, 2006, 2007, 2009. # Rudolfs <rudolfs.mazurs@gmail.com>, 2011. # Rūdofls Mazurs <rudolfs.mazurs@gmail.com>, 2011, 2012. +# Rūdolfs Mazurs <rudolfs.mazurs@gmail.com>, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019. msgid "" msgstr "" "Project-Id-Version: lv\n" -"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=muffin" -"&keywords=I18N+L10N&component=general\n" -"POT-Creation-Date: 2012-03-11 21:56+0000\n" -"PO-Revision-Date: 2012-03-13 23:11+0200\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2019-08-06 00:49+0000\n" +"PO-Revision-Date: 2019-08-24 19:55+0200\n" "Last-Translator: Rūdolfs Mazurs <rudolfs.mazurs@gmail.com>\n" "Language-Team: Latvian <lata-l10n@googlegroups.com>\n" +"Language: lv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : " -"2);\n" -"X-Generator: Lokalize 1.2\n" -"Language: lv\n" - -#: ../src/50-muffin-windows.xml.in.h:1 -#: ../src/50-muffin-windows.xml.in.h:3 -#| msgid "_Windows" -msgid "Windows" -msgstr "Logi" - -#: ../src/50-muffin-windows.xml.in.h:2 -#: ../src/50-muffin-windows.xml.in.h:1 -msgid "View split on left" -msgstr "Izvietot kreisajā ekrāna pusē" - -#: ../src/50-muffin-windows.xml.in.h:3 -#: ../src/50-muffin-windows.xml.in.h:2 -msgid "View split on right" -msgstr "Izvietot labajā ekrāna pusē" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 :" +" 2);\n" +"X-Generator: Lokalize 2.0\n" -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format -msgid "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." -msgstr "Cits kompozīcijas pārvaldnieks jau darbojas ekrānā %d displejā \"%s\"." +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Navigācija" -#: ../src/core/bell.c:307 -msgid "Bell event" -msgstr "Zvana notikums" +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Pārvietot logu uz 1. darbvietu" -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Nezināms logu informācijas pieprasījums: %d" +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Pārvietot logu uz 2. darbvietu" -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> nereaģē." +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Pārvietot logu uz 3. darbvietu" -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "Lietotne nereaģē." +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Pārvietot logu uz 4. darbvietu" -#: ../src/core/delete.c:119 -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "" -"Jūs varat uzgaidīt neilgu brīdi, līdz tā atgūstas, vai arī aizvērt to " -"piespiedu kārtā." +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Pārvietot logu uz pēdējo darbvietu" -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "_Gaidīt" +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "Pārvietot logu uz darbvietu augšup" -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "Aizvērt _piespiedu kārtā" +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "Pārvietot logu uz darbvietu lejup" -#: ../src/core/display.c:361 -#: ../src/core/display.c:365 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "Trūkst %s paplašinājuma, kas nepieciešams kompozicionēšanai" +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "Pārvietot logu uz monitoru pa kreisi" -#: ../src/core/display.c:427 -#: ../src/core/display.c:431 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Neizdevās atvērt X logu sistēmas displeju '%s'\n" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "Pārvietot logu uz monitoru pa labi" -#: ../src/core/keybindings.c:852 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "" -"Kāda cita programma jau lieto taustiņu %s ar modificētājiem %x kā sasaisti\n" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "Pārvietot logu uz monitoru augšup" -#: ../src/core/main.c:206 -msgid "Disable connection to session manager" -msgstr "Atslēgt savienojumu ar sesiju pārvaldnieku" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "Pārvietot logu uz monitoru lejup" -#: ../src/core/main.c:212 -msgid "Replace the running window manager" -msgstr "Aizvietot darbojošos logu pārvaldnieku" +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "Pārslēgt lietotnes" -#: ../src/core/main.c:218 -msgid "Specify session management ID" -msgstr "Norādīt sesijas pārvaldības ID" +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "Pārslēgties uz iepriekšējo lietotni" -#: ../src/core/main.c:223 -msgid "X Display to use" -msgstr "Lietojamais X displejs" +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "Pārslēgt logus" -#: ../src/core/main.c:229 -msgid "Initialize session from savefile" -msgstr "Inicializēt sesiju no saglabātā faila" +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "Pārslēgties uz iepriekšējo logu" -#: ../src/core/main.c:235 -msgid "Make X calls synchronous" -msgstr "Padarīt X izsaukumus sinhronus" +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "Pārslēgt vienas lietotnes logus" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Neizdevās noskanēt tēmu direktoriju: %s\n" +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "Pārslēgties uz lietotnes iepriekšējo logu" -#: ../src/core/main.c:520 -#, c-format -msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "" -"Neizdevās atrast tēmu! Pārliecinieties, ka %s eksistē un satur parastās " -"tēmas.\n" +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "Pārslēgt sistēmas vadīklas" -#: ../src/core/muffin.c:40 -#: ../src/core/muffin.c:42 -#, c-format -msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" -"muffin %s\n" -"Autortiesības (C) 2001-%d Havoc Pennington, Red Hat, Inc., un citi\n" -"Šī ir brīvā programmatūra; par kopēšanas nosacījumiem skatīt avotu.\n" -"Netiek dota NEKĀDA garantija; pat ne KOMERCIĀLAS VĒRTĪBAS vai DERĪGUMA " -"NOTEIKTAM NOLŪKAM.\n" +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "Pārslēgties uz iepriekšējo sistēmas vadīklu" -#: ../src/core/muffin.c:54 -#: ../src/core/muffin.c:56 -msgid "Print version" -msgstr "Parādīt versiju" +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "Pārslēgties starp logiem tieši" -#: ../src/core/muffin.c:60 -#: ../src/core/muffin.c:62 -msgid "Comma-separated list of compositor plugins" -msgstr "Ar komatu atdalīts kompozīcijas spraudņu saraksts" +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "Pārslēgties tieši uz iepriekšējo logu" -#: ../src/core/prefs.c:1077 -#: ../src/core/prefs.c:1067 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"Apvedceļi bojātām lietotnēm atslēgti. Dažas lietotnes var neuzvesties " -"pareizi.\n" - -#: ../src/core/prefs.c:1152 -#: ../src/core/prefs.c:1142 -#, c-format, c-format -#| msgid "Could not parse font description \"%s\" from GConf key %s\n" -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "Neizdevās parsēt fonta aprakstu \"%s\" no GSettings atslēgas %s\n" - -#: ../src/core/prefs.c:1218 -#: ../src/core/prefs.c:1208 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"\"%s\", kas atrasta konfigurācijas datubāzē, nav derīga vērtība peles pogas " -"modifikatoram\n" +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "Pārslēgties starp lietotnes logiem tieši" -#: ../src/core/prefs.c:1736 -#: ../src/core/prefs.c:1720 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "" -"\"%s\", kas atrasta konfigurācijas datubāzē, nav derīga vērtība " -"taustiņsasaistei \"%s\"\n" +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "Pārslēgties tieši uz iepriekšējo lietotnes logu" -#: ../src/core/prefs.c:1833 -#: ../src/core/prefs.c:1817 -#, c-format -msgid "Workspace %d" -msgstr "Darbvieta %d" +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "Pārslēgt sistēmas vadīklas tieši" -#: ../src/core/screen.c:730 -#: ../src/core/screen.c:741 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "Ekrāna %d displejs \"%s\" ir nederīgs\n" +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "Pārslēgties tieši uz iepriekšējo sistēmas vadīklu" -#: ../src/core/screen.c:746 -#: ../src/core/screen.c:757 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"Ekrāna %d displejam \"%s\" jau ir logu pārvaldnieks; mēģiniet lietot " -"--replace " -"iespēju, lai aizvietotu pašreizējo logu pārvaldnieku.\n" +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "Slēpt visus parastos logus" -#: ../src/core/screen.c:773 -#: ../src/core/screen.c:784 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "Neizdevās iegūt logu pārvaldnieka izvēli ekrāna %d displejā \"%s\"\n" +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "Pārslēgties uz 1. darbvietu" -#: ../src/core/screen.c:828 -#: ../src/core/screen.c:839 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "Ekrāna %d displejam \"%s\" jau ir logu pārvaldnieks\n" +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "Pārslēgties uz 2. darbvietu" -#: ../src/core/screen.c:1013 -#: ../src/core/screen.c:1024 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "Neizdevās atlaist ekrānu %d uz displeja \"%s\"\n" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "Pārslēgties uz 3. darbvietu" -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Neizdevās izveidot mapi '%s': %s\n" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "Pārslēgties uz 4. darbvietu" -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "Neizdevās atvērt sesijas failu '%s' rakstīšanai: %s\n" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "Pārslēgties uz pēdējo darbvietu" -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Kļūda, ierakstot sesijas failu '%s': %s\n" +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "Pāriet uz darbvietu augšup" -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Kļūda, aizverot sesijas failu '%s': %s\n" +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "Pāriet uz darbvietu lejup" -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Kļūda, parsējot saglabāto sesijas failu: %s\n" +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "Sistēma" -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "<muffin_session> atribūts pamanits, bet mums jau ir sesijas ID" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Rādīt palaišanas komandrindu" -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Nezināms atribūts %s <%s> elementam" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Rādīt aktivitāšu pārskatu" -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "ligzdota <window> birka" +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Atjaunot tastatūras saīsnes" -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "Nezināms elements %s" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Logi" -#: ../src/core/session.c:1809 -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" -"Šie logi neatbalsta "saglabāt pašreizējos iestatījumus" un būs " -"jāpārstartē pašrocīgi nākamreiz, kad pieteiksieties." +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "Aktivizēt loga izvēlni" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Neizdevās atvērt atkļūdošanas žurnālu: %s\n" +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Pārslēgt pilnekrāna režīmu" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Neizdevās fdopen() žurnāla failu %s: %s\n" +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "Pārslēgt maksimizācijas stāvokli" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "Atvērtais žurnāla fails %s\n" +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "Maksimizēt logu" -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "Muffin tika kompilēts bez vārdiskā režīma atbalsta\n" +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Atjaunot loga izmēru" -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "Logu pārvaldnieks: " +#: data/50-mutter-windows.xml:18 +msgid "Close window" +msgstr "Aizvērt logu" -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "Kļūda logu pārvaldniekā: " +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "Paslēpt logu" -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "Logu pārvaldnieka brīdinājums: " +#: data/50-mutter-windows.xml:22 +msgid "Move window" +msgstr "Pārvietot logu" -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "Logu pārvaldnieka kļūda: " +#: data/50-mutter-windows.xml:24 +msgid "Resize window" +msgstr "Mainīt loga izmēru" -#. first time through -#: ../src/core/window.c:7224 -#: ../src/core/window.c:7145 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"Logs %s iestata SM_CLIENT_ID pats sev, nevis WM_CLIENT_LEADER logam kā " -"norādīts ICCCM.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7887 -#: ../src/core/window.c:7808 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %" -"d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"Logs %s iestata MWM padomu, ka tā izmērs nav maināms, bet iestata minimālo " -"izmēru %d x %d un maksimālo izmēru %d x %d; tas ir diezgan dīvaini.\n" +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "Pārslēgt, vai logam jābūt visās darbvietās vai vienā" -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "Lietotne iestatīja neīstu _NET_WM_PID %lu\n" +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "Pacelt logu, ja to aizsedz, citādi pazemināt" -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (uz %s)" +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "Pacelt logu virs citiem logiem" -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "Nederīgs WM_TRANSIENT_FOR logs 0x%lx norādīts %s.\n" +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "Pazemināt logu zem citiem logiem" -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "WM_TRANSIENT_FOR logs 0x%lx priekš %s veidotu cilpu.\n" +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "Maksimizēt logu vertikāli" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"Logam 0x%lx ir rekvizīts %s,\n" -"kam vajadzēja būt %s tipa formātā %d,\n" -"bet īstenībā bija %s tipa formātā %d n_items %d\n" -"Šī visdrīzāk ir lietotnes, nevis logu pārvaldnieka kļūda.\n" -"Logam bija virsraksts=\"%s\" klase=\"%s\" nosaukums=\"%s\"\n" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "Maksimizēt logu horizontāli" -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "Rekvizīts %s logā 0x%lx saturēja nederīgu UTF-8\n" +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "Izvietot kreisajā ekrāna pusē" -#: ../src/core/xprops.c:494 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"Rekvizīts %slogā 0x%lx saturēja nederīgu UTF-8 priekšmetam %d no saraksta\n" +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "Izvietot labajā ekrāna pusē" -#: ../src/muffin.desktop.in.h:1 ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 +#: data/org.gnome.mutter.gschema.xml.in:7 msgid "Modifier to use for extended window management operations" msgstr "Modifikators, kuru lietot paplašinātām loga pārvaldības darbībām" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 +#: data/org.gnome.mutter.gschema.xml.in:8 msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." msgstr "" -"Šis taustiņš inicializēs \"pārklāšanu\", kas ir kombināciju loga pārskats un " -"lietotnes palaišanas sistēma. Noklusētais parasti ir \"Windows taustiņš\" uz " -"PC aparatūras. Tiek sagaidīts, ka šī sasaite ir vai nu noklusētā, vai tukša " -"virkne." +"Šis taustiņš inicializēs “pārklāšanu”, kas ir kombināciju loga pārskats un " +"lietotnes palaišanas sistēma. Noklusētais parasti ir “Windows taustiņš” uz " +"PC aparatūras. Tiek sagaidīts, ka šī sasaite ir vai nu noklusējuma, vai " +"tukša virkne." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 +#: data/org.gnome.mutter.gschema.xml.in:20 msgid "Attach modal dialogs" msgstr "Piesaistīt modālos dialogus" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 +#: data/org.gnome.mutter.gschema.xml.in:21 msgid "" "When true, instead of having independent titlebars, modal dialogs appear " "attached to the titlebar of the parent window and are moved together with " "the parent window." msgstr "" -"Ja patiess, vietā, lai būtu neatkarīgas virsraksta joslas, modālais dialogs " -"būs piesaistīts virsraksta joslai vecāka logam un tiks pārvietots kopā ar " -"vecāka logu." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 -msgid "Live Hidden Windows" -msgstr "Dzīvie slēptie logi" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"Nosaka, vai slēpto logu vajadzētu (t.i. minimizētie logi un logi, kas " -"atrodas citās darbvietās) uzturēt pie dzīvības." +"Ja patiess, tā vietā, lai būtu neatkarīgas virsraksta joslas, modālais " +"dialogs būs piesaistīts virsraksta joslai vecāka logam un tiks pārvietots " +"kopā ar vecāka logu." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 +#: data/org.gnome.mutter.gschema.xml.in:30 msgid "Enable edge tiling when dropping windows on screen edges" -msgstr "Automātiski izklāt logu, kad to nomet uz ekrāna malas" +msgstr "Aktivēt logu sānisko izklāšanu, kad to nomet uz ekrāna malas" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 +#: data/org.gnome.mutter.gschema.xml.in:31 msgid "" "If enabled, dropping windows on vertical screen edges maximizes them " "vertically and resizes them horizontally to cover half of the available " "area. Dropping windows on the top screen edge maximizes them completely." msgstr "" -"Logi, kas nomesti uz ekrāna labās vai kreisās malas, tiks izklāti pa visu " -"ekrāna augstumu un pusi no pieejamā platuma, bet tie, kas nomesti uz " -"augšējās malas, tiks izklāti pa visu ekrānu." +"Ja aktivēts, logi, kas nomesti uz ekrāna labās vai kreisās malas, tiks " +"izklāti pa visu ekrāna augstumu pusē no pieejamā platuma, bet tie, kas " +"nomesti uz augšējās malas, tiks izklāti pa visu ekrānu." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 +#: data/org.gnome.mutter.gschema.xml.in:40 msgid "Workspaces are managed dynamically" msgstr "Darbvirsmas tiek pārvaldītas dinamiski" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 +#: data/org.gnome.mutter.gschema.xml.in:41 msgid "" -"Determines whether workspaces are managed dynamically or whether there's a " +"Determines whether workspaces are managed dynamically or whether there’s a " "static number of workspaces (determined by the num-workspaces key in org." "gnome.desktop.wm.preferences)." msgstr "" "Nosaka, vai darbvirsmas tiek pārvaldītas dinamiski, vai arī ir statisks " -"darbvirsmu skaits (ko nosaka num-workspaces atslēga laukā org." -"gnome.desktop.wm.preferences)." +"darbvirsmu skaits (ko nosaka num-workspaces atslēga laukā org.gnome.desktop." +"wm.preferences)." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 +#: data/org.gnome.mutter.gschema.xml.in:50 msgid "Workspaces only on primary" msgstr "Darbvietas tikai uz galvenā" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 +#: data/org.gnome.mutter.gschema.xml.in:51 msgid "" "Determines whether workspace switching should happen for windows on all " "monitors or only for windows on the primary monitor." @@ -503,13 +322,11 @@ msgstr "" "Nosaka, vai darbvietu pārslēgšanai vajadzētu notikt visiem logiem visos " "monitoros, vai tikai logiem galvenajā monitorā." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 +#: data/org.gnome.mutter.gschema.xml.in:59 msgid "No tab popup" msgstr "Nerādīt logus pārslēgšanās laikā" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 +#: data/org.gnome.mutter.gschema.xml.in:60 msgid "" "Determines whether the use of popup and highlight frame should be disabled " "for window cycling." @@ -517,1909 +334,442 @@ msgstr "" "Nosaka, vai atslēgt uzlecošo izvēlni ar logu attēliem un izvēles rāmi, kad " "notiek pārslēgšanās starp logiem ar tabulatora vai tildes taustiņiem." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Aizkavēt fokusa izmaiņas, līdz rādītājs pārstāj kustēties" + +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" +"Ja patiess un fokusēšanas režīms ir vai nu “sloppy” (paviršs) vai " +"“mouse” (pele), tad fokuss nemainīsies uzreiz pēc ieiešanas logā, bet tikai " +"pēc tam, kad rādītājs beidzis kustēties." + +#: data/org.gnome.mutter.gschema.xml.in:79 msgid "Draggable border width" msgstr "Velkams malas platums" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 +#: data/org.gnome.mutter.gschema.xml.in:80 msgid "" -"The amount of total draggable borders. If the theme's visible borders are " +"The amount of total draggable borders. If the theme’s visible borders are " "not enough, invisible borders will be added to meet this value." msgstr "" -"Kopējo velkamo malu apjoms. Ja tēmas redzamās robežas nav pietiekamas, tiks " +"Kopējo velkamo malu apjoms. Ja motīva redzamās robežas nav pietiekamas, tiks " "pievienotas neredzamas robežas, lai iegūtu šo vērtību." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:17 -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 -#| msgid "Remove Window From Top" +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "Automātiski maksimizēt logus, kas ir gandrīz ar monitora izmēru" + +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" +"Ja aktivizēts, jauni logi, kuru izmērs ir gandrīz tāds pats, kā monitoram, " +"tiks maksimizēti." + +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Novietot logu vidū" + +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" +"Ja patiess, jaunie logi vienmēr tiks novietoti monitora aktīvā ekrāna vidū." + +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Ieslēgt eksperimentālās iespējas" + +#: data/org.gnome.mutter.gschema.xml.in:108 +#| msgid "" +#| "To enable experimental features, add the feature keyword to the list. " +#| "Whether the feature requires restarting the compositor depends on the " +#| "given feature. Any experimental feature is not required to still be " +#| "available, or configurable. Don’t expect adding anything in this setting " +#| "to be future proof. Currently possible keywords: • “scale-monitor-" +#| "framebuffer” — makes mutter default to layout logical monitors in a " +#| "logical pixel coordinate space, while scaling monitor framebuffers " +#| "instead of window content, to manage HiDPI monitors. Does not require a " +#| "restart." +msgid "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes " +"mutter request a low priority real-time scheduling. The executable or user " +"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — " +"initializes Xwayland lazily if there are X11 clients. Requires restart." +msgstr "" +"Lai ieslēgtu eksperimentālās iespējas, pievienojiet iespējas atslēgvārdu " +"sarakstam. Vai iespējai būs nepieciešama kompozitora pārstartēšana, būs " +"atkarīga no dotās iespējas. Jebkura eksperimentāla iespēja var būt " +"nepieejama vai nekonfigurējama. Negaidiet, ka jebkura no šīm iespējām " +"nākotnē strādās. Pašlaik pieejamie atslēgvārdi: • “scale-monitor-" +"framebuffer” — liek mutter pēc noklusējuma izkārtot loģiskos monitorus " +"loģisko pikseļu koordināšu telpā, kamēr mērogo monitora kadru buferus, nevis " +"loga saturu, lai pārvaldītu HiDPI monitorus. Pārstartēšana nav nepieciešama." +" • “rt-scheduler” — liek mutter pieprasīt mazāku prioritāti reālā laika" +" procesu plānošanā. Izpildāmajai datnei vai lietotājam ir jābūt ar" +" CAP_SYS_NICE. Pārstartēšana ir nepieciešama. • “autostart-xwayland” —" +" inicializē Xwayland slinki, ja eksistē X11 klienti. Pārstartēšana ir" +" nepieciešama." + +#: data/org.gnome.mutter.gschema.xml.in:134 +msgid "Modifier to use to locate the pointer" +msgstr "Modifikators, ko izmantot, lai atrastu rādītāju" + +#: data/org.gnome.mutter.gschema.xml.in:135 +msgid "This key will initiate the “locate pointer” action." +msgstr "Šī atslēga inicializēs “atrast rādītāju” darbību." + +#: data/org.gnome.mutter.gschema.xml.in:155 msgid "Select window from tab popup" msgstr "Izvēlēties logu no tabulatora izvēlnes" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:18 -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 +#: data/org.gnome.mutter.gschema.xml.in:160 msgid "Cancel tab popup" msgstr "Atcelt logu rādīšanu" -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "Lietojums: %s\n" - -#: ../src/ui/frames.c:1158 -#: ../src/ui/frames.c:1157 -msgid "Close Window" -msgstr "Aizvērt logu" - -#: ../src/ui/frames.c:1161 -#: ../src/ui/frames.c:1160 -msgid "Window Menu" -msgstr "Loga izvēlne" - -#: ../src/ui/frames.c:1164 -#: ../src/ui/frames.c:1163 -msgid "Minimize Window" -msgstr "Minimizēt logu" - -#: ../src/ui/frames.c:1167 -#: ../src/ui/frames.c:1166 -msgid "Maximize Window" -msgstr "Maksimizēt logu" - -#: ../src/ui/frames.c:1170 -#: ../src/ui/frames.c:1169 -msgid "Restore Window" -msgstr "Atjaunot logu" - -#: ../src/ui/frames.c:1173 -#: ../src/ui/frames.c:1172 -msgid "Roll Up Window" -msgstr "Uzrullēt logu" - -#: ../src/ui/frames.c:1176 -#: ../src/ui/frames.c:1175 -msgid "Unroll Window" -msgstr "Norullēt logu" - -#: ../src/ui/frames.c:1179 -#: ../src/ui/frames.c:1178 -msgid "Keep Window On Top" -msgstr "Turēt logu virspusē" - -#: ../src/ui/frames.c:1182 -#: ../src/ui/frames.c:1181 -msgid "Remove Window From Top" -msgstr "Aizvākt logu no virspuses" - -#: ../src/ui/frames.c:1185 -#: ../src/ui/frames.c:1184 -msgid "Always On Visible Workspace" -msgstr "Vienmēr redzamajā darbvietā" - -#: ../src/ui/frames.c:1188 -#: ../src/ui/frames.c:1187 -msgid "Put Window On Only One Workspace" -msgstr "Turēt logu tikai vienā darbvietā" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "Mi_nimizēt" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "Ma_ksimizēt" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "At_jaunot" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "_Uzrullēt" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "_Norullēt" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "_Pārvietot" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "_Mainīt" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "Pārvietot virsrak_sta joslu uz ekrāna" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "Vienmēr _virspusē" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "Vienmēr uz redzamās d_arbvietas" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "_Tikai uz šīs darbvietas" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "Pārvietot uz darbvietu pa _kreisi" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "Pārvietot uz darbvietu pa lab_i" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "Pārvietot _uz augstāku darbvietu" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "Pārvietot uz zemāku _darbvietu" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "_Aizvērt" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "Darbvieta %d%n" - -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "Darbvieta 1_0" - -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "Darbvieta %s%d" - -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "Pārvietot uz citu darb_vietu" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. +#: data/org.gnome.mutter.gschema.xml.in:165 +msgid "Switch monitor configurations" +msgstr "Pārslēgt monitoru konfigurācijas" + +#: data/org.gnome.mutter.gschema.xml.in:170 +msgid "Rotates the built-in monitor configuration" +msgstr "Pagriež iebūvētā monitora konfigurāciju" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Pārslēgties uz VT 1" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Pārslēgties uz VT 2" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Pārslēgties uz VT 3" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Pārslēgties uz VT 4" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Pārslēgties uz VT 5" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Pārslēgties uz VT 6" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Pārslēgties uz VT 7" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Pārslēgties uz VT 8" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Pārslēgties uz VT 9" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Pārslēgties uz VT 10" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Pārslēgties uz VT 11" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Pārslēgties uz VT 12" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "Atkal ieslēdz saīsnes" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +#| msgid "Allow grabs with Xwayland" +msgid "Allow X11 grabs to lock keyboard focus with Xwayland" +msgstr "Atļaut X11 satvērieniem bloķēt tastatūras fokusu ar Xwayland" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 +#| msgid "" +#| "Allow keyboard grabs issued by X11 applications running in Xwayland to be " +#| "taken into account. For a X11 grab to be taken into account under " +#| "Wayland, the client must also either send a specific X11 ClientMessage to " +#| "the root window or be among the applications white-listed in key " +#| "“xwayland-grab-access-rules”." +msgid "" +"Allow all keyboard events to be routed to X11 “override redirect” windows " +"with a grab when running in Xwayland. This option is to support X11 clients " +"which map an “override redirect” window (which do not receive keyboard " +"focus) and issue a keyboard grab to force all keyboard events to that " +"window. This option is seldom used and has no effect on regular X11 windows " +"which can receive keyboard focus under normal circumstances. For a X11 grab " +"to be taken into account under Wayland, the client must also either send a " +"specific X11 ClientMessage to the root window or be among the applications " +"white-listed in key “xwayland-grab-access-rules”." +msgstr "" +"Atļaut viesus tastatūras notikumus sūtīt cauri X11 “pārrakstīt pārsūtīšanu”" +" logiem ar satvērienu, kad darbina Xwayland. Šī opcija ir domāta atbalstīt" +" X11 klientus, kas kartē “pārrakstīt pārsūtīšanu” logu (kas nesaņem" +" tastatūras fokusu) un veic tastatūras satveršanu, lai forsētu visus" +" tastatūras notikumus uz šo logu. Šo opciju izmanto reti un tā neietekmē" +" parastos X11 logus, kuri var saņemt tastatūras fokusu normālos apstākļos." +" Lai ņemtu vērā X11 tvērienus Wayland vidē, klientam arī jāsūta specifisks" +" X11 ClientMessage uz root (saknes) logu, vai arī jābūt lietotņu baltajā" +" sarakstā atslēgā “xwayland-grab-access-rules”." + +#: data/org.gnome.mutter.wayland.gschema.xml.in:84 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "Xwayland lietotnes, kuras drīkst pieprasīt tastatūras satveršanu" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:85 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "" +"Saraksts ar resursu nosaukumiem vai resursu klasi X11 logiem, kuri vai nu " +"drīkst, vai nedrīkst pieprasīt X11 tastatūras satveršanu zem Xwayland. " +"Resursa nosaukumu vai resursa klasi dotajam X11 logam var iegūt, izmantojot " +"komandu “xprop WM_CLASS”. Vērtībās ir atbalstītas aizstājējzīmes “*” un “?”. " +"Vērtības, ka sākas ar “!”, ir melnajā sarakstā, kam ir prioritāte pār balto " +"sarakstu, kad atsauc lietotnes no noklusējuma sistēmas saraksta. Noklusējuma " +"sistēmas sarakstā iekļauj sekojošās lietotnes: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Lietotāji var pārtraukt esošo " +"tvērienu, izmantojot noteiktus tastatūras īsinājumtaustiņus, kas ir noteikti " +"“restore-shortcuts” atslēgā." + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. #. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" - -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" - -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "augša" - -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "apakša" - -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "pa kreisi" - -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "pa labi" - -#: ../src/ui/theme.c:286 +#: src/backends/meta-input-settings.c:2531 #, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "rāmja ģeometrija nenosaka \"%s\" dimensiju" +msgid "Mode Switch (Group %d)" +msgstr "Režīma slēdzis (grupa %d)" -#: ../src/ui/theme.c:305 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "rāmja ģeometrija nenosaka dimensiju \"%s\" robežai \"%s\"" +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2554 +msgid "Switch monitor" +msgstr "Pārslēgt monitoru" -#: ../src/ui/theme.c:342 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "Pogas samērs %g nav saprātīgs" +#: src/backends/meta-input-settings.c:2556 +msgid "Show on-screen help" +msgstr "Rādīt palīdzību uz ekrāna" -#: ../src/ui/theme.c:354 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "Rāmja ģeometrija nenosaka pogu izmēru" +#: src/backends/meta-monitor.c:223 +msgid "Built-in display" +msgstr "Iebūvēts displejs" -#: ../src/ui/theme.c:1067 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "Krāsu pārejās ir jābūt vismaz divām krāsām" +#: src/backends/meta-monitor.c:252 +msgid "Unknown" +msgstr "Nezināms" -#: ../src/ui/theme.c:1219 -#, c-format -msgid "" -"GTK custom color specification must have color name and fallback in " -"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" -msgstr "" -"GTK pielāgotajā krāsu specifikācijā ir jābūt krāsas nosaukumam un atkāpšanās " -"ceļam iekavās, piem., gtk:custom(foo,bar); neizdevās parsēt \"%s\"" +#: src/backends/meta-monitor.c:254 +msgid "Unknown Display" +msgstr "Nezināms displejs" -#: ../src/ui/theme.c:1235 +#: src/backends/meta-monitor.c:262 #, c-format -msgid "" -"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" -"_ are valid" -msgstr "" -"Nederīga rakstzīme '%c' iekš color_name parameter no gtk:custom, tikai " -"A-Za-z0-9-_ ir derīgas" +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme.c:1249 +#: src/backends/meta-monitor.c:270 #, c-format -msgid "" -"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " -"fit the format" -msgstr "" -"Gtk:custom formāts ir \"gtk:custom(color_name,fallback)\", \"%s\" neiekļaujas " -"formātā" +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme.c:1294 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"GTK krāsas specifikācijā ir jābūt stāvoklim iekavās, piem., gtk:fg[NORMAL], " -"kur NORMAL ir stāvoklis; neizdevās parsēt \"%s\"" +#. Translators: this string will appear in Sysprof +#: src/backends/meta-profiler.c:82 +msgid "Compositor" +msgstr "Kompozitors" -#: ../src/ui/theme.c:1308 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:510 #, c-format msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"GTK krāsas specifikācijā ir jābūt kvadrātiekavām pēc stāvokļa, piem., " -"gtk:fg[NORMAL], kur NORMAL ir stāvoklis; neizdevās parsēt \"%s\"" +"Another compositing manager is already running on screen %i on display “%s”." +msgstr "Cits kompozīcijas pārvaldnieks jau darbojas ekrānā %d displejā “%s”." -#: ../src/ui/theme.c:1319 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "Nesaprotams stāvoklis \"%s\" krāsas specifikācijā" - -#: ../src/ui/theme.c:1332 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "Nesaprotams krāsas komponents \"%s\" krāsas specifikācijā" +#: src/core/bell.c:192 +msgid "Bell event" +msgstr "Zvana notikums" -#: ../src/ui/theme.c:1361 -#, c-format -msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" -msgstr "" -"Saplūšanas formāts ir \"blend/bg_color/fg_color/alpha\", \"%s\" neatbilst " -"formātam" +#: src/core/main.c:185 +msgid "Disable connection to session manager" +msgstr "Deaktivēt savienojumu ar sesiju pārvaldnieku" -#: ../src/ui/theme.c:1372 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "Neizdevās parsēt alfa vērtību \"%s\" sapludinātajā krāsā" +#: src/core/main.c:191 +msgid "Replace the running window manager" +msgstr "Aizvietot darbojošos logu pārvaldnieku" -#: ../src/ui/theme.c:1382 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "Alfa vērtība \"%s\" sapludinātajā krāsā nav starp 0.0 un 1.0" +#: src/core/main.c:197 +msgid "Specify session management ID" +msgstr "Norādiet sesiju pārvaldības ID" -#: ../src/ui/theme.c:1429 -#, c-format -msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "" -"Ēnošanas formāts ir \"shade/base_color/factor\", \"%s\" neatbilst formātam" +#: src/core/main.c:202 +msgid "X Display to use" +msgstr "Lietojamais X displejs" -#: ../src/ui/theme.c:1440 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "Neizdevās parsēt ēnas faktoru \"%s\" ēnotajā krāsā" +#: src/core/main.c:208 +msgid "Initialize session from savefile" +msgstr "Inicializēt sesiju no saglabātās datnes" -#: ../src/ui/theme.c:1450 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "Ēnošanas faktors \"%s\" ēnotajā krāsā ir negatīvs" +#: src/core/main.c:214 +msgid "Make X calls synchronous" +msgstr "Padarīt X izsaukumus sinhronus" -#: ../src/ui/theme.c:1479 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Neizdevās parsēt krāsu \"%s\"" +#: src/core/main.c:221 +msgid "Run as a wayland compositor" +msgstr "Palaist kā wayland kompozitoru" -#: ../src/ui/theme.c:1790 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "Koordinātu izteiksme satur rakstzīmi '%s', kas nav atļauta" +#: src/core/main.c:227 +msgid "Run as a nested compositor" +msgstr "Palaist kā ligzdotu kompozitoru" -#: ../src/ui/theme.c:1817 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "Koordinātu izteiksme satur neparsējamu peldošā punkta skaitli '%s'" +#: src/core/main.c:233 +msgid "Run wayland compositor without starting Xwayland" +msgstr "Palaist wayland kompozitoru nestartējot Xwayland" -#: ../src/ui/theme.c:1831 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "Koordinātu izteiksme satur neparsējamu veselu skaitli '%s'" +#: src/core/main.c:241 +msgid "Run as a full display server, rather than nested" +msgstr "Palaist kā pilnu attēlošanas serveri, nevis iegultu" -#: ../src/ui/theme.c:1953 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "Koordinātu izteiksme satur nezināmu operatoru šī teksta sākumā: \"%s\"" +#: src/core/main.c:247 +msgid "Run with X11 backend" +msgstr "Palaist ar X11 aizmuguri" -#: ../src/ui/theme.c:2010 +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:151 #, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "Koordinātu izteiksme bija tukša vai nesaprasta" +msgid "“%s” is not responding." +msgstr "“%s” nereaģē." -#: ../src/ui/theme.c:2121 ../src/ui/theme.c:2131 ../src/ui/theme.c:2165 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "Koordinātu izteiksme noved pie dalīšanas ar nulli" +#: src/core/meta-close-dialog-default.c:153 +msgid "Application is not responding." +msgstr "Lietotne nereaģē." -#: ../src/ui/theme.c:2173 -#, c-format +#: src/core/meta-close-dialog-default.c:158 msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." msgstr "" -"Koordinātu izteiksme mēģina lietot mod operatoru uz peldošā punkta skaitļa" - -#: ../src/ui/theme.c:2229 -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "Koordinātu izteiksmei ir operators \"%s\", kur tika gaidīts operands" +"Var uzgaidīt neilgu brīdi, līdz tā atgūstas, vai arī aizvērt to piespiedu " +"kārtā." -#: ../src/ui/theme.c:2238 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "Koordinātu izteiksmei bija operands, kur tika gaidīts operators" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Force Quit" +msgstr "Aizvērt _piespiedu kārtā" -#: ../src/ui/theme.c:2246 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "Koordinātu izteiksme beidzās ar operatoru, nevis ar operandu" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Wait" +msgstr "_Gaidīt" -#: ../src/ui/theme.c:2256 +#: src/core/mutter.c:38 #, c-format msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" msgstr "" -"Koordinātu izteiksmē ir operatoram \"%c\" sekojošais operators \"%c\" bez " -"operanda to starpā" - -#: ../src/ui/theme.c:2407 ../src/ui/theme.c:2452 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "Koordinātu izteiksmē bija nezināms mainīgais vai konstante \"%s\"" +"mutter %s\n" +"Autortiesības © 2001-%d Havoc Pennington, Red Hat, Inc., un citi\n" +"Šī ir brīvā programmatūra; par kopēšanas nosacījumiem skatīt avotu.\n" +"Netiek dota NEKĀDA garantija; pat ne KOMERCIĀLAS VĒRTĪBAS vai DERĪGUMA " +"NOTEIKTAM NOLŪKAM.\n" -#: ../src/ui/theme.c:2506 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "Koordinātu izteiksme pārpildīja parsera buferi." +#: src/core/mutter.c:52 +msgid "Print version" +msgstr "Parādīt versiju" -#: ../src/ui/theme.c:2535 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "" -"Koordinātu izteiksmei bija aizvērtās iekavas bez nevienas atvērtās iekavas" +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "Izmantojamais mutter spraudnis" -#: ../src/ui/theme.c:2599 +#: src/core/prefs.c:1849 #, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "" -"Koordinātu izteiksmei bija atvērtās iekavas bez nevienas aizvērtās iekavas" +msgid "Workspace %d" +msgstr "Darbvieta %d" -#: ../src/ui/theme.c:2610 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "Šķiet, ka koordinātu izteiksmē nav ne operatoru, ne operandu" +#: src/core/util.c:121 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter tika kompilēts bez detalizētas izvades režīma atbalsta\n" -#: ../src/ui/theme.c:2822 ../src/ui/theme.c:2842 ../src/ui/theme.c:2862 +#: src/wayland/meta-wayland-tablet-pad.c:567 #, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "Tēma saturēja izteiksmi, kas noveda pie kļūdas: %s\n" +msgid "Mode Switch: Mode %d" +msgstr "Režīma slēdzis: režīms %d" -#: ../src/ui/theme.c:4533 +#: src/x11/meta-x11-display.c:671 #, c-format msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." msgstr "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"jebkas\"/> jābūt noteiktam " -"šajā " -"rāmja stilā" +"Displejam “%s” jau ir logu pārvaldnieks; mēģiniet lietot --replace iespēju, " +"lai aizvietotu pašreizējo logu pārvaldnieku." -#: ../src/ui/theme.c:5066 ../src/ui/theme.c:5091 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" -"Iztrūkst <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"jebkas\"/>" +#: src/x11/meta-x11-display.c:1032 +msgid "Failed to initialize GDK\n" +msgstr "Neizdevās inicializēt GDK\n" -#: ../src/ui/theme.c:5139 +#: src/x11/meta-x11-display.c:1056 #, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Neizdevās ielādēt tēmu \"%s\": %s\n" +msgid "Failed to open X Window System display “%s”\n" +msgstr "Neizdevās atvērt X logu sistēmas displeju “%s”\n" -#: ../src/ui/theme.c:5275 ../src/ui/theme.c:5282 ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 ../src/ui/theme.c:5303 +#: src/x11/meta-x11-display.c:1140 #, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "Nav iestatīts <%s> tēmai \"%s\"" +msgid "Screen %d on display “%s” is invalid\n" +msgstr "Ekrāna %d displejs “%s“ nav derīgs\n" -#: ../src/ui/theme.c:5311 +#: src/x11/meta-x11-selection-input-stream.c:445 #, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" -"Nav rāmja stila kopas loga tipam \"%s\" tēmā \"%s\"; pievienojiet <window " -"type=\"" -"%s\" style_set=\"jebkas\"/> elementu" +msgid "Format %s not supported" +msgstr "%s formāts nav atbalstīts" -#: ../src/ui/theme.c:5709 ../src/ui/theme.c:5771 ../src/ui/theme.c:5834 -#, c-format +#: src/x11/session.c:1821 msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." msgstr "" -"Lietotāja definētajām konstantēm jāsākas ar lielo burtu; \"%s\" nesākas" - -#: ../src/ui/theme.c:5717 ../src/ui/theme.c:5779 ../src/ui/theme.c:5842 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "Konstante \"%s\" jau tikusi definēta" - -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. -#. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "Nav \"%s\" atribūta elementam <%s>" - -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Rinda %d rakstzīme %d: %s" +"Šie logi neatbalsta “saglabāt pašreizējos iestatījumus” un būs jāpārstartē " +"pašrocīgi nākamreiz, kad ierakstīsities." -#: ../src/ui/theme-parser.c:479 +#: src/x11/window-props.c:569 #, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "Atribūts \"%s\" atkārtots divreiz vienam <%s> elementam" - -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "Atribūts \"%s\" ir nederīgs <%s> elementam šajā kontekstā" - -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "Neizdevās parsēt \"%s\" kā veselu skaitli" - -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "Nesaprotamas sekojošās rakstzīmes \"%s\" virknē \"%s\"" - -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "Skaitlim %ld jābūt pozitīvam" - -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "Skaitlis %ld ir pārāk liels, pašreizējais maksimums ir %d" - -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "Neizdevās parsēt \"%s\" kā peldošā punkta skaitli" - -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "Vērtībai jābūt \"true\" vai \"false\", nevis \"%s\"" - -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "Leņķim jābūt starp 0.0 un 360.0, bija %g\n" - -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" -"Alfa jābūt starp 0.0 (neredzams) un 1.0 (pilnībā necaurredzams), bija %g\n" - -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"Nederīgs virsraksta mērogs \"%s\" (var būt: xx-" -"small,x-small,small,medium,large,x-large,xx-large)\n" - -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s> vārds \"%s\" lietots otru reizi" - -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "<%s> vecāks \"%s\" nav ticis definēts" - -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "<%s> ģeometrija \"%s\" nav tikusi definēta" - -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "<%s> jānosaka vai nu ģeometrija, vai vecāks, kam ir ģeometrija" - -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "Lai alfa vērtībai būtu jēga, jānorāda fons" - -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Nezināms tips \"%s\" <%s> elementam" - -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "Nezināms style_set \"%s\" <%s> elementam" - -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "Loga tipam \"%s\" jau ir piešķirta stila kopa" - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "Elements <%s> netiek atļauts zem <%s>" - -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" -msgstr "" -"Nevar noteikt gan \"button_width\"/\"button_height\", gan \"aspect_ratio\" " -"pogām" - -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "Attālums \"%s\" ir nezināms" - -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "Samērs \"%s\" ir nezināms" - -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "Robeža \"%s\" ir nezināma" - -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "Nav \"start_angle\" vai \"from\" atribūta elementam <%s>" - -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "Nav \"extent_angle\" vai \"to\" atribūta elementam <%s>" - -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "Nesaprotama krāsu pārejas tipa vērtība \"%s\"" - -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "Nesaprotams aizpildījuma tips \"%s\" <%s> elementam" - -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "Nesaprotams stāvoklis \"%s\" elementam <%s>" - -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "Nesaprotama ēna \"%s\" elementam <%s>" - -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "Nesaprotama bulta \"%s\" elementam <%s>" - -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "Neviens <draw_ops> ar nosaukumu \"%s\" nav ticis definēts" - -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "Iekļaujot šeit draw_ops \"%s\", rastos riņķveida atsauce" - -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Nezināma pozīcija \"%s\" rāmja daļai" - -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "Rāmja stilam jau ir daļa %s pozīcijā" - -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "Neviens <draw_ops> ar nosaukumu \"%s\" nav ticis definēts" - -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Nezināma pogas funkcija \"%s\"" - -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "Pogas funkcija \"%s\" neeksistē šajā versijā (%d, nepieciešama %d)" - -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Nezināms pogas stāvoklis \"%s\"" - -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "Rāmja stilam jau ir poga funkcijas %s stāvoklim %s" - -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "\"%s\" nav derīga vērtība fokusa atribūtam" - -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "\"%s\" nav derīga vērtība stāvokļa atribūtam" - -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "Stils \"%s\" nav ticis definēts" - -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "\"%s\" nav derīga vērtība izmēra maiņas atribūtam" - -#: ../src/ui/theme-parser.c:3147 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" -"Elementam <%s> nevajadzētu būt \"resize\" atribūtam maksimizētos/ēnotos " -"stāvokļos" - -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "" -"Elementam <%s> nevajadzētu būt \"resize\" atribūtam maksimizētajos stāvokļos" - -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "Stils jau ir ticis noteikts stāvokļa %s izmēra maiņas %s fokusam %s" - -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "Stils jau ir ticis noteikts stāvokļa %s fokusam %s" - -#: ../src/ui/theme-parser.c:3294 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Nevar būt divi draw_ops <piece> elementam (tēma noteica draw_ops atribūtu un " -"arī <draw_ops> elementu, vai noteica divus elementus)" - -#: ../src/ui/theme-parser.c:3332 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Nevar būt divi draw_ops <button> elementam (tēma noteica draw_ops atribūtu " -"un arī <draw_ops> elementu, vai noteica divus elementus)" - -#: ../src/ui/theme-parser.c:3370 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Nevar būt divi draw_ops <menu_icon> elementam (tēma noteica draw_ops " -"atribūtu un arī <draw_ops> elementu, vai noteica divus elementus)" - -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "Slikta versijas specifikācija '%s'" - -#: ../src/ui/theme-parser.c:3507 -msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" -msgstr "" -"\"version\" atribūtu nevar izmantot iekš metacity-theme-1.xml vai metacity-" -"theme-2.xml" - -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "" -"Šai tēmai ir nepieciešama versija %s, bet jaunākā atbalstītā tēmas versija " -"ir %d.%d" - -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "Ārējam tēmas elementam jābūt <metacity_theme>, nevis <%s>" - -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "Elements <%s> netiek atļauts elementā name/author/date/description" - -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "Elements <%s> netiek atļauts elementā <constant>" - -#: ../src/ui/theme-parser.c:3599 -#, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "Elements <%s> netiek atļauts distance/border/aspect_ratio elementā" - -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "Elements <%s> netiek atļauts zīmēšanas operāciju elementā" - -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "Elements <%s> netiek atļauts elementā <%s>" - -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "Nav dots draw_ops rāmja daļai" - -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "Nav dots draw_ops pogai" - -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "Teksts nav atļauts elementā <%s>" - -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "<%s> šai tēmai noteikts divreiz" - -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Neizdevās atrast derīgu faila nosaukumu tēmai %s\n" - -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "_Windows" - -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "_Dialoglodziņš" - -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "_Modālais dialogs" - -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "_Utilīta" - -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "Uzplaik_snījuma ekrāns" - -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "Au_gšējais doks" - -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "Apakšējais _doks" - -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "_Kreisais doks" - -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "La_bais doks" - -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "_Visi doki" - -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "Darbvi_rsma" - -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "Atvērt vēlvienu no šiem logiem" - -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "Šī ir demo poga ar 'atvērt' ikonu" - -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "Šī ir demo poga ar 'aizvērt' ikonu" - -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "Šis ir paraugpaziņojums parauga dialogā" - -#: ../src/ui/theme-viewer.c:328 -#, c-format -msgid "Fake menu item %d\n" -msgstr "Neīsts izvēlnes elements %d\n" - -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "Logs tikai ar apmali" - -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "Josla" - -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "Normāls lietotnes logs" - -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "Dialoglodziņš" - -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "Modālais dialoglodziņš" - -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "Utilītpalete" - -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "Atrauta izvēlne" - -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "Apmale" - -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "Piesaistītais modālais dialogs" - -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "Pogu izkārtojuma tests %d" - -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g milisekundes, lai uzzīmētu loga rāmi" - -#: ../src/ui/theme-viewer.c:813 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Pielietojums: metacity-theme-viewer [TĒMASNOSAUKUMS]\n" - -#: ../src/ui/theme-viewer.c:820 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "Kļūda, ielādējot tēmu: %s\n" - -#: ../src/ui/theme-viewer.c:826 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "Tēma \"%s\" ielādēta \"%g\"sekundēs\n" - -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "Normāls virsraksta fonts" - -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "Mazs virsraksta fonts" - -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "Liels virsraksta fonts" - -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "Pogu izkārtojumi" - -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "Etalonuzdevums" - -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "Šeit paredzēts loga virsraksts" - -#: ../src/ui/theme-viewer.c:1047 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"Uzzīmēju %d kadrus %g klienta puses sekundēs (%g milisekundes uz kadru) un %" -"g sekundēs pēc ierastā laika, ieskaitot X servera resursus (%g milisekundes " -"uz kadru)\n" - -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "pozīcijas izteiksmes tests atgrieza TRUE, bet ziņoja par kļūdu" - -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "pozīcijas izteiksmes tests atgrieza FALSE, bet nenorādīja kļūdu" - -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "Tika gaidīta kļūda, taču tā netika dota" - -#: ../src/ui/theme-viewer.c:1274 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "Tika gaidīta kļūda %d, bet saņemta kļūda %d" - -#: ../src/ui/theme-viewer.c:1280 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "Kļūda netika gaidīta, taču tika saņemta: %s" - -#: ../src/ui/theme-viewer.c:1284 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "x vērtība bija %d, tika gaidīta %d" - -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "y vērtība bija %d, tika gaidīta %d" - -#: ../src/ui/theme-viewer.c:1352 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "%d koordinātas izteiksme noparsēta %g sekundēs (vidēji %g sekundēs)\n" - -#~ msgid "Switch to workspace 1" -#~ msgstr "Pārslēgties uz 1. darbvietu" - -#~ msgid "Switch to workspace 2" -#~ msgstr "Pārslēgties uz 2. darbvietu" - -#~ msgid "Switch to workspace 3" -#~ msgstr "Pārslēgties uz 3. darbvietu" - -#~ msgid "Switch to workspace 4" -#~ msgstr "Pārslēgties uz 4. darbvietu" - -#~ msgid "Switch to workspace 5" -#~ msgstr "Pārslēgties uz 5. darbvietu" - -#~ msgid "Switch to workspace 6" -#~ msgstr "Pārslēgties uz 6. darbvietu" - -#~ msgid "Switch to workspace 7" -#~ msgstr "Pārslēgties uz 7. darbvietu" - -#~ msgid "Switch to workspace 8" -#~ msgstr "Pārslēgties uz 8. darbvietu" - -#~ msgid "Switch to workspace 9" -#~ msgstr "Pārslēgties uz 9. darbvietu" - -#~ msgid "Switch to workspace 10" -#~ msgstr "Pārslēgties uz 10. darbvietu" - -#~ msgid "Switch to workspace 11" -#~ msgstr "Pārslēgties uz 11. darbvietu" - -#~ msgid "Switch to workspace 12" -#~ msgstr "Pārslēgties uz 12. darbvietu" - -#~ msgid "Switch to workspace on the left of the current workspace" -#~ msgstr "Pārslēgties uz darba vietu pa kreisi no pašreizējās" - -#~ msgid "Switch to workspace on the right of the current workspace" -#~ msgstr "Pārslēgties uz darba vietu pa labi no pašreizējās" - -#~ msgid "Switch to workspace above the current workspace" -#~ msgstr "Pārslēgties uz darba vietu virs pašreizējās" - -#~ msgid "Switch to workspace below the current workspace" -#~ msgstr "Pārslēgties uz darba vietu zem pašreizējās" - -#~ msgid "Move between windows of an application, using a popup window" -#~ msgstr "Pārvietoties starp lietotnes logiem, lietojot izlecošo logu" - -#~ msgid "" -#~ "Move backward between windows of an application, using a popup window" -#~ msgstr "Pārvietoties atpakaļ starp lietotnes logiem, lietojot izlecošo logu" - -#~ msgid "Move between windows, using a popup window" -#~ msgstr "Pārvietoties starp logiem, lietojot izlecošo logu" - -#~ msgid "Move backward between windows, using a popup window" -#~ msgstr "Pārvietoties atpakaļ starp logiem, lietojot izlecošo logu" - -#~ msgid "Move between panels and the desktop, using a popup window" -#~ msgstr "Pārvietoties starp paneļiem un darbvirsmu, lietojot izlecošo logu" - -#~ msgid "Move backward between panels and the desktop, using a popup window" -#~ msgstr "" -#~ "Pārvietoties atpakaļ starp paneļiem un darbvirsmu, lietojot izlecošo logu" - -#~ msgid "Move between windows of an application immediately" -#~ msgstr "Nekavējoties pārvietoties starp lietotņu logiem" - -#~ msgid "Move backward between windows of an application immediately" -#~ msgstr "Nekavējoties pārvietoties atpakaļ starp lietotņu logiem" - -#~ msgid "Move between windows immediately" -#~ msgstr "Pārvietoties starp logiem nekavējoties" - -#~ msgid "Move backward between windows immediately" -#~ msgstr "Nekavējoties pārvietoties atpakaļ starp logiem" - -#~ msgid "Move between panels and the desktop immediately" -#~ msgstr "Nekavējoties pārvietoties starp paneļiem un darbvirsmu" - -#~ msgid "Move backward between panels and the desktop immediately" -#~ msgstr "Nekavējoties pārvietoties atpakaļ starp paneļiem un darbvirsmu" - -#~ msgid "Hide all normal windows and set focus to the desktop" -#~ msgstr "Paslēpt visus logus un fokusēties uz darbvirsmu" - -#~ msgid "Show the panel's main menu" -#~ msgstr "Parāda paneļa galveno izvēlni" - -#~ msgid "Show the panel's \"Run Application\" dialog box" -#~ msgstr "Parāda paneļa \"Palaist lietotni\" logu" - -#~ msgid "Start or stop recording the session" -#~ msgstr "Sākt vai apturēt sesijas ierakstīšanu" - -#~ msgid "Take a screenshot" -#~ msgstr "Uzņemt ekrānattēlu" - -#~ msgid "Take a screenshot of a window" -#~ msgstr "Uzņemt loga ekrānattēlu" - -#~ msgid "Run a terminal" -#~ msgstr "Palaist termināli" - -#~ msgid "Activate the window menu" -#~ msgstr "Aktivizēt loga izvēlni" - -#~ msgid "Toggle fullscreen mode" -#~ msgstr "Pārslēgt pilnekrāna režīmu" - -#~ msgid "Toggle maximization state" -#~ msgstr "Pārslēgt maksimizācijas stāvokli" - -#~ msgid "Toggle whether a window will always be visible over other windows" -#~ msgstr "Pārslēdz to, vai logs vienmēr redzams virs citiem logiem" - -#~ msgid "Maximize window" -#~ msgstr "Maksimizēt logu" - -#~ msgid "Restore window" -#~ msgstr "Atjaunot logu" - -#~ msgid "Toggle shaded state" -#~ msgstr "Pārslēgt ēnoto stāvokli" - -#~ msgid "Minimize window" -#~ msgstr "Minimizēt logu" - -#~ msgid "Close window" -#~ msgstr "Aizvērt logu" - -#~ msgid "Move window" -#~ msgstr "Pārvietot logu" - -#~ msgid "Resize window" -#~ msgstr "Mainīt loga izmēru" - -#~ msgid "Toggle whether window is on all workspaces or just one" -#~ msgstr "Pārslēgt, vai logs ir redzams visās darbvirsmās vai tikai vienā" - -#~ msgid "Move window to workspace 1" -#~ msgstr "Pārvietot logu uz 1. darbvietu" - -#~ msgid "Move window to workspace 2" -#~ msgstr "Pārvietot logu uz 2. darbvietu" - -#~ msgid "Move window to workspace 3" -#~ msgstr "Pārvietot logu uz 3. darbvietu" - -#~ msgid "Move window to workspace 4" -#~ msgstr "Pārvietot logu uz 4. darbvietu" - -#~ msgid "Move window to workspace 5" -#~ msgstr "Pārvietot logu uz 5. darbvietu" - -#~ msgid "Move window to workspace 6" -#~ msgstr "Pārvietot logu uz 6. darbvietu" - -#~ msgid "Move window to workspace 7" -#~ msgstr "Pārvietot logu uz 7. darbvietu" - -#~ msgid "Move window to workspace 8" -#~ msgstr "Pārvietot logu uz 8. darbvietu" - -#~ msgid "Move window to workspace 9" -#~ msgstr "Pārvietot logu uz 9. darbvietu" - -#~ msgid "Move window to workspace 10" -#~ msgstr "Pārvietot logu uz 10. darbvietu" - -#~ msgid "Move window to workspace 11" -#~ msgstr "Pārvietot logu uz 11. darbvietu" - -#~ msgid "Move window to workspace 12" -#~ msgstr "Pārvietot logu uz 12. darbvietu" - -#~ msgid "Move window one workspace to the left" -#~ msgstr "Pārvietot logu vienu darbvietu pa kreisi" - -#~ msgid "Move window one workspace to the right" -#~ msgstr "Pārvietot logu vienu darbvietu pa labi" - -#~ msgid "Move window one workspace up" -#~ msgstr "Pārvietot logu vienu darbvietu augšup" - -#~ msgid "Move window one workspace down" -#~ msgstr "Pārvietot logu vienu darbvietu lejup" - -#~ msgid "Raise window if it's covered by another window, otherwise lower it" -#~ msgstr "Pacelt logu, ja to aizsedz kāds cits, citādi pazemināt" - -#~ msgid "Raise window above other windows" -#~ msgstr "Pacelt logu virs citiem logiem" - -#~ msgid "Lower window below other windows" -#~ msgstr "Pazemināt logu zem citiem logiem" - -#~ msgid "Maximize window vertically" -#~ msgstr "Maksimizēt logu vertikāli" - -#~ msgid "Maximize window horizontally" -#~ msgstr "Maksimizēt logu horizontāli" - -#~ msgid "Move window to north-west (top left) corner" -#~ msgstr "Pārvietot logu uz ekrāna ziemeļrietumu (augšējo kreiso) stūri" - -#~ msgid "Move window to north-east (top right) corner" -#~ msgstr "Pārvietot logu uz ekrāna ziemeļaustrumu (augšējo labo) stūri" - -#~ msgid "Move window to south-west (bottom left) corner" -#~ msgstr "Pārvietot logu uz ekrāna dienvidrietumu (apakšējo kreiso) stūri" - -#~ msgid "Move window to south-east (bottom right) corner" -#~ msgstr "Pārvietot logu uz ekrāna dienvidaustrumu (apakšējo labo) stūri" - -#~ msgid "Move window to north (top) side of screen" -#~ msgstr "Pārvietot logu uz ekrāna ziemeļu (augšējo) malu" - -#~ msgid "Move window to south (bottom) side of screen" -#~ msgstr "Pārvietot logu uz ekrāna dienvidu (apakšējo) malu" - -#~ msgid "Move window to east (right) side of screen" -#~ msgstr "Pārvietot logu uz ekrāna austrumu (labo) malu" - -#~ msgid "Move window to west (left) side of screen" -#~ msgstr "Pārvietot logu uz ekrāna rietumu (kreiso) malu" - -#~ msgid "Move window to center of screen" -#~ msgstr "Pārvietot logu uz ekrāna centru" - -#~ msgid "" -#~ "There was an error running <tt>%s</tt>:\n" -#~ "\n" -#~ "%s" -#~ msgstr "" -#~ "Kļūda, darbinot <tt>%s</tt>:\n" -#~ "\n" -#~ "%s" - -#~ msgid "No command %d has been defined.\n" -#~ msgstr "Komanda %d nav definēta.\n" - -#~ msgid "No terminal command has been defined.\n" -#~ msgstr "Termināla komandas nav definētas.\n" - -#~ msgid "GConf key '%s' is set to an invalid value\n" -#~ msgstr "GConf atslēga '%s' ir iestatīta uz nederīgu vērtību\n" - -#~ msgid "%d stored in GConf key %s is out of range %d to %d\n" -#~ msgstr "%d, kas saglabāts GConf atslēgā %s, ir ārpus %d līdz %d diapazona\n" - -#~ msgid "GConf key \"%s\" is set to an invalid type\n" -#~ msgstr "GConf atslēga \"%s\" ir iestatīta uz nederīgu tipu\n" - -#~ msgid "GConf key %s is already in use and can't be used to override %s\n" -#~ msgstr "GConf atslēga \"%s\" jau tiek izmantota un to nevar izmantot, lai pārrakstītu " -#~ "%s\n" - -#~ msgid "Can't override GConf key, %s not found\n" -#~ msgstr "Nevar pārrakstīt GConf atslēgu, %s nav atrasts\n" - -#~ msgid "Error setting number of workspaces to %d: %s\n" -#~ msgstr "Kļūda, iestatot darbvietu daudzumu uz %d: %s\n" - -#~ msgid "Error setting name for workspace %d to \"%s\": %s\n" -#~ msgstr "Kļūda, iestatot darbvietas %d nosaukumu uz \"%s\": %s\n" +msgid "%s (on %s)" +msgstr "%s (uz %s)" -#~ msgid "Error setting live hidden windows status status: %s\n" -#~ msgstr "Kļūda, iestatot dzīvo slēptā loga statusu: %s\n" - -#~ msgid "Error setting no tab popup status: %s\n" -#~ msgstr "Kļūda, iestatot bez ciļņu uzvednes statusu: %s\n" - -#~ msgid "Window Management" -#~ msgstr "Logu pārvaldība" - -#~ msgid "Failed to parse message \"%s\" from dialog process\n" -#~ msgstr "Neizdevās parsēt ziņu \"%s\" no dialoga procesa\n" - -#~ msgid "Error reading from dialog display process: %s\n" -#~ msgstr "Kļūda lasot no dialoga displeja procesa: %s\n" - -#~ msgid "" -#~ "Error launching metacity-dialog to ask about killing an application: %s\n" -#~ msgstr "Kļūda palaižot metacity-dialogu, lai pavaicātu par šīs aplikācijas " -#~ "nokaušanu: %s\n" - -#~ msgid "Failed to get hostname: %s\n" -#~ msgstr "Neizdevās dabūt resursdatora nosaukumu: %s\n" - -#~ msgid "" -#~ "Lost connection to the display '%s';\n" -#~ "most likely the X server was shut down or you killed/destroyed\n" -#~ "the window manager.\n" -#~ msgstr "" -#~ "Zaudēju savienojumu ar displeju '%s';\n" -#~ "ļoti iespējams, X serveris tika izslēgts vai arī jūs apturējāt\n" -#~ "logu pārvaldnieku.\n" - -#~ msgid "Fatal IO error %d (%s) on display '%s'.\n" -#~ msgstr "Fatāla IO kļūda %d (%s) displejā '%s'.\n" - -#~ msgid "Turn compositing on" -#~ msgstr "Ieslēgt kompozicionēšanu" - -#~ msgid "Turn compositing off" -#~ msgstr "Izslēgt kompozicionēšanu" - -#~ msgid "Failed to restart: %s\n" -#~ msgstr "Nevarēju pārstartēt: %s\n" - -#~ msgid "" -#~ "The format looks like \"<Control>a\" or <Shift><Alt>F1\".\n" -#~ "\n" -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Formāts izskatās kā \"<Control>a\" vai \"<Shift><Alt>F1\".\n" -#~ "\n" -#~ "Sadalīšana ir diezgan liberāla un pieļauj lielos un mazos burtus, arī " -#~ "saīsinājumus, tādus kā \"<Ctl>\" un \"<Ctrl>\". Ja jūs iestatīsit iespēju uz " -#~ "speciālo rindiņu \"disabled\", tad šeit nebūs taustiņsasaistes šai darbībai." - -#~ msgid "" -#~ "The format looks like \"<Control>a\" or <Shift><Alt>F1\".\n" -#~ "\n" -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action.\n" -#~ "\n" -#~ "This keybinding may be reversed by holding down the \"shift\" key; " -#~ "therefore, \"shift\" cannot be one of the keys it uses." -#~ msgstr "" -#~ "Formāts izskatās kā \"<Control>a\" vai \"<Shift><Alt>F1\".\n" -#~ "\n" -#~ "Sadalīšana ir diezgan liberāla un pieļauj lielos un mazos burtus, arī " -#~ "saīsinājumus, tādus kā \"<Ctl>\" un \"<Ctrl>\". Ja jūs iestatīsit iespēju uz " -#~ "speciālo rindiņu \"disabled\", tad šeit nebūs taustiņsasaistes šai darbībai.\n" -#~ "\n" -#~ "Taustiņsaiti var rezervēt turot nospiestu \"shift\" taustiņu, tāpēc \"shift\" " -#~ "taustiņu nevar piesaistīt nevienā taustiņu kombinācijā." - -#~ msgid "Failed to read saved session file %s: %s\n" -#~ msgstr "Nevarēja nolasīt saglabāto sesijas failu %s: %s\n" - -#~ msgid "" -#~ "Error launching metacity-dialog to warn about apps that don't support " -#~ "session management: %s\n" -#~ msgstr "Kļūda palaižot metacity-dialogu, lai paziņotu par aplikācijām, kas " -#~ "neatbalsta sesijas pārvaldīšanu: %s\n" - -#~ msgid "Metacity" -#~ msgstr "Metacity" - -#~ msgid "" -#~ "(Not implemented) Navigation works in terms of applications not windows" -#~ msgstr "" -#~ "(Nav iestrādāts) Navigācija darbojas vairāk pēc aplikāciju, nekā logu " -#~ "nosacījumiem" - -#~ msgid "" -#~ "A font description string describing a font for window titlebars. The " -#~ "size from the description will only be used if the titlebar_font_size " -#~ "option is set to 0. Also, this option is disabled if the " -#~ "titlebar_uses_desktop_font option is set to true." -#~ msgstr "" -#~ "Fonta apraksta virkne, kas apraksta fontu logu nosaukumjoslās. Izmērs no " -#~ "apraksta tiks lietots, ja titlebar_font_size vērtība ir iestādīta uz 0. " -#~ "Tāpat arī šī vērtība tiek deaktivizēta, ja titlebar_uses_desktop_font " -#~ "vērtība ir iestādīta kā patiesa." - -#~ msgid "Action on title bar double-click" -#~ msgstr "Darbība uz virsrakstjoslas dubultklikšķa" - -#~ msgid "Action on title bar middle-click" -#~ msgstr "Vidējā taustiņa kliksķa darbība uz virsrakstjoslas" - -#~ msgid "Action on title bar right-click" -#~ msgstr "Labā taustiņa kliksķa darbība uz virsrakstjoslas" - -#~ msgid "Arrangement of buttons on the titlebar" -#~ msgstr "Pogu kārtība virsrakstjoslā" - -#~ msgid "" -#~ "Arrangement of buttons on the titlebar. The value should be a string, " -#~ "such as \"menu:minimize,maximize,spacer,close\"; the colon separates the " -#~ "left corner of the window from the right corner, and the button names are " -#~ "comma-separated. Duplicate buttons are not allowed. Unknown button names " -#~ "are silently ignored so that buttons can be added in future metacity " -#~ "versions without breaking older versions. A special spacer tag can be " -#~ "used to insert some space between two adjacent buttons." -#~ msgstr "" -#~ "Pogu kārtība virsrakstjoslā. Vērtībai jābūt virknei, tādai kā " -#~ "\"menu:minimize,maximize,close\"; kols atdala kreiso loga stūri no labā stūra " -#~ "un pogu nosaukumi ir komatu atdalīti. Dublētas pogas netiek pieļautas. " -#~ "Nezināmi pogu nosaukumi tiek klusi ignorēti, tādējādi pogas var tikt " -#~ "pievienotas turpmākās metacity versijās, nesabojājot vecākas versijas. " -#~ "Speciālas atstarpju birkas var izmantot, lai ievietotu atstarpes starp " -#~ "blakus esošām pogām." - -#~ msgid "Automatically raises the focused window" -#~ msgstr "Automātiski pacelt fokusēto logu" - -#~ msgid "" -#~ "Clicking a window while holding down this modifier key will move the " -#~ "window (left click), resize the window (middle click), or show the window " -#~ "menu (right click). Modifier is expressed as \"<Alt>\" or \"<" -#~ "Super>\" for example." -#~ msgstr "" -#~ "Klikšķinot uz loga, turot nospiestu šo modifikatoru, pārvietos logu " -#~ "(kreisais klikšķis), mainīs loga izmēru (vidējais klikšķis) vai parādīs loga " -#~ "izvēlni (labais klikšķis). Modifikātors tieks izteikts, piemēram, kā " -#~ "\"<Alt>\" vai \"<Super>\"." - -#~ msgid "Commands to run in response to keybindings" -#~ msgstr "Komandas, kuras palaist kā atbildes uz taustiņsasaistēm" - -#~ msgid "Compositing Manager" -#~ msgstr "Kompozīcijas menedžeris" - -#~ msgid "Control how new windows get focus" -#~ msgstr "Kontrole pār to kā logi iegūst fokusu" - -#~ msgid "Current theme" -#~ msgstr "Pašreizējā tēma" - -#~ msgid "Delay in milliseconds for the auto raise option" -#~ msgstr "Aizture milisekundēs automātiskās pacelšanas vērtībai" - -#~ msgid "Determines whether Metacity is a compositing manager." -#~ msgstr "Nosaka vai Metacity ir jaukts pārvaldnieks." - -#~ msgid "" -#~ "Determines whether applications or the system can generate audible " -#~ "'beeps'; may be used in conjunction with 'visual bell' to allow silent " -#~ "'beeps'." -#~ msgstr "" -#~ "Nosaka vai programmas un sistēma var ģenerēt dzirdamus 'pīkstienus'; var " -#~ "tikt lietota kopā ar 'vizuālo zvanu' lai atļautu klusos 'zvanus'." - -#~ msgid "Disable misfeatures that are required by old or broken applications" -#~ msgstr "" -#~ "Deaktivizēt nepilnības, kas nepieciešamas vecām vai sabojātām aplikācijām" - -#~ msgid "Enable Visual Bell" -#~ msgstr "Aktivizēt vizuālo zvanu" - -#~ msgid "" -#~ "If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " -#~ "the focused window will be automatically raised after a delay specified " -#~ "by the auto_raise_delay key. This is not related to clicking on a window " -#~ "to raise it, nor to entering a window during drag-and-drop." -#~ msgstr "" -#~ "Ja patiess un fokusēšanas režīms ir vai nu \"paviršs\" vai \"pele\", tad " -#~ "fokusetais logs tiks automātiski aktivizēts pēc aiztures (aizture tiek " -#~ "noteikta ar auto_raise_delay taustiņu). Tas nebūs saistīts ar loga " -#~ "aktivizēšanu pēc tam, kad uz to tiek uzklikšķināts vai arī ja tajā tiek kaut " -#~ "kas ievilkts." - -#~ msgid "" -#~ "If true, ignore the titlebar_font option, and use the standard " -#~ "application font for window titles." -#~ msgstr "" -#~ "Ja patiess, ignorēt titlebar_font iespēju un lietot standarta aplikāciju " -#~ "fontus logu nosaukumiem." - -#~ msgid "" -#~ "If true, metacity will give the user less feedback by using wireframes, " -#~ "avoiding animations, or other means. This is a significant reduction in " -#~ "usability for many users, but may allow legacy applications to continue " -#~ "working, and may also be a useful tradeoff for terminal servers. However, " -#~ "the wireframe feature is disabled when accessibility is on." -#~ msgstr "" -#~ "Ja šī vēŗtība ir atzīmēta, metacity sniegs lietotājam mazāku atbalstu " -#~ "izmantojot vadrāmjus, izvairoties no animācijām vai kā savādāk. Tas ir " -#~ "ievērojams lietojamības līmeņa zaudējums, taču ļauj veiksmīgi darboties arī " -#~ "vecākām programmu versijām. Šī iespēja varētu noderēt terminālserveru " -#~ "risinājumos, taču, ja ir aktivizētas pieejamības funkcijas vadrāmji " -#~ "nedarbojas." - -#~ msgid "" -#~ "If true, then Metacity works in terms of applications rather than " -#~ "windows. The concept is a bit abstract, but in general an application-" -#~ "based setup is more like the Mac and less like Windows. When you focus a " -#~ "window in application-based mode, all the windows in the application will " -#~ "be raised. Also, in application-based mode, focus clicks are not passed " -#~ "through to windows in other applications. Application-based mode is, " -#~ "however, largely unimplemented at the moment." -#~ msgstr "" -#~ "Ja patiess, tad Metacity darbojas vairāk pēc aplikāciju, nekā logu " -#~ "nosacījumiem. Koncepcija ir nedaudz apstrakta, taču kopumā " -#~ "aplikācijām-bāzēts iestatījums ir vairāk līdzinās Mac nekā Windows. Kad jūs " -#~ "fokusējat logu aplikācijām-bāzētajā režīmā, visi logi aplikacijā tiks " -#~ "aktivizēti. Tāpat arī aplikācijām-bāzētajā režīmā fokusēšanas klikšķi netiek " -#~ "laisti caur logiem citās aplikācijās. Šī iestatījuma eksistence ir diezgan " -#~ "apšaubāma. Bet šādi ir labāk, nekā iestatījumi visām specifiskajām detaļām " -#~ "attiecībās starp aplikācijām-bāzētajiem un logiem-bāzētajiem režīmiem, " -#~ "piem., vai caurlaist klikšķus. Tāpat arī aplikācijām-bāzētais režīms ir " -#~ "diezgan neizstrādāta uz doto brīdi." - -#~ msgid "If true, trade off usability for less resource usage" -#~ msgstr "" -#~ "Ja šis elements ir atsīmēts, lietojamība tiks iemainīta pret mazāku resursu " -#~ "izmantojumu" - -#~ msgid "Name of workspace" -#~ msgstr "Darba vietas nosaukums" - -#~ msgid "Number of workspaces" -#~ msgstr "Darba vietu skaits" - -#~ msgid "" -#~ "Number of workspaces. Must be more than zero, and has a fixed maximum to " -#~ "prevent making the desktop unusable by accidentally asking for too many " -#~ "workspaces." -#~ msgstr "" -#~ "Darba vietu skaits. Jābūt lielākam par nulli un ir fiksēts maksimums (lai " -#~ "nejauši neizpostītu jūsu darba virsmu, pieprasot 34 milionus darba vietu)." - -#~ msgid "Run a defined command" -#~ msgstr "Palaist definēto komandu" - -#~ msgid "" -#~ "Some applications disregard specifications in ways that result in window " -#~ "manager misfeatures. This option puts Metacity in a rigorously correct " -#~ "mode, which gives a more consistent user interface, provided one does not " -#~ "need to run any misbehaving applications." -#~ msgstr "" -#~ "Dažas programmas neievēro specifikācijas, kas noved pie logu pārvaldnieka " -#~ "kļūmēm. Šī vērtība aktivizē metacity aktīvās koriģēšanas režīmu, kas ļauj " -#~ "iegūt daudz saskangāku lietotāja saskarni, pieņemot, ka jums nav vajadzīgas " -#~ "nepaklausīgās programmas." - -#~ msgid "System Bell is Audible" -#~ msgstr "Sistēmas zvans ir dzirdams" - -#~ msgid "" -#~ "Tells Metacity how to implement the visual indication that the system " -#~ "bell or another application 'bell' indicator has been rung. Currently " -#~ "there are two valid values, \"fullscreen\", which causes a fullscreen " -#~ "white-black flash, and \"frame_flash\" which causes the titlebar of the " -#~ "application which sent the bell signal to flash. If the application which " -#~ "sent the bell is unknown (as is usually the case for the default \"system " -#~ "beep\"), the currently focused window's titlebar is flashed." -#~ msgstr "" -#~ "Nosaka kā Metacity vajadzētu implementēt vizuālo indikāciku, ka sistēmas " -#~ "zvans vai citas programmas 'zvana' indikators ir darbojies. Šobrīd ir divas " -#~ "derīgas vērtības, \"fullscreen\", kas izraisa zipsni pa visu ekrānu un " -#~ "\"frame_flash\", kas liek iezipznīties izsaucošās programmas virsraksta " -#~ "joslai. Ja nav zināma programma, kas ir nosūtījusi zvanu, tad iezipsnīsies " -#~ "aktīvā loga virsraksta josla." - -#~ msgid "" -#~ "The /apps/metacity/global_keybindings/run_command_N keys define " -#~ "keybindings that correspond to these commands. Pressing the keybinding " -#~ "for run_command_N will execute command_N." -#~ msgstr "" -#~ "/apps/metacity/global_keybindings/run_command_N keys definē " -#~ "taustiņsasaistes, kas atbilst šīm komandām. Spiežot taustiņsasaisti priekš " -#~ "run_command_N palaidīs command_N." - -#~ msgid "" -#~ "The /apps/metacity/global_keybindings/run_command_screenshot key defines " -#~ "a keybinding which causes the command specified by this setting to be " -#~ "invoked." -#~ msgstr "" -#~ "/apps/metacity/global_keybindings/run_command_screenshot atslēga definē " -#~ "taustiņsasaistes, kas nospiežot norādīto taustiņu kombināciju izpilda " -#~ "attiecīgo komandu." - -#~ msgid "" -#~ "The /apps/metacity/global_keybindings/run_command_window_screenshot key " -#~ "defines a keybinding which causes the command specified by this setting " -#~ "to be invoked." -#~ msgstr "" -#~ "/apps/metacity/global_keybindings/run_command_window_screenshot atslēga " -#~ "definē taustiņsasaistes, kas nospiežot norādīto taustiņu kombināciju izpilda " -#~ "attiecīgo komandu." - -#~ msgid "" -#~ "The keybinding that runs the correspondingly-numbered command in /apps/" -#~ "metacity/keybinding_commands The format looks like \"<Control>a\" " -#~ "or \"<Shift><Alt>F1\". The parser is fairly liberal and " -#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" -#~ "\" and \"<Ctrl>\". If you set the option to the special string " -#~ "\"disabled\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "Taustiņsasaiste, kas palaiž atbilstoši numurēto komandu no " -#~ "/apps/metacity/keybinding_commands. Formāts izskatās kā \"<Control>a\" " -#~ "vai \"<Shift><Alt>F1. Sadalīšana ir diezgan liberāla un pieļauj " -#~ "lielos un mazos burtus, arī saīsinājumus, tādus kā \"<Ctl>\" un " -#~ "\"<Ctrl>\". Ja jūs iestatīsit iespēju uz speciālo rindiņu \"disabled\", " -#~ "tad šeit nebūs taustiņsasaistes šai darbībai." - -#~ msgid "The name of a workspace." -#~ msgstr "Darba vietas nosaukums." - -#~ msgid "The screenshot command" -#~ msgstr "Ekrānkopijas komanda" - -#~ msgid "" -#~ "The theme determines the appearance of window borders, titlebar, and so " -#~ "forth." -#~ msgstr "Tēma nosaka izskatu loga robežām, nosaukumjoslai un tamlīdzīgi." - -#~ msgid "" -#~ "The time delay before raising a window if auto_raise is set to true. The " -#~ "delay is given in thousandths of a second." -#~ msgstr "" -#~ "Laika aizture pirms loga pacelšanas, ja auto_raise ir iestatīts kā patiess. " -#~ "Aizture tiek izteikta sekundes tūkstošdaļās." - -#~ msgid "" -#~ "The window focus mode indicates how windows are activated. It has three " -#~ "possible values; \"click\" means windows must be clicked in order to " -#~ "focus them, \"sloppy\" means windows are focused when the mouse enters " -#~ "the window, and \"mouse\" means windows are focused when the mouse enters " -#~ "the window and unfocused when the mouse leaves the window." -#~ msgstr "" -#~ "Loga fokusēšanās režīms nosaka, kā logi tiek aktivizēti. Tam ir trīs " -#~ "iespējamās vērtības; \"klikšķis\" nozīmē, ka uz logiem ir jāuzklikšķina, lai " -#~ "tos fokusētu, \"paviršs\" nozīmē , ka logi tiek fokusēti, kad pele slīd tiem " -#~ "pāri, un \"pele\" nozīmē, ka logi tiek fokusēti, kad pele slīd logam pāri, un " -#~ "atfokusēti, kad pele pamet logu." - -#~ msgid "The window screenshot command" -#~ msgstr "Loga ekrānkopijas komanda" - -#~ msgid "" -#~ "This option determines the effects of double-clicking on the title bar. " -#~ "Current valid options are 'toggle_shade', which will shade/unshade the " -#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " -#~ "will maximize/unmaximize the window in that direction only, 'minimize' " -#~ "which will minimize the window, 'shade' which will roll the window up, " -#~ "'menu' which will display the window menu, 'lower' which will put the " -#~ "window behind all the others, and 'none' which will not do anything." -#~ msgstr "" -#~ "Šī vērtība nosaka peles dubultklikšķa efektu uz virsrakstjoslas. Šobrīd " -#~ "derīgas vērtības ir 'toggle_shade', kas ēnos/atēnos logu, un " -#~ "'toggle_maximize_horizontally' un 'toggle_maximize_vertically', kas " -#~ "maksimizēs/atmaksimizēs logu tikai šajā virzienā, 'minimize', kas minimizēs " -#~ "logu, 'shade', kas uzritinās logu augšup, 'menu', kas parādīs loga izvēlni, " -#~ "'lower', kas novietos logu aiz visiem citiem logiem un 'none', kas nedarīs " -#~ "neko." - -#~ msgid "" -#~ "This option determines the effects of middle-clicking on the title bar. " -#~ "Current valid options are 'toggle_shade', which will shade/unshade the " -#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " -#~ "will maximize/unmaximize the window in that direction only, 'minimize' " -#~ "which will minimize the window, 'shade' which will roll the window up, " -#~ "'menu' which will display the window menu, 'lower' which will put the " -#~ "window behind all the others, and 'none' which will not do anything." -#~ msgstr "" -#~ "Šī vērtība nosaka peles vidējā taustiņa klikšķa efektu uz virsrakstjoslas. " -#~ "Šobrīd derīgas vērtības ir 'toggle_shade', kas ēnos/atēnos logu, un " -#~ "'toggle_maximize_horizontally' un 'toggle_maximize_vertically', kas " -#~ "maksimizēs/atmaksimizēs logu tikai šajā virzienā, 'minimize', kas minimizēs " -#~ "logu, 'shade', kas uzritinās logu augšup, 'menu', kas parādīs loga izvēlni, " -#~ "'lower', kas novietos logu aiz visiem citiem logiem un 'none', kas nedarīs " -#~ "neko." - -#~ msgid "" -#~ "This option determines the effects of right-clicking on the title bar. " -#~ "Current valid options are 'toggle_shade', which will shade/unshade the " -#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " -#~ "will maximize/unmaximize the window in that direction only, 'minimize' " -#~ "which will minimize the window, 'shade' which will roll the window up, " -#~ "'menu' which will display the window menu, 'lower' which will put the " -#~ "window behind all the others, and 'none' which will not do anything." -#~ msgstr "" -#~ "Šī vērtība nosaka peles labā taustiņa klikšķa efektu uz virsrakstjoslas. " -#~ "Šobrīd derīgas vērtības ir 'toggle_shade', kas ēnos/atēnos logu, un " -#~ "'toggle_maximize_horizontally' un 'toggle_maximize_vertically', kas " -#~ "maksimizēs/atmaksimizēs logu tikai šajā virzienā, 'minimize', kas minimizēs " -#~ "logu, 'shade', kas uzritinās logu augšup, 'menu', kas parādīs loga izvēlni, " -#~ "'lower', kas novietos logu aiz visiem citiem logiem un 'none', kas nedarīs " -#~ "neko." - -#~ msgid "" -#~ "This option provides additional control over how newly created windows " -#~ "get focus. It has two possible values; \"smart\" applies the user's " -#~ "normal focus mode, and \"strict\" results in windows started from a " -#~ "terminal not being given focus." -#~ msgstr "" -#~ "Šī vērtība nodrošina paildus kontroli pār to, kā jauizveidotie logi tiek " -#~ "aktivizēti. Tai ir divas iespējamas vērtības; \"smart\", izmanto standarta " -#~ "aktivizēšanas iestatījumus un \"strict\", kas nosaka, ka no komandrindas " -#~ "palaistie logi netiks aktivizēti." - -#~ msgid "" -#~ "Turns on a visual indication when an application or the system issues a " -#~ "'bell' or 'beep'; useful for the hard-of-hearing and for use in noisy " -#~ "environments." -#~ msgstr "" -#~ "Ieslēdz programmu vai sistēmas 'zvanu' vai 'pīkstienu' vizuālu indikāciju; " -#~ "noderīga troksņainos un sliktas dzirdamības vidēs." - -#~ msgid "Use standard system font in window titles" -#~ msgstr "Lietot sistēmas standarta fontu logu nosaukumos" - -#~ msgid "Visual Bell Type" -#~ msgstr "Vizuālā zvana tips" - -#~ msgid "Whether raising should be a side-effect of other user interactions" -#~ msgstr "Vai logu aktivizēšanai būtu jābūt kā citu darbību blakusrezultātam" - -#~ msgid "Window focus mode" -#~ msgstr "Logu fokusēšanās režīms" - -#~ msgid "Window title font" -#~ msgstr "Loga nosaukuma fonts" - -#~ msgid "Title" -#~ msgstr "Nosaukums" - -#~ msgid "Class" -#~ msgstr "Klase" - -#~ msgid "" -#~ "There was an error running \"%s\":\n" -#~ "%s." -#~ msgstr "" -#~ "Atgadījās kļūda, darbinot \"%s\":\n" -#~ "%s." - -#~ msgid "<author> specified twice for this theme" -#~ msgstr "<author> šai tēmai noteikts divreiz" - -#~ msgid "<copyright> specified twice for this theme" -#~ msgstr "<copyright> šai tēmai noteikts divreiz" - -#~ msgid "<date> specified twice for this theme" -#~ msgstr "<date> šai tēmai noteikts divreiz" - -#~ msgid "<description> specified twice for this theme" -#~ msgstr "<description> šai tēmai noteikts divreiz" - -#~ msgid "Theme file %s did not contain a root <metacity_theme> element" -#~ msgstr "Tēmas fails %s nesaturēja saknes <metacity_theme> elementu" - -#~ msgid "/Windows/tearoff" -#~ msgstr "/Windows/tearoff" - -#~ msgid "/Windows/_Dialog" -#~ msgstr "/Windows/_Dialog" - -#~ msgid "/Windows/_Modal dialog" -#~ msgstr "/Windows/_Modal dialog" - -#~ msgid "/Windows/Des_ktop" -#~ msgstr "/Windows/Des_ktop" diff --git a/po/mai.po b/po/mai.po index 551b1a235..ce3102e0b 100644 --- a/po/mai.po +++ b/po/mai.po @@ -11,6 +11,7 @@ msgstr "" "PO-Revision-Date: 2009-03-15 16:17+0530\n" "Last-Translator: Sangeeta Kumari <sangeeta09@gmail.com>\n" "Language-Team: Maithili <maithili.sf.net>\n" +"Language: mai\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" diff --git a/po/meson.build b/po/meson.build new file mode 100644 index 000000000..e9b77d79b --- /dev/null +++ b/po/meson.build @@ -0,0 +1 @@ +i18n.gettext(meson.project_name(), preset: 'glib') diff --git a/po/mg.po b/po/mg.po index 0624a5e17..e42797af7 100644 --- a/po/mg.po +++ b/po/mg.po @@ -12,6 +12,7 @@ msgstr "" "PO-Revision-Date: 2006-06-29 22:27+0300\n" "Last-Translator: Fano Rajaonarisoa <rajfanhar@yahoo.fr>\n" "Language-Team: Malagasy <i18n-malagasy-gnome@gna.org>\n" +"Language: mg\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit" diff --git a/po/mk.po b/po/mk.po index 8aa0058d7..9876547cc 100644 --- a/po/mk.po +++ b/po/mk.po @@ -19,6 +19,7 @@ msgstr "" "PO-Revision-Date: 2008-02-03 12:50+0100\n" "Last-Translator: Arangel Angov <ufo@linux.net.mk>\n" "Language-Team: Macedonian <ossm-members@hedona.on.net.mk>\n" +"Language: mk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" diff --git a/po/ml.po b/po/ml.po index 517481ab5..bae3c588b 100644 --- a/po/ml.po +++ b/po/ml.po @@ -1,2640 +1,1654 @@ # translation of metacity.HEAD.ml.po to Malayalam # This file is distributed under the same license as the PACKAGE package. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER. -# # FSF-India <locale@gnu.org.in>, 2003. -# Ani Peter <apeter@redhat.com>, 2006, 2007. +# Ani Peter <apeter@redhat.com>, 2006, 2007, 2013. +# Anish A <aneesh.nl@gmail.com>, 2012. msgid "" msgstr "" "Project-Id-Version: metacity.HEAD.ml\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2007-08-07 03:38+0100\n" -"PO-Revision-Date: 2007-08-30 13:05+0530\n" -"Last-Translator: Ani Peter <apeter@redhat.com>\n" -"Language-Team: Malayalam <en@li.org>\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=mutter&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2013-03-01 15:50+0000\n" +"PO-Revision-Date: 2013-03-26 12:50+0530\n" +"Last-Translator: Ani Peter <peter.ani@gmail.com>\n" +"Language-Team: American English <kde-i18n-doc@kde.org>\n" +"Language: ml\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: KBabel 1.11.4\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -"\n" +"X-Generator: Lokalize 1.5\n" -#: ../src/50-metacity-desktop-key.xml.in.h:1 -msgid "Desktop" -msgstr "ഡസ്ക്ടോപ്പ്" - -#: ../src/50-metacity-key.xml.in.h:1 -msgid "Window Management" -msgstr "ജാലക നിരീക്ഷണം" - -#: ../src/tools/metacity-message.c:150 -#, c-format -msgid "Usage: %s\n" -msgstr "ഉപയോഗം: %s\n" - -#: ../src/tools/metacity-message.c:176 ../src/util.c:133 -msgid "Metacity was compiled without support for verbose mode\n" -msgstr "verbose-നുള്ള പിന്തുണ ഇല്ലാതെയാണ് മെറ്റാ സിറ്റി തയ്യാറാക്കിയത്\n" - -#: ../src/core.c:206 -#, c-format -msgid "Unknown window information request: %d" -msgstr "ജാലകത്തിനുള്ള ആവശ്യം അപരിചിതമായ സ്ഥലത്ത് നിന്നും : %d" - -#: ../src/delete.c:67 ../src/delete.c:94 ../src/metacity-dialog.c:50 -#: ../src/theme-parser.c:484 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "%s നെ ഒരു സംഖ്യയായി വേ‌ര്തിരിക്കാന്‌ കഴിയുഞ്ഞില്ല" - -#: ../src/delete.c:74 ../src/delete.c:101 ../src/metacity-dialog.c:57 -#: ../src/theme-parser.c:493 ../src/theme-parser.c:548 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "" - -#: ../src/delete.c:132 -#, c-format -msgid "Failed to parse message \"%s\" from dialog process\n" -msgstr "രചന %sലെ പ്രമേയം വായിക്കുന്നതില്‌ പരാജയപ്പെട്ടു:\n" - -#: ../src/delete.c:267 -#, c-format -msgid "Error reading from dialog display process: %s\n" -msgstr "%s വായിക്കുന്നതില്‌ പരാജയം : \n" - -#: ../src/delete.c:350 -#, c-format -msgid "Error launching metacity-dialog to ask about killing an application: %s\n" +#: ../src/50-mutter-navigation.xml.in.h:1 +msgid "Navigation" msgstr "" -#: ../src/delete.c:459 -#, c-format -msgid "Failed to get hostname: %s\n" -msgstr "ആതിഥേയനാമം ലഭിക്കുന്നതില്‌ പരാജയപ്പെട്ടു: %s\n" - -#: ../src/display.c:349 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "XWindow തുറക്കുന്നതില്‌ പരാജയം : %s\n" - -#: ../src/errors.c:271 -#, c-format -msgid "" -"Lost connection to the display '%s';\n" -"most likely the X server was shut down or you killed/destroyed\n" -"the window manager.\n" -msgstr "" +#: ../src/50-mutter-navigation.xml.in.h:2 +msgid "Move window to workspace 1" +msgstr "പണിയറ ജാലകം ഒന്നിലേക്ക് നീക്കുക" -#: ../src/errors.c:278 -#, c-format -msgid "Fatal IO error %d (%s) on display '%s'.\n" -msgstr "ഗുരുതരമായ IO പിശക് %d (%s) ('%s' ദൃശ്യത്തില്‍).\n" +#: ../src/50-mutter-navigation.xml.in.h:3 +msgid "Move window to workspace 2" +msgstr "പണിയറ ജാലകം 2ലേക്ക് നീക്കുക" -#: ../src/frames.c:1078 -msgid "Close Window" -msgstr "ജാലകം അടയ്‍ക്കുക" +#: ../src/50-mutter-navigation.xml.in.h:4 +msgid "Move window to workspace 3" +msgstr "പണിയറ ജാലകം 3ലേക്ക് നീക്കുക" -#: ../src/frames.c:1081 -msgid "Window Menu" -msgstr "ജാലക പട്ടിക‌" +#: ../src/50-mutter-navigation.xml.in.h:5 +msgid "Move window to workspace 4" +msgstr "പണിയറ ജാലകം 4ലേക്ക് നീക്കുക" -#: ../src/frames.c:1084 -msgid "Minimize Window" -msgstr "ജാലകം ചെറുതാക്കുക" +#: ../src/50-mutter-navigation.xml.in.h:6 +msgid "Move window one workspace to the left" +msgstr "ഒരു പണിയറ‌‌‌‌‌യ‌്ക്ക് ഇടതുവശത്തേക്ക് ജാലകം നീക്കുക" -#: ../src/frames.c:1087 -msgid "Maximize Window" -msgstr "ജാലകം വലുതാക്കുക" +#: ../src/50-mutter-navigation.xml.in.h:7 +msgid "Move window one workspace to the right" +msgstr "ഒരു പണിയറ‌‌‌‌‌യ‌്ക്ക് വലതുവശത്തേക്ക് ജാലകം നീക്കുക" -#: ../src/frames.c:1090 -msgid "Unmaximize Window" -msgstr "ജാലകം വലുതാക്കിയതൊഴിവാക്കുക" +#: ../src/50-mutter-navigation.xml.in.h:8 +msgid "Move window one workspace up" +msgstr "പണിയറകളിലെ ജാലകങ്ങള് മുകളിലേക്ക് ചലിപ്പിക്കുക" -#: ../src/frames.c:1093 -msgid "Roll Up Window" -msgstr "ജാലകം ചുരുട്ടുക" +#: ../src/50-mutter-navigation.xml.in.h:9 +msgid "Move window one workspace down" +msgstr "ഒരു പണിയറ‌‌‌‌‌യ‌്ക്ക് താഴെ ജാലകം നീക്കുക" -#: ../src/frames.c:1096 -msgid "Unroll Window" -msgstr "Unroll Window" +#: ../src/50-mutter-navigation.xml.in.h:10 +msgid "Switch applications" +msgstr "പ്രയോഗങ്ങള്‍ തമ്മില്‍ മാറ്റുക" -#: ../src/frames.c:1099 -msgid "Keep Window On Top" -msgstr "ജാലകം മുകളിലാക്കുക" +#: ../src/50-mutter-navigation.xml.in.h:11 +msgid "Switch windows" +msgstr "ജാലകങ്ങള്‍ തമ്മില്‍ മാറ്റുക" -#: ../src/frames.c:1102 -msgid "Remove Window From Top" -msgstr "ജാലകം മുകളില്‍ നിന്നും നീക്കുക" +#: ../src/50-mutter-navigation.xml.in.h:12 +msgid "Switch windows of an application" +msgstr "ഒരു പ്രയോഗത്തിന്റെ ജാലകങ്ങള്‍ തമ്മില്‍ മാറ്റുക" -#: ../src/frames.c:1105 -msgid "Always On Visible Workspace" -msgstr "എപ്പോഴും ദൃശ്യമായ പണിയറയില്‍ " +#: ../src/50-mutter-navigation.xml.in.h:13 +msgid "Switch system controls" +msgstr "സിസ്റ്റം നിയന്ത്രണങ്ങള്‍ മാറ്റുക" -#: ../src/frames.c:1108 -msgid "Put Window On Only One Workspace" -msgstr "ഒരു പണിയറയില്‍ ജാലകം കാണിക്കുക" +#: ../src/50-mutter-navigation.xml.in.h:14 +msgid "Switch windows directly" +msgstr "ജാലകങ്ങള്‍ നേരിട്ട് മാറ്റുക" -#: ../src/keybindings.c:1087 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" +#: ../src/50-mutter-navigation.xml.in.h:15 +msgid "Switch windows of an app directly" msgstr "" -#: ../src/keybindings.c:2716 -#, c-format -msgid "Error launching metacity-dialog to print an error about a command: %s\n" +#: ../src/50-mutter-navigation.xml.in.h:16 +msgid "Switch system controls directly" msgstr "" -#: ../src/keybindings.c:2821 -#, c-format -msgid "No command %d has been defined.\n" -msgstr "%d എന്ന കമാന്‍ഡ് ലഭ്യമല്ല.\n" - -#: ../src/keybindings.c:3849 -msgid "No terminal command has been defined.\n" -msgstr "ഒരു ടെറ്‍മിനല്‍ കമാന്‍ഡും ലഭ്യമല്ല.\n" +#: ../src/50-mutter-navigation.xml.in.h:17 +msgid "Hide all normal windows" +msgstr "എല്ലാ സാധാരണ ജാലകങ്ങളും അദൃശ്യമാക്കുക" -#: ../src/main.c:67 -#, c-format -msgid "" -"metacity %s\n" -"Copyright (C) 2001-2007 Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" - -#: ../src/main.c:171 -msgid "Disable connection to session manager" -msgstr "സെഷന്‍ മാനേജറിലേക്കുള്ള കണക്ഷന്‍ പ്റവറ്‍ത്തന രഹിതമാക്കുക" - -#: ../src/main.c:177 -msgid "Replace the running window manager with Metacity" -msgstr "പ്റവറ്‍ത്തനത്തിലുള്ള ജാലകത്തിന്റെ മാനേജറിനെ മെറ്റാസിറ്റി ഉപയോഗിച്ച് മാറ്റുക" - -#: ../src/main.c:183 -msgid "Specify session management ID" -msgstr "സെഷന്‍ കൈകാര്യം ചെയ്യുന്ന ID നല്‍കുക" - -#: ../src/main.c:188 -msgid "X Display to use" -msgstr "ഉപയോഗിക്കുന്നതിനുള്ള X ഡിസ്പ്ളെ" - -#: ../src/main.c:194 -msgid "Initialize session from savefile" -msgstr "savefile-ല്‍ നിന്നും സെഷന്‍ ആരംഭിക്കുക" - -#: ../src/main.c:200 -msgid "Print version" -msgstr "പ്റിന്റ് ചെയ്യുവാനുള്ള വേറ്‍ഷന്‍" +#: ../src/50-mutter-navigation.xml.in.h:18 +msgid "Switch to workspace 1" +msgstr "പപണിയറകള് 1ലേക്ക് മാറ്റൂ" -#: ../src/main.c:353 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "പ്രമേയം സ്കാന്‍ ചെയ്യുവാന്‍ കഴിഞ്ഞില്ല: %s\n" +#: ../src/50-mutter-navigation.xml.in.h:19 +msgid "Switch to workspace 2" +msgstr "പണിയറകള് 2ലേക്ക് മാറ്റൂ" -#: ../src/main.c:369 -#, c-format -msgid "Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "" +#: ../src/50-mutter-navigation.xml.in.h:20 +msgid "Switch to workspace 3" +msgstr "പണിയറകള് 3ലേക്ക് മാറ്റൂ" -#: ../src/main.c:429 -#, c-format -msgid "Failed to restart: %s\n" -msgstr "പുനരാരംഭിക്കുന്നതില്‌ പരാജയപ്പെട്ടു: %s\n" +#: ../src/50-mutter-navigation.xml.in.h:21 +msgid "Switch to workspace 4" +msgstr "പണിയറകള് 4ലേക്ക് മാറ്റൂ" -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/menu.c:70 -msgid "Mi_nimize" -msgstr "ചെറുതാക്കുക (_n)" +#: ../src/50-mutter-navigation.xml.in.h:22 +#| msgid "Move to Workspace _Left" +msgid "Move to workspace left" +msgstr "ഇടത്തുളള പണിയറയിലേക്ക് നീങ്ങുക" -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/menu.c:72 -msgid "Ma_ximize" -msgstr "വലുതാക്കുക (_x)" +#: ../src/50-mutter-navigation.xml.in.h:23 +#| msgid "Move to Workspace R_ight" +msgid "Move to workspace right" +msgstr "വലത്തുളള പണിയറയിലേക്ക് നീങ്ങുക" -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/menu.c:74 -msgid "Unma_ximize" -msgstr "വലുതാക്കിയതൊഴിവാക്കുക (_x)" +#: ../src/50-mutter-navigation.xml.in.h:24 +#| msgid "Move to Workspace _Left" +msgid "Move to workspace above" +msgstr "മുകളിലുള്ള പണിയറയിലേക്ക് നീങ്ങുക " -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/menu.c:76 -msgid "Roll _Up" -msgstr "ചുരുട്ടുക" +#: ../src/50-mutter-navigation.xml.in.h:25 +#| msgid "Move to Workspace _Down" +msgid "Move to workspace below" +msgstr "താഴെയുളള പണിയറയിലേക്ക് നീങ്ങുക" -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/menu.c:78 -msgid "_Unroll" -msgstr "ചുരുളഴിക്കുക" +#: ../src/50-mutter-system.xml.in.h:1 +msgid "System" +msgstr "സിസ്റ്റം" -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/menu.c:80 -msgid "_Move" -msgstr "നീക്കുക (_M)" +#: ../src/50-mutter-system.xml.in.h:2 +msgid "Show the run command prompt" +msgstr "കമാന്‍ഡ് പ്രോപ്റ്റ് കാണിയ്ക്കുക" -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/menu.c:82 -msgid "_Resize" -msgstr "വലിപ്പം മാറ്റുക (_R)" +#: ../src/50-mutter-system.xml.in.h:3 +msgid "Show the activities overview" +msgstr "പ്രവര്‍ത്തനങ്ങളുടെ അവലോകനം കാണിയ്ക്കുക" -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/menu.c:84 -msgid "Move Titlebar On_screen" -msgstr "സ്ക്രീനിലേക്ക് തലക്കെട്ടിന്റെ ബാറ്‍ നീക്കുക (_s)" +#: ../src/50-mutter-windows.xml.in.h:1 +msgid "Windows" +msgstr "ജാലകങ്ങള്‍ (_W)" -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/menu.c:87 ../src/menu.c:89 -msgid "Always on _Top" -msgstr "എപ്പോഴും മുകളില്‍ (_T)" +#: ../src/50-mutter-windows.xml.in.h:2 +#| msgid "Activate window menu" +msgid "Activate the window menu" +msgstr "ജാലകത്തിന്റെ മെനു സജീവമാക്കുക" -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/menu.c:91 -msgid "_Always on Visible Workspace" -msgstr "എപ്പോഴും ദൃശ്യമായ പണിയറയില്‍ (_A)" +#: ../src/50-mutter-windows.xml.in.h:3 +msgid "Toggle fullscreen mode" +msgstr "അക്ഷര വിവര രീതിയില്‌ അളവ് ദൃശ്യമാക്കുക" -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/menu.c:93 -msgid "_Only on This Workspace" -msgstr "ഈ പണിയറയില്‍ മാത്രം (_O)" +#: ../src/50-mutter-windows.xml.in.h:4 +msgid "Toggle maximization state" +msgstr "" -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/menu.c:95 -msgid "Move to Workspace _Left" -msgstr "ഇടത്തുളള പണിയറയിലേക്ക് നീങ്ങുക (_L)" +#: ../src/50-mutter-windows.xml.in.h:5 +msgid "Maximize window" +msgstr "ജാലകം ഏറ്റവും വലുതാക്കുക" -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/menu.c:97 -msgid "Move to Workspace R_ight" -msgstr "വലത്തുളള പണിയറയിലേക്ക് നീങ്ങുക (_R)" +#: ../src/50-mutter-windows.xml.in.h:6 +#| msgid "Resize window" +msgid "Restore window" +msgstr "ജാലകം വീണ്ടെടുക്കുക" -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/menu.c:99 -msgid "Move to Workspace _Up" -msgstr "മുകളിലുളള പണിയറയിലേക്ക് നീങ്ങുക (_U)" +#: ../src/50-mutter-windows.xml.in.h:7 +msgid "Toggle shaded state" +msgstr "" -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/menu.c:101 -msgid "Move to Workspace _Down" -msgstr "താഴെയുളള പണിയറയിലേക്ക് നീങ്ങുക (_D)" +#: ../src/50-mutter-windows.xml.in.h:8 +msgid "Close window" +msgstr "ജാലകം അടയ്‍ക്കുക" -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/menu.c:105 -msgid "_Close" -msgstr "അടയ്‍ക്കുക (_C)" +#: ../src/50-mutter-windows.xml.in.h:9 +#| msgid "Resize window" +msgid "Hide window" +msgstr "ജാലകം അദൃശ്യമാക്കുക" -#: ../src/menu.c:199 ../src/prefs.c:2246 ../src/prefs.c:2780 -#, c-format -msgid "Workspace %d" -msgstr "പണിയറ %d" +#: ../src/50-mutter-windows.xml.in.h:10 +msgid "Move window" +msgstr "ജാലകം നീക്കുക" -#: ../src/menu.c:208 -msgid "Workspace 1_0" -msgstr "പണിയറ 10 (_0)" +#: ../src/50-mutter-windows.xml.in.h:11 +msgid "Resize window" +msgstr "ജാലകത്തിന്‍റെ വലിപ്പം മാറ്റുക" -#: ../src/menu.c:210 -#, c-format -msgid "Workspace %s%d" -msgstr "പണിയറ %s%d" +#: ../src/50-mutter-windows.xml.in.h:12 +#| msgid "Toggle window on all workspaces" +msgid "Toggle window on all workspaces or one" +msgstr "എല്ലാ പണിയറകളിലെയും ജാലകങ്ങള്‍ കാണിക്കുക" -#: ../src/menu.c:390 -msgid "Move to Another _Workspace" -msgstr "മറ്റൊരു പണിയറയിലേക്ക് നീങ്ങുക (_W)" +#: ../src/50-mutter-windows.xml.in.h:13 +#| msgid "Raise obscured window, otherwise lower" +msgid "Raise window if covered, otherwise lower it" +msgstr "" -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:105 -msgid "Shift" -msgstr "മാറ്റുക" +#: ../src/50-mutter-windows.xml.in.h:14 +msgid "Raise window above other windows" +msgstr "ജാലകം മറ്റ് ജാലകങ്ങള്ക്ക‌‌് മുകളിലേക്ക് ഉയ‌ര്ത്തുക" -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:111 -msgid "Ctrl" -msgstr "നിയന്ത്രണം" +#: ../src/50-mutter-windows.xml.in.h:15 +msgid "Lower window below other windows" +msgstr "ജാലകം മറ്റ് ജാലകങ്ങള്ക്കടിയിലാക്കുക" -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:117 -msgid "Alt" -msgstr "Alt" +#: ../src/50-mutter-windows.xml.in.h:16 +msgid "Maximize window vertically" +msgstr "ജാലകം ലംബമായ് വലുതാക്കുക" -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:123 -msgid "Meta" -msgstr "Meta" +#: ../src/50-mutter-windows.xml.in.h:17 +msgid "Maximize window horizontally" +msgstr "ജാലകം തിരശ്ചീനമായ് വലുതാക്കുക" -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:129 -msgid "Super" -msgstr "Super" +#: ../src/50-mutter-windows.xml.in.h:18 +msgid "View split on left" +msgstr "" -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:135 -msgid "Hyper" -msgstr "Hyper" +#: ../src/50-mutter-windows.xml.in.h:19 +msgid "View split on right" +msgstr "" -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:141 -msgid "Mod2" -msgstr "Mod2" +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: ../src/compositor/compositor.c:507 +#, c-format +msgid "" +"Another compositing manager is already running on screen %i on display \"%s" +"\"." +msgstr "" -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:147 -msgid "Mod3" -msgstr "Mod3" +#: ../src/compositor/meta-background.c:1111 +msgid "background texture could not be created from file" +msgstr "" -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:153 -msgid "Mod4" -msgstr "Mod4" +#: ../src/core/bell.c:320 +msgid "Bell event" +msgstr "ബെല്‍ ഇവെന്റ്" -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:159 -msgid "Mod5" -msgstr "Mod5" +#: ../src/core/core.c:157 +#, c-format +msgid "Unknown window information request: %d" +msgstr "ജാലകത്തിനുള്ള ആവശ്യം അപരിചിതമായ സ്ഥലത്ത് നിന്നും : %d" -#: ../src/metacity-dialog.c:90 +#: ../src/core/delete.c:111 #, c-format -msgid "\"%s\" is not responding." -msgstr "\"%s\"-ല്‍ നിന്നും ഒരു മറുപടിയും ലഭ്യമല്ല." +#| msgid "%s is not responding." +msgid "“%s” is not responding." +msgstr "\"%s\"-ല്‍ നിന്നും മറുപടി ലഭ്യമല്ല." + +#: ../src/core/delete.c:113 +msgid "Application is not responding." +msgstr "പ്രയോഗത്തില്‍ നിന്നും ഒരു മറുപടിയും ലഭ്യമല്ല." -#: ../src/metacity-dialog.c:97 +#: ../src/core/delete.c:118 msgid "" "You may choose to wait a short while for it to continue or force the " "application to quit entirely." msgstr "" +"ഒന്നുകില്‍ പ്രയോഗം മുഴുവനായി നീര്‍ത്താം, അല്ലെങ്കില്‍ അതിന് കുറച്ച് സമയം കൂടി " +"കൊടുത്ത് തുടരാം." -#: ../src/metacity-dialog.c:107 +#: ../src/core/delete.c:125 msgid "_Wait" msgstr "കാത്തിരിക്കുക (_W)" -#: ../src/metacity-dialog.c:109 +#: ../src/core/delete.c:125 msgid "_Force Quit" -msgstr "നിറ്‍ബന്ധമായും പുറത്ത് കടക്കുക (_F)" +msgstr "നിര്‍ബന്ധമായും പുറത്ത് കടക്കുക (_F)" -#: ../src/metacity-dialog.c:206 -msgid "Title" -msgstr "തലക്കെട്ട്" - -#: ../src/metacity-dialog.c:218 -msgid "Class" -msgstr "ക്ളാസ്" - -#: ../src/metacity-dialog.c:244 -msgid "" -"These windows do not support \"save current setup\" and will have to be " -"restarted manually next time you log in." -msgstr "" - -#: ../src/metacity-dialog.c:310 +#: ../src/core/display.c:401 #, c-format -msgid "" -"There was an error running \"%s\":\n" -"%s." -msgstr "" -"\"%s\" പ്രവ‍ര്ത്തിക്കുന്നതില് തകരാറ്:\n" -"%s." - -#: ../src/metacity.desktop.in.h:1 -msgid "Metacity" -msgstr "മെറ്റാസിറ്റി" - -#: ../src/metacity.schemas.in.h:1 -msgid "(Not implemented) Navigation works in terms of applications not windows" -msgstr "" - -#: ../src/metacity.schemas.in.h:2 -msgid "" -"A font description string describing a font for window titlebars. The size " -"from the description will only be used if the titlebar_font_size option is " -"set to 0. Also, this option is disabled if the titlebar_uses_desktop_font " -"option is set to true." +msgid "Missing %s extension required for compositing" msgstr "" -#: ../src/metacity.schemas.in.h:3 -msgid "Action on title bar double-click" -msgstr "തലക്കെട്ടിനുള്ള ബാറ്‍ രണ്ട് തവണ ക്ളിക്ക് ചെയ്യുമ്പോള്‍ ഉണ്ടാകുന്ന പ്റവറ്‍ത്തി" - -#: ../src/metacity.schemas.in.h:4 -msgid "Action on title bar middle-click" -msgstr "തലക്കെട്ടിനുള്ള ബാറില്‍ നടുക്ക് ക്ളിക്ക് ചെയ്യുമ്പോള്‍ ഉണ്ടാകുന്ന പ്റവറ്‍ത്തി" - -#: ../src/metacity.schemas.in.h:5 -msgid "Action on title bar right-click" -msgstr "തലക്കെട്ടിനുള്ള ബാറില്‍ റൈറ്റ് ക്ളിക്ക് ചെയ്യുമ്പോള്‍ ഉണ്ടാകുന്ന പ്റവറ്‍ത്തി" - -#: ../src/metacity.schemas.in.h:6 -msgid "Activate window menu" -msgstr "ജാലകപട്ടികയെ സജ്ജമാക്കുക" - -#: ../src/metacity.schemas.in.h:7 -msgid "Arrangement of buttons on the titlebar" -msgstr "തലക്കെട്ടിനുള്ള ബാറില്‍ ബട്ടണുകളുടെ ക്റമികരണം" +#: ../src/core/display.c:493 +#, c-format +msgid "Failed to open X Window System display '%s'\n" +msgstr "XWindow തുറക്കുന്നതില്‌ പരാജയം : %s\n" -#: ../src/metacity.schemas.in.h:8 +#: ../src/core/keybindings.c:929 +#, c-format msgid "" -"Arrangement of buttons on the titlebar. The value should be a string, such " -"as \"menu:minimize,maximize,close\"; the colon separates the left corner of " -"the window from the right corner, and the button names are comma-separated. " -"Duplicate buttons are not allowed. Unknown button names are silently ignored " -"so that buttons can be added in future metacity versions without breaking " -"older versions." +"Some other program is already using the key %s with modifiers %x as a " +"binding\n" msgstr "" -#: ../src/metacity.schemas.in.h:9 -msgid "Automatically raises the focused window" -msgstr "അവസ്ഥാ മാറ്റങ്ങള് സ്വയമേവ സംരക്ഷിക്കുക" - -#: ../src/metacity.schemas.in.h:10 -msgid "" -"Clicking a window while holding down this modifier key will move the window " -"(left click), resize the window (middle click), or show the window menu " -"(right click). Modifier is expressed as \"<Alt>\" or \"<Super>\" " -"for example." +#: ../src/core/keybindings.c:1129 +#, c-format +msgid "\"%s\" is not a valid accelerator\n" msgstr "" -#: ../src/metacity.schemas.in.h:11 -msgid "Close window" -msgstr "ജാലകം അടയ്‍ക്കുക" +#: ../src/core/main.c:196 +msgid "Disable connection to session manager" +msgstr "സെഷന്‍ മാനേജറിലേക്കുള്ള കണക്ഷന്‍ പ്രവര്‍ത്തന രഹിതമാക്കുക" -#: ../src/metacity.schemas.in.h:12 -msgid "Commands to run in response to keybindings" -msgstr "" +#: ../src/core/main.c:202 +msgid "Replace the running window manager" +msgstr "പ്രവര്‍ത്തനത്തിലുള്ള ജാലകത്തിന്റെ മാനേജറിനെ മാറ്റുക" -#: ../src/metacity.schemas.in.h:13 -msgid "Compositing Manager" -msgstr "" +#: ../src/core/main.c:208 +msgid "Specify session management ID" +msgstr "സെഷന്‍ കൈകാര്യം ചെയ്യുന്ന ID നല്‍കുക" -#: ../src/metacity.schemas.in.h:14 -msgid "Control how new windows get focus" -msgstr "" +#: ../src/core/main.c:213 +msgid "X Display to use" +msgstr "ഉപയോഗിക്കുന്നതിനുള്ള X ഡിസ്പ്ളെ" -#: ../src/metacity.schemas.in.h:15 -msgid "Current theme" -msgstr "സജീവ തീം" +#: ../src/core/main.c:219 +msgid "Initialize session from savefile" +msgstr "savefile-ല്‍ നിന്നും സെഷന്‍ ആരംഭിക്കുക" -#: ../src/metacity.schemas.in.h:16 -msgid "Delay in milliseconds for the auto raise option" +#: ../src/core/main.c:225 +msgid "Make X calls synchronous" msgstr "" -#: ../src/metacity.schemas.in.h:17 -msgid "Determines whether Metacity is a compositing manager." -msgstr "" +#: ../src/core/main.c:494 +#, c-format +msgid "Failed to scan themes directory: %s\n" +msgstr "പ്രമേയം സ്കാന്‍ ചെയ്യുവാന്‍ കഴിഞ്ഞില്ല: %s\n" -#: ../src/metacity.schemas.in.h:18 +#: ../src/core/main.c:510 +#, c-format msgid "" -"Determines whether applications or the system can generate audible 'beeps'; " -"may be used in conjunction with 'visual bell' to allow silent 'beeps'." +"Could not find a theme! Be sure %s exists and contains the usual themes.\n" msgstr "" -#: ../src/metacity.schemas.in.h:19 -msgid "Disable misfeatures that are required by old or broken applications" +#: ../src/core/mutter.c:40 +#, c-format +msgid "" +"mutter %s\n" +"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" msgstr "" +"മട്ടര്‍ %s\n" +"പകര്‍പ്പവകാശം (C) 2001-%d ഹാവോക്ക് പെന്നിംഗിടണ്‍, റെഡ്ഹാറ്റ്, പിന്നെ " +"മറ്റുള്ളവരും\n" +"ഇത് ഒരു സ്വതന്ത്ര സോഫ്റ്റ്‌വെയറാണ്; പകര്‍ത്താനുള്ള നിബന്ധനകള്‍ കാണാന്‍ " +"സോഴ്സ്കോഡ് നോക്കുക.\n" +"ഇതിന് ഒരു ഉറപ്പും ഇല്ല; ഏതെങ്കിലും കാര്യങ്ങള്‍ക്ക് അനുയോജ്യമാണെന്നോ " +"ഉപയോഗയോഗ്യമാണന്നോഉള്ള ഉറപ്പ് " +"പോലും.\n" -#: ../src/metacity.schemas.in.h:20 -msgid "Enable Visual Bell" -msgstr "" +#: ../src/core/mutter.c:54 +msgid "Print version" +msgstr "അച്ചടി പതിപ്പ്" -#: ../src/metacity.schemas.in.h:21 -msgid "Hide all windows and focus desktop" -msgstr "എല്ലാ ജാലകങ്ങളും അദൃശ്യമാക്കി ഡസ്ക്ടോപ്പ് കാണിക്കുക" +#: ../src/core/mutter.c:60 +msgid "Mutter plugin to use" +msgstr "ഉപയോഗിക്കേണ്ട മട്ടര്‍ പ്ലഗ്ഗിന്‍" -#: ../src/metacity.schemas.in.h:22 +#: ../src/core/prefs.c:1087 msgid "" -"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " -"the focused window will be automatically raised after a delay specified by " -"the auto_raise_delay key. This is not related to clicking on a window to " -"raise it, nor to entering a window during drag-and-drop." +"Workarounds for broken applications disabled. Some applications may not " +"behave properly.\n" msgstr "" -#: ../src/metacity.schemas.in.h:23 -msgid "" -"If true, ignore the titlebar_font option, and use the standard application " -"font for window titles." +#: ../src/core/prefs.c:1162 +#, c-format +msgid "Could not parse font description \"%s\" from GSettings key %s\n" msgstr "" -#: ../src/metacity.schemas.in.h:24 +#: ../src/core/prefs.c:1228 +#, c-format msgid "" -"If true, metacity will give the user less feedback by using wireframes, " -"avoiding animations, or other means. This is a significant reduction in " -"usability for many users, but may allow legacy applications to continue " -"working, and may also be a useful tradeoff for terminal servers. However, " -"the wireframe feature is disabled when accessibility is on." +"\"%s\" found in configuration database is not a valid value for mouse button " +"modifier\n" msgstr "" -#: ../src/metacity.schemas.in.h:25 +#: ../src/core/prefs.c:1780 +#, c-format msgid "" -"If true, then Metacity works in terms of applications rather than windows. " -"The concept is a bit abstract, but in general an application-based setup is " -"more like the Mac and less like Windows. When you focus a window in " -"application-based mode, all the windows in the application will be raised. " -"Also, in application-based mode, focus clicks are not passed through to " -"windows in other applications. Application-based mode is, however, largely " -"unimplemented at the moment." -msgstr "" - -#: ../src/metacity.schemas.in.h:26 -msgid "If true, trade off usability for less resource usage" -msgstr "" - -#: ../src/metacity.schemas.in.h:27 -msgid "Lower window below other windows" -msgstr "ജാലകം മറ്റ് ജാലകങ്ങള്ക്കടിയിലാക്കുക" - -#: ../src/metacity.schemas.in.h:28 -msgid "Maximize window" -msgstr "ജാലകം ഏറ്റവും വലുതാക്കുക" - -#: ../src/metacity.schemas.in.h:29 -msgid "Maximize window horizontally" -msgstr "ജാലകം തിരശ്ചീനമായ് വലുതാക്കുക" - -#: ../src/metacity.schemas.in.h:30 -msgid "Maximize window vertically" -msgstr "ജാലകം ലംബമായ് വലുതാക്കുക" - -#: ../src/metacity.schemas.in.h:31 -msgid "Minimize window" -msgstr "ജാലകം ഏറ്റവും ചെറുതാക്കുക" - -#: ../src/metacity.schemas.in.h:32 -msgid "Modifier to use for modified window click actions" -msgstr "" - -#: ../src/metacity.schemas.in.h:33 -msgid "Move backward between panels and the desktop immediately" -msgstr "" - -#: ../src/metacity.schemas.in.h:34 -msgid "Move backwards between panels and the desktop with popup" -msgstr "" - -#: ../src/metacity.schemas.in.h:35 -msgid "Move backwards between windows immediately" -msgstr "" - -#: ../src/metacity.schemas.in.h:36 -msgid "Move backwards between windows of an application immediately" -msgstr "" - -#: ../src/metacity.schemas.in.h:37 -msgid "Move backwards between windows of an application with popup" -msgstr "" - -#: ../src/metacity.schemas.in.h:38 -msgid "Move between panels and the desktop immediately" -msgstr "" - -#: ../src/metacity.schemas.in.h:39 -msgid "Move between panels and the desktop with popup" -msgstr "" - -#: ../src/metacity.schemas.in.h:40 -msgid "Move between windows immediately" -msgstr "" - -#: ../src/metacity.schemas.in.h:41 -msgid "Move between windows of an application immediately" -msgstr "" - -#: ../src/metacity.schemas.in.h:42 -msgid "Move between windows of an application with popup" -msgstr "" - -#: ../src/metacity.schemas.in.h:43 -msgid "Move between windows with popup" -msgstr "" - -#: ../src/metacity.schemas.in.h:44 -msgid "Move focus backwards between windows using popup display" +"\"%s\" found in configuration database is not a valid value for keybinding " +"\"%s\"\n" msgstr "" -#: ../src/metacity.schemas.in.h:45 -msgid "Move window" -msgstr "ജാലകം നീക്കുക" - -#: ../src/metacity.schemas.in.h:46 -msgid "Move window one workspace down" -msgstr "ഒരു പണിയറ‌‌‌‌‌യ‌്ക്ക് താഴെ ജാലകം നീക്കുക" - -#: ../src/metacity.schemas.in.h:47 -msgid "Move window one workspace to the left" -msgstr "ഒരു പണിയറ‌‌‌‌‌യ‌്ക്ക് ഇടതുവശത്തേക്ക് ജാലകം നീക്കുക" - -#: ../src/metacity.schemas.in.h:48 -msgid "Move window one workspace to the right" -msgstr "ഒരു പണിയറ‌‌‌‌‌യ‌്ക്ക് വലതുവശത്തേക്ക് ജാലകം നീക്കുക" - -#: ../src/metacity.schemas.in.h:49 -msgid "Move window one workspace up" -msgstr "പണിയറകളിലെ ജാലകങ്ങള് മുകളിലേക്ക് ചലിപ്പിക്കുക" - -#: ../src/metacity.schemas.in.h:50 -msgid "Move window to east side of screen" -msgstr "സ്ക്രീനിന്റെ കിഴക്ക് വശത്തേക്ക് ജാലകം മാറ്റുക" - -#: ../src/metacity.schemas.in.h:51 -msgid "Move window to north side of screen" -msgstr "സ്ക്രീനിന്റെ വടക്ക് വശത്തേക്ക് ജാലകം മാറ്റുക" - -#: ../src/metacity.schemas.in.h:52 -msgid "Move window to north-east corner" -msgstr "സ്ക്രീനിന്റെ വടക്ക്-കിഴക്ക് വശത്തേക്ക് ജാലകം മാറ്റുക" - -#: ../src/metacity.schemas.in.h:53 -msgid "Move window to north-west corner" -msgstr "സ്ക്രീനിന്റെ വടക്ക്-പടിഞ്ഞാറ് വശത്തേക്ക് ജാലകം മാറ്റുക" - -#: ../src/metacity.schemas.in.h:54 -msgid "Move window to south side of screen" -msgstr "സ്ക്രീനിന്റെ തെക്ക് വശത്തേക്ക് ജാലകം മാറ്റുക" - -#: ../src/metacity.schemas.in.h:55 -msgid "Move window to south-east corner" -msgstr "സ്ക്രീനിന്റെ തെക്ക്-കിഴക്ക് വശത്തേക്ക് ജാലകം മാറ്റുക" - -#: ../src/metacity.schemas.in.h:56 -msgid "Move window to south-west corner" -msgstr "സ്ക്രീനിന്റെ തെക്ക്-പടിഞ്ഞാറ് വശത്തേക്ക് ജാലകം മാറ്റുക" - -#: ../src/metacity.schemas.in.h:57 -msgid "Move window to west side of screen" -msgstr "സ്ക്രീനിന്റെ പടിഞ്ഞാറിലേക്ക് ജാലകം മാറ്റുക" - -#: ../src/metacity.schemas.in.h:58 -msgid "Move window to workspace 1" -msgstr "പണിയറ ജാലകം ഒന്നിലേക്ക് നീക്കുക" - -#: ../src/metacity.schemas.in.h:59 -msgid "Move window to workspace 10" -msgstr "പണിയറ ജാലകം പത്തിലേക്ക് നീക്കുക" - -#: ../src/metacity.schemas.in.h:60 -msgid "Move window to workspace 11" -msgstr "പണിയറ ജാലകം 11ലേക്ക് നീക്കുക" - -#: ../src/metacity.schemas.in.h:61 -msgid "Move window to workspace 12" -msgstr "പണിയറ ജാലകം 12ലേക്ക് നീക്കുക" - -#: ../src/metacity.schemas.in.h:62 -msgid "Move window to workspace 2" -msgstr "പണിയറ ജാലകം 2ലേക്ക് നീക്കുക" - -#: ../src/metacity.schemas.in.h:63 -msgid "Move window to workspace 3" -msgstr "പണിയറ ജാലകം 3ലേക്ക് നീക്കുക" - -#: ../src/metacity.schemas.in.h:64 -msgid "Move window to workspace 4" -msgstr "പണിയറ ജാലകം 4ലേക്ക് നീക്കുക" - -#: ../src/metacity.schemas.in.h:65 -msgid "Move window to workspace 5" -msgstr "പണിയറ ജാലകം 5ലേക്ക് നീക്കുക" - -#: ../src/metacity.schemas.in.h:66 -msgid "Move window to workspace 6" -msgstr "പണിയറ ജാലകം 6ലേക്ക് നീക്കുക" - -#: ../src/metacity.schemas.in.h:67 -msgid "Move window to workspace 7" -msgstr "പണിയറ ജാലകം 7ലേക്ക് നീക്കുക" - -#: ../src/metacity.schemas.in.h:68 -msgid "Move window to workspace 8" -msgstr "പണിയറ ജാലകം 8ലേക്ക് നീക്കുക" - -#: ../src/metacity.schemas.in.h:69 -msgid "Move window to workspace 9" -msgstr "പണിയറ ജാലകം 9ലേക്ക് നീക്കുക" - -#: ../src/metacity.schemas.in.h:70 -msgid "Name of workspace" -msgstr "പണിയറയുടെ പേര‌്" +#: ../src/core/prefs.c:1879 +#, c-format +msgid "Workspace %d" +msgstr "പണിയറ %d" -#: ../src/metacity.schemas.in.h:71 -msgid "Number of workspaces" -msgstr "പണിയറകളുടെ എണ്ണം" +#: ../src/core/screen.c:673 +#, c-format +msgid "Screen %d on display '%s' is invalid\n" +msgstr "സ്ക്രീന്‍ %d (ഡിസ്പ്ളേ '%s'ലെ) അസാധുവാണ്\n" -#: ../src/metacity.schemas.in.h:72 +#: ../src/core/screen.c:689 +#, c-format msgid "" -"Number of workspaces. Must be more than zero, and has a fixed maximum to " -"prevent making the desktop unusable by accidentally asking for too many " -"workspaces." +"Screen %d on display \"%s\" already has a window manager; try using the --" +"replace option to replace the current window manager.\n" msgstr "" -#: ../src/metacity.schemas.in.h:73 -msgid "Raise obscured window, otherwise lower" -msgstr "ജാലകം മറ്റ് ജാലകങ്ങള്ക്ക‌‌് മുകളിലേക്ക് ഉയ‌ര്ത്തുക" - -#: ../src/metacity.schemas.in.h:74 -msgid "Raise window above other windows" -msgstr "ജാലകം മറ്റ് ജാലകങ്ങള്ക്ക‌‌് മുകളിലേക്ക് ഉയ‌ര്ത്തുക" - -#: ../src/metacity.schemas.in.h:75 -msgid "Resize window" -msgstr "ജാലകത്തിന്‍റെ വലിപ്പം മാറ്റുക" - -#: ../src/metacity.schemas.in.h:76 -msgid "Run a defined command" -msgstr "നി‌‌‌ര്‌വചിച്ച നി‌ര്ദ്ദേശം പ്രാവ‌‌ര്ത്തികമാക്കൂ" - -#: ../src/metacity.schemas.in.h:77 -msgid "Run a terminal" -msgstr "ഒരു ടറ്‍മിനല്‍ ലഭ്യമാക്കുക" - -#: ../src/metacity.schemas.in.h:78 -msgid "" -"Setting this option to false can lead to buggy behavior, so users are " -"strongly discouraged from changing it from the default of true. Many actions " -"(e.g. clicking in the client area, moving or resizing the window) normally " -"raise the window as a side-effect. Set this option to false to decouple " -"raising from other user actions. Even when this option is false, windows can " -"still be raised by an alt-left-click anywhere on the window, a normal click " -"on the window decorations, or by special messages from pagers, such as " -"activation requests from tasklist applets. This option is currently disabled " -"in click-to-focus mode. Note that the list of ways to raise windows when " -"raise_on_click is false does not include programmatic requests from " -"applications to raise windows; such requests will be ignored regardless of " -"the reason for the request. If you are an application developer and have a " -"user complaining that your application does not work with this setting " -"disabled, tell them it is _their_ fault for breaking their window manager " -"and that they need to change this option back to true or live with the bug " -"they requested. See also http://bugzilla.gnome.org/show_bug.cgi?id=445447#c6." -msgstr "" - -#: ../src/metacity.schemas.in.h:79 -msgid "Show the panel menu" -msgstr "പാനലിന്റെ മെനു കാണിക്കുക" - -#: ../src/metacity.schemas.in.h:80 -msgid "Show the panel run application dialog" -msgstr "" - -#: ../src/metacity.schemas.in.h:81 +#: ../src/core/screen.c:716 +#, c-format msgid "" -"Some applications disregard specifications in ways that result in window " -"manager misfeatures. This option puts Metacity in a rigorously correct mode, " -"which gives a more consistent user interface, provided one does not need to " -"run any misbehaving applications." +"Could not acquire window manager selection on screen %d display \"%s\"\n" msgstr "" -#: ../src/metacity.schemas.in.h:82 -msgid "Switch to workspace 1" -msgstr "പപണിയറകള് 1ലേക്ക് മാറ്റൂ" - -#: ../src/metacity.schemas.in.h:83 -msgid "Switch to workspace 10" -msgstr "പണിയറകള് 10ലേക്ക് മാറ്റൂ" - -#: ../src/metacity.schemas.in.h:84 -msgid "Switch to workspace 11" -msgstr "പണിയറകള് 11ലേക്ക് മാറ്റൂ" - -#: ../src/metacity.schemas.in.h:85 -msgid "Switch to workspace 12" -msgstr "പണിയറകള് 12ലേക്ക് മാറ്റൂ" - -#: ../src/metacity.schemas.in.h:86 -msgid "Switch to workspace 2" -msgstr "പണിയറകള് 2ലേക്ക് മാറ്റൂ" - -#: ../src/metacity.schemas.in.h:87 -msgid "Switch to workspace 3" -msgstr "പണിയറകള് 3ലേക്ക് മാറ്റൂ" - -#: ../src/metacity.schemas.in.h:88 -msgid "Switch to workspace 4" -msgstr "പണിയറകള് 4ലേക്ക് മാറ്റൂ" - -#: ../src/metacity.schemas.in.h:89 -msgid "Switch to workspace 5" -msgstr "പണിയറകള് 5ലേക്ക് മാറ്റൂ" - -#: ../src/metacity.schemas.in.h:90 -msgid "Switch to workspace 6" -msgstr "പണിയറകള് 6ലേക്ക് മാറ്റൂ" - -#: ../src/metacity.schemas.in.h:91 -msgid "Switch to workspace 7" -msgstr "പണിയറകള് 7ലേക്ക് മാറ്റൂ" +#: ../src/core/screen.c:794 +#, c-format +msgid "Screen %d on display \"%s\" already has a window manager\n" +msgstr "" -#: ../src/metacity.schemas.in.h:92 -msgid "Switch to workspace 8" -msgstr "പണിയറകള് 8ലേക്ക് മാറ്റൂ" +#: ../src/core/screen.c:979 +#, c-format +msgid "Could not release screen %d on display \"%s\"\n" +msgstr "" -#: ../src/metacity.schemas.in.h:93 -msgid "Switch to workspace 9" -msgstr "പണിയറകള് 9ലേക്ക് മാറ്റൂ" +#: ../src/core/session.c:843 ../src/core/session.c:850 +#, c-format +msgid "Could not create directory '%s': %s\n" +msgstr "'%s'എന്ന കൂട് ഉണ്ടാക്കാന്‌ കഴിയുന്നില്ല: %s\n" -#: ../src/metacity.schemas.in.h:94 -msgid "Switch to workspace above this one" -msgstr "ഇതിന്റെ മുകളിലുള്ള പണിയറകളിേക്ക് മാറ്റൂ" +#: ../src/core/session.c:860 +#, c-format +msgid "Could not open session file '%s' for writing: %s\n" +msgstr "%s എഴുതാനായി തുറക്കുന്നതില്‌ %s പരാജയം\n" -#: ../src/metacity.schemas.in.h:95 -msgid "Switch to workspace below this one" -msgstr "ഇതിന്റെ താഴെയുള്ള പണിയറകളിേക്ക് മാറ്റൂ" +#: ../src/core/session.c:1001 +#, c-format +msgid "Error writing session file '%s': %s\n" +msgstr "'%s' രചനാ എഴുതുന്നതില്‌ പരാജയം: %s\n" -#: ../src/metacity.schemas.in.h:96 -msgid "Switch to workspace on the left" -msgstr "ഇതിന്റെ ഇടതുവശത്തുള്ള പണിയറകളിേക്ക് മാറ്റൂ" +#: ../src/core/session.c:1006 +#, c-format +msgid "Error closing session file '%s': %s\n" +msgstr "'%s' രചന അട‌യ്‌ക്കുന്നതില്‌‌ പരാജയം: %s\n" -#: ../src/metacity.schemas.in.h:97 -msgid "Switch to workspace on the right" -msgstr "ഇതിന്റെ വലതുവശത്തുള്ള പണിയറകളിേക്ക് മാറ്റൂ" +#: ../src/core/session.c:1136 +#, c-format +msgid "Failed to parse saved session file: %s\n" +msgstr "രചന വായിക്കുന്നതില്‌ പരാജയപ്പെട്ടു: %s\n" -#: ../src/metacity.schemas.in.h:98 -msgid "System Bell is Audible" +#: ../src/core/session.c:1185 +#, c-format +msgid "<mutter_session> attribute seen but we already have the session ID" msgstr "" -#: ../src/metacity.schemas.in.h:99 -msgid "Take a screenshot" -msgstr "ഒരു സ്ക്രീന്‍ ഷോട്ട് എടുക്കുക" - -#: ../src/metacity.schemas.in.h:100 -msgid "Take a screenshot of a window" -msgstr "ജാലകത്തിന്റെ ഒരു സ്ക്രീന്‍ ഷോട്ട് എടുക്കുക" +#: ../src/core/session.c:1198 ../src/core/session.c:1273 +#: ../src/core/session.c:1305 ../src/core/session.c:1377 +#: ../src/core/session.c:1437 +#, c-format +msgid "Unknown attribute %s on <%s> element" +msgstr "\"%s\" എന്ന ആട്രിബ്യൂട്ട് <%s> എലമെന്റില്‍ ലഭ്യമല്ല" -#: ../src/metacity.schemas.in.h:101 -msgid "" -"Tells Metacity how to implement the visual indication that the system bell " -"or another application 'bell' indicator has been rung. Currently there are " -"two valid values, \"fullscreen\", which causes a fullscreen white-black " -"flash, and \"frame_flash\" which causes the titlebar of the application " -"which sent the bell signal to flash. If the application which sent the bell " -"is unknown (as is usually the case for the default \"system beep\"), the " -"currently focused window's titlebar is flashed." -msgstr "" +#: ../src/core/session.c:1215 +#, c-format +msgid "nested <window> tag" +msgstr "തരക്കെട്ടില്ലാത്ത ജാലകം" -#: ../src/metacity.schemas.in.h:102 -msgid "" -"The /apps/metacity/global_keybindings/run_command_N keys define keybindings " -"that correspond to these commands. Pressing the keybinding for run_command_N " -"will execute command_N." -msgstr "" +#: ../src/core/session.c:1457 +#, c-format +msgid "Unknown element %s" +msgstr "%s ന്റെ അറിയാത്ത ഘടകം" -#: ../src/metacity.schemas.in.h:103 +#: ../src/core/session.c:1809 msgid "" -"The /apps/metacity/global_keybindings/run_command_screenshot key defines a " -"keybinding which causes the command specified by this setting to be invoked." +"These windows do not support "save current setup" and will have to " +"be restarted manually next time you log in." msgstr "" -#: ../src/metacity.schemas.in.h:104 -msgid "" -"The /apps/metacity/global_keybindings/run_command_window_screenshot key " -"defines a keybinding which causes the command specified by this setting to " -"be invoked." -msgstr "" +#: ../src/core/util.c:80 +#, c-format +msgid "Failed to open debug log: %s\n" +msgstr "തുറക്കുന്നതില്‌ പരാജയം: %s\n" -#: ../src/metacity.schemas.in.h:105 -msgid "" -"The keybinding that runs the correspondingly-numbered command in /apps/" -"metacity/keybinding_commands The format looks like \"<Control>a\" or " -"\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -"lower or upper case, and also abbreviations such as \"<Ctl>\" and " -"\"<Ctrl>\". If you set the option to the special string \"disabled\", " -"then there will be no keybinding for this action." -msgstr "" +#: ../src/core/util.c:90 +#, c-format +msgid "Failed to fdopen() log file %s: %s\n" +msgstr "fdopen() log രചന %s തുറക്കുന്നതില്‌ പരാജയം : %s\n" -#: ../src/metacity.schemas.in.h:106 -msgid "" -"The keybinding that switches to the workspace above the current workspace. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" +#: ../src/core/util.c:96 +#, c-format +msgid "Opened log file %s\n" +msgstr "തുറന്ന ഒരു ലോഗ് രചന %s\n" -#: ../src/metacity.schemas.in.h:107 -msgid "" -"The keybinding that switches to the workspace below the current workspace. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." +#: ../src/core/util.c:115 ../src/tools/mutter-message.c:149 +#, c-format +msgid "Mutter was compiled without support for verbose mode\n" msgstr "" +"വിശദാംശങ്ങള്‍ കാണിക്കുന്ന രീതിയുടെ പിന്തുണ ഇല്ലാതെയാണ് ഈ മെറ്റാ സിറ്റി " +"തയ്യാറാക്കിയത്\n" -#: ../src/metacity.schemas.in.h:108 -msgid "" -"The keybinding that switches to the workspace on the left of the current " -"workspace. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" +#: ../src/core/util.c:259 +msgid "Window manager: " +msgstr "ജാലക പാലകന്:‌" -#: ../src/metacity.schemas.in.h:109 -msgid "" -"The keybinding that switches to the workspace on the right of the current " -"workspace. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" +#: ../src/core/util.c:407 +msgid "Bug in window manager: " +msgstr "ജാലക പാലകനിലെ പിഴവ്: ‌" -#: ../src/metacity.schemas.in.h:110 -msgid "" -"The keybinding that switches to workspace 1. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: ../src/core/util.c:438 +msgid "Window manager warning: " +msgstr "ജാലക പാലകന്റെ മുന്നറിയിപ്പ്:‌" -#: ../src/metacity.schemas.in.h:111 -msgid "" -"The keybinding that switches to workspace 10. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: ../src/core/util.c:466 +msgid "Window manager error: " +msgstr "ജാലക പാലകന്റെ തെറ്റ്:‌‌" -#: ../src/metacity.schemas.in.h:112 +#. first time through +#: ../src/core/window.c:7539 +#, c-format msgid "" -"The keybinding that switches to workspace 11. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." +"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " +"window as specified in the ICCCM.\n" msgstr "" -#: ../src/metacity.schemas.in.h:113 +#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the +#. * authoritative source for that info. Some apps such as mplayer or +#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that +#. * leads to e.g. us not fullscreening their windows. Apps that set +#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain +#. * about these apps but make them work. +#. +#: ../src/core/window.c:8263 +#, c-format msgid "" -"The keybinding that switches to workspace 12. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." +"Window %s sets an MWM hint indicating it isn't resizable, but sets min size " +"%d x %d and max size %d x %d; this doesn't make much sense.\n" msgstr "" -#: ../src/metacity.schemas.in.h:114 -msgid "" -"The keybinding that switches to workspace 2. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." +#: ../src/core/window-props.c:318 +#, c-format +msgid "Application set a bogus _NET_WM_PID %lu\n" msgstr "" -#: ../src/metacity.schemas.in.h:115 -msgid "" -"The keybinding that switches to workspace 3. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: ../src/core/window-props.c:434 +#, c-format +msgid "%s (on %s)" +msgstr "%s (%s-ല്‍)" -#: ../src/metacity.schemas.in.h:116 -msgid "" -"The keybinding that switches to workspace 4. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." +#: ../src/core/window-props.c:1517 +#, c-format +msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" msgstr "" -#: ../src/metacity.schemas.in.h:117 -msgid "" -"The keybinding that switches to workspace 5. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." +#: ../src/core/window-props.c:1528 +#, c-format +msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" msgstr "" -#: ../src/metacity.schemas.in.h:118 +#: ../src/core/xprops.c:155 +#, c-format msgid "" -"The keybinding that switches to workspace 6. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." +"Window 0x%lx has property %s\n" +"that was expected to have type %s format %d\n" +"and actually has type %s format %d n_items %d.\n" +"This is most likely an application bug, not a window manager bug.\n" +"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" msgstr "" -#: ../src/metacity.schemas.in.h:119 -msgid "" -"The keybinding that switches to workspace 7. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." +#: ../src/core/xprops.c:411 +#, c-format +msgid "Property %s on window 0x%lx contained invalid UTF-8\n" msgstr "" -#: ../src/metacity.schemas.in.h:120 +#: ../src/core/xprops.c:494 +#, c-format msgid "" -"The keybinding that switches to workspace 8. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." +"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" msgstr "" -#: ../src/metacity.schemas.in.h:121 -msgid "" -"The keybinding that switches to workspace 9. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: ../src/mutter.desktop.in.h:1 ../src/mutter-wm.desktop.in.h:1 +msgid "Mutter" +msgstr "മട്ടര്‍" -#: ../src/metacity.schemas.in.h:122 -msgid "" -"The keybinding used to activate the window menu. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." +#: ../src/org.gnome.mutter.gschema.xml.in.h:1 +msgid "Modifier to use for extended window management operations" msgstr "" -#: ../src/metacity.schemas.in.h:123 +#: ../src/org.gnome.mutter.gschema.xml.in.h:2 msgid "" -"The keybinding used to close a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." +"This key will initiate the \"overlay\", which is a combination window " +"overview and application launching system. The default is intended to be the " +"\"Windows key\" on PC hardware. It's expected that this binding either the " +"default or set to the empty string." msgstr "" -#: ../src/metacity.schemas.in.h:124 -msgid "" -"The keybinding used to enter \"move mode\" and begin moving a window using " -"the keyboard. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" +#: ../src/org.gnome.mutter.gschema.xml.in.h:3 +msgid "Attach modal dialogs" +msgstr "മോഡല്‍ ഡയലോഗ് കൂട്ടിചേര്‍ക്കുക" -#: ../src/metacity.schemas.in.h:125 +#: ../src/org.gnome.mutter.gschema.xml.in.h:4 msgid "" -"The keybinding used to enter \"resize mode\" and begin resizing a window " -"using the keyboard. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." msgstr "" -#: ../src/metacity.schemas.in.h:126 -msgid "" -"The keybinding used to hide all normal windows and set the focus to the " -"desktop background. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." +#: ../src/org.gnome.mutter.gschema.xml.in.h:5 +msgid "Enable edge tiling when dropping windows on screen edges" msgstr "" -#: ../src/metacity.schemas.in.h:127 +#: ../src/org.gnome.mutter.gschema.xml.in.h:6 msgid "" -"The keybinding used to maximize a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." msgstr "" -#: ../src/metacity.schemas.in.h:128 -msgid "" -"The keybinding used to minimize a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." +#: ../src/org.gnome.mutter.gschema.xml.in.h:7 +msgid "Workspaces are managed dynamically" msgstr "" -#: ../src/metacity.schemas.in.h:129 +#: ../src/org.gnome.mutter.gschema.xml.in.h:8 msgid "" -"The keybinding used to move a window one workspace down. The format looks " -"like \"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -"fairly liberal and allows lower or upper case, and also abbreviations such " -"as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -"special string \"disabled\", then there will be no keybinding for this " -"action." +"Determines whether workspaces are managed dynamically or whether there's a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." msgstr "" -#: ../src/metacity.schemas.in.h:130 -msgid "" -"The keybinding used to move a window one workspace to the left. The format " -"looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -"parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." +#: ../src/org.gnome.mutter.gschema.xml.in.h:9 +msgid "Workspaces only on primary" msgstr "" -#: ../src/metacity.schemas.in.h:131 +#: ../src/org.gnome.mutter.gschema.xml.in.h:10 msgid "" -"The keybinding used to move a window one workspace to the right. The format " -"looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -"parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." msgstr "" -#: ../src/metacity.schemas.in.h:132 -msgid "" -"The keybinding used to move a window one workspace up. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: ../src/org.gnome.mutter.gschema.xml.in.h:11 +msgid "No tab popup" +msgstr "റ്റാബ് പോപ്പപ്പ് ലഭ്യമല്ല" -#: ../src/metacity.schemas.in.h:133 +#: ../src/org.gnome.mutter.gschema.xml.in.h:12 msgid "" -"The keybinding used to move a window to workspace 1. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." msgstr "" -#: ../src/metacity.schemas.in.h:134 -msgid "" -"The keybinding used to move a window to workspace 10. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." +#: ../src/org.gnome.mutter.gschema.xml.in.h:13 +msgid "Delay focus changes until the pointer stops moving" msgstr "" -#: ../src/metacity.schemas.in.h:135 +#: ../src/org.gnome.mutter.gschema.xml.in.h:14 msgid "" -"The keybinding used to move a window to workspace 11. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." +"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " +"the focus will not be changed immediately when entering a window, but only " +"after the pointer stops moving." msgstr "" -#: ../src/metacity.schemas.in.h:136 -msgid "" -"The keybinding used to move a window to workspace 12. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." +#: ../src/org.gnome.mutter.gschema.xml.in.h:15 +msgid "Draggable border width" msgstr "" -#: ../src/metacity.schemas.in.h:137 +#: ../src/org.gnome.mutter.gschema.xml.in.h:16 msgid "" -"The keybinding used to move a window to workspace 2. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." +"The amount of total draggable borders. If the theme's visible borders are " +"not enough, invisible borders will be added to meet this value." msgstr "" -#: ../src/metacity.schemas.in.h:138 -msgid "" -"The keybinding used to move a window to workspace 3. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." +#: ../src/org.gnome.mutter.gschema.xml.in.h:17 +msgid "Auto maximize nearly monitor sized windows" msgstr "" -#: ../src/metacity.schemas.in.h:139 +#: ../src/org.gnome.mutter.gschema.xml.in.h:18 msgid "" -"The keybinding used to move a window to workspace 4. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." msgstr "" -#: ../src/metacity.schemas.in.h:140 -msgid "" -"The keybinding used to move a window to workspace 5. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: ../src/org.gnome.mutter.gschema.xml.in.h:19 +msgid "Select window from tab popup" +msgstr "റ്റാബ് പോപ്പപ്പില്‍ നിന്നും ജാലകം തെരഞ്ഞെടുക്കുക" -#: ../src/metacity.schemas.in.h:141 -msgid "" -"The keybinding used to move a window to workspace 6. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: ../src/org.gnome.mutter.gschema.xml.in.h:20 +msgid "Cancel tab popup" +msgstr "റ്റാബ് പോപ്പപ്പ് റദ്ദാക്കുക" -#: ../src/metacity.schemas.in.h:142 -msgid "" -"The keybinding used to move a window to workspace 7. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: ../src/tools/mutter-message.c:123 +#, c-format +msgid "Usage: %s\n" +msgstr "ഉപയോഗം: %s\n" -#: ../src/metacity.schemas.in.h:143 -msgid "" -"The keybinding used to move a window to workspace 8. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:69 +msgid "Mi_nimize" +msgstr "ചെറുതാക്കുക (_n)" -#: ../src/metacity.schemas.in.h:144 -msgid "" -"The keybinding used to move a window to workspace 9. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:71 +msgid "Ma_ximize" +msgstr "വലുതാക്കുക (_x)" -#: ../src/metacity.schemas.in.h:145 -msgid "" -"The keybinding used to move focus backwards between panels and the desktop, " -"using a popup window. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:73 +msgid "Unma_ximize" +msgstr "വലുതാക്കിയതൊഴിവാക്കുക (_x)" -#: ../src/metacity.schemas.in.h:146 -msgid "" -"The keybinding used to move focus backwards between panels and the desktop, " -"without a popup window. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:75 +msgid "Roll _Up" +msgstr "ചുരുട്ടുക" -#: ../src/metacity.schemas.in.h:147 -msgid "" -"The keybinding used to move focus backwards between windows of an " -"application without a popup window. Holding \"shift\" together with this " -"binding makes the direction go forward again. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:77 +msgid "_Unroll" +msgstr "ചുരുളഴിക്കുക" -#: ../src/metacity.schemas.in.h:148 -msgid "" -"The keybinding used to move focus backwards between windows of an " -"application, using a popup window. Holding \"shift\" together with this " -"binding makes the direction go forward again. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:79 +msgid "_Move" +msgstr "നീക്കുക (_M)" -#: ../src/metacity.schemas.in.h:149 -msgid "" -"The keybinding used to move focus backwards between windows without a popup " -"window. Holding \"shift\" together with this binding makes the direction go " -"forward again. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:81 +msgid "_Resize" +msgstr "വലിപ്പം മാറ്റുക (_R)" -#: ../src/metacity.schemas.in.h:150 -msgid "" -"The keybinding used to move focus backwards between windows, using a popup " -"window. Holding \"shift\" together with this binding makes the direction go " -"forward again. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:83 +msgid "Move Titlebar On_screen" +msgstr "സ്ക്രീനിലേക്ക് തലക്കെട്ടിന്റെ ബാറ്‍ നീക്കുക (_s)" -#: ../src/metacity.schemas.in.h:151 -msgid "" -"The keybinding used to move focus between panels and the desktop, using a " -"popup window. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" +#. separator +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 +msgid "Always on _Top" +msgstr "എപ്പോഴും മുകളില്‍ (_T)" -#: ../src/metacity.schemas.in.h:152 -msgid "" -"The keybinding used to move focus between panels and the desktop, without a " -"popup window. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:90 +msgid "_Always on Visible Workspace" +msgstr "എപ്പോഴും ദൃശ്യമായ പണിയറയില്‍ (_A)" -#: ../src/metacity.schemas.in.h:153 -msgid "" -"The keybinding used to move focus between windows of an application without " -"a popup window. Holding the \"shift\" key while using this binding reverses " -"the direction of movement. The format looks like \"<Control>a\" or " -"\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -"lower or upper case, and also abbreviations such as \"<Ctl>\" and " -"\"<Ctrl>\". If you set the option to the special string \"disabled\", " -"then there will be no keybinding for this action." -msgstr "" +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:92 +msgid "_Only on This Workspace" +msgstr "ഈ പണിയറയില്‍ മാത്രം (_O)" -#: ../src/metacity.schemas.in.h:154 -msgid "" -"The keybinding used to move focus between windows of an application, using a " -"popup window. (Traditionally <Alt>F6) Holding the \"shift\" key while " -"using this binding reverses the direction of movement. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:94 +msgid "Move to Workspace _Left" +msgstr "ഇടത്തുളള പണിയറയിലേക്ക് നീങ്ങുക (_L)" -#: ../src/metacity.schemas.in.h:155 -msgid "" -"The keybinding used to move focus between windows without a popup window. " -"(Traditionally <Alt>Escape) Holding the \"shift\" key while using this " -"binding reverses the direction of movement. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:96 +msgid "Move to Workspace R_ight" +msgstr "വലത്തുളള പണിയറയിലേക്ക് നീങ്ങുക (_R)" -#: ../src/metacity.schemas.in.h:156 -msgid "" -"The keybinding used to move focus between windows, using a popup window. " -"(Traditionally <Alt>Tab) Holding the \"shift\" key while using this " -"binding reverses the direction of movement. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:98 +msgid "Move to Workspace _Up" +msgstr "മുകളിലുളള പണിയറയിലേക്ക് നീങ്ങുക (_U)" -#: ../src/metacity.schemas.in.h:157 -msgid "" -"The keybinding used to toggle always on top. A window that is always on top " -"will always be visible over other overlapping windows. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:100 +msgid "Move to Workspace _Down" +msgstr "താഴെയുളള പണിയറയിലേക്ക് നീങ്ങുക (_D)" -#: ../src/metacity.schemas.in.h:158 -msgid "" -"The keybinding used to toggle fullscreen mode. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#. separator +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:104 +msgid "_Close" +msgstr "അടയ്ക്കുക (_C)" -#: ../src/metacity.schemas.in.h:159 -msgid "" -"The keybinding used to toggle maximization. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: ../src/ui/menu.c:204 +#, c-format +msgid "Workspace %d%n" +msgstr "പണിയറ %d%n" -#: ../src/metacity.schemas.in.h:160 -msgid "" -"The keybinding used to toggle shaded/unshaded state. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: ../src/ui/menu.c:214 +#, c-format +msgid "Workspace 1_0" +msgstr "പണിയറ 1_0" -#: ../src/metacity.schemas.in.h:161 -msgid "" -"The keybinding used to toggle whether the window is on all workspaces or " -"just one. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" +#: ../src/ui/menu.c:216 +#, c-format +msgid "Workspace %s%d" +msgstr "പണിയറ %s%d" -#: ../src/metacity.schemas.in.h:162 -msgid "" -"The keybinding used to unmaximize a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: ../src/ui/menu.c:397 +msgid "Move to Another _Workspace" +msgstr "മറ്റൊരു പണിയറയിലേക്ക് നീങ്ങുക (_W)" -#: ../src/metacity.schemas.in.h:163 -msgid "" -"The keybinding which display's the panel's \"Run Application\" dialog box. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" +#. This is the text that should appear next to menu accelerators +#. * that use the shift key. If the text on this key isn't typically +#. * translated on keyboards used for your language, don't translate +#. * this. +#. +#: ../src/ui/metaaccellabel.c:77 +msgid "Shift" +msgstr "മാറ്റുക" -#: ../src/metacity.schemas.in.h:164 -msgid "" -"The keybinding which invokes a terminal. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#. This is the text that should appear next to menu accelerators +#. * that use the control key. If the text on this key isn't typically +#. * translated on keyboards used for your language, don't translate +#. * this. +#. +#: ../src/ui/metaaccellabel.c:83 +msgid "Ctrl" +msgstr "നിയന്ത്രണം" -#: ../src/metacity.schemas.in.h:165 -msgid "" -"The keybinding which invokes the panel's screenshot utility to take a " -"screenshot of a window. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" +#. This is the text that should appear next to menu accelerators +#. * that use the alt key. If the text on this key isn't typically +#. * translated on keyboards used for your language, don't translate +#. * this. +#. +#: ../src/ui/metaaccellabel.c:89 +msgid "Alt" +msgstr "Alt" -#: ../src/metacity.schemas.in.h:166 -msgid "" -"The keybinding which invokes the panel's screenshot utility. The format " -"looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -"parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" +#. This is the text that should appear next to menu accelerators +#. * that use the meta key. If the text on this key isn't typically +#. * translated on keyboards used for your language, don't translate +#. * this. +#. +#: ../src/ui/metaaccellabel.c:95 +msgid "Meta" +msgstr "Meta" -#: ../src/metacity.schemas.in.h:167 -msgid "" -"The keybinding which shows the panel's main menu. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#. This is the text that should appear next to menu accelerators +#. * that use the super key. If the text on this key isn't typically +#. * translated on keyboards used for your language, don't translate +#. * this. +#. +#: ../src/ui/metaaccellabel.c:101 +msgid "Super" +msgstr "Super" -#: ../src/metacity.schemas.in.h:168 -msgid "The name of a workspace." -msgstr "പണിയറുടെ പേര‍്" +#. This is the text that should appear next to menu accelerators +#. * that use the hyper key. If the text on this key isn't typically +#. * translated on keyboards used for your language, don't translate +#. * this. +#. +#: ../src/ui/metaaccellabel.c:107 +msgid "Hyper" +msgstr "Hyper" -#: ../src/metacity.schemas.in.h:169 -msgid "The screenshot command" -msgstr "സ്ക്രീന്‍ ഷോട്ടിനുള്ള കമാന്‍ഡ്" +#. This is the text that should appear next to menu accelerators +#. * that use the mod2 key. If the text on this key isn't typically +#. * translated on keyboards used for your language, don't translate +#. * this. +#. +#: ../src/ui/metaaccellabel.c:113 +msgid "Mod2" +msgstr "Mod2" -#: ../src/metacity.schemas.in.h:170 -msgid "" -"The theme determines the appearance of window borders, titlebar, and so " -"forth." -msgstr "" +#. This is the text that should appear next to menu accelerators +#. * that use the mod3 key. If the text on this key isn't typically +#. * translated on keyboards used for your language, don't translate +#. * this. +#. +#: ../src/ui/metaaccellabel.c:119 +msgid "Mod3" +msgstr "Mod3" -#: ../src/metacity.schemas.in.h:171 -msgid "" -"The time delay before raising a window if auto_raise is set to true. The " -"delay is given in thousandths of a second." -msgstr "" +#. This is the text that should appear next to menu accelerators +#. * that use the mod4 key. If the text on this key isn't typically +#. * translated on keyboards used for your language, don't translate +#. * this. +#. +#: ../src/ui/metaaccellabel.c:125 +msgid "Mod4" +msgstr "Mod4" -#: ../src/metacity.schemas.in.h:172 -msgid "" -"The window focus mode indicates how windows are activated. It has three " -"possible values; \"click\" means windows must be clicked in order to focus " -"them, \"sloppy\" means windows are focused when the mouse enters the window, " -"and \"mouse\" means windows are focused when the mouse enters the window and " -"unfocused when the mouse leaves the window." -msgstr "" +#. This is the text that should appear next to menu accelerators +#. * that use the mod5 key. If the text on this key isn't typically +#. * translated on keyboards used for your language, don't translate +#. * this. +#. +#: ../src/ui/metaaccellabel.c:131 +msgid "Mod5" +msgstr "Mod5" -#: ../src/metacity.schemas.in.h:173 -msgid "The window screenshot command" -msgstr "ജാലകത്തിന്റെ സ്ക്രീന്‍ഷോട്ടിനുള്ള കമാന്‍ഡ്" +#. Translators: This represents the size of a window. The first number is +#. * the width of the window and the second is the height. +#. +#: ../src/ui/resizepopup.c:136 +#, c-format +msgid "%d x %d" +msgstr "%d x %d" -#: ../src/metacity.schemas.in.h:174 -msgid "" -"This keybinding changes whether a window is above or below other windows. If " -"the window is covered by another one, it raises the window above all others, " -"and if the window is already fully visible, it lowers it below all others. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" +#: ../src/ui/theme.c:235 +msgid "top" +msgstr "മുകളില്‌" -#: ../src/metacity.schemas.in.h:175 -msgid "" -"This keybinding lowers a window below other windows. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: ../src/ui/theme.c:237 +msgid "bottom" +msgstr "താഴെ" -#: ../src/metacity.schemas.in.h:176 -msgid "" -"This keybinding moves a window against the north (top) side of the screen. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" +#: ../src/ui/theme.c:239 +msgid "left" +msgstr "ഇടത്" -#: ../src/metacity.schemas.in.h:177 -msgid "" -"This keybinding moves a window into the east (right) side of the screen. The " -"format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" +#: ../src/ui/theme.c:241 +msgid "right" +msgstr "വലത്" -#: ../src/metacity.schemas.in.h:178 -msgid "" -"This keybinding moves a window into the north-east (top right) corner of the " -"screen. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." +#: ../src/ui/theme.c:269 +#, c-format +msgid "frame geometry does not specify \"%s\" dimension" msgstr "" -#: ../src/metacity.schemas.in.h:179 -msgid "" -"This keybinding moves a window into the north-west (top left) corner of the " -"screen. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." +#: ../src/ui/theme.c:288 +#, c-format +msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" msgstr "" -#: ../src/metacity.schemas.in.h:180 -msgid "" -"This keybinding moves a window into the south (bottom) side of the screen. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." +#: ../src/ui/theme.c:325 +#, c-format +msgid "Button aspect ratio %g is not reasonable" msgstr "" -#: ../src/metacity.schemas.in.h:181 -msgid "" -"This keybinding moves a window into the south-east (bottom right) corner of " -"the screen. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." +#: ../src/ui/theme.c:337 +#, c-format +msgid "Frame geometry does not specify size of buttons" msgstr "" -#: ../src/metacity.schemas.in.h:182 -msgid "" -"This keybinding moves a window into the south-west (bottom left) corner of " -"the screen. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." +#: ../src/ui/theme.c:1050 +#, c-format +msgid "Gradients should have at least two colors" msgstr "" -#: ../src/metacity.schemas.in.h:183 +#: ../src/ui/theme.c:1202 +#, c-format msgid "" -"This keybinding moves a window into the west (left) side of the screen. The " -"format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." +"GTK custom color specification must have color name and fallback in " +"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" msgstr "" -#: ../src/metacity.schemas.in.h:184 +#: ../src/ui/theme.c:1218 +#, c-format msgid "" -"This keybinding raises the window above other windows. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." +"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" +"_ are valid" msgstr "" -#: ../src/metacity.schemas.in.h:185 +#: ../src/ui/theme.c:1232 +#, c-format msgid "" -"This keybinding resizes a window to fill available horizontal space. The " -"format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." +"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " +"fit the format" msgstr "" -#: ../src/metacity.schemas.in.h:186 +#: ../src/ui/theme.c:1277 +#, c-format msgid "" -"This keybinding resizes a window to fill available vertical space. The " -"format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." +"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " +"where NORMAL is the state; could not parse \"%s\"" msgstr "" -#: ../src/metacity.schemas.in.h:187 +#: ../src/ui/theme.c:1291 +#, c-format msgid "" -"This option determines the effects of double-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, 'toggle_maximize' which will maximize/unmaximize the window, " -"'minimize' which will minimize the window, and 'none' which will not do " -"anything." +"GTK color specification must have a close bracket after the state, e.g. gtk:" +"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" msgstr "" -#: ../src/metacity.schemas.in.h:188 -msgid "" -"This option determines the effects of middle-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, 'toggle_maximize' which will maximize/unmaximize the window, " -"'minimize' which will minimize the window, and 'none' which will not do " -"anything." +#: ../src/ui/theme.c:1302 +#, c-format +msgid "Did not understand state \"%s\" in color specification" msgstr "" -#: ../src/metacity.schemas.in.h:189 -msgid "" -"This option determines the effects of right-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, 'toggle_maximize' which will maximize/unmaximize the window, " -"'minimize' which will minimize the window, and 'none' which will not do " -"anything." +#: ../src/ui/theme.c:1315 +#, c-format +msgid "Did not understand color component \"%s\" in color specification" msgstr "" -#: ../src/metacity.schemas.in.h:190 +#: ../src/ui/theme.c:1344 +#, c-format msgid "" -"This option provides additional control over how newly created windows get " -"focus. It has two possible values; \"smart\" applies the user's normal focus " -"mode, and \"strict\" results in windows started from a terminal not being " -"given focus." -msgstr "" - -#: ../src/metacity.schemas.in.h:191 -msgid "Toggle always on top state" +"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " +"format" msgstr "" -#: ../src/metacity.schemas.in.h:192 -msgid "Toggle fullscreen mode" -msgstr "അക്ഷര വിവര രീതിയില്‌ അളവ് ദൃശ്യമാക്കുക" - -#: ../src/metacity.schemas.in.h:193 -msgid "Toggle maximization state" +#: ../src/ui/theme.c:1355 +#, c-format +msgid "Could not parse alpha value \"%s\" in blended color" msgstr "" -#: ../src/metacity.schemas.in.h:194 -msgid "Toggle shaded state" +#: ../src/ui/theme.c:1365 +#, c-format +msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" msgstr "" -#: ../src/metacity.schemas.in.h:195 -msgid "Toggle window on all workspaces" -msgstr "എല്ലാ പണിയറകളിലെയും ജാലകങ്ങള് കാണിക്കുക" - -#: ../src/metacity.schemas.in.h:196 +#: ../src/ui/theme.c:1412 +#, c-format msgid "" -"Turns on a visual indication when an application or the system issues a " -"'bell' or 'beep'; useful for the hard-of-hearing and for use in noisy " -"environments." -msgstr "" - -#: ../src/metacity.schemas.in.h:197 -msgid "Unmaximize window" -msgstr "ജാലകം ചെറുതാക്കുക " - -#: ../src/metacity.schemas.in.h:198 -msgid "Use standard system font in window titles" +"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" msgstr "" -#: ../src/metacity.schemas.in.h:199 -msgid "Visual Bell Type" -msgstr "" - -#: ../src/metacity.schemas.in.h:200 -msgid "Whether raising should be a side-effect of other user interactions" -msgstr "" - -#: ../src/metacity.schemas.in.h:201 -msgid "Window focus mode" -msgstr "ജാലക കേന്ദ്രീകരണരീതി" - -#: ../src/metacity.schemas.in.h:202 -msgid "Window title font" -msgstr "ജാലക തലക്കെട്ട് അക്ഷരരൂപം" - -#: ../src/prefs.c:434 +#: ../src/ui/theme.c:1423 #, c-format -msgid "Type of %s was not integer" +msgid "Could not parse shade factor \"%s\" in shaded color" msgstr "" -#: ../src/prefs.c:572 ../src/prefs.c:600 ../src/prefs.c:616 ../src/prefs.c:632 -#: ../src/prefs.c:648 ../src/prefs.c:664 ../src/prefs.c:680 ../src/prefs.c:696 -#: ../src/prefs.c:716 ../src/prefs.c:732 ../src/prefs.c:748 ../src/prefs.c:766 -#: ../src/prefs.c:782 ../src/prefs.c:801 ../src/prefs.c:817 ../src/prefs.c:852 -#: ../src/prefs.c:868 ../src/prefs.c:885 ../src/prefs.c:901 ../src/prefs.c:917 -#: ../src/prefs.c:933 ../src/prefs.c:949 ../src/prefs.c:964 ../src/prefs.c:979 -#: ../src/prefs.c:994 ../src/prefs.c:1010 ../src/prefs.c:1026 -#: ../src/prefs.c:1042 ../src/prefs.c:1058 +#: ../src/ui/theme.c:1433 #, c-format -msgid "GConf key \"%s\" is set to an invalid type\n" +msgid "Shade factor \"%s\" in shaded color is negative" msgstr "" -#: ../src/prefs.c:1103 +#: ../src/ui/theme.c:1462 #, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" +msgid "Could not parse color \"%s\"" +msgstr "\"%s\" നിറം പാഴ്സ് ചെയ്യുക" -#: ../src/prefs.c:1127 ../src/prefs.c:1148 ../src/prefs.c:1705 +#: ../src/ui/theme.c:1779 #, c-format -msgid "GConf key '%s' is set to an invalid value\n" +msgid "Coordinate expression contains character '%s' which is not allowed" msgstr "" -#: ../src/prefs.c:1277 +#: ../src/ui/theme.c:1806 #, c-format msgid "" -"%d stored in GConf key %s is not a reasonable cursor_size; must be in the " -"range 1..128\n" +"Coordinate expression contains floating point number '%s' which could not be " +"parsed" msgstr "" -#: ../src/prefs.c:1357 +#: ../src/ui/theme.c:1820 #, c-format -msgid "Could not parse font description \"%s\" from GConf key %s\n" +msgid "Coordinate expression contains integer '%s' which could not be parsed" msgstr "" -#: ../src/prefs.c:1599 +#: ../src/ui/theme.c:1941 #, c-format msgid "" -"%d stored in GConf key %s is not a reasonable number of workspaces, current " -"maximum is %d\n" -msgstr "" - -#: ../src/prefs.c:1659 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" +"Coordinate expression contained unknown operator at the start of this text: " +"\"%s\"" msgstr "" -#: ../src/prefs.c:1732 +#: ../src/ui/theme.c:1998 #, c-format -msgid "%d stored in GConf key %s is out of range 0 to %d\n" +msgid "Coordinate expression was empty or not understood" msgstr "" -#: ../src/prefs.c:1881 +#: ../src/ui/theme.c:2111 ../src/ui/theme.c:2121 ../src/ui/theme.c:2155 #, c-format -msgid "Error setting number of workspaces to %d: %s\n" +msgid "Coordinate expression results in division by zero" msgstr "" -#: ../src/prefs.c:2276 ../src/prefs.c:2446 +#: ../src/ui/theme.c:2163 #, c-format msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" +"Coordinate expression tries to use mod operator on a floating-point number" msgstr "" -#: ../src/prefs.c:2861 +#: ../src/ui/theme.c:2219 #, c-format -msgid "Error setting name for workspace %d to \"%s\": %s\n" -msgstr "%d യില്‌നിന്ന് \"%s\"ലേക്ക് പണിയറയുടെ പേ‌ര‌് സജ്ജമാക്കുന്നതില്‌ തെറ്റ്: %s\n" +msgid "" +"Coordinate expression has an operator \"%s\" where an operand was expected" +msgstr "" -#: ../src/resizepopup.c:113 +#: ../src/ui/theme.c:2228 #, c-format -msgid "%d x %d" -msgstr "%d x %d" +msgid "Coordinate expression had an operand where an operator was expected" +msgstr "" -#: ../src/screen.c:410 +#: ../src/ui/theme.c:2236 #, c-format -msgid "Screen %d on display '%s' is invalid\n" +msgid "Coordinate expression ended with an operator instead of an operand" msgstr "" -#: ../src/screen.c:426 +#: ../src/ui/theme.c:2246 #, c-format msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" +"Coordinate expression has operator \"%c\" following operator \"%c\" with no " +"operand in between" msgstr "" -#: ../src/screen.c:453 +#: ../src/ui/theme.c:2397 ../src/ui/theme.c:2442 #, c-format -msgid "Could not acquire window manager selection on screen %d display \"%s\"\n" +msgid "Coordinate expression had unknown variable or constant \"%s\"" msgstr "" -#: ../src/screen.c:511 +#: ../src/ui/theme.c:2496 #, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" +msgid "Coordinate expression parser overflowed its buffer." msgstr "" -#: ../src/screen.c:716 +#: ../src/ui/theme.c:2525 #, c-format -msgid "Could not release screen %d on display \"%s\"\n" +msgid "Coordinate expression had a close parenthesis with no open parenthesis" msgstr "" -#: ../src/session.c:826 ../src/session.c:833 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "'%s'എന്ന കൂട് ഉണ്ടാക്കാന്‌ കഴിയുന്നില്ല: %s\n" - -#: ../src/session.c:843 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "%s എഴുതാനായി തുറക്കുന്നതില്‌ %s പരാജയം\n" - -#: ../src/session.c:995 +#: ../src/ui/theme.c:2589 #, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "'%s' രചനാ എഴുതുന്നതില്‌ പരാജയം: %s\n" +msgid "Coordinate expression had an open parenthesis with no close parenthesis" +msgstr "" -#: ../src/session.c:1000 +#: ../src/ui/theme.c:2600 #, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "'%s' രചന അട‌യ്‌ക്കുന്നതില്‌‌ പരാജയം: %s\n" +msgid "Coordinate expression doesn't seem to have any operators or operands" +msgstr "" -#: ../src/session.c:1075 +#: ../src/ui/theme.c:2813 ../src/ui/theme.c:2833 ../src/ui/theme.c:2853 #, c-format -msgid "Failed to read saved session file %s: %s\n" -msgstr "രചന %sലെ പ്രമേയം വായിക്കുന്നതില്‌ പരാജയപ്പെട്ടു: %s\n" +msgid "Theme contained an expression that resulted in an error: %s\n" +msgstr "" -#: ../src/session.c:1110 +#: ../src/ui/theme.c:4499 #, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "രചന വായിക്കുന്നതില്‌ പരാജയപ്പെട്ടു: %s\n" - -#: ../src/session.c:1159 -msgid "<metacity_session> attribute seen but we already have the session ID" +msgid "" +"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " +"specified for this frame style" msgstr "" -#: ../src/session.c:1172 +#: ../src/ui/theme.c:5010 ../src/ui/theme.c:5035 #, c-format -msgid "Unknown attribute %s on <metacity_session> element" +msgid "" +"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" msgstr "" +"<frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/> ലഭ്യമല്ല" -#: ../src/session.c:1189 -msgid "nested <window> tag" -msgstr "തരക്കെട്ടില്ലാത്ത ജാലകം" +#: ../src/ui/theme.c:5083 +#, c-format +msgid "Failed to load theme \"%s\": %s\n" +msgstr "പ്രമേയം %s കൊണ്ട് വരാന് കഴിഞ്ഞില്ല: %s\n" -#: ../src/session.c:1247 ../src/session.c:1279 +#: ../src/ui/theme.c:5219 ../src/ui/theme.c:5226 ../src/ui/theme.c:5233 +#: ../src/ui/theme.c:5240 ../src/ui/theme.c:5247 #, c-format -msgid "Unknown attribute %s on <window> element" -msgstr "" +msgid "No <%s> set for theme \"%s\"" +msgstr "<%s>, \"%s\"-നു് സജ്ജമല്ല" -#: ../src/session.c:1351 +#: ../src/ui/theme.c:5255 #, c-format -msgid "Unknown attribute %s on <maximized> element" +msgid "" +"No frame style set for window type \"%s\" in theme \"%s\", add a <window " +"type=\"%s\" style_set=\"whatever\"/> element" msgstr "" -#: ../src/session.c:1411 +#: ../src/ui/theme.c:5662 ../src/ui/theme.c:5724 ../src/ui/theme.c:5787 #, c-format -msgid "Unknown attribute %s on <geometry> element" +msgid "" +"User-defined constants must begin with a capital letter; \"%s\" does not" msgstr "" -#: ../src/session.c:1431 +#: ../src/ui/theme.c:5670 ../src/ui/theme.c:5732 ../src/ui/theme.c:5795 #, c-format -msgid "Unknown element %s" -msgstr "%s ന്റെ അറിയാത്ത ഘടകം" +msgid "Constant \"%s\" has already been defined" +msgstr "" -#: ../src/session.c:1868 +#. Translators: This means that an attribute which should have been found +#. * on an XML element was not in fact found. +#. +#: ../src/ui/theme-parser.c:236 #, c-format -msgid "" -"Error launching metacity-dialog to warn about apps that don't support " -"session management: %s\n" -msgstr "" +msgid "No \"%s\" attribute on element <%s>" +msgstr "<%s> എലമെന്‍റില്‍ \"%s\" ആട്രിബ്യൂട്ട് ഇല്ല" -#: ../src/theme-parser.c:227 ../src/theme-parser.c:245 +#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 #, c-format msgid "Line %d character %d: %s" msgstr "%d-ആം വരി %d എന്ന അക്ഷരം: %s" -#: ../src/theme-parser.c:399 +#: ../src/ui/theme-parser.c:479 #, c-format msgid "Attribute \"%s\" repeated twice on the same <%s> element" msgstr "" -#: ../src/theme-parser.c:417 ../src/theme-parser.c:442 +#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 #, c-format msgid "Attribute \"%s\" is invalid on <%s> element in this context" +msgstr "ഇവിടെ <%s> എന്ന എലമെന്‍റില്‍ \"%s\" ആട്ട്രിബ്യൂട്ട് അസാധുവാണ്." + +#: ../src/ui/theme-parser.c:594 +#, c-format +msgid "Could not parse \"%s\" as an integer" +msgstr "%s നെ ഒരു സംഖ്യയായി വേ‌ര്തിരിക്കാന്‌ കഴിയുഞ്ഞില്ല" + +#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 +#, c-format +msgid "Did not understand trailing characters \"%s\" in string \"%s\"" msgstr "" -#: ../src/theme-parser.c:503 +#: ../src/ui/theme-parser.c:613 #, c-format msgid "Integer %ld must be positive" -msgstr "" +msgstr "%ld ഇന്റിജര്‍ പോസിറ്റീവായിരിയ്ക്കണം" -#: ../src/theme-parser.c:511 +#: ../src/ui/theme-parser.c:621 #, c-format msgid "Integer %ld is too large, current max is %d" msgstr "" -#: ../src/theme-parser.c:539 ../src/theme-parser.c:655 +#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 #, c-format msgid "Could not parse \"%s\" as a floating point number" msgstr "%s നെ ഒരു സംഖ്യയായി വേ‌ര്തിരിക്കാന്‌ കഴിയുഞ്ഞില്ല" -#: ../src/theme-parser.c:570 ../src/theme-parser.c:598 +#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 #, c-format msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" msgstr "" -#: ../src/theme-parser.c:625 +#: ../src/ui/theme-parser.c:735 #, c-format msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "" +msgstr "കോണ്‍ 0.0 തിനും 360.0 നും ഇടയിലായിരിക്കണം, പക്ഷേ ഇവിടെ %g ആയിരുന്നു\n" -#: ../src/theme-parser.c:688 +#: ../src/ui/theme-parser.c:798 #, c-format msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" msgstr "" -#: ../src/theme-parser.c:753 +#: ../src/ui/theme-parser.c:863 #, c-format msgid "" "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," "large,x-large,xx-large)\n" msgstr "" -#: ../src/theme-parser.c:798 ../src/theme-parser.c:806 -#: ../src/theme-parser.c:888 ../src/theme-parser.c:985 -#: ../src/theme-parser.c:1027 ../src/theme-parser.c:1138 -#: ../src/theme-parser.c:1188 ../src/theme-parser.c:1196 -#: ../src/theme-parser.c:3074 ../src/theme-parser.c:3163 -#: ../src/theme-parser.c:3170 ../src/theme-parser.c:3177 -#, c-format -msgid "No \"%s\" attribute on <%s> element" -msgstr "" - -#: ../src/theme-parser.c:922 ../src/theme-parser.c:993 -#: ../src/theme-parser.c:1035 ../src/theme-parser.c:1146 +#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 +#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 #, c-format msgid "<%s> name \"%s\" used a second time" msgstr "<%s> പേര് \"%s\" രണ്ടാം തവണ ഉപയോഗിച്ചിരിക്കുന്നു" -#: ../src/theme-parser.c:934 ../src/theme-parser.c:1047 -#: ../src/theme-parser.c:1158 +#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 +#: ../src/ui/theme-parser.c:1231 #, c-format msgid "<%s> parent \"%s\" has not been defined" msgstr "<%s> പേരന്റ് \"%s\" വ്യക്തമാക്കിയിട്ടില്ല" -#: ../src/theme-parser.c:1060 +#: ../src/ui/theme-parser.c:1141 #, c-format msgid "<%s> geometry \"%s\" has not been defined" msgstr "" -#: ../src/theme-parser.c:1073 +#: ../src/ui/theme-parser.c:1154 #, c-format msgid "<%s> must specify either a geometry or a parent that has a geometry" msgstr "" -#: ../src/theme-parser.c:1115 +#: ../src/ui/theme-parser.c:1196 msgid "You must specify a background for an alpha value to be meaningful" msgstr "" -#: ../src/theme-parser.c:1206 +#: ../src/ui/theme-parser.c:1264 #, c-format msgid "Unknown type \"%s\" on <%s> element" -msgstr "" +msgstr "അപരിചിതമായ \"%s\" തരം <%s> എലമെന്റില്‍" -#: ../src/theme-parser.c:1217 +#: ../src/ui/theme-parser.c:1275 #, c-format msgid "Unknown style_set \"%s\" on <%s> element" msgstr "" -#: ../src/theme-parser.c:1225 +#: ../src/ui/theme-parser.c:1283 #, c-format msgid "Window type \"%s\" has already been assigned a style set" msgstr "" -#: ../src/theme-parser.c:1261 -msgid "Theme already has a fallback icon" -msgstr "" - -#: ../src/theme-parser.c:1273 -msgid "Theme already has a fallback mini_icon" -msgstr "" - -#: ../src/theme-parser.c:1286 ../src/theme-parser.c:1350 -#: ../src/theme-parser.c:1639 ../src/theme-parser.c:3262 -#: ../src/theme-parser.c:3316 ../src/theme-parser.c:3488 -#: ../src/theme-parser.c:3704 ../src/theme-parser.c:3742 -#: ../src/theme-parser.c:3780 ../src/theme-parser.c:3818 +#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 +#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 +#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 +#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 +#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 #, c-format msgid "Element <%s> is not allowed below <%s>" -msgstr "" - -#: ../src/theme-parser.c:1376 ../src/theme-parser.c:1463 -#: ../src/theme-parser.c:1533 -#, c-format -msgid "No \"name\" attribute on element <%s>" -msgstr "" +msgstr "<%s>-ന്‍റെ കീഴില്‍ <%s> എന്ന എലമെന്‍റിന് അനുവാദമില്ല" -#: ../src/theme-parser.c:1383 ../src/theme-parser.c:1470 -#, c-format -msgid "No \"value\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:1414 ../src/theme-parser.c:1428 -#: ../src/theme-parser.c:1487 -msgid "Cannot specify both button_width/button_height and aspect ratio for buttons" +#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 +#: ../src/ui/theme-parser.c:1486 +msgid "" +"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " +"for buttons" msgstr "" -#: ../src/theme-parser.c:1437 +#: ../src/ui/theme-parser.c:1450 #, c-format msgid "Distance \"%s\" is unknown" msgstr "\"%s\" എന്ന ദൂരം അപരിചിതമാണ്" -#: ../src/theme-parser.c:1496 +#: ../src/ui/theme-parser.c:1495 #, c-format msgid "Aspect ratio \"%s\" is unknown" msgstr "\"%s\" എന്ന ആസ്പെക്റ്റ് റേഷ്യോ അപരിചിതമാണ്" -#: ../src/theme-parser.c:1540 -#, c-format -msgid "No \"top\" attribute on element <%s>" -msgstr "\"മുകളില്‍\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" - -#: ../src/theme-parser.c:1547 -#, c-format -msgid "No \"bottom\" attribute on element <%s>" -msgstr "\"താഴെ\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" - -#: ../src/theme-parser.c:1554 -#, c-format -msgid "No \"left\" attribute on element <%s>" -msgstr "\"ഇടത്\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" - -#: ../src/theme-parser.c:1561 -#, c-format -msgid "No \"right\" attribute on element <%s>" -msgstr "\"വലത്\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" - -#: ../src/theme-parser.c:1593 +#: ../src/ui/theme-parser.c:1557 #, c-format msgid "Border \"%s\" is unknown" msgstr "\"%s\" എന്ന അതിര് അപരിചിതമാണ്" -#: ../src/theme-parser.c:1746 ../src/theme-parser.c:1856 -#: ../src/theme-parser.c:1963 ../src/theme-parser.c:2190 -#: ../src/theme-parser.c:3007 -#, c-format -msgid "No \"color\" attribute on element <%s>" -msgstr "\"നിറം\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" - -#: ../src/theme-parser.c:1753 -#, c-format -msgid "No \"x1\" attribute on element <%s>" -msgstr "\"x1\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" - -#: ../src/theme-parser.c:1760 ../src/theme-parser.c:2852 -#, c-format -msgid "No \"y1\" attribute on element <%s>" -msgstr "\"y1\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" - -#: ../src/theme-parser.c:1767 -#, c-format -msgid "No \"x2\" attribute on element <%s>" -msgstr "\"x2\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" - -#: ../src/theme-parser.c:1774 ../src/theme-parser.c:2859 -#, c-format -msgid "No \"y2\" attribute on element <%s>" -msgstr "\"y2\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" - -#: ../src/theme-parser.c:1863 ../src/theme-parser.c:1970 -#: ../src/theme-parser.c:2116 ../src/theme-parser.c:2197 -#: ../src/theme-parser.c:2303 ../src/theme-parser.c:2401 -#: ../src/theme-parser.c:2621 ../src/theme-parser.c:2747 -#: ../src/theme-parser.c:2845 ../src/theme-parser.c:2919 -#: ../src/theme-parser.c:3014 -#, c-format -msgid "No \"x\" attribute on element <%s>" -msgstr "\"x\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" - -#: ../src/theme-parser.c:1870 ../src/theme-parser.c:1977 -#: ../src/theme-parser.c:2123 ../src/theme-parser.c:2204 -#: ../src/theme-parser.c:2310 ../src/theme-parser.c:2408 -#: ../src/theme-parser.c:2628 ../src/theme-parser.c:2754 -#: ../src/theme-parser.c:2926 ../src/theme-parser.c:3021 -#, c-format -msgid "No \"y\" attribute on element <%s>" -msgstr "\"y\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" - -#: ../src/theme-parser.c:1877 ../src/theme-parser.c:1984 -#: ../src/theme-parser.c:2130 ../src/theme-parser.c:2211 -#: ../src/theme-parser.c:2317 ../src/theme-parser.c:2415 -#: ../src/theme-parser.c:2635 ../src/theme-parser.c:2761 -#: ../src/theme-parser.c:2933 -#, c-format -msgid "No \"width\" attribute on element <%s>" -msgstr "\"വീതി\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" - -#: ../src/theme-parser.c:1884 ../src/theme-parser.c:1991 -#: ../src/theme-parser.c:2137 ../src/theme-parser.c:2218 -#: ../src/theme-parser.c:2324 ../src/theme-parser.c:2422 -#: ../src/theme-parser.c:2642 ../src/theme-parser.c:2768 -#: ../src/theme-parser.c:2940 -#, c-format -msgid "No \"height\" attribute on element <%s>" -msgstr "\"ഉയരം\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" - -#: ../src/theme-parser.c:2000 +#: ../src/ui/theme-parser.c:1868 #, c-format msgid "No \"start_angle\" or \"from\" attribute on element <%s>" msgstr "" -#: ../src/theme-parser.c:2007 +#: ../src/ui/theme-parser.c:1875 #, c-format msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" msgstr "" -#: ../src/theme-parser.c:2016 -#, c-format -msgid "No \"start_angle\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:2023 -#, c-format -msgid "No \"extent_angle\" attribute on element <%s>" -msgstr "" - -#: ../src/theme-parser.c:2225 -#, c-format -msgid "No \"alpha\" attribute on element <%s>" -msgstr "\"ആല്‍ഫാ\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" - -#: ../src/theme-parser.c:2296 -#, c-format -msgid "No \"type\" attribute on element <%s>" -msgstr "\"ഏത് തരം\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" - -#: ../src/theme-parser.c:2344 +#: ../src/ui/theme-parser.c:2115 #, c-format msgid "Did not understand value \"%s\" for type of gradient" msgstr "" -#: ../src/theme-parser.c:2429 -#, c-format -msgid "No \"filename\" attribute on element <%s>" -msgstr "\"ഫയലിന്റെ പേര്\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" - -#: ../src/theme-parser.c:2454 ../src/theme-parser.c:2965 +#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 #, c-format msgid "Did not understand fill type \"%s\" for <%s> element" msgstr "" -#: ../src/theme-parser.c:2600 ../src/theme-parser.c:2733 -#: ../src/theme-parser.c:2838 -#, c-format -msgid "No \"state\" attribute on element <%s>" -msgstr "\"അവസ്ഥ\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" - -#: ../src/theme-parser.c:2607 ../src/theme-parser.c:2740 -#, c-format -msgid "No \"shadow\" attribute on element <%s>" -msgstr "\"ഷാഡോ\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" - -#: ../src/theme-parser.c:2614 -#, c-format -msgid "No \"arrow\" attribute on element <%s>" -msgstr "\"ആരോ\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" - -#: ../src/theme-parser.c:2667 ../src/theme-parser.c:2789 -#: ../src/theme-parser.c:2877 +#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 +#: ../src/ui/theme-parser.c:2506 #, c-format msgid "Did not understand state \"%s\" for <%s> element" msgstr "" -#: ../src/theme-parser.c:2677 ../src/theme-parser.c:2799 +#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 #, c-format msgid "Did not understand shadow \"%s\" for <%s> element" msgstr "" -#: ../src/theme-parser.c:2687 +#: ../src/ui/theme-parser.c:2380 #, c-format msgid "Did not understand arrow \"%s\" for <%s> element" msgstr "" -#: ../src/theme-parser.c:3100 ../src/theme-parser.c:3216 +#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 #, c-format msgid "No <draw_ops> called \"%s\" has been defined" msgstr "" -#: ../src/theme-parser.c:3112 ../src/theme-parser.c:3228 +#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 #, c-format msgid "Including draw_ops \"%s\" here would create a circular reference" msgstr "" -#: ../src/theme-parser.c:3291 -#, c-format -msgid "No \"value\" attribute on <%s> element" -msgstr "\"മൂല്ല്യം\" എന്ന ആട്രിബ്യൂട്ട് <%s> എലമെന്റില്‍ ലഭ്യമല്ല" - -#: ../src/theme-parser.c:3348 -#, c-format -msgid "No \"position\" attribute on <%s> element" -msgstr "\"സ്ഥാനം\" എന്ന ആട്രിബ്യൂട്ട് <%s> എലമെന്റില്‍ ലഭ്യമല്ല" - -#: ../src/theme-parser.c:3357 +#: ../src/ui/theme-parser.c:2917 #, c-format msgid "Unknown position \"%s\" for frame piece" msgstr "" -#: ../src/theme-parser.c:3365 +#: ../src/ui/theme-parser.c:2925 #, c-format msgid "Frame style already has a piece at position %s" msgstr "" -#: ../src/theme-parser.c:3382 ../src/theme-parser.c:3473 +#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 #, c-format msgid "No <draw_ops> with the name \"%s\" has been defined" msgstr "" -#: ../src/theme-parser.c:3410 -#, c-format -msgid "No \"function\" attribute on <%s> element" -msgstr "\"ഫംഗ്ഷന്‍\" എന്ന ആട്രിബ്യൂട്ട് <%s> എലമെന്റില്‍ ലഭ്യമല്ല" - -#: ../src/theme-parser.c:3418 ../src/theme-parser.c:3534 -#, c-format -msgid "No \"state\" attribute on <%s> element" -msgstr "\"അവസ്ഥ\" എന്ന ആട്രിബ്യൂട്ട് <%s> എലമെന്റില്‍ ലഭ്യമല്ല" - -#: ../src/theme-parser.c:3427 +#: ../src/ui/theme-parser.c:2972 #, c-format msgid "Unknown function \"%s\" for button" -msgstr "" +msgstr "ബട്ടണു് അപരിചിതമായ ഫംഗ്ഷന്‍ \"%s\"" -#: ../src/theme-parser.c:3436 +#: ../src/ui/theme-parser.c:2982 #, c-format msgid "Button function \"%s\" does not exist in this version (%d, need %d)" msgstr "" -#: ../src/theme-parser.c:3448 +#: ../src/ui/theme-parser.c:2994 #, c-format msgid "Unknown state \"%s\" for button" -msgstr "" +msgstr "ബട്ടണു് അപരിചിതമായ അവസ്ഥ \"%s\" " -#: ../src/theme-parser.c:3456 +#: ../src/ui/theme-parser.c:3002 #, c-format msgid "Frame style already has a button for function %s state %s" msgstr "" -#: ../src/theme-parser.c:3526 -#, c-format -msgid "No \"focus\" attribute on <%s> element" -msgstr "\"ഫോക്കസ്\" എന്ന ആട്രിബ്യൂട്ട് <%s> എലമെന്റില്‍ ലഭ്യമല്ല" - -#: ../src/theme-parser.c:3542 -#, c-format -msgid "No \"style\" attribute on <%s> element" -msgstr "\"രീതി\" എന്ന ആട്രിബ്യൂട്ട് <%s> എലമെന്റില്‍ ലഭ്യമല്ല" - -#: ../src/theme-parser.c:3551 +#: ../src/ui/theme-parser.c:3073 #, c-format msgid "\"%s\" is not a valid value for focus attribute" msgstr "" -#: ../src/theme-parser.c:3560 +#: ../src/ui/theme-parser.c:3082 #, c-format msgid "\"%s\" is not a valid value for state attribute" msgstr "" -#: ../src/theme-parser.c:3570 +#: ../src/ui/theme-parser.c:3092 #, c-format msgid "A style called \"%s\" has not been defined" msgstr "" -#: ../src/theme-parser.c:3581 -#, c-format -msgid "No \"resize\" attribute on <%s> element" -msgstr "" - -#: ../src/theme-parser.c:3591 ../src/theme-parser.c:3614 +#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 #, c-format msgid "\"%s\" is not a valid value for resize attribute" msgstr "" -#: ../src/theme-parser.c:3625 +#: ../src/ui/theme-parser.c:3147 #, c-format msgid "" "Should not have \"resize\" attribute on <%s> element for maximized/shaded " "states" msgstr "" -#: ../src/theme-parser.c:3639 +#: ../src/ui/theme-parser.c:3161 #, c-format -msgid "Should not have \"resize\" attribute on <%s> element for maximized states" +msgid "" +"Should not have \"resize\" attribute on <%s> element for maximized states" msgstr "" -#: ../src/theme-parser.c:3653 ../src/theme-parser.c:3675 +#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 #, c-format msgid "Style has already been specified for state %s resize %s focus %s" msgstr "" -#: ../src/theme-parser.c:3664 ../src/theme-parser.c:3686 +#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 +#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 +#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 #, c-format msgid "Style has already been specified for state %s focus %s" msgstr "" -#: ../src/theme-parser.c:3725 +#: ../src/ui/theme-parser.c:3294 msgid "" "Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " "attribute and also a <draw_ops> element, or specified two elements)" msgstr "" -#: ../src/theme-parser.c:3763 +#: ../src/ui/theme-parser.c:3332 msgid "" "Can't have a two draw_ops for a <button> element (theme specified a draw_ops " "attribute and also a <draw_ops> element, or specified two elements)" msgstr "" -#: ../src/theme-parser.c:3801 +#: ../src/ui/theme-parser.c:3370 msgid "" "Can't have a two draw_ops for a <menu_icon> element (theme specified a " "draw_ops attribute and also a <draw_ops> element, or specified two elements)" msgstr "" -#: ../src/theme-parser.c:3849 +#: ../src/ui/theme-parser.c:3434 +#, c-format +msgid "Bad version specification '%s'" +msgstr "തെറ്റായ പതിപ്പു് '%s'" + +#: ../src/ui/theme-parser.c:3507 +msgid "" +"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" +"theme-2.xml" +msgstr "" + +#: ../src/ui/theme-parser.c:3530 +#, c-format +msgid "Theme requires version %s but latest supported theme version is %d.%d" +msgstr "" + +#: ../src/ui/theme-parser.c:3562 #, c-format msgid "Outermost element in theme must be <metacity_theme> not <%s>" msgstr "" -#: ../src/theme-parser.c:3869 +#: ../src/ui/theme-parser.c:3582 #, c-format -msgid "Element <%s> is not allowed inside a name/author/date/description element" +msgid "" +"Element <%s> is not allowed inside a name/author/date/description element" msgstr "" -#: ../src/theme-parser.c:3874 +#: ../src/ui/theme-parser.c:3587 #, c-format msgid "Element <%s> is not allowed inside a <constant> element" msgstr "" -#: ../src/theme-parser.c:3886 +#: ../src/ui/theme-parser.c:3599 #, c-format -msgid "Element <%s> is not allowed inside a distance/border/aspect_ratio element" +msgid "" +"Element <%s> is not allowed inside a distance/border/aspect_ratio element" msgstr "" -#: ../src/theme-parser.c:3908 +#: ../src/ui/theme-parser.c:3621 #, c-format msgid "Element <%s> is not allowed inside a draw operation element" msgstr "" -#: ../src/theme-parser.c:3918 ../src/theme-parser.c:3948 -#: ../src/theme-parser.c:3953 ../src/theme-parser.c:3958 +#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 +#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 #, c-format msgid "Element <%s> is not allowed inside a <%s> element" msgstr "" -#: ../src/theme-parser.c:4180 +#: ../src/ui/theme-parser.c:3899 msgid "No draw_ops provided for frame piece" msgstr "" -#: ../src/theme-parser.c:4195 +#: ../src/ui/theme-parser.c:3914 msgid "No draw_ops provided for button" msgstr "" -#: ../src/theme-parser.c:4247 +#: ../src/ui/theme-parser.c:3968 #, c-format msgid "No text is allowed inside element <%s>" -msgstr "" - -#: ../src/theme-parser.c:4302 -msgid "<name> specified twice for this theme" -msgstr "" - -#: ../src/theme-parser.c:4313 -msgid "<author> specified twice for this theme" -msgstr "" - -#: ../src/theme-parser.c:4324 -msgid "<copyright> specified twice for this theme" -msgstr "" - -#: ../src/theme-parser.c:4335 -msgid "<date> specified twice for this theme" -msgstr "" - -#: ../src/theme-parser.c:4346 -msgid "<description> specified twice for this theme" -msgstr "" +msgstr "എലമെന്റ് <%s>-ല്‍ വാചകം അനുവദിയ്ക്കുന്നില്ല" -#: ../src/theme-parser.c:4573 +#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 +#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 +#: ../src/ui/theme-parser.c:4074 #, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "%s ഥീമിന് യോജിക്കുന്ന ഒരു ഫയല്‍ ലഭ്യമാക്കുവാന്‍ സാധ്യമായില്ല\n" +msgid "<%s> specified twice for this theme" +msgstr "<%s> ഈ പ്രമേയത്തിനു് രണ്ടു് തവണ നല്‍കിയിരിയ്ക്കുന്നു" -#: ../src/theme-parser.c:4629 +#: ../src/ui/theme-parser.c:4334 #, c-format -msgid "Theme file %s did not contain a root <metacity_theme> element" -msgstr "" - -#: ../src/theme-viewer.c:74 -msgid "/_Windows" -msgstr "/ജാലകങ്ങള്‍ (_W)" - -#: ../src/theme-viewer.c:75 -msgid "/Windows/tearoff" -msgstr "/Windows/tearoff" - -#: ../src/theme-viewer.c:76 -msgid "/Windows/_Dialog" -msgstr "/Windows/_Dialog" - -#: ../src/theme-viewer.c:77 -msgid "/Windows/_Modal dialog" -msgstr "/Windows/_Modal dialog" - -#: ../src/theme-viewer.c:78 -msgid "/Windows/_Utility" -msgstr "/Windows/_Utility" - -#: ../src/theme-viewer.c:79 -msgid "/Windows/_Splashscreen" -msgstr "/Windows/_Splashscreen" - -#: ../src/theme-viewer.c:80 -msgid "/Windows/_Top dock" -msgstr "/Windows/Top dock (_T)" - -#: ../src/theme-viewer.c:81 -msgid "/Windows/_Bottom dock" -msgstr "/Windows/_Bottom dock" - -#: ../src/theme-viewer.c:82 -msgid "/Windows/_Left dock" -msgstr "/Windows/_Left dock" - -#: ../src/theme-viewer.c:83 -msgid "/Windows/_Right dock" -msgstr "/Windows/_Right dock" - -#: ../src/theme-viewer.c:84 -msgid "/Windows/_All docks" -msgstr "/Windows/_All docks" - -#: ../src/theme-viewer.c:85 -msgid "/Windows/Des_ktop" -msgstr "/Windows/Des_ktop" - -#: ../src/theme-viewer.c:134 +msgid "Failed to find a valid file for theme %s\n" +msgstr "%s തീമിന് യോജിക്കുന്ന ഒരു ഫയല്‍ ലഭ്യമാക്കുവാന്‍ സാധ്യമായില്ല\n" + +#: ../src/ui/theme-viewer.c:99 +msgid "_Windows" +msgstr "_ജാലകങ്ങള്‍ (_W)" + +#: ../src/ui/theme-viewer.c:100 +msgid "_Dialog" +msgstr "_ഡയലോഗ് ബോക്സ്" + +#: ../src/ui/theme-viewer.c:101 +msgid "_Modal dialog" +msgstr "_മോഡല്‍ ഡയലോഗ് ബോക്സ്" + +#: ../src/ui/theme-viewer.c:102 +#| msgid "/Windows/_Utility" +msgid "_Utility" +msgstr "_Utility" + +#: ../src/ui/theme-viewer.c:103 +msgid "_Splashscreen" +msgstr "മി_ന്നല്‍ ജാലകം" + +#: ../src/ui/theme-viewer.c:104 +#| msgid "/Windows/_Top dock" +msgid "_Top dock" +msgstr "_Top dock" + +#: ../src/ui/theme-viewer.c:105 +#| msgid "/Windows/_Bottom dock" +msgid "_Bottom dock" +msgstr "_Bottom dock" + +#: ../src/ui/theme-viewer.c:106 +#| msgid "/Windows/_Left dock" +msgid "_Left dock" +msgstr "_Left dock" + +#: ../src/ui/theme-viewer.c:107 +#| msgid "/Windows/_Right dock" +msgid "_Right dock" +msgstr "_Right dock" + +#: ../src/ui/theme-viewer.c:108 +#| msgid "/Windows/_All docks" +msgid "_All docks" +msgstr "_All docks" + +#: ../src/ui/theme-viewer.c:109 +msgid "Des_ktop" +msgstr "_പണിയിടം" + +#: ../src/ui/theme-viewer.c:115 msgid "Open another one of these windows" msgstr "ഈ ജാലകത്തിലൊന്ന് തുറക്കുക" -#: ../src/theme-viewer.c:141 +#: ../src/ui/theme-viewer.c:117 msgid "This is a demo button with an 'open' icon" msgstr "" -#: ../src/theme-viewer.c:148 +#: ../src/ui/theme-viewer.c:119 msgid "This is a demo button with a 'quit' icon" msgstr "" -#: ../src/theme-viewer.c:241 +#: ../src/ui/theme-viewer.c:248 msgid "This is a sample message in a sample dialog" msgstr "" -#: ../src/theme-viewer.c:324 +#: ../src/ui/theme-viewer.c:328 #, c-format msgid "Fake menu item %d\n" -msgstr "" +msgstr "ശരിയല്ലാത്ത മെനു വസ്തു %d\n" -#: ../src/theme-viewer.c:358 +#: ../src/ui/theme-viewer.c:363 msgid "Border-only window" msgstr "" -#: ../src/theme-viewer.c:360 +#: ../src/ui/theme-viewer.c:365 msgid "Bar" -msgstr "ബാറ്‍" +msgstr "ബാര്‍" -#: ../src/theme-viewer.c:377 +#: ../src/ui/theme-viewer.c:382 msgid "Normal Application Window" -msgstr "പ്റയോഗത്തിനുള്ള സാധാരണ ജാലകം" +msgstr "പ്രയോഗത്തിനുള്ള സാധാരണ ജാലകം" -#: ../src/theme-viewer.c:381 +#: ../src/ui/theme-viewer.c:386 msgid "Dialog Box" msgstr "ഡയലോഗ് ബോക്സ്" -#: ../src/theme-viewer.c:385 +#: ../src/ui/theme-viewer.c:390 msgid "Modal Dialog Box" msgstr "മോഡല്‍ ഡയലോഗ് ബോക്സ്" -#: ../src/theme-viewer.c:389 +#: ../src/ui/theme-viewer.c:394 msgid "Utility Palette" msgstr "യൂട്ടിലിറ്റിയ്ക്കുള്ള നിറക്കൂട്ട്" -#: ../src/theme-viewer.c:393 +#: ../src/ui/theme-viewer.c:398 msgid "Torn-off Menu" msgstr "" -#: ../src/theme-viewer.c:397 +#: ../src/ui/theme-viewer.c:402 msgid "Border" msgstr "അതിര്" -#: ../src/theme-viewer.c:725 +#: ../src/ui/theme-viewer.c:406 +msgid "Attached Modal Dialog" +msgstr "കൂടെയുള്ള മോഡല്‍ ഡയലോഗ് ബോക്സ്" + +#: ../src/ui/theme-viewer.c:737 #, c-format msgid "Button layout test %d" -msgstr "" +msgstr "ബട്ടണ്‍ ശൈലി പരീക്ഷണം %d" -#: ../src/theme-viewer.c:754 +#: ../src/ui/theme-viewer.c:766 #, c-format msgid "%g milliseconds to draw one window frame" msgstr "" -#: ../src/theme-viewer.c:797 +#: ../src/ui/theme-viewer.c:811 +#, c-format msgid "Usage: metacity-theme-viewer [THEMENAME]\n" msgstr "ഉപയോഗിക്കേണ്ട വിധം: metacity-theme-viewer [THEMENAME]\n" -#: ../src/theme-viewer.c:804 +#: ../src/ui/theme-viewer.c:818 #, c-format msgid "Error loading theme: %s\n" msgstr "പ്രമേയം ലോഡ് ചെയ്യുന്നതില്‍ പിശക്: %s\n" -#: ../src/theme-viewer.c:810 +#: ../src/ui/theme-viewer.c:824 #, c-format msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "" +msgstr "\"%s\" എന്ന തീം %g സെക്കന്റ് കൊണ്ട് ലോഡ് ചെയ്തു\n" -#: ../src/theme-viewer.c:833 +#: ../src/ui/theme-viewer.c:869 msgid "Normal Title Font" -msgstr "" +msgstr "സാധാരണ ശീര്‍ഷക ഫോണ്ട്" -#: ../src/theme-viewer.c:839 +#: ../src/ui/theme-viewer.c:875 msgid "Small Title Font" -msgstr "" +msgstr "ചെറിയ ശീര്‍ഷക ഫോണ്ട്" -#: ../src/theme-viewer.c:845 +#: ../src/ui/theme-viewer.c:881 msgid "Large Title Font" -msgstr "" +msgstr "വലിയ ശീര്‍ഷക ഫോണ്ട്" -#: ../src/theme-viewer.c:850 +#: ../src/ui/theme-viewer.c:886 msgid "Button Layouts" msgstr "" -#: ../src/theme-viewer.c:855 +#: ../src/ui/theme-viewer.c:891 msgid "Benchmark" msgstr "" -#: ../src/theme-viewer.c:902 +#: ../src/ui/theme-viewer.c:947 msgid "Window Title Goes Here" -msgstr "" +msgstr "ജാലകത്തിന്റേ തലക്കെട്ട് ഇവിടെ" -#: ../src/theme-viewer.c:1006 +#: ../src/ui/theme-viewer.c:1053 #, c-format msgid "" "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " @@ -2642,350 +1656,343 @@ msgid "" "frame)\n" msgstr "" -#: ../src/theme-viewer.c:1219 +#: ../src/ui/theme-viewer.c:1273 msgid "position expression test returned TRUE but set error" msgstr "" -#: ../src/theme-viewer.c:1221 +#: ../src/ui/theme-viewer.c:1275 msgid "position expression test returned FALSE but didn't set error" msgstr "" -#: ../src/theme-viewer.c:1225 +#: ../src/ui/theme-viewer.c:1279 msgid "Error was expected but none given" msgstr "" -#: ../src/theme-viewer.c:1227 +#: ../src/ui/theme-viewer.c:1281 #, c-format msgid "Error %d was expected but %d given" msgstr "" -#: ../src/theme-viewer.c:1233 +#: ../src/ui/theme-viewer.c:1287 #, c-format msgid "Error not expected but one was returned: %s" msgstr "" -#: ../src/theme-viewer.c:1237 +#: ../src/ui/theme-viewer.c:1291 #, c-format msgid "x value was %d, %d was expected" -msgstr "x-ന്റെ മൂല്ല്യം %d ആയിരുന്നു, പക്ഷേ പ്റതീക്ഷിച്ചത് %d ആണ്" +msgstr "x-ന്റെ മൂല്ല്യം %d ആയിരുന്നു, പക്ഷേ പ്രതീക്ഷിച്ചത് %d ആണ്" -#: ../src/theme-viewer.c:1240 +#: ../src/ui/theme-viewer.c:1294 #, c-format msgid "y value was %d, %d was expected" -msgstr "y-യുടെ മൂല്ല്യം %d ആയിരുന്നു, പക്ഷേ പ്റതീക്ഷിച്ചത് %d ആണ്" +msgstr "y-യുടെ മൂല്ല്യം %d ആയിരുന്നു, പക്ഷേ പ്രതീക്ഷിച്ചത് %d ആണ്" -#: ../src/theme-viewer.c:1303 +#: ../src/ui/theme-viewer.c:1359 #, c-format msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" msgstr "" -#: ../src/theme.c:206 -msgid "top" -msgstr "മുകളില്‌" +#~ msgid "Window Management" +#~ msgstr "ജാലക നിരീക്ഷണം" -#: ../src/theme.c:208 -msgid "bottom" -msgstr "താഴെ" +#~ msgid "Failed to parse message \"%s\" from dialog process\n" +#~ msgstr "രചന %sലെ പ്രമേയം വായിക്കുന്നതില്‌ പരാജയപ്പെട്ടു:\n" -#: ../src/theme.c:210 -msgid "left" -msgstr "ഇടത്" +#~ msgid "Error reading from dialog display process: %s\n" +#~ msgstr "%s വായിക്കുന്നതില്‌ പരാജയം : \n" -#: ../src/theme.c:212 -msgid "right" -msgstr "വലത്" +#~ msgid "Failed to get hostname: %s\n" +#~ msgstr "ആതിഥേയനാമം ലഭിക്കുന്നതില്‌ പരാജയപ്പെട്ടു: %s\n" -#: ../src/theme.c:226 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "" +#~ msgid "Fatal IO error %d (%s) on display '%s'.\n" +#~ msgstr "ഗുരുതരമായ IO പിശക് %d (%s) ('%s' ദൃശ്യത്തില്‍).\n" -#: ../src/theme.c:245 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "" +#~ msgid "Close Window" +#~ msgstr "ജാലകം അടയ്‍ക്കുക" -#: ../src/theme.c:282 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "" +#~ msgid "Window Menu" +#~ msgstr "ജാലക പട്ടിക‌" -#: ../src/theme.c:294 -msgid "Frame geometry does not specify size of buttons" -msgstr "" +#~ msgid "Minimize Window" +#~ msgstr "ജാലകം ചെറുതാക്കുക" -#: ../src/theme.c:925 -msgid "Gradients should have at least two colors" -msgstr "" +#~ msgid "Maximize Window" +#~ msgstr "ജാലകം വലുതാക്കുക" -#: ../src/theme.c:1051 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" +#~ msgid "Unmaximize Window" +#~ msgstr "ജാലകം വലുതാക്കിയതൊഴിവാക്കുക" -#: ../src/theme.c:1065 -#, c-format -msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "" +#~ msgid "Roll Up Window" +#~ msgstr "ജാലകം ചുരുട്ടുക" -#: ../src/theme.c:1076 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "" +#~ msgid "Unroll Window" +#~ msgstr "Unroll Window" -#: ../src/theme.c:1089 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "" +#~ msgid "Keep Window On Top" +#~ msgstr "ജാലകം മുകളിലാക്കുക" -#: ../src/theme.c:1119 -#, c-format -msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" -msgstr "" +#~ msgid "Always On Visible Workspace" +#~ msgstr "എപ്പോഴും ദൃശ്യമായ പണിയറയില്‍ " -#: ../src/theme.c:1130 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "%s നെ ഒരു സംഖ്യയായി വേ‌ര്തിരിക്കാന്‌ കഴിയുഞ്ഞില്ല" +#~ msgid "Put Window On Only One Workspace" +#~ msgstr "ഒരു പണിയറയില്‍ ജാലകം കാണിക്കുക" -#: ../src/theme.c:1140 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "" +#~ msgid "No command %d has been defined.\n" +#~ msgstr "%d എന്ന കമാന്‍ഡ് ലഭ്യമല്ല.\n" -#: ../src/theme.c:1187 -#, c-format -msgid "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "" +#~ msgid "No terminal command has been defined.\n" +#~ msgstr "ഒരു ടെറ്‍മിനല്‍ കമാന്‍ഡും ലഭ്യമല്ല.\n" -#: ../src/theme.c:1198 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "%s നെ ഒരു സംഖ്യയായി വേ‌ര്തിരിക്കാന്‌ കഴിയുഞ്ഞില്ല" +#~ msgid "Failed to restart: %s\n" +#~ msgstr "പുനരാരംഭിക്കുന്നതില്‌ പരാജയപ്പെട്ടു: %s\n" -#: ../src/theme.c:1208 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "" +#~ msgid "Title" +#~ msgstr "തലക്കെട്ട്" -#: ../src/theme.c:1237 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "" +#~ msgid "Class" +#~ msgstr "ക്ളാസ്" -#: ../src/theme.c:1496 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "" +#~ msgid "" +#~ "There was an error running \"%s\":\n" +#~ "%s." +#~ msgstr "" +#~ "\"%s\" പ്രവ‍ര്ത്തിക്കുന്നതില് തകരാറ്:\n" +#~ "%s." -#: ../src/theme.c:1523 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "" +#~ msgid "Metacity" +#~ msgstr "മെറ്റാസിറ്റി" -#: ../src/theme.c:1537 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "" +#~ msgid "Action on title bar double-click" +#~ msgstr "തലക്കെട്ടിനുള്ള ബാറ്‍ രണ്ട് തവണ ക്ളിക്ക് ചെയ്യുമ്പോള്‍ ഉണ്ടാകുന്ന പ്റവറ്‍ത്തി" -#: ../src/theme.c:1604 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "" +#~ msgid "Action on title bar middle-click" +#~ msgstr "തലക്കെട്ടിനുള്ള ബാറില്‍ നടുക്ക് ക്ളിക്ക് ചെയ്യുമ്പോള്‍ ഉണ്ടാകുന്ന പ്റവറ്‍ത്തി" -#: ../src/theme.c:1661 -msgid "Coordinate expression was empty or not understood" -msgstr "" +#~ msgid "Action on title bar right-click" +#~ msgstr "തലക്കെട്ടിനുള്ള ബാറില്‍ റൈറ്റ് ക്ളിക്ക് ചെയ്യുമ്പോള്‍ ഉണ്ടാകുന്ന പ്റവറ്‍ത്തി" -#: ../src/theme.c:1798 ../src/theme.c:1808 ../src/theme.c:1842 -msgid "Coordinate expression results in division by zero" -msgstr "" +#~ msgid "Arrangement of buttons on the titlebar" +#~ msgstr "തലക്കെട്ടിനുള്ള ബാറില്‍ ബട്ടണുകളുടെ ക്റമികരണം" -#: ../src/theme.c:1850 -msgid "Coordinate expression tries to use mod operator on a floating-point number" -msgstr "" +#~ msgid "Automatically raises the focused window" +#~ msgstr "അവസ്ഥാ മാറ്റങ്ങള് സ്വയമേവ സംരക്ഷിക്കുക" -#: ../src/theme.c:1906 -#, c-format -msgid "Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "" +#~ msgid "Current theme" +#~ msgstr "സജീവ തീം" -#: ../src/theme.c:1915 -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "" +#~ msgid "Hide all windows and focus desktop" +#~ msgstr "എല്ലാ ജാലകങ്ങളും അദൃശ്യമാക്കി ഡസ്ക്ടോപ്പ് കാണിക്കുക" -#: ../src/theme.c:1923 -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "" +#~ msgid "Minimize window" +#~ msgstr "ജാലകം ഏറ്റവും ചെറുതാക്കുക" -#: ../src/theme.c:1933 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" +#~ msgid "Move window to east side of screen" +#~ msgstr "സ്ക്രീനിന്റെ കിഴക്ക് വശത്തേക്ക് ജാലകം മാറ്റുക" -#: ../src/theme.c:2051 -msgid "Coordinate expression parser overflowed its buffer." -msgstr "" +#~ msgid "Move window to north side of screen" +#~ msgstr "സ്ക്രീനിന്റെ വടക്ക് വശത്തേക്ക് ജാലകം മാറ്റുക" -#: ../src/theme.c:2080 -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "" +#~ msgid "Move window to north-east corner" +#~ msgstr "സ്ക്രീനിന്റെ വടക്ക്-കിഴക്ക് വശത്തേക്ക് ജാലകം മാറ്റുക" -#: ../src/theme.c:2142 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "" +#~ msgid "Move window to north-west corner" +#~ msgstr "സ്ക്രീനിന്റെ വടക്ക്-പടിഞ്ഞാറ് വശത്തേക്ക് ജാലകം മാറ്റുക" -#: ../src/theme.c:2197 -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "" +#~ msgid "Move window to south side of screen" +#~ msgstr "സ്ക്രീനിന്റെ തെക്ക് വശത്തേക്ക് ജാലകം മാറ്റുക" -#: ../src/theme.c:2208 -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "" +#~ msgid "Move window to south-east corner" +#~ msgstr "സ്ക്രീനിന്റെ തെക്ക്-കിഴക്ക് വശത്തേക്ക് ജാലകം മാറ്റുക" -#: ../src/theme.c:2449 ../src/theme.c:2471 ../src/theme.c:2492 -#, c-format -msgid "Theme contained an expression \"%s\" that resulted in an error: %s\n" -msgstr "" +#~ msgid "Move window to south-west corner" +#~ msgstr "സ്ക്രീനിന്റെ തെക്ക്-പടിഞ്ഞാറ് വശത്തേക്ക് ജാലകം മാറ്റുക" -#: ../src/theme.c:3946 -#, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" +#~ msgid "Move window to west side of screen" +#~ msgstr "സ്ക്രീനിന്റെ പടിഞ്ഞാറിലേക്ക് ജാലകം മാറ്റുക" -#: ../src/theme.c:4422 ../src/theme.c:4447 -#, c-format -msgid "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "<frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/> ലഭ്യമല്ല" +#~ msgid "Move window to workspace 10" +#~ msgstr "പണിയറ ജാലകം പത്തിലേക്ക് നീക്കുക" -#: ../src/theme.c:4493 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "പ്രമേയം %s കൊണ്ട് വരാന് കഴിഞ്ഞില്ല: %s\n" +#~ msgid "Move window to workspace 11" +#~ msgstr "പണിയറ ജാലകം 11ലേക്ക് നീക്കുക" -#: ../src/theme.c:4603 ../src/theme.c:4610 ../src/theme.c:4617 -#: ../src/theme.c:4624 ../src/theme.c:4631 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "" +#~ msgid "Move window to workspace 12" +#~ msgstr "പണിയറ ജാലകം 12ലേക്ക് നീക്കുക" -#: ../src/theme.c:4639 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" +#~ msgid "Move window to workspace 5" +#~ msgstr "പണിയറ ജാലകം 5ലേക്ക് നീക്കുക" -#: ../src/theme.c:5006 ../src/theme.c:5068 ../src/theme.c:5131 -#, c-format -msgid "User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" +#~ msgid "Move window to workspace 6" +#~ msgstr "പണിയറ ജാലകം 6ലേക്ക് നീക്കുക" -#: ../src/theme.c:5014 ../src/theme.c:5076 ../src/theme.c:5139 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "" +#~ msgid "Move window to workspace 7" +#~ msgstr "പണിയറ ജാലകം 7ലേക്ക് നീക്കുക" -#: ../src/util.c:98 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "തുറക്കുന്നതില്‌ പരാജയം: %s\n" +#~ msgid "Move window to workspace 8" +#~ msgstr "പണിയറ ജാലകം 8ലേക്ക് നീക്കുക" -#: ../src/util.c:108 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "fdopen() log രചന %s തുറക്കുന്നതില്‌ പരാജയം : %s\n" +#~ msgid "Move window to workspace 9" +#~ msgstr "പണിയറ ജാലകം 9ലേക്ക് നീക്കുക" -#: ../src/util.c:114 -#, c-format -msgid "Opened log file %s\n" -msgstr "തുറന്ന ഒരു ലോഗ് രചന %s\n" +#~ msgid "Name of workspace" +#~ msgstr "പണിയറയുടെ പേര‌്" -#: ../src/util.c:231 -msgid "Window manager: " -msgstr "ജാലക പാലകന്:‌" +#~ msgid "Number of workspaces" +#~ msgstr "പണിയറകളുടെ എണ്ണം" -#: ../src/util.c:379 -msgid "Bug in window manager: " -msgstr "ജാലക പാലകനിലെ ഛിദ്രം: ‌" +#~ msgid "Run a defined command" +#~ msgstr "നി‌‌‌ര്‌വചിച്ച നി‌ര്ദ്ദേശം പ്രാവ‌‌ര്ത്തികമാക്കൂ" -#: ../src/util.c:408 -msgid "Window manager warning: " -msgstr "ജാലക പാലകന്റെ മുന്നറിയിപ്പ്:‌" +#~ msgid "Run a terminal" +#~ msgstr "ഒരു ടറ്‍മിനല്‍ ലഭ്യമാക്കുക" -#: ../src/util.c:432 -msgid "Window manager error: " -msgstr "ജാലക പാലകന്റെ തെറ്റ്:‌‌" +#~ msgid "Show the panel menu" +#~ msgstr "പാനലിന്റെ മെനു കാണിക്കുക" -#: ../src/window-props.c:192 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "" +#~ msgid "Switch to workspace 10" +#~ msgstr "പണിയറകള് 10ലേക്ക് മാറ്റൂ" -#: ../src/window-props.c:324 -#, c-format -msgid "%s (on %s)" -msgstr "%s (%s-ല്‍)" +#~ msgid "Switch to workspace 11" +#~ msgstr "പണിയറകള് 11ലേക്ക് മാറ്റൂ" -#: ../src/window-props.c:1406 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "" +#~ msgid "Switch to workspace 12" +#~ msgstr "പണിയറകള് 12ലേക്ക് മാറ്റൂ" -#. first time through -#: ../src/window.c:5540 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" +#~ msgid "Switch to workspace 5" +#~ msgstr "പണിയറകള് 5ലേക്ക് മാറ്റൂ" -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/window.c:6105 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %" -"d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" +#~ msgid "Switch to workspace 6" +#~ msgstr "പണിയറകള് 6ലേക്ക് മാറ്റൂ" -#: ../src/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" +#~ msgid "Switch to workspace 7" +#~ msgstr "പണിയറകള് 7ലേക്ക് മാറ്റൂ" -#: ../src/xprops.c:401 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "" +#~ msgid "Switch to workspace 8" +#~ msgstr "പണിയറകള് 8ലേക്ക് മാറ്റൂ" -#: ../src/xprops.c:484 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" +#~ msgid "Switch to workspace 9" +#~ msgstr "പണിയറകള് 9ലേക്ക് മാറ്റൂ" + +#~ msgid "Switch to workspace above this one" +#~ msgstr "ഇതിന്റെ മുകളിലുള്ള പണിയറകളിേക്ക് മാറ്റൂ" + +#~ msgid "Switch to workspace below this one" +#~ msgstr "ഇതിന്റെ താഴെയുള്ള പണിയറകളിേക്ക് മാറ്റൂ" + +#~ msgid "Switch to workspace on the left" +#~ msgstr "ഇതിന്റെ ഇടതുവശത്തുള്ള പണിയറകളിേക്ക് മാറ്റൂ" + +#~ msgid "Switch to workspace on the right" +#~ msgstr "ഇതിന്റെ വലതുവശത്തുള്ള പണിയറകളിേക്ക് മാറ്റൂ" + +#~ msgid "Take a screenshot" +#~ msgstr "ഒരു സ്ക്രീന്‍ ഷോട്ട് എടുക്കുക" + +#~ msgid "Take a screenshot of a window" +#~ msgstr "ജാലകത്തിന്റെ ഒരു സ്ക്രീന്‍ ഷോട്ട് എടുക്കുക" + +#~ msgid "The name of a workspace." +#~ msgstr "പണിയറുടെ പേര‍്" + +#~ msgid "The screenshot command" +#~ msgstr "സ്ക്രീന്‍ ഷോട്ടിനുള്ള കമാന്‍ഡ്" + +#~ msgid "The window screenshot command" +#~ msgstr "ജാലകത്തിന്റെ സ്ക്രീന്‍ഷോട്ടിനുള്ള കമാന്‍ഡ്" + +#~ msgid "Unmaximize window" +#~ msgstr "ജാലകം ചെറുതാക്കുക " + +#~ msgid "Window focus mode" +#~ msgstr "ജാലക കേന്ദ്രീകരണരീതി" + +#~ msgid "Window title font" +#~ msgstr "ജാലക തലക്കെട്ട് അക്ഷരരൂപം" + +#~ msgid "Error setting name for workspace %d to \"%s\": %s\n" +#~ msgstr "%d യില്‌നിന്ന് \"%s\"ലേക്ക് പണിയറയുടെ പേ‌ര‌് സജ്ജമാക്കുന്നതില്‌ തെറ്റ്: %s\n" + +#~ msgid "Failed to read saved session file %s: %s\n" +#~ msgstr "രചന %sലെ പ്രമേയം വായിക്കുന്നതില്‌ പരാജയപ്പെട്ടു: %s\n" + +#~ msgid "No \"top\" attribute on element <%s>" +#~ msgstr "\"മുകളില്‍\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" + +#~ msgid "No \"bottom\" attribute on element <%s>" +#~ msgstr "\"താഴെ\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" + +#~ msgid "No \"left\" attribute on element <%s>" +#~ msgstr "\"ഇടത്\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" + +#~ msgid "No \"right\" attribute on element <%s>" +#~ msgstr "\"വലത്\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" + +#~ msgid "No \"color\" attribute on element <%s>" +#~ msgstr "\"നിറം\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" + +#~ msgid "No \"x1\" attribute on element <%s>" +#~ msgstr "\"x1\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" + +#~ msgid "No \"y1\" attribute on element <%s>" +#~ msgstr "\"y1\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" + +#~ msgid "No \"x2\" attribute on element <%s>" +#~ msgstr "\"x2\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" + +#~ msgid "No \"y2\" attribute on element <%s>" +#~ msgstr "\"y2\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" + +#~ msgid "No \"y\" attribute on element <%s>" +#~ msgstr "\"y\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" + +#~ msgid "No \"width\" attribute on element <%s>" +#~ msgstr "\"വീതി\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" + +#~ msgid "No \"height\" attribute on element <%s>" +#~ msgstr "\"ഉയരം\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" + +#~ msgid "No \"alpha\" attribute on element <%s>" +#~ msgstr "\"ആല്‍ഫാ\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" + +#~ msgid "No \"type\" attribute on element <%s>" +#~ msgstr "\"ഏത് തരം\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" + +#~ msgid "No \"filename\" attribute on element <%s>" +#~ msgstr "\"ഫയലിന്റെ പേര്\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" + +#~ msgid "No \"state\" attribute on element <%s>" +#~ msgstr "\"അവസ്ഥ\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" + +#~ msgid "No \"shadow\" attribute on element <%s>" +#~ msgstr "\"ഷാഡോ\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" + +#~ msgid "No \"arrow\" attribute on element <%s>" +#~ msgstr "\"ആരോ\" എന്ന ആട്രിബ്യൂട്ട് <%s> എന്ന എലമെന്റില്‍ ലഭ്യമല്ല" + +#~ msgid "No \"value\" attribute on <%s> element" +#~ msgstr "\"മൂല്ല്യം\" എന്ന ആട്രിബ്യൂട്ട് <%s> എലമെന്റില്‍ ലഭ്യമല്ല" + +#~ msgid "No \"position\" attribute on <%s> element" +#~ msgstr "\"സ്ഥാനം\" എന്ന ആട്രിബ്യൂട്ട് <%s> എലമെന്റില്‍ ലഭ്യമല്ല" + +#~ msgid "No \"state\" attribute on <%s> element" +#~ msgstr "\"അവസ്ഥ\" എന്ന ആട്രിബ്യൂട്ട് <%s> എലമെന്റില്‍ ലഭ്യമല്ല" + +#~ msgid "No \"focus\" attribute on <%s> element" +#~ msgstr "\"ഫോക്കസ്\" എന്ന ആട്രിബ്യൂട്ട് <%s> എലമെന്റില്‍ ലഭ്യമല്ല" + +#~ msgid "No \"style\" attribute on <%s> element" +#~ msgstr "\"രീതി\" എന്ന ആട്രിബ്യൂട്ട് <%s> എലമെന്റില്‍ ലഭ്യമല്ല" + +#~ msgid "/Windows/tearoff" +#~ msgstr "/Windows/tearoff" + +#~ msgid "/Windows/_Dialog" +#~ msgstr "/Windows/_Dialog" + +#~ msgid "/Windows/_Modal dialog" +#~ msgstr "/Windows/_Modal dialog" +#~ msgid "/Windows/Des_ktop" +#~ msgstr "/Windows/Des_ktop" diff --git a/po/mn.po b/po/mn.po index a87c09097..0f8dd8f1f 100644 --- a/po/mn.po +++ b/po/mn.po @@ -17,10 +17,11 @@ msgstr "" "PO-Revision-Date: 2004-01-03 15:09+0100\n" "Last-Translator: Sanlig Badral <Badral@openmn.org>\n" "Language-Team: Mongolian <openmn-core@lists.sf.net>\n" +"Language: mn\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: KBabel 1.0.3\n" +"X-Generator: KBabel 1.0.2\n" #: ../src/tools/metacity-message.c:150 #, c-format diff --git a/po/mr.po b/po/mr.po index fae9f3cc5..d55adbdd2 100644 --- a/po/mr.po +++ b/po/mr.po @@ -1,1788 +1,833 @@ # translation of metacity.gnome-2-26.mr.po to marathi -# Rahul Bhalerao <b.rahul.pm@gmail.com>, 2006. -# sandeep shedmake <sandeep.shedmake@gmail.com>, 2008. -# Sandeep Shedmake <sandeep.shedmake@gmail.com>, 2009. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. +# Rahul Bhalerao <b.rahul.pm@gmail.com>, 2006. +# sandeep shedmake <sandeep.shedmake@gmail.com>, 2008. +# Sandeep Shedmake <sshedmak@redhat.com>, 2009, 2012, 2013, 2014. msgid "" msgstr "" "Project-Id-Version: metacity.gnome-2-26.mr\n" -"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=metacity&component=general\n" -"POT-Creation-Date: 2009-02-05 16:08+0000\n" -"PO-Revision-Date: 2009-03-14 13:28+0530\n" -"Last-Translator: Sandeep Shedmake <sandeep.shedmake@gmail.com>\n" -"Language-Team: marathi\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=mutter&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2014-09-14 09:55+0000\n" +"PO-Revision-Date: 2014-09-14 21:13+0530\n" +"Last-Translator: Sandeep Shedmake <sshedmak@redhat.com>\n" +"Language-Team: Marathi <maajhe-sanganak@freelists.org>\n" +"Language: mr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: KBabel 1.11.4\n" +"X-Generator: Lokalize 1.5\n" "Plural-Forms: nplurals=2; plural=(n!=1);\n" "\n" -#: ../src/50-metacity-desktop-key.xml.in.h:1 -msgid "Desktop" -msgstr "डेस्कटॉप" - -#: ../src/50-metacity-key.xml.in.h:1 -msgid "Window Management" -msgstr "चौकट व्यवस्थापन" - -#: ../src/core/core.c:206 -#, c-format -msgid "Unknown window information request: %d" -msgstr "अपरिचीत चौकट माहिती विनंती: %d" - -#: ../src/core/delete.c:70 ../src/core/delete.c:97 -#: ../src/ui/metacity-dialog.c:50 ../src/ui/theme-parser.c:522 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "\"%s\" चे पुर्णांक म्हणून विश्लेषण करता आले नाही" - -#: ../src/core/delete.c:77 ../src/core/delete.c:104 -#: ../src/ui/metacity-dialog.c:57 ../src/ui/theme-parser.c:531 -#: ../src/ui/theme-parser.c:586 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "अक्षरमाळा \"%2$s\" मधिल शेवटचे अक्षरं \"%1$s\" कळले नाही" - -#: ../src/core/delete.c:135 -#, c-format -msgid "Failed to parse message \"%s\" from dialog process\n" -msgstr "संवाद कार्यपध्दती मधून संदेश \"%s\" वाचता आले नाही\n" - -#: ../src/core/delete.c:253 -#, c-format -msgid "Error reading from dialog display process: %s\n" -msgstr "संवाद दृश्य पध्दती वाचताना त्रुटी: %s\n" - -#: ../src/core/delete.c:336 -#, c-format -msgid "Error launching metacity-dialog to ask about killing an application: %s\n" -msgstr "अनुप्रयोग पूर्णपणे बंद करण्याकरीता metacity-dialog प्रक्षेपीत करतेवेळी त्रुटी: %s\n" - -#: ../src/core/delete.c:445 -#, c-format -msgid "Failed to get hostname: %s\n" -msgstr "सादरकर्त्याचे नाव प्राप्त करण्यास अपयशी: %s\n" - -#: ../src/core/display.c:256 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "एकत्रीकरण करीता आवश्यक %s विस्तार आढळले नाही" - -#: ../src/core/display.c:334 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "X चौकट प्रणाली दृश्य '%s' उघडण्यास अपयशी\n" - -#: ../src/core/errors.c:272 -#, c-format -msgid "" -"Lost connection to the display '%s';\n" -"most likely the X server was shut down or you killed/destroyed\n" -"the window manager.\n" -msgstr "" -"दृश्य'%s' शी जुळवणी तुटली;\n" -"संभाव्य X सर्वर बंद केले गेले किंवा\n" -"तुम्ही चौकट व्यवस्थापक रद्द/नष्ट केले असावे.\n" - -#: ../src/core/errors.c:279 -#, c-format -msgid "Fatal IO error %d (%s) on display '%s'.\n" -msgstr "दृश्य '%3$s' वरील धोकादायक IO त्रुटी %1$d (%2$s) आढळले.\n" - -#: ../src/core/keybindings.c:680 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "कुठलेतरी इतर कार्यक्रम आधिपासूनच किल्ली %s ला संपादक %x सह बांधणी म्हणून वापरत आहे\n" - -#. Displayed when a keybinding which is -#. * supposed to launch a program fails. -#. -#: ../src/core/keybindings.c:2294 -#, c-format -#| msgid "" -#| "There was an error running \"%s\":\n" -#| "%s." -msgid "" -"There was an error running <tt>%s</tt>:\n" -"\n" -"%s" -msgstr "" -"<tt>%s</tt> चालवतेवेळी त्रुटी आढळली:\n" -"\n" -"%s" - -#: ../src/core/keybindings.c:2381 -#, c-format -msgid "No command %d has been defined.\n" -msgstr "आदेश %d परिभाषीत नाही.\n" - -#: ../src/core/keybindings.c:3335 -#, c-format -msgid "No terminal command has been defined.\n" -msgstr "टर्मिनल आदेश परिभाषीत नाही.\n" - -#: ../src/core/main.c:116 -#, c-format -msgid "" -"metacity %s\n" -"Copyright (C) 2001-2008 Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" -"metacity %s\n" -"सर्वहक्कअधिकार (C) 2001-2008 Havoc Pennington, Red Hat, Inc., व इतर\n" -"हे मुक्त सॉफ्टवेअल आहे; प्रतिकृत करण्याकरीता स्त्रोत पहा.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" - -#: ../src/core/main.c:253 -msgid "Disable connection to session manager" -msgstr "सत्र व्यवस्थपानशी जुळवणी अकार्यान्वती करा" - -#: ../src/core/main.c:259 -msgid "Replace the running window manager with Metacity" -msgstr "सध्याचे कार्यरत चौकट व्यवस्थापक Metacity शी बदलवा" - -#: ../src/core/main.c:265 -msgid "Specify session management ID" -msgstr "सत्र व्यवस्थापन ID निश्चित करा" - -#: ../src/core/main.c:270 -msgid "X Display to use" -msgstr "वापरण्याकरीताचे X दृश्य" - -#: ../src/core/main.c:276 -msgid "Initialize session from savefile" -msgstr "संचयन फाइल पासून सत्र प्रारंभीत करा" - -#: ../src/core/main.c:282 -msgid "Print version" -msgstr "मुद्रण आवृत्ती" - -#: ../src/core/main.c:288 -msgid "Make X calls synchronous" -msgstr "X कॉल सुसंगत करा" - -#: ../src/core/main.c:294 -#| msgid "Compositing Manager" -msgid "Turn compositing on" -msgstr "संयुक्त चालू करा" - -#: ../src/core/main.c:300 -msgid "Turn compositing off" -msgstr "संयुक्त बंद करा" - -#: ../src/core/main.c:478 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "सुत्रयोजना संचयीका स्कॅन करण्यास अपयशी: %s\n" - -#: ../src/core/main.c:494 -#, c-format -msgid "Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "" -"सुत्रयोजना शोधू शकले नाही! %s अस्तित्वात आहे व त्यात नेहमीचे सुत्रयोजना समाविष्टीत आहे " -"याची खात्री घ्या.\n" - -#: ../src/core/main.c:550 -#, c-format -msgid "Failed to restart: %s\n" -msgstr "पुनःआरंभ करण्यास अपयशी: %s\n" - -#. -#. * We found it, but it was invalid. Complain. -#. * -#. * FIXME: This replicates the original behaviour, but in the future -#. * we might consider reverting invalid keys to their original values. -#. * (We know the old value, so we can look up a suitable string in -#. * the symtab.) -#. * -#. * (Empty comment follows so the translators don't see this.) -#. -#. -#: ../src/core/prefs.c:505 ../src/core/prefs.c:660 -#, c-format -msgid "GConf key '%s' is set to an invalid value\n" -msgstr "अयोग्य मुल्यसाठी '%s' GConf किल्ली जोडली आहे\n" - -#: ../src/core/prefs.c:586 ../src/core/prefs.c:829 -#, c-format -#| msgid "%d stored inGConf key %s is out of range 0 to %d\n" -msgid "%d stored in GConf key %s is out of range %d to %d\n" -msgstr "GConf कि %2$s अंतर्गत साठवलेले %1$d, %3$d ते %4$d क्षेत्राच्या बाहेर आहे\n" - -#: ../src/core/prefs.c:630 ../src/core/prefs.c:707 ../src/core/prefs.c:755 -#: ../src/core/prefs.c:819 ../src/core/prefs.c:1112 ../src/core/prefs.c:1128 -#: ../src/core/prefs.c:1145 ../src/core/prefs.c:1161 -#, c-format -msgid "GConf key \"%s\" is set to an invalid type\n" -msgstr "अयोग्य प्रकारच्या \"%s\" GConf किल्ली जोडली आहे\n" - -#: ../src/core/prefs.c:1231 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"अनिश्चित अनुप्रोयगांकरीता कार्य अकार्यान्वीत केले गेले. काहीक अनुप्रयोगांची वागणून " -"योग्यरित्या आढळणार नाही\n" - -#: ../src/core/prefs.c:1302 -#, c-format -msgid "Could not parse font description \"%s\" from GConf key %s\n" -msgstr "GConf किल्ली \"%s\" पासून फॉन्टची माहिती पार्स करू शकली नाही %s\n" - -#: ../src/core/prefs.c:1364 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "माउस बटन संपादक करीता संयोजना माहितीकोश मध्ये आढळलेले \"%s\" वैध मुल्य नाही\n" - -#: ../src/core/prefs.c:1782 -#, c-format -msgid "Error setting number of workspaces to %d: %s\n" -msgstr "%d करीता कार्यक्षेत्राची एकूण संख्या स्थापित करतेवेळी त्रुटी: %s\n" - -#: ../src/core/prefs.c:1971 ../src/core/prefs.c:2474 -#, c-format -msgid "Workspace %d" -msgstr "कार्यक्षेत्र %d" - -#: ../src/core/prefs.c:2001 ../src/core/prefs.c:2179 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "keybinding \"%2$s\" करीता संयोजना माहितीकोश मध्ये आढळलेले \"%1$s\" वैध मुल्य नाही\n" - -#: ../src/core/prefs.c:2555 -#, c-format -msgid "Error setting name for workspace %d to \"%s\": %s\n" -msgstr "कार्यक्षेत्र %d करीता \"%s\" असे नाव स्थापीत करतेवेळी त्रुटी: %s\n" - -#: ../src/core/prefs.c:2753 -#, c-format -#| msgid "Error setting name for workspace %d to \"%s\": %s\n" -msgid "Error setting compositor status: %s\n" -msgstr "कंपोसीटर स्थिती संयोजीत करतेवेळी त्रुटी आढळली: %s\n" - -#: ../src/core/screen.c:350 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "दृश्य '%2$s' वरील पडदा %1$d अवैध आहे\n" +#: ../data/50-mutter-navigation.xml.in.h:1 +msgid "Navigation" +msgstr "संचारन" -#: ../src/core/screen.c:366 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"दृश्य \"%2$s\" वरील पडदा %1$d कडे आधिपासूनच चौकट व्यवस्थापक आहे; --replace पर्याय चा " -"वापर सद्याचे चौकट व्यवस्थापक बदलविण्याकरीता केले जाऊ शकतो.\n" - -#: ../src/core/screen.c:393 -#, c-format -msgid "Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "दृश्य \"%2$s\" वरील पडदा %1$d करीता चौकट व्यवस्थापक निवड प्राप्त करू शकले नाही\n" - -#: ../src/core/screen.c:451 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "दृश्य \"%2$s\" वरील पडदा %1$d कडे आधिपासूनच चौकट व्यवस्थापक आहे\n" - -#: ../src/core/screen.c:661 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "दृश्य \"%2$s\" वरील पडदा %1$d मोकळे करू शकला नाही\n" - -#. Translators: Please don't translate "Control", "Shift", etc, since these -#. * are hardcoded (in gtk/gtkaccelgroup.c; it's not metacity's fault). -#. * "disabled" must also stay as it is. -#. -#: ../src/core/schema-bindings.c:169 -#| msgid "" -#| "The keybinding used to close a window. The format looks like \"<" -#| "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#| "liberal and allows lower or upper case, and also abbreviations such as " -#| "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#| "special string \"disabled\", then there will be no keybinding for this " -#| "action." -msgid "" -"The format looks like \"<Control>a\" or <Shift><Alt>F1\".\n" -"\n" -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -"special string \"disabled\", then there will be no keybinding for this " -"action." -msgstr "" -"स्वरूप \"<Control>a\" किंवा \"<Shift><Alt>F1\" नुरूप दिसते.\n" -"\n " -"पार्सर लहान किंवा मोठे केस स्वीकारतो, व \"<Ctl>\" व \"<Ctrl>\" प्रमाणे संक्षिप्त रूप देखिल स्वीकारतो. विशेष अक्षरमाळा \"disabled\" करीता पर्याय निश्चित केल्यास, या कृती करीता किबाईन्डींग आढळली जाणार नाही." - -#: ../src/core/schema-bindings.c:177 -#| msgid "" -#| "The keybinding used to close a window. The format looks like \"<" -#| "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#| "liberal and allows lower or upper case, and also abbreviations such as " -#| "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#| "special string \"disabled\", then there will be no keybinding for this " -#| "action." -msgid "" -"The format looks like \"<Control>a\" or <Shift><Alt>F1\".\n" -"\n" -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -"special string \"disabled\", then there will be no keybinding for this " -"action.\n" -"\n" -"This keybinding may be reversed by holding down the \"shift\" key; " -"therefore, \"shift\" cannot be one of the keys it uses." -msgstr "" -"स्वरूप \"<Control>a\" किंवा \"<Shift><Alt>F1\" नुरूप दिसते.\n" -"\n " -"पार्सर लहान किंवा मोठे केस स्वीकारतो, " -"व \"<Ctl>\" व \"<Ctrl>\" प्रमाणे संक्षिप्त रूप देखिल स्वीकारतो. " -"विशेष अक्षरमाळा \"disabled\" करीता पर्याय निश्चित केल्यास, " -"या कृती करीता किबाईन्डींग आढळली जाणार नाही.\n" -"\n" -"\"shift\" कि दाबून ठेवल्यास किबाइन्डींग उल्टे केली जाऊ शकते; " -"त्यामुळे, \"shift\" वापरणी पैकी एखादी कि असू शकत नाही." - -#: ../src/core/session.c:837 ../src/core/session.c:844 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "संचयीका '%s' बनवू शकले नाही: %s\n" - -#: ../src/core/session.c:854 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "लिहीण्यासाठी सत्र फाइल '%s' उघडू शकले नाही: %s\n" - -#: ../src/core/session.c:995 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "सत्र फाइल '%s' लिहीतेवेळी त्रुटी: %s\n" - -#: ../src/core/session.c:1000 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "सत्र फाइल '%s' लिहीतेवेळी त्रुटी: %s\n" - -#. oh, just give up -#: ../src/core/session.c:1093 -#, c-format -msgid "Failed to read saved session file %s: %s\n" -msgstr "सत्र फाइल %s वाचतेवेळी त्रुटी: %s\n" - -#: ../src/core/session.c:1132 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "संचयीत सत्र फाइल वाचण्यास अपयशी: %s\n" - -#: ../src/core/session.c:1181 -#, c-format -msgid "<metacity_session> attribute seen but we already have the session ID" -msgstr "<metacity_session> हा गुणधर्म आढळले पण आमच्याकडे आधिपासूनच सत्र ओळखक्रमांक आहे" - -#: ../src/core/session.c:1194 ../src/core/session.c:1269 -#: ../src/core/session.c:1301 ../src/core/session.c:1373 -#: ../src/core/session.c:1433 -#, c-format -#| msgid "Unknown attribute %s on <window> element" -msgid "Unknown attribute %s on <%s> element" -msgstr "<%2$s> घटक वरील अपरिचीत गुणधर्म %1$s" - -#: ../src/core/session.c:1211 -#, c-format -msgid "nested <window> tag" -msgstr "नेस्टेड <window> टॅग" - -#: ../src/core/session.c:1453 -#, c-format -msgid "Unknown element %s" -msgstr "अपरिचीत घटक %s" +#: ../data/50-mutter-navigation.xml.in.h:2 +msgid "Move window to workspace 1" +msgstr "पटल कार्यक्षेत्र १ वर हलवा" -#: ../src/core/session.c:1879 -#, c-format -msgid "" -"Error launching metacity-dialog to warn about apps that don't support " -"session management: %s\n" -msgstr "" -"सत्र व्यवस्थापन समर्थन प्रदान न करणारे अनुप्रयोगांविषयी सावधान करण्याकरीता metacity-" -"dialog दाखल करतेवेळी त्रुटी: %s\n" +#: ../data/50-mutter-navigation.xml.in.h:3 +msgid "Move window to workspace 2" +msgstr "पटल कार्यक्षेत्र २ वर हलवा" -#: ../src/core/util.c:101 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "डिबग लॉग उघडण्यास अपयश आले: %s\n" +#: ../data/50-mutter-navigation.xml.in.h:4 +msgid "Move window to workspace 3" +msgstr "पटल कार्यक्षेत्र ३ वर हलवा" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "एफडीउघड() लॉग फाइल उघडण्यास अपयशी%s: %s\n" +#: ../data/50-mutter-navigation.xml.in.h:5 +msgid "Move window to workspace 4" +msgstr "पटल कार्यक्षेत्र ४ वर हलवा" -#: ../src/core/util.c:117 -#, c-format -msgid "Opened log file %s\n" -msgstr "लॉग फाइल %s उघडली\n" +#: ../data/50-mutter-navigation.xml.in.h:6 +#| msgid "Move window to workspace 1" +msgid "Move window to last workspace" +msgstr "पटलाला शेवटच्या कार्यक्षेत्रकरिता स्थानांतरित करा" -#: ../src/core/util.c:136 ../src/tools/metacity-message.c:176 -#, c-format -msgid "Metacity was compiled without support for verbose mode\n" -msgstr "Metacity शब्दबंबाळ रितीव्यतिरिक्त कम्पाइल केला होता\n" +#: ../data/50-mutter-navigation.xml.in.h:7 +msgid "Move window one workspace to the left" +msgstr "पटल एक कार्यक्षेत्र डावीकडे हलवा" -#: ../src/core/util.c:236 -msgid "Window manager: " -msgstr "चौकट व्यवस्थापक: " +#: ../data/50-mutter-navigation.xml.in.h:8 +msgid "Move window one workspace to the right" +msgstr "पटल एक कार्यक्षेत्र उजवीकडे हलवा" -#: ../src/core/util.c:388 -msgid "Bug in window manager: " -msgstr "चौकट व्यवस्थापकात त्रुटी: " +#: ../data/50-mutter-navigation.xml.in.h:9 +msgid "Move window one workspace up" +msgstr "पटल एक कार्यक्षेत्र वर हलवा" -#: ../src/core/util.c:421 -msgid "Window manager warning: " -msgstr "चौकट व्यवस्थापक सुचना: " +#: ../data/50-mutter-navigation.xml.in.h:10 +msgid "Move window one workspace down" +msgstr "पटल एक कार्यक्षेत्र खाली हलवा" + +#: ../data/50-mutter-navigation.xml.in.h:11 +#| msgid "Move window one workspace to the left" +msgid "Move window one monitor to the left" +msgstr "पटलाला एक मॉनिटर डावीकडे हलवा" + +#: ../data/50-mutter-navigation.xml.in.h:12 +#| msgid "Move window one workspace to the right" +msgid "Move window one monitor to the right" +msgstr "पटलाला एक मॉनिटर ऊजवीकडे हलवा" + +#: ../data/50-mutter-navigation.xml.in.h:13 +#| msgid "Move window one workspace up" +msgid "Move window one monitor up" +msgstr "पटलाला एक मॉनिटर वर हलवा" + +#: ../data/50-mutter-navigation.xml.in.h:14 +#| msgid "Move window one workspace down" +msgid "Move window one monitor down" +msgstr "पटलाला एक मॉनिटर खाली हलवा" + +#: ../data/50-mutter-navigation.xml.in.h:15 +msgid "Switch applications" +msgstr "ॲप्लिकेशन्स बदला" + +#: ../data/50-mutter-navigation.xml.in.h:16 +#| msgid "Switch applications" +msgid "Switch to previous application" +msgstr "मागील ॲप्लिकेशनचा वापर करा" + +#: ../data/50-mutter-navigation.xml.in.h:17 +msgid "Switch windows" +msgstr "पटल बदला" + +#: ../data/50-mutter-navigation.xml.in.h:18 +#| msgid "Switch windows" +msgid "Switch to previous window" +msgstr "मागील पटलाचा वापर करा" + +#: ../data/50-mutter-navigation.xml.in.h:19 +msgid "Switch windows of an application" +msgstr "ॲप्लिकेशनच्या पटलांना बदला" + +#: ../data/50-mutter-navigation.xml.in.h:20 +#| msgid "Switch windows of an application" +msgid "Switch to previous window of an application" +msgstr "ॲप्लिकेशनच्या मागील पटलाचा वापर करा" + +#: ../data/50-mutter-navigation.xml.in.h:21 +msgid "Switch system controls" +msgstr "सिस्टम कंट्रोल्स् बदला" + +#: ../data/50-mutter-navigation.xml.in.h:22 +#| msgid "Switch system controls" +msgid "Switch to previous system control" +msgstr "मागील प्रणाली नियंत्रणाचा वापर करा" + +#: ../data/50-mutter-navigation.xml.in.h:23 +msgid "Switch windows directly" +msgstr "पटलांना प्रत्यक्षरित्या बदला" + +#: ../data/50-mutter-navigation.xml.in.h:24 +msgid "Switch directly to previous window" +msgstr "मागील पटलाचा प्रत्यक्षरित्या वापर करा" + +#: ../data/50-mutter-navigation.xml.in.h:25 +msgid "Switch windows of an app directly" +msgstr "पटलांना ॲप्लिकेशनकरीता प्रत्यक्षरित्या बदला" + +#: ../data/50-mutter-navigation.xml.in.h:26 +#| msgid "Switch windows of an application" +msgid "Switch directly to previous window of an app" +msgstr "ॲप्लिकेशनच्या मागील पटलाचा प्रत्यक्षरित्या वापर करा" + +#: ../data/50-mutter-navigation.xml.in.h:27 +msgid "Switch system controls directly" +msgstr "सिस्टम कंट्रोल्स प्रत्यक्षरित्या बदला" + +#: ../data/50-mutter-navigation.xml.in.h:28 +#| msgid "Switch system controls" +msgid "Switch directly to previous system control" +msgstr "मागील प्रणाली नियंत्रणाचा प्रत्यक्षरित्या वापर करा" + +#: ../data/50-mutter-navigation.xml.in.h:29 +msgid "Hide all normal windows" +msgstr "सर्व साधारण पटलांना लपवा" + +#: ../data/50-mutter-navigation.xml.in.h:30 +msgid "Switch to workspace 1" +msgstr "कार्यक्षेत्र १चा वापर करा" -#: ../src/core/util.c:449 -msgid "Window manager error: " -msgstr "चौकट व्यवस्थापक त्रुटी: " +#: ../data/50-mutter-navigation.xml.in.h:31 +msgid "Switch to workspace 2" +msgstr "कार्यक्षेत्र २चा वापर करा" -#. Translators: This is the title used on dialog boxes -#. eof all-keybindings.h -#: ../src/core/util.c:577 ../src/metacity.desktop.in.h:1 -#: ../src/metacity-wm.desktop.in.h:1 -msgid "Metacity" -msgstr "Metacity" +#: ../data/50-mutter-navigation.xml.in.h:32 +msgid "Switch to workspace 3" +msgstr "कार्यक्षेत्र ३चा वापर करा" -#. first time through -#: ../src/core/window.c:5626 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"ICCCM मधिल निश्चित केलेल्या WM_CLIENT_LEADER चौकट ऐवजी चौकट %s, स्वतःवरच " -"SM_CLIENT_ID निश्चित करते.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:6191 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %" -"d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"चौकट %s MWM निश्चित करतो ज्याचा अर्थ ते पुन्हआकार देण्याजोगी नाही, परंतु किमान आकार %d " -"x %d व कमाल आकार %d x %d; निश्चित करते ज्याचा जास्त अर्थ दिसून येत नाही.\n" +#: ../data/50-mutter-navigation.xml.in.h:33 +msgid "Switch to workspace 4" +msgstr "कार्यक्षेत्र ४चा वापर करा" -#: ../src/core/window-props.c:260 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "अनुप्रयोग फरजी _NET_WM_PID %lu निश्चित करा\n" +#: ../data/50-mutter-navigation.xml.in.h:34 +#| msgid "Switch to workspace 1" +msgid "Switch to last workspace" +msgstr "अखेरच्या कार्यक्षेत्राचा वापर करा" -#: ../src/core/window-props.c:377 -#, c-format -msgid "%s (on %s)" -msgstr "%1$s (%2$s वर)" +#: ../data/50-mutter-navigation.xml.in.h:35 +msgid "Move to workspace left" +msgstr "डाव्या कार्यक्षेत्रावर जा" -#: ../src/core/window-props.c:1358 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "%2$s करीता अवैध WM_TRANSIENT_FOR window 0x%1$lx निश्चित केले गेले.\n" +#: ../data/50-mutter-navigation.xml.in.h:36 +msgid "Move to workspace right" +msgstr "उजव्या कार्यक्षेत्रावर जा" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"Window 0x%lx चे गुणधर्म %s\n" -"ज्याला प्रकार %s स्वरूप %d असणे अपेक्षीत होते\n" -"व वास्तवीकरित्या त्याचा प्रकार %s स्वरूप %d n_items %d आहे.\n" -"ये संभाव्यरित्या अनुप्रयोग दोष आहे, व चौकट व्यवस्थापक दोष नाही.\n" -"चौकटचे शिर्षक=\"%s\" वर्ग=\"%s\" नाव=\"%s\" या प्रमाणे आहे\n" +#: ../data/50-mutter-navigation.xml.in.h:37 +msgid "Move to workspace above" +msgstr "वरील कार्यक्षेत्रावर जा" -#: ../src/core/xprops.c:401 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "चौकट %s वरील गुणधर्म 0x%lx चुकीचे UTF-8 साठविले\n" +#: ../data/50-mutter-navigation.xml.in.h:38 +msgid "Move to workspace below" +msgstr "खालिल कार्यक्षेत्रावर जा" -#: ../src/core/xprops.c:484 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"चौकट 0x%2$lx वरील गुणधर्म %1$s मध्ये यादी मधिल %3$d करीता अवैध UTF-8 घटक " -"समाविष्टीत\n" +#: ../data/50-mutter-system.xml.in.h:1 +msgid "System" +msgstr "प्रणाली" -#: ../src/include/all-keybindings.h:88 -msgid "Switch to workspace 1" -msgstr "कार्यक्षेत्र १ वर जा" +#: ../data/50-mutter-system.xml.in.h:2 +msgid "Show the run command prompt" +msgstr "रन कमांड प्रॉम्प्ट दाखवा" -#: ../src/include/all-keybindings.h:90 -msgid "Switch to workspace 2" -msgstr "कार्यक्षेत्र २ वर जा" +#: ../data/50-mutter-system.xml.in.h:3 +msgid "Show the activities overview" +msgstr "कार्यांचे अवलोकन दाखवा" -#: ../src/include/all-keybindings.h:92 -msgid "Switch to workspace 3" -msgstr "कार्यक्षेत्र ३ वर जा" +#: ../data/50-mutter-windows.xml.in.h:1 +msgid "Windows" +msgstr "पटल" -#: ../src/include/all-keybindings.h:94 -msgid "Switch to workspace 4" -msgstr "कार्यक्षेत्र ४ वर जा" - -#: ../src/include/all-keybindings.h:96 -msgid "Switch to workspace 5" -msgstr "कार्यक्षेत्र ५ वर जा" - -#: ../src/include/all-keybindings.h:98 -msgid "Switch to workspace 6" -msgstr "कार्यक्षेत्र ६ वर जा" - -#: ../src/include/all-keybindings.h:100 -msgid "Switch to workspace 7" -msgstr "कार्यक्षेत्र ७ वर जा" - -#: ../src/include/all-keybindings.h:102 -msgid "Switch to workspace 8" -msgstr "कार्यक्षेत्र ८ वर जा" - -#: ../src/include/all-keybindings.h:104 -msgid "Switch to workspace 9" -msgstr "कार्यक्षेत्र ९ वर जा" - -#: ../src/include/all-keybindings.h:106 -msgid "Switch to workspace 10" -msgstr "कार्यक्षेत्र १० वर जा" - -#: ../src/include/all-keybindings.h:108 -msgid "Switch to workspace 11" -msgstr "कार्यक्षेत्र ११ वर जा" - -#: ../src/include/all-keybindings.h:110 -msgid "Switch to workspace 12" -msgstr "कार्यक्षेत्र १२ वर जा" - -#: ../src/include/all-keybindings.h:122 -#| msgid "Switch to workspace on the left" -msgid "Switch to workspace on the left of the current workspace" -msgstr "वर्तमान कार्यक्षेत्रच्या डाव्या बाजूचे कार्यक्षेत्र वापरा" - -#: ../src/include/all-keybindings.h:126 -#| msgid "Switch to workspace on the right" -msgid "Switch to workspace on the right of the current workspace" -msgstr "वर्तमान कार्यक्षेत्रच्या उजव्या बाजूचे कार्यक्षेत्र वापरा" - -#: ../src/include/all-keybindings.h:130 -#| msgid "Switch to workspace above this one" -msgid "Switch to workspace above the current workspace" -msgstr "वर्तमान कार्यक्षेत्रच्या वरच्या बाजूचे कार्यक्षेत्र वापरा" - -#: ../src/include/all-keybindings.h:134 -#| msgid "Switch to workspace below this one" -msgid "Switch to workspace below the current workspace" -msgstr "वर्तमान कार्यक्षेत्रच्या खालच्या बाजूचे कार्यक्षेत्र वापरा" - -#: ../src/include/all-keybindings.h:150 -#| msgid "Move between windows of an application with popup" -msgid "Move between windows of an application, using a popup window" -msgstr "पॉपअप खिडकीचा वापर करून, अनुप्रोयगच्या खिडकी अंतर्गत हला" - -#: ../src/include/all-keybindings.h:153 -#| msgid "Move backwards between windows of an application with popup" -msgid "Move backward between windows of an application, using a popup window" -msgstr "पॉपअप खिडकीचा वापर करून, अनुप्रोयगच्या खिडकी अंतर्गत मागे हला" - -#: ../src/include/all-keybindings.h:157 -#| msgid "Move between windows with popup" -msgid "Move between windows, using a popup window" -msgstr "पॉपअप खिडकीचा वापर करून, खिडकी अंतर्गत हला" - -#: ../src/include/all-keybindings.h:160 -#| msgid "Move focus backwards between windows using popup display" -msgid "Move backward between windows, using a popup window" -msgstr "पॉपअप खिडकीचा वापर करून, खिडकी अंतर्गत मागे हला" - -#: ../src/include/all-keybindings.h:163 -#| msgid "Move between panels and the desktop with popup" -msgid "Move between panels and the desktop, using a popup window" -msgstr "पॉपअप खिडकीचा वापर करून, पटल व डेस्कटॉप अंतर्गत हला" - -#: ../src/include/all-keybindings.h:166 -#| msgid "Move backwards between panels and the desktop with popup" -msgid "Move backward between panels and the desktop, using a popup window" -msgstr "पॉपअप खिडकीचा वापर करून, पटल व डेस्कटॉप अंतर्गत मागे हला" - -#: ../src/include/all-keybindings.h:171 -msgid "Move between windows of an application immediately" -msgstr "अनुप्रयोगतील चौकट मधून त्वरीत स्थानांतरीत व्हा" - -#: ../src/include/all-keybindings.h:174 -#| msgid "Move backwards between windows of an application immediately" -msgid "Move backward between windows of an application immediately" -msgstr "अनुप्रयोगाच्या खिडकी अंतर्गत लगेच मागे हला" - -#: ../src/include/all-keybindings.h:177 -msgid "Move between windows immediately" -msgstr "चौकट मधून लगेच स्थानांतरीत व्हा" - -#: ../src/include/all-keybindings.h:180 -#| msgid "Move backwards between windows immediately" -msgid "Move backward between windows immediately" -msgstr "खिडकी अंतर्गत लगेच मागे हला" - -#: ../src/include/all-keybindings.h:183 -msgid "Move between panels and the desktop immediately" -msgstr "पटल आणि डेस्कटॉप यामधून लगेचच स्थानांतरीत व्हा" - -#: ../src/include/all-keybindings.h:186 -msgid "Move backward between panels and the desktop immediately" -msgstr "डेस्कटॉप व पॅनल यामधून लगेचच मागे व्हा" - -#: ../src/include/all-keybindings.h:191 -#| msgid "Hide all windows and focus desktop" -msgid "Hide all normal windows and set focus to the desktop" -msgstr "सर्व खिडक्या लपवा व केंद्रबिन्दू डेस्कटॉप वर निश्चित करा" - -#: ../src/include/all-keybindings.h:194 -#| msgid "Show the panel menu" -msgid "Show the panel's main menu" -msgstr "पटलाचे मुख्य मेन्यू दाखवा" - -#: ../src/include/all-keybindings.h:197 -#| msgid "Show the panel run application dialog" -msgid "Show the panel's \"Run Application\" dialog box" -msgstr "पटलाचे \"Run Application\" संवाद पेटी दाखवा" - -#: ../src/include/all-keybindings.h:238 -msgid "Take a screenshot" -msgstr "स्क्रीनशॉट घ्या" - -#: ../src/include/all-keybindings.h:240 -msgid "Take a screenshot of a window" -msgstr "चौकटचे स्क्रीनशॉट घ्या" - -#: ../src/include/all-keybindings.h:242 -msgid "Run a terminal" -msgstr "टर्मिनल चालवा" - -#: ../src/include/all-keybindings.h:257 -#| msgid "Activate window menu" +#: ../data/50-mutter-windows.xml.in.h:2 msgid "Activate the window menu" -msgstr "खिडकी मेन्यू सक्रीय करा" +msgstr "पटल मेन्यु सक्रीय करा" -#: ../src/include/all-keybindings.h:260 +#: ../data/50-mutter-windows.xml.in.h:3 msgid "Toggle fullscreen mode" -msgstr "पूर्ण पडदा पध्दती टॉगल करा" +msgstr "पडदाभर मोड टॉगल करा" -#: ../src/include/all-keybindings.h:262 +#: ../data/50-mutter-windows.xml.in.h:4 msgid "Toggle maximization state" -msgstr "जास्तीत जास्त स्थितीत टॉगल करा" +msgstr "मॅक्सीमाइजेशन स्तर टॉगल करा" -#: ../src/include/all-keybindings.h:264 -#| msgid "Lower window below other windows" -msgid "Toggle whether a window will always be visible over other windows" -msgstr "खिडकी इतर खिडकींवर नेहमी दृष्यास्पद होईल का त्याकरीता टॉगल करा" - -#: ../src/include/all-keybindings.h:266 +#: ../data/50-mutter-windows.xml.in.h:5 msgid "Maximize window" -msgstr "चौकट मोठी करा" +msgstr "पटल मोठे करा" -#: ../src/include/all-keybindings.h:268 -#| msgid "Resize window" +#: ../data/50-mutter-windows.xml.in.h:6 msgid "Restore window" -msgstr "खिडकी पूर्वस्थितीत आणा" +msgstr "पटल पूर्वस्थितीत आणा" -#: ../src/include/all-keybindings.h:270 +#: ../data/50-mutter-windows.xml.in.h:7 msgid "Toggle shaded state" -msgstr "सावलीतील स्थितीत टॉगल करा" - -#: ../src/include/all-keybindings.h:272 -msgid "Minimize window" -msgstr "चौकट लहान करा" +msgstr "शेडेड स्तर टॉगल करा" -#: ../src/include/all-keybindings.h:274 +#: ../data/50-mutter-windows.xml.in.h:8 msgid "Close window" -msgstr "चौकट बंद करा" +msgstr "पटल बंद करा" -#: ../src/include/all-keybindings.h:276 +#: ../data/50-mutter-windows.xml.in.h:9 +msgid "Hide window" +msgstr "पटल लपवा" + +#: ../data/50-mutter-windows.xml.in.h:10 msgid "Move window" -msgstr "चौकट हलवा" +msgstr "पटल हलवा" -#: ../src/include/all-keybindings.h:278 +#: ../data/50-mutter-windows.xml.in.h:11 msgid "Resize window" -msgstr "चौकट पुनःआकार करा" - -#: ../src/include/all-keybindings.h:281 -#| msgid "Toggle window on all workspaces" -msgid "Toggle whether window is on all workspaces or just one" -msgstr "सर्व किंवा फक्त एकच वर्कस्पेस वर खिडकी स्थित आहे त्याकरीता टॉगल करा" - -#: ../src/include/all-keybindings.h:285 -msgid "Move window to workspace 1" -msgstr "चौकट कार्यक्षेत्र १ वर हलवा" - -#: ../src/include/all-keybindings.h:288 -msgid "Move window to workspace 2" -msgstr "चौकट कार्यक्षेत्र २ वर हलवा" - -#: ../src/include/all-keybindings.h:291 -msgid "Move window to workspace 3" -msgstr "चौकट कार्यक्षेत्र ३ वर हलवा" - -#: ../src/include/all-keybindings.h:294 -msgid "Move window to workspace 4" -msgstr "चौकट कार्यक्षेत्र ४ वर हलवा" - -#: ../src/include/all-keybindings.h:297 -msgid "Move window to workspace 5" -msgstr "चौकट कार्यक्षेत्र ५ वर हलवा" - -#: ../src/include/all-keybindings.h:300 -msgid "Move window to workspace 6" -msgstr "चौकट कार्यक्षेत्र ६ वर हलवा" - -#: ../src/include/all-keybindings.h:303 -msgid "Move window to workspace 7" -msgstr "चौकट कार्यक्षेत्र ७ वर हलवा" - -#: ../src/include/all-keybindings.h:306 -msgid "Move window to workspace 8" -msgstr "चौकट कार्यक्षेत्र ८ वर हलवा" +msgstr "पटल आकार बदला" -#: ../src/include/all-keybindings.h:309 -msgid "Move window to workspace 9" -msgstr "चौकट कार्यक्षेत्र ९ वर हलवा" +#: ../data/50-mutter-windows.xml.in.h:12 +msgid "Toggle window on all workspaces or one" +msgstr "पटलास सर्व कार्यक्षेत्र किंवा एका कार्यक्षेत्राचा वापर करा" -#: ../src/include/all-keybindings.h:312 -msgid "Move window to workspace 10" -msgstr "चौकट कार्यक्षेत्र १० वर हलवा" +#: ../data/50-mutter-windows.xml.in.h:13 +msgid "Raise window if covered, otherwise lower it" +msgstr "कवर केले असल्यास पटल ऊंचवा, नाहीतर खाली करा" -#: ../src/include/all-keybindings.h:315 -msgid "Move window to workspace 11" -msgstr "चौकट कार्यक्षेत्र ११ वर हलवा" - -#: ../src/include/all-keybindings.h:318 -msgid "Move window to workspace 12" -msgstr "चौकट कार्यक्षेत्र १२ वर हलवा" - -#: ../src/include/all-keybindings.h:330 -msgid "Move window one workspace to the left" -msgstr "चौकट एक कार्यक्षेत्र डावीकडे हलवा" - -#: ../src/include/all-keybindings.h:333 -msgid "Move window one workspace to the right" -msgstr "चौकट एक कार्यक्षेत्र उजवीकडे हलवा" - -#: ../src/include/all-keybindings.h:336 -msgid "Move window one workspace up" -msgstr "चौकट एक कार्यक्षेत्र वर हलवा" - -#: ../src/include/all-keybindings.h:339 -msgid "Move window one workspace down" -msgstr "चौकट एक कार्यक्षेत्र खाली हलवा" - -#: ../src/include/all-keybindings.h:342 -#| msgid "Raise obscured window, otherwise lower" -msgid "Raise window if it's covered by another window, otherwise lower it" -msgstr "इतर खिडकी द्वारे झाकलेले असल्यावर खिडकी उंचावा, नाहीतर खाली सरकवा" - -#: ../src/include/all-keybindings.h:344 +#: ../data/50-mutter-windows.xml.in.h:14 msgid "Raise window above other windows" -msgstr "इतर चौकटवर चौकट प्राधान्यकृत करा" +msgstr "इतर पटलांच्या तुलनेत पटल वर करा" -#: ../src/include/all-keybindings.h:346 +#: ../data/50-mutter-windows.xml.in.h:15 msgid "Lower window below other windows" -msgstr "इतर खिडक्यांच्या खाली तळाची चौकट" +msgstr "इतर पटलांच्या तुलनेत पटल खाली करा" -#: ../src/include/all-keybindings.h:350 +#: ../data/50-mutter-windows.xml.in.h:16 msgid "Maximize window vertically" -msgstr "चौकट उभी मोठी करा" +msgstr "पटल उभ्यारित्या वाढवा" -#: ../src/include/all-keybindings.h:354 +#: ../data/50-mutter-windows.xml.in.h:17 msgid "Maximize window horizontally" -msgstr "चौकट आडवी मोठी करा" - -#: ../src/include/all-keybindings.h:358 -#| msgid "Move window to north-west corner" -msgid "Move window to north-west (top left) corner" -msgstr "खिडकीला उत्तर-पश्चिम (वरून डावीकडे) बाजूस हलवा" - -#: ../src/include/all-keybindings.h:361 -#| msgid "Move window to north-east corner" -msgid "Move window to north-east (top right) corner" -msgstr "खिडकीला उत्तर-पूर्व (वरून उजवीकडे) बाजूस हलवा" - -#: ../src/include/all-keybindings.h:364 -#| msgid "Move window to south-west corner" -msgid "Move window to south-west (bottom left) corner" -msgstr "खिडकीला दक्षिण-पश्चिम (खालून डावीकडे) बाजूस हलवा" - -#: ../src/include/all-keybindings.h:367 -#| msgid "Move window to south-east corner" -msgid "Move window to south-east (bottom right) corner" -msgstr "खिडकीला दक्षिण-पूर्व (खालून उजवीकडे) बाजूस हलवा" - -#: ../src/include/all-keybindings.h:371 -#| msgid "Move window to north side of screen" -msgid "Move window to north (top) side of screen" -msgstr "खिडकीला पडद्याच्या उत्तर (शिर्ष) बाजूस हलवा" - -#: ../src/include/all-keybindings.h:374 -#| msgid "Move window to south side of screen" -msgid "Move window to south (bottom) side of screen" -msgstr "खिडकीला पडद्याच्या दक्षिण (तळ) बाजूस हलवा" - -#: ../src/include/all-keybindings.h:377 -#| msgid "Move window to east side of screen" -msgid "Move window to east (right) side of screen" -msgstr "खिडकीला पडद्याच्या पूर्व (उजवे) बाजूस हलवा" - -#: ../src/include/all-keybindings.h:380 -#| msgid "Move window to west side of screen" -msgid "Move window to west (left) side of screen" -msgstr "खिडकीला पडद्याच्या पश्चिम (डावे) बाजूस हलवा" - -#: ../src/include/all-keybindings.h:383 -#| msgid "Move window to east side of screen" -msgid "Move window to center of screen" -msgstr "खिडकीला पडद्याच्या मध्य बाजूस हलवा" - -#: ../src/metacity.schemas.in.in.h:1 -msgid "(Not implemented) Navigation works in terms of applications not windows" -msgstr "(कार्यान्वीत नाही) संचार अनुप्रयोगच्या स्वरूपात कार्य करते चौकटच्या स्वरूपात नाही" - -#: ../src/metacity.schemas.in.in.h:2 -msgid "" -"A font description string describing a font for window titlebars. The size " -"from the description will only be used if the titlebar_font_size option is " -"set to 0. Also, this option is disabled if the titlebar_uses_desktop_font " -"option is set to true." -msgstr "" -"चौकट शिर्षकपट्टी करीता फॉन्ट वर्णन अक्षरमाळा परिभाषीत करा. परिभाषातील आकार तेव्हाच " -"वापरले जाईल जेव्हा शिर्षकपट्टी_फॉन्ट_आकार पर्याय 0 करीता निश्चित केले जाईल. आणखी, जर " -"हा पर्याय अकार्यान्वीत केला जाईल जर शिर्षकपट्टी_डेस्कटॉप_फॉन्ट_वापर पर्याय खरे आहे असे " -"निश्चितही केले जाऊ शकते." - -#: ../src/metacity.schemas.in.in.h:3 -msgid "Action on title bar double-click" -msgstr "शिर्षक पट्टीवरील दोनवेळा क्लिक केल्यावरची कृती" - -#: ../src/metacity.schemas.in.in.h:4 -msgid "Action on title bar middle-click" -msgstr "शिर्षक पट्टीवरील मध्य क्लिक केल्यावरची कृती" - -#: ../src/metacity.schemas.in.in.h:5 -msgid "Action on title bar right-click" -msgstr "शिर्षक पट्टीवरील उजवी क्लिक केल्यावरची कृती" - -#: ../src/metacity.schemas.in.in.h:6 -msgid "Arrangement of buttons on the titlebar" -msgstr "शिर्षक पट्टीवरील बटणांची मांडणी" - -#: ../src/metacity.schemas.in.in.h:7 -#| msgid "" -#| "Arrangement of buttons on the titlebar. The value should be a string, " -#| "such as \"menu:minimize,maximize,close\"; the colon separates the left " -#| "corner of the window from the right corner, and the button names are " -#| "comma-separated. Duplicate buttons are not allowed. Unknown button names " -#| "are silently ignored so that buttons can be added in future metacity " -#| "versions without breaking older versions." -msgid "" -"Arrangement of buttons on the titlebar. The value should be a string, such " -"as \"menu:minimize,maximize,spacer,close\"; the colon separates the left " -"corner of the window from the right corner, and the button names are comma-" -"separated. Duplicate buttons are not allowed. Unknown button names are " -"silently ignored so that buttons can be added in future metacity versions " -"without breaking older versions. A special spacer tag can be used to insert " -"some space between two adjacent buttons." -msgstr "" -"शिर्षक पट्टीवरील बटणांची मांडणी. मुल्य अक्षरमाळा असायला हवे, जसे की \"menu:minimize,maximize,spacer,close\"; द्विबिंदुचिन्ह चौकटीच्या उजव्या कोपऱ्यापासून डावी कोपरा अलग करतो, " -"व बटण नाव स्वल्पविराम-विभाजीत आसतात. समान बटणांना परवानगी नाही. अपरिचीत बटण नाव " -"दुर्लक्षीत केले जाते ज्यामुळे बटण भविष्यात मेटासिटी आवृत्ती करीता जुनी आवृत्ती न मोडता " -"जोडल्या जाऊ शकते. दोन बटणांच्या अंतर्गत मोकळी जागा अंतर्भूत करण्याकरीता स्पेसर टॅग वापरले जाऊ शकते." - -#: ../src/metacity.schemas.in.in.h:8 -msgid "Automatically raises the focused window" -msgstr "फोकस केलेली चौकट आपोआप उघडते" - -#: ../src/metacity.schemas.in.in.h:9 -#| msgid "" -#| "Clicking a window while holding down this modifier key will move the " -#| "window (left click), resize the window (middle click), or show the window " -#| "menu (right click). Modifier is expressed as \"<Alt>\" or \"<" -#| "Super>\" for example." -msgid "" -"Clicking a window while holding down this modifier key will move the window " -"(left click), resize the window (middle click), or show the window menu " -"(right click). The left and right operations may be swapped using the " -"\"mouse_button_resize\" key. Modifier is expressed as \"<Alt>\" or " -"\"<Super>\" for example." -msgstr "" -"ही संपादन कळ दाबून ठेवल्यास चौकटवर किल्क केल्यास चौकट हलविले जाईल (डावी क्लिक), चौकट " -"पुन्ह आकार (मध्य किल्क), किंवा चौकट मेन्यू दर्शवायचे असल्यास (उजवी क्लिक) चा वापर केला " -"जाऊ शकतो. \"mouse_button_resize\" कि याचा वापर करून डावे व उजवे कार्य स्वॅप केले जाऊ शकते. " -"मॉडिफायर \"<Alt>\" किंवा \"<Super>\" यानुरूप स्वॅप केले जाऊ शकते." - -#: ../src/metacity.schemas.in.in.h:10 -msgid "Commands to run in response to keybindings" -msgstr "कळीच्या बंधाना प्रतिसाद म्हणून आदेश काम करतात" +msgstr "पटल आडवीरित्या मोठे करा" -#: ../src/metacity.schemas.in.in.h:11 -msgid "Compositing Manager" -msgstr "व्यवस्थापक संयोजीत करीत आहे" +#: ../data/50-mutter-windows.xml.in.h:18 +msgid "View split on left" +msgstr "डावीकडील विभाजनचे अवलोकन" -#: ../src/metacity.schemas.in.in.h:12 -msgid "Control how new windows get focus" -msgstr "नविन चौकटीस लक्ष्यकेंद्रीत कसे करायचे ते नियंत्रीत करते" +#: ../data/50-mutter-windows.xml.in.h:19 +msgid "View split on right" +msgstr "उजवीकडील विभाजनचे अवलोकन" -#: ../src/metacity.schemas.in.in.h:13 -msgid "Current theme" -msgstr "सद्याची सुत्रयोजना" +#: ../data/mutter.desktop.in.h:1 +msgid "Mutter" +msgstr "मुटर" -#: ../src/metacity.schemas.in.in.h:14 -msgid "Delay in milliseconds for the auto raise option" -msgstr "स्व वाढ पर्यायकरीता मिलीसेकंदामधिल उशीर" +#: ../data/org.gnome.mutter.gschema.xml.in.h:1 +msgid "Modifier to use for extended window management operations" +msgstr "वाढिव पटल व्यवस्थापन कार्यांकरीता वापरण्याजोगी मॉडिफायर" -#: ../src/metacity.schemas.in.in.h:15 -msgid "Determines whether Metacity is a compositing manager." -msgstr "Metacity संयोजना व्यस्थापक आहे का ते निश्चित करते." - -#: ../src/metacity.schemas.in.in.h:16 +#: ../data/org.gnome.mutter.gschema.xml.in.h:2 msgid "" -"Determines whether applications or the system can generate audible 'beeps'; " -"may be used in conjunction with 'visual bell' to allow silent 'beeps'." +"This key will initiate the \"overlay\", which is a combination window " +"overview and application launching system. The default is intended to be the " +"\"Windows key\" on PC hardware. It's expected that this binding either the " +"default or set to the empty string." msgstr "" -"अनुप्रयोग किंवा प्रणाली एकण्याजोगी 'बीप' निर्माण करू शकते की नाही ते निश्चित करते; शांत " -"'बीप' करीता परवानगी देण्यास दृश्यात्मक घंटाशी संयुक्तपणे वापरले जाऊ शकते." - -#: ../src/metacity.schemas.in.in.h:17 -msgid "Disable misfeatures that are required by old or broken applications" -msgstr "जुन्या व टाकाऊ कार्यक्रम आवश्यक अयोग्य गुणधर्म अकार्यक्षम करा" +"हि कि \"overlay\" सुरू करतो, जे पटल पुनरावलोकन व ॲप्लिकेशन सुरू करण्यासाठीची " +"प्रणाली " +"आहे. पूर्वनिर्धारित PC हार्डवेअरवरील \"Windows key\" आहे. असे अपेक्षित आहे कि " +"हि बाइंडिंग " +"एकतर पूर्वनिर्धारित किंवा रिकामी स्ट्रिंगकरीता निश्चित केली आहे." -#: ../src/metacity.schemas.in.in.h:18 -msgid "Enable Visual Bell" -msgstr "दृश्य घंटा सक्षम करा" +#: ../data/org.gnome.mutter.gschema.xml.in.h:3 +msgid "Attach modal dialogs" +msgstr "मोडल संवाद जोडा" -#: ../src/metacity.schemas.in.in.h:19 +#: ../data/org.gnome.mutter.gschema.xml.in.h:4 msgid "" -"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " -"the focused window will be automatically raised after a delay specified by " -"the auto_raise_delay key. This is not related to clicking on a window to " -"raise it, nor to entering a window during drag-and-drop." +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." msgstr "" -"खरे निश्चित केल्यास, व लक्ष्यकेंद्र पध्दती एकतर \"गचाळ\" किंवा \"माउस\" असल्यास " -"लक्ष्यकेंद्रीय चौकट आपोआप स्व_वाढ_उशीर किल्ली द्वारे निश्चित उशीर नंतर दृश्यीस केले जाईल. हे " -"चौकटवर क्लिक केल्यास चौकट दर्शविण्याकरीता समान नाही, व ओढा-व-टाकावेळी चौकट दाखलन " -"समान देखिल नाही." +"खरे असल्यास, स्वतंत्र शीर्षकपट्टी ऐवजी, पॅरेंट पटलाशी जोडलेल्या शीर्षकपट्टीसह " +"मोडल संवाद " +"आढळतात व पॅरेंट पटलासह एकत्रपणे स्थानांतरीत केले जातात." -#: ../src/metacity.schemas.in.in.h:20 -msgid "" -"If true, ignore the titlebar_font option, and use the standard application " -"font for window titles." -msgstr "" -"खरे असल्यास, शिर्षकपट्टी_फॉन्ट पर्याय दुर्लक्ष करा, व चौकट शिर्षक करीता मानक अनुप्रयोग " -"फॉन्ट वापरा." +#: ../data/org.gnome.mutter.gschema.xml.in.h:5 +msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "स्क्रीन एड्जेसवर पटलांना वगळतेवेळी एड्ज टाइलिंग सुरू करा" -#: ../src/metacity.schemas.in.in.h:21 +#: ../data/org.gnome.mutter.gschema.xml.in.h:6 msgid "" -"If true, metacity will give the user less feedback by using wireframes, " -"avoiding animations, or other means. This is a significant reduction in " -"usability for many users, but may allow legacy applications to continue " -"working, and may also be a useful tradeoff for terminal servers. However, " -"the wireframe feature is disabled when accessibility is on." +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." msgstr "" -"खरे असल्यास, मेटासिटी वापरकर्त्यास वायरफ्रेम, चित्रचेतनीकरण दुर्लक्ष करून, किंवा अन्य " -"कुठल्याही तऱ्हेचा वापर करून कमी प्रतिसाद देते. हे बहुदा वापरकर्त्यास वापरणीच्या " -"दृष्टीकोणातून महत्वाचे नाही, पण कार्यरत राहण्याकरीता लेगसी अनुप्रोयागला परवानगी देऊ " -"शकते, व टर्मिनल सर्वर करीता उपयोगी ठरू शकते. तरी, प्रवेश सुरू असल्यास वायरफ्रेम वैशिष्ट्ये " -"अकार्यान्वीत केले जाते." +"सुरू असल्यास, उभी स्क्रीन किनाऱ्यांवर पटल स्थिती केल्यास उभ्यादिशेना वाढवते व " +"उपलब्ध " +"क्षेत्राचे अर्धे भाग समाविष्ट करायचे असल्यास आडवेरित्या पुनःआकार देते. शीर्ष " +"पडद्यावरील " +"किनारवर पटल स्थित केल्यास त्यांना पूर्णपणे वाढवतो." -#: ../src/metacity.schemas.in.in.h:22 -msgid "" -"If true, then Metacity works in terms of applications rather than windows. " -"The concept is a bit abstract, but in general an application-based setup is " -"more like the Mac and less like Windows. When you focus a window in " -"application-based mode, all the windows in the application will be raised. " -"Also, in application-based mode, focus clicks are not passed through to " -"windows in other applications. Application-based mode is, however, largely " -"unimplemented at the moment." -msgstr "" -"खरे असल्यास, मेटासिटी अनुप्रयोग एवजी चौकट स्वरूपात कार्य करतो. ही पध्दत वेगळी आहे, पण " -"अनुप्रयोग-आधारीत संयोजना Mac सारखे जास्त व Windows सारखे कमी आहे. अनुप्रयोग-आधारीत " -"पध्दती मध्ये चौकट केंद्रीत करत असल्यास, अनुप्रयोगातील सर्व चौकट वाढविले जातील. तरी, " -"अनुप्रयोग-आधारीत पध्दतीमध्ये, इतर अनुप्रयोग मध्ये लक्ष्यकेंद्र किल्क स्थानांतरीत केले जात नाही. " -"अनुप्रयोग-आधारीत पध्दती, याक्षणी तरी कार्यरत केले गेले नाही." - -#: ../src/metacity.schemas.in.in.h:23 -msgid "If true, trade off usability for less resource usage" -msgstr "ट्रेड ऑफ वापरला कमी साधन वापरली, जर बरोबर" - -#: ../src/metacity.schemas.in.in.h:24 -msgid "Modifier to use for modified window click actions" -msgstr "टिचकी मारण्याची कृतीसाठी सुधारकर्ता सुधारीत चौकट वापरतो" - -#: ../src/metacity.schemas.in.in.h:25 -msgid "Name of workspace" -msgstr "कार्यक्षेत्राचे नाव" +#: ../data/org.gnome.mutter.gschema.xml.in.h:7 +msgid "Workspaces are managed dynamically" +msgstr "वर्कस्पेसेस्ना गतियरित्या व्यवस्थापीत केले जाते" -#: ../src/metacity.schemas.in.in.h:26 -msgid "Number of workspaces" -msgstr "कार्यक्षेत्रांची संख्या" - -#: ../src/metacity.schemas.in.in.h:27 +#: ../data/org.gnome.mutter.gschema.xml.in.h:8 msgid "" -"Number of workspaces. Must be more than zero, and has a fixed maximum to " -"prevent making the desktop unusable by accidentally asking for too many " -"workspaces." +"Determines whether workspaces are managed dynamically or whether there's a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." msgstr "" -"कार्यक्षेत्रांची संख्या. शून्यपेक्षा जास्त असायला हवे, व डेस्कटॉपला पुष्कळ कार्यक्षेत्र " -"वापरण्यापासून प्रतिबंधित करण्याकरीता कमाल संख्या देखिल स्थापित केली जाते." - -#: ../src/metacity.schemas.in.in.h:28 -msgid "Run a defined command" -msgstr "परिभाषीत आदेश चालवा" +"वर्कस्पेसेस् गतियरित्या व्यवस्थापीत केले जातात किंवा वर्कस्पेस्ची एकूण संख्या " +"ओळखतो (org.gnome." +"desktop.wm.preferences मध्ये num-workspaces कितर्फे ओळखले जाते)." -#: ../src/metacity.schemas.in.in.h:29 -msgid "" -"Set this to true to resize with the right button and show a menu with the " -"middle button while holding down the key given in \"mouse_button_modifier\"; " -"set it to false to make it work the opposite way around." -msgstr "" -"उजव्या बटणाशी पुन्ह आकार करण्यासाठी true निश्चित करा व " -"\"mouse_button_modifier\" अंतर्गत कि दाबून ठेवून मध्य बटण द्वारे मेन्यू दाखवा; " -"false निश्चित केल्यास विरूद्ध नुरूप कार्य करतो." +#: ../data/org.gnome.mutter.gschema.xml.in.h:9 +msgid "Workspaces only on primary" +msgstr "वर्कस्पेसेस् फक्त प्राथमिक" -#: ../src/metacity.schemas.in.in.h:30 -msgid "" -"Setting this option to false can lead to buggy behavior, so users are " -"strongly discouraged from changing it from the default of true. Many actions " -"(e.g. clicking in the client area, moving or resizing the window) normally " -"raise the window as a side-effect. Setting this option to false, which is " -"strongly discouraged, will decouple raising from other user actions, and " -"ignore raise requests generated by applications. See http://bugzilla.gnome." -"org/show_bug.cgi?id=445447#c6. Even when this option is false, windows can " -"still be raised by an alt-left-click anywhere on the window, a normal click " -"on the window decorations, or by special messages from pagers, such as " -"activation requests from tasklist applets. This option is currently disabled " -"in click-to-focus mode. Note that the list of ways to raise windows when " -"raise_on_click is false does not include programmatic requests from " -"applications to raise windows; such requests will be ignored regardless of " -"the reason for the request. If you are an application developer and have a " -"user complaining that your application does not work with this setting " -"disabled, tell them it is _their_ fault for breaking their window manager " -"and that they need to change this option back to true or live with the \"bug" -"\" they requested." -msgstr "" -"Setting this option to false can lead to buggy behavior, so users are " -"strongly discouraged from changing it from the default of true. Many actions " -"(e.g. clicking in the client area, moving or resizing the window) normally " -"raise the window as a side-effect. Setting this option to false, which is " -"strongly discouraged, will decouple raising from other user actions, and " -"ignore raise requests generated by applications. See http://bugzilla.gnome." -"org/show_bug.cgi?id=445447#c6. Even when this option is false, windows can " -"still be raised by an alt-left-click anywhere on the window, a normal click " -"on the window decorations, or by special messages from pagers, such as " -"activation requests from tasklist applets. This option is currently disabled " -"in click-to-focus mode. Note that the list of ways to raise windows when " -"raise_on_click is false does not include programmatic requests from " -"applications to raise windows; such requests will be ignored regardless of " -"the reason for the request. If you are an application developer and have a " -"user complaining that your application does not work with this setting " -"disabled, tell them it is _their_ fault for breaking their window manager " -"and that they need to change this option back to true or live with the \"bug" -"\" they requested." - -#: ../src/metacity.schemas.in.in.h:31 +#: ../data/org.gnome.mutter.gschema.xml.in.h:10 msgid "" -"Some applications disregard specifications in ways that result in window " -"manager misfeatures. This option puts Metacity in a rigorously correct mode, " -"which gives a more consistent user interface, provided one does not need to " -"run any misbehaving applications." +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." msgstr "" -"काहीक अनुप्रयोग संयोजनाचे उल्लंगन करते ज्यामुळे चौकट व्यवस्थापकचे वैशिष्ट्ये सदोषीत होते. या " -"पर्याय Metacity ला योग्य पध्तीत कार्यरत करतो, ज्यामुळे सुस्थित वापरकर्ता संवाद प्राप्त " -"होते, व त्याकरीता एवढीच अट अशी आहे की त्याक्षणी असुसंगती अनुप्रयोग चालवायचे नाही." +"वर्कस्पेस् बदलणे सर्व मॉनीटरकरीता किंवा फक्त प्राथमिक मॉनिटरवरील पटलांकरीता " +"व्हायला हवे." -#: ../src/metacity.schemas.in.in.h:32 -msgid "System Bell is Audible" -msgstr "प्रणाली घंटा एकू येण्याजोगी आहे" +#: ../data/org.gnome.mutter.gschema.xml.in.h:11 +msgid "No tab popup" +msgstr "टॅब पॉपअप आढळले नाही" -#: ../src/metacity.schemas.in.in.h:33 +#: ../data/org.gnome.mutter.gschema.xml.in.h:12 msgid "" -"Tells Metacity how to implement the visual indication that the system bell " -"or another application 'bell' indicator has been rung. Currently there are " -"two valid values, \"fullscreen\", which causes a fullscreen white-black " -"flash, and \"frame_flash\" which causes the titlebar of the application " -"which sent the bell signal to flash. If the application which sent the bell " -"is unknown (as is usually the case for the default \"system beep\"), the " -"currently focused window's titlebar is flashed." +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." msgstr "" -"प्रणाली घंटा किंवा अन्य अनुप्रयोगाची 'घंटा' वाजविली अल्यास दृश्नीय सूचक कसे कार्यरत करायचे " -"ते Metacity ला कळविते. सद्या दोन वैध मुल्य, \"पूर्णपडदा\", ज्यामुळे पूर्णपडदा पांढरे-काळे असे " -"दिसून पडते, व \"फेम_फ्लॅश\" ज्यामुळे अनुप्रयोगची शिर्षकपट्टी दिसण्यास सुरू होते. ज्या " -"अनुप्रयोगने संकेत पाठविले ते अपरिचीत असल्यास (जे मुलभूत \"प्रणाली बीप\" करीता स्वरूप आहे), " -"सद्याचे केंद्रीत चौकटाचे शिर्षकपट्टी दिसते." +"पॉपअपचा वापर व विंडो सायकलिंगकरीता फ्रेम ठळक करणे अशक्य करायचे, हे ओळखतो." -#: ../src/metacity.schemas.in.in.h:34 -msgid "" -"The /apps/metacity/global_keybindings/run_command_N keys define keybindings " -"that correspond to these commands. Pressing the keybinding for run_command_N " -"will execute command_N." -msgstr "" -"/apps/metacity/global_keybindings/run_command_N किल्ली keybinding निश्चित करते " -"जे या आदेशशी परस्पर आहे. कळबांधणी run_command_N करीता दाबल्यास command_N कार्यान्वीत " -"होईल." +#: ../data/org.gnome.mutter.gschema.xml.in.h:13 +msgid "Delay focus changes until the pointer stops moving" +msgstr "पॉइंटरचे हलणे थांबेपर्यंत फोकस बदलमध्ये विलंब करा" -#: ../src/metacity.schemas.in.in.h:35 +#: ../data/org.gnome.mutter.gschema.xml.in.h:14 msgid "" -"The /apps/metacity/global_keybindings/run_command_screenshot key defines a " -"keybinding which causes the command specified by this setting to be invoked." +"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " +"the focus will not be changed immediately when entering a window, but only " +"after the pointer stops moving." msgstr "" -"/apps/metacity/global_keybindings/run_command_screenshot किल्ली keybinding " -"निश्चित करते जे या संयोजना द्वारे निश्चित आदेशला सुरू करते." +"true असल्यास, व फोकस मोड एकतर \"sloppy\" किंवा \"mouse\" असल्यास पटलमध्ये " +"प्रवेश " +"करतेवेळी फोकस पटकन बदलणार नाही, पॉइंटरचे हलणे थांबल्यावरच फोकसचे बदल शक्य आहे." -#: ../src/metacity.schemas.in.in.h:36 -msgid "" -"The /apps/metacity/global_keybindings/run_command_window_screenshot key " -"defines a keybinding which causes the command specified by this setting to " -"be invoked." -msgstr "" -"/apps/metacity/global_keybindings/run_command_window_screenshot किल्ली " -"keybinding निश्चित करते जे या संयोजना द्वारे निश्चित आदेशला सुरू करते." +#: ../data/org.gnome.mutter.gschema.xml.in.h:15 +msgid "Draggable border width" +msgstr "ओढण्याजोगी किनार रूंदी" -#: ../src/metacity.schemas.in.in.h:37 +#: ../data/org.gnome.mutter.gschema.xml.in.h:16 msgid "" -"The keybinding that runs the correspondingly-numbered command in /apps/" -"metacity/keybinding_commands The format looks like \"<Control>a\" or " -"\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -"lower or upper case, and also abbreviations such as \"<Ctl>\" and " -"\"<Ctrl>\". If you set the option to the special string \"disabled\", " -"then there will be no keybinding for this action." +"The amount of total draggable borders. If the theme's visible borders are " +"not enough, invisible borders will be added to meet this value." msgstr "" -"keybinding जे /apps/metacity/keybinding_commands मधिल परस्पर-क्रमांकीत आदेश " -"चालवितो. स्वरूप खालिल प्रमाणे दिसते \"<Control>a\" किंवा \"<Shift><" -"Alt>F1\". पार्सर सुलभ आहे व लहान किंवा मोठ्या आकाराचे अक्षरास, व \"<Ctl>\" " -"किंवा \"<Ctrl>\" सारखे संक्षिप्त रूप करीता परवानगी देते. विशेष अक्षरमाळा करीता " -"पर्याय \"अकार्यान्वीत\" असे निश्चित केल्यास, या कृती करीता keybinding स्थापीत केले जाऊ " -"शकणार नाही." - -#: ../src/metacity.schemas.in.in.h:38 -msgid "The name of a workspace." -msgstr "कार्यक्षेत्राचे नाव." - -#: ../src/metacity.schemas.in.in.h:39 -msgid "The screenshot command" -msgstr "पडद्यांच्या फोटोंची आदेश" - -#: ../src/metacity.schemas.in.in.h:40 -msgid "" -"The theme determines the appearance of window borders, titlebar, and so " -"forth." -msgstr "चौकटची सीमा, शिर्षकपट्टी, व याच तऱ्हने पुढे सुत्रयोजना निश्चित करतो." +"एकूण ओढण्याजोगी किनारची संख्या. सुत्रयोजनाचे दृष्यास्पद किनार अतिरिक्त " +"नसल्यास, ह्या " +"मूल्याशी जुळणीकरीता छुपे किनार समाविष्ट केले जाईल." -#: ../src/metacity.schemas.in.in.h:41 -msgid "" -"The time delay before raising a window if auto_raise is set to true. The " -"delay is given in thousandths of a second." -msgstr "" -"स्वः_वाढ खरे निश्चित केल्यास होणारा वेळेतील उशीर . या उशीर सेकंदाच्या हजाराव्या अंशात " -"प्रविष्ट केले जाते." +#: ../data/org.gnome.mutter.gschema.xml.in.h:17 +msgid "Auto maximize nearly monitor sized windows" +msgstr "अंदाजे मॉनीटर आकराचे पटल स्वयंरित्या वाढवा" -#: ../src/metacity.schemas.in.in.h:42 -msgid "" -"The window focus mode indicates how windows are activated. It has three " -"possible values; \"click\" means windows must be clicked in order to focus " -"them, \"sloppy\" means windows are focused when the mouse enters the window, " -"and \"mouse\" means windows are focused when the mouse enters the window and " -"unfocused when the mouse leaves the window." -msgstr "" -"पध्दती चौकट कसे सक्रीय करायचे याचे सूचक चौकट लक्ष्यकेंद्र पध्दती आहे. याचे तीन संभाव्य मुल्य " -"आहे; \"क्लिक\" म्हणजे लक्षकेंद्र करण्याकरीता चौकटवर क्लिक केले पाहिजे, \"गचाळ\" म्हणजे जेव्हा " -"माउस चौकट मध्ये प्रवेश करतो तेव्हा चौकट लक्ष्यकेंद्रीत केले जाते व \"माउस\" म्हणजे जेव्हा माउस " -"चौकटीत प्रवेश करतो तेव्हा चौकट लक्ष्यकेंद्रीत केले जाते व जेव्हा माउस चौकटीत प्रवेश करत नाही " -"तेव्हा चौकट लक्ष्यकेंद्रीत केले जात नाही." - -#: ../src/metacity.schemas.in.in.h:43 -msgid "The window screenshot command" -msgstr "चौकटच्या पडदा फोटोंची आदेश" - -#: ../src/metacity.schemas.in.in.h:44 -#| msgid "" -#| "This option determines the effects of double-clicking on the title bar. " -#| "Current valid options are 'toggle_shade', which will shade/unshade the " -#| "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#| "'minimize' which will minimize the window, and 'none' which will not do " -#| "anything." -msgid "" -"This option determines the effects of double-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, 'toggle_maximize' which will maximize/unmaximize the window, " -"'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which will " -"maximize/unmaximize the window in that direction only, 'minimize' which will " -"minimize the window, 'shade' which will roll the window up, 'menu' which " -"will display the window menu, 'lower' which will put the window behind all " -"the others, and 'none' which will not do anything." -msgstr "" -"या पर्याय शिर्षक पट्टीवर दुय्यम-क्लिकचा प्रभाव निश्चित करतो. वर्तमान वैध पर्याय " -"खालिल प्रमाणे आहे 'toggle_shade', जे खिडकीला छटा देईल/छटा देणे अशक्य करेल, 'toggle_maximize' जे " -"खिडकीला मोठे करेल/नाही, 'toggle_maximize_horizontally' व 'toggle_maximize_vertically' जे खिडकीला फक्त त्याच दिशेत मोठे/मोठे अशक्य करेल, 'minimize' जे खिडकीला लहान करेल, 'छटा' जे खिडकीला वर रोल करते, 'menu' जे खिडकी मेन्यू दाखवते, 'lower' जे खिडकीला इतर खिडकींच्या पार्श्वभूमीत स्थायीत करते, व 'काहीच नाही' जे काहीच करणार नाही." - -#: ../src/metacity.schemas.in.in.h:45 -#| msgid "" -#| "This option determines the effects of middle-clicking on the title bar. " -#| "Current valid options are 'toggle_shade', which will shade/unshade the " -#| "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#| "'minimize' which will minimize the window, and 'none' which will not do " -#| "anything." -msgid "" -"This option determines the effects of middle-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, 'toggle_maximize' which will maximize/unmaximize the window, " -"'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which will " -"maximize/unmaximize the window in that direction only, 'minimize' which will " -"minimize the window, 'shade' which will roll the window up, 'menu' which " -"will display the window menu, 'lower' which will put the window behind all " -"the others, and 'none' which will not do anything." -msgstr "" -"या पर्याय शिर्षक पट्टीवर मध्य-क्लिक दिल्यानंतर प्रभाव निश्चित करतो. वर्तमान वैध पर्याय " -"खालिल प्रमाणे आहे 'toggle_shade', जे खिडकीला छटा देईल/छटा देणे अशक्य करेल, 'toggle_maximize' जे " -"खिडकीला मोठे करेल/नाही, 'toggle_maximize_horizontally' व 'toggle_maximize_vertically' जे खिडकीला फक्त त्याच दिशेत मोठे/मोठे अशक्य करेल, 'minimize' जे खिडकीला लहान करेल, 'छटा' जे खिडकीला वर रोल करते, 'menu' जे खिडकी मेन्यू दाखवते, 'lower' जे खिडकीला इतर खिडकींच्या पार्श्वभूमीत स्थायीत करते, व 'काहीच नाही' जे काहीच करणार नाही." - -#: ../src/metacity.schemas.in.in.h:46 -#| msgid "" -#| "This option determines the effects of right-clicking on the title bar. " -#| "Current valid options are 'toggle_shade', which will shade/unshade the " -#| "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#| "'minimize' which will minimize the window, and 'none' which will not do " -#| "anything." +#: ../data/org.gnome.mutter.gschema.xml.in.h:18 msgid "" -"This option determines the effects of right-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, 'toggle_maximize' which will maximize/unmaximize the window, " -"'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which will " -"maximize/unmaximize the window in that direction only, 'minimize' which will " -"minimize the window, 'shade' which will roll the window up, 'menu' which " -"will display the window menu, 'lower' which will put the window behind all " -"the others, and 'none' which will not do anything." -msgstr "" -"या पर्याय शिर्षक पट्टीवर उजवी-क्लिक दिल्यानंतर प्रभाव निश्चित करतो. वर्तमान वैध पर्याय " -"खालिल प्रमाणे आहे 'toggle_shade', जे खिडकीला छटा देईल/छटा देणे अशक्य करेल, 'toggle_maximize' जे " -"खिडकीला मोठे करेल/नाही, 'toggle_maximize_horizontally' व 'toggle_maximize_vertically' जे खिडकीला फक्त त्याच दिशेत मोठे/मोठे अशक्य करेल, 'minimize' जे खिडकीला लहान करेल, 'छटा' जे खिडकीला वर रोल करते, 'menu' जे खिडकी मेन्यू दाखवते, 'lower' जे खिडकीला इतर खिडकींच्या पार्श्वभूमीत स्थायीत करते, व 'काहीच नाही' जे काहीच करणार नाही." +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "सुरू असल्यास, मॉनीटरच्या आकाराचे नवीन पटल आपोआप कमालीचे होतात." -#: ../src/metacity.schemas.in.in.h:47 +#: ../data/org.gnome.mutter.gschema.xml.in.h:19 +msgid "Place new windows in the center" +msgstr "नवीन पटलांना मधोमध दाखवा" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:20 msgid "" -"This option provides additional control over how newly created windows get " -"focus. It has two possible values; \"smart\" applies the user's normal focus " -"mode, and \"strict\" results in windows started from a terminal not being " -"given focus." +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." msgstr "" -"या पर्याय नविन नर्मित चौकटी करीता लक्ष्यकेंद्र कसे प्राप्त होते या करीता अगाऊ नियंत्रण " -"पुरवितो. दोन संभाव्य मुल्य आहेत; \"smart\" म्हणजे वापरकर्त्याचे साधारण लक्ष्यकेंद्र पध्दती, व " -"\"strict\" म्हणजे टर्मिनल पासून सुरू होणारे चौकटी ज्यास लक्ष्यकेंद्र देऊ शकत नाही." +"खरे असल्यास, नवीन पटलांना नेहमी मॉनिटरच्या सक्रीय पडद्याच्या मधोमध स्थीत केले " +"जाईल." + +#: ../data/org.gnome.mutter.gschema.xml.in.h:21 +msgid "Select window from tab popup" +msgstr "टॅब पॉपअपपासून पटल नीवडा" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:22 +msgid "Cancel tab popup" +msgstr "टॅब पॉपअप रद्द करा" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:1 +#| msgid "Switch to workspace 1" +msgid "Switch to VT 1" +msgstr "VT 1 चा वापर करा" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:2 +#| msgid "Switch to workspace 2" +msgid "Switch to VT 2" +msgstr "VT 2 चा वापर करा" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:3 +#| msgid "Switch to workspace 3" +msgid "Switch to VT 3" +msgstr "VT 3 चा वापर करा" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:4 +#| msgid "Switch to workspace 4" +msgid "Switch to VT 4" +msgstr "VT 4 चा वापर करा" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:5 +#| msgid "Switch to workspace 5" +msgid "Switch to VT 5" +msgstr "VT 5 चा वापर करा" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:6 +#| msgid "Switch to workspace 6" +msgid "Switch to VT 6" +msgstr "VT 6 चा वापर करा" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:7 +#| msgid "Switch to workspace 7" +msgid "Switch to VT 7" +msgstr "VT 7 चा वापर करा" + +#: ../src/backends/meta-monitor-manager.c:412 +msgid "Built-in display" +msgstr "बिल्टइन डिस्पले" + +#: ../src/backends/meta-monitor-manager.c:437 +msgid "Unknown" +msgstr "अपरिचीत" + +#: ../src/backends/meta-monitor-manager.c:439 +msgid "Unknown Display" +msgstr "अपरिचीत डिस्पले" + +#. TRANSLATORS: this is a monitor vendor name, followed by a +#. * size in inches, like 'Dell 15"' +#. +#: ../src/backends/meta-monitor-manager.c:447 +#, c-format +msgid "%s %s" +msgstr "%s %s" -#: ../src/metacity.schemas.in.in.h:48 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: ../src/compositor/compositor.c:443 +#, c-format msgid "" -"Turns on a visual indication when an application or the system issues a " -"'bell' or 'beep'; useful for the hard-of-hearing and for use in noisy " -"environments." +"Another compositing manager is already running on screen %i on display \"%s" +"\"." msgstr "" -"प्रणाली घंटा किंवा अन्य अनुप्रयोगाची 'घंटा' किंवा 'बीप' वाजविली अल्यास दृश्नीय सूचक चालू " -"करा; जे एकण्यास कठिण जाणाऱ्यांना व जास्त आवाज वातवरणात फारच उपयोगी ठरू शकते." +"डिस्पले \"%2$s\" वरील पडदा %1$d करीता इतर कम्पोजिटिंग व्यवस्थापक आधिपासूनच " +"सुरू आहे." -#: ../src/metacity.schemas.in.in.h:49 -msgid "Use standard system font in window titles" -msgstr "चौकट शिर्षकाकरिता नेहमीची प्रणाली फॉन्ट वापरा" - -#: ../src/metacity.schemas.in.in.h:50 -msgid "Visual Bell Type" -msgstr "दृश्य बेल प्रकार" - -#: ../src/metacity.schemas.in.in.h:51 -msgid "Whether raising should be a side-effect of other user interactions" -msgstr "अन्य वापरकर्त्याशी परस्पर संवाद अप्रत्यक्ष परिणाम असायला हवे का" - -#: ../src/metacity.schemas.in.in.h:52 -msgid "Whether to resize with the right button" -msgstr "उजव्या बटणसह पुन्हआकार करायचे" - -#: ../src/metacity.schemas.in.in.h:53 -msgid "Window focus mode" -msgstr "चौकट फोकस पध्दत" - -#: ../src/metacity.schemas.in.in.h:54 -msgid "Window title font" -msgstr "चौकट शिर्षक लिपी" - -#: ../src/tools/metacity-message.c:150 -#, c-format -msgid "Usage: %s\n" -msgstr "वापर: %s\n" - -#: ../src/ui/frames.c:1118 -msgid "Close Window" -msgstr "चौकट बंद करा" - -#: ../src/ui/frames.c:1121 -msgid "Window Menu" -msgstr "चौकट मेनू" - -#: ../src/ui/frames.c:1124 -msgid "Minimize Window" -msgstr "चौकट लहान करा" - -#: ../src/ui/frames.c:1127 -msgid "Maximize Window" -msgstr "चौकट मोठ्यात मोठी करा" - -#: ../src/ui/frames.c:1130 -#| msgid "Resize window" -msgid "Restore Window" -msgstr "खिडकी पूर्वस्थितीत आणा" - -#: ../src/ui/frames.c:1133 -msgid "Roll Up Window" -msgstr "चौकट गुंडाळा" - -#: ../src/ui/frames.c:1136 -msgid "Unroll Window" -msgstr "चौकट गुंडाळा" - -#: ../src/ui/frames.c:1139 -msgid "Keep Window On Top" -msgstr "चौकट वर दर्शवा" - -#: ../src/ui/frames.c:1142 -msgid "Remove Window From Top" -msgstr "शिर्ष पासून चौकट काढूण टाका" - -#: ../src/ui/frames.c:1145 -msgid "Always On Visible Workspace" -msgstr "नेहमी दिसण्याजोगी कार्यक्षेत्रावर दर्शवा" - -#: ../src/ui/frames.c:1148 -msgid "Put Window On Only One Workspace" -msgstr "चौकट फक्त एका कार्यक्षेत्रावर दर्शवा" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:70 -msgid "Mi_nimize" -msgstr "लहान करा(_n)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:72 -msgid "Ma_ximize" -msgstr "मोठ्यात मोठे करा(_x)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:74 -msgid "Unma_ximize" -msgstr "लहान करा(_x)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:76 -msgid "Roll _Up" -msgstr "वर गुंडाळा(_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:78 -msgid "_Unroll" -msgstr "गुंडाळी उघडा(_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:80 -msgid "_Move" -msgstr "हलवा(_M)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:82 -msgid "_Resize" -msgstr "पुनःआकारित करा(_R)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:84 -msgid "Move Titlebar On_screen" -msgstr "शिर्षकपट्टी स्क्रीनवर हलवा(_s)" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:87 ../src/ui/menu.c:89 -msgid "Always on _Top" -msgstr "नेहमी वर (_T)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:91 -msgid "_Always on Visible Workspace" -msgstr "नेहमी दृश्य कार्यक्षेत्रावर(_A)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:93 -msgid "_Only on This Workspace" -msgstr "फक्त या कार्यक्षेत्रावर(_O)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:95 -msgid "Move to Workspace _Left" -msgstr "डाव्या कार्यक्षेत्रावर हलवा(_L)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:97 -msgid "Move to Workspace R_ight" -msgstr "उजव्या कार्यक्षेत्रावर हलवा(_i)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:99 -msgid "Move to Workspace _Up" -msgstr "वरील कार्यक्षेत्रावर हलवा(_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:101 -msgid "Move to Workspace _Down" -msgstr "खालील कार्यक्षेत्रावर हलवा(_D)" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:105 -msgid "_Close" -msgstr "बंद करा(_C)" - -#: ../src/ui/menu.c:203 -#, c-format -#| msgid "Workspace %d" -msgid "Workspace %d%n" -msgstr "Workspace %d%n" - -#: ../src/ui/menu.c:213 -#, c-format -msgid "Workspace 1_0" -msgstr "कार्यक्षेत्र १०(_0)" - -#: ../src/ui/menu.c:215 -#, c-format -msgid "Workspace %s%d" -msgstr "कार्यक्षेत्र %s%d" - -#: ../src/ui/menu.c:395 -msgid "Move to Another _Workspace" -msgstr "वेगळ्या कार्यक्षेत्रावर हलवा(_W)" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:104 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:110 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:116 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:122 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:128 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:134 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:140 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:146 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:152 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, -#. * this. -#. -#: ../src/ui/metaaccellabel.c:158 -msgid "Mod5" -msgstr "Mod5" +#: ../src/core/bell.c:185 +msgid "Bell event" +msgstr "बेल इव्हेंट" -#: ../src/ui/metacity-dialog.c:90 +#: ../src/core/delete.c:127 #, c-format -msgid "\"%s\" is not responding." -msgstr "\"%s\" प्रतिसाद देत नाही आहे." +msgid "“%s” is not responding." +msgstr "“%s” प्रतिसाद देत नाही." + +#: ../src/core/delete.c:129 +msgid "Application is not responding." +msgstr "ॲप्लिकेशन प्रतिसाद देत नाही." -#: ../src/ui/metacity-dialog.c:97 +#: ../src/core/delete.c:134 msgid "" "You may choose to wait a short while for it to continue or force the " "application to quit entirely." msgstr "" -"तुम्ही काहीकवेळ पुढे जाण्यापासून थांबण्यास निवड करू शकता किंवा अनुप्रयोगातून बाहेर " +"तुम्ही काहीकवेळ पुढे जाण्यापासून थांबण्यास निवड करू शकता किंवा अनुप्रयोगातून " +"बाहेर " "पडण्याकरीता विनंतीकृत करू शखता." -#: ../src/ui/metacity-dialog.c:107 +#: ../src/core/delete.c:141 msgid "_Wait" msgstr "वाट पहा(_W)" -#: ../src/ui/metacity-dialog.c:109 +#: ../src/core/delete.c:141 msgid "_Force Quit" msgstr "जबरन बाहेर पडा (_F)" -#: ../src/ui/metacity-dialog.c:206 -msgid "Title" -msgstr "शिर्षक" +#: ../src/core/display.c:547 +#, c-format +msgid "Failed to open X Window System display '%s'\n" +msgstr "X चौकट प्रणाली दृश्य '%s' उघडण्यास अपयशी\n" + +#: ../src/core/main.c:176 +msgid "Disable connection to session manager" +msgstr "सत्र व्यवस्थपानशी जुळवणी अकार्यान्वती करा" + +#: ../src/core/main.c:182 +msgid "Replace the running window manager" +msgstr "कार्यरत पटल व्यवस्थापकशी अदलाबदल करा" + +#: ../src/core/main.c:188 +msgid "Specify session management ID" +msgstr "सत्र व्यवस्थापन ID निश्चित करा" + +#: ../src/core/main.c:193 +msgid "X Display to use" +msgstr "वापरण्याकरीताचे X दृश्य" + +#: ../src/core/main.c:199 +msgid "Initialize session from savefile" +msgstr "संचयन फाइल पासून सत्र प्रारंभीत करा" + +#: ../src/core/main.c:205 +msgid "Make X calls synchronous" +msgstr "X कॉल सुसंगत करा" + +#: ../src/core/main.c:212 +msgid "Run as a wayland compositor" +msgstr "wayland कम्पोजिटर म्हणून दाखवा" + +#: ../src/core/main.c:220 +msgid "Run as a full display server, rather than nested" +msgstr "नेस्टेड ऐवजी, संपूर्ण डिस्पले सर्व्हर म्हणून चालवा" + +#: ../src/core/main.c:451 +#, c-format +msgid "Failed to scan themes directory: %s\n" +msgstr "सुत्रयोजना संचयीका स्कॅन करण्यास अपयशी: %s\n" -#: ../src/ui/metacity-dialog.c:218 -msgid "Class" -msgstr "वर्ग" +#: ../src/core/main.c:467 +#, c-format +msgid "" +"Could not find a theme! Be sure %s exists and contains the usual themes.\n" +msgstr "" +"सुत्रयोजना शोधू शकले नाही! %s अस्तित्वात आहे व त्यात नेहमीचे सुत्रयोजना " +"समाविष्टीत आहे " +"याची खात्री घ्या.\n" -#: ../src/ui/metacity-dialog.c:244 +#: ../src/core/mutter.c:39 +#, c-format msgid "" -"These windows do not support \"save current setup\" and will have to be " -"restarted manually next time you log in." +"mutter %s\n" +"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" msgstr "" -"या चौकटी \"सद्याची संयोजना संचयीत करा\" या पर्यायास समर्थन देत नाही व पुढच्यावेळी " -"दाखलन करतेवेळी तुम्हाला ते पुन्हा सुरू करावे लागेल." +"mutter %s\n" +"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" + +#: ../src/core/mutter.c:53 +msgid "Print version" +msgstr "मुद्रण आवृत्ती" + +#: ../src/core/mutter.c:59 +msgid "Mutter plugin to use" +msgstr "वापरण्याजोगी Mutter प्लगइन" + +#: ../src/core/prefs.c:2117 +#, c-format +msgid "Workspace %d" +msgstr "कार्यक्षेत्र %d" + +#: ../src/core/screen.c:543 +#, c-format +msgid "Screen %d on display '%s' is invalid\n" +msgstr "दृश्य '%2$s' वरील पडदा %1$d अवैध आहे\n" -#: ../src/ui/metacity-dialog.c:310 +#: ../src/core/screen.c:559 #, c-format msgid "" -"There was an error running \"%s\":\n" -"%s." +"Screen %d on display \"%s\" already has a window manager; try using the --" +"replace option to replace the current window manager.\n" msgstr "" -"चालवताना त्रुटी होती \"%s\":\n" -"%s." +"दृश्य \"%2$s\" वरील पडदा %1$d कडे आधिपासूनच चौकट व्यवस्थापक आहे; --replace " +"पर्याय चा " +"वापर सद्याचे चौकट व्यवस्थापक बदलविण्याकरीता केले जाऊ शकतो.\n" + +#: ../src/core/screen.c:652 +#, c-format +msgid "Screen %d on display \"%s\" already has a window manager\n" +msgstr "दृश्य \"%2$s\" वरील पडदा %1$d कडे आधिपासूनच चौकट व्यवस्थापक आहे\n" + +#: ../src/core/util.c:118 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "वर्बोस् मोडकरीता समर्थनविना Mutter कंपाइल केले\n" #. Translators: This represents the size of a window. The first number is #. * the width of the window and the second is the height. #. -#: ../src/ui/resizepopup.c:113 +#: ../src/ui/resizepopup.c:134 #, c-format msgid "%d x %d" msgstr "%d x %d" -#: ../src/ui/theme.c:254 +#: ../src/ui/theme.c:233 msgid "top" msgstr "उच्च" -#: ../src/ui/theme.c:256 +#: ../src/ui/theme.c:235 msgid "bottom" msgstr "तळ" -#: ../src/ui/theme.c:258 +#: ../src/ui/theme.c:237 msgid "left" msgstr "डावे" -#: ../src/ui/theme.c:260 +#: ../src/ui/theme.c:239 msgid "right" msgstr "उजवे" -#: ../src/ui/theme.c:287 +#: ../src/ui/theme.c:267 #, c-format msgid "frame geometry does not specify \"%s\" dimension" msgstr "हे आकारमान चौकट भूमिती \"%s\" ठरवत नाही" -#: ../src/ui/theme.c:306 +#: ../src/ui/theme.c:286 #, c-format msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" msgstr "हे आकारमान सीमारेषेसाठी \"%s\" चौकट भूमिती \"%s\" ठरवत नाही" -#: ../src/ui/theme.c:343 +#: ../src/ui/theme.c:323 #, c-format msgid "Button aspect ratio %g is not reasonable" msgstr "बटन aspect प्रमाण %g योग्य नाही" -#: ../src/ui/theme.c:355 +#: ../src/ui/theme.c:335 #, c-format msgid "Frame geometry does not specify size of buttons" msgstr "हे आकारमान चौकट भूमिती बटणाचा आकार ठरवत नाही" -#: ../src/ui/theme.c:1020 +#: ../src/ui/theme.c:1061 #, c-format msgid "Gradients should have at least two colors" msgstr "चढानी कमीत कमी दोन रंग हवेत" -#: ../src/ui/theme.c:1146 +#: ../src/ui/theme.c:1211 +#, c-format +msgid "" +"GTK custom color specification must have color name and fallback in " +"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" +msgstr "" +"GTK पसंतीचे रंग निर्देशनामध्ये कंसात रंगाचे नाव व फॉलबॅक असणे आवश्यक आहे, " +"उ.दा. gtk:" +"custom(foo,bar); \"%s\"ला वाचण्यास अशक्य आहे" + +#: ../src/ui/theme.c:1227 +#, c-format +msgid "" +"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" +"_ are valid" +msgstr "" +"अवैध अक्षर '%c' मध्ये gtk:custom चे color_name घटक आढळले, फक्त A-Za-z0-9-_ " +"वैध आहे" + +#: ../src/ui/theme.c:1241 +#, c-format +msgid "" +"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " +"fit the format" +msgstr "" +"Gtk:custom रूपण \"gtk:custom(color_name,fallback)\" असे आहे, \"%s\" या " +"रूपणमध्ये " +"बसत नाही" + +#: ../src/ui/theme.c:1286 #, c-format msgid "" "GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " "where NORMAL is the state; could not parse \"%s\"" msgstr "" -"GTK रंग संयोजना कंसा मध्ये असायला हवे, उ.दा. gtk:fg[साधारण] जेथे साधारण असे स्थर आहे; जे " +"GTK रंग संयोजना कंसा मध्ये असायला हवे, उ.दा. gtk:fg[साधारण] जेथे साधारण असे " +"स्थर आहे; जे " "\"%s\" ला वाचू शकले नाही" -#: ../src/ui/theme.c:1160 +#: ../src/ui/theme.c:1300 #, c-format msgid "" "GTK color specification must have a close bracket after the state, e.g. gtk:" "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" msgstr "" -"GTK रंग संयोजनास बंद कंस असायला हवे, उ.दा. gtk:fg[साधारण] जेथे साधारण असे स्थर आहे; जे " +"GTK रंग संयोजनास बंद कंस असायला हवे, उ.दा. gtk:fg[साधारण] जेथे साधारण असे " +"स्थर आहे; जे " "\"%s\" ला वाचू शकले नाही" -#: ../src/ui/theme.c:1171 +#: ../src/ui/theme.c:1311 #, c-format msgid "Did not understand state \"%s\" in color specification" msgstr "रंग ठरावात \"%s\" हा भाग समजला गेला नाही" -#: ../src/ui/theme.c:1184 +#: ../src/ui/theme.c:1324 #, c-format msgid "Did not understand color component \"%s\" in color specification" msgstr "रंग ठरावात \"%s\" रंगाचे घटक समजले गेले नाही" -#: ../src/ui/theme.c:1214 +#: ../src/ui/theme.c:1352 #, c-format msgid "" "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " "format" -msgstr "ब्लेंड पध्दती \"blend/bg_color/fg_color/alpha\" आहे, \"%s\" ह्या पध्दतीत बसत नाही" +msgstr "" +"ब्लेंड पध्दती \"blend/bg_color/fg_color/alpha\" आहे, \"%s\" ह्या पध्दतीत बसत " +"नाही" -#: ../src/ui/theme.c:1225 +#: ../src/ui/theme.c:1363 #, c-format msgid "Could not parse alpha value \"%s\" in blended color" msgstr "मिसळलेल्या रंगात अल्फा किंमत \"%s\" पार्स होऊ शकत नाही" -#: ../src/ui/theme.c:1235 +#: ../src/ui/theme.c:1373 #, c-format msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" msgstr "मिसळलेल्या रंगात अल्फा किंमत \"%s\" ही 0.0 आणि 1.0 मध्ये नाही" -#: ../src/ui/theme.c:1282 +#: ../src/ui/theme.c:1419 #, c-format -msgid "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "सावली पध्दती \"blend/bg_color/fg_color/alpha\", \"%s\" ह्या पध्दतीत बसत नाही" +msgid "" +"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" +msgstr "" +"सावली पध्दती \"blend/bg_color/fg_color/alpha\", \"%s\" ह्या पध्दतीत बसत नाही" -#: ../src/ui/theme.c:1293 +#: ../src/ui/theme.c:1430 #, c-format msgid "Could not parse shade factor \"%s\" in shaded color" msgstr "सावली पध्दत सावलीतील रंगात \"%s\" पार्स होऊ शकत नाही" -#: ../src/ui/theme.c:1303 +#: ../src/ui/theme.c:1440 #, c-format msgid "Shade factor \"%s\" in shaded color is negative" msgstr "सावली रंगात सावली भाग \"%s\" नकारात्मक आहे" -#: ../src/ui/theme.c:1332 +#: ../src/ui/theme.c:1469 #, c-format msgid "Could not parse color \"%s\"" msgstr "रंग \"%s\" विश्लेषित करता आला नाही" -#: ../src/ui/theme.c:1582 +#: ../src/ui/theme.c:1778 #, c-format msgid "Coordinate expression contains character '%s' which is not allowed" msgstr "निबंधक वाक्यरचनातील '%s' अक्षराला परवानगी नाही" -#: ../src/ui/theme.c:1609 +#: ../src/ui/theme.c:1805 #, c-format msgid "" "Coordinate expression contains floating point number '%s' which could not be " "parsed" -msgstr "निबंधक वाक्यरचना मध्ये फ्लोटींग पॉईंट क्रमांक '%s' समाविष्टीत आहे जे वाचले जाऊ शकत नाही" +msgstr "" +"निबंधक वाक्यरचना मध्ये फ्लोटींग पॉईंट क्रमांक '%s' समाविष्टीत आहे जे वाचले " +"जाऊ शकत नाही" -#: ../src/ui/theme.c:1623 +#: ../src/ui/theme.c:1819 #, c-format msgid "Coordinate expression contains integer '%s' which could not be parsed" msgstr "निबंधक वाक्यरचनात '%s' हा इंटिजर पार्स होऊ शकत नाही" -#: ../src/ui/theme.c:1745 +#: ../src/ui/theme.c:1940 #, c-format msgid "" "Coordinate expression contained unknown operator at the start of this text: " "\"%s\"" -msgstr "निबंधक वाक्यरचनात पाठ्यच्या सुरवातीस अपरिचीत operator समाविष्टीत आहे: \"%s\"" +msgstr "" +"निबंधक वाक्यरचनात पाठ्यच्या सुरवातीस अपरिचीत operator समाविष्टीत आहे: \"%s\"" -#: ../src/ui/theme.c:1802 +#: ../src/ui/theme.c:1997 #, c-format msgid "Coordinate expression was empty or not understood" msgstr "निबंध वाक्यरचना रिकामे होते किंवा समझण्याजोगी नाही" -#: ../src/ui/theme.c:1913 ../src/ui/theme.c:1923 ../src/ui/theme.c:1957 +#: ../src/ui/theme.c:2110 ../src/ui/theme.c:2120 ../src/ui/theme.c:2154 #, c-format msgid "Coordinate expression results in division by zero" msgstr "निबंधक वाक्यरचना division by zero चा परिणाम देते" -#: ../src/ui/theme.c:1965 +#: ../src/ui/theme.c:2162 #, c-format -msgid "Coordinate expression tries to use mod operator on a floating-point number" -msgstr "निबंधक वाक्यरचना फ्लोटींग पॉईंट क्रमांकवर mod नियंत्रक वापरण्याचा प्रयत्न करीत आहे" +msgid "" +"Coordinate expression tries to use mod operator on a floating-point number" +msgstr "" +"निबंधक वाक्यरचना फ्लोटींग पॉईंट क्रमांकवर mod नियंत्रक वापरण्याचा प्रयत्न " +"करीत आहे" -#: ../src/ui/theme.c:2021 +#: ../src/ui/theme.c:2218 #, c-format -msgid "Coordinate expression has an operator \"%s\" where an operand was expected" +msgid "" +"Coordinate expression has an operator \"%s\" where an operand was expected" msgstr "निबंधक वाक्यरचनातील operator \"%s\" च्या जागी operand अपेक्षीत" -#: ../src/ui/theme.c:2030 +#: ../src/ui/theme.c:2227 #, c-format msgid "Coordinate expression had an operand where an operator was expected" msgstr "निबंधक वाक्यरचनातील operand च्या जागी operator अपेक्षीत" -#: ../src/ui/theme.c:2038 +#: ../src/ui/theme.c:2235 #, c-format msgid "Coordinate expression ended with an operator instead of an operand" msgstr "निबंधक वाक्यरचना operand च्या एवजी operator मध्ये समाप्त होते" -#: ../src/ui/theme.c:2048 +#: ../src/ui/theme.c:2245 #, c-format msgid "" "Coordinate expression has operator \"%c\" following operator \"%c\" with no " @@ -1791,37 +836,39 @@ msgstr "" "निबंधक वाक्यरचनाकडे operator \"%c\" खालिल operator \"%c\" आहे व तेही कुठलेही " "operand विना" -#: ../src/ui/theme.c:2195 ../src/ui/theme.c:2236 +#: ../src/ui/theme.c:2396 ../src/ui/theme.c:2441 #, c-format msgid "Coordinate expression had unknown variable or constant \"%s\"" msgstr "निबंधक वाक्यरचना मध्ये अपरिचीत variable किंवा constant \"%s\" आढळले" -#: ../src/ui/theme.c:2290 +#: ../src/ui/theme.c:2495 #, c-format msgid "Coordinate expression parser overflowed its buffer." msgstr "निबंधक वाक्यरचना पार्सर मधिल बफर मध्ये जागा नाही." -#: ../src/ui/theme.c:2319 +#: ../src/ui/theme.c:2524 #, c-format msgid "Coordinate expression had a close parenthesis with no open parenthesis" msgstr "निबंधक वाक्यरचना कडे बंद पॅरंथसीस आहे व तेही उघडे पॅरंथसीस विनाआहे" -#: ../src/ui/theme.c:2383 +#: ../src/ui/theme.c:2588 #, c-format msgid "Coordinate expression had an open parenthesis with no close parenthesis" msgstr "निबंधक वाक्यरचना कडे उघडे पॅरंथसीस आहे व तेही बंद पॅरंथसीस विना" -#: ../src/ui/theme.c:2394 +#: ../src/ui/theme.c:2599 #, c-format msgid "Coordinate expression doesn't seem to have any operators or operands" msgstr "निबंधक वाक्यरचना कडे ऑपरेटर किंवा ऑपरंड नाही असे दिसून येत" -#: ../src/ui/theme.c:2596 ../src/ui/theme.c:2616 ../src/ui/theme.c:2636 +#: ../src/ui/theme.c:2812 ../src/ui/theme.c:2832 ../src/ui/theme.c:2852 #, c-format msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "सुत्रयोजना मध्ये वाक्यरचना समाविष्टीत आहे ज्यामुळे त्रुटी परिणामस्वरूपी उधभवली: %s\n" +msgstr "" +"सुत्रयोजना मध्ये वाक्यरचना समाविष्टीत आहे ज्यामुळे त्रुटी परिणामस्वरूपी " +"उधभवली: %s\n" -#: ../src/ui/theme.c:4187 +#: ../src/ui/theme.c:4455 #, c-format msgid "" "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " @@ -1830,37 +877,43 @@ msgstr "" "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> ह्या " "भिंतफितीसाठी ठरविलेले आहे" -#: ../src/ui/theme.c:4695 ../src/ui/theme.c:4720 +#: ../src/ui/theme.c:4970 ../src/ui/theme.c:4995 #, c-format -msgid "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "हरवले आहे <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" +msgid "" +"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" +msgstr "" +"हरवले आहे <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -#: ../src/ui/theme.c:4764 +#: ../src/ui/theme.c:5041 #, c-format msgid "Failed to load theme \"%s\": %s\n" msgstr "थीम \"%s\" भारित करण्यास अपयशी: %s\n" -#: ../src/ui/theme.c:4894 ../src/ui/theme.c:4901 ../src/ui/theme.c:4908 -#: ../src/ui/theme.c:4915 ../src/ui/theme.c:4922 +#: ../src/ui/theme.c:5177 ../src/ui/theme.c:5184 ../src/ui/theme.c:5191 +#: ../src/ui/theme.c:5198 ../src/ui/theme.c:5205 #, c-format msgid "No <%s> set for theme \"%s\"" msgstr "कोणतेही <%s> थीम \"%s\" साठी निर्धारित नाही" -#: ../src/ui/theme.c:4930 +#: ../src/ui/theme.c:5213 #, c-format msgid "" "No frame style set for window type \"%s\" in theme \"%s\", add a <window " "type=\"%s\" style_set=\"whatever\"/> element" msgstr "" -"संकल्पनेमध्ये चौकट प्रकारासाठी फिती \"%s\" शैलीची मांडणी नाही \"%s\", गुणधर्म <window " +"संकल्पनेमध्ये चौकट प्रकारासाठी फिती \"%s\" शैलीची मांडणी नाही \"%s\", गुणधर्म " +"<window " "type=\"%s\" style_set=\"whatever\"/> जोडा" -#: ../src/ui/theme.c:5383 ../src/ui/theme.c:5445 ../src/ui/theme.c:5508 +#: ../src/ui/theme.c:5620 ../src/ui/theme.c:5682 ../src/ui/theme.c:5745 #, c-format -msgid "User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "वापरणाऱ्याने सुचविलेला स्थिरांक मोठ्या अक्षरांचे सुरू व्हायला हवा; \"%s\" नाही " +msgid "" +"User-defined constants must begin with a capital letter; \"%s\" does not" +msgstr "" +"वापरणाऱ्याने सुचविलेला स्थिरांक मोठ्या अक्षरांचे सुरू व्हायला हवा; \"%s\" " +"नाही " -#: ../src/ui/theme.c:5391 ../src/ui/theme.c:5453 ../src/ui/theme.c:5516 +#: ../src/ui/theme.c:5628 ../src/ui/theme.c:5690 ../src/ui/theme.c:5753 #, c-format msgid "Constant \"%s\" has already been defined" msgstr "स्थिरांक \"%s\" हा अगोदर पासूनच ठरवण्यात आलेला आहे" @@ -1868,265 +921,279 @@ msgstr "स्थिरांक \"%s\" हा अगोदर पासून #. Translators: This means that an attribute which should have been found #. * on an XML element was not in fact found. #. -#: ../src/ui/theme-parser.c:202 +#: ../src/ui/theme-parser.c:234 #, c-format -#| msgid "No \"x\" attribute on element <%s>" msgid "No \"%s\" attribute on element <%s>" msgstr "घटक <%s> येथे गुणधर्म \"%s\" आढळले नाही" -#: ../src/ui/theme-parser.c:231 ../src/ui/theme-parser.c:249 +#: ../src/ui/theme-parser.c:263 ../src/ui/theme-parser.c:281 #, c-format msgid "Line %d character %d: %s" msgstr "रेषा %d अक्षर %d: %s" -#: ../src/ui/theme-parser.c:413 +#: ../src/ui/theme-parser.c:481 #, c-format msgid "Attribute \"%s\" repeated twice on the same <%s> element" msgstr "त्याच \"%s\" गुणधर्मावर हे गुणधर्म दोनदा <%s> लिहीले आहेत" -#: ../src/ui/theme-parser.c:437 ../src/ui/theme-parser.c:480 +#: ../src/ui/theme-parser.c:505 ../src/ui/theme-parser.c:554 #, c-format msgid "Attribute \"%s\" is invalid on <%s> element in this context" msgstr "ह्या स्थितीत \"%s\" गुणधर्मावर ही वाक्यरचना <%s> अवैध आहे" -#: ../src/ui/theme-parser.c:541 +#: ../src/ui/theme-parser.c:596 +#, c-format +msgid "Could not parse \"%s\" as an integer" +msgstr "\"%s\" चे पुर्णांक म्हणून विश्लेषण करता आले नाही" + +#: ../src/ui/theme-parser.c:605 ../src/ui/theme-parser.c:660 +#, c-format +msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +msgstr "अक्षरमाळा \"%2$s\" मधिल शेवटचे अक्षरं \"%1$s\" कळले नाही" + +#: ../src/ui/theme-parser.c:615 #, c-format msgid "Integer %ld must be positive" msgstr "%ld हा अंक धन हवा" -#: ../src/ui/theme-parser.c:549 +#: ../src/ui/theme-parser.c:623 #, c-format msgid "Integer %ld is too large, current max is %d" msgstr "सध्याचा सर्वात %ld जास्त इंटीजर आहे, हा खूप मोठा आहे %d" -#: ../src/ui/theme-parser.c:577 ../src/ui/theme-parser.c:693 +#: ../src/ui/theme-parser.c:651 ../src/ui/theme-parser.c:767 #, c-format msgid "Could not parse \"%s\" as a floating point number" msgstr "वाहता बिंदू क्रमांक म्हणून \"%s\" हा पार्स करता आला नाही" -#: ../src/ui/theme-parser.c:608 ../src/ui/theme-parser.c:636 +#: ../src/ui/theme-parser.c:682 ../src/ui/theme-parser.c:710 #, c-format msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" msgstr "बुलीयन मुल्य \"खरे\" किंवा \"खोटे\" असावे पण \"%s\" नाही" -#: ../src/ui/theme-parser.c:663 +#: ../src/ui/theme-parser.c:737 #, c-format msgid "Angle must be between 0.0 and 360.0, was %g\n" msgstr "अल्फाची किंमत 0.0 आणि 360.0, असायला हवी %g होती\n" -#: ../src/ui/theme-parser.c:726 +#: ../src/ui/theme-parser.c:800 #, c-format msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" msgstr "अल्फाची किंमत 0.0 आणि 1.0, असायला हवी %g होती\n" -#: ../src/ui/theme-parser.c:791 +#: ../src/ui/theme-parser.c:865 #, c-format msgid "" "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," "large,x-large,xx-large)\n" msgstr "" -"अवैध शिर्षक प्रमाण \"%s\" (यापैकी एक असायले हवे xx-लहान,x-लहान,लहान,मध्यम,मोठे,x-मोठे," +"अवैध शिर्षक प्रमाण \"%s\" (यापैकी एक असायले हवे " +"xx-लहान,x-लहान,लहान,मध्यम,मोठे,x-मोठे," "xx-मोठे)\n" -#: ../src/ui/theme-parser.c:936 ../src/ui/theme-parser.c:999 -#: ../src/ui/theme-parser.c:1033 ../src/ui/theme-parser.c:1136 +#: ../src/ui/theme-parser.c:1021 ../src/ui/theme-parser.c:1084 +#: ../src/ui/theme-parser.c:1118 ../src/ui/theme-parser.c:1221 #, c-format msgid "<%s> name \"%s\" used a second time" msgstr "<%s> हे नाव \"%s\" दुसऱ्यांदा वापरले" -#: ../src/ui/theme-parser.c:948 ../src/ui/theme-parser.c:1045 -#: ../src/ui/theme-parser.c:1148 +#: ../src/ui/theme-parser.c:1033 ../src/ui/theme-parser.c:1130 +#: ../src/ui/theme-parser.c:1233 #, c-format msgid "<%s> parent \"%s\" has not been defined" msgstr "<%s> मुख्य \"%s\" चे वर्णन नाही" -#: ../src/ui/theme-parser.c:1058 +#: ../src/ui/theme-parser.c:1143 #, c-format msgid "<%s> geometry \"%s\" has not been defined" msgstr "<%s> भूमिती \"%s\" संज्ञा झाली नाही" -#: ../src/ui/theme-parser.c:1071 +#: ../src/ui/theme-parser.c:1156 #, c-format msgid "<%s> must specify either a geometry or a parent that has a geometry" msgstr "<%s> ने भूमिती किंवा मूळ ज्याला भूमिती आहे ते ठरवून घ्या" -#: ../src/ui/theme-parser.c:1113 +#: ../src/ui/theme-parser.c:1198 msgid "You must specify a background for an alpha value to be meaningful" msgstr "अल्फा मुल्य अर्थयुक्त करीता तुम्ही पार्श्वभूमी निश्चित केले पाहिजे" -#: ../src/ui/theme-parser.c:1180 +#: ../src/ui/theme-parser.c:1266 #, c-format msgid "Unknown type \"%s\" on <%s> element" msgstr "गुणधर्मावर \"%s\" अपरिचीत <%s> प्रकार" -#: ../src/ui/theme-parser.c:1191 +#: ../src/ui/theme-parser.c:1277 #, c-format msgid "Unknown style_set \"%s\" on <%s> element" msgstr "गुणधर्मावर \"%s\" अपरिचीत <%s> शैलीची मांडणी" -#: ../src/ui/theme-parser.c:1199 +#: ../src/ui/theme-parser.c:1285 #, c-format msgid "Window type \"%s\" has already been assigned a style set" msgstr "चौकट प्रकार \"%s\" आधीच शैलीसंचात ठरवून ठेवलेला आहे" -#: ../src/ui/theme-parser.c:1229 ../src/ui/theme-parser.c:1293 -#: ../src/ui/theme-parser.c:1519 ../src/ui/theme-parser.c:2732 -#: ../src/ui/theme-parser.c:2778 ../src/ui/theme-parser.c:2926 -#: ../src/ui/theme-parser.c:3118 ../src/ui/theme-parser.c:3156 -#: ../src/ui/theme-parser.c:3194 ../src/ui/theme-parser.c:3232 +#: ../src/ui/theme-parser.c:1315 ../src/ui/theme-parser.c:1379 +#: ../src/ui/theme-parser.c:1605 ../src/ui/theme-parser.c:2840 +#: ../src/ui/theme-parser.c:2886 ../src/ui/theme-parser.c:3036 +#: ../src/ui/theme-parser.c:3272 ../src/ui/theme-parser.c:3310 +#: ../src/ui/theme-parser.c:3348 ../src/ui/theme-parser.c:3386 #, c-format msgid "Element <%s> is not allowed below <%s>" msgstr "च्याखाली <%s> गुमधर्माना परवानगी नाही <%s>" -#: ../src/ui/theme-parser.c:1343 ../src/ui/theme-parser.c:1357 -#: ../src/ui/theme-parser.c:1402 -#| msgid "" -#| "Cannot specify both button_width/button_height and aspect ratio for " -#| "buttons" +#: ../src/ui/theme-parser.c:1429 ../src/ui/theme-parser.c:1443 +#: ../src/ui/theme-parser.c:1488 msgid "" "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " "for buttons" -msgstr "बटण करीता \"button_width\"/\"button_height\" व \"aspect_ratio\" निश्चित करणे शक्य नाही" +msgstr "" +"बटण करीता \"button_width\"/\"button_height\" व \"aspect_ratio\" निश्चित करणे " +"शक्य नाही" -#: ../src/ui/theme-parser.c:1366 +#: ../src/ui/theme-parser.c:1452 #, c-format msgid "Distance \"%s\" is unknown" msgstr "\"%s\" अंतर अजञात" -#: ../src/ui/theme-parser.c:1411 +#: ../src/ui/theme-parser.c:1497 #, c-format msgid "Aspect ratio \"%s\" is unknown" msgstr "Aspect प्रमाण \"%s\" अपरिचीत आहे" -#: ../src/ui/theme-parser.c:1473 +#: ../src/ui/theme-parser.c:1559 #, c-format msgid "Border \"%s\" is unknown" msgstr "कडा \"%s\" अपरिचीत आहे" -#: ../src/ui/theme-parser.c:1776 +#: ../src/ui/theme-parser.c:1870 #, c-format msgid "No \"start_angle\" or \"from\" attribute on element <%s>" msgstr "घटक <%s> वरील \"start_angle\" किंवा \"पासून\" गुणधर्म नाही" -#: ../src/ui/theme-parser.c:1783 +#: ../src/ui/theme-parser.c:1877 #, c-format msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" msgstr "घटक <%s> वरील \"extent_angle\" किंवा \"प्रति\" गुणधर्म नाही" -#: ../src/ui/theme-parser.c:2023 +#: ../src/ui/theme-parser.c:2117 #, c-format msgid "Did not understand value \"%s\" for type of gradient" msgstr "ही किंमत \"%s\" प्रकारच्या चढाकरिता समजू शकली नाही" -#: ../src/ui/theme-parser.c:2101 ../src/ui/theme-parser.c:2476 +#: ../src/ui/theme-parser.c:2195 ../src/ui/theme-parser.c:2570 #, c-format msgid "Did not understand fill type \"%s\" for <%s> element" msgstr "गुणधर्मासाठी रिकाम्या प्रकारचे \"%s\" for <%s> समजू शकली नाही" -#: ../src/ui/theme-parser.c:2268 ../src/ui/theme-parser.c:2351 -#: ../src/ui/theme-parser.c:2414 +#: ../src/ui/theme-parser.c:2362 ../src/ui/theme-parser.c:2445 +#: ../src/ui/theme-parser.c:2508 #, c-format msgid "Did not understand state \"%s\" for <%s> element" msgstr "गुणधर्मासाठी स्थिती \"%s\" for <%s> समजू शकली नाही" -#: ../src/ui/theme-parser.c:2278 ../src/ui/theme-parser.c:2361 +#: ../src/ui/theme-parser.c:2372 ../src/ui/theme-parser.c:2455 #, c-format msgid "Did not understand shadow \"%s\" for <%s> element" msgstr "गुणधर्मासाठी सावली \"%s\" for <%s> समजू शकली नाही" -#: ../src/ui/theme-parser.c:2288 +#: ../src/ui/theme-parser.c:2382 #, c-format msgid "Did not understand arrow \"%s\" for <%s> element" msgstr "गुणधर्मासाठी बाण \"%s\" for <%s> समजू शकला नाही" -#: ../src/ui/theme-parser.c:2588 ../src/ui/theme-parser.c:2684 +#: ../src/ui/theme-parser.c:2696 ../src/ui/theme-parser.c:2792 #, c-format msgid "No <draw_ops> called \"%s\" has been defined" msgstr "म्हणून <draw_ops> तो \"%s\" ठरवले आहे" -#: ../src/ui/theme-parser.c:2600 ../src/ui/theme-parser.c:2696 +#: ../src/ui/theme-parser.c:2708 ../src/ui/theme-parser.c:2804 #, c-format msgid "Including draw_ops \"%s\" here would create a circular reference" msgstr "ड्रॉ ऑपमिळून \"%s\" येथे वर्तुळाकार संदर्भ केला आहे" -#: ../src/ui/theme-parser.c:2811 +#: ../src/ui/theme-parser.c:2919 #, c-format msgid "Unknown position \"%s\" for frame piece" msgstr "फितीवरील चित्रासाठी \"%s\" स्थिती अवैध आहे" -#: ../src/ui/theme-parser.c:2819 +#: ../src/ui/theme-parser.c:2927 #, c-format msgid "Frame style already has a piece at position %s" msgstr "%s ह्या स्थितीतील फितचित्राकरिता शैली आधीच आहे" -#: ../src/ui/theme-parser.c:2836 ../src/ui/theme-parser.c:2911 +#: ../src/ui/theme-parser.c:2944 ../src/ui/theme-parser.c:3021 #, c-format msgid "No <draw_ops> with the name \"%s\" has been defined" msgstr "नावाबरोबर <draw_ops> विश्लेषण \"%s\" केले नाही" -#: ../src/ui/theme-parser.c:2865 +#: ../src/ui/theme-parser.c:2974 #, c-format msgid "Unknown function \"%s\" for button" msgstr "बटणासाठी \"%s\" अयोग्य कार्य" -#: ../src/ui/theme-parser.c:2874 +#: ../src/ui/theme-parser.c:2984 #, c-format msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "बटन कार्यपध्दती \"%1$s\" या आवृत्ती मध्ये अस्तीत्वात नाही (%2$d, आवश्यक %3$d)" +msgstr "" +"बटन कार्यपध्दती \"%1$s\" या आवृत्ती मध्ये अस्तीत्वात नाही (%2$d, आवश्यक %3$d)" -#: ../src/ui/theme-parser.c:2886 +#: ../src/ui/theme-parser.c:2996 #, c-format msgid "Unknown state \"%s\" for button" msgstr "बटणाकरिता \"%s\" अयोग्य स्थिती" -#: ../src/ui/theme-parser.c:2894 +#: ../src/ui/theme-parser.c:3004 #, c-format msgid "Frame style already has a button for function %s state %s" msgstr "कार्य %s स्थिती %s करिता फितीची शैली आधीच आहे" -#: ../src/ui/theme-parser.c:2965 +#: ../src/ui/theme-parser.c:3075 #, c-format msgid "\"%s\" is not a valid value for focus attribute" msgstr "\"%s\" फोकस गुणविशेषासाठी हि योग्य किंमत नाही" -#: ../src/ui/theme-parser.c:2974 +#: ../src/ui/theme-parser.c:3084 #, c-format msgid "\"%s\" is not a valid value for state attribute" msgstr "\"%s\" स्थिती गुणविशेषासाठी हि योग्य किंमत नाही" -#: ../src/ui/theme-parser.c:2984 +#: ../src/ui/theme-parser.c:3094 #, c-format msgid "A style called \"%s\" has not been defined" msgstr "\"%s\" ह्या नावाची शैली अस्तित्वात नाही" -#: ../src/ui/theme-parser.c:3005 ../src/ui/theme-parser.c:3028 +#: ../src/ui/theme-parser.c:3115 ../src/ui/theme-parser.c:3138 #, c-format msgid "\"%s\" is not a valid value for resize attribute" msgstr "\"%s\" पुर्नआकार या गुणविशेषासाठी हि योग्य किंमत नाही" -#: ../src/ui/theme-parser.c:3039 +#: ../src/ui/theme-parser.c:3149 #, c-format msgid "" "Should not have \"resize\" attribute on <%s> element for maximized/shaded " "states" -msgstr "मोठे करा/छटा स्थिती करीता <%s> घटकावरील \"पुन्हआकार\" गुणधर्म नसायला हवे" +msgstr "" +"मोठे करा/छटा स्थिती करीता <%s> घटकावरील \"पुन्हआकार\" गुणधर्म नसायला हवे" -#: ../src/ui/theme-parser.c:3053 +#: ../src/ui/theme-parser.c:3163 #, c-format -msgid "Should not have \"resize\" attribute on <%s> element for maximized states" +msgid "" +"Should not have \"resize\" attribute on <%s> element for maximized states" msgstr "मोठे करा स्थिती करीता <%s> घटकावरील \"पुन्हआकार\" गुणधर्म नसायला हवे" -#: ../src/ui/theme-parser.c:3067 ../src/ui/theme-parser.c:3089 +#: ../src/ui/theme-parser.c:3177 ../src/ui/theme-parser.c:3221 #, c-format msgid "Style has already been specified for state %s resize %s focus %s" msgstr "%s पुर्नआकार %s फोकस %s स्थितीसाठी शैली ही अगोदरच ठरवलेली आहे" -#: ../src/ui/theme-parser.c:3078 ../src/ui/theme-parser.c:3100 +#: ../src/ui/theme-parser.c:3188 ../src/ui/theme-parser.c:3199 +#: ../src/ui/theme-parser.c:3210 ../src/ui/theme-parser.c:3232 +#: ../src/ui/theme-parser.c:3243 ../src/ui/theme-parser.c:3254 #, c-format msgid "Style has already been specified for state %s focus %s" msgstr "%s फोकस %s स्थितीसाठी शैली ही अगोदरच ठरवलेली आहे" -#: ../src/ui/theme-parser.c:3139 +#: ../src/ui/theme-parser.c:3293 msgid "" "Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " "attribute and also a <draw_ops> element, or specified two elements)" @@ -2134,7 +1201,7 @@ msgstr "" "<piece> घटक करीता दोन draw_ops असू शकत नाही (सुत्रयोजनाने draw_ops गुणधर्म व " "<draw_ops> घटक निश्चित केले, किंवा दोन घटक निश्चित केले)" -#: ../src/ui/theme-parser.c:3177 +#: ../src/ui/theme-parser.c:3331 msgid "" "Can't have a two draw_ops for a <button> element (theme specified a draw_ops " "attribute and also a <draw_ops> element, or specified two elements)" @@ -2142,282 +1209,1289 @@ msgstr "" "<button> घटक करीता दोन draw_ops असू शकत नाही (सुत्रयोजनाने draw_ops गुणधर्म व " "<draw_ops> घटक निश्चित केले, किंवा दोन घटक निश्चित केले)" -#: ../src/ui/theme-parser.c:3215 +#: ../src/ui/theme-parser.c:3369 msgid "" "Can't have a two draw_ops for a <menu_icon> element (theme specified a " "draw_ops attribute and also a <draw_ops> element, or specified two elements)" msgstr "" -"<menu_icon> घटक करीता दोन draw_ops असू शकत नाही (सुत्रयोजनाने draw_ops गुणधर्म व " +"<menu_icon> घटक करीता दोन draw_ops असू शकत नाही (सुत्रयोजनाने draw_ops " +"गुणधर्म व " "<draw_ops> घटक निश्चित केले, किंवा दोन घटक निश्चित केले)" -#: ../src/ui/theme-parser.c:3263 +#: ../src/ui/theme-parser.c:3433 +#, c-format +msgid "Bad version specification '%s'" +msgstr "अयोग्य आवृत्ती स्पेसिफिकेशन '%s'" + +#: ../src/ui/theme-parser.c:3506 +msgid "" +"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" +"theme-2.xml" +msgstr "" +"\"version\" गुणधर्माला metacity-theme-1.xml किंवा metacity-theme-2.xml मध्ये " +"वापरणे अशक्य" + +#: ../src/ui/theme-parser.c:3529 +#, c-format +msgid "Theme requires version %s but latest supported theme version is %d.%d" +msgstr "" +"सुत्रयोजनेला आवृत्ती %s आवश्यक परंतु किमान समर्थीत सुत्रयोजना आवृत्ती %d.%d " +"आहे" + +#: ../src/ui/theme-parser.c:3561 #, c-format msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "संकल्पनेमधील सर्वात बाहेरचे गुणधर्म हेच असले पाहिजे <मेटॅसिटी संकल्पना> नाही <%s>" +msgstr "" +"संकल्पनेमधील सर्वात बाहेरचे गुणधर्म हेच असले पाहिजे <मेटॅसिटी संकल्पना> नाही " +"<%s>" -#: ../src/ui/theme-parser.c:3283 +#: ../src/ui/theme-parser.c:3581 #, c-format -msgid "Element <%s> is not allowed inside a name/author/date/description element" +msgid "" +"Element <%s> is not allowed inside a name/author/date/description element" msgstr "गुणधर्माच्या <%s> नाव/लेखक/दिनांक/वर्णन गुणधर्मासाठी परवानगी नाही" -#: ../src/ui/theme-parser.c:3288 +#: ../src/ui/theme-parser.c:3586 #, c-format msgid "Element <%s> is not allowed inside a <constant> element" msgstr "<स्थिरांक> गुणधर्मामध्ये <%s> गुणधर्माला परवानगी नाही" -#: ../src/ui/theme-parser.c:3300 +#: ../src/ui/theme-parser.c:3598 #, c-format -msgid "Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "गुणधर्माच्या <%s> अंतर/सीमारेषा/हवे असलेले प्रमाण या गुणधर्माना परवानगी नाही" +msgid "" +"Element <%s> is not allowed inside a distance/border/aspect_ratio element" +msgstr "" +"गुणधर्माच्या <%s> अंतर/सीमारेषा/हवे असलेले प्रमाण या गुणधर्माना परवानगी नाही" -#: ../src/ui/theme-parser.c:3322 +#: ../src/ui/theme-parser.c:3620 #, c-format msgid "Element <%s> is not allowed inside a draw operation element" msgstr "गुणधर्मामध्ये <%s> ड्रॉ प्रक्रिया गुणधर्माना परवानगी नाही" -#: ../src/ui/theme-parser.c:3332 ../src/ui/theme-parser.c:3362 -#: ../src/ui/theme-parser.c:3367 ../src/ui/theme-parser.c:3372 +#: ../src/ui/theme-parser.c:3630 ../src/ui/theme-parser.c:3660 +#: ../src/ui/theme-parser.c:3665 ../src/ui/theme-parser.c:3670 #, c-format msgid "Element <%s> is not allowed inside a <%s> element" msgstr "गुणधर्मामध्ये <%s> गुणधर्माना परवानगी <%s> नाही" -#: ../src/ui/theme-parser.c:3594 +#: ../src/ui/theme-parser.c:3898 msgid "No draw_ops provided for frame piece" msgstr "भिंत फितीसाठी चित्रांचे विकल्प नाहीत" -#: ../src/ui/theme-parser.c:3609 +#: ../src/ui/theme-parser.c:3913 msgid "No draw_ops provided for button" msgstr "बटणासाठी चित्र काढण्याचे विकल्प नाहीत" -#: ../src/ui/theme-parser.c:3661 +#: ../src/ui/theme-parser.c:3967 #, c-format msgid "No text is allowed inside element <%s>" msgstr "गुमधर्मामध्ये वाक्यरचना असण्याची परवानगी नाही <%s>" -#: ../src/ui/theme-parser.c:3716 -msgid "<name> specified twice for this theme" -msgstr "ह्या संकल्पनेकरिता <नाव> दोनदा ठरवून देण्यात आले" - -#: ../src/ui/theme-parser.c:3727 -msgid "<author> specified twice for this theme" -msgstr "ह्या संकल्पनैकरिता <लेखक> दोनदा ठरवून देण्यात आले" - -#: ../src/ui/theme-parser.c:3738 -msgid "<copyright> specified twice for this theme" -msgstr "ह्या संकल्पनेकरिता <प्रतहक्क> दोनदा ठरवून देण्यात आले" - -#: ../src/ui/theme-parser.c:3749 -msgid "<date> specified twice for this theme" -msgstr "ह्या संकल्पनेकरिता <दिनांक> दोनदा ठरवून देण्यात आले" - -#: ../src/ui/theme-parser.c:3760 -msgid "<description> specified twice for this theme" -msgstr "ह्या संकल्पनेकरिता <वर्णन> दोनदा ठरवून देण्यात आले" +#: ../src/ui/theme-parser.c:4025 ../src/ui/theme-parser.c:4037 +#: ../src/ui/theme-parser.c:4049 ../src/ui/theme-parser.c:4061 +#: ../src/ui/theme-parser.c:4073 +#, c-format +msgid "<%s> specified twice for this theme" +msgstr "<%s> या सुत्रयोजनेकरीता दोनवेळा निर्देशीत केले" -#: ../src/ui/theme-parser.c:4027 +#: ../src/ui/theme-parser.c:4335 #, c-format msgid "Failed to find a valid file for theme %s\n" msgstr "सुत्रयोजना %s करीता वैध फाइल शोधण्यास अपयशी\n" -#: ../src/ui/theme-parser.c:4083 +#: ../src/x11/session.c:1815 +msgid "" +"These windows do not support "save current setup" and will have to " +"be restarted manually next time you log in." +msgstr "" +"हे पटल "सध्याचे सेटअप साठवा" करीता समर्थन पुरवत नाही व पुढच्यावेळी " +"प्रवेश " +"करताना स्वहस्तेरित्या सुरू करावे लागेल." + +#: ../src/x11/window-props.c:515 #, c-format -msgid "Theme file %s did not contain a root <metacity_theme> element" -msgstr "सुत्रयोजना फाइलमध्ये %s मूळ गुणधर्म <मेटॅसिटी_सुत्रयोजना> अस्तित्वात नाही" +msgid "%s (on %s)" +msgstr "%1$s (%2$s वर)" -#: ../src/ui/theme-viewer.c:75 -msgid "/_Windows" -msgstr "/खिडक्या(_W)" +#~ msgid "background texture could not be created from file" +#~ msgstr "फाइलपासून निर्माण न होण्याजोगी पार्श्वभूमी टेक्सचर" -#: ../src/ui/theme-viewer.c:76 -msgid "/Windows/tearoff" -msgstr "/खिडक्या/टिअरऑफ" +#~ msgid "Unknown window information request: %d" +#~ msgstr "अपरिचीत चौकट माहिती विनंती: %d" -#: ../src/ui/theme-viewer.c:77 -msgid "/Windows/_Dialog" -msgstr "/खिडक्या/संवाद(_D)" +#~ msgid "Missing %s extension required for compositing" +#~ msgstr "एकत्रीकरण करीता आवश्यक %s विस्तार आढळले नाही" -#: ../src/ui/theme-viewer.c:78 -msgid "/Windows/_Modal dialog" -msgstr "/खिडक्या/मोडल संवाद(_M)" +#~ msgid "" +#~ "Some other program is already using the key %s with modifiers %x as a " +#~ "binding\n" +#~ msgstr "" +#~ "कुठलेतरी इतर कार्यक्रम आधिपासूनच किल्ली %s ला संपादक %x सह बांधणी म्हणून वापरत आहे\n" -#: ../src/ui/theme-viewer.c:79 -msgid "/Windows/_Utility" -msgstr "/खिडक्या/उपयुक्तता(_U)" +#~| msgid "\"%s\" is not a valid value for focus attribute" +#~ msgid "\"%s\" is not a valid accelerator\n" +#~ msgstr "\"%s\" वैध ॲक्सिलरेटर नाही\n" -#: ../src/ui/theme-viewer.c:80 -msgid "/Windows/_Splashscreen" -msgstr "/खिडक्या/स्प्लॅशस्क्रीन(_S)" +#~ msgid "" +#~ "Workarounds for broken applications disabled. Some applications may not " +#~ "behave properly.\n" +#~ msgstr "" +#~ "अनिश्चित अनुप्रोयगांकरीता कार्य अकार्यान्वीत केले गेले. काहीक अनुप्रयोगांची वागणून " +#~ "योग्यरित्या आढळणार नाही\n" -#: ../src/ui/theme-viewer.c:81 -msgid "/Windows/_Top dock" -msgstr "/खिडक्या/उच्च डॉक(_T)" +#~ msgid "Could not parse font description \"%s\" from GSettings key %s\n" +#~ msgstr "GSettings कि %2$s पासून फाँट वर्णन \"%1$s\" वाचणे अशक्य\n" -#: ../src/ui/theme-viewer.c:82 -msgid "/Windows/_Bottom dock" -msgstr "/खिडक्या/तळाचा डॉक(_B)" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" +#~ msgstr "" +#~ "माउस बटन संपादक करीता संयोजना माहितीकोश मध्ये आढळलेले \"%s\" वैध मुल्य नाही\n" -#: ../src/ui/theme-viewer.c:83 -msgid "/Windows/_Left dock" -msgstr "/खिडक्या/डावा डॉक(_L)" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for " +#~ "keybinding \"%s\"\n" +#~ msgstr "" +#~ "keybinding \"%2$s\" करीता संयोजना माहितीकोश मध्ये आढळलेले \"%1$s\" वैध मुल्य " +#~ "नाही\n" -#: ../src/ui/theme-viewer.c:84 -msgid "/Windows/_Right dock" -msgstr "/खिडक्या/उजवा डॉक(_R)" +#~ msgid "" +#~ "Could not acquire window manager selection on screen %d display \"%s\"\n" +#~ msgstr "" +#~ "दृश्य \"%2$s\" वरील पडदा %1$d करीता चौकट व्यवस्थापक निवड प्राप्त करू शकले नाही\n" -#: ../src/ui/theme-viewer.c:85 -msgid "/Windows/_All docks" -msgstr "/खिडक्या/सर्व डॉक(_A)" +#~ msgid "Could not release screen %d on display \"%s\"\n" +#~ msgstr "दृश्य \"%2$s\" वरील पडदा %1$d मोकळे करू शकला नाही\n" -#: ../src/ui/theme-viewer.c:86 -msgid "/Windows/Des_ktop" -msgstr "/खिडक्या/कार्यक्षेत्र(_k)" +#~ msgid "Could not create directory '%s': %s\n" +#~ msgstr "संचयीका '%s' बनवू शकले नाही: %s\n" -#: ../src/ui/theme-viewer.c:135 -msgid "Open another one of these windows" -msgstr "यापैकी वेगळी चौकट उघडा" +#~ msgid "Could not open session file '%s' for writing: %s\n" +#~ msgstr "लिहीण्यासाठी सत्र फाइल '%s' उघडू शकले नाही: %s\n" -#: ../src/ui/theme-viewer.c:142 -msgid "This is a demo button with an 'open' icon" -msgstr "'उघडा' ह्या चिन्हाबरोबर हे प्रदर्शनीय बटण आहे" +#~ msgid "Error writing session file '%s': %s\n" +#~ msgstr "सत्र फाइल '%s' लिहीतेवेळी त्रुटी: %s\n" -#: ../src/ui/theme-viewer.c:149 -msgid "This is a demo button with a 'quit' icon" -msgstr "'बाहेर पडा' ह्या चिन्हाबरोबर हे प्रदर्शनीय बटण आहे" +#~ msgid "Error closing session file '%s': %s\n" +#~ msgstr "सत्र फाइल '%s' लिहीतेवेळी त्रुटी: %s\n" -#: ../src/ui/theme-viewer.c:242 -msgid "This is a sample message in a sample dialog" -msgstr "उदाहरणाकरिता दिलेल्या संभाषणात ह्या नमुन्याचा संदेश आहे" +#~ msgid "Failed to parse saved session file: %s\n" +#~ msgstr "संचयीत सत्र फाइल वाचण्यास अपयशी: %s\n" -#: ../src/ui/theme-viewer.c:325 -#, c-format -msgid "Fake menu item %d\n" -msgstr "खोटी मेनू वस्तू %d\n" +#~ msgid "<mutter_session> attribute seen but we already have the session ID" +#~ msgstr "<mutter_session> गुणधर्म आढळले परंतु सत्र ID आधिपासून अस्तित्वात आहे" -#: ../src/ui/theme-viewer.c:359 -msgid "Border-only window" -msgstr "फक्त-किनार चौकट" +#~ msgid "Unknown attribute %s on <%s> element" +#~ msgstr "<%2$s> घटक वरील अपरिचीत गुणधर्म %1$s" -#: ../src/ui/theme-viewer.c:361 -msgid "Bar" -msgstr "पट्टी" +#~ msgid "nested <window> tag" +#~ msgstr "नेस्टेड <window> टॅग" -#: ../src/ui/theme-viewer.c:378 -msgid "Normal Application Window" -msgstr "सामान्य अनुप्रयोग चौकट" +#~ msgid "Unknown element %s" +#~ msgstr "अपरिचीत घटक %s" -#: ../src/ui/theme-viewer.c:382 -msgid "Dialog Box" -msgstr "संवाद खोका" +#~ msgid "Failed to open debug log: %s\n" +#~ msgstr "डिबग लॉग उघडण्यास अपयश आले: %s\n" -#: ../src/ui/theme-viewer.c:386 -msgid "Modal Dialog Box" -msgstr "मोडल संवाद खोका" +#~ msgid "Failed to fdopen() log file %s: %s\n" +#~ msgstr "एफडीउघड() लॉग फाइल उघडण्यास अपयशी%s: %s\n" -#: ../src/ui/theme-viewer.c:390 -msgid "Utility Palette" -msgstr "उपयुक्तता पॅलेट" +#~ msgid "Opened log file %s\n" +#~ msgstr "लॉग फाइल %s उघडली\n" -#: ../src/ui/theme-viewer.c:394 -msgid "Torn-off Menu" -msgstr "टिअर-ऑफ मेनू" +#~ msgid "Window manager: " +#~ msgstr "चौकट व्यवस्थापक: " -#: ../src/ui/theme-viewer.c:398 -msgid "Border" -msgstr "किनार" +#~ msgid "Bug in window manager: " +#~ msgstr "चौकट व्यवस्थापकात त्रुटी: " -#: ../src/ui/theme-viewer.c:726 -#, c-format -msgid "Button layout test %d" -msgstr "बटन लेआउट कसोटी %d" +#~ msgid "Window manager warning: " +#~ msgstr "चौकट व्यवस्थापक सुचना: " -#: ../src/ui/theme-viewer.c:755 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "एक चौकटची चौकट काढण्यासाठी %g मिलीसेकंद" +#~ msgid "Window manager error: " +#~ msgstr "चौकट व्यवस्थापक त्रुटी: " -#: ../src/ui/theme-viewer.c:798 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "वापर: metacity-theme-viewer [THEMENAME]\n" +#~ msgid "" +#~ "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " +#~ "window as specified in the ICCCM.\n" +#~ msgstr "" +#~ "ICCCM मधिल निश्चित केलेल्या WM_CLIENT_LEADER चौकट ऐवजी चौकट %s, स्वतःवरच " +#~ "SM_CLIENT_ID निश्चित करते.\n" -#: ../src/ui/theme-viewer.c:805 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "थीम भारित करण्यात त्रुटी: %s\n" +#~ msgid "" +#~ "Window %s sets an MWM hint indicating it isn't resizable, but sets min " +#~ "size %d x %d and max size %d x %d; this doesn't make much sense.\n" +#~ msgstr "" +#~ "चौकट %s MWM निश्चित करतो ज्याचा अर्थ ते पुन्हआकार देण्याजोगी नाही, परंतु किमान आकार " +#~ "%d x %d व कमाल आकार %d x %d; निश्चित करते ज्याचा जास्त अर्थ दिसून येत नाही.\n" -#: ../src/ui/theme-viewer.c:811 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "\"%s\" थीम %g सेकंदांत भारित करत आहे\n" +#~ msgid "Application set a bogus _NET_WM_PID %lu\n" +#~ msgstr "अनुप्रयोग फरजी _NET_WM_PID %lu निश्चित करा\n" -#: ../src/ui/theme-viewer.c:852 -msgid "Normal Title Font" -msgstr "सामान्य शिर्षक फॉन्ट" +#~ msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +#~ msgstr "%2$s करीता अवैध WM_TRANSIENT_FOR window 0x%1$lx निश्चित केले गेले.\n" -#: ../src/ui/theme-viewer.c:858 -msgid "Small Title Font" -msgstr "लहान शिर्षक फॉन्ट" +#~ msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" +#~ msgstr "WM_TRANSIENT_FOR पटल 0x%lx, %s करीता लूप निर्माण करेल.\n" -#: ../src/ui/theme-viewer.c:864 -msgid "Large Title Font" -msgstr "मोठा शिर्षक फॉन्ट" +#~ msgid "" +#~ "Window 0x%lx has property %s\n" +#~ "that was expected to have type %s format %d\n" +#~ "and actually has type %s format %d n_items %d.\n" +#~ "This is most likely an application bug, not a window manager bug.\n" +#~ "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +#~ msgstr "" +#~ "Window 0x%lx चे गुणधर्म %s\n" +#~ "ज्याला प्रकार %s स्वरूप %d असणे अपेक्षीत होते\n" +#~ "व वास्तवीकरित्या त्याचा प्रकार %s स्वरूप %d n_items %d आहे.\n" +#~ "ये संभाव्यरित्या अनुप्रयोग दोष आहे, व चौकट व्यवस्थापक दोष नाही.\n" +#~ "चौकटचे शिर्षक=\"%s\" वर्ग=\"%s\" नाव=\"%s\" या प्रमाणे आहे\n" -#: ../src/ui/theme-viewer.c:869 -msgid "Button Layouts" -msgstr "बटन लेआउट" +#~ msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +#~ msgstr "चौकट %s वरील गुणधर्म 0x%lx चुकीचे UTF-8 साठविले\n" -#: ../src/ui/theme-viewer.c:874 -msgid "Benchmark" -msgstr "बेंचमार्क" +#~ msgid "" +#~ "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the " +#~ "list\n" +#~ msgstr "" +#~ "चौकट 0x%2$lx वरील गुणधर्म %1$s मध्ये यादी मधिल %3$d करीता अवैध UTF-8 घटक " +#~ "समाविष्टीत\n" -#: ../src/ui/theme-viewer.c:921 -msgid "Window Title Goes Here" -msgstr "चौकटचे शिर्षक येथे जाते" +#~ msgid "Usage: %s\n" +#~ msgstr "वापर: %s\n" -#: ../src/ui/theme-viewer.c:1025 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"%2$g client-side सेकंद मध्ये %1$d पटल रेखाटले (%3$g मिलीसेकंद दर पटल) व %4$g सेकंद " -"घड्याळ वेळ व X सर्वर स्त्रोत अंतर्भुतीत (%5$g मिलीसेकंद दर पटल)\n" +#~ msgid "Mi_nimize" +#~ msgstr "लहान करा(_n)" -#: ../src/ui/theme-viewer.c:1244 -msgid "position expression test returned TRUE but set error" -msgstr "स्थिती संबोधन परिक्षा बरोबर परत आली पण तिने त्रुटी दर्शविली" +#~ msgid "Ma_ximize" +#~ msgstr "मोठ्यात मोठे करा(_x)" -#: ../src/ui/theme-viewer.c:1246 -msgid "position expression test returned FALSE but didn't set error" -msgstr "position expression चाचणी FALSE ठरली परंतु त्रुटी निश्चित झाली नाही" +#~ msgid "Unma_ximize" +#~ msgstr "लहान करा(_x)" -#: ../src/ui/theme-viewer.c:1250 -msgid "Error was expected but none given" -msgstr "त्रुटी अपेक्षित होती पम कोणतीच दिली गेली नाही" +#~ msgid "Roll _Up" +#~ msgstr "वर गुंडाळा(_U)" -#: ../src/ui/theme-viewer.c:1252 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "त्रुटी %d अपेक्षित होती पण %d दिली गेली" +#~ msgid "_Unroll" +#~ msgstr "गुंडाळी उघडा(_U)" -#: ../src/ui/theme-viewer.c:1258 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "त्रुटी अपेक्षित नव्हती पण एक परत पाठवली गेली: %s" +#~ msgid "_Move" +#~ msgstr "हलवा(_M)" -#: ../src/ui/theme-viewer.c:1262 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "X किंमत होती %d, %d ही हवी होती" +#~ msgid "_Resize" +#~ msgstr "पुनःआकारित करा(_R)" -#: ../src/ui/theme-viewer.c:1265 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "वाय किंमत होती %d, %d ही हवी होती" +#~ msgid "Move Titlebar On_screen" +#~ msgstr "शिर्षकपट्टी स्क्रीनवर हलवा(_s)" -#: ../src/ui/theme-viewer.c:1330 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "%d सेकंदात निबंधक वाक्यरचना वर्णन पार्स %g झाले (%g सेकंदाची सरासरी)\n" +#~ msgid "Always on _Top" +#~ msgstr "नेहमी वर (_T)" + +#~ msgid "_Always on Visible Workspace" +#~ msgstr "नेहमी दृश्य कार्यक्षेत्रावर(_A)" + +#~ msgid "_Only on This Workspace" +#~ msgstr "फक्त या कार्यक्षेत्रावर(_O)" + +#~ msgid "Move to Workspace _Left" +#~ msgstr "डाव्या कार्यक्षेत्रावर हलवा(_L)" + +#~ msgid "Move to Workspace R_ight" +#~ msgstr "उजव्या कार्यक्षेत्रावर हलवा(_i)" + +#~ msgid "Move to Workspace _Up" +#~ msgstr "वरील कार्यक्षेत्रावर हलवा(_U)" + +#~ msgid "Move to Workspace _Down" +#~ msgstr "खालील कार्यक्षेत्रावर हलवा(_D)" + +#~ msgid "_Close" +#~ msgstr "बंद करा(_C)" + +#~ msgid "Workspace %d%n" +#~ msgstr "Workspace %d%n" + +#~ msgid "Workspace 1_0" +#~ msgstr "कार्यक्षेत्र 10 (_0)" + +#~ msgid "Workspace %s%d" +#~ msgstr "कार्यक्षेत्र %s%d" + +#~ msgid "Move to Another _Workspace" +#~ msgstr "वेगळ्या कार्यक्षेत्रावर हलवा(_W)" + +#~ msgid "Shift" +#~ msgstr "Shift" + +#~ msgid "Ctrl" +#~ msgstr "Ctrl" + +#~ msgid "Alt" +#~ msgstr "Alt" + +#~ msgid "Meta" +#~ msgstr "Meta" + +#~ msgid "Super" +#~ msgstr "Super" + +#~ msgid "Hyper" +#~ msgstr "Hyper" + +#~ msgid "Mod2" +#~ msgstr "Mod2" + +#~ msgid "Mod3" +#~ msgstr "Mod3" + +#~ msgid "Mod4" +#~ msgstr "Mod4" + +#~ msgid "Mod5" +#~ msgstr "Mod5" + +#~ msgid "_Windows" +#~ msgstr "पटल (_W)" + +#~ msgid "_Dialog" +#~ msgstr "संवाद (_D)" + +#~ msgid "_Modal dialog" +#~ msgstr "मोडल संवाद (_M)" + +#~ msgid "_Utility" +#~ msgstr "युटिलिटि (_U)" + +#~ msgid "_Splashscreen" +#~ msgstr "स्प्लॅशस्क्रीन (_S)" + +#~ msgid "_Top dock" +#~ msgstr "टॉप डॉक (_T)" + +#~ msgid "_Bottom dock" +#~ msgstr "तळ डॉक (_B)" + +#~ msgid "_Left dock" +#~ msgstr "डावा डॉक (_L)" + +#~ msgid "_Right dock" +#~ msgstr "उजवा डॉक (_R)" + +#~ msgid "_All docks" +#~ msgstr "सर्व डॉक्स् (_A)" + +#~ msgid "Des_ktop" +#~ msgstr "डेस्कटॉप (_k)" + +#~ msgid "Open another one of these windows" +#~ msgstr "यापैकी वेगळी चौकट उघडा" + +#~ msgid "This is a demo button with an 'open' icon" +#~ msgstr "'उघडा' ह्या चिन्हाबरोबर हे प्रदर्शनीय बटण आहे" + +#~ msgid "This is a demo button with a 'quit' icon" +#~ msgstr "'बाहेर पडा' ह्या चिन्हाबरोबर हे प्रदर्शनीय बटण आहे" + +#~ msgid "This is a sample message in a sample dialog" +#~ msgstr "उदाहरणाकरिता दिलेल्या संभाषणात ह्या नमुन्याचा संदेश आहे" + +#~ msgid "Fake menu item %d\n" +#~ msgstr "खोटी मेनू वस्तू %d\n" + +#~ msgid "Border-only window" +#~ msgstr "फक्त-किनार चौकट" + +#~ msgid "Bar" +#~ msgstr "पट्टी" + +#~ msgid "Normal Application Window" +#~ msgstr "सामान्य अनुप्रयोग चौकट" + +#~ msgid "Dialog Box" +#~ msgstr "संवाद खोका" + +#~ msgid "Modal Dialog Box" +#~ msgstr "मोडल संवाद खोका" + +#~ msgid "Utility Palette" +#~ msgstr "उपयुक्तता पॅलेट" + +#~ msgid "Torn-off Menu" +#~ msgstr "टिअर-ऑफ मेनू" + +#~ msgid "Border" +#~ msgstr "किनार" + +#~ msgid "Attached Modal Dialog" +#~ msgstr "मोडल संवाद जोडले" + +#~ msgid "Button layout test %d" +#~ msgstr "बटन लेआउट कसोटी %d" + +#~ msgid "%g milliseconds to draw one window frame" +#~ msgstr "एक चौकटची चौकट काढण्यासाठी %g मिलीसेकंद" + +#~ msgid "Usage: metacity-theme-viewer [THEMENAME]\n" +#~ msgstr "वापर: metacity-theme-viewer [THEMENAME]\n" + +#~ msgid "Error loading theme: %s\n" +#~ msgstr "थीम भारित करण्यात त्रुटी: %s\n" + +#~ msgid "Loaded theme \"%s\" in %g seconds\n" +#~ msgstr "\"%s\" थीम %g सेकंदांत भारित करत आहे\n" + +#~ msgid "Normal Title Font" +#~ msgstr "सामान्य शिर्षक फॉन्ट" + +#~ msgid "Small Title Font" +#~ msgstr "लहान शिर्षक फॉन्ट" + +#~ msgid "Large Title Font" +#~ msgstr "मोठा शिर्षक फॉन्ट" + +#~ msgid "Button Layouts" +#~ msgstr "बटन लेआउट" + +#~ msgid "Benchmark" +#~ msgstr "बेंचमार्क" + +#~ msgid "Window Title Goes Here" +#~ msgstr "चौकटचे शिर्षक येथे जाते" + +#~ msgid "" +#~ "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and " +#~ "%g seconds wall clock time including X server resources (%g milliseconds " +#~ "per frame)\n" +#~ msgstr "" +#~ "%2$g client-side सेकंद मध्ये %1$d पटल रेखाटले (%3$g मिलीसेकंद दर पटल) व %4$g सेकंद " +#~ "घड्याळ वेळ व X सर्वर स्त्रोत अंतर्भुतीत (%5$g मिलीसेकंद दर पटल)\n" + +#~ msgid "position expression test returned TRUE but set error" +#~ msgstr "स्थिती संबोधन परिक्षा बरोबर परत आली पण तिने त्रुटी दर्शविली" + +#~ msgid "position expression test returned FALSE but didn't set error" +#~ msgstr "position expression चाचणी FALSE ठरली परंतु त्रुटी निश्चित झाली नाही" + +#~ msgid "Error was expected but none given" +#~ msgstr "त्रुटी अपेक्षित होती पम कोणतीच दिली गेली नाही" + +#~ msgid "Error %d was expected but %d given" +#~ msgstr "त्रुटी %d अपेक्षित होती पण %d दिली गेली" + +#~ msgid "Error not expected but one was returned: %s" +#~ msgstr "त्रुटी अपेक्षित नव्हती पण एक परत पाठवली गेली: %s" + +#~ msgid "x value was %d, %d was expected" +#~ msgstr "X किंमत होती %d, %d ही हवी होती" + +#~ msgid "y value was %d, %d was expected" +#~ msgstr "वाय किंमत होती %d, %d ही हवी होती" + +#~ msgid "" +#~ "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" +#~ msgstr "%d सेकंदात निबंधक वाक्यरचना वर्णन पार्स %g झाले (%g सेकंदाची सरासरी)\n" + +#, fuzzy +#~ msgid "Minimize window" +#~ msgstr "" +#~ "#-#-#-#-# mr.po (metacity.gnome-2-26.mr) #-#-#-#-#\n" +#~ "चौकट लहान करा\n" +#~ "#-#-#-#-# mr.po (metacity.gnome-2-26.mr) #-#-#-#-#\n" +#~ "पटल लहान करा" + +#~ msgid "Window Management" +#~ msgstr "चौकट व्यवस्थापन" + +#~ msgid "Failed to parse message \"%s\" from dialog process\n" +#~ msgstr "संवाद कार्यपध्दती मधून संदेश \"%s\" वाचता आले नाही\n" + +#~ msgid "Error reading from dialog display process: %s\n" +#~ msgstr "संवाद दृश्य पध्दती वाचताना त्रुटी: %s\n" + +#~ msgid "" +#~ "Error launching metacity-dialog to ask about killing an application: %s\n" +#~ msgstr "" +#~ "अनुप्रयोग पूर्णपणे बंद करण्याकरीता metacity-dialog प्रक्षेपीत करतेवेळी त्रुटी: %s\n" + +#~ msgid "Failed to get hostname: %s\n" +#~ msgstr "सादरकर्त्याचे नाव प्राप्त करण्यास अपयशी: %s\n" + +#~ msgid "" +#~ "Lost connection to the display '%s';\n" +#~ "most likely the X server was shut down or you killed/destroyed\n" +#~ "the window manager.\n" +#~ msgstr "" +#~ "दृश्य'%s' शी जुळवणी तुटली;\n" +#~ "संभाव्य X सर्वर बंद केले गेले किंवा\n" +#~ "तुम्ही चौकट व्यवस्थापक रद्द/नष्ट केले असावे.\n" + +#~ msgid "Fatal IO error %d (%s) on display '%s'.\n" +#~ msgstr "दृश्य '%3$s' वरील धोकादायक IO त्रुटी %1$d (%2$s) आढळले.\n" + +#~| msgid "" +#~| "There was an error running \"%s\":\n" +#~| "%s." +#~ msgid "" +#~ "There was an error running <tt>%s</tt>:\n" +#~ "\n" +#~ "%s" +#~ msgstr "" +#~ "<tt>%s</tt> चालवतेवेळी त्रुटी आढळली:\n" +#~ "\n" +#~ "%s" + +#~ msgid "No command %d has been defined.\n" +#~ msgstr "आदेश %d परिभाषीत नाही.\n" + +#~ msgid "No terminal command has been defined.\n" +#~ msgstr "टर्मिनल आदेश परिभाषीत नाही.\n" + +#~| msgid "Compositing Manager" +#~ msgid "Turn compositing on" +#~ msgstr "संयुक्त चालू करा" + +#~ msgid "Turn compositing off" +#~ msgstr "संयुक्त बंद करा" + +#~ msgid "Failed to restart: %s\n" +#~ msgstr "पुनःआरंभ करण्यास अपयशी: %s\n" + +#~ msgid "GConf key '%s' is set to an invalid value\n" +#~ msgstr "अयोग्य मुल्यसाठी '%s' GConf किल्ली जोडली आहे\n" + +#~| msgid "%d stored inGConf key %s is out of range 0 to %d\n" +#~ msgid "%d stored in GConf key %s is out of range %d to %d\n" +#~ msgstr "GConf कि %2$s अंतर्गत साठवलेले %1$d, %3$d ते %4$d क्षेत्राच्या बाहेर आहे\n" + +#~ msgid "GConf key \"%s\" is set to an invalid type\n" +#~ msgstr "अयोग्य प्रकारच्या \"%s\" GConf किल्ली जोडली आहे\n" + +#~ msgid "Error setting number of workspaces to %d: %s\n" +#~ msgstr "%d करीता कार्यक्षेत्राची एकूण संख्या स्थापित करतेवेळी त्रुटी: %s\n" + +#~ msgid "Error setting name for workspace %d to \"%s\": %s\n" +#~ msgstr "कार्यक्षेत्र %d करीता \"%s\" असे नाव स्थापीत करतेवेळी त्रुटी: %s\n" + +#~| msgid "Error setting name for workspace %d to \"%s\": %s\n" +#~ msgid "Error setting compositor status: %s\n" +#~ msgstr "कंपोसीटर स्थिती संयोजीत करतेवेळी त्रुटी आढळली: %s\n" + +#~| msgid "" +#~| "The keybinding used to close a window. The format looks like \"<" +#~| "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~| "liberal and allows lower or upper case, and also abbreviations such as " +#~| "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~| "special string \"disabled\", then there will be no keybinding for this " +#~| "action." +#~ msgid "" +#~ "The format looks like \"<Control>a\" or <Shift><Alt>F1\".\n" +#~ "\n" +#~ "The parser is fairly liberal and allows lower or upper case, and also " +#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "स्वरूप \"<Control>a\" किंवा \"<Shift><Alt>F1\" नुरूप दिसते.\n" +#~ "\n" +#~ " पार्सर लहान किंवा मोठे केस स्वीकारतो, व \"<Ctl>\" व \"<Ctrl>\" प्रमाणे संक्षिप्त " +#~ "रूप देखिल स्वीकारतो. विशेष अक्षरमाळा \"disabled\" करीता पर्याय निश्चित केल्यास, " +#~ "या कृती करीता किबाईन्डींग आढळली जाणार नाही." + +#~| msgid "" +#~| "The keybinding used to close a window. The format looks like \"<" +#~| "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~| "liberal and allows lower or upper case, and also abbreviations such as " +#~| "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~| "special string \"disabled\", then there will be no keybinding for this " +#~| "action." +#~ msgid "" +#~ "The format looks like \"<Control>a\" or <Shift><Alt>F1\".\n" +#~ "\n" +#~ "The parser is fairly liberal and allows lower or upper case, and also " +#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action.\n" +#~ "\n" +#~ "This keybinding may be reversed by holding down the \"shift\" key; " +#~ "therefore, \"shift\" cannot be one of the keys it uses." +#~ msgstr "" +#~ "स्वरूप \"<Control>a\" किंवा \"<Shift><Alt>F1\" नुरूप दिसते.\n" +#~ "\n" +#~ " पार्सर लहान किंवा मोठे केस स्वीकारतो, व \"<Ctl>\" व \"<Ctrl>\" प्रमाणे संक्षिप्त " +#~ "रूप देखिल स्वीकारतो. विशेष अक्षरमाळा \"disabled\" करीता पर्याय निश्चित केल्यास, या " +#~ "कृती करीता किबाईन्डींग आढळली जाणार नाही.\n" +#~ "\n" +#~ "\"shift\" कि दाबून ठेवल्यास किबाइन्डींग उल्टे केली जाऊ शकते; त्यामुळे, \"shift\" " +#~ "वापरणी पैकी एखादी कि असू शकत नाही." + +#~ msgid "Failed to read saved session file %s: %s\n" +#~ msgstr "सत्र फाइल %s वाचतेवेळी त्रुटी: %s\n" + +#~ msgid "" +#~ "Error launching metacity-dialog to warn about apps that don't support " +#~ "session management: %s\n" +#~ msgstr "" +#~ "सत्र व्यवस्थापन समर्थन प्रदान न करणारे अनुप्रयोगांविषयी सावधान करण्याकरीता metacity-" +#~ "dialog दाखल करतेवेळी त्रुटी: %s\n" + +#~ msgid "Metacity" +#~ msgstr "Metacity" + +#~ msgid "Switch to workspace 8" +#~ msgstr "कार्यक्षेत्र ८ वर जा" + +#~ msgid "Switch to workspace 9" +#~ msgstr "कार्यक्षेत्र ९ वर जा" + +#~ msgid "Switch to workspace 10" +#~ msgstr "कार्यक्षेत्र १० वर जा" + +#~ msgid "Switch to workspace 11" +#~ msgstr "कार्यक्षेत्र ११ वर जा" + +#~ msgid "Switch to workspace 12" +#~ msgstr "कार्यक्षेत्र १२ वर जा" + +#~| msgid "Switch to workspace on the left" +#~ msgid "Switch to workspace on the left of the current workspace" +#~ msgstr "वर्तमान कार्यक्षेत्रच्या डाव्या बाजूचे कार्यक्षेत्र वापरा" + +#~| msgid "Switch to workspace on the right" +#~ msgid "Switch to workspace on the right of the current workspace" +#~ msgstr "वर्तमान कार्यक्षेत्रच्या उजव्या बाजूचे कार्यक्षेत्र वापरा" + +#~| msgid "Switch to workspace above this one" +#~ msgid "Switch to workspace above the current workspace" +#~ msgstr "वर्तमान कार्यक्षेत्रच्या वरच्या बाजूचे कार्यक्षेत्र वापरा" + +#~| msgid "Switch to workspace below this one" +#~ msgid "Switch to workspace below the current workspace" +#~ msgstr "वर्तमान कार्यक्षेत्रच्या खालच्या बाजूचे कार्यक्षेत्र वापरा" + +#~| msgid "Move between windows of an application with popup" +#~ msgid "Move between windows of an application, using a popup window" +#~ msgstr "पॉपअप खिडकीचा वापर करून, अनुप्रोयगच्या खिडकी अंतर्गत हला" + +#~| msgid "Move backwards between windows of an application with popup" +#~ msgid "" +#~ "Move backward between windows of an application, using a popup window" +#~ msgstr "पॉपअप खिडकीचा वापर करून, अनुप्रोयगच्या खिडकी अंतर्गत मागे हला" + +#~| msgid "Move between windows with popup" +#~ msgid "Move between windows, using a popup window" +#~ msgstr "पॉपअप खिडकीचा वापर करून, खिडकी अंतर्गत हला" + +#~| msgid "Move focus backwards between windows using popup display" +#~ msgid "Move backward between windows, using a popup window" +#~ msgstr "पॉपअप खिडकीचा वापर करून, खिडकी अंतर्गत मागे हला" + +#~| msgid "Move between panels and the desktop with popup" +#~ msgid "Move between panels and the desktop, using a popup window" +#~ msgstr "पॉपअप खिडकीचा वापर करून, पटल व डेस्कटॉप अंतर्गत हला" + +#~| msgid "Move backwards between panels and the desktop with popup" +#~ msgid "Move backward between panels and the desktop, using a popup window" +#~ msgstr "पॉपअप खिडकीचा वापर करून, पटल व डेस्कटॉप अंतर्गत मागे हला" + +#~ msgid "Move between windows of an application immediately" +#~ msgstr "अनुप्रयोगतील चौकट मधून त्वरीत स्थानांतरीत व्हा" + +#~| msgid "Move backwards between windows of an application immediately" +#~ msgid "Move backward between windows of an application immediately" +#~ msgstr "अनुप्रयोगाच्या खिडकी अंतर्गत लगेच मागे हला" + +#~ msgid "Move between windows immediately" +#~ msgstr "चौकट मधून लगेच स्थानांतरीत व्हा" + +#~| msgid "Move backwards between windows immediately" +#~ msgid "Move backward between windows immediately" +#~ msgstr "खिडकी अंतर्गत लगेच मागे हला" + +#~ msgid "Move between panels and the desktop immediately" +#~ msgstr "पटल आणि डेस्कटॉप यामधून लगेचच स्थानांतरीत व्हा" + +#~ msgid "Move backward between panels and the desktop immediately" +#~ msgstr "डेस्कटॉप व पॅनल यामधून लगेचच मागे व्हा" + +#~| msgid "Hide all windows and focus desktop" +#~ msgid "Hide all normal windows and set focus to the desktop" +#~ msgstr "सर्व खिडक्या लपवा व केंद्रबिन्दू डेस्कटॉप वर निश्चित करा" + +#~| msgid "Show the panel menu" +#~ msgid "Show the panel's main menu" +#~ msgstr "पटलाचे मुख्य मेन्यू दाखवा" + +#~| msgid "Show the panel run application dialog" +#~ msgid "Show the panel's \"Run Application\" dialog box" +#~ msgstr "पटलाचे \"Run Application\" संवाद पेटी दाखवा" + +#~ msgid "Take a screenshot" +#~ msgstr "स्क्रीनशॉट घ्या" + +#~ msgid "Take a screenshot of a window" +#~ msgstr "चौकटचे स्क्रीनशॉट घ्या" + +#~ msgid "Run a terminal" +#~ msgstr "टर्मिनल चालवा" + +#~| msgid "Lower window below other windows" +#~ msgid "Toggle whether a window will always be visible over other windows" +#~ msgstr "खिडकी इतर खिडकींवर नेहमी दृष्यास्पद होईल का त्याकरीता टॉगल करा" + +#~| msgid "Toggle window on all workspaces" +#~ msgid "Toggle whether window is on all workspaces or just one" +#~ msgstr "सर्व किंवा फक्त एकच वर्कस्पेस वर खिडकी स्थित आहे त्याकरीता टॉगल करा" + +#~ msgid "Move window to workspace 5" +#~ msgstr "चौकट कार्यक्षेत्र ५ वर हलवा" + +#~ msgid "Move window to workspace 6" +#~ msgstr "चौकट कार्यक्षेत्र ६ वर हलवा" + +#~ msgid "Move window to workspace 7" +#~ msgstr "चौकट कार्यक्षेत्र ७ वर हलवा" + +#~ msgid "Move window to workspace 8" +#~ msgstr "चौकट कार्यक्षेत्र ८ वर हलवा" + +#~ msgid "Move window to workspace 9" +#~ msgstr "चौकट कार्यक्षेत्र ९ वर हलवा" + +#~ msgid "Move window to workspace 10" +#~ msgstr "चौकट कार्यक्षेत्र १० वर हलवा" + +#~ msgid "Move window to workspace 11" +#~ msgstr "चौकट कार्यक्षेत्र ११ वर हलवा" + +#~ msgid "Move window to workspace 12" +#~ msgstr "चौकट कार्यक्षेत्र १२ वर हलवा" + +#~| msgid "Raise obscured window, otherwise lower" +#~ msgid "Raise window if it's covered by another window, otherwise lower it" +#~ msgstr "इतर खिडकी द्वारे झाकलेले असल्यावर खिडकी उंचावा, नाहीतर खाली सरकवा" + +#~| msgid "Move window to north-west corner" +#~ msgid "Move window to north-west (top left) corner" +#~ msgstr "खिडकीला उत्तर-पश्चिम (वरून डावीकडे) बाजूस हलवा" + +#~| msgid "Move window to north-east corner" +#~ msgid "Move window to north-east (top right) corner" +#~ msgstr "खिडकीला उत्तर-पूर्व (वरून उजवीकडे) बाजूस हलवा" + +#~| msgid "Move window to south-west corner" +#~ msgid "Move window to south-west (bottom left) corner" +#~ msgstr "खिडकीला दक्षिण-पश्चिम (खालून डावीकडे) बाजूस हलवा" + +#~| msgid "Move window to south-east corner" +#~ msgid "Move window to south-east (bottom right) corner" +#~ msgstr "खिडकीला दक्षिण-पूर्व (खालून उजवीकडे) बाजूस हलवा" + +#~| msgid "Move window to north side of screen" +#~ msgid "Move window to north (top) side of screen" +#~ msgstr "खिडकीला पडद्याच्या उत्तर (शिर्ष) बाजूस हलवा" + +#~| msgid "Move window to south side of screen" +#~ msgid "Move window to south (bottom) side of screen" +#~ msgstr "खिडकीला पडद्याच्या दक्षिण (तळ) बाजूस हलवा" + +#~| msgid "Move window to east side of screen" +#~ msgid "Move window to east (right) side of screen" +#~ msgstr "खिडकीला पडद्याच्या पूर्व (उजवे) बाजूस हलवा" + +#~| msgid "Move window to west side of screen" +#~ msgid "Move window to west (left) side of screen" +#~ msgstr "खिडकीला पडद्याच्या पश्चिम (डावे) बाजूस हलवा" + +#~| msgid "Move window to east side of screen" +#~ msgid "Move window to center of screen" +#~ msgstr "खिडकीला पडद्याच्या मध्य बाजूस हलवा" + +#~ msgid "" +#~ "(Not implemented) Navigation works in terms of applications not windows" +#~ msgstr "" +#~ "(कार्यान्वीत नाही) संचार अनुप्रयोगच्या स्वरूपात कार्य करते चौकटच्या स्वरूपात नाही" + +#~ msgid "" +#~ "A font description string describing a font for window titlebars. The " +#~ "size from the description will only be used if the titlebar_font_size " +#~ "option is set to 0. Also, this option is disabled if the " +#~ "titlebar_uses_desktop_font option is set to true." +#~ msgstr "" +#~ "चौकट शिर्षकपट्टी करीता फॉन्ट वर्णन अक्षरमाळा परिभाषीत करा. परिभाषातील आकार " +#~ "तेव्हाच वापरले जाईल जेव्हा शिर्षकपट्टी_फॉन्ट_आकार पर्याय 0 करीता निश्चित केले जाईल. " +#~ "आणखी, जर हा पर्याय अकार्यान्वीत केला जाईल जर शिर्षकपट्टी_डेस्कटॉप_फॉन्ट_वापर पर्याय " +#~ "खरे आहे असे निश्चितही केले जाऊ शकते." + +#~ msgid "Action on title bar double-click" +#~ msgstr "शिर्षक पट्टीवरील दोनवेळा क्लिक केल्यावरची कृती" + +#~ msgid "Action on title bar middle-click" +#~ msgstr "शिर्षक पट्टीवरील मध्य क्लिक केल्यावरची कृती" + +#~ msgid "Action on title bar right-click" +#~ msgstr "शिर्षक पट्टीवरील उजवी क्लिक केल्यावरची कृती" + +#~ msgid "Arrangement of buttons on the titlebar" +#~ msgstr "शिर्षक पट्टीवरील बटणांची मांडणी" + +#~| msgid "" +#~| "Arrangement of buttons on the titlebar. The value should be a string, " +#~| "such as \"menu:minimize,maximize,close\"; the colon separates the left " +#~| "corner of the window from the right corner, and the button names are " +#~| "comma-separated. Duplicate buttons are not allowed. Unknown button names " +#~| "are silently ignored so that buttons can be added in future metacity " +#~| "versions without breaking older versions." +#~ msgid "" +#~ "Arrangement of buttons on the titlebar. The value should be a string, " +#~ "such as \"menu:minimize,maximize,spacer,close\"; the colon separates the " +#~ "left corner of the window from the right corner, and the button names are " +#~ "comma-separated. Duplicate buttons are not allowed. Unknown button names " +#~ "are silently ignored so that buttons can be added in future metacity " +#~ "versions without breaking older versions. A special spacer tag can be " +#~ "used to insert some space between two adjacent buttons." +#~ msgstr "" +#~ "शिर्षक पट्टीवरील बटणांची मांडणी. मुल्य अक्षरमाळा असायला हवे, जसे की \"menu:" +#~ "minimize,maximize,spacer,close\"; द्विबिंदुचिन्ह चौकटीच्या उजव्या कोपऱ्यापासून " +#~ "डावी कोपरा अलग करतो, व बटण नाव स्वल्पविराम-विभाजीत आसतात. समान बटणांना " +#~ "परवानगी नाही. अपरिचीत बटण नाव दुर्लक्षीत केले जाते ज्यामुळे बटण भविष्यात मेटासिटी " +#~ "आवृत्ती करीता जुनी आवृत्ती न मोडता जोडल्या जाऊ शकते. दोन बटणांच्या अंतर्गत मोकळी " +#~ "जागा अंतर्भूत करण्याकरीता स्पेसर टॅग वापरले जाऊ शकते." + +#~ msgid "Automatically raises the focused window" +#~ msgstr "फोकस केलेली चौकट आपोआप उघडते" + +#~| msgid "" +#~| "Clicking a window while holding down this modifier key will move the " +#~| "window (left click), resize the window (middle click), or show the " +#~| "window menu (right click). Modifier is expressed as \"<Alt>\" or " +#~| "\"<Super>\" for example." +#~ msgid "" +#~ "Clicking a window while holding down this modifier key will move the " +#~ "window (left click), resize the window (middle click), or show the window " +#~ "menu (right click). The left and right operations may be swapped using " +#~ "the \"mouse_button_resize\" key. Modifier is expressed as \"<Alt>\" " +#~ "or \"<Super>\" for example." +#~ msgstr "" +#~ "ही संपादन कळ दाबून ठेवल्यास चौकटवर किल्क केल्यास चौकट हलविले जाईल (डावी क्लिक), " +#~ "चौकट पुन्ह आकार (मध्य किल्क), किंवा चौकट मेन्यू दर्शवायचे असल्यास (उजवी क्लिक) चा " +#~ "वापर केला जाऊ शकतो. \"mouse_button_resize\" कि याचा वापर करून डावे व उजवे " +#~ "कार्य स्वॅप केले जाऊ शकते. मॉडिफायर \"<Alt>\" किंवा \"<Super>\" " +#~ "यानुरूप स्वॅप केले जाऊ शकते." + +#~ msgid "Commands to run in response to keybindings" +#~ msgstr "कळीच्या बंधाना प्रतिसाद म्हणून आदेश काम करतात" + +#~ msgid "Compositing Manager" +#~ msgstr "व्यवस्थापक संयोजीत करीत आहे" + +#~ msgid "Control how new windows get focus" +#~ msgstr "नविन चौकटीस लक्ष्यकेंद्रीत कसे करायचे ते नियंत्रीत करते" + +#~ msgid "Current theme" +#~ msgstr "सद्याची सुत्रयोजना" + +#~ msgid "Delay in milliseconds for the auto raise option" +#~ msgstr "स्व वाढ पर्यायकरीता मिलीसेकंदामधिल उशीर" + +#~ msgid "Determines whether Metacity is a compositing manager." +#~ msgstr "Metacity संयोजना व्यस्थापक आहे का ते निश्चित करते." + +#~ msgid "" +#~ "Determines whether applications or the system can generate audible " +#~ "'beeps'; may be used in conjunction with 'visual bell' to allow silent " +#~ "'beeps'." +#~ msgstr "" +#~ "अनुप्रयोग किंवा प्रणाली एकण्याजोगी 'बीप' निर्माण करू शकते की नाही ते निश्चित करते; " +#~ "शांत 'बीप' करीता परवानगी देण्यास दृश्यात्मक घंटाशी संयुक्तपणे वापरले जाऊ शकते." + +#~ msgid "Disable misfeatures that are required by old or broken applications" +#~ msgstr "जुन्या व टाकाऊ कार्यक्रम आवश्यक अयोग्य गुणधर्म अकार्यक्षम करा" + +#~ msgid "Enable Visual Bell" +#~ msgstr "दृश्य घंटा सक्षम करा" + +#~ msgid "" +#~ "If true, ignore the titlebar_font option, and use the standard " +#~ "application font for window titles." +#~ msgstr "" +#~ "खरे असल्यास, शिर्षकपट्टी_फॉन्ट पर्याय दुर्लक्ष करा, व चौकट शिर्षक करीता मानक " +#~ "अनुप्रयोग फॉन्ट वापरा." + +#~ msgid "" +#~ "If true, metacity will give the user less feedback by using wireframes, " +#~ "avoiding animations, or other means. This is a significant reduction in " +#~ "usability for many users, but may allow legacy applications to continue " +#~ "working, and may also be a useful tradeoff for terminal servers. However, " +#~ "the wireframe feature is disabled when accessibility is on." +#~ msgstr "" +#~ "खरे असल्यास, मेटासिटी वापरकर्त्यास वायरफ्रेम, चित्रचेतनीकरण दुर्लक्ष करून, किंवा अन्य " +#~ "कुठल्याही तऱ्हेचा वापर करून कमी प्रतिसाद देते. हे बहुदा वापरकर्त्यास वापरणीच्या " +#~ "दृष्टीकोणातून महत्वाचे नाही, पण कार्यरत राहण्याकरीता लेगसी अनुप्रोयागला परवानगी देऊ " +#~ "शकते, व टर्मिनल सर्वर करीता उपयोगी ठरू शकते. तरी, प्रवेश सुरू असल्यास वायरफ्रेम " +#~ "वैशिष्ट्ये अकार्यान्वीत केले जाते." + +#~ msgid "" +#~ "If true, then Metacity works in terms of applications rather than " +#~ "windows. The concept is a bit abstract, but in general an application-" +#~ "based setup is more like the Mac and less like Windows. When you focus a " +#~ "window in application-based mode, all the windows in the application will " +#~ "be raised. Also, in application-based mode, focus clicks are not passed " +#~ "through to windows in other applications. Application-based mode is, " +#~ "however, largely unimplemented at the moment." +#~ msgstr "" +#~ "खरे असल्यास, मेटासिटी अनुप्रयोग एवजी चौकट स्वरूपात कार्य करतो. ही पध्दत वेगळी आहे, " +#~ "पण अनुप्रयोग-आधारीत संयोजना Mac सारखे जास्त व Windows सारखे कमी आहे. अनुप्रयोग-" +#~ "आधारीत पध्दती मध्ये चौकट केंद्रीत करत असल्यास, अनुप्रयोगातील सर्व चौकट वाढविले " +#~ "जातील. तरी, अनुप्रयोग-आधारीत पध्दतीमध्ये, इतर अनुप्रयोग मध्ये लक्ष्यकेंद्र किल्क " +#~ "स्थानांतरीत केले जात नाही. अनुप्रयोग-आधारीत पध्दती, याक्षणी तरी कार्यरत केले गेले नाही." + +#~ msgid "If true, trade off usability for less resource usage" +#~ msgstr "ट्रेड ऑफ वापरला कमी साधन वापरली, जर बरोबर" + +#~ msgid "Name of workspace" +#~ msgstr "कार्यक्षेत्राचे नाव" + +#~ msgid "Number of workspaces" +#~ msgstr "कार्यक्षेत्रांची संख्या" + +#~ msgid "" +#~ "Number of workspaces. Must be more than zero, and has a fixed maximum to " +#~ "prevent making the desktop unusable by accidentally asking for too many " +#~ "workspaces." +#~ msgstr "" +#~ "कार्यक्षेत्रांची संख्या. शून्यपेक्षा जास्त असायला हवे, व डेस्कटॉपला पुष्कळ कार्यक्षेत्र " +#~ "वापरण्यापासून प्रतिबंधित करण्याकरीता कमाल संख्या देखिल स्थापित केली जाते." + +#~ msgid "Run a defined command" +#~ msgstr "परिभाषीत आदेश चालवा" + +#~ msgid "" +#~ "Set this to true to resize with the right button and show a menu with the " +#~ "middle button while holding down the key given in \"mouse_button_modifier" +#~ "\"; set it to false to make it work the opposite way around." +#~ msgstr "" +#~ "उजव्या बटणाशी पुन्ह आकार करण्यासाठी true निश्चित करा व \"mouse_button_modifier" +#~ "\" अंतर्गत कि दाबून ठेवून मध्य बटण द्वारे मेन्यू दाखवा; false निश्चित केल्यास विरूद्ध नुरूप " +#~ "कार्य करतो." + +#~ msgid "" +#~ "Setting this option to false can lead to buggy behavior, so users are " +#~ "strongly discouraged from changing it from the default of true. Many " +#~ "actions (e.g. clicking in the client area, moving or resizing the window) " +#~ "normally raise the window as a side-effect. Setting this option to false, " +#~ "which is strongly discouraged, will decouple raising from other user " +#~ "actions, and ignore raise requests generated by applications. See http://" +#~ "bugzilla.gnome.org/show_bug.cgi?id=445447#c6. Even when this option is " +#~ "false, windows can still be raised by an alt-left-click anywhere on the " +#~ "window, a normal click on the window decorations, or by special messages " +#~ "from pagers, such as activation requests from tasklist applets. This " +#~ "option is currently disabled in click-to-focus mode. Note that the list " +#~ "of ways to raise windows when raise_on_click is false does not include " +#~ "programmatic requests from applications to raise windows; such requests " +#~ "will be ignored regardless of the reason for the request. If you are an " +#~ "application developer and have a user complaining that your application " +#~ "does not work with this setting disabled, tell them it is _their_ fault " +#~ "for breaking their window manager and that they need to change this " +#~ "option back to true or live with the \"bug\" they requested." +#~ msgstr "" +#~ "Setting this option to false can lead to buggy behavior, so users are " +#~ "strongly discouraged from changing it from the default of true. Many " +#~ "actions (e.g. clicking in the client area, moving or resizing the window) " +#~ "normally raise the window as a side-effect. Setting this option to false, " +#~ "which is strongly discouraged, will decouple raising from other user " +#~ "actions, and ignore raise requests generated by applications. See http://" +#~ "bugzilla.gnome.org/show_bug.cgi?id=445447#c6. Even when this option is " +#~ "false, windows can still be raised by an alt-left-click anywhere on the " +#~ "window, a normal click on the window decorations, or by special messages " +#~ "from pagers, such as activation requests from tasklist applets. This " +#~ "option is currently disabled in click-to-focus mode. Note that the list " +#~ "of ways to raise windows when raise_on_click is false does not include " +#~ "programmatic requests from applications to raise windows; such requests " +#~ "will be ignored regardless of the reason for the request. If you are an " +#~ "application developer and have a user complaining that your application " +#~ "does not work with this setting disabled, tell them it is _their_ fault " +#~ "for breaking their window manager and that they need to change this " +#~ "option back to true or live with the \"bug\" they requested." + +#~ msgid "" +#~ "Some applications disregard specifications in ways that result in window " +#~ "manager misfeatures. This option puts Metacity in a rigorously correct " +#~ "mode, which gives a more consistent user interface, provided one does not " +#~ "need to run any misbehaving applications." +#~ msgstr "" +#~ "काहीक अनुप्रयोग संयोजनाचे उल्लंगन करते ज्यामुळे चौकट व्यवस्थापकचे वैशिष्ट्ये सदोषीत होते. " +#~ "या पर्याय Metacity ला योग्य पध्तीत कार्यरत करतो, ज्यामुळे सुस्थित वापरकर्ता संवाद " +#~ "प्राप्त होते, व त्याकरीता एवढीच अट अशी आहे की त्याक्षणी असुसंगती अनुप्रयोग चालवायचे " +#~ "नाही." + +#~ msgid "System Bell is Audible" +#~ msgstr "प्रणाली घंटा एकू येण्याजोगी आहे" + +#~ msgid "" +#~ "Tells Metacity how to implement the visual indication that the system " +#~ "bell or another application 'bell' indicator has been rung. Currently " +#~ "there are two valid values, \"fullscreen\", which causes a fullscreen " +#~ "white-black flash, and \"frame_flash\" which causes the titlebar of the " +#~ "application which sent the bell signal to flash. If the application which " +#~ "sent the bell is unknown (as is usually the case for the default \"system " +#~ "beep\"), the currently focused window's titlebar is flashed." +#~ msgstr "" +#~ "प्रणाली घंटा किंवा अन्य अनुप्रयोगाची 'घंटा' वाजविली अल्यास दृश्नीय सूचक कसे कार्यरत " +#~ "करायचे ते Metacity ला कळविते. सद्या दोन वैध मुल्य, \"पूर्णपडदा\", ज्यामुळे पूर्णपडदा " +#~ "पांढरे-काळे असे दिसून पडते, व \"फेम_फ्लॅश\" ज्यामुळे अनुप्रयोगची शिर्षकपट्टी दिसण्यास सुरू " +#~ "होते. ज्या अनुप्रयोगने संकेत पाठविले ते अपरिचीत असल्यास (जे मुलभूत \"प्रणाली बीप\" " +#~ "करीता स्वरूप आहे), सद्याचे केंद्रीत चौकटाचे शिर्षकपट्टी दिसते." + +#~ msgid "" +#~ "The /apps/metacity/global_keybindings/run_command_N keys define " +#~ "keybindings that correspond to these commands. Pressing the keybinding " +#~ "for run_command_N will execute command_N." +#~ msgstr "" +#~ "/apps/metacity/global_keybindings/run_command_N किल्ली keybinding निश्चित " +#~ "करते जे या आदेशशी परस्पर आहे. कळबांधणी run_command_N करीता दाबल्यास command_N " +#~ "कार्यान्वीत होईल." + +#~ msgid "" +#~ "The /apps/metacity/global_keybindings/run_command_screenshot key defines " +#~ "a keybinding which causes the command specified by this setting to be " +#~ "invoked." +#~ msgstr "" +#~ "/apps/metacity/global_keybindings/run_command_screenshot किल्ली keybinding " +#~ "निश्चित करते जे या संयोजना द्वारे निश्चित आदेशला सुरू करते." + +#~ msgid "" +#~ "The /apps/metacity/global_keybindings/run_command_window_screenshot key " +#~ "defines a keybinding which causes the command specified by this setting " +#~ "to be invoked." +#~ msgstr "" +#~ "/apps/metacity/global_keybindings/run_command_window_screenshot किल्ली " +#~ "keybinding निश्चित करते जे या संयोजना द्वारे निश्चित आदेशला सुरू करते." + +#~ msgid "" +#~ "The keybinding that runs the correspondingly-numbered command in /apps/" +#~ "metacity/keybinding_commands The format looks like \"<Control>a\" " +#~ "or \"<Shift><Alt>F1\". The parser is fairly liberal and " +#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" +#~ "\" and \"<Ctrl>\". If you set the option to the special string " +#~ "\"disabled\", then there will be no keybinding for this action." +#~ msgstr "" +#~ "keybinding जे /apps/metacity/keybinding_commands मधिल परस्पर-क्रमांकीत आदेश " +#~ "चालवितो. स्वरूप खालिल प्रमाणे दिसते \"<Control>a\" किंवा \"<Shift>" +#~ "<Alt>F1\". पार्सर सुलभ आहे व लहान किंवा मोठ्या आकाराचे अक्षरास, व \"<" +#~ "Ctl>\" किंवा \"<Ctrl>\" सारखे संक्षिप्त रूप करीता परवानगी देते. विशेष " +#~ "अक्षरमाळा करीता पर्याय \"अकार्यान्वीत\" असे निश्चित केल्यास, या कृती करीता " +#~ "keybinding स्थापीत केले जाऊ शकणार नाही." + +#~ msgid "The name of a workspace." +#~ msgstr "कार्यक्षेत्राचे नाव." + +#~ msgid "The screenshot command" +#~ msgstr "पडद्यांच्या फोटोंची आदेश" + +#~ msgid "" +#~ "The theme determines the appearance of window borders, titlebar, and so " +#~ "forth." +#~ msgstr "चौकटची सीमा, शिर्षकपट्टी, व याच तऱ्हने पुढे सुत्रयोजना निश्चित करतो." + +#~ msgid "" +#~ "The time delay before raising a window if auto_raise is set to true. The " +#~ "delay is given in thousandths of a second." +#~ msgstr "" +#~ "स्वः_वाढ खरे निश्चित केल्यास होणारा वेळेतील उशीर . या उशीर सेकंदाच्या हजाराव्या अंशात " +#~ "प्रविष्ट केले जाते." + +#~ msgid "" +#~ "The window focus mode indicates how windows are activated. It has three " +#~ "possible values; \"click\" means windows must be clicked in order to " +#~ "focus them, \"sloppy\" means windows are focused when the mouse enters " +#~ "the window, and \"mouse\" means windows are focused when the mouse enters " +#~ "the window and unfocused when the mouse leaves the window." +#~ msgstr "" +#~ "पध्दती चौकट कसे सक्रीय करायचे याचे सूचक चौकट लक्ष्यकेंद्र पध्दती आहे. याचे तीन संभाव्य " +#~ "मुल्य आहे; \"क्लिक\" म्हणजे लक्षकेंद्र करण्याकरीता चौकटवर क्लिक केले पाहिजे, \"गचाळ\" " +#~ "म्हणजे जेव्हा माउस चौकट मध्ये प्रवेश करतो तेव्हा चौकट लक्ष्यकेंद्रीत केले जाते व \"माउस\" " +#~ "म्हणजे जेव्हा माउस चौकटीत प्रवेश करतो तेव्हा चौकट लक्ष्यकेंद्रीत केले जाते व जेव्हा माउस " +#~ "चौकटीत प्रवेश करत नाही तेव्हा चौकट लक्ष्यकेंद्रीत केले जात नाही." + +#~ msgid "The window screenshot command" +#~ msgstr "चौकटच्या पडदा फोटोंची आदेश" + +#~| msgid "" +#~| "This option determines the effects of double-clicking on the title bar. " +#~| "Current valid options are 'toggle_shade', which will shade/unshade the " +#~| "window, 'toggle_maximize' which will maximize/unmaximize the window, " +#~| "'minimize' which will minimize the window, and 'none' which will not do " +#~| "anything." +#~ msgid "" +#~ "This option determines the effects of double-clicking on the title bar. " +#~ "Current valid options are 'toggle_shade', which will shade/unshade the " +#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " +#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " +#~ "will maximize/unmaximize the window in that direction only, 'minimize' " +#~ "which will minimize the window, 'shade' which will roll the window up, " +#~ "'menu' which will display the window menu, 'lower' which will put the " +#~ "window behind all the others, and 'none' which will not do anything." +#~ msgstr "" +#~ "या पर्याय शिर्षक पट्टीवर दुय्यम-क्लिकचा प्रभाव निश्चित करतो. वर्तमान वैध पर्याय " +#~ "खालिल प्रमाणे आहे 'toggle_shade', जे खिडकीला छटा देईल/छटा देणे अशक्य करेल, " +#~ "'toggle_maximize' जे खिडकीला मोठे करेल/नाही, 'toggle_maximize_horizontally' " +#~ "व 'toggle_maximize_vertically' जे खिडकीला फक्त त्याच दिशेत मोठे/मोठे अशक्य करेल, " +#~ "'minimize' जे खिडकीला लहान करेल, 'छटा' जे खिडकीला वर रोल करते, 'menu' जे खिडकी " +#~ "मेन्यू दाखवते, 'lower' जे खिडकीला इतर खिडकींच्या पार्श्वभूमीत स्थायीत करते, व 'काहीच " +#~ "नाही' जे काहीच करणार नाही." + +#~| msgid "" +#~| "This option determines the effects of middle-clicking on the title bar. " +#~| "Current valid options are 'toggle_shade', which will shade/unshade the " +#~| "window, 'toggle_maximize' which will maximize/unmaximize the window, " +#~| "'minimize' which will minimize the window, and 'none' which will not do " +#~| "anything." +#~ msgid "" +#~ "This option determines the effects of middle-clicking on the title bar. " +#~ "Current valid options are 'toggle_shade', which will shade/unshade the " +#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " +#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " +#~ "will maximize/unmaximize the window in that direction only, 'minimize' " +#~ "which will minimize the window, 'shade' which will roll the window up, " +#~ "'menu' which will display the window menu, 'lower' which will put the " +#~ "window behind all the others, and 'none' which will not do anything." +#~ msgstr "" +#~ "या पर्याय शिर्षक पट्टीवर मध्य-क्लिक दिल्यानंतर प्रभाव निश्चित करतो. वर्तमान वैध " +#~ "पर्याय खालिल प्रमाणे आहे 'toggle_shade', जे खिडकीला छटा देईल/छटा देणे अशक्य करेल, " +#~ "'toggle_maximize' जे खिडकीला मोठे करेल/नाही, 'toggle_maximize_horizontally' " +#~ "व 'toggle_maximize_vertically' जे खिडकीला फक्त त्याच दिशेत मोठे/मोठे अशक्य करेल, " +#~ "'minimize' जे खिडकीला लहान करेल, 'छटा' जे खिडकीला वर रोल करते, 'menu' जे खिडकी " +#~ "मेन्यू दाखवते, 'lower' जे खिडकीला इतर खिडकींच्या पार्श्वभूमीत स्थायीत करते, व 'काहीच " +#~ "नाही' जे काहीच करणार नाही." + +#~| msgid "" +#~| "This option determines the effects of right-clicking on the title bar. " +#~| "Current valid options are 'toggle_shade', which will shade/unshade the " +#~| "window, 'toggle_maximize' which will maximize/unmaximize the window, " +#~| "'minimize' which will minimize the window, and 'none' which will not do " +#~| "anything." +#~ msgid "" +#~ "This option determines the effects of right-clicking on the title bar. " +#~ "Current valid options are 'toggle_shade', which will shade/unshade the " +#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " +#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " +#~ "will maximize/unmaximize the window in that direction only, 'minimize' " +#~ "which will minimize the window, 'shade' which will roll the window up, " +#~ "'menu' which will display the window menu, 'lower' which will put the " +#~ "window behind all the others, and 'none' which will not do anything." +#~ msgstr "" +#~ "या पर्याय शिर्षक पट्टीवर उजवी-क्लिक दिल्यानंतर प्रभाव निश्चित करतो. वर्तमान वैध " +#~ "पर्याय खालिल प्रमाणे आहे 'toggle_shade', जे खिडकीला छटा देईल/छटा देणे अशक्य करेल, " +#~ "'toggle_maximize' जे खिडकीला मोठे करेल/नाही, 'toggle_maximize_horizontally' " +#~ "व 'toggle_maximize_vertically' जे खिडकीला फक्त त्याच दिशेत मोठे/मोठे अशक्य करेल, " +#~ "'minimize' जे खिडकीला लहान करेल, 'छटा' जे खिडकीला वर रोल करते, 'menu' जे खिडकी " +#~ "मेन्यू दाखवते, 'lower' जे खिडकीला इतर खिडकींच्या पार्श्वभूमीत स्थायीत करते, व 'काहीच " +#~ "नाही' जे काहीच करणार नाही." + +#~ msgid "" +#~ "This option provides additional control over how newly created windows " +#~ "get focus. It has two possible values; \"smart\" applies the user's " +#~ "normal focus mode, and \"strict\" results in windows started from a " +#~ "terminal not being given focus." +#~ msgstr "" +#~ "या पर्याय नविन नर्मित चौकटी करीता लक्ष्यकेंद्र कसे प्राप्त होते या करीता अगाऊ नियंत्रण " +#~ "पुरवितो. दोन संभाव्य मुल्य आहेत; \"smart\" म्हणजे वापरकर्त्याचे साधारण लक्ष्यकेंद्र " +#~ "पध्दती, व \"strict\" म्हणजे टर्मिनल पासून सुरू होणारे चौकटी ज्यास लक्ष्यकेंद्र देऊ शकत " +#~ "नाही." + +#~ msgid "" +#~ "Turns on a visual indication when an application or the system issues a " +#~ "'bell' or 'beep'; useful for the hard-of-hearing and for use in noisy " +#~ "environments." +#~ msgstr "" +#~ "प्रणाली घंटा किंवा अन्य अनुप्रयोगाची 'घंटा' किंवा 'बीप' वाजविली अल्यास दृश्नीय सूचक " +#~ "चालू करा; जे एकण्यास कठिण जाणाऱ्यांना व जास्त आवाज वातवरणात फारच उपयोगी ठरू शकते." + +#~ msgid "Use standard system font in window titles" +#~ msgstr "चौकट शिर्षकाकरिता नेहमीची प्रणाली फॉन्ट वापरा" + +#~ msgid "Visual Bell Type" +#~ msgstr "दृश्य बेल प्रकार" + +#~ msgid "Whether raising should be a side-effect of other user interactions" +#~ msgstr "अन्य वापरकर्त्याशी परस्पर संवाद अप्रत्यक्ष परिणाम असायला हवे का" + +#~ msgid "Whether to resize with the right button" +#~ msgstr "उजव्या बटणसह पुन्हआकार करायचे" + +#~ msgid "Window focus mode" +#~ msgstr "चौकट फोकस पध्दत" + +#~ msgid "Window title font" +#~ msgstr "चौकट शिर्षक लिपी" + +#~ msgid "Close Window" +#~ msgstr "चौकट बंद करा" + +#~ msgid "Window Menu" +#~ msgstr "चौकट मेनू" + +#~ msgid "Minimize Window" +#~ msgstr "चौकट लहान करा" + +#~ msgid "Maximize Window" +#~ msgstr "चौकट मोठ्यात मोठी करा" + +#~| msgid "Resize window" +#~ msgid "Restore Window" +#~ msgstr "खिडकी पूर्वस्थितीत आणा" + +#~ msgid "Roll Up Window" +#~ msgstr "चौकट गुंडाळा" + +#~ msgid "Unroll Window" +#~ msgstr "चौकट गुंडाळा" + +#~ msgid "Keep Window On Top" +#~ msgstr "चौकट वर दर्शवा" + +#~ msgid "Always On Visible Workspace" +#~ msgstr "नेहमी दिसण्याजोगी कार्यक्षेत्रावर दर्शवा" + +#~ msgid "Put Window On Only One Workspace" +#~ msgstr "चौकट फक्त एका कार्यक्षेत्रावर दर्शवा" + +#~ msgid "Title" +#~ msgstr "शिर्षक" + +#~ msgid "Class" +#~ msgstr "वर्ग" + +#~ msgid "" +#~ "There was an error running \"%s\":\n" +#~ "%s." +#~ msgstr "" +#~ "चालवताना त्रुटी होती \"%s\":\n" +#~ "%s." + +#~ msgid "<author> specified twice for this theme" +#~ msgstr "ह्या संकल्पनैकरिता <लेखक> दोनदा ठरवून देण्यात आले" + +#~ msgid "<copyright> specified twice for this theme" +#~ msgstr "ह्या संकल्पनेकरिता <प्रतहक्क> दोनदा ठरवून देण्यात आले" + +#~ msgid "<date> specified twice for this theme" +#~ msgstr "ह्या संकल्पनेकरिता <दिनांक> दोनदा ठरवून देण्यात आले" + +#~ msgid "<description> specified twice for this theme" +#~ msgstr "ह्या संकल्पनेकरिता <वर्णन> दोनदा ठरवून देण्यात आले" + +#~ msgid "Theme file %s did not contain a root <metacity_theme> element" +#~ msgstr "सुत्रयोजना फाइलमध्ये %s मूळ गुणधर्म <मेटॅसिटी_सुत्रयोजना> अस्तित्वात नाही" + +#~ msgid "/Windows/tearoff" +#~ msgstr "/खिडक्या/टिअरऑफ" + +#~ msgid "/Windows/_Dialog" +#~ msgstr "/खिडक्या/संवाद(_D)" + +#~ msgid "/Windows/_Modal dialog" +#~ msgstr "/खिडक्या/मोडल संवाद(_M)" +#~ msgid "/Windows/Des_ktop" +#~ msgstr "/खिडक्या/कार्यक्षेत्र(_k)" diff --git a/po/ms.po b/po/ms.po index 2aa7383bf..65b9ade24 100644 --- a/po/ms.po +++ b/po/ms.po @@ -5,2750 +5,1798 @@ msgid "" msgstr "" "Project-Id-Version: Metacity 2.3.x\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2005-09-19 12:30+0200\n" -"PO-Revision-Date: 2004-01-16 23:12+0730\n" -"Last-Translator: Hasbullah Bin Pit <sebol@ikhlas.com>\n" -"Language-Team: Projek Gabai (Bahasa Melayu) <gabai-penyumbang@lists." -"sourceforge.net>\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2020-01-24 16:29+0000\n" +"PO-Revision-Date: 2020-01-27 03:54+0800\n" +"Last-Translator: abuyop <abuyop@gmail.com>\n" +"Language-Team: Pasukan Terjemahan GNOME Malaysia\n" +"Language: ms\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Poedit 2.0.6\n" -#: ../src/tools/metacity-message.c:150 -#, c-format -msgid "Usage: %s\n" -msgstr "Penggunaan: %s\n" - -#: ../src/tools/metacity-message.c:176 ../src/util.c:128 -msgid "Metacity was compiled without support for verbose mode\n" -msgstr "Metacity telah dikompil tanpa sokongan mod verbose\n" - -#: ../src/delete.c:63 ../src/delete.c:90 ../src/metacity-dialog.c:70 -#: ../src/theme-parser.c:467 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "Tak dapat menghantar \"%s\" sebagai integer" - -#: ../src/delete.c:70 ../src/delete.c:97 ../src/metacity-dialog.c:77 -#: ../src/theme-parser.c:476 ../src/theme-parser.c:530 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "Tidak memahami aksara berikut \"%s\" pada rentetan \"%s\"" - -#: ../src/delete.c:128 -#, c-format -msgid "Failed to parse message \"%s\" from dialog process\n" -msgstr "Gagal menghantar mesej \"%s\" dari proses dialog\n" - -#: ../src/delete.c:263 -#, c-format -msgid "Error reading from dialog display process: %s\n" -msgstr "Ralat membaca dari proses paparan dialog: %s\n" - -#: ../src/delete.c:344 -#, c-format -msgid "" -"Error launching metacity-dialog to ask about killing an application: %s\n" -msgstr "" -"Ralat melancarkan dialog-metacity untuk tanya tentang pembunuhan satu " -"aplikasi: %s\n" - -#: ../src/delete.c:452 -#, c-format -msgid "Failed to get hostname: %s\n" -msgstr "Gagal mendapatkan namahos:: %s\n" - -#: ../src/display.c:319 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Gagal membuka paparan %s Sistem X Window\n" - -#: ../src/errors.c:231 -#, c-format -msgid "" -"Lost connection to the display '%s';\n" -"most likely the X server was shut down or you killed/destroyed\n" -"the window manager.\n" -msgstr "" -"Hilang sambungan ke paparan '%s';\n" -"agaknya pelayan X telah dimatikan atau anda telah membunuh\n" -"pengurus tetingkap.\n" - -#: ../src/errors.c:238 -#, c-format -msgid "Fatal IO error %d (%s) on display '%s'.\n" -msgstr "Ralat IO fatal %d (%s) pada paparan '%s'.\n" - -#: ../src/frames.c:1125 -msgid "Close Window" -msgstr "Tutup Tetingkap" - -#: ../src/frames.c:1128 -msgid "Window Menu" -msgstr "Menu Tetingkap" - -#: ../src/frames.c:1131 -msgid "Minimize Window" -msgstr "Miniatur Tetingkap" - -#: ../src/frames.c:1134 -msgid "Maximize Window" -msgstr "Maksimum tetingkap" - -#: ../src/frames.c:1137 -msgid "Unmaximize Window" -msgstr "Nyah Maksimum Tetingkap" - -# modifier=? binding=? -#: ../src/keybindings.c:994 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "" -"Terdapat program lain yang sudah menggunakan kekukci %s dengan modifier %x " -"sebagai binding\n" - -#: ../src/keybindings.c:2620 -#, c-format -msgid "Error launching metacity-dialog to print an error about a command: %s\n" -msgstr "" -"Ralat melancarkan dialog-metacity untuk mencetak ralat tentang arahan: %s\n" - -#: ../src/keybindings.c:2725 -#, c-format -msgid "No command %d has been defined.\n" -msgstr "Tiada arahan %d ditakrifkan.\n" - -#: ../src/keybindings.c:3570 -#, fuzzy -msgid "No terminal command has been defined.\n" -msgstr "Tiada arahan %d ditakrifkan.\n" - -#: ../src/main.c:69 -#, c-format -msgid "" -"metacity %s\n" -"Copyright (C) 2001-2002 Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Navigasi" -#: ../src/main.c:257 -msgid "Disable connection to session manager" -msgstr "" - -#: ../src/main.c:263 -msgid "Replace the running window manager with Metacity" -msgstr "" - -#: ../src/main.c:269 -msgid "Specify session management ID" -msgstr "" - -#: ../src/main.c:274 -msgid "X Display to use" -msgstr "" - -#: ../src/main.c:280 -msgid "Initialize session from savefile" -msgstr "" - -#: ../src/main.c:286 -msgid "Print version" -msgstr "" - -#: ../src/main.c:440 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Gagal mengimbas direktori tema: %s\n" - -#: ../src/main.c:456 -#, c-format -msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes." -msgstr "" -"Tak dapat menjumpai tema! pastikan %s wujud dan mengandungi tema biasa." - -#: ../src/main.c:518 -#, c-format -msgid "Failed to restart: %s\n" -msgstr "Gagal mengulanghidupkan: %s\n" - -#: ../src/menu.c:54 -msgid "Mi_nimize" -msgstr "Mi_nimum" - -#: ../src/menu.c:55 -msgid "Ma_ximize" -msgstr "Ma_ksimum" - -#: ../src/menu.c:56 -msgid "Unma_ximize" -msgstr "_Nyah maksimum" +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Alih tetingkap ke ruang kerja 1" -#: ../src/menu.c:57 -msgid "Roll _Up" -msgstr "_Gulung" +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Alih tetingkap ke ruang kerja 2" -#: ../src/menu.c:58 -msgid "_Unroll" -msgstr "_Bentang" +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Alih tetingkap ke ruang kerja 3" -#: ../src/menu.c:59 ../src/menu.c:60 -msgid "On _Top" -msgstr "Di _Atas" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Alih tetingkap ke ruang kerja 4" -#: ../src/menu.c:61 -msgid "_Move" -msgstr "_Alih" +#: data/50-mutter-navigation.xml:21 +#| msgid "Move window to workspace 1" +msgid "Move window to last workspace" +msgstr "Alih tetingkap ke ruang kerja terakhir" -#: ../src/menu.c:62 -msgid "_Resize" -msgstr "_Ubahsaiz" +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "Alih tetingkap satu ruang kerja ke atas" -#. separator -#: ../src/menu.c:64 -msgid "_Close" -msgstr "_Tutup" +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "Alih tetingkap satu ruang kerja ke bawah" -#. separator -#: ../src/menu.c:66 -#, fuzzy -msgid "_Always on Visible Workspace" -msgstr "_Ikon pada Ruangkerja ini" +#: data/50-mutter-navigation.xml:30 +#| msgid "Move window one workspace to the left" +msgid "Move window one monitor to the left" +msgstr "Alih tetingkap satu monitor sebelah kiri" -#: ../src/menu.c:67 -#, fuzzy -msgid "_Only on This Workspace" -msgstr "_Ikon pada Ruangkerja ini" +#: data/50-mutter-navigation.xml:33 +#| msgid "Move window one workspace to the right" +msgid "Move window one monitor to the right" +msgstr "Alih tetingkap satu monitor sebelah kanan" -#: ../src/menu.c:68 -msgid "Move to Workspace _Left" -msgstr "Pindah ke Ruangkerja Ki_ri" +#: data/50-mutter-navigation.xml:36 +#| msgid "Move window one workspace up" +msgid "Move window one monitor up" +msgstr "Alih tetingkap satu monitor sebelah atas" -#: ../src/menu.c:69 -msgid "Move to Workspace R_ight" -msgstr "Pindah ke Ruangkerja Ka_nan" +#: data/50-mutter-navigation.xml:39 +#| msgid "Move window one workspace down" +msgid "Move window one monitor down" +msgstr "Alih tetingkap satu monitor sebelah bawah" -#: ../src/menu.c:70 -msgid "Move to Workspace _Up" -msgstr "Pindah ke Ruangkerja _Atas" +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "Alih aplikasi" -#: ../src/menu.c:71 -msgid "Move to Workspace _Down" -msgstr "Pindah ke Ruangkerja Bawah" +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "Beralih ke aplikasi terdahulu" -#: ../src/menu.c:162 ../src/prefs.c:2106 -#, c-format -msgid "Workspace %d" -msgstr "Ruangkerja %d" +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "Alih tetingkap" -#: ../src/menu.c:171 -msgid "Workspace 1_0" -msgstr "Ruangkerja 1_0" +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "Beralioh ke tetingkap terdahulu" -#: ../src/menu.c:173 -#, c-format -msgid "Workspace %s%d" -msgstr "Ruangkerja %s%d" +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "Alih tetingkap sesebuah aplikasi" -#: ../src/menu.c:368 -msgid "Move to Another _Workspace" -msgstr "Pindah ke Ruangkerja lain" +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "Beralih ke tetingkap terdahulu bagi sesebuah aplikasi" -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:105 -msgid "Shift" -msgstr "Shif" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:111 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:117 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:123 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:129 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:135 -msgid "Hyper" -msgstr "Hiper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:141 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:147 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:153 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:159 -msgid "Mod5" -msgstr "Mod5" +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "Alih kawalan sistem" -#: ../src/metacity-dialog.c:110 -#, c-format -msgid "The window \"%s\" is not responding." -msgstr "Tetingkap \"%s\" tak bertindakbalas." +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "Beralih ke kawalan sistem terdahulu" -#: ../src/metacity-dialog.c:118 -msgid "" -"Forcing this application to quit will cause you to lose any unsaved changes." -msgstr "" -"Memaksa aplikasi ini keluar akan menyebabkan anda kehilangan sebarang " -"perubahan yg betul disimpan." +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "Alih tetingkap secara terus" -#: ../src/metacity-dialog.c:129 -msgid "_Force Quit" -msgstr "_Paksa keluar" +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "Beralih terus ke tetingkap terdahulu" -#: ../src/metacity-dialog.c:226 -msgid "Title" -msgstr "Tajuk" +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "Alih tetingkap satu aplikasi secara terus" -#: ../src/metacity-dialog.c:238 -msgid "Class" -msgstr "Kelas" +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "Beralih terus ke tetingkap terdahulu sesebuah aplikasi" -#: ../src/metacity-dialog.c:264 -msgid "" -"These windows do not support \"save current setup\" and will have to be " -"restarted manually next time you log in." -msgstr "" -"tetingkap ini tidak menyokong \"Simpan tetapan semasa\" dan akan " -"diulanghidupkan secara manual bila anda log masuk kelak." +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "Alih kawalan sistem secara terus" -#: ../src/metacity-dialog.c:330 -#, c-format -msgid "" -"There was an error running \"%s\":\n" -"%s." -msgstr "" -"Terdapat ralat melaksanakan \"%s\":\n" -"%s." +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "Beralih terus ke kawalan sistem terdahulu" -#: ../src/metacity.desktop.in.h:1 -msgid "Metacity" -msgstr "Metacity" +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "Sembunyi semua tetingkap biasa" -#: ../src/metacity.schemas.in.h:1 -msgid "(Not implemented) Navigation works in terms of applications not windows" -msgstr "Navigasi berkerja dari segi aplikasi bukannya tetingkap" +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "Beralih ke ruang kerja 1" -#: ../src/metacity.schemas.in.h:2 -msgid "" -"A font description string describing a font for window titlebars. The size " -"from the description will only be used if the titlebar_font_size option is " -"set to 0, however. Also, this option is disabled if the " -"titlebar_uses_desktop_font option is set to true. By default, titlebar_font " -"is unset, causing Metacity to fall back to the desktop font even if " -"titlebar_uses_desktop_font is false." -msgstr "" +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "Beralih ke ruang kerja 2" -#: ../src/metacity.schemas.in.h:3 -msgid "Action on title bar double-click" -msgstr "Aksi pada dwi-klik bar tajuk" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "Beralih ke ruang kerja 3" -#: ../src/metacity.schemas.in.h:4 -msgid "Activate window menu" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "Beralih ke ruang kerja 4" + +#: data/50-mutter-navigation.xml:120 +#| msgid "Switch to workspace 1" +msgid "Switch to last workspace" +msgstr "Beralih ke ruang kerja terakhir" + +#: data/50-mutter-navigation.xml:123 +#| msgid "Move to Workspace _Left" +msgid "Move to workspace above" +msgstr "Alih ke ruang kerja sebelah atas" + +#: data/50-mutter-navigation.xml:126 +#| msgid "Move to Workspace _Down" +msgid "Move to workspace below" +msgstr "Alih ke ruang kerja sebelah bawah" + +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "Sistem" + +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Tunjuk bisikan jalan perintah" + +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Tunjuk selayang pandang aktiviti" + +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Pulih pintasan papan kekunci" + +#: data/50-mutter-windows.xml:6 +#| msgid "/_Windows" +msgid "Windows" +msgstr "Tetingkap" + +#: data/50-mutter-windows.xml:8 +#| msgid "Activate window menu" +msgid "Activate the window menu" msgstr "Aktifkan menu tetingkap" -#: ../src/metacity.schemas.in.h:5 -msgid "Arrangement of buttons on the titlebar" -msgstr "Penyusunan butang pada bar tajuk" - -#: ../src/metacity.schemas.in.h:6 -msgid "" -"Arrangement of buttons on the titlebar. The value should be a string, such " -"as \"menu:minimize,maximize,close\"; the colon separates the left corner of " -"the window from the right corner, and the button names are comma-separated. " -"Duplicate buttons are not allowed. Unknown button names are silently ignored " -"so that buttons can be added in future metacity versions without breaking " -"older versions." -msgstr "" - -#: ../src/metacity.schemas.in.h:7 -msgid "Automatically raises the focused window" -msgstr "Automatik angkat bila tetingkap difokus" - -#: ../src/metacity.schemas.in.h:8 -msgid "" -"Clicking a window while holding down this modifier key will move the window " -"(left click), resize the window (middle click), or show the window menu " -"(right click). Modifier is expressed as \"<Alt>\" or \"<Super>\" " -"for example." -msgstr "" - -#: ../src/metacity.schemas.in.h:9 -#, fuzzy -msgid "Close window" -msgstr "Tutup Tetingkap" - -#: ../src/metacity.schemas.in.h:10 -msgid "Commands to run in response to keybindings" -msgstr "Arahan untuk dilaksana tindakbalas pengikatan kekunci" - -#: ../src/metacity.schemas.in.h:11 -msgid "Current theme" -msgstr "Tema semasa" - -#: ../src/metacity.schemas.in.h:12 -msgid "Delay in milliseconds for the auto raise option" -msgstr "Selangmasa dalam milisaat bagi opsyen auto angkat" - -#: ../src/metacity.schemas.in.h:13 -msgid "" -"Determines whether applications or the system can generate audible 'beeps'; " -"may be used in conjunction with 'visual bell' to allow silent 'beeps'." -msgstr "" - -#: ../src/metacity.schemas.in.h:14 -msgid "Disable misfeatures that are required by old or broken applications" -msgstr "" - -#: ../src/metacity.schemas.in.h:15 -msgid "Enable Visual Bell" -msgstr "Hidupkan Loceng Visual" - -#: ../src/metacity.schemas.in.h:16 -msgid "Hide all windows and focus desktop" -msgstr "Sembunyi semua tetingkap dan fokus desktop" - -#: ../src/metacity.schemas.in.h:17 -msgid "" -"If true, and the focus mode is either \"sloppy\" or \"mouse\" then the " -"focused window will be automatically raised after a delay (the delay is " -"specified by the auto_raise_delay key)." -msgstr "" - -#: ../src/metacity.schemas.in.h:18 -msgid "" -"If true, ignore the titlebar_font option, and use the standard application " -"font for window titles." -msgstr "" - -#: ../src/metacity.schemas.in.h:19 -msgid "" -"If true, metacity will give the user less feedback and less sense of " -"\"direct manipulation\", by using wireframes, avoiding animations, or other " -"means. This is a significant reduction in usability for many users, but may " -"allow legacy applications and terminal servers to function when they would " -"otherwise be impractical. However, the wireframe feature is disabled when " -"accessibility is on to avoid weird desktop breakages." -msgstr "" - -#: ../src/metacity.schemas.in.h:20 -msgid "" -"If true, then Metacity works in terms of applications rather than windows. " -"The concept is a bit abstract, but in general an application-based setup is " -"more like the Mac and less like Windows. When you focus a window in " -"application-based mode, all the windows in the application will be raised. " -"Also, in application-based mode, focus clicks are not passed through to " -"windows in other applications. The existence of this setting is somewhat " -"questionable. But it's better than having settings for all the specific " -"details of application-based vs. window-based, e.g. whether to pass through " -"clicks. Also, application-based mode is largely unimplemented at the moment." -msgstr "" - -#: ../src/metacity.schemas.in.h:21 -msgid "If true, trade off usability for less resource usage" -msgstr "" +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Togol mod skrin penuh" -#: ../src/metacity.schemas.in.h:22 -msgid "Lower window below other windows" -msgstr "Rendahkan tetingkap di bawah tetingkap lain" +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "Togol keadaan maksimum" -#: ../src/metacity.schemas.in.h:23 -#, fuzzy +#: data/50-mutter-windows.xml:14 msgid "Maximize window" msgstr "Maksimum tetingkap" -#: ../src/metacity.schemas.in.h:24 -msgid "Maximize window horizontally" -msgstr "Maksimumkan tetingkap mengufuk" - -#: ../src/metacity.schemas.in.h:25 -msgid "Maximize window vertically" -msgstr "Maksimumkan tetingkap menegak" - -#: ../src/metacity.schemas.in.h:26 -#, fuzzy -msgid "Minimize window" -msgstr "Miniatur tetingkap" - -#: ../src/metacity.schemas.in.h:27 -msgid "Modifier to use for modified window click actions" -msgstr "" +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Pulih tetingkap" -#: ../src/metacity.schemas.in.h:28 -msgid "Move backward between panels and the desktop immediately" -msgstr "Beralih ke belakang antara panel dan desktop serta merta" - -#: ../src/metacity.schemas.in.h:29 -msgid "Move backwards between panels and the desktop with popup" -msgstr "Beralih ke belakang antara panel dan desktop menggunakan popup" - -#: ../src/metacity.schemas.in.h:30 -msgid "Move backwards between windows immediately" -msgstr "Beralih kebelakang antara tetingkap serta merta" - -#: ../src/metacity.schemas.in.h:31 -msgid "Move between panels and the desktop immediately" -msgstr "Beralih antara panel dan desktop serta merta" - -#: ../src/metacity.schemas.in.h:32 -msgid "Move between panels and the desktop with popup" -msgstr "Beralih antara panel dan desktop menggunakan paparan popup" - -#: ../src/metacity.schemas.in.h:33 -msgid "Move between windows immediately" -msgstr "Beralih antara tetingkap serta merta" - -#: ../src/metacity.schemas.in.h:34 -msgid "Move between windows with popup" -msgstr "Beralih antara tetingkap menggunakan popup" +#: data/50-mutter-windows.xml:18 +msgid "Close window" +msgstr "Tutup tetingkap" -#: ../src/metacity.schemas.in.h:35 -msgid "Move focus backwards between windows using popup display" -msgstr "Alih fokus ke belakang antara tetingkap menggunakan paparan popup" +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "Sembunyi tetingkap" -#: ../src/metacity.schemas.in.h:36 -#, fuzzy +#: data/50-mutter-windows.xml:22 msgid "Move window" msgstr "Gerak tetingkap" -#: ../src/metacity.schemas.in.h:37 -msgid "Move window one workspace down" -msgstr "Pindah tetingkap satu ruangkerja ke bawah" - -#: ../src/metacity.schemas.in.h:38 -msgid "Move window one workspace to the left" -msgstr "Pindah tetingkap satu ruangkerja ke kiri" - -#: ../src/metacity.schemas.in.h:39 -msgid "Move window one workspace to the right" -msgstr "Pindah tetingkap satu ruangkerja ke kanan" - -#: ../src/metacity.schemas.in.h:40 -msgid "Move window one workspace up" -msgstr "Pindah tetingkap satu ruangkerja ke atas" - -#: ../src/metacity.schemas.in.h:41 -msgid "Move window to workspace 1" -msgstr "Pindah tetingkap ke ruangkerja 1" - -#: ../src/metacity.schemas.in.h:42 -msgid "Move window to workspace 10" -msgstr "Pindah tetingkap ke ruangkerja 10" - -#: ../src/metacity.schemas.in.h:43 -msgid "Move window to workspace 11" -msgstr "Pindah tetingkap ke ruangkerja 11" - -#: ../src/metacity.schemas.in.h:44 -msgid "Move window to workspace 12" -msgstr "Pindah tetingkap ke ruangkerja 12" - -#: ../src/metacity.schemas.in.h:45 -msgid "Move window to workspace 2" -msgstr "Pindah tetingkap ke ruangkerja 2" - -#: ../src/metacity.schemas.in.h:46 -msgid "Move window to workspace 3" -msgstr "Pindah tetingkap ke ruangkerja 3" - -#: ../src/metacity.schemas.in.h:47 -msgid "Move window to workspace 4" -msgstr "Pindah tetingkap ke ruangkerja 4" - -#: ../src/metacity.schemas.in.h:48 -msgid "Move window to workspace 5" -msgstr "Pindah tetingkap ke ruangkerja %s%d" - -#: ../src/metacity.schemas.in.h:49 -msgid "Move window to workspace 6" -msgstr "Pindah tetingkap ke ruangkerja 6" - -#: ../src/metacity.schemas.in.h:50 -msgid "Move window to workspace 7" -msgstr "Pindah tetingkap ke ruangkerja 7" - -#: ../src/metacity.schemas.in.h:51 -msgid "Move window to workspace 8" -msgstr "Pindah tetingkap ke ruangkerja 8" - -#: ../src/metacity.schemas.in.h:52 -msgid "Move window to workspace 9" -msgstr "Pindah tetingkap ke ruangkerja 9" - -#: ../src/metacity.schemas.in.h:53 -msgid "Name of workspace" -msgstr "Nama ruangkerja" - -#: ../src/metacity.schemas.in.h:54 -msgid "Number of workspaces" -msgstr "Bilangan ruangkerja" - -#: ../src/metacity.schemas.in.h:55 -msgid "" -"Number of workspaces. Must be more than zero, and has a fixed maximum (to " -"prevent accidentally destroying your desktop by asking for 34 million " -"workspaces)." -msgstr "" -"Bilangan ruangkerja. Mesti lebih daripada sifar, dan mempunyai bilangan " -"maksimum tetap (untuk mencegah pemusnahan desktop akibat daripada meminta 34 " -"juta ruangkerja)." - -#: ../src/metacity.schemas.in.h:56 -msgid "Raise obscured window, otherwise lower" -msgstr "Angkat tetingkap tersembunyi, yang lain diturunkan " - -#: ../src/metacity.schemas.in.h:57 -msgid "Raise window above other windows" -msgstr "Angkat tetingkap di atas tetingkap lain" - -#: ../src/metacity.schemas.in.h:58 -#, fuzzy +#: data/50-mutter-windows.xml:24 msgid "Resize window" -msgstr "Ubahsaiz tetingkap" - -#: ../src/metacity.schemas.in.h:59 -msgid "Run a defined command" -msgstr "Laksana arahan tertakrif" - -#: ../src/metacity.schemas.in.h:60 -msgid "Run a terminal" -msgstr "" - -#: ../src/metacity.schemas.in.h:61 -msgid "Show the panel menu" -msgstr "Papar menu panel" - -#: ../src/metacity.schemas.in.h:62 -#, fuzzy -msgid "Show the panel run application dialog" -msgstr "Papar dialog perlaksanaan panel" - -#: ../src/metacity.schemas.in.h:63 -msgid "" -"Some applications break specifications in ways that result in window manager " -"misfeatures. For example, ideally Metacity would place all dialogs in a " -"consistent position with respect to their parent window. This requires " -"ignoring application-specified positions for dialogs. But some versions of " -"Java/Swing mark their popup menus as dialogs, so Metacity has to disable " -"dialog positioning to allow menus to work in broken Java applications. There " -"are several other examples like this. This option puts Metacity in full-on " -"Correct mode, which perhaps gives a moderately nicer UI if you don't need to " -"run any broken apps. Sadly, workarounds must be enabled by default; the real " -"world is an ugly place. Some of the workarounds are workarounds for " -"limitations in the specifications themselves, so sometimes a bug in no-" -"workarounds mode won't be fixable without amending a spec." -msgstr "" - -#: ../src/metacity.schemas.in.h:64 -msgid "Switch to workspace 1" -msgstr "Bertukar ke ruangkerja 1" - -#: ../src/metacity.schemas.in.h:65 -msgid "Switch to workspace 10" -msgstr "Bertukar ke ruangkerja 10" - -#: ../src/metacity.schemas.in.h:66 -msgid "Switch to workspace 11" -msgstr "Bertukar ke ruangkerja 11" - -#: ../src/metacity.schemas.in.h:67 -msgid "Switch to workspace 12" -msgstr "Bertukar ke ruangkerja 12" - -#: ../src/metacity.schemas.in.h:68 -msgid "Switch to workspace 2" -msgstr "Bertukar ke ruangkerja 2" - -#: ../src/metacity.schemas.in.h:69 -msgid "Switch to workspace 3" -msgstr "Bertukar ke ruangkerja 3" - -#: ../src/metacity.schemas.in.h:70 -msgid "Switch to workspace 4" -msgstr "Bertukar ke ruangkerja 4" - -#: ../src/metacity.schemas.in.h:71 -msgid "Switch to workspace 5" -msgstr "Bertukar ke ruangkerja 5" - -#: ../src/metacity.schemas.in.h:72 -msgid "Switch to workspace 6" -msgstr "Bertukar ke ruangkerja 6" +msgstr "Saiz semula tetingkap" -#: ../src/metacity.schemas.in.h:73 -msgid "Switch to workspace 7" -msgstr "Bertukar ke ruangkerja 7" +#: data/50-mutter-windows.xml:27 +#| msgid "Toggle window on all workspaces" +msgid "Toggle window on all workspaces or one" +msgstr "Togol tetingkap pada semua ruang kerja atau satu" -#: ../src/metacity.schemas.in.h:74 -msgid "Switch to workspace 8" -msgstr "Bertukar ke ruangkerja 8" +#: data/50-mutter-windows.xml:29 +#| msgid "Raise obscured window, otherwise lower" +msgid "Raise window if covered, otherwise lower it" +msgstr "Naikkan tetingkap jika diliputi, jika tidak turunkannya" -#: ../src/metacity.schemas.in.h:75 -msgid "Switch to workspace 9" -msgstr "Bertukar ke ruangkerja 9" - -#: ../src/metacity.schemas.in.h:76 -msgid "Switch to workspace above this one" -msgstr "Bertukar ke ruangkerja di atas yang ini" - -#: ../src/metacity.schemas.in.h:77 -msgid "Switch to workspace below this one" -msgstr "Bertukar ke ruangkerja di bawah yang ini" - -#: ../src/metacity.schemas.in.h:78 -msgid "Switch to workspace on the left" -msgstr "Bertukar ke ruangkerja di sebelah kiri" - -#: ../src/metacity.schemas.in.h:79 -msgid "Switch to workspace on the right" -msgstr "Bertukar ke ruangkerja di sebelah kanan" - -#: ../src/metacity.schemas.in.h:80 -msgid "System Bell is Audible" -msgstr "Loceng Sistem boleh didengar" - -#: ../src/metacity.schemas.in.h:81 -msgid "Take a screenshot" -msgstr "Tangkap cekupanskrin" - -#: ../src/metacity.schemas.in.h:82 -msgid "Take a screenshot of a window" -msgstr "Ambil cekupan skrin tetingkap" - -#: ../src/metacity.schemas.in.h:83 -msgid "" -"Tells Metacity how to implement the visual indication that the system bell " -"or another application 'bell' indicator has been rung. Currently there are " -"two valid values, \"fullscreen\", which causes a fullscreen white-black " -"flash, and \"frame_flash\" which causes the titlebar of the application " -"which sent the bell signal to flash. If the application which sent the bell " -"is unknown (as is usually the case for the default \"system beep\"), the " -"currently focused window's titlebar is flashed." -msgstr "" - -#: ../src/metacity.schemas.in.h:84 -msgid "" -"The /apps/metacity/global_keybindings/run_command_N keys define keybindings " -"that correspond to these commands. Pressing the keybinding for run_command_N " -"will execute command_N." -msgstr "" -"Kekunci /apps/metacity/global_keybindings/run_command_N keys mentakrifkan " -"pengikatan kekunci yang merujuk kepada arahan ini. Menekan pengikatan " -"kekunci lanksana_arahan_N akan melaksanakan arahan_N will execute command_N." +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "Naikkan tetingkap di atas tetingkap lain" -#: ../src/metacity.schemas.in.h:85 -msgid "" -"The /apps/metacity/global_keybindings/run_command_screenshot key defines a " -"keybinding which causes the command specified by this setting to be invoked." -msgstr "" -"Kekunci /apps/metacity/global_keybindings/run_command_screenshot " -"mentakrifkan pengikatan kekunci yang menyebabkan arahan di nyatakan oleh " -"tetapan ini akan dipanggil" +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "Rendahkan tetingkap di bawah tetingkap lain" -#: ../src/metacity.schemas.in.h:86 -msgid "" -"The /apps/metacity/global_keybindings/run_command_window_screenshot key " -"defines a keybinding which causes the command specified by this setting to " -"be invoked." -msgstr "" -"Kekunci /apps/metacity/global_keybindings/run_command_window mentakrifkan " -"pengikatan kekunci yang menyebabkan arahan dinyatakan oleh tetapan ini akan " -"dilaksanakan." +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "Maksimumkan tetingkap secara menegak" -#: ../src/metacity.schemas.in.h:87 -msgid "" -"The keybinding that runs the correspondingly-numbered command in /apps/" -"metacity/keybinding_commands The format looks like \"<Control>a\" or " -"\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -"lower or upper case, and also abbreviations such as \"<Ctl>\" and " -"\"<Ctrl>\". If you set the option to the special string \"disabled\", " -"then there will be no keybinding for this action." -msgstr "" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "Maksimumkan tetingkap secara mengufuk" -#: ../src/metacity.schemas.in.h:88 -msgid "" -"The keybinding that switches to the workspace above the current workspace. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "Pisah pandangan di sebelah kiri" -#: ../src/metacity.schemas.in.h:89 -msgid "" -"The keybinding that switches to the workspace below the current workspace. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "Pisah pandangan di sebelah kanan" -#: ../src/metacity.schemas.in.h:90 -msgid "" -"The keybinding that switches to the workspace on the left of the current " -"workspace. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" -#: ../src/metacity.schemas.in.h:91 -msgid "" -"The keybinding that switches to the workspace on the right of the current " -"workspace. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" +#: data/org.gnome.mutter.gschema.xml.in:7 +msgid "Modifier to use for extended window management operations" +msgstr "Penerang yang digunakan untuk operasi pengurusan tetingkap lanjutan" -#: ../src/metacity.schemas.in.h:92 +#: data/org.gnome.mutter.gschema.xml.in:8 msgid "" -"The keybinding that switches to workspace 1. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." msgstr "" +"Kunci ini mengawalkan \"overlay\", iaitu satu gabungan selayang pandang " +"tetingkap dan sistem pelancaran aplikasi. Lalai dikhususkan pada \"Windows " +"key\" iaitu perkakasan PC. Dijangkakan pengikatan ini sama ada lalai atau " +"ditetapkan pada rentetan kosong." -#: ../src/metacity.schemas.in.h:93 -msgid "" -"The keybinding that switches to workspace 10. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: data/org.gnome.mutter.gschema.xml.in:20 +msgid "Attach modal dialogs" +msgstr "Lampir dialog modal" -#: ../src/metacity.schemas.in.h:94 +#: data/org.gnome.mutter.gschema.xml.in:21 msgid "" -"The keybinding that switches to workspace 11. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." msgstr "" +"Jika benar, selain dari mempunyai palang tajuk bebas, dialog modal muncul " +"bersama-sama dengan palang tajuk tetingkap induk dan bergerak bersama-sama " +"dengannya." -#: ../src/metacity.schemas.in.h:95 -msgid "" -"The keybinding that switches to workspace 12. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." +#: data/org.gnome.mutter.gschema.xml.in:30 +msgid "Enable edge tiling when dropping windows on screen edges" msgstr "" +"Benarkan penjubinan pinggir ketika melepaskan tetingkap pada pinggir skrin" -#: ../src/metacity.schemas.in.h:96 +#: data/org.gnome.mutter.gschema.xml.in:31 msgid "" -"The keybinding that switches to workspace 2. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." msgstr "" +"Jika dibenarkan, melepaskan tetingkap pada pinggir skrin menegak dapat " +"memaksimumkannya secara menegak dan saizkan semula mereka secara mengufuk " +"untuk meliputi separuh kawasan yang ada. Melepaskan tetingkap pada pinggir " +"skrin atas pula dapat memaksimumkan sepenuhnya." -#: ../src/metacity.schemas.in.h:97 -msgid "" -"The keybinding that switches to workspace 3. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: data/org.gnome.mutter.gschema.xml.in:40 +msgid "Workspaces are managed dynamically" +msgstr "Ruang kerja diurus secara dinamik" -#: ../src/metacity.schemas.in.h:98 +#: data/org.gnome.mutter.gschema.xml.in:41 msgid "" -"The keybinding that switches to workspace 4. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." +"Determines whether workspaces are managed dynamically or whether there’s a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." msgstr "" +"Tentukan sama ada ruang kerja diurus secara dinamik atau sama ada terdapat " +"bilangan ruang kerja statik (ditentukan oleh kunci num-workspaces key dalam " +"org.gnome.desktop.wm.preferences)." -#: ../src/metacity.schemas.in.h:99 -msgid "" -"The keybinding that switches to workspace 5. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: data/org.gnome.mutter.gschema.xml.in:50 +msgid "Workspaces only on primary" +msgstr "Ruang kerja hanya pada utama" -#: ../src/metacity.schemas.in.h:100 +#: data/org.gnome.mutter.gschema.xml.in:51 msgid "" -"The keybinding that switches to workspace 6. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." msgstr "" +"Tentukan sama ada pertukaran ruang kerja patut berlaku untuk tetingkap pada " +"semua monitor atau hanya untuk tetingkap pada monitor utama." -#: ../src/metacity.schemas.in.h:101 -msgid "" -"The keybinding that switches to workspace 7. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: data/org.gnome.mutter.gschema.xml.in:59 +msgid "No tab popup" +msgstr "Tiada tab timbul" -#: ../src/metacity.schemas.in.h:102 +#: data/org.gnome.mutter.gschema.xml.in:60 msgid "" -"The keybinding that switches to workspace 8. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." msgstr "" +"Tentukan sama ada pengguna timbul dan bingkai sorot patut dilumpuhkan untuk " +"kitaran tetingkap." -#: ../src/metacity.schemas.in.h:103 -msgid "" -"The keybinding that switches to workspace 9. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Lengah perubahan fokus sehinggalah penuding berhenti gerak" -#: ../src/metacity.schemas.in.h:104 +#: data/org.gnome.mutter.gschema.xml.in:69 msgid "" -"The keybinding used to activate the window menu. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." msgstr "" +"Jika ditetapkan pada benar, dan mod fokus sama ada sloppy” atau “mouse” maka " +"fokus tidak berubah serta-merta ketika memasuki tetingkap, tetapi selepas " +"penuding berhenti gerak." -#: ../src/metacity.schemas.in.h:105 -msgid "" -"The keybinding used to close a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: data/org.gnome.mutter.gschema.xml.in:79 +msgid "Draggable border width" +msgstr "Lebar sempadan boleh diseret" -#: ../src/metacity.schemas.in.h:106 +#: data/org.gnome.mutter.gschema.xml.in:80 msgid "" -"The keybinding used to enter \"move mode\" and begin moving a window using " -"the keyboard. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." +"The amount of total draggable borders. If the theme’s visible borders are " +"not enough, invisible borders will be added to meet this value." msgstr "" +"Amaun jumlah sempadan boleh diseret. Jika sempadan tampak tema tidak " +"mencukupi, sempadan halimunan akan ditambah untuk memenuhi nilai ini." -#: ../src/metacity.schemas.in.h:107 -msgid "" -"The keybinding used to enter \"resize mode\" and begin resizing a window " -"using the keyboard. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "Auto maksimum tetingkap bersaiz hampir dengan monitor" -#: ../src/metacity.schemas.in.h:108 +#: data/org.gnome.mutter.gschema.xml.in:90 msgid "" -"The keybinding used to hide all normal windows and set the focus to the " -"desktop background. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." msgstr "" +"Jika dibenarkan, tetingkap baharu yang awalnya bersaiz monitor akan " +"dimaksimumkan secara automatik." -#: ../src/metacity.schemas.in.h:109 -msgid "" -"The keybinding used to maximize a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Letak tetingkap baharu di tengah-tengah" -#: ../src/metacity.schemas.in.h:110 +#: data/org.gnome.mutter.gschema.xml.in:99 msgid "" -"The keybinding used to minimize a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." msgstr "" +"Jika benar, tetingkap baharu akan sentiasa berada ditengah-tengah skrin " +"aktif monitor." -#: ../src/metacity.schemas.in.h:111 +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Benarkan fitur-fitur eksperimental" + +#: data/org.gnome.mutter.gschema.xml.in:108 msgid "" -"The keybinding used to move a window one workspace down. The format looks " -"like \"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -"fairly liberal and allows lower or upper case, and also abbreviations such " -"as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -"special string \"disabled\", then there will be no keybinding for this " -"action." -msgstr "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes " +"mutter request a low priority real-time scheduling. The executable or user " +"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — " +"initializes Xwayland lazily if there are X11 clients. Requires restart." +msgstr "" +"Untuk membenarkan fitur-fitur eksperimental, tambah kata kunci fitur pada " +"senarai. Sama ada fitur perlu memulakan semula penggubah adalah bergantung " +"pada fitur yang diberi. Mana-mana fitur eksperimental tidak diperlukan untuk " +"tersedia, atau boleh dikonfigur. Jangan jangka dapat menambah apa-apa dalam " +"tetapan ini sebagai penambahbaikan akan datang. Kata kunci mungkin buat masa " +"ini: • “scale-monitor-framebuffer” — jadikan mutter lalai pada monitor " +"logikal bentangan dalam ruang koordinat piksel logikal, ketika mengskalakan " +"framebuffers monitor selain dari kandungan tetingkap, untuk mengurus monitor " +"HiDPI. Tidak perlu mula semula. • “rt-scheduler” — menjadikan mutter pinta " +"satu penjadualan masa-nyata berprioriti-rendah. Boleh laku atau pengguna " +"mesti ada CAP_SYS_NICE. Perlukan mula semula. • “autostart-xwayland” — " +"mengawalkan Xwayland secara malas jika terdapat klien X11. Perlu mula semula." + +#: data/org.gnome.mutter.gschema.xml.in:134 +msgid "Modifier to use to locate the pointer" +msgstr "Penerang digunakan untuk mencari penuding" + +#: data/org.gnome.mutter.gschema.xml.in:135 +msgid "This key will initiate the “locate pointer” action." +msgstr "Kunci ini akan mengawalkan tindakan “locate pointer”." + +#: data/org.gnome.mutter.gschema.xml.in:155 +#| msgid "Move between windows with popup" +msgid "Select window from tab popup" +msgstr "Pilih tetingkap dari timbul tab" + +#: data/org.gnome.mutter.gschema.xml.in:160 +msgid "Cancel tab popup" +msgstr "Batal timbul tab" + +#: data/org.gnome.mutter.gschema.xml.in:165 +msgid "Switch monitor configurations" +msgstr "Alih konfigurasi monitor" + +#: data/org.gnome.mutter.gschema.xml.in:170 +msgid "Rotates the built-in monitor configuration" +msgstr "Putarkan konfigurasi monitor terbina-dalam" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +#| msgid "Switch to workspace 1" +msgid "Switch to VT 1" +msgstr "Beralih ke VT 1" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +#| msgid "Switch to workspace 2" +msgid "Switch to VT 2" +msgstr "Beralih ke VT 2" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +#| msgid "Switch to workspace 3" +msgid "Switch to VT 3" +msgstr "Beralih ke VT 3" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +#| msgid "Switch to workspace 4" +msgid "Switch to VT 4" +msgstr "Beralih ke VT 4" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +#| msgid "Switch to workspace 5" +msgid "Switch to VT 5" +msgstr "Beralih ke VT 5" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +#| msgid "Switch to workspace 6" +msgid "Switch to VT 6" +msgstr "Beralih ke VT 6" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +#| msgid "Switch to workspace 7" +msgid "Switch to VT 7" +msgstr "Beralih ke VT 7" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +#| msgid "Switch to workspace 8" +msgid "Switch to VT 8" +msgstr "Beralih ke VT 8" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +#| msgid "Switch to workspace 9" +msgid "Switch to VT 9" +msgstr "Beralih ke VT 9" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +#| msgid "Switch to workspace 10" +msgid "Switch to VT 10" +msgstr "Beralih ke VT 10" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +#| msgid "Switch to workspace 11" +msgid "Switch to VT 11" +msgstr "Beralih ke VT 11" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +#| msgid "Switch to workspace 12" +msgid "Switch to VT 12" +msgstr "Beralih ke VT 12" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "Benarkan-semula pintasan" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow X11 grabs to lock keyboard focus with Xwayland" +msgstr "Benarkan cekau X11 untuk mengunci fokus papan kekunci dengan Xwayland" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 +msgid "" +"Allow all keyboard events to be routed to X11 “override redirect” windows " +"with a grab when running in Xwayland. This option is to support X11 clients " +"which map an “override redirect” window (which do not receive keyboard " +"focus) and issue a keyboard grab to force all keyboard events to that " +"window. This option is seldom used and has no effect on regular X11 windows " +"which can receive keyboard focus under normal circumstances. For a X11 grab " +"to be taken into account under Wayland, the client must also either send a " +"specific X11 ClientMessage to the root window or be among the applications " +"white-listed in key “xwayland-grab-access-rules”." +msgstr "" +"Benarkan semua peristiwa papan kekunci dihala ke tetingkap X11 “override " +"redirect” dengan satu cekau ketika dijalankan dalam Xwayland. Pilihan ini " +"adalah untuk menyokong klien X11 yang memetakan tetingkap “override " +"redirect” (yang tidak menerima fokus papan kekunci) dan mengeluarkan satu " +"cekau papan kekunci untuk paksa semua peristiwa papan kekunci pada tetingkap " +"tersebut. Pilihan ini jarang digunakan dan tiada kesan pada tetingkap X11 " +"biasa yang dapat menerima fokus papan kekunci di bawah situasi biasa. Untuk " +"satu cekau X11 yang diambil kira di bawah Wayland, klien juga mesti hantar " +"sama ada satu Mesej Klien X11 khusus pada tetingkap root atau berada dalam " +"aplikasi tersenarai-putih di dalam kunci “xwayland-grab-access-rules”." + +#: data/org.gnome.mutter.wayland.gschema.xml.in:84 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "Aplikasi Xwayland dibenarkan membuat cekau papan kekunci" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:85 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "" +"Senaraikan nama sumber atau kelas sumber bagi tetingkap X11 sama ada " +"dibenarkan atau tidak untuk mengeluarkan cekau papan kekunci X11 di bawah " +"Xwayland. Nama sumber atau kelassumber bagi tetingkap X11 yang diberi boleh " +"diperoleh menggunakan perintah WM_CLASS”. Kad liar “*” dan joker “?” di " +"dalam nilai adalah disokong. Nilai-nilai yang bermula dengan tanda “!” " +"adalah disenarai-hitam, yang mendahului senarai putih, untuk membatalkan " +"aplikasi-aplikasi daripada senarai sistem lalai. Senarai sistem lalai " +"termasuklah aplikasi-aplikasi berikut: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Pengguna boleh hentikan cekau sedia " +"ada dengan menggunakan pintasan papan kekuci khusus seperti yang ditakrif " +"oleh kunci pengikatan kekunci “restore-shortcuts”." + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. +#. +#: src/backends/meta-input-settings.c:2557 +#, c-format +msgid "Mode Switch (Group %d)" +msgstr "Suis Mod (Kumpulan %d)" -#: ../src/metacity.schemas.in.h:112 -msgid "" -"The keybinding used to move a window one workspace to the left. The format " -"looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -"parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2580 +msgid "Switch monitor" +msgstr "Alih monitor" -#: ../src/metacity.schemas.in.h:113 -msgid "" -"The keybinding used to move a window one workspace to the right. The format " -"looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -"parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" +#: src/backends/meta-input-settings.c:2582 +msgid "Show on-screen help" +msgstr "Tunjuk bantuan atas-skrin" -#: ../src/metacity.schemas.in.h:114 -msgid "" -"The keybinding used to move a window one workspace up. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: src/backends/meta-monitor.c:223 +msgid "Built-in display" +msgstr "Paparan terbina-dalam" -#: ../src/metacity.schemas.in.h:115 -msgid "" -"The keybinding used to move a window to workspace 1. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: src/backends/meta-monitor.c:252 +msgid "Unknown" +msgstr "Tidak diketahui" -#: ../src/metacity.schemas.in.h:116 -msgid "" -"The keybinding used to move a window to workspace 10. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: src/backends/meta-monitor.c:254 +msgid "Unknown Display" +msgstr "Paparan Tidak Diketahui" -#: ../src/metacity.schemas.in.h:117 -msgid "" -"The keybinding used to move a window to workspace 11. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: src/backends/meta-monitor.c:262 +#, c-format +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" -#: ../src/metacity.schemas.in.h:118 -msgid "" -"The keybinding used to move a window to workspace 12. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: src/backends/meta-monitor.c:270 +#, c-format +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" -#: ../src/metacity.schemas.in.h:119 -msgid "" -"The keybinding used to move a window to workspace 2. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#. Translators: this string will appear in Sysprof +#: src/backends/meta-profiler.c:79 +msgid "Compositor" +msgstr "Penggubah" -#: ../src/metacity.schemas.in.h:120 -msgid "" -"The keybinding used to move a window to workspace 3. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:121 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:533 +#, c-format +#| msgid "" +#| "Could not acquire window manager selection on screen %d display \"%s\"\n" msgid "" -"The keybinding used to move a window to workspace 4. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." +"Another compositing manager is already running on screen %i on display “%s”." msgstr "" +"Ada pengurus penggubahan lain sudah berjalan di skrin %i pada paparan \"%s" +"\"." -#: ../src/metacity.schemas.in.h:122 -msgid "" -"The keybinding used to move a window to workspace 5. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: src/core/bell.c:192 +msgid "Bell event" +msgstr "Peristiwa loceng" -#: ../src/metacity.schemas.in.h:123 -msgid "" -"The keybinding used to move a window to workspace 6. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: src/core/main.c:190 +msgid "Disable connection to session manager" +msgstr "Lumpuhkan sambungan ke pengurus sesi" -#: ../src/metacity.schemas.in.h:124 -msgid "" -"The keybinding used to move a window to workspace 7. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: src/core/main.c:196 +#| msgid "Bug in window manager: " +msgid "Replace the running window manager" +msgstr "Gantikan pengurus tetingkap yang berjalan" -#: ../src/metacity.schemas.in.h:125 -msgid "" -"The keybinding used to move a window to workspace 8. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: src/core/main.c:202 +msgid "Specify session management ID" +msgstr "Nyatakan ID pengurusan sesi" -#: ../src/metacity.schemas.in.h:126 -msgid "" -"The keybinding used to move a window to workspace 9. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: src/core/main.c:207 +msgid "X Display to use" +msgstr "Paparan X yang digunakan" -#: ../src/metacity.schemas.in.h:127 -msgid "" -"The keybinding used to move focus backwards between panels and the desktop, " -"using a popup window. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" +#: src/core/main.c:213 +msgid "Initialize session from savefile" +msgstr "Awalkan sesi dari fail simpan" -#: ../src/metacity.schemas.in.h:128 -msgid "" -"The keybinding used to move focus backwards between panels and the desktop, " -"without a popup window. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" +#: src/core/main.c:219 +msgid "Make X calls synchronous" +msgstr "Buat panggilan X segerak" -#: ../src/metacity.schemas.in.h:129 -msgid "" -"The keybinding used to move focus backwards between windows without a popup " -"window. Holding \"shift\" together with this binding makes the direction go " -"forward again. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" +#: src/core/main.c:226 +msgid "Run as a wayland compositor" +msgstr "Jalankan sebagai penggubah wayland" -#: ../src/metacity.schemas.in.h:130 -msgid "" -"The keybinding used to move focus backwards between windows, using a popup " -"window. Holding \"shift\" together with this binding makes the direction go " -"forward again. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" +#: src/core/main.c:232 +msgid "Run as a nested compositor" +msgstr "Jalankan sebagai penggubah tersarang" -#: ../src/metacity.schemas.in.h:131 -msgid "" -"The keybinding used to move focus between panels and the desktop, using a " -"popup window. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" +#: src/core/main.c:238 +msgid "Run wayland compositor without starting Xwayland" +msgstr "Jalankan penggubah wayland tanpa memulakan Xwayland" -#: ../src/metacity.schemas.in.h:132 -msgid "" -"The keybinding used to move focus between panels and the desktop, without a " -"popup window. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" +#: src/core/main.c:246 +msgid "Run as a full display server, rather than nested" +msgstr "Jalankan sebagai satu pelayan paparan penuh, berbanding tersarang" -#: ../src/metacity.schemas.in.h:133 -msgid "" -"The keybinding used to move focus between windows without a popup window. " -"(Traditionally <Alt>Escape) Holding the \"shift\" key while using this " -"binding reverses the direction of movement. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: src/core/main.c:252 +msgid "Run with X11 backend" +msgstr "Jalankan dengan bahagian belakang X11" -#: ../src/metacity.schemas.in.h:134 -msgid "" -"The keybinding used to move focus between windows, using a popup window. " -"(Traditionally <Alt>Tab) Holding the \"shift\" key while using this " -"binding reverses the direction of movement. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:151 +#, c-format +#| msgid "The window \"%s\" is not responding." +msgid "“%s” is not responding." +msgstr "\"%s\" tidak bertindak balas." -#: ../src/metacity.schemas.in.h:135 -msgid "" -"The keybinding used to toggle always on top. A window that is always on top " -"will always be visible over other overlapping windows. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: src/core/meta-close-dialog-default.c:153 +#| msgid "The window \"%s\" is not responding." +msgid "Application is not responding." +msgstr "Aplikasi tidak bertindak balas." -#: ../src/metacity.schemas.in.h:136 +#: src/core/meta-close-dialog-default.c:158 msgid "" -"The keybinding used to toggle fullscreen mode. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." msgstr "" +"Anda boleh memilih untuk tunggu sebentar supaya dapat diteruskan atau paksa " +"aplikasi ditutup sepenuhnya." -#: ../src/metacity.schemas.in.h:137 -msgid "" -"The keybinding used to toggle maximization. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Force Quit" +msgstr "_Paksa keluar" -#: ../src/metacity.schemas.in.h:138 -msgid "" -"The keybinding used to toggle shaded/unshaded state. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Wait" +msgstr "_Tunggu" -#: ../src/metacity.schemas.in.h:139 +#: src/core/mutter.c:38 +#, c-format msgid "" -"The keybinding used to toggle whether the window is on all workspaces or " -"just one. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" msgstr "" +"mutter %s\n" +"Hak cipta © 2001-%d Havoc Pennington, Red Hat, Inc., dan lain-lain\n" +"Ini adalah perisian bebas; sila rujuk sumber untuk syarat penyalinan.\n" +"TIADA jaminan; walaupun untuk KEBOLEHDAGANGAN atau KESESUAIAN ATAS APA JUA " +"TUJUAN.\n" -#: ../src/metacity.schemas.in.h:140 -msgid "" -"The keybinding used to unmaximize a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: src/core/mutter.c:52 +msgid "Print version" +msgstr "Versi cetak" -#: ../src/metacity.schemas.in.h:141 -msgid "" -"The keybinding which display's the panel's \"Run Application\" dialog box. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "Pemalam Mutter yang digunakan" -#: ../src/metacity.schemas.in.h:142 -msgid "" -"The keybinding which invokes a terminal. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: src/core/prefs.c:1849 +#, c-format +msgid "Workspace %d" +msgstr "Ruang kerja %d" -#: ../src/metacity.schemas.in.h:143 -msgid "" -"The keybinding which invokes the panel's screenshot utility to take a " -"screenshot of a window. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" +#: src/core/util.c:122 +#| msgid "Metacity was compiled without support for verbose mode\n" +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter telah dikompil tanpa sokongan mod berjela\n" -#: ../src/metacity.schemas.in.h:144 -msgid "" -"The keybinding which invokes the panel's screenshot utility. The format " -"looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -"parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" +#: src/wayland/meta-wayland-tablet-pad.c:568 +#, c-format +msgid "Mode Switch: Mode %d" +msgstr "Suis Mod: Mod %d" -#: ../src/metacity.schemas.in.h:145 +#: src/x11/meta-x11-display.c:675 +#, c-format +#| msgid "" +#| "Screen %d on display \"%s\" already has a window manager; try using the --" +#| "replace option to replace the current window manager.\n" msgid "" -"The keybinding which shows the panel's main menu. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." msgstr "" +"Paparan \"%s\" sudah mempunyai satu pengurus tetingkap; cuba guna pilihan --" +"replace untuk menggantikan pengurus tetingkap semasa." -#: ../src/metacity.schemas.in.h:146 -msgid "The name of a workspace." -msgstr "nama ruangkerja." - -#: ../src/metacity.schemas.in.h:147 -msgid "The screenshot command" -msgstr "Arahan cekupan skrin" +#: src/x11/meta-x11-display.c:1036 +msgid "Failed to initialize GDK\n" +msgstr "Gagal mengawalkan GDK\n" -#: ../src/metacity.schemas.in.h:148 -msgid "" -"The theme determines the appearance of window borders, titlebar, and so " -"forth." -msgstr "" -"Tema menentukan penampilan bagi sempadan, bar tajuk dan lain2 bagi tetingkap." - -#: ../src/metacity.schemas.in.h:149 -msgid "" -"The time delay before raising a window if auto_raise is set to true. The " -"delay is given in thousandths of a second." -msgstr "" -"Masa dilengahkan sebelum mengangkat tetingkap jika auto_raise ditetapkan " -"sebagai benar. Lengahan dikira dalam 1/1000 saat." +#: src/x11/meta-x11-display.c:1060 +#, c-format +#| msgid "Failed to open X Window System display '%s'\n" +msgid "Failed to open X Window System display “%s”\n" +msgstr "Gagal membuka paparan Sistem Window X \"%s\"\n" -#: ../src/metacity.schemas.in.h:150 -msgid "" -"The window focus mode indicates how windows are activated. It has three " -"possible values; \"click\" means windows must be clicked in order to focus " -"them, \"sloppy\" means windows are focused when the mouse enters the window, " -"and \"mouse\" means windows are focused when the mouse enters the window and " -"unfocused when the mouse leaves the window." -msgstr "" +#: src/x11/meta-x11-display.c:1143 +#, c-format +#| msgid "Screen %d on display '%s' is invalid\n" +msgid "Screen %d on display “%s” is invalid\n" +msgstr "Skrin %d pada paparan \"%s\" adalah tidak sah\n" -#: ../src/metacity.schemas.in.h:151 -msgid "The window screenshot command" -msgstr "Arahan mencekup skrin tetingkap" +#: src/x11/meta-x11-selection-input-stream.c:460 +#, c-format +msgid "Format %s not supported" +msgstr "Format %s tidak disokong" -#: ../src/metacity.schemas.in.h:152 +#: src/x11/session.c:1821 +#| msgid "" +#| "These windows do not support \"save current setup\" and will have to be " +#| "restarted manually next time you log in." msgid "" -"This keybinding changes whether a window is above or below other windows. If " -"the window is covered by another window, it raises the window above other " -"windows. If the window is already fully visible, it lowers the window below " -"other windows. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." msgstr "" +"Tetingkap ini tidak menyokong \"simpan persediaan semasa\" dan akan " +"dimulakan semula secara manual bila anda mendaftar masuk kelak." -#: ../src/metacity.schemas.in.h:153 -msgid "" -"This keybinding lowers a window below other windows. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#: src/x11/window-props.c:569 +#, c-format +msgid "%s (on %s)" +msgstr "%s (pada %s)" -#: ../src/metacity.schemas.in.h:154 -msgid "" -"This keybinding raises the window above other windows. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" +#~ msgid "Usage: %s\n" +#~ msgstr "Penggunaan: %s\n" -#: ../src/metacity.schemas.in.h:155 -msgid "" -"This keybinding resizes a window to fill available horizontal space. The " -"format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" +#~ msgid "Could not parse \"%s\" as an integer" +#~ msgstr "Tak dapat menghantar \"%s\" sebagai integer" -#: ../src/metacity.schemas.in.h:156 -msgid "" -"This keybinding resizes a window to fill available vertical space. The " -"format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" +#~ msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +#~ msgstr "Tidak memahami aksara berikut \"%s\" pada rentetan \"%s\"" -#: ../src/metacity.schemas.in.h:157 -msgid "" -"This option determines the effects of double-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, and 'toggle_maximize' which will maximize/unmaximize the window." -msgstr "" +#~ msgid "Failed to parse message \"%s\" from dialog process\n" +#~ msgstr "Gagal menghantar mesej \"%s\" dari proses dialog\n" -#: ../src/metacity.schemas.in.h:158 -msgid "Toggle always on top state" -msgstr "Togol keadaan sentiasa di atas" +#~ msgid "Error reading from dialog display process: %s\n" +#~ msgstr "Ralat membaca dari proses paparan dialog: %s\n" -#: ../src/metacity.schemas.in.h:159 -msgid "Toggle fullscreen mode" -msgstr "Togol mod skrinpenuh" +#~ msgid "" +#~ "Error launching metacity-dialog to ask about killing an application: %s\n" +#~ msgstr "" +#~ "Ralat melancarkan dialog-metacity untuk tanya tentang pembunuhan satu " +#~ "aplikasi: %s\n" -#: ../src/metacity.schemas.in.h:160 -msgid "Toggle maximization state" -msgstr "togol keadaan maksimum" +#~ msgid "Failed to get hostname: %s\n" +#~ msgstr "Gagal mendapatkan namahos:: %s\n" -#: ../src/metacity.schemas.in.h:161 -msgid "Toggle shaded state" -msgstr "Togol keadaan tersuram" +#~ msgid "" +#~ "Lost connection to the display '%s';\n" +#~ "most likely the X server was shut down or you killed/destroyed\n" +#~ "the window manager.\n" +#~ msgstr "" +#~ "Hilang sambungan ke paparan '%s';\n" +#~ "agaknya pelayan X telah dimatikan atau anda telah membunuh\n" +#~ "pengurus tetingkap.\n" -#: ../src/metacity.schemas.in.h:162 -msgid "Toggle window on all workspaces" -msgstr "Togol tetingkap pada semua ruangkerja" +#~ msgid "Fatal IO error %d (%s) on display '%s'.\n" +#~ msgstr "Ralat IO fatal %d (%s) pada paparan '%s'.\n" -#: ../src/metacity.schemas.in.h:163 -msgid "" -"Turns on a visual indication when an application or the system issues a " -"'bell' or 'beep'; useful for the hard-of-hearing and for use in noisy " -"environments, or when 'audible bell' is off." -msgstr "" +#~ msgid "Close Window" +#~ msgstr "Tutup Tetingkap" -#: ../src/metacity.schemas.in.h:164 -#, fuzzy -msgid "Unmaximize window" -msgstr "Nyahmaksimum tetingkap" - -#: ../src/metacity.schemas.in.h:165 -msgid "Use standard system font in window titles" -msgstr "Guna font sistem piawai pada tajuk tetingkap" - -#: ../src/metacity.schemas.in.h:166 -msgid "Visual Bell Type" -msgstr "Jenis Loceng Visual" - -#: ../src/metacity.schemas.in.h:167 -msgid "Window focus mode" -msgstr "Mod fokus tetingkap" - -#: ../src/metacity.schemas.in.h:168 -msgid "Window title font" -msgstr "Font tajuk tetingkap" - -#: ../src/prefs.c:528 ../src/prefs.c:544 ../src/prefs.c:560 ../src/prefs.c:576 -#: ../src/prefs.c:592 ../src/prefs.c:612 ../src/prefs.c:628 ../src/prefs.c:644 -#: ../src/prefs.c:660 ../src/prefs.c:676 ../src/prefs.c:692 ../src/prefs.c:708 -#: ../src/prefs.c:724 ../src/prefs.c:741 ../src/prefs.c:757 ../src/prefs.c:773 -#: ../src/prefs.c:789 ../src/prefs.c:805 ../src/prefs.c:820 ../src/prefs.c:835 -#: ../src/prefs.c:850 ../src/prefs.c:866 ../src/prefs.c:882 ../src/prefs.c:898 -#, c-format -msgid "GConf key \"%s\" is set to an invalid type\n" -msgstr "Kekunci GConf \"%s\" ditetapkan kepada jenis yang tidak sah\n" +#~ msgid "Window Menu" +#~ msgstr "Menu Tetingkap" -#: ../src/prefs.c:943 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"\"%s\" dijumpai pada pangkalan data konfigurasi adalah bukan pengubahsuai " -"butang tetikus yang sah\n" +#~ msgid "Minimize Window" +#~ msgstr "Miniatur Tetingkap" -#: ../src/prefs.c:967 ../src/prefs.c:1428 -#, c-format -msgid "GConf key '%s' is set to an invalid value\n" -msgstr "Kekunci GConf '%s' ditetapkan kepada nilai yang tidak sah\n" +#~ msgid "Maximize Window" +#~ msgstr "Maksimum tetingkap" -#: ../src/prefs.c:1145 -#, c-format -msgid "Could not parse font description \"%s\" from GConf key %s\n" -msgstr "Tak dapat menghantar huraian font \"%s\" daripada kekunci GConf %s\n" +#~ msgid "Unmaximize Window" +#~ msgstr "Nyah Maksimum Tetingkap" -#: ../src/prefs.c:1330 -#, c-format -msgid "" -"%d stored in GConf key %s is not a reasonable number of workspaces, current " -"maximum is %d\n" -msgstr "" -"%d yang disimpan pada kekunci GConf %s adalah bilangan ruangkerja yang tak " -"munasabah, maksimum semasa ialah %d\n" +# modifier=? binding=? +#~ msgid "" +#~ "Some other program is already using the key %s with modifiers %x as a " +#~ "binding\n" +#~ msgstr "" +#~ "Terdapat program lain yang sudah menggunakan kekukci %s dengan modifier " +#~ "%x sebagai binding\n" + +#~ msgid "" +#~ "Error launching metacity-dialog to print an error about a command: %s\n" +#~ msgstr "" +#~ "Ralat melancarkan dialog-metacity untuk mencetak ralat tentang arahan: " +#~ "%s\n" + +#~ msgid "No command %d has been defined.\n" +#~ msgstr "Tiada arahan %d ditakrifkan.\n" -#: ../src/prefs.c:1390 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" +#, fuzzy +#~ msgid "No terminal command has been defined.\n" +#~ msgstr "Tiada arahan %d ditakrifkan.\n" -#: ../src/prefs.c:1455 -#, c-format -msgid "%d stored in GConf key %s is out of range 0 to %d\n" -msgstr "" -"%d yang disimpan pada kekunci GConf %s adalah diluar julat 0 hingga %d\n" +#~ msgid "Failed to scan themes directory: %s\n" +#~ msgstr "Gagal mengimbas direktori tema: %s\n" -#: ../src/prefs.c:1589 -#, c-format -msgid "Error setting number of workspaces to %d: %s\n" -msgstr "Ralat menetapkan bilangan ruangkerja ke %d: %s\n" +#~ msgid "" +#~ "Could not find a theme! Be sure %s exists and contains the usual themes." +#~ msgstr "" +#~ "Tak dapat menjumpai tema! pastikan %s wujud dan mengandungi tema biasa." -#: ../src/prefs.c:1833 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "" +#~ msgid "Failed to restart: %s\n" +#~ msgstr "Gagal mengulanghidupkan: %s\n" -#: ../src/prefs.c:2187 -#, c-format -msgid "Error setting name for workspace %d to \"%s\": %s\n" -msgstr "Ralat menetapkan nama bagi ruangkerja %d ke \"%s\": %s\n" +#~ msgid "Mi_nimize" +#~ msgstr "Mi_nimum" -#: ../src/resizepopup.c:126 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" +#~ msgid "Ma_ximize" +#~ msgstr "Ma_ksimum" -#: ../src/screen.c:408 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "Skrin %d pada paparan '%s' adalah tidak sah\n" +#~ msgid "Unma_ximize" +#~ msgstr "_Nyah maksimum" -#: ../src/screen.c:424 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"Skrin %d pada paparan \"%s\" sudah mempunyai pengurus tetingkap; cuba guna " -"opsyen --replacei untuk menggantikan pengurus tetingkap semasa.\n" +#~ msgid "Roll _Up" +#~ msgstr "_Gulung" -#: ../src/screen.c:448 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "" -"Tak dapat pemilihan pengurus tetingkap pada skrin %d di paparan \"%s\"\n" +#~ msgid "_Unroll" +#~ msgstr "_Bentang" -#: ../src/screen.c:506 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "Skrin %d pada paparan \"%s\" sudah mempunyai pengurus tetingkap\n" +#~ msgid "On _Top" +#~ msgstr "Di _Atas" -#: ../src/screen.c:716 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "Tak dapat melepaskan skrin %d pada paparan \"%s\"\n" +#~ msgid "_Move" +#~ msgstr "_Alih" -#: ../src/session.c:884 ../src/session.c:891 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Tak dapat mencipta direktori %s: %s\n" +#~ msgid "_Resize" +#~ msgstr "_Ubahsaiz" -#: ../src/session.c:901 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "tak dapat membuka fail sessi '%s' untuk ditulis: %s\n" +#~ msgid "_Close" +#~ msgstr "_Tutup" -#: ../src/session.c:1053 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Ralat ketika menulis fail sessi '%s': %s\n" +#, fuzzy +#~ msgid "_Always on Visible Workspace" +#~ msgstr "_Ikon pada Ruangkerja ini" -#: ../src/session.c:1058 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Ralat menutup fail sessi '%s': %s\n" +#, fuzzy +#~ msgid "_Only on This Workspace" +#~ msgstr "_Ikon pada Ruangkerja ini" -#: ../src/session.c:1133 -#, c-format -msgid "Failed to read saved session file %s: %s\n" -msgstr "Gagal dapat baca fail sessi yang disimpan %s: %s\n" +#~ msgid "Move to Workspace R_ight" +#~ msgstr "Pindah ke Ruangkerja Ka_nan" -#: ../src/session.c:1168 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Gagal menghantar fail sessi yang disimpan: %s\n" +#~ msgid "Move to Workspace _Up" +#~ msgstr "Pindah ke Ruangkerja _Atas" -#: ../src/session.c:1217 -msgid "<metacity_session> attribute seen but we already have the session ID" -msgstr "atribut <metacity_session> dilihat tetapi kami sudah mempunya IS sessi" +#~ msgid "Workspace 1_0" +#~ msgstr "Ruangkerja 1_0" -#: ../src/session.c:1230 -#, c-format -msgid "Unknown attribute %s on <metacity_session> element" -msgstr "Atirbut tidak dikenali %s pada unsur <metacity_session>" +#~ msgid "Workspace %s%d" +#~ msgstr "Ruangkerja %s%d" -#: ../src/session.c:1247 -msgid "nested <window> tag" -msgstr "tag <window> bersarang" +#~ msgid "Move to Another _Workspace" +#~ msgstr "Pindah ke Ruangkerja lain" -#: ../src/session.c:1305 ../src/session.c:1337 -#, c-format -msgid "Unknown attribute %s on <window> element" -msgstr "Atribut tidak dikenali %s pada unsur <window>" +#~ msgid "Shift" +#~ msgstr "Shif" -#: ../src/session.c:1409 -#, c-format -msgid "Unknown attribute %s on <maximized> element" -msgstr "Atribut tidak dikenali %s pada unsur <maximized>" +#~ msgid "Ctrl" +#~ msgstr "Ctrl" -#: ../src/session.c:1469 -#, c-format -msgid "Unknown attribute %s on <geometry> element" -msgstr "Atirbut tidak dikenali %s pada unsur <geometry>" +#~ msgid "Alt" +#~ msgstr "Alt" -#: ../src/session.c:1489 -#, c-format -msgid "Unknown element %s" -msgstr "Unsur yang tidak dikenali %s" +#~ msgid "Meta" +#~ msgstr "Meta" -#: ../src/session.c:1961 -#, c-format -msgid "" -"Error launching metacity-dialog to warn about apps that don't support " -"session management: %s\n" -msgstr "" -"Ralat melancarkan metacity-dialog untuk memberitahu mengenai apps yang tidak " -"menyokong pengurusan sessi: %s\n" +#~ msgid "Super" +#~ msgstr "Super" -#: ../src/theme-parser.c:224 ../src/theme-parser.c:242 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Baris %d aksara %d: %s" +#~ msgid "Hyper" +#~ msgstr "Hiper" -#: ../src/theme-parser.c:396 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "Atribut \"%s\" berulang dua kali pada unsur <%s> yang sama" +#~ msgid "Mod2" +#~ msgstr "Mod2" -#: ../src/theme-parser.c:414 ../src/theme-parser.c:439 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "Atribut \"%s\" adalah tidak sah pada unsur <%s> dalam konteks ini" +#~ msgid "Mod3" +#~ msgstr "Mod3" -#: ../src/theme-parser.c:485 -#, c-format -msgid "Integer %ld must be positive" -msgstr "Integer %ld mestilah positif" +#~ msgid "Mod4" +#~ msgstr "Mod4" -#: ../src/theme-parser.c:493 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "Integer %ld adalah terlalu besar, maksimum semasa ialah %d" +#~ msgid "Mod5" +#~ msgstr "Mod5" -#: ../src/theme-parser.c:521 ../src/theme-parser.c:602 -#: ../src/theme-parser.c:626 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr " Tak dapat hantar \"%s\" sebagai nombor titik apungan" +#~ msgid "" +#~ "Forcing this application to quit will cause you to lose any unsaved " +#~ "changes." +#~ msgstr "" +#~ "Memaksa aplikasi ini keluar akan menyebabkan anda kehilangan sebarang " +#~ "perubahan yg betul disimpan." -#: ../src/theme-parser.c:552 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "Nilai Boolean mestikan \"benar\" atau \"palsu\" bukan \"%s\"" +#~ msgid "Title" +#~ msgstr "Tajuk" -#: ../src/theme-parser.c:572 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "Sudut mestilah diantara 0.0 dan 360.0, adalah %g\n" +#~ msgid "Class" +#~ msgstr "Kelas" -#: ../src/theme-parser.c:638 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" +#~ msgid "" +#~ "There was an error running \"%s\":\n" +#~ "%s." +#~ msgstr "" +#~ "Terdapat ralat melaksanakan \"%s\":\n" +#~ "%s." -#: ../src/theme-parser.c:684 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" +#~ msgid "Metacity" +#~ msgstr "Metacity" -#: ../src/theme-parser.c:729 ../src/theme-parser.c:737 -#: ../src/theme-parser.c:807 ../src/theme-parser.c:897 -#: ../src/theme-parser.c:935 ../src/theme-parser.c:1012 -#: ../src/theme-parser.c:1062 ../src/theme-parser.c:1070 -#: ../src/theme-parser.c:1126 ../src/theme-parser.c:1134 -#: ../src/theme-parser.c:2936 ../src/theme-parser.c:3025 -#: ../src/theme-parser.c:3032 ../src/theme-parser.c:3039 -#, c-format -msgid "No \"%s\" attribute on <%s> element" -msgstr "Tiada atribut \"%s\" pada unsur <%s>" +#~ msgid "" +#~ "(Not implemented) Navigation works in terms of applications not windows" +#~ msgstr "Navigasi berkerja dari segi aplikasi bukannya tetingkap" -#: ../src/theme-parser.c:837 ../src/theme-parser.c:905 -#: ../src/theme-parser.c:943 ../src/theme-parser.c:1020 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s> nama \"%s\" digunakan kali kedua" +#~ msgid "Action on title bar double-click" +#~ msgstr "Aksi pada dwi-klik bar tajuk" -#: ../src/theme-parser.c:849 ../src/theme-parser.c:955 -#: ../src/theme-parser.c:1032 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "<%s> parent \"%s\" tidak ditakrifkan" +#~ msgid "Arrangement of buttons on the titlebar" +#~ msgstr "Penyusunan butang pada bar tajuk" -#: ../src/theme-parser.c:968 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "<%s> geometry \"%s\" tidak ditakrifkan" +#~ msgid "Automatically raises the focused window" +#~ msgstr "Automatik angkat bila tetingkap difokus" -#: ../src/theme-parser.c:981 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "<%s> mesti menyatakan geometri atau induk yang mempunyai geometri" +#~ msgid "Commands to run in response to keybindings" +#~ msgstr "Arahan untuk dilaksana tindakbalas pengikatan kekunci" -#: ../src/theme-parser.c:1080 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Jenis tidak dikenali \"%s\" pada unsur <%s>" +#~ msgid "Current theme" +#~ msgstr "Tema semasa" -#: ../src/theme-parser.c:1091 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "style_set tidak dikenali \"%s\" pada unsur <%s>" +#~ msgid "Delay in milliseconds for the auto raise option" +#~ msgstr "Selangmasa dalam milisaat bagi opsyen auto angkat" -#: ../src/theme-parser.c:1099 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "" +#~ msgid "Enable Visual Bell" +#~ msgstr "Hidupkan Loceng Visual" -#: ../src/theme-parser.c:1143 -#, c-format -msgid "Unknown function \"%s\" for menu icon" -msgstr "Fungsi \"%s\" tidak diketahui bagi ikon menu" +#~ msgid "Hide all windows and focus desktop" +#~ msgstr "Sembunyi semua tetingkap dan fokus desktop" -#: ../src/theme-parser.c:1152 -#, c-format -msgid "Unknown state \"%s\" for menu icon" -msgstr "Keadaan \"%s\" tidak diketahui bagi ikon menu" +#, fuzzy +#~ msgid "Minimize window" +#~ msgstr "Miniatur tetingkap" -#: ../src/theme-parser.c:1160 -#, c-format -msgid "Theme already has a menu icon for function %s state %s" -msgstr "Tema sudah mempunyai ikon menu bagi fungsi %s keadaan %s" +#~ msgid "Move backward between panels and the desktop immediately" +#~ msgstr "Beralih ke belakang antara panel dan desktop serta merta" -#: ../src/theme-parser.c:1177 ../src/theme-parser.c:3244 -#: ../src/theme-parser.c:3323 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "Tiada <draw_ops> dengan nama \"%s\" telah ditakrifkan" - -#: ../src/theme-parser.c:1192 ../src/theme-parser.c:1256 -#: ../src/theme-parser.c:1545 ../src/theme-parser.c:3124 -#: ../src/theme-parser.c:3178 ../src/theme-parser.c:3338 -#: ../src/theme-parser.c:3515 ../src/theme-parser.c:3553 -#: ../src/theme-parser.c:3591 ../src/theme-parser.c:3629 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "Unsur <%s> adalah tidak diizinkan dibawah <%s>" +#~ msgid "Move backwards between panels and the desktop with popup" +#~ msgstr "Beralih ke belakang antara panel dan desktop menggunakan popup" -#: ../src/theme-parser.c:1282 ../src/theme-parser.c:1369 -#: ../src/theme-parser.c:1439 -#, c-format -msgid "No \"name\" attribute on element <%s>" -msgstr "Tiada atribut \"name\" pada unsur <%s>" +#~ msgid "Move backwards between windows immediately" +#~ msgstr "Beralih kebelakang antara tetingkap serta merta" -#: ../src/theme-parser.c:1289 ../src/theme-parser.c:1376 -#, c-format -msgid "No \"value\" attribute on element <%s>" -msgstr "Tiada atribut \"value\" pada unsur <%s>" +#~ msgid "Move between panels and the desktop immediately" +#~ msgstr "Beralih antara panel dan desktop serta merta" -#: ../src/theme-parser.c:1320 ../src/theme-parser.c:1334 -#: ../src/theme-parser.c:1393 -msgid "" -"Cannot specify both button_width/button_height and aspect ratio for buttons" -msgstr "" -"Tak dapat menyatakan kedua-dua button_width/button_height dan nisbah aspek " -"bagi butang" +#~ msgid "Move between panels and the desktop with popup" +#~ msgstr "Beralih antara panel dan desktop menggunakan paparan popup" -#: ../src/theme-parser.c:1343 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "Jarak \"%s\" tidak diketahui" +#~ msgid "Move between windows immediately" +#~ msgstr "Beralih antara tetingkap serta merta" -#: ../src/theme-parser.c:1402 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "Nisbah aspek butang \"%s\" tidak diketahui" +#~ msgid "Move focus backwards between windows using popup display" +#~ msgstr "Alih fokus ke belakang antara tetingkap menggunakan paparan popup" -#: ../src/theme-parser.c:1446 -#, c-format -msgid "No \"top\" attribute on element <%s>" -msgstr "Tiada atribut \"top\" pada unsur <%s>" +#~ msgid "Move window to workspace 10" +#~ msgstr "Pindah tetingkap ke ruangkerja 10" -#: ../src/theme-parser.c:1453 -#, c-format -msgid "No \"bottom\" attribute on element <%s>" -msgstr "Tiada atribut \"bottom\" pada unsur <%s>" +#~ msgid "Move window to workspace 11" +#~ msgstr "Pindah tetingkap ke ruangkerja 11" -#: ../src/theme-parser.c:1460 -#, c-format -msgid "No \"left\" attribute on element <%s>" -msgstr "Tiada atribut \"left\" pada unsur <%s>" +#~ msgid "Move window to workspace 12" +#~ msgstr "Pindah tetingkap ke ruangkerja 12" -#: ../src/theme-parser.c:1467 -#, c-format -msgid "No \"right\" attribute on element <%s>" -msgstr "Tiada atribut \"right\" pada unsur <%s>" +#~ msgid "Move window to workspace 5" +#~ msgstr "Pindah tetingkap ke ruangkerja %s%d" -#: ../src/theme-parser.c:1499 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "Sempadan \"%s\" tidak diketahui" +#~ msgid "Move window to workspace 6" +#~ msgstr "Pindah tetingkap ke ruangkerja 6" -#: ../src/theme-parser.c:1655 ../src/theme-parser.c:1765 -#: ../src/theme-parser.c:1868 ../src/theme-parser.c:2055 -#: ../src/theme-parser.c:2869 -#, c-format -msgid "No \"color\" attribute on element <%s>" -msgstr "Tiada atribut \"color\" pada unsur <%s>" +#~ msgid "Move window to workspace 7" +#~ msgstr "Pindah tetingkap ke ruangkerja 7" -#: ../src/theme-parser.c:1662 -#, c-format -msgid "No \"x1\" attribute on element <%s>" -msgstr "Tiada atribut \"x1\" pada unsur <%s>" +#~ msgid "Move window to workspace 8" +#~ msgstr "Pindah tetingkap ke ruangkerja 8" -#: ../src/theme-parser.c:1669 ../src/theme-parser.c:2714 -#, c-format -msgid "No \"y1\" attribute on element <%s>" -msgstr "Tiada atribut \"y1\" pada unsur <%s>" +#~ msgid "Move window to workspace 9" +#~ msgstr "Pindah tetingkap ke ruangkerja 9" -#: ../src/theme-parser.c:1676 -#, c-format -msgid "No \"x2\" attribute on element <%s>" -msgstr "Tiada atribut \"x2\" pada unsur <%s>" +#~ msgid "Name of workspace" +#~ msgstr "Nama ruangkerja" -#: ../src/theme-parser.c:1683 ../src/theme-parser.c:2721 -#, c-format -msgid "No \"y2\" attribute on element <%s>" -msgstr "Tiada atribut \"y2\" pada unsur <%s>" - -#: ../src/theme-parser.c:1772 ../src/theme-parser.c:1875 -#: ../src/theme-parser.c:1981 ../src/theme-parser.c:2062 -#: ../src/theme-parser.c:2168 ../src/theme-parser.c:2266 -#: ../src/theme-parser.c:2483 ../src/theme-parser.c:2609 -#: ../src/theme-parser.c:2707 ../src/theme-parser.c:2781 -#: ../src/theme-parser.c:2876 -#, c-format -msgid "No \"x\" attribute on element <%s>" -msgstr "Tiada atribut \"x\" pada unsur <%s>" - -#: ../src/theme-parser.c:1779 ../src/theme-parser.c:1882 -#: ../src/theme-parser.c:1988 ../src/theme-parser.c:2069 -#: ../src/theme-parser.c:2175 ../src/theme-parser.c:2273 -#: ../src/theme-parser.c:2490 ../src/theme-parser.c:2616 -#: ../src/theme-parser.c:2788 ../src/theme-parser.c:2883 -#, c-format -msgid "No \"y\" attribute on element <%s>" -msgstr "Tiada atribut \"y\" pada unsur <%s>" - -#: ../src/theme-parser.c:1786 ../src/theme-parser.c:1889 -#: ../src/theme-parser.c:1995 ../src/theme-parser.c:2076 -#: ../src/theme-parser.c:2182 ../src/theme-parser.c:2280 -#: ../src/theme-parser.c:2497 ../src/theme-parser.c:2623 -#: ../src/theme-parser.c:2795 -#, c-format -msgid "No \"width\" attribute on element <%s>" -msgstr "Tiada atribut \"width\" pada unsur <%s>" - -#: ../src/theme-parser.c:1793 ../src/theme-parser.c:1896 -#: ../src/theme-parser.c:2002 ../src/theme-parser.c:2083 -#: ../src/theme-parser.c:2189 ../src/theme-parser.c:2287 -#: ../src/theme-parser.c:2504 ../src/theme-parser.c:2630 -#: ../src/theme-parser.c:2802 -#, c-format -msgid "No \"height\" attribute on element <%s>" -msgstr "Tiada atribut \"height\" pada unsur <%s>" +#~ msgid "Number of workspaces" +#~ msgstr "Bilangan ruangkerja" -#: ../src/theme-parser.c:1903 -#, c-format -msgid "No \"start_angle\" attribute on element <%s>" -msgstr "Tiada atribut \"start_angle\" pada unsur <%s>" +#~ msgid "" +#~ "Number of workspaces. Must be more than zero, and has a fixed maximum (to " +#~ "prevent accidentally destroying your desktop by asking for 34 million " +#~ "workspaces)." +#~ msgstr "" +#~ "Bilangan ruangkerja. Mesti lebih daripada sifar, dan mempunyai bilangan " +#~ "maksimum tetap (untuk mencegah pemusnahan desktop akibat daripada meminta " +#~ "34 juta ruangkerja)." -#: ../src/theme-parser.c:1910 -#, c-format -msgid "No \"extent_angle\" attribute on element <%s>" -msgstr "Tiada atribut \"extent_angle\" pada unsur <%s>" +#~ msgid "Run a defined command" +#~ msgstr "Laksana arahan tertakrif" -#: ../src/theme-parser.c:2090 -#, c-format -msgid "No \"alpha\" attribute on element <%s>" -msgstr "Tiada atribut \"alpha\" pada unsur <%s>" +#~ msgid "Show the panel menu" +#~ msgstr "Papar menu panel" -#: ../src/theme-parser.c:2161 -#, c-format -msgid "No \"type\" attribute on element <%s>" -msgstr "Tiada atribut \"type\" pada unsur <%s>" +#, fuzzy +#~ msgid "Show the panel run application dialog" +#~ msgstr "Papar dialog perlaksanaan panel" + +#~ msgid "Switch to workspace above this one" +#~ msgstr "Bertukar ke ruangkerja di atas yang ini" + +#~ msgid "Switch to workspace below this one" +#~ msgstr "Bertukar ke ruangkerja di bawah yang ini" + +#~ msgid "Switch to workspace on the left" +#~ msgstr "Bertukar ke ruangkerja di sebelah kiri" + +#~ msgid "Switch to workspace on the right" +#~ msgstr "Bertukar ke ruangkerja di sebelah kanan" + +#~ msgid "System Bell is Audible" +#~ msgstr "Loceng Sistem boleh didengar" + +#~ msgid "Take a screenshot" +#~ msgstr "Tangkap cekupanskrin" + +#~ msgid "Take a screenshot of a window" +#~ msgstr "Ambil cekupan skrin tetingkap" + +#~ msgid "" +#~ "The /apps/metacity/global_keybindings/run_command_N keys define " +#~ "keybindings that correspond to these commands. Pressing the keybinding " +#~ "for run_command_N will execute command_N." +#~ msgstr "" +#~ "Kekunci /apps/metacity/global_keybindings/run_command_N keys mentakrifkan " +#~ "pengikatan kekunci yang merujuk kepada arahan ini. Menekan pengikatan " +#~ "kekunci lanksana_arahan_N akan melaksanakan arahan_N will execute " +#~ "command_N." + +#~ msgid "" +#~ "The /apps/metacity/global_keybindings/run_command_screenshot key defines " +#~ "a keybinding which causes the command specified by this setting to be " +#~ "invoked." +#~ msgstr "" +#~ "Kekunci /apps/metacity/global_keybindings/run_command_screenshot " +#~ "mentakrifkan pengikatan kekunci yang menyebabkan arahan di nyatakan oleh " +#~ "tetapan ini akan dipanggil" + +#~ msgid "" +#~ "The /apps/metacity/global_keybindings/run_command_window_screenshot key " +#~ "defines a keybinding which causes the command specified by this setting " +#~ "to be invoked." +#~ msgstr "" +#~ "Kekunci /apps/metacity/global_keybindings/run_command_window mentakrifkan " +#~ "pengikatan kekunci yang menyebabkan arahan dinyatakan oleh tetapan ini " +#~ "akan dilaksanakan." + +#~ msgid "The name of a workspace." +#~ msgstr "nama ruangkerja." + +#~ msgid "The screenshot command" +#~ msgstr "Arahan cekupan skrin" + +#~ msgid "" +#~ "The theme determines the appearance of window borders, titlebar, and so " +#~ "forth." +#~ msgstr "" +#~ "Tema menentukan penampilan bagi sempadan, bar tajuk dan lain2 bagi " +#~ "tetingkap." + +#~ msgid "" +#~ "The time delay before raising a window if auto_raise is set to true. The " +#~ "delay is given in thousandths of a second." +#~ msgstr "" +#~ "Masa dilengahkan sebelum mengangkat tetingkap jika auto_raise ditetapkan " +#~ "sebagai benar. Lengahan dikira dalam 1/1000 saat." + +#~ msgid "The window screenshot command" +#~ msgstr "Arahan mencekup skrin tetingkap" + +#~ msgid "Toggle always on top state" +#~ msgstr "Togol keadaan sentiasa di atas" + +#~ msgid "Toggle shaded state" +#~ msgstr "Togol keadaan tersuram" -#: ../src/theme-parser.c:2209 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "Tak memahami nilai \"%s\" bagi jenis gradien" +#, fuzzy +#~ msgid "Unmaximize window" +#~ msgstr "Nyahmaksimum tetingkap" -#: ../src/theme-parser.c:2294 -#, c-format -msgid "No \"filename\" attribute on element <%s>" -msgstr "Tiada atribut \"filename\" pada unsur <%s>" +#~ msgid "Use standard system font in window titles" +#~ msgstr "Guna font sistem piawai pada tajuk tetingkap" -#: ../src/theme-parser.c:2319 ../src/theme-parser.c:2827 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "Tidak memahami jenis isi \"%s\" pada unsur <%s>" +#~ msgid "Visual Bell Type" +#~ msgstr "Jenis Loceng Visual" -#: ../src/theme-parser.c:2462 ../src/theme-parser.c:2595 -#: ../src/theme-parser.c:2700 -#, c-format -msgid "No \"state\" attribute on element <%s>" -msgstr "Tiada atribut \"state\" pada unsur <%s>" +#~ msgid "Window focus mode" +#~ msgstr "Mod fokus tetingkap" -#: ../src/theme-parser.c:2469 ../src/theme-parser.c:2602 -#, c-format -msgid "No \"shadow\" attribute on element <%s>" -msgstr "Tiada atribut \"shadow\" pada unsur <%s>" +#~ msgid "Window title font" +#~ msgstr "Font tajuk tetingkap" -#: ../src/theme-parser.c:2476 -#, c-format -msgid "No \"arrow\" attribute on element <%s>" -msgstr "Tiada atribut \"arrow\" pada unsur <%s>" +#~ msgid "GConf key \"%s\" is set to an invalid type\n" +#~ msgstr "Kekunci GConf \"%s\" ditetapkan kepada jenis yang tidak sah\n" -#: ../src/theme-parser.c:2529 ../src/theme-parser.c:2651 -#: ../src/theme-parser.c:2739 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "Tak memahami keadaan \"%s\" bagi unsur <%s>" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" +#~ msgstr "" +#~ "\"%s\" dijumpai pada pangkalan data konfigurasi adalah bukan pengubahsuai " +#~ "butang tetikus yang sah\n" -#: ../src/theme-parser.c:2539 ../src/theme-parser.c:2661 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "Tak memahami bebayang \"%s\" bagi unsur <%s>" +#~ msgid "GConf key '%s' is set to an invalid value\n" +#~ msgstr "Kekunci GConf '%s' ditetapkan kepada nilai yang tidak sah\n" -#: ../src/theme-parser.c:2549 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "Tak memahami panah \"%s\" bagi unsur <%s>" +#~ msgid "Could not parse font description \"%s\" from GConf key %s\n" +#~ msgstr "" +#~ "Tak dapat menghantar huraian font \"%s\" daripada kekunci GConf %s\n" -#: ../src/theme-parser.c:2962 ../src/theme-parser.c:3078 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "Tiada <draw_ops> yg dipanggil \"%s\" telah ditakrifkan" +#~ msgid "" +#~ "%d stored in GConf key %s is not a reasonable number of workspaces, " +#~ "current maximum is %d\n" +#~ msgstr "" +#~ "%d yang disimpan pada kekunci GConf %s adalah bilangan ruangkerja yang " +#~ "tak munasabah, maksimum semasa ialah %d\n" -#: ../src/theme-parser.c:2974 ../src/theme-parser.c:3090 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "Penyertaan draw_ops \"%s\" di sini akan mencipta rujukan bergelung" +#~ msgid "%d stored in GConf key %s is out of range 0 to %d\n" +#~ msgstr "" +#~ "%d yang disimpan pada kekunci GConf %s adalah diluar julat 0 hingga %d\n" -#: ../src/theme-parser.c:3153 -#, c-format -msgid "No \"value\" attribute on <%s> element" -msgstr "Tiada atribut \"value\" pada unsur <%s>" +#~ msgid "Error setting number of workspaces to %d: %s\n" +#~ msgstr "Ralat menetapkan bilangan ruangkerja ke %d: %s\n" -#: ../src/theme-parser.c:3210 -#, c-format -msgid "No \"position\" attribute on <%s> element" -msgstr "Tiada atribut \"position\" pada unsur <%s>" +#~ msgid "Error setting name for workspace %d to \"%s\": %s\n" +#~ msgstr "Ralat menetapkan nama bagi ruangkerja %d ke \"%s\": %s\n" -#: ../src/theme-parser.c:3219 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Posisi tidak diketahui \"%s\" bagi serpihan kerangka" +#~ msgid "%d x %d" +#~ msgstr "%d x %d" -#: ../src/theme-parser.c:3227 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "" +#~ msgid "Screen %d on display \"%s\" already has a window manager\n" +#~ msgstr "Skrin %d pada paparan \"%s\" sudah mempunyai pengurus tetingkap\n" -#: ../src/theme-parser.c:3272 -#, c-format -msgid "No \"function\" attribute on <%s> element" -msgstr "Tiada atribut \"function\" pada unsur <%s>" +#~ msgid "Could not release screen %d on display \"%s\"\n" +#~ msgstr "Tak dapat melepaskan skrin %d pada paparan \"%s\"\n" -#: ../src/theme-parser.c:3280 ../src/theme-parser.c:3384 -#, c-format -msgid "No \"state\" attribute on <%s> element" -msgstr "Tiada atribut \"focus\" pada unsur <%s>" +#~ msgid "Could not create directory '%s': %s\n" +#~ msgstr "Tak dapat mencipta direktori %s: %s\n" -#: ../src/theme-parser.c:3289 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Fungsi \"%s\" tidak diketahui bagi butang" +#~ msgid "Could not open session file '%s' for writing: %s\n" +#~ msgstr "tak dapat membuka fail sessi '%s' untuk ditulis: %s\n" -#: ../src/theme-parser.c:3298 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Keadaan \"%s\" tidak diketahui bagi butang" +#~ msgid "Error writing session file '%s': %s\n" +#~ msgstr "Ralat ketika menulis fail sessi '%s': %s\n" -#: ../src/theme-parser.c:3306 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "" +#~ msgid "Error closing session file '%s': %s\n" +#~ msgstr "Ralat menutup fail sessi '%s': %s\n" -#: ../src/theme-parser.c:3376 -#, c-format -msgid "No \"focus\" attribute on <%s> element" -msgstr "Tiada atribut \"focus\" pada unsur <%s>" +#~ msgid "Failed to read saved session file %s: %s\n" +#~ msgstr "Gagal dapat baca fail sessi yang disimpan %s: %s\n" -#: ../src/theme-parser.c:3392 -#, c-format -msgid "No \"style\" attribute on <%s> element" -msgstr "Tiada atribut \"style\" pada unsur <%s>" +#~ msgid "Failed to parse saved session file: %s\n" +#~ msgstr "Gagal menghantar fail sessi yang disimpan: %s\n" -#: ../src/theme-parser.c:3401 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "\"%s\" adalah bukan nilai atribut fokus yang sah" +#~ msgid "<metacity_session> attribute seen but we already have the session ID" +#~ msgstr "" +#~ "atribut <metacity_session> dilihat tetapi kami sudah mempunya IS sessi" -#: ../src/theme-parser.c:3410 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "\"%s\" adalah bukan nilai sah bagi atribut keadaan" +#~ msgid "Unknown attribute %s on <metacity_session> element" +#~ msgstr "Atirbut tidak dikenali %s pada unsur <metacity_session>" -#: ../src/theme-parser.c:3420 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "Gaya yang dipanggil \"%s\" tidak ditakrifkan" +#~ msgid "nested <window> tag" +#~ msgstr "tag <window> bersarang" -#: ../src/theme-parser.c:3430 -#, c-format -msgid "No \"resize\" attribute on <%s> element" -msgstr "Tiada atribut \"resize\" pada unsur <%s>" +#~ msgid "Unknown attribute %s on <window> element" +#~ msgstr "Atribut tidak dikenali %s pada unsur <window>" -#: ../src/theme-parser.c:3440 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "\"%s\" adalah bukan nilai atribut ubahsaiz yang sah" +#~ msgid "Unknown attribute %s on <maximized> element" +#~ msgstr "Atribut tidak dikenali %s pada unsur <maximized>" -#: ../src/theme-parser.c:3450 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" -"Tak sepatutnya mempunyai atribut \"resize\" pada unsur <%s> untuk keadaan " -"maksimum/gulung" +#~ msgid "Unknown attribute %s on <geometry> element" +#~ msgstr "Atirbut tidak dikenali %s pada unsur <geometry>" -#: ../src/theme-parser.c:3464 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "Gaya telah dinyatakan bagi keadaan %s ubahsaiz %s fokus %s" +#~ msgid "Unknown element %s" +#~ msgstr "Unsur yang tidak dikenali %s" -#: ../src/theme-parser.c:3475 ../src/theme-parser.c:3486 -#: ../src/theme-parser.c:3497 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "Gaya telah dinyatakan bagi keadaan %s fokus %s" +#~ msgid "" +#~ "Error launching metacity-dialog to warn about apps that don't support " +#~ "session management: %s\n" +#~ msgstr "" +#~ "Ralat melancarkan metacity-dialog untuk memberitahu mengenai apps yang " +#~ "tidak menyokong pengurusan sessi: %s\n" -#: ../src/theme-parser.c:3536 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" +#~ msgid "Line %d character %d: %s" +#~ msgstr "Baris %d aksara %d: %s" -#: ../src/theme-parser.c:3574 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" +#~ msgid "Attribute \"%s\" repeated twice on the same <%s> element" +#~ msgstr "Atribut \"%s\" berulang dua kali pada unsur <%s> yang sama" -#: ../src/theme-parser.c:3612 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" +#~ msgid "Attribute \"%s\" is invalid on <%s> element in this context" +#~ msgstr "Atribut \"%s\" adalah tidak sah pada unsur <%s> dalam konteks ini" -#: ../src/theme-parser.c:3659 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "" +#~ msgid "Integer %ld must be positive" +#~ msgstr "Integer %ld mestilah positif" -#: ../src/theme-parser.c:3679 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "Unsur <%s> tidak diizinkan di dalam unsur name/author/date/description" +#~ msgid "Integer %ld is too large, current max is %d" +#~ msgstr "Integer %ld adalah terlalu besar, maksimum semasa ialah %d" -#: ../src/theme-parser.c:3684 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "Unsur <%s> tidak diizinkan di dalam unsur <constant>" +#~ msgid "Could not parse \"%s\" as a floating point number" +#~ msgstr " Tak dapat hantar \"%s\" sebagai nombor titik apungan" -#: ../src/theme-parser.c:3696 -#, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "Unsur <%s> tak diizinkan di dalan unsur distance/border/aspect_ratio" +#~ msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" +#~ msgstr "Nilai Boolean mestikan \"benar\" atau \"palsu\" bukan \"%s\"" -#: ../src/theme-parser.c:3718 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "Unsur <%s> tidak diizinkan di dalam unsur operasi lukisan" +#~ msgid "Angle must be between 0.0 and 360.0, was %g\n" +#~ msgstr "Sudut mestilah diantara 0.0 dan 360.0, adalah %g\n" -#: ../src/theme-parser.c:3728 ../src/theme-parser.c:3758 -#: ../src/theme-parser.c:3763 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "Unsur <%s> tidak diizinkan di dalam unsur <%s>" +#~ msgid "No \"%s\" attribute on <%s> element" +#~ msgstr "Tiada atribut \"%s\" pada unsur <%s>" -#: ../src/theme-parser.c:3984 -msgid "No draw_ops provided for frame piece" -msgstr "" +#~ msgid "<%s> name \"%s\" used a second time" +#~ msgstr "<%s> nama \"%s\" digunakan kali kedua" -#: ../src/theme-parser.c:3999 -msgid "No draw_ops provided for button" -msgstr "Tiada draw_ops dibekalkan untuk butang" +#~ msgid "<%s> parent \"%s\" has not been defined" +#~ msgstr "<%s> parent \"%s\" tidak ditakrifkan" -#: ../src/theme-parser.c:4014 -msgid "No draw_ops provided for menu icon" -msgstr "Tiada draw_ops dibekalkan bagi ikon menu" +#~ msgid "<%s> geometry \"%s\" has not been defined" +#~ msgstr "<%s> geometry \"%s\" tidak ditakrifkan" -#: ../src/theme-parser.c:4054 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "Teks tidak diizinkan di dalam unsur <%s>" +#~ msgid "<%s> must specify either a geometry or a parent that has a geometry" +#~ msgstr "<%s> mesti menyatakan geometri atau induk yang mempunyai geometri" -#: ../src/theme-parser.c:4109 -msgid "<name> specified twice for this theme" -msgstr "<nama> dinyatakan dua kali pada tema ini" +#~ msgid "Unknown type \"%s\" on <%s> element" +#~ msgstr "Jenis tidak dikenali \"%s\" pada unsur <%s>" -#: ../src/theme-parser.c:4120 -msgid "<author> specified twice for this theme" -msgstr "<author> dinyatakan dua kali pada tema ini" +#~ msgid "Unknown style_set \"%s\" on <%s> element" +#~ msgstr "style_set tidak dikenali \"%s\" pada unsur <%s>" -#: ../src/theme-parser.c:4131 -msgid "<copyright> specified twice for this theme" -msgstr "<copyright> dinyatakan dua kali pada tema ini" +#~ msgid "Unknown function \"%s\" for menu icon" +#~ msgstr "Fungsi \"%s\" tidak diketahui bagi ikon menu" -#: ../src/theme-parser.c:4142 -msgid "<date> specified twice for this theme" -msgstr "<date> dinyatakan dua kali pada tema ini" +#~ msgid "Unknown state \"%s\" for menu icon" +#~ msgstr "Keadaan \"%s\" tidak diketahui bagi ikon menu" -#: ../src/theme-parser.c:4153 -msgid "<description> specified twice for this theme" -msgstr "<description> dinyatakan dua kali pada tema ini" +#~ msgid "Theme already has a menu icon for function %s state %s" +#~ msgstr "Tema sudah mempunyai ikon menu bagi fungsi %s keadaan %s" -#: ../src/theme-parser.c:4348 -#, c-format -msgid "Failed to read theme from file %s: %s\n" -msgstr "Gagal dapat baca tema dari fail %s: %s\n" +#~ msgid "No <draw_ops> with the name \"%s\" has been defined" +#~ msgstr "Tiada <draw_ops> dengan nama \"%s\" telah ditakrifkan" -#: ../src/theme-parser.c:4403 -#, c-format -msgid "Theme file %s did not contain a root <metacity_theme> element" -msgstr "Fail tema %s tak mengandungi unsur root <metacity_theme>" +#~ msgid "Element <%s> is not allowed below <%s>" +#~ msgstr "Unsur <%s> adalah tidak diizinkan dibawah <%s>" -#: ../src/theme-viewer.c:70 -msgid "/_Windows" -msgstr "/_Tetingkap" +#~ msgid "No \"name\" attribute on element <%s>" +#~ msgstr "Tiada atribut \"name\" pada unsur <%s>" -#: ../src/theme-viewer.c:71 -msgid "/Windows/tearoff" -msgstr "/Tetingkap/koyak" +#~ msgid "No \"value\" attribute on element <%s>" +#~ msgstr "Tiada atribut \"value\" pada unsur <%s>" -#: ../src/theme-viewer.c:72 -msgid "/Windows/_Dialog" -msgstr "/Tetingkap/_Dialog" +#~ msgid "" +#~ "Cannot specify both button_width/button_height and aspect ratio for " +#~ "buttons" +#~ msgstr "" +#~ "Tak dapat menyatakan kedua-dua button_width/button_height dan nisbah " +#~ "aspek bagi butang" -#: ../src/theme-viewer.c:73 -msgid "/Windows/_Modal dialog" -msgstr "/Tetingkap/Dialog _modal" +#~ msgid "Distance \"%s\" is unknown" +#~ msgstr "Jarak \"%s\" tidak diketahui" -#: ../src/theme-viewer.c:74 -msgid "/Windows/_Utility" -msgstr "/Tetingkap/_Utiliti" +#~ msgid "Aspect ratio \"%s\" is unknown" +#~ msgstr "Nisbah aspek butang \"%s\" tidak diketahui" -#: ../src/theme-viewer.c:75 -msgid "/Windows/_Splashscreen" -msgstr "" +#~ msgid "No \"top\" attribute on element <%s>" +#~ msgstr "Tiada atribut \"top\" pada unsur <%s>" -#: ../src/theme-viewer.c:76 -msgid "/Windows/_Top dock" -msgstr "/Tetingkap/Dok _atas" +#~ msgid "No \"bottom\" attribute on element <%s>" +#~ msgstr "Tiada atribut \"bottom\" pada unsur <%s>" -#: ../src/theme-viewer.c:77 -msgid "/Windows/_Bottom dock" -msgstr "" +#~ msgid "No \"left\" attribute on element <%s>" +#~ msgstr "Tiada atribut \"left\" pada unsur <%s>" -#: ../src/theme-viewer.c:78 -msgid "/Windows/_Left dock" -msgstr "" +#~ msgid "No \"right\" attribute on element <%s>" +#~ msgstr "Tiada atribut \"right\" pada unsur <%s>" -#: ../src/theme-viewer.c:79 -msgid "/Windows/_Right dock" -msgstr "" +#~ msgid "Border \"%s\" is unknown" +#~ msgstr "Sempadan \"%s\" tidak diketahui" -#: ../src/theme-viewer.c:80 -msgid "/Windows/_All docks" -msgstr "/Tetingkap/_Semua dok" +#~ msgid "No \"color\" attribute on element <%s>" +#~ msgstr "Tiada atribut \"color\" pada unsur <%s>" -#: ../src/theme-viewer.c:81 -msgid "/Windows/Des_ktop" -msgstr "/Tetingkap/Des_ktop" +#~ msgid "No \"x1\" attribute on element <%s>" +#~ msgstr "Tiada atribut \"x1\" pada unsur <%s>" -#: ../src/theme-viewer.c:131 -msgid "Open another one of these windows" -msgstr "Buka lagi satu tetingkap ini" +#~ msgid "No \"y1\" attribute on element <%s>" +#~ msgstr "Tiada atribut \"y1\" pada unsur <%s>" -#: ../src/theme-viewer.c:138 -msgid "This is a demo button with an 'open' icon" -msgstr "Ini adalah demo dengan butang 'buka'" +#~ msgid "No \"x2\" attribute on element <%s>" +#~ msgstr "Tiada atribut \"x2\" pada unsur <%s>" -#: ../src/theme-viewer.c:145 -msgid "This is a demo button with a 'quit' icon" -msgstr "Ini adalah demo dengan butang 'keluar'" +#~ msgid "No \"y2\" attribute on element <%s>" +#~ msgstr "Tiada atribut \"y2\" pada unsur <%s>" -#: ../src/theme-viewer.c:241 -msgid "This is a sample message in a sample dialog" -msgstr "" +#~ msgid "No \"x\" attribute on element <%s>" +#~ msgstr "Tiada atribut \"x\" pada unsur <%s>" -#: ../src/theme-viewer.c:324 -#, c-format -msgid "Fake menu item %d\n" -msgstr "Item menu palsu %d\n" +#~ msgid "No \"y\" attribute on element <%s>" +#~ msgstr "Tiada atribut \"y\" pada unsur <%s>" -#: ../src/theme-viewer.c:358 -msgid "Border-only window" -msgstr "Tetingkap sempadan-sahaja" +#~ msgid "No \"width\" attribute on element <%s>" +#~ msgstr "Tiada atribut \"width\" pada unsur <%s>" -#: ../src/theme-viewer.c:360 -msgid "Bar" -msgstr "Bar" +#~ msgid "No \"height\" attribute on element <%s>" +#~ msgstr "Tiada atribut \"height\" pada unsur <%s>" -#: ../src/theme-viewer.c:377 -msgid "Normal Application Window" -msgstr "Tetingkap Aplikasi Normal" +#~ msgid "No \"start_angle\" attribute on element <%s>" +#~ msgstr "Tiada atribut \"start_angle\" pada unsur <%s>" -#: ../src/theme-viewer.c:382 -msgid "Dialog Box" -msgstr "Kekotak Dialog" +#~ msgid "No \"extent_angle\" attribute on element <%s>" +#~ msgstr "Tiada atribut \"extent_angle\" pada unsur <%s>" -#: ../src/theme-viewer.c:387 -msgid "Modal Dialog Box" -msgstr "Kekotak Dialog Modal" +#~ msgid "No \"alpha\" attribute on element <%s>" +#~ msgstr "Tiada atribut \"alpha\" pada unsur <%s>" -#: ../src/theme-viewer.c:392 -msgid "Utility Palette" -msgstr "Palet Utiliti" +#~ msgid "No \"type\" attribute on element <%s>" +#~ msgstr "Tiada atribut \"type\" pada unsur <%s>" -#: ../src/theme-viewer.c:397 -msgid "Torn-off Menu" -msgstr "" +#~ msgid "Did not understand value \"%s\" for type of gradient" +#~ msgstr "Tak memahami nilai \"%s\" bagi jenis gradien" -#: ../src/theme-viewer.c:402 -msgid "Border" -msgstr "Sempadan" +#~ msgid "No \"filename\" attribute on element <%s>" +#~ msgstr "Tiada atribut \"filename\" pada unsur <%s>" -#: ../src/theme-viewer.c:731 -#, c-format -msgid "Button layout test %d" -msgstr "" +#~ msgid "Did not understand fill type \"%s\" for <%s> element" +#~ msgstr "Tidak memahami jenis isi \"%s\" pada unsur <%s>" -#: ../src/theme-viewer.c:760 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "" +#~ msgid "No \"state\" attribute on element <%s>" +#~ msgstr "Tiada atribut \"state\" pada unsur <%s>" -#: ../src/theme-viewer.c:803 -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Penggunaan: metacity-theme-viewer [THEMENAME]\n" +#~ msgid "No \"shadow\" attribute on element <%s>" +#~ msgstr "Tiada atribut \"shadow\" pada unsur <%s>" -#: ../src/theme-viewer.c:810 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "Ralat memuatkan tema: %s\n" +#~ msgid "No \"arrow\" attribute on element <%s>" +#~ msgstr "Tiada atribut \"arrow\" pada unsur <%s>" -#: ../src/theme-viewer.c:816 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "Tema \"%s\" dimuatkan dalam %g saat\n" +#~ msgid "Did not understand state \"%s\" for <%s> element" +#~ msgstr "Tak memahami keadaan \"%s\" bagi unsur <%s>" -#: ../src/theme-viewer.c:839 -msgid "Normal Title Font" -msgstr "Font Tajuk Normal" +#~ msgid "Did not understand shadow \"%s\" for <%s> element" +#~ msgstr "Tak memahami bebayang \"%s\" bagi unsur <%s>" -#: ../src/theme-viewer.c:845 -msgid "Small Title Font" -msgstr "Font Tajuk Kecil" +#~ msgid "Did not understand arrow \"%s\" for <%s> element" +#~ msgstr "Tak memahami panah \"%s\" bagi unsur <%s>" -#: ../src/theme-viewer.c:851 -msgid "Large Title Font" -msgstr "Font Tajuk Besar" +#~ msgid "No <draw_ops> called \"%s\" has been defined" +#~ msgstr "Tiada <draw_ops> yg dipanggil \"%s\" telah ditakrifkan" -#: ../src/theme-viewer.c:856 -msgid "Button Layouts" -msgstr "Susunatur Butang" +#~ msgid "Including draw_ops \"%s\" here would create a circular reference" +#~ msgstr "Penyertaan draw_ops \"%s\" di sini akan mencipta rujukan bergelung" -#: ../src/theme-viewer.c:861 -msgid "Benchmark" -msgstr "" +#~ msgid "No \"value\" attribute on <%s> element" +#~ msgstr "Tiada atribut \"value\" pada unsur <%s>" -#: ../src/theme-viewer.c:908 -msgid "Window Title Goes Here" -msgstr "Tajuk Tetingkap di sini" +#~ msgid "No \"position\" attribute on <%s> element" +#~ msgstr "Tiada atribut \"position\" pada unsur <%s>" -#: ../src/theme-viewer.c:1012 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" +#~ msgid "Unknown position \"%s\" for frame piece" +#~ msgstr "Posisi tidak diketahui \"%s\" bagi serpihan kerangka" -#: ../src/theme-viewer.c:1227 -msgid "position expression test returned TRUE but set error" -msgstr "" +#~ msgid "No \"function\" attribute on <%s> element" +#~ msgstr "Tiada atribut \"function\" pada unsur <%s>" -#: ../src/theme-viewer.c:1229 -msgid "position expression test returned FALSE but didn't set error" -msgstr "" +#~ msgid "No \"state\" attribute on <%s> element" +#~ msgstr "Tiada atribut \"focus\" pada unsur <%s>" -#: ../src/theme-viewer.c:1233 -msgid "Error was expected but none given" -msgstr "" +#~ msgid "Unknown function \"%s\" for button" +#~ msgstr "Fungsi \"%s\" tidak diketahui bagi butang" -#: ../src/theme-viewer.c:1235 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "" +#~ msgid "Unknown state \"%s\" for button" +#~ msgstr "Keadaan \"%s\" tidak diketahui bagi butang" -#: ../src/theme-viewer.c:1241 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "" +#~ msgid "No \"focus\" attribute on <%s> element" +#~ msgstr "Tiada atribut \"focus\" pada unsur <%s>" -#: ../src/theme-viewer.c:1245 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "nilai x adalah %d, %d dijangka" +#~ msgid "No \"style\" attribute on <%s> element" +#~ msgstr "Tiada atribut \"style\" pada unsur <%s>" -#: ../src/theme-viewer.c:1248 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "" +#~ msgid "\"%s\" is not a valid value for focus attribute" +#~ msgstr "\"%s\" adalah bukan nilai atribut fokus yang sah" -#: ../src/theme-viewer.c:1310 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "" +#~ msgid "\"%s\" is not a valid value for state attribute" +#~ msgstr "\"%s\" adalah bukan nilai sah bagi atribut keadaan" -#: ../src/theme.c:202 -msgid "top" -msgstr "atas" +#~ msgid "A style called \"%s\" has not been defined" +#~ msgstr "Gaya yang dipanggil \"%s\" tidak ditakrifkan" -#: ../src/theme.c:204 -msgid "bottom" -msgstr "bawah" +#~ msgid "No \"resize\" attribute on <%s> element" +#~ msgstr "Tiada atribut \"resize\" pada unsur <%s>" -#: ../src/theme.c:206 -msgid "left" -msgstr "kiri" +#~ msgid "\"%s\" is not a valid value for resize attribute" +#~ msgstr "\"%s\" adalah bukan nilai atribut ubahsaiz yang sah" -#: ../src/theme.c:208 -msgid "right" -msgstr "kanan" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized/shaded " +#~ "states" +#~ msgstr "" +#~ "Tak sepatutnya mempunyai atribut \"resize\" pada unsur <%s> untuk " +#~ "keadaan maksimum/gulung" -#: ../src/theme.c:222 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "geometri kerangka tidak menyatakan dimensi \"%s\" " +#~ msgid "Style has already been specified for state %s resize %s focus %s" +#~ msgstr "Gaya telah dinyatakan bagi keadaan %s ubahsaiz %s fokus %s" -#: ../src/theme.c:241 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "" +#~ msgid "Style has already been specified for state %s focus %s" +#~ msgstr "Gaya telah dinyatakan bagi keadaan %s fokus %s" -#: ../src/theme.c:278 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "Nisbah aspek butang %g adalah tidak masuk akal" +#~ msgid "" +#~ "Element <%s> is not allowed inside a name/author/date/description element" +#~ msgstr "" +#~ "Unsur <%s> tidak diizinkan di dalam unsur name/author/date/description" -#: ../src/theme.c:290 -msgid "Frame geometry does not specify size of buttons" -msgstr "Geometri kerangka tidak menyatakan saiz butang" +#~ msgid "Element <%s> is not allowed inside a <constant> element" +#~ msgstr "Unsur <%s> tidak diizinkan di dalam unsur <constant>" -#: ../src/theme.c:843 -msgid "Gradients should have at least two colors" -msgstr "Gradien sepatutnya mempunyai sekurang-kurang dua warna" +#~ msgid "" +#~ "Element <%s> is not allowed inside a distance/border/aspect_ratio element" +#~ msgstr "" +#~ "Unsur <%s> tak diizinkan di dalan unsur distance/border/aspect_ratio" -#: ../src/theme.c:969 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" +#~ msgid "Element <%s> is not allowed inside a draw operation element" +#~ msgstr "Unsur <%s> tidak diizinkan di dalam unsur operasi lukisan" -#: ../src/theme.c:983 -#, c-format -msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "" +#~ msgid "Element <%s> is not allowed inside a <%s> element" +#~ msgstr "Unsur <%s> tidak diizinkan di dalam unsur <%s>" -#: ../src/theme.c:994 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "" +#~ msgid "No draw_ops provided for button" +#~ msgstr "Tiada draw_ops dibekalkan untuk butang" -#: ../src/theme.c:1007 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "Tak memahami komponen warna \"%s\" pada spesifikasi warna" +#~ msgid "No draw_ops provided for menu icon" +#~ msgstr "Tiada draw_ops dibekalkan bagi ikon menu" -#: ../src/theme.c:1037 -#, c-format -msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" -msgstr "" +#~ msgid "No text is allowed inside element <%s>" +#~ msgstr "Teks tidak diizinkan di dalam unsur <%s>" -#: ../src/theme.c:1048 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "" +#~ msgid "<name> specified twice for this theme" +#~ msgstr "<nama> dinyatakan dua kali pada tema ini" -#: ../src/theme.c:1058 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "" +#~ msgid "<author> specified twice for this theme" +#~ msgstr "<author> dinyatakan dua kali pada tema ini" -#: ../src/theme.c:1105 -#, c-format -msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "" +#~ msgid "<copyright> specified twice for this theme" +#~ msgstr "<copyright> dinyatakan dua kali pada tema ini" -#: ../src/theme.c:1116 -#, fuzzy, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "Tak dapat mencipta direktori %s: %s\n" +#~ msgid "<date> specified twice for this theme" +#~ msgstr "<date> dinyatakan dua kali pada tema ini" -#: ../src/theme.c:1126 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "" +#~ msgid "<description> specified twice for this theme" +#~ msgstr "<description> dinyatakan dua kali pada tema ini" -#: ../src/theme.c:1155 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Tak dapat menghantar warna \"%s\"" +#~ msgid "Failed to read theme from file %s: %s\n" +#~ msgstr "Gagal dapat baca tema dari fail %s: %s\n" -#: ../src/theme.c:1417 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "Penyataan kordinat mengandungi aksara '%s' yang tidak diizinkan" +#~ msgid "Theme file %s did not contain a root <metacity_theme> element" +#~ msgstr "Fail tema %s tak mengandungi unsur root <metacity_theme>" -#: ../src/theme.c:1444 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "" -"Penyataan koordinat mengandungi nombor titik apungan '%s' yang tak dpaat " -"dihantar" +#~ msgid "/Windows/tearoff" +#~ msgstr "/Tetingkap/koyak" -#: ../src/theme.c:1458 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "Penyataan kordinat mengandungi integer '%s' yang tak boleh dihantar" +#~ msgid "/Windows/_Dialog" +#~ msgstr "/Tetingkap/_Dialog" -#: ../src/theme.c:1525 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "Ungkapan kordinat mengandungi operator pada permulaan teks ini: \"%s\"" +#~ msgid "/Windows/_Modal dialog" +#~ msgstr "/Tetingkap/Dialog _modal" -#: ../src/theme.c:1582 -msgid "Coordinate expression was empty or not understood" -msgstr "Penyataan kordinat kosong dan tidak difahami" +#~ msgid "/Windows/_Utility" +#~ msgstr "/Tetingkap/_Utiliti" -#: ../src/theme.c:1725 ../src/theme.c:1735 ../src/theme.c:1769 -msgid "Coordinate expression results in division by zero" -msgstr "Penyataan kordinat dibahagi sifar" +#~ msgid "/Windows/_Top dock" +#~ msgstr "/Tetingkap/Dok _atas" -#: ../src/theme.c:1777 -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "" -"Penyatana kordinat cuba menggunakan operator mod pada nombor titik apungan" +#~ msgid "/Windows/_All docks" +#~ msgstr "/Tetingkap/_Semua dok" -#: ../src/theme.c:1834 -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "Ungkapan kordinat mempunyai operator \"%s\" dimana operand dijangka" +#~ msgid "/Windows/Des_ktop" +#~ msgstr "/Tetingkap/Des_ktop" -#: ../src/theme.c:1843 -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "Penyataan kordinat mempunyai operand dimana operator diperlukan" +#~ msgid "Open another one of these windows" +#~ msgstr "Buka lagi satu tetingkap ini" -#: ../src/theme.c:1851 -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "Penyataan kordinat ditamatkan dengan operator selain daripada operand" +#~ msgid "This is a demo button with an 'open' icon" +#~ msgstr "Ini adalah demo dengan butang 'buka'" -#: ../src/theme.c:1861 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" -"Penyataan kordinat mempunyai operator \"%c\" selepas operator \"%c\" tanpa " -"operand diantaranya" +#~ msgid "This is a demo button with a 'quit' icon" +#~ msgstr "Ini adalah demo dengan butang 'keluar'" -#: ../src/theme.c:1980 -msgid "" -"Coordinate expression parser overflowed its buffer, this is really a " -"Metacity bug, but are you sure you need a huge expression like that?" -msgstr "" -"Penghantar penyataan kordinat telah overflow buffernya, ini memang pepijat " -"metacity, tetapi anda pasti memerlukan penyataan yang besar sebegitu?" +#~ msgid "Fake menu item %d\n" +#~ msgstr "Item menu palsu %d\n" -#: ../src/theme.c:2009 -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "Penyataan kordinat mempunyai penutup kurungan tanpa pembuka kurungan" +#~ msgid "Border-only window" +#~ msgstr "Tetingkap sempadan-sahaja" -#: ../src/theme.c:2072 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "" -"Ungkapan kordinat mempunyai pembolehubah atau pemalar tidak diketahui \"%s\"" +#~ msgid "Bar" +#~ msgstr "Bar" -#: ../src/theme.c:2129 -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "\"Penyataan kordinat mempunyai membuka kurungan tanpa penutup kurungan" +#~ msgid "Normal Application Window" +#~ msgstr "Tetingkap Aplikasi Normal" -#: ../src/theme.c:2140 -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "Penyataan kordinat tidak mempunyai operator atau operand" +#~ msgid "Dialog Box" +#~ msgstr "Kekotak Dialog" -#: ../src/theme.c:2384 ../src/theme.c:2406 ../src/theme.c:2427 -#, c-format -msgid "Theme contained an expression \"%s\" that resulted in an error: %s\n" -msgstr "Tema mengandungi penyataan \"%s\" yang menyebabkan ralat: %s\n" +#~ msgid "Modal Dialog Box" +#~ msgstr "Kekotak Dialog Modal" -#: ../src/theme.c:3913 -#, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> mesti " -"dinyatakan bagi gaya kerangka ini" +#~ msgid "Utility Palette" +#~ msgstr "Palet Utiliti" -#: ../src/theme.c:4363 ../src/theme.c:4395 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" -"Kehilangan <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/" -">" +#~ msgid "Border" +#~ msgstr "Sempadan" -#: ../src/theme.c:4446 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Gagal memuatkan tema \"%s\": %s\n" +#~ msgid "Usage: metacity-theme-viewer [THEMENAME]\n" +#~ msgstr "Penggunaan: metacity-theme-viewer [THEMENAME]\n" -#: ../src/theme.c:4592 ../src/theme.c:4599 ../src/theme.c:4606 -#: ../src/theme.c:4613 ../src/theme.c:4620 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "Tiada <%s> ditetapkan untuk tema \"%s\"" +#~ msgid "Error loading theme: %s\n" +#~ msgstr "Ralat memuatkan tema: %s\n" -#: ../src/theme.c:4630 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" +#~ msgid "Loaded theme \"%s\" in %g seconds\n" +#~ msgstr "Tema \"%s\" dimuatkan dalam %g saat\n" -#: ../src/theme.c:4652 -#, c-format -msgid "" -"<menu_icon function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this theme" -msgstr "" -"<menu_icon function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> mesti " -"dinyatakan bagi tema ini" +#~ msgid "Normal Title Font" +#~ msgstr "Font Tajuk Normal" -#: ../src/theme.c:5041 ../src/theme.c:5103 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" +#~ msgid "Small Title Font" +#~ msgstr "Font Tajuk Kecil" -#: ../src/theme.c:5049 ../src/theme.c:5111 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "Konstans \"%s\" sudah ditakrifkan" +#~ msgid "Large Title Font" +#~ msgstr "Font Tajuk Besar" -#: ../src/util.c:93 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Gagal untuk membuka log nyahpepijat: %s\n" +#~ msgid "Button Layouts" +#~ msgstr "Susunatur Butang" -#: ../src/util.c:103 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Gagal untuk fdopen() fail log %sl: %s\n" +#~ msgid "Window Title Goes Here" +#~ msgstr "Tajuk Tetingkap di sini" -#: ../src/util.c:109 -#, c-format -msgid "Opened log file %s\n" -msgstr "Fail log %s dibuka\n" +#~ msgid "x value was %d, %d was expected" +#~ msgstr "nilai x adalah %d, %d dijangka" -#: ../src/util.c:203 -msgid "Window manager: " -msgstr "pengurus tetingkap:" +#~ msgid "top" +#~ msgstr "atas" -#: ../src/util.c:349 -msgid "Bug in window manager: " -msgstr "Pepijat pada pengurus tetingkap: " +#~ msgid "bottom" +#~ msgstr "bawah" -#: ../src/util.c:378 -msgid "Window manager warning: " -msgstr "Amaran pengurus tetingkap:" +#~ msgid "left" +#~ msgstr "kiri" -#: ../src/util.c:402 -msgid "Window manager error: " -msgstr "Ralat pengurus tetingkap:" +#~ msgid "right" +#~ msgstr "kanan" -#: ../src/window-props.c:162 -#, c-format -msgid "Application set a bogus _NET_WM_PID %ld\n" -msgstr "" +#~ msgid "frame geometry does not specify \"%s\" dimension" +#~ msgstr "geometri kerangka tidak menyatakan dimensi \"%s\" " -#. first time through -#: ../src/window.c:5205 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" +#~ msgid "Button aspect ratio %g is not reasonable" +#~ msgstr "Nisbah aspek butang %g adalah tidak masuk akal" -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/window.c:5876 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %" -"d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" +#~ msgid "Frame geometry does not specify size of buttons" +#~ msgstr "Geometri kerangka tidak menyatakan saiz butang" -#: ../src/xprops.c:153 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"Tetingkap 0x%lx mempunyai ciri-ciri %s \n" -"yang dijangka mempunyai jenis %s format %d\n" -" dan sebenarnya mempunyai jenis %s format %d n_items %d\n" -"Ianya mungkin pepijat aplikasi, bukan pengurus tetingkap.\n" -"Tetingkap membunyai title=\"%s\" class=\"%s\" name=\"%s\"\n" +#~ msgid "Gradients should have at least two colors" +#~ msgstr "Gradien sepatutnya mempunyai sekurang-kurang dua warna" -#: ../src/xprops.c:399 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "Ciri-ciri %s pada tetingkap 0x%lx mengandungi UTF-8 yang tidak sah\n" +#~ msgid "Did not understand color component \"%s\" in color specification" +#~ msgstr "Tak memahami komponen warna \"%s\" pada spesifikasi warna" -#: ../src/xprops.c:482 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"Ciri-ciri %s pada tetingkap 0x%lx mengandungi UTF-8 yang tidak sah bagi " -"item %d pada senarai\n" +#, fuzzy +#~ msgid "Could not parse shade factor \"%s\" in shaded color" +#~ msgstr "Tak dapat mencipta direktori %s: %s\n" + +#~ msgid "Could not parse color \"%s\"" +#~ msgstr "Tak dapat menghantar warna \"%s\"" + +#~ msgid "Coordinate expression contains character '%s' which is not allowed" +#~ msgstr "Penyataan kordinat mengandungi aksara '%s' yang tidak diizinkan" + +#~ msgid "" +#~ "Coordinate expression contains floating point number '%s' which could not " +#~ "be parsed" +#~ msgstr "" +#~ "Penyataan koordinat mengandungi nombor titik apungan '%s' yang tak dpaat " +#~ "dihantar" + +#~ msgid "" +#~ "Coordinate expression contains integer '%s' which could not be parsed" +#~ msgstr "Penyataan kordinat mengandungi integer '%s' yang tak boleh dihantar" + +#~ msgid "" +#~ "Coordinate expression contained unknown operator at the start of this " +#~ "text: \"%s\"" +#~ msgstr "" +#~ "Ungkapan kordinat mengandungi operator pada permulaan teks ini: \"%s\"" + +#~ msgid "Coordinate expression was empty or not understood" +#~ msgstr "Penyataan kordinat kosong dan tidak difahami" + +#~ msgid "Coordinate expression results in division by zero" +#~ msgstr "Penyataan kordinat dibahagi sifar" + +#~ msgid "" +#~ "Coordinate expression tries to use mod operator on a floating-point number" +#~ msgstr "" +#~ "Penyatana kordinat cuba menggunakan operator mod pada nombor titik apungan" + +#~ msgid "" +#~ "Coordinate expression has an operator \"%s\" where an operand was expected" +#~ msgstr "Ungkapan kordinat mempunyai operator \"%s\" dimana operand dijangka" + +#~ msgid "Coordinate expression had an operand where an operator was expected" +#~ msgstr "Penyataan kordinat mempunyai operand dimana operator diperlukan" + +#~ msgid "Coordinate expression ended with an operator instead of an operand" +#~ msgstr "" +#~ "Penyataan kordinat ditamatkan dengan operator selain daripada operand" + +#~ msgid "" +#~ "Coordinate expression has operator \"%c\" following operator \"%c\" with " +#~ "no operand in between" +#~ msgstr "" +#~ "Penyataan kordinat mempunyai operator \"%c\" selepas operator \"%c\" " +#~ "tanpa operand diantaranya" + +#~ msgid "" +#~ "Coordinate expression parser overflowed its buffer, this is really a " +#~ "Metacity bug, but are you sure you need a huge expression like that?" +#~ msgstr "" +#~ "Penghantar penyataan kordinat telah overflow buffernya, ini memang " +#~ "pepijat metacity, tetapi anda pasti memerlukan penyataan yang besar " +#~ "sebegitu?" + +#~ msgid "" +#~ "Coordinate expression had a close parenthesis with no open parenthesis" +#~ msgstr "" +#~ "Penyataan kordinat mempunyai penutup kurungan tanpa pembuka kurungan" + +#~ msgid "Coordinate expression had unknown variable or constant \"%s\"" +#~ msgstr "" +#~ "Ungkapan kordinat mempunyai pembolehubah atau pemalar tidak diketahui \"%s" +#~ "\"" + +#~ msgid "" +#~ "Coordinate expression had an open parenthesis with no close parenthesis" +#~ msgstr "" +#~ "\"Penyataan kordinat mempunyai membuka kurungan tanpa penutup kurungan" + +#~ msgid "Coordinate expression doesn't seem to have any operators or operands" +#~ msgstr "Penyataan kordinat tidak mempunyai operator atau operand" + +#~ msgid "Theme contained an expression \"%s\" that resulted in an error: %s\n" +#~ msgstr "Tema mengandungi penyataan \"%s\" yang menyebabkan ralat: %s\n" + +#~ msgid "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " +#~ "specified for this frame style" +#~ msgstr "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> mesti " +#~ "dinyatakan bagi gaya kerangka ini" + +#~ msgid "" +#~ "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/" +#~ ">" +#~ msgstr "" +#~ "Kehilangan <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever" +#~ "\"/>" + +#~ msgid "Failed to load theme \"%s\": %s\n" +#~ msgstr "Gagal memuatkan tema \"%s\": %s\n" + +#~ msgid "No <%s> set for theme \"%s\"" +#~ msgstr "Tiada <%s> ditetapkan untuk tema \"%s\"" + +#~ msgid "" +#~ "<menu_icon function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " +#~ "specified for this theme" +#~ msgstr "" +#~ "<menu_icon function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> mesti " +#~ "dinyatakan bagi tema ini" + +#~ msgid "Constant \"%s\" has already been defined" +#~ msgstr "Konstans \"%s\" sudah ditakrifkan" + +#~ msgid "Failed to open debug log: %s\n" +#~ msgstr "Gagal untuk membuka log nyahpepijat: %s\n" + +#~ msgid "Failed to fdopen() log file %s: %s\n" +#~ msgstr "Gagal untuk fdopen() fail log %sl: %s\n" + +#~ msgid "Opened log file %s\n" +#~ msgstr "Fail log %s dibuka\n" + +#~ msgid "Window manager: " +#~ msgstr "pengurus tetingkap:" + +#~ msgid "Window manager warning: " +#~ msgstr "Amaran pengurus tetingkap:" + +#~ msgid "Window manager error: " +#~ msgstr "Ralat pengurus tetingkap:" + +#~ msgid "" +#~ "Window 0x%lx has property %s\n" +#~ "that was expected to have type %s format %d\n" +#~ "and actually has type %s format %d n_items %d.\n" +#~ "This is most likely an application bug, not a window manager bug.\n" +#~ "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +#~ msgstr "" +#~ "Tetingkap 0x%lx mempunyai ciri-ciri %s \n" +#~ "yang dijangka mempunyai jenis %s format %d\n" +#~ " dan sebenarnya mempunyai jenis %s format %d n_items %d\n" +#~ "Ianya mungkin pepijat aplikasi, bukan pengurus tetingkap.\n" +#~ "Tetingkap membunyai title=\"%s\" class=\"%s\" name=\"%s\"\n" + +#~ msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +#~ msgstr "" +#~ "Ciri-ciri %s pada tetingkap 0x%lx mengandungi UTF-8 yang tidak sah\n" + +#~ msgid "" +#~ "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the " +#~ "list\n" +#~ msgstr "" +#~ "Ciri-ciri %s pada tetingkap 0x%lx mengandungi UTF-8 yang tidak sah bagi " +#~ "item %d pada senarai\n" diff --git a/po/nb.po b/po/nb.po index 6cfc680c4..f010e891d 100644 --- a/po/nb.po +++ b/po/nb.po @@ -1,411 +1,289 @@ -# Norwegian bokmål translation of muffin. +# Norwegian bokmål translation of mutter. # Copyright © 2002-2004 Free Software Foundation, Inc. -# Kjartan Maraas <kmaraas@gnome.org>, 2002-2012. +# Kjartan Maraas <kmaraas@gnome.org>, 2002-2017. # msgid "" msgstr "" -"Project-Id-Version: muffin 3.3.x\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-03-12 18:54+0100\n" -"PO-Revision-Date: 2012-03-12 18:54+0100\n" +"Project-Id-Version: mutter 3.27.x\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=mutter&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-11-10 18:31+0000\n" +"PO-Revision-Date: 2017-11-11 18:19+0100\n" "Last-Translator: Kjartan Maraas <kmaraas@gnome.org>\n" "Language-Team: Norwegian bokmål <i18n-no@lister.ping.uio.no>\n" -"Language: \n" +"Language: nb\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: ../src/50-muffin-windows.xml.in.h:1 -msgid "Windows" -msgstr "Vinduer" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Navigasjon" -#: ../src/50-muffin-windows.xml.in.h:2 -msgid "View split on left" -msgstr "Visning delt til venstre" +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Flytt vindu til arbeidsområde 1" -#: ../src/50-muffin-windows.xml.in.h:3 -msgid "View split on right" -msgstr "Visning delt til høyre" +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Flytt vindu til arbeidsområde 2" -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format -msgid "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." -msgstr "En annen compositing manager kjører skjerm %i på display «%s»." +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Flytt vindu til arbeidsområde 3" -#: ../src/core/bell.c:307 -msgid "Bell event" -msgstr "Klokkehendelse" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Flytt vindu til arbeidsområde 4" -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Ukjent forespørsel om vindusinformasjon: %d" +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Flytt vindu til siste arbeidsområde" -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> svarer ikke." +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace to the left" +msgstr "Flytt vindu ett arbeidsområde til venstre" -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "Programmet svarer ikke." +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace to the right" +msgstr "Flytt vindu ett arbeidsområde til høyre" -#: ../src/core/delete.c:119 -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "" -"Du kan velge å vente en kort stund for å se om det fortsetter eller tvinge " -"programmet til å avslutte helt." +#: data/50-mutter-navigation.xml:30 +msgid "Move window one workspace up" +msgstr "Flytt vindu ett arbeidsområde opp" -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "_Vent" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one workspace down" +msgstr "Flytt vindu ett arbeidsområde ned" -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "_Tvungen nedstenging" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor to the left" +msgstr "Flytt vindu en skjerm til venstre" -#: ../src/core/display.c:361 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "Mangler utvidelsen %s som kreves for komposittfunksjon" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor to the right" +msgstr "Flytt vindu en skjerm til høyre" -#: ../src/core/display.c:427 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Feil under åpning av X Window System skjerm «%s»\n" +#: data/50-mutter-navigation.xml:42 +msgid "Move window one monitor up" +msgstr "Flytt vindu en skjerm opp" -#: ../src/core/keybindings.c:852 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "" -"Et annet program bruker allerede nøkkelen %s med modifikatorer %x som " -"binding\n" +#: data/50-mutter-navigation.xml:45 +msgid "Move window one monitor down" +msgstr "Flytt vindu en skjerm ned" -#: ../src/core/main.c:206 -msgid "Disable connection to session manager" -msgstr "Deaktiver tilkobling til sesjonshåndtereren" +#: data/50-mutter-navigation.xml:49 +msgid "Switch applications" +msgstr "Bytt programmer" -#: ../src/core/main.c:212 -msgid "Replace the running window manager" -msgstr "Erstatt kjørende vindushåndterer" +#: data/50-mutter-navigation.xml:54 +msgid "Switch to previous application" +msgstr "Bytt til forrige program" -#: ../src/core/main.c:218 -msgid "Specify session management ID" -msgstr "Oppgi sesjonshåndterings-ID" +#: data/50-mutter-navigation.xml:58 +msgid "Switch windows" +msgstr "Bytt vinduer" -#: ../src/core/main.c:223 -msgid "X Display to use" -msgstr "X-skjerm som skal brukes" +#: data/50-mutter-navigation.xml:63 +msgid "Switch to previous window" +msgstr "Bytt forrige vindu" -#: ../src/core/main.c:229 -msgid "Initialize session from savefile" -msgstr "Initier sesjonen fra en lagret fil" +#: data/50-mutter-navigation.xml:67 +msgid "Switch windows of an application" +msgstr "Bytt mellom et programs vinduer" -#: ../src/core/main.c:235 -msgid "Make X calls synchronous" -msgstr "Gjør X-kall synkrone" +#: data/50-mutter-navigation.xml:72 +msgid "Switch to previous window of an application" +msgstr "Bytt til forrige vindu i et program" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Feil under søk i temakatalog: %s\n" +#: data/50-mutter-navigation.xml:76 +msgid "Switch system controls" +msgstr "Bytt systemkontroller" -#: ../src/core/main.c:520 -#, c-format -msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "" -"Kunne ikke finne et tema! Sjekk at %s eksisterer og inneholder de vanlige " -"temaene.\n" +#: data/50-mutter-navigation.xml:81 +msgid "Switch to previous system control" +msgstr "Bytt til forrige systemkontroll" -#: ../src/core/muffin.c:40 -#, c-format -msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" -"muffin %s\n" -"Opphavsrett © 2001-%d Havoc Pennington, Red Hat, Inc, og andre\n" -"Dette er fri programvare; se i kildekoden for kopibetingelser.\n" -"Det gis INGEN garanti.\n" +#: data/50-mutter-navigation.xml:85 +msgid "Switch windows directly" +msgstr "Bytt vinduer direkte" -#: ../src/core/muffin.c:54 -msgid "Print version" -msgstr "Skriv versjonsnummer" +#: data/50-mutter-navigation.xml:90 +msgid "Switch directly to previous window" +msgstr "Bytt direkte til forrige vindu" -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "Kommaseparert liste av tillegg for compositor" +#: data/50-mutter-navigation.xml:94 +msgid "Switch windows of an app directly" +msgstr "Bytt mellom et programs vinduer direkte" -#: ../src/core/prefs.c:1077 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"Funksjonalitet for å gå rundt ødelagte programmer er deaktivert. Noen " -"programmer vil kanskje ikke oppføre seg korrekt.\n" +#: data/50-mutter-navigation.xml:99 +msgid "Switch directly to previous window of an app" +msgstr "Bytt direkte til forrive vindu i et program" -#: ../src/core/prefs.c:1152 -#, c-format -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "Kunne ikke tolke skriftbeskrivelsen «%s» fra GSettings-nøkkel %s\n" +#: data/50-mutter-navigation.xml:103 +msgid "Switch system controls directly" +msgstr "Bytt systemkontroller direkte" -#: ../src/core/prefs.c:1218 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"«%s» funnet i konfigurasjonsdatabasen er ikke en gyldig verdi for endring av " -"musknapp\n" +#: data/50-mutter-navigation.xml:108 +msgid "Switch directly to previous system control" +msgstr "Bytt direkte til forrige systemkontroll" -#: ../src/core/prefs.c:1739 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "" -"«%s» funnet i konfigurasjonsdatabasen er ikke en gyldig verdi for " -"tastaturbinding «%s»\n" +#: data/50-mutter-navigation.xml:111 +msgid "Hide all normal windows" +msgstr "Skjul alle normale vinduer" -#: ../src/core/prefs.c:1836 -#, c-format -msgid "Workspace %d" -msgstr "Arbeidsområde %d" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 1" +msgstr "Bytt til arbeidsområde 1" -#: ../src/core/screen.c:730 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "Skjerm %d på display «%s» er ugyldig\n" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 2" +msgstr "Bytt til arbeidsområde 2" -#: ../src/core/screen.c:746 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"Skjerm %d på display «%s» har allerede en vindushåndterer; prøv å bruke " -"flagget --replace for å erstatte aktiv vindushåndterer.\n" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to workspace 3" +msgstr "Bytt til arbeidsområde 3" -#: ../src/core/screen.c:773 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "" -"Kunne ikke hente utvalg fra vinduhåndterer på skjerm %d, display «%s»\n" +#: data/50-mutter-navigation.xml:123 +msgid "Switch to workspace 4" +msgstr "Bytt til arbeidsområde 4" -#: ../src/core/screen.c:828 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "Skjerm %d på display «%s» har allerede en vinduhåndterer\n" +#: data/50-mutter-navigation.xml:126 +msgid "Switch to last workspace" +msgstr "Bytt til siste arbeidsområde" -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "Kunne ikke slippe skjerm %d på display «%s»\n" +#: data/50-mutter-navigation.xml:129 +msgid "Move to workspace left" +msgstr "Flytt til arbeidsområdet til venstre" -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Kunne ikke opprette katalog «%s»: %s\n" +#: data/50-mutter-navigation.xml:132 +msgid "Move to workspace right" +msgstr "Flytt til arbeidsområdet til høyre" -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "Kunne ikke åpne sesjonsfil «%s» for skriving: %s\n" +#: data/50-mutter-navigation.xml:135 +msgid "Move to workspace above" +msgstr "Flytt til arbeidsområdet over" -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Feil under skriving av sesjonsfil «%s»: %s\n" +#: data/50-mutter-navigation.xml:138 +msgid "Move to workspace below" +msgstr "Flytt til arbeidsområdet under" -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Feil under lukking av sesjonsfil «%s»: %s\n" +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "System" -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Feil under tolking av lagret sesjonsfil: %s\n" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Vis kommandolinje" -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "<muffin_session>-attributt sett men vi har allerede sesjons-ID" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Vis oversikt over aktiviteter" -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Ukjent attributt %s på <%s>-element" +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Gjenopprett tastatursnarveier" -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "<window> tag med flere nivåer" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Vinduer" -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "Ukjent element %s" +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "Aktiver vindumenyen" -#: ../src/core/session.c:1809 -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" -"Disse vinduene støtter ikke "lagre aktiv konfigurasjon"og vil " -"måtte startes på nytt manuelt neste gang du logger inn." +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Slå av/på fullskjermmodus" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Feil under åpning av feilsøkingslogg: %s\n" +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "Endre tilstand for maksimering" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Feil under fdopen() av loggfil %s: %s\n" +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "Maksimer vindu" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "Åpnet loggfil %s\n" +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Gjenopprett vindu" -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "Muffin er kompilert uten støtte for «verbose» modus\n" +#: data/50-mutter-windows.xml:18 +msgid "Toggle shaded state" +msgstr "Endre tilstand for skyggelegging" -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "Vindushåndterer: " +#: data/50-mutter-windows.xml:20 +msgid "Close window" +msgstr "Lukk vindu" -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "Feil i vindushåndterer: " +#: data/50-mutter-windows.xml:22 +msgid "Hide window" +msgstr "Skjul vindu" -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "Advarsel fra vindushåndterer: " +#: data/50-mutter-windows.xml:24 +msgid "Move window" +msgstr "Flytt vindu" -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "Feil i vindushåndterer: " +#: data/50-mutter-windows.xml:26 +msgid "Resize window" +msgstr "Endre størrelse på vindu" -#. first time through -#: ../src/core/window.c:7224 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"Vindu %s setter SM_CLIENT_ID på seg selv i steden for på WM_CLIENT_LEADER-" -"vinduet som spesifisert i ICCCM.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7887 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size " -"%d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"Vindu %s setter et MWM-hint som indikerer at det ikke kan endre størrelse, " -"men setter minste størrelse %d x %d og maks størrelse %d x %d; dette virker " -"ikke fornuftig.\n" +#: data/50-mutter-windows.xml:29 +msgid "Toggle window on all workspaces or one" +msgstr "Slå av/på om vinduet skal vises på alle arbeidsområder eller bare ett" -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "Programmet satte en feil _NET_WM_PID %lu\n" +#: data/50-mutter-windows.xml:31 +msgid "Raise window if covered, otherwise lower it" +msgstr "Hev vindu hvis skjult av et annet vindu, senk det ellers" -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (på %s)" +#: data/50-mutter-windows.xml:33 +msgid "Raise window above other windows" +msgstr "Hev vinduet over andre vinduer" -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "Ugyldig WM_TRANSIENT_FOR vindu 0x%lx oppgitt for %s.\n" +#: data/50-mutter-windows.xml:35 +msgid "Lower window below other windows" +msgstr "Senk vinduet under andre vinduer" -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "WM_TRANSIENT_FOR vindu 0x%lx for %s ville skapt en løkke.\n" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window vertically" +msgstr "Maksimer vinduet vertikalt" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"Vindu 0x%lx har egenskap %s\n" -"som var forventet å ha type %s format %d\n" -"og faktisk har type %s format %d n_items %d.\n" -"Dette er mest sannsynlig en feil i programmet, ikke vindushåndtereren.\n" -"Vinduet har title=«%s» class=«%s» name=«%s»\n" +#: data/50-mutter-windows.xml:39 +msgid "Maximize window horizontally" +msgstr "Maksimer vinduet horisontalt" -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "Egenskap %s på vindu 0x%lx inneholdt ugyldig UTF-8\n" +#: data/50-mutter-windows.xml:43 +msgid "View split on left" +msgstr "Visning delt til venstre" -#: ../src/core/xprops.c:494 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"Egenskap %s på vindu 0x%lx inneholdt ugyldig UTF-8 for oppføring %d i " -"listen\n" +#: data/50-mutter-windows.xml:47 +msgid "View split on right" +msgstr "Visning delt til høyre" -#: ../src/muffin.desktop.in.h:1 ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 +#: data/org.gnome.mutter.gschema.xml.in:7 msgid "Modifier to use for extended window management operations" msgstr "Endringstast som skal brukes for utvidede vindushåndteringsoperasjoner" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 +#: data/org.gnome.mutter.gschema.xml.in:8 msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." msgstr "" "Denne tasten vil initiere «overlay», som er en kombinasjon av vindusoversikt " "og et system for å starte programmer. Forvalget er ment å være «Windows-" "tasten» på PC-maskinvare. Det forventes at denne bindingen er satt til " "forvalg eller en tom streng." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 +#: data/org.gnome.mutter.gschema.xml.in:20 msgid "Attach modal dialogs" msgstr "Fest modale dialoger" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 +#: data/org.gnome.mutter.gschema.xml.in:21 msgid "" "When true, instead of having independent titlebars, modal dialogs appear " "attached to the titlebar of the parent window and are moved together with " @@ -415,23 +293,11 @@ msgstr "" "tittellinjen på opphavsvinduet og flyttes sammen med dette i stedet for å ha " "individuelle tittellinjer." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -msgid "Live Hidden Windows" -msgstr "Levende skjulte vinduer" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"Bestemmer om skjulte vinduer, f.eks minimerte vinduer og vinduer på andre " -"arbeidsområder enn aktivt arbeidsområde, skal holdes i live." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 +#: data/org.gnome.mutter.gschema.xml.in:30 msgid "Enable edge tiling when dropping windows on screen edges" msgstr "Slå på kantflising ved slipp av vinduer på skjermkantene" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 +#: data/org.gnome.mutter.gschema.xml.in:31 msgid "" "If enabled, dropping windows on vertical screen edges maximizes them " "vertically and resizes them horizontally to cover half of the available " @@ -442,22 +308,25 @@ msgstr "" "skjermkanter. Hvis vindu slippes på øverste kant av skjermen maksimeres de " "fullstendig." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 +#: data/org.gnome.mutter.gschema.xml.in:40 msgid "Workspaces are managed dynamically" msgstr "Arbeidsområder håndteres dynamisk" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 +#: data/org.gnome.mutter.gschema.xml.in:41 msgid "" -"Determines whether workspaces are managed dynamically or whether there's a " +"Determines whether workspaces are managed dynamically or whether there’s a " "static number of workspaces (determined by the num-workspaces key in org." "gnome.desktop.wm.preferences)." -msgstr "Bestemmer om arbeidsområder skal håndteres dynamisk eller om det er et fast antall arbeidsområder (bestemt av num-workspaces nøkkelen i org.cinnamon.desktop.wm.preferences)." +msgstr "" +"Bestemmer om arbeidsområder skal håndteres dynamisk eller om det er et fast " +"antall arbeidsområder (bestemt av num-workspaces nøkkelen i org.gnome." +"desktop.wm.preferences)." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 +#: data/org.gnome.mutter.gschema.xml.in:50 msgid "Workspaces only on primary" msgstr "Arbeidsområder kun på primær skjerm" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 +#: data/org.gnome.mutter.gschema.xml.in:51 msgid "" "Determines whether workspace switching should happen for windows on all " "monitors or only for windows on the primary monitor." @@ -465,11 +334,11 @@ msgstr "" "Bestemmer om bytting mellom arbeidsområder skal skje for vinduer på alle " "skjermer eller kun på primær skjerm." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 +#: data/org.gnome.mutter.gschema.xml.in:59 msgid "No tab popup" msgstr "Ingen tabulatordialog" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 +#: data/org.gnome.mutter.gschema.xml.in:60 msgid "" "Determines whether the use of popup and highlight frame should be disabled " "for window cycling." @@ -477,1132 +346,321 @@ msgstr "" "Bestemmer om bruk av dialog og uthevingsramme skal slås av for bytting " "mellom vinduer." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Utsett fokusendringer til pekeren slutter å bevege seg" + +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" +"Hvis denne settes til «true» og fokusmodus er enten «sloppy» eller «mouse» " +"så vil fokus ikke endres med en gang markøren kommer inn i et vindu, men i " +"stedet når markørens bevegelse stopper." + +#: data/org.gnome.mutter.gschema.xml.in:79 msgid "Draggable border width" msgstr "Bredde på drakant" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 +#: data/org.gnome.mutter.gschema.xml.in:80 msgid "" -"The amount of total draggable borders. If the theme's visible borders are " +"The amount of total draggable borders. If the theme’s visible borders are " "not enough, invisible borders will be added to meet this value." msgstr "" "Total mengde med drakant. Hvis temas synlige kanter ikke er nok vil usynlige " "kanter legges til for å imøtekomme denne verdien." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:17 -msgid "Select window from tab popup" -msgstr "Fjern vindu fra tabulatordialog" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:18 -msgid "Cancel tab popup" -msgstr "Avbryt tabulatordialog" - -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr " Bruk: %s\n" - -#: ../src/ui/frames.c:1158 -msgid "Close Window" -msgstr "Lukk vindu" - -#: ../src/ui/frames.c:1161 -msgid "Window Menu" -msgstr "Vindumeny" - -#: ../src/ui/frames.c:1164 -msgid "Minimize Window" -msgstr "Minimer vindu" - -#: ../src/ui/frames.c:1167 -msgid "Maximize Window" -msgstr "Maksimer vindu" - -#: ../src/ui/frames.c:1170 -msgid "Restore Window" -msgstr "Gjenopprett vindu" - -#: ../src/ui/frames.c:1173 -msgid "Roll Up Window" -msgstr "Rull opp vindu" - -#: ../src/ui/frames.c:1176 -msgid "Unroll Window" -msgstr "Rull ned vindu" - -#: ../src/ui/frames.c:1179 -msgid "Keep Window On Top" -msgstr "Plasser vindu i forgrunnen" - -#: ../src/ui/frames.c:1182 -msgid "Remove Window From Top" -msgstr "Fjern vindu fra forgrunnen" - -#: ../src/ui/frames.c:1185 -msgid "Always On Visible Workspace" -msgstr "Alltid på synlig arbeidsområde" - -#: ../src/ui/frames.c:1188 -msgid "Put Window On Only One Workspace" -msgstr "Plasser vindu kun på ett arbeidsområde" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "Mi_nimer" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "Ma_ksimer" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "G_jenopprett" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "Rull _opp" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "R_ull ned" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "_Flytt" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "End_re størrelse" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "Flytt tittellinje på _skjermen" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "All_tid øverst" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "_Alltid på synlig arbeidsområde" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "K_un på dette arbeidsområdet" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "Flytt til arbeidsområdet ti_l venstre" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "Flytt til a_rbeidsområdet til høyre" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "Flytt til arbeidsområdet _over" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "Flytt til arbeidsområdet ne_denfor" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "_Lukk" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "Arbeidsområde %d%n" - -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "Arbeidsområde 1_0" - -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "Arbeidsområde %s%d" - -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "Flytt til et annet ar_beidsområde" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" - -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" - -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "topp" - -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "bunn" - -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "venstre" +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "Maksimer vinduer automatisk hvis de er nesten like store som skjermen" -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "høyre" - -#: ../src/ui/theme.c:286 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "rammegeometrien spesifiserer ikke «%s»-dimensjon" - -#: ../src/ui/theme.c:305 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "rammegeometri spesifiserer ikke dimensjon «%s» for kant «%s»" - -#: ../src/ui/theme.c:342 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "Aspektrate %g for knapp er ikke fornuftig" - -#: ../src/ui/theme.c:354 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "Rammegeometrien spesifiserer ikke størrelse på knapper" - -#: ../src/ui/theme.c:1067 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "Gradienter må ha minst to farger" - -#: ../src/ui/theme.c:1219 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:90 msgid "" -"GTK custom color specification must have color name and fallback in " -"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." msgstr "" -"Egendefinert GTK-fargespesifikasjon må ha fargenavn og reserve i parantes, f." -"eks gtk:custom(foo,bar); kunne ikke lese «%s»" +"Nye vinduer som i utgangspunktet er samme størrelse som skjermen vil " +"automatisk bli maksimert hvis denne slås på." -#: ../src/ui/theme.c:1235 -#, c-format -msgid "" -"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" -"_ are valid" -msgstr "" -"Ugyldig tegn «%c» i parameter color_name for gtk:custom, kun A-Za-z0-9-_ er " -"gyldig" +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Plasser nye vinduer i senter" -#: ../src/ui/theme.c:1249 -#, c-format -msgid "" -"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " -"fit the format" -msgstr "" -"Gtk:custom-format er «gtk:custom(color_name,fallback)», «%s» passer ikke i " -"formatet" - -#: ../src/ui/theme.c:1294 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"GTK-fargespesifikasjon må ha tilstand i klammer, f.eks. gtk:fg[NORMAL], hvor " -"NORMAL er tilstanden; kunne ikke lese «%s»" - -#: ../src/ui/theme.c:1308 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:99 msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." msgstr "" -"GTK-fargespesifikasjon må ha en avsluttende klamme etter tilstanden, f.eks. " -"gtk:fg[NORMAL], hvor NORMAL er tilstanden; kunne ikke lese «%s»" +"Når denne er «true» vil mye vinduer alltid plasseres midt på aktivt område " +"på skjermen." -#: ../src/ui/theme.c:1319 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "Forsto ikke tilstand «%s» i fargespesifikasjonen" +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Slå på eksperimentelle funksjoner" -#: ../src/ui/theme.c:1332 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "Forsto ikke fargekomponent «%s» i fargespesifikasjonen" - -#: ../src/ui/theme.c:1361 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:108 msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “remote-desktop” — " +"enables remote desktop support. To support remote desktop with screen " +"sharing, “screen-cast” must also be enabled. • “screen-cast” — enables " +"screen cast support." msgstr "" -"Blandingsformat er «blend/bg_color/fg_color/alpha», «%s» passer ikke i " -"formatet" - -#: ../src/ui/theme.c:1372 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "Kunne ikke lese alpha-verdi «%s» i blandet farge" - -#: ../src/ui/theme.c:1382 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "Alpha-verdi «%s» i blandet farge er ikke mellom 0.0 og 1.0" - -#: ../src/ui/theme.c:1429 -#, c-format -msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "" -"Skyggeformatet er «shade/base_color/factor», «%s» passer ikke i formatet" - -#: ../src/ui/theme.c:1440 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "Kunne ikke lese skyggefaktor «%s» i skyggelagt farge" - -#: ../src/ui/theme.c:1450 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "Skyggefaktor «%s» i skyggelagt farge er negativ" - -#: ../src/ui/theme.c:1479 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Kunne ikke lese farge «%s»" - -#: ../src/ui/theme.c:1790 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "Koordinatuttrykk inneholder tegn «%s» som ikke er tillatt" - -#: ../src/ui/theme.c:1817 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "Koordinatuttrykk inneholder flyttall «%s» som ikke kunne tolkes" - -#: ../src/ui/theme.c:1831 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "Koordinatuttrykk inneholder heltall «%s» som ikke kunne tolkes" - -#: ../src/ui/theme.c:1953 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "" -"Koordinatuttrykket inneholdt en ukjent operator ved begynnelsen av denne " -"teksten: «%s»" - -#: ../src/ui/theme.c:2010 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "Koordinatuttrykket var tomt eller ble ikke forstått" - -#: ../src/ui/theme.c:2121 ../src/ui/theme.c:2131 ../src/ui/theme.c:2165 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "Koordinatuttrykket resulterer i divisjon med null" -#: ../src/ui/theme.c:2173 -#, c-format -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "Koordinatuttrykket prøver å bruke mod-operator på et flyttall" +#: data/org.gnome.mutter.gschema.xml.in:145 +msgid "Select window from tab popup" +msgstr "Fjern vindu fra tabulatordialog" -#: ../src/ui/theme.c:2229 -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "Koordinatuttrykket har en operator «%s» hvor en operand var ventet" +#: data/org.gnome.mutter.gschema.xml.in:150 +msgid "Cancel tab popup" +msgstr "Avbryt tabulatordialog" -#: ../src/ui/theme.c:2238 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "Koordinatuttrykket hadde en operand hvor en operator var ventet" +#: data/org.gnome.mutter.gschema.xml.in:155 +msgid "Switch monitor configurations" +msgstr "Bytt skjermkonfigurasjon" -#: ../src/ui/theme.c:2246 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "Koordinatuttrykket sluttet med en operator i stedet for en operand" +#: data/org.gnome.mutter.gschema.xml.in:160 +msgid "Rotates the built-in monitor configuration" +msgstr "Roterer mellom innebyggede skjermkonfigurasjoner" -#: ../src/ui/theme.c:2256 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" -"Koordinatuttrykket har en operator «%c» etter en operator «%c» og ingen " -"operand mellom dem." +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Bytt til VT 1" -#: ../src/ui/theme.c:2407 ../src/ui/theme.c:2452 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "Koordinatuttrykket haddeen ukjent variabel eller konstant «%s»" +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Bytt til VT 2" -#: ../src/ui/theme.c:2506 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "Tolkeren for koordinatuttrykk oversteg buffergrensen." +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Bytt til VT 3" -#: ../src/ui/theme.c:2535 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "Koordinatuttrykket hadde en parantes slutt uten parantes start" +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Bytt til VT 4" -#: ../src/ui/theme.c:2599 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "Koordinatuttrykket hadde en åpen parantes uten en avsluttende parantes" +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Bytt til VT 5" -#: ../src/ui/theme.c:2610 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "" -"Koordinatuttrykket ser ikke ut til å ha noen operatorer eller operander" +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Bytt til VT 6" -#: ../src/ui/theme.c:2822 ../src/ui/theme.c:2842 ../src/ui/theme.c:2862 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "Tema inneholdt et uttrykk som resulterte i en feil: %s\n" +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Bytt til VT 7" -#: ../src/ui/theme.c:4533 -#, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" -"<button function=«%s» state=«%s» draw_ops=«ett-eller-annet»/> må " -"spesifiseres for denne rammestilen" +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Bytt til VT 8" -#: ../src/ui/theme.c:5066 ../src/ui/theme.c:5091 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" -"Mangler <frame state=«%s» resize=«%s» focus=«%s» stil=«ett-eller-annet»/>" +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Bytt til VT 9" -#: ../src/ui/theme.c:5139 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Klarte ikke å laste tema «%s»: %s\n" +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Bytt til VT 10" -#: ../src/ui/theme.c:5275 ../src/ui/theme.c:5282 ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 ../src/ui/theme.c:5303 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "<%s> er ikke satt for tema «%s»" +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Bytt til VT 11" -#: ../src/ui/theme.c:5311 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" -"Ingen rammestil satt for vindutype «%s» i tema «%s», legg til et <window " -"type=«%s» style_set=«ett-eller-annet»/>-element" +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Bytt til VT 12" -#: ../src/ui/theme.c:5709 ../src/ui/theme.c:5771 ../src/ui/theme.c:5834 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" -"Brukerdefinerte konstanter må begynne med stor bokstav; «%s» gjør ikke det" - -#: ../src/ui/theme.c:5717 ../src/ui/theme.c:5779 ../src/ui/theme.c:5842 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "Konstant «%s» er allerede definert" +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "Slå på snarveier igjen" -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. #. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "Ingen «%s»-attributt på element <%s>" - -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Linje %d tegn %d: %s" - -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "Attributt «%s» gjentatt to ganger på samme <%s>-element" - -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "Attributt «%s» er ugyldig på <%s>-element i denne konteksten" - -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "Kunne ikke lese «%s» som et heltall" - -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "Forsto ikke etterslepende tegn «%s» i streng «%s»" - -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "Heltall %ld må være positivt" - -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "Heltall %ld er for stort, maksimalverdien er %d" - -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "Kunne ikke lese «%s» som et flyttall" - -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "Bolske verdier må være «sann» eller «usann» ikke «%s»" - -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "Vinkelen må være mellom 0.0 og 360.0, var %g\n" - -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" -"Alpha må være mellom 0.0 (usynlig) og 1.0 (helt ugjennomsiktig), var %g\n" - -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"Ugyldig skalering av tittel «%s» (må være en av xx-small,x-small,small," -"medium,large,x-large,xx-large)\n" - -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 +#: src/backends/meta-input-settings.c:2167 #, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s> navn «%s» brukt på nytt" +msgid "Mode Switch (Group %d)" +msgstr "Modusbytte: (Gruppe %d)" -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "<%s> opphav «%s» er ikke definert" +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2190 +msgid "Switch monitor" +msgstr "Bytt skjerm" -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "<%s> geometri «%s» er ikke definert" +#: src/backends/meta-input-settings.c:2192 +msgid "Show on-screen help" +msgstr "Vis hjelp på skjermen" -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "<%s> må spesifisere enten en geometri eller et opphav som har geometri" +#: src/backends/meta-monitor-manager.c:900 +msgid "Built-in display" +msgstr "Innebygget skjerm" -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "Du må oppgi en bakgrunn for at en alpha-verdi skal ha mening" +#: src/backends/meta-monitor-manager.c:923 +msgid "Unknown" +msgstr "Ukjent" -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Ukjent type «%s» på <%s>-element" +#: src/backends/meta-monitor-manager.c:925 +msgid "Unknown Display" +msgstr "Ukjent skjerm" -#: ../src/ui/theme-parser.c:1275 +#. TRANSLATORS: this is a monitor vendor name, followed by a +#. * size in inches, like 'Dell 15"' +#. +#: src/backends/meta-monitor-manager.c:933 #, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "Ukjent style_set «%s» på <%s>-element" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "Vindutype «%s» er allerede tildelt et stilsett" - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:476 #, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "Element <%s> er ikke tillatt under <%s>" - -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" -msgstr "" -"Kan ikke spesifisere både «button_width»/«button_height» og «aspect_ratio» " -"for knapper" - -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "Avstand «%s» er ukjent" - -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "Aspektrate «%s» er ukjent" - -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "Grense «%s» er ukjent" - -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "Ingen «start_angle» eller «from»-attributt på element <%s>" - -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "Ingen «extent_angle» eller «to»-attributt <%s>-element" - -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "Forsto ikke verdi «%s» for gradienttype" - -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "Forsto ikke fyll-type «%s» for <%s>-element" - -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "Forsto ikke tilstand «%s» for element <%s>" - -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "Forsto ikke skygge «%s» for element <%s>" - -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "Forsto ikke pil «%s» for element <%s>" +"Another compositing manager is already running on screen %i on display “%s”." +msgstr "En annen compositing manager kjører skjerm %i på display «%s»." -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "Ingen <draw_ops> kalt «%s» er definert" +#: src/core/bell.c:194 +msgid "Bell event" +msgstr "Klokkehendelse" -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 +#: src/core/display.c:608 #, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "Hvis du tar med draw_ops «%s» her vil dette lage en sirkulær referanse" +msgid "Failed to open X Window System display “%s”\n" +msgstr "Klarte ikke å åpne X Window System skjerm «%s»\n" -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Ukjent posisjon «%s» for rammesdel" +#: src/core/main.c:189 +msgid "Disable connection to session manager" +msgstr "Deaktiver tilkobling til sesjonshåndtereren" -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "Rammestil har allerede en del i posisjon %s" +#: src/core/main.c:195 +msgid "Replace the running window manager" +msgstr "Erstatt kjørende vindushåndterer" -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "Ingen <draw_ops> med navn «%s» er definert" +#: src/core/main.c:201 +msgid "Specify session management ID" +msgstr "Oppgi sesjonshåndterings-ID" -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Ukjent funksjon «%s» for knapp" +#: src/core/main.c:206 +msgid "X Display to use" +msgstr "X-skjerm som skal brukes" -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "Knappefunksjon «%s» eksisterer ikke i denne versjonen (%d, trenger %d)" +#: src/core/main.c:212 +msgid "Initialize session from savefile" +msgstr "Initier sesjonen fra en lagret fil" -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Ukjent tilstand «%s» for knapp" +#: src/core/main.c:218 +msgid "Make X calls synchronous" +msgstr "Gjør X-kall synkrone" -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "Rammestil har allerede en knapp for funksjon %s tilstand %s" +#: src/core/main.c:225 +msgid "Run as a wayland compositor" +msgstr "Kjør som en wayland-kompositør" -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "«%s» er ikke en gyldig verdi for fokusattributt" +#: src/core/main.c:231 +msgid "Run as a nested compositor" +msgstr "Kjør som en nøstet kompositør" -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "«%s» er ikke en gyldig verdi for tilstandsattributt" +#: src/core/main.c:239 +msgid "Run as a full display server, rather than nested" +msgstr "Kjør som en full skjermtjener, heller enn nøstet" -#: ../src/ui/theme-parser.c:3092 +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:147 #, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "En stil med navn «%s» er ikke definert" +msgid "“%s” is not responding." +msgstr "«%s» svarer ikke." -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "«%s» er ikke en gyldig verdi for attributt for endring av størrelse" +#: src/core/meta-close-dialog-default.c:149 +msgid "Application is not responding." +msgstr "Programmet svarer ikke." -#: ../src/ui/theme-parser.c:3147 -#, c-format +#: src/core/meta-close-dialog-default.c:154 msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." msgstr "" -"Skal ikke være noen «resize»-attributt på <%s>-element for maksimert/" -"skyggelagt tilstand" +"Du kan velge å vente en kort stund for å se om det fortsetter eller tvinge " +"programmet til å avslutte helt." -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "" -"Skal ikke være noen «resize»-attributt på <%s>-element for maksimert tilstand" +#: src/core/meta-close-dialog-default.c:161 +msgid "_Force Quit" +msgstr "_Tvungen nedstenging" -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "" -"Stil er allerede spesifisert for tilstand %s størrelsesendring %s fokus %s" +#: src/core/meta-close-dialog-default.c:161 +msgid "_Wait" +msgstr "_Vent" -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 +#: src/core/mutter.c:39 #, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "Stil er allerede spesifisert for tilstand %s fokus %s" - -#: ../src/ui/theme-parser.c:3294 msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Kan ikke ha to draw_ops for et <piece>-element (tema spesifiserte en " -"draw_ops-attributt i tillegg til et <draw_ops>-element, eller så " -"spesifiserte det to elementer)" - -#: ../src/ui/theme-parser.c:3332 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Kan ikke ha to draw_ops for et <button>-element (tema spesifiserte en " -"draw_ops-attributt i tillegg til et <draw_ops>-element, eller det " -"spesifiserte to elementer)" - -#: ../src/ui/theme-parser.c:3370 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" msgstr "" -"Kan ikke ha to draw_ops for et <menu_icon>-element (tema spesifiserte en " -"draw_ops-attributt i tillegg til et <draw_ops>-element, eller det " -"spesifiserte to elementer)" - -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "Ugyldig versjonspesifikasjon «%s»" +"mutter %s\n" +"Opphavsrett © 2001-%d Havoc Pennington, Red Hat, Inc, og andre\n" +"Dette er fri programvare; se i kildekoden for kopibetingelser.\n" +"Det gis INGEN garanti; ikke en gang for SALGBARHET eller PASSENDE FOR ET " +"BESTEMT FORMÅL.\n" -#: ../src/ui/theme-parser.c:3507 -msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" -msgstr "" -"«version»-attributt kan ikke brukes i metacity-theme-1.xml eller metacity-" -"theme-2.xml" +#: src/core/mutter.c:53 +msgid "Print version" +msgstr "Skriv versjonsnummer" -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "Tema krever versjon %s men siste støttede temaversjon er %d.%d" +#: src/core/mutter.c:59 +msgid "Mutter plugin to use" +msgstr "Mutter-tillegg som skal brukes" -#: ../src/ui/theme-parser.c:3562 +#: src/core/prefs.c:1997 #, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "Ytterste element i temaet må være <metacity_theme> ikke <%s>" +msgid "Workspace %d" +msgstr "Arbeidsområde %d" -#: ../src/ui/theme-parser.c:3582 +#: src/core/screen.c:583 #, c-format msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." msgstr "" -"Element <%s> er ikke tillatt inne i et name/author/date/description element" - -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "Element <%s> er ikke tillatt inne i et <constand> element" - -#: ../src/ui/theme-parser.c:3599 -#, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "Element <%s> er ikke tillatt inne i et avstand/kant/aspektrate-element" - -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "Element <%s> er ikke tillatt inne i et element for tegneoperasjon" - -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "Element <%s> er ikke tillatt inne i et <%s>-element" - -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "Ingen draw_ops tilbys for rammedelen" - -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "Ingen draw_ops tilbys for knappen" - -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "Ingen tekst er tillatt inne i element <%s>" - -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "<%s> spesifisert to ganger for dette temaet" +"Skjerm «%s» har allerede en vindushåndterer; prøv å bruke flagget --replace " +"for å erstatte aktiv vindushåndterer." -#: ../src/ui/theme-parser.c:4348 +#: src/core/screen.c:668 #, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Fant ikke en gyldig fil for tema %s\n" - -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "_Vinduer" - -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "_Dialog" - -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "_Modal dialog" - -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "_Verktøy" - -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "Opp_startskjerm" - -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "_Toppdokk" - -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "_Bunndokk" - -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "_Venstre dokk" - -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "Høy_re dokk" - -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "_Alle dokker" - -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "S_krivebord" - -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "Åpne et til av disse vinduene" - -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "Dette er en demoknapp med et «åpne»-ikon" - -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "Dette er en demoknapp med et «avslutt»-ikon" - -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "Dette er en eksempelbeskjed i en eksempeldialog" - -#: ../src/ui/theme-viewer.c:328 -#, c-format -msgid "Fake menu item %d\n" -msgstr "Falsk menyoppføring %d\n" - -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "Vindu uten innhold" - -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "Linje" - -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "Normalt programvindu" - -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "Dialogboks" - -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "Modal dialogboks" - -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "Verktøypalett" - -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "Avrevet meny" - -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "Kant" - -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "Festet modal dialog" - -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "Test av knappeplassering %d" - -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g millisekunder for å tegne en vindusramme" - -#: ../src/ui/theme-viewer.c:813 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Bruk: metacity-theme-viewer [TEMANAVN]\n" +msgid "Screen %d on display “%s” is invalid\n" +msgstr "Skjerm %d på display «%s» er ugyldig\n" -#: ../src/ui/theme-viewer.c:820 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "Feil under lasting av tema: %s\n" +#: src/core/util.c:120 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter er kompilert uten støtte for «verbose» modus\n" -#: ../src/ui/theme-viewer.c:826 +#: src/wayland/meta-wayland-tablet-pad.c:563 #, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "Lastet tema «%s» på %g sekunder\n" - -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "Normal tittelskrift" - -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "Liten tittelskrift" - -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "Stor tittelskrift" - -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "Knappeplasseringer" - -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "Ytelsestest" - -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "Vindutittel skal her" +msgid "Mode Switch: Mode %d" +msgstr "Modusbytte: Modus %d" -#: ../src/ui/theme-viewer.c:1047 -#, c-format +#: src/x11/session.c:1815 msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." msgstr "" -"Tegnet %d rammer på %g sekunder hos klienten (%g millisekunder per ramme) og " -"%g sekunder på klokken inklusive ressurser på X-tjener (%g millisekunder per " -"ramme)\n" - -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "test av posisjonsuttrykk returnerte TRUE, men satte en feilkode" - -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "test av posisjonsuttrykk returnerte FALSE, men satte ikke en feilkode" - -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "Feil var ventet men ingen ble gitt" - -#: ../src/ui/theme-viewer.c:1274 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "Feil %d var ventet men %d ble gitt" - -#: ../src/ui/theme-viewer.c:1280 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "Feil ikke ventet men en ble returnert: %s" - -#: ../src/ui/theme-viewer.c:1284 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "x-verdi var %d, %d var ventet" +"Disse vinduene støtter ikke «lagre aktiv konfigurasjon», og vil måtte " +"startes på nytt manuelt neste gang du logger inn." -#: ../src/ui/theme-viewer.c:1287 +#: src/x11/window-props.c:559 #, c-format -msgid "y value was %d, %d was expected" -msgstr "y-verdi var %d, %d var ventet" - -#: ../src/ui/theme-viewer.c:1352 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "%d koordinatuttrykk lest på %g sekunder (%g sekunder i snitt)\n" +msgid "%s (on %s)" +msgstr "%s (på %s)" diff --git a/po/nds.po b/po/nds.po index 48146e03e..083972f1e 100644 --- a/po/nds.po +++ b/po/nds.po @@ -1,16 +1,17 @@ -# Low German translation for muffin. -# Copyright (C) 2009 muffin's COPYRIGHT HOLDER -# This file is distributed under the same license as the muffin package. +# Low German translation for mutter. +# Copyright (C) 2009 mutter's COPYRIGHT HOLDER +# This file is distributed under the same license as the mutter package. # Nils-Christoph Fiedler <ncfiedler@gnome.org>, 2009. # msgid "" msgstr "" -"Project-Id-Version: muffin master\n" -"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=muffin&component=general\n" +"Project-Id-Version: mutter master\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=mutter&component=general\n" "POT-Creation-Date: 2009-11-24 21:04+0000\n" "PO-Revision-Date: 2010-08-08 15:45+0100\n" "Last-Translator: Nils-Christoph Fiedler <ncfiedler@gnome.org>\n" "Language-Team: Low German <nds-lowgerman@lists.sourceforge.net>\n" +"Language: nds\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -96,7 +97,7 @@ msgstr "" #: ../src/core/main.c:127 #, c-format msgid "" -"muffin %s\n" +"mutter %s\n" "Copyright (C) 2001-2008 Havoc Pennington, Red Hat, Inc., and others\n" "This is free software; see the source for copying conditions.\n" "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" @@ -107,7 +108,7 @@ msgid "Disable connection to session manager" msgstr "" #: ../src/core/main.c:263 -msgid "Replace the running window manager with Muffin" +msgid "Replace the running window manager with Mutter" msgstr "" #: ../src/core/main.c:269 @@ -315,7 +316,7 @@ msgstr "" #: ../src/core/session.c:1196 #, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" +msgid "<mutter_session> attribute seen but we already have the session ID" msgstr "" #: ../src/core/session.c:1209 @@ -357,9 +358,9 @@ msgid "Opened log file %s\n" msgstr "" #: ../src/core/util.c:139 -#: ../src/tools/muffin-message.c:176 +#: ../src/tools/mutter-message.c:176 #, c-format -msgid "Muffin was compiled without support for verbose mode\n" +msgid "Mutter was compiled without support for verbose mode\n" msgstr "" #: ../src/core/util.c:239 @@ -381,10 +382,10 @@ msgstr "Finsteroppasserfehler:" #. Translators: This is the title used on dialog boxes #. eof all-keybindings.h #: ../src/core/util.c:573 -#: ../src/muffin.desktop.in.h:1 -#: ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" +#: ../src/mutter.desktop.in.h:1 +#: ../src/mutter-wm.desktop.in.h:1 +msgid "Mutter" +msgstr "Mutter" #. first time through #: ../src/core/window.c:6161 @@ -747,31 +748,31 @@ msgstr "" msgid "Move window to center of screen" msgstr "Finster to de Midde vu'm Billschirm verschuven" -#: ../src/muffin.schemas.in.h:1 +#: ../src/mutter.schemas.in.h:1 msgid "Clutter Plugins" msgstr "Clutter Plugins" -#: ../src/muffin.schemas.in.h:2 +#: ../src/mutter.schemas.in.h:2 msgid "Determines whether hidden windows (i.e., minimized windows and windows on other workspaces than the current one) should be kept alive." msgstr "" -#: ../src/muffin.schemas.in.h:3 +#: ../src/mutter.schemas.in.h:3 msgid "Live Hidden Windows" msgstr "" -#: ../src/muffin.schemas.in.h:4 +#: ../src/mutter.schemas.in.h:4 msgid "Modifier to use for extended window management operations" msgstr "" -#: ../src/muffin.schemas.in.h:5 +#: ../src/mutter.schemas.in.h:5 msgid "Plugins to load for the Clutter-based compositing manager." msgstr "" -#: ../src/muffin.schemas.in.h:6 +#: ../src/mutter.schemas.in.h:6 msgid "This key will initiate the \"overlay\", which is a combination window overview and application launching system. The default is intended to be the \"Windows key\" on PC hardware. It's expected that this binding either the default or set to the empty string." msgstr "" -#: ../src/tools/muffin-message.c:150 +#: ../src/tools/mutter-message.c:150 #, c-format msgid "Usage: %s\n" msgstr "Gebruk: %s\n" diff --git a/po/ne.po b/po/ne.po index 5052f5742..b0b338b70 100644 --- a/po/ne.po +++ b/po/ne.po @@ -6,3333 +6,2767 @@ # Nabin Gautam <nabin@mpp.org.np>, 2007. msgid "" msgstr "" -"Project-Id-Version: metacity.gnome-2-20.ne\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2007-10-03 03:39+0100\n" -"PO-Revision-Date: 2007-12-26 15:17+0545\n" -"Last-Translator: Nabin Gautam <nabin@mpp.org.np>\n" -"Language-Team: Nepali <info@mpp.org.np>\n" +"Project-Id-Version: Gnome Nepali Translation Project\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=mutter&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-08-02 10:05+0000\n" +"PO-Revision-Date: 2017-11-26 11:03+0545\n" +"Last-Translator: Pawan Chitrakar <chautari@gmail.com>\n" +"Language-Team: Nepali Translation Team <chautari@gmail.com>\n" +"Language: ne\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: KBabel 1.11.4\n" -"Plural-Forms: nplurals=2; plural=n !=1\n" +"X-Generator: Poedit 2.0.4\n" +"Plural-Forms: nplurals=2; plural=n !=1;\n" -#: ../src/50-metacity-desktop-key.xml.in.h:1 -msgid "Desktop" -msgstr "डेस्कटप" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "नेभिगेशन" -#: ../src/50-metacity-key.xml.in.h:1 -msgid "Window Management" -msgstr "सञ्झ्याल प्रबन्ध" - -#: ../src/tools/metacity-message.c:150 -#, c-format -msgid "Usage: %s\n" -msgstr "प्रयोग: %s\n" - -#: ../src/tools/metacity-message.c:176 ../src/util.c:133 -msgid "Metacity was compiled without support for verbose mode\n" -msgstr "भर्बोज मोडलाई सहयोग बिनानै मेटासिटि सङ्ग्रह गरियो\n" - -#: ../src/core.c:206 -#, c-format -msgid "Unknown window information request: %d" -msgstr "अज्ञात सञ्झ्याल सूचना अनुरोध: %d" - -#: ../src/delete.c:67 ../src/delete.c:94 ../src/metacity-dialog.c:50 -#: ../src/theme-parser.c:484 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "\"%s\" लाई इन्टिजरको रूपमा व्याख्या गर्न सकेन" +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "सञ्झ्याललाई कार्यक्षेत्र १ मा सार्नुहोस्" -#: ../src/delete.c:74 ../src/delete.c:101 ../src/metacity-dialog.c:57 -#: ../src/theme-parser.c:493 ../src/theme-parser.c:548 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "स्ट्रिङ \"%s\" मा पछि रहेका क्यारेक्टर \"%s\" बुझेन" +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "सञ्झ्याललाई कार्यक्षेत्र २ मा सार्नुहोस्" -#: ../src/delete.c:132 -#, c-format -msgid "Failed to parse message \"%s\" from dialog process\n" -msgstr "संवाद प्रक्रियाबाट सन्देश \"%s\" व्याख्या गर्न असफल\n" +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "सञ्झ्याललाई कार्यक्षेत्र ३ मा सार्नुहोस्" -#: ../src/delete.c:267 -#, c-format -msgid "Error reading from dialog display process: %s\n" -msgstr "संवाद प्रदर्शन प्रक्रियाबाट पढ्नमा त्रुटि: %s\n" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "सञ्झ्याललाई कार्यक्षेत्र ४ मा सार्नुहोस्" -#: ../src/delete.c:350 -#, c-format -msgid "Error launching metacity-dialog to ask about killing an application: %s\n" -msgstr "एउटा अनुप्रयोग नष्ट गर्ने बारेमा सोध्ने मेटासिटी संवाद सुरुआत गर्दा त्रुटि: %s\n" +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "सञ्झ्याललाई अन्तिम कार्यक्षेत्र मा सार्नुहोस्" -#: ../src/delete.c:459 -#, c-format -msgid "Failed to get hostname: %s\n" -msgstr "होस्टनाम प्राप्त गर्न असफल: %s\n" +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace to the left" +msgstr "सञ्झ्याललाई एक कार्यक्षेत्र बायाँ सार्नुहोस्" -#: ../src/display.c:349 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "X सञ्झ्याल प्रणाली प्रदर्शन '%s' खोल्न असफल\n" +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace to the right" +msgstr "सञ्झ्याललाई एक कार्यक्षेत्र दायाँ सार्नुहोस्" -#: ../src/errors.c:271 -#, c-format -msgid "" -"Lost connection to the display '%s';\n" -"most likely the X server was shut down or you killed/destroyed\n" -"the window manager.\n" -msgstr "" -"प्रदर्शन '%s' मा जडान छुट्यो;\n" -"X सर्भर बन्द गरिएको वा तपाईँले सञ्झ्याल प्रबन्धक नष्ट/बिगारेको कारणले\n" -"गर्दा प्राय: यस्तो हुन्छ\n" +#: data/50-mutter-navigation.xml:30 +msgid "Move window one workspace up" +msgstr "सञ्झ्याललाई एक कार्यक्षेत्र माथि सार्नुहोस्" -#: ../src/errors.c:278 -#, c-format -msgid "Fatal IO error %d (%s) on display '%s'.\n" -msgstr "घातक IO त्रुटि %d (%s) प्रदर्शन '%s' मा ।\n" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one workspace down" +msgstr "सञ्झ्याललाई एक कार्यक्षेत्र तल सार्नुहोस्" -#: ../src/frames.c:1078 -msgid "Close Window" -msgstr "सञ्झ्याल बन्द गर्नुहोस्" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor to the left" +msgstr "सञ्झ्याललाई एक कार्यक्षेत्र बायाँ सार्नुहोस्" -#: ../src/frames.c:1081 -msgid "Window Menu" -msgstr "सञ्झ्याल मेनु" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor to the right" +msgstr "सञ्झ्याललाई एक कार्यक्षेत्र दायाँ सार्नुहोस्" -#: ../src/frames.c:1084 -msgid "Minimize Window" -msgstr "सञ्झ्याल घटाउनुहोस्" +#: data/50-mutter-navigation.xml:42 +msgid "Move window one monitor up" +msgstr "सञ्झ्याललाई एक कार्यक्षेत्र माथि सार्नुहोस्" -#: ../src/frames.c:1087 -msgid "Maximize Window" -msgstr "सञ्झ्याल बढाउनुहोस्" +#: data/50-mutter-navigation.xml:45 +msgid "Move window one monitor down" +msgstr "सञ्झ्याललाई एक कार्यक्षेत्र तल सार्नुहोस्" -#: ../src/frames.c:1090 -msgid "Unmaximize Window" -msgstr "सञ्झ्याल पूर्वस्थितिमा फर्काउनुहोस्" +#: data/50-mutter-navigation.xml:49 +msgid "Switch applications" +msgstr "अनुप्रयोगहरू स्विच गर्नुहोस्" -#: ../src/frames.c:1093 -msgid "Roll Up Window" -msgstr "सञ्झ्याल माथि रोल गर्नुहोस्" +#: data/50-mutter-navigation.xml:54 +msgid "Switch to previous application" +msgstr "अघिल्लो अनुप्रयोगमा स्विच गर्नुहोस्" -#: ../src/frames.c:1096 -msgid "Unroll Window" -msgstr "सञ्झ्याल रोल नगर्नुहोस्" +#: data/50-mutter-navigation.xml:58 +msgid "Switch windows" +msgstr "सञ्झ्यालहरू बीचमा स्विच गर्नुहोस्" -#: ../src/frames.c:1099 -msgid "Keep Window On Top" -msgstr "सञ्झ्याललाई माथि राख्नुहोस्" +#: data/50-mutter-navigation.xml:63 +#, fuzzy +msgid "Switch to previous window" +msgstr "सबै भ्यूपोर्टमा भएकामध्ये खुलिरहेको अघिल्लो विन्डोमा जान्छ ।" -#: ../src/frames.c:1102 -msgid "Remove Window From Top" -msgstr "सञ्झ्याललाई माथिबाट हटाउनुहोस्" +#: data/50-mutter-navigation.xml:67 +msgid "Switch windows of an application" +msgstr "अनुप्रयोग सञ्झ्यालहरू बीचमा स्विच गर्नुहोस्" -#: ../src/frames.c:1105 -msgid "Always On Visible Workspace" -msgstr "जहिलेपनि दृश्यात्मक कार्यक्षेत्रमा" +#: data/50-mutter-navigation.xml:72 +msgid "Switch to previous window of an application" +msgstr "अघिल्लो अनुप्रयोग सञ्झ्यालहरू बीचमा स्विच गर्नुहोस्" -#: ../src/frames.c:1108 -msgid "Put Window On Only One Workspace" -msgstr "सञ्झ्याललाई एउटा कार्यक्षेत्रमा मात्र राख्नुहोस्" +#: data/50-mutter-navigation.xml:76 +msgid "Switch system controls" +msgstr "प्रणाली नियन्त्रण स्विच गर्नुहोस्" -#: ../src/keybindings.c:1087 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "केही अन्य कार्यक्रमले पहिले नै कुञ्जी %s प्रयोग गरिरहेका छन् जसमा परिमार्जक %x बाइन्डिङका रूपमा छन्\n" +#: data/50-mutter-navigation.xml:81 +msgid "Switch to previous system control" +msgstr "अघिल्लो प्रणाली नियन्त्रणमा स्विच गर्नुहोस्" -#: ../src/keybindings.c:2716 -#, c-format -msgid "Error launching metacity-dialog to print an error about a command: %s\n" -msgstr "आदेश बारेको त्रुटि मुद्रण गर्ने मेटासिटि संवाद सुरुआत गर्दा त्रुटि: %s\n" +#: data/50-mutter-navigation.xml:85 +msgid "Switch windows directly" +msgstr "सञ्झ्याल सिधा स्विच गर्नुहोस्" -#: ../src/keybindings.c:2821 -#, c-format -msgid "No command %d has been defined.\n" -msgstr "आदेश %d परिभाषित गरिएको छैन ।\n" +#: data/50-mutter-navigation.xml:90 +msgid "Switch directly to previous window" +msgstr "अघिल्लो सञ्झ्याल सिधा स्विच गर्नुहोस्" -#: ../src/keybindings.c:3849 -msgid "No terminal command has been defined.\n" -msgstr "टर्मिनल आदेश परिभाषित गरिएको छैन ।\n" +#: data/50-mutter-navigation.xml:94 +#, fuzzy +#| msgid "Move between windows of an application immediately" +msgid "Switch windows of an app directly" +msgstr "सञ्झ्यालहरू बीचमा स्विच गर्ने उपकरण" -#: ../src/main.c:67 -#, c-format -msgid "" -"metacity %s\n" -"Copyright (C) 2001-2007 Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" -"मेटासिटि %s\n" -"प्रतिलिपि अधिकार (C) २००१-२००७ हावोक पेनिङटोन, रेड ह्याट, संस्था., र अन्य\n" -"यो नि:शुल्क सफ्टवेयर हो; प्रतिलिपि सर्तका लागि स्रोत हेर्नुहोस् ।\n" -"वारेन्टी छैन; ब्यापारीकरण गरिएको छैन वा निश्चित उद्देश्यको लागि मिलाइएको पनि छैन ।\n" +#: data/50-mutter-navigation.xml:99 +#, fuzzy +msgid "Switch directly to previous window of an app" +msgstr "अघिल्लो कागजात सञ्झ्याललाई स्विच गर्नुहोस्" -#: ../src/main.c:171 -msgid "Disable connection to session manager" -msgstr "सत्र प्रबन्धकमा जडान गर्न अक्षम" +#: data/50-mutter-navigation.xml:103 +msgid "Switch system controls directly" +msgstr "प्रणाली नियन्त्रण सिधा स्विच गर्नुहोस्" -#: ../src/main.c:177 -msgid "Replace the running window manager with Metacity" -msgstr "चलिरहेको सञ्झ्याल प्रबन्धकलाई मेटासिटिसँग बदल्नुहोस्" +#: data/50-mutter-navigation.xml:108 +msgid "Switch directly to previous system control" +msgstr "अघिल्लो प्रणाली नियन्त्रणमा सिधा स्विच गर्नुहोस्" -#: ../src/main.c:183 -msgid "Specify session management ID" -msgstr "सत्र प्रबन्धक आईडी (ID) निर्दिष्ट गर्नुहोस्" +#: data/50-mutter-navigation.xml:111 +msgid "Hide all normal windows" +msgstr "सामान्य सन्ज्यालहरु सबै लुकाउनुहोस्" -#: ../src/main.c:188 -msgid "X Display to use" -msgstr "प्रयोग गरिने X प्रदर्शन" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 1" +msgstr "कार्यक्षेत्र १ मा स्विच गर्नुहोस्" -#: ../src/main.c:194 -msgid "Initialize session from savefile" -msgstr "बचत फाइलबाट सत्र सुरुआत गर्नुहोस्" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 2" +msgstr "कार्यक्षेत्र २ मा स्विच गर्नुहोस्" -#: ../src/main.c:200 -msgid "Print version" -msgstr "मुद्रण संस्करण" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to workspace 3" +msgstr "कार्यक्षेत्र ३ मा स्विच गर्नुहोस्" -#: ../src/main.c:353 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "विषयवस्तु डाइरेक्टरी स्क्यान गर्न असफल: %s\n" +#: data/50-mutter-navigation.xml:123 +msgid "Switch to workspace 4" +msgstr "कार्यक्षेत्र ४ मा स्विच गर्नुहोस्" -#: ../src/main.c:369 -#, c-format -msgid "Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "विषयवस्तु फेला पार्न सकेन ! %s अवस्थित भएको र उपयोगी विषयवस्तु समाविष्ट भएको जाँच गर्नुहोस् ।\n" +#: data/50-mutter-navigation.xml:126 +msgid "Switch to last workspace" +msgstr "अन्तिम कार्यक्षेत्र मा स्विच गर्नुहोस्" -#: ../src/main.c:429 -#, c-format -msgid "Failed to restart: %s\n" -msgstr "फेरि सुरु गर्न असफल: %s\n" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/menu.c:70 -msgid "Mi_nimize" -msgstr "घटाउनुहोस्" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/menu.c:72 -msgid "Ma_ximize" -msgstr "बढाउनुहोस्" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/menu.c:74 -msgid "Unma_ximize" -msgstr "पूर्वावस्थामा ल्याउनुहोस्" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/menu.c:76 -msgid "Roll _Up" -msgstr "माथि रोल गर्नुहोस्" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/menu.c:78 -msgid "_Unroll" -msgstr "रोल नगर्नुहोस्" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/menu.c:80 -msgid "_Move" -msgstr "सार्नुहोस्" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/menu.c:82 -msgid "_Resize" -msgstr "पूर्वावस्थामा फर्काउनुहोस्" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/menu.c:84 -msgid "Move Titlebar On_screen" -msgstr "शीर्षकपट्टीलाई पर्दामा सार्नुहोस्" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/menu.c:87 ../src/menu.c:89 -msgid "Always on _Top" -msgstr "सधैँ माथि" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/menu.c:91 -msgid "_Always on Visible Workspace" -msgstr "सधैँ दृश्यात्मक कार्यक्षेत्रमा" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/menu.c:93 -msgid "_Only on This Workspace" -msgstr "यस कार्यक्षेत्रमा मात्र" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/menu.c:95 -msgid "Move to Workspace _Left" +#: data/50-mutter-navigation.xml:129 +msgid "Move to workspace left" msgstr "कार्यक्षेत्र बायाँ सार्नुहोस्" -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/menu.c:97 -msgid "Move to Workspace R_ight" +#: data/50-mutter-navigation.xml:132 +msgid "Move to workspace right" msgstr "कार्यक्षेत्र दायाँ सार्नुहोस्" -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/menu.c:99 -msgid "Move to Workspace _Up" -msgstr "कार्यक्षेत्र माथि सार्नुहोस्" +#: data/50-mutter-navigation.xml:135 +msgid "Move to workspace above" +msgstr "माथिल्लो कार्यक्षेत्र सार्नुहोस्" -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/menu.c:101 -msgid "Move to Workspace _Down" -msgstr "कार्यक्षेत्र तल सार्नुहोस्" +#: data/50-mutter-navigation.xml:138 +msgid "Move to workspace below" +msgstr "तल्लो कार्यक्षेत्र मा सार्नुहोस्" -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/menu.c:105 -msgid "_Close" -msgstr "बन्द गर्नुहोस्" +#: data/50-mutter-system.xml:6 +msgid "System" +msgstr "प्रणाली" -#: ../src/menu.c:199 ../src/prefs.c:2246 ../src/prefs.c:2780 -#, c-format -msgid "Workspace %d" -msgstr "कार्यक्षेत्र %d" +#: data/50-mutter-system.xml:8 +#, fuzzy +msgid "Show the run command prompt" +msgstr "टर्मिनलमा आदेश चलाउनुहोस् ।" -#: ../src/menu.c:208 -msgid "Workspace 1_0" -msgstr "कार्यक्षेत्र १_०" +#: data/50-mutter-system.xml:10 +#, fuzzy +msgid "Show the activities overview" +msgstr "अधिलेखन हेर्नुहोस्" -#: ../src/menu.c:210 -#, c-format -msgid "Workspace %s%d" -msgstr "कार्यक्षेत्र %s%d" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "विन्डोहरू" -#: ../src/menu.c:390 -msgid "Move to Another _Workspace" -msgstr "अन्य कार्यक्षेत्रमा सार्नुहोस्" +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "संज्यालको मेनु सक्रिय गर्ने" -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:105 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:111 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:117 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:123 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:129 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:135 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:141 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:147 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:153 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/metaaccellabel.c:159 -msgid "Mod5" -msgstr "Mod5" +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "पूरा पर्दा मोड टगल गर्नुहोस्" -#: ../src/metacity-dialog.c:90 -#, c-format -msgid "\"%s\" is not responding." -msgstr "\"%s\" ले प्रतिक्रिया दिएको छैन ।" +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "बढाइएको स्थितिलाई टगल गर्नुहोस्" -#: ../src/metacity-dialog.c:97 -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "तपाईँले अनुप्रयोगलाई जारी राख्न केही समय प्रतिक्षा गर्नुहोस् रोज्न वा यसलाई पूर्ण रूपमा अन्त्य गर्न दवाब दिन सक्नुहुन्छ ।" +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "सञ्झ्याल बढाउनुहोस्" -#: ../src/metacity-dialog.c:107 -msgid "_Wait" -msgstr "प्रतिक्षा गर्नुहोस्" +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "सञ्झ्याल पूर्वावस्थामा ल्याउनुहोस्" -#: ../src/metacity-dialog.c:109 -msgid "_Force Quit" -msgstr "अन्त्य गर्न दवाब दिनुहोस्" +#: data/50-mutter-windows.xml:18 +msgid "Toggle shaded state" +msgstr "छायाँ पारिएको वस्तुस्थिति टगल गर्नुहोस्" -#: ../src/metacity-dialog.c:206 -msgid "Title" -msgstr "शीर्षक" +#: data/50-mutter-windows.xml:20 +msgid "Close window" +msgstr "सञ्झ्याल बन्द गर्नुहोस्" -#: ../src/metacity-dialog.c:218 -msgid "Class" -msgstr "वर्ग" +#: data/50-mutter-windows.xml:22 +msgid "Hide window" +msgstr "सञ्झ्याल लुकाउनुहोस्" -#: ../src/metacity-dialog.c:244 -msgid "" -"These windows do not support \"save current setup\" and will have to be " -"restarted manually next time you log in." -msgstr "यस प्रकारका सञ्झ्यालले \"हालको सेटअप बचत गर्नुहोस्\" समर्थन गर्दैन र तपाईँले पछिल्लो पटक लगइन गर्दा म्यानुअली फेरि सुरु गर्नु पर्दछ ।" +#: data/50-mutter-windows.xml:24 +msgid "Move window" +msgstr "सञ्झ्याल सार्नुहोस्" -#: ../src/metacity-dialog.c:310 -#, c-format -msgid "" -"There was an error running \"%s\":\n" -"%s." -msgstr "" -" \"%s\" चलाउदा एउटा त्रुटि भयो:\n" -"%s." +#: data/50-mutter-windows.xml:26 +msgid "Resize window" +msgstr "सञ्झ्याललाई रिसाइज गर्नुहोस्" -#: ../src/metacity.desktop.in.h:1 -msgid "Metacity" -msgstr "मेटासिटि" +#: data/50-mutter-windows.xml:29 +#, fuzzy +#| msgid "Toggle window on all workspaces" +msgid "Toggle window on all workspaces or one" +msgstr "सञ्झ्याललाई सबै कार्यस्थानमा देखिने बनाउनुहोस्" -#: ../src/metacity.schemas.in.h:1 -msgid "(Not implemented) Navigation works in terms of applications not windows" -msgstr "(कार्यान्वयन नगरिएका) नेभिगेसनले अनुप्रयोगका रूपमा कार्य गर्दछन् सञ्झ्यालमा कार्य गर्दैनन्" +#: data/50-mutter-windows.xml:31 +#, fuzzy +#| msgid "Raise obscured window, otherwise lower" +msgid "Raise window if covered, otherwise lower it" +msgstr "अदृश्य सञ्झ्याल बढाउनुहोस्, अन्यथा घटाउनुहोस्" -#: ../src/metacity.schemas.in.h:2 -msgid "" -"A font description string describing a font for window titlebars. The size " -"from the description will only be used if the titlebar_font_size option is " -"set to 0. Also, this option is disabled if the titlebar_uses_desktop_font " -"option is set to true." -msgstr "सञ्झ्याल शीर्षकपट्टीका लागि फन्ट वर्णन गर्ने फन्ट वर्णन स्ट्रिङ । यदि शीर्षकपट्टी_फन्ट_साइज विकल्प ० मा सेट गरिएमा मात्र वर्णन अनुसारको साइज प्रयोग गरिन्छ । त्यस्तै, यदि शीर्षकपट्टी_प्रयोग_डेस्कटप_फन्ट ठीकमा सेट गरिएमा यस विकल्पलाई अक्षम पारिन्छ ।" +#: data/50-mutter-windows.xml:33 +msgid "Raise window above other windows" +msgstr "सञ्झ्याललाई अन्य सञ्झ्याल माथि बढाउनुहोस्" -#: ../src/metacity.schemas.in.h:3 -msgid "Action on title bar double-click" -msgstr "शीर्षकपट्टी डबल क्लिक गर्दा हुने कार्य" +#: data/50-mutter-windows.xml:35 +msgid "Lower window below other windows" +msgstr "अन्य सञ्झ्याल तल सञ्झ्याल झार्नुहोस्" -#: ../src/metacity.schemas.in.h:4 -msgid "Action on title bar middle-click" -msgstr "शीर्षकपट्टीको बीचमा क्लिक गर्दा हुने कार्य" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window vertically" +msgstr "ठाडो रूपमा सञ्झ्याल बढाउनुहोस्" -#: ../src/metacity.schemas.in.h:5 -msgid "Action on title bar right-click" -msgstr "शीर्षकपट्टीमा दायाँ क्लिक गर्दा हुने कार्य" +#: data/50-mutter-windows.xml:39 +msgid "Maximize window horizontally" +msgstr "तेर्सो रूपमा सञ्झ्याल बढाउनुहोस्" -#: ../src/metacity.schemas.in.h:6 -msgid "Activate window menu" -msgstr "सञ्झ्याल मेनु सक्रिय पार्नुहोस्" +#: data/50-mutter-windows.xml:43 +#, fuzzy +msgid "View split on left" +msgstr "स्प्लिट" -#: ../src/metacity.schemas.in.h:7 -msgid "Arrangement of buttons on the titlebar" -msgstr "शीर्षकपट्टीमा बटनको प्रबन्ध" +#: data/50-mutter-windows.xml:47 +#, fuzzy +msgid "View split on right" +msgstr "स्प्लिट" -#: ../src/metacity.schemas.in.h:8 -msgid "" -"Arrangement of buttons on the titlebar. The value should be a string, such " -"as \"menu:minimize,maximize,close\"; the colon separates the left corner of " -"the window from the right corner, and the button names are comma-separated. " -"Duplicate buttons are not allowed. Unknown button names are silently ignored " -"so that buttons can be added in future metacity versions without breaking " -"older versions." -msgstr "" -"शिर्षकपट्टीमा बटनको प्रबन्ध । मान स्ट्रिङ हुनुपर्छ, जस्तै \"मेनु: घटाउनुहोस्, बढाउनुहोस्, बन्द गर्नुहोस्\"; विराम चिन्हले " -"दाँया कुनाबाट सञ्झ्यालको बाँया कुना छुट्याउछ र बटन नाम अल्पविरामद्वारा छुट्याइएका हुन्छन् । नक्कली बटनलाई " -"अनुमती छैन । अज्ञात बटनको नामलाई उपेक्षा गरिन्छ, त्यसैले बटनलाई पूरानो " -"संस्करणलाई विच्छेद नगरी भविष्यका मेटासिटि संस्करणमा जोड्न सकिन्छ ।" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "मटर" -#: ../src/metacity.schemas.in.h:9 -msgid "Automatically raises the focused window" -msgstr "केन्द्रित सञ्झ्याल स्वचालित रूपमा बढाउदछ" +#: data/org.gnome.mutter.gschema.xml.in:7 +#, fuzzy +#| msgid "Modifier to use for modified window click actions" +msgid "Modifier to use for extended window management operations" +msgstr "परिमार्जित सञ्झ्याल क्लिक कार्य परिमार्जन गर्नका लागि प्रयोग गरिने परिमार्जक" -#: ../src/metacity.schemas.in.h:10 +#: data/org.gnome.mutter.gschema.xml.in:8 msgid "" -"Clicking a window while holding down this modifier key will move the window " -"(left click), resize the window (middle click), or show the window menu " -"(right click). Modifier is expressed as \"<Alt>\" or \"<Super>\" " -"for example." +"This key will initiate the “overlay”, which is a combination window overview and application launching system. The " +"default is intended to be the “Windows key” on PC hardware. It’s expected that this binding either the default or set to " +"the empty string." msgstr "" -"यो परिमार्जक कुञ्जीलाई होल्ड गरेर सञ्झ्यालमा क्लिक गर्दा " -"(बायाँ क्लिक गर्दा) सञ्झ्याललाई सार्दछ, (बीचमा क्लिक गर्दा) सञ्झ्याल रिसाइज गर्दछ, वा " -"(दायाँ क्लिक गर्दा) सञ्झ्याल मेनु देखाउदछ । उदाहरणका लागि परिमार्जकलाई \"<Alt>\" वा \"<Super>\" " -"का रूपमा प्रस्तुत गरिन्छ ।" +"यो कुञ्जीले \"ओभरले\" को प्रारम्भ गर्नेछ, जुन एक संयोजन सन्झ्याल अवलोकन र अनुप्रयोग सुरूवात प्रणाली हो। पूर्वनिर्धारित पीसी हार्डवेयरमा " +"\"विन्डोज कुञ्जी\" हुनुको उद्देश्य हो। यो अपेक्षा गरिएको छ कि यो बाध्यकारी वा पूर्वनिर्धारित वा खाली स्ट्रिङमा सेट गर्नुहोस्।" -#: ../src/metacity.schemas.in.h:11 -msgid "Close window" -msgstr "सञ्झ्याल बन्द गर्नुहोस्" - -#: ../src/metacity.schemas.in.h:12 -msgid "Commands to run in response to keybindings" -msgstr "कुञ्जी बाइन्डिङको प्रतिक्रियामा चलाइने आदेश" - -#: ../src/metacity.schemas.in.h:13 -msgid "Compositing Manager" -msgstr "प्रबन्धक रचना गर्दैछ" - -#: ../src/metacity.schemas.in.h:14 -msgid "Control how new windows get focus" -msgstr "कति नयाँ सञ्झ्यालले फोकस प्राप्त गर्दछन् नियन्त्रण गर्नुहोस्" - -#: ../src/metacity.schemas.in.h:15 -msgid "Current theme" -msgstr "हालको विषयवस्तु" - -#: ../src/metacity.schemas.in.h:16 -msgid "Delay in milliseconds for the auto raise option" -msgstr "स्वत बढाउने विकल्पका लागि मिलिसेकेन्ड विलम्ब" +#: data/org.gnome.mutter.gschema.xml.in:20 +#, fuzzy +msgid "Attach modal dialogs" +msgstr "संवादहरू" -#: ../src/metacity.schemas.in.h:17 -msgid "Determines whether Metacity is a compositing manager." -msgstr "मेटासिटि रचना प्रबन्धक हो या होइन निर्धारण गर्दछ ।" - -#: ../src/metacity.schemas.in.h:18 +#: data/org.gnome.mutter.gschema.xml.in:21 msgid "" -"Determines whether applications or the system can generate audible 'beeps'; " -"may be used in conjunction with 'visual bell' to allow silent 'beeps'." +"When true, instead of having independent titlebars, modal dialogs appear attached to the titlebar of the parent window " +"and are moved together with the parent window." msgstr "" -"अनुप्रयोग वा प्रणालीले श्रव्य 'बीप' उत्पन्न गर्न सक्दछ या सक्दैन निर्धारण गर्दछ; " -"मौन 'बीप' लाई अनुमति दिन 'दृश्यात्मक घन्टी' को संयोजकसँग प्रयोग गर्न सकिन्छ ।" - -#: ../src/metacity.schemas.in.h:19 -msgid "Disable misfeatures that are required by old or broken applications" -msgstr "पूरानो वा विच्छेद गरिएको अनुप्रयोगलाई आवश्यक हुने विकृत गुण अक्षम पार्नुहोस्" - -#: ../src/metacity.schemas.in.h:20 -msgid "Enable Visual Bell" -msgstr "दृश्यात्मक घन्टी सक्षम पार्नुहोस्" +"जब सँधै, स्वतन्त्र शीर्षकपट्टीको सट्टामा, मोडल संवादहरू अभिभावक सञ्झ्यालको शीर्षकपट्टीमा संलग्न हुन्छन् र अभिभावकको सञ्झ्यालमा सँगै सारिन्छन्।" -#: ../src/metacity.schemas.in.h:21 -msgid "Hide all windows and focus desktop" -msgstr "सबै सञ्झ्याल लुकाउनुहोस् र डेक्सटपमा फोकस गर्नुहोस्" +#: data/org.gnome.mutter.gschema.xml.in:30 +msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "स्क्रिन किनाराहरूमा सञ्झ्याल छोड्दा किनारा टायल सक्षम गर्नुहोस्" -#: ../src/metacity.schemas.in.h:22 +#: data/org.gnome.mutter.gschema.xml.in:31 msgid "" -"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " -"the focused window will be automatically raised after a delay specified by " -"the auto_raise_delay key. This is not related to clicking on a window to " -"raise it, nor to entering a window during drag-and-drop." -msgstr "यदि ठीकमा सेट भएमा, र फोकस मोड यात \"स्लोपी\" वा \"माउस\" भएमा फोकस गरिएको सञ्झ्याल स्वत वृद्धि विलम्ब कुञ्जीद्वारा निर्दिष्ट गरिएको विलम्ब पछि स्वचालित रूपमा बढ्दछ । यसलाई बढाउनु न सञ्झ्यालमा क्लिक गर्नुसँग सम्बन्धित छैन, त्यस्तै तान्ने र छोड्ने गर्दा सञ्झ्यालमा प्रविष्टि गर्नुसँग पनि सम्बन्धित छैन ।" - -#: ../src/metacity.schemas.in.h:23 -msgid "" -"If true, ignore the titlebar_font option, and use the standard application " -"font for window titles." +"If enabled, dropping windows on vertical screen edges maximizes them vertically and resizes them horizontally to cover " +"half of the available area. Dropping windows on the top screen edge maximizes them completely." msgstr "" -"यदि ठीक भएमा, शीर्षकपट्टी फन्ट विकल्पलाई उपेक्षा गर्नुहोस्, र सञ्झ्याल शीर्षकका लागि " -"मानक अनुप्रयोग फन्ट प्रयोग गर्नुहोस् ।" +"यदि सक्षम भएमा, ठाडो स्क्रिन किनाराहरूमा विन्डो छोडेर तिनीहरू ठाडो रूपमा बढाउँछ र तिनीहरूलाई क्षैतिज रूपमा उपलब्ध क्षेत्रको आधा कवर गर्न " +"रिसाइज गर्दछ। शीर्ष स्क्रिन किनारामा विन्डो छोडेर उनीहरूलाई पूर्ण रूपमा अधिकतम गर्दछ।" -#: ../src/metacity.schemas.in.h:24 -msgid "" -"If true, metacity will give the user less feedback by using wireframes, " -"avoiding animations, or other means. This is a significant reduction in " -"usability for many users, but may allow legacy applications to continue " -"working, and may also be a useful tradeoff for terminal servers. However, " -"the wireframe feature is disabled when accessibility is on." -msgstr "यदि ठीक भएमा, मेटासिटिले प्रयोगकर्तालाई वायरफ्रेम प्रयोग गरेर, एनिमेसन हटाएर, वा अन्य उद्देश्यले कम पृष्ठपोषण प्रदान गर्दछ । यो धेरै प्रयोगकर्ताको महत्वपूर्ण उपयोगिता न्यूनिकरण हुन सक्छ, तर लेगेसी अनुप्रयोगलाई जारी राख्न अनुमति दिन् सक्दछ, र टर्मिनल सर्भरका लागि व्यापारीकरण गर्न उपयोगी पनि हुनसक्दछ । तापनि, पहुँचता खुला हुदा वायरफ्रेम गुण अक्षम पारिएको हुन्छ ।" - -#: ../src/metacity.schemas.in.h:25 +#: data/org.gnome.mutter.gschema.xml.in:40 +#, fuzzy +msgid "Workspaces are managed dynamically" +msgstr "यो यन्त्र रङ व्यवस्थित छैन।" + +#: data/org.gnome.mutter.gschema.xml.in:41 msgid "" -"If true, then Metacity works in terms of applications rather than windows. " -"The concept is a bit abstract, but in general an application-based setup is " -"more like the Mac and less like Windows. When you focus a window in " -"application-based mode, all the windows in the application will be raised. " -"Also, in application-based mode, focus clicks are not passed through to " -"windows in other applications. Application-based mode is, however, largely " -"unimplemented at the moment." +"Determines whether workspaces are managed dynamically or whether there’s a static number of workspaces (determined by " +"the num-workspaces key in org.gnome.desktop.wm.preferences)." msgstr "" -"यदि ठीक भएमा, मेटासिटिले विन्डोजको साटोमा अनुप्रयोगको सर्तमा कार्य गर्दछ ।" -"यो धारणा केही अव्यावहारिक हुन्छ, तर सामान्यतया अनुप्रयोगमा आधारित सेटअप धेरै म्याकसँग मिल्ने र सञ्झ्यालसँग नमिल्ने हुन्छ । तपाईँले सञ्झ्याललाई नुप्रयोगमा आधारित मोडमा फोकस गरेमा, अनुप्रयोगका सबै सञ्झ्याल बढ्नेछन् । " -"त्यस्तै, अनुप्रयोग आधारित मोडमा, फोकस क्लिक अन्य अनुप्रयोगमा सञ्झ्यालबाट पास हुदैनन् । तापनि अनुप्रयोग आधारित मोड, हालको अवस्थामा ठूलो, कार्यान्वयन गर्न नसकिने हुन्छ ।" - -#: ../src/metacity.schemas.in.h:26 -msgid "If true, trade off usability for less resource usage" -msgstr "यदि ठीक भएमा, कम स्रोत प्रयोगका लागि व्यापारिकरण उपयोगिता हुन्छ" - -#: ../src/metacity.schemas.in.h:27 -msgid "Lower window below other windows" -msgstr "अन्य सञ्झ्याल तल सञ्झ्याल झार्नुहोस्" - -#: ../src/metacity.schemas.in.h:28 -msgid "Maximize window" -msgstr "सञ्झ्याल बढाउनुहोस्" +"निर्धारण गर्दछ कि कार्यस्थानहरू गतिशील रूपमा व्यवस्थित छन् वा चाहेको स्थिर कार्य सङ्ख्या (यदि सङ्ख्या-कार्यक्षेत्र कुञ्जीद्वारा org.gnome." +"desktop.wm.preferences मा निर्धारण गरिएको हो)।" -#: ../src/metacity.schemas.in.h:29 -msgid "Maximize window horizontally" -msgstr "तेर्सो रूपमा सञ्झ्याल बढाउनुहोस्" +#: data/org.gnome.mutter.gschema.xml.in:50 +#, fuzzy +msgid "Workspaces only on primary" +msgstr "प्राइमेरी" -#: ../src/metacity.schemas.in.h:30 -msgid "Maximize window vertically" -msgstr "ठाडो रूपमा सञ्झ्याल बढाउनुहोस्" +#: data/org.gnome.mutter.gschema.xml.in:51 +msgid "" +"Determines whether workspace switching should happen for windows on all monitors or only for windows on the primary " +"monitor." +msgstr "सबै मनिटरहरूमा सञ्झ्यालका लागि कार्यस्थान स्विच गर्नु पर्दछ वा केवल प्राथमिक मनिटरमा सञ्झ्याल को लागि हुनुपर्छ।" -#: ../src/metacity.schemas.in.h:31 -msgid "Minimize window" -msgstr "सञ्झ्याल घटाउनुहोस्" +#: data/org.gnome.mutter.gschema.xml.in:59 +#, fuzzy +msgid "No tab popup" +msgstr "पपअप मेनु" -#: ../src/metacity.schemas.in.h:32 -msgid "Modifier to use for modified window click actions" -msgstr "परिमार्जित सञ्झ्याल क्लिक कार्य परिमार्जन गर्नका लागि प्रयोग गरिने परिमार्जक" +#: data/org.gnome.mutter.gschema.xml.in:60 +msgid "Determines whether the use of popup and highlight frame should be disabled for window cycling." +msgstr "पिकअप र हाइलाइट फ्रेमको प्रयोग सञ्झ्याल चलाउन असक्षम हुनु पर्दछ।" -#: ../src/metacity.schemas.in.h:33 -msgid "Move backward between panels and the desktop immediately" -msgstr "प्यानल र डेक्सटपको बीचमा तुरुन्त पछाडिपट्टि सार्नुहोस् ।" +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "" -#: ../src/metacity.schemas.in.h:34 -msgid "Move backwards between panels and the desktop with popup" -msgstr "पपअप भएको प्यानल र डेक्सटप बीचमा पछाडिपट्टि सार्नुहोस्" +#: data/org.gnome.mutter.gschema.xml.in:69 +#, fuzzy +#| msgid "" +#| "If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then the focused window will be automatically " +#| "raised after a delay specified by the auto_raise_delay key. This is not related to clicking on a window to raise it, " +#| "nor to entering a window during drag-and-drop." +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the focus will not be changed immediately when " +"entering a window, but only after the pointer stops moving." +msgstr "" +"यदि ठीकमा सेट भएमा, र फोकस मोड यात \"स्लोपी\" वा \"माउस\" भएमा फोकस गरिएको सञ्झ्याल स्वत वृद्धि विलम्ब कुञ्जीद्वारा निर्दिष्ट गरिएको " +"विलम्ब पछि स्वचालित रूपमा बढ्दछ । यसलाई बढाउनु न सञ्झ्यालमा क्लिक गर्नुसँग सम्बन्धित छैन, त्यस्तै तान्ने र छोड्ने गर्दा सञ्झ्यालमा प्रविष्टि गर्नुसँग " +"पनि सम्बन्धित छैन ।" -#: ../src/metacity.schemas.in.h:35 -msgid "Move backwards between windows immediately" -msgstr "सञ्झ्यालको बिचमा पछाडिपट्टि तुरुन्त सार्नुहोस्" +#: data/org.gnome.mutter.gschema.xml.in:79 +#, fuzzy +msgid "Draggable border width" +msgstr "सीमाना चौडाई" -#: ../src/metacity.schemas.in.h:36 -msgid "Move backwards between windows of an application immediately" -msgstr "अनुप्रयोगको सञ्झ्याल बीचमा तुरुन्त पछाडिपट्टि सार्नुहोस्" +#: data/org.gnome.mutter.gschema.xml.in:80 +msgid "" +"The amount of total draggable borders. If the theme’s visible borders are not enough, invisible borders will be added to " +"meet this value." +msgstr "" -#: ../src/metacity.schemas.in.h:37 -msgid "Move backwards between windows of an application with popup" -msgstr "पपअप भएको अनुप्रयोगको सञ्झ्याल बीचमा पछाडिपट्टि सार्नुहोस्" +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "" -#: ../src/metacity.schemas.in.h:38 -msgid "Move between panels and the desktop immediately" -msgstr "प्यानल र डेस्कटप बीचमा तुरुन्त सार्नुहोस्" +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "If enabled, new windows that are initially the size of the monitor automatically get maximized." +msgstr "" -#: ../src/metacity.schemas.in.h:39 -msgid "Move between panels and the desktop with popup" -msgstr "पपअप भएको प्यानल र डेक्सटप बिचमा सार्नुहोस्" +#: data/org.gnome.mutter.gschema.xml.in:98 +#, fuzzy +msgid "Place new windows in the center" +msgstr "नयाँ कल राख्नुहोस्" -#: ../src/metacity.schemas.in.h:40 -msgid "Move between windows immediately" -msgstr "सञ्झ्याल बीचमा तुरुन्त सार्नुहोस्" +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "When true, the new windows will always be put in the center of the active screen of the monitor." +msgstr "" -#: ../src/metacity.schemas.in.h:41 -msgid "Move between windows of an application immediately" -msgstr "अनुप्रयोगको सञ्झ्याल बीचमा तुरुन्त सार्नुहोस्" +#: data/org.gnome.mutter.gschema.xml.in:107 +#, fuzzy +msgid "Enable experimental features" +msgstr "माउस पहुँच सुविधाहरू सक्षम पार्न सकिएन" -#: ../src/metacity.schemas.in.h:42 -msgid "Move between windows of an application with popup" -msgstr "पपअप भएको अनुप्रयोगको सञ्झ्याल बीचमा तुरुन्त सार्नुहोस्" +#: data/org.gnome.mutter.gschema.xml.in:108 +msgid "" +"To enable experimental features, add the feature keyword to the list. Whether the feature requires restarting the " +"compositor depends on the given feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future proof. Currently possible keywords: • “monitor-" +"config-manager” — use the new monitor configuration system, aimed to replace the old one. This enables a higher level " +"configuration API to be used by configuration applications, as well as the ability to configure per logical monitor " +"scale. • “scale-monitor-framebuffer” — makes mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to manage HiDPI monitors. Does not require a " +"restart. Also enabling “monitor-config-manager” is required for this feature to be enabled." +msgstr "" -#: ../src/metacity.schemas.in.h:43 -msgid "Move between windows with popup" +#: data/org.gnome.mutter.gschema.xml.in:151 +#, fuzzy +#| msgid "Move between windows with popup" +msgid "Select window from tab popup" msgstr "पपअप भएको सञ्झ्याल बीचमा सार्नुहोस्" -#: ../src/metacity.schemas.in.h:44 -msgid "Move focus backwards between windows using popup display" -msgstr "पपअप प्रदर्शन प्रयोग गर्ने सञ्झ्याल बीचमा फोकस पछाडिपट्टि सार्नुहोस्" - -#: ../src/metacity.schemas.in.h:45 -msgid "Move window" -msgstr "सञ्झ्याल सार्नुहोस्" - -#: ../src/metacity.schemas.in.h:46 -msgid "Move window one workspace down" -msgstr "सञ्झ्याललाई एक कार्यक्षेत्र तल सार्नुहोस्" - -#: ../src/metacity.schemas.in.h:47 -msgid "Move window one workspace to the left" -msgstr "सञ्झ्याललाई एक कार्यक्षेत्र बायाँ सार्नुहोस्" - -#: ../src/metacity.schemas.in.h:48 -msgid "Move window one workspace to the right" -msgstr "सञ्झ्याललाई एक कार्यक्षेत्र दायाँ सार्नुहोस्" - -#: ../src/metacity.schemas.in.h:49 -msgid "Move window one workspace up" -msgstr "सञ्झ्याललाई एक कार्यक्षेत्र माथि सार्नुहोस्" - -#: ../src/metacity.schemas.in.h:50 -msgid "Move window to east side of screen" -msgstr "सञ्झ्याललाई पर्दाको पुर्व छेउमा सार्नुहोस्" - -#: ../src/metacity.schemas.in.h:51 -msgid "Move window to north side of screen" -msgstr "सञ्झ्याललाई पर्दाको उत्तर छेउमा सार्नुहोस्" - -#: ../src/metacity.schemas.in.h:52 -msgid "Move window to north-east corner" -msgstr "सञ्झ्याललाई उत्तर पुर्व कुनामा सार्नुहोस्" - -#: ../src/metacity.schemas.in.h:53 -msgid "Move window to north-west corner" -msgstr "सञ्झ्याललाई उत्तर पश्चिम कुनामा सार्नुहोस्" - -#: ../src/metacity.schemas.in.h:54 -msgid "Move window to south side of screen" -msgstr "सञ्झ्याललाई पर्दाको दक्षिण कुनामा सार्नुहोस्" - -#: ../src/metacity.schemas.in.h:55 -msgid "Move window to south-east corner" -msgstr "सञ्झ्याललाई पर्दाको दक्षिण पर्व कुनामा सार्नुहोस्" - -#: ../src/metacity.schemas.in.h:56 -msgid "Move window to south-west corner" -msgstr "सञ्झ्याललाई पर्दाको दक्षिण पश्चिम कुनामा सार्नुहोस्" - -#: ../src/metacity.schemas.in.h:57 -msgid "Move window to west side of screen" -msgstr "सञ्झ्याललाई पर्दाको पश्चिम कुनामा सार्नुहोस्" - -#: ../src/metacity.schemas.in.h:58 -msgid "Move window to workspace 1" -msgstr "सञ्झ्याललाई कार्यक्षेत्र १ मा सार्नुहोस्" - -#: ../src/metacity.schemas.in.h:59 -msgid "Move window to workspace 10" -msgstr "सञ्झ्याललाई कार्यक्षेत्र १० मा सार्नुहोस्" - -#: ../src/metacity.schemas.in.h:60 -msgid "Move window to workspace 11" -msgstr "सञ्झ्याललाई कार्यक्षेत्र ११ मा सार्नुहोस्" - -#: ../src/metacity.schemas.in.h:61 -msgid "Move window to workspace 12" -msgstr "सञ्झ्याललाई कार्यक्षेत्र १२ मा सार्नुहोस्" - -#: ../src/metacity.schemas.in.h:62 -msgid "Move window to workspace 2" -msgstr "सञ्झ्याललाई कार्यक्षेत्र २ मा सार्नुहोस्" - -#: ../src/metacity.schemas.in.h:63 -msgid "Move window to workspace 3" -msgstr "सञ्झ्याललाई कार्यक्षेत्र ३ मा सार्नुहोस्" - -#: ../src/metacity.schemas.in.h:64 -msgid "Move window to workspace 4" -msgstr "सञ्झ्याललाई कार्यक्षेत्र ४ मा सार्नुहोस्" - -#: ../src/metacity.schemas.in.h:65 -msgid "Move window to workspace 5" -msgstr "सञ्झ्याललाई कार्यक्षेत्र ५ मा सार्नुहोस्" +#: data/org.gnome.mutter.gschema.xml.in:156 +msgid "Cancel tab popup" +msgstr "पपउप रद्द गर्ने" -#: ../src/metacity.schemas.in.h:66 -msgid "Move window to workspace 6" -msgstr "सञ्झ्याललाई कार्यक्षेत्र ६ मा सार्नुहोस्" +#: data/org.gnome.mutter.gschema.xml.in:161 +#, fuzzy +msgid "Switch monitor configurations" +msgstr "मनिटरको कन्फिगरेसन बदल्न सकिएन" -#: ../src/metacity.schemas.in.h:67 -msgid "Move window to workspace 7" -msgstr "सञ्झ्याललाई कार्यक्षेत्र ७ मा सार्नुहोस्" +#: data/org.gnome.mutter.gschema.xml.in:166 +#, fuzzy +msgid "Rotates the built-in monitor configuration" +msgstr "मनिटरको कन्फिगरेसन बदल्न सकिएन" -#: ../src/metacity.schemas.in.h:68 -msgid "Move window to workspace 8" -msgstr "सञ्झ्याललाई कार्यक्षेत्र ८ मा सार्नुहोस्" - -#: ../src/metacity.schemas.in.h:69 -msgid "Move window to workspace 9" -msgstr "सञ्झ्याललाई कार्यक्षेत्र ९ मा सार्नुहोस्" +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "कार्यक्षेत्र १ मा स्विच गर्नुहोस्" -#: ../src/metacity.schemas.in.h:70 -msgid "Name of workspace" -msgstr "कार्यक्षेत्रको नाम" +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "कार्यक्षेत्र २ मा स्विच गर्नुहोस्" -#: ../src/metacity.schemas.in.h:71 -msgid "Number of workspaces" -msgstr "कार्यक्षेत्रका सङ्ख्या" +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "कार्यक्षेत्र ३ मा स्विच गर्नुहोस्" -#: ../src/metacity.schemas.in.h:72 -msgid "" -"Number of workspaces. Must be more than zero, and has a fixed maximum to " -"prevent making the desktop unusable by accidentally asking for too many " -"workspaces." -msgstr "कार्यक्षेत्रका सङ्ख्या । शून्यभन्दा धेरै हुनुपर्दछ, आकस्मिक रूपमा धेरै कार्यक्षेत्रका लागि सोधिने डेस्कटपलाई अनुपयोगी बनाउन अधिकतमलाई निषेधमा निश्चित गरिएको छ ।" +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "कार्यक्षेत्र ४ मा स्विच गर्नुहोस्" -#: ../src/metacity.schemas.in.h:73 -msgid "Raise obscured window, otherwise lower" -msgstr "अदृश्य सञ्झ्याल बढाउनुहोस्, अन्यथा घटाउनुहोस्" +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "कार्यक्षेत्र ५ मा स्विच गर्नुहोस्" -#: ../src/metacity.schemas.in.h:74 -msgid "Raise window above other windows" -msgstr "सञ्झ्याललाई अन्य सञ्झ्याल माथि बढाउनुहोस्" +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "कार्यक्षेत्र ६ मा स्विच गर्नुहोस्" -#: ../src/metacity.schemas.in.h:75 -msgid "Resize window" -msgstr "सञ्झ्याललाई रिसाइज गर्नुहोस्" +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "कार्यक्षेत्र ७ मा स्विच गर्नुहोस्" -#: ../src/metacity.schemas.in.h:76 -msgid "Run a defined command" -msgstr "परिभाषित आदेश चलाउनुहोस्" +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "कार्यक्षेत्र ८ मा स्विच गर्नुहोस्" -#: ../src/metacity.schemas.in.h:77 -msgid "Run a terminal" -msgstr "टर्मिनल चलाउनुहोस्" +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "कार्यक्षेत्र ९ मा स्विच गर्नुहोस्" -#: ../src/metacity.schemas.in.h:78 -msgid "" -"Setting this option to false can lead to buggy behavior, so users are " -"strongly discouraged from changing it from the default of true. Many actions " -"(e.g. clicking in the client area, moving or resizing the window) normally " -"raise the window as a side-effect. Set this option to false to decouple " -"raising from other user actions. Even when this option is false, windows can " -"still be raised by an alt-left-click anywhere on the window, a normal click " -"on the window decorations, or by special messages from pagers, such as " -"activation requests from tasklist applets. This option is currently disabled " -"in click-to-focus mode. Note that the list of ways to raise windows when " -"raise_on_click is false does not include programmatic requests from " -"applications to raise windows; such requests will be ignored regardless of " -"the reason for the request. If you are an application developer and have a " -"user complaining that your application does not work with this setting " -"disabled, tell them it is _their_ fault for breaking their window manager " -"and that they need to change this option back to true or live with the bug " -"they requested. See also http://bugzilla.gnome.org/show_bug.cgi?id=445447#c6." -msgstr "" -"यस विकल्पलाई गलतमा सेटिङ गर्दा बग व्यवहार अगुवा हुनसक्दछ, त्यसैले प्रयोगकर्तालाई पूर्वनिर्धारित ठीकबाट परिवर्तन गर्न कडाइका साथ निरुत्साहहित गरिन्छ । धेरै कार्यहरू " -"(जस्तै; क्लाइन्ट क्षेत्र भित्र क्लिक गर्दा, सञ्झ्याल सार्दा वा रिसाइज गर्दा) सामान्यतया " -"नकाराम्मक प्रभावले सञ्झ्याललाई बढाउदछ । अन्य प्रयोगकर्ता कार्य बढ्नबाट अलग गर्न यस विकल्पलाई गलतमा सेट गर्नुहोस् । यो विकल्प गलत भएता पनि, सञ्झ्याललाई अझै पनि सञ्झ्यालको कुनै पनि ठाउमा alt-left क्लिक गरेर, सञ्झ्याल सजावटमा सामान्य क्लिक गरेर, वा कार्यसूची एप्लेटका सक्रियता अनुरोध जस्ता पेजरका विशेष सन्देशद्वारा बढाउन सकिन्छ । यस विकल्पलाई click-to-focus मोडमा अक्षम पारिएको छ । याद गर्नुहोस् " -"raise_on_click हुदा सञ्झ्याल बढाउने तरिकाको सूची गलत हो जसले अनुप्रयोगका सञ्झ्याल बढाउने कार्यक्रमिक अनुरोध सम्मिलित गर्दैन; अनुरोधको कारणले पनि त्यस्ता अनुरोध उपेक्षा गरिन्छन् । यदि तपाईँ अनुप्रयोग विकासकर्ता हो र तपाईँको अनुप्रयोगले यस सेटिङसँग कार्य गर्दैन अक्षम पारिएको छ भन्ने प्रयोगकर्ता सिकायत भएमा, प्रयोगकर्तालाई उनीहरूको सञ्झ्याल प्रबन्धक विच्छेद गर्दाको दोसको कारणले भएको र प्रयोगकर्ताले यस विकल्पलाई फेरि ठीकमा सेट गर्नु वा अनुरोध गरिएको त्रुटिसँग चलाउनु पर्ने अवगत गराउनुहोस् । http://bugzilla.gnome.org/show_bug.cgi?id=445447#c6 पनि हेर्नुहोस् ।" +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "कार्यक्षेत्र १० मा स्विच गर्नुहोस्" -#: ../src/metacity.schemas.in.h:79 -msgid "Show the panel menu" -msgstr "प्यानल मेनु देखाउनुहोस्" +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "कार्यक्षेत्र ११ मा स्विच गर्नुहोस्" -#: ../src/metacity.schemas.in.h:80 -msgid "Show the panel run application dialog" -msgstr "प्यानल चल्ने अनुप्रयोग संवाद देखाउनुहोस्" +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "कार्यक्षेत्र १२ मा स्विच गर्नुहोस्" -#: ../src/metacity.schemas.in.h:81 -msgid "" -"Some applications disregard specifications in ways that result in window " -"manager misfeatures. This option puts Metacity in a rigorously correct mode, " -"which gives a more consistent user interface, provided one does not need to " -"run any misbehaving applications." -msgstr "केही अनुप्रयोगले सञ्झ्याल प्रबन्धकमा नतिजा विकृत हुने तरिकाले विशेष वर्णन अस्वीकार गर्दछन् । यस विकल्पले मेटासिटिलाई कठीन सुधार मोडमा राख्दछ, जसले धेरै अनुकूल प्रयोगकर्ता इन्टरफेस प्रदान गर्दछ, उपलब्ध कुनै एकले अन्य खराब ब्यवहार गर्ने कुनै पनि अनुप्रयोग चलाउनु पर्दैन ।" +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "सर्टकट सक्षम गर्नुहोस्" -#: ../src/metacity.schemas.in.h:82 -msgid "Switch to workspace 1" -msgstr "कार्यक्षेत्र १ मा स्विच गर्नुहोस्" +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. +#. +#: src/backends/meta-input-settings.c:2118 +#, c-format +msgid "Mode Switch (Group %d)" +msgstr "मोड स्विच (समूह %d)" -#: ../src/metacity.schemas.in.h:83 -msgid "Switch to workspace 10" -msgstr "कार्यक्षेत्र १० मा स्विच गर्नुहोस्" +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2141 +msgid "Switch monitor" +msgstr "निगरानि बदल्नुहोस्" + +#: src/backends/meta-input-settings.c:2143 +msgid "Show on-screen help" +msgstr "अन-स्क्रिन सहयोग हेर्नुहोस्" + +#: src/backends/meta-monitor-manager.c:927 +#, fuzzy +msgid "Built-in display" +msgstr "स्वतः निर्मित" + +#: src/backends/meta-monitor-manager.c:950 +msgid "Unknown" +msgstr "अज्ञात" + +#: src/backends/meta-monitor-manager.c:952 +#, fuzzy +msgid "Unknown Display" +msgstr "** अज्ञात **" + +#. TRANSLATORS: this is a monitor vendor name, followed by a +#. * size in inches, like 'Dell 15"' +#. +#: src/backends/meta-monitor-manager.c:960 +#, c-format +msgid "%s %s" +msgstr "%s %s" -#: ../src/metacity.schemas.in.h:84 -msgid "Switch to workspace 11" -msgstr "कार्यक्षेत्र ११ मा स्विच गर्नुहोस्" +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:476 +#, fuzzy, c-format +#| msgid "Could not acquire window manager selection on screen %d display \"%s\"\n" +msgid "Another compositing manager is already running on screen %i on display “%s”." +msgstr "पर्दा %d को \"%s\" मा प्रदर्शन गर्दा विन्डो प्रबन्धक छनौट पाउन सक्नु भएन\n" -#: ../src/metacity.schemas.in.h:85 -msgid "Switch to workspace 12" -msgstr "कार्यक्षेत्र १२ मा स्विच गर्नुहोस्" +#: src/core/bell.c:194 +msgid "Bell event" +msgstr "घटना घण्टी" -#: ../src/metacity.schemas.in.h:86 -msgid "Switch to workspace 2" -msgstr "कार्यक्षेत्र २ मा स्विच गर्नुहोस्" +#: src/core/display.c:608 +#, fuzzy, c-format +#| msgid "Failed to open X Window System display '%s'\n" +msgid "Failed to open X Window System display “%s”\n" +msgstr "X सञ्झ्याल प्रणाली प्रदर्शन '%s' खोल्न असफल\n" -#: ../src/metacity.schemas.in.h:87 -msgid "Switch to workspace 3" -msgstr "कार्यक्षेत्र ३ मा स्विच गर्नुहोस्" +#: src/core/main.c:189 +msgid "Disable connection to session manager" +msgstr "सत्र प्रबन्धकमा जडान गर्न अक्षम" -#: ../src/metacity.schemas.in.h:88 -msgid "Switch to workspace 4" -msgstr "कार्यक्षेत्र ४ मा स्विच गर्नुहोस्" +#: src/core/main.c:195 +#, fuzzy +#| msgid "Replace the running window manager with Metacity" +msgid "Replace the running window manager" +msgstr "चलिरहेको सञ्झ्याल प्रबन्धकलाई मेटासिटिसँग बदल्नुहोस्" -#: ../src/metacity.schemas.in.h:89 -msgid "Switch to workspace 5" -msgstr "कार्यक्षेत्र ५ मा स्विच गर्नुहोस्" +#: src/core/main.c:201 +msgid "Specify session management ID" +msgstr "सत्र प्रबन्धक आईडी (ID) निर्दिष्ट गर्नुहोस्" -#: ../src/metacity.schemas.in.h:90 -msgid "Switch to workspace 6" -msgstr "कार्यक्षेत्र ६ मा स्विच गर्नुहोस्" +#: src/core/main.c:206 +msgid "X Display to use" +msgstr "प्रयोग गरिने X प्रदर्शन" -#: ../src/metacity.schemas.in.h:91 -msgid "Switch to workspace 7" -msgstr "कार्यक्षेत्र ७ मा स्विच गर्नुहोस्" +#: src/core/main.c:212 +msgid "Initialize session from savefile" +msgstr "बचत फाइलबाट सत्र सुरुआत गर्नुहोस्" -#: ../src/metacity.schemas.in.h:92 -msgid "Switch to workspace 8" -msgstr "कार्यक्षेत्र ८ मा स्विच गर्नुहोस्" +#: src/core/main.c:218 +msgid "Make X calls synchronous" +msgstr "X कल समकालीन बनाउनुहोस्" -#: ../src/metacity.schemas.in.h:93 -msgid "Switch to workspace 9" -msgstr "कार्यक्षेत्र ९ मा स्विच गर्नुहोस्" +#: src/core/main.c:225 +#, fuzzy +msgid "Run as a wayland compositor" +msgstr "चलाएँ" -#: ../src/metacity.schemas.in.h:94 -msgid "Switch to workspace above this one" -msgstr "यस भन्दा माथिको कार्यक्षेत्रमा स्विच गर्नुहोस्" +#: src/core/main.c:231 +#, fuzzy +msgid "Run as a nested compositor" +msgstr "चलाएँ" -#: ../src/metacity.schemas.in.h:95 -msgid "Switch to workspace below this one" -msgstr "यस भन्दा मुनिको कार्यक्षेत्रमा स्विच गर्नुहोस्" +#: src/core/main.c:239 +msgid "Run as a full display server, rather than nested" +msgstr "नेस्ट गरिएको सट्टा पूर्ण प्रदर्शन सर्भरको रूपमा चलाउनुहोस्" -#: ../src/metacity.schemas.in.h:96 -msgid "Switch to workspace on the left" -msgstr "बायाँको कार्यक्षेत्रमा स्विच गर्नुहोस्" +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:147 +#, c-format +msgid "“%s” is not responding." +msgstr "%s ले जवाफ दिन बन्द गरेको छ." -#: ../src/metacity.schemas.in.h:97 -msgid "Switch to workspace on the right" -msgstr "दायाँको कार्यक्षेत्रमा स्विच गर्नुहोस्" +#: src/core/meta-close-dialog-default.c:149 +#, fuzzy +#| msgid "\"%s\" is not responding." +msgid "Application is not responding." +msgstr "अनुप्रयोग %s ले जवाफ दिन बन्द गरेको छ।" -#: ../src/metacity.schemas.in.h:98 -msgid "System Bell is Audible" -msgstr "प्रणाली घन्टी सुन्न सकिन्छ" +#: src/core/meta-close-dialog-default.c:154 +msgid "You may choose to wait a short while for it to continue or force the application to quit entirely." +msgstr "तपाईँले अनुप्रयोगलाई जारी राख्न केही समय प्रतिक्षा गर्नुहोस् रोज्न वा यसलाई पूर्ण रूपमा अन्त्य गर्न दवाब दिन सक्नुहुन्छ ।" -#: ../src/metacity.schemas.in.h:99 -msgid "Take a screenshot" -msgstr "स्क्रिनसट लिनुहोस्" +#: src/core/meta-close-dialog-default.c:161 +msgid "_Force Quit" +msgstr "अन्त्य गर्न दवाब दिनुहोस्" -#: ../src/metacity.schemas.in.h:100 -msgid "Take a screenshot of a window" -msgstr "सञ्झ्यालको स्क्रिनसट लिनुहोस्" +#: src/core/meta-close-dialog-default.c:161 +msgid "_Wait" +msgstr "प्रतिक्षा गर्नुहोस्" -#: ../src/metacity.schemas.in.h:101 +#: src/core/mutter.c:39 +#, fuzzy, c-format +#| msgid "" +#| "metacity %s\n" +#| "Copyright (C) 2001-2007 Havoc Pennington, Red Hat, Inc., and others\n" +#| "This is free software; see the source for copying conditions.\n" +#| "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" msgid "" -"Tells Metacity how to implement the visual indication that the system bell " -"or another application 'bell' indicator has been rung. Currently there are " -"two valid values, \"fullscreen\", which causes a fullscreen white-black " -"flash, and \"frame_flash\" which causes the titlebar of the application " -"which sent the bell signal to flash. If the application which sent the bell " -"is unknown (as is usually the case for the default \"system beep\"), the " -"currently focused window's titlebar is flashed." +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" msgstr "" -"प्रणाली घन्टी वा अन्य अनुप्रयोग 'घन्टी' सूचकले बजाएको घन्टीलाई कसरी दृश्यात्मक सूचकमा प्रयोग गर्ने मेटासिटिले दर्शाउदछ । हाल यहाँ दुईवटा मान्य मानहरू छन्, \"पूरा पर्दा\", जसको " -"कारणले सेतो-कालो पूरा पर्दा फ्ल्यास हुन्छ, र \"फ्रेम फ्ल्यास\", जसको कारणले घन्टी सङ्केत पठाउने अनुप्रयोगको शीर्षकपट्टी फ्ल्यास हुन्छ । यदि अनुरोधपत्र, जसले घन्टी पठाउछ, अज्ञात भएमा (सधैँको जस्तै " -"पूर्वनिर्धारित \"प्रणाली बिप\" का लागि), हाल फोकस गरिएको सञ्झ्याल शिर्षकपट्टी फ्ल्यास हुन्छ ।" +"मेटासिटि %s\n" +"प्रतिलिपि अधिकार (C) २००१-२००७ हावोक पेनिङटोन, रेड ह्याट, संस्था., र अन्य\n" +"यो नि:शुल्क सफ्टवेयर हो; प्रतिलिपि सर्तका लागि स्रोत हेर्नुहोस् ।\n" +"वारेन्टी छैन; ब्यापारीकरण गरिएको छैन वा निश्चित उद्देश्यको लागि मिलाइएको पनि छैन ।\n" -#: ../src/metacity.schemas.in.h:102 -msgid "" -"The /apps/metacity/global_keybindings/run_command_N keys define keybindings " -"that correspond to these commands. Pressing the keybinding for run_command_N " -"will execute command_N." -msgstr "" -" /apps/metacity/global_keybindings/run_command_N कुञ्जीले यी आदेशमा सम्बन्धित कुञ्जी बाइन्डिङलाई परिभाषित गर्दछ । run_command_N " -"का लागि कुञ्जी बाइन्डिङ थिच्दा command_N कार्यान्वयन गर्नेछ ।" +#: src/core/mutter.c:53 +msgid "Print version" +msgstr "मुद्रण संस्करण" -#: ../src/metacity.schemas.in.h:103 -msgid "" -"The /apps/metacity/global_keybindings/run_command_screenshot key defines a " -"keybinding which causes the command specified by this setting to be invoked." -msgstr " /apps/metacity/global_keybindings/run_command_screenshot कुञ्जीले कुञ्जी बाइन्डिङ परिभाषित गर्दछ जसको कारणले यस सेटिङद्वारा निर्दिष्ट गरिएका आदेश आह्वान गरिन्छन् ।" +#: src/core/mutter.c:59 +#, fuzzy +msgid "Mutter plugin to use" +msgstr "प्लगइन निश्चित गर्नका लागि प्रयोग गरिने प्लगइन प्रवन्धक" -#: ../src/metacity.schemas.in.h:104 -msgid "" -"The /apps/metacity/global_keybindings/run_command_window_screenshot key " -"defines a keybinding which causes the command specified by this setting to " -"be invoked." -msgstr "" -" /apps/metacity/global_keybindings/run_command_window_screenshot कुञ्जीले " -"कुञ्जी बाइन्डिङ परिभाषित गर्दछ जसको कारणले यस सेटिङद्वारा निर्दिष्ट गरिएका आदेश आह्वान गर्दछ ।" +#: src/core/prefs.c:1997 +#, c-format +msgid "Workspace %d" +msgstr "कार्यक्षेत्र %d" -#: ../src/metacity.schemas.in.h:105 -msgid "" -"The keybinding that runs the correspondingly-numbered command in /apps/" -"metacity/keybinding_commands The format looks like \"<Control>a\" or " -"\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -"lower or upper case, and also abbreviations such as \"<Ctl>\" and " -"\"<Ctrl>\". If you set the option to the special string \"disabled\", " -"then there will be no keybinding for this action." +#: src/core/screen.c:580 +#, fuzzy, c-format +#| msgid "" +#| "Screen %d on display \"%s\" already has a window manager; try using the --replace option to replace the current " +#| "window manager.\n" +msgid "Display “%s” already has a window manager; try using the --replace option to replace the current window manager." msgstr "" -"/apps/" -"metacity/keybinding_commands मा सङ्गत क्रमाङ्कन गरिएका आदेश चलाउने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा " -"\"<Shift><Alt>F1\" जस्तो देखिन्छ ।" -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, \"<Ctl>\" र " -"\"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +"पर्दा %d को प्रदर्शन \"%s\" मा पहिले नै सञ्झ्याल प्रबन्धक छ; हालको सञ्झ्याल प्रबन्धकलाई बदल्न --बदल्ने विकल्प प्रयोग गर्ने प्रयास गर्नुहोस् ।\n" -#: ../src/metacity.schemas.in.h:106 -msgid "" -"The keybinding that switches to the workspace above the current workspace. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"हालको कार्यक्षेत्रको माथिको कार्यक्षेत्रलाई स्विच गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1" -"\" जस्तो " -"देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#: src/core/screen.c:665 +#, fuzzy, c-format +#| msgid "Screen %d on display '%s' is invalid\n" +msgid "Screen %d on display “%s” is invalid\n" +msgstr "पर्दा %d को प्रदर्शन '%s' अमान्य छ\n" -#: ../src/metacity.schemas.in.h:107 -msgid "" -"The keybinding that switches to the workspace below the current workspace. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"हालको कार्यक्षेत्रको तलको कार्यक्षेत्रलाई स्विच गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1" -"\" जस्तो " -"देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#: src/core/util.c:120 +#, fuzzy +#| msgid "Metacity was compiled without support for verbose mode\n" +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "भर्बोज मोडलाई सहयोग बिनानै मेटासिटि सङ्ग्रह गरियो\n" -#: ../src/metacity.schemas.in.h:108 -msgid "" -"The keybinding that switches to the workspace on the left of the current " -"workspace. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" -"हालको कार्यक्षेत्रको बायाँको कार्यक्षेत्रलाई स्विच गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><" -"Alt>F1\" जस्तो " -"देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#: src/wayland/meta-wayland-tablet-pad.c:563 +#, fuzzy, c-format +msgid "Mode Switch: Mode %d" +msgstr "मोड स्विच (समूह %d)" -#: ../src/metacity.schemas.in.h:109 -msgid "" -"The keybinding that switches to the workspace on the right of the current " -"workspace. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" -"हालको कार्यक्षेत्रको दायाँको कार्यक्षेत्रलाई स्विच गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><" -"Alt>F1\" जस्तो " -"देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#: src/x11/session.c:1815 +#, fuzzy +#| msgid "These windows do not support \"save current setup\" and will have to be restarted manually next time you log in." +msgid "These windows do not support “save current setup” and will have to be restarted manually next time you log in." +msgstr "यस प्रकारका सञ्झ्यालले \"हालको सेटअप बचत गर्नुहोस्\" समर्थन गर्दैन र तपाईँले पछिल्लो पटक लगइन गर्दा म्यानुअली फेरि सुरु गर्नु पर्दछ ।" -#: ../src/metacity.schemas.in.h:110 -msgid "" -"The keybinding that switches to workspace 1. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"कार्यक्षेत्र १ लाई स्विच गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<" -"Control>a\" वा \"<Shift><Alt>F1\" जस्तो " -"देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#: src/x11/window-props.c:559 +#, c-format +msgid "%s (on %s)" +msgstr "%s (मा %s)" -#: ../src/metacity.schemas.in.h:111 -msgid "" -"The keybinding that switches to workspace 10. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"कार्यक्षेत्र १० लाई स्विच गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<" -"Control>a\" वा \"<Shift><Alt>F1\" जस्तो " -"देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Desktop" +#~ msgstr "डेस्कटप" -#: ../src/metacity.schemas.in.h:112 -msgid "" -"The keybinding that switches to workspace 11. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"कार्यक्षेत्र ११ लाई स्विच गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<" -"Control>a\" वा \"<Shift><Alt>F1\" जस्तो " -"देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Window Management" +#~ msgstr "सञ्झ्याल प्रबन्ध" -#: ../src/metacity.schemas.in.h:113 -msgid "" -"The keybinding that switches to workspace 12. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"कार्यक्षेत्र १२ लाई स्विच गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<" -"Control>a\" वा \"<Shift><Alt>F1\" जस्तो " -"देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Usage: %s\n" +#~ msgstr "प्रयोग: %s\n" -#: ../src/metacity.schemas.in.h:114 -msgid "" -"The keybinding that switches to workspace 2. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"कार्यक्षेत्र २ लाई स्विच गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<" -"Control>a\" वा \"<Shift><Alt>F1\" जस्तो " -"देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Unknown window information request: %d" +#~ msgstr "अज्ञात सञ्झ्याल सूचना अनुरोध: %d" -#: ../src/metacity.schemas.in.h:115 -msgid "" -"The keybinding that switches to workspace 3. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"कार्यक्षेत्र ३ लाई स्विच गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<" -"Control>a\" वा \"<Shift><Alt>F1\" जस्तो " -"देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Could not parse \"%s\" as an integer" +#~ msgstr "\"%s\" लाई इन्टिजरको रूपमा व्याख्या गर्न सकेन" -#: ../src/metacity.schemas.in.h:116 -msgid "" -"The keybinding that switches to workspace 4. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"कार्यक्षेत्र ४ लाई स्विच गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<" -"Control>a\" वा \"<Shift><Alt>F1\" जस्तो " -"देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +#~ msgstr "स्ट्रिङ \"%s\" मा पछि रहेका क्यारेक्टर \"%s\" बुझेन" -#: ../src/metacity.schemas.in.h:117 -msgid "" -"The keybinding that switches to workspace 5. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"कार्यक्षेत्र ५ लाई स्विच गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<" -"Control>a\" वा \"<Shift><Alt>F1\" जस्तो " -"देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Failed to parse message \"%s\" from dialog process\n" +#~ msgstr "संवाद प्रक्रियाबाट सन्देश \"%s\" व्याख्या गर्न असफल\n" -#: ../src/metacity.schemas.in.h:118 -msgid "" -"The keybinding that switches to workspace 6. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"कार्यक्षेत्र ६ लाई स्विच गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<" -"Control>a\" वा \"<Shift><Alt>F1\" जस्तो " -"देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Error reading from dialog display process: %s\n" +#~ msgstr "संवाद प्रदर्शन प्रक्रियाबाट पढ्नमा त्रुटि: %s\n" -#: ../src/metacity.schemas.in.h:119 -msgid "" -"The keybinding that switches to workspace 7. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"कार्यक्षेत्र ७ लाई स्विच गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<" -"Control>a\" वा \"<Shift><Alt>F1\" जस्तो " -"देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Error launching metacity-dialog to ask about killing an application: %s\n" +#~ msgstr "एउटा अनुप्रयोग नष्ट गर्ने बारेमा सोध्ने मेटासिटी संवाद सुरुआत गर्दा त्रुटि: %s\n" -#: ../src/metacity.schemas.in.h:120 -msgid "" -"The keybinding that switches to workspace 8. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"कार्यक्षेत्र ८ लाई स्विच गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<" -"Control>a\" वा \"<Shift><Alt>F1\" जस्तो " -"देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Failed to get hostname: %s\n" +#~ msgstr "होस्टनाम प्राप्त गर्न असफल: %s\n" -#: ../src/metacity.schemas.in.h:121 -msgid "" -"The keybinding that switches to workspace 9. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"कार्यक्षेत्र ९ लाई स्विच गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<" -"Control>a\" वा \"<Shift><Alt>F1\" जस्तो " -"देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "" +#~ "Lost connection to the display '%s';\n" +#~ "most likely the X server was shut down or you killed/destroyed\n" +#~ "the window manager.\n" +#~ msgstr "" +#~ "प्रदर्शन '%s' मा जडान छुट्यो;\n" +#~ "X सर्भर बन्द गरिएको वा तपाईँले सञ्झ्याल प्रबन्धक नष्ट/बिगारेको कारणले\n" +#~ "गर्दा प्राय: यस्तो हुन्छ\n" -#: ../src/metacity.schemas.in.h:122 -msgid "" -"The keybinding used to activate the window menu. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"सञ्झ्याल मेनु सक्रिय पार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<" -"Control>a\" वा \"<Shift><Alt>F1\" जस्तो " -"देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Fatal IO error %d (%s) on display '%s'.\n" +#~ msgstr "घातक IO त्रुटि %d (%s) प्रदर्शन '%s' मा ।\n" -#: ../src/metacity.schemas.in.h:123 -msgid "" -"The keybinding used to close a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"सञ्झ्याल बन्द गर्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<" -"Control>a\" वा \"<Shift><Alt>F1\" जस्तो " -"देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Close Window" +#~ msgstr "सञ्झ्याल बन्द गर्नुहोस्" -#: ../src/metacity.schemas.in.h:124 -msgid "" -"The keybinding used to enter \"move mode\" and begin moving a window using " -"the keyboard. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" -"कुञ्जीपाटी प्रयोग गरेर \"सार्ने मोड\" प्रविष्टि गर्न र सञ्झ्याल सार्न सुरु गर्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift>" -"<Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Window Menu" +#~ msgstr "सञ्झ्याल मेनु" -#: ../src/metacity.schemas.in.h:125 -msgid "" -"The keybinding used to enter \"resize mode\" and begin resizing a window " -"using the keyboard. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" -"कुञ्जीपाटी प्रयोग गरेर \"रिसाइज मोड\" प्रविष्टि गर्न र सञ्झ्याल रिसाइज सुरु गर्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<" -"Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>" -"\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Minimize Window" +#~ msgstr "सञ्झ्याल घटाउनुहोस्" -#: ../src/metacity.schemas.in.h:126 -msgid "" -"The keybinding used to hide all normal windows and set the focus to the " -"desktop background. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" -"सबै सामान्य सञ्झ्याललाई लुकाउन र डेस्कटप पृष्ठभूमिमा फोकस सेट गर्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<" -"Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>" -"\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Maximize Window" +#~ msgstr "सञ्झ्याल बढाउनुहोस्" -#: ../src/metacity.schemas.in.h:127 -msgid "" -"The keybinding used to maximize a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"सञ्झ्याललाई बढाउन प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<" -"Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Unmaximize Window" +#~ msgstr "सञ्झ्याल पूर्वस्थितिमा फर्काउनुहोस्" -#: ../src/metacity.schemas.in.h:128 -msgid "" -"The keybinding used to minimize a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"सञ्झ्याललाई घटाउन प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<" -"Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Roll Up Window" +#~ msgstr "सञ्झ्याल माथि रोल गर्नुहोस्" -#: ../src/metacity.schemas.in.h:129 -msgid "" -"The keybinding used to move a window one workspace down. The format looks " -"like \"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -"fairly liberal and allows lower or upper case, and also abbreviations such " -"as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -"special string \"disabled\", then there will be no keybinding for this " -"action." -msgstr "" -"एक कार्यक्षेत्र तल सञ्झ्याल सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Unroll Window" +#~ msgstr "सञ्झ्याल रोल नगर्नुहोस्" -#: ../src/metacity.schemas.in.h:130 -msgid "" -"The keybinding used to move a window one workspace to the left. The format " -"looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -"parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"एक कार्यक्षेत्र बायाँ सञ्झ्याल सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Keep Window On Top" +#~ msgstr "सञ्झ्याललाई माथि राख्नुहोस्" -#: ../src/metacity.schemas.in.h:131 -msgid "" -"The keybinding used to move a window one workspace to the right. The format " -"looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -"parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"एक कार्यक्षेत्र दायाँ सञ्झ्याल सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Remove Window From Top" +#~ msgstr "सञ्झ्याललाई माथिबाट हटाउनुहोस्" -#: ../src/metacity.schemas.in.h:132 -msgid "" -"The keybinding used to move a window one workspace up. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"एक कार्यक्षेत्र माथि सञ्झ्याल सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Always On Visible Workspace" +#~ msgstr "जहिलेपनि दृश्यात्मक कार्यक्षेत्रमा" -#: ../src/metacity.schemas.in.h:133 -msgid "" -"The keybinding used to move a window to workspace 1. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"कार्यक्षेत्र १० मा सञ्झ्याल सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Put Window On Only One Workspace" +#~ msgstr "सञ्झ्याललाई एउटा कार्यक्षेत्रमा मात्र राख्नुहोस्" -#: ../src/metacity.schemas.in.h:134 -msgid "" -"The keybinding used to move a window to workspace 10. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"कार्यक्षेत्र १० मा सञ्झ्याल सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Some other program is already using the key %s with modifiers %x as a binding\n" +#~ msgstr "केही अन्य कार्यक्रमले पहिले नै कुञ्जी %s प्रयोग गरिरहेका छन् जसमा परिमार्जक %x बाइन्डिङका रूपमा छन्\n" -#: ../src/metacity.schemas.in.h:135 -msgid "" -"The keybinding used to move a window to workspace 11. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"कार्यक्षेत्र ११ मा सञ्झ्याल सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Error launching metacity-dialog to print an error about a command: %s\n" +#~ msgstr "आदेश बारेको त्रुटि मुद्रण गर्ने मेटासिटि संवाद सुरुआत गर्दा त्रुटि: %s\n" -#: ../src/metacity.schemas.in.h:136 -msgid "" -"The keybinding used to move a window to workspace 12. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"कार्यक्षेत्र १२ मा सञ्झ्याल सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "No command %d has been defined.\n" +#~ msgstr "आदेश %d परिभाषित गरिएको छैन ।\n" -#: ../src/metacity.schemas.in.h:137 -msgid "" -"The keybinding used to move a window to workspace 2. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"कार्यक्षेत्र २ मा सञ्झ्याल सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "No terminal command has been defined.\n" +#~ msgstr "टर्मिनल आदेश परिभाषित गरिएको छैन ।\n" -#: ../src/metacity.schemas.in.h:138 -msgid "" -"The keybinding used to move a window to workspace 3. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"कार्यक्षेत्र ३ मा सञ्झ्याल सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Failed to scan themes directory: %s\n" +#~ msgstr "विषयवस्तु डाइरेक्टरी स्क्यान गर्न असफल: %s\n" -#: ../src/metacity.schemas.in.h:139 -msgid "" -"The keybinding used to move a window to workspace 4. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"कार्यक्षेत्र ४ मा सञ्झ्याल सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Could not find a theme! Be sure %s exists and contains the usual themes.\n" +#~ msgstr "विषयवस्तु फेला पार्न सकेन ! %s अवस्थित भएको र उपयोगी विषयवस्तु समाविष्ट भएको जाँच गर्नुहोस् ।\n" -#: ../src/metacity.schemas.in.h:140 -msgid "" -"The keybinding used to move a window to workspace 5. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"कार्यक्षेत्र ५ मा सञ्झ्याल सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Failed to restart: %s\n" +#~ msgstr "फेरि सुरु गर्न असफल: %s\n" -#: ../src/metacity.schemas.in.h:141 -msgid "" -"The keybinding used to move a window to workspace 6. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"कार्यक्षेत्र ६ मा सञ्झ्याल सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Mi_nimize" +#~ msgstr "घटाउनुहोस्" -#: ../src/metacity.schemas.in.h:142 -msgid "" -"The keybinding used to move a window to workspace 7. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"कार्यक्षेत्र ७ मा सञ्झ्याल सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Ma_ximize" +#~ msgstr "बढाउनुहोस्" -#: ../src/metacity.schemas.in.h:143 -msgid "" -"The keybinding used to move a window to workspace 8. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"कार्यक्षेत्र ८ मा सञ्झ्याल सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Unma_ximize" +#~ msgstr "पूर्वावस्थामा ल्याउनुहोस्" -#: ../src/metacity.schemas.in.h:144 -msgid "" -"The keybinding used to move a window to workspace 9. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"कार्यक्षेत्र ९ मा सञ्झ्याल सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Roll _Up" +#~ msgstr "माथि रोल गर्नुहोस्" -#: ../src/metacity.schemas.in.h:145 -msgid "" -"The keybinding used to move focus backwards between panels and the desktop, " -"using a popup window. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" -"पपअप सञ्झ्याल प्रयोग गरेर, प्यानल र डेस्कटप बिचमा फोकस पछाडिपट्टी सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<" -"Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>" -"\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "_Unroll" +#~ msgstr "रोल नगर्नुहोस्" -#: ../src/metacity.schemas.in.h:146 -msgid "" -"The keybinding used to move focus backwards between panels and the desktop, " -"without a popup window. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" -"पपअप सञ्झ्याल बिना, प्यानल र डेस्कटप बिचमा फोकस पछाडिपट्टी सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<" -"Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>" -"\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "_Move" +#~ msgstr "सार्नुहोस्" -#: ../src/metacity.schemas.in.h:147 -msgid "" -"The keybinding used to move focus backwards between windows of an " -"application without a popup window. Holding \"shift\" together with this " -"binding makes the direction go forward again. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"पपअप सञ्झ्याल बिना अनुप्रयोगको सञ्झ्याल बीचमा फोकस पछाडिपट्टी सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । \"shift\" कुञ्जीलाई बाइन्डिङ सँगसँगै होल्ड गर्दा दिशा फेरि अगाडि बढ्ने बनाउदछ । ढाँचा \"<" -"Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "_Resize" +#~ msgstr "पूर्वावस्थामा फर्काउनुहोस्" -#: ../src/metacity.schemas.in.h:148 -msgid "" -"The keybinding used to move focus backwards between windows of an " -"application, using a popup window. Holding \"shift\" together with this " -"binding makes the direction go forward again. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"पपअप सञ्झ्याल प्रयोग गरेर, अनुप्रयोगको सञ्झ्याल बीचमा फोकस पछाडिपट्टी सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । \"shift\" कुञ्जीलाई बाइन्डिङ सँगसँगै होल्ड गर्दा दिशा फेरि अगाडि बढ्ने बनाउदछ । ढाँचा \"<" -"Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Move Titlebar On_screen" +#~ msgstr "शीर्षकपट्टीलाई पर्दामा सार्नुहोस्" -#: ../src/metacity.schemas.in.h:149 -msgid "" -"The keybinding used to move focus backwards between windows without a popup " -"window. Holding \"shift\" together with this binding makes the direction go " -"forward again. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" -"पपअप सञ्झ्याल प्रयोग नगरी सञ्झ्याल बीचमा फोकस पछाडिपट्टी सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । \"shift\" कुञ्जीलाई बाइन्डिङ सँगसँगै होल्ड गर्दा दिशा फेरि अगाडि बढ्ने बनाउदछ । ढाँचा \"<Control>a\" वा \"<Shift>" -"<Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Always on _Top" +#~ msgstr "सधैँ माथि" -#: ../src/metacity.schemas.in.h:150 -msgid "" -"The keybinding used to move focus backwards between windows, using a popup " -"window. Holding \"shift\" together with this binding makes the direction go " -"forward again. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" -"पपअप सञ्झ्याल प्रयोग गरेर, सञ्झ्याल बीचमा फोकस पछाडिपट्टी सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । \"shift\" कुञ्जीलाई बाइन्डिङ सँगसँगै होल्ड गर्दा दिशा फेरि अगाडि बढ्ने बनाउदछ । ढाँचा \"<Control>a\" वा \"<Shift>" -"<Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "_Always on Visible Workspace" +#~ msgstr "सधैँ दृश्यात्मक कार्यक्षेत्रमा" -#: ../src/metacity.schemas.in.h:151 -msgid "" -"The keybinding used to move focus between panels and the desktop, using a " -"popup window. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" -"पपअप सञ्झ्याल प्रयोग गरेर, प्यानल र डेस्कटप बीचमा फोकस सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift>" -"<Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "_Only on This Workspace" +#~ msgstr "यस कार्यक्षेत्रमा मात्र" -#: ../src/metacity.schemas.in.h:152 -msgid "" -"The keybinding used to move focus between panels and the desktop, without a " -"popup window. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" -"पपअप सञ्झ्याल बिना, प्यानल र डेस्कटप बीचमा फोकस सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift>" -"<Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Move to Workspace _Up" +#~ msgstr "कार्यक्षेत्र माथि सार्नुहोस्" -#: ../src/metacity.schemas.in.h:153 -msgid "" -"The keybinding used to move focus between windows of an application without " -"a popup window. Holding the \"shift\" key while using this binding reverses " -"the direction of movement. The format looks like \"<Control>a\" or " -"\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -"lower or upper case, and also abbreviations such as \"<Ctl>\" and " -"\"<Ctrl>\". If you set the option to the special string \"disabled\", " -"then there will be no keybinding for this action." -msgstr "" -"पपअप सञ्झ्याल बिना, अनुप्रयोगको सञ्झ्याल बीचमा फोकस सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । यो बाइन्डिङ प्रयोग गर्दा \"shift\" कुञ्जी होल्ड गरेमा चालको दिशा उल्टो बनाउदछ । ढाँचा \"<Control>a\" वा " -"\"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र " -"\"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "_Close" +#~ msgstr "बन्द गर्नुहोस्" -#: ../src/metacity.schemas.in.h:154 -msgid "" -"The keybinding used to move focus between windows of an application, using a " -"popup window. (Traditionally <Alt>F6) Holding the \"shift\" key while " -"using this binding reverses the direction of movement. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"पपअप सञ्झ्याल प्रयोग गरेर, अनुप्रयोगको सञ्झ्याल बीचमा फोकस सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । (परम्परागत रूपमा <Alt>F6) यो बाइन्डिङ प्रयोग गर्दा \"shift\" कुञ्जी होल्ड गरेमा चालको दिशा उल्टो बनाउदछ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Workspace 1_0" +#~ msgstr "कार्यक्षेत्र १_०" -#: ../src/metacity.schemas.in.h:155 -msgid "" -"The keybinding used to move focus between windows without a popup window. " -"(Traditionally <Alt>Escape) Holding the \"shift\" key while using this " -"binding reverses the direction of movement. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"पपअप सञ्झ्याल बिना, सञ्झ्याल बीचमा फोकस सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । " -"(परम्परागत रूपमा <Alt>Escape) यो बाइन्डिङ प्रयोग गर्दा \"shift\" कुञ्जी होल्ड गरेमा चालको दिशा उल्टो बनाउदछ । ढाँचा \"<" -"Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" and \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Workspace %s%d" +#~ msgstr "कार्यक्षेत्र %s%d" -#: ../src/metacity.schemas.in.h:156 -msgid "" -"The keybinding used to move focus between windows, using a popup window. " -"(Traditionally <Alt>Tab) Holding the \"shift\" key while using this " -"binding reverses the direction of movement. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"पपअप सञ्झ्याल प्रयोग गरेर, सञ्झ्याल बीचमा फोकस सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । " -"(परम्परागत रूपमा <Alt>Tab) बाइन्डिङ प्रयोग गर्दा \"shift\" कुञ्जी होल्ड गरेमा चालको दिशा उल्टो बनाउदछ । ढाँचा \"<" -"Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Move to Another _Workspace" +#~ msgstr "अन्य कार्यक्षेत्रमा सार्नुहोस्" -#: ../src/metacity.schemas.in.h:157 -msgid "" -"The keybinding used to toggle always on top. A window that is always on top " -"will always be visible over other overlapping windows. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"सधैँ माथि टगल गर्न प्रयोग गरिने कुञ्जी बाइन्डिङ । सधैँ माथि रहने सञ्झ्याल अन्य खप्टिएका सञ्झ्याल माथि देखिन्छ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Shift" +#~ msgstr "Shift" -#: ../src/metacity.schemas.in.h:158 -msgid "" -"The keybinding used to toggle fullscreen mode. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"पूरा पर्दा मोड टगल गर्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<" -"Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Ctrl" +#~ msgstr "Ctrl" -#: ../src/metacity.schemas.in.h:159 -msgid "" -"The keybinding used to toggle maximization. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"बढाइएकोलाई टगल गर्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<" -"Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Alt" +#~ msgstr "Alt" -#: ../src/metacity.schemas.in.h:160 -msgid "" -"The keybinding used to toggle shaded/unshaded state. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"छाया पारिएको/हटाइएको वस्तुस्थिति टगल गर्न प्रयोग गर्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Meta" +#~ msgstr "Meta" -#: ../src/metacity.schemas.in.h:161 -msgid "" -"The keybinding used to toggle whether the window is on all workspaces or " -"just one. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" -"सञ्झ्याल सबै कार्यक्षेत्र वा केवल एकमा मात्र हुदा टगल गर्न प्रयोग गरिने कुञ्जीबाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><" -"Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Super" +#~ msgstr "Super" -#: ../src/metacity.schemas.in.h:162 -msgid "" -"The keybinding used to unmaximize a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"सञ्झ्याललाई घटाउनका लागि प्रयोग गरिने कुञ्जी बाइन्डिङ । " -"ढाँचा \"<" -"Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Hyper" +#~ msgstr "Hyper" -#: ../src/metacity.schemas.in.h:163 -msgid "" -"The keybinding which display's the panel's \"Run Application\" dialog box. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"प्यानलको \"अनुप्रयोग चलाउनुहोस्\" संवाद बाकस प्रदर्शन गर्ने कुञ्जी बाइन्डिङ । " -"ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1" -"\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Mod2" +#~ msgstr "Mod2" -#: ../src/metacity.schemas.in.h:164 -msgid "" -"The keybinding which invokes a terminal. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"टर्मिनललाई आह्वान गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<" -"Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Mod3" +#~ msgstr "Mod3" -#: ../src/metacity.schemas.in.h:165 -msgid "" -"The keybinding which invokes the panel's screenshot utility to take a " -"screenshot of a window. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" -"सञ्झ्यालको स्क्रिनसट लिनका लागि प्यानलको स्क्रिनसट उपयोगिता आह्वान गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<" -"Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>" -"\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Mod4" +#~ msgstr "Mod4" + +#~ msgid "Mod5" +#~ msgstr "Mod5" -#: ../src/metacity.schemas.in.h:166 -msgid "" -"The keybinding which invokes the panel's screenshot utility. The format " -"looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -"parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"प्यानलको स्क्रिनसट उपयोगिता आह्वान गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Title" +#~ msgstr "शीर्षक" -#: ../src/metacity.schemas.in.h:167 -msgid "" -"The keybinding which shows the panel's main menu. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"प्यानलको मुख्य मेनु देखाउने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Class" +#~ msgstr "वर्ग" -#: ../src/metacity.schemas.in.h:168 -msgid "The name of a workspace." -msgstr "कार्यक्षेत्रको नाम ।" +#~ msgid "" +#~ "There was an error running \"%s\":\n" +#~ "%s." +#~ msgstr "" +#~ " \"%s\" चलाउदा एउटा त्रुटि भयो:\n" +#~ "%s." -#: ../src/metacity.schemas.in.h:169 -msgid "The screenshot command" -msgstr "स्क्रिनसट आदेश" +#~ msgid "Metacity" +#~ msgstr "मेटासिटि" -#: ../src/metacity.schemas.in.h:170 -msgid "" -"The theme determines the appearance of window borders, titlebar, and so " -"forth." -msgstr "विषयवस्तुले सञ्झ्याल, किनारा, शीर्षकपट्टी, र त्यस्तै चौथोको देखावट निर्धारण गर्दछ ।" +#~ msgid "(Not implemented) Navigation works in terms of applications not windows" +#~ msgstr "(कार्यान्वयन नगरिएका) नेभिगेसनले अनुप्रयोगका रूपमा कार्य गर्दछन् सञ्झ्यालमा कार्य गर्दैनन्" -#: ../src/metacity.schemas.in.h:171 -msgid "" -"The time delay before raising a window if auto_raise is set to true. The " -"delay is given in thousandths of a second." -msgstr "यदि स्वत: वृद्धीलाई ठीकमा सेट भएमा सञ्झ्याल वृद्धी हुनु पहिलेको विलम्ब समय । विलम्ब हजारौ सेकेन्डमा दिइएको हुन्छ ।" +#~ msgid "" +#~ "A font description string describing a font for window titlebars. The size from the description will only be used if " +#~ "the titlebar_font_size option is set to 0. Also, this option is disabled if the titlebar_uses_desktop_font option is " +#~ "set to true." +#~ msgstr "" +#~ "सञ्झ्याल शीर्षकपट्टीका लागि फन्ट वर्णन गर्ने फन्ट वर्णन स्ट्रिङ । यदि शीर्षकपट्टी_फन्ट_साइज विकल्प ० मा सेट गरिएमा मात्र वर्णन अनुसारको " +#~ "साइज प्रयोग गरिन्छ । त्यस्तै, यदि शीर्षकपट्टी_प्रयोग_डेस्कटप_फन्ट ठीकमा सेट गरिएमा यस विकल्पलाई अक्षम पारिन्छ ।" -#: ../src/metacity.schemas.in.h:172 -msgid "" -"The window focus mode indicates how windows are activated. It has three " -"possible values; \"click\" means windows must be clicked in order to focus " -"them, \"sloppy\" means windows are focused when the mouse enters the window, " -"and \"mouse\" means windows are focused when the mouse enters the window and " -"unfocused when the mouse leaves the window." -msgstr "" -"सञ्झ्याल फोकस बिधिले सञ्झ्याल कसरी सक्रिय हुन्छन् सङ्केत गर्दछ । यससँग तीनवटा सम्भावित मान हुन्छन्, " -"\"क्लिक\" को अर्थ फोकस गर्नका लागि सञ्झ्यालमा क्लिक गर्नुपर्दछ, \"स्लोपि\" को अर्थ माउस सञ्झ्यालमा प्रविष्टि गर्दा यो फोकस हुन्छ र \"माउस\" को अर्थ माउस सञ्झ्यालमा प्रविष्टि हुदा फोकस हुन्छ र माउसले सञ्झ्याल छोड्दा फोकस हराउदछ ।" +#~ msgid "Action on title bar double-click" +#~ msgstr "शीर्षकपट्टी डबल क्लिक गर्दा हुने कार्य" -#: ../src/metacity.schemas.in.h:173 -msgid "The window screenshot command" -msgstr "सञ्झ्याल स्क्रिनसट आदेश" +#~ msgid "Action on title bar middle-click" +#~ msgstr "शीर्षकपट्टीको बीचमा क्लिक गर्दा हुने कार्य" -#: ../src/metacity.schemas.in.h:174 -msgid "" -"This keybinding changes whether a window is above or below other windows. If " -"the window is covered by another one, it raises the window above all others, " -"and if the window is already fully visible, it lowers it below all others. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"यस कुञ्जी बाइन्डिङले सञ्झ्याल अन्य सञ्झ्याल तल वा माथि भएमा परिवर्तन गर्दछ । यदि सञ्झ्याल अन्य एकद्वारा ढाकिएको भएमा, यसले सञ्झ्याललाई अन्य सबैको माथि ल्याउछ, र यदि सञ्झ्याल पहिला नै पूर्ण दृश्यात्मक भएमा, यसले सञ्झ्याललाई अन्य सबै तल झार्दछ । " -"ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1" -"\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Action on title bar right-click" +#~ msgstr "शीर्षकपट्टीमा दायाँ क्लिक गर्दा हुने कार्य" -#: ../src/metacity.schemas.in.h:175 -msgid "" -"This keybinding lowers a window below other windows. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"यस कुञ्जी बाइन्डिङले सञ्झ्याललाई अन्य सञ्झ्यालको तल झार्दछ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<" -"Ctl>\" and \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Arrangement of buttons on the titlebar" +#~ msgstr "शीर्षकपट्टीमा बटनको प्रबन्ध" -#: ../src/metacity.schemas.in.h:176 -msgid "" -"This keybinding moves a window against the north (top) side of the screen. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"यस कुञ्जी बाइन्डिङले सञ्झ्याललाई पर्दाको उत्तर (माथि) छेउमा सार्दछ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1" -"\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "" +#~ "Arrangement of buttons on the titlebar. The value should be a string, such as \"menu:minimize,maximize,close\"; the " +#~ "colon separates the left corner of the window from the right corner, and the button names are comma-separated. " +#~ "Duplicate buttons are not allowed. Unknown button names are silently ignored so that buttons can be added in future " +#~ "metacity versions without breaking older versions." +#~ msgstr "" +#~ "शिर्षकपट्टीमा बटनको प्रबन्ध । मान स्ट्रिङ हुनुपर्छ, जस्तै \"मेनु: घटाउनुहोस्, बढाउनुहोस्, बन्द गर्नुहोस्\"; विराम चिन्हले दाँया कुनाबाट " +#~ "सञ्झ्यालको बाँया कुना छुट्याउछ र बटन नाम अल्पविरामद्वारा छुट्याइएका हुन्छन् । नक्कली बटनलाई अनुमती छैन । अज्ञात बटनको नामलाई उपेक्षा " +#~ "गरिन्छ, त्यसैले बटनलाई पूरानो संस्करणलाई विच्छेद नगरी भविष्यका मेटासिटि संस्करणमा जोड्न सकिन्छ ।" -#: ../src/metacity.schemas.in.h:177 -msgid "" -"This keybinding moves a window into the east (right) side of the screen. The " -"format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"यस कुञ्जी बाइन्डिङले सञ्झ्याललाई पर्दाको पुर्व (दायाँ) छेउमा सार्दछ । ढाँचा \"<Control>a\" वा \"<Shift><" -"Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Automatically raises the focused window" +#~ msgstr "केन्द्रित सञ्झ्याल स्वचालित रूपमा बढाउदछ" -#: ../src/metacity.schemas.in.h:178 -msgid "" -"This keybinding moves a window into the north-east (top right) corner of the " -"screen. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" -"यस कुञ्जी बाइन्डिङले सञ्झ्याललाई पर्दाको उत्तर-पुर्व (माथि दायाँ) कुनामा सार्दछ । ढाँचा \"<Control>a\" वा \"<Shift><" -"Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "" +#~ "Clicking a window while holding down this modifier key will move the window (left click), resize the window (middle " +#~ "click), or show the window menu (right click). Modifier is expressed as \"<Alt>\" or \"<Super>\" for " +#~ "example." +#~ msgstr "" +#~ "यो परिमार्जक कुञ्जीलाई होल्ड गरेर सञ्झ्यालमा क्लिक गर्दा (बायाँ क्लिक गर्दा) सञ्झ्याललाई सार्दछ, (बीचमा क्लिक गर्दा) सञ्झ्याल रिसाइज " +#~ "गर्दछ, वा (दायाँ क्लिक गर्दा) सञ्झ्याल मेनु देखाउदछ । उदाहरणका लागि परिमार्जकलाई \"<Alt>\" वा \"<Super>\" का रूपमा " +#~ "प्रस्तुत गरिन्छ ।" -#: ../src/metacity.schemas.in.h:179 -msgid "" -"This keybinding moves a window into the north-west (top left) corner of the " -"screen. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" -"यस कुञ्जी बाइन्डिङले सञ्झ्याललाई पर्दाको उत्तर-पश्चिम (माथि बायाँ) कुनामा सार्दछ । ढाँचा \"<Control>a\" वा \"<Shift><" -"Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Commands to run in response to keybindings" +#~ msgstr "कुञ्जी बाइन्डिङको प्रतिक्रियामा चलाइने आदेश" -#: ../src/metacity.schemas.in.h:180 -msgid "" -"This keybinding moves a window into the south (bottom) side of the screen. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"यस कुञ्जी बाइन्डिङले सञ्झ्याललाई पर्दाको दक्षिण (तल) सार्दछ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1" -"\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Compositing Manager" +#~ msgstr "प्रबन्धक रचना गर्दैछ" -#: ../src/metacity.schemas.in.h:181 -msgid "" -"This keybinding moves a window into the south-east (bottom right) corner of " -"the screen. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" -"यस कुञ्जी बाइन्डिङले सञ्झ्याललाई पर्दाको दक्षिण-पुर्व (तल दायाँ) कुनामा सार्दछ । ढाँचा \"<Control>a\" वा \"<Shift><" -"Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Control how new windows get focus" +#~ msgstr "कति नयाँ सञ्झ्यालले फोकस प्राप्त गर्दछन् नियन्त्रण गर्नुहोस्" -#: ../src/metacity.schemas.in.h:182 -msgid "" -"This keybinding moves a window into the south-west (bottom left) corner of " -"the screen. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" -"यस कुञ्जी बाइन्डिङले सञ्झ्याललाई पर्दाको दक्षिण-पश्चिम (तल बायाँ) कुनामा सार्दछ । ढाँचा \"<Control>a\" वा \"<Shift><" -"Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Current theme" +#~ msgstr "हालको विषयवस्तु" -#: ../src/metacity.schemas.in.h:183 -msgid "" -"This keybinding moves a window into the west (left) side of the screen. The " -"format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"यस कुञ्जी बाइन्डिङले सञ्झ्याललाई पर्दाको पश्चिम (बायाँ) छेउमा सार्दछ । ढाँचा " -"\"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Delay in milliseconds for the auto raise option" +#~ msgstr "स्वत बढाउने विकल्पका लागि मिलिसेकेन्ड विलम्ब" -#: ../src/metacity.schemas.in.h:184 -msgid "" -"This keybinding raises the window above other windows. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" -"यस कुञ्जी बाइन्डिङले अन्य सञ्झ्याल माथि सञ्झ्याललाई बढाउदछ । ढाँचा " -"\"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Determines whether Metacity is a compositing manager." +#~ msgstr "मेटासिटि रचना प्रबन्धक हो या होइन निर्धारण गर्दछ ।" -#: ../src/metacity.schemas.in.h:185 -msgid "" -"This keybinding resizes a window to fill available horizontal space. The " -"format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"यस कुञ्जी बाइन्डिङले उपलब्ध ठाडो खालीस्थान भर्न सञ्झ्याल रिसाइज गर्दछ । ढाँचा " -"\"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "" +#~ "Determines whether applications or the system can generate audible 'beeps'; may be used in conjunction with 'visual " +#~ "bell' to allow silent 'beeps'." +#~ msgstr "" +#~ "अनुप्रयोग वा प्रणालीले श्रव्य 'बीप' उत्पन्न गर्न सक्दछ या सक्दैन निर्धारण गर्दछ; मौन 'बीप' लाई अनुमति दिन 'दृश्यात्मक घन्टी' को संयोजकसँग " +#~ "प्रयोग गर्न सकिन्छ ।" -#: ../src/metacity.schemas.in.h:186 -msgid "" -"This keybinding resizes a window to fill available vertical space. The " -"format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" -"यस कुञ्जी बाइन्डिङले उपलब्ध ठाडो खालीस्थान भर्न सञ्झ्याल रिसाइज गर्दछ । ढाँचा " -"\"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " -"पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" +#~ msgid "Disable misfeatures that are required by old or broken applications" +#~ msgstr "पूरानो वा विच्छेद गरिएको अनुप्रयोगलाई आवश्यक हुने विकृत गुण अक्षम पार्नुहोस्" -#: ../src/metacity.schemas.in.h:187 -msgid "" -"This option determines the effects of double-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, 'toggle_maximize' which will maximize/unmaximize the window, " -"'minimize' which will minimize the window, and 'none' which will not do " -"anything." -msgstr "" -"यस विकल्पले शीर्षकपट्टीमा डबल क्लिकको प्रभाव निर्धारण गर्दछ । " -"हालका मान्य विकल्पहरू 'छाया टगल गर्नुहोस्', जसले सञ्झ्यालमा छाया पार्ने/हटाउने गर्दछ, 'बढाइएको टगल गर्नुहोस्' जसले सञ्झ्याल बढाउने/घटाउने गर्दछ, " -"'घटाउनुहोस्' जसले सञ्झ्याल घटाउदछ, र 'कुनै पनि होइन' जसले केही पनि गर्दैन हुन् ।" +#~ msgid "Enable Visual Bell" +#~ msgstr "दृश्यात्मक घन्टी सक्षम पार्नुहोस्" -#: ../src/metacity.schemas.in.h:188 -msgid "" -"This option determines the effects of middle-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, 'toggle_maximize' which will maximize/unmaximize the window, " -"'minimize' which will minimize the window, and 'none' which will not do " -"anything." -msgstr "" -"यस विकल्पले शीर्षकपट्टीमा बीचमा गरेको क्लिकको प्रभाव निर्धारण गर्दछ । " -"हालका मान्य विकल्पहरू 'छाया टगल गर्नुहोस्', जसले सञ्झ्यालमा छाया पार्ने/हटाउने गर्दछ, 'बढाइएको टगल गर्नुहोस्' जसले सञ्झ्याल बढाउने/घटाउने गर्दछ, " -"'घटाउनुहोस्' जसले सञ्झ्याल घटाउदछ, र 'कुनै पनि होइन' जसले केही पनि गर्दैन हुन् ।" +#~ msgid "Hide all windows and focus desktop" +#~ msgstr "सबै सञ्झ्याल लुकाउनुहोस् र डेक्सटपमा फोकस गर्नुहोस्" -#: ../src/metacity.schemas.in.h:189 -msgid "" -"This option determines the effects of right-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, 'toggle_maximize' which will maximize/unmaximize the window, " -"'minimize' which will minimize the window, and 'none' which will not do " -"anything." -msgstr "" -"यस विकल्पले शीर्षकपट्टीमा दायाँ क्लिकको प्रभाव निर्धारण गर्दछ । " -"हालका मान्य विकल्पहरू 'छाया टगल गर्नुहोस्', जसले सञ्झ्यालमा छाया पार्ने/हटाउने गर्दछ, 'बढाइएको टगल गर्नुहोस्' जसले सञ्झ्याल बढाउने/घटाउने गर्दछ, " -"'घटाउनुहोस्' जसले सञ्झ्याल घटाउदछ, र 'कुनै पनि होइन' जसले केही पनि गर्दैन हुन् ।" +#~ msgid "If true, ignore the titlebar_font option, and use the standard application font for window titles." +#~ msgstr "यदि ठीक भएमा, शीर्षकपट्टी फन्ट विकल्पलाई उपेक्षा गर्नुहोस्, र सञ्झ्याल शीर्षकका लागि मानक अनुप्रयोग फन्ट प्रयोग गर्नुहोस् ।" -#: ../src/metacity.schemas.in.h:190 -msgid "" -"This option provides additional control over how newly created windows get " -"focus. It has two possible values; \"smart\" applies the user's normal focus " -"mode, and \"strict\" results in windows started from a terminal not being " -"given focus." -msgstr "यस विकल्पले नयाँ सिर्जना गरिएका सञ्झ्यालले कसरी फोकस प्राप्त गर्दछन् अतिरिक्त नियन्त्रण उपलब्ध गर्दछ । यसका दुई सम्भावित मानहरू छन्; \"छरितो\" ले प्रयोगकर्ताको सामान्य फोकस मोड लागू गर्दछ, र सञ्झ्यालमा \"कठीन\" नतिजा फोकस नदिइएको टर्मिनलबाट सुरु हुन्छ ।" +#~ msgid "" +#~ "If true, metacity will give the user less feedback by using wireframes, avoiding animations, or other means. This is " +#~ "a significant reduction in usability for many users, but may allow legacy applications to continue working, and may " +#~ "also be a useful tradeoff for terminal servers. However, the wireframe feature is disabled when accessibility is on." +#~ msgstr "" +#~ "यदि ठीक भएमा, मेटासिटिले प्रयोगकर्तालाई वायरफ्रेम प्रयोग गरेर, एनिमेसन हटाएर, वा अन्य उद्देश्यले कम पृष्ठपोषण प्रदान गर्दछ । यो धेरै " +#~ "प्रयोगकर्ताको महत्वपूर्ण उपयोगिता न्यूनिकरण हुन सक्छ, तर लेगेसी अनुप्रयोगलाई जारी राख्न अनुमति दिन् सक्दछ, र टर्मिनल सर्भरका लागि " +#~ "व्यापारीकरण गर्न उपयोगी पनि हुनसक्दछ । तापनि, पहुँचता खुला हुदा वायरफ्रेम गुण अक्षम पारिएको हुन्छ ।" -#: ../src/metacity.schemas.in.h:191 -msgid "Toggle always on top state" -msgstr "सधैँ माथि वस्तुस्थितिमा टगल गर्नुहोस्" +#~ msgid "" +#~ "If true, then Metacity works in terms of applications rather than windows. The concept is a bit abstract, but in " +#~ "general an application-based setup is more like the Mac and less like Windows. When you focus a window in application-" +#~ "based mode, all the windows in the application will be raised. Also, in application-based mode, focus clicks are not " +#~ "passed through to windows in other applications. Application-based mode is, however, largely unimplemented at the " +#~ "moment." +#~ msgstr "" +#~ "यदि ठीक भएमा, मेटासिटिले विन्डोजको साटोमा अनुप्रयोगको सर्तमा कार्य गर्दछ ।यो धारणा केही अव्यावहारिक हुन्छ, तर सामान्यतया अनुप्रयोगमा " +#~ "आधारित सेटअप धेरै म्याकसँग मिल्ने र सञ्झ्यालसँग नमिल्ने हुन्छ । तपाईँले सञ्झ्याललाई नुप्रयोगमा आधारित मोडमा फोकस गरेमा, अनुप्रयोगका सबै " +#~ "सञ्झ्याल बढ्नेछन् । त्यस्तै, अनुप्रयोग आधारित मोडमा, फोकस क्लिक अन्य अनुप्रयोगमा सञ्झ्यालबाट पास हुदैनन् । तापनि अनुप्रयोग आधारित मोड, " +#~ "हालको अवस्थामा ठूलो, कार्यान्वयन गर्न नसकिने हुन्छ ।" -#: ../src/metacity.schemas.in.h:192 -msgid "Toggle fullscreen mode" -msgstr "पूरा पर्दा मोड टगल गर्नुहोस्" +#~ msgid "If true, trade off usability for less resource usage" +#~ msgstr "यदि ठीक भएमा, कम स्रोत प्रयोगका लागि व्यापारिकरण उपयोगिता हुन्छ" -#: ../src/metacity.schemas.in.h:193 -msgid "Toggle maximization state" -msgstr "बढाइएको स्थितिलाई टगल गर्नुहोस्" +#~ msgid "Minimize window" +#~ msgstr "सञ्झ्याल घटाउनुहोस्" -#: ../src/metacity.schemas.in.h:194 -msgid "Toggle shaded state" -msgstr "छायाँ पारिएको वस्तुस्थिति टगल गर्नुहोस्" +#~ msgid "Move backward between panels and the desktop immediately" +#~ msgstr "प्यानल र डेक्सटपको बीचमा तुरुन्त पछाडिपट्टि सार्नुहोस् ।" -#: ../src/metacity.schemas.in.h:195 -msgid "Toggle window on all workspaces" -msgstr "सबै कार्यक्षेत्रमा सञ्झ्याल टगल गर्नुहोस्" +#~ msgid "Move backwards between panels and the desktop with popup" +#~ msgstr "पपअप भएको प्यानल र डेक्सटप बीचमा पछाडिपट्टि सार्नुहोस्" -#: ../src/metacity.schemas.in.h:196 -msgid "" -"Turns on a visual indication when an application or the system issues a " -"'bell' or 'beep'; useful for the hard-of-hearing and for use in noisy " -"environments." -msgstr "अनुप्रयोग वा प्रणालीले 'घन्टी' वा 'बीप' जारी गर्दा दृश्यात्मक सङ्केत खोल्दछ; सुन्न नसक्नेलाई र हल्ला हुने परिवेशमा प्रयोग गर्न उपयोगी हुन्छ ।" +#~ msgid "Move backwards between windows immediately" +#~ msgstr "सञ्झ्यालको बिचमा पछाडिपट्टि तुरुन्त सार्नुहोस्" -#: ../src/metacity.schemas.in.h:197 -msgid "Unmaximize window" -msgstr "ठुलो नबनाइएको सञ्झ्याल" +#~ msgid "Move backwards between windows of an application immediately" +#~ msgstr "अनुप्रयोगको सञ्झ्याल बीचमा तुरुन्त पछाडिपट्टि सार्नुहोस्" + +#~ msgid "Move backwards between windows of an application with popup" +#~ msgstr "पपअप भएको अनुप्रयोगको सञ्झ्याल बीचमा पछाडिपट्टि सार्नुहोस्" + +#~ msgid "Move between panels and the desktop immediately" +#~ msgstr "प्यानल र डेस्कटप बीचमा तुरुन्त सार्नुहोस्" + +#~ msgid "Move between panels and the desktop with popup" +#~ msgstr "पपअप भएको प्यानल र डेक्सटप बिचमा सार्नुहोस्" -#: ../src/metacity.schemas.in.h:198 -msgid "Use standard system font in window titles" -msgstr "सञ्झ्याल शीर्षकमा मानक प्रणाली फन्ट प्रयोग गर्नुहोस्" +#~ msgid "Move between windows immediately" +#~ msgstr "सञ्झ्याल बीचमा तुरुन्त सार्नुहोस्" -#: ../src/metacity.schemas.in.h:199 -msgid "Visual Bell Type" -msgstr "दृश्यात्मक घन्टी प्रकार" +#~ msgid "Move focus backwards between windows using popup display" +#~ msgstr "पपअप प्रदर्शन प्रयोग गर्ने सञ्झ्याल बीचमा फोकस पछाडिपट्टि सार्नुहोस्" -#: ../src/metacity.schemas.in.h:200 -msgid "Whether raising should be a side-effect of other user interactions" -msgstr "अन्य प्रयोगकर्ताको अन्तर्क्रिया बढाउदा अप्रत्यक्ष प्रभाव हुनुपर्दछ या पर्दैन" +#~ msgid "Move window to east side of screen" +#~ msgstr "सञ्झ्याललाई पर्दाको पुर्व छेउमा सार्नुहोस्" + +#~ msgid "Move window to north side of screen" +#~ msgstr "सञ्झ्याललाई पर्दाको उत्तर छेउमा सार्नुहोस्" -#: ../src/metacity.schemas.in.h:201 -msgid "Window focus mode" -msgstr "सञ्झ्याल फोकस मोड" +#~ msgid "Move window to north-east corner" +#~ msgstr "सञ्झ्याललाई उत्तर पुर्व कुनामा सार्नुहोस्" -#: ../src/metacity.schemas.in.h:202 -msgid "Window title font" -msgstr "सञ्झ्याल शीर्षक फन्ट" +#~ msgid "Move window to north-west corner" +#~ msgstr "सञ्झ्याललाई उत्तर पश्चिम कुनामा सार्नुहोस्" -#: ../src/prefs.c:434 -#, c-format -msgid "Type of %s was not integer" -msgstr " %s को प्रकार इन्टिजर थिएन" - -#: ../src/prefs.c:572 ../src/prefs.c:600 ../src/prefs.c:616 ../src/prefs.c:632 -#: ../src/prefs.c:648 ../src/prefs.c:664 ../src/prefs.c:680 ../src/prefs.c:696 -#: ../src/prefs.c:716 ../src/prefs.c:732 ../src/prefs.c:748 ../src/prefs.c:766 -#: ../src/prefs.c:782 ../src/prefs.c:801 ../src/prefs.c:817 ../src/prefs.c:852 -#: ../src/prefs.c:868 ../src/prefs.c:885 ../src/prefs.c:901 ../src/prefs.c:917 -#: ../src/prefs.c:933 ../src/prefs.c:949 ../src/prefs.c:964 ../src/prefs.c:979 -#: ../src/prefs.c:994 ../src/prefs.c:1010 ../src/prefs.c:1026 -#: ../src/prefs.c:1042 ../src/prefs.c:1058 -#, c-format -msgid "GConf key \"%s\" is set to an invalid type\n" -msgstr "जीकन्फ कुञ्जी \"%s\" लाई अमान्य प्रकारमा सेट गरिएको छ\n" +#~ msgid "Move window to south side of screen" +#~ msgstr "सञ्झ्याललाई पर्दाको दक्षिण कुनामा सार्नुहोस्" -#: ../src/prefs.c:1103 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "माउस बटन परिमार्जकका लागि कन्फिगरेसन डाटाबेसमा फेला परेको \"%s\" मान्य मान होइन\n" +#~ msgid "Move window to south-east corner" +#~ msgstr "सञ्झ्याललाई पर्दाको दक्षिण पर्व कुनामा सार्नुहोस्" -#: ../src/prefs.c:1127 ../src/prefs.c:1148 ../src/prefs.c:1705 -#, c-format -msgid "GConf key '%s' is set to an invalid value\n" -msgstr "जीकन्फ कुञ्जी \"%s\" लाई अमान्य मानमा सेट गरिएको छ\n" +#~ msgid "Move window to south-west corner" +#~ msgstr "सञ्झ्याललाई पर्दाको दक्षिण पश्चिम कुनामा सार्नुहोस्" -#: ../src/prefs.c:1277 -#, c-format -msgid "" -"%d stored in GConf key %s is not a reasonable cursor_size; must be in the " -"range 1..128\n" -msgstr "%d लाई जीकन्फ कुञ्जी %s मा मौज्दात गरियो जुन उचित साइजमा छैन; दायरा १..१२८ भित्र हुनुपर्दछ\n" +#~ msgid "Move window to west side of screen" +#~ msgstr "सञ्झ्याललाई पर्दाको पश्चिम कुनामा सार्नुहोस्" -#: ../src/prefs.c:1357 -#, c-format -msgid "Could not parse font description \"%s\" from GConf key %s\n" -msgstr "जीकन्फ कुन्जी %s बाट फन्ट वर्णन \"%s\" पद वर्णन गर्न सकेन\n" +#~ msgid "Move window to workspace 10" +#~ msgstr "सञ्झ्याललाई कार्यक्षेत्र १० मा सार्नुहोस्" -#: ../src/prefs.c:1599 -#, c-format -msgid "" -"%d stored in GConf key %s is not a reasonable number of workspaces, current " -"maximum is %d\n" -msgstr "%d लाई जीकन्फ कुञ्जी %s मा मौज्दात गरियो जुन कार्यक्षेत्रको उचित नम्बर होइन, हालको अधिकतम %d हो\n" +#~ msgid "Move window to workspace 11" +#~ msgstr "सञ्झ्याललाई कार्यक्षेत्र ११ मा सार्नुहोस्" -#: ../src/prefs.c:1659 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "विच्छेद अनुप्रयोगका लागि वर्कअराउन्ड अक्षम पारियो । केही अनुप्रयोगले उचित रूपमा कार्य नगर्न सक्दछन् ।\n" +#~ msgid "Move window to workspace 12" +#~ msgstr "सञ्झ्याललाई कार्यक्षेत्र १२ मा सार्नुहोस्" + +#~ msgid "Move window to workspace 5" +#~ msgstr "सञ्झ्याललाई कार्यक्षेत्र ५ मा सार्नुहोस्" + +#~ msgid "Move window to workspace 6" +#~ msgstr "सञ्झ्याललाई कार्यक्षेत्र ६ मा सार्नुहोस्" + +#~ msgid "Move window to workspace 7" +#~ msgstr "सञ्झ्याललाई कार्यक्षेत्र ७ मा सार्नुहोस्" + +#~ msgid "Move window to workspace 8" +#~ msgstr "सञ्झ्याललाई कार्यक्षेत्र ८ मा सार्नुहोस्" + +#~ msgid "Move window to workspace 9" +#~ msgstr "सञ्झ्याललाई कार्यक्षेत्र ९ मा सार्नुहोस्" + +#~ msgid "Name of workspace" +#~ msgstr "कार्यक्षेत्रको नाम" + +#~ msgid "Number of workspaces" +#~ msgstr "कार्यक्षेत्रका सङ्ख्या" + +#~ msgid "" +#~ "Number of workspaces. Must be more than zero, and has a fixed maximum to prevent making the desktop unusable by " +#~ "accidentally asking for too many workspaces." +#~ msgstr "" +#~ "कार्यक्षेत्रका सङ्ख्या । शून्यभन्दा धेरै हुनुपर्दछ, आकस्मिक रूपमा धेरै कार्यक्षेत्रका लागि सोधिने डेस्कटपलाई अनुपयोगी बनाउन अधिकतमलाई निषेधमा " +#~ "निश्चित गरिएको छ ।" + +#~ msgid "Run a defined command" +#~ msgstr "परिभाषित आदेश चलाउनुहोस्" + +#~ msgid "Run a terminal" +#~ msgstr "टर्मिनल चलाउनुहोस्" + +#~ msgid "" +#~ "Setting this option to false can lead to buggy behavior, so users are strongly discouraged from changing it from the " +#~ "default of true. Many actions (e.g. clicking in the client area, moving or resizing the window) normally raise the " +#~ "window as a side-effect. Set this option to false to decouple raising from other user actions. Even when this option " +#~ "is false, windows can still be raised by an alt-left-click anywhere on the window, a normal click on the window " +#~ "decorations, or by special messages from pagers, such as activation requests from tasklist applets. This option is " +#~ "currently disabled in click-to-focus mode. Note that the list of ways to raise windows when raise_on_click is false " +#~ "does not include programmatic requests from applications to raise windows; such requests will be ignored regardless " +#~ "of the reason for the request. If you are an application developer and have a user complaining that your application " +#~ "does not work with this setting disabled, tell them it is _their_ fault for breaking their window manager and that " +#~ "they need to change this option back to true or live with the bug they requested. See also http://bugzilla.gnome.org/" +#~ "show_bug.cgi?id=445447#c6." +#~ msgstr "" +#~ "यस विकल्पलाई गलतमा सेटिङ गर्दा बग व्यवहार अगुवा हुनसक्दछ, त्यसैले प्रयोगकर्तालाई पूर्वनिर्धारित ठीकबाट परिवर्तन गर्न कडाइका साथ " +#~ "निरुत्साहहित गरिन्छ । धेरै कार्यहरू (जस्तै; क्लाइन्ट क्षेत्र भित्र क्लिक गर्दा, सञ्झ्याल सार्दा वा रिसाइज गर्दा) सामान्यतया नकाराम्मक प्रभावले " +#~ "सञ्झ्याललाई बढाउदछ । अन्य प्रयोगकर्ता कार्य बढ्नबाट अलग गर्न यस विकल्पलाई गलतमा सेट गर्नुहोस् । यो विकल्प गलत भएता पनि, सञ्झ्याललाई " +#~ "अझै पनि सञ्झ्यालको कुनै पनि ठाउमा alt-left क्लिक गरेर, सञ्झ्याल सजावटमा सामान्य क्लिक गरेर, वा कार्यसूची एप्लेटका सक्रियता अनुरोध जस्ता " +#~ "पेजरका विशेष सन्देशद्वारा बढाउन सकिन्छ । यस विकल्पलाई click-to-focus मोडमा अक्षम पारिएको छ । याद गर्नुहोस् raise_on_click हुदा " +#~ "सञ्झ्याल बढाउने तरिकाको सूची गलत हो जसले अनुप्रयोगका सञ्झ्याल बढाउने कार्यक्रमिक अनुरोध सम्मिलित गर्दैन; अनुरोधको कारणले पनि त्यस्ता " +#~ "अनुरोध उपेक्षा गरिन्छन् । यदि तपाईँ अनुप्रयोग विकासकर्ता हो र तपाईँको अनुप्रयोगले यस सेटिङसँग कार्य गर्दैन अक्षम पारिएको छ भन्ने प्रयोगकर्ता " +#~ "सिकायत भएमा, प्रयोगकर्तालाई उनीहरूको सञ्झ्याल प्रबन्धक विच्छेद गर्दाको दोसको कारणले भएको र प्रयोगकर्ताले यस विकल्पलाई फेरि ठीकमा सेट " +#~ "गर्नु वा अनुरोध गरिएको त्रुटिसँग चलाउनु पर्ने अवगत गराउनुहोस् । http://bugzilla.gnome.org/show_bug.cgi?id=445447#c6 पनि हेर्नुहोस् ।" + +#~ msgid "Show the panel menu" +#~ msgstr "प्यानल मेनु देखाउनुहोस्" + +#~ msgid "Show the panel run application dialog" +#~ msgstr "प्यानल चल्ने अनुप्रयोग संवाद देखाउनुहोस्" + +#~ msgid "" +#~ "Some applications disregard specifications in ways that result in window manager misfeatures. This option puts " +#~ "Metacity in a rigorously correct mode, which gives a more consistent user interface, provided one does not need to " +#~ "run any misbehaving applications." +#~ msgstr "" +#~ "केही अनुप्रयोगले सञ्झ्याल प्रबन्धकमा नतिजा विकृत हुने तरिकाले विशेष वर्णन अस्वीकार गर्दछन् । यस विकल्पले मेटासिटिलाई कठीन सुधार मोडमा " +#~ "राख्दछ, जसले धेरै अनुकूल प्रयोगकर्ता इन्टरफेस प्रदान गर्दछ, उपलब्ध कुनै एकले अन्य खराब ब्यवहार गर्ने कुनै पनि अनुप्रयोग चलाउनु पर्दैन ।" + +#~ msgid "Switch to workspace above this one" +#~ msgstr "यस भन्दा माथिको कार्यक्षेत्रमा स्विच गर्नुहोस्" + +#~ msgid "Switch to workspace below this one" +#~ msgstr "यस भन्दा मुनिको कार्यक्षेत्रमा स्विच गर्नुहोस्" + +#~ msgid "Switch to workspace on the left" +#~ msgstr "बायाँको कार्यक्षेत्रमा स्विच गर्नुहोस्" + +#~ msgid "Switch to workspace on the right" +#~ msgstr "दायाँको कार्यक्षेत्रमा स्विच गर्नुहोस्" + +#~ msgid "System Bell is Audible" +#~ msgstr "प्रणाली घन्टी सुन्न सकिन्छ" + +#~ msgid "Take a screenshot" +#~ msgstr "स्क्रिनसट लिनुहोस्" + +#~ msgid "Take a screenshot of a window" +#~ msgstr "सञ्झ्यालको स्क्रिनसट लिनुहोस्" + +#~ msgid "" +#~ "Tells Metacity how to implement the visual indication that the system bell or another application 'bell' indicator " +#~ "has been rung. Currently there are two valid values, \"fullscreen\", which causes a fullscreen white-black flash, and " +#~ "\"frame_flash\" which causes the titlebar of the application which sent the bell signal to flash. If the application " +#~ "which sent the bell is unknown (as is usually the case for the default \"system beep\"), the currently focused " +#~ "window's titlebar is flashed." +#~ msgstr "" +#~ "प्रणाली घन्टी वा अन्य अनुप्रयोग 'घन्टी' सूचकले बजाएको घन्टीलाई कसरी दृश्यात्मक सूचकमा प्रयोग गर्ने मेटासिटिले दर्शाउदछ । हाल यहाँ दुईवटा " +#~ "मान्य मानहरू छन्, \"पूरा पर्दा\", जसको कारणले सेतो-कालो पूरा पर्दा फ्ल्यास हुन्छ, र \"फ्रेम फ्ल्यास\", जसको कारणले घन्टी सङ्केत पठाउने " +#~ "अनुप्रयोगको शीर्षकपट्टी फ्ल्यास हुन्छ । यदि अनुरोधपत्र, जसले घन्टी पठाउछ, अज्ञात भएमा (सधैँको जस्तै पूर्वनिर्धारित \"प्रणाली बिप\" का " +#~ "लागि), हाल फोकस गरिएको सञ्झ्याल शिर्षकपट्टी फ्ल्यास हुन्छ ।" + +#~ msgid "" +#~ "The /apps/metacity/global_keybindings/run_command_N keys define keybindings that correspond to these commands. " +#~ "Pressing the keybinding for run_command_N will execute command_N." +#~ msgstr "" +#~ " /apps/metacity/global_keybindings/run_command_N कुञ्जीले यी आदेशमा सम्बन्धित कुञ्जी बाइन्डिङलाई परिभाषित गर्दछ । run_command_N " +#~ "का लागि कुञ्जी बाइन्डिङ थिच्दा command_N कार्यान्वयन गर्नेछ ।" + +#~ msgid "" +#~ "The /apps/metacity/global_keybindings/run_command_screenshot key defines a keybinding which causes the command " +#~ "specified by this setting to be invoked." +#~ msgstr "" +#~ " /apps/metacity/global_keybindings/run_command_screenshot कुञ्जीले कुञ्जी बाइन्डिङ परिभाषित गर्दछ जसको कारणले यस सेटिङद्वारा " +#~ "निर्दिष्ट गरिएका आदेश आह्वान गरिन्छन् ।" + +#~ msgid "" +#~ "The /apps/metacity/global_keybindings/run_command_window_screenshot key defines a keybinding which causes the command " +#~ "specified by this setting to be invoked." +#~ msgstr "" +#~ " /apps/metacity/global_keybindings/run_command_window_screenshot कुञ्जीले कुञ्जी बाइन्डिङ परिभाषित गर्दछ जसको कारणले यस " +#~ "सेटिङद्वारा निर्दिष्ट गरिएका आदेश आह्वान गर्दछ ।" + +#~ msgid "" +#~ "The keybinding that runs the correspondingly-numbered command in /apps/metacity/keybinding_commands The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper " +#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the special " +#~ "string \"disabled\", then there will be no keybinding for this action." +#~ msgstr "" +#~ "/apps/metacity/keybinding_commands मा सङ्गत क्रमाङ्कन गरिएका आदेश चलाउने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<" +#~ "Shift><Alt>F1\" जस्तो देखिन्छ ।पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, \"<Ctl>\" र \"<" +#~ "Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका " +#~ "लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding that switches to the workspace above the current workspace. The format looks like \"<Control>a\" " +#~ "or \"<Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also " +#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", " +#~ "then there will be no keybinding for this action." +#~ msgstr "" +#~ "हालको कार्यक्षेत्रको माथिको कार्यक्षेत्रलाई स्विच गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>" +#~ "F1\" जस्तो देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त " +#~ "रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding that switches to the workspace below the current workspace. The format looks like \"<Control>a\" " +#~ "or \"<Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also " +#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", " +#~ "then there will be no keybinding for this action." +#~ msgstr "" +#~ "हालको कार्यक्षेत्रको तलको कार्यक्षेत्रलाई स्विच गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" " +#~ "जस्तो देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई " +#~ "पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding that switches to the workspace on the left of the current workspace. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, and " +#~ "also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string " +#~ "\"disabled\", then there will be no keybinding for this action." +#~ msgstr "" +#~ "हालको कार्यक्षेत्रको बायाँको कार्यक्षेत्रलाई स्विच गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>" +#~ "F1\" जस्तो देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त " +#~ "रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding that switches to the workspace on the right of the current workspace. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, and " +#~ "also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string " +#~ "\"disabled\", then there will be no keybinding for this action." +#~ msgstr "" +#~ "हालको कार्यक्षेत्रको दायाँको कार्यक्षेत्रलाई स्विच गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>" +#~ "F1\" जस्तो देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त " +#~ "रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding that switches to workspace 1. The format looks like \"<Control>a\" or \"<Shift><Alt>" +#~ "F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>\" and " +#~ "\"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "कार्यक्षेत्र १ लाई स्विच गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । पद " +#~ "वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । " +#~ "यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding that switches to workspace 10. The format looks like \"<Control>a\" or \"<Shift><Alt>" +#~ "F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>\" and " +#~ "\"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "कार्यक्षेत्र १० लाई स्विच गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । पद " +#~ "वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । " +#~ "यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding that switches to workspace 11. The format looks like \"<Control>a\" or \"<Shift><Alt>" +#~ "F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>\" and " +#~ "\"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "कार्यक्षेत्र ११ लाई स्विच गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । पद " +#~ "वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ " +#~ "। यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding that switches to workspace 12. The format looks like \"<Control>a\" or \"<Shift><Alt>" +#~ "F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>\" and " +#~ "\"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "कार्यक्षेत्र १२ लाई स्विच गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । पद " +#~ "वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ " +#~ "। यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding that switches to workspace 2. The format looks like \"<Control>a\" or \"<Shift><Alt>" +#~ "F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>\" and " +#~ "\"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "कार्यक्षेत्र २ लाई स्विच गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । पद " +#~ "वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ " +#~ "। यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding that switches to workspace 3. The format looks like \"<Control>a\" or \"<Shift><Alt>" +#~ "F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>\" and " +#~ "\"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "कार्यक्षेत्र ३ लाई स्विच गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । पद " +#~ "वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ " +#~ "। यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding that switches to workspace 4. The format looks like \"<Control>a\" or \"<Shift><Alt>" +#~ "F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>\" and " +#~ "\"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "कार्यक्षेत्र ४ लाई स्विच गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । पद " +#~ "वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ " +#~ "। यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding that switches to workspace 5. The format looks like \"<Control>a\" or \"<Shift><Alt>" +#~ "F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>\" and " +#~ "\"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "कार्यक्षेत्र ५ लाई स्विच गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । पद " +#~ "वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ " +#~ "। यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding that switches to workspace 6. The format looks like \"<Control>a\" or \"<Shift><Alt>" +#~ "F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>\" and " +#~ "\"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "कार्यक्षेत्र ६ लाई स्विच गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । पद " +#~ "वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ " +#~ "। यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding that switches to workspace 7. The format looks like \"<Control>a\" or \"<Shift><Alt>" +#~ "F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>\" and " +#~ "\"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "कार्यक्षेत्र ७ लाई स्विच गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । पद " +#~ "वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ " +#~ "। यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding that switches to workspace 8. The format looks like \"<Control>a\" or \"<Shift><Alt>" +#~ "F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>\" and " +#~ "\"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "कार्यक्षेत्र ८ लाई स्विच गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । पद " +#~ "वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ " +#~ "। यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding that switches to workspace 9. The format looks like \"<Control>a\" or \"<Shift><Alt>" +#~ "F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>\" and " +#~ "\"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "कार्यक्षेत्र ९ लाई स्विच गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । पद " +#~ "वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ " +#~ "। यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to activate the window menu. The format looks like \"<Control>a\" or \"<Shift><" +#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>" +#~ "\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding " +#~ "for this action." +#~ msgstr "" +#~ "सञ्झ्याल मेनु सक्रिय पार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ " +#~ "। पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति " +#~ "दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to close a window. The format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " +#~ "The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>\" and \"<" +#~ "Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "सञ्झ्याल बन्द गर्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । पद " +#~ "वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ " +#~ "। यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to enter \"move mode\" and begin moving a window using the keyboard. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, and " +#~ "also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string " +#~ "\"disabled\", then there will be no keybinding for this action." +#~ msgstr "" +#~ "कुञ्जीपाटी प्रयोग गरेर \"सार्ने मोड\" प्रविष्टि गर्न र सञ्झ्याल सार्न सुरु गर्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" " +#~ "वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र " +#~ "\"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस " +#~ "कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to enter \"resize mode\" and begin resizing a window using the keyboard. The format looks like " +#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, " +#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string " +#~ "\"disabled\", then there will be no keybinding for this action." +#~ msgstr "" +#~ "कुञ्जीपाटी प्रयोग गरेर \"रिसाइज मोड\" प्रविष्टि गर्न र सञ्झ्याल रिसाइज सुरु गर्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a" +#~ "\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>" +#~ "\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ " +#~ "यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to hide all normal windows and set the focus to the desktop background. The format looks like " +#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, " +#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string " +#~ "\"disabled\", then there will be no keybinding for this action." +#~ msgstr "" +#~ "सबै सामान्य सञ्झ्याललाई लुकाउन र डेस्कटप पृष्ठभूमिमा फोकस सेट गर्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<" +#~ "Shift><Alt>F1\" जस्तो देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<" +#~ "Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका " +#~ "लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to maximize a window. The format looks like \"<Control>a\" or \"<Shift><Alt>" +#~ "F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>\" and " +#~ "\"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "सञ्झ्याललाई बढाउन प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । पद " +#~ "वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ " +#~ "। यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to minimize a window. The format looks like \"<Control>a\" or \"<Shift><Alt>" +#~ "F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>\" and " +#~ "\"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "सञ्झ्याललाई घटाउन प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । पद " +#~ "वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ " +#~ "। यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to move a window one workspace down. The format looks like \"<Control>a\" or \"<Shift>" +#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<" +#~ "Ctl>\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no " +#~ "keybinding for this action." +#~ msgstr "" +#~ "एक कार्यक्षेत्र तल सञ्झ्याल सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो " +#~ "देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि " +#~ "अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to move a window one workspace to the left. The format looks like \"<Control>a\" or \"<" +#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no " +#~ "keybinding for this action." +#~ msgstr "" +#~ "एक कार्यक्षेत्र बायाँ सञ्झ्याल सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" " +#~ "जस्तो देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त " +#~ "रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to move a window one workspace to the right. The format looks like \"<Control>a\" or \"<" +#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no " +#~ "keybinding for this action." +#~ msgstr "" +#~ "एक कार्यक्षेत्र दायाँ सञ्झ्याल सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" " +#~ "जस्तो देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त " +#~ "रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to move a window one workspace up. The format looks like \"<Control>a\" or \"<Shift>" +#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<" +#~ "Ctl>\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no " +#~ "keybinding for this action." +#~ msgstr "" +#~ "एक कार्यक्षेत्र माथि सञ्झ्याल सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" " +#~ "जस्तो देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त " +#~ "रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to move a window to workspace 1. The format looks like \"<Control>a\" or \"<Shift><" +#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>" +#~ "\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding " +#~ "for this action." +#~ msgstr "" +#~ "कार्यक्षेत्र १० मा सञ्झ्याल सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो " +#~ "देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि " +#~ "अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to move a window to workspace 10. The format looks like \"<Control>a\" or \"<Shift>" +#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<" +#~ "Ctl>\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no " +#~ "keybinding for this action." +#~ msgstr "" +#~ "कार्यक्षेत्र १० मा सञ्झ्याल सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो " +#~ "देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि " +#~ "अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to move a window to workspace 11. The format looks like \"<Control>a\" or \"<Shift>" +#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<" +#~ "Ctl>\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no " +#~ "keybinding for this action." +#~ msgstr "" +#~ "कार्यक्षेत्र ११ मा सञ्झ्याल सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो " +#~ "देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि " +#~ "अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to move a window to workspace 12. The format looks like \"<Control>a\" or \"<Shift>" +#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<" +#~ "Ctl>\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no " +#~ "keybinding for this action." +#~ msgstr "" +#~ "कार्यक्षेत्र १२ मा सञ्झ्याल सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो " +#~ "देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि " +#~ "अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to move a window to workspace 2. The format looks like \"<Control>a\" or \"<Shift><" +#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>" +#~ "\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding " +#~ "for this action." +#~ msgstr "" +#~ "कार्यक्षेत्र २ मा सञ्झ्याल सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो " +#~ "देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि " +#~ "अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to move a window to workspace 3. The format looks like \"<Control>a\" or \"<Shift><" +#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>" +#~ "\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding " +#~ "for this action." +#~ msgstr "" +#~ "कार्यक्षेत्र ३ मा सञ्झ्याल सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो " +#~ "देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि " +#~ "अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to move a window to workspace 4. The format looks like \"<Control>a\" or \"<Shift><" +#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>" +#~ "\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding " +#~ "for this action." +#~ msgstr "" +#~ "कार्यक्षेत्र ४ मा सञ्झ्याल सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो " +#~ "देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि " +#~ "अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to move a window to workspace 5. The format looks like \"<Control>a\" or \"<Shift><" +#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>" +#~ "\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding " +#~ "for this action." +#~ msgstr "" +#~ "कार्यक्षेत्र ५ मा सञ्झ्याल सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो " +#~ "देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि " +#~ "अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to move a window to workspace 6. The format looks like \"<Control>a\" or \"<Shift><" +#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>" +#~ "\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding " +#~ "for this action." +#~ msgstr "" +#~ "कार्यक्षेत्र ६ मा सञ्झ्याल सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो " +#~ "देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि " +#~ "अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to move a window to workspace 7. The format looks like \"<Control>a\" or \"<Shift><" +#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>" +#~ "\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding " +#~ "for this action." +#~ msgstr "" +#~ "कार्यक्षेत्र ७ मा सञ्झ्याल सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो " +#~ "देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि " +#~ "अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to move a window to workspace 8. The format looks like \"<Control>a\" or \"<Shift><" +#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>" +#~ "\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding " +#~ "for this action." +#~ msgstr "" +#~ "कार्यक्षेत्र ८ मा सञ्झ्याल सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो " +#~ "देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि " +#~ "अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to move a window to workspace 9. The format looks like \"<Control>a\" or \"<Shift><" +#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>" +#~ "\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding " +#~ "for this action." +#~ msgstr "" +#~ "कार्यक्षेत्र ९ मा सञ्झ्याल सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो " +#~ "देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि " +#~ "अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to move focus backwards between panels and the desktop, using a popup window. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper " +#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the special " +#~ "string \"disabled\", then there will be no keybinding for this action." +#~ msgstr "" +#~ "पपअप सञ्झ्याल प्रयोग गरेर, प्यानल र डेस्कटप बिचमा फोकस पछाडिपट्टी सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा " +#~ "\"<Shift><Alt>F1\" जस्तो देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र " +#~ "\"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस " +#~ "कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to move focus backwards between panels and the desktop, without a popup window. The format looks " +#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper " +#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the special " +#~ "string \"disabled\", then there will be no keybinding for this action." +#~ msgstr "" +#~ "पपअप सञ्झ्याल बिना, प्यानल र डेस्कटप बिचमा फोकस पछाडिपट्टी सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा " +#~ "\"<Shift><Alt>F1\" जस्तो देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र " +#~ "\"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस " +#~ "कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to move focus backwards between windows of an application without a popup window. Holding \"shift" +#~ "\" together with this binding makes the direction go forward again. The format looks like \"<Control>a\" or " +#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there " +#~ "will be no keybinding for this action." +#~ msgstr "" +#~ "पपअप सञ्झ्याल बिना अनुप्रयोगको सञ्झ्याल बीचमा फोकस पछाडिपट्टी सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । \"shift\" कुञ्जीलाई बाइन्डिङ सँगसँगै " +#~ "होल्ड गर्दा दिशा फेरि अगाडि बढ्ने बनाउदछ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । पद " +#~ "वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ " +#~ "। यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to move focus backwards between windows of an application, using a popup window. Holding \"shift" +#~ "\" together with this binding makes the direction go forward again. The format looks like \"<Control>a\" or " +#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there " +#~ "will be no keybinding for this action." +#~ msgstr "" +#~ "पपअप सञ्झ्याल प्रयोग गरेर, अनुप्रयोगको सञ्झ्याल बीचमा फोकस पछाडिपट्टी सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । \"shift\" कुञ्जीलाई बाइन्डिङ " +#~ "सँगसँगै होल्ड गर्दा दिशा फेरि अगाडि बढ्ने बनाउदछ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " +#~ "पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति " +#~ "दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to move focus backwards between windows without a popup window. Holding \"shift\" together with " +#~ "this binding makes the direction go forward again. The format looks like \"<Control>a\" or \"<Shift><" +#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>" +#~ "\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding " +#~ "for this action." +#~ msgstr "" +#~ "पपअप सञ्झ्याल प्रयोग नगरी सञ्झ्याल बीचमा फोकस पछाडिपट्टी सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । \"shift\" कुञ्जीलाई बाइन्डिङ सँगसँगै होल्ड " +#~ "गर्दा दिशा फेरि अगाडि बढ्ने बनाउदछ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । पद वर्णनकर्ता " +#~ "पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि " +#~ "तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to move focus backwards between windows, using a popup window. Holding \"shift\" together with " +#~ "this binding makes the direction go forward again. The format looks like \"<Control>a\" or \"<Shift><" +#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>" +#~ "\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding " +#~ "for this action." +#~ msgstr "" +#~ "पपअप सञ्झ्याल प्रयोग गरेर, सञ्झ्याल बीचमा फोकस पछाडिपट्टी सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । \"shift\" कुञ्जीलाई बाइन्डिङ सँगसँगै होल्ड " +#~ "गर्दा दिशा फेरि अगाडि बढ्ने बनाउदछ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । पद वर्णनकर्ता " +#~ "पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि " +#~ "तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to move focus between panels and the desktop, using a popup window. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, and " +#~ "also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string " +#~ "\"disabled\", then there will be no keybinding for this action." +#~ msgstr "" +#~ "पपअप सञ्झ्याल प्रयोग गरेर, प्यानल र डेस्कटप बीचमा फोकस सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<" +#~ "Shift><Alt>F1\" जस्तो देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<" +#~ "Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका " +#~ "लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to move focus between panels and the desktop, without a popup window. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, and " +#~ "also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string " +#~ "\"disabled\", then there will be no keybinding for this action." +#~ msgstr "" +#~ "पपअप सञ्झ्याल बिना, प्यानल र डेस्कटप बीचमा फोकस सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift>" +#~ "<Alt>F1\" जस्तो देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" " +#~ "जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी " +#~ "बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to move focus between windows of an application without a popup window. Holding the \"shift\" key " +#~ "while using this binding reverses the direction of movement. The format looks like \"<Control>a\" or \"<" +#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no " +#~ "keybinding for this action." +#~ msgstr "" +#~ "पपअप सञ्झ्याल बिना, अनुप्रयोगको सञ्झ्याल बीचमा फोकस सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । यो बाइन्डिङ प्रयोग गर्दा \"shift\" कुञ्जी " +#~ "होल्ड गरेमा चालको दिशा उल्टो बनाउदछ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । पद " +#~ "वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ " +#~ "। यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to move focus between windows of an application, using a popup window. (Traditionally <Alt>" +#~ "F6) Holding the \"shift\" key while using this binding reverses the direction of movement. The format looks like " +#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, " +#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string " +#~ "\"disabled\", then there will be no keybinding for this action." +#~ msgstr "" +#~ "पपअप सञ्झ्याल प्रयोग गरेर, अनुप्रयोगको सञ्झ्याल बीचमा फोकस सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । (परम्परागत रूपमा <Alt>F6) यो " +#~ "बाइन्डिङ प्रयोग गर्दा \"shift\" कुञ्जी होल्ड गरेमा चालको दिशा उल्टो बनाउदछ । ढाँचा \"<Control>a\" वा \"<Shift><" +#~ "Alt>F1\" जस्तो देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता " +#~ "संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी " +#~ "बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to move focus between windows without a popup window. (Traditionally <Alt>Escape) Holding " +#~ "the \"shift\" key while using this binding reverses the direction of movement. The format looks like \"<Control>" +#~ "a\" or \"<Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also " +#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", " +#~ "then there will be no keybinding for this action." +#~ msgstr "" +#~ "पपअप सञ्झ्याल बिना, सञ्झ्याल बीचमा फोकस सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । (परम्परागत रूपमा <Alt>Escape) यो बाइन्डिङ प्रयोग " +#~ "गर्दा \"shift\" कुञ्जी होल्ड गरेमा चालको दिशा उल्टो बनाउदछ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" " +#~ "जस्तो देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" and \"<Ctrl>\" जस्ता संक्षिप्त " +#~ "रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to move focus between windows, using a popup window. (Traditionally <Alt>Tab) Holding the " +#~ "\"shift\" key while using this binding reverses the direction of movement. The format looks like \"<Control>a\" " +#~ "or \"<Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also " +#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", " +#~ "then there will be no keybinding for this action." +#~ msgstr "" +#~ "पपअप सञ्झ्याल प्रयोग गरेर, सञ्झ्याल बीचमा फोकस सार्न प्रयोग गरिने कुञ्जी बाइन्डिङ । (परम्परागत रूपमा <Alt>Tab) बाइन्डिङ प्रयोग " +#~ "गर्दा \"shift\" कुञ्जी होल्ड गरेमा चालको दिशा उल्टो बनाउदछ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" " +#~ "जस्तो देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त " +#~ "रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to toggle always on top. A window that is always on top will always be visible over other " +#~ "overlapping windows. The format looks like \"<Control>a\" or \"<Shift><Alt>F1\". The parser is " +#~ "fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " +#~ "If you set the option to the special string \"disabled\", then there will be no keybinding for this action." +#~ msgstr "" +#~ "सधैँ माथि टगल गर्न प्रयोग गरिने कुञ्जी बाइन्डिङ । सधैँ माथि रहने सञ्झ्याल अन्य खप्टिएका सञ्झ्याल माथि देखिन्छ । ढाँचा \"<Control>a" +#~ "\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>" +#~ "\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ " +#~ "यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to toggle fullscreen mode. The format looks like \"<Control>a\" or \"<Shift><" +#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>" +#~ "\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding " +#~ "for this action." +#~ msgstr "" +#~ "पूरा पर्दा मोड टगल गर्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ " +#~ "। पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति " +#~ "दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to toggle maximization. The format looks like \"<Control>a\" or \"<Shift><Alt>" +#~ "F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>\" and " +#~ "\"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "बढाइएकोलाई टगल गर्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । " +#~ "पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति " +#~ "दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to toggle shaded/unshaded state. The format looks like \"<Control>a\" or \"<Shift><" +#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>" +#~ "\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding " +#~ "for this action." +#~ msgstr "" +#~ "छाया पारिएको/हटाइएको वस्तुस्थिति टगल गर्न प्रयोग गर्न प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift>" +#~ "<Alt>F1\" जस्तो देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" " +#~ "जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी " +#~ "बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to toggle whether the window is on all workspaces or just one. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, and " +#~ "also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string " +#~ "\"disabled\", then there will be no keybinding for this action." +#~ msgstr "" +#~ "सञ्झ्याल सबै कार्यक्षेत्र वा केवल एकमा मात्र हुदा टगल गर्न प्रयोग गरिने कुञ्जीबाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift>" +#~ "<Alt>F1\" जस्तो देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" " +#~ "जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी " +#~ "बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding used to unmaximize a window. The format looks like \"<Control>a\" or \"<Shift><Alt>" +#~ "F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>\" and " +#~ "\"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "सञ्झ्याललाई घटाउनका लागि प्रयोग गरिने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो " +#~ "देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि " +#~ "अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding which display's the panel's \"Run Application\" dialog box. The format looks like \"<Control>a\" " +#~ "or \"<Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also " +#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", " +#~ "then there will be no keybinding for this action." +#~ msgstr "" +#~ "प्यानलको \"अनुप्रयोग चलाउनुहोस्\" संवाद बाकस प्रदर्शन गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><" +#~ "Alt>F1\" जस्तो देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता " +#~ "संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी " +#~ "बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding which invokes a terminal. The format looks like \"<Control>a\" or \"<Shift><Alt>" +#~ "F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>\" and " +#~ "\"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding for this " +#~ "action." +#~ msgstr "" +#~ "टर्मिनललाई आह्वान गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । पद " +#~ "वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ " +#~ "। यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding which invokes the panel's screenshot utility to take a screenshot of a window. The format looks like " +#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, " +#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string " +#~ "\"disabled\", then there will be no keybinding for this action." +#~ msgstr "" +#~ "सञ्झ्यालको स्क्रिनसट लिनका लागि प्यानलको स्क्रिनसट उपयोगिता आह्वान गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<" +#~ "Shift><Alt>F1\" जस्तो देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<" +#~ "Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका " +#~ "लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding which invokes the panel's screenshot utility. The format looks like \"<Control>a\" or \"<" +#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as " +#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no " +#~ "keybinding for this action." +#~ msgstr "" +#~ "प्यानलको स्क्रिनसट उपयोगिता आह्वान गर्ने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो " +#~ "देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि " +#~ "अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "The keybinding which shows the panel's main menu. The format looks like \"<Control>a\" or \"<Shift><" +#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>" +#~ "\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding " +#~ "for this action." +#~ msgstr "" +#~ "प्यानलको मुख्य मेनु देखाउने कुञ्जी बाइन्डिङ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । पद " +#~ "वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ " +#~ "। यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "The name of a workspace." +#~ msgstr "कार्यक्षेत्रको नाम ।" + +#~ msgid "The screenshot command" +#~ msgstr "स्क्रिनसट आदेश" + +#~ msgid "The theme determines the appearance of window borders, titlebar, and so forth." +#~ msgstr "विषयवस्तुले सञ्झ्याल, किनारा, शीर्षकपट्टी, र त्यस्तै चौथोको देखावट निर्धारण गर्दछ ।" + +#~ msgid "" +#~ "The time delay before raising a window if auto_raise is set to true. The delay is given in thousandths of a second." +#~ msgstr "यदि स्वत: वृद्धीलाई ठीकमा सेट भएमा सञ्झ्याल वृद्धी हुनु पहिलेको विलम्ब समय । विलम्ब हजारौ सेकेन्डमा दिइएको हुन्छ ।" + +#~ msgid "" +#~ "The window focus mode indicates how windows are activated. It has three possible values; \"click\" means windows must " +#~ "be clicked in order to focus them, \"sloppy\" means windows are focused when the mouse enters the window, and \"mouse" +#~ "\" means windows are focused when the mouse enters the window and unfocused when the mouse leaves the window." +#~ msgstr "" +#~ "सञ्झ्याल फोकस बिधिले सञ्झ्याल कसरी सक्रिय हुन्छन् सङ्केत गर्दछ । यससँग तीनवटा सम्भावित मान हुन्छन्, \"क्लिक\" को अर्थ फोकस गर्नका लागि " +#~ "सञ्झ्यालमा क्लिक गर्नुपर्दछ, \"स्लोपि\" को अर्थ माउस सञ्झ्यालमा प्रविष्टि गर्दा यो फोकस हुन्छ र \"माउस\" को अर्थ माउस सञ्झ्यालमा " +#~ "प्रविष्टि हुदा फोकस हुन्छ र माउसले सञ्झ्याल छोड्दा फोकस हराउदछ ।" + +#~ msgid "The window screenshot command" +#~ msgstr "सञ्झ्याल स्क्रिनसट आदेश" + +#~ msgid "" +#~ "This keybinding changes whether a window is above or below other windows. If the window is covered by another one, it " +#~ "raises the window above all others, and if the window is already fully visible, it lowers it below all others. The " +#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly liberal and allows " +#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for this action." +#~ msgstr "" +#~ "यस कुञ्जी बाइन्डिङले सञ्झ्याल अन्य सञ्झ्याल तल वा माथि भएमा परिवर्तन गर्दछ । यदि सञ्झ्याल अन्य एकद्वारा ढाकिएको भएमा, यसले सञ्झ्याललाई " +#~ "अन्य सबैको माथि ल्याउछ, र यदि सञ्झ्याल पहिला नै पूर्ण दृश्यात्मक भएमा, यसले सञ्झ्याललाई अन्य सबै तल झार्दछ । ढाँचा \"<Control>a\" " +#~ "वा \"<Shift><Alt>F1\" जस्तो देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र " +#~ "\"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस " +#~ "कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "This keybinding lowers a window below other windows. The format looks like \"<Control>a\" or \"<Shift><" +#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<Ctl>" +#~ "\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no keybinding " +#~ "for this action." +#~ msgstr "" +#~ "यस कुञ्जी बाइन्डिङले सञ्झ्याललाई अन्य सञ्झ्यालको तल झार्दछ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो " +#~ "देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" and \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई " +#~ "पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "This keybinding moves a window against the north (top) side of the screen. The format looks like \"<Control>a\" " +#~ "or \"<Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also " +#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", " +#~ "then there will be no keybinding for this action." +#~ msgstr "" +#~ "यस कुञ्जी बाइन्डिङले सञ्झ्याललाई पर्दाको उत्तर (माथि) छेउमा सार्दछ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>" +#~ "F1\" जस्तो देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त " +#~ "रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "This keybinding moves a window into the east (right) side of the screen. The format looks like \"<Control>a\" " +#~ "or \"<Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also " +#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", " +#~ "then there will be no keybinding for this action." +#~ msgstr "" +#~ "यस कुञ्जी बाइन्डिङले सञ्झ्याललाई पर्दाको पुर्व (दायाँ) छेउमा सार्दछ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" " +#~ "जस्तो देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त " +#~ "रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "This keybinding moves a window into the north-east (top right) corner of the screen. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, and " +#~ "also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string " +#~ "\"disabled\", then there will be no keybinding for this action." +#~ msgstr "" +#~ "यस कुञ्जी बाइन्डिङले सञ्झ्याललाई पर्दाको उत्तर-पुर्व (माथि दायाँ) कुनामा सार्दछ । ढाँचा \"<Control>a\" वा \"<Shift><" +#~ "Alt>F1\" जस्तो देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता " +#~ "संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी " +#~ "बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "This keybinding moves a window into the north-west (top left) corner of the screen. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, and " +#~ "also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string " +#~ "\"disabled\", then there will be no keybinding for this action." +#~ msgstr "" +#~ "यस कुञ्जी बाइन्डिङले सञ्झ्याललाई पर्दाको उत्तर-पश्चिम (माथि बायाँ) कुनामा सार्दछ । ढाँचा \"<Control>a\" वा \"<Shift>" +#~ "<Alt>F1\" जस्तो देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" " +#~ "जस्ता संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी " +#~ "बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "This keybinding moves a window into the south (bottom) side of the screen. The format looks like \"<Control>a\" " +#~ "or \"<Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also " +#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", " +#~ "then there will be no keybinding for this action." +#~ msgstr "" +#~ "यस कुञ्जी बाइन्डिङले सञ्झ्याललाई पर्दाको दक्षिण (तल) सार्दछ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो " +#~ "देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि " +#~ "अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "This keybinding moves a window into the south-east (bottom right) corner of the screen. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, and " +#~ "also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string " +#~ "\"disabled\", then there will be no keybinding for this action." +#~ msgstr "" +#~ "यस कुञ्जी बाइन्डिङले सञ्झ्याललाई पर्दाको दक्षिण-पुर्व (तल दायाँ) कुनामा सार्दछ । ढाँचा \"<Control>a\" वा \"<Shift><" +#~ "Alt>F1\" जस्तो देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता " +#~ "संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी " +#~ "बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "This keybinding moves a window into the south-west (bottom left) corner of the screen. The format looks like \"<" +#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, and " +#~ "also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string " +#~ "\"disabled\", then there will be no keybinding for this action." +#~ msgstr "" +#~ "यस कुञ्जी बाइन्डिङले सञ्झ्याललाई पर्दाको दक्षिण-पश्चिम (तल बायाँ) कुनामा सार्दछ । ढाँचा \"<Control>a\" वा \"<Shift><" +#~ "Alt>F1\" जस्तो देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता " +#~ "संक्षिप्त रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी " +#~ "बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "This keybinding moves a window into the west (left) side of the screen. The format looks like \"<Control>a\" or " +#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there " +#~ "will be no keybinding for this action." +#~ msgstr "" +#~ "यस कुञ्जी बाइन्डिङले सञ्झ्याललाई पर्दाको पश्चिम (बायाँ) छेउमा सार्दछ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>" +#~ "F1\" जस्तो देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त " +#~ "रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "This keybinding raises the window above other windows. The format looks like \"<Control>a\" or \"<Shift>" +#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations such as \"<" +#~ "Ctl>\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there will be no " +#~ "keybinding for this action." +#~ msgstr "" +#~ "यस कुञ्जी बाइन्डिङले अन्य सञ्झ्याल माथि सञ्झ्याललाई बढाउदछ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>F1\" जस्तो " +#~ "देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त रूपलाई पनि " +#~ "अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "This keybinding resizes a window to fill available horizontal space. The format looks like \"<Control>a\" or " +#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there " +#~ "will be no keybinding for this action." +#~ msgstr "" +#~ "यस कुञ्जी बाइन्डिङले उपलब्ध ठाडो खालीस्थान भर्न सञ्झ्याल रिसाइज गर्दछ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>" +#~ "F1\" जस्तो देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त " +#~ "रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "This keybinding resizes a window to fill available vertical space. The format looks like \"<Control>a\" or " +#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows lower or upper case, and also abbreviations " +#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the special string \"disabled\", then there " +#~ "will be no keybinding for this action." +#~ msgstr "" +#~ "यस कुञ्जी बाइन्डिङले उपलब्ध ठाडो खालीस्थान भर्न सञ्झ्याल रिसाइज गर्दछ । ढाँचा \"<Control>a\" वा \"<Shift><Alt>" +#~ "F1\" जस्तो देखिन्छ । पद वर्णनकर्ता पर्याप्त उदार हुन्छ र सानोवर्ण र ठूलोवर्णलाई, र \"<Ctl>\" र \"<Ctrl>\" जस्ता संक्षिप्त " +#~ "रूपलाई पनि अनुमति दिन्छ । यदि तपाईँले विकल्पलाई विशेष स्ट्रिङ \"अक्षम पारिएको\" सेट गरेमा, त्यहाँ यस कार्यका लागि कुञ्जी बाइन्डिङ हुदैन ।" + +#~ msgid "" +#~ "This option determines the effects of double-clicking on the title bar. Current valid options are 'toggle_shade', " +#~ "which will shade/unshade the window, 'toggle_maximize' which will maximize/unmaximize the window, 'minimize' which " +#~ "will minimize the window, and 'none' which will not do anything." +#~ msgstr "" +#~ "यस विकल्पले शीर्षकपट्टीमा डबल क्लिकको प्रभाव निर्धारण गर्दछ । हालका मान्य विकल्पहरू 'छाया टगल गर्नुहोस्', जसले सञ्झ्यालमा छाया पार्ने/" +#~ "हटाउने गर्दछ, 'बढाइएको टगल गर्नुहोस्' जसले सञ्झ्याल बढाउने/घटाउने गर्दछ, 'घटाउनुहोस्' जसले सञ्झ्याल घटाउदछ, र 'कुनै पनि होइन' जसले केही " +#~ "पनि गर्दैन हुन् ।" + +#~ msgid "" +#~ "This option determines the effects of middle-clicking on the title bar. Current valid options are 'toggle_shade', " +#~ "which will shade/unshade the window, 'toggle_maximize' which will maximize/unmaximize the window, 'minimize' which " +#~ "will minimize the window, and 'none' which will not do anything." +#~ msgstr "" +#~ "यस विकल्पले शीर्षकपट्टीमा बीचमा गरेको क्लिकको प्रभाव निर्धारण गर्दछ । हालका मान्य विकल्पहरू 'छाया टगल गर्नुहोस्', जसले सञ्झ्यालमा छाया " +#~ "पार्ने/हटाउने गर्दछ, 'बढाइएको टगल गर्नुहोस्' जसले सञ्झ्याल बढाउने/घटाउने गर्दछ, 'घटाउनुहोस्' जसले सञ्झ्याल घटाउदछ, र 'कुनै पनि होइन' जसले " +#~ "केही पनि गर्दैन हुन् ।" + +#~ msgid "" +#~ "This option determines the effects of right-clicking on the title bar. Current valid options are 'toggle_shade', " +#~ "which will shade/unshade the window, 'toggle_maximize' which will maximize/unmaximize the window, 'minimize' which " +#~ "will minimize the window, and 'none' which will not do anything." +#~ msgstr "" +#~ "यस विकल्पले शीर्षकपट्टीमा दायाँ क्लिकको प्रभाव निर्धारण गर्दछ । हालका मान्य विकल्पहरू 'छाया टगल गर्नुहोस्', जसले सञ्झ्यालमा छाया पार्ने/" +#~ "हटाउने गर्दछ, 'बढाइएको टगल गर्नुहोस्' जसले सञ्झ्याल बढाउने/घटाउने गर्दछ, 'घटाउनुहोस्' जसले सञ्झ्याल घटाउदछ, र 'कुनै पनि होइन' जसले केही " +#~ "पनि गर्दैन हुन् ।" + +#~ msgid "" +#~ "This option provides additional control over how newly created windows get focus. It has two possible values; \"smart" +#~ "\" applies the user's normal focus mode, and \"strict\" results in windows started from a terminal not being given " +#~ "focus." +#~ msgstr "" +#~ "यस विकल्पले नयाँ सिर्जना गरिएका सञ्झ्यालले कसरी फोकस प्राप्त गर्दछन् अतिरिक्त नियन्त्रण उपलब्ध गर्दछ । यसका दुई सम्भावित मानहरू छन्; " +#~ "\"छरितो\" ले प्रयोगकर्ताको सामान्य फोकस मोड लागू गर्दछ, र सञ्झ्यालमा \"कठीन\" नतिजा फोकस नदिइएको टर्मिनलबाट सुरु हुन्छ ।" + +#~ msgid "Toggle always on top state" +#~ msgstr "सधैँ माथि वस्तुस्थितिमा टगल गर्नुहोस्" + +#~ msgid "" +#~ "Turns on a visual indication when an application or the system issues a 'bell' or 'beep'; useful for the hard-of-" +#~ "hearing and for use in noisy environments." +#~ msgstr "" +#~ "अनुप्रयोग वा प्रणालीले 'घन्टी' वा 'बीप' जारी गर्दा दृश्यात्मक सङ्केत खोल्दछ; सुन्न नसक्नेलाई र हल्ला हुने परिवेशमा प्रयोग गर्न उपयोगी हुन्छ ।" + +#~ msgid "Unmaximize window" +#~ msgstr "ठुलो नबनाइएको सञ्झ्याल" + +#~ msgid "Use standard system font in window titles" +#~ msgstr "सञ्झ्याल शीर्षकमा मानक प्रणाली फन्ट प्रयोग गर्नुहोस्" + +#~ msgid "Visual Bell Type" +#~ msgstr "दृश्यात्मक घन्टी प्रकार" + +#~ msgid "Whether raising should be a side-effect of other user interactions" +#~ msgstr "अन्य प्रयोगकर्ताको अन्तर्क्रिया बढाउदा अप्रत्यक्ष प्रभाव हुनुपर्दछ या पर्दैन" + +#~ msgid "Window focus mode" +#~ msgstr "सञ्झ्याल फोकस मोड" + +#~ msgid "Window title font" +#~ msgstr "सञ्झ्याल शीर्षक फन्ट" + +#~ msgid "Type of %s was not integer" +#~ msgstr " %s को प्रकार इन्टिजर थिएन" + +#~ msgid "GConf key \"%s\" is set to an invalid type\n" +#~ msgstr "जीकन्फ कुञ्जी \"%s\" लाई अमान्य प्रकारमा सेट गरिएको छ\n" + +#~ msgid "\"%s\" found in configuration database is not a valid value for mouse button modifier\n" +#~ msgstr "माउस बटन परिमार्जकका लागि कन्फिगरेसन डाटाबेसमा फेला परेको \"%s\" मान्य मान होइन\n" + +#~ msgid "GConf key '%s' is set to an invalid value\n" +#~ msgstr "जीकन्फ कुञ्जी \"%s\" लाई अमान्य मानमा सेट गरिएको छ\n" + +#~ msgid "%d stored in GConf key %s is not a reasonable cursor_size; must be in the range 1..128\n" +#~ msgstr "%d लाई जीकन्फ कुञ्जी %s मा मौज्दात गरियो जुन उचित साइजमा छैन; दायरा १..१२८ भित्र हुनुपर्दछ\n" + +#~ msgid "Could not parse font description \"%s\" from GConf key %s\n" +#~ msgstr "जीकन्फ कुन्जी %s बाट फन्ट वर्णन \"%s\" पद वर्णन गर्न सकेन\n" + +#~ msgid "%d stored in GConf key %s is not a reasonable number of workspaces, current maximum is %d\n" +#~ msgstr "%d लाई जीकन्फ कुञ्जी %s मा मौज्दात गरियो जुन कार्यक्षेत्रको उचित नम्बर होइन, हालको अधिकतम %d हो\n" + +#~ msgid "Workarounds for broken applications disabled. Some applications may not behave properly.\n" +#~ msgstr "विच्छेद अनुप्रयोगका लागि वर्कअराउन्ड अक्षम पारियो । केही अनुप्रयोगले उचित रूपमा कार्य नगर्न सक्दछन् ।\n" # fuzzy, c-format -#: ../src/prefs.c:1732 -#, c-format -msgid "%d stored in GConf key %s is out of range 0 to %d\n" -msgstr "%d लाई जीकन्फ कुञ्जी %s मा मौज्दात गरियो जुन ० देखि %d सम्मको दायरा बाहिर छ\n" +#~ msgid "%d stored in GConf key %s is out of range 0 to %d\n" +#~ msgstr "%d लाई जीकन्फ कुञ्जी %s मा मौज्दात गरियो जुन ० देखि %d सम्मको दायरा बाहिर छ\n" -#: ../src/prefs.c:1881 -#, c-format -msgid "Error setting number of workspaces to %d: %s\n" -msgstr "कार्यक्षेत्रको नम्बर %d: %s मा सेटिङ गर्दा त्रुटि\n" +#~ msgid "Error setting number of workspaces to %d: %s\n" +#~ msgstr "कार्यक्षेत्रको नम्बर %d: %s मा सेटिङ गर्दा त्रुटि\n" -#: ../src/prefs.c:2276 ../src/prefs.c:2446 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "कन्फिगरेसन डाटाबेसमा भेटिएको \"%s\" कुञ्जी बाइन्डिङ \"%s\" का लागि मान्य मान होइन\n" +#~ msgid "\"%s\" found in configuration database is not a valid value for keybinding \"%s\"\n" +#~ msgstr "कन्फिगरेसन डाटाबेसमा भेटिएको \"%s\" कुञ्जी बाइन्डिङ \"%s\" का लागि मान्य मान होइन\n" -#: ../src/prefs.c:2861 -#, c-format -msgid "Error setting name for workspace %d to \"%s\": %s\n" -msgstr "कार्यक्षेत्र %d देखि \"%s\" का लागि नाम सेटिङ गर्दा त्रुटि: %s\n" +#~ msgid "Error setting name for workspace %d to \"%s\": %s\n" +#~ msgstr "कार्यक्षेत्र %d देखि \"%s\" का लागि नाम सेटिङ गर्दा त्रुटि: %s\n" -#: ../src/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" +#~ msgid "%d x %d" +#~ msgstr "%d x %d" -#: ../src/screen.c:410 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "पर्दा %d को प्रदर्शन '%s' अमान्य छ\n" +#~ msgid "Screen %d on display \"%s\" already has a window manager\n" +#~ msgstr "पर्दा %d को प्रदर्शन \"%s\" सँग पहिले नै सञ्झ्याल प्रबन्धक छ\n" -#: ../src/screen.c:426 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"पर्दा %d को प्रदर्शन \"%s\" मा पहिले नै सञ्झ्याल प्रबन्धक छ; हालको सञ्झ्याल प्रबन्धकलाई बदल्न --" -"बदल्ने विकल्प प्रयोग गर्ने प्रयास गर्नुहोस् ।\n" +#~ msgid "Could not release screen %d on display \"%s\"\n" +#~ msgstr "पर्दा %d लाई प्रदर्शन \"%s\" मा निस्कासन गर्न सकेन\n" -#: ../src/screen.c:453 -#, c-format -msgid "Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "पर्दा %d को \"%s\" मा प्रदर्शन गर्दा विन्डो प्रबन्धक छनौट पाउन सक्नु भएन\n" +#~ msgid "Could not create directory '%s': %s\n" +#~ msgstr "डाइरेक्टरी '%s' सिर्जना गर्न सकेन: %s\n" -#: ../src/screen.c:511 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "पर्दा %d को प्रदर्शन \"%s\" सँग पहिले नै सञ्झ्याल प्रबन्धक छ\n" +#~ msgid "Could not open session file '%s' for writing: %s\n" +#~ msgstr "लेखनका लागि सत्र फाइल '%s' खोल्न सकेन: %s\n" -#: ../src/screen.c:716 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "पर्दा %d लाई प्रदर्शन \"%s\" मा निस्कासन गर्न सकेन\n" +#~ msgid "Error writing session file '%s': %s\n" +#~ msgstr "सत्र फाइल '%s' लेखनमा त्रुटि: %s\n" -#: ../src/session.c:826 ../src/session.c:833 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "डाइरेक्टरी '%s' सिर्जना गर्न सकेन: %s\n" +#~ msgid "Error closing session file '%s': %s\n" +#~ msgstr "सत्र फाइल '%s' बन्द गर्दा त्रुटि: %s\n" -#: ../src/session.c:843 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "लेखनका लागि सत्र फाइल '%s' खोल्न सकेन: %s\n" +#~ msgid "Failed to read saved session file %s: %s\n" +#~ msgstr "बचत गरिएका सत्र फाइल %s पढ्न असफल: %s\n" -#: ../src/session.c:995 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "सत्र फाइल '%s' लेखनमा त्रुटि: %s\n" +#~ msgid "Failed to parse saved session file: %s\n" +#~ msgstr "बचत गरिएका सत्र फाइलको पद वर्णन गर्न असफल: %s\n" -#: ../src/session.c:1000 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "सत्र फाइल '%s' बन्द गर्दा त्रुटि: %s\n" +#~ msgid "<metacity_session> attribute seen but we already have the session ID" +#~ msgstr "<metacity_session> गुण देखियो तर हामीले पहिले नै सत्र आइडी लिइसकेका छौ" -#: ../src/session.c:1075 -#, c-format -msgid "Failed to read saved session file %s: %s\n" -msgstr "बचत गरिएका सत्र फाइल %s पढ्न असफल: %s\n" +#~ msgid "Unknown attribute %s on <metacity_session> element" +#~ msgstr "<metacity_session> तत्वमा अज्ञात गुण %s" -#: ../src/session.c:1110 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "बचत गरिएका सत्र फाइलको पद वर्णन गर्न असफल: %s\n" +#~ msgid "nested <window> tag" +#~ msgstr "नेस्टेड <window> ट्याग" -#: ../src/session.c:1159 -msgid "<metacity_session> attribute seen but we already have the session ID" -msgstr "<metacity_session> गुण देखियो तर हामीले पहिले नै सत्र आइडी लिइसकेका छौ" +#~ msgid "Unknown attribute %s on <window> element" +#~ msgstr "<window> तत्वमा अज्ञात गुण %s" -#: ../src/session.c:1172 -#, c-format -msgid "Unknown attribute %s on <metacity_session> element" -msgstr "<metacity_session> तत्वमा अज्ञात गुण %s" +#~ msgid "Unknown attribute %s on <maximized> element" +#~ msgstr "<maximized> तत्वमा अज्ञात गुण %s" -#: ../src/session.c:1189 -msgid "nested <window> tag" -msgstr "नेस्टेड <window> ट्याग" +#~ msgid "Unknown attribute %s on <geometry> element" +#~ msgstr "<geometry> तत्वमा अज्ञात गुण %s" -#: ../src/session.c:1247 ../src/session.c:1279 -#, c-format -msgid "Unknown attribute %s on <window> element" -msgstr "<window> तत्वमा अज्ञात गुण %s" +#~ msgid "Unknown element %s" +#~ msgstr "अज्ञात तत्व %s" -#: ../src/session.c:1351 -#, c-format -msgid "Unknown attribute %s on <maximized> element" -msgstr "<maximized> तत्वमा अज्ञात गुण %s" +#~ msgid "Error launching metacity-dialog to warn about apps that don't support session management: %s\n" +#~ msgstr "सत्र प्रबन्धलाई समर्थन नगर्ने अनुप्रयोगलाई चेतावनी दिने मेटासिटि संवाद सुरुआत गर्दा त्रुटि: %s\n" -#: ../src/session.c:1411 -#, c-format -msgid "Unknown attribute %s on <geometry> element" -msgstr "<geometry> तत्वमा अज्ञात गुण %s" +#~ msgid "Line %d character %d: %s" +#~ msgstr "लाइन %d क्यारेक्टर %d: %s" -#: ../src/session.c:1431 -#, c-format -msgid "Unknown element %s" -msgstr "अज्ञात तत्व %s" +#~ msgid "Attribute \"%s\" repeated twice on the same <%s> element" +#~ msgstr "गुण \"%s\" उस्तै <%s> तत्वमा दुई पटक दोहोरियो" -#: ../src/session.c:1868 -#, c-format -msgid "" -"Error launching metacity-dialog to warn about apps that don't support " -"session management: %s\n" -msgstr "सत्र प्रबन्धलाई समर्थन नगर्ने अनुप्रयोगलाई चेतावनी दिने मेटासिटि संवाद सुरुआत गर्दा त्रुटि: %s\n" +#~ msgid "Attribute \"%s\" is invalid on <%s> element in this context" +#~ msgstr "यो स्थितिमा <%s> तत्वमा \"%s\"गुण अमान्य छ" -#: ../src/theme-parser.c:227 ../src/theme-parser.c:245 -#, c-format -msgid "Line %d character %d: %s" -msgstr "लाइन %d क्यारेक्टर %d: %s" +#~ msgid "Integer %ld must be positive" +#~ msgstr "इन्टिजर %ld धनात्मक हुनुपर्दछ" -#: ../src/theme-parser.c:399 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "गुण \"%s\" उस्तै <%s> तत्वमा दुई पटक दोहोरियो" +#~ msgid "Integer %ld is too large, current max is %d" +#~ msgstr "इनटिजर %ld धेरै ठूलो छ, हालको %d हो" -#: ../src/theme-parser.c:417 ../src/theme-parser.c:442 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "यो स्थितिमा <%s> तत्वमा \"%s\"गुण अमान्य छ" +#~ msgid "Could not parse \"%s\" as a floating point number" +#~ msgstr "उत्प्लावन बिन्दु नम्बरका रूपमा \"%s\" लाई पद वर्णन गर्न सकेन" -#: ../src/theme-parser.c:503 -#, c-format -msgid "Integer %ld must be positive" -msgstr "इन्टिजर %ld धनात्मक हुनुपर्दछ" +#~ msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" +#~ msgstr "बूलियन मान \"ठिक\" वा \"बेठिक\" हुनुपर्छ \"%s\" होइन" -#: ../src/theme-parser.c:511 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "इनटिजर %ld धेरै ठूलो छ, हालको %d हो" +#~ msgid "Angle must be between 0.0 and 360.0, was %g\n" +#~ msgstr "कोण०.० र ३६०.० बीचमा हुनुपर्दछ, %g थियो\n" -#: ../src/theme-parser.c:539 ../src/theme-parser.c:655 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "उत्प्लावन बिन्दु नम्बरका रूपमा \"%s\" लाई पद वर्णन गर्न सकेन" +#~ msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" +#~ msgstr "अल्फा ०.० (अदृश्य) र १.० (पूरै अस्पष्ट) बीचमा हुनुपर्दछ, %g थियो\n" -#: ../src/theme-parser.c:570 ../src/theme-parser.c:598 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "बूलियन मान \"ठिक\" वा \"बेठिक\" हुनुपर्छ \"%s\" होइन" +#~ msgid "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium,large,x-large,xx-large)\n" +#~ msgstr "अमान्य शीर्षक मापन \"%s\" (xx-सानो, x-सानो, सानो, मध्यम, ठूलो, x-ठूलो, xx-ठूलो मध्ये एक हुनुपर्दछ)\n" -#: ../src/theme-parser.c:625 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "कोण०.० र ३६०.० बीचमा हुनुपर्दछ, %g थियो\n" +#~ msgid "No \"%s\" attribute on <%s> element" +#~ msgstr " <%s> तत्वमा \"%s\" गुण छैन" -#: ../src/theme-parser.c:688 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "अल्फा ०.० (अदृश्य) र १.० (पूरै अस्पष्ट) बीचमा हुनुपर्दछ, %g थियो\n" +#~ msgid "<%s> name \"%s\" used a second time" +#~ msgstr "<%s> नाम \"%s\" दोस्रो पटक प्रयोग गरियो" -#: ../src/theme-parser.c:753 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"अमान्य शीर्षक मापन \"%s\" (xx-सानो, x-सानो, सानो, मध्यम, " -"ठूलो, x-ठूलो, xx-ठूलो मध्ये एक हुनुपर्दछ)\n" - -#: ../src/theme-parser.c:798 ../src/theme-parser.c:806 -#: ../src/theme-parser.c:888 ../src/theme-parser.c:985 -#: ../src/theme-parser.c:1027 ../src/theme-parser.c:1138 -#: ../src/theme-parser.c:1188 ../src/theme-parser.c:1196 -#: ../src/theme-parser.c:3074 ../src/theme-parser.c:3163 -#: ../src/theme-parser.c:3170 ../src/theme-parser.c:3177 -#, c-format -msgid "No \"%s\" attribute on <%s> element" -msgstr " <%s> तत्वमा \"%s\" गुण छैन" +#~ msgid "<%s> parent \"%s\" has not been defined" +#~ msgstr "<%s> प्रमूल \"%s\" परिभाषित गरिएको छैन" -#: ../src/theme-parser.c:922 ../src/theme-parser.c:993 -#: ../src/theme-parser.c:1035 ../src/theme-parser.c:1146 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s> नाम \"%s\" दोस्रो पटक प्रयोग गरियो" +#~ msgid "<%s> geometry \"%s\" has not been defined" +#~ msgstr "<%s> जमेट्री \"%s\" परिभाषित गरिएको छैन" -#: ../src/theme-parser.c:934 ../src/theme-parser.c:1047 -#: ../src/theme-parser.c:1158 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "<%s> प्रमूल \"%s\" परिभाषित गरिएको छैन" +#~ msgid "<%s> must specify either a geometry or a parent that has a geometry" +#~ msgstr "<%s> ले जमेट्री भएको यात जमेट्री वा प्रमूल निर्दिष्ट गर्नुपर्दछ" -#: ../src/theme-parser.c:1060 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "<%s> जमेट्री \"%s\" परिभाषित गरिएको छैन" +#~ msgid "You must specify a background for an alpha value to be meaningful" +#~ msgstr "अल्फा मान सार्थक हुनका लागि तपाईँले पृष्ठभूमि निर्दिष्ट गर्नुपर्दछ" -#: ../src/theme-parser.c:1073 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "<%s> ले जमेट्री भएको यात जमेट्री वा प्रमूल निर्दिष्ट गर्नुपर्दछ" +#~ msgid "Unknown type \"%s\" on <%s> element" +#~ msgstr "<%s> तत्वमा अज्ञात प्रकार \"%s\"" -#: ../src/theme-parser.c:1115 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "अल्फा मान सार्थक हुनका लागि तपाईँले पृष्ठभूमि निर्दिष्ट गर्नुपर्दछ" +#~ msgid "Unknown style_set \"%s\" on <%s> element" +#~ msgstr "<%s> तत्वमा अज्ञात शैली सेट \"%s\"" -#: ../src/theme-parser.c:1206 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "<%s> तत्वमा अज्ञात प्रकार \"%s\"" +#~ msgid "Window type \"%s\" has already been assigned a style set" +#~ msgstr "सञ्झ्याल प्रकार \"%s\" सँग शैली सेट पहिले नै मानाङ्कन गरिएको छ" -#: ../src/theme-parser.c:1217 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "<%s> तत्वमा अज्ञात शैली सेट \"%s\"" +#~ msgid "Theme already has a fallback icon" +#~ msgstr "विषयवस्तुमा पहिले नै फलब्याक प्रतिमा छ" -#: ../src/theme-parser.c:1225 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "सञ्झ्याल प्रकार \"%s\" सँग शैली सेट पहिले नै मानाङ्कन गरिएको छ" - -#: ../src/theme-parser.c:1261 -msgid "Theme already has a fallback icon" -msgstr "विषयवस्तुमा पहिले नै फलब्याक प्रतिमा छ" - -#: ../src/theme-parser.c:1273 -msgid "Theme already has a fallback mini_icon" -msgstr "विषयवस्तुमा पहिला नै फलब्याक सानो प्रतिमा छ" - -#: ../src/theme-parser.c:1286 ../src/theme-parser.c:1350 -#: ../src/theme-parser.c:1639 ../src/theme-parser.c:3262 -#: ../src/theme-parser.c:3316 ../src/theme-parser.c:3488 -#: ../src/theme-parser.c:3704 ../src/theme-parser.c:3742 -#: ../src/theme-parser.c:3780 ../src/theme-parser.c:3818 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "<%s> को तल <%s> तत्वलाई अनुमति छैन" +#~ msgid "Theme already has a fallback mini_icon" +#~ msgstr "विषयवस्तुमा पहिला नै फलब्याक सानो प्रतिमा छ" -#: ../src/theme-parser.c:1376 ../src/theme-parser.c:1463 -#: ../src/theme-parser.c:1533 -#, c-format -msgid "No \"name\" attribute on element <%s>" -msgstr "<%s> तत्वमा तत्व \"नाम\" छैन" +#~ msgid "Element <%s> is not allowed below <%s>" +#~ msgstr "<%s> को तल <%s> तत्वलाई अनुमति छैन" -#: ../src/theme-parser.c:1383 ../src/theme-parser.c:1470 -#, c-format -msgid "No \"value\" attribute on element <%s>" -msgstr "<%s> तत्वमा \"मान\" गुण छैन" +#~ msgid "No \"name\" attribute on element <%s>" +#~ msgstr "<%s> तत्वमा तत्व \"नाम\" छैन" -#: ../src/theme-parser.c:1414 ../src/theme-parser.c:1428 -#: ../src/theme-parser.c:1487 -msgid "Cannot specify both button_width/button_height and aspect ratio for buttons" -msgstr "वटनका लागि वटनको चौडाइ/वटनको उचाइ र आकार अनुपात दुबै निर्दिष्ट गर्न सकिँदैन" +#~ msgid "No \"value\" attribute on element <%s>" +#~ msgstr "<%s> तत्वमा \"मान\" गुण छैन" -#: ../src/theme-parser.c:1437 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "दुरी \"%s\" अज्ञात छ" +#~ msgid "Cannot specify both button_width/button_height and aspect ratio for buttons" +#~ msgstr "वटनका लागि वटनको चौडाइ/वटनको उचाइ र आकार अनुपात दुबै निर्दिष्ट गर्न सकिँदैन" -#: ../src/theme-parser.c:1496 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "आकार अनुपात \"%s\" अज्ञात छ ।" +#~ msgid "Distance \"%s\" is unknown" +#~ msgstr "दुरी \"%s\" अज्ञात छ" -#: ../src/theme-parser.c:1540 -#, c-format -msgid "No \"top\" attribute on element <%s>" -msgstr "<%s> तत्वमा \"माथि\" गुण छैन" +#~ msgid "Aspect ratio \"%s\" is unknown" +#~ msgstr "आकार अनुपात \"%s\" अज्ञात छ ।" -#: ../src/theme-parser.c:1547 -#, c-format -msgid "No \"bottom\" attribute on element <%s>" -msgstr "<%s> तत्वमा \"तल\" गुण छैन" +#~ msgid "No \"top\" attribute on element <%s>" +#~ msgstr "<%s> तत्वमा \"माथि\" गुण छैन" -#: ../src/theme-parser.c:1554 -#, c-format -msgid "No \"left\" attribute on element <%s>" -msgstr "<%s> तत्वमा \"बायाँ\" गुण छैन" +#~ msgid "No \"bottom\" attribute on element <%s>" +#~ msgstr "<%s> तत्वमा \"तल\" गुण छैन" -#: ../src/theme-parser.c:1561 -#, c-format -msgid "No \"right\" attribute on element <%s>" -msgstr "<%s> तत्वमा \"दायाँ\" गुण छैन" +#~ msgid "No \"left\" attribute on element <%s>" +#~ msgstr "<%s> तत्वमा \"बायाँ\" गुण छैन" -#: ../src/theme-parser.c:1593 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "किनारा \"%s\" अज्ञात छ" +#~ msgid "No \"right\" attribute on element <%s>" +#~ msgstr "<%s> तत्वमा \"दायाँ\" गुण छैन" -#: ../src/theme-parser.c:1746 ../src/theme-parser.c:1856 -#: ../src/theme-parser.c:1963 ../src/theme-parser.c:2190 -#: ../src/theme-parser.c:3007 -#, c-format -msgid "No \"color\" attribute on element <%s>" -msgstr "<%s> तत्वमा \"रङ\" गुण छैन" +#~ msgid "Border \"%s\" is unknown" +#~ msgstr "किनारा \"%s\" अज्ञात छ" -#: ../src/theme-parser.c:1753 -#, c-format -msgid "No \"x1\" attribute on element <%s>" -msgstr "<%s> तत्वमा \"x1\" गुण छैन" +#~ msgid "No \"color\" attribute on element <%s>" +#~ msgstr "<%s> तत्वमा \"रङ\" गुण छैन" -#: ../src/theme-parser.c:1760 ../src/theme-parser.c:2852 -#, c-format -msgid "No \"y1\" attribute on element <%s>" -msgstr "<%s> तत्वमा \"y1\" गुण छैन" +#~ msgid "No \"x1\" attribute on element <%s>" +#~ msgstr "<%s> तत्वमा \"x1\" गुण छैन" -#: ../src/theme-parser.c:1767 -#, c-format -msgid "No \"x2\" attribute on element <%s>" -msgstr "<%s> तत्वमा \"x2\" गुण छैन" +#~ msgid "No \"y1\" attribute on element <%s>" +#~ msgstr "<%s> तत्वमा \"y1\" गुण छैन" -#: ../src/theme-parser.c:1774 ../src/theme-parser.c:2859 -#, c-format -msgid "No \"y2\" attribute on element <%s>" -msgstr "<%s> तत्वमा \"y2\" गुण छैन" - -#: ../src/theme-parser.c:1863 ../src/theme-parser.c:1970 -#: ../src/theme-parser.c:2116 ../src/theme-parser.c:2197 -#: ../src/theme-parser.c:2303 ../src/theme-parser.c:2401 -#: ../src/theme-parser.c:2621 ../src/theme-parser.c:2747 -#: ../src/theme-parser.c:2845 ../src/theme-parser.c:2919 -#: ../src/theme-parser.c:3014 -#, c-format -msgid "No \"x\" attribute on element <%s>" -msgstr "<%s> तत्वमा \"x\" गुण छैन" - -#: ../src/theme-parser.c:1870 ../src/theme-parser.c:1977 -#: ../src/theme-parser.c:2123 ../src/theme-parser.c:2204 -#: ../src/theme-parser.c:2310 ../src/theme-parser.c:2408 -#: ../src/theme-parser.c:2628 ../src/theme-parser.c:2754 -#: ../src/theme-parser.c:2926 ../src/theme-parser.c:3021 -#, c-format -msgid "No \"y\" attribute on element <%s>" -msgstr "<%s> तत्वमा \"y\" गुण छैन" - -#: ../src/theme-parser.c:1877 ../src/theme-parser.c:1984 -#: ../src/theme-parser.c:2130 ../src/theme-parser.c:2211 -#: ../src/theme-parser.c:2317 ../src/theme-parser.c:2415 -#: ../src/theme-parser.c:2635 ../src/theme-parser.c:2761 -#: ../src/theme-parser.c:2933 -#, c-format -msgid "No \"width\" attribute on element <%s>" -msgstr "<%s> तत्वमा \"चौडाई\" गुण छैन" - -#: ../src/theme-parser.c:1884 ../src/theme-parser.c:1991 -#: ../src/theme-parser.c:2137 ../src/theme-parser.c:2218 -#: ../src/theme-parser.c:2324 ../src/theme-parser.c:2422 -#: ../src/theme-parser.c:2642 ../src/theme-parser.c:2768 -#: ../src/theme-parser.c:2940 -#, c-format -msgid "No \"height\" attribute on element <%s>" -msgstr "तत्व <%s> मा \"उचाइ\" गुण छैन" +#~ msgid "No \"x2\" attribute on element <%s>" +#~ msgstr "<%s> तत्वमा \"x2\" गुण छैन" -#: ../src/theme-parser.c:2000 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "तत्व <%s> मा \"सुरु कोण\" वा \"बाट\" गुण छैन" +#~ msgid "No \"y2\" attribute on element <%s>" +#~ msgstr "<%s> तत्वमा \"y2\" गुण छैन" -#: ../src/theme-parser.c:2007 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "तत्व <%s> मा \"विस्तार कोण\" वा \"लाई\" गुण छैन" +#~ msgid "No \"x\" attribute on element <%s>" +#~ msgstr "<%s> तत्वमा \"x\" गुण छैन" -#: ../src/theme-parser.c:2016 -#, c-format -msgid "No \"start_angle\" attribute on element <%s>" -msgstr "<%s> तत्वमा \"सुरुको कोण\" गुण छैन" +#~ msgid "No \"y\" attribute on element <%s>" +#~ msgstr "<%s> तत्वमा \"y\" गुण छैन" -#: ../src/theme-parser.c:2023 -#, c-format -msgid "No \"extent_angle\" attribute on element <%s>" -msgstr "<%s> तत्वमा \"विस्तार कोण\" गुण छैन" +#~ msgid "No \"width\" attribute on element <%s>" +#~ msgstr "<%s> तत्वमा \"चौडाई\" गुण छैन" -#: ../src/theme-parser.c:2225 -#, c-format -msgid "No \"alpha\" attribute on element <%s>" -msgstr "<%s> तत्वमा \"अल्फा\" गुण छैन" +#~ msgid "No \"height\" attribute on element <%s>" +#~ msgstr "तत्व <%s> मा \"उचाइ\" गुण छैन" -#: ../src/theme-parser.c:2296 -#, c-format -msgid "No \"type\" attribute on element <%s>" -msgstr "<%s> तत्वमा \"प्रकार\" गुण छैन" +#~ msgid "No \"start_angle\" or \"from\" attribute on element <%s>" +#~ msgstr "तत्व <%s> मा \"सुरु कोण\" वा \"बाट\" गुण छैन" -#: ../src/theme-parser.c:2344 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "ग्रेडियन्टको प्रकारका लागि मान \"%s\" पहिचान गरेन" +#~ msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" +#~ msgstr "तत्व <%s> मा \"विस्तार कोण\" वा \"लाई\" गुण छैन" -#: ../src/theme-parser.c:2429 -#, c-format -msgid "No \"filename\" attribute on element <%s>" -msgstr "<%s> तत्वमा \"फाइलनाम\" गुण छैन" +#~ msgid "No \"start_angle\" attribute on element <%s>" +#~ msgstr "<%s> तत्वमा \"सुरुको कोण\" गुण छैन" -#: ../src/theme-parser.c:2454 ../src/theme-parser.c:2965 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "तत्व <%s> का लागि भर्ने प्रकार \"%s\" पहिचान गर्न सकेन" +#~ msgid "No \"extent_angle\" attribute on element <%s>" +#~ msgstr "<%s> तत्वमा \"विस्तार कोण\" गुण छैन" -#: ../src/theme-parser.c:2600 ../src/theme-parser.c:2733 -#: ../src/theme-parser.c:2838 -#, c-format -msgid "No \"state\" attribute on element <%s>" -msgstr "<%s> तत्वमा \"वस्तुस्थिति\" गुण छैन" +#~ msgid "No \"alpha\" attribute on element <%s>" +#~ msgstr "<%s> तत्वमा \"अल्फा\" गुण छैन" -#: ../src/theme-parser.c:2607 ../src/theme-parser.c:2740 -#, c-format -msgid "No \"shadow\" attribute on element <%s>" -msgstr "<%s> तत्वमा \"छाँया\" गुण छैन" +#~ msgid "No \"type\" attribute on element <%s>" +#~ msgstr "<%s> तत्वमा \"प्रकार\" गुण छैन" -#: ../src/theme-parser.c:2614 -#, c-format -msgid "No \"arrow\" attribute on element <%s>" -msgstr "तत्व <%s> मा \"बाण\" गुण छैन" +#~ msgid "Did not understand value \"%s\" for type of gradient" +#~ msgstr "ग्रेडियन्टको प्रकारका लागि मान \"%s\" पहिचान गरेन" -#: ../src/theme-parser.c:2667 ../src/theme-parser.c:2789 -#: ../src/theme-parser.c:2877 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "तत्व <%s> का लागि वस्तुस्थिति \"%s\" पहिचान गरेन" +#~ msgid "No \"filename\" attribute on element <%s>" +#~ msgstr "<%s> तत्वमा \"फाइलनाम\" गुण छैन" -#: ../src/theme-parser.c:2677 ../src/theme-parser.c:2799 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "तत्व <%s> का लागि छाया \"%s\" पहिचान गरेन" +#~ msgid "Did not understand fill type \"%s\" for <%s> element" +#~ msgstr "तत्व <%s> का लागि भर्ने प्रकार \"%s\" पहिचान गर्न सकेन" -#: ../src/theme-parser.c:2687 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "तत्व <%s> का लागि बाण \"%s\" पहिचान गरेन" +#~ msgid "No \"state\" attribute on element <%s>" +#~ msgstr "<%s> तत्वमा \"वस्तुस्थिति\" गुण छैन" -#: ../src/theme-parser.c:3100 ../src/theme-parser.c:3216 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "\"%s\" भनिने <draw_ops> वर्णन गरिएको छैन" +#~ msgid "No \"shadow\" attribute on element <%s>" +#~ msgstr "<%s> तत्वमा \"छाँया\" गुण छैन" -#: ../src/theme-parser.c:3112 ../src/theme-parser.c:3228 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "यहाँ रेखाङ्कन विकल्प \"%s\" सम्मिलित चक्रिय सन्दर्भ सिर्जना गरिन्छ" +#~ msgid "No \"arrow\" attribute on element <%s>" +#~ msgstr "तत्व <%s> मा \"बाण\" गुण छैन" -#: ../src/theme-parser.c:3291 -#, c-format -msgid "No \"value\" attribute on <%s> element" -msgstr "तत्व <%s> मा \"मान\" गुण छैन" +#~ msgid "Did not understand state \"%s\" for <%s> element" +#~ msgstr "तत्व <%s> का लागि वस्तुस्थिति \"%s\" पहिचान गरेन" -#: ../src/theme-parser.c:3348 -#, c-format -msgid "No \"position\" attribute on <%s> element" -msgstr "तत्व <%s> मा \"स्थिति\" गुण छैन" +#~ msgid "Did not understand shadow \"%s\" for <%s> element" +#~ msgstr "तत्व <%s> का लागि छाया \"%s\" पहिचान गरेन" -#: ../src/theme-parser.c:3357 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "फ्रेम टुक्राका लागि अज्ञात स्थिति \"%s\"" +#~ msgid "Did not understand arrow \"%s\" for <%s> element" +#~ msgstr "तत्व <%s> का लागि बाण \"%s\" पहिचान गरेन" -#: ../src/theme-parser.c:3365 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "फ्रेम शैलीको स्थिति %s मा पहिले नै टुक्रा छ" +#~ msgid "No <draw_ops> called \"%s\" has been defined" +#~ msgstr "\"%s\" भनिने <draw_ops> वर्णन गरिएको छैन" -#: ../src/theme-parser.c:3382 ../src/theme-parser.c:3473 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr " \"%s\" नाम भएको <draw_ops> परिभाषित गरिएको छैन" +#~ msgid "Including draw_ops \"%s\" here would create a circular reference" +#~ msgstr "यहाँ रेखाङ्कन विकल्प \"%s\" सम्मिलित चक्रिय सन्दर्भ सिर्जना गरिन्छ" -#: ../src/theme-parser.c:3410 -#, c-format -msgid "No \"function\" attribute on <%s> element" -msgstr "तत्व <%s> मा \"प्रकार्य\" गुण छैन" +#~ msgid "No \"value\" attribute on <%s> element" +#~ msgstr "तत्व <%s> मा \"मान\" गुण छैन" -#: ../src/theme-parser.c:3418 ../src/theme-parser.c:3534 -#, c-format -msgid "No \"state\" attribute on <%s> element" -msgstr "तत्व <%s> मा \"वस्तुस्थिति\" गुण छैन" +#~ msgid "No \"position\" attribute on <%s> element" +#~ msgstr "तत्व <%s> मा \"स्थिति\" गुण छैन" -#: ../src/theme-parser.c:3427 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "बटन \"%s\" का लागि अज्ञात प्रकार्य" +#~ msgid "Unknown position \"%s\" for frame piece" +#~ msgstr "फ्रेम टुक्राका लागि अज्ञात स्थिति \"%s\"" -#: ../src/theme-parser.c:3436 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "बटन प्रकार्य \"%s\" यो संस्करणमा अवस्थित छैन (%d, आवश्यक %d)" +#~ msgid "Frame style already has a piece at position %s" +#~ msgstr "फ्रेम शैलीको स्थिति %s मा पहिले नै टुक्रा छ" -#: ../src/theme-parser.c:3448 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "वटनका लागि अज्ञात स्थिति \"%s\"" +#~ msgid "No <draw_ops> with the name \"%s\" has been defined" +#~ msgstr " \"%s\" नाम भएको <draw_ops> परिभाषित गरिएको छैन" -#: ../src/theme-parser.c:3456 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "प्रकार्य %s वस्तुस्थिति %s का लागि फ्रेम शैलीमा पहिले नै एउटा बटन छ" +#~ msgid "No \"function\" attribute on <%s> element" +#~ msgstr "तत्व <%s> मा \"प्रकार्य\" गुण छैन" -#: ../src/theme-parser.c:3526 -#, c-format -msgid "No \"focus\" attribute on <%s> element" -msgstr "तत्व <%s> मा \"फोकस\" गुण छैन" +#~ msgid "No \"state\" attribute on <%s> element" +#~ msgstr "तत्व <%s> मा \"वस्तुस्थिति\" गुण छैन" -#: ../src/theme-parser.c:3542 -#, c-format -msgid "No \"style\" attribute on <%s> element" -msgstr "तत्व <%s> मा \"शैली\" गुण छैन" +#~ msgid "Unknown function \"%s\" for button" +#~ msgstr "बटन \"%s\" का लागि अज्ञात प्रकार्य" -#: ../src/theme-parser.c:3551 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "फोकस गुणका लागि \"%s\" मान्य मान होइन" +#~ msgid "Button function \"%s\" does not exist in this version (%d, need %d)" +#~ msgstr "बटन प्रकार्य \"%s\" यो संस्करणमा अवस्थित छैन (%d, आवश्यक %d)" -#: ../src/theme-parser.c:3560 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "वस्तुस्थिति गुणका लागि \"%s\" मान्य मान होइन" +#~ msgid "Unknown state \"%s\" for button" +#~ msgstr "वटनका लागि अज्ञात स्थिति \"%s\"" -#: ../src/theme-parser.c:3570 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "\"%s\" भनिने शैली परिभाषित गरिएको छैन" +#~ msgid "Frame style already has a button for function %s state %s" +#~ msgstr "प्रकार्य %s वस्तुस्थिति %s का लागि फ्रेम शैलीमा पहिले नै एउटा बटन छ" -#: ../src/theme-parser.c:3581 -#, c-format -msgid "No \"resize\" attribute on <%s> element" -msgstr "तत्व <%s> मा \"रिसाइज\" गुण छैन" +#~ msgid "No \"focus\" attribute on <%s> element" +#~ msgstr "तत्व <%s> मा \"फोकस\" गुण छैन" -#: ../src/theme-parser.c:3591 ../src/theme-parser.c:3614 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "रिसाइज गुणका लागि \"%s\" मान्य मान होइन" +#~ msgid "No \"style\" attribute on <%s> element" +#~ msgstr "तत्व <%s> मा \"शैली\" गुण छैन" -#: ../src/theme-parser.c:3625 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "बढाइएका/छाया पारिएका वस्तुस्थितिका लागि <%s> तत्वमा \"रिसाइज\" गुण हुनुहुदैन" +#~ msgid "\"%s\" is not a valid value for focus attribute" +#~ msgstr "फोकस गुणका लागि \"%s\" मान्य मान होइन" -#: ../src/theme-parser.c:3639 -#, c-format -msgid "Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "बढाइएका वस्तुस्थितिका लागि <%s> तत्वमा \"रिसाइज\" गुण हुनुहुदैन" +#~ msgid "\"%s\" is not a valid value for state attribute" +#~ msgstr "वस्तुस्थिति गुणका लागि \"%s\" मान्य मान होइन" -#: ../src/theme-parser.c:3653 ../src/theme-parser.c:3675 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "वस्तुस्थिति %s रिसाइज %s फोकस %s का लागि शैली पहिले नै निर्दिष्ट गरिएको छ" +#~ msgid "A style called \"%s\" has not been defined" +#~ msgstr "\"%s\" भनिने शैली परिभाषित गरिएको छैन" -#: ../src/theme-parser.c:3664 ../src/theme-parser.c:3686 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "वस्तुस्थिति %s फोकस %s का लागि शैली पहिले नै निर्दिष्ट गरिएको छ" +#~ msgid "No \"resize\" attribute on <%s> element" +#~ msgstr "तत्व <%s> मा \"रिसाइज\" गुण छैन" -#: ../src/theme-parser.c:3725 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "<piece> तत्वको लागी दुई रेखाङ्कन विकल्प राख्न सकिँदैन (विषयवस्तु निर्दिष्ट गरिएका रेखाङ्कन विकल्प गुण र एउटा <draw_ops> तत्व, वा निर्दिष्ट गरिएका दुई तत्व पनि)" +#~ msgid "\"%s\" is not a valid value for resize attribute" +#~ msgstr "रिसाइज गुणका लागि \"%s\" मान्य मान होइन" -#: ../src/theme-parser.c:3763 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "<button> बटनका लागि दुई रेखाङ्कन विकल्प राख्न सकिँदैन (विषयवस्तु निर्दिष्ट गरिएका रेखाङ्कन विकल्प गुण र एउटा <draw_ops> तत्व, वा निर्दिष्ट गरिएका दुई तत्व पनि)" +#~ msgid "Should not have \"resize\" attribute on <%s> element for maximized/shaded states" +#~ msgstr "बढाइएका/छाया पारिएका वस्तुस्थितिका लागि <%s> तत्वमा \"रिसाइज\" गुण हुनुहुदैन" -#: ../src/theme-parser.c:3801 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "तत्व <menu_icon> का लागि दुई रेखाङ्कन विकल्प राख्न सकिँदैन (विषयवस्तु निर्दिष्ट गरिएका रेखाङ्कन विकल्प गुण र एउटा <draw_ops> तत्व, वा निर्दिष्ट गरिएका दुई तत्व पनि)" +#~ msgid "Should not have \"resize\" attribute on <%s> element for maximized states" +#~ msgstr "बढाइएका वस्तुस्थितिका लागि <%s> तत्वमा \"रिसाइज\" गुण हुनुहुदैन" -#: ../src/theme-parser.c:3849 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "विषयवस्तुको सबैभन्दा बाहिरको तत्व <metacity_theme> नहुनुपर्दछ <%s>" +#~ msgid "Style has already been specified for state %s resize %s focus %s" +#~ msgstr "वस्तुस्थिति %s रिसाइज %s फोकस %s का लागि शैली पहिले नै निर्दिष्ट गरिएको छ" -#: ../src/theme-parser.c:3869 -#, c-format -msgid "Element <%s> is not allowed inside a name/author/date/description element" -msgstr "तत्व <%s> लाई name/author/date/description तत्व भित्र अनुमति छैन" +#~ msgid "Style has already been specified for state %s focus %s" +#~ msgstr "वस्तुस्थिति %s फोकस %s का लागि शैली पहिले नै निर्दिष्ट गरिएको छ" -#: ../src/theme-parser.c:3874 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "तत्व <%s> लाई <constant> तत्व भित्र अनुमति छैन" +#~ msgid "" +#~ "Can't have a two draw_ops for a <piece> element (theme specified a draw_ops attribute and also a <draw_ops> element, " +#~ "or specified two elements)" +#~ msgstr "" +#~ "<piece> तत्वको लागी दुई रेखाङ्कन विकल्प राख्न सकिँदैन (विषयवस्तु निर्दिष्ट गरिएका रेखाङ्कन विकल्प गुण र एउटा <draw_ops> तत्व, वा " +#~ "निर्दिष्ट गरिएका दुई तत्व पनि)" -#: ../src/theme-parser.c:3886 -#, c-format -msgid "Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "तत्व <%s> लाई distance/border/aspect_ratio तत्व भित्र अनुमति छैन" +#~ msgid "" +#~ "Can't have a two draw_ops for a <button> element (theme specified a draw_ops attribute and also a <draw_ops> element, " +#~ "or specified two elements)" +#~ msgstr "" +#~ "<button> बटनका लागि दुई रेखाङ्कन विकल्प राख्न सकिँदैन (विषयवस्तु निर्दिष्ट गरिएका रेखाङ्कन विकल्प गुण र एउटा <draw_ops> तत्व, वा " +#~ "निर्दिष्ट गरिएका दुई तत्व पनि)" -#: ../src/theme-parser.c:3908 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "तत्व <%s> लाई रेखाङ्कन कार्य तत्व भित्र अनुमती छैन" +#~ msgid "" +#~ "Can't have a two draw_ops for a <menu_icon> element (theme specified a draw_ops attribute and also a <draw_ops> " +#~ "element, or specified two elements)" +#~ msgstr "" +#~ "तत्व <menu_icon> का लागि दुई रेखाङ्कन विकल्प राख्न सकिँदैन (विषयवस्तु निर्दिष्ट गरिएका रेखाङ्कन विकल्प गुण र एउटा <draw_ops> तत्व, वा " +#~ "निर्दिष्ट गरिएका दुई तत्व पनि)" -#: ../src/theme-parser.c:3918 ../src/theme-parser.c:3948 -#: ../src/theme-parser.c:3953 ../src/theme-parser.c:3958 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "<%s>तत्व भित्र <%s>तत्वलाई अनुमति छैन" +#~ msgid "Outermost element in theme must be <metacity_theme> not <%s>" +#~ msgstr "विषयवस्तुको सबैभन्दा बाहिरको तत्व <metacity_theme> नहुनुपर्दछ <%s>" -#: ../src/theme-parser.c:4180 -msgid "No draw_ops provided for frame piece" -msgstr "फ्रेम टुक्राका लागि रेखाङ्कन विकल्प उपलब्ध छैन" +#~ msgid "Element <%s> is not allowed inside a name/author/date/description element" +#~ msgstr "तत्व <%s> लाई name/author/date/description तत्व भित्र अनुमति छैन" -#: ../src/theme-parser.c:4195 -msgid "No draw_ops provided for button" -msgstr "बटनका लागि कुनै रेखाङ्कन विकल्प उपलब्ध छैन" +#~ msgid "Element <%s> is not allowed inside a <constant> element" +#~ msgstr "तत्व <%s> लाई <constant> तत्व भित्र अनुमति छैन" -#: ../src/theme-parser.c:4247 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "<%s> तत्वभित्र कुनै पाठलाइ अनुमति छैन" +#~ msgid "Element <%s> is not allowed inside a distance/border/aspect_ratio element" +#~ msgstr "तत्व <%s> लाई distance/border/aspect_ratio तत्व भित्र अनुमति छैन" -#: ../src/theme-parser.c:4302 -msgid "<name> specified twice for this theme" -msgstr "<name> यस विषयका लागि दुई पटक निर्दिष्ट गरियो" +#~ msgid "Element <%s> is not allowed inside a draw operation element" +#~ msgstr "तत्व <%s> लाई रेखाङ्कन कार्य तत्व भित्र अनुमती छैन" -#: ../src/theme-parser.c:4313 -msgid "<author> specified twice for this theme" -msgstr "<author> यस विषयवस्तुका लागि दुई पटक निर्दिष्ट गरियो" +#~ msgid "Element <%s> is not allowed inside a <%s> element" +#~ msgstr "<%s>तत्व भित्र <%s>तत्वलाई अनुमति छैन" -#: ../src/theme-parser.c:4324 -msgid "<copyright> specified twice for this theme" -msgstr "<copyright> यस विषयवस्तुका लागि दुई पटक निर्दिष्ट गरियो" +#~ msgid "No draw_ops provided for frame piece" +#~ msgstr "फ्रेम टुक्राका लागि रेखाङ्कन विकल्प उपलब्ध छैन" -#: ../src/theme-parser.c:4335 -msgid "<date> specified twice for this theme" -msgstr "<date> यस विषयवस्तुका लागि दुई पटक निर्दिष्ट गरियो" +#~ msgid "No draw_ops provided for button" +#~ msgstr "बटनका लागि कुनै रेखाङ्कन विकल्प उपलब्ध छैन" -#: ../src/theme-parser.c:4346 -msgid "<description> specified twice for this theme" -msgstr "<description> यस विषयवस्तुका लागि दुई पटक निर्दिष्ट गरियो" +#~ msgid "No text is allowed inside element <%s>" +#~ msgstr "<%s> तत्वभित्र कुनै पाठलाइ अनुमति छैन" -#: ../src/theme-parser.c:4573 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "विषयवस्तु %s का लागि मान्य फाइल फेला पार्न असफल\n" +#~ msgid "<name> specified twice for this theme" +#~ msgstr "<name> यस विषयका लागि दुई पटक निर्दिष्ट गरियो" -#: ../src/theme-parser.c:4629 -#, c-format -msgid "Theme file %s did not contain a root <metacity_theme> element" -msgstr "विषयवस्तु फाइल %s ले मूल <metacity_theme> तत्व समावेश गरेन" +#~ msgid "<author> specified twice for this theme" +#~ msgstr "<author> यस विषयवस्तुका लागि दुई पटक निर्दिष्ट गरियो" -#: ../src/theme-viewer.c:74 -msgid "/_Windows" -msgstr "/सञ्झ्याल" +#~ msgid "<copyright> specified twice for this theme" +#~ msgstr "<copyright> यस विषयवस्तुका लागि दुई पटक निर्दिष्ट गरियो" -#: ../src/theme-viewer.c:75 -msgid "/Windows/tearoff" -msgstr "/सञ्झ्याल/टियरअफ" +#~ msgid "<date> specified twice for this theme" +#~ msgstr "<date> यस विषयवस्तुका लागि दुई पटक निर्दिष्ट गरियो" -#: ../src/theme-viewer.c:76 -msgid "/Windows/_Dialog" -msgstr "/सञ्झ्याल/संवाद" +#~ msgid "<description> specified twice for this theme" +#~ msgstr "<description> यस विषयवस्तुका लागि दुई पटक निर्दिष्ट गरियो" -#: ../src/theme-viewer.c:77 -msgid "/Windows/_Modal dialog" -msgstr "/सञ्झ्याल/मोडल संवाद" +#~ msgid "Failed to find a valid file for theme %s\n" +#~ msgstr "विषयवस्तु %s का लागि मान्य फाइल फेला पार्न असफल\n" -#: ../src/theme-viewer.c:78 -msgid "/Windows/_Utility" -msgstr "/सञ्झ्याल/उपयोगिता" +#~ msgid "Theme file %s did not contain a root <metacity_theme> element" +#~ msgstr "विषयवस्तु फाइल %s ले मूल <metacity_theme> तत्व समावेश गरेन" -#: ../src/theme-viewer.c:79 -msgid "/Windows/_Splashscreen" -msgstr "/सञ्झ्याल/स्प्लासस्क्रिन" +#~ msgid "/Windows/tearoff" +#~ msgstr "/सञ्झ्याल/टियरअफ" -#: ../src/theme-viewer.c:80 -msgid "/Windows/_Top dock" -msgstr "/सञ्झ्याल/माथिको डक" +#~ msgid "/Windows/_Dialog" +#~ msgstr "/सञ्झ्याल/संवाद" -#: ../src/theme-viewer.c:81 -msgid "/Windows/_Bottom dock" -msgstr "/सञ्झ्याल/तलको डक" +#~ msgid "/Windows/_Modal dialog" +#~ msgstr "/सञ्झ्याल/मोडल संवाद" -#: ../src/theme-viewer.c:82 -msgid "/Windows/_Left dock" -msgstr "/सञ्झ्याल/बायाँ डक" +#~ msgid "/Windows/_Utility" +#~ msgstr "/सञ्झ्याल/उपयोगिता" -#: ../src/theme-viewer.c:83 -msgid "/Windows/_Right dock" -msgstr "/सञ्झ्याल/दायाँ डक" +#~ msgid "/Windows/_Splashscreen" +#~ msgstr "/सञ्झ्याल/स्प्लासस्क्रिन" -#: ../src/theme-viewer.c:84 -msgid "/Windows/_All docks" -msgstr "/सञ्झ्याल/सबै डक" +#~ msgid "/Windows/_Top dock" +#~ msgstr "/सञ्झ्याल/माथिको डक" -#: ../src/theme-viewer.c:85 -msgid "/Windows/Des_ktop" -msgstr "/सञ्झ्याल/डेस्कटप" +#~ msgid "/Windows/_Bottom dock" +#~ msgstr "/सञ्झ्याल/तलको डक" -#: ../src/theme-viewer.c:134 -msgid "Open another one of these windows" -msgstr "यी सञ्झ्याल बाहेकको सञ्झ्याल खोल्नुहोस्" +#~ msgid "/Windows/_Left dock" +#~ msgstr "/सञ्झ्याल/बायाँ डक" -#: ../src/theme-viewer.c:141 -msgid "This is a demo button with an 'open' icon" -msgstr "यो 'खोल्नुहोस्' प्रतिमा भएको प्रदर्शन बटन हो" +#~ msgid "/Windows/_Right dock" +#~ msgstr "/सञ्झ्याल/दायाँ डक" -#: ../src/theme-viewer.c:148 -msgid "This is a demo button with a 'quit' icon" -msgstr "यो 'अन्त्य' प्रतिमा भएको प्रदर्शन बटन हो" +#~ msgid "/Windows/_All docks" +#~ msgstr "/सञ्झ्याल/सबै डक" -#: ../src/theme-viewer.c:241 -msgid "This is a sample message in a sample dialog" -msgstr "यो नमुना संवादको नमुना सन्देश हो" +#~ msgid "/Windows/Des_ktop" +#~ msgstr "/सञ्झ्याल/डेस्कटप" -#: ../src/theme-viewer.c:324 -#, c-format -msgid "Fake menu item %d\n" -msgstr "नक्कली मेनु सामाग्री %d\n" +#~ msgid "Open another one of these windows" +#~ msgstr "यी सञ्झ्याल बाहेकको सञ्झ्याल खोल्नुहोस्" -#: ../src/theme-viewer.c:358 -msgid "Border-only window" -msgstr "किनारा मात्रको सञ्झ्याल" +#~ msgid "This is a demo button with an 'open' icon" +#~ msgstr "यो 'खोल्नुहोस्' प्रतिमा भएको प्रदर्शन बटन हो" -#: ../src/theme-viewer.c:360 -msgid "Bar" -msgstr "पट्टी" +#~ msgid "This is a demo button with a 'quit' icon" +#~ msgstr "यो 'अन्त्य' प्रतिमा भएको प्रदर्शन बटन हो" -#: ../src/theme-viewer.c:377 -msgid "Normal Application Window" -msgstr "सामान्य अनुप्रयोग सञ्झ्याल" +#~ msgid "This is a sample message in a sample dialog" +#~ msgstr "यो नमुना संवादको नमुना सन्देश हो" -#: ../src/theme-viewer.c:381 -msgid "Dialog Box" -msgstr "संवाद बाकस" +#~ msgid "Fake menu item %d\n" +#~ msgstr "नक्कली मेनु सामाग्री %d\n" -#: ../src/theme-viewer.c:385 -msgid "Modal Dialog Box" -msgstr "नमूना संवाद बाकस" +#~ msgid "Border-only window" +#~ msgstr "किनारा मात्रको सञ्झ्याल" -#: ../src/theme-viewer.c:389 -msgid "Utility Palette" -msgstr "रङदानी उपयोगिता" +#~ msgid "Bar" +#~ msgstr "पट्टी" -#: ../src/theme-viewer.c:393 -msgid "Torn-off Menu" -msgstr "टर्न अफ मेनु" +#~ msgid "Normal Application Window" +#~ msgstr "सामान्य अनुप्रयोग सञ्झ्याल" -#: ../src/theme-viewer.c:397 -msgid "Border" -msgstr "किनारा" +#~ msgid "Dialog Box" +#~ msgstr "संवाद बाकस" -#: ../src/theme-viewer.c:725 -#, c-format -msgid "Button layout test %d" -msgstr "बटन सजावट परीक्षण %d" +#~ msgid "Modal Dialog Box" +#~ msgstr "नमूना संवाद बाकस" -#: ../src/theme-viewer.c:754 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "एउटा सञ्झ्याल फ्रेम कोर्न %g मिलिसेकेन्ड" +#~ msgid "Utility Palette" +#~ msgstr "रङदानी उपयोगिता" -#: ../src/theme-viewer.c:797 -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "प्रयोग: मेटासिटि विषयवस्तु दर्शक [THEMENAME]\n" +#~ msgid "Torn-off Menu" +#~ msgstr "टर्न अफ मेनु" -#: ../src/theme-viewer.c:804 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "विषयवस्तु लोड गर्दा त्रुटि: %s\n" +#~ msgid "Border" +#~ msgstr "किनारा" -#: ../src/theme-viewer.c:810 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "विषयवस्तु \"%s\" लाई %g सेकेन्डमा लोड गरियो\n" +#~ msgid "Button layout test %d" +#~ msgstr "बटन सजावट परीक्षण %d" -#: ../src/theme-viewer.c:833 -msgid "Normal Title Font" -msgstr "सामान्य शीर्षक फन्ट" +#~ msgid "%g milliseconds to draw one window frame" +#~ msgstr "एउटा सञ्झ्याल फ्रेम कोर्न %g मिलिसेकेन्ड" -#: ../src/theme-viewer.c:839 -msgid "Small Title Font" -msgstr "सानो शीर्षक फन्ट" +#~ msgid "Usage: metacity-theme-viewer [THEMENAME]\n" +#~ msgstr "प्रयोग: मेटासिटि विषयवस्तु दर्शक [THEMENAME]\n" -#: ../src/theme-viewer.c:845 -msgid "Large Title Font" -msgstr "ठूलो शीर्षक फन्ट" +#~ msgid "Error loading theme: %s\n" +#~ msgstr "विषयवस्तु लोड गर्दा त्रुटि: %s\n" -#: ../src/theme-viewer.c:850 -msgid "Button Layouts" -msgstr "बटन सजावट" +#~ msgid "Loaded theme \"%s\" in %g seconds\n" +#~ msgstr "विषयवस्तु \"%s\" लाई %g सेकेन्डमा लोड गरियो\n" -#: ../src/theme-viewer.c:855 -msgid "Benchmark" -msgstr "बेन्चमार्क" +#~ msgid "Normal Title Font" +#~ msgstr "सामान्य शीर्षक फन्ट" -#: ../src/theme-viewer.c:902 -msgid "Window Title Goes Here" -msgstr "सञ्झ्याल शीर्षक यहाँ देखिन्छ" +#~ msgid "Small Title Font" +#~ msgstr "सानो शीर्षक फन्ट" -#: ../src/theme-viewer.c:1006 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -" %d फ्रेमलाई %g क्लाइन्ट तिरको सेकेन्डमा (%g मिलिसेकेन्ड प्रति फ्रेम) र %g सेकेन्ड वाल घडी समय जहाँ " -"X सर्भर संसाधन सम्मिलित (%g मिलिसेकेन्ड प्रति फ्रेम) हुन्छ रेखाङ्कन गर्नुहोस्\n" +#~ msgid "Large Title Font" +#~ msgstr "ठूलो शीर्षक फन्ट" -#: ../src/theme-viewer.c:1219 -msgid "position expression test returned TRUE but set error" -msgstr "स्थिति अभिव्यक्ति परीक्षणले TRUE फिर्ता गर्यो तर त्रुटि सेट गर्यो" +#~ msgid "Button Layouts" +#~ msgstr "बटन सजावट" -#: ../src/theme-viewer.c:1221 -msgid "position expression test returned FALSE but didn't set error" -msgstr "स्थिति अभिव्यक्ति परीक्षणले FALSE फिर्ता गर्यो तर त्रुटि सेट गरेन" +#~ msgid "Benchmark" +#~ msgstr "बेन्चमार्क" -#: ../src/theme-viewer.c:1225 -msgid "Error was expected but none given" -msgstr "त्रुटि अपेक्षा गरिएको थियो तर केही दिएन" +#~ msgid "Window Title Goes Here" +#~ msgstr "सञ्झ्याल शीर्षक यहाँ देखिन्छ" -#: ../src/theme-viewer.c:1227 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "त्रुटि %d अपेक्षा गरिएको थियो तर %d प्राप्त भएको छ" +#~ msgid "" +#~ "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g seconds wall clock time including X " +#~ "server resources (%g milliseconds per frame)\n" +#~ msgstr "" +#~ " %d फ्रेमलाई %g क्लाइन्ट तिरको सेकेन्डमा (%g मिलिसेकेन्ड प्रति फ्रेम) र %g सेकेन्ड वाल घडी समय जहाँ X सर्भर संसाधन सम्मिलित (%g मिलिसेकेन्ड " +#~ "प्रति फ्रेम) हुन्छ रेखाङ्कन गर्नुहोस्\n" -#: ../src/theme-viewer.c:1233 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "त्रुटि अपेक्षा गरिएको थिएन तर एउटा फिर्ता भयो: %s" +#~ msgid "position expression test returned TRUE but set error" +#~ msgstr "स्थिति अभिव्यक्ति परीक्षणले TRUE फिर्ता गर्यो तर त्रुटि सेट गर्यो" -#: ../src/theme-viewer.c:1237 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "x मान %d थियो, %d अपेक्षा गरिएको थियो" +#~ msgid "position expression test returned FALSE but didn't set error" +#~ msgstr "स्थिति अभिव्यक्ति परीक्षणले FALSE फिर्ता गर्यो तर त्रुटि सेट गरेन" -#: ../src/theme-viewer.c:1240 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "y मान %d थियो, %d अपेक्षा गरिएको थियो" +#~ msgid "Error was expected but none given" +#~ msgstr "त्रुटि अपेक्षा गरिएको थियो तर केही दिएन" -#: ../src/theme-viewer.c:1303 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "%d संयोजन अभिव्यक्ति %g सेकेन्डमा पद वर्णन गरियो ( औसत %g सेकेन्ड)\n" +#~ msgid "Error %d was expected but %d given" +#~ msgstr "त्रुटि %d अपेक्षा गरिएको थियो तर %d प्राप्त भएको छ" -#: ../src/theme.c:206 -msgid "top" -msgstr "माथि" +#~ msgid "Error not expected but one was returned: %s" +#~ msgstr "त्रुटि अपेक्षा गरिएको थिएन तर एउटा फिर्ता भयो: %s" -#: ../src/theme.c:208 -msgid "bottom" -msgstr "तल" +#~ msgid "x value was %d, %d was expected" +#~ msgstr "x मान %d थियो, %d अपेक्षा गरिएको थियो" -#: ../src/theme.c:210 -msgid "left" -msgstr "बायाँ" +#~ msgid "y value was %d, %d was expected" +#~ msgstr "y मान %d थियो, %d अपेक्षा गरिएको थियो" -#: ../src/theme.c:212 -msgid "right" -msgstr "दायाँ" +#~ msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" +#~ msgstr "%d संयोजन अभिव्यक्ति %g सेकेन्डमा पद वर्णन गरियो ( औसत %g सेकेन्ड)\n" -#: ../src/theme.c:226 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "फ्रेम जमेट्रीले \"%s\" आयाम निर्दिष्ट गर्दैन" +#~ msgid "top" +#~ msgstr "माथि" -#: ../src/theme.c:245 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "फ्रेम जमेट्रीले किनारा \"%s\" का लागि आयाम \"%s\" निर्दिष्ट गर्दैन" +#~ msgid "bottom" +#~ msgstr "तल" -#: ../src/theme.c:282 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "बटन आकार अनुपात %g उचित छैन" +#~ msgid "left" +#~ msgstr "बायाँ" -#: ../src/theme.c:294 -msgid "Frame geometry does not specify size of buttons" -msgstr "फ्रेम जमेट्रीले बटनको साइज निर्दिष्ट गर्दैन" +#~ msgid "right" +#~ msgstr "दायाँ" -#: ../src/theme.c:925 -msgid "Gradients should have at least two colors" -msgstr "ग्रेडियन्टमा कम्तिमा पनि दुई रङ हुनुपर्दछ" +#~ msgid "frame geometry does not specify \"%s\" dimension" +#~ msgstr "फ्रेम जमेट्रीले \"%s\" आयाम निर्दिष्ट गर्दैन" -#: ../src/theme.c:1051 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"जीटीके (GTK) रङ विशिष्टिकरणमा कोष्ठक स्थिति हुनुपर्दछ, जस्तै; gtk:fg[NORMAL] " -"जहाँ NORMAL स्थिति हो; पद वर्णन गर्न सकेन \"%s\"" +#~ msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" +#~ msgstr "फ्रेम जमेट्रीले किनारा \"%s\" का लागि आयाम \"%s\" निर्दिष्ट गर्दैन" -#: ../src/theme.c:1065 -#, c-format -msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"जीटीके (GTK) रङ विशिष्टिकरणमा अवस्थिति पछाडी बन्द कोष्ठक हुनुपर्दछ, जस्तै gtk:" -"fg[NORMAL] जहाँ NORMAL स्थिति हो; पद वर्णन गर् सकेन \"%s\"" +#~ msgid "Button aspect ratio %g is not reasonable" +#~ msgstr "बटन आकार अनुपात %g उचित छैन" -#: ../src/theme.c:1076 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "रङ विशिष्टिकरणमा स्थिति \"%s\" पहिचान गरेन" +#~ msgid "Frame geometry does not specify size of buttons" +#~ msgstr "फ्रेम जमेट्रीले बटनको साइज निर्दिष्ट गर्दैन" -#: ../src/theme.c:1089 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "रङ विशिष्टिकरणमा रङ अवयव \"%s\" पहिचान गरने" +#~ msgid "Gradients should have at least two colors" +#~ msgstr "ग्रेडियन्टमा कम्तिमा पनि दुई रङ हुनुपर्दछ" -#: ../src/theme.c:1119 -#, c-format -msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" -msgstr "मिश्रण ढाँचा \"blend/bg_color/fg_color/alpha\" हो, \"%s\" ढाँचामा मिल्दैन" +#~ msgid "" +#~ "GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] where NORMAL is the state; could not " +#~ "parse \"%s\"" +#~ msgstr "जीटीके (GTK) रङ विशिष्टिकरणमा कोष्ठक स्थिति हुनुपर्दछ, जस्तै; gtk:fg[NORMAL] जहाँ NORMAL स्थिति हो; पद वर्णन गर्न सकेन \"%s\"" -#: ../src/theme.c:1130 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "मिश्रण गरिएको रङमा अल्फा मान \"%s\" पद वर्णन गर्न सकेन" +#~ msgid "" +#~ "GTK color specification must have a close bracket after the state, e.g. gtk:fg[NORMAL] where NORMAL is the state; " +#~ "could not parse \"%s\"" +#~ msgstr "" +#~ "जीटीके (GTK) रङ विशिष्टिकरणमा अवस्थिति पछाडी बन्द कोष्ठक हुनुपर्दछ, जस्तै gtk:fg[NORMAL] जहाँ NORMAL स्थिति हो; पद वर्णन गर् सकेन " +#~ "\"%s\"" -#: ../src/theme.c:1140 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "मिश्रण गरिएको रङमा अल्फा मान \"%s\" ०.० र १.० को बीचमा छैन" +#~ msgid "Did not understand state \"%s\" in color specification" +#~ msgstr "रङ विशिष्टिकरणमा स्थिति \"%s\" पहिचान गरेन" -#: ../src/theme.c:1187 -#, c-format -msgid "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "छाया ढाँचा \"shade/base_color/factor\" हो, \"%s\" ढाँचामा मिल्दैन" +#~ msgid "Did not understand color component \"%s\" in color specification" +#~ msgstr "रङ विशिष्टिकरणमा रङ अवयव \"%s\" पहिचान गरने" -#: ../src/theme.c:1198 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "छाया पारिएको रङमा छाया तत्व \"%s\" पद वर्णन गर्न सकेन" +#~ msgid "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the format" +#~ msgstr "मिश्रण ढाँचा \"blend/bg_color/fg_color/alpha\" हो, \"%s\" ढाँचामा मिल्दैन" -#: ../src/theme.c:1208 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "छाया पारिएको रङको छाया तत्व \"%s\" ऋणात्मक छ" +#~ msgid "Could not parse alpha value \"%s\" in blended color" +#~ msgstr "मिश्रण गरिएको रङमा अल्फा मान \"%s\" पद वर्णन गर्न सकेन" -#: ../src/theme.c:1237 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "रङ \"%s\" पद वर्णन गर्न सकेन" +#~ msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" +#~ msgstr "मिश्रण गरिएको रङमा अल्फा मान \"%s\" ०.० र १.० को बीचमा छैन" -#: ../src/theme.c:1496 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "संयोजन अभिव्यक्तिले अनुमति नभएको क्यारेक्टर '%s' समाविष्ट गर्दछ" +#~ msgid "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" +#~ msgstr "छाया ढाँचा \"shade/base_color/factor\" हो, \"%s\" ढाँचामा मिल्दैन" -#: ../src/theme.c:1523 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "संयोजन अभिव्यक्तिले पद वर्णन गर्न नसकिने उत्प्लावन बिन्दु नम्बर '%s' समाविष्ट गर्दछ" +#~ msgid "Could not parse shade factor \"%s\" in shaded color" +#~ msgstr "छाया पारिएको रङमा छाया तत्व \"%s\" पद वर्णन गर्न सकेन" -#: ../src/theme.c:1537 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "संयोजन अभिव्यक्तिले पद वर्णन गर्न नसकिने इन्टिजर '%s' समाविष्ट गर्दछ" +#~ msgid "Shade factor \"%s\" in shaded color is negative" +#~ msgstr "छाया पारिएको रङको छाया तत्व \"%s\" ऋणात्मक छ" -#: ../src/theme.c:1604 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "" -"संयोजन अभिव्यक्तिले यसो पाठकोसुुरूमा अज्ञातञ्चालक राखेको छ: " -"\"%s\"" +#~ msgid "Could not parse color \"%s\"" +#~ msgstr "रङ \"%s\" पद वर्णन गर्न सकेन" -#: ../src/theme.c:1661 -msgid "Coordinate expression was empty or not understood" -msgstr "संयोजन अभिव्यक्ति खाली वा नबुझिने थियो" +#~ msgid "Coordinate expression contains character '%s' which is not allowed" +#~ msgstr "संयोजन अभिव्यक्तिले अनुमति नभएको क्यारेक्टर '%s' समाविष्ट गर्दछ" -#: ../src/theme.c:1798 ../src/theme.c:1808 ../src/theme.c:1842 -msgid "Coordinate expression results in division by zero" -msgstr "संयोजन अभिव्यक्ति परिणाम शून्यद्वारा भाग जाने हुन्छ" +#~ msgid "Coordinate expression contains floating point number '%s' which could not be parsed" +#~ msgstr "संयोजन अभिव्यक्तिले पद वर्णन गर्न नसकिने उत्प्लावन बिन्दु नम्बर '%s' समाविष्ट गर्दछ" -#: ../src/theme.c:1850 -msgid "Coordinate expression tries to use mod operator on a floating-point number" -msgstr "संयोजन अभिव्यक्तिले उत्प्लाव बिन्दु नम्बरमा मोड सञ्चालनकर्ता प्रयोग गर्ने प्रयास गर्दछ" +#~ msgid "Coordinate expression contains integer '%s' which could not be parsed" +#~ msgstr "संयोजन अभिव्यक्तिले पद वर्णन गर्न नसकिने इन्टिजर '%s' समाविष्ट गर्दछ" -#: ../src/theme.c:1906 -#, c-format -msgid "Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "संयोजन अभिव्यक्तिमा अपेक्षित अपरेन्डको साटोमा सञ्चालनकर्ता \"%s\" छ" +#~ msgid "Coordinate expression contained unknown operator at the start of this text: \"%s\"" +#~ msgstr "संयोजन अभिव्यक्तिले यसो पाठकोसुुरूमा अज्ञातञ्चालक राखेको छ: \"%s\"" -#: ../src/theme.c:1915 -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "संयोजन अभिव्यक्तिमा अपेक्षित सञ्चालनकर्ताको साटोमा अपरेन्ड थियो" +#~ msgid "Coordinate expression was empty or not understood" +#~ msgstr "संयोजन अभिव्यक्ति खाली वा नबुझिने थियो" -#: ../src/theme.c:1923 -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "संयोजन अभिव्यक्ति ओपरन्डको साटोमा सञ्चालनकर्तासँग समाप्त भयो" +#~ msgid "Coordinate expression results in division by zero" +#~ msgstr "संयोजन अभिव्यक्ति परिणाम शून्यद्वारा भाग जाने हुन्छ" -#: ../src/theme.c:1933 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "संयोजन अभिव्यक्तिसँग सञ्चालनकर्ता \"%c\" पछ्याउने सञ्चालनकर्ता \"%c\" छ जसको बीचमा अपरेन्ड छैन" +#~ msgid "Coordinate expression tries to use mod operator on a floating-point number" +#~ msgstr "संयोजन अभिव्यक्तिले उत्प्लाव बिन्दु नम्बरमा मोड सञ्चालनकर्ता प्रयोग गर्ने प्रयास गर्दछ" -#: ../src/theme.c:2051 -msgid "Coordinate expression parser overflowed its buffer." -msgstr "संयोजन अभिव्यक्ति पद वर्णकले यसको बफरलाई अतिप्रवाह गर्यो ।" +#~ msgid "Coordinate expression has an operator \"%s\" where an operand was expected" +#~ msgstr "संयोजन अभिव्यक्तिमा अपेक्षित अपरेन्डको साटोमा सञ्चालनकर्ता \"%s\" छ" -#: ../src/theme.c:2080 -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "संयोजन अभिव्यक्तिमा खुला कोष्ठक नभएको खुला कोष्ठक थियो" +#~ msgid "Coordinate expression had an operand where an operator was expected" +#~ msgstr "संयोजन अभिव्यक्तिमा अपेक्षित सञ्चालनकर्ताको साटोमा अपरेन्ड थियो" -#: ../src/theme.c:2142 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "संयोजन अभिव्यक्तिमा अज्ञात चल वा अचल \"%s\" थियो ।" +#~ msgid "Coordinate expression ended with an operator instead of an operand" +#~ msgstr "संयोजन अभिव्यक्ति ओपरन्डको साटोमा सञ्चालनकर्तासँग समाप्त भयो" -#: ../src/theme.c:2197 -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "संयोजन अभिव्यक्तिमा बन्द गर्ने कोष्ठक नभएको खुला कोष्ठक थियो" +#~ msgid "Coordinate expression has operator \"%c\" following operator \"%c\" with no operand in between" +#~ msgstr "संयोजन अभिव्यक्तिसँग सञ्चालनकर्ता \"%c\" पछ्याउने सञ्चालनकर्ता \"%c\" छ जसको बीचमा अपरेन्ड छैन" -#: ../src/theme.c:2208 -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "संयोजन अभिव्यक्तिमा कुनै सञ्चालक वा अपरेन्ड नभएको देखिन्छ" +#~ msgid "Coordinate expression parser overflowed its buffer." +#~ msgstr "संयोजन अभिव्यक्ति पद वर्णकले यसको बफरलाई अतिप्रवाह गर्यो ।" -#: ../src/theme.c:2449 ../src/theme.c:2471 ../src/theme.c:2492 -#, c-format -msgid "Theme contained an expression \"%s\" that resulted in an error: %s\n" -msgstr "विषयवस्तुले अभिव्यक्ति \"%s\" समाविष्ट गर्यो जसको कारणले एउटा त्रुटि भयो: %s\n" +#~ msgid "Coordinate expression had a close parenthesis with no open parenthesis" +#~ msgstr "संयोजन अभिव्यक्तिमा खुला कोष्ठक नभएको खुला कोष्ठक थियो" -#: ../src/theme.c:3946 -#, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> यो फ्रेम शैलीका लागि निर्दिष्ट गरिएको हुनुपर्दछ" +#~ msgid "Coordinate expression had unknown variable or constant \"%s\"" +#~ msgstr "संयोजन अभिव्यक्तिमा अज्ञात चल वा अचल \"%s\" थियो ।" -#: ../src/theme.c:4422 ../src/theme.c:4447 -#, c-format -msgid "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "हराइराखेको <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" +#~ msgid "Coordinate expression had an open parenthesis with no close parenthesis" +#~ msgstr "संयोजन अभिव्यक्तिमा बन्द गर्ने कोष्ठक नभएको खुला कोष्ठक थियो" -#: ../src/theme.c:4493 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "\"%s\": %s विषयवस्तु लोड गर्न असफल\n" +#~ msgid "Coordinate expression doesn't seem to have any operators or operands" +#~ msgstr "संयोजन अभिव्यक्तिमा कुनै सञ्चालक वा अपरेन्ड नभएको देखिन्छ" -#: ../src/theme.c:4603 ../src/theme.c:4610 ../src/theme.c:4617 -#: ../src/theme.c:4624 ../src/theme.c:4631 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "\"%s\" विषयको लागी <%s> सेट भएन" +#~ msgid "Theme contained an expression \"%s\" that resulted in an error: %s\n" +#~ msgstr "विषयवस्तुले अभिव्यक्ति \"%s\" समाविष्ट गर्यो जसको कारणले एउटा त्रुटि भयो: %s\n" -#: ../src/theme.c:4639 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" -"विन्डो प्रकार \"%s\" को लागी विषय \"%s\" मा खाका शैली सेट भएको छैन, <windowtype=" -"\"%s\"style_set=\"whatever\"/> तत्व थप्नुहोस्" +#~ msgid "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be specified for this frame style" +#~ msgstr "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> यो फ्रेम शैलीका लागि निर्दिष्ट गरिएको हुनुपर्दछ" -#: ../src/theme.c:5006 ../src/theme.c:5068 ../src/theme.c:5131 -#, c-format -msgid "User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "प्रयोगकर्ताको वर्णन ठूलो अक्षरबाट सुरू हुनुपर्छ, \"%s\" होइन" +#~ msgid "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" +#~ msgstr "हराइराखेको <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -#: ../src/theme.c:5014 ../src/theme.c:5076 ../src/theme.c:5139 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "अचर \"%s\" पहिले नै परिभाषित गरिएको छ" +#~ msgid "Failed to load theme \"%s\": %s\n" +#~ msgstr "\"%s\": %s विषयवस्तु लोड गर्न असफल\n" -#: ../src/util.c:98 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "त्रुटिमोचक कार्य खोल्न असफल: %s\n" +#~ msgid "No <%s> set for theme \"%s\"" +#~ msgstr "\"%s\" विषयको लागी <%s> सेट भएन" -#: ../src/util.c:108 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "कार्य फाइल %s: %s fdopen() गर्न असफल\n" +#~ msgid "" +#~ "No frame style set for window type \"%s\" in theme \"%s\", add a <window type=\"%s\" style_set=\"whatever\"/> element" +#~ msgstr "" +#~ "विन्डो प्रकार \"%s\" को लागी विषय \"%s\" मा खाका शैली सेट भएको छैन, <windowtype=\"%s\"style_set=\"whatever\"/> तत्व थप्नुहोस्" -#: ../src/util.c:114 -#, c-format -msgid "Opened log file %s\n" -msgstr "कार्य फाइल %s खोलियो\n" +#~ msgid "User-defined constants must begin with a capital letter; \"%s\" does not" +#~ msgstr "प्रयोगकर्ताको वर्णन ठूलो अक्षरबाट सुरू हुनुपर्छ, \"%s\" होइन" -#: ../src/util.c:231 -msgid "Window manager: " -msgstr "सञ्झ्याल प्रबन्धक: " +#~ msgid "Constant \"%s\" has already been defined" +#~ msgstr "अचर \"%s\" पहिले नै परिभाषित गरिएको छ" -#: ../src/util.c:379 -msgid "Bug in window manager: " -msgstr "सञ्झ्याल प्रबन्धकमा त्रुटि: " +#~ msgid "Failed to open debug log: %s\n" +#~ msgstr "त्रुटिमोचक कार्य खोल्न असफल: %s\n" -#: ../src/util.c:408 -msgid "Window manager warning: " -msgstr "सञ्झ्याल प्रबन्धक चेतावनी: " +#~ msgid "Failed to fdopen() log file %s: %s\n" +#~ msgstr "कार्य फाइल %s: %s fdopen() गर्न असफल\n" -#: ../src/util.c:432 -msgid "Window manager error: " -msgstr "सञ्झ्याल प्रबन्धक त्रुटि: " +#~ msgid "Opened log file %s\n" +#~ msgstr "कार्य फाइल %s खोलियो\n" -#: ../src/window-props.c:192 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "एउटा bogus _NET_WM_PID %lu अनुप्रयोग सेट\n" +#~ msgid "Window manager: " +#~ msgstr "सञ्झ्याल प्रबन्धक: " -#: ../src/window-props.c:324 -#, c-format -msgid "%s (on %s)" -msgstr "%s (मा %s)" +#~ msgid "Bug in window manager: " +#~ msgstr "सञ्झ्याल प्रबन्धकमा त्रुटि: " -#: ../src/window-props.c:1406 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "अमान्य WM_TRANSIENT_FOR सञ्झ्याल 0x%lx जसलाई %s का लागि निर्दिष्ट गरिएको छ ।\n" +#~ msgid "Window manager warning: " +#~ msgstr "सञ्झ्याल प्रबन्धक चेतावनी: " -#. first time through -#: ../src/window.c:5551 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"सञ्झ्याल %s ले ICCCM मा निर्दिष्ट गरे अनुरूपको " -"सञ्झ्याल WM_CLIENT_LEADER " -"को साटोमा आफ्नैमा SM_CLIENT_ID सेट गर्दछ ।\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/window.c:6116 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %" -"d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"सञ्झ्याल %s ले MWM सङ्केतलाई साइज परिवर्तन गर्न नमिल्ने देखाएर सेट गर्दछ, तर न्यूनतम साइज %" -"d x %d र अधिकतम साइज %d x %d सेट गर्दछ; यसले धेरै अर्थ दिदैन ।\n" +#~ msgid "Window manager error: " +#~ msgstr "सञ्झ्याल प्रबन्धक त्रुटि: " -#: ../src/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"सञ्झ्याल 0x%lx मा %s गुण छ\n" -"त्यसमा प्रकार %s ढाँचा %d हुने अपेक्षा गरिएको थियो\n" -"र वास्तवमा प्रकार %s ढाँचा %d n_items %d छ ।\n" -"यो धेरैजसो सञ्झ्याल प्रबन्धक बगका कारणले नभई अनुप्रयोग बगका कारणले हुनसक्छ ।\n" -"सञ्झ्यालमा title=\"%s\" class=\"%s\" name=\"%s\" छ\n" +#~ msgid "Application set a bogus _NET_WM_PID %lu\n" +#~ msgstr "एउटा bogus _NET_WM_PID %lu अनुप्रयोग सेट\n" -#: ../src/xprops.c:401 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "गुण %s जुन सञ्झ्याल 0x%lx छ र अमान्य UTF-8 समावेश छ\n" +#~ msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +#~ msgstr "अमान्य WM_TRANSIENT_FOR सञ्झ्याल 0x%lx जसलाई %s का लागि निर्दिष्ट गरिएको छ ।\n" -#: ../src/xprops.c:484 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "गुण %s जुन सञ्झ्याल 0x%lx मा छ, सूचीमा वस्तु %d का लागि अमान्य UTF-8 समावेश गरेको छ\n" +#~ msgid "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER window as specified in the ICCCM.\n" +#~ msgstr "सञ्झ्याल %s ले ICCCM मा निर्दिष्ट गरे अनुरूपको सञ्झ्याल WM_CLIENT_LEADER को साटोमा आफ्नैमा SM_CLIENT_ID सेट गर्दछ ।\n" + +#~ msgid "" +#~ "Window %s sets an MWM hint indicating it isn't resizable, but sets min size %d x %d and max size %d x %d; this " +#~ "doesn't make much sense.\n" +#~ msgstr "" +#~ "सञ्झ्याल %s ले MWM सङ्केतलाई साइज परिवर्तन गर्न नमिल्ने देखाएर सेट गर्दछ, तर न्यूनतम साइज %d x %d र अधिकतम साइज %d x %d सेट गर्दछ; " +#~ "यसले धेरै अर्थ दिदैन ।\n" + +#~ msgid "" +#~ "Window 0x%lx has property %s\n" +#~ "that was expected to have type %s format %d\n" +#~ "and actually has type %s format %d n_items %d.\n" +#~ "This is most likely an application bug, not a window manager bug.\n" +#~ "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +#~ msgstr "" +#~ "सञ्झ्याल 0x%lx मा %s गुण छ\n" +#~ "त्यसमा प्रकार %s ढाँचा %d हुने अपेक्षा गरिएको थियो\n" +#~ "र वास्तवमा प्रकार %s ढाँचा %d n_items %d छ ।\n" +#~ "यो धेरैजसो सञ्झ्याल प्रबन्धक बगका कारणले नभई अनुप्रयोग बगका कारणले हुनसक्छ ।\n" +#~ "सञ्झ्यालमा title=\"%s\" class=\"%s\" name=\"%s\" छ\n" + +#~ msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +#~ msgstr "गुण %s जुन सञ्झ्याल 0x%lx छ र अमान्य UTF-8 समावेश छ\n" +#~ msgid "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" +#~ msgstr "गुण %s जुन सञ्झ्याल 0x%lx मा छ, सूचीमा वस्तु %d का लागि अमान्य UTF-8 समावेश गरेको छ\n" diff --git a/po/nl.po b/po/nl.po index dfc03a106..d3e6f64f3 100644 --- a/po/nl.po +++ b/po/nl.po @@ -1,421 +1,276 @@ -# Dutch translation for muffin -# -# This file is distributed under the same license as the muffin package. -# +# Dutch translation for mutter +# This file is distributed under the same license as the mutter package. # Tino Meinen <a.t.meinen@chello.nl>, 2003–2004, 2006, 2008. -# Reinout van Schouwen <reinouts@gnome.org>, 2003–2007. +# Reinout van Schouwen <reinouts@gnome.org>, 2003–2007, 2013, 2016 (nalezen). # Michiel Sikkes <michiels@gnome.org>, 2005. # Wouter Bolsterlee <wbolster@gnome.org>, 2006–2012. -# +# Hannie Dumoleyn <hannie@ubuntu-nl.org>, 2016. +# Nathan Follens <nthn@unseen.is>, 2017, 2019-2020. msgid "" msgstr "" -"Project-Id-Version: muffin\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-03-16 23:20+0100\n" -"PO-Revision-Date: 2011-03-29 23:29+0200\n" -"Last-Translator: Wouter Bolsterlee <wbolster@gnome.org>\n" +"Project-Id-Version: mutter\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2020-02-23 17:41+0000\n" +"PO-Revision-Date: 2020-02-24 19:06+0100\n" +"Last-Translator: Nathan Follens <nthn@unseen.is>\n" "Language-Team: Dutch <vertaling@vrijschrift.org>\n" "Language: nl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Project-Style: gnome\n" +"X-Generator: Poedit 2.3\n" -#: ../src/50-muffin-windows.xml.in.h:1 -msgid "Windows" -msgstr "Vensters" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Navigatie" -#: ../src/50-muffin-windows.xml.in.h:2 -msgid "View split on left" -msgstr "" +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Venster verplaatsen naar werkblad 1" -#: ../src/50-muffin-windows.xml.in.h:3 -msgid "View split on right" -msgstr "" +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Venster verplaatsen naar werkblad 2" -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format -msgid "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." -msgstr "" -"Er is al een andere ‘compositing manager’ actief op scherm %i van display " -"‘%s’." +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Venster verplaatsen naar werkblad 3" -#: ../src/core/bell.c:307 -msgid "Bell event" -msgstr "Bel-evenement" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Venster verplaatsen naar werkblad 4" -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Onbekende aanvraag voor vensterinformatie: %d" +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Venster verplaatsen naar laatste werkblad" -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> reageert niet." +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "Venster één werkblad naar boven verplaatsen" -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "De toepassing reageert niet." +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "Venster één werkblad naar beneden verplaatsen" -#: ../src/core/delete.c:119 -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "" -"U kunt ervoor kiezen even te wachten totdat het doorgaat of de toepassing " -"dwingen om helemaal af te sluiten." +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "Venster één monitor naar links verplaatsen" -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "_Wachten" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "Venster één monitor naar rechts verplaatsen" -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "Ge_forceerd afsluiten" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "Venster één monitor naar boven verplaatsen" -#: ../src/core/display.c:387 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "Benodigde extensie ‘%s’ voor ‘compositing’ ontbreekt" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "Venster één monitor naar beneden verplaatsen" -#: ../src/core/display.c:453 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Openen van X Window System display ‘%s’ mislukt\n" +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "Tussen toepassingen schakelen" -# Gebruik controletoets als vertaling van modifier (Ctrl/Shift/Alt/Esc) -#: ../src/core/keybindings.c:852 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "" -"Een ander programma gebruikt reeds de %s-toets met controletoets %x als " -"sneltoets\n" +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "Schakelen naar vorige toepassing" -#: ../src/core/main.c:206 -msgid "Disable connection to session manager" -msgstr "Schakel de verbinding met het sessiebeheer uit" +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "Tussen vensters schakelen" -#: ../src/core/main.c:212 -msgid "Replace the running window manager" -msgstr "De huidige toepassing voor vensterbeheer vervangen" +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "Schakelen naar vorig venster" -#: ../src/core/main.c:218 -msgid "Specify session management ID" -msgstr "Specificeer de ID van het sessiebeheer" +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "Wisselen van venster binnen een toepassing" -#: ../src/core/main.c:223 -msgid "X Display to use" -msgstr "De te gebruiken X-weergave" +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "Wisselen naar vorig gebruikte venster van een toepassing" -#: ../src/core/main.c:229 -msgid "Initialize session from savefile" -msgstr "Initialiseer de sessie middels een opslagbestand" +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "Systeemschermen wisselen" -#: ../src/core/main.c:235 -msgid "Make X calls synchronous" -msgstr "X-aanroepen synchroon maken" +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "Schakelen naar vorige systeemregelaar" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Kon themamap niet scannen: %s\n" +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "Direct tussen vensters schakelen" -#: ../src/core/main.c:520 -#, c-format -msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "" -"Kon geen thema vinden! Zorg ervoor dat %s bestaat en de gebruikelijke " -"thema's bevat.\n" +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "Schakel direct naar vorig venster" -#: ../src/core/muffin.c:40 -#, c-format -msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" -"muffin %s\n" -"Copyright © 2001–%d Havoc Pennington, Red Hat, Inc., en anderen\n" -"Dit is vrije software; zie de broncode voor de kopieervoorwaarden.\n" -"Er is GEEN garantie; zelfs niet voor VERKOOPBAARHEID of GESCHIKTHEID VOOR " -"EEN BEPAALD DOEL.\n" - -#: ../src/core/muffin.c:54 -msgid "Print version" -msgstr "Versie-informatie tonen" - -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "Komma-gescheiden lijst van compositor-plugins" - -#: ../src/core/prefs.c:1077 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"Werkoplossing voor gebroken toepassingen uitgezet. Bepaalde toepassingen " -"zullen niet naar behoren functioneren.\n" - -#: ../src/core/prefs.c:1152 -#, c-format -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "Kon lettertypebeschrijving ‘%s’ niet lezen uit GSettings-sleutel %s\n" +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "Direct wisselen van venster binnen een toepassing" -#: ../src/core/prefs.c:1218 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"‘%s’, gevonden in de configuratiedatabase, is geen geldige waarde voor de " -"muisknop-optietoets\n" +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "Direct wisselen naar vorig venster van een toepassing" -#: ../src/core/prefs.c:1739 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "" -"‘%s’ in de configuratiedatabase is geen geldige waarde voor sneltoets ‘%s’\n" +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "Direct tussen systeemschermen wisselen" -#: ../src/core/prefs.c:1836 -#, c-format -msgid "Workspace %d" -msgstr "Werkblad %d" +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "Direct schakelen naar vorige systeemregelaar" -#: ../src/core/screen.c:730 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "Scherm %d op display '%s' is ongeldig\n" +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "Alle normale vensters verbergen" -#: ../src/core/screen.c:746 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"Scherm %d op display ‘%s’ heeft al een ‘window manager’; probeer de optie: --" -"replace te gebruiken om de huidige ‘window manager’ te vervangen.\n" +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "Schakelen naar werkblad 1" -#: ../src/core/screen.c:773 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "" -"Kon ‘window manager’-selectie niet verkrijgen op scherm %d display ‘%s’\n" +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "Schakelen naar werkblad 2" -#: ../src/core/screen.c:828 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "Scherm %d op display ‘%s’ heeft al een ‘window manager’\n" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "Schakelen naar werkblad 3" -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "Kon scherm %d op display ‘%s’ niet vrijmaken\n" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "Schakelen naar werkblad 4" -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Kon map '%s' niet aanmaken: %s\n" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "Overschakelen naar laatste werkblad" -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "Kon sessiebestand '%s' niet openen voor schrijven: %s\n" +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "Verplaatsen naar werkblad hierboven" -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Fout bij schrijven sessiebestand '%s': %s\n" +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "Verplaatsen naar werkblad hieronder" -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Fout bij sluiten sessiebestand '%s': %s\n" +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "Systeem" -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Verwerken van opgeslagen sessiebestand mislukt: %s\n" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Het opdrachtregelvenster tonen" -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "<muffin_session>-attribuut opgemerkt maar sessie-ID was al bekend" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Het activiteitenoverzicht tonen" -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Onbekend attribuut ‘%s’ op <%s>-element" +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Sneltoetsen opnieuw instellen" -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "ingebedde <window>-markering" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Vensters" -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "Onbekend element %s" +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "Venstermenu activeren" -#: ../src/core/session.c:1809 -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" -"Deze vensters ondersteunen het opslaan van de huidige instellingen niet en " -"zullen bij een volgende sessie opnieuw moeten worden opgestart." +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Volledig-schermmodus omschakelen" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Debug-logboek openen mislukt: %s\n" +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "Maximalisatie in- of uitschakelen" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Logboek %s openen via fdopen() mislukt: %s\n" +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "Venster maximaliseren" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "Logboek %s geopend\n" +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Venster herstellen" -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "Muffin is gecompileerd zonder ondersteuning voor verbose-mode\n" +#: data/50-mutter-windows.xml:18 +msgid "Close window" +msgstr "Venster sluiten" -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "Vensterbeheer:" +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "Venster verbergen" -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "Fout in vensterbeheer:" +#: data/50-mutter-windows.xml:22 +msgid "Move window" +msgstr "Venster verplaatsen" -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "Waarschuwing van vensterbeheer:" +#: data/50-mutter-windows.xml:24 +msgid "Resize window" +msgstr "Vensterafmetingen veranderen" -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "Fout van vensterbeheer:" +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "Schakelen tussen venster op alle werkbladen zichtbaar of op één" -#. first time through -#: ../src/core/window.c:7274 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"Venster %s stelt zelf SM_CLIENT_ID in, in plaats van bij het " -"WM_CLIENT_LEADER-venster zoals gespecificeerd wordt in de ICCCM.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7937 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size " -"%d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"Venster %s geeft een MWM-hint dat de grootte niet kan worden aangepast, maar " -"stelt wel minimale grootte %d×%d en maximale grootte %d×%d in; dit is niet " -"logisch.\n" +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "Vensters naar voren halen indien bedekt of anders naar achter brengen" -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "Toepassing heeft een overbodige _NET_WM_PID %lu ingesteld\n" +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "Venster voor andere vensters halen" -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (op %s)" +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "Venster achter andere vensters brengen" -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "Ongeldig WM_TRANSIENT_FOR venster 0x%lx opgegeven voor %s.\n" +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "Venster verticaal maximaliseren" -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "WM_TRANSIENT_FOR venster 0x%lx voor %s zou een ‘loop’ creëren.\n" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "Venster horizontaal maximaliseren" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"Venster 0x%lx heeft eigenschap %s\n" -"welke zou moeten hebben: type %s en formaat %d\n" -"maar in feite heeft: type %s formaat %d n_items %d.\n" -"Dit is waarschijnlijk een fout van de toepassing, niet van de ‘window " -"manager’.\n" -"Het venster heeft title=‘%s’ class=‘%s’ naam=‘%s’\n" - -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "Eigenschap %s bij venster 0x%lx bevat ongeldige UTF-8\n" +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "Weergave gesplitst op links" -#: ../src/core/xprops.c:494 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"Eigenschap %s bij venster 0x%lx bevat ongeldige UTF-8 voor item %d van de " -"lijst\n" +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "Weergave gesplitst op rechts" -#: ../src/muffin.desktop.in.h:1 ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 +#: data/org.gnome.mutter.gschema.xml.in:7 msgid "Modifier to use for extended window management operations" msgstr "Controletoets voor uitgebreide vensterbeheerfunctionaliteit" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 +#: data/org.gnome.mutter.gschema.xml.in:8 msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." msgstr "" "Deze sleutel activeert de ‘overlay’, een combinatie van een vensteroverzicht " -"en een systeem om toepassingen te starten. Standaard is dit de ‘Windows’-" -"toets en de bedoeling is dat deze sneltoets ofwel de standaardwaarde bevat " +"en een systeem om toepassingen te starten. Standaard is dit de ‘Windows-" +"toets’ en de bedoeling is dat deze sneltoets ofwel de standaardwaarde bevat " "ofwel leeggemaakt is." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 +#: data/org.gnome.mutter.gschema.xml.in:20 msgid "Attach modal dialogs" msgstr "Blokkerende dialoogvensters vastmaken" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 +#: data/org.gnome.mutter.gschema.xml.in:21 msgid "" "When true, instead of having independent titlebars, modal dialogs appear " "attached to the titlebar of the parent window and are moved together with " @@ -425,45 +280,40 @@ msgstr "" "maar vastgekoppeld aan het achterliggende venster en bewegen daardoor ook " "mee met het achterliggende venster." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -msgid "Live Hidden Windows" -msgstr "Verborgen vensters ‘live’ houden" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"Geeft aan of verborgen vensters (bijvoorbeeld geminimaliseerd of op een " -"ander werkblad) in ‘live’ gehouden moeten worden." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 +#: data/org.gnome.mutter.gschema.xml.in:30 msgid "Enable edge tiling when dropping windows on screen edges" -msgstr "" +msgstr "Randtegels inschakelen bij het slepen van vensters naar schermranden" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 +#: data/org.gnome.mutter.gschema.xml.in:31 msgid "" "If enabled, dropping windows on vertical screen edges maximizes them " "vertically and resizes them horizontally to cover half of the available " "area. Dropping windows on the top screen edge maximizes them completely." msgstr "" +"Indien ingeschakeld, zal het laten vallen van vensters op verticale " +"schermranden ze verticaal maximaliseren en horizontaal op halve " +"schermgrootte brengen. Het laten vallen van vensters op de bovenrand van het " +"scherm maximaliseert ze helemaal." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 +#: data/org.gnome.mutter.gschema.xml.in:40 msgid "Workspaces are managed dynamically" -msgstr "" +msgstr "Werkbladen worden dynamisch beheerd" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 +#: data/org.gnome.mutter.gschema.xml.in:41 msgid "" -"Determines whether workspaces are managed dynamically or whether there's a " +"Determines whether workspaces are managed dynamically or whether there’s a " "static number of workspaces (determined by the num-workspaces key in org." "gnome.desktop.wm.preferences)." msgstr "" +"Bepaalt of werkbladen dynamisch worden beheerd of dat er een statisch aantal " +"werkbladen is (gegeven door de sleutel num-workspaces in org.gnome.desktop." +"wm.preferences)." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 +#: data/org.gnome.mutter.gschema.xml.in:50 msgid "Workspaces only on primary" msgstr "Werkbladen alleen voor primaire venster" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 +#: data/org.gnome.mutter.gschema.xml.in:51 msgid "" "Determines whether workspace switching should happen for windows on all " "monitors or only for windows on the primary monitor." @@ -471,1159 +321,1362 @@ msgstr "" "Geeft aan of wisselen van werkblad voor vensters op alle schermen of alleen " "voor vensters op het hoofdscherm moet gebeuren." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 +#: data/org.gnome.mutter.gschema.xml.in:59 msgid "No tab popup" -msgstr "" +msgstr "Geen tab-pop-up" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 +#: data/org.gnome.mutter.gschema.xml.in:60 msgid "" "Determines whether the use of popup and highlight frame should be disabled " "for window cycling." msgstr "" +"Bepaalt of het gebruik van pop-up en markering van het kader uitgeschakeld " +"wordt voor het vensterbladeren." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 -msgid "Draggable border width" +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Aandacht vertragen totdat de muispijl stopt met bewegen" + +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." msgstr "" +"Indien op ‘true’ ingesteld en de aandachtsmodus is ofwel ‘sloppy’ of " +"‘mouse’, dan zal de aandacht niet direct veranderd worden bij het binnengaan " +"van een venster, maar slechts wanneer de muispijl stopt met bewegen." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 +#: data/org.gnome.mutter.gschema.xml.in:79 +msgid "Draggable border width" +msgstr "Sleepbare randbreedte" + +#: data/org.gnome.mutter.gschema.xml.in:80 msgid "" -"The amount of total draggable borders. If the theme's visible borders are " +"The amount of total draggable borders. If the theme’s visible borders are " "not enough, invisible borders will be added to meet this value." msgstr "" +"Het totaal aantal sleepbare randen. Als de zichtbare randen in het thema " +"onvoldoende zijn, worden onzichtbare randen toegevoegd om deze waarde te " +"bereiken." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:17 -#, fuzzy +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "Vensters van bijna-monitorformaat auto-maximaliseren" + +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" +"Indien ingeschakeld, worden vensters die initieel ongeveer even groot zijn " +"als de monitor automatisch gemaximaliseerd." + +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Plaats nieuwe vensters in het midden" + +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" +"Indien waar zullen nieuwe vensters steeds in het midden van het actieve " +"scherm van de monitor geplaatst worden." + +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Experimentele functies inschakelen" + +#: data/org.gnome.mutter.gschema.xml.in:108 +msgid "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes " +"mutter request a low priority real-time scheduling. The executable or user " +"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — " +"initializes Xwayland lazily if there are X11 clients. Requires restart." +msgstr "" +"Voeg het sleutelwoord van een experimentele functie toe aan de lijst om deze " +"in te schakelen. Of de compositor herstart moet worden vooraleer de functie " +"gebruikt kan worden is afhankelijk van de functie. Experimentele functies " +"die u aan deze lijst toevoegt kunnen op een later moment weer verwijderd of " +"op een andere manier ingesteld worden, waardoor het mogelijk is dat ze dan " +"niet meer werken. Momenteel bruikbare sleutelwoorden: • ‘scale-monitor-" +"framebuffer’ — zorgt dat mutter standaard logische beeldschermen indeelt in " +"een logische pixelcoördinaatruimte, en beeldschermframebuffers schaalt in " +"plaats van vensterinhoud, om HiDPI-beeldschermen te beheren. Hiervoor is " +"opnieuw opstarten niet vereist. • “rt-scheduler” — zorgt ervoor dat mutter " +"real-time plannen met lage prioriteit aanvraagt. Het uitvoerbaar bestand of " +"de gebruiker moet CAP_SYS_NICE hebben. Hiervoor is opnieuw opstarten " +"vereist. • “autostart-xwayland” — initialiseert Xwayland op een luie manier " +"als er X11-cliënten zijn. Hiervoor is opnieuw opstarten vereist." + +#: data/org.gnome.mutter.gschema.xml.in:134 +msgid "Modifier to use to locate the pointer" +msgstr "Controletoets om de muispijl te lokaliseren" + +#: data/org.gnome.mutter.gschema.xml.in:135 +msgid "This key will initiate the “locate pointer” action." +msgstr "Deze sleutel activeert de actie ‘muispijl lokaliseren’." + +#: data/org.gnome.mutter.gschema.xml.in:142 +msgid "Timeout for check-alive ping" +msgstr "Time-out voor levenscontroleping" + +#: data/org.gnome.mutter.gschema.xml.in:143 +msgid "" +"Number of milliseconds a client has to respond to a ping request in order to " +"not be detected as frozen. Using 0 will disable the alive check completely." +msgstr "" +"Aantal milliseconden dat een cliënt heeft om te antwoorden om een ping-" +"verzoek om niet als bevroren beschouwd te worden. Stel dit in op 0 om de " +"levenscontrole volledig uit te schakelen." + +#: data/org.gnome.mutter.gschema.xml.in:165 msgid "Select window from tab popup" -msgstr "Venster van boven weghalen" +msgstr "Venster selecteren uit tab-pop-up" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:18 +#: data/org.gnome.mutter.gschema.xml.in:170 msgid "Cancel tab popup" -msgstr "" +msgstr "Tab-pop-up annuleren" -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "Gebruik: %s\n" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "_Minimaliseren" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "Ma_ximaliseren" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "_Herstellen" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "_Oprollen" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "_Uitrollen" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "_Verplaatsen" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "Afmetingen _wijzigen" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "_Titelbalk op scherm plaatsen" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "Altijd _bovenop" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "Op _alle werkbladen zichtbaar" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "Alleen op _dit werkblad" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "Verplaatsen naar werkblad lin_ks" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "Verplaatsen naar werkblad _rechts" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "Verplaatsen naar werkblad hierbov_en" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "Verplaatsen naar werkblad hier_onder" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "Sl_uiten" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "Werkblad %d%n" +#: data/org.gnome.mutter.gschema.xml.in:175 +msgid "Switch monitor configurations" +msgstr "Tussen beeldschermconfiguraties schakelen" -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "Werkblad 1_0" +#: data/org.gnome.mutter.gschema.xml.in:180 +msgid "Rotates the built-in monitor configuration" +msgstr "Roteert de ingebouwde beeldschermconfiguratie" -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "Werkblad %s%d" +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Schakelen naar VT 1" -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "Naar ander werkblad ver_plaatsen" +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Schakelen naar VT 2" -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Schakelen naar VT 3" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Schakelen naar VT 4" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Schakelen naar VT 5" -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Schakelen naar VT 6" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Schakelen naar VT 7" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Schakelen naar VT 8" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Schakelen naar VT 9" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Schakelen naar VT 10" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Schakelen naar VT 11" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Schakelen naar VT 12" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "Sneltoetsen opnieuw inschakelen" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow X11 grabs to lock keyboard focus with Xwayland" +msgstr "X11-grabs toestaan om toetsenbordfocus met Xwayland te vergrendelen" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 +msgid "" +"Allow all keyboard events to be routed to X11 “override redirect” windows " +"with a grab when running in Xwayland. This option is to support X11 clients " +"which map an “override redirect” window (which do not receive keyboard " +"focus) and issue a keyboard grab to force all keyboard events to that " +"window. This option is seldom used and has no effect on regular X11 windows " +"which can receive keyboard focus under normal circumstances. For a X11 grab " +"to be taken into account under Wayland, the client must also either send a " +"specific X11 ClientMessage to the root window or be among the applications " +"white-listed in key “xwayland-grab-access-rules”." +msgstr "" +"Toestaan dat alle toetsgebeurtenissen met een grab doorverwezen worden naar " +"X11 ‘doorverwijzingsoverschrijfvensters’ wanneer ze in Xwayland draaien. " +"Deze optie dient ter ondersteuning van X11-cliënten (die geen " +"toetsenbordfocus verkrijgen) die een venster om doorverwijzingen te " +"overschrijven gebruiken en een toetsenbord-grab gebruiken om alle " +"toetsgebeurtenissen naar dat venster dwingen. Deze optie wordt zelden " +"gebruikt en heeft geen effect op gewone X11-vensters, die in normale " +"omstandigheden toetsenbordfocus kunnen verkrijgen. Om rekening te houden met " +"een X11-grab onder Wayland, moet de client ook: óf een specifieke X11-" +"ClientMessage naar het root-venster sturen, óf vermeld staan in de witte " +"lijst van toepassingen in de sleutel ‘xwayland-grab-access-rules’." + +#: data/org.gnome.mutter.wayland.gschema.xml.in:84 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "Xwayland-toepassingen mogen toetsenbord-grabs doen" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:85 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "" +"Lijst met bronnamen of -klassen van X11-vensters die al dan niet worden " +"toegestaan X11-toetsonderscheppingen onder Xwayland uit te voeren. De " +"bronnaam of -klasse van een gegeven X11-venster kan worden verkregen met de " +"opdracht ‘xprop WM_CLASS’. Jokers als ‘*’ en ‘?’ worden ondersteund. Waarden " +"die beginnen met ‘!’ komen op de zwarte lijst, die voorrang heeft op de " +"witte lijst, om toepassingen de toegang tot de standaardsysteemlijst te " +"ontzeggen. De standaardsysteemlijst bevat volgende toepassingen: " +"‘@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@’. Gebruikers kunnen een bestaande " +"toetsonderschepping verbreken door de sneltoets te gebruiken die door de " +"toetsinstellende toets ‘restore-shortcuts’ wordt gedefinieerd." + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. #. -#: ../src/ui/resizepopup.c:113 +#: src/backends/meta-input-settings.c:2567 #, c-format -msgid "%d x %d" -msgstr "%d×%d" +msgid "Mode Switch (Group %d)" +msgstr "Moduswisselaar (groep %d)" -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "boven" +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2590 +msgid "Switch monitor" +msgstr "Van beeldscherm wisselen" -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "onder" +#: src/backends/meta-input-settings.c:2592 +msgid "Show on-screen help" +msgstr "Hulptekst op scherm tonen" -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "links" +#: src/backends/meta-monitor.c:223 +msgid "Built-in display" +msgstr "Ingebouwd beeldscherm" -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "rechts" +#: src/backends/meta-monitor.c:252 +msgid "Unknown" +msgstr "Onbekend" -# betere vertaling voor frame geometry? -#: ../src/ui/theme.c:286 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "kader-afmetingen geeft geen ‘%s’ dimensie" +#: src/backends/meta-monitor.c:254 +msgid "Unknown Display" +msgstr "Onbekend beeldscherm" -#: ../src/ui/theme.c:305 +#: src/backends/meta-monitor.c:262 #, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "kader-afmetingen geeft geen dimensie ‘%s’ voor rand ‘%s’" +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme.c:342 +#: src/backends/meta-monitor.c:270 #, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "Knopverhouding %g is onredelijk" +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme.c:354 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "Kader-afmetingen geeft geen afmeting van knoppen" +#. Translators: this string will appear in Sysprof +#: src/backends/meta-profiler.c:79 +msgid "Compositor" +msgstr "Compositor" -# Gradiënt hier beter? -#: ../src/ui/theme.c:1067 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:533 #, c-format -msgid "Gradients should have at least two colors" -msgstr "Kleurverloop moet tenminste twee kleuren hebben" - -#: ../src/ui/theme.c:1219 -#, fuzzy, c-format msgid "" -"GTK custom color specification must have color name and fallback in " -"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" +"Another compositing manager is already running on screen %i on display “%s”." msgstr "" -"GTK-kleurspecificatie moet een sluithaakje hebben na de status, dus: gtk: fg" -"[NORMAL] waarbij NORMAL de stutus is; kon ‘%s’ niet verwerken" +"Er is al een andere ‘compositing manager’ actief op scherm %i van " +"beeldscherm ‘%s’." + +#: src/core/bell.c:192 +msgid "Bell event" +msgstr "Bel-gebeurtenis" + +#: src/core/main.c:190 +msgid "Disable connection to session manager" +msgstr "Schakel de verbinding met het sessiebeheer uit" -#: ../src/ui/theme.c:1235 +#: src/core/main.c:196 +msgid "Replace the running window manager" +msgstr "De huidige toepassing voor vensterbeheer vervangen" + +#: src/core/main.c:202 +msgid "Specify session management ID" +msgstr "Specificeer de ID van het sessiebeheer" + +#: src/core/main.c:207 +msgid "X Display to use" +msgstr "De te gebruiken X-weergave" + +#: src/core/main.c:213 +msgid "Initialize session from savefile" +msgstr "Initialiseer de sessie middels een opslagbestand" + +#: src/core/main.c:219 +msgid "Make X calls synchronous" +msgstr "X-aanroepen synchroon maken" + +#: src/core/main.c:226 +msgid "Run as a wayland compositor" +msgstr "Uitvoeren als een wayland compositor" + +#: src/core/main.c:232 +msgid "Run as a nested compositor" +msgstr "Uitvoeren als een geneste compositor" + +#: src/core/main.c:238 +msgid "Run wayland compositor without starting Xwayland" +msgstr "Wayland-compositor uitvoeren zonder Xwayland te starten" + +#: src/core/main.c:246 +msgid "Run as a full display server, rather than nested" +msgstr "Uitvoeren als een volledige displayserver, in plaats van genest" + +#: src/core/main.c:252 +msgid "Run with X11 backend" +msgstr "Uitvoeren met X11-backend" + +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:151 #, c-format -msgid "" -"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" -"_ are valid" -msgstr "" +msgid "“%s” is not responding." +msgstr "‘%s’ reageert niet." + +#: src/core/meta-close-dialog-default.c:153 +msgid "Application is not responding." +msgstr "De toepassing reageert niet." -#: ../src/ui/theme.c:1249 -#, fuzzy, c-format +#: src/core/meta-close-dialog-default.c:158 msgid "" -"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " -"fit the format" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." msgstr "" -"Schaduwformaat is ‘schaduw/basiskleur/factor’, ‘%s’ voldoet niet aan dit " -"formaat" +"U kunt ervoor kiezen even te wachten totdat het doorgaat of de toepassing " +"dwingen om helemaal af te sluiten." + +#: src/core/meta-close-dialog-default.c:165 +msgid "_Force Quit" +msgstr "Ge_forceerd afsluiten" + +#: src/core/meta-close-dialog-default.c:165 +msgid "_Wait" +msgstr "_Wachten" -#: ../src/ui/theme.c:1294 +#: src/core/mutter.c:38 #, c-format msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" msgstr "" -"GTK-kleurspecificatie moet de toestand in rechte haken hebben, bijv. gtk:fg" -"[NORMAL] waarbij NORMAL de toestand is; kon ‘%s’ niet verwerken" +"mutter %s\n" +"Copyright © 2001–%d Havoc Pennington, Red Hat, Inc., en anderen\n" +"Dit is vrije software; zie de broncode voor de kopieervoorwaarden.\n" +"Er is GEEN garantie; zelfs niet voor VERKOOPBAARHEID of GESCHIKTHEID VOOR " +"EEN BEPAALD DOEL.\n" + +#: src/core/mutter.c:52 +msgid "Print version" +msgstr "Versie-informatie tonen" + +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "Te gebruiken Mutter-plug-in" -#: ../src/ui/theme.c:1308 +#: src/core/prefs.c:1911 +#, c-format +msgid "Workspace %d" +msgstr "Werkblad %d" + +#: src/core/util.c:122 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter is gecompileerd zonder ondersteuning voor verbose-mode\n" + +#: src/wayland/meta-wayland-tablet-pad.c:568 +#, c-format +msgid "Mode Switch: Mode %d" +msgstr "Moduswisselaar: modus %d" + +#: src/x11/meta-x11-display.c:676 #, c-format msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." msgstr "" -"GTK-kleurspecificatie moet een sluithaakje hebben na de status, dus: gtk: fg" -"[NORMAL] waarbij NORMAL de stutus is; kon ‘%s’ niet verwerken" +"Beeldscherm ‘%s’ heeft al een vensterbeheerder; probeer de optie: --replace " +"te gebruiken om de huidige vensterbeheerder te vervangen." + +#: src/x11/meta-x11-display.c:1089 +msgid "Failed to initialize GDK\n" +msgstr "Initialiseren van GDK mislukt\n" -#: ../src/ui/theme.c:1319 +#: src/x11/meta-x11-display.c:1113 #, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "Niet begrepen: status ‘%s’ in kleurspecificatie" +msgid "Failed to open X Window System display “%s”\n" +msgstr "Openen van X Window System display ‘%s’ mislukt\n" -#: ../src/ui/theme.c:1332 +#: src/x11/meta-x11-display.c:1196 #, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "Niet begrepen: kleurcomponent ‘%s’ in kleurspecificatie" +msgid "Screen %d on display “%s” is invalid\n" +msgstr "Scherm %d op beeldscherm ‘%s’ is ongeldig\n" -#: ../src/ui/theme.c:1361 +#: src/x11/meta-x11-selection-input-stream.c:460 #, c-format +msgid "Format %s not supported" +msgstr "Formaat %s wordt niet ondersteund" + +#: src/x11/session.c:1821 msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." msgstr "" -"Mengformaat is ‘meng/vg_kleur/ag_kleur/alpha’, ‘%s’ voldoet niet aan dit " -"formaat" +"Deze vensters ondersteunen het opslaan van de huidige instellingen niet en " +"zullen bij een volgende sessie opnieuw moeten worden opgestart." + +#: src/x11/window-props.c:569 +#, c-format +msgid "%s (on %s)" +msgstr "%s (op %s)" + +#~ msgid "Move window one workspace to the left" +#~ msgstr "Venster één werkblad naar links verplaatsen" + +#~ msgid "Move window one workspace to the right" +#~ msgstr "Venster één werkblad naar rechts verplaatsen" + +#~ msgid "Move to workspace left" +#~ msgstr "Verplaatsen naar werkblad links" + +#~ msgid "Move to workspace right" +#~ msgstr "Verplaatsen naar werkblad rechts" + +#~ msgid "Toggle shaded state" +#~ msgstr "Oprollen in- of uitschakelen" + +#~ msgid "background texture could not be created from file" +#~ msgstr "aanmaken achtergrondstructuur uit bestand mislukt" + +#~ msgid "Unknown window information request: %d" +#~ msgstr "Onbekende aanvraag voor vensterinformatie: %d" + +#~ msgid "Missing %s extension required for compositing" +#~ msgstr "Benodigde extensie ‘%s’ voor ‘compositing’ ontbreekt" + +# Gebruik controletoets als vertaling van modifier (Ctrl/Shift/Alt/Esc) +#~ msgid "" +#~ "Some other program is already using the key %s with modifiers %x as a " +#~ "binding\n" +#~ msgstr "" +#~ "Een ander programma gebruikt reeds de %s-toets met controletoets %x als " +#~ "sneltoets\n" + +#~ msgid "\"%s\" is not a valid accelerator\n" +#~ msgstr "‘%s’ is geen geldige sneltoets\n" + +#~ msgid "Failed to scan themes directory: %s\n" +#~ msgstr "Kon themamap niet scannen: %s\n" + +#~ msgid "" +#~ "Could not find a theme! Be sure %s exists and contains the usual themes.\n" +#~ msgstr "" +#~ "Kon geen thema vinden! Zorg ervoor dat %s bestaat en de gebruikelijke " +#~ "thema's bevat.\n" + +#~ msgid "" +#~ "Workarounds for broken applications disabled. Some applications may not " +#~ "behave properly.\n" +#~ msgstr "" +#~ "Werkoplossing voor gebroken toepassingen uitgezet. Bepaalde toepassingen " +#~ "zullen niet naar behoren functioneren.\n" + +#~ msgid "Could not parse font description \"%s\" from GSettings key %s\n" +#~ msgstr "" +#~ "Kon lettertypebeschrijving ‘%s’ niet lezen uit GSettings-sleutel %s\n" + +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" +#~ msgstr "" +#~ "‘%s’, gevonden in de configuratiedatabase, is geen geldige waarde voor de " +#~ "muisknop-optietoets\n" + +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for " +#~ "keybinding \"%s\"\n" +#~ msgstr "" +#~ "‘%s’ in de configuratiedatabase is geen geldige waarde voor sneltoets " +#~ "‘%s’\n" + +#~ msgid "" +#~ "Could not acquire window manager selection on screen %d display \"%s\"\n" +#~ msgstr "" +#~ "Kon ‘window manager’-selectie niet verkrijgen op scherm %d display ‘%s’\n" + +#~ msgid "Screen %d on display \"%s\" already has a window manager\n" +#~ msgstr "Scherm %d op display ‘%s’ heeft al een ‘window manager’\n" + +#~ msgid "Could not release screen %d on display \"%s\"\n" +#~ msgstr "Kon scherm %d op display ‘%s’ niet vrijmaken\n" + +#~ msgid "Could not create directory '%s': %s\n" +#~ msgstr "Kon map '%s' niet aanmaken: %s\n" + +#~ msgid "Could not open session file '%s' for writing: %s\n" +#~ msgstr "Kon sessiebestand '%s' niet openen voor schrijven: %s\n" + +#~ msgid "Error writing session file '%s': %s\n" +#~ msgstr "Fout bij schrijven sessiebestand '%s': %s\n" + +#~ msgid "Error closing session file '%s': %s\n" +#~ msgstr "Fout bij sluiten sessiebestand '%s': %s\n" + +#~ msgid "Failed to parse saved session file: %s\n" +#~ msgstr "Verwerken van opgeslagen sessiebestand mislukt: %s\n" + +#~ msgid "<mutter_session> attribute seen but we already have the session ID" +#~ msgstr "<mutter_session>-attribuut opgemerkt maar sessie-ID was al bekend" + +#~ msgid "Unknown attribute %s on <%s> element" +#~ msgstr "Onbekend attribuut ‘%s’ op <%s>-element" + +#~ msgid "nested <window> tag" +#~ msgstr "ingebedde <window>-markering" + +#~ msgid "Unknown element %s" +#~ msgstr "Onbekend element %s" + +#~ msgid "Failed to open debug log: %s\n" +#~ msgstr "Debug-logboek openen mislukt: %s\n" + +#~ msgid "Failed to fdopen() log file %s: %s\n" +#~ msgstr "Logboek %s openen via fdopen() mislukt: %s\n" + +#~ msgid "Opened log file %s\n" +#~ msgstr "Logboek %s geopend\n" + +#~ msgid "Window manager: " +#~ msgstr "Vensterbeheer:" + +#~ msgid "Bug in window manager: " +#~ msgstr "Fout in vensterbeheer:" + +#~ msgid "Window manager warning: " +#~ msgstr "Waarschuwing van vensterbeheer:" + +#~ msgid "Window manager error: " +#~ msgstr "Fout van vensterbeheer:" + +#~ msgid "" +#~ "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " +#~ "window as specified in the ICCCM.\n" +#~ msgstr "" +#~ "Venster %s stelt zelf SM_CLIENT_ID in, in plaats van bij het " +#~ "WM_CLIENT_LEADER-venster zoals gespecificeerd wordt in de ICCCM.\n" + +#~ msgid "" +#~ "Window %s sets an MWM hint indicating it isn't resizable, but sets min " +#~ "size %d x %d and max size %d x %d; this doesn't make much sense.\n" +#~ msgstr "" +#~ "Venster %s geeft een MWM-hint dat de grootte niet kan worden aangepast, " +#~ "maar stelt wel minimale grootte %d×%d en maximale grootte %d×%d in; dit " +#~ "is niet logisch.\n" + +#~ msgid "Application set a bogus _NET_WM_PID %lu\n" +#~ msgstr "Toepassing heeft een overbodige _NET_WM_PID %lu ingesteld\n" + +#~ msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +#~ msgstr "Ongeldig WM_TRANSIENT_FOR venster 0x%lx opgegeven voor %s.\n" + +#~ msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" +#~ msgstr "WM_TRANSIENT_FOR venster 0x%lx voor %s zou een ‘loop’ creëren.\n" + +#~ msgid "" +#~ "Window 0x%lx has property %s\n" +#~ "that was expected to have type %s format %d\n" +#~ "and actually has type %s format %d n_items %d.\n" +#~ "This is most likely an application bug, not a window manager bug.\n" +#~ "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +#~ msgstr "" +#~ "Venster 0x%lx heeft eigenschap %s\n" +#~ "welke zou moeten hebben: type %s en formaat %d\n" +#~ "maar in feite heeft: type %s formaat %d n_items %d.\n" +#~ "Dit is waarschijnlijk een fout van de toepassing, niet van de ‘window " +#~ "manager’.\n" +#~ "Het venster heeft title=‘%s’ class=‘%s’ naam=‘%s’\n" + +#~ msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +#~ msgstr "Eigenschap %s bij venster 0x%lx bevat ongeldige UTF-8\n" + +#~ msgid "" +#~ "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the " +#~ "list\n" +#~ msgstr "" +#~ "Eigenschap %s bij venster 0x%lx bevat ongeldige UTF-8 voor item %d van de " +#~ "lijst\n" + +#~ msgid "Mi_nimize" +#~ msgstr "_Minimaliseren" + +#~ msgid "Ma_ximize" +#~ msgstr "Ma_ximaliseren" + +#~ msgid "Unma_ximize" +#~ msgstr "_Herstellen" + +#~ msgid "Roll _Up" +#~ msgstr "_Oprollen" + +#~ msgid "_Unroll" +#~ msgstr "_Uitrollen" + +#~ msgid "_Move" +#~ msgstr "_Verplaatsen" + +#~ msgid "_Resize" +#~ msgstr "Afmetingen _wijzigen" + +#~ msgid "Move Titlebar On_screen" +#~ msgstr "_Titelbalk op scherm plaatsen" + +#~ msgid "Always on _Top" +#~ msgstr "Altijd _bovenop" + +#~ msgid "_Always on Visible Workspace" +#~ msgstr "Op _alle werkbladen zichtbaar" + +#~ msgid "_Only on This Workspace" +#~ msgstr "Alleen op _dit werkblad" + +#~ msgid "Move to Workspace _Left" +#~ msgstr "Verplaatsen naar werkblad lin_ks" + +#~ msgid "Move to Workspace R_ight" +#~ msgstr "Verplaatsen naar werkblad _rechts" + +#~ msgid "Move to Workspace _Up" +#~ msgstr "Verplaatsen naar werkblad hierbov_en" + +#~ msgid "Move to Workspace _Down" +#~ msgstr "Verplaatsen naar werkblad hier_onder" + +#~ msgid "_Close" +#~ msgstr "Sl_uiten" + +#~ msgid "Workspace %d%n" +#~ msgstr "Werkblad %d%n" + +#~ msgid "Workspace 1_0" +#~ msgstr "Werkblad 1_0" + +#~ msgid "Workspace %s%d" +#~ msgstr "Werkblad %s%d" + +#~ msgid "Move to Another _Workspace" +#~ msgstr "Naar ander werkblad ver_plaatsen" + +#~ msgid "Shift" +#~ msgstr "Shift" + +#~ msgid "Ctrl" +#~ msgstr "Ctrl" + +#~ msgid "Alt" +#~ msgstr "Alt" + +#~ msgid "Meta" +#~ msgstr "Meta" + +#~ msgid "Super" +#~ msgstr "Super" + +#~ msgid "Hyper" +#~ msgstr "Hyper" + +#~ msgid "Mod2" +#~ msgstr "Mod2" + +#~ msgid "Mod3" +#~ msgstr "Mod3" + +#~ msgid "Mod4" +#~ msgstr "Mod4" + +#~ msgid "Mod5" +#~ msgstr "Mod5" + +#~ msgid "%d x %d" +#~ msgstr "%d×%d" + +#~ msgid "top" +#~ msgstr "boven" + +#~ msgid "bottom" +#~ msgstr "onder" + +#~ msgid "left" +#~ msgstr "links" + +#~ msgid "right" +#~ msgstr "rechts" + +# betere vertaling voor frame geometry? +#~ msgid "frame geometry does not specify \"%s\" dimension" +#~ msgstr "kader-afmetingen geeft geen ‘%s’ dimensie" + +#~ msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" +#~ msgstr "kader-afmetingen geeft geen dimensie ‘%s’ voor rand ‘%s’" + +#~ msgid "Button aspect ratio %g is not reasonable" +#~ msgstr "Knopverhouding %g is onredelijk" + +#~ msgid "Frame geometry does not specify size of buttons" +#~ msgstr "Kader-afmetingen geeft geen afmeting van knoppen" + +# Gradiënt hier beter? +#~ msgid "Gradients should have at least two colors" +#~ msgstr "Kleurverloop moet tenminste twee kleuren hebben" + +#~ msgid "" +#~ "GTK custom color specification must have color name and fallback in " +#~ "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" +#~ msgstr "" +#~ "Aangepaste GTK-kleurspecificatie moet een kleurnaam en terugvaloptie " +#~ "hebben tussen haakjes, dus: gtk:custom(foo,bar); kon ‘%s’ niet verwerken" + +#~ msgid "" +#~ "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-" +#~ "z0-9-_ are valid" +#~ msgstr "" +#~ "Ongeldig teken ‘%c’ in color_name-parameter van gtk:custom, alleen A-Za-" +#~ "z0-9-_ zijn geldig" + +#~ msgid "" +#~ "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " +#~ "fit the format" +#~ msgstr "" +#~ "Gtk:custom-formaat is ‘gtk:custom(color_name,fallback)’, ‘%s’ voldoet " +#~ "niet aan dit formaat" + +#~ msgid "" +#~ "GTK color specification must have the state in brackets, e.g. gtk:" +#~ "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "GTK-kleurspecificatie moet de toestand in rechte haken hebben, bijv. gtk:" +#~ "fg[NORMAL] waarbij NORMAL de toestand is; kon ‘%s’ niet verwerken" + +#~ msgid "" +#~ "GTK color specification must have a close bracket after the state, e.g. " +#~ "gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "GTK-kleurspecificatie moet een sluithaakje hebben na de status, dus: gtk: " +#~ "fg[NORMAL] waarbij NORMAL de stutus is; kon ‘%s’ niet verwerken" + +#~ msgid "Did not understand state \"%s\" in color specification" +#~ msgstr "Niet begrepen: status ‘%s’ in kleurspecificatie" + +#~ msgid "Did not understand color component \"%s\" in color specification" +#~ msgstr "Niet begrepen: kleurcomponent ‘%s’ in kleurspecificatie" + +#~ msgid "" +#~ "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit " +#~ "the format" +#~ msgstr "" +#~ "Mengformaat is ‘meng/vg_kleur/ag_kleur/alpha’, ‘%s’ voldoet niet aan dit " +#~ "formaat" -#: ../src/ui/theme.c:1372 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "Kon alpha-waarde ‘%s’ niet verwerken in gemengde kleur" +#~ msgid "Could not parse alpha value \"%s\" in blended color" +#~ msgstr "Kon alpha-waarde ‘%s’ niet verwerken in gemengde kleur" -#: ../src/ui/theme.c:1382 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "Alpha-waarde ‘%s’ in gemengde kleur zit niet tussen 0.0 en 1.0" +#~ msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" +#~ msgstr "Alpha-waarde ‘%s’ in gemengde kleur zit niet tussen 0.0 en 1.0" -#: ../src/ui/theme.c:1429 -#, c-format -msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "" -"Schaduwformaat is ‘schaduw/basiskleur/factor’, ‘%s’ voldoet niet aan dit " -"formaat" +#~ msgid "" +#~ "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the " +#~ "format" +#~ msgstr "" +#~ "Schaduwformaat is ‘schaduw/basiskleur/factor’, ‘%s’ voldoet niet aan dit " +#~ "formaat" -#: ../src/ui/theme.c:1440 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "Kon schaduwfactor ‘%s’ in schaduwkleur niet verwerken" +#~ msgid "Could not parse shade factor \"%s\" in shaded color" +#~ msgstr "Kon schaduwfactor ‘%s’ in schaduwkleur niet verwerken" -#: ../src/ui/theme.c:1450 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "Schaduwfactor ‘%s’ in schaduwkleur is negatief" +#~ msgid "Shade factor \"%s\" in shaded color is negative" +#~ msgstr "Schaduwfactor ‘%s’ in schaduwkleur is negatief" -#: ../src/ui/theme.c:1479 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Kon kleur ‘%s’ niet verwerken" +#~ msgid "Could not parse color \"%s\"" +#~ msgstr "Kon kleur ‘%s’ niet verwerken" -#: ../src/ui/theme.c:1790 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "Coördinaatuitdrukking bevat letterteken '%s' wat niet is toegestaan" +#~ msgid "Coordinate expression contains character '%s' which is not allowed" +#~ msgstr "Coördinaatuitdrukking bevat letterteken '%s' wat niet is toegestaan" -#: ../src/ui/theme.c:1817 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "" -"Coördinaatuitdrukking bevat floating-point getal '%s' wat niet kon worden " -"verwerkt" +#~ msgid "" +#~ "Coordinate expression contains floating point number '%s' which could not " +#~ "be parsed" +#~ msgstr "" +#~ "Coördinaatuitdrukking bevat floating-point getal '%s' wat niet kon worden " +#~ "verwerkt" -#: ../src/ui/theme.c:1831 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "" -"Coördinaatuitdrukking bevat geheel getal '%s' wat niet kon worden verwerkt" +#~ msgid "" +#~ "Coordinate expression contains integer '%s' which could not be parsed" +#~ msgstr "" +#~ "Coördinaatuitdrukking bevat geheel getal '%s' wat niet kon worden verwerkt" # hoe vertalen we operator en operand? -#: ../src/ui/theme.c:1953 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "" -"Coördinaatuitdrukking bevat een onbekende functie aan het begin van deze " -"tekst: ‘%s’" +#~ msgid "" +#~ "Coordinate expression contained unknown operator at the start of this " +#~ "text: \"%s\"" +#~ msgstr "" +#~ "Coördinaatuitdrukking bevat een onbekende functie aan het begin van deze " +#~ "tekst: ‘%s’" -#: ../src/ui/theme.c:2010 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "Coördinaatuitdrukking was leeg of was niet begrepen" +#~ msgid "Coordinate expression was empty or not understood" +#~ msgstr "Coördinaatuitdrukking was leeg of was niet begrepen" -#: ../src/ui/theme.c:2121 ../src/ui/theme.c:2131 ../src/ui/theme.c:2165 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "Coördinaatuitdrukking resulteert in een deling door nul" +#~ msgid "Coordinate expression results in division by zero" +#~ msgstr "Coördinaatuitdrukking resulteert in een deling door nul" -#: ../src/ui/theme.c:2173 -#, c-format -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "" -"Coördinaatuitdrukking probeert een mod-functie te gebruiken op een floating-" -"point getal" +#~ msgid "" +#~ "Coordinate expression tries to use mod operator on a floating-point number" +#~ msgstr "" +#~ "Coördinaatuitdrukking probeert een mod-functie te gebruiken op een " +#~ "floating-point getal" -#: ../src/ui/theme.c:2229 -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "" -"Coördinaatuitdrukking bevat een functie ‘%s’ waar een argument werd verwacht" +#~ msgid "" +#~ "Coordinate expression has an operator \"%s\" where an operand was expected" +#~ msgstr "" +#~ "Coördinaatuitdrukking bevat een functie ‘%s’ waar een argument werd " +#~ "verwacht" -#: ../src/ui/theme.c:2238 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "" -"Coördinaatuitdrukking bevat een argument waar een functie werd verwacht" +#~ msgid "Coordinate expression had an operand where an operator was expected" +#~ msgstr "" +#~ "Coördinaatuitdrukking bevat een argument waar een functie werd verwacht" -#: ../src/ui/theme.c:2246 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "" -"Coördinaatuitdrukking eindigde met een functie in plaats van een argument" +#~ msgid "Coordinate expression ended with an operator instead of an operand" +#~ msgstr "" +#~ "Coördinaatuitdrukking eindigde met een functie in plaats van een argument" -#: ../src/ui/theme.c:2256 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" -"Coördinaatuitdrukking bevat functie ‘%c’ volgend op functie ‘%c’ zonder " -"argument in het midden" +#~ msgid "" +#~ "Coordinate expression has operator \"%c\" following operator \"%c\" with " +#~ "no operand in between" +#~ msgstr "" +#~ "Coördinaatuitdrukking bevat functie ‘%c’ volgend op functie ‘%c’ zonder " +#~ "argument in het midden" -#: ../src/ui/theme.c:2407 ../src/ui/theme.c:2452 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "Coördinaatuitdrukking bevat een onbekende variabele of constante ‘%s’" +#~ msgid "Coordinate expression had unknown variable or constant \"%s\"" +#~ msgstr "" +#~ "Coördinaatuitdrukking bevat een onbekende variabele of constante ‘%s’" # Dit is zo'n dergelijk moeilijke vertaling als in het Nederlands, dat het # Engelse origineel een beter restultaat oplevert. # -- Michiel Sikkes, zo 9 apr 2006 -#: ../src/ui/theme.c:2506 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "Coordinate experssion parser overflowed its buffer." - -#: ../src/ui/theme.c:2535 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "Coördinaatuitdrukking bevat een sluithaakje zonder openingshaakje" - -#: ../src/ui/theme.c:2599 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "Coördinaatuitdrukking bevat een openingshaakje zonder sluithaakje" - -#: ../src/ui/theme.c:2610 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "Coördinaatuitdrukking bevat schijnbaar geen functies of argumenten" - -#: ../src/ui/theme.c:2822 ../src/ui/theme.c:2842 ../src/ui/theme.c:2862 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "Expressie in thema resulteerde in een foutmelding: %s\n" - -#: ../src/ui/theme.c:4533 -#, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"iets\"/> moet voor deze " -"kader-stijl gespecificeerd worden" - -#: ../src/ui/theme.c:5066 ../src/ui/theme.c:5091 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" -"Ontbrekende <frame state=\"%s\" resize=\"%s\" docus=\"%s\" style=\"iets\"/>" +#~ msgid "Coordinate expression parser overflowed its buffer." +#~ msgstr "Coordinate experssion parser overflowed its buffer." -#: ../src/ui/theme.c:5139 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Laden thema ‘%s’ mislukt: %s\n" +#~ msgid "" +#~ "Coordinate expression had a close parenthesis with no open parenthesis" +#~ msgstr "Coördinaatuitdrukking bevat een sluithaakje zonder openingshaakje" -#: ../src/ui/theme.c:5275 ../src/ui/theme.c:5282 ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 ../src/ui/theme.c:5303 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "Geen <%s> ingesteld voor thema ‘%s’ " +#~ msgid "" +#~ "Coordinate expression had an open parenthesis with no close parenthesis" +#~ msgstr "Coördinaatuitdrukking bevat een openingshaakje zonder sluithaakje" -#: ../src/ui/theme.c:5311 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" -"Geen kader-stijl ingesteld voor venstertype ‘%s’ in thema ‘%s’, voeg een " -"<window type=\"%s\" style_set=\"iets\"/> element toe" +#~ msgid "Coordinate expression doesn't seem to have any operators or operands" +#~ msgstr "Coördinaatuitdrukking bevat schijnbaar geen functies of argumenten" -#: ../src/ui/theme.c:5709 ../src/ui/theme.c:5771 ../src/ui/theme.c:5834 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" -"Door de gebruiker gedefinieerde constanten moeten met een hoofdletter " -"beginnen; ‘%s’ doet dat niet" +#~ msgid "Theme contained an expression that resulted in an error: %s\n" +#~ msgstr "Expressie in thema resulteerde in een foutmelding: %s\n" -#: ../src/ui/theme.c:5717 ../src/ui/theme.c:5779 ../src/ui/theme.c:5842 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "Constante ‘%s’ is reeds gedefinieerd" +#~ msgid "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " +#~ "specified for this frame style" +#~ msgstr "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"iets\"/> moet voor deze " +#~ "kader-stijl gespecificeerd worden" -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. -#. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "Geen ‘%s’-attribuut op element <%s>" +#~ msgid "" +#~ "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/" +#~ ">" +#~ msgstr "" +#~ "Ontbrekende <frame state=\"%s\" resize=\"%s\" docus=\"%s\" style=\"iets\"/" +#~ ">" -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Regel %d teken %d: %s" +#~ msgid "Failed to load theme \"%s\": %s\n" +#~ msgstr "Laden thema ‘%s’ mislukt: %s\n" -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "Attribuut ‘%s’ twee keer herhaald op hetzelfde <%s>-element" +#~ msgid "No <%s> set for theme \"%s\"" +#~ msgstr "Geen <%s> ingesteld voor thema ‘%s’ " -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "Attribuut ‘%s’ is ongeldig op een <%s>-element in deze context" +#~ msgid "" +#~ "No frame style set for window type \"%s\" in theme \"%s\", add a <window " +#~ "type=\"%s\" style_set=\"whatever\"/> element" +#~ msgstr "" +#~ "Geen kader-stijl ingesteld voor venstertype ‘%s’ in thema ‘%s’, voeg een " +#~ "<window type=\"%s\" style_set=\"iets\"/> element toe" -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "Kon ‘%s’ niet verwerken als geheel getal" +#~ msgid "" +#~ "User-defined constants must begin with a capital letter; \"%s\" does not" +#~ msgstr "" +#~ "Door de gebruiker gedefinieerde constanten moeten met een hoofdletter " +#~ "beginnen; ‘%s’ doet dat niet" -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "Niet begrepen: de laatste tekens ‘%s’ in ‘%s’" +#~ msgid "Constant \"%s\" has already been defined" +#~ msgstr "Constante ‘%s’ is reeds gedefinieerd" -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "Geheel getal %ld moet positief zijn" +#~ msgid "No \"%s\" attribute on element <%s>" +#~ msgstr "Geen ‘%s’-attribuut op element <%s>" -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "Geheel getal %ld is te groot, huidige maximum is %d" +#~ msgid "Line %d character %d: %s" +#~ msgstr "Regel %d teken %d: %s" -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "Kon ‘%s’ niet als 'floating-point'-getal verwerken" +#~ msgid "Attribute \"%s\" repeated twice on the same <%s> element" +#~ msgstr "Attribuut ‘%s’ twee keer herhaald op hetzelfde <%s>-element" -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "Boolese waarde moet ‘true’ of ‘false’ zijn, niet ‘%s’" +#~ msgid "Attribute \"%s\" is invalid on <%s> element in this context" +#~ msgstr "Attribuut ‘%s’ is ongeldig op een <%s>-element in deze context" -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "Hoek moet liggen tussen 0.0 en 360.0, maar was %g\n" +#~ msgid "Could not parse \"%s\" as an integer" +#~ msgstr "Kon ‘%s’ niet verwerken als geheel getal" -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" -"Alpha moet liggen tussen 0.0 (onzichtbaar) en 1.0 (volledig ondoorzichtig), " -"maar was %g\n" +#~ msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +#~ msgstr "Niet begrepen: de laatste tekens ‘%s’ in ‘%s’" -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"Ongeldige titel-schaal ‘%s’ (u kunt kiezen uit: xx-small, x-small, small, " -"medium, large, x-large, xx-large)\n" +#~ msgid "Integer %ld must be positive" +#~ msgstr "Geheel getal %ld moet positief zijn" -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s>-naam ‘%s’ een tweede keer gebruikt" +#~ msgid "Integer %ld is too large, current max is %d" +#~ msgstr "Geheel getal %ld is te groot, huidige maximum is %d" -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "<%s>-ouder ‘%s’ is niet gedefinieerd" +#~ msgid "Could not parse \"%s\" as a floating point number" +#~ msgstr "Kon ‘%s’ niet als 'floating-point'-getal verwerken" -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "<%s>-afmetingen ‘%s’ is niet gedefinieerd" +#~ msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" +#~ msgstr "Boolese waarde moet ‘true’ of ‘false’ zijn, niet ‘%s’" -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "<%s> moet ofwel afmetingen specificeren, of een ouder met afmetingen" +#~ msgid "Angle must be between 0.0 and 360.0, was %g\n" +#~ msgstr "Hoek moet liggen tussen 0.0 en 360.0, maar was %g\n" -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "" -"U dient een achtergrond te specificeren voordat een alpha-waarde betekenis " -"heeft" +#~ msgid "" +#~ "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" +#~ msgstr "" +#~ "Alpha moet liggen tussen 0.0 (onzichtbaar) en 1.0 (volledig " +#~ "ondoorzichtig), maar was %g\n" -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Onbekend type ‘%s’ op <%s>-element" +#~ msgid "" +#~ "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," +#~ "large,x-large,xx-large)\n" +#~ msgstr "" +#~ "Ongeldige titel-schaal ‘%s’ (u kunt kiezen uit: xx-small, x-small, small, " +#~ "medium, large, x-large, xx-large)\n" -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "Onbekende style_set ‘%s’ op <%s>-element" +#~ msgid "<%s> name \"%s\" used a second time" +#~ msgstr "<%s>-naam ‘%s’ een tweede keer gebruikt" -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "Venstertype ‘%s’ heeft reeds een stijlset toegewezen gekregen" - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "Element <%s> is niet toegestaan onder <%s>" +#~ msgid "<%s> parent \"%s\" has not been defined" +#~ msgstr "<%s>-ouder ‘%s’ is niet gedefinieerd" -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" -msgstr "" -"Kan niet tegelijk ‘button_width’/‘button_height’ en ‘aspect_ratio’ voor " -"knoppen opgeven." +#~ msgid "<%s> geometry \"%s\" has not been defined" +#~ msgstr "<%s>-afmetingen ‘%s’ is niet gedefinieerd" -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "Afstand ‘%s’ is onbekend" +#~ msgid "<%s> must specify either a geometry or a parent that has a geometry" +#~ msgstr "" +#~ "<%s> moet ofwel afmetingen specificeren, of een ouder met afmetingen" -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "Verhouding ‘%s’ is onbekend" +#~ msgid "You must specify a background for an alpha value to be meaningful" +#~ msgstr "" +#~ "U dient een achtergrond te specificeren voordat een alpha-waarde " +#~ "betekenis heeft" -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "Rand ‘%s’ is onbekend" +#~ msgid "Unknown type \"%s\" on <%s> element" +#~ msgstr "Onbekend type ‘%s’ op <%s>-element" -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "Geen ‘start_angle’- of ‘from’-attribuut op element <%s>" +#~ msgid "Unknown style_set \"%s\" on <%s> element" +#~ msgstr "Onbekende style_set ‘%s’ op <%s>-element" -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "Geen ‘extent_angle’- of ‘to’-attribuut op element <%s>" +#~ msgid "Window type \"%s\" has already been assigned a style set" +#~ msgstr "Venstertype ‘%s’ heeft reeds een stijlset toegewezen gekregen" -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "Niet begrepen: de waarde ‘%s’ voor type kleurverloop" +#~ msgid "Element <%s> is not allowed below <%s>" +#~ msgstr "Element <%s> is niet toegestaan onder <%s>" -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "Niet begrepen: vul-type ‘%s’ voor <%s>-element" +#~ msgid "" +#~ "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio" +#~ "\" for buttons" +#~ msgstr "" +#~ "Kan niet tegelijk ‘button_width’/‘button_height’ en ‘aspect_ratio’ voor " +#~ "knoppen opgeven." -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "Niet begrepen: status ‘%s’ voor <%s>-element" +#~ msgid "Distance \"%s\" is unknown" +#~ msgstr "Afstand ‘%s’ is onbekend" -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "Niet begrepen: schaduw ‘%s’ voor <%s>-element" +#~ msgid "Aspect ratio \"%s\" is unknown" +#~ msgstr "Verhouding ‘%s’ is onbekend" -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "Niet begrepen: pijl ‘%s’ voor <%s>-element" +#~ msgid "Border \"%s\" is unknown" +#~ msgstr "Rand ‘%s’ is onbekend" -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "Er zijn geen <draw_ops> genaamd ‘%s’ gedefinieerd" +#~ msgid "No \"start_angle\" or \"from\" attribute on element <%s>" +#~ msgstr "Geen ‘start_angle’- of ‘from’-attribuut op element <%s>" -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "Hier ‘draw_ops’ ‘%s’ meenemen zou een circulaire verwijzing creëren" +#~ msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" +#~ msgstr "Geen ‘extent_angle’- of ‘to’-attribuut op element <%s>" -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Onbekende positie ‘%s’ voor kader-onderdeel" +#~ msgid "Did not understand value \"%s\" for type of gradient" +#~ msgstr "Niet begrepen: de waarde ‘%s’ voor type kleurverloop" -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "Kader-stijl heeft al een onderdeel op positie %s" +#~ msgid "Did not understand fill type \"%s\" for <%s> element" +#~ msgstr "Niet begrepen: vul-type ‘%s’ voor <%s>-element" -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "Er zijn geen <draw_ops> met naam ‘%s’ gedefinieerd" +#~ msgid "Did not understand state \"%s\" for <%s> element" +#~ msgstr "Niet begrepen: status ‘%s’ voor <%s>-element" -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Onbekende functie ‘%s’ voor knop" +#~ msgid "Did not understand shadow \"%s\" for <%s> element" +#~ msgstr "Niet begrepen: schaduw ‘%s’ voor <%s>-element" -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "Knopfunctie ‘%s’ bestaat niet in deze versie (%d, %d benodigd)" +#~ msgid "Did not understand arrow \"%s\" for <%s> element" +#~ msgstr "Niet begrepen: pijl ‘%s’ voor <%s>-element" -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Onbekende status ‘%s’ voor knop" +#~ msgid "No <draw_ops> called \"%s\" has been defined" +#~ msgstr "Er zijn geen <draw_ops> genaamd ‘%s’ gedefinieerd" -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "Kader-stijl heeft reeds een knop voor functie %s status %s" +#~ msgid "Including draw_ops \"%s\" here would create a circular reference" +#~ msgstr "Hier ‘draw_ops’ ‘%s’ meenemen zou een circulaire verwijzing creëren" -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "‘%s’ is geen geldige waarde voor ‘focus’-attribuut" +#~ msgid "Unknown position \"%s\" for frame piece" +#~ msgstr "Onbekende positie ‘%s’ voor kader-onderdeel" -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "‘%s’ is geen geldige waarde voor ‘state’-attribuut" +#~ msgid "Frame style already has a piece at position %s" +#~ msgstr "Kader-stijl heeft al een onderdeel op positie %s" -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "Een stijl genaamd ‘%s’ is niet gedefinieerd" +#~ msgid "No <draw_ops> with the name \"%s\" has been defined" +#~ msgstr "Er zijn geen <draw_ops> met naam ‘%s’ gedefinieerd" -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "‘%s’ is geen geldige waarde voor ‘resize’-attribuut" +#~ msgid "Unknown function \"%s\" for button" +#~ msgstr "Onbekende functie ‘%s’ voor knop" -#: ../src/ui/theme-parser.c:3147 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" -"Behoort geen ‘resize’-attribuut te hebben op <%s>-element voor " -"gemaximaliseerde/opgerolde toestanden" +#~ msgid "Button function \"%s\" does not exist in this version (%d, need %d)" +#~ msgstr "Knopfunctie ‘%s’ bestaat niet in deze versie (%d, %d benodigd)" -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "" -"Behoort geen ‘resize’-attribuut te hebben op <%s>-element voor " -"gemaximaliseerde toestand" +#~ msgid "Unknown state \"%s\" for button" +#~ msgstr "Onbekende status ‘%s’ voor knop" -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "" -"Stijl is reeds gespecificeerd voor status %s grootte aanpassen %s aandacht %s" +#~ msgid "Frame style already has a button for function %s state %s" +#~ msgstr "Kader-stijl heeft reeds een knop voor functie %s status %s" -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "Stijl is reeds gespecificeerd voor status %s aandacht %s" +#~ msgid "\"%s\" is not a valid value for focus attribute" +#~ msgstr "‘%s’ is geen geldige waarde voor ‘focus’-attribuut" -#: ../src/ui/theme-parser.c:3294 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Kan niet twee ‘draw_ops’ voor een <piece>-element hebben (thema " -"specificeerde een ‘draw_ops’-attribuut en tevens een <draw_ops>-element, of " -"specificeerde twee elementen)" +#~ msgid "\"%s\" is not a valid value for state attribute" +#~ msgstr "‘%s’ is geen geldige waarde voor ‘state’-attribuut" -#: ../src/ui/theme-parser.c:3332 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Kan niet twee ‘draw_ops’ voor een <button>-element hebben (thema " -"specificeerde een ‘draw_ops’-attribuut en tevens een <draw_ops>-element, of " -"specificeerde twee elementen)" +#~ msgid "A style called \"%s\" has not been defined" +#~ msgstr "Een stijl genaamd ‘%s’ is niet gedefinieerd" -#: ../src/ui/theme-parser.c:3370 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Kan niet twee ‘draw_ops’ voor een <menu_icon>-element hebben (thema " -"specificeerde een ‘draw_ops’-attribuut en tevens een <draw_ops>-element, of " -"specificeerde twee elementen)" +#~ msgid "\"%s\" is not a valid value for resize attribute" +#~ msgstr "‘%s’ is geen geldige waarde voor ‘resize’-attribuut" -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "Foutieve opgave van versie: ‘%s’" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized/shaded " +#~ "states" +#~ msgstr "" +#~ "Behoort geen ‘resize’-attribuut te hebben op <%s>-element voor " +#~ "gemaximaliseerde/opgerolde toestanden" -#: ../src/ui/theme-parser.c:3507 -msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" -msgstr "" -"Het ‘version’-attribuut kan niet gebruikt worden in metacity-theme-1.xml of " -"metacity-theme-2.xml." +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized states" +#~ msgstr "" +#~ "Behoort geen ‘resize’-attribuut te hebben op <%s>-element voor " +#~ "gemaximaliseerde toestand" -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "" -"Het thema vereist versie %s, maar de recentste ondersteunde versie is %d.%d" +#~ msgid "Style has already been specified for state %s resize %s focus %s" +#~ msgstr "" +#~ "Stijl is reeds gespecificeerd voor status %s grootte aanpassen %s " +#~ "aandacht %s" -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "Buitenste element in thema moet zijn: <metacity_theme>, niet <%s>" +#~ msgid "Style has already been specified for state %s focus %s" +#~ msgstr "Stijl is reeds gespecificeerd voor status %s aandacht %s" -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "" -"Element <%s> is niet toegestaan binnen een naam/auteur/datum/beschrijving " -"element" +#~ msgid "" +#~ "Can't have a two draw_ops for a <piece> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Kan niet twee ‘draw_ops’ voor een <piece>-element hebben (thema " +#~ "specificeerde een ‘draw_ops’-attribuut en tevens een <draw_ops>-element, " +#~ "of specificeerde twee elementen)" -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "Element <%s> is niet toegestaan binnen een <constant>-element" +#~ msgid "" +#~ "Can't have a two draw_ops for a <button> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Kan niet twee ‘draw_ops’ voor een <button>-element hebben (thema " +#~ "specificeerde een ‘draw_ops’-attribuut en tevens een <draw_ops>-element, " +#~ "of specificeerde twee elementen)" -#: ../src/ui/theme-parser.c:3599 -#, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "" -"Element <%s> is niet toegestaan binnen de elementen distance/border/" -"aspect_ratio" +#~ msgid "" +#~ "Can't have a two draw_ops for a <menu_icon> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Kan niet twee ‘draw_ops’ voor een <menu_icon>-element hebben (thema " +#~ "specificeerde een ‘draw_ops’-attribuut en tevens een <draw_ops>-element, " +#~ "of specificeerde twee elementen)" -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "Element <%s> is niet toegestaan binnen een ‘draw operation’-element" +#~ msgid "Bad version specification '%s'" +#~ msgstr "Foutieve opgave van versie: ‘%s’" -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "Element <%s> is niet toegestaan binnen een <%s>-element" +#~ msgid "" +#~ "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" +#~ "theme-2.xml" +#~ msgstr "" +#~ "Het ‘version’-attribuut kan niet gebruikt worden in metacity-theme-1.xml " +#~ "of metacity-theme-2.xml." -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "Geen ‘draw_ops’ gegeven voor kader-onderdeel" +#~ msgid "" +#~ "Theme requires version %s but latest supported theme version is %d.%d" +#~ msgstr "" +#~ "Het thema vereist versie %s, maar de recentste ondersteunde versie is %d." +#~ "%d" -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "Geen ‘draw_ops’ gegeven voor knop" +#~ msgid "Outermost element in theme must be <metacity_theme> not <%s>" +#~ msgstr "Buitenste element in thema moet zijn: <metacity_theme>, niet <%s>" -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "Geen tekst toegestaan binnen element <%s>" +#~ msgid "" +#~ "Element <%s> is not allowed inside a name/author/date/description element" +#~ msgstr "" +#~ "Element <%s> is niet toegestaan binnen een naam/auteur/datum/beschrijving " +#~ "element" -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "<%s> twee keer gegeven voor dit thema" +#~ msgid "Element <%s> is not allowed inside a <constant> element" +#~ msgstr "Element <%s> is niet toegestaan binnen een <constant>-element" -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Geen geldig bestand gevonden voor thema %s\n" +#~ msgid "" +#~ "Element <%s> is not allowed inside a distance/border/aspect_ratio element" +#~ msgstr "" +#~ "Element <%s> is niet toegestaan binnen de elementen distance/border/" +#~ "aspect_ratio" -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "_Vensters" +#~ msgid "Element <%s> is not allowed inside a draw operation element" +#~ msgstr "Element <%s> is niet toegestaan binnen een ‘draw operation’-element" -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "_Dialoogvenster" +#~ msgid "Element <%s> is not allowed inside a <%s> element" +#~ msgstr "Element <%s> is niet toegestaan binnen een <%s>-element" -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "_Blokkerend dialoogvenster" +#~ msgid "No draw_ops provided for frame piece" +#~ msgstr "Geen ‘draw_ops’ gegeven voor kader-onderdeel" -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "_Hulpvensters" +#~ msgid "No draw_ops provided for button" +#~ msgstr "Geen ‘draw_ops’ gegeven voor knop" -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "_Introvenster" +#~ msgid "No text is allowed inside element <%s>" +#~ msgstr "Geen tekst toegestaan binnen element <%s>" -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "_Bovenpaneel" +#~ msgid "<%s> specified twice for this theme" +#~ msgstr "<%s> twee keer gegeven voor dit thema" -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "_Onderpaneel" +#~ msgid "Failed to find a valid file for theme %s\n" +#~ msgstr "Geen geldig bestand gevonden voor thema %s\n" -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "Paneel _links" +#~ msgid "Comma-separated list of compositor plugins" +#~ msgstr "Komma-gescheiden lijst van compositor-plugins" -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "Paneel _rechts" +#~ msgid "Live Hidden Windows" +#~ msgstr "Verborgen vensters ‘live’ houden" -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "_Alle panelen" +#~ msgid "" +#~ "Determines whether hidden windows (i.e., minimized windows and windows on " +#~ "other workspaces than the current one) should be kept alive." +#~ msgstr "" +#~ "Geeft aan of verborgen vensters (bijvoorbeeld geminimaliseerd of op een " +#~ "ander werkblad) in ‘live’ gehouden moeten worden." -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "_Bureaublad" +#~ msgid "Usage: %s\n" +#~ msgstr "Gebruik: %s\n" -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "Nog zo'n venster openen" +#~ msgid "_Windows" +#~ msgstr "_Vensters" -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "Dit is een demoknop met een 'openen'-pictogram" +#~ msgid "_Dialog" +#~ msgstr "_Dialoogvenster" -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "Dit is een demoknop met een 'afsluiten'-pictogram" +#~ msgid "_Modal dialog" +#~ msgstr "_Blokkerend dialoogvenster" -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "Dit is een voorbeeldbericht in een voorbeelddialoogvenster" +#~ msgid "_Utility" +#~ msgstr "_Hulpvensters" -#: ../src/ui/theme-viewer.c:328 -#, c-format -msgid "Fake menu item %d\n" -msgstr "Nepmenu-item %d\n" +#~ msgid "_Splashscreen" +#~ msgstr "_Introvenster" -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "Venster met alleen randen" +#~ msgid "_Top dock" +#~ msgstr "_Bovenpaneel" -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "Balk" +#~ msgid "_Bottom dock" +#~ msgstr "_Onderpaneel" -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "Normaal programmavenster" +#~ msgid "_Left dock" +#~ msgstr "Paneel _links" -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "Dialoogvenster" +#~ msgid "_Right dock" +#~ msgstr "Paneel _rechts" -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "Blokkerend dialoogvenster" +#~ msgid "_All docks" +#~ msgstr "_Alle panelen" -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "Gereedschapskist" +#~ msgid "Des_ktop" +#~ msgstr "_Bureaublad" -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "Losgescheurd menu" +#~ msgid "Open another one of these windows" +#~ msgstr "Nog zo'n venster openen" -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "Rand" +#~ msgid "This is a demo button with an 'open' icon" +#~ msgstr "Dit is een demoknop met een 'openen'-pictogram" -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "Aangekoppeld blokkerend dialoogvenster" +#~ msgid "This is a demo button with a 'quit' icon" +#~ msgstr "Dit is een demoknop met een 'afsluiten'-pictogram" -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "Knoppenopmaaktest %d" +#~ msgid "This is a sample message in a sample dialog" +#~ msgstr "Dit is een voorbeeldbericht in een voorbeelddialoogvenster" -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g milliseconden om een vensterraamwerk te tekenen" +#~ msgid "Fake menu item %d\n" +#~ msgstr "Nepmenu-item %d\n" -#: ../src/ui/theme-viewer.c:813 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Gebruik: metacity-theme-viewer [THEMANAAM]\n" +#~ msgid "Border-only window" +#~ msgstr "Venster met alleen randen" -#: ../src/ui/theme-viewer.c:820 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "Fout bij laden van thema: %s\n" +#~ msgid "Bar" +#~ msgstr "Balk" -#: ../src/ui/theme-viewer.c:826 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "Thema ‘%s’ in %g seconden geladen\n" +#~ msgid "Normal Application Window" +#~ msgstr "Normaal programmavenster" -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "Lettertype voor normale titel" +#~ msgid "Dialog Box" +#~ msgstr "Dialoogvenster" -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "Lettertype voor kleine titel" +#~ msgid "Modal Dialog Box" +#~ msgstr "Blokkerend dialoogvenster" -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "Lettertype voor grote titel" +#~ msgid "Utility Palette" +#~ msgstr "Gereedschapskist" -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "Knoppenopmaak" +#~ msgid "Torn-off Menu" +#~ msgstr "Losgescheurd menu" -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "Benchmark" +#~ msgid "Border" +#~ msgstr "Rand" -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "Hier komt de titel" +#~ msgid "Attached Modal Dialog" +#~ msgstr "Aangekoppeld blokkerend dialoogvenster" -#: ../src/ui/theme-viewer.c:1047 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"%d frames getekend in %g seconden voor client (%g milliseconden per frame) " -"en %g seconden op wandklok inclusief X serverbronnen (%g milliseconden per " -"frame)\n" +#~ msgid "Button layout test %d" +#~ msgstr "Knoppenopmaaktest %d" -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "positie-expressietest gaf WAAR terug, maar gaf wel een fout" +#~ msgid "%g milliseconds to draw one window frame" +#~ msgstr "%g milliseconden om een vensterraamwerk te tekenen" -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "positie-expressietest gaf ONWAAR terug, maar gaf geen fout" +#~ msgid "Usage: metacity-theme-viewer [THEMENAME]\n" +#~ msgstr "Gebruik: metacity-theme-viewer [THEMANAAM]\n" -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "Fout verwacht maar niet ontvangen" +#~ msgid "Error loading theme: %s\n" +#~ msgstr "Fout bij laden van thema: %s\n" -#: ../src/ui/theme-viewer.c:1274 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "Fout %d verwacht maar %d gekregen" +#~ msgid "Loaded theme \"%s\" in %g seconds\n" +#~ msgstr "Thema ‘%s’ in %g seconden geladen\n" -#: ../src/ui/theme-viewer.c:1280 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "Geen fout verwacht maar kreeg wel een fout: %s" +#~ msgid "Normal Title Font" +#~ msgstr "Lettertype voor normale titel" -#: ../src/ui/theme-viewer.c:1284 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "x-waarde is %d, %d verwacht" +#~ msgid "Small Title Font" +#~ msgstr "Lettertype voor kleine titel" -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "y-waarde is %d, %d verwacht" +#~ msgid "Large Title Font" +#~ msgstr "Lettertype voor grote titel" -#: ../src/ui/theme-viewer.c:1352 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "" -"%d coördinatenexpressies verwerkt in %g seconden (gemiddelde van %g " -"seconden)\n" +#~ msgid "Button Layouts" +#~ msgstr "Knoppenopmaak" -#~ msgid "Switch to workspace 1" -#~ msgstr "Schakelen naar werkblad 1" +#~ msgid "Benchmark" +#~ msgstr "Benchmark" -#~ msgid "Switch to workspace 2" -#~ msgstr "Schakelen naar werkblad 2" +#~ msgid "Window Title Goes Here" +#~ msgstr "Hier komt de titel" -#~ msgid "Switch to workspace 3" -#~ msgstr "Schakelen naar werkblad 3" +#~ msgid "" +#~ "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and " +#~ "%g seconds wall clock time including X server resources (%g milliseconds " +#~ "per frame)\n" +#~ msgstr "" +#~ "%d frames getekend in %g seconden voor client (%g milliseconden per " +#~ "frame) en %g seconden op wandklok inclusief X serverbronnen (%g " +#~ "milliseconden per frame)\n" -#~ msgid "Switch to workspace 4" -#~ msgstr "Schakelen naar werkblad 4" +#~ msgid "position expression test returned TRUE but set error" +#~ msgstr "positie-expressietest gaf WAAR terug, maar gaf wel een fout" -#~ msgid "Switch to workspace 5" -#~ msgstr "Schakelen naar werkblad 5" +#~ msgid "position expression test returned FALSE but didn't set error" +#~ msgstr "positie-expressietest gaf ONWAAR terug, maar gaf geen fout" -#~ msgid "Switch to workspace 6" -#~ msgstr "Schakelen naar werkblad 6" +#~ msgid "Error was expected but none given" +#~ msgstr "Fout verwacht maar niet ontvangen" -#~ msgid "Switch to workspace 7" -#~ msgstr "Schakelen naar werkblad 7" +#~ msgid "Error %d was expected but %d given" +#~ msgstr "Fout %d verwacht maar %d gekregen" -#~ msgid "Switch to workspace 8" -#~ msgstr "Schakelen naar werkblad 8" +#~ msgid "Error not expected but one was returned: %s" +#~ msgstr "Geen fout verwacht maar kreeg wel een fout: %s" -#~ msgid "Switch to workspace 9" -#~ msgstr "Schakelen naar werkblad 9" +#~ msgid "x value was %d, %d was expected" +#~ msgstr "x-waarde is %d, %d verwacht" -#~ msgid "Switch to workspace 10" -#~ msgstr "Schakelen naar werkblad 10" +#~ msgid "y value was %d, %d was expected" +#~ msgstr "y-waarde is %d, %d verwacht" -#~ msgid "Switch to workspace 11" -#~ msgstr "Schakelen naar werkblad 11" +#~ msgid "" +#~ "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" +#~ msgstr "" +#~ "%d coördinatenexpressies verwerkt in %g seconden (gemiddelde van %g " +#~ "seconden)\n" -#~ msgid "Switch to workspace 12" -#~ msgstr "Schakelen naar werkblad 12" +#, fuzzy +#~ msgid "Minimize window" +#~ msgstr "Venster minimaliseren" #~ msgid "Switch to workspace on the left of the current workspace" #~ msgstr "Schakelen naar werkblad links van het huidige werkblad" @@ -1699,54 +1752,12 @@ msgstr "" #~ msgid "Run a terminal" #~ msgstr "Een terminal opstarten" -#~ msgid "Activate the window menu" -#~ msgstr "Venstermenu activeren" - -#~ msgid "Toggle fullscreen mode" -#~ msgstr "Volledig scherm-modus omschakelen" - -#~ msgid "Toggle maximization state" -#~ msgstr "Maximalisatie in- of uitschakelen" - #~ msgid "Toggle whether a window will always be visible over other windows" #~ msgstr "‘Altijd bovenop’-instelling omschakelen" -#~ msgid "Maximize window" -#~ msgstr "Venster maximaliseren" - -#~ msgid "Restore window" -#~ msgstr "Venster herstellen" - -#~ msgid "Toggle shaded state" -#~ msgstr "Oprollen in- of uitschakelen" - -#~ msgid "Minimize window" -#~ msgstr "Venster minimaliseren" - -#~ msgid "Close window" -#~ msgstr "Venster sluiten" - -#~ msgid "Move window" -#~ msgstr "Venster verplaatsen" - -#~ msgid "Resize window" -#~ msgstr "Vensterafmetingen veranderen" - #~ msgid "Toggle whether window is on all workspaces or just one" #~ msgstr "‘Venster is op alle werkbladen zichtbaar’ omschakelen" -#~ msgid "Move window to workspace 1" -#~ msgstr "Venster verplaatsen naar werkblad 1" - -#~ msgid "Move window to workspace 2" -#~ msgstr "Venster verplaatsen naar werkblad 2" - -#~ msgid "Move window to workspace 3" -#~ msgstr "Venster verplaatsen naar werkblad 3" - -#~ msgid "Move window to workspace 4" -#~ msgstr "Venster verplaatsen naar werkblad 4" - #~ msgid "Move window to workspace 5" #~ msgstr "Venster verplaatsen naar werkblad 5" @@ -1771,35 +1782,11 @@ msgstr "" #~ msgid "Move window to workspace 12" #~ msgstr "Venster verplaatsen naar werkblad 12" -#~ msgid "Move window one workspace to the left" -#~ msgstr "Venster één werkblad naar links verplaatsen" - -#~ msgid "Move window one workspace to the right" -#~ msgstr "Venster één werkblad naar rechts verplaatsen" - -#~ msgid "Move window one workspace up" -#~ msgstr "Venster één werkblad naar boven verplaatsen" - -#~ msgid "Move window one workspace down" -#~ msgstr "Venster één werkblad naar beneden verplaatsen" - #~ msgid "Raise window if it's covered by another window, otherwise lower it" #~ msgstr "" #~ "Venster naar boven halen indien overlapt door een ander venster, anders " #~ "naar beneden halen" -#~ msgid "Raise window above other windows" -#~ msgstr "Venster voor andere vensters brengen" - -#~ msgid "Lower window below other windows" -#~ msgstr "Venster achter andere vensters brengen" - -#~ msgid "Maximize window vertically" -#~ msgstr "Een venster verticaal maximaliseren" - -#~ msgid "Maximize window horizontally" -#~ msgstr "Een venster horizontaal maximaliseren" - #~ msgid "Move window to north-west (top left) corner" #~ msgstr "Venster verplaatsen naar de noordwest-hoek (linksboven)" diff --git a/po/nn.po b/po/nn.po index b43e9a9ba..d91808a35 100644 --- a/po/nn.po +++ b/po/nn.po @@ -11,6 +11,7 @@ msgstr "" "PO-Revision-Date: 2009-06-16 09:54-0400\n" "Last-Translator: Eskild Hustvedt <eskildh@gnome.org>\n" "Language-Team: Norwegian Nynorsk <i18n-no@lister.ping.uio.no>\n" +"Language: nn\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" diff --git a/po/oc.po b/po/oc.po index 916c9b9b2..92539f432 100644 --- a/po/oc.po +++ b/po/oc.po @@ -1,3038 +1,623 @@ -# Translation of oc.po to Occitan -# Occitan translation of metacity. -# Copyright (C) 2002-2006, 2007 Free Software Foundation, Inc. +# Occitan translation of mutter. +# Copyright (C) 2002-2015 Free Software Foundation, Inc. # This file is distributed under the same license as the metacity package. -# # Yannig Marchegay (Kokoyaya) <yannig@marchegay.org>, 2006-2008 +# Cédric Valmary (totenoc.eu) <cvalmary@yahoo.fr>, 2016. msgid "" msgstr "" -"Project-Id-Version: oc\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-06-09 15:21+0200\n" -"PO-Revision-Date: 2008-06-11 13:33+0200\n" -"Last-Translator: Yannig Marchegay (Kokoyaya) <yannig@marchegay.org>\n" -"Language-Team: Occitan <ubuntu-l10n-oci@lists.ubuntu.com>\n" +"Project-Id-Version: mutter master\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=mutter&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2016-05-20 13:48+0000\n" +"PO-Revision-Date: 2016-05-08 18:48+0200\n" +"Last-Translator: Cédric Valmary (totenoc.eu) <cvalmary@yahoo.fr>\n" +"Language-Team: Tot En Òc\n" +"Language: oc\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n > 1);" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Virtaal 0.7.1\n" +"X-Project-Style: gnome\n" -#: ../src/50-metacity-desktop-key.xml.in.h:1 -msgid "Desktop" -msgstr "Burèu" +#: ../data/50-mutter-navigation.xml.in.h:1 +msgid "Navigation" +msgstr "Navigacion" -#: ../src/50-metacity-key.xml.in.h:1 -msgid "Window Management" -msgstr "Gestion de las fenèstras" - -#: ../src/core/core.c:206 -#, c-format -msgid "Unknown window information request: %d" -msgstr "" - -#: ../src/core/delete.c:70 ../src/core/delete.c:97 -#: ../src/ui/metacity-dialog.c:50 ../src/ui/theme-parser.c:481 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "Impossible d'analizar '%s' coma entièr" - -#: ../src/core/delete.c:77 ../src/core/delete.c:104 -#: ../src/ui/metacity-dialog.c:57 ../src/ui/theme-parser.c:490 -#: ../src/ui/theme-parser.c:545 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "" - -#: ../src/core/delete.c:135 -#, c-format -msgid "Failed to parse message \"%s\" from dialog process\n" -msgstr "" - -#: ../src/core/delete.c:253 -#, c-format -msgid "Error reading from dialog display process: %s\n" -msgstr "" - -#: ../src/core/delete.c:336 -#, c-format -msgid "" -"Error launching metacity-dialog to ask about killing an application: %s\n" -msgstr "" - -#: ../src/core/delete.c:445 -#, c-format -msgid "Failed to get hostname: %s\n" -msgstr "Impossible d'obténer lo nom d'òste : %s\n" - -#: ../src/core/display.c:256 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "" - -#: ../src/core/display.c:334 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "" - -#: ../src/core/errors.c:272 -#, c-format -msgid "" -"Lost connection to the display '%s';\n" -"most likely the X server was shut down or you killed/destroyed\n" -"the window manager.\n" -msgstr "" - -#: ../src/core/errors.c:279 -#, c-format -msgid "Fatal IO error %d (%s) on display '%s'.\n" -msgstr "" - -#: ../src/core/keybindings.c:1090 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "" - -#: ../src/core/keybindings.c:2722 -#, c-format -msgid "Error launching metacity-dialog to print an error about a command: %s\n" -msgstr "" - -#: ../src/core/keybindings.c:2827 -#, c-format -msgid "No command %d has been defined.\n" -msgstr "Pas cap de comanda %d definida.\n" - -#: ../src/core/keybindings.c:3855 -#, c-format -msgid "No terminal command has been defined.\n" -msgstr "Pas cap de comanda de terminal definida.\n" - -#: ../src/core/main.c:115 -#, c-format -msgid "" -"metacity %s\n" -"Copyright (C) 2001-2008 Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" - -#: ../src/core/main.c:242 -msgid "Disable connection to session manager" -msgstr "Desactiva la connexion amb lo gestionari de sessions" - -#: ../src/core/main.c:248 -msgid "Replace the running window manager with Metacity" -msgstr "Remplaçar lo gestionari de fenèstras actiu per Metacity" - -#: ../src/core/main.c:254 -msgid "Specify session management ID" -msgstr "Especifica l'ID de gestion de session" - -#: ../src/core/main.c:259 -msgid "X Display to use" -msgstr "" - -#: ../src/core/main.c:265 -msgid "Initialize session from savefile" -msgstr "" - -#: ../src/core/main.c:271 -msgid "Print version" -msgstr "Visualizar la version" - -#: ../src/core/main.c:277 -msgid "Make X calls synchronous" -msgstr "" - -#: ../src/core/main.c:428 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "" - -#: ../src/core/main.c:444 -#, c-format -msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "" - -#: ../src/core/main.c:500 -#, c-format -msgid "Failed to restart: %s\n" -msgstr "Impossible de tornar aviar : %s\n" - -#. -#. * We found it, but it was invalid. Complain. -#. * -#. * FIXME: This replicates the original behaviour, but in the future -#. * we might consider reverting invalid keys to their original values. -#. * (We know the old value, so we can look up a suitable string in -#. * the symtab.) -#. -#: ../src/core/prefs.c:450 ../src/core/prefs.c:564 -#, c-format -msgid "GConf key '%s' is set to an invalid value\n" -msgstr "" - -#: ../src/core/prefs.c:537 ../src/core/prefs.c:611 ../src/core/prefs.c:659 -#: ../src/core/prefs.c:978 ../src/core/prefs.c:996 ../src/core/prefs.c:1012 -#: ../src/core/prefs.c:1031 ../src/core/prefs.c:1047 ../src/core/prefs.c:1064 -#: ../src/core/prefs.c:1081 ../src/core/prefs.c:1097 ../src/core/prefs.c:1113 -#, c-format -msgid "GConf key \"%s\" is set to an invalid type\n" -msgstr "" - -#: ../src/core/prefs.c:873 -#, c-format -msgid "Type of %s was not integer" -msgstr "" - -#: ../src/core/prefs.c:1182 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" - -#: ../src/core/prefs.c:1237 -#, c-format -msgid "" -"%d stored in GConf key %s is not a reasonable cursor_size; must be in the " -"range 1..128\n" -msgstr "" - -#: ../src/core/prefs.c:1263 -#, c-format -msgid "Could not parse font description \"%s\" from GConf key %s\n" -msgstr "" - -#: ../src/core/prefs.c:1323 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" - -#: ../src/core/prefs.c:1602 -#, c-format -msgid "" -"%d stored in GConf key %s is not a reasonable number of workspaces, current " -"maximum is %d\n" -msgstr "" - -#: ../src/core/prefs.c:1646 -#, c-format -msgid "%d stored in GConf key %s is out of range 0 to %d\n" -msgstr "" - -#: ../src/core/prefs.c:1777 -#, c-format -msgid "Error setting number of workspaces to %d: %s\n" -msgstr "" - -#: ../src/core/prefs.c:2142 ../src/core/prefs.c:2654 -#, c-format -msgid "Workspace %d" -msgstr "Espaci de trabalh %d" - -#: ../src/core/prefs.c:2172 ../src/core/prefs.c:2345 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "" - -#: ../src/core/prefs.c:2735 -#, c-format -msgid "Error setting name for workspace %d to \"%s\": %s\n" -msgstr "" - -#: ../src/core/screen.c:350 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "" - -#: ../src/core/screen.c:366 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" - -#: ../src/core/screen.c:393 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "" - -#: ../src/core/screen.c:451 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "" - -#: ../src/core/screen.c:661 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "" - -#: ../src/core/session.c:837 ../src/core/session.c:844 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Impossible de crear lo repertòri '%s' : %s\n" - -#: ../src/core/session.c:854 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "" - -#: ../src/core/session.c:995 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Error al moment d'escriure lo fichièr de session '%s' : %s\n" - -#: ../src/core/session.c:1000 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "" - -#. oh, just give up -#: ../src/core/session.c:1093 -#, c-format -msgid "Failed to read saved session file %s: %s\n" -msgstr "" - -#: ../src/core/session.c:1132 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "" - -#: ../src/core/session.c:1181 -#, c-format -msgid "<metacity_session> attribute seen but we already have the session ID" -msgstr "" - -#: ../src/core/session.c:1194 -#, c-format -msgid "Unknown attribute %s on <metacity_session> element" -msgstr "" - -#: ../src/core/session.c:1211 -#, c-format -msgid "nested <window> tag" -msgstr "" - -#: ../src/core/session.c:1269 ../src/core/session.c:1301 -#, c-format -msgid "Unknown attribute %s on <window> element" -msgstr "" - -#: ../src/core/session.c:1373 -#, c-format -msgid "Unknown attribute %s on <maximized> element" -msgstr "" - -#: ../src/core/session.c:1433 -#, c-format -msgid "Unknown attribute %s on <geometry> element" -msgstr "" - -#: ../src/core/session.c:1453 -#, c-format -msgid "Unknown element %s" -msgstr "Element %s desconegut" - -#: ../src/core/session.c:1879 -#, c-format -msgid "" -"Error launching metacity-dialog to warn about apps that don't support " -"session management: %s\n" -msgstr "" - -#: ../src/core/util.c:101 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "" - -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "" - -#: ../src/core/util.c:117 -#, c-format -msgid "Opened log file %s\n" -msgstr "" - -#: ../src/core/util.c:136 ../src/tools/metacity-message.c:176 -#, c-format -msgid "Metacity was compiled without support for verbose mode\n" -msgstr "" - -#: ../src/core/util.c:236 -msgid "Window manager: " -msgstr "Gestionari de fenèstras : " - -#: ../src/core/util.c:388 -msgid "Bug in window manager: " -msgstr "Anomalia dins lo gestionari de fenèstras : " - -#: ../src/core/util.c:421 -msgid "Window manager warning: " -msgstr "Alèrta del gestionari de fenèstras : " - -#: ../src/core/util.c:449 -msgid "Window manager error: " -msgstr "Error de gestionari de fenèstras : " - -#: ../src/core/window-props.c:195 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "" - -#: ../src/core/window-props.c:327 -#, c-format -msgid "%s (on %s)" -msgstr "%s (sus %s)" - -#: ../src/core/window-props.c:1409 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "" - -#. first time through -#: ../src/core/window.c:5674 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:6239 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %" -"d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" - -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" - -#: ../src/core/xprops.c:401 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "" - -#: ../src/core/xprops.c:484 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" - -#: ../src/metacity.desktop.in.h:1 -msgid "Metacity" -msgstr "Metacity" - -#: ../src/metacity.schemas.in.h:1 -msgid "(Not implemented) Navigation works in terms of applications not windows" -msgstr "" - -#: ../src/metacity.schemas.in.h:2 -msgid "" -"A font description string describing a font for window titlebars. The size " -"from the description will only be used if the titlebar_font_size option is " -"set to 0. Also, this option is disabled if the titlebar_uses_desktop_font " -"option is set to true." -msgstr "" - -#: ../src/metacity.schemas.in.h:3 -msgid "Action on title bar double-click" -msgstr "Accion quand doble-clicatz sus la barra de títol" - -#: ../src/metacity.schemas.in.h:4 -msgid "Action on title bar middle-click" -msgstr "" - -#: ../src/metacity.schemas.in.h:5 -msgid "Action on title bar right-click" -msgstr "" - -#: ../src/metacity.schemas.in.h:6 -msgid "Activate window menu" -msgstr "Activar lo menut fenèstra" - -#: ../src/metacity.schemas.in.h:7 -msgid "Arrangement of buttons on the titlebar" -msgstr "" - -#: ../src/metacity.schemas.in.h:8 -msgid "" -"Arrangement of buttons on the titlebar. The value should be a string, such " -"as \"menu:minimize,maximize,spacer,close\"; the colon separates the left " -"corner of the window from the right corner, and the button names are comma-" -"separated. Duplicate buttons are not allowed. Unknown button names are " -"silently ignored so that buttons can be added in future metacity versions " -"without breaking older versions. A special spacer tag can be used to insert " -"some space between two adjacent buttons." -msgstr "" - -#: ../src/metacity.schemas.in.h:9 -msgid "Automatically raises the focused window" -msgstr "" - -#: ../src/metacity.schemas.in.h:10 -msgid "" -"Clicking a window while holding down this modifier key will move the window " -"(left click), resize the window (middle click), or show the window menu " -"(right click). Modifier is expressed as \"<Alt>\" or \"<Super>\" " -"for example." -msgstr "" - -#: ../src/metacity.schemas.in.h:11 -msgid "Close window" -msgstr "Tampar la fenèstra" - -#: ../src/metacity.schemas.in.h:12 -msgid "Commands to run in response to keybindings" -msgstr "" - -#: ../src/metacity.schemas.in.h:13 -msgid "Compositing Manager" -msgstr "" - -#: ../src/metacity.schemas.in.h:14 -msgid "Control how new windows get focus" -msgstr "" - -#: ../src/metacity.schemas.in.h:15 -msgid "Current theme" -msgstr "Tèma actiu" - -#: ../src/metacity.schemas.in.h:16 -msgid "Delay in milliseconds for the auto raise option" -msgstr "" - -#: ../src/metacity.schemas.in.h:17 -msgid "Determines whether Metacity is a compositing manager." -msgstr "" - -#: ../src/metacity.schemas.in.h:18 -msgid "" -"Determines whether applications or the system can generate audible 'beeps'; " -"may be used in conjunction with 'visual bell' to allow silent 'beeps'." -msgstr "" - -#: ../src/metacity.schemas.in.h:19 -msgid "Disable misfeatures that are required by old or broken applications" -msgstr "" - -#: ../src/metacity.schemas.in.h:20 -msgid "Enable Visual Bell" -msgstr "Activar la lo sonadís visual" - -#: ../src/metacity.schemas.in.h:21 -msgid "Hide all windows and focus desktop" -msgstr "" - -#: ../src/metacity.schemas.in.h:22 -msgid "" -"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " -"the focused window will be automatically raised after a delay specified by " -"the auto_raise_delay key. This is not related to clicking on a window to " -"raise it, nor to entering a window during drag-and-drop." -msgstr "" - -#: ../src/metacity.schemas.in.h:23 -msgid "" -"If true, ignore the titlebar_font option, and use the standard application " -"font for window titles." -msgstr "" - -#: ../src/metacity.schemas.in.h:24 -msgid "" -"If true, metacity will give the user less feedback by using wireframes, " -"avoiding animations, or other means. This is a significant reduction in " -"usability for many users, but may allow legacy applications to continue " -"working, and may also be a useful tradeoff for terminal servers. However, " -"the wireframe feature is disabled when accessibility is on." -msgstr "" - -#: ../src/metacity.schemas.in.h:25 -msgid "" -"If true, then Metacity works in terms of applications rather than windows. " -"The concept is a bit abstract, but in general an application-based setup is " -"more like the Mac and less like Windows. When you focus a window in " -"application-based mode, all the windows in the application will be raised. " -"Also, in application-based mode, focus clicks are not passed through to " -"windows in other applications. Application-based mode is, however, largely " -"unimplemented at the moment." -msgstr "" - -#: ../src/metacity.schemas.in.h:26 -msgid "If true, trade off usability for less resource usage" -msgstr "" - -#: ../src/metacity.schemas.in.h:27 -msgid "Lower window below other windows" -msgstr "" - -#: ../src/metacity.schemas.in.h:28 -msgid "" -"Many actions (e.g. clicking in the client area, moving or resizing the " -"window) normally raise the window as a side-effect. Setting this option to " -"false, which is strongly discouraged, will decouple raising from other user " -"actions, and ignore raise requests generated by applications. See http://" -"bugzilla.gnome.org/show_bug.cgi?id=445447#c6." -msgstr "" - -#: ../src/metacity.schemas.in.h:29 -msgid "Maximize window" -msgstr "" - -#: ../src/metacity.schemas.in.h:30 -msgid "Maximize window horizontally" -msgstr "" - -#: ../src/metacity.schemas.in.h:31 -msgid "Maximize window vertically" -msgstr "" - -#: ../src/metacity.schemas.in.h:32 -msgid "Minimize window" -msgstr "" - -#: ../src/metacity.schemas.in.h:33 -msgid "Modifier to use for modified window click actions" -msgstr "" - -#: ../src/metacity.schemas.in.h:34 -msgid "Move backward between panels and the desktop immediately" -msgstr "" - -#: ../src/metacity.schemas.in.h:35 -msgid "Move backwards between panels and the desktop with popup" -msgstr "" - -#: ../src/metacity.schemas.in.h:36 -msgid "Move backwards between windows immediately" -msgstr "" - -#: ../src/metacity.schemas.in.h:37 -msgid "Move backwards between windows of an application immediately" -msgstr "" - -#: ../src/metacity.schemas.in.h:38 -msgid "Move backwards between windows of an application with popup" -msgstr "" - -#: ../src/metacity.schemas.in.h:39 -msgid "Move between panels and the desktop immediately" -msgstr "" - -#: ../src/metacity.schemas.in.h:40 -msgid "Move between panels and the desktop with popup" -msgstr "" - -#: ../src/metacity.schemas.in.h:41 -msgid "Move between windows immediately" -msgstr "" - -#: ../src/metacity.schemas.in.h:42 -msgid "Move between windows of an application immediately" -msgstr "" - -#: ../src/metacity.schemas.in.h:43 -msgid "Move between windows of an application with popup" -msgstr "" - -#: ../src/metacity.schemas.in.h:44 -msgid "Move between windows with popup" -msgstr "Se desplaçar entre las fenèstras per un menut" - -#: ../src/metacity.schemas.in.h:45 -msgid "Move focus backwards between windows using popup display" -msgstr "" - -#: ../src/metacity.schemas.in.h:46 -msgid "Move window" -msgstr "Desplaçar la fenèstra" - -#: ../src/metacity.schemas.in.h:47 -msgid "Move window one workspace down" -msgstr "" - -#: ../src/metacity.schemas.in.h:48 -msgid "Move window one workspace to the left" -msgstr "" - -#: ../src/metacity.schemas.in.h:49 -msgid "Move window one workspace to the right" -msgstr "" - -#: ../src/metacity.schemas.in.h:50 -msgid "Move window one workspace up" -msgstr "" - -#: ../src/metacity.schemas.in.h:51 -msgid "Move window to east side of screen" -msgstr "" - -#: ../src/metacity.schemas.in.h:52 -msgid "Move window to north side of screen" -msgstr "" - -#: ../src/metacity.schemas.in.h:53 -msgid "Move window to north-east corner" -msgstr "" - -#: ../src/metacity.schemas.in.h:54 -msgid "Move window to north-west corner" -msgstr "" - -#: ../src/metacity.schemas.in.h:55 -msgid "Move window to south side of screen" -msgstr "" - -#: ../src/metacity.schemas.in.h:56 -msgid "Move window to south-east corner" -msgstr "" - -#: ../src/metacity.schemas.in.h:57 -msgid "Move window to south-west corner" -msgstr "" - -#: ../src/metacity.schemas.in.h:58 -msgid "Move window to west side of screen" -msgstr "" - -#: ../src/metacity.schemas.in.h:59 -msgid "Move window to workspace 1" -msgstr "Desplaçar la fenèstra al espaci de trabalh 1" - -#: ../src/metacity.schemas.in.h:60 -msgid "Move window to workspace 10" -msgstr "Desplaçar la fenèstra al espaci de trabalh 10" - -#: ../src/metacity.schemas.in.h:61 -msgid "Move window to workspace 11" -msgstr "Desplaçar la fenèstra al espaci de trabalh 11" - -#: ../src/metacity.schemas.in.h:62 -msgid "Move window to workspace 12" -msgstr "Desplaçar la fenèstra cap al espaci de trabalh 12" - -#: ../src/metacity.schemas.in.h:63 -msgid "Move window to workspace 2" -msgstr "Desplaçar la fenèstra cap al espaci de trabalh 2" - -#: ../src/metacity.schemas.in.h:64 -msgid "Move window to workspace 3" -msgstr "Desplaçar la fenèstra cap al espaci de trabalh 3" - -#: ../src/metacity.schemas.in.h:65 -msgid "Move window to workspace 4" -msgstr "Desplaçar la fenèstra al espaci de trabalh 4" - -#: ../src/metacity.schemas.in.h:66 -msgid "Move window to workspace 5" -msgstr "Desplaçar la fenèstra al espaci de trabalh 5" - -#: ../src/metacity.schemas.in.h:67 -msgid "Move window to workspace 6" -msgstr "Desplaçar la fenèstra al espaci de trabalh 6" - -#: ../src/metacity.schemas.in.h:68 -msgid "Move window to workspace 7" -msgstr "Desplaçar la fenèstra al espaci de trabalh 7" - -#: ../src/metacity.schemas.in.h:69 -msgid "Move window to workspace 8" -msgstr "Desplaçar la fenèstra al espaci de trabalh 8" - -#: ../src/metacity.schemas.in.h:70 -msgid "Move window to workspace 9" -msgstr "Desplaçar la fenèstra al espaci de trabalh 9" - -#: ../src/metacity.schemas.in.h:71 -msgid "Name of workspace" -msgstr "Nom del espaci de trabalh" - -#: ../src/metacity.schemas.in.h:72 -msgid "Number of workspaces" -msgstr "Nombre d'espacis de trabalh" - -#: ../src/metacity.schemas.in.h:73 -msgid "" -"Number of workspaces. Must be more than zero, and has a fixed maximum to " -"prevent making the desktop unusable by accidentally asking for too many " -"workspaces." -msgstr "" - -#: ../src/metacity.schemas.in.h:74 -msgid "Raise obscured window, otherwise lower" -msgstr "" - -#: ../src/metacity.schemas.in.h:75 -msgid "Raise window above other windows" -msgstr "" - -#: ../src/metacity.schemas.in.h:76 -msgid "Resize window" -msgstr "" - -#: ../src/metacity.schemas.in.h:77 -msgid "Run a defined command" -msgstr "" - -#: ../src/metacity.schemas.in.h:78 -msgid "Run a terminal" -msgstr "Executar un terminal" - -#: ../src/metacity.schemas.in.h:79 -msgid "Show the panel menu" -msgstr "Visualizar lo menut del panèl" - -#: ../src/metacity.schemas.in.h:80 -msgid "Show the panel run application dialog" -msgstr "" - -#: ../src/metacity.schemas.in.h:81 -msgid "" -"Some applications disregard specifications in ways that result in window " -"manager misfeatures. This option puts Metacity in a rigorously correct mode, " -"which gives a more consistent user interface, provided one does not need to " -"run any misbehaving applications." -msgstr "" - -#: ../src/metacity.schemas.in.h:82 -msgid "Switch to workspace 1" -msgstr "Anar al espaci de trabalh 1" - -#: ../src/metacity.schemas.in.h:83 -msgid "Switch to workspace 10" -msgstr "Anar al espaci de trabalh 10" - -#: ../src/metacity.schemas.in.h:84 -msgid "Switch to workspace 11" -msgstr "Anar al espaci de trabalh 11" - -#: ../src/metacity.schemas.in.h:85 -msgid "Switch to workspace 12" -msgstr "Anar al espaci de trabalh 12" - -#: ../src/metacity.schemas.in.h:86 -msgid "Switch to workspace 2" -msgstr "Anar al espaci de trabalh 2" - -#: ../src/metacity.schemas.in.h:87 -msgid "Switch to workspace 3" -msgstr "Anar al espaci de trabalh 3" - -#: ../src/metacity.schemas.in.h:88 -msgid "Switch to workspace 4" -msgstr "Anar al espaci de trabalh 4" - -#: ../src/metacity.schemas.in.h:89 -msgid "Switch to workspace 5" -msgstr "Anar al espaci de trabalh 5" - -#: ../src/metacity.schemas.in.h:90 -msgid "Switch to workspace 6" -msgstr "Anar al espaci de trabalh 6" - -#: ../src/metacity.schemas.in.h:91 -msgid "Switch to workspace 7" -msgstr "Anar al espaci de trabalh 7" - -#: ../src/metacity.schemas.in.h:92 -msgid "Switch to workspace 8" -msgstr "Anar al espaci de trabalh 8" - -#: ../src/metacity.schemas.in.h:93 -msgid "Switch to workspace 9" -msgstr "Anar al espaci de trabalh 9" - -#: ../src/metacity.schemas.in.h:94 -msgid "Switch to workspace above this one" -msgstr "Passar a l'espaci de trabalh ennaut d'aqueste" - -#: ../src/metacity.schemas.in.h:95 -msgid "Switch to workspace below this one" -msgstr "Passar a l'espaci de trabalh enbàs d'aqueste" - -#: ../src/metacity.schemas.in.h:96 -msgid "Switch to workspace on the left" -msgstr "Passar a l'espaci de trabalh a l'esquèrra" - -#: ../src/metacity.schemas.in.h:97 -msgid "Switch to workspace on the right" -msgstr "Passar a l'espaci de trabalh a la drecha" - -#: ../src/metacity.schemas.in.h:98 -msgid "System Bell is Audible" -msgstr "Podètz ausir lo bip sistèma" - -#: ../src/metacity.schemas.in.h:99 -msgid "Take a screenshot" -msgstr "" - -#: ../src/metacity.schemas.in.h:100 -msgid "Take a screenshot of a window" -msgstr "" - -#: ../src/metacity.schemas.in.h:101 -msgid "" -"Tells Metacity how to implement the visual indication that the system bell " -"or another application 'bell' indicator has been rung. Currently there are " -"two valid values, \"fullscreen\", which causes a fullscreen white-black " -"flash, and \"frame_flash\" which causes the titlebar of the application " -"which sent the bell signal to flash. If the application which sent the bell " -"is unknown (as is usually the case for the default \"system beep\"), the " -"currently focused window's titlebar is flashed." -msgstr "" - -#: ../src/metacity.schemas.in.h:102 -msgid "" -"The /apps/metacity/global_keybindings/run_command_N keys define keybindings " -"that correspond to these commands. Pressing the keybinding for run_command_N " -"will execute command_N." -msgstr "" - -#: ../src/metacity.schemas.in.h:103 -msgid "" -"The /apps/metacity/global_keybindings/run_command_screenshot key defines a " -"keybinding which causes the command specified by this setting to be invoked." -msgstr "" - -#: ../src/metacity.schemas.in.h:104 -msgid "" -"The /apps/metacity/global_keybindings/run_command_window_screenshot key " -"defines a keybinding which causes the command specified by this setting to " -"be invoked." -msgstr "" - -#: ../src/metacity.schemas.in.h:105 -msgid "" -"The keybinding that runs the correspondingly-numbered command in /apps/" -"metacity/keybinding_commands The format looks like \"<Control>a\" or " -"\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -"lower or upper case, and also abbreviations such as \"<Ctl>\" and " -"\"<Ctrl>\". If you set the option to the special string \"disabled\", " -"then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:106 -msgid "" -"The keybinding that switches to the workspace above the current workspace. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:107 -msgid "" -"The keybinding that switches to the workspace below the current workspace. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:108 -msgid "" -"The keybinding that switches to the workspace on the left of the current " -"workspace. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:109 -msgid "" -"The keybinding that switches to the workspace on the right of the current " -"workspace. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:110 -msgid "" -"The keybinding that switches to workspace 1. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:111 -msgid "" -"The keybinding that switches to workspace 10. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:112 -msgid "" -"The keybinding that switches to workspace 11. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:113 -msgid "" -"The keybinding that switches to workspace 12. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:114 -msgid "" -"The keybinding that switches to workspace 2. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:115 -msgid "" -"The keybinding that switches to workspace 3. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:116 -msgid "" -"The keybinding that switches to workspace 4. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:117 -msgid "" -"The keybinding that switches to workspace 5. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:118 -msgid "" -"The keybinding that switches to workspace 6. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:119 -msgid "" -"The keybinding that switches to workspace 7. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:120 -msgid "" -"The keybinding that switches to workspace 8. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:121 -msgid "" -"The keybinding that switches to workspace 9. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:122 -msgid "" -"The keybinding used to activate the window menu. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:123 -msgid "" -"The keybinding used to close a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:124 -msgid "" -"The keybinding used to enter \"move mode\" and begin moving a window using " -"the keyboard. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:125 -msgid "" -"The keybinding used to enter \"resize mode\" and begin resizing a window " -"using the keyboard. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:126 -msgid "" -"The keybinding used to hide all normal windows and set the focus to the " -"desktop background. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:127 -msgid "" -"The keybinding used to maximize a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:128 -msgid "" -"The keybinding used to minimize a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:129 -msgid "" -"The keybinding used to move a window one workspace down. The format looks " -"like \"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -"fairly liberal and allows lower or upper case, and also abbreviations such " -"as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -"special string \"disabled\", then there will be no keybinding for this " -"action." -msgstr "" - -#: ../src/metacity.schemas.in.h:130 -msgid "" -"The keybinding used to move a window one workspace to the left. The format " -"looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -"parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:131 -msgid "" -"The keybinding used to move a window one workspace to the right. The format " -"looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -"parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:132 -msgid "" -"The keybinding used to move a window one workspace up. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:133 -msgid "" -"The keybinding used to move a window to workspace 1. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:134 -msgid "" -"The keybinding used to move a window to workspace 10. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:135 -msgid "" -"The keybinding used to move a window to workspace 11. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:136 -msgid "" -"The keybinding used to move a window to workspace 12. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:137 -msgid "" -"The keybinding used to move a window to workspace 2. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:138 -msgid "" -"The keybinding used to move a window to workspace 3. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:139 -msgid "" -"The keybinding used to move a window to workspace 4. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:140 -msgid "" -"The keybinding used to move a window to workspace 5. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:141 -msgid "" -"The keybinding used to move a window to workspace 6. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:142 -msgid "" -"The keybinding used to move a window to workspace 7. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:143 -msgid "" -"The keybinding used to move a window to workspace 8. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:144 -msgid "" -"The keybinding used to move a window to workspace 9. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:145 -msgid "" -"The keybinding used to move focus backwards between panels and the desktop, " -"using a popup window. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:146 -msgid "" -"The keybinding used to move focus backwards between panels and the desktop, " -"without a popup window. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:147 -msgid "" -"The keybinding used to move focus backwards between windows of an " -"application without a popup window. Holding \"shift\" together with this " -"binding makes the direction go forward again. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:148 -msgid "" -"The keybinding used to move focus backwards between windows of an " -"application, using a popup window. Holding \"shift\" together with this " -"binding makes the direction go forward again. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:149 -msgid "" -"The keybinding used to move focus backwards between windows without a popup " -"window. Holding \"shift\" together with this binding makes the direction go " -"forward again. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:150 -msgid "" -"The keybinding used to move focus backwards between windows, using a popup " -"window. Holding \"shift\" together with this binding makes the direction go " -"forward again. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:151 -msgid "" -"The keybinding used to move focus between panels and the desktop, using a " -"popup window. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:152 -msgid "" -"The keybinding used to move focus between panels and the desktop, without a " -"popup window. The format looks like \"<Control>a\" or \"<Shift>" -"<Alt>F1\". The parser is fairly liberal and allows lower or upper " -"case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". " -"If you set the option to the special string \"disabled\", then there will be " -"no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:153 -msgid "" -"The keybinding used to move focus between windows of an application without " -"a popup window. Holding the \"shift\" key while using this binding reverses " -"the direction of movement. The format looks like \"<Control>a\" or " -"\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -"lower or upper case, and also abbreviations such as \"<Ctl>\" and " -"\"<Ctrl>\". If you set the option to the special string \"disabled\", " -"then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:154 -msgid "" -"The keybinding used to move focus between windows of an application, using a " -"popup window. (Traditionally <Alt>F6) Holding the \"shift\" key while " -"using this binding reverses the direction of movement. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:155 -msgid "" -"The keybinding used to move focus between windows without a popup window. " -"(Traditionally <Alt>Escape) Holding the \"shift\" key while using this " -"binding reverses the direction of movement. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:156 -msgid "" -"The keybinding used to move focus between windows, using a popup window. " -"(Traditionally <Alt>Tab) Holding the \"shift\" key while using this " -"binding reverses the direction of movement. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:157 -msgid "" -"The keybinding used to toggle always on top. A window that is always on top " -"will always be visible over other overlapping windows. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:158 -msgid "" -"The keybinding used to toggle fullscreen mode. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:159 -msgid "" -"The keybinding used to toggle maximization. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:160 -msgid "" -"The keybinding used to toggle shaded/unshaded state. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:161 -msgid "" -"The keybinding used to toggle whether the window is on all workspaces or " -"just one. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:162 -msgid "" -"The keybinding used to unmaximize a window. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:163 -msgid "" -"The keybinding which display's the panel's \"Run Application\" dialog box. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:164 -msgid "" -"The keybinding which invokes a terminal. The format looks like \"<" -"Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:165 -msgid "" -"The keybinding which invokes the panel's screenshot utility to take a " -"screenshot of a window. The format looks like \"<Control>a\" or \"<" -"Shift><Alt>F1\". The parser is fairly liberal and allows lower or " -"upper case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -"\". If you set the option to the special string \"disabled\", then there " -"will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:166 -msgid "" -"The keybinding which invokes the panel's screenshot utility. The format " -"looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -"parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:167 -msgid "" -"The keybinding which shows the panel's main menu. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:168 -msgid "The name of a workspace." -msgstr "Lo nom d'un espaci de trabalh." - -#: ../src/metacity.schemas.in.h:169 -msgid "The screenshot command" -msgstr "" - -#: ../src/metacity.schemas.in.h:170 -msgid "" -"The theme determines the appearance of window borders, titlebar, and so " -"forth." -msgstr "" - -#: ../src/metacity.schemas.in.h:171 -msgid "" -"The time delay before raising a window if auto_raise is set to true. The " -"delay is given in thousandths of a second." -msgstr "" - -#: ../src/metacity.schemas.in.h:172 -msgid "" -"The window focus mode indicates how windows are activated. It has three " -"possible values; \"click\" means windows must be clicked in order to focus " -"them, \"sloppy\" means windows are focused when the mouse enters the window, " -"and \"mouse\" means windows are focused when the mouse enters the window and " -"unfocused when the mouse leaves the window." -msgstr "" - -#: ../src/metacity.schemas.in.h:173 -msgid "The window screenshot command" -msgstr "" - -#: ../src/metacity.schemas.in.h:174 -msgid "" -"This keybinding changes whether a window is above or below other windows. If " -"the window is covered by another one, it raises the window above all others, " -"and if the window is already fully visible, it lowers it below all others. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:175 -msgid "" -"This keybinding lowers a window below other windows. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:176 -msgid "" -"This keybinding moves a window against the north (top) side of the screen. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:177 -msgid "" -"This keybinding moves a window into the east (right) side of the screen. The " -"format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:178 -msgid "" -"This keybinding moves a window into the north-east (top right) corner of the " -"screen. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:179 -msgid "" -"This keybinding moves a window into the north-west (top left) corner of the " -"screen. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:180 -msgid "" -"This keybinding moves a window into the south (bottom) side of the screen. " -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -"\". The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:181 -msgid "" -"This keybinding moves a window into the south-east (bottom right) corner of " -"the screen. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:182 -msgid "" -"This keybinding moves a window into the south-west (bottom left) corner of " -"the screen. The format looks like \"<Control>a\" or \"<Shift><" -"Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -"and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -"set the option to the special string \"disabled\", then there will be no " -"keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:183 -msgid "" -"This keybinding moves a window into the west (left) side of the screen. The " -"format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:184 -msgid "" -"This keybinding raises the window above other windows. The format looks like " -"\"<Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -"liberal and allows lower or upper case, and also abbreviations such as \"<" -"Ctl>\" and \"<Ctrl>\". If you set the option to the special string " -"\"disabled\", then there will be no keybinding for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:185 -msgid "" -"This keybinding resizes a window to fill available horizontal space. The " -"format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:186 -msgid "" -"This keybinding resizes a window to fill available vertical space. The " -"format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the " -"option to the special string \"disabled\", then there will be no keybinding " -"for this action." -msgstr "" - -#: ../src/metacity.schemas.in.h:187 -msgid "" -"This option determines the effects of double-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, 'toggle_maximize' which will maximize/unmaximize the window, " -"'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which will " -"maximize/unmaximize the window in that direction only, 'minimize' which will " -"minimize the window, 'shade' which will roll the window up, 'menu' which " -"will display the window menu, 'lower' which will put the window behind all " -"the others, and 'none' which will not do anything." -msgstr "" - -#: ../src/metacity.schemas.in.h:188 -msgid "" -"This option determines the effects of middle-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, 'toggle_maximize' which will maximize/unmaximize the window, " -"'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which will " -"maximize/unmaximize the window in that direction only, 'minimize' which will " -"minimize the window, 'shade' which will roll the window up, 'menu' which " -"will display the window menu, 'lower' which will put the window behind all " -"the others, and 'none' which will not do anything." -msgstr "" - -#: ../src/metacity.schemas.in.h:189 -msgid "" -"This option determines the effects of right-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, 'toggle_maximize' which will maximize/unmaximize the window, " -"'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which will " -"maximize/unmaximize the window in that direction only, 'minimize' which will " -"minimize the window, 'shade' which will roll the window up, 'menu' which " -"will display the window menu, 'lower' which will put the window behind all " -"the others, and 'none' which will not do anything." -msgstr "" - -#: ../src/metacity.schemas.in.h:190 -msgid "" -"This option provides additional control over how newly created windows get " -"focus. It has two possible values; \"smart\" applies the user's normal focus " -"mode, and \"strict\" results in windows started from a terminal not being " -"given focus." -msgstr "" - -#: ../src/metacity.schemas.in.h:191 -msgid "Toggle always on top state" -msgstr "" - -#: ../src/metacity.schemas.in.h:192 -msgid "Toggle fullscreen mode" -msgstr "" - -#: ../src/metacity.schemas.in.h:193 -msgid "Toggle maximization state" -msgstr "" - -#: ../src/metacity.schemas.in.h:194 -msgid "Toggle shaded state" -msgstr "" - -#: ../src/metacity.schemas.in.h:195 -msgid "Toggle window on all workspaces" -msgstr "" - -#: ../src/metacity.schemas.in.h:196 -msgid "" -"Turns on a visual indication when an application or the system issues a " -"'bell' or 'beep'; useful for the hard-of-hearing and for use in noisy " -"environments." -msgstr "" - -#: ../src/metacity.schemas.in.h:197 -msgid "Unmaximize window" -msgstr "" - -#: ../src/metacity.schemas.in.h:198 -msgid "Use standard system font in window titles" -msgstr "" - -#: ../src/metacity.schemas.in.h:199 -msgid "Visual Bell Type" -msgstr "Tipe de sonadís visual" - -#: ../src/metacity.schemas.in.h:200 -msgid "Whether raising should be a side-effect of other user interactions" -msgstr "" - -#: ../src/metacity.schemas.in.h:201 -msgid "Window focus mode" -msgstr "" - -#: ../src/metacity.schemas.in.h:202 -msgid "Window title font" -msgstr "Poliça de títol de las fenèstras" - -#: ../src/ui/frames.c:1077 -msgid "Close Window" -msgstr "Tampar la fenèstra" - -#: ../src/ui/frames.c:1080 -msgid "Window Menu" -msgstr "Menut Fenèstra" - -#: ../src/ui/frames.c:1083 -msgid "Minimize Window" -msgstr "Redusir la fenèstra" - -#: ../src/ui/frames.c:1086 -msgid "Maximize Window" -msgstr "Maximizar la fenèstra" - -#: ../src/ui/frames.c:1089 -msgid "Unmaximize Window" -msgstr "Desmaximizar la fenèstra" - -#: ../src/ui/frames.c:1092 -msgid "Roll Up Window" -msgstr "" - -#: ../src/ui/frames.c:1095 -msgid "Unroll Window" -msgstr "" - -#: ../src/ui/frames.c:1098 -msgid "Keep Window On Top" -msgstr "" - -#: ../src/ui/frames.c:1101 -msgid "Remove Window From Top" -msgstr "" - -#: ../src/ui/frames.c:1104 -msgid "Always On Visible Workspace" -msgstr "Totjorn sul espaci de trabalh visible" - -#: ../src/ui/frames.c:1107 -msgid "Put Window On Only One Workspace" -msgstr "" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:70 -msgid "Mi_nimize" -msgstr "" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:72 -msgid "Ma_ximize" -msgstr "" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:74 -msgid "Unma_ximize" -msgstr "" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:76 -msgid "Roll _Up" -msgstr "" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:78 -msgid "_Unroll" -msgstr "" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:80 -msgid "_Move" -msgstr "_Desplaçar" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:82 -msgid "_Resize" -msgstr "" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:84 -msgid "Move Titlebar On_screen" -msgstr "" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:87 ../src/ui/menu.c:89 -msgid "Always on _Top" -msgstr "" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:91 -msgid "_Always on Visible Workspace" -msgstr "_Totjorn sul espaci de trabalh visible" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:93 -msgid "_Only on This Workspace" -msgstr "_Sonque sus aqueste espaci de trabalh" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:95 -msgid "Move to Workspace _Left" -msgstr "" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:97 -msgid "Move to Workspace R_ight" -msgstr "" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:99 -msgid "Move to Workspace _Up" -msgstr "Desplaçar dins l'espaci de trabalh _superior" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:101 -msgid "Move to Workspace _Down" -msgstr "Desplaçar dins l'espaci de trabalh _inferior" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:105 -msgid "_Close" -msgstr "_Tampar" - -#: ../src/ui/menu.c:203 -#, c-format -msgid "Workspace %d%n" -msgstr "Espaci de trabalh %d%n" - -#: ../src/ui/menu.c:213 -#, c-format -msgid "Workspace 1_0" -msgstr "Espaci de trabalh 1_0" - -#: ../src/ui/menu.c:215 -#, c-format -msgid "Workspace %s%d" -msgstr "Espaci de trabalh %s%d" - -#: ../src/ui/menu.c:395 -msgid "Move to Another _Workspace" -msgstr "Desplaçar cap a un autre _espaci de trabalh" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:105 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:111 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:117 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:123 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:129 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:135 -msgid "Hyper" -msgstr "Iper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:141 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:147 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:153 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:159 -msgid "Mod5" -msgstr "Mod5" - -#: ../src/ui/metacity-dialog.c:90 -#, c-format -msgid "\"%s\" is not responding." -msgstr "\"%s\" respon pas." - -#: ../src/ui/metacity-dialog.c:97 -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "" - -#: ../src/ui/metacity-dialog.c:107 -msgid "_Wait" -msgstr "_Esperar" - -#: ../src/ui/metacity-dialog.c:109 -msgid "_Force Quit" -msgstr "" - -#: ../src/ui/metacity-dialog.c:206 -msgid "Title" -msgstr "Títol" - -#: ../src/ui/metacity-dialog.c:218 -msgid "Class" -msgstr "" - -#: ../src/ui/metacity-dialog.c:244 -msgid "" -"These windows do not support \"save current setup\" and will have to be " -"restarted manually next time you log in." -msgstr "" - -#: ../src/ui/metacity-dialog.c:310 -#, c-format -msgid "" -"There was an error running \"%s\":\n" -"%s." -msgstr "" -"I a aguda una error al moment d'executar \"%s\" :\n" -"%s." - -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" - -#: ../src/ui/theme-parser.c:227 ../src/ui/theme-parser.c:245 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Linha %d caractèr %d : %s" - -#: ../src/ui/theme-parser.c:396 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "" - -#: ../src/ui/theme-parser.c:414 ../src/ui/theme-parser.c:439 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "" - -#: ../src/ui/theme-parser.c:500 -#, c-format -msgid "Integer %ld must be positive" -msgstr "L'entièr %ld deu èsser positiu" - -#: ../src/ui/theme-parser.c:508 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "" - -#: ../src/ui/theme-parser.c:536 ../src/ui/theme-parser.c:652 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "" - -#: ../src/ui/theme-parser.c:567 ../src/ui/theme-parser.c:595 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "" - -#: ../src/ui/theme-parser.c:622 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "L'angle deu èsser entre 0,0 e 360,0. Èra de %g\n" - -#: ../src/ui/theme-parser.c:685 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" - -#: ../src/ui/theme-parser.c:750 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" - -#: ../src/ui/theme-parser.c:795 ../src/ui/theme-parser.c:803 -#: ../src/ui/theme-parser.c:885 ../src/ui/theme-parser.c:982 -#: ../src/ui/theme-parser.c:1024 ../src/ui/theme-parser.c:1135 -#: ../src/ui/theme-parser.c:1185 ../src/ui/theme-parser.c:1193 -#: ../src/ui/theme-parser.c:3093 ../src/ui/theme-parser.c:3184 -#: ../src/ui/theme-parser.c:3191 ../src/ui/theme-parser.c:3198 -#, c-format -msgid "No \"%s\" attribute on <%s> element" -msgstr "" - -#: ../src/ui/theme-parser.c:919 ../src/ui/theme-parser.c:990 -#: ../src/ui/theme-parser.c:1032 ../src/ui/theme-parser.c:1143 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "" - -#: ../src/ui/theme-parser.c:931 ../src/ui/theme-parser.c:1044 -#: ../src/ui/theme-parser.c:1155 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "" - -#: ../src/ui/theme-parser.c:1057 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "" - -#: ../src/ui/theme-parser.c:1070 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "" - -#: ../src/ui/theme-parser.c:1112 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "" - -#: ../src/ui/theme-parser.c:1203 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Tipe desconegut \"%s\" sul element <%s>" - -#: ../src/ui/theme-parser.c:1214 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "" - -#: ../src/ui/theme-parser.c:1222 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "" - -#: ../src/ui/theme-parser.c:1258 -msgid "Theme already has a fallback icon" -msgstr "" - -#: ../src/ui/theme-parser.c:1270 -msgid "Theme already has a fallback mini_icon" -msgstr "" - -#: ../src/ui/theme-parser.c:1283 ../src/ui/theme-parser.c:1347 -#: ../src/ui/theme-parser.c:1636 ../src/ui/theme-parser.c:3285 -#: ../src/ui/theme-parser.c:3339 ../src/ui/theme-parser.c:3511 -#: ../src/ui/theme-parser.c:3727 ../src/ui/theme-parser.c:3765 -#: ../src/ui/theme-parser.c:3803 ../src/ui/theme-parser.c:3841 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:1373 ../src/ui/theme-parser.c:1460 -#: ../src/ui/theme-parser.c:1530 -#, c-format -msgid "No \"name\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:1380 ../src/ui/theme-parser.c:1467 -#, c-format -msgid "No \"value\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:1411 ../src/ui/theme-parser.c:1425 -#: ../src/ui/theme-parser.c:1484 -msgid "" -"Cannot specify both button_width/button_height and aspect ratio for buttons" -msgstr "" - -#: ../src/ui/theme-parser.c:1434 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "Distància \"%s\" desconeguda" - -#: ../src/ui/theme-parser.c:1493 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "" - -#: ../src/ui/theme-parser.c:1537 -#, c-format -msgid "No \"top\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:1544 -#, c-format -msgid "No \"bottom\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:1551 -#, c-format -msgid "No \"left\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:1558 -#, c-format -msgid "No \"right\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:1590 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "La bordadura \"%s\" es desconeguda" - -#: ../src/ui/theme-parser.c:1736 ../src/ui/theme-parser.c:1850 -#: ../src/ui/theme-parser.c:1961 ../src/ui/theme-parser.c:2192 -#: ../src/ui/theme-parser.c:3023 -#, c-format -msgid "No \"color\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:1743 -#, c-format -msgid "No \"x1\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:1750 ../src/ui/theme-parser.c:2864 -#, c-format -msgid "No \"y1\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:1757 -#, c-format -msgid "No \"x2\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:1764 ../src/ui/theme-parser.c:2871 -#, c-format -msgid "No \"y2\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:1857 ../src/ui/theme-parser.c:1968 -#: ../src/ui/theme-parser.c:2117 ../src/ui/theme-parser.c:2199 -#: ../src/ui/theme-parser.c:2306 ../src/ui/theme-parser.c:2408 -#: ../src/ui/theme-parser.c:2630 ../src/ui/theme-parser.c:2758 -#: ../src/ui/theme-parser.c:2857 ../src/ui/theme-parser.c:2934 -#: ../src/ui/theme-parser.c:3030 -#, c-format -msgid "No \"x\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:1864 ../src/ui/theme-parser.c:1975 -#: ../src/ui/theme-parser.c:2124 ../src/ui/theme-parser.c:2206 -#: ../src/ui/theme-parser.c:2313 ../src/ui/theme-parser.c:2415 -#: ../src/ui/theme-parser.c:2637 ../src/ui/theme-parser.c:2765 -#: ../src/ui/theme-parser.c:2941 ../src/ui/theme-parser.c:3037 -#, c-format -msgid "No \"y\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:1871 ../src/ui/theme-parser.c:1982 -#: ../src/ui/theme-parser.c:2131 ../src/ui/theme-parser.c:2213 -#: ../src/ui/theme-parser.c:2320 ../src/ui/theme-parser.c:2422 -#: ../src/ui/theme-parser.c:2644 ../src/ui/theme-parser.c:2772 -#: ../src/ui/theme-parser.c:2948 -#, c-format -msgid "No \"width\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:1878 ../src/ui/theme-parser.c:1989 -#: ../src/ui/theme-parser.c:2138 ../src/ui/theme-parser.c:2220 -#: ../src/ui/theme-parser.c:2327 ../src/ui/theme-parser.c:2429 -#: ../src/ui/theme-parser.c:2651 ../src/ui/theme-parser.c:2779 -#: ../src/ui/theme-parser.c:2955 -#, c-format -msgid "No \"height\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:1998 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:2005 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:2014 -#, c-format -msgid "No \"start_angle\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:2021 -#, c-format -msgid "No \"extent_angle\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:2227 -#, c-format -msgid "No \"alpha\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:2299 -#, c-format -msgid "No \"type\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:2349 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "" - -#: ../src/ui/theme-parser.c:2436 -#, c-format -msgid "No \"filename\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:2461 ../src/ui/theme-parser.c:2980 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "" - -#: ../src/ui/theme-parser.c:2609 ../src/ui/theme-parser.c:2744 -#: ../src/ui/theme-parser.c:2850 -#, c-format -msgid "No \"state\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:2616 ../src/ui/theme-parser.c:2751 -#, c-format -msgid "No \"shadow\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:2623 -#, c-format -msgid "No \"arrow\" attribute on element <%s>" -msgstr "" - -#: ../src/ui/theme-parser.c:2676 ../src/ui/theme-parser.c:2800 -#: ../src/ui/theme-parser.c:2891 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "" - -#: ../src/ui/theme-parser.c:2686 ../src/ui/theme-parser.c:2810 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "" - -#: ../src/ui/theme-parser.c:2696 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "" - -#: ../src/ui/theme-parser.c:3120 ../src/ui/theme-parser.c:3237 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "" - -#: ../src/ui/theme-parser.c:3132 ../src/ui/theme-parser.c:3249 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "" - -#: ../src/ui/theme-parser.c:3314 -#, c-format -msgid "No \"value\" attribute on <%s> element" -msgstr "" - -#: ../src/ui/theme-parser.c:3371 -#, c-format -msgid "No \"position\" attribute on <%s> element" -msgstr "" - -#: ../src/ui/theme-parser.c:3380 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "" - -#: ../src/ui/theme-parser.c:3388 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:2 +msgid "Move window to workspace 1" +msgstr "Desplaçar la fenèstra cap a l'espaci de trabalh 1" -#: ../src/ui/theme-parser.c:3405 ../src/ui/theme-parser.c:3496 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:3 +msgid "Move window to workspace 2" +msgstr "Desplaçar la fenèstra cap a l'espaci de trabalh 2" -#: ../src/ui/theme-parser.c:3433 -#, c-format -msgid "No \"function\" attribute on <%s> element" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:4 +msgid "Move window to workspace 3" +msgstr "Desplaçar la fenèstra cap a l'espaci de trabalh 3" -#: ../src/ui/theme-parser.c:3441 ../src/ui/theme-parser.c:3557 -#, c-format -msgid "No \"state\" attribute on <%s> element" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:5 +msgid "Move window to workspace 4" +msgstr "Desplaçar la fenèstra cap a l'espaci de trabalh 4" -#: ../src/ui/theme-parser.c:3450 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Foncion \"%s\" desconeguda pel boton" +#: ../data/50-mutter-navigation.xml.in.h:6 +msgid "Move window to last workspace" +msgstr "Desplaçar la fenèstra cap al darrièr espaci de trabalh" -#: ../src/ui/theme-parser.c:3459 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:7 +msgid "Move window one workspace to the left" +msgstr "Desplaçar la fenèstra d'un espaci de trabalh cap a esquèrra" -#: ../src/ui/theme-parser.c:3471 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Estat \"%s\" desconegut pel boton" +#: ../data/50-mutter-navigation.xml.in.h:8 +msgid "Move window one workspace to the right" +msgstr "Desplaçar la fenèstra d'un espaci de trabalh cap a dreita" -#: ../src/ui/theme-parser.c:3479 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:9 +msgid "Move window one workspace up" +msgstr "Desplaçar la fenèstra d'un espaci de trabalh cap amont" -#: ../src/ui/theme-parser.c:3549 -#, c-format -msgid "No \"focus\" attribute on <%s> element" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:10 +msgid "Move window one workspace down" +msgstr "Desplaçar la fenèstra d'un espaci de trabalh cap aval" -#: ../src/ui/theme-parser.c:3565 -#, c-format -msgid "No \"style\" attribute on <%s> element" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:11 +msgid "Move window one monitor to the left" +msgstr "Desplaçar la fenèstra d'un ecran cap a esquèrra" -#: ../src/ui/theme-parser.c:3574 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:12 +msgid "Move window one monitor to the right" +msgstr "Desplaçar la fenèstra d'un ecran cap a dreita" -#: ../src/ui/theme-parser.c:3583 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:13 +msgid "Move window one monitor up" +msgstr "Desplaçar la fenèstra d'un ecran cap amont" -#: ../src/ui/theme-parser.c:3593 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:14 +msgid "Move window one monitor down" +msgstr "Desplaçar la fenèstra d'un ecran cap aval" -#: ../src/ui/theme-parser.c:3604 -#, c-format -msgid "No \"resize\" attribute on <%s> element" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:15 +msgid "Switch applications" +msgstr "Cambiar d'aplicacion" -#: ../src/ui/theme-parser.c:3614 ../src/ui/theme-parser.c:3637 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:16 +msgid "Switch to previous application" +msgstr "Passar a l'aplicacion precedenta" -#: ../src/ui/theme-parser.c:3648 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:17 +msgid "Switch windows" +msgstr "Cambiar de fenèstra" -#: ../src/ui/theme-parser.c:3662 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:18 +msgid "Switch to previous window" +msgstr "Passar a la fenèstra precedenta" -#: ../src/ui/theme-parser.c:3676 ../src/ui/theme-parser.c:3698 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:19 +msgid "Switch windows of an application" +msgstr "Cambiar de fenèstra d'una aplicacion" -#: ../src/ui/theme-parser.c:3687 ../src/ui/theme-parser.c:3709 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:20 +msgid "Switch to previous window of an application" +msgstr "Passar a la fenèstra precedenta d'una aplicacion" -#: ../src/ui/theme-parser.c:3748 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:21 +msgid "Switch system controls" +msgstr "Cambiar los contraròtles sistèma" -#: ../src/ui/theme-parser.c:3786 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:22 +msgid "Switch to previous system control" +msgstr "Passar al contraròtle sistèma precedent" -#: ../src/ui/theme-parser.c:3824 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:23 +msgid "Switch windows directly" +msgstr "Cambiar de fenèstra dirèctament" -#: ../src/ui/theme-parser.c:3872 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:24 +msgid "Switch directly to previous window" +msgstr "Passar dirèctament a la fenèstra precedenta" -#: ../src/ui/theme-parser.c:3892 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:25 +msgid "Switch windows of an app directly" +msgstr "Cambiar de fenèstra d'una aplicacion dirèctament" -#: ../src/ui/theme-parser.c:3897 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:26 +msgid "Switch directly to previous window of an app" +msgstr "Passar dirèctament a la fenèstra precedenta d'una aplicacion" -#: ../src/ui/theme-parser.c:3909 -#, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:27 +msgid "Switch system controls directly" +msgstr "Cambiar los contraròtles sistèma dirèctament" -#: ../src/ui/theme-parser.c:3931 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:28 +msgid "Switch directly to previous system control" +msgstr "Passar dirèctament al contraròtle sistèma precedent" -#: ../src/ui/theme-parser.c:3941 ../src/ui/theme-parser.c:3971 -#: ../src/ui/theme-parser.c:3976 ../src/ui/theme-parser.c:3981 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:29 +msgid "Hide all normal windows" +msgstr "Amagar totas las fenèstras normalas" -#: ../src/ui/theme-parser.c:4203 -msgid "No draw_ops provided for frame piece" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:30 +msgid "Switch to workspace 1" +msgstr "Passar a l'espaci de trabalh 1" -#: ../src/ui/theme-parser.c:4218 -msgid "No draw_ops provided for button" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:31 +msgid "Switch to workspace 2" +msgstr "Passar a l'espaci de trabalh 2" -#: ../src/ui/theme-parser.c:4270 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:32 +msgid "Switch to workspace 3" +msgstr "Passar a l'espaci de trabalh 3" -#: ../src/ui/theme-parser.c:4325 -msgid "<name> specified twice for this theme" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:33 +msgid "Switch to workspace 4" +msgstr "Passar a l'espaci de trabalh 4" -#: ../src/ui/theme-parser.c:4336 -msgid "<author> specified twice for this theme" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:34 +msgid "Switch to last workspace" +msgstr "Passar al darrièr espaci de trabalh" -#: ../src/ui/theme-parser.c:4347 -msgid "<copyright> specified twice for this theme" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:35 +msgid "Move to workspace left" +msgstr "Desplaçar cap a l'espaci de trabalh d'esquèrra" -#: ../src/ui/theme-parser.c:4358 -msgid "<date> specified twice for this theme" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:36 +msgid "Move to workspace right" +msgstr "Desplaçar cap a l'espaci de trabalh de dreita" -#: ../src/ui/theme-parser.c:4369 -msgid "<description> specified twice for this theme" -msgstr "" +#: ../data/50-mutter-navigation.xml.in.h:37 +msgid "Move to workspace above" +msgstr "Desplaçar cap a l'espaci de trabalh de dessús" -#: ../src/ui/theme-parser.c:4636 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Impossible de trobar un fichièr valid pel tèma %s\n" +#: ../data/50-mutter-navigation.xml.in.h:38 +msgid "Move to workspace below" +msgstr "Desplaçar cap a l'espaci de trabalh de dejós" -#: ../src/ui/theme-parser.c:4692 -#, c-format -msgid "Theme file %s did not contain a root <metacity_theme> element" -msgstr "" +#: ../data/50-mutter-system.xml.in.h:1 +msgid "System" +msgstr "Sistèma" -#: ../src/ui/theme-viewer.c:74 -msgid "/_Windows" -msgstr "/_Fenèstras" +#: ../data/50-mutter-system.xml.in.h:2 +msgid "Show the run command prompt" +msgstr "Afichar la fenèstra per aviar una comanda" -#: ../src/ui/theme-viewer.c:75 -msgid "/Windows/tearoff" -msgstr "/Fenèstras/tearoff" +#: ../data/50-mutter-system.xml.in.h:3 +msgid "Show the activities overview" +msgstr "Afichar l'apercebut de las activitats" -#: ../src/ui/theme-viewer.c:76 -msgid "/Windows/_Dialog" -msgstr "" +#: ../data/50-mutter-windows.xml.in.h:1 +msgid "Windows" +msgstr "Fenèstras" -#: ../src/ui/theme-viewer.c:77 -msgid "/Windows/_Modal dialog" -msgstr "" +#: ../data/50-mutter-windows.xml.in.h:2 +msgid "Activate the window menu" +msgstr "Activar lo menú fenèstra" -#: ../src/ui/theme-viewer.c:78 -msgid "/Windows/_Utility" -msgstr "/_Fenèstras/Utilitari" +#: ../data/50-mutter-windows.xml.in.h:3 +msgid "Toggle fullscreen mode" +msgstr "Bascular lo mòde ecran complet" -#: ../src/ui/theme-viewer.c:79 -msgid "/Windows/_Splashscreen" -msgstr "" +#: ../data/50-mutter-windows.xml.in.h:4 +msgid "Toggle maximization state" +msgstr "Bascular l'estat d'agrandiment" -#: ../src/ui/theme-viewer.c:80 -msgid "/Windows/_Top dock" -msgstr "" +#: ../data/50-mutter-windows.xml.in.h:5 +msgid "Maximize window" +msgstr "Maximizar la fenèstra" -#: ../src/ui/theme-viewer.c:81 -msgid "/Windows/_Bottom dock" -msgstr "" +#: ../data/50-mutter-windows.xml.in.h:6 +msgid "Restore window" +msgstr "Restablir la fenèstra" -#: ../src/ui/theme-viewer.c:82 -msgid "/Windows/_Left dock" -msgstr "" +#: ../data/50-mutter-windows.xml.in.h:7 +msgid "Toggle shaded state" +msgstr "Bascular l'estat de replec" -#: ../src/ui/theme-viewer.c:83 -msgid "/Windows/_Right dock" -msgstr "" +#: ../data/50-mutter-windows.xml.in.h:8 +msgid "Close window" +msgstr "Tampar la fenèstra" -#: ../src/ui/theme-viewer.c:84 -msgid "/Windows/_All docks" -msgstr "" +#: ../data/50-mutter-windows.xml.in.h:9 +msgid "Hide window" +msgstr "Amagar la fenèstra" -#: ../src/ui/theme-viewer.c:85 -msgid "/Windows/Des_ktop" -msgstr "/_Fenèstras/Burèu" +#: ../data/50-mutter-windows.xml.in.h:10 +msgid "Move window" +msgstr "Desplaçar la fenèstra" -#: ../src/ui/theme-viewer.c:134 -msgid "Open another one of these windows" -msgstr "" +#: ../data/50-mutter-windows.xml.in.h:11 +msgid "Resize window" +msgstr "Redimensionar la fenèstra" -#: ../src/ui/theme-viewer.c:141 -msgid "This is a demo button with an 'open' icon" -msgstr "" +#: ../data/50-mutter-windows.xml.in.h:12 +msgid "Toggle window on all workspaces or one" +msgstr "Plaçar la fenèstra sus totes los espacis de trabalh, o sus un sol" -#: ../src/ui/theme-viewer.c:148 -msgid "This is a demo button with a 'quit' icon" -msgstr "" +#: ../data/50-mutter-windows.xml.in.h:13 +msgid "Raise window if covered, otherwise lower it" +msgstr "Metre la fenèstra al primièr plan se es amagada, siquenon al rèireplan" -#: ../src/ui/theme-viewer.c:241 -msgid "This is a sample message in a sample dialog" -msgstr "" +#: ../data/50-mutter-windows.xml.in.h:14 +msgid "Raise window above other windows" +msgstr "Metre la fenèstra al primièr plan" -#: ../src/ui/theme-viewer.c:324 -#, c-format -msgid "Fake menu item %d\n" -msgstr "" +#: ../data/50-mutter-windows.xml.in.h:15 +msgid "Lower window below other windows" +msgstr "Metre la fenèstra jos las autras fenèstras" -#: ../src/ui/theme-viewer.c:358 -msgid "Border-only window" -msgstr "" +#: ../data/50-mutter-windows.xml.in.h:16 +msgid "Maximize window vertically" +msgstr "Maximizar la fenèstra verticalament" -#: ../src/ui/theme-viewer.c:360 -msgid "Bar" -msgstr "Barra" +#: ../data/50-mutter-windows.xml.in.h:17 +msgid "Maximize window horizontally" +msgstr "Maximizar la fenèstra orizontalament" -#: ../src/ui/theme-viewer.c:377 -msgid "Normal Application Window" -msgstr "" +#: ../data/50-mutter-windows.xml.in.h:18 +msgid "View split on left" +msgstr "Vista devesida a esquèrra" -#: ../src/ui/theme-viewer.c:381 -msgid "Dialog Box" -msgstr "" +#: ../data/50-mutter-windows.xml.in.h:19 +msgid "View split on right" +msgstr "Vista devesida a dreita" -#: ../src/ui/theme-viewer.c:385 -msgid "Modal Dialog Box" -msgstr "" +#: ../data/mutter.desktop.in.h:1 +msgid "Mutter" +msgstr "Mutter" -#: ../src/ui/theme-viewer.c:389 -msgid "Utility Palette" +#: ../data/org.gnome.mutter.gschema.xml.in.h:1 +msgid "Modifier to use for extended window management operations" msgstr "" +"Tòca d'utilizar per las operacions espandidas de gestion de las fenèstras" -#: ../src/ui/theme-viewer.c:393 -msgid "Torn-off Menu" +#: ../data/org.gnome.mutter.gschema.xml.in.h:2 +msgid "" +"This key will initiate the \"overlay\", which is a combination window " +"overview and application launching system. The default is intended to be the " +"\"Windows key\" on PC hardware. It's expected that this binding either the " +"default or set to the empty string." msgstr "" +"Aquesta tòca inicia l'« overlay », una combinason d'apercebut de las " +"fenèstras e d'un sistèma d'aviada d'aplicacions. La tòca per defaut sul " +"material PC es la tòca Windows. En principi, aqueste acorchi es configurat " +"sul reglatge per defaut o sus la cadena voida." -#: ../src/ui/theme-viewer.c:397 -msgid "Border" -msgstr "Bordadura" +#: ../data/org.gnome.mutter.gschema.xml.in.h:3 +msgid "Attach modal dialogs" +msgstr "Estacar las bóstias de dialòg modal" -#: ../src/ui/theme-viewer.c:725 -#, c-format -msgid "Button layout test %d" +#: ../data/org.gnome.mutter.gschema.xml.in.h:4 +msgid "" +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." msgstr "" +"Se verai, al luòc d'aver de barras de títol independantas, las bóstias de " +"dialòg apareisson estacadas a la barra de títol de la fenèstra parenta e son " +"desplaçadas ensembles amb ela." -#: ../src/ui/theme-viewer.c:754 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "" +#: ../data/org.gnome.mutter.gschema.xml.in.h:5 +msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "Activar l'empilatge de las fenèstras depausadas suls bòrds de l'ecran" -#: ../src/ui/theme-viewer.c:797 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" +#: ../data/org.gnome.mutter.gschema.xml.in.h:6 +msgid "" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." msgstr "" +"Se activat, lo depaus de las fenèstras suls bòrds verticals de l'ecran las " +"maximiza verticalament e las redimensiona orizontalament per recobrir la " +"mitat de la zòna disponibla. Lo depaus de las fenèstras sul bòrd superior de " +"l'ecran las maximiza completament." -#: ../src/ui/theme-viewer.c:804 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "Error al moment de cargar lo tèma : %s\n" +#: ../data/org.gnome.mutter.gschema.xml.in.h:7 +msgid "Workspaces are managed dynamically" +msgstr "Les espacis de trabalh son gerits d'un biais dinamic" -#: ../src/ui/theme-viewer.c:810 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" +#: ../data/org.gnome.mutter.gschema.xml.in.h:8 +msgid "" +"Determines whether workspaces are managed dynamically or whether there's a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." msgstr "" +"Determina se los espacis de trabalh son gerits d'un biais dinamica o se lo " +"nombre d'espacis de trabalh es fixe (determinat per la clau num-workspaces " +"dins org.gnome.desktop.wm.preferences)." -#: ../src/ui/theme-viewer.c:833 -msgid "Normal Title Font" -msgstr "Poliça de títol normal" +#: ../data/org.gnome.mutter.gschema.xml.in.h:9 +msgid "Workspaces only on primary" +msgstr "Espacis de trabalh solament sus l'ecran principal" -#: ../src/ui/theme-viewer.c:839 -msgid "Small Title Font" -msgstr "Pichona poliça de títol" - -#: ../src/ui/theme-viewer.c:845 -msgid "Large Title Font" +#: ../data/org.gnome.mutter.gschema.xml.in.h:10 +msgid "" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." msgstr "" +"Determina se lo cambiament d'espaci de trabalh se deu produire per las " +"fenèstras de totes los ecrans o solament per las fenèstras de l'ecran " +"principal." -#: ../src/ui/theme-viewer.c:850 -msgid "Button Layouts" -msgstr "" +#: ../data/org.gnome.mutter.gschema.xml.in.h:11 +msgid "No tab popup" +msgstr "Pas cap d'aparicion en seguida d'una quichada sus la tòca tab" -#: ../src/ui/theme-viewer.c:855 -msgid "Benchmark" +#: ../data/org.gnome.mutter.gschema.xml.in.h:12 +msgid "" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." msgstr "" +"Determina se l'utilizacion de fenèstras sorgissentas e de mesa en valor deu " +"èsser desactivada per la consultacion de las fenèstras." -#: ../src/ui/theme-viewer.c:902 -msgid "Window Title Goes Here" -msgstr "" +#: ../data/org.gnome.mutter.gschema.xml.in.h:13 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Espèra l'arrèst del puntador abans lo cambiament de focus" -#: ../src/ui/theme-viewer.c:1006 -#, c-format +#: ../data/org.gnome.mutter.gschema.xml.in.h:14 msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" +"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " +"the focus will not be changed immediately when entering a window, but only " +"after the pointer stops moving." msgstr "" +"Se definit a true e que lo mòde de focus es siá « sloppy » o « mirga », " +"alara lo focus serà pas cambiat immediatament en passant sus una fenèstra, " +"mas solament aprèp que lo puntador s'arrèsta." -#: ../src/ui/theme-viewer.c:1225 -msgid "position expression test returned TRUE but set error" -msgstr "" +#: ../data/org.gnome.mutter.gschema.xml.in.h:15 +msgid "Draggable border width" +msgstr "Largor de bordadura ajustabla" -#: ../src/ui/theme-viewer.c:1227 -msgid "position expression test returned FALSE but didn't set error" +#: ../data/org.gnome.mutter.gschema.xml.in.h:16 +msgid "" +"The amount of total draggable borders. If the theme's visible borders are " +"not enough, invisible borders will be added to meet this value." msgstr "" +"La talha totala de las bordaduras que se pòt desplaçar. Se las bordaduras " +"visiblas del tèma son pas sufisentas, de bordaduras invisiblas son apondudas " +"per arribar a aquesta valor." -#: ../src/ui/theme-viewer.c:1231 -msgid "Error was expected but none given" +#: ../data/org.gnome.mutter.gschema.xml.in.h:17 +msgid "Auto maximize nearly monitor sized windows" msgstr "" +"Maximizar automaticament las fenèstras que la talha n'es pròcha de la de " +"l'ecran" -#: ../src/ui/theme-viewer.c:1233 -#, c-format -msgid "Error %d was expected but %d given" +#: ../data/org.gnome.mutter.gschema.xml.in.h:18 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." msgstr "" +"Se activat, las novèlas fenèstras qu'an gaireben la talha de l'ecran a la " +"dobertura seràn maximizadas automaticament." -#: ../src/ui/theme-viewer.c:1239 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "" +#: ../data/org.gnome.mutter.gschema.xml.in.h:19 +msgid "Place new windows in the center" +msgstr "Plaçar las novèlas fenèstras al centre" -#: ../src/ui/theme-viewer.c:1243 -#, c-format -msgid "x value was %d, %d was expected" +#: ../data/org.gnome.mutter.gschema.xml.in.h:20 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." msgstr "" +"Se true (verai), las novèlas fenèstras seràn totjorn plaçadas al centre de " +"l'ecran actiu del monitor." -#: ../src/ui/theme-viewer.c:1246 -#, c-format -msgid "y value was %d, %d was expected" +#: ../data/org.gnome.mutter.gschema.xml.in.h:21 +msgid "Select window from tab popup" msgstr "" +"Seleccionar la fenèstra dins la vista qu'apareis en seguida d'una quichada " +"sus la tòca tab" -#: ../src/ui/theme-viewer.c:1311 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "" +#: ../data/org.gnome.mutter.gschema.xml.in.h:22 +msgid "Cancel tab popup" +msgstr "Tampar la vista qu'apareis en seguida d'una quichada sus la tòca tab" -#: ../src/ui/theme.c:256 -msgid "top" -msgstr "" +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:1 +msgid "Switch to VT 1" +msgstr "Passar a l'emulator de terminal 1" -#: ../src/ui/theme.c:258 -msgid "bottom" -msgstr "" +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:2 +msgid "Switch to VT 2" +msgstr "Passar a l'emulator de terminal 2" -#: ../src/ui/theme.c:260 -msgid "left" -msgstr "esquèrra" +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:3 +msgid "Switch to VT 3" +msgstr "Passar a l'emulator de terminal 3" -#: ../src/ui/theme.c:262 -msgid "right" -msgstr "drecha" +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:4 +msgid "Switch to VT 4" +msgstr "Passar a l'emulator de terminal 4" -#: ../src/ui/theme.c:289 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "" +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:5 +msgid "Switch to VT 5" +msgstr "Passar a l'emulator de terminal 5" -#: ../src/ui/theme.c:308 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "" +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:6 +msgid "Switch to VT 6" +msgstr "Passar a l'emulator de terminal 6" -#: ../src/ui/theme.c:345 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "" +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:7 +msgid "Switch to VT 7" +msgstr "Passar a l'emulator de terminal 7" -#: ../src/ui/theme.c:357 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "" +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:8 +msgid "Switch to VT 8" +msgstr "Passar a l'emulator de terminal 8" -#: ../src/ui/theme.c:1022 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "" +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:9 +msgid "Switch to VT 9" +msgstr "Passar a l'emulator de terminal 9" -#: ../src/ui/theme.c:1148 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:10 +msgid "Switch to VT 10" +msgstr "Passar a l'emulator de terminal 10" -#: ../src/ui/theme.c:1162 -#, c-format -msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "" +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:11 +msgid "Switch to VT 11" +msgstr "Passar a l'emulator de terminal 11" -#: ../src/ui/theme.c:1173 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "" +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:12 +msgid "Switch to VT 12" +msgstr "Passar a l'emulator de terminal 12" -#: ../src/ui/theme.c:1186 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "" +#: ../src/backends/meta-monitor-manager.c:515 +msgid "Built-in display" +msgstr "Afichatge integrat" -#: ../src/ui/theme.c:1216 -#, c-format -msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" -msgstr "" +#: ../src/backends/meta-monitor-manager.c:538 +msgid "Unknown" +msgstr "Desconegut" -#: ../src/ui/theme.c:1227 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "" +#: ../src/backends/meta-monitor-manager.c:540 +msgid "Unknown Display" +msgstr "Afichatge desconegut" -#: ../src/ui/theme.c:1237 +#. TRANSLATORS: this is a monitor vendor name, followed by a +#. * size in inches, like 'Dell 15"' +#. +#: ../src/backends/meta-monitor-manager.c:548 #, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme.c:1284 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: ../src/compositor/compositor.c:456 #, c-format msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "" - -#: ../src/ui/theme.c:1295 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" +"Another compositing manager is already running on screen %i on display \"%s" +"\"." msgstr "" +"Un autre gestionari de composicion es ja aviat sus l'ecran %i de l'afichatge " +"« %s »." -#: ../src/ui/theme.c:1305 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "" +#: ../src/core/bell.c:194 +msgid "Bell event" +msgstr "Eveniment sonòr" -#: ../src/ui/theme.c:1334 +#: ../src/core/delete.c:127 #, c-format -msgid "Could not parse color \"%s\"" -msgstr "" +msgid "“%s” is not responding." +msgstr "« %s » respond pas." -#: ../src/ui/theme.c:1584 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "" +#: ../src/core/delete.c:129 +msgid "Application is not responding." +msgstr "L'aplicacion respond pas." -#: ../src/ui/theme.c:1611 -#, c-format +#: ../src/core/delete.c:134 msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." msgstr "" +"Podètz pacientar un moment per contunhar o forçar l'aplicacion a quitar " +"definitivament." -#: ../src/ui/theme.c:1625 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "" +#: ../src/core/delete.c:141 +msgid "_Wait" +msgstr "_Esperar" -#: ../src/ui/theme.c:1747 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "" +#: ../src/core/delete.c:141 +msgid "_Force Quit" +msgstr "_Forçar a quitar" -#: ../src/ui/theme.c:1804 +#: ../src/core/display.c:555 #, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "" +msgid "Failed to open X Window System display '%s'\n" +msgstr "Impossible de dobrir l'afichatge « %s » del sistèma X Window\n" -#: ../src/ui/theme.c:1915 ../src/ui/theme.c:1925 ../src/ui/theme.c:1959 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "" +#: ../src/core/main.c:181 +msgid "Disable connection to session manager" +msgstr "Desactivar la connexion al gestionari de sessions" -#: ../src/ui/theme.c:1967 -#, c-format -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "" +#: ../src/core/main.c:187 +msgid "Replace the running window manager" +msgstr "Remplaçar lo gestionari de fenèstras en cors de foncionament" -#: ../src/ui/theme.c:2023 -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "" +#: ../src/core/main.c:193 +msgid "Specify session management ID" +msgstr "Indicar l'ID de gestion de sessions" -#: ../src/ui/theme.c:2032 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "" +#: ../src/core/main.c:198 +msgid "X Display to use" +msgstr "Afichatge X d'utilizar" -#: ../src/ui/theme.c:2040 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "" +#: ../src/core/main.c:204 +msgid "Initialize session from savefile" +msgstr "Inicializar la session dempuèi lo fichièr de salvament" -#: ../src/ui/theme.c:2050 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" +#: ../src/core/main.c:210 +msgid "Make X calls synchronous" +msgstr "Rendre sincròns los apèls a X" -#: ../src/ui/theme.c:2197 ../src/ui/theme.c:2238 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "" +#: ../src/core/main.c:217 +msgid "Run as a wayland compositor" +msgstr "Aviar coma un compositor wayland" -#: ../src/ui/theme.c:2292 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." +#: ../src/core/main.c:223 +msgid "Run as a nested compositor" msgstr "" -#: ../src/ui/theme.c:2321 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "" +#: ../src/core/main.c:231 +msgid "Run as a full display server, rather than nested" +msgstr "Aviar coma un servidor d'afichatge complet, puslèu qu'imbricat" -#: ../src/ui/theme.c:2385 +#: ../src/core/mutter.c:39 #, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" +msgid "" +"mutter %s\n" +"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" msgstr "" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., e autres.\n" +"Aquò es un logicial liure ; consultatz lo còdi font per las\n" +"condicions de còpia.\n" +"I a PAS CAP DE garantida ; quitament pas de VALOR MERCANDA o\n" +"d'ADEQÜACION A UN USATGE PARTICULAR.\n" -#: ../src/ui/theme.c:2396 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "" +#: ../src/core/mutter.c:53 +msgid "Print version" +msgstr "Imprimir la version" -#: ../src/ui/theme.c:2598 ../src/ui/theme.c:2618 ../src/ui/theme.c:2638 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "" +#: ../src/core/mutter.c:59 +msgid "Mutter plugin to use" +msgstr "Empeuton de Mutter d'utilizar" -#: ../src/ui/theme.c:4157 +#: ../src/core/prefs.c:1997 #, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" +msgid "Workspace %d" +msgstr "Espaci de trabalh %d" -#: ../src/ui/theme.c:4633 ../src/ui/theme.c:4658 +#: ../src/core/screen.c:521 #, c-format msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" +"Display \"%s\" already has a window manager; try using the --replace option " +"to replace the current window manager." msgstr "" +"L'afichatge « %s » a ja un gestionari de fenèstras ; ensajatz d'utilizar " +"l'opcion --replace per remplaçar lo gestionari de fenèstras actual." -#: ../src/ui/theme.c:4702 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Impossible de cargar lo tèma \"%s\" : %s\n" - -#: ../src/ui/theme.c:4828 ../src/ui/theme.c:4835 ../src/ui/theme.c:4842 -#: ../src/ui/theme.c:4849 ../src/ui/theme.c:4856 +#: ../src/core/screen.c:603 #, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "" +msgid "Screen %d on display '%s' is invalid\n" +msgstr "L'ecran %d sus l'afichatge « %s » es pas valid\n" -#: ../src/ui/theme.c:4864 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" +#: ../src/core/util.c:121 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter es estat compilat sens la presa en carga del mòde verbós\n" -#: ../src/ui/theme.c:5231 ../src/ui/theme.c:5293 ../src/ui/theme.c:5356 -#, c-format +#: ../src/x11/session.c:1815 msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" - -#: ../src/ui/theme.c:5239 ../src/ui/theme.c:5301 ../src/ui/theme.c:5364 -#, c-format -msgid "Constant \"%s\" has already been defined" +"These windows do not support "save current setup" and will have to " +"be restarted manually next time you log in." msgstr "" +"Aquestas fenèstras prenon pas en carga « l'enregistrament de la " +"configuracion actuala » e deuràn èsser reaviadas manualament a la connexion " +"que ven." -#: ../src/tools/metacity-message.c:150 +#: ../src/x11/window-props.c:549 #, c-format -msgid "Usage: %s\n" -msgstr "Sintaxi : %s\n" - +msgid "%s (on %s)" +msgstr "%s (sus %s)" diff --git a/po/or.po b/po/or.po index 4d79ec770..5e124c8c2 100644 --- a/po/or.po +++ b/po/or.po @@ -5,1849 +5,889 @@ # $Id: or.po,v 1.12 2006/03/23 18:54:56 gmohanty Exp $ # # Gora Mohanty <gora_mohanty@yahoo.co.in>, 2004, 2006. -# Manoj Kumar Giri <mgiri@redhat.com>, 2009. +# Manoj Kumar Giri <mgiri@redhat.com>, 2009, 2012, 2013, 2014. msgid "" msgstr "" "Project-Id-Version: or\n" -"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=metacity&component=general\n" -"POT-Creation-Date: 2009-02-05 16:08+0000\n" -"PO-Revision-Date: 2009-03-12 15:21+0530\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=mutter&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2014-09-15 09:53+0000\n" +"PO-Revision-Date: 2014-09-17 16:56+0530\n" "Last-Translator: Manoj Kumar Giri <mgiri@redhat.com>\n" "Language-Team: Oriya <oriya-it@googlegroups.com>\n" +"Language: or\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: KBabel 1.11.4\n" -"Plural-Forms: nplurals=2; plural=(n!=1);\n\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" "\n" "\n" - -#: ../src/50-metacity-desktop-key.xml.in.h:1 -#| msgid "top" -msgid "Desktop" -msgstr "ଡେସ୍କଟପ" - -#: ../src/50-metacity-key.xml.in.h:1 -#| msgid "Window manager: " -msgid "Window Management" -msgstr "ୱିଣ୍ଡୋ ପରିଚାଳନା" - -#: ../src/core/core.c:206 -#, c-format -msgid "Unknown window information request: %d" -msgstr "ଅଜଣା ୱିଣ୍ଡୋ ସୂଚନା ଅନୁରୋଧ କରାଯାଇଛି: %d" - -#: ../src/core/delete.c:70 ../src/core/delete.c:97 -#: ../src/ui/metacity-dialog.c:50 ../src/ui/theme-parser.c:522 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "\"%s\"କୁ ପୁର୍ଣ ସଂଖ୍ଯା ଭାବରେ ବିଶ୍ଳେଷଣ କରିହେଲା ନାହିଁ" - -#: ../src/core/delete.c:77 ../src/core/delete.c:104 -#: ../src/ui/metacity-dialog.c:57 ../src/ui/theme-parser.c:531 -#: ../src/ui/theme-parser.c:586 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "\"%s\" ବାକ୍ଯଖଣ୍ଡର ପଛପାଖରେ ଥିବା ଅକ୍ଷର \"%s\" ବୁଝିହେଲା ନାହିଁ" - -#: ../src/core/delete.c:135 -#, c-format -msgid "Failed to parse message \"%s\" from dialog process\n" -msgstr "ସଂଳାପ ସଂସାଧନରୁ \"%s\" ସନ୍ଦେଶକୁ ବିଶ୍ଳେଷଣ କରିବାରେ ଅସମର୍ଥ\n" - -#: ../src/core/delete.c:253 -#, c-format -msgid "Error reading from dialog display process: %s\n" -msgstr "ସଂଳାପ ପ୍ରଦର୍ଶନ ସଂସାଧନରୁ ପଢ଼ିବାରେ ତ୍ରୁଟି: %s\n" - -#: ../src/core/delete.c:336 -#, c-format -msgid "Error launching metacity-dialog to ask about killing an application: %s\n" -msgstr "ଗୋଟିଏ ପ୍ରୟୋଗର ସମାପନ କରିବା ବିଷୟରେ ପଚାରିବା ପାଇଁ ମେଟାସିଟି ସଂଳାପ ଚଳାଇବାରେ ତ୍ରୁଟି: %s\n" - -#: ../src/core/delete.c:445 -#, c-format -msgid "Failed to get hostname: %s\n" -msgstr "ହୋଷ୍ଟ ନାମ ପାଇବାରେ ଅସମର୍ଥ: %s\n" - -#: ../src/core/display.c:256 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "ମିଶ୍ରଣ ପାଇଁ ଅନୁପସ୍ଥିତ %s ଅନୁଲଗ୍ନ ଆବଶ୍ୟକ" - -#: ../src/core/display.c:334 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "ଏକ୍ସ ୱିଣ୍ଡୋ ତନ୍ତ୍ରର ପ୍ରଦର୍ଶିକା '%s' ଖୋଲିବାରେ ଅସମର୍ଥ\n" - -#: ../src/core/errors.c:272 -#, c-format -msgid "" -"Lost connection to the display '%s';\n" -"most likely the X server was shut down or you killed/destroyed\n" -"the window manager.\n" -msgstr "" -"ପ୍ରଦର୍ଶିକା '%s'; ସହିତ ସଂୟୋଗ କଟି ଗଲା\n" -"ସମ୍ଭବତଃ କି ଏକ୍ସ ସେବକ ବନ୍ଦ କରା ଦିଆ ଯାଇଛି ବା ଆପଣ ୱିଣ୍ଡୋ ପରିଚାଳକକୁ ସମାପ୍ତ/ନଷ୍ଟ କରିଦେଇଛନ୍ତି.\n" - -#: ../src/core/errors.c:279 -#, c-format -msgid "Fatal IO error %d (%s) on display '%s'.\n" -msgstr "ପ୍ରଦର୍ଶିକା '%3$s'ରେ ସାଂଘାତିକ ଆଇ.ଓ. (ନିବେଶ/ନିର୍ଗମ) ତ୍ରୁଟି %1$d (%2$s).\n" - -#: ../src/core/keybindings.c:680 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "ଏକ ଅଲଗା କାରିକା ପୂର୍ବରୁ ଚାବି %sକୁ ରୂପାନ୍ତରକ %x ସହିତ ବନ୍ଧନ ରୂପେ ବ୍ଯବହାର କରୁଛି\n" - -#. Displayed when a keybinding which is -#. * supposed to launch a program fails. -#. -#: ../src/core/keybindings.c:2294 -#, c-format -#| msgid "" -#| "There was an error running \"%s\":\n" -#| "%s." -msgid "" -"There was an error running <tt>%s</tt>:\n" -"\n" -"%s" -msgstr "" -"ସେଠାରେ ଗୋଟିଏ ତ୍ରୁଟି ଚାଲୁଅଛି <tt>%s</tt>:\n" "\n" -"%s" - -#: ../src/core/keybindings.c:2381 -#, c-format -msgid "No command %d has been defined.\n" -msgstr "%d ନିର୍ଦ୍ଦେଶ ବ୍ଯାଖ୍ଯା କରାଯାଇ ନାହିଁ.\n" - -#: ../src/core/keybindings.c:3335 -#, c-format -msgid "No terminal command has been defined.\n" -msgstr "କୌଣସି ଟର୍ମିନାଲ ନିର୍ଦ୍ଦେଶ ବ୍ଯାଖ୍ଯା କରାଯାଇ ନାହିଁ.\n" - -#: ../src/core/main.c:116 -#, c-format -#| msgid "" -#| "metacity %s\n" -#| "Copyright (C) 2001-2002 Havoc Pennington, Red Hat, Inc., and others\n" -#| "This is free software; see the source for copying conditions.\n" -#| "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -#| "PARTICULAR PURPOSE.\n" -msgid "" -"metacity %s\n" -"Copyright (C) 2001-2008 Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" -"metacity %s\n" -"Copyright (C) 2001-2008 Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" - -#: ../src/core/main.c:253 -msgid "Disable connection to session manager" -msgstr "ଅଧିବେଶନ ପରିଚାଳକ ସଙ୍ଗେ ସଂଯୋଗ ନିଷ୍କ୍ରିୟ କରନ୍ତୁ" - -#: ../src/core/main.c:259 -msgid "Replace the running window manager with Metacity" -msgstr "ଚଳନ୍ତା ୱିଣ୍ଡୋ ପରିଚାଳକକୁ ମେଟାସିଟି ସହିତ ବଦଳାନ୍ତୁ" - -#: ../src/core/main.c:265 -msgid "Specify session management ID" -msgstr "ଅଧିବେଶନ ପରିଚାଳନ ପରିଚୟ ନିର୍ଦ୍ଦିଷ୍ଟ କରନ୍ତୁ" - -#: ../src/core/main.c:270 -msgid "X Display to use" -msgstr "ବ୍ଯବହାର ପାଇଁ ଏକ୍ସ ପ୍ରଦର୍ଶକ" - -#: ../src/core/main.c:276 -msgid "Initialize session from savefile" -msgstr "ଅଧିବେଶନକୁ ସଞ୍ଚିତ ଫାଇଲଠାରୁ ପ୍ରାରମ୍ଭ କରନ୍ତୁ" - -#: ../src/core/main.c:282 -msgid "Print version" -msgstr "ସଂସ୍କରଣ ମୁଦ୍ରଣ କରନ୍ତୁ" - -#: ../src/core/main.c:288 -msgid "Make X calls synchronous" -msgstr "ଏକ୍ସ ଡାକରା ସମକାଳିତ କରନ୍ତୁ" - -#: ../src/core/main.c:294 -#| msgid "Compositing Manager" -msgid "Turn compositing on" -msgstr "ମିଶ୍ରଣ ପ୍ରକ୍ରିୟାକୁ ଅନକରନ୍ତୁ" - -#: ../src/core/main.c:300 -msgid "Turn compositing off" -msgstr "ମିଶ୍ରଣ ପ୍ରକ୍ରିୟାକୁ ଅଫକରନ୍ତୁ" - -#: ../src/core/main.c:478 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "ପ୍ରସଙ୍ଗ ଡିରେକ୍ଟୋରି: %sକୁ କ୍ରମବୀକ୍ଷଣ କରିବାରେ ଅସମର୍ଥ\n" - -#: ../src/core/main.c:494 -#, c-format -#| msgid "" -#| "Could not find a theme! Be sure %s exists and contains the usual themes." -msgid "Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "ପ୍ରସଙ୍ଗ ମିଳିଲା ନାହିଁ! ନିଶ୍ଚିତ କରନ୍ତୁ କି %s ବାସ୍ତବରେ ଅଛି ଓ ତାହା ଭିତରେ ସାଧାରଣ ପ୍ରସଙ୍ଗଗୁଡ଼ିକ ରହିଛି।\n" -#: ../src/core/main.c:550 -#, c-format -msgid "Failed to restart: %s\n" -msgstr "ପୁନଃ ପ୍ରାରମ୍ଭ କରିବାରେ ଅସମର୍ଥ: %s\n" - -#. -#. * We found it, but it was invalid. Complain. -#. * -#. * FIXME: This replicates the original behaviour, but in the future -#. * we might consider reverting invalid keys to their original values. -#. * (We know the old value, so we can look up a suitable string in -#. * the symtab.) -#. * -#. * (Empty comment follows so the translators don't see this.) -#. -#. -#: ../src/core/prefs.c:505 ../src/core/prefs.c:660 -#, c-format -msgid "GConf key '%s' is set to an invalid value\n" -msgstr "ଜିକନ୍ଫ ଚାବି '%s' ଅବୈଧ ମୂଲ୍ଯକୁ ବିନ୍ଯାସ କରାଯାଇଛି\n" - -#: ../src/core/prefs.c:586 ../src/core/prefs.c:829 -#, c-format -#| msgid "%d stored in GConf key %s is out of range 0 to %d\n" -msgid "%d stored in GConf key %s is out of range %d to %d\n" -msgstr "%d ଯାହାକି GConf କି %s ମଧ୍ଯରେ ସଂରକ୍ଷିତ ଥାଏ, ପରିସର %d ବାହାରୁ %dରେ ଅଛି\n" - -#: ../src/core/prefs.c:630 ../src/core/prefs.c:707 ../src/core/prefs.c:755 -#: ../src/core/prefs.c:819 ../src/core/prefs.c:1112 ../src/core/prefs.c:1128 -#: ../src/core/prefs.c:1145 ../src/core/prefs.c:1161 -#, c-format -msgid "GConf key \"%s\" is set to an invalid type\n" -msgstr "ଜିକନ୍ଫ ଚାବି \"%s\" ଅବୈଧ ପ୍ରକାରକୁ ବିନ୍ଯାସ କରାଯାଇଛି\n" - -#: ../src/core/prefs.c:1231 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "ଅବୈଧ ପ୍ରୟୋଗ ପାଇଁ ଅନ୍ଯତର ଉପାୟଗୁଡ଼ିକ ଅସମର୍ଥ କରାଯାଇଛି. କିଛି ପ୍ରୟୋଗ ଠିକ ଭାବେ ନ ଚଳିପାରନ୍ତି.\n" - -#: ../src/core/prefs.c:1302 -#, c-format -msgid "Could not parse font description \"%s\" from GConf key %s\n" -msgstr "ଜିକନ୍ଫ ଚାବି %2$sରୁ \"%1$s\" ଅକ୍ଷରରୂପ ବିବରଣୀ ବିଶ୍ଳେଷଣ କରିହେଲା ନାହିଁ\n" - -#: ../src/core/prefs.c:1364 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "ବିନ୍ଯାସ ତଥ୍ଯାଧାରରେ ପାୟାଯାଇଥିବା \"%s\" ମାଉସ ଚାବି ରୂପାନ୍ତରକ ପାଇଁ ଗୋଟିଏ ବୈଧ ମୂଲ୍ଯ ନୁହେଁ\n" - -#: ../src/core/prefs.c:1782 -#, c-format -msgid "Error setting number of workspaces to %d: %s\n" -msgstr "କାର୍ଯ୍ଯକ୍ଷେତ୍ର ସଂଖ୍ଯାକୁ %d ଭଳି ବିନ୍ଯାସ କରିବାରେ ତ୍ରୁଟି: %s\n" - -#: ../src/core/prefs.c:1971 ../src/core/prefs.c:2474 -#, c-format -msgid "Workspace %d" -msgstr "କାର୍ଯ୍ଯକ୍ଷେତ୍ର %d" - -#: ../src/core/prefs.c:2001 ../src/core/prefs.c:2179 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "ବିନ୍ଯାସ ତଥ୍ଯାଧାରରେ ପାୟାଯାଇଥିବା \"%s\" ଚାବିବନ୍ଧନୀ \"%s\" ପାଇଁ ଗୋଟିଏ ବୈଧ ମୂଲ୍ଯ ନୁହେଁ\n" - -#: ../src/core/prefs.c:2555 -#, c-format -msgid "Error setting name for workspace %d to \"%s\": %s\n" -msgstr "କାର୍ଯ୍ଯକ୍ଷେତ୍ର %dର ନାମ \"%s\" ବିନ୍ଯାସ କରିବାରେ ତ୍ରୁଟି: %s\n" - -#: ../src/core/prefs.c:2753 -#, c-format -#| msgid "Error setting name for workspace %d to \"%s\": %s\n" -msgid "Error setting compositor status: %s\n" -msgstr "ମିଶ୍ରଣ ପ୍ରକ୍ରିୟା ସ୍ଥିତି ବିନ୍ୟାସ କରିବାରେ ତ୍ରୁଟି: %s\n" - -#: ../src/core/screen.c:350 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "ପ୍ରଦର୍ଶକ '%2$s'ରେ ପରଦା %1$d ଅବୈଧ\n" - -#: ../src/core/screen.c:366 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"ପ୍ରଦର୍ଶକ \"%2$s\"ରେ ପରଦା %1$dର ପୂର୍ବରୁ ଗୋଟିଏ ୱିଣ୍ଢୋ ପରିଚାଳକ ଅଛି; ସାମ୍ପ୍ରତିକ ୱିଣ୍ଢୋ ପରିଚାଳକକୁ " -"ବଦଳାଇବା ପାଇଁ, ବଦଳ ଚୟନ ବ୍ଯବହାର କରିବାକୁ ଚେଷ୍ଟା କରନ୍ତୁ.\n" - -#: ../src/core/screen.c:393 -#, c-format -msgid "Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "ପ୍ରଦର୍ଶକ \"%2$s\"ରେ ପରଦା %1$dର ୱିଣ୍ଢୋ ପରିଚାଳକ ଚୟନ ବୁଝିହେଲା ନାହିଁ\n" - -#: ../src/core/screen.c:451 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "ପ୍ରଦର୍ଶକ \"%2$s\"ରେ ପରଦା %1$dର ପୂର୍ବରୁ ଗୋଟିଏ ୱିଣ୍ଢୋ ପରିଚାଳକ ଅଛି\n" - -#: ../src/core/screen.c:661 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "ପ୍ରଦର୍ଶକ \"%2$s\"ରେ ପରଦା %1$dକୁ ନୁକ୍ତ କରିହେଲା ନାହିଁ\n" - -#. Translators: Please don't translate "Control", "Shift", etc, since these -#. * are hardcoded (in gtk/gtkaccelgroup.c; it's not metacity's fault). -#. * "disabled" must also stay as it is. -#. -#: ../src/core/schema-bindings.c:169 -#| msgid "" -#| "The keybinding used to close a window. The format looks like \"<" -#| "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#| "liberal and allows lower or upper case, and also abbreviations such as " -#| "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#| "special string \"disabled\", then there will be no keybinding for this " -#| "action." -msgid "" -"The format looks like \"<Control>a\" or <Shift><Alt>F1\".\n" -"\n" -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -"special string \"disabled\", then there will be no keybinding for this " -"action." -msgstr "" -"ସଜ୍ଜିକରଣ ଶୈଳୀଟି \"<Control>a\" କିମ୍ବା <Shift><Alt>F1\" ପରି ଦେଖାଯାଉଛି।\n" -"\n" -"ବିଶ୍ଳେଷକଟି ବେଶ୍ ଉଦାରମନା, ଓ ଛୋଟ ବା ବଡ଼ ଅକ୍ଷର, ଏବଂ " -"\"<Ctl>\" ଏବଂ \"<Ctrl>\" ଭଳି ସଂକ୍ଷେପ ମଧ୍ଯ ଗ୍ରହଣ କରେ. ଆପଣ ଏହି ଚୟନକୁ ବିଶେଷ " -"ବାକ୍ଯଖଣ୍ଡ \"disabled\" ରୂପେ ବିନ୍ଯାସ କଲେ, ଏହି କାର୍ଯ୍ଯ ପାଇଁ ଚାବିବନ୍ଧନୀ ରହିବ ନାହିଁ।" - -#: ../src/core/schema-bindings.c:177 -#| msgid "" -#| "The keybinding used to close a window. The format looks like \"<" -#| "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#| "liberal and allows lower or upper case, and also abbreviations such as " -#| "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#| "special string \"disabled\", then there will be no keybinding for this " -#| "action." -msgid "" -"The format looks like \"<Control>a\" or <Shift><Alt>F1\".\n" -"\n" -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -"special string \"disabled\", then there will be no keybinding for this " -"action.\n" -"\n" -"This keybinding may be reversed by holding down the \"shift\" key; " -"therefore, \"shift\" cannot be one of the keys it uses." -msgstr "" -"ସଜ୍ଜିକରଣ ଶୈଳୀଟି \"<Control>a\" କିମ୍ବା <Shift><Alt>F1\" ପରି ଦେଖାଯାଉଛି।\n" -"\n" -"ବିଶ୍ଳେଷକଟି ବେଶ୍ ଉଦାରମନା, ଓ ଛୋଟ ବା ବଡ଼ ଅକ୍ଷର, ଏବଂ " -"\"<Ctl>\" ଏବଂ \"<Ctrl>\" ଭଳି ସଂକ୍ଷେପ ମଧ୍ଯ ଗ୍ରହଣ କରେ. ଆପଣ ଏହି ଚୟନକୁ ବିଶେଷ " -"ବାକ୍ଯଖଣ୍ଡ \"disabled\" ରୂପେ ବିନ୍ଯାସ କଲେ, ଏହି କାର୍ଯ୍ଯ ପାଇଁ ଚାବିବନ୍ଧନୀ ରହିବ ନାହିଁ। " -"\n" -"\"shift\" କି କୁ ଧରିରଖି ଏହି କି ବନ୍ଧନିକୁ ଓଲଟା କରିହେବ; " -"ତେଣୁ, \"shift\" ଏହା ବ୍ୟବହାର କରୁଥିବା କି ମଧ୍ଯରୁ ଗୋଟିଏ ହୋଇନପାରେ।" - -#: ../src/core/session.c:837 ../src/core/session.c:844 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "'%s' ଡିରେକ୍ଟୋରି ସୃଷ୍ଟି କରିହେଲା ନାହିଁ: %s\n" - -#: ../src/core/session.c:854 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "ଅଧିବେଶନ ଫାଇଲ '%s' ଲିଖନ ପାଇଁ ଖୋଲିହେଲା ନାହିଁ: %s\n" - -#: ../src/core/session.c:995 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "ଅଧିବେଶନ ଫାଇଲ '%s' ଲେଖିବାରେ ତ୍ରୁଟି: %s\n" - -#: ../src/core/session.c:1000 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "ଅଧିବେଶନ ଫାଇଲ '%s' ବନ୍ଦ କରିବାରେ ତ୍ରୁଟି: %s\n" - -#. oh, just give up -#: ../src/core/session.c:1093 -#, c-format -msgid "Failed to read saved session file %s: %s\n" -msgstr "ସଞ୍ଚିତ ଅଧିବେଶନ ଫାଇଲ '%s' ପଢ଼ିବାରେ ଅସଫଳ: %s\n" - -#: ../src/core/session.c:1132 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "ସଞ୍ଚିତ ଅଧିବେଶନ ଫାଇଲ ବିଶ୍ଳେଷଣ କରିବାରେ ଅସଫଳ: %s\n" - -#: ../src/core/session.c:1181 -#, c-format -msgid "<metacity_session> attribute seen but we already have the session ID" -msgstr "<metacity_session> ଗୁଣ ଦେଖାଗଲା, କିନ୍ତୁ ଆମ ପାଖରେ ଅଧିବେଶନ ପରିଚୟ ପୂର୍ବରୁ ଅଛି" - -#: ../src/core/session.c:1194 ../src/core/session.c:1269 -#: ../src/core/session.c:1301 ../src/core/session.c:1373 -#: ../src/core/session.c:1433 -#, c-format -#| msgid "Unknown attribute %s on <window> element" -msgid "Unknown attribute %s on <%s> element" -msgstr "<%s> ଉପାଦାନ ଉପରେ ଅଜଣା ଗୁଣଧର୍ମ %s" - -#: ../src/core/session.c:1211 -#, c-format -msgid "nested <window> tag" -msgstr "ଘେରାଯାଇଥିବା <window> ସୂଚକ" - -#: ../src/core/session.c:1453 -#, c-format -msgid "Unknown element %s" -msgstr "ଅଜଣା ଉପାଦାନ %s" +#: ../data/50-mutter-navigation.xml.in.h:1 +msgid "Navigation" +msgstr "ଅନ୍ୱେଷଣ" -#: ../src/core/session.c:1879 -#, c-format -msgid "" -"Error launching metacity-dialog to warn about apps that don't support " -"session management: %s\n" -msgstr "" -"ଅଧିବେଶନ ପରିଚାଳନ ସହାୟକ ନ କରୁଥିବା ପ୍ରୟୋଗଗୁଡ଼ିକ ବିଷୟରେ ଚେତାବନୀ ଜଣାଇବା ପାଇଁ ମେଟାସିଟି-ସଂଳାପ " -"ଚଳାଇବାରେ ତ୍ରୁଟି: %s\n" - -#: ../src/core/util.c:101 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "ତ୍ରୁଟିମୁକ୍ତ ବିବରଣୀ ଖୋଲିବାରେ ଅସଫଳ: %s\n" - -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "%s ବିବରଣୀ ଫାଇଲକୁ fdopen() କରିବୋରେ ଅସଫଳ: %s\n" - -#: ../src/core/util.c:117 -#, c-format -msgid "Opened log file %s\n" -msgstr "%s ବିବରଣୀ ଫାଇଲ ଖୋଲାହେଲା\n" - -#: ../src/core/util.c:136 ../src/tools/metacity-message.c:176 -#, c-format -msgid "Metacity was compiled without support for verbose mode\n" -msgstr "ମେଟାସିଟି ଦୃଷ୍ଟ ସୂଚନା ଧାରାର ସହାୟକ ବିନା ସଂକଳିତ ହୋଇଥିଲା.\n" - -#: ../src/core/util.c:236 -msgid "Window manager: " -msgstr "ୱିଣ୍ଡୋ ପରିଚାଳକ" +#: ../data/50-mutter-navigation.xml.in.h:2 +msgid "Move window to workspace 1" +msgstr "ୱିଣ୍ଡୋକୁ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୧କୁ ଘୁଞ୍ଚାନ୍ତୁ" -#: ../src/core/util.c:388 -msgid "Bug in window manager: " -msgstr "ୱିଣ୍ଡୋ ପରିଚାଳକରେ ତ୍ରୁଟି" +#: ../data/50-mutter-navigation.xml.in.h:3 +msgid "Move window to workspace 2" +msgstr "ୱିଣ୍ଡୋକୁ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୨କୁ ଘୁଞ୍ଚାନ୍ତୁ" -#: ../src/core/util.c:421 -msgid "Window manager warning: " -msgstr "ୱିଣ୍ଡୋ ପରିଚାଳକ ଚେତାବନୀ" +#: ../data/50-mutter-navigation.xml.in.h:4 +msgid "Move window to workspace 3" +msgstr "ୱିଣ୍ଡୋକୁ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୩କୁ ଘୁଞ୍ଚାନ୍ତୁ" -#: ../src/core/util.c:449 -msgid "Window manager error: " -msgstr "ୱିଣ୍ଡୋ ପରିଚାଳକ ତ୍ରୁଟି" +#: ../data/50-mutter-navigation.xml.in.h:5 +msgid "Move window to workspace 4" +msgstr "ୱିଣ୍ଡୋକୁ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୪କୁ ଘୁଞ୍ଚାନ୍ତୁ" -#. Translators: This is the title used on dialog boxes -#. eof all-keybindings.h -#: ../src/core/util.c:577 ../src/metacity.desktop.in.h:1 -#: ../src/metacity-wm.desktop.in.h:1 -msgid "Metacity" -msgstr "ମେଟାସିଟି" +#: ../data/50-mutter-navigation.xml.in.h:6 +#| msgid "Move window to workspace 1" +msgid "Move window to last workspace" +msgstr "ୱିଣ୍ଡୋକୁ ଶେଷ କାର୍ଯ୍ଯକ୍ଷେତ୍ରକୁ ଘୁଞ୍ଚାନ୍ତୁ" -#. first time through -#: ../src/core/window.c:5626 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"%s ୱିଣ୍ଡୋ WM_CLIENT_LEADERରେ (ଯେପରି ICCCM ନିର୍ଦ୍ଦିଷ୍ଟ ହୋଇଛି) ଅପେକ୍ଷା ନିଜ ଉପରେ " -"SM_CLIENT_ID ବିନ୍ଯାସ କରେ.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:6191 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %" -"d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"%s ୱିଣ୍ଡୋ ଗୋଟିଏ MWM ଆଭାସ ଦ୍ବାରା ସୂଚିତ କରେ କି ତାହାର ଆକେର ବଦଳେଇ ହେବ ନାହିଁ, କିନ୍ତୁ ସର୍ବନିମ୍ନ " -"ଆକାର %d x %d ଓ ସର୍ବାଧିକ ଆକାର %d x %d ବିନ୍ଯାସ କରେ; ଏହାର ବିଶେଷ ମାନେ ନାହିଁ.\n" +#: ../data/50-mutter-navigation.xml.in.h:7 +msgid "Move window one workspace to the left" +msgstr "ୱିଣ୍ଡୋକୁ ଗୋଟିଏ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ବାମକୁ ଘୁଞ୍ଚାନ୍ତୁ" -#: ../src/core/window-props.c:260 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "ପ୍ରୟୋଗ ଗୋଟିଏ ନକଲି _NET_WM_PID %lu ବିନ୍ଯାସ କଲା\n" +#: ../data/50-mutter-navigation.xml.in.h:8 +msgid "Move window one workspace to the right" +msgstr "ୱିଣ୍ଡୋକୁ ଗୋଟିଏ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ଡାହାଣକୁ ଘୁଞ୍ଚାନ୍ତୁ" -#: ../src/core/window-props.c:377 -#, c-format -msgid "%s (on %s)" -msgstr "%s (%s ଉପରେ)" +#: ../data/50-mutter-navigation.xml.in.h:9 +msgid "Move window one workspace up" +msgstr "ୱିଣ୍ଡୋକୁ ଗୋଟିଏ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ଉପରକୁ ଘୁଞ୍ଚାନ୍ତୁ" -#: ../src/core/window-props.c:1358 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "ଅବୈଧ WM_TRANSIENT_FOR ୱିଣ୍ଡୋ 0x%lx। ଯାହାକି %s ପାଇଁ ଉଲ୍ଲିଖିତ ।\n" +#: ../data/50-mutter-navigation.xml.in.h:10 +msgid "Move window one workspace down" +msgstr "ୱିଣ୍ଡୋକୁ ଗୋଟିଏ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ତଳକୁ ଘୁଞ୍ଚାନ୍ତୁ" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"ୱିଣ୍ଡୋ 0x%lxର ଗୁଣଧର୍ମ %s ଅଛି\n" -"ଯାହାର %s ପ୍ରକାରର %d ସଜ୍ଜିକରଣ ଶୈଳୀ ଥିବା ପ୍ରତ୍ଯାଶିତ ଥିଲା\n" -"ଓ ବାସ୍ତବରେ %s ପ୍ରକାରର %d ସଜ୍ଜିକରଣ ଶୈଳୀ n_items %d ଅଛି.\n" -"ସବୁଠାରୁ ସମ୍ଭବତଃ କି ଏହା ପ୍ରୟୋଗର ତ୍ରୁଟି, ୱିଣ୍ଡୋ ପରିଚାଳକର ନୁହେଁ.\n" -"ୱିଣ୍ଡୋର ଶୀର୍ଷକ ହେଲା \"%s\" class=\"%s\" name=\"%s\"\n" +#: ../data/50-mutter-navigation.xml.in.h:11 +#| msgid "Move window one workspace to the left" +msgid "Move window one monitor to the left" +msgstr "ୱିଣ୍ଡୋକୁ ବାମକୁ ଗୋଟିଏ ମନିଟର ପରେ ଘୁଞ୍ଚାନ୍ତୁ" -#: ../src/core/xprops.c:401 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "ୱିଣ୍ଡୋ 0x%2$lxର %1$s ଗୁଣଧର୍ମରେ ଅବୈଧ ୟି.ଟି.ଏଫ.-୮ ଅଛି\n" +#: ../data/50-mutter-navigation.xml.in.h:12 +#| msgid "Move window one workspace to the right" +msgid "Move window one monitor to the right" +msgstr "ୱିଣ୍ଡୋକୁ ଡ଼ାହାଣକୁ ଗୋଟିଏ ମନିଟର ପରେ ଘୁଞ୍ଚାନ୍ତୁ" -#: ../src/core/xprops.c:484 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "ୱିଣ୍ଡୋ 0x%2$lxର %1$s ଗୁଣଧର୍ମର ତାଲିକାରେ %3$d ବସ୍ତୁରେ ଅବୈଧ ୟି.ଟି.ଏଫ.-୮ ଅଛି\n" +#: ../data/50-mutter-navigation.xml.in.h:13 +#| msgid "Move window one workspace up" +msgid "Move window one monitor up" +msgstr "ୱିଣ୍ଡୋକୁ ଉପକରକୁ ଗୋଟିଏ ମନିଟର ପରେ ଘୁଞ୍ଚାନ୍ତୁ" -#: ../src/include/all-keybindings.h:88 +#: ../data/50-mutter-navigation.xml.in.h:14 +#| msgid "Move window one workspace down" +msgid "Move window one monitor down" +msgstr "ୱିଣ୍ଡୋକୁ ତଳକୁ ଗୋଟିଏ ମନିଟର ପରେ ଘୁଞ୍ଚାନ୍ତୁ" + +#: ../data/50-mutter-navigation.xml.in.h:15 +msgid "Switch applications" +msgstr "ପ୍ରୟୋଗଗୁଡ଼ିକୁ ବଦଳାନ୍ତୁ" + +#: ../data/50-mutter-navigation.xml.in.h:16 +#| msgid "Switch applications" +msgid "Switch to previous application" +msgstr "ପୂର୍ବବର୍ତ୍ତୀ ପ୍ରୟୋଗକୁ ବଦଳ କରନ୍ତୁ" + +#: ../data/50-mutter-navigation.xml.in.h:17 +msgid "Switch windows" +msgstr "ୱିଣ୍ଡୋଗୁଡ଼ିକୁ ବଦଳାନ୍ତୁ" + +#: ../data/50-mutter-navigation.xml.in.h:18 +#| msgid "Switch windows" +msgid "Switch to previous window" +msgstr "ପୂର୍ବବର୍ତ୍ତୀ ୱିଣ୍ଡୋକୁ ବଦଳ କରନ୍ତୁ" + +#: ../data/50-mutter-navigation.xml.in.h:19 +msgid "Switch windows of an application" +msgstr "ଗୋଟିଏ ପ୍ରୟୋଗର ୱିଣ୍ଡୋଗୁଡ଼ିକ ମଧ୍ଯରେ ଚାଲନ୍ତୁ" + +#: ../data/50-mutter-navigation.xml.in.h:20 +#| msgid "Switch windows of an application" +msgid "Switch to previous window of an application" +msgstr "ପ୍ରୟୋଗର ପୂର୍ବବର୍ତ୍ତୀ ୱିଣ୍ଡୋକୁ ବଦଳ କରନ୍ତୁ" + +#: ../data/50-mutter-navigation.xml.in.h:21 +msgid "Switch system controls" +msgstr "ତନ୍ତ୍ର ନିୟନ୍ତ୍ରଣଗୁଡିକୁ ବଦଳାନ୍ତୁ" + +#: ../data/50-mutter-navigation.xml.in.h:22 +#| msgid "Switch system controls" +msgid "Switch to previous system control" +msgstr "ପୂର୍ବବର୍ତ୍ତୀ ତନ୍ତ୍ର ନିୟନ୍ତ୍ରଣକୁ ବଦଳାନ୍ତୁ" + +#: ../data/50-mutter-navigation.xml.in.h:23 +msgid "Switch windows directly" +msgstr "ୱିଣ୍ଡୋଗୁଡ଼ିକୁ ସିଧାସଳଖ ଭାବରେ ବଦଳାନ୍ତୁ" + +#: ../data/50-mutter-navigation.xml.in.h:24 +msgid "Switch directly to previous window" +msgstr "ପୂର୍ବବର୍ତ୍ତୀ ୱିଣ୍ଡୋକୁ ସିଧାସଳଖ ଭାବରେ ବଦଳ କରନ୍ତୁ" + +#: ../data/50-mutter-navigation.xml.in.h:25 +msgid "Switch windows of an app directly" +msgstr "ଗୋଟିଏ ପ୍ରୟୋଗର ୱିଣ୍ଡୋଗୁଡ଼ିକୁ ଓଲଟା ଭାବରେ ବଦଳାନ୍ତୁ" + +#: ../data/50-mutter-navigation.xml.in.h:26 +#| msgid "Switch windows of an application" +msgid "Switch directly to previous window of an app" +msgstr "ଏକ ପ୍ରୟୋଗର ପୂର୍ବବର୍ତ୍ତୀ ୱିଣ୍ଡୋକୁ ସିଧାସଳଖ ଭାବରେ ବଦଳ କରନ୍ତୁ" + +#: ../data/50-mutter-navigation.xml.in.h:27 +msgid "Switch system controls directly" +msgstr "ତନ୍ତ୍ର ନିୟନ୍ତ୍ରଣଗୁଡିକୁ ସିଧାସଳଖ ଭାବରେ ବଦଳାନ୍ତୁ" + +#: ../data/50-mutter-navigation.xml.in.h:28 +#| msgid "Switch system controls" +msgid "Switch directly to previous system control" +msgstr "ପୂର୍ବବର୍ତ୍ତୀ ତନ୍ତ୍ର ନିୟନ୍ତ୍ରଣକୁ ସିଧାସଳଖ ଭାବରେ ବଦଳାନ୍ତୁ" + +#: ../data/50-mutter-navigation.xml.in.h:29 +msgid "Hide all normal windows" +msgstr "ସମସ୍ତ ସାଧାରଣ ୱିଣ୍ଡୋଗୁଡ଼ିକୁ ଲୁଚାନ୍ତୁ" + +#: ../data/50-mutter-navigation.xml.in.h:30 msgid "Switch to workspace 1" msgstr "କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୧କୁ ଯାଆନ୍ତୁ" -#: ../src/include/all-keybindings.h:90 +#: ../data/50-mutter-navigation.xml.in.h:31 msgid "Switch to workspace 2" msgstr "କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୨କୁ ଯାଆନ୍ତୁ" -#: ../src/include/all-keybindings.h:92 +#: ../data/50-mutter-navigation.xml.in.h:32 msgid "Switch to workspace 3" msgstr "କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୩କୁ ଯାଆନ୍ତୁ" -#: ../src/include/all-keybindings.h:94 +#: ../data/50-mutter-navigation.xml.in.h:33 msgid "Switch to workspace 4" msgstr "କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୪କୁ ଯାଆନ୍ତୁ" -#: ../src/include/all-keybindings.h:96 -msgid "Switch to workspace 5" -msgstr "କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୫କୁ ଯାଆନ୍ତୁ" +#: ../data/50-mutter-navigation.xml.in.h:34 +#| msgid "Switch to workspace 1" +msgid "Switch to last workspace" +msgstr "ଶେଷ କାର୍ଯ୍ଯକ୍ଷେତ୍ରକୁ ଯାଆନ୍ତୁ" -#: ../src/include/all-keybindings.h:98 -msgid "Switch to workspace 6" -msgstr "କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୬କୁ ଯାଆନ୍ତୁ" +#: ../data/50-mutter-navigation.xml.in.h:35 +msgid "Move to workspace left" +msgstr "ବାମ କାର୍ଯ୍ଯକ୍ଷେତ୍ରକୁ ପଠାନ୍ତୁ" -#: ../src/include/all-keybindings.h:100 -msgid "Switch to workspace 7" -msgstr "କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୭କୁ ଯାଆନ୍ତୁ" +#: ../data/50-mutter-navigation.xml.in.h:36 +msgid "Move to workspace right" +msgstr "ଡାହାଣ କାର୍ଯ୍ଯକ୍ଷେତ୍ରକୁ ପଠାନ୍ତୁ" -#: ../src/include/all-keybindings.h:102 -msgid "Switch to workspace 8" -msgstr "କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୮କୁ ଯାଆନ୍ତୁ" +#: ../data/50-mutter-navigation.xml.in.h:37 +msgid "Move to workspace above" +msgstr "ଉପର କାର୍ଯ୍ଯକ୍ଷେତ୍ରକୁ ପଠାନ୍ତୁ" -#: ../src/include/all-keybindings.h:104 -msgid "Switch to workspace 9" -msgstr "କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୯କୁ ଯାଆନ୍ତୁ" +#: ../data/50-mutter-navigation.xml.in.h:38 +msgid "Move to workspace below" +msgstr "ତଳ କାର୍ଯ୍ଯକ୍ଷେତ୍ରକୁ ପଠାନ୍ତୁ" -#: ../src/include/all-keybindings.h:106 -msgid "Switch to workspace 10" -msgstr "କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୧୦କୁ ଯାଆନ୍ତୁ" +#: ../data/50-mutter-system.xml.in.h:1 +msgid "System" +msgstr "ତନ୍ତ୍ର" -#: ../src/include/all-keybindings.h:108 -msgid "Switch to workspace 11" -msgstr "କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୧୧କୁ ଯାଆନ୍ତୁ" +#: ../data/50-mutter-system.xml.in.h:2 +msgid "Show the run command prompt" +msgstr "ନିର୍ଦ୍ଦେଶ ପ୍ରମ୍ପଟକୁ ଚଲାନ୍ତୁକୁ ଦେଖାନ୍ତୁ" -#: ../src/include/all-keybindings.h:110 -msgid "Switch to workspace 12" -msgstr "କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୧୨କୁ ଯାଆନ୍ତୁ" +#: ../data/50-mutter-system.xml.in.h:3 +msgid "Show the activities overview" +msgstr "କାର୍ଯ୍ୟକଳାପଗୁଡ଼ିକର ସମୀକ୍ଷାକୁ ଦର୍ଶାନ୍ତୁ" -#: ../src/include/all-keybindings.h:122 -#| msgid "Switch to workspace on the left" -msgid "Switch to workspace on the left of the current workspace" -msgstr "ଏହାର ବାମରେ ସ୍ଥିତ କାର୍ଯ୍ଯକ୍ଷେତ୍ରକୁ ଯାଆନ୍ତୁ" +#: ../data/50-mutter-windows.xml.in.h:1 +msgid "Windows" +msgstr "ୱିଣ୍ଡୋମାନ" -#: ../src/include/all-keybindings.h:126 -#, fuzzy -#| msgid "Switch to workspace on the right" -msgid "Switch to workspace on the right of the current workspace" -msgstr "ଏହାର ଡାହାଣରେ ସ୍ଥିତ କାର୍ଯ୍ଯକ୍ଷେତ୍ରକୁ ଯାଆନ୍ତୁ" - -#: ../src/include/all-keybindings.h:130 -#| msgid "Switch to workspace above this one" -msgid "Switch to workspace above the current workspace" -msgstr "ଏହାର ଉପରେ ସ୍ଥିତ କାର୍ଯ୍ଯକ୍ଷେତ୍ରକୁ ଯାଆନ୍ତୁ" - -#: ../src/include/all-keybindings.h:134 -#| msgid "Switch to workspace below this one" -msgid "Switch to workspace below the current workspace" -msgstr "ଏହାର ତଳେ ସ୍ଥିତ କାର୍ଯ୍ଯକ୍ଷେତ୍ରକୁ ଯାଆନ୍ତୁ" - -#: ../src/include/all-keybindings.h:150 -#| msgid "Move between windows with popup" -msgid "Move between windows of an application, using a popup window" -msgstr "ପପ୍ଅପ୍ ସହିତ ୱିଣ୍ଡୋଗୁଡ଼ିକ ମଧ୍ଯରେ ଘୁଞ୍ଚନ୍ତୁ" - -#: ../src/include/all-keybindings.h:153 -#| msgid "Move focus backwards between windows using popup display" -msgid "Move backward between windows of an application, using a popup window" -msgstr "ପପ୍ଅପ୍ ସହିତ ୱିଣ୍ଡୋଗୁଡ଼ିକ ମଧ୍ଯରେ କେନ୍ଦ୍ରକୁ ପଛୁଆ ଘୁଞ୍ଚାନ୍ତୁ" - -#: ../src/include/all-keybindings.h:157 -#| msgid "Move between windows with popup" -msgid "Move between windows, using a popup window" -msgstr "ପପ୍ଅପ୍ ସହିତ ୱିଣ୍ଡୋଗୁଡ଼ିକ ମଧ୍ଯରେ ଘୁଞ୍ଚନ୍ତୁ" - -#: ../src/include/all-keybindings.h:160 -#| msgid "Move focus backwards between windows using popup display" -msgid "Move backward between windows, using a popup window" -msgstr "ପପ୍ଅପ୍ ସହିତ ୱିଣ୍ଡୋଗୁଡ଼ିକ ମଧ୍ଯରେ କେନ୍ଦ୍ରକୁ ପଛୁଆ ଘୁଞ୍ଚାନ୍ତୁ" - -#: ../src/include/all-keybindings.h:163 -#| msgid "Move between panels and the desktop with popup" -msgid "Move between panels and the desktop, using a popup window" -msgstr "ଫଳକ ଓ ପପ୍ଅପ୍ ସହିତ ଡେସ୍କଟପ୍ ମଧ୍ଯରେ ସଙ୍ଗେ ସଙ୍ଗେ ଘୁଞ୍ଚନ୍ତୁ" - -#: ../src/include/all-keybindings.h:166 -#| msgid "Move backwards between panels and the desktop with popup" -msgid "Move backward between panels and the desktop, using a popup window" -msgstr "ଫଳକ ଓ ପପ୍ଅପ୍ ସହିତ ଡେସ୍କଟପ୍ ମଧ୍ଯରେ ସଙ୍ଗେ ସଙ୍ଗେ ପଛୁଆ ଘୁଞ୍ଚନ୍ତୁ" - -#: ../src/include/all-keybindings.h:171 -#| msgid "Move between windows immediately" -msgid "Move between windows of an application immediately" -msgstr "ୱିଣ୍ଡୋଗୁଡ଼ିକ ମଧ୍ଯରେ ସଙ୍ଗେ ସଙ୍ଗେ ଘୁଞ୍ଚନ୍ତୁ" - -#: ../src/include/all-keybindings.h:174 -#| msgid "Move backwards between windows immediately" -msgid "Move backward between windows of an application immediately" -msgstr "ୱିଣ୍ଡୋଗୁଡ଼ିକ ମଧ୍ଯରେ ସଙ୍ଗେ ସଙ୍ଗେ ପଛୁଆ ଘୁଞ୍ଚନ୍ତୁ" - -#: ../src/include/all-keybindings.h:177 -msgid "Move between windows immediately" -msgstr "ୱିଣ୍ଡୋଗୁଡ଼ିକ ମଧ୍ଯରେ ସଙ୍ଗେ ସଙ୍ଗେ ଘୁଞ୍ଚନ୍ତୁ" - -#: ../src/include/all-keybindings.h:180 -#| msgid "Move backwards between windows immediately" -msgid "Move backward between windows immediately" -msgstr "ୱିଣ୍ଡୋଗୁଡ଼ିକ ମଧ୍ଯରେ ସଙ୍ଗେ ସଙ୍ଗେ ପଛୁଆ ଘୁଞ୍ଚନ୍ତୁ" - -#: ../src/include/all-keybindings.h:183 -msgid "Move between panels and the desktop immediately" -msgstr "ଫଳକ ଓ ଡେସ୍କଟପ୍ ମଧ୍ଯରେ ସଙ୍ଗେ ସଙ୍ଗେ ଘୁଞ୍ଚନ୍ତୁ" - -#: ../src/include/all-keybindings.h:186 -msgid "Move backward between panels and the desktop immediately" -msgstr "ଫଳକ ଓ ଡେସ୍କଟପ୍ ମଧ୍ଯରେ ସଙ୍ଗେ ସଙ୍ଗେ ପଛୁଆ ଘୁଞ୍ଚନ୍ତୁ" - -#: ../src/include/all-keybindings.h:191 -#| msgid "Hide all windows and focus desktop" -msgid "Hide all normal windows and set focus to the desktop" -msgstr "ସବୁ ୱିଣ୍ଡୋଗୁଡ଼ିକୁ ଲୁଚାଇ ଡେସ୍କଟପକୁ କେନ୍ଦ୍ରିତ କରନ୍ତୁ" - -#: ../src/include/all-keybindings.h:194 -#| msgid "Show the panel menu" -msgid "Show the panel's main menu" -msgstr "ଫଳକ ମେନୁ ଦେଖାନ୍ତୁ" - -#: ../src/include/all-keybindings.h:197 -#| msgid "Show the panel run application dialog" -msgid "Show the panel's \"Run Application\" dialog box" -msgstr "ଫଳକର \"Run Application\" ସଂଳାପ ଦେଖାନ୍ତୁ" - -#: ../src/include/all-keybindings.h:238 -msgid "Take a screenshot" -msgstr "ପରଦା ପ୍ରତିଛବି ନିଅନ୍ତୁ" - -#: ../src/include/all-keybindings.h:240 -msgid "Take a screenshot of a window" -msgstr "ଗୋଟିଏ ୱିଣ୍ଡୋର ପରଦା ପ୍ରତିଛବି ନିଅନ୍ତୁ" - -#: ../src/include/all-keybindings.h:242 -msgid "Run a terminal" -msgstr "ଟର୍ମିନାଲ ଚଳାନ୍ତୁ" - -#: ../src/include/all-keybindings.h:257 -#| msgid "Activate window menu" +#: ../data/50-mutter-windows.xml.in.h:2 msgid "Activate the window menu" msgstr "ୱିଣ୍ଡୋ ମେନୁ ସକ୍ରିୟ କରନ୍ତୁ" -#: ../src/include/all-keybindings.h:260 +#: ../data/50-mutter-windows.xml.in.h:3 msgid "Toggle fullscreen mode" msgstr "ପୂର୍ଣ୍ମପରଦା ଧାରା ଅଦଳବଦଳ କରନ୍ତୁ" -#: ../src/include/all-keybindings.h:262 +#: ../data/50-mutter-windows.xml.in.h:4 msgid "Toggle maximization state" msgstr "ବୃହତ୍ତମ ଅବସ୍ଥା ଅଦଳବଦଳ କରନ୍ତୁ" -#: ../src/include/all-keybindings.h:264 -#| msgid "Lower window below other windows" -msgid "Toggle whether a window will always be visible over other windows" -msgstr "ୱିଣ୍ଡୋକୁ ଅଲଗା ୱିଣ୍ଡୋ ପଛକୁ ନିଅନ୍ତୁ" - -#: ../src/include/all-keybindings.h:266 +#: ../data/50-mutter-windows.xml.in.h:5 msgid "Maximize window" msgstr "ୱିଣ୍ଡୋକୁ ଯଥାସମ୍ଭବ ବଢ଼ାନ୍ତୁ" -#: ../src/include/all-keybindings.h:268 -#| msgid "Resize window" +#: ../data/50-mutter-windows.xml.in.h:6 msgid "Restore window" msgstr "ୱିଣ୍ଡୋକୁ ପୁନଃସ୍ଥାପନ କରନ୍ତୁ" -#: ../src/include/all-keybindings.h:270 +#: ../data/50-mutter-windows.xml.in.h:7 msgid "Toggle shaded state" msgstr "ଘୋଡାହୋଇଥିବା ଅବସ୍ଥା ଅଦଳବଦଳ କରନ୍ତୁ" -#: ../src/include/all-keybindings.h:272 -msgid "Minimize window" -msgstr "ୱିଣ୍ଡୋକୁ ଯଥାସମ୍ଭବ ଛୋଟ କରନ୍ତୁ" - -#: ../src/include/all-keybindings.h:274 +#: ../data/50-mutter-windows.xml.in.h:8 msgid "Close window" msgstr "ୱିଣ୍ଡୋ ବନ୍ଦ କରନ୍ତୁ" -#: ../src/include/all-keybindings.h:276 +#: ../data/50-mutter-windows.xml.in.h:9 +msgid "Hide window" +msgstr "ୱିଣ୍ଡୋ ଲୁଚାନ୍ତୁ" + +#: ../data/50-mutter-windows.xml.in.h:10 msgid "Move window" msgstr "ୱିଣ୍ଡୋକୁ ଘୁଞ୍ଚାନ୍ତୁ" -#: ../src/include/all-keybindings.h:278 +#: ../data/50-mutter-windows.xml.in.h:11 msgid "Resize window" msgstr "ୱିଣ୍ଡୋର ଆକାର ବଦଳାନ୍ତୁ" -#: ../src/include/all-keybindings.h:281 -#| msgid "Toggle window on all workspaces" -msgid "Toggle whether window is on all workspaces or just one" -msgstr "ୱିଣ୍ଡୋ ସବୁ କାର୍ଯ୍ଯକ୍ଷେତ୍ରରେ ଥିବା ଅଦଳବଦଳ କରନ୍ତୁ" - -#: ../src/include/all-keybindings.h:285 -msgid "Move window to workspace 1" -msgstr "ୱିଣ୍ଡୋକୁ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୧କୁ ଘୁଞ୍ଚାନ୍ତୁ" - -#: ../src/include/all-keybindings.h:288 -msgid "Move window to workspace 2" -msgstr "ୱିଣ୍ଡୋକୁ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୨କୁ ଘୁଞ୍ଚାନ୍ତୁ" - -#: ../src/include/all-keybindings.h:291 -msgid "Move window to workspace 3" -msgstr "ୱିଣ୍ଡୋକୁ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୩କୁ ଘୁଞ୍ଚାନ୍ତୁ" - -#: ../src/include/all-keybindings.h:294 -msgid "Move window to workspace 4" -msgstr "ୱିଣ୍ଡୋକୁ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୪କୁ ଘୁଞ୍ଚାନ୍ତୁ" - -#: ../src/include/all-keybindings.h:297 -msgid "Move window to workspace 5" -msgstr "ୱିଣ୍ଡୋକୁ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୫କୁ ଘୁଞ୍ଚାନ୍ତୁ" - -#: ../src/include/all-keybindings.h:300 -msgid "Move window to workspace 6" -msgstr "ୱିଣ୍ଡୋକୁ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୬କୁ ଘୁଞ୍ଚାନ୍ତୁ" - -#: ../src/include/all-keybindings.h:303 -msgid "Move window to workspace 7" -msgstr "ୱିଣ୍ଡୋକୁ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୭କୁ ଘୁଞ୍ଚାନ୍ତୁ" - -#: ../src/include/all-keybindings.h:306 -msgid "Move window to workspace 8" -msgstr "ୱିଣ୍ଡୋକୁ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୮କୁ ଘୁଞ୍ଚାନ୍ତୁ" - -#: ../src/include/all-keybindings.h:309 -msgid "Move window to workspace 9" -msgstr "ୱିଣ୍ଡୋକୁ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୯କୁ ଘୁଞ୍ଚାନ୍ତୁ" - -#: ../src/include/all-keybindings.h:312 -msgid "Move window to workspace 10" -msgstr "ୱିଣ୍ଡୋକୁ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୧୦କୁ ଘୁଞ୍ଚାନ୍ତୁ" - -#: ../src/include/all-keybindings.h:315 -msgid "Move window to workspace 11" -msgstr "ୱିଣ୍ଡୋକୁ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୧୧କୁ ଘୁଞ୍ଚାନ୍ତୁ" - -#: ../src/include/all-keybindings.h:318 -msgid "Move window to workspace 12" -msgstr "ୱିଣ୍ଡୋକୁ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୧୨କୁ ଘୁଞ୍ଚାନ୍ତୁ" - -#: ../src/include/all-keybindings.h:330 -msgid "Move window one workspace to the left" -msgstr "ୱିଣ୍ଡୋକୁ ଗୋଟିଏ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ବାମକୁ ଘୁଞ୍ଚାନ୍ତୁ" - -#: ../src/include/all-keybindings.h:333 -msgid "Move window one workspace to the right" -msgstr "ୱିଣ୍ଡୋକୁ ଗୋଟିଏ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ଡାହାଣକୁ ଘୁଞ୍ଚାନ୍ତୁ" - -#: ../src/include/all-keybindings.h:336 -msgid "Move window one workspace up" -msgstr "ୱିଣ୍ଡୋକୁ ଗୋଟିଏ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ଉପରକୁ ଘୁଞ୍ଚାନ୍ତୁ" - -#: ../src/include/all-keybindings.h:339 -msgid "Move window one workspace down" -msgstr "ୱିଣ୍ଡୋକୁ ଗୋଟିଏ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ତଳକୁ ଘୁଞ୍ଚାନ୍ତୁ" +#: ../data/50-mutter-windows.xml.in.h:12 +msgid "Toggle window on all workspaces or one" +msgstr "ହଲୁଥିବା ୱିଣ୍ଡୋ ସବୁ କାର୍ଯ୍ଯକ୍ଷେତ୍ରରେ ଅଛି ଅଥବା କେବଳ ଗୋଟିକରେ ଅଛି" -#: ../src/include/all-keybindings.h:342 -#| msgid "Raise obscured window, otherwise lower" -msgid "Raise window if it's covered by another window, otherwise lower it" -msgstr "ୱିଣ୍ଡୋ ଲୁଚାହୋଇଥିଲେ ତାହାକୁ ସାମନାକୁ ଆଣନ୍ତୁ, ନଚେତ୍ ତାହାକୁ ପଛକୁ ନିଅନ୍ତୁ" +#: ../data/50-mutter-windows.xml.in.h:13 +msgid "Raise window if covered, otherwise lower it" +msgstr "ୱିଣ୍ଡୋ ଲୁଚାହୋଇଥିଲେ ତାହାକୁ ସାମନାକୁ ଆଣନ୍ତୁ, ନଚେତ ତାହାକୁ ତଳକୁ କରନ୍ତୁ" -#: ../src/include/all-keybindings.h:344 +#: ../data/50-mutter-windows.xml.in.h:14 msgid "Raise window above other windows" msgstr "ୱିଣ୍ଡୋକୁ ଅଲଗା ୱିଣ୍ଡୋଗୁଡ଼ିକର ସାମନାକୁ ଆଣନ୍ତୁ" -#: ../src/include/all-keybindings.h:346 +#: ../data/50-mutter-windows.xml.in.h:15 msgid "Lower window below other windows" msgstr "ୱିଣ୍ଡୋକୁ ଅଲଗା ୱିଣ୍ଡୋ ପଛକୁ ନିଅନ୍ତୁ" -#: ../src/include/all-keybindings.h:350 +#: ../data/50-mutter-windows.xml.in.h:16 msgid "Maximize window vertically" msgstr "ୱିଣ୍ଡୋକୁ ଭୂଲମ୍ବ ଭାବରେ ଯଥାସମ୍ଭବ ବଢ଼ାନ୍ତୁ" -#: ../src/include/all-keybindings.h:354 +#: ../data/50-mutter-windows.xml.in.h:17 msgid "Maximize window horizontally" msgstr "ୱିଣ୍ଡୋକୁ ଭୂସମାନ୍ତର ଭାବରେ ଯଥାସମ୍ଭବ ବଢ଼ାନ୍ତୁ" -#: ../src/include/all-keybindings.h:358 -#| msgid "Move window one workspace to the left" -msgid "Move window to north-west (top left) corner" -msgstr "ୱିଣ୍ଡୋକୁ ଗୋଟିଏ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ବାମକୁ ଘୁଞ୍ଚାନ୍ତୁ" +#: ../data/50-mutter-windows.xml.in.h:18 +msgid "View split on left" +msgstr "ବାମ ପାଖରେ ବିଭାଜନକୁ ଦେଖନ୍ତୁ" -#: ../src/include/all-keybindings.h:361 -#| msgid "Move window one workspace to the right" -msgid "Move window to north-east (top right) corner" -msgstr "ୱିଣ୍ଡୋକୁ ଗୋଟିଏ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ଡାହାଣକୁ ଘୁଞ୍ଚାନ୍ତୁ" - -#: ../src/include/all-keybindings.h:364 -msgid "Move window to south-west (bottom left) corner" -msgstr "ୱିଣ୍ଡୋକୁ ଦକ୍ଷିଣ-ପଶ୍ଚିମ (ବାମପଟ ତଳ) କୋଣକୁ ଘୁଞ୍ଚାନ୍ତୁ" +#: ../data/50-mutter-windows.xml.in.h:19 +msgid "View split on right" +msgstr "ଡ଼ାହାଣ ପାଖରେ ବିଭାଜନକୁ ଦେଖନ୍ତୁ" -#: ../src/include/all-keybindings.h:367 -msgid "Move window to south-east (bottom right) corner" -msgstr "ୱିଣ୍ଡୋକୁ ଦକ୍ଷିଣ-ପୂର୍ବ (ଡାହାଣ ପଟ ତଳ) କୋଣକୁ ଘୁଞ୍ଚାନ୍ତୁ" +#: ../data/mutter.desktop.in.h:1 +msgid "Mutter" +msgstr "Mutter" -#: ../src/include/all-keybindings.h:371 -msgid "Move window to north (top) side of screen" -msgstr "ୱିଣ୍ଡୋକୁ ପରଦାର ପଶ୍ଚିମ (ଉପର) କୋଣକୁ ଘୁଞ୍ଚାନ୍ତୁ" +#: ../data/org.gnome.mutter.gschema.xml.in.h:1 +msgid "Modifier to use for extended window management operations" +msgstr "ବିସ୍ତାରିତ ୱିଣ୍ଡୋ ପରିଚାଳନା କାର୍ଯ୍ଯଗୁଡ଼ିକ ପାଇଁ ରୂପାନ୍ତରକ" -#: ../src/include/all-keybindings.h:374 -msgid "Move window to south (bottom) side of screen" -msgstr "ୱିଣ୍ଡୋକୁ ପରଦାର ଦକ୍ଷିଣ (ତଳ) କୋଣକୁ ଘୁଞ୍ଚାନ୍ତୁ" - -#: ../src/include/all-keybindings.h:377 -msgid "Move window to east (right) side of screen" +#: ../data/org.gnome.mutter.gschema.xml.in.h:2 +msgid "" +"This key will initiate the \"overlay\", which is a combination window " +"overview and application launching system. The default is intended to be the " +"\"Windows key\" on PC hardware. It's expected that this binding either the " +"default or set to the empty string." msgstr "" +"ଏହି କି ଟି \"overlay\" କୁ ଆରମ୍ଭ କରିବ, ଯାହାକି ୱିଣ୍ଡୋ ସମୀକ୍ଷା ଏବଂ ପ୍ରୟୋଗ " +"ପ୍ରାରମ୍ଭ ତନ୍ତ୍ରର ଏକ " +"ମିଶ୍ରଣ ଅଟେ। ପୂର୍ବନିର୍ଦ୍ଧାରିତଟି PC ହାର୍ଡୱେର ଉପରେ \"Windows key\" ପାଇଁ " +"ଉଦ୍ଦିଷ୍ଟ। ଏହା " +"ଆଶାକରାଯାଇଥାଏ ଯେ ଏହି ମିଶ୍ରଣଟି ହୁଏତଃ ପୂର୍ବନିର୍ଦ୍ଧାରିତ ଅଥବା ଖାଲି ବାକ୍ୟଖଣ୍ଡ ଅଟେ।" -#: ../src/include/all-keybindings.h:380 -msgid "Move window to west (left) side of screen" -msgstr "ୱିଣ୍ଡୋକୁ ପରଦାର ପଶ୍ଚିମ (ବାମ) କୋଣକୁ ଘୁଞ୍ଚାନ୍ତୁ" +#: ../data/org.gnome.mutter.gschema.xml.in.h:3 +msgid "Attach modal dialogs" +msgstr "କ୍ରିୟାତ୍ମକ ସଂଳାପଗୁଡ଼ିକୁ ଲଗାନ୍ତୁ" -#: ../src/include/all-keybindings.h:383 -#| msgid "Move window one workspace down" -msgid "Move window to center of screen" -msgstr "ୱିଣ୍ଡୋକୁ ପରଦାର କେନ୍ଦ୍ରକୁ ଘୁଞ୍ଚାନ୍ତୁ" - -#: ../src/metacity.schemas.in.in.h:1 -msgid "(Not implemented) Navigation works in terms of applications not windows" -msgstr "(କାର୍ଯ୍ଯକାରୀ ନୁହେଁ) ପଥପ୍ରଦର୍ଶନ ପ୍ରୟୋଗ ହିସାବରେ କାମ କରେ, ୱିଣ୍ଡୋ ହିସାବରେ ନୁହେଁ" - -#: ../src/metacity.schemas.in.in.h:2 -#| msgid "" -#| "A font description string describing a font for window titlebars. The " -#| "size from the description will only be used if the titlebar_font_size " -#| "option is set to 0, however. Also, this option is disabled if the " -#| "titlebar_uses_desktop_font option is set to true. By default, " -#| "titlebar_font is unset, causing Metacity to fall back to the desktop font " -#| "even if titlebar_uses_desktop_font is false." -msgid "" -"A font description string describing a font for window titlebars. The size " -"from the description will only be used if the titlebar_font_size option is " -"set to 0. Also, this option is disabled if the titlebar_uses_desktop_font " -"option is set to true." -msgstr "" -"ୱିଣ୍ଡୋ ଶୀର୍ଷକ ପଟିର ଅକ୍ଷରରୂପ ବର୍ଣ୍ଣନା କରୁଥିବା ଗୋଟିଏ ଅକ୍ଷରରୂପ ବର୍ଣ୍ଣନା ବାକ୍ଯଖଣ୍ଡ. " -"ଶୀର୍ଷକପଟି_ଅକ୍ଷରରୂପ_ଆକାର ଚୟନ ଶୂନ୍ଯ ଥିଲେ ହିଁ ବର୍ଣ୍ଣନାରୁ ଆକାରଟି ବ୍ଯବହାର ହେବ. " -"ଶୀର୍ଷକପଟି_ଡେସ୍କଟପ_ଅକ୍ଷରରୂପ_ବ୍ଯବହାର_କରେ ଚୟନ ସତ ନିର୍ଦ୍ଦିଷ୍ଟ ହୋଇଥିଲେ ଭି ଏହି ଚୟନଟି ନିଷ୍କ୍ରିୟ " -"କରାଯାଇଥିବ. ସାଧାରଣରେ ଶୀର୍ଷକପଟି_ଅକ୍ଷରରୂପ ବିନ୍ଯାସ ହୋଇ ନ ଥାଏ, ଯାହା ଯୋଗୁ " -"ଶୀର୍ଷକପଟି_ଡେସ୍କଟପ_ଅକ୍ଷରରୂପ_ବ୍ଯବହାର_କରେ ଅସତ୍ଯ ନିର୍ଦ୍ଦିଷ୍ଟ ହୋଇଥିଲେ ମଧ୍ଯ ମେଟାସିଟି ଡେସ୍କଟପ " -"ଅକ୍ଷରରୂପକୁ ହିଁ ବ୍ଯବହାର କରିବ," - -#: ../src/metacity.schemas.in.in.h:3 -msgid "Action on title bar double-click" -msgstr "ଶୀର୍ଷକ ପଟିରେ ମାଉସ୍ କୁ ଯୁଗ୍ନ ଭାବରେ ଦବାଇଲେ କି କାମ ଚାଳନ ହେବ" - -#: ../src/metacity.schemas.in.in.h:4 -#| msgid "Action on title bar double-click" -msgid "Action on title bar middle-click" -msgstr "ଶୀର୍ଷକ ପଟିରେ ମାଉସ୍ କୁ ଯୁଗ୍ନ ଭାବରେ ଦବାଇଲେ କି କାମ ଚାଳନ ହେବ" - -#: ../src/metacity.schemas.in.in.h:5 -#| msgid "Action on title bar double-click" -msgid "Action on title bar right-click" -msgstr "ଶୀର୍ଷକ ପଟିରେ ମାଉସ୍ କୁ ଯୁଗ୍ନ ଭାବରେ ଦବାଇଲେ କି କାମ ଚାଳନ ହେବ" - -#: ../src/metacity.schemas.in.in.h:6 -msgid "Arrangement of buttons on the titlebar" -msgstr "ଶୀର୍ଷକ ପଟିରେ ଚାବିର ସଜ୍ଜା" - -#: ../src/metacity.schemas.in.in.h:7 -#| msgid "" -#| "Arrangement of buttons on the titlebar. The value should be a string, " -#| "such as \"menu:minimize,maximize,close\"; the colon separates the left " -#| "corner of the window from the right corner, and the button names are " -#| "comma-separated. Duplicate buttons are not allowed. Unknown button names " -#| "are silently ignored so that buttons can be added in future metacity " -#| "versions without breaking older versions." -msgid "" -"Arrangement of buttons on the titlebar. The value should be a string, such " -"as \"menu:minimize,maximize,spacer,close\"; the colon separates the left " -"corner of the window from the right corner, and the button names are comma-" -"separated. Duplicate buttons are not allowed. Unknown button names are " -"silently ignored so that buttons can be added in future metacity versions " -"without breaking older versions. A special spacer tag can be used to insert " -"some space between two adjacent buttons." -msgstr "" -"ଶୀର୍ଷକ ପଟିରେ ଚାବିଗୁଡ଼ିକର ସଜ୍ଜା. ଏହି ମୂଲ୍ଯ ଗୌଟିଏ ବାକ୍ଯକଣ୍ଡ ହେବା ଉଚିତ, ଉଦାହରଣ ସ୍ବରୂପ, " -"\"menu:minimize,maximize,spacer,close\"; ବିରାମ ଚିହ୍ନଟି ୱିଣ୍ଡୋର ବାମ ଓ ଡାହାଣ କଣକୁ ବିଭାଜନ " -"କରେ, ଏବଂ ଚାବି ନାମଗୁଡ଼ିକ କମା ଦ୍ବାରା ବିଭାଜିତ. ଦ୍ବିଗୁଣିତ ଚାବି ନିଷେଧ. ଅଜଣା ଚାବି ନାମଗୁଡ଼ିକ ଚୁପଚାପ " -"ଅଗ୍ରାହ୍ଯ କରାଯିବ, ଯାହା ଫଳେ ମେଟାସିଟିର ପୁରୁଣା ସଂସ୍କରଣଗୁଡ଼ିକୁ ପ୍ରଭାବିତ ନ କରି, ନୂଆ ସଂସ୍କରଣଗୁଡ଼ିକରେ " -"ଚାବି ଯୋଡ଼ି ହୋଇପାରିବ." - -#: ../src/metacity.schemas.in.in.h:8 -msgid "Automatically raises the focused window" -msgstr "କେନ୍ଦ୍ରିତ ୱିଣ୍ଡୋକୁ ଆପେଆପେ ସାମନାକୁ ଆଣେ" - -#: ../src/metacity.schemas.in.in.h:9 -#| msgid "" -#| "Clicking a window while holding down this modifier key will move the " -#| "window (left click), resize the window (middle click), or show the window " -#| "menu (right click). Modifier is expressed as \"<Alt>\" or \"<" -#| "Super>\" for example." +#: ../data/org.gnome.mutter.gschema.xml.in.h:4 msgid "" -"Clicking a window while holding down this modifier key will move the window " -"(left click), resize the window (middle click), or show the window menu " -"(right click). The left and right operations may be swapped using the " -"\"mouse_button_resize\" key. Modifier is expressed as \"<Alt>\" or " -"\"<Super>\" for example." +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." msgstr "" -"ଏହି ରୂପାନ୍ତରକ ଚାବିକି ଚାପି ୱିଣ୍ଡୋରେ ମାଉସ୍ ଚାବି ଦବାଇଲେ ୱିଣ୍ଡୋ ଘୁଞ୍ଚା ଯାଇପାରିବ (ବାମ ମାଉସ୍ ଚାବି), " -"ୱିଣ୍ଡୋ ଆକାର ବଦଳା ଯାଇପାରିବ (ମଝି ମାଉସ୍ ଚାବି), ବା ନର ମେନୁ ପ୍ରଦର୍ଶନ କରା ଯାଇପାରିବ (ଡାହାଣ " -"ମାଉସ୍ ଚାବି)। \"mouse_button_resize\" କୁ ବ୍ୟବହାର କରି ବାମ ଏବଂ ଡ଼ାହାଣ ପ୍ରୟୋଗକୁ " -"ବଦଳାଯାଇପାରିବ ରୂପାନ୍ତରକ ଚାବି \"<Alt>\" ବା \"<Super>\" " -"ଭାବରେ ଅଭିବ୍ଯକ୍ତ କରା ଯାଇପାରିବ।" - -#: ../src/metacity.schemas.in.in.h:10 -msgid "Commands to run in response to keybindings" -msgstr "ଚାବି ବନ୍ଧନ ସ୍ବରୂପେ ଚଳାଇବା ପାଇଁ ନିର୍ଦ୍ଦେଶ" - -#: ../src/metacity.schemas.in.in.h:11 -msgid "Compositing Manager" -msgstr "ମିଶ୍ରଣ ପରିଚାଳକ" - -#: ../src/metacity.schemas.in.in.h:12 -msgid "Control how new windows get focus" -msgstr "ନୂତନ ୱିଣ୍ଡୋଗୁଡ଼ିକ କିପରି ଲକ୍ଷ୍ୟ ସାଧନ କରିଥାନ୍ତି ତାହାକୁ ନିୟନ୍ତ୍ରଣ କରନ୍ତୁ" - -#: ../src/metacity.schemas.in.in.h:13 -msgid "Current theme" -msgstr "ସାମ୍ପ୍ରତିକ ପ୍ରସଙ୍ଗ" - -#: ../src/metacity.schemas.in.in.h:14 -msgid "Delay in milliseconds for the auto raise option" -msgstr "ସ୍ବଂୟ ସାମନାକୁ ଆଣିବା ପାଇଁ ମିଲିସେକଣ୍ଡରେ ବିଳମ୍ବ" +"ଯେତେବେଳେ ସତ୍ୟ ଅଟେ, ବ୍ୟକ୍ତିଗତ ଶୀର୍ଷକ ପଟି ପରିବର୍ତ୍ତେ, କ୍ରିୟାତ୍ମକ ସଂଳାପଗୁଡ଼ିକ " +"ମୂଖ୍ୟ ୱିଣ୍ଡୋର ଶୀର୍ଷକ " +"ପଟି ସହିତ ସଂଲଗ୍ନ ଥିବା ପରି ଲାଗିଥାଏ ଏବଂ ମୂଖ୍ୟ ୱିଣ୍ଡୋ ସହିତ ଗତି କରିଥାଏ।" -#: ../src/metacity.schemas.in.in.h:15 -msgid "Determines whether Metacity is a compositing manager." -msgstr "ନିର୍ଦ୍ଧାରିତ କରେ ମେଟାସିଟି ଗୋଟିଏ ମିଶ୍ରଣ ପରିଚାଳକ ବା ନୁହେଁ." +#: ../data/org.gnome.mutter.gschema.xml.in.h:5 +msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "ୱିଣ୍ଡୋଗୁଡ଼ିକୁ ପରଦା ଧାରରେ ରଖିବା ସମୟରେ ଧାର ଟାଇଲକୁ ସକ୍ରିୟ କରନ୍ତୁ" -#: ../src/metacity.schemas.in.in.h:16 +#: ../data/org.gnome.mutter.gschema.xml.in.h:6 msgid "" -"Determines whether applications or the system can generate audible 'beeps'; " -"may be used in conjunction with 'visual bell' to allow silent 'beeps'." +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." msgstr "" -"ନିର୍ଦ୍ଧାରିତ କରେ ପ୍ରୟୋଗ ବା ତନ୍ତ୍ର ଶ୍ରାବ୍ଯ 'ବିପ' ସୃଷ୍ଟି କରିପାରିବ କି; ଏହା ସହିତ 'ଚାକ୍ଷୁଷ ଘଣ୍ଟି' ଚୟନକୁ " -"ଯୋଡ଼ି ନିଃଶବ୍ଦ 'ବିପ' ହ୍ଯବହାର କରା ଯାଇରାରିବ." - -#: ../src/metacity.schemas.in.in.h:17 -msgid "Disable misfeatures that are required by old or broken applications" -msgstr "ପୁରୁଣା ବା ଅବୈଧ ପ୍ରୟୋଗ ପାଇଁ ଆବଶ୍ଯକ ଦୁର୍ଗୁଣଗୁଡ଼ିକୁ ଅସମର୍ଥ କରନ୍ତୁ" - -#: ../src/metacity.schemas.in.in.h:18 -msgid "Enable Visual Bell" -msgstr "ଚାକ୍ଷୁଷ ଘଣ୍ଟିକୁ ସମର୍ଥ କରନ୍ତୁ" - -#: ../src/metacity.schemas.in.in.h:19 -#| msgid "" -#| "If true, and the focus mode is either \"sloppy\" or \"mouse\" then the " -#| "focused window will be automatically raised after a delay (the delay is " -#| "specified by the auto_raise_delay key)." +"ଯଦି ସକ୍ରିୟ ଥାଏ, ତେବେ ୱିଣ୍ଡୋକୁ ଭୂ-ଲମ୍ବ ପରଦା ଧାରରେ ରଖିବା ଫଳରେ ତାହାର ଆକାର ଭୂଲମ୍ବ " +"ଆକାରରେ " +"ସର୍ବାଧିକ ହୋଇଥାଏ ଏବଂ ଉପଲବ୍ଧ ସ୍ଥାନରେ ସଜାଡ଼ିବା ପାଇଁ ଭୂ-ସମାନ୍ତରାଳରେ ଆକାର " +"ପରିବର୍ତ୍ତନ କରିଥାଏ।" +"ୱିଣ୍ଡୋଗୁଡ଼ିକୁ ପରଦାର ଉପର ସୀମାରେ ରଖିବା ଫଳରେ ତାହା ସମ୍ପୂର୍ଣ୍ଣ ଭାବରେ ଆକାର ବୃଦ୍ଧି " +"କରିଥାଏ।" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:7 +msgid "Workspaces are managed dynamically" +msgstr "କାର୍ଯ୍ୟକ୍ଷେତ୍ରଗୁଡ଼ିକ ଅସ୍ଥାୟୀ ଭାବରେ ପରିଚାଳିତ ହୋଇଥାଏ" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:8 msgid "" -"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " -"the focused window will be automatically raised after a delay specified by " -"the auto_raise_delay key. This is not related to clicking on a window to " -"raise it, nor to entering a window during drag-and-drop." +"Determines whether workspaces are managed dynamically or whether there's a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." msgstr "" -"ଏହା ସତ ହେଲେ, ଓ କେନ୍ଦ୍ରୀଭୂତ ଧାରା \"sloppy\" କିମ୍ବା \"mouse\" ଥିଲେ, କେନ୍ଦ୍ରିତ ୱିଣ୍ଡୋକୁ କିଛି ସମୟ " -"ପରେ ଆପେଆପେ ସାମନାକୁ ଅଣାଯିବ (auto_raise_delay କି ଦ୍ବାରା ନିର୍ଦ୍ଦିଷ୍ଟ କରାଯାଏ)" +"କାର୍ଯ୍ୟକ୍ଷେତ୍ରଗୁଡ଼ିକ ଅସ୍ଥାୟୀ ଭାବରେ ପରିଚାଳିତ ହୋଇଥାଏ କି ସେଠାରେ ସ୍ଥାୟୀ ସଂଖ୍ୟକ " +"କାର୍ଯ୍ୟକ୍ଷେତ୍ର " +"ଥାଏ ତାହା ନିର୍ଦ୍ଧାରଣ କରିଥାଏ (org.gnome.desktop.wm.preferences ଦ୍ୱାରା num-" +"workspaces କି ଦ୍ୱାରା ନିର୍ଦ୍ଧାରିତ ହୋଇଥାଏ)।" -#: ../src/metacity.schemas.in.in.h:20 -msgid "" -"If true, ignore the titlebar_font option, and use the standard application " -"font for window titles." -msgstr "" -"ଏହା ସତ ହେଲେ, ଶୀର୍ଷକପଟି_ଅକ୍ଷରରୂପ ପସନ୍ଦକୁ ଏଡ଼ାଇ, ୱିଣ୍ଡୋ ଶୀର୍ଷକ ପାଇଁ ସାଧାରଣ ପ୍ରୟୋଗ ଅକ୍ଷରରୂପ " -"ବ୍ଯବହାର କରନ୍ତୁ." - -#: ../src/metacity.schemas.in.in.h:21 -#, fuzzy -#| msgid "" -#| "If true, metacity will give the user less feedback and less sense of " -#| "\"direct manipulation\", by using wireframes, avoiding animations, or " -#| "other means. This is a significant reduction in usability for many users, " -#| "but may allow legacy applications and terminal servers to function when " -#| "they would otherwise be impractical. However, the wireframe feature is " -#| "disabled when accessibility is on to avoid weird desktop breakages." -msgid "" -"If true, metacity will give the user less feedback by using wireframes, " -"avoiding animations, or other means. This is a significant reduction in " -"usability for many users, but may allow legacy applications to continue " -"working, and may also be a useful tradeoff for terminal servers. However, " -"the wireframe feature is disabled when accessibility is on." -msgstr "" -"ଏହା ସତ ହେଲେ, ମେଟାସିଟି ତାର ଆକୃତି ବ୍ଯବହାର କରି, ଜୀବନାୟନଗୁଡ଼ିକୁ ଏଡ଼ାଇ, ବା ଅନ୍ଯ ଉପାୟ ଦ୍ବାରା " -"ବ୍ଯବହାରକାରୀକୁ କମ ପ୍ରତିକ୍ରିୟା, ଓ \"ପ୍ରତ୍ଯକ୍ଷ ପ୍ରକଳନ\"ର କମ ଭାବ ଦେବ. ଅନେକ ବ୍ଯବହାରକାରୀଙ୍କ " -"ଏହା ବ୍ଯବହାରଯୋଗ୍ଯତାକୁ ଢେର କମେଇ ଦିଏ, କିନ୍ତୁ ଏହା ଦ୍ବାରା ପୁରୁଣା ପ୍ରୟୋଗ ଓ ଟର୍ମିନାଲ ସେବକ ଚଲାଯାଇ " -"ପାରିବ, ନଚେତ୍ ଜେଉଁଟାକି ଅବ୍ଯବହାରିକ ରୁହନ୍ତା. ତଥାପି, ବ୍ଯବହାରସରଳତା ସକ୍ରିୟ କରାଯାଇଥିଲେ, ଅଦ୍ଭୁତ " -"ଡେସ୍କଟପ ସମସ୍ଯା ଏଡ଼ାଇବା ପାଇଁ, ତାର ଆକୃତି ନିଷ୍କ୍ରିୟ କରାଯିବ." +#: ../data/org.gnome.mutter.gschema.xml.in.h:9 +msgid "Workspaces only on primary" +msgstr "କାର୍ଯ୍ୟକ୍ଷେତ୍ର କେବଳ ପ୍ରାଥମିକ ସ୍ଥାନରେ ଥାଏ" -# Gora: not exactly translated. Bug report filed re: syntax/length -#: ../src/metacity.schemas.in.in.h:22 -#| msgid "" -#| "If true, then Metacity works in terms of applications rather than " -#| "windows. The concept is a bit abstract, but in general an application-" -#| "based setup is more like the Mac and less like Windows. When you focus a " -#| "window in application-based mode, all the windows in the application will " -#| "be raised. Also, in application-based mode, focus clicks are not passed " -#| "through to windows in other applications. The existence of this setting " -#| "is somewhat questionable. But it's better than having settings for all " -#| "the specific details of application-based vs. window-based, e.g. whether " -#| "to pass through clicks. Also, application-based mode is largely " -#| "unimplemented at the moment." -msgid "" -"If true, then Metacity works in terms of applications rather than windows. " -"The concept is a bit abstract, but in general an application-based setup is " -"more like the Mac and less like Windows. When you focus a window in " -"application-based mode, all the windows in the application will be raised. " -"Also, in application-based mode, focus clicks are not passed through to " -"windows in other applications. Application-based mode is, however, largely " -"unimplemented at the moment." -msgstr "" -"ଏହା ସତ ହେଲେ, ମେଟାସିଟି ୱିଣ୍ଡୋ ବଦଳରେ ପ୍ରୟୋଗର ଭାବରେ କାମ କରେ. ଏହି ଧାରଣାଟି ଟିକେ ଅମୂର୍ତ୍ତ, " -"କିନ୍ତୁ ସାଧାରଣରେ ପ୍ରୟୋଗ-ଆଧାରିତ ବ୍ଯବସ୍ଥାଟି ଅଧିକ ମାକ୍ ଭଳି ଓ କମ ମାଇକ୍ରୋସଫ୍ଟ ୱିଣ୍ଡୋଜ ଭଳି. ପ୍ରୟୋଗ-" -"ଆଧାରିତ ବ୍ଯବସ୍ଥାରେ ଆପଣ ଗୋଟିଏ ୱିଣ୍ଡୋକୁ କେନ୍ଦ୍ରିତ କଲେ, ପ୍ରୟୋଗର ସବୁ ୱିଣ୍ଡୋଗୁଡ଼ିକ ସାମନାକୁ ଅଣାଯିବ. " -"ପ୍ରୟୋଗ-ଆଧାରିତ ବ୍ଯବସ୍ଥାରେ ମଧ୍ଯ କେନ୍ଦ୍ରୀଭୂତ ମାଉସ୍ ଚାପ ଅଲଗା ପ୍ରୟୋଗର ୱିଣ୍ଡୋଗୁଡ଼ିକ ବଢ଼ାଇ ଦିଆଯାଏ " -"ନାହିଁ. ଏହି ବିନ୍ଯାସର ଅସ୍ତିତ୍ବ କିଛିଟି ସନ୍ଦେହଜନକ. କିନ୍ତୁ, ପ୍ରୟୋଗ-ଆଧାରିତ ଓ ୱିଣ୍ଡୋ-ଆଧାରିତ ଧାରାର ସବୁ " -"ବିସ୍ତୃତ ବିବରଣୀ ପାଇଁ ଅଲଗା ବିନ୍ଯାସ ରଖିବା ଅପେକ୍ଷା, ଏହା ଅଧିକ ଭଲ. ଏହି ସମୟରେ, ପ୍ରୟୋଗ-ଆଧାରିତ " -"ଧାରା ମୁଖ୍ଯତଃ ଅକାର୍ଯ୍ଯକାରୀ ରହିଛି." - -#: ../src/metacity.schemas.in.in.h:23 -msgid "If true, trade off usability for less resource usage" -msgstr "ଏହା ସତ ହେଲେ, ବ୍ଯବହାରଯୋଗ୍ଯତା କମାଇ ମଧ୍ଯ, କମ ସମ୍ବଳ ବ୍ଯବହାର କରନ୍ତୁ" - -#: ../src/metacity.schemas.in.in.h:24 -msgid "Modifier to use for modified window click actions" -msgstr "ରୂପାନ୍ତରିତ ୱିଣ୍ଡୋର ମାଉସ୍ ଚାପ କାର୍ଯ୍ଯଗୁଡ଼ିକ ପାଇଁ ରୂପାନ୍ତରକ" - -#: ../src/metacity.schemas.in.in.h:25 -msgid "Name of workspace" -msgstr "କାର୍ଯ୍ଯକ୍ଷେତ୍ରର ନାମ" - -#: ../src/metacity.schemas.in.in.h:26 -msgid "Number of workspaces" -msgstr "କାର୍ଯ୍ଯକ୍ଷେତ୍ରର ସଂଖ୍ଯା" - -#: ../src/metacity.schemas.in.in.h:27 -#| msgid "" -#| "Number of workspaces. Must be more than zero, and has a fixed maximum (to " -#| "prevent accidentally destroying your desktop by asking for 34 million " -#| "workspaces)." +#: ../data/org.gnome.mutter.gschema.xml.in.h:10 msgid "" -"Number of workspaces. Must be more than zero, and has a fixed maximum to " -"prevent making the desktop unusable by accidentally asking for too many " -"workspaces." +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." msgstr "" -"କାର୍ଯ୍ଯକ୍ଷେତ୍ରର ସଂଖ୍ଯା. ଏହା ଶୂନ୍ଯଠାରୁ ଅଧିକ ହେବା ବାଧ୍ଯ, ଓ ଏହାର ଗୋଟିଏ ସ୍ଥିର ସର୍ବାଧିକ ମୂଲ୍ଯ ଅଛି " -"(ଭୁଲରେ ୩୪୦ ଲକ୍ଷ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ନିର୍ଦ୍ଦଷ୍ଟ କରି ନିଜ ଡେସ୍କଟପକୁ ନଷ୍ଟ କରିବାରୁ ରୋକିବା ପାଇଁ)" +"ସମସ୍ତ ମନିଟର ଅଥବା କେବଳ ପ୍ରାଥମିକ ମନିଟରରେ ଥିବା କାର୍ଯ୍ୟକ୍ଷେତ୍ର ପରିବର୍ତ୍ତନ ହୋଇଥାଏ " +"ତାହା ନିର୍ଦ୍ଧାରଣ " +"କରିଥାଏ।" -#: ../src/metacity.schemas.in.in.h:28 -msgid "Run a defined command" -msgstr "ଗୋଟିଏ ନିର୍ଦ୍ଦଷ୍ଟ ନିର୍ଦ୍ଦେଶ ଚଳାନ୍ତୁ" +#: ../data/org.gnome.mutter.gschema.xml.in.h:11 +msgid "No tab popup" +msgstr "କୌଣସି ଟ୍ୟାବ ପପଅପ ନାହିଁ" -#: ../src/metacity.schemas.in.in.h:29 +#: ../data/org.gnome.mutter.gschema.xml.in.h:12 msgid "" -"Set this to true to resize with the right button and show a menu with the " -"middle button while holding down the key given in \"mouse_button_modifier\"; " -"set it to false to make it work the opposite way around." +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." msgstr "" +"ୱିଣ୍ଡୋ ଚକ୍ର ପାଇଁ ପପଅପ ଏବଂ ଆଲୋକିତ ଫ୍ରେମକୁ ବ୍ୟବହାରକୁ ନିଷ୍କ୍ରିୟ କରିବା ଉଚିତ କି " +"ନୁହଁ ତାହା ନିର୍ଦ୍ଧାରଣ " +"କରିଥାଏ।" -#: ../src/metacity.schemas.in.in.h:30 -msgid "" -"Setting this option to false can lead to buggy behavior, so users are " -"strongly discouraged from changing it from the default of true. Many actions " -"(e.g. clicking in the client area, moving or resizing the window) normally " -"raise the window as a side-effect. Setting this option to false, which is " -"strongly discouraged, will decouple raising from other user actions, and " -"ignore raise requests generated by applications. See http://bugzilla.gnome." -"org/show_bug.cgi?id=445447#c6. Even when this option is false, windows can " -"still be raised by an alt-left-click anywhere on the window, a normal click " -"on the window decorations, or by special messages from pagers, such as " -"activation requests from tasklist applets. This option is currently disabled " -"in click-to-focus mode. Note that the list of ways to raise windows when " -"raise_on_click is false does not include programmatic requests from " -"applications to raise windows; such requests will be ignored regardless of " -"the reason for the request. If you are an application developer and have a " -"user complaining that your application does not work with this setting " -"disabled, tell them it is _their_ fault for breaking their window manager " -"and that they need to change this option back to true or live with the \"bug" -"\" they requested." +#: ../data/org.gnome.mutter.gschema.xml.in.h:13 +msgid "Delay focus changes until the pointer stops moving" msgstr "" +"ସୂଚକ ଗତି କରିବା ବନ୍ଦ ନହେଲା ପର୍ଯ୍ୟନ୍ତ ଲକ୍ଷ୍ଯସ୍ଥଳ ପରିବର୍ତ୍ତନକୁ ବିଳମ୍ବ କରନ୍ତୁ" -#: ../src/metacity.schemas.in.in.h:31 +#: ../data/org.gnome.mutter.gschema.xml.in.h:14 msgid "" -"Some applications disregard specifications in ways that result in window " -"manager misfeatures. This option puts Metacity in a rigorously correct mode, " -"which gives a more consistent user interface, provided one does not need to " -"run any misbehaving applications." +"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " +"the focus will not be changed immediately when entering a window, but only " +"after the pointer stops moving." msgstr "" +"ଏହା ସତ ହେଲେ, ଓ କେନ୍ଦ୍ରୀଭୂତ ଧାରା \"sloppy\" କିମ୍ବା \"mouse\" ଥିଲେ ୱିଣ୍ଡୋ " +"ମଧ୍ଯରେ ଯିବା " +"ସମୟରେ ଲକ୍ଷ୍ଯସ୍ଥଳ ସଙ୍ଗେ ସଙ୍ଗେ ପରିବର୍ତ୍ତନ ହେବ ନାହିଁ, କିନ୍ତୁ କେବଳ ସୂଚକ ଗତି " +"କରିବା ବନ୍ଦ ହେଲେ " +"ସାମନାକୁ ଅଣାଯିବ।" -#: ../src/metacity.schemas.in.in.h:32 -msgid "System Bell is Audible" -msgstr "ତନ୍ତ୍ର ଘଣ୍ଟିଟି ଶ୍ରାବ୍ଯ" +#: ../data/org.gnome.mutter.gschema.xml.in.h:15 +msgid "Draggable border width" +msgstr "ଟଣାଯୋଗ୍ୟ ସୀମା ଓସାର" -#: ../src/metacity.schemas.in.in.h:33 +#: ../data/org.gnome.mutter.gschema.xml.in.h:16 msgid "" -"Tells Metacity how to implement the visual indication that the system bell " -"or another application 'bell' indicator has been rung. Currently there are " -"two valid values, \"fullscreen\", which causes a fullscreen white-black " -"flash, and \"frame_flash\" which causes the titlebar of the application " -"which sent the bell signal to flash. If the application which sent the bell " -"is unknown (as is usually the case for the default \"system beep\"), the " -"currently focused window's titlebar is flashed." +"The amount of total draggable borders. If the theme's visible borders are " +"not enough, invisible borders will be added to meet this value." msgstr "" -"ମେଟାସିଟି ପାଇଁ ନିର୍ଦ୍ଦିଷ୍ଟ କରେ ତନ୍ତ୍ରର ଘଣ୍ଟି ବା ଅନ୍ଯ ପ୍ରୟୋଗର ଘଣ୍ଟି ବାଜିବା କିପରି ଚାକ୍ଷୁଷ ଭାବରେ ସୂଚିତ " -"କରାଯିବ. ବର୍ତ୍ରମାନ ଦୁଇଟି ବୈଧ ମୂଲ୍ଯ ଅଛି, \"ପୂର୍ଣ୍ଣପରଦା\" ଯେଉଁଟାକି ପୂର୍ଣ୍ଣ ପରଦାଟିକୁ ଧଳାରୁ କଳା ଝଲସି " -"ଦିଏ, ଓ \"ବନ୍ଧେଇ_ଝଲସା\" ଯେଉଁଟାକି ଘଣ୍ଟି ସଙ୍କେତ ପଠାଇ ଥିବା ପ୍ରୟୋଗର ଶୀର୍ଷକ ପଟିକୁ ଝଲସି ଦିଏ. ଘଣ୍ଟି " -"ପଠାଇ ଥିବା ପ୍ରୟୋଗ ଅଜଣା ଥିଲେ (ଯେଉଁଟାକି ପୂର୍ବନିର୍ଦ୍ଧାରିତ \"ତନ୍ତ୍ର ବିପ୍\" ପାଇଁ ସାଧାରଣରେ ଘଟଣା), " -"ସାମ୍ପ୍ରତିକ କେନ୍ଦ୍ରିତ ୱିଣ୍ଡୋର ଶୀର୍ଷକ ପଟିକୁ ଝଲସି ଦିଆଯାଏ." +"ସମୁଦାୟ ଟଣାଯୋଗ୍ୟ ସୀମାର ପରିମାଣ। ଯଦି ପ୍ରସଙ୍ଗର ଦୃଶ୍ୟମାନ ସୀମାଗୁଡ଼ିକ ଯଥେଷ୍ଟ ନୁହଁ, " +"ଅଦୃଶ୍ୟ ସୀମାଗୁଡ଼ିକୁ " +"ମୂଲ୍ୟାଙ୍କନ ପାଇଁ ଯୋଗ କରାଯିବ।" -#: ../src/metacity.schemas.in.in.h:34 -msgid "" -"The /apps/metacity/global_keybindings/run_command_N keys define keybindings " -"that correspond to these commands. Pressing the keybinding for run_command_N " -"will execute command_N." -msgstr "" -"/ପ୍ରୟୋଗ/ମେଟାସିଟି/ସାମଗ୍ରି_ଚାବିବନ୍ଧନୀ/ନିର୍ଦ୍ଦେଶ_N_ଚଳାନ୍ତୁ ଚାବିଗୁଡ଼ିକ ଏହି ନିର୍ଦ୍ଦେଶଗୁଡ଼ିକ ଚାବିବନ୍ଧନୀ " -"ନିର୍ଦ୍ଦିଷ୍ଟ କରନ୍ତି. ନିର୍ଦ୍ଦେଶ_N_ଚଳାନ୍ତୁ ଚାବିବନ୍ଧନୀ ଦବାଇଲେ ନିର୍ଦ୍ଦେଶ_N ଚଳାଯିବ." +#: ../data/org.gnome.mutter.gschema.xml.in.h:17 +msgid "Auto maximize nearly monitor sized windows" +msgstr "ସ୍ୱୟଂଚାଳିତ ଭାବରେ ମନିଟର ଆକାରର ୱିଣ୍ଡୋ ବର୍ଦ୍ଧନ କରନ୍ତୁ" -#: ../src/metacity.schemas.in.in.h:35 +#: ../data/org.gnome.mutter.gschema.xml.in.h:18 msgid "" -"The /apps/metacity/global_keybindings/run_command_screenshot key defines a " -"keybinding which causes the command specified by this setting to be invoked." +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." msgstr "" -"/ପ୍ରୟୋଗ/ମେଟାସିଟି/ସାମଗ୍ରି_ଚାବିବନ୍ଧନୀ/ପରଦାପ୍ରତିଛବି_ନିର୍ଦ୍ଦେଶ_ଚଳାନ୍ତୁ ଚାବି ଗୋଟିଏ ଚାବିବନ୍ଧନୀ ନିର୍ଦ୍ଦିଷ୍ଟ " -"କରେ ଯେଉଁଟାକି ଏହି ବିନ୍ଯାସ ଦ୍ବାରା ଉଲ୍ଲେଖିତ ନିର୍ଦ୍ଦେଶକୁ ଆବାହନ କରେ," +"ଯଦି ସକ୍ରିୟ କରାଯାଏ, ନୂତନ ୱିଣ୍ଡୋଗୁଡ଼ିକ ଯାହାକି ପ୍ରଥମେ ମନିଟର ଆକାର ସ୍ୱୟଂଚାଳିତ " +"ଭାବରେ ବଢ଼ିଥାଏ।" -#: ../src/metacity.schemas.in.in.h:36 -msgid "" -"The /apps/metacity/global_keybindings/run_command_window_screenshot key " -"defines a keybinding which causes the command specified by this setting to " -"be invoked." -msgstr "" -"/ପ୍ରୟୋଗ/ମେଟାସିଟି/ସାମଗ୍ରି_ଚାବିବନ୍ଧନୀ/ୱିଣ୍ଡୋ_ପରଦାପ୍ରତିଛବି_ନିର୍ଦ୍ଦେଶ_ଚଳାନ୍ତୁ ଚାବି ଗୋଟିଏ ଚାବିବନ୍ଧନୀ " -"ନିର୍ଦ୍ଦିଷ୍ଟ କରେ ଯେଉଁଟାକି ଏହି ବିନ୍ଯାସ ଦ୍ବାରା ଉଲ୍ଲେଖିତ ନିର୍ଦ୍ଦେଶକୁ ଆବାହନ କରେ," +#: ../data/org.gnome.mutter.gschema.xml.in.h:19 +msgid "Place new windows in the center" +msgstr "କେନ୍ଦ୍ରରେ ନୂତନ ୱିଣ୍ଡୋଗୁଡ଼ିକୁ ରଖନ୍ତୁ" -#: ../src/metacity.schemas.in.in.h:37 +#: ../data/org.gnome.mutter.gschema.xml.in.h:20 msgid "" -"The keybinding that runs the correspondingly-numbered command in /apps/" -"metacity/keybinding_commands The format looks like \"<Control>a\" or " -"\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -"lower or upper case, and also abbreviations such as \"<Ctl>\" and " -"\"<Ctrl>\". If you set the option to the special string \"disabled\", " -"then there will be no keybinding for this action." +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." msgstr "" -"ଚାବିବନ୍ଧନୀ ଯେଉଁଟାକି /ପ୍ରୟୋଗ/ମେଟାସିଟି/ଚାବିବନ୍ଧନୀ_ନିର୍ଦ୍ଦେଶ ର ସଙ୍ଗତ ନିର୍ଦ୍ଦେଶକୁ ଚଳାଏ. ସଜ୍ଜିକରଣ " -"ଶୈଳୀ ହେଲା \"<Control>a\" ବା \"<Shift><Alt>F1\". ବିଶ୍ଳେଷକଟି " -"ବେଶ୍ ଉଦାରମନା, ଓ ଛୋଟ ବା ବଡ଼ ଅକ୍ଷର, ଏବଂ \"<Ctl>\", \"<Ctrl>\" ଭଳି " -"ସଂକ୍ଷେପ ମଧ୍ଯ ଗ୍ରହଣ କରେ. ଆପଣ ଏହି ଚୟନକୁ ବିଶେଷ ବାକ୍ଯଖଣ୍ଡ \"disabled\" ରୂପେ ବିନ୍ଯାସ କଲେ, ଏହି " -"କାର୍ଯ୍ଯ ପାଇଁ ଚାବିବନ୍ଧନୀ ରହିବ ନାହିଁ." - -#: ../src/metacity.schemas.in.in.h:38 -msgid "The name of a workspace." -msgstr "ଗୋଟିଏ କାର୍ଯ୍ଯକ୍ଷେତ୍ରର ନାମ." - -#: ../src/metacity.schemas.in.in.h:39 -msgid "The screenshot command" -msgstr "ପରଦା ପ୍ରତିଛବି ନିର୍ଦ୍ଦେଶ" - -#: ../src/metacity.schemas.in.in.h:40 -msgid "" -"The theme determines the appearance of window borders, titlebar, and so " -"forth." -msgstr "ପ୍ରସଙ୍ଗଟି ୱିଣ୍ଡୋ ଧାର, ଶୀର୍ଷକପଟି, ଇତ୍ଯାଦିର ଚେହେରା ସ୍ଥିର କରେ." +"ଯଦି true, ତେବେ ନୂତନ ୱିଣ୍ଡୋଗୁଡ଼ିକୁ ସର୍ବଦା ମନିଟରର ସକ୍ରିୟ ପରଦାର କେନ୍ଦ୍ରରେ ରଖାଯିବ।" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:21 +msgid "Select window from tab popup" +msgstr "ଟ୍ୟାବ ପପଅପରୁ ୱିଣ୍ଡୋକୁ ବାଛନ୍ତୁ" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:22 +msgid "Cancel tab popup" +msgstr "ଟ୍ୟାବ ପପଅପକୁ ବାତିଲ କରନ୍ତୁ" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:1 +#| msgid "Switch to workspace 1" +msgid "Switch to VT 1" +msgstr "VT 1 କୁ ବଦଳାନ୍ତୁ" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:2 +#| msgid "Switch to workspace 2" +msgid "Switch to VT 2" +msgstr "VT 2 କୁ ବଦଳାନ୍ତୁ" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:3 +#| msgid "Switch to workspace 3" +msgid "Switch to VT 3" +msgstr "VT 3 କୁ ବଦଳାନ୍ତୁ" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:4 +#| msgid "Switch to workspace 4" +msgid "Switch to VT 4" +msgstr "VT 4 କୁ ବଦଳାନ୍ତୁ" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:5 +#| msgid "Switch to workspace 5" +msgid "Switch to VT 5" +msgstr "VT 5 କୁ ବଦଳାନ୍ତୁ" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:6 +#| msgid "Switch to workspace 6" +msgid "Switch to VT 6" +msgstr "VT 6 କୁ ବଦଳାନ୍ତୁ" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:7 +#| msgid "Switch to workspace 7" +msgid "Switch to VT 7" +msgstr "VT 7 କୁ ବଦଳାନ୍ତୁ" + +#: ../src/backends/meta-monitor-manager.c:412 +msgid "Built-in display" +msgstr "ଅନ୍ତଃନିର୍ମିତ ପ୍ରଦର୍ଶନୀ" + +#: ../src/backends/meta-monitor-manager.c:437 +msgid "Unknown" +msgstr "ଅଜଣା" + +#: ../src/backends/meta-monitor-manager.c:439 +msgid "Unknown Display" +msgstr "ଅଜଣା ପ୍ରଦର୍ଶନୀ" + +#. TRANSLATORS: this is a monitor vendor name, followed by a +#. * size in inches, like 'Dell 15"' +#. +#: ../src/backends/meta-monitor-manager.c:447 +#, c-format +msgid "%s %s" +msgstr "%s %s" -#: ../src/metacity.schemas.in.in.h:41 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: ../src/compositor/compositor.c:443 +#, c-format msgid "" -"The time delay before raising a window if auto_raise is set to true. The " -"delay is given in thousandths of a second." +"Another compositing manager is already running on screen %i on display \"%s" +"\"." msgstr "" -"ଯଦି ସ୍ବଂୟ_ସାମନାକୁ_ଆଣିବା ସତ ହୋଇଥାଏ, ୱିଣ୍ଡୋକୁ ସାମନାକୁ ଆଣିବା ପୂର୍ବରୁ ମଧ୍ଯବର୍ତ୍ତୀ ସମୟ. ବିଳମ୍ବଟି " -"ମିଲିସେକଣ୍ଡରେ ନିର୍ଦ୍ଧିଷ୍ଟ ହୋଇଥାଏ.." +"ଅନ୍ୟ ଏକ ମିଶ୍ରିତ ପରିଚାଳକ ପୂର୍ବରୁ ପରଦା %i ଉପରେ ପ୍ରଦର୍ଶନୀ \"%s\" ରେ ଚାଲୁଅଛି।" -#: ../src/metacity.schemas.in.in.h:42 -msgid "" -"The window focus mode indicates how windows are activated. It has three " -"possible values; \"click\" means windows must be clicked in order to focus " -"them, \"sloppy\" means windows are focused when the mouse enters the window, " -"and \"mouse\" means windows are focused when the mouse enters the window and " -"unfocused when the mouse leaves the window." -msgstr "" -"ୱିଣ୍ଡୋ କେନ୍ଦ୍ରୀଭୂତ ଧାରା ନିର୍ଦ୍ଧିଷ୍ଟ କରେ ୱିଣ୍ଡୋଗୁଡ଼ିକ କିପରି ସକ୍ରିୟ କରାଯିବ. ଏହାର ତିନୋଟି ମୂଲ୍ଯ ସମ୍ଭବ; " -"\"ଚାପ\" ମାନେ ୱିଣ୍ଡୋଗୁଡ଼ିକ କେନ୍ଦ୍ରିତ କରିବା ପାଇଁ ତାଙ୍କ ଦେହରେ ମାଉସ୍ ଦବାଇବାକୁ ପଡ଼ିବ, \"ଅଯତ୍ନକୃତ\" " -"ମାନେ ମାଉସ୍ ୱିଣ୍ଡୋରେ ପ୍ରବେଶ କଲେ ୱିଣ୍ଡୋଟି କେନ୍ଦ୍ରିତ ହେବ, ଓ \"ମାଉସ\" ମାନେ ମାଉସ୍ ୱିଣ୍ଡୋରେ " -"ପ୍ରବେଶ କଲେ ୱିଣ୍ଡୋଟି କେନ୍ଦ୍ରିତ ହେବ ଏବଂ ୱିଣ୍ଡୋରୁ ବାହାରିଲେ ୱିଣ୍ଡୋଟି ଅକେନ୍ଦ୍ରିତ ହେବ." - -#: ../src/metacity.schemas.in.in.h:43 -msgid "The window screenshot command" -msgstr "ୱିଣ୍ଡୋ ପରଦା ପ୍ରତିଛବି ନିର୍ଦ୍ଦେଶ" - -#: ../src/metacity.schemas.in.in.h:44 -#| msgid "" -#| "This option determines the effects of double-clicking on the title bar. " -#| "Current valid options are 'toggle_shade', which will shade/unshade the " -#| "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#| "'minimize' which will minimize the window, and 'none' which will not do " -#| "anything." -msgid "" -"This option determines the effects of double-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, 'toggle_maximize' which will maximize/unmaximize the window, " -"'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which will " -"maximize/unmaximize the window in that direction only, 'minimize' which will " -"minimize the window, 'shade' which will roll the window up, 'menu' which " -"will display the window menu, 'lower' which will put the window behind all " -"the others, and 'none' which will not do anything." -msgstr "" -"ଏହି ଚୟନ ଶୀର୍ଷକପଟି ଉପରେ ଦୁଇଥର ଦବାଇବାର ପ୍ରଭାବ ନିର୍ଦ୍ଧିଷ୍ଟ କରେ. ସାମ୍ପ୍ରତିକ ବୈଧ ମୂଲ୍ଯଗୁଡ଼ିକ ହେଲା " -"'toggle_shade' ଯେଉଁଟାକି ୱିଣ୍ଡୋକୁ ଘୋଢାଇବ ବା ପ୍ରକାଶିତ କରିବ, 'toggle_maximize' ଯେଉଁଟାକି " -"ୱିଣ୍ଡୋକୁ ବୃହତ୍ତମନ କରିବ ବା ବୃହତ୍ତମରୁ ଛୋଟ କରିବ, ଓ 'none' ଯେଉଁଟାକି କିଛି କରିବ ନାହିଁ." - -#: ../src/metacity.schemas.in.in.h:45 -#| msgid "" -#| "This option determines the effects of double-clicking on the title bar. " -#| "Current valid options are 'toggle_shade', which will shade/unshade the " -#| "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#| "'minimize' which will minimize the window, and 'none' which will not do " -#| "anything." -msgid "" -"This option determines the effects of middle-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, 'toggle_maximize' which will maximize/unmaximize the window, " -"'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which will " -"maximize/unmaximize the window in that direction only, 'minimize' which will " -"minimize the window, 'shade' which will roll the window up, 'menu' which " -"will display the window menu, 'lower' which will put the window behind all " -"the others, and 'none' which will not do anything." -msgstr "" -"ଏହି ଚୟନ ଶୀର୍ଷକପଟି ଉପରେ ଦୁଇଥର ଦବାଇବାର ପ୍ରଭାବ ନିର୍ଦ୍ଧିଷ୍ଟ କରେ. ସାମ୍ପ୍ରତିକ ବୈଧ ମୂଲ୍ଯଗୁଡ଼ିକ ହେଲା " -"'toggle_shade' ଯେଉଁଟାକି ୱିଣ୍ଡୋକୁ ଘୋଢାଇବ ବା ପ୍ରକାଶିତ କରିବ, 'toggle_maximize' ଯେଉଁଟାକି " -"ୱିଣ୍ଡୋକୁ ବୃହତ୍ତମନ କରିବ ବା ବୃହତ୍ତମରୁ ଛୋଟ କରିବ, ଓ 'none' ଯେଉଁଟାକି କିଛି କରିବ ନାହିଁ." +#: ../src/core/bell.c:185 +msgid "Bell event" +msgstr "ବେଲ ଘଟଣା" -#: ../src/metacity.schemas.in.in.h:46 -#, fuzzy -#| msgid "" -#| "This option determines the effects of double-clicking on the title bar. " -#| "Current valid options are 'toggle_shade', which will shade/unshade the " -#| "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#| "'minimize' which will minimize the window, and 'none' which will not do " -#| "anything." -msgid "" -"This option determines the effects of right-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, 'toggle_maximize' which will maximize/unmaximize the window, " -"'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which will " -"maximize/unmaximize the window in that direction only, 'minimize' which will " -"minimize the window, 'shade' which will roll the window up, 'menu' which " -"will display the window menu, 'lower' which will put the window behind all " -"the others, and 'none' which will not do anything." -msgstr "" -"ଏହି ଚୟନ ଶୀର୍ଷକପଟି ଉପରେ ଦୁଇଥର ଦବାଇବାର ପ୍ରଭାବ ନିର୍ଦ୍ଧିଷ୍ଟ କରେ. ସାମ୍ପ୍ରତିକ ବୈଧ ମୂଲ୍ଯଗୁଡ଼ିକ ହେଲା " -"'toggle_shade' ଯେଉଁଟାକି ୱିଣ୍ଡୋକୁ ଘୋଢାଇବ ବା ପ୍ରକାଶିତ କରିବ, 'toggle_maximize' ଯେଉଁଟାକି " -"ୱିଣ୍ଡୋକୁ ବୃହତ୍ତମନ କରିବ ବା ବୃହତ୍ତମରୁ ଛୋଟ କରିବ, ଓ 'none' ଯେଉଁଟାକି କିଛି କରିବ ନାହିଁ." +#: ../src/core/delete.c:127 +#, c-format +msgid "“%s” is not responding." +msgstr "“%s” ଉତ୍ତର ଦେଉ ନାହିଁ।" -#: ../src/metacity.schemas.in.in.h:47 -msgid "" -"This option provides additional control over how newly created windows get " -"focus. It has two possible values; \"smart\" applies the user's normal focus " -"mode, and \"strict\" results in windows started from a terminal not being " -"given focus." -msgstr "" +#: ../src/core/delete.c:129 +msgid "Application is not responding." +msgstr "ପ୍ରୟୋଗଟି ଉତ୍ତର ଦେଉ ନାହିଁ।" -#: ../src/metacity.schemas.in.in.h:48 -#, fuzzy -#| msgid "" -#| "Turns on a visual indication when an application or the system issues a " -#| "'bell' or 'beep'; useful for the hard-of-hearing and for use in noisy " -#| "environments, or when 'audible bell' is off." +#: ../src/core/delete.c:134 msgid "" -"Turns on a visual indication when an application or the system issues a " -"'bell' or 'beep'; useful for the hard-of-hearing and for use in noisy " -"environments." +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." msgstr "" -"ଗୋଟିଏ ପ୍ରୟୋଗ ବା ତନ୍ତ୍ର 'ଘଣ୍ଟି' ବା 'ବିପ' କଲେ, ଏକ ଚାକ୍ଷୁଷ ସୂଚକ ବ୍ଯବହାର କରେ; ଏହା କାଲ ଲୋକଙ୍କ " -"ପାଇଁ ବା କୋଲାହଳପୂର୍ଣ୍ଣ ପରିବେଶରେ ବା 'ଶ୍ରାବ୍ଯ ଘଣ୍ଟି' ଚାଲୁ ନ ଥିଲେ ଉପକାରୀ" - -#: ../src/metacity.schemas.in.in.h:49 -msgid "Use standard system font in window titles" -msgstr "ୱିଣ୍ଡୋ ଶୀର୍ଷକରେ ତନ୍ତ୍ରର ସାଧାରଣ ଅକ୍ଷରରୂପ ବ୍ଯବହାର କରନ୍ତୁ" - -#: ../src/metacity.schemas.in.in.h:50 -msgid "Visual Bell Type" -msgstr "ଚାକ୍ଷୁଷ ଘଣ୍ଟି ପ୍ରକାର" +"ଏହାକୁ ଅଗ୍ରସର କରିବା ପାଇଁ ଆପଣ କିଛି କ୍ଷଣ ଅପେକ୍ଷା କରିପାରିବେ ଅଥବା ପ୍ରୟୋଗରୁ ବିଦାୟ " +"ନେବା ପାଇଁ " +"ବାଧ୍ଯକରିପାରିବେ।" -#: ../src/metacity.schemas.in.in.h:51 -msgid "Whether raising should be a side-effect of other user interactions" -msgstr "ସାମନାକୁ ଆଣିବା ଅନ୍ଯ ବ୍ଯବହାରକାରୀ ପାରସ୍ପରିକ କ୍ରିୟାର ଅବାଂଛିତ ପ୍ରତିକ୍ରିୟା ହେବା ଉଚିତ କି" +#: ../src/core/delete.c:141 +msgid "_Wait" +msgstr "_ଅପେକ୍ଷା କର" -#: ../src/metacity.schemas.in.in.h:52 -msgid "Whether to resize with the right button" -msgstr "ଡ଼ାହାଣ ବଟନ ଦ୍ୱାରା ଆକାର ପରିବର୍ତ୍ତନ କରାଯିବ କି" +#: ../src/core/delete.c:141 +msgid "_Force Quit" +msgstr "ବିଦାୟ ନେବାକୁ ବାଧ୍ଯ କରନ୍ତୁ (_F)" -#: ../src/metacity.schemas.in.in.h:53 -msgid "Window focus mode" -msgstr "ୱିଣ୍ଡୋ କେନ୍ଦ୍ରୀଭୂତ ଧାରା" +#: ../src/core/display.c:547 +#, c-format +msgid "Failed to open X Window System display '%s'\n" +msgstr "ଏକ୍ସ ୱିଣ୍ଡୋ ତନ୍ତ୍ରର ପ୍ରଦର୍ଶିକା '%s' ଖୋଲିବାରେ ଅସମର୍ଥ\n" -#: ../src/metacity.schemas.in.in.h:54 -msgid "Window title font" -msgstr "ୱିଣ୍ଡୋ ଶୀର୍ଷକ ଅକ୍ଷରରୂପ" +#: ../src/core/main.c:176 +msgid "Disable connection to session manager" +msgstr "ଅଧିବେଶନ ପରିଚାଳକ ସଙ୍ଗେ ସଂଯୋଗ ନିଷ୍କ୍ରିୟ କରନ୍ତୁ" -#: ../src/tools/metacity-message.c:150 -#, c-format -msgid "Usage: %s\n" -msgstr "ବ୍ଯବହାର: %s\n" +#: ../src/core/main.c:182 +msgid "Replace the running window manager" +msgstr "ଚଳନ୍ତା ୱିଣ୍ଡୋ ପରିଚାଳକକୁ ବଦଳାନ୍ତୁ" -#: ../src/ui/frames.c:1118 -msgid "Close Window" -msgstr "ୱିଣ୍ଡୋ ବନ୍ଦ କରନ୍ତୁ" +#: ../src/core/main.c:188 +msgid "Specify session management ID" +msgstr "ଅଧିବେଶନ ପରିଚାଳନ ପରିଚୟ ନିର୍ଦ୍ଦିଷ୍ଟ କରନ୍ତୁ" -#: ../src/ui/frames.c:1121 -msgid "Window Menu" -msgstr "ୱିଣ୍ଡୋ ମେନୁ" +#: ../src/core/main.c:193 +msgid "X Display to use" +msgstr "ବ୍ଯବହାର ପାଇଁ ଏକ୍ସ ପ୍ରଦର୍ଶକ" -#: ../src/ui/frames.c:1124 -msgid "Minimize Window" -msgstr "ୱିଣ୍ଡୋକୁ କ୍ଷୁଦ୍ରତମ କରନ୍ତୁ" +#: ../src/core/main.c:199 +msgid "Initialize session from savefile" +msgstr "ଅଧିବେଶନକୁ ସଞ୍ଚିତ ଫାଇଲଠାରୁ ପ୍ରାରମ୍ଭ କରନ୍ତୁ" -#: ../src/ui/frames.c:1127 -msgid "Maximize Window" -msgstr "ୱିଣ୍ଡୋକୁ ବୃହତ୍ତମ କରନ୍ତୁ" +#: ../src/core/main.c:205 +msgid "Make X calls synchronous" +msgstr "ଏକ୍ସ ଡାକରା ସମକାଳିତ କରନ୍ତୁ" -#: ../src/ui/frames.c:1130 -#| msgid "Resize window" -msgid "Restore Window" -msgstr "ୱିଣ୍ଡୋକୁ ପୁନଃସ୍ଥାପନ କରନ୍ତୁ" +#: ../src/core/main.c:212 +msgid "Run as a wayland compositor" +msgstr "ୱେଲ୍ୟାଣ୍ଡ ଯୋଜନାକାରୀ ଭାବରେ ଚଲାନ୍ତୁ" -#: ../src/ui/frames.c:1133 -#| msgid "Roll _Up" -msgid "Roll Up Window" -msgstr "ୱିଣ୍ଡୋକୁ ଗଡ଼ାନ୍ତୁ" - -#: ../src/ui/frames.c:1136 -#| msgid "Close Window" -msgid "Unroll Window" -msgstr "ୱିଣ୍ଡୋକୁ ଗଡ଼ାଇବା ବନ୍ଦ କରନ୍ତୁ" - -#: ../src/ui/frames.c:1139 -msgid "Keep Window On Top" -msgstr "ୱିଣ୍ଡୋକୁ ଉପରେ ରଖନ୍ତୁ" - -#: ../src/ui/frames.c:1142 -msgid "Remove Window From Top" -msgstr "ୱିଣ୍ଡୋକୁ ଉପରୁ କାଢ଼ନ୍ତୁ" - -#: ../src/ui/frames.c:1145 -#| msgid "_Always on Visible Workspace" -msgid "Always On Visible Workspace" -msgstr "ସଦାବେଳେ ଦୃଶ୍ଯମାନ କାର୍ଯ୍ଯକ୍ଷେତ୍ରରେ ଥାଏ" - -#: ../src/ui/frames.c:1148 -#| msgid "Toggle window on all workspaces" -msgid "Put Window On Only One Workspace" -msgstr "ୱିଣ୍ଡୋକୁ କେବଳ ଗୋଟିଏ କାର୍ଯ୍ଯକ୍ଷେତ୍ରରେ ରଖନ୍ତୁ" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:70 -msgid "Mi_nimize" -msgstr "କ୍ଷୁଦ୍ରତମ କରନ୍ତୁ (_n)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:72 -msgid "Ma_ximize" -msgstr "ବୃହତ୍ତମ କରନ୍ତୁ (_x)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:74 -msgid "Unma_ximize" -msgstr "ସାଧାରଣ ଆକାର ଦିଅନ୍ତୁ (_x)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:76 -msgid "Roll _Up" -msgstr "ଉପରକୁ ଗୁଡ଼ାନ୍ତୁ (_U)" +#: ../src/core/main.c:220 +msgid "Run as a full display server, rather than nested" +msgstr "ସମ୍ପୂର୍ଣ୍ଣ ପ୍ରଦର୍ଶନୀ ସର୍ଭର ଭାବରେ ଚଲାନ୍ତୁ, ସଂଲଗ୍ନ ଭାବରେ ବ୍ୟବହାର ନକରି" -# Should have been "ଗୁଡ଼ା ହୋଇଥିବାକୁ ଖୋଲନ୍ତୁ". Shortened for menu -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:78 -msgid "_Unroll" -msgstr "ଖୋଲନ୍ତୁ (_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:80 -msgid "_Move" -msgstr "ଘୁଞ୍ଚାନ୍ତୁ (_M)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:82 -msgid "_Resize" -msgstr "ଆକାର ବଦଳାନ୍ତୁ (_R)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:84 -msgid "Move Titlebar On_screen" -msgstr "ଶୀର୍ଷକ ପରଦାକୁ ପଟି ଘୁଞ୍ଚାନ୍ତୁ (_s)" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:87 ../src/ui/menu.c:89 -msgid "Always on _Top" -msgstr "ସର୍ବଦା ଉପରେ (_T)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:91 -msgid "_Always on Visible Workspace" -msgstr "ସଦାବେଳେ ଦୃଶ୍ଯମାନ କାର୍ଯ୍ଯକ୍ଷେତ୍ରରେ (_A)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:93 -msgid "_Only on This Workspace" -msgstr "କେବଳ ଏହି କାର୍ଯ୍ଯକ୍ଷେତ୍ରରେ (_O)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:95 -msgid "Move to Workspace _Left" -msgstr "ବାମ କାର୍ଯ୍ଯକ୍ଷେତ୍ରକୁ ପଠାନ୍ତୁ (_L)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:97 -msgid "Move to Workspace R_ight" -msgstr "ଡାହାଣ କାର୍ଯ୍ଯକ୍ଷେତ୍ରକୁ ପଠାନ୍ତୁ (_R)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:99 -msgid "Move to Workspace _Up" -msgstr "ଉପର କାର୍ଯ୍ଯକ୍ଷେତ୍ରକୁ ପଠାନ୍ତୁ (_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:101 -msgid "Move to Workspace _Down" -msgstr "ତଳ କାର୍ଯ୍ଯକ୍ଷେତ୍ରକୁ ପଠାନ୍ତୁ (_D)" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:105 -msgid "_Close" -msgstr "ବନ୍ଦ କରନ୍ତୁ (_C)" - -#: ../src/ui/menu.c:203 -#, c-format -#| msgid "Workspace %d" -msgid "Workspace %d%n" -msgstr "କାର୍ଯ୍ଯକ୍ଷେତ୍ର %d%n" - -#: ../src/ui/menu.c:213 -#, c-format -msgid "Workspace 1_0" -msgstr "କାର୍ଯ୍ଯକ୍ଷେତ୍ର 1_0" - -#: ../src/ui/menu.c:215 -#, c-format -msgid "Workspace %s%d" -msgstr "କାର୍ଯ୍ଯକ୍ଷେତ୍ର %s%d" - -#: ../src/ui/menu.c:395 -msgid "Move to Another _Workspace" -msgstr "ଅଲଗା କାର୍ଯ୍ଯକ୍ଷେତ୍ରକୁ ପଠାନ୍ତୁ (_W)" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:104 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:110 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:116 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:122 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:128 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:134 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:140 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:146 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:152 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:158 -msgid "Mod5" -msgstr "Mod5" +#: ../src/core/main.c:451 +#, c-format +msgid "Failed to scan themes directory: %s\n" +msgstr "ପ୍ରସଙ୍ଗ ଡିରେକ୍ଟୋରି: %sକୁ କ୍ରମବୀକ୍ଷଣ କରିବାରେ ଅସମର୍ଥ\n" -#: ../src/ui/metacity-dialog.c:90 +#: ../src/core/main.c:467 #, c-format -#| msgid "The window \"%s\" is not responding." -msgid "\"%s\" is not responding." -msgstr "\"%s\"ରୁ ଉତ୍ତର ମିଳୁ ନାହିଁ।" +msgid "" +"Could not find a theme! Be sure %s exists and contains the usual themes.\n" +msgstr "" +"ପ୍ରସଙ୍ଗ ମିଳିଲା ନାହିଁ! ନିଶ୍ଚିତ କରନ୍ତୁ କି %s ବାସ୍ତବରେ ଅଛି ଓ ତାହା ଭିତରେ ସାଧାରଣ " +"ପ୍ରସଙ୍ଗଗୁଡ଼ିକ ରହିଛି।\n" -#: ../src/ui/metacity-dialog.c:97 +#: ../src/core/mutter.c:39 +#, c-format msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." +"mutter %s\n" +"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" msgstr "" +"mutter %s\n" +"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" -#: ../src/ui/metacity-dialog.c:107 -msgid "_Wait" -msgstr "_ଅପେକ୍ଷା କର" +#: ../src/core/mutter.c:53 +msgid "Print version" +msgstr "ସଂସ୍କରଣ ମୁଦ୍ରଣ କରନ୍ତୁ" -#: ../src/ui/metacity-dialog.c:109 -msgid "_Force Quit" -msgstr "ବିଦାୟ ନେବାକୁ ବାଧ୍ଯ କରନ୍ତୁ (_F)" +#: ../src/core/mutter.c:59 +msgid "Mutter plugin to use" +msgstr "ବ୍ୟବହାର କରିବାକୁ ଥିବା Mutter ପ୍ଲଗଇନ" -#: ../src/ui/metacity-dialog.c:206 -msgid "Title" -msgstr "ଶୀର୍ଷକ" +#: ../src/core/prefs.c:2106 +#, c-format +msgid "Workspace %d" +msgstr "କାର୍ଯ୍ଯକ୍ଷେତ୍ର %d" -#: ../src/ui/metacity-dialog.c:218 -msgid "Class" -msgstr "ଶ୍ରେଣୀ" +#: ../src/core/screen.c:543 +#, c-format +msgid "Screen %d on display '%s' is invalid\n" +msgstr "ପ୍ରଦର୍ଶକ '%2$s'ରେ ପରଦା %1$d ଅବୈଧ\n" -#: ../src/ui/metacity-dialog.c:244 +#: ../src/core/screen.c:559 +#, c-format msgid "" -"These windows do not support \"save current setup\" and will have to be " -"restarted manually next time you log in." +"Screen %d on display \"%s\" already has a window manager; try using the --" +"replace option to replace the current window manager.\n" msgstr "" -"ଏହି ୱିଣ୍ଡୋଗୁଡ଼ିକର \"ସାମ୍ପ୍ରତିକ ବ୍ଯବସ୍ଥା ସଂରକ୍ଷଣ\" ସହାୟକ ନାହିଁ, ଏବଂ ଆପଣ ପୁଣି ଲଗଇନ୍ କଲେ " -"ଏହୋଙ୍କୁନିଜେ ପୁନଃ ପ୍ରାରମ୍ଭ କରିବାକୁ ହେବ." +"ପ୍ରଦର୍ଶକ \"%2$s\"ରେ ପରଦା %1$dର ପୂର୍ବରୁ ଗୋଟିଏ ୱିଣ୍ଢୋ ପରିଚାଳକ ଅଛି; ସାମ୍ପ୍ରତିକ " +"ୱିଣ୍ଢୋ ପରିଚାଳକକୁ " +"ବଦଳାଇବା ପାଇଁ, ବଦଳ ଚୟନ ବ୍ଯବହାର କରିବାକୁ ଚେଷ୍ଟା କରନ୍ତୁ.\n" -#: ../src/ui/metacity-dialog.c:310 +#: ../src/core/screen.c:652 #, c-format -msgid "" -"There was an error running \"%s\":\n" -"%s." -msgstr "" -"\"%s\" ଚଳେବାରେ ତ୍ରୁଟି:\n" -"%s." +msgid "Screen %d on display \"%s\" already has a window manager\n" +msgstr "ପ୍ରଦର୍ଶକ \"%2$s\"ରେ ପରଦା %1$dର ପୂର୍ବରୁ ଗୋଟିଏ ୱିଣ୍ଢୋ ପରିଚାଳକ ଅଛି\n" + +#: ../src/core/util.c:118 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter ଶବ୍ଦଡମ୍ବରପୂର୍ଣ୍ଣ ଧାରାରେ ସହାୟକ ବିନା ସଂକଳିତ ହୋଇଥିଲା\n" #. Translators: This represents the size of a window. The first number is #. * the width of the window and the second is the height. #. -#: ../src/ui/resizepopup.c:113 +#: ../src/ui/resizepopup.c:134 #, c-format msgid "%d x %d" msgstr "%d x %d" -#: ../src/ui/theme.c:254 +#: ../src/ui/theme.c:233 msgid "top" msgstr "ଉପର" -#: ../src/ui/theme.c:256 +#: ../src/ui/theme.c:235 msgid "bottom" msgstr "ତଳ" -#: ../src/ui/theme.c:258 +#: ../src/ui/theme.c:237 msgid "left" msgstr "ବାମ" -#: ../src/ui/theme.c:260 +#: ../src/ui/theme.c:239 msgid "right" msgstr "ଡାହାଣ" -#: ../src/ui/theme.c:287 +#: ../src/ui/theme.c:267 #, c-format msgid "frame geometry does not specify \"%s\" dimension" msgstr "ବନ୍ଧେଇ ଜ୍ଯାମିତି \"%s\" ପରିସର ନିର୍ଦ୍ଦିଷ୍ଟ କରି ନାହିଁ" -#: ../src/ui/theme.c:306 +#: ../src/ui/theme.c:286 #, c-format msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" msgstr "ବନ୍ଧେଇ ଜ୍ଯାମିତି \"%2$s\" ଧାର ଫାଇଁ \"%1$s\" ପରିସର ନିର୍ଦ୍ଦିଷ୍ଟ କରି ନାହିଁ" -#: ../src/ui/theme.c:343 +#: ../src/ui/theme.c:323 #, c-format msgid "Button aspect ratio %g is not reasonable" msgstr "ଚାବି ପରିମାପ ଅନୁପାଦ %g ଯୁକ୍ତିଯୁକ୍ତ ନୁହେଁ" -#: ../src/ui/theme.c:355 +#: ../src/ui/theme.c:335 #, c-format msgid "Frame geometry does not specify size of buttons" msgstr "ବନ୍ଧେଇ ଜ୍ଯାମିତି ତାବିଗୁଡ଼ିକର ଆକାର ନିର୍ଦ୍ଦିଷ୍ଟ କରି ନାହିଁ" -#: ../src/ui/theme.c:1020 +#: ../src/ui/theme.c:1061 #, c-format msgid "Gradients should have at least two colors" msgstr "ଗଡ଼ାଣିଗୁଡ଼ିକର କମସେକମ ଦୁଇଟି ରଙ୍ଗ ଥିବା ଉଚିତ" -#: ../src/ui/theme.c:1146 +#: ../src/ui/theme.c:1211 +#, c-format +msgid "" +"GTK custom color specification must have color name and fallback in " +"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" +msgstr "" +"GTK ର ରଙ୍ଗ ନିର୍ଦ୍ଦିଷ୍ଟକରଣରେ ଅବସ୍ଥା ପରେ ଡାହାଣ ବନ୍ଧନୀ ଥିବା ବାଧ୍ଯ, ଉଦାହରଣ ସ୍ବରୂପ " +" gtk:" +"custom(foo,bar); \"%s\" ବିଶ୍ଳେଷଣ କରିହେଲା ନାହିଁ" + +#: ../src/ui/theme.c:1227 +#, c-format +msgid "" +"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" +"_ are valid" +msgstr "" +"gtk:ଇଚ୍ଛାରୂପଣର color_name ପ୍ରାଚଳରେ ଅବୈଧ ଅକ୍ଷର '%c', କେବଳ A-Za-z0-9-_ ଗୁଡ଼ିକ " +"ବୈଧ ଅଟେ" + +#: ../src/ui/theme.c:1241 +#, c-format +msgid "" +"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " +"fit the format" +msgstr "" +"Gtk:ଇଚ୍ଛାରୂପଣ ଶୈଳୀଟି ହେଉଛି \"gtk:custom(color_name,fallback)\", \"%s\" ଶୈଳୀ " +"ସହିତ " +"ସମାନ ହୋଇନଥାଏ" + +#: ../src/ui/theme.c:1286 #, c-format msgid "" "GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " "where NORMAL is the state; could not parse \"%s\"" msgstr "" -"ଜି.ଟି.କେ.ର ରଙ୍ଗ ନିର୍ଦ୍ଦିଷ୍ଟକରଣରେ ଅବସ୍ଥା ବନ୍ଧନୀରେ ଥିବା ବାଧ୍ଯ, ଉଦାହରଣ ସ୍ବରୂପ gtk:fg[NORMAL] " +"ଜି.ଟି.କେ.ର ରଙ୍ଗ ନିର୍ଦ୍ଦିଷ୍ଟକରଣରେ ଅବସ୍ଥା ବନ୍ଧନୀରେ ଥିବା ବାଧ୍ଯ, ଉଦାହରଣ ସ୍ବରୂପ " +"gtk:fg[NORMAL] " "ଯେଉଁଠାରେ NORMAL ହେଲା ଅବସ୍ଥା; \"%s\" ବିଶ୍ଳେଷଣ କରିହେଲା ନାହିଁ" -#: ../src/ui/theme.c:1160 +#: ../src/ui/theme.c:1300 #, c-format msgid "" "GTK color specification must have a close bracket after the state, e.g. gtk:" "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" msgstr "" -"ଜି.ଟି.କେ.ର ରଙ୍ଗ ନିର୍ଦ୍ଦିଷ୍ଟକରଣରେ ଅବସ୍ଥା ପରେ ଡାହାଣ ବନ୍ଧନୀ ଥିବା ବାଧ୍ଯ, ଉଦାହରଣ ସ୍ବରୂପ gtk:fg" -"[NORMAL] ଯେଉଁଠାରେ NORMAL ହେଲା ଅବସ୍ଥା; \"%s\" ବିଶ୍ଳେଷଣ କରିହେଲା ନାହିଁ" +"ଜି.ଟି.କେ.ର ରଙ୍ଗ ନିର୍ଦ୍ଦିଷ୍ଟକରଣରେ ଅବସ୍ଥା ପରେ ଡାହାଣ ବନ୍ଧନୀ ଥିବା ବାଧ୍ଯ, ଉଦାହରଣ " +"ସ୍ବରୂପ gtk:" +"fg[NORMAL] ଯେଉଁଠାରେ NORMAL ହେଲା ଅବସ୍ଥା; \"%s\" ବିଶ୍ଳେଷଣ କରିହେଲା ନାହିଁ" -#: ../src/ui/theme.c:1171 +#: ../src/ui/theme.c:1311 #, c-format msgid "Did not understand state \"%s\" in color specification" msgstr "ରଙ୍ଗ ନିର୍ଦ୍ଦିଷ୍ଟକରଣରେ \"%s\" ଅବସ୍ଥା ବୁଝିହେଲା ନାହିଁ" -#: ../src/ui/theme.c:1184 +#: ../src/ui/theme.c:1324 #, c-format msgid "Did not understand color component \"%s\" in color specification" msgstr "ରଙ୍ଗ ନିର୍ଦ୍ଦିଷ୍ଟକରଣରେ ରଙ୍ଗ ଯନ୍ତ୍ରାଂଶ \"%s\" ବୁଝିହେଲା ନାହିଁ" -#: ../src/ui/theme.c:1214 +#: ../src/ui/theme.c:1352 #, c-format msgid "" "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " "format" msgstr "" -"ମିଶ୍ରଣ ସଜ୍ଜିକରଣ ଶୈଳୀ ହେଲା \"blend/bg_color/fg_color/alpha\", \"%s\" ଏହି ଶୈଳୀ ଭାବେ " +"ମିଶ୍ରଣ ସଜ୍ଜିକରଣ ଶୈଳୀ ହେଲା \"blend/bg_color/fg_color/alpha\", \"%s\" ଏହି ଶୈଳୀ " +"ଭାବେ " "ନାହିଁ" -#: ../src/ui/theme.c:1225 +#: ../src/ui/theme.c:1363 #, c-format msgid "Could not parse alpha value \"%s\" in blended color" msgstr "ମିଶ୍ରିତ ରଙ୍ଗରେ ଆଲ୍ଫା ମୂଲ୍ଯ \"%s\"କୁ ବିଶ୍ଳେଷଣ କରିହେଲା ନାହିଁ" -#: ../src/ui/theme.c:1235 +#: ../src/ui/theme.c:1373 #, c-format msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" msgstr "ମିଶ୍ରିତ ରଙ୍ଗରେ ଆଲ୍ଫା ମୂଲ୍ଯ \"%s\" ୦.୦ ଓ ୧.୦ ମଧ୍ଯରେ ନାହିଁ" -#: ../src/ui/theme.c:1282 +#: ../src/ui/theme.c:1419 #, c-format -msgid "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "ଛାଇ ସଜ୍ଜିକରଣ ଶୈଳୀ ହେଲା \"shade/base_color/factor\", \"%s\" ଏହି ଶୈଳୀ ଭାବେ ନାହିଁ" +msgid "" +"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" +msgstr "" +"ଛାଇ ସଜ୍ଜିକରଣ ଶୈଳୀ ହେଲା \"shade/base_color/factor\", \"%s\" ଏହି ଶୈଳୀ ଭାବେ ନାହିଁ" -#: ../src/ui/theme.c:1293 +#: ../src/ui/theme.c:1430 #, c-format msgid "Could not parse shade factor \"%s\" in shaded color" msgstr "ଛାଇ ରଙ୍ଗରେ ଛାଇ ଗୁଣନୀୟକ \"%s\"କୁ ବିଶ୍ଳେଷଣ କରିହେଲା ନାହିଁ" -#: ../src/ui/theme.c:1303 +#: ../src/ui/theme.c:1440 #, c-format msgid "Shade factor \"%s\" in shaded color is negative" msgstr "ଛାଇ ରଙ୍ଗରେ ଛାଇ ଗୁଣନୀୟକ \"%s\" ଶୂନ୍ଯଠାରୁ କମ ଅଛି" -#: ../src/ui/theme.c:1332 +#: ../src/ui/theme.c:1469 #, c-format msgid "Could not parse color \"%s\"" msgstr "\"%s\" ରଙ୍ଗକୁ ବିଶ୍ଳେଷଣ କରିହେଲା ନାହିଁ" -#: ../src/ui/theme.c:1582 +#: ../src/ui/theme.c:1778 #, c-format msgid "Coordinate expression contains character '%s' which is not allowed" msgstr "ସ୍ଥାନ ନିର୍ଣ୍ଣୟ ଅଭିବ୍ଯକ୍ତିରେ '%s' ଅକ୍ଷର ଅଛି, ଯାହାର ଅନୁମତି ନାହିଁ" -#: ../src/ui/theme.c:1609 +#: ../src/ui/theme.c:1805 #, c-format msgid "" "Coordinate expression contains floating point number '%s' which could not be " "parsed" -msgstr "ସ୍ଥାନ ନିର୍ଣ୍ଣୟ ଅଭିବ୍ଯକ୍ତିରେ '%s' ଅସ୍ଥାୟୀ ବିନ୍ଦୁ ସଂଖ୍ଯା ଅଛି, ଯେଉଁଟାକି ବିଶ୍ଳେଷଣ କରିହେଲା ନାହିଁ" +msgstr "" +"ସ୍ଥାନ ନିର୍ଣ୍ଣୟ ଅଭିବ୍ଯକ୍ତିରେ '%s' ଅସ୍ଥାୟୀ ବିନ୍ଦୁ ସଂଖ୍ଯା ଅଛି, ଯେଉଁଟାକି ବିଶ୍ଳେଷଣ " +"କରିହେଲା ନାହିଁ" -#: ../src/ui/theme.c:1623 +#: ../src/ui/theme.c:1819 #, c-format msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "ସ୍ଥାନ ନିର୍ଣ୍ଣୟ ଅଭିବ୍ଯକ୍ତିରେ '%s' ପୂର୍ଣ୍ଣ ସଂଖ୍ଯା ଅଛି, ଯେଉଁଟାକି ବିଶ୍ଳେଷଣ କରିହେଲା ନାହିଁ" +msgstr "" +"ସ୍ଥାନ ନିର୍ଣ୍ଣୟ ଅଭିବ୍ଯକ୍ତିରେ '%s' ପୂର୍ଣ୍ଣ ସଂଖ୍ଯା ଅଛି, ଯେଉଁଟାକି ବିଶ୍ଳେଷଣ " +"କରିହେଲା ନାହିଁ" -#: ../src/ui/theme.c:1745 +#: ../src/ui/theme.c:1940 #, c-format msgid "" "Coordinate expression contained unknown operator at the start of this text: " "\"%s\"" msgstr "ସ୍ଥାନ ନିର୍ଣ୍ଣୟ ଅଭିବ୍ଯକ୍ତିରେ ଅଜଣା ଚାଳକ ଅଛି, ଏହି ପାଠ୍ଯର ଆରମ୍ଭରେ: \"%s\"" -#: ../src/ui/theme.c:1802 +#: ../src/ui/theme.c:1997 #, c-format msgid "Coordinate expression was empty or not understood" msgstr "ସ୍ଥାନ ନିର୍ଣ୍ଣୟ ଅଭିବ୍ଯକ୍ତିରେ ଖାଲି ଅଛି ବା ବୁଝିହେଲା ନାହିଁ" -#: ../src/ui/theme.c:1913 ../src/ui/theme.c:1923 ../src/ui/theme.c:1957 +#: ../src/ui/theme.c:2110 ../src/ui/theme.c:2120 ../src/ui/theme.c:2154 #, c-format msgid "Coordinate expression results in division by zero" msgstr "ସ୍ଥାନ ନିର୍ଣ୍ଣୟ ଅଭିବ୍ଯକ୍ତିର ପରିଣାମ ସୂନ୍ଯ ଦ୍ବାରା ବିଭାଜନ" -#: ../src/ui/theme.c:1965 +#: ../src/ui/theme.c:2162 #, c-format -msgid "Coordinate expression tries to use mod operator on a floating-point number" -msgstr "ସ୍ଥାନ ନିର୍ଣ୍ଣୟ ଅଭିବ୍ଯକ୍ତି mod ଚାଳକକୁ ଗୋଟିଏ ଅସ୍ଥାୟୀ ବିନ୍ଦୁ ସଂଖ୍ଯା ପ୍ରତି ବ୍ଯବହାର କରିବାକୁ ଚେଷ୍ଟା କରେ" +msgid "" +"Coordinate expression tries to use mod operator on a floating-point number" +msgstr "" +"ସ୍ଥାନ ନିର୍ଣ୍ଣୟ ଅଭିବ୍ଯକ୍ତି mod ଚାଳକକୁ ଗୋଟିଏ ଅସ୍ଥାୟୀ ବିନ୍ଦୁ ସଂଖ୍ଯା ପ୍ରତି " +"ବ୍ଯବହାର କରିବାକୁ ଚେଷ୍ଟା କରେ" -#: ../src/ui/theme.c:2021 +#: ../src/ui/theme.c:2218 #, c-format -msgid "Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "ସ୍ଥାନ ନିର୍ଣ୍ଣୟ ଅଭିବ୍ଯକ୍ତିରେ ଚାଳକ \"%s\" ଅଛି, ଯେଉଁଠାରେ ସଂକାର୍ଯ୍ଯ ପ୍ରତ୍ଯାଶିତ ଥିଲା" +msgid "" +"Coordinate expression has an operator \"%s\" where an operand was expected" +msgstr "" +"ସ୍ଥାନ ନିର୍ଣ୍ଣୟ ଅଭିବ୍ଯକ୍ତିରେ ଚାଳକ \"%s\" ଅଛି, ଯେଉଁଠାରେ ସଂକାର୍ଯ୍ଯ ପ୍ରତ୍ଯାଶିତ " +"ଥିଲା" -#: ../src/ui/theme.c:2030 +#: ../src/ui/theme.c:2227 #, c-format msgid "Coordinate expression had an operand where an operator was expected" -msgstr "ସ୍ଥାନ ନିର୍ଣ୍ଣୟ ଅଭିବ୍ଯକ୍ତିରେ ଚାଳକ ଥିଲା, ଯେଉଁଠାରେ ସଂକାର୍ଯ୍ଯ ପ୍ରତ୍ଯାଶିତ ଥିଲା" +msgstr "" +"ସ୍ଥାନ ନିର୍ଣ୍ଣୟ ଅଭିବ୍ଯକ୍ତିରେ ଚାଳକ ଥିଲା, ଯେଉଁଠାରେ ସଂକାର୍ଯ୍ଯ ପ୍ରତ୍ଯାଶିତ ଥିଲା" -#: ../src/ui/theme.c:2038 +#: ../src/ui/theme.c:2235 #, c-format msgid "Coordinate expression ended with an operator instead of an operand" msgstr "ସ୍ଥାନ ନିର୍ଣ୍ଣୟ ଅଭିବ୍ଯକ୍ତି ସଂକାର୍ଯ୍ଯ ଅପେକ୍ଷା ଚାଳକରା ଶେଷହେଲା" -#: ../src/ui/theme.c:2048 +#: ../src/ui/theme.c:2245 #, c-format msgid "" "Coordinate expression has operator \"%c\" following operator \"%c\" with no " "operand in between" -msgstr "ସ୍ଥାନ ନିର୍ଣ୍ଣୟ ଅଭିବ୍ଯକ୍ତିରେ \"%2$c\" ଚାଳକ ପରେ \"%1$c\" ଚାଳକ ଅଛି, ମଝିରେ ସଂକାର୍ଯ୍ଯ ନ ଥାଇ" +msgstr "" +"ସ୍ଥାନ ନିର୍ଣ୍ଣୟ ଅଭିବ୍ଯକ୍ତିରେ \"%2$c\" ଚାଳକ ପରେ \"%1$c\" ଚାଳକ ଅଛି, ମଝିରେ " +"ସଂକାର୍ଯ୍ଯ ନ ଥାଇ" -#: ../src/ui/theme.c:2195 ../src/ui/theme.c:2236 +#: ../src/ui/theme.c:2396 ../src/ui/theme.c:2441 #, c-format msgid "Coordinate expression had unknown variable or constant \"%s\"" msgstr "ସ୍ଥାନ ନିର୍ଣ୍ଣୟ ଅଭିବ୍ଯକ୍ତିରେ ଅଜଣା ଚଳ ବା ସ୍ଥାୟୀ ମୂଲ୍ଯ \"%s\" ଥିଲା" -#: ../src/ui/theme.c:2290 -#, fuzzy, c-format -#| msgid "Coordinate expression was empty or not understood" +#: ../src/ui/theme.c:2495 +#, c-format msgid "Coordinate expression parser overflowed its buffer." -msgstr "ସ୍ଥାନ ନିର୍ଣ୍ଣୟ ଅଭିବ୍ଯକ୍ତିରେ ଖାଲି ଅଛି ବା ବୁଝିହେଲା ନାହିଁ" +msgstr "ନିର୍ଣ୍ଣୟ ଅଭିବ୍ଯକ୍ତି ବିଶ୍ଳେଷକ ଏହାର ବଫରରେ ଅତିପ୍ରବାହ ହୋଇଥାଏ।" -#: ../src/ui/theme.c:2319 +#: ../src/ui/theme.c:2524 #, c-format msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "ସ୍ଥାନ ନିର୍ଣ୍ଣୟ ଅଭିବ୍ଯକ୍ତିରେ ବାମ ବନ୍ଧନୀ ଚିହ୍ନ ବିନା ଗୋଟିଏ ଡାହାଣ ବନ୍ଧନୀ ଚିହ୍ନ ଥିଲା" +msgstr "" +"ସ୍ଥାନ ନିର୍ଣ୍ଣୟ ଅଭିବ୍ଯକ୍ତିରେ ବାମ ବନ୍ଧନୀ ଚିହ୍ନ ବିନା ଗୋଟିଏ ଡାହାଣ ବନ୍ଧନୀ ଚିହ୍ନ " +"ଥିଲା" -#: ../src/ui/theme.c:2383 +#: ../src/ui/theme.c:2588 #, c-format msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "ସ୍ଥାନ ନିର୍ଣ୍ଣୟ ଅଭିବ୍ଯକ୍ତିରେ ଡାହାଣ ବନ୍ଧନୀ ଚିହ୍ନ ବିନା ଗୋଟିଏ ବାମ ବନ୍ଧନୀ ଚିହ୍ନ ଥିଲା" +msgstr "" +"ସ୍ଥାନ ନିର୍ଣ୍ଣୟ ଅଭିବ୍ଯକ୍ତିରେ ଡାହାଣ ବନ୍ଧନୀ ଚିହ୍ନ ବିନା ଗୋଟିଏ ବାମ ବନ୍ଧନୀ ଚିହ୍ନ " +"ଥିଲା" -#: ../src/ui/theme.c:2394 +#: ../src/ui/theme.c:2599 #, c-format msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "ସ୍ଥାନ ନିର୍ଣ୍ଣୟ ଅଭିବ୍ଯକ୍ତିରେ କୌଣସି ଚାଳକ ବା ସଂକାର୍ଯ୍ଯ ଥାଲା ଭଳିଆ ବୋଧହେଉ ନାହିଁ" +msgstr "" +"ସ୍ଥାନ ନିର୍ଣ୍ଣୟ ଅଭିବ୍ଯକ୍ତିରେ କୌଣସି ଚାଳକ ବା ସଂକାର୍ଯ୍ଯ ଥାଲା ଭଳିଆ ବୋଧହେଉ ନାହିଁ" -#: ../src/ui/theme.c:2596 ../src/ui/theme.c:2616 ../src/ui/theme.c:2636 +#: ../src/ui/theme.c:2812 ../src/ui/theme.c:2832 ../src/ui/theme.c:2852 #, c-format -#| msgid "Theme contained an expression \"%s\" that resulted in an error: %s\n" msgid "Theme contained an expression that resulted in an error: %s\n" msgstr "ପ୍ରସଙ୍ଗରେ ଗୋଟିଏ ଅଭିବ୍ଯକ୍ତି ଯୋଗୁ ତ୍ରୁଟି ହେଲା: %s\n" -#: ../src/ui/theme.c:4187 +#: ../src/ui/theme.c:4455 #, c-format msgid "" "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " @@ -1856,39 +896,44 @@ msgstr "" "ଏହି ବନ୍ଧେଇ ସଜ୍ଜିକରଣ ଶୈଳୀ ପାଇଁ <button function=\"%s\" state=\"%s\" draw_ops=" "\"whatever\"/> ନିର୍ଦ୍ଦିଷ୍ଟ କରିବା ବାଧ୍ଯ" -#: ../src/ui/theme.c:4695 ../src/ui/theme.c:4720 +#: ../src/ui/theme.c:4970 ../src/ui/theme.c:4995 #, c-format -msgid "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "ନିଖୋଜ <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" +msgid "" +"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" +msgstr "" +"ନିଖୋଜ <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -#: ../src/ui/theme.c:4764 +#: ../src/ui/theme.c:5041 #, c-format msgid "Failed to load theme \"%s\": %s\n" msgstr "\"%s\" ପ୍ରସଙ୍ଗ ଧାରଣ କରିବାରେ ଅସଫଳ: %s\n" -#: ../src/ui/theme.c:4894 ../src/ui/theme.c:4901 ../src/ui/theme.c:4908 -#: ../src/ui/theme.c:4915 ../src/ui/theme.c:4922 +#: ../src/ui/theme.c:5177 ../src/ui/theme.c:5184 ../src/ui/theme.c:5191 +#: ../src/ui/theme.c:5198 ../src/ui/theme.c:5205 #, c-format msgid "No <%s> set for theme \"%s\"" msgstr "\"%2$s\" ପ୍ରସଙ୍ଗ ପାଇଁ କୌଣସି <%1$s> ବିନ୍ଯାସ କରାଯାଇ ନାହିଁ" -#: ../src/ui/theme.c:4930 +#: ../src/ui/theme.c:5213 #, c-format msgid "" "No frame style set for window type \"%s\" in theme \"%s\", add a <window " "type=\"%s\" style_set=\"whatever\"/> element" msgstr "" -"\"%2$s\" ପ୍ରସଙ୍ଗରେ ୱିଣ୍ଡୋ ପ୍ରକାର \"%1$s\" ପାଇଁ କୌଣସି ବନ୍ଧେଇ ଶୈଳୀ ବିନ୍ଯାସ କରାଯାଇ ନାହିଁ, " +"\"%2$s\" ପ୍ରସଙ୍ଗରେ ୱିଣ୍ଡୋ ପ୍ରକାର \"%1$s\" ପାଇଁ କୌଣସି ବନ୍ଧେଇ ଶୈଳୀ ବିନ୍ଯାସ " +"କରାଯାଇ ନାହିଁ, " "ଗୋଟିଏ <windowtype=\"%3$s\" style_set=\"whatever\"/> ଉପାଦାନ ଯୋଗ କରନ୍ତୁ" -#: ../src/ui/theme.c:5383 ../src/ui/theme.c:5445 ../src/ui/theme.c:5508 +#: ../src/ui/theme.c:5620 ../src/ui/theme.c:5682 ../src/ui/theme.c:5745 #, c-format -msgid "User-defined constants must begin with a capital letter; \"%s\" does not" +msgid "" +"User-defined constants must begin with a capital letter; \"%s\" does not" msgstr "" -"ଚାଳକ ଦ୍ବାରା ବ୍ଯାଖ୍ଯା କରାଯାଇଥାବା ସ୍ଥାୟୀ ମୂଲ୍ଯଗୁଡ଼ିକ ବଡ଼ ଅକ୍ଷରରେ ଆରମ୍ଭ ହେବା ବାଧ୍ଯ; \"%s\" " +"ଚାଳକ ଦ୍ବାରା ବ୍ଯାଖ୍ଯା କରାଯାଇଥାବା ସ୍ଥାୟୀ ମୂଲ୍ଯଗୁଡ଼ିକ ବଡ଼ ଅକ୍ଷରରେ ଆରମ୍ଭ ହେବା " +"ବାଧ୍ଯ; \"%s\" " "କରୁ ନାହିଁ" -#: ../src/ui/theme.c:5391 ../src/ui/theme.c:5453 ../src/ui/theme.c:5516 +#: ../src/ui/theme.c:5628 ../src/ui/theme.c:5690 ../src/ui/theme.c:5753 #, c-format msgid "Constant \"%s\" has already been defined" msgstr "\"%s\" ସ୍ଥାୟୀ ମୂଲ୍ଯ ପୂର୍ବରୁ ବ୍ଯାଖ୍ଯା କରାଯାଇଛି" @@ -1896,58 +941,69 @@ msgstr "\"%s\" ସ୍ଥାୟୀ ମୂଲ୍ଯ ପୂର୍ବରୁ ବ୍ #. Translators: This means that an attribute which should have been found #. * on an XML element was not in fact found. #. -#: ../src/ui/theme-parser.c:202 +#: ../src/ui/theme-parser.c:234 #, c-format -#| msgid "No \"x\" attribute on element <%s>" msgid "No \"%s\" attribute on element <%s>" msgstr "କୌଣସି \"%s\" ଗୁଣ ବସ୍ତୁରେ ନାହିଁ <%s>" -#: ../src/ui/theme-parser.c:231 ../src/ui/theme-parser.c:249 +#: ../src/ui/theme-parser.c:263 ../src/ui/theme-parser.c:281 #, c-format msgid "Line %d character %d: %s" msgstr "ଧାଡ଼ି %d ଅକ୍ଷର %d: %s" -#: ../src/ui/theme-parser.c:413 +#: ../src/ui/theme-parser.c:481 #, c-format msgid "Attribute \"%s\" repeated twice on the same <%s> element" msgstr "\"%s\" ଗୁଣ ଏକା ଉପାଦାନ <%s>ରେ ଦୁଇଥର ଅଛି" -#: ../src/ui/theme-parser.c:437 ../src/ui/theme-parser.c:480 +#: ../src/ui/theme-parser.c:505 ../src/ui/theme-parser.c:554 #, c-format msgid "Attribute \"%s\" is invalid on <%s> element in this context" msgstr "\"%s\" ଗୁଣ <%s> ଉପାଦାନ ଫାଇଁ ଏହି ପ୍ରସଙ୍ଗରେ ଅବୈଧ" -#: ../src/ui/theme-parser.c:541 +#: ../src/ui/theme-parser.c:596 +#, c-format +msgid "Could not parse \"%s\" as an integer" +msgstr "\"%s\"କୁ ପୁର୍ଣ ସଂଖ୍ଯା ଭାବରେ ବିଶ୍ଳେଷଣ କରିହେଲା ନାହିଁ" + +#: ../src/ui/theme-parser.c:605 ../src/ui/theme-parser.c:660 +#, c-format +msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +msgstr "\"%s\" ବାକ୍ଯଖଣ୍ଡର ପଛପାଖରେ ଥିବା ଅକ୍ଷର \"%s\" ବୁଝିହେଲା ନାହିଁ" + +#: ../src/ui/theme-parser.c:615 #, c-format msgid "Integer %ld must be positive" msgstr "%ld ପୂର୍ଣ୍ମ ସମଖ୍ଯା ଶୂନ୍ଯଠାରୁ ଅଧିକ ହେବା ବାଧ୍ଯ" -#: ../src/ui/theme-parser.c:549 +#: ../src/ui/theme-parser.c:623 #, c-format msgid "Integer %ld is too large, current max is %d" msgstr "%ld ପୂର୍ଣ୍ମ ସମଖ୍ଯାଟି ଅତି ବଡ଼, ସାମ୍ପ୍ରତିକ ସର୍ବାଧିକ ମୂଲ୍ଯ ହେଲା %d" -#: ../src/ui/theme-parser.c:577 ../src/ui/theme-parser.c:693 +#: ../src/ui/theme-parser.c:651 ../src/ui/theme-parser.c:767 #, c-format msgid "Could not parse \"%s\" as a floating point number" msgstr "\"%s\"କୁ ଅସ୍ଥାୟୀ ବିନ୍ଦୁ ରୂପେ ବିଶ୍ଳେଷଣ କରିବାରେ ଅସଫଳ" -#: ../src/ui/theme-parser.c:608 ../src/ui/theme-parser.c:636 +#: ../src/ui/theme-parser.c:682 ../src/ui/theme-parser.c:710 #, c-format msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" msgstr "ବୁଲିଆନ ମୂଲ୍ଯଗୁଡ଼ିକ \"true\" ବା \"false\" ହୋଇଥିବା ବାଧ୍ଯ, \"%s\" ନୁହେଁ" -#: ../src/ui/theme-parser.c:663 +#: ../src/ui/theme-parser.c:737 #, c-format msgid "Angle must be between 0.0 and 360.0, was %g\n" msgstr "କୋଣ ୦.୦ ଓ ୩୬୦.୦ ମଧ୍ଯରେ ଥିବା ବାଧ୍ଯ, %g ଥିଲା\n" -#: ../src/ui/theme-parser.c:726 +#: ../src/ui/theme-parser.c:800 #, c-format msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "ଆଲ୍ଫା ୦.୦ (ଅଦୃଶ୍ଯ) ଓ ୧.୦ (ସମ୍ପୂର୍ଣ୍ମ ଭାବେ ଅସ୍ବଚ୍ଛ) ମଧ୍ଯରେ ଥିବା ବାଧ୍ଯ, %g ଥିଲା\n" +msgstr "" +"ଆଲ୍ଫା ୦.୦ (ଅଦୃଶ୍ଯ) ଓ ୧.୦ (ସମ୍ପୂର୍ଣ୍ମ ଭାବେ ଅସ୍ବଚ୍ଛ) ମଧ୍ଯରେ ଥିବା ବାଧ୍ଯ, %g " +"ଥିଲା\n" -#: ../src/ui/theme-parser.c:791 +#: ../src/ui/theme-parser.c:865 #, c-format msgid "" "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," @@ -1956,503 +1012,1431 @@ msgstr "" "ଅବୈଧ ଶୀର୍ଷକ ମାପ \"%s\" (xx-small,x-small,small,medium,large,x-large,xx-large " "ମଧ୍ଯରୁ ଗୋଟିଏ ହୋଇଥିବା ବାଧ୍ଯ)\n" -#: ../src/ui/theme-parser.c:936 ../src/ui/theme-parser.c:999 -#: ../src/ui/theme-parser.c:1033 ../src/ui/theme-parser.c:1136 +#: ../src/ui/theme-parser.c:1021 ../src/ui/theme-parser.c:1084 +#: ../src/ui/theme-parser.c:1118 ../src/ui/theme-parser.c:1221 #, c-format msgid "<%s> name \"%s\" used a second time" msgstr "<%s> ନାମ \"%s\" ଦୁଇଥର ବ୍ଯବହୃତ" -#: ../src/ui/theme-parser.c:948 ../src/ui/theme-parser.c:1045 -#: ../src/ui/theme-parser.c:1148 +#: ../src/ui/theme-parser.c:1033 ../src/ui/theme-parser.c:1130 +#: ../src/ui/theme-parser.c:1233 #, c-format msgid "<%s> parent \"%s\" has not been defined" msgstr "<%s> ମୂଳ \"%s\" ବ୍ଯାଖ୍ଯା ହୋଇ ନାହିଁ" -#: ../src/ui/theme-parser.c:1058 +#: ../src/ui/theme-parser.c:1143 #, c-format msgid "<%s> geometry \"%s\" has not been defined" msgstr "<%s> ଜ୍ଯାମିତି \"%s\" ବ୍ଯାଖ୍ଯା ହୋଇ ନାହିଁ" -#: ../src/ui/theme-parser.c:1071 +#: ../src/ui/theme-parser.c:1156 #, c-format msgid "<%s> must specify either a geometry or a parent that has a geometry" msgstr "<%s> ଗୋଟିଏ ଜ୍ଯାମିତି ବା ଜ୍ଯାମିତି ଥିବା ମୂଳ ନିର୍ଦ୍ଦିଷ୍ଟ କରିବା ବାଧ୍ଯ" -#: ../src/ui/theme-parser.c:1113 +#: ../src/ui/theme-parser.c:1198 msgid "You must specify a background for an alpha value to be meaningful" -msgstr "" +msgstr "ଆପଣଙ୍କୁ ଆଲଫା ମୂଲ୍ୟ ପାଇଁ ଗୋଟିଏ ଅର୍ଥପୂର୍ଣ୍ଣ ପୃଷ୍ଠଭୂମି ଉଲ୍ଲେଖ କରିବା ଉଚିତ" -#: ../src/ui/theme-parser.c:1180 +#: ../src/ui/theme-parser.c:1266 #, c-format msgid "Unknown type \"%s\" on <%s> element" msgstr "ଉପାଦାନ <%s>ରେ ଅଜଣା ପ୍ରକାର \"%s\"" -#: ../src/ui/theme-parser.c:1191 +#: ../src/ui/theme-parser.c:1277 #, c-format msgid "Unknown style_set \"%s\" on <%s> element" msgstr "ଉପାଦାନ <%s>ରେ ଅଜଣା ଶୈଳୀ_ସେଟ୍ \"%s\"" -#: ../src/ui/theme-parser.c:1199 +#: ../src/ui/theme-parser.c:1285 #, c-format msgid "Window type \"%s\" has already been assigned a style set" msgstr "\"%s\" ୱିଣ୍ଡୋ ପ୍ରକାର ପାଇଁ ପୂର୍ବରୁ ଗୋଟିଏ ଶୈଳୀ ସେଟ୍ ନିର୍ଦ୍ଧାରିତ କରାଯାଇଛି" -#: ../src/ui/theme-parser.c:1229 ../src/ui/theme-parser.c:1293 -#: ../src/ui/theme-parser.c:1519 ../src/ui/theme-parser.c:2732 -#: ../src/ui/theme-parser.c:2778 ../src/ui/theme-parser.c:2926 -#: ../src/ui/theme-parser.c:3118 ../src/ui/theme-parser.c:3156 -#: ../src/ui/theme-parser.c:3194 ../src/ui/theme-parser.c:3232 +#: ../src/ui/theme-parser.c:1315 ../src/ui/theme-parser.c:1379 +#: ../src/ui/theme-parser.c:1605 ../src/ui/theme-parser.c:2840 +#: ../src/ui/theme-parser.c:2886 ../src/ui/theme-parser.c:3036 +#: ../src/ui/theme-parser.c:3272 ../src/ui/theme-parser.c:3310 +#: ../src/ui/theme-parser.c:3348 ../src/ui/theme-parser.c:3386 #, c-format msgid "Element <%s> is not allowed below <%s>" msgstr "<%2$s> ତଳେ <%1$s> ଉପାଦାନର ଅନୁମତି ନାହିଁ" -#: ../src/ui/theme-parser.c:1343 ../src/ui/theme-parser.c:1357 -#: ../src/ui/theme-parser.c:1402 -#, fuzzy -#| msgid "" -#| "Cannot specify both button_width/button_height and aspect ratio for " -#| "buttons" +#: ../src/ui/theme-parser.c:1429 ../src/ui/theme-parser.c:1443 +#: ../src/ui/theme-parser.c:1488 msgid "" "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " "for buttons" -msgstr "ଚାବିର ଓସାର/ଉଚ୍ଚତା ସହିତ ତାହାର ପରିମାପ ଅନୁପାଦ ବିନ୍ଯାସ କରିହେବ ନାହିଁ" +msgstr "" +"ବଟନଗୁଡ଼ିକ ପାଇଁ ଉଭୟ \"button_width\"/\"button_height\" ଏବଂ \"aspect_ratio\"କୁ " +"ଉଲ୍ଲେଖ କରିପାରିବେ ନାହିଁ" -#: ../src/ui/theme-parser.c:1366 +#: ../src/ui/theme-parser.c:1452 #, c-format msgid "Distance \"%s\" is unknown" msgstr "\"%s\" ଦୂରତା ଅଜଣା" -#: ../src/ui/theme-parser.c:1411 +#: ../src/ui/theme-parser.c:1497 #, c-format msgid "Aspect ratio \"%s\" is unknown" msgstr "\"%s\" ପରିମାପ ଅନୁପାଦ ଅଜଣା" -#: ../src/ui/theme-parser.c:1473 +#: ../src/ui/theme-parser.c:1559 #, c-format msgid "Border \"%s\" is unknown" msgstr "\"%s\" ଧାର ଅଜଣା" -#: ../src/ui/theme-parser.c:1776 +#: ../src/ui/theme-parser.c:1870 #, c-format -#| msgid "No \"start_angle\" attribute on element <%s>" msgid "No \"start_angle\" or \"from\" attribute on element <%s>" msgstr "<%s> ଉପାଦାନରେ \"start_angle\" କିମ୍ବା \"from\" ଗୁଣ ନାହିଁ" -#: ../src/ui/theme-parser.c:1783 +#: ../src/ui/theme-parser.c:1877 #, c-format -#| msgid "No \"extent_angle\" attribute on element <%s>" msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" msgstr "<%s> ଉପାଦାନରେ \"extent_angle\" କିମ୍ବା \"to\" ଗୁଣ ନାହିଁ" -#: ../src/ui/theme-parser.c:2023 +#: ../src/ui/theme-parser.c:2117 #, c-format msgid "Did not understand value \"%s\" for type of gradient" msgstr "ଗଡ଼ାଣି ପ୍ରକାର ପାଇଁ \"%s\" ମୂଲ୍ଯ ବୁଝିହେଲା ନାହିଁ" -#: ../src/ui/theme-parser.c:2101 ../src/ui/theme-parser.c:2476 +#: ../src/ui/theme-parser.c:2195 ../src/ui/theme-parser.c:2570 #, c-format msgid "Did not understand fill type \"%s\" for <%s> element" msgstr "<%2$s> ଉପାଦାନ ପାଇଁ \"%1$s\" ଭରଣ ଶୈଳୀ ବୁଝିହେଲା ନାହିଁ" -#: ../src/ui/theme-parser.c:2268 ../src/ui/theme-parser.c:2351 -#: ../src/ui/theme-parser.c:2414 +#: ../src/ui/theme-parser.c:2362 ../src/ui/theme-parser.c:2445 +#: ../src/ui/theme-parser.c:2508 #, c-format msgid "Did not understand state \"%s\" for <%s> element" msgstr "<%2$s> ଉପାଦାନ ପାଇଁ \"%1$s\" ଅବସ୍ଥା ବୁଝିହେଲା ନାହିଁ" -#: ../src/ui/theme-parser.c:2278 ../src/ui/theme-parser.c:2361 +#: ../src/ui/theme-parser.c:2372 ../src/ui/theme-parser.c:2455 #, c-format msgid "Did not understand shadow \"%s\" for <%s> element" msgstr "<%2$s> ଉପାଦାନ ପାଇଁ \"%1$s\" ଛାଇ ବୁଝିହେଲା ନାହିଁ" -#: ../src/ui/theme-parser.c:2288 +#: ../src/ui/theme-parser.c:2382 #, c-format msgid "Did not understand arrow \"%s\" for <%s> element" msgstr "<%2$s> ଉପାଦାନ ପାଇଁ \"%1$s\" ତୀର ବୁଝିହେଲା ନାହିଁ" -#: ../src/ui/theme-parser.c:2588 ../src/ui/theme-parser.c:2684 +#: ../src/ui/theme-parser.c:2696 ../src/ui/theme-parser.c:2792 #, c-format msgid "No <draw_ops> called \"%s\" has been defined" msgstr "\"%s\" ନାମକ <draw_ops> ବ୍ଯାଖ୍ଯା ହୋଇ ନାହିଁ" -#: ../src/ui/theme-parser.c:2600 ../src/ui/theme-parser.c:2696 +#: ../src/ui/theme-parser.c:2708 ../src/ui/theme-parser.c:2804 #, c-format msgid "Including draw_ops \"%s\" here would create a circular reference" msgstr "ଏଠାରେ \"%s\" draw_ops ଭର୍ତ୍ତି କଲେ, ଗୋଟିଏ ବୃତ୍ତାକାର ରେଫରେନ୍ସ ସୃଷ୍ଟି ହେବ" -#: ../src/ui/theme-parser.c:2811 +#: ../src/ui/theme-parser.c:2919 #, c-format msgid "Unknown position \"%s\" for frame piece" msgstr "ବନ୍ଧେଇ ଖଣ୍ଡ ପାଇଁ ଅଜଣା ଅବସ୍ଥାନ \"%s\"" -#: ../src/ui/theme-parser.c:2819 +#: ../src/ui/theme-parser.c:2927 #, c-format msgid "Frame style already has a piece at position %s" msgstr "ବନ୍ଧେଇ ଶୈଳୀର ପୂର୍ବରୁ %s ଅବସ୍ଥାନରେ ଗୋଟିଏ ଖଣ୍ଡ ଅଛି" -#: ../src/ui/theme-parser.c:2836 ../src/ui/theme-parser.c:2911 +#: ../src/ui/theme-parser.c:2944 ../src/ui/theme-parser.c:3021 #, c-format msgid "No <draw_ops> with the name \"%s\" has been defined" msgstr "\"%s\" ନାମକ <draw_ops> ବ୍ଯାଖ୍ଯା ହୋଇ ନାହିଁ" -#: ../src/ui/theme-parser.c:2865 +#: ../src/ui/theme-parser.c:2974 #, c-format msgid "Unknown function \"%s\" for button" msgstr "ଚାବି ପାଇଁ ଅଜଣା ଫଳନ \"%s\"" -#: ../src/ui/theme-parser.c:2874 +#: ../src/ui/theme-parser.c:2984 #, c-format msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "" +msgstr "ବଟନ ଫଳନ \"%s\" ଏହି ସଂସ୍କରଣରେ ଅବସ୍ଥିତ ନାହିଁ (%d, %d ଆବଶ୍ୟକ)" -#: ../src/ui/theme-parser.c:2886 +#: ../src/ui/theme-parser.c:2996 #, c-format msgid "Unknown state \"%s\" for button" msgstr "ଚାବି ପାଇଁ ଅଜଣା ଅବସ୍ଥା\"%s\"" -#: ../src/ui/theme-parser.c:2894 +#: ../src/ui/theme-parser.c:3004 #, c-format msgid "Frame style already has a button for function %s state %s" msgstr "ଫଳନ %s, ସ୍ଥିତି %s ପାଇଁ ପୂର୍ବରୁ ବନ୍ଧେଇ ଶୈଳୀର ଗୋଟିଏ ଚାବି ଅଛି" -#: ../src/ui/theme-parser.c:2965 +#: ../src/ui/theme-parser.c:3075 #, c-format msgid "\"%s\" is not a valid value for focus attribute" msgstr "କେନ୍ଦ୍ର ଗୁଣ ପାଇଁ \"%s\" ବୈଧ ମୂଲ୍ଯ ନୁହେଁ" -#: ../src/ui/theme-parser.c:2974 +#: ../src/ui/theme-parser.c:3084 #, c-format msgid "\"%s\" is not a valid value for state attribute" msgstr "ଅବସ୍ଥା ଗୁଣ ପାଇଁ \"%s\" ବୈଧ ମୂଲ୍ଯ ନୁହେଁ" -#: ../src/ui/theme-parser.c:2984 +#: ../src/ui/theme-parser.c:3094 #, c-format msgid "A style called \"%s\" has not been defined" msgstr "\"%s\" ନାମକ ଶୈଳୀ ବ୍ଯାଖ୍ଯା ହୋଇ ନାହିଁ" -#: ../src/ui/theme-parser.c:3005 ../src/ui/theme-parser.c:3028 +#: ../src/ui/theme-parser.c:3115 ../src/ui/theme-parser.c:3138 #, c-format msgid "\"%s\" is not a valid value for resize attribute" msgstr "ଆକାର ବଦଳାଇବା ଗୁଣ ପାଇଁ \"%s\" ବୈଧ ମୂଲ୍ଯ ନୁହେଁ" -#: ../src/ui/theme-parser.c:3039 +#: ../src/ui/theme-parser.c:3149 #, c-format msgid "" "Should not have \"resize\" attribute on <%s> element for maximized/shaded " "states" -msgstr "ବୃହତ୍ତମ/ଘୋଡାହୋଇଥିବା ଅବସ୍ଥା ପାଇଁ <%s> ଉପାଦାନର \"resize\" ଗୁଣ ଥିବା ଉଚିତ ନୁହେଁ" +msgstr "" +"ବୃହତ୍ତମ/ଘୋଡାହୋଇଥିବା ଅବସ୍ଥା ପାଇଁ <%s> ଉପାଦାନର \"resize\" ଗୁଣ ଥିବା ଉଚିତ ନୁହେଁ" -#: ../src/ui/theme-parser.c:3053 +#: ../src/ui/theme-parser.c:3163 #, c-format -#| msgid "" -#| "Should not have \"resize\" attribute on <%s> element for maximized/shaded " -#| "states" -msgid "Should not have \"resize\" attribute on <%s> element for maximized states" +msgid "" +"Should not have \"resize\" attribute on <%s> element for maximized states" msgstr "ବୃହତ୍ତମ ଅବସ୍ଥା ପାଇଁ <%s> ଉପାଦାନରେ \"resize\" ଗୁଣ ଥିବା ଉଚିତ ନୁହେଁ" -#: ../src/ui/theme-parser.c:3067 ../src/ui/theme-parser.c:3089 +#: ../src/ui/theme-parser.c:3177 ../src/ui/theme-parser.c:3221 #, c-format msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "ଅବସ୍ଥା %s ଆକାର ବଦଳାଇବା %s କେନ୍ଦ୍ର %s ପାଇଁ ଶୈଳୀ ପୂର୍ବରୁ ବିନ୍ଯାସ କରାଯାଇଛି" +msgstr "" +"ଅବସ୍ଥା %s ଆକାର ବଦଳାଇବା %s କେନ୍ଦ୍ର %s ପାଇଁ ଶୈଳୀ ପୂର୍ବରୁ ବିନ୍ଯାସ କରାଯାଇଛି" -#: ../src/ui/theme-parser.c:3078 ../src/ui/theme-parser.c:3100 +#: ../src/ui/theme-parser.c:3188 ../src/ui/theme-parser.c:3199 +#: ../src/ui/theme-parser.c:3210 ../src/ui/theme-parser.c:3232 +#: ../src/ui/theme-parser.c:3243 ../src/ui/theme-parser.c:3254 #, c-format msgid "Style has already been specified for state %s focus %s" msgstr "ଅବସ୍ଥା %s କେନ୍ଦ୍ର %s ପାଇଁ ଶୈଳୀ ପୂର୍ବରୁ ବିନ୍ଯାସ କରାଯାଇଛି" -#: ../src/ui/theme-parser.c:3139 +#: ../src/ui/theme-parser.c:3293 msgid "" "Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " "attribute and also a <draw_ops> element, or specified two elements)" msgstr "" -"<piece> ଉପାଦାନ ପାଇଁ ଦୁଇଟି draw_ops ରହିପାରିବ ନାହିଁ (ପ୍ରସଙ୍ଗ ଗୋଟିଏ draw_ops ଗୁଣ ଏବଂ ଗୋଟିଏ " +"<piece> ଉପାଦାନ ପାଇଁ ଦୁଇଟି draw_ops ରହିପାରିବ ନାହିଁ (ପ୍ରସଙ୍ଗ ଗୋଟିଏ draw_ops ଗୁଣ " +"ଏବଂ ଗୋଟିଏ " "<draw_ops> ଉପାଦାନ, ବା ଦୁଇଟି ଉପାଦାନ ନିର୍ଦ୍ଦିଷ୍ଟ କରିଥିଲା)" -#: ../src/ui/theme-parser.c:3177 +#: ../src/ui/theme-parser.c:3331 msgid "" "Can't have a two draw_ops for a <button> element (theme specified a draw_ops " "attribute and also a <draw_ops> element, or specified two elements)" msgstr "" -"<button> ଉପାଦାନ ପାଇଁ ଦୁଇଟି draw_ops ରହିପାରିବ ନାହିଁ (ପ୍ରସଙ୍ଗ ଗୋଟିଏ draw_ops ଗୁଣ ଏବଂ ଗୋଟିଏ " +"<button> ଉପାଦାନ ପାଇଁ ଦୁଇଟି draw_ops ରହିପାରିବ ନାହିଁ (ପ୍ରସଙ୍ଗ ଗୋଟିଏ draw_ops " +"ଗୁଣ ଏବଂ ଗୋଟିଏ " "<draw_ops> ଉପାଦାନ, ବା ଦୁଇଟି ଉପାଦାନ ନିର୍ଦ୍ଦିଷ୍ଟ କରିଥିଲା)" -#: ../src/ui/theme-parser.c:3215 +#: ../src/ui/theme-parser.c:3369 msgid "" "Can't have a two draw_ops for a <menu_icon> element (theme specified a " "draw_ops attribute and also a <draw_ops> element, or specified two elements)" msgstr "" -"<menu_icon> ଉପାଦାନ ପାଇଁ ଦୁଇଟି draw_ops ରହିପାରିବ ନାହିଁ (ପ୍ରସଙ୍ଗ ଗୋଟିଏ draw_ops ଗୁଣ ଏବଂ " +"<menu_icon> ଉପାଦାନ ପାଇଁ ଦୁଇଟି draw_ops ରହିପାରିବ ନାହିଁ (ପ୍ରସଙ୍ଗ ଗୋଟିଏ draw_ops " +"ଗୁଣ ଏବଂ " "ଗୋଟିଏ <draw_ops> ଉପାଦାନ, ବା ଦୁଇଟି ଉପାଦାନ ନିର୍ଦ୍ଦିଷ୍ଟ କରିଥିଲା)" -#: ../src/ui/theme-parser.c:3263 +#: ../src/ui/theme-parser.c:3433 +#, c-format +msgid "Bad version specification '%s'" +msgstr "ଖରାପ ସଂସ୍କରଣ ବିଶେଷତା '%s'" + +#: ../src/ui/theme-parser.c:3506 +msgid "" +"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" +"theme-2.xml" +msgstr "" +"\"ସଂସ୍କରଣ\" ଗୁଣଧର୍ମକୁ metacity-theme-1.xml ଅଥବା metacity-theme-2.xml ରେ " +"ବ୍ୟବହାର " +"କରାଯାଇପାରିବ ନାହିଁ" + +#: ../src/ui/theme-parser.c:3529 +#, c-format +msgid "Theme requires version %s but latest supported theme version is %d.%d" +msgstr "" +"ପ୍ରସଙ୍ଗଟି ସଂସ୍କରଣ %s ଆବଶ୍ୟକ କରିଥାଏ କିନ୍ତୁ ନୂତନତମ ସହାୟତା ପ୍ରାପ୍ତ ପ୍ରସଙ୍ଗ " +"ସଂସ୍କରଣଟି ହେଉଛି %d.%d" + +#: ../src/ui/theme-parser.c:3561 #, c-format msgid "Outermost element in theme must be <metacity_theme> not <%s>" msgstr "ପ୍ରସଙ୍ଗର ବାହ୍ଯତ୍ତମ ଉପାଦାନ <metacity_theme> ହେବା ବାଧ୍ଯ, <%s> ନୁହେଁ" -#: ../src/ui/theme-parser.c:3283 +#: ../src/ui/theme-parser.c:3581 #, c-format -msgid "Element <%s> is not allowed inside a name/author/date/description element" +msgid "" +"Element <%s> is not allowed inside a name/author/date/description element" msgstr "ନାମ/ଲେଖକ/ତାରିଖ/ବର୍ଣ୍ଣନା ଉପାଦାନ ଭିତରେ <%s> ଉପାଦାନର ଅନୁମତି ନାହିଁ" -#: ../src/ui/theme-parser.c:3288 +#: ../src/ui/theme-parser.c:3586 #, c-format msgid "Element <%s> is not allowed inside a <constant> element" msgstr "<constant> ଉପାଦାନ ଭିତରେ <%s> ଉପାଦାନର ଅନୁମତି ନାହିଁ" -#: ../src/ui/theme-parser.c:3300 +#: ../src/ui/theme-parser.c:3598 #, c-format -msgid "Element <%s> is not allowed inside a distance/border/aspect_ratio element" +msgid "" +"Element <%s> is not allowed inside a distance/border/aspect_ratio element" msgstr "ଦୂରତା/ଧାର/ପରିମାପ_ଅନୁପାଦ ଉପାଦାନ ଭିତରେ <%s> ଉପାଦାନର ଅନୁମତି ନାହିଁ" -#: ../src/ui/theme-parser.c:3322 +#: ../src/ui/theme-parser.c:3620 #, c-format msgid "Element <%s> is not allowed inside a draw operation element" msgstr "ଅଙ୍କନ ଚାଳନା ଉପାଦାନ ଭିତରେ <%s> ଉପାଦାନର ଅନୁମତି ନାହିଁ" -#: ../src/ui/theme-parser.c:3332 ../src/ui/theme-parser.c:3362 -#: ../src/ui/theme-parser.c:3367 ../src/ui/theme-parser.c:3372 +#: ../src/ui/theme-parser.c:3630 ../src/ui/theme-parser.c:3660 +#: ../src/ui/theme-parser.c:3665 ../src/ui/theme-parser.c:3670 #, c-format msgid "Element <%s> is not allowed inside a <%s> element" msgstr "<%2$s> ଉପାଦାନ ଭିତରେ <%1$s> ଉପାଦାନର ଅନୁମତି ନାହିଁ" -#: ../src/ui/theme-parser.c:3594 +#: ../src/ui/theme-parser.c:3898 msgid "No draw_ops provided for frame piece" msgstr "ବନ୍ଧେଇ ଖଣ୍ଡ ପାଇଁ draw_ops ନାହିଁ" -#: ../src/ui/theme-parser.c:3609 +#: ../src/ui/theme-parser.c:3913 msgid "No draw_ops provided for button" msgstr "ଚାବି ପାଇଁ draw_ops ନାହିଁ" -#: ../src/ui/theme-parser.c:3661 +#: ../src/ui/theme-parser.c:3967 #, c-format msgid "No text is allowed inside element <%s>" msgstr "<%s> ଉପାଦାନ ଭିତରେ ପାଠ୍ଯର ଅନୁମତି ନାହିଁ" -#: ../src/ui/theme-parser.c:3716 -msgid "<name> specified twice for this theme" -msgstr "ଏହି ପ୍ରସଙ୍ଗ ପାଇଁ <name> ଦୁଇଥର ବିନ୍ଯାସ କରାଯାଇଛି" - -#: ../src/ui/theme-parser.c:3727 -msgid "<author> specified twice for this theme" -msgstr "ଏହି ପ୍ରସଙ୍ଗ ପାଇଁ <author> ଦୁଇଥର ବିନ୍ଯାସ କରାଯାଇଛି" - -#: ../src/ui/theme-parser.c:3738 -msgid "<copyright> specified twice for this theme" -msgstr "ଏହି ପ୍ରସଙ୍ଗ ପାଇଁ <copyright> ଦୁଇଥର ବିନ୍ଯାସ କରାଯାଇଛି" - -#: ../src/ui/theme-parser.c:3749 -msgid "<date> specified twice for this theme" -msgstr "ଏହି ପ୍ରସଙ୍ଗ ପାଇଁ <date> ଦୁଇଥର ବିନ୍ଯାସ କରାଯାଇଛି" - -#: ../src/ui/theme-parser.c:3760 -msgid "<description> specified twice for this theme" -msgstr "ଏହି ପ୍ରସଙ୍ଗ ପାଇଁ <description> ଦୁଇଥର ବିନ୍ଯାସ କରାଯାଇଛି" +#: ../src/ui/theme-parser.c:4025 ../src/ui/theme-parser.c:4037 +#: ../src/ui/theme-parser.c:4049 ../src/ui/theme-parser.c:4061 +#: ../src/ui/theme-parser.c:4073 +#, c-format +msgid "<%s> specified twice for this theme" +msgstr "ଏହି ପ୍ରସଙ୍ଗ ପାଇଁ <%s> ଦୁଇଥର ଉଲ୍ଲେଖ କରାଯାଇଛି" -#: ../src/ui/theme-parser.c:4027 +#: ../src/ui/theme-parser.c:4335 #, c-format -#| msgid "Failed to fdopen() log file %s: %s\n" msgid "Failed to find a valid file for theme %s\n" msgstr "ପ୍ରସଙ୍ଗ %s ପାଇଁ ବୈଧ ଫାଇଲକୁ ଖୋଜିବାରେ ଅସଫଳ \n" -#: ../src/ui/theme-parser.c:4083 +#: ../src/x11/session.c:1815 +msgid "" +"These windows do not support "save current setup" and will have to " +"be restarted manually next time you log in." +msgstr "" +"ଏହି ୱିଣ୍ଡୋଗୁଡ଼ିକ " ସାମ୍ପ୍ରତିକ ବ୍ଯବସ୍ଥା ସଂରକ୍ଷଣ " କୁ ସହାୟତା କରିନଥାଏ, " +"ଏବଂ ପୁଣିଥରେ " +"ଲଗଇନ ହେବା ସମୟରେ ହସ୍ତକୃତ ଭାବରେ ପୁନଃ ପ୍ରାରମ୍ଭ କରିବାକୁ ହେବ।" + +#: ../src/x11/window-props.c:515 #, c-format -msgid "Theme file %s did not contain a root <metacity_theme> element" -msgstr "ପ୍ରସଙ୍ଗ ଫାଇଲ %sରେ ମୂଳ <metacity_theme> ଉପାଦାନ ନ ଥିଲା" +msgid "%s (on %s)" +msgstr "%s (%s ଉପରେ)" -#: ../src/ui/theme-viewer.c:75 -msgid "/_Windows" -msgstr "/ୱିଣ୍ଡୋ (_W)" +#~ msgid "background texture could not be created from file" +#~ msgstr "ପୃଷ୍ଠଭୂମି ସଂରଚନା ଫାଇଲରୁ ନିର୍ମାଣ କରିପାରିଲା ନାହିଁ" -#: ../src/ui/theme-viewer.c:76 -msgid "/Windows/tearoff" -msgstr "/ୱିଣ୍ଡୋ/ଛିଣ୍ଡାନ୍ତୁ" +#~ msgid "Unknown window information request: %d" +#~ msgstr "ଅଜଣା ୱିଣ୍ଡୋ ସୂଚନା ଅନୁରୋଧ କରାଯାଇଛି: %d" -#: ../src/ui/theme-viewer.c:77 -msgid "/Windows/_Dialog" -msgstr "/ୱିଣ୍ଡୋ/ସଂଳାପ (_D)" +#~ msgid "Missing %s extension required for compositing" +#~ msgstr "ମିଶ୍ରଣ ପାଇଁ ଅନୁପସ୍ଥିତ %s ଅନୁଲଗ୍ନ ଆବଶ୍ୟକ" -#: ../src/ui/theme-viewer.c:78 -msgid "/Windows/_Modal dialog" -msgstr "/ୱିଣ୍ଡୋ/ଅବସ୍ଥା ସଂଳାପ (_M)" +#~ msgid "" +#~ "Some other program is already using the key %s with modifiers %x as a " +#~ "binding\n" +#~ msgstr "ଏକ ଅଲଗା କାରିକା ପୂର୍ବରୁ ଚାବି %sକୁ ରୂପାନ୍ତରକ %x ସହିତ ବନ୍ଧନ ରୂପେ ବ୍ଯବହାର କରୁଛି\n" -#: ../src/ui/theme-viewer.c:79 -msgid "/Windows/_Utility" -msgstr "/ୱିଣ୍ଡୋ/ସାଧନ (_U)" +#~| msgid "\"%s\" is not a valid value for focus attribute" +#~ msgid "\"%s\" is not a valid accelerator\n" +#~ msgstr "\"%s\" ଟି ଗୋଟିଏ ବୈଧ ତ୍ୱରକ ନୁହଁ\n" -#: ../src/ui/theme-viewer.c:80 -msgid "/Windows/_Splashscreen" -msgstr "/ୱିଣ୍ଡୋ/ଛିଟା ପରଦା (_S)" +#~ msgid "" +#~ "Workarounds for broken applications disabled. Some applications may not " +#~ "behave properly.\n" +#~ msgstr "" +#~ "ଅବୈଧ ପ୍ରୟୋଗ ପାଇଁ ଅନ୍ଯତର ଉପାୟଗୁଡ଼ିକ ଅସମର୍ଥ କରାଯାଇଛି. କିଛି ପ୍ରୟୋଗ ଠିକ ଭାବେ ନ ଚଳିପାରନ୍ତି.\n" -#: ../src/ui/theme-viewer.c:81 -msgid "/Windows/_Top dock" -msgstr "/ୱିଣ୍ଡୋ/ଉପର ପୋତାଶ୍ରୟ (_T)" +#~ msgid "Could not parse font description \"%s\" from GSettings key %s\n" +#~ msgstr "ଅକ୍ଷରରୂପ ବର୍ଣ୍ଣନା \"%s\" କୁ GSettings କି %s ରୁ ବିଶ୍ଳେଷଣ କରିପାରିଲା ନାହିଁ\n" -#: ../src/ui/theme-viewer.c:82 -msgid "/Windows/_Bottom dock" -msgstr "/ୱିଣ୍ଡୋ/ତଳ ପୋତାଶ୍ରୟ (_B)" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" +#~ msgstr "" +#~ "ବିନ୍ଯାସ ତଥ୍ଯାଧାରରେ ପାୟାଯାଇଥିବା \"%s\" ମାଉସ ଚାବି ରୂପାନ୍ତରକ ପାଇଁ ଗୋଟିଏ ବୈଧ ମୂଲ୍ଯ ନୁହେଁ\n" -#: ../src/ui/theme-viewer.c:83 -msgid "/Windows/_Left dock" -msgstr "/ୱିଣ୍ଡୋ/ବାମ ପୋତାଶ୍ରୟ (_L)" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for " +#~ "keybinding \"%s\"\n" +#~ msgstr "" +#~ "ବିନ୍ଯାସ ତଥ୍ଯାଧାରରେ ପାୟାଯାଇଥିବା \"%s\" ଚାବିବନ୍ଧନୀ \"%s\" ପାଇଁ ଗୋଟିଏ ବୈଧ ମୂଲ୍ଯ ନୁହେଁ\n" -#: ../src/ui/theme-viewer.c:84 -msgid "/Windows/_Right dock" -msgstr "/ୱିଣ୍ଡୋ/ଡାହାଣ ପୋତାଶ୍ରୟ (_R)" +#~ msgid "" +#~ "Could not acquire window manager selection on screen %d display \"%s\"\n" +#~ msgstr "ପ୍ରଦର୍ଶକ \"%2$s\"ରେ ପରଦା %1$dର ୱିଣ୍ଢୋ ପରିଚାଳକ ଚୟନ ବୁଝିହେଲା ନାହିଁ\n" -#: ../src/ui/theme-viewer.c:85 -msgid "/Windows/_All docks" -msgstr "/ୱିଣ୍ଡୋ/ସବୁ ପୋତାଶ୍ରୟ (_A)" +#~ msgid "Could not release screen %d on display \"%s\"\n" +#~ msgstr "ପ୍ରଦର୍ଶକ \"%2$s\"ରେ ପରଦା %1$dକୁ ନୁକ୍ତ କରିହେଲା ନାହିଁ\n" -#: ../src/ui/theme-viewer.c:86 -msgid "/Windows/Des_ktop" -msgstr "/ୱିଣ୍ଡୋ/ଡେସ୍କଟପ୍ (_k)" +#~ msgid "Could not create directory '%s': %s\n" +#~ msgstr "'%s' ଡିରେକ୍ଟୋରି ସୃଷ୍ଟି କରିହେଲା ନାହିଁ: %s\n" -#: ../src/ui/theme-viewer.c:135 -msgid "Open another one of these windows" -msgstr "ଏହି ୱିଣ୍ଡୋରୁ ଆହୁରି ଗୋଟିଏ ଖୋଲନ୍ତୁ" +#~ msgid "Could not open session file '%s' for writing: %s\n" +#~ msgstr "ଅଧିବେଶନ ଫାଇଲ '%s' ଲିଖନ ପାଇଁ ଖୋଲିହେଲା ନାହିଁ: %s\n" -#: ../src/ui/theme-viewer.c:142 -msgid "This is a demo button with an 'open' icon" -msgstr "ଏହା ଗୋଟିଏ ପ୍ରଦର୍ଶନ ଚାବି, 'ଖୋଲନ୍ତୁ' ଚିତ୍ରସଙ୍କେତ ସହିତ" +#~ msgid "Error writing session file '%s': %s\n" +#~ msgstr "ଅଧିବେଶନ ଫାଇଲ '%s' ଲେଖିବାରେ ତ୍ରୁଟି: %s\n" -#: ../src/ui/theme-viewer.c:149 -msgid "This is a demo button with a 'quit' icon" -msgstr "ଏହା ଗୋଟିଏ ପ୍ରଦର୍ଶନ ଚାବି, 'ବିଦାୟ' ଚିତ୍ରସଙ୍କେତ ସହିତ" +#~ msgid "Error closing session file '%s': %s\n" +#~ msgstr "ଅଧିବେଶନ ଫାଇଲ '%s' ବନ୍ଦ କରିବାରେ ତ୍ରୁଟି: %s\n" -#: ../src/ui/theme-viewer.c:242 -msgid "This is a sample message in a sample dialog" -msgstr "ଏହା ଗୋଟିଏ ନମୁନା ସଂଳାପରେ ଗୋଟିଏ ନମୁନା ସନ୍ଦେଶ" +#~ msgid "Failed to parse saved session file: %s\n" +#~ msgstr "ସଞ୍ଚିତ ଅଧିବେଶନ ଫାଇଲ ବିଶ୍ଳେଷଣ କରିବାରେ ଅସଫଳ: %s\n" -#: ../src/ui/theme-viewer.c:325 -#, c-format -msgid "Fake menu item %d\n" -msgstr "ନକଲି ମେନୁ ବସ୍ତୁ %d\n" +#~ msgid "<mutter_session> attribute seen but we already have the session ID" +#~ msgstr "<mutter_session> ଗୁଣ ଦେଖାଗଲା, କିନ୍ତୁ ଆମ ପାଖରେ ଅଧିବେଶନ ID ପୂର୍ବରୁ ଅଛି" -#: ../src/ui/theme-viewer.c:359 -msgid "Border-only window" -msgstr "କେବଳ ଧାରବାଲା ୱିଣ୍ଡୋ" +#~ msgid "Unknown attribute %s on <%s> element" +#~ msgstr "<%s> ଉପାଦାନ ଉପରେ ଅଜଣା ଗୁଣଧର୍ମ %s" -#: ../src/ui/theme-viewer.c:361 -msgid "Bar" -msgstr "ପିଣ୍ଡ" +#~ msgid "nested <window> tag" +#~ msgstr "ଘେରାଯାଇଥିବା <window> ସୂଚକ" -#: ../src/ui/theme-viewer.c:378 -msgid "Normal Application Window" -msgstr "ସାଧାରଣ ପ୍ରୟୋଗ ୱିଣ୍ଡୋ" +#~ msgid "Unknown element %s" +#~ msgstr "ଅଜଣା ଉପାଦାନ %s" -#: ../src/ui/theme-viewer.c:382 -msgid "Dialog Box" -msgstr "ସଂଳାପ ବାକ୍ସ" +#~ msgid "Failed to open debug log: %s\n" +#~ msgstr "ତ୍ରୁଟିମୁକ୍ତ ବିବରଣୀ ଖୋଲିବାରେ ଅସଫଳ: %s\n" -#: ../src/ui/theme-viewer.c:386 -msgid "Modal Dialog Box" -msgstr "ଧାରା ସଂଳାପ ବାକ୍ସ" +#~ msgid "Failed to fdopen() log file %s: %s\n" +#~ msgstr "%s ବିବରଣୀ ଫାଇଲକୁ fdopen() କରିବୋରେ ଅସଫଳ: %s\n" -#: ../src/ui/theme-viewer.c:390 -msgid "Utility Palette" -msgstr "ସାଧନ ଥାଳି" +#~ msgid "Opened log file %s\n" +#~ msgstr "%s ବିବରଣୀ ଫାଇଲ ଖୋଲାହେଲା\n" -#: ../src/ui/theme-viewer.c:394 -msgid "Torn-off Menu" -msgstr "ଛିଣ୍ଡା ମେନୁ" +#~ msgid "Window manager: " +#~ msgstr "ୱିଣ୍ଡୋ ପରିଚାଳକ" -#: ../src/ui/theme-viewer.c:398 -msgid "Border" -msgstr "ଧାର" +#~ msgid "Bug in window manager: " +#~ msgstr "ୱିଣ୍ଡୋ ପରିଚାଳକରେ ତ୍ରୁଟି" -#: ../src/ui/theme-viewer.c:726 -#, c-format -msgid "Button layout test %d" -msgstr "ଚାବି ବିନ୍ଯାସ ପରିକ୍ଷଣ %d" +#~ msgid "Window manager warning: " +#~ msgstr "ୱିଣ୍ଡୋ ପରିଚାଳକ ଚେତାବନୀ" -#: ../src/ui/theme-viewer.c:755 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "ଗୋଟିଏ ୱିଣ୍ଡୋ ବନ୍ଧେଇ ଆଙ୍କିବାକୁ %g ମିଲିସେକଣ୍ଡ" +#~ msgid "Window manager error: " +#~ msgstr "ୱିଣ୍ଡୋ ପରିଚାଳକ ତ୍ରୁଟି" -#: ../src/ui/theme-viewer.c:798 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "ବ୍ଯବହାର: metacity-theme-viewer [ପ୍ରସଙ୍ଗ ନାମ]\n" +#~ msgid "" +#~ "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " +#~ "window as specified in the ICCCM.\n" +#~ msgstr "" +#~ "%s ୱିଣ୍ଡୋ WM_CLIENT_LEADERରେ (ଯେପରି ICCCM ନିର୍ଦ୍ଦିଷ୍ଟ ହୋଇଛି) ଅପେକ୍ଷା ନିଜ ଉପରେ " +#~ "SM_CLIENT_ID ବିନ୍ଯାସ କରେ.\n" -#: ../src/ui/theme-viewer.c:805 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "ପ୍ରସଙ୍ଗ ଧାରଣ କରିବାରେ ତ୍ରୁଟି: %s\n" +#~ msgid "" +#~ "Window %s sets an MWM hint indicating it isn't resizable, but sets min " +#~ "size %d x %d and max size %d x %d; this doesn't make much sense.\n" +#~ msgstr "" +#~ "%s ୱିଣ୍ଡୋ ଗୋଟିଏ MWM ଆଭାସ ଦ୍ବାରା ସୂଚିତ କରେ କି ତାହାର ଆକେର ବଦଳେଇ ହେବ ନାହିଁ, କିନ୍ତୁ " +#~ "ସର୍ବନିମ୍ନ ଆକାର %d x %d ଓ ସର୍ବାଧିକ ଆକାର %d x %d ବିନ୍ଯାସ କରେ; ଏହାର ବିଶେଷ ମାନେ ନାହିଁ.\n" -#: ../src/ui/theme-viewer.c:811 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "\"%s\" ପ୍ରସଙ୍ଗ %g ସେକଣ୍ଡରେ ଧାରଣ ହେଲା\n" +#~ msgid "Application set a bogus _NET_WM_PID %lu\n" +#~ msgstr "ପ୍ରୟୋଗ ଗୋଟିଏ ନକଲି _NET_WM_PID %lu ବିନ୍ଯାସ କଲା\n" -#: ../src/ui/theme-viewer.c:852 -msgid "Normal Title Font" -msgstr "ସାଧାରଣ ଶୀର୍ଷକ ଅକ୍ଷରରୂପ" +#~ msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +#~ msgstr "ଅବୈଧ WM_TRANSIENT_FOR ୱିଣ୍ଡୋ 0x%lx। ଯାହାକି %s ପାଇଁ ଉଲ୍ଲିଖିତ ।\n" -#: ../src/ui/theme-viewer.c:858 -msgid "Small Title Font" -msgstr "ଛୋଟ ଶୀର୍ଷକ ଅକ୍ଷରରୂପ" +#~ msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" +#~ msgstr "WM_TRANSIENT_FOR ୱିଣ୍ଡୋ 0x%lx %s ପାଇଁ ଲୁପ ନିର୍ମାଣ କରିଥାଏ।\n" -#: ../src/ui/theme-viewer.c:864 -msgid "Large Title Font" -msgstr "ବଡ଼ ଶୀର୍ଷକ ଅକ୍ଷରରୂପ" +#~ msgid "" +#~ "Window 0x%lx has property %s\n" +#~ "that was expected to have type %s format %d\n" +#~ "and actually has type %s format %d n_items %d.\n" +#~ "This is most likely an application bug, not a window manager bug.\n" +#~ "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +#~ msgstr "" +#~ "ୱିଣ୍ଡୋ 0x%lxର ଗୁଣଧର୍ମ %s ଅଛି\n" +#~ "ଯାହାର %s ପ୍ରକାରର %d ସଜ୍ଜିକରଣ ଶୈଳୀ ଥିବା ପ୍ରତ୍ଯାଶିତ ଥିଲା\n" +#~ "ଓ ବାସ୍ତବରେ %s ପ୍ରକାରର %d ସଜ୍ଜିକରଣ ଶୈଳୀ n_items %d ଅଛି.\n" +#~ "ସବୁଠାରୁ ସମ୍ଭବତଃ କି ଏହା ପ୍ରୟୋଗର ତ୍ରୁଟି, ୱିଣ୍ଡୋ ପରିଚାଳକର ନୁହେଁ.\n" +#~ "ୱିଣ୍ଡୋର ଶୀର୍ଷକ ହେଲା \"%s\" class=\"%s\" name=\"%s\"\n" -#: ../src/ui/theme-viewer.c:869 -msgid "Button Layouts" -msgstr "ଚାବି ବିନ୍ଯାସଗୁଡ଼ିକ" +#~ msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +#~ msgstr "ୱିଣ୍ଡୋ 0x%2$lxର %1$s ଗୁଣଧର୍ମରେ ଅବୈଧ ୟି.ଟି.ଏଫ.-୮ ଅଛି\n" -#: ../src/ui/theme-viewer.c:874 -msgid "Benchmark" -msgstr "ମାନଦଣ୍ଡ" +#~ msgid "" +#~ "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the " +#~ "list\n" +#~ msgstr "ୱିଣ୍ଡୋ 0x%2$lxର %1$s ଗୁଣଧର୍ମର ତାଲିକାରେ %3$d ବସ୍ତୁରେ ଅବୈଧ ୟି.ଟି.ଏଫ.-୮ ଅଛି\n" -#: ../src/ui/theme-viewer.c:921 -msgid "Window Title Goes Here" -msgstr "ୱିଣ୍ଡୋ ଶୀର୍ଷକ ଏଇଠି" +#~ msgid "Usage: %s\n" +#~ msgstr "ବ୍ଯବହାର: %s\n" -#: ../src/ui/theme-viewer.c:1025 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"%d ବନ୍ଧେଇ ଆଙ୍କିବାକୁ %g ଗ୍ରାହକ-ପକ୍ଷ ସେକଣ୍ଡ (ପ୍ରତି ବନ୍ଧେଇକୁ %g ମିଲିସେକଣ୍ଡ) ଓ ଙଡ଼ି ଅନୁସାରେ %g " -"ସେକଣ୍ଡ, ଏକ୍ସ ସେବକ ସମ୍ବଳଗୁଡ଼ିକୁ ମିଶାଇ (ପ୍ରତି ବନ୍ଧେଇକୁ %g ମିଲିସେକଣ୍ଡ)\n" +#~ msgid "Mi_nimize" +#~ msgstr "କ୍ଷୁଦ୍ରତମ କରନ୍ତୁ (_n)" -#: ../src/ui/theme-viewer.c:1244 -msgid "position expression test returned TRUE but set error" -msgstr "ଅବସ୍ଥାନ ଅଭିବ୍ଯକ୍ତି ପରୀକ୍ଷଣ ସତ ଫେରାଇ ତ୍ରୁଟି ବିନ୍ଯାସ କରିଛି" +#~ msgid "Ma_ximize" +#~ msgstr "ବୃହତ୍ତମ କରନ୍ତୁ (_x)" -#: ../src/ui/theme-viewer.c:1246 -msgid "position expression test returned FALSE but didn't set error" -msgstr "ଅବସ୍ଥାନ ଅଭିବ୍ଯକ୍ତି ପରୀକ୍ଷଣ ମିଛ ଫେରାଇ ତ୍ରୁଟି ବିନ୍ଯାସ କରି ନାବିଁ" +#~ msgid "Unma_ximize" +#~ msgstr "ସାଧାରଣ ଆକାର ଦିଅନ୍ତୁ (_x)" -#: ../src/ui/theme-viewer.c:1250 -msgid "Error was expected but none given" -msgstr "ତ୍ରୁଟି ପ୍ରତ୍ଯାଶିତ ଥିଲା କିନ୍ତୁ ଦିଆଯାଇ ନାହିଁ" +#~ msgid "Roll _Up" +#~ msgstr "ଉପରକୁ ଗୁଡ଼ାନ୍ତୁ (_U)" -#: ../src/ui/theme-viewer.c:1252 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "%d ତ୍ରୁଟି ପ୍ରତ୍ଯାଶିତ ଥିଲା କିନ୍ତୁ %d ଦିଆଯାଇଛି" +# Should have been "ଗୁଡ଼ା ହୋଇଥିବାକୁ ଖୋଲନ୍ତୁ". Shortened for menu +#~ msgid "_Unroll" +#~ msgstr "ଖୋଲନ୍ତୁ (_U)" -#: ../src/ui/theme-viewer.c:1258 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "ତ୍ରୁଟି ପ୍ରତ୍ଯାଶିତ ନ ଥିଲା କିନ୍ତୁ ଦିଆଯାଇଛି: %s" +#~ msgid "_Move" +#~ msgstr "ଘୁଞ୍ଚାନ୍ତୁ (_M)" -#: ../src/ui/theme-viewer.c:1262 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "x ମୂଲ୍ଯ %d ଥିଲା, %d ପ୍ରତ୍ଯାଶିତ ଥିଲା" +#~ msgid "_Resize" +#~ msgstr "ଆକାର ବଦଳାନ୍ତୁ (_R)" -#: ../src/ui/theme-viewer.c:1265 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "y ମୂଲ୍ଯ %d ଥିଲା, %d ପ୍ରତ୍ଯାଶିତ ଥିଲା" +#~ msgid "Move Titlebar On_screen" +#~ msgstr "ଶୀର୍ଷକ ପରଦାକୁ ପଟି ଘୁଞ୍ଚାନ୍ତୁ (_s)" -#: ../src/ui/theme-viewer.c:1330 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "%2$g ସେକଣ୍ଡରେ %1$d ସ୍ଥାନ ନିର୍ଣ୍ଣୟ ଅଭିବ୍ଯକ୍ତି ବିଶ୍ଳେଷିତ (%3$g ସେକଣ୍ଡ ମାଧ୍ଯମାନ)\n" +#~ msgid "Always on _Top" +#~ msgstr "ସର୍ବଦା ଉପରେ (_T)" + +#~ msgid "_Always on Visible Workspace" +#~ msgstr "ସଦାବେଳେ ଦୃଶ୍ଯମାନ କାର୍ଯ୍ଯକ୍ଷେତ୍ରରେ (_A)" + +#~ msgid "_Only on This Workspace" +#~ msgstr "କେବଳ ଏହି କାର୍ଯ୍ଯକ୍ଷେତ୍ରରେ (_O)" + +#~ msgid "Move to Workspace _Left" +#~ msgstr "ବାମ କାର୍ଯ୍ଯକ୍ଷେତ୍ରକୁ ପଠାନ୍ତୁ (_L)" + +#~ msgid "Move to Workspace R_ight" +#~ msgstr "ଡାହାଣ କାର୍ଯ୍ଯକ୍ଷେତ୍ରକୁ ପଠାନ୍ତୁ (_R)" + +#~ msgid "Move to Workspace _Up" +#~ msgstr "ଉପର କାର୍ଯ୍ଯକ୍ଷେତ୍ରକୁ ପଠାନ୍ତୁ (_U)" + +#~ msgid "Move to Workspace _Down" +#~ msgstr "ତଳ କାର୍ଯ୍ଯକ୍ଷେତ୍ରକୁ ପଠାନ୍ତୁ (_D)" + +#~ msgid "_Close" +#~ msgstr "ବନ୍ଦ କରନ୍ତୁ (_C)" + +#~ msgid "Workspace %d%n" +#~ msgstr "କାର୍ଯ୍ଯକ୍ଷେତ୍ର %d%n" + +#~ msgid "Workspace 1_0" +#~ msgstr "କାର୍ଯ୍ଯକ୍ଷେତ୍ର 1_0" + +#~ msgid "Workspace %s%d" +#~ msgstr "କାର୍ଯ୍ଯକ୍ଷେତ୍ର %s%d" + +#~ msgid "Move to Another _Workspace" +#~ msgstr "ଅଲଗା କାର୍ଯ୍ଯକ୍ଷେତ୍ରକୁ ପଠାନ୍ତୁ (_W)" + +#~ msgid "Shift" +#~ msgstr "Shift" + +#~ msgid "Ctrl" +#~ msgstr "Ctrl" + +#~ msgid "Alt" +#~ msgstr "Alt" + +#~ msgid "Meta" +#~ msgstr "Meta" + +#~ msgid "Super" +#~ msgstr "Super" + +#~ msgid "Hyper" +#~ msgstr "Hyper" + +#~ msgid "Mod2" +#~ msgstr "Mod2" + +#~ msgid "Mod3" +#~ msgstr "Mod3" + +#~ msgid "Mod4" +#~ msgstr "Mod4" + +#~ msgid "Mod5" +#~ msgstr "Mod5" + +#~ msgid "_Windows" +#~ msgstr "ୱିଣ୍ଡୋଗୁଡ଼ିକ (_W)" + +#~ msgid "_Dialog" +#~ msgstr "ସଂଳାପ (_D)" + +#~ msgid "_Modal dialog" +#~ msgstr "ଅବସ୍ଥା ସଂଳାପ (_M)" + +#~ msgid "_Utility" +#~ msgstr "ଉପଯୋଗିତା (_U)" + +#~ msgid "_Splashscreen" +#~ msgstr "ଛିଟା ପରଦା (_S)" + +#~ msgid "_Top dock" +#~ msgstr "ଉପର ପୋତାଶ୍ରୟ (_T)" + +#~ msgid "_Bottom dock" +#~ msgstr "ତଳ ପୋତାଶ୍ରୟ (_B)" + +#~ msgid "_Left dock" +#~ msgstr "ବାମ ପୋତାଶ୍ରୟ (_L)" + +#~ msgid "_Right dock" +#~ msgstr "ଡାହାଣ ପୋତାଶ୍ରୟ (_R)" + +#~ msgid "_All docks" +#~ msgstr "ସମସ୍ତ ପୋତାଶ୍ରୟ (_A)" + +#~ msgid "Des_ktop" +#~ msgstr "ଡେସ୍କଟପ୍ (_k)" + +#~ msgid "Open another one of these windows" +#~ msgstr "ଏହି ୱିଣ୍ଡୋରୁ ଆହୁରି ଗୋଟିଏ ଖୋଲନ୍ତୁ" + +#~ msgid "This is a demo button with an 'open' icon" +#~ msgstr "ଏହା ଗୋଟିଏ ପ୍ରଦର୍ଶନ ଚାବି, 'ଖୋଲନ୍ତୁ' ଚିତ୍ରସଙ୍କେତ ସହିତ" + +#~ msgid "This is a demo button with a 'quit' icon" +#~ msgstr "ଏହା ଗୋଟିଏ ପ୍ରଦର୍ଶନ ଚାବି, 'ବିଦାୟ' ଚିତ୍ରସଙ୍କେତ ସହିତ" + +#~ msgid "This is a sample message in a sample dialog" +#~ msgstr "ଏହା ଗୋଟିଏ ନମୁନା ସଂଳାପରେ ଗୋଟିଏ ନମୁନା ସନ୍ଦେଶ" + +#~ msgid "Fake menu item %d\n" +#~ msgstr "ନକଲି ମେନୁ ବସ୍ତୁ %d\n" + +#~ msgid "Border-only window" +#~ msgstr "କେବଳ ଧାରବାଲା ୱିଣ୍ଡୋ" + +#~ msgid "Bar" +#~ msgstr "ପିଣ୍ଡ" + +#~ msgid "Normal Application Window" +#~ msgstr "ସାଧାରଣ ପ୍ରୟୋଗ ୱିଣ୍ଡୋ" + +#~ msgid "Dialog Box" +#~ msgstr "ସଂଳାପ ବାକ୍ସ" + +#~ msgid "Modal Dialog Box" +#~ msgstr "ଧାରା ସଂଳାପ ବାକ୍ସ" + +#~ msgid "Utility Palette" +#~ msgstr "ସାଧନ ଥାଳି" + +#~ msgid "Torn-off Menu" +#~ msgstr "ଛିଣ୍ଡା ମେନୁ" + +#~ msgid "Border" +#~ msgstr "ଧାର" + +#~ msgid "Attached Modal Dialog" +#~ msgstr "ସଂଲଗ୍ନ ଧାରା ସଂଳାପ" + +#~ msgid "Button layout test %d" +#~ msgstr "ଚାବି ବିନ୍ଯାସ ପରିକ୍ଷଣ %d" + +#~ msgid "%g milliseconds to draw one window frame" +#~ msgstr "ଗୋଟିଏ ୱିଣ୍ଡୋ ବନ୍ଧେଇ ଆଙ୍କିବାକୁ %g ମିଲିସେକଣ୍ଡ" + +#~ msgid "Usage: metacity-theme-viewer [THEMENAME]\n" +#~ msgstr "ବ୍ଯବହାର: metacity-theme-viewer [ପ୍ରସଙ୍ଗ ନାମ]\n" + +#~ msgid "Error loading theme: %s\n" +#~ msgstr "ପ୍ରସଙ୍ଗ ଧାରଣ କରିବାରେ ତ୍ରୁଟି: %s\n" + +#~ msgid "Loaded theme \"%s\" in %g seconds\n" +#~ msgstr "\"%s\" ପ୍ରସଙ୍ଗ %g ସେକଣ୍ଡରେ ଧାରଣ ହେଲା\n" + +#~ msgid "Normal Title Font" +#~ msgstr "ସାଧାରଣ ଶୀର୍ଷକ ଅକ୍ଷରରୂପ" + +#~ msgid "Small Title Font" +#~ msgstr "ଛୋଟ ଶୀର୍ଷକ ଅକ୍ଷରରୂପ" + +#~ msgid "Large Title Font" +#~ msgstr "ବଡ଼ ଶୀର୍ଷକ ଅକ୍ଷରରୂପ" + +#~ msgid "Button Layouts" +#~ msgstr "ଚାବି ବିନ୍ଯାସଗୁଡ଼ିକ" + +#~ msgid "Benchmark" +#~ msgstr "ମାନଦଣ୍ଡ" + +#~ msgid "Window Title Goes Here" +#~ msgstr "ୱିଣ୍ଡୋ ଶୀର୍ଷକ ଏଇଠି" + +#~ msgid "" +#~ "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and " +#~ "%g seconds wall clock time including X server resources (%g milliseconds " +#~ "per frame)\n" +#~ msgstr "" +#~ "%d ବନ୍ଧେଇ ଆଙ୍କିବାକୁ %g ଗ୍ରାହକ-ପକ୍ଷ ସେକଣ୍ଡ (ପ୍ରତି ବନ୍ଧେଇକୁ %g ମିଲିସେକଣ୍ଡ) ଓ ଙଡ଼ି ଅନୁସାରେ %g " +#~ "ସେକଣ୍ଡ, ଏକ୍ସ ସେବକ ସମ୍ବଳଗୁଡ଼ିକୁ ମିଶାଇ (ପ୍ରତି ବନ୍ଧେଇକୁ %g ମିଲିସେକଣ୍ଡ)\n" + +#~ msgid "position expression test returned TRUE but set error" +#~ msgstr "ଅବସ୍ଥାନ ଅଭିବ୍ଯକ୍ତି ପରୀକ୍ଷଣ ସତ ଫେରାଇ ତ୍ରୁଟି ବିନ୍ଯାସ କରିଛି" + +#~ msgid "position expression test returned FALSE but didn't set error" +#~ msgstr "ଅବସ୍ଥାନ ଅଭିବ୍ଯକ୍ତି ପରୀକ୍ଷଣ ମିଛ ଫେରାଇ ତ୍ରୁଟି ବିନ୍ଯାସ କରି ନାବିଁ" + +#~ msgid "Error was expected but none given" +#~ msgstr "ତ୍ରୁଟି ପ୍ରତ୍ଯାଶିତ ଥିଲା କିନ୍ତୁ ଦିଆଯାଇ ନାହିଁ" + +#~ msgid "Error %d was expected but %d given" +#~ msgstr "%d ତ୍ରୁଟି ପ୍ରତ୍ଯାଶିତ ଥିଲା କିନ୍ତୁ %d ଦିଆଯାଇଛି" + +#~ msgid "Error not expected but one was returned: %s" +#~ msgstr "ତ୍ରୁଟି ପ୍ରତ୍ଯାଶିତ ନ ଥିଲା କିନ୍ତୁ ଦିଆଯାଇଛି: %s" + +#~ msgid "x value was %d, %d was expected" +#~ msgstr "x ମୂଲ୍ଯ %d ଥିଲା, %d ପ୍ରତ୍ଯାଶିତ ଥିଲା" + +#~ msgid "y value was %d, %d was expected" +#~ msgstr "y ମୂଲ୍ଯ %d ଥିଲା, %d ପ୍ରତ୍ଯାଶିତ ଥିଲା" + +#~ msgid "" +#~ "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" +#~ msgstr "%2$g ସେକଣ୍ଡରେ %1$d ସ୍ଥାନ ନିର୍ଣ୍ଣୟ ଅଭିବ୍ଯକ୍ତି ବିଶ୍ଳେଷିତ (%3$g ସେକଣ୍ଡ ମାଧ୍ଯମାନ)\n" + +#~| msgid "Window manager: " +#~ msgid "Window Management" +#~ msgstr "ୱିଣ୍ଡୋ ପରିଚାଳନା" + +#~ msgid "Failed to parse message \"%s\" from dialog process\n" +#~ msgstr "ସଂଳାପ ସଂସାଧନରୁ \"%s\" ସନ୍ଦେଶକୁ ବିଶ୍ଳେଷଣ କରିବାରେ ଅସମର୍ଥ\n" + +#~ msgid "Error reading from dialog display process: %s\n" +#~ msgstr "ସଂଳାପ ପ୍ରଦର୍ଶନ ସଂସାଧନରୁ ପଢ଼ିବାରେ ତ୍ରୁଟି: %s\n" + +#~ msgid "" +#~ "Error launching metacity-dialog to ask about killing an application: %s\n" +#~ msgstr "" +#~ "ଗୋଟିଏ ପ୍ରୟୋଗର ସମାପନ କରିବା ବିଷୟରେ ପଚାରିବା ପାଇଁ ମେଟାସିଟି ସଂଳାପ ଚଳାଇବାରେ ତ୍ରୁଟି: %s\n" + +#~ msgid "Failed to get hostname: %s\n" +#~ msgstr "ହୋଷ୍ଟ ନାମ ପାଇବାରେ ଅସମର୍ଥ: %s\n" + +#~ msgid "" +#~ "Lost connection to the display '%s';\n" +#~ "most likely the X server was shut down or you killed/destroyed\n" +#~ "the window manager.\n" +#~ msgstr "" +#~ "ପ୍ରଦର୍ଶିକା '%s'; ସହିତ ସଂୟୋଗ କଟି ଗଲା\n" +#~ "ସମ୍ଭବତଃ କି ଏକ୍ସ ସେବକ ବନ୍ଦ କରା ଦିଆ ଯାଇଛି ବା ଆପଣ ୱିଣ୍ଡୋ ପରିଚାଳକକୁ ସମାପ୍ତ/ନଷ୍ଟ " +#~ "କରିଦେଇଛନ୍ତି.\n" + +#~ msgid "Fatal IO error %d (%s) on display '%s'.\n" +#~ msgstr "ପ୍ରଦର୍ଶିକା '%3$s'ରେ ସାଂଘାତିକ ଆଇ.ଓ. (ନିବେଶ/ନିର୍ଗମ) ତ୍ରୁଟି %1$d (%2$s).\n" + +#~| msgid "" +#~| "There was an error running \"%s\":\n" +#~| "%s." +#~ msgid "" +#~ "There was an error running <tt>%s</tt>:\n" +#~ "\n" +#~ "%s" +#~ msgstr "" +#~ "ସେଠାରେ ଗୋଟିଏ ତ୍ରୁଟି ଚାଲୁଅଛି <tt>%s</tt>:\n" +#~ "\n" +#~ "%s" + +#~ msgid "No command %d has been defined.\n" +#~ msgstr "%d ନିର୍ଦ୍ଦେଶ ବ୍ଯାଖ୍ଯା କରାଯାଇ ନାହିଁ.\n" + +#~ msgid "No terminal command has been defined.\n" +#~ msgstr "କୌଣସି ଟର୍ମିନାଲ ନିର୍ଦ୍ଦେଶ ବ୍ଯାଖ୍ଯା କରାଯାଇ ନାହିଁ.\n" + +#~| msgid "Compositing Manager" +#~ msgid "Turn compositing on" +#~ msgstr "ମିଶ୍ରଣ ପ୍ରକ୍ରିୟାକୁ ଅନକରନ୍ତୁ" + +#~ msgid "Turn compositing off" +#~ msgstr "ମିଶ୍ରଣ ପ୍ରକ୍ରିୟାକୁ ଅଫକରନ୍ତୁ" + +#~ msgid "Failed to restart: %s\n" +#~ msgstr "ପୁନଃ ପ୍ରାରମ୍ଭ କରିବାରେ ଅସମର୍ଥ: %s\n" + +#~ msgid "GConf key '%s' is set to an invalid value\n" +#~ msgstr "ଜିକନ୍ଫ ଚାବି '%s' ଅବୈଧ ମୂଲ୍ଯକୁ ବିନ୍ଯାସ କରାଯାଇଛି\n" + +#~| msgid "%d stored in GConf key %s is out of range 0 to %d\n" +#~ msgid "%d stored in GConf key %s is out of range %d to %d\n" +#~ msgstr "%d ଯାହାକି GConf କି %s ମଧ୍ଯରେ ସଂରକ୍ଷିତ ଥାଏ, ପରିସର %d ବାହାରୁ %dରେ ଅଛି\n" + +#~ msgid "GConf key \"%s\" is set to an invalid type\n" +#~ msgstr "ଜିକନ୍ଫ ଚାବି \"%s\" ଅବୈଧ ପ୍ରକାରକୁ ବିନ୍ଯାସ କରାଯାଇଛି\n" + +#~ msgid "Error setting number of workspaces to %d: %s\n" +#~ msgstr "କାର୍ଯ୍ଯକ୍ଷେତ୍ର ସଂଖ୍ଯାକୁ %d ଭଳି ବିନ୍ଯାସ କରିବାରେ ତ୍ରୁଟି: %s\n" + +#~ msgid "Error setting name for workspace %d to \"%s\": %s\n" +#~ msgstr "କାର୍ଯ୍ଯକ୍ଷେତ୍ର %dର ନାମ \"%s\" ବିନ୍ଯାସ କରିବାରେ ତ୍ରୁଟି: %s\n" + +#~| msgid "Error setting name for workspace %d to \"%s\": %s\n" +#~ msgid "Error setting compositor status: %s\n" +#~ msgstr "ମିଶ୍ରଣ ପ୍ରକ୍ରିୟା ସ୍ଥିତି ବିନ୍ୟାସ କରିବାରେ ତ୍ରୁଟି: %s\n" + +#~| msgid "" +#~| "The keybinding used to close a window. The format looks like \"<" +#~| "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~| "liberal and allows lower or upper case, and also abbreviations such as " +#~| "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~| "special string \"disabled\", then there will be no keybinding for this " +#~| "action." +#~ msgid "" +#~ "The format looks like \"<Control>a\" or <Shift><Alt>F1\".\n" +#~ "\n" +#~ "The parser is fairly liberal and allows lower or upper case, and also " +#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action." +#~ msgstr "" +#~ "ସଜ୍ଜିକରଣ ଶୈଳୀଟି \"<Control>a\" କିମ୍ବା <Shift><Alt>F1\" ପରି ଦେଖାଯାଉଛି।\n" +#~ "\n" +#~ "ବିଶ୍ଳେଷକଟି ବେଶ୍ ଉଦାରମନା, ଓ ଛୋଟ ବା ବଡ଼ ଅକ୍ଷର, ଏବଂ \"<Ctl>\" ଏବଂ \"<Ctrl>\" ଭଳି " +#~ "ସଂକ୍ଷେପ ମଧ୍ଯ ଗ୍ରହଣ କରେ. ଆପଣ ଏହି ଚୟନକୁ ବିଶେଷ ବାକ୍ଯଖଣ୍ଡ \"disabled\" ରୂପେ ବିନ୍ଯାସ କଲେ, " +#~ "ଏହି କାର୍ଯ୍ଯ ପାଇଁ ଚାବିବନ୍ଧନୀ ରହିବ ନାହିଁ।" + +#~| msgid "" +#~| "The keybinding used to close a window. The format looks like \"<" +#~| "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " +#~| "liberal and allows lower or upper case, and also abbreviations such as " +#~| "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " +#~| "special string \"disabled\", then there will be no keybinding for this " +#~| "action." +#~ msgid "" +#~ "The format looks like \"<Control>a\" or <Shift><Alt>F1\".\n" +#~ "\n" +#~ "The parser is fairly liberal and allows lower or upper case, and also " +#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " +#~ "the special string \"disabled\", then there will be no keybinding for " +#~ "this action.\n" +#~ "\n" +#~ "This keybinding may be reversed by holding down the \"shift\" key; " +#~ "therefore, \"shift\" cannot be one of the keys it uses." +#~ msgstr "" +#~ "ସଜ୍ଜିକରଣ ଶୈଳୀଟି \"<Control>a\" କିମ୍ବା <Shift><Alt>F1\" ପରି ଦେଖାଯାଉଛି।\n" +#~ "\n" +#~ "ବିଶ୍ଳେଷକଟି ବେଶ୍ ଉଦାରମନା, ଓ ଛୋଟ ବା ବଡ଼ ଅକ୍ଷର, ଏବଂ \"<Ctl>\" ଏବଂ \"<Ctrl>\" ଭଳି " +#~ "ସଂକ୍ଷେପ ମଧ୍ଯ ଗ୍ରହଣ କରେ. ଆପଣ ଏହି ଚୟନକୁ ବିଶେଷ ବାକ୍ଯଖଣ୍ଡ \"disabled\" ରୂପେ ବିନ୍ଯାସ କଲେ, " +#~ "ଏହି କାର୍ଯ୍ଯ ପାଇଁ ଚାବିବନ୍ଧନୀ ରହିବ ନାହିଁ। \n" +#~ "\"shift\" କି କୁ ଧରିରଖି ଏହି କି ବନ୍ଧନିକୁ ଓଲଟା କରିହେବ; ତେଣୁ, \"shift\" ଏହା ବ୍ୟବହାର କରୁଥିବା " +#~ "କି ମଧ୍ଯରୁ ଗୋଟିଏ ହୋଇନପାରେ।" + +#~ msgid "Failed to read saved session file %s: %s\n" +#~ msgstr "ସଞ୍ଚିତ ଅଧିବେଶନ ଫାଇଲ '%s' ପଢ଼ିବାରେ ଅସଫଳ: %s\n" + +#~ msgid "" +#~ "Error launching metacity-dialog to warn about apps that don't support " +#~ "session management: %s\n" +#~ msgstr "" +#~ "ଅଧିବେଶନ ପରିଚାଳନ ସହାୟକ ନ କରୁଥିବା ପ୍ରୟୋଗଗୁଡ଼ିକ ବିଷୟରେ ଚେତାବନୀ ଜଣାଇବା ପାଇଁ ମେଟାସିଟି-" +#~ "ସଂଳାପ ଚଳାଇବାରେ ତ୍ରୁଟି: %s\n" + +#~ msgid "Metacity" +#~ msgstr "ମେଟାସିଟି" + +#~ msgid "Switch to workspace 8" +#~ msgstr "କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୮କୁ ଯାଆନ୍ତୁ" + +#~ msgid "Switch to workspace 9" +#~ msgstr "କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୯କୁ ଯାଆନ୍ତୁ" + +#~ msgid "Switch to workspace 10" +#~ msgstr "କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୧୦କୁ ଯାଆନ୍ତୁ" + +#~ msgid "Switch to workspace 11" +#~ msgstr "କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୧୧କୁ ଯାଆନ୍ତୁ" + +#~ msgid "Switch to workspace 12" +#~ msgstr "କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୧୨କୁ ଯାଆନ୍ତୁ" + +#~| msgid "Switch to workspace on the left" +#~ msgid "Switch to workspace on the left of the current workspace" +#~ msgstr "ଏହାର ବାମରେ ସ୍ଥିତ କାର୍ଯ୍ଯକ୍ଷେତ୍ରକୁ ଯାଆନ୍ତୁ" + +#, fuzzy +#~| msgid "Switch to workspace on the right" +#~ msgid "Switch to workspace on the right of the current workspace" +#~ msgstr "ଏହାର ଡାହାଣରେ ସ୍ଥିତ କାର୍ଯ୍ଯକ୍ଷେତ୍ରକୁ ଯାଆନ୍ତୁ" + +#~| msgid "Switch to workspace above this one" +#~ msgid "Switch to workspace above the current workspace" +#~ msgstr "ଏହାର ଉପରେ ସ୍ଥିତ କାର୍ଯ୍ଯକ୍ଷେତ୍ରକୁ ଯାଆନ୍ତୁ" + +#~| msgid "Switch to workspace below this one" +#~ msgid "Switch to workspace below the current workspace" +#~ msgstr "ଏହାର ତଳେ ସ୍ଥିତ କାର୍ଯ୍ଯକ୍ଷେତ୍ରକୁ ଯାଆନ୍ତୁ" + +#~| msgid "Move between windows with popup" +#~ msgid "Move between windows of an application, using a popup window" +#~ msgstr "ପପ୍ଅପ୍ ସହିତ ୱିଣ୍ଡୋଗୁଡ଼ିକ ମଧ୍ଯରେ ଘୁଞ୍ଚନ୍ତୁ" + +#~| msgid "Move focus backwards between windows using popup display" +#~ msgid "" +#~ "Move backward between windows of an application, using a popup window" +#~ msgstr "ପପ୍ଅପ୍ ସହିତ ୱିଣ୍ଡୋଗୁଡ଼ିକ ମଧ୍ଯରେ କେନ୍ଦ୍ରକୁ ପଛୁଆ ଘୁଞ୍ଚାନ୍ତୁ" + +#~| msgid "Move between windows with popup" +#~ msgid "Move between windows, using a popup window" +#~ msgstr "ପପ୍ଅପ୍ ସହିତ ୱିଣ୍ଡୋଗୁଡ଼ିକ ମଧ୍ଯରେ ଘୁଞ୍ଚନ୍ତୁ" + +#~| msgid "Move focus backwards between windows using popup display" +#~ msgid "Move backward between windows, using a popup window" +#~ msgstr "ପପ୍ଅପ୍ ସହିତ ୱିଣ୍ଡୋଗୁଡ଼ିକ ମଧ୍ଯରେ କେନ୍ଦ୍ରକୁ ପଛୁଆ ଘୁଞ୍ଚାନ୍ତୁ" + +#~| msgid "Move between panels and the desktop with popup" +#~ msgid "Move between panels and the desktop, using a popup window" +#~ msgstr "ଫଳକ ଓ ପପ୍ଅପ୍ ସହିତ ଡେସ୍କଟପ୍ ମଧ୍ଯରେ ସଙ୍ଗେ ସଙ୍ଗେ ଘୁଞ୍ଚନ୍ତୁ" + +#~| msgid "Move backwards between panels and the desktop with popup" +#~ msgid "Move backward between panels and the desktop, using a popup window" +#~ msgstr "ଫଳକ ଓ ପପ୍ଅପ୍ ସହିତ ଡେସ୍କଟପ୍ ମଧ୍ଯରେ ସଙ୍ଗେ ସଙ୍ଗେ ପଛୁଆ ଘୁଞ୍ଚନ୍ତୁ" + +#~| msgid "Move backwards between windows immediately" +#~ msgid "Move backward between windows of an application immediately" +#~ msgstr "ୱିଣ୍ଡୋଗୁଡ଼ିକ ମଧ୍ଯରେ ସଙ୍ଗେ ସଙ୍ଗେ ପଛୁଆ ଘୁଞ୍ଚନ୍ତୁ" + +#~ msgid "Move between windows immediately" +#~ msgstr "ୱିଣ୍ଡୋଗୁଡ଼ିକ ମଧ୍ଯରେ ସଙ୍ଗେ ସଙ୍ଗେ ଘୁଞ୍ଚନ୍ତୁ" + +#~| msgid "Move backwards between windows immediately" +#~ msgid "Move backward between windows immediately" +#~ msgstr "ୱିଣ୍ଡୋଗୁଡ଼ିକ ମଧ୍ଯରେ ସଙ୍ଗେ ସଙ୍ଗେ ପଛୁଆ ଘୁଞ୍ଚନ୍ତୁ" + +#~ msgid "Move between panels and the desktop immediately" +#~ msgstr "ଫଳକ ଓ ଡେସ୍କଟପ୍ ମଧ୍ଯରେ ସଙ୍ଗେ ସଙ୍ଗେ ଘୁଞ୍ଚନ୍ତୁ" + +#~ msgid "Move backward between panels and the desktop immediately" +#~ msgstr "ଫଳକ ଓ ଡେସ୍କଟପ୍ ମଧ୍ଯରେ ସଙ୍ଗେ ସଙ୍ଗେ ପଛୁଆ ଘୁଞ୍ଚନ୍ତୁ" + +#~| msgid "Show the panel run application dialog" +#~ msgid "Show the panel's \"Run Application\" dialog box" +#~ msgstr "ଫଳକର \"Run Application\" ସଂଳାପ ଦେଖାନ୍ତୁ" + +#~ msgid "Take a screenshot" +#~ msgstr "ପରଦା ପ୍ରତିଛବି ନିଅନ୍ତୁ" + +#~ msgid "Take a screenshot of a window" +#~ msgstr "ଗୋଟିଏ ୱିଣ୍ଡୋର ପରଦା ପ୍ରତିଛବି ନିଅନ୍ତୁ" + +#~ msgid "Run a terminal" +#~ msgstr "ଟର୍ମିନାଲ ଚଳାନ୍ତୁ" + +#~| msgid "Lower window below other windows" +#~ msgid "Toggle whether a window will always be visible over other windows" +#~ msgstr "ୱିଣ୍ଡୋକୁ ଅଲଗା ୱିଣ୍ଡୋ ପଛକୁ ନିଅନ୍ତୁ" + +#~ msgid "Minimize window" +#~ msgstr "ୱିଣ୍ଡୋକୁ ଯଥାସମ୍ଭବ ଛୋଟ କରନ୍ତୁ" + +#~ msgid "Move window to workspace 5" +#~ msgstr "ୱିଣ୍ଡୋକୁ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୫କୁ ଘୁଞ୍ଚାନ୍ତୁ" + +#~ msgid "Move window to workspace 6" +#~ msgstr "ୱିଣ୍ଡୋକୁ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୬କୁ ଘୁଞ୍ଚାନ୍ତୁ" + +#~ msgid "Move window to workspace 7" +#~ msgstr "ୱିଣ୍ଡୋକୁ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୭କୁ ଘୁଞ୍ଚାନ୍ତୁ" + +#~ msgid "Move window to workspace 8" +#~ msgstr "ୱିଣ୍ଡୋକୁ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୮କୁ ଘୁଞ୍ଚାନ୍ତୁ" + +#~ msgid "Move window to workspace 9" +#~ msgstr "ୱିଣ୍ଡୋକୁ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୯କୁ ଘୁଞ୍ଚାନ୍ତୁ" + +#~ msgid "Move window to workspace 10" +#~ msgstr "ୱିଣ୍ଡୋକୁ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୧୦କୁ ଘୁଞ୍ଚାନ୍ତୁ" + +#~ msgid "Move window to workspace 11" +#~ msgstr "ୱିଣ୍ଡୋକୁ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୧୧କୁ ଘୁଞ୍ଚାନ୍ତୁ" + +#~ msgid "Move window to workspace 12" +#~ msgstr "ୱିଣ୍ଡୋକୁ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ୧୨କୁ ଘୁଞ୍ଚାନ୍ତୁ" + +#~| msgid "Move window one workspace to the left" +#~ msgid "Move window to north-west (top left) corner" +#~ msgstr "ୱିଣ୍ଡୋକୁ ଗୋଟିଏ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ବାମକୁ ଘୁଞ୍ଚାନ୍ତୁ" + +#~| msgid "Move window one workspace to the right" +#~ msgid "Move window to north-east (top right) corner" +#~ msgstr "ୱିଣ୍ଡୋକୁ ଗୋଟିଏ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ଡାହାଣକୁ ଘୁଞ୍ଚାନ୍ତୁ" + +#~ msgid "Move window to south-west (bottom left) corner" +#~ msgstr "ୱିଣ୍ଡୋକୁ ଦକ୍ଷିଣ-ପଶ୍ଚିମ (ବାମପଟ ତଳ) କୋଣକୁ ଘୁଞ୍ଚାନ୍ତୁ" + +#~ msgid "Move window to south-east (bottom right) corner" +#~ msgstr "ୱିଣ୍ଡୋକୁ ଦକ୍ଷିଣ-ପୂର୍ବ (ଡାହାଣ ପଟ ତଳ) କୋଣକୁ ଘୁଞ୍ଚାନ୍ତୁ" + +#~ msgid "Move window to north (top) side of screen" +#~ msgstr "ୱିଣ୍ଡୋକୁ ପରଦାର ପଶ୍ଚିମ (ଉପର) କୋଣକୁ ଘୁଞ୍ଚାନ୍ତୁ" + +#~ msgid "Move window to south (bottom) side of screen" +#~ msgstr "ୱିଣ୍ଡୋକୁ ପରଦାର ଦକ୍ଷିଣ (ତଳ) କୋଣକୁ ଘୁଞ୍ଚାନ୍ତୁ" + +#~ msgid "Move window to west (left) side of screen" +#~ msgstr "ୱିଣ୍ଡୋକୁ ପରଦାର ପଶ୍ଚିମ (ବାମ) କୋଣକୁ ଘୁଞ୍ଚାନ୍ତୁ" + +#~| msgid "Move window one workspace down" +#~ msgid "Move window to center of screen" +#~ msgstr "ୱିଣ୍ଡୋକୁ ପରଦାର କେନ୍ଦ୍ରକୁ ଘୁଞ୍ଚାନ୍ତୁ" + +#~ msgid "" +#~ "(Not implemented) Navigation works in terms of applications not windows" +#~ msgstr "(କାର୍ଯ୍ଯକାରୀ ନୁହେଁ) ପଥପ୍ରଦର୍ଶନ ପ୍ରୟୋଗ ହିସାବରେ କାମ କରେ, ୱିଣ୍ଡୋ ହିସାବରେ ନୁହେଁ" + +#~| msgid "" +#~| "A font description string describing a font for window titlebars. The " +#~| "size from the description will only be used if the titlebar_font_size " +#~| "option is set to 0, however. Also, this option is disabled if the " +#~| "titlebar_uses_desktop_font option is set to true. By default, " +#~| "titlebar_font is unset, causing Metacity to fall back to the desktop " +#~| "font even if titlebar_uses_desktop_font is false." +#~ msgid "" +#~ "A font description string describing a font for window titlebars. The " +#~ "size from the description will only be used if the titlebar_font_size " +#~ "option is set to 0. Also, this option is disabled if the " +#~ "titlebar_uses_desktop_font option is set to true." +#~ msgstr "" +#~ "ୱିଣ୍ଡୋ ଶୀର୍ଷକ ପଟିର ଅକ୍ଷରରୂପ ବର୍ଣ୍ଣନା କରୁଥିବା ଗୋଟିଏ ଅକ୍ଷରରୂପ ବର୍ଣ୍ଣନା ବାକ୍ଯଖଣ୍ଡ. " +#~ "ଶୀର୍ଷକପଟି_ଅକ୍ଷରରୂପ_ଆକାର ଚୟନ ଶୂନ୍ଯ ଥିଲେ ହିଁ ବର୍ଣ୍ଣନାରୁ ଆକାରଟି ବ୍ଯବହାର ହେବ. " +#~ "ଶୀର୍ଷକପଟି_ଡେସ୍କଟପ_ଅକ୍ଷରରୂପ_ବ୍ଯବହାର_କରେ ଚୟନ ସତ ନିର୍ଦ୍ଦିଷ୍ଟ ହୋଇଥିଲେ ଭି ଏହି ଚୟନଟି ନିଷ୍କ୍ରିୟ " +#~ "କରାଯାଇଥିବ. ସାଧାରଣରେ ଶୀର୍ଷକପଟି_ଅକ୍ଷରରୂପ ବିନ୍ଯାସ ହୋଇ ନ ଥାଏ, ଯାହା ଯୋଗୁ " +#~ "ଶୀର୍ଷକପଟି_ଡେସ୍କଟପ_ଅକ୍ଷରରୂପ_ବ୍ଯବହାର_କରେ ଅସତ୍ଯ ନିର୍ଦ୍ଦିଷ୍ଟ ହୋଇଥିଲେ ମଧ୍ଯ ମେଟାସିଟି ଡେସ୍କଟପ " +#~ "ଅକ୍ଷରରୂପକୁ ହିଁ ବ୍ଯବହାର କରିବ," + +#~ msgid "Action on title bar double-click" +#~ msgstr "ଶୀର୍ଷକ ପଟିରେ ମାଉସ୍ କୁ ଯୁଗ୍ନ ଭାବରେ ଦବାଇଲେ କି କାମ ଚାଳନ ହେବ" + +#~| msgid "Action on title bar double-click" +#~ msgid "Action on title bar middle-click" +#~ msgstr "ଶୀର୍ଷକ ପଟିରେ ମାଉସ୍ କୁ ଯୁଗ୍ନ ଭାବରେ ଦବାଇଲେ କି କାମ ଚାଳନ ହେବ" + +#~| msgid "Action on title bar double-click" +#~ msgid "Action on title bar right-click" +#~ msgstr "ଶୀର୍ଷକ ପଟିରେ ମାଉସ୍ କୁ ଯୁଗ୍ନ ଭାବରେ ଦବାଇଲେ କି କାମ ଚାଳନ ହେବ" + +#~ msgid "Arrangement of buttons on the titlebar" +#~ msgstr "ଶୀର୍ଷକ ପଟିରେ ଚାବିର ସଜ୍ଜା" + +#~| msgid "" +#~| "Arrangement of buttons on the titlebar. The value should be a string, " +#~| "such as \"menu:minimize,maximize,close\"; the colon separates the left " +#~| "corner of the window from the right corner, and the button names are " +#~| "comma-separated. Duplicate buttons are not allowed. Unknown button names " +#~| "are silently ignored so that buttons can be added in future metacity " +#~| "versions without breaking older versions." +#~ msgid "" +#~ "Arrangement of buttons on the titlebar. The value should be a string, " +#~ "such as \"menu:minimize,maximize,spacer,close\"; the colon separates the " +#~ "left corner of the window from the right corner, and the button names are " +#~ "comma-separated. Duplicate buttons are not allowed. Unknown button names " +#~ "are silently ignored so that buttons can be added in future metacity " +#~ "versions without breaking older versions. A special spacer tag can be " +#~ "used to insert some space between two adjacent buttons." +#~ msgstr "" +#~ "ଶୀର୍ଷକ ପଟିରେ ଚାବିଗୁଡ଼ିକର ସଜ୍ଜା. ଏହି ମୂଲ୍ଯ ଗୌଟିଏ ବାକ୍ଯକଣ୍ଡ ହେବା ଉଚିତ, ଉଦାହରଣ ସ୍ବରୂପ, " +#~ "\"menu:minimize,maximize,spacer,close\"; ବିରାମ ଚିହ୍ନଟି ୱିଣ୍ଡୋର ବାମ ଓ ଡାହାଣ କଣକୁ " +#~ "ବିଭାଜନ କରେ, ଏବଂ ଚାବି ନାମଗୁଡ଼ିକ କମା ଦ୍ବାରା ବିଭାଜିତ. ଦ୍ବିଗୁଣିତ ଚାବି ନିଷେଧ. ଅଜଣା ଚାବି " +#~ "ନାମଗୁଡ଼ିକ ଚୁପଚାପ ଅଗ୍ରାହ୍ଯ କରାଯିବ, ଯାହା ଫଳେ ମେଟାସିଟିର ପୁରୁଣା ସଂସ୍କରଣଗୁଡ଼ିକୁ ପ୍ରଭାବିତ ନ କରି, " +#~ "ନୂଆ ସଂସ୍କରଣଗୁଡ଼ିକରେ ଚାବି ଯୋଡ଼ି ହୋଇପାରିବ." + +#~ msgid "Automatically raises the focused window" +#~ msgstr "କେନ୍ଦ୍ରିତ ୱିଣ୍ଡୋକୁ ଆପେଆପେ ସାମନାକୁ ଆଣେ" + +#~| msgid "" +#~| "Clicking a window while holding down this modifier key will move the " +#~| "window (left click), resize the window (middle click), or show the " +#~| "window menu (right click). Modifier is expressed as \"<Alt>\" or " +#~| "\"<Super>\" for example." +#~ msgid "" +#~ "Clicking a window while holding down this modifier key will move the " +#~ "window (left click), resize the window (middle click), or show the window " +#~ "menu (right click). The left and right operations may be swapped using " +#~ "the \"mouse_button_resize\" key. Modifier is expressed as \"<Alt>\" " +#~ "or \"<Super>\" for example." +#~ msgstr "" +#~ "ଏହି ରୂପାନ୍ତରକ ଚାବିକି ଚାପି ୱିଣ୍ଡୋରେ ମାଉସ୍ ଚାବି ଦବାଇଲେ ୱିଣ୍ଡୋ ଘୁଞ୍ଚା ଯାଇପାରିବ (ବାମ ମାଉସ୍ " +#~ "ଚାବି), ୱିଣ୍ଡୋ ଆକାର ବଦଳା ଯାଇପାରିବ (ମଝି ମାଉସ୍ ଚାବି), ବା ନର ମେନୁ ପ୍ରଦର୍ଶନ କରା ଯାଇପାରିବ " +#~ "(ଡାହାଣ ମାଉସ୍ ଚାବି)। \"mouse_button_resize\" କୁ ବ୍ୟବହାର କରି ବାମ ଏବଂ ଡ଼ାହାଣ " +#~ "ପ୍ରୟୋଗକୁ ବଦଳାଯାଇପାରିବ ରୂପାନ୍ତରକ ଚାବି \"<Alt>\" ବା \"<Super>\" ଭାବରେ " +#~ "ଅଭିବ୍ଯକ୍ତ କରା ଯାଇପାରିବ।" + +#~ msgid "Commands to run in response to keybindings" +#~ msgstr "ଚାବି ବନ୍ଧନ ସ୍ବରୂପେ ଚଳାଇବା ପାଇଁ ନିର୍ଦ୍ଦେଶ" + +#~ msgid "Compositing Manager" +#~ msgstr "ମିଶ୍ରଣ ପରିଚାଳକ" + +#~ msgid "Control how new windows get focus" +#~ msgstr "ନୂତନ ୱିଣ୍ଡୋଗୁଡ଼ିକ କିପରି ଲକ୍ଷ୍ୟ ସାଧନ କରିଥାନ୍ତି ତାହାକୁ ନିୟନ୍ତ୍ରଣ କରନ୍ତୁ" + +#~ msgid "Current theme" +#~ msgstr "ସାମ୍ପ୍ରତିକ ପ୍ରସଙ୍ଗ" + +#~ msgid "Delay in milliseconds for the auto raise option" +#~ msgstr "ସ୍ବଂୟ ସାମନାକୁ ଆଣିବା ପାଇଁ ମିଲିସେକଣ୍ଡରେ ବିଳମ୍ବ" + +#~ msgid "Determines whether Metacity is a compositing manager." +#~ msgstr "ନିର୍ଦ୍ଧାରିତ କରେ ମେଟାସିଟି ଗୋଟିଏ ମିଶ୍ରଣ ପରିଚାଳକ ବା ନୁହେଁ." + +#~ msgid "" +#~ "Determines whether applications or the system can generate audible " +#~ "'beeps'; may be used in conjunction with 'visual bell' to allow silent " +#~ "'beeps'." +#~ msgstr "" +#~ "ନିର୍ଦ୍ଧାରିତ କରେ ପ୍ରୟୋଗ ବା ତନ୍ତ୍ର ଶ୍ରାବ୍ଯ 'ବିପ' ସୃଷ୍ଟି କରିପାରିବ କି; ଏହା ସହିତ 'ଚାକ୍ଷୁଷ ଘଣ୍ଟି' " +#~ "ଚୟନକୁ ଯୋଡ଼ି ନିଃଶବ୍ଦ 'ବିପ' ହ୍ଯବହାର କରା ଯାଇରାରିବ." + +#~ msgid "Disable misfeatures that are required by old or broken applications" +#~ msgstr "ପୁରୁଣା ବା ଅବୈଧ ପ୍ରୟୋଗ ପାଇଁ ଆବଶ୍ଯକ ଦୁର୍ଗୁଣଗୁଡ଼ିକୁ ଅସମର୍ଥ କରନ୍ତୁ" + +#~ msgid "Enable Visual Bell" +#~ msgstr "ଚାକ୍ଷୁଷ ଘଣ୍ଟିକୁ ସମର୍ଥ କରନ୍ତୁ" + +#~ msgid "" +#~ "If true, ignore the titlebar_font option, and use the standard " +#~ "application font for window titles." +#~ msgstr "" +#~ "ଏହା ସତ ହେଲେ, ଶୀର୍ଷକପଟି_ଅକ୍ଷରରୂପ ପସନ୍ଦକୁ ଏଡ଼ାଇ, ୱିଣ୍ଡୋ ଶୀର୍ଷକ ପାଇଁ ସାଧାରଣ ପ୍ରୟୋଗ " +#~ "ଅକ୍ଷରରୂପ ବ୍ଯବହାର କରନ୍ତୁ." + +#, fuzzy +#~| msgid "" +#~| "If true, metacity will give the user less feedback and less sense of " +#~| "\"direct manipulation\", by using wireframes, avoiding animations, or " +#~| "other means. This is a significant reduction in usability for many " +#~| "users, but may allow legacy applications and terminal servers to " +#~| "function when they would otherwise be impractical. However, the " +#~| "wireframe feature is disabled when accessibility is on to avoid weird " +#~| "desktop breakages." +#~ msgid "" +#~ "If true, metacity will give the user less feedback by using wireframes, " +#~ "avoiding animations, or other means. This is a significant reduction in " +#~ "usability for many users, but may allow legacy applications to continue " +#~ "working, and may also be a useful tradeoff for terminal servers. However, " +#~ "the wireframe feature is disabled when accessibility is on." +#~ msgstr "" +#~ "ଏହା ସତ ହେଲେ, ମେଟାସିଟି ତାର ଆକୃତି ବ୍ଯବହାର କରି, ଜୀବନାୟନଗୁଡ଼ିକୁ ଏଡ଼ାଇ, ବା ଅନ୍ଯ ଉପାୟ ଦ୍ବାରା " +#~ "ବ୍ଯବହାରକାରୀକୁ କମ ପ୍ରତିକ୍ରିୟା, ଓ \"ପ୍ରତ୍ଯକ୍ଷ ପ୍ରକଳନ\"ର କମ ଭାବ ଦେବ. ଅନେକ ବ୍ଯବହାରକାରୀଙ୍କ " +#~ "ଏହା ବ୍ଯବହାରଯୋଗ୍ଯତାକୁ ଢେର କମେଇ ଦିଏ, କିନ୍ତୁ ଏହା ଦ୍ବାରା ପୁରୁଣା ପ୍ରୟୋଗ ଓ ଟର୍ମିନାଲ ସେବକ " +#~ "ଚଲାଯାଇ ପାରିବ, ନଚେତ୍ ଜେଉଁଟାକି ଅବ୍ଯବହାରିକ ରୁହନ୍ତା. ତଥାପି, ବ୍ଯବହାରସରଳତା ସକ୍ରିୟ " +#~ "କରାଯାଇଥିଲେ, ଅଦ୍ଭୁତ ଡେସ୍କଟପ ସମସ୍ଯା ଏଡ଼ାଇବା ପାଇଁ, ତାର ଆକୃତି ନିଷ୍କ୍ରିୟ କରାଯିବ." + +# Gora: not exactly translated. Bug report filed re: syntax/length +#~| msgid "" +#~| "If true, then Metacity works in terms of applications rather than " +#~| "windows. The concept is a bit abstract, but in general an application-" +#~| "based setup is more like the Mac and less like Windows. When you focus a " +#~| "window in application-based mode, all the windows in the application " +#~| "will be raised. Also, in application-based mode, focus clicks are not " +#~| "passed through to windows in other applications. The existence of this " +#~| "setting is somewhat questionable. But it's better than having settings " +#~| "for all the specific details of application-based vs. window-based, e.g. " +#~| "whether to pass through clicks. Also, application-based mode is largely " +#~| "unimplemented at the moment." +#~ msgid "" +#~ "If true, then Metacity works in terms of applications rather than " +#~ "windows. The concept is a bit abstract, but in general an application-" +#~ "based setup is more like the Mac and less like Windows. When you focus a " +#~ "window in application-based mode, all the windows in the application will " +#~ "be raised. Also, in application-based mode, focus clicks are not passed " +#~ "through to windows in other applications. Application-based mode is, " +#~ "however, largely unimplemented at the moment." +#~ msgstr "" +#~ "ଏହା ସତ ହେଲେ, ମେଟାସିଟି ୱିଣ୍ଡୋ ବଦଳରେ ପ୍ରୟୋଗର ଭାବରେ କାମ କରେ. ଏହି ଧାରଣାଟି ଟିକେ ଅମୂର୍ତ୍ତ, " +#~ "କିନ୍ତୁ ସାଧାରଣରେ ପ୍ରୟୋଗ-ଆଧାରିତ ବ୍ଯବସ୍ଥାଟି ଅଧିକ ମାକ୍ ଭଳି ଓ କମ ମାଇକ୍ରୋସଫ୍ଟ ୱିଣ୍ଡୋଜ ଭଳି. " +#~ "ପ୍ରୟୋଗ-ଆଧାରିତ ବ୍ଯବସ୍ଥାରେ ଆପଣ ଗୋଟିଏ ୱିଣ୍ଡୋକୁ କେନ୍ଦ୍ରିତ କଲେ, ପ୍ରୟୋଗର ସବୁ ୱିଣ୍ଡୋଗୁଡ଼ିକ ସାମନାକୁ " +#~ "ଅଣାଯିବ. ପ୍ରୟୋଗ-ଆଧାରିତ ବ୍ଯବସ୍ଥାରେ ମଧ୍ଯ କେନ୍ଦ୍ରୀଭୂତ ମାଉସ୍ ଚାପ ଅଲଗା ପ୍ରୟୋଗର ୱିଣ୍ଡୋଗୁଡ଼ିକ " +#~ "ବଢ଼ାଇ ଦିଆଯାଏ ନାହିଁ. ଏହି ବିନ୍ଯାସର ଅସ୍ତିତ୍ବ କିଛିଟି ସନ୍ଦେହଜନକ. କିନ୍ତୁ, ପ୍ରୟୋଗ-ଆଧାରିତ ଓ ୱିଣ୍ଡୋ-" +#~ "ଆଧାରିତ ଧାରାର ସବୁ ବିସ୍ତୃତ ବିବରଣୀ ପାଇଁ ଅଲଗା ବିନ୍ଯାସ ରଖିବା ଅପେକ୍ଷା, ଏହା ଅଧିକ ଭଲ. ଏହି " +#~ "ସମୟରେ, ପ୍ରୟୋଗ-ଆଧାରିତ ଧାରା ମୁଖ୍ଯତଃ ଅକାର୍ଯ୍ଯକାରୀ ରହିଛି." + +#~ msgid "If true, trade off usability for less resource usage" +#~ msgstr "ଏହା ସତ ହେଲେ, ବ୍ଯବହାରଯୋଗ୍ଯତା କମାଇ ମଧ୍ଯ, କମ ସମ୍ବଳ ବ୍ଯବହାର କରନ୍ତୁ" + +#~ msgid "Name of workspace" +#~ msgstr "କାର୍ଯ୍ଯକ୍ଷେତ୍ରର ନାମ" + +#~ msgid "Number of workspaces" +#~ msgstr "କାର୍ଯ୍ଯକ୍ଷେତ୍ରର ସଂଖ୍ଯା" + +#~| msgid "" +#~| "Number of workspaces. Must be more than zero, and has a fixed maximum " +#~| "(to prevent accidentally destroying your desktop by asking for 34 " +#~| "million workspaces)." +#~ msgid "" +#~ "Number of workspaces. Must be more than zero, and has a fixed maximum to " +#~ "prevent making the desktop unusable by accidentally asking for too many " +#~ "workspaces." +#~ msgstr "" +#~ "କାର୍ଯ୍ଯକ୍ଷେତ୍ରର ସଂଖ୍ଯା. ଏହା ଶୂନ୍ଯଠାରୁ ଅଧିକ ହେବା ବାଧ୍ଯ, ଓ ଏହାର ଗୋଟିଏ ସ୍ଥିର ସର୍ବାଧିକ ମୂଲ୍ଯ " +#~ "ଅଛି (ଭୁଲରେ ୩୪୦ ଲକ୍ଷ କାର୍ଯ୍ଯକ୍ଷେତ୍ର ନିର୍ଦ୍ଦଷ୍ଟ କରି ନିଜ ଡେସ୍କଟପକୁ ନଷ୍ଟ କରିବାରୁ ରୋକିବା ପାଇଁ)" + +#~ msgid "Run a defined command" +#~ msgstr "ଗୋଟିଏ ନିର୍ଦ୍ଦଷ୍ଟ ନିର୍ଦ୍ଦେଶ ଚଳାନ୍ତୁ" + +#~ msgid "System Bell is Audible" +#~ msgstr "ତନ୍ତ୍ର ଘଣ୍ଟିଟି ଶ୍ରାବ୍ଯ" + +#~ msgid "" +#~ "Tells Metacity how to implement the visual indication that the system " +#~ "bell or another application 'bell' indicator has been rung. Currently " +#~ "there are two valid values, \"fullscreen\", which causes a fullscreen " +#~ "white-black flash, and \"frame_flash\" which causes the titlebar of the " +#~ "application which sent the bell signal to flash. If the application which " +#~ "sent the bell is unknown (as is usually the case for the default \"system " +#~ "beep\"), the currently focused window's titlebar is flashed." +#~ msgstr "" +#~ "ମେଟାସିଟି ପାଇଁ ନିର୍ଦ୍ଦିଷ୍ଟ କରେ ତନ୍ତ୍ରର ଘଣ୍ଟି ବା ଅନ୍ଯ ପ୍ରୟୋଗର ଘଣ୍ଟି ବାଜିବା କିପରି ଚାକ୍ଷୁଷ ଭାବରେ " +#~ "ସୂଚିତ କରାଯିବ. ବର୍ତ୍ରମାନ ଦୁଇଟି ବୈଧ ମୂଲ୍ଯ ଅଛି, \"ପୂର୍ଣ୍ଣପରଦା\" ଯେଉଁଟାକି ପୂର୍ଣ୍ଣ ପରଦାଟିକୁ ଧଳାରୁ " +#~ "କଳା ଝଲସି ଦିଏ, ଓ \"ବନ୍ଧେଇ_ଝଲସା\" ଯେଉଁଟାକି ଘଣ୍ଟି ସଙ୍କେତ ପଠାଇ ଥିବା ପ୍ରୟୋଗର ଶୀର୍ଷକ ପଟିକୁ " +#~ "ଝଲସି ଦିଏ. ଘଣ୍ଟି ପଠାଇ ଥିବା ପ୍ରୟୋଗ ଅଜଣା ଥିଲେ (ଯେଉଁଟାକି ପୂର୍ବନିର୍ଦ୍ଧାରିତ \"ତନ୍ତ୍ର ବିପ୍\" ପାଇଁ " +#~ "ସାଧାରଣରେ ଘଟଣା), ସାମ୍ପ୍ରତିକ କେନ୍ଦ୍ରିତ ୱିଣ୍ଡୋର ଶୀର୍ଷକ ପଟିକୁ ଝଲସି ଦିଆଯାଏ." + +#~ msgid "" +#~ "The /apps/metacity/global_keybindings/run_command_N keys define " +#~ "keybindings that correspond to these commands. Pressing the keybinding " +#~ "for run_command_N will execute command_N." +#~ msgstr "" +#~ "/ପ୍ରୟୋଗ/ମେଟାସିଟି/ସାମଗ୍ରି_ଚାବିବନ୍ଧନୀ/ନିର୍ଦ୍ଦେଶ_N_ଚଳାନ୍ତୁ ଚାବିଗୁଡ଼ିକ ଏହି ନିର୍ଦ୍ଦେଶଗୁଡ଼ିକ ଚାବିବନ୍ଧନୀ " +#~ "ନିର୍ଦ୍ଦିଷ୍ଟ କରନ୍ତି. ନିର୍ଦ୍ଦେଶ_N_ଚଳାନ୍ତୁ ଚାବିବନ୍ଧନୀ ଦବାଇଲେ ନିର୍ଦ୍ଦେଶ_N ଚଳାଯିବ." + +#~ msgid "" +#~ "The /apps/metacity/global_keybindings/run_command_screenshot key defines " +#~ "a keybinding which causes the command specified by this setting to be " +#~ "invoked." +#~ msgstr "" +#~ "/ପ୍ରୟୋଗ/ମେଟାସିଟି/ସାମଗ୍ରି_ଚାବିବନ୍ଧନୀ/ପରଦାପ୍ରତିଛବି_ନିର୍ଦ୍ଦେଶ_ଚଳାନ୍ତୁ ଚାବି ଗୋଟିଏ ଚାବିବନ୍ଧନୀ " +#~ "ନିର୍ଦ୍ଦିଷ୍ଟ କରେ ଯେଉଁଟାକି ଏହି ବିନ୍ଯାସ ଦ୍ବାରା ଉଲ୍ଲେଖିତ ନିର୍ଦ୍ଦେଶକୁ ଆବାହନ କରେ," + +#~ msgid "" +#~ "The /apps/metacity/global_keybindings/run_command_window_screenshot key " +#~ "defines a keybinding which causes the command specified by this setting " +#~ "to be invoked." +#~ msgstr "" +#~ "/ପ୍ରୟୋଗ/ମେଟାସିଟି/ସାମଗ୍ରି_ଚାବିବନ୍ଧନୀ/ୱିଣ୍ଡୋ_ପରଦାପ୍ରତିଛବି_ନିର୍ଦ୍ଦେଶ_ଚଳାନ୍ତୁ ଚାବି ଗୋଟିଏ " +#~ "ଚାବିବନ୍ଧନୀ ନିର୍ଦ୍ଦିଷ୍ଟ କରେ ଯେଉଁଟାକି ଏହି ବିନ୍ଯାସ ଦ୍ବାରା ଉଲ୍ଲେଖିତ ନିର୍ଦ୍ଦେଶକୁ ଆବାହନ କରେ," + +#~ msgid "" +#~ "The keybinding that runs the correspondingly-numbered command in /apps/" +#~ "metacity/keybinding_commands The format looks like \"<Control>a\" " +#~ "or \"<Shift><Alt>F1\". The parser is fairly liberal and " +#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" +#~ "\" and \"<Ctrl>\". If you set the option to the special string " +#~ "\"disabled\", then there will be no keybinding for this action." +#~ msgstr "" +#~ "ଚାବିବନ୍ଧନୀ ଯେଉଁଟାକି /ପ୍ରୟୋଗ/ମେଟାସିଟି/ଚାବିବନ୍ଧନୀ_ନିର୍ଦ୍ଦେଶ ର ସଙ୍ଗତ ନିର୍ଦ୍ଦେଶକୁ ଚଳାଏ. ସଜ୍ଜିକରଣ " +#~ "ଶୈଳୀ ହେଲା \"<Control>a\" ବା \"<Shift><Alt>F1\". ବିଶ୍ଳେଷକଟି " +#~ "ବେଶ୍ ଉଦାରମନା, ଓ ଛୋଟ ବା ବଡ଼ ଅକ୍ଷର, ଏବଂ \"<Ctl>\", \"<Ctrl>\" ଭଳି " +#~ "ସଂକ୍ଷେପ ମଧ୍ଯ ଗ୍ରହଣ କରେ. ଆପଣ ଏହି ଚୟନକୁ ବିଶେଷ ବାକ୍ଯଖଣ୍ଡ \"disabled\" ରୂପେ ବିନ୍ଯାସ କଲେ, " +#~ "ଏହି କାର୍ଯ୍ଯ ପାଇଁ ଚାବିବନ୍ଧନୀ ରହିବ ନାହିଁ." + +#~ msgid "The name of a workspace." +#~ msgstr "ଗୋଟିଏ କାର୍ଯ୍ଯକ୍ଷେତ୍ରର ନାମ." + +#~ msgid "The screenshot command" +#~ msgstr "ପରଦା ପ୍ରତିଛବି ନିର୍ଦ୍ଦେଶ" + +#~ msgid "" +#~ "The theme determines the appearance of window borders, titlebar, and so " +#~ "forth." +#~ msgstr "ପ୍ରସଙ୍ଗଟି ୱିଣ୍ଡୋ ଧାର, ଶୀର୍ଷକପଟି, ଇତ୍ଯାଦିର ଚେହେରା ସ୍ଥିର କରେ." + +#~ msgid "" +#~ "The time delay before raising a window if auto_raise is set to true. The " +#~ "delay is given in thousandths of a second." +#~ msgstr "" +#~ "ଯଦି ସ୍ବଂୟ_ସାମନାକୁ_ଆଣିବା ସତ ହୋଇଥାଏ, ୱିଣ୍ଡୋକୁ ସାମନାକୁ ଆଣିବା ପୂର୍ବରୁ ମଧ୍ଯବର୍ତ୍ତୀ ସମୟ. ବିଳମ୍ବଟି " +#~ "ମିଲିସେକଣ୍ଡରେ ନିର୍ଦ୍ଧିଷ୍ଟ ହୋଇଥାଏ.." + +#~ msgid "" +#~ "The window focus mode indicates how windows are activated. It has three " +#~ "possible values; \"click\" means windows must be clicked in order to " +#~ "focus them, \"sloppy\" means windows are focused when the mouse enters " +#~ "the window, and \"mouse\" means windows are focused when the mouse enters " +#~ "the window and unfocused when the mouse leaves the window." +#~ msgstr "" +#~ "ୱିଣ୍ଡୋ କେନ୍ଦ୍ରୀଭୂତ ଧାରା ନିର୍ଦ୍ଧିଷ୍ଟ କରେ ୱିଣ୍ଡୋଗୁଡ଼ିକ କିପରି ସକ୍ରିୟ କରାଯିବ. ଏହାର ତିନୋଟି ମୂଲ୍ଯ ସମ୍ଭବ; " +#~ "\"ଚାପ\" ମାନେ ୱିଣ୍ଡୋଗୁଡ଼ିକ କେନ୍ଦ୍ରିତ କରିବା ପାଇଁ ତାଙ୍କ ଦେହରେ ମାଉସ୍ ଦବାଇବାକୁ ପଡ଼ିବ, \"ଅଯତ୍ନକୃତ" +#~ "\" ମାନେ ମାଉସ୍ ୱିଣ୍ଡୋରେ ପ୍ରବେଶ କଲେ ୱିଣ୍ଡୋଟି କେନ୍ଦ୍ରିତ ହେବ, ଓ \"ମାଉସ\" ମାନେ ମାଉସ୍ " +#~ "ୱିଣ୍ଡୋରେ ପ୍ରବେଶ କଲେ ୱିଣ୍ଡୋଟି କେନ୍ଦ୍ରିତ ହେବ ଏବଂ ୱିଣ୍ଡୋରୁ ବାହାରିଲେ ୱିଣ୍ଡୋଟି ଅକେନ୍ଦ୍ରିତ ହେବ." + +#~ msgid "The window screenshot command" +#~ msgstr "ୱିଣ୍ଡୋ ପରଦା ପ୍ରତିଛବି ନିର୍ଦ୍ଦେଶ" + +#~| msgid "" +#~| "This option determines the effects of double-clicking on the title bar. " +#~| "Current valid options are 'toggle_shade', which will shade/unshade the " +#~| "window, 'toggle_maximize' which will maximize/unmaximize the window, " +#~| "'minimize' which will minimize the window, and 'none' which will not do " +#~| "anything." +#~ msgid "" +#~ "This option determines the effects of double-clicking on the title bar. " +#~ "Current valid options are 'toggle_shade', which will shade/unshade the " +#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " +#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " +#~ "will maximize/unmaximize the window in that direction only, 'minimize' " +#~ "which will minimize the window, 'shade' which will roll the window up, " +#~ "'menu' which will display the window menu, 'lower' which will put the " +#~ "window behind all the others, and 'none' which will not do anything." +#~ msgstr "" +#~ "ଏହି ଚୟନ ଶୀର୍ଷକପଟି ଉପରେ ଦୁଇଥର ଦବାଇବାର ପ୍ରଭାବ ନିର୍ଦ୍ଧିଷ୍ଟ କରେ. ସାମ୍ପ୍ରତିକ ବୈଧ ମୂଲ୍ଯଗୁଡ଼ିକ " +#~ "ହେଲା 'toggle_shade' ଯେଉଁଟାକି ୱିଣ୍ଡୋକୁ ଘୋଢାଇବ ବା ପ୍ରକାଶିତ କରିବ, 'toggle_maximize' " +#~ "ଯେଉଁଟାକି ୱିଣ୍ଡୋକୁ ବୃହତ୍ତମନ କରିବ ବା ବୃହତ୍ତମରୁ ଛୋଟ କରିବ, ଓ 'none' ଯେଉଁଟାକି କିଛି କରିବ ନାହିଁ." + +#~| msgid "" +#~| "This option determines the effects of double-clicking on the title bar. " +#~| "Current valid options are 'toggle_shade', which will shade/unshade the " +#~| "window, 'toggle_maximize' which will maximize/unmaximize the window, " +#~| "'minimize' which will minimize the window, and 'none' which will not do " +#~| "anything." +#~ msgid "" +#~ "This option determines the effects of middle-clicking on the title bar. " +#~ "Current valid options are 'toggle_shade', which will shade/unshade the " +#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " +#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " +#~ "will maximize/unmaximize the window in that direction only, 'minimize' " +#~ "which will minimize the window, 'shade' which will roll the window up, " +#~ "'menu' which will display the window menu, 'lower' which will put the " +#~ "window behind all the others, and 'none' which will not do anything." +#~ msgstr "" +#~ "ଏହି ଚୟନ ଶୀର୍ଷକପଟି ଉପରେ ଦୁଇଥର ଦବାଇବାର ପ୍ରଭାବ ନିର୍ଦ୍ଧିଷ୍ଟ କରେ. ସାମ୍ପ୍ରତିକ ବୈଧ ମୂଲ୍ଯଗୁଡ଼ିକ " +#~ "ହେଲା 'toggle_shade' ଯେଉଁଟାକି ୱିଣ୍ଡୋକୁ ଘୋଢାଇବ ବା ପ୍ରକାଶିତ କରିବ, 'toggle_maximize' " +#~ "ଯେଉଁଟାକି ୱିଣ୍ଡୋକୁ ବୃହତ୍ତମନ କରିବ ବା ବୃହତ୍ତମରୁ ଛୋଟ କରିବ, ଓ 'none' ଯେଉଁଟାକି କିଛି କରିବ ନାହିଁ." + +#, fuzzy +#~| msgid "" +#~| "This option determines the effects of double-clicking on the title bar. " +#~| "Current valid options are 'toggle_shade', which will shade/unshade the " +#~| "window, 'toggle_maximize' which will maximize/unmaximize the window, " +#~| "'minimize' which will minimize the window, and 'none' which will not do " +#~| "anything." +#~ msgid "" +#~ "This option determines the effects of right-clicking on the title bar. " +#~ "Current valid options are 'toggle_shade', which will shade/unshade the " +#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " +#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " +#~ "will maximize/unmaximize the window in that direction only, 'minimize' " +#~ "which will minimize the window, 'shade' which will roll the window up, " +#~ "'menu' which will display the window menu, 'lower' which will put the " +#~ "window behind all the others, and 'none' which will not do anything." +#~ msgstr "" +#~ "ଏହି ଚୟନ ଶୀର୍ଷକପଟି ଉପରେ ଦୁଇଥର ଦବାଇବାର ପ୍ରଭାବ ନିର୍ଦ୍ଧିଷ୍ଟ କରେ. ସାମ୍ପ୍ରତିକ ବୈଧ ମୂଲ୍ଯଗୁଡ଼ିକ " +#~ "ହେଲା 'toggle_shade' ଯେଉଁଟାକି ୱିଣ୍ଡୋକୁ ଘୋଢାଇବ ବା ପ୍ରକାଶିତ କରିବ, 'toggle_maximize' " +#~ "ଯେଉଁଟାକି ୱିଣ୍ଡୋକୁ ବୃହତ୍ତମନ କରିବ ବା ବୃହତ୍ତମରୁ ଛୋଟ କରିବ, ଓ 'none' ଯେଉଁଟାକି କିଛି କରିବ ନାହିଁ." + +#, fuzzy +#~| msgid "" +#~| "Turns on a visual indication when an application or the system issues a " +#~| "'bell' or 'beep'; useful for the hard-of-hearing and for use in noisy " +#~| "environments, or when 'audible bell' is off." +#~ msgid "" +#~ "Turns on a visual indication when an application or the system issues a " +#~ "'bell' or 'beep'; useful for the hard-of-hearing and for use in noisy " +#~ "environments." +#~ msgstr "" +#~ "ଗୋଟିଏ ପ୍ରୟୋଗ ବା ତନ୍ତ୍ର 'ଘଣ୍ଟି' ବା 'ବିପ' କଲେ, ଏକ ଚାକ୍ଷୁଷ ସୂଚକ ବ୍ଯବହାର କରେ; ଏହା କାଲ " +#~ "ଲୋକଙ୍କ ପାଇଁ ବା କୋଲାହଳପୂର୍ଣ୍ଣ ପରିବେଶରେ ବା 'ଶ୍ରାବ୍ଯ ଘଣ୍ଟି' ଚାଲୁ ନ ଥିଲେ ଉପକାରୀ" + +#~ msgid "Use standard system font in window titles" +#~ msgstr "ୱିଣ୍ଡୋ ଶୀର୍ଷକରେ ତନ୍ତ୍ରର ସାଧାରଣ ଅକ୍ଷରରୂପ ବ୍ଯବହାର କରନ୍ତୁ" + +#~ msgid "Visual Bell Type" +#~ msgstr "ଚାକ୍ଷୁଷ ଘଣ୍ଟି ପ୍ରକାର" + +#~ msgid "Whether raising should be a side-effect of other user interactions" +#~ msgstr "ସାମନାକୁ ଆଣିବା ଅନ୍ଯ ବ୍ଯବହାରକାରୀ ପାରସ୍ପରିକ କ୍ରିୟାର ଅବାଂଛିତ ପ୍ରତିକ୍ରିୟା ହେବା ଉଚିତ କି" + +#~ msgid "Whether to resize with the right button" +#~ msgstr "ଡ଼ାହାଣ ବଟନ ଦ୍ୱାରା ଆକାର ପରିବର୍ତ୍ତନ କରାଯିବ କି" + +#~ msgid "Window focus mode" +#~ msgstr "ୱିଣ୍ଡୋ କେନ୍ଦ୍ରୀଭୂତ ଧାରା" + +#~ msgid "Window title font" +#~ msgstr "ୱିଣ୍ଡୋ ଶୀର୍ଷକ ଅକ୍ଷରରୂପ" + +#~ msgid "Close Window" +#~ msgstr "ୱିଣ୍ଡୋ ବନ୍ଦ କରନ୍ତୁ" + +#~ msgid "Window Menu" +#~ msgstr "ୱିଣ୍ଡୋ ମେନୁ" + +#~ msgid "Minimize Window" +#~ msgstr "ୱିଣ୍ଡୋକୁ କ୍ଷୁଦ୍ରତମ କରନ୍ତୁ" + +#~ msgid "Maximize Window" +#~ msgstr "ୱିଣ୍ଡୋକୁ ବୃହତ୍ତମ କରନ୍ତୁ" + +#~| msgid "Resize window" +#~ msgid "Restore Window" +#~ msgstr "ୱିଣ୍ଡୋକୁ ପୁନଃସ୍ଥାପନ କରନ୍ତୁ" + +#~| msgid "Roll _Up" +#~ msgid "Roll Up Window" +#~ msgstr "ୱିଣ୍ଡୋକୁ ଗଡ଼ାନ୍ତୁ" + +#~| msgid "Close Window" +#~ msgid "Unroll Window" +#~ msgstr "ୱିଣ୍ଡୋକୁ ଗଡ଼ାଇବା ବନ୍ଦ କରନ୍ତୁ" + +#~ msgid "Keep Window On Top" +#~ msgstr "ୱିଣ୍ଡୋକୁ ଉପରେ ରଖନ୍ତୁ" + +#~| msgid "_Always on Visible Workspace" +#~ msgid "Always On Visible Workspace" +#~ msgstr "ସଦାବେଳେ ଦୃଶ୍ଯମାନ କାର୍ଯ୍ଯକ୍ଷେତ୍ରରେ ଥାଏ" + +#~| msgid "Toggle window on all workspaces" +#~ msgid "Put Window On Only One Workspace" +#~ msgstr "ୱିଣ୍ଡୋକୁ କେବଳ ଗୋଟିଏ କାର୍ଯ୍ଯକ୍ଷେତ୍ରରେ ରଖନ୍ତୁ" + +#~ msgid "Title" +#~ msgstr "ଶୀର୍ଷକ" + +#~ msgid "Class" +#~ msgstr "ଶ୍ରେଣୀ" + +#~ msgid "" +#~ "There was an error running \"%s\":\n" +#~ "%s." +#~ msgstr "" +#~ "\"%s\" ଚଳେବାରେ ତ୍ରୁଟି:\n" +#~ "%s." + +#~ msgid "<author> specified twice for this theme" +#~ msgstr "ଏହି ପ୍ରସଙ୍ଗ ପାଇଁ <author> ଦୁଇଥର ବିନ୍ଯାସ କରାଯାଇଛି" + +#~ msgid "<copyright> specified twice for this theme" +#~ msgstr "ଏହି ପ୍ରସଙ୍ଗ ପାଇଁ <copyright> ଦୁଇଥର ବିନ୍ଯାସ କରାଯାଇଛି" + +#~ msgid "<date> specified twice for this theme" +#~ msgstr "ଏହି ପ୍ରସଙ୍ଗ ପାଇଁ <date> ଦୁଇଥର ବିନ୍ଯାସ କରାଯାଇଛି" + +#~ msgid "<description> specified twice for this theme" +#~ msgstr "ଏହି ପ୍ରସଙ୍ଗ ପାଇଁ <description> ଦୁଇଥର ବିନ୍ଯାସ କରାଯାଇଛି" + +#~ msgid "Theme file %s did not contain a root <metacity_theme> element" +#~ msgstr "ପ୍ରସଙ୍ଗ ଫାଇଲ %sରେ ମୂଳ <metacity_theme> ଉପାଦାନ ନ ଥିଲା" + +#~ msgid "/Windows/tearoff" +#~ msgstr "/ୱିଣ୍ଡୋ/ଛିଣ୍ଡାନ୍ତୁ" + +#~ msgid "/Windows/_Dialog" +#~ msgstr "/ୱିଣ୍ଡୋ/ସଂଳାପ (_D)" + +#~ msgid "/Windows/_Modal dialog" +#~ msgstr "/ୱିଣ୍ଡୋ/ଅବସ୍ଥା ସଂଳାପ (_M)" +#~ msgid "/Windows/Des_ktop" +#~ msgstr "/ୱିଣ୍ଡୋ/ଡେସ୍କଟପ୍ (_k)" diff --git a/po/pa.po b/po/pa.po index 77f53fd8c..47da5141a 100644 --- a/po/pa.po +++ b/po/pa.po @@ -5,1657 +5,1624 @@ # # Amanpreet_Singh <amanlinux@netscape.net>, 2004. # Amanpreet Singh Alam <amanlinux@netscape.net>, 2004. -# Amanpreet Singh Alam <aalam@redhat.com>, 2004. -# Amanpreet Singh Alam <amanpreetalam@yahoo.com>, 2005. -# A S Alam <apbrar@gmail.com>, 2006. +# A S Alam <aalam@users.sf.net>, 2006. # A S Alam <aalam@users.sf.net>, 2007, 2009, 2010, 2011. # ASB <aalam@users.sf.net>, 2007. -# Amanpreet Singh Alam <aalam@users.sf.net>, 2009, 2012. +# Amanpreet Singh Alam <aalam@users.sf.net>, 2009, 2012, 2013, 2014, 2015, 2017, 2020. msgid "" msgstr "" "Project-Id-Version: metacity.gnome-2-26\n" -"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" -"product=muffin&keywords=I18N+L10N&component=general\n" -"POT-Creation-Date: 2012-03-11 21:56+0000\n" -"PO-Revision-Date: 2012-03-15 07:19+0530\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2020-02-23 17:41+0000\n" +"PO-Revision-Date: 2020-03-04 19:52-0800\n" "Last-Translator: A S Alam <aalam@users.sf.net>\n" -"Language-Team: Punjabi/Panjabi <punjabi-users@lists.sf.net>\n" +"Language-Team: Punjabi <punjabi-users@lists.sf.net>\n" +"Language: pa\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Lokalize 1.2\n" +"X-Generator: Lokalize 19.04.3\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "\n" -"Language: pa\n" -#: ../src/50-muffin-windows.xml.in.h:1 +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "ਨੇਵੀਗੇਸ਼ਨ" + +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "ਵਿੰਡੋ ਨੂੰ ਵਰਕਸਪੇਸ ੧ ਵਿੱਚ ਲਿਜਾਓ" + +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "ਵਿੰਡੋ ਨੂੰ ਵਰਕਸਪੇਸ ੨ ਵਿੱਚ ਲਿਜਾਓ" + +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "ਵਿੰਡੋ ਨੂੰ ਵਰਕਸਪੇਸ ੩ ਵਿੱਚ ਲਿਜਾਓ" + +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "ਵਿੰਡੋ ਨੂੰ ਵਰਕਸਪੇਸ ੪ ਵਿੱਚ ਲਿਜਾਓ" + +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "ਵਿੰਡੋ ਨੂੰ ਪਿਛਲੇ ਵਰਕਸਪੇਸ ਵਿੱਚ ਲਿਜਾਓ" + +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "ਵਿੰਡੋ ਨੂੰ ਇੱਕ ਵਰਕਸਪੇਸ ਉੱਤੇ ਲਿਜਾਓ" + +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "ਵਿੰਡੋ ਨੂੰ ਇੱਕ ਵਰਕਸਪੇਸ ਹੇਠਾਂ ਲਿਜਾਓ" + +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "ਵਿੰਡੋ ਨੂੰ ਇੱਕ ਮਾਨੀਟਰ ਖੱਬੇ ਵੱਲ ਲਿਜਾਓ" + +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "ਵਿੰਡੋ ਨੂੰ ਇੱਕ ਮਾਨੀਟਰ ਸੱਜੇ ਵੱਲ ਲਿਜਾਓ" + +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "ਵਿੰਡੋ ਨੂੰ ਇੱਕ ਮਾਨੀਟਰ ਉੱਤੇ ਲਿਜਾਓ" + +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "ਵਿੰਡੋ ਨੂੰ ਇੱਕ ਮਾਨੀਟਰ ਹੇਠਾਂ ਲਿਜਾਓ" + +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "ਐਪਲੀਕੇਸ਼ਨ ਬਦਲੋ" + +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "ਪਿਛਲੀ ਐਪਲੀਕੇਸ਼ਨ ਲਈ ਬਦਲੋ" + +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "ਵਿੰਡੋਜ਼ ਬਦਲੋ" + +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "ਪਿਛਲੀ ਵਿੰਡੋ ਲਈ ਬਦਲੋ" + +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "ਐਪਲੀਕੇਸ਼ਨ ਦੀਆਂ ਵਿੰਡੋਜ਼ ਬਦਲੋ" + +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "ਐਪਲੀਕੇਸ਼ਨ ਦੀ ਪਿਛਲੀ ਵਿੰਡੋ ਵਿੱਚ ਜਾਓ" + +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "ਸਿਸਟਮ ਕੰਟਰੋਲ ਬਦਲੋ" + +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "ਪਿਛਲੇ ਸਿਸਟਮ ਕੰਟਰੋਲ ਬਦਲੋ" + +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "ਵਿੰਡੋਜ਼ ਸਿੱਧੀਆਂ ਬਦਲੋ" + +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "ਸਿੱਧਾ ਪਿਛਲੀ ਵਿੰਡੋ ਲਈ ਬਦਲੋ" + +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "ਐਪਲੀਕੇਸ਼ਨ ਦੀ ਵਿੰਡੋਜ਼ ਸਿੱਧੀ ਬਦਲੋ" + +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "ਸਿੱਧਾ ਐਪ ਦੀ ਪਿਛਲੀ ਵਿੰਡੋ ਲਈ ਬਦਲੋ" + +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "ਸਿਸਟਮ ਕੰਟਰੋਲ ਸਿੱਧੇ ਬਦਲੋ" + +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "ਸਿੱਧਾ ਪਿਛਲੇ ਸਿਸਟਮ ਕੰਟਰੋਲ ਲਈ ਬਦਲੋ" + +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "ਸਭ ਸਧਾਰਨ ਵਿੰਡੋਜ਼ ਓਹਲੇ ਕਰੋ" + +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "ਵਰਕਸਪੇਸ ੧ ਵਿੱਚ ਜਾਓ" + +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "ਵਰਕਸਪੇਸ ੨ ਵਿੱਚ ਜਾਓ" + +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "ਵਰਕਸਪੇਸ ੩ ਵਿੱਚ ਜਾਓ" + +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "ਵਰਕਸਪੇਸ ੪ ਵਿੱਚ ਜਾਓ" + +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "ਪਿਛਲੇ ਵਰਕਸਪੇਸ ਵਿੱਚ ਜਾਓ" + +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "ਉੱਤੇ ਵਰਕਸਪੇਸ 'ਚ ਭੇਜੋ" + +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "ਹੇਠਾਂ ਵਰਕਸਪੇਸ 'ਚ ਭੇਜੋ" + +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "ਸਿਸਟਮ" + +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "ਕਮਾਂਡ ਚਲਾਉ ਪਰੋਉਟ ਵੇਖੋ" + +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "ਸਰਗਰਮੀ ਸੰਖੇਪ ਜਾਣਕਾਰੀ ਵੇਖੋ" + +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "ਕੀ-ਬੋਰਡ ਸ਼ਾਰਟਕੱਟ ਬਹਾਲ ਕਰੋ" + +#: data/50-mutter-windows.xml:6 msgid "Windows" -msgstr "ਵਿੰਡੋ" +msgstr "ਵਿੰਡੋਜ਼" + +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "ਐਕਟਿਵੇਟ ਵਿੰਡੋ ਮੇਨੂ" + +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "ਪੂਰੀ ਸਕਰੀਨ ਮੋਡ ਬਦਲੋ" + +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "ਅਧਿਕਤਮ ਸਥਿਤੀ ਬਦਲੋ" + +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "ਵਿੰਡੋ ਵੱਧੋ-ਵੱਧ" + +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "ਵਿੰਡੋ ਮੁੜ-ਸਟੋਰ" + +#: data/50-mutter-windows.xml:18 +msgid "Close window" +msgstr "ਵਿੰਡੋ ਬੰਦ ਕਰੋ" + +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "ਵਿੰਡੋ ਓਹਲੇ" + +#: data/50-mutter-windows.xml:22 +msgid "Move window" +msgstr "ਵਿੰਡੋ ਹਿਲਾਓ" + +#: data/50-mutter-windows.xml:24 +msgid "Resize window" +msgstr "ਵਿੰਡੋ ਮੁੜ-ਅਕਾਰ" + +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "ਵਿੰਡੋ ਸਭ ਵਰਕਸਪੇਸ ਜਾਂ ਇੱਕ ਵਿੱਚ ਬਦਲੋ" + +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "ਵਿੰਡੋ ਉਭਾਰੋ, ਜੇ ਢੱਕੀ ਹੈ, ਨਹੀਂ ਤਾਂ ਹੇਠਾਂ ਭੇਜੋ" -#: ../src/50-muffin-windows.xml.in.h:2 +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "ਵਿੰਡੋ ਨੂੰ ਹੋਰ ਵਿੰਡੋਜ਼ ਤੋਂ ਉੱਤੇ ਲਿਆਓ" + +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "ਵਿੰਡੋ ਨੂੰ ਹੋਰ ਵਿੰਡੋ ਤੋਂ ਹੇਠਾਂ ਲੈ ਜਾਉ" + +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "ਵਿੰਡੋ ਖੜਵੇਂ ਰੂਪ ਵਿੱਚ ਵੱਧੋ-ਵੱਧ" + +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "ਵਿੰਡੋ ਲੇਟਵੇਂ ਰੂਪ ਵਿੱਚ ਵੱਧੋ-ਵੱਧ" + +#: data/50-mutter-windows.xml:41 msgid "View split on left" msgstr "ਖੱਬੇ ਪਾਸੇ ਵੰਡ ਵੇਖੋ" -#: ../src/50-muffin-windows.xml.in.h:3 +#: data/50-mutter-windows.xml:45 msgid "View split on right" msgstr "ਸੱਜੇ ਪਾਸੇ ਵੰਡ ਵੇਖੋ" -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "ਮੱਟਰ" + +#: data/org.gnome.mutter.gschema.xml.in:7 +msgid "Modifier to use for extended window management operations" +msgstr "ਵਾਧੂ ਵਿੰਡੋ ਪਰਬੰਧ ਓਪਰੇਸ਼ਨਾਂ ਲਈ ਵਰਤਣ ਵਾਸਤੇ ਮੋਡੀਫਾਇਰ" + +#: data/org.gnome.mutter.gschema.xml.in:8 msgid "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." msgstr "" -"ਇੱਕ ਹੋਰ ਕੰਪੋਜ਼ਟਿੰਗ ਮੈਨੇਜਰ %i ਸਕਰੀਨ ਉੱਤੇ ਡਿਸਪਲੇਅ \"%s\" ਉੱਤੇ ਪਹਿਲਾਂ ਹੀ ਚੱਲ " -"ਰਿਹਾ ਹੈ।" +"ਇਹ ਸਵਿੱਚ ”ਓਵਰਲੇ” ਸ਼ੁਰੂ ਕਰਦੀ ਹੈ, ਜੋ ਕਿ ਵਿੰਡੋ ਸੰਖੇਪ ਤੇ ਐਪਲੀਕੇਸ਼ਨ ਚਲਾਉਣ ਸਿਸਟਮ ਦੀ" +" ਜੋੜ ਹੈ। ਡਿਫਾਲਟ " +"ਇਹ PC ਹਾਰਡਵੇਅਰ ਉੱਤੇ ”ਵਿੰਡੋਜ਼ ਸਵਿੱਚ” ਨਾਲ ਵਰਤਣ ਲਈ ਹੈ। ਇਹ ਉਮੀਦ ਕੀਤੀ ਜਾਂਦੀ ਹੈ ਕਿ" +" ਜਾਂ ਤਾਂ " +"ਡਿਫਾਲਟ ਬਾਈਡਿੰਗ ਰੱਖੀ ਜਾਵੇ ਜਾਂ ਖਾਲੀ ਲਾਈਨ ਵਰਤੀ ਜਾਵੇ।" -#: ../src/core/bell.c:307 -msgid "Bell event" -msgstr "ਘੰਟੀ ਈਵੈਂਟ" +#: data/org.gnome.mutter.gschema.xml.in:20 +msgid "Attach modal dialogs" +msgstr "ਮਾਡਲ ਡਾਈਲਾਗ ਅਟੈਚਮੈਂਟ" -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "ਅਣਜਾਣ ਵਿੰਡੋ ਜਾਣਕਾਰੀ ਮੰਗ: %d" +#: data/org.gnome.mutter.gschema.xml.in:21 +msgid "" +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." +msgstr "" +"ਜਦੋਂ ਸਹੀਂ ਹੋਵੇ ਤਾਂ ਵੱਖ ਵੱਖ ਟਾਈਟਲਬਾਰ ਦੀ ਬਜਾਏ, ਮਾਡਲ ਡਾਈਲਾਗ ਮੁੱਢਲੀ ਵਿੰਡੋ ਦੇ" +" ਟਾਈਟਲ ਬਾਰ ਨਾਲ " +"ਜੁੜਿਆ ਉਭਰੇਗਾ ਤੇ ਮੁੱਢਲੀ ਵਿੰਡੋ ਨਾਲ ਹੀ ਹਿੱਲੇਗਾ।" -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> ਜਵਾਬ ਨਹੀ ਦਿੰਦਾ।" +#: data/org.gnome.mutter.gschema.xml.in:30 +msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "ਕੋਨਾ ਟਿਲਿੰਗ ਚਾਲੂ, ਜਦੋਂ ਵਿੰਡੋਜ਼ ਨੂੰ ਸਕਰੀਨ ਕੋਨਿਆਂ ਤੋਂ ਡਰਾਪ ਕਰਨਾ ਹੋਵੇ" -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "ਐਪਲੀਕੇਸ਼ਨ ਜਵਾਬ ਨਹੀਂ ਦੇ ਰਹੀ ਹੈ।" +#: data/org.gnome.mutter.gschema.xml.in:31 +msgid "" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." +msgstr "" +"ਜੇ ਚਾਲੂ ਕੀਤਾ ਤਾਂ ਵਿੰਡੋਜ਼ ਨੂੰ ਖੜ੍ਹਵੀਂ ਸਕਰੀਨ ਬਾਹੀ ਉੱਤੇ ਲੈ ਜਾਣ ਨਾਲ ਉਹ ਖੜ੍ਹਵੇਂ" +" ਰੂਪ ਵਿੱਚ ਵੱਧ ਤੋਂ ਵੱਧ " +"ਕਰਦਾ ਹੈ ਅਤੇ ਖਿਤਿਜੀ (ਹਰੀਜੱਟਲ) ਰੂਪ ਵਿੱਚ ਉਪਲੱਬਧ ਖੇਤਰ ਵਿੱਚ ਅੱਧੇ ਥਾਂ ਲਈ ਮੁੜ-ਆਕਾਰ" +" ਕਰਦਾ ਹੈ। ਵਿੰਡੋਜ਼ " +"ਨੂੰ ਉੱਤੇ ਸਕਰੀਨ ਬਾਹੀ ਵਿੱਚ ਲੈ ਕੇ ਜਾਣ ਨਾਲ ਉਹ ਪੂਰੀ ਤਰ੍ਹਾਂ ਵੱਧ ਤੋਂ ਵੱਧ ਹੁੰਦਾ ਹੈ।" + +#: data/org.gnome.mutter.gschema.xml.in:40 +msgid "Workspaces are managed dynamically" +msgstr "ਵਰਕਸਪੇਸ ਦਾ ਪਰਬੰਧ ਚਲਵੇਂ ਰੂਪ ਵਿੱਚ ਕੀਤਾ ਜਾਂਦਾ ਹੈ" -#: ../src/core/delete.c:119 +#: data/org.gnome.mutter.gschema.xml.in:41 msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." +"Determines whether workspaces are managed dynamically or whether there’s a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." +msgstr "" +"ਦੱਸੋ ਕਿ ਕੀ ਵਰਕਸਪੇਸ ਨੂੰ ਚਲਵੇਂ ਰੂਪ ਵਿੱਚ ਰੱਖਣਾ ਹੈ ਜਾਂ ਵਰਕਸਪੇਸ ਦੀ ਗਿਣਤੀ ਸਥਿਰ ਹੋਵੇ" +" (ਜੋ ਕਿ org." +"gnome.desktop.wm.preferences ਵਿੱਚ num-workspaces ਕੁੰਜੀ ਰਾਹੀਂ ਦੱਸੀ ਜਾਂਦੀ ਹੈ)।" + +#: data/org.gnome.mutter.gschema.xml.in:50 +msgid "Workspaces only on primary" +msgstr "ਵਰਕਸਪੇਸ ਕੇਵਲ ਪ੍ਰਾਇਮਰੀ ਉੱਤੇ ਹੀ" + +#: data/org.gnome.mutter.gschema.xml.in:51 +msgid "" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." msgstr "" -"ਤੁਸੀਂ ਇਸ ਲਈ ਕੁਝ ਸਮੇਂ ਵਾਸਤੇ ਉਡੀਕ ਕਰ ਸਕਦੇ ਹੋ ਜਾਂ ਕਾਰਜ ਨੂੰ ਧੱਕੇ ਨਾਲ ਬੰਦ ਕਰ ਸਕਦੇ " -"ਹੋ।" +"ਕੀ ਵਰਕਸਪੇਸ ਬਦਲਣਾ ਸਭ ਮਾਨੀਟਰ ਦੀਆਂ ਵਿੰਡੋ ਲਈ ਹੋਵੇ ਜਾਂ ਕੇਵਲ ਪ੍ਰਾਇਮਰੀ ਮਾਨੀਟਰ ਦੀਆਂ" +" ਵਿੰਡੋ ਲਈ ਹੀ " -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "ਉਡੀਕੋ(_W)" +#: data/org.gnome.mutter.gschema.xml.in:59 +msgid "No tab popup" +msgstr "ਕੋਈ ਟੈਬ ਪੋਪਅੱਪ ਨਹੀਂ" -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "ਧੱਕੇ ਨਾਲ ਬੰਦ(_F)" +#: data/org.gnome.mutter.gschema.xml.in:60 +msgid "" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." +msgstr "" +"ਜਾਣੋ ਕਿ ਕੀ ਪੋਪਅੱਪ ਅਤੇ ਹਾਈਲਾਈਟ ਫਰੇਮ ਦੀ ਵਰਤੋਂ ਨੂੰ ਵਿੰਡੋਜ਼ ਦੇ ਚੱਕਰ ਦੌਰਾਨ ਬੰਦ" +" ਕਰਨਾ ਹੈ।" + +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "ਪੁਆਇੰਟਰ ਦੇ ਰੁਕਣ ਤੱਕ ਫੋਕਸ ਬਦਲਣ ਨੂੰ ਰੋਕੋ" + +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" +"ਜੇ ਇਹ ਸਹੀਂ ਹੋਵੇ ਤਾਂ ਫੋਕਸ ਢੰਗ ਜਾਂ ਤਾਂ ”ਸਲੋਪੀ” ਜਾਂ ”ਮਾਊਂਸ” ਹੁੰਦਾ ਹੈ ਤਾਂ ਫੋਕਸ" +" ਹੋਇਆ ਵਿੰਡੋ " +"auto_raise_delay ਕੁੰਜੀ ਵਲੋਂ ਦਿੱਤੇ ਇੱਕ ਅੰਤਰਾਲ ਬਾਅਦ ਆਟੋਮੈਟਿਕ ਹੀ ਉਭਾਰਿਆ ਜਾਵੇਗਾ।" + +#: data/org.gnome.mutter.gschema.xml.in:79 +msgid "Draggable border width" +msgstr "ਡਰੈਗ ਹੋਣ ਯੋਗ ਬਾਰਡਰ ਚੌੜਾਈ" + +#: data/org.gnome.mutter.gschema.xml.in:80 +msgid "" +"The amount of total draggable borders. If the theme’s visible borders are " +"not enough, invisible borders will be added to meet this value." +msgstr "" +"ਕੁੱਲ ਡਰੈਗ ਹੋਣ ਯੋਗ ਬਾਰਡਰ ਦੀ ਮਾਤਰਾ। ਜੇ ਥੀਮ ਦੇ ਦਿੱਖ ਬਾਰਡਰ ਲੋੜ ਮੁਤਾਬਕ ਨਾ ਹੋਣ ਤਾਂ" +" ਅਦਿੱਖ ਬਾਰਡਰ " +"ਨੂੰ ਇਹ ਮੁੱਲ ਦੇ ਬਰਾਬਰ ਕਰਨ ਲਈ ਵਧਾਇਆ ਜਾਵੇਗਾ।" + +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "ਲਗਭਗ ਮਾਨੀਟਰ ਆਕਾਰ ਦੀਆਂ ਵਿੰਡੋਜ਼ ਆਪਣੇ-ਆਪ ਵੱਧੋ-ਵੱਧੋ" + +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" +"ਜੇ ਚਾਲੂ ਕੀਤਾ ਤਾਂ ਨਵੀਆਂ ਵਿੰਡੋਜ਼, ਜੋ ਕਿ ਸ਼ੁਰੂ ਵਿੱਚ ਮਾਨੀਟਰ ਦੇ ਆਕਾਰ ਦੀਆਂ ਹੁੰਦੀਆਂ" +" ਹਨ, ਆਪਣੇ-ਆਪ ਵੱਧ ਤੋਂ " +"ਵੱਧ ਹੋ ਜਾਣਗੀਆਂ।" + +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "ਨਵੀਆਂ ਵਿੰਡੋ ਕੇਂਦਰ ਵਿੱਚ ਰੱਖੋ" + +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" +"ਜੇ ਸਹੀਂ ਹੈ ਤਾਂ ਨਵੀਂ ਵਿੰਡੋਜ਼ ਨੂੰ ਹਮੇਸ਼ਾ ਮਾਨੀਟਰ ਦੀ ਸਰਗਰਮ ਸਕਰੀਮ ਦੇ ਕੇਂਦਰ ਵਿੱਚ" +" ਰੱਖਿਆ ਜਾਵੇਗਾ।" + +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "ਤਜਰਬੇ ਅਧੀਨ ਫ਼ੀਚਰਾਂ ਨੂੰ ਸਮਰੱਥ ਕਰੋ" + +#: data/org.gnome.mutter.gschema.xml.in:108 +msgid "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes " +"mutter request a low priority real-time scheduling. The executable or user " +"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — " +"initializes Xwayland lazily if there are X11 clients. Requires restart." +msgstr "" + +#: data/org.gnome.mutter.gschema.xml.in:134 +msgid "Modifier to use to locate the pointer" +msgstr "ਪੁਆਇੰਟਰ ਲੱਭਣ ਲਈ ਵਰਤਣ ਵਾਸਤੇ ਸੋਧਣ" + +#: data/org.gnome.mutter.gschema.xml.in:135 +msgid "This key will initiate the “locate pointer” action." +msgstr "ਇਹ ਕੁੰਜੀ “ਪੁਆਇੰਟਰ ਲੱਭੋ“ ਕਾਰਵਾਈ ਸ਼ੁਰੂ ਕਰਦੀ ਹੈ।" + +#: data/org.gnome.mutter.gschema.xml.in:142 +msgid "Timeout for check-alive ping" +msgstr "ਚੈਕ-ਸਰਗਰਮ ਪਿੰਗ ਲਈ ਸਮਾਂ-ਅੰਤਰਾਲ" + +#: data/org.gnome.mutter.gschema.xml.in:143 +msgid "" +"Number of milliseconds a client has to respond to a ping request in order to " +"not be detected as frozen. Using 0 will disable the alive check completely." +msgstr "" +"ਮਿਲੀਸਕਿੰਟਾਂ ਦੀ ਗਿਣਤੀ, ਜਿਸ ਵਿੱਚ ਕਲਾਂਇਟ ਨੇ ਪਿੰਗ ਦੀ ਬੇਨਤੀ ਦਾ ਜਵਾਬ ਦੇਣਾ ਹੁੰਦਾ ਹੈ" +" ਤਾਂ ਕਿ ਜਕੜਿਆ " +"ਨਾ ਖੋਜਿਆ ਜਾਵੇ। 0 ਵਰਤਣ ਨਾਲ ਸਰਗਰਮੀ ਦੀ ਜਾਂਚ ਨੂੰ ਪੂਰੀ ਤਰ੍ਹਾਂ ਅਸਮਰੱਥ ਕੀਤਾ ਜਾਵੇਗਾ।" -#: ../src/core/display.c:361 +#: data/org.gnome.mutter.gschema.xml.in:165 +msgid "Select window from tab popup" +msgstr "ਟੈਬ ਪੋਪਅੱਪ ਤੋਂ ਵਿੰਡੋ ਚੁਣੋ" + +#: data/org.gnome.mutter.gschema.xml.in:170 +msgid "Cancel tab popup" +msgstr "ਟੈਬ ਪੋਪਅੱਪ ਰੱਦ ਕਰੋ" + +#: data/org.gnome.mutter.gschema.xml.in:175 +msgid "Switch monitor configurations" +msgstr "ਮਾਨੀਟਰ ਸੰਰਚਨਾ ਨੂੰ ਬਦਲੋ" + +#: data/org.gnome.mutter.gschema.xml.in:180 +msgid "Rotates the built-in monitor configuration" +msgstr "ਬਿਲਟ-ਇਨ ਮਾਨੀਟਰ ਸੰਰਚਨਾ ਨੂੰ ਘੁੰਮਾਓ" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "VT 1 ਲਈ ਬਦਲੋ" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "VT 2 ਲਈ ਬਦਲੋ" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "VT 3 ਲਈ ਬਦਲੋ" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "VT 4 ਲਈ ਬਦਲੋ" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "VT 5 ਲਈ ਬਦਲੋ" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "VT 6 ਲਈ ਬਦਲੋ" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "VT 7 ਲਈ ਬਦਲੋ" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "VT 8 ਲਈ ਬਦਲੋ" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "VT 9 ਲਈ ਬਦਲੋ" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "VT 10 ਲਈ ਬਦਲੋ" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "VT 11 ਲਈ ਬਦਲੋ" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "VT 12 ਲਈ ਬਦਲੋ" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "ਸ਼ਾਰਟਕੱਟ ਮੁੜ-ਸਮਰੱਥ ਕਰੋ" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow X11 grabs to lock keyboard focus with Xwayland" +msgstr "X11 ਨੂੰ Xwayland ਨਾਲ ਲਾਕ ਕੀਤੇ ਕੀਬੋਰਡ ਫੋਕਸ ਨਾਲ ਫੜਨ ਦੀ ਇਜਾਜ਼ਤ ਦਿੰਦਾ ਹੈ" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 +msgid "" +"Allow all keyboard events to be routed to X11 “override redirect” windows " +"with a grab when running in Xwayland. This option is to support X11 clients " +"which map an “override redirect” window (which do not receive keyboard " +"focus) and issue a keyboard grab to force all keyboard events to that " +"window. This option is seldom used and has no effect on regular X11 windows " +"which can receive keyboard focus under normal circumstances. For a X11 grab " +"to be taken into account under Wayland, the client must also either send a " +"specific X11 ClientMessage to the root window or be among the applications " +"white-listed in key “xwayland-grab-access-rules”." +msgstr "" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:84 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "Xwayland ਐਪਲੀਕੇਸ਼ਨਾਂ ਕੀਬੋਰਡ ਫੜਨ ਦੀ ਇਜਾਜ਼ਤ ਦਿੰਦੀਆਂ ਹਨ" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:85 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "" + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. +#. +#: src/backends/meta-input-settings.c:2567 +#, c-format +msgid "Mode Switch (Group %d)" +msgstr "ਮੋਡ ਬਦਲੋ (ਗਰੁੱਪ %d)" + +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2590 +msgid "Switch monitor" +msgstr "ਮਾਨੀਟਰ ਨੂੰ ਬਦਲੋ" + +#: src/backends/meta-input-settings.c:2592 +msgid "Show on-screen help" +msgstr "ਆਨ-ਸਕਰੀਨ ਮਦਦ ਵੇਖੋ" + +#: src/backends/meta-monitor.c:223 +msgid "Built-in display" +msgstr "ਬਿਲਟ-ਇਨ ਡਿਸਪਲੇਅ" + +#: src/backends/meta-monitor.c:252 +msgid "Unknown" +msgstr "ਅਣਜਾਣ" + +#: src/backends/meta-monitor.c:254 +msgid "Unknown Display" +msgstr "ਅਣਜਾਣ ਡਿਸਪਲੇਅ" + +#: src/backends/meta-monitor.c:262 #, c-format -msgid "Missing %s extension required for compositing" -msgstr "ਕੰਪੋਜ਼ਿਸ਼ਨਿੰਗ ਲਈ %s ਐਕਸਟੈਨਸ਼ਨ ਗੁੰਮ ਹੈ" +#| msgid "%s %s" +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" -#: ../src/core/display.c:427 +#: src/backends/meta-monitor.c:270 #, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "X ਵਿੰਡੋ ਸਿਸਟਮ ਡਿਸਪਲੇਅ '%s' ਨੂੰ ਖੋਲਣ ਵਿੱਚ ਅਸਮਰਥ\n" +#| msgid "%s %s" +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" + +#. Translators: this string will appear in Sysprof +#: src/backends/meta-profiler.c:79 +#| msgid "Compositing Manager" +msgid "Compositor" +msgstr "ਕੰਪੋਜੀਟਰ" -#: ../src/core/keybindings.c:852 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:533 #, c-format msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" +"Another compositing manager is already running on screen %i on display “%s”." msgstr "" -"ਕੋਈ ਹੋਰ ਪਰੋਗਰਾਮ %s ਸਵਿੱਚ ਨੂੰ %x ਸੋਧਕ ਨਾਲ ਪਹਿਲਾਂ ਹੀ ਜੋੜ ਵਾਂਗ ਵਰਤ ਰਿਹਾ ਹੈ\n" +"ਇੱਕ ਹੋਰ ਕੰਪੋਜ਼ਟਿੰਗ ਮੈਨੇਜਰ %i ਸਕਰੀਨ ਉੱਤੇ ਡਿਸਪਲੇਅ ”%s” ਉੱਤੇ ਪਹਿਲਾਂ ਹੀ ਚੱਲ ਰਿਹਾ" +" ਹੈ।" + +#: src/core/bell.c:192 +msgid "Bell event" +msgstr "ਘੰਟੀ ਈਵੈਂਟ" -#: ../src/core/main.c:206 +#: src/core/main.c:190 msgid "Disable connection to session manager" msgstr "ਸ਼ੈਸ਼ਨ ਮੈਨੇਜਰ ਨਾਲ ਕੁਨੈਕਸ਼ਨ ਅਯੋਗ" -#: ../src/core/main.c:212 +#: src/core/main.c:196 msgid "Replace the running window manager" msgstr "ਚੱਲ ਰਹੇ ਵਿੰਡੋ ਮੈਨੇਜਰ ਨੂੰ ਬਦਲੋ" -#: ../src/core/main.c:218 +#: src/core/main.c:202 msgid "Specify session management ID" msgstr "ਸ਼ੈਸ਼ਨ ਪਰਬੰਧਨ ID ਦਿਓ" -#: ../src/core/main.c:223 +#: src/core/main.c:207 msgid "X Display to use" msgstr "ਵਰਤਣ ਲਈ X ਡਿਸਪਲੇਅ" -#: ../src/core/main.c:229 +#: src/core/main.c:213 msgid "Initialize session from savefile" msgstr "ਸੰਭਾਲੀ ਫਾਇਲ ਤੋਂ ਸ਼ੈਸ਼ਨ ਸ਼ੁਰੂ" -#: ../src/core/main.c:235 +#: src/core/main.c:219 msgid "Make X calls synchronous" msgstr "X ਕਾਲ ਸੈਕਰੋਨਸ ਬਣਾਓ" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "ਥੀਮ ਡਾਇਰੈਕਟਰੀ ਦੀ ਜਾਂਚ ਅਸਫਲ: %s\n" +#: src/core/main.c:226 +msgid "Run as a wayland compositor" +msgstr "ਵੇਲੈਂਡ ਕੰਪੋਜ਼ਰ ਵਜੋਂ ਚਲਾਓ" + +#: src/core/main.c:232 +msgid "Run as a nested compositor" +msgstr "ਨੈਸਟਡ ਕੰਪੋਜ਼ਰ ਵਜੋਂ ਚਲਾਓ" + +#: src/core/main.c:238 +msgid "Run wayland compositor without starting Xwayland" +msgstr "Xwayland ਸ਼ੁਰੂ ਕੀਤੇ ਬਿਨਾਂ ਵੇਲੈਂਡ ਕੰਪੋਜ਼ੀਟਰ ਚਲਾਓ" + +#: src/core/main.c:246 +msgid "Run as a full display server, rather than nested" +msgstr "ਅੰਦਰੂਨੀ ਰੂਪ ਵਿੱਚ ਚਲਾਉਣ ਦੀ ਬਜਾਏ ਪੂਰੇ ਡਿਸਪਲੇਅ ਸਰਵਰ ਵਜੋਂ ਚਲਾਓ" -#: ../src/core/main.c:520 +#: src/core/main.c:252 +msgid "Run with X11 backend" +msgstr "X11 ਬੈਕਐਡ ਨਾਲ ਚਲਾਓ" + +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:151 #, c-format +msgid "“%s” is not responding." +msgstr "\"%s\" ਜਵਾਬ ਨਹੀਂ ਦੇ ਰਹੀ ਹੈ।" + +#: src/core/meta-close-dialog-default.c:153 +msgid "Application is not responding." +msgstr "ਐਪਲੀਕੇਸ਼ਨ ਜਵਾਬ ਨਹੀਂ ਦੇ ਰਹੀ ਹੈ।" + +#: src/core/meta-close-dialog-default.c:158 msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." msgstr "" -"ਥੀਮ ਨਹੀ ਲੱਭ ਸਕਿਆ! ਯਕੀਨੀ ਬਣਾਓ ਕਿ %s ਮੌਜੂਦ ਹੈ ਅਤੇ ਇਸ ਵਿਚ ਵਰਤਣ ਵਾਲੇ ਥੀਮ ਹਨ।\n" +"ਤੁਸੀਂ ਇਸ ਲਈ ਕੁਝ ਸਮੇਂ ਵਾਸਤੇ ਉਡੀਕ ਕਰ ਸਕਦੇ ਹੋ ਜਾਂ ਕਾਰਜ ਨੂੰ ਧੱਕੇ ਨਾਲ ਬੰਦ ਕਰ ਸਕਦੇ" +" ਹੋ।" + +#: src/core/meta-close-dialog-default.c:165 +msgid "_Force Quit" +msgstr "ਧੱਕੇ ਨਾਲ ਬੰਦ(_F)" + +#: src/core/meta-close-dialog-default.c:165 +msgid "_Wait" +msgstr "ਉਡੀਕੋ(_W)" -#: ../src/core/muffin.c:40 +#: src/core/mutter.c:38 #, c-format msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" "This is free software; see the source for copying conditions.\n" "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " "PARTICULAR PURPOSE.\n" msgstr "" -"ਮੱਟਰ %s\n" -"ਹੱਕ ਰਾਖਵੇਂ ਹਨ(C) ੨੦੦੧-%d ਹਾਵੇਨ ਪੈਨਿੰਗਟੋਨ, ਰੈੱਡ ਹੈੱਟ, ਅਤੇ ਹੋਰ\n" +"ਮੁੱਟਰ %s\n" +"ਹੱਕ ਰਾਖਵੇਂ ਹਨ © ੨੦੦੧-%d ਹਾਵੇਨ ਪੈਨਿੰਗਟੋਨ, ਰੈੱਡ ਹੈੱਟ, ਅਤੇ ਹੋਰ\n" "ਇਹ ਮੁਫਤ ਸਾਫਟਵੇਅਰ ਹੈ; ਉਤਾਰਾ ਹਾਲਤਾਂ ਲਈ ਸਰੋਤ ਵੇਖੋ।\n" "ਇਸ ਦੀ ਕੋਈ ਗਰੰਟੀ ਨਹੀ; ਇਥੋਂ ਤੱਕ ਕਿ ਖਰੀਦਦਾਰੀ ਜਾਂ ਖਾਸ ਮਕਸਦ ਦੀ ਪੂਰਤੀ ਲਈ ਵੀ।\n" -#: ../src/core/muffin.c:54 +#: src/core/mutter.c:52 msgid "Print version" msgstr "ਵਰਜਨ ਛਾਪੋ" -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "ਕਾਮਿਆਂ ਨਾਲ ਵੱਖ ਕੀਤੀ ਕੰਪੋਜ਼ਿਤਰ ਪਲੱਗਇਨ ਦੀ ਲਿਸਟ" - -#: ../src/core/prefs.c:1077 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"ਖਰਾਬ ਐਪਲੀਕੇਸ਼ਨ ਲਈ ਜੁਗਾੜ ਬੰਦ ਕੀਤਾ ਹੈ। ਕੁਝ ਐਪਲੀਕੇਸ਼ਨ ਚੰਗੀ ਤਰਾਂ ਕੰਮ ਨਹੀਂ ਕਰ ਸਕਦੇ " -"ਹਨ।\n" +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "ਵਰਤਣ ਲਈ ਮੁੱਟਰ ਪਲੱਗਇਨ" -#: ../src/core/prefs.c:1152 +#: src/core/prefs.c:1911 #, c-format -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "" -"GSettings ਸਵਿੱਚ \"%2$s\" ਤੋਂ ਫੋਂਟ ਵੇਰਵੇ \"%1$s\" ਨੂੰ ਪਾਰਸ ਨਹੀਂ ਕਰ ਸਕਿਆ\n" +msgid "Workspace %d" +msgstr "ਵਰਕਸਪੇਸ %d" + +#: src/core/util.c:122 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "ਮੱਟਰ, ਵਰਬੋਜ਼ ਮੋਡ ਲਈ ਸਹਾਰੇ ਤੋਂ ਬਿਨਾਂ ਕੰਪਾਇਲ ਹੋਇਆ\n" -#: ../src/core/prefs.c:1218 +#: src/wayland/meta-wayland-tablet-pad.c:568 #, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"ਸੰਰਚਨਾ ਡਾਟਾਬੇਸ ਵਿੱਚ ਲੱਭੀ ਹੋਈ \"%s\" ਮਾਊਸ ਬਟਨ ਸੋਧਕ ਲਈ ਯੋਗ ਕੀਮਤ ਨਹੀਂ ਹੈ\n" +msgid "Mode Switch: Mode %d" +msgstr "ਮੋਡ ਬਦਲੋ: ਮੋਡ %d" -#: ../src/core/prefs.c:1736 +#: src/x11/meta-x11-display.c:676 #, c-format msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." msgstr "" -"ਸੰਰਚਨਾ ਡਾਟਾਬੇਸ ਵਿੱਚ ਲੱਭੀ ਹੋਈ \"%s\" ਸਵਿੱਚ-ਬਾਈਡਿੰਗ \"%s\" ਲਈ ਯੋਗ ਕੀਮਤ ਨਹੀਂ " -"ਹੈ\n" +"ਡਿਸਪਲੇਅ ”%s” ਉੱਤੇ ਪਹਿਲਾਂ ਹੀ ਵਿੰਡੋ ਮੈਨੇਜਰ ਮੌਜੂਦ ਹੈ; ਮੌਜੂਦਾ ਵਿੰਡੋ ਮੈਨੇਜਰ ਨੂੰ" +" ਬਦਲਣ ਲਈ --replace ਚੋਣ " +"ਵਰਤ ਕੇ ਦੇਖੋ।" + +#: src/x11/meta-x11-display.c:1089 +msgid "Failed to initialize GDK\n" +msgstr "GDK ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਅਸਫ਼ਲ ਹੈ\n" -#: ../src/core/prefs.c:1833 +#: src/x11/meta-x11-display.c:1113 #, c-format -msgid "Workspace %d" -msgstr "ਵਰਕਸਪੇਸ %d" +msgid "Failed to open X Window System display “%s”\n" +msgstr "X ਵਿੰਡੋ ਸਿਸਟਮ ਡਿਸਪਲੇਅ ”%s” ਨੂੰ ਖੋਲਣ ਵਿੱਚ ਅਸਮਰਥ\n" -#: ../src/core/screen.c:730 +#: src/x11/meta-x11-display.c:1196 #, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "ਡਿਸਪਲੇਅ '%2$s' ਉੱਤੇ ਸਕਰੀਨ %1$d ਗਲਤ ਹੈ\n" +msgid "Screen %d on display “%s” is invalid\n" +msgstr "ਡਿਸਪਲੇਅ ”%2$s” ਉੱਤੇ ਸਕਰੀਨ %1$d ਗਲਤ ਹੈ\n" -#: ../src/core/screen.c:746 +#: src/x11/meta-x11-selection-input-stream.c:460 #, c-format +msgid "Format %s not supported" +msgstr "ਫਾਰਮੈਟ %s ਸਹਾਇਕ ਨਹੀਂ ਹੈ" + +#: src/x11/session.c:1821 msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." msgstr "" -"ਡਿਸਪਲੇਅ \"%2$s\" ਉੱਤੇ ਸਕਰੀਨ %1$d ਪਹਿਲਾਂ ਹੀ ਮੌਜੂਦ ਹੈ, ਇਸ ਨੂੰ ਤਬਦੀਲ ਕਰਨ ਦੀ ਚੋਣ " -"--replace " -"ਮੌਜੂਦਾ ਵਿੰਡੋ ਮੈਨੇਜਰ ਵਰਤੋਂ।\n" +"ਇਹ ਵਿੰਡੋ ”ਮੌਜੂਦਾ ਸੈਟਅੱਪ ਸੰਭਾਲੋ” ਵਾਸਤੇ ਸਹਾਇਕ ਨਹੀਂ ਅਤੇ ਅਗਲੀ ਵਾਰ ਜਦੋਂ ਤੁਸੀਂ" +" ਲਾਗਇਨ ਕਰੋਗੇ ਤਾਂ ਮੁੜ ਸ਼ੁਰੂ " +"ਕਰਨਾ ਪਵੇਗਾ।" -#: ../src/core/screen.c:773 +#: src/x11/window-props.c:569 #, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "ਡਿਸਪਲੇਅ \"%2$s\" %1$d ਸਕਰੀਨ ਉੱਤੇ ਵਿੰਡੋ ਮੈਨੇਜਰ ਚੋਣ ਉਪਲੱਬਧ ਨਹੀਂ ਹੋ ਸਕੀ\n" +msgid "%s (on %s)" +msgstr "%s (%s ਉੱਤੇ)" -#: ../src/core/screen.c:828 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "ਡਿਸਪਲੇਅ \"%2$s\" ਉੱਤੇ ਸਕਰੀਨ %1$d ਕੋਲ ਪਹਿਲਾਂ ਹੀ ਵਿੰਡੋ ਮੈਨੇਜਰ ਹੈ\n" +#~ msgid "Move window one workspace to the left" +#~ msgstr "ਵਿੰਡੋ ਨੂੰ ਇੱਕ ਵਰਕਸਪੇਸ ਖੱਬੇ ਵੱਲ ਲਿਜਾਓ" -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "ਡਿਸਪਲੇਅ \"%2$s\" ਉੱਤੇ ਸਕਰੀਨ %1$d ਰੀਲਿਜ਼ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ\n" +#~ msgid "Move window one workspace to the right" +#~ msgstr "ਵਿੰਡੋ ਨੂੰ ਇੱਕ ਵਰਕਸਪੇਸ ਸੱਜੇ ਵੱਲ ਲਿਜਾਓ" -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "'%s' ਡਾਇਰੈਕਟਰੀ ਬਣਾਈ ਨਹੀਂ ਜਾ ਸਕੀ:%s\n" +#~ msgid "Move to workspace left" +#~ msgstr "ਖੱਬੇ ਵਰਕਸਪੇਸ 'ਚ ਭੇਜੋ" -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "ਲਿਖਣ ਲਈ ਸ਼ੈਸ਼ਨ ਫਾਇਲ '%s' ਖੋਲ੍ਹੀ ਨਹੀਂ ਜਾ ਸਕੀ: %s\n" +#~ msgid "Move to workspace right" +#~ msgstr "ਸੱਜੇ ਵਰਕਸਪੇਸ 'ਚ ਭੇਜੋ" -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "ਸ਼ੈਸ਼ਨ ਫਾਇਲ '%s' ਲਿਖਣ ਦੀ ਗਲਤੀ:%s\n" +#~ msgid "Toggle shaded state" +#~ msgstr "ਰੰਗਤ ਸਥਿਤੀ ਬਦਲੋ" -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "ਸ਼ੈਸ਼ਨ ਫਾਇਲ '%s' ਖੋਲ੍ਹਣ ਦੀ ਗਲਤੀ: %s\n" +#~ msgid "Failed to scan themes directory: %s\n" +#~ msgstr "ਥੀਮ ਡਾਇਰੈਕਟਰੀ ਦੀ ਜਾਂਚ ਅਸਫਲ: %s\n" -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "ਸੰਭਾਲੀ ਸ਼ੈਸ਼ਨ ਫਾਇਲ ਨੂੰ ਪਾਰਸ ਕਰਨ ਲਈ ਅਸਫਲ: %s\n" +#~ msgid "" +#~ "Could not find a theme! Be sure %s exists and contains the usual themes.\n" +#~ msgstr "" +#~ "ਥੀਮ ਨਹੀ ਲੱਭ ਸਕਿਆ! ਯਕੀਨੀ ਬਣਾਓ ਕਿ %s ਮੌਜੂਦ ਹੈ ਅਤੇ ਇਸ ਵਿਚ ਵਰਤਣ ਵਾਲੇ ਥੀਮ ਹਨ।\n" -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "<muffin_session> ਗੁਣ ਦਿਖਿਆ, ਪਰ ਸਾਡੇ ਕੋਲ ਸ਼ੈਸ਼ਨ ID ਪਹਿਲਾਂ ਹੀ ਹੈ" +#~ msgid "Screen %d on display \"%s\" already has a window manager\n" +#~ msgstr "ਡਿਸਪਲੇਅ \"%2$s\" ਉੱਤੇ ਸਕਰੀਨ %1$d ਕੋਲ ਪਹਿਲਾਂ ਹੀ ਵਿੰਡੋ ਮੈਨੇਜਰ ਹੈ\n" -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "<%2$s> ਐਲੀਮੈਂਟ ਉੱਤੇ ਅਣਜਾਣ %1$s ਗੁਣ" +#~ msgid "%d x %d" +#~ msgstr "%d x %d" -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "ਨੈਸਟਡ <window> ਟੈਗ" +#~ msgid "top" +#~ msgstr "ਉੱਤੇ" -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "ਅਣਜਾਣ ਐਲੀਮੈਂਟ %s" +#~ msgid "bottom" +#~ msgstr "ਹੇਠਾਂ" -#: ../src/core/session.c:1809 -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" -"ਇਹ ਵਿੰਡੋ "ਮੌਜੂਦਾ ਸੈਟਅੱਪ ਸੰਭਾਲੋ" ਵਾਸਤੇ ਸਹਾਇਕ ਨਹੀਂ ਅਤੇ ਅਗਲੀ ਵਾਰ ਜਦੋਂ " -"ਤੁਸੀਂ ਲਾਗਇਨ " -"ਕਰੋਗੇ ਤਾਂ ਮੁੜ ਸ਼ੁਰੂ ਕਰਨਾ ਪਵੇਗਾ।" +#~ msgid "left" +#~ msgstr "ਖੱਬਾ" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "ਡੀਬੱਗ ਲਾਗ ਖੋਲ੍ਹਣ ਵਿੱਚ ਅਸਫਲ: %s\n" +#~ msgid "right" +#~ msgstr "ਸੱਜਾ" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "ਲਾਗ ਫਾਇਲ %s ਨੂੰ fdopen() ਲਈ ਅਸਫਲ: %s\n" +#~ msgid "frame geometry does not specify \"%s\" dimension" +#~ msgstr "ਫਰੇਮ ਜੁਮੈਟਰੀ \"%s\" ਮਾਪ ਨਹੀਂ ਦਰਸਾਉਦੀ ਹੈ" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "ਖੁੱਲ੍ਹੀ ਲਾਗ ਫਾਇਲ %s\n" +#~ msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" +#~ msgstr "ਫਰੇਮ ਜੁਮੈਟਰੀ \"%2$s\" ਹਾਸ਼ੀਏ ਲਈ \"%1$s\" ਮਾਪ ਨਹੀਂ ਦਰਸਾਉਦੀ ਹੈ" -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "ਮੱਟਰ, ਵਰਬੋਜ਼ ਮੋਡ ਲਈ ਸਹਾਰੇ ਤੋਂ ਬਿਨਾਂ ਕੰਪਾਇਲ ਹੋਇਆ\n" +#~ msgid "Button aspect ratio %g is not reasonable" +#~ msgstr "ਤਲ ਆਕਾਰ ਅਨੁਪਾਤ %g ਢੁੱਕਵਾਂ ਨਹੀਂ ਹੈ" -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "ਵਿੰਡੋ ਮੈਨੇਜਰ: " +#~ msgid "Frame geometry does not specify size of buttons" +#~ msgstr "ਫਰੇਮ ਜੁਮੈਟਰੀ ਬਟਨਾਂ ਦਾ ਆਕਾਰ ਨਹੀਂ ਦਰਸਾਉਦੀ" -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "ਵਿੰਡੋ ਮੈਨੇਜਰ ਵਿੱਚ ਬੱਗ: " +#~ msgid "Gradients should have at least two colors" +#~ msgstr "ਢਾਲਵੇ ਲਈ ਘੱਟ ਤੋਂ ਘੱਟ ਦੋ ਰੰਗ ਚਾਹੀਦੇ ਹਨ" -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "ਵਿੰਡੋ ਮੈਨੇਜਰ ਚੇਤਾਵਨੀ: " +#~ msgid "" +#~ "GTK custom color specification must have color name and fallback in " +#~ "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" +#~ msgstr "" +#~ "ਹਾਲਤ ਤੋਂ ਬਾਅਦ GTK ਰੰਗ ਹਦਾਇਤ ਬਰੈਕਟਾਂ ਵਿੱਚ ਬੰਦ ਕਰਨੀ ਜ਼ਰੂਰੀ ਹੈ, ਉਦਾਹਰਨ ਵਜੋਂ gtk:custom " +#~ "(foo,bar); \"%s\" ਦੀ ਪਾਰਸ ਨਹੀਂ ਕਰ ਸਕਿਆ" -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "ਵਿੰਡੋ ਮੈਨੇਜਰ ਗਲਤੀ: " +#~ msgid "" +#~ "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-" +#~ "z0-9-_ are valid" +#~ msgstr "" +#~ "gtk:custom ਦੇ color_name ਪੈਰਾਮੀਟਰ ਵਿੱਚ ਗਲਤ ਅੱਖਰ '%c' ਹੈ, ਕੇਵਲ A-Za-z0-9-_ ਸ਼ਾਮਲ " +#~ "ਹੋ ਸਕਦੇ ਹਨ" -#. first time through -#: ../src/core/window.c:7224 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"ਵਿੰਡੋ %s ਨੇ ਆਪਣੇ ਉੱਤੇ ICCCM ਰਾਹੀਂ ਦੱਸੇ ਅਨੁਸਾਰ WM_CLIENT_LEADER ਵਿੰਡੋ ਦੀ ਬਜਾਏ " -"SM_CLIENT_ID ਨਿਰਧਾਰਿਤ ਕੀਤਾ ਹੈ।\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7887 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %" -"d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"ਵਿੰਡੋ %s ਨੇ MWM ਸੰਕੇਤ ਸੈੱਟ ਵੇਖਾਇਆ ਕਿ ਇਹ ਮੁੜ-ਆਕਾਰ-ਯੋਗ ਨਹੀਂ ਹੈ, ਪਰ ਘੱਟੋ-ਘੱਟ " -"ਆਕਾਰ %d x %d ਅਤੇ " -"ਵੱਧ ਤੋਂ ਵੱਧ ਆਕਾਰ %d x %d ਸੈੱਟ ਕਰਦਾ ਹੈ, ਪਰ ਇਹ ਦਾ ਜ਼ਿਆਦਾ ਮਤਲਬ ਨਹੀਂ ਹੈ।\n" +#~ msgid "" +#~ "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " +#~ "fit the format" +#~ msgstr "" +#~ "Gtk:custom ਫਾਰਮੈਟ \"gtk:custom(color_name,fallback)\" ਹੈ, \"%s\" ਫਾਰਮੈਟ ਵਿੱਚ " +#~ "ਫਿੱਟ ਨਹੀਂ ਹੈ" -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "ਐਪਲੀਕੇਸ਼ਨ ਨੇ ਇੱਕ ਫਰਜ਼ੀ _NET_WM_PID %lu ਦਿੱਤਾ ਹੈ\n" +#~ msgid "" +#~ "GTK color specification must have the state in brackets, e.g. gtk:" +#~ "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "GTK ਰੰਗ ਹਦਾਇਤਾਂ ਦੀ ਹਾਲਤ ਬਰੈਕਟਾਂ ਵਿੱਚ ਜਰੂਰੀ ਹੈ, ਉਦਾਹਰਨ ਵਜੋਂ gtk:fg[ਸਾਧਾਰਨ] ਜਿੱਥੇ " +#~ "ਸਾਧਾਰਨ ਇੱਕ ਹਾਲਤ ਹੈ; \"%s\" ਦੀ ਪਾਰਸ ਨਹੀਂ ਕਰ ਸਕਿਆ" -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (%s ਉੱਤੇ)" +#~ msgid "" +#~ "GTK color specification must have a close bracket after the state, e.g. " +#~ "gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "ਹਾਲਤ ਤੋਂ ਬਾਅਦ GTK ਰੰਗ ਹਦਾਇਤ ਬਰੈਕਟਾਂ ਵਿੱਚ ਬੰਦ ਕਰਨੀ ਜ਼ਰੂਰੀ ਹੈ, ਉਦਾਹਰਨ ਵਜੋਂ gtk:" +#~ "fg[ਸਾਧਾਰਨ] ਜਿੱਥੇ ਸਾਧਾਰਨ ਇੱਕ ਹਾਲਤ ਹੈ; \"%s\" ਦੀ ਪਾਰਸ ਨਹੀਂ ਕਰ ਸਕਿਆ" -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "ਗਲਤ WM_TRANSIENT_FOR ਵਿੰਡੋ 0x%lx %s ਲਈ ਦਿੱਤਾ ਗਿਆ ਹੈ।\n" +#~ msgid "Did not understand state \"%s\" in color specification" +#~ msgstr "ਰੰਗ ਹਦਾਇਤ ਵਿੱਚ \"%s\" ਹਾਲਤ ਨੂੰ ਨਹੀਂ ਸਮਝਿਆ" -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "WM_TRANSIENT_FOR ਵਿੰਡੋ 0x%lx %s ਲੂਪ ਬਣਾਏਗਾ।\n" +#~ msgid "Did not understand color component \"%s\" in color specification" +#~ msgstr "ਰੰਗ ਹਦਾਇਤ ਵਿੱਚ ਰੰਗ ਸੰਖੇਪ \"%s\" ਨੂੰ ਨਹੀਂ ਸਮਝਿਆ" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"0x%lx ਵਿੰਡੋ ਵਿੱਚ %s ਵਿਸ਼ੇਸ਼ਤਾ ਹੈ\n" -"ਜੋ ਕਿ ਕਿਸਮ %s ਫਾਰਮੈਟ %d ਹੋਣ ਦੀ ਉਮੀਦ ਹੈ\n" -"ਅਤੇ ਅਸਲ ਵਿੱਚ ਕਿਸਮ %s ਵਿਸ਼ੇਸ਼ਤਾ %d n_ਅੰਗ %d ਹੈ।\n" -"ਇਹ ਜਿਆਦਾਤਰ ਐਪਲੀਕੇਸ਼ਨ ਬੱਗ ਵਰਗਾ ਹੈ ਵਿੰਡੋ ਬੱਗ ਵਰਗਾ ਨਹੀਂ।\n" -"ਵਿੰਡੋ ਦਾ ਟਾਇਟਲ=\"%s\" ਕਿਸਮ=\"%s\" ਨਾਂ=\"%s\" ਹੈ\n" +#~ msgid "" +#~ "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit " +#~ "the format" +#~ msgstr "ਧੁੰਦਲੀ ਬਣਤਰ \"ਧੁੰਦਲੀ/bg_ਰੰਗ/ਐਲਫਾ, \"%s\" ਬਣਤਰ ਵਿੱਚ ਠੀਕ ਨਹੀਂ ਆਂਉਦੀ" -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "ਵਿਸ਼ੇਸ਼ਤਾ %s ਵਿੰਡੋ 0x%lx ਵਿੱਚ ਅਯੋਗ UTF-8 ਸ਼ਾਮਿਲ ਹੈ\n" +#~ msgid "Could not parse alpha value \"%s\" in blended color" +#~ msgstr "ਧੁੰਦਲੇ ਰੰਗ ਵਿੱਚ ਐਲਫਾ ਕੀਮਤ \"%s\" ਦੀ ਪਾਰਸ ਨਹੀਂ ਕਰ ਸਕਿਆ" -#: ../src/core/xprops.c:494 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"%s ਵਿਸ਼ੇਸ਼ਤਾ 0x%lx ਵਿੰਡੋ ਉੱਤੇ ਵਿੱਚ ਲੜੀ ਵਿਚਲੇ ਮੈਂਬਰ %d ਲਈ ਅਯੋਗ UTF-8 ਸ਼ਾਮਿਲ ਹੈ\n" +#~ msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" +#~ msgstr "ਧੁੰਦਲੇ ਰੰਗ ਵਿੱਚ ਐਲਫਾ ਕੀਮਤ \"%s\" 0.0 ਅਤੇ 1.0 ਵਿਚਕਾਰ ਨਹੀਂ ਹੈ" -#: ../src/muffin.desktop.in.h:1 ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "ਮੱਟਰ" +#~ msgid "" +#~ "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the " +#~ "format" +#~ msgstr "ਰੰਗਤ ਬਣਤਰ \"ਰੰਗਤ/ਆਧਾਰ_ਰੰਗ/ਫੈਕਟਰ\" ਹੈ, \"%s\" ਬਣਤਰ ਵਿੱਚ ਠੀਕ ਨਹੀਂ ਆਉਦੀ" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 -msgid "Modifier to use for extended window management operations" -msgstr "ਵਾਧੂ ਵਿੰਡੋ ਪਰਬੰਧ ਓਪਰੇਸ਼ਨਾਂ ਲਈ ਵਰਤਣ ਵਾਸਤੇ ਮੋਡੀਫਾਇਰ" +#~ msgid "Could not parse shade factor \"%s\" in shaded color" +#~ msgstr "ਛਾਇਆ ਰੰਗ ਵਿੱਚ ਰੰਗਤ ਫੈਕਟਰ \"%s\" ਦੀ ਪਾਰਸ ਨਹੀਂ ਕਰ ਸਕਿਆ" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 -msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." -msgstr "" -"ਇਹ ਸਵਿੱਚ \"ਓਵਰਲੇ\" ਸ਼ੁਰੂ ਕਰਦੀ ਹੈ, ਜੋ ਕਿ ਵਿੰਡੋ ਸੰਖੇਪ ਤੇ ਐਪਲੀਕੇਸ਼ਨ ਚਲਾਉਣ ਸਿਸਟਮ " -"ਦੀ ਜੋੜ ਹੈ। " -"ਡਿਫਾਲਟ ਇਹ PC ਹਾਰਡਵੇਅਰ ਉੱਤੇ \"ਵਿੰਡੋਜ਼ ਸਵਿੱਚ\" ਨਾਲ ਵਰਤਣ ਲਈ ਹੈ। ਇਹ ਉਮੀਦ ਕੀਤੀ " -"ਜਾਂਦੀ ਹੈ ਕਿ " -"ਜਾਂ ਤਾਂ ਡਿਫਾਲਟ ਬਾਈਡਿੰਗ ਰੱਖੀ ਜਾਵੇ ਜਾਂ ਖਾਲੀ ਲਾਈਨ ਵਰਤੀ ਜਾਵੇ।" +#~ msgid "Shade factor \"%s\" in shaded color is negative" +#~ msgstr "ਛਾਇਆ ਰੰਗ ਵਿੱਚ ਰੰਗਤ ਫੈਕਟਰ \"%s\" ਨਾਂਹਵਾਚਕ ਹੈ" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 -msgid "Attach modal dialogs" -msgstr "ਮਾਡਲ ਡਾਈਲਾਗ ਅਟੈਚਮੈਂਟ" +#~ msgid "Could not parse color \"%s\"" +#~ msgstr "\"%s\" ਰੰਗ ਦੀ ਪਾਰਸ ਨਹੀਂ ਕਰ ਸਕਿਆ" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 -msgid "" -"When true, instead of having independent titlebars, modal dialogs appear " -"attached to the titlebar of the parent window and are moved together with " -"the parent window." -msgstr "" -"ਜਦੋਂ ਸਹੀਂ ਹੋਵੇ ਤਾਂ ਵੱਖ ਵੱਖ ਟਾਈਟਲਬਾਰ ਦੀ ਬਜਾਏ, ਮਾਡਲ ਡਾਈਲਾਗ ਮੁੱਢਲੀ ਵਿੰਡੋ ਦੇ " -"ਟਾਈਟਲ ਬਾਰ ਨਾਲ " -"ਜੁੜਿਆ ਉਭਰੇਗਾ ਤੇ ਮੁੱਢਲੀ ਵਿੰਡੋ ਨਾਲ ਹੀ ਹਿੱਲੇਗਾ।" +#~ msgid "Coordinate expression contains character '%s' which is not allowed" +#~ msgstr "ਕਰੋਆਡੀਨੇਟ ਐਕਸ਼ਪਰੈਸ਼ਨ ਵਿੱਚ ਅੱਖਰ '%s' ਸ਼ਾਮਿਲ ਹੈ ਜਿਸ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -msgid "Live Hidden Windows" -msgstr "ਲੁਕਵੀਆਂ ਵਿੰਡੋਜ਼ ਲਾਈਵ" +#~ msgid "" +#~ "Coordinate expression contains floating point number '%s' which could not " +#~ "be parsed" +#~ msgstr "" +#~ "ਕਰੋਆਡੀਨੇਟ ਐਕਸ਼ਪਰੈਸ਼ਨ ਵਿੱਚ ਦਸ਼ਮਲਵ ਅੰਕ '%s' ਸ਼ਾਮਿਲ ਹੈ ਜਿਸ ਦੀ ਪਾਰਸ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"ਦੱਸੋ ਕਿ ਕੀ ਲੁਕਵੀਆਂ ਵਿੰਡੋਜ਼ ਚਾਲੂ ਰੱਖਣੀਆਂ ਹਨ (ਜਿਵੇਂ ਕਿ ਘੱਟੋ-ਘੱਟ ਕੀਤੀ ਵਿੰਡੋਜ਼ ਤੇ " -"ਮੌਜੂਦਾ ਵਰਕਸਪੇਸ ਤੋਂ " -"ਬਿਨਾਂ ਹੋਰ ਤੋਂ ਵਿੰਡੋਜ਼)।" +#~ msgid "" +#~ "Coordinate expression contains integer '%s' which could not be parsed" +#~ msgstr "" +#~ "ਕਰੋਆਡੀਨੇਟ ਐਕਸ਼ਪਰੈਸ਼ਨ ਵਿੱਚ ਪੂਰਨ ਅੰਕ '%s' ਸ਼ਾਮਿਲ ਹੈ ਜਿਸ ਦੀ ਪਾਰਸ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 -msgid "Enable edge tiling when dropping windows on screen edges" -msgstr "ਕੋਨਾ ਟਿਲਿੰਗ ਚਾਲੂ, ਜਦੋਂ ਵਿੰਡੋਜ਼ ਨੂੰ ਸਕਰੀਨ ਕੋਨਿਆਂ ਤੋਂ ਡਰਾਪ ਕਰਨਾ ਹੋਵੇ" +#~ msgid "" +#~ "Coordinate expression contained unknown operator at the start of this " +#~ "text: \"%s\"" +#~ msgstr "ਕਰੋਆਡੀਨੇਟ ਐਕਸ਼ਪਰੈਸ਼ਨ ਵਿੱਚ ਇਸ ਪਾਠ \"%s\" ਦੇ ਸ਼ੁਰੂ ਵਿੱਚ ਅਣਪਛਾਤਾ ਆਪ੍ਰੇਟਰ ਸ਼ਾਮਿਲ ਹੈ" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 -msgid "" -"If enabled, dropping windows on vertical screen edges maximizes them " -"vertically and resizes them horizontally to cover half of the available " -"area. Dropping windows on the top screen edge maximizes them completely." -msgstr "" -"ਜੇ ਚਾਲੂ ਕੀਤਾ ਤਾਂ ਵਿੰਡੋਜ਼ ਨੂੰ ਖੜ੍ਹਵੀਂ ਸਕਰੀਨ ਬਾਹੀ ਉੱਤੇ ਲੈ ਜਾਣ ਨਾਲ ਉਹ ਖੜ੍ਹਵੇਂ " -"ਰੂਪ ਵਿੱਚ ਵੱਧ ਤੋਂ ਵੱਧ " -"ਕਰਦਾ ਹੈ ਅਤੇ ਖਿਤਿਜੀ (ਹਰੀਜੱਟਲ) ਰੂਪ ਵਿੱਚ ਉਪਲੱਬਧ ਖੇਤਰ ਵਿੱਚ ਅੱਧੇ ਥਾਂ ਲਈ ਮੁੜ-ਆਕਾਰ " -"ਕਰਦਾ ਹੈ। ਵਿੰਡੋਜ਼ " -"ਨੂੰ ਉੱਤੇ ਸਕਰੀਨ ਬਾਹੀ ਵਿੱਚ ਲੈ ਕੇ ਜਾਣ ਨਾਲ ਉਹ ਪੂਰੀ ਤਰ੍ਹਾਂ ਵੱਧ ਤੋਂ ਵੱਧ ਹੁੰਦਾ ਹੈ।" +#~ msgid "Coordinate expression was empty or not understood" +#~ msgstr "ਕਰੋਆਡੀਨੇਟ ਐਕਸ਼ਪਰੈਸ਼ਨ ਖਾਲੀ ਸੀ ਜਾਂ ਸਮਝਿਆ ਨਹੀਂ" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 -msgid "Workspaces are managed dynamically" -msgstr "ਵਰਕਸਪੇਸ ਦਾ ਪਰਬੰਧ ਚਲਵੇਂ ਰੂਪ ਵਿੱਚ ਕੀਤਾ ਜਾਂਦਾ ਹੈ" +#~ msgid "Coordinate expression results in division by zero" +#~ msgstr "ਕਰੋਆਡੀਨੇਟ ਐਕਸ਼ਪਰੈਸ਼ਨ ਦੇ ਨਤੀਜੇ ਵਜੋਂ ਜੀਰੋ ਨਾਲ ਭਾਗ ਹੈ" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 -msgid "" -"Determines whether workspaces are managed dynamically or whether there's a " -"static number of workspaces (determined by the num-workspaces key in org." -"gnome.desktop.wm.preferences)." -msgstr "" -"ਦੱਸੋ ਕਿ ਕੀ ਵਰਕਸਪੇਸ ਨੂੰ ਚਲਵੇਂ ਰੂਪ ਵਿੱਚ ਰੱਖਣਾ ਹੈ ਜਾਂ ਵਰਕਸਪੇਸ ਦੀ ਗਿਣਤੀ ਸਥਿਰ ਹੋਵੇ " -"(ਜੋ ਕਿ org." -"gnome.desktop.wm.preferences ਵਿੱਚ num-workspaces ਕੁੰਜੀ ਰਾਹੀਂ ਦੱਸੀ ਜਾਂਦੀ ਹੈ)।" +#~ msgid "" +#~ "Coordinate expression tries to use mod operator on a floating-point number" +#~ msgstr "ਕਰੋਆਡੀਨੇਟ ਐਕਸ਼ਪਰੈਸ਼ਨ ਦਸ਼ਮਲਵ ਅੰਕ ਉੱਤੇ ਮਾਡ (mod) ਆਪ੍ਰੇਟਰ ਵਰਤਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰਦਾ ਹੈ" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 -msgid "Workspaces only on primary" -msgstr "ਵਰਕਸਪੇਸ ਕੇਵਲ ਪ੍ਰਾਇਮਰੀ ਉੱਤੇ ਹੀ" +#~ msgid "" +#~ "Coordinate expression has an operator \"%s\" where an operand was expected" +#~ msgstr "ਕਰੋਆਡੀਨੇਟ ਐਕਸ਼ਪਰੈਸ਼ਨ ਵਿੱਚ ਆਪ੍ਰੇਟਰ \"%s\" ਹੈ ਜਿੱਥੇ ਪ੍ਰਭਾਵੀ ਅੰਕ ਦੀ ਉਮੀਦ ਸੀ" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 -msgid "" -"Determines whether workspace switching should happen for windows on all " -"monitors or only for windows on the primary monitor." -msgstr "" -"ਕੀ ਵਰਕਸਪੇਸ ਬਦਲਣਾ ਸਭ ਮਾਨੀਟਰ ਦੀਆਂ ਵਿੰਡੋ ਲਈ ਹੋਵੇ ਜਾਂ ਕੇਵਲ ਪ੍ਰਾਇਮਰੀ ਮਾਨੀਟਰ ਦੀਆਂ " -"ਵਿੰਡੋ ਲਈ ਹੀ " +#~ msgid "Coordinate expression had an operand where an operator was expected" +#~ msgstr "ਕਰੋਆਡੀਨੇਟ ਐਕਸ਼ਪਰੈਸ਼ਨ ਵਿੱਚ ਪ੍ਰਭਾਵੀ ਅੰਕ ਸੀ ਜਿੱਥੇ ਆਪ੍ਰੇਟਰ ਦੀ ਉਮੀਦ ਸੀ" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 -msgid "No tab popup" -msgstr "ਕੋਈ ਟੈਬ ਪੋਪਅੱਪ ਨਹੀਂ" +#~ msgid "Coordinate expression ended with an operator instead of an operand" +#~ msgstr "ਕਰੋਆਡੀਨੇਟ ਐਕਸ਼ਪਰੈਸ਼ਨ ਦੀ ਸਮਾਪਤੀ ਆਪ੍ਰੇਟਰ ਨਾਲ ਹੁੰਦੀ ਹੈ ਨਾ ਕਿ ਪ੍ਰਭਾਵੀ ਅੰਕ ਨਾਲ" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 -msgid "" -"Determines whether the use of popup and highlight frame should be disabled " -"for window cycling." -msgstr "" -"ਜਾਣੋ ਕਿ ਕੀ ਪੋਪਅੱਪ ਅਤੇ ਹਾਈਲਾਈਟ ਫਰੇਮ ਦੀ ਵਰਤੋਂ ਨੂੰ ਵਿੰਡੋਜ਼ ਦੇ ਚੱਕਰ ਦੌਰਾਨ ਬੰਦ " -"ਕਰਨਾ ਹੈ।" +#~ msgid "" +#~ "Coordinate expression has operator \"%c\" following operator \"%c\" with " +#~ "no operand in between" +#~ msgstr "" +#~ "ਕਰੋਆਡੀਨੇਟ ਐਕਸ਼ਪਰੈਸ਼ਨ ਵਿੱਚ ਵਿਚਕਾਰ ਪ੍ਰਭਾਵੀ ਅੰਕ ਤੋਂ ਬਿਨਾਂ ਆਪ੍ਰੇਟਰ \"%c\" ਤੋਂ ਬਾਅਦ ਆਪ੍ਰੇਟਰ " +#~ "\"%c\" ਹੈ " -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 -msgid "Draggable border width" -msgstr "ਡਰੈਗ ਹੋਣ ਯੋਗ ਬਾਰਡਰ ਚੌੜਾਈ" +#~ msgid "Coordinate expression had unknown variable or constant \"%s\"" +#~ msgstr "ਕਰੋਆਡੀਨੇਟ ਐਕਸ਼ਪਰੈਸ਼ਨ ਵਿੱਚ ਅਣਪਛਾਤਾ ਅਸਥਿਰ ਜਾਂ ਸਥਿਰ \"%s\" ਸੀ" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 -msgid "" -"The amount of total draggable borders. If the theme's visible borders are " -"not enough, invisible borders will be added to meet this value." -msgstr "" -"ਕੁੱਲ ਡਰੈਗ ਹੋਣ ਯੋਗ ਬਾਰਡਰ ਦੀ ਮਾਤਰਾ। ਜੇ ਥੀਮ ਦੇ ਦਿੱਖ ਬਾਰਡਰ ਲੋੜ ਮੁਤਾਬਕ ਨਾ ਹੋਣ ਤਾਂ " -"ਅਦਿੱਖ ਬਾਰਡਰ " -"ਨੂੰ ਇਹ ਮੁੱਲ ਦੇ ਬਰਾਬਰ ਕਰਨ ਲਈ ਵਧਾਇਆ ਜਾਵੇਗਾ।" +#~ msgid "Coordinate expression parser overflowed its buffer." +#~ msgstr "ਕਰੋਆਡੀਨੇਟ ਐਕਸ਼ਪਰੈਸ਼ਨ ਪਾਰਸਰ ਦਾ ਬਫ਼ਰ ਓਵਰਫਲੋ ਹੋ ਗਿਆ ਹੈ।" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:17 -msgid "Select window from tab popup" -msgstr "ਟੈਬ ਪੋਪਅੱਪ ਤੋਂ ਵਿੰਡੋ ਚੁਣੋ" +#~ msgid "" +#~ "Coordinate expression had a close parenthesis with no open parenthesis" +#~ msgstr "ਕਰੋਆਡੀਨੇਟ ਐਕਸ਼ਪਰੈਸ਼ਨ ਵਿੱਚ ਕੋਈ ਖੁੱਲੀ ਬਰੈਕਟ ਨਾ ਹੋਣ ਕਰਕੇ ਬੰਦ ਬਰੈਕਟ(parenthesis) ਸੀ" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:18 -msgid "Cancel tab popup" -msgstr "ਟੈਬ ਪੋਪਅੱਪ ਰੱਦ ਕਰੋ" +#~ msgid "" +#~ "Coordinate expression had an open parenthesis with no close parenthesis" +#~ msgstr "ਕਰੋਆਡੀਨੇਟ ਐਕਸ਼ਪਰੈਸ਼ਨ ਵਿੱਚ ਕੋਈ ਬੰਦ ਬਰੈਕਟ ਨਾ ਹੋਣ ਕਰਕੇ ਖੁੱਲੀ ਬਰੈਕਟ ਸੀ" -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "ਵਰਤੋਂ: %s\n" +#~ msgid "Coordinate expression doesn't seem to have any operators or operands" +#~ msgstr "ਕਰੋਆਡੀਨੇਟ ਐਕਸ਼ਪਰੈਸ਼ਨ ਵਿੱਚ ਕੋਈ ਵੀ ਆਪ੍ਰੇਟਰ ਜਾਂ ਪ੍ਰਭਾਵੀ ਅੰਕ ਨਹੀਂ ਦਿਸਦਾ" -#: ../src/ui/frames.c:1158 -msgid "Close Window" -msgstr "ਵਿੰਡੋ ਬੰਦ ਕਰੋ" +#~ msgid "Theme contained an expression that resulted in an error: %s\n" +#~ msgstr "ਥੀਮ ਵਿੱਚ ਸਮੀਕਰਨ ਹੈ, ਜਿਸ ਦਾ ਨਤੀਜਾ ਹੈ ਗਲਤੀ: %s\n" + +#~ msgid "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " +#~ "specified for this frame style" +#~ msgstr "" +#~ "ਇਸ ਫਰੇਮ ਵਾਸਤੇ <button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> " +#~ "ਦੇਣਾ ਲਾਜ਼ਮੀ ਹੈ" + +#~ msgid "" +#~ "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/" +#~ ">" +#~ msgstr "" +#~ "<frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/> ਗੁੰਮ ਹੈ" -#: ../src/ui/frames.c:1161 -msgid "Window Menu" -msgstr "ਵਿੰਡੋ ਮੇਨੂ" +#~ msgid "Failed to load theme \"%s\": %s\n" +#~ msgstr "ਥੀਮ \"%s\" ਲੋਡ ਕਰਨ ਲਈ ਅਸਫਲ: %s\n" -#: ../src/ui/frames.c:1164 -msgid "Minimize Window" -msgstr "ਵਿੰਡੋ ਘੱਟੋ-ਘੱਟ" +#~ msgid "No <%s> set for theme \"%s\"" +#~ msgstr "ਥੀਮ \"%2$s\" ਲਈ <%1$s> ਨਹੀਂ ਸੈੱਟ ਕੀਤਾ" -#: ../src/ui/frames.c:1167 -msgid "Maximize Window" -msgstr "ਵਿੰਡੋ ਵੱਧੋ-ਵੱਧ" +#~ msgid "" +#~ "No frame style set for window type \"%s\" in theme \"%s\", add a <window " +#~ "type=\"%s\" style_set=\"whatever\"/> element" +#~ msgstr "" +#~ "ਸ਼ੈਸ਼ਨ \"%s\" ਵਿੱਚ ਵਿੰਡੋ ਕਿਸਮ \"%s\" ਲਈ ਕੋਈ ਫਰੇਮ ਸਾਇਟਲ ਸੈੱਟ ਨਹੀਂ ਕੀਤਾ, ਇੱਕ <window " +#~ "type=\"%s\" style_set=\"whatever\"/> ਐਲੀਮੈਂਟ ਸ਼ਾਮਿਲ ਕਰੋ" -#: ../src/ui/frames.c:1170 -msgid "Restore Window" -msgstr "ਵਿੰਡੋ ਮੁੜ-ਸਟੋਰ" +#~ msgid "" +#~ "User-defined constants must begin with a capital letter; \"%s\" does not" +#~ msgstr "ਯੂਜ਼ਰ ਰਾਹੀਂ ਪਰਭਾਸ਼ਿਤ ਸਥਿਰ ਵੱਡੇ ਅੱਖਰ ਨਾਲ ਸ਼ੁਰੂ ਹੋਣ; \"%s\" ਨਹੀਂ ਹੁੰਦੇ" -#: ../src/ui/frames.c:1173 -msgid "Roll Up Window" -msgstr "ਵਿੰਡੋ ਸਮੇਟੋ" - -#: ../src/ui/frames.c:1176 -msgid "Unroll Window" -msgstr "ਵਿੰਡੋ ਫੈਲਾਓ" - -#: ../src/ui/frames.c:1179 -msgid "Keep Window On Top" -msgstr "ਵਿੰਡੋ ਉੱਤੇ ਰੱਖੋ" - -#: ../src/ui/frames.c:1182 -msgid "Remove Window From Top" -msgstr "ਵਿੰਡੋ ਉੱਤੇ ਤੋਂ ਹਟਾਓ" - -#: ../src/ui/frames.c:1185 -msgid "Always On Visible Workspace" -msgstr "ਹਮੇਸ਼ਾ ਉਪਲੱਬਧ ਵਰਕਸਪੇਸ 'ਚ" - -#: ../src/ui/frames.c:1188 -msgid "Put Window On Only One Workspace" -msgstr "ਵਿੰਡੋ ਨੂੰ ਸਿਰਫ਼ ਇੱਕ ਵਰਕਸਪੇਸ ਉੱਤੇ ਰੱਖੋ" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "ਘੱਟੋ-ਘੱਟੋ(_n)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "ਵੱਧੋ-ਵੱਧ(_x)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "ਨਾ-ਵੱਧੋ-ਵੱਧ(_x)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "ਸਮੇਟੋ(_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "ਖੋਲ੍ਹੋ(_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "ਏਧਰ-ਓਧਰ(_M)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "ਮੁੜ-ਅਕਾਰ(_R)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "ਟਾਇਟਲ ਸਕਰੀਨ ਉੱਤੇ ਭੇਜੋ(_s)" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "ਹਮੇਸ਼ਾ ਸਭ ਤੋਂ ਉੱਤੇ(_T)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "ਸਿਰਫ਼ ਇਸ ਵਰਕਸਪੇਸ ਵਿੱਚ ਰੱਖੋ(_A)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "ਸਿਰਫ਼ ਇਸ ਵਰਕਸਪੇਸ ਵਿੱਚ ਰੱਖੋ(_O)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "ਵਰਕਸਪੇਸ ਵਿੱਚ ਖੱਬੇ ਭੇਜੋ(_L)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "ਵਰਕਸਪੇਸ ਵਿੱਚ ਸੱਜੇ ਭੇਜੋ(_i)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "ਵਰਕਸਪੇਸ ਵਿੱਚ ਉੱਤੇ ਲੈ ਜਾਓ(_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "ਵਰਕਸਪੇਸ ਵਿੱਚ ਹੇਠਾਂ ਲੈ ਜਾਓ(_D)" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "ਬੰਦ ਕਰੋ(_C)" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "ਵਰਕਸਪੇਸ %d%n" +#~ msgid "Constant \"%s\" has already been defined" +#~ msgstr "ਸਥਿਰ \"%s\" ਪਹਿਲਾਂ ਹੀ ਪਰਭਾਸ਼ਿਤ ਕੀਤਾ ਹੈ" + +#~ msgid "No \"%s\" attribute on element <%s>" +#~ msgstr "<%2$s> ਐਲੀਮੈਂਟ ਉੱਤੇ ਕੋਈ \"%1$s\" ਗੁਣ ਨਹੀਂ" + +#~ msgid "Line %d character %d: %s" +#~ msgstr "ਲਾਈਨ %d ਅੱਖਰ %d:%s" + +#~ msgid "Attribute \"%s\" repeated twice on the same <%s> element" +#~ msgstr "ਗੁਣ \"%s\" ਇੱਕੋ ਐਲੀਮੈਂਟ <%s> ਉੱਤੇ ਦੋ ਵਾਰ ਦੁਹਰਾਇਆ ਗਿਆ" + +#~ msgid "Attribute \"%s\" is invalid on <%s> element in this context" +#~ msgstr "ਇਸ ਸਬੰਧ ਵਿਚਲਾ \"%s\" ਗੁਣ ਅਯੋਗ ਹੈ ਐਲੀਮੈਂਟ <%s> ਉੱਤੇ" + +#~ msgid "Could not parse \"%s\" as an integer" +#~ msgstr "\"%s\" ਦੀ ਪੂਰਨ ਅੰਕ ਵਾਂਗ ਪਾਰਸ ਨਹੀ ਕਰ ਸਕਿਆ" + +#~ msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +#~ msgstr "\"%s\" ਸਤਰ ਵਿਚ ਖੋਜੇ ਅੱਖਰ \"%s\" ਨੂੰ ਸਮਝ ਨਹੀ ਸਕੇ" + +#~ msgid "Integer %ld must be positive" +#~ msgstr "ਪੂਰਨ ਅੰਕ %ld ਜੋੜ ਦਾ ਹੋਣਾ ਜਰੂਰੀ ਹੈ" + +#~ msgid "Integer %ld is too large, current max is %d" +#~ msgstr "ਪੂਰਨ ਅੰਕ %ld ਬਹੁਤ ਵੱਡਾ ਹੈ, ਮੌਜੂਦਾ ਅਧਿਕਤਮ %d ਹੈ" + +#~ msgid "Could not parse \"%s\" as a floating point number" +#~ msgstr "\"%s\" ਦੀ ਦਸ਼ਮਲਵ ਅੰਕ ਵਾਂਗ ਪਾਰਸ ਨਹੀਂ ਕਰ ਸਕਿਆ" + +#~ msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" +#~ msgstr "ਬੂਲੀਅਨ ਕੀਮਤ \"ਠੀਕ\" ਜਾਂ \"ਗਲਤ\" ਹੋਵੇ \"%s\" ਨਹੀਂ" + +#~ msgid "Angle must be between 0.0 and 360.0, was %g\n" +#~ msgstr "ਕੋਣ 0.0 ਤੋਂ 360.0 ਵਿਚਕਾਰ ਹੋਵੇ, ਕੀ %g ਸੀ\n" + +#~ msgid "" +#~ "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" +#~ msgstr "ਐਲਫਾ 0.0 (ਅਦਿੱਖ) ਅਤੇ 1.0 (ਪੂਰੀ ਤਰਾਂ ਅਪਾਰਦਰਸ਼ੀ) ਵਿਚਕਾਰ ਹੋਵੇ, ਕੀ %g ਸੀ\n" + +#~ msgid "" +#~ "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," +#~ "large,x-large,xx-large)\n" +#~ msgstr "ਅਯੋਗ ਟਾਇਟਲ ਪੈਮਾਨਾ \"%s\" (xx-ਛੋਟਾ,x-ਛੋਟਾ,ਛੋਟਾ,ਮੱਧਮ,ਵੱਡਾ,x-ਵੱਡਾ,xx-ਵੱਡਾ)\n" + +#~ msgid "<%s> name \"%s\" used a second time" +#~ msgstr "<%s> ਨਾਂ \"%s\" ਦੂਜੀ ਵਾਰ ਵਰਤਿਆ ਗਿਆ" + +#~ msgid "<%s> parent \"%s\" has not been defined" +#~ msgstr "<%s> ਮੂਲ \"%s\" ਪਰਭਾਸ਼ਿਤ ਨਹੀਂ ਕੀਤਾ ਗਿਆ" + +#~ msgid "<%s> geometry \"%s\" has not been defined" +#~ msgstr "<%s> ਜੁਮੈਟਰੀ \"%s\" ਪਰਭਾਸ਼ਿਤ ਨਹੀਂ ਕੀਤੀ ਗਈ" + +#~ msgid "<%s> must specify either a geometry or a parent that has a geometry" +#~ msgstr "<%s> ਜੁਮੈਟਰੀ ਜਾਂ ਜੁਮੈਟਰੀ ਵਾਲੇ ਮੂਲ ਨੂੰ ਦੇਣਾ ਲਾਜ਼ਮੀ ਹੈ" + +#~ msgid "You must specify a background for an alpha value to be meaningful" +#~ msgstr "ਤੁਹਾਨੂੰ ਇੱਕ ਐਲਫ਼ਾ ਮੁੱਲ ਲਈ ਇੱਕ ਬੈਕਗਰਾਊਂਡ ਮੁੱਲ ਦਿਓ, ਜੋ ਕਿ ਮਤਲਬ ਸਿਰ ਹੋਵੇ" + +#~ msgid "Unknown type \"%s\" on <%s> element" +#~ msgstr "ਅਣਜਾਣ ਕਿਸਮ \"%s\" ਉੱਤੇ <%s> ਐਲੀਮੈਂਟ" + +#~ msgid "Unknown style_set \"%s\" on <%s> element" +#~ msgstr "ਅਣਜਾਣ ਸਟਾਇਲ_ਸੈੱਟ \"%s\" <%s> ਐਲੀਮੈਂਟ ਉੱਤੇ" + +#~ msgid "Window type \"%s\" has already been assigned a style set" +#~ msgstr "ਵਿੰਡੋ ਕਿਸਮ \"%s\" ਵਾਸਤੇ ਪਹਿਲਾਂ ਹੀ ਇੱਕ ਸਟਾਇਲ ਸੈੱਟ ਦਿੱਤਾ ਹੈ" + +#~ msgid "Element <%s> is not allowed below <%s>" +#~ msgstr "<%s> ਐਲੀਮੈਂਟ ਨੂੰ <%s> ਹੇਠਾਂ ਇਜਾਜ਼ਤ ਨਹੀਂ" + +#~ msgid "" +#~ "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio" +#~ "\" for buttons" +#~ msgstr "" +#~ "ਦੋਵੇਂ \"button_width (ਬਟਨ ਚੌੜਾਈ)\"/\"button_height (ਬਟਨ ਉਚਾਈ)\" ਅਤੇ " +#~ "\"aspect_ratio\" ਬਟਨਾਂ ਲਈ ਨਹੀਂ ਦਿੱਤੇ ਦੇ ਸਕਦੇ" -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "ਵਰਕਸਪੇਸ ੧_0" +#~ msgid "Distance \"%s\" is unknown" +#~ msgstr "ਫਾਸਲਾ \"%s\" ਅਣਜਾਣ ਹੈ" -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "ਵਰਕਸਪੇਸ %s%d" +#~ msgid "Aspect ratio \"%s\" is unknown" +#~ msgstr "ਅਕਾਰ ਅਨੁਪਾਤ \"%s\" ਅਣਜਾਣ ਹੈ" -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "ਹੋਰ ਵਰਕਸਪੇਸ ਉੱਤੇ ਭੇਜੋ(_W)" +#~ msgid "Border \"%s\" is unknown" +#~ msgstr "ਬਾਰਡਰ \"%s\" ਅਣਜਾਣ ਹੈ" -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "ਮਾਡ੨" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "ਮਾਡ੩" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "ਮਾਡ੪" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "ਮਾਡ੫" +#~ msgid "No \"start_angle\" or \"from\" attribute on element <%s>" +#~ msgstr "<%s> ਐਲੀਮੈਂਟ ਉੱਤੇ ਕੋਈ \"ਸ਼ੁਰੂ_ਕੋਣ\" ਜਾਂ \"ਇਸ ਤੋਂ\"ਗੁਣ ਨਹੀਂ ਹੈ ।" -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" +#~ msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" +#~ msgstr "<%s> ਐਲੀਮੈਂਟ ਉੱਤੇ ਕੋਈ \"ਸੀਮਾਂ_ਕੋਣ\" ਜਾਂ \"ਵੱਲ\" ਗੁਣ ਨਹੀਂ ਹੈ।" -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "ਉੱਤੇ" +#~ msgid "Did not understand value \"%s\" for type of gradient" +#~ msgstr "ਢਾਲ ਦੇ ਅਨੁਪਾਤ ਦੀ ਕਿਸਮ ਵਾਸਤੇ ਕੀਮਤ \"%s\" ਨਹੀਂ ਸਮਝਿਆ ਹੈ।" -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "ਹੇਠਾਂ" +#~ msgid "Did not understand fill type \"%s\" for <%s> element" +#~ msgstr "ਐਲੀਮੈਂਟ <%s> ਵਾਸਤੇ ਭਰਨ ਕਿਸਮ \"%s\" ਨਹੀਂ ਸਮਝਿਆ ਹੈ।" -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "ਖੱਬਾ" +#~ msgid "Did not understand state \"%s\" for <%s> element" +#~ msgstr "ਐਲੀਮੈਂਟ <%s> ਲਈ ਸਥਿਤੀ \"%s\" ਨਹੀਂ ਸਮਝਿਆ ਹੈ।" -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "ਸੱਜਾ" +#~ msgid "Did not understand shadow \"%s\" for <%s> element" +#~ msgstr "ਐਲੀਮੈਂਟ <%s> ਲਈ ਪਰਛਾਂਵਾਂ \"%s\" ਨਹੀਂ ਸਮਝਿਆ ਹੈ।" -#: ../src/ui/theme.c:286 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "ਫਰੇਮ ਜੁਮੈਟਰੀ \"%s\" ਮਾਪ ਨਹੀਂ ਦਰਸਾਉਦੀ ਹੈ" +#~ msgid "Did not understand arrow \"%s\" for <%s> element" +#~ msgstr "ਐਲੀਮੈਂਟ <%s> ਲਈ ਤੀਰ \"%s\" ਨਹੀਂ ਸਮਝਿਆ ਹੈ।" -#: ../src/ui/theme.c:305 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "ਫਰੇਮ ਜੁਮੈਟਰੀ \"%2$s\" ਹਾਸ਼ੀਏ ਲਈ \"%1$s\" ਮਾਪ ਨਹੀਂ ਦਰਸਾਉਦੀ ਹੈ" +#~ msgid "No <draw_ops> called \"%s\" has been defined" +#~ msgstr "ਕੋਈ <draw_ops> \"%s\" ਪਰਭਾਸ਼ਿਤ ਨਹੀਂ ਕੀਤੀ ਹੈ।" -#: ../src/ui/theme.c:342 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "ਤਲ ਆਕਾਰ ਅਨੁਪਾਤ %g ਢੁੱਕਵਾਂ ਨਹੀਂ ਹੈ" +#~ msgid "Including draw_ops \"%s\" here would create a circular reference" +#~ msgstr "draw_ops ਦੇ ਨਾਲ \"%s\" ਇੱਥੇ ਗੋਲਾਕਾਰ ਸੰਬੰਧ ਬਣਾਏਗਾ ਹੈ।" -#: ../src/ui/theme.c:354 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "ਫਰੇਮ ਜੁਮੈਟਰੀ ਬਟਨਾਂ ਦਾ ਆਕਾਰ ਨਹੀਂ ਦਰਸਾਉਦੀ" +#~ msgid "Unknown position \"%s\" for frame piece" +#~ msgstr "ਫਰੇਮ ਟੁਕੜੇ ਲਈ ਅਣਜਾਣੀ ਸਥਿਤੀ \"%s\" ਹੈ।" -#: ../src/ui/theme.c:1067 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "ਢਾਲਵੇ ਲਈ ਘੱਟ ਤੋਂ ਘੱਟ ਦੋ ਰੰਗ ਚਾਹੀਦੇ ਹਨ" +#~ msgid "Frame style already has a piece at position %s" +#~ msgstr "ਫਰੇਮ ਸਟਾਇਲ ਵਿੱਚ ਪਹਿਲਾਂ ਹੀ %s ਸਥਿਤੀ ਉੱਤੇ ਇੱਕ ਟੁਕੜਾ ਹੈ।" -#: ../src/ui/theme.c:1219 -#, c-format -msgid "" -"GTK custom color specification must have color name and fallback in " -"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" -msgstr "" -"ਹਾਲਤ ਤੋਂ ਬਾਅਦ GTK ਰੰਗ ਹਦਾਇਤ ਬਰੈਕਟਾਂ ਵਿੱਚ ਬੰਦ ਕਰਨੀ ਜ਼ਰੂਰੀ ਹੈ, ਉਦਾਹਰਨ ਵਜੋਂ " -"gtk:custom (foo," -"bar); \"%s\" ਦੀ ਪਾਰਸ ਨਹੀਂ ਕਰ ਸਕਿਆ" +#~ msgid "No <draw_ops> with the name \"%s\" has been defined" +#~ msgstr "\"%s\" ਨਾਂ ਨਾਲ <draw_ops> ਪਰਭਾਸ਼ਿਤ ਨਹੀਂ ਕੀਤੀਆਂ" -#: ../src/ui/theme.c:1235 -#, c-format -msgid "" -"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" -"_ are valid" -msgstr "" -"gtk:custom ਦੇ color_name ਪੈਰਾਮੀਟਰ ਵਿੱਚ ਗਲਤ ਅੱਖਰ '%c' ਹੈ, ਕੇਵਲ A-Za-z0-9-_ " -"ਸ਼ਾਮਲ ਹੋ " -"ਸਕਦੇ ਹਨ" +#~ msgid "Unknown function \"%s\" for button" +#~ msgstr "ਬਟਨ ਲਈ ਅਣਜਾਣ ਕੰਮ \"%s\" ਹੈ।" -#: ../src/ui/theme.c:1249 -#, c-format -msgid "" -"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " -"fit the format" -msgstr "" -"Gtk:custom ਫਾਰਮੈਟ \"gtk:custom(color_name,fallback)\" ਹੈ, \"%s\" ਫਾਰਮੈਟ ਵਿੱਚ " -"ਫਿੱਟ " -"ਨਹੀਂ ਹੈ" +#~ msgid "Button function \"%s\" does not exist in this version (%d, need %d)" +#~ msgstr "ਬਟਨ ਫੰਕਸ਼ਨ \"%s\" ਇਹ ਵਰਜਨ 'ਚ ਮੌਜੂਦ ਨਹੀਂ ਹੈ (%d, %d ਲੋੜੀਦਾ ਹੈ)" -#: ../src/ui/theme.c:1294 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"GTK ਰੰਗ ਹਦਾਇਤਾਂ ਦੀ ਹਾਲਤ ਬਰੈਕਟਾਂ ਵਿੱਚ ਜਰੂਰੀ ਹੈ, ਉਦਾਹਰਨ ਵਜੋਂ gtk:fg[ਸਾਧਾਰਨ] " -"ਜਿੱਥੇ ਸਾਧਾਰਨ " -"ਇੱਕ ਹਾਲਤ ਹੈ; \"%s\" ਦੀ ਪਾਰਸ ਨਹੀਂ ਕਰ ਸਕਿਆ" +#~ msgid "Unknown state \"%s\" for button" +#~ msgstr "ਬਟਨ ਲਈ ਅਣਜਾਣ ਹਾਲਤ \"%s\" ਹੈ।" -#: ../src/ui/theme.c:1308 -#, c-format -msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"ਹਾਲਤ ਤੋਂ ਬਾਅਦ GTK ਰੰਗ ਹਦਾਇਤ ਬਰੈਕਟਾਂ ਵਿੱਚ ਬੰਦ ਕਰਨੀ ਜ਼ਰੂਰੀ ਹੈ, ਉਦਾਹਰਨ ਵਜੋਂ " -"gtk:fg[ਸਾਧਾਰਨ] " -"ਜਿੱਥੇ ਸਾਧਾਰਨ ਇੱਕ ਹਾਲਤ ਹੈ; \"%s\" ਦੀ ਪਾਰਸ ਨਹੀਂ ਕਰ ਸਕਿਆ" +#~ msgid "Frame style already has a button for function %s state %s" +#~ msgstr "ਫਰੇਮ ਸਟਾਇਲ ਵਿੱਚ ਪਹਿਲਾਂ ਹੀ ਕੰਮ %s ਹਾਲਤ %s ਬਟਨ ਹੈ।" -#: ../src/ui/theme.c:1319 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "ਰੰਗ ਹਦਾਇਤ ਵਿੱਚ \"%s\" ਹਾਲਤ ਨੂੰ ਨਹੀਂ ਸਮਝਿਆ" +#~ msgid "\"%s\" is not a valid value for focus attribute" +#~ msgstr "ਫੋਕਸ ਗੁਣ ਲਈ \"%s\" ਯੋਗ ਕੀਮਤ ਨਹੀਂ ਹੈ।" -#: ../src/ui/theme.c:1332 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "ਰੰਗ ਹਦਾਇਤ ਵਿੱਚ ਰੰਗ ਸੰਖੇਪ \"%s\" ਨੂੰ ਨਹੀਂ ਸਮਝਿਆ" +#~ msgid "\"%s\" is not a valid value for state attribute" +#~ msgstr "ਹਾਲਤ ਗੁਣ ਲਈ \"%s\" ਯੋਗ ਕੀਮਤ ਨਹੀਂ ਹੈ।" -#: ../src/ui/theme.c:1361 -#, c-format -msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" -msgstr "ਧੁੰਦਲੀ ਬਣਤਰ \"ਧੁੰਦਲੀ/bg_ਰੰਗ/ਐਲਫਾ, \"%s\" ਬਣਤਰ ਵਿੱਚ ਠੀਕ ਨਹੀਂ ਆਂਉਦੀ" +#~ msgid "A style called \"%s\" has not been defined" +#~ msgstr "ਇੱਕ ਸਟਾਇਲ \"%s\" ਪਰਭਾਸ਼ਿਤ ਨਹੀਂ ਕੀਤਾ ਹੈ।" -#: ../src/ui/theme.c:1372 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "ਧੁੰਦਲੇ ਰੰਗ ਵਿੱਚ ਐਲਫਾ ਕੀਮਤ \"%s\" ਦੀ ਪਾਰਸ ਨਹੀਂ ਕਰ ਸਕਿਆ" +#~ msgid "\"%s\" is not a valid value for resize attribute" +#~ msgstr "ਮੁੜ ਆਕਾਰ ਦਿਓ ਗੁਣ ਲਈ \"%s\" ਯੋਗ ਕੀਮਤ ਨਹੀਂ ਹੈ।" -#: ../src/ui/theme.c:1382 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "ਧੁੰਦਲੇ ਰੰਗ ਵਿੱਚ ਐਲਫਾ ਕੀਮਤ \"%s\" 0.0 ਅਤੇ 1.0 ਵਿਚਕਾਰ ਨਹੀਂ ਹੈ" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized/shaded " +#~ "states" +#~ msgstr "<%s> ਐਲੀਮੈਂਟ ਉੱਤੇ ਵੱਡਾ/ਰੰਗਤ ਹਾਲਤ ਲਈ \"ਮੁੜ ਆਕਾਰ ਦਿਓ\" ਗੁਣ ਨਹੀਂ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ।" -#: ../src/ui/theme.c:1429 -#, c-format -msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "ਰੰਗਤ ਬਣਤਰ \"ਰੰਗਤ/ਆਧਾਰ_ਰੰਗ/ਫੈਕਟਰ\" ਹੈ, \"%s\" ਬਣਤਰ ਵਿੱਚ ਠੀਕ ਨਹੀਂ ਆਉਦੀ" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized states" +#~ msgstr "<%s> ਐਲੀਮੈਂਟ ਲਈ ਵੱਧ ਤੋਂ ਵੱਧ ਹਾਲਤਾਂ ਲਈ \"ਮੁੜ ਆਕਾਰ\" ਗੁਣ ਨਹੀਂ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ।" -#: ../src/ui/theme.c:1440 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "ਛਾਇਆ ਰੰਗ ਵਿੱਚ ਰੰਗਤ ਫੈਕਟਰ \"%s\" ਦੀ ਪਾਰਸ ਨਹੀਂ ਕਰ ਸਕਿਆ" +#~ msgid "Style has already been specified for state %s resize %s focus %s" +#~ msgstr "ਹਾਲਤ %s ਮੁੜ ਅਕਾਰ ਦਿਓ %s ਫੋਕਸ %s ਬਾਰੇ ਸਟਾਇਲ ਪਹਿਲਾਂ ਦਿੱਤਾ ਗਿਆ ਹੈ" -#: ../src/ui/theme.c:1450 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "ਛਾਇਆ ਰੰਗ ਵਿੱਚ ਰੰਗਤ ਫੈਕਟਰ \"%s\" ਨਾਂਹਵਾਚਕ ਹੈ" +#~ msgid "Style has already been specified for state %s focus %s" +#~ msgstr "ਹਾਲਤ %s ਫੋਕਸ %s ਬਾਰੇ ਸਟਾਇਲ ਪਹਿਲਾਂ ਦਿੱਤਾ ਹੈ" -#: ../src/ui/theme.c:1479 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "\"%s\" ਰੰਗ ਦੀ ਪਾਰਸ ਨਹੀਂ ਕਰ ਸਕਿਆ" +#~ msgid "" +#~ "Can't have a two draw_ops for a <piece> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "<piece> ਐਲੀਮੈਂਟ ਵਾਸਤੇ ਦੋ draw_ops ਨਹੀਂ ਹੋ ਸਕਦੀਆਂ (ਥੀਮ ਨੇ draw_ops ਗੁਣ ਅਤੇ " +#~ "<draw_ops> ਐਲੀਮੈਂਟ ਵੀ ਹੋ ਸਕਦੀ ਹੈ ਜਾਂ ਦੋ ਐਲੀਮੈਂਟ ਦਿੱਤੀਆਂ ਹੋ ਸਕਦੀਆਂ ਹਨ)" -#: ../src/ui/theme.c:1790 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "ਕਰੋਆਡੀਨੇਟ ਐਕਸ਼ਪਰੈਸ਼ਨ ਵਿੱਚ ਅੱਖਰ '%s' ਸ਼ਾਮਿਲ ਹੈ ਜਿਸ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ" +#~ msgid "" +#~ "Can't have a two draw_ops for a <button> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "<button> ਐਲੀਮੈਂਟ ਵਾਸਤੇ ਦੋ draw_ops ਨਹੀਂ ਹੋ ਸਕਦੀਆਂ(ਥੀਮ ਨੇ ਉਲੀਕ ਚੋਣਾਂ ਗੁਣ ਅਤੇ " +#~ "<draw_ops> ਐਲੀਮੈਂਟ ਵੀ ਦਿੱਤਾ ਹੈ, ਜਾਂ ਦੋ ਐਲੀਮੈਂਟ ਦਿੱਤੇ ਹਨ)" -#: ../src/ui/theme.c:1817 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "" -"ਕਰੋਆਡੀਨੇਟ ਐਕਸ਼ਪਰੈਸ਼ਨ ਵਿੱਚ ਦਸ਼ਮਲਵ ਅੰਕ '%s' ਸ਼ਾਮਿਲ ਹੈ ਜਿਸ ਦੀ ਪਾਰਸ ਨਹੀਂ ਕੀਤੀ ਜਾ " -"ਸਕਦੀ" +#~ msgid "" +#~ "Can't have a two draw_ops for a <menu_icon> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "ਇੱਕ ਐਲੀਮੈਂਟ ਵਾਸਤੇ <menu_icon> draw_ops ਨਹੀਂ ਹੋ ਸਕਦੀਆਂ (ਥੀਮ ਨੇ draw_ops ਗੁਣ ਅਤੇ " +#~ "<draw_ops> ਇਕਾਈਆਂ ਦਿੱਤੀਆਂ ਹਨ, ਜਾਂ ਦੋ ਇਕਾਈਆਂ ਦਿੱਤੀਆਂ ਹਨ)" -#: ../src/ui/theme.c:1831 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "" -"ਕਰੋਆਡੀਨੇਟ ਐਕਸ਼ਪਰੈਸ਼ਨ ਵਿੱਚ ਪੂਰਨ ਅੰਕ '%s' ਸ਼ਾਮਿਲ ਹੈ ਜਿਸ ਦੀ ਪਾਰਸ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ" +#~ msgid "Bad version specification '%s'" +#~ msgstr "ਗਲਤ ਵਰਜਨ ਹਦਾਇਤਾਂ '%s'" -#: ../src/ui/theme.c:1953 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "" -"ਕਰੋਆਡੀਨੇਟ ਐਕਸ਼ਪਰੈਸ਼ਨ ਵਿੱਚ ਇਸ ਪਾਠ \"%s\" ਦੇ ਸ਼ੁਰੂ ਵਿੱਚ ਅਣਪਛਾਤਾ ਆਪ੍ਰੇਟਰ ਸ਼ਾਮਿਲ ਹੈ" +#~ msgid "" +#~ "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" +#~ "theme-2.xml" +#~ msgstr "" +#~ "\"version\" ਗੁਣ metacity-theme-1.xml ਜਾਂ metacity-theme-2.xml ਵਿੱਚ ਵਰਤਿਆ ਨਹੀਂ " +#~ "ਜਾ ਸਕਦਾ" -#: ../src/ui/theme.c:2010 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "ਕਰੋਆਡੀਨੇਟ ਐਕਸ਼ਪਰੈਸ਼ਨ ਖਾਲੀ ਸੀ ਜਾਂ ਸਮਝਿਆ ਨਹੀਂ" +#~ msgid "" +#~ "Theme requires version %s but latest supported theme version is %d.%d" +#~ msgstr "ਥੀਮ ਲਈ %s ਵਰਜਨ ਚਾਹੀਦਾ ਹੈ, ਪਰ ਸਭ ਤੋਂ ਨਵਾਂ ਸਹਾਇਕ ਥੀਮ ਵਰਜਨ ਹੈ %d.%d" -#: ../src/ui/theme.c:2121 ../src/ui/theme.c:2131 ../src/ui/theme.c:2165 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "ਕਰੋਆਡੀਨੇਟ ਐਕਸ਼ਪਰੈਸ਼ਨ ਦੇ ਨਤੀਜੇ ਵਜੋਂ ਜੀਰੋ ਨਾਲ ਭਾਗ ਹੈ" +#~ msgid "Outermost element in theme must be <metacity_theme> not <%s>" +#~ msgstr "ਥੀਮ ਵਿੱਚ ਸਭ ਤੋਂ ਬਾਹਰੀ ਐਲੀਮੈਂਟ <metacity_theme> ਹੋਵੇ <%s> ਨਹੀਂ" -#: ../src/ui/theme.c:2173 -#, c-format -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "" -"ਕਰੋਆਡੀਨੇਟ ਐਕਸ਼ਪਰੈਸ਼ਨ ਦਸ਼ਮਲਵ ਅੰਕ ਉੱਤੇ ਮਾਡ (mod) ਆਪ੍ਰੇਟਰ ਵਰਤਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰਦਾ ਹੈ" +#~ msgid "" +#~ "Element <%s> is not allowed inside a name/author/date/description element" +#~ msgstr "<%s> ਐਲੀਮੈਂਟ ਨੂੰ ਨਾਂ/ਲੇਖਕ/ਮਿਤੀ/ਵੇਰਵਾ ਐਲੀਮੈਂਟ ਵਿੱਚ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ" -#: ../src/ui/theme.c:2229 -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "" -"ਕਰੋਆਡੀਨੇਟ ਐਕਸ਼ਪਰੈਸ਼ਨ ਵਿੱਚ ਆਪ੍ਰੇਟਰ \"%s\" ਹੈ ਜਿੱਥੇ ਪ੍ਰਭਾਵੀ ਅੰਕ ਦੀ ਉਮੀਦ ਸੀ" +#~ msgid "Element <%s> is not allowed inside a <constant> element" +#~ msgstr "<%s> ਐਲੀਮੈਂਟ ਨੂੰ <constant> ਐਲੀਮੈਂਟ ਵਿੱਚ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ" -#: ../src/ui/theme.c:2238 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "ਕਰੋਆਡੀਨੇਟ ਐਕਸ਼ਪਰੈਸ਼ਨ ਵਿੱਚ ਪ੍ਰਭਾਵੀ ਅੰਕ ਸੀ ਜਿੱਥੇ ਆਪ੍ਰੇਟਰ ਦੀ ਉਮੀਦ ਸੀ" +#~ msgid "" +#~ "Element <%s> is not allowed inside a distance/border/aspect_ratio element" +#~ msgstr "" +#~ "<%s> ਐਲੀਮੈਂਟ ਨੂੰ ਫਾਸਲਾ/ਹਾਸ਼ੀਆ/ਅਕਾਰ ਅਨੁਪਾਤ(aspect_ratio) ਐਲੀਮੈਂਟ ਵਿੱਚ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ" -#: ../src/ui/theme.c:2246 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "" -"ਕਰੋਆਡੀਨੇਟ ਐਕਸ਼ਪਰੈਸ਼ਨ ਦੀ ਸਮਾਪਤੀ ਆਪ੍ਰੇਟਰ ਨਾਲ ਹੁੰਦੀ ਹੈ ਨਾ ਕਿ ਪ੍ਰਭਾਵੀ ਅੰਕ ਨਾਲ" +#~ msgid "Element <%s> is not allowed inside a draw operation element" +#~ msgstr "<%s> ਐਲੀਮੈਂਟ ਨੂੰ ਉਲੀਕ ਕਿਰਿਆ ਐਲੀਮੈਂਟ ਵਿੱਚ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ" -#: ../src/ui/theme.c:2256 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" -"ਕਰੋਆਡੀਨੇਟ ਐਕਸ਼ਪਰੈਸ਼ਨ ਵਿੱਚ ਵਿਚਕਾਰ ਪ੍ਰਭਾਵੀ ਅੰਕ ਤੋਂ ਬਿਨਾਂ ਆਪ੍ਰੇਟਰ \"%c\" ਤੋਂ " -"ਬਾਅਦ ਆਪ੍ਰੇਟਰ \"%c" -"\" ਹੈ " +#~ msgid "Element <%s> is not allowed inside a <%s> element" +#~ msgstr "<%s> ਐਲੀਮੈਂਟ ਨੂੰ <%s> ਐਲੀਮੈਂਟ ਵਿੱਚ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ" -#: ../src/ui/theme.c:2407 ../src/ui/theme.c:2452 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "ਕਰੋਆਡੀਨੇਟ ਐਕਸ਼ਪਰੈਸ਼ਨ ਵਿੱਚ ਅਣਪਛਾਤਾ ਅਸਥਿਰ ਜਾਂ ਸਥਿਰ \"%s\" ਸੀ" +#~ msgid "No draw_ops provided for frame piece" +#~ msgstr "ਫਰੇਮ ਟੁਕੜੇ ਲਈ ਕੋਈ draw_ops ਨਹੀਂ ਦਿੱਤੀ ਗਈ" -#: ../src/ui/theme.c:2506 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "ਕਰੋਆਡੀਨੇਟ ਐਕਸ਼ਪਰੈਸ਼ਨ ਪਾਰਸਰ ਦਾ ਬਫ਼ਰ ਓਵਰਫਲੋ ਹੋ ਗਿਆ ਹੈ।" +#~ msgid "No draw_ops provided for button" +#~ msgstr "ਬਟਨ ਲਈ ਕੋਈ ਉਲੀਕ ਕਿਰਿਆ ਨਹੀ ਦਿੱਤੀ ਗਈ" -#: ../src/ui/theme.c:2535 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "" -"ਕਰੋਆਡੀਨੇਟ ਐਕਸ਼ਪਰੈਸ਼ਨ ਵਿੱਚ ਕੋਈ ਖੁੱਲੀ ਬਰੈਕਟ ਨਾ ਹੋਣ ਕਰਕੇ ਬੰਦ ਬਰੈਕਟ(parenthesis) " -"ਸੀ" +#~ msgid "No text is allowed inside element <%s>" +#~ msgstr "<%s> ਐਲੀਮੈਂਟ ਵਿੱਚ ਕਿਸੇ ਪਾਠ ਨੂੰ ਇਜਾਜ਼ਤ ਨਹੀਂ" -#: ../src/ui/theme.c:2599 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "ਕਰੋਆਡੀਨੇਟ ਐਕਸ਼ਪਰੈਸ਼ਨ ਵਿੱਚ ਕੋਈ ਬੰਦ ਬਰੈਕਟ ਨਾ ਹੋਣ ਕਰਕੇ ਖੁੱਲੀ ਬਰੈਕਟ ਸੀ" +#~ msgid "<%s> specified twice for this theme" +#~ msgstr "ਇਸ ਥੀਮ ਲਈ <%s> ਦੋ ਵਾਰ ਦਿੱਤਾ ਗਿਆ" -#: ../src/ui/theme.c:2610 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "ਕਰੋਆਡੀਨੇਟ ਐਕਸ਼ਪਰੈਸ਼ਨ ਵਿੱਚ ਕੋਈ ਵੀ ਆਪ੍ਰੇਟਰ ਜਾਂ ਪ੍ਰਭਾਵੀ ਅੰਕ ਨਹੀਂ ਦਿਸਦਾ" +#~ msgid "Failed to find a valid file for theme %s\n" +#~ msgstr "ਥੀਮ %s ਲਈ ਇੱਕ ਢੁੱਕਵੀਂ ਫਾਇਲ ਲੱਭਣ ਲਈ ਫੇਲ੍ਹ\n" -#: ../src/ui/theme.c:2822 ../src/ui/theme.c:2842 ../src/ui/theme.c:2862 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "ਥੀਮ ਵਿੱਚ ਸਮੀਕਰਨ ਹੈ, ਜਿਸ ਦਾ ਨਤੀਜਾ ਹੈ ਗਲਤੀ: %s\n" +#~ msgid "background texture could not be created from file" +#~ msgstr "ਬੈਕਗਰਾਊਂਡ ਟੈਕਸਚਰ ਨੂੰ ਫਾਇਲ ਤੋਂ ਨਹੀਂ ਬਣਾਇਆ ਜਾ ਸਕਿਆ" -#: ../src/ui/theme.c:4533 -#, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" -"ਇਸ ਫਰੇਮ ਵਾਸਤੇ <button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> " -"ਦੇਣਾ " -"ਲਾਜ਼ਮੀ ਹੈ" +#~ msgid "Unknown window information request: %d" +#~ msgstr "ਅਣਜਾਣ ਵਿੰਡੋ ਜਾਣਕਾਰੀ ਮੰਗ: %d" -#: ../src/ui/theme.c:5066 ../src/ui/theme.c:5091 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" -"<frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/> ਗੁੰਮ ਹੈ" +#~ msgid "Missing %s extension required for compositing" +#~ msgstr "ਕੰਪੋਜ਼ਿਸ਼ਨਿੰਗ ਲਈ %s ਐਕਸਟੈਨਸ਼ਨ ਗੁੰਮ ਹੈ" -#: ../src/ui/theme.c:5139 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "ਥੀਮ \"%s\" ਲੋਡ ਕਰਨ ਲਈ ਅਸਫਲ: %s\n" +#~ msgid "" +#~ "Some other program is already using the key %s with modifiers %x as a " +#~ "binding\n" +#~ msgstr "ਕੋਈ ਹੋਰ ਪਰੋਗਰਾਮ %s ਸਵਿੱਚ ਨੂੰ %x ਸੋਧਕ ਨਾਲ ਪਹਿਲਾਂ ਹੀ ਜੋੜ ਵਾਂਗ ਵਰਤ ਰਿਹਾ ਹੈ\n" -#: ../src/ui/theme.c:5275 ../src/ui/theme.c:5282 ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 ../src/ui/theme.c:5303 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "ਥੀਮ \"%2$s\" ਲਈ <%1$s> ਨਹੀਂ ਸੈੱਟ ਕੀਤਾ" +#~ msgid "\"%s\" is not a valid accelerator\n" +#~ msgstr "\"%s\" ਢੁੱਕਵਾਂ ਐਕਸਲੇਟਰ ਨਹੀਂ ਹੈ\n" -#: ../src/ui/theme.c:5311 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" -"ਸ਼ੈਸ਼ਨ \"%s\" ਵਿੱਚ ਵਿੰਡੋ ਕਿਸਮ \"%s\" ਲਈ ਕੋਈ ਫਰੇਮ ਸਾਇਟਲ ਸੈੱਟ ਨਹੀਂ ਕੀਤਾ, ਇੱਕ <" -"window type=" -"\"%s\" style_set=\"whatever\"/> ਐਲੀਮੈਂਟ ਸ਼ਾਮਿਲ ਕਰੋ" +#~ msgid "" +#~ "Workarounds for broken applications disabled. Some applications may not " +#~ "behave properly.\n" +#~ msgstr "" +#~ "ਖਰਾਬ ਐਪਲੀਕੇਸ਼ਨ ਲਈ ਜੁਗਾੜ ਬੰਦ ਕੀਤਾ ਹੈ। ਕੁਝ ਐਪਲੀਕੇਸ਼ਨ ਚੰਗੀ ਤਰਾਂ ਕੰਮ ਨਹੀਂ ਕਰ ਸਕਦੇ ਹਨ।\n" -#: ../src/ui/theme.c:5709 ../src/ui/theme.c:5771 ../src/ui/theme.c:5834 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "ਯੂਜ਼ਰ ਰਾਹੀਂ ਪਰਭਾਸ਼ਿਤ ਸਥਿਰ ਵੱਡੇ ਅੱਖਰ ਨਾਲ ਸ਼ੁਰੂ ਹੋਣ; \"%s\" ਨਹੀਂ ਹੁੰਦੇ" +#~ msgid "Could not parse font description \"%s\" from GSettings key %s\n" +#~ msgstr "GSettings ਸਵਿੱਚ \"%2$s\" ਤੋਂ ਫੋਂਟ ਵੇਰਵੇ \"%1$s\" ਨੂੰ ਪਾਰਸ ਨਹੀਂ ਕਰ ਸਕਿਆ\n" -#: ../src/ui/theme.c:5717 ../src/ui/theme.c:5779 ../src/ui/theme.c:5842 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "ਸਥਿਰ \"%s\" ਪਹਿਲਾਂ ਹੀ ਪਰਭਾਸ਼ਿਤ ਕੀਤਾ ਹੈ" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" +#~ msgstr "ਸੰਰਚਨਾ ਡਾਟਾਬੇਸ ਵਿੱਚ ਲੱਭੀ ਹੋਈ \"%s\" ਮਾਊਸ ਬਟਨ ਸੋਧਕ ਲਈ ਯੋਗ ਕੀਮਤ ਨਹੀਂ ਹੈ\n" -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. -#. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "<%2$s> ਐਲੀਮੈਂਟ ਉੱਤੇ ਕੋਈ \"%1$s\" ਗੁਣ ਨਹੀਂ" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for " +#~ "keybinding \"%s\"\n" +#~ msgstr "" +#~ "ਸੰਰਚਨਾ ਡਾਟਾਬੇਸ ਵਿੱਚ ਲੱਭੀ ਹੋਈ \"%s\" ਸਵਿੱਚ-ਬਾਈਡਿੰਗ \"%s\" ਲਈ ਯੋਗ ਕੀਮਤ ਨਹੀਂ ਹੈ\n" -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "ਲਾਈਨ %d ਅੱਖਰ %d:%s" +#~ msgid "" +#~ "Could not acquire window manager selection on screen %d display \"%s\"\n" +#~ msgstr "ਡਿਸਪਲੇਅ \"%2$s\" %1$d ਸਕਰੀਨ ਉੱਤੇ ਵਿੰਡੋ ਮੈਨੇਜਰ ਚੋਣ ਉਪਲੱਬਧ ਨਹੀਂ ਹੋ ਸਕੀ\n" -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "ਗੁਣ \"%s\" ਇੱਕੋ ਐਲੀਮੈਂਟ <%s> ਉੱਤੇ ਦੋ ਵਾਰ ਦੁਹਰਾਇਆ ਗਿਆ" +#~ msgid "Could not release screen %d on display \"%s\"\n" +#~ msgstr "ਡਿਸਪਲੇਅ \"%2$s\" ਉੱਤੇ ਸਕਰੀਨ %1$d ਰੀਲਿਜ਼ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ\n" -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "ਇਸ ਸਬੰਧ ਵਿਚਲਾ \"%s\" ਗੁਣ ਅਯੋਗ ਹੈ ਐਲੀਮੈਂਟ <%s> ਉੱਤੇ" +#~ msgid "Could not create directory '%s': %s\n" +#~ msgstr "'%s' ਡਾਇਰੈਕਟਰੀ ਬਣਾਈ ਨਹੀਂ ਜਾ ਸਕੀ:%s\n" -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "\"%s\" ਦੀ ਪੂਰਨ ਅੰਕ ਵਾਂਗ ਪਾਰਸ ਨਹੀ ਕਰ ਸਕਿਆ" +#~ msgid "Could not open session file '%s' for writing: %s\n" +#~ msgstr "ਲਿਖਣ ਲਈ ਸ਼ੈਸ਼ਨ ਫਾਇਲ '%s' ਖੋਲ੍ਹੀ ਨਹੀਂ ਜਾ ਸਕੀ: %s\n" -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "\"%s\" ਸਤਰ ਵਿਚ ਖੋਜੇ ਅੱਖਰ \"%s\" ਨੂੰ ਸਮਝ ਨਹੀ ਸਕੇ" +#~ msgid "Error writing session file '%s': %s\n" +#~ msgstr "ਸ਼ੈਸ਼ਨ ਫਾਇਲ '%s' ਲਿਖਣ ਦੀ ਗਲਤੀ:%s\n" -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "ਪੂਰਨ ਅੰਕ %ld ਜੋੜ ਦਾ ਹੋਣਾ ਜਰੂਰੀ ਹੈ" +#~ msgid "Error closing session file '%s': %s\n" +#~ msgstr "ਸ਼ੈਸ਼ਨ ਫਾਇਲ '%s' ਖੋਲ੍ਹਣ ਦੀ ਗਲਤੀ: %s\n" -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "ਪੂਰਨ ਅੰਕ %ld ਬਹੁਤ ਵੱਡਾ ਹੈ, ਮੌਜੂਦਾ ਅਧਿਕਤਮ %d ਹੈ" +#~ msgid "Failed to parse saved session file: %s\n" +#~ msgstr "ਸੰਭਾਲੀ ਸ਼ੈਸ਼ਨ ਫਾਇਲ ਨੂੰ ਪਾਰਸ ਕਰਨ ਲਈ ਅਸਫਲ: %s\n" -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "\"%s\" ਦੀ ਦਸ਼ਮਲਵ ਅੰਕ ਵਾਂਗ ਪਾਰਸ ਨਹੀਂ ਕਰ ਸਕਿਆ" +#~ msgid "<mutter_session> attribute seen but we already have the session ID" +#~ msgstr "<mutter_session> ਗੁਣ ਦਿਖਿਆ, ਪਰ ਸਾਡੇ ਕੋਲ ਸ਼ੈਸ਼ਨ ID ਪਹਿਲਾਂ ਹੀ ਹੈ" -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "ਬੂਲੀਅਨ ਕੀਮਤ \"ਠੀਕ\" ਜਾਂ \"ਗਲਤ\" ਹੋਵੇ \"%s\" ਨਹੀਂ" +#~ msgid "Unknown attribute %s on <%s> element" +#~ msgstr "<%2$s> ਐਲੀਮੈਂਟ ਉੱਤੇ ਅਣਜਾਣ %1$s ਗੁਣ" -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "ਕੋਣ 0.0 ਤੋਂ 360.0 ਵਿਚਕਾਰ ਹੋਵੇ, ਕੀ %g ਸੀ\n" +#~ msgid "nested <window> tag" +#~ msgstr "ਨੈਸਟਡ <window> ਟੈਗ" -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "ਐਲਫਾ 0.0 (ਅਦਿੱਖ) ਅਤੇ 1.0 (ਪੂਰੀ ਤਰਾਂ ਅਪਾਰਦਰਸ਼ੀ) ਵਿਚਕਾਰ ਹੋਵੇ, ਕੀ %g ਸੀ\n" +#~ msgid "Unknown element %s" +#~ msgstr "ਅਣਜਾਣ ਐਲੀਮੈਂਟ %s" -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"ਅਯੋਗ ਟਾਇਟਲ ਪੈਮਾਨਾ \"%s\" (xx-ਛੋਟਾ,x-ਛੋਟਾ,ਛੋਟਾ,ਮੱਧਮ,ਵੱਡਾ,x-ਵੱਡਾ,xx-ਵੱਡਾ)\n" +#~ msgid "Failed to open debug log: %s\n" +#~ msgstr "ਡੀਬੱਗ ਲਾਗ ਖੋਲ੍ਹਣ ਵਿੱਚ ਅਸਫਲ: %s\n" -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s> ਨਾਂ \"%s\" ਦੂਜੀ ਵਾਰ ਵਰਤਿਆ ਗਿਆ" +#~ msgid "Failed to fdopen() log file %s: %s\n" +#~ msgstr "ਲਾਗ ਫਾਇਲ %s ਨੂੰ fdopen() ਲਈ ਅਸਫਲ: %s\n" -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "<%s> ਮੂਲ \"%s\" ਪਰਭਾਸ਼ਿਤ ਨਹੀਂ ਕੀਤਾ ਗਿਆ" +#~ msgid "Opened log file %s\n" +#~ msgstr "ਖੁੱਲ੍ਹੀ ਲਾਗ ਫਾਇਲ %s\n" -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "<%s> ਜੁਮੈਟਰੀ \"%s\" ਪਰਭਾਸ਼ਿਤ ਨਹੀਂ ਕੀਤੀ ਗਈ" +#~ msgid "Window manager: " +#~ msgstr "ਵਿੰਡੋ ਮੈਨੇਜਰ: " -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "<%s> ਜੁਮੈਟਰੀ ਜਾਂ ਜੁਮੈਟਰੀ ਵਾਲੇ ਮੂਲ ਨੂੰ ਦੇਣਾ ਲਾਜ਼ਮੀ ਹੈ" +#~ msgid "Bug in window manager: " +#~ msgstr "ਵਿੰਡੋ ਮੈਨੇਜਰ ਵਿੱਚ ਬੱਗ: " -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "ਤੁਹਾਨੂੰ ਇੱਕ ਐਲਫ਼ਾ ਮੁੱਲ ਲਈ ਇੱਕ ਬੈਕਗਰਾਊਂਡ ਮੁੱਲ ਦਿਓ, ਜੋ ਕਿ ਮਤਲਬ ਸਿਰ ਹੋਵੇ" +#~ msgid "Window manager warning: " +#~ msgstr "ਵਿੰਡੋ ਮੈਨੇਜਰ ਚੇਤਾਵਨੀ: " -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "ਅਣਜਾਣ ਕਿਸਮ \"%s\" ਉੱਤੇ <%s> ਐਲੀਮੈਂਟ" +#~ msgid "Window manager error: " +#~ msgstr "ਵਿੰਡੋ ਮੈਨੇਜਰ ਗਲਤੀ: " -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "ਅਣਜਾਣ ਸਟਾਇਲ_ਸੈੱਟ \"%s\" <%s> ਐਲੀਮੈਂਟ ਉੱਤੇ" +#~ msgid "" +#~ "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " +#~ "window as specified in the ICCCM.\n" +#~ msgstr "" +#~ "ਵਿੰਡੋ %s ਨੇ ਆਪਣੇ ਉੱਤੇ ICCCM ਰਾਹੀਂ ਦੱਸੇ ਅਨੁਸਾਰ WM_CLIENT_LEADER ਵਿੰਡੋ ਦੀ ਬਜਾਏ " +#~ "SM_CLIENT_ID ਨਿਰਧਾਰਿਤ ਕੀਤਾ ਹੈ।\n" -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "ਵਿੰਡੋ ਕਿਸਮ \"%s\" ਵਾਸਤੇ ਪਹਿਲਾਂ ਹੀ ਇੱਕ ਸਟਾਇਲ ਸੈੱਟ ਦਿੱਤਾ ਹੈ" - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "<%s> ਐਲੀਮੈਂਟ ਨੂੰ <%s> ਹੇਠਾਂ ਇਜਾਜ਼ਤ ਨਹੀਂ" +#~ msgid "" +#~ "Window %s sets an MWM hint indicating it isn't resizable, but sets min " +#~ "size %d x %d and max size %d x %d; this doesn't make much sense.\n" +#~ msgstr "" +#~ "ਵਿੰਡੋ %s ਨੇ MWM ਸੰਕੇਤ ਸੈੱਟ ਵੇਖਾਇਆ ਕਿ ਇਹ ਮੁੜ-ਆਕਾਰ-ਯੋਗ ਨਹੀਂ ਹੈ, ਪਰ ਘੱਟੋ-ਘੱਟ ਆਕਾਰ %d x %d " +#~ "ਅਤੇ ਵੱਧ ਤੋਂ ਵੱਧ ਆਕਾਰ %d x %d ਸੈੱਟ ਕਰਦਾ ਹੈ, ਪਰ ਇਹ ਦਾ ਜ਼ਿਆਦਾ ਮਤਲਬ ਨਹੀਂ ਹੈ।\n" -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" -msgstr "" -"ਦੋਵੇਂ \"button_width (ਬਟਨ ਚੌੜਾਈ)\"/\"button_height (ਬਟਨ ਉਚਾਈ)\" ਅਤੇ " -"\"aspect_ratio" -"\" ਬਟਨਾਂ ਲਈ ਨਹੀਂ ਦਿੱਤੇ ਦੇ ਸਕਦੇ" +#~ msgid "Application set a bogus _NET_WM_PID %lu\n" +#~ msgstr "ਐਪਲੀਕੇਸ਼ਨ ਨੇ ਇੱਕ ਫਰਜ਼ੀ _NET_WM_PID %lu ਦਿੱਤਾ ਹੈ\n" -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "ਫਾਸਲਾ \"%s\" ਅਣਜਾਣ ਹੈ" +#~ msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +#~ msgstr "ਗਲਤ WM_TRANSIENT_FOR ਵਿੰਡੋ 0x%lx %s ਲਈ ਦਿੱਤਾ ਗਿਆ ਹੈ।\n" -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "ਅਕਾਰ ਅਨੁਪਾਤ \"%s\" ਅਣਜਾਣ ਹੈ" +#~ msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" +#~ msgstr "WM_TRANSIENT_FOR ਵਿੰਡੋ 0x%lx %s ਲੂਪ ਬਣਾਏਗਾ।\n" -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "ਬਾਰਡਰ \"%s\" ਅਣਜਾਣ ਹੈ" +#~ msgid "" +#~ "Window 0x%lx has property %s\n" +#~ "that was expected to have type %s format %d\n" +#~ "and actually has type %s format %d n_items %d.\n" +#~ "This is most likely an application bug, not a window manager bug.\n" +#~ "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +#~ msgstr "" +#~ "0x%lx ਵਿੰਡੋ ਵਿੱਚ %s ਵਿਸ਼ੇਸ਼ਤਾ ਹੈ\n" +#~ "ਜੋ ਕਿ ਕਿਸਮ %s ਫਾਰਮੈਟ %d ਹੋਣ ਦੀ ਉਮੀਦ ਹੈ\n" +#~ "ਅਤੇ ਅਸਲ ਵਿੱਚ ਕਿਸਮ %s ਵਿਸ਼ੇਸ਼ਤਾ %d n_ਅੰਗ %d ਹੈ।\n" +#~ "ਇਹ ਜਿਆਦਾਤਰ ਐਪਲੀਕੇਸ਼ਨ ਬੱਗ ਵਰਗਾ ਹੈ ਵਿੰਡੋ ਬੱਗ ਵਰਗਾ ਨਹੀਂ।\n" +#~ "ਵਿੰਡੋ ਦਾ ਟਾਇਟਲ=\"%s\" ਕਿਸਮ=\"%s\" ਨਾਂ=\"%s\" ਹੈ\n" -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "<%s> ਐਲੀਮੈਂਟ ਉੱਤੇ ਕੋਈ \"ਸ਼ੁਰੂ_ਕੋਣ\" ਜਾਂ \"ਇਸ ਤੋਂ\"ਗੁਣ ਨਹੀਂ ਹੈ ।" +#~ msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +#~ msgstr "ਵਿਸ਼ੇਸ਼ਤਾ %s ਵਿੰਡੋ 0x%lx ਵਿੱਚ ਅਯੋਗ UTF-8 ਸ਼ਾਮਿਲ ਹੈ\n" -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "<%s> ਐਲੀਮੈਂਟ ਉੱਤੇ ਕੋਈ \"ਸੀਮਾਂ_ਕੋਣ\" ਜਾਂ \"ਵੱਲ\" ਗੁਣ ਨਹੀਂ ਹੈ।" +#~ msgid "" +#~ "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the " +#~ "list\n" +#~ msgstr "%s ਵਿਸ਼ੇਸ਼ਤਾ 0x%lx ਵਿੰਡੋ ਉੱਤੇ ਵਿੱਚ ਲੜੀ ਵਿਚਲੇ ਮੈਂਬਰ %d ਲਈ ਅਯੋਗ UTF-8 ਸ਼ਾਮਿਲ ਹੈ\n" -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "ਢਾਲ ਦੇ ਅਨੁਪਾਤ ਦੀ ਕਿਸਮ ਵਾਸਤੇ ਕੀਮਤ \"%s\" ਨਹੀਂ ਸਮਝਿਆ ਹੈ।" +#~ msgid "Mi_nimize" +#~ msgstr "ਘੱਟੋ-ਘੱਟੋ(_n)" -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "ਐਲੀਮੈਂਟ <%s> ਵਾਸਤੇ ਭਰਨ ਕਿਸਮ \"%s\" ਨਹੀਂ ਸਮਝਿਆ ਹੈ।" +#~ msgid "Ma_ximize" +#~ msgstr "ਵੱਧੋ-ਵੱਧ(_x)" -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "ਐਲੀਮੈਂਟ <%s> ਲਈ ਸਥਿਤੀ \"%s\" ਨਹੀਂ ਸਮਝਿਆ ਹੈ।" +#~ msgid "Unma_ximize" +#~ msgstr "ਨਾ-ਵੱਧੋ-ਵੱਧ(_x)" -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "ਐਲੀਮੈਂਟ <%s> ਲਈ ਪਰਛਾਂਵਾਂ \"%s\" ਨਹੀਂ ਸਮਝਿਆ ਹੈ।" +#~ msgid "Roll _Up" +#~ msgstr "ਸਮੇਟੋ(_U)" -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "ਐਲੀਮੈਂਟ <%s> ਲਈ ਤੀਰ \"%s\" ਨਹੀਂ ਸਮਝਿਆ ਹੈ।" +#~ msgid "_Unroll" +#~ msgstr "ਖੋਲ੍ਹੋ(_U)" -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "ਕੋਈ <draw_ops> \"%s\" ਪਰਭਾਸ਼ਿਤ ਨਹੀਂ ਕੀਤੀ ਹੈ।" +#~ msgid "_Move" +#~ msgstr "ਏਧਰ-ਓਧਰ(_M)" -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "draw_ops ਦੇ ਨਾਲ \"%s\" ਇੱਥੇ ਗੋਲਾਕਾਰ ਸੰਬੰਧ ਬਣਾਏਗਾ ਹੈ।" +#~ msgid "_Resize" +#~ msgstr "ਮੁੜ-ਅਕਾਰ(_R)" -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "ਫਰੇਮ ਟੁਕੜੇ ਲਈ ਅਣਜਾਣੀ ਸਥਿਤੀ \"%s\" ਹੈ।" +#~ msgid "Move Titlebar On_screen" +#~ msgstr "ਟਾਇਟਲ ਸਕਰੀਨ ਉੱਤੇ ਭੇਜੋ(_s)" -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "ਫਰੇਮ ਸਟਾਇਲ ਵਿੱਚ ਪਹਿਲਾਂ ਹੀ %s ਸਥਿਤੀ ਉੱਤੇ ਇੱਕ ਟੁਕੜਾ ਹੈ।" +#~ msgid "Always on _Top" +#~ msgstr "ਹਮੇਸ਼ਾ ਸਭ ਤੋਂ ਉੱਤੇ(_T)" -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "\"%s\" ਨਾਂ ਨਾਲ <draw_ops> ਪਰਭਾਸ਼ਿਤ ਨਹੀਂ ਕੀਤੀਆਂ" +#~ msgid "_Always on Visible Workspace" +#~ msgstr "ਸਿਰਫ਼ ਇਸ ਵਰਕਸਪੇਸ ਵਿੱਚ ਰੱਖੋ(_A)" -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "ਬਟਨ ਲਈ ਅਣਜਾਣ ਕੰਮ \"%s\" ਹੈ।" +#~ msgid "_Only on This Workspace" +#~ msgstr "ਸਿਰਫ਼ ਇਸ ਵਰਕਸਪੇਸ ਵਿੱਚ ਰੱਖੋ(_O)" -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "ਬਟਨ ਫੰਕਸ਼ਨ \"%s\" ਇਹ ਵਰਜਨ 'ਚ ਮੌਜੂਦ ਨਹੀਂ ਹੈ (%d, %d ਲੋੜੀਦਾ ਹੈ)" +#~ msgid "Move to Workspace _Left" +#~ msgstr "ਵਰਕਸਪੇਸ ਵਿੱਚ ਖੱਬੇ ਭੇਜੋ(_L)" -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "ਬਟਨ ਲਈ ਅਣਜਾਣ ਹਾਲਤ \"%s\" ਹੈ।" +#~ msgid "Move to Workspace R_ight" +#~ msgstr "ਵਰਕਸਪੇਸ ਵਿੱਚ ਸੱਜੇ ਭੇਜੋ(_i)" -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "ਫਰੇਮ ਸਟਾਇਲ ਵਿੱਚ ਪਹਿਲਾਂ ਹੀ ਕੰਮ %s ਹਾਲਤ %s ਬਟਨ ਹੈ।" +#~ msgid "Move to Workspace _Up" +#~ msgstr "ਵਰਕਸਪੇਸ ਵਿੱਚ ਉੱਤੇ ਲੈ ਜਾਓ(_U)" -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "ਫੋਕਸ ਗੁਣ ਲਈ \"%s\" ਯੋਗ ਕੀਮਤ ਨਹੀਂ ਹੈ।" +#~ msgid "Move to Workspace _Down" +#~ msgstr "ਵਰਕਸਪੇਸ ਵਿੱਚ ਹੇਠਾਂ ਲੈ ਜਾਓ(_D)" -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "ਹਾਲਤ ਗੁਣ ਲਈ \"%s\" ਯੋਗ ਕੀਮਤ ਨਹੀਂ ਹੈ।" +#~ msgid "_Close" +#~ msgstr "ਬੰਦ ਕਰੋ(_C)" -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "ਇੱਕ ਸਟਾਇਲ \"%s\" ਪਰਭਾਸ਼ਿਤ ਨਹੀਂ ਕੀਤਾ ਹੈ।" +#~ msgid "Workspace %d%n" +#~ msgstr "ਵਰਕਸਪੇਸ %d%n" -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "ਮੁੜ ਆਕਾਰ ਦਿਓ ਗੁਣ ਲਈ \"%s\" ਯੋਗ ਕੀਮਤ ਨਹੀਂ ਹੈ।" +#~ msgid "Workspace 1_0" +#~ msgstr "ਵਰਕਸਪੇਸ ੧_0" -#: ../src/ui/theme-parser.c:3147 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" -"<%s> ਐਲੀਮੈਂਟ ਉੱਤੇ ਵੱਡਾ/ਰੰਗਤ ਹਾਲਤ ਲਈ \"ਮੁੜ ਆਕਾਰ ਦਿਓ\" ਗੁਣ ਨਹੀਂ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ।" +#~ msgid "Workspace %s%d" +#~ msgstr "ਵਰਕਸਪੇਸ %s%d" -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "" -"<%s> ਐਲੀਮੈਂਟ ਲਈ ਵੱਧ ਤੋਂ ਵੱਧ ਹਾਲਤਾਂ ਲਈ \"ਮੁੜ ਆਕਾਰ\" ਗੁਣ ਨਹੀਂ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ।" +#~ msgid "Move to Another _Workspace" +#~ msgstr "ਹੋਰ ਵਰਕਸਪੇਸ ਉੱਤੇ ਭੇਜੋ(_W)" -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "ਹਾਲਤ %s ਮੁੜ ਅਕਾਰ ਦਿਓ %s ਫੋਕਸ %s ਬਾਰੇ ਸਟਾਇਲ ਪਹਿਲਾਂ ਦਿੱਤਾ ਗਿਆ ਹੈ" +#~ msgid "Shift" +#~ msgstr "Shift" -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "ਹਾਲਤ %s ਫੋਕਸ %s ਬਾਰੇ ਸਟਾਇਲ ਪਹਿਲਾਂ ਦਿੱਤਾ ਹੈ" +#~ msgid "Ctrl" +#~ msgstr "Ctrl" -#: ../src/ui/theme-parser.c:3294 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"<piece> ਐਲੀਮੈਂਟ ਵਾਸਤੇ ਦੋ draw_ops ਨਹੀਂ ਹੋ ਸਕਦੀਆਂ (ਥੀਮ ਨੇ draw_ops ਗੁਣ ਅਤੇ <" -"draw_ops> " -"ਐਲੀਮੈਂਟ ਵੀ ਹੋ ਸਕਦੀ ਹੈ ਜਾਂ ਦੋ ਐਲੀਮੈਂਟ ਦਿੱਤੀਆਂ ਹੋ ਸਕਦੀਆਂ ਹਨ)" +#~ msgid "Alt" +#~ msgstr "Alt" -#: ../src/ui/theme-parser.c:3332 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"<button> ਐਲੀਮੈਂਟ ਵਾਸਤੇ ਦੋ draw_ops ਨਹੀਂ ਹੋ ਸਕਦੀਆਂ(ਥੀਮ ਨੇ ਉਲੀਕ ਚੋਣਾਂ ਗੁਣ ਅਤੇ <" -"draw_ops> " -"ਐਲੀਮੈਂਟ ਵੀ ਦਿੱਤਾ ਹੈ, ਜਾਂ ਦੋ ਐਲੀਮੈਂਟ ਦਿੱਤੇ ਹਨ)" +#~ msgid "Meta" +#~ msgstr "Meta" -#: ../src/ui/theme-parser.c:3370 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"ਇੱਕ ਐਲੀਮੈਂਟ ਵਾਸਤੇ <menu_icon> draw_ops ਨਹੀਂ ਹੋ ਸਕਦੀਆਂ (ਥੀਮ ਨੇ draw_ops ਗੁਣ " -"ਅਤੇ " -"<draw_ops> ਇਕਾਈਆਂ ਦਿੱਤੀਆਂ ਹਨ, ਜਾਂ ਦੋ ਇਕਾਈਆਂ ਦਿੱਤੀਆਂ ਹਨ)" +#~ msgid "Super" +#~ msgstr "Super" -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "ਗਲਤ ਵਰਜਨ ਹਦਾਇਤਾਂ '%s'" +#~ msgid "Hyper" +#~ msgstr "Hyper" -#: ../src/ui/theme-parser.c:3507 -msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" -msgstr "" -"\"version\" ਗੁਣ metacity-theme-1.xml ਜਾਂ metacity-theme-2.xml ਵਿੱਚ ਵਰਤਿਆ ਨਹੀਂ " -"ਜਾ " -"ਸਕਦਾ" +#~ msgid "Mod2" +#~ msgstr "ਮਾਡ੨" -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "ਥੀਮ ਲਈ %s ਵਰਜਨ ਚਾਹੀਦਾ ਹੈ, ਪਰ ਸਭ ਤੋਂ ਨਵਾਂ ਸਹਾਇਕ ਥੀਮ ਵਰਜਨ ਹੈ %d.%d" +#~ msgid "Mod3" +#~ msgstr "ਮਾਡ੩" -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "ਥੀਮ ਵਿੱਚ ਸਭ ਤੋਂ ਬਾਹਰੀ ਐਲੀਮੈਂਟ <metacity_theme> ਹੋਵੇ <%s> ਨਹੀਂ" +#~ msgid "Mod4" +#~ msgstr "ਮਾਡ੪" -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "<%s> ਐਲੀਮੈਂਟ ਨੂੰ ਨਾਂ/ਲੇਖਕ/ਮਿਤੀ/ਵੇਰਵਾ ਐਲੀਮੈਂਟ ਵਿੱਚ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ" +#~ msgid "Mod5" +#~ msgstr "ਮਾਡ੫" -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "<%s> ਐਲੀਮੈਂਟ ਨੂੰ <constant> ਐਲੀਮੈਂਟ ਵਿੱਚ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ" +#~ msgid "Usage: %s\n" +#~ msgstr "ਵਰਤੋਂ: %s\n" -#: ../src/ui/theme-parser.c:3599 -#, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "" -"<%s> ਐਲੀਮੈਂਟ ਨੂੰ ਫਾਸਲਾ/ਹਾਸ਼ੀਆ/ਅਕਾਰ ਅਨੁਪਾਤ(aspect_ratio) ਐਲੀਮੈਂਟ ਵਿੱਚ ਇਜਾਜ਼ਤ " -"ਨਹੀਂ ਹੈ" +#~ msgid "_Windows" +#~ msgstr "ਵਿੰਡੋ(_W)" -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "<%s> ਐਲੀਮੈਂਟ ਨੂੰ ਉਲੀਕ ਕਿਰਿਆ ਐਲੀਮੈਂਟ ਵਿੱਚ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ" +#~ msgid "_Dialog" +#~ msgstr "ਡਾਈਲਾਗ(_D)" -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "<%s> ਐਲੀਮੈਂਟ ਨੂੰ <%s> ਐਲੀਮੈਂਟ ਵਿੱਚ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ" +#~ msgid "_Modal dialog" +#~ msgstr "ਮਾਡਲ ਡਾਈਲਾਗ(_M)" -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "ਫਰੇਮ ਟੁਕੜੇ ਲਈ ਕੋਈ draw_ops ਨਹੀਂ ਦਿੱਤੀ ਗਈ" +#~ msgid "_Utility" +#~ msgstr "ਸਹੂਲਤ(_U)" -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "ਬਟਨ ਲਈ ਕੋਈ ਉਲੀਕ ਕਿਰਿਆ ਨਹੀ ਦਿੱਤੀ ਗਈ" +#~ msgid "_Splashscreen" +#~ msgstr "ਸਵਾਗਤੀ ਸਕਰੀਨ(_S)" -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "<%s> ਐਲੀਮੈਂਟ ਵਿੱਚ ਕਿਸੇ ਪਾਠ ਨੂੰ ਇਜਾਜ਼ਤ ਨਹੀਂ" +#~ msgid "_Top dock" +#~ msgstr "ਉੱਤੇ ਡੌਕ(_T)" -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "ਇਸ ਥੀਮ ਲਈ <%s> ਦੋ ਵਾਰ ਦਿੱਤਾ ਗਿਆ" +#~ msgid "_Bottom dock" +#~ msgstr "ਹੇਠਾਂ ਡੌਕ(_B)" -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "ਥੀਮ %s ਲਈ ਇੱਕ ਢੁੱਕਵੀਂ ਫਾਇਲ ਲੱਭਣ ਲਈ ਫੇਲ੍ਹ\n" +#~ msgid "_Left dock" +#~ msgstr "ਖੱਬੇ ਡੌਕ(_L)" -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "ਵਿੰਡੋ(_W)" +#~ msgid "_Right dock" +#~ msgstr "ਸੱਜੇ ਡੌਕ(_R)" -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "ਡਾਈਲਾਗ(_D)" +#~ msgid "_All docks" +#~ msgstr "ਸਭ ਡੌਕ(_A)" -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "ਮਾਡਲ ਡਾਈਲਾਗ(_M)" +#~ msgid "Des_ktop" +#~ msgstr "ਡੈਸਕਟਾਪ(_k)" -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "ਸਹੂਲਤ(_U)" +#~ msgid "Open another one of these windows" +#~ msgstr "ਇਹਨਾਂ ਵਿੰਡੋਜ਼ ਵਿੱਚੋਂ ਕੋਈ ਹੋਰ ਖੋਲ੍ਹੋ" -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "ਸਵਾਗਤੀ ਸਕਰੀਨ(_S)" +#~ msgid "This is a demo button with an 'open' icon" +#~ msgstr "ਇਹ 'ਖੋਲ੍ਹੋ' ਆਈਕਾਨ ਨਾਲ ਡੈਮੋ ਬਟਨ ਹੈ" -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "ਉੱਤੇ ਡੌਕ(_T)" +#~ msgid "This is a demo button with a 'quit' icon" +#~ msgstr "ਇਹ 'ਬਾਹਰ ਜਾਓ' ਆਈਕਾਨ ਨਾਲ ਡੈਮੋ ਬਟਨ ਹੈ" -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "ਹੇਠਾਂ ਡੌਕ(_B)" +#~ msgid "This is a sample message in a sample dialog" +#~ msgstr "ਇਹ ਸੈਂਪਲ ਡਾਈਲਾਗ ਵਿੱਚ ਸੈਂਪਲ ਸੁਨੇਹਾ ਹੈ" -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "ਖੱਬੇ ਡੌਕ(_L)" +#~ msgid "Fake menu item %d\n" +#~ msgstr "ਨਕਲੀ ਮੇਨੂ ਆਈਟਮ %d\n" -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "ਸੱਜੇ ਡੌਕ(_R)" +#~ msgid "Border-only window" +#~ msgstr "ਕੇਵਲ ਬਾਰਡਰ ਵਿੰਡੋ" -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "ਸਭ ਡੌਕ(_A)" +#~ msgid "Bar" +#~ msgstr "ਬਾਰ" -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "ਡੈਸਕਟਾਪ(_k)" +#~ msgid "Normal Application Window" +#~ msgstr "ਸਾਧਾਰਨ ਐਪਲੀਕੇਸ਼ਨ ਵਿੰਡੋ" -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "ਇਹਨਾਂ ਵਿੰਡੋਜ਼ ਵਿੱਚੋਂ ਕੋਈ ਹੋਰ ਖੋਲ੍ਹੋ" +#~ msgid "Dialog Box" +#~ msgstr "ਡਾਈਲਾਗ ਡੱਬਾ" -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "ਇਹ 'ਖੋਲ੍ਹੋ' ਆਈਕਾਨ ਨਾਲ ਡੈਮੋ ਬਟਨ ਹੈ" +#~ msgid "Modal Dialog Box" +#~ msgstr "ਮਾਡਲ ਡਾਈਲਾਗ ਡੱਬਾ" -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "ਇਹ 'ਬਾਹਰ ਜਾਓ' ਆਈਕਾਨ ਨਾਲ ਡੈਮੋ ਬਟਨ ਹੈ" +#~ msgid "Utility Palette" +#~ msgstr "ਸਹੂਲਤ ਪਲੇਅਟ" -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "ਇਹ ਸੈਂਪਲ ਡਾਈਲਾਗ ਵਿੱਚ ਸੈਂਪਲ ਸੁਨੇਹਾ ਹੈ" +#~ msgid "Torn-off Menu" +#~ msgstr "ਮੇਨੂ ਵੱਖ ਕਰੋ" -#: ../src/ui/theme-viewer.c:328 -#, c-format -msgid "Fake menu item %d\n" -msgstr "ਨਕਲੀ ਮੇਨੂ ਆਈਟਮ %d\n" +#~ msgid "Border" +#~ msgstr "ਬਾਰਡਰ" -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "ਕੇਵਲ ਬਾਰਡਰ ਵਿੰਡੋ" +#~ msgid "Attached Modal Dialog" +#~ msgstr "ਮਾਡਲ ਡਾਈਲਾਗ ਅਟੈਚ ਹੈ" -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "ਬਾਰ" +#~ msgid "Button layout test %d" +#~ msgstr "ਬਟਨ ਲੇਆਉਟ ਟੈਸਟ %d" -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "ਸਾਧਾਰਨ ਐਪਲੀਕੇਸ਼ਨ ਵਿੰਡੋ" +#~ msgid "%g milliseconds to draw one window frame" +#~ msgstr "ਇੱਕ ਵਿੰਡੋ ਫਰੇਮ ਉਲੀਕਣ ਲਈ %g ਮਿਲੀ ਸਕਿੰਟ" -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "ਡਾਈਲਾਗ ਡੱਬਾ" +#~ msgid "Usage: metacity-theme-viewer [THEMENAME]\n" +#~ msgstr "ਵਰਤੋਂ: metacity-theme-viewer [THEMENAME]\n" -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "ਮਾਡਲ ਡਾਈਲਾਗ ਡੱਬਾ" +#~ msgid "Error loading theme: %s\n" +#~ msgstr "ਥੀਮ ਲੋਡ ਕਰਨ ਵਿੱਚ ਗਲਤੀ: %s\n" -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "ਸਹੂਲਤ ਪਲੇਅਟ" +#~ msgid "Loaded theme \"%s\" in %g seconds\n" +#~ msgstr "ਥੀਮ \"%s\" ਨੂੰ ਲੋਡ ਕਰਨ ਵਿੱਚ ਲੱਗਾ ਸਮਾਂ %g ਸਕਿੰਟਾਂ ਵਿੱਚ \n" -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "ਮੇਨੂ ਵੱਖ ਕਰੋ" +#~ msgid "Normal Title Font" +#~ msgstr "ਸਾਧਾਰਨ ਟਾਇਟਲ ਫੋਂਟ" -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "ਬਾਰਡਰ" +#~ msgid "Small Title Font" +#~ msgstr "ਛੋਟੇ ਟਾਇਟਲ ਫੋਂਟ" -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "ਮਾਡਲ ਡਾਈਲਾਗ ਅਟੈਚ ਹੈ" +#~ msgid "Large Title Font" +#~ msgstr "ਵੱਡੇ ਟਾਇਟਲ ਫੋਂਟ" -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "ਬਟਨ ਲੇਆਉਟ ਟੈਸਟ %d" +#~ msgid "Button Layouts" +#~ msgstr "ਬਟਨ ਲੇਆਉਟ" -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "ਇੱਕ ਵਿੰਡੋ ਫਰੇਮ ਉਲੀਕਣ ਲਈ %g ਮਿਲੀ ਸਕਿੰਟ" +#~ msgid "Benchmark" +#~ msgstr "ਬੈਂਚਮਾਰਕ" -#: ../src/ui/theme-viewer.c:813 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "ਵਰਤੋਂ: metacity-theme-viewer [THEMENAME]\n" +#~ msgid "Window Title Goes Here" +#~ msgstr "ਵਿੰਡੋ ਟਾਇਟਲ ਇੱਥੇ ਹੋਵੇਗਾ" -#: ../src/ui/theme-viewer.c:820 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "ਥੀਮ ਲੋਡ ਕਰਨ ਵਿੱਚ ਗਲਤੀ: %s\n" +#~ msgid "" +#~ "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and " +#~ "%g seconds wall clock time including X server resources (%g milliseconds " +#~ "per frame)\n" +#~ msgstr "" +#~ "%d ਫਰੇਮ ਉਲੀਕੇ %g ਕਲਾਈਂਟ ਸਾਈਡ ਸਕਿੰਟਾਂ ਵਿੱਚ (%g ਮਿਲੀ ਸਕਿੰਟ ਪ੍ਰਤੀ ਫਰੇਮ) ਅਤੇ X ਸਰਵਰ ਸਮੇਤ " +#~ "%g ਸਕਿੰਟ ਕੰਧ ਘੜੀ ਸਮਾਂ (%g ਮਿਲੀ ਸਕਿੰਟ ਪ੍ਰਤੀ ਫਰੇਮ)\n" -#: ../src/ui/theme-viewer.c:826 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "ਥੀਮ \"%s\" ਨੂੰ ਲੋਡ ਕਰਨ ਵਿੱਚ ਲੱਗਾ ਸਮਾਂ %g ਸਕਿੰਟਾਂ ਵਿੱਚ \n" +#~ msgid "position expression test returned TRUE but set error" +#~ msgstr "ਸਥਿਤੀ ਕਥਨ ਜਾਂਚ ਨੇ ਜਵਾਬ ਠੀਕ(TRUE) ਦਿੱਤਾ ਪਰ ਗਲਤੀ ਕੱਢੀ ਹੈ" -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "ਸਾਧਾਰਨ ਟਾਇਟਲ ਫੋਂਟ" +#~ msgid "position expression test returned FALSE but didn't set error" +#~ msgstr "ਸਥਿਤੀ ਕਥਨ ਜਾਂਚ ਨੇ ਜਵਾਬ ਗਲਤ(FALSE) ਦਿੱਤਾ ਪਰ ਗਲਤੀ ਨਹੀਂ ਕੱਢੀ ਹੈ" -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "ਛੋਟੇ ਟਾਇਟਲ ਫੋਂਟ" +#~ msgid "Error was expected but none given" +#~ msgstr "ਗਲਤੀ ਦੀ ਉਮੀਦ ਸੀ ਪਰ ਕੋਈ ਵਿਖਾਈ ਨਹੀਂ" -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "ਵੱਡੇ ਟਾਇਟਲ ਫੋਂਟ" +#~ msgid "Error %d was expected but %d given" +#~ msgstr "ਗਲਤੀ %d ਦੀ ਉਮੀਦ ਸੀ ਪਰ ਵਿਖਾਈ %d" -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "ਬਟਨ ਲੇਆਉਟ" +#~ msgid "Error not expected but one was returned: %s" +#~ msgstr "ਗਲਤੀ ਦੀ ਉਮੀਦ ਨਹੀਂ ਸੀ ਪਰ ਇੱਕ ਨਿਕਲੀ: %s" -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "ਬੈਂਚਮਾਰਕ" +#~ msgid "x value was %d, %d was expected" +#~ msgstr "x ਕੀਮਤ %d ਹੈ, %d ਦੀ ਉਮੀਦ ਸੀ" -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "ਵਿੰਡੋ ਟਾਇਟਲ ਇੱਥੇ ਹੋਵੇਗਾ" +#~ msgid "y value was %d, %d was expected" +#~ msgstr "y ਕੀਮਤ %d ਸੀ, %d ਦੀ ਉਮੀਦ ਸੀ" -#: ../src/ui/theme-viewer.c:1047 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"%d ਫਰੇਮ ਉਲੀਕੇ %g ਕਲਾਈਂਟ ਸਾਈਡ ਸਕਿੰਟਾਂ ਵਿੱਚ (%g ਮਿਲੀ ਸਕਿੰਟ ਪ੍ਰਤੀ ਫਰੇਮ) ਅਤੇ X " -"ਸਰਵਰ ਸਮੇਤ %g " -"ਸਕਿੰਟ ਕੰਧ ਘੜੀ ਸਮਾਂ (%g ਮਿਲੀ ਸਕਿੰਟ ਪ੍ਰਤੀ ਫਰੇਮ)\n" +#~ msgid "" +#~ "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" +#~ msgstr "%d ਕੋਆਰਡੀਨੇਟਰ ਸਮੀਕਰਨ ਪਾਰਸ %g ਸਕਿੰਟਾਂ ਵਿੱਚ ਕੀਤੀ (ਔਸਤਨ %g ਸਕਿੰਟ)\n" -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "ਸਥਿਤੀ ਕਥਨ ਜਾਂਚ ਨੇ ਜਵਾਬ ਠੀਕ(TRUE) ਦਿੱਤਾ ਪਰ ਗਲਤੀ ਕੱਢੀ ਹੈ" +#~ msgid "Minimize window" +#~ msgstr "ਵਿੰਡੋ ਘੱਟੋ-ਘੱਟ" -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "ਸਥਿਤੀ ਕਥਨ ਜਾਂਚ ਨੇ ਜਵਾਬ ਗਲਤ(FALSE) ਦਿੱਤਾ ਪਰ ਗਲਤੀ ਨਹੀਂ ਕੱਢੀ ਹੈ" +#~ msgid "Comma-separated list of compositor plugins" +#~ msgstr "ਕਾਮਿਆਂ ਨਾਲ ਵੱਖ ਕੀਤੀ ਕੰਪੋਜ਼ਿਤਰ ਪਲੱਗਇਨ ਦੀ ਲਿਸਟ" -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "ਗਲਤੀ ਦੀ ਉਮੀਦ ਸੀ ਪਰ ਕੋਈ ਵਿਖਾਈ ਨਹੀਂ" +#~ msgid "Live Hidden Windows" +#~ msgstr "ਲੁਕਵੀਆਂ ਵਿੰਡੋਜ਼ ਲਾਈਵ" -#: ../src/ui/theme-viewer.c:1274 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "ਗਲਤੀ %d ਦੀ ਉਮੀਦ ਸੀ ਪਰ ਵਿਖਾਈ %d" +#~ msgid "" +#~ "Determines whether hidden windows (i.e., minimized windows and windows on " +#~ "other workspaces than the current one) should be kept alive." +#~ msgstr "" +#~ "ਦੱਸੋ ਕਿ ਕੀ ਲੁਕਵੀਆਂ ਵਿੰਡੋਜ਼ ਚਾਲੂ ਰੱਖਣੀਆਂ ਹਨ (ਜਿਵੇਂ ਕਿ ਘੱਟੋ-ਘੱਟ ਕੀਤੀ ਵਿੰਡੋਜ਼ ਤੇ ਮੌਜੂਦਾ ਵਰਕਸਪੇਸ ਤੋਂ " +#~ "ਬਿਨਾਂ ਹੋਰ ਤੋਂ ਵਿੰਡੋਜ਼)।" -#: ../src/ui/theme-viewer.c:1280 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "ਗਲਤੀ ਦੀ ਉਮੀਦ ਨਹੀਂ ਸੀ ਪਰ ਇੱਕ ਨਿਕਲੀ: %s" +#~ msgid "Close Window" +#~ msgstr "ਵਿੰਡੋ ਬੰਦ ਕਰੋ" -#: ../src/ui/theme-viewer.c:1284 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "x ਕੀਮਤ %d ਹੈ, %d ਦੀ ਉਮੀਦ ਸੀ" +#~ msgid "Window Menu" +#~ msgstr "ਵਿੰਡੋ ਮੇਨੂ" -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "y ਕੀਮਤ %d ਸੀ, %d ਦੀ ਉਮੀਦ ਸੀ" +#~ msgid "Minimize Window" +#~ msgstr "ਵਿੰਡੋ ਘੱਟੋ-ਘੱਟ" -#: ../src/ui/theme-viewer.c:1352 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "%d ਕੋਆਰਡੀਨੇਟਰ ਸਮੀਕਰਨ ਪਾਰਸ %g ਸਕਿੰਟਾਂ ਵਿੱਚ ਕੀਤੀ (ਔਸਤਨ %g ਸਕਿੰਟ)\n" +#~ msgid "Maximize Window" +#~ msgstr "ਵਿੰਡੋ ਵੱਧੋ-ਵੱਧ" -#~ msgid "Switch to workspace 1" -#~ msgstr "ਵਰਕਸਪੇਸ ੧ ਵਿੱਚ ਜਾਓ" +#~ msgid "Restore Window" +#~ msgstr "ਵਿੰਡੋ ਮੁੜ-ਸਟੋਰ" -#~ msgid "Switch to workspace 2" -#~ msgstr "ਵਰਕਸਪੇਸ ੨ ਵਿੱਚ ਜਾਓ" +#~ msgid "Roll Up Window" +#~ msgstr "ਵਿੰਡੋ ਸਮੇਟੋ" -#~ msgid "Switch to workspace 3" -#~ msgstr "ਵਰਕਸਪੇਸ ੩ ਵਿੱਚ ਜਾਓ" +#~ msgid "Unroll Window" +#~ msgstr "ਵਿੰਡੋ ਫੈਲਾਓ" -#~ msgid "Switch to workspace 4" -#~ msgstr "ਵਰਕਸਪੇਸ ੪ ਵਿੱਚ ਜਾਓ" +#~ msgid "Keep Window On Top" +#~ msgstr "ਵਿੰਡੋ ਉੱਤੇ ਰੱਖੋ" -#~ msgid "Switch to workspace 5" -#~ msgstr "ਵਰਕਸਪੇਸ ੫ ਵਿੱਚ ਜਾਓ" +#~ msgid "Remove Window From Top" +#~ msgstr "ਵਿੰਡੋ ਉੱਤੇ ਤੋਂ ਹਟਾਓ" -#~ msgid "Switch to workspace 6" -#~ msgstr "ਵਰਕਸਪੇਸ ੬ ਵਿੱਚ ਜਾਓ" +#~ msgid "Always On Visible Workspace" +#~ msgstr "ਹਮੇਸ਼ਾ ਉਪਲੱਬਧ ਵਰਕਸਪੇਸ 'ਚ" -#~ msgid "Switch to workspace 7" -#~ msgstr "ਵਰਕਸਪੇਸ ੭ ਵਿੱਚ ਜਾਓ" +#~ msgid "Put Window On Only One Workspace" +#~ msgstr "ਵਿੰਡੋ ਨੂੰ ਸਿਰਫ਼ ਇੱਕ ਵਰਕਸਪੇਸ ਉੱਤੇ ਰੱਖੋ" #~ msgid "Switch to workspace 8" #~ msgstr "ਵਰਕਸਪੇਸ ੮ ਵਿੱਚ ਜਾਓ" @@ -1742,54 +1709,12 @@ msgstr "%d ਕੋਆਰਡੀਨੇਟਰ ਸਮੀਕਰਨ ਪਾਰਸ %g ਸ #~ msgid "Run a terminal" #~ msgstr "ਟਰਮੀਨਲ ਚਲਾਓ" -#~ msgid "Activate the window menu" -#~ msgstr "ਵਿੰਡੋ ਮੇਨੂ ਐਕਟੀਵੇਟ" - -#~ msgid "Toggle fullscreen mode" -#~ msgstr "ਪੂਰੀ ਸਕਰੀਨ ਕਰੋ" - -#~ msgid "Toggle maximization state" -#~ msgstr "ਅਧਿਕਤਮ ਸਥਿਤੀ ਕਰੋ" - #~ msgid "Toggle whether a window will always be visible over other windows" #~ msgstr "ਬਦਲੋ ਕਿ ਕੀ ਵਿੰਡੋ ਹਮੇਸ਼ਾ ਦੂਜੀਆਂ ਵਿੰਡੋਜ਼ ਦੇ ਉੱਤੇ ਵੇਖਾਈ ਦੇਵੇ" -#~ msgid "Maximize window" -#~ msgstr "ਵਿੰਡੋ ਅਧਿਕਤਮ" - -#~ msgid "Restore window" -#~ msgstr "ਵਿੰਡੋ ਮੁੜ-ਸਟੋਰ" - -#~ msgid "Toggle shaded state" -#~ msgstr "ਰੰਗਤ ਸਥਿਤੀ ਕਰੋ" - -#~ msgid "Minimize window" -#~ msgstr "ਵਿੰਡੋ ਘੱਟੋ-ਘੱਟ" - -#~ msgid "Close window" -#~ msgstr "ਵਿੰਡੋ ਬੰਦ ਕਰੋ" - -#~ msgid "Move window" -#~ msgstr "ਵਿੰਡੋ ਹਿਲਾਓ" - -#~ msgid "Resize window" -#~ msgstr "ਵਿੰਡੋ ਮੁੜ-ਅਕਾਰ" - #~ msgid "Toggle whether window is on all workspaces or just one" #~ msgstr "ਕੀ ਵਿੰਡੋ ਸਭ ਵਰਕਸਪੇਸ ਵਿੱਚ ਵੇਖਾਈ ਦੇਵੇ ਜਾਂ ਕੇਵਲ ਇੱਕ ਵਿੱਚ" -#~ msgid "Move window to workspace 1" -#~ msgstr "ਵਿੰਡੋ ਨੂੰ ਵਰਕਸਪੇਸ ੧ ਵਿੱਚ ਲਿਜਾਓ" - -#~ msgid "Move window to workspace 2" -#~ msgstr "ਵਿੰਡੋ ਨੂੰ ਵਰਕਸਪੇਸ ੨ ਵਿੱਚ ਲਿਜਾਓ" - -#~ msgid "Move window to workspace 3" -#~ msgstr "ਵਿੰਡੋ ਨੂੰ ਵਰਕਸਪੇਸ ੩ ਵਿੱਚ ਲਿਜਾਓ" - -#~ msgid "Move window to workspace 4" -#~ msgstr "ਵਿੰਡੋ ਨੂੰ ਵਰਕਸਪੇਸ ੪ ਵਿੱਚ ਲਿਜਾਓ" - #~ msgid "Move window to workspace 5" #~ msgstr "ਵਿੰਡੋ ਨੂੰ ਵਰਕਸਪੇਸ ੫ ਵਿੱਚ ਲਿਜਾਓ" @@ -1814,33 +1739,9 @@ msgstr "%d ਕੋਆਰਡੀਨੇਟਰ ਸਮੀਕਰਨ ਪਾਰਸ %g ਸ #~ msgid "Move window to workspace 12" #~ msgstr "ਵਿੰਡੋ ਨੂੰ ਵਰਕਸਪੇਸ ੧੨ ਵਿੱਚ ਲਿਜਾਓ" -#~ msgid "Move window one workspace to the left" -#~ msgstr "ਵਿੰਡੋ ਨੂੰ ਇੱਕ ਵਰਕਸਪੇਸ ਖੱਬੇ ਵੱਲ ਲਿਜਾਓ" - -#~ msgid "Move window one workspace to the right" -#~ msgstr "ਵਿੰਡੋ ਨੂੰ ਇੱਕ ਵਰਕਸਪੇਸ ਸੱਜੇ ਵੱਲ ਲਿਜਾਓ" - -#~ msgid "Move window one workspace up" -#~ msgstr "ਵਿੰਡੋ ਨੂੰ ਇੱਕ ਵਰਕਸਪੇਸ ਉੱਤੇ ਲਿਜਾਓ" - -#~ msgid "Move window one workspace down" -#~ msgstr "ਵਿੰਡੋ ਨੂੰ ਇੱਕ ਵਰਕਸਪੇਸ ਹੇਠਾਂ ਲਿਜਾਓ" - #~ msgid "Raise window if it's covered by another window, otherwise lower it" #~ msgstr "ਵਿੰਡੋ ਉਭਾਰੋ, ਜੇ ਇਹ ਹੋਰ ਵਿੰਡੋ ਨਾਲ ਢੱਕੀ ਹੈ ਜਾਂ ਇਸ ਨੂੰ ਹੇਠਾਂ ਕਰੋ" -#~ msgid "Raise window above other windows" -#~ msgstr "ਹੋਰ ਵਿੰਡੋ ਤੋਂ ਉੱਪਰਲੀ ਵਿੰਡੋ ਉਠਾਓ" - -#~ msgid "Lower window below other windows" -#~ msgstr "ਹੋਰ ਵਿੰਡੋ ਹੇਠਾਂ ਥੱਲੇ ਵਾਲੀ ਵਿੰਡੋ" - -#~ msgid "Maximize window vertically" -#~ msgstr "ਵਿੰਡੋ ਲੰਬਕਾਰੀ ਅਧਿਕਤਮ" - -#~ msgid "Maximize window horizontally" -#~ msgstr "ਵਿੰਡੋ ਖਿਤਿਜੀ ਅਧਿਕਤਮ" - #~ msgid "Move window to north-west (top left) corner" #~ msgstr "ਵਿੰਡੋ ਉੱਤਰੀ-ਪੱਛਮੀ (ਉੱਤੇ ਖੱਬੇ) ਕੋਨੇ 'ਚ ਭੇਜੋ" @@ -1927,9 +1828,6 @@ msgstr "%d ਕੋਆਰਡੀਨੇਟਰ ਸਮੀਕਰਨ ਪਾਰਸ %g ਸ #~ msgid "Error setting clutter plugin list: %s\n" #~ msgstr "ਕਲੁੱਟਰ ਪਲੱਗਇਨ ਸੈਟਿੰਗ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ: %s\n" -#~ msgid "Clutter Plugins" -#~ msgstr "ਕਲੁੱਟਰ ਪਲੱਗਇਨ" - #~ msgid "Plugins to load for the Clutter-based compositing manager." #~ msgstr "ਕਲੁੱਟਰ-ਅਧਾਰਿਤ ਕੰਪੋਜ਼ਿਸ਼ਨ ਮੈਨੇਜਰ ਲਈ ਲੋਡ ਕਰਨ ਵਾਸਤੇ ਪਲੱਗਇਨ।" @@ -2081,9 +1979,6 @@ msgstr "%d ਕੋਆਰਡੀਨੇਟਰ ਸਮੀਕਰਨ ਪਾਰਸ %g ਸ #~ msgid "Commands to run in response to keybindings" #~ msgstr "ਸਵਿੱਚ ਸੰਬੰਧਾਂ ਦੇ ਉੱਤਰ ਵਿਚ ਚੱਲਣ ਵਾਲੀ ਕਮਾਂਡ" -#~ msgid "Compositing Manager" -#~ msgstr "ਕੰਪੋਜਿੰਗ ਮੈਨੇਜਰ" - #~ msgid "Control how new windows get focus" #~ msgstr "ਕੰਟਰੋਲ ਕਿ ਕਿਵੇਂ ਨਵੀਂ ਵਿੰਡੋ ਫੋਕਸ ਹੋਣ" @@ -2110,16 +2005,6 @@ msgstr "%d ਕੋਆਰਡੀਨੇਟਰ ਸਮੀਕਰਨ ਪਾਰਸ %g ਸ #~ msgid "Enable Visual Bell" #~ msgstr "ਦਿੱਖ ਘੰਟੀ ਯੋਗ ਕਰੋ" -#~ msgid "" -#~ "If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " -#~ "the focused window will be automatically raised after a delay specified " -#~ "by the auto_raise_delay key. This is not related to clicking on a window " -#~ "to raise it, nor to entering a window during drag-and-drop." -#~ msgstr "" -#~ "ਜੇ ਇਹ ਸਹੀਂ ਹੋਵੇ ਤਾਂ ਫੋਕਸ ਢੰਗ ਜਾਂ ਤਾਂ \"ਸਲੋਪੀ\" ਜਾਂ \"ਮਾਊਂਸ\" ਹੁੰਦਾ ਹੈ ਤਾਂ ਫੋਕਸ ਹੋਇਆ ਵਿੰਡੋ " -#~ "auto_raise_delay ਕੁੰਜੀ ਵਲੋਂ ਦਿੱਤੇ ਇੱਕ ਅੰਤਰਾਲ ਬਾਅਦ ਆਟੋਮੈਟਿਕ ਹੀ ਉਭਾਰਿਆ ਜਾਵੇਗਾ। ਇਹ " -#~ "ਉਭਾਰਨ ਲਈ ਵਿੰਡੋ ਉੱਤੇ ਨਿਰਭਰ ਨਹੀਂ ਹੈ ਅਤੇ ਨਾ ਹੀ ਚੁੱਕਣ ਅਤੇ ਸੁੱਟਣ ਸਮੇਂ ਇੱਕ ਵਿੰਡੋ ਉੱਤੇ ਵੀ ਨਹੀਂ।" - #~ msgid "" #~ "If true, ignore the titlebar_font option, and use the standard " #~ "application font for window titles." diff --git a/po/pl.po b/po/pl.po index b63aeef70..9fb7df5ba 100644 --- a/po/pl.po +++ b/po/pl.po @@ -1,485 +1,325 @@ -# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -# Aviary.pl -# Jeśli masz jakiekolwiek uwagi odnoszące się do tłumaczenia lub chcesz -# pomóc w jego rozwijaniu i pielęgnowaniu, napisz do nas: -# gnomepl@aviary.pl -# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -msgid "" -msgstr "" -"Project-Id-Version: muffin\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-03-11 23:19+0100\n" -"PO-Revision-Date: 2012-03-11 23:20+0100\n" +# Polish translation for mutter. +# Copyright © 2002-2020 the mutter authors. +# This file is distributed under the same license as the mutter package. +# Zbigniew Chyla <chyla@alice.ci.pwr.wroc.pl>, 2002-2003. +# Artur Flinta <aflinta@at.kernel.pl>, 2003-2005. +# Marek Stępień <marcoos@aviary.pl>, 2007. +# Wadim Dziedzic <wdziedzic@aviary.pl>, 2007. +# Tomasz Dominikowski <dominikowski@gmail.com>, 2008-2009. +# Piotr Drąg <piotrdrag@gmail.com>, 2010-2020. +# Aviary.pl <community-poland@mozilla.org>, 2007-2020. +# +msgid "" +msgstr "" +"Project-Id-Version: mutter\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2020-02-23 17:41+0000\n" +"PO-Revision-Date: 2020-02-29 13:15+0100\n" "Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n" -"Language-Team: Polish <gnomepl@aviary.pl>\n" +"Language-Team: Polish <community-poland@mozilla.org>\n" "Language: pl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " "|| n%100>=20) ? 1 : 2);\n" -"X-Poedit-Language: Polish\n" -"X-Poedit-Country: Poland\n" -#: ../src/50-muffin-windows.xml.in.h:1 -msgid "Windows" -msgstr "Okna" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Nawigacja" -#: ../src/50-muffin-windows.xml.in.h:2 -msgid "View split on left" -msgstr "Podział widoku po lewej" +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Przeniesienie okna na 1. obszar roboczy" -#: ../src/50-muffin-windows.xml.in.h:3 -msgid "View split on right" -msgstr "Podział widoku po prawej" +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Przeniesienie okna na 2. obszar roboczy" -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format -msgid "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." -msgstr "" -"Inny menedżer składania jest już uruchomiony na podekranie %i ekranu \"%s\"." +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Przeniesienie okna na 3. obszar roboczy" -#: ../src/core/bell.c:307 -msgid "Bell event" -msgstr "Zdarzenie sygnału dźwiękowego" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Przeniesienie okna na 4. obszar roboczy" -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Żądanie nieznanej informacji okna: %d" +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Przeniesienie okna na ostatni obszar roboczy" -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "Okno <tt>%s</tt> nie odpowiada." +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "Przeniesienie okna o obszar roboczy w górę" -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "Program nie odpowiada." +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "Przeniesienie okna o obszar roboczy w dół" -#: ../src/core/delete.c:119 -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "Można poczekać chwilę dłużej lub wymusić zakończenie programu." +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "Przeniesienie okna na monitor po lewej" -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "_Czekaj" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "Przeniesienie okna na monitor po prawej" -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "_Zakończ" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "Przeniesienie okna na monitor na górze" -#: ../src/core/display.c:361 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "Brak rozszerzenia %s wymaganego przez składanie" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "Przeniesienie okna na monitor na dole" -#: ../src/core/display.c:427 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "" -"Otwarcie połączenia z ekranem \"%s\" systemu X Window się nie powiodło\n" +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "Przełączenie programów" -#: ../src/core/keybindings.c:852 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "" -"Skrótu klawiszowego z klawiszem %s i modyfikatorami %x używa już inny " -"program\n" +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "Przełączenie na poprzedni program" -#: ../src/core/main.c:206 -msgid "Disable connection to session manager" -msgstr "Wyłącza połączenie z menedżerem sesji" +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "Przełączenie okien" -#: ../src/core/main.c:212 -msgid "Replace the running window manager" -msgstr "Zastępuje uruchomionego menedżera okien" +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "Przełączenie na poprzednie okno" -#: ../src/core/main.c:218 -msgid "Specify session management ID" -msgstr "Określa identyfikator zarządzania sesją" +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "Przełączenie między oknami programu" -#: ../src/core/main.c:223 -msgid "X Display to use" -msgstr "Używany ekran X" +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "Przełączenie na poprzednie okno programu" -#: ../src/core/main.c:229 -msgid "Initialize session from savefile" -msgstr "Inicjuje sesję z zapisanego pliku" +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "Przełączenie kontroli systemowej" -#: ../src/core/main.c:235 -msgid "Make X calls synchronous" -msgstr "Synchroniczne wezwania X" +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "Przełączenie na poprzednią kontrolę systemową" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Przejrzenie katalogu z motywami się nie powiodło: %s\n" +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "Bezpośrednie przełączenie między oknami" -#: ../src/core/main.c:520 -#, c-format -msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "" -"Nie można odnaleźć żadnego motywu. Proszę sprawdzić, czy katalog %s istnieje " -"i zawiera standardowe motywy.\n" +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "Bezpośrednie przełączenie na poprzednie okno" -#: ../src/core/muffin.c:40 -#, c-format -msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., oraz inni\n" -"Niniejszy program jest wolnym oprogramowaniem, aby poznać warunki, pod\n" -"jakimi dopuszczalne jest kopiowanie programu, zajrzyj do jego źródeł.\n" -"Na program nie udziela się ŻADNYCH GWARANCJI, nawet domyślnej gwarancji\n" -"PRZYDATNOŚCI HANDLOWEJ albo PRZYDATNOŚCI DO OKREŚLONYCH ZASTOSOWAŃ.\n" +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "Bezpośrednie przełączenie między oknami programu" -#: ../src/core/muffin.c:54 -msgid "Print version" -msgstr "Wyświetla wersję" +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "Bezpośrednie przełączenie na poprzednie okno programu" -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "Lista wtyczek składania oddzielonych przecinkami" +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "Bezpośrednie przełączenie kontroli systemowej" -#: ../src/core/prefs.c:1077 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"Obejścia dla błędnie działających programów są wyłączone. Niektóre z nich " -"mogą się więc zachowywać w sposób nieprzewidywalny.\n" +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "Bezpośrednie przełączenie na poprzednią kontrolę systemową" -#: ../src/core/prefs.c:1152 -#, c-format -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "" -"Nie można przetworzyć opisu czcionki \"%s\", powiązanego z kluczem GSettings " -"%s\n" +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "Ukrycie wszystkich zwykłych okien" -#: ../src/core/prefs.c:1218 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"Wartość \"%s\", odnaleziona w bazie danych konfiguracji nie opisuje " -"prawidłowo modyfikatora przycisku myszy\n" +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "Przełączenie na 1. obszar roboczy" -#: ../src/core/prefs.c:1736 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "" -"Wartość \"%s\", odnaleziona w bazie danych konfiguracji nie opisuje " -"prawidłowo skrótu klawiszowego \"%s\"\n" +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "Przełączenie na 2. obszar roboczy" -#: ../src/core/prefs.c:1833 -#, c-format -msgid "Workspace %d" -msgstr "Obszar roboczy %d" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "Przełączenie na 3. obszar roboczy" -#: ../src/core/screen.c:730 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "Podekran %d ekranu \"%s\" jest nieprawidłowy\n" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "Przełączenie na 4. obszar roboczy" -#: ../src/core/screen.c:746 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"Na podekranie %d ekranu \"%s\" działa już menedżer okien. Aby zastąpić " -"działającego menedżera okien, proszę spróbować użyć opcji --replace.\n" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "Przełączenie na ostatni obszar roboczy" -#: ../src/core/screen.c:773 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "" -"Nie można uzyskać zaznaczenia menedżera okien na podekranie %d ekranu \"%s" -"\"\n" +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "Przeniesienie na górny obszar roboczy" -#: ../src/core/screen.c:828 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "Na podekranie %d ekranu \"%s\" działa już menedżer okien\n" +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "Przeniesienie na dolny obszar roboczy" -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "Nie można zwolnić podekranu %d ekranu \"%s\"\n" +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "System" -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Nie można utworzyć katalogu \"%s\": %s\n" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Wyświetlenie okna wykonania polecenia" -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "Nie można otworzyć pliku sesji \"%s\" do zapisania: %s\n" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Wyświetlenie podglądu aktywności" -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Błąd podczas zapisywania pliku sesji \"%s\": %s\n" +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Przywrócenie skrótów klawiszowych" -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Błąd podczas zamykania pliku sesji \"%s\": %s\n" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Okna" -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Przetworzenie zapisanego pliku sesji się nie powiodło: %s\n" +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "Otwarcie menu okna" -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "" -"Odnaleziono atrybut <muffin_session>, kiedy identyfikator sesji został już " -"ustawiony" +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Przełączenie trybu pełnoekranowego" -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Nieznany atrybut %s elementu <%s>" +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "Przełączenie stanu maksymalizacji" -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "zagnieżdżony znacznik <window>" +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "Maksymalizacja okna" -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "Nieznany element %s" +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Przywrócenie okna" -#: ../src/core/session.c:1809 -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" -"Te okna nie obsługują opcji zapisu aktualnego stanu (\"save current setup" -"\"), więc przy następnym zalogowaniu będą musiały zostać uruchomione ręcznie." +#: data/50-mutter-windows.xml:18 +msgid "Close window" +msgstr "Zamknięcie okna" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Otwarcie dziennika z zapisem wykonania się nie powiodło: %s\n" +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "Ukrycie okna" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Wykonać fdopen() na pliku dziennika %s się nie powiodło: %s\n" +#: data/50-mutter-windows.xml:22 +msgid "Move window" +msgstr "Przeniesienie okna" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "Otwarty plik dziennika %s\n" +#: data/50-mutter-windows.xml:24 +msgid "Resize window" +msgstr "Zmiana rozmiaru okna" -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" msgstr "" -"Program Muffin został skompilowany bez obsługi trybu z obszerną informacją\n" - -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "Menedżer okien: " - -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "Błąd w programie menedżera okien: " - -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "Ostrzeżenie menedżera okien: " +"Przełączenie obecności okna na wszystkich obszarach roboczych lub jednym" -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "Błąd menedżera okien: " - -#. first time through -#: ../src/core/window.c:7224 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" msgstr "" -"Okno %s ustawia na sobie SM_CLIENT_ID, zamiast na oknie WM_CLIENT_LEADER, " -"jak to określono w specyfikacji ICCCM.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7887 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size " -"%d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"Okno %s ustawia atrybut MWM, określający, że jego rozmiar okna jest " -"niezmienny, lecz jednocześnie ustawia minimalny rozmiar na %d x %d, a " -"maksymalny rozmiar na %d x %d. To nie ma żadnego sensu.\n" +"Wysunięcie okna, jeśli jest zasłonięte, odsunięcie w przeciwnym wypadku" -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "Program ustawił błędną wartość _NET_WM_PID %lu\n" +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "Wysunięcie okna przed pozostałe" -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (na %s)" +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "Odsunięcie okna pod pozostałe" -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "" -"Nieprawidłowa wartość WM_TRANSIENT_FOR dla okna 0x%lx określona w %s.\n" +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "Pionowa maksymalizacja okna" -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "WM_TRANSIENT_FOR okna 0x%lx dla %s utworzyłoby pętlę.\n" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "Pozioma maksymalizacja okna" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"Okno 0x%lx ma właściwość %s,\n" -"której oczekiwanym typem jest %s, w formacie %d,\n" -"a w rzeczywistości ma typ %s, w formacie %d przy n_items %d.\n" -"Prawdopodobnie jest to błąd programu, a nie menedżera okien.\n" -"Właściwości okna: tytuł=\"%s\" klasa=\"%s\" nazwa=\"%s\"\n" - -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "" -"Własność %s odnosząca się do okna 0x%lx zawiera nieprawidłową sekwencję " -"UTF-8\n" +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "Podział widoku po lewej" -#: ../src/core/xprops.c:494 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"Własność %s odnosząca się do okna 0x%lx zawiera nieprawidłową sekwencję " -"UTF-8 w %d. elemencie listy\n" +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "Podział widoku po prawej" -#: ../src/muffin.desktop.in.h:1 ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 +#: data/org.gnome.mutter.gschema.xml.in:7 msgid "Modifier to use for extended window management operations" msgstr "Modyfikator używany do rozszerzonych działań menedżera okien" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 +#: data/org.gnome.mutter.gschema.xml.in:8 msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." msgstr "" -"Ten klawisz inicjuje tryb \"overlay\", który jest połączeniem podglądu okien " -"i systemu uruchamiania programów. Domyślnie jest przeznaczony do powiązania " -"z klawiszem \"Windows\" na sprzęcie typu PC. Ustawienie tego powiązania " -"powinno być domyślne lub puste." +"Ten klawisz inicjuje tryb „overlay” (nakładki), który jest połączeniem " +"podglądu okien i systemu uruchamiania programów. Domyślnie jest przeznaczony " +"do powiązania z klawiszem „Windows” na komputerach typu PC. Ustawienie tego " +"powiązania powinno być domyślne lub puste." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 +#: data/org.gnome.mutter.gschema.xml.in:20 msgid "Attach modal dialogs" msgstr "Dołączanie modalnych okien dialogowych" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 +#: data/org.gnome.mutter.gschema.xml.in:21 msgid "" "When true, instead of having independent titlebars, modal dialogs appear " "attached to the titlebar of the parent window and are moved together with " "the parent window." msgstr "" -"Jeśli wynosi \"true\", to modalne okna dialogowe pojawiają się dołączone do " -"paska tytułowego okna nadrzędnego zamiast posiadać oddzielne paski tytułowe " -"i są przenoszone razem z nim." +"Jeśli wynosi wartość „true”, to modalne okna dialogowe pojawiają się " +"dołączone do paska tytułowego okna nadrzędnego, zamiast mieć oddzielne paski " +"tytułowe, i są przenoszone razem z nim." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -msgid "Live Hidden Windows" -msgstr "Aktywne ukryte okna" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"Określa, czy ukryte okna (tzn. okna zminimalizowane i okna na innych " -"obszarach roboczych niż bieżący) powinny pozostać aktywne." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 +#: data/org.gnome.mutter.gschema.xml.in:30 msgid "Enable edge tiling when dropping windows on screen edges" msgstr "" "Włączenie kafelkowania przy krawędziach podczas przenoszenia okien do " "krawędzi ekranu" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 +#: data/org.gnome.mutter.gschema.xml.in:31 msgid "" "If enabled, dropping windows on vertical screen edges maximizes them " "vertically and resizes them horizontally to cover half of the available " "area. Dropping windows on the top screen edge maximizes them completely." msgstr "" "Jeśli jest włączone, to przeniesienie okien do pionowych krawędzi ekranu " -"spowoduje ich maksymalizację w pionie i zmianę rozmiaru w poziomie, aby " +"spowoduje ich maksymalizację w pionie i zmianę rozmiaru w poziomie, aby " "pokryć połowę dostępnego obszaru. Przeniesienie okien na górną krawędź " "ekranu spowoduje ich całkowitą maksymalizację." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 +#: data/org.gnome.mutter.gschema.xml.in:40 msgid "Workspaces are managed dynamically" msgstr "Dynamiczne zarządzanie obszarami roboczymi" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 +#: data/org.gnome.mutter.gschema.xml.in:41 msgid "" -"Determines whether workspaces are managed dynamically or whether there's a " +"Determines whether workspaces are managed dynamically or whether there’s a " "static number of workspaces (determined by the num-workspaces key in org." "gnome.desktop.wm.preferences)." msgstr "" "Określa, czy obszary robocze są zarządzane dynamicznie, czy istnieje " -"statyczna liczba obszarów (określona przez klucz \"num-workspaces\" w org." -"gnome.desktop.wm.preferences)." +"statyczna liczba obszarów (określona przez klucz „num-workspaces” w „org." +"gnome.desktop.wm.preferences”)." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 +#: data/org.gnome.mutter.gschema.xml.in:50 msgid "Workspaces only on primary" -msgstr "Obszary robocze tylko na pierwszym" +msgstr "Obszary robocze tylko na pierwszym monitorze" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 +#: data/org.gnome.mutter.gschema.xml.in:51 msgid "" "Determines whether workspace switching should happen for windows on all " "monitors or only for windows on the primary monitor." @@ -487,11 +327,11 @@ msgstr "" "Określa, czy przełączanie obszarów roboczych powinno być wykonywane dla " "okien na wszystkich monitorach, czy tylko dla okien na pierwszym monitorze." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 +#: data/org.gnome.mutter.gschema.xml.in:59 msgid "No tab popup" msgstr "Bez wyskakującego okna dla tabulacji" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 +#: data/org.gnome.mutter.gschema.xml.in:60 msgid "" "Determines whether the use of popup and highlight frame should be disabled " "for window cycling." @@ -499,1167 +339,445 @@ msgstr "" "Określa, czy wyłączyć użycie wyskakującej, wyróżnionej ramki podczas " "przełączania między oknami." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Opóźnienie zmian aktywności do zatrzymania ruchu kursora" + +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" +"Jeśli jest ustawione na wartość „true”, a tryb aktywności to „sloppy” lub " +"„mouse”, to aktywność nie będzie zmieniana od razu po przejściu do okna, ale " +"dopiero po zatrzymaniu ruchu kursora." + +#: data/org.gnome.mutter.gschema.xml.in:79 msgid "Draggable border width" msgstr "Szerokość krawędzi możliwej do przenoszenia" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 +#: data/org.gnome.mutter.gschema.xml.in:80 msgid "" -"The amount of total draggable borders. If the theme's visible borders are " +"The amount of total draggable borders. If the theme’s visible borders are " "not enough, invisible borders will be added to meet this value." msgstr "" "Suma całkowitych krawędzi możliwych do przenoszenia. Jeśli widoczne " "krawędzie motywu nie są dostateczne, to zostaną dodane niewidoczne " "krawędzie, aby spełnić tę wartość." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:17 -msgid "Select window from tab popup" -msgstr "Wybór okna z wyskakującego okna dla tabulacji" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:18 -msgid "Cancel tab popup" -msgstr "Anulowanie wyskakującego okna dla tabulacji" - -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "Użycie: %s\n" - -#: ../src/ui/frames.c:1158 -msgid "Close Window" -msgstr "Zamyka okno" - -#: ../src/ui/frames.c:1161 -msgid "Window Menu" -msgstr "Menu okna" - -#: ../src/ui/frames.c:1164 -msgid "Minimize Window" -msgstr "Minimalizuje okno" - -#: ../src/ui/frames.c:1167 -msgid "Maximize Window" -msgstr "Maksymalizuje okno" - -#: ../src/ui/frames.c:1170 -msgid "Restore Window" -msgstr "Przywrócenie okna" - -#: ../src/ui/frames.c:1173 -msgid "Roll Up Window" -msgstr "Zwiń okno" - -#: ../src/ui/frames.c:1176 -msgid "Unroll Window" -msgstr "Rozwiń okno" - -#: ../src/ui/frames.c:1179 -msgid "Keep Window On Top" -msgstr "Zatrzymaj okno na wierzchu" - -#: ../src/ui/frames.c:1182 -msgid "Remove Window From Top" -msgstr "Usuń okno z wierzchu" - -#: ../src/ui/frames.c:1185 -msgid "Always On Visible Workspace" -msgstr "Zawsze na widocznym obszarze roboczym" - -#: ../src/ui/frames.c:1188 -msgid "Put Window On Only One Workspace" -msgstr "Umieść okno tylko na jednym obszarze roboczym" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "Zm_inimalizuj" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "Zm_aksymalizuj" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "Przywróć zm_aksymalizowane" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "_Zwiń" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "Ro_zwiń" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "Prz_esuń" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "Zmień _rozmiar" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "Przeno_szenie paska tytułowego na ekranie" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "Zawsze na _wierzchu" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "_Zawsze na widocznym obszarze roboczym" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "_Tylko na tym obszarze roboczym" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "Przenieś na _lewy obszar roboczy" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "Przen_ieś na prawy obszar roboczy" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "_Przenieś na górny obszar roboczy" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "Przenieś na _dolny obszar roboczy" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "Za_mknij" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "Obszar roboczy %d%n" - -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "Obszar roboczy 1_0" - -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "Obszar roboczy %s%d" - -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "Przeniesienie na inny _obszar roboczy" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" - -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" - -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "góra" - -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "dół" - -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "lewa" - -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "prawa" - -#: ../src/ui/theme.c:286 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "Rozmiar ramki nie określa wymiaru \"%s\"" - -#: ../src/ui/theme.c:305 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "Rozmiar ramki nie określa wymiaru \"%s\" dla krawędzi \"%s\"" - -#: ../src/ui/theme.c:342 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "" -"Współczynnik proporcji przycisku %g nie mieści się w rozsądnych granicach" - -#: ../src/ui/theme.c:354 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "Rozmiar ramki nie określa liczby przycisków" - -#: ../src/ui/theme.c:1067 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "Gradienty powinny się składać co najmniej z dwóch kolorów" - -#: ../src/ui/theme.c:1219 -#, c-format -msgid "" -"GTK custom color specification must have color name and fallback in " -"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" -msgstr "" -"Własna specyfikacja koloru GTK+ musi posiadać nazwę koloru i kolor zastępczy " -"w nawiasach, np. gtk:custom(foo,bar); nie można przetworzyć \"%s\"" - -#: ../src/ui/theme.c:1235 -#, c-format -msgid "" -"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" -"_ are valid" -msgstr "" -"Nieprawidłowy znak \"%c\" w parametrze nazwa_koloru opcji gtk:custom, tylko " -"znaki A-Za-z0-9-_ są prawidłowe" - -#: ../src/ui/theme.c:1249 -#, c-format -msgid "" -"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " -"fit the format" -msgstr "" -"Formatem Gtk:custom jest \"gtk:custom(nazwa_koloru,kolor_zastępczy)\", \"%s" -"\" nie pasuje do formatu" - -#: ../src/ui/theme.c:1294 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"Specyfikacja koloru GTK+ musi zawierać stan w nawiasach kwadratowych, np. " -"gtk:fg[NORMAL], gdzie NORMAL jest nazwą stanu; nie można przetworzyć \"%s\"" - -#: ../src/ui/theme.c:1308 -#, c-format -msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"Specyfikacja koloru GTK+ musi po nazwie stanu zawierać zamykający nawias " -"kwadratowy, np. gtk:fg[NORMAL], gdzie NORMAL jest nazwą stanu; nie można " -"przetworzyć \"%s\"" - -#: ../src/ui/theme.c:1319 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "Niezrozumiały stan \"%s\" w specyfikacji koloru" - -#: ../src/ui/theme.c:1332 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "Niezrozumiała definicja koloru \"%s\" w specyfikacji koloru" - -#: ../src/ui/theme.c:1361 -#, c-format -msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" -msgstr "" -"Formatem przenikania jest \"blend/bg_color/fg_color/alpha\", \"%s\" nie " -"pasuje do formatu" - -#: ../src/ui/theme.c:1372 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "Nie można przetworzyć wartości alfa \"%s\" w przenikającym kolorze" - -#: ../src/ui/theme.c:1382 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "" -"Wartość alfa \"%s\" w przenikającym kolorze nie zawiera się pomiędzy 0,0 i " -"1,0" - -#: ../src/ui/theme.c:1429 -#, c-format -msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "" -"Formatem przenikania jest \"shade/base_color/factor\", \"%s\" nie pasuje do " -"formatu" - -#: ../src/ui/theme.c:1440 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "" -"Nie można przetworzyć współczynnika przenikania \"%s\" w przenikającym " -"kolorze" - -#: ../src/ui/theme.c:1450 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "Współczynnik przenikania \"%s\" w przenikającym kolorze jest ujemny" - -#: ../src/ui/theme.c:1479 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Nie można przetworzyć koloru \"%s\"" - -#: ../src/ui/theme.c:1790 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "Wyrażenie określające współrzędne zawiera niedozwolony znak \"%s\"" - -#: ../src/ui/theme.c:1817 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "" -"Wyrażenie określające współrzędne zawiera liczbę zmiennoprzecinkową \"%s\", " -"której nie można przetworzyć" - -#: ../src/ui/theme.c:1831 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" msgstr "" -"Wyrażenie określające współrzędne zawiera liczbę całkowitą \"%s\", której " -"nie można przetworzyć" +"Automatyczne maksymalizowanie okien o rozmiarze zbliżonym do rozmiaru " +"monitora" -#: ../src/ui/theme.c:1953 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:90 msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." msgstr "" -"Wyrażenie określające współrzędne zawiera nieznany operator na początku " -"tekstu: \"%s\"" +"Jeśli jest włączone, to nowe okna o początkowym rozmiarze zbliżonym do " +"rozmiaru monitora zostają automatycznie maksymalizowane." -#: ../src/ui/theme.c:2010 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "" -"Wyrażenie określające współrzędne jest puste lub nie można go rozpoznać" - -#: ../src/ui/theme.c:2121 ../src/ui/theme.c:2131 ../src/ui/theme.c:2165 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "Wyrażenie opisujące położenie zawiera dzielenie przez zero" +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Umieszczanie nowych okien na środku" -#: ../src/ui/theme.c:2173 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:99 msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "" -"Wyrażenie opisujące położenie używa operatora dzielenia modulo z argumentem " -"zmiennoprzecinkowym" - -#: ../src/ui/theme.c:2229 -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "" -"Wyrażenie opisujące położenie zawiera operand \"%s\" w miejscu, w którym " -"oczekiwano argumentu" - -#: ../src/ui/theme.c:2238 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." msgstr "" -"Wyrażenie opisujące położenie zawiera operand w miejscu, w którym oczekiwano " -"operatora" +"Jeśli wynosi wartość „true”, to nowe okna będą zawsze umieszczane na środku " +"aktywnego ekranu monitora." -#: ../src/ui/theme.c:2246 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "Wyrażenie opisujące położenie kończy się operatorem zamiast operandem" +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Funkcje eksperymentalne" -#: ../src/ui/theme.c:2256 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:108 msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes " +"mutter request a low priority real-time scheduling. The executable or user " +"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — " +"initializes Xwayland lazily if there are X11 clients. Requires restart." msgstr "" -"Wyrażenie opisujące położenie zawiera argument \"%c\" bezpośrednio po " -"argumencie \"%c\" bez rozdzielającego ich operatora" +"Aby włączyć eksperymentalne funkcje, należy dodać słowo kluczowe funkcji do " +"tej listy. Niektóre funkcje wymagają ponownego uruchomienia menedżera okien. " +"Dostępność funkcji eksperymentalnych nie jest gwarantowana. W przyszłości " +"każda funkcja może zostać usunięta. Obecnie obsługiwane słowa kluczowe: • " +"„scale-monitor-framebuffer” — sprawia, że menedżer okien do zarządzania " +"monitorami o wysokiej rozdzielczości domyślnie układa logiczne monitory " +"w przestrzeni współrzędnych logicznych pikseli, jednocześnie skalując bufory " +"ramki monitorów zamiast zawartości okien. Nie wymaga ponownego uruchomienia. " +"• „rt-scheduler” — sprawia, że Mutter żąda planowania w czasie rzeczywistym " +"o niskim priorytecie. Plik wykonywalny lub użytkownik musi mieć " +"CAP_SYS_NICE. Wymaga ponownego uruchomienia. • „autostart-xwayland” — " +"inicjuje Xwayland na żądanie, jeśli są klienci X11. Wymaga ponownego " +"uruchomienia." -#: ../src/ui/theme.c:2407 ../src/ui/theme.c:2452 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "" -"Wyrażenie opisujące położenie zawiera nieznaną zmienną lub stałą \"%s\"" +#: data/org.gnome.mutter.gschema.xml.in:134 +msgid "Modifier to use to locate the pointer" +msgstr "Modyfikator używany do znalezienia kursora" -#: ../src/ui/theme.c:2506 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "Parser wyrażeń określających współrzędne przepełnił swój bufor." +#: data/org.gnome.mutter.gschema.xml.in:135 +msgid "This key will initiate the “locate pointer” action." +msgstr "Ten klawisz inicjuje działanie „znajdź kursor”." -#: ../src/ui/theme.c:2535 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "" -"Wyrażenie opisujące położenie zawiera nawias zamykający bez odpowiadającego " -"mu nawiasu otwierającego" +#: data/org.gnome.mutter.gschema.xml.in:142 +msgid "Timeout for check-alive ping" +msgstr "Czas oczekiwania na odpowiedź żądania sprawdzenia aktywności" -#: ../src/ui/theme.c:2599 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "" -"Wyrażenie opisujące położenie zawiera nawias otwierający bez odpowiadającego " -"mu nawiasu zamykającego" - -#: ../src/ui/theme.c:2610 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "" -"Wyrażenie opisujące położenie nie zawiera żadnych operatorów ani operandów" - -#: ../src/ui/theme.c:2822 ../src/ui/theme.c:2842 ../src/ui/theme.c:2862 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "Motyw zawiera wyrażenie, przy którego obliczaniu wystąpił błąd: %s\n" - -#: ../src/ui/theme.c:4533 -#, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" -"Przy tym stylu ramki należy podać <button function=\"%s\" state=\"%s\" " -"draw_ops=\"cokolwiek\"/>" - -#: ../src/ui/theme.c:5066 ../src/ui/theme.c:5091 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:143 msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" +"Number of milliseconds a client has to respond to a ping request in order to " +"not be detected as frozen. Using 0 will disable the alive check completely." msgstr "" -"Brak <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"cokolwiek\"/>" - -#: ../src/ui/theme.c:5139 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Wczytanie motywu \"%s\" się nie powiodło: %s\n" +"Liczba milisekund, w ciągu których klient musi odpowiedzieć na żądanie, aby " +"nie został wykryty jako zawieszony. Wartość 0 całkowicie wyłączy sprawdzanie " +"aktywności." -#: ../src/ui/theme.c:5275 ../src/ui/theme.c:5282 ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 ../src/ui/theme.c:5303 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "Nie określono elementu <%s> dla motywu \"%s\"" - -#: ../src/ui/theme.c:5311 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" -"Przy typie okna \"%s\" w motywie \"%s\" nie ustawiono stylu ramki. Należy " -"dodać element <window type=\"%s\" style_set=\"cokolwiek\"/>" - -#: ../src/ui/theme.c:5709 ../src/ui/theme.c:5771 ../src/ui/theme.c:5834 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" -"Stałe definiowane przez użytkownika powinny rozpoczynać się wielką literą, " -"natomiast \"%s\" nie spełnia tego warunku" +#: data/org.gnome.mutter.gschema.xml.in:165 +msgid "Select window from tab popup" +msgstr "Wybór okna z wyskakującego okna dla tabulacji" -#: ../src/ui/theme.c:5717 ../src/ui/theme.c:5779 ../src/ui/theme.c:5842 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "Stała \"%s\" została już określona" +#: data/org.gnome.mutter.gschema.xml.in:170 +msgid "Cancel tab popup" +msgstr "Anulowanie wyskakującego okna dla tabulacji" -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. +#: data/org.gnome.mutter.gschema.xml.in:175 +msgid "Switch monitor configurations" +msgstr "Przełączenie konfiguracji monitorów" + +#: data/org.gnome.mutter.gschema.xml.in:180 +msgid "Rotates the built-in monitor configuration" +msgstr "Obrócenie wbudowanego monitora" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Przełączenie na 1. konsolę wirtualną" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Przełączenie na 2. konsolę wirtualną" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Przełączenie na 3. konsolę wirtualną" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Przełączenie na 4. konsolę wirtualną" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Przełączenie na 5. konsolę wirtualną" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Przełączenie na 6. konsolę wirtualną" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Przełączenie na 7. konsolę wirtualną" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Przełączenie na 8. konsolę wirtualną" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Przełączenie na 9. konsolę wirtualną" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Przełączenie na 10. konsolę wirtualną" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Przełączenie na 11. konsolę wirtualną" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Przełączenie na 12. konsolę wirtualną" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "Ponowne włączenie skrótów" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow X11 grabs to lock keyboard focus with Xwayland" +msgstr "" +"Zezwolenie przechwyceniom X11 na blokowanie aktywności klawiatury za pomocą " +"Xwayland" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 +msgid "" +"Allow all keyboard events to be routed to X11 “override redirect” windows " +"with a grab when running in Xwayland. This option is to support X11 clients " +"which map an “override redirect” window (which do not receive keyboard " +"focus) and issue a keyboard grab to force all keyboard events to that " +"window. This option is seldom used and has no effect on regular X11 windows " +"which can receive keyboard focus under normal circumstances. For a X11 grab " +"to be taken into account under Wayland, the client must also either send a " +"specific X11 ClientMessage to the root window or be among the applications " +"white-listed in key “xwayland-grab-access-rules”." +msgstr "" +"Zezwolenie na przekierowanie wszystkich zdarzeń klawiatury do okien " +"„przekierowania zastąpienia” X11 za pomocą przechwycenia podczas działania " +"w systemie Xwayland. Ta opcja służy do obsługi klientów X11 mapujących okno " +"„przekierowania zastąpienia” (które nie otrzymują aktywności klawiatury) " +"i wywołujących przechwycenie klawiatury, aby wymusić wszystkie zdarzenia " +"klawiatury do tego okna. Ta opcja jest rzadko używana i nie ma wpływu na " +"zwykłe okna X11, które mogą otrzymywać aktywność klawiatury w zwykłych " +"okolicznościach. Aby przechwycenie X11 zostało uwzględnione w systemie " +"Wayland, klient musi także wysłać konkretny komunikat ClientMessage systemu " +"X11 do głównego okna lub być na liście programów w kluczu „xwayland-grab-" +"access-rules”." + +#: data/org.gnome.mutter.wayland.gschema.xml.in:84 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "Programy Xwayland, które mogą wywoływać przechwycenia klawiatury" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:85 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "" +"Lista nazw zasobów lub klas zasobów okien X11, które mogą lub nie mogą " +"wywoływać przechwyceń klawiatury X11 w systemie Xwayland. Można uzyskać " +"nazwę zasobu lub klasę zasobów danego okna X11 za pomocą polecenia „xprop " +"WM_CLASS”. W wartościach obsługiwane są wieloznaczniki „*” i „?”. Wartości " +"zaczynające się od znaku „!” nie mają zezwolenia, co ma pierwszeństwo przed " +"zezwoleniami, aby usunąć je z domyślnej listy systemu. Domyślna lista " +"systemu zawiera te programy: „@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@”. " +"Użytkownicy mogą przerwać istniejące przechwycenie za pomocą skrótu " +"klawiszowego określonego w kluczu „restore-shortcuts”." + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. #. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "Brak atrybutu \"%s\" w elemencie <%s>" - -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Wiersz %d, znak %d: %s" - -#: ../src/ui/theme-parser.c:479 +#: src/backends/meta-input-settings.c:2567 #, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "Atrybut \"%s\" wystąpił dwukrotnie wewnątrz jednego elementu <%s>" +msgid "Mode Switch (Group %d)" +msgstr "Przełącznik trybu (%d. grupa)" -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "" -"Atrybut \"%s\" jest nieprawidłowy wewnątrz elementu <%s> w tym kontekście" - -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "Nie można przetworzyć \"%s\" jako liczby całkowitej" - -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "Nie można rozpoznać końcowych znaków \"%s\" w napisie \"%s\"" - -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "Liczba całkowita %ld musi być dodatnia" - -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "Liczba całkowita %ld jest zbyt duża, obecne maksimum to %d" - -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "Napis \"%s\" nie jest zapisem liczby zmiennoprzecinkowej" - -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "Wartościami logicznymi są \"true\" i \"false\", a nie \"%s\"" - -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "Wartość kąta musi się mieścić pomiędzy 0,0 i 360,0, odczytano %g\n" - -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" -"Wartość alfa musi się mieścić pomiędzy 0,0 (niewidoczne) i 1,0 (w pełni " -"przezroczyste), odczytano %g\n" +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2590 +msgid "Switch monitor" +msgstr "Przełączenie monitora" -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"Nieprawidłowy rozmiar tytułu \"%s\" (musi on być jedną z wartości: xx-small, " -"x-small, small, medium, large, x-large, xx-large)\n" +#: src/backends/meta-input-settings.c:2592 +msgid "Show on-screen help" +msgstr "Ekran pomocy" -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s>: użyto nazwy \"%s\" po raz drugi" +#: src/backends/meta-monitor.c:223 +msgid "Built-in display" +msgstr "Wbudowany ekran" -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "<%s>: nie określono elementu nadrzędnego o nazwie \"%s\"" +#: src/backends/meta-monitor.c:252 +msgid "Unknown" +msgstr "Nieznany" -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "<%s>: nie określono geometrii o nazwie \"%s\"" +#: src/backends/meta-monitor.c:254 +msgid "Unknown Display" +msgstr "Nieznany ekran" -#: ../src/ui/theme-parser.c:1154 +#: src/backends/meta-monitor.c:262 #, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "<%s> musi albo określać geometrię, albo element nadrzędny z geometrią" +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "Aby wartość alpha miała sens, należy określić tło" - -#: ../src/ui/theme-parser.c:1264 +#: src/backends/meta-monitor.c:270 #, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Nieznany typ \"%s\" wewnątrz elementu <%s>" +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "Nieznana wartość atrybutu \"style_set\" (%s) wewnątrz elementu <%s>" +#. Translators: this string will appear in Sysprof +#: src/backends/meta-profiler.c:79 +msgid "Compositor" +msgstr "Menedżer składania" -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "Z typem okna \"%s\" powiązano już zbiór stylów" - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:533 #, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "Element <%s> nie jest dopuszczalny poniżej <%s>" - -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" +"Another compositing manager is already running on screen %i on display “%s”." msgstr "" -"Nie można jednocześnie określać dla przycisku jego szerokości i wysokości " -"oraz współczynnika proporcji" - -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "Odległość \"%s\" jest nieznana" - -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "Współczynnik proporcji \"%s\" jest nieznany" - -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "Krawędź \"%s\" jest nieznana" - -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "Brak atrybutu \"start_angle\" wewnątrz elementu <%s>" - -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "Brak atrybutu \"extent_angle\" wewnątrz elementu <%s>" - -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "Niezrozumiała wartość \"%s\" typu gradientu" - -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "Niezrozumiały typ wypełnienia \"%s\" elementu <%s>" - -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "Niezrozumiały stan \"%s\" (atrybut state) elementu <%s>" +"Inny menedżer składania jest już uruchomiony na podekranie %i ekranu „%s”." -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "Niezrozumiały cień \"%s\" (atrybut shadow) elementu <%s>" - -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "Niezrozumiała strzałka \"%s\" (atrybut arrow) elementu <%s>" +#: src/core/bell.c:192 +msgid "Bell event" +msgstr "Zdarzenie sygnału dźwiękowego" -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "Nie określono elementu <draw_ops> o nazwie \"%s\"" +#: src/core/main.c:190 +msgid "Disable connection to session manager" +msgstr "Rozłącza połączenie z menedżerem sesji" -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "" -"Włączenie tutaj elementu draw_ops o nazwie \"%s\" spowodowałoby zapętlone " -"odwołanie" +#: src/core/main.c:196 +msgid "Replace the running window manager" +msgstr "Zastępuje uruchomionego menedżera okien" -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Nieznane położenie \"%s\" elementu ramki" +#: src/core/main.c:202 +msgid "Specify session management ID" +msgstr "Podaje identyfikator zarządzania sesją" -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "Styl ramki zawiera już element o położeniu %s" +#: src/core/main.c:207 +msgid "X Display to use" +msgstr "Używany ekran X" -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "Nie określono elementu <draw_ops> o nazwie \"%s\"" +#: src/core/main.c:213 +msgid "Initialize session from savefile" +msgstr "Inicjuje sesję z zapisanego pliku" -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Nieznana funkcja \"%s\" powiązana z przyciskiem" +#: src/core/main.c:219 +msgid "Make X calls synchronous" +msgstr "Synchroniczne wywołania X" -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "Funkcja \"%s\" przycisku nie istnieje w tej wersji (%d, wymaga %d)" +#: src/core/main.c:226 +msgid "Run as a wayland compositor" +msgstr "Uruchamia jako menedżer składania Wayland" -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Nieznany stan \"%s\" powiązany z przyciskiem" +#: src/core/main.c:232 +msgid "Run as a nested compositor" +msgstr "Uruchamia jako osadzony menedżer składania" -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "" -"Dla stylu ramki określono już przycisk, związany z funkcją %s i stanem %s" +#: src/core/main.c:238 +msgid "Run wayland compositor without starting Xwayland" +msgstr "Uruchamia menedżer składania Wayland bez uruchamiania Xwayland" -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "\"%s\" nie jest prawidłową wartością atrybutu \"focus\"" +#: src/core/main.c:246 +msgid "Run as a full display server, rather than nested" +msgstr "Uruchamia jako pełny serwer wyświetlania zamiast osadzonego" -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "\"%s\" nie jest prawidłową wartością atrybutu \"state\"" +#: src/core/main.c:252 +msgid "Run with X11 backend" +msgstr "Uruchamia za pomocą mechanizmu X11" -#: ../src/ui/theme-parser.c:3092 +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:151 #, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "Nie określono stylu o nazwie \"%s\"" +msgid "“%s” is not responding." +msgstr "Okno „%s” nie odpowiada." -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "\"%s\" nie jest prawidłową wartością atrybutu \"resize\"" +#: src/core/meta-close-dialog-default.c:153 +msgid "Application is not responding." +msgstr "Program nie odpowiada." -#: ../src/ui/theme-parser.c:3147 -#, c-format +#: src/core/meta-close-dialog-default.c:158 msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" -"Element <%s> nie powinien zawierać atrybutu \"resize\" przy stanie " -"zmaksymalizowanym lub zwiniętym" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." +msgstr "Można poczekać chwilę dłużej lub wymusić zakończenie programu." -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "" -"Element <%s> nie powinien zawierać atrybutu \"resize\" przy stanie " -"zmaksymalizowanym" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Force Quit" +msgstr "_Zakończ" -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "Określono już styl dla stanu %s, rozmiaru %s i uaktywnienia %s" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Wait" +msgstr "_Czekaj" -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 +#: src/core/mutter.c:38 #, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "Określono już styl dla stanu %s i uaktywnienia %s" - -#: ../src/ui/theme-parser.c:3294 msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Element <piece> nie może zawierać dwóch draw_ops (motyw zawiera atrybut " -"draw_ops i element <draw_ops> lub dwa elementy)" - -#: ../src/ui/theme-parser.c:3332 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Element <button> nie może zawierać dwóch draw_ops (motyw zawiera atrybut " -"draw_ops i element <draw_ops> lub dwa elementy)" - -#: ../src/ui/theme-parser.c:3370 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" msgstr "" -"Element <menu_icon> nie może zawierać dwóch draw_ops (motyw zawiera atrybut " -"draw_ops i element <draw_ops> lub dwa elementy)" - -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "Błędne określenie wersji \"%s\"" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., oraz inni\n" +"Niniejszy program jest wolnym oprogramowaniem, aby poznać warunki, pod\n" +"jakimi dopuszczalne jest kopiowanie programu, zajrzyj do jego źródeł.\n" +"Na program nie udziela się ŻADNYCH GWARANCJI, nawet domyślnej gwarancji\n" +"PRZYDATNOŚCI HANDLOWEJ albo PRZYDATNOŚCI DO OKREŚLONYCH ZASTOSOWAŃ.\n" -#: ../src/ui/theme-parser.c:3507 -msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" -msgstr "" -"Atrybut \"version\" nie może być używany w plikach metacity-theme-1.xml lub " -"metacity-theme-2.xml" +#: src/core/mutter.c:52 +msgid "Print version" +msgstr "Wyświetla wersję" -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "" -"Motyw wymaga wersji %s, ale najnowsza obsługiwana wersja motywów to %d.%d" +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "Używana wtyczka menedżera Mutter" -#: ../src/ui/theme-parser.c:3562 +#: src/core/prefs.c:1911 #, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "Głównym elementem motywu musi być <metacity_theme>, nie <%s>" +msgid "Workspace %d" +msgstr "%d. obszar roboczy" -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" +#: src/core/util.c:122 +msgid "Mutter was compiled without support for verbose mode\n" msgstr "" -"Element <%s> nie jest dopuszczalny wewnątrz elementu name/author/date/" -"description" +"Menedżer Mutter został skompilowany bez obsługi trybu z obszerną informacją\n" -#: ../src/ui/theme-parser.c:3587 +#: src/wayland/meta-wayland-tablet-pad.c:568 #, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "Element <%s> nie jest dopuszczalny wewnątrz elementu <constant>" +msgid "Mode Switch: Mode %d" +msgstr "Przełącznik trybu: %d. tryb" -#: ../src/ui/theme-parser.c:3599 +#: src/x11/meta-x11-display.c:676 #, c-format msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." msgstr "" -"Element <%s> nie jest dopuszczalny wewnątrz elementu distance/border/" -"aspect_ratio" - -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "" -"Element <%s> nie jest dopuszczalny wewnątrz elementu operacji rysowania" - -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "Element <%s> nie jest dopuszczalny wewnątrz elementu <%s>" +"Na ekranie „%s” działa już menedżer okien. Aby zastąpić działającego " +"menedżera okien, należy użyć opcji „--replace”." -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "Brak elementu <draw_ops> powiązanego z elementem ramki" +#: src/x11/meta-x11-display.c:1089 +msgid "Failed to initialize GDK\n" +msgstr "Zainicjowanie biblioteki GDK się nie powiodło\n" -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "Brak elementu <draw_ops> powiązanego z przyciskiem" - -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "Wewnątrz elementu <%s> nie jest dopuszczalny tekst" - -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "<%s> określono dwukrotnie dla tego motywu" - -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Odnalezienie prawidłowego pliku dla motywu %s się nie powiodło\n" - -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "_Okna" - -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "Okno _dialogowe" - -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "_Modalne okno dialogowe" - -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "_Narzędzie" - -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "_Ekran powitalny" - -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "_Górny dok" - -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "_Dolny dok" - -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "_Lewy dok" - -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "_Prawy dok" - -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "_Wszystkie doki" - -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "Pu_lpit" - -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "Otwiera kolejne z tych okien" - -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "To jest przycisk demonstracyjny z ikoną \"otwórz\"" - -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "To jest przycisk demonstracyjny z ikoną \"zakończ\"" - -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "To jest przykładowy komunikat w prostym oknie dialogowym" - -#: ../src/ui/theme-viewer.c:328 -#, c-format -msgid "Fake menu item %d\n" -msgstr "Imitacja elementu menu %d\n" - -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "Okno zawierające tylko krawędzie" - -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "Pasek" - -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "Zwykłe okno programu" - -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "Okno dialogowe" - -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "Modalne okno dialogowe" - -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "Paleta narzędziowa" - -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "Menu rozwijane" - -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "Krawędź" - -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "Dołączone modalne okno dialogowe" - -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "Test układu przycisków %d" - -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g milisekundy do narysowania jednej ramki okna" - -#: ../src/ui/theme-viewer.c:813 +#: src/x11/meta-x11-display.c:1113 #, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Użycie: methacity-theme-viewer [NAZWA_MOTYWU]\n" +msgid "Failed to open X Window System display “%s”\n" +msgstr "Otwarcie połączenia z ekranem „%s” systemu X Window się nie powiodło\n" -#: ../src/ui/theme-viewer.c:820 +#: src/x11/meta-x11-display.c:1196 #, c-format -msgid "Error loading theme: %s\n" -msgstr "Błąd podczas wczytywania motywu: %s\n" +msgid "Screen %d on display “%s” is invalid\n" +msgstr "Podekran %d ekranu „%s” jest nieprawidłowy\n" -#: ../src/ui/theme-viewer.c:826 +#: src/x11/meta-x11-selection-input-stream.c:460 #, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "Wczytano motyw \"%s\" w ciągu %g sekund\n" +msgid "Format %s not supported" +msgstr "Format %s jest nieobsługiwany" -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "Zwykła czcionka tytułu" - -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "Mała czcionka tytułu" - -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "Duża czcionka tytułu" - -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "Układy przycisków" - -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "Test wydajności" - -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "Tutaj znajduje się tytuł okna" - -# FIXME - bełkot -#: ../src/ui/theme-viewer.c:1047 -#, c-format +#: src/x11/session.c:1821 msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." msgstr "" -"Narysowano %d ramek w ciągu %g sekund klienta (%g milisekund na ramkę) oraz " -"%g sekund rzeczywistych, włączając w to zasoby serwera X (%g milisekund na " -"ramkę)\n" +"Te okna nie obsługują opcji zapisu obecnego stanu („save current setup”), " +"więc przy następnym zalogowaniu będą musiały zostać uruchomione ręcznie." -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "test wyrażenia pozycji zwrócił wartość PRAWDA, lecz ustawił błąd" - -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "test wyrażenia pozycji zwrócił wartość FAŁSZ, lecz nie ustawił błędu" - -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "Spodziewano się błędu, lecz nie podano żadnego" - -#: ../src/ui/theme-viewer.c:1274 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "Spodziewano się błędu %d, lecz otrzymano %d" - -#: ../src/ui/theme-viewer.c:1280 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "Nie spodziewano się błędu, lecz został on zwrócony: %s" - -#: ../src/ui/theme-viewer.c:1284 +#: src/x11/window-props.c:569 #, c-format -msgid "x value was %d, %d was expected" -msgstr "wartością x było %d, spodziewano się wartości %d" - -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "wartością y było %d, spodziewano się wartości %d" - -#: ../src/ui/theme-viewer.c:1352 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "" -"wyrażenia współrzędnych %d zostało przetworzone w %g sekund (średnio %g " -"sekund(y))\n" +msgid "%s (on %s)" +msgstr "%s (na %s)" diff --git a/po/pt.po b/po/pt.po index a2e760520..0395d6760 100644 --- a/po/pt.po +++ b/po/pt.po @@ -1,474 +1,327 @@ -# muffin's Portuguese Translation -# Copyright © 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 metacity +# mutter's Portuguese Translation +# Copyright © 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 metacity/mutter # Distributed under the same licence as the metacity package -# Duarte Loreto <happyguy_pt@hotmail.com>, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012. +# Duarte Loreto <happyguy_pt@hotmail.com>, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014. +# Pedro Albuquerque <palbuquerque73@openmailbox.com>, 2015. +# Tiago Santos <tiagofsantos81@sapo.pt>, 2016. +# Juliano de Souza Camargo <julianosc@protonmail.com>, 2020. # msgid "" msgstr "" -"Project-Id-Version: 3.4\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-03-14 00:55+0000\n" -"PO-Revision-Date: 2012-03-14 00:59+0000\n" -"Last-Translator: Duarte Loreto <happyguy_pt@hotmail.com>\n" -"Language-Team: Portuguese <gnome_pt@yahoogroups.com>\n" +"Project-Id-Version: 3.10\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2020-05-29 14:52+0000\n" +"PO-Revision-Date: 2020-09-14 21:15-0300\n" +"Last-Translator: Juliano de Souza Camargo <julianosc@protonmail.com>\n" +"Language-Team: Portuguese <>\n" "Language: pt\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"X-Generator: Gtranslator 3.36.0\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" -#: ../src/50-muffin-windows.xml.in.h:1 -msgid "Windows" -msgstr "Janelas" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Navegação" -#: ../src/50-muffin-windows.xml.in.h:2 -msgid "View split on left" -msgstr "Visualizar a divisão à esquerda" +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Mover janela para a área de trabalho 1" -#: ../src/50-muffin-windows.xml.in.h:3 -msgid "View split on right" -msgstr "Visualizar a divisão à direita" +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Mover janela para a área de trabalho 2" -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format -msgid "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." -msgstr "" -"Já se encontra em execução outro gestor de janelas no ecrã %i do monitor \"%s" -"\"." +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Mover janela para a área de trabalho 3" -#: ../src/core/bell.c:307 -msgid "Bell event" -msgstr "Evento de campainha" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Mover janela para a área de trabalho 4" -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Pedido de informação de janela desconhecido: %d" +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Mover janela para a última área de trabalho" -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> não está a responder." +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "Mover a janela uma área de trabalho acima" -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "A aplicação não está a responder." +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "Mover a janela uma área de trabalho abaixo" -#: ../src/core/delete.c:119 -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "" -"Poderá aguardar uns instantes para que continue ou forçar a aplicação a " -"terminar definitivamente." +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "Mover a janela um monitor para a esquerda" -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "_Aguardar" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "Mover a janela um monitor para a direita" -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "_Forçar Terminar" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "Mover a janela um monitor acima" -#: ../src/core/display.c:387 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "Incapaz de encontrar a extensão %s, necessária para a composição" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "Mover a janela um monitor abaixo" -#: ../src/core/display.c:453 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Falha ao abrir ecrã '%s' do Sistema Janelas X\n" +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "Mudar de aplicações" -#: ../src/core/keybindings.c:852 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "" -"A tecla %s com os modificadores %x já está a ser utilizada como atalho por " -"outra aplicação\n" +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "Mudar para a aplicação anterior" -#: ../src/core/main.c:206 -msgid "Disable connection to session manager" -msgstr "Desactivar a ligação ao gestor de sessão" +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "Mudar de janelas" -#: ../src/core/main.c:212 -msgid "Replace the running window manager" -msgstr "Substituir o gestor de janelas em execução" +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "Mudar para a janela anterior" -#: ../src/core/main.c:218 -msgid "Specify session management ID" -msgstr "Especificar o ID de gestão de sessão" +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "Alternar entre janelas de uma aplicação" -#: ../src/core/main.c:223 -msgid "X Display to use" -msgstr "Ecrã X a utilizar" +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "Mudar para a janela anterior de uma aplicação" -#: ../src/core/main.c:229 -msgid "Initialize session from savefile" -msgstr "Inicializar a sessão a partir de um ficheiro de gravação de sessão" +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "Alternar controlos de sistema" -#: ../src/core/main.c:235 -msgid "Make X calls synchronous" -msgstr "Realizar as invocações X sincronamente" +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "Mudar para o controlo de sistema anterior" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Falha ao analizar directório de temas: %s\n" +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "Alternar diretamente entre janelas" -#: ../src/core/main.c:520 -#, c-format -msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "" -"Incapaz de encontrar um tema! Certifique-se que %s existe e contém os temas " -"normais.\n" +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "Mudar diretamente para a janela anterior" -#: ../src/core/muffin.c:40 -#, c-format -msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" -"muffin %s\n" -"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., e outros\n" -"Esta é uma aplicação livre; consulte o código fonte para condições de " -"cópia.\n" -"NÃO existe qualquer garantia; nem sequer de COMERCIALIZAÇÃO ou ADEQUAÇÃO A " -"UM PROPÓSITO ESPECÍFICO.\n" +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "Alternar diretamente entre janelas de uma aplicação" -#: ../src/core/muffin.c:54 -msgid "Print version" -msgstr "Imprimir a versão" +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "Mudar diretamente para a janela anterior de uma aplicação" -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "Lista separada por vírgulas de plugins de compositor" +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "Alternar diretamente entre controlos de sistema" -#: ../src/core/prefs.c:1077 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"Recursos para aplicações problemáticas inactivos. Algumas aplicações poderão " -"não funcionar correctamente.\n" +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "Mudar diretamente para o controlo de sistema anterior" -#: ../src/core/prefs.c:1152 -#, c-format -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "Incapaz de processar a descrição de fonte \"%s\" da chave GSettings %s\n" +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "Ocultar todas as janelas normais" -#: ../src/core/prefs.c:1218 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"\"%s\" encontrado na base de dados de configuração não é um valor válido " -"para o modificador de botão de rato\n" +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "Mudar para a área de trabalho 1" -#: ../src/core/prefs.c:1739 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "" -"\"%s\" encontrado na base de dados de configuração não é um valor válido " -"para o atalho de teclado \"%s\"\n" +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "Mudar para a área de trabalho 2" -#: ../src/core/prefs.c:1836 -#, c-format -msgid "Workspace %d" -msgstr "Área de Trabalho %d" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "Mudar para a área de trabalho 3" -#: ../src/core/screen.c:730 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "Ecrã %d no monitor '%s' é inválido\n" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "Mudar para a área de trabalho 4" -#: ../src/core/screen.c:746 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"Ecrã %d no monitor \"%s\" já tem um gestor de janelas; tente utilizar a " -"opção --replace para substituir o gestor de janelas actual.\n" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "Mudar para a última área de trabalho 1" -#: ../src/core/screen.c:773 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "" -"Incapaz de obter selecção do gestor de janelas no ecrã %d monitor \"%s\"\n" +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "Mover para a área de trabalho acima" -#: ../src/core/screen.c:828 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "Ecrã %d no monitor \"%s\" já tem um gestor de janelas\n" +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "Mover para a área de trabalho abaixo" -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "Incapaz libertar ecrã %d no monitor \"%s\"\n" +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "Sistema" -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Incapaz de criar directório '%s': %s\n" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Mostrar a linha de comando de execução" -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "Incapaz de abrir ficheiro de sessão '%s' para escrita: %s\n" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Mostrar o resumo de atividades" -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Erro ao escrever ficheiro de sessão '%s': %s\n" +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Redefinir os atalhos de teclado" -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Erro ao fechar ficheiro de sessão '%s': %s\n" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Janelas" -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Falha ao processar ficheiro de sessão gravado: %s\n" +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "Ativar o menu de janela" -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "Atributo <muffin_session> observado mas o ID de sessão já é conhecido" +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Alternar modo de ecrã completo" -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Atributo %s desconhecido no elemento <%s>" +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "Alternar estado de maximização" -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "etiqueta de <window> encadeada" +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "Maximizar a janela" -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "Elemento %s desconhecido" +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Restaurar a janela" -#: ../src/core/session.c:1809 -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" -"Estas janelas não suportam "gravar configuração actual" e terão de " -"ser reiniciadas manualmente da próxima vez que iniciar sessão." +#: data/50-mutter-windows.xml:18 +msgid "Close window" +msgstr "Fechar a janela" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Falha ao abrir registo de depuração: %s\n" +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "Esconder a janela" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Falha ao efectuar fdopen() do ficheiro de registo %s: %s\n" +#: data/50-mutter-windows.xml:22 +msgid "Move window" +msgstr "Mover a janela" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "Ficheiro de registo %s aberto\n" +#: data/50-mutter-windows.xml:24 +msgid "Resize window" +msgstr "Redimensionar a janela" -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "" -"Muffin foi compilado sem suporte para modo de registo detalhado (verbose)\n" +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "Alternar janela em todas as áreas de trabalho ou só numa" -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "Gestor de janelas: " +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "Elevar a janela se estiver tapada, caso contrário baixá-la" -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "Erro no gestor de janelas: " +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "Elevar janela acima de outras janelas" -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "Aviso do gestor de janelas: " +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "Baixar janela abaixo de outras janelas" -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "Erro do gestor de janelas: " +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "Maximizar janela verticalmente" -#. first time through -#: ../src/core/window.c:7224 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"Janela %s define SM_CLIENT_ID em si própria, em vez de na janela " -"WM_CLIENT_LEADER tal como especificado no ICCCM.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7887 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size " -"%d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"Janela %s define uma dica MWM indicando que não é redimensionável, mas " -"define tamanho mínimo %d x %d e tamanho máximo %d x %d; isto não faz muito " -"sentido.\n" - -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "Aplicação definiu um _NET_WM_PID %lu fictício\n" - -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (em %s)" - -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "Janela 0x%lx de WM_TRANSIENT_FOR inválido especificada para %s.\n" - -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "" -"Janela 0x%lx de WM_TRANSIENT_FOR para %s iria criar um ciclo infinito.\n" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "Maximizar janela horizontalmente" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"A janela 0x%lx possui a propriedade %s\n" -"que se esperava ter o tipo %s formato %d\n" -"mas na verdade tem o tipo %s formato %d nº itens %d.\n" -"Isto é provavelmente um erro da aplicação, não um erro do gestor de " -"janelas.\n" -"A janela tem o título=\"%s\" classe=\"%s\" nome=\"%s\"\n" - -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "Propriedade %s na janela 0x%lx continha UTF-8 inválido\n" +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "Ver a divisão à esquerda" -#: ../src/core/xprops.c:494 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"Propriedade %s na janela 0x%lx continha UTF-8 inválido para item %d na " -"lista\n" +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "Ver a divisão à direita" -#: ../src/muffin.desktop.in.h:1 ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 +#: data/org.gnome.mutter.gschema.xml.in:7 msgid "Modifier to use for extended window management operations" msgstr "Modificador a utilizar para operações estendidas de gestão de janelas" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 +#: data/org.gnome.mutter.gschema.xml.in:8 +#| msgid "" +#| "This key will initiate the \"overlay\", which is a combination window " +#| "overview and application launching system. The default is intended to be " +#| "the \"Windows key\" on PC hardware. It's expected that this binding " +#| "either the default or set to the empty string." msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." msgstr "" "Esta chave irá iniciar a \"sobreposição\", que é um sistema de visão " -"combinada de janelas e arranque de aplicações. Por omissão é a \"tecla " -"Windows\" em computadores PC. Espera-se que esta associação esteja para a " -"omissão ou uma expressão vazia." +"combinada de janelas e arranque de aplicações. A predefinição é a \"tecla " +"Windows\" em computadores PC. Espera-se que esta associação seja a " +"predefinição ou uma cadeia vazia." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 +#: data/org.gnome.mutter.gschema.xml.in:20 msgid "Attach modal dialogs" msgstr "Anexar diálogos modais" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 +#: data/org.gnome.mutter.gschema.xml.in:21 msgid "" "When true, instead of having independent titlebars, modal dialogs appear " "attached to the titlebar of the parent window and are moved together with " "the parent window." msgstr "" "Quando verdadeiro, em vez de terem barras de título independentes, os " -"diálogos modais surgem anexados à barra de título da janela pai e são " -"movidos juntamente com a janela pai." +"diálogos modais surgem anexados à barra de título da janela-mãe e são " +"movidos juntamente com a janela-mãe." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -msgid "Live Hidden Windows" -msgstr "Janelas Escondidas Activas" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"Determina se as janelas escondidas (ex: janelas minimizadas e janelas " -"noutras áreas de trabalho que não a actual) deverão ser mantidas activas." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 +#: data/org.gnome.mutter.gschema.xml.in:30 msgid "Enable edge tiling when dropping windows on screen edges" -msgstr "Activar ajustar em grelha ao largar janelas nos limites do ecrã" +msgstr "Ativar ajuste em grelha ao largar janelas nos limites do ecrã" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 +#: data/org.gnome.mutter.gschema.xml.in:31 msgid "" "If enabled, dropping windows on vertical screen edges maximizes them " "vertically and resizes them horizontally to cover half of the available " "area. Dropping windows on the top screen edge maximizes them completely." msgstr "" -"Se activo, ao largar janelas nos limites verticais do ecrã maxima-as " -"verticalmente e redimensiona-as horizontalmente para cobrirem metade da " -"área disponível. Largar janelas no limite superior do ecrã maximiza-as " +"Se ativo, ao largar janelas nos limites verticais do ecrã maximiza-as " +"verticalmente e redimensiona-as horizontalmente para cobrirem metade da área " +"disponível. Largar janelas no limite superior do ecrã maximiza-as " "completamente." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 +#: data/org.gnome.mutter.gschema.xml.in:40 msgid "Workspaces are managed dynamically" -msgstr "As áreas de trabalho são geridas dinamicamente" +msgstr "Áreas de trabalho geridas dinamicamente" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 +#: data/org.gnome.mutter.gschema.xml.in:41 +#| msgid "" +#| "Determines whether workspaces are managed dynamically or whether there's " +#| "a static number of workspaces (determined by the num-workspaces key in " +#| "org.gnome.desktop.wm.preferences)." msgid "" -"Determines whether workspaces are managed dynamically or whether there's a " +"Determines whether workspaces are managed dynamically or whether there’s a " "static number of workspaces (determined by the num-workspaces key in org." "gnome.desktop.wm.preferences)." msgstr "" "Determina se as áreas de trabalho são geridas dinamicamente ou se existe um " "número estático de áreas de trabalho (determinado pela chave num-workspaces " -"em org.cinnamon.desktop.wm.preferences)." +"em org.gnome.desktop.wm.preferences)." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 +#: data/org.gnome.mutter.gschema.xml.in:50 msgid "Workspaces only on primary" -msgstr "Áreas de trabalho apenas para a principal" +msgstr "Áreas de trabalho só no principal" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 +#: data/org.gnome.mutter.gschema.xml.in:51 msgid "" "Determines whether workspace switching should happen for windows on all " "monitors or only for windows on the primary monitor." @@ -476,1217 +329,1417 @@ msgstr "" "Determina se a troca de área de trabalho deverá ocorrer para janelas em " "todos os monitores ou apenas para janelas no monitor principal." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 +#: data/org.gnome.mutter.gschema.xml.in:59 msgid "No tab popup" msgstr "Sem popup ao utilizar tabulador" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 +#: data/org.gnome.mutter.gschema.xml.in:60 msgid "" "Determines whether the use of popup and highlight frame should be disabled " "for window cycling." msgstr "" -"Determina se deverá ou não ser desactivado o popup e o realce na janela ao " -"ciclar entre janelas." +"Determina se deverá ou não ser desativado o popup e o realce na janela ao " +"circular entre janelas." + +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Adiar as alterações de foco até que o ponteiro pare de se mover" + +#: data/org.gnome.mutter.gschema.xml.in:69 +#| msgid "" +#| "If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " +#| "the focus will not be changed immediately when entering a window, but " +#| "only after the pointer stops moving." +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" +"Se verdadeiro, e o modo de foco for \"sloppy\" ou \"mouse\" então o foco não " +"será alterado imediatamente ao entrar numa janela mas apenas quando o " +"ponteiro parar de se mover." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 +#: data/org.gnome.mutter.gschema.xml.in:79 msgid "Draggable border width" msgstr "Largura da margem de arrasto" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 +#: data/org.gnome.mutter.gschema.xml.in:80 +#| msgid "" +#| "The amount of total draggable borders. If the theme's visible borders are " +#| "not enough, invisible borders will be added to meet this value." msgid "" -"The amount of total draggable borders. If the theme's visible borders are " +"The amount of total draggable borders. If the theme’s visible borders are " "not enough, invisible borders will be added to meet this value." msgstr "" "A quantidade de margem total arrastável. Se as margens visíveis do tema não " "forem suficientes, serão adicionadas margens invisíveis para atingir este " "valor." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:17 +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "Maximizar automaticamente janelas de dimensão aproximada à do monitor" + +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" +"Se ativo, novas janelas que sejam inicialmente do tamanho do monitor são " +"maximizadas automaticamente." + +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Posicionar novas janelas no centro" + +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" +"Se ativo, as novas janelas são sempre posicionadas no centro do ecrã do " +"monitor ativo." + +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Ativar as funcionalidades experimentais" + +#: data/org.gnome.mutter.gschema.xml.in:108 +#, fuzzy +msgid "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes " +"mutter request a low priority real-time scheduling. The executable or user " +"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — " +"initializes Xwayland lazily if there are X11 clients. Requires restart." +msgstr "" +"Para ativar as funcionalidades experimentais, adicione a palavra-chave da " +"funcionalidade na lista. Se deve reiniciar o compositor após ativá-la, " +"depende de cada funcionalidade. Qualquer funcionalidade experimental não " +"necessita de estar disponível ou configurável. Não espere que adicionar algo " +"nas definições seja mantido pode tempo indeterminado. Atualmente as palavras-" +"chave são: • “scale-monitor-framebuffer” — makes mutter default to layout " +"logical monitors in a logical pixel coordinate space, while scaling monitor " +"framebuffers instead of window content, to manage HiDPI monitors. Does not " +"require a restart. • “rt-scheduler” — makes mutter request a low priority " +"real-time scheduling. The executable or user must have CAP_SYS_NICE. " +"Requires a restart. • “autostart-xwayland” — initializes Xwayland lazily if " +"there are X11 clients. Requires restart." + +#: data/org.gnome.mutter.gschema.xml.in:134 +msgid "Modifier to use to locate the pointer" +msgstr "Modificador para localizar o ponteiro" + +#: data/org.gnome.mutter.gschema.xml.in:135 +msgid "This key will initiate the “locate pointer” action." +msgstr "Esta chave inicializa a ação “localizar ponteiro”" + +#: data/org.gnome.mutter.gschema.xml.in:142 +msgid "Timeout for check-alive ping" +msgstr "Expirou o teste de atividade " + +#: data/org.gnome.mutter.gschema.xml.in:143 +msgid "" +"Number of milliseconds a client has to respond to a ping request in order to " +"not be detected as frozen. Using 0 will disable the alive check completely." +msgstr "" +"Número em milissegundos que um cliente precisa responder a um teste de " +"atividade de maneira que não seja detetado como inativo. Usar 0 desativará o " +"teste de atividade completamente." + +#: data/org.gnome.mutter.gschema.xml.in:165 msgid "Select window from tab popup" -msgstr "Seleccionar a janela no popup de tabulador" +msgstr "Selecionar a janela no popup de tabulador" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:18 +#: data/org.gnome.mutter.gschema.xml.in:170 msgid "Cancel tab popup" msgstr "Cancelar o popup de tabulador" -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "Utilização: %s\n" - -#: ../src/ui/frames.c:1158 -msgid "Close Window" -msgstr "Fechar Janela" - -#: ../src/ui/frames.c:1161 -msgid "Window Menu" -msgstr "Menu de Janela" - -#: ../src/ui/frames.c:1164 -msgid "Minimize Window" -msgstr "Minimizar Janela" - -#: ../src/ui/frames.c:1167 -msgid "Maximize Window" -msgstr "Maximizar Janela" - -#: ../src/ui/frames.c:1170 -msgid "Restore Window" -msgstr "Restaurar a Janela" - -#: ../src/ui/frames.c:1173 -msgid "Roll Up Window" -msgstr "Enrolar a Janela" - -#: ../src/ui/frames.c:1176 -msgid "Unroll Window" -msgstr "Desenrolar a Janela" - -#: ../src/ui/frames.c:1179 -msgid "Keep Window On Top" -msgstr "Manter a Janela no Topo" - -#: ../src/ui/frames.c:1182 -msgid "Remove Window From Top" -msgstr "Remover a Janela do Topo" - -#: ../src/ui/frames.c:1185 -msgid "Always On Visible Workspace" -msgstr "Sempre na Área de Trabalho Visível" - -#: ../src/ui/frames.c:1188 -msgid "Put Window On Only One Workspace" -msgstr "Colocar a Janela Apenas em Uma Área de Trabalho" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "Mi_nimizar" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "Ma_ximizar" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "Resta_urar" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "_Enrolar" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "D_esenrolar" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "_Mover" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "_Redimensionar" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "Mover a _Barra de Títulos no Ecrã" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "Sempre no _Topo" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "_Sempre na Área de Trabalho Visível" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "_Apenas nesta Área de Trabalho" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "Mover para a Área de Trabalho à _Esquerda" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "Mover para a Área de Trabalho à _Direita" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "Mover para a Área de Trabalho _Acima" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "Mover para a Área de Trabalho A_baixo" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "_Fechar" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "Área de Trabalho %d%n" +#: data/org.gnome.mutter.gschema.xml.in:175 +#| msgid "Switch monitor" +msgid "Switch monitor configurations" +msgstr "Alternar configurações de ecrã" -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "Área de Trabalho 1_0" +#: data/org.gnome.mutter.gschema.xml.in:180 +msgid "Rotates the built-in monitor configuration" +msgstr "Alternar as configurações nativas do ecrã" -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "Área de Trabalho %s%d" +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Alternar para a área de trabalho 1" -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "Mover para Outra Área de _Trabalho" +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Alternar para a área de trabalho 2" -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Alternar para a área de trabalho 3" -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Alternar para a área de trabalho 4" -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "superior" +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Mover para a área de trabalho 5" -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "inferior" +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Mover para a área de trabalho 6" -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "esquerda" +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Mover para a área de trabalho 7" -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "direita" +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Mover para a área de trabalho 8" -#: ../src/ui/theme.c:286 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "geometria de moldura não especifica dimensão \"%s\"" +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Mover para a área de trabalho 9" -#: ../src/ui/theme.c:305 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "geometria de moldura não especifica dimensão \"%s\" para margem \"%s\"" +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Mover para a área de trabalho 10" -#: ../src/ui/theme.c:342 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "Rácio de aparência de botão %g não é um valor razoável" +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Mover para a área de trabalho 11" -#: ../src/ui/theme.c:354 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "Geometria de moldura não especifica dimensão dos botões" +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Mover para a área de trabalho 12" -#: ../src/ui/theme.c:1067 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "Gradientes deverão ter pelo menos duas cores" +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "Reativar os atalhos" -#: ../src/ui/theme.c:1219 -#, c-format -msgid "" -"GTK custom color specification must have color name and fallback in " -"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow X11 grabs to lock keyboard focus with Xwayland" msgstr "" -"Especificação de cor GTK tem de ter o nome da cor e o recurso entre " -"parentesis, por ex. gtk:custom(foo,bar); incapaz de processar \"%s\"" -#: ../src/ui/theme.c:1235 -#, c-format +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 msgid "" -"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" -"_ are valid" +"Allow all keyboard events to be routed to X11 “override redirect” windows " +"with a grab when running in Xwayland. This option is to support X11 clients " +"which map an “override redirect” window (which do not receive keyboard " +"focus) and issue a keyboard grab to force all keyboard events to that " +"window. This option is seldom used and has no effect on regular X11 windows " +"which can receive keyboard focus under normal circumstances. For a X11 grab " +"to be taken into account under Wayland, the client must also either send a " +"specific X11 ClientMessage to the root window or be among the applications " +"white-listed in key “xwayland-grab-access-rules”." msgstr "" -"Caracter '%c' inválido no parâmetro color_name de gtk:custom, apenas são " -"válidos os caracteres A-Za-z0-9-_" -#: ../src/ui/theme.c:1249 +#: data/org.gnome.mutter.wayland.gschema.xml.in:84 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:85 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "" + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. +#. +#: src/backends/meta-input-settings.c:2631 +#, c-format +#| msgid "Mode Switch: Mode %d" +msgid "Mode Switch (Group %d)" +msgstr "Alteração de modo (Grupo %d)" + +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2654 +msgid "Switch monitor" +msgstr "Alternar monitor" + +#: src/backends/meta-input-settings.c:2656 +msgid "Show on-screen help" +msgstr "Mostrar ajuda no ecrã" + +#: src/backends/meta-monitor.c:226 +msgid "Built-in display" +msgstr "Ecrã embutido" + +#: src/backends/meta-monitor.c:255 +msgid "Unknown" +msgstr "Desconhecido" + +#: src/backends/meta-monitor.c:257 +msgid "Unknown Display" +msgstr "Ecrã desconhecido" + +#: src/backends/meta-monitor.c:265 +#, c-format +#| msgid "%s %s" +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" + +#: src/backends/meta-monitor.c:273 +#, c-format +#| msgid "%s %s" +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" + +#. Translators: this string will appear in Sysprof +#: src/backends/meta-profiler.c:79 +#| msgid "Compositing Manager" +msgid "Compositor" +msgstr "Compositor" + +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:533 #, c-format +#| msgid "" +#| "Another compositing manager is already running on screen %i on display " +#| "\"%s\"." msgid "" -"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " -"fit the format" +"Another compositing manager is already running on screen %i on display “%s”." msgstr "" -"Formato Gtk:custom é \"gtk:custom(color_name,fallback)\", \"%s\" não cumpre " -"o formato" +"Já se encontra em execução outro gestor de janelas no ecrã %i do ecrã “%s”." + +#: src/core/bell.c:192 +msgid "Bell event" +msgstr "Evento de campainha" + +#: src/core/main.c:190 +msgid "Disable connection to session manager" +msgstr "Desativar a ligação ao gestor de sessão" -#: ../src/ui/theme.c:1294 +#: src/core/main.c:196 +msgid "Replace the running window manager" +msgstr "Substituir o gestor de janelas em execução" + +#: src/core/main.c:202 +msgid "Specify session management ID" +msgstr "Especificar a ID de gestão de sessão" + +#: src/core/main.c:207 +msgid "X Display to use" +msgstr "Ecrã X a utilizar" + +#: src/core/main.c:213 +msgid "Initialize session from savefile" +msgstr "Inicializar a sessão a partir de um ficheiro de gravação de sessão" + +#: src/core/main.c:219 +msgid "Make X calls synchronous" +msgstr "Fazer as chamadas X sincronamente" + +#: src/core/main.c:226 +msgid "Run as a wayland compositor" +msgstr "Executar como compositor wayland" + +#: src/core/main.c:232 +msgid "Run as a nested compositor" +msgstr "Executar como compositor aninhado" + +#: src/core/main.c:238 +msgid "Run wayland compositor without starting Xwayland" +msgstr "Executar o compositor wayland sem a utilização do Xwayland" + +#: src/core/main.c:246 +msgid "Run as a full display server, rather than nested" +msgstr "Executar como servidor de ecrã completo, em vez de aninhado" + +#: src/core/main.c:252 +msgid "Run with X11 backend" +msgstr "Executar com a infira-estrutura X11" + +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:151 #, c-format +msgid "“%s” is not responding." +msgstr "“%s” não está a responder." + +#: src/core/meta-close-dialog-default.c:153 +msgid "Application is not responding." +msgstr "A aplicação não está a responder." + +#: src/core/meta-close-dialog-default.c:158 msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." msgstr "" -"Especificação de cor GTK tem de ter o estado entre parentesis rectos, por " -"ex. gtk:fg[NORMAL] em que NORMAL é o estado; incapaz de processar \"%s\"" +"Poderá aguardar uns instantes para que continue ou forçar a aplicação a " +"terminar definitivamente." + +#: src/core/meta-close-dialog-default.c:165 +msgid "_Force Quit" +msgstr "_Forçar terminar" + +#: src/core/meta-close-dialog-default.c:165 +msgid "_Wait" +msgstr "_Aguardar" -#: ../src/ui/theme.c:1308 +#: src/core/mutter.c:38 #, c-format +#| msgid "" +#| "mutter %s\n" +#| "Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +#| "This is free software; see the source for copying conditions.\n" +#| "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +#| "PARTICULAR PURPOSE.\n" msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" msgstr "" -"Especificação de cor GTK tem de ter um parentesis recto de fecho após o " -"estado, por ex. gtk:fg[NORMAL] em que NORMAL é o estado; incapaz de " -"processar \"%s\"" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., e outros\n" +"Esta é uma aplicação livre; consulte o código fonte para condições de " +"cópia.\n" +"NÃO existe qualquer garantia; nem sequer de COMERCIALIZAÇÃO ou ADEQUAÇÃO A " +"UM PROPÓSITO ESPECÍFICO.\n" + +#: src/core/mutter.c:52 +msgid "Print version" +msgstr "Imprimir a versão" + +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "Extensão Mutter a utilizar" -#: ../src/ui/theme.c:1319 +#: src/core/prefs.c:1911 #, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "Incapaz de compreender o estado \"%s\" na especificação de cor" +msgid "Workspace %d" +msgstr "Área de trabalho %d" + +#: src/core/util.c:122 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "O Mutter foi compilado sem suporte para modo verboso\n" -#: ../src/ui/theme.c:1332 +#: src/wayland/meta-wayland-tablet-pad.c:568 #, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "" -"Incapaz de compreender componente de cor \"%s\" na especificação de cor" +msgid "Mode Switch: Mode %d" +msgstr "Alteração de Modo: Modo %d" -#: ../src/ui/theme.c:1361 +#: src/x11/meta-x11-display.c:676 #, c-format +#| msgid "" +#| "Display \"%s\" already has a window manager; try using the --replace " +#| "option to replace the current window manager." msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." msgstr "" -"Formato de mistura é \"blend/bg_color/fg_color/alpha\", \"%s\" não cumpre o " -"formato" +"O ecrã “%s” já tem um gestor de janelas; tente utilizar a opção --replace " +"para substituir o gestor de janelas atual." -#: ../src/ui/theme.c:1372 +#: src/x11/meta-x11-display.c:1089 +msgid "Failed to initialize GDK\n" +msgstr "Falhou ao iniciar o GDK\n" + +#: src/x11/meta-x11-display.c:1113 #, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "Incapaz de processar o valor alfa \"%s\" na mistura de cor" +#| msgid "Failed to open X Window System display '%s'\n" +msgid "Failed to open X Window System display “%s”\n" +msgstr "Falha ao abrir ecrã “%s” do sistema Janelas X\n" -#: ../src/ui/theme.c:1382 +#: src/x11/meta-x11-display.c:1196 #, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "Valor alfa \"%s\" na mistura de cor não está entre 0.0 e 1.0" +#| msgid "Screen %d on display '%s' is invalid\n" +msgid "Screen %d on display “%s” is invalid\n" +msgstr "Ecrã %d no monitor “%s” é inválido\n" -#: ../src/ui/theme.c:1429 +#: src/x11/meta-x11-selection-input-stream.c:460 #, c-format +msgid "Format %s not supported" +msgstr "O formato “%s” não é suportado" + +#: src/x11/session.c:1821 +#| msgid "" +#| "These windows do not support "save current setup" and will have " +#| "to be restarted manually next time you log in." msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." msgstr "" -"Formato de sombra é \"shade/base_color/factor\", \"%s\" não cumpre o formato" +"Estas janelas não suportam “gravar configuração atual” e terão de ser " +"reiniciadas manualmente da próxima vez que iniciar sessão." -#: ../src/ui/theme.c:1440 +#: src/x11/window-props.c:569 #, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "" -"Incapaz de processar o valor de factor de sombra \"%s\" na cor sombreada" +msgid "%s (on %s)" +msgstr "%s (em %s)" + +#~ msgid "Move window one workspace to the left" +#~ msgstr "Mover a janela uma área de trabalho para a esquerda" + +#~ msgid "Move window one workspace to the right" +#~ msgstr "Mover a janela uma área de trabalho para a direita" + +#~ msgid "Move to workspace left" +#~ msgstr "Mover para a área de trabalho à esquerda" + +#~ msgid "Move to workspace right" +#~ msgstr "Mover para a área de trabalho à direita" + +#~ msgid "Toggle shaded state" +#~ msgstr "Alternar estado sombreado" + +#~ msgid "background texture could not be created from file" +#~ msgstr "incapaz de criar de ficheiro a textura de fundo" + +#~ msgid "Unknown window information request: %d" +#~ msgstr "Pedido de informação de janela desconhecido: %d" + +#~ msgid "Missing %s extension required for compositing" +#~ msgstr "Incapaz de encontrar a extensão %s, necessária para a composição" + +#~ msgid "" +#~ "Some other program is already using the key %s with modifiers %x as a " +#~ "binding\n" +#~ msgstr "" +#~ "A tecla %s com os modificadores %x já está a ser utilizada como atalho " +#~ "por outra aplicação\n" + +#~ msgid "\"%s\" is not a valid accelerator\n" +#~ msgstr "\"%s\" não é um atalho válido\n" + +#~ msgid "Failed to scan themes directory: %s\n" +#~ msgstr "Falha ao analizar diretório de temas: %s\n" + +#~ msgid "" +#~ "Could not find a theme! Be sure %s exists and contains the usual themes.\n" +#~ msgstr "" +#~ "Incapaz de encontrar um tema! Certifique-se que %s existe e contém os " +#~ "temas normais.\n" + +#~ msgid "" +#~ "Workarounds for broken applications disabled. Some applications may not " +#~ "behave properly.\n" +#~ msgstr "" +#~ "Recursos para aplicações problemáticas inativos. Algumas aplicações " +#~ "poderão não funcionar corretamente.\n" + +#~ msgid "Could not parse font description \"%s\" from GSettings key %s\n" +#~ msgstr "" +#~ "Incapaz de processar a descrição de fonte \"%s\" da chave GSettings %s\n" + +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" +#~ msgstr "" +#~ "\"%s\" encontrado na base de dados de configuração não é um valor válido " +#~ "para o modificador de botão de rato\n" + +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for " +#~ "keybinding \"%s\"\n" +#~ msgstr "" +#~ "\"%s\" encontrado na base de dados de configuração não é um valor válido " +#~ "para o atalho de teclado \"%s\"\n" + +#~ msgid "" +#~ "Could not acquire window manager selection on screen %d display \"%s\"\n" +#~ msgstr "" +#~ "Incapaz de obter seleção do gestor de janelas no ecrã %d monitor \"%s\"\n" + +#~ msgid "Screen %d on display \"%s\" already has a window manager\n" +#~ msgstr "Ecrã %d no monitor \"%s\" já tem um gestor de janelas\n" + +#~ msgid "Could not release screen %d on display \"%s\"\n" +#~ msgstr "Incapaz libertar ecrã %d no monitor \"%s\"\n" + +#~ msgid "Could not create directory '%s': %s\n" +#~ msgstr "Incapaz de criar diretório '%s': %s\n" + +#~ msgid "Could not open session file '%s' for writing: %s\n" +#~ msgstr "Incapaz de abrir ficheiro de sessão '%s' para escrita: %s\n" + +#~ msgid "Error writing session file '%s': %s\n" +#~ msgstr "Erro ao escrever ficheiro de sessão '%s': %s\n" + +#~ msgid "Error closing session file '%s': %s\n" +#~ msgstr "Erro ao fechar ficheiro de sessão '%s': %s\n" + +#~ msgid "Failed to parse saved session file: %s\n" +#~ msgstr "Falha ao processar ficheiro de sessão gravado: %s\n" + +#~ msgid "<mutter_session> attribute seen but we already have the session ID" +#~ msgstr "" +#~ "Atributo <mutter_session> observado mas o ID de sessão já é conhecido" + +#~ msgid "Unknown attribute %s on <%s> element" +#~ msgstr "Atributo %s desconhecido no elemento <%s>" + +#~ msgid "nested <window> tag" +#~ msgstr "etiqueta de <window> encadeada" + +#~ msgid "Unknown element %s" +#~ msgstr "Elemento %s desconhecido" + +#~ msgid "Failed to open debug log: %s\n" +#~ msgstr "Falha ao abrir registo de depuração: %s\n" + +#~ msgid "Failed to fdopen() log file %s: %s\n" +#~ msgstr "Falha ao efetuar fdopen() do ficheiro de registo %s: %s\n" + +#~ msgid "Opened log file %s\n" +#~ msgstr "Ficheiro de registo %s aberto\n" + +#~ msgid "Window manager: " +#~ msgstr "Gestor de janelas: " + +#~ msgid "Bug in window manager: " +#~ msgstr "Erro no gestor de janelas: " + +#~ msgid "Window manager warning: " +#~ msgstr "Aviso do gestor de janelas: " + +#~ msgid "Window manager error: " +#~ msgstr "Erro do gestor de janelas: " + +#~ msgid "" +#~ "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " +#~ "window as specified in the ICCCM.\n" +#~ msgstr "" +#~ "Janela %s define SM_CLIENT_ID em si própria, em vez de na janela " +#~ "WM_CLIENT_LEADER tal como especificado no ICCCM.\n" + +#~ msgid "" +#~ "Window %s sets an MWM hint indicating it isn't resizable, but sets min " +#~ "size %d x %d and max size %d x %d; this doesn't make much sense.\n" +#~ msgstr "" +#~ "Janela %s define uma dica MWM indicando que não é redimensionável, mas " +#~ "define tamanho mínimo %d x %d e tamanho máximo %d x %d; isto não faz " +#~ "muito sentido.\n" + +#~ msgid "Application set a bogus _NET_WM_PID %lu\n" +#~ msgstr "Aplicação definiu um _NET_WM_PID %lu fictício\n" + +#~ msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +#~ msgstr "Janela 0x%lx de WM_TRANSIENT_FOR inválido especificada para %s.\n" + +#~ msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" +#~ msgstr "" +#~ "Janela 0x%lx de WM_TRANSIENT_FOR para %s iria criar um ciclo infinito.\n" + +#~ msgid "" +#~ "Window 0x%lx has property %s\n" +#~ "that was expected to have type %s format %d\n" +#~ "and actually has type %s format %d n_items %d.\n" +#~ "This is most likely an application bug, not a window manager bug.\n" +#~ "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +#~ msgstr "" +#~ "A janela 0x%lx possui a propriedade %s\n" +#~ "que se esperava ter o tipo %s formato %d\n" +#~ "mas na verdade tem o tipo %s formato %d nº itens %d.\n" +#~ "Isto é provavelmente um erro da aplicação, não um erro do gestor de " +#~ "janelas.\n" +#~ "A janela tem o título=\"%s\" classe=\"%s\" nome=\"%s\"\n" + +#~ msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +#~ msgstr "Propriedade %s na janela 0x%lx continha UTF-8 inválido\n" + +#~ msgid "" +#~ "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the " +#~ "list\n" +#~ msgstr "" +#~ "Propriedade %s na janela 0x%lx continha UTF-8 inválido para item %d na " +#~ "lista\n" + +#~ msgid "Mi_nimize" +#~ msgstr "Mi_nimizar" + +#~ msgid "Ma_ximize" +#~ msgstr "Ma_ximizar" + +#~ msgid "Unma_ximize" +#~ msgstr "Resta_urar" + +#~ msgid "Roll _Up" +#~ msgstr "_Enrolar" + +#~ msgid "_Unroll" +#~ msgstr "D_esenrolar" + +#~ msgid "_Move" +#~ msgstr "_Mover" + +#~ msgid "_Resize" +#~ msgstr "_Redimensionar" + +#~ msgid "Move Titlebar On_screen" +#~ msgstr "Mover a _Barra de Títulos no Ecrã" + +#~ msgid "Always on _Top" +#~ msgstr "Sempre no _Topo" + +#~ msgid "_Always on Visible Workspace" +#~ msgstr "_Sempre na Área de Trabalho Visível" + +#~ msgid "_Only on This Workspace" +#~ msgstr "_Apenas nesta Área de Trabalho" + +#~ msgid "Move to Workspace _Left" +#~ msgstr "Mover para a Área de Trabalho à _Esquerda" + +#~ msgid "Move to Workspace R_ight" +#~ msgstr "Mover para a Área de Trabalho à _Direita" + +#~ msgid "Move to Workspace _Up" +#~ msgstr "Mover para a Área de Trabalho _Acima" + +#~ msgid "Move to Workspace _Down" +#~ msgstr "Mover para a Área de Trabalho A_baixo" + +#~ msgid "_Close" +#~ msgstr "_Fechar" + +#~ msgid "Workspace %d%n" +#~ msgstr "Área de Trabalho %d%n" + +#~ msgid "Workspace 1_0" +#~ msgstr "Área de Trabalho 1_0" + +#~ msgid "Workspace %s%d" +#~ msgstr "Área de Trabalho %s%d" + +#~ msgid "Move to Another _Workspace" +#~ msgstr "Mover para Outra Área de _Trabalho" + +#~ msgid "Shift" +#~ msgstr "Shift" + +#~ msgid "Ctrl" +#~ msgstr "Ctrl" + +#~ msgid "Alt" +#~ msgstr "Alt" + +#~ msgid "Meta" +#~ msgstr "Meta" + +#~ msgid "Super" +#~ msgstr "Super" + +#~ msgid "Hyper" +#~ msgstr "Hyper" + +#~ msgid "Mod2" +#~ msgstr "Mod2" + +#~ msgid "Mod3" +#~ msgstr "Mod3" + +#~ msgid "Mod4" +#~ msgstr "Mod4" + +#~ msgid "Mod5" +#~ msgstr "Mod5" + +#~ msgid "%d x %d" +#~ msgstr "%d x %d" + +#~ msgid "top" +#~ msgstr "superior" + +#~ msgid "bottom" +#~ msgstr "inferior" + +#~ msgid "left" +#~ msgstr "esquerda" + +#~ msgid "right" +#~ msgstr "direita" + +#~ msgid "frame geometry does not specify \"%s\" dimension" +#~ msgstr "geometria de moldura não especifica dimensão \"%s\"" + +#~ msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" +#~ msgstr "" +#~ "geometria de moldura não especifica dimensão \"%s\" para margem \"%s\"" + +#~ msgid "Button aspect ratio %g is not reasonable" +#~ msgstr "Rácio de aparência de botão %g não é um valor razoável" + +#~ msgid "Frame geometry does not specify size of buttons" +#~ msgstr "Geometria de moldura não especifica dimensão dos botões" + +#~ msgid "Gradients should have at least two colors" +#~ msgstr "Gradientes deverão ter pelo menos duas cores" + +#~ msgid "" +#~ "GTK custom color specification must have color name and fallback in " +#~ "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" +#~ msgstr "" +#~ "Especificação de cor GTK tem de ter o nome da cor e o recurso entre " +#~ "parentesis, por ex. gtk:custom(foo,bar); incapaz de processar \"%s\"" + +#~ msgid "" +#~ "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-" +#~ "z0-9-_ are valid" +#~ msgstr "" +#~ "Caracter '%c' inválido no parâmetro color_name de gtk:custom, apenas são " +#~ "válidos os carateres A-Za-z0-9-_" + +#~ msgid "" +#~ "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " +#~ "fit the format" +#~ msgstr "" +#~ "Formato Gtk:custom é \"gtk:custom(color_name,fallback)\", \"%s\" não " +#~ "cumpre o formato" + +#~ msgid "" +#~ "GTK color specification must have the state in brackets, e.g. gtk:" +#~ "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "Especificação de cor GTK tem de ter o estado entre parentesis retos, por " +#~ "ex. gtk:fg[NORMAL] em que NORMAL é o estado; incapaz de processar \"%s\"" + +#~ msgid "" +#~ "GTK color specification must have a close bracket after the state, e.g. " +#~ "gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "Especificação de cor GTK tem de ter um parentesis reto de fecho após o " +#~ "estado, por ex. gtk:fg[NORMAL] em que NORMAL é o estado; incapaz de " +#~ "processar \"%s\"" + +#~ msgid "Did not understand state \"%s\" in color specification" +#~ msgstr "Incapaz de compreender o estado \"%s\" na especificação de cor" + +#~ msgid "Did not understand color component \"%s\" in color specification" +#~ msgstr "" +#~ "Incapaz de compreender componente de cor \"%s\" na especificação de cor" + +#~ msgid "" +#~ "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit " +#~ "the format" +#~ msgstr "" +#~ "Formato de mistura é \"blend/bg_color/fg_color/alpha\", \"%s\" não cumpre " +#~ "o formato" + +#~ msgid "Could not parse alpha value \"%s\" in blended color" +#~ msgstr "Incapaz de processar o valor alfa \"%s\" na mistura de cor" + +#~ msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" +#~ msgstr "Valor alfa \"%s\" na mistura de cor não está entre 0.0 e 1.0" + +#~ msgid "" +#~ "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the " +#~ "format" +#~ msgstr "" +#~ "Formato de sombra é \"shade/base_color/fator\", \"%s\" não cumpre o " +#~ "formato" + +#~ msgid "Could not parse shade factor \"%s\" in shaded color" +#~ msgstr "" +#~ "Incapaz de processar o valor de fator de sombra \"%s\" na cor sombreada" + +#~ msgid "Shade factor \"%s\" in shaded color is negative" +#~ msgstr "Fator de sombreado \"%s\" na cor sombreada é negativo" + +#~ msgid "Could not parse color \"%s\"" +#~ msgstr "Incapaz de processar cor \"%s\"" + +#~ msgid "Coordinate expression contains character '%s' which is not allowed" +#~ msgstr "Expressão de coordenada contém caracter '%s' que não é permitido" + +#~ msgid "" +#~ "Coordinate expression contains floating point number '%s' which could not " +#~ "be parsed" +#~ msgstr "" +#~ "Expressão de coordenada contém número decimal '%s' que não pode ser " +#~ "processado" + +#~ msgid "" +#~ "Coordinate expression contains integer '%s' which could not be parsed" +#~ msgstr "" +#~ "Expressão de coordenada contém número inteiro '%s' que não pode ser " +#~ "processado" -#: ../src/ui/theme.c:1450 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "Factor de sombreado \"%s\" na cor sombreada é negativo" +#~ msgid "" +#~ "Coordinate expression contained unknown operator at the start of this " +#~ "text: \"%s\"" +#~ msgstr "" +#~ "Expressão de coordenada contém operador desconhecido no início deste " +#~ "texto: \"%s\"" -#: ../src/ui/theme.c:1479 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Incapaz de processar cor \"%s\"" +#~ msgid "Coordinate expression was empty or not understood" +#~ msgstr "Expressão de coordenada está vazia ou não foi compreendida" -#: ../src/ui/theme.c:1790 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "Expressão de coordenada contém caracter '%s' que não é permitido" +#~ msgid "Coordinate expression results in division by zero" +#~ msgstr "Expressão de coordenada resulta em divisão por zero" -#: ../src/ui/theme.c:1817 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "" -"Expressão de coordenada contém número decimal '%s' que não pode ser " -"processado" +#~ msgid "" +#~ "Coordinate expression tries to use mod operator on a floating-point number" +#~ msgstr "" +#~ "Expressão de coordenada tenta utilizar operador mod num número decimal" -#: ../src/ui/theme.c:1831 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "" -"Expressão de coordenada contém número inteiro '%s' que não pode ser " -"processado" +#~ msgid "" +#~ "Coordinate expression has an operator \"%s\" where an operand was expected" +#~ msgstr "" +#~ "Expressão de coordenada tem um operador \"%s\" onde era esperado um " +#~ "operando" -#: ../src/ui/theme.c:1953 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "" -"Expressão de coordenada contém operador desconhecido no início deste texto: " -"\"%s\"" +#~ msgid "Coordinate expression had an operand where an operator was expected" +#~ msgstr "" +#~ "Expressão de coordenada tem um operando onde era esperado um operador" -#: ../src/ui/theme.c:2010 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "Expressão de coordenada está vazia ou não foi compreendida" +#~ msgid "Coordinate expression ended with an operator instead of an operand" +#~ msgstr "" +#~ "Expressão de coordenada terminou com um operador em vez de um operando" -#: ../src/ui/theme.c:2121 ../src/ui/theme.c:2131 ../src/ui/theme.c:2165 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "Expressão de coordenada resulta em divisão por zero" +#~ msgid "" +#~ "Coordinate expression has operator \"%c\" following operator \"%c\" with " +#~ "no operand in between" +#~ msgstr "" +#~ "Expressão de coordenada tem o operador \"%c\" seguido do operador \"%c\" " +#~ "sem um operando entre os dois" -#: ../src/ui/theme.c:2173 -#, c-format -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "Expressão de coordenada tenta utilizar operador mod num número decimal" +#~ msgid "Coordinate expression had unknown variable or constant \"%s\"" +#~ msgstr "" +#~ "Expressão de coordenada tem uma variável ou constante \"%s\" desconhecida" -#: ../src/ui/theme.c:2229 -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "" -"Expressão de coordenada tem um operador \"%s\" onde era esperado um operando" +#~ msgid "Coordinate expression parser overflowed its buffer." +#~ msgstr "O processador de expressão de coordenada transbordou o seu buffer." -#: ../src/ui/theme.c:2238 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "Expressão de coordenada tem um operando onde era esperado um operador" +#~ msgid "" +#~ "Coordinate expression had a close parenthesis with no open parenthesis" +#~ msgstr "" +#~ "Expressão de coordenada tem um fecho de parentesis sem a respetiva " +#~ "abertura" -#: ../src/ui/theme.c:2246 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "Expressão de coordenada terminou com um operador em vez de um operando" +#~ msgid "" +#~ "Coordinate expression had an open parenthesis with no close parenthesis" +#~ msgstr "" +#~ "Expressão de coordenada tem uma abertura de parentesis sem o respetivo " +#~ "fecho" -#: ../src/ui/theme.c:2256 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" -"Expressão de coordenada tem o operador \"%c\" seguido do operador \"%c\" sem " -"um operando entre os dois" +#~ msgid "Coordinate expression doesn't seem to have any operators or operands" +#~ msgstr "Expressão de coordenada não aparenta ter operadores nem operandos" -#: ../src/ui/theme.c:2407 ../src/ui/theme.c:2452 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "" -"Expressão de coordenada tem uma variável ou constante \"%s\" desconhecida" +#~ msgid "Theme contained an expression that resulted in an error: %s\n" +#~ msgstr "O tema continha uma expressão que resultou num erro: %s\n" -#: ../src/ui/theme.c:2506 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "O processador de expressão de coordenada transbordou o seu buffer." +#~ msgid "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " +#~ "specified for this frame style" +#~ msgstr "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"qualquercoisa\"/> tem de " +#~ "ser especificado para este estilo de moldura" -#: ../src/ui/theme.c:2535 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "" -"Expressão de coordenada tem um fecho de parentesis sem a respectiva abertura" +#~ msgid "" +#~ "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/" +#~ ">" +#~ msgstr "" +#~ "Falta <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"qualquercoisa" +#~ "\"/>" -#: ../src/ui/theme.c:2599 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "" -"Expressão de coordenada tem uma abertura de parentesis sem o respectivo fecho" +#~ msgid "Failed to load theme \"%s\": %s\n" +#~ msgstr "Falha ao ler tema \"%s\": %s\n" -#: ../src/ui/theme.c:2610 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "Expressão de coordenada não aparenta ter operadores nem operandos" +#~ msgid "No <%s> set for theme \"%s\"" +#~ msgstr "Nenhum <%s> definido para o tema \"%s\"" -#: ../src/ui/theme.c:2822 ../src/ui/theme.c:2842 ../src/ui/theme.c:2862 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "O tema continha uma expressão que resultou num erro: %s\n" +#~ msgid "" +#~ "No frame style set for window type \"%s\" in theme \"%s\", add a <window " +#~ "type=\"%s\" style_set=\"whatever\"/> element" +#~ msgstr "" +#~ "Nenhum estilo de moldura definido para tipo de janela \"%s\" no tema \"%s" +#~ "\", adicione um elemento <window type=\"%s\" style_set=\"qualquer\"/>" -#: ../src/ui/theme.c:4533 -#, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"qualquercoisa\"/> tem de ser " -"especificado para este estilo de moldura" +#~ msgid "" +#~ "User-defined constants must begin with a capital letter; \"%s\" does not" +#~ msgstr "" +#~ "Constante definida pelo utilizador tem de começar com uma maiúscula; \"%s" +#~ "\" não começa" -#: ../src/ui/theme.c:5066 ../src/ui/theme.c:5091 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" -"Falta <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"qualquercoisa\"/" -">" +#~ msgid "Constant \"%s\" has already been defined" +#~ msgstr "Constante \"%s\" já foi definida" -#: ../src/ui/theme.c:5139 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Falha ao ler tema \"%s\": %s\n" +#~ msgid "No \"%s\" attribute on element <%s>" +#~ msgstr "Nenhum atributo \"%s\" no elemento <%s>" -#: ../src/ui/theme.c:5275 ../src/ui/theme.c:5282 ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 ../src/ui/theme.c:5303 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "Nenhum <%s> definido para o tema \"%s\"" +#~ msgid "Line %d character %d: %s" +#~ msgstr "Linha %d caracter %d: %s" -#: ../src/ui/theme.c:5311 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" -"Nenhum estilo de moldura definido para tipo de janela \"%s\" no tema \"%s\", " -"adicione um elemento <window type=\"%s\" style_set=\"qualquer\"/>" +#~ msgid "Attribute \"%s\" repeated twice on the same <%s> element" +#~ msgstr "Atributo \"%s\" repetido duas vezes no mesmo elemento <%s>" -#: ../src/ui/theme.c:5709 ../src/ui/theme.c:5771 ../src/ui/theme.c:5834 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" -"Constante definida pelo utilizador tem de começar com uma maiúscula; \"%s\" " -"não começa" +#~ msgid "Attribute \"%s\" is invalid on <%s> element in this context" +#~ msgstr "Atributo \"%s\" é inválido no elemento <%s> neste contexto" -#: ../src/ui/theme.c:5717 ../src/ui/theme.c:5779 ../src/ui/theme.c:5842 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "Constante \"%s\" já foi definida" +#~ msgid "Could not parse \"%s\" as an integer" +#~ msgstr "Incapaz de processar \"%s\" como um inteiro" -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. -#. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "Nenhum atributo \"%s\" no elemento <%s>" +#~ msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +#~ msgstr "Incapaz de compreender últimos carateres \"%s\" na expressão \"%s\"" -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Linha %d caracter %d: %s" +#~ msgid "Integer %ld must be positive" +#~ msgstr "Inteiro %ld tem de ser positivo" -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "Atributo \"%s\" repetido duas vezes no mesmo elemento <%s>" +#~ msgid "Integer %ld is too large, current max is %d" +#~ msgstr "Inteiro %ld é demasiado grande, máx atual é %d" -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "Atributo \"%s\" é inválido no elemento <%s> neste contexto" +#~ msgid "Could not parse \"%s\" as a floating point number" +#~ msgstr "Incapaz de processar \"%s\" como um númerico decimal" -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "Incapaz de processar \"%s\" como um inteiro" +#~ msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" +#~ msgstr "Valores boleanos têm de ser \"true\" ou \"false\" não \"%s\"" -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "Incapaz de compreender últimos caracteres \"%s\" na expressão \"%s\"" +#~ msgid "Angle must be between 0.0 and 360.0, was %g\n" +#~ msgstr "Ângulo tem de ser entre 0.0 e 360.0, era %g\n" -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "Inteiro %ld tem de ser positivo" +#~ msgid "" +#~ "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" +#~ msgstr "" +#~ "Alfa tem de ser entre 0.0 (invisível) e 1.0 (completamente opaco), era " +#~ "%g\n" -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "Inteiro %ld é demasiado grande, máx actual é %d" +#~ msgid "" +#~ "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," +#~ "large,x-large,xx-large)\n" +#~ msgstr "" +#~ "Título de escala \"%s\" inválido (tem de ser um de xx-small,x-small,small," +#~ "medium,large,x-large,xx-large)\n" -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "Incapaz de processar \"%s\" como um númerico decimal" +#~ msgid "<%s> name \"%s\" used a second time" +#~ msgstr "Nome \"%s\" de <%s> utilizado uma segunda vez" -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "Valores boleanos têm de ser \"true\" ou \"false\" não \"%s\"" +#~ msgid "<%s> parent \"%s\" has not been defined" +#~ msgstr "Pai \"%s\" de <%s> não foi definido" -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "Ângulo tem de ser entre 0.0 e 360.0, era %g\n" +#~ msgid "<%s> geometry \"%s\" has not been defined" +#~ msgstr "Geometria \"%s\" de <%s> não foi definida" -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" -"Alfa tem de ser entre 0.0 (invisível) e 1.0 (completamente opaco), era %g\n" +#~ msgid "<%s> must specify either a geometry or a parent that has a geometry" +#~ msgstr "" +#~ "<%s> tem de especificar ou uma geometria ou um pai que tenha geometria" -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"Título de escala \"%s\" inválido (tem de ser um de xx-small,x-small,small," -"medium,large,x-large,xx-large)\n" +#~ msgid "You must specify a background for an alpha value to be meaningful" +#~ msgstr "" +#~ "Tem de especificar um fundo para que o valor alfa tenha algum significado" -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "Nome \"%s\" de <%s> utilizado uma segunda vez" +#~ msgid "Unknown type \"%s\" on <%s> element" +#~ msgstr "Tipo \"%s\" desconhecido no elemento <%s>" -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "Pai \"%s\" de <%s> não foi definido" +#~ msgid "Unknown style_set \"%s\" on <%s> element" +#~ msgstr "Style_set \"%s\" desconhecido no elemento <%s>" -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "Geometria \"%s\" de <%s> não foi definida" +#~ msgid "Window type \"%s\" has already been assigned a style set" +#~ msgstr "Tipo de janela \"%s\" já tem um tipo de estilo atribuido" -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "<%s> tem de especificar ou uma geometria ou um pai que tenha geometria" +#~ msgid "Element <%s> is not allowed below <%s>" +#~ msgstr "Elemento <%s> no é permitido abaixo de <%s>" -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "" -"Tem de especificar um fundo para que o valor alfa tenha algum significado" +#~ msgid "" +#~ "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio" +#~ "\" for buttons" +#~ msgstr "" +#~ "Impossível especificar ambos \"button_width\"/\"button_height\" e " +#~ "\"aspect_ratio\" para botões" -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Tipo \"%s\" desconhecido no elemento <%s>" +#~ msgid "Distance \"%s\" is unknown" +#~ msgstr "Distância \"%s\" é desconhecida" -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "Style_set \"%s\" desconhecido no elemento <%s>" +#~ msgid "Aspect ratio \"%s\" is unknown" +#~ msgstr "Rácio de aparência \"%s\" é desconhecido" -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "Tipo de janela \"%s\" já tem um tipo de estilo atribuido" - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "Elemento <%s> no é permitido abaixo de <%s>" +#~ msgid "Border \"%s\" is unknown" +#~ msgstr "Margem \"%s\" é desconhecida" -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" -msgstr "" -"Impossível especificar ambos \"button_width\"/\"button_height\" e " -"\"aspect_ratio\" para botões" +#~ msgid "No \"start_angle\" or \"from\" attribute on element <%s>" +#~ msgstr "Nenhum atributo \"start_angle\" ou \"from\" no elemento <%s>" -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "Distância \"%s\" é desconhecida" +#~ msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" +#~ msgstr "Nenhum atributo \"extent_angle\" ou \"to\" no elemento <%s>" -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "Rácio de aparência \"%s\" é desconhecido" +#~ msgid "Did not understand value \"%s\" for type of gradient" +#~ msgstr "Incapaz de compreender valor \"%s\" para tipo de gradiente" -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "Margem \"%s\" é desconhecida" +#~ msgid "Did not understand fill type \"%s\" for <%s> element" +#~ msgstr "Incapaz de compreender tipo de enchimento \"%s\" para elemento <%s>" -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "Nenhum atributo \"start_angle\" ou \"from\" no elemento <%s>" +#~ msgid "Did not understand state \"%s\" for <%s> element" +#~ msgstr "Incapaz de compreender estado \"%s\" para elemento <%s>" -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "Nenhum atributo \"extent_angle\" ou \"to\" no elemento <%s>" +#~ msgid "Did not understand shadow \"%s\" for <%s> element" +#~ msgstr "Incapaz de compreender sombra \"%s\" para elemento <%s>" -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "Incapaz de compreender valor \"%s\" para tipo de gradiente" +#~ msgid "Did not understand arrow \"%s\" for <%s> element" +#~ msgstr "Incapaz de compreender seta \"%s\" para elemento <%s>" -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "Incapaz de compreender tipo de enchimento \"%s\" para elemento <%s>" +#~ msgid "No <draw_ops> called \"%s\" has been defined" +#~ msgstr "Não foi definido nenhum <draw_ops> chamado \"%s\"" -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "Incapaz de compreender estado \"%s\" para elemento <%s>" +#~ msgid "Including draw_ops \"%s\" here would create a circular reference" +#~ msgstr "Incluir aqui draw_ops \"%s\" iria criar uma referência circular" -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "Incapaz de compreender sombra \"%s\" para elemento <%s>" +#~ msgid "Unknown position \"%s\" for frame piece" +#~ msgstr "Posição \"%s\" desconhecida para peça de moldura" -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "Incapaz de compreender seta \"%s\" para elemento <%s>" +#~ msgid "Frame style already has a piece at position %s" +#~ msgstr "Estilo de moldura já tem uma peça na posição %s" -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "Não foi definido nenhum <draw_ops> chamado \"%s\"" +#~ msgid "No <draw_ops> with the name \"%s\" has been defined" +#~ msgstr "Não foi definido nenhum <draw_ops> com o nome \"%s\"" -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "Incluir aqui draw_ops \"%s\" iria criar uma referência circular" +#~ msgid "Unknown function \"%s\" for button" +#~ msgstr "Função \"%s\" desconhecida para botão" -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Posição \"%s\" desconhecida para peça de moldura" +#~ msgid "Button function \"%s\" does not exist in this version (%d, need %d)" +#~ msgstr "Função do botão \"%s\" não existe nesta versão (%d, necessita %d)" -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "Estilo de moldura já tem uma peça na posição %s" +#~ msgid "Unknown state \"%s\" for button" +#~ msgstr "Estado \"%s\" desconhecido para botão" -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "Não foi definido nenhum <draw_ops> com o nome \"%s\"" +#~ msgid "Frame style already has a button for function %s state %s" +#~ msgstr "Estilo de moldura já tem um botão para a função %s estado %s" -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Função \"%s\" desconhecida para botão" +#~ msgid "\"%s\" is not a valid value for focus attribute" +#~ msgstr "\"%s\" não é um valor válido para o atributo de foco" -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "Função do botão \"%s\" não existe nesta versão (%d, necessita %d)" +#~ msgid "\"%s\" is not a valid value for state attribute" +#~ msgstr "\"%s\" não é um valor válido para o atributo de estado" -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Estado \"%s\" desconhecido para botão" +#~ msgid "A style called \"%s\" has not been defined" +#~ msgstr "Não foi definido um estilo chamado \"%s\"" -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "Estilo de moldura já tem um botão para a função %s estado %s" +#~ msgid "\"%s\" is not a valid value for resize attribute" +#~ msgstr "\"%s\" não é um valor válido para o atributo redimensionar" -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "\"%s\" não é um valor válido para o atributo de foco" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized/shaded " +#~ "states" +#~ msgstr "" +#~ "Não deveria ter atributo \"resize\" no elemento <%s> para os estados " +#~ "maximizado/sombreado" -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "\"%s\" não é um valor válido para o atributo de estado" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized states" +#~ msgstr "" +#~ "Não deveria ter atributo \"resize\" no elemento <%s> para os estados " +#~ "maximizados" -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "Não foi definido um estilo chamado \"%s\"" +#~ msgid "Style has already been specified for state %s resize %s focus %s" +#~ msgstr "" +#~ "Estilo já foi especificado para o estado %s redimensionamento %s foco %s" -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "\"%s\" não é um valor válido para o atributo redimensionar" +#~ msgid "Style has already been specified for state %s focus %s" +#~ msgstr "Estilo já foi especificado para o estado %s foco %s" -#: ../src/ui/theme-parser.c:3147 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" -"Não deveria ter atributo \"resize\" no elemento <%s> para os estados " -"maximizado/sombreado" +#~ msgid "" +#~ "Can't have a two draw_ops for a <piece> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Impossível ter dois draw_ops num elemento <piece> (tema especificou um " +#~ "atributo draw_ops e também um elemento <draw_ops>, ou especificou dois " +#~ "elementos)" -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "" -"Não deveria ter atributo \"resize\" no elemento <%s> para os estados " -"maximizados" +#~ msgid "" +#~ "Can't have a two draw_ops for a <button> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Impossível ter dois draw_ops num elemento <button> (tema especificou um " +#~ "atributo draw_ops e também um elemento <draw_ops>, ou especificou dois " +#~ "elementos)" -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "" -"Estilo já foi especificado para o estado %s redimensionamento %s foco %s" +#~ msgid "" +#~ "Can't have a two draw_ops for a <menu_icon> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Impossível ter dois draw_ops num elemento <menu_icon> (tema especificou " +#~ "um atributo draw_ops e também um elemento <draw_ops>, ou especificou dois " +#~ "elementos)" -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "Estilo já foi especificado para o estado %s foco %s" +#~ msgid "Bad version specification '%s'" +#~ msgstr "Especificação de versão '%s' inválida" -#: ../src/ui/theme-parser.c:3294 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Impossível ter dois draw_ops num elemento <piece> (tema especificou um " -"atributo draw_ops e também um elemento <draw_ops>, ou especificou dois " -"elementos)" +#~ msgid "" +#~ "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" +#~ "theme-2.xml" +#~ msgstr "" +#~ "O atributo \"version\" não pode ser utilizado nos ficheiros metacity-" +#~ "theme1.xml nem metacity-theme2.xml" -#: ../src/ui/theme-parser.c:3332 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Impossível ter dois draw_ops num elemento <button> (tema especificou um " -"atributo draw_ops e também um elemento <draw_ops>, ou especificou dois " -"elementos)" +#~ msgid "" +#~ "Theme requires version %s but latest supported theme version is %d.%d" +#~ msgstr "" +#~ "Tema requer a versão %s mas a mais recente versão de tema suportado é a " +#~ "%d.%d" -#: ../src/ui/theme-parser.c:3370 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Impossível ter dois draw_ops num elemento <menu_icon> (tema especificou um " -"atributo draw_ops e também um elemento <draw_ops>, ou especificou dois " -"elementos)" +#~ msgid "Outermost element in theme must be <metacity_theme> not <%s>" +#~ msgstr "Elemento mais externo tem de ser <metacity_theme> não <%s>" -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "Especificação de versão '%s' inválida" +#~ msgid "" +#~ "Element <%s> is not allowed inside a name/author/date/description element" +#~ msgstr "" +#~ "Elemento <%s> não é permitido dentro de um elemento name/author/date/" +#~ "description" -#: ../src/ui/theme-parser.c:3507 -msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" -msgstr "" -"O atributo \"version\" não pode ser utilizado nos ficheiros metacity-theme-1." -"xml nem metacity-theme-2.xml" +#~ msgid "Element <%s> is not allowed inside a <constant> element" +#~ msgstr "Elemento <%s> não é permitido dentro de um elemento <constant>" -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "" -"Tema requer a versão %s mas a mais recente versão de tema suportado é a %d.%d" +#~ msgid "" +#~ "Element <%s> is not allowed inside a distance/border/aspect_ratio element" +#~ msgstr "" +#~ "Elemento <%s> não é permitido dentro de um elemento distance/border/" +#~ "aspect_ratio" -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "Elemento mais externo tem de ser <metacity_theme> não <%s>" +#~ msgid "Element <%s> is not allowed inside a draw operation element" +#~ msgstr "" +#~ "Elemento <%s> não é permitido dentro de um elemento de operação de desenho" -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "" -"Elemento <%s> não é permitido dentro de um elemento name/author/date/" -"description" +#~ msgid "Element <%s> is not allowed inside a <%s> element" +#~ msgstr "Elemento <%s> não é permitido dentro de um elemento <%s>" -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "Elemento <%s> não é permitido dentro de um elemento <constant>" +#~ msgid "No draw_ops provided for frame piece" +#~ msgstr "Nenhum draw_ops indicado para peça de moldura" -#: ../src/ui/theme-parser.c:3599 -#, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "" -"Elemento <%s> não é permitido dentro de um elemento distance/border/" -"aspect_ratio" +#~ msgid "No draw_ops provided for button" +#~ msgstr "Nenhum draw_ops indicado para botão" -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "" -"Elemento <%s> não é permitido dentro de um elemento de operação de desenho" +#~ msgid "No text is allowed inside element <%s>" +#~ msgstr "Não é permitido texto dentro do elemento <%s>" -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "Elemento <%s> não é permitido dentro de um elemento <%s>" +#~ msgid "<%s> specified twice for this theme" +#~ msgstr "<%s> especificado duas vezes para este tema" -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "Nenhum draw_ops indicado para peça de moldura" +#~ msgid "Failed to find a valid file for theme %s\n" +#~ msgstr "Falha ao procurar um ficheiro válido para o tema %s\n" -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "Nenhum draw_ops indicado para botão" +#~ msgid "Usage: %s\n" +#~ msgstr "Utilização: %s\n" -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "Não é permitido texto dentro do elemento <%s>" +#~ msgid "_Windows" +#~ msgstr "_Janelas" -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "<%s> especificado duas vezes para este tema" +#~ msgid "_Dialog" +#~ msgstr "_Diálogo" -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Falha ao procurar um ficheiro válido para o tema %s\n" +#~ msgid "_Modal dialog" +#~ msgstr "Diálogo _modal" -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "_Janelas" +#~ msgid "_Utility" +#~ msgstr "_Utilitário" -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "_Diálogo" +#~ msgid "_Splashscreen" +#~ msgstr "_Ecrã de logotipo" -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "Diálogo _modal" +#~ msgid "_Top dock" +#~ msgstr "Doca _superior" -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "_Utilitário" +#~ msgid "_Bottom dock" +#~ msgstr "Doca _inferior" -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "_Ecrã de logotipo" +#~ msgid "_Left dock" +#~ msgstr "Doca _esquerda" -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "Doca _superior" +#~ msgid "_Right dock" +#~ msgstr "Doca _direita" -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "Doca _inferior" +#~ msgid "_All docks" +#~ msgstr "_Todas as docas" -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "Doca _esquerda" +#~ msgid "Des_ktop" +#~ msgstr "Áre_a de Trabalho" -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "Doca _direita" +#~ msgid "Open another one of these windows" +#~ msgstr "Abrir outra destas janelas" -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "_Todas as docas" +#~ msgid "This is a demo button with an 'open' icon" +#~ msgstr "Este é um botão de demonstração com um ícone 'abrir'" -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "Áre_a de Trabalho" +#~ msgid "This is a demo button with a 'quit' icon" +#~ msgstr "Este é um botão de demonstração com um ícone 'sair'" -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "Abrir outra destas janelas" +#~ msgid "This is a sample message in a sample dialog" +#~ msgstr "Esta é uma mensagem de exemplo num diálogo de exemplo" -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "Este é um botão de demonstração com um ícone 'abrir'" +#~ msgid "Fake menu item %d\n" +#~ msgstr "Item de menu %d falso\n" -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "Este é um botão de demonstração com um ícone 'sair'" +#~ msgid "Border-only window" +#~ msgstr "Janela apenas com margem" -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "Esta é uma mensagem de exemplo num diálogo de exemplo" +#~ msgid "Bar" +#~ msgstr "Barra" -#: ../src/ui/theme-viewer.c:328 -#, c-format -msgid "Fake menu item %d\n" -msgstr "Item de menu %d falso\n" +#~ msgid "Normal Application Window" +#~ msgstr "Janela Normal de Aplicação" -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "Janela apenas com margem" +#~ msgid "Dialog Box" +#~ msgstr "Janela de Diálogo" -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "Barra" +#~ msgid "Modal Dialog Box" +#~ msgstr "Janela de Diálogo Modal" -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "Janela Normal de Aplicação" +#~ msgid "Utility Palette" +#~ msgstr "Paleta de Utilitários" -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "Janela de Diálogo" +#~ msgid "Torn-off Menu" +#~ msgstr "Menu Destacável" -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "Janela de Diálogo Modal" +#~ msgid "Border" +#~ msgstr "Margem" -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "Paleta de Utilitários" +#~ msgid "Attached Modal Dialog" +#~ msgstr "Diálogo Modal Anexado" -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "Menu Destacável" +#~ msgid "Button layout test %d" +#~ msgstr "Teste %d de disposição de botão" -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "Margem" +#~ msgid "%g milliseconds to draw one window frame" +#~ msgstr "%g milisegundos para desenhar uma moldura de janela" -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "Diálogo Modal Anexado" +#~ msgid "Usage: metacity-theme-viewer [THEMENAME]\n" +#~ msgstr "Utilização: metacity-theme-viewer [NOMETEMA]\n" -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "Teste %d de disposição de botão" +#~ msgid "Error loading theme: %s\n" +#~ msgstr "Erro ao ler tema: %s\n" -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g milisegundos para desenhar uma moldura de janela" +#~ msgid "Loaded theme \"%s\" in %g seconds\n" +#~ msgstr "Tema \"%s\" lido em %g segundos\n" -#: ../src/ui/theme-viewer.c:813 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Utilização: metacity-theme-viewer [NOMETEMA]\n" +#~ msgid "Normal Title Font" +#~ msgstr "Fonte Normal de Título" -#: ../src/ui/theme-viewer.c:820 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "Erro ao ler tema: %s\n" +#~ msgid "Small Title Font" +#~ msgstr "Fonte Pequena de Título" -#: ../src/ui/theme-viewer.c:826 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "Tema \"%s\" lido em %g segundos\n" +#~ msgid "Large Title Font" +#~ msgstr "Fonte Grande de Título" -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "Fonte Normal de Título" +#~ msgid "Button Layouts" +#~ msgstr "Disposição de Botões" -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "Fonte Pequena de Título" +#~ msgid "Benchmark" +#~ msgstr "Análise de Desempenho" -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "Fonte Grande de Título" +#~ msgid "Window Title Goes Here" +#~ msgstr "Título da Janela Fica Aqui" -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "Disposição de Botões" +#~ msgid "" +#~ "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and " +#~ "%g seconds wall clock time including X server resources (%g milliseconds " +#~ "per frame)\n" +#~ msgstr "" +#~ "Desenhadas %d frames em %g segundos no lado do cliente (%g milisegundos " +#~ "por frame) e %g segundos globais incluindo recursos do servidor X (%g " +#~ "milisegundos por frame)\n" -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "Análise de Desempenho" +#~ msgid "position expression test returned TRUE but set error" +#~ msgstr "" +#~ "teste de expressão de posição devolveu VERDADEIRO mas definiu um erro" -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "Título da Janela Fica Aqui" +#~ msgid "position expression test returned FALSE but didn't set error" +#~ msgstr "" +#~ "teste de expressão de posição devolveu FALSO mas não definiu um erro" -#: ../src/ui/theme-viewer.c:1047 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"Desenhadas %d frames em %g segundos no lado do cliente (%g milisegundos por " -"frame) e %g segundos globais incluindo recursos do servidor X (%g " -"milisegundos por frame)\n" +#~ msgid "Error was expected but none given" +#~ msgstr "Era esperado um erro mas nenhum foi devolvido" -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "teste de expressão de posição devolveu VERDADEIRO mas definiu um erro" +#~ msgid "Error %d was expected but %d given" +#~ msgstr "Era esperado o erro %d mas foi devolvido o %d" -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "teste de expressão de posição devolveu FALSO mas não definiu um erro" +#~ msgid "Error not expected but one was returned: %s" +#~ msgstr "Não era esperado nenhum erro mas foi devolvido um: %s" -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "Era esperado um erro mas nenhum foi devolvido" +#~ msgid "x value was %d, %d was expected" +#~ msgstr "valor x era %d, era esperado %d" -#: ../src/ui/theme-viewer.c:1274 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "Era esperado o erro %d mas foi devolvido o %d" +#~ msgid "y value was %d, %d was expected" +#~ msgstr "valor y era %d, era esperado %d" -#: ../src/ui/theme-viewer.c:1280 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "Não era esperado nenhum erro mas foi devolvido um: %s" +#~ msgid "" +#~ "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" +#~ msgstr "" +#~ "expressões de coordenada %d processadas em %g segundos (%g segundos em " +#~ "média)\n" -#: ../src/ui/theme-viewer.c:1284 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "valor x era %d, era esperado %d" +#~ msgid "Minimize window" +#~ msgstr "Minimizar a janela" -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "valor y era %d, era esperado %d" +#~ msgid "Comma-separated list of compositor plugins" +#~ msgstr "Lista separada por vírgulas de plugins de compositor" -#: ../src/ui/theme-viewer.c:1352 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "" -"expressões de coordenada %d processadas em %g segundos (%g segundos em " -"média)\n" +#~ msgid "Live Hidden Windows" +#~ msgstr "Janelas Escondidas Ativas" -#~ msgid "Switch to workspace 1" -#~ msgstr "Mover para a área de trabalho 1" +#~ msgid "" +#~ "Determines whether hidden windows (i.e., minimized windows and windows on " +#~ "other workspaces than the current one) should be kept alive." +#~ msgstr "" +#~ "Determina se as janelas escondidas (ex: janelas minimizadas e janelas " +#~ "noutras áreas de trabalho que não a atual) deverão ser mantidas ativas." -#~ msgid "Switch to workspace 2" -#~ msgstr "Mover para a área de trabalho 2" +#~ msgid "Close Window" +#~ msgstr "Fechar Janela" -#~ msgid "Switch to workspace 3" -#~ msgstr "Mover para a área de trabalho 3" +#~ msgid "Window Menu" +#~ msgstr "Menu de Janela" -#~ msgid "Switch to workspace 4" -#~ msgstr "Mover para a área de trabalho 4" +#~ msgid "Minimize Window" +#~ msgstr "Minimizar Janela" -#~ msgid "Switch to workspace 5" -#~ msgstr "Mover para a área de trabalho 5" +#~ msgid "Maximize Window" +#~ msgstr "Maximizar Janela" -#~ msgid "Switch to workspace 6" -#~ msgstr "Mover para a área de trabalho 6" +#~ msgid "Restore Window" +#~ msgstr "Restaurar a Janela" -#~ msgid "Switch to workspace 7" -#~ msgstr "Mover para a área de trabalho 7" +#~ msgid "Roll Up Window" +#~ msgstr "Enrolar a Janela" -#~ msgid "Switch to workspace 8" -#~ msgstr "Mover para a área de trabalho 8" +#~ msgid "Unroll Window" +#~ msgstr "Desenrolar a Janela" -#~ msgid "Switch to workspace 9" -#~ msgstr "Mover para a área de trabalho 9" +#~ msgid "Keep Window On Top" +#~ msgstr "Manter a Janela no Topo" -#~ msgid "Switch to workspace 10" -#~ msgstr "Mover para a área de trabalho 10" +#~ msgid "Remove Window From Top" +#~ msgstr "Remover a Janela do Topo" -#~ msgid "Switch to workspace 11" -#~ msgstr "Mover para a área de trabalho 11" +#~ msgid "Always On Visible Workspace" +#~ msgstr "Sempre na Área de Trabalho Visível" -#~ msgid "Switch to workspace 12" -#~ msgstr "Mover para a área de trabalho 12" +#~ msgid "Put Window On Only One Workspace" +#~ msgstr "Colocar a Janela Apenas em Uma Área de Trabalho" #~ msgid "Switch to workspace on the left of the current workspace" -#~ msgstr "Mover para a área de trabalho à esquerda da actual" +#~ msgstr "Mover para a área de trabalho à esquerda da atual" #~ msgid "Switch to workspace on the right of the current workspace" -#~ msgstr "Mover para a área de trabalho à direita da actual" +#~ msgstr "Mover para a área de trabalho à direita da atual" #~ msgid "Switch to workspace above the current workspace" -#~ msgstr "Mover para a área de trabalho acima da actual" +#~ msgstr "Mover para a área de trabalho acima da atual" #~ msgid "Switch to workspace below the current workspace" -#~ msgstr "Mover para a área de trabalho abaixo da actual" +#~ msgstr "Mover para a área de trabalho abaixo da atual" #~ msgid "Move between windows of an application, using a popup window" #~ msgstr "" @@ -1745,64 +1798,22 @@ msgstr "" #~ msgstr "Iniciar ou parar a gravação da sessão" #~ msgid "Take a screenshot" -#~ msgstr "Efectuar uma captura de ecrã" +#~ msgstr "Efetuar uma captura de ecrã" #~ msgid "Take a screenshot of a window" -#~ msgstr "Efectuar uma captura de uma janela" +#~ msgstr "Efetuar uma captura de uma janela" #~ msgid "Run a terminal" #~ msgstr "Executar uma consola" -#~ msgid "Activate the window menu" -#~ msgstr "Activar o menu de janela" - -#~ msgid "Toggle fullscreen mode" -#~ msgstr "Alternar modo de ecrã completo" - -#~ msgid "Toggle maximization state" -#~ msgstr "Alternar estado de maximização" - #~ msgid "Toggle whether a window will always be visible over other windows" #~ msgstr "" #~ "Alternar se uma janela será ou não sempre visível sobre as outras janelas" -#~ msgid "Maximize window" -#~ msgstr "Maximizar a janela" - -#~ msgid "Restore window" -#~ msgstr "Restaurar a janela" - -#~ msgid "Toggle shaded state" -#~ msgstr "Alternar estado sombreado" - -#~ msgid "Minimize window" -#~ msgstr "Minimizar a janela" - -#~ msgid "Close window" -#~ msgstr "Fechar a janela" - -#~ msgid "Move window" -#~ msgstr "Mover a janela" - -#~ msgid "Resize window" -#~ msgstr "Redimensionar a janela" - #~ msgid "Toggle whether window is on all workspaces or just one" #~ msgstr "" #~ "Alternar se a janela está em todas as áreas de trabalho ou apenas numa" -#~ msgid "Move window to workspace 1" -#~ msgstr "Mover janela para a área de trabalho 1" - -#~ msgid "Move window to workspace 2" -#~ msgstr "Mover janela para a área de trabalho 2" - -#~ msgid "Move window to workspace 3" -#~ msgstr "Mover janela para a área de trabalho 3" - -#~ msgid "Move window to workspace 4" -#~ msgstr "Mover janela para a área de trabalho 4" - #~ msgid "Move window to workspace 5" #~ msgstr "Mover janela para a área de trabalho 5" @@ -1827,35 +1838,11 @@ msgstr "" #~ msgid "Move window to workspace 12" #~ msgstr "Mover janela para a área de trabalho 12" -#~ msgid "Move window one workspace to the left" -#~ msgstr "Mover a janela uma área de trabalho para a esquerda" - -#~ msgid "Move window one workspace to the right" -#~ msgstr "Mover a janela uma área de trabalho para a direita" - -#~ msgid "Move window one workspace up" -#~ msgstr "Mover a janela uma área de trabalho acima" - -#~ msgid "Move window one workspace down" -#~ msgstr "Mover a janela uma área de trabalho abaixo" - #~ msgid "Raise window if it's covered by another window, otherwise lower it" #~ msgstr "" #~ "Elevar a janela se estiver tapada por outra janela, caso contrário baixá-" #~ "la" -#~ msgid "Raise window above other windows" -#~ msgstr "Elevar janela acima de outras janelas" - -#~ msgid "Lower window below other windows" -#~ msgstr "Baixar janela abaixo de outras janelas" - -#~ msgid "Maximize window vertically" -#~ msgstr "Maximizar janela verticalmente" - -#~ msgid "Maximize window horizontally" -#~ msgstr "Maximizar janela horizontalmente" - #~ msgid "Move window to north-west (top left) corner" #~ msgstr "Mover a janela para o canto noroeste (superior esquerdo)" @@ -1922,7 +1909,7 @@ msgstr "" #~ msgstr "Erro ao definir nome da área de trabalho %d para \"%s\": %s\n" #~ msgid "Error setting live hidden windows status status: %s\n" -#~ msgstr "Erro ao definir o estado das janelas escondidas activas: %s\n" +#~ msgstr "Erro ao definir o estado das janelas escondidas ativas: %s\n" #~ msgid "Error setting no tab popup status: %s\n" #~ msgstr "Erro ao definir o estado de popup ao ciclar: %s\n" @@ -1940,10 +1927,10 @@ msgstr "" #~ msgstr "Erro IO fatal %d (%s) no ecrã '%s'.\n" #~ msgid "Turn compositing on" -#~ msgstr "Activar a composição" +#~ msgstr "Ativar a composição" #~ msgid "Turn compositing off" -#~ msgstr "Desactivar a composição" +#~ msgstr "Desativar a composição" #~ msgid "" #~ "Don't make fullscreen windows that are maximized and have no decorations" @@ -1955,7 +1942,7 @@ msgstr "" #~ msgstr "Se a janela frame/popup deverá ser apresentada ao ciclar janelas." #~ msgid "Internal argument for GObject introspection" -#~ msgstr "Argumento interno para introspecção GObject" +#~ msgstr "Argumento interno para introspeção GObject" #~ msgid "Failed to restart: %s\n" #~ msgstr "Falha ao reiniciar: %s\n" @@ -1966,9 +1953,6 @@ msgstr "" #~ msgid "Error setting clutter plugin list: %s\n" #~ msgstr "Erro ao definir a lista de plugins do clutter: %s\n" -#~ msgid "Clutter Plugins" -#~ msgstr "Plugins Clutter" - #~ msgid "Plugins to load for the Clutter-based compositing manager." #~ msgstr "Plugins a ler para o gestor de composição baseado no Clutter." @@ -2003,7 +1987,7 @@ msgstr "" #~ "O processador é razoavelmente liberal e permite capitalização maiúscula " #~ "ou minúscula e também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>\". Se " #~ "definir a opção para a expressão especial \"disabled\", não existirão " -#~ "quaisquer atalhos de teclado para esta acção." +#~ "quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The format looks like \"<Control>a\" or <Shift><Alt>F1\".\n" @@ -2021,7 +2005,7 @@ msgstr "" #~ "O processador é razoavelmente liberal e permite capitalização maiúscula " #~ "ou minúscula e também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>\". Se " #~ "definir a opção para a expressão especial \"disabled\", não existirão " -#~ "quaisquer atalhos de teclado para esta acção.\n" +#~ "quaisquer atalhos de teclado para esta ação.\n" #~ "Este atalho de teclado poderá ser invertido premindo a tecla \"shift\"; " #~ "assim, \"shift\" não poderá ser uma das teclas utilizadas." @@ -2056,13 +2040,13 @@ msgstr "" #~ "se a opção titlebar_uses_desktop_font estiver definida como verdadeira." #~ msgid "Action on title bar double-click" -#~ msgstr "Acção do duplo-clique na barra de título" +#~ msgstr "Ação do duplo-clique na barra de título" #~ msgid "Action on title bar middle-click" -#~ msgstr "Acção do clique-do-meio na barra de título" +#~ msgstr "Ação do clique-do-meio na barra de título" #~ msgid "Action on title bar right-click" -#~ msgstr "Acção do clique-direito na barra de título" +#~ msgstr "Ação do clique-direito na barra de título" #~ msgid "Arrangement of buttons on the titlebar" #~ msgstr "Disposição dos botões na barra de título" @@ -2105,14 +2089,11 @@ msgstr "" #~ msgid "Commands to run in response to keybindings" #~ msgstr "Comandos a executar em resposta a um atalho de teclado" -#~ msgid "Compositing Manager" -#~ msgstr "Gestor de Composições" - #~ msgid "Control how new windows get focus" #~ msgstr "Controla como as novas janelas obtém o foco" #~ msgid "Current theme" -#~ msgstr "Tema actual" +#~ msgstr "Tema atual" #~ msgid "Delay in milliseconds for the auto raise option" #~ msgstr "Atraso em milisegundos para a opção de elevar automaticamente" @@ -2135,19 +2116,7 @@ msgstr "" #~ "ou estragadas" #~ msgid "Enable Visual Bell" -#~ msgstr "Activar Campainha Visual" - -#~ msgid "" -#~ "If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " -#~ "the focused window will be automatically raised after a delay specified " -#~ "by the auto_raise_delay key. This is not related to clicking on a window " -#~ "to raise it, nor to entering a window during drag-and-drop." -#~ msgstr "" -#~ "Se verdadeiro, e o modo de foco for \"sloppy\" ou \"mouse\" então a " -#~ "janela com foco será automaticamente elevada após um atraso especificado " -#~ "pela chave auto_raise_delay. Isto não está relacionado com clicar numa " -#~ "janela para a elevar, nem com entrar numa janela durante um processo de " -#~ "arrastar-e-largar." +#~ msgstr "Ativar Campainha Visual" #~ msgid "" #~ "If true, ignore the titlebar_font option, and use the standard " @@ -2168,8 +2137,8 @@ msgstr "" #~ "Isto representa para muitos utilizadores uma redução significativa na " #~ "usabilidade, mas poderá permitir que aplicações antigas funcionem e pode " #~ "também ser um bom compromisso para servidores de consola. No entanto, a " -#~ "funcionalidade de molduras de linhas estará inactiva quando a " -#~ "acessibilidade estiver activa." +#~ "funcionalidade de molduras de linhas estará inativa quando a " +#~ "acessibilidade estiver ativa." #~ msgid "" #~ "If true, then Metacity works in terms of applications rather than " @@ -2181,7 +2150,7 @@ msgstr "" #~ "however, largely unimplemented at the moment." #~ msgstr "" #~ "Se verdadeiro, o Metacity funcionará em termos de aplicações e não de " -#~ "janelas. O conceito é algo abstracto, mas em geral uma configuração " +#~ "janelas. O conceito é algo abstrato, mas em geral uma configuração " #~ "baseada em aplicações é mais tipo Mac e menos tipo Windows. Ao colocar o " #~ "foco numa janela em modo aplicação, todas as janelas da aplicação são " #~ "elevadas. Também, em modo aplicação, cliques de foco não são passados " @@ -2241,22 +2210,22 @@ msgstr "" #~ msgstr "" #~ "Definir esta opção como \"false\" poderá originar um comportamento com " #~ "erros, pelo que se desaconselha a alteração do valor por omissão, que é " -#~ "\"true\". Muitas acções (por ex. clicar na área de cliente, mover ou " +#~ "\"true\". Muitas ações (por ex. clicar na área de cliente, mover ou " #~ "redimensionar a janela) normalmente elevam a janela como efeito " #~ "colateral. Definir esta opção como \"false\", o que é fortemente " -#~ "desencorajado, irá desassociar o elevar de outras acções do utilizador, e " +#~ "desencorajado, irá desassociar o elevar de outras ações do utilizador, e " #~ "ignorar pedidos de elevação gerados por aplicações. Consulte http://" #~ "bugzilla.gnome.org/show_bug.cgi?id=445447#c6. Mesmo quando esta opção é " #~ "\"false\", as janelas ainda podem ser elevadas com um alt-clique-esquerdo " #~ "em qualquer local da janela, um clique normal nas decorações da janela, " -#~ "ou por mensagens especiais de pagers, tais como pedidos de activação de " -#~ "applets de lista de tarefas. Esta opção está de momento desactivada no " +#~ "ou por mensagens especiais de pagers, tais como pedidos de ativação de " +#~ "applets de lista de tarefas. Esta opção está de momento desativada no " #~ "modo clique-para-transmitir-foco. Note que a lista de formas de elevar " #~ "janelas quando raise_on_click for \"false\" não inclui pedidos " #~ "programáticos de aplicações para elevar janelas; tais pedidos serão " #~ "ignorados independentemente do motivo do pedido. Se for um programador de " #~ "aplicações e tiver um utilizador a queixar-se que a sua aplicação não " -#~ "funciona com esta definição desactivada, diga-lhe que é _dele_ a culpa de " +#~ "funciona com esta definição desativada, diga-lhe que é _dele_ a culpa de " #~ "quebrar o seu gestor de janelas e que terá de alterar esta opção de volta " #~ "para \"true\" ou viver com o erro que deseja e originou." @@ -2267,8 +2236,8 @@ msgstr "" #~ "need to run any misbehaving applications." #~ msgstr "" #~ "Algumas aplicações ignoram as especificações de formas que resultam num " -#~ "funcionamento incorrecto do gestor de janelas. Esta opção coloca o " -#~ "Metacity num modo de correcção estrita, o que disponibiliza um interface " +#~ "funcionamento incorreto do gestor de janelas. Esta opção coloca o " +#~ "Metacity num modo de correção estrita, o que disponibiliza um interface " #~ "de utilizador mais consistente, desde que não seja necessário utilizar " #~ "nenhuma aplicação que seja problemática." @@ -2286,7 +2255,7 @@ msgstr "" #~ msgstr "" #~ "Indica ao Metacity como implementar a indicação visual de que a campainha " #~ "de sistema ou o indicador de 'campainha' de outra aplicação tocou. " -#~ "Actualmente existem dois valores válidos, \"fullscreen\", que causa um " +#~ "Atualmente existem dois valores válidos, \"fullscreen\", que causa um " #~ "flash branco-preto de ecrã completo, e \"frame_flash\" que faz com que a " #~ "barra de título da aplicação que emitiu a campainha emita um flash. Se a " #~ "aplicação que tocou a campainha for desconhecida (é normalmente o caso " @@ -2333,7 +2302,7 @@ msgstr "" #~ "razoavelmente liberal e permite capitalização maiúscula ou minúscula e " #~ "também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>\". Se " #~ "definir a opção para a expressão especial \"disabled\", não existirão " -#~ "quaisquer atalhos de teclado para esta acção." +#~ "quaisquer atalhos de teclado para esta ação." #~ msgid "The name of a workspace." #~ msgstr "O nome de uma área de trabalho." @@ -2362,7 +2331,7 @@ msgstr "" #~ "the window, and \"mouse\" means windows are focused when the mouse enters " #~ "the window and unfocused when the mouse leaves the window." #~ msgstr "" -#~ "O modo de foco de janela indica como as janelas são activadas. Tem três " +#~ "O modo de foco de janela indica como as janelas são ativadas. Tem três " #~ "valores possíveis; \"click\" significa que a janela tem de ser clicada " #~ "para obter o foco, \"sloppy\" significa que a janela fica com foco quando " #~ "o rato entra na janela, e \"mouse\" significa que a janela fica com o " @@ -2382,13 +2351,13 @@ msgstr "" #~ "window behind all the others, and 'none' which will not do anything." #~ msgstr "" #~ "Esta opção determina o efeito do clique-duplo na barra de título. As " -#~ "opções actualmente válidas são 'toggle_shade', que sombreia/remove sombra " +#~ "opções atualmente válidas são 'toggle_shade', que sombreia/remove sombra " #~ "na janela, 'toggle_maximize' que maximiza/restaura a janela, " #~ "'toggle_maximize_horizontally' e 'toggle_maximize_vertically' que irão " -#~ "maximizar/restaurar a janela apenas nessa direcção, 'minimize' que irá " +#~ "maximizar/restaurar a janela apenas nessa direção, 'minimize' que irá " #~ "minimizar a janela, 'shade' que irá enrolar a janela, 'menu' que irá " #~ "apresentar o menu da janela, 'lower' que irá colocar a janela por detrás " -#~ "de todas as outras e 'none' que não fará qualquer acção." +#~ "de todas as outras e 'none' que não fará qualquer ação." #~ msgid "" #~ "This option determines the effects of middle-clicking on the title bar. " @@ -2401,13 +2370,13 @@ msgstr "" #~ "window behind all the others, and 'none' which will not do anything." #~ msgstr "" #~ "Esta opção determina o efeito do clique-do-meio na barra de título. As " -#~ "opções actualmente válidas são 'toggle_shade', que sombreia/remove sombra " +#~ "opções atualmente válidas são 'toggle_shade', que sombreia/remove sombra " #~ "na janela, 'toggle_maximize' que maximiza/restaura a janela, " #~ "'toggle_maximize_horizontally' e 'toggle_maximize_vertically' que irão " -#~ "maximizar/restaurar a janela apenas nessa direcção, 'minimize' que irá " +#~ "maximizar/restaurar a janela apenas nessa direção, 'minimize' que irá " #~ "minimizar a janela, 'shade' que irá enrolar a janela, 'menu' que irá " #~ "apresentar o menu da janela, 'lower' que irá colocar a janela por detrás " -#~ "de todas as outras e 'none' que não fará qualquer acção." +#~ "de todas as outras e 'none' que não fará qualquer ação." #~ msgid "" #~ "This option determines the effects of right-clicking on the title bar. " @@ -2420,13 +2389,13 @@ msgstr "" #~ "window behind all the others, and 'none' which will not do anything." #~ msgstr "" #~ "Esta opção determina o efeito do clique-direito na barra de título. As " -#~ "opções actualmente válidas são 'toggle_shade', que sombreia/remove sombra " +#~ "opções atualmente válidas são 'toggle_shade', que sombreia/remove sombra " #~ "na janela, 'toggle_maximize' que maximiza/restaura a janela, " #~ "'toggle_maximize_horizontally' e 'toggle_maximize_vertically' que irão " -#~ "maximizar/restaurar a janela apenas nessa direcção, 'minimize' que irá " +#~ "maximizar/restaurar a janela apenas nessa direção, 'minimize' que irá " #~ "minimizar a janela, 'shade' que irá enrolar a janela, 'menu' que irá " #~ "apresentar o menu da janela, 'lower' que irá colocar a janela por detrás " -#~ "de todas as outras e 'none' que não fará qualquer acção." +#~ "de todas as outras e 'none' que não fará qualquer ação." #~ msgid "" #~ "This option provides additional control over how newly created windows " @@ -2444,9 +2413,9 @@ msgstr "" #~ "'bell' or 'beep'; useful for the hard-of-hearing and for use in noisy " #~ "environments." #~ msgstr "" -#~ "Activa um indicador visual de quando uma aplicação ou o sistema emitem " -#~ "uma 'campainha' ou 'beep'; útil para os deficientes auditivos e para " -#~ "utilizar em ambientes ruidosos." +#~ "Ativa um indicador visual de quando uma aplicação ou o sistema emitem uma " +#~ "'campainha' ou 'beep'; útil para os deficientes auditivos e para utilizar " +#~ "em ambientes ruidosos." #~ msgid "Use standard system font in window titles" #~ msgstr "Utilizar fonte de sistema standard nos títulos das janelas" @@ -2456,7 +2425,7 @@ msgstr "" #~ msgid "Whether raising should be a side-effect of other user interactions" #~ msgstr "" -#~ "Se elevar deverá ou não ser um efeito secundário de outras acções do " +#~ "Se elevar deverá ou não ser um efeito secundário de outras ações do " #~ "utilizador" #~ msgid "Whether to resize with the right button" @@ -2530,12 +2499,11 @@ msgstr "" #~ "user actions, and ignore raise requests generated by applications. See " #~ "http://bugzilla.gnome.org/show_bug.cgi?id=445447#c6." #~ msgstr "" -#~ "Muitas acções (por ex. clicar na área de cliente, mover ou redimensionar " -#~ "a janela) normalmente elevam a janela como efeito secundário. Definir " -#~ "esta opção como falsa, o que é muito desaconselhável, irá desassociar o " -#~ "elevar de outras acções do utilizador e ignorar pedidos de elevação " -#~ "gerados pelas aplicações. Consulte http://bugzilla.gnome.org/show_bug.cgi?" -#~ "id=445447#c6." +#~ "Muitas ações (por ex. clicar na área de cliente, mover ou redimensionar a " +#~ "janela) normalmente elevam a janela como efeito secundário. Definir esta " +#~ "opção como falsa, o que é muito desaconselhável, irá desassociar o elevar " +#~ "de outras ações do utilizador e ignorar pedidos de elevação gerados pelas " +#~ "aplicações. Consulte http://bugzilla.gnome.org/show_bug.cgi?id=445447#c6." #~ msgid "" #~ "The keybinding that switches to the workspace above the current " @@ -2545,13 +2513,12 @@ msgstr "" #~ "\". If you set the option to the special string \"disabled\", then there " #~ "will be no keybinding for this action." #~ msgstr "" -#~ "O atalho de teclado que alterna para a área de trabalho acima da actual. " -#~ "O formato assemelha-se a \"<Control>a\" ou \"<Shift><" -#~ "Alt>F1\". O processador é razoavelmente liberal e permite " -#~ "capitalização maiúscula ou minúscula e também abreviaturas tais como " -#~ "\"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a expressão " -#~ "especial \"disabled\", não existirão quaisquer atalhos de teclado para " -#~ "esta acção." +#~ "O atalho de teclado que alterna para a área de trabalho acima da atual. O " +#~ "formato assemelha-se a \"<Control>a\" ou \"<Shift><Alt>" +#~ "F1\". O processador é razoavelmente liberal e permite capitalização " +#~ "maiúscula ou minúscula e também abreviaturas tais como \"<Ctl>\" e " +#~ "\"<Ctrl>\". Se definir a opção para a expressão especial \"disabled" +#~ "\", não existirão quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The keybinding that switches to the workspace below the current " @@ -2561,13 +2528,13 @@ msgstr "" #~ "\". If you set the option to the special string \"disabled\", then there " #~ "will be no keybinding for this action." #~ msgstr "" -#~ "O atalho de teclado que alterna para a área de trabalho abaixo da actual. " +#~ "O atalho de teclado que alterna para a área de trabalho abaixo da atual. " #~ "O formato assemelha-se a \"<Control>a\" ou \"<Shift><" #~ "Alt>F1\". O processador é razoavelmente liberal e permite " #~ "capitalização maiúscula ou minúscula e também abreviaturas tais como " #~ "\"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a expressão " #~ "especial \"disabled\", não existirão quaisquer atalhos de teclado para " -#~ "esta acção." +#~ "esta ação." #~ msgid "" #~ "The keybinding that switches to the workspace on the left of the current " @@ -2578,12 +2545,12 @@ msgstr "" #~ "will be no keybinding for this action." #~ msgstr "" #~ "O atalho de teclado que alterna para a área de trabalho à esquerda da " -#~ "actual. O formato assemelha-se a \"<Control>a\" ou \"<Shift>" +#~ "atual. O formato assemelha-se a \"<Control>a\" ou \"<Shift>" #~ "<Alt>F1\". O processador é razoavelmente liberal e permite " #~ "capitalização maiúscula ou minúscula e também abreviaturas tais como " #~ "\"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a expressão " #~ "especial \"disabled\", não existirão quaisquer atalhos de teclado para " -#~ "esta acção." +#~ "esta ação." #~ msgid "" #~ "The keybinding that switches to the workspace on the right of the current " @@ -2594,12 +2561,12 @@ msgstr "" #~ "will be no keybinding for this action." #~ msgstr "" #~ "O atalho de teclado que alterna para a área de trabalho à direita da " -#~ "actual. O formato assemelha-se a \"<Control>a\" ou \"<Shift>" +#~ "atual. O formato assemelha-se a \"<Control>a\" ou \"<Shift>" #~ "<Alt>F1\". O processador é razoavelmente liberal e permite " #~ "capitalização maiúscula ou minúscula e também abreviaturas tais como " #~ "\"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a expressão " #~ "especial \"disabled\", não existirão quaisquer atalhos de teclado para " -#~ "esta acção." +#~ "esta ação." #~ msgid "" #~ "The keybinding that switches to workspace 1. The format looks like \"<" @@ -2614,7 +2581,7 @@ msgstr "" #~ "processador é razoavelmente liberal e permite capitalização maiúscula ou " #~ "minúscula e também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>" #~ "\". Se definir a opção para a expressão especial \"disabled\", não " -#~ "existirão quaisquer atalhos de teclado para esta acção." +#~ "existirão quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The keybinding that switches to workspace 10. The format looks like \"<" @@ -2629,7 +2596,7 @@ msgstr "" #~ "processador é razoavelmente liberal e permite capitalização maiúscula ou " #~ "minúscula e também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>" #~ "\". Se definir a opção para a expressão especial \"disabled\", não " -#~ "existirão quaisquer atalhos de teclado para esta acção." +#~ "existirão quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The keybinding that switches to workspace 11. The format looks like \"<" @@ -2644,7 +2611,7 @@ msgstr "" #~ "processador é razoavelmente liberal e permite capitalização maiúscula ou " #~ "minúscula e também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>" #~ "\". Se definir a opção para a expressão especial \"disabled\", não " -#~ "existirão quaisquer atalhos de teclado para esta acção." +#~ "existirão quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The keybinding that switches to workspace 12. The format looks like \"<" @@ -2659,7 +2626,7 @@ msgstr "" #~ "processador é razoavelmente liberal e permite capitalização maiúscula ou " #~ "minúscula e também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>" #~ "\". Se definir a opção para a expressão especial \"disabled\", não " -#~ "existirão quaisquer atalhos de teclado para esta acção." +#~ "existirão quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The keybinding that switches to workspace 2. The format looks like \"<" @@ -2674,7 +2641,7 @@ msgstr "" #~ "processador é razoavelmente liberal e permite capitalização maiúscula ou " #~ "minúscula e também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>" #~ "\". Se definir a opção para a expressão especial \"disabled\", não " -#~ "existirão quaisquer atalhos de teclado para esta acção." +#~ "existirão quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The keybinding that switches to workspace 3. The format looks like \"<" @@ -2689,7 +2656,7 @@ msgstr "" #~ "processador é razoavelmente liberal e permite capitalização maiúscula ou " #~ "minúscula e também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>" #~ "\". Se definir a opção para a expressão especial \"disabled\", não " -#~ "existirão quaisquer atalhos de teclado para esta acção." +#~ "existirão quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The keybinding that switches to workspace 4. The format looks like \"<" @@ -2704,7 +2671,7 @@ msgstr "" #~ "processador é razoavelmente liberal e permite capitalização maiúscula ou " #~ "minúscula e também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>" #~ "\". Se definir a opção para a expressão especial \"disabled\", não " -#~ "existirão quaisquer atalhos de teclado para esta acção." +#~ "existirão quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The keybinding that switches to workspace 5. The format looks like \"<" @@ -2719,7 +2686,7 @@ msgstr "" #~ "processador é razoavelmente liberal e permite capitalização maiúscula ou " #~ "minúscula e também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>" #~ "\". Se definir a opção para a expressão especial \"disabled\", não " -#~ "existirão quaisquer atalhos de teclado para esta acção." +#~ "existirão quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The keybinding that switches to workspace 6. The format looks like \"<" @@ -2734,7 +2701,7 @@ msgstr "" #~ "processador é razoavelmente liberal e permite capitalização maiúscula ou " #~ "minúscula e também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>" #~ "\". Se definir a opção para a expressão especial \"disabled\", não " -#~ "existirão quaisquer atalhos de teclado para esta acção." +#~ "existirão quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The keybinding that switches to workspace 7. The format looks like \"<" @@ -2749,7 +2716,7 @@ msgstr "" #~ "processador é razoavelmente liberal e permite capitalização maiúscula ou " #~ "minúscula e também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>" #~ "\". Se definir a opção para a expressão especial \"disabled\", não " -#~ "existirão quaisquer atalhos de teclado para esta acção." +#~ "existirão quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The keybinding that switches to workspace 8. The format looks like \"<" @@ -2764,7 +2731,7 @@ msgstr "" #~ "processador é razoavelmente liberal e permite capitalização maiúscula ou " #~ "minúscula e também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>" #~ "\". Se definir a opção para a expressão especial \"disabled\", não " -#~ "existirão quaisquer atalhos de teclado para esta acção." +#~ "existirão quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The keybinding that switches to workspace 9. The format looks like \"<" @@ -2779,7 +2746,7 @@ msgstr "" #~ "processador é razoavelmente liberal e permite capitalização maiúscula ou " #~ "minúscula e também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>" #~ "\". Se definir a opção para a expressão especial \"disabled\", não " -#~ "existirão quaisquer atalhos de teclado para esta acção." +#~ "existirão quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The keybinding used to activate the window menu. The format looks like " @@ -2789,12 +2756,12 @@ msgstr "" #~ "the special string \"disabled\", then there will be no keybinding for " #~ "this action." #~ msgstr "" -#~ "O atalho de teclado utilizado para activar o menu da janela. O formato " +#~ "O atalho de teclado utilizado para ativar o menu da janela. O formato " #~ "assemelha-se a \"<Control>a\" ou \"<Shift><Alt>F1\". O " #~ "processador é razoavelmente liberal e permite capitalização maiúscula ou " #~ "minúscula e também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>" #~ "\". Se definir a opção para a expressão especial \"disabled\", não " -#~ "existirão quaisquer atalhos de teclado para esta acção." +#~ "existirão quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The keybinding used to enter \"move mode\" and begin moving a window " @@ -2810,7 +2777,7 @@ msgstr "" #~ "razoavelmente liberal e permite capitalização maiúscula ou minúscula e " #~ "também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>\". Se " #~ "definir a opção para a expressão especial \"disabled\", não existirão " -#~ "quaisquer atalhos de teclado para esta acção." +#~ "quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The keybinding used to enter \"resize mode\" and begin resizing a window " @@ -2826,7 +2793,7 @@ msgstr "" #~ "processador é razoavelmente liberal e permite capitalização maiúscula ou " #~ "minúscula e também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>" #~ "\". Se definir a opção para a expressão especial \"disabled\", não " -#~ "existirão quaisquer atalhos de teclado para esta acção." +#~ "existirão quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The keybinding used to hide all normal windows and set the focus to the " @@ -2842,7 +2809,7 @@ msgstr "" #~ "razoavelmente liberal e permite capitalização maiúscula ou minúscula e " #~ "também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>\". Se " #~ "definir a opção para a expressão especial \"disabled\", não existirão " -#~ "quaisquer atalhos de teclado para esta acção." +#~ "quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The keybinding used to maximize a window. The format looks like \"<" @@ -2857,7 +2824,7 @@ msgstr "" #~ "processador é razoavelmente liberal e permite capitalização maiúscula ou " #~ "minúscula e também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>" #~ "\". Se definir a opção para a expressão especial \"disabled\", não " -#~ "existirão quaisquer atalhos de teclado para esta acção." +#~ "existirão quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The keybinding used to minimize a window. The format looks like \"<" @@ -2872,7 +2839,7 @@ msgstr "" #~ "processador é razoavelmente liberal e permite capitalização maiúscula ou " #~ "minúscula e também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>" #~ "\". Se definir a opção para a expressão especial \"disabled\", não " -#~ "existirão quaisquer atalhos de teclado para esta acção." +#~ "existirão quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The keybinding used to move a window one workspace down. The format looks " @@ -2888,7 +2855,7 @@ msgstr "" #~ "capitalização maiúscula ou minúscula e também abreviaturas tais como " #~ "\"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a expressão " #~ "especial \"disabled\", não existirão quaisquer atalhos de teclado para " -#~ "esta acção." +#~ "esta ação." #~ msgid "" #~ "The keybinding used to move a window one workspace to the left. The " @@ -2904,7 +2871,7 @@ msgstr "" #~ "capitalização maiúscula ou minúscula e também abreviaturas tais como " #~ "\"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a expressão " #~ "especial \"disabled\", não existirão quaisquer atalhos de teclado para " -#~ "esta acção." +#~ "esta ação." #~ msgid "" #~ "The keybinding used to move a window one workspace to the right. The " @@ -2920,7 +2887,7 @@ msgstr "" #~ "capitalização maiúscula ou minúscula e também abreviaturas tais como " #~ "\"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a expressão " #~ "especial \"disabled\", não existirão quaisquer atalhos de teclado para " -#~ "esta acção." +#~ "esta ação." #~ msgid "" #~ "The keybinding used to move a window one workspace up. The format looks " @@ -2936,7 +2903,7 @@ msgstr "" #~ "capitalização maiúscula ou minúscula e também abreviaturas tais como " #~ "\"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a expressão " #~ "especial \"disabled\", não existirão quaisquer atalhos de teclado para " -#~ "esta acção." +#~ "esta ação." #~ msgid "" #~ "The keybinding used to move a window to workspace 1. The format looks " @@ -2952,7 +2919,7 @@ msgstr "" #~ "capitalização maiúscula ou minúscula e também abreviaturas tais como " #~ "\"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a expressão " #~ "especial \"disabled\", não existirão quaisquer atalhos de teclado para " -#~ "esta acção." +#~ "esta ação." #~ msgid "" #~ "The keybinding used to move a window to workspace 10. The format looks " @@ -2968,7 +2935,7 @@ msgstr "" #~ "capitalização maiúscula ou minúscula e também abreviaturas tais como " #~ "\"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a expressão " #~ "especial \"disabled\", não existirão quaisquer atalhos de teclado para " -#~ "esta acção." +#~ "esta ação." #~ msgid "" #~ "The keybinding used to move a window to workspace 11. The format looks " @@ -2984,7 +2951,7 @@ msgstr "" #~ "capitalização maiúscula ou minúscula e também abreviaturas tais como " #~ "\"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a expressão " #~ "especial \"disabled\", não existirão quaisquer atalhos de teclado para " -#~ "esta acção." +#~ "esta ação." #~ msgid "" #~ "The keybinding used to move a window to workspace 12. The format looks " @@ -3000,7 +2967,7 @@ msgstr "" #~ "capitalização maiúscula ou minúscula e também abreviaturas tais como " #~ "\"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a expressão " #~ "especial \"disabled\", não existirão quaisquer atalhos de teclado para " -#~ "esta acção." +#~ "esta ação." #~ msgid "" #~ "The keybinding used to move a window to workspace 2. The format looks " @@ -3016,7 +2983,7 @@ msgstr "" #~ "capitalização maiúscula ou minúscula e também abreviaturas tais como " #~ "\"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a expressão " #~ "especial \"disabled\", não existirão quaisquer atalhos de teclado para " -#~ "esta acção." +#~ "esta ação." #~ msgid "" #~ "The keybinding used to move a window to workspace 3. The format looks " @@ -3032,7 +2999,7 @@ msgstr "" #~ "capitalização maiúscula ou minúscula e também abreviaturas tais como " #~ "\"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a expressão " #~ "especial \"disabled\", não existirão quaisquer atalhos de teclado para " -#~ "esta acção." +#~ "esta ação." #~ msgid "" #~ "The keybinding used to move a window to workspace 4. The format looks " @@ -3048,7 +3015,7 @@ msgstr "" #~ "capitalização maiúscula ou minúscula e também abreviaturas tais como " #~ "\"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a expressão " #~ "especial \"disabled\", não existirão quaisquer atalhos de teclado para " -#~ "esta acção." +#~ "esta ação." #~ msgid "" #~ "The keybinding used to move a window to workspace 5. The format looks " @@ -3064,7 +3031,7 @@ msgstr "" #~ "capitalização maiúscula ou minúscula e também abreviaturas tais como " #~ "\"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a expressão " #~ "especial \"disabled\", não existirão quaisquer atalhos de teclado para " -#~ "esta acção." +#~ "esta ação." #~ msgid "" #~ "The keybinding used to move a window to workspace 6. The format looks " @@ -3080,7 +3047,7 @@ msgstr "" #~ "capitalização maiúscula ou minúscula e também abreviaturas tais como " #~ "\"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a expressão " #~ "especial \"disabled\", não existirão quaisquer atalhos de teclado para " -#~ "esta acção." +#~ "esta ação." #~ msgid "" #~ "The keybinding used to move a window to workspace 7. The format looks " @@ -3096,7 +3063,7 @@ msgstr "" #~ "capitalização maiúscula ou minúscula e também abreviaturas tais como " #~ "\"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a expressão " #~ "especial \"disabled\", não existirão quaisquer atalhos de teclado para " -#~ "esta acção." +#~ "esta ação." #~ msgid "" #~ "The keybinding used to move a window to workspace 8. The format looks " @@ -3112,7 +3079,7 @@ msgstr "" #~ "capitalização maiúscula ou minúscula e também abreviaturas tais como " #~ "\"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a expressão " #~ "especial \"disabled\", não existirão quaisquer atalhos de teclado para " -#~ "esta acção." +#~ "esta ação." #~ msgid "" #~ "The keybinding used to move a window to workspace 9. The format looks " @@ -3128,7 +3095,7 @@ msgstr "" #~ "capitalização maiúscula ou minúscula e também abreviaturas tais como " #~ "\"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a expressão " #~ "especial \"disabled\", não existirão quaisquer atalhos de teclado para " -#~ "esta acção." +#~ "esta ação." #~ msgid "" #~ "The keybinding used to move focus backwards between panels and the " @@ -3144,7 +3111,7 @@ msgstr "" #~ "razoavelmente liberal e permite capitalização maiúscula ou minúscula e " #~ "também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>\". Se " #~ "definir a opção para a expressão especial \"disabled\", não existirão " -#~ "quaisquer atalhos de teclado para esta acção." +#~ "quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The keybinding used to move focus backwards between panels and the " @@ -3160,7 +3127,7 @@ msgstr "" #~ "processador é razoavelmente liberal e permite capitalização maiúscula ou " #~ "minúscula e também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>" #~ "\". Se definir a opção para a expressão especial \"disabled\", não " -#~ "existirão quaisquer atalhos de teclado para esta acção." +#~ "existirão quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The keybinding used to move focus backwards between windows of an " @@ -3174,12 +3141,12 @@ msgstr "" #~ msgstr "" #~ "O atalho de teclado utilizado para mover o foco atrás entre janelas de " #~ "uma aplicação sem utilizar uma janela de popup. Premir \"Shift\" junto " -#~ "com este atalho de teclado faz a direcção avançar novamente. O formato " +#~ "com este atalho de teclado faz a direção avançar novamente. O formato " #~ "assemelha-se a \"<Control>a\" ou \"<Shift><Alt>F1\". O " #~ "processador é razoavelmente liberal e permite capitalização maiúscula ou " #~ "minúscula e também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>" #~ "\". Se definir a opção para a expressão especial \"disabled\", não " -#~ "existirão quaisquer atalhos de teclado para esta acção." +#~ "existirão quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The keybinding used to move focus backwards between windows of an " @@ -3193,12 +3160,12 @@ msgstr "" #~ msgstr "" #~ "O atalho de teclado utilizado para mover o foco atrás entre janelas de " #~ "uma aplicação, utilizando uma janela de popup. Premir \"Shift\" junto com " -#~ "este atalho de teclado faz a direcção avançar novamente. O formato " +#~ "este atalho de teclado faz a direção avançar novamente. O formato " #~ "assemelha-se a \"<Control>a\" ou \"<Shift><Alt>F1\". O " #~ "processador é razoavelmente liberal e permite capitalização maiúscula ou " #~ "minúscula e também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>" #~ "\". Se definir a opção para a expressão especial \"disabled\", não " -#~ "existirão quaisquer atalhos de teclado para esta acção." +#~ "existirão quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The keybinding used to move focus backwards between windows without a " @@ -3211,12 +3178,12 @@ msgstr "" #~ msgstr "" #~ "O atalho de teclado utilizado para mover o foco atrás entre janelas sem " #~ "utilizar uma janela de popup. Premir \"Shift\" junto com este atalho de " -#~ "teclado faz a direcção avançar novamente. O formato assemelha-se a \"<" +#~ "teclado faz a direção avançar novamente. O formato assemelha-se a \"<" #~ "Control>a\" ou \"<Shift><Alt>F1\". O processador é " #~ "razoavelmente liberal e permite capitalização maiúscula ou minúscula e " #~ "também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>\". Se " #~ "definir a opção para a expressão especial \"disabled\", não existirão " -#~ "quaisquer atalhos de teclado para esta acção." +#~ "quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The keybinding used to move focus backwards between windows, using a " @@ -3229,12 +3196,12 @@ msgstr "" #~ msgstr "" #~ "O atalho de teclado utilizado para mover o foco atrás entre janelas " #~ "utilizando uma janela de popup. Premir \"Shift\" junto com este atalho de " -#~ "teclado faz a direcção avançar novamente. O formato assemelha-se a \"<" +#~ "teclado faz a direção avançar novamente. O formato assemelha-se a \"<" #~ "Control>a\" ou \"<Shift><Alt>F1\". O processador é " #~ "razoavelmente liberal e permite capitalização maiúscula ou minúscula e " #~ "também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>\". Se " #~ "definir a opção para a expressão especial \"disabled\", não existirão " -#~ "quaisquer atalhos de teclado para esta acção." +#~ "quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The keybinding used to move focus between panels and the desktop, using a " @@ -3250,7 +3217,7 @@ msgstr "" #~ "razoavelmente liberal e permite capitalização maiúscula ou minúscula e " #~ "também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>\". Se " #~ "definir a opção para a expressão especial \"disabled\", não existirão " -#~ "quaisquer atalhos de teclado para esta acção." +#~ "quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The keybinding used to move focus between panels and the desktop, without " @@ -3266,7 +3233,7 @@ msgstr "" #~ "razoavelmente liberal e permite capitalização maiúscula ou minúscula e " #~ "também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>\". Se " #~ "definir a opção para a expressão especial \"disabled\", não existirão " -#~ "quaisquer atalhos de teclado para esta acção." +#~ "quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The keybinding used to move focus between windows of an application " @@ -3280,13 +3247,13 @@ msgstr "" #~ msgstr "" #~ "O atalho de teclado utilizado para mover o foco entre janelas de uma " #~ "aplicação, sem utilizar uma janela de popup. (Tradicionalmente <Alt>" -#~ "Escape) Premindo o \"Shift\" ao utilizar este atalho inverte a direcção " -#~ "do movimento. O formato assemelha-se a \"<Control>a\" ou \"<" +#~ "Escape) Premindo o \"Shift\" ao utilizar este atalho inverte a direção do " +#~ "movimento. O formato assemelha-se a \"<Control>a\" ou \"<" #~ "Shift><Alt>F1\". O processador é razoavelmente liberal e permite " #~ "capitalização maiúscula ou minúscula e também abreviaturas tais como " #~ "\"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a expressão " #~ "especial \"disabled\", não existirão quaisquer atalhos de teclado para " -#~ "esta acção." +#~ "esta ação." #~ msgid "" #~ "The keybinding used to move focus between windows of an application, " @@ -3300,13 +3267,13 @@ msgstr "" #~ msgstr "" #~ "O atalho de teclado utilizado para mover o foco entre janelas de uma " #~ "aplicação, utilizando uma janela de popup. (Tradicionalmente <Alt>" -#~ "Tab) Premindo o \"Shift\" ao utilizar este atalho inverte a direcção do " +#~ "Tab) Premindo o \"Shift\" ao utilizar este atalho inverte a direção do " #~ "movimento. O formato assemelha-se a \"<Control>a\" ou \"<" #~ "Shift><Alt>F1\". O processador é razoavelmente liberal e permite " #~ "capitalização maiúscula ou minúscula e também abreviaturas tais como " #~ "\"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a expressão " #~ "especial \"disabled\", não existirão quaisquer atalhos de teclado para " -#~ "esta acção." +#~ "esta ação." #~ msgid "" #~ "The keybinding used to move focus between windows without a popup window. " @@ -3320,13 +3287,13 @@ msgstr "" #~ msgstr "" #~ "O atalho de teclado utilizado para mover o foco entre janelas, sem " #~ "utilizar uma janela de popup. (Tradicionalmente <Alt>Escape) " -#~ "Premindo o \"Shift\" ao utilizar este atalho inverte a direcção do " +#~ "Premindo o \"Shift\" ao utilizar este atalho inverte a direção do " #~ "movimento. O formato assemelha-se a \"<Control>a\" ou \"<" #~ "Shift><Alt>F1\". O processador é razoavelmente liberal e permite " #~ "capitalização maiúscula ou minúscula e também abreviaturas tais como " #~ "\"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a expressão " #~ "especial \"disabled\", não existirão quaisquer atalhos de teclado para " -#~ "esta acção." +#~ "esta ação." #~ msgid "" #~ "The keybinding used to move focus between windows, using a popup window. " @@ -3340,12 +3307,12 @@ msgstr "" #~ msgstr "" #~ "O atalho de teclado utilizado para mover o foco entre janelas, utilizando " #~ "uma janela de popup. (Tradicionalmente <Alt>Tab) Premindo o \"Shift" -#~ "\" ao utilizar este atalho inverte a direcção do movimento. O formato " +#~ "\" ao utilizar este atalho inverte a direção do movimento. O formato " #~ "assemelha-se a \"<Control>a\" ou \"<Shift><Alt>F1\". O " #~ "processador é razoavelmente liberal e permite capitalização maiúscula ou " #~ "minúscula e também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>" #~ "\". Se definir a opção para a expressão especial \"disabled\", não " -#~ "existirão quaisquer atalhos de teclado para esta acção." +#~ "existirão quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The keybinding used to toggle always on top. A window that is always on " @@ -3363,7 +3330,7 @@ msgstr "" #~ "capitalização maiúscula ou minúscula e também abreviaturas tais como " #~ "\"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a expressão " #~ "especial \"disabled\", não existirão quaisquer atalhos de teclado para " -#~ "esta acção." +#~ "esta ação." #~ msgid "" #~ "The keybinding used to toggle fullscreen mode. The format looks like " @@ -3378,7 +3345,7 @@ msgstr "" #~ "F1\". O processador é razoavelmente liberal e permite capitalização " #~ "maiúscula ou minúscula e também abreviaturas tais como \"<Ctl>\" e " #~ "\"<Ctrl>\". Se definir a opção para a expressão especial \"disabled" -#~ "\", não existirão quaisquer atalhos de teclado para esta acção." +#~ "\", não existirão quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The keybinding used to toggle maximization. The format looks like \"<" @@ -3393,7 +3360,7 @@ msgstr "" #~ "processador é razoavelmente liberal e permite capitalização maiúscula ou " #~ "minúscula e também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>" #~ "\". Se definir a opção para a expressão especial \"disabled\", não " -#~ "existirão quaisquer atalhos de teclado para esta acção." +#~ "existirão quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The keybinding used to toggle shaded/unshaded state. The format looks " @@ -3409,7 +3376,7 @@ msgstr "" #~ "capitalização maiúscula ou minúscula e também abreviaturas tais como " #~ "\"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a expressão " #~ "especial \"disabled\", não existirão quaisquer atalhos de teclado para " -#~ "esta acção." +#~ "esta ação." #~ msgid "" #~ "The keybinding used to toggle whether the window is on all workspaces or " @@ -3425,7 +3392,7 @@ msgstr "" #~ "razoavelmente liberal e permite capitalização maiúscula ou minúscula e " #~ "também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>\". Se " #~ "definir a opção para a expressão especial \"disabled\", não existirão " -#~ "quaisquer atalhos de teclado para esta acção." +#~ "quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The keybinding used to unmaximize a window. The format looks like \"<" @@ -3440,7 +3407,7 @@ msgstr "" #~ "processador é razoavelmente liberal e permite capitalização maiúscula ou " #~ "minúscula e também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>" #~ "\". Se definir a opção para a expressão especial \"disabled\", não " -#~ "existirão quaisquer atalhos de teclado para esta acção." +#~ "existirão quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The keybinding which display's the panel's \"Run Application\" dialog " @@ -3456,7 +3423,7 @@ msgstr "" #~ "capitalização maiúscula ou minúscula e também abreviaturas tais como " #~ "\"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a expressão " #~ "especial \"disabled\", não existirão quaisquer atalhos de teclado para " -#~ "esta acção." +#~ "esta ação." #~ msgid "" #~ "The keybinding which invokes a terminal. The format looks like \"<" @@ -3471,7 +3438,7 @@ msgstr "" #~ "razoavelmente liberal e permite capitalização maiúscula ou minúscula e " #~ "também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>\". Se " #~ "definir a opção para a expressão especial \"disabled\", não existirão " -#~ "quaisquer atalhos de teclado para esta acção." +#~ "quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The keybinding which invokes the panel's screenshot utility to take a " @@ -3487,7 +3454,7 @@ msgstr "" #~ "razoavelmente liberal e permite capitalização maiúscula ou minúscula e " #~ "também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>\". Se " #~ "definir a opção para a expressão especial \"disabled\", não existirão " -#~ "quaisquer atalhos de teclado para esta acção." +#~ "quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The keybinding which invokes the panel's screenshot utility. The format " @@ -3502,7 +3469,7 @@ msgstr "" #~ "processador é razoavelmente liberal e permite capitalização maiúscula ou " #~ "minúscula e também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>" #~ "\". Se definir a opção para a expressão especial \"disabled\", não " -#~ "existirão quaisquer atalhos de teclado para esta acção." +#~ "existirão quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "The keybinding which shows the panel's main menu. The format looks like " @@ -3517,7 +3484,7 @@ msgstr "" #~ "processador é razoavelmente liberal e permite capitalização maiúscula ou " #~ "minúscula e também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>" #~ "\". Se definir a opção para a expressão especial \"disabled\", não " -#~ "existirão quaisquer atalhos de teclado para esta acção." +#~ "existirão quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "This keybinding changes whether a window is above or below other windows. " @@ -3537,7 +3504,7 @@ msgstr "" #~ "liberal e permite capitalização maiúscula ou minúscula e também " #~ "abreviaturas tais como \"<Ctl>\" e \"<Ctrl>\". Se definir a " #~ "opção para a expressão especial \"disabled\", não existirão quaisquer " -#~ "atalhos de teclado para esta acção." +#~ "atalhos de teclado para esta ação." #~ msgid "" #~ "This keybinding lowers a window below other windows. The format looks " @@ -3552,7 +3519,7 @@ msgstr "" #~ "F1\". O processador é razoavelmente liberal e permite capitalização " #~ "maiúscula ou minúscula e também abreviaturas tais como \"<Ctl>\" e " #~ "\"<Ctrl>\". Se definir a opção para a expressão especial \"disabled" -#~ "\", não existirão quaisquer atalhos de teclado para esta acção." +#~ "\", não existirão quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "This keybinding moves a window against the north (top) side of the " @@ -3568,7 +3535,7 @@ msgstr "" #~ "capitalização maiúscula ou minúscula e também abreviaturas tais como " #~ "\"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a expressão " #~ "especial \"disabled\", não existirão quaisquer atalhos de teclado para " -#~ "esta acção." +#~ "esta ação." #~ msgid "" #~ "This keybinding moves a window into the center of the screen. The format " @@ -3583,7 +3550,7 @@ msgstr "" #~ "processador é razoavelmente liberal e permite capitalização maiúscula ou " #~ "minúscula e também abreviaturas tais como \"<Ctl>\" e \"<Ctrl>" #~ "\". Se definir a opção para a expressão especial \"disabled\", não " -#~ "existirão quaisquer atalhos de teclado para esta acção." +#~ "existirão quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "This keybinding moves a window into the east (right) side of the screen. " @@ -3599,7 +3566,7 @@ msgstr "" #~ "capitalização maiúscula ou minúscula e também abreviaturas tais como " #~ "\"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a expressão " #~ "especial \"disabled\", não existirão quaisquer atalhos de teclado para " -#~ "esta acção." +#~ "esta ação." #~ msgid "" #~ "This keybinding moves a window into the north-east (top right) corner of " @@ -3615,7 +3582,7 @@ msgstr "" #~ "capitalização maiúscula ou minúscula e também abreviaturas tais como " #~ "\"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a expressão " #~ "especial \"disabled\", não existirão quaisquer atalhos de teclado para " -#~ "esta acção." +#~ "esta ação." #~ msgid "" #~ "This keybinding moves a window into the north-west (top left) corner of " @@ -3631,7 +3598,7 @@ msgstr "" #~ "capitalização maiúscula ou minúscula e também abreviaturas tais como " #~ "\"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a expressão " #~ "especial \"disabled\", não existirão quaisquer atalhos de teclado para " -#~ "esta acção." +#~ "esta ação." #~ msgid "" #~ "This keybinding moves a window into the south (bottom) side of the " @@ -3647,7 +3614,7 @@ msgstr "" #~ "capitalização maiúscula ou minúscula e também abreviaturas tais como " #~ "\"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a expressão " #~ "especial \"disabled\", não existirão quaisquer atalhos de teclado para " -#~ "esta acção." +#~ "esta ação." #~ msgid "" #~ "This keybinding moves a window into the south-east (bottom right) corner " @@ -3663,7 +3630,7 @@ msgstr "" #~ "capitalização maiúscula ou minúscula e também abreviaturas tais como " #~ "\"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a expressão " #~ "especial \"disabled\", não existirão quaisquer atalhos de teclado para " -#~ "esta acção." +#~ "esta ação." #~ msgid "" #~ "This keybinding moves a window into the south-west (bottom left) corner " @@ -3679,7 +3646,7 @@ msgstr "" #~ "capitalização maiúscula ou minúscula e também abreviaturas tais como " #~ "\"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a expressão " #~ "especial \"disabled\", não existirão quaisquer atalhos de teclado para " -#~ "esta acção." +#~ "esta ação." #~ msgid "" #~ "This keybinding moves a window into the west (left) side of the screen. " @@ -3695,7 +3662,7 @@ msgstr "" #~ "capitalização maiúscula ou minúscula e também abreviaturas tais como " #~ "\"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a expressão " #~ "especial \"disabled\", não existirão quaisquer atalhos de teclado para " -#~ "esta acção." +#~ "esta ação." #~ msgid "" #~ "This keybinding raises the window above other windows. The format looks " @@ -3710,7 +3677,7 @@ msgstr "" #~ "F1\". O processador é razoavelmente liberal e permite capitalização " #~ "maiúscula ou minúscula e também abreviaturas tais como \"<Ctl>\" e " #~ "\"<Ctrl>\". Se definir a opção para a expressão especial \"disabled" -#~ "\", não existirão quaisquer atalhos de teclado para esta acção." +#~ "\", não existirão quaisquer atalhos de teclado para esta ação." #~ msgid "" #~ "This keybinding resizes a window to fill available horizontal space. The " @@ -3726,7 +3693,7 @@ msgstr "" #~ "permite capitalização maiúscula ou minúscula e também abreviaturas tais " #~ "como \"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a " #~ "expressão especial \"disabled\", não existirão quaisquer atalhos de " -#~ "teclado para esta acção." +#~ "teclado para esta ação." #~ msgid "" #~ "This keybinding resizes a window to fill available vertical space. The " @@ -3742,7 +3709,7 @@ msgstr "" #~ "permite capitalização maiúscula ou minúscula e também abreviaturas tais " #~ "como \"<Ctl>\" e \"<Ctrl>\". Se definir a opção para a " #~ "expressão especial \"disabled\", não existirão quaisquer atalhos de " -#~ "teclado para esta acção." +#~ "teclado para esta ação." #~ msgid "Toggle always on top state" #~ msgstr "Alternar estado sempre no topo" @@ -3864,7 +3831,7 @@ msgstr "" #~ "current maximum is %d\n" #~ msgstr "" #~ "%d armazenado na chave GConf %s não é um número razoável de ambientes de " -#~ "trabalho, o número máximo actual é %d\n" +#~ "trabalho, o número máximo atual é %d\n" #~ msgid "On _Top" #~ msgstr "No _Topo" @@ -3942,12 +3909,12 @@ msgstr "" #~ "Metacity colocaria todos os diálogos numa posição consistente em relação " #~ "à janela pai. Isto requer ignorar posições de diálogos definidos pelas " #~ "aplicações. Mas algumas versões de Java/Swing marcam os seus menus popup " -#~ "como diálogos, pelo que o Metacity tem de desactivar o posicionamento de " +#~ "como diálogos, pelo que o Metacity tem de desativar o posicionamento de " #~ "diálogos para permitir que os menus funcionem em aplicações Java " #~ "problemáticas. Existem outros exemplos como este. Esta opção coloca o " -#~ "Metacity em modo de Correcção Completa, que provavelmente disponibiliza " -#~ "um Interface melhor caso não tenha de executar nenhuma aplicação " -#~ "problemática. Infelizmente têm de ser activados recursos por omissão; o " +#~ "Metacity em modo de Correção Completa, que provavelmente disponibiliza um " +#~ "Interface melhor caso não tenha de executar nenhuma aplicação " +#~ "problemática. Infelizmente têm de ser ativados recursos por omissão; o " #~ "mundo real é um sitio horrível. Alguns dos recursos servem para " #~ "limitações nas próprias especificações, pelo que por vezes um erro em " #~ "modo sem recursos pode não ser corrijível sem alterar a própria " diff --git a/po/pt_BR.po b/po/pt_BR.po index 73ba494cb..576d7dda1 100644 --- a/po/pt_BR.po +++ b/po/pt_BR.po @@ -1,5 +1,6 @@ -# Brazilian Portuguese translation of metacity. -# Copyright (C) 2002-2012 Free Software Foundation, Inc. +# Brazilian Portuguese translation of mutter. +# Copyright (C) 2002-2019 Free Software Foundation, Inc. +# This file is distributed under the same license as the mutter package. # Sun G11n <gnome_int_l10n@ireland.sun.com>, 2002. # Evandro Fernandes Giovanini <evandrofg@ig.com.br>, 2002, 2003, 2006. # Gustavo Noronha Silva <kov@debian.org>, 2004. @@ -12,1634 +13,1692 @@ # Vladimir Melo <vmelo@gnome.org>, 2009. # Antonio Fernandes C. Neto <fernandes@pelivre.org>, 2010. # Rodrigo Padula de Oliveira <contato@rodrigopadula.com>, 2011. -# Enrico Nicoletto <liverig@gmail.com>, 2012. +# Artur de Aquino Morais <artur.morais93@outlook.com>, 2016. +# Enrico Nicoletto <liverig@gmail.com>, 2012-2016. +# Rafael Fontenelle <rafaelff@gnome.org>, 2013-2020. # msgid "" msgstr "" -"Project-Id-Version: metacity\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-03-21 14:53-0300\n" -"PO-Revision-Date: 2012-03-21 09:33-0300\n" -"Last-Translator: Enrico Nicoletto <liverig@gmail.com>\n" +"Project-Id-Version: mutter\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2020-04-27 14:06+0000\n" +"PO-Revision-Date: 2020-07-17 17:56-0300\n" +"Last-Translator: Rafael Fontenelle <rafaelff@gnome.org>\n" "Language-Team: Brazilian Portuguese <gnome-pt_br-list@gnome.org>\n" "Language: pt_BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" -"X-Generator: Virtaal 0.6.1\n" -"X-Poedit-Language: Portuguese\n" -"X-Poedit-Country: BRAZIL\n" +"Plural-Forms: nplurals=2; plural=(n > 1)\n" +"X-Generator: Gtranslator 3.36.0\n" +"X-Project-Style: gnome\n" + +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Navegação" + +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Mover a janela para o espaço de trabalho 1" + +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Mover a janela para o espaço de trabalho 2" + +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Mover a janela para o espaço de trabalho 3" + +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Mover a janela para o espaço de trabalho 4" + +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Mover a janela para o último espaço de trabalho" + +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "Mover a janela para um espaço de trabalho acima" + +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "Mover a janela para um espaço de trabalho abaixo" + +# Em conformidade com a tradução do gsettings-desktop-schemas --Enrico +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "Mover a janela para o monitor da esquerda" + +# Em conformidade com a tradução do gsettings-desktop-schemas --Enrico +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "Mover a janela para o monitor da direita" + +# Em conformidade com a tradução do gsettings-desktop-schemas --Enrico +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "Mover a janela para o monitor acima" + +# Em conformidade com a tradução do gsettings-desktop-schemas --Enrico +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "Mover a janela para o monitor abaixo" + +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "Alternar entre aplicativos" + +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "Alternar para o aplicativo anterior" + +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "Alternar entre janelas" + +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "Alternar para a janela anterior" + +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "Alternar as janelas de um aplicativo" + +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "Alternar para a janela anterior de um aplicativo" + +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "Alternar os controles do sistema" + +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "Alternar para o controle de sistema anterior" + +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "Alternar as janelas diretamente" + +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "Alternar diretamente para a janela anterior" + +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "Alternar as janelas de um aplicativo diretamente" + +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "Alternar diretamente para a janela anterior de um aplicativo" -#: ../src/50-muffin-windows.xml.in.h:1 -msgid "View split on left" -msgstr "Visualizar divisão à esquerda" +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "Alternar os controles de sistema diretamente" -#: ../src/50-muffin-windows.xml.in.h:2 -msgid "View split on right" -msgstr "Visualizar divisão à direita" +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "Alternar diretamente para o controle de sistema anterior" + +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "Ocultar todas as janelas normais" + +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "Trocar para o espaço de trabalho 1" + +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "Trocar para o espaço de trabalho 2" + +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "Trocar para o espaço de trabalho 3" + +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "Trocar para o espaço de trabalho 4" + +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "Trocar para o último espaço de trabalho" + +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "Mover a visualização para o espaço de trabalho acima" + +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "Mover a visualização para o espaço de trabalho abaixo" + +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "Sistema" + +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Mostrar o prompt de comando de execução" + +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Mostrar o panorama de atividades" + +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Restaurar os atalhos de teclado" -#: ../src/50-muffin-windows.xml.in.h:3 +#: data/50-mutter-windows.xml:6 msgid "Windows" msgstr "Janelas" -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "Ativar o menu da janela" + +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Alternar o modo de tela inteira" + +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "Alternar o estado de maximização" + +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "Maximizar a janela" + +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Restaurar a anela" + +#: data/50-mutter-windows.xml:18 +msgid "Close window" +msgstr "Fechar a janela" + +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "Ocultar a janela" + +#: data/50-mutter-windows.xml:22 +msgid "Move window" +msgstr "Mover a janela" + +#: data/50-mutter-windows.xml:24 +msgid "Resize window" +msgstr "Redimensionar a janela" + +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "Alternar a janela em todos os espaços de trabalho ou apenas em um" + +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "Trazer a janela se estiver coberta; caso contrário, coloca atrás" + +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "Trazer a janela para frente das outras" + +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "Colocar a janela atrás das outras" + +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "Maximizar a janela verticalmente" + +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "Maximizar a janela horizontalmente" + +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "Visualizar a divisão à esquerda" + +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "Visualizar a divisão à direita" + +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" + +#: data/org.gnome.mutter.gschema.xml.in:7 +msgid "Modifier to use for extended window management operations" +msgstr "" +"Modificador a ser usado para operações de gerenciamento de janelas estendido" + +#: data/org.gnome.mutter.gschema.xml.in:8 msgid "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." msgstr "" -"Outro compositor de janelas está em execução na tela %i na área \"%s\"." +"Esta chave irá iniciar a “sobreposição”, que é a combinação de visão de " +"janela e sistema de lançamento de aplicativos. O padrão pretendido é a " +"“tecla Windows” no hardware do computador. É esperada para esta associação " +"tanto o padrão quanto a definição de uma string vazia." -#: ../src/core/bell.c:307 -msgid "Bell event" -msgstr "Evento de som" +#: data/org.gnome.mutter.gschema.xml.in:20 +msgid "Attach modal dialogs" +msgstr "Anexar diálogos modais" -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Informação solicitada de janela desconhecida: %d" +#: data/org.gnome.mutter.gschema.xml.in:21 +msgid "" +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." +msgstr "" +"Quando verdadeiro, em vez de terem barras de título independentes, os " +"diálogos modais surgem anexados à barra de título da janela pai e são " +"movidos juntamente com a janela pai." -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> não está respondendo." +#: data/org.gnome.mutter.gschema.xml.in:30 +msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "" +"Habilitar contorno ladrilhado ao arrastar janelas sobre as bordas da tela" -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "O aplicativo não está respondendo." +#: data/org.gnome.mutter.gschema.xml.in:31 +msgid "" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." +msgstr "" +"Caso esteja habilitado, ao arrastar janelas sobre bordas verticais da tela " +"as maximizará verticalmente e as redimensionarão horizontalmente para cobrir " +"metade da área disponível. Arrastar janelas no topo da borda da tela as " +"maximiza completamente." -#: ../src/core/delete.c:119 +#: data/org.gnome.mutter.gschema.xml.in:40 +msgid "Workspaces are managed dynamically" +msgstr "Áreas de trabalho são gerenciadas dinamicamente" + +#: data/org.gnome.mutter.gschema.xml.in:41 msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." +"Determines whether workspaces are managed dynamically or whether there’s a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." msgstr "" -"Você pode escolher aguardar um pouco e continuar ou forçar o aplicativo a " -"sair completamente." +"Determina se as áreas de trabalho são gerenciadas de forma dinâmica ou se há " +"um número estático de áreas de trabalho (determinado pela chave num-" +"workspaces em org.gnome.desktop.wm.preferences)." -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "_Esperar" +#: data/org.gnome.mutter.gschema.xml.in:50 +msgid "Workspaces only on primary" +msgstr "Áreas de trabalho apenas para a principal" -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "_Forçar sair" +#: data/org.gnome.mutter.gschema.xml.in:51 +msgid "" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." +msgstr "" +"Determina se a troca de área de trabalho deve ocorrer para janelas em todos " +"os monitores ou apenas para janelas no monitor principal." + +#: data/org.gnome.mutter.gschema.xml.in:59 +msgid "No tab popup" +msgstr "Nenhuma aba instantânea" + +#: data/org.gnome.mutter.gschema.xml.in:60 +msgid "" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." +msgstr "" +"Determina se a utilização de quadros instantâneos e destacados devem ser " +"desabilitados na alternância de janelas." + +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Atrasar alterações de foco até que o ponteiro pare de mover" + +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" +"Se verdadeiro, e o modo de foco for “sloppy” ou “mouse”, o foco não será " +"alterado imediatamente quando o ponteiro do mouse entrar na janela, e sim " +"quando parar de mover." + +#: data/org.gnome.mutter.gschema.xml.in:79 +msgid "Draggable border width" +msgstr "Largura da borda arrastável" + +#: data/org.gnome.mutter.gschema.xml.in:80 +msgid "" +"The amount of total draggable borders. If the theme’s visible borders are " +"not enough, invisible borders will be added to meet this value." +msgstr "" +"A quantidade do total de bordas arrastáveis. Se as bordas dos temas visíveis " +"não são suficientes, as bordas invisíveis serão adicionadas para encontrar " +"este valor." + +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "Maximizar automaticamente janelas com tamanho próximo ao do monitor" + +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" +"Se habilitado, novas janelas que, ao iniciar, possuírem o tamanho do monitor " +"serão maximizadas automaticamente." + +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Posicionar novas janelas ao centro" + +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" +"Quando verdadeiro, as novas janelas serão sempre colocadas no centro da tela " +"ativa do monitor." + +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Habilitar recursos experimentais" + +#: data/org.gnome.mutter.gschema.xml.in:108 +msgid "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes " +"mutter request a low priority real-time scheduling. The executable or user " +"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — " +"initializes Xwayland lazily if there are X11 clients. Requires restart." +msgstr "" +"Para habilitar recursos experimentais, adicione a palavra-chave do recurso à " +"lista. Se o recurso exige ou não reiniciar o compositor, depende do recurso " +"dado. Qualquer recurso experimental não precisa estar disponível ou ser " +"configurável. Não espere que adicionar alguma coisa nesta configuração seja " +"a prova de futuro. Atualmente, palavras-chaves possíveis: • “scale-monitor-" +"framebuffer” — torna o mutter padrão para a disposição de monitores lógicos " +"em um espaço lógico coordenado por pixels, ao dimensionar buffers de quadros " +"de monitor em vez de conteúdo de janela, para gerenciar monitores HiDPI. Não " +"exige uma reinicialização. • “rt-scheduler” — faz o mutter solicitar um " +"agendamento de tempo real de baixa prioridade. O executável ou usuário deve " +"ter CAP_SYS_NICE. Exige uma reinicialização. • “autostart-xwayland” — " +"inicializa o Xwayland de forma relaxada, caso haja clientes X11. Exige uma " +"reinicialização." + +#: data/org.gnome.mutter.gschema.xml.in:134 +msgid "Modifier to use to locate the pointer" +msgstr "Modificador para usar ao localizar o ponteiro" + +#: data/org.gnome.mutter.gschema.xml.in:135 +msgid "This key will initiate the “locate pointer” action." +msgstr "Essa chave vai iniciar a ação de “localizar ponteiro”." + +#: data/org.gnome.mutter.gschema.xml.in:142 +msgid "Timeout for check-alive ping" +msgstr "Tempo limite para o ping de verificação ativa" + +#: data/org.gnome.mutter.gschema.xml.in:143 +msgid "" +"Number of milliseconds a client has to respond to a ping request in order to " +"not be detected as frozen. Using 0 will disable the alive check completely." +msgstr "" +"Número de milissegundos limite dentro do qual um cliente precisa responder a " +"uma solicitação de ping para não ser detectado como congelado. Usar 0 " +"desativará completamente a verificação ativa." + +#: data/org.gnome.mutter.gschema.xml.in:165 +msgid "Select window from tab popup" +msgstr "Selecione a janela a partir da aba instantânea" -#: ../src/core/display.c:387 +#: data/org.gnome.mutter.gschema.xml.in:170 +msgid "Cancel tab popup" +msgstr "Cancelar aba instantânea" + +#: data/org.gnome.mutter.gschema.xml.in:175 +msgid "Switch monitor configurations" +msgstr "Trocar configurações de monitor" + +#: data/org.gnome.mutter.gschema.xml.in:180 +msgid "Rotates the built-in monitor configuration" +msgstr "Gira a configuração de monitor embutido" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Trocar para o VT 1" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Trocar para o VT 2" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Trocar para o VT 3" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Trocar para o VT 4" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Trocar para o VT 5" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Trocar para o VT 6" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Trocar para o VT 7" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Trocar para o VT 8" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Trocar para o VT 9" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Trocar para o VT 10" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Trocar para o VT 11" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Trocar para o VT 12" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "Reabilita atalhos" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow X11 grabs to lock keyboard focus with Xwayland" +msgstr "Permitir as capturas do X11 travar o foco do teclado com Xwayland" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 +msgid "" +"Allow all keyboard events to be routed to X11 “override redirect” windows " +"with a grab when running in Xwayland. This option is to support X11 clients " +"which map an “override redirect” window (which do not receive keyboard " +"focus) and issue a keyboard grab to force all keyboard events to that " +"window. This option is seldom used and has no effect on regular X11 windows " +"which can receive keyboard focus under normal circumstances. For a X11 grab " +"to be taken into account under Wayland, the client must also either send a " +"specific X11 ClientMessage to the root window or be among the applications " +"white-listed in key “xwayland-grab-access-rules”." +msgstr "" +"Permita que todos os eventos do teclado sejam roteados para as janelas " +"“override redirect” do X11 com uma captura ao executar no Xwayland. Esta " +"opção é para ter suporte a clientes X11 que mapeiam uma janela “override " +"redirect” (que não recebe o foco do teclado) e emitem uma captura de teclado " +"para forçar todos os eventos do teclado para aquela janela. Esta opção é " +"raramente usada e não tem efeito nas janelas comuns do X11, que podem " +"receber o foco do teclado em circunstâncias normais. Para que uma captura de " +"X11 seja levada em conta no Wayland, o cliente também deve enviar uma " +"ClientMessage específica do X11 para a janela raiz ou estar entre os " +"aplicativos na lista branca na chave “xwayland-grab-access-rules”." + +#: data/org.gnome.mutter.wayland.gschema.xml.in:84 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "Aplicativos Xwayland com permissão para emitir capturas de teclado" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:85 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "" +"Lista os nomes dos recursos ou classe de recursos do janelas X11 com ou sem " +"permissão para emitir capturas de teclado X11 no Xwayland. O nome do recurso " +"ou a classe de recurso de uma determinada janela X11 podem ser obtidos " +"usando o comando “xprop WM_CLASS”. Há suporte a curingas “*” e “?” nos " +"valores. Os valores que começam com “!” são colocados em uma lista negra, " +"que tem precedência sobre a lista branca, para revogar aplicativos da lista " +"padrão do sistema. A lista de sistema padrão inclui os seguintes " +"aplicativos: “@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@”. Os usuários podem " +"quebrar uma captura existente usando o atalho de teclado específico definido " +"pela chave de associação de tecla “restore-shortcuts”." + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. +#. +#: src/backends/meta-input-settings.c:2631 #, c-format -msgid "Missing %s extension required for compositing" -msgstr "Faltando extensão %s necessária para composição" +msgid "Mode Switch (Group %d)" +msgstr "Alternador de modo (Grupo %d)" + +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2654 +msgid "Switch monitor" +msgstr "Trocar monitor" + +#: src/backends/meta-input-settings.c:2656 +msgid "Show on-screen help" +msgstr "Mostrar ajuda na tela" + +#: src/backends/meta-monitor.c:226 +msgid "Built-in display" +msgstr "Tela embutida" -#: ../src/core/display.c:453 +#: src/backends/meta-monitor.c:255 +msgid "Unknown" +msgstr "Desconhecido" + +#: src/backends/meta-monitor.c:257 +msgid "Unknown Display" +msgstr "Monitor desconhecido" + +#: src/backends/meta-monitor.c:265 +#, c-format +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" + +#: src/backends/meta-monitor.c:273 #, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Falha ao abrir a exibição \"%s\" do X Window System\n" +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" -#: ../src/core/keybindings.c:852 +#. Translators: this string will appear in Sysprof +#: src/backends/meta-profiler.c:79 +msgid "Compositor" +msgstr "Compositor" + +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:533 #, c-format msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" +"Another compositing manager is already running on screen %i on display “%s”." msgstr "" -"Algum outro programa já está usando a chave %s com modificadores %x como uma " -"tecla de atalho\n" +"Outro gerenciador de composição de janelas está em execução na tela %i na " +"área “%s”." -#: ../src/core/main.c:206 +#: src/core/bell.c:192 +msgid "Bell event" +msgstr "Evento de som" + +#: src/core/main.c:190 msgid "Disable connection to session manager" -msgstr "Desabilitar a conexão com o gerenciador de sessões" +msgstr "Desabilita a conexão com o gerenciador de sessões" -#: ../src/core/main.c:212 +#: src/core/main.c:196 msgid "Replace the running window manager" -msgstr "Substituir o gerenciador de janelas em execução" +msgstr "Substitui o gerenciador de janelas em execução" -#: ../src/core/main.c:218 +#: src/core/main.c:202 msgid "Specify session management ID" -msgstr "Especificar o ID do gerenciador de sessões" +msgstr "Especifica o ID do gerenciador de sessões" -#: ../src/core/main.c:223 +#: src/core/main.c:207 msgid "X Display to use" -msgstr "Exibição do X a ser utilizada" +msgstr "Display X a ser usado" -#: ../src/core/main.c:229 +#: src/core/main.c:213 msgid "Initialize session from savefile" -msgstr "Inicializar a sessão a partir do arquivo salvo" +msgstr "Inicializa a sessão a partir do arquivo salvo" -#: ../src/core/main.c:235 +#: src/core/main.c:219 msgid "Make X calls synchronous" -msgstr "Fazer X chamadas síncronas" +msgstr "Faz X chamadas síncronas" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Falha ao varrer a pasta de temas: %s\n" +#: src/core/main.c:226 +msgid "Run as a wayland compositor" +msgstr "Executa como um compositor wayland" + +#: src/core/main.c:232 +msgid "Run as a nested compositor" +msgstr "Executa como um compositor aninhado" + +#: src/core/main.c:238 +msgid "Run wayland compositor without starting Xwayland" +msgstr "Executa o compositor wayland sem iniciar o Xwayland" -#: ../src/core/main.c:520 +#: src/core/main.c:246 +msgid "Run as a full display server, rather than nested" +msgstr "Executa como um servidor de tela cheia, ao invés de aninhado" + +#: src/core/main.c:252 +msgid "Run with X11 backend" +msgstr "Executa com backend X11" + +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:151 #, c-format +msgid "“%s” is not responding." +msgstr "“%s” não está respondendo." + +#: src/core/meta-close-dialog-default.c:153 +msgid "Application is not responding." +msgstr "O aplicativo não está respondendo." + +#: src/core/meta-close-dialog-default.c:158 msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." msgstr "" -"Não foi possível localizar um tema! Verifique se %s existe e contém os temas " -"comuns.\n" +"Você pode escolher aguardar um pouco e continuar ou forçar o aplicativo a " +"sair completamente." + +#: src/core/meta-close-dialog-default.c:165 +msgid "_Force Quit" +msgstr "_Forçar sair" -#: ../src/core/muffin.c:40 +#: src/core/meta-close-dialog-default.c:165 +msgid "_Wait" +msgstr "_Esperar" + +#: src/core/mutter.c:38 #, c-format msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" "This is free software; see the source for copying conditions.\n" "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " "PARTICULAR PURPOSE.\n" msgstr "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., e outros\n" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., e outros\n" "Esse programa é um software livre; veja o código fonte para obter as " "condições de cópia.\n" -"Não há NENHUMA garantia; nem mesmo para o COMERCIALIZAÇÃO ou ADEQUAÇÃO\n" +"Não há NENHUMA garantia; nem mesmo para a COMERCIALIZAÇÃO ou ADEQUAÇÃO\n" "PARA UM PROPÓSITO PARTICULAR.\n" -#: ../src/core/muffin.c:54 +#: src/core/mutter.c:52 msgid "Print version" msgstr "Versão impressa" -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "Lista de plugins de composição separados por vírgula" +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "Plug-in do Mutter para usar" -#: ../src/core/prefs.c:1077 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"As alternativas para aplicativos quebrados estão desabilitadas. É possível " -"que alguns aplicativos não funcionem de maneira adequada.\n" - -#: ../src/core/prefs.c:1152 +#: src/core/prefs.c:1911 #, c-format -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "" -"Não foi possível analisar a descrição da fonte \"%s\" a partir da chave " -"GSettings %s\n" +msgid "Workspace %d" +msgstr "Espaço de trabalho %d" + +#: src/core/util.c:122 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "O Mutter foi compilado sem suporte para modo detalhado\n" -#: ../src/core/prefs.c:1218 +#: src/wayland/meta-wayland-tablet-pad.c:568 #, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"\"%s\" localizado no banco de dados de configurações não é um valor válido " -"para o modificador de botão do mouse\n" +msgid "Mode Switch: Mode %d" +msgstr "Alternador de modo: Modo %d" -#: ../src/core/prefs.c:1739 +#: src/x11/meta-x11-display.c:676 #, c-format msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." msgstr "" -"\"%s\" localizado no banco de dados de configurações não é um valor válido " -"para a tecla de atalho \"%s\"\n" +"A exibição “%s” já possui um gerenciador de janelas; tente usar a opção --" +"replace para substituir o gerenciador de janelas atual." -#: ../src/core/prefs.c:1836 -#, c-format -msgid "Workspace %d" -msgstr "Espaço de trabalho %d" +#: src/x11/meta-x11-display.c:1089 +msgid "Failed to initialize GDK\n" +msgstr "Falha ao inicializar GDK\n" -#: ../src/core/screen.c:730 +#: src/x11/meta-x11-display.c:1113 #, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "A tela %d na exibição \"%s\" é inválida\n" +msgid "Failed to open X Window System display “%s”\n" +msgstr "Falha ao abrir a exibição “%s” do sistema de janelas X\n" -#: ../src/core/screen.c:746 +#: src/x11/meta-x11-display.c:1196 #, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"A tela %d na exibição \"%s\" já possui um gerenciador de janelas; tente usar " -"a opção --replace para substituir o gerenciador de janelas atual.\n" +msgid "Screen %d on display “%s” is invalid\n" +msgstr "A tela %d na exibição “%s” é inválida\n" -#: ../src/core/screen.c:773 +#: src/x11/meta-x11-selection-input-stream.c:460 #, c-format +msgid "Format %s not supported" +msgstr "Sem suporte ao formato %s" + +#: src/x11/session.c:1821 msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." msgstr "" -"Não foi possível obter a seleção do gerenciador de janelas na exibição \"%2$s" -"\" da tela %1$d\n" +"Estas janelas não oferecem suporte para a opção “salvar configuração atual” " +"e precisarão ser reiniciadas manualmente quando você reiniciar a sessão." -#: ../src/core/screen.c:828 +#: src/x11/window-props.c:569 #, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "A tela %d na exibição \"%s\" já possui um gerenciador de janelas\n" +msgid "%s (on %s)" +msgstr "%s (em %s)" -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "Não foi possível liberar a tela %d na exibição \"%s\"\n" +#~ msgid "Move window one workspace to the left" +#~ msgstr "Mover a janela um espaço de trabalho à esquerda" -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Não foi possível criar o diretório \"%s\": %s\n" +#~ msgid "Move window one workspace to the right" +#~ msgstr "Mover a janela um espaço de trabalho à direita" -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "Não foi possível abrir o arquivo de sessão \"%s\" para gravação: %s\n" +#~ msgid "Move to workspace left" +#~ msgstr "Move para o espaço de trabalho à esquerda" -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Erro ao gravar o arquivo de sessão\"%s\": %s\n" +#~ msgid "Move to workspace right" +#~ msgstr "Move para o espaço de trabalho à direita" -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Erro ao fechar o arquivo de sessão \"%s\": %s\n" +#~ msgid "Toggle shaded state" +#~ msgstr "Alternar estado sombreado" -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Falha ao analisar o arquivo de sessão salvo: %s\n" +#~ msgid "background texture could not be created from file" +#~ msgstr "textura de plano de fundo não pôde ser criado de arquivo" -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "O atributo <muffin_session> foi visto, mas já temos o ID da sessão" +#~ msgid "Failed to scan themes directory: %s\n" +#~ msgstr "Falha ao varrer a pasta de temas: %s\n" -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Atributo %s desconhecido no elemento <%s>" +#~ msgid "" +#~ "Could not find a theme! Be sure %s exists and contains the usual themes.\n" +#~ msgstr "" +#~ "Não foi possível localizar um tema! Verifique se %s existe e contém os " +#~ "temas comuns.\n" -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "marca de <window> aninhada" +#~ msgid "Screen %d on display \"%s\" already has a window manager\n" +#~ msgstr "A tela %d na exibição \"%s\" já possui um gerenciador de janelas\n" -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "Elemento %s desconhecido" +#~ msgid "%d x %d" +#~ msgstr "%d x %d" -#: ../src/core/session.c:1809 -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" -"Estas janelas não oferecem suporte para a opção "salvar configuração " -"atual" e precisarão ser reiniciadas manualmente quando você reiniciar a " -"sessão." +#~ msgid "top" +#~ msgstr "superior" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Falha ao abrir o log de depuração: %s\n" +#~ msgid "bottom" +#~ msgstr "inferior" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Falha ao executar fdopen() no arquivo de log %s: %s\n" +#~ msgid "left" +#~ msgstr "esquerda" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "Arquivo de log %s aberto\n" +#~ msgid "right" +#~ msgstr "direita" -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "O Muffin foi compilado sem suporte para modo detalhado\n" +#~ msgid "frame geometry does not specify \"%s\" dimension" +#~ msgstr "a geometria do quadro não especifica a dimensão \"%s\"" -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "Gerenciador de janelas: " +#~ msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" +#~ msgstr "" +#~ "a geometria do quadro não especifica a dimensão \"%s\" da borda \"%s\"" -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "Bug no gerenciador de janelas: " +#~ msgid "Button aspect ratio %g is not reasonable" +#~ msgstr "A taxa de proporção %g do botão não é razoável" -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "Aviso do gerenciador de janelas: " +#~ msgid "Frame geometry does not specify size of buttons" +#~ msgstr "A geometria do quadro não especifica o tamanho dos botões" -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "Erro do gerenciador de janelas: " +#~ msgid "Gradients should have at least two colors" +#~ msgstr "Os degradês devem ter pelo menos duas cores" -#. first time through -#: ../src/core/window.c:7266 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"A janela %s define SM_CLIENT_ID em si mesma, ao invés de definir na janela " -"WM_CLIENT_LEADER como o ICCCM especifica.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7931 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size " -"%d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"A janela %s define uma dica MWM indicando que não é redimensionável, mas " -"define o tamanho mínimo %d x %d e máximo %d x %d; isso não faz muito " -"sentido.\n" +#~ msgid "" +#~ "GTK custom color specification must have color name and fallback in " +#~ "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" +#~ msgstr "" +#~ "A especificação de cor personalizada do GTK deve ter um nome de cor e " +#~ "fallback em parênteses, por exemplo, gtk:custom[foo,bar]; não foi " +#~ "possível analisar \"%s\"" -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "O aplicativo definiu um _NET_WM_PID %lu inválido\n" +#~ msgid "" +#~ "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-" +#~ "z0-9-_ are valid" +#~ msgstr "" +#~ "Caractere inválido \"%c\" no parâmetro color_name do gtk:custom, somente " +#~ "A-Za-z0-9-_ são válidos" -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (em %s)" +#~ msgid "" +#~ "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " +#~ "fit the format" +#~ msgstr "" +#~ "Formato gtk:custom é \"gtk:custom(color_name,fallback)\", \"%s\" não é " +#~ "adequado ao formato" -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "Janela WM_TRANSIENT_FOR inválida 0x%lx especificada para %s.\n" +#~ msgid "" +#~ "GTK color specification must have the state in brackets, e.g. gtk:" +#~ "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "O estado da especificação de cor GTK deve estar entre colchetes, por " +#~ "exemplo, gtk:fg[NORMAL], onde NORMAL é o estado; não foi possível " +#~ "analisar \"%s\"" -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "Janela WM_TRANSIENT_FOR 0x%lx especificada para %s iriar criar loop.\n" +#~ msgid "" +#~ "GTK color specification must have a close bracket after the state, e.g. " +#~ "gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "Deve haver um colchete de fechamento após o estado da especificação de " +#~ "cor GTK, por exemplo, gtk:fg[NORMAL], onde NORMAL é o estado; não foi " +#~ "possível analisar \"%s\"" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"A janela 0x%lx tem a propriedade %s\n" -"que deveria ter tipo %s formato %d\n" -"e, na verdade, ela tem tipo %s, %d n_items %d.\n" -"Isso é bem provavelmente um erro do aplicativo, não do gerenciador de " -"janelas.\n" -"A janela tem title=\"%s\" class=\"%s\" name=\"%s\"\n" - -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "A propriedade %s na janela 0x%lx continha UTF-8 inválido\n" +#~ msgid "Did not understand state \"%s\" in color specification" +#~ msgstr "O estado \"%s\" não foi compreendido na especificação de cor" -#: ../src/core/xprops.c:494 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"A propriedade %s na janela 0x%lx continha UTF-8 inválido para o item %d da " -"lista\n" +#~ msgid "Did not understand color component \"%s\" in color specification" +#~ msgstr "" +#~ "O componente de cor \"%s\" não foi compreendido na especificação de cor" -#: ../src/muffin.desktop.in.h:1 ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" +#~ msgid "" +#~ "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit " +#~ "the format" +#~ msgstr "" +#~ "O formato de mistura é \"blend/bg_color/fg_color/alpha\"; \"%s\" não é " +#~ "adequado ao formato" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 -msgid "Attach modal dialogs" -msgstr "Anexar diálogos modais" +#~ msgid "Could not parse alpha value \"%s\" in blended color" +#~ msgstr "Não foi possível analisar o valor de alfa \"%s\" na cor misturada" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 -msgid "Cancel tab popup" -msgstr "Cancelar aba instantânea" +#~ msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" +#~ msgstr "O valor de alfa \"%s\" na cor misturada não está entre 0,0 e 1,0" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"Determina se as janelas ocultas (janelas minimizadas e nas outras áreas de " -"trabalho que não é a atual) devem ser mantidas ativas." +#~ msgid "" +#~ "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the " +#~ "format" +#~ msgstr "" +#~ "O formato de sombra é \"shade/base_color/factor\", \"%s\" não é adequado " +#~ "ao formato" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 -msgid "" -"Determines whether the use of popup and highlight frame should be disabled " -"for window cycling." -msgstr "" -"Determina se a utilização de quadros instantâneos e destacados devem ser " -"desabilitados na alternância de janelas." +#~ msgid "Could not parse shade factor \"%s\" in shaded color" +#~ msgstr "Não foi possível analisar o fator de sombra \"%s\" na cor sombreada" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -msgid "" -"Determines whether workspace switching should happen for windows on all " -"monitors or only for windows on the primary monitor." -msgstr "" -"Determina se a troca de área de trabalho deve ocorrer para janelas em todos " -"os monitores ou apenas para janelas no monitor principal." +#~ msgid "Shade factor \"%s\" in shaded color is negative" +#~ msgstr "O fator de sombra \"%s\" na cor sombreada é negativo" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 -msgid "" -"Determines whether workspaces are managed dynamically or whether there's a " -"static number of workspaces (determined by the num-workspaces key in org." -"gnome.desktop.wm.preferences)." -msgstr "" -"Determina se as áreas de trabalho são gerenciadas de forma dinâmica ou se há " -"um número estático de áreas de trabalho (determinado pela chave num-" -"workspaces em org.cinnamon.desktop.wm.preferences)." +#~ msgid "Could not parse color \"%s\"" +#~ msgstr "Não foi possível analisar a cor \"%s\"" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 -msgid "Draggable border width" -msgstr "Largura da borda arrastável" +#~ msgid "Coordinate expression contains character '%s' which is not allowed" +#~ msgstr "" +#~ "A expressão coordenada contém o caractere \"%s\" que não é permitido" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 -msgid "Enable edge tiling when dropping windows on screen edges" -msgstr "" -"Habilitar contorno ladrilhado ao arrastar janelas sobre as bordas da tela" +#~ msgid "" +#~ "Coordinate expression contains floating point number '%s' which could not " +#~ "be parsed" +#~ msgstr "" +#~ "A expressão coordenada contém o número de ponto flutuante \"%s\" que não " +#~ "pôde ser analisado" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 -msgid "" -"If enabled, dropping windows on vertical screen edges maximizes them " -"vertically and resizes them horizontally to cover half of the available " -"area. Dropping windows on the top screen edge maximizes them completely." -msgstr "" -"Caso esteja habilitado, ao arrastar janelas sobre bordas verticais da tela " -"as maximizará verticalmente e as redimensionarão horizontalmente para cobrir " -"metade da área disponível. Arrastar janelas no topo da borda da tela as " -"maximiza completamente." +#~ msgid "" +#~ "Coordinate expression contains integer '%s' which could not be parsed" +#~ msgstr "" +#~ "A expressão coordenada contém o inteiro \"%s\" que não pôde ser analisado" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 -msgid "Live Hidden Windows" -msgstr "Janelas ocultas ativas" +#~ msgid "" +#~ "Coordinate expression contained unknown operator at the start of this " +#~ "text: \"%s\"" +#~ msgstr "" +#~ "A expressão coordenada continha um operador desconhecido no início deste " +#~ "texto: \"%s\"" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 -msgid "Modifier to use for extended window management operations" -msgstr "" -"Modificador a ser usado para operações de gerenciamento de janelas extendido." +#~ msgid "Coordinate expression was empty or not understood" +#~ msgstr "A expressão coordenada estava vazia ou não foi compreendida" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 -msgid "No tab popup" -msgstr "Nenhuma aba instantânea" +#~ msgid "Coordinate expression results in division by zero" +#~ msgstr "A expressão coordenada resulta na divisão por zero" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 -msgid "Select window from tab popup" -msgstr "Selecione a janela a partir da aba instantânea" +#~ msgid "" +#~ "Coordinate expression tries to use mod operator on a floating-point number" +#~ msgstr "" +#~ "A expressão coordenada tenta usar o operador mod em um número de ponto " +#~ "flutuante" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 -msgid "" -"The amount of total draggable borders. If the theme's visible borders are " -"not enough, invisible borders will be added to meet this value." -msgstr "" -"A quantidade do total de bordas arrastáveis. Se as bordas dos temas visíveis " -"não são suficientes, as bordas invisíveis serão adicionadas para encontrar " -"este valor." +#~ msgid "" +#~ "Coordinate expression has an operator \"%s\" where an operand was expected" +#~ msgstr "" +#~ "A expressão coordenada tem o operador \"%s\" onde era esperado um operando" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 -msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." -msgstr "" -"Esta chave irá iniciar a \"sobreposição\", que é a combinação de visão de " -"janela e sistema de lançamento de aplicativos. O padrão pretendido é a " -"\"tecla Windows\" no hardware do computador. É esperada para esta associação " -"tanto o padrão quanto a definição de uma string vazia. " +#~ msgid "Coordinate expression had an operand where an operator was expected" +#~ msgstr "" +#~ "A expressão coordenada tinha um operando onde era esperado um operador" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 -msgid "" -"When true, instead of having independent titlebars, modal dialogs appear " -"attached to the titlebar of the parent window and are moved together with " -"the parent window." -msgstr "" -"Quando verdadeiro, em vez de terem barras de título independentes, os " -"diálogos modais surgem anexados à barra de título da janela pai e são " -"movidos juntamente com a janela pai." +#~ msgid "Coordinate expression ended with an operator instead of an operand" +#~ msgstr "" +#~ "A expressão coordenada terminou com um operador, em vez de com um operando" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:17 -msgid "Workspaces are managed dynamically" -msgstr "Áreas de trabalho são gerenciadas dinamicamente" +#~ msgid "" +#~ "Coordinate expression has operator \"%c\" following operator \"%c\" with " +#~ "no operand in between" +#~ msgstr "" +#~ "A expressão coordenada tem o operador \"%c\" após o operador \"%c\" sem " +#~ "nenhum operando entre eles" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:18 -msgid "Workspaces only on primary" -msgstr "Áreas de trabalho apenas para a principal" +#~ msgid "Coordinate expression had unknown variable or constant \"%s\"" +#~ msgstr "" +#~ "A expressão coordenada tinha uma variável ou uma constante desconhecida " +#~ "\"%s\"" -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "Uso: %s\n" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "Mi_nimizar" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "Ma_ximizar" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "Desfazer ma_ximizar" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "_Enrolar" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "_Desenrolar" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "_Mover" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "_Redimensionar" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "Mover barra de título para te_la" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "Sempre no _topo" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "_Sempre no espaço de trabalho visível" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "_Apenas neste espaço de trabalho" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "Mover para o espaço de trabalho à _esquerda" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "Mover para o espaço de trabalho à d_ireita" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "Mover para o espaço de trabalho _acima" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "Mover para o espaço de trabalho a_baixo" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "Fe_char" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "Espaço de trabalho %d%n" +#~ msgid "Coordinate expression parser overflowed its buffer." +#~ msgstr "O analisador de expressão coordenada estourou o buffer." -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "Espaço de trabalho 1_0" +#~ msgid "" +#~ "Coordinate expression had a close parenthesis with no open parenthesis" +#~ msgstr "" +#~ "A expressão coordenada tinha um parêntese de fechamento sem um parêntese " +#~ "de abertura" -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "Espaço de trabalho %s%d" +#~ msgid "" +#~ "Coordinate expression had an open parenthesis with no close parenthesis" +#~ msgstr "" +#~ "A expressão coordenada tinha um parêntese de abertura sem um parêntese de " +#~ "fechamento" -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "Mover para _outro espaço de trabalho" +#~ msgid "Coordinate expression doesn't seem to have any operators or operands" +#~ msgstr "" +#~ "Aparentemente não há operadores nem operandos na expressão coordenada" -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" +#~ msgid "Theme contained an expression that resulted in an error: %s\n" +#~ msgstr "O tema continha uma expressão que resultou em um erro: %s \n" -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" +#~ msgid "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " +#~ "specified for this frame style" +#~ msgstr "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> deve ser " +#~ "especificado para este estilo de quadro" -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "superior" +#~ msgid "" +#~ "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/" +#~ ">" +#~ msgstr "" +#~ "<frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/> " +#~ "ausente" -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "inferior" +#~ msgid "Failed to load theme \"%s\": %s\n" +#~ msgstr "Falha ao carregar o tema \"%s\": %s\n" -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "esquerda" +#~ msgid "No <%s> set for theme \"%s\"" +#~ msgstr "Nenhum <%s> definido para o tema \"%s\"" -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "direita" +#~ msgid "" +#~ "No frame style set for window type \"%s\" in theme \"%s\", add a <window " +#~ "type=\"%s\" style_set=\"whatever\"/> element" +#~ msgstr "" +#~ "Nenhum estilo de quadro definido para o tipo de janela \"%s\" no tema \"%s" +#~ "\", adicione um elemento <window type=\"%s\" style_set=\"whatever\"/>" -#: ../src/ui/theme.c:286 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "a geometria do quadro não especifica a dimensão \"%s\"" +#~ msgid "" +#~ "User-defined constants must begin with a capital letter; \"%s\" does not" +#~ msgstr "" +#~ "As constantes definidas pelo usuário devem iniciar com letra maiúscula; " +#~ "\"%s\" não inicia" -#: ../src/ui/theme.c:305 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "a geometria do quadro não especifica a dimensão \"%s\" da borda \"%s\"" +#~ msgid "Constant \"%s\" has already been defined" +#~ msgstr "A constante \"%s\" já foi definida" -#: ../src/ui/theme.c:342 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "A taxa de proporção %g do botão não é razoável" +#~ msgid "No \"%s\" attribute on element <%s>" +#~ msgstr "Nenhum atributo \"%s\" no elemento <%s>" -#: ../src/ui/theme.c:354 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "A geometria do quadro não especifica o tamanho dos botões" +#~ msgid "Line %d character %d: %s" +#~ msgstr "Caractere %d da linha %d: %s" -#: ../src/ui/theme.c:1067 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "Os gradientes devem ter pelo menos duas cores" +#~ msgid "Attribute \"%s\" repeated twice on the same <%s> element" +#~ msgstr "O atributo \"%s\" foi repetido duas vezes no mesmo elemento <%s>" -#: ../src/ui/theme.c:1219 -#, c-format -msgid "" -"GTK custom color specification must have color name and fallback in " -"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" -msgstr "" -"A especificação de cor personalizada do GTK deve ter um nome de cor e " -"fallback em parênteses, por exemplo, gtk:custom[foo,bar]; não foi possível " -"analisar \"%s\"" +#~ msgid "Attribute \"%s\" is invalid on <%s> element in this context" +#~ msgstr "O atributo \"%s\" é inválido no elemento <%s> neste contexto" -#: ../src/ui/theme.c:1235 -#, c-format -msgid "" -"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" -"_ are valid" -msgstr "" -"Caractere inválido \"%c\" no parâmetro color_name do gtk:custom, somente A-" -"Za-z0-9-_ são válidos" +#~ msgid "Could not parse \"%s\" as an integer" +#~ msgstr "Não foi possível analisar \"%s\" como um inteiro" -#: ../src/ui/theme.c:1249 -#, c-format -msgid "" -"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " -"fit the format" -msgstr "" -"Formato gtk:custom é \"gtk:custom(color_name,fallback)\", \"%s\" não é " -"adequado ao formato" +#~ msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +#~ msgstr "" +#~ "Os caracteres à direita \"%s\" na string \"%s\" não foram compreendidos" -#: ../src/ui/theme.c:1294 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"O estado da especificação de cor GTK deve estar entre colchetes, por " -"exemplo, gtk:fg[NORMAL], onde NORMAL é o estado; não foi possível analisar " -"\"%s\"" +#~ msgid "Integer %ld must be positive" +#~ msgstr "O inteiro %ld deve ser positivo" + +#~ msgid "Integer %ld is too large, current max is %d" +#~ msgstr "O inteiro %ld é muito grande; o valor máximo atual é %d" + +#~ msgid "Could not parse \"%s\" as a floating point number" +#~ msgstr "Não foi possível analisar \"%s\" como um número de ponto flutuante" + +#~ msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" +#~ msgstr "Os valores booleanos devem ser \"true\" ou \"false\" e não \"%s\"" + +#~ msgid "Angle must be between 0.0 and 360.0, was %g\n" +#~ msgstr "O ângulo deve estar entre 0,0 e 360,0 e era %g\n" + +#~ msgid "" +#~ "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" +#~ msgstr "" +#~ "Alfa deve estar entre 0,0 (invisível) e 1,0 (totalmente opaco) e era %g\n" + +#~ msgid "" +#~ "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," +#~ "large,x-large,xx-large)\n" +#~ msgstr "" +#~ "Escala de título \"%s\" inválida (deve ser super pequena, extra pequena, " +#~ "pequena, média, grande, extra grande ou super grande)\n" + +#~ msgid "<%s> name \"%s\" used a second time" +#~ msgstr "<%s> nome \"%s\" usado uma segunda vez" + +#~ msgid "<%s> parent \"%s\" has not been defined" +#~ msgstr "<%s> pai \"%s\" não foi definido" + +#~ msgid "<%s> geometry \"%s\" has not been defined" +#~ msgstr "<%s> geometria \"%s\" não foi definida" + +#~ msgid "<%s> must specify either a geometry or a parent that has a geometry" +#~ msgstr "" +#~ "<%s> deve especificar uma geometria ou um pai que tenha uma geometria" + +#~ msgid "You must specify a background for an alpha value to be meaningful" +#~ msgstr "" +#~ "Você pode especificar um plano de fundo para que um valor alfa faça " +#~ "sentido" + +#~ msgid "Unknown type \"%s\" on <%s> element" +#~ msgstr "Tipo \"%s\" desconhecido no elemento <%s>" + +#~ msgid "Unknown style_set \"%s\" on <%s> element" +#~ msgstr "conjunto_de_estilo \"%s\" desconhecido no elemento <%s>" + +#~ msgid "Window type \"%s\" has already been assigned a style set" +#~ msgstr "O tipo de janela \"%s\" já foi atribuído a um estilo definido" + +#~ msgid "Element <%s> is not allowed below <%s>" +#~ msgstr "O elemento <%s> não é permitido abaixo de <%s>" + +#~ msgid "" +#~ "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio" +#~ "\" for buttons" +#~ msgstr "" +#~ "Não foi possível especificar \"button_width\"/\"button_height\" e " +#~ "\"aspect_ratio\" para os botões" + +#~ msgid "Distance \"%s\" is unknown" +#~ msgstr "A distância \"%s\" é desconhecida" + +#~ msgid "Aspect ratio \"%s\" is unknown" +#~ msgstr "A taxa de proporção \"%s\" é desconhecida" + +#~ msgid "Border \"%s\" is unknown" +#~ msgstr "A borda \"%s\" é desconhecida" -#: ../src/ui/theme.c:1308 -#, c-format -msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"Deve haver um colchete de fechamento após o estado da especificação de cor " -"GTK, por exemplo, gtk:fg[NORMAL], onde NORMAL é o estado; não foi possível " -"analisar \"%s\"" +#~ msgid "No \"start_angle\" or \"from\" attribute on element <%s>" +#~ msgstr "Nenhum atributo \"start_angle\" ou \"from\" no elemento <%s>" -#: ../src/ui/theme.c:1319 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "O estado \"%s\" não foi compreendido na especificação de cor" +#~ msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" +#~ msgstr "Nenhum atributo \"extent_angle\" ou \"to\" no elemento <%s>" -#: ../src/ui/theme.c:1332 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "" -"O componente de cor \"%s\" não foi compreendido na especificação de cor" +#~ msgid "Did not understand value \"%s\" for type of gradient" +#~ msgstr "O valor \"%s\" não foi compreendido para o tipo de degradê" -#: ../src/ui/theme.c:1361 -#, c-format -msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" -msgstr "" -"O formato de mistura é \"blend/bg_color/fg_color/alpha\"; \"%s\" não é " -"adequado ao formato" +#~ msgid "Did not understand fill type \"%s\" for <%s> element" +#~ msgstr "" +#~ "O tipo de preenchimento \"%s\" não foi compreendido para o elemento <%s>" -#: ../src/ui/theme.c:1372 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "Não foi possível analisar o valor de alfa \"%s\" na cor misturada" +#~ msgid "Did not understand state \"%s\" for <%s> element" +#~ msgstr "O estado \"%s\" não foi compreendido para o elemento <%s>" -#: ../src/ui/theme.c:1382 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "O valor de alfa \"%s\" na cor misturada não está entre 0,0 e 1,0" +#~ msgid "Did not understand shadow \"%s\" for <%s> element" +#~ msgstr "A sombra \"%s\" não foi compreendida para o elemento <%s>" -#: ../src/ui/theme.c:1429 -#, c-format -msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "" -"O formato de sombra é \"shade/base_color/factor\", \"%s\" não é adequado ao " -"formato" +#~ msgid "Did not understand arrow \"%s\" for <%s> element" +#~ msgstr "A seta \"%s\" não foi compreendida para o elemento <%s>" -#: ../src/ui/theme.c:1440 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "Não foi possível analisar o fator de sombra \"%s\" na cor sombreada" +#~ msgid "No <draw_ops> called \"%s\" has been defined" +#~ msgstr "Nenhum <draw_ops> chamado \"%s\" foi definido" -#: ../src/ui/theme.c:1450 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "O fator de sombra \"%s\" na cor sombreada é negativo" +#~ msgid "Including draw_ops \"%s\" here would create a circular reference" +#~ msgstr "A inclusão do draw_ops \"%s\" aqui criaria uma referência circular" -#: ../src/ui/theme.c:1479 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Não foi possível analisar a cor \"%s\"" +#~ msgid "Unknown position \"%s\" for frame piece" +#~ msgstr "Posição \"%s\" desconhecida para a parte do quadro" -#: ../src/ui/theme.c:1790 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "A expressão coordenada contém o caractere \"%s\" que não é permitido" +#~ msgid "Frame style already has a piece at position %s" +#~ msgstr "O estilo de quadro já tem uma parte na posição %s" -#: ../src/ui/theme.c:1817 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "" -"A expressão coordenada contém o número de ponto flutuante \"%s\" que não " -"pôde ser analisado" +#~ msgid "No <draw_ops> with the name \"%s\" has been defined" +#~ msgstr "Nenhum <draw_ops> com o nome \"%s\" foi definido" -#: ../src/ui/theme.c:1831 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "" -"A expressão coordenada contém o inteiro \"%s\" que não pôde ser analisado" +#~ msgid "Unknown function \"%s\" for button" +#~ msgstr "Função \"%s\" desconhecida para o botão" -#: ../src/ui/theme.c:1953 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "" -"A expressão coordenada continha um operador desconhecido no início deste " -"texto: \"%s\"" +#~ msgid "Button function \"%s\" does not exist in this version (%d, need %d)" +#~ msgstr "" +#~ "A função \"%s\" de botão não existe nesta versão (%d, necessário %d)" -#: ../src/ui/theme.c:2010 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "A expressão coordenada estava vazia ou não foi compreendida" +#~ msgid "Unknown state \"%s\" for button" +#~ msgstr "Estado \"%s\" desconhecido para o botão" -#: ../src/ui/theme.c:2121 ../src/ui/theme.c:2131 ../src/ui/theme.c:2165 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "A expressão coordenada resulta na divisão por zero" +#~ msgid "Frame style already has a button for function %s state %s" +#~ msgstr "O estilo de quadro já possui um botão para o estado %s da função %s" -#: ../src/ui/theme.c:2173 -#, c-format -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "" -"A expressão coordenada tenta usar o operador mod em um número de ponto " -"flutuante" +#~ msgid "\"%s\" is not a valid value for focus attribute" +#~ msgstr "\"%s\" não é um valor válido para o atributo de foco" -#: ../src/ui/theme.c:2229 -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "" -"A expressão coordenada tem o operador \"%s\" onde era esperado um operando" +#~ msgid "\"%s\" is not a valid value for state attribute" +#~ msgstr "\"%s\" não é um valor válido para o atributo de estado" -#: ../src/ui/theme.c:2238 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "A expressão coordenada tinha um operando onde era esperado um operador" +#~ msgid "A style called \"%s\" has not been defined" +#~ msgstr "Um estilo chamado \"%s\" não foi definido" -#: ../src/ui/theme.c:2246 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "" -"A expressão coordenada terminou com um operador, em vez de com um operando" +#~ msgid "\"%s\" is not a valid value for resize attribute" +#~ msgstr "\"%s\" não é um valor válido para o atributo de redimensionamento" -#: ../src/ui/theme.c:2256 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" -"A expressão coordenada tem o operador \"%c\" após o operador \"%c\" sem " -"nenhum operando entre eles" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized/shaded " +#~ "states" +#~ msgstr "" +#~ "Não deve haver o atributo \"resize\" no elemento <%s> para os estados " +#~ "maximizado/sombreado" -#: ../src/ui/theme.c:2407 ../src/ui/theme.c:2452 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "" -"A expressão coordenada tinha uma variável ou uma constante desconhecida \"%s" -"\"" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized states" +#~ msgstr "" +#~ "Não deve haver o atributo \"resize\" no elemento <%s> para os estados " +#~ "maximizados" -#: ../src/ui/theme.c:2506 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "O analisador de expressão coordenada estourou o buffer." +#~ msgid "Style has already been specified for state %s resize %s focus %s" +#~ msgstr "" +#~ "O estilo já foi especificado para o foco %s de redimensionamento %s do " +#~ "estado %s" -#: ../src/ui/theme.c:2535 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "" -"A expressão coordenada tinha um parêntese de fechamento sem um parêntese de " -"abertura" +#~ msgid "Style has already been specified for state %s focus %s" +#~ msgstr "O estilo já foi especificado para o foco %s do estado %s" -#: ../src/ui/theme.c:2599 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "" -"A expressão coordenada tinha um parêntese de abertura sem um parêntese de " -"fechamento" +#~ msgid "" +#~ "Can't have a two draw_ops for a <piece> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Não pode haver um segundo draw_ops para um elemento <piece> (o tema " +#~ "especificou um atributo draw_ops e um elemento <draw_ops> ou especificou " +#~ "dois elementos)" -#: ../src/ui/theme.c:2610 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "Aparentemente não há operadores nem operandos na expressão coordenada" +#~ msgid "" +#~ "Can't have a two draw_ops for a <button> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Não pode haver um segundo draw_ops para um elemento <button> (o tema " +#~ "especificou um atributo draw_ops e um elemento <draw_ops> ou especificou " +#~ "dois elementos)" -#: ../src/ui/theme.c:2822 ../src/ui/theme.c:2842 ../src/ui/theme.c:2862 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "O tema continha uma expressão que resultou em um erro: %s \n" +#~ msgid "" +#~ "Can't have a two draw_ops for a <menu_icon> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Não pode haver um segundo draw_ops para um elemento <menu_icon> (o tema " +#~ "especificou um atributo draw_ops e um elemento <draw_ops> ou especificou " +#~ "dois elementos)" -#: ../src/ui/theme.c:4533 -#, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> deve ser " -"especificado para este estilo de quadro" +#~ msgid "Bad version specification '%s'" +#~ msgstr "Especificação da versão inválida \"%s\"" -#: ../src/ui/theme.c:5066 ../src/ui/theme.c:5091 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" -"<frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/> ausente" +#~ msgid "" +#~ "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" +#~ "theme-2.xml" +#~ msgstr "" +#~ "O atributo \"versão\" não pode ser usado em metacity-theme-1.xml ou " +#~ "metacity-theme-2.xml" -#: ../src/ui/theme.c:5139 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Falha ao carregar o tema \"%s\": %s\n" +#~ msgid "" +#~ "Theme requires version %s but latest supported theme version is %d.%d" +#~ msgstr "" +#~ "Tema requer versão %s, mas a última versão que o tema suporta é %d.%d" -#: ../src/ui/theme.c:5275 ../src/ui/theme.c:5282 ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 ../src/ui/theme.c:5303 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "Nenhum <%s> definido para o tema \"%s\"" +#~ msgid "Outermost element in theme must be <metacity_theme> not <%s>" +#~ msgstr "" +#~ "O elemento mais externo no tema deve ser <metacity_theme> e não <%s>" -#: ../src/ui/theme.c:5311 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" -"Nenhum estilo de quadro definido para o tipo de janela \"%s\" no tema \"%s" -"\", adicione um elemento <window type=\"%s\" style_set=\"whatever\"/>" +#~ msgid "" +#~ "Element <%s> is not allowed inside a name/author/date/description element" +#~ msgstr "" +#~ "O elemento <%s> não é permitido em um elemento nome/autor/data/descrição" -#: ../src/ui/theme.c:5709 ../src/ui/theme.c:5771 ../src/ui/theme.c:5834 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" -"As constantes definidas pelo usuário devem iniciar com letra maiúscula; \"%s" -"\" não inicia" +#~ msgid "Element <%s> is not allowed inside a <constant> element" +#~ msgstr "O elemento <%s> não é permitido em um elemento <constant>" -#: ../src/ui/theme.c:5717 ../src/ui/theme.c:5779 ../src/ui/theme.c:5842 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "A constante \"%s\" já foi definida" +#~ msgid "" +#~ "Element <%s> is not allowed inside a distance/border/aspect_ratio element" +#~ msgstr "" +#~ "O elemento <%s> não é permitido em um elemento distância/borda/" +#~ "taxa_de_proporção" -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. -#. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "Nenhum atributo \"%s\" no elemento <%s>" +#~ msgid "Element <%s> is not allowed inside a draw operation element" +#~ msgstr "" +#~ "O elemento <%s> não é permitido em um elemento de operação de desenho" -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Caractere %d da linha %d: %s" +#~ msgid "Element <%s> is not allowed inside a <%s> element" +#~ msgstr "O elemento <%s> não é permitido em um elemento <%s>" -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "O atributo \"%s\" foi repetido duas vezes no mesmo elemento <%s>" +#~ msgid "No draw_ops provided for frame piece" +#~ msgstr "Nenhum draw_ops foi fornecido para a parte do quadro" -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "O atributo \"%s\" é inválido no elemento <%s> neste contexto" +#~ msgid "No draw_ops provided for button" +#~ msgstr "Nenhum draw_ops foi fornecido para o botão" -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "Não foi possível analisar \"%s\" como um inteiro" +#~ msgid "No text is allowed inside element <%s>" +#~ msgstr "Nenhum texto é permitido no elemento <%s>" -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "" -"Os caracteres à direita \"%s\" na string \"%s\" não foram compreendidos" +#~ msgid "<%s> specified twice for this theme" +#~ msgstr "<%s> especificado duas vezes para este tema" -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "O inteiro %ld deve ser positivo" +#~ msgid "Failed to find a valid file for theme %s\n" +#~ msgstr "Falha ao localizar um arquivo válido para o tema %s\n" -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "O inteiro %ld é muito grande; o valor máximo atual é %d" +#~ msgid "Unknown window information request: %d" +#~ msgstr "Informação solicitada de janela desconhecida: %d" -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "Não foi possível analisar \"%s\" como um número de ponto flutuante" +#~ msgid "Missing %s extension required for compositing" +#~ msgstr "Faltando extensão %s necessária para composição" -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "Os valores booleanos devem ser \"true\" ou \"false\" e não \"%s\"" +#~ msgid "" +#~ "Some other program is already using the key %s with modifiers %x as a " +#~ "binding\n" +#~ msgstr "" +#~ "Algum outro programa já está usando a chave %s com modificadores %x como " +#~ "uma tecla de atalho\n" -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "O ângulo deve estar entre 0,0 e 360,0 e era %g\n" +#~ msgid "\"%s\" is not a valid accelerator\n" +#~ msgstr "\"%s\" não é um acelerador válido\n" -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" -"Alfa deve estar entre 0,0 (invisível) e 1,0 (totalmente opaco) e era %g\n" +#~ msgid "" +#~ "Workarounds for broken applications disabled. Some applications may not " +#~ "behave properly.\n" +#~ msgstr "" +#~ "As alternativas para aplicativos quebrados estão desabilitadas. É " +#~ "possível que alguns aplicativos não funcionem de maneira adequada.\n" -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"Escala de título \"%s\" inválida (deve ser super pequena, extra pequena, " -"pequena, média, grande, extra grande ou super grande)\n" +#~ msgid "Could not parse font description \"%s\" from GSettings key %s\n" +#~ msgstr "" +#~ "Não foi possível analisar a descrição da fonte \"%s\" a partir da chave " +#~ "GSettings %s\n" -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s> nome \"%s\" usado uma segunda vez" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" +#~ msgstr "" +#~ "\"%s\" localizado no banco de dados de configurações não é um valor " +#~ "válido para o modificador de botão do mouse\n" -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "<%s> pai \"%s\" não foi definido" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for " +#~ "keybinding \"%s\"\n" +#~ msgstr "" +#~ "\"%s\" localizado no banco de dados de configurações não é um valor " +#~ "válido para a tecla de atalho \"%s\"\n" -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "<%s> geometria \"%s\" não foi definida" +#~ msgid "" +#~ "Could not acquire window manager selection on screen %d display \"%s\"\n" +#~ msgstr "" +#~ "Não foi possível obter a seleção do gerenciador de janelas na exibição " +#~ "\"%2$s\" da tela %1$d\n" -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "<%s> deve especificar uma geometria ou um pai que tenha uma geometria" +#~ msgid "Could not release screen %d on display \"%s\"\n" +#~ msgstr "Não foi possível liberar a tela %d na exibição \"%s\"\n" -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "" -"Você pode especificar um plano de fundo para que um valor alfa faça sentido" +#~ msgid "Could not create directory '%s': %s\n" +#~ msgstr "Não foi possível criar o diretório \"%s\": %s\n" -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Tipo \"%s\" desconhecido no elemento <%s>" +#~ msgid "Could not open session file '%s' for writing: %s\n" +#~ msgstr "" +#~ "Não foi possível abrir o arquivo de sessão \"%s\" para gravação: %s\n" -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "conjunto_de_estilo \"%s\" desconhecido no elemento <%s>" +#~ msgid "Error writing session file '%s': %s\n" +#~ msgstr "Erro ao gravar o arquivo de sessão\"%s\": %s\n" -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "O tipo de janela \"%s\" já foi atribuído a um estilo definido" - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "O elemento <%s> não é permitido abaixo de <%s>" +#~ msgid "Error closing session file '%s': %s\n" +#~ msgstr "Erro ao fechar o arquivo de sessão \"%s\": %s\n" -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" -msgstr "" -"Não foi possível especificar \"button_width\"/\"button_height\" e " -"\"aspect_ratio\" para os botões" +#~ msgid "Failed to parse saved session file: %s\n" +#~ msgstr "Falha ao analisar o arquivo de sessão salvo: %s\n" -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "A distância \"%s\" é desconhecida" +#~ msgid "<mutter_session> attribute seen but we already have the session ID" +#~ msgstr "O atributo <mutter_session> foi visto, mas já temos o ID da sessão" -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "A taxa de proporção \"%s\" é desconhecida" +#~ msgid "Unknown attribute %s on <%s> element" +#~ msgstr "Atributo %s desconhecido no elemento <%s>" -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "A borda \"%s\" é desconhecida" +#~ msgid "nested <window> tag" +#~ msgstr "marca de <window> aninhada" -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "Nenhum atributo \"start_angle\" ou \"from\" no elemento <%s>" +#~ msgid "Unknown element %s" +#~ msgstr "Elemento %s desconhecido" -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "Nenhum atributo \"extent_angle\" ou \"to\" no elemento <%s>" +#~ msgid "Failed to open debug log: %s\n" +#~ msgstr "Falha ao abrir o log de depuração: %s\n" -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "O valor \"%s\" não foi compreendido para o tipo de gradiente" +#~ msgid "Failed to fdopen() log file %s: %s\n" +#~ msgstr "Falha ao executar fdopen() no arquivo de log %s: %s\n" -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "" -"O tipo de preenchimento \"%s\" não foi compreendido para o elemento <%s>" +#~ msgid "Opened log file %s\n" +#~ msgstr "Arquivo de log %s aberto\n" -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "O estado \"%s\" não foi compreendido para o elemento <%s>" +#~ msgid "Window manager: " +#~ msgstr "Gerenciador de janelas: " -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "A sombra \"%s\" não foi compreendida para o elemento <%s>" +#~ msgid "Bug in window manager: " +#~ msgstr "Bug no gerenciador de janelas: " -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "A seta \"%s\" não foi compreendida para o elemento <%s>" +#~ msgid "Window manager warning: " +#~ msgstr "Aviso do gerenciador de janelas: " -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "Nenhum <draw_ops> chamado \"%s\" foi definido" +#~ msgid "Window manager error: " +#~ msgstr "Erro do gerenciador de janelas: " -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "A inclusão do draw_ops \"%s\" aqui criaria uma referência circular" +#~ msgid "" +#~ "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " +#~ "window as specified in the ICCCM.\n" +#~ msgstr "" +#~ "A janela %s define SM_CLIENT_ID em si mesma, ao invés de definir na " +#~ "janela WM_CLIENT_LEADER como o ICCCM especifica.\n" -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Posição \"%s\" desconhecida para a parte do quadro" +#~ msgid "" +#~ "Window %s sets an MWM hint indicating it isn't resizable, but sets min " +#~ "size %d x %d and max size %d x %d; this doesn't make much sense.\n" +#~ msgstr "" +#~ "A janela %s define uma dica MWM indicando que não é redimensionável, mas " +#~ "define o tamanho mínimo %d x %d e máximo %d x %d; isso não faz muito " +#~ "sentido.\n" -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "O estilo de quadro já tem uma parte na posição %s" +#~ msgid "Application set a bogus _NET_WM_PID %lu\n" +#~ msgstr "O aplicativo definiu um _NET_WM_PID %lu inválido\n" -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "Nenhum <draw_ops> com o nome \"%s\" foi definido" +#~ msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +#~ msgstr "Janela WM_TRANSIENT_FOR inválida 0x%lx especificada para %s.\n" -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Função \"%s\" desconhecida para o botão" +#~ msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" +#~ msgstr "" +#~ "Janela WM_TRANSIENT_FOR 0x%lx especificada para %s iriar criar loop.\n" -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "A função \"%s\" de botão não existe nesta versão (%d, necessário %d)" +#~ msgid "" +#~ "Window 0x%lx has property %s\n" +#~ "that was expected to have type %s format %d\n" +#~ "and actually has type %s format %d n_items %d.\n" +#~ "This is most likely an application bug, not a window manager bug.\n" +#~ "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +#~ msgstr "" +#~ "A janela 0x%lx tem a propriedade %s\n" +#~ "que deveria ter tipo %s formato %d\n" +#~ "e, na verdade, ela tem tipo %s, %d n_items %d.\n" +#~ "Isso é bem provavelmente um erro do aplicativo, não do gerenciador de " +#~ "janelas.\n" +#~ "A janela tem title=\"%s\" class=\"%s\" name=\"%s\"\n" -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Estado \"%s\" desconhecido para o botão" +#~ msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +#~ msgstr "A propriedade %s na janela 0x%lx continha UTF-8 inválido\n" -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "O estilo de quadro já possui um botão para o estado %s da função %s" +#~ msgid "" +#~ "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the " +#~ "list\n" +#~ msgstr "" +#~ "A propriedade %s na janela 0x%lx continha UTF-8 inválido para o item %d " +#~ "da lista\n" -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "\"%s\" não é um valor válido para o atributo de foco" +#~ msgid "Mi_nimize" +#~ msgstr "Mi_nimizar" -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "\"%s\" não é um valor válido para o atributo de estado" +#~ msgid "Ma_ximize" +#~ msgstr "Ma_ximizar" -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "Um estilo chamado \"%s\" não foi definido" +#~ msgid "Unma_ximize" +#~ msgstr "Desfazer ma_ximizar" -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "\"%s\" não é um valor válido para o atributo de redimensionamento" +#~ msgid "Roll _Up" +#~ msgstr "_Enrolar" -#: ../src/ui/theme-parser.c:3147 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" -"Não deve haver o atributo \"resize\" no elemento <%s> para os estados " -"maximizado/sombreado" +#~ msgid "_Unroll" +#~ msgstr "_Desenrolar" -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "" -"Não deve haver o atributo \"resize\" no elemento <%s> para os estados " -"maximizados" +#~ msgid "_Move" +#~ msgstr "_Mover" -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "" -"O estilo já foi especificado para o foco %s de redimensionamento %s do " -"estado %s" +#~ msgid "_Resize" +#~ msgstr "_Redimensionar" -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "O estilo já foi especificado para o foco %s do estado %s" +#~ msgid "Move Titlebar On_screen" +#~ msgstr "Mover barra de título para te_la" -#: ../src/ui/theme-parser.c:3294 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Não pode haver um segundo draw_ops para um elemento <piece> (o tema " -"especificou um atributo draw_ops e um elemento <draw_ops> ou especificou " -"dois elementos)" +#~ msgid "Always on _Top" +#~ msgstr "Sempre no _topo" -#: ../src/ui/theme-parser.c:3332 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Não pode haver um segundo draw_ops para um elemento <button> (o tema " -"especificou um atributo draw_ops e um elemento <draw_ops> ou especificou " -"dois elementos)" +#~ msgid "_Always on Visible Workspace" +#~ msgstr "_Sempre no espaço de trabalho visível" -#: ../src/ui/theme-parser.c:3370 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Não pode haver um segundo draw_ops para um elemento <menu_icon> (o tema " -"especificou um atributo draw_ops e um elemento <draw_ops> ou especificou " -"dois elementos)" +#~ msgid "_Only on This Workspace" +#~ msgstr "_Apenas neste espaço de trabalho" -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "Especificação da versão inválida \"%s\"" +#~ msgid "Move to Workspace _Left" +#~ msgstr "Mover para o espaço de trabalho à _esquerda" -#: ../src/ui/theme-parser.c:3507 -msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" -msgstr "" -"O atributo \"versão\" não pode ser usado em metacity-theme-1.xml ou metacity-" -"theme-2.xml" +#~ msgid "Move to Workspace R_ight" +#~ msgstr "Mover para o espaço de trabalho à d_ireita" -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "Tema requer versão %s, mas a última versão que o tema suporta é %d.%d" +#~ msgid "Move to Workspace _Up" +#~ msgstr "Mover para o espaço de trabalho _acima" -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "O elemento mais externo no tema deve ser <metacity_theme> e não <%s>" +#~ msgid "Move to Workspace _Down" +#~ msgstr "Mover para o espaço de trabalho a_baixo" -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "" -"O elemento <%s> não é permitido em um elemento nome/autor/data/descrição" +#~ msgid "_Close" +#~ msgstr "Fe_char" -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "O elemento <%s> não é permitido em um elemento <constant>" +#~ msgid "Workspace %d%n" +#~ msgstr "Espaço de trabalho %d%n" -#: ../src/ui/theme-parser.c:3599 -#, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "" -"O elemento <%s> não é permitido em um elemento distância/borda/" -"taxa_de_proporção" +#~ msgid "Workspace 1_0" +#~ msgstr "Espaço de trabalho 1_0" -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "O elemento <%s> não é permitido em um elemento de operação de desenho" +#~ msgid "Workspace %s%d" +#~ msgstr "Espaço de trabalho %s%d" -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "O elemento <%s> não é permitido em um elemento <%s>" +#~ msgid "Move to Another _Workspace" +#~ msgstr "Mover para _outro espaço de trabalho" -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "Nenhum draw_ops foi fornecido para a parte do quadro" +#~ msgid "Shift" +#~ msgstr "Shift" -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "Nenhum draw_ops foi fornecido para o botão" +#~ msgid "Ctrl" +#~ msgstr "Ctrl" -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "Nenhum texto é permitido no elemento <%s>" +#~ msgid "Alt" +#~ msgstr "Alt" -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "<%s> especificado duas vezes para este tema" +#~ msgid "Meta" +#~ msgstr "Meta" -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Falha ao localizar um arquivo válido para o tema %s\n" +#~ msgid "Super" +#~ msgstr "Super" -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "_Janelas" +#~ msgid "Hyper" +#~ msgstr "Hyper" -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "_Diálogo" +#~ msgid "Mod2" +#~ msgstr "Mod2" -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "Diálogo _modal" +#~ msgid "Mod3" +#~ msgstr "Mod3" -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "_Utilitário" +#~ msgid "Mod4" +#~ msgstr "Mod4" -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "Tela de _abertura" +#~ msgid "Mod5" +#~ msgstr "Mod5" -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "Encaixe de _cima" +#~ msgid "Usage: %s\n" +#~ msgstr "Uso: %s\n" -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "Encaixe de _fundo" +#~ msgid "_Windows" +#~ msgstr "_Janelas" -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "Encaixe da _esquerda" +#~ msgid "_Dialog" +#~ msgstr "_Diálogo" -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "Encaixe da _direita" +#~ msgid "_Modal dialog" +#~ msgstr "Diálogo _modal" -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "Tod_os os encaixes" +#~ msgid "_Utility" +#~ msgstr "_Utilitário" -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "Áre_a de trabalho" +#~ msgid "_Splashscreen" +#~ msgstr "Tela de _abertura" -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "Abrir outra janela desse tipo" +#~ msgid "_Top dock" +#~ msgstr "Encaixe de _cima" -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "Este é um botão de demonstração com um ícone \"abrir\"" +#~ msgid "_Bottom dock" +#~ msgstr "Encaixe de _fundo" -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "Este é um botão de demonstração com um ícone \"sair\"" +#~ msgid "_Left dock" +#~ msgstr "Encaixe da _esquerda" -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "Esta é uma mensagem de exemplo em um diálogo de exemplo" +#~ msgid "_Right dock" +#~ msgstr "Encaixe da _direita" -#: ../src/ui/theme-viewer.c:328 -#, c-format -msgid "Fake menu item %d\n" -msgstr "Item falso de menu %d\n" +#~ msgid "_All docks" +#~ msgstr "Tod_os os encaixes" -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "Janela com bordas somente" +#~ msgid "Des_ktop" +#~ msgstr "Áre_a de trabalho" -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "Barra" +#~ msgid "Open another one of these windows" +#~ msgstr "Abrir outra janela desse tipo" -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "Janela normal de aplicativos" +#~ msgid "This is a demo button with an 'open' icon" +#~ msgstr "Este é um botão de demonstração com um ícone \"abrir\"" -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "Caixa de diálogo" +#~ msgid "This is a demo button with a 'quit' icon" +#~ msgstr "Este é um botão de demonstração com um ícone \"sair\"" -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "Caixa de diálogo modal" +#~ msgid "This is a sample message in a sample dialog" +#~ msgstr "Esta é uma mensagem de exemplo em um diálogo de exemplo" -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "Paleta utilitária" +#~ msgid "Fake menu item %d\n" +#~ msgstr "Item falso de menu %d\n" -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "Menu destacável" +#~ msgid "Border-only window" +#~ msgstr "Janela com bordas somente" -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "Borda" +#~ msgid "Bar" +#~ msgstr "Barra" -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "Diálogo modal anexado" +#~ msgid "Normal Application Window" +#~ msgstr "Janela normal de aplicativos" -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "Teste de disposição dos botões %d" +#~ msgid "Dialog Box" +#~ msgstr "Caixa de diálogo" -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g milissegundos para desenhar um quadro de janela" +#~ msgid "Modal Dialog Box" +#~ msgstr "Caixa de diálogo modal" -#: ../src/ui/theme-viewer.c:813 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Uso: metacity-theme-viewer [NOMEDOTEMA]\n" +#~ msgid "Utility Palette" +#~ msgstr "Paleta utilitária" -#: ../src/ui/theme-viewer.c:820 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "Erro ao carregar tema: %s\n" +#~ msgid "Torn-off Menu" +#~ msgstr "Menu destacável" -#: ../src/ui/theme-viewer.c:826 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "Tema \"%s\" carregado em %g segundos\n" +#~ msgid "Border" +#~ msgstr "Borda" -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "Fonte de título normal" +#~ msgid "Attached Modal Dialog" +#~ msgstr "Diálogo modal anexado" -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "Fonte de título pequeno" +#~ msgid "Button layout test %d" +#~ msgstr "Teste de disposição dos botões %d" -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "Fonte de título grande" +#~ msgid "%g milliseconds to draw one window frame" +#~ msgstr "%g milissegundos para desenhar um quadro de janela" -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "Disposições de botões" +#~ msgid "Usage: metacity-theme-viewer [THEMENAME]\n" +#~ msgstr "Uso: metacity-theme-viewer [NOMEDOTEMA]\n" -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "Benchmark" +#~ msgid "Error loading theme: %s\n" +#~ msgstr "Erro ao carregar tema: %s\n" -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "O título da janela vem aqui" +#~ msgid "Loaded theme \"%s\" in %g seconds\n" +#~ msgstr "Tema \"%s\" carregado em %g segundos\n" -#: ../src/ui/theme-viewer.c:1047 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"%d quadros desenhados em %g segundos do lado cliente (%g milissegundos por " -"quadro) e %g segundos no relógio, incluindo recursos do servidor X (%g " -"milissegundos por quadro)\n" +#~ msgid "Normal Title Font" +#~ msgstr "Fonte de título normal" -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "teste de expressão de posição retornou VERDADEIRO mas definiu erro" +#~ msgid "Small Title Font" +#~ msgstr "Fonte de título pequeno" -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "teste de expressão de posição retornou FALSO mas não definiu erro" +#~ msgid "Large Title Font" +#~ msgstr "Fonte de título grande" -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "Um erro era esperado mas nenhum foi fornecido" +#~ msgid "Button Layouts" +#~ msgstr "Disposições de botões" -#: ../src/ui/theme-viewer.c:1274 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "O erro %d era esperado, mas o %d foi fornecido" +#~ msgid "Benchmark" +#~ msgstr "Benchmark" -#: ../src/ui/theme-viewer.c:1280 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "Não era esperado um erro, mas um foi retornado: %s" +#~ msgid "Window Title Goes Here" +#~ msgstr "O título da janela vem aqui" -#: ../src/ui/theme-viewer.c:1284 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "valor x era %d, mas %d era esperado" +#~ msgid "" +#~ "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and " +#~ "%g seconds wall clock time including X server resources (%g milliseconds " +#~ "per frame)\n" +#~ msgstr "" +#~ "%d quadros desenhados em %g segundos do lado cliente (%g milissegundos " +#~ "por quadro) e %g segundos no relógio, incluindo recursos do servidor X " +#~ "(%g milissegundos por quadro)\n" -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "o valor y era %d, mas %d era esperado" +#~ msgid "position expression test returned TRUE but set error" +#~ msgstr "teste de expressão de posição retornou VERDADEIRO mas definiu erro" -#: ../src/ui/theme-viewer.c:1352 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "" -"%d expressões de coordenadas analisadas em %g segundos (%g segundos em " -"média)\n" +#~ msgid "position expression test returned FALSE but didn't set error" +#~ msgstr "teste de expressão de posição retornou FALSO mas não definiu erro" + +#~ msgid "Error was expected but none given" +#~ msgstr "Um erro era esperado mas nenhum foi fornecido" + +#~ msgid "Error %d was expected but %d given" +#~ msgstr "O erro %d era esperado, mas o %d foi fornecido" -#~ msgid "Switch to workspace 1" -#~ msgstr "Trocar para o espaço de trabalho 1" +#~ msgid "Error not expected but one was returned: %s" +#~ msgstr "Não era esperado um erro, mas um foi retornado: %s" -#~ msgid "Switch to workspace 2" -#~ msgstr "Trocar para o espaço de trabalho 2" +#~ msgid "x value was %d, %d was expected" +#~ msgstr "valor x era %d, mas %d era esperado" -#~ msgid "Switch to workspace 3" -#~ msgstr "Trocar para o espaço de trabalho 3" +#~ msgid "y value was %d, %d was expected" +#~ msgstr "o valor y era %d, mas %d era esperado" -#~ msgid "Switch to workspace 4" -#~ msgstr "Trocar para o espaço de trabalho 4" +#~ msgid "" +#~ "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" +#~ msgstr "" +#~ "%d expressões de coordenadas analisadas em %g segundos (%g segundos em " +#~ "média)\n" -#~ msgid "Switch to workspace 5" -#~ msgstr "Trocar para o espaço de trabalho 5" +#~ msgid "Comma-separated list of compositor plugins" +#~ msgstr "Lista de plugins de composição separados por vírgula" -#~ msgid "Switch to workspace 6" -#~ msgstr "Trocar para o espaço de trabalho 6" +#~ msgid "" +#~ "Determines whether hidden windows (i.e., minimized windows and windows on " +#~ "other workspaces than the current one) should be kept alive." +#~ msgstr "" +#~ "Determina se as janelas ocultas (janelas minimizadas e nas outras áreas " +#~ "de trabalho que não é a atual) devem ser mantidas ativas." -#~ msgid "Switch to workspace 7" -#~ msgstr "Trocar para o espaço de trabalho 7" +#~ msgid "Live Hidden Windows" +#~ msgstr "Janelas ocultas ativas" #~ msgid "Switch to workspace 8" #~ msgstr "Trocar para o espaço de trabalho 8" @@ -1693,9 +1752,6 @@ msgstr "" #~ "Mover para trás entre os painéis e a área de trabalho, usando uma janela " #~ "instantânea" -#~ msgid "Move between windows of an application immediately" -#~ msgstr "Mover entre janelas de um aplicativo imediatamente" - #~ msgid "Move backward between windows of an application immediately" #~ msgstr "Mover para trás entre as janelas de um aplicativo imediatamente" @@ -1711,12 +1767,6 @@ msgstr "" #~ msgid "Move backward between panels and the desktop immediately" #~ msgstr "Mover para trás entre os painéis e a área de trabalho imediatamente" -#~ msgid "Hide all normal windows and set focus to the desktop" -#~ msgstr "Ocultar todas as janelas normais e focar a área de trabalho" - -#~ msgid "Show the panel's main menu" -#~ msgstr "Mostrar o menu principal do painel" - #~ msgid "Show the panel's \"Run Application\" dialog box" #~ msgstr "Mostrar a caixa de diálogo \"Executar aplicativo\" do painel" @@ -1732,55 +1782,12 @@ msgstr "" #~ msgid "Run a terminal" #~ msgstr "Executar um terminal" -#~ msgid "Activate the window menu" -#~ msgstr "Ativar o menu da janela" - -#~ msgid "Toggle fullscreen mode" -#~ msgstr "Alternar modo de tela inteira" - -#~ msgid "Toggle maximization state" -#~ msgstr "Alternar estado de maximização" - #~ msgid "Toggle whether a window will always be visible over other windows" #~ msgstr "Alternar se uma janela será sempre visível sobre as outras" -#~ msgid "Maximize window" -#~ msgstr "Maximizar a janela" - -#~ msgid "Restore window" -#~ msgstr "Restaurar janela" - -#~ msgid "Toggle shaded state" -#~ msgstr "Alternar estado sombreado" - #~ msgid "Minimize window" #~ msgstr "Minimizar a janela" -#~ msgid "Close window" -#~ msgstr "Fechar a janela" - -#~ msgid "Move window" -#~ msgstr "Mover a janela" - -#~ msgid "Resize window" -#~ msgstr "Redimensionar a janela" - -#~ msgid "Toggle whether window is on all workspaces or just one" -#~ msgstr "" -#~ "Alternar se a janela está em todos os espaços de trabalho ou em apenas um" - -#~ msgid "Move window to workspace 1" -#~ msgstr "Mover a janela para o espaço de trabalho 1" - -#~ msgid "Move window to workspace 2" -#~ msgstr "Mover a janela para o espaço de trabalho 2" - -#~ msgid "Move window to workspace 3" -#~ msgstr "Mover a janela para o espaço de trabalho 3" - -#~ msgid "Move window to workspace 4" -#~ msgstr "Mover a janela para o espaço de trabalho 4" - #~ msgid "Move window to workspace 5" #~ msgstr "Mover a janela para o espaço de trabalho 5" @@ -1805,35 +1812,6 @@ msgstr "" #~ msgid "Move window to workspace 12" #~ msgstr "Mover a janela para o espaço de trabalho 12" -#~ msgid "Move window one workspace to the left" -#~ msgstr "Mover a janela um espaço de trabalho à esquerda" - -#~ msgid "Move window one workspace to the right" -#~ msgstr "Mover a janela um espaço de trabalho à direita" - -#~ msgid "Move window one workspace up" -#~ msgstr "Mover a janela um espaço de trabalho acima" - -#~ msgid "Move window one workspace down" -#~ msgstr "Mover a janela um espaço de trabalho abaixo" - -#~ msgid "Raise window if it's covered by another window, otherwise lower it" -#~ msgstr "" -#~ "Elevar a janela se ela estiver coberta por outra; caso contrário, abaixá-" -#~ "la" - -#~ msgid "Raise window above other windows" -#~ msgstr "Elevar a janela para frente das outras" - -#~ msgid "Lower window below other windows" -#~ msgstr "Colocar a janela atrás das outras" - -#~ msgid "Maximize window vertically" -#~ msgstr "Maximizar a janela verticalmente" - -#~ msgid "Maximize window horizontally" -#~ msgstr "Maximizar a janela horizontalmente" - #~ msgid "Move window to north-west (top left) corner" #~ msgstr "Mover a janela para o canto superior esquerdo" @@ -1975,9 +1953,6 @@ msgstr "" #~ msgid "Error setting clutter plugin list: %s\n" #~ msgstr "Erro ao definir a lista de plugins do clutter: %s\n" -#~ msgid "Clutter Plugins" -#~ msgstr "Plugins do Clutter" - #~ msgid "Plugins to load for the Clutter-based compositing manager." #~ msgstr "" #~ "Plugins para carregar os gerenciadores de composição baseados em Clutter." @@ -2144,9 +2119,6 @@ msgstr "" #~ msgid "Commands to run in response to keybindings" #~ msgstr "Comandos executados em resposta a teclas de atalho" -#~ msgid "Compositing Manager" -#~ msgstr "Gerenciador de composição" - #~ msgid "Control how new windows get focus" #~ msgstr "Controla como novas janelas obtêm foco" @@ -2176,18 +2148,6 @@ msgstr "" #~ msgid "Enable Visual Bell" #~ msgstr "Habilitar campainha visual" -#~ msgid "" -#~ "If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " -#~ "the focused window will be automatically raised after a delay specified " -#~ "by the auto_raise_delay key. This is not related to clicking on a window " -#~ "to raise it, nor to entering a window during drag-and-drop." -#~ msgstr "" -#~ "Se verdadeiro, e o modo de foco for \"sloppy\" ou \"mouse\", a janela " -#~ "focada será automaticamente elevada após um atraso especificado pela " -#~ "chave auto_raise_delay. Isso não tem relação alguma com clicar em uma " -#~ "janela para elevá-la, ou alcançar uma janela durante uma ação de arrastar-" -#~ "e-soltar." - #~ msgid "" #~ "If true, ignore the titlebar_font option, and use the standard " #~ "application font for window titles." diff --git a/po/ro.po b/po/ro.po index 307c76691..7803c092a 100644 --- a/po/ro.po +++ b/po/ro.po @@ -4,1945 +4,1869 @@ # Mugurel Tudor <mugurelu@gnome.ro>, 2002-2004, 2005, 2006, 2007. # Adi Roiban https://launchpad.net/~adiroiban, 2008, 2009 # Lucian Adrian Grijincu <lucian.grijincu@gmail.com>, 2011. +# Daniel Șerbănescu <daniel [at] serbanescu [dot] dk>, 2015, 2018. msgid "" msgstr "" "Project-Id-Version: metacity.HEAD.ro\n" -"Report-Msgid-Bugs-To: " -"http://bugzilla.gnome.org/enter_bug.cgi?product=muffin&component=general\n" -"POT-Creation-Date: 2011-03-07 23:35+0000\n" -"PO-Revision-Date: 2011-03-14 13:40+0200\n" -"Last-Translator: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>\n" -"Language-Team: Romanian Gnome Team <gnomero-list@lists.sourceforge.net>\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2020-02-23 17:41+0000\n" +"PO-Revision-Date: 2020-03-19 11:58+0100\n" +"Last-Translator: Daniel Șerbănescu <daniel [at] serbanescu [dot] dk>\n" +"Language-Team: Gnome Romanian Translation Team <gnomero-list@lists." +"sourceforge.net>\n" "Language: ro\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < " -"20)) ? 1 : 2);;\n" -"X-Generator: Virtaal 0.6.1\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n==0 || (n!=1 && n%100>=1 && n" +"%100<=19) ? 1 : 2);\n" +"X-Generator: Poedit 2.3\n" +"X-Project-Style: gnome\n" +"X-Poedit-SourceCharset: UTF-8\n" -#: ../src/core/all-keybindings.h:88 -msgid "Switch to workspace 1" -msgstr "Comută la spațiul de lucru 1" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Navigare" -#: ../src/core/all-keybindings.h:90 -msgid "Switch to workspace 2" -msgstr "Comută la spațiul de lucru 2" +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Mută fereastra pe spațiul de lucru 1" -#: ../src/core/all-keybindings.h:92 -msgid "Switch to workspace 3" -msgstr "Comută la spațiul de lucru 3" +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Mută fereastra pe spațiul de lucru 2" -#: ../src/core/all-keybindings.h:94 -msgid "Switch to workspace 4" -msgstr "Comută la spațiul de lucru 4" +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Mută fereastra pe spațiul de lucru 3" -#: ../src/core/all-keybindings.h:96 -msgid "Switch to workspace 5" -msgstr "Comută la spațiul de lucru 5" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Mută fereastra pe spațiul de lucru 4" -#: ../src/core/all-keybindings.h:98 -msgid "Switch to workspace 6" -msgstr "Comută la spațiul de lucru 6" +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Mută fereastra pe spațiul de lucru anterior" -#: ../src/core/all-keybindings.h:100 -msgid "Switch to workspace 7" -msgstr "Comută la spațiul de lucru 7" +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "Mută fereastra pe spațiul de lucru de mai sus" -#: ../src/core/all-keybindings.h:102 -msgid "Switch to workspace 8" -msgstr "Comută la spațiul de lucru 8" +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "Mută fereastra pe spațiul de lucru de mai jos" -#: ../src/core/all-keybindings.h:104 -msgid "Switch to workspace 9" -msgstr "Comută la spațiul de lucru 9" +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "Mută fereastra cu un monitor la stânga" -#: ../src/core/all-keybindings.h:106 -msgid "Switch to workspace 10" -msgstr "Comută la spațiul de lucru 10" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "Mută fereastra un monitor la dreapta" -#: ../src/core/all-keybindings.h:108 -msgid "Switch to workspace 11" -msgstr "Comută la spațiul de lucru 11" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "Mută fereastra cu un monitor mai sus" -#: ../src/core/all-keybindings.h:110 -msgid "Switch to workspace 12" -msgstr "Comută la spațiul de lucru 12" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "Mută fereastra cu un monitor mai jos" -#: ../src/core/all-keybindings.h:122 -msgid "Switch to workspace on the left of the current workspace" -msgstr "Schimbă cu spațiul de lucru din stânga celui actual" +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "Comută aplicațiile" -#: ../src/core/all-keybindings.h:126 -msgid "Switch to workspace on the right of the current workspace" -msgstr "Schimbă cu spațiul de lucru din dreapta celui actual" +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "Schimbă la aplicația anterioară" -#: ../src/core/all-keybindings.h:130 -msgid "Switch to workspace above the current workspace" -msgstr "Schimbă cu spațiul de lucru de deasupra celui actual" +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "Schimbă ferestre" -#: ../src/core/all-keybindings.h:134 -msgid "Switch to workspace below the current workspace" -msgstr "Schimbă cu spațiul de lucru de dedesubtul celui actual" +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "Schimbă la fereastra anterioară" -#: ../src/core/all-keybindings.h:150 -msgid "Move between windows of an application, using a popup window" -msgstr "Comută între ferestrele unui program, folosind o fereastră informativă" +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "Schimbă ferestrele unei aplicații" -#: ../src/core/all-keybindings.h:153 -msgid "Move backward between windows of an application, using a popup window" -msgstr "" -"Comută înapoi între ferestrele unui program, folosind o fereastră informativă" +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "Schimbă la fereastra anterioară a unei aplicații" -#: ../src/core/all-keybindings.h:157 -msgid "Move between windows, using a popup window" -msgstr "Comută între ferestre, folosind o fereastră informativă" +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "Schimbă comenzile de sistem" -#: ../src/core/all-keybindings.h:160 -msgid "Move backward between windows, using a popup window" -msgstr "Comută înapoi între ferestre, folosind o fereastră informativă" +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "Schimbă la comanda de control anterioară" -#: ../src/core/all-keybindings.h:163 -msgid "Move between panels and the desktop, using a popup window" -msgstr "" -"Comută între panouri și spațiul de lucru, folosind o fereastră informativă" +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "Schimbă ferestrele în mod direct" -#: ../src/core/all-keybindings.h:166 -msgid "Move backward between panels and the desktop, using a popup window" -msgstr "" -"Comută înapoi între panouri și spațiul de lucru, folosind o fereastră " -"informativă" +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "Schimbă la fereastra anterioară în mod direct" + +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "Comută direct ferestrele unei aplicații" + +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "Schimbă în mod direct la fereastra anterioară a unei aplicații" + +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "Schimbă comenzile de sistem în mod direct" -#: ../src/core/all-keybindings.h:171 -msgid "Move between windows of an application immediately" -msgstr "Mută imediat între ferestrele unei aplicații" +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "Schimbă în mod direct la o comandă de sistem anterioară" -#: ../src/core/all-keybindings.h:174 -msgid "Move backward between windows of an application immediately" -msgstr "Comută imediat înapoi între ferestrele unui program" +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "Ascunde toate ferestrele normale" -#: ../src/core/all-keybindings.h:177 -msgid "Move between windows immediately" -msgstr "Mută imediat între ferestre" +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "Comută la spațiul de lucru 1" -#: ../src/core/all-keybindings.h:180 -msgid "Move backward between windows immediately" -msgstr "Comută imediat înapoi între ferestre" +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "Comută la spațiul de lucru 2" -#: ../src/core/all-keybindings.h:183 -msgid "Move between panels and the desktop immediately" -msgstr "Mută imediat între panouri și desktop" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "Comută la spațiul de lucru 3" -#: ../src/core/all-keybindings.h:186 -msgid "Move backward between panels and the desktop immediately" -msgstr "Mută imediat înapoi între panouri și desktop" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "Comută la spațiul de lucru 4" + +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "Comută la ultimul spațiu de lucru" -#: ../src/core/all-keybindings.h:203 -msgid "Hide all normal windows and set focus to the desktop" -msgstr "Ascunde toate ferestrele normale și definește focalizarea pe desktop" +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "Mută pe spațiul de lucru deasupra" -#: ../src/core/all-keybindings.h:206 -msgid "Show the panel's main menu" -msgstr "Arată meniul principal al panoului" +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "Mută pe spațiul de lucru de jos" -#: ../src/core/all-keybindings.h:209 -msgid "Show the panel's \"Run Application\" dialog box" -msgstr "Arată fereastra de dialog „Rulează aplicația” a panoului" +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "Sistem" -#: ../src/core/all-keybindings.h:211 -msgid "Start or stop recording the session" -msgstr "Pornește sau oprește înregistrarea sesiunii" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Arată prompterul de comandă al comenzii run (rulează)" -#: ../src/core/all-keybindings.h:252 -msgid "Take a screenshot" -msgstr "Captură ecran" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Arată prezentarea generală a activităților" -#: ../src/core/all-keybindings.h:254 -msgid "Take a screenshot of a window" -msgstr "Salvează o captură a ecranului" +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Restaurează scurtăturile de tastatură" -#: ../src/core/all-keybindings.h:256 -msgid "Run a terminal" -msgstr "Pornește un terminal" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Ferestre" -#: ../src/core/all-keybindings.h:271 +#: data/50-mutter-windows.xml:8 msgid "Activate the window menu" msgstr "Activează meniul ferestrei" -#: ../src/core/all-keybindings.h:274 +#: data/50-mutter-windows.xml:10 msgid "Toggle fullscreen mode" msgstr "Comută modul pe tot ecranul" -#: ../src/core/all-keybindings.h:276 +#: data/50-mutter-windows.xml:12 msgid "Toggle maximization state" msgstr "Comută starea de maximizare" -#: ../src/core/all-keybindings.h:278 -msgid "Toggle whether a window will always be visible over other windows" -msgstr "" -"Comută dacă o fereastră este întotdeauna vizibilă deasupra altor ferestre" - -#: ../src/core/all-keybindings.h:280 +#: data/50-mutter-windows.xml:14 msgid "Maximize window" msgstr "Maximizează fereastra" -#: ../src/core/all-keybindings.h:282 +#: data/50-mutter-windows.xml:16 msgid "Restore window" msgstr "Restabilește fereastra" -#: ../src/core/all-keybindings.h:284 -msgid "Toggle shaded state" -msgstr "Comută starea de umbrire" - -#: ../src/core/all-keybindings.h:286 -msgid "Minimize window" -msgstr "Minimizează fereastra" - -#: ../src/core/all-keybindings.h:288 +#: data/50-mutter-windows.xml:18 msgid "Close window" msgstr "Închide fereastra" -#: ../src/core/all-keybindings.h:290 +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "Ascunde fereastra" + +#: data/50-mutter-windows.xml:22 msgid "Move window" msgstr "Mută fereastra" -#: ../src/core/all-keybindings.h:292 +#: data/50-mutter-windows.xml:24 msgid "Resize window" msgstr "Redimensionează fereastra" -#: ../src/core/all-keybindings.h:295 -msgid "Toggle whether window is on all workspaces or just one" +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "Comută fereastra pe toate spațiile de lucru sau doar pe unul" + +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "Ridică fereastra dacă este acoperită, altfel, coboar-o" + +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "Ridică fereastra deasupra celorlalte ferestre" + +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "Coboară fereastra sub alte ferestre" + +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "Maximizează fereastra pe verticală" + +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "Maximizează fereastra pe orizontală" + +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "Împarte în stânga" + +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "Împarte în dreapta" + +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" + +#: data/org.gnome.mutter.gschema.xml.in:7 +msgid "Modifier to use for extended window management operations" msgstr "" -"Comută dacă fereastra este în toate spațiile de lucru sau doar într-unul" +"Modificatorul folosit pentru operațiile extinse de management al ferestrelor" -#: ../src/core/all-keybindings.h:299 -msgid "Move window to workspace 1" -msgstr "Mută fereastra pe spațiul de lucru 1" +#: data/org.gnome.mutter.gschema.xml.in:8 +msgid "" +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." +msgstr "" +"Această cheie va iniția „suprapunerea”, care este o combinație între o " +"privire de ansamblu a ferestrelor și un sistem de lansare de aplicații. " +"Implicit este tasta „Windows” pe hardware PC. Este de așteptat ca această " +"legătură să fie ori stabilită la implicit sau la șirul vid." -#: ../src/core/all-keybindings.h:302 -msgid "Move window to workspace 2" -msgstr "Mută fereastra pe spațiul de lucru 2" +#: data/org.gnome.mutter.gschema.xml.in:20 +msgid "Attach modal dialogs" +msgstr "Atașează dialogurile modale" -#: ../src/core/all-keybindings.h:305 -msgid "Move window to workspace 3" -msgstr "Mută fereastra pe spațiul de lucru 3" +#: data/org.gnome.mutter.gschema.xml.in:21 +msgid "" +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." +msgstr "" +"Când e adevărat, în loc de a avea bare de titlu independente, dialogurile " +"modale apar atașate la bara de titlu a ferestrei părinte și sunt mutate " +"împreună cu fereastra părinte." -#: ../src/core/all-keybindings.h:308 -msgid "Move window to workspace 4" -msgstr "Mută fereastra pe spațiul de lucru 4" +#: data/org.gnome.mutter.gschema.xml.in:30 +msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "" +"Activează mozaicul de margine la plasarea ferestrelor pe marginile ecranului" -#: ../src/core/all-keybindings.h:311 -msgid "Move window to workspace 5" -msgstr "Mută fereastra pe spațiul de lucru 5" +#: data/org.gnome.mutter.gschema.xml.in:31 +msgid "" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." +msgstr "" +"Dacă este activată, plasarea ferestrelor pe marginile verticale ale " +"ecranului le maximizează pe vertical și le redimensionează pe orizontal " +"pentru a acoperi jumătate din suprafața disponibilă. Plasarea ferestrelor pe " +"marginea de sus a ecranului le maximizează complet." -#: ../src/core/all-keybindings.h:314 -msgid "Move window to workspace 6" -msgstr "Mută fereastra pe spațiul de lucru 6" +#: data/org.gnome.mutter.gschema.xml.in:40 +msgid "Workspaces are managed dynamically" +msgstr "Spațiile de lucru sunt gestionate în mod dinamic" -#: ../src/core/all-keybindings.h:317 -msgid "Move window to workspace 7" -msgstr "Mută fereastra pe spațiul de lucru 7" +#: data/org.gnome.mutter.gschema.xml.in:41 +msgid "" +"Determines whether workspaces are managed dynamically or whether there’s a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." +msgstr "" +"Determină dacă spațiile de lucru sunt administrate dinamic sau dacă există " +"un număr static de spații de lucru (determinat de cheia num-workspaces din " +"org.gnome.desktop.wm.preferences)" -#: ../src/core/all-keybindings.h:320 -msgid "Move window to workspace 8" -msgstr "Mută fereastra pe spațiul de lucru 8" +#: data/org.gnome.mutter.gschema.xml.in:50 +msgid "Workspaces only on primary" +msgstr "Spații de lucru doar pe ecranul principal" -#: ../src/core/all-keybindings.h:323 -msgid "Move window to workspace 9" -msgstr "Mută fereastra pe spațiul de lucru 9" +#: data/org.gnome.mutter.gschema.xml.in:51 +msgid "" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." +msgstr "" +"Determină dacă schimbarea spațiilor de lucru trebuie să se petreacă pentru " +"ferestrele de pe toate monitoarele sau doar pentru ferestrele de pe " +"monitorul principal." -#: ../src/core/all-keybindings.h:326 -msgid "Move window to workspace 10" -msgstr "Mută fereastra pe spațiul de lucru 10" +#: data/org.gnome.mutter.gschema.xml.in:59 +msgid "No tab popup" +msgstr "Fără popup pentru tab" -#: ../src/core/all-keybindings.h:329 -msgid "Move window to workspace 11" -msgstr "Mută fereastra pe spațiul de lucru 11" +#: data/org.gnome.mutter.gschema.xml.in:60 +msgid "" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." +msgstr "" +"Determină dacă utilizarea unui popup sau a unui cadrul evidențiat ar trebui " +"să fie dezactivată pentru rotirea ferestrelor." -#: ../src/core/all-keybindings.h:332 -msgid "Move window to workspace 12" -msgstr "Mută fereastra pe spațiul de lucru 12" +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "" +"Întârzie schimbările de focalizare până când cursorul încetează să se miște" -#: ../src/core/all-keybindings.h:344 -msgid "Move window one workspace to the left" -msgstr "Mută fereastra pe spațiul de lucru de la stânga" +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" +"Dacă este stabilit ca adevărat, iar modul de focalizare este ori „neglijent” " +"ori „maus”, atunci focalizarea nu va fi schimbată imediat la intrarea într-o " +"fereastră, ci doar după ce indicatorul nu se mai mișcă." -#: ../src/core/all-keybindings.h:347 -msgid "Move window one workspace to the right" -msgstr "Mută fereastra pe spațiul de lucru de la dreapta" +#: data/org.gnome.mutter.gschema.xml.in:79 +msgid "Draggable border width" +msgstr "Lățimea marginii ce poate fi plasată" -#: ../src/core/all-keybindings.h:350 -msgid "Move window one workspace up" -msgstr "Mută fereastra pe spațiul de lucru de mai sus" +#: data/org.gnome.mutter.gschema.xml.in:80 +msgid "" +"The amount of total draggable borders. If the theme’s visible borders are " +"not enough, invisible borders will be added to meet this value." +msgstr "" +"Numărul total de margini ce pot fi plasate. Dacă marginile vizibile ale " +"temei nu sunt suficiente, vor fi adăugate margini invizibile pentru a " +"respecta această valoare." -#: ../src/core/all-keybindings.h:353 -msgid "Move window one workspace down" -msgstr "Mută fereastra pe spațiul de lucru de mai jos" +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "" +"Maximizează automat ferestrele de dimensiune apropiată de cea a monitorului" -#: ../src/core/all-keybindings.h:356 -msgid "Raise window if it's covered by another window, otherwise lower it" +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." msgstr "" -"Ridică fereastra dacă este acoperită de altă fereastră, altfel coboar-o" +"Dacă este activată, ferestrele noi care sunt inițial de mărimea monitorului " +"sunt maximizate în mod automat." -#: ../src/core/all-keybindings.h:358 -msgid "Raise window above other windows" -msgstr "Ridică fereastra deasupra celorlalte ferestre" +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Plasează ferestre noi în centru" -#: ../src/core/all-keybindings.h:360 -msgid "Lower window below other windows" -msgstr "Coboară fereastra sub alte ferestre" +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" +"Când este adevărat, ferestrele noi vor fi plasate în centrul ecranului activ " +"al monitorului." -#: ../src/core/all-keybindings.h:364 -msgid "Maximize window vertically" -msgstr "Maximizează fereastra pe verticală" +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Activează funcționalitățile experimentale" -#: ../src/core/all-keybindings.h:368 -msgid "Maximize window horizontally" -msgstr "Maximizează fereastra pe orizontală" +#: data/org.gnome.mutter.gschema.xml.in:108 +msgid "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes " +"mutter request a low priority real-time scheduling. The executable or user " +"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — " +"initializes Xwayland lazily if there are X11 clients. Requires restart." +msgstr "" +"Pentru a activa funcționalitățile experimentale, adăugați cuvântul cheie al " +"funcționalității la listă. Dacă funcționalitatea necesită sau nu repornirea " +"compunătorului depinde de funcționalitatea dată. Nu este necesar ca " +"funcționalitatea experimentală să fie încă disponibilă, sau configurabilă. " +"Nu vă așteptați să adăugați ceva la această configurare care va rezista " +"timpului. Cuvintele cheie posibile în mod curent: • „scale-monitor-" +"framebuffer” — face ca mutter să treacă implicit la aranjarea monitoarelor " +"logice într-un spațiu logic de coordonate pixel, în timpul scalării de " +"framebuffer-uri de monitor în locul conținutului ferestrei, pentru a " +"gestiona monitoare HiDPI. Nu necesită o repornire. • „rt-scheduler” — face " +"ca mutter să ceară o programare în timp real de prioritate scăzută. " +"Executabilul sau utilizatorul trebuie să aibă CAP_SYS_NICE. Necesită o " +"repornire. • „autostart-xwayland” — inițializează Xwayland cu încetinitorul " +"dacă există clienți X11. Necesită o repornire." + +#: data/org.gnome.mutter.gschema.xml.in:134 +msgid "Modifier to use to locate the pointer" +msgstr "Modificator de utilizat pentru a localiza pointerul" + +#: data/org.gnome.mutter.gschema.xml.in:135 +msgid "This key will initiate the “locate pointer” action." +msgstr "Această cheie va iniția acțiunea „localizează pointer”." + +#: data/org.gnome.mutter.gschema.xml.in:142 +msgid "Timeout for check-alive ping" +msgstr "A expirat limita de timp pentru check-alive ping" + +#: data/org.gnome.mutter.gschema.xml.in:143 +msgid "" +"Number of milliseconds a client has to respond to a ping request in order to " +"not be detected as frozen. Using 0 will disable the alive check completely." +msgstr "" +"Număr de millisecunde în care un client trebuie să răspundă la o cerere de " +"ping pentru a nu fi detectat ca înghețat. Utilizând 0 va dezactiva check-" +"alive complet." -#: ../src/core/all-keybindings.h:372 -msgid "Move window to north-west (top left) corner" -msgstr "Mută fereastra spre colțul de nord-vest (stânga sus)" +#: data/org.gnome.mutter.gschema.xml.in:165 +msgid "Select window from tab popup" +msgstr "Selectează fereastra din popup-ul tabului" -#: ../src/core/all-keybindings.h:375 -msgid "Move window to north-east (top right) corner" -msgstr "Mută fereastra spre colțul de nord-est (dreapta sus)" +#: data/org.gnome.mutter.gschema.xml.in:170 +msgid "Cancel tab popup" +msgstr "Elimină popup-ul pentru tab" -#: ../src/core/all-keybindings.h:378 -msgid "Move window to south-west (bottom left) corner" -msgstr "Mută fereastra spre colțul de sud-vest (stânga jos)" +#: data/org.gnome.mutter.gschema.xml.in:175 +msgid "Switch monitor configurations" +msgstr "Comută configurațiile de monitor" -#: ../src/core/all-keybindings.h:381 -msgid "Move window to south-east (bottom right) corner" -msgstr "Mută fereastra spre colțul de sud-est (dreapta jos)" +#: data/org.gnome.mutter.gschema.xml.in:180 +msgid "Rotates the built-in monitor configuration" +msgstr "Rotește configurarea de monitor integrat" -#: ../src/core/all-keybindings.h:385 -msgid "Move window to north (top) side of screen" -msgstr "Mută fereastra spre nord (partea de sus a ecranului)" +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Comută la terminalul virtual 1" -#: ../src/core/all-keybindings.h:388 -msgid "Move window to south (bottom) side of screen" -msgstr "Mută fereastra spre sud (partea de jos a ecranului)" +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Comută la terminalul virtual 2" -#: ../src/core/all-keybindings.h:391 -msgid "Move window to east (right) side of screen" -msgstr "Mută fereastra spre est (partea dreaptă a ecranului)" +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Comută la terminalul virtual 3" -#: ../src/core/all-keybindings.h:394 -msgid "Move window to west (left) side of screen" -msgstr "Mută fereastra spre vest (partea stângă a ecranului)" +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Comută la terminalul virtual 4" -#: ../src/core/all-keybindings.h:397 -msgid "Move window to center of screen" -msgstr "Mută fereastra în centrul ecranului" +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Comută la terminalul virtual 5" -#: ../src/core/bell.c:302 -msgid "Bell event" -msgstr "Eveniment sonor" +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Comută la terminalul virtual 6" -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Cerere necunoscută de informație despre fereastră: %d" +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Comută la terminalul virtual 7" -#. Translators: %s is a window title -#: ../src/core/delete.c:94 -#, c-format -#| msgid "\"%s\" is not responding." -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> nu răspunde." +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Comută la terminalul virtual 8" -#: ../src/core/delete.c:99 -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "" -"Puteți alege între a aștepta pentru câteva secunde ca aplicația să continue " -"sau a forța terminarea aplicației." +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Comută la terminalul virtual 9" -#: ../src/core/delete.c:108 -msgid "_Wait" -msgstr "_Așteaptă" +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Comută la terminalul virtual 10" -#: ../src/core/delete.c:108 -msgid "_Force Quit" -msgstr "_Forțează închiderea" +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Comută la terminalul virtual 11" -#: ../src/core/display.c:365 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "Extensie %s negăsită, necesară pentru compunere" +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Comută la terminalul virtual 12" -#: ../src/core/display.c:431 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Nu s-a putut deschide afișajul X Window System „%s”\n" +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "Reactivează scurtăturile" -#: ../src/core/keybindings.c:759 -#, c-format +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow X11 grabs to lock keyboard focus with Xwayland" +msgstr "Permite capturilor X11 să blocheze focusul tastaturii cu Xwayland" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" +"Allow all keyboard events to be routed to X11 “override redirect” windows " +"with a grab when running in Xwayland. This option is to support X11 clients " +"which map an “override redirect” window (which do not receive keyboard " +"focus) and issue a keyboard grab to force all keyboard events to that " +"window. This option is seldom used and has no effect on regular X11 windows " +"which can receive keyboard focus under normal circumstances. For a X11 grab " +"to be taken into account under Wayland, the client must also either send a " +"specific X11 ClientMessage to the root window or be among the applications " +"white-listed in key “xwayland-grab-access-rules”." msgstr "" -"Alt program folosește deja tasta %s cu modificatorul %x drept combinație\n" +"Permite ca toate evenimentele de tastatură să fie rutate la ferestrele de " +"„redirecționare suprascriere” X11 cu o blocare când se rulează Xwayland. " +"Această opțiune este pentru a suporta clienții X11 care mapează o fereastră " +"de „redirecționare suprascriere” (care nu primesc focusul tastaturii) și " +"furnizează o blocare de tastatură pentru a forța toate evenimentele de " +"tastatură la acea fereastră. Această opțiune este utilizată rar și nu are " +"niciun efect asupra ferestrelor X11 obișnuite care pot primi focusul " +"tastaturii sub circumstanțe normale. Pentru ca o blocare X11 să fie luată în " +"considerare sub Wayland, clientul trebuie de asemenea să trimită ori un " +"ClientMessage X11 specific la fereastra root sau să fie printre aplicațiile " +"din lista albă în cheia „xwayland-grab-access-rules”." + +#: data/org.gnome.mutter.wayland.gschema.xml.in:84 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "Aplicațiile Xwayland sunt permise de a emite capturi de tastatură" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:85 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "" +"Listează numele resurselor sau clasa resurselor ale ferestrelor X11 permise " +"sau nepermise să emită capturi de tastatură X11 în Xwayland. Numele resursei " +"sau clasa resursei a unei ferestre X11 date pot fi obținute utilizând " +"comanda „xprop WM_CLASS*. Metacaracterele „*” și jokerii „?” în valori sunt " +"suportați. Valorile care încep cu „!” sunt adăugate în lista de interziceri, " +"care are prioritate peste lista de permisiuni, pentru a revoca aplicații din " +"lista de sistem implicită. Lista de sistem implicită include următoarele " +"aplicații: „@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Utilizatorii pot să " +"întrerupă o captură existentă prin utilizarea scurtăturii de tastatură " +"specifice definite de tasta de stabilire a combinațiilor de taste „restore-" +"shortcuts”." + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. +#. +#: src/backends/meta-input-settings.c:2567 +#, c-format +msgid "Mode Switch (Group %d)" +msgstr "Comutator de mod (grupul %d)" -#. Displayed when a keybinding which is -#. * supposed to launch a program fails. +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. #. -#: ../src/core/keybindings.c:2468 +#: src/backends/meta-input-settings.c:2590 +msgid "Switch monitor" +msgstr "Comută monitorul" + +#: src/backends/meta-input-settings.c:2592 +msgid "Show on-screen help" +msgstr "Arată ajutorul virtual" + +#: src/backends/meta-monitor.c:223 +msgid "Built-in display" +msgstr "Afișaj integrat" + +#: src/backends/meta-monitor.c:252 +msgid "Unknown" +msgstr "Necunoscut" + +#: src/backends/meta-monitor.c:254 +msgid "Unknown Display" +msgstr "Afișaj necunoscut" + +#: src/backends/meta-monitor.c:262 #, c-format -msgid "" -"There was an error running <tt>%s</tt>:\n" -"\n" -"%s" -msgstr "" -"A apărut o eroare la rularea <tt>%s</tt>:\n" -"\n" -"%s" +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" -#: ../src/core/keybindings.c:2558 +#: src/backends/meta-monitor.c:270 #, c-format -msgid "No command %d has been defined.\n" -msgstr "Nici o comandă %d nu a fost definită.\n" +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" + +#. Translators: this string will appear in Sysprof +#: src/backends/meta-profiler.c:79 +msgid "Compositor" +msgstr "Compunător" -#: ../src/core/keybindings.c:3570 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:533 #, c-format -msgid "No terminal command has been defined.\n" -msgstr "Nici o comandă pentru terminal nu a fost definită.\n" +msgid "" +"Another compositing manager is already running on screen %i on display “%s”." +msgstr "" +"Un alt administrator de ferestre de compunere rulează deja pe ecranul %i pe " +"afișajul „%s”." + +#: src/core/bell.c:192 +msgid "Bell event" +msgstr "Eveniment sonor" -#: ../src/core/main.c:206 +#: src/core/main.c:190 msgid "Disable connection to session manager" msgstr "Dezactivează conexiunea la administratorul de sesiune" -#: ../src/core/main.c:212 -#| msgid "Replace the running window manager with Metacity" +#: src/core/main.c:196 msgid "Replace the running window manager" msgstr "Înlocuiește administratorul de ferestre curent" -#: ../src/core/main.c:218 +#: src/core/main.c:202 msgid "Specify session management ID" msgstr "Specifică ID-ul administrării de sesiune" -#: ../src/core/main.c:223 +#: src/core/main.c:207 msgid "X Display to use" msgstr "Ecranul X ce va fi folosit" -#: ../src/core/main.c:229 +#: src/core/main.c:213 msgid "Initialize session from savefile" msgstr "Inițializează sesiunea din fișierul salvat" -#: ../src/core/main.c:235 +#: src/core/main.c:219 msgid "Make X calls synchronous" msgstr "Realizează apelurile X sincron" -#: ../src/core/main.c:508 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Nu s-a putut citi dosarul de teme: %s\n" +#: src/core/main.c:226 +msgid "Run as a wayland compositor" +msgstr "Rulează ca un compunător wayland" + +#: src/core/main.c:232 +msgid "Run as a nested compositor" +msgstr "Rulează ca un compunător imbricat" + +#: src/core/main.c:238 +msgid "Run wayland compositor without starting Xwayland" +msgstr "Rulează compunătorul wayland fără a porni Xwayland" -#: ../src/core/main.c:524 +#: src/core/main.c:246 +msgid "Run as a full display server, rather than nested" +msgstr "Rulează ca server de afișare și nu ca server imbricat" + +#: src/core/main.c:252 +msgid "Run with X11 backend" +msgstr "Rulează cu backend X11" + +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:151 #, c-format +msgid "“%s” is not responding." +msgstr "„%s” nu răspunde." + +#: src/core/meta-close-dialog-default.c:153 +msgid "Application is not responding." +msgstr "Aplicația nu răspunde." + +#: src/core/meta-close-dialog-default.c:158 msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." msgstr "" -"Nu s-a putut găsi o temă! Asigurați-vă că %s există și că aceasta conține " -"temele uzuale.\n" +"Puteți alege între a aștepta pentru câteva secunde ca aplicația să continue " +"sau a forța terminarea aplicației." -#: ../src/core/muffin.c:42 +#: src/core/meta-close-dialog-default.c:165 +msgid "_Force Quit" +msgstr "_Forțează închiderea" + +#: src/core/meta-close-dialog-default.c:165 +msgid "_Wait" +msgstr "_Așteaptă" + +#: src/core/mutter.c:38 #, c-format -#| msgid "" -#| "metacity %s\n" -#| "Copyright (C) 2001-2008 Havoc Pennington, Red Hat, Inc., and others\n" -#| "This is free software; see the source for copying conditions.\n" -#| "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -#| "PARTICULAR PURPOSE.\n" msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" "This is free software; see the source for copying conditions.\n" "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " "PARTICULAR PURPOSE.\n" msgstr "" -"muffin %s\n" -"Drepturi de autor (C) 2001--%d Havoc Pennington, Red Hat, Inc., și alții\n" +"mutter %s\n" +"Drepturi de autor (C) 2001-%d Havoc Pennington, Red Hat, Inc., și alții\n" "Acesta este software liber; consultați codul sursă pentru condițiile de " "copiere.\n" -"Nu există NICI O garanție; nici pentru COMERCIALIZARE sau UTILIZAREA ÎNTR-UN " +"Nu există NICIO garanție; nici pentru COMERCIALIZARE sau UTILIZAREA ÎNTR-UN " "SCOP ANUME.\n" -#: ../src/core/muffin.c:56 +#: src/core/mutter.c:52 msgid "Print version" msgstr "Afișează versiunea" -#: ../src/core/muffin.c:62 -msgid "Comma-separated list of compositor plugins" -msgstr "Listă separată prin virgule de module pentru compozitor" - -#. -#. * We found it, but it was invalid. Complain. -#. * -#. * FIXME: This replicates the original behaviour, but in the future -#. * we might consider reverting invalid keys to their original values. -#. * (We know the old value, so we can look up a suitable string in -#. * the symtab.) -#. * -#. * (Empty comment follows so the translators don't see this.) -#. -#. -#: ../src/core/prefs.c:536 ../src/core/prefs.c:697 -#, c-format -msgid "GConf key '%s' is set to an invalid value\n" -msgstr "Cheia GConf „%s” este definită la o valoare invalidă\n" +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "Modul Mutter de utilizat" -#: ../src/core/prefs.c:623 ../src/core/prefs.c:866 +#: src/core/prefs.c:1911 #, c-format -msgid "%d stored in GConf key %s is out of range %d to %d\n" -msgstr "%d stocat în cheia GConf %s este în afara intervalului %d la %d\n" +msgid "Workspace %d" +msgstr "Spațiu de lucru %d" -#: ../src/core/prefs.c:667 ../src/core/prefs.c:744 ../src/core/prefs.c:792 -#: ../src/core/prefs.c:856 ../src/core/prefs.c:1317 ../src/core/prefs.c:1333 -#: ../src/core/prefs.c:1350 ../src/core/prefs.c:1366 -#, c-format -msgid "GConf key \"%s\" is set to an invalid type\n" -msgstr "Cheia GConf „%s” este setată la o valoare nevalidă\n" +#: src/core/util.c:122 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter a fost compilat fără suport pentru modul detaliat\n" -#: ../src/core/prefs.c:1196 +#: src/wayland/meta-wayland-tablet-pad.c:568 #, c-format -msgid "GConf key %s is already in use and can't be used to override %s\n" -msgstr "" -"Cheia GConf %s este deja în uz și nu poate fi folosită pentru a suprima %s\n" +msgid "Mode Switch: Mode %d" +msgstr "Comutator de mod: modul %d" -#: ../src/core/prefs.c:1255 +#: src/x11/meta-x11-display.c:676 #, c-format -msgid "Can't override GConf key, %s not found\n" -msgstr "Nu se poate trece peste cheia GConf, %s nu a fost găsit\n" - -#: ../src/core/prefs.c:1440 msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." msgstr "" -"Soluțiile de compromis pentru aplicațiile problematice sunt dezactivate. " -"Există posibilitatea ca unele aplicații să nu se comporte corect.\n" +"Afișajul „%s” are deja un administrator de ferestre; încercați să utilizați " +"opțiunea --replace (înlocuiește) pentru a înlocui administratorul de " +"ferestre curent." -#: ../src/core/prefs.c:1517 -#, c-format -msgid "Could not parse font description \"%s\" from GConf key %s\n" -msgstr "Nu am putut parsa descrierea fontului „%s” din cheia GConf %s\n" +#: src/x11/meta-x11-display.c:1089 +msgid "Failed to initialize GDK\n" +msgstr "Nu s-a putut inițializa GDK\n" -#: ../src/core/prefs.c:1579 +#: src/x11/meta-x11-display.c:1113 #, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"„%s” găsită în configurație nu este o cheie validă pentru modificatorul " -"butonului de maus\n" +msgid "Failed to open X Window System display “%s”\n" +msgstr "Nu s-a putut deschide afișajul sistemului de ferestre X „%s”\n" -#: ../src/core/prefs.c:2006 +#: src/x11/meta-x11-display.c:1196 #, c-format -msgid "Error setting number of workspaces to %d: %s\n" -msgstr "Eroare la definirea numărului de ecrane la %d: %s\n" +msgid "Screen %d on display “%s” is invalid\n" +msgstr "Ecranul %d de pe afișajul „%s” nu este valid\n" -#: ../src/core/prefs.c:2190 ../src/core/prefs.c:2692 +#: src/x11/meta-x11-selection-input-stream.c:460 #, c-format -msgid "Workspace %d" -msgstr "Spațiu de lucru %d" +msgid "Format %s not supported" +msgstr "Formatul %s nu este suportat" -#: ../src/core/prefs.c:2222 ../src/core/prefs.c:2400 -#, c-format +#: src/x11/session.c:1821 msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." msgstr "" -"„%s” găsită în configurație nu este o cheie validă pentru combinația de " -"taste „%s”\n" +"Aceste ferestre nu suportă „salvează configurarea curentă” și vor trebui " +"repornite manual următoarea dată când vă veți autentifica." -#: ../src/core/prefs.c:2773 +#: src/x11/window-props.c:569 #, c-format -msgid "Error setting name for workspace %d to \"%s\": %s\n" -msgstr "Eroare la definirea numelui pentru spațiul de lucru %d la „%s”: %s\n" +msgid "%s (on %s)" +msgstr "%s (pe %s)" -#: ../src/core/prefs.c:2987 -#, c-format -#| msgid "Error setting compositor status: %s\n" -msgid "Error setting live hidden windows status status: %s\n" -msgstr "Eroare la stabilirea stării ferestrelor active ascunse: %s\n" +#~ msgid "Move window one workspace to the left" +#~ msgstr "Mută fereastra pe spațiul de lucru de la stânga" -#: ../src/core/prefs.c:3015 -#, c-format -#| msgid "Error setting compositor status: %s\n" -msgid "Error setting no tab popup status: %s\n" -msgstr "" +#~ msgid "Move window one workspace to the right" +#~ msgstr "Mută fereastra pe spațiul de lucru de la dreapta" -#: ../src/core/screen.c:577 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "Ecranul %d pe afișajul „%s” este invalid\n" +#~ msgid "Move to workspace left" +#~ msgstr "Mută pe spațiul de lucru din stânga" -#: ../src/core/screen.c:593 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"Ecranul %d pe afișajul „%s” are deja un administrator de ferestre; încercați " -"să folosiți opțiunea --replace pentru a înlocui administratorul de ferestre " -"actual.\n" +#~ msgid "Move to workspace right" +#~ msgstr "Mută pe spațiul de lucru din dreapta" -#: ../src/core/screen.c:620 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "" -"Nu s-a putut achiziționa selecția administratorului de ferestre pe ecranul %" -"d afișajul „%s”\n" +#~ msgid "Toggle shaded state" +#~ msgstr "Comută starea de umbrire" -#: ../src/core/screen.c:675 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "Ecranul %d pe afișajul „%s” are deja un administrator de ferestre\n" +#~ msgid "Switch to workspace on the left of the current workspace" +#~ msgstr "Schimbă cu spațiul de lucru din stânga celui actual" -#: ../src/core/screen.c:860 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "Nu s-a putut elibera ecranul %d pe afișajul „%s”\n" +#~ msgid "Switch to workspace on the right of the current workspace" +#~ msgstr "Schimbă cu spațiul de lucru din dreapta celui actual" -#: ../src/core/session.c:863 ../src/core/session.c:870 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Nu s-a putut crea dosarul „%s”: %s\n" +#~ msgid "Switch to workspace above the current workspace" +#~ msgstr "Schimbă cu spațiul de lucru de deasupra celui actual" -#: ../src/core/session.c:880 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "Nu s-a putut deschide fișierul de sesiune „%s” pentru scriere: %s\n" +#~ msgid "Switch to workspace below the current workspace" +#~ msgstr "Schimbă cu spațiul de lucru de dedesubtul celui actual" -#: ../src/core/session.c:1021 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Eroare la scrierea fișierului de sesiune „%s”: %s\n" +#~ msgid "Move between windows of an application, using a popup window" +#~ msgstr "" +#~ "Comută între ferestrele unui program, folosind o fereastră informativă" -#: ../src/core/session.c:1026 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Eroare la închiderea fișierului de sesiune „%s”: %s\n" +#~ msgid "" +#~ "Move backward between windows of an application, using a popup window" +#~ msgstr "" +#~ "Comută înapoi între ferestrele unui program, folosind o fereastră " +#~ "informativă" -#: ../src/core/session.c:1156 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Nu s-a putut parcurge fișierul sesiunii salvate: %s\n" +#~ msgid "Move between windows, using a popup window" +#~ msgstr "Comută între ferestre, folosind o fereastră informativă" -#: ../src/core/session.c:1205 -#, c-format -#| msgid "<metacity_session> attribute seen but we already have the session ID" -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "atributul <muffin_session> a fost văzut dar avem deja ID-ul sesiunii" +#~ msgid "Move backward between windows, using a popup window" +#~ msgstr "Comută înapoi între ferestre, folosind o fereastră informativă" -#: ../src/core/session.c:1218 ../src/core/session.c:1293 -#: ../src/core/session.c:1325 ../src/core/session.c:1397 -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Atribut necunoscut %s al elementului <%s>" +#~ msgid "Move between panels and the desktop, using a popup window" +#~ msgstr "" +#~ "Comută între panouri și spațiul de lucru, folosind o fereastră informativă" -#: ../src/core/session.c:1235 -#, c-format -msgid "nested <window> tag" -msgstr "etichetă imbricată <window>" +#~ msgid "Move backward between panels and the desktop, using a popup window" +#~ msgstr "" +#~ "Comută înapoi între panouri și spațiul de lucru, folosind o fereastră " +#~ "informativă" -#: ../src/core/session.c:1477 -#, c-format -msgid "Unknown element %s" -msgstr "Element necunoscut %s" +#~ msgid "Move backward between windows of an application immediately" +#~ msgstr "Comută imediat înapoi între ferestrele unui program" -#: ../src/core/session.c:1829 -#| msgid "" -#| "These windows do not support \"save current setup\" and will have to be " -#| "restarted manually next time you log in." -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" -"Aceste ferestre nu suportă „salvează configurarea curentă” și vor trebui " -"repornite manual următoarea dată când vă veți autentifica." +#~ msgid "Move between windows immediately" +#~ msgstr "Mută imediat între ferestre" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Nu s-a putut deschide înregistrarea de depanare: %s\n" +#~ msgid "Move backward between windows immediately" +#~ msgstr "Comută imediat înapoi între ferestre" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Nu s-a putut deschide ( fdopen() ) fișierul de înregistrare %s: %s\n" +#~ msgid "Move between panels and the desktop immediately" +#~ msgstr "Mută imediat între panouri și desktop" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "S-a deschis fișierul de înregistrare %s\n" +#~ msgid "Move backward between panels and the desktop immediately" +#~ msgstr "Mută imediat înapoi între panouri și desktop" -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -#| msgid "Metacity was compiled without support for verbose mode\n" -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "Muffin a fost compilat fără suport pentru modul detaliat\n" - -#: ../src/core/util.c:286 -msgid "Window manager: " -msgstr "Administrator de ferestre: " - -#: ../src/core/util.c:434 -msgid "Bug in window manager: " -msgstr "Problemă în administratorul de ferestre: " - -#: ../src/core/util.c:467 -msgid "Window manager warning: " -msgstr "Avertisment al administratorului de ferestre: " - -#: ../src/core/util.c:495 -msgid "Window manager error: " -msgstr "Eroare administrator ferestre: " - -#. Translators: This is the title used on dialog boxes -#: ../src/core/util.c:616 ../src/muffin.desktop.in.h:1 -#: ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" - -#. first time through -#: ../src/core/window.c:6492 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"Fereastra %s definește SM_CLIENT_ID asupra sa, în loc să o facă asupra " -"ferestrei WM_CLIENT_LEADER așa cum este specificat în ICCCM.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7155 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %" -"d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"Fereastra %s definește un indicator MWM indicând că nu e redimensionabilă, " -"dar definește dimensiunea minimă %d x %d și dimensiunea maximă %d x %d; asta " -"nu prea are sens.\n" +#~ msgid "Show the panel's \"Run Application\" dialog box" +#~ msgstr "Arată fereastra de dialog „Rulează aplicația” a panoului" -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "Aplicația a definit un _NET_WM_PID fals %lu\n" +#~ msgid "Start or stop recording the session" +#~ msgstr "Pornește sau oprește înregistrarea sesiunii" -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (pe %s)" +#~ msgid "Take a screenshot" +#~ msgstr "Captură ecran" -#: ../src/core/window-props.c:1478 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "Fereastră 0x%lx WM_TRANSIENT_FOR nevalidă specificată pentru %s.\n" +#~ msgid "Take a screenshot of a window" +#~ msgstr "Salvează o captură a ecranului" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"Fereastra 0x%lx are proprietatea %s\n" -"care era așteptată să aibă tipul %s formatul %d\n" -"și de fapt are tipul %s formatul %d n_items %d.\n" -"Acest lucru e cel mai probabil o problemă a aplicației, nu a managerului de " -"ferestre.\n" -"Fereastra are titlul=„%s” clasa=„%s” nume=„%s”\n" - -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "Proprietatea %s din fereastra 0x%lx conține date invalide UTF-8\n" +#~ msgid "Run a terminal" +#~ msgstr "Pornește un terminal" -#: ../src/core/xprops.c:494 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"Proprietatea %s din fereastra 0x%lx conține date invalide UTF-8 pentru " -"elementul %d din listă\n" +#~ msgid "Toggle whether a window will always be visible over other windows" +#~ msgstr "" +#~ "Comută dacă o fereastră este întotdeauna vizibilă deasupra altor ferestre" -#: ../src/muffin.schemas.in.h:1 -msgid "Attach modal dialogs" -msgstr "Atașează dialogurile modale" +#~ msgid "Minimize window" +#~ msgstr "Minimizează fereastra" -#: ../src/muffin.schemas.in.h:2 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"Determină dacă ferestrele ascunse (de ex., ferestrele minimizate și " -"ferestrele de pe alte spații de lucru) ar trebui păstrate ca active." +#~ msgid "Toggle whether window is on all workspaces or just one" +#~ msgstr "" +#~ "Comută dacă fereastra este în toate spațiile de lucru sau doar într-unul" -#: ../src/muffin.schemas.in.h:3 -msgid "Live Hidden Windows" -msgstr "Ferestre ascunse active" +#~ msgid "Move window to workspace 5" +#~ msgstr "Mută fereastra pe spațiul de lucru 5" -#: ../src/muffin.schemas.in.h:4 -#| msgid "Modifier to use for modified window click actions" -msgid "Modifier to use for extended window management operations" -msgstr "" -"Modificatorul folosit pentru operațiile extinse de management al ferestrelor" +#~ msgid "Move window to workspace 6" +#~ msgstr "Mută fereastra pe spațiul de lucru 6" -#: ../src/muffin.schemas.in.h:5 -msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." -msgstr "" -"Această cheie va iniția „overlay”-ul, care este o combinație între o privire " -"de ansamblu a ferestrelor și un sistemul de lansare de aplicații. Implicit " -"este testa „Windows” pe hardware PC. Este de așteptat ca această cheie să " -"fie sau implicit sau setat la șirul vid." +#~ msgid "Move window to workspace 7" +#~ msgstr "Mută fereastra pe spațiul de lucru 7" -#: ../src/muffin.schemas.in.h:6 -msgid "" -"When true, instead of having independent titlebars, modal dialogs appear " -"attached to the titlebar of the parent window and are moved together with " -"the parent window." -msgstr "" -"Când e adevărat, în loc de a avea bare de titlu independente, dialogurile " -"modale apar atașate la bara de titlu a ferestrei părinte și sunt mutate " -"împreună cu fereastra părinte." +#~ msgid "Move window to workspace 8" +#~ msgstr "Mută fereastra pe spațiul de lucru 8" -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "Utilizare: %s\n" +#~ msgid "Move window to workspace 9" +#~ msgstr "Mută fereastra pe spațiul de lucru 9" -#: ../src/ui/frames.c:1099 -msgid "Close Window" -msgstr "Închide fereastra" +#~ msgid "Move window to workspace 10" +#~ msgstr "Mută fereastra pe spațiul de lucru 10" -#: ../src/ui/frames.c:1102 -msgid "Window Menu" -msgstr "Meniu fereastră" +#~ msgid "Move window to workspace 11" +#~ msgstr "Mută fereastra pe spațiul de lucru 11" -#: ../src/ui/frames.c:1105 -msgid "Minimize Window" -msgstr "Minimizează fereastra" +#~ msgid "Move window to workspace 12" +#~ msgstr "Mută fereastra pe spațiul de lucru 12" -#: ../src/ui/frames.c:1108 -msgid "Maximize Window" -msgstr "Maximizează fereastra" +#~ msgid "Move window to north-west (top left) corner" +#~ msgstr "Mută fereastra spre colțul de nord-vest (stânga sus)" -#: ../src/ui/frames.c:1111 -msgid "Restore Window" -msgstr "Restabilește fereastra" +#~ msgid "Move window to north-east (top right) corner" +#~ msgstr "Mută fereastra spre colțul de nord-est (dreapta sus)" -#: ../src/ui/frames.c:1114 -msgid "Roll Up Window" -msgstr "Rulează fereastra" - -#: ../src/ui/frames.c:1117 -msgid "Unroll Window" -msgstr "Derulează fereastra" - -#: ../src/ui/frames.c:1120 -msgid "Keep Window On Top" -msgstr "Menține fereastra deasupra" - -#: ../src/ui/frames.c:1123 -msgid "Remove Window From Top" -msgstr "Anulează menținerea fereastrei deasupra" - -#: ../src/ui/frames.c:1126 -msgid "Always On Visible Workspace" -msgstr "Visibil permanent pe spațiu de lucru" - -#: ../src/ui/frames.c:1129 -msgid "Put Window On Only One Workspace" -msgstr "Pune fereastra pe un singur spațiu de lucru" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "Mi_nimizează" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "Ma_ximizează" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "_Restaurează" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "În_fășoară" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "_Desfășoară" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "_Mută" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "_Redimensionează" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "Mută bara de _titlu pe ecran" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "În_totdeauna deasupra" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "Întotde_auna pe spațiul de lucru vizibil" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "Doar pe _acest spațiu de lucru" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "Mută pe spațiul de lucru din _stânga" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "Mută pe spațiul de lucru din _dreapta" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "Mută pe spațiul de lucru de s_us" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "Mută pe spațiul de lucru de _jos" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "_Închide" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "Spațiu de lucru %d%n" +#~ msgid "Move window to south-west (bottom left) corner" +#~ msgstr "Mută fereastra spre colțul de sud-vest (stânga jos)" -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "Spațiul de lucru 1_0" +#~ msgid "Move window to south-east (bottom right) corner" +#~ msgstr "Mută fereastra spre colțul de sud-est (dreapta jos)" -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "Spațiul de lucru %s%d" +#~ msgid "Move window to north (top) side of screen" +#~ msgstr "Mută fereastra spre nord (partea de sus a ecranului)" + +#~ msgid "Move window to south (bottom) side of screen" +#~ msgstr "Mută fereastra spre sud (partea de jos a ecranului)" + +#~ msgid "Move window to east (right) side of screen" +#~ msgstr "Mută fereastra spre est (partea dreaptă a ecranului)" + +#~ msgid "Move window to west (left) side of screen" +#~ msgstr "Mută fereastra spre vest (partea stângă a ecranului)" + +#~ msgid "Move window to center of screen" +#~ msgstr "Mută fereastra în centrul ecranului" + +#~ msgid "Unknown window information request: %d" +#~ msgstr "Cerere necunoscută de informație despre fereastră: %d" + +#~ msgid "Missing %s extension required for compositing" +#~ msgstr "Extensie %s negăsită, necesară pentru compunere" + +#~ msgid "" +#~ "Some other program is already using the key %s with modifiers %x as a " +#~ "binding\n" +#~ msgstr "" +#~ "Alt program folosește deja tasta %s cu modificatorul %x drept combinație\n" + +#~ msgid "" +#~ "There was an error running <tt>%s</tt>:\n" +#~ "\n" +#~ "%s" +#~ msgstr "" +#~ "A apărut o eroare la rularea <tt>%s</tt>:\n" +#~ "\n" +#~ "%s" + +#~ msgid "No command %d has been defined.\n" +#~ msgstr "Nici o comandă %d nu a fost definită.\n" + +#~ msgid "No terminal command has been defined.\n" +#~ msgstr "Nici o comandă pentru terminal nu a fost definită.\n" + +#~ msgid "Failed to scan themes directory: %s\n" +#~ msgstr "Nu s-a putut citi dosarul de teme: %s\n" + +#~ msgid "" +#~ "Could not find a theme! Be sure %s exists and contains the usual themes.\n" +#~ msgstr "" +#~ "Nu s-a putut găsi o temă! Asigurați-vă că %s există și că aceasta conține " +#~ "temele uzuale.\n" + +#~ msgid "Comma-separated list of compositor plugins" +#~ msgstr "Listă separată prin virgule de module pentru compozitor" + +#~ msgid "GConf key '%s' is set to an invalid value\n" +#~ msgstr "Cheia GConf „%s” este definită la o valoare invalidă\n" + +#~ msgid "%d stored in GConf key %s is out of range %d to %d\n" +#~ msgstr "%d stocat în cheia GConf %s este în afara intervalului %d la %d\n" + +#~ msgid "GConf key \"%s\" is set to an invalid type\n" +#~ msgstr "Cheia GConf „%s” este setată la o valoare nevalidă\n" + +#~ msgid "GConf key %s is already in use and can't be used to override %s\n" +#~ msgstr "" +#~ "Cheia GConf %s este deja în uz și nu poate fi folosită pentru a suprima " +#~ "%s\n" + +#~ msgid "Can't override GConf key, %s not found\n" +#~ msgstr "Nu se poate trece peste cheia GConf, %s nu a fost găsit\n" + +#~ msgid "" +#~ "Workarounds for broken applications disabled. Some applications may not " +#~ "behave properly.\n" +#~ msgstr "" +#~ "Soluțiile de compromis pentru aplicațiile problematice sunt dezactivate. " +#~ "Există posibilitatea ca unele aplicații să nu se comporte corect.\n" + +#~ msgid "Could not parse font description \"%s\" from GConf key %s\n" +#~ msgstr "Nu am putut parsa descrierea fontului „%s” din cheia GConf %s\n" + +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" +#~ msgstr "" +#~ "„%s” găsită în configurație nu este o cheie validă pentru modificatorul " +#~ "butonului de maus\n" + +#~ msgid "Error setting number of workspaces to %d: %s\n" +#~ msgstr "Eroare la definirea numărului de ecrane la %d: %s\n" + +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for " +#~ "keybinding \"%s\"\n" +#~ msgstr "" +#~ "„%s” găsită în configurație nu este o cheie validă pentru combinația de " +#~ "taste „%s”\n" + +#~ msgid "Error setting name for workspace %d to \"%s\": %s\n" +#~ msgstr "" +#~ "Eroare la definirea numelui pentru spațiul de lucru %d la „%s”: %s\n" + +#~| msgid "Error setting compositor status: %s\n" +#~ msgid "Error setting live hidden windows status status: %s\n" +#~ msgstr "Eroare la stabilirea stării ferestrelor active ascunse: %s\n" + +#~ msgid "Screen %d on display \"%s\" already has a window manager\n" +#~ msgstr "Ecranul %d pe afișajul „%s” are deja un administrator de ferestre\n" + +#~ msgid "Could not release screen %d on display \"%s\"\n" +#~ msgstr "Nu s-a putut elibera ecranul %d pe afișajul „%s”\n" + +#~ msgid "Could not create directory '%s': %s\n" +#~ msgstr "Nu s-a putut crea dosarul „%s”: %s\n" + +#~ msgid "Could not open session file '%s' for writing: %s\n" +#~ msgstr "Nu s-a putut deschide fișierul de sesiune „%s” pentru scriere: %s\n" + +#~ msgid "Error writing session file '%s': %s\n" +#~ msgstr "Eroare la scrierea fișierului de sesiune „%s”: %s\n" + +#~ msgid "Error closing session file '%s': %s\n" +#~ msgstr "Eroare la închiderea fișierului de sesiune „%s”: %s\n" + +#~ msgid "Failed to parse saved session file: %s\n" +#~ msgstr "Nu s-a putut parcurge fișierul sesiunii salvate: %s\n" + +#~| msgid "" +#~| "<metacity_session> attribute seen but we already have the session ID" +#~ msgid "<mutter_session> attribute seen but we already have the session ID" +#~ msgstr "" +#~ "atributul <mutter_session> a fost văzut dar avem deja ID-ul sesiunii" + +#~ msgid "Unknown attribute %s on <%s> element" +#~ msgstr "Atribut necunoscut %s al elementului <%s>" + +#~ msgid "nested <window> tag" +#~ msgstr "etichetă imbricată <window>" + +#~ msgid "Unknown element %s" +#~ msgstr "Element necunoscut %s" + +#~ msgid "Failed to open debug log: %s\n" +#~ msgstr "Nu s-a putut deschide înregistrarea de depanare: %s\n" + +#~ msgid "Failed to fdopen() log file %s: %s\n" +#~ msgstr "" +#~ "Nu s-a putut deschide ( fdopen() ) fișierul de înregistrare %s: %s\n" + +#~ msgid "Opened log file %s\n" +#~ msgstr "S-a deschis fișierul de înregistrare %s\n" + +#~ msgid "Window manager: " +#~ msgstr "Administrator de ferestre: " + +#~ msgid "Bug in window manager: " +#~ msgstr "Problemă în administratorul de ferestre: " + +#~ msgid "Window manager warning: " +#~ msgstr "Avertisment al administratorului de ferestre: " + +#~ msgid "Window manager error: " +#~ msgstr "Eroare administrator ferestre: " + +#~ msgid "" +#~ "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " +#~ "window as specified in the ICCCM.\n" +#~ msgstr "" +#~ "Fereastra %s definește SM_CLIENT_ID asupra sa, în loc să o facă asupra " +#~ "ferestrei WM_CLIENT_LEADER așa cum este specificat în ICCCM.\n" + +#~ msgid "" +#~ "Window %s sets an MWM hint indicating it isn't resizable, but sets min " +#~ "size %d x %d and max size %d x %d; this doesn't make much sense.\n" +#~ msgstr "" +#~ "Fereastra %s definește un indicator MWM indicând că nu e " +#~ "redimensionabilă, dar definește dimensiunea minimă %d x %d și dimensiunea " +#~ "maximă %d x %d; asta nu prea are sens.\n" + +#~ msgid "Application set a bogus _NET_WM_PID %lu\n" +#~ msgstr "Aplicația a definit un _NET_WM_PID fals %lu\n" + +#~ msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +#~ msgstr "Fereastră 0x%lx WM_TRANSIENT_FOR nevalidă specificată pentru %s.\n" + +#~ msgid "" +#~ "Window 0x%lx has property %s\n" +#~ "that was expected to have type %s format %d\n" +#~ "and actually has type %s format %d n_items %d.\n" +#~ "This is most likely an application bug, not a window manager bug.\n" +#~ "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +#~ msgstr "" +#~ "Fereastra 0x%lx are proprietatea %s\n" +#~ "care era așteptată să aibă tipul %s formatul %d\n" +#~ "și de fapt are tipul %s formatul %d n_items %d.\n" +#~ "Acest lucru e cel mai probabil o problemă a aplicației, nu a managerului " +#~ "de ferestre.\n" +#~ "Fereastra are titlul=„%s” clasa=„%s” nume=„%s”\n" + +#~ msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +#~ msgstr "Proprietatea %s din fereastra 0x%lx conține date invalide UTF-8\n" + +#~ msgid "" +#~ "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the " +#~ "list\n" +#~ msgstr "" +#~ "Proprietatea %s din fereastra 0x%lx conține date invalide UTF-8 pentru " +#~ "elementul %d din listă\n" + +#~ msgid "" +#~ "Determines whether hidden windows (i.e., minimized windows and windows on " +#~ "other workspaces than the current one) should be kept alive." +#~ msgstr "" +#~ "Determină dacă ferestrele ascunse (de ex., ferestrele minimizate și " +#~ "ferestrele de pe alte spații de lucru) ar trebui păstrate ca active." + +#~ msgid "Live Hidden Windows" +#~ msgstr "Ferestre ascunse active" + +#~ msgid "Usage: %s\n" +#~ msgstr "Utilizare: %s\n" + +#~ msgid "Close Window" +#~ msgstr "Închide fereastra" + +#~ msgid "Window Menu" +#~ msgstr "Meniu fereastră" + +#~ msgid "Minimize Window" +#~ msgstr "Minimizează fereastra" + +#~ msgid "Maximize Window" +#~ msgstr "Maximizează fereastra" + +#~ msgid "Restore Window" +#~ msgstr "Restabilește fereastra" + +#~ msgid "Roll Up Window" +#~ msgstr "Rulează fereastra" + +#~ msgid "Unroll Window" +#~ msgstr "Derulează fereastra" + +#~ msgid "Keep Window On Top" +#~ msgstr "Menține fereastra deasupra" + +#~ msgid "Remove Window From Top" +#~ msgstr "Anulează menținerea fereastrei deasupra" + +#~ msgid "Always On Visible Workspace" +#~ msgstr "Visibil permanent pe spațiu de lucru" + +#~ msgid "Put Window On Only One Workspace" +#~ msgstr "Pune fereastra pe un singur spațiu de lucru" + +#~ msgid "Mi_nimize" +#~ msgstr "Mi_nimizează" + +#~ msgid "Ma_ximize" +#~ msgstr "Ma_ximizează" + +#~ msgid "Unma_ximize" +#~ msgstr "_Restaurează" + +#~ msgid "Roll _Up" +#~ msgstr "În_fășoară" + +#~ msgid "_Unroll" +#~ msgstr "_Desfășoară" + +#~ msgid "_Move" +#~ msgstr "_Mută" + +#~ msgid "_Resize" +#~ msgstr "_Redimensionează" + +#~ msgid "Move Titlebar On_screen" +#~ msgstr "Mută bara de _titlu pe ecran" + +#~ msgid "Always on _Top" +#~ msgstr "În_totdeauna deasupra" + +#~ msgid "_Always on Visible Workspace" +#~ msgstr "Întotde_auna pe spațiul de lucru vizibil" + +#~ msgid "_Only on This Workspace" +#~ msgstr "Doar pe _acest spațiu de lucru" + +#~ msgid "Move to Workspace _Up" +#~ msgstr "Mută pe spațiul de lucru de s_us" + +#~ msgid "_Close" +#~ msgstr "_Închide" + +#~ msgid "Workspace %d%n" +#~ msgstr "Spațiu de lucru %d%n" + +#~ msgid "Workspace 1_0" +#~ msgstr "Spațiul de lucru 1_0" + +#~ msgid "Workspace %s%d" +#~ msgstr "Spațiul de lucru %s%d" + +#~ msgid "Move to Another _Workspace" +#~ msgstr "Mută pe un alt _spațiul de lucru" + +#~ msgid "Shift" +#~ msgstr "Shift" + +#~ msgid "Ctrl" +#~ msgstr "Ctrl" + +#~ msgid "Alt" +#~ msgstr "Alt" + +#~ msgid "Meta" +#~ msgstr "Meta" + +#~ msgid "Super" +#~ msgstr "Super" + +#~ msgid "Hyper" +#~ msgstr "Hyper" + +#~ msgid "Mod2" +#~ msgstr "Mod2" + +#~ msgid "Mod3" +#~ msgstr "Mod3" + +#~ msgid "Mod4" +#~ msgstr "Mod4" + +#~ msgid "Mod5" +#~ msgstr "Mod5" + +#~ msgid "%d x %d" +#~ msgstr "%d x %d" + +#~ msgid "top" +#~ msgstr "sus" + +#~ msgid "bottom" +#~ msgstr "jos" + +#~ msgid "left" +#~ msgstr "stânga" + +#~ msgid "right" +#~ msgstr "dreapta" + +#~ msgid "frame geometry does not specify \"%s\" dimension" +#~ msgstr "geometria cadrului nu specifică dimensiunea „%s”" + +#~ msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" +#~ msgstr "" +#~ "geometria cadrului nu specifică dimensiunea „%s” pentru marginea „%s”" + +#~ msgid "Button aspect ratio %g is not reasonable" +#~ msgstr "Proporția butonul %g nu este rezonabilă" + +#~ msgid "Frame geometry does not specify size of buttons" +#~ msgstr "Geometria cadrului nu specifică mărimea butoanelor" + +#~ msgid "Gradients should have at least two colors" +#~ msgstr "Degradeul ar trebui să aibă cel puțin două culori" + +#~ msgid "" +#~ "GTK color specification must have the state in brackets, e.g. gtk:" +#~ "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "Specificația culorilor GTK trebuie să aibă starea între paranteze drepte, " +#~ "de exemplu gtk:fg[NORMAL], unde starea este NORMAL; nu s-a putut analiza " +#~ "„%s”" + +#~ msgid "" +#~ "GTK color specification must have a close bracket after the state, e.g. " +#~ "gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "Specificația culorilor GTK trebuie să fie aibă o paranteză dreaptă după " +#~ "stare, de exemplu gtk:fg[NORMAL], unde starea este NORMAL; nu s-a putut " +#~ "analiza „%s”" + +#~ msgid "Did not understand state \"%s\" in color specification" +#~ msgstr "Nu s-a putut înțelege starea „%s” în specificarea culorilor" + +#~ msgid "Did not understand color component \"%s\" in color specification" +#~ msgstr "" +#~ "Nu s-a putut înțelege componenta de culoare „%s” în specificarea culorilor" + +#~ msgid "" +#~ "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit " +#~ "the format" +#~ msgstr "" +#~ "Formatul blend este „blend/bg_color/fg_color/alpha”, unde„%s” nu se " +#~ "potrivește formatului" + +#~ msgid "Could not parse alpha value \"%s\" in blended color" +#~ msgstr "Nu s-a putut analiza valoarea alfa „%s” în culoarea blend-ată" + +#~ msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" +#~ msgstr "Valoarea alfa „%s” în culoarea blend-ată nu este între 0.0 și 1.0" -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "Mută pe un alt _spațiul de lucru" +#~ msgid "" +#~ "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the " +#~ "format" +#~ msgstr "" +#~ "Formatul de umbră este „shade/base_color/factor”, „%s” nu se potrivește " +#~ "formatului" -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" +#~ msgid "Could not parse shade factor \"%s\" in shaded color" +#~ msgstr "Nu s-a putut analiza factorul de umbrire „%s” în culoarea umbrită" -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" +#~ msgid "Shade factor \"%s\" in shaded color is negative" +#~ msgstr "Factorul de umbrire „%s” în culoarea umbrită este negativ" -#: ../src/ui/theme.c:255 -msgid "top" -msgstr "sus" +#~ msgid "Could not parse color \"%s\"" +#~ msgstr "Nu s-a putut analiza culoarea „%s”" -#: ../src/ui/theme.c:257 -msgid "bottom" -msgstr "jos" +#~ msgid "Coordinate expression contains character '%s' which is not allowed" +#~ msgstr "Expresia coordonatelor conține caracterul nepermis „%s”" -#: ../src/ui/theme.c:259 -msgid "left" -msgstr "stânga" +#~ msgid "" +#~ "Coordinate expression contains floating point number '%s' which could not " +#~ "be parsed" +#~ msgstr "" +#~ "Expresia coordonatelor conține numărul în virgulă mobilă „%s” care nu a " +#~ "putut fi analizat." -#: ../src/ui/theme.c:261 -msgid "right" -msgstr "dreapta" +#~ msgid "" +#~ "Coordinate expression contains integer '%s' which could not be parsed" +#~ msgstr "" +#~ "Expresia coordonatelor conține întregul „%s” care nu a putut fi analizat" -#: ../src/ui/theme.c:288 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "geometria cadrului nu specifică dimensiunea „%s”" +#~ msgid "" +#~ "Coordinate expression contained unknown operator at the start of this " +#~ "text: \"%s\"" +#~ msgstr "" +#~ "Expresia coordonatelor conține operatorul necunoscut la începutul acestui " +#~ "text: „%s”" -#: ../src/ui/theme.c:307 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "geometria cadrului nu specifică dimensiunea „%s” pentru marginea „%s”" +#~ msgid "Coordinate expression was empty or not understood" +#~ msgstr "Expresia coordonatelor a fost goală sau neînțeleasă" -#: ../src/ui/theme.c:344 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "Proporția butonul %g nu este rezonabilă" +#~ msgid "Coordinate expression results in division by zero" +#~ msgstr "" +#~ "Expresia coordonatelor este rezultată în urma unei împărțiri la zero" -#: ../src/ui/theme.c:356 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "Geometria cadrului nu specifică mărimea butoanelor" +#~ msgid "" +#~ "Coordinate expression tries to use mod operator on a floating-point number" +#~ msgstr "" +#~ "Expresia coordonatelor încearcă să folosească operatorul mod asupra unui " +#~ "număr în virgulă mobilă" -#: ../src/ui/theme.c:1064 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "Degradeul ar trebui să aibă cel puțin două culori" +#~ msgid "" +#~ "Coordinate expression has an operator \"%s\" where an operand was expected" +#~ msgstr "" +#~ "Expresia coordonatelor are un operator „%s” care așteaptă un operand" -#: ../src/ui/theme.c:1202 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"Specificația culorilor GTK trebuie să aibă starea între paranteze drepte, de " -"exemplu gtk:fg[NORMAL], unde starea este NORMAL; nu s-a putut analiza „%s”" +#~ msgid "Coordinate expression had an operand where an operator was expected" +#~ msgstr "Expresia coordonatelor are un operand unde un operator era așteptat" -#: ../src/ui/theme.c:1216 -#, c-format -msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"Specificația culorilor GTK trebuie să fie aibă o paranteză dreaptă după " -"stare, de exemplu gtk:fg[NORMAL], unde starea este NORMAL; nu s-a putut " -"analiza „%s”" +#~ msgid "Coordinate expression ended with an operator instead of an operand" +#~ msgstr "" +#~ "Expresia coordonatelor a fost terminată cu un operator în locul " +#~ "operandului" -#: ../src/ui/theme.c:1227 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "Nu s-a putut înțelege starea „%s” în specificarea culorilor" +#~ msgid "" +#~ "Coordinate expression has operator \"%c\" following operator \"%c\" with " +#~ "no operand in between" +#~ msgstr "" +#~ "Expresia coordonatelor are un operator „%c” urmând operatorului „%c” fără " +#~ "un operand între ele" -#: ../src/ui/theme.c:1240 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "" -"Nu s-a putut înțelege componenta de culoare „%s” în specificarea culorilor" +#~ msgid "Coordinate expression had unknown variable or constant \"%s\"" +#~ msgstr "Expresia coordonatelor are variabila necunscută sau constanta „%s”" -#: ../src/ui/theme.c:1270 -#, c-format -msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" -msgstr "" -"Formatul blend este „blend/bg_color/fg_color/alpha”, unde„%s” nu se " -"potrivește formatului" +#~ msgid "Coordinate expression parser overflowed its buffer." +#~ msgstr "" +#~ "Analizatorul expresiei de coordonate a depăsit dimeniunea zonei de " +#~ "memorie tampon." -#: ../src/ui/theme.c:1281 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "Nu s-a putut analiza valoarea alfa „%s” în culoarea blend-ată" +#~ msgid "" +#~ "Coordinate expression had a close parenthesis with no open parenthesis" +#~ msgstr "" +#~ "Expresia coordonatelor are o paranteză închisă fără nici o paranteză " +#~ "deschisă" -#: ../src/ui/theme.c:1291 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "Valoarea alfa „%s” în culoarea blend-ată nu este între 0.0 și 1.0" +#~ msgid "" +#~ "Coordinate expression had an open parenthesis with no close parenthesis" +#~ msgstr "Expresia coordonatelor are o paranteză deschisă și nici una închisă" -#: ../src/ui/theme.c:1338 -#, c-format -msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "" -"Formatul de umbră este „shade/base_color/factor”, „%s” nu se potrivește " -"formatului" +#~ msgid "Coordinate expression doesn't seem to have any operators or operands" +#~ msgstr "Expresia coordonatelor nu are nici un operator și operand" -#: ../src/ui/theme.c:1349 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "Nu s-a putut analiza factorul de umbrire „%s” în culoarea umbrită" +#~ msgid "Theme contained an expression that resulted in an error: %s\n" +#~ msgstr "Tema conținea o expresie ce a rezultat într-o eroare: %s\n" -#: ../src/ui/theme.c:1359 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "Factorul de umbrire „%s” în culoarea umbrită este negativ" +#~ msgid "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " +#~ "specified for this frame style" +#~ msgstr "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> trebuie " +#~ "specificate pentru stilul acestui cadru" -#: ../src/ui/theme.c:1388 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Nu s-a putut analiza culoarea „%s”" +#~ msgid "" +#~ "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/" +#~ ">" +#~ msgstr "" +#~ "Lipsește <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever" +#~ "\"/>" -#: ../src/ui/theme.c:1646 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "Expresia coordonatelor conține caracterul nepermis „%s”" +#~ msgid "Failed to load theme \"%s\": %s\n" +#~ msgstr "Nu s-a putut încărca tema „%s”: %s\n" -#: ../src/ui/theme.c:1673 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "" -"Expresia coordonatelor conține numărul în virgulă mobilă „%s” care nu a " -"putut fi analizat." +#~ msgid "No <%s> set for theme \"%s\"" +#~ msgstr "Nu a fost definit nici un <%s> pentru tema „%s”" -#: ../src/ui/theme.c:1687 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "" -"Expresia coordonatelor conține întregul „%s” care nu a putut fi analizat" +#~ msgid "" +#~ "No frame style set for window type \"%s\" in theme \"%s\", add a <window " +#~ "type=\"%s\" style_set=\"whatever\"/> element" +#~ msgstr "" +#~ "Nici un stil de cadru definit pentru tipul de fereastră „%s” în tema " +#~ "„%s”; adăugați un element <window type=\"%s\" style_set=\"whatever\"/>" -#: ../src/ui/theme.c:1809 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "" -"Expresia coordonatelor conține operatorul necunoscut la începutul acestui " -"text: „%s”" +#~ msgid "" +#~ "User-defined constants must begin with a capital letter; \"%s\" does not" +#~ msgstr "" +#~ "Constantele definite de utilizatori trebuie să înceapă cu o majusculă; " +#~ "„%s” nu respectă acest lucru" -#: ../src/ui/theme.c:1866 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "Expresia coordonatelor a fost goală sau neînțeleasă" +#~ msgid "Constant \"%s\" has already been defined" +#~ msgstr "Constanta „%s” a fost deja definită" -#: ../src/ui/theme.c:1977 ../src/ui/theme.c:1987 ../src/ui/theme.c:2021 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "Expresia coordonatelor este rezultată în urma unei împărțiri la zero" +#~ msgid "No \"%s\" attribute on element <%s>" +#~ msgstr "Nici un atribut „%s” în elementul <%s>" -#: ../src/ui/theme.c:2029 -#, c-format -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "" -"Expresia coordonatelor încearcă să folosească operatorul mod asupra unui " -"număr în virgulă mobilă" +#~ msgid "Line %d character %d: %s" +#~ msgstr "Linia %d caracterul %d: %s" -#: ../src/ui/theme.c:2085 -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "Expresia coordonatelor are un operator „%s” care așteaptă un operand" +#~ msgid "Attribute \"%s\" repeated twice on the same <%s> element" +#~ msgstr "Atributul „%s” se repetă de două ori în același element <%s>" -#: ../src/ui/theme.c:2094 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "Expresia coordonatelor are un operand unde un operator era așteptat" +#~ msgid "Attribute \"%s\" is invalid on <%s> element in this context" +#~ msgstr "Atributul „%s” este invalid în elementul <%s> în acest context" -#: ../src/ui/theme.c:2102 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "" -"Expresia coordonatelor a fost terminată cu un operator în locul operandului" +#~ msgid "Could not parse \"%s\" as an integer" +#~ msgstr "Nu s-a putut analiza „%s” ca un întreg" -#: ../src/ui/theme.c:2112 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" -"Expresia coordonatelor are un operator „%c” urmând operatorului „%c” fără un " -"operand între ele" +#~ msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +#~ msgstr "Nu s-au putut înțelege caracterele „%s” din șirul „%s”" -#: ../src/ui/theme.c:2263 ../src/ui/theme.c:2308 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "Expresia coordonatelor are variabila necunscută sau constanta „%s”" +#~ msgid "Integer %ld must be positive" +#~ msgstr "Întregul %ld trebuie să fie pozitiv" -#: ../src/ui/theme.c:2362 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "" -"Analizatorul expresiei de coordonate a depăsit dimeniunea zonei de memorie " -"tampon." +#~ msgid "Integer %ld is too large, current max is %d" +#~ msgstr "Întregul %ld este prea mare, maximul este %d" -#: ../src/ui/theme.c:2391 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "" -"Expresia coordonatelor are o paranteză închisă fără nici o paranteză deschisă" +#~ msgid "Could not parse \"%s\" as a floating point number" +#~ msgstr "Nu s-a putut analiza „%s” drept un număr în virgulă mobilă" -#: ../src/ui/theme.c:2455 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "Expresia coordonatelor are o paranteză deschisă și nici una închisă" +#~ msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" +#~ msgstr "Valorile logice trebuie să fie „true” sau „false” nu „%s”" -#: ../src/ui/theme.c:2466 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "Expresia coordonatelor nu are nici un operator și operand" +#~ msgid "Angle must be between 0.0 and 360.0, was %g\n" +#~ msgstr "Unghiul trebuie să fie între 0.0 și 360.0, el fiind %g\n" -#: ../src/ui/theme.c:2676 ../src/ui/theme.c:2696 ../src/ui/theme.c:2716 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "Tema conținea o expresie ce a rezultat într-o eroare: %s\n" +#~ msgid "" +#~ "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" +#~ msgstr "" +#~ "Alfa trebuie să fie între 0.0 (invizibil) și 1.0 (complet opac), el fiind " +#~ "%g\n" -#: ../src/ui/theme.c:4410 -#, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> trebuie " -"specificate pentru stilul acestui cadru" +#~ msgid "" +#~ "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," +#~ "large,x-large,xx-large)\n" +#~ msgstr "" +#~ "Scalare invalidă a titlului „%s” (trebuie să fie una dintre xx-small,x-" +#~ "small,small,medium,large,x-large,xx-large)\n" -#: ../src/ui/theme.c:4940 ../src/ui/theme.c:4965 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" -"Lipsește <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" +#~ msgid "<%s> name \"%s\" used a second time" +#~ msgstr "<%s> numit „%s” este folosit a doua oară" -#: ../src/ui/theme.c:5013 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Nu s-a putut încărca tema „%s”: %s\n" +#~ msgid "<%s> parent \"%s\" has not been defined" +#~ msgstr "<%s> părinte „%s” nu a fost definit" -#: ../src/ui/theme.c:5149 ../src/ui/theme.c:5156 ../src/ui/theme.c:5163 -#: ../src/ui/theme.c:5170 ../src/ui/theme.c:5177 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "Nu a fost definit nici un <%s> pentru tema „%s”" +#~ msgid "<%s> geometry \"%s\" has not been defined" +#~ msgstr "<%s> geometrie „%s” nu a fost definită" -#: ../src/ui/theme.c:5185 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" -"Nici un stil de cadru definit pentru tipul de fereastră „%s” în tema „%s”; " -"adăugați un element <window type=\"%s\" style_set=\"whatever\"/>" +#~ msgid "<%s> must specify either a geometry or a parent that has a geometry" +#~ msgstr "" +#~ "<%s> trebuie să specifice o geometrie sau un părinte care are o geometrie" -#: ../src/ui/theme.c:5635 ../src/ui/theme.c:5697 ../src/ui/theme.c:5760 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" -"Constantele definite de utilizatori trebuie să înceapă cu o majusculă; „%s” " -"nu respectă acest lucru" +#~ msgid "You must specify a background for an alpha value to be meaningful" +#~ msgstr "" +#~ "Trebuie să specificați un fundal pentru o valoare alfa pentru a avea sens" -#: ../src/ui/theme.c:5643 ../src/ui/theme.c:5705 ../src/ui/theme.c:5768 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "Constanta „%s” a fost deja definită" +#~ msgid "Unknown type \"%s\" on <%s> element" +#~ msgstr "Tip necunoscut „%s” în elementul <%s>" -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. -#. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "Nici un atribut „%s” în elementul <%s>" +#~ msgid "Unknown style_set \"%s\" on <%s> element" +#~ msgstr "style_set necunoscut „%s” în elementul <%s>" -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Linia %d caracterul %d: %s" +#~ msgid "Window type \"%s\" has already been assigned a style set" +#~ msgstr "Ferestrei tip „%s” i-a fost deja atribuit un set de stil" -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "Atributul „%s” se repetă de două ori în același element <%s>" +#~ msgid "Element <%s> is not allowed below <%s>" +#~ msgstr "Elementul <%s> nu poate coborî sub <%s>" -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "Atributul „%s” este invalid în elementul <%s> în acest context" +#~ msgid "" +#~ "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio" +#~ "\" for buttons" +#~ msgstr "" +#~ "Nu se pot specifica în același timp „button_width”/„button_height” și " +#~ "„aspect_ratio” pentru butoane" -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "Nu s-a putut analiza „%s” ca un întreg" +#~ msgid "Distance \"%s\" is unknown" +#~ msgstr "Distanța „%s” este necunoscută" -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "Nu s-au putut înțelege caracterele „%s” din șirul „%s”" +#~ msgid "Aspect ratio \"%s\" is unknown" +#~ msgstr "Proporția „%s” este necunoscută" -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "Întregul %ld trebuie să fie pozitiv" +#~ msgid "Border \"%s\" is unknown" +#~ msgstr "Marginea „%s” este necunoscută" -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "Întregul %ld este prea mare, maximul este %d" +#~ msgid "No \"start_angle\" or \"from\" attribute on element <%s>" +#~ msgstr "Nu există atributul „start_angle” sau „from” în elementul <%s>" -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "Nu s-a putut analiza „%s” drept un număr în virgulă mobilă" +#~ msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" +#~ msgstr "Nu există atributul „extent_angle” sau „to” în elementul <%s>" -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "Valorile logice trebuie să fie „true” sau „false” nu „%s”" +#~ msgid "Did not understand value \"%s\" for type of gradient" +#~ msgstr "Nu s-a putut întelege valoarea „%s” pentru tipul de degrade" -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "Unghiul trebuie să fie între 0.0 și 360.0, el fiind %g\n" +#~ msgid "Did not understand fill type \"%s\" for <%s> element" +#~ msgstr "Nu s-a putut înțelege tipul de umplere „%s” pentru elementul <%s>" -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" -"Alfa trebuie să fie între 0.0 (invizibil) și 1.0 (complet opac), el fiind %" -"g\n" +#~ msgid "Did not understand state \"%s\" for <%s> element" +#~ msgstr "Nu s-a putut înțelege starea „%s” pentru elementul <%s>" -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"Scalare invalidă a titlului „%s” (trebuie să fie una dintre xx-small,x-small," -"small,medium,large,x-large,xx-large)\n" +#~ msgid "Did not understand shadow \"%s\" for <%s> element" +#~ msgstr "Nu s-a putut înțelege umbra „%s” pentru elementul <%s>" -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s> numit „%s” este folosit a doua oară" +#~ msgid "Did not understand arrow \"%s\" for <%s> element" +#~ msgstr "Nu s-a putut înțelege săgeata „%s” pentru elementul <%s>" -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "<%s> părinte „%s” nu a fost definit" +#~ msgid "No <draw_ops> called \"%s\" has been defined" +#~ msgstr "Nici un <draw_ops> numit „%s” nu a fost definit" -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "<%s> geometrie „%s” nu a fost definită" +#~ msgid "Including draw_ops \"%s\" here would create a circular reference" +#~ msgstr "Includerea lui draw_ops „%s” aici ar crea o referință circulară" -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "" -"<%s> trebuie să specifice o geometrie sau un părinte care are o geometrie" +#~ msgid "Unknown position \"%s\" for frame piece" +#~ msgstr "Poziție necunoscută „%s” pentru componenta cadrului" -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "" -"Trebuie să specificați un fundal pentru o valoare alfa pentru a avea sens" +#~ msgid "Frame style already has a piece at position %s" +#~ msgstr "Stilul cadrului are deja o componentă la poziția %s" -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Tip necunoscut „%s” în elementul <%s>" +#~ msgid "No <draw_ops> with the name \"%s\" has been defined" +#~ msgstr "Nici o <draw_ops> cu numele „%s” nu a fost definită" -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "style_set necunoscut „%s” în elementul <%s>" +#~ msgid "Unknown function \"%s\" for button" +#~ msgstr "Funcție necunoscută „%s” pentru buton" -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "Ferestrei tip „%s” i-a fost deja atribuit un set de stil" - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "Elementul <%s> nu poate coborî sub <%s>" +#~ msgid "Button function \"%s\" does not exist in this version (%d, need %d)" +#~ msgstr "" +#~ "Funcția pentru butonul „%s” nu există în această versiune (%d, avem " +#~ "nevoie de %d)" -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" -msgstr "" -"Nu se pot specifica în același timp „button_width”/„button_height” și " -"„aspect_ratio” pentru butoane" +#~ msgid "Unknown state \"%s\" for button" +#~ msgstr "Stare necunoscută „%s” pentru buton" -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "Distanța „%s” este necunoscută" +#~ msgid "Frame style already has a button for function %s state %s" +#~ msgstr "Stilul cadrului are deja un buton pentru funcția %s starea %s" -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "Proporția „%s” este necunoscută" +#~ msgid "\"%s\" is not a valid value for focus attribute" +#~ msgstr "„%s”nu este o valoare validă pentru atributul de focalizare" -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "Marginea „%s” este necunoscută" +#~ msgid "\"%s\" is not a valid value for state attribute" +#~ msgstr "„%s”nu este o valoare validă pentru atributul de stare" -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "Nu există atributul „start_angle” sau „from” în elementul <%s>" +#~ msgid "A style called \"%s\" has not been defined" +#~ msgstr "Un stil numit „%s” nu a fost definit" -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "Nu există atributul „extent_angle” sau „to” în elementul <%s>" +#~ msgid "\"%s\" is not a valid value for resize attribute" +#~ msgstr "„%s” nu este o valoare validă pentru atributul de redimensionare" -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "Nu s-a putut întelege valoarea „%s” pentru tipul de degrade" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized/shaded " +#~ "states" +#~ msgstr "" +#~ "Nu ar trebui să aveți atributul „resize” în elementul <%s> pentru stările " +#~ "maximizate/umbrite" -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "Nu s-a putut înțelege tipul de umplere „%s” pentru elementul <%s>" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized states" +#~ msgstr "" +#~ "Nu trebuie să conțină atributul „resize” în elementul <%s> pentru stările " +#~ "maximizate" -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "Nu s-a putut înțelege starea „%s” pentru elementul <%s>" +#~ msgid "Style has already been specified for state %s resize %s focus %s" +#~ msgstr "" +#~ "Stilul a fost deja specificat pentru starea %s redimensionare %s " +#~ "focalizare %s" -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "Nu s-a putut înțelege umbra „%s” pentru elementul <%s>" +#~ msgid "Style has already been specified for state %s focus %s" +#~ msgstr "Stilul deja a fost specificat pentru starea %s focalizarea %s" -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "Nu s-a putut înțelege săgeata „%s” pentru elementul <%s>" +#~ msgid "" +#~ "Can't have a two draw_ops for a <piece> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Nu puteți avea două draw_ops pentru un element <piece> (tema a specificat " +#~ "un atribut draw_ops și un element <draw_ops>, sau pe amândouă)" -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "Nici un <draw_ops> numit „%s” nu a fost definit" +#~ msgid "" +#~ "Can't have a two draw_ops for a <button> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Nu puteți avea două draw_ops pentru un element <button> (tema a " +#~ "specificat un atribut draw_ops și un element <draw_ops>, sau pe amândouă)" -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "Includerea lui draw_ops „%s” aici ar crea o referință circulară" +#~ msgid "" +#~ "Can't have a two draw_ops for a <menu_icon> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Nu puteți avea două draw_ops pentru un element <menu_icon> (tema a " +#~ "specificat un atribut draw_ops și un element <draw_ops>, sau pe amândouă)" -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Poziție necunoscută „%s” pentru componenta cadrului" +#~ msgid "Bad version specification '%s'" +#~ msgstr "Specificator de versiune nevalid „%s”" -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "Stilul cadrului are deja o componentă la poziția %s" +#~ msgid "" +#~ "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" +#~ "theme-2.xml" +#~ msgstr "" +#~ "atributul „version” nu poate fi utilizat în metacity-theme-1.xml sau " +#~ "metacity-theme-2.xml" -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "Nici o <draw_ops> cu numele „%s” nu a fost definită" +#~ msgid "" +#~ "Theme requires version %s but latest supported theme version is %d.%d" +#~ msgstr "" +#~ "Tema necesită versiunea %s, dar cea mai recentă versiune de temă acceptă " +#~ "este %d.%d" -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Funcție necunoscută „%s” pentru buton" +#~ msgid "Outermost element in theme must be <metacity_theme> not <%s>" +#~ msgstr "Elementul extern în temă trebuie să fie <metacity_theme> nu %s" -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "" -"Funcția pentru butonul „%s” nu există în această versiune (%d, avem nevoie " -"de %d)" +#~ msgid "" +#~ "Element <%s> is not allowed inside a name/author/date/description element" +#~ msgstr "" +#~ "Elementul <%s> nu este permis în interiorul un element name/author/date/" +#~ "description" -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Stare necunoscută „%s” pentru buton" +#~ msgid "Element <%s> is not allowed inside a <constant> element" +#~ msgstr "Elementul <%s> nu este permis în interiorul unui element <constant>" -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "Stilul cadrului are deja un buton pentru funcția %s starea %s" +#~ msgid "" +#~ "Element <%s> is not allowed inside a distance/border/aspect_ratio element" +#~ msgstr "" +#~ "Elementul <%s> nu este permis în interiorul unui element distance/border/" +#~ "aspect_ratio" -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "„%s”nu este o valoare validă pentru atributul de focalizare" +#~ msgid "Element <%s> is not allowed inside a draw operation element" +#~ msgstr "" +#~ "Elementul <%s> nu este permis în interiorul unui element de desenare" -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "„%s”nu este o valoare validă pentru atributul de stare" +#~ msgid "Element <%s> is not allowed inside a <%s> element" +#~ msgstr "Elementul <%s> nu este permis în interiorul unui element <%s>" -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "Un stil numit „%s” nu a fost definit" +#~ msgid "No draw_ops provided for frame piece" +#~ msgstr "Nici o draw_ops furnizată pentru o componentă de cadru" -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "„%s” nu este o valoare validă pentru atributul de redimensionare" +#~ msgid "No draw_ops provided for button" +#~ msgstr "Nici o draw_ops furnizată pentru buton" -#: ../src/ui/theme-parser.c:3147 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" -"Nu ar trebui să aveți atributul „resize” în elementul <%s> pentru stările " -"maximizate/umbrite" +#~ msgid "No text is allowed inside element <%s>" +#~ msgstr "Nici un text nu este permis în interiorul <%s>" -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "" -"Nu trebuie să conțină atributul „resize” în elementul <%s> pentru stările " -"maximizate" +#~| msgid "<name> specified twice for this theme" +#~ msgid "<%s> specified twice for this theme" +#~ msgstr "<%s> este specificat de două ori pentru această temă" -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "" -"Stilul a fost deja specificat pentru starea %s redimensionare %s focalizare %" -"s" +#~ msgid "Failed to find a valid file for theme %s\n" +#~ msgstr "Nu am putut găsi un fișier valid pentru tema %s\n" -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "Stilul deja a fost specificat pentru starea %s focalizarea %s" +#~| msgid "/_Windows" +#~ msgid "_Windows" +#~ msgstr "_Ferestre" -#: ../src/ui/theme-parser.c:3294 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Nu puteți avea două draw_ops pentru un element <piece> (tema a specificat un " -"atribut draw_ops și un element <draw_ops>, sau pe amândouă)" +#~| msgid "Dialog Box" +#~ msgid "_Dialog" +#~ msgstr "_Dialog" -#: ../src/ui/theme-parser.c:3332 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Nu puteți avea două draw_ops pentru un element <button> (tema a specificat " -"un atribut draw_ops și un element <draw_ops>, sau pe amândouă)" +#~| msgid "Modal Dialog Box" +#~ msgid "_Modal dialog" +#~ msgstr "Fereastră _modală de dialog" -#: ../src/ui/theme-parser.c:3370 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Nu puteți avea două draw_ops pentru un element <menu_icon> (tema a " -"specificat un atribut draw_ops și un element <draw_ops>, sau pe amândouă)" +#~| msgid "/Windows/_Utility" +#~ msgid "_Utility" +#~ msgstr "_Utilitar" -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "Specificator de versiune nevalid „%s”" +#~| msgid "/Windows/_Splashscreen" +#~ msgid "_Splashscreen" +#~ msgstr "_Ecran de pornire" -#: ../src/ui/theme-parser.c:3507 -msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" -msgstr "" -"atributul „version” nu poate fi utilizat în metacity-theme-1.xml sau " -"metacity-theme-2.xml" +#~| msgid "/Windows/_Top dock" +#~ msgid "_Top dock" +#~ msgstr "Andocare _sus" -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "" -"Tema necesită versiunea %s, dar cea mai recentă versiune de temă acceptă " -"este %d.%d" +#~| msgid "/Windows/_Bottom dock" +#~ msgid "_Bottom dock" +#~ msgstr "Andocare _jos" -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "Elementul extern în temă trebuie să fie <metacity_theme> nu %s" +#~| msgid "/Windows/_Left dock" +#~ msgid "_Left dock" +#~ msgstr "_Andocare stânga" -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "" -"Elementul <%s> nu este permis în interiorul un element name/author/date/" -"description" +#~| msgid "/Windows/_Right dock" +#~ msgid "_Right dock" +#~ msgstr "Andocare _dreapta" -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "Elementul <%s> nu este permis în interiorul unui element <constant>" +#~| msgid "/Windows/_All docks" +#~ msgid "_All docks" +#~ msgstr "Toate _andocările" -#: ../src/ui/theme-parser.c:3599 -#, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "" -"Elementul <%s> nu este permis în interiorul unui element distance/border/" -"aspect_ratio" +#~| msgid "Desktop" +#~ msgid "Des_ktop" +#~ msgstr "Des_ktop" -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "Elementul <%s> nu este permis în interiorul unui element de desenare" +#~ msgid "Open another one of these windows" +#~ msgstr "Deschide încă o fereastră" -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "Elementul <%s> nu este permis în interiorul unui element <%s>" +#~ msgid "This is a demo button with an 'open' icon" +#~ msgstr "Acesta este un buton demo cu o iconiță „deschide”" -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "Nici o draw_ops furnizată pentru o componentă de cadru" +#~ msgid "This is a demo button with a 'quit' icon" +#~ msgstr "Acesta este un buton demo cu o iconiță „renunță”" -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "Nici o draw_ops furnizată pentru buton" +#~ msgid "This is a sample message in a sample dialog" +#~ msgstr "Acesta este un mesaj de test într-un dialog de test" -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "Nici un text nu este permis în interiorul <%s>" +#~ msgid "Fake menu item %d\n" +#~ msgstr "Element fals de meniu %d\n" -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -#| msgid "<name> specified twice for this theme" -msgid "<%s> specified twice for this theme" -msgstr "<%s> este specificat de două ori pentru această temă" +#~ msgid "Border-only window" +#~ msgstr "Fereastră doar cu margine" -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Nu am putut găsi un fișier valid pentru tema %s\n" - -#: ../src/ui/theme-viewer.c:99 -#| msgid "/_Windows" -msgid "_Windows" -msgstr "_Ferestre" - -#: ../src/ui/theme-viewer.c:100 -#| msgid "Dialog Box" -msgid "_Dialog" -msgstr "_Dialog" - -#: ../src/ui/theme-viewer.c:101 -#| msgid "Modal Dialog Box" -msgid "_Modal dialog" -msgstr "Fereastră _modală de dialog" - -#: ../src/ui/theme-viewer.c:102 -#| msgid "/Windows/_Utility" -msgid "_Utility" -msgstr "_Utilitar" - -#: ../src/ui/theme-viewer.c:103 -#| msgid "/Windows/_Splashscreen" -msgid "_Splashscreen" -msgstr "_Ecran de pornire" - -#: ../src/ui/theme-viewer.c:104 -#| msgid "/Windows/_Top dock" -msgid "_Top dock" -msgstr "Andocare _sus" - -#: ../src/ui/theme-viewer.c:105 -#| msgid "/Windows/_Bottom dock" -msgid "_Bottom dock" -msgstr "Andocare _jos" - -#: ../src/ui/theme-viewer.c:106 -#| msgid "/Windows/_Left dock" -msgid "_Left dock" -msgstr "_Andocare stânga" - -#: ../src/ui/theme-viewer.c:107 -#| msgid "/Windows/_Right dock" -msgid "_Right dock" -msgstr "Andocare _dreapta" - -#: ../src/ui/theme-viewer.c:108 -#| msgid "/Windows/_All docks" -msgid "_All docks" -msgstr "Toate _andocările" - -#: ../src/ui/theme-viewer.c:109 -#| msgid "Desktop" -msgid "Des_ktop" -msgstr "Des_ktop" - -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "Deschide încă o fereastră" - -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "Acesta este un buton demo cu o iconiță „deschide”" - -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "Acesta este un buton demo cu o iconiță „renunță”" - -#: ../src/ui/theme-viewer.c:253 -msgid "This is a sample message in a sample dialog" -msgstr "Acesta este un mesaj de test într-un dialog de test" - -#: ../src/ui/theme-viewer.c:336 -#, c-format -msgid "Fake menu item %d\n" -msgstr "Element fals de meniu %d\n" +#~ msgid "Bar" +#~ msgstr "Bară" -#: ../src/ui/theme-viewer.c:370 -msgid "Border-only window" -msgstr "Fereastră doar cu margine" +#~ msgid "Normal Application Window" +#~ msgstr "Fereastră normală de aplicație" -#: ../src/ui/theme-viewer.c:372 -msgid "Bar" -msgstr "Bară" +#~ msgid "Dialog Box" +#~ msgstr "Fereastră de dialog" -#: ../src/ui/theme-viewer.c:389 -msgid "Normal Application Window" -msgstr "Fereastră normală de aplicație" +#~ msgid "Modal Dialog Box" +#~ msgstr "Fereastră modală de dialog" -#: ../src/ui/theme-viewer.c:393 -msgid "Dialog Box" -msgstr "Fereastră de dialog" +#~ msgid "Utility Palette" +#~ msgstr "Paletă utilitară" -#: ../src/ui/theme-viewer.c:397 -msgid "Modal Dialog Box" -msgstr "Fereastră modală de dialog" +#~ msgid "Torn-off Menu" +#~ msgstr "Meniu Torn-off" -#: ../src/ui/theme-viewer.c:401 -msgid "Utility Palette" -msgstr "Paletă utilitară" +#~ msgid "Border" +#~ msgstr "Margine" -#: ../src/ui/theme-viewer.c:405 -msgid "Torn-off Menu" -msgstr "Meniu Torn-off" +#~| msgid "Modal Dialog Box" +#~ msgid "Attached Modal Dialog" +#~ msgstr "Fereastră modală de dialog atașată" -#: ../src/ui/theme-viewer.c:409 -msgid "Border" -msgstr "Margine" +#~ msgid "Button layout test %d" +#~ msgstr "Aranjament de test pentru buton %d" -#: ../src/ui/theme-viewer.c:413 -#| msgid "Modal Dialog Box" -msgid "Attached Modal Dialog" -msgstr "Fereastră modală de dialog atașată" +#~ msgid "%g milliseconds to draw one window frame" +#~ msgstr "%g milisecunde pentru a afișa un cadru de fereastră" -#: ../src/ui/theme-viewer.c:744 -#, c-format -msgid "Button layout test %d" -msgstr "Aranjament de test pentru buton %d" +#~ msgid "Usage: metacity-theme-viewer [THEMENAME]\n" +#~ msgstr "Utilizare: metacity-theme-viewer [NUME TEMĂ]\n" -#: ../src/ui/theme-viewer.c:773 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g milisecunde pentru a afișa un cadru de fereastră" +#~ msgid "Error loading theme: %s\n" +#~ msgstr "Eroare la încărcarea temei: %s\n" -#: ../src/ui/theme-viewer.c:818 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Utilizare: metacity-theme-viewer [NUME TEMĂ]\n" +#~ msgid "Loaded theme \"%s\" in %g seconds\n" +#~ msgstr "S-a încărcat tema „%s“ în %g secunde\n" -#: ../src/ui/theme-viewer.c:825 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "Eroare la încărcarea temei: %s\n" +#~ msgid "Normal Title Font" +#~ msgstr "Font pentru titlu normal" -#: ../src/ui/theme-viewer.c:831 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "S-a încărcat tema „%s“ în %g secunde\n" +#~ msgid "Small Title Font" +#~ msgstr "Font pentru titlu mic" -#: ../src/ui/theme-viewer.c:875 -msgid "Normal Title Font" -msgstr "Font pentru titlu normal" +#~ msgid "Large Title Font" +#~ msgstr "Font pentru titlu mare" -#: ../src/ui/theme-viewer.c:881 -msgid "Small Title Font" -msgstr "Font pentru titlu mic" +#~ msgid "Button Layouts" +#~ msgstr "Aranjamente butoane" -#: ../src/ui/theme-viewer.c:887 -msgid "Large Title Font" -msgstr "Font pentru titlu mare" +#~ msgid "Benchmark" +#~ msgstr "Test de performanță" -#: ../src/ui/theme-viewer.c:892 -msgid "Button Layouts" -msgstr "Aranjamente butoane" +#~ msgid "Window Title Goes Here" +#~ msgstr "Titlul de fereastră vine aici" -#: ../src/ui/theme-viewer.c:897 -msgid "Benchmark" -msgstr "Test de performanță" +#~ msgid "" +#~ "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and " +#~ "%g seconds wall clock time including X server resources (%g milliseconds " +#~ "per frame)\n" +#~ msgstr "" +#~ "%d cadre desenate în %g secunde măsurate la client (%g milisecunde pe " +#~ "cadru) și %g secunde consumate de proces incluzând resursele serverului X " +#~ "(%g milisecunde pe cadru)\n" -#: ../src/ui/theme-viewer.c:949 -msgid "Window Title Goes Here" -msgstr "Titlul de fereastră vine aici" +#~ msgid "position expression test returned TRUE but set error" +#~ msgstr "testul de poziție a returnat TRUE dar a setat eroare" -#: ../src/ui/theme-viewer.c:1055 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"%d cadre desenate în %g secunde măsurate la client (%g milisecunde pe cadru) " -"și %g secunde consumate de proces incluzând resursele serverului X (%g " -"milisecunde pe cadru)\n" +#~ msgid "position expression test returned FALSE but didn't set error" +#~ msgstr "testul de poziție a returnat FALSE dar nu a setat eroarea" -#: ../src/ui/theme-viewer.c:1274 -msgid "position expression test returned TRUE but set error" -msgstr "testul de poziție a returnat TRUE dar a setat eroare" +#~ msgid "Error was expected but none given" +#~ msgstr "A fost așteptată o eroare, dar nu a fost furnizată" -#: ../src/ui/theme-viewer.c:1276 -msgid "position expression test returned FALSE but didn't set error" -msgstr "testul de poziție a returnat FALSE dar nu a setat eroarea" +#~ msgid "Error %d was expected but %d given" +#~ msgstr "Eroarea %d a fost așteptată dar a fost furnizată %d" -#: ../src/ui/theme-viewer.c:1280 -msgid "Error was expected but none given" -msgstr "A fost așteptată o eroare, dar nu a fost furnizată" +#~ msgid "Error not expected but one was returned: %s" +#~ msgstr "Eroare neașteptată a fost returnată: %s" -#: ../src/ui/theme-viewer.c:1282 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "Eroarea %d a fost așteptată dar a fost furnizată %d" +#~ msgid "x value was %d, %d was expected" +#~ msgstr "valoarea x a fost %d, %d fiind așteptată" -#: ../src/ui/theme-viewer.c:1288 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "Eroare neașteptată a fost returnată: %s" +#~ msgid "y value was %d, %d was expected" +#~ msgstr "valoarea y a fost %d, %d fiind așteptată" -#: ../src/ui/theme-viewer.c:1292 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "valoarea x a fost %d, %d fiind așteptată" +#~ msgid "" +#~ "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" +#~ msgstr "" +#~ "Expresiile pentru coordonate %d parsate în %g secunde (o medie de %g " +#~ "secunde)\n" -#: ../src/ui/theme-viewer.c:1295 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "valoarea y a fost %d, %d fiind așteptată" +#, fuzzy +#~ msgid "Launchers" +#~ msgstr "Lansatori" -#: ../src/ui/theme-viewer.c:1360 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "" -"Expresiile pentru coordonate %d parsate în %g secunde (o medie de %g " -"secunde)\n" +#, fuzzy +#~| msgid "Take a screenshot" +#~ msgid "Screenshots" +#~ msgstr "Capturi de ecran" #~ msgid "Window Management" #~ msgstr "Administrare ferestre" @@ -2098,9 +2022,6 @@ msgstr "" #~ msgid "Commands to run in response to keybindings" #~ msgstr "Comanda care va fi rulată la o combinație de taste" -#~ msgid "Compositing Manager" -#~ msgstr "Manager de compoziție" - #~ msgid "Control how new windows get focus" #~ msgstr "Controlează modul de activare a ferestrelor noi" @@ -2130,18 +2051,6 @@ msgstr "" #~ msgid "Enable Visual Bell" #~ msgstr "Activează bip vizual" -#~ msgid "" -#~ "If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " -#~ "the focused window will be automatically raised after a delay specified " -#~ "by the auto_raise_delay key. This is not related to clicking on a window " -#~ "to raise it, nor to entering a window during drag-and-drop." -#~ msgstr "" -#~ "Dacă este activat iar modul de focalizare este „sloppy” sau „mouse”, " -#~ "fereastra focalizată va fi automat ridicată după o întârziere precizată " -#~ "de cheia auto_raise_delay. Aceasta nu are legătură cu clicul pe o " -#~ "fereastră pentru a o ridica și nici cu pătrunderea într-o fereastră în " -#~ "timpul unei operațiuni trage-și-plasează." - #~ msgid "" #~ "If true, ignore the titlebar_font option, and use the standard " #~ "application font for window titles." @@ -2568,12 +2477,6 @@ msgstr "" #~ msgid "Move between panels and the desktop with popup" #~ msgstr "Mută între panouri și desktop cu popup" -#~ msgid "Move between windows of an application with popup" -#~ msgstr "Mută între ferestrele unei aplicații cu popup" - -#~ msgid "Move between windows with popup" -#~ msgstr "Mută între ferestre cu popup" - #~ msgid "Move focus backwards between windows using popup display" #~ msgstr "Mută focalizarea înapoi între ferestre folosind afișare popup" @@ -3616,10 +3519,10 @@ msgstr "" #~ msgid "" #~ "This keybinding moves a window into the east (right) side of the screen. " -#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -#~ "\". The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " +#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>" +#~ "F1\". The parser is fairly liberal and allows lower or upper case, and " +#~ "also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " +#~ "set the option to the special string \"disabled\", then there will be no " #~ "keybinding for this action." #~ msgstr "" #~ "Combinația de taste folosită pentru a muta fereastra în partea de est " @@ -3706,10 +3609,10 @@ msgstr "" #~ msgid "" #~ "This keybinding moves a window into the west (left) side of the screen. " -#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -#~ "\". The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " +#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>" +#~ "F1\". The parser is fairly liberal and allows lower or upper case, and " +#~ "also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " +#~ "set the option to the special string \"disabled\", then there will be no " #~ "keybinding for this action." #~ msgstr "" #~ "Combinația de taste folosită pentru a muta fereastra în partea de vest " @@ -3767,9 +3670,6 @@ msgstr "" #~ msgid "Toggle always on top state" #~ msgstr "Comută întotdeauna deasupra" -#~ msgid "Toggle window on all workspaces" -#~ msgstr "Comută fereastra pe toate spațiile de lucru" - #~ msgid "Unmaximize Window" #~ msgstr "Restaurează fereastra" diff --git a/po/ru.po b/po/ru.po index 61c7d306e..0f136c89a 100644 --- a/po/ru.po +++ b/po/ru.po @@ -7,1751 +7,1123 @@ # Andrew w. Nosenko <awn@bcs.zp.ua>, 2003. # Leonid Kanter <leon@asplinux.ru>, 2004, 2005, 2006. # Yuri Kozlov <yuray@komyakino.ru>, 2011. +# Yuri Myasoedov <ymyasoedov@yandex.ru>, 2012-2014, 2015. +# Ivan Komaritsyn <vantu5z@mail.ru>, 2015. +# Stas Solovey <whats_up@tut.by>, 2016. +# msgid "" msgstr "" "Project-Id-Version: metacity ru\n" -"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=muffin&keywords=I18N+L10N&component=general\n" -"POT-Creation-Date: 2012-03-15 21:29+0000\n" -"PO-Revision-Date: 2012-03-21 22:26+0300\n" -"Last-Translator: Yuri Myasoedov <omerta13@yandex.ru>\n" -"Language-Team: Russian <gnome-cyr@gnome.org>\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?" +"product=mutter&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-02-28 06:20+0000\n" +"PO-Revision-Date: 2017-03-18 10:56+0400\n" +"Last-Translator: Yuri Myasoedov <ymyasoedov@yandex.ru>\n" +"Language-Team: Русский <gnome-cyr@gnome.org>\n" +"Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -"X-Generator: Lokalize 1.0\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Poedit 1.8.7.1\n" -#: ../src/50-muffin-windows.xml.in.h:1 -msgid "Windows" -msgstr "Окна" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Перемещение" -#: ../src/50-muffin-windows.xml.in.h:2 -msgid "View split on left" -msgstr "Разделитель слева" +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Переместить окно на рабочее место 1" -#: ../src/50-muffin-windows.xml.in.h:3 -msgid "View split on right" -msgstr "Разделитель справа" +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Переместить окно на рабочее место 2" -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format -msgid "Another compositing manager is already running on screen %i on display \"%s\"." -msgstr "На экране %i дисплея «%s» уже запущен другой оконный менеджер." +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Переместить окно на рабочее место 3" -#: ../src/core/bell.c:307 -msgid "Bell event" -msgstr "Событие звонка" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Переместить окно на рабочее место 4" -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Неизвестный запрос сведений об окне: %d" +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Переместить окно на последнее рабочее место" -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> не отвечает." +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace to the left" +msgstr "Переместить окно на одно рабочее место влево" -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "Приложение не отвечает." +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace to the right" +msgstr "Переместить окно на одно рабочее место вправо" -#: ../src/core/delete.c:119 -msgid "You may choose to wait a short while for it to continue or force the application to quit entirely." -msgstr "Можно немного подождать или принудительно завершить работу приложения." +#: data/50-mutter-navigation.xml:30 +msgid "Move window one workspace up" +msgstr "Переместить окно на одно рабочее место вверх" -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "_Подождать" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one workspace down" +msgstr "Переместить окно на одно рабочее место вниз" -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "Завер_шить" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor to the left" +msgstr "Переместить окно на один монитор влево" -#: ../src/core/display.c:387 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "Отсутствует расширение %s, требуемое для композиции" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor to the right" +msgstr "Переместить окно на один монитор вправо" -#: ../src/core/display.c:453 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Не удалось открыть дисплей «%s» системы X Window\n" +#: data/50-mutter-navigation.xml:42 +msgid "Move window one monitor up" +msgstr "Переместить окно на один монитор вверх" -#: ../src/core/keybindings.c:852 -#, c-format -msgid "Some other program is already using the key %s with modifiers %x as a binding\n" -msgstr "Клавишу «%s» с модификаторами «%x» уже использует другая программа\n" +#: data/50-mutter-navigation.xml:45 +msgid "Move window one monitor down" +msgstr "Переместить окно на один монитор вниз" -#: ../src/core/main.c:206 -msgid "Disable connection to session manager" -msgstr "Запретить подключение к менеджеру сеансов" +#: data/50-mutter-navigation.xml:49 +msgid "Switch applications" +msgstr "Переключить приложения" -#: ../src/core/main.c:212 -msgid "Replace the running window manager" -msgstr "Заменить запущенный оконный менеджер" +#: data/50-mutter-navigation.xml:54 +msgid "Switch to previous application" +msgstr "Переключить на предыдущее приложение" -#: ../src/core/main.c:218 -msgid "Specify session management ID" -msgstr "Указать идентификатор управления сеансом" +#: data/50-mutter-navigation.xml:58 +msgid "Switch windows" +msgstr "Переключить окна" -#: ../src/core/main.c:223 -msgid "X Display to use" -msgstr "Используемый дисплей X" +#: data/50-mutter-navigation.xml:63 +msgid "Switch to previous window" +msgstr "Переключить на предыдущее окно" -#: ../src/core/main.c:229 -msgid "Initialize session from savefile" -msgstr "Инициализировать сеанс из сохранённого файла" +#: data/50-mutter-navigation.xml:67 +msgid "Switch windows of an application" +msgstr "Переключить окна приложения" -#: ../src/core/main.c:235 -msgid "Make X calls synchronous" -msgstr "Сделать X-вызовы синхронными" +#: data/50-mutter-navigation.xml:72 +msgid "Switch to previous window of an application" +msgstr "Переключить на окно приложения" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Не удалось прочитать каталог тем: %s\n" +#: data/50-mutter-navigation.xml:76 +msgid "Switch system controls" +msgstr "Переключить элементы управления" -#: ../src/core/main.c:520 -#, c-format -msgid "Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "Не удалось найти тему! Убедитесь, что «%s» существует и содержит обычные темы.\n" +#: data/50-mutter-navigation.xml:81 +msgid "Switch to previous system control" +msgstr "Переключить на предыдущий элемент управления" -#: ../src/core/muffin.c:40 -#, c-format -msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" -msgstr "" -"metacity %s\n" -"Авторское право © 2001—%d Havoc Pennington, Red Hat, Inc. и другие\n" -"Это — свободное программное обеспечение; условия копирования указаны в исходном тексте.\n" -"Распространяется без каких-либо гарантий, в том числе и БЕЗ гарантий потребительской стоимости и пригодности для выполнения каких бы то ни было определённых задач.\n" +#: data/50-mutter-navigation.xml:85 +msgid "Switch windows directly" +msgstr "Немедленно переключить окна" -#: ../src/core/muffin.c:54 -msgid "Print version" -msgstr "Вывести версию" +#: data/50-mutter-navigation.xml:90 +msgid "Switch directly to previous window" +msgstr "Немедленно переключить на предыдущее окно" -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "Список модулей, разделённых запятыми" +#: data/50-mutter-navigation.xml:94 +msgid "Switch windows of an app directly" +msgstr "Немедленно переключить окна приложения" -#: ../src/core/prefs.c:1077 -msgid "Workarounds for broken applications disabled. Some applications may not behave properly.\n" -msgstr "Устранение недоделок для сломанных приложений отключено. Некоторые приложения могут работать неправильно.\n" +#: data/50-mutter-navigation.xml:99 +msgid "Switch directly to previous window of an app" +msgstr "Немедленно переключить на предыдущее окно приложения" -#: ../src/core/prefs.c:1152 -#, c-format -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "Не удалось разобрать описание шрифта «%s» из ключа GSettings %s\n" +#: data/50-mutter-navigation.xml:103 +msgid "Switch system controls directly" +msgstr "Немедленно переключить элементы управления" -#: ../src/core/prefs.c:1218 -#, c-format -msgid "\"%s\" found in configuration database is not a valid value for mouse button modifier\n" -msgstr "Значение «%s» из базы данных настроек является недопустимым значением для модификатора кнопки мыши\n" +#: data/50-mutter-navigation.xml:108 +msgid "Switch directly to previous system control" +msgstr "Немедленно переключить на предыдущий элемент управления" -#: ../src/core/prefs.c:1739 -#, c-format -msgid "\"%s\" found in configuration database is not a valid value for keybinding \"%s\"\n" -msgstr "Значение «%s» из базы данных настроек является недопустимым значением для комбинации клавиш «%s»\n" +#: data/50-mutter-navigation.xml:111 +msgid "Hide all normal windows" +msgstr "Скрыть все обычные окна" -#: ../src/core/prefs.c:1836 -#, c-format -msgid "Workspace %d" -msgstr "Рабочее место %d" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 1" +msgstr "Переключиться на рабочее место 1" -#: ../src/core/screen.c:730 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "Недопустимый экран %d дисплея «%s»\n" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 2" +msgstr "Переключиться на рабочее место 2" -#: ../src/core/screen.c:746 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager; try using the --replace option to replace the current window manager.\n" -msgstr "У экрана %d дисплея «%s» уже есть менеджер окон. Попробуйте использовать параметр --replace, чтобы заместить текущий менеджер окон.\n" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to workspace 3" +msgstr "Переключиться на рабочее место 3" -#: ../src/core/screen.c:773 -#, c-format -msgid "Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "Не удалось выбрать менеджер окон на экране %d дисплея «%s»\n" +#: data/50-mutter-navigation.xml:123 +msgid "Switch to workspace 4" +msgstr "Переключиться на рабочее место 4" -#: ../src/core/screen.c:828 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "У экрана %d дисплея «%s» уже есть менеджер окон\n" +#: data/50-mutter-navigation.xml:126 +msgid "Switch to last workspace" +msgstr "Переключиться на последнее рабочее место" -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "Не удалось освободить экран %d дисплея «%s»\n" +#: data/50-mutter-navigation.xml:129 +msgid "Move to workspace left" +msgstr "Переместить на рабочее место влево" -#: ../src/core/session.c:843 -#: ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Не удалось создать каталог «%s»: %s\n" +#: data/50-mutter-navigation.xml:132 +msgid "Move to workspace right" +msgstr "Переместить на рабочее место вправо" -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "Не удалось открыть для записи файл сеанса «%s»: %s\n" +#: data/50-mutter-navigation.xml:135 +msgid "Move to workspace above" +msgstr "Переместить на рабочее место вверх" -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Произошла ошибка при записи файла сеанса «%s»: %s\n" +#: data/50-mutter-navigation.xml:138 +msgid "Move to workspace below" +msgstr "Переместить на рабочее место вниз" -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Произошла ошибка при закрытии файла сеанса «%s»: %s\n" +#: data/50-mutter-system.xml:6 +msgid "System" +msgstr "Система" -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Не удалось разобрать сохранённый файл сеанса: %s\n" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Показать командную строку" -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "Атрибут <muffin_session> обнаружен, но у нас уже есть ID сеанса" - -#: ../src/core/session.c:1198 -#: ../src/core/session.c:1273 -#: ../src/core/session.c:1305 -#: ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Атрибут %s элемента <%s> неизвестен" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Открыть обзор" -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "вложенный тег <window>" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Окна" -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "Элемент %s неизвестен" +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "Активировать меню окна" -#: ../src/core/session.c:1809 -msgid "These windows do not support "save current setup" and will have to be restarted manually next time you log in." -msgstr "Эти окна не поддерживают команду «Сохранить текущие настройки». При следующем входе в систему их придётся перезапустить вручную." +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Переключить полноэкранный режим" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Не удалось открыть журнал отладочной информации: %s\n" +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "Переключить состояние развёрнутости на весь экран" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Не удалось применить fdopen() к журналу отладочной информации %s: %s\n" +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "Развернуть окно на весь экран" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "Открыт журнал отладочной информации %s\n" +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Восстановить окно" -#: ../src/core/util.c:146 -#: ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "Metacity собран без поддержки режима подробных сообщений\n" +#: data/50-mutter-windows.xml:18 +msgid "Toggle shaded state" +msgstr "Переключить затенённое состояние" -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "Менеджер окон: " +#: data/50-mutter-windows.xml:20 +msgid "Close window" +msgstr "Закрыть окно" -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "Ошибка в менеджере окон: " +#: data/50-mutter-windows.xml:22 +msgid "Hide window" +msgstr "Скрыть окно" -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "Предупреждение менеджера окон: " +#: data/50-mutter-windows.xml:24 +msgid "Move window" +msgstr "Переместить окно" -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "Ошибка менеджера окон: " +#: data/50-mutter-windows.xml:26 +msgid "Resize window" +msgstr "Изменить размер окна" -#. first time through -#: ../src/core/window.c:7269 -#, c-format -msgid "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER window as specified in the ICCCM.\n" -msgstr "Окно %s установило на себя значение SM_CLIENT_ID вместо окна с значением WM_CLIENT_LEADER, как это определено в ICCCM.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7932 -#, c-format -msgid "Window %s sets an MWM hint indicating it isn't resizable, but sets min size %d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "Окно %s установило подсказку MWM, определяющую, что его размер не меняется, но установило минимальный размер %d × %d и максимальный размер %d × %d, что не имеет смысла.\n" +#: data/50-mutter-windows.xml:29 +msgid "Toggle window on all workspaces or one" +msgstr "Переключить окно на все рабочие места или на одно" -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "Приложение установило неправильное значение параметра _NET_WM_PID %lu\n" +#: data/50-mutter-windows.xml:31 +msgid "Raise window if covered, otherwise lower it" +msgstr "Поднять окно, если оно закрыто другими окнами, иначе — опустить его" -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (на %s)" +#: data/50-mutter-windows.xml:33 +msgid "Raise window above other windows" +msgstr "Поместить окно поверх всех окон" -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "Неверный параметр WM_TRANSIENT_FOR окна 0x%lx указан для %s.\n" +#: data/50-mutter-windows.xml:35 +msgid "Lower window below other windows" +msgstr "Поместить окно под другими окнами" -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "Из-за WM_TRANSIENT_FOR окна 0x%lx для %s произошло бы зацикливание.\n" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window vertically" +msgstr "Развернуть окно на весь экран вертикально" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"У окна 0x%lx есть свойство %s,\n" -"у которого должен быть тип %s, формат %d,\n" -"а на самом деле используется тип %s, формат %d, число элементов %d.\n" -"Похоже на ошибку в приложении, а не в менеджере окон.\n" -"Заголовок окна — «%s», класс — «%s», имя — «%s»\n" +#: data/50-mutter-windows.xml:39 +msgid "Maximize window horizontally" +msgstr "Развернуть окно на весь экран горизонтально" -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "Свойство %s для окна 0x%lx содержало недопустимые данные UTF-8\n" +#: data/50-mutter-windows.xml:43 +msgid "View split on left" +msgstr "Разделитель слева" -#: ../src/core/xprops.c:494 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "Свойство %s для окна 0x%lx содержало недопустимые данные UTF-8 для элемента %d в списке\n" +#: data/50-mutter-windows.xml:47 +msgid "View split on right" +msgstr "Разделитель справа" -#: ../src/muffin.desktop.in.h:1 -#: ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 +#: data/org.gnome.mutter.gschema.xml.in:7 msgid "Modifier to use for extended window management operations" -msgstr "Модификатор для использования дополнительных действий управления окнами" +msgstr "" +"Модификатор для использования дополнительных действий управления окнами" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 -msgid "This key will initiate the \"overlay\", which is a combination window overview and application launching system. The default is intended to be the \"Windows key\" on PC hardware. It's expected that this binding either the default or set to the empty string." -msgstr "Этот ключ инициирует перекрытие (обзор окон и система запуска приложений). Для обычных ПК используется клавиша «Windows». Ожидается, что значение этой привязки будет иметь значение по умолчанию или будет пустой строкой." +#: data/org.gnome.mutter.gschema.xml.in:8 +msgid "" +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." +msgstr "" +"Этот ключ инициирует перекрытие (обзор окон и система запуска приложений). " +"Для обычных ПК используется клавиша «Windows». Ожидается, что значение этой " +"привязки будет иметь значение по умолчанию или будет пустой строкой." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 +#: data/org.gnome.mutter.gschema.xml.in:20 msgid "Attach modal dialogs" msgstr "Прикреплять модальные диалоговые окна" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 -msgid "When true, instead of having independent titlebars, modal dialogs appear attached to the titlebar of the parent window and are moved together with the parent window." -msgstr "Если установлено, вместо независимых заголовков окон модальные диалоговые окна будут прикрепляться к заголовку родительского окна и перемещаться вместе с родительским окном." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -msgid "Live Hidden Windows" -msgstr "Существование скрытых окон" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 -msgid "Determines whether hidden windows (i.e., minimized windows and windows on other workspaces than the current one) should be kept alive." -msgstr "Определяет, должны ли существовать скрытые окна (например, минимизированные окна и окна, находящиеся на другом рабочем месте)." +#: data/org.gnome.mutter.gschema.xml.in:21 +msgid "" +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." +msgstr "" +"Если установлено, вместо независимых заголовков окон модальные диалоговые " +"окна будут прикрепляться к заголовку родительского окна и перемещаться " +"вместе с родительским окном." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 +#: data/org.gnome.mutter.gschema.xml.in:30 msgid "Enable edge tiling when dropping windows on screen edges" msgstr "Включить краевые фреймы при перемещении окон к границам экрана" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 -msgid "If enabled, dropping windows on vertical screen edges maximizes them vertically and resizes them horizontally to cover half of the available area. Dropping windows on the top screen edge maximizes them completely." -msgstr "Если включено, то перемещение окна к вертикальным границам экрана разворачивает окно по вертикали и изменяет горизонтальный размер окна, покрывая половину доступного места. Перемещение окна к верхней части экрана полностью разворачивает окно." +#: data/org.gnome.mutter.gschema.xml.in:31 +msgid "" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." +msgstr "" +"Если включено, то перемещение окна к вертикальным границам экрана " +"разворачивает окно по вертикали и изменяет горизонтальный размер окна, " +"покрывая половину доступного места. Перемещение окна к верхней части экрана " +"полностью разворачивает окно." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 +#: data/org.gnome.mutter.gschema.xml.in:40 msgid "Workspaces are managed dynamically" msgstr "Рабочие места управляются динамически" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 -msgid "Determines whether workspaces are managed dynamically or whether there's a static number of workspaces (determined by the num-workspaces key in org.cinnamon.desktop.wm.preferences)." -msgstr "Определяет, управляются ли рабочие места автоматически или количество рабочих место постоянно (количество задаётся ключом в org.cinnamon.desktop.wm.preferences)." +#: data/org.gnome.mutter.gschema.xml.in:41 +msgid "" +"Determines whether workspaces are managed dynamically or whether there’s a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." +msgstr "" +"Определяет, управляются ли рабочие места динамически или количество рабочих " +"мест постоянно (количество задаётся ключом в org.gnome.desktop.wm." +"preferences)." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 +#: data/org.gnome.mutter.gschema.xml.in:50 msgid "Workspaces only on primary" msgstr "Рабочие места только на главном окне" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 -msgid "Determines whether workspace switching should happen for windows on all monitors or only for windows on the primary monitor." -msgstr "Определяет, должно ли переключение рабочего места происходить для окон на всех мониторах или только для окон на главном мониторе." +#: data/org.gnome.mutter.gschema.xml.in:51 +msgid "" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." +msgstr "" +"Определяет, должно ли переключение рабочего места происходить для окон на " +"всех мониторах или только для окон на главном мониторе." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 +#: data/org.gnome.mutter.gschema.xml.in:59 msgid "No tab popup" msgstr "Без всплывающей табуляции" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 -msgid "Determines whether the use of popup and highlight frame should be disabled for window cycling." -msgstr "Определяет, нужно ли отключить использование всплывающей области для циклического переключения окон." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 -msgid "Draggable border width" -msgstr "Ширина рамки перетаскивания" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 -msgid "The amount of total draggable borders. If the theme's visible borders are not enough, invisible borders will be added to meet this value." -msgstr "Общая ширина рамок для перетаскивания. Если видимых рамок темы недостаточно, то до этого значения будут добавлены невидимые рамки." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:17 -msgid "Select window from tab popup" -msgstr "Выбор окна из всплывающей табуляции" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:18 -msgid "Cancel tab popup" -msgstr "Отменить всплывающую табуляцию" - -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "Применение: %s\n" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "_Свернуть" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "Развернуть на весь _экран" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "Восстановить _прежний размер" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "С_крутить в полоску" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "Рас_катать" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "Пере_местить" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "_Изменить размер" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "Переместить заголовок на _экран" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 -#: ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "_Закрепить на переднем плане" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "_Всегда на видимом рабочем месте" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "Т_олько на этом рабочем месте" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "Переместить на рабочее место в_лево" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "Переместить на рабочее место в_право" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "Переместить на рабочее место _вверх" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "Переместить на рабочее место в_низ" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "_Закрыть" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "Рабочее место %d%n" - -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "Рабочее место 1_0" - -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "Рабочее место %s%d" - -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "Переместить на другое _рабочее место" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" - -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d × %d" - -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "top" - -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "bottom" - -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "left" - -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "right" - -#: ../src/ui/theme.c:286 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "геометрия рамки не указывает размер «%s»" - -#: ../src/ui/theme.c:305 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "геометрия рамки не указывает размер «%s» для границы «%s»" - -#: ../src/ui/theme.c:342 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "Соотношение сторон кнопки %g недопустимо" - -#: ../src/ui/theme.c:354 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "Геометрия рамки не указывает размер кнопок" - -#: ../src/ui/theme.c:1067 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "У градиентов должно быть не меньше двух цветов" - -#: ../src/ui/theme.c:1219 -#, c-format -msgid "GTK custom color specification must have color name and fallback in parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" -msgstr "В пользовательской спецификации цвета GTK+ в скобках должно быть указано имя цвета и значение по умолчанию, например, gtk:custom(foo,bar); не удалось разобрать «%s»" - -#: ../src/ui/theme.c:1235 -#, c-format -msgid "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-_ are valid" -msgstr "Недопустимый символ «%c» в параметре color_name для gtk:custom; разрешены только A-Za-z0-9-_" - -#: ../src/ui/theme.c:1249 -#, c-format -msgid "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not fit the format" -msgstr "Формат Gtk:custom — «gtk:custom(color_name,fallback)»; «%s» не соответствует формату" - -#: ../src/ui/theme.c:1294 -#, c-format -msgid "GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "У спецификации цвета GTK+ в скобках должен быть указан режим, например, gtk:fg[NORMAL], где NORMAL — это режим; не удалось разобрать «%s»" - -#: ../src/ui/theme.c:1308 -#, c-format -msgid "GTK color specification must have a close bracket after the state, e.g. gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "У спецификации цвета GTK+ после указания режима должна быть закрывающая скобка, например, gtk:fg[NORMAL], где NORMAL — это режим; не удалось разобрать «%s»" - -#: ../src/ui/theme.c:1319 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "Не удалось распознать режим «%s» в спецификации цвета" - -#: ../src/ui/theme.c:1332 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "Не удалось распознать составную часть цвета «%s» в спецификации цвета" - -#: ../src/ui/theme.c:1361 -#, c-format -msgid "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the format" -msgstr "Формат определения смешанного цвета — «blend/bg_color/fg_color/alpha»; «%s» не соответствует формату" - -#: ../src/ui/theme.c:1372 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "Не удалось разобрать значение альфа-канала «%s» в смешанном цвете" - -#: ../src/ui/theme.c:1382 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "Значение альфа-канала «%s» в смешанном цвете не входит в диапазон между 0.0 и 1.0" - -#: ../src/ui/theme.c:1429 -#, c-format -msgid "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "Формат тени — «shade/base_color/factor»; «%s» не соответствует формату" - -#: ../src/ui/theme.c:1440 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "Не удалось разобрать составную часть тени «%s» в затенённом цвете" - -#: ../src/ui/theme.c:1450 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "Составная часть тени «%s» в затенённом цвете отрицательна" - -#: ../src/ui/theme.c:1479 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Не удалось разобрать цвет «%s»" - -#: ../src/ui/theme.c:1790 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "Выражение координаты содержит символ «%s», который нельзя использовать" +#: data/org.gnome.mutter.gschema.xml.in:60 +msgid "" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." +msgstr "" +"Определяет, нужно ли отключить использование всплывающей области для " +"циклического переключения окон." -#: ../src/ui/theme.c:1817 -#, c-format -msgid "Coordinate expression contains floating point number '%s' which could not be parsed" -msgstr "Выражение координаты содержит число с плавающей запятой «%s», которое не удалось разобрать" +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Отложить переключение фокуса до тех пор, пока не остановится указатель" -#: ../src/ui/theme.c:1831 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "Выражение координаты содержит целое число «%s», которое не удалось разобрать" +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" +"Если установлено в значение «true» и режим фокуса установлен в значение " +"«sloppy» или «mouse», тогда фокус не будет меняться при переходе к другому " +"окну до тех пор, пока не остановится указатель." -#: ../src/ui/theme.c:1953 -#, c-format -msgid "Coordinate expression contained unknown operator at the start of this text: \"%s\"" -msgstr "Выражение координаты содержит неизвестный оператор в начале следующего текста: «%s»" +#: data/org.gnome.mutter.gschema.xml.in:79 +msgid "Draggable border width" +msgstr "Ширина рамки перетаскивания" -#: ../src/ui/theme.c:2010 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "Выражение координаты пустое, или его не удалось распознать" +#: data/org.gnome.mutter.gschema.xml.in:80 +msgid "" +"The amount of total draggable borders. If the theme’s visible borders are " +"not enough, invisible borders will be added to meet this value." +msgstr "" +"Общая ширина рамок для перетаскивания. Если видимых рамок, используемых в " +"теме, недостаточно, то будут добавлены невидимые рамки до этого значения." -#: ../src/ui/theme.c:2121 -#: ../src/ui/theme.c:2131 -#: ../src/ui/theme.c:2165 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "Вычисление выражения координаты привело к делению на ноль" +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "Автоматически увеличивать размеры окна до размеров монитора" -#: ../src/ui/theme.c:2173 -#, c-format -msgid "Coordinate expression tries to use mod operator on a floating-point number" -msgstr "Выражение координаты пытается использовать оператор взятия остатка от деления для числа с плавающей запятой" +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" +"Если включено, новые окна будут автоматически увеличены до максимального " +"размера." -#: ../src/ui/theme.c:2229 -#, c-format -msgid "Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "В выражении координаты используется оператор «%s» там, где должен быть операнд" +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Размещать новые окна в центре" -#: ../src/ui/theme.c:2238 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "В выражении координаты используется операнд там, где должен быть оператор" +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" +"Если выбрано, то новые окна всегда будут помещаться в центр активного экрана " +"монитора." -#: ../src/ui/theme.c:2246 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "Выражение координаты заканчивается оператором, а не операндом" +#: data/org.gnome.mutter.gschema.xml.in:120 +msgid "Select window from tab popup" +msgstr "Выбор окна из всплывающей табуляции" -#: ../src/ui/theme.c:2256 -#, c-format -msgid "Coordinate expression has operator \"%c\" following operator \"%c\" with no operand in between" -msgstr "В выражении координаты за оператором «%c» следует оператор «%c», между ними нет операнда" +#: data/org.gnome.mutter.gschema.xml.in:125 +msgid "Cancel tab popup" +msgstr "Отменить всплывающую табуляцию" -#: ../src/ui/theme.c:2407 -#: ../src/ui/theme.c:2452 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "В выражении координаты неизвестная переменная или константа «%s»" +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Переключиться на виртуальный терминал 1" -#: ../src/ui/theme.c:2506 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "Произошло переполнение буфера обработчика координат." +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Переключиться на виртуальный терминал 2" -#: ../src/ui/theme.c:2535 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "В выражении координаты использованы закрывающие скобки, но нет соответствующих открывающих скобок" +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Переключиться на виртуальный терминал 3" -#: ../src/ui/theme.c:2599 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "В выражении координаты использованы открывающие скобки, но нет соответствующих закрывающих скобок" +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Переключиться на виртуальный терминал 4" -#: ../src/ui/theme.c:2610 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "В выражении координаты нет операторов и операндов" +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Переключиться на виртуальный терминал 5" -#: ../src/ui/theme.c:2822 -#: ../src/ui/theme.c:2842 -#: ../src/ui/theme.c:2862 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "В теме было выражение, которое вызвало ошибку: %s\n" +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Переключиться на виртуальный терминал 6" -#: ../src/ui/theme.c:4533 -#, c-format -msgid "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be specified for this frame style" -msgstr "для этого стиля рамки необходимо указать <button function=\"%s\" state=\"%s\" draw_ops=\"что-нибудь\"/>" +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Переключиться на виртуальный терминал 7" -#: ../src/ui/theme.c:5066 -#: ../src/ui/theme.c:5091 -#, c-format -msgid "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "Отсутствует <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"что-нибудь\"/>" +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Переключиться на виртуальный терминал 8" -#: ../src/ui/theme.c:5139 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Не удалось загрузить тему «%s»: %s\n" - -#: ../src/ui/theme.c:5275 -#: ../src/ui/theme.c:5282 -#: ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 -#: ../src/ui/theme.c:5303 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "Отсутствует элемент <%s> для темы «%s»" +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Переключиться на виртуальный терминал 9" -#: ../src/ui/theme.c:5311 -#, c-format -msgid "No frame style set for window type \"%s\" in theme \"%s\", add a <window type=\"%s\" style_set=\"whatever\"/> element" -msgstr "Нет стиля рамки для типа окна «%s» в теме «%s», добавьте элемент <window type=\"%s\" style_set=\"что-нибудь\"/>" +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Переключиться на виртуальный терминал 10" -#: ../src/ui/theme.c:5709 -#: ../src/ui/theme.c:5771 -#: ../src/ui/theme.c:5834 -#, c-format -msgid "User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "Константы, заданные пользователем, должны начинаться с заглавной буквы; «%s» не начинается с заглавной буквы" +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Переключиться на виртуальный терминал 11" -#: ../src/ui/theme.c:5717 -#: ../src/ui/theme.c:5779 -#: ../src/ui/theme.c:5842 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "Константа «%s» уже задана" +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Переключиться на виртуальный терминал 12" -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. #. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "Отсутствует атрибут «%s» для элемента <%s>" - -#: ../src/ui/theme-parser.c:265 -#: ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Строка %d, символ %d: %s" - -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "Атрибут «%s» дважды повторяется в одном и том же элементе <%s>" - -#: ../src/ui/theme-parser.c:503 -#: ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "Атрибут «%s» не может применяться в элементе <%s> в этом контексте" - -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "Не удалось разобрать «%s» как целое число" - -#: ../src/ui/theme-parser.c:603 -#: ../src/ui/theme-parser.c:658 +#: src/backends/meta-input-settings.c:1800 #, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "Не удалось распознать замыкающие символы «%s» в строке «%s»" +msgid "Mode Switch (Group %d)" +msgstr "Переключатель режима: группа %d" -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "Целое число %ld должно быть положительным" +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:1822 +msgid "Switch monitor" +msgstr "Переключить монитор" -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "Целое число %ld слишком большое, текущий максимум равен %d" +#: src/backends/meta-input-settings.c:1824 +msgid "Show on-screen help" +msgstr "Показать справку на экране" -#: ../src/ui/theme-parser.c:649 -#: ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "Не удалось разобрать «%s» как число с плавающей запятой" +#: src/backends/meta-monitor-manager.c:675 +msgid "Built-in display" +msgstr "Встроенный дисплей" -#: ../src/ui/theme-parser.c:680 -#: ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "Логические значения должны быть «true» или «false», а не «%s»" +#: src/backends/meta-monitor-manager.c:698 +msgid "Unknown" +msgstr "Неизвестный" -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "Угол должен быть от 0,0 до 360,0, а был %g\n" +#: src/backends/meta-monitor-manager.c:700 +msgid "Unknown Display" +msgstr "Неизвестный дисплей" -#: ../src/ui/theme-parser.c:798 +#. TRANSLATORS: this is a monitor vendor name, followed by a +#. * size in inches, like 'Dell 15"' +#. +#: src/backends/meta-monitor-manager.c:708 #, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "Альфа-канал должен быть от 0,0 (невидимость) до 1,0 (полная непрозрачность), а был %g\n" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme-parser.c:863 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:471 #, c-format -msgid "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium,large,x-large,xx-large)\n" -msgstr "Масштаб заголовка «%s» (возможные значения: xx-small, x-small, small, medium, large, x-large, xx-large) недопустим\n" +msgid "" +"Another compositing manager is already running on screen %i on display “%s”." +msgstr "На экране %i дисплея «%s» уже запущен другой композитный менеджер." -#: ../src/ui/theme-parser.c:1019 -#: ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 -#: ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "Имя «%s» элемента <%s> использовалось второй раз" +#: src/core/bell.c:194 +msgid "Bell event" +msgstr "Событие звонка" -#: ../src/ui/theme-parser.c:1031 -#: ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 +#. Translators: %s is a window title +#: src/core/delete.c:127 #, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "Родительский объект «%s» элемента <%s> не определён" +msgid "“%s” is not responding." +msgstr "«%s» не отвечает." -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "Геометрия «%s» объекта <%s> не определена" +#: src/core/delete.c:129 +msgid "Application is not responding." +msgstr "Приложение не отвечает." -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "В элементе <%s> должны быть определены либо геометрия, либо родительский объект, имеющий геометрию" +#: src/core/delete.c:134 +msgid "" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." +msgstr "Можно немного подождать или принудительно завершить работу приложения." -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "Необходимо задать фон, чтобы значение альфа-канала имело смысл" +#: src/core/delete.c:141 +msgid "_Force Quit" +msgstr "Завер_шить" -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Тип «%s» для элемента <%s> неизвестен" +#: src/core/delete.c:141 +msgid "_Wait" +msgstr "_Подождать" -#: ../src/ui/theme-parser.c:1275 +#: src/core/display.c:608 #, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "Параметр style_set «%s» для элемента <%s> неизвестен" +msgid "Failed to open X Window System display “%s”\n" +msgstr "Не удалось открыть дисплей «%s» системы X Window\n" -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "Типу окна «%s» уже был приписан набор стилей" - -#: ../src/ui/theme-parser.c:1313 -#: ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 -#: ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 -#: ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 -#: ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 -#: ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "Использование элемента <%s> под <%s> недопустимо" +#: src/core/main.c:189 +msgid "Disable connection to session manager" +msgstr "Запретить подключение к менеджеру сеансов" -#: ../src/ui/theme-parser.c:1427 -#: ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" for buttons" -msgstr "Невозможно одновременно задать параметры \"button_width\"/\"button_height\" и \"aspect_ratio\" для кнопок" +#: src/core/main.c:195 +msgid "Replace the running window manager" +msgstr "Заменить запущенный оконный менеджер" -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "Расстояние «%s» неизвестно" +#: src/core/main.c:201 +msgid "Specify session management ID" +msgstr "Указать идентификатор управления сеансом" -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "Соотношение сторон «%s» неизвестно" +#: src/core/main.c:206 +msgid "X Display to use" +msgstr "Используемый дисплей X" -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "Рамка «%s» неизвестна" +#: src/core/main.c:212 +msgid "Initialize session from savefile" +msgstr "Инициализировать сеанс из сохранённого файла" -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "Нет ни атрибута «start_angle», ни атрибута «from» для элемента <%s>" +#: src/core/main.c:218 +msgid "Make X calls synchronous" +msgstr "Сделать X-вызовы синхронными" -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "Нет ни атрибута «extent_angle», ни атрибута «to» для элемента <%s>" +#: src/core/main.c:225 +msgid "Run as a wayland compositor" +msgstr "Запустить в качестве композитора wayland" -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "Не удалось распознать значение «%s» для типа градиента" +#: src/core/main.c:231 +msgid "Run as a nested compositor" +msgstr "Запустить в качестве встроенного композитора" -#: ../src/ui/theme-parser.c:2193 -#: ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "Не удалось распознать тип заливки «%s» для элемента <%s> " +#: src/core/main.c:239 +msgid "Run as a full display server, rather than nested" +msgstr "Запустить в качестве полноэкранного сервера вместо встроенного" -#: ../src/ui/theme-parser.c:2360 -#: ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 +#: src/core/mutter.c:39 #, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "Не удалось распознать состояние «%s» для элемента <%s> " +msgid "" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" +msgstr "" +"mutter %s\n" +"Авторское право © 2001—%d Havoc Pennington, Red Hat, Inc. и другие\n" +"Это — свободное программное обеспечение; условия копирования указаны в " +"исходном тексте.\n" +"Распространяется без каких-либо гарантий, в том числе и БЕЗ гарантий " +"потребительской стоимости и пригодности для выполнения каких бы то ни было " +"определённых задач.\n" -#: ../src/ui/theme-parser.c:2370 -#: ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "Не удалось распознать тень «%s» для элемента <%s>" +#: src/core/mutter.c:53 +msgid "Print version" +msgstr "Вывести версию" -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "Не удалось распознать стрелку «%s» для элемента <%s>" +#: src/core/mutter.c:59 +msgid "Mutter plugin to use" +msgstr "Использовать модуль mutter" -#: ../src/ui/theme-parser.c:2694 -#: ../src/ui/theme-parser.c:2790 +#: src/core/prefs.c:1997 #, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "Параметр <draw_ops> с именем «%s» не задан" +msgid "Workspace %d" +msgstr "Рабочее место %d" -#: ../src/ui/theme-parser.c:2706 -#: ../src/ui/theme-parser.c:2802 +#: src/core/screen.c:580 #, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "Вставка сюда параметра draw_ops «%s» создаст циклическую ссылку" +msgid "" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." +msgstr "" +"Дисплей «%s» уже использует менеджер окон; попробуйте использовать параметр " +"--replace, чтобы заменить текущий менеджер окон." -#: ../src/ui/theme-parser.c:2917 +#: src/core/screen.c:665 #, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Неизвестная позиция «%s» для участка рамки" +msgid "Screen %d on display “%s” is invalid\n" +msgstr "Недопустимый экран %d дисплея «%s»\n" -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "У стиля рамки уже есть участок в позиции %s" +#: src/core/util.c:120 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter собран без поддержки режима подробных сообщений\n" -#: ../src/ui/theme-parser.c:2942 -#: ../src/ui/theme-parser.c:3019 +#: src/wayland/meta-wayland-tablet-pad.c:563 #, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "Не задан ни один параметр <draw_ops> с именем «%s»" +msgid "Mode Switch: Mode %d" +msgstr "Переключатель режима: режим %d" -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Неизвестная функция «%s» для кнопки" +#: src/x11/session.c:1815 +msgid "" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." +msgstr "" +"Эти окна не поддерживают команду «Сохранить текущую настройку». При " +"следующем входе в систему их придётся перезапустить вручную." -#: ../src/ui/theme-parser.c:2982 +#: src/x11/window-props.c:559 #, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "Функция кнопки «%s» не существует в этой версии (%d, необходима версия %d)" +msgid "%s (on %s)" +msgstr "%s (на %s)" -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Неизвестное состояние «%s» для кнопки" +#~ msgid "Failed to scan themes directory: %s\n" +#~ msgstr "Не удалось прочитать каталог тем: %s\n" -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "У стиля рамки уже есть кнопка для режима %s функции %s" +#~ msgid "" +#~ "Could not find a theme! Be sure %s exists and contains the usual themes.\n" +#~ msgstr "" +#~ "Не удалось найти тему! Убедитесь, что «%s» существует и содержит обычные " +#~ "темы.\n" -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "«%s» — недопустимое значение для атрибута «focus»" +#~ msgid "Screen %d on display \"%s\" already has a window manager\n" +#~ msgstr "У экрана %d дисплея «%s» уже есть менеджер окон\n" -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "«%s» — недопустимое значение для атрибута «state»" +#~ msgid "%d x %d" +#~ msgstr "%d × %d" -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "Стиль с именем «%s» не задан" +#~ msgid "top" +#~ msgstr "top" -#: ../src/ui/theme-parser.c:3113 -#: ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "«%s» — недопустимое значение для атрибута «resize»" +#~ msgid "bottom" +#~ msgstr "bottom" -#: ../src/ui/theme-parser.c:3147 -#, c-format -msgid "Should not have \"resize\" attribute on <%s> element for maximized/shaded states" -msgstr "Не следует использовать атрибут «resize» в элементе <%s> для развернутого и скрученного состояний" +#~ msgid "left" +#~ msgstr "left" -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "Не следует использовать атрибут «resize» в элементе <%s> для развёрнутых состояний" +#~ msgid "right" +#~ msgstr "right" -#: ../src/ui/theme-parser.c:3175 -#: ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "Для атрибутов state %s resize %s focus %s стиль уже задан" - -#: ../src/ui/theme-parser.c:3186 -#: ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 -#: ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 -#: ../src/ui/theme-parser.c:3255 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "Для атрибутов state %s focus %s стиль уже задан" +#~ msgid "frame geometry does not specify \"%s\" dimension" +#~ msgstr "геометрия рамки не указывает размер «%s»" -#: ../src/ui/theme-parser.c:3294 -msgid "Can't have a two draw_ops for a <piece> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "Невозможно использовать два параметра draw_ops для элемента <piece> (в теме указан атрибут draw_ops и элемент <draw_ops> или указаны два элемента)" +#~ msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" +#~ msgstr "геометрия рамки не указывает размер «%s» для границы «%s»" -#: ../src/ui/theme-parser.c:3332 -msgid "Can't have a two draw_ops for a <button> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "Невозможно использовать два параметра draw_ops для элемента <button> (в теме указан атрибут draw_ops и элемент <draw_ops> или указаны два элемента)" +#~ msgid "Button aspect ratio %g is not reasonable" +#~ msgstr "Соотношение сторон кнопки %g недопустимо" -#: ../src/ui/theme-parser.c:3370 -msgid "Can't have a two draw_ops for a <menu_icon> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "Невозможно использовать два параметра draw_ops для элемента <menu_icon> (в теме указан атрибут draw_ops и элемент <draw_ops> или указаны два элемента)" +#~ msgid "Frame geometry does not specify size of buttons" +#~ msgstr "Геометрия рамки не указывает размер кнопок" -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "Неверная спецификация версии «%s»" +#~ msgid "Gradients should have at least two colors" +#~ msgstr "У градиентов должно быть не меньше двух цветов" -#: ../src/ui/theme-parser.c:3507 -msgid "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-theme-2.xml" -msgstr "Атрибут «version» не может использоваться в metacity-theme-1.xml или metacity-theme-2.xml" +#~ msgid "" +#~ "GTK custom color specification must have color name and fallback in " +#~ "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" +#~ msgstr "" +#~ "В пользовательской спецификации цвета GTK+ в скобках должно быть указано " +#~ "имя цвета и значение по умолчанию, например, gtk:custom(foo,bar); не " +#~ "удалось разобрать «%s»" -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "Тема требует версию %s, но последняя поддерживаемая версия — %d.%d" +#~ msgid "" +#~ "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-" +#~ "z0-9-_ are valid" +#~ msgstr "" +#~ "Недопустимый символ «%c» в параметре color_name для gtk:custom; разрешены " +#~ "только A-Za-z0-9-_" -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "Элемент верхнего уровня в теме должен быть <metacity_theme>, а не <%s>" +#~ msgid "" +#~ "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " +#~ "fit the format" +#~ msgstr "" +#~ "Формат Gtk:custom — «gtk:custom(color_name,fallback)»; «%s» не " +#~ "соответствует формату" -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "Element <%s> is not allowed inside a name/author/date/description element" -msgstr "Использование элемента <%s> внутри элементов name/author/date/description недопустимо" +#~ msgid "" +#~ "GTK color specification must have the state in brackets, e.g. gtk:" +#~ "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "У спецификации цвета GTK+ в скобках должен быть указан режим, например, " +#~ "gtk:fg[NORMAL], где NORMAL — это режим; не удалось разобрать «%s»" -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "Использование элемента <%s> внутри элемента <constant> недопустимо" +#~ msgid "" +#~ "GTK color specification must have a close bracket after the state, e.g. " +#~ "gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "У спецификации цвета GTK+ после указания режима должна быть закрывающая " +#~ "скобка, например, gtk:fg[NORMAL], где NORMAL — это режим; не удалось " +#~ "разобрать «%s»" -#: ../src/ui/theme-parser.c:3599 -#, c-format -msgid "Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "Использование элемента <%s> внутри элементов distance/border/aspect_ratio недопустимо" +#~ msgid "Did not understand state \"%s\" in color specification" +#~ msgstr "Не удалось распознать режим «%s» в спецификации цвета" -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "Использование элемента <%s> внутри элемента draw operation недопустимо" +#~ msgid "Did not understand color component \"%s\" in color specification" +#~ msgstr "" +#~ "Не удалось распознать составную часть цвета «%s» в спецификации цвета" -#: ../src/ui/theme-parser.c:3631 -#: ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 -#: ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "Использование элемента <%s> внутри элемента <%s> недопустимо" +#~ msgid "" +#~ "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit " +#~ "the format" +#~ msgstr "" +#~ "Формат определения смешанного цвета — «blend/bg_color/fg_color/alpha»; " +#~ "«%s» не соответствует формату" -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "Не задан параметр draw_ops для участка рамки" +#~ msgid "Could not parse alpha value \"%s\" in blended color" +#~ msgstr "Не удалось разобрать значение альфа-канала «%s» в смешанном цвете" -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "Не задан параметр draw_ops для кнопки" +#~ msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" +#~ msgstr "" +#~ "Значение альфа-канала «%s» в смешанном цвете не входит в диапазон между " +#~ "0.0 и 1.0" -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "Использование текста внутри элемента <%s> недопустимо" - -#: ../src/ui/theme-parser.c:4026 -#: ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 -#: ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "<%s> указан для этой темы дважды" +#~ msgid "" +#~ "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the " +#~ "format" +#~ msgstr "" +#~ "Формат тени — «shade/base_color/factor»; «%s» не соответствует формату" -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Не удалось найти допустимый файл для темы %s\n" +#~ msgid "Could not parse shade factor \"%s\" in shaded color" +#~ msgstr "Не удалось разобрать составную часть тени «%s» в затенённом цвете" -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "_Окна" +#~ msgid "Shade factor \"%s\" in shaded color is negative" +#~ msgstr "Составная часть тени «%s» в затенённом цвете отрицательна" -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "_Диалоговое окно" +#~ msgid "Could not parse color \"%s\"" +#~ msgstr "Не удалось разобрать цвет «%s»" -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "_Модальное диалоговое окно" +#~ msgid "Coordinate expression contains character '%s' which is not allowed" +#~ msgstr "" +#~ "Выражение координаты содержит символ «%s», который нельзя использовать" -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "_Утилита" +#~ msgid "" +#~ "Coordinate expression contains floating point number '%s' which could not " +#~ "be parsed" +#~ msgstr "" +#~ "Выражение координаты содержит число с плавающей запятой «%s», которое не " +#~ "удалось разобрать" -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "_Экран-заставка" +#~ msgid "" +#~ "Coordinate expression contains integer '%s' which could not be parsed" +#~ msgstr "" +#~ "Выражение координаты содержит целое число «%s», которое не удалось " +#~ "разобрать" -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "_Верхний док" +#~ msgid "" +#~ "Coordinate expression contained unknown operator at the start of this " +#~ "text: \"%s\"" +#~ msgstr "" +#~ "Выражение координаты содержит неизвестный оператор в начале следующего " +#~ "текста: «%s»" -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "_Нижний док" +#~ msgid "Coordinate expression was empty or not understood" +#~ msgstr "Выражение координаты пустое, или его не удалось распознать" -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "_Левый док" +#~ msgid "Coordinate expression results in division by zero" +#~ msgstr "Вычисление выражения координаты привело к делению на ноль" -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "_Правый док" +#~ msgid "" +#~ "Coordinate expression tries to use mod operator on a floating-point number" +#~ msgstr "" +#~ "Выражение координаты пытается использовать оператор взятия остатка от " +#~ "деления для числа с плавающей запятой" -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "В_се доки" +#~ msgid "" +#~ "Coordinate expression has an operator \"%s\" where an operand was expected" +#~ msgstr "" +#~ "В выражении координаты используется оператор «%s» там, где должен быть " +#~ "операнд" -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "_Рабочий стол" +#~ msgid "Coordinate expression had an operand where an operator was expected" +#~ msgstr "" +#~ "В выражении координаты используется операнд там, где должен быть оператор" -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "Открыть другое окно" +#~ msgid "Coordinate expression ended with an operator instead of an operand" +#~ msgstr "Выражение координаты заканчивается оператором, а не операндом" -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "Это демонстрационная кнопка со значком «открыть»" +#~ msgid "" +#~ "Coordinate expression has operator \"%c\" following operator \"%c\" with " +#~ "no operand in between" +#~ msgstr "" +#~ "В выражении координаты за оператором «%c» следует оператор «%c», между " +#~ "ними нет операнда" -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "Это демонстрационная кнопка со значком «выйти»" +#~ msgid "Coordinate expression had unknown variable or constant \"%s\"" +#~ msgstr "В выражении координаты неизвестная переменная или константа «%s»" -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "Это образец сообщения в образце диалога" +#~ msgid "Coordinate expression parser overflowed its buffer." +#~ msgstr "Произошло переполнение буфера обработчика координат." -#: ../src/ui/theme-viewer.c:328 -#, c-format -msgid "Fake menu item %d\n" -msgstr "Фальшивый элемент меню %d\n" +#~ msgid "" +#~ "Coordinate expression had a close parenthesis with no open parenthesis" +#~ msgstr "" +#~ "В выражении координаты использованы закрывающие скобки, но нет " +#~ "соответствующих открывающих скобок" -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "Окно только с рамкой" +#~ msgid "" +#~ "Coordinate expression had an open parenthesis with no close parenthesis" +#~ msgstr "" +#~ "В выражении координаты использованы открывающие скобки, но нет " +#~ "соответствующих закрывающих скобок" -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "Панель" +#~ msgid "Coordinate expression doesn't seem to have any operators or operands" +#~ msgstr "В выражении координаты нет операторов и операндов" -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "Обычное окно приложения" +#~ msgid "Theme contained an expression that resulted in an error: %s\n" +#~ msgstr "В теме было выражение, которое вызвало ошибку: %s\n" -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "Диалог" +#~ msgid "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " +#~ "specified for this frame style" +#~ msgstr "" +#~ "для этого стиля рамки необходимо указать <button function=\"%s\" state=" +#~ "\"%s\" draw_ops=\"что-нибудь\"/>" -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "Модальный диалог" +#~ msgid "" +#~ "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/" +#~ ">" +#~ msgstr "" +#~ "Отсутствует <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"что-" +#~ "нибудь\"/>" -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "Вспомогательная палитра" +#~ msgid "Failed to load theme \"%s\": %s\n" +#~ msgstr "Не удалось загрузить тему «%s»: %s\n" -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "Отделённое меню" +#~ msgid "No <%s> set for theme \"%s\"" +#~ msgstr "Отсутствует элемент <%s> для темы «%s»" -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "Рамка" +#~ msgid "" +#~ "No frame style set for window type \"%s\" in theme \"%s\", add a <window " +#~ "type=\"%s\" style_set=\"whatever\"/> element" +#~ msgstr "" +#~ "Нет стиля рамки для типа окна «%s» в теме «%s», добавьте элемент <window " +#~ "type=\"%s\" style_set=\"что-нибудь\"/>" -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "Прикреплённый модальный диалог" +#~ msgid "" +#~ "User-defined constants must begin with a capital letter; \"%s\" does not" +#~ msgstr "" +#~ "Константы, заданные пользователем, должны начинаться с заглавной буквы; " +#~ "«%s» не начинается с заглавной буквы" -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "Проверка размещения кнопок %d" +#~ msgid "Constant \"%s\" has already been defined" +#~ msgstr "Константа «%s» уже задана" -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g мс для рисования одной рамки окна" +#~ msgid "No \"%s\" attribute on element <%s>" +#~ msgstr "Отсутствует атрибут «%s» для элемента <%s>" -#: ../src/ui/theme-viewer.c:813 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Применение: metacity-theme-viewer [ИМЯТЕМЫ]\n" +#~ msgid "Line %d character %d: %s" +#~ msgstr "Строка %d, символ %d: %s" -#: ../src/ui/theme-viewer.c:820 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "Ошибка загрузки темы: %s\n" +#~ msgid "Attribute \"%s\" repeated twice on the same <%s> element" +#~ msgstr "Атрибут «%s» дважды повторяется в одном и том же элементе <%s>" -#: ../src/ui/theme-viewer.c:826 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "Тема «%s» загружена за %g секунд\n" +#~ msgid "Attribute \"%s\" is invalid on <%s> element in this context" +#~ msgstr "Атрибут «%s» не может применяться в элементе <%s> в этом контексте" -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "Обычный текст заголовка" +#~ msgid "Could not parse \"%s\" as an integer" +#~ msgstr "Не удалось разобрать «%s» как целое число" -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "Маленький шрифт заголовка" +#~ msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +#~ msgstr "Не удалось распознать замыкающие символы «%s» в строке «%s»" -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "Большой шрифт заголовка" +#~ msgid "Integer %ld must be positive" +#~ msgstr "Целое число %ld должно быть положительным" -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "Расположение кнопок" +#~ msgid "Integer %ld is too large, current max is %d" +#~ msgstr "Целое число %ld слишком большое, текущий максимум равен %d" -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "Рейтинг производительности" +#~ msgid "Could not parse \"%s\" as a floating point number" +#~ msgstr "Не удалось разобрать «%s» как число с плавающей запятой" -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "Тут будет заголовок окна" +#~ msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" +#~ msgstr "Логические значения должны быть «true» или «false», а не «%s»" -#: ../src/ui/theme-viewer.c:1047 -#, c-format -msgid "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g seconds wall clock time including X server resources (%g milliseconds per frame)\n" -msgstr "Отрисовано %d кадров за %g секунд клиентского времени (%g миллисекунд на кадр) и %g секунд календарного времени, включая ресурсы X-сервера (%g миллисекунд на кадр)\n" +#~ msgid "Angle must be between 0.0 and 360.0, was %g\n" +#~ msgstr "Угол должен быть от 0,0 до 360,0, а был %g\n" -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "проверка выражения позиции вернула TRUE, но установила ошибку" +#~ msgid "" +#~ "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" +#~ msgstr "" +#~ "Альфа-канал должен быть от 0,0 (невидимость) до 1,0 (полная " +#~ "непрозрачность), а был %g\n" -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "проверка выражения позиции вернула FALSE, но не установила ошибку" +#~ msgid "" +#~ "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," +#~ "large,x-large,xx-large)\n" +#~ msgstr "" +#~ "Масштаб заголовка «%s» (возможные значения: xx-small, x-small, small, " +#~ "medium, large, x-large, xx-large) недопустим\n" -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "Ожидалась ошибка, но ни одна не произошла" +#~ msgid "<%s> name \"%s\" used a second time" +#~ msgstr "Имя «%s» элемента <%s> использовалось второй раз" -#: ../src/ui/theme-viewer.c:1274 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "Ожидалась ошибка %d, но произошла ошибка %d" +#~ msgid "<%s> parent \"%s\" has not been defined" +#~ msgstr "Родительский объект «%s» элемента <%s> не определён" -#: ../src/ui/theme-viewer.c:1280 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "Ошибка не ожидалась, но произошла: %s" +#~ msgid "<%s> geometry \"%s\" has not been defined" +#~ msgstr "Геометрия «%s» объекта <%s> не определена" -#: ../src/ui/theme-viewer.c:1284 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "значение x было %d, а ожидалось %d" +#~ msgid "<%s> must specify either a geometry or a parent that has a geometry" +#~ msgstr "" +#~ "В элементе <%s> должны быть определены либо геометрия, либо родительский " +#~ "объект, имеющий геометрию" -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "значение y было %d, а ожидалось %d" +#~ msgid "You must specify a background for an alpha value to be meaningful" +#~ msgstr "Необходимо задать фон, чтобы значение альфа-канала имело смысл" -#: ../src/ui/theme-viewer.c:1352 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "%d координатных выражений разобрано за %g секунд (в среднем %g c)\n" +#~ msgid "Unknown type \"%s\" on <%s> element" +#~ msgstr "Тип «%s» для элемента <%s> неизвестен" -#~ msgid "Close Window" -#~ msgstr "Закрыть окно" +#~ msgid "Unknown style_set \"%s\" on <%s> element" +#~ msgstr "Параметр style_set «%s» для элемента <%s> неизвестен" -#~ msgid "Window Menu" -#~ msgstr "Меню окна" +#~ msgid "Window type \"%s\" has already been assigned a style set" +#~ msgstr "Типу окна «%s» уже был приписан набор стилей" -#~ msgid "Minimize Window" -#~ msgstr "Свернуть окно" +#~ msgid "Element <%s> is not allowed below <%s>" +#~ msgstr "Использование элемента <%s> под <%s> недопустимо" -#~ msgid "Maximize Window" -#~ msgstr "Развернуть окно на весь экран" +#~ msgid "" +#~ "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio" +#~ "\" for buttons" +#~ msgstr "" +#~ "Невозможно одновременно задать параметры \"button_width\"/\"button_height" +#~ "\" и \"aspect_ratio\" для кнопок" -#~ msgid "Restore Window" -#~ msgstr "Восстановить окно" +#~ msgid "Distance \"%s\" is unknown" +#~ msgstr "Расстояние «%s» неизвестно" -#~ msgid "Roll Up Window" -#~ msgstr "Скрутить окно в полоску" +#~ msgid "Aspect ratio \"%s\" is unknown" +#~ msgstr "Соотношение сторон «%s» неизвестно" -#~ msgid "Unroll Window" -#~ msgstr "Раскатать окно" +#~ msgid "Border \"%s\" is unknown" +#~ msgstr "Рамка «%s» неизвестна" -#~ msgid "Keep Window On Top" -#~ msgstr "Сохранять окно на переднем плане" +#~ msgid "No \"start_angle\" or \"from\" attribute on element <%s>" +#~ msgstr "Нет ни атрибута «start_angle», ни атрибута «from» для элемента <%s>" -#~ msgid "Remove Window From Top" -#~ msgstr "Убрать с переднего плана" +#~ msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" +#~ msgstr "Нет ни атрибута «extent_angle», ни атрибута «to» для элемента <%s>" -#~ msgid "Always On Visible Workspace" -#~ msgstr "Всегда на видимом рабочем месте" +#~ msgid "Did not understand value \"%s\" for type of gradient" +#~ msgstr "Не удалось распознать значение «%s» для типа градиента" -#~ msgid "Put Window On Only One Workspace" -#~ msgstr "Помещать только на одно рабочее место" +#~ msgid "Did not understand fill type \"%s\" for <%s> element" +#~ msgstr "Не удалось распознать тип заливки «%s» для элемента <%s> " -#~ msgid "Switch to workspace 1" -#~ msgstr "Переключиться на рабочее место 1" +#~ msgid "Did not understand state \"%s\" for <%s> element" +#~ msgstr "Не удалось распознать состояние «%s» для элемента <%s> " -#~ msgid "Switch to workspace 2" -#~ msgstr "Переключиться на рабочее место 2" +#~ msgid "Did not understand shadow \"%s\" for <%s> element" +#~ msgstr "Не удалось распознать тень «%s» для элемента <%s>" -#~ msgid "Switch to workspace 3" -#~ msgstr "Переключиться на рабочее место 3" +#~ msgid "Did not understand arrow \"%s\" for <%s> element" +#~ msgstr "Не удалось распознать стрелку «%s» для элемента <%s>" -#~ msgid "Switch to workspace 4" -#~ msgstr "Переключиться на рабочее место 4" +#~ msgid "No <draw_ops> called \"%s\" has been defined" +#~ msgstr "Параметр <draw_ops> с именем «%s» не задан" -#~ msgid "Switch to workspace 5" -#~ msgstr "Переключиться на рабочее место 5" +#~ msgid "Including draw_ops \"%s\" here would create a circular reference" +#~ msgstr "Вставка сюда параметра draw_ops «%s» создаст циклическую ссылку" -#~ msgid "Switch to workspace 6" -#~ msgstr "Переключиться на рабочее место 6" +#~ msgid "Unknown position \"%s\" for frame piece" +#~ msgstr "Неизвестная позиция «%s» для участка рамки" -#~ msgid "Switch to workspace 7" -#~ msgstr "Переключиться на рабочее место 7" +#~ msgid "Frame style already has a piece at position %s" +#~ msgstr "У стиля рамки уже есть участок в позиции %s" -#~ msgid "Switch to workspace 8" -#~ msgstr "Переключиться на рабочее место 8" +#~ msgid "No <draw_ops> with the name \"%s\" has been defined" +#~ msgstr "Не задан ни один параметр <draw_ops> с именем «%s»" -#~ msgid "Switch to workspace 9" -#~ msgstr "Переключиться на рабочее место 9" +#~ msgid "Unknown function \"%s\" for button" +#~ msgstr "Неизвестная функция «%s» для кнопки" -#~ msgid "Switch to workspace 10" -#~ msgstr "Переключиться на рабочее место 10" +#~ msgid "Button function \"%s\" does not exist in this version (%d, need %d)" +#~ msgstr "" +#~ "Функция кнопки «%s» не существует в этой версии (%d, необходима версия %d)" -#~ msgid "Switch to workspace 11" -#~ msgstr "Переключиться на рабочее место 11" +#~ msgid "Unknown state \"%s\" for button" +#~ msgstr "Неизвестное состояние «%s» для кнопки" -#~ msgid "Switch to workspace 12" -#~ msgstr "Переключиться на рабочее место 12" +#~ msgid "Frame style already has a button for function %s state %s" +#~ msgstr "У стиля рамки уже есть кнопка для режима %s функции %s" -#~ msgid "Switch to workspace on the left of the current workspace" -#~ msgstr "Переключиться на рабочее место слева от текущего" +#~ msgid "\"%s\" is not a valid value for focus attribute" +#~ msgstr "«%s» — недопустимое значение для атрибута «focus»" -#~ msgid "Switch to workspace on the right of the current workspace" -#~ msgstr "Переключиться на рабочее место справа от текущего" +#~ msgid "\"%s\" is not a valid value for state attribute" +#~ msgstr "«%s» — недопустимое значение для атрибута «state»" -#~ msgid "Switch to workspace above the current workspace" -#~ msgstr "Переключиться на рабочее место над текущим" +#~ msgid "A style called \"%s\" has not been defined" +#~ msgstr "Стиль с именем «%s» не задан" -#~ msgid "Switch to workspace below the current workspace" -#~ msgstr "Переключиться на рабочее место под текущим" +#~ msgid "\"%s\" is not a valid value for resize attribute" +#~ msgstr "«%s» — недопустимое значение для атрибута «resize»" -#~ msgid "Move between windows of an application, using a popup window" -#~ msgstr "Переключиться между окнами приложения через всплывающее окно" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized/shaded " +#~ "states" +#~ msgstr "" +#~ "Не следует использовать атрибут «resize» в элементе <%s> для развернутого " +#~ "и скрученного состояний" #~ msgid "" -#~ "Move backward between windows of an application, using a popup window" +#~ "Should not have \"resize\" attribute on <%s> element for maximized states" #~ msgstr "" -#~ "Переключиться в обратном порядке между окнами приложения через " -#~ "всплывающее окно" +#~ "Не следует использовать атрибут «resize» в элементе <%s> для развёрнутых " +#~ "состояний" -#~ msgid "Move between windows, using a popup window" -#~ msgstr "Переключиться между окнами через всплывающее окно" +#~ msgid "Style has already been specified for state %s resize %s focus %s" +#~ msgstr "Для атрибутов state %s resize %s focus %s стиль уже задан" -#~ msgid "Move backward between windows, using a popup window" -#~ msgstr "" -#~ "Переключиться в обратном порядке между окнами с использованием " -#~ "всплывающего окна" +#~ msgid "Style has already been specified for state %s focus %s" +#~ msgstr "Для атрибутов state %s focus %s стиль уже задан" -#~ msgid "Move between panels and the desktop, using a popup window" +#~ msgid "" +#~ "Can't have a two draw_ops for a <piece> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" #~ msgstr "" -#~ "Переключиться между панелями и рабочим столом через всплывающее окно" +#~ "Невозможно использовать два параметра draw_ops для элемента <piece> (в " +#~ "теме указан атрибут draw_ops и элемент <draw_ops> или указаны два " +#~ "элемента)" -#~ msgid "Move backward between panels and the desktop, using a popup window" +#~ msgid "" +#~ "Can't have a two draw_ops for a <button> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" #~ msgstr "" -#~ "Переключиться в обратном порядке между панелями и рабочим столом через " -#~ "всплывающее окно" - -#~ msgid "Move between windows of an application immediately" -#~ msgstr "Переключиться между окнами приложения немедленно" - -#~ msgid "Move backward between windows of an application immediately" -#~ msgstr "Переключиться в обратном порядке между окнами приложения немедленно" - -#~ msgid "Move between windows immediately" -#~ msgstr "Переключиться между окнами немедленно" - -#~ msgid "Move backward between windows immediately" -#~ msgstr "Переключиться в обратном порядке между окнами немедленно" - -#~ msgid "Move between panels and the desktop immediately" -#~ msgstr "Переключиться между панелями и рабочим столом немедленно" +#~ "Невозможно использовать два параметра draw_ops для элемента <button> (в " +#~ "теме указан атрибут draw_ops и элемент <draw_ops> или указаны два " +#~ "элемента)" -#~ msgid "Move backward between panels and the desktop immediately" +#~ msgid "" +#~ "Can't have a two draw_ops for a <menu_icon> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" #~ msgstr "" -#~ "Переключиться в обратном порядке между панелями и рабочим столом " -#~ "немедленно" - -#~ msgid "Hide all normal windows and set focus to the desktop" -#~ msgstr "Скрыть все обычные окна и активировать рабочий стол" - -#~ msgid "Show the panel's main menu" -#~ msgstr "Вызвать главное меню панели" - -#~ msgid "Show the panel's \"Run Application\" dialog box" -#~ msgstr "Показать диалоговое окно панели «Выполнить программу»" - -#~ msgid "Start or stop recording the session" -#~ msgstr "Начать или остановить запись сеанса" - -#~ msgid "Take a screenshot" -#~ msgstr "Получить снимок экрана" - -#~ msgid "Take a screenshot of a window" -#~ msgstr "Получить снимок окна" - -#~ msgid "Run a terminal" -#~ msgstr "Открыть терминал" - -#~ msgid "Activate the window menu" -#~ msgstr "Активировать меню окна" - -#~ msgid "Toggle fullscreen mode" -#~ msgstr "Переключить полноэкранный режим" - -#~ msgid "Toggle maximization state" -#~ msgstr "Переключить состояние развёрнутости на весь экран" - -#~ msgid "Toggle whether a window will always be visible over other windows" -#~ msgstr "Будет ли окно всегда расположено надо другими окнами" - -#~ msgid "Maximize window" -#~ msgstr "Развернуть окно на весь экран" - -#~ msgid "Restore window" -#~ msgstr "Восстановить окно" - -#~ msgid "Toggle shaded state" -#~ msgstr "Переключить состояние скрученности в полоску" - -#~ msgid "Minimize window" -#~ msgstr "Свернуть окно" - -#~ msgid "Close window" -#~ msgstr "Закрыть окно" - -#~ msgid "Move window" -#~ msgstr "Переместить окно" - -#~ msgid "Resize window" -#~ msgstr "Изменить размер окна" - -#~ msgid "Toggle whether window is on all workspaces or just one" -#~ msgstr "Будет ли окно помещено на всех рабочих местах или только на одном" - -#~ msgid "Move window to workspace 1" -#~ msgstr "Переместить окно на рабочее место 1" - -#~ msgid "Move window to workspace 2" -#~ msgstr "Переместить окно на рабочее место 2" - -#~ msgid "Move window to workspace 3" -#~ msgstr "Переместить окно на рабочее место 3" - -#~ msgid "Move window to workspace 4" -#~ msgstr "Переместить окно на рабочее место 4" - -#~ msgid "Move window to workspace 5" -#~ msgstr "Переместить окно на рабочее место 5" - -#~ msgid "Move window to workspace 6" -#~ msgstr "Переместить окно на рабочее место 6" - -#~ msgid "Move window to workspace 7" -#~ msgstr "Переместить окно на рабочее место 7" - -#~ msgid "Move window to workspace 8" -#~ msgstr "Переместить окно на рабочее место 8" +#~ "Невозможно использовать два параметра draw_ops для элемента <menu_icon> " +#~ "(в теме указан атрибут draw_ops и элемент <draw_ops> или указаны два " +#~ "элемента)" -#~ msgid "Move window to workspace 9" -#~ msgstr "Переместить окно на рабочее место 9" +#~ msgid "Bad version specification '%s'" +#~ msgstr "Неверная спецификация версии «%s»" -#~ msgid "Move window to workspace 10" -#~ msgstr "Переместить окно на рабочее место 10" - -#~ msgid "Move window to workspace 11" -#~ msgstr "Переместить окно на рабочее место 11" - -#~ msgid "Move window to workspace 12" -#~ msgstr "Переместить окно на рабочее место 12" - -#~ msgid "Move window one workspace to the left" -#~ msgstr "Переместить окно на одно рабочее место влево" - -#~ msgid "Move window one workspace to the right" -#~ msgstr "Переместить окно на одно рабочее место вправо" - -#~ msgid "Move window one workspace up" -#~ msgstr "Переместить окно на одно рабочее место вверх" - -#~ msgid "Move window one workspace down" -#~ msgstr "Переместить окно на одно рабочее место вниз" - -#~ msgid "Raise window if it's covered by another window, otherwise lower it" +#~ msgid "" +#~ "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" +#~ "theme-2.xml" #~ msgstr "" -#~ "Поднять окно на передний план, если оно заслонено другими, иначе опустить " -#~ "его" - -#~ msgid "Raise window above other windows" -#~ msgstr "Поднять окно на передний план" - -#~ msgid "Lower window below other windows" -#~ msgstr "Поместить окно под другими окнами" - -#~ msgid "Maximize window vertically" -#~ msgstr "Развернуть окно на весь экран вертикально" - -#~ msgid "Maximize window horizontally" -#~ msgstr "Развернуть окно на весь экран горизонтально" - -#~ msgid "Move window to north-west (top left) corner" -#~ msgstr "Переместить окно в северо-западный (верхний левый) угол" - -#~ msgid "Move window to north-east (top right) corner" -#~ msgstr "Переместить окно в северо-восточный (верхний правый) угол" +#~ "Атрибут «version» не может использоваться в metacity-theme-1.xml или " +#~ "metacity-theme-2.xml" -#~ msgid "Move window to south-west (bottom left) corner" -#~ msgstr "Переместить окно в юго-западный (нижний левый) угол" - -#~ msgid "Move window to south-east (bottom right) corner" -#~ msgstr "Переместить окно в юго-восточный (нижний правый) угол" - -#~ msgid "Move window to north (top) side of screen" -#~ msgstr "Переместить окно к северной (верхней) стороне экрана" - -#~ msgid "Move window to south (bottom) side of screen" -#~ msgstr "Переместить окно к южной (нижней) стороне экрана" - -#~ msgid "Move window to east (right) side of screen" -#~ msgstr "Переместить окно к западной (правой) стороне экрана" - -#~ msgid "Move window to west (left) side of screen" -#~ msgstr "Переместить окно к восточной (левой) стороне экрана" +#~ msgid "" +#~ "Theme requires version %s but latest supported theme version is %d.%d" +#~ msgstr "Тема требует версию %s, но последняя поддерживаемая версия — %d.%d" -#~ msgid "Move window to center of screen" -#~ msgstr "Переместить окно в центр экрана" +#~ msgid "Outermost element in theme must be <metacity_theme> not <%s>" +#~ msgstr "" +#~ "Элемент верхнего уровня в теме должен быть <metacity_theme>, а не <%s>" #~ msgid "" -#~ "There was an error running <tt>%s</tt>:\n" -#~ "\n" -#~ "%s" +#~ "Element <%s> is not allowed inside a name/author/date/description element" #~ msgstr "" -#~ "Произошла ошибка при запуске программы <tt>%s</tt>:\n" -#~ "\n" -#~ "%s" +#~ "Использование элемента <%s> внутри элементов name/author/date/description " +#~ "недопустимо" -#~ msgid "No command %d has been defined.\n" -#~ msgstr "Команда %d не была определена.\n" +#~ msgid "Element <%s> is not allowed inside a <constant> element" +#~ msgstr "Использование элемента <%s> внутри элемента <constant> недопустимо" -#~ msgid "No terminal command has been defined.\n" -#~ msgstr "Команда терминала не была определена.\n" - -#~ msgid "GConf key '%s' is set to an invalid value\n" -#~ msgstr "Для ключа GConf «%s» установлено недопустимое значение\n" - -#~ msgid "%d stored in GConf key %s is out of range %d to %d\n" +#~ msgid "" +#~ "Element <%s> is not allowed inside a distance/border/aspect_ratio element" #~ msgstr "" -#~ "Значение %d ключа GConf «%s» не входит в диапазон значений от %d до %d\n" +#~ "Использование элемента <%s> внутри элементов distance/border/aspect_ratio " +#~ "недопустимо" -#~ msgid "GConf key \"%s\" is set to an invalid type\n" -#~ msgstr "Для ключа GConf «%s» выбран недопустимый тип\n" - -#~ msgid "GConf key %s is already in use and can't be used to override %s\n" +#~ msgid "Element <%s> is not allowed inside a draw operation element" #~ msgstr "" -#~ "Ключ %s GConf уже используется и не может использоваться для перезаписи %" -#~ "s\n" +#~ "Использование элемента <%s> внутри элемента draw operation недопустимо" -#~ msgid "Can't override GConf key, %s not found\n" -#~ msgstr "Не удалось переписать ключ GConf, %s не найден\n" +#~ msgid "Element <%s> is not allowed inside a <%s> element" +#~ msgstr "Использование элемента <%s> внутри элемента <%s> недопустимо" -#~ msgid "Error setting number of workspaces to %d: %s\n" -#~ msgstr "" -#~ "Произошла ошибка при установке количества рабочих мест равным %d: %s\n" +#~ msgid "No draw_ops provided for frame piece" +#~ msgstr "Не задан параметр draw_ops для участка рамки" + +#~ msgid "No draw_ops provided for button" +#~ msgstr "Не задан параметр draw_ops для кнопки" -#~ msgid "Error setting name for workspace %d to \"%s\": %s\n" -#~ msgstr "Произошла ошибка при установке имени рабочего места %d в «%s»: %s\n" +#~ msgid "No text is allowed inside element <%s>" +#~ msgstr "Использование текста внутри элемента <%s> недопустимо" -#~ msgid "Error setting live hidden windows status status: %s\n" -#~ msgstr "Ошибка установки состояния существования скрытых окон: %s\n" +#~ msgid "<%s> specified twice for this theme" +#~ msgstr "<%s> указан для этой темы дважды" -#~ msgid "Error setting no tab popup status: %s\n" -#~ msgstr "Ошибка установки состояния всплывающего окна вкладки: %s\n" +#~ msgid "Failed to find a valid file for theme %s\n" +#~ msgstr "Не удалось найти допустимый файл для темы %s\n" diff --git a/po/rw.po b/po/rw.po index 0b6b10b4e..f0395e34f 100644 --- a/po/rw.po +++ b/po/rw.po @@ -19,6 +19,7 @@ msgstr "" "PO-Revision-Date: 2005-03-28 19:35-0700\n" "Last-Translator: Steve Murphy <murf@e-tools.com>\n" "Language-Team: Kinyarwanda <translation-team-rw@lists.sourceforge.net>\n" +"Language: rw\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" diff --git a/po/si.po b/po/si.po index b3fa949be..aa343366b 100644 --- a/po/si.po +++ b/po/si.po @@ -11,6 +11,7 @@ msgstr "" "PO-Revision-Date: 2007-08-17 14:12+0530\n" "Last-Translator: Danishka Navin <snavin@redhat.com>\n" "Language-Team: Sinhala <en@li.org>\n" +"Language: si\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" diff --git a/po/sk.po b/po/sk.po index 3a647a501..d22e1a24c 100644 --- a/po/sk.po +++ b/po/sk.po @@ -1,3822 +1,1572 @@ -# Slovak translation for metacity. -# Copyright (C) 2001, 2002, 2003, 2005, 2007-2010 Free Software Foundation, Inc. -# This file is distributed under the same license as the metacity package. -# Stanislav Višňovský <visnovsky@nenya.ms.mff.cuni.cz>, 2001, 2002, 2003. +# Slovak translation for mutter. +# Copyright (C) 2001-2003, 2005, 2007-2010, 2013 Free Software Foundation, Inc. +# This file is distributed under the same license as the mutter package. +# Stanislav Višňovský <visnovsky@nenya.ms.mff.cuni.cz>, 2001-2003. # Stanislav Visnovsky <visnovsky@kde.org>, 2003. # Marcel Telka <marcel@telka.sk>, 2005. # Peter Tuharsky <tuharsky@misbb.sk>, 2007. -# Pavol Šimo <palo.simo@gmail.com>, 2007, 2008, 2009, 2010. +# Pavol Šimo <palo.simo@gmail.com>, 2007-2010. +# Ján Kyselica <kyselica.jan@gmail.com>, 2013. +# Pavol Klačanský <pavol@klacansky.com>, 2013. # msgid "" msgstr "" -"Project-Id-Version: metacity\n" -"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" -"product=metacity&component=general\n" -"POT-Creation-Date: 2010-03-06 00:21+0000\n" -"PO-Revision-Date: 2010-03-07 20:17+0100\n" -"Last-Translator: Pavol Šimo <palo.simo@gmail.com>\n" +"Project-Id-Version: mutter\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2020-03-30 20:11+0000\n" +"PO-Revision-Date: 2020-04-05 22:21+0200\n" +"Last-Translator: Dušan Kazik <prescott66@gmail.com>\n" "Language-Team: Slovak <gnome-sk-list@gnome.org>\n" +"Language: sk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 1 : (n>=2 && n<=4) ? 2 : 0;\n" +"X-Generator: Poedit 2.3\n" -#: ../src/50-metacity-desktop-key.xml.in.h:1 -msgid "Desktop" -msgstr "Pracovná plocha" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Navigácia" -#: ../src/50-metacity-key.xml.in.h:1 -msgid "Window Management" -msgstr "Správca okien" - -#: ../src/core/bell.c:294 -msgid "Bell event" -msgstr "Udalosť zvončeka" - -#: ../src/core/core.c:206 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Neznáma požiadavka na informácie o okne: %d" - -#. Translators: %s is a window title -#: ../src/core/delete.c:96 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> neodpovedá." - -#: ../src/core/delete.c:101 -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "" -"Môžete chvíľu počkať na pokračovanie aplikácie, alebo ju môžete ukončiť." - -#: ../src/core/delete.c:110 -msgid "_Wait" -msgstr "_Počkať" - -#: ../src/core/delete.c:110 -msgid "_Force Quit" -msgstr "_Vynútiť ukončenie" - -#: ../src/core/delete.c:208 -#, c-format -msgid "Failed to get hostname: %s\n" -msgstr "Nepodarilo sa získať názov hostiteľa: %s\n" - -#: ../src/core/display.c:258 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "Rozšírenie %s chýba a je potrebné pre kompozitné prostredie" - -#: ../src/core/display.c:336 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Nepodarilo sa otvoriť displej X Window System '%s'\n" - -#: ../src/core/errors.c:272 -#, c-format -msgid "" -"Lost connection to the display '%s';\n" -"most likely the X server was shut down or you killed/destroyed\n" -"the window manager.\n" -msgstr "" -"Stratilo sa spojenie s displejom '%s'.\n" -"Asi sa X server vypol alebo ste ukončili/zničili\n" -"správcu okien.\n" - -#: ../src/core/errors.c:279 -#, c-format -msgid "Fatal IO error %d (%s) on display '%s'.\n" -msgstr "Kritická chyba V/V %d (%s) na displeji '%s'\n" - -#: ../src/core/keybindings.c:680 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "" -"Iný program už používa kláves %s s modifikátormi %x ako klávesovú skratku.\n" - -#. Displayed when a keybinding which is -#. * supposed to launch a program fails. -#. -#: ../src/core/keybindings.c:2294 -#, c-format -msgid "" -"There was an error running <tt>%s</tt>:\n" -"\n" -"%s" -msgstr "" -"Pri spustení <tt>%s</tt> nastala chyba:\n" -"\n" -"%s" - -#: ../src/core/keybindings.c:2383 -#, c-format -msgid "No command %d has been defined.\n" -msgstr "Nedefinovaný príkaz %d.\n" - -#: ../src/core/keybindings.c:3337 -#, c-format -msgid "No terminal command has been defined.\n" -msgstr "Nebol definovaný žiadny terminálový príkaz.\n" - -#: ../src/core/main.c:131 -#, c-format -msgid "" -"metacity %s\n" -"Copyright (C) 2001-%s Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" -"metacity %s\n" -"Autorské práva (C) 2001-%s Havoc Pennington, Red Hat, Inc., a ostatní\n" -"Toto je slobodný softvér; pozrite podmienky kopírovania v zdrojových " -"kódoch.\n" -"Záruka sa NEPOSKYTUJE; ani na PREDAJNOSŤ alebo VHODNOSŤ PRE URČITÝ ÚČEL.\n" - -#: ../src/core/main.c:269 -msgid "Disable connection to session manager" -msgstr "Zakázať spojenia na správcu relácií" - -#: ../src/core/main.c:275 -msgid "Replace the running window manager with Metacity" -msgstr "Nahradiť bežiaceho správcu okien správcom Metacity" - -#: ../src/core/main.c:281 -msgid "Specify session management ID" -msgstr "Zadať ID správy relácií" - -#: ../src/core/main.c:286 -msgid "X Display to use" -msgstr "X displej, ktorý bude použitý" - -#: ../src/core/main.c:292 -msgid "Initialize session from savefile" -msgstr "Inicializovať reláciu z uloženého súboru" - -#: ../src/core/main.c:298 -msgid "Print version" -msgstr "Vypísať verziu" - -#: ../src/core/main.c:304 -msgid "Make X calls synchronous" -msgstr "Používať synchrónne volania X" - -#: ../src/core/main.c:310 -msgid "Turn compositing on" -msgstr "Zapnúť kompozíciu" - -#: ../src/core/main.c:316 -msgid "Turn compositing off" -msgstr "Vypnúť kompozíciu" - -#: ../src/core/main.c:322 -msgid "" -"Don't make fullscreen windows that are maximized and have no decorations" -msgstr "" -"Nevytvárať celoobrazovkové okná, ktoré sú maximalizované a bez dekorácií" - -#: ../src/core/main.c:528 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Nepodarilo sa prehľadať adresár s témami: %s\n" - -#: ../src/core/main.c:544 -#, c-format -msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "" -"Nepodarilo sa nájsť tému. Overte, že %s existuje a obsahuje obvyklé témy.\n" - -#: ../src/core/main.c:603 -#, c-format -msgid "Failed to restart: %s\n" -msgstr "Nepodarilo znovu spustiť: %s\n" - -#. -#. * We found it, but it was invalid. Complain. -#. * -#. * FIXME: This replicates the original behaviour, but in the future -#. * we might consider reverting invalid keys to their original values. -#. * (We know the old value, so we can look up a suitable string in -#. * the symtab.) -#. * -#. * (Empty comment follows so the translators don't see this.) -#. -#. -#: ../src/core/prefs.c:508 ../src/core/prefs.c:663 -#, c-format -msgid "GConf key '%s' is set to an invalid value\n" -msgstr "GConf kľúč '%s' má nastavenú neplatnú hodnotu\n" - -#: ../src/core/prefs.c:589 ../src/core/prefs.c:832 -#, c-format -msgid "%d stored in GConf key %s is out of range %d to %d\n" -msgstr "Hodnota %d uložená v GConf kľúči %s nie je v rozsahu od %d do %d\n" - -#: ../src/core/prefs.c:633 ../src/core/prefs.c:710 ../src/core/prefs.c:758 -#: ../src/core/prefs.c:822 ../src/core/prefs.c:1115 ../src/core/prefs.c:1131 -#: ../src/core/prefs.c:1148 ../src/core/prefs.c:1164 -#, c-format -msgid "GConf key \"%s\" is set to an invalid type\n" -msgstr "GConf kľúč \"%s\" má nastavený neplatný typ\n" - -#: ../src/core/prefs.c:1234 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"Náhradné riešenia pre chybné aplikácie nie sú povolené. Niektoré aplikácie " -"sa nemusia správať slušne.\n" - -#: ../src/core/prefs.c:1305 -#, c-format -msgid "Could not parse font description \"%s\" from GConf key %s\n" -msgstr "Nepodarilo sa spracovať popis písma \"%s\" z GConf kľúča %s\n" - -#: ../src/core/prefs.c:1367 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"V konfiguračnej databáze sa našlo \"%s\", čo nie je platná hodnota pre " -"modifikátor tlačidla myši.\n" - -#: ../src/core/prefs.c:1788 -#, c-format -msgid "Error setting number of workspaces to %d: %s\n" -msgstr "Chyba pri nastavovaní počtu pracovných plôch na %d: %s\n" - -#: ../src/core/prefs.c:1953 ../src/core/prefs.c:2456 -#, c-format -msgid "Workspace %d" -msgstr "Pracovná plocha %d" - -#: ../src/core/prefs.c:1983 ../src/core/prefs.c:2161 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "" -"V konfiguračnej databáze sa našlo \"%s\", čo nie je platná hodnota pre " -"klávesovú skratku \"%s\".\n" - -#: ../src/core/prefs.c:2537 -#, c-format -msgid "Error setting name for workspace %d to \"%s\": %s\n" -msgstr "Chyba pri nastavovaní názvu pracovnej plochy %d na \"%s\": %s\n" - -#: ../src/core/prefs.c:2741 -#, c-format -msgid "Error setting compositor status: %s\n" -msgstr "Chyba pri nastavovaní stavu kompozítora: %s\n" - -#: ../src/core/screen.c:357 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "Obrazovka %d na displeji '%s' nie je platná\n" - -#: ../src/core/screen.c:373 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"Obrazovka %d na displeji \"%s\" už má správcu okien. Skúste použiť prepínač " -"--replace, aby sa aktuálny správca predefinoval.\n" - -#: ../src/core/screen.c:400 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "" -"Nepodarilo sa získať výber správcu okien pre obrazovku %d na displeji \"%s" -"\".\n" - -#: ../src/core/screen.c:458 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "Obrazovka %d na displeji \"%s\" už má správcu okien\n" - -#: ../src/core/screen.c:668 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "Nepodarilo sa uvoľniť obrazovku %d na displeji \"%s\"\n" - -#. Translators: Please don't translate "Control", "Shift", etc, since these -#. * are hardcoded (in gtk/gtkaccelgroup.c; it's not metacity's fault). -#. * "disabled" must also stay as it is. -#. -#: ../src/core/schema-bindings.c:169 -msgid "" -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1\".\n" -"\n" -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -"special string \"disabled\", then there will be no keybinding for this " -"action." -msgstr "" -"Formát je niečo ako \"<Control>a\" alebo \"<Shift><Alt>F1\".\n" -"\n" -"Spracovanie je dosť liberálne a povoľuje malé aj veľké písmená a taktiež " -"skratky ako je \"<Ctl>\" a \"<Ctrl>\". Ak nastavíte túto možnosť na " -"špeciálnu hodnotu \"disabled\", pre túto akciu nebude definovaná žiadna " -"klávesová skratka." - -#: ../src/core/schema-bindings.c:177 -msgid "" -"The format looks like \"<Control>a\" or \"<Shift><Alt>F1\".\n" -"\n" -"The parser is fairly liberal and allows lower or upper case, and also " -"abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -"special string \"disabled\", then there will be no keybinding for this " -"action.\n" -"\n" -"This keybinding may be reversed by holding down the \"shift\" key; " -"therefore, \"shift\" cannot be one of the keys it uses." -msgstr "" -"Formát je niečo ako \"<Control>a\" alebo \"<Shift><Alt>F1\".\n" -"\n" -"Spracovanie je dosť liberálne a povoľuje malé aj veľké písmená a taktiež " -"skratky ako je \"<Ctl>\" a \"<Ctrl>\". Ak nastavíte túto možnosť na " -"špeciálnu hodnotu \"disabled\", pre túto akciu nebude definovaná žiadna " -"klávesová skratka.\n" -"\n" -"Táto klávesová skratka môže byť obrátená podržaním klávesu \"shift\"; takže " -"\"shift\" nemôže byť jedným z použitých klávesov." - -#: ../src/core/session.c:850 ../src/core/session.c:857 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Nepodarilo sa vytvoriť priečinok '%s': %s\n" - -#: ../src/core/session.c:867 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "Nepodarilo sa otvoriť súbor relácie '%s' pre zápis: %s\n" - -#: ../src/core/session.c:1008 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Chyba pri zápise súboru relácie '%s': %s\n" - -#: ../src/core/session.c:1013 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Chyba pri zatváraní súboru relácie '%s': %s\n" - -#. oh, just give up -#: ../src/core/session.c:1106 -#, c-format -msgid "Failed to read saved session file %s: %s\n" -msgstr "Nepodarilo sa prečítať uložený súbor relácie %s: %s\n" - -#: ../src/core/session.c:1145 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Nepodarilo sa spracovať uložený súbor relácie: %s\n" - -#: ../src/core/session.c:1194 -#, c-format -msgid "<metacity_session> attribute seen but we already have the session ID" -msgstr "Našiel sa atribút <metacity_session>, ale ID relácie už je nastavené" - -#: ../src/core/session.c:1207 ../src/core/session.c:1282 -#: ../src/core/session.c:1314 ../src/core/session.c:1386 -#: ../src/core/session.c:1446 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Neznámy atribút %s v prvku <%s>" - -#: ../src/core/session.c:1224 -#, c-format -msgid "nested <window> tag" -msgstr "vnorená značka <window>" - -#: ../src/core/session.c:1466 -#, c-format -msgid "Unknown element %s" -msgstr "Neznámy prvok %s" - -#: ../src/core/session.c:1818 -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" -"Tieto okná nepodporujú "uložiť aktuálne nastavenie" a pri budúcom " -"prihlásení ich budete musieť znovu spustiť ručne." - -#: ../src/core/util.c:101 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Nepodarilo sa otvoriť záznam pre ladenie: %s\n" - -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Nepodarilo sa otvoriť súbor so záznamom pomocou fdopen() %s: %s\n" - -#: ../src/core/util.c:117 -#, c-format -msgid "Opened log file %s\n" -msgstr "Otvorený súbor so záznamom %s\n" - -#: ../src/core/util.c:136 ../src/tools/metacity-message.c:176 -#, c-format -msgid "Metacity was compiled without support for verbose mode\n" -msgstr "Metacity bol skompilovaný bez podpory zobrazovania informácií\n" - -#: ../src/core/util.c:236 -msgid "Window manager: " -msgstr "Správca okien:" - -#: ../src/core/util.c:388 -msgid "Bug in window manager: " -msgstr "Chyba v správcovi okien:" - -#: ../src/core/util.c:421 -msgid "Window manager warning: " -msgstr "Varovanie správcu okien:" - -#: ../src/core/util.c:449 -msgid "Window manager error: " -msgstr "Chyba správcu okien:" - -#. Translators: This is the title used on dialog boxes -#. eof all-keybindings.h -#: ../src/core/util.c:570 ../src/metacity.desktop.in.h:1 -#: ../src/metacity-wm.desktop.in.h:1 -msgid "Metacity" -msgstr "Metacity" - -#. first time through -#: ../src/core/window.c:5642 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"Okno %s nastavuje SM_CLIENT_ID na seba a nie na WM_CLIENT_LEADER, ako je " -"uvedené v ICCCM.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:6207 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %" -"d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"Okno %s nastavuje radu MWM že nie je možné zmeniť jeho veľkosť, ale " -"nastavuje minimálnu veľkosť %d x %d a maximálnu veľkosť %d x %d. To nedáva " -"zmysel.\n" - -#: ../src/core/window-props.c:244 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "Aplikácia nastavila neplatné _NET_WM_PID %lu\n" - -#. Translators: the title of a window from another machine -#: ../src/core/window-props.c:388 -#, c-format -msgid "%s (on %s)" -msgstr "%s (na %s)" - -#. Simple case-- don't bother to look it up. It's root. -#: ../src/core/window-props.c:420 -#, c-format -msgid "%s (as superuser)" -msgstr "%s (ako superpoužívateľ)" - -#. Translators: the title of a window owned by another user -#. * on this machine -#: ../src/core/window-props.c:438 -#, c-format -msgid "%s (as %s)" -msgstr "%s (ako %s)" +# description +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Presunúť okno na pracovný priestor č. 1" -#. Translators: the title of a window owned by another user -#. * on this machine, whose name we don't know -#: ../src/core/window-props.c:444 -#, c-format -msgid "%s (as another user)" -msgstr "%s (ako iný používateľ)" +# description +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Presunúť okno na pracovný priestor č. 2" -#: ../src/core/window-props.c:1430 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "Neplatné WM_TRANSIENT_FOR okno 0x%lx nastavené pre %s.\n" +# description +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Presunúť okno na pracovný priestor č. 3" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"Okno 0x%lx má vlastnosť %s,\n" -"ktorá by mala mať typ %s, formát %d,\n" -"a v skutočnosti má typ %s a formát %d, počet položiek %d.\n" -"Asi sa jedná o chybu aplikácie, a nie správcu okien.\n" -"Okno má titulok \"%s\", triedu \"%s\" a názov \"%s\"\n" +# description +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Presunúť okno na pracovný priestor č. 4" -#: ../src/core/xprops.c:401 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "Vlastnosť %s pre okno 0x%lx obsahuje neplatné UTF-8\n" +# description +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Presunúť okno na posledný pracovný priestor" -#: ../src/core/xprops.c:484 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"Vlastnosť %s pre okno 0x%lx obsahuje neplatné UTF-8 pre položku %d v " -"zozname\n" +# description +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "Presunúť okno o jeden pracovný priestor hore" -#: ../src/include/all-keybindings.h:88 +# description +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "Presunúť okno o jeden pracovný priestor dolu" + +# description +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "Presunúť okno o jeden monitor vľavo" + +# description +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "Presunúť okno o jeden monitor vpravo" + +# description +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "Presunúť okno o jeden monitor hore" + +# description +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "Presunúť okno o jeden monitor dolu" + +# description +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "Prepnúť aplikácie" + +# description +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "Prepnúť na predchádzajúcu aplikáciu" + +# description +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "Prepnúť okná" + +# description +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "Prepnúť na predchádzajúce okno" + +# description +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "Prepnúť okná aplikácie" + +# description +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "Prepnúť na predchádzajúce okno aplikácie" + +# PK: predpokladam ze to prepisane medzi tlacidlami +# description +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "Prepnúť medzi ovládacími prvkami systému" + +# PK: predpokladam ze to prepisane medzi tlacidlami +# description +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "Prepnúť na predchádzajúci ovládací prvok systému" + +# description +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "Prepnúť okná priamo" + +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "Priamo prepnúť na predchádzajúce okno" + +# description +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "Prepnúť okná aplikácie priamo" + +# description +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "Priamo prepnúť na predchádzajúce okno aplikácie" + +# description +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "Prepnúť medzi ovládacími prvkami systému priamo" + +# PK: predpokladam ze to prepisane medzi tlacidlami +# description +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "Priamo prepnúť na predchádzajúci ovládací prvok systému" + +# description +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "Skryť všetky normálne okná" + +# description +#: data/50-mutter-navigation.xml:108 msgid "Switch to workspace 1" -msgstr "Prepnúť na pracovnú plochu 1" +msgstr "Prepnúť na pracovný priestor č. 1" -#: ../src/include/all-keybindings.h:90 +# description +#: data/50-mutter-navigation.xml:111 msgid "Switch to workspace 2" -msgstr "Prepnúť na pracovnú plochu 2" +msgstr "Prepnúť na pracovný priestor č. 2" -#: ../src/include/all-keybindings.h:92 +# description +#: data/50-mutter-navigation.xml:114 msgid "Switch to workspace 3" -msgstr "Prepnúť na pracovnú plochu 3" +msgstr "Prepnúť na pracovný priestor č. 3" -#: ../src/include/all-keybindings.h:94 +# description +#: data/50-mutter-navigation.xml:117 msgid "Switch to workspace 4" -msgstr "Prepnúť na pracovnú plochu 4" - -#: ../src/include/all-keybindings.h:96 -msgid "Switch to workspace 5" -msgstr "Prepnúť na pracovnú plochu 5" - -#: ../src/include/all-keybindings.h:98 -msgid "Switch to workspace 6" -msgstr "Prepnúť na pracovnú plochu 6" - -#: ../src/include/all-keybindings.h:100 -msgid "Switch to workspace 7" -msgstr "Prepnúť na pracovnú plochu 7" - -#: ../src/include/all-keybindings.h:102 -msgid "Switch to workspace 8" -msgstr "Prepnúť na pracovnú plochu 8" - -#: ../src/include/all-keybindings.h:104 -msgid "Switch to workspace 9" -msgstr "Prepnúť na pracovnú plochu 9" - -#: ../src/include/all-keybindings.h:106 -msgid "Switch to workspace 10" -msgstr "Prepnúť na pracovnú plochu 10" - -#: ../src/include/all-keybindings.h:108 -msgid "Switch to workspace 11" -msgstr "Prepnúť na pracovnú plochu 11" - -#: ../src/include/all-keybindings.h:110 -msgid "Switch to workspace 12" -msgstr "Prepnúť na pracovnú plochu 12" - -#: ../src/include/all-keybindings.h:122 -msgid "Switch to workspace on the left of the current workspace" -msgstr "Prepnúť na pracovnú plochu vľavo od aktuálnej pracovnej plochy" - -#: ../src/include/all-keybindings.h:126 -msgid "Switch to workspace on the right of the current workspace" -msgstr "Prepnúť na pracovnú plochu vpravo od aktuálnej pracovnej plochy" - -#: ../src/include/all-keybindings.h:130 -msgid "Switch to workspace above the current workspace" -msgstr "Prepnúť na pracovnú plochu nad aktuálnou pracovnou plochou" - -#: ../src/include/all-keybindings.h:134 -msgid "Switch to workspace below the current workspace" -msgstr "Prepnúť na pracovnú plochu pod aktuálnou pracovnou plochou" - -#: ../src/include/all-keybindings.h:150 -msgid "Move between windows of an application, using a popup window" -msgstr "Presúvať medzi oknami aplikácie pomocou vyskakovacieho okna" - -#: ../src/include/all-keybindings.h:153 -msgid "Move backward between windows of an application, using a popup window" -msgstr "Presúvať dozadu medzi oknami aplikácie pomocou vyskakovacieho okna" - -#: ../src/include/all-keybindings.h:157 -msgid "Move between windows, using a popup window" -msgstr "Presúvať medzi oknami pomocou vyskakovacieho okna" - -#: ../src/include/all-keybindings.h:160 -msgid "Move backward between windows, using a popup window" -msgstr "Presúvať dozadu medzi oknami pomocou vyskakovacieho okna" - -#: ../src/include/all-keybindings.h:163 -msgid "Move between panels and the desktop, using a popup window" -msgstr "Presúvať medzi panelmi a plochou pomocou vyskakovacieho okna" - -#: ../src/include/all-keybindings.h:166 -msgid "Move backward between panels and the desktop, using a popup window" -msgstr "Presúvať dozadu medzi panelmi a plochou pomocou vyskakovacieho okna" - -#: ../src/include/all-keybindings.h:171 -msgid "Move between windows of an application immediately" -msgstr "Presúvať medzi oknami aplikácie okamžite" - -#: ../src/include/all-keybindings.h:174 -msgid "Move backward between windows of an application immediately" -msgstr "Presúvať dozadu medzi oknami aplikácie okamžite" - -#: ../src/include/all-keybindings.h:177 -msgid "Move between windows immediately" -msgstr "Presúvať medzi oknami okamžite" - -#: ../src/include/all-keybindings.h:180 -msgid "Move backward between windows immediately" -msgstr "Presúvať dozadu medzi oknami okamžite" - -#: ../src/include/all-keybindings.h:183 -msgid "Move between panels and the desktop immediately" -msgstr "Presúvať medzi panelmi a plochou okamžite" - -#: ../src/include/all-keybindings.h:186 -msgid "Move backward between panels and the desktop immediately" -msgstr "Presúvať dozadu medzi panelmi a plochou okamžite" - -#: ../src/include/all-keybindings.h:191 -msgid "Hide all normal windows and set focus to the desktop" -msgstr "Skryť všetky normálne okná a aktivovať plochu" - -#: ../src/include/all-keybindings.h:194 -msgid "Show the panel's main menu" -msgstr "Zobraziť hlavnú ponuku panelu" - -#: ../src/include/all-keybindings.h:197 -msgid "Show the panel's \"Run Application\" dialog box" -msgstr "Zobraziť dialógové okno \"Spustiť aplikáciu\" z panelu" - -#: ../src/include/all-keybindings.h:238 -msgid "Take a screenshot" -msgstr "Zachytiť obsah obrazovky" - -#: ../src/include/all-keybindings.h:240 -msgid "Take a screenshot of a window" -msgstr "Zachytiť obsah okna" - -#: ../src/include/all-keybindings.h:242 -msgid "Run a terminal" -msgstr "Spustiť terminál" - -#: ../src/include/all-keybindings.h:257 +msgstr "Prepnúť na pracovný priestor č. 4" + +# description +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "Prepnúť na posledný pracovný priestor" + +# description +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "Presunúť na pracovný priestor hore" + +# description +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "Presunúť na pracovný priestor dole" + +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "Systém" + +# description +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Zobraziť riadok pre spustenie príkazu" + +# description +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Zobraziť prehľad aktivít" + +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Obnoviť klávesové skratky" + +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Okná" + +# description +#: data/50-mutter-windows.xml:8 msgid "Activate the window menu" msgstr "Aktivovať ponuku okna" -#: ../src/include/all-keybindings.h:260 +# description +#: data/50-mutter-windows.xml:10 msgid "Toggle fullscreen mode" -msgstr "Prepnúť celoobrazovkový režim" +msgstr "Prepnúť režim na celú obrazovku" -#: ../src/include/all-keybindings.h:262 +# description +#: data/50-mutter-windows.xml:12 msgid "Toggle maximization state" msgstr "Prepnúť stav maximalizácie" -#: ../src/include/all-keybindings.h:264 -msgid "Toggle whether a window will always be visible over other windows" -msgstr "Prepnúť či bude okno vždy viditeľné nad ostatnými oknami" - -#: ../src/include/all-keybindings.h:266 +# description +#: data/50-mutter-windows.xml:14 msgid "Maximize window" msgstr "Maximalizovať okno" -#: ../src/include/all-keybindings.h:268 +# description +#: data/50-mutter-windows.xml:16 msgid "Restore window" msgstr "Obnoviť okno" -#: ../src/include/all-keybindings.h:270 -msgid "Toggle shaded state" -msgstr "Prepnúť zabalenie okna" - -#: ../src/include/all-keybindings.h:272 -msgid "Minimize window" -msgstr "Minimalizovať okno" - -#: ../src/include/all-keybindings.h:274 +# description +#: data/50-mutter-windows.xml:18 msgid "Close window" msgstr "Zatvoriť okno" -#: ../src/include/all-keybindings.h:276 +# description +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "Skryť okno" + +# description +#: data/50-mutter-windows.xml:22 msgid "Move window" msgstr "Presunúť okno" -#: ../src/include/all-keybindings.h:278 +# description +#: data/50-mutter-windows.xml:24 msgid "Resize window" msgstr "Zmeniť veľkosť okna" -#: ../src/include/all-keybindings.h:281 -msgid "Toggle whether window is on all workspaces or just one" -msgstr "" -"Prepnúť, či je okno na všetkých pracovných plochách alebo len na jednej" - -#: ../src/include/all-keybindings.h:285 -msgid "Move window to workspace 1" -msgstr "Presunúť okno na pracovnú plochu 1" - -#: ../src/include/all-keybindings.h:288 -msgid "Move window to workspace 2" -msgstr "Presunúť okno na pracovnú plochu 2" - -#: ../src/include/all-keybindings.h:291 -msgid "Move window to workspace 3" -msgstr "Presunúť okno na pracovnú plochu 3" - -#: ../src/include/all-keybindings.h:294 -msgid "Move window to workspace 4" -msgstr "Presunúť okno na pracovnú plochu 4" - -#: ../src/include/all-keybindings.h:297 -msgid "Move window to workspace 5" -msgstr "Presunúť okno na pracovnú plochu 5" - -#: ../src/include/all-keybindings.h:300 -msgid "Move window to workspace 6" -msgstr "Presunúť okno na pracovnú plochu 6" - -#: ../src/include/all-keybindings.h:303 -msgid "Move window to workspace 7" -msgstr "Presunúť okno na pracovnú plochu 7" - -#: ../src/include/all-keybindings.h:306 -msgid "Move window to workspace 8" -msgstr "Presunúť okno na pracovnú plochu 8" - -#: ../src/include/all-keybindings.h:309 -msgid "Move window to workspace 9" -msgstr "Presunúť okno na pracovnú plochu 9" +# description +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "Prepnúť okno na všetky pracovné priestory alebo len na jeden" -#: ../src/include/all-keybindings.h:312 -msgid "Move window to workspace 10" -msgstr "Presunúť okno na pracovnú plochu 10" +# description +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "Presunúť okno dopredu ak je zakryté, inak presunúť dozadu" -#: ../src/include/all-keybindings.h:315 -msgid "Move window to workspace 11" -msgstr "Presunúť okno na pracovnú plochu 11" - -#: ../src/include/all-keybindings.h:318 -msgid "Move window to workspace 12" -msgstr "Presunúť okno na pracovnú plochu 12" - -#: ../src/include/all-keybindings.h:330 -msgid "Move window one workspace to the left" -msgstr "Presunúť okno o jednu pracovnú plochu vľavo" - -#: ../src/include/all-keybindings.h:333 -msgid "Move window one workspace to the right" -msgstr "Presunúť okno o jednu pracovnú plochu vpravo" - -#: ../src/include/all-keybindings.h:336 -msgid "Move window one workspace up" -msgstr "Presunúť okno o jednu pracovnú plochu hore" - -#: ../src/include/all-keybindings.h:339 -msgid "Move window one workspace down" -msgstr "Presunúť okno o jednu pracovnú plochu dolu" - -#: ../src/include/all-keybindings.h:342 -msgid "Raise window if it's covered by another window, otherwise lower it" -msgstr "Presunúť okno dopredu ak je zakryté iným oknom, inak presunúť dozadu" - -#: ../src/include/all-keybindings.h:344 +# description +#: data/50-mutter-windows.xml:31 msgid "Raise window above other windows" -msgstr "Presunúť okno dopredu nad ostatné okná" +msgstr "Presunúť okno nad ostatné okná" -#: ../src/include/all-keybindings.h:346 +# description +#: data/50-mutter-windows.xml:33 msgid "Lower window below other windows" msgstr "Presunúť okno pod ostatné okná" -#: ../src/include/all-keybindings.h:350 +# description +#: data/50-mutter-windows.xml:35 msgid "Maximize window vertically" msgstr "Maximalizovať okno zvisle" -#: ../src/include/all-keybindings.h:354 +# description +#: data/50-mutter-windows.xml:37 msgid "Maximize window horizontally" msgstr "Maximalizovať okno vodorovne" -#: ../src/include/all-keybindings.h:358 -msgid "Move window to north-west (top left) corner" -msgstr "Presunúť okno ku severozápadnému rohu (vľavo hore)" - -#: ../src/include/all-keybindings.h:361 -msgid "Move window to north-east (top right) corner" -msgstr "Presunúť okno ku severovýchodnému rohu (vpravo hore)" - -#: ../src/include/all-keybindings.h:364 -msgid "Move window to south-west (bottom left) corner" -msgstr "Presunúť okno ku juhozápadnému rohu (vľavo dole)" - -#: ../src/include/all-keybindings.h:367 -msgid "Move window to south-east (bottom right) corner" -msgstr "Presunúť okno ku juhovýchodnému rohu (vpravo dole)" - -#: ../src/include/all-keybindings.h:371 -msgid "Move window to north (top) side of screen" -msgstr "Presunúť okno na severnú stranu obrazovky (nahor)" - -#: ../src/include/all-keybindings.h:374 -msgid "Move window to south (bottom) side of screen" -msgstr "Presunúť okno na južnú stranu obrazovky (nadol)" +# Description +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "Zobraziť rozdelenie naľavo" -#: ../src/include/all-keybindings.h:377 -msgid "Move window to east (right) side of screen" -msgstr "Presunúť okno na východnú stranu obrazovky (vpravo)" +# Description +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "Zobraziť rozdelenie napravo" -#: ../src/include/all-keybindings.h:380 -msgid "Move window to west (left) side of screen" -msgstr "Presunúť okno na západnú stranu obrazovky (vľavo)" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" -#: ../src/include/all-keybindings.h:383 -msgid "Move window to center of screen" -msgstr "Presunúť okno doprostred obrazovky" +# summary +#: data/org.gnome.mutter.gschema.xml.in:7 +msgid "Modifier to use for extended window management operations" +msgstr "Modifikátor pre rozšírené operácie správcu okien" -#: ../src/metacity.schemas.in.in.h:1 -msgid "(Not implemented) Navigation works in terms of applications not windows" -msgstr "(Neimplementované) Navigácia vzhľadom k aplikáciám, nie oknám" - -#: ../src/metacity.schemas.in.in.h:2 +# description +#: data/org.gnome.mutter.gschema.xml.in:8 msgid "" -"A font description string describing a font for window titlebars. The size " -"from the description will only be used if the titlebar_font_size option is " -"set to 0. Also, this option is disabled if the titlebar_uses_desktop_font " -"option is set to true." +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." msgstr "" -"Reťazec popisu písma pre titulky okien. Veľkosť sa použije iba v prípade, že " -"voľba titlebar_font_size je 0. Táto voľba je vypnutá v prípade, že je na " -"true nastavené titlebar_uses_desktop_font." - -#: ../src/metacity.schemas.in.in.h:3 -msgid "Action on title bar double-click" -msgstr "Akcia pri dvojitom kliknutí na titulok" - -#: ../src/metacity.schemas.in.in.h:4 -msgid "Action on title bar middle-click" -msgstr "Akcia pri kliknutí stredným myšítkom na titulok" - -#: ../src/metacity.schemas.in.in.h:5 -msgid "Action on title bar right-click" -msgstr "Akcia pri kliknutí pravým myšítkom na titulok" +"Tento kláves spustí „prekrytie“, čo znamená kombináciu náhľadu okna a " +"systému na spustenie aplikácií. Štandardne nastavená je na osobných " +"počítačoch „kláves Windows“. Očakáva sa štandardné nastavenie alebo " +"nastavenie na prázdny reťazec." -#: ../src/metacity.schemas.in.in.h:6 -msgid "Arrangement of buttons on the titlebar" -msgstr "Usporiadanie tlačidiel v titulku" +# summary +#: data/org.gnome.mutter.gschema.xml.in:20 +msgid "Attach modal dialogs" +msgstr "Pripojiť modálne dialógové okná" -#: ../src/metacity.schemas.in.in.h:7 +# description +#: data/org.gnome.mutter.gschema.xml.in:21 msgid "" -"Arrangement of buttons on the titlebar. The value should be a string, such " -"as \"menu:minimize,maximize,spacer,close\"; the colon separates the left " -"corner of the window from the right corner, and the button names are comma-" -"separated. Duplicate buttons are not allowed. Unknown button names are " -"silently ignored so that buttons can be added in future metacity versions " -"without breaking older versions. A special spacer tag can be used to insert " -"some space between two adjacent buttons." +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." msgstr "" -"Usporiadanie tlačidiel v titulku. Hodnota je reťazec, napríklad \"menu:" -"minimize,maximize,spacer,close\". Dvojbodka oddeľuje ľavý roh okna od " -"pravého a názvy tlačidiel sú oddelené čiarkami. Viacnásobné použitie " -"tlačidiel nie je povolené. Neznáme názvy tlačidiel sú potichu ignorované, " -"takže tlačidlá pridané v budúcich verziách metacity nespôsobia nefunkčnosť " -"starších verzií. Specialny retazec \"spacer\" moze byt pouzity pre vlozenie " -"medzery medzi dve susedne tlacidla" - -#: ../src/metacity.schemas.in.in.h:8 -msgid "Automatically raises the focused window" -msgstr "Automaticky presunúť aktívne okno dopredu" - -#: ../src/metacity.schemas.in.in.h:9 -msgid "" -"Clicking a window while holding down this modifier key will move the window " -"(left click), resize the window (middle click), or show the window menu " -"(right click). The middle and right click operations may be swapped using " -"the \"resize_with_right_button\" key. Modifier is expressed as \"<Alt>" -"\" or \"<Super>\" for example." -msgstr "" -"Kliknutím na okno pri podržaní tohto modifikátora sa okno presunie (ľavé " -"kliknutie), zmení jeho veľkosť (stredné kliknutie) alebo sa zobrazí ponuka " -"okna (pravé kliknutie). Operácie na stredné a pravé kliknutie sa dajú " -"prehodiť pomocou nastavenia kľúča \"resize_with_right_button\". Modifikátor " -"je vyjadrený napr. ako \"<Alt>\" alebo \"<Super>\"." - -#: ../src/metacity.schemas.in.in.h:10 -msgid "Commands to run in response to keybindings" -msgstr "Príkazy spustené ako reakcia na klávesové skratky" - -#: ../src/metacity.schemas.in.in.h:11 -msgid "Compositing Manager" -msgstr "Správca kompozície" +"Ak je nastavené na true, namiesto nezávislých titulkov okien sa modálnym " +"dialógovým oknám pripojí titulok z okna rodiča. Súčasne budú aj presúvané " +"spolu s oknom rodiča." -#: ../src/metacity.schemas.in.in.h:12 -msgid "Control how new windows get focus" -msgstr "Nastavenie, ako sa nové okno stane aktívnym" +# summary +#: data/org.gnome.mutter.gschema.xml.in:30 +msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "Povoliť natiahnutie k okraju pri pustení okien na okrajoch obrazovky" -#: ../src/metacity.schemas.in.in.h:13 -msgid "Current theme" -msgstr "Aktuálna téma" - -#: ../src/metacity.schemas.in.in.h:14 -msgid "Delay in milliseconds for the auto raise option" -msgstr "Čakanie v milisekundách pred automatickým presunom dopredu" - -#: ../src/metacity.schemas.in.in.h:15 -msgid "Determines whether Metacity is a compositing manager." -msgstr "Určuje, či je Metacity kompozičný správca" - -#: ../src/metacity.schemas.in.in.h:16 +# description +#: data/org.gnome.mutter.gschema.xml.in:31 msgid "" -"Determines whether applications or the system can generate audible 'beeps'; " -"may be used in conjunction with 'visual bell' to allow silent 'beeps'." +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." msgstr "" -"Určuje, či majú aplikácie alebo systém generovať zvukové pípnutia. Spolu s " -"vizuálnym zvončekom umožňuje tiché pípanie." +"Ak je povolené, upustenie okien pri zvislých okrajoch obrazovky ich zvislo " +"maximalizuje a vodorovná veľkosť sa zmení na polovicu dostupnej plochy. " +"Upustenie okien pri vrchnom okraji obrazovky ich maximalizuje úplne." -#: ../src/metacity.schemas.in.in.h:17 -msgid "Disable misfeatures that are required by old or broken applications" -msgstr "" -"Vypnúť chybné funkcie, ktoré sú vyžadované starými alebo chybnými aplikáciami" +# summary +#: data/org.gnome.mutter.gschema.xml.in:40 +msgid "Workspaces are managed dynamically" +msgstr "Pracovné priestory sú spravované dynamicky" -#: ../src/metacity.schemas.in.in.h:18 -msgid "Enable Visual Bell" -msgstr "Povoliť vizuálny zvonček" - -#: ../src/metacity.schemas.in.in.h:19 +# description +#: data/org.gnome.mutter.gschema.xml.in:41 msgid "" -"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " -"the focused window will be automatically raised after a delay specified by " -"the auto_raise_delay key. This is not related to clicking on a window to " -"raise it, nor to entering a window during drag-and-drop." +"Determines whether workspaces are managed dynamically or whether there’s a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." msgstr "" -"Ak je nastavené na true, a režim aktivizácie okien je buď \"sloppy\" alebo " -"\"myš\", potom okno v zábere sa automaticky zobudí po čase zadanom v kľúči " -"auto_raise_delay. Toto sa nevzťahuje na prebúdzanie okna klikaním, ani na " -"vstup do okna pomocou ťahaj-a-pusť." +"Určuje, či pracovné priestory sú spravované dynamicky alebo ich počet je " +"pevný (určený kľúčom num-workspaces v org.gnome.desktop.wm.preferences)." -#: ../src/metacity.schemas.in.in.h:20 -msgid "" -"If true, ignore the titlebar_font option, and use the standard application " -"font for window titles." -msgstr "" -"Ak je true, ignoruje sa titlebar_font a použije sa štandardné písmo " -"aplikácie pre titulky okien." +# summary +#: data/org.gnome.mutter.gschema.xml.in:50 +msgid "Workspaces only on primary" +msgstr "Pracovné priestory len na hlavnom monitore" -#: ../src/metacity.schemas.in.in.h:21 +# description +#: data/org.gnome.mutter.gschema.xml.in:51 msgid "" -"If true, metacity will give the user less feedback by using wireframes, " -"avoiding animations, or other means. This is a significant reduction in " -"usability for many users, but may allow legacy applications to continue " -"working, and may also be a useful tradeoff for terminal servers. However, " -"the wireframe feature is disabled when accessibility is on." +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." msgstr "" -"Ak je true, metacity bude poskytovať používateľovi menej spätnej väzby " -"pomocou obrysov, vynechaním animácií, alebo inak. Toto pre mnohých " -"používateľov znamená výrazné zníženie použiteľnosti, ale môže umožniť " -"pracovať starým aplikáciam a terminálovým serverom, ktoré by inak boli " -"prakticky nepoužiteľné. Avšak obrysy nebudú povolené pri zapnutej " -"použiteľnosti." - -#: ../src/metacity.schemas.in.in.h:22 -msgid "" -"If true, then Metacity works in terms of applications rather than windows. " -"The concept is a bit abstract, but in general an application-based setup is " -"more like the Mac and less like Windows. When you focus a window in " -"application-based mode, all the windows in the application will be raised. " -"Also, in application-based mode, focus clicks are not passed through to " -"windows in other applications. Application-based mode is, however, largely " -"unimplemented at the moment." -msgstr "" -"Ak je true, Metacity funguje v rámci aplikácií a nie okien. Je to trochu " -"abstraktnejšie, ale všeobecne sa dá povedať, že nastavenie vzhľadom k " -"aplikáciám sa podobá viac systému Mac a menej systému Windows. Ak urobíte " -"okno aktívnym v režime aplikácií, všetky okná tejto aplikácie sa presunú " -"dopredu. Kliknutie kvôli aktivácii sa oknám iných aplikácií neodovzdáva. Na " -"druhú stranu, máloktorá aplikácia je napísaná pre mód založený na " -"aplikáciách." - -#: ../src/metacity.schemas.in.in.h:23 -msgid "If true, trade off usability for less resource usage" -msgstr "Ak je true, zhorší sa použiteľnosť, ale klesne spotreba zdrojov" - -#: ../src/metacity.schemas.in.in.h:24 -msgid "Modifier to use for modified window click actions" -msgstr "Modifikátor pre upravené akcie pri kliknutí na okno" - -#: ../src/metacity.schemas.in.in.h:25 -msgid "Name of workspace" -msgstr "Názov pracovnej plochy" - -#: ../src/metacity.schemas.in.in.h:26 -msgid "Number of workspaces" -msgstr "Počet pracovných plôch" - -#: ../src/metacity.schemas.in.in.h:27 -msgid "" -"Number of workspaces. Must be more than zero, and has a fixed maximum to " -"prevent making the desktop unusable by accidentally asking for too many " -"workspaces." -msgstr "" -"Počet pracovných plôch. Musí byť viac ako 0 a má pevné maximum (aby sa " -"zabránilo zničeniu pracovného prostredia požadovaním 34 miliónov pracovných " -"plôch)." +"Určuje, či sa má pracovný priestor prepínať medzi oknami na všetkých " +"monitoroch alebo iba medzi oknami na hlavnom monitore." -#: ../src/metacity.schemas.in.in.h:28 -msgid "Run a defined command" -msgstr "Spustiť definovaný príkaz" - -#: ../src/metacity.schemas.in.in.h:29 -msgid "" -"Set this to true to resize with the right button and show a menu with the " -"middle button while holding down the key given in \"mouse_button_modifier\"; " -"set it to false to make it work the opposite way around." -msgstr "" -"Nastavením na true povolíte zmenu veľkosti okna pravým tlačidlom a " -"zobrazenie ponuky okna stredným tlačidlom pri súčasnom podržaní klávesu " -"určeného v \"mouse_button_modifier\"; nastavením na false to bude fungovať " -"presne naopak." +# summary +#: data/org.gnome.mutter.gschema.xml.in:59 +msgid "No tab popup" +msgstr "Bez vyvolávania tabulátorom" -#: ../src/metacity.schemas.in.in.h:30 +# description +#: data/org.gnome.mutter.gschema.xml.in:60 msgid "" -"Setting this option to false can lead to buggy behavior, so users are " -"strongly discouraged from changing it from the default of true. Many actions " -"(e.g. clicking in the client area, moving or resizing the window) normally " -"raise the window as a side-effect. Setting this option to false, which is " -"strongly discouraged, will decouple raising from other user actions, and " -"ignore raise requests generated by applications. See http://bugzilla.gnome." -"org/show_bug.cgi?id=445447#c6. Even when this option is false, windows can " -"still be raised by an alt-left-click anywhere on the window, a normal click " -"on the window decorations, or by special messages from pagers, such as " -"activation requests from tasklist applets. This option is currently disabled " -"in click-to-focus mode. Note that the list of ways to raise windows when " -"raise_on_click is false does not include programmatic requests from " -"applications to raise windows; such requests will be ignored regardless of " -"the reason for the request. If you are an application developer and have a " -"user complaining that your application does not work with this setting " -"disabled, tell them it is _their_ fault for breaking their window manager " -"and that they need to change this option back to true or live with the \"bug" -"\" they requested." +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." msgstr "" -"Nastavenie tejto voľby na false môže viesť k chybnému správaniu, takže " -"používateľom dôrazne neodporúčame meniť predvolenú hodnotu true. Viaceré " -"akcie (napr. kliknutie v klientskej oblasti, presun alebo zmena veľkosti " -"okna) zvyčajne zároveň vyzdvihnú okno ako vedľajší efekt. Nastavenie tejto " -"voľby na false, čo sa dôrazne neodporúča, oddelí vyzdvihnutie od ostatných " -"akcií používateľa a bude ignorovať požiadavky na vyzdvihnutie od aplikácie. " -"Pozrite http://bugzilla.gnome.org/show_bug.cgi?id=445447#c6. Dokonca aj keď " -"má táto voľba hodnotu false, budú sa okná dať vyzdvihnúť pomocou alt-ľavý " -"klik kdekoľvek v okne, normálnym kliknutím na dekorácie okna, alebo " -"špeciálnymi správami od pagerov, ako sú napríklad požiadavky na aktiváciu od " -"apletov zoznamov úloh. Táto voľba je v súčasnosti vypnutá v režime aktivácie " -"kliknutím. Poznámka: zoznam spôsobov, ako vyzdvihnúť okno pri nastavení " -"raise_on_click na false, nezahŕňa programové požiadavky aplikácií na " -"vyzdvihnutie okien; takéto požiadavky budú ignorované bez ohľadu na dôvod " -"požiadavky. Ak vyvíjate aplikáciu a nejaký používateľ sa sťažuje, že vaša " -"aplikácia nefunguje, keď je toto nastavenie vypnuté, povedzte mu, že " -"pokazenie správcu okien je _ich_ chybou, a že si musia nastaviť túto hodnotu " -"naspäť na true alebo sa zmieriť s \"chybou\", ktorú si vyžiadali." - -#: ../src/metacity.schemas.in.in.h:31 -msgid "" -"Some applications disregard specifications in ways that result in window " -"manager misfeatures. This option puts Metacity in a rigorously correct mode, " -"which gives a more consistent user interface, provided one does not need to " -"run any misbehaving applications." -msgstr "" -"Niektoré aplikácie porušujú špecifikácie spôsobmi, ktoré vedú k chybnému " -"správaniu správcu okien. Táto voľba prepne Metacity do puritánsky správneho " -"režimu, čo prináša jednotnejšie používateľské rozhranie, za predpokladu že " -"nepotrebujeme spúšťať nijaké nekorektné aplikácie." +"Určuje, či sa má používať rozbaľovacia ponuka a zvýraznenie rámcom sa má " +"vypnúť pri prepínaní okien." -#: ../src/metacity.schemas.in.in.h:32 -msgid "System Bell is Audible" -msgstr "Systémový zvonček je počuteľný" - -#: ../src/metacity.schemas.in.in.h:33 -msgid "" -"Tells Metacity how to implement the visual indication that the system bell " -"or another application 'bell' indicator has been rung. Currently there are " -"two valid values, \"fullscreen\", which causes a fullscreen white-black " -"flash, and \"frame_flash\" which causes the titlebar of the application " -"which sent the bell signal to flash. If the application which sent the bell " -"is unknown (as is usually the case for the default \"system beep\"), the " -"currently focused window's titlebar is flashed." -msgstr "" -"Určuje, ako má Metacity implementovať vizuálne zobrazenie pípnutia " -"aplikáciou alebo systémom. Momentálne sú platné dve hodnoty, \"fullscreen\", " -"ktorá čiernobielo blikne celou obrazovkou a \"frame_flash\", kde blikne " -"titulok okna, v ktorom je pípajúca aplikácia. Ak nie je možné určiť pípajúcu " -"aplikáciu (napríklad u \"pípnutia systému\"), blikne titulok momentálne " -"aktívneho okna." - -#: ../src/metacity.schemas.in.in.h:34 -msgid "" -"The /apps/metacity/global_keybindings/run_command_N keys define keybindings " -"that correspond to these commands. Pressing the keybinding for run_command_N " -"will execute command_N." -msgstr "" -"Kľúče /apps/metacity/global_keybindings/run_command_N definujú klávesové " -"skratky odpovedajúce týmto príkazom. Stlačením skratky pre run_command_N " -"spustíte command_N." +# summary +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Odložiť zmeny zamerania až po zastavení pohybu ukazovateľa" -#: ../src/metacity.schemas.in.in.h:35 +# description +#: data/org.gnome.mutter.gschema.xml.in:69 msgid "" -"The /apps/metacity/global_keybindings/run_command_screenshot key defines a " -"keybinding which causes the command specified by this setting to be invoked." +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." msgstr "" -"Kľúč /apps/metacity/global_keybindings/run_command_screenshot definuje " -"klávesovú skratku, ktorá spustí zadaný príkaz." - -#: ../src/metacity.schemas.in.in.h:36 -msgid "" -"The /apps/metacity/global_keybindings/run_command_window_screenshot key " -"defines a keybinding which causes the command specified by this setting to " -"be invoked." -msgstr "" -"Kľúč /apps/metacity/global_keybindings/run_command_window_screenshot " -"definuje klávesovú skratku, ktorá spustí zadaný príkaz." - -#: ../src/metacity.schemas.in.in.h:37 -msgid "" -"The keybinding that runs the correspondingly-numbered command in /apps/" -"metacity/keybinding_commands The format looks like \"<Control>a\" or " -"\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -"lower or upper case, and also abbreviations such as \"<Ctl>\" and " -"\"<Ctrl>\". If you set the option to the special string \"disabled\", " -"then there will be no keybinding for this action." -msgstr "" -"Klávesová skratka, ktorá spustí príkaz podľa čísla v /apps/metacity/" -"keybinding_commands. Formát je \"<Control>a\" alebo \"<Shift><" -"Alt>F1\". Spracovanie je dosť liberálne a umožňuje malé aj veľké písmená " -"a skratky ako je \"<Ctl>\" a \"<Ctrl>\". Ak nastavíte túto " -"možnosť na špeciálnu hodnotu \"disabled\", pre túto akciu nebude definovaná " -"žiadna klávesová skratka." - -#: ../src/metacity.schemas.in.in.h:38 -msgid "The name of a workspace." -msgstr "Názov pracovnej plochy." - -#: ../src/metacity.schemas.in.in.h:39 -msgid "The screenshot command" -msgstr "Príkaz pre zachytenie obrazovky" - -#: ../src/metacity.schemas.in.in.h:40 -msgid "" -"The theme determines the appearance of window borders, titlebar, and so " -"forth." -msgstr "Téma určuje vzhľad rámu okna, titulku a tak ďalej." - -#: ../src/metacity.schemas.in.in.h:41 -msgid "" -"The time delay before raising a window if auto_raise is set to true. The " -"delay is given in thousandths of a second." -msgstr "" -"Čas čakania pred presunom okna dopredu, ak je auto_raise true. Hodnota je v " -"tisícinách sekundy." - -#: ../src/metacity.schemas.in.in.h:42 -msgid "" -"The window focus mode indicates how windows are activated. It has three " -"possible values; \"click\" means windows must be clicked in order to focus " -"them, \"sloppy\" means windows are focused when the mouse enters the window, " -"and \"mouse\" means windows are focused when the mouse enters the window and " -"unfocused when the mouse leaves the window." -msgstr "" -"Režim aktivizácie okien má tri možné hodnoty: \"click\" znamená, že na okno " -"sa musí kliknúť, \"sloppy\" znamená, že okno sa stane aktívnym, ak sa kurzor " -"myši nastaví nad okno, a \"mouse\" znamená, že sa okno stane aktívnym pri " -"ukázaní kurzorom myši a pri presune kurzoru myši mimo okno prestane byť okno " -"aktívne." - -#: ../src/metacity.schemas.in.in.h:43 -msgid "The window screenshot command" -msgstr "Príkaz pre zachytenie obsahu okna" - -#: ../src/metacity.schemas.in.in.h:44 -msgid "" -"This option determines the effects of double-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, 'toggle_maximize' which will maximize/unmaximize the window, " -"'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which will " -"maximize/unmaximize the window in that direction only, 'minimize' which will " -"minimize the window, 'shade' which will roll the window up, 'menu' which " -"will display the window menu, 'lower' which will put the window behind all " -"the others, and 'none' which will not do anything." -msgstr "" -"Táto voľba určuje výsledok dvojitého kliknutia na titulok okna. Momentálne " -"je možné použiť 'toggle_shade', ktoré rozbalí resp. zabalí okno, " -"'toggle_maximize', ktoré maximalizuje alebo zruší maximalizáciu okna, " -"'toggle_maximize_horizontally' a 'toggle_maximize_vertically' ktoré prepne " -"maximalizovanie okna v horizontálnom alebo vertikálnom smere, 'minimize', " -"ktoré okno minimalizuje, 'shade', ktoré zroluje okno nahor, 'menu', ktoré " -"zobrazí ponuku okna, 'lower', ktoré pošle okno dozadu za všetky ostatné a " -"'none' čo nespraví nič." - -#: ../src/metacity.schemas.in.in.h:45 -msgid "" -"This option determines the effects of middle-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, 'toggle_maximize' which will maximize/unmaximize the window, " -"'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which will " -"maximize/unmaximize the window in that direction only, 'minimize' which will " -"minimize the window, 'shade' which will roll the window up, 'menu' which " -"will display the window menu, 'lower' which will put the window behind all " -"the others, and 'none' which will not do anything." -msgstr "" -"Táto voľba určuje výsledok kliknutia stredným tlačidlom na titulok okna. " -"Momentálne je možné použiť 'toggle_shade', ktoré rozbalí resp. zabalí okno, " -"'toggle_maximize', ktoré maximalizuje alebo zruší maximalizáciu okna, " -"'toggle_maximize_horizontally' a 'toggle_maximize_vertically' ktoré prepne " -"maximalizovanie okna v horizontálnom alebo vertikálnom smere, 'minimize', " -"ktoré okno minimalizuje, 'shade', ktoré zroluje okno nahor, 'menu', ktoré " -"zobrazí ponuku okna, 'lower', ktoré pošle okno dozadu za všetky ostatné a " -"'none' čo nespraví nič." - -#: ../src/metacity.schemas.in.in.h:46 -msgid "" -"This option determines the effects of right-clicking on the title bar. " -"Current valid options are 'toggle_shade', which will shade/unshade the " -"window, 'toggle_maximize' which will maximize/unmaximize the window, " -"'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which will " -"maximize/unmaximize the window in that direction only, 'minimize' which will " -"minimize the window, 'shade' which will roll the window up, 'menu' which " -"will display the window menu, 'lower' which will put the window behind all " -"the others, and 'none' which will not do anything." -msgstr "" -"Táto voľba určuje výsledok kliknutia pravým tlačidlom na titulok okna. " -"Momentálne je možné použiť 'toggle_shade', ktoré rozbalí resp. zabalí okno, " -"'toggle_maximize', ktoré maximalizuje alebo zruší maximalizáciu okna, " -"'toggle_maximize_horizontally' a 'toggle_maximize_vertically' ktoré prepne " -"maximalizovanie okna v horizontálnom alebo vertikálnom smere, 'minimize', " -"ktoré okno minimalizuje, 'shade', ktoré zroluje okno nahor, 'menu', ktoré " -"zobrazí ponuku okna, 'lower', ktoré pošle okno dozadu za všetky ostatné a " -"'none' čo nespraví nič." - -#: ../src/metacity.schemas.in.in.h:47 -msgid "" -"This option provides additional control over how newly created windows get " -"focus. It has two possible values; \"smart\" applies the user's normal focus " -"mode, and \"strict\" results in windows started from a terminal not being " -"given focus." -msgstr "" -"Táto možnosť ponúka rozšírenú kontrolu nad tým, ako sa novovytvorené okná " -"stávajú aktívnymi. Má dve možné hodnoty: \"smart\" použije bežný " -"používateľský režim, a \"strict\" spôsobí, že okná spustené z terminálu nie " -"sú hneď aktívne." - -#: ../src/metacity.schemas.in.in.h:48 -msgid "" -"Turns on a visual indication when an application or the system issues a " -"'bell' or 'beep'; useful for the hard-of-hearing and for use in noisy " -"environments." -msgstr "" -"Zapne vizuálnu zobrazenie pokusu aplikácie alebo systému o pípnutie alebo " -"zvonček. To sa hodí pre slabo počujúcich ľudí alebo ak pracujete v hlučnom " -"prostredí, alebo pri vypnutom počuteľnom zvončeku." - -#: ../src/metacity.schemas.in.in.h:49 -msgid "Use standard system font in window titles" -msgstr "Použiť štandardné systémové písmo v titulkoch okna" - -#: ../src/metacity.schemas.in.in.h:50 -msgid "Visual Bell Type" -msgstr "Typ vizuálneho zvončeka" - -#: ../src/metacity.schemas.in.in.h:51 -msgid "Whether raising should be a side-effect of other user interactions" -msgstr "Určuje, či sa má okno zobudiť aj pri iných interakciách s používateľom" - -#: ../src/metacity.schemas.in.in.h:52 -msgid "Whether to resize with the right button" -msgstr "Či sa bude meniť veľkosť okna pravým tlačidlom" - -#: ../src/metacity.schemas.in.in.h:53 -msgid "Window focus mode" -msgstr "Režim aktivácie okna" - -#: ../src/metacity.schemas.in.in.h:54 -msgid "Window title font" -msgstr "Písmo titulku okna" - -#: ../src/tools/metacity-message.c:150 -#, c-format -msgid "Usage: %s\n" -msgstr "Použitie: %s\n" - -#: ../src/ui/frames.c:1118 -msgid "Close Window" -msgstr "Zavrieť okno" - -#: ../src/ui/frames.c:1121 -msgid "Window Menu" -msgstr "Ponuka okna" - -#: ../src/ui/frames.c:1124 -msgid "Minimize Window" -msgstr "Minimalizovať okno" - -#: ../src/ui/frames.c:1127 -msgid "Maximize Window" -msgstr "Maximalizovať okno" - -#: ../src/ui/frames.c:1130 -msgid "Restore Window" -msgstr "Obnoviť okno" - -#: ../src/ui/frames.c:1133 -msgid "Roll Up Window" -msgstr "Zabaliť okno" - -#: ../src/ui/frames.c:1136 -msgid "Unroll Window" -msgstr "Rozbaliť okno" - -#: ../src/ui/frames.c:1139 -msgid "Keep Window On Top" -msgstr "Ponechať okno vždy navrchu" - -#: ../src/ui/frames.c:1142 -msgid "Remove Window From Top" -msgstr "Okno nemusí byť navrchu" - -#: ../src/ui/frames.c:1145 -msgid "Always On Visible Workspace" -msgstr "Vždy na viditeľnej pracovnej ploche" - -#: ../src/ui/frames.c:1148 -msgid "Put Window On Only One Workspace" -msgstr "Poslať okno na jedinú pracovnú plochu" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:70 -msgid "Mi_nimize" -msgstr "Mi_nimalizovať" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:72 -msgid "Ma_ximize" -msgstr "Ma_ximalizovať" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:74 -msgid "Unma_ximize" -msgstr "Zrušiť ma_ximalizáciu" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:76 -msgid "Roll _Up" -msgstr "_Zabaliť" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:78 -msgid "_Unroll" -msgstr "_Rozbaliť" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:80 -msgid "_Move" -msgstr "Pre_miestniť" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:82 -msgid "_Resize" -msgstr "Zmeniť veľko_sť" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:84 -msgid "Move Titlebar On_screen" -msgstr "Presunúť titulok na _obrazovku" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:87 ../src/ui/menu.c:89 -msgid "Always on _Top" -msgstr "Vždy na_vrchu" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:91 -msgid "_Always on Visible Workspace" -msgstr "Vž_dy na viditeľnej pracovnej ploche" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:93 -msgid "_Only on This Workspace" -msgstr "_Len na tejto pracovnej ploche" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:95 -msgid "Move to Workspace _Left" -msgstr "Presunúť na pracovnú plochu vľav_o" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:97 -msgid "Move to Workspace R_ight" -msgstr "Presunúť na pracovnú plochu v_pravo" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:99 -msgid "Move to Workspace _Up" -msgstr "Presunúť na pracovnú plochu _hore" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:101 -msgid "Move to Workspace _Down" -msgstr "Presunúť na pracovnú plochu _dole" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:105 -msgid "_Close" -msgstr "_Zavrieť" - -#: ../src/ui/menu.c:203 -#, c-format -msgid "Workspace %d%n" -msgstr "Pracovná plocha %d%n" - -#: ../src/ui/menu.c:213 -#, c-format -msgid "Workspace 1_0" -msgstr "Pracovná plocha 1_0" - -#: ../src/ui/menu.c:215 -#, c-format -msgid "Workspace %s%d" -msgstr "Pracovná plocha %s%d" - -#: ../src/ui/menu.c:395 -msgid "Move to Another _Workspace" -msgstr "P_resunúť na inú pracovnú plochu" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:104 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:110 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:116 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:122 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:128 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:134 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:140 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:146 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:152 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:158 -msgid "Mod5" -msgstr "Mod5" - -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" - -#: ../src/ui/theme.c:254 -msgid "top" -msgstr "hore" - -#: ../src/ui/theme.c:256 -msgid "bottom" -msgstr "dole" - -#: ../src/ui/theme.c:258 -msgid "left" -msgstr "vľavo" +"Ak je nastavené na true, a režim aktivácie okien je buď „sloppy“ (nedbalý) " +"alebo „mouse“ (myš), potom sa záber nezmení okamžite ale až po vstupe do " +"okna a zastavení ukazovateľa." -#: ../src/ui/theme.c:260 -msgid "right" -msgstr "vpravo" +# summary +#: data/org.gnome.mutter.gschema.xml.in:79 +msgid "Draggable border width" +msgstr "Šírka posúvateľného okraja" -#: ../src/ui/theme.c:287 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "geometria rámca neurčuje rozmer \"%s\"" - -#: ../src/ui/theme.c:306 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "geometria rámca neurčuje rozmer \"%s\" pre okraj \"%s\"" - -#: ../src/ui/theme.c:343 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "Pomer stránok tlačidla %g nie je použiteľný." - -#: ../src/ui/theme.c:355 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "Geometria rámca neurčuje rozmer tlačidiel" - -#: ../src/ui/theme.c:1020 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "Prechody by mali mať aspoň dve farby" - -#: ../src/ui/theme.c:1146 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"Špecifikácia farby GTK musí mať stav v hranatých zátvorkách, napr. gtk:fg" -"[NORMAL], kde NORMAL je stav. Nepodarilo sa spracovať \"%s\"" - -#: ../src/ui/theme.c:1160 -#, c-format +# description +#: data/org.gnome.mutter.gschema.xml.in:80 msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +"The amount of total draggable borders. If the theme’s visible borders are " +"not enough, invisible borders will be added to meet this value." msgstr "" -"Špecifikácia farby GTK musí mať stav uzavretý v hranatých zátvorkách, napr. " -"gtk:fg[NORMAL], kde NORMAL je stav. Nepodarilo sa spracovať \"%s\"" - -#: ../src/ui/theme.c:1171 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "V špecifikácii farby je nerozpoznaný stav \"%s\"" +"Celkový počet preťahovateľných okrajov. Ak nestačia viditeľné okraje, " +"nastavené témou, budú pridané neviditeľné okraje až do požadovanej hodnoty." -#: ../src/ui/theme.c:1184 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "V špecifikácii farby je nerozpoznaný komponent \"%s\"" +# summary +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "Automaticky maximalizovať okná podobnej veľkosti ako je monitor" -#: ../src/ui/theme.c:1214 -#, c-format +# description +#: data/org.gnome.mutter.gschema.xml.in:90 msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." msgstr "" -"Formát miešania je \"blend/bg_color/fg_color/alpha\", \"%s\" tomu neodpovedá" - -#: ../src/ui/theme.c:1225 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "Nepodarilo sa spracovať hodnotu alfa \"%s\" v miešanej farbe" +"Ak je povolené, nové okná inicializované na veľkosť monitora budú " +"automaticky maximalizované." -#: ../src/ui/theme.c:1235 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "Hodnota alfa \"%s\" v miešanej farbe nie je medzi 0.0 a 1.0" +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Umiestniť nové okná do stredu" -#: ../src/ui/theme.c:1282 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:99 msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "Formát tieňa je \"shade/base_color/factor\", \"%s\" tomu neodpovedá" - -#: ../src/ui/theme.c:1293 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "Nepodarilo sa spracovať hodnotu tieňa \"%s\" v tieňovanej farbe" - -#: ../src/ui/theme.c:1303 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "Faktor tieňa \"%s\" v tieňovanej farbe je záporný." - -#: ../src/ui/theme.c:1332 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Nepodarilo sa spracovať farbu \"%s\"" - -#: ../src/ui/theme.c:1582 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "Výraz umiestnenia obsahuje znak '%s', ktorý nie je povolený" - -#: ../src/ui/theme.c:1609 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." msgstr "" -"Výraz umiestnenia obsahuje reálne číslo '%s', ktoré nie je možné spracovať." +"Ak je nastavené na true, budú nové okná vždy umiestnené v strede aktívnej " +"obrazovky monitoru." -#: ../src/ui/theme.c:1623 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "" -"Výraz umiestnenia obsahuje celé číslo '%s', ktoré nie je možné spracovať." +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Povoliť experimentálne funkcie" -#: ../src/ui/theme.c:1745 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:108 msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes " +"mutter request a low priority real-time scheduling. The executable or user " +"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — " +"initializes Xwayland lazily if there are X11 clients. Requires restart." msgstr "" -"Výraz umiestnenia obsahuje neznámy operátor na začiatku tohto textu: \"%s\"" - -#: ../src/ui/theme.c:1802 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "Výraz umiestnenia je prázdny alebo nerozpoznaný" -#: ../src/ui/theme.c:1913 ../src/ui/theme.c:1923 ../src/ui/theme.c:1957 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "Výsledok výrazu umiestnenia je delenie nulou" +#: data/org.gnome.mutter.gschema.xml.in:134 +msgid "Modifier to use to locate the pointer" +msgstr "Modifikátor použitý na lokalizovanie ukazovateľa" -#: ../src/ui/theme.c:1965 -#, c-format -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" +#: data/org.gnome.mutter.gschema.xml.in:135 +msgid "This key will initiate the “locate pointer” action." msgstr "" -"Výraz umiestnenia sa snaží použiť operátor modulo na číslo s desatinnými " -"miestami" - -#: ../src/ui/theme.c:2021 -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "Výraz umiestnenia obsahuje operátor \"%s\" tam, kde sa očakáva operand" - -#: ../src/ui/theme.c:2030 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "Výraz umiestnenia obsahuje operand tam, kde sa očakáva operátor" -#: ../src/ui/theme.c:2038 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "Výraz umiestnenia skončil operátorom namiesto operandom" - -#: ../src/ui/theme.c:2048 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" +#: data/org.gnome.mutter.gschema.xml.in:142 +msgid "Timeout for check-alive ping" msgstr "" -"Výraz umiestnenia obsahuje operátor \"%c\" za operátorom \"%c\" bez " -"operandov medzi nimi." - -#: ../src/ui/theme.c:2195 ../src/ui/theme.c:2236 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "Výraz umiestnenia obsahuje neznámu premennú alebo konštantu \"%s\"" - -#: ../src/ui/theme.c:2290 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "Výraz umiestnenia spôsobil preťaženie vyrovnávacej pamäte analyzátora" - -#: ../src/ui/theme.c:2319 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "Výraz umiestnenia obsahuje zatváraciu zátvorku bez otváracej zátvorky" -#: ../src/ui/theme.c:2383 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "Výraz umiestnenia má otváraciu zátvorku bez zatváracej zátvorky" - -#: ../src/ui/theme.c:2394 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "Výraz umiestnenia asi neobsahuje žiadne operátory ani operandy" - -#: ../src/ui/theme.c:2596 ../src/ui/theme.c:2616 ../src/ui/theme.c:2636 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "Téma obsahuje výraz, ktorý spôsobil chybu: %s\n" - -#: ../src/ui/theme.c:4203 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:143 msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" +"Number of milliseconds a client has to respond to a ping request in order to " +"not be detected as frozen. Using 0 will disable the alive check completely." msgstr "" -"Pre tento štýl rámca musí byť uvedené <button function=\"%s\" state=\"%s\" " -"draw_ops=\"whatever\"/>" -#: ../src/ui/theme.c:4711 ../src/ui/theme.c:4736 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" -"Chýbajúce <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" +# summary +#: data/org.gnome.mutter.gschema.xml.in:165 +msgid "Select window from tab popup" +msgstr "Vybrať okno z rozbaľovacej ponuky tabulátora" -#: ../src/ui/theme.c:4780 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Nepodarilo sa prečítať tému \"%s\": %s\n" +# summary +#: data/org.gnome.mutter.gschema.xml.in:170 +msgid "Cancel tab popup" +msgstr "Zrušit rozbaľovaciu ponuku tabulátora" -#: ../src/ui/theme.c:4910 ../src/ui/theme.c:4917 ../src/ui/theme.c:4924 -#: ../src/ui/theme.c:4931 ../src/ui/theme.c:4938 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "Pre tému \"%s\" nie je nastavené <%s>" +# PK: predpokladam ze to prepisane medzi tlacidlami +# description +#: data/org.gnome.mutter.gschema.xml.in:175 +msgid "Switch monitor configurations" +msgstr "Prepnúť nastavenia monitorov" -#: ../src/ui/theme.c:4946 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" -"Pre typ okna \"%s\" nie je sada štýlov v téme \"%s\", pridajte prvok <window " -"type=\"%s\" style_set=\"whatever\"/>" +#: data/org.gnome.mutter.gschema.xml.in:180 +msgid "Rotates the built-in monitor configuration" +msgstr "Otočí nastavenie vstavaného monitora" -#: ../src/ui/theme.c:5389 ../src/ui/theme.c:5451 ../src/ui/theme.c:5514 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "Používateľské konštanty musia začínať veľkým písmenom, \"%s\" nezačína" +# description +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Prepnúť na VT č. 1" -#: ../src/ui/theme.c:5397 ../src/ui/theme.c:5459 ../src/ui/theme.c:5522 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "Konštanta \"%s\" už je definovaná" +# description +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Prepnúť na VT č. 2" -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. -#. -#: ../src/ui/theme-parser.c:202 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "Chýbajúci atribút \"%s\" v prvku <%s>" +# description +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Prepnúť na VT č. 3" -#: ../src/ui/theme-parser.c:231 ../src/ui/theme-parser.c:249 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Riadok %d znak %d: %s" +# description +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Prepnúť na VT č. 4" -#: ../src/ui/theme-parser.c:413 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "Atribút \"%s\" je uvedený dvakrát v jednom prvku <%s>" +# description +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Prepnúť na VT č. 5" -#: ../src/ui/theme-parser.c:437 ../src/ui/theme-parser.c:480 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "Atribút \"%s\" je neplatný v tomto kontexte v prvku <%s>" +# description +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Prepnúť na VT č. 6" -#: ../src/ui/theme-parser.c:522 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "Nepodarilo sa spracovať \"%s\" ako celé číslo" +# description +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Prepnúť na VT č. 7" -#: ../src/ui/theme-parser.c:531 ../src/ui/theme-parser.c:586 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "Nerozpoznané znaky na konci \"%s\" v reťazci \"%s\"" +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Prepnúť na VT č. 8" -#: ../src/ui/theme-parser.c:541 -#, c-format -msgid "Integer %ld must be positive" -msgstr "Celé číslo %ld musí byť kladné" +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Prepnúť na VT č. 9" -#: ../src/ui/theme-parser.c:549 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "Celé číslo %ld je príliš veľké, maximum je %d" +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Prepnúť na VT č. 10" -#: ../src/ui/theme-parser.c:577 ../src/ui/theme-parser.c:693 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "" -"Nepodarilo sa spracovať \"%s\" ako číslo s plávajúcou desatinnou čiarkou" +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Prepnúť na VT č. 11" -#: ../src/ui/theme-parser.c:608 ../src/ui/theme-parser.c:636 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "Pravdivostná hodnota musí byť \"true\" alebo \"false\", nie \"%s\"" +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Prepnúť na VT č. 12" -#: ../src/ui/theme-parser.c:663 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "Uhol musí byť medzi 0.0 a 360.0, a teraz je %g\n" +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "Znovu povoliť klávesové skratky" -#: ../src/ui/theme-parser.c:726 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow X11 grabs to lock keyboard focus with Xwayland" msgstr "" -"Alfa musí byť medzi 0.0 (neviditeľné) a 1.0 (úplne nakreslené), a je %g\n" -#: ../src/ui/theme-parser.c:791 -#, c-format +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" +"Allow all keyboard events to be routed to X11 “override redirect” windows " +"with a grab when running in Xwayland. This option is to support X11 clients " +"which map an “override redirect” window (which do not receive keyboard " +"focus) and issue a keyboard grab to force all keyboard events to that " +"window. This option is seldom used and has no effect on regular X11 windows " +"which can receive keyboard focus under normal circumstances. For a X11 grab " +"to be taken into account under Wayland, the client must also either send a " +"specific X11 ClientMessage to the root window or be among the applications " +"white-listed in key “xwayland-grab-access-rules”." msgstr "" -"Neplatná mierka titulku \"%s\" (musí byť xx-small,x-small,small,medium,large," -"x-large,xx-large)\n" - -#: ../src/ui/theme-parser.c:936 ../src/ui/theme-parser.c:999 -#: ../src/ui/theme-parser.c:1033 ../src/ui/theme-parser.c:1136 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "Názov <%s> pre \"%s\" použitý dvakrát" - -#: ../src/ui/theme-parser.c:948 ../src/ui/theme-parser.c:1045 -#: ../src/ui/theme-parser.c:1148 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "Nedefinovaný rodič <%s> pre \"%s\"" - -#: ../src/ui/theme-parser.c:1058 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "Nedefinovaná geometria <%s> pre \"%s\"" - -#: ../src/ui/theme-parser.c:1071 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "<%s> musí uvádzať buď geometriu alebo rodiča, ktorý má geometriu" - -#: ../src/ui/theme-parser.c:1113 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "Ak má byť hodnota alpha zmysluplná, tak musíte vybrať nejaké pozadie" - -#: ../src/ui/theme-parser.c:1180 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Neznámy typ \"%s\" v prvku <%s>" - -#: ../src/ui/theme-parser.c:1191 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "Neznámy style_set \"%s\" v prvku <%s>" -#: ../src/ui/theme-parser.c:1199 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "Typ okna \"%s\" už má priradenú sadu štýlov" - -#: ../src/ui/theme-parser.c:1229 ../src/ui/theme-parser.c:1293 -#: ../src/ui/theme-parser.c:1519 ../src/ui/theme-parser.c:2740 -#: ../src/ui/theme-parser.c:2786 ../src/ui/theme-parser.c:2934 -#: ../src/ui/theme-parser.c:3126 ../src/ui/theme-parser.c:3164 -#: ../src/ui/theme-parser.c:3202 ../src/ui/theme-parser.c:3240 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "Prvok <%s> nie je povolený v <%s>" - -#: ../src/ui/theme-parser.c:1343 ../src/ui/theme-parser.c:1357 -#: ../src/ui/theme-parser.c:1402 -msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" +#: data/org.gnome.mutter.wayland.gschema.xml.in:84 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:85 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." msgstr "" -"Pre tlačidlá nie je možné zadať zároveň \"button_width\"/\"button_height\" " -"spolu s \"aspect_ratio\"" -#: ../src/ui/theme-parser.c:1366 +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. +#. +#: src/backends/meta-input-settings.c:2631 #, c-format -msgid "Distance \"%s\" is unknown" -msgstr "Vzdialenosť \"%s\" je neznáma" +msgid "Mode Switch (Group %d)" +msgstr "Prepínač režimu (skupina č. %d)" -#: ../src/ui/theme-parser.c:1411 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "Pomer strán \"%s\" je neznámy" +# PK: predpokladam ze to prepisane medzi tlacidlami +# description +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2654 +msgid "Switch monitor" +msgstr "Prepnúť monitor" -#: ../src/ui/theme-parser.c:1473 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "Okraj \"%s\" je neznámy" +#: src/backends/meta-input-settings.c:2656 +msgid "Show on-screen help" +msgstr "Zobraziť pomocníka na obrazovke" -#: ../src/ui/theme-parser.c:1784 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "Chýba atribút \"start_angle\" alebo \"from\" v prvku <%s>" +#: src/backends/meta-monitor.c:226 +msgid "Built-in display" +msgstr "Vstavaný displej" -#: ../src/ui/theme-parser.c:1791 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "Chýba atribút \"extent_angle\" alebo \"to\" v prvku <%s>" +#: src/backends/meta-monitor.c:255 +msgid "Unknown" +msgstr "Neznámy" -#: ../src/ui/theme-parser.c:2031 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "Nerozpoznaná hodnota \"%s\" pre typ prechodu" +#: src/backends/meta-monitor.c:257 +msgid "Unknown Display" +msgstr "Neznámy displej" -#: ../src/ui/theme-parser.c:2109 ../src/ui/theme-parser.c:2484 +#: src/backends/meta-monitor.c:265 #, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "Nerozpoznaný typ výplne \"%s\" pre prvok <%s>" +#| msgid "%s %s" +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme-parser.c:2276 ../src/ui/theme-parser.c:2359 -#: ../src/ui/theme-parser.c:2422 +#: src/backends/meta-monitor.c:273 #, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "Nerozpoznaný stav \"%s\" pre prvok <%s>" +#| msgid "%s %s" +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme-parser.c:2286 ../src/ui/theme-parser.c:2369 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "Nerozpoznaný tieň \"%s\" pre prvok <%s>" +#. Translators: this string will appear in Sysprof +#: src/backends/meta-profiler.c:79 +msgid "Compositor" +msgstr "Kompozítor" -#: ../src/ui/theme-parser.c:2296 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:533 #, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "Nerozpoznaná šípka \"%s\" pre prvok <%s>" +msgid "" +"Another compositing manager is already running on screen %i on display “%s”." +msgstr "" +"Pre obrazovku č. %i na displeji „%s“ je spustený už iný správca rozloženia." -#: ../src/ui/theme-parser.c:2596 ../src/ui/theme-parser.c:2692 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "Nebola definovaná <draw_ops> nazvaná \"%s\"" +#: src/core/bell.c:192 +msgid "Bell event" +msgstr "Udalosť zvončeka" -#: ../src/ui/theme-parser.c:2608 ../src/ui/theme-parser.c:2704 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "Pridaním draw_ops \"%s\" na tomto mieste vznikne cyklická referencia" +# cmd desc +#: src/core/main.c:190 +msgid "Disable connection to session manager" +msgstr "Zakáže pripojenia k správcovi relácií" -#: ../src/ui/theme-parser.c:2819 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Neznáma pozícia \"%s\" pre časť rámca" +# cmd desc +#: src/core/main.c:196 +msgid "Replace the running window manager" +msgstr "Nahradí bežiaceho správcu okien" -#: ../src/ui/theme-parser.c:2827 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "Štýl rámca už má časť na pozícii %s" +# cmd desc +#: src/core/main.c:202 +msgid "Specify session management ID" +msgstr "Zadá identifikátor správy relácií" -#: ../src/ui/theme-parser.c:2844 ../src/ui/theme-parser.c:2919 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "Nebola definovaná <draw_ops> nazvaná \"%s\"" +#: src/core/main.c:207 +msgid "X Display to use" +msgstr "X displej, ktorý bude použitý" -#: ../src/ui/theme-parser.c:2873 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Neznáma funkcia \"%s\" pre tlačidlo" +# cmd desc +#: src/core/main.c:213 +msgid "Initialize session from savefile" +msgstr "Inicializuje reláciu z uloženého súboru" -#: ../src/ui/theme-parser.c:2882 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "Funkcia tlačidla \"%s\" v tejto verzii neexistuje (%d, potrebná %d)" +# cmd desc +#: src/core/main.c:219 +msgid "Make X calls synchronous" +msgstr "Použije synchrónne volania X" -#: ../src/ui/theme-parser.c:2894 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Neznámy stav \"%s\" pre tlačidlo" +# cmd desc +#: src/core/main.c:226 +msgid "Run as a wayland compositor" +msgstr "Spustí ako kompozitor protokolu wayland" -#: ../src/ui/theme-parser.c:2902 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "Štýl rámca už má tlačidlo pre funkciu %s stav %s" +# cmd desc +#: src/core/main.c:232 +msgid "Run as a nested compositor" +msgstr "Spustí ako kompozitor s vnoreným režimom" -#: ../src/ui/theme-parser.c:2973 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "\"%s\" nie je platná hodnota pre atribút fokusu" +#: src/core/main.c:238 +msgid "Run wayland compositor without starting Xwayland" +msgstr "" -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "\"%s\" nie je platná hodnota pre atribút stavu" +#: src/core/main.c:246 +msgid "Run as a full display server, rather than nested" +msgstr "Spustí ako plnohodnotný zobrazovací server, namiesto vnoreného režimu" -#: ../src/ui/theme-parser.c:2992 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "Štýl \"%s\" nie je definovaný" +#: src/core/main.c:252 +msgid "Run with X11 backend" +msgstr "Spustí s obslužným programom X11" -#: ../src/ui/theme-parser.c:3013 ../src/ui/theme-parser.c:3036 +# %s is a window title +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:151 #, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "\"%s\" nie je platná hodnota pre atribút zmeny veľkosti" +msgid "“%s” is not responding." +msgstr "„%s“ neodpovedá." -#: ../src/ui/theme-parser.c:3047 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" -"Pre prvok <%s> by nemal byť atribút \"resize\" pre stavy maximalizované/" -"zabalené" +#: src/core/meta-close-dialog-default.c:153 +msgid "Application is not responding." +msgstr "Aplikácia neodpovedá." -#: ../src/ui/theme-parser.c:3061 -#, c-format +#: src/core/meta-close-dialog-default.c:158 msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." msgstr "" -"Pre prvok <%s> by nemal byť atribút \"resize\" pre maximalizované stavy" +"Môžete chvíľu počkať na pokračovanie aplikácie, alebo ju môžete ukončiť." -#: ../src/ui/theme-parser.c:3075 ../src/ui/theme-parser.c:3097 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "Pre stav %s zmena veľkosti %s fokus %s už bol štýl definovaný" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Force Quit" +msgstr "_Vynútiť ukončenie" -#: ../src/ui/theme-parser.c:3086 ../src/ui/theme-parser.c:3108 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "Pre stav %s fokus %s už bol štýl definovaný" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Wait" +msgstr "_Počkať" -#: ../src/ui/theme-parser.c:3147 +#: src/core/mutter.c:38 +#, c-format msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" msgstr "" -"Pre prvok <piece> nie je možné mať dve draw_ops (téma obsahuje atribút " -"draw_ops a aj prvok <draw_ops>, prípadne dva rovnaké prvky)" +"mutter %s\n" +"Autorské práva © 2001-%d Havoc Pennington, Red Hat, Inc., a ostatní\n" +"Toto je slobodný softvér; pozrite podmienky kopírovania v zdrojových " +"kódoch.\n" +"Záruka sa NEPOSKYTUJE; ani na PREDAJNOSŤ alebo VHODNOSŤ PRE URČITÝ ÚČEL.\n" -#: ../src/ui/theme-parser.c:3185 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Pre prvok <button> nie je možné mať dve draw_ops (téma obsahuje atribút " -"draw_ops a aj prvok <draw_ops>, prípadne dva rovnaké prvky)" +# cmd desc +#: src/core/mutter.c:52 +msgid "Print version" +msgstr "Zobrazí verziu" -#: ../src/ui/theme-parser.c:3223 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Pre prvok <menu_icon> nie je možné mať dve draw_ops (téma obsahuje atribút " -"draw_ops a aj prvok <draw_ops>, prípadne dva rovnaké prvky)" +# cmd desc +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "Použije zásuvný modul Mutter" -#: ../src/ui/theme-parser.c:3271 +#: src/core/prefs.c:1911 #, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "Najvyšším prvkom témy musí byť <metacity_theme>, nie <%s>" +msgid "Workspace %d" +msgstr "Pracovný priestor č. %d" -#: ../src/ui/theme-parser.c:3291 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "" -"Prvok <%s> nie je povolený v popisnom prvku name/author/date/description" +#: src/core/util.c:122 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter bol skompilovaný bez výpisu podrobností pri behu\n" -#: ../src/ui/theme-parser.c:3296 +#: src/wayland/meta-wayland-tablet-pad.c:568 #, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "Prvok <%s> nie je povolený v prvku <constant>" +msgid "Mode Switch: Mode %d" +msgstr "Prepínač režimu: Režim č. %d" -#: ../src/ui/theme-parser.c:3308 +#: src/x11/meta-x11-display.c:676 #, c-format msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "Prvok <%s> nie je povolený v prvku vzdialenosti/okrajov/pomeru strán" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." +msgstr "" +"Displej „%s“ už má správcu okien. Skúste použiť prepínač --replace, aby sa " +"aktuálny správca nahradil." -#: ../src/ui/theme-parser.c:3330 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "Prvok <%s> nie je povolený v prvku operácie pre kreslenie" +#: src/x11/meta-x11-display.c:1089 +msgid "Failed to initialize GDK\n" +msgstr "Zlyhala inicializácia GDK\n" -#: ../src/ui/theme-parser.c:3340 ../src/ui/theme-parser.c:3370 -#: ../src/ui/theme-parser.c:3375 ../src/ui/theme-parser.c:3380 +# X window system preloz, napr. system na spravu okien X +#: src/x11/meta-x11-display.c:1113 #, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "Prvok <%s> nie je povolený v prvku <%s>" - -#: ../src/ui/theme-parser.c:3602 -msgid "No draw_ops provided for frame piece" -msgstr "Pre časť rámu nie je uvedená operácia draw_ops" +msgid "Failed to open X Window System display “%s”\n" +msgstr "Zlyhalo otvorenie displeja systému na správu okien X „%s“\n" -#: ../src/ui/theme-parser.c:3617 -msgid "No draw_ops provided for button" -msgstr "Pre tlačidlo nie je uvedená operácia draw_ops" - -#: ../src/ui/theme-parser.c:3669 +#: src/x11/meta-x11-display.c:1196 #, c-format -msgid "No text is allowed inside element <%s>" -msgstr "V prvku <%s> nie je povolený žiadny text" +msgid "Screen %d on display “%s” is invalid\n" +msgstr "Obrazovka č. %d na displeji „%s“ nie je platná\n" -#: ../src/ui/theme-parser.c:3724 ../src/ui/theme-parser.c:3736 -#: ../src/ui/theme-parser.c:3748 ../src/ui/theme-parser.c:3760 -#: ../src/ui/theme-parser.c:3772 +#: src/x11/meta-x11-selection-input-stream.c:460 #, c-format -msgid "<%s> specified twice for this theme" -msgstr "<%s> uvedený dvakrát pre túto tému" +msgid "Format %s not supported" +msgstr "Formát %s nie je podporovaný" -#: ../src/ui/theme-parser.c:4040 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Nepodarilo sa nájsť platný súbor pre tému%s\n" +#: src/x11/session.c:1821 +msgid "" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." +msgstr "" +"Tieto okná nepodporujú „uloženie aktuálnych nastavení“ a pri budúcom " +"prihlásení ich budete musieť znovu spustiť ručne." -#: ../src/ui/theme-parser.c:4096 +# window title; wm_client_machine +#: src/x11/window-props.c:569 #, c-format -msgid "Theme file %s did not contain a root <metacity_theme> element" -msgstr "Súbor témy %s neobsahuje koreňový prvok <metacity_theme>" - -#: ../src/ui/theme-viewer.c:75 -msgid "/_Windows" -msgstr "/_Okná" - -#: ../src/ui/theme-viewer.c:76 -msgid "/Windows/tearoff" -msgstr "/Okná/odtrhávatko" - -#: ../src/ui/theme-viewer.c:77 -msgid "/Windows/_Dialog" -msgstr "/Okná/_Dialógové okno" - -#: ../src/ui/theme-viewer.c:78 -msgid "/Windows/_Modal dialog" -msgstr "/Okná/_Modálne dialógové okno" - -#: ../src/ui/theme-viewer.c:79 -msgid "/Windows/_Utility" -msgstr "/Okná/_Nástroje" - -#: ../src/ui/theme-viewer.c:80 -msgid "/Windows/_Splashscreen" -msgstr "/Okná/Ú_vodná obrazovka" +msgid "%s (on %s)" +msgstr "%s (na %s)" -#: ../src/ui/theme-viewer.c:81 -msgid "/Windows/_Top dock" -msgstr "/Okná/_Horný dok" +# description +#~ msgid "Move window one workspace to the left" +#~ msgstr "Presunúť okno o jeden pracovný priestor vľavo" -#: ../src/ui/theme-viewer.c:82 -msgid "/Windows/_Bottom dock" -msgstr "/Okná/_Spodný dok" +# description +#~ msgid "Move window one workspace to the right" +#~ msgstr "Presunúť okno o jeden pracovný priestor vpravo" -#: ../src/ui/theme-viewer.c:83 -msgid "/Windows/_Left dock" -msgstr "/Okná/Ľ_avý dok" +# description +#~ msgid "Move to workspace left" +#~ msgstr "Presunúť na pracovný priestor vľavo" -#: ../src/ui/theme-viewer.c:84 -msgid "/Windows/_Right dock" -msgstr "/Okná/_Pravý dok" +# description +#~ msgid "Move to workspace right" +#~ msgstr "Presunúť na pracovný priestor vpravo" -#: ../src/ui/theme-viewer.c:85 -msgid "/Windows/_All docks" -msgstr "/Okná/_Všetky doky" +# description +#~ msgid "Toggle shaded state" +#~ msgstr "Prepnúť stav zatienenia" -#: ../src/ui/theme-viewer.c:86 -msgid "/Windows/Des_ktop" -msgstr "/Okná/Praco_vná plocha" +#~ msgid "background texture could not be created from file" +#~ msgstr "nepodarilo sa vytvoriť textúru pozadia zo súboru" -#: ../src/ui/theme-viewer.c:244 -msgid "This is a sample message in a sample dialog" -msgstr "Toto je ukážková správa v ukážkovom dialógovom okne" +#~ msgid "Unknown window information request: %d" +#~ msgstr "Neznáma požiadavka na informácie o okne: %d" -#: ../src/ui/theme-viewer.c:327 -#, c-format -msgid "Fake menu item %d\n" -msgstr "Vymyslená položka ponuky %d\n" +#~ msgid "Missing %s extension required for compositing" +#~ msgstr "Rozšírenie %s, potrebné pre kompozitné prostredie, chýba" -#: ../src/ui/theme-viewer.c:361 -msgid "Border-only window" -msgstr "Okno len s okrajom" +#~ msgid "" +#~ "Some other program is already using the key %s with modifiers %x as a " +#~ "binding\n" +#~ msgstr "" +#~ "Iný program už používa kláves %s s modifikátormi %x ako klávesovú " +#~ "skratku\n" -#: ../src/ui/theme-viewer.c:363 -msgid "Bar" -msgstr "Lišta" +#~ msgid "\"%s\" is not a valid accelerator\n" +#~ msgstr "„%s“ nie je platný akcelerátor\n" -#: ../src/ui/theme-viewer.c:380 -msgid "Normal Application Window" -msgstr "Normálne aplikačné okno" +#~ msgid "Failed to scan themes directory: %s\n" +#~ msgstr "Zlyhalo prehľadanie adresára s témami: %s\n" -#: ../src/ui/theme-viewer.c:384 -msgid "Dialog Box" -msgstr "Dialógové okno" +#~ msgid "" +#~ "Could not find a theme! Be sure %s exists and contains the usual themes.\n" +#~ msgstr "" +#~ "Nepodarilo sa nájsť tému! Overte, že %s existuje a obsahuje obvyklé " +#~ "témy.\n" -#: ../src/ui/theme-viewer.c:388 -msgid "Modal Dialog Box" -msgstr "Modálne dialógové okno" +#~ msgid "" +#~ "Workarounds for broken applications disabled. Some applications may not " +#~ "behave properly.\n" +#~ msgstr "" +#~ "Náhradné riešenia pre chybné aplikácie nie sú povolené. Niektoré " +#~ "aplikácie sa nemusia správať správne.\n" -#: ../src/ui/theme-viewer.c:392 -msgid "Utility Palette" -msgstr "Paleta nástrojov" +#~ msgid "Could not parse font description \"%s\" from GSettings key %s\n" +#~ msgstr "Nepodarilo sa spracovať popis písma „%s“ z kľúča GSettings %s\n" -#: ../src/ui/theme-viewer.c:396 -msgid "Torn-off Menu" -msgstr "Vypnúť ponuku" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" +#~ msgstr "" +#~ "V konfiguračnej databáze sa našlo „%s“, čo nie je platná hodnota pre " +#~ "modifikátor tlačidla myši\n" -#: ../src/ui/theme-viewer.c:400 -msgid "Border" -msgstr "Okraj" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for " +#~ "keybinding \"%s\"\n" +#~ msgstr "" +#~ "V konfiguračnej databáze sa našlo „%s“, čo nie je platná hodnota pre " +#~ "klávesovú skratku „%s“\n" -#: ../src/ui/theme-viewer.c:728 -#, c-format -msgid "Button layout test %d" -msgstr "Test rozloženia tlačidiel %d" +#~ msgid "" +#~ "Could not acquire window manager selection on screen %d display \"%s\"\n" +#~ msgstr "" +#~ "Nepodarilo sa získať výber správcu okien pre obrazovku č. %d na displeji " +#~ "„%s“\n" -#: ../src/ui/theme-viewer.c:757 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g milisekúnd pre vykreslenie jedného rámca okna" +#~ msgid "Screen %d on display \"%s\" already has a window manager\n" +#~ msgstr "Obrazovka č. %d na displeji „%s“ už má správcu okien\n" -#: ../src/ui/theme-viewer.c:800 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Použitie: metacity-theme-viewer [NÁZOVTÉMY]\n" +#~ msgid "Could not release screen %d on display \"%s\"\n" +#~ msgstr "Nepodarilo sa uvoľniť obrazovku č. %d na displeji „%s“\n" -#: ../src/ui/theme-viewer.c:807 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "Chyba pri načítavaní témy: %s\n" +#~ msgid "Could not create directory '%s': %s\n" +#~ msgstr "Nepodarilo sa vytvoriť adresár „%s“: %s\n" -#: ../src/ui/theme-viewer.c:813 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "Téma \"%s\" načítaná za %g sekúnd\n" +#~ msgid "Could not open session file '%s' for writing: %s\n" +#~ msgstr "Nepodarilo sa otvoriť súbor relácie „%s“ pre zápis: %s\n" -#: ../src/ui/theme-viewer.c:854 -msgid "Normal Title Font" -msgstr "Obyčajné písmo nadpisu" +#~ msgid "Error writing session file '%s': %s\n" +#~ msgstr "Chyba pri zápise súboru relácie „%s“: %s\n" -#: ../src/ui/theme-viewer.c:860 -msgid "Small Title Font" -msgstr "Malé písmo nadpisu" +#~ msgid "Error closing session file '%s': %s\n" +#~ msgstr "Chyba pri zatváraní súboru relácie „%s“: %s\n" -#: ../src/ui/theme-viewer.c:866 -msgid "Large Title Font" -msgstr "Veľké písmo nadpisu" +#~ msgid "Failed to parse saved session file: %s\n" +#~ msgstr "Zlyhalo spracovanie uloženého súboru relácie: %s\n" -#: ../src/ui/theme-viewer.c:871 -msgid "Button Layouts" -msgstr "Rozloženia tlačidiel" +#~ msgid "<mutter_session> attribute seen but we already have the session ID" +#~ msgstr "" +#~ "Našiel sa atribút <mutter_session>, ale identifikátor relácie už je " +#~ "nastavený" -#: ../src/ui/theme-viewer.c:876 -msgid "Benchmark" -msgstr "Test rýchlosti" +#~ msgid "Unknown attribute %s on <%s> element" +#~ msgstr "Neznámy atribút %s v prvku <%s>" -#: ../src/ui/theme-viewer.c:923 -msgid "Window Title Goes Here" -msgstr "Sem príde názov okna" +#~ msgid "nested <window> tag" +#~ msgstr "vnorená značka <window>" -#: ../src/ui/theme-viewer.c:1027 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"Vykreslených %d rámcov za %g sekúnd na strane klienta (%g milisekúnd na " -"rámec) a %g sekúnd celkového času vrátane zdrojov X servera (%g milisekúnd " -"na rámec)\n" +#~ msgid "Unknown element %s" +#~ msgstr "Neznámy prvok %s" -#: ../src/ui/theme-viewer.c:1246 -msgid "position expression test returned TRUE but set error" -msgstr "test výrazu polohy vrátil TRUE, ale nastavil chybu" +#~ msgid "Failed to open debug log: %s\n" +#~ msgstr "Zlyhalo otvorenie záznamu pre ladenie: %s\n" -#: ../src/ui/theme-viewer.c:1248 -msgid "position expression test returned FALSE but didn't set error" -msgstr "test výrazu polohy vrátil FALSE, ale nenastavil chybu" +#~ msgid "Failed to fdopen() log file %s: %s\n" +#~ msgstr "Zlyhalo otvorenie súboru so záznamom pomocou fdopen() %s: %s\n" -#: ../src/ui/theme-viewer.c:1252 -msgid "Error was expected but none given" -msgstr "Bola očakávaná chyba, ale žiadna nenastala" +#~ msgid "Opened log file %s\n" +#~ msgstr "Otvorený súbor so záznamom %s\n" -#: ../src/ui/theme-viewer.c:1254 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "Bola očakávaná chyba %d, ale nastala %d" +#  * https://bugzilla.gnome.org/show_bug.cgi?id=698123 +#~ msgid "Window manager: " +#~ msgstr "Správca okien: " -#: ../src/ui/theme-viewer.c:1260 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "Chyba nebola očakávaná, ale bola vrátená: %s" +# * https://bugzilla.gnome.org/show_bug.cgi?id=698123 +#~ msgid "Bug in window manager: " +#~ msgstr "Chyba v správcovi okien: " -#: ../src/ui/theme-viewer.c:1264 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "hodnota x bola %d, očakávaná bola %d" +#  * https://bugzilla.gnome.org/show_bug.cgi?id=698123 +#~ msgid "Window manager warning: " +#~ msgstr "Varovanie správcu okien: " -#: ../src/ui/theme-viewer.c:1267 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "hodnota y bola %d, očakávaná bola %d" +#  * https://bugzilla.gnome.org/show_bug.cgi?id=698123 +#~ msgid "Window manager error: " +#~ msgstr "Chyba správcu okien: " -#: ../src/ui/theme-viewer.c:1332 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "" -"%d výrazov pre súradnice analyzovaných za %g sekúnd (priemer %g sekúnd)\n" +#~ msgid "" +#~ "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " +#~ "window as specified in the ICCCM.\n" +#~ msgstr "" +#~ "Okno %s nastavuje SM_CLIENT_ID na seba a nie na WM_CLIENT_LEADER, ako je " +#~ "uvedené v ICCCM.\n" #~ msgid "" -#~ "<big><b><tt>%s</tt> is not responding.</b></big>\n" -#~ "\n" -#~ "<i>You may choose to wait a short while for it to continue or force the " -#~ "application to quit entirely.</i>" +#~ "Window %s sets an MWM hint indicating it isn't resizable, but sets min " +#~ "size %d x %d and max size %d x %d; this doesn't make much sense.\n" #~ msgstr "" -#~ "<big><b><tt>%s</tt> neodpovedá.</b></big>\n" -#~ "\n" -#~ "<i>Môžete chvíľu počkať na pokračovanie aplikácie, alebo ju môžete " -#~ "násilne ukončiť.</i>" +#~ "Okno %s nastavuje radu MWM, že nie je možné zmeniť jeho veľkosť, ale " +#~ "nastavuje minimálnu veľkosť %d x %d a maximálnu veľkosť %d x %d. To " +#~ "nedáva zmysel.\n" -#~ msgid "Open another one of these windows" -#~ msgstr "Otvoriť ďalšie z týchto okien" +#~ msgid "Application set a bogus _NET_WM_PID %lu\n" +#~ msgstr "Aplikácia nastavila neplatné _NET_WM_PID %lu\n" -#~ msgid "This is a demo button with an 'open' icon" -#~ msgstr "Toto je ukážkové tlačidlo s ikonou 'otvoriť'" +#~ msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +#~ msgstr "Neplatné WM_TRANSIENT_FOR okno 0x%lx nastavené pre %s.\n" -#~ msgid "This is a demo button with a 'quit' icon" -#~ msgstr "Toto je ukážkové tlačidlo s ikonou 'ukončiť'" +# MČ: zacykliť sa, alebo vytvoriť slučku. +#~ msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" +#~ msgstr "WM_TRANSIENT_FOR okno 0x%lx pre %s môže vytvoriť slučku.\n" #~ msgid "" -#~ "Error launching metacity-dialog to warn about apps that don't support " -#~ "session management: %s\n" +#~ "Window 0x%lx has property %s\n" +#~ "that was expected to have type %s format %d\n" +#~ "and actually has type %s format %d n_items %d.\n" +#~ "This is most likely an application bug, not a window manager bug.\n" +#~ "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" #~ msgstr "" -#~ "Chyba pri spustení dialógu metacity pre varovanie o aplikácii, ktorá " -#~ "nepodporuje správu relácií: %s\n" - -#~ msgid "Title" -#~ msgstr "Titulok" +#~ "Okno 0x%lx má vlastnosť %s,\n" +#~ "ktorá by mala mať typ %s, formát %d,\n" +#~ "a v skutočnosti má typ %s a formát %d, počet položiek %d.\n" +#~ "Asi sa jedná o chybu aplikácie, a nie správcu okien.\n" +#~ "Okno má titulok „%s“, triedu „%s“ a názov „%s“\n" -#~ msgid "Class" -#~ msgstr "Trieda" +# * https://bugzilla.gnome.org/show_bug.cgi?id=697989 +#~ msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +#~ msgstr "Vlastnosť %s pre okno 0x%lx obsahuje neplatné UTF-8\n" +# * https://bugzilla.gnome.org/show_bug.cgi?id=697989 #~ msgid "" -#~ "There was an error running \"%s\":\n" -#~ "%s." +#~ "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the " +#~ "list\n" #~ msgstr "" -#~ "Pri spustení \"%s\" nastala chyba:\n" -#~ "%s" +#~ "Vlastnosť %s pre okno 0x%lx obsahuje neplatné UTF-8 pre položku č. %d v " +#~ "zozname\n" -#~ msgid "Failed to parse message \"%s\" from dialog process\n" -#~ msgstr "Nepodarilo sa spracovať správu \"%s\" z dialógového procesu\n" +#~ msgid "Mi_nimize" +#~ msgstr "Mi_nimalizovať" -#~ msgid "Error reading from dialog display process: %s\n" -#~ msgstr "Chyba pri čítaní z procesu pre zobrazenie dialógu: %s\n" +#~ msgid "Ma_ximize" +#~ msgstr "Ma_ximalizovať" -#~ msgid "" -#~ "Error launching metacity-dialog to ask about killing an application: %s\n" -#~ msgstr "" -#~ "Chyba pri spustení dialógu metacity pre nútené ukončenie aplikácie: %s\n" +#~ msgid "Unma_ximize" +#~ msgstr "Zrušiť ma_ximalizáciu" -#~ msgid "<author> specified twice for this theme" -#~ msgstr "<author> uvedený dvakrát pre túto tému" +#~ msgid "Roll _Up" +#~ msgstr "_Zabaliť" -#~ msgid "<copyright> specified twice for this theme" -#~ msgstr "<copyright> uvedený dvakrát pre túto tému" +#~ msgid "_Unroll" +#~ msgstr "_Rozbaliť" -#~ msgid "<date> specified twice for this theme" -#~ msgstr "<date> uvedený dvakrát pre túto tému" +#~ msgid "_Move" +#~ msgstr "Pre_miestniť" -#~ msgid "<description> specified twice for this theme" -#~ msgstr "<description> uvedený dvakrát pre túto tému" - -#~ msgid "" -#~ "Error launching metacity-dialog to print an error about a command: %s\n" -#~ msgstr "" -#~ "Chyba pri spustení dialógu metacity pre zobrazenie chyby príkazu: %s\n" +#~ msgid "_Resize" +#~ msgstr "Zmeniť veľko_sť" -#, fuzzy -#~ msgid "" -#~ "The keybinding used to move focus between windows of anapplication, using " -#~ "a popup window." -#~ msgstr "Prepnúť ihneď medzi oknami pomocou vyskakovacieho okna" +#~ msgid "Move Titlebar On_screen" +#~ msgstr "Presunúť titulok na _obrazovku" -#, fuzzy -#~ msgid "" -#~ "The keybinding used to move focus backwards between windowsof an " -#~ "application, using a popup window." -#~ msgstr "Prepnúť ihneď dozadu oknami aplikácie s vyskakovacím oknom" +#~ msgid "Always on _Top" +#~ msgstr "Vždy na_vrchu" -#, fuzzy -#~ msgid "" -#~ "The keybinding used to move focus between windows, using a popup window." -#~ msgstr "Prepnúť aktívne okno naspäť pomocou vyskakovacieho okna" +#~ msgid "_Always on Visible Workspace" +#~ msgstr "Vž_dy na viditeľnom pracovnom priestore" -#, fuzzy -#~ msgid "" -#~ "The keybinding used to move focus backwards between windows, using a " -#~ "popup window." -#~ msgstr "Prepnúť aktívne okno naspäť pomocou vyskakovacieho okna" +#~ msgid "_Only on This Workspace" +#~ msgstr "_Len na tomto pracovnom priestore" -#, fuzzy -#~ msgid "" -#~ "The keybinding used to move focus between panels and the desktop, using a " -#~ "popup window." -#~ msgstr "Prepnúť medzi panelmi a plochou pomocou vyskakovacieho okna" +#~ msgid "Move to Workspace _Left" +#~ msgstr "Presunúť na pracovný priestor vľav_o" -#, fuzzy -#~ msgid "" -#~ "The keybinding used to move focus backwards between panels and the " -#~ "desktop, using a popup window." -#~ msgstr "" -#~ "Prepnúť ihneď naspäť medzi panelmi a plochou pomocou vyskakovacieho okna" +#~ msgid "Move to Workspace R_ight" +#~ msgstr "Presunúť na pracovný priestor v_pravo" -#, fuzzy -#~ msgid "" -#~ "The keybinding used to move focus between windows of an application " -#~ "without a popup window." -#~ msgstr "Prepnúť ihneď medzi oknami pomocou vyskakovacieho okna" +#~ msgid "Move to Workspace _Up" +#~ msgstr "Presunúť na pracovný priestor _hore" -#, fuzzy -#~ msgid "" -#~ "The keybinding used to move focus backwards between windows of an " -#~ "application without a popup window." -#~ msgstr "Prepnúť ihneď dozadu oknami aplikácie s vyskakovacím oknom" +#~ msgid "Move to Workspace _Down" +#~ msgstr "Presunúť na pracovný priestor _dole" -#, fuzzy -#~ msgid "" -#~ "The keybinding used to move focus backwards between windows without a " -#~ "popup window." -#~ msgstr "Prepnúť aktívne okno naspäť pomocou vyskakovacieho okna" +#~ msgid "_Close" +#~ msgstr "_Zavrieť" -#, fuzzy -#~ msgid "" -#~ "The keybinding used to move focus between panels and the desktop, without " -#~ "a popup window." -#~ msgstr "Prepnúť medzi panelmi a plochou pomocou vyskakovacieho okna" +#~ msgid "Workspace %d%n" +#~ msgstr "Pracovný priestor %d%n" -#, fuzzy -#~ msgid "" -#~ "The keybinding used to move focus backwards between panels and the " -#~ "desktop, without a popup window." -#~ msgstr "" -#~ "Prepnúť ihneď naspäť medzi panelmi a plochou pomocou vyskakovacieho okna" +#~ msgid "Workspace 1_0" +#~ msgstr "Pracovný priestor 1_0" -#, fuzzy -#~ msgid "" -#~ "The keybinding which display's the panel's \"Run Application\" dialog box." -#~ msgstr "Zobraziť aplikačné dialógové okno pre spustenie programu panelu" +#~ msgid "Workspace %s%d" +#~ msgstr "Pracovný priestor %s%d" -#, fuzzy -#~ msgid "The keybinding used to toggle fullscreen mode." -#~ msgstr "Prepnúť celoobrazovkový režim" +#~ msgid "Move to Another _Workspace" +#~ msgstr "P_resunúť na iný pracovný priestor" -#~ msgid "Toggle always on top state" -#~ msgstr "Prepnúť vždy navrchu" +#~ msgid "Shift" +#~ msgstr "Shift" -#~ msgid "Unmaximize window" -#~ msgstr "Odmaximalizovať okno" +#~ msgid "Ctrl" +#~ msgstr "Ctrl" -#, fuzzy -#~ msgid "The keybinding used to move a window one workspace to the left." -#~ msgstr "Presunúť okno o jednu pracovnú plochu vľavo" +#~ msgid "Alt" +#~ msgstr "Alt" -#, fuzzy -#~ msgid "The keybinding used to move a window one workspace to the right." -#~ msgstr "Presunúť okno o jednu pracovnú plochu vpravo" +#~ msgid "Meta" +#~ msgstr "Meta" -#, fuzzy -#~ msgid "The keybinding used to move a window one workspace up." -#~ msgstr "Presunúť okno o jednu pracovnú plochu hore" +#~ msgid "Super" +#~ msgstr "Super" -#, fuzzy -#~ msgid "The keybinding used to move a window one workspace down." -#~ msgstr "Presunúť okno o jednu pracovnú plochu dolu" +#~ msgid "Hyper" +#~ msgstr "Hyper" -#, fuzzy -#~ msgid "This keybinding raises the window above other windows." -#~ msgstr "Presunúť okno dopredu nad ostatné okná" +#~ msgid "Mod2" +#~ msgstr "Mod2" -#, fuzzy -#~ msgid "This keybinding lowers a window below other windows." -#~ msgstr "Presunúť okno pod ostatné okná" +#~ msgid "Mod3" +#~ msgstr "Mod3" -#, fuzzy -#~ msgid "" -#~ "This keybinding moves a window against the north (top) side of the screen." -#~ msgstr "Presunúť okno na severnú stranu obrazovky" +#~ msgid "Mod4" +#~ msgstr "Mod4" -#, fuzzy -#~ msgid "This keybinding moves a window into the center of the screen." -#~ msgstr "Presunúť okno doprostred obrazovky" +#~ msgid "Mod5" +#~ msgstr "Mod5" -#~ msgid "" -#~ "Many actions (e.g. clicking in the client area, moving or resizing the " -#~ "window) normally raise the window as a side-effect. Setting this option " -#~ "to false, which is strongly discouraged, will decouple raising from other " -#~ "user actions, and ignore raise requests generated by applications. See " -#~ "http://bugzilla.gnome.org/show_bug.cgi?id=445447#c6." -#~ msgstr "" -#~ "Veľa akcií (napríklad kliknutie do oblasti klienta, premiestnenie alebo " -#~ "zmena veľkosti okna) obyčajne vyzdvihne okno do popredia ako vedľajší " -#~ "efekt. Nastavením tohto na false, od čoho dôrazne odrádzame, izoluje " -#~ "vyzdvihnutie od ostatných používateľských akcií a ignoruje požiadavky od " -#~ "aplikácií. Viac informácií na http://bugzilla.gnome.org/show_bug.cgi?" -#~ "id=445447#c6" +#~ msgid "%d x %d" +#~ msgstr "%d x %d" -#~ msgid "Unmaximize Window" -#~ msgstr "Zrušiť maximalizáciu okno" +#~ msgid "top" +#~ msgstr "hore" -#~ msgid "Unknown attribute %s on <metacity_session> element" -#~ msgstr "Neznámy atribút %s v prvku <metacity_session>" +#~ msgid "bottom" +#~ msgstr "dole" -#~ msgid "Unknown attribute %s on <maximized> element" -#~ msgstr "Neznámy atribút %s v prvku <maximized>" +#~ msgid "left" +#~ msgstr "vľavo" -#~ msgid "Unknown attribute %s on <geometry> element" -#~ msgstr "Neznámy atribúť %s v prvku <geometry>" +#~ msgid "right" +#~ msgstr "vpravo" -#~ msgid "" -#~ "The keybinding that switches to the workspace above the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Klávesová skratka, ktorá prepne na pracovnú plochu nad aktuálnou " -#~ "pracovnou plochou. Formát je \"<Control>a\" alebo \"<Shift>" -#~ "<Alt>F1. Spracovanie je dosť liberálne a umožňuje malé aj veľké " -#~ "písmená a skratky ako je \"<Ctl>\" a \"<Ctrl>\". Ak nastavíte " -#~ "túto možnosť na špeciálnu hodnotu \"disabled\", pre túto akciu nebude " -#~ "definovaná žiadna klávesová skratka." +#~ msgid "frame geometry does not specify \"%s\" dimension" +#~ msgstr "geometria rámca neurčuje rozmer „%s“" -#~ msgid "" -#~ "The keybinding that switches to the workspace below the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Klávesová skratka, ktorá prepne na pracovnú plochu pod aktuálnou " -#~ "pracovnou plochou. Formát je \"<Control>a\" alebo \"<Shift>" -#~ "<Alt>F1. Spracovanie je dosť liberálne a umožňuje malé aj veľké " -#~ "písmená a skratky ako je \"<Ctl>\" a \"<Ctrl>\". Ak nastavíte " -#~ "túto možnosť na špeciálnu hodnotu \"disabled\", pre túto akciu nebude " -#~ "definovaná žiadna klávesová skratka." +#~ msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" +#~ msgstr "geometria rámca neurčuje rozmer „%s“ pre okraj „%s“" -#~ msgid "" -#~ "The keybinding that switches to the workspace on the left of the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Klávesová skratka, ktorá prepne na pracovnú plochu vľavo od aktuálnej " -#~ "parcovnej plochy. Formát je \"<Control>a\" alebo \"<Shift><" -#~ "Alt>F1. Spracovanie je dosť liberálne a umožňuje malé aj veľké písmená " -#~ "a skratky ako je \"<Ctl>\" a \"<Ctrl>\". Ak nastavíte túto " -#~ "možnosť na špeciálnu hodnotu \"disabled\", pre túto akciu nebude " -#~ "definovaná žiadna klávesová skratka." +#~ msgid "Button aspect ratio %g is not reasonable" +#~ msgstr "Pomer strán tlačidla %g nedáva zmysel" -#~ msgid "" -#~ "The keybinding that switches to the workspace on the right of the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Klávesová skratka, ktorá prepne na pracovnú plochu vpravo od aktuálnej " -#~ "pracovnej plochy. Formát je \"<Control>a\" alebo \"<Shift><" -#~ "Alt>F1. Spracovanie je dosť liberálne a umožňuje malé aj veľké písmená " -#~ "a skratky ako je \"<Ctl>\" a \"<Ctrl>\". Ak nastavíte túto " -#~ "možnosť na špeciálnu hodnotu \"disabled\", pre túto akciu nebude " -#~ "definovaná žiadna klávesová skratka." +#~ msgid "Frame geometry does not specify size of buttons" +#~ msgstr "Geometria rámca neurčuje rozmer tlačidiel" -#~ msgid "" -#~ "The keybinding that switches to workspace 1. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Klávesová skratka, ktorá prepne na pracovnú plochu 1. Formát je \"<" -#~ "Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je dosť " -#~ "liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<Ctl>" -#~ "\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu hodnotu " -#~ "\"disabled\", pre túto akciu nebude definovaná žiadna klávesová skratka." +#~ msgid "Gradients should have at least two colors" +#~ msgstr "Prechody by mali mať aspoň dve farby" #~ msgid "" -#~ "The keybinding that switches to workspace 10. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "GTK custom color specification must have color name and fallback in " +#~ "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" #~ msgstr "" -#~ "Klávesová skratka, ktorá prepne na pracovnú plochu 10. Formát je \"<" -#~ "Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je dosť " -#~ "liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<Ctl>" -#~ "\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu hodnotu " -#~ "\"disabled\", pre túto akciu nebude definovaná žiadna klávesová skratka." +#~ "Špecifikácia používateľskej farby GTK musí mať názov a náhradnú hodnotu " +#~ "uzavretú v okrúhlych zátvorkách, napr. gtk:custom(foo,bar). Nepodarilo sa " +#~ "spracovať „%s“" #~ msgid "" -#~ "The keybinding that switches to workspace 11. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-" +#~ "z0-9-_ are valid" #~ msgstr "" -#~ "Klávesová skratka, ktorá prepne na pracovnú plochu 11. Formát je \"<" -#~ "Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je dosť " -#~ "liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<Ctl>" -#~ "\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu hodnotu " -#~ "\"disabled\", pre túto akciu nebude definovaná žiadna klávesová skratka." +#~ "V parametri color_name (názov farby) pre gtk:custom je neplatný znak " +#~ "„%c“, platné sú len znaky A-Za-z0-9-_" #~ msgid "" -#~ "The keybinding that switches to workspace 12. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " +#~ "fit the format" #~ msgstr "" -#~ "Klávesová skratka, ktorá prepne na pracovnú plochu 12. Formát je \"<" -#~ "Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je dosť " -#~ "liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<Ctl>" -#~ "\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu hodnotu " -#~ "\"disabled\", pre túto akciu nebude definovaná žiadna klávesová skratka." +#~ "Formát Gtk:custom je „gtk:custom(color_name,fallback)“, „%s“ tomu " +#~ "nezodpovedá" #~ msgid "" -#~ "The keybinding that switches to workspace 2. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "GTK color specification must have the state in brackets, e.g. gtk:" +#~ "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" #~ msgstr "" -#~ "Klávesová skratka, ktorá prepne na pracovnú plochu 2. Formát je \"<" -#~ "Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je dosť " -#~ "liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<Ctl>" -#~ "\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu hodnotu " -#~ "\"disabled\", pre túto akciu nebude definovaná žiadna klávesová skratka." +#~ "Špecifikácia farby GTK musí mať stav v hranatých zátvorkách, napr. gtk:" +#~ "fg[NORMAL], kde NORMAL je stav. Nepodarilo sa spracovať „%s“" #~ msgid "" -#~ "The keybinding that switches to workspace 3. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "GTK color specification must have a close bracket after the state, e.g. " +#~ "gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" #~ msgstr "" -#~ "Klávesová skratka, ktorá prepne na pracovnú plochu 3. Formát je \"<" -#~ "Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je dosť " -#~ "liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<Ctl>" -#~ "\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu hodnotu " -#~ "\"disabled\", pre túto akciu nebude definovaná žiadna klávesová skratka." +#~ "Špecifikácia farby GTK musí mať za stavom pravú hranatú zátvorku, napr. " +#~ "gtk:fg[NORMAL], kde NORMAL je stav. Nepodarilo sa spracovať „%s“" -#~ msgid "" -#~ "The keybinding that switches to workspace 4. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Klávesová skratka, ktorá prepne na pracovnú plochu 4. Formát je \"<" -#~ "Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je dosť " -#~ "liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<Ctl>" -#~ "\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu hodnotu " -#~ "\"disabled\", pre túto akciu nebude definovaná žiadna klávesová skratka." +#~ msgid "Did not understand state \"%s\" in color specification" +#~ msgstr "V špecifikácii farby je nerozpoznaný stav „%s“" -#~ msgid "" -#~ "The keybinding that switches to workspace 5. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Klávesová skratka, ktorá prepne na pracovnú plochu 5. Formát je \"<" -#~ "Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je dosť " -#~ "liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<Ctl>" -#~ "\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu hodnotu " -#~ "\"disabled\", pre túto akciu nebude definovaná žiadna klávesová skratka." +#~ msgid "Did not understand color component \"%s\" in color specification" +#~ msgstr "V špecifikácii farby je nerozpoznaný komponent „%s“" #~ msgid "" -#~ "The keybinding that switches to workspace 6. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit " +#~ "the format" #~ msgstr "" -#~ "Klávesová skratka, ktorá prepne na pracovnú plochu 6. Formát je \"<" -#~ "Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je dosť " -#~ "liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<Ctl>" -#~ "\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu hodnotu " -#~ "\"disabled\", pre túto akciu nebude definovaná žiadna klávesová skratka." +#~ "Formát miešania je „blend/bg_color/fg_color/alpha“, „%s“ tomu neodpovedá" -#~ msgid "" -#~ "The keybinding that switches to workspace 7. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Klávesová skratka, ktorá prepne na pracovnú plochu 7. Formát je \"<" -#~ "Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je dosť " -#~ "liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<Ctl>" -#~ "\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu hodnotu " -#~ "\"disabled\", pre túto akciu nebude definovaná žiadna klávesová skratka." +#~ msgid "Could not parse alpha value \"%s\" in blended color" +#~ msgstr "Nepodarilo sa spracovať hodnotu alfa „%s“ v miešanej farbe" -#~ msgid "" -#~ "The keybinding that switches to workspace 8. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Klávesová skratka, ktorá prepne na pracovnú plochu 8. Formát je \"<" -#~ "Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je dosť " -#~ "liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<Ctl>" -#~ "\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu hodnotu " -#~ "\"disabled\", pre túto akciu nebude definovaná žiadna klávesová skratka." +#~ msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" +#~ msgstr "Hodnota alfa „%s“ v miešanej farbe nie je medzi 0.0 a 1.0" #~ msgid "" -#~ "The keybinding that switches to workspace 9. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Klávesová skratka, ktorá prepne na pracovnú plochu 9. Formát je \"<" -#~ "Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je dosť " -#~ "liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<Ctl>" -#~ "\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu hodnotu " -#~ "\"disabled\", pre túto akciu nebude definovaná žiadna klávesová skratka." +#~ "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the " +#~ "format" +#~ msgstr "Formát tieňa je „shade/base_color/factor“, „%s“ tomu neodpovedá" -#~ msgid "" -#~ "The keybinding used to activate the window menu. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Klávesová skratka použitá pre aktiváciu ponuky okna. Formát je \"<" -#~ "Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je dosť " -#~ "liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<Ctl>" -#~ "\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu hodnotu " -#~ "\"disabled\", pre túto akciu nebude definovaná žiadna klávesová skratka." +#~ msgid "Could not parse shade factor \"%s\" in shaded color" +#~ msgstr "Nepodarilo sa spracovať hodnotu tieňa „%s“ v tieňovanej farbe" -#~ msgid "" -#~ "The keybinding used to enter \"move mode\" and begin moving a window " -#~ "using the keyboard. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "Klávesová skratka použitá pre vstup do \"režimu presunu\" a začiatok " -#~ "presunu okna pomocou klávesnice. Formát je \"<Control>a\" alebo " -#~ "\"<Shift><Alt>F1. Spracovanie je dosť liberálne a umožňuje " -#~ "malé aj veľké písmená a skratky ako je \"<Ctl>\" a \"<Ctrl>" -#~ "\". Ak nastavíte túto možnosť na špeciálnu hodnotu \"disabled\", pre túto " -#~ "akciu nebude definovaná žiadna klávesová skratka." +#~ msgid "Shade factor \"%s\" in shaded color is negative" +#~ msgstr "Faktor tieňa „%s“ v tieňovanej farbe je záporný" -#~ msgid "" -#~ "The keybinding used to enter \"resize mode\" and begin resizing a window " -#~ "using the keyboard. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "Klávesová skratka použitá pre vstup do \"režimu zmeny veľkosti\" a " -#~ "začiatok zmeny veľkosti okna pomocou klávesnice. Formát je \"<" -#~ "Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je dosť " -#~ "liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<Ctl>" -#~ "\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu hodnotu " -#~ "\"disabled\", pre túto akciu nebude definovaná žiadna klávesová skratka." +#~ msgid "Could not parse color \"%s\"" +#~ msgstr "Nepodarilo sa spracovať farbu „%s“" -#~ msgid "" -#~ "The keybinding used to hide all normal windows and set the focus to the " -#~ "desktop background. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "Klávesová skratka použitá pre skrytie všetkých normálnych okien a " -#~ "nastavenie ako aktívne pozadie plochy. Formát je \"<Control>a\" " -#~ "alebo \"<Shift><Alt>F1. Spracovanie je dosť liberálne a " -#~ "umožňuje malé aj veľké písmená a skratky ako je \"<Ctl>\" a \"<" -#~ "Ctrl>\". Ak nastavíte túto možnosť na špeciálnu hodnotu \"disabled\", " -#~ "pre túto akciu nebude definovaná žiadna klávesová skratka." +#~ msgid "Coordinate expression contains character '%s' which is not allowed" +#~ msgstr "Výraz umiestnenia obsahuje znak „%s“, ktorý nie je povolený" #~ msgid "" -#~ "The keybinding used to maximize a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "Coordinate expression contains floating point number '%s' which could not " +#~ "be parsed" #~ msgstr "" -#~ "Klávesová skratka použitá pre maximalizáciu okna. Formát je \"<" -#~ "Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je dosť " -#~ "liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<Ctl>" -#~ "\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu hodnotu " -#~ "\"disabled\", pre túto akciu nebude definovaná žiadna klávesová skratka." +#~ "Výraz umiestnenia obsahuje číslo s pohyblivou rádovou čiarkou „%s“, ktoré " +#~ "nie je možné spracovať" #~ msgid "" -#~ "The keybinding used to minimize a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "Coordinate expression contains integer '%s' which could not be parsed" #~ msgstr "" -#~ "Klávesová skratka použitá pre minimalizáciu okna. Formát je \"<" -#~ "Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je dosť " -#~ "liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<Ctl>" -#~ "\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu hodnotu " -#~ "\"disabled\", pre túto akciu nebude definovaná žiadna klávesová skratka." +#~ "Výraz umiestnenia obsahuje celé číslo „%s“, ktoré nie je možné spracovať" #~ msgid "" -#~ "The keybinding used to move a window one workspace down. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "Coordinate expression contained unknown operator at the start of this " +#~ "text: \"%s\"" #~ msgstr "" -#~ "Klávesová skratka použitá na presun okna o jednu pracovnú plochu dolu. " -#~ "Formát je \"<Control>a\" alebo \"<Shift><Alt>F1. " -#~ "Spracovanie je dosť liberálne a umožňuje malé aj veľké písmená a skratky " -#~ "ako je \"<Ctl>\" a \"<Ctrl>\". Ak nastavíte túto možnosť na " -#~ "špeciálnu hodnotu \"disabled\", pre túto akciu nebude definovaná žiadna " -#~ "klávesová skratka." +#~ "Výraz umiestnenia obsahuje neznámy operátor na začiatku tohto textu: „%s“" -#~ msgid "" -#~ "The keybinding used to move a window one workspace to the left. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Klávesová skratka použitá na presun okna o jednu pracovnú plochu vľavo. " -#~ "Formát je \"<Control>a\" alebo \"<Shift><Alt>F1. " -#~ "Spracovanie je dosť liberálne a umožňuje malé aj veľké písmená a skratky " -#~ "ako je \"<Ctl>\" a \"<Ctrl>\". Ak nastavíte túto možnosť na " -#~ "špeciálnu hodnotu \"disabled\", pre túto akciu nebude definovaná žiadna " -#~ "klávesová skratka." +#~ msgid "Coordinate expression was empty or not understood" +#~ msgstr "Výraz umiestnenia je prázdny alebo nerozpoznaný" -#~ msgid "" -#~ "The keybinding used to move a window one workspace to the right. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Klávesová skratka použitá na presun okna o jednu pracovnú plochu vpravo. " -#~ "Formát je \"<Control>a\" alebo \"<Shift><Alt>F1. " -#~ "Spracovanie je dosť liberálne a umožňuje malé aj veľké písmená a skratky " -#~ "ako je \"<Ctl>\" a \"<Ctrl>\". Ak nastavíte túto možnosť na " -#~ "špeciálnu hodnotu \"disabled\", pre túto akciu nebude definovaná žiadna " -#~ "klávesová skratka." +#~ msgid "Coordinate expression results in division by zero" +#~ msgstr "Výsledok výrazu umiestnenia je delenie nulou" #~ msgid "" -#~ "The keybinding used to move a window one workspace up. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "Coordinate expression tries to use mod operator on a floating-point number" #~ msgstr "" -#~ "Klávesová skratka použitá na presun okna o jednu pracovnú plochu hore. " -#~ "Formát je \"<Control>a\" alebo \"<Shift><Alt>F1. " -#~ "Spracovanie je dosť liberálne a umožňuje malé aj veľké písmená a skratky " -#~ "ako je \"<Ctl>\" a \"<Ctrl>\". Ak nastavíte túto možnosť na " -#~ "špeciálnu hodnotu \"disabled\", pre túto akciu nebude definovaná žiadna " -#~ "klávesová skratka." +#~ "Výraz umiestnenia sa snaží použiť operátor modulo na číslo s pohyblivou " +#~ "rádovou čiarkou" #~ msgid "" -#~ "The keybinding used to move a window to workspace 1. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "Coordinate expression has an operator \"%s\" where an operand was expected" #~ msgstr "" -#~ "Klávesová skratka použitá na presun okna na pracovnú plochu 1. Formát je " -#~ "\"<Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je " -#~ "dosť liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<" -#~ "Ctl>\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu " -#~ "hodnotu \"disabled\", pre túto akciu nebude definovaná žiadna klávesová " -#~ "skratka." +#~ "Výraz umiestnenia obsahuje operátor „%s“ tam, kde sa očakáva operand" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 10. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Klávesová skratka použitá na presun okna na pracovnú plochu 10. Formát je " -#~ "\"<Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je " -#~ "dosť liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<" -#~ "Ctl>\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu " -#~ "hodnotu \"disabled\", pre túto akciu nebude definovaná žiadna klávesová " -#~ "skratka." +#~ msgid "Coordinate expression had an operand where an operator was expected" +#~ msgstr "Výraz umiestnenia obsahuje operand tam, kde sa očakáva operátor" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 11. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Klávesová skratka použitá na presun okna na pracovnú plochu 11. Formát je " -#~ "\"<Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je " -#~ "dosť liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<" -#~ "Ctl>\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu " -#~ "hodnotu \"disabled\", pre túto akciu nebude definovaná žiadna klávesová " -#~ "skratka." +#~ msgid "Coordinate expression ended with an operator instead of an operand" +#~ msgstr "Výraz umiestnenia skončil operátorom namiesto operandom" #~ msgid "" -#~ "The keybinding used to move a window to workspace 12. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "Coordinate expression has operator \"%c\" following operator \"%c\" with " +#~ "no operand in between" #~ msgstr "" -#~ "Klávesová skratka použitá na presun okna na pracovnú plochu 12. Formát je " -#~ "\"<Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je " -#~ "dosť liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<" -#~ "Ctl>\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu " -#~ "hodnotu \"disabled\", pre túto akciu nebude definovaná žiadna klávesová " -#~ "skratka." +#~ "Výraz umiestnenia obsahuje operátor „%c“ za operátorom „%c“ bez operandov " +#~ "medzi nimi" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 2. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Klávesová skratka použitá na presun okna na pracovnú plochu 2. Formát je " -#~ "\"<Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je " -#~ "dosť liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<" -#~ "Ctl>\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu " -#~ "hodnotu \"disabled\", pre túto akciu nebude definovaná žiadna klávesová " -#~ "skratka." +#~ msgid "Coordinate expression had unknown variable or constant \"%s\"" +#~ msgstr "Výraz umiestnenia obsahuje neznámu premennú alebo konštantu „%s“" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 3. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ msgid "Coordinate expression parser overflowed its buffer." #~ msgstr "" -#~ "Klávesová skratka použitá na presun okna na pracovnú plochu 3. Formát je " -#~ "\"<Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je " -#~ "dosť liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<" -#~ "Ctl>\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu " -#~ "hodnotu \"disabled\", pre túto akciu nebude definovaná žiadna klávesová " -#~ "skratka." +#~ "Výraz umiestnenia spôsobil pretečenie vyrovnávacej pamäte analyzátora." #~ msgid "" -#~ "The keybinding used to move a window to workspace 4. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Klávesová skratka použitá na presun okna na pracovnú plochu 4. Formát je " -#~ "\"<Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je " -#~ "dosť liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<" -#~ "Ctl>\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu " -#~ "hodnotu \"disabled\", pre túto akciu nebude definovaná žiadna klávesová " -#~ "skratka." +#~ "Coordinate expression had a close parenthesis with no open parenthesis" +#~ msgstr "Výraz umiestnenia obsahuje pravú zátvorku bez ľavej zátvorky" #~ msgid "" -#~ "The keybinding used to move a window to workspace 5. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Klávesová skratka použitá na presun okna na pracovnú plochu 5. Formát je " -#~ "\"<Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je " -#~ "dosť liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<" -#~ "Ctl>\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu " -#~ "hodnotu \"disabled\", pre túto akciu nebude definovaná žiadna klávesová " -#~ "skratka." +#~ "Coordinate expression had an open parenthesis with no close parenthesis" +#~ msgstr "Výraz umiestnenia má ľavú zátvorku bez pravej zátvorky" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 6. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Klávesová skratka použitá na presun okna na pracovnú plochu 6. Formát je " -#~ "\"<Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je " -#~ "dosť liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<" -#~ "Ctl>\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu " -#~ "hodnotu \"disabled\", pre túto akciu nebude definovaná žiadna klávesová " -#~ "skratka." +#~ msgid "Coordinate expression doesn't seem to have any operators or operands" +#~ msgstr "Výraz umiestnenia asi neobsahuje žiadne operátory ani operandy" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 7. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Klávesová skratka použitá na presun okna na pracovnú plochu 7. Formát je " -#~ "\"<Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je " -#~ "dosť liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<" -#~ "Ctl>\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu " -#~ "hodnotu \"disabled\", pre túto akciu nebude definovaná žiadna klávesová " -#~ "skratka." +#~ msgid "Theme contained an expression that resulted in an error: %s\n" +#~ msgstr "Téma obsahuje výraz, ktorý spôsobil chybu: %s\n" #~ msgid "" -#~ "The keybinding used to move a window to workspace 8. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " +#~ "specified for this frame style" #~ msgstr "" -#~ "Klávesová skratka použitá na presun okna na pracovnú plochu 8. Formát je " -#~ "\"<Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je " -#~ "dosť liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<" -#~ "Ctl>\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu " -#~ "hodnotu \"disabled\", pre túto akciu nebude definovaná žiadna klávesová " -#~ "skratka." +#~ "Pre tento štýl rámca musí byť uvedené <button function=\"%s\" state=\"%s" +#~ "\" draw_ops=\"whatever\"/>" #~ msgid "" -#~ "The keybinding used to move a window to workspace 9. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/" +#~ ">" #~ msgstr "" -#~ "Klávesová skratka použitá na presun okna na pracovnú plochu 9. Formát je " -#~ "\"<Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je " -#~ "dosť liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<" -#~ "Ctl>\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu " -#~ "hodnotu \"disabled\", pre túto akciu nebude definovaná žiadna klávesová " -#~ "skratka." +#~ "Chýbajúce <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever" +#~ "\"/>" -#~ msgid "" -#~ "The keybinding used to move focus backwards between panels and the " -#~ "desktop, using a popup window. The format looks like \"<Control>a\" " -#~ "or \"<Shift><Alt>F1\". The parser is fairly liberal and " -#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" -#~ "\" and \"<Ctrl>\". If you set the option to the special string " -#~ "\"disabled\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "Klávesová skratka použitá na prepnutie ohniska dozadu medzi panelmi a " -#~ "plochou so zobrazením vyskakovacieho okna. Formát je \"<Control>a\" " -#~ "alebo \"<Shift><Alt>F1. Spracovanie je dosť liberálne a " -#~ "umožňuje malé aj veľké písmená a skratky ako je \"<Ctl>\" a \"<" -#~ "Ctrl>\". Ak nastavíte túto možnosť na špeciálnu hodnotu \"disabled\", " -#~ "pre túto akciu nebude definovaná žiadna klávesová skratka." +#~ msgid "Failed to load theme \"%s\": %s\n" +#~ msgstr "Zlyhalo načítanie témy „%s“: %s\n" -#~ msgid "" -#~ "The keybinding used to move focus backwards between panels and the " -#~ "desktop, without a popup window. The format looks like \"<Control>a" -#~ "\" or \"<Shift><Alt>F1\". The parser is fairly liberal and " -#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" -#~ "\" and \"<Ctrl>\". If you set the option to the special string " -#~ "\"disabled\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "Klávesová skratka použitá na prepnutie ohniska dozadu medzi panelmi a " -#~ "plochou bez zobrazenia vyskakovacieho okna. Formát je \"<Control>a" -#~ "\" alebo \"<Shift><Alt>F1. Spracovanie je dosť liberálne a " -#~ "umožňuje malé aj veľké písmená a skratky ako je \"<Ctl>\" a \"<" -#~ "Ctrl>\". Ak nastavíte túto možnosť na špeciálnu hodnotu \"disabled\", " -#~ "pre túto akciu nebude definovaná žiadna klávesová skratka." +# JK: XML značka (XML tag) +#~ msgid "No <%s> set for theme \"%s\"" +#~ msgstr "Pre tému „%s“ nie je nastavená <%s>" #~ msgid "" -#~ "The keybinding used to move focus backwards between windows of an " -#~ "application without a popup window. Holding \"shift\" together with this " -#~ "binding makes the direction go forward again. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "No frame style set for window type \"%s\" in theme \"%s\", add a <window " +#~ "type=\"%s\" style_set=\"whatever\"/> element" #~ msgstr "" -#~ "Klávesová skratka použitá na prepnutie ohniska dozadu medzi oknami bez " -#~ "zobrazenia vyskakovacieho okna. Držaním \"shift\" spolu s touto " -#~ "klávesovou skratkou znovu obrátite smer prepínania. Formát je \"<" -#~ "Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je dosť " -#~ "liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<Ctl>" -#~ "\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu hodnotu " -#~ "\"disabled\", pre túto akciu nebude definovaná žiadna klávesová skratka." +#~ "Pre typ okna „%s“ nie je sada štýlov v téme „%s“, pridajte prvok <window " +#~ "type=\"%s\" style_set=\"whatever\"/>" #~ msgid "" -#~ "The keybinding used to move focus backwards between windows of an " -#~ "application, using a popup window. Holding \"shift\" together with this " -#~ "binding makes the direction go forward again. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "User-defined constants must begin with a capital letter; \"%s\" does not" #~ msgstr "" -#~ "Klávesová skratka použitá na prepnutie ohniska dozadu medzi oknami so " -#~ "zobrazením vyskakovacieho okna. Držaním \"shift\" spolu s touto " -#~ "klávesovou skratkou znovu obrátite smer prepínania. Formát je \"<" -#~ "Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je dosť " -#~ "liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<Ctl>" -#~ "\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu hodnotu " -#~ "\"disabled\", pre túto akciu nebude definovaná žiadna klávesová skratka." +#~ "Používateľské konštanty musia začínať veľkým písmenom, „%s“ nezačína" -#~ msgid "" -#~ "The keybinding used to move focus backwards between windows without a " -#~ "popup window. Holding \"shift\" together with this binding makes the " -#~ "direction go forward again. The format looks like \"<Control>a\" or " -#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " -#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" -#~ "\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "Klávesová skratka použitá na prepnutie ohniska dozadu medzi oknami bez " -#~ "zobrazenia vyskakovacieho okna. Držaním \"shift\" spolu s touto " -#~ "klávesovou skratkou znovu obráti smer prepínania. Formát je \"<" -#~ "Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je dosť " -#~ "liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<Ctl>" -#~ "\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu hodnotu " -#~ "\"disabled\", pre túto akciu nebude definovaná žiadna klávesová skratka." +#~ msgid "Constant \"%s\" has already been defined" +#~ msgstr "Konštanta „%s“ už je definovaná" -#~ msgid "" -#~ "The keybinding used to move focus backwards between windows, using a " -#~ "popup window. Holding \"shift\" together with this binding makes the " -#~ "direction go forward again. The format looks like \"<Control>a\" or " -#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " -#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" -#~ "\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "Klávesová skratka použitá na prepnutie ohniska dozadu medzi oknami so " -#~ "zobrazením vyskakovacieho okna. Držaním \"shift\" spolu s touto " -#~ "klávesovou skratkou znovu obráti smer prepínania. Formát je \"<" -#~ "Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je dosť " -#~ "liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<Ctl>" -#~ "\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu hodnotu " -#~ "\"disabled\", pre túto akciu nebude definovaná žiadna klávesová skratka." +#~ msgid "No \"%s\" attribute on element <%s>" +#~ msgstr "Chýbajúci atribút „%s“ v prvku <%s>" -#~ msgid "" -#~ "The keybinding used to move focus between panels and the desktop, using a " -#~ "popup window. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "Klávesová skratka použitá na prepnutie ohniska medzi panelmi a pracovnou " -#~ "plochou so zobrazním vyskakovacieho okna. Formát je \"<Control>a\" " -#~ "alebo \"<Shift><Alt>F1. Spracovanie je dosť liberálne a " -#~ "umožňuje malé aj veľké písmená a skratky ako je \"<Ctl>\" a \"<" -#~ "Ctrl>\". Ak nastavíte túto možnosť na špeciálnu hodnotu \"disabled\", " -#~ "pre túto akciu nebude definovaná žiadna klávesová skratka." +#~ msgid "Line %d character %d: %s" +#~ msgstr "Riadok č. %d znak č. %d: %s" -#~ msgid "" -#~ "The keybinding used to move focus between panels and the desktop, without " -#~ "a popup window. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "Klávesová skratka použitá na prepnutie ohniska medzi panelmi a pracovnou " -#~ "plochou bez zobrazenia vyskakovacieho okna. Formát je \"<Control>a" -#~ "\" alebo \"<Shift><Alt>F1. Spracovanie je dosť liberálne a " -#~ "umožňuje malé aj veľké písmená a skratky ako je \"<Ctl>\" a \"<" -#~ "Ctrl>\". Ak nastavíte túto možnosť na špeciálnu hodnotu \"disabled\", " -#~ "pre túto akciu nebude definovaná žiadna klávesová skratka." +#~ msgid "Attribute \"%s\" repeated twice on the same <%s> element" +#~ msgstr "Atribút „%s“ je uvedený dvakrát v jednom prvku <%s>" -#~ msgid "" -#~ "The keybinding used to move focus between windows of an application " -#~ "without a popup window. Holding the \"shift\" key while using this " -#~ "binding reverses the direction of movement. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Klávesová skratka použitá na prepnutie ohniska medzi oknami bez " -#~ "zobrazenia vyskakovacieho okna. Držaním \"shift\" spolu s touto " -#~ "klávesovou skratkou znovu obrátite smer prepínania. Formát je \"<" -#~ "Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je dosť " -#~ "liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<Ctl>" -#~ "\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu hodnotu " -#~ "\"disabled\", pre túto akciu nebude definovaná žiadna klávesová skratka." +#~ msgid "Attribute \"%s\" is invalid on <%s> element in this context" +#~ msgstr "Atribút „%s“ je neplatný v tomto kontexte v prvku <%s>" -#~ msgid "" -#~ "The keybinding used to move focus between windows of an application, " -#~ "using a popup window. (Traditionally <Alt>F6) Holding the \"shift\" " -#~ "key while using this binding reverses the direction of movement. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Klávesová skratka použitá na prepnutie ohniska medzi oknami so zobrazením " -#~ "vyskakovacieho okna. (Tradične <Alt>F6) Držaním \"shift\" spolu s " -#~ "touto klávesovou skratkou znovu obrátite smer prepínania. Formát je \"<" -#~ "Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je dosť " -#~ "liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<Ctl>" -#~ "\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu hodnotu " -#~ "\"disabled\", pre túto akciu nebude definovaná žiadna klávesová skratka." +#~ msgid "Could not parse \"%s\" as an integer" +#~ msgstr "Nepodarilo sa spracovať „%s“ ako celé číslo" -#~ msgid "" -#~ "The keybinding used to move focus between windows without a popup window. " -#~ "(Traditionally <Alt>Escape) Holding the \"shift\" key while using " -#~ "this binding reverses the direction of movement. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Klávesová skratka použitá na prepnutie ohniska medzi oknami bez " -#~ "zobrazenia vyskakovacieho okna. (Tradične <Alt>Tab) Držaním \"shift" -#~ "\" spolu s touto klávesovou skratkou znovu obráti smer prepínania. Formát " -#~ "je \"<Control>a\" alebo \"<Shift><Alt>F1. Spracovanie " -#~ "je dosť liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<" -#~ "Ctl>\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu " -#~ "hodnotu \"disabled\", pre túto akciu nebude definovaná žiadna klávesová " -#~ "skratka." +#~ msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +#~ msgstr "Nerozpoznané znaky na konci „%s“ v reťazci „%s“" -#~ msgid "" -#~ "The keybinding used to move focus between windows, using a popup window. " -#~ "(Traditionally <Alt>Tab) Holding the \"shift\" key while using this " -#~ "binding reverses the direction of movement. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Klávesová skratka použitá na prepnutie ohniska medzi oknami so zobrazením " -#~ "vyskakovacieho okna. (Tradične <Alt>Tab) Držaním \"shift\" spolu s " -#~ "touto klávesovou skratkou znovu obráti smer prepínania. Formát je \"<" -#~ "Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je dosť " -#~ "liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<Ctl>" -#~ "\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu hodnotu " -#~ "\"disabled\", pre túto akciu nebude definovaná žiadna klávesová skratka." +#~ msgid "Integer %ld must be positive" +#~ msgstr "Celé číslo %ld musí byť kladné" -#~ msgid "" -#~ "The keybinding used to toggle always on top. A window that is always on " -#~ "top will always be visible over other overlapping windows. The format " -#~ "looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -#~ "parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Klávesová skratka použitá na prepnutie, či je okno vždy navrchu. Okno, " -#~ "ktoré je vždy navrchu bude vždy viditeľné nad ostatnými prekrývajúcimi sa " -#~ "oknami. Formát je \"<Control>a\" alebo \"<Shift><Alt>" -#~ "F1. Spracovanie je dosť liberálne a umožňuje malé aj veľké písmená a " -#~ "skratky ako je \"<Ctl>\" a \"<Ctrl>\". Ak nastavíte túto " -#~ "možnosť na špeciálnu hodnotu \"disabled\", pre túto akciu nebude " -#~ "definovaná žiadna klávesová skratka." +#~ msgid "Integer %ld is too large, current max is %d" +#~ msgstr "Celé číslo %ld je príliš veľké, maximum je %d" -#~ msgid "" -#~ "The keybinding used to toggle fullscreen mode. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Klávesová skratka použitá na prepnutie celoobrazovkového režimu. Formát " -#~ "je \"<Control>a\" alebo \"<Shift><Alt>F1. Spracovanie " -#~ "je dosť liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<" -#~ "Ctl>\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu " -#~ "hodnotu \"disabled\", pre túto akciu nebude definovaná žiadna klávesová " -#~ "skratka." +#~ msgid "Could not parse \"%s\" as a floating point number" +#~ msgstr "Nepodarilo sa spracovať „%s“ ako číslo s pohyblivou rádovou čiarkou" -#~ msgid "" -#~ "The keybinding used to toggle maximization. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Klávesová skratka použitá na prepnutie maximalizácie. Formát je \"<" -#~ "Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je dosť " -#~ "liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<Ctl>" -#~ "\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu hodnotu " -#~ "\"disabled\", pre túto akciu nebude definovaná žiadna klávesová skratka." +#~ msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" +#~ msgstr "Pravdivostná hodnota musí byť „true“ alebo „false“, nie „%s“" -#~ msgid "" -#~ "The keybinding used to toggle shaded/unshaded state. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Klávesová skratka použitá na prepnutie zabalenie/rozbalenie okna. Formát " -#~ "je \"<Control>a\" alebo \"<Shift><Alt>F1. Spracovanie " -#~ "je dosť liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<" -#~ "Ctl>\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu " -#~ "hodnotu \"disabled\", pre túto akciu nebude definovaná žiadna klávesová " -#~ "skratka." +#~ msgid "Angle must be between 0.0 and 360.0, was %g\n" +#~ msgstr "Uhol musí byť medzi 0.0 a 360.0, a teraz je %g\n" #~ msgid "" -#~ "The keybinding used to toggle whether the window is on all workspaces or " -#~ "just one. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." +#~ "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" #~ msgstr "" -#~ "Klávesová skratka použitá na prepnutie, či je okno na všetkých pracovných " -#~ "plochách alebo iba na jednej. Formát je \"<Control>a\" alebo \"<" -#~ "Shift><Alt>F1. Spracovanie je dosť liberálne a umožňuje malé aj " -#~ "veľké písmená a skratky ako je \"<Ctl>\" a \"<Ctrl>\". Ak " -#~ "nastavíte túto možnosť na špeciálnu hodnotu \"disabled\", pre túto akciu " -#~ "nebude definovaná žiadna klávesová skratka." +#~ "Alfa musí byť medzi 0.0 (priehľadné) a 1.0 (nepriehľadné), a je %g\n" #~ msgid "" -#~ "The keybinding used to unmaximize a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," +#~ "large,x-large,xx-large)\n" #~ msgstr "" -#~ "Klávesová skratka použitá na zrušenie maximalizácie okna. Formát je \"<" -#~ "Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je dosť " -#~ "liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<Ctl>" -#~ "\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu hodnotu " -#~ "\"disabled\", pre túto akciu nebude definovaná žiadna klávesová skratka." +#~ "Neplatná mierka titulku „%s“ (musí byť xx-small, x-small, small, medium, " +#~ "large, x-large, xx-large)\n" -#~ msgid "" -#~ "The keybinding which display's the panel's \"Run Application\" dialog " -#~ "box. The format looks like \"<Control>a\" or \"<Shift><" -#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If " -#~ "you set the option to the special string \"disabled\", then there will be " -#~ "no keybinding for this action." -#~ msgstr "" -#~ "Klávesová skratka, ktorá zobrazí dialógové okno panelu \"Spustiť aplikáciu" -#~ "\". Formát je \"<Control>a\" alebo \"<Shift><Alt>F1. " -#~ "Spracovanie je dosť liberálne a umožňuje malé aj veľké písmená a skratky " -#~ "ako je \"<Ctl>\" a \"<Ctrl>\". Ak nastavíte túto možnosť na " -#~ "špeciálnu hodnotu \"disabled\", pre túto akciu nebude definovaná žiadna " -#~ "klávesová skratka." +#~ msgid "<%s> name \"%s\" used a second time" +#~ msgstr "Názov <%s> pre „%s“ použitý dvakrát" -#~ msgid "" -#~ "The keybinding which invokes a terminal. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Klávesová skratka, ktorá spustí terminál. Formát je \"<Control>a\" " -#~ "alebo \"<Shift><Alt>F1. Spracovanie je dosť liberálne a " -#~ "umožňuje malé aj veľké písmená a skratky ako je \"<Ctl>\" a \"<" -#~ "Ctrl>\". Ak nastavíte túto možnosť na špeciálnu hodnotu \"disabled\", " -#~ "pre túto akciu nebude definovaná žiadna klávesová skratka." +#~ msgid "<%s> parent \"%s\" has not been defined" +#~ msgstr "Nedefinovaný rodič <%s> pre „%s“" -#~ msgid "" -#~ "The keybinding which invokes the panel's screenshot utility to take a " -#~ "screenshot of a window. The format looks like \"<Control>a\" or " -#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " -#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" -#~ "\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "Klávesová skratka, ktorá spustí nástroj panelu na zachytenie obsahu okna. " -#~ "Formát je \"<Control>a\" alebo \"<Shift><Alt>F1. " -#~ "Spracovanie je dosť liberálne a umožňuje malé aj veľké písmená a skratky " -#~ "ako je \"<Ctl>\" a \"<Ctrl>\". Ak nastavíte túto možnosť na " -#~ "špeciálnu hodnotu \"disabled\", pre túto akciu nebude definovaná žiadna " -#~ "klávesová skratka." +#~ msgid "<%s> geometry \"%s\" has not been defined" +#~ msgstr "Nedefinovaná geometria <%s> pre „%s“" -#~ msgid "" -#~ "The keybinding which invokes the panel's screenshot utility. The format " -#~ "looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -#~ "parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Klávesová skratka, ktorá spustí nástroj panelu pre zachytenie obsahu " -#~ "obrazovky. Formát je \"<Control>a\" alebo \"<Shift><Alt>" -#~ "F1. Spracovanie je dosť liberálne a umožňuje malé aj veľké písmená a " -#~ "skratky ako je \"<Ctl>\" a \"<Ctrl>\". Ak nastavíte túto " -#~ "možnosť na špeciálnu hodnotu \"disabled\", pre túto akciu nebude " -#~ "definovaná žiadna klávesová skratka." +#~ msgid "<%s> must specify either a geometry or a parent that has a geometry" +#~ msgstr "<%s> musí uviesť, buď geometriu alebo rodiča, ktorý má geometriu" -#~ msgid "" -#~ "The keybinding which shows the panel's main menu. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Klávesová skratka, ktorá zobrazí hlavnú ponuku panelu. Formát je \"<" -#~ "Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je dosť " -#~ "liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<Ctl>" -#~ "\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu hodnotu " -#~ "\"disabled\", pre túto akciu nebude definovaná žiadna klávesová skratka." +#~ msgid "You must specify a background for an alpha value to be meaningful" +#~ msgstr "Ak má byť hodnota alfa zmysluplná, tak musíte vybrať nejaké pozadie" -#~ msgid "" -#~ "This keybinding changes whether a window is above or below other windows. " -#~ "If the window is covered by another one, it raises the window above all " -#~ "others, and if the window is already fully visible, it lowers it below " -#~ "all others. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Táto klávesová skratka mení, či je okno nad alebo pod ostatnými oknami. " -#~ "Ak je okno zakryté iným oknom, posunie ho dopredu pred ostatné okná. Ak " -#~ "už je okno plne viditeľné, posunie ho dozadu za ostatné okná. Formát je " -#~ "\"<Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je " -#~ "dosť liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<" -#~ "Ctl>\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu " -#~ "hodnotu \"disabled\", pre túto akciu nebude definovaná žiadna klávesová " -#~ "skratka." +# * https://bugzilla.gnome.org/show_bug.cgi?id=698123 +#~ msgid "Unknown type \"%s\" on <%s> element" +#~ msgstr "Neznámy typ „%s“ v prvku <%s>" -#~ msgid "" -#~ "This keybinding lowers a window below other windows. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Táto klávesová skratka presunie okno za ostatné okná. Formát je \"<" -#~ "Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je dosť " -#~ "liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<Ctl>" -#~ "\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu hodnotu " -#~ "\"disabled\", pre túto akciu nebude definovaná žiadna klávesová skratka." +# * https://bugzilla.gnome.org/show_bug.cgi?id=698123 +#~ msgid "Unknown style_set \"%s\" on <%s> element" +#~ msgstr "Neznámy style_set „%s“ v prvku <%s>" -#~ msgid "" -#~ "This keybinding moves a window against the north (top) side of the " -#~ "screen. The format looks like \"<Control>a\" or \"<Shift><" -#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If " -#~ "you set the option to the special string \"disabled\", then there will be " -#~ "no keybinding for this action." -#~ msgstr "" -#~ "Táto klávesová skratka presunie okno voči severnej (hornej) strane " -#~ "obrazovky. Formát je \"<Control>a\" alebo \"<Shift><Alt>" -#~ "F1. Spracovanie je dosť liberálne a umožňuje malé aj veľké písmená a " -#~ "skratky ako je \"<Ctl>\" a \"<Ctrl>\". Ak nastavíte túto " -#~ "možnosť na špeciálnu hodnotu \"disabled\", pre túto akciu nebude " -#~ "definovaná žiadna klávesová skratka." +#~ msgid "Window type \"%s\" has already been assigned a style set" +#~ msgstr "Typ okna „%s“ už má priradenú sadu štýlov" -#~ msgid "" -#~ "This keybinding moves a window into the center of the screen. The format " -#~ "looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -#~ "parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Táto klávesová skratka presunie okno doprostriedku obrazovky. Formát je " -#~ "\"<Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je " -#~ "dosť liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<" -#~ "Ctl>\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu " -#~ "hodnotu \"disabled\", pre túto akciu nebude definovaná žiadna klávesová " -#~ "skratka." +#~ msgid "Element <%s> is not allowed below <%s>" +#~ msgstr "Prvok <%s> nie je povolený pod <%s>" +# * https://bugzilla.gnome.org/show_bug.cgi?id=698123 #~ msgid "" -#~ "This keybinding moves a window into the east (right) side of the screen. " -#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -#~ "\". The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." +#~ "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio" +#~ "\" for buttons" #~ msgstr "" -#~ "Táto klávesová skratka presunie okno voči východnej (pravej) strane " -#~ "obrazovky. Formát je \"<Control>a\" alebo \"<Shift><Alt>" -#~ "F1. Spracovanie je dosť liberálne a umožňuje malé aj veľké písmená a " -#~ "skratky ako je \"<Ctl>\" a \"<Ctrl>\". Ak nastavíte túto " -#~ "možnosť na špeciálnu hodnotu \"disabled\", pre túto akciu nebude " -#~ "definovaná žiadna klávesová skratka." +#~ "Pre tlačidlá nie je možné zadať zároveň „button_width“/„button_height“ " +#~ "spolu s „aspect_ratio“" -#~ msgid "" -#~ "This keybinding moves a window into the north-east (top right) corner of " -#~ "the screen. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Táto klávesová skratka presunie okno do severovýchodného (pravého " -#~ "horného) rohu obrazovky. Formát je \"<Control>a\" alebo \"<" -#~ "Shift><Alt>F1. Spracovanie je dosť liberálne a umožňuje malé aj " -#~ "veľké písmená a skratky ako je \"<Ctl>\" a \"<Ctrl>\". Ak " -#~ "nastavíte túto možnosť na špeciálnu hodnotu \"disabled\", pre túto akciu " -#~ "nebude definovaná žiadna klávesová skratka." +#~ msgid "Distance \"%s\" is unknown" +#~ msgstr "Vzdialenosť „%s“ je neznáma" -#~ msgid "" -#~ "This keybinding moves a window into the north-west (top left) corner of " -#~ "the screen. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Táto klávesová skratka presunie okno do severozápadného (ľavého horného) " -#~ "rohu obrazovky. Formát je \"<Control>a\" alebo \"<Shift><" -#~ "Alt>F1. Spracovanie je dosť liberálne a umožňuje malé aj veľké písmená " -#~ "a skratky ako je \"<Ctl>\" a \"<Ctrl>\". Ak nastavíte túto " -#~ "možnosť na špeciálnu hodnotu \"disabled\", pre túto akciu nebude " -#~ "definovaná žiadna klávesová skratka." +#~ msgid "Aspect ratio \"%s\" is unknown" +#~ msgstr "Pomer strán „%s“ je neznámy" -#~ msgid "" -#~ "This keybinding moves a window into the south (bottom) side of the " -#~ "screen. The format looks like \"<Control>a\" or \"<Shift><" -#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If " -#~ "you set the option to the special string \"disabled\", then there will be " -#~ "no keybinding for this action." -#~ msgstr "" -#~ "Táto klávesová skratka presunie okno voči južnej (spodnej) strane " -#~ "obrazovky. Formát je \"<Control>a\" alebo \"<Shift><Alt>" -#~ "F1. Spracovanie je dosť liberálne a umožňuje malé aj veľké písmená a " -#~ "skratky ako je \"<Ctl>\" a \"<Ctrl>\". Ak nastavíte túto " -#~ "možnosť na špeciálnu hodnotu \"disabled\", pre túto akciu nebude " -#~ "definovaná žiadna klávesová skratka." +#~ msgid "Border \"%s\" is unknown" +#~ msgstr "Okraj „%s“ je neznámy" -#~ msgid "" -#~ "This keybinding moves a window into the south-east (bottom right) corner " -#~ "of the screen. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." +#~ msgid "No \"start_angle\" or \"from\" attribute on element <%s>" #~ msgstr "" -#~ "Táto klávesová skratka presunie okno do juhovýchodného (pravého dolného) " -#~ "rohu obrazovky. Formát je \"<Control>a\" alebo \"<Shift><" -#~ "Alt>F1. Spracovanie je dosť liberálne a umožňuje malé aj veľké písmená " -#~ "a skratky ako je \"<Ctl>\" a \"<Ctrl>\". Ak nastavíte túto " -#~ "možnosť na špeciálnu hodnotu \"disabled\", pre túto akciu nebude " -#~ "definovaná žiadna klávesová skratka." +#~ "Chýba atribút „start_angle“ (počiatočný uhol) alebo „from“ (od) v prvku <" +#~ "%s>" -#~ msgid "" -#~ "This keybinding moves a window into the south-west (bottom left) corner " -#~ "of the screen. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." +#~ msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" #~ msgstr "" -#~ "Táto klávesová skratka presunie do juhozápadného (ľavého dolného) rohu " -#~ "obrazovky. Formát je \"<Control>a\" alebo \"<Shift><Alt>" -#~ "F1. Spracovanie je dosť liberálne a umožňuje malé aj veľké písmená a " -#~ "skratky ako je \"<Ctl>\" a \"<Ctrl>\". Ak nastavíte túto " -#~ "možnosť na špeciálnu hodnotu \"disabled\", pre túto akciu nebude " -#~ "definovaná žiadna klávesová skratka." +#~ "Chýba atribút „extent_angle“ (rozsah uhla) alebo „to“ (do) v prvku <%s>" -#~ msgid "" -#~ "This keybinding moves a window into the west (left) side of the screen. " -#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -#~ "\". The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Táto klávesová skratka presunie okno voči západnej (ľavej) strane " -#~ "obrazovky. Formát je \"<Control>a\" alebo \"<Shift><Alt>" -#~ "F1. Spracovanie je dosť liberálne a umožňuje malé aj veľké písmená a " -#~ "skratky ako je \"<Ctl>\" a \"<Ctrl>\". Ak nastavíte túto " -#~ "možnosť na špeciálnu hodnotu \"disabled\", pre túto akciu nebude " -#~ "definovaná žiadna klávesová skratka." +#~ msgid "Did not understand value \"%s\" for type of gradient" +#~ msgstr "Nerozpoznaná hodnota „%s“ pre typ prechodu" -#~ msgid "" -#~ "This keybinding raises the window above other windows. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Táto klávesová skratka presunie okno pred ostatné okná. Formát je \"<" -#~ "Control>a\" alebo \"<Shift><Alt>F1. Spracovanie je dosť " -#~ "liberálne a umožňuje malé aj veľké písmená a skratky ako je \"<Ctl>" -#~ "\" a \"<Ctrl>\". Ak nastavíte túto možnosť na špeciálnu hodnotu " -#~ "\"disabled\", pre túto akciu nebude definovaná žiadna klávesová skratka." +#~ msgid "Did not understand fill type \"%s\" for <%s> element" +#~ msgstr "Nerozpoznaný typ výplne „%s“ pre prvok <%s>" -#~ msgid "" -#~ "This keybinding resizes a window to fill available horizontal space. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Táto klávesová skratka zmení veľkosť okna tak, aby vyplnilo celý " -#~ "vodorovný priestor. Formát je \"<Control>a\" alebo \"<Shift>" -#~ "<Alt>F1. Spracovanie je dosť liberálne a umožňuje malé aj veľké " -#~ "písmená a skratky ako je \"<Ctl>\" a \"<Ctrl>\". Ak nastavíte " -#~ "túto možnosť na špeciálnu hodnotu \"disabled\", pre túto akciu nebude " -#~ "definovaná žiadna klávesová skratka." +#~ msgid "Did not understand state \"%s\" for <%s> element" +#~ msgstr "Nerozpoznaný stav „%s“ pre prvok <%s>" -#~ msgid "" -#~ "This keybinding resizes a window to fill available vertical space. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Táto klávesová skratka zmení veľkosť okna tak, aby vyplnilo celý zvislý " -#~ "priestor. Formát je \"<Control>a\" alebo \"<Shift><Alt>" -#~ "F1. Spracovanie je dosť liberálne a umožňuje malé aj veľké písmená a " -#~ "skratky ako je \"<Ctl>\" a \"<Ctrl>\". Ak nastavíte túto " -#~ "možnosť na špeciálnu hodnotu \"disabled\", pre túto akciu nebude " -#~ "definovaná žiadna klávesová skratka." +#~ msgid "Did not understand shadow \"%s\" for <%s> element" +#~ msgstr "Nerozpoznaný tieň „%s“ pre prvok <%s>" -#~ msgid "No \"%s\" attribute on <%s> element" -#~ msgstr "Chýbajúci atribút \"%s\" v prvku <%s>" +#~ msgid "Did not understand arrow \"%s\" for <%s> element" +#~ msgstr "Nerozpoznaná šípka „%s“ pre prvok <%s>" -#~ msgid "Theme already has a fallback icon" -#~ msgstr "Táto téma už má základnú ikonu" +#~ msgid "No <draw_ops> called \"%s\" has been defined" +#~ msgstr "Nebola definovaná <draw_ops> nazvaná „%s“" -#~ msgid "Theme already has a fallback mini_icon" -#~ msgstr "Táto téma už má základnú mini ikonu" +# PK: asi ako v strukturach v C +#~ msgid "Including draw_ops \"%s\" here would create a circular reference" +#~ msgstr "Pridaním draw_ops „%s“ na tomto mieste vznikne cyklická referencia" -#~ msgid "No \"name\" attribute on element <%s>" -#~ msgstr "Chýbajúci atribút \"name\" v prvku <%s>" +#~ msgid "Unknown position \"%s\" for frame piece" +#~ msgstr "Neznáma pozícia „%s“ pre časť rámca" -#~ msgid "No \"value\" attribute on element <%s>" -#~ msgstr "Chýbajúci atribút \"value\" v prvku <%s>" +#~ msgid "Frame style already has a piece at position %s" +#~ msgstr "Štýl rámca už má časť na pozícii %s" -#~ msgid "No \"top\" attribute on element <%s>" -#~ msgstr "Chýbajúci atribút \"top\" v prvku <%s>" +#~ msgid "No <draw_ops> with the name \"%s\" has been defined" +#~ msgstr "Nebola definovaná <draw_ops> nazvaná „%s“" -#~ msgid "No \"bottom\" attribute on element <%s>" -#~ msgstr "Chýbajúci atribút \"bottom\" v prvku <%s>" +#~ msgid "Unknown function \"%s\" for button" +#~ msgstr "Neznáma funkcia „%s“ pre tlačidlo" -#~ msgid "No \"left\" attribute on element <%s>" -#~ msgstr "Chýbajúci atribút \"left\" v prvku <%s>" +#~ msgid "Button function \"%s\" does not exist in this version (%d, need %d)" +#~ msgstr "Funkcia tlačidla „%s“ v tejto verzii neexistuje (%d, potrebná %d)" -#~ msgid "No \"right\" attribute on element <%s>" -#~ msgstr "Chýbajúci atribút \"right\" v prvku <%s>" +#~ msgid "Unknown state \"%s\" for button" +#~ msgstr "Neznámy stav „%s“ pre tlačidlo" -#~ msgid "No \"color\" attribute on element <%s>" -#~ msgstr "Chýbajúci atribút \"color\" v prvku <%s>" +#~ msgid "Frame style already has a button for function %s state %s" +#~ msgstr "Štýl rámca už má tlačidlo pre funkciu %s stav %s" -#~ msgid "No \"x1\" attribute on element <%s>" -#~ msgstr "Chýbajúci atribút \"x1\" v prvku <%s>" +#~ msgid "\"%s\" is not a valid value for focus attribute" +#~ msgstr "„%s“ nie je platná hodnota pre atribút zamerania" -#~ msgid "No \"y1\" attribute on element <%s>" -#~ msgstr "Chýbajúci atribút \"y1\" v prvku <%s>" +#~ msgid "\"%s\" is not a valid value for state attribute" +#~ msgstr "„%s“ nie je platná hodnota pre atribút stavu" -#~ msgid "No \"x2\" attribute on element <%s>" -#~ msgstr "Chýbajúci atribút \"x2\" v prvku <%s>" +#~ msgid "A style called \"%s\" has not been defined" +#~ msgstr "Štýl „%s“ nie je definovaný" -#~ msgid "No \"y2\" attribute on element <%s>" -#~ msgstr "Chýbajúci atribút \"y2\" v prvku <%s>" +#~ msgid "\"%s\" is not a valid value for resize attribute" +#~ msgstr "„%s“ nie je platná hodnota pre atribút zmeny veľkosti" -#~ msgid "No \"y\" attribute on element <%s>" -#~ msgstr "Chýbajúci atribút \"y\" v prvku <%s>" +# * https://bugzilla.gnome.org/show_bug.cgi?id=698123 +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized/shaded " +#~ "states" +#~ msgstr "" +#~ "Prvok <%s> by nemal mať atribút „resize“ (zmeniť veľkosť) pre stavy " +#~ "maximized (maximalizovaný)/shaded (zatienený)" -#~ msgid "No \"width\" attribute on element <%s>" -#~ msgstr "Chýbajúci atribút \"width\" v prvku <%s>" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized states" +#~ msgstr "" +#~ "Prvok <%s> by nemal mať atribút „resize“ (zmeniť veľkosť) pre stavy " +#~ "maximized (maximalizovaný)" -#~ msgid "No \"height\" attribute on element <%s>" -#~ msgstr "Chýbajúci atribút \"height\" v prvku <%s>" +#~ msgid "Style has already been specified for state %s resize %s focus %s" +#~ msgstr "Pre stav %s zmena veľkosti %s zameranie %s už bol štýl definovaný" -#~ msgid "No \"start_angle\" attribute on element <%s>" -#~ msgstr "Chýbajúci atribút \"start_angle\" v prvku <%s>" +#~ msgid "Style has already been specified for state %s focus %s" +#~ msgstr "Pre stav %s zameranie %s už bol štýl definovaný" -#~ msgid "No \"extent_angle\" attribute on element <%s>" -#~ msgstr "Chýbajúci atribút \"extent_angle\" v prvku <%s>" +# * https://bugzilla.gnome.org/show_bug.cgi?id=697988 +#~ msgid "" +#~ "Can't have a two draw_ops for a <piece> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Pre prvok <piece> nie je možné mať dve draw_ops (téma obsahuje atribút " +#~ "draw_ops a aj prvok <draw_ops>, prípadne dva rovnaké prvky)" -#~ msgid "No \"alpha\" attribute on element <%s>" -#~ msgstr "Chýbajúci atribút \"alpha\" v prvku <%s>" +# * https://bugzilla.gnome.org/show_bug.cgi?id=697988 +#~ msgid "" +#~ "Can't have a two draw_ops for a <button> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Pre prvok <button> nie je možné mať dve draw_ops (téma obsahuje atribút " +#~ "draw_ops a aj prvok <draw_ops>, prípadne dva rovnaké prvky)" -#~ msgid "No \"type\" attribute on element <%s>" -#~ msgstr "Chýbajúci atribút \"type\" v prvku <%s>" +# * https://bugzilla.gnome.org/show_bug.cgi?id=697988 +#~ msgid "" +#~ "Can't have a two draw_ops for a <menu_icon> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Pre prvok <menu_icon> nie je možné mať dve draw_ops (téma obsahuje " +#~ "atribút draw_ops a aj prvok <draw_ops>, prípadne dva rovnaké prvky)" -#~ msgid "No \"filename\" attribute on element <%s>" -#~ msgstr "Chýbajúci atribút \"filename\" v prvku <%s>" +#~ msgid "Bad version specification '%s'" +#~ msgstr "Zlá verzia špecifikácie „%s“" -#~ msgid "No \"state\" attribute on element <%s>" -#~ msgstr "Chýbajúci atribút \"state\" v prvku <%s>" +#~ msgid "" +#~ "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" +#~ "theme-2.xml" +#~ msgstr "" +#~ "Atribút „version“ nemôže byť použitý v metacity-theme-1.xml alebo " +#~ "metacity-theme-2.xml" -#~ msgid "No \"shadow\" attribute on element <%s>" -#~ msgstr "Chýbajúci atribút \"shadow\" v prvku <%s>" +#~ msgid "" +#~ "Theme requires version %s but latest supported theme version is %d.%d" +#~ msgstr "" +#~ "Téma vyžaduje verziu %s, ale posledná podporovaná verzia témy je %d.%d" -#~ msgid "No \"arrow\" attribute on element <%s>" -#~ msgstr "Chýbajúci atribút \"arrow\" v prvku <%s>" +#~ msgid "Outermost element in theme must be <metacity_theme> not <%s>" +#~ msgstr "Najvyšším prvkom témy musí byť <metacity_theme>, nie <%s>" -#~ msgid "No \"value\" attribute on <%s> element" -#~ msgstr "Chýbajúci atribút \"value\" v prvku <%s>" +# * https://bugzilla.gnome.org/show_bug.cgi?id=698123 +#~ msgid "" +#~ "Element <%s> is not allowed inside a name/author/date/description element" +#~ msgstr "Prvok <%s> nie je povolený v prvku name/author/date/description" -#~ msgid "No \"position\" attribute on <%s> element" -#~ msgstr "Chýbajúci atribút \"position\" v prvku <%s>" +#~ msgid "Element <%s> is not allowed inside a <constant> element" +#~ msgstr "Prvok <%s> nie je povolený v prvku <constant>" -#~ msgid "No \"function\" attribute on <%s> element" -#~ msgstr "Chýbajúci atribút \"function\" v prvku <%s>" +# * https://bugzilla.gnome.org/show_bug.cgi?id=698123 +#~ msgid "" +#~ "Element <%s> is not allowed inside a distance/border/aspect_ratio element" +#~ msgstr "Prvok <%s> nie je povolený v prvku distance/border/aspect_ratio" -#~ msgid "No \"state\" attribute on <%s> element" -#~ msgstr "Chýbajúci atribút \"state\" v prvku <%s>" +#~ msgid "Element <%s> is not allowed inside a draw operation element" +#~ msgstr "Prvok <%s> nie je povolený v prvku operácie pre kreslenie" -#~ msgid "No \"focus\" attribute on <%s> element" -#~ msgstr "Chýbajúci atribút \"focus\" v prvku <%s>" +#~ msgid "Element <%s> is not allowed inside a <%s> element" +#~ msgstr "Prvok <%s> nie je povolený v prvku <%s>" -#~ msgid "No \"style\" attribute on <%s> element" -#~ msgstr "Chýbajúci atribút \"style\" v prvku <%s>" +#~ msgid "No draw_ops provided for frame piece" +#~ msgstr "Pre časť rámca nie je uvedená operácia draw_ops" -#~ msgid "No \"resize\" attribute on <%s> element" -#~ msgstr "Chýbajúci atribút \"resize\" v prvku <%s>" +#~ msgid "No draw_ops provided for button" +#~ msgstr "Pre tlačidlo nie je uvedená operácia draw_ops" -#~ msgid "Type of %s was not integer" -#~ msgstr "Nepodarilo sa spracovať %s ako celé číslo" +#~ msgid "No text is allowed inside element <%s>" +#~ msgstr "V prvku <%s> nie je povolený žiadny text" -#~ msgid "" -#~ "%d stored in GConf key %s is not a reasonable cursor_size; must be in the " -#~ "range 1..128\n" -#~ msgstr "" -#~ "%d uložená v GConf kľúči %s nie je rozumná cursor_size; musí byť medzi " -#~ "1..128\n" +#~ msgid "<%s> specified twice for this theme" +#~ msgstr "<%s> uvedený dvakrát pre túto tému" -#~ msgid "" -#~ "%d stored in GConf key %s is not a reasonable number of workspaces, " -#~ "current maximum is %d\n" -#~ msgstr "" -#~ "Hodnota %d uložená v GConf kľúči %s nie je rozumný počet pracovných " -#~ "plôch, maximum je %d\n" +#~ msgid "Failed to find a valid file for theme %s\n" +#~ msgstr "Zlyhalo nájdenie platného súboru pre tému %s\n" diff --git a/po/sl.po b/po/sl.po index f56b12cbb..847afe0f9 100644 --- a/po/sl.po +++ b/po/sl.po @@ -1,1594 +1,803 @@ -# Slovenian translations for muffin. -# Copyright (C) 2009 muffin COPYRIGHT HOLDER -# This file is distributed under the same license as the muffin package. +# Slovenian translations for mutter. +# Copyright (C) 2009 mutter COPYRIGHT HOLDER +# This file is distributed under the same license as the mutter package. # # Andraž Tori <andraz.tori1@guest.arnes.si>, 2000. # Matjaž Horvat <m@owca.info>, 2006. -# Matej Urbančič <mateju@svn.gnome.org>, 2007 - 2012. +# Matej Urbančič <mateju@svn.gnome.org>, 2007–2020. # msgid "" msgstr "" -"Project-Id-Version: muffin master\n" -"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=muffin&keywords=I18N+L10N&component=general\n" -"POT-Creation-Date: 2012-03-12 09:11+0000\n" -"PO-Revision-Date: 2012-03-12 12:10+0100\n" +"Project-Id-Version: mutter master\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2020-02-29 19:52+0000\n" +"PO-Revision-Date: 2020-02-29 21:23+0100\n" "Last-Translator: Matej Urbančič <mateju@svn.gnome.org>\n" "Language-Team: Slovenian GNOME Translation Team <gnome-si@googlegroups.com>\n" +"Language: sl_SI\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Language: \n" -"Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || n%100==4 ? 3 : 0);\n" -"X-Poedit-Language: Slovenian\n" -"X-Poedit-Country: SLOVENIA\n" +"Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || n" +"%100==4 ? 3 : 0);\n" "X-Poedit-SourceCharset: utf-8\n" +"X-Generator: Poedit 2.2.4\n" -#: ../src/50-muffin-windows.xml.in.h:1 -msgid "Windows" -msgstr "Okna" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Krmarjenje" -#: ../src/50-muffin-windows.xml.in.h:2 -msgid "View split on left" -msgstr "Poglej razdelek na levi" +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Premakni okno na delovno površino 1" -#: ../src/50-muffin-windows.xml.in.h:3 -msgid "View split on right" -msgstr "Poglej razdelek na desni" +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Premakni okno na delovno površino 2" -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format -msgid "Another compositing manager is already running on screen %i on display \"%s\"." -msgstr "Drug upravljalnik sestavljanja je že zagnan na zaslonu %i prikaza \"%s\"." +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Premakni okno na delovno površino 3" -#: ../src/core/bell.c:307 -msgid "Bell event" -msgstr "Dogodek zvonjenja" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Premakni okno na delovno površino 4" -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Zahteva izpisa podrobnosti neznanega okna: %d" +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Premakni okno na zadnjo delovno površino" -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> se ne odziva." +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "Premakni okno eno delovno površino navzgor" -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "Program se ne odziva." +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "Prestavi okno eno delovno površino navzdol" -#: ../src/core/delete.c:119 -msgid "You may choose to wait a short while for it to continue or force the application to quit entirely." -msgstr "Lahko še malo počakate, če program morda spet začne delovati, ali pa vsilite končanje delovanja." +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "Premakni okno en zaslon levo" -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "_Počakaj" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "Premakni okno en zaslon desno" -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "_Vsili konec" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "Premakni okno en zaslon navzgor" -#: ../src/core/display.c:361 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "Manjka razširitev %s, ki je ključna za sestavljanje" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "Prestavi okno en zaslon navzdol" -#: ../src/core/display.c:427 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Ni mogoče odpreti zaslona '%s' okenskega sistema X\n" +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "Preklopi programe" -# G:1 K:0 O:0 -#: ../src/core/keybindings.c:852 -#, c-format -msgid "Some other program is already using the key %s with modifiers %x as a binding\n" -msgstr "Tipko %s s spremenilnikom %x uporablja že nek drug program\n" +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "Preklopi na prejšnji program" -#: ../src/core/main.c:206 -msgid "Disable connection to session manager" -msgstr "Onemogoči povezavo z upravljalnikom sej" +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "Preklopi okna" -#: ../src/core/main.c:212 -msgid "Replace the running window manager" -msgstr "Zamenjaj trenutni upravljalnik oken" +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "Preklopi na prejšnje okno" -#: ../src/core/main.c:218 -msgid "Specify session management ID" -msgstr "Navedite ID upravljanja seje" +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "Preklopi okna programa" -#: ../src/core/main.c:223 -msgid "X Display to use" -msgstr "Zaslon X za uporabo" +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "Preklopi na predhodno okno programa" -#: ../src/core/main.c:229 -msgid "Initialize session from savefile" -msgstr "Začni sejo iz shranjene datoteke" +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "Preklopi tipkovne bližnjice" -#: ../src/core/main.c:235 -msgid "Make X calls synchronous" -msgstr "Uskladi klice X" +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "Preklopi na predhodno sistemsko okno" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Ni mogoče preiskati mape tem: %s\n" +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "Preklopi okna neposredno" -#: ../src/core/main.c:520 -#, c-format -msgid "Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "Ni mogoče najti teme! Prepričajte se, da %s obstaja in vsebuje običajni zapis teme.\n" +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "Preklopi na predhodno okno" -#: ../src/core/muffin.c:40 -#, c-format -msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" -msgstr "" -"muffin %s\n" -"Avtorske pravice pridržane (C) 2001-%d Havoc Pennington, Red Hat in drugi\n" -"To je prosta programska oprema; za pogoje kopiranja si poglejte izvorno kodo.\n" -"Program je na voljo BREZ KAKRŠNIHKOLI ZAGOTOVIL.\n" +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "Preklopi okna programa neposredno" -#: ../src/core/muffin.c:54 -msgid "Print version" -msgstr "Izpiši različico" +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "Preklopi na predhodno okno programa" -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "Z vejico ločen seznam vstavkov sestavljanja" +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "Preklopi tipkovne bližnjice neposredno" -#: ../src/core/prefs.c:1077 -msgid "Workarounds for broken applications disabled. Some applications may not behave properly.\n" -msgstr "Obhodi za pokvarjene programe so onemogočeni. Nekateri programi se morda ne bodo odzivali na pričakovan način.\n" +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "Preklopi na predhodno sistemsko okno" -#: ../src/core/prefs.c:1152 -#, c-format -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "Ni mogoče razčleniti opisa pisave \"%s\" iz ključa GSettings %s\n" +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "Skrij vsa običajna okna" -#: ../src/core/prefs.c:1218 -#, c-format -msgid "\"%s\" found in configuration database is not a valid value for mouse button modifier\n" -msgstr "\"%s\", najden v podatkovni zbirki nastavitev, ni veljaven spremenilnik za miškine gumbe.\n" +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "Preklopi na delovno površino 1" -#: ../src/core/prefs.c:1739 -#, c-format -msgid "\"%s\" found in configuration database is not a valid value for keybinding \"%s\"\n" -msgstr "\"%s\", najden v podatkovni zbirki nastavitev, ni veljaven ključ za tipkovno bližnjico \"%s\"\n" +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "Preklopi na delovno površino 2" -# G:1 K:0 O:0 -#: ../src/core/prefs.c:1836 -#, c-format -msgid "Workspace %d" -msgstr "Delovna površina %d" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "Preklopi na delovno površino 3" -#: ../src/core/screen.c:730 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "Zaslon %d na prikazu '%s' ni veljaven\n" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "Preklopi na delovno površino 4" -#: ../src/core/screen.c:746 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager; try using the --replace option to replace the current window manager.\n" -msgstr "Zaslon %d na prikazu \"%s\" je že upravljan z upravljalnikom oken; poskušajte uporabiti možnost --replace za zamenjavo trenutnega.\n" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "Preklopi na zadnjo delovno površino" -#: ../src/core/screen.c:773 -#, c-format -msgid "Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "Ni mogoče dobiti izbire upravljalnika oken na zaslonu %d prikaza \"%s\"\n" +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "Premakni na zgornjo delovno površino" -#: ../src/core/screen.c:828 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "Zaslon %d na prikazu \"%s\" je že upravljan z upravljalnikom oken\n" +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "Premakni na spodnjo delovno površino" -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "Ni mogoče opustiti zaslona %d na prikazu \"%s\"\n" +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "Sistem" -#: ../src/core/session.c:843 -#: ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Ni mogoče ustvariti imenika '%s': %s\n" - -# G:2 K:0 O:0 -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "Ni mogoče odpreti datoteke seje '%s' za pisanje: %s\n" - -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Napaka med zapisovanjem datoteke seje '%s': %s\n" - -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Napaka med zapiranjem datoteke seje '%s': %s\n" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Pokaži možnost zagona ukazne vrstice" -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Ni mogoče razčleniti datoteke shranjene seje: %s\n" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Pokaži okno pregleda dejavnosti" -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "atribut <muffin_session> je zaznan, vendar pa ima sistem že določen ID seje" - -#: ../src/core/session.c:1198 -#: ../src/core/session.c:1273 -#: ../src/core/session.c:1305 -#: ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Neznan atribut %s predmeta <%s>" +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Obnovi tipkovne bližnjice" -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "gnezdena označba <window>" - -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "Neznan predmet %s" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Okna" -# G:2 K:6 O:0 -#: ../src/core/session.c:1809 -msgid "These windows do not support "save current setup" and will have to be restarted manually next time you log in." -msgstr "Ta okna ne podpirajo možnosti "shranjevanja trenutnih nastavitev", zato jih bo treba ob naslednji prijavi zagnati ročno." +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "Omogoči meni okna" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Napaka med odpiranjem dnevnika razhroščevanja: %s\n" +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Preklopi celozaslonski način" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Napaka ukaza fdopen() dnevniške datoteke %s: %s\n" +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "Preklopi stanje razpetosti" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "Odprta dnevniška datoteka %s\n" +# G:1 K:0 O:0 +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "Razpni okno" -#: ../src/core/util.c:146 -#: ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "Program Muffin je kodno preveden brez podpore za podrobni način izpisovanja\n" +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Obnovi okno" -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "Upravljalnik oken: " +#: data/50-mutter-windows.xml:18 +msgid "Close window" +msgstr "Zapri okno" -# G:4 K:0 O:0 -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "Hrošč v upravljalniku oken: " +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "Skrij okno" -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "Opozorilo upravljalnika oken: " +#: data/50-mutter-windows.xml:22 +msgid "Move window" +msgstr "Premakni okno" -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "Napaka upravljalnika oken: " +#: data/50-mutter-windows.xml:24 +msgid "Resize window" +msgstr "Spremeni velikost okna" -#. first time through -#: ../src/core/window.c:7224 -#, c-format -msgid "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER window as specified in the ICCCM.\n" -msgstr "Okno %s nastavi svoj SM_CLIENT_ID, namesto, da bi nastavilo WM_CLIENT_LEADER kot je zavedeno v ICCCM.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7887 -#, c-format -msgid "Window %s sets an MWM hint indicating it isn't resizable, but sets min size %d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "Okno %s določi namig MWM, ki pove, da ni mogoče spremeniti velikosti, hkrati pa določi najmanjšo velikost na %d x %d in največjo na %d x %d; vrednost ni smiselna.\n" +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "Preklopi okno na vse delovne površine oziroma le na eno" -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "Program je nastavil pokvarjen _NET_WM_PID %lu\n" +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "Dvigni okno, če ga prekriva drugo okno, sicer ga spusti" -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (na %s)" +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "Dvigni okno nad druga okna" -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "Neveljaven WM_TRANSIENT_FOR za okno 0x%lx naveden za %s.\n" +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "Spusti okno pod druga" -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "Predmet WM_TRANSIENT_FOR okna 0x%lx za %s lahko ustvari zanko.\n" +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "Razpni okno navpično" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"Okno 0x%lx ima nastavljeno lastnost %s,\n" -"za katero je pričakovana možnost vrste %s in oblike %d,\n" -"a je v resnici vrste %s z obliko %d n_items %d.\n" -"To je najverjetneje hrošč v programu in ne v upravljalniku oken.\n" -"Okno ima naziv=\"%s\" razreda=\"%s\" ime=\"%s\"\n" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "Razpni okno vodoravno" -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "Lastnost %s okna 0x%lx vsebuje neveljaven znak UTF-8\n" +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "Poglej razdelek na levi" -#: ../src/core/xprops.c:494 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "Lastnost %s okna 0x%lx vsebuje neveljaven znak UTF-8 za predmet %d na seznamu\n" +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "Poglej razdelek na desni" -#: ../src/muffin.desktop.in.h:1 -#: ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 +#: data/org.gnome.mutter.gschema.xml.in:7 msgid "Modifier to use for extended window management operations" msgstr "Spremenilnik, ki naj se uporabi za upravljanje oken" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 -msgid "This key will initiate the \"overlay\", which is a combination window overview and application launching system. The default is intended to be the \"Windows key\" on PC hardware. It's expected that this binding either the default or set to the empty string." -msgstr "Ta vrednost določa \"prevleko\", ki združuje predogled okna in zaganjalnik programa. Vrednost je zamišljena kot \"ključ oken\" na strojni opremi računalnika. Pričakovano je, da je vrednost določena privzeto ali pa ni določena." +#: data/org.gnome.mutter.gschema.xml.in:8 +msgid "" +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." +msgstr "" +"Ta vrednost določa »prekrivno plast«, ki združuje predogled okna in " +"zaganjalnik programa. Vrednost je zamišljena kot »ključ oken« na strojni " +"opremi računalnika. Pričakovano je, da je vrednost določena privzeto ali pa " +"ni določena." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 +#: data/org.gnome.mutter.gschema.xml.in:20 msgid "Attach modal dialogs" msgstr "Pripni modalna pogovorna okna" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 -msgid "When true, instead of having independent titlebars, modal dialogs appear attached to the titlebar of the parent window and are moved together with the parent window." -msgstr "Izbrana možnost omogoči, da je namesto samostojnih nazivnih vrstic, na to mesto pripeto modalno pogovorno okno, ki se premika z nadrejenim oknom." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -msgid "Live Hidden Windows" -msgstr "Ohranjena skrita okna" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 -msgid "Determines whether hidden windows (i.e., minimized windows and windows on other workspaces than the current one) should be kept alive." -msgstr "Določa ali naj se skrita okna (skrčena okna in okna na drugih delovnih površinah) ohranjajo odprta." +#: data/org.gnome.mutter.gschema.xml.in:21 +msgid "" +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." +msgstr "" +"Izbrana možnost omogoči, da je namesto samostojnih nazivnih vrstic, na to " +"mesto pripeto modalno pogovorno okno, ki se premika z nadrejenim oknom." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 +#: data/org.gnome.mutter.gschema.xml.in:30 msgid "Enable edge tiling when dropping windows on screen edges" msgstr "Omogoči prilagajanje velikosti okna ob dotiku robov zaslona" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 -msgid "If enabled, dropping windows on vertical screen edges maximizes them vertically and resizes them horizontally to cover half of the available area. Dropping windows on the top screen edge maximizes them completely." -msgstr "Izbrana možnost omogoča, da se okna, ki se dotaknejo navpičnih robov zaslona razpeta po navpični osi in razširjena na polovično širino. Dotik vrhnjega roba razpne okno čez cel zaslon." +#: data/org.gnome.mutter.gschema.xml.in:31 +msgid "" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." +msgstr "" +"Izbrana možnost omogoča, da se okna, ki se dotaknejo navpičnih robov zaslona " +"razpeta po navpični osi in razširjena na polovično širino. Dotik vrhnjega " +"roba razpne okno čez cel zaslon." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 +#: data/org.gnome.mutter.gschema.xml.in:40 msgid "Workspaces are managed dynamically" msgstr "Število delovnih površin je spremenljivo" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 -msgid "Determines whether workspaces are managed dynamically or whether there's a static number of workspaces (determined by the num-workspaces key in org.cinnamon.desktop.wm.preferences)." -msgstr "Možnost določa ali je število delovnih površin spremenljivo ali pa je to število stalno (določenih s ključem števila delovnih površin med možnostmi v org.cinnamon.desktop.wm.preferences)." +#: data/org.gnome.mutter.gschema.xml.in:41 +msgid "" +"Determines whether workspaces are managed dynamically or whether there’s a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." +msgstr "" +"Možnost določa ali je število delovnih površin spremenljivo ali pa je to " +"število stalno (določenih s ključem števila delovnih površin med možnostmi v " +"org.gnome.desktop.wm.preferences)." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 +#: data/org.gnome.mutter.gschema.xml.in:50 msgid "Workspaces only on primary" msgstr "Delovne površine le na prvem zaslonu" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 -msgid "Determines whether workspace switching should happen for windows on all monitors or only for windows on the primary monitor." -msgstr "Določa ali naj se delovne površine preklapljajo na vseh zaslonih ali le na prvem, glavnem zaslonu." +#: data/org.gnome.mutter.gschema.xml.in:51 +msgid "" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." +msgstr "" +"Določa ali naj se delovne površine preklapljajo na vseh zaslonih ali le na " +"prvem, glavnem zaslonu." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 +#: data/org.gnome.mutter.gschema.xml.in:59 msgid "No tab popup" msgstr "Brez pojavnih zavihkov" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 -msgid "Determines whether the use of popup and highlight frame should be disabled for window cycling." -msgstr "Določa ali naj bo uporaba pojavnih zavihkov in poudarjanja onemogočena med kroženjem oken." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 -msgid "Draggable border width" -msgstr "Prilagodljiva obroba pravokotnika" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 -msgid "The amount of total draggable borders. If the theme's visible borders are not enough, invisible borders will be added to meet this value." -msgstr "Delež skupne prilagodljive obrobe. V kolikor vidni robovi teme niso dovolj, so dodane nevidne obrobe, za dodatno prilagajanje." +#: data/org.gnome.mutter.gschema.xml.in:60 +msgid "" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." +msgstr "" +"Določa ali naj bo uporaba pojavnih zavihkov in poudarjanja onemogočena med " +"kroženjem oken." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:17 -msgid "Select window from tab popup" -msgstr "Izbor okna iz pojavnega zavihka" +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Zamakni spremembe žarišča, dokler se kazalnik še premika" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:18 -msgid "Cancel tab popup" -msgstr "Prekliči pojavni zavihek" +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" +"Izbrana možnost omogoča, da se žarišče, v kolikor je izbran način »sloppy« " +"ali »miška«, ne spremeni takoj ob izbiri okna. Žarišče se spremeni, ko se " +"kazalnik preneha premikati." -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "Uporaba: %s\n" +#: data/org.gnome.mutter.gschema.xml.in:79 +msgid "Draggable border width" +msgstr "Prilagodljiva obroba pravokotnika" -#: ../src/ui/frames.c:1158 -msgid "Close Window" -msgstr "Zapri okno" +#: data/org.gnome.mutter.gschema.xml.in:80 +msgid "" +"The amount of total draggable borders. If the theme’s visible borders are " +"not enough, invisible borders will be added to meet this value." +msgstr "" +"Delež skupne prilagodljive obrobe. V kolikor vidni robovi teme niso dovolj, " +"so dodane nevidne obrobe za dodatno prilagajanje." -# G:1 K:1 O:0 -#: ../src/ui/frames.c:1161 -msgid "Window Menu" -msgstr "Meni okna" +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "Samodejno razpni okna, ki so skoraj enaka velikosti zaslona" -# G:0 K:1 O:0 -#: ../src/ui/frames.c:1164 -msgid "Minimize Window" -msgstr "Skrči okno" +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" +"Izbrana možnost omogoča, da bodo okna, ki so skoraj tako velika, kot je " +"velik zaslon, med preslikavo samodejno razpeta." -#: ../src/ui/frames.c:1167 -msgid "Maximize Window" -msgstr "Razpni okno" +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Postavi novo okno v središče" -#: ../src/ui/frames.c:1170 -msgid "Restore Window" -msgstr "Obnovi okno" +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" +"Izbrana možnost določa, da bo novo okno vedno v središču dejavnega zaslona." -# G:2 K:0 O:0 -#: ../src/ui/frames.c:1173 -msgid "Roll Up Window" -msgstr "Zavij okno" +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Omogoči preizkusne možnosti" -#: ../src/ui/frames.c:1176 -msgid "Unroll Window" -msgstr "Odvij okno" +#: data/org.gnome.mutter.gschema.xml.in:108 +msgid "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes " +"mutter request a low priority real-time scheduling. The executable or user " +"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — " +"initializes Xwayland lazily if there are X11 clients. Requires restart." +msgstr "" +"Za omogočanje preizkusnih možnosti je treba dodati ključne besede na seznam " +"ključev. Ali vpisana možnost zahteva ponovni zagon sestavljalnika, je " +"odvisno od posamezne možnosti. Te možnosti niso zahtevane niti nastavljive, " +"najverjetneje niti ne bodo. Trenutno so na voljo ključne besede: • »scale-" +"monitor-framebuffer« – določi privzeto rabo sistema mutter za logične " +"zaslone v logičnem točkovnem koordinatnem prostoru, pri čemer prilagaja " +"predpomnilnik in ne vsebine za upravljanje z zasloni HiDPI. Možnost ne " +"zahteva ponovnega zagona.• “rt-scheduler” — postavi zahteve mutter na nižjo " +"prednostno raven. Izvršljivi program oziroma uporabnik mora imeti omogočeno " +"možnost CAP_SYS_NICE. Ta možnost zahteva ponovni zagon. • »autostart-" +"xwayland« - lenobno zažne okolje Xwayland, če ima odjemalce X11. Prav tako " +"zahteva ponoven zagon." + +#: data/org.gnome.mutter.gschema.xml.in:134 +msgid "Modifier to use to locate the pointer" +msgstr "Spremenilnik, ki naj se uporabi za določanje mesta kazalnika" + +#: data/org.gnome.mutter.gschema.xml.in:135 +msgid "This key will initiate the “locate pointer” action." +msgstr "Ključ začne dejanje »zaznavanja kazalnika«." + +#: data/org.gnome.mutter.gschema.xml.in:142 +msgid "Timeout for check-alive ping" +msgstr "Časovni zamik za preverjanje delovanja z ukazom ping" + +#: data/org.gnome.mutter.gschema.xml.in:143 +msgid "" +"Number of milliseconds a client has to respond to a ping request in order to " +"not be detected as frozen. Using 0 will disable the alive check completely." +msgstr "" +"Čas v milisekundah, po katerih se mora odjemalec odzvati na zahtevo ping, " +"preden sistem sporoči napako odziva. Vrednost 0 povsem omogoči preverjanje " +"stanja povezave." -#: ../src/ui/frames.c:1179 -msgid "Keep Window On Top" -msgstr "Ohrani okno na vrhu" +#: data/org.gnome.mutter.gschema.xml.in:165 +msgid "Select window from tab popup" +msgstr "Izbor okna iz pojavnega zavihka" -#: ../src/ui/frames.c:1182 -msgid "Remove Window From Top" -msgstr "Odstrani okno z vrha" +#: data/org.gnome.mutter.gschema.xml.in:170 +msgid "Cancel tab popup" +msgstr "Prekliči pojavni zavihek" -# G:1 K:0 O:0 -#: ../src/ui/frames.c:1185 -msgid "Always On Visible Workspace" -msgstr "Vedno na vidni delovni površini" +#: data/org.gnome.mutter.gschema.xml.in:175 +msgid "Switch monitor configurations" +msgstr "Nastavitve nadzornika preklopa" -#: ../src/ui/frames.c:1188 -msgid "Put Window On Only One Workspace" -msgstr "Postavi okno na samo eno delovno površino" +#: data/org.gnome.mutter.gschema.xml.in:180 +msgid "Rotates the built-in monitor configuration" +msgstr "Zavrti vgrajene nastavitve zaslona" -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "_Skrči" +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Preklopi na VT 1" -# G:1 K:0 O:0 -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "Ra_zpni" +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Preklopi na VT 2" -# G:1 K:0 O:0 -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "Pomanjšaj" +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Preklopi na VT 3" -# G:2 K:0 O:0 -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "_Zavij" +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Preklopi na VT 4" -# G:1 K:0 O:0 -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "_Odvij" +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Preklopi na VT 5" -# G:1 K:0 O:0 -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "_Premakni" - -# G:2 K:2 O:0 -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "Sp_remeni velikost" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "Premakni nazivno vrstico na _zaslonu" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 -#: ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "Vedno na _vrhu" +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Preklopi na VT 6" -# G:1 K:0 O:0 -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "Vedno n_a vidni delovni površini" +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Preklopi na VT 7" -# G:1 K:0 O:0 -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "Sam_o na tej delovni površini" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "Premakni na _levo delovno površino" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "Premakni na _desno delovno površino" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "Premakni na _zgornjo delovno površino" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "Premakni na _spodnjo delovno površino" - -# G:0 K:1 O:0 -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "_Zapri" +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Preklopi na VT 8" -# G:1 K:0 O:0 -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "Delovna površina %d%n" +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Preklopi na VT 9" -# G:1 K:0 O:0 -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "Delovna površina 1_0" +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Preklopi na VT 10" -# G:2 K:0 O:0 -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "Delovna površina %s%d" +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Preklopi na VT 11" -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "Premakni na dru_go delovno površino" +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Preklopi na VT 12" -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -# G:2 K:1 O:0 -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -# G:2 K:1 O:0 -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -# G:5 K:2 O:0 -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -# G:0 K:2 O:0 -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hiper" +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "Ponovno omogoči tipkovne bližnjice" -# G:1 K:0 O:0 -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -# G:0 K:1 O:0 -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow X11 grabs to lock keyboard focus with Xwayland" +msgstr "Dovoli zajemanje za zaklep žariščenja tipkovnice z XWayland" -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 +msgid "" +"Allow all keyboard events to be routed to X11 “override redirect” windows " +"with a grab when running in Xwayland. This option is to support X11 clients " +"which map an “override redirect” window (which do not receive keyboard " +"focus) and issue a keyboard grab to force all keyboard events to that " +"window. This option is seldom used and has no effect on regular X11 windows " +"which can receive keyboard focus under normal circumstances. For a X11 grab " +"to be taken into account under Wayland, the client must also either send a " +"specific X11 ClientMessage to the root window or be among the applications " +"white-listed in key “xwayland-grab-access-rules”." +msgstr "" +"Upošteva zajeme s tipkovnico, ki jih sprožijo programi X11, zagnani v okolju " +"Xwayland. možnost je namenjena podpori odjemalcem X11, ki preslikajo okno s " +"\"preglasitvijo preusmeritve\" (ne dobi žarišča tipkovnice) in vsili dogodke " +"tipkovnice v to okno. Možnost se uporablja redko ne vpliva na običajna okna " +"X11, ki lahko v običajnih okoliščinah pridobijo žarišča. Da bo zajem X11 " +"upoštevan v okolju Waylandu, mora odjemalec poslati tudi določeno sporočilo " +"odjemalcu X11 v korensko okno ali pa mora biti med mrogrami na belem seznamu " +"v ključu \"xwayland-grab-access-rules\"." + +#: data/org.gnome.mutter.wayland.gschema.xml.in:84 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "Program XWayland ima dovoljenje za zajemanje s tipkovnico" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:85 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "" +"Seznam imen ali razredov virov oken X11, ki lahko sprožijo zajeme v okolju " +"Xwayland. Ime oziroma razred vira podanega okna X11 je mogoče pridobiti z " +"ukazom »xprop WM_CLASS«. Uporaba pomožnih znakov » * « in » ? « je podprta. " +"Vrednosti, ki se začnejo z znakom » ! « so uvrščeni na črni seznam. Ta " +"seznam je obravnavan prednostno pred belim seznamom in prekliče zajeme na " +"seznamu sistema. Privzeti seznam vključuje ključ: " +"»@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@« Uporabniki lahko prekinejo obstoječi " +"zajem z uporabo posebne tipkovne bližnjice, določene s tipkovnim ključem " +"»restore-shortcuts«." + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. #. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" - -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "zgoraj" - -# G:12 K:5 O:0 -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "spodaj" - -# G:10 K:4 O:0 -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "levo" - -# G:1 K:0 O:0 -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "desno" - -# G:1 K:0 O:0 -#: ../src/ui/theme.c:286 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "geometrija okvirja ne navaja dimenzije \"%s\"" - -#: ../src/ui/theme.c:305 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "geometrija okvirja ne navaja dimenzije \"%s\" za rob \"%s\"" - -#: ../src/ui/theme.c:342 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "Vrednost razmerja gumba %g ni smiselna" - -#: ../src/ui/theme.c:354 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "Geometrija okvirja ne navaja velikosti gumbov" - -#: ../src/ui/theme.c:1067 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "Prelivi bi morali imeti vsaj dve barvi" - -#: ../src/ui/theme.c:1219 -#, c-format -msgid "GTK custom color specification must have color name and fallback in parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" -msgstr "Navedba barve GTK mora biti opredeljena z imenom barve in v navednicah povrnjeno barvo , npr. gtk:izbirno(ime_barve,povrnjena_barva); ni mogoče razčleniti \"%s\"" - -#: ../src/ui/theme.c:1235 -#, c-format -msgid "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-_ are valid" -msgstr "Neveljaven znak '%c' v imenu barve gtk:izbirno; dovoljeni znaki so le A-Za-z0-9-_." - -#: ../src/ui/theme.c:1249 -#, c-format -msgid "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not fit the format" -msgstr "Gtk:zapis po meri \"gtk:izbirno(ime_barve,povrnjena_barva)\", \"%s\" ne ustreza pravilni obliki." - -#: ../src/ui/theme.c:1294 -#, c-format -msgid "GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "Navedba barve GTK mora vsebovati stanje v oglatih oklepajih, npr. gtk:fg[NORMAL], kjer je NORMAL stanje; ni mogoče razčleniti \"%s\"" - -#: ../src/ui/theme.c:1308 -#, c-format -msgid "GTK color specification must have a close bracket after the state, e.g. gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "Navedbi barve GTK manjka oglati zaklepaj za stanjem, npr. gtk:fg[NORMAL], kjer je NORMAL stanje; ni mogoče razčleniti \"%s\"" - -#: ../src/ui/theme.c:1319 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "Ni mogoče razumeti stanja \"%s\" v navedbi barve " - -#: ../src/ui/theme.c:1332 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "Ni mogoče razumeti barvne komponente \"%s\" v navedbi barve" - -#: ../src/ui/theme.c:1361 -#, c-format -msgid "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the format" -msgstr "Oblika zapisa preliva je \"blend/bg_color/fg_color/alpha\", \"%s\" ne ustreza pravilni obliki" - -#: ../src/ui/theme.c:1372 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "V prelivni barvi ni mogoče razčleniti vrednosti alfa \"%s\"" - -#: ../src/ui/theme.c:1382 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "V prelivni barvi alfa vrednost \"%s\" ni med 0.0 in 1.0" - -#: ../src/ui/theme.c:1429 -#, c-format -msgid "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "Oblika zapisa barve senčenja je \"shade/base_color/factor\", \"%s\" ne ustreza pravilni obliki." - -#: ../src/ui/theme.c:1440 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "Ni mogoče razčleniti vrednosti senčenja \"%s\" v senčeni barvi" - -#: ../src/ui/theme.c:1450 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "V senčeni barvi je vrednost senčenja \"%s\" negativna" - -#: ../src/ui/theme.c:1479 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Ni mogoče razčleniti barve \"%s\"" - -#: ../src/ui/theme.c:1790 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "Izraz koordinat vsebuje znak '%s', ki pa ni dovoljen" - -#: ../src/ui/theme.c:1817 -#, c-format -msgid "Coordinate expression contains floating point number '%s' which could not be parsed" -msgstr "Izraz koordinat vsebuje številko s plavajočo vejico '%s', ki je ni mogoče razčleniti" - -#: ../src/ui/theme.c:1831 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "Izraz koordinat vsebuje celo število '%s', ki ga ni mogoče razčleniti" - -#: ../src/ui/theme.c:1953 -#, c-format -msgid "Coordinate expression contained unknown operator at the start of this text: \"%s\"" -msgstr "Izraz koordinat vsebuje neznan operator na začetku besedila: \"%s\"" - -#: ../src/ui/theme.c:2010 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "Izraz koordinat je prazen ali pa ni v razumljivem zapisu" - -#: ../src/ui/theme.c:2121 -#: ../src/ui/theme.c:2131 -#: ../src/ui/theme.c:2165 +#: src/backends/meta-input-settings.c:2567 #, c-format -msgid "Coordinate expression results in division by zero" -msgstr "Izraz koordinat povzroči deljenje z vrednostjo nič" +msgid "Mode Switch (Group %d)" +msgstr "Preklop načina (skupina %d)" -#: ../src/ui/theme.c:2173 -#, c-format -msgid "Coordinate expression tries to use mod operator on a floating-point number" -msgstr "Izraz koordinat poskuša uporabiti operator mod ali številko s plavajočo vejico" - -#: ../src/ui/theme.c:2229 -#, c-format -msgid "Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "Izraz koordinat vsebuje operator \"%s\", kjer je pričakovan operand" - -#: ../src/ui/theme.c:2238 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "Izraz koordinat vsebuje operand kjer je pričakovan operator" - -#: ../src/ui/theme.c:2246 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "Izraz koordinat se konča z operatorjem namesto z operandom" - -#: ../src/ui/theme.c:2256 -#, c-format -msgid "Coordinate expression has operator \"%c\" following operator \"%c\" with no operand in between" -msgstr "Izraz koordinat vsebuje operator \"%c\", ki sledi operatorju \"%c\", brez vmesnega operanda" - -#: ../src/ui/theme.c:2407 -#: ../src/ui/theme.c:2452 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "Izraz koordinat vsebuje neznano spremenljivko ali konstanto \"%s\"" - -#: ../src/ui/theme.c:2506 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "Razčlenjevalnik izrazov koordinat je preplavil medpomnilnik." - -#: ../src/ui/theme.c:2535 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "Izraz koordinat vsebuje zaklepaj, ne pa tudi uklepaja" - -#: ../src/ui/theme.c:2599 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "Izraz koordinat vsebuje uklepaj, vendar je brez zaklepaja" - -#: ../src/ui/theme.c:2610 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "Videti je, da izraz koordinat ne vsebuje operatorjev ali operandov" - -#: ../src/ui/theme.c:2822 -#: ../src/ui/theme.c:2842 -#: ../src/ui/theme.c:2862 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "Tema vsebuje izraz, ki povzroča napako: %s\n" - -#: ../src/ui/theme.c:4533 -#, c-format -msgid "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be specified for this frame style" -msgstr "Za ta slog okvirja mora biti naveden <button function=\"%s\" state=\"%s\" draw_ops=\"karkoli\"/>" - -#: ../src/ui/theme.c:5066 -#: ../src/ui/theme.c:5091 -#, c-format -msgid "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "Manjka <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"karkoli\"/>" - -#: ../src/ui/theme.c:5139 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Napaka med nalaganjem teme \"%s\": %s\n" - -#: ../src/ui/theme.c:5275 -#: ../src/ui/theme.c:5282 -#: ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 -#: ../src/ui/theme.c:5303 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "Ni nastavljena vrednost <%s> za temo \"%s\"" - -#: ../src/ui/theme.c:5311 -#, c-format -msgid "No frame style set for window type \"%s\" in theme \"%s\", add a <window type=\"%s\" style_set=\"whatever\"/> element" -msgstr "Ni določenega sloga okvirja okna vrste \"%s\" v temi \"%s\". Dodajte predmet <window type=\"%s\" style_set=\"whatever\"/>" - -#: ../src/ui/theme.c:5709 -#: ../src/ui/theme.c:5771 -#: ../src/ui/theme.c:5834 -#, c-format -msgid "User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "Uporabniško določene konstante se morajo začeti z veliko črko; vrednost \"%s\" se ne" - -#: ../src/ui/theme.c:5717 -#: ../src/ui/theme.c:5779 -#: ../src/ui/theme.c:5842 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "Konstanta \"%s\" je že določena" - -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. #. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "Ni atributa \"%s\" za predmet <%s>" - -#: ../src/ui/theme-parser.c:265 -#: ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Vrstica %d, znak %d: %s" - -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "Atribut \"%s\" je bil v enakem predmetu <%s> ponovljen dvakrat" - -#: ../src/ui/theme-parser.c:503 -#: ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "Atribut \"%s\" je na ta način v predmetu <%s> neveljaven" - -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "Ni mogoče razčleniti \"%s\" kot celoštevilčne vrednosti" - -#: ../src/ui/theme-parser.c:603 -#: ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "Ni mogoče razumeti končnih znakov \"%s\" v nizu \"%s\"" - -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "Celoštevilska vrednost %ld mora biti pozitivna" - -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "Celoštevilska vrednost %ld je prevelika; trenutna omejitev je %d" +#: src/backends/meta-input-settings.c:2590 +msgid "Switch monitor" +msgstr "Nadzornik preklopa" -#: ../src/ui/theme-parser.c:649 -#: ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "Ni mogoče razčleniti \"%s\" kot števila s plavajočo vejico" +#: src/backends/meta-input-settings.c:2592 +msgid "Show on-screen help" +msgstr "Pokaži zaslonsko pomoč" -#: ../src/ui/theme-parser.c:680 -#: ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "Logične vrednosti morajo biti \"prav\" ali \"napak\" in ne \"%s\"" +#: src/backends/meta-monitor.c:226 +msgid "Built-in display" +msgstr "Vgrajen zaslon" -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "Kot mora biti med 0.0 in 360.0, določen pa je z vrednostjo %g\n" +#: src/backends/meta-monitor.c:255 +msgid "Unknown" +msgstr "Neznano" -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "Alfa mora biti med 0.0 (nevidno) in 1.0 (popolnoma vidno), vrednost pa je določena na %g\n" +#: src/backends/meta-monitor.c:257 +msgid "Unknown Display" +msgstr "Neznan zaslon" -#: ../src/ui/theme-parser.c:863 +#: src/backends/meta-monitor.c:265 #, c-format -msgid "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium,large,x-large,xx-large)\n" -msgstr "Neveljavna velikost naziva \"%s\" (mora biti eno od xx-small,x-small,small,medium,large,x-large,xx-large)\n" +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme-parser.c:1019 -#: ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 -#: ../src/ui/theme-parser.c:1219 +#: src/backends/meta-monitor.c:273 #, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "ime <%s> \"%s\" je uporabljeno drugič" +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme-parser.c:1031 -#: ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "nadrejeni predmet <%s> \"%s\" ni naveden" - -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "geometrija <%s> \"%s\" ni navedena" +#. Translators: this string will appear in Sysprof +#: src/backends/meta-profiler.c:79 +msgid "Compositor" +msgstr "Sestavljalnik" -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "<%s> mora imeti navedeno ali geometrijo ali nadrejeni predmet z določeno geometrijo" - -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "Določiti je treba ozadje, v kolikor naj ima alfa vrednost pomen." - -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Neznana vrsta \"%s\" v predmetu <%s>" - -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "Neznan style_set \"%s\" v predmetu <%s>" - -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "Vrsti okna \"%s\" je slog že določen" - -#: ../src/ui/theme-parser.c:1313 -#: ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 -#: ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 -#: ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 -#: ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 -#: ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "Predmet <%s> ni dovoljen pod <%s>" - -#: ../src/ui/theme-parser.c:1427 -#: ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" for buttons" -msgstr "Ni mogoče navesti tako vrednosti \"button_width\"/\"button_height\", kot vrednosti razmerja\"aspect_ratio\" gumba" - -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "Razdalja \"%s\" ni znana" - -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "Razmerje \"%s\" ni znano" - -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "Rob \"%s\" ni znane vrste" - -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "Predmet <%s> nima določenega atributa \"start_angle\" ali \"from\"" - -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "Predmet <%s> nima določenega atributa \"extent_angle\" ali \"to\"" - -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "Ni mogoče razumeti vrednosti za vrsto preliva \"%s\"" - -#: ../src/ui/theme-parser.c:2193 -#: ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "Neprepoznana vrsta polnjenja \"%s\" za predmet <%s>" - -#: ../src/ui/theme-parser.c:2360 -#: ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "Ni mogoče razumeti stanja \"%s\" za predmet <%s>" - -#: ../src/ui/theme-parser.c:2370 -#: ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "Ni mogoče razumeti senčenja \"%s\" za predmet <%s>" - -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "Ni mogoče razumeti puščice \"%s\" za predmet <%s>" - -#: ../src/ui/theme-parser.c:2694 -#: ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "<draw_ops> imenovan \"%s\" ni naveden" - -#: ../src/ui/theme-parser.c:2706 -#: ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "Vključevanje draw_ops \"%s\" na tem mestu ustvari krožno sklicevanje" - -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Neznan položaj \"%s\" za del okvirja" - -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "Slog okvirja že ima del na položaju %s" - -#: ../src/ui/theme-parser.c:2942 -#: ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "Za ime \"%s\" ni navedenega <draw_ops>" - -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Neznana funkcija \"%s\" za gumb" - -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "Funkcija gumba \"%s\" ne obstaja v tej različici (%d, zahtevana %d)" - -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Neznano stanje \"%s\" za gumb" - -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "Slog okvirja že ima gumb za funkcijo %s stanje %s" - -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "\"%s\" ni veljavna vrednost za atribut \"focus\"" - -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "\"%s\" ni veljavna vrednost za atribut \"state\"" - -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "Slog imenovan \"%s\" ni določen" - -#: ../src/ui/theme-parser.c:3113 -#: ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "\"%s\" ni veljavna vrednost za atribut \"resize\"" - -#: ../src/ui/theme-parser.c:3147 -#, c-format -msgid "Should not have \"resize\" attribute on <%s> element for maximized/shaded states" -msgstr "Predmetu <%s> ni mogoče določiti atributa \"resize\" za razpeta/senčena stanja" - -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "Predmetu <%s> ni mogoče določiti atributa \"resize\" za razpeta stanja" - -#: ../src/ui/theme-parser.c:3175 -#: ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "Slog za stanje %s, spremenjeno velikost %s in žarišče %s je že naveden" - -#: ../src/ui/theme-parser.c:3186 -#: ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 -#: ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 -#: ../src/ui/theme-parser.c:3255 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:533 #, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "Slog za stanje %s in žarišče %s je že naveden" - -#: ../src/ui/theme-parser.c:3294 -msgid "Can't have a two draw_ops for a <piece> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "Za predmet <piece> ni mogoče imeti določenih dveh vrednosti draw_ops (tema je navedla atribut draw_ops in hkrati predmet <draw_ops> ali navedena dva predmeta)" - -#: ../src/ui/theme-parser.c:3332 -msgid "Can't have a two draw_ops for a <button> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "Za predmet <button> ni mogoče imeti določenih dveh vrednosti draw_ops (tema ima naveden atribut draw_ops in hkrati element <draw_ops> ali pa ima navedena dva elementa)" - -#: ../src/ui/theme-parser.c:3370 -msgid "Can't have a two draw_ops for a <menu_icon> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "Za element <menu_icon> ni mogoče imeti dveh draw_ops (tema ima naveden atribut draw_ops in hkrati predmet <draw_ops> ali pa ima navedena dva predmeta)" +msgid "" +"Another compositing manager is already running on screen %i on display “%s”." +msgstr "" +"Drug upravljalnik sestavljanja je že zagnan na zaslonu %i prikaza »%s«." -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "Slabo določilo različice '%s'" +#: src/core/bell.c:192 +msgid "Bell event" +msgstr "Dogodek zvonjenja" -#: ../src/ui/theme-parser.c:3507 -msgid "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-theme-2.xml" -msgstr "atributa \"version\" ni mogoče uporabiti v temi metacity-theme-1.xml oziroma metacity-theme-2.xml" +#: src/core/main.c:190 +msgid "Disable connection to session manager" +msgstr "Onemogoči povezavo z upravljalnikom sej" -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "Tema zahteva različico %s, zadnja podprta različica teme pa je %d.%d" +#: src/core/main.c:196 +msgid "Replace the running window manager" +msgstr "Zamenjaj trenutni upravljalnik oken" -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "Najbolj zunanji predmet teme mora biti <metacity_theme> in ne <%s>" +#: src/core/main.c:202 +msgid "Specify session management ID" +msgstr "Navedite ID upravljanja seje" -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "Element <%s> is not allowed inside a name/author/date/description element" -msgstr "Predmet <%s> ni dovoljen znotraj predmetov imena, avtorja, datuma ali opisa" +#: src/core/main.c:207 +msgid "X Display to use" +msgstr "Zaslon X za uporabo" -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "Predmet <%s> ni dovoljen znotraj predmeta <constant>" +#: src/core/main.c:213 +msgid "Initialize session from savefile" +msgstr "Začni sejo iz shranjene datoteke" -#: ../src/ui/theme-parser.c:3599 -#, c-format -msgid "Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "Predmet <%s> ni dovoljen znotraj predmetov razdalje/robov/razmerja velikosti" +#: src/core/main.c:219 +msgid "Make X calls synchronous" +msgstr "Uskladi klice X" -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "Predmet <%s> ni dovoljen znotraj predmeta izrisevanja" +#: src/core/main.c:226 +msgid "Run as a wayland compositor" +msgstr "Zaženi izbirnik wayland" -#: ../src/ui/theme-parser.c:3631 -#: ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 -#: ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "Predmet <%s> ni dovoljen znotraj predmeta <%s>" +#: src/core/main.c:232 +msgid "Run as a nested compositor" +msgstr "Zaženi kot gnezden vpisovalnik" -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "Za del okvirja ni navedena vrednost draw_ops" +#: src/core/main.c:238 +msgid "Run wayland compositor without starting Xwayland" +msgstr "Zaženi sestavljalnik wayland brez zagona okolja Xwayland" -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "Za gumb ni navedena vrednost draw_ops" +#: src/core/main.c:246 +msgid "Run as a full display server, rather than nested" +msgstr "Zaženi kot polni strežnik zaslona in ne vstavljeno" -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "Znotraj predmeta <%s> besedilo ni dovoljeno" - -#: ../src/ui/theme-parser.c:4026 -#: ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 -#: ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "Vrednost <%s> je za to temo navedena dvakrat" +#: src/core/main.c:252 +msgid "Run with X11 backend" +msgstr "Zaženi z zaledjem X11" -#: ../src/ui/theme-parser.c:4348 +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:151 #, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Ni mogoče najti veljavne datoteke za temo %s\n" - -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "_Okna" - -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "_Pogovorno okno" - -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "_Modalno okno" - -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "_Pripomoček" - -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "Pre_dstavitveno okno" +msgid "“%s” is not responding." +msgstr "Okno »%s« se ne odziva." -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "_Zgornje sidro" - -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "_Spodnje sidro" - -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "_Levo sidro" - -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "_Desno sidro" - -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "_Vsa sidra" - -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "_Namizje" - -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "Odpri drugo izmed teh oken" +#: src/core/meta-close-dialog-default.c:153 +msgid "Application is not responding." +msgstr "Program se ne odziva." -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "To je preizkusni gumb z ikono 'odpri'" +#: src/core/meta-close-dialog-default.c:158 +msgid "" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." +msgstr "" +"Lahko še malo počakate, če program morda spet začne delovati, ali pa vsilite " +"končanje delovanja." -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "To je preizkusni gumb z ikono 'izhod'" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Force Quit" +msgstr "_Vsili konec" -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "To je preizkusno sporočilo v pogovornem oknu" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Wait" +msgstr "_Počakaj" -#: ../src/ui/theme-viewer.c:328 +#: src/core/mutter.c:38 #, c-format -msgid "Fake menu item %d\n" -msgstr "Lažni predmet menija %d\n" - -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "Okno samo z okvirjem" - -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "Vrstica" - -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "Običajno okno programa" - -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "Pogovorno okno" - -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "Modalno pogovorno okno" - -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "Paleta pripomočkov" - -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "Odtrgan meni" - -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "Okvir" - -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "Pripeto modalno okno" +msgid "" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" +msgstr "" +"mutter %s\n" +"Avtorske pravice pridržane (C) 2001-%d Havoc Pennington, Red Hat in drugi\n" +"To je prosta programska oprema; za pogoje kopiranja si oglejte dovoljenje.\n" +"Program je na voljo BREZ KAKRŠNIHKOLI ZAGOTOVIL.\n" -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "Preizkus razporeditve gumbov %d" +#: src/core/mutter.c:52 +msgid "Print version" +msgstr "Izpiši različico" -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g milisekund za risanje ene sličice okna" +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "Vstavek Mutter za uporabo" -#: ../src/ui/theme-viewer.c:813 +# G:1 K:0 O:0 +#: src/core/prefs.c:1911 #, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Uporaba: metacity-theme-viewer [IMETEME]\n" +msgid "Workspace %d" +msgstr "Delovna površina %d" -#: ../src/ui/theme-viewer.c:820 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "Napaka med nalaganjem teme: %s\n" +#: src/core/util.c:122 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "" +"Program Mutter je kodno preveden brez podpore za podrobni način izpisovanja\n" -#: ../src/ui/theme-viewer.c:826 +#: src/wayland/meta-wayland-tablet-pad.c:568 #, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "Tema \"%s\" naložena v %g sekundah\n" - -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "Običajna pisava naziva" - -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "Majhna pisava naziva" - -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "Velika pisava naziva" - -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "Razpored gumbov" - -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "Primerjalni preizkus" +msgid "Mode Switch: Mode %d" +msgstr "Način preklopa: način %d" -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "Tukaj je izpisan naziv okna" - -#: ../src/ui/theme-viewer.c:1047 +#: src/x11/meta-x11-display.c:676 #, c-format -msgid "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g seconds wall clock time including X server resources (%g milliseconds per frame)\n" -msgstr "Izrisanih %d sličic v %g sekundah odjemalca (%g milisekund na sličico) in %g sekund v času stenske ure, upoštevajoč sredstva strežnika X (%g milisekund na sličico)\n" - -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "preizkus izjave položaja je vrnil logični PRAV, vendar je določil tudi napako" - -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "preizkus izjave položaja je vrnil logični NAPAK in ni določil napake" +msgid "" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." +msgstr "" +"Zaslon »%s« že ima določen upravljalnik oken; poskušajte uporabiti možnost --" +"replace za zamenjavo trenutnega upravljalnika zaslona." -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "Pričakovana je napaka, vendar ni odziva" +#: src/x11/meta-x11-display.c:1089 +msgid "Failed to initialize GDK\n" +msgstr "Začenjanje okolja GDK je spodletelo\n" -#: ../src/ui/theme-viewer.c:1274 +#: src/x11/meta-x11-display.c:1113 #, c-format -msgid "Error %d was expected but %d given" -msgstr "Pričakovana je napaka %d, vrnjena pa je bila %d" +msgid "Failed to open X Window System display “%s”\n" +msgstr "Odpiranje zaslona »%s« okenskega sistema X je spodletelo\n" -#: ../src/ui/theme-viewer.c:1280 +#: src/x11/meta-x11-display.c:1196 #, c-format -msgid "Error not expected but one was returned: %s" -msgstr "Napaka ni pričakovana, vendar je vrnjen odziv: %s" +msgid "Screen %d on display “%s” is invalid\n" +msgstr "Zaslon %d na prikazu »%s« ni veljaven\n" -#: ../src/ui/theme-viewer.c:1284 +#: src/x11/meta-x11-selection-input-stream.c:460 #, c-format -msgid "x value was %d, %d was expected" -msgstr "vrednost x je %d, pričakovana pa je %d" +msgid "Format %s not supported" +msgstr "Zapis %s ni podprt." -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "vrednost y je %d, pričakovana pa je %d" +# G:2 K:6 O:0 +#: src/x11/session.c:1821 +msgid "" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." +msgstr "" +"Ta okna ne podpirajo možnosti »shranjevanja trenutnih nastavitev«, zato jih " +"bo treba ob naslednji prijavi zagnati ročno." -#: ../src/ui/theme-viewer.c:1352 +#: src/x11/window-props.c:569 #, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "%d izjav koordinat razčlenjenih v %g sekundah (%g sekund v povprečju)\n" - -#~ msgid "Switch to workspace 1" -#~ msgstr "Preklopi na delovno površino 1" - -#~ msgid "Switch to workspace 2" -#~ msgstr "Preklopi na delovno površino 2" - -#~ msgid "Switch to workspace 3" -#~ msgstr "Preklopi na delovno površino 3" - -#~ msgid "Switch to workspace 4" -#~ msgstr "Preklopi na delovno površino 4" - -#~ msgid "Switch to workspace 5" -#~ msgstr "Preklopi na delovno površino 5" - -#~ msgid "Switch to workspace 6" -#~ msgstr "Preklopi na delovno površino 6" - -#~ msgid "Switch to workspace 7" -#~ msgstr "Preklopi na delovno površino 7" - -#~ msgid "Switch to workspace 8" -#~ msgstr "Preklopi na delovno površino 8" - -#~ msgid "Switch to workspace 9" -#~ msgstr "Preklopi na delovno površino 9" - -#~ msgid "Switch to workspace 10" -#~ msgstr "Preklopi na delovno površino 10" - -#~ msgid "Switch to workspace 11" -#~ msgstr "Preklopi na delovno površino 11" +msgid "%s (on %s)" +msgstr "%s (na %s)" -#~ msgid "Switch to workspace 12" -#~ msgstr "Preklopi na delovno površino 12" +#~ msgid "Move window one workspace to the left" +#~ msgstr "Premakni okno eno delovno površino levo" -#~ msgid "Switch to workspace on the left of the current workspace" -#~ msgstr "Preklopi na delovno površino na levi od trenutne delovne površine" +#~ msgid "Move window one workspace to the right" +#~ msgstr "Premakni okno eno delovno površino desno" -#~ msgid "Switch to workspace on the right of the current workspace" -#~ msgstr "Preklopi na delovno površino na desni od trenutne delovne površine" +#~ msgid "Move to workspace left" +#~ msgstr "Premakni na levo delovno površino" -#~ msgid "Switch to workspace above the current workspace" -#~ msgstr "Preklopi na delovno površino nad trenutno delovno površino" +#~ msgid "Move to workspace right" +#~ msgstr "Premakni na desno delovno površino" -#~ msgid "Switch to workspace below the current workspace" -#~ msgstr "Preklopi na delovno površino pod trenutno delovno površino" +#~ msgid "Toggle shaded state" +#~ msgstr "Preklopi stanje senčenja" -#~ msgid "Move between windows of an application, using a popup window" -#~ msgstr "Premakni med okni programa s pojavnim oknom" +#~ msgid "Failed to scan themes directory: %s\n" +#~ msgstr "Ni mogoče preiskati mape tem: %s\n" #~ msgid "" -#~ "Move backward between windows of an application, using a popup window" -#~ msgstr "Premakni nazaj med okni programa s pojavnim oknom" - -#~ msgid "Move between windows, using a popup window" -#~ msgstr "Premakni med okni s pojavnim oknom" - -#~ msgid "Move backward between windows, using a popup window" -#~ msgstr "Premakni nazaj med okni s pojavnim oknom" - -#~ msgid "Move between panels and the desktop, using a popup window" -#~ msgstr "Premakni med pulti in namizjem s pojavnim oknom" - -#~ msgid "Move backward between panels and the desktop, using a popup window" -#~ msgstr "Premakni nazaj med pulti in namizjem s pojavnim oknom" - -#~ msgid "Move between windows of an application immediately" -#~ msgstr "Takoj premakni med okni programa" - -#~ msgid "Move backward between windows of an application immediately" -#~ msgstr "Takoj premakni nazaj med okni programa" +#~ "Could not find a theme! Be sure %s exists and contains the usual themes.\n" +#~ msgstr "" +#~ "Ni mogoče najti teme! Prepričajte se, da %s obstaja in vsebuje običajni " +#~ "zapis teme.\n" -#~ msgid "Move between windows immediately" -#~ msgstr "Takoj premakni med okni" +#~ msgid "Screen %d on display \"%s\" already has a window manager\n" +#~ msgstr "" +#~ "Zaslon %d na prikazu \"%s\" je že upravljan z upravljalnikom oken\n" -#~ msgid "Move backward between windows immediately" -#~ msgstr "Takoj premakni nazaj med okni" +#~ msgid "%d x %d" +#~ msgstr "%d x %d" -#~ msgid "Move between panels and the desktop immediately" -#~ msgstr "Takoj premakni med pulti in namizjem" +#~ msgid "top" +#~ msgstr "zgoraj" diff --git a/po/sq.po b/po/sq.po index c5ceba376..27f7c8918 100644 --- a/po/sq.po +++ b/po/sq.po @@ -11,6 +11,7 @@ msgstr "" "PO-Revision-Date: 2008-09-27 12:27+0200\n" "Last-Translator: Laurent Dhima <laurenti@alblinux.net>\n" "Language-Team: albanian <gnome-albanian-perkthyesit@lists.sourceforge.net>\n" +"Language: sq\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" diff --git a/po/sr.po b/po/sr.po index abb5860c0..1fb3aec68 100644 --- a/po/sr.po +++ b/po/sr.po @@ -1,443 +1,292 @@ -# Serbian translation of metacity -# Courtesy of Prevod.org team (http://prevod.org/) -- 2003—2012. -# This file is distributed under the same license as the metacity package. -# Maintainer: Горан Ракић <grakic@devbase.net> -# Reviewed on 2005-09-03 by: Данило Шеган <danilo@prevod.org>" +# Serbian translation of mutter. +# Courtesy of Prevod.org team (http://prevod.org/) -- 2003—2017. +# This file is distributed under the same license as the mutter package. +# Translators: +# Горан Ракић <grakic@devbase.net> +# Данило Шеган <danilo@prevod.org>, 2005. # Милош Поповић <gpopac@gmail.com>, 2010. -# Мирослав Николић <miroslavnikolic@rocketmail.com>, 2011, 2012. +# Мирослав Николић <miroslavnikolic@rocketmail.com>, 2011—2017. msgid "" msgstr "" -"Project-Id-Version: metacity\n" -"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=muffin" -"&keywords=I18N+L10N&component=general\n" -"POT-Creation-Date: 2012-03-11 21:56+0000\n" -"PO-Revision-Date: 2012-03-13 08:36+0200\n" -"Last-Translator: Мирослав Николић <miroslavnikolic@rocketmail.com>\n" -"Language-Team: Serbian <gnom@prevod.org>\n" +"Project-Id-Version: mutter\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2020-02-23 17:41+0000\n" +"PO-Revision-Date: 2020-03-08 21:20+0100\n" +"Last-Translator: Марко М. Костић <marko.m.kostic@gmail.com>\n" +"Language-Team: српски <gnome-sr@googlegroups.org>\n" "Language: sr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : " -"n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : n" +"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "X-Project-Style: gnome\n" +"X-Generator: Poedit 2.3\n" -#: ../src/50-muffin-windows.xml.in.h:1 -msgid "Windows" -msgstr "Прозори" - -#: ../src/50-muffin-windows.xml.in.h:2 -msgid "View split on left" -msgstr "Прикажите поделу на лево" - -#: ../src/50-muffin-windows.xml.in.h:3 -msgid "View split on right" -msgstr "Прикажите поделу на десно" - -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format -msgid "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." -msgstr "" -"Неки други композитни управник је већ покренут на приказу %i еркана „%s“." - -#: ../src/core/bell.c:307 -msgid "Bell event" -msgstr "Звонца" - -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Захтевана је непозната информација о прозору: %d" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Навигација" -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> не даје одзив." +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Премешта прозор на радни простор број 1" -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "Програм не даје одзив." +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Премешта прозор на радни простор број 2" -#: ../src/core/delete.c:119 -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "" -"Можете мало сачекати док се програм не сабере или приморати програм да " -"комплетно прекине са радом." +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Премешта прозор на радни простор број 3" -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "_Сачекај" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Премешта прозор на радни простор број 4" -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "_Приморај излаз" +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Премешта прозор на последњи радни простор" -#: ../src/core/display.c:361 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "Недостаје потребан композитни додатак %s" +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "Премешта прозор један радни простор на горе" -#: ../src/core/display.c:427 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Нисам успео да отворим екран „%s“ Икс система прозора\n" +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "Премешта прозор један радни простор на доле" -#: ../src/core/keybindings.c:852 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "" -"Неки други програм већ користи тастер %s са измењивачима %x за неку " -"функцију\n" +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "Премешта прозор један монитор на лево" -#: ../src/core/main.c:206 -msgid "Disable connection to session manager" -msgstr "Онемогућава везу са управником сесије" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "Премешта прозор један монитор на десно" -#: ../src/core/main.c:212 -msgid "Replace the running window manager" -msgstr "Мења текућег управника прозорима" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "Премешта прозор један монитор на горе" -#: ../src/core/main.c:218 -msgid "Specify session management ID" -msgstr "Наводи ИД за управљање сесијом" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "Премешта прозор један монитор на доле" -#: ../src/core/main.c:223 -msgid "X Display to use" -msgstr "Икс екран који ће бити коришћен" +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "Пребацује програме" -#: ../src/core/main.c:229 -msgid "Initialize session from savefile" -msgstr "Користи сесију из датотеке" +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "Пребацује на претходни програм" -#: ../src/core/main.c:235 -msgid "Make X calls synchronous" -msgstr "Чини Икс позиве усклађеним" +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "Пребацује прозоре" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Нисам успео да прочитам директоријум тема: %s\n" +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "Пребацује на претходни прозор" -#: ../src/core/main.c:520 -#, c-format -msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "" -"Не могу да пронђем тему! Проверите да %s постоји и да садржи уобичајне " -"теме.\n" +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "Пребацује прозоре програма" -#: ../src/core/muffin.c:40 -#, c-format -msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" -"матер %s\n" -"Сва права задржана (C) 2001–%d Havoc Pennington, Red Hat, Inc., и остали\n" -"Ово је слободан програм; погледајте изворни код за услове коришћења.\n" -"НЕ постоји никаква гаранција; чак ни гаранција о ТРЖИШНОЈ ВРЕДНОСТИ или " -"ПРИЛАГОЂЕНОСТИ ОДРЕЂЕНОЈ НАМЕНИ.\n" +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "Пребацује на претходни прозор програма" -#: ../src/core/muffin.c:54 -msgid "Print version" -msgstr "Исписује издање" +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "Пребацује контроле система" -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "Списак додатака раздвојених зарезом" +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "Пребацује на претходну контролу система" -#: ../src/core/prefs.c:1077 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"Компромиси за лоше програме су искључени. Неке апликације се могу понашати " -"чудно.\n" +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "Пребацује прозоре директно" -#: ../src/core/prefs.c:1152 -#, c-format -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "Не могу да обрадим опис „%s“ из кључа „%s“ у Гномовим подешавањима\n" +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "Пребацује непосредно на претходни прозор" -#: ../src/core/prefs.c:1218 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"„%s“ је пронађен у бази подешавања што није исправна вредност која мења " -"понашање тастера миша\n" +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "Пребацује прозоре програма директно" -#: ../src/core/prefs.c:1736 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "„%s“ из базе са подешавањима није исправна комбинација тастера „%s“\n" +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "Пребацује непосредно на претходни прозор програма" -#: ../src/core/prefs.c:1833 -#, c-format -msgid "Workspace %d" -msgstr "%d. радни простор" +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "Пребацује контроле система директно" -#: ../src/core/screen.c:730 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "Приказ %d на екрану „%s“ није исправан\n" +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "Пребацује непосредно на претходну контролу система" -#: ../src/core/screen.c:746 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"Приказ %d на екрану „%s“ већ има управника прозора; покушајте да користите --" -"replace опцију да замените тренутног управника прозора.\n" +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "Скрива све обичне прозоре" -#: ../src/core/screen.c:773 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "Не могу да добијем избор управника прозора на приказу %d еркана „%s“\n" +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "Пребацује се на радни простор 1" -#: ../src/core/screen.c:828 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "Приказ %d на екрану „%s“ већ има управника прозора\n" +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "Пребацује се на радни простор 2" -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "Не могу да отпустим приказ %d на екрану „%s“\n" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "Пребацује се на радни простор 3" -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Не могу да направим директоријум „%s“: %s\n" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "Пребацује се на радни простор 4" -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "Не могу да отворим датотеку сесије „%s“ за упис: %s\n" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "Пребацује се на последњи радни простор" -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Грешка приликом уписа у датотеку сесије „%s“: %s\n" +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "Премешта на радни простор изнад" -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Грешка приликом затварања датотеке сесије „%s“: %s\n" +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "Премешта на радни простор испод" -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Нисам успео да обрадим сачувану датотеку сесије: %s\n" +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "Систем" -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "Атрибут <muffin_session> је примећен али ми већ имамо ИБ сесије" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Приказује упит за извршавање наредбе" -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Непознат атрибут %s у <%s> елементу" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Приказује преглед активности" -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "угњежден <window> елемент" +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Поврати пречице на тастатури" -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "Непознат елемент %s" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Прозори" -#: ../src/core/session.c:1809 -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" -"Ови прозори не подржавају могућност „сними тренутна подешавања“ па ћете " -"морати да их ручно поново покренете када се следећи пут пријавите." +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "Активира мени прозора" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Нисам успео да отворим историјат грешака: %s\n" +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Искључује или укључује приказ преко целог екрана" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Нисам успео да fdopen() датотеку са историјатом %s: %s\n" +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "Искључује или укључује стање увећања" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "Отворена датотека са историјатом %s\n" +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "Увећава прозор" -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "Матер је преведен без подршке за опширан режим\n" +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Враћа величину прозора" -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "Управник прозора: " +#: data/50-mutter-windows.xml:18 +msgid "Close window" +msgstr "Затвара прозор" -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "Грешка у управнику прозора: " +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "Скрива прозор" -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "Упозорење управника прозора: " +#: data/50-mutter-windows.xml:22 +msgid "Move window" +msgstr "Премешта прозор" -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "Грешка управника прозора: " +#: data/50-mutter-windows.xml:24 +msgid "Resize window" +msgstr "Мења величину прозора" -#. first time through -#: ../src/core/window.c:7224 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"Прозор %s је поставио SM_CLIENT_ID на самог себе уместо на WM_CLIENT_LEADER " -"прозор као што је наведено у ICCCM.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7887 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %" -"d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"Прозор %s је поставио MWM што наговештава да није променљиве величине, али " -"је поставио најмању величину %d x %d и највећу величину %d x %d; што нема " -"много смисла.\n" +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "Приказује прозор на свим радним просторима или само на једном" -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "Програм је поставио нетачан _NET_WM_PID %lu\n" +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "Издиже прозор уколико га други прозор заклања, у противном га спушта" -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (на %s)" +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "Издиже прозор изнад осталих прозора" -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "Неисправан прозор 0x%lx наведен као WM_TRANSIENT_FOR за %s.\n" +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "Спушта прозор испод осталих прозора" -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "WM_TRANSIENT_FOR прозор 0x%lx за %s ће направити петљу.\n" +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "Увећава прозор вертикално" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"Прозор 0x%lx има особину %s\n" -"тако да је очекивано да има врсту %s формат %d,\n" -"а заправо има врсту %s формат %d n_ставки %d.\n" -"Ово је највероватније грешка у програму, а не у управнику прозора.\n" -"Прозор има наслов=„%s“ класа=„%s“ назив=„%s“\n" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "Увећава прозор хоризонтално" -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "Особина %s прозора 0x%lx садржи неисправан УТФ-8\n" +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "Прикажите поделу на лево" -#: ../src/core/xprops.c:494 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"Особина %s прозора 0x%lx садржи неисправан УТФ-8 за ставку %d на списку\n" +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "Прикажите поделу на десно" -#: ../src/muffin.desktop.in.h:1 ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" +#: data/mutter.desktop.in:4 +msgid "Mutter" msgstr "Матер" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 +#: data/org.gnome.mutter.gschema.xml.in:7 msgid "Modifier to use for extended window management operations" msgstr "Тастер који се користи за проширене радње управника прозорима" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 +#: data/org.gnome.mutter.gschema.xml.in:8 msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." msgstr "" -"Овај кључ покреће преклапање (overlay), које комбинује преглед прозора и " +"Овај кључ покреће „overlay“ (преклапање), које комбинује преглед прозора и " "покретач програма. Подразумевано је намењен као „Windows key“ (кључ прозора) " "за компоненте рачунара. Очекује се да ово везује или подразумевани или низ " "празних знакова." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 +#: data/org.gnome.mutter.gschema.xml.in:20 msgid "Attach modal dialogs" msgstr "Прилагање модалних прозорчића" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 +#: data/org.gnome.mutter.gschema.xml.in:21 msgid "" "When true, instead of having independent titlebars, modal dialogs appear " "attached to the titlebar of the parent window and are moved together with " "the parent window." msgstr "" "Када је изабрано, уместо независних линија наслова, модални прозорчићи се " -"појављују приложени на линију алата матичног прозора и бивају премештани " +"појављују приложени на траку алата матичног прозора и бивају премештани " "заједно са матичним прозором." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -msgid "Live Hidden Windows" -msgstr "Одржавање скривених прозора" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"Одређује да ли да скривени прозори (нпр. умањени прозори или прозори на " -"другој радној површи) остану покренути." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 +#: data/org.gnome.mutter.gschema.xml.in:30 msgid "Enable edge tiling when dropping windows on screen edges" msgstr "" "Укључује поплочавање ивице приликом отпуштања прозора на ивицама екрана" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 +#: data/org.gnome.mutter.gschema.xml.in:31 msgid "" "If enabled, dropping windows on vertical screen edges maximizes them " "vertically and resizes them horizontally to cover half of the available " @@ -447,25 +296,25 @@ msgstr "" "усправно и мења им величину водоравно да прекрију половину доступне области. " "Отпуштање прозора на горњој ивици екрана увећава их у потпуности." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 +#: data/org.gnome.mutter.gschema.xml.in:40 msgid "Workspaces are managed dynamically" msgstr "Радним просторима се управља динамички" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 +#: data/org.gnome.mutter.gschema.xml.in:41 msgid "" -"Determines whether workspaces are managed dynamically or whether there's a " +"Determines whether workspaces are managed dynamically or whether there’s a " "static number of workspaces (determined by the num-workspaces key in org." "gnome.desktop.wm.preferences)." msgstr "" "Одређује да ли се радним просторима управља динамички или ће постојати " -"стални број радних простора (одређен бројем радних простора у " -"„org.cinnamon.desktop.wm.preferences“)." +"стални број радних простора (одређен бројем радних простора у „org.gnome." +"desktop.wm.preferences“)." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 +#: data/org.gnome.mutter.gschema.xml.in:50 msgid "Workspaces only on primary" msgstr "Радни простори само на примарне" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 +#: data/org.gnome.mutter.gschema.xml.in:51 msgid "" "Determines whether workspace switching should happen for windows on all " "monitors or only for windows on the primary monitor." @@ -473,11 +322,11 @@ msgstr "" "Одређује да ли пребацивање радног простора треба да се деси за прозоре на " "свим мониторима или само за прозоре на главном монитору." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 +#: data/org.gnome.mutter.gschema.xml.in:59 msgid "No tab popup" msgstr "Без искакања језичка" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 +#: data/org.gnome.mutter.gschema.xml.in:60 msgid "" "Determines whether the use of popup and highlight frame should be disabled " "for window cycling." @@ -485,3380 +334,1156 @@ msgstr "" "Одређује да ли ће употреба оквира искакања и истицања бити приказана за " "кретање по прозорима." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Застој првог плана се мења док се показивач не заустави" + +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" +"Ако је изабрано, а режим првог плана је или „sloppy“ или „mouse“ онда први " +"план неће бити мењан одмах по уласку у прозор, већ само након што показивач " +"престане да се помера." + +#: data/org.gnome.mutter.gschema.xml.in:79 msgid "Draggable border width" msgstr "Ширина ивице за превлачење" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 +#: data/org.gnome.mutter.gschema.xml.in:80 msgid "" -"The amount of total draggable borders. If the theme's visible borders are " +"The amount of total draggable borders. If the theme’s visible borders are " "not enough, invisible borders will be added to meet this value." msgstr "" "Износ укупне ивице за превлачење. Ако видљиве ивице теме нису довољне, биће " "додате невидљиве ивице за достизање ове вредности." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:17 -msgid "Select window from tab popup" -msgstr "Бира прозор из језичка искакања" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:18 -msgid "Cancel tab popup" -msgstr "Отказивање језичка искакања" - -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "Употреба: %s\n" - -#: ../src/ui/frames.c:1158 -msgid "Close Window" -msgstr "Затвори прозор" - -#: ../src/ui/frames.c:1161 -msgid "Window Menu" -msgstr "Изборник прозора" - -#: ../src/ui/frames.c:1164 -msgid "Minimize Window" -msgstr "Умањи прозор" - -#: ../src/ui/frames.c:1167 -msgid "Maximize Window" -msgstr "Увећај прозор" - -#: ../src/ui/frames.c:1170 -msgid "Restore Window" -msgstr "Врати величину прозора" - -#: ../src/ui/frames.c:1173 -msgid "Roll Up Window" -msgstr "Замотај прозор" - -#: ../src/ui/frames.c:1176 -msgid "Unroll Window" -msgstr "Одмотај прозор" - -#: ../src/ui/frames.c:1179 -msgid "Keep Window On Top" -msgstr "Постави прозор изнад осталих" - -#: ../src/ui/frames.c:1182 -msgid "Remove Window From Top" -msgstr "Уклони прозор са врха" - -#: ../src/ui/frames.c:1185 -msgid "Always On Visible Workspace" -msgstr "Увек на приказаној радној површи" - -#: ../src/ui/frames.c:1188 -msgid "Put Window On Only One Workspace" -msgstr "Постави прозор само на једну радну површ" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "_Умањи" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "Ув_ећај" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "Поништи у_већање" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "_Замотај" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "_Одмотај" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "_Премести" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "П_ромени величину" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "Премести насловну линију на _екран" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "Увек изнад ос_талих" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "_Увек на видљивом радном простору" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "Само на _овом радном простору" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "Премести на радни простор ле_во" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "Премести на радни простор де_сно" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "Премести на радни простор го_ре" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "Премести на радни простор до_ле" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "_Затвори" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "Радни простор %d%n" - -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "1_0. радни простор" - -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "%s%d. радни простор" - -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "Премести на други _радни простор" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Шифт" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ктрл" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Алт" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Мета" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Супер" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Хипер" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Мод2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Мод3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Мод4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Мод5" - -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" - -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "горњу" - -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "доњу" +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "Сам увећава повећане прозоре најближег монитора" -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "леву" - -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "десну" - -#: ../src/ui/theme.c:286 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "геометрија оквира не подешава „%s“ димензију" - -#: ../src/ui/theme.c:305 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "геометрија оквира не подешава „%s“ димензију за ивицу „%s“" - -#: ../src/ui/theme.c:342 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "Однос размере дугмета %g није разуман" - -#: ../src/ui/theme.c:354 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "Геометрија оквира не подешава величину дугмића" - -#: ../src/ui/theme.c:1067 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "Преливи морају имати најмање две боје" - -#: ../src/ui/theme.c:1219 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:90 msgid "" -"GTK custom color specification must have color name and fallback in " -"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." msgstr "" -"Спецификација произвољне ГТК боје мора имати назив боје и пребацивање у " -"загради, на пример gtk:custom(foo,bar); не могу да обрадим „%s“" +"Ако је укључено, нови прозори који су почетно величине монитора самостално " +"бивају увећани." -#: ../src/ui/theme.c:1235 -#, c-format -msgid "" -"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" -"_ are valid" -msgstr "" -"Неисправан знак „%c“ параметра назив_боје у gtk:custom, иасправни су само A-" -"Za-z0-9-_" +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Нови прозор у средиште" -#: ../src/ui/theme.c:1249 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:99 msgid "" -"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " -"fit the format" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." msgstr "" -"Гтк:произвољни формат је „gtk:custom(назив_боје,пребацивање)“, „%s“ се не " -"уклапа у формат" +"Ако је изабрано, нови прозори ће увек бити постављени на средину радног " +"екрана монитора." -#: ../src/ui/theme.c:1294 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"Спецификација ГТК боје мора имати наведено стање у загради, на пример gtk:fg" -"[NORMAL] где је NORMAL стање; не могу да обрадим „%s“" +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Укључује експерименталне функције" -#: ../src/ui/theme.c:1308 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:108 msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes " +"mutter request a low priority real-time scheduling. The executable or user " +"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — " +"initializes Xwayland lazily if there are X11 clients. Requires restart." msgstr "" -"Спецификација ГТК боје мора имати наведено стање у загради, на пример gtk:fg" -"[NORMAL] где је NORMAL стање; не могу да обрадим „%s“" - -#: ../src/ui/theme.c:1319 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "Нисам разумео стање „%s“ у спецификацији боје" - -#: ../src/ui/theme.c:1332 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "Нисам разумео део боје „%s“ у спецификацији боје" - -#: ../src/ui/theme.c:1361 -#, c-format +"Да укључите пробне функције, додајте кључну реч функције на списак. Да ли " +"функција захтева поновно покретање састављача зависи од дате функције. Није " +"потребно да нека пробна могућност буде и даље доступна или подесива. Немојте " +"очекивати да додавање било чега у овом подешавању буде отпорно на будуће " +"измене. Тренутно могуће кључне речи су: • „scale-monitor-framebuffer“ — чини " +"да матер подразумевано распоређује логичке екране у логичком координантном " +"простору пиксела, приликом промене величине спремишта кадрова екрана уместо " +"садржаја прозора, зарад управљања екранима високе резолуције. Не захтева " +"поновно покретање. • „rt-scheduler“ — чини да матер затражи заказивање у " +"реалном времену нижег приоритета. Извршна датотека или корисник мора имати " +"CAP_SYS_NICE. Потребно је поновно покретање. • “autostart-xwayland” — лењо " +"покреће Икс-вејланд ако има Икс11 клијената. Потребно је поновно покретање." + +#: data/org.gnome.mutter.gschema.xml.in:134 +msgid "Modifier to use to locate the pointer" +msgstr "Тастер који се користи за проналажење показивача" + +#: data/org.gnome.mutter.gschema.xml.in:135 +msgid "This key will initiate the “locate pointer” action." +msgstr "Овај тастер ће покренути „пронађи показивач“ радњу" + +#: data/org.gnome.mutter.gschema.xml.in:142 +msgid "Timeout for check-alive ping" +msgstr "Време истицања провере живахности" + +#: data/org.gnome.mutter.gschema.xml.in:143 msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" +"Number of milliseconds a client has to respond to a ping request in order to " +"not be detected as frozen. Using 0 will disable the alive check completely." msgstr "" -"Формат смеше је „blend/bg_color/fg_color/alpha“, „%s“ се не уклапа у тражени " -"формат записа" - -#: ../src/ui/theme.c:1372 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "Не могу да обрадим алфа вредност „%s“ у смешаној боји" - -#: ../src/ui/theme.c:1382 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "Алфа вредност „%s“ у смешаној боји није између 0.0 и 1.0" - -#: ../src/ui/theme.c:1429 -#, c-format -msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "Формат сенке је „shade/base_color/factor“, „%s“ се не уклапа у формат" - -#: ../src/ui/theme.c:1440 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "Не могу да обрадим фактор сенке „%s“ у осенченој боји" - -#: ../src/ui/theme.c:1450 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "Фактор сенке „%s“ у осенченој боји је негативан" - -#: ../src/ui/theme.c:1479 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Не могу да обрадим боју „%s“" +"Број милисекунди за које клијент мора одговорити на пинг захтев да се не би " +"сматрао замрзнутим. Унос броја 0 ће онемогућити проверу живахности у " +"потпуности." -#: ../src/ui/theme.c:1790 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "Израз координата садржи знак „%s“ који није дозвољен" - -#: ../src/ui/theme.c:1817 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "Израз координата садржи децимални број „%s“ који не може бити обрађен" - -#: ../src/ui/theme.c:1831 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "Израз координата садржи цели број „%s“ који не може бити обрађен" - -#: ../src/ui/theme.c:1953 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "" -"Израз са координатама садржи непознати оператор на почетку овог текста: „%s“" +#: data/org.gnome.mutter.gschema.xml.in:165 +msgid "Select window from tab popup" +msgstr "Бира прозор из језичка искакања" -#: ../src/ui/theme.c:2010 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "Израз са координатама је био празан или неразумљив" +#: data/org.gnome.mutter.gschema.xml.in:170 +msgid "Cancel tab popup" +msgstr "Отказивање језичка искакања" -#: ../src/ui/theme.c:2121 ../src/ui/theme.c:2131 ../src/ui/theme.c:2165 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "Израз са координатама води дељењу са нулом" +#: data/org.gnome.mutter.gschema.xml.in:175 +msgid "Switch monitor configurations" +msgstr "Мења подешавања монитора" -#: ../src/ui/theme.c:2173 -#, c-format -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "" -"Израз са координатам покушава да користи оператор остатка при дељењу за " -"децимални број" +#: data/org.gnome.mutter.gschema.xml.in:180 +msgid "Rotates the built-in monitor configuration" +msgstr "Заокреће уграђена подешавања монитора" -#: ../src/ui/theme.c:2229 -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "Израз са координатама има оператор „%s“ где је очекиван операнд" +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Прелазак на ВТ 1" -#: ../src/ui/theme.c:2238 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "Израз са координарама има операнд где је очекиван оператор" +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Прелазак на ВТ 2" -#: ../src/ui/theme.c:2246 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "Израз са координарама је завршио са оператором уместо са операндом" +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Прелазак на ВТ 3" -#: ../src/ui/theme.c:2256 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" -"Израз са координатама има оператор „%c“, а затим оператор „%c“ без операнда " -"између" +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Прелазак на ВТ 4" -#: ../src/ui/theme.c:2407 ../src/ui/theme.c:2452 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "Израз са координатама има непознату променљиву или константи „%s“" +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Прелазак на ВТ 5" -#: ../src/ui/theme.c:2506 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "Израз са координатама је био превелики за смештај и обраду." +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Прелазак на ВТ 6" -#: ../src/ui/theme.c:2535 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "Израз са координатама има затворене заграде без отворених заграда" +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Прелазак на ВТ 7" -#: ../src/ui/theme.c:2599 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "Израз са координатама има отворене заграде без затворених заграда" +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Прелазак на ВТ 8" -#: ../src/ui/theme.c:2610 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "Израз са координатама нема ни један оператор или операнд" +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Прелазак на ВТ 9" -#: ../src/ui/theme.c:2822 ../src/ui/theme.c:2842 ../src/ui/theme.c:2862 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "Тема садржи израз који резултира грешком: %s\n" +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Прелазак на ВТ 10" -#: ../src/ui/theme.c:4533 -#, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"било шта\"/> мора бити " -"наведен за овај стил оквира" +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Прелазак на ВТ 11" -#: ../src/ui/theme.c:5066 ../src/ui/theme.c:5091 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" -"Недостаје <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"било шта\"/>" +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Прелазак на ВТ 12" -#: ../src/ui/theme.c:5139 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Нисам успео да учитам тему „%s“: %s\n" +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "Поново укључивање пречица" -#: ../src/ui/theme.c:5275 ../src/ui/theme.c:5282 ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 ../src/ui/theme.c:5303 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "Није дефинисан елемент <%s> за тему „%s“" +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow X11 grabs to lock keyboard focus with Xwayland" +msgstr "Дозволи Икс11 грабљења да закључају фокус тастатуре у Икс-вејланду" -#: ../src/ui/theme.c:5311 -#, c-format +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" +"Allow all keyboard events to be routed to X11 “override redirect” windows " +"with a grab when running in Xwayland. This option is to support X11 clients " +"which map an “override redirect” window (which do not receive keyboard " +"focus) and issue a keyboard grab to force all keyboard events to that " +"window. This option is seldom used and has no effect on regular X11 windows " +"which can receive keyboard focus under normal circumstances. For a X11 grab " +"to be taken into account under Wayland, the client must also either send a " +"specific X11 ClientMessage to the root window or be among the applications " +"white-listed in key “xwayland-grab-access-rules”." msgstr "" -"Није подешен стил оквира за прозор врсте „%s“ у теми „%s“. Додајте <window " -"type=\"%s\" style_set=\"било шта\"/> елемент." - -#: ../src/ui/theme.c:5709 ../src/ui/theme.c:5771 ../src/ui/theme.c:5834 -#, c-format +"Дозволи да се сви догађаји тастатуре преусмере на Икс11 \"override redirect" +"\" прозоре са грабљењем када се извршавају унутар Икс-вејленда. Ова опција " +"постоји као подршка за Икс11 клијенте који мапирају \"override redirect\" " +"прозор (који не добија фокус тастатуре) па онда пошаљу грабљење тастатуре " +"које присили све догађаје са тастатуре на овај прозор. Ова опција се ретко " +"користи и нема утицаја на обичне Икс11 прозоре који могу бити у фокусу " +"тастатуре у обичним околностима. Да би се Икс11 грабљење узело у обзир под " +"Вејлендом, клијент такође мра или послати одређену Икс11 клијентску поруку у " +"корени прозор или мора бити одобрени програм у кључу \"xwayland-grab-access-" +"rules\"." + +#: data/org.gnome.mutter.wayland.gschema.xml.in:84 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "Икс-вејленд програми којима је дозвољено да раде грабљења на тастатури" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:85 msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." msgstr "" -"Кориснички дефинисане константе морају почети великим словом; „%s“ не почиње" - -#: ../src/ui/theme.c:5717 ../src/ui/theme.c:5779 ../src/ui/theme.c:5842 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "Константа „%s“ је већ дефинисана" - -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. -#. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "Није дефинисан „%s“ атрибут у елементу <%s>" - -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Линија %d знак %d: %s" - -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "Атрибут „%s“ је поновљен два пута у истом елементу <%s>" - -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "Атрибут „%s“ је неисправан у елементу <%s> у овом контексту" - -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "Не могу да издвојим „%s“ као целобројну вредност" - -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "Не разумем водеће знаке „%s“ у низу карактера „%s“" - -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "Цели број %ld мора бити позитиван" - -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "Цели број %ld је превелик, тренутно највећи је %d" - -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "Не могу да обрадим „%s“ као децимални број" - -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "Логичке вредности морају бити „true“ или „false“, а не „%s“" - -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "Угао мора бити између 0.0 и 360.0, био је %g\n" - -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" -"Алфа степен мора бити између 0.0 (невидљиво) и 1.0 (потпуно видљиво), био је " -"%g\n" - -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"Нетачно скалирање наслова „%s“ (мора бити један од следећих: xx-small,x-" -"small,small,medium,large,x-large,xx-large)\n" - -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s> назив „%s“ је коришћен по други пут" - -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "<%s> матични „%s“ није дефинисан" - -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "<%s> геометрија „%s“ није дефинисана" - -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "" -"<%s> мора бити наведена или геометрија или матични елемент који има " -"геометрију" - -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "Морате навести позадину да би алфа вредност имала смисла" - -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Непознат тип „%s“ у елементу <%s>" - -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "Непознат style_set „%s“ у елементу <%s>" - -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "Типу прозора „%s“ је већ додељен скуп стила" - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "Елемент <%s> није дозвољен испод <%s>" - -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" -msgstr "Не могу да подесим и ширину/висину и размеру дугмади" - -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "Удаљеност „%s“ је непозната" - -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "Однос „%s“ је непознат" - -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "Ивица „%s“ је непозната" - -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "" -"Није дефинисан почетни_угао (start_angle) или од (from) атрибут у елементу <%" -"s>" - -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "Није дефинисан „extent_angle“ или „to“ атрибут у елементу <%s>" - -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "Нисам разумео вредност „%s“ као тип градијента" - -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "Нисам разумео тип попуњавања површине „%s“ у елементу <%s>" - -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "Нисам разумео стање „%s“ у елементу <%s>" - -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "Нисам разумео сенку „%s“ у елементу <%s>" - -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "Нисам разумео стрелицу „%s“ у елементу <%s>" - -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "Није дефинисан <draw_ops> означен као „%s“" - -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "Укључивање елемента draw_ops „%s“ овде би направило кружну референцу" - -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Непознат положај „%s“ за део оквира" - -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "Стил оквира већ има део на положају %s" - -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "Није дефинисан <draw_ops> са именом „%s“" - -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Непозната функција „%s“ за дугме" - -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "" -"Функција „%s“ за дугме не постоји у овој верзији (верзија %d, а треба вам %d)" - -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Непознато стање „%s“ за дугме" - -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "Стил оквира већ има дугме са функцијом %s и стањем %s" - -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "„%s“ није дозвољена вредност за атрибут фокуса" - -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "„%s“ није дозвољена вредност за атрибут стања" - -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "Стил „%s“ није дефинисан" - -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "„%s“ није дозвољена вредност за атрибут resize" - -#: ../src/ui/theme-parser.c:3147 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" -"Никако не треба имати „resize“ атрибут у елементу <%s> за увећана/засенчена " -"стања" - -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "" -"Никако не треба имати „resize“ атрибут у елементу <%s> за увећана стања" - -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "Стил је већ наведен за стање %s увећање %s фокус %s" - -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "Стил је већ наведен за стање %s фокус %s" - -#: ../src/ui/theme-parser.c:3294 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Не могу постојати два draw_ops-а за елемент <piece> (тема наводи draw_ops " -"атрибут и <draw_ops> елемент, или наводи два елемента)" - -#: ../src/ui/theme-parser.c:3332 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Не могу постојати два draw_ops-а за елемент <button> (тема наводи draw_ops " -"атрибут и <draw_ops> елемент, или наводи два елемента)" - -#: ../src/ui/theme-parser.c:3370 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Не могу постојати два draw_ops-а за елемент <menu_icon> (тема наводи " -"draw_ops атрибут и <draw_ops> елемент, или наводи два елемента)" - -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "Издање је лоше одређено „%s“" - -#: ../src/ui/theme-parser.c:3507 -msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" -msgstr "" -"Не могу да користим „version“ (издање) у metacity-theme-1.xml или metacity-" -"theme-2.xml" - -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "За ову тему је неопходно издање %s, а последња подржана тема је %d.%d" - -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "Најстарији елемент теме мора бити <metacity_theme>, а не <%s>" - -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "" -"Елемент <%s> није дозвољен унутар елемената name, author, date и description" - -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "Елемент <%s> није дозвољен унутар елемента <constant>" - -#: ../src/ui/theme-parser.c:3599 -#, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "" -"Елемент <%s> није дозвољен унутар елемената distance, border и aspect_ratio" - -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "Елемент <%s> није дозвољен унутар елемената операција цртања" - -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "Елемент <%s> није дозвољен унутар <%s> елемента" - -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "Није наведен draw_ops за део оквира" - -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "Није наведен draw_ops дугме" - -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "Није дозвољен текст унутар елемента <%s>" - -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "<%s> је наведен два пута у овој теми" - -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Нисам успео да пронађем исправну датотеку за тему %s\n" - -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "_Прозори" - -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "Про_зорче" - -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "_Важно прозорче" - -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "_Алатка" - -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "_Уводни екран" - -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "_Горње припајање" - -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "_Доње припајање" - -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "_Лево припајање" - -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "Д_есно припајање" - -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "_Сва припајања" - -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "_Радна површ" - -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "Отвори неки други од ових прозора" - -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "Ово је пробно дугме са „отвори“ иконом" - -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "Ово је пробно дугме са „изађи“ иконицом" - -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "Ово је пример поруке у пробном прозорчету" - -#: ../src/ui/theme-viewer.c:328 -#, c-format -msgid "Fake menu item %d\n" -msgstr "Лажна ставка изборника %d\n" - -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "Прозор само са ивицом" - -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "Трака" - -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "Обичан прозор програма" - -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "Прозорче" - -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "Важно прозорче" - -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "Палета алата" - -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "Откинути изборник" - -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "Ивица" - -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "Приложено важно прозорче" - -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "Проба распореда дугмића %d" - -# bug: plural-forms -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g милисекунди за исцртавање оквира једног прозора" - -#: ../src/ui/theme-viewer.c:813 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Употреба: metacity-theme-viewer [НАЗИВ_ТЕМЕ]\n" - -#: ../src/ui/theme-viewer.c:820 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "Грешка приликом учитавања теме: %s\n" - -# bug: plural-forms -#: ../src/ui/theme-viewer.c:826 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "Учитана је тема „%s“ за %g секунде\n" - -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "Обичан насловни словни лик" - -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "Мали насловни словни лик" - -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "Велики насловни словни лик" - -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "Распоред дугмића" - -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "Провера брзине" - -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "Овде иде наслов прозора" - -# bug: plural-forms -#: ../src/ui/theme-viewer.c:1047 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"Нацртао је %d оквира за %g клијентских секунди (%g милисекунди по оквиру) и %" -"g секунди времена на зидном часовнику укључујући и ресурсе Икс сервера (%g " -"милисекунди по оквиру)\n" - -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "провера израза положаја је вратила тачно, али је поставила грешку" - -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "провера израза положаја је вратила нетачно, али није поставила грешку" - -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "Очекивана је грешка, али није дата" - -#: ../src/ui/theme-viewer.c:1274 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "Очекивана је грешка %d, али је дата %d" - -#: ../src/ui/theme-viewer.c:1280 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "Грешка није очекивана, али је враћена: %s" - -#: ../src/ui/theme-viewer.c:1284 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "x вредност је била %d, а очекивана је %d" - -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "y вредност је била %d, а очекивана је %d" - -# bug: plural-forms -#: ../src/ui/theme-viewer.c:1352 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "%d израза координата је обрађено за %g секунде (просек %g секунде)\n" - -#~ msgid "Switch to workspace 1" -#~ msgstr "Пребаците се на радни простор 1" - -#~ msgid "Switch to workspace 2" -#~ msgstr "Пребаците се на радни простор 2" - -#~ msgid "Switch to workspace 3" -#~ msgstr "Пребаците се на радни простор 3" - -#~ msgid "Switch to workspace 4" -#~ msgstr "Пребаците се на радни простор 4" - -#~ msgid "Switch to workspace 5" -#~ msgstr "Пребаците се на радни простор 5" - -#~ msgid "Switch to workspace 6" -#~ msgstr "Пребаците се на радни простор 6" - -#~ msgid "Switch to workspace 7" -#~ msgstr "Пребаците се на радни простор 7" - -#~ msgid "Switch to workspace 8" -#~ msgstr "Пребаците се на радни простор 8" - -#~ msgid "Switch to workspace 9" -#~ msgstr "Пребаците се на радни простор 9" - -#~ msgid "Switch to workspace 10" -#~ msgstr "Пребаците се на радни простор 10" - -#~ msgid "Switch to workspace 11" -#~ msgstr "Пребаците се на радни простор 11" - -#~ msgid "Switch to workspace 12" -#~ msgstr "Пребаците се на радни простор 12" - -#~ msgid "Switch to workspace on the left of the current workspace" -#~ msgstr "Пребаците се на радни простор на лево" - -#~ msgid "Switch to workspace on the right of the current workspace" -#~ msgstr "Пребаците се на радни простор на десно" - -#~ msgid "Switch to workspace above the current workspace" -#~ msgstr "Пребаците се на радни простор изнад овог" - -#~ msgid "Switch to workspace below the current workspace" -#~ msgstr "Пребаците се на радни простор испод овог" - -#~ msgid "Move between windows of an application, using a popup window" -#~ msgstr "Премести између прозора програма уз искакање" - -#~ msgid "" -#~ "Move backward between windows of an application, using a popup window" -#~ msgstr "Премести уназад између прозора програма уз искакање" - -#~ msgid "Move between windows, using a popup window" -#~ msgstr "Премести између прозора уз искакање" - -#~ msgid "Move backward between windows, using a popup window" -#~ msgstr "Премести уназад између прозора уз искакање" - -#~ msgid "Move between panels and the desktop, using a popup window" -#~ msgstr "Премести између панела и радне површине уз искакање" - -#~ msgid "Move backward between panels and the desktop, using a popup window" -#~ msgstr "Премести уназад између панела и радне површине уз искакање" - -#~ msgid "Move between windows of an application immediately" -#~ msgstr "Премести одмах између прозора програма" - -#~ msgid "Move backward between windows of an application immediately" -#~ msgstr "Премести одмах уназад између прозора програма" - -#~ msgid "Move between windows immediately" -#~ msgstr "Премести одмах између прозора" - -#~ msgid "Move backward between windows immediately" -#~ msgstr "Премести одмах уназад између прозора" - -#~ msgid "Move between panels and the desktop immediately" -#~ msgstr "Премести одмах између панела и радне површине" - -#~ msgid "Move backward between panels and the desktop immediately" -#~ msgstr "Премести одмах уназад између панела и радне површине" - -#~ msgid "Hide all normal windows and set focus to the desktop" -#~ msgstr "Сакриј све обичне прозоре и прикажи радну површину" - -#~ msgid "Show the panel's main menu" -#~ msgstr "Прикажи главни мени панела" - -#~ msgid "Show the panel's \"Run Application\" dialog box" -#~ msgstr "Прикажи прозорче за покретање програма у панелу" - -#~ msgid "Start or stop recording the session" -#~ msgstr "Почиње и зауставља снимање сесије" - -#~ msgid "Take a screenshot" -#~ msgstr "Направи снимак екрана" - -#~ msgid "Take a screenshot of a window" -#~ msgstr "Направи снимак прозора" - -#~ msgid "Run a terminal" -#~ msgstr "Покрени терминал" - -#~ msgid "Activate the window menu" -#~ msgstr "Активирај мени прозора" - -#~ msgid "Toggle fullscreen mode" -#~ msgstr "Пребаци приказ преко целог екрана" - -#~ msgid "Toggle maximization state" -#~ msgstr "Промени стање увећања" - -#~ msgid "Toggle whether a window will always be visible over other windows" -#~ msgstr "Одређује да ли се прозор увек приказује изнад осталих" - -#~ msgid "Maximize window" -#~ msgstr "Увећај прозор" - -#~ msgid "Restore window" -#~ msgstr "Врати величину прозору" - -#~ msgid "Toggle shaded state" -#~ msgstr "Промени стање засенчености" - -#~ msgid "Minimize window" -#~ msgstr "Умањи прозор" - -#~ msgid "Close window" -#~ msgstr "Затвори прозор" - -#~ msgid "Move window" -#~ msgstr "Премести прозор" - -#~ msgid "Resize window" -#~ msgstr "Промени величину прозору" - -#~ msgid "Toggle whether window is on all workspaces or just one" -#~ msgstr "Приказује прозор на свим или само на једној радној површи" - -#~ msgid "Move window to workspace 1" -#~ msgstr "Премести прозор на радни простор број 1" - -#~ msgid "Move window to workspace 2" -#~ msgstr "Премести прозор на радни простор број 2" - -#~ msgid "Move window to workspace 3" -#~ msgstr "Премести прозор на радни простор број 3" - -#~ msgid "Move window to workspace 4" -#~ msgstr "Премести прозор на радни простор број 4" - -#~ msgid "Move window to workspace 5" -#~ msgstr "Премести прозор на радни простор број 5" - -#~ msgid "Move window to workspace 6" -#~ msgstr "Премести прозор на радни простор број 6" - -#~ msgid "Move window to workspace 7" -#~ msgstr "Премести прозор на радни простор број 7" - -#~ msgid "Move window to workspace 8" -#~ msgstr "Премести прозор на радни простор број 8" - -#~ msgid "Move window to workspace 9" -#~ msgstr "Премести прозор на радни простор број 9" - -#~ msgid "Move window to workspace 10" -#~ msgstr "Премести прозор на радни простор број 10" - -#~ msgid "Move window to workspace 11" -#~ msgstr "Премести прозор на радни простор број 11" - -#~ msgid "Move window to workspace 12" -#~ msgstr "Премести прозор на радни простор број 12" - -#~ msgid "Move window one workspace to the left" -#~ msgstr "Премести прозор за један следећи радни простор улево" - -#~ msgid "Move window one workspace to the right" -#~ msgstr "Премести прозор за један следећи радни простор удесно" - -#~ msgid "Move window one workspace up" -#~ msgstr "Премести прозор за један радни простор на горе" - -#~ msgid "Move window one workspace down" -#~ msgstr "Премести прозор за један радни простор на доле" - -#~ msgid "Raise window if it's covered by another window, otherwise lower it" -#~ msgstr "" -#~ "Подигни прозор уколико га други прозор заклања, у противном га спусти" - -#~ msgid "Raise window above other windows" -#~ msgstr "Подигни прозор изнад осталих прозора" - -#~ msgid "Lower window below other windows" -#~ msgstr "Спусти прозор испод осталих прозора" - -#~ msgid "Maximize window vertically" -#~ msgstr "Увећај прозор вертикално" +"Списак назива ресурса или класи ресурса Икс11 прозора којима је дозвољено " +"или забрањено да раде грабљења на тастатури под Икс-вејлендом. Назив ресурса " +"или класа ресурса датог Икс11 прозора се може наћи преко наредбе \"xprop " +"WM_CLASS\". Џокер знакови „*“ и „?“ унутар вредности су подржани. Вредности " +"које почињу са „!“ се стављају на црни списак, који има предност у односу на " +"бели списак, за опозив програма за подразумеваног системског списка. " +"Подразумевани системски списак садржи следеће програме: " +"\"@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@\" Корисници могу сломити постојеће " +"грабљење тако што ће употребити посебну пречицу на тастатури која је " +"наведена у кључу за везивање тастера са називом \"restore-shortcuts\"." + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. +#. +#: src/backends/meta-input-settings.c:2567 +#, c-format +msgid "Mode Switch (Group %d)" +msgstr "Режим прекидача (група %d)" -#~ msgid "Maximize window horizontally" -#~ msgstr "Увећај прозор хоризонтално" +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2590 +msgid "Switch monitor" +msgstr "Промени монитор" -#~ msgid "Move window to north-west (top left) corner" -#~ msgstr "Премести прозор у горњи, леви ћошак" +#: src/backends/meta-input-settings.c:2592 +msgid "Show on-screen help" +msgstr "Прикажи помоћ на екрану" -#~ msgid "Move window to north-east (top right) corner" -#~ msgstr "Премести прозор у горњи, десни ћошак" +#: src/backends/meta-monitor.c:223 +msgid "Built-in display" +msgstr "Уграђени дисплеј" -#~ msgid "Move window to south-west (bottom left) corner" -#~ msgstr "Премести прозор у доњи, леви ћошак" +#: src/backends/meta-monitor.c:252 +msgid "Unknown" +msgstr "Непознато" -#~ msgid "Move window to south-east (bottom right) corner" -#~ msgstr "Премести прозор у доњи, десни ћошак" +#: src/backends/meta-monitor.c:254 +msgid "Unknown Display" +msgstr "Непознат дисплеј" -#~ msgid "Move window to north (top) side of screen" -#~ msgstr "Премести прозор у врх екрана" +#: src/backends/meta-monitor.c:262 +#, c-format +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" -#~ msgid "Move window to south (bottom) side of screen" -#~ msgstr "Премести прозор у дно екрана" +#: src/backends/meta-monitor.c:270 +#, c-format +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" -#~ msgid "Move window to east (right) side of screen" -#~ msgstr "Премести прозор уз десну ивицу екрана" +#. Translators: this string will appear in Sysprof +#: src/backends/meta-profiler.c:79 +msgid "Compositor" +msgstr "Састављач" -#~ msgid "Move window to west (left) side of screen" -#~ msgstr "Премести прозор уз леву ивицу екрана" +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:533 +#, c-format +msgid "" +"Another compositing manager is already running on screen %i on display “%s”." +msgstr "" +"Неки други композитни управник је већ покренут на приказу %i екрана „%s“." -#~ msgid "Move window to center of screen" -#~ msgstr "Премести прозор на средину екрана" +#: src/core/bell.c:192 +msgid "Bell event" +msgstr "Звонца" -#~ msgid "" -#~ "There was an error running <tt>%s</tt>:\n" -#~ "\n" -#~ "%s" -#~ msgstr "" -#~ "Јавила се грешка при покретању <tt>%s</tt>:\n" -#~ "\n" -#~ "%s" +#: src/core/main.c:190 +msgid "Disable connection to session manager" +msgstr "Искључује везу са управником сесије" -#~ msgid "No command %d has been defined.\n" -#~ msgstr "Није дефинисана команда %d.\n" +#: src/core/main.c:196 +msgid "Replace the running window manager" +msgstr "Мења текућег управника прозорима" -#~ msgid "No terminal command has been defined.\n" -#~ msgstr "Није дефинисана наредба терминала.\n" +#: src/core/main.c:202 +msgid "Specify session management ID" +msgstr "Наводи ИБ управника сесије" -#~ msgid "GConf key '%s' is set to an invalid value\n" -#~ msgstr "Кључ „%s“ у гном подешавањима је подешен на непрописну вредност\n" +#: src/core/main.c:207 +msgid "X Display to use" +msgstr "Икс екран који ће бити коришћен" -#~ msgid "%d stored in GConf key %s is out of range %d to %d\n" -#~ msgstr "%d сачуван у кључу %s је изван опсега од %d до %d\n" +#: src/core/main.c:213 +msgid "Initialize session from savefile" +msgstr "Покреће сесију из датотеке чувања" -#~ msgid "GConf key \"%s\" is set to an invalid type\n" -#~ msgstr "Кључ „%s“ у гном подешавањима је подешен на непрописни тип\n" +#: src/core/main.c:219 +msgid "Make X calls synchronous" +msgstr "Чини Икс позиве усклађеним" -#~ msgid "GConf key %s is already in use and can't be used to override %s\n" -#~ msgstr "ГКонф кључ %s је већ употребљен и не може преписати %s\n" +#: src/core/main.c:226 +msgid "Run as a wayland compositor" +msgstr "Ради као вејлендов композитор" -#~ msgid "Can't override GConf key, %s not found\n" -#~ msgstr "Не могу да препишем ГКонф кључ, %s није пронађен\n" +#: src/core/main.c:232 +msgid "Run as a nested compositor" +msgstr "Ради као угнежђени композитор" -#~ msgid "Error setting number of workspaces to %d: %s\n" -#~ msgstr "Грешка приликом постављања броја радних површина на %d: %s\n" +#: src/core/main.c:238 +msgid "Run wayland compositor without starting Xwayland" +msgstr "Ради као вејлендов композитор без покретања Икс-вејленда" -#~ msgid "Error setting name for workspace %d to \"%s\": %s\n" -#~ msgstr "Грешка приликом постављања назива за радну површ %d у „%s“: %s\n" +#: src/core/main.c:246 +msgid "Run as a full display server, rather than nested" +msgstr "Ради као пуни сервер приказа, уместо као угнеждени" -#~ msgid "Error setting live hidden windows status status: %s\n" -#~ msgstr "Грешка при постављању стања скривених прозора: %s\n" +#: src/core/main.c:252 +msgid "Run with X11 backend" +msgstr "Покрени на Икс11 позадинцу" -#~ msgid "Error setting no tab popup status: %s\n" -#~ msgstr "Грешка при постављању стања без искачућих листова: %s\n" +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:151 +#, c-format +msgid "“%s” is not responding." +msgstr "„%s“ не даје одзив." -#~ msgid "" -#~ "Lost connection to the display '%s';\n" -#~ "most likely the X server was shut down or you killed/destroyed\n" -#~ "the window manager.\n" -#~ msgstr "" -#~ "Изгубио сам везу са екраном „%s“;\n" -#~ "највероватније је да је Икс сервер угашен или да сте убили\n" -#~ "менаџер прозора.\n" +#: src/core/meta-close-dialog-default.c:153 +msgid "Application is not responding." +msgstr "Програм не даје одзив." -#~ msgid "Fatal IO error %d (%s) on display '%s'.\n" -#~ msgstr "Кобна грешка са излазом/улазом: %d (%s) на екрану „%s“.\n" +#: src/core/meta-close-dialog-default.c:158 +msgid "" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." +msgstr "" +"Можете мало сачекати док се програм не сабере или приморати програм да " +"комплетно прекине са радом." -#~ msgid "Turn compositing on" -#~ msgstr "Укључи композицију" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Force Quit" +msgstr "_Приморај излаз" -#~ msgid "Turn compositing off" -#~ msgstr "Искључи композицију" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Wait" +msgstr "_Сачекај" -#~ msgid "" -#~ "Don't make fullscreen windows that are maximized and have no decorations" -#~ msgstr "" -#~ "Не постављај прозоре преко целог екрана уколико су увећани и немају " -#~ "декорацију" +#: src/core/mutter.c:38 +#, c-format +msgid "" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" +msgstr "" +"матер %s\n" +"Сва права задржана © 2001–%d Хевок Пенингтон, Ред Хет, Инк., и остали\n" +"Ово је слободан програм; погледајте изворни кôд за услове коришћења.\n" +"НЕ постоји никаква гаранција; чак ни гаранција о ТРЖИШНОЈ ВРЕДНОСТИ или " +"ПРИЛАГОЂЕНОСТИ ОДРЕЂЕНОЈ НАМЕНИ.\n" -#~ msgid "Whether window popup/frame should be shown when cycling windows." -#~ msgstr "Да ли да прозор искочи када листате прозоре." +#: src/core/mutter.c:52 +msgid "Print version" +msgstr "Исписује издање" -#~ msgid "Internal argument for GObject introspection" -#~ msgstr "Унутарњи аргумент инспекције ГОбјекта" +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "Прикључци Матера за коришћење" -#~ msgid "Failed to restart: %s\n" -#~ msgstr "Нисам успео да се поново покренем: %s\n" +#: src/core/prefs.c:1911 +#, c-format +msgid "Workspace %d" +msgstr "%d. радни простор" -#~ msgid "Error setting compositor status: %s\n" -#~ msgstr "Грешка при постављању стања композитора: %s\n" +#: src/core/util.c:122 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Матер је преведен без подршке за опширан режим\n" -#~ msgid "Error setting clutter plugin list: %s\n" -#~ msgstr "Грешка при постављању списка додатака за клатер: %s\n" +#: src/wayland/meta-wayland-tablet-pad.c:568 +#, c-format +msgid "Mode Switch: Mode %d" +msgstr "Режим прекидача: Режим %d" -#~ msgid "Clutter Plugins" -#~ msgstr "Додаци за Клатер" +#: src/x11/meta-x11-display.c:676 +#, c-format +msgid "" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." +msgstr "" +"Приказ „%s“ већ има управника прозора; пробајте да користите опцију „--" +"replace“ да замените тренутног управника прозора." -#~ msgid "Plugins to load for the Clutter-based compositing manager." -#~ msgstr "Додатак за учитавање Клатерових композитних управника." +#: src/x11/meta-x11-display.c:1089 +msgid "Failed to initialize GDK\n" +msgstr "Нисам успео да покренем ГДК\n" -#~ msgid "Window Management" -#~ msgstr "Управљање прозорима" +#: src/x11/meta-x11-display.c:1113 +#, c-format +msgid "Failed to open X Window System display “%s”\n" +msgstr "Нисам успео да отворим екран „%s“ Икс система прозора\n" -#~ msgid "Failed to parse message \"%s\" from dialog process\n" -#~ msgstr "Нисам успео да издвојим поруку „%s“ из прозорчета процеса\n" +#: src/x11/meta-x11-display.c:1196 +#, c-format +msgid "Screen %d on display “%s” is invalid\n" +msgstr "Приказ „%d“ на екрану „%s“ није исправан\n" -#~ msgid "Error reading from dialog display process: %s\n" -#~ msgstr "Грешка приликом читања из прозорчета процеса: %s\n" +#: src/x11/meta-x11-selection-input-stream.c:460 +#, c-format +msgid "Format %s not supported" +msgstr "Формат %s није подржан" -#~ msgid "" -#~ "Error launching metacity-dialog to ask about killing an application: %s\n" -#~ msgstr "" -#~ "Грешка приликом покретања metacity-dialog због упита о убијању програма „%" -#~ "s“\n" +#: src/x11/session.c:1821 +msgid "" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." +msgstr "" +"Ови прозори не подржавају могућност „сачувај тренутна подешавања“ па ћете " +"морати ручно да их поново покренете када се следећи пут пријавите." -#~ msgid "Failed to get hostname: %s\n" -#~ msgstr "Нисам успео да сазнам име компјутера: %s\n" +#: src/x11/window-props.c:569 +#, c-format +msgid "%s (on %s)" +msgstr "%s (на %s)" -#~ msgid "" -#~ "The format looks like \"<Control>a\" or <Shift><Alt>F1\".\n" -#~ "\n" -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Облик записа је „<Control>a“ или „<Shift><Alt>F1“.\n" -#~ "\n" -#~ "Програм за обраду је доста слободан и дозвољава велика или мала слова, " -#~ "као и скраћенице попут „<Ctl>“ или „<Ctrl>“. Уколико поставите опцију на " -#~ "„disabled“, неће бити коришћена ниједна комбинација тастера за ову акцију." +#~ msgid "Move window one workspace to the left" +#~ msgstr "Премешта прозор један радни простор на лево" -#~ msgid "" -#~ "The format looks like \"<Control>a\" or <Shift><Alt>F1\".\n" -#~ "\n" -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action.\n" -#~ "\n" -#~ "This keybinding may be reversed by holding down the \"shift\" key; " -#~ "therefore, \"shift\" cannot be one of the keys it uses." -#~ msgstr "" -#~ "Облик записа је „<Control>“ или „<Shift><Alt>F1“.\n" -#~ "\n" -#~ "Програм за обраду је доста слободан и дозвољава велика или мала слова, " -#~ "као и скраћенице попут „<Ctl>“ или „<Ctrl>“. Уколико поставите опцију на " -#~ "„disabled“, неће бити коришћена ниједна комбинација тастера за ову акцију." +#~ msgid "Move window one workspace to the right" +#~ msgstr "Премешта прозор један радни простор на десно" -#~ msgid "Failed to read saved session file %s: %s\n" -#~ msgstr "Нисам успео да прочитам сачувану датотеку сесије %s: %s\n" +#~ msgid "Move to workspace left" +#~ msgstr "Премешта на радни простор лево" -#~ msgid "" -#~ "Error launching metacity-dialog to warn about apps that don't support " -#~ "session management: %s\n" -#~ msgstr "" -#~ "Грешка приликом покретања metacity-dialog ради упозорења о програмима " -#~ "који не подржавају менаџер сесија: %s\n" +#~ msgid "Move to workspace right" +#~ msgstr "Премешта на радни простор десно" -#~ msgid "Metacity" -#~ msgstr "Метасити" +#~ msgid "Toggle shaded state" +#~ msgstr "Искључује или укључује стање засенчености" -#~ msgid "" -#~ "(Not implemented) Navigation works in terms of applications not windows" -#~ msgstr "(Није уграђено) Навигација ради у контексту програма, не и прозора" +#~ msgid "Failed to scan themes directory: %s\n" +#~ msgstr "Нисам успео да прочитам директоријум тема: %s\n" #~ msgid "" -#~ "A font description string describing a font for window titlebars. The " -#~ "size from the description will only be used if the titlebar_font_size " -#~ "option is set to 0. Also, this option is disabled if the " -#~ "titlebar_uses_desktop_font option is set to true." +#~ "Could not find a theme! Be sure %s exists and contains the usual themes.\n" #~ msgstr "" -#~ "Низ карактера који описује словни лик за насловну линију прозора. " -#~ "Величина из описа ће бити коришћена само ако је опција titlebar_font_size " -#~ "подешена на 0. Такође, ова опција је искључена ако је " -#~ "опцијаtitlebar_uses_desktop_font постављена на „true“." +#~ "Не могу да пронађем тему! Проверите да „%s“ постоји и да садржи " +#~ "уобичајене теме.\n" -#~ msgid "Action on title bar double-click" -#~ msgstr "Акција за дупли клик на траку са насловом" +#~ msgid "Screen %d on display \"%s\" already has a window manager\n" +#~ msgstr "Приказ %d на екрану „%s“ већ има управника прозора\n" -#~ msgid "Action on title bar middle-click" -#~ msgstr "Акција за средњи клик на траку са насловом" +#~ msgid "%d x %d" +#~ msgstr "%d x %d" -#~ msgid "Action on title bar right-click" -#~ msgstr "Акција за десни клик на траку са насловом" +#~ msgid "top" +#~ msgstr "горњу" -#~ msgid "Arrangement of buttons on the titlebar" -#~ msgstr "Распоред дугмића на линији са насловом" +#~ msgid "bottom" +#~ msgstr "доњу" -#~ msgid "" -#~ "Arrangement of buttons on the titlebar. The value should be a string, " -#~ "such as \"menu:minimize,maximize,spacer,close\"; the colon separates the " -#~ "left corner of the window from the right corner, and the button names are " -#~ "comma-separated. Duplicate buttons are not allowed. Unknown button names " -#~ "are silently ignored so that buttons can be added in future metacity " -#~ "versions without breaking older versions. A special spacer tag can be " -#~ "used to insert some space between two adjacent buttons." -#~ msgstr "" -#~ "Распоред дугмића на насловној линији. Вредност треба да буде низ " -#~ "карактера, као на пример „menu:minimize,maximize,close“; две тачке " -#~ "раздвајају леви угао прозора од десног, а дугмићи су раздвојени запетама. " -#~ "Дуплирање дугмића није дозвољено. Непозната имена дугмића се игноришу " -#~ "тако да дугмићи који у будућности буду додати у метасити не разбију " -#~ "подешавања старијих издања. Могу се користити специјалне ознака за " -#~ "раздвајање како би се направило места између два суседна дугмета." - -#~ msgid "Automatically raises the focused window" -#~ msgstr "Аутоматски подигни прозор са фокусом" - -#~ msgid "" -#~ "Clicking a window while holding down this modifier key will move the " -#~ "window (left click), resize the window (middle click), or show the window " -#~ "menu (right click). The left and right operations may be swapped using " -#~ "the \"mouse_button_resize\" key. Modifier is expressed as \"<Alt>\" " -#~ "or \"<Super>\" for example." -#~ msgstr "" -#~ "Клик на прозор за време држања овог тастера ће преместити прозор (леви " -#~ "клик), променити величину прозора (средњи клик) или приказати мени " -#~ "прозора (десни клик). Можете заменити леви и десни тастер миша помоћу " -#~ "кључа „mouse_button_resize“. На пример, тастер може бити „<Алт>“ " -#~ "или „<Супер>“." +#~ msgid "left" +#~ msgstr "леву" -#~ msgid "Commands to run in response to keybindings" -#~ msgstr "Команда коју треба покренути као одговор на притисак тастера" +#~ msgid "right" +#~ msgstr "десну" -#~ msgid "Compositing Manager" -#~ msgstr "Композитни управник" +#~ msgid "frame geometry does not specify \"%s\" dimension" +#~ msgstr "геометрија оквира не подешава „%s“ димензију" -#~ msgid "Control how new windows get focus" -#~ msgstr "Како нови прозор добија фокус" +#~ msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" +#~ msgstr "геометрија оквира не подешава „%s“ димензију за ивицу „%s“" -#~ msgid "Current theme" -#~ msgstr "Тренутна тема" +#~ msgid "Button aspect ratio %g is not reasonable" +#~ msgstr "Однос размере дугмета %g није разуман" -#~ msgid "Delay in milliseconds for the auto raise option" -#~ msgstr "Временски период у милисекундама за аутоматско подизање прозора" +#~ msgid "Frame geometry does not specify size of buttons" +#~ msgstr "Геометрија оквира не подешава величину дугмића" -#~ msgid "Determines whether Metacity is a compositing manager." -#~ msgstr "Одређује да ли је Метасити композитни управник." +#~ msgid "Gradients should have at least two colors" +#~ msgstr "Преливи морају имати најмање две боје" #~ msgid "" -#~ "Determines whether applications or the system can generate audible " -#~ "'beeps'; may be used in conjunction with 'visual bell' to allow silent " -#~ "'beeps'." +#~ "GTK custom color specification must have color name and fallback in " +#~ "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" #~ msgstr "" -#~ "Одређује да ли програми или систем могу да пусте звучне сигнале; може се " -#~ "користити уз „визуелне звуке“ ради дозвољавања тихих звукова." - -#~ msgid "Disable misfeatures that are required by old or broken applications" -#~ msgstr "Искључи лоше могућности које су обавезне за старе или лоше програме" - -#~ msgid "Enable Visual Bell" -#~ msgstr "Омогући визуелне звуке" +#~ "Спецификација произвољне ГТК боје мора имати назив боје и пребацивање у " +#~ "загради, на пример gtk:custom(foo,bar); не могу да обрадим „%s“" #~ msgid "" -#~ "If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " -#~ "the focused window will be automatically raised after a delay specified " -#~ "by the auto_raise_delay key. This is not related to clicking on a window " -#~ "to raise it, nor to entering a window during drag-and-drop." +#~ "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-" +#~ "z0-9-_ are valid" #~ msgstr "" -#~ "Ако је тачно, а начин фокуса је или „sloppy“ или „mouse“ онда ће прозор у " -#~ "фокусу бити аутоматски подигнут након истека временског периода (који је " -#~ "подешен преко auto_raise_delay кључа). Ово није повезано са подизањем " -#~ "прозора кликом, нити са фокусирањем у току повуци-и-испусти." +#~ "Неисправан знак „%c“ параметра назив_боје у gtk:custom, иасправни су само " +#~ "A-Za-z0-9-_" #~ msgid "" -#~ "If true, ignore the titlebar_font option, and use the standard " -#~ "application font for window titles." +#~ "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " +#~ "fit the format" #~ msgstr "" -#~ "Ако је тачно, игнорише се опција titlebar_font, и метасити ће користити " -#~ "стандардан словни лик програма за словни лик наслова прозора." +#~ "Гтк:произвољни формат је „gtk:custom(назив_боје,пребацивање)“, „%s“ се не " +#~ "уклапа у формат" #~ msgid "" -#~ "If true, metacity will give the user less feedback by using wireframes, " -#~ "avoiding animations, or other means. This is a significant reduction in " -#~ "usability for many users, but may allow legacy applications to continue " -#~ "working, and may also be a useful tradeoff for terminal servers. However, " -#~ "the wireframe feature is disabled when accessibility is on." +#~ "GTK color specification must have the state in brackets, e.g. gtk:" +#~ "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" #~ msgstr "" -#~ "Ако је постављено, Метасити ће кориснику приказати мање података и мање " -#~ "осећаја о „непосредном управљању“, употребом линија, избегавањем " -#~ "анимација или другим средствима. Ово је значајни недостатак по питању " -#~ "употребљивости за многе кориснике, али може омогућити старим програмима и " -#~ "терминалским серверима да раде када би иначе били непрактични. Такође, " -#~ "употреба линија је онемогућена када је укључена приступачност." +#~ "Спецификација ГТК боје мора имати наведено стање у загради, на пример " +#~ "„gtk:fg[NORMAL]“ где је „NORMAL“ стање; не могу да обрадим „%s“" #~ msgid "" -#~ "If true, then Metacity works in terms of applications rather than " -#~ "windows. The concept is a bit abstract, but in general an application-" -#~ "based setup is more like the Mac and less like Windows. When you focus a " -#~ "window in application-based mode, all the windows in the application will " -#~ "be raised. Also, in application-based mode, focus clicks are not passed " -#~ "through to windows in other applications. Application-based mode is, " -#~ "however, largely unimplemented at the moment." +#~ "GTK color specification must have a close bracket after the state, e.g. " +#~ "gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" #~ msgstr "" -#~ "Ако је тачно, метасити рада у контексту програма, а не прозора. Концепт " -#~ "је помало чудан, али у општем случају поставке базиране на програму су " -#~ "више сличне Mac систему, а мање сличне Windows систему. Када поставите " -#~ "прозор у фокус у овом начину рада, сви прозори те апликације ће бити " -#~ "подигнути. Такође, у овом начину рада, фокусни клик се не шаље прозорима " -#~ "других програма. Такође овај начин рада је увелико недовршен у садашњим " -#~ "верзијама." - -#~ msgid "If true, trade off usability for less resource usage" -#~ msgstr "" -#~ "Уколико је постављено, жртвуј употребљивост зарад употребе мање ресурса" +#~ "Спецификација ГТК боје мора имати наведено стање у загради, на пример " +#~ "„gtk:fg[NORMAL]“ где је „NORMAL“ стање; не могу да обрадим „%s“" -#~ msgid "Name of workspace" -#~ msgstr "Име радног простора" +#~ msgid "Did not understand state \"%s\" in color specification" +#~ msgstr "Нисам разумео стање „%s“ у спецификацији боје" -#~ msgid "Number of workspaces" -#~ msgstr "Број радних простора" +#~ msgid "Did not understand color component \"%s\" in color specification" +#~ msgstr "Нисам разумео део боје „%s“ у спецификацији боје" #~ msgid "" -#~ "Number of workspaces. Must be more than zero, and has a fixed maximum to " -#~ "prevent making the desktop unusable by accidentally asking for too many " -#~ "workspaces." +#~ "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit " +#~ "the format" #~ msgstr "" -#~ "Број радних простора. Мора бити већи од нуле, и имати фиксиран максимум " -#~ "како бисте спречили да случајно уништите радну површину тражећи превише " -#~ "радних простора." +#~ "Формат смеше је „blend/bg_color/fg_color/alpha“, „%s“ се не уклапа у " +#~ "тражени формат записа" -#~ msgid "Run a defined command" -#~ msgstr "Покрени дефинисану команду" +#~ msgid "Could not parse alpha value \"%s\" in blended color" +#~ msgstr "Не могу да обрадим алфа вредност „%s“ у смешаној боји" -#~ msgid "" -#~ "Set this to true to resize with the right button and show a menu with the " -#~ "middle button while holding down the key given in \"mouse_button_modifier" -#~ "\"; set it to false to make it work the opposite way around." -#~ msgstr "" -#~ "Поставите на „true“ за промену величине прозора десним тастером и приказ " -#~ "менија средњим тастером уз држање задатог тастера преко кључа " -#~ "„mouse_button_modifier“. Поставите на „false“ како би користили обрнут " -#~ "распоред тастера." +#~ msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" +#~ msgstr "Алфа вредност „%s“ у смешаној боји није између 0.0 и 1.0" #~ msgid "" -#~ "Setting this option to false can lead to buggy behavior, so users are " -#~ "strongly discouraged from changing it from the default of true. Many " -#~ "actions (e.g. clicking in the client area, moving or resizing the window) " -#~ "normally raise the window as a side-effect. Setting this option to false, " -#~ "which is strongly discouraged, will decouple raising from other user " -#~ "actions, and ignore raise requests generated by applications. See http://" -#~ "bugzilla.gnome.org/show_bug.cgi?id=445447#c6. Even when this option is " -#~ "false, windows can still be raised by an alt-left-click anywhere on the " -#~ "window, a normal click on the window decorations, or by special messages " -#~ "from pagers, such as activation requests from tasklist applets. This " -#~ "option is currently disabled in click-to-focus mode. Note that the list " -#~ "of ways to raise windows when raise_on_click is false does not include " -#~ "programmatic requests from applications to raise windows; such requests " -#~ "will be ignored regardless of the reason for the request. If you are an " -#~ "application developer and have a user complaining that your application " -#~ "does not work with this setting disabled, tell them it is _their_ fault " -#~ "for breaking their window manager and that they need to change this " -#~ "option back to true or live with the \"bug\" they requested." +#~ "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the " +#~ "format" #~ msgstr "" -#~ "Постављање ове опције на „false“ (нетачно) може проузроковати неисправно " -#~ "понашање програма, па није препоручљиво. Многе наредбе (нпр. клик усред " -#~ "области клијента, померање или промена величине прозора) обично уједно и " -#~ "подижу прозор. Искључивањем ове опције ће раздвојити подизање прозора од " -#~ "осталих радњи и занемарити захтеве за подизање прозора од стране " -#~ "програма. Погледајте http://bugzilla.gnome.org/show_bug.cgi?id=445447#c6. " -#~ "Чак и уколико искључите ову опцију, прозоре можете подићи левим кликом " -#~ "унутар прозора уз држање тастера Алт, обичним кликом на насловну линију " -#~ "прозора или преко посебних порука из пребацивача радних површина (као што " -#~ "је укључивање захтева из програмчета са списком задатака). Ова опција је " -#~ "тренутно искључена у режиму „click-to-focus“ (клик за фокус). Списак " -#~ "начина за подизање прозора када је „raise_on_click“ (подигни на клик) " -#~ "постављен на „false“ (нетачно) не укључује захтеве из програма за " -#~ "подизање прозора, па ће такви захтеви бити занемарени без обзира на на " -#~ "разлог. Уколико пишете сопствени програм и добијете примедбе од стране " -#~ "корисника како ваш програм не ради по искључивању ове опције, кажите им " -#~ "да је њихова кривица за неисправан рад управника прозорима и да врате " -#~ "опцију на „true“ (тачно) или да се навикну на пропратне појаве." +#~ "Формат сенке је „shade/base_color/factor“, „%s“ се не уклапа у формат" -#~ msgid "" -#~ "Some applications disregard specifications in ways that result in window " -#~ "manager misfeatures. This option puts Metacity in a rigorously correct " -#~ "mode, which gives a more consistent user interface, provided one does not " -#~ "need to run any misbehaving applications." -#~ msgstr "" -#~ "Неки програми не поштују спецификације на начин који води до тога да " -#~ "управник прозора не може да функционише. Ово подешавање поставља Метасити " -#~ "у строг режим рада који доприноси правилнијем понашању, под условом да се " -#~ "не покушава покретање неисправних програма." +#~ msgid "Could not parse shade factor \"%s\" in shaded color" +#~ msgstr "Не могу да обрадим фактор сенке „%s“ у осенченој боји" -#~ msgid "System Bell is Audible" -#~ msgstr "Системско звонце се чује" +#~ msgid "Shade factor \"%s\" in shaded color is negative" +#~ msgstr "Фактор сенке „%s“ у осенченој боји је негативан" -#~ msgid "" -#~ "Tells Metacity how to implement the visual indication that the system " -#~ "bell or another application 'bell' indicator has been rung. Currently " -#~ "there are two valid values, \"fullscreen\", which causes a fullscreen " -#~ "white-black flash, and \"frame_flash\" which causes the titlebar of the " -#~ "application which sent the bell signal to flash. If the application which " -#~ "sent the bell is unknown (as is usually the case for the default \"system " -#~ "beep\"), the currently focused window's titlebar is flashed." -#~ msgstr "" -#~ "Наређује Метаситију да прикаже нешто када зазвони системско звонце или " -#~ "неки други програм зазвони. Тренутно су могуће две вредности, " -#~ "„fullscreen“ којим цео екран трепери црно-бело, и „frame_flash“ када " -#~ "трепери само насловна линија прозора који је зазвонио. Уколико није " -#~ "познат програм који је зазвонио (као што је то обично случај са " -#~ "„системским звонцетом“), трепереће насловна линија прозора који је " -#~ "тренутно у жижи." +#~ msgid "Could not parse color \"%s\"" +#~ msgstr "Не могу да обрадим боју „%s“" -#~ msgid "" -#~ "The /apps/metacity/global_keybindings/run_command_N keys define " -#~ "keybindings that correspond to these commands. Pressing the keybinding " -#~ "for run_command_N will execute command_N." -#~ msgstr "" -#~ "Кључ /apps/metacity/global_keybindings/run_command_N дефинише тастере " -#~ "који одговарају овим командама. Притиском комбинације тастера за " -#~ "покрени_комаду_Н ће извршити команду_Н." +#~ msgid "Coordinate expression contains character '%s' which is not allowed" +#~ msgstr "Израз координата садржи знак „%s“ који није дозвољен" #~ msgid "" -#~ "The /apps/metacity/global_keybindings/run_command_screenshot key defines " -#~ "a keybinding which causes the command specified by this setting to be " -#~ "invoked." +#~ "Coordinate expression contains floating point number '%s' which could not " +#~ "be parsed" #~ msgstr "" -#~ "Кључ /apps/metacity/global_keybindings/run_command_N дефинише функцију " -#~ "тастера којим се покреће наредба наведена помоћу њега." +#~ "Израз координата садржи децимални број „%s“ који не може бити обрађен" #~ msgid "" -#~ "The /apps/metacity/global_keybindings/run_command_window_screenshot key " -#~ "defines a keybinding which causes the command specified by this setting " -#~ "to be invoked." -#~ msgstr "" -#~ "Кључ /apps/metacity/global_keybindings/run_command_window_screenshot " -#~ "дефинише функцију тастера којим се покреће наредба наведена помоћу њега." +#~ "Coordinate expression contains integer '%s' which could not be parsed" +#~ msgstr "Израз координата садржи цели број „%s“ који не може бити обрађен" -# bug: missing dot (.) after keybinding_commands? #~ msgid "" -#~ "The keybinding that runs the correspondingly-numbered command in /apps/" -#~ "metacity/keybinding_commands The format looks like \"<Control>a\" " -#~ "or \"<Shift><Alt>F1\". The parser is fairly liberal and " -#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" -#~ "\" and \"<Ctrl>\". If you set the option to the special string " -#~ "\"disabled\", then there will be no keybinding for this action." +#~ "Coordinate expression contained unknown operator at the start of this " +#~ "text: \"%s\"" #~ msgstr "" -#~ "Комбинације тастера који покрећу одговарајуће означену команду у /apps/" -#~ "metacity/keybinding_commands кључу. Облик записа је „<Control>a“ " -#~ "или „<Shift><Alt>F1“. Програм за обраду је доста слободан и " -#~ "дозвољава велика или мала слова, као и скраћенице попут „<Ctl>“ или " -#~ "„< Ctrl>“. Ако подесите опцију на нарочити низ знакова „disabled“, " -#~ "онда неће бити коришћена ниједна комбинација тастера за ову акцију." +#~ "Израз са координатама садржи непознати оператор на почетку овог текста: " +#~ "„%s“" -#~ msgid "The name of a workspace." -#~ msgstr "Име радне површине." +#~ msgid "Coordinate expression was empty or not understood" +#~ msgstr "Израз са координатама је био празан или неразумљив" -#~ msgid "The screenshot command" -#~ msgstr "Наредба за снимак екрана" +#~ msgid "Coordinate expression results in division by zero" +#~ msgstr "Израз са координатама резултира у дељењу нулом" #~ msgid "" -#~ "The theme determines the appearance of window borders, titlebar, and so " -#~ "forth." +#~ "Coordinate expression tries to use mod operator on a floating-point number" #~ msgstr "" -#~ "Тема утврђује изглед ивица прозора, насловне линије и свега осталог " -#~ "сличног." +#~ "Израз са координатам покушава да користи оператор остатка при дељењу за " +#~ "децимални број" #~ msgid "" -#~ "The time delay before raising a window if auto_raise is set to true. The " -#~ "delay is given in thousandths of a second." -#~ msgstr "" -#~ "Временски период пре подизања прозора ако је опција auto_raise постављена " -#~ "на „true“. Период се изражава у хиљадитим деловима секунде." +#~ "Coordinate expression has an operator \"%s\" where an operand was expected" +#~ msgstr "Израз са координатама има оператор „%s“ где је очекиван операнд" -#~ msgid "" -#~ "The window focus mode indicates how windows are activated. It has three " -#~ "possible values; \"click\" means windows must be clicked in order to " -#~ "focus them, \"sloppy\" means windows are focused when the mouse enters " -#~ "the window, and \"mouse\" means windows are focused when the mouse enters " -#~ "the window and unfocused when the mouse leaves the window." -#~ msgstr "" -#~ "Фокус прозора подешава како ће прозори бити активирани. Има три могуће " -#~ "вредности „click“ значи да прозор мора бити селектован да би добио фокус, " -#~ "„sloppy“ значи да прозор добија фокус када показивач миша уђе у прозор и " -#~ "„mouse“ штп значи да ће прозор бити фокуситан када показивачка стрелица " -#~ "миша уђе у прозор и бити дефокусиран када стрелица изађе из прозора." +#~ msgid "Coordinate expression had an operand where an operator was expected" +#~ msgstr "Израз са координатама имаше операнд где је очекиван оператор" -#~ msgid "The window screenshot command" -#~ msgstr "Наредба за узимање снимка прозора" +#~ msgid "Coordinate expression ended with an operator instead of an operand" +#~ msgstr "Израз са координарама је завршио са оператором уместо са операндом" #~ msgid "" -#~ "This option determines the effects of double-clicking on the title bar. " -#~ "Current valid options are 'toggle_shade', which will shade/unshade the " -#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " -#~ "will maximize/unmaximize the window in that direction only, 'minimize' " -#~ "which will minimize the window, 'shade' which will roll the window up, " -#~ "'menu' which will display the window menu, 'lower' which will put the " -#~ "window behind all the others, and 'none' which will not do anything." +#~ "Coordinate expression has operator \"%c\" following operator \"%c\" with " +#~ "no operand in between" #~ msgstr "" -#~ "Ова могућност одређује ефекат дуплог клика на насловну линију прозора. " -#~ "Тренутно исправни су „toggle_shade“ што ће замотати/одмотати прозор, " -#~ "„toggle_maximize“ што ће увећати или поништити увећање прозора, " -#~ "„toggle_maximize_horizontally“ и „toggle_maximize_vertically“, што ће " -#~ "увећати или поништити увећање прозора само у хоризонтално или усправно, " -#~ "„minimize“ што ће умањити прозор, „shade“ што ће замотат прозор, „menu“ " -#~ "што ће приказати мени прозора, „lower“ што ће поставити прозор иза " -#~ "осталих и „none“ чиме се не обавља никаква радња." +#~ "Израз са координатама има оператор „%c“, а затим оператор „%c“ без " +#~ "операнда између" -#~ msgid "" -#~ "This option determines the effects of middle-clicking on the title bar. " -#~ "Current valid options are 'toggle_shade', which will shade/unshade the " -#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " -#~ "will maximize/unmaximize the window in that direction only, 'minimize' " -#~ "which will minimize the window, 'shade' which will roll the window up, " -#~ "'menu' which will display the window menu, 'lower' which will put the " -#~ "window behind all the others, and 'none' which will not do anything." -#~ msgstr "" -#~ "Ова могућност одређује ефекат средњег клика на насловну линију прозора. " -#~ "Тренутно исправни су „toggle_shade“ што ће замотати/одмотати прозор, " -#~ "„toggle_maximize“ што ће увећати или поништити увећање прозора, " -#~ "„toggle_maximize_horizontally“ и „toggle_maximize_vertically“, што ће " -#~ "увећати или поништити увећање прозора само у хоризонтално или усправно, " -#~ "„minimize“ што ће умањити прозор, „shade“ што ће замотат прозор, „menu“ " -#~ "што ће приказати мени прозора, „lower“ што ће поставити прозор иза " -#~ "осталих и „none“ чиме се не обавља никаква радња." +#~ msgid "Coordinate expression had unknown variable or constant \"%s\"" +#~ msgstr "Израз са координатама има непознату променљиву или константи „%s“" -#~ msgid "" -#~ "This option determines the effects of right-clicking on the title bar. " -#~ "Current valid options are 'toggle_shade', which will shade/unshade the " -#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " -#~ "will maximize/unmaximize the window in that direction only, 'minimize' " -#~ "which will minimize the window, 'shade' which will roll the window up, " -#~ "'menu' which will display the window menu, 'lower' which will put the " -#~ "window behind all the others, and 'none' which will not do anything." -#~ msgstr "" -#~ "Ова могућност одређује ефекат десног клика на насловну линију прозора. " -#~ "Тренутно исправни су „toggle_shade“ што ће замотати/одмотати прозор, " -#~ "„toggle_maximize“ што ће увећати или поништити увећање прозора, " -#~ "„toggle_maximize_horizontally“ и „toggle_maximize_vertically“, што ће " -#~ "увећати или поништити увећање прозора само у хоризонтално или усправно, " -#~ "„minimize“ што ће умањити прозор, „shade“ што ће замотат прозор, „menu“ " -#~ "што ће приказати мени прозора, „lower“ што ће поставити прозор иза " -#~ "осталих и „none“ чиме се не обавља никаква радња." +#~ msgid "Coordinate expression parser overflowed its buffer." +#~ msgstr "Израз са координатама је био превелики за смештај и обраду." #~ msgid "" -#~ "This option provides additional control over how newly created windows " -#~ "get focus. It has two possible values; \"smart\" applies the user's " -#~ "normal focus mode, and \"strict\" results in windows started from a " -#~ "terminal not being given focus." -#~ msgstr "" -#~ "Ова опција пружа додатну контролу над начином на који нови прозори улазе " -#~ "у фокус. Има две могуће вредности: „smart“ поставља нормални режим фокуса " -#~ "и „strict“ када прозори покренути из командне линије не улазе у фокус." +#~ "Coordinate expression had a close parenthesis with no open parenthesis" +#~ msgstr "Израз са координатама има затворене заграде без отворених заграда" #~ msgid "" -#~ "Turns on a visual indication when an application or the system issues a " -#~ "'bell' or 'beep'; useful for the hard-of-hearing and for use in noisy " -#~ "environments." -#~ msgstr "" -#~ "Укључује визуелни приказ када програм или систем „зазвони“; корисно у " -#~ "бучним условима." +#~ "Coordinate expression had an open parenthesis with no close parenthesis" +#~ msgstr "Израз са координатама има отворену заграду без затворене заграде" -#~ msgid "Use standard system font in window titles" -#~ msgstr "Користи стандардни системски словни лик за наслов прозора" +#~ msgid "Coordinate expression doesn't seem to have any operators or operands" +#~ msgstr "Израз са координатама изгледа да нема ни један оператор или операнд" -#~ msgid "Visual Bell Type" -#~ msgstr "Врста визелног звонцета" +#~ msgid "Theme contained an expression that resulted in an error: %s\n" +#~ msgstr "Тема садржи израз који резултира грешком: %s\n" -#~ msgid "Whether raising should be a side-effect of other user interactions" +#~ msgid "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " +#~ "specified for this frame style" #~ msgstr "" -#~ "Да ли подизање прозора треба да буде бочни ефекат неких других " -#~ "корисникових радњи" - -#~ msgid "Whether to resize with the right button" -#~ msgstr "Да ли да промени величину десним тастером" - -#~ msgid "Window focus mode" -#~ msgstr "Начин фокуса прозора" - -#~ msgid "Window title font" -#~ msgstr "Словни лик наслова прозора" - -#~ msgid "Title" -#~ msgstr "Наслов" - -#~ msgid "Class" -#~ msgstr "Класа" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> мора бити " +#~ "наведен за овај стил оквира" #~ msgid "" -#~ "There was an error running \"%s\":\n" -#~ "%s." +#~ "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/" +#~ ">" #~ msgstr "" -#~ "Догодила се грешка приликом покретања „%s“:\n" -#~ "%s." - -#, fuzzy -#~ msgid "<name> specified twice for this theme" -#~ msgstr "Елемент <date> је наведен два пута у овој теми" +#~ "Недостаје <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever" +#~ "\"/>" -#~ msgid "<author> specified twice for this theme" -#~ msgstr "Елемент <author> је наведен два пута у овој теми" +#~ msgid "Failed to load theme \"%s\": %s\n" +#~ msgstr "Нисам успео да учитам тему „%s“: %s\n" -#~ msgid "<copyright> specified twice for this theme" -#~ msgstr "Елемент <copyright> је наведен два пута у овој теми" +#~ msgid "No <%s> set for theme \"%s\"" +#~ msgstr "Није дефинисан елемент <%s> за тему „%s“" -#~ msgid "<date> specified twice for this theme" -#~ msgstr "Елемент <date> је наведен два пута у овој теми" - -#~ msgid "<description> specified twice for this theme" -#~ msgstr "Елемент <description> је наведен два пута у овој теми" +#~ msgid "" +#~ "No frame style set for window type \"%s\" in theme \"%s\", add a <window " +#~ "type=\"%s\" style_set=\"whatever\"/> element" +#~ msgstr "" +#~ "Није подешен стил оквира за прозор типа „%s“ у теми „%s“. Додајте елемент " +#~ "<window type=\"%s\" style_set=\"whatever\"/>" -#~ msgid "Theme file %s did not contain a root <metacity_theme> element" -#~ msgstr "Датотека са темом %s не садржи коренски <metacity_theme> елемент" +#~ msgid "" +#~ "User-defined constants must begin with a capital letter; \"%s\" does not" +#~ msgstr "" +#~ "Кориснички дефинисане константе морају почети великим словом; „%s“ не " +#~ "почиње" -#~ msgid "/Windows/tearoff" -#~ msgstr "/Прозори/откини" +#~ msgid "Constant \"%s\" has already been defined" +#~ msgstr "Константа „%s“ је већ дефинисана" -#~ msgid "/Windows/_Dialog" -#~ msgstr "/Прозори/_Прозорче" +#~ msgid "No \"%s\" attribute on element <%s>" +#~ msgstr "Није дефинисан „%s“ атрибут у елементу <%s>" -#~ msgid "/Windows/_Modal dialog" -#~ msgstr "/Прозори/_Важно прозорче" +#~ msgid "Line %d character %d: %s" +#~ msgstr "Ред %d, знак %d: %s" -#~ msgid "/Windows/Des_ktop" -#~ msgstr "/Прозори/Рад_на површина" +#~ msgid "Attribute \"%s\" repeated twice on the same <%s> element" +#~ msgstr "Атрибут „%s“ је поновљен два пута у истом <%s> елементу" -#, fuzzy -#~ msgid "%s (as %s)" -#~ msgstr "%s (на %s)" +#~ msgid "Attribute \"%s\" is invalid on <%s> element in this context" +#~ msgstr "Атрибут „%s“ је неисправан у елементу <%s> у овом контексту" -#~ msgid "" -#~ "Error launching metacity-dialog to print an error about a command: %s\n" -#~ msgstr "" -#~ "Грешка приликом покретања metacity-dialog програма због штампања грешке о " -#~ "команди: %s\n" +#~ msgid "Could not parse \"%s\" as an integer" +#~ msgstr "Не могу да обрадим „%s“ као цео број" -#~ msgid "Unknown attribute %s on <metacity_session> element" -#~ msgstr "Непознат атрибут %s у <metacity_session> елементу" +#~ msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +#~ msgstr "Нисам разумео водеће знаке „%s“ у низу знакова „%s“" -#~ msgid "Unknown attribute %s on <maximized> element" -#~ msgstr "Непознат атрибут %s у <maximized> елементу" +#~ msgid "Integer %ld must be positive" +#~ msgstr "Цео број %ld мора бити позитиван" -#~ msgid "Unknown attribute %s on <geometry> element" -#~ msgstr "Непознат атрибут %s у <geometry> елементу" +#~ msgid "Integer %ld is too large, current max is %d" +#~ msgstr "Цео број %ld је превелик, тренутни највећи је %d" -#~ msgid "" -#~ "Many actions (e.g. clicking in the client area, moving or resizing the " -#~ "window) normally raise the window as a side-effect. Setting this option " -#~ "to false, which is strongly discouraged, will decouple raising from other " -#~ "user actions, and ignore raise requests generated by applications. See " -#~ "http://bugzilla.gnome.org/show_bug.cgi?id=445447#c6." -#~ msgstr "" -#~ "Многе радње (нпр. притисак на простор програма, премештање или мењање " -#~ "величине прозора) уобичајено, као споредни ефекат, подижу прозор. " -#~ "Постављање овог прекидача на истинитосну вредност „false“, што је крајње " -#~ "непрепоручљиво, ће раздвојити подизање прозора од осталих наредби " -#~ "корисника и занемарити захтеве за подизање од стране програма. Видите See " -#~ "http://bugzilla.gnome.org/show_bug.cgi?id=445447#c6 за више детаља." +#~ msgid "Could not parse \"%s\" as a floating point number" +#~ msgstr "Не могу да обрадим „%s“ као децимални број" -#~ msgid "" -#~ "The keybinding that switches to the workspace above the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Комбинација тастера која пребацује на радни простор изнад текућег. Облик " -#~ "записа је „<Control>a“ или „<Shift><Alt>F1“. Програм за " -#~ "обраду је доста слободан и дозвољава велика или мала слова, као и " -#~ "скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако подесите опцију " -#~ "на нарочити низ знакова „disabled“, онда неће бити коришћена ниједна " -#~ "комбинација тастера за ову акцију." +#~ msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" +#~ msgstr "Логичке вредности морају бити „true“ или „false“, а не „%s“" -#~ msgid "" -#~ "The keybinding that switches to the workspace below the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Комбинација тастера која пребацује на радни простор испод текућег. Облик " -#~ "записа је „<Control>a“ или „<Shift><Alt>F1“. Програм за " -#~ "обраду је доста слободан и дозвољава велика или мала слова, као и " -#~ "скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако подесите опцију " -#~ "на нарочити низ знакова „disabled“, онда неће бити коришћена ниједна " -#~ "комбинација тастера за ову акцију." +#~ msgid "Angle must be between 0.0 and 360.0, was %g\n" +#~ msgstr "Угао мора бити између 0.0 и 360.0, био је %g\n" #~ msgid "" -#~ "The keybinding that switches to the workspace on the left of the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." +#~ "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" #~ msgstr "" -#~ "Комбинација тастера која пребацује на радни простор лево од текућег. " -#~ "Облик записа је „<Control>a“ или „<Shift><Alt>F1“. " -#~ "Програм за обраду је доста слободан и дозвољава велика или мала слова, " -#~ "као и скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако подесите " -#~ "опцију на нарочити низ знакова „disabled“, онда неће бити коришћена " -#~ "ниједна комбинација тастера за ову акцију." +#~ "Алфа степен мора бити између 0.0 (невидљиво) и 1.0 (потпуно видљиво), био " +#~ "је %g\n" #~ msgid "" -#~ "The keybinding that switches to the workspace on the right of the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." +#~ "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," +#~ "large,x-large,xx-large)\n" #~ msgstr "" -#~ "Комбинација тастера која пребацује на радни простор десно од текућег. " -#~ "Облик записа је „<Control>a“ или „<Shift><Alt>F1“. " -#~ "Програм за обраду је доста слободан и дозвољава велика или мала слова, " -#~ "као и скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако подесите " -#~ "опцију на нарочити низ знакова „disabled“, онда неће бити коришћена " -#~ "ниједна комбинација тастера за ову акцију." +#~ "Нетачно скалирање наслова „%s“ (мора бити један од следећих: xx-small,x-" +#~ "small,small,medium,large,x-large,xx-large)\n" -#~ msgid "" -#~ "The keybinding that switches to workspace 1. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбинација тастера која пребацује на радни простор број 1. Облик записа " -#~ "је „<Control>a“ или „<Shift><Alt>F1“. Програм за обраду " -#~ "је доста слободан и дозвољава велика или мала слова, као и скраћенице " -#~ "попут „<Ctl>“ или „< Ctrl>“. Ако подесите опцију на нарочити " -#~ "низ знакова „disabled“, онда неће бити коришћена ниједна комбинација " -#~ "тастера за ову акцију." +#~ msgid "<%s> name \"%s\" used a second time" +#~ msgstr "<%s> назив „%s“ је коришћен по други пут" -#~ msgid "" -#~ "The keybinding that switches to workspace 10. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбинација тастера која пребацује на радни простор број 10. Облик записа " -#~ "је „<Control>a“ или „<Shift><Alt>F1“. Програм за обраду " -#~ "је доста слободан и дозвољава велика или мала слова, као и скраћенице " -#~ "попут „<Ctl>“ или „< Ctrl>“. Ако подесите опцију на нарочити " -#~ "низ знакова „disabled“, онда неће бити коришћена ниједна комбинација " -#~ "тастера за ову акцију." +#~ msgid "<%s> parent \"%s\" has not been defined" +#~ msgstr "<%s> матични „%s“ није одређен" -#~ msgid "" -#~ "The keybinding that switches to workspace 11. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбинација тастера која пребацује на радни простор број 11. Облик записа " -#~ "је „<Control>a“ или „<Shift><Alt>F1“. Програм за обраду " -#~ "је доста слободан и дозвољава велика или мала слова, као и скраћенице " -#~ "попут „<Ctl>“ или „< Ctrl>“. Ако подесите опцију на нарочити " -#~ "низ знакова „disabled“, онда неће бити коришћена ниједна комбинација " -#~ "тастера за ову акцију." +#~ msgid "<%s> geometry \"%s\" has not been defined" +#~ msgstr "<%s> геометрија „%s“ није дефинисана" -#~ msgid "" -#~ "The keybinding that switches to workspace 12. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ msgid "<%s> must specify either a geometry or a parent that has a geometry" #~ msgstr "" -#~ "Комбинација тастера која пребацује на радни простор број 12. Облик записа " -#~ "је „<Control>a“ или „<Shift><Alt>F1“. Програм за обраду " -#~ "је доста слободан и дозвољава велика или мала слова, као и скраћенице " -#~ "попут „<Ctl>“ или „< Ctrl>“. Ако подесите опцију на нарочити " -#~ "низ знакова „disabled“, онда неће бити коришћена ниједна комбинација " -#~ "тастера за ову акцију." +#~ "<%s> мора бити наведена или геометрија или матични елемент који има " +#~ "геометрију" -#~ msgid "" -#~ "The keybinding that switches to workspace 2. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбинација тастера која пребацује на радни простор број 2. Облик записа " -#~ "је „<Control>a“ или „<Shift><Alt>F1“. Програм за обраду " -#~ "је доста слободан и дозвољава велика или мала слова, као и скраћенице " -#~ "попут „<Ctl>“ или „< Ctrl>“. Ако подесите опцију на нарочити " -#~ "низ знакова „disabled“, онда неће бити коришћена ниједна комбинација " -#~ "тастера за ову акцију." +#~ msgid "You must specify a background for an alpha value to be meaningful" +#~ msgstr "Морате навести позадину да би алфа вредност имала смисла" -#~ msgid "" -#~ "The keybinding that switches to workspace 3. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбинација тастера која пребацује на радни простор број 3. Облик записа " -#~ "је „<Control>a“ или „<Shift><Alt>F1“. Програм за обраду " -#~ "је доста слободан и дозвољава велика или мала слова, као и скраћенице " -#~ "попут „<Ctl>“ или „< Ctrl>“. Ако подесите опцију на нарочити " -#~ "низ знакова „disabled“, онда неће бити коришћена ниједна комбинација " -#~ "тастера за ову акцију." +#~ msgid "Unknown type \"%s\" on <%s> element" +#~ msgstr "Непознат тип „%s“ у елементу <%s>" -#~ msgid "" -#~ "The keybinding that switches to workspace 4. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбинација тастера која пребацује на радни простор број 4. Облик записа " -#~ "је „<Control>a“ или „<Shift><Alt>F1“. Програм за обраду " -#~ "је доста слободан и дозвољава велика или мала слова, као и скраћенице " -#~ "попут „<Ctl>“ или „< Ctrl>“. Ако подесите опцију на нарочити " -#~ "низ знакова „disabled“, онда неће бити коришћена ниједна комбинација " -#~ "тастера за ову акцију." +#~ msgid "Unknown style_set \"%s\" on <%s> element" +#~ msgstr "Непознат „style_set“ „%s“ у елементу <%s>" -#~ msgid "" -#~ "The keybinding that switches to workspace 5. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбинација тастера која пребацује на радни простор број 5. Облик записа " -#~ "је „<Control>a“ или „<Shift><Alt>F1“. Програм за обраду " -#~ "је доста слободан и дозвољава велика или мала слова, као и скраћенице " -#~ "попут „<Ctl>“ или „< Ctrl>“. Ако подесите опцију на нарочити " -#~ "низ знакова „disabled“, онда неће бити коришћена ниједна комбинација " -#~ "тастера за ову акцију." +#~ msgid "Window type \"%s\" has already been assigned a style set" +#~ msgstr "Типу прозора „%s“ је већ додељен скуп стила" -#~ msgid "" -#~ "The keybinding that switches to workspace 6. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбинација тастера која пребацује на радни простор број 6. Облик записа " -#~ "је „<Control>a“ или „<Shift><Alt>F1“. Програм за обраду " -#~ "је доста слободан и дозвољава велика или мала слова, као и скраћенице " -#~ "попут „<Ctl>“ или „< Ctrl>“. Ако подесите опцију на нарочити " -#~ "низ знакова „disabled“, онда неће бити коришћена ниједна комбинација " -#~ "тастера за ову акцију." +#~ msgid "Element <%s> is not allowed below <%s>" +#~ msgstr "Елемент <%s> није дозвољен испод <%s>" #~ msgid "" -#~ "The keybinding that switches to workspace 7. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбинација тастера која пребацује на радни простор број 7. Облик записа " -#~ "је „<Control>a“ или „<Shift><Alt>F1“. Програм за обраду " -#~ "је доста слободан и дозвољава велика или мала слова, као и скраћенице " -#~ "попут „<Ctl>“ или „< Ctrl>“. Ако подесите опцију на нарочити " -#~ "низ знакова „disabled“, онда неће бити коришћена ниједна комбинација " -#~ "тастера за ову акцију." +#~ "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio" +#~ "\" for buttons" +#~ msgstr "Не могу да подесим и ширину/висину и размеру дугмади" -#~ msgid "" -#~ "The keybinding that switches to workspace 8. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбинација тастера која пребацује на радни простор број 8. Облик записа " -#~ "је „<Control>a“ или „<Shift><Alt>F1“. Програм за обраду " -#~ "је доста слободан и дозвољава велика или мала слова, као и скраћенице " -#~ "попут „<Ctl>“ или „< Ctrl>“. Ако подесите опцију на нарочити " -#~ "низ знакова „disabled“, онда неће бити коришћена ниједна комбинација " -#~ "тастера за ову акцију." +#~ msgid "Distance \"%s\" is unknown" +#~ msgstr "Удаљеност „%s“ је непозната" -#~ msgid "" -#~ "The keybinding that switches to workspace 9. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбинација тастера која пребацује на радни простор број 9. Облик записа " -#~ "је „<Control>a“ или „<Shift><Alt>F1“. Програм за обраду " -#~ "је доста слободан и дозвољава велика или мала слова, као и скраћенице " -#~ "попут „<Ctl>“ или „< Ctrl>“. Ако подесите опцију на нарочити " -#~ "низ знакова „disabled“, онда неће бити коришћена ниједна комбинација " -#~ "тастера за ову акцију." +#~ msgid "Aspect ratio \"%s\" is unknown" +#~ msgstr "Однос размере „%s је непознат" -#~ msgid "" -#~ "The keybinding used to activate the window menu. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбинација тастера за приказивање менија прозора. Облик записа је „<" -#~ "Control>a“ или „<Shift><Alt>F1“. Програм за обраду је " -#~ "доста слободан и дозвољава велика или мала слова, као и скраћенице попут " -#~ "„<Ctl>“ или „< Ctrl>“. Ако подесите опцију на нарочити низ " -#~ "знакова „disabled“, онда неће бити коришћена ниједна комбинација тастера " -#~ "за ову акцију." +#~ msgid "Border \"%s\" is unknown" +#~ msgstr "Ивица „%s“ је непозната" -#~ msgid "" -#~ "The keybinding used to enter \"move mode\" and begin moving a window " -#~ "using the keyboard. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." +#~ msgid "No \"start_angle\" or \"from\" attribute on element <%s>" #~ msgstr "" -#~ "Комбинација тастера за улазак у „режим премештања“ или за почетак " -#~ "премештања прозора помоћу тастатуре. Облик записа је „<Control>a“ " -#~ "или „<Shift><Alt>F1“. Програм за обраду је доста слободан и " -#~ "дозвољава велика или мала слова, као и скраћенице попут „<Ctl>“ или " -#~ "„< Ctrl>“. Ако подесите опцију на нарочити низ знакова „disabled“, " -#~ "онда неће бити коришћена ниједна комбинација тастера за ову акцију." +#~ "Није одређен „start_angle“ (почетни_угао) или „from“ (од) атрибут у " +#~ "елементу <%s>" -#~ msgid "" -#~ "The keybinding used to enter \"resize mode\" and begin resizing a window " -#~ "using the keyboard. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "Комбинација тастера за улазак у „режим промене величине“ или за почетак " -#~ "промене величине прозора помоћу тастатуре. Облик записа је „<" -#~ "Control>a“ или „<Shift><Alt>F1“. Програм за обраду је " -#~ "доста слободан и дозвољава велика или мала слова, као и скраћенице попут " -#~ "„<Ctl>“ или „< Ctrl>“. Ако подесите опцију на нарочити низ " -#~ "знакова „disabled“, онда неће бити коришћена ниједна комбинација тастера " -#~ "за ову акцију." +#~ msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" +#~ msgstr "Није дефинисан „extent_angle“ или „to“ атрибут у елементу <%s>" -#~ msgid "" -#~ "The keybinding used to hide all normal windows and set the focus to the " -#~ "desktop background. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "Комбинација тастера за сакривање свих обичних прозора и фокусирање " -#~ "позадине радне површи. Облик записа је „<Control>a“ или „<" -#~ "Shift><Alt>F1“. Програм за обраду је доста слободан и дозвољава " -#~ "велика или мала слова, као и скраћенице попут „<Ctl>“ или „< " -#~ "Ctrl>“. Ако подесите опцију на нарочити низ знакова „disabled“, онда " -#~ "неће бити коришћена ниједна комбинација тастера за ову акцију." +#~ msgid "Did not understand value \"%s\" for type of gradient" +#~ msgstr "Нисам разумео вредност „%s“ као тип градијента" -#~ msgid "" -#~ "The keybinding used to maximize a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбинација тастера за увећавање прозора. Облик записа је „<Control>" -#~ "a“ или „<Shift><Alt>F1“. Програм за обраду је доста слободан " -#~ "и дозвољава велика или мала слова, као и скраћенице попут „<Ctl>“ " -#~ "или „< Ctrl>“. Ако подесите опцију на нарочити низ знакова " -#~ "„disabled“, онда неће бити коришћена ниједна комбинација тастера за ову " -#~ "акцију." +#~ msgid "Did not understand fill type \"%s\" for <%s> element" +#~ msgstr "Нисам разумео тип попуњавања површине „%s“ у елементу <%s>" -#~ msgid "" -#~ "The keybinding used to minimize a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбинација тастера за умањивање прозора. Облик записа је „<Control>" -#~ "a“ или „<Shift><Alt>F1“. Програм за обраду је доста слободан " -#~ "и дозвољава велика или мала слова, као и скраћенице попут „<Ctl>“ " -#~ "или „< Ctrl>“. Ако подесите опцију на нарочити низ знакова " -#~ "„disabled“, онда неће бити коришћена ниједна комбинација тастера за ову " -#~ "акцију." +#~ msgid "Did not understand state \"%s\" for <%s> element" +#~ msgstr "Нисам разумео стање „%s“ у елементу <%s>" -#~ msgid "" -#~ "The keybinding used to move a window one workspace down. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбинација тастера за пребацивање прозора на радни простор испод. Облик " -#~ "записа је „<Control>a“ или „<Shift><Alt>F1“. Програм за " -#~ "обраду је доста слободан и дозвољава велика или мала слова, као и " -#~ "скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако подесите опцију " -#~ "на нарочити низ знакова „disabled“, онда неће бити коришћена ниједна " -#~ "комбинација тастера за ову акцију." +#~ msgid "Did not understand shadow \"%s\" for <%s> element" +#~ msgstr "Нисам разумео сенку „%s“ у елементу <%s>" -#~ msgid "" -#~ "The keybinding used to move a window one workspace to the left. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Комбинација тастера за пребацивање прозора на радни простор лево. Облик " -#~ "записа је „<Control>a“ или „<Shift><Alt>F1“. Програм за " -#~ "обраду је доста слободан и дозвољава велика или мала слова, као и " -#~ "скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако подесите опцију " -#~ "на нарочити низ знакова „disabled“, онда неће бити коришћена ниједна " -#~ "комбинација тастера за ову акцију." +#~ msgid "Did not understand arrow \"%s\" for <%s> element" +#~ msgstr "Нисам разумео стрелицу „%s“ у елементу <%s>" -#~ msgid "" -#~ "The keybinding used to move a window one workspace to the right. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Комбинација тастера за пребацивање прозора на радни простор десно. Облик " -#~ "записа је „<Control>a“ или „<Shift><Alt>F1“. Програм за " -#~ "обраду је доста слободан и дозвољава велика или мала слова, као и " -#~ "скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако подесите опцију " -#~ "на нарочити низ знакова „disabled“, онда неће бити коришћена ниједна " -#~ "комбинација тастера за ову акцију." +#~ msgid "No <draw_ops> called \"%s\" has been defined" +#~ msgstr "Није дефинисан <draw_ops> означен као „%s“" -#~ msgid "" -#~ "The keybinding used to move a window one workspace up. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ msgid "Including draw_ops \"%s\" here would create a circular reference" #~ msgstr "" -#~ "Комбинација тастера за пребацивање прозора на радни простор горе. Облик " -#~ "записа је „<Control>a“ или „<Shift><Alt>F1“. Програм за " -#~ "обраду је доста слободан и дозвољава велика или мала слова, као и " -#~ "скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако подесите опцију " -#~ "на нарочити низ знакова „disabled“, онда неће бити коришћена ниједна " -#~ "комбинација тастера за ову акцију." +#~ "Укључивање елемента „draw_ops“ „%s“ овде би направило кружну референцу" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 1. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбинација тастера за пребацивање прозора на радни простор број 1. Облик " -#~ "записа је „<Control>a“ или „<Shift><Alt>F1“. Програм за " -#~ "обраду је доста слободан и дозвољава велика или мала слова, као и " -#~ "скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако подесите опцију " -#~ "на нарочити низ знакова „disabled“, онда неће бити коришћена ниједна " -#~ "комбинација тастера за ову акцију." +#~ msgid "Unknown position \"%s\" for frame piece" +#~ msgstr "Непознат положај „%s“ за део оквира" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 10. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбинација тастера за пребацивање прозора на радни простор број 10. " -#~ "Облик записа је „<Control>a“ или „<Shift><Alt>F1“. " -#~ "Програм за обраду је доста слободан и дозвољава велика или мала слова, " -#~ "као и скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако подесите " -#~ "опцију на нарочити низ знакова „disabled“, онда неће бити коришћена " -#~ "ниједна комбинација тастера за ову акцију." +#~ msgid "Frame style already has a piece at position %s" +#~ msgstr "Стил оквира већ има део на положају %s" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 11. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбинација тастера за пребацивање прозора на радни простор број 11. " -#~ "Облик записа је „<Control>a“ или „<Shift><Alt>F1“. " -#~ "Програм за обраду је доста слободан и дозвољава велика или мала слова, " -#~ "као и скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако подесите " -#~ "опцију на нарочити низ знакова „disabled“, онда неће бити коришћена " -#~ "ниједна комбинација тастера за ову акцију." +#~ msgid "No <draw_ops> with the name \"%s\" has been defined" +#~ msgstr "Није дефинисан <draw_ops> са именом „%s“" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 12. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбинација тастера за пребацивање прозора на радни простор број 12. " -#~ "Облик записа је „<Control>a“ или „<Shift><Alt>F1“. " -#~ "Програм за обраду је доста слободан и дозвољава велика или мала слова, " -#~ "као и скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако подесите " -#~ "опцију на нарочити низ знакова „disabled“, онда неће бити коришћена " -#~ "ниједна комбинација тастера за ову акцију." +#~ msgid "Unknown function \"%s\" for button" +#~ msgstr "Непозната функција „%s“ за дугме" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 2. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ msgid "Button function \"%s\" does not exist in this version (%d, need %d)" #~ msgstr "" -#~ "Комбинација тастера за пребацивање прозора на радни простор број 2. Облик " -#~ "записа је „<Control>a“ или „<Shift><Alt>F1“. Програм за " -#~ "обраду је доста слободан и дозвољава велика или мала слова, као и " -#~ "скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако подесите опцију " -#~ "на нарочити низ знакова „disabled“, онда неће бити коришћена ниједна " -#~ "комбинација тастера за ову акцију." +#~ "Функција „%s“ за дугме не постоји у овој верзији (верзија %d, а треба вам " +#~ "%d)" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 3. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбинација тастера за пребацивање прозора на радни простор број 3. Облик " -#~ "записа је „<Control>a“ или „<Shift><Alt>F1“. Програм за " -#~ "обраду је доста слободан и дозвољава велика или мала слова, као и " -#~ "скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако подесите опцију " -#~ "на нарочити низ знакова „disabled“, онда неће бити коришћена ниједна " -#~ "комбинација тастера за ову акцију." +#~ msgid "Unknown state \"%s\" for button" +#~ msgstr "Непознато стање „%s“ за дугме" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 4. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбинација тастера за пребацивање прозора на радни простор број 4. Облик " -#~ "записа је „<Control>a“ или „<Shift><Alt>F1“. Програм за " -#~ "обраду је доста слободан и дозвољава велика или мала слова, као и " -#~ "скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако подесите опцију " -#~ "на нарочити низ знакова „disabled“, онда неће бити коришћена ниједна " -#~ "комбинација тастера за ову акцију." +#~ msgid "Frame style already has a button for function %s state %s" +#~ msgstr "Стил оквира већ има дугме са функцијом %s и стањем %s" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 5. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбинација тастера за пребацивање прозора на радни простор број 5. Облик " -#~ "записа је „<Control>a“ или „<Shift><Alt>F1“. Програм за " -#~ "обраду је доста слободан и дозвољава велика или мала слова, као и " -#~ "скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако подесите опцију " -#~ "на нарочити низ знакова „disabled“, онда неће бити коришћена ниједна " -#~ "комбинација тастера за ову акцију." +#~ msgid "\"%s\" is not a valid value for focus attribute" +#~ msgstr "„%s“ није дозвољена вредност за атрибут фокуса" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 6. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбинација тастера за пребацивање прозора на радни простор број 6. Облик " -#~ "записа је „<Control>a“ или „<Shift><Alt>F1“. Програм за " -#~ "обраду је доста слободан и дозвољава велика или мала слова, као и " -#~ "скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако подесите опцију " -#~ "на нарочити низ знакова „disabled“, онда неће бити коришћена ниједна " -#~ "комбинација тастера за ову акцију." +#~ msgid "\"%s\" is not a valid value for state attribute" +#~ msgstr "„%s“ није дозвољена вредност за атрибут стања" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 7. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбинација тастера за пребацивање прозора на радни простор број 7. Облик " -#~ "записа је „<Control>a“ или „<Shift><Alt>F1“. Програм за " -#~ "обраду је доста слободан и дозвољава велика или мала слова, као и " -#~ "скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако подесите опцију " -#~ "на нарочити низ знакова „disabled“, онда неће бити коришћена ниједна " -#~ "комбинација тастера за ову акцију." +#~ msgid "A style called \"%s\" has not been defined" +#~ msgstr "Стил „%s“ није дефинисан" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 8. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбинација тастера за пребацивање прозора на радни простор број 8. Облик " -#~ "записа је „<Control>a“ или „<Shift><Alt>F1“. Програм за " -#~ "обраду је доста слободан и дозвољава велика или мала слова, као и " -#~ "скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако подесите опцију " -#~ "на нарочити низ знакова „disabled“, онда неће бити коришћена ниједна " -#~ "комбинација тастера за ову акцију." +#~ msgid "\"%s\" is not a valid value for resize attribute" +#~ msgstr "„%s“ није дозвољена вредност за атрибут промене величине" #~ msgid "" -#~ "The keybinding used to move a window to workspace 9. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "Should not have \"resize\" attribute on <%s> element for maximized/shaded " +#~ "states" #~ msgstr "" -#~ "Комбинација тастера за пребацивање прозора на радни простор број 9. Облик " -#~ "записа је „<Control>a“ или „<Shift><Alt>F1“. Програм за " -#~ "обраду је доста слободан и дозвољава велика или мала слова, као и " -#~ "скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако подесите опцију " -#~ "на нарочити низ знакова „disabled“, онда неће бити коришћена ниједна " -#~ "комбинација тастера за ову акцију." +#~ "Никако не треба имати „resize“ атрибут у елементу <%s> за увећана/" +#~ "засенчена стања" #~ msgid "" -#~ "The keybinding used to move focus backwards between panels and the " -#~ "desktop, using a popup window. The format looks like \"<Control>a\" " -#~ "or \"<Shift><Alt>F1\". The parser is fairly liberal and " -#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" -#~ "\" and \"<Ctrl>\". If you set the option to the special string " -#~ "\"disabled\", then there will be no keybinding for this action." +#~ "Should not have \"resize\" attribute on <%s> element for maximized states" #~ msgstr "" -#~ "Комбинација тастера за пребацивање фокуса уназад између панела и радне " -#~ "површи, помоћу искачућег прозора. Облик записа је „<Control>a“ или " -#~ "„<Shift><Alt>F1“. Програм за обраду је доста слободан и " -#~ "дозвољава велика или мала слова, као и скраћенице попут „<Ctl>“ или " -#~ "„< Ctrl>“. Ако подесите опцију на нарочити низ знакова „disabled“, " -#~ "онда неће бити коришћена ниједна комбинација тастера за ову акцију." +#~ "Никако не треба имати „resize“ атрибут у елементу <%s> за увећана стања" -#~ msgid "" -#~ "The keybinding used to move focus backwards between panels and the " -#~ "desktop, without a popup window. The format looks like \"<Control>a" -#~ "\" or \"<Shift><Alt>F1\". The parser is fairly liberal and " -#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" -#~ "\" and \"<Ctrl>\". If you set the option to the special string " -#~ "\"disabled\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "Комбинација тастера за пребацивање фокуса уназад између панела и радне " -#~ "површи, без искачућег прозора. Облик записа је „<Control>a“ или " -#~ "„<Shift><Alt>F1“. Програм за обраду је доста слободан и " -#~ "дозвољава велика или мала слова, као и скраћенице попут „<Ctl>“ или " -#~ "„< Ctrl>“. Ако подесите опцију на нарочити низ знакова „disabled“, " -#~ "онда неће бити коришћена ниједна комбинација тастера за ову акцију." +#~ msgid "Style has already been specified for state %s resize %s focus %s" +#~ msgstr "Стил је већ наведен за стање „%s“ увећање „%s“ фокус „%s“" -#~ msgid "" -#~ "The keybinding used to move focus backwards between windows of an " -#~ "application without a popup window. Holding \"shift\" together with this " -#~ "binding makes the direction go forward again. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбинација тастера за пребацивање фокуса уназад између прозора програма, " -#~ "без искачућег прозора. Држање „shift“ уз ову пречицу ће ићи опет унапред. " -#~ "Облик записа је „<Control>a“ или „<Shift><Alt>F1“. " -#~ "Програм за обраду је доста слободан и дозвољава велика или мала слова, " -#~ "као и скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако подесите " -#~ "опцију на нарочити низ знакова „disabled“, онда неће бити коришћена " -#~ "ниједна комбинација тастера за ову акцију." +#~ msgid "Style has already been specified for state %s focus %s" +#~ msgstr "Стил је већ наведен за стање „%s“ фокус „“%s" #~ msgid "" -#~ "The keybinding used to move focus backwards between windows of an " -#~ "application, using a popup window. Holding \"shift\" together with this " -#~ "binding makes the direction go forward again. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "Can't have a two draw_ops for a <piece> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" #~ msgstr "" -#~ "Комбинација тастера за пребацивање фокуса уназад између прозора програма, " -#~ "помоћу искачућег прозора. Држање „shift“ уз ову пречицу ће ићи опет " -#~ "унапред. Облик записа је „<Control>a“ или „<Shift><Alt>" -#~ "F1“. Програм за обраду је доста слободан и дозвољава велика или мала " -#~ "слова, као и скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако " -#~ "подесите опцију на нарочити низ знакова „disabled“, онда неће бити " -#~ "коришћена ниједна комбинација тастера за ову акцију." +#~ "Не могу постојати два „draw_ops“ за елемент <piece> (тема наводи " +#~ "„draw_ops“ атрибут и <draw_ops> елемент, или наводи два елемента)" #~ msgid "" -#~ "The keybinding used to move focus backwards between windows without a " -#~ "popup window. Holding \"shift\" together with this binding makes the " -#~ "direction go forward again. The format looks like \"<Control>a\" or " -#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " -#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" -#~ "\", then there will be no keybinding for this action." +#~ "Can't have a two draw_ops for a <button> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" #~ msgstr "" -#~ "Комбинација тастера за пребацивање фокуса уназад између прозора, без " -#~ "искачућег прозора. Држање „shift“ уз ову пречицу ће ићи опет унапред. " -#~ "Облик записа је „<Control>a“ или „<Shift><Alt>F1“. " -#~ "Програм за обраду је доста слободан и дозвољава велика или мала слова, " -#~ "као и скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако подесите " -#~ "опцију на нарочити низ знакова „disabled“, онда неће бити коришћена " -#~ "ниједна комбинација тастера за ову акцију." +#~ "Не могу постојати два „draw_ops“ за елемент <button> (тема наводи " +#~ "„draw_ops“ атрибут и <draw_ops> елемент, или наводи два елемента)" #~ msgid "" -#~ "The keybinding used to move focus backwards between windows, using a " -#~ "popup window. Holding \"shift\" together with this binding makes the " -#~ "direction go forward again. The format looks like \"<Control>a\" or " -#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " -#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" -#~ "\", then there will be no keybinding for this action." +#~ "Can't have a two draw_ops for a <menu_icon> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" #~ msgstr "" -#~ "Комбинација тастера за пребацивање фокуса уназад између прозора, помоћу " -#~ "искачућег прозора. Држање „shift“ уз ову пречицу ће ићи опет унапред. " -#~ "Облик записа је „<Control>a“ или „<Shift><Alt>F1“. " -#~ "Програм за обраду је доста слободан и дозвољава велика или мала слова, " -#~ "као и скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако подесите " -#~ "опцију на нарочити низ знакова „disabled“, онда неће бити коришћена " -#~ "ниједна комбинација тастера за ову акцију." +#~ "Не могу постојати два „draw_ops“ за елемент <menu_icon> (тема наводи " +#~ "„draw_ops“ атрибут и <draw_ops> елемент, или наводи два елемента)" -#~ msgid "" -#~ "The keybinding used to move focus between panels and the desktop, using a " -#~ "popup window. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "Комбинација тастера за пребацивање фокуса између панела и радне површи, " -#~ "помоћу искачућег прозора. Облик записа је „<Control>a“ или „<" -#~ "Shift><Alt>F1“. Програм за обраду је доста слободан и дозвољава " -#~ "велика или мала слова, као и скраћенице попут „<Ctl>“ или „< " -#~ "Ctrl>“. Ако подесите опцију на нарочити низ знакова „disabled“, онда " -#~ "неће бити коришћена ниједна комбинација тастера за ову акцију." +#~ msgid "Bad version specification '%s'" +#~ msgstr "Издање је лоше одређено „%s“" #~ msgid "" -#~ "The keybinding used to move focus between panels and the desktop, without " -#~ "a popup window. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." +#~ "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" +#~ "theme-2.xml" #~ msgstr "" -#~ "Комбинација тастера за пребацивање фокуса између панела и радне површи, " -#~ "без искачућег прозора. Облик записа је „<Control>a“ или „<" -#~ "Shift><Alt>F1“. Програм за обраду је доста слободан и дозвољава " -#~ "велика или мала слова, као и скраћенице попут „<Ctl>“ или „< " -#~ "Ctrl>“. Ако подесите опцију на нарочити низ знакова „disabled“, онда " -#~ "неће бити коришћена ниједна комбинација тастера за ову акцију." +#~ "Не могу да користим „version“ (издање) у metacity-theme-1.xml или " +#~ "metacity-theme-2.xml" #~ msgid "" -#~ "The keybinding used to move focus between windows of an application " -#~ "without a popup window. Holding the \"shift\" key while using this " -#~ "binding reverses the direction of movement. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "Theme requires version %s but latest supported theme version is %d.%d" #~ msgstr "" -#~ "Комбинација тастера за пребацивање фокуса између прозора програма, без " -#~ "искачућег прозора. (Традиционално <Alt&gr;Escape) Држање тастера " -#~ "„shift“ при употреби ове комбинације обрће смер кретања. Облик записа је " -#~ "„<Control>a“ или „<Shift><Alt>F1“. Програм за обраду је " -#~ "доста слободан и дозвољава велика или мала слова, као и скраћенице попут " -#~ "„<Ctl>“ или „< Ctrl>“. Ако подесите опцију на нарочити низ " -#~ "знакова „disabled“, онда неће бити коришћена ниједна комбинација тастера " -#~ "за ову акцију." +#~ "За ову тему је неопходно издање %s, а последња подржана тема је %d.%d" -#~ msgid "" -#~ "The keybinding used to move focus between windows of an application, " -#~ "using a popup window. (Traditionally <Alt>F6) Holding the \"shift\" " -#~ "key while using this binding reverses the direction of movement. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Комбинација тастера за пребацивање фокуса између прозора програма, помоћу " -#~ "искачућег прозора. (Традиционално <Alt&gr;Tab) Држање тастера „shift“ " -#~ "при употреби ове комбинације обрће смер кретања. Облик записа је „<" -#~ "Control>a“ или „<Shift><Alt>F1“. Програм за обраду је " -#~ "доста слободан и дозвољава велика или мала слова, као и скраћенице попут " -#~ "„<Ctl>“ или „< Ctrl>“. Ако подесите опцију на нарочити низ " -#~ "знакова „disabled“, онда неће бити коришћена ниједна комбинација тастера " -#~ "за ову акцију." +#~ msgid "Outermost element in theme must be <metacity_theme> not <%s>" +#~ msgstr "Најстарији елемент теме мора бити <metacity_theme>, а не <%s>" #~ msgid "" -#~ "The keybinding used to move focus between windows without a popup window. " -#~ "(Traditionally <Alt>Escape) Holding the \"shift\" key while using " -#~ "this binding reverses the direction of movement. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "Element <%s> is not allowed inside a name/author/date/description element" #~ msgstr "" -#~ "Комбинација тастера за пребацивање фокуса између прозора, без искачућег " -#~ "прозора. (Традиционално <Alt&gr;Escape) Држање тастера „shift“ при " -#~ "употреби ове комбинације обрће смер кретања. Облик записа је „<" -#~ "Control>a“ или „<Shift><Alt>F1“. Програм за обраду је " -#~ "доста слободан и дозвољава велика или мала слова, као и скраћенице попут " -#~ "„<Ctl>“ или „< Ctrl>“. Ако подесите опцију на нарочити низ " -#~ "знакова „disabled“, онда неће бити коришћена ниједна комбинација тастера " -#~ "за ову акцију." +#~ "Елемент <%s> није дозвољен унутар елемената „name, author, date и " +#~ "description“" -#~ msgid "" -#~ "The keybinding used to move focus between windows, using a popup window. " -#~ "(Traditionally <Alt>Tab) Holding the \"shift\" key while using this " -#~ "binding reverses the direction of movement. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбинација тастера за пребацивање фокуса између прозора, помоћу " -#~ "искачућег прозора. (Традиционално <Alt&gr;Tab) Држање тастера „shift“ " -#~ "при употреби ове комбинације обрће смер кретања. Облик записа је „<" -#~ "Control>a“ или „<Shift><Alt>F1“. Програм за обраду је " -#~ "доста слободан и дозвољава велика или мала слова, као и скраћенице попут " -#~ "„<Ctl>“ или „< Ctrl>“. Ако подесите опцију на нарочити низ " -#~ "знакова „disabled“, онда неће бити коришћена ниједна комбинација тастера " -#~ "за ову акцију." +#~ msgid "Element <%s> is not allowed inside a <constant> element" +#~ msgstr "Елемент <%s> није дозвољен унутар елемента <constant>" #~ msgid "" -#~ "The keybinding used to toggle always on top. A window that is always on " -#~ "top will always be visible over other overlapping windows. The format " -#~ "looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -#~ "parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." +#~ "Element <%s> is not allowed inside a distance/border/aspect_ratio element" #~ msgstr "" -#~ "Комбинација тастера за укључивање/искључивање да прозор буде увек на " -#~ "врху. Прозор који је увек на врху ће се видети и преко осталих " -#~ "преклапајућих прозора. Облик записа је „<Control>a“ или „<" -#~ "Shift><Alt>F1“. Програм за обраду је доста слободан и дозвољава " -#~ "велика или мала слова, као и скраћенице попут „<Ctl>“ или „< " -#~ "Ctrl>“. Ако подесите опцију на нарочити низ знакова „disabled“, онда " -#~ "неће бити коришћена ниједна комбинација тастера за ову акцију." +#~ "Елемент <%s> није дозвољен унутар елемената „distance, border и " +#~ "aspect_ratio“" -#~ msgid "" -#~ "The keybinding used to toggle fullscreen mode. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбинација тастера за укључивање/искључивање режима целог екрана. Облик " -#~ "записа је „<Control>a“ или „<Shift><Alt>F1“. Програм за " -#~ "обраду је доста слободан и дозвољава велика или мала слова, као и " -#~ "скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако подесите опцију " -#~ "на нарочити низ знакова „disabled“, онда неће бити коришћена ниједна " -#~ "комбинација тастера за ову акцију." +#~ msgid "Element <%s> is not allowed inside a draw operation element" +#~ msgstr "Елемент <%s> није дозвољен унутар елемената операција цртања" -#~ msgid "" -#~ "The keybinding used to toggle maximization. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбинација тастера за укључивање/искључивање увећање. Облик записа је " -#~ "„<Control>a“ или „<Shift><Alt>F1“. Програм за обраду је " -#~ "доста слободан и дозвољава велика или мала слова, као и скраћенице попут " -#~ "„<Ctl>“ или „< Ctrl>“. Ако подесите опцију на нарочити низ " -#~ "знакова „disabled“, онда неће бити коришћена ниједна комбинација тастера " -#~ "за ову акцију." +#~ msgid "Element <%s> is not allowed inside a <%s> element" +#~ msgstr "Елемент <%s> није дозвољен унутар <%s> елемента" -#~ msgid "" -#~ "The keybinding used to toggle shaded/unshaded state. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбинација тастера за замотавање/одмотавање. Облик записа је „<" -#~ "Control>a“ или „<Shift><Alt>F1“. Програм за обраду је " -#~ "доста слободан и дозвољава велика или мала слова, као и скраћенице попут " -#~ "„<Ctl>“ или „< Ctrl>“. Ако подесите опцију на нарочити низ " -#~ "знакова „disabled“, онда неће бити коришћена ниједна комбинација тастера " -#~ "за ову акцију." +#~ msgid "No draw_ops provided for frame piece" +#~ msgstr "Није наведен „draw_ops“ за део оквира" -#~ msgid "" -#~ "The keybinding used to toggle whether the window is on all workspaces or " -#~ "just one. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Комбинација тастера за измену да ли је прозор у свим радним просторима " -#~ "или само у једном. Облик записа је „<Control>a“ или „<Shift>" -#~ "<Alt>F1“. Програм за обраду је доста слободан и дозвољава велика " -#~ "или мала слова, као и скраћенице попут „<Ctl>“ или „< Ctrl>“. " -#~ "Ако подесите опцију на нарочити низ знакова „disabled“, онда неће бити " -#~ "коришћена ниједна комбинација тастера за ову акцију." +#~ msgid "No draw_ops provided for button" +#~ msgstr "Није наведен „draw_ops“ за дугме" -#~ msgid "" -#~ "The keybinding used to unmaximize a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбинација тастера за поништавање увећања прозора. Облик записа је „<" -#~ "Control>a“ или „<Shift><Alt>F1“. Програм за обраду је " -#~ "доста слободан и дозвољава велика или мала слова, као и скраћенице попут " -#~ "„<Ctl>“ или „< Ctrl>“. Ако подесите опцију на нарочити низ " -#~ "знакова „disabled“, онда неће бити коришћена ниједна комбинација тастера " -#~ "за ову акцију." - -# bug: s/display's/displays/ (it's not genitive, but a verb as in "it displays") -#~ msgid "" -#~ "The keybinding which display's the panel's \"Run Application\" dialog " -#~ "box. The format looks like \"<Control>a\" or \"<Shift><" -#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If " -#~ "you set the option to the special string \"disabled\", then there will be " -#~ "no keybinding for this action." -#~ msgstr "" -#~ "Комбинација тастера која приказује прозорче панела „Покрени програм“. " -#~ "Облик записа је „<Control>a“ или „<Shift><Alt>F1“. " -#~ "Програм за обраду је доста слободан и дозвољава велика или мала слова, " -#~ "као и скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако подесите " -#~ "опцију на нарочити низ знакова „disabled“, онда неће бити коришћена " -#~ "ниједна комбинација тастера за ову акцију." +#~ msgid "No text is allowed inside element <%s>" +#~ msgstr "Није дозвољен текст унутар елемента <%s>" -#~ msgid "" -#~ "The keybinding which invokes a terminal. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбинација тастера која покреће терминал. Облик записа је „<" -#~ "Control>a“ или „<Shift><Alt>F1“. Програм за обраду је " -#~ "доста слободан и дозвољава велика или мала слова, као и скраћенице попут " -#~ "„<Ctl>“ или „< Ctrl>“. Ако подесите опцију на нарочити низ " -#~ "знакова „disabled“, онда неће бити коришћена ниједна комбинација тастера " -#~ "за ову акцију." +#~ msgid "<%s> specified twice for this theme" +#~ msgstr "<%s> је наведен два пута у овој теми" -#~ msgid "" -#~ "The keybinding which invokes the panel's screenshot utility to take a " -#~ "screenshot of a window. The format looks like \"<Control>a\" or " -#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " -#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" -#~ "\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "Комбинација тастера која приказује алатку панела за снимке екрана за " -#~ "снимак прозора. Облик записа је „<Control>a“ или „<Shift><" -#~ "Alt>F1“. Програм за обраду је доста слободан и дозвољава велика или " -#~ "мала слова, као и скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако " -#~ "подесите опцију на нарочити низ знакова „disabled“, онда неће бити " -#~ "коришћена ниједна комбинација тастера за ову акцију." +#~ msgid "Failed to find a valid file for theme %s\n" +#~ msgstr "Нисам успео да пронађем исправну датотеку за тему „%s“\n" -#~ msgid "" -#~ "The keybinding which invokes the panel's screenshot utility. The format " -#~ "looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -#~ "parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Комбинација тастера која приказује алатку панела за снимке екрана. Облик " -#~ "записа је „<Control>a“ или „<Shift><Alt>F1“. Програм за " -#~ "обраду је доста слободан и дозвољава велика или мала слова, као и " -#~ "скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако подесите опцију " -#~ "на нарочити низ знакова „disabled“, онда неће бити коришћена ниједна " -#~ "комбинација тастера за ову акцију." +#~ msgid "background texture could not be created from file" +#~ msgstr "склоп позадине не може бити створен из датотеке" -#~ msgid "" -#~ "The keybinding which shows the panel's main menu. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбинација тастера која приказује главни мени панела. Облик записа је " -#~ "„<Control>a“ или „<Shift><Alt>F1“. Програм за обраду је " -#~ "доста слободан и дозвољава велика или мала слова, као и скраћенице попут " -#~ "„<Ctl>“ или „< Ctrl>“. Ако подесите опцију на нарочити низ " -#~ "знакова „disabled“, онда неће бити коришћена ниједна комбинација тастера " -#~ "за ову акцију." +#~ msgid "Unknown window information request: %d" +#~ msgstr "Захтевана је непозната информација о прозору: %d" -#~ msgid "" -#~ "This keybinding changes whether a window is above or below other windows. " -#~ "If the window is covered by another one, it raises the window above all " -#~ "others, and if the window is already fully visible, it lowers it below " -#~ "all others. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Комбинација тастера која мења да ли је прозор изнад или испод осталих " -#~ "прозора. Ако је прозор покривен неким прозором, онда се издиже изнад " -#~ "осталих, а ако је већ у потпуности приказан, онда се сакрива иза свих " -#~ "осталих прозора. Облик записа је „<Control>a“ или „<Shift><" -#~ "Alt>F1“. Програм за обраду је доста слободан и дозвољава велика или " -#~ "мала слова, као и скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако " -#~ "подесите опцију на нарочити низ знакова „disabled“, онда неће бити " -#~ "коришћена ниједна комбинација тастера за ову акцију." +#~ msgid "Missing %s extension required for compositing" +#~ msgstr "Недостаје потребан композитни додатак %s" #~ msgid "" -#~ "This keybinding lowers a window below other windows. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "Some other program is already using the key %s with modifiers %x as a " +#~ "binding\n" #~ msgstr "" -#~ "Комбинација тастера која сакрива прозор иза свих осталих прозора. Облик " -#~ "записа је „<Control>a“ или „<Shift><Alt>F1“. Програм за " -#~ "обраду је доста слободан и дозвољава велика или мала слова, као и " -#~ "скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако подесите опцију " -#~ "на нарочити низ знакова „disabled“, онда неће бити коришћена ниједна " -#~ "комбинација тастера за ову акцију." +#~ "Неки други програм већ користи тастер %s са измењивачима %x за неку " +#~ "функцију\n" -#~ msgid "" -#~ "This keybinding moves a window against the north (top) side of the " -#~ "screen. The format looks like \"<Control>a\" or \"<Shift><" -#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If " -#~ "you set the option to the special string \"disabled\", then there will be " -#~ "no keybinding for this action." -#~ msgstr "" -#~ "Комбинација тастера која помера прозор на север екрана (горња ивица). " -#~ "Облик записа је „<Control>a“ или „<Shift><Alt>F1“. " -#~ "Програм за обраду је доста слободан и дозвољава велика или мала слова, " -#~ "као и скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако подесите " -#~ "опцију на нарочити низ знакова „disabled“, онда неће бити коришћена " -#~ "ниједна комбинација тастера за ову акцију." +#~ msgid "\"%s\" is not a valid accelerator\n" +#~ msgstr "„%s“ није исправна пречица\n" #~ msgid "" -#~ "This keybinding moves a window into the center of the screen. The format " -#~ "looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -#~ "parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." +#~ "Workarounds for broken applications disabled. Some applications may not " +#~ "behave properly.\n" #~ msgstr "" -#~ "Комбинација тастера која помера прозор на средину екрана. Облик записа је " -#~ "„<Control>a“ или „<Shift><Alt>F1“. Програм за обраду је " -#~ "доста слободан и дозвољава велика или мала слова, као и скраћенице попут " -#~ "„<Ctl>“ или „< Ctrl>“. Ако подесите опцију на нарочити низ " -#~ "знакова „disabled“, онда неће бити коришћена ниједна комбинација тастера " -#~ "за ову акцију." +#~ "Решења за оштећене програме су искључена. Неке апликације се могу " +#~ "понашати чудно.\n" -#~ msgid "" -#~ "This keybinding moves a window into the east (right) side of the screen. " -#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -#~ "\". The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." +#~ msgid "Could not parse font description \"%s\" from GSettings key %s\n" #~ msgstr "" -#~ "Комбинација тастера која помера прозор на исток екрана (десна ивица). " -#~ "Облик записа је „<Control>a“ или „<Shift><Alt>F1“. " -#~ "Програм за обраду је доста слободан и дозвољава велика или мала слова, " -#~ "као и скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако подесите " -#~ "опцију на нарочити низ знакова „disabled“, онда неће бити коришћена " -#~ "ниједна комбинација тастера за ову акцију." +#~ "Не могу да обрадим опис „%s“ из кључа „%s“ у Гномовим подешавањима\n" #~ msgid "" -#~ "This keybinding moves a window into the north-east (top right) corner of " -#~ "the screen. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" #~ msgstr "" -#~ "Комбинација тастера која помера прозор на североисток екрана (горе " -#~ "десно). Облик записа је „<Control>a“ или „<Shift><Alt>" -#~ "F1“. Програм за обраду је доста слободан и дозвољава велика или мала " -#~ "слова, као и скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако " -#~ "подесите опцију на нарочити низ знакова „disabled“, онда неће бити " -#~ "коришћена ниједна комбинација тастера за ову акцију." +#~ "„%s“ је пронађен у бази подешавања што није исправна вредност која мења " +#~ "понашање тастера миша\n" #~ msgid "" -#~ "This keybinding moves a window into the north-west (top left) corner of " -#~ "the screen. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." +#~ "\"%s\" found in configuration database is not a valid value for " +#~ "keybinding \"%s\"\n" #~ msgstr "" -#~ "Комбинација тастера која помера прозор на северозапад екрана (горе лево). " -#~ "Облик записа је „<Control>a“ или „<Shift><Alt>F1“. " -#~ "Програм за обраду је доста слободан и дозвољава велика или мала слова, " -#~ "као и скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако подесите " -#~ "опцију на нарочити низ знакова „disabled“, онда неће бити коришћена " -#~ "ниједна комбинација тастера за ову акцију." +#~ "„%s“ из базе са подешавањима није исправна комбинација тастера „%s“\n" #~ msgid "" -#~ "This keybinding moves a window into the south (bottom) side of the " -#~ "screen. The format looks like \"<Control>a\" or \"<Shift><" -#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If " -#~ "you set the option to the special string \"disabled\", then there will be " -#~ "no keybinding for this action." +#~ "Could not acquire window manager selection on screen %d display \"%s\"\n" #~ msgstr "" -#~ "Комбинација тастера која помера прозор на југ екрана (доња ивица). Облик " -#~ "записа је „<Control>a“ или „<Shift><Alt>F1“. Програм за " -#~ "обраду је доста слободан и дозвољава велика или мала слова, као и " -#~ "скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако подесите опцију " -#~ "на нарочити низ знакова „disabled“, онда неће бити коришћена ниједна " -#~ "комбинација тастера за ову акцију." +#~ "Не могу да добијем избор управника прозора на приказу %d еркана „%s“\n" -#~ msgid "" -#~ "This keybinding moves a window into the south-east (bottom right) corner " -#~ "of the screen. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "Комбинација тастера која помера прозор на југоисток екрана (доле десно). " -#~ "Облик записа је „<Control>a“ или „<Shift><Alt>F1“. " -#~ "Програм за обраду је доста слободан и дозвољава велика или мала слова, " -#~ "као и скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако подесите " -#~ "опцију на нарочити низ знакова „disabled“, онда неће бити коришћена " -#~ "ниједна комбинација тастера за ову акцију." +#~ msgid "Could not release screen %d on display \"%s\"\n" +#~ msgstr "Не могу да отпустим приказ %d на екрану „%s“\n" -#~ msgid "" -#~ "This keybinding moves a window into the south-west (bottom left) corner " -#~ "of the screen. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "Комбинација тастера која помера прозор на југозапад екрана (доле лево). " -#~ "Облик записа је „<Control>a“ или „<Shift><Alt>F1“. " -#~ "Програм за обраду је доста слободан и дозвољава велика или мала слова, " -#~ "као и скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако подесите " -#~ "опцију на нарочити низ знакова „disabled“, онда неће бити коришћена " -#~ "ниједна комбинација тастера за ову акцију." +#~ msgid "Could not create directory '%s': %s\n" +#~ msgstr "Не могу да направим директоријум „%s“: %s\n" -#~ msgid "" -#~ "This keybinding moves a window into the west (left) side of the screen. " -#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -#~ "\". The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Комбинација тастера која помера прозор на запад екрана (лева ивица). " -#~ "Облик записа је „<Control>a“ или „<Shift><Alt>F1“. " -#~ "Програм за обраду је доста слободан и дозвољава велика или мала слова, " -#~ "као и скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако подесите " -#~ "опцију на нарочити низ знакова „disabled“, онда неће бити коришћена " -#~ "ниједна комбинација тастера за ову акцију." +#~ msgid "Could not open session file '%s' for writing: %s\n" +#~ msgstr "Не могу да отворим датотеку сесије „%s“ за упис: %s\n" -#~ msgid "" -#~ "This keybinding raises the window above other windows. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбинација тастера која издиже прозор испред свих осталих прозора. Облик " -#~ "записа је „<Control>a“ или „<Shift><Alt>F1“. Програм за " -#~ "обраду је доста слободан и дозвољава велика или мала слова, као и " -#~ "скраћенице попут „<Ctl>“ или „< Ctrl>“. Ако подесите опцију " -#~ "на нарочити низ знакова „disabled“, онда неће бити коришћена ниједна " -#~ "комбинација тастера за ову акцију." +#~ msgid "Error writing session file '%s': %s\n" +#~ msgstr "Грешка записивања датотеке сесије „%s“: %s\n" -#~ msgid "" -#~ "This keybinding resizes a window to fill available horizontal space. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Комбинација тастера за измену величине прозора тако да попуни сав " -#~ "водоравни простор. Облик записа је „<Control>a“ или „<Shift>" -#~ "<Alt>F1“. Програм за обраду је доста слободан и дозвољава велика " -#~ "или мала слова, као и скраћенице попут „<Ctl>“ или „< Ctrl>“. " -#~ "Ако подесите опцију на нарочити низ знакова „disabled“, онда неће бити " -#~ "коришћена ниједна комбинација тастера за ову акцију." +#~ msgid "Error closing session file '%s': %s\n" +#~ msgstr "Грешка приликом затварања датотеке сесије „%s“: %s\n" -#~ msgid "" -#~ "This keybinding resizes a window to fill available vertical space. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Комбинација тастера за измену величине прозора тако да попуни сав " -#~ "усправни простор. Облик записа је „<Control>a“ или „<Shift>" -#~ "<Alt>F1“. Програм за обраду је доста слободан и дозвољава велика " -#~ "или мала слова, као и скраћенице попут „<Ctl>“ или „< Ctrl>“. " -#~ "Ако подесите опцију на нарочити низ знакова „disabled“, онда неће бити " -#~ "коришћена ниједна комбинација тастера за ову акцију." +#~ msgid "Failed to parse saved session file: %s\n" +#~ msgstr "Нисам успео да обрадим сачувану датотеку сесије: %s\n" -#~ msgid "Toggle always on top state" -#~ msgstr "Измени да ли је увек на врху" +#~ msgid "<mutter_session> attribute seen but we already have the session ID" +#~ msgstr "Атрибут <mutter_session> је примећен али ми већ имамо ИБ сесије" -#~ msgid "Unmaximize window" -#~ msgstr "Поништи увећање прозора" +#~ msgid "Unknown attribute %s on <%s> element" +#~ msgstr "Непознат атрибут „%s“ у <%s> елементу" -#~ msgid "Unmaximize Window" -#~ msgstr "Поништи увећавање прозора" +#~ msgid "nested <window> tag" +#~ msgstr "угњежден <window> елемент" -#~ msgid "No \"%s\" attribute on <%s> element" -#~ msgstr "Не постоји атрибут „%s“ у елементу <%s>" +#~ msgid "Unknown element %s" +#~ msgstr "Непознат елемент „%s“" -#~ msgid "Theme already has a fallback icon" -#~ msgstr "Тема већ има резервy за icon" +#~ msgid "Failed to open debug log: %s\n" +#~ msgstr "Нисам успео да отворим дневник грешака: %s\n" -#~ msgid "Theme already has a fallback mini_icon" -#~ msgstr "Тема већ има резерву за mini_icon" +#~ msgid "Failed to fdopen() log file %s: %s\n" +#~ msgstr "Нисам успео да „fdopen()“ датотеку дневника „%s“: %s\n" -#~ msgid "No \"name\" attribute on element <%s>" -#~ msgstr "Није дефинисан „name“ атрибут у елементу <%s>" +#~ msgid "Opened log file %s\n" +#~ msgstr "Отворена је датотека дневника „%s“\n" -#~ msgid "No \"value\" attribute on element <%s>" -#~ msgstr "Није дефинисан „value“ атрибут у елементу <%s>" +#~ msgid "Window manager: " +#~ msgstr "Управник прозора: " -#~ msgid "No \"top\" attribute on element <%s>" -#~ msgstr "Није дефинисан „top“ атрибут у елементу <%s>" +#~ msgid "Bug in window manager: " +#~ msgstr "Грешка у управнику прозора: " -#~ msgid "No \"bottom\" attribute on element <%s>" -#~ msgstr "Није дефинисан „bottom“ атрибут у елементу <%s>" +#~ msgid "Window manager warning: " +#~ msgstr "Упозорење управника прозора: " -#~ msgid "No \"left\" attribute on element <%s>" -#~ msgstr "Није дефинисан „left“ атрибут у елементу <%s>" +#~ msgid "Window manager error: " +#~ msgstr "Грешка управника прозора: " -#~ msgid "No \"right\" attribute on element <%s>" -#~ msgstr "Није дефинисан „right“ атрибут у елементу <%s>" +#~ msgid "" +#~ "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " +#~ "window as specified in the ICCCM.\n" +#~ msgstr "" +#~ "Прозор „%s“ је поставио „SM_CLIENT_ID“ на себи самом уместо на прозору " +#~ "„WM_CLIENT_LEADER“ као што је наведено у ИЦЦЦМ.\n" -#~ msgid "No \"color\" attribute on element <%s>" -#~ msgstr "Није дефинисан „color“ атрибут у елементу <%s>" +#~ msgid "" +#~ "Window %s sets an MWM hint indicating it isn't resizable, but sets min " +#~ "size %d x %d and max size %d x %d; this doesn't make much sense.\n" +#~ msgstr "" +#~ "Прозор „%s“ је поставио „MWM“ што наговештава да није променљиве " +#~ "величине, али је поставио најмању величину %d x %d и највећу величину %d " +#~ "x %d што нема много смисла.\n" -#~ msgid "No \"x1\" attribute on element <%s>" -#~ msgstr "Није дефинисан „x1“ атрибут у елементу <%s>" +#~ msgid "Application set a bogus _NET_WM_PID %lu\n" +#~ msgstr "Програм је поставио нетачан _NET_WM_PID %lu\n" -#~ msgid "No \"y1\" attribute on element <%s>" -#~ msgstr "Није дефинисан „y1“ атрибут у елементу <%s>" +#~ msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +#~ msgstr "Неисправан прозор 0x%lx наведен као WM_TRANSIENT_FOR за %s.\n" -#~ msgid "No \"x2\" attribute on element <%s>" -#~ msgstr "Није дефинисан „x2“ атрибут у елементу <%s>" +#~ msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" +#~ msgstr "WM_TRANSIENT_FOR прозор 0x%lx за %s ће направити петљу.\n" -#~ msgid "No \"y2\" attribute on element <%s>" -#~ msgstr "Није дефинисан „y2“ атрибут у елементу <%s>" +#~ msgid "" +#~ "Window 0x%lx has property %s\n" +#~ "that was expected to have type %s format %d\n" +#~ "and actually has type %s format %d n_items %d.\n" +#~ "This is most likely an application bug, not a window manager bug.\n" +#~ "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +#~ msgstr "" +#~ "Прозор 0x%lx има особину %s\n" +#~ "тако да је очекивано да има врсту %s формат %d,\n" +#~ "а заправо има врсту %s формат %d n_ставки %d.\n" +#~ "Ово је највероватније грешка у програму, а не у управнику прозора.\n" +#~ "Прозор има наслов=„%s“ класу=„%s“ назив=„%s“\n" -#~ msgid "No \"y\" attribute on element <%s>" -#~ msgstr "Није дефинисан „y“ атрибут у елементу <%s>" +#~ msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +#~ msgstr "Особина „%s“ прозора 0x%lx садржи неисправан УТФ-8\n" -#~ msgid "No \"width\" attribute on element <%s>" -#~ msgstr "Није дефинисан „width“ атрибут у елементу <%s>" +#~ msgid "" +#~ "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the " +#~ "list\n" +#~ msgstr "" +#~ "Особина „%s“ прозора 0x%lx садржи неисправан УТФ-8 за ставку „%d“ на " +#~ "списку\n" -#~ msgid "No \"height\" attribute on element <%s>" -#~ msgstr "Није дефинисан „height“ атрибут у елементу <%s>" +#~ msgid "Mi_nimize" +#~ msgstr "У_мањи" -#~ msgid "No \"start_angle\" attribute on element <%s>" -#~ msgstr "Није дефинисан „start_angle“ атрибут у елементу <%s>" +#~ msgid "Ma_ximize" +#~ msgstr "У_већај" -#~ msgid "No \"extent_angle\" attribute on element <%s>" -#~ msgstr "Није дефинисан „extent_angle“ атрибут у елементу <%s>" +#~ msgid "Unma_ximize" +#~ msgstr "Поништи у_већање" -#~ msgid "No \"alpha\" attribute on element <%s>" -#~ msgstr "Није дефинисан „alpha“ атрибут у елементу <%s>" +#~ msgid "Roll _Up" +#~ msgstr "_Замотај" -#~ msgid "No \"type\" attribute on element <%s>" -#~ msgstr "Није дефинисан „type“ атрибут у елементу <%s>" +#~ msgid "_Unroll" +#~ msgstr "_Одмотај" -#~ msgid "No \"filename\" attribute on element <%s>" -#~ msgstr "Није дефинисан „filename“ атрибут у елементу <%s>" +#~ msgid "_Move" +#~ msgstr "_Премести" -#~ msgid "No \"state\" attribute on element <%s>" -#~ msgstr "Није дефинисан „state“ атрибут у елементу <%s>" +#~ msgid "_Resize" +#~ msgstr "П_ромени величину" -#~ msgid "No \"shadow\" attribute on element <%s>" -#~ msgstr "Није дефинисан „shadow“ атрибут у елементу <%s>" +#~ msgid "Move Titlebar On_screen" +#~ msgstr "Премести траку _наслова на екран" -#~ msgid "No \"arrow\" attribute on element <%s>" -#~ msgstr "Није дефинисан „arrow“ атрибут у елементу <%s>" +#~ msgid "Always on _Top" +#~ msgstr "Увек _изнад осталих" -#~ msgid "No \"value\" attribute on <%s> element" -#~ msgstr "Није дефинисан „value“ атрибут у елементу <%s>" +#~ msgid "_Always on Visible Workspace" +#~ msgstr "_Увек на видљивом радном простору" -#~ msgid "No \"position\" attribute on <%s> element" -#~ msgstr "Није дефинисан „position“ атрибут у елементу <%s>" +#~ msgid "_Only on This Workspace" +#~ msgstr "Само на _овом радном простору" -#~ msgid "No \"function\" attribute on <%s> element" -#~ msgstr "Није дефинисан „function“ атрибут у елементу <%s>" +#~ msgid "Move to Workspace _Left" +#~ msgstr "Премести на радни простор ле_во" -#~ msgid "No \"state\" attribute on <%s> element" -#~ msgstr "Није дефинисан „state“ атрибут у елементу <%s>" +#~ msgid "Move to Workspace R_ight" +#~ msgstr "Премести на радни простор де_сно" -#~ msgid "No \"focus\" attribute on <%s> element" -#~ msgstr "Није дефинисан „focus“ атрибут у елементу <%s>" +#~ msgid "Move to Workspace _Up" +#~ msgstr "Премести на радни простор го_ре" -#~ msgid "No \"style\" attribute on <%s> element" -#~ msgstr "Није дефинисан „style“ атрибут у елементу <%s>" +#~ msgid "Move to Workspace _Down" +#~ msgstr "Премести на радни простор до_ле" -#~ msgid "No \"resize\" attribute on <%s> element" -#~ msgstr "Није дефинисан „resize“ атрибут у елементу <%s>" +#~ msgid "_Close" +#~ msgstr "_Затвори" -#~ msgid "Type of %s was not integer" -#~ msgstr "Тип податка „%s“ није целобројна вредност" +#~ msgid "Workspace %d%n" +#~ msgstr "Радни простор %d%n" -#~ msgid "" -#~ "%d stored in GConf key %s is not a reasonable cursor_size; must be in the " -#~ "range 1..128\n" -#~ msgstr "" -#~ "Број %d сачуван у кључу %s у Гномовим подешавањима не представља разумну " -#~ "величину курсора која мора бити у опсегу од 1 до 128\n" +#~ msgid "Workspace 1_0" +#~ msgstr "1_0. радни простор" -#~ msgid "" -#~ "%d stored in GConf key %s is not a reasonable number of workspaces, " -#~ "current maximum is %d\n" -#~ msgstr "" -#~ "%d сачувано у кључу %s у гном подешавањима није разуман број радних " -#~ "површина, тренутни максимум је %d\n" +#~ msgid "Workspace %s%d" +#~ msgstr "%s%d. радни простор" -#~ msgid "On _Top" -#~ msgstr "Изна_д свега" +#~ msgid "Move to Another _Workspace" +#~ msgstr "Премести на други _радни простор" -#~ msgid "" -#~ "Forcing this application to quit will cause you to lose any unsaved " -#~ "changes." -#~ msgstr "Приморавањем програма на излаз ћете изгубити све несачуване измене." +#~ msgid "Shift" +#~ msgstr "Шифт" -#~ msgid "Unknown function \"%s\" for menu icon" -#~ msgstr "Непозната функција „%s“ за икону менија" +#~ msgid "Ctrl" +#~ msgstr "Ктрл" -#~ msgid "Unknown state \"%s\" for menu icon" -#~ msgstr "Непознато стањр „%s“ за икону менија" +#~ msgid "Alt" +#~ msgstr "Алт" -#~ msgid "Theme already has a menu icon for function %s state %s" -#~ msgstr "Тема већ поседује икону менија за функцију %s стање %s" +#~ msgid "Meta" +#~ msgstr "Мета" -#~ msgid "No draw_ops provided for menu icon" -#~ msgstr "Није наведен draw_ops икону менија" +#~ msgid "Super" +#~ msgstr "Супер" -#~ msgid "Failed to read theme from file %s: %s\n" -#~ msgstr "Нисам успео да прочитам тему из датотеке %s: %s\n" +#~ msgid "Hyper" +#~ msgstr "Хипер" -#~ msgid "" -#~ "<menu_icon function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -#~ "specified for this theme" -#~ msgstr "" -#~ "<menu_icon function=\"%s\" state=\"%s\" draw_ops=\"било шта\"/> мора бити " -#~ "дефинисан за ову тему" +#~ msgid "Mod2" +#~ msgstr "Мод2" -#~ msgid "" -#~ "If true, and the focus mode is either \"sloppy\" or \"mouse\" then the " -#~ "focused window will be automatically raised after a delay (the delay is " -#~ "specified by the auto_raise_delay key). This preference is poorly named, " -#~ "but kept for backwards compatibility. To try to be more clear (at least " -#~ "to the technically inclined), its meaning is \"automatically raise the " -#~ "window following a timeout which is triggered by non-grabbed mouse entry " -#~ "in sloppy or mouse focus modes\". It is unrelated to clicking behavior (i." -#~ "e. this is not related to raise-on-click/orthogonal-raise). It is " -#~ "unrelated to entering a window during drag and drop (because that results " -#~ "in the application grabbing the mouse)" -#~ msgstr "" -#~ "Ако је истинито и режим фокуса је или „sloppy“ или „mouse“ тада ће " -#~ "фокусирани прозор бити сам подигнут након неке задршке која је одређена у " -#~ "кључу „auto_raise_delay“. Ова поставка је неодговарајуће именована али " -#~ "задржана због сагласности са старим издањима. Да би били јаснији (барем " -#~ "оним технички образованим), њено значење је — сам подигни прозор након " -#~ "задршке што се окида у режимима „sloppy“ и „mouse“. То нема везе са " -#~ "понашањем при притискању (није сродно са подизањем по притиску). Није " -#~ "сросно такође са уласком у прозор при радњи „Превуци и отпусти“ јер " -#~ "резултат тога је да сам програм преузима миш." +#~ msgid "Mod3" +#~ msgstr "Мод3" -#~ msgid "" -#~ "Some applications break specifications in ways that result in window " -#~ "manager misfeatures. For example, ideally Metacity would place all " -#~ "dialogs in a consistent position with respect to their parent window. " -#~ "This requires ignoring application-specified positions for dialogs. But " -#~ "some versions of Java/Swing mark their popup menus as dialogs, so " -#~ "Metacity has to disable dialog positioning to allow menus to work in " -#~ "broken Java applications. There are several other examples like this. " -#~ "This option puts Metacity in full-on Correct mode, which perhaps gives a " -#~ "moderately nicer UI if you don't need to run any broken apps. Sadly, " -#~ "workarounds must be enabled by default; the real world is an ugly place. " -#~ "Some of the workarounds are workarounds for limitations in the " -#~ "specifications themselves, so sometimes a bug in no-workarounds mode " -#~ "won't be fixable without amending a spec." -#~ msgstr "" -#~ "Неки програми крше спецификације што резултира неисправним могућностима " -#~ "менаџера прозора. На пример, у идеалном случају метасити би поставио " -#~ "дијалоге на конзистентне позиције у зависности од старијег прозора. То " -#~ "захтева игнорисање програмски специфираних позиција дијалога. Али неке " -#~ "верзије Јаве/Свинга обележавају њихове контекстне меније као дијалоге, " -#~ "тако да метасити мора да искључи позиционирање дијалога и омогући " -#~ "менијима да раде у лошим Јава програмима. Постоји неколико сличних " -#~ "примера. Ова опција поставља метасити у потпуно тачан начин рада, што " -#~ "можда даје опште лепши кориснички интерфејс ако не морате да покрећете " -#~ "некомпатибилне програме. Међутим компромиси морају бити предефинисано " -#~ "дозвољени; старни свет је јако ружно место. Неки од компромиса су " -#~ "компромиси за ограничења која се јављају у самим спецификацијама, тако да " -#~ "се грешка у некомпромисном начину рада неможе исправити без-заобилажења " -#~ "спецификација." +#~ msgid "Mod4" +#~ msgstr "Мод4" -#~ msgid "" -#~ "Coordinate expression parser overflowed its buffer, this is really a " -#~ "Metacity bug, but are you sure you need a huge expression like that?" -#~ msgstr "" -#~ "Обрађивач израза са координатама је препунио свој багер, што је велика " -#~ "грешка у метаситију, али да ли стебаш сигурни да вам треба толики израз?" +#~ msgid "Mod5" +#~ msgstr "Мод5" diff --git a/po/sr@latin.po b/po/sr@latin.po index daa0dd5cb..75c09b354 100644 --- a/po/sr@latin.po +++ b/po/sr@latin.po @@ -1,443 +1,292 @@ -# Serbian translation of metacity -# Courtesy of Prevod.org team (http://prevod.org/) -- 2003—2012. -# This file is distributed under the same license as the metacity package. -# Maintainer: Goran Rakić <grakic@devbase.net> -# Reviewed on 2005-09-03 by: Danilo Šegan <danilo@prevod.org>" +# Serbian translation of mutter. +# Courtesy of Prevod.org team (http://prevod.org/) -- 2003—2017. +# This file is distributed under the same license as the mutter package. +# Translators: +# Goran Rakić <grakic@devbase.net> +# Danilo Šegan <danilo@prevod.org>, 2005. # Miloš Popović <gpopac@gmail.com>, 2010. -# Miroslav Nikolić <miroslavnikolic@rocketmail.com>, 2011, 2012. +# Miroslav Nikolić <miroslavnikolic@rocketmail.com>, 2011—2017. msgid "" msgstr "" -"Project-Id-Version: metacity\n" -"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=muffin" -"&keywords=I18N+L10N&component=general\n" -"POT-Creation-Date: 2012-03-11 21:56+0000\n" -"PO-Revision-Date: 2012-03-13 08:36+0200\n" -"Last-Translator: Miroslav Nikolić <miroslavnikolic@rocketmail.com>\n" -"Language-Team: Serbian <gnom@prevod.org>\n" +"Project-Id-Version: mutter\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2018-02-21 15:53+0000\n" +"PO-Revision-Date: 2018-02-21 21:58+0100\n" +"Last-Translator: Marko M. Kostić <marko.m.kostic@gmail.com>\n" +"Language-Team: srpski <gnome-sr@googlegroups.org>\n" "Language: sr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : " -"n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : n" +"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "X-Project-Style: gnome\n" +"X-Generator: Poedit 2.0.6\n" -#: ../src/50-muffin-windows.xml.in.h:1 -msgid "Windows" -msgstr "Prozori" - -#: ../src/50-muffin-windows.xml.in.h:2 -msgid "View split on left" -msgstr "Prikažite podelu na levo" - -#: ../src/50-muffin-windows.xml.in.h:3 -msgid "View split on right" -msgstr "Prikažite podelu na desno" - -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format -msgid "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." -msgstr "" -"Neki drugi kompozitni upravnik je već pokrenut na prikazu %i erkana „%s“." - -#: ../src/core/bell.c:307 -msgid "Bell event" -msgstr "Zvonca" - -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Zahtevana je nepoznata informacija o prozoru: %d" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Navigacija" -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> ne daje odziv." +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Premešta prozor na radni prostor broj 1" -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "Program ne daje odziv." +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Premešta prozor na radni prostor broj 2" -#: ../src/core/delete.c:119 -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "" -"Možete malo sačekati dok se program ne sabere ili primorati program da " -"kompletno prekine sa radom." +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Premešta prozor na radni prostor broj 3" -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "_Sačekaj" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Premešta prozor na radni prostor broj 4" -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "_Primoraj izlaz" +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Premešta prozor na poslednji radni prostor" -#: ../src/core/display.c:361 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "Nedostaje potreban kompozitni dodatak %s" +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "Premešta prozor jedan radni prostor na gore" -#: ../src/core/display.c:427 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Nisam uspeo da otvorim ekran „%s“ Iks sistema prozora\n" +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "Premešta prozor jedan radni prostor na dole" -#: ../src/core/keybindings.c:852 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "" -"Neki drugi program već koristi taster %s sa izmenjivačima %x za neku " -"funkciju\n" +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "Premešta prozor jedan monitor na levo" -#: ../src/core/main.c:206 -msgid "Disable connection to session manager" -msgstr "Onemogućava vezu sa upravnikom sesije" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "Premešta prozor jedan monitor na desno" -#: ../src/core/main.c:212 -msgid "Replace the running window manager" -msgstr "Menja tekućeg upravnika prozorima" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "Premešta prozor jedan monitor na gore" -#: ../src/core/main.c:218 -msgid "Specify session management ID" -msgstr "Navodi ID za upravljanje sesijom" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "Premešta prozor jedan monitor na dole" -#: ../src/core/main.c:223 -msgid "X Display to use" -msgstr "Iks ekran koji će biti korišćen" +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "Prebacuje programe" -#: ../src/core/main.c:229 -msgid "Initialize session from savefile" -msgstr "Koristi sesiju iz datoteke" +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "Prebacuje na prethodni program" -#: ../src/core/main.c:235 -msgid "Make X calls synchronous" -msgstr "Čini Iks pozive usklađenim" +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "Prebacuje prozore" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Nisam uspeo da pročitam direktorijum tema: %s\n" +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "Prebacuje na prethodni prozor" -#: ../src/core/main.c:520 -#, c-format -msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "" -"Ne mogu da pronđem temu! Proverite da %s postoji i da sadrži uobičajne " -"teme.\n" +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "Prebacuje prozore programa" -#: ../src/core/muffin.c:40 -#, c-format -msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" -"mater %s\n" -"Sva prava zadržana (C) 2001–%d Havoc Pennington, Red Hat, Inc., i ostali\n" -"Ovo je slobodan program; pogledajte izvorni kod za uslove korišćenja.\n" -"NE postoji nikakva garancija; čak ni garancija o TRŽIŠNOJ VREDNOSTI ili " -"PRILAGOĐENOSTI ODREĐENOJ NAMENI.\n" +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "Prebacuje na prethodni prozor programa" -#: ../src/core/muffin.c:54 -msgid "Print version" -msgstr "Ispisuje izdanje" +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "Prebacuje kontrole sistema" -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "Spisak dodataka razdvojenih zarezom" +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "Prebacuje na prethodnu kontrolu sistema" -#: ../src/core/prefs.c:1077 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"Kompromisi za loše programe su isključeni. Neke aplikacije se mogu ponašati " -"čudno.\n" +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "Prebacuje prozore direktno" -#: ../src/core/prefs.c:1152 -#, c-format -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "Ne mogu da obradim opis „%s“ iz ključa „%s“ u Gnomovim podešavanjima\n" +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "Prebacuje neposredno na prethodni prozor" -#: ../src/core/prefs.c:1218 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"„%s“ je pronađen u bazi podešavanja što nije ispravna vrednost koja menja " -"ponašanje tastera miša\n" +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "Prebacuje prozore programa direktno" -#: ../src/core/prefs.c:1736 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "„%s“ iz baze sa podešavanjima nije ispravna kombinacija tastera „%s“\n" +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "Prebacuje neposredno na prethodni prozor programa" -#: ../src/core/prefs.c:1833 -#, c-format -msgid "Workspace %d" -msgstr "%d. radni prostor" +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "Prebacuje kontrole sistema direktno" -#: ../src/core/screen.c:730 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "Prikaz %d na ekranu „%s“ nije ispravan\n" +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "Prebacuje neposredno na prethodnu kontrolu sistema" -#: ../src/core/screen.c:746 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"Prikaz %d na ekranu „%s“ već ima upravnika prozora; pokušajte da koristite --" -"replace opciju da zamenite trenutnog upravnika prozora.\n" +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "Skriva sve obične prozore" -#: ../src/core/screen.c:773 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "Ne mogu da dobijem izbor upravnika prozora na prikazu %d erkana „%s“\n" +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "Prebacuje se na radni prostor 1" -#: ../src/core/screen.c:828 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "Prikaz %d na ekranu „%s“ već ima upravnika prozora\n" +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "Prebacuje se na radni prostor 2" -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "Ne mogu da otpustim prikaz %d na ekranu „%s“\n" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "Prebacuje se na radni prostor 3" -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Ne mogu da napravim direktorijum „%s“: %s\n" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "Prebacuje se na radni prostor 4" -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "Ne mogu da otvorim datoteku sesije „%s“ za upis: %s\n" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "Prebacuje se na poslednji radni prostor" -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Greška prilikom upisa u datoteku sesije „%s“: %s\n" +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "Premešta na radni prostor iznad" -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Greška prilikom zatvaranja datoteke sesije „%s“: %s\n" +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "Premešta na radni prostor ispod" -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Nisam uspeo da obradim sačuvanu datoteku sesije: %s\n" +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "Sistem" -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "Atribut <muffin_session> je primećen ali mi već imamo IB sesije" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Prikazuje upit za izvršavanje naredbe" -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Nepoznat atribut %s u <%s> elementu" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Prikazuje pregled aktivnosti" -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "ugnježden <window> element" +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Povrati prečice na tastaturi" -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "Nepoznat element %s" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Prozori" -#: ../src/core/session.c:1809 -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" -"Ovi prozori ne podržavaju mogućnost „snimi trenutna podešavanja“ pa ćete " -"morati da ih ručno ponovo pokrenete kada se sledeći put prijavite." +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "Aktivira meni prozora" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Nisam uspeo da otvorim istorijat grešaka: %s\n" +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Isključuje ili uključuje prikaz preko celog ekrana" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Nisam uspeo da fdopen() datoteku sa istorijatom %s: %s\n" +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "Isključuje ili uključuje stanje uvećanja" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "Otvorena datoteka sa istorijatom %s\n" +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "Uvećava prozor" -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "Mater je preveden bez podrške za opširan režim\n" +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Vraća veličinu prozora" -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "Upravnik prozora: " +#: data/50-mutter-windows.xml:18 +msgid "Close window" +msgstr "Zatvara prozor" -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "Greška u upravniku prozora: " +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "Skriva prozor" -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "Upozorenje upravnika prozora: " +#: data/50-mutter-windows.xml:22 +msgid "Move window" +msgstr "Premešta prozor" -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "Greška upravnika prozora: " +#: data/50-mutter-windows.xml:24 +msgid "Resize window" +msgstr "Menja veličinu prozora" -#. first time through -#: ../src/core/window.c:7224 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"Prozor %s je postavio SM_CLIENT_ID na samog sebe umesto na WM_CLIENT_LEADER " -"prozor kao što je navedeno u ICCCM.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7887 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %" -"d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"Prozor %s je postavio MWM što nagoveštava da nije promenljive veličine, ali " -"je postavio najmanju veličinu %d x %d i najveću veličinu %d x %d; što nema " -"mnogo smisla.\n" +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "Prikazuje prozor na svim radnim prostorima ili samo na jednom" -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "Program je postavio netačan _NET_WM_PID %lu\n" +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "Izdiže prozor ukoliko ga drugi prozor zaklanja, u protivnom ga spušta" -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (na %s)" +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "Izdiže prozor iznad ostalih prozora" -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "Neispravan prozor 0x%lx naveden kao WM_TRANSIENT_FOR za %s.\n" +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "Spušta prozor ispod ostalih prozora" -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "WM_TRANSIENT_FOR prozor 0x%lx za %s će napraviti petlju.\n" +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "Uvećava prozor vertikalno" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"Prozor 0x%lx ima osobinu %s\n" -"tako da je očekivano da ima vrstu %s format %d,\n" -"a zapravo ima vrstu %s format %d n_stavki %d.\n" -"Ovo je najverovatnije greška u programu, a ne u upravniku prozora.\n" -"Prozor ima naslov=„%s“ klasa=„%s“ naziv=„%s“\n" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "Uvećava prozor horizontalno" -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "Osobina %s prozora 0x%lx sadrži neispravan UTF-8\n" +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "Prikažite podelu na levo" -#: ../src/core/xprops.c:494 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"Osobina %s prozora 0x%lx sadrži neispravan UTF-8 za stavku %d na spisku\n" +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "Prikažite podelu na desno" -#: ../src/muffin.desktop.in.h:1 ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" +#: data/mutter.desktop.in:4 +msgid "Mutter" msgstr "Mater" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 +#: data/org.gnome.mutter.gschema.xml.in:7 msgid "Modifier to use for extended window management operations" msgstr "Taster koji se koristi za proširene radnje upravnika prozorima" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 +#: data/org.gnome.mutter.gschema.xml.in:8 msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." msgstr "" -"Ovaj ključ pokreće preklapanje (overlay), koje kombinuje pregled prozora i " +"Ovaj ključ pokreće „overlay“ (preklapanje), koje kombinuje pregled prozora i " "pokretač programa. Podrazumevano je namenjen kao „Windows key“ (ključ prozora) " "za komponente računara. Očekuje se da ovo vezuje ili podrazumevani ili niz " "praznih znakova." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 +#: data/org.gnome.mutter.gschema.xml.in:20 msgid "Attach modal dialogs" msgstr "Prilaganje modalnih prozorčića" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 +#: data/org.gnome.mutter.gschema.xml.in:21 msgid "" "When true, instead of having independent titlebars, modal dialogs appear " "attached to the titlebar of the parent window and are moved together with " "the parent window." msgstr "" "Kada je izabrano, umesto nezavisnih linija naslova, modalni prozorčići se " -"pojavljuju priloženi na liniju alata matičnog prozora i bivaju premeštani " +"pojavljuju priloženi na traku alata matičnog prozora i bivaju premeštani " "zajedno sa matičnim prozorom." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -msgid "Live Hidden Windows" -msgstr "Održavanje skrivenih prozora" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"Određuje da li da skriveni prozori (npr. umanjeni prozori ili prozori na " -"drugoj radnoj površi) ostanu pokrenuti." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 +#: data/org.gnome.mutter.gschema.xml.in:30 msgid "Enable edge tiling when dropping windows on screen edges" msgstr "" "Uključuje popločavanje ivice prilikom otpuštanja prozora na ivicama ekrana" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 +#: data/org.gnome.mutter.gschema.xml.in:31 msgid "" "If enabled, dropping windows on vertical screen edges maximizes them " "vertically and resizes them horizontally to cover half of the available " @@ -447,25 +296,25 @@ msgstr "" "uspravno i menja im veličinu vodoravno da prekriju polovinu dostupne oblasti. " "Otpuštanje prozora na gornjoj ivici ekrana uvećava ih u potpunosti." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 +#: data/org.gnome.mutter.gschema.xml.in:40 msgid "Workspaces are managed dynamically" msgstr "Radnim prostorima se upravlja dinamički" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 +#: data/org.gnome.mutter.gschema.xml.in:41 msgid "" -"Determines whether workspaces are managed dynamically or whether there's a " +"Determines whether workspaces are managed dynamically or whether there’s a " "static number of workspaces (determined by the num-workspaces key in org." "gnome.desktop.wm.preferences)." msgstr "" "Određuje da li se radnim prostorima upravlja dinamički ili će postojati " -"stalni broj radnih prostora (određen brojem radnih prostora u " -"„org.cinnamon.desktop.wm.preferences“)." +"stalni broj radnih prostora (određen brojem radnih prostora u „org.gnome." +"desktop.wm.preferences“)." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 +#: data/org.gnome.mutter.gschema.xml.in:50 msgid "Workspaces only on primary" msgstr "Radni prostori samo na primarne" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 +#: data/org.gnome.mutter.gschema.xml.in:51 msgid "" "Determines whether workspace switching should happen for windows on all " "monitors or only for windows on the primary monitor." @@ -473,11 +322,11 @@ msgstr "" "Određuje da li prebacivanje radnog prostora treba da se desi za prozore na " "svim monitorima ili samo za prozore na glavnom monitoru." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 +#: data/org.gnome.mutter.gschema.xml.in:59 msgid "No tab popup" msgstr "Bez iskakanja jezička" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 +#: data/org.gnome.mutter.gschema.xml.in:60 msgid "" "Determines whether the use of popup and highlight frame should be disabled " "for window cycling." @@ -485,3380 +334,1100 @@ msgstr "" "Određuje da li će upotreba okvira iskakanja i isticanja biti prikazana za " "kretanje po prozorima." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Zastoj prvog plana se menja dok se pokazivač ne zaustavi" + +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" +"Ako je izabrano, a režim prvog plana je ili „sloppy“ ili „mouse“ onda prvi " +"plan neće biti menjan odmah po ulasku u prozor, već samo nakon što pokazivač " +"prestane da se pomera." + +#: data/org.gnome.mutter.gschema.xml.in:79 msgid "Draggable border width" msgstr "Širina ivice za prevlačenje" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 +#: data/org.gnome.mutter.gschema.xml.in:80 msgid "" -"The amount of total draggable borders. If the theme's visible borders are " +"The amount of total draggable borders. If the theme’s visible borders are " "not enough, invisible borders will be added to meet this value." msgstr "" "Iznos ukupne ivice za prevlačenje. Ako vidljive ivice teme nisu dovoljne, biće " "dodate nevidljive ivice za dostizanje ove vrednosti." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:17 -msgid "Select window from tab popup" -msgstr "Bira prozor iz jezička iskakanja" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:18 -msgid "Cancel tab popup" -msgstr "Otkazivanje jezička iskakanja" - -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "Upotreba: %s\n" - -#: ../src/ui/frames.c:1158 -msgid "Close Window" -msgstr "Zatvori prozor" - -#: ../src/ui/frames.c:1161 -msgid "Window Menu" -msgstr "Izbornik prozora" - -#: ../src/ui/frames.c:1164 -msgid "Minimize Window" -msgstr "Umanji prozor" - -#: ../src/ui/frames.c:1167 -msgid "Maximize Window" -msgstr "Uvećaj prozor" - -#: ../src/ui/frames.c:1170 -msgid "Restore Window" -msgstr "Vrati veličinu prozora" - -#: ../src/ui/frames.c:1173 -msgid "Roll Up Window" -msgstr "Zamotaj prozor" - -#: ../src/ui/frames.c:1176 -msgid "Unroll Window" -msgstr "Odmotaj prozor" - -#: ../src/ui/frames.c:1179 -msgid "Keep Window On Top" -msgstr "Postavi prozor iznad ostalih" - -#: ../src/ui/frames.c:1182 -msgid "Remove Window From Top" -msgstr "Ukloni prozor sa vrha" - -#: ../src/ui/frames.c:1185 -msgid "Always On Visible Workspace" -msgstr "Uvek na prikazanoj radnoj površi" - -#: ../src/ui/frames.c:1188 -msgid "Put Window On Only One Workspace" -msgstr "Postavi prozor samo na jednu radnu površ" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "_Umanji" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "Uv_ećaj" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "Poništi u_većanje" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "_Zamotaj" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "_Odmotaj" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "_Premesti" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "P_romeni veličinu" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "Premesti naslovnu liniju na _ekran" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "Uvek iznad os_talih" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "_Uvek na vidljivom radnom prostoru" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "Samo na _ovom radnom prostoru" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "Premesti na radni prostor le_vo" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "Premesti na radni prostor de_sno" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "Premesti na radni prostor go_re" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "Premesti na radni prostor do_le" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "_Zatvori" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "Radni prostor %d%n" - -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "1_0. radni prostor" - -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "%s%d. radni prostor" - -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "Premesti na drugi _radni prostor" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Šift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ktrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hiper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" - -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" - -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "gornju" +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "Sam uvećava povećane prozore najbližeg monitora" -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "donju" - -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "levu" - -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "desnu" - -#: ../src/ui/theme.c:286 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "geometrija okvira ne podešava „%s“ dimenziju" - -#: ../src/ui/theme.c:305 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "geometrija okvira ne podešava „%s“ dimenziju za ivicu „%s“" - -#: ../src/ui/theme.c:342 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "Odnos razmere dugmeta %g nije razuman" - -#: ../src/ui/theme.c:354 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "Geometrija okvira ne podešava veličinu dugmića" - -#: ../src/ui/theme.c:1067 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "Prelivi moraju imati najmanje dve boje" - -#: ../src/ui/theme.c:1219 -#, c-format -msgid "" -"GTK custom color specification must have color name and fallback in " -"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" -msgstr "" -"Specifikacija proizvoljne GTK boje mora imati naziv boje i prebacivanje u " -"zagradi, na primer gtk:custom(foo,bar); ne mogu da obradim „%s“" - -#: ../src/ui/theme.c:1235 -#, c-format -msgid "" -"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" -"_ are valid" -msgstr "" -"Neispravan znak „%c“ parametra naziv_boje u gtk:custom, iaspravni su samo A-" -"Za-z0-9-_" - -#: ../src/ui/theme.c:1249 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:90 msgid "" -"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " -"fit the format" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." msgstr "" -"Gtk:proizvoljni format je „gtk:custom(naziv_boje,prebacivanje)“, „%s“ se ne " -"uklapa u format" +"Ako je uključeno, novi prozori koji su početno veličine monitora samostalno " +"bivaju uvećani." -#: ../src/ui/theme.c:1294 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"Specifikacija GTK boje mora imati navedeno stanje u zagradi, na primer gtk:fg" -"[NORMAL] gde je NORMAL stanje; ne mogu da obradim „%s“" +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Novi prozor u središte" -#: ../src/ui/theme.c:1308 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:99 msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." msgstr "" -"Specifikacija GTK boje mora imati navedeno stanje u zagradi, na primer gtk:fg" -"[NORMAL] gde je NORMAL stanje; ne mogu da obradim „%s“" - -#: ../src/ui/theme.c:1319 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "Nisam razumeo stanje „%s“ u specifikaciji boje" +"Ako je izabrano, novi prozori će uvek biti postavljeni na sredinu radnog " +"ekrana monitora." -#: ../src/ui/theme.c:1332 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "Nisam razumeo deo boje „%s“ u specifikaciji boje" +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Uključuje eksperimentalne funkcije" -#: ../src/ui/theme.c:1361 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:108 msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “remote-desktop” — " +"enables remote desktop support. To support remote desktop with screen " +"sharing, “screen-cast” must also be enabled. • “screen-cast” — enables " +"screen cast support." msgstr "" -"Format smeše je „blend/bg_color/fg_color/alpha“, „%s“ se ne uklapa u traženi " -"format zapisa" - -#: ../src/ui/theme.c:1372 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "Ne mogu da obradim alfa vrednost „%s“ u smešanoj boji" - -#: ../src/ui/theme.c:1382 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "Alfa vrednost „%s“ u smešanoj boji nije između 0.0 i 1.0" - -#: ../src/ui/theme.c:1429 -#, c-format -msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "Format senke je „shade/base_color/factor“, „%s“ se ne uklapa u format" - -#: ../src/ui/theme.c:1440 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "Ne mogu da obradim faktor senke „%s“ u osenčenoj boji" - -#: ../src/ui/theme.c:1450 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "Faktor senke „%s“ u osenčenoj boji je negativan" - -#: ../src/ui/theme.c:1479 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Ne mogu da obradim boju „%s“" - -#: ../src/ui/theme.c:1790 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "Izraz koordinata sadrži znak „%s“ koji nije dozvoljen" +"Da uključite probne funkcije, dodajte ključnu reč funkcije na spisak. Da li " +"funkcija zahteva ponovno pokretanje sastavljača zavisi od date funkcije. Nije " +"potrebno da neka probna mogućnost bude i dalje dostupna ili podesiva. Nemojte " +"očekivati da dodavanje bilo čega u ovom podešavanju bude otporno na buduće " +"izmene. Trenutno moguće ključne reči su: • „scale-monitor-framebuffer“ — čini " +"da mater podrazumevano raspoređuje logičke ekrane u logičkom koordinantnom " +"prostoru piksela, prilikom promene veličine spremišta kadrova ekrana umesto " +"sadržaja prozora, zarad upravljanja ekranima visoke rezolucije. Ne zahteva " +"ponovno pokretanje. • “remote-desktop” — omogućava udaljenu tehničku podršku. " +"Da biste podržali udaljenu tehničku podršku sa deljenjem ekrana, “screen-cast” " +"takođe mora biti omogućen. • “screen-cast” — omogućava podršku za " +"projektovanje ekrana." + +#: data/org.gnome.mutter.gschema.xml.in:145 +msgid "Select window from tab popup" +msgstr "Bira prozor iz jezička iskakanja" -#: ../src/ui/theme.c:1817 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "Izraz koordinata sadrži decimalni broj „%s“ koji ne može biti obrađen" +#: data/org.gnome.mutter.gschema.xml.in:150 +msgid "Cancel tab popup" +msgstr "Otkazivanje jezička iskakanja" -#: ../src/ui/theme.c:1831 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "Izraz koordinata sadrži celi broj „%s“ koji ne može biti obrađen" +#: data/org.gnome.mutter.gschema.xml.in:155 +msgid "Switch monitor configurations" +msgstr "Menja podešavanja monitora" -#: ../src/ui/theme.c:1953 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "" -"Izraz sa koordinatama sadrži nepoznati operator na početku ovog teksta: „%s“" +#: data/org.gnome.mutter.gschema.xml.in:160 +msgid "Rotates the built-in monitor configuration" +msgstr "Zaokreće ugrađena podešavanja monitora" -#: ../src/ui/theme.c:2010 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "Izraz sa koordinatama je bio prazan ili nerazumljiv" +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Prelazak na VT 1" -#: ../src/ui/theme.c:2121 ../src/ui/theme.c:2131 ../src/ui/theme.c:2165 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "Izraz sa koordinatama vodi deljenju sa nulom" +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Prelazak na VT 2" -#: ../src/ui/theme.c:2173 -#, c-format -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "" -"Izraz sa koordinatam pokušava da koristi operator ostatka pri deljenju za " -"decimalni broj" +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Prelazak na VT 3" -#: ../src/ui/theme.c:2229 -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "Izraz sa koordinatama ima operator „%s“ gde je očekivan operand" +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Prelazak na VT 4" -#: ../src/ui/theme.c:2238 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "Izraz sa koordinarama ima operand gde je očekivan operator" +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Prelazak na VT 5" -#: ../src/ui/theme.c:2246 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "Izraz sa koordinarama je završio sa operatorom umesto sa operandom" +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Prelazak na VT 6" -#: ../src/ui/theme.c:2256 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" -"Izraz sa koordinatama ima operator „%c“, a zatim operator „%c“ bez operanda " -"između" +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Prelazak na VT 7" -#: ../src/ui/theme.c:2407 ../src/ui/theme.c:2452 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "Izraz sa koordinatama ima nepoznatu promenljivu ili konstanti „%s“" +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Prelazak na VT 8" -#: ../src/ui/theme.c:2506 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "Izraz sa koordinatama je bio preveliki za smeštaj i obradu." +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Prelazak na VT 9" -#: ../src/ui/theme.c:2535 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "Izraz sa koordinatama ima zatvorene zagrade bez otvorenih zagrada" +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Prelazak na VT 10" -#: ../src/ui/theme.c:2599 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "Izraz sa koordinatama ima otvorene zagrade bez zatvorenih zagrada" +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Prelazak na VT 11" -#: ../src/ui/theme.c:2610 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "Izraz sa koordinatama nema ni jedan operator ili operand" +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Prelazak na VT 12" -#: ../src/ui/theme.c:2822 ../src/ui/theme.c:2842 ../src/ui/theme.c:2862 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "Tema sadrži izraz koji rezultira greškom: %s\n" +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "Ponovo uključivanje prečica" -#: ../src/ui/theme.c:4533 -#, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"bilo šta\"/> mora biti " -"naveden za ovaj stil okvira" +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow grabs with Xwayland" +msgstr "Dozvoli grabljenje na Iks-vejlendu" -#: ../src/ui/theme.c:5066 ../src/ui/theme.c:5091 -#, c-format +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" +"Allow keyboard grabs issued by X11 applications running in Xwayland to be " +"taken into account. For a X11 grab to be taken into account under Wayland, " +"the client must also either send a specific X11 ClientMessage to the root " +"window or be among the applications white-listed in key “xwayland-grab-" +"access-rules”." msgstr "" -"Nedostaje <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"bilo šta\"/>" - -#: ../src/ui/theme.c:5139 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Nisam uspeo da učitam temu „%s“: %s\n" - -#: ../src/ui/theme.c:5275 ../src/ui/theme.c:5282 ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 ../src/ui/theme.c:5303 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "Nije definisan element <%s> za temu „%s“" +"Dozvoli da se uzmu u obzir grabljenja od strane Iks11 programa unutar Iks-" +"vejlenda. Da bi se Iks11 grabljenje uzelo u obzir pod Vejlendom, klijent mora " +"takođe poslati specifičnu Iks11 klijentsku poruku ka korenom prozoru ili " +"mora biti na belom spisku programa u ključu „xwayland-grab-access-rules“." -#: ../src/ui/theme.c:5311 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" -"Nije podešen stil okvira za prozor vrste „%s“ u temi „%s“. Dodajte <window " -"type=\"%s\" style_set=\"bilo šta\"/> element." +#: data/org.gnome.mutter.wayland.gschema.xml.in:77 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "Iks-vejlend programi kojima je dozvoljeno da rade grabljenja na tastaturi" -#: ../src/ui/theme.c:5709 ../src/ui/theme.c:5771 ../src/ui/theme.c:5834 -#, c-format +#: data/org.gnome.mutter.wayland.gschema.xml.in:78 msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." msgstr "" -"Korisnički definisane konstante moraju početi velikim slovom; „%s“ ne počinje" - -#: ../src/ui/theme.c:5717 ../src/ui/theme.c:5779 ../src/ui/theme.c:5842 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "Konstanta „%s“ je već definisana" - -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. -#. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "Nije definisan „%s“ atribut u elementu <%s>" - -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Linija %d znak %d: %s" - -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "Atribut „%s“ je ponovljen dva puta u istom elementu <%s>" - -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "Atribut „%s“ je neispravan u elementu <%s> u ovom kontekstu" - -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "Ne mogu da izdvojim „%s“ kao celobrojnu vrednost" - -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "Ne razumem vodeće znake „%s“ u nizu karaktera „%s“" - -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "Celi broj %ld mora biti pozitivan" - -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "Celi broj %ld je prevelik, trenutno najveći je %d" - -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "Ne mogu da obradim „%s“ kao decimalni broj" - -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "Logičke vrednosti moraju biti „true“ ili „false“, a ne „%s“" - -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "Ugao mora biti između 0.0 i 360.0, bio je %g\n" - -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" -"Alfa stepen mora biti između 0.0 (nevidljivo) i 1.0 (potpuno vidljivo), bio je " -"%g\n" - -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"Netačno skaliranje naslova „%s“ (mora biti jedan od sledećih: xx-small,x-" -"small,small,medium,large,x-large,xx-large)\n" - -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s> naziv „%s“ je korišćen po drugi put" - -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "<%s> matični „%s“ nije definisan" - -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "<%s> geometrija „%s“ nije definisana" - -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "" -"<%s> mora biti navedena ili geometrija ili matični element koji ima " -"geometriju" - -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "Morate navesti pozadinu da bi alfa vrednost imala smisla" - -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Nepoznat tip „%s“ u elementu <%s>" - -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "Nepoznat style_set „%s“ u elementu <%s>" - -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "Tipu prozora „%s“ je već dodeljen skup stila" - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "Element <%s> nije dozvoljen ispod <%s>" - -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" -msgstr "Ne mogu da podesim i širinu/visinu i razmeru dugmadi" - -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "Udaljenost „%s“ je nepoznata" - -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "Odnos „%s“ je nepoznat" - -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "Ivica „%s“ je nepoznata" - -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "" -"Nije definisan početni_ugao (start_angle) ili od (from) atribut u elementu <%" -"s>" - -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "Nije definisan „extent_angle“ ili „to“ atribut u elementu <%s>" - -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "Nisam razumeo vrednost „%s“ kao tip gradijenta" - -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "Nisam razumeo tip popunjavanja površine „%s“ u elementu <%s>" - -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "Nisam razumeo stanje „%s“ u elementu <%s>" - -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "Nisam razumeo senku „%s“ u elementu <%s>" - -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "Nisam razumeo strelicu „%s“ u elementu <%s>" - -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "Nije definisan <draw_ops> označen kao „%s“" - -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "Uključivanje elementa draw_ops „%s“ ovde bi napravilo kružnu referencu" - -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Nepoznat položaj „%s“ za deo okvira" - -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "Stil okvira već ima deo na položaju %s" - -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "Nije definisan <draw_ops> sa imenom „%s“" - -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Nepoznata funkcija „%s“ za dugme" - -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "" -"Funkcija „%s“ za dugme ne postoji u ovoj verziji (verzija %d, a treba vam %d)" - -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Nepoznato stanje „%s“ za dugme" - -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "Stil okvira već ima dugme sa funkcijom %s i stanjem %s" - -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "„%s“ nije dozvoljena vrednost za atribut fokusa" - -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "„%s“ nije dozvoljena vrednost za atribut stanja" - -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "Stil „%s“ nije definisan" - -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "„%s“ nije dozvoljena vrednost za atribut resize" - -#: ../src/ui/theme-parser.c:3147 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" -"Nikako ne treba imati „resize“ atribut u elementu <%s> za uvećana/zasenčena " -"stanja" - -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "" -"Nikako ne treba imati „resize“ atribut u elementu <%s> za uvećana stanja" - -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "Stil je već naveden za stanje %s uvećanje %s fokus %s" - -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "Stil je već naveden za stanje %s fokus %s" - -#: ../src/ui/theme-parser.c:3294 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Ne mogu postojati dva draw_ops-a za element <piece> (tema navodi draw_ops " -"atribut i <draw_ops> element, ili navodi dva elementa)" - -#: ../src/ui/theme-parser.c:3332 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Ne mogu postojati dva draw_ops-a za element <button> (tema navodi draw_ops " -"atribut i <draw_ops> element, ili navodi dva elementa)" - -#: ../src/ui/theme-parser.c:3370 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Ne mogu postojati dva draw_ops-a za element <menu_icon> (tema navodi " -"draw_ops atribut i <draw_ops> element, ili navodi dva elementa)" - -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "Izdanje je loše određeno „%s“" - -#: ../src/ui/theme-parser.c:3507 -msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" -msgstr "" -"Ne mogu da koristim „version“ (izdanje) u metacity-theme-1.xml ili metacity-" -"theme-2.xml" - -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "Za ovu temu je neophodno izdanje %s, a poslednja podržana tema je %d.%d" - -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "Najstariji element teme mora biti <metacity_theme>, a ne <%s>" - -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "" -"Element <%s> nije dozvoljen unutar elemenata name, author, date i description" - -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "Element <%s> nije dozvoljen unutar elementa <constant>" - -#: ../src/ui/theme-parser.c:3599 -#, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "" -"Element <%s> nije dozvoljen unutar elemenata distance, border i aspect_ratio" - -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "Element <%s> nije dozvoljen unutar elemenata operacija crtanja" - -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "Element <%s> nije dozvoljen unutar <%s> elementa" - -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "Nije naveden draw_ops za deo okvira" - -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "Nije naveden draw_ops dugme" - -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "Nije dozvoljen tekst unutar elementa <%s>" - -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "<%s> je naveden dva puta u ovoj temi" - -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Nisam uspeo da pronađem ispravnu datoteku za temu %s\n" - -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "_Prozori" - -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "Pro_zorče" - -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "_Važno prozorče" - -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "_Alatka" - -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "_Uvodni ekran" - -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "_Gornje pripajanje" - -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "_Donje pripajanje" - -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "_Levo pripajanje" - -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "D_esno pripajanje" - -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "_Sva pripajanja" - -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "_Radna površ" - -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "Otvori neki drugi od ovih prozora" - -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "Ovo je probno dugme sa „otvori“ ikonom" - -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "Ovo je probno dugme sa „izađi“ ikonicom" - -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "Ovo je primer poruke u probnom prozorčetu" - -#: ../src/ui/theme-viewer.c:328 -#, c-format -msgid "Fake menu item %d\n" -msgstr "Lažna stavka izbornika %d\n" - -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "Prozor samo sa ivicom" - -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "Traka" - -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "Običan prozor programa" - -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "Prozorče" - -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "Važno prozorče" - -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "Paleta alata" - -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "Otkinuti izbornik" - -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "Ivica" - -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "Priloženo važno prozorče" - -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "Proba rasporeda dugmića %d" - -# bug: plural-forms -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g milisekundi za iscrtavanje okvira jednog prozora" - -#: ../src/ui/theme-viewer.c:813 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Upotreba: metacity-theme-viewer [NAZIV_TEME]\n" - -#: ../src/ui/theme-viewer.c:820 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "Greška prilikom učitavanja teme: %s\n" - -# bug: plural-forms -#: ../src/ui/theme-viewer.c:826 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "Učitana je tema „%s“ za %g sekunde\n" - -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "Običan naslovni slovni lik" - -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "Mali naslovni slovni lik" - -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "Veliki naslovni slovni lik" - -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "Raspored dugmića" - -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "Provera brzine" - -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "Ovde ide naslov prozora" - -# bug: plural-forms -#: ../src/ui/theme-viewer.c:1047 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"Nacrtao je %d okvira za %g klijentskih sekundi (%g milisekundi po okviru) i %" -"g sekundi vremena na zidnom časovniku uključujući i resurse Iks servera (%g " -"milisekundi po okviru)\n" - -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "provera izraza položaja je vratila tačno, ali je postavila grešku" - -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "provera izraza položaja je vratila netačno, ali nije postavila grešku" - -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "Očekivana je greška, ali nije data" - -#: ../src/ui/theme-viewer.c:1274 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "Očekivana je greška %d, ali je data %d" - -#: ../src/ui/theme-viewer.c:1280 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "Greška nije očekivana, ali je vraćena: %s" - -#: ../src/ui/theme-viewer.c:1284 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "x vrednost je bila %d, a očekivana je %d" - -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "y vrednost je bila %d, a očekivana je %d" - -# bug: plural-forms -#: ../src/ui/theme-viewer.c:1352 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "%d izraza koordinata je obrađeno za %g sekunde (prosek %g sekunde)\n" - -#~ msgid "Switch to workspace 1" -#~ msgstr "Prebacite se na radni prostor 1" - -#~ msgid "Switch to workspace 2" -#~ msgstr "Prebacite se na radni prostor 2" - -#~ msgid "Switch to workspace 3" -#~ msgstr "Prebacite se na radni prostor 3" - -#~ msgid "Switch to workspace 4" -#~ msgstr "Prebacite se na radni prostor 4" - -#~ msgid "Switch to workspace 5" -#~ msgstr "Prebacite se na radni prostor 5" - -#~ msgid "Switch to workspace 6" -#~ msgstr "Prebacite se na radni prostor 6" - -#~ msgid "Switch to workspace 7" -#~ msgstr "Prebacite se na radni prostor 7" - -#~ msgid "Switch to workspace 8" -#~ msgstr "Prebacite se na radni prostor 8" - -#~ msgid "Switch to workspace 9" -#~ msgstr "Prebacite se na radni prostor 9" - -#~ msgid "Switch to workspace 10" -#~ msgstr "Prebacite se na radni prostor 10" - -#~ msgid "Switch to workspace 11" -#~ msgstr "Prebacite se na radni prostor 11" - -#~ msgid "Switch to workspace 12" -#~ msgstr "Prebacite se na radni prostor 12" - -#~ msgid "Switch to workspace on the left of the current workspace" -#~ msgstr "Prebacite se na radni prostor na levo" - -#~ msgid "Switch to workspace on the right of the current workspace" -#~ msgstr "Prebacite se na radni prostor na desno" - -#~ msgid "Switch to workspace above the current workspace" -#~ msgstr "Prebacite se na radni prostor iznad ovog" - -#~ msgid "Switch to workspace below the current workspace" -#~ msgstr "Prebacite se na radni prostor ispod ovog" - -#~ msgid "Move between windows of an application, using a popup window" -#~ msgstr "Premesti između prozora programa uz iskakanje" - -#~ msgid "" -#~ "Move backward between windows of an application, using a popup window" -#~ msgstr "Premesti unazad između prozora programa uz iskakanje" - -#~ msgid "Move between windows, using a popup window" -#~ msgstr "Premesti između prozora uz iskakanje" - -#~ msgid "Move backward between windows, using a popup window" -#~ msgstr "Premesti unazad između prozora uz iskakanje" - -#~ msgid "Move between panels and the desktop, using a popup window" -#~ msgstr "Premesti između panela i radne površine uz iskakanje" - -#~ msgid "Move backward between panels and the desktop, using a popup window" -#~ msgstr "Premesti unazad između panela i radne površine uz iskakanje" - -#~ msgid "Move between windows of an application immediately" -#~ msgstr "Premesti odmah između prozora programa" - -#~ msgid "Move backward between windows of an application immediately" -#~ msgstr "Premesti odmah unazad između prozora programa" - -#~ msgid "Move between windows immediately" -#~ msgstr "Premesti odmah između prozora" - -#~ msgid "Move backward between windows immediately" -#~ msgstr "Premesti odmah unazad između prozora" - -#~ msgid "Move between panels and the desktop immediately" -#~ msgstr "Premesti odmah između panela i radne površine" - -#~ msgid "Move backward between panels and the desktop immediately" -#~ msgstr "Premesti odmah unazad između panela i radne površine" - -#~ msgid "Hide all normal windows and set focus to the desktop" -#~ msgstr "Sakrij sve obične prozore i prikaži radnu površinu" - -#~ msgid "Show the panel's main menu" -#~ msgstr "Prikaži glavni meni panela" - -#~ msgid "Show the panel's \"Run Application\" dialog box" -#~ msgstr "Prikaži prozorče za pokretanje programa u panelu" - -#~ msgid "Start or stop recording the session" -#~ msgstr "Počinje i zaustavlja snimanje sesije" - -#~ msgid "Take a screenshot" -#~ msgstr "Napravi snimak ekrana" - -#~ msgid "Take a screenshot of a window" -#~ msgstr "Napravi snimak prozora" - -#~ msgid "Run a terminal" -#~ msgstr "Pokreni terminal" - -#~ msgid "Activate the window menu" -#~ msgstr "Aktiviraj meni prozora" - -#~ msgid "Toggle fullscreen mode" -#~ msgstr "Prebaci prikaz preko celog ekrana" - -#~ msgid "Toggle maximization state" -#~ msgstr "Promeni stanje uvećanja" - -#~ msgid "Toggle whether a window will always be visible over other windows" -#~ msgstr "Određuje da li se prozor uvek prikazuje iznad ostalih" - -#~ msgid "Maximize window" -#~ msgstr "Uvećaj prozor" - -#~ msgid "Restore window" -#~ msgstr "Vrati veličinu prozoru" - -#~ msgid "Toggle shaded state" -#~ msgstr "Promeni stanje zasenčenosti" - -#~ msgid "Minimize window" -#~ msgstr "Umanji prozor" - -#~ msgid "Close window" -#~ msgstr "Zatvori prozor" - -#~ msgid "Move window" -#~ msgstr "Premesti prozor" - -#~ msgid "Resize window" -#~ msgstr "Promeni veličinu prozoru" - -#~ msgid "Toggle whether window is on all workspaces or just one" -#~ msgstr "Prikazuje prozor na svim ili samo na jednoj radnoj površi" - -#~ msgid "Move window to workspace 1" -#~ msgstr "Premesti prozor na radni prostor broj 1" - -#~ msgid "Move window to workspace 2" -#~ msgstr "Premesti prozor na radni prostor broj 2" - -#~ msgid "Move window to workspace 3" -#~ msgstr "Premesti prozor na radni prostor broj 3" - -#~ msgid "Move window to workspace 4" -#~ msgstr "Premesti prozor na radni prostor broj 4" - -#~ msgid "Move window to workspace 5" -#~ msgstr "Premesti prozor na radni prostor broj 5" - -#~ msgid "Move window to workspace 6" -#~ msgstr "Premesti prozor na radni prostor broj 6" - -#~ msgid "Move window to workspace 7" -#~ msgstr "Premesti prozor na radni prostor broj 7" - -#~ msgid "Move window to workspace 8" -#~ msgstr "Premesti prozor na radni prostor broj 8" - -#~ msgid "Move window to workspace 9" -#~ msgstr "Premesti prozor na radni prostor broj 9" - -#~ msgid "Move window to workspace 10" -#~ msgstr "Premesti prozor na radni prostor broj 10" - -#~ msgid "Move window to workspace 11" -#~ msgstr "Premesti prozor na radni prostor broj 11" - -#~ msgid "Move window to workspace 12" -#~ msgstr "Premesti prozor na radni prostor broj 12" - -#~ msgid "Move window one workspace to the left" -#~ msgstr "Premesti prozor za jedan sledeći radni prostor ulevo" - -#~ msgid "Move window one workspace to the right" -#~ msgstr "Premesti prozor za jedan sledeći radni prostor udesno" - -#~ msgid "Move window one workspace up" -#~ msgstr "Premesti prozor za jedan radni prostor na gore" - -#~ msgid "Move window one workspace down" -#~ msgstr "Premesti prozor za jedan radni prostor na dole" - -#~ msgid "Raise window if it's covered by another window, otherwise lower it" -#~ msgstr "" -#~ "Podigni prozor ukoliko ga drugi prozor zaklanja, u protivnom ga spusti" - -#~ msgid "Raise window above other windows" -#~ msgstr "Podigni prozor iznad ostalih prozora" - -#~ msgid "Lower window below other windows" -#~ msgstr "Spusti prozor ispod ostalih prozora" - -#~ msgid "Maximize window vertically" -#~ msgstr "Uvećaj prozor vertikalno" - -#~ msgid "Maximize window horizontally" -#~ msgstr "Uvećaj prozor horizontalno" - -#~ msgid "Move window to north-west (top left) corner" -#~ msgstr "Premesti prozor u gornji, levi ćošak" - -#~ msgid "Move window to north-east (top right) corner" -#~ msgstr "Premesti prozor u gornji, desni ćošak" - -#~ msgid "Move window to south-west (bottom left) corner" -#~ msgstr "Premesti prozor u donji, levi ćošak" - -#~ msgid "Move window to south-east (bottom right) corner" -#~ msgstr "Premesti prozor u donji, desni ćošak" +"Spisak naziva resursa ili klasi resursa Iks11 prozora kojima je dozvoljeno " +"ili zabranjeno da rade grabljenja na tastaturi pod Iks-vejlendom. Naziv resursa " +"ili klasa resursa datog Iks11 prozora se može naći preko naredbe \"xprop " +"WM_CLASS\". Džoker znakovi „*“ i „?“ unutar vrednosti su podržani. Vrednosti " +"koje počinju sa „!“ se stavljaju na crni spisak, koji ima prednost u odnosu na " +"beli spisak, za opoziv programa za podrazumevanog sistemskog spiska. " +"Podrazumevani sistemski spisak sadrži sledeće programe: " +"\"@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@\" Korisnici mogu slomiti postojeće " +"grabljenje tako što će upotrebiti posebnu prečicu na tastaturi koja je " +"navedena u ključu za vezivanje tastera sa nazivom \"restore-shortcuts\"." + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. +#. +#: src/backends/meta-input-settings.c:2325 +#, c-format +msgid "Mode Switch (Group %d)" +msgstr "Režim prekidača (grupa %d)" -#~ msgid "Move window to north (top) side of screen" -#~ msgstr "Premesti prozor u vrh ekrana" +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2348 +msgid "Switch monitor" +msgstr "Promeni monitor" -#~ msgid "Move window to south (bottom) side of screen" -#~ msgstr "Premesti prozor u dno ekrana" +#: src/backends/meta-input-settings.c:2350 +msgid "Show on-screen help" +msgstr "Prikaži pomoć na ekranu" -#~ msgid "Move window to east (right) side of screen" -#~ msgstr "Premesti prozor uz desnu ivicu ekrana" +#: src/backends/meta-monitor-manager.c:900 +msgid "Built-in display" +msgstr "Ugrađeni displej" -#~ msgid "Move window to west (left) side of screen" -#~ msgstr "Premesti prozor uz levu ivicu ekrana" +#: src/backends/meta-monitor-manager.c:923 +msgid "Unknown" +msgstr "Nepoznato" -#~ msgid "Move window to center of screen" -#~ msgstr "Premesti prozor na sredinu ekrana" +#: src/backends/meta-monitor-manager.c:925 +msgid "Unknown Display" +msgstr "Nepoznat displej" -#~ msgid "" -#~ "There was an error running <tt>%s</tt>:\n" -#~ "\n" -#~ "%s" -#~ msgstr "" -#~ "Javila se greška pri pokretanju <tt>%s</tt>:\n" -#~ "\n" -#~ "%s" +#. TRANSLATORS: this is a monitor vendor name, followed by a +#. * size in inches, like 'Dell 15"' +#. +#: src/backends/meta-monitor-manager.c:933 +#, c-format +msgid "%s %s" +msgstr "%s %s" -#~ msgid "No command %d has been defined.\n" -#~ msgstr "Nije definisana komanda %d.\n" +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:481 +#, c-format +msgid "" +"Another compositing manager is already running on screen %i on display “%s”." +msgstr "" +"Neki drugi kompozitni upravnik je već pokrenut na prikazu %i erkana „%s“." -#~ msgid "No terminal command has been defined.\n" -#~ msgstr "Nije definisana naredba terminala.\n" +#: src/core/bell.c:194 +msgid "Bell event" +msgstr "Zvonca" -#~ msgid "GConf key '%s' is set to an invalid value\n" -#~ msgstr "Ključ „%s“ u gnom podešavanjima je podešen na nepropisnu vrednost\n" +#: src/core/display.c:608 +#, c-format +msgid "Failed to open X Window System display “%s”\n" +msgstr "Nisam uspeo da otvorim ekran „%s“ Iks sistema prozora\n" -#~ msgid "%d stored in GConf key %s is out of range %d to %d\n" -#~ msgstr "%d sačuvan u ključu %s je izvan opsega od %d do %d\n" +#: src/core/main.c:190 +msgid "Disable connection to session manager" +msgstr "Isključuje vezu sa upravnikom sesije" -#~ msgid "GConf key \"%s\" is set to an invalid type\n" -#~ msgstr "Ključ „%s“ u gnom podešavanjima je podešen na nepropisni tip\n" +#: src/core/main.c:196 +msgid "Replace the running window manager" +msgstr "Menja tekućeg upravnika prozorima" -#~ msgid "GConf key %s is already in use and can't be used to override %s\n" -#~ msgstr "GKonf ključ %s je već upotrebljen i ne može prepisati %s\n" +#: src/core/main.c:202 +msgid "Specify session management ID" +msgstr "Navodi IB upravnika sesije" -#~ msgid "Can't override GConf key, %s not found\n" -#~ msgstr "Ne mogu da prepišem GKonf ključ, %s nije pronađen\n" +#: src/core/main.c:207 +msgid "X Display to use" +msgstr "Iks ekran koji će biti korišćen" -#~ msgid "Error setting number of workspaces to %d: %s\n" -#~ msgstr "Greška prilikom postavljanja broja radnih površina na %d: %s\n" +#: src/core/main.c:213 +msgid "Initialize session from savefile" +msgstr "Pokreće sesiju iz datoteke čuvanja" -#~ msgid "Error setting name for workspace %d to \"%s\": %s\n" -#~ msgstr "Greška prilikom postavljanja naziva za radnu površ %d u „%s“: %s\n" +#: src/core/main.c:219 +msgid "Make X calls synchronous" +msgstr "Čini Iks pozive usklađenim" -#~ msgid "Error setting live hidden windows status status: %s\n" -#~ msgstr "Greška pri postavljanju stanja skrivenih prozora: %s\n" +#: src/core/main.c:226 +msgid "Run as a wayland compositor" +msgstr "Radi kao vajlandov sastavnik" -#~ msgid "Error setting no tab popup status: %s\n" -#~ msgstr "Greška pri postavljanju stanja bez iskačućih listova: %s\n" +#: src/core/main.c:232 +msgid "Run as a nested compositor" +msgstr "Radi kao ugneždeni sastavnik" -#~ msgid "" -#~ "Lost connection to the display '%s';\n" -#~ "most likely the X server was shut down or you killed/destroyed\n" -#~ "the window manager.\n" -#~ msgstr "" -#~ "Izgubio sam vezu sa ekranom „%s“;\n" -#~ "najverovatnije je da je Iks server ugašen ili da ste ubili\n" -#~ "menadžer prozora.\n" +#: src/core/main.c:240 +msgid "Run as a full display server, rather than nested" +msgstr "Radi kao puni server prikaza, umesto kao ugneždeni" -#~ msgid "Fatal IO error %d (%s) on display '%s'.\n" -#~ msgstr "Kobna greška sa izlazom/ulazom: %d (%s) na ekranu „%s“.\n" +#: src/core/main.c:246 +msgid "Run with X11 backend" +msgstr "Pokreni na Iks11 pozadincu" -#~ msgid "Turn compositing on" -#~ msgstr "Uključi kompoziciju" +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:147 +#, c-format +msgid "“%s” is not responding." +msgstr "„%s“ ne daje odziv." -#~ msgid "Turn compositing off" -#~ msgstr "Isključi kompoziciju" +#: src/core/meta-close-dialog-default.c:149 +msgid "Application is not responding." +msgstr "Program ne daje odziv." -#~ msgid "" -#~ "Don't make fullscreen windows that are maximized and have no decorations" -#~ msgstr "" -#~ "Ne postavljaj prozore preko celog ekrana ukoliko su uvećani i nemaju " -#~ "dekoraciju" +#: src/core/meta-close-dialog-default.c:154 +msgid "" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." +msgstr "" +"Možete malo sačekati dok se program ne sabere ili primorati program da " +"kompletno prekine sa radom." -#~ msgid "Whether window popup/frame should be shown when cycling windows." -#~ msgstr "Da li da prozor iskoči kada listate prozore." +#: src/core/meta-close-dialog-default.c:161 +msgid "_Force Quit" +msgstr "_Primoraj izlaz" -#~ msgid "Internal argument for GObject introspection" -#~ msgstr "Unutarnji argument inspekcije GObjekta" +#: src/core/meta-close-dialog-default.c:161 +msgid "_Wait" +msgstr "_Sačekaj" -#~ msgid "Failed to restart: %s\n" -#~ msgstr "Nisam uspeo da se ponovo pokrenem: %s\n" +#: src/core/mutter.c:39 +#, c-format +msgid "" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" +msgstr "" +"mater %s\n" +"Sva prava zadržana © 2001–%d Hevok Penington, Red Het, Ink., i ostali\n" +"Ovo je slobodan program; pogledajte izvorni kôd za uslove korišćenja.\n" +"NE postoji nikakva garancija; čak ni garancija o TRŽIŠNOJ VREDNOSTI ili " +"PRILAGOĐENOSTI ODREĐENOJ NAMENI.\n" -#~ msgid "Error setting compositor status: %s\n" -#~ msgstr "Greška pri postavljanju stanja kompozitora: %s\n" +#: src/core/mutter.c:53 +msgid "Print version" +msgstr "Ispisuje izdanje" -#~ msgid "Error setting clutter plugin list: %s\n" -#~ msgstr "Greška pri postavljanju spiska dodataka za klater: %s\n" +#: src/core/mutter.c:59 +msgid "Mutter plugin to use" +msgstr "Priključci Matera za korišćenje" -#~ msgid "Clutter Plugins" -#~ msgstr "Dodaci za Klater" +#: src/core/prefs.c:1997 +#, c-format +msgid "Workspace %d" +msgstr "%d. radni prostor" -#~ msgid "Plugins to load for the Clutter-based compositing manager." -#~ msgstr "Dodatak za učitavanje Klaterovih kompozitnih upravnika." +#: src/core/screen.c:583 +#, c-format +msgid "" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." +msgstr "" +"Prikaz „%s“ već ima upravnika prozora; probajte da koristite opciju „--" +"replace“ da zamenite trenutnog upravnika prozora." -#~ msgid "Window Management" -#~ msgstr "Upravljanje prozorima" +#: src/core/screen.c:668 +#, c-format +msgid "Screen %d on display “%s” is invalid\n" +msgstr "Prikaz „%d“ na ekranu „%s“ nije ispravan\n" -#~ msgid "Failed to parse message \"%s\" from dialog process\n" -#~ msgstr "Nisam uspeo da izdvojim poruku „%s“ iz prozorčeta procesa\n" +#: src/core/util.c:120 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mater je preveden bez podrške za opširan režim\n" -#~ msgid "Error reading from dialog display process: %s\n" -#~ msgstr "Greška prilikom čitanja iz prozorčeta procesa: %s\n" +#: src/wayland/meta-wayland-tablet-pad.c:567 +#, c-format +msgid "Mode Switch: Mode %d" +msgstr "Režim prekidača: Režim %d" -#~ msgid "" -#~ "Error launching metacity-dialog to ask about killing an application: %s\n" -#~ msgstr "" -#~ "Greška prilikom pokretanja metacity-dialog zbog upita o ubijanju programa „%" -#~ "s“\n" +#: src/x11/session.c:1818 +msgid "" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." +msgstr "" +"Ovi prozori ne podržavaju mogućnost „sačuvaj trenutna podešavanja“ pa ćete " +"morati ručno da ih ponovo pokrenete kada se sledeći put prijavite." -#~ msgid "Failed to get hostname: %s\n" -#~ msgstr "Nisam uspeo da saznam ime kompjutera: %s\n" +#: src/x11/window-props.c:559 +#, c-format +msgid "%s (on %s)" +msgstr "%s (na %s)" -#~ msgid "" -#~ "The format looks like \"<Control>a\" or <Shift><Alt>F1\".\n" -#~ "\n" -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Oblik zapisa je „<Control>a“ ili „<Shift><Alt>F1“.\n" -#~ "\n" -#~ "Program za obradu je dosta slobodan i dozvoljava velika ili mala slova, " -#~ "kao i skraćenice poput „<Ctl>“ ili „<Ctrl>“. Ukoliko postavite opciju na " -#~ "„disabled“, neće biti korišćena nijedna kombinacija tastera za ovu akciju." +#~ msgid "Move window one workspace to the left" +#~ msgstr "Premešta prozor jedan radni prostor na levo" -#~ msgid "" -#~ "The format looks like \"<Control>a\" or <Shift><Alt>F1\".\n" -#~ "\n" -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action.\n" -#~ "\n" -#~ "This keybinding may be reversed by holding down the \"shift\" key; " -#~ "therefore, \"shift\" cannot be one of the keys it uses." -#~ msgstr "" -#~ "Oblik zapisa je „<Control>“ ili „<Shift><Alt>F1“.\n" -#~ "\n" -#~ "Program za obradu je dosta slobodan i dozvoljava velika ili mala slova, " -#~ "kao i skraćenice poput „<Ctl>“ ili „<Ctrl>“. Ukoliko postavite opciju na " -#~ "„disabled“, neće biti korišćena nijedna kombinacija tastera za ovu akciju." +#~ msgid "Move window one workspace to the right" +#~ msgstr "Premešta prozor jedan radni prostor na desno" -#~ msgid "Failed to read saved session file %s: %s\n" -#~ msgstr "Nisam uspeo da pročitam sačuvanu datoteku sesije %s: %s\n" +#~ msgid "Move to workspace left" +#~ msgstr "Premešta na radni prostor levo" -#~ msgid "" -#~ "Error launching metacity-dialog to warn about apps that don't support " -#~ "session management: %s\n" -#~ msgstr "" -#~ "Greška prilikom pokretanja metacity-dialog radi upozorenja o programima " -#~ "koji ne podržavaju menadžer sesija: %s\n" +#~ msgid "Move to workspace right" +#~ msgstr "Premešta na radni prostor desno" -#~ msgid "Metacity" -#~ msgstr "Metasiti" +#~ msgid "Toggle shaded state" +#~ msgstr "Isključuje ili uključuje stanje zasenčenosti" -#~ msgid "" -#~ "(Not implemented) Navigation works in terms of applications not windows" -#~ msgstr "(Nije ugrađeno) Navigacija radi u kontekstu programa, ne i prozora" +#~ msgid "Failed to scan themes directory: %s\n" +#~ msgstr "Nisam uspeo da pročitam direktorijum tema: %s\n" #~ msgid "" -#~ "A font description string describing a font for window titlebars. The " -#~ "size from the description will only be used if the titlebar_font_size " -#~ "option is set to 0. Also, this option is disabled if the " -#~ "titlebar_uses_desktop_font option is set to true." +#~ "Could not find a theme! Be sure %s exists and contains the usual themes.\n" #~ msgstr "" -#~ "Niz karaktera koji opisuje slovni lik za naslovnu liniju prozora. " -#~ "Veličina iz opisa će biti korišćena samo ako je opcija titlebar_font_size " -#~ "podešena na 0. Takođe, ova opcija je isključena ako je " -#~ "opcijatitlebar_uses_desktop_font postavljena na „true“." +#~ "Ne mogu da pronađem temu! Proverite da „%s“ postoji i da sadrži " +#~ "uobičajene teme.\n" -#~ msgid "Action on title bar double-click" -#~ msgstr "Akcija za dupli klik na traku sa naslovom" +#~ msgid "Screen %d on display \"%s\" already has a window manager\n" +#~ msgstr "Prikaz %d na ekranu „%s“ već ima upravnika prozora\n" -#~ msgid "Action on title bar middle-click" -#~ msgstr "Akcija za srednji klik na traku sa naslovom" +#~ msgid "%d x %d" +#~ msgstr "%d x %d" -#~ msgid "Action on title bar right-click" -#~ msgstr "Akcija za desni klik na traku sa naslovom" +#~ msgid "top" +#~ msgstr "gornju" -#~ msgid "Arrangement of buttons on the titlebar" -#~ msgstr "Raspored dugmića na liniji sa naslovom" +#~ msgid "bottom" +#~ msgstr "donju" -#~ msgid "" -#~ "Arrangement of buttons on the titlebar. The value should be a string, " -#~ "such as \"menu:minimize,maximize,spacer,close\"; the colon separates the " -#~ "left corner of the window from the right corner, and the button names are " -#~ "comma-separated. Duplicate buttons are not allowed. Unknown button names " -#~ "are silently ignored so that buttons can be added in future metacity " -#~ "versions without breaking older versions. A special spacer tag can be " -#~ "used to insert some space between two adjacent buttons." -#~ msgstr "" -#~ "Raspored dugmića na naslovnoj liniji. Vrednost treba da bude niz " -#~ "karaktera, kao na primer „menu:minimize,maximize,close“; dve tačke " -#~ "razdvajaju levi ugao prozora od desnog, a dugmići su razdvojeni zapetama. " -#~ "Dupliranje dugmića nije dozvoljeno. Nepoznata imena dugmića se ignorišu " -#~ "tako da dugmići koji u budućnosti budu dodati u metasiti ne razbiju " -#~ "podešavanja starijih izdanja. Mogu se koristiti specijalne oznaka za " -#~ "razdvajanje kako bi se napravilo mesta između dva susedna dugmeta." - -#~ msgid "Automatically raises the focused window" -#~ msgstr "Automatski podigni prozor sa fokusom" - -#~ msgid "" -#~ "Clicking a window while holding down this modifier key will move the " -#~ "window (left click), resize the window (middle click), or show the window " -#~ "menu (right click). The left and right operations may be swapped using " -#~ "the \"mouse_button_resize\" key. Modifier is expressed as \"<Alt>\" " -#~ "or \"<Super>\" for example." -#~ msgstr "" -#~ "Klik na prozor za vreme držanja ovog tastera će premestiti prozor (levi " -#~ "klik), promeniti veličinu prozora (srednji klik) ili prikazati meni " -#~ "prozora (desni klik). Možete zameniti levi i desni taster miša pomoću " -#~ "ključa „mouse_button_resize“. Na primer, taster može biti „<Alt>“ " -#~ "ili „<Super>“." +#~ msgid "left" +#~ msgstr "levu" -#~ msgid "Commands to run in response to keybindings" -#~ msgstr "Komanda koju treba pokrenuti kao odgovor na pritisak tastera" +#~ msgid "right" +#~ msgstr "desnu" -#~ msgid "Compositing Manager" -#~ msgstr "Kompozitni upravnik" +#~ msgid "frame geometry does not specify \"%s\" dimension" +#~ msgstr "geometrija okvira ne podešava „%s“ dimenziju" -#~ msgid "Control how new windows get focus" -#~ msgstr "Kako novi prozor dobija fokus" +#~ msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" +#~ msgstr "geometrija okvira ne podešava „%s“ dimenziju za ivicu „%s“" -#~ msgid "Current theme" -#~ msgstr "Trenutna tema" +#~ msgid "Button aspect ratio %g is not reasonable" +#~ msgstr "Odnos razmere dugmeta %g nije razuman" -#~ msgid "Delay in milliseconds for the auto raise option" -#~ msgstr "Vremenski period u milisekundama za automatsko podizanje prozora" +#~ msgid "Frame geometry does not specify size of buttons" +#~ msgstr "Geometrija okvira ne podešava veličinu dugmića" -#~ msgid "Determines whether Metacity is a compositing manager." -#~ msgstr "Određuje da li je Metasiti kompozitni upravnik." +#~ msgid "Gradients should have at least two colors" +#~ msgstr "Prelivi moraju imati najmanje dve boje" #~ msgid "" -#~ "Determines whether applications or the system can generate audible " -#~ "'beeps'; may be used in conjunction with 'visual bell' to allow silent " -#~ "'beeps'." +#~ "GTK custom color specification must have color name and fallback in " +#~ "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" #~ msgstr "" -#~ "Određuje da li programi ili sistem mogu da puste zvučne signale; može se " -#~ "koristiti uz „vizuelne zvuke“ radi dozvoljavanja tihih zvukova." - -#~ msgid "Disable misfeatures that are required by old or broken applications" -#~ msgstr "Isključi loše mogućnosti koje su obavezne za stare ili loše programe" - -#~ msgid "Enable Visual Bell" -#~ msgstr "Omogući vizuelne zvuke" +#~ "Specifikacija proizvoljne GTK boje mora imati naziv boje i prebacivanje u " +#~ "zagradi, na primer gtk:custom(foo,bar); ne mogu da obradim „%s“" #~ msgid "" -#~ "If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " -#~ "the focused window will be automatically raised after a delay specified " -#~ "by the auto_raise_delay key. This is not related to clicking on a window " -#~ "to raise it, nor to entering a window during drag-and-drop." +#~ "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-" +#~ "z0-9-_ are valid" #~ msgstr "" -#~ "Ako je tačno, a način fokusa je ili „sloppy“ ili „mouse“ onda će prozor u " -#~ "fokusu biti automatski podignut nakon isteka vremenskog perioda (koji je " -#~ "podešen preko auto_raise_delay ključa). Ovo nije povezano sa podizanjem " -#~ "prozora klikom, niti sa fokusiranjem u toku povuci-i-ispusti." +#~ "Neispravan znak „%c“ parametra naziv_boje u gtk:custom, iaspravni su samo " +#~ "A-Za-z0-9-_" #~ msgid "" -#~ "If true, ignore the titlebar_font option, and use the standard " -#~ "application font for window titles." +#~ "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " +#~ "fit the format" #~ msgstr "" -#~ "Ako je tačno, ignoriše se opcija titlebar_font, i metasiti će koristiti " -#~ "standardan slovni lik programa za slovni lik naslova prozora." +#~ "Gtk:proizvoljni format je „gtk:custom(naziv_boje,prebacivanje)“, „%s“ se ne " +#~ "uklapa u format" #~ msgid "" -#~ "If true, metacity will give the user less feedback by using wireframes, " -#~ "avoiding animations, or other means. This is a significant reduction in " -#~ "usability for many users, but may allow legacy applications to continue " -#~ "working, and may also be a useful tradeoff for terminal servers. However, " -#~ "the wireframe feature is disabled when accessibility is on." +#~ "GTK color specification must have the state in brackets, e.g. gtk:" +#~ "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" #~ msgstr "" -#~ "Ako je postavljeno, Metasiti će korisniku prikazati manje podataka i manje " -#~ "osećaja o „neposrednom upravljanju“, upotrebom linija, izbegavanjem " -#~ "animacija ili drugim sredstvima. Ovo je značajni nedostatak po pitanju " -#~ "upotrebljivosti za mnoge korisnike, ali može omogućiti starim programima i " -#~ "terminalskim serverima da rade kada bi inače bili nepraktični. Takođe, " -#~ "upotreba linija je onemogućena kada je uključena pristupačnost." +#~ "Specifikacija GTK boje mora imati navedeno stanje u zagradi, na primer " +#~ "„gtk:fg[NORMAL]“ gde je „NORMAL“ stanje; ne mogu da obradim „%s“" #~ msgid "" -#~ "If true, then Metacity works in terms of applications rather than " -#~ "windows. The concept is a bit abstract, but in general an application-" -#~ "based setup is more like the Mac and less like Windows. When you focus a " -#~ "window in application-based mode, all the windows in the application will " -#~ "be raised. Also, in application-based mode, focus clicks are not passed " -#~ "through to windows in other applications. Application-based mode is, " -#~ "however, largely unimplemented at the moment." +#~ "GTK color specification must have a close bracket after the state, e.g. " +#~ "gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" #~ msgstr "" -#~ "Ako je tačno, metasiti rada u kontekstu programa, a ne prozora. Koncept " -#~ "je pomalo čudan, ali u opštem slučaju postavke bazirane na programu su " -#~ "više slične Mac sistemu, a manje slične Windows sistemu. Kada postavite " -#~ "prozor u fokus u ovom načinu rada, svi prozori te aplikacije će biti " -#~ "podignuti. Takođe, u ovom načinu rada, fokusni klik se ne šalje prozorima " -#~ "drugih programa. Takođe ovaj način rada je uveliko nedovršen u sadašnjim " -#~ "verzijama." - -#~ msgid "If true, trade off usability for less resource usage" -#~ msgstr "" -#~ "Ukoliko je postavljeno, žrtvuj upotrebljivost zarad upotrebe manje resursa" +#~ "Specifikacija GTK boje mora imati navedeno stanje u zagradi, na primer " +#~ "„gtk:fg[NORMAL]“ gde je „NORMAL“ stanje; ne mogu da obradim „%s“" -#~ msgid "Name of workspace" -#~ msgstr "Ime radnog prostora" +#~ msgid "Did not understand state \"%s\" in color specification" +#~ msgstr "Nisam razumeo stanje „%s“ u specifikaciji boje" -#~ msgid "Number of workspaces" -#~ msgstr "Broj radnih prostora" +#~ msgid "Did not understand color component \"%s\" in color specification" +#~ msgstr "Nisam razumeo deo boje „%s“ u specifikaciji boje" #~ msgid "" -#~ "Number of workspaces. Must be more than zero, and has a fixed maximum to " -#~ "prevent making the desktop unusable by accidentally asking for too many " -#~ "workspaces." +#~ "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit " +#~ "the format" #~ msgstr "" -#~ "Broj radnih prostora. Mora biti veći od nule, i imati fiksiran maksimum " -#~ "kako biste sprečili da slučajno uništite radnu površinu tražeći previše " -#~ "radnih prostora." +#~ "Format smeše je „blend/bg_color/fg_color/alpha“, „%s“ se ne uklapa u " +#~ "traženi format zapisa" -#~ msgid "Run a defined command" -#~ msgstr "Pokreni definisanu komandu" +#~ msgid "Could not parse alpha value \"%s\" in blended color" +#~ msgstr "Ne mogu da obradim alfa vrednost „%s“ u smešanoj boji" -#~ msgid "" -#~ "Set this to true to resize with the right button and show a menu with the " -#~ "middle button while holding down the key given in \"mouse_button_modifier" -#~ "\"; set it to false to make it work the opposite way around." -#~ msgstr "" -#~ "Postavite na „true“ za promenu veličine prozora desnim tasterom i prikaz " -#~ "menija srednjim tasterom uz držanje zadatog tastera preko ključa " -#~ "„mouse_button_modifier“. Postavite na „false“ kako bi koristili obrnut " -#~ "raspored tastera." +#~ msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" +#~ msgstr "Alfa vrednost „%s“ u smešanoj boji nije između 0.0 i 1.0" #~ msgid "" -#~ "Setting this option to false can lead to buggy behavior, so users are " -#~ "strongly discouraged from changing it from the default of true. Many " -#~ "actions (e.g. clicking in the client area, moving or resizing the window) " -#~ "normally raise the window as a side-effect. Setting this option to false, " -#~ "which is strongly discouraged, will decouple raising from other user " -#~ "actions, and ignore raise requests generated by applications. See http://" -#~ "bugzilla.gnome.org/show_bug.cgi?id=445447#c6. Even when this option is " -#~ "false, windows can still be raised by an alt-left-click anywhere on the " -#~ "window, a normal click on the window decorations, or by special messages " -#~ "from pagers, such as activation requests from tasklist applets. This " -#~ "option is currently disabled in click-to-focus mode. Note that the list " -#~ "of ways to raise windows when raise_on_click is false does not include " -#~ "programmatic requests from applications to raise windows; such requests " -#~ "will be ignored regardless of the reason for the request. If you are an " -#~ "application developer and have a user complaining that your application " -#~ "does not work with this setting disabled, tell them it is _their_ fault " -#~ "for breaking their window manager and that they need to change this " -#~ "option back to true or live with the \"bug\" they requested." +#~ "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the " +#~ "format" #~ msgstr "" -#~ "Postavljanje ove opcije na „false“ (netačno) može prouzrokovati neispravno " -#~ "ponašanje programa, pa nije preporučljivo. Mnoge naredbe (npr. klik usred " -#~ "oblasti klijenta, pomeranje ili promena veličine prozora) obično ujedno i " -#~ "podižu prozor. Isključivanjem ove opcije će razdvojiti podizanje prozora od " -#~ "ostalih radnji i zanemariti zahteve za podizanje prozora od strane " -#~ "programa. Pogledajte http://bugzilla.gnome.org/show_bug.cgi?id=445447#c6. " -#~ "Čak i ukoliko isključite ovu opciju, prozore možete podići levim klikom " -#~ "unutar prozora uz držanje tastera Alt, običnim klikom na naslovnu liniju " -#~ "prozora ili preko posebnih poruka iz prebacivača radnih površina (kao što " -#~ "je uključivanje zahteva iz programčeta sa spiskom zadataka). Ova opcija je " -#~ "trenutno isključena u režimu „click-to-focus“ (klik za fokus). Spisak " -#~ "načina za podizanje prozora kada je „raise_on_click“ (podigni na klik) " -#~ "postavljen na „false“ (netačno) ne uključuje zahteve iz programa za " -#~ "podizanje prozora, pa će takvi zahtevi biti zanemareni bez obzira na na " -#~ "razlog. Ukoliko pišete sopstveni program i dobijete primedbe od strane " -#~ "korisnika kako vaš program ne radi po isključivanju ove opcije, kažite im " -#~ "da je njihova krivica za neispravan rad upravnika prozorima i da vrate " -#~ "opciju na „true“ (tačno) ili da se naviknu na propratne pojave." +#~ "Format senke je „shade/base_color/factor“, „%s“ se ne uklapa u format" -#~ msgid "" -#~ "Some applications disregard specifications in ways that result in window " -#~ "manager misfeatures. This option puts Metacity in a rigorously correct " -#~ "mode, which gives a more consistent user interface, provided one does not " -#~ "need to run any misbehaving applications." -#~ msgstr "" -#~ "Neki programi ne poštuju specifikacije na način koji vodi do toga da " -#~ "upravnik prozora ne može da funkcioniše. Ovo podešavanje postavlja Metasiti " -#~ "u strog režim rada koji doprinosi pravilnijem ponašanju, pod uslovom da se " -#~ "ne pokušava pokretanje neispravnih programa." +#~ msgid "Could not parse shade factor \"%s\" in shaded color" +#~ msgstr "Ne mogu da obradim faktor senke „%s“ u osenčenoj boji" -#~ msgid "System Bell is Audible" -#~ msgstr "Sistemsko zvonce se čuje" +#~ msgid "Shade factor \"%s\" in shaded color is negative" +#~ msgstr "Faktor senke „%s“ u osenčenoj boji je negativan" -#~ msgid "" -#~ "Tells Metacity how to implement the visual indication that the system " -#~ "bell or another application 'bell' indicator has been rung. Currently " -#~ "there are two valid values, \"fullscreen\", which causes a fullscreen " -#~ "white-black flash, and \"frame_flash\" which causes the titlebar of the " -#~ "application which sent the bell signal to flash. If the application which " -#~ "sent the bell is unknown (as is usually the case for the default \"system " -#~ "beep\"), the currently focused window's titlebar is flashed." -#~ msgstr "" -#~ "Naređuje Metasitiju da prikaže nešto kada zazvoni sistemsko zvonce ili " -#~ "neki drugi program zazvoni. Trenutno su moguće dve vrednosti, " -#~ "„fullscreen“ kojim ceo ekran treperi crno-belo, i „frame_flash“ kada " -#~ "treperi samo naslovna linija prozora koji je zazvonio. Ukoliko nije " -#~ "poznat program koji je zazvonio (kao što je to obično slučaj sa " -#~ "„sistemskim zvoncetom“), trepereće naslovna linija prozora koji je " -#~ "trenutno u žiži." +#~ msgid "Could not parse color \"%s\"" +#~ msgstr "Ne mogu da obradim boju „%s“" -#~ msgid "" -#~ "The /apps/metacity/global_keybindings/run_command_N keys define " -#~ "keybindings that correspond to these commands. Pressing the keybinding " -#~ "for run_command_N will execute command_N." -#~ msgstr "" -#~ "Ključ /apps/metacity/global_keybindings/run_command_N definiše tastere " -#~ "koji odgovaraju ovim komandama. Pritiskom kombinacije tastera za " -#~ "pokreni_komadu_N će izvršiti komandu_N." +#~ msgid "Coordinate expression contains character '%s' which is not allowed" +#~ msgstr "Izraz koordinata sadrži znak „%s“ koji nije dozvoljen" #~ msgid "" -#~ "The /apps/metacity/global_keybindings/run_command_screenshot key defines " -#~ "a keybinding which causes the command specified by this setting to be " -#~ "invoked." +#~ "Coordinate expression contains floating point number '%s' which could not " +#~ "be parsed" #~ msgstr "" -#~ "Ključ /apps/metacity/global_keybindings/run_command_N definiše funkciju " -#~ "tastera kojim se pokreće naredba navedena pomoću njega." +#~ "Izraz koordinata sadrži decimalni broj „%s“ koji ne može biti obrađen" #~ msgid "" -#~ "The /apps/metacity/global_keybindings/run_command_window_screenshot key " -#~ "defines a keybinding which causes the command specified by this setting " -#~ "to be invoked." -#~ msgstr "" -#~ "Ključ /apps/metacity/global_keybindings/run_command_window_screenshot " -#~ "definiše funkciju tastera kojim se pokreće naredba navedena pomoću njega." +#~ "Coordinate expression contains integer '%s' which could not be parsed" +#~ msgstr "Izraz koordinata sadrži celi broj „%s“ koji ne može biti obrađen" -# bug: missing dot (.) after keybinding_commands? #~ msgid "" -#~ "The keybinding that runs the correspondingly-numbered command in /apps/" -#~ "metacity/keybinding_commands The format looks like \"<Control>a\" " -#~ "or \"<Shift><Alt>F1\". The parser is fairly liberal and " -#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" -#~ "\" and \"<Ctrl>\". If you set the option to the special string " -#~ "\"disabled\", then there will be no keybinding for this action." +#~ "Coordinate expression contained unknown operator at the start of this " +#~ "text: \"%s\"" #~ msgstr "" -#~ "Kombinacije tastera koji pokreću odgovarajuće označenu komandu u /apps/" -#~ "metacity/keybinding_commands ključu. Oblik zapisa je „<Control>a“ " -#~ "ili „<Shift><Alt>F1“. Program za obradu je dosta slobodan i " -#~ "dozvoljava velika ili mala slova, kao i skraćenice poput „<Ctl>“ ili " -#~ "„< Ctrl>“. Ako podesite opciju na naročiti niz znakova „disabled“, " -#~ "onda neće biti korišćena nijedna kombinacija tastera za ovu akciju." +#~ "Izraz sa koordinatama sadrži nepoznati operator na početku ovog teksta: " +#~ "„%s“" -#~ msgid "The name of a workspace." -#~ msgstr "Ime radne površine." +#~ msgid "Coordinate expression was empty or not understood" +#~ msgstr "Izraz sa koordinatama je bio prazan ili nerazumljiv" -#~ msgid "The screenshot command" -#~ msgstr "Naredba za snimak ekrana" +#~ msgid "Coordinate expression results in division by zero" +#~ msgstr "Izraz sa koordinatama rezultira u deljenju nulom" #~ msgid "" -#~ "The theme determines the appearance of window borders, titlebar, and so " -#~ "forth." +#~ "Coordinate expression tries to use mod operator on a floating-point number" #~ msgstr "" -#~ "Tema utvrđuje izgled ivica prozora, naslovne linije i svega ostalog " -#~ "sličnog." +#~ "Izraz sa koordinatam pokušava da koristi operator ostatka pri deljenju za " +#~ "decimalni broj" #~ msgid "" -#~ "The time delay before raising a window if auto_raise is set to true. The " -#~ "delay is given in thousandths of a second." -#~ msgstr "" -#~ "Vremenski period pre podizanja prozora ako je opcija auto_raise postavljena " -#~ "na „true“. Period se izražava u hiljaditim delovima sekunde." +#~ "Coordinate expression has an operator \"%s\" where an operand was expected" +#~ msgstr "Izraz sa koordinatama ima operator „%s“ gde je očekivan operand" -#~ msgid "" -#~ "The window focus mode indicates how windows are activated. It has three " -#~ "possible values; \"click\" means windows must be clicked in order to " -#~ "focus them, \"sloppy\" means windows are focused when the mouse enters " -#~ "the window, and \"mouse\" means windows are focused when the mouse enters " -#~ "the window and unfocused when the mouse leaves the window." -#~ msgstr "" -#~ "Fokus prozora podešava kako će prozori biti aktivirani. Ima tri moguće " -#~ "vrednosti „click“ znači da prozor mora biti selektovan da bi dobio fokus, " -#~ "„sloppy“ znači da prozor dobija fokus kada pokazivač miša uđe u prozor i " -#~ "„mouse“ štp znači da će prozor biti fokusitan kada pokazivačka strelica " -#~ "miša uđe u prozor i biti defokusiran kada strelica izađe iz prozora." +#~ msgid "Coordinate expression had an operand where an operator was expected" +#~ msgstr "Izraz sa koordinatama imaše operand gde je očekivan operator" -#~ msgid "The window screenshot command" -#~ msgstr "Naredba za uzimanje snimka prozora" +#~ msgid "Coordinate expression ended with an operator instead of an operand" +#~ msgstr "Izraz sa koordinarama je završio sa operatorom umesto sa operandom" #~ msgid "" -#~ "This option determines the effects of double-clicking on the title bar. " -#~ "Current valid options are 'toggle_shade', which will shade/unshade the " -#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " -#~ "will maximize/unmaximize the window in that direction only, 'minimize' " -#~ "which will minimize the window, 'shade' which will roll the window up, " -#~ "'menu' which will display the window menu, 'lower' which will put the " -#~ "window behind all the others, and 'none' which will not do anything." +#~ "Coordinate expression has operator \"%c\" following operator \"%c\" with " +#~ "no operand in between" #~ msgstr "" -#~ "Ova mogućnost određuje efekat duplog klika na naslovnu liniju prozora. " -#~ "Trenutno ispravni su „toggle_shade“ što će zamotati/odmotati prozor, " -#~ "„toggle_maximize“ što će uvećati ili poništiti uvećanje prozora, " -#~ "„toggle_maximize_horizontally“ i „toggle_maximize_vertically“, što će " -#~ "uvećati ili poništiti uvećanje prozora samo u horizontalno ili uspravno, " -#~ "„minimize“ što će umanjiti prozor, „shade“ što će zamotat prozor, „menu“ " -#~ "što će prikazati meni prozora, „lower“ što će postaviti prozor iza " -#~ "ostalih i „none“ čime se ne obavlja nikakva radnja." +#~ "Izraz sa koordinatama ima operator „%c“, a zatim operator „%c“ bez " +#~ "operanda između" -#~ msgid "" -#~ "This option determines the effects of middle-clicking on the title bar. " -#~ "Current valid options are 'toggle_shade', which will shade/unshade the " -#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " -#~ "will maximize/unmaximize the window in that direction only, 'minimize' " -#~ "which will minimize the window, 'shade' which will roll the window up, " -#~ "'menu' which will display the window menu, 'lower' which will put the " -#~ "window behind all the others, and 'none' which will not do anything." -#~ msgstr "" -#~ "Ova mogućnost određuje efekat srednjeg klika na naslovnu liniju prozora. " -#~ "Trenutno ispravni su „toggle_shade“ što će zamotati/odmotati prozor, " -#~ "„toggle_maximize“ što će uvećati ili poništiti uvećanje prozora, " -#~ "„toggle_maximize_horizontally“ i „toggle_maximize_vertically“, što će " -#~ "uvećati ili poništiti uvećanje prozora samo u horizontalno ili uspravno, " -#~ "„minimize“ što će umanjiti prozor, „shade“ što će zamotat prozor, „menu“ " -#~ "što će prikazati meni prozora, „lower“ što će postaviti prozor iza " -#~ "ostalih i „none“ čime se ne obavlja nikakva radnja." +#~ msgid "Coordinate expression had unknown variable or constant \"%s\"" +#~ msgstr "Izraz sa koordinatama ima nepoznatu promenljivu ili konstanti „%s“" -#~ msgid "" -#~ "This option determines the effects of right-clicking on the title bar. " -#~ "Current valid options are 'toggle_shade', which will shade/unshade the " -#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " -#~ "will maximize/unmaximize the window in that direction only, 'minimize' " -#~ "which will minimize the window, 'shade' which will roll the window up, " -#~ "'menu' which will display the window menu, 'lower' which will put the " -#~ "window behind all the others, and 'none' which will not do anything." -#~ msgstr "" -#~ "Ova mogućnost određuje efekat desnog klika na naslovnu liniju prozora. " -#~ "Trenutno ispravni su „toggle_shade“ što će zamotati/odmotati prozor, " -#~ "„toggle_maximize“ što će uvećati ili poništiti uvećanje prozora, " -#~ "„toggle_maximize_horizontally“ i „toggle_maximize_vertically“, što će " -#~ "uvećati ili poništiti uvećanje prozora samo u horizontalno ili uspravno, " -#~ "„minimize“ što će umanjiti prozor, „shade“ što će zamotat prozor, „menu“ " -#~ "što će prikazati meni prozora, „lower“ što će postaviti prozor iza " -#~ "ostalih i „none“ čime se ne obavlja nikakva radnja." +#~ msgid "Coordinate expression parser overflowed its buffer." +#~ msgstr "Izraz sa koordinatama je bio preveliki za smeštaj i obradu." #~ msgid "" -#~ "This option provides additional control over how newly created windows " -#~ "get focus. It has two possible values; \"smart\" applies the user's " -#~ "normal focus mode, and \"strict\" results in windows started from a " -#~ "terminal not being given focus." -#~ msgstr "" -#~ "Ova opcija pruža dodatnu kontrolu nad načinom na koji novi prozori ulaze " -#~ "u fokus. Ima dve moguće vrednosti: „smart“ postavlja normalni režim fokusa " -#~ "i „strict“ kada prozori pokrenuti iz komandne linije ne ulaze u fokus." +#~ "Coordinate expression had a close parenthesis with no open parenthesis" +#~ msgstr "Izraz sa koordinatama ima zatvorene zagrade bez otvorenih zagrada" #~ msgid "" -#~ "Turns on a visual indication when an application or the system issues a " -#~ "'bell' or 'beep'; useful for the hard-of-hearing and for use in noisy " -#~ "environments." -#~ msgstr "" -#~ "Uključuje vizuelni prikaz kada program ili sistem „zazvoni“; korisno u " -#~ "bučnim uslovima." +#~ "Coordinate expression had an open parenthesis with no close parenthesis" +#~ msgstr "Izraz sa koordinatama ima otvorenu zagradu bez zatvorene zagrade" -#~ msgid "Use standard system font in window titles" -#~ msgstr "Koristi standardni sistemski slovni lik za naslov prozora" +#~ msgid "Coordinate expression doesn't seem to have any operators or operands" +#~ msgstr "Izraz sa koordinatama izgleda da nema ni jedan operator ili operand" -#~ msgid "Visual Bell Type" -#~ msgstr "Vrsta vizelnog zvonceta" +#~ msgid "Theme contained an expression that resulted in an error: %s\n" +#~ msgstr "Tema sadrži izraz koji rezultira greškom: %s\n" -#~ msgid "Whether raising should be a side-effect of other user interactions" +#~ msgid "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " +#~ "specified for this frame style" #~ msgstr "" -#~ "Da li podizanje prozora treba da bude bočni efekat nekih drugih " -#~ "korisnikovih radnji" - -#~ msgid "Whether to resize with the right button" -#~ msgstr "Da li da promeni veličinu desnim tasterom" - -#~ msgid "Window focus mode" -#~ msgstr "Način fokusa prozora" - -#~ msgid "Window title font" -#~ msgstr "Slovni lik naslova prozora" - -#~ msgid "Title" -#~ msgstr "Naslov" - -#~ msgid "Class" -#~ msgstr "Klasa" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> mora biti " +#~ "naveden za ovaj stil okvira" #~ msgid "" -#~ "There was an error running \"%s\":\n" -#~ "%s." +#~ "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/" +#~ ">" #~ msgstr "" -#~ "Dogodila se greška prilikom pokretanja „%s“:\n" -#~ "%s." - -#, fuzzy -#~ msgid "<name> specified twice for this theme" -#~ msgstr "Element <date> je naveden dva puta u ovoj temi" +#~ "Nedostaje <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever" +#~ "\"/>" -#~ msgid "<author> specified twice for this theme" -#~ msgstr "Element <author> je naveden dva puta u ovoj temi" +#~ msgid "Failed to load theme \"%s\": %s\n" +#~ msgstr "Nisam uspeo da učitam temu „%s“: %s\n" -#~ msgid "<copyright> specified twice for this theme" -#~ msgstr "Element <copyright> je naveden dva puta u ovoj temi" +#~ msgid "No <%s> set for theme \"%s\"" +#~ msgstr "Nije definisan element <%s> za temu „%s“" -#~ msgid "<date> specified twice for this theme" -#~ msgstr "Element <date> je naveden dva puta u ovoj temi" - -#~ msgid "<description> specified twice for this theme" -#~ msgstr "Element <description> je naveden dva puta u ovoj temi" +#~ msgid "" +#~ "No frame style set for window type \"%s\" in theme \"%s\", add a <window " +#~ "type=\"%s\" style_set=\"whatever\"/> element" +#~ msgstr "" +#~ "Nije podešen stil okvira za prozor tipa „%s“ u temi „%s“. Dodajte element " +#~ "<window type=\"%s\" style_set=\"whatever\"/>" -#~ msgid "Theme file %s did not contain a root <metacity_theme> element" -#~ msgstr "Datoteka sa temom %s ne sadrži korenski <metacity_theme> element" +#~ msgid "" +#~ "User-defined constants must begin with a capital letter; \"%s\" does not" +#~ msgstr "" +#~ "Korisnički definisane konstante moraju početi velikim slovom; „%s“ ne " +#~ "počinje" -#~ msgid "/Windows/tearoff" -#~ msgstr "/Prozori/otkini" +#~ msgid "Constant \"%s\" has already been defined" +#~ msgstr "Konstanta „%s“ je već definisana" -#~ msgid "/Windows/_Dialog" -#~ msgstr "/Prozori/_Prozorče" +#~ msgid "No \"%s\" attribute on element <%s>" +#~ msgstr "Nije definisan „%s“ atribut u elementu <%s>" -#~ msgid "/Windows/_Modal dialog" -#~ msgstr "/Prozori/_Važno prozorče" +#~ msgid "Line %d character %d: %s" +#~ msgstr "Red %d, znak %d: %s" -#~ msgid "/Windows/Des_ktop" -#~ msgstr "/Prozori/Rad_na površina" +#~ msgid "Attribute \"%s\" repeated twice on the same <%s> element" +#~ msgstr "Atribut „%s“ je ponovljen dva puta u istom <%s> elementu" -#, fuzzy -#~ msgid "%s (as %s)" -#~ msgstr "%s (na %s)" +#~ msgid "Attribute \"%s\" is invalid on <%s> element in this context" +#~ msgstr "Atribut „%s“ je neispravan u elementu <%s> u ovom kontekstu" -#~ msgid "" -#~ "Error launching metacity-dialog to print an error about a command: %s\n" -#~ msgstr "" -#~ "Greška prilikom pokretanja metacity-dialog programa zbog štampanja greške o " -#~ "komandi: %s\n" +#~ msgid "Could not parse \"%s\" as an integer" +#~ msgstr "Ne mogu da obradim „%s“ kao ceo broj" -#~ msgid "Unknown attribute %s on <metacity_session> element" -#~ msgstr "Nepoznat atribut %s u <metacity_session> elementu" +#~ msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +#~ msgstr "Nisam razumeo vodeće znake „%s“ u nizu znakova „%s“" -#~ msgid "Unknown attribute %s on <maximized> element" -#~ msgstr "Nepoznat atribut %s u <maximized> elementu" +#~ msgid "Integer %ld must be positive" +#~ msgstr "Ceo broj %ld mora biti pozitivan" -#~ msgid "Unknown attribute %s on <geometry> element" -#~ msgstr "Nepoznat atribut %s u <geometry> elementu" +#~ msgid "Integer %ld is too large, current max is %d" +#~ msgstr "Ceo broj %ld je prevelik, trenutni najveći je %d" -#~ msgid "" -#~ "Many actions (e.g. clicking in the client area, moving or resizing the " -#~ "window) normally raise the window as a side-effect. Setting this option " -#~ "to false, which is strongly discouraged, will decouple raising from other " -#~ "user actions, and ignore raise requests generated by applications. See " -#~ "http://bugzilla.gnome.org/show_bug.cgi?id=445447#c6." -#~ msgstr "" -#~ "Mnoge radnje (npr. pritisak na prostor programa, premeštanje ili menjanje " -#~ "veličine prozora) uobičajeno, kao sporedni efekat, podižu prozor. " -#~ "Postavljanje ovog prekidača na istinitosnu vrednost „false“, što je krajnje " -#~ "nepreporučljivo, će razdvojiti podizanje prozora od ostalih naredbi " -#~ "korisnika i zanemariti zahteve za podizanje od strane programa. Vidite See " -#~ "http://bugzilla.gnome.org/show_bug.cgi?id=445447#c6 za više detalja." +#~ msgid "Could not parse \"%s\" as a floating point number" +#~ msgstr "Ne mogu da obradim „%s“ kao decimalni broj" -#~ msgid "" -#~ "The keybinding that switches to the workspace above the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Kombinacija tastera koja prebacuje na radni prostor iznad tekućeg. Oblik " -#~ "zapisa je „<Control>a“ ili „<Shift><Alt>F1“. Program za " -#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, kao i " -#~ "skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako podesite opciju " -#~ "na naročiti niz znakova „disabled“, onda neće biti korišćena nijedna " -#~ "kombinacija tastera za ovu akciju." +#~ msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" +#~ msgstr "Logičke vrednosti moraju biti „true“ ili „false“, a ne „%s“" -#~ msgid "" -#~ "The keybinding that switches to the workspace below the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Kombinacija tastera koja prebacuje na radni prostor ispod tekućeg. Oblik " -#~ "zapisa je „<Control>a“ ili „<Shift><Alt>F1“. Program za " -#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, kao i " -#~ "skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako podesite opciju " -#~ "na naročiti niz znakova „disabled“, onda neće biti korišćena nijedna " -#~ "kombinacija tastera za ovu akciju." +#~ msgid "Angle must be between 0.0 and 360.0, was %g\n" +#~ msgstr "Ugao mora biti između 0.0 i 360.0, bio je %g\n" #~ msgid "" -#~ "The keybinding that switches to the workspace on the left of the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." +#~ "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" #~ msgstr "" -#~ "Kombinacija tastera koja prebacuje na radni prostor levo od tekućeg. " -#~ "Oblik zapisa je „<Control>a“ ili „<Shift><Alt>F1“. " -#~ "Program za obradu je dosta slobodan i dozvoljava velika ili mala slova, " -#~ "kao i skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako podesite " -#~ "opciju na naročiti niz znakova „disabled“, onda neće biti korišćena " -#~ "nijedna kombinacija tastera za ovu akciju." +#~ "Alfa stepen mora biti između 0.0 (nevidljivo) i 1.0 (potpuno vidljivo), bio " +#~ "je %g\n" #~ msgid "" -#~ "The keybinding that switches to the workspace on the right of the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." +#~ "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," +#~ "large,x-large,xx-large)\n" #~ msgstr "" -#~ "Kombinacija tastera koja prebacuje na radni prostor desno od tekućeg. " -#~ "Oblik zapisa je „<Control>a“ ili „<Shift><Alt>F1“. " -#~ "Program za obradu je dosta slobodan i dozvoljava velika ili mala slova, " -#~ "kao i skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako podesite " -#~ "opciju na naročiti niz znakova „disabled“, onda neće biti korišćena " -#~ "nijedna kombinacija tastera za ovu akciju." +#~ "Netačno skaliranje naslova „%s“ (mora biti jedan od sledećih: xx-small,x-" +#~ "small,small,medium,large,x-large,xx-large)\n" -#~ msgid "" -#~ "The keybinding that switches to workspace 1. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Kombinacija tastera koja prebacuje na radni prostor broj 1. Oblik zapisa " -#~ "je „<Control>a“ ili „<Shift><Alt>F1“. Program za obradu " -#~ "je dosta slobodan i dozvoljava velika ili mala slova, kao i skraćenice " -#~ "poput „<Ctl>“ ili „< Ctrl>“. Ako podesite opciju na naročiti " -#~ "niz znakova „disabled“, onda neće biti korišćena nijedna kombinacija " -#~ "tastera za ovu akciju." +#~ msgid "<%s> name \"%s\" used a second time" +#~ msgstr "<%s> naziv „%s“ je korišćen po drugi put" -#~ msgid "" -#~ "The keybinding that switches to workspace 10. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Kombinacija tastera koja prebacuje na radni prostor broj 10. Oblik zapisa " -#~ "je „<Control>a“ ili „<Shift><Alt>F1“. Program za obradu " -#~ "je dosta slobodan i dozvoljava velika ili mala slova, kao i skraćenice " -#~ "poput „<Ctl>“ ili „< Ctrl>“. Ako podesite opciju na naročiti " -#~ "niz znakova „disabled“, onda neće biti korišćena nijedna kombinacija " -#~ "tastera za ovu akciju." +#~ msgid "<%s> parent \"%s\" has not been defined" +#~ msgstr "<%s> matični „%s“ nije određen" -#~ msgid "" -#~ "The keybinding that switches to workspace 11. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Kombinacija tastera koja prebacuje na radni prostor broj 11. Oblik zapisa " -#~ "je „<Control>a“ ili „<Shift><Alt>F1“. Program za obradu " -#~ "je dosta slobodan i dozvoljava velika ili mala slova, kao i skraćenice " -#~ "poput „<Ctl>“ ili „< Ctrl>“. Ako podesite opciju na naročiti " -#~ "niz znakova „disabled“, onda neće biti korišćena nijedna kombinacija " -#~ "tastera za ovu akciju." +#~ msgid "<%s> geometry \"%s\" has not been defined" +#~ msgstr "<%s> geometrija „%s“ nije definisana" -#~ msgid "" -#~ "The keybinding that switches to workspace 12. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ msgid "<%s> must specify either a geometry or a parent that has a geometry" #~ msgstr "" -#~ "Kombinacija tastera koja prebacuje na radni prostor broj 12. Oblik zapisa " -#~ "je „<Control>a“ ili „<Shift><Alt>F1“. Program za obradu " -#~ "je dosta slobodan i dozvoljava velika ili mala slova, kao i skraćenice " -#~ "poput „<Ctl>“ ili „< Ctrl>“. Ako podesite opciju na naročiti " -#~ "niz znakova „disabled“, onda neće biti korišćena nijedna kombinacija " -#~ "tastera za ovu akciju." +#~ "<%s> mora biti navedena ili geometrija ili matični element koji ima " +#~ "geometriju" -#~ msgid "" -#~ "The keybinding that switches to workspace 2. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Kombinacija tastera koja prebacuje na radni prostor broj 2. Oblik zapisa " -#~ "je „<Control>a“ ili „<Shift><Alt>F1“. Program za obradu " -#~ "je dosta slobodan i dozvoljava velika ili mala slova, kao i skraćenice " -#~ "poput „<Ctl>“ ili „< Ctrl>“. Ako podesite opciju na naročiti " -#~ "niz znakova „disabled“, onda neće biti korišćena nijedna kombinacija " -#~ "tastera za ovu akciju." +#~ msgid "You must specify a background for an alpha value to be meaningful" +#~ msgstr "Morate navesti pozadinu da bi alfa vrednost imala smisla" -#~ msgid "" -#~ "The keybinding that switches to workspace 3. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Kombinacija tastera koja prebacuje na radni prostor broj 3. Oblik zapisa " -#~ "je „<Control>a“ ili „<Shift><Alt>F1“. Program za obradu " -#~ "je dosta slobodan i dozvoljava velika ili mala slova, kao i skraćenice " -#~ "poput „<Ctl>“ ili „< Ctrl>“. Ako podesite opciju na naročiti " -#~ "niz znakova „disabled“, onda neće biti korišćena nijedna kombinacija " -#~ "tastera za ovu akciju." +#~ msgid "Unknown type \"%s\" on <%s> element" +#~ msgstr "Nepoznat tip „%s“ u elementu <%s>" -#~ msgid "" -#~ "The keybinding that switches to workspace 4. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Kombinacija tastera koja prebacuje na radni prostor broj 4. Oblik zapisa " -#~ "je „<Control>a“ ili „<Shift><Alt>F1“. Program za obradu " -#~ "je dosta slobodan i dozvoljava velika ili mala slova, kao i skraćenice " -#~ "poput „<Ctl>“ ili „< Ctrl>“. Ako podesite opciju na naročiti " -#~ "niz znakova „disabled“, onda neće biti korišćena nijedna kombinacija " -#~ "tastera za ovu akciju." +#~ msgid "Unknown style_set \"%s\" on <%s> element" +#~ msgstr "Nepoznat „style_set“ „%s“ u elementu <%s>" -#~ msgid "" -#~ "The keybinding that switches to workspace 5. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Kombinacija tastera koja prebacuje na radni prostor broj 5. Oblik zapisa " -#~ "je „<Control>a“ ili „<Shift><Alt>F1“. Program za obradu " -#~ "je dosta slobodan i dozvoljava velika ili mala slova, kao i skraćenice " -#~ "poput „<Ctl>“ ili „< Ctrl>“. Ako podesite opciju na naročiti " -#~ "niz znakova „disabled“, onda neće biti korišćena nijedna kombinacija " -#~ "tastera za ovu akciju." +#~ msgid "Window type \"%s\" has already been assigned a style set" +#~ msgstr "Tipu prozora „%s“ je već dodeljen skup stila" -#~ msgid "" -#~ "The keybinding that switches to workspace 6. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Kombinacija tastera koja prebacuje na radni prostor broj 6. Oblik zapisa " -#~ "je „<Control>a“ ili „<Shift><Alt>F1“. Program za obradu " -#~ "je dosta slobodan i dozvoljava velika ili mala slova, kao i skraćenice " -#~ "poput „<Ctl>“ ili „< Ctrl>“. Ako podesite opciju na naročiti " -#~ "niz znakova „disabled“, onda neće biti korišćena nijedna kombinacija " -#~ "tastera za ovu akciju." +#~ msgid "Element <%s> is not allowed below <%s>" +#~ msgstr "Element <%s> nije dozvoljen ispod <%s>" #~ msgid "" -#~ "The keybinding that switches to workspace 7. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Kombinacija tastera koja prebacuje na radni prostor broj 7. Oblik zapisa " -#~ "je „<Control>a“ ili „<Shift><Alt>F1“. Program za obradu " -#~ "je dosta slobodan i dozvoljava velika ili mala slova, kao i skraćenice " -#~ "poput „<Ctl>“ ili „< Ctrl>“. Ako podesite opciju na naročiti " -#~ "niz znakova „disabled“, onda neće biti korišćena nijedna kombinacija " -#~ "tastera za ovu akciju." +#~ "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio" +#~ "\" for buttons" +#~ msgstr "Ne mogu da podesim i širinu/visinu i razmeru dugmadi" -#~ msgid "" -#~ "The keybinding that switches to workspace 8. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Kombinacija tastera koja prebacuje na radni prostor broj 8. Oblik zapisa " -#~ "je „<Control>a“ ili „<Shift><Alt>F1“. Program za obradu " -#~ "je dosta slobodan i dozvoljava velika ili mala slova, kao i skraćenice " -#~ "poput „<Ctl>“ ili „< Ctrl>“. Ako podesite opciju na naročiti " -#~ "niz znakova „disabled“, onda neće biti korišćena nijedna kombinacija " -#~ "tastera za ovu akciju." +#~ msgid "Distance \"%s\" is unknown" +#~ msgstr "Udaljenost „%s“ je nepoznata" -#~ msgid "" -#~ "The keybinding that switches to workspace 9. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Kombinacija tastera koja prebacuje na radni prostor broj 9. Oblik zapisa " -#~ "je „<Control>a“ ili „<Shift><Alt>F1“. Program za obradu " -#~ "je dosta slobodan i dozvoljava velika ili mala slova, kao i skraćenice " -#~ "poput „<Ctl>“ ili „< Ctrl>“. Ako podesite opciju na naročiti " -#~ "niz znakova „disabled“, onda neće biti korišćena nijedna kombinacija " -#~ "tastera za ovu akciju." +#~ msgid "Aspect ratio \"%s\" is unknown" +#~ msgstr "Odnos razmere „%s je nepoznat" -#~ msgid "" -#~ "The keybinding used to activate the window menu. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Kombinacija tastera za prikazivanje menija prozora. Oblik zapisa je „<" -#~ "Control>a“ ili „<Shift><Alt>F1“. Program za obradu je " -#~ "dosta slobodan i dozvoljava velika ili mala slova, kao i skraćenice poput " -#~ "„<Ctl>“ ili „< Ctrl>“. Ako podesite opciju na naročiti niz " -#~ "znakova „disabled“, onda neće biti korišćena nijedna kombinacija tastera " -#~ "za ovu akciju." +#~ msgid "Border \"%s\" is unknown" +#~ msgstr "Ivica „%s“ je nepoznata" -#~ msgid "" -#~ "The keybinding used to enter \"move mode\" and begin moving a window " -#~ "using the keyboard. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." +#~ msgid "No \"start_angle\" or \"from\" attribute on element <%s>" #~ msgstr "" -#~ "Kombinacija tastera za ulazak u „režim premeštanja“ ili za početak " -#~ "premeštanja prozora pomoću tastature. Oblik zapisa je „<Control>a“ " -#~ "ili „<Shift><Alt>F1“. Program za obradu je dosta slobodan i " -#~ "dozvoljava velika ili mala slova, kao i skraćenice poput „<Ctl>“ ili " -#~ "„< Ctrl>“. Ako podesite opciju na naročiti niz znakova „disabled“, " -#~ "onda neće biti korišćena nijedna kombinacija tastera za ovu akciju." +#~ "Nije određen „start_angle“ (početni_ugao) ili „from“ (od) atribut u " +#~ "elementu <%s>" -#~ msgid "" -#~ "The keybinding used to enter \"resize mode\" and begin resizing a window " -#~ "using the keyboard. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "Kombinacija tastera za ulazak u „režim promene veličine“ ili za početak " -#~ "promene veličine prozora pomoću tastature. Oblik zapisa je „<" -#~ "Control>a“ ili „<Shift><Alt>F1“. Program za obradu je " -#~ "dosta slobodan i dozvoljava velika ili mala slova, kao i skraćenice poput " -#~ "„<Ctl>“ ili „< Ctrl>“. Ako podesite opciju na naročiti niz " -#~ "znakova „disabled“, onda neće biti korišćena nijedna kombinacija tastera " -#~ "za ovu akciju." +#~ msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" +#~ msgstr "Nije definisan „extent_angle“ ili „to“ atribut u elementu <%s>" -#~ msgid "" -#~ "The keybinding used to hide all normal windows and set the focus to the " -#~ "desktop background. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "Kombinacija tastera za sakrivanje svih običnih prozora i fokusiranje " -#~ "pozadine radne površi. Oblik zapisa je „<Control>a“ ili „<" -#~ "Shift><Alt>F1“. Program za obradu je dosta slobodan i dozvoljava " -#~ "velika ili mala slova, kao i skraćenice poput „<Ctl>“ ili „< " -#~ "Ctrl>“. Ako podesite opciju na naročiti niz znakova „disabled“, onda " -#~ "neće biti korišćena nijedna kombinacija tastera za ovu akciju." +#~ msgid "Did not understand value \"%s\" for type of gradient" +#~ msgstr "Nisam razumeo vrednost „%s“ kao tip gradijenta" -#~ msgid "" -#~ "The keybinding used to maximize a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Kombinacija tastera za uvećavanje prozora. Oblik zapisa je „<Control>" -#~ "a“ ili „<Shift><Alt>F1“. Program za obradu je dosta slobodan " -#~ "i dozvoljava velika ili mala slova, kao i skraćenice poput „<Ctl>“ " -#~ "ili „< Ctrl>“. Ako podesite opciju na naročiti niz znakova " -#~ "„disabled“, onda neće biti korišćena nijedna kombinacija tastera za ovu " -#~ "akciju." +#~ msgid "Did not understand fill type \"%s\" for <%s> element" +#~ msgstr "Nisam razumeo tip popunjavanja površine „%s“ u elementu <%s>" -#~ msgid "" -#~ "The keybinding used to minimize a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Kombinacija tastera za umanjivanje prozora. Oblik zapisa je „<Control>" -#~ "a“ ili „<Shift><Alt>F1“. Program za obradu je dosta slobodan " -#~ "i dozvoljava velika ili mala slova, kao i skraćenice poput „<Ctl>“ " -#~ "ili „< Ctrl>“. Ako podesite opciju na naročiti niz znakova " -#~ "„disabled“, onda neće biti korišćena nijedna kombinacija tastera za ovu " -#~ "akciju." +#~ msgid "Did not understand state \"%s\" for <%s> element" +#~ msgstr "Nisam razumeo stanje „%s“ u elementu <%s>" -#~ msgid "" -#~ "The keybinding used to move a window one workspace down. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Kombinacija tastera za prebacivanje prozora na radni prostor ispod. Oblik " -#~ "zapisa je „<Control>a“ ili „<Shift><Alt>F1“. Program za " -#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, kao i " -#~ "skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako podesite opciju " -#~ "na naročiti niz znakova „disabled“, onda neće biti korišćena nijedna " -#~ "kombinacija tastera za ovu akciju." +#~ msgid "Did not understand shadow \"%s\" for <%s> element" +#~ msgstr "Nisam razumeo senku „%s“ u elementu <%s>" -#~ msgid "" -#~ "The keybinding used to move a window one workspace to the left. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Kombinacija tastera za prebacivanje prozora na radni prostor levo. Oblik " -#~ "zapisa je „<Control>a“ ili „<Shift><Alt>F1“. Program za " -#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, kao i " -#~ "skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako podesite opciju " -#~ "na naročiti niz znakova „disabled“, onda neće biti korišćena nijedna " -#~ "kombinacija tastera za ovu akciju." +#~ msgid "Did not understand arrow \"%s\" for <%s> element" +#~ msgstr "Nisam razumeo strelicu „%s“ u elementu <%s>" -#~ msgid "" -#~ "The keybinding used to move a window one workspace to the right. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Kombinacija tastera za prebacivanje prozora na radni prostor desno. Oblik " -#~ "zapisa je „<Control>a“ ili „<Shift><Alt>F1“. Program za " -#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, kao i " -#~ "skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako podesite opciju " -#~ "na naročiti niz znakova „disabled“, onda neće biti korišćena nijedna " -#~ "kombinacija tastera za ovu akciju." +#~ msgid "No <draw_ops> called \"%s\" has been defined" +#~ msgstr "Nije definisan <draw_ops> označen kao „%s“" -#~ msgid "" -#~ "The keybinding used to move a window one workspace up. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ msgid "Including draw_ops \"%s\" here would create a circular reference" #~ msgstr "" -#~ "Kombinacija tastera za prebacivanje prozora na radni prostor gore. Oblik " -#~ "zapisa je „<Control>a“ ili „<Shift><Alt>F1“. Program za " -#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, kao i " -#~ "skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako podesite opciju " -#~ "na naročiti niz znakova „disabled“, onda neće biti korišćena nijedna " -#~ "kombinacija tastera za ovu akciju." +#~ "Uključivanje elementa „draw_ops“ „%s“ ovde bi napravilo kružnu referencu" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 1. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Kombinacija tastera za prebacivanje prozora na radni prostor broj 1. Oblik " -#~ "zapisa je „<Control>a“ ili „<Shift><Alt>F1“. Program za " -#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, kao i " -#~ "skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako podesite opciju " -#~ "na naročiti niz znakova „disabled“, onda neće biti korišćena nijedna " -#~ "kombinacija tastera za ovu akciju." +#~ msgid "Unknown position \"%s\" for frame piece" +#~ msgstr "Nepoznat položaj „%s“ za deo okvira" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 10. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Kombinacija tastera za prebacivanje prozora na radni prostor broj 10. " -#~ "Oblik zapisa je „<Control>a“ ili „<Shift><Alt>F1“. " -#~ "Program za obradu je dosta slobodan i dozvoljava velika ili mala slova, " -#~ "kao i skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako podesite " -#~ "opciju na naročiti niz znakova „disabled“, onda neće biti korišćena " -#~ "nijedna kombinacija tastera za ovu akciju." +#~ msgid "Frame style already has a piece at position %s" +#~ msgstr "Stil okvira već ima deo na položaju %s" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 11. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Kombinacija tastera za prebacivanje prozora na radni prostor broj 11. " -#~ "Oblik zapisa je „<Control>a“ ili „<Shift><Alt>F1“. " -#~ "Program za obradu je dosta slobodan i dozvoljava velika ili mala slova, " -#~ "kao i skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako podesite " -#~ "opciju na naročiti niz znakova „disabled“, onda neće biti korišćena " -#~ "nijedna kombinacija tastera za ovu akciju." +#~ msgid "No <draw_ops> with the name \"%s\" has been defined" +#~ msgstr "Nije definisan <draw_ops> sa imenom „%s“" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 12. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Kombinacija tastera za prebacivanje prozora na radni prostor broj 12. " -#~ "Oblik zapisa je „<Control>a“ ili „<Shift><Alt>F1“. " -#~ "Program za obradu je dosta slobodan i dozvoljava velika ili mala slova, " -#~ "kao i skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako podesite " -#~ "opciju na naročiti niz znakova „disabled“, onda neće biti korišćena " -#~ "nijedna kombinacija tastera za ovu akciju." +#~ msgid "Unknown function \"%s\" for button" +#~ msgstr "Nepoznata funkcija „%s“ za dugme" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 2. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ msgid "Button function \"%s\" does not exist in this version (%d, need %d)" #~ msgstr "" -#~ "Kombinacija tastera za prebacivanje prozora na radni prostor broj 2. Oblik " -#~ "zapisa je „<Control>a“ ili „<Shift><Alt>F1“. Program za " -#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, kao i " -#~ "skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako podesite opciju " -#~ "na naročiti niz znakova „disabled“, onda neće biti korišćena nijedna " -#~ "kombinacija tastera za ovu akciju." +#~ "Funkcija „%s“ za dugme ne postoji u ovoj verziji (verzija %d, a treba vam " +#~ "%d)" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 3. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Kombinacija tastera za prebacivanje prozora na radni prostor broj 3. Oblik " -#~ "zapisa je „<Control>a“ ili „<Shift><Alt>F1“. Program za " -#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, kao i " -#~ "skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako podesite opciju " -#~ "na naročiti niz znakova „disabled“, onda neće biti korišćena nijedna " -#~ "kombinacija tastera za ovu akciju." +#~ msgid "Unknown state \"%s\" for button" +#~ msgstr "Nepoznato stanje „%s“ za dugme" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 4. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Kombinacija tastera za prebacivanje prozora na radni prostor broj 4. Oblik " -#~ "zapisa je „<Control>a“ ili „<Shift><Alt>F1“. Program za " -#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, kao i " -#~ "skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako podesite opciju " -#~ "na naročiti niz znakova „disabled“, onda neće biti korišćena nijedna " -#~ "kombinacija tastera za ovu akciju." +#~ msgid "Frame style already has a button for function %s state %s" +#~ msgstr "Stil okvira već ima dugme sa funkcijom %s i stanjem %s" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 5. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Kombinacija tastera za prebacivanje prozora na radni prostor broj 5. Oblik " -#~ "zapisa je „<Control>a“ ili „<Shift><Alt>F1“. Program za " -#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, kao i " -#~ "skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako podesite opciju " -#~ "na naročiti niz znakova „disabled“, onda neće biti korišćena nijedna " -#~ "kombinacija tastera za ovu akciju." +#~ msgid "\"%s\" is not a valid value for focus attribute" +#~ msgstr "„%s“ nije dozvoljena vrednost za atribut fokusa" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 6. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Kombinacija tastera za prebacivanje prozora na radni prostor broj 6. Oblik " -#~ "zapisa je „<Control>a“ ili „<Shift><Alt>F1“. Program za " -#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, kao i " -#~ "skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako podesite opciju " -#~ "na naročiti niz znakova „disabled“, onda neće biti korišćena nijedna " -#~ "kombinacija tastera za ovu akciju." +#~ msgid "\"%s\" is not a valid value for state attribute" +#~ msgstr "„%s“ nije dozvoljena vrednost za atribut stanja" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 7. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Kombinacija tastera za prebacivanje prozora na radni prostor broj 7. Oblik " -#~ "zapisa je „<Control>a“ ili „<Shift><Alt>F1“. Program za " -#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, kao i " -#~ "skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako podesite opciju " -#~ "na naročiti niz znakova „disabled“, onda neće biti korišćena nijedna " -#~ "kombinacija tastera za ovu akciju." +#~ msgid "A style called \"%s\" has not been defined" +#~ msgstr "Stil „%s“ nije definisan" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 8. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Kombinacija tastera za prebacivanje prozora na radni prostor broj 8. Oblik " -#~ "zapisa je „<Control>a“ ili „<Shift><Alt>F1“. Program za " -#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, kao i " -#~ "skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako podesite opciju " -#~ "na naročiti niz znakova „disabled“, onda neće biti korišćena nijedna " -#~ "kombinacija tastera za ovu akciju." +#~ msgid "\"%s\" is not a valid value for resize attribute" +#~ msgstr "„%s“ nije dozvoljena vrednost za atribut promene veličine" #~ msgid "" -#~ "The keybinding used to move a window to workspace 9. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "Should not have \"resize\" attribute on <%s> element for maximized/shaded " +#~ "states" #~ msgstr "" -#~ "Kombinacija tastera za prebacivanje prozora na radni prostor broj 9. Oblik " -#~ "zapisa je „<Control>a“ ili „<Shift><Alt>F1“. Program za " -#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, kao i " -#~ "skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako podesite opciju " -#~ "na naročiti niz znakova „disabled“, onda neće biti korišćena nijedna " -#~ "kombinacija tastera za ovu akciju." +#~ "Nikako ne treba imati „resize“ atribut u elementu <%s> za uvećana/" +#~ "zasenčena stanja" #~ msgid "" -#~ "The keybinding used to move focus backwards between panels and the " -#~ "desktop, using a popup window. The format looks like \"<Control>a\" " -#~ "or \"<Shift><Alt>F1\". The parser is fairly liberal and " -#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" -#~ "\" and \"<Ctrl>\". If you set the option to the special string " -#~ "\"disabled\", then there will be no keybinding for this action." +#~ "Should not have \"resize\" attribute on <%s> element for maximized states" #~ msgstr "" -#~ "Kombinacija tastera za prebacivanje fokusa unazad između panela i radne " -#~ "površi, pomoću iskačućeg prozora. Oblik zapisa je „<Control>a“ ili " -#~ "„<Shift><Alt>F1“. Program za obradu je dosta slobodan i " -#~ "dozvoljava velika ili mala slova, kao i skraćenice poput „<Ctl>“ ili " -#~ "„< Ctrl>“. Ako podesite opciju na naročiti niz znakova „disabled“, " -#~ "onda neće biti korišćena nijedna kombinacija tastera za ovu akciju." +#~ "Nikako ne treba imati „resize“ atribut u elementu <%s> za uvećana stanja" -#~ msgid "" -#~ "The keybinding used to move focus backwards between panels and the " -#~ "desktop, without a popup window. The format looks like \"<Control>a" -#~ "\" or \"<Shift><Alt>F1\". The parser is fairly liberal and " -#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" -#~ "\" and \"<Ctrl>\". If you set the option to the special string " -#~ "\"disabled\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "Kombinacija tastera za prebacivanje fokusa unazad između panela i radne " -#~ "površi, bez iskačućeg prozora. Oblik zapisa je „<Control>a“ ili " -#~ "„<Shift><Alt>F1“. Program za obradu je dosta slobodan i " -#~ "dozvoljava velika ili mala slova, kao i skraćenice poput „<Ctl>“ ili " -#~ "„< Ctrl>“. Ako podesite opciju na naročiti niz znakova „disabled“, " -#~ "onda neće biti korišćena nijedna kombinacija tastera za ovu akciju." +#~ msgid "Style has already been specified for state %s resize %s focus %s" +#~ msgstr "Stil je već naveden za stanje „%s“ uvećanje „%s“ fokus „%s“" -#~ msgid "" -#~ "The keybinding used to move focus backwards between windows of an " -#~ "application without a popup window. Holding \"shift\" together with this " -#~ "binding makes the direction go forward again. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Kombinacija tastera za prebacivanje fokusa unazad između prozora programa, " -#~ "bez iskačućeg prozora. Držanje „shift“ uz ovu prečicu će ići opet unapred. " -#~ "Oblik zapisa je „<Control>a“ ili „<Shift><Alt>F1“. " -#~ "Program za obradu je dosta slobodan i dozvoljava velika ili mala slova, " -#~ "kao i skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako podesite " -#~ "opciju na naročiti niz znakova „disabled“, onda neće biti korišćena " -#~ "nijedna kombinacija tastera za ovu akciju." +#~ msgid "Style has already been specified for state %s focus %s" +#~ msgstr "Stil je već naveden za stanje „%s“ fokus „“%s" #~ msgid "" -#~ "The keybinding used to move focus backwards between windows of an " -#~ "application, using a popup window. Holding \"shift\" together with this " -#~ "binding makes the direction go forward again. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "Can't have a two draw_ops for a <piece> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" #~ msgstr "" -#~ "Kombinacija tastera za prebacivanje fokusa unazad između prozora programa, " -#~ "pomoću iskačućeg prozora. Držanje „shift“ uz ovu prečicu će ići opet " -#~ "unapred. Oblik zapisa je „<Control>a“ ili „<Shift><Alt>" -#~ "F1“. Program za obradu je dosta slobodan i dozvoljava velika ili mala " -#~ "slova, kao i skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako " -#~ "podesite opciju na naročiti niz znakova „disabled“, onda neće biti " -#~ "korišćena nijedna kombinacija tastera za ovu akciju." +#~ "Ne mogu postojati dva „draw_ops“ za element <piece> (tema navodi " +#~ "„draw_ops“ atribut i <draw_ops> element, ili navodi dva elementa)" #~ msgid "" -#~ "The keybinding used to move focus backwards between windows without a " -#~ "popup window. Holding \"shift\" together with this binding makes the " -#~ "direction go forward again. The format looks like \"<Control>a\" or " -#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " -#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" -#~ "\", then there will be no keybinding for this action." +#~ "Can't have a two draw_ops for a <button> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" #~ msgstr "" -#~ "Kombinacija tastera za prebacivanje fokusa unazad između prozora, bez " -#~ "iskačućeg prozora. Držanje „shift“ uz ovu prečicu će ići opet unapred. " -#~ "Oblik zapisa je „<Control>a“ ili „<Shift><Alt>F1“. " -#~ "Program za obradu je dosta slobodan i dozvoljava velika ili mala slova, " -#~ "kao i skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako podesite " -#~ "opciju na naročiti niz znakova „disabled“, onda neće biti korišćena " -#~ "nijedna kombinacija tastera za ovu akciju." +#~ "Ne mogu postojati dva „draw_ops“ za element <button> (tema navodi " +#~ "„draw_ops“ atribut i <draw_ops> element, ili navodi dva elementa)" #~ msgid "" -#~ "The keybinding used to move focus backwards between windows, using a " -#~ "popup window. Holding \"shift\" together with this binding makes the " -#~ "direction go forward again. The format looks like \"<Control>a\" or " -#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " -#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" -#~ "\", then there will be no keybinding for this action." +#~ "Can't have a two draw_ops for a <menu_icon> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" #~ msgstr "" -#~ "Kombinacija tastera za prebacivanje fokusa unazad između prozora, pomoću " -#~ "iskačućeg prozora. Držanje „shift“ uz ovu prečicu će ići opet unapred. " -#~ "Oblik zapisa je „<Control>a“ ili „<Shift><Alt>F1“. " -#~ "Program za obradu je dosta slobodan i dozvoljava velika ili mala slova, " -#~ "kao i skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako podesite " -#~ "opciju na naročiti niz znakova „disabled“, onda neće biti korišćena " -#~ "nijedna kombinacija tastera za ovu akciju." +#~ "Ne mogu postojati dva „draw_ops“ za element <menu_icon> (tema navodi " +#~ "„draw_ops“ atribut i <draw_ops> element, ili navodi dva elementa)" -#~ msgid "" -#~ "The keybinding used to move focus between panels and the desktop, using a " -#~ "popup window. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "Kombinacija tastera za prebacivanje fokusa između panela i radne površi, " -#~ "pomoću iskačućeg prozora. Oblik zapisa je „<Control>a“ ili „<" -#~ "Shift><Alt>F1“. Program za obradu je dosta slobodan i dozvoljava " -#~ "velika ili mala slova, kao i skraćenice poput „<Ctl>“ ili „< " -#~ "Ctrl>“. Ako podesite opciju na naročiti niz znakova „disabled“, onda " -#~ "neće biti korišćena nijedna kombinacija tastera za ovu akciju." +#~ msgid "Bad version specification '%s'" +#~ msgstr "Izdanje je loše određeno „%s“" #~ msgid "" -#~ "The keybinding used to move focus between panels and the desktop, without " -#~ "a popup window. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." +#~ "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" +#~ "theme-2.xml" #~ msgstr "" -#~ "Kombinacija tastera za prebacivanje fokusa između panela i radne površi, " -#~ "bez iskačućeg prozora. Oblik zapisa je „<Control>a“ ili „<" -#~ "Shift><Alt>F1“. Program za obradu je dosta slobodan i dozvoljava " -#~ "velika ili mala slova, kao i skraćenice poput „<Ctl>“ ili „< " -#~ "Ctrl>“. Ako podesite opciju na naročiti niz znakova „disabled“, onda " -#~ "neće biti korišćena nijedna kombinacija tastera za ovu akciju." +#~ "Ne mogu da koristim „version“ (izdanje) u metacity-theme-1.xml ili " +#~ "metacity-theme-2.xml" #~ msgid "" -#~ "The keybinding used to move focus between windows of an application " -#~ "without a popup window. Holding the \"shift\" key while using this " -#~ "binding reverses the direction of movement. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "Theme requires version %s but latest supported theme version is %d.%d" #~ msgstr "" -#~ "Kombinacija tastera za prebacivanje fokusa između prozora programa, bez " -#~ "iskačućeg prozora. (Tradicionalno <Alt&gr;Escape) Držanje tastera " -#~ "„shift“ pri upotrebi ove kombinacije obrće smer kretanja. Oblik zapisa je " -#~ "„<Control>a“ ili „<Shift><Alt>F1“. Program za obradu je " -#~ "dosta slobodan i dozvoljava velika ili mala slova, kao i skraćenice poput " -#~ "„<Ctl>“ ili „< Ctrl>“. Ako podesite opciju na naročiti niz " -#~ "znakova „disabled“, onda neće biti korišćena nijedna kombinacija tastera " -#~ "za ovu akciju." +#~ "Za ovu temu je neophodno izdanje %s, a poslednja podržana tema je %d.%d" -#~ msgid "" -#~ "The keybinding used to move focus between windows of an application, " -#~ "using a popup window. (Traditionally <Alt>F6) Holding the \"shift\" " -#~ "key while using this binding reverses the direction of movement. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Kombinacija tastera za prebacivanje fokusa između prozora programa, pomoću " -#~ "iskačućeg prozora. (Tradicionalno <Alt&gr;Tab) Držanje tastera „shift“ " -#~ "pri upotrebi ove kombinacije obrće smer kretanja. Oblik zapisa je „<" -#~ "Control>a“ ili „<Shift><Alt>F1“. Program za obradu je " -#~ "dosta slobodan i dozvoljava velika ili mala slova, kao i skraćenice poput " -#~ "„<Ctl>“ ili „< Ctrl>“. Ako podesite opciju na naročiti niz " -#~ "znakova „disabled“, onda neće biti korišćena nijedna kombinacija tastera " -#~ "za ovu akciju." +#~ msgid "Outermost element in theme must be <metacity_theme> not <%s>" +#~ msgstr "Najstariji element teme mora biti <metacity_theme>, a ne <%s>" #~ msgid "" -#~ "The keybinding used to move focus between windows without a popup window. " -#~ "(Traditionally <Alt>Escape) Holding the \"shift\" key while using " -#~ "this binding reverses the direction of movement. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "Element <%s> is not allowed inside a name/author/date/description element" #~ msgstr "" -#~ "Kombinacija tastera za prebacivanje fokusa između prozora, bez iskačućeg " -#~ "prozora. (Tradicionalno <Alt&gr;Escape) Držanje tastera „shift“ pri " -#~ "upotrebi ove kombinacije obrće smer kretanja. Oblik zapisa je „<" -#~ "Control>a“ ili „<Shift><Alt>F1“. Program za obradu je " -#~ "dosta slobodan i dozvoljava velika ili mala slova, kao i skraćenice poput " -#~ "„<Ctl>“ ili „< Ctrl>“. Ako podesite opciju na naročiti niz " -#~ "znakova „disabled“, onda neće biti korišćena nijedna kombinacija tastera " -#~ "za ovu akciju." +#~ "Element <%s> nije dozvoljen unutar elemenata „name, author, date i " +#~ "description“" -#~ msgid "" -#~ "The keybinding used to move focus between windows, using a popup window. " -#~ "(Traditionally <Alt>Tab) Holding the \"shift\" key while using this " -#~ "binding reverses the direction of movement. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Kombinacija tastera za prebacivanje fokusa između prozora, pomoću " -#~ "iskačućeg prozora. (Tradicionalno <Alt&gr;Tab) Držanje tastera „shift“ " -#~ "pri upotrebi ove kombinacije obrće smer kretanja. Oblik zapisa je „<" -#~ "Control>a“ ili „<Shift><Alt>F1“. Program za obradu je " -#~ "dosta slobodan i dozvoljava velika ili mala slova, kao i skraćenice poput " -#~ "„<Ctl>“ ili „< Ctrl>“. Ako podesite opciju na naročiti niz " -#~ "znakova „disabled“, onda neće biti korišćena nijedna kombinacija tastera " -#~ "za ovu akciju." +#~ msgid "Element <%s> is not allowed inside a <constant> element" +#~ msgstr "Element <%s> nije dozvoljen unutar elementa <constant>" #~ msgid "" -#~ "The keybinding used to toggle always on top. A window that is always on " -#~ "top will always be visible over other overlapping windows. The format " -#~ "looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -#~ "parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." +#~ "Element <%s> is not allowed inside a distance/border/aspect_ratio element" #~ msgstr "" -#~ "Kombinacija tastera za uključivanje/isključivanje da prozor bude uvek na " -#~ "vrhu. Prozor koji je uvek na vrhu će se videti i preko ostalih " -#~ "preklapajućih prozora. Oblik zapisa je „<Control>a“ ili „<" -#~ "Shift><Alt>F1“. Program za obradu je dosta slobodan i dozvoljava " -#~ "velika ili mala slova, kao i skraćenice poput „<Ctl>“ ili „< " -#~ "Ctrl>“. Ako podesite opciju na naročiti niz znakova „disabled“, onda " -#~ "neće biti korišćena nijedna kombinacija tastera za ovu akciju." +#~ "Element <%s> nije dozvoljen unutar elemenata „distance, border i " +#~ "aspect_ratio“" -#~ msgid "" -#~ "The keybinding used to toggle fullscreen mode. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Kombinacija tastera za uključivanje/isključivanje režima celog ekrana. Oblik " -#~ "zapisa je „<Control>a“ ili „<Shift><Alt>F1“. Program za " -#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, kao i " -#~ "skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako podesite opciju " -#~ "na naročiti niz znakova „disabled“, onda neće biti korišćena nijedna " -#~ "kombinacija tastera za ovu akciju." +#~ msgid "Element <%s> is not allowed inside a draw operation element" +#~ msgstr "Element <%s> nije dozvoljen unutar elemenata operacija crtanja" -#~ msgid "" -#~ "The keybinding used to toggle maximization. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Kombinacija tastera za uključivanje/isključivanje uvećanje. Oblik zapisa je " -#~ "„<Control>a“ ili „<Shift><Alt>F1“. Program za obradu je " -#~ "dosta slobodan i dozvoljava velika ili mala slova, kao i skraćenice poput " -#~ "„<Ctl>“ ili „< Ctrl>“. Ako podesite opciju na naročiti niz " -#~ "znakova „disabled“, onda neće biti korišćena nijedna kombinacija tastera " -#~ "za ovu akciju." +#~ msgid "Element <%s> is not allowed inside a <%s> element" +#~ msgstr "Element <%s> nije dozvoljen unutar <%s> elementa" -#~ msgid "" -#~ "The keybinding used to toggle shaded/unshaded state. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Kombinacija tastera za zamotavanje/odmotavanje. Oblik zapisa je „<" -#~ "Control>a“ ili „<Shift><Alt>F1“. Program za obradu je " -#~ "dosta slobodan i dozvoljava velika ili mala slova, kao i skraćenice poput " -#~ "„<Ctl>“ ili „< Ctrl>“. Ako podesite opciju na naročiti niz " -#~ "znakova „disabled“, onda neće biti korišćena nijedna kombinacija tastera " -#~ "za ovu akciju." +#~ msgid "No draw_ops provided for frame piece" +#~ msgstr "Nije naveden „draw_ops“ za deo okvira" -#~ msgid "" -#~ "The keybinding used to toggle whether the window is on all workspaces or " -#~ "just one. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Kombinacija tastera za izmenu da li je prozor u svim radnim prostorima " -#~ "ili samo u jednom. Oblik zapisa je „<Control>a“ ili „<Shift>" -#~ "<Alt>F1“. Program za obradu je dosta slobodan i dozvoljava velika " -#~ "ili mala slova, kao i skraćenice poput „<Ctl>“ ili „< Ctrl>“. " -#~ "Ako podesite opciju na naročiti niz znakova „disabled“, onda neće biti " -#~ "korišćena nijedna kombinacija tastera za ovu akciju." +#~ msgid "No draw_ops provided for button" +#~ msgstr "Nije naveden „draw_ops“ za dugme" -#~ msgid "" -#~ "The keybinding used to unmaximize a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Kombinacija tastera za poništavanje uvećanja prozora. Oblik zapisa je „<" -#~ "Control>a“ ili „<Shift><Alt>F1“. Program za obradu je " -#~ "dosta slobodan i dozvoljava velika ili mala slova, kao i skraćenice poput " -#~ "„<Ctl>“ ili „< Ctrl>“. Ako podesite opciju na naročiti niz " -#~ "znakova „disabled“, onda neće biti korišćena nijedna kombinacija tastera " -#~ "za ovu akciju." - -# bug: s/display's/displays/ (it's not genitive, but a verb as in "it displays") -#~ msgid "" -#~ "The keybinding which display's the panel's \"Run Application\" dialog " -#~ "box. The format looks like \"<Control>a\" or \"<Shift><" -#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If " -#~ "you set the option to the special string \"disabled\", then there will be " -#~ "no keybinding for this action." -#~ msgstr "" -#~ "Kombinacija tastera koja prikazuje prozorče panela „Pokreni program“. " -#~ "Oblik zapisa je „<Control>a“ ili „<Shift><Alt>F1“. " -#~ "Program za obradu je dosta slobodan i dozvoljava velika ili mala slova, " -#~ "kao i skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako podesite " -#~ "opciju na naročiti niz znakova „disabled“, onda neće biti korišćena " -#~ "nijedna kombinacija tastera za ovu akciju." +#~ msgid "No text is allowed inside element <%s>" +#~ msgstr "Nije dozvoljen tekst unutar elementa <%s>" -#~ msgid "" -#~ "The keybinding which invokes a terminal. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Kombinacija tastera koja pokreće terminal. Oblik zapisa je „<" -#~ "Control>a“ ili „<Shift><Alt>F1“. Program za obradu je " -#~ "dosta slobodan i dozvoljava velika ili mala slova, kao i skraćenice poput " -#~ "„<Ctl>“ ili „< Ctrl>“. Ako podesite opciju na naročiti niz " -#~ "znakova „disabled“, onda neće biti korišćena nijedna kombinacija tastera " -#~ "za ovu akciju." +#~ msgid "<%s> specified twice for this theme" +#~ msgstr "<%s> je naveden dva puta u ovoj temi" -#~ msgid "" -#~ "The keybinding which invokes the panel's screenshot utility to take a " -#~ "screenshot of a window. The format looks like \"<Control>a\" or " -#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " -#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" -#~ "\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "Kombinacija tastera koja prikazuje alatku panela za snimke ekrana za " -#~ "snimak prozora. Oblik zapisa je „<Control>a“ ili „<Shift><" -#~ "Alt>F1“. Program za obradu je dosta slobodan i dozvoljava velika ili " -#~ "mala slova, kao i skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako " -#~ "podesite opciju na naročiti niz znakova „disabled“, onda neće biti " -#~ "korišćena nijedna kombinacija tastera za ovu akciju." +#~ msgid "Failed to find a valid file for theme %s\n" +#~ msgstr "Nisam uspeo da pronađem ispravnu datoteku za temu „%s“\n" -#~ msgid "" -#~ "The keybinding which invokes the panel's screenshot utility. The format " -#~ "looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -#~ "parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Kombinacija tastera koja prikazuje alatku panela za snimke ekrana. Oblik " -#~ "zapisa je „<Control>a“ ili „<Shift><Alt>F1“. Program za " -#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, kao i " -#~ "skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako podesite opciju " -#~ "na naročiti niz znakova „disabled“, onda neće biti korišćena nijedna " -#~ "kombinacija tastera za ovu akciju." +#~ msgid "background texture could not be created from file" +#~ msgstr "sklop pozadine ne može biti stvoren iz datoteke" -#~ msgid "" -#~ "The keybinding which shows the panel's main menu. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Kombinacija tastera koja prikazuje glavni meni panela. Oblik zapisa je " -#~ "„<Control>a“ ili „<Shift><Alt>F1“. Program za obradu je " -#~ "dosta slobodan i dozvoljava velika ili mala slova, kao i skraćenice poput " -#~ "„<Ctl>“ ili „< Ctrl>“. Ako podesite opciju na naročiti niz " -#~ "znakova „disabled“, onda neće biti korišćena nijedna kombinacija tastera " -#~ "za ovu akciju." +#~ msgid "Unknown window information request: %d" +#~ msgstr "Zahtevana je nepoznata informacija o prozoru: %d" -#~ msgid "" -#~ "This keybinding changes whether a window is above or below other windows. " -#~ "If the window is covered by another one, it raises the window above all " -#~ "others, and if the window is already fully visible, it lowers it below " -#~ "all others. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Kombinacija tastera koja menja da li je prozor iznad ili ispod ostalih " -#~ "prozora. Ako je prozor pokriven nekim prozorom, onda se izdiže iznad " -#~ "ostalih, a ako je već u potpunosti prikazan, onda se sakriva iza svih " -#~ "ostalih prozora. Oblik zapisa je „<Control>a“ ili „<Shift><" -#~ "Alt>F1“. Program za obradu je dosta slobodan i dozvoljava velika ili " -#~ "mala slova, kao i skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako " -#~ "podesite opciju na naročiti niz znakova „disabled“, onda neće biti " -#~ "korišćena nijedna kombinacija tastera za ovu akciju." +#~ msgid "Missing %s extension required for compositing" +#~ msgstr "Nedostaje potreban kompozitni dodatak %s" #~ msgid "" -#~ "This keybinding lowers a window below other windows. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "Some other program is already using the key %s with modifiers %x as a " +#~ "binding\n" #~ msgstr "" -#~ "Kombinacija tastera koja sakriva prozor iza svih ostalih prozora. Oblik " -#~ "zapisa je „<Control>a“ ili „<Shift><Alt>F1“. Program za " -#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, kao i " -#~ "skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako podesite opciju " -#~ "na naročiti niz znakova „disabled“, onda neće biti korišćena nijedna " -#~ "kombinacija tastera za ovu akciju." +#~ "Neki drugi program već koristi taster %s sa izmenjivačima %x za neku " +#~ "funkciju\n" -#~ msgid "" -#~ "This keybinding moves a window against the north (top) side of the " -#~ "screen. The format looks like \"<Control>a\" or \"<Shift><" -#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If " -#~ "you set the option to the special string \"disabled\", then there will be " -#~ "no keybinding for this action." -#~ msgstr "" -#~ "Kombinacija tastera koja pomera prozor na sever ekrana (gornja ivica). " -#~ "Oblik zapisa je „<Control>a“ ili „<Shift><Alt>F1“. " -#~ "Program za obradu je dosta slobodan i dozvoljava velika ili mala slova, " -#~ "kao i skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako podesite " -#~ "opciju na naročiti niz znakova „disabled“, onda neće biti korišćena " -#~ "nijedna kombinacija tastera za ovu akciju." +#~ msgid "\"%s\" is not a valid accelerator\n" +#~ msgstr "„%s“ nije ispravna prečica\n" #~ msgid "" -#~ "This keybinding moves a window into the center of the screen. The format " -#~ "looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -#~ "parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." +#~ "Workarounds for broken applications disabled. Some applications may not " +#~ "behave properly.\n" #~ msgstr "" -#~ "Kombinacija tastera koja pomera prozor na sredinu ekrana. Oblik zapisa je " -#~ "„<Control>a“ ili „<Shift><Alt>F1“. Program za obradu je " -#~ "dosta slobodan i dozvoljava velika ili mala slova, kao i skraćenice poput " -#~ "„<Ctl>“ ili „< Ctrl>“. Ako podesite opciju na naročiti niz " -#~ "znakova „disabled“, onda neće biti korišćena nijedna kombinacija tastera " -#~ "za ovu akciju." +#~ "Rešenja za oštećene programe su isključena. Neke aplikacije se mogu " +#~ "ponašati čudno.\n" -#~ msgid "" -#~ "This keybinding moves a window into the east (right) side of the screen. " -#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -#~ "\". The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." +#~ msgid "Could not parse font description \"%s\" from GSettings key %s\n" #~ msgstr "" -#~ "Kombinacija tastera koja pomera prozor na istok ekrana (desna ivica). " -#~ "Oblik zapisa je „<Control>a“ ili „<Shift><Alt>F1“. " -#~ "Program za obradu je dosta slobodan i dozvoljava velika ili mala slova, " -#~ "kao i skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako podesite " -#~ "opciju na naročiti niz znakova „disabled“, onda neće biti korišćena " -#~ "nijedna kombinacija tastera za ovu akciju." +#~ "Ne mogu da obradim opis „%s“ iz ključa „%s“ u Gnomovim podešavanjima\n" #~ msgid "" -#~ "This keybinding moves a window into the north-east (top right) corner of " -#~ "the screen. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" #~ msgstr "" -#~ "Kombinacija tastera koja pomera prozor na severoistok ekrana (gore " -#~ "desno). Oblik zapisa je „<Control>a“ ili „<Shift><Alt>" -#~ "F1“. Program za obradu je dosta slobodan i dozvoljava velika ili mala " -#~ "slova, kao i skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako " -#~ "podesite opciju na naročiti niz znakova „disabled“, onda neće biti " -#~ "korišćena nijedna kombinacija tastera za ovu akciju." +#~ "„%s“ je pronađen u bazi podešavanja što nije ispravna vrednost koja menja " +#~ "ponašanje tastera miša\n" #~ msgid "" -#~ "This keybinding moves a window into the north-west (top left) corner of " -#~ "the screen. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." +#~ "\"%s\" found in configuration database is not a valid value for " +#~ "keybinding \"%s\"\n" #~ msgstr "" -#~ "Kombinacija tastera koja pomera prozor na severozapad ekrana (gore levo). " -#~ "Oblik zapisa je „<Control>a“ ili „<Shift><Alt>F1“. " -#~ "Program za obradu je dosta slobodan i dozvoljava velika ili mala slova, " -#~ "kao i skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako podesite " -#~ "opciju na naročiti niz znakova „disabled“, onda neće biti korišćena " -#~ "nijedna kombinacija tastera za ovu akciju." +#~ "„%s“ iz baze sa podešavanjima nije ispravna kombinacija tastera „%s“\n" #~ msgid "" -#~ "This keybinding moves a window into the south (bottom) side of the " -#~ "screen. The format looks like \"<Control>a\" or \"<Shift><" -#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If " -#~ "you set the option to the special string \"disabled\", then there will be " -#~ "no keybinding for this action." +#~ "Could not acquire window manager selection on screen %d display \"%s\"\n" #~ msgstr "" -#~ "Kombinacija tastera koja pomera prozor na jug ekrana (donja ivica). Oblik " -#~ "zapisa je „<Control>a“ ili „<Shift><Alt>F1“. Program za " -#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, kao i " -#~ "skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako podesite opciju " -#~ "na naročiti niz znakova „disabled“, onda neće biti korišćena nijedna " -#~ "kombinacija tastera za ovu akciju." +#~ "Ne mogu da dobijem izbor upravnika prozora na prikazu %d erkana „%s“\n" -#~ msgid "" -#~ "This keybinding moves a window into the south-east (bottom right) corner " -#~ "of the screen. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "Kombinacija tastera koja pomera prozor na jugoistok ekrana (dole desno). " -#~ "Oblik zapisa je „<Control>a“ ili „<Shift><Alt>F1“. " -#~ "Program za obradu je dosta slobodan i dozvoljava velika ili mala slova, " -#~ "kao i skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako podesite " -#~ "opciju na naročiti niz znakova „disabled“, onda neće biti korišćena " -#~ "nijedna kombinacija tastera za ovu akciju." +#~ msgid "Could not release screen %d on display \"%s\"\n" +#~ msgstr "Ne mogu da otpustim prikaz %d na ekranu „%s“\n" -#~ msgid "" -#~ "This keybinding moves a window into the south-west (bottom left) corner " -#~ "of the screen. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "Kombinacija tastera koja pomera prozor na jugozapad ekrana (dole levo). " -#~ "Oblik zapisa je „<Control>a“ ili „<Shift><Alt>F1“. " -#~ "Program za obradu je dosta slobodan i dozvoljava velika ili mala slova, " -#~ "kao i skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako podesite " -#~ "opciju na naročiti niz znakova „disabled“, onda neće biti korišćena " -#~ "nijedna kombinacija tastera za ovu akciju." +#~ msgid "Could not create directory '%s': %s\n" +#~ msgstr "Ne mogu da napravim direktorijum „%s“: %s\n" -#~ msgid "" -#~ "This keybinding moves a window into the west (left) side of the screen. " -#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -#~ "\". The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Kombinacija tastera koja pomera prozor na zapad ekrana (leva ivica). " -#~ "Oblik zapisa je „<Control>a“ ili „<Shift><Alt>F1“. " -#~ "Program za obradu je dosta slobodan i dozvoljava velika ili mala slova, " -#~ "kao i skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako podesite " -#~ "opciju na naročiti niz znakova „disabled“, onda neće biti korišćena " -#~ "nijedna kombinacija tastera za ovu akciju." +#~ msgid "Could not open session file '%s' for writing: %s\n" +#~ msgstr "Ne mogu da otvorim datoteku sesije „%s“ za upis: %s\n" -#~ msgid "" -#~ "This keybinding raises the window above other windows. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Kombinacija tastera koja izdiže prozor ispred svih ostalih prozora. Oblik " -#~ "zapisa je „<Control>a“ ili „<Shift><Alt>F1“. Program za " -#~ "obradu je dosta slobodan i dozvoljava velika ili mala slova, kao i " -#~ "skraćenice poput „<Ctl>“ ili „< Ctrl>“. Ako podesite opciju " -#~ "na naročiti niz znakova „disabled“, onda neće biti korišćena nijedna " -#~ "kombinacija tastera za ovu akciju." +#~ msgid "Error writing session file '%s': %s\n" +#~ msgstr "Greška zapisivanja datoteke sesije „%s“: %s\n" -#~ msgid "" -#~ "This keybinding resizes a window to fill available horizontal space. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Kombinacija tastera za izmenu veličine prozora tako da popuni sav " -#~ "vodoravni prostor. Oblik zapisa je „<Control>a“ ili „<Shift>" -#~ "<Alt>F1“. Program za obradu je dosta slobodan i dozvoljava velika " -#~ "ili mala slova, kao i skraćenice poput „<Ctl>“ ili „< Ctrl>“. " -#~ "Ako podesite opciju na naročiti niz znakova „disabled“, onda neće biti " -#~ "korišćena nijedna kombinacija tastera za ovu akciju." +#~ msgid "Error closing session file '%s': %s\n" +#~ msgstr "Greška prilikom zatvaranja datoteke sesije „%s“: %s\n" -#~ msgid "" -#~ "This keybinding resizes a window to fill available vertical space. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Kombinacija tastera za izmenu veličine prozora tako da popuni sav " -#~ "uspravni prostor. Oblik zapisa je „<Control>a“ ili „<Shift>" -#~ "<Alt>F1“. Program za obradu je dosta slobodan i dozvoljava velika " -#~ "ili mala slova, kao i skraćenice poput „<Ctl>“ ili „< Ctrl>“. " -#~ "Ako podesite opciju na naročiti niz znakova „disabled“, onda neće biti " -#~ "korišćena nijedna kombinacija tastera za ovu akciju." +#~ msgid "Failed to parse saved session file: %s\n" +#~ msgstr "Nisam uspeo da obradim sačuvanu datoteku sesije: %s\n" -#~ msgid "Toggle always on top state" -#~ msgstr "Izmeni da li je uvek na vrhu" +#~ msgid "<mutter_session> attribute seen but we already have the session ID" +#~ msgstr "Atribut <mutter_session> je primećen ali mi već imamo IB sesije" -#~ msgid "Unmaximize window" -#~ msgstr "Poništi uvećanje prozora" +#~ msgid "Unknown attribute %s on <%s> element" +#~ msgstr "Nepoznat atribut „%s“ u <%s> elementu" -#~ msgid "Unmaximize Window" -#~ msgstr "Poništi uvećavanje prozora" +#~ msgid "nested <window> tag" +#~ msgstr "ugnježden <window> element" -#~ msgid "No \"%s\" attribute on <%s> element" -#~ msgstr "Ne postoji atribut „%s“ u elementu <%s>" +#~ msgid "Unknown element %s" +#~ msgstr "Nepoznat element „%s“" -#~ msgid "Theme already has a fallback icon" -#~ msgstr "Tema već ima rezervy za icon" +#~ msgid "Failed to open debug log: %s\n" +#~ msgstr "Nisam uspeo da otvorim dnevnik grešaka: %s\n" -#~ msgid "Theme already has a fallback mini_icon" -#~ msgstr "Tema već ima rezervu za mini_icon" +#~ msgid "Failed to fdopen() log file %s: %s\n" +#~ msgstr "Nisam uspeo da „fdopen()“ datoteku dnevnika „%s“: %s\n" -#~ msgid "No \"name\" attribute on element <%s>" -#~ msgstr "Nije definisan „name“ atribut u elementu <%s>" +#~ msgid "Opened log file %s\n" +#~ msgstr "Otvorena je datoteka dnevnika „%s“\n" -#~ msgid "No \"value\" attribute on element <%s>" -#~ msgstr "Nije definisan „value“ atribut u elementu <%s>" +#~ msgid "Window manager: " +#~ msgstr "Upravnik prozora: " -#~ msgid "No \"top\" attribute on element <%s>" -#~ msgstr "Nije definisan „top“ atribut u elementu <%s>" +#~ msgid "Bug in window manager: " +#~ msgstr "Greška u upravniku prozora: " -#~ msgid "No \"bottom\" attribute on element <%s>" -#~ msgstr "Nije definisan „bottom“ atribut u elementu <%s>" +#~ msgid "Window manager warning: " +#~ msgstr "Upozorenje upravnika prozora: " -#~ msgid "No \"left\" attribute on element <%s>" -#~ msgstr "Nije definisan „left“ atribut u elementu <%s>" +#~ msgid "Window manager error: " +#~ msgstr "Greška upravnika prozora: " -#~ msgid "No \"right\" attribute on element <%s>" -#~ msgstr "Nije definisan „right“ atribut u elementu <%s>" +#~ msgid "" +#~ "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " +#~ "window as specified in the ICCCM.\n" +#~ msgstr "" +#~ "Prozor „%s“ je postavio „SM_CLIENT_ID“ na sebi samom umesto na prozoru " +#~ "„WM_CLIENT_LEADER“ kao što je navedeno u ICCCM.\n" -#~ msgid "No \"color\" attribute on element <%s>" -#~ msgstr "Nije definisan „color“ atribut u elementu <%s>" +#~ msgid "" +#~ "Window %s sets an MWM hint indicating it isn't resizable, but sets min " +#~ "size %d x %d and max size %d x %d; this doesn't make much sense.\n" +#~ msgstr "" +#~ "Prozor „%s“ je postavio „MWM“ što nagoveštava da nije promenljive " +#~ "veličine, ali je postavio najmanju veličinu %d x %d i najveću veličinu %d " +#~ "x %d što nema mnogo smisla.\n" -#~ msgid "No \"x1\" attribute on element <%s>" -#~ msgstr "Nije definisan „x1“ atribut u elementu <%s>" +#~ msgid "Application set a bogus _NET_WM_PID %lu\n" +#~ msgstr "Program je postavio netačan _NET_WM_PID %lu\n" -#~ msgid "No \"y1\" attribute on element <%s>" -#~ msgstr "Nije definisan „y1“ atribut u elementu <%s>" +#~ msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +#~ msgstr "Neispravan prozor 0x%lx naveden kao WM_TRANSIENT_FOR za %s.\n" -#~ msgid "No \"x2\" attribute on element <%s>" -#~ msgstr "Nije definisan „x2“ atribut u elementu <%s>" +#~ msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" +#~ msgstr "WM_TRANSIENT_FOR prozor 0x%lx za %s će napraviti petlju.\n" -#~ msgid "No \"y2\" attribute on element <%s>" -#~ msgstr "Nije definisan „y2“ atribut u elementu <%s>" +#~ msgid "" +#~ "Window 0x%lx has property %s\n" +#~ "that was expected to have type %s format %d\n" +#~ "and actually has type %s format %d n_items %d.\n" +#~ "This is most likely an application bug, not a window manager bug.\n" +#~ "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +#~ msgstr "" +#~ "Prozor 0x%lx ima osobinu %s\n" +#~ "tako da je očekivano da ima vrstu %s format %d,\n" +#~ "a zapravo ima vrstu %s format %d n_stavki %d.\n" +#~ "Ovo je najverovatnije greška u programu, a ne u upravniku prozora.\n" +#~ "Prozor ima naslov=„%s“ klasu=„%s“ naziv=„%s“\n" -#~ msgid "No \"y\" attribute on element <%s>" -#~ msgstr "Nije definisan „y“ atribut u elementu <%s>" +#~ msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +#~ msgstr "Osobina „%s“ prozora 0x%lx sadrži neispravan UTF-8\n" -#~ msgid "No \"width\" attribute on element <%s>" -#~ msgstr "Nije definisan „width“ atribut u elementu <%s>" +#~ msgid "" +#~ "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the " +#~ "list\n" +#~ msgstr "" +#~ "Osobina „%s“ prozora 0x%lx sadrži neispravan UTF-8 za stavku „%d“ na " +#~ "spisku\n" -#~ msgid "No \"height\" attribute on element <%s>" -#~ msgstr "Nije definisan „height“ atribut u elementu <%s>" +#~ msgid "Mi_nimize" +#~ msgstr "U_manji" -#~ msgid "No \"start_angle\" attribute on element <%s>" -#~ msgstr "Nije definisan „start_angle“ atribut u elementu <%s>" +#~ msgid "Ma_ximize" +#~ msgstr "U_većaj" -#~ msgid "No \"extent_angle\" attribute on element <%s>" -#~ msgstr "Nije definisan „extent_angle“ atribut u elementu <%s>" +#~ msgid "Unma_ximize" +#~ msgstr "Poništi u_većanje" -#~ msgid "No \"alpha\" attribute on element <%s>" -#~ msgstr "Nije definisan „alpha“ atribut u elementu <%s>" +#~ msgid "Roll _Up" +#~ msgstr "_Zamotaj" -#~ msgid "No \"type\" attribute on element <%s>" -#~ msgstr "Nije definisan „type“ atribut u elementu <%s>" +#~ msgid "_Unroll" +#~ msgstr "_Odmotaj" -#~ msgid "No \"filename\" attribute on element <%s>" -#~ msgstr "Nije definisan „filename“ atribut u elementu <%s>" +#~ msgid "_Move" +#~ msgstr "_Premesti" -#~ msgid "No \"state\" attribute on element <%s>" -#~ msgstr "Nije definisan „state“ atribut u elementu <%s>" +#~ msgid "_Resize" +#~ msgstr "P_romeni veličinu" -#~ msgid "No \"shadow\" attribute on element <%s>" -#~ msgstr "Nije definisan „shadow“ atribut u elementu <%s>" +#~ msgid "Move Titlebar On_screen" +#~ msgstr "Premesti traku _naslova na ekran" -#~ msgid "No \"arrow\" attribute on element <%s>" -#~ msgstr "Nije definisan „arrow“ atribut u elementu <%s>" +#~ msgid "Always on _Top" +#~ msgstr "Uvek _iznad ostalih" -#~ msgid "No \"value\" attribute on <%s> element" -#~ msgstr "Nije definisan „value“ atribut u elementu <%s>" +#~ msgid "_Always on Visible Workspace" +#~ msgstr "_Uvek na vidljivom radnom prostoru" -#~ msgid "No \"position\" attribute on <%s> element" -#~ msgstr "Nije definisan „position“ atribut u elementu <%s>" +#~ msgid "_Only on This Workspace" +#~ msgstr "Samo na _ovom radnom prostoru" -#~ msgid "No \"function\" attribute on <%s> element" -#~ msgstr "Nije definisan „function“ atribut u elementu <%s>" +#~ msgid "Move to Workspace _Left" +#~ msgstr "Premesti na radni prostor le_vo" -#~ msgid "No \"state\" attribute on <%s> element" -#~ msgstr "Nije definisan „state“ atribut u elementu <%s>" +#~ msgid "Move to Workspace R_ight" +#~ msgstr "Premesti na radni prostor de_sno" -#~ msgid "No \"focus\" attribute on <%s> element" -#~ msgstr "Nije definisan „focus“ atribut u elementu <%s>" +#~ msgid "Move to Workspace _Up" +#~ msgstr "Premesti na radni prostor go_re" -#~ msgid "No \"style\" attribute on <%s> element" -#~ msgstr "Nije definisan „style“ atribut u elementu <%s>" +#~ msgid "Move to Workspace _Down" +#~ msgstr "Premesti na radni prostor do_le" -#~ msgid "No \"resize\" attribute on <%s> element" -#~ msgstr "Nije definisan „resize“ atribut u elementu <%s>" +#~ msgid "_Close" +#~ msgstr "_Zatvori" -#~ msgid "Type of %s was not integer" -#~ msgstr "Tip podatka „%s“ nije celobrojna vrednost" +#~ msgid "Workspace %d%n" +#~ msgstr "Radni prostor %d%n" -#~ msgid "" -#~ "%d stored in GConf key %s is not a reasonable cursor_size; must be in the " -#~ "range 1..128\n" -#~ msgstr "" -#~ "Broj %d sačuvan u ključu %s u Gnomovim podešavanjima ne predstavlja razumnu " -#~ "veličinu kursora koja mora biti u opsegu od 1 do 128\n" +#~ msgid "Workspace 1_0" +#~ msgstr "1_0. radni prostor" -#~ msgid "" -#~ "%d stored in GConf key %s is not a reasonable number of workspaces, " -#~ "current maximum is %d\n" -#~ msgstr "" -#~ "%d sačuvano u ključu %s u gnom podešavanjima nije razuman broj radnih " -#~ "površina, trenutni maksimum je %d\n" +#~ msgid "Workspace %s%d" +#~ msgstr "%s%d. radni prostor" -#~ msgid "On _Top" -#~ msgstr "Izna_d svega" +#~ msgid "Move to Another _Workspace" +#~ msgstr "Premesti na drugi _radni prostor" -#~ msgid "" -#~ "Forcing this application to quit will cause you to lose any unsaved " -#~ "changes." -#~ msgstr "Primoravanjem programa na izlaz ćete izgubiti sve nesačuvane izmene." +#~ msgid "Shift" +#~ msgstr "Šift" -#~ msgid "Unknown function \"%s\" for menu icon" -#~ msgstr "Nepoznata funkcija „%s“ za ikonu menija" +#~ msgid "Ctrl" +#~ msgstr "Ktrl" -#~ msgid "Unknown state \"%s\" for menu icon" -#~ msgstr "Nepoznato stanjr „%s“ za ikonu menija" +#~ msgid "Alt" +#~ msgstr "Alt" -#~ msgid "Theme already has a menu icon for function %s state %s" -#~ msgstr "Tema već poseduje ikonu menija za funkciju %s stanje %s" +#~ msgid "Meta" +#~ msgstr "Meta" -#~ msgid "No draw_ops provided for menu icon" -#~ msgstr "Nije naveden draw_ops ikonu menija" +#~ msgid "Super" +#~ msgstr "Super" -#~ msgid "Failed to read theme from file %s: %s\n" -#~ msgstr "Nisam uspeo da pročitam temu iz datoteke %s: %s\n" +#~ msgid "Hyper" +#~ msgstr "Hiper" -#~ msgid "" -#~ "<menu_icon function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -#~ "specified for this theme" -#~ msgstr "" -#~ "<menu_icon function=\"%s\" state=\"%s\" draw_ops=\"bilo šta\"/> mora biti " -#~ "definisan za ovu temu" +#~ msgid "Mod2" +#~ msgstr "Mod2" -#~ msgid "" -#~ "If true, and the focus mode is either \"sloppy\" or \"mouse\" then the " -#~ "focused window will be automatically raised after a delay (the delay is " -#~ "specified by the auto_raise_delay key). This preference is poorly named, " -#~ "but kept for backwards compatibility. To try to be more clear (at least " -#~ "to the technically inclined), its meaning is \"automatically raise the " -#~ "window following a timeout which is triggered by non-grabbed mouse entry " -#~ "in sloppy or mouse focus modes\". It is unrelated to clicking behavior (i." -#~ "e. this is not related to raise-on-click/orthogonal-raise). It is " -#~ "unrelated to entering a window during drag and drop (because that results " -#~ "in the application grabbing the mouse)" -#~ msgstr "" -#~ "Ako je istinito i režim fokusa je ili „sloppy“ ili „mouse“ tada će " -#~ "fokusirani prozor biti sam podignut nakon neke zadrške koja je određena u " -#~ "ključu „auto_raise_delay“. Ova postavka je neodgovarajuće imenovana ali " -#~ "zadržana zbog saglasnosti sa starim izdanjima. Da bi bili jasniji (barem " -#~ "onim tehnički obrazovanim), njeno značenje je — sam podigni prozor nakon " -#~ "zadrške što se okida u režimima „sloppy“ i „mouse“. To nema veze sa " -#~ "ponašanjem pri pritiskanju (nije srodno sa podizanjem po pritisku). Nije " -#~ "srosno takođe sa ulaskom u prozor pri radnji „Prevuci i otpusti“ jer " -#~ "rezultat toga je da sam program preuzima miš." +#~ msgid "Mod3" +#~ msgstr "Mod3" -#~ msgid "" -#~ "Some applications break specifications in ways that result in window " -#~ "manager misfeatures. For example, ideally Metacity would place all " -#~ "dialogs in a consistent position with respect to their parent window. " -#~ "This requires ignoring application-specified positions for dialogs. But " -#~ "some versions of Java/Swing mark their popup menus as dialogs, so " -#~ "Metacity has to disable dialog positioning to allow menus to work in " -#~ "broken Java applications. There are several other examples like this. " -#~ "This option puts Metacity in full-on Correct mode, which perhaps gives a " -#~ "moderately nicer UI if you don't need to run any broken apps. Sadly, " -#~ "workarounds must be enabled by default; the real world is an ugly place. " -#~ "Some of the workarounds are workarounds for limitations in the " -#~ "specifications themselves, so sometimes a bug in no-workarounds mode " -#~ "won't be fixable without amending a spec." -#~ msgstr "" -#~ "Neki programi krše specifikacije što rezultira neispravnim mogućnostima " -#~ "menadžera prozora. Na primer, u idealnom slučaju metasiti bi postavio " -#~ "dijaloge na konzistentne pozicije u zavisnosti od starijeg prozora. To " -#~ "zahteva ignorisanje programski specifiranih pozicija dijaloga. Ali neke " -#~ "verzije Jave/Svinga obeležavaju njihove kontekstne menije kao dijaloge, " -#~ "tako da metasiti mora da isključi pozicioniranje dijaloga i omogući " -#~ "menijima da rade u lošim Java programima. Postoji nekoliko sličnih " -#~ "primera. Ova opcija postavlja metasiti u potpuno tačan način rada, što " -#~ "možda daje opšte lepši korisnički interfejs ako ne morate da pokrećete " -#~ "nekompatibilne programe. Međutim kompromisi moraju biti predefinisano " -#~ "dozvoljeni; starni svet je jako ružno mesto. Neki od kompromisa su " -#~ "kompromisi za ograničenja koja se javljaju u samim specifikacijama, tako da " -#~ "se greška u nekompromisnom načinu rada nemože ispraviti bez-zaobilaženja " -#~ "specifikacija." +#~ msgid "Mod4" +#~ msgstr "Mod4" -#~ msgid "" -#~ "Coordinate expression parser overflowed its buffer, this is really a " -#~ "Metacity bug, but are you sure you need a huge expression like that?" -#~ msgstr "" -#~ "Obrađivač izraza sa koordinatama je prepunio svoj bager, što je velika " -#~ "greška u metasitiju, ali da li stebaš sigurni da vam treba toliki izraz?" +#~ msgid "Mod5" +#~ msgstr "Mod5" diff --git a/po/sv.po b/po/sv.po index 1b988b838..c9bf18e7b 100644 --- a/po/sv.po +++ b/po/sv.po @@ -1,1671 +1,772 @@ -# Swedish messages for muffin. -# Copyright (C) 2001-2012 Free Software Foundation, Inc. +# Swedish messages for mutter. +# Copyright © 2001-2019 Free Software Foundation, Inc. # Christian Rose <menthos@menthos.com>, 2001, 2002, 2003, 2004, 2005. # Daniel Nylander <po@danielnylander.se>, 2006, 2007, 2008, 2009, 2010, 2011, 2012. +# Mattias Eriksson <snaggen@gmail.com>, 2014. +# Anders Jonsson <anders.jonsson@norsjovallen.se>, 2015, 2016, 2017, 2018, 2019. +# Sebastian Rasmussen <sebras@gmail.com>, 2016. # msgid "" msgstr "" -"Project-Id-Version: muffin\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-03-12 18:21+0100\n" -"PO-Revision-Date: 2012-03-12 18:26+0100\n" -"Last-Translator: Daniel Nylander <po@danielnylander.se>\n" +"Project-Id-Version: mutter\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2020-02-23 17:41+0000\n" +"PO-Revision-Date: 2020-03-02 19:49+0100\n" +"Last-Translator: Anders Jonsson <anders.jonsson@norsjovallen.se>\n" "Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n" "Language: sv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.3\n" -#: ../src/50-muffin-windows.xml.in.h:1 -msgid "Windows" -msgstr "Fönster" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Navigation" -#: ../src/50-muffin-windows.xml.in.h:2 -msgid "View split on left" -msgstr "Vy delad till vänster" +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Flytta fönster till arbetsyta 1" -#: ../src/50-muffin-windows.xml.in.h:3 -msgid "View split on right" -msgstr "Vy delad till höger" +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Flytta fönster till arbetsyta 2" -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format -msgid "Another compositing manager is already running on screen %i on display \"%s\"." -msgstr "En annan compositing-hanterare körs redan på skärm %i på display \"%s\"." +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Flytta fönster till arbetsyta 3" -#: ../src/core/bell.c:307 -msgid "Bell event" -msgstr "Ljudsignalhändelse" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Flytta fönster till arbetsyta 4" -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Okänd fråga efter fönsterinformation: %d" +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Flytta fönster till sista arbetsyta" -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> svarar inte." +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "Flytta fönster en arbetsyta uppåt" -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "Programmet svarar inte." +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "Flytta fönster en arbetsyta nedåt" -#: ../src/core/delete.c:119 -msgid "You may choose to wait a short while for it to continue or force the application to quit entirely." -msgstr "Du kan välja att vänta en kort stund på det för att fortsätta eller tvinga programmet att helt avslutas." +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "Flytta fönster en skärm åt vänster" -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "_Vänta" - -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "_Tvinga avslut" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "Flytta fönster en skärm åt höger" -#: ../src/core/display.c:361 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "Saknar %s-tillägg som krävs för kompositing" - -#: ../src/core/display.c:427 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Misslyckades med att öppna X Window System-displayen \"%s\"\n" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "Flytta fönster en skärm uppåt" -#: ../src/core/keybindings.c:852 -#, c-format -msgid "Some other program is already using the key %s with modifiers %x as a binding\n" -msgstr "Ett annat program använder redan tangenten %s med modifierarna %x som en bindning\n" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "Flytta fönster en skärm nedåt" -#: ../src/core/main.c:206 -msgid "Disable connection to session manager" -msgstr "Inaktivera anslutning till sessionshanteraren" - -#: ../src/core/main.c:212 -msgid "Replace the running window manager" -msgstr "Ersätt körande fönsterhanteraren" - -#: ../src/core/main.c:218 -msgid "Specify session management ID" -msgstr "Ange sessionshanteringsid" +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "Växla program" -#: ../src/core/main.c:223 -msgid "X Display to use" -msgstr "X-display att använda" +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "Växla till föregående program" -#: ../src/core/main.c:229 -msgid "Initialize session from savefile" -msgstr "Initiera session från sparandefil" +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "Växla fönster" -#: ../src/core/main.c:235 -msgid "Make X calls synchronous" -msgstr "Gör X-anrop synkrona" +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "Växla till föregående fönster" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Misslyckades med att genomsöka temakatalogen: %s\n" +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "Växla fönster för ett program" -#: ../src/core/main.c:520 -#, c-format -msgid "Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "Kunde inte hitta ett tema! Försäkra dig om att %s finns och innehåller vanliga teman.\n" +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "Växla till föregående fönster för ett program" -#: ../src/core/muffin.c:40 -#, c-format -msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" -msgstr "" -"muffin %s\n" -"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc. och andra\n" -"Det här är fri programvara; se källkoden för kopieringsvillkor.\n" -"Det finns INGA garantier; inte ens för SÄLJBARHET eller LÄMPLIGHET FÖR NÅGOT SPECIELLT ÄNDAMÅL.\n" +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "Växla systemkontroller" -#: ../src/core/muffin.c:54 -msgid "Print version" -msgstr "Skriv ut version" +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "Växla till föregående systemkontroll" -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "Kommaseparerad lista över compositor-instick" +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "Växla fönster direkt" -#: ../src/core/prefs.c:1077 -msgid "Workarounds for broken applications disabled. Some applications may not behave properly.\n" -msgstr "Fixar för trasiga program är inaktiverade. En del program fungerar kanske inte korrekt.\n" +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "Växla direkt till föregående fönster" -#: ../src/core/prefs.c:1152 -#, c-format -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "Kunde inte tolka typsnittsbeskrivningen \"%s\" från GSettings-nyckeln %s\n" +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "Växla fönster för ett program direkt" -#: ../src/core/prefs.c:1218 -#, c-format -msgid "\"%s\" found in configuration database is not a valid value for mouse button modifier\n" -msgstr "\"%s\" som hittades i konfigurationsdatabasen är inte ett giltigt värde för musknappsmodifierare\n" +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "Växla direkt till föregående fönster för ett program" -#: ../src/core/prefs.c:1739 -#, c-format -msgid "\"%s\" found in configuration database is not a valid value for keybinding \"%s\"\n" -msgstr "\"%s\" som hittades i konfigurationsdatabasen är inte ett giltigt värde för tangentbindningen \"%s\"\n" +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "Växla systemkontroller direkt" -#: ../src/core/prefs.c:1836 -#, c-format -msgid "Workspace %d" -msgstr "Arbetsyta %d" +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "Växla direkt till föregående systemkontroll" -#: ../src/core/screen.c:730 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "Skärm %d på display \"%s\" är ogiltig\n" +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "Dölj alla normala fönster" -#: ../src/core/screen.c:746 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager; try using the --replace option to replace the current window manager.\n" -msgstr "Skärm %d på display \"%s\" har redan en fönsterhanterare; försök med flaggan --replace för att ersätta den aktuella fönsterhanteraren.\n" +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "Växla till arbetsyta 1" -#: ../src/core/screen.c:773 -#, c-format -msgid "Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "Kunde inte få tag i fönsterhanterarval på skärm %d display \"%s\"\n" +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "Växla till arbetsyta 2" -#: ../src/core/screen.c:828 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "Skärm %d på display \"%s\" har redan en fönsterhanterare\n" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "Växla till arbetsyta 3" -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "Kunde inte släppa skärm %d på display \"%s\"\n" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "Växla till arbetsyta 4" -#: ../src/core/session.c:843 -#: ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Kunde inte skapa katalogen \"%s\": %s\n" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "Växla till sista arbetsyta" -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "Kunde inte öppna sessionsfilen \"%s\" för skrivning: %s\n" +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "Flytta till arbetsyta ovanför" -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Fel vid skrivning av sessionsfilen \"%s\": %s\n" +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "Flytta till arbetsyta nedanför" -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Fel vid stängning av sessionsfilen \"%s\": %s\n" +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "System" -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Misslyckades med att tolka sparad sessionsfil: %s\n" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Visa Kör kommando-dialogen" -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "<muffin_session>-attribut hittat men vi har redan sessions-ID" - -# SUN CHANGED MESSAGE -#: ../src/core/session.c:1198 -#: ../src/core/session.c:1273 -#: ../src/core/session.c:1305 -#: ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Okänt attribut %s i <%s>-element" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Visa aktivitetsöversikt" -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "nästlad <window>-tagg" +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Återställ tangentbordsgenvägarna" -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "Okänt element %s" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Fönster" -#: ../src/core/session.c:1809 -msgid "These windows do not support "save current setup" and will have to be restarted manually next time you log in." -msgstr "Dessa fönster saknar stöd för "spara nuvarande inställningar" och kommer att behöva startas om manuellt nästa gång du loggar in." +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "Aktivera fönstermenyn" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Misslyckades med att öppna felsökningslogg: %s\n" +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Växla helskärmsläge" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Misslyckades med att använda fdopen() på loggfilen %s: %s\n" +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "Växla maximeringstillstånd" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "Öppnade loggfilen %s\n" +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "Maximera fönster" -#: ../src/core/util.c:146 -#: ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "Muffin kompilerades utan stöd för utförligt läge\n" +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Återställ fönster" -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "Fönsterhanterare: " +#: data/50-mutter-windows.xml:18 +msgid "Close window" +msgstr "Stäng fönster" -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "Fel i fönsterhanterare: " +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "Dölj fönster" -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "Fönsterhanterarvarning: " +#: data/50-mutter-windows.xml:22 +msgid "Move window" +msgstr "Flytta fönster" -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "Fönsterhanterarfel: " +#: data/50-mutter-windows.xml:24 +msgid "Resize window" +msgstr "Ändra storlek på fönster" -#. first time through -#: ../src/core/window.c:7224 -#, c-format -msgid "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER window as specified in the ICCCM.\n" -msgstr "Fönstret %s ställer in SM_CLIENT_ID på sig själv, istället för på WM_CLIENT_LEADER-fönstret som är angivet i ICCCM.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7887 -#, c-format -msgid "Window %s sets an MWM hint indicating it isn't resizable, but sets min size %d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "Fönstret %s ställer in ett MWM-tips som anger att det inte går att ändra storlek på, men ställer in minsta storleken %d × %d och största storleken %d × %d; detta verkar inte vettigt.\n" +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "Växla fönster på alla arbetsytor eller bara en" -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "Programmet ställde in ett felaktigt _NET_WM_PID %lu\n" +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "Höj fönstret om det skyms av ett annat fönster, sänk det annars" -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (på %s)" +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "Höj fönstret över andra fönster" -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "Ogiltigt WM_TRANSIENT_FOR-fönster 0x%lx angivet för %s.\n" +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "Sänk fönster under andra fönster" -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "WM_TRANSIENT_FOR-fönstret 0x%lx för %s skulle skapa en loop.\n" +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "Maximera fönster vertikalt" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"Fönster 0x%lx har egenskap %s\n" -"som förväntades ha typen %s format %d\n" -"och har i verkligheten typ %s format %d n_items %d.\n" -"Det här är sannolikt ett programfel och inte ett fel i fönsterhanteraren.\n" -"Fönstret har titeln=\"%s\" klass=\"%s\" namn=\"%s\"\n" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "Maximera fönster horisontellt" -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "Egenskap %s på fönster 0x%lx innehöll ogiltig UTF-8\n" +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "Vy delad till vänster" -#: ../src/core/xprops.c:494 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "Egenskap %s på fönster 0x%lx innehöll ogiltig UTF-8 för objekt %d i listan\n" +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "Vy delad till höger" -#: ../src/muffin.desktop.in.h:1 -#: ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 +#: data/org.gnome.mutter.gschema.xml.in:7 msgid "Modifier to use for extended window management operations" msgstr "Modifierare att använda för utökade fönsterhanteringsåtgärder" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 -msgid "This key will initiate the \"overlay\", which is a combination window overview and application launching system. The default is intended to be the \"Windows key\" on PC hardware. It's expected that this binding either the default or set to the empty string." -msgstr "Denna nyckel kommer att initiera \"overlay\", som är en kombinerad fönsteröversikt och programstartare. Standard är tänkt att vara \"Windows-tangenten\" på PC-maskinvara. Det är förväntat att denna bindning antingen är standard eller inställd till en tom sträng." +#: data/org.gnome.mutter.gschema.xml.in:8 +msgid "" +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." +msgstr "" +"Denna nyckel kommer att initiera ”overlay”, som är en kombinerad " +"fönsteröversikt och programstartare. Standard är tänkt att vara ”Windows-" +"tangenten” på PC-maskinvara. Det är förväntat att denna bindning antingen är " +"standard eller inställd till en tom sträng." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 +#: data/org.gnome.mutter.gschema.xml.in:20 msgid "Attach modal dialogs" msgstr "Bifoga modala dialogfönster" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 -msgid "When true, instead of having independent titlebars, modal dialogs appear attached to the titlebar of the parent window and are moved together with the parent window." -msgstr "När true kommer, istället för oberoende titellistor, modala dialogfönster att visas anslutna till titellisten i föräldrafönstret och flyttas tillsammans med föräldrafönstret." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -msgid "Live Hidden Windows" -msgstr "Levande, dolda fönster" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 -msgid "Determines whether hidden windows (i.e., minimized windows and windows on other workspaces than the current one) should be kept alive." -msgstr "Bestämmer huruvida dolda fönster (t.ex., minimerade fönster och fönster på andra arbetsytor än den aktuella) ska hållas vid liv." +#: data/org.gnome.mutter.gschema.xml.in:21 +msgid "" +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." +msgstr "" +"När true kommer, istället för att ha oberoende namnlister, modala " +"dialogfönster att visas anslutna till namnlisten i föräldrafönstret och " +"flyttas tillsammans med föräldrafönstret." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 +#: data/org.gnome.mutter.gschema.xml.in:30 msgid "Enable edge tiling when dropping windows on screen edges" msgstr "Aktivera kantframhävning när fönster släpps på skärmkanter" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 -msgid "If enabled, dropping windows on vertical screen edges maximizes them vertically and resizes them horizontally to cover half of the available area. Dropping windows on the top screen edge maximizes them completely." -msgstr "Om aktiverad, släppa fönster på vertikala skärmkanter kommer att maximera dem vertikalt och storleksändra dem horisontellt till att täcka hälften av den tillgängliga ytan. Släppa fönster på övre skärmkanten maximerar dem helt." +#: data/org.gnome.mutter.gschema.xml.in:31 +msgid "" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." +msgstr "" +"Om aktiverad, släppa fönster på vertikala skärmkanter kommer att maximera " +"dem vertikalt och storleksändra dem horisontellt till att täcka hälften av " +"den tillgängliga ytan. Släppa fönster på övre skärmkanten maximerar dem helt." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 +#: data/org.gnome.mutter.gschema.xml.in:40 msgid "Workspaces are managed dynamically" msgstr "Arbetsytor hanteras dynamiskt" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 -msgid "Determines whether workspaces are managed dynamically or whether there's a static number of workspaces (determined by the num-workspaces key in org.cinnamon.desktop.wm.preferences)." -msgstr "Bestämmer huruvida arbetsytor hanteras dynamiskt eller huruvida det finns ett fast antal arbetsytor (bestäms av nyckeln num-workspaces i org.cinnamon.desktop.wm.preferences)." +#: data/org.gnome.mutter.gschema.xml.in:41 +msgid "" +"Determines whether workspaces are managed dynamically or whether there’s a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." +msgstr "" +"Bestämmer huruvida arbetsytor hanteras dynamiskt eller huruvida det finns " +"ett fast antal arbetsytor (bestäms av nyckeln num-workspaces i org.gnome." +"desktop.wm.preferences)." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 +#: data/org.gnome.mutter.gschema.xml.in:50 msgid "Workspaces only on primary" msgstr "Arbetsytor endast på primär" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 -msgid "Determines whether workspace switching should happen for windows on all monitors or only for windows on the primary monitor." -msgstr "Bestämmer huruvida arbetsyteväxling ska hända för alla fönster på alla skärmar eller endast för fönster på den primära skärmen." +#: data/org.gnome.mutter.gschema.xml.in:51 +msgid "" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." +msgstr "" +"Bestämmer huruvida arbetsyteväxling ska hända för alla fönster på alla " +"skärmar eller endast för fönster på den primära skärmen." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 +#: data/org.gnome.mutter.gschema.xml.in:59 msgid "No tab popup" msgstr "Ingen flik-popup" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 -msgid "Determines whether the use of popup and highlight frame should be disabled for window cycling." -msgstr "Bestämmer huruvida användning av popup och framhävning av kontur ska inaktiveras vid fönsterväxling." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 -msgid "Draggable border width" -msgstr "Dragbar rambredd" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 -msgid "The amount of total draggable borders. If the theme's visible borders are not enough, invisible borders will be added to meet this value." -msgstr "Mängd av totalt dragbara ramar. Om temats synliga ramar inte är tillräckliga kommer osynliga ramar att läggas till för att möta detta värde." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:17 -msgid "Select window from tab popup" -msgstr "Välj fönster från flik-popup" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:18 -msgid "Cancel tab popup" -msgstr "Avbryt flik-popup" - -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "Användning: %s\n" - -#: ../src/ui/frames.c:1158 -msgid "Close Window" -msgstr "Stäng fönster" - -#: ../src/ui/frames.c:1161 -msgid "Window Menu" -msgstr "Fönstermeny" - -#: ../src/ui/frames.c:1164 -msgid "Minimize Window" -msgstr "Minimera fönster" - -#: ../src/ui/frames.c:1167 -msgid "Maximize Window" -msgstr "Maximera fönster" - -#: ../src/ui/frames.c:1170 -msgid "Restore Window" -msgstr "Återställ fönster" - -#: ../src/ui/frames.c:1173 -msgid "Roll Up Window" -msgstr "Rulla upp fönstret" - -#: ../src/ui/frames.c:1176 -msgid "Unroll Window" -msgstr "Rulla tillbaka fönstret" - -#: ../src/ui/frames.c:1179 -msgid "Keep Window On Top" -msgstr "Behåll fönstret överst" - -#: ../src/ui/frames.c:1182 -msgid "Remove Window From Top" -msgstr "Ta bort överliggande fönster" - -#: ../src/ui/frames.c:1185 -msgid "Always On Visible Workspace" -msgstr "Alltid på synlig arbetsyta" - -#: ../src/ui/frames.c:1188 -msgid "Put Window On Only One Workspace" -msgstr "Placera fönstret på endast en arbetsyta" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "_Minimera" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "Ma_ximera" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "Avma_ximera" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "_Rulla upp" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "_Rulla ned" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "_Flytta" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "_Ändra storlek" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "Flytta titelrad på _skärm" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 -#: ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "Alltid _överst" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "Alltid på _synlig arbetsyta" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "_Endast på denna arbetsyta" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "Flytta till arbetsyta till _vänster" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "Flytta till arbetsyta till _höger" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "Flytta till arbetsyta _uppåt" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "Flytta till arbetsyta _nedanför" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "S_täng" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "Arbetsyta %d%n" - -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "Arbetsyta 1_0" - -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "Arbetsyta %s%d" - -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "Flytta till en annan _arbetsyta" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Skift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" - -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d × %d" - -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "överkant" - -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "nederkant" - -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "vänster" - -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "höger" - -#: ../src/ui/theme.c:286 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "ramgeometrin anger inte \"%s\"-dimension" - -#: ../src/ui/theme.c:305 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "ramgeometrin anger inte dimensionen \"%s\" för ramen \"%s\"" - -#: ../src/ui/theme.c:342 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "Knappförhållandet %g är inte rimligt" - -#: ../src/ui/theme.c:354 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "ramgeometrin anger inte storlek på knappar" - -#: ../src/ui/theme.c:1067 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "Toningarna bör ha minst två färger" - -#: ../src/ui/theme.c:1219 -#, c-format -msgid "GTK custom color specification must have color name and fallback in parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" -msgstr "Anpassad GTK-färgspecifikationen måste ha färgnamn och fallback inom paranteser, t.ex. gtk:custom(foo,bar); kunde inte tolka \"%s\"" - -#: ../src/ui/theme.c:1235 -#, c-format -msgid "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-_ are valid" -msgstr "Ogiltigt tecken \"%c\" i parametern color_name för gtk:custom, endast A-Za-z0-9-_ är giltiga" - -#: ../src/ui/theme.c:1249 -#, c-format -msgid "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not fit the format" -msgstr "Gtk:custom format är \"gtk:custom(color_name,fallback)\", \"%s\" passar inte formatet" - -#: ../src/ui/theme.c:1294 -#, c-format -msgid "GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "GTK-färgspecifikationen måste ha tillståndet inom klamrar, t.ex. gtk:fg[NORMAL], där NORMAL är tillståndet; kunde inte tolka \"%s\"" - -#: ../src/ui/theme.c:1308 -#, c-format -msgid "GTK color specification must have a close bracket after the state, e.g. gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "GTK-färgspecifikationen måste ha en stängningsklammer efter tillståndet, t.ex. gtk:fg[NORMAL], där NORMAL är tillståndet; kunde inte tolka \"%s\"" - -#: ../src/ui/theme.c:1319 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "Förstod inte tillståndet \"%s\" i färgspecifikation" - -#: ../src/ui/theme.c:1332 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "Förstod inte färgkomponenten \"%s\" i färgspecifikation" - -#: ../src/ui/theme.c:1361 -#, c-format -msgid "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the format" -msgstr "Blandningsformatet är \"blend/bg_color/fg_color/alpha\", \"%s\" passar inte med formatet" - -#: ../src/ui/theme.c:1372 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "Kunde inte tolka alfavärdet \"%s\" i blandad färg" +#: data/org.gnome.mutter.gschema.xml.in:60 +msgid "" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." +msgstr "" +"Bestämmer huruvida användning av popup och framhävning av kontur ska " +"inaktiveras vid fönsterväxling." -#: ../src/ui/theme.c:1382 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "Alfavärdet \"%s\" i blandad färg är inte mellan 0,0 och 1,0" +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Fördröj fokusändringar till muspekaren hålls still" -#: ../src/ui/theme.c:1429 -#, c-format -msgid "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "Skuggformatet är \"shade/base_color/factor\", \"%s\" passar inte med formatet" +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" +"Om satt till true (sant), och fokusläget är antingen ”sloppy” eller ”mouse” " +"kommer fokus inte att ändras omedelbart när muspekaren går in över ett " +"fönster, utan först efter att muspekaren slutar röra sig." -#: ../src/ui/theme.c:1440 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "Kunde inte tolka skuggfaktorn \"%s\" i skuggad färg" +#: data/org.gnome.mutter.gschema.xml.in:79 +msgid "Draggable border width" +msgstr "Dragbar rambredd" -#: ../src/ui/theme.c:1450 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "Skuggfaktorn \"%s\" i skuggad färg är negativ" +#: data/org.gnome.mutter.gschema.xml.in:80 +msgid "" +"The amount of total draggable borders. If the theme’s visible borders are " +"not enough, invisible borders will be added to meet this value." +msgstr "" +"Mängd av totalt dragbara ramar. Om temats synliga ramar inte är tillräckliga " +"kommer osynliga ramar att läggas till för att möta detta värde." -#: ../src/ui/theme.c:1479 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Kunde inte tolka färgen \"%s\"" +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "Automatiskt maximera fönster vars storlek ligger nära skärmens storlek" -#: ../src/ui/theme.c:1790 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "Koordinatuttrycket innehåller tecknet \"%s\" vilket inte är tillåtet" +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" +"Om aktiverad kommer nya fönster med nästan samma storlek som skärmen att bli " +"automatiskt maximerade." -#: ../src/ui/theme.c:1817 -#, c-format -msgid "Coordinate expression contains floating point number '%s' which could not be parsed" -msgstr "Koordinatuttrycket innehåller flyttalet \"%s\" som inte kunde tolkas" +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Placera nya fönster centrerat" -#: ../src/ui/theme.c:1831 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "Koordinatuttrycket innehåller heltalet \"%s\" som inte kunde tolkas" +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" +"När satt till \"true\", kommer nya fönster alltid att placeras centrerat på " +"den aktiva skärmen." -#: ../src/ui/theme.c:1953 -#, c-format -msgid "Coordinate expression contained unknown operator at the start of this text: \"%s\"" -msgstr "Koordinatuttrycket hade en okänd operand vid början av denna text: \"%s\"" +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Aktivera experimentella funktioner" -#: ../src/ui/theme.c:2010 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "Koordinatuttrycket var tomt eller förstods inte" +#: data/org.gnome.mutter.gschema.xml.in:108 +msgid "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes " +"mutter request a low priority real-time scheduling. The executable or user " +"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — " +"initializes Xwayland lazily if there are X11 clients. Requires restart." +msgstr "" +"För att aktivera experimentella funktioner, lägg till funktionens nyckelord " +"till listan. Huruvida funktionen kräver att kompositionshanteraren startas " +"om beror på den angivna funktionen. En experimentell funktion har inget krav " +"på sig att fortfarande vara tillgänglig eller konfigurerbar. Förvänta dig " +"inte att något som läggs till i denna inställning garanterat kommer att " +"fungera i framtiden. För närvarande möjliga nyckelord: • ”scale-monitor-" +"framebuffer” — gör så att mutter som standard använder en layout med logiska " +"skärmar i en rymd av logiska bildpunktskoordinater, medan skärmars " +"rambuffert skalas i stället för fönsterinnehållet, för att hantera HiDPI-" +"skärmar. Kräver inte en omstart. • ”rt-scheduler” — gör så att mutter " +"efterfrågar realtidsschemaläggning med låg prioritet. Den körbara filen " +"eller användaren måste ha CAP_SYS_NICE. Kräver en omstart. • ”autostart-" +"xwayland” — lat initiering av Xwayland om det finns X11-klienter. Kräver en " +"omstart." + +#: data/org.gnome.mutter.gschema.xml.in:134 +msgid "Modifier to use to locate the pointer" +msgstr "Modifierare att använda för att hitta muspekaren" + +#: data/org.gnome.mutter.gschema.xml.in:135 +msgid "This key will initiate the “locate pointer” action." +msgstr "Denna tangent kommer att initiera åtgärden ”hitta muspekare”." + +#: data/org.gnome.mutter.gschema.xml.in:142 +msgid "Timeout for check-alive ping" +msgstr "Tidsgräns för åtkomlighetstest med ping" + +#: data/org.gnome.mutter.gschema.xml.in:143 +msgid "" +"Number of milliseconds a client has to respond to a ping request in order to " +"not be detected as frozen. Using 0 will disable the alive check completely." +msgstr "" +"Antal millisekunder som en klient har på sig att svara på en pingförfrågan " +"för att inte anses vara frusen. Att använda 0 kommer inaktivera kontrollen " +"helt." -#: ../src/ui/theme.c:2121 -#: ../src/ui/theme.c:2131 -#: ../src/ui/theme.c:2165 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "Koordinatuttrycket resulterar i division med noll" +#: data/org.gnome.mutter.gschema.xml.in:165 +msgid "Select window from tab popup" +msgstr "Välj fönster från flik-popup" -#: ../src/ui/theme.c:2173 -#, c-format -msgid "Coordinate expression tries to use mod operator on a floating-point number" -msgstr "Koordinatuttrycket försöker använda mod-operator på ett flyttal" +#: data/org.gnome.mutter.gschema.xml.in:170 +msgid "Cancel tab popup" +msgstr "Avbryt flik-popup" -#: ../src/ui/theme.c:2229 -#, c-format -msgid "Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "Koordinatuttrycket har en operator \"%s\" där en operand förväntades" +#: data/org.gnome.mutter.gschema.xml.in:175 +msgid "Switch monitor configurations" +msgstr "Växla skärmkonfiguration" -#: ../src/ui/theme.c:2238 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "Koordinatuttrycket hade en operand där en operator förväntades" +#: data/org.gnome.mutter.gschema.xml.in:180 +msgid "Rotates the built-in monitor configuration" +msgstr "Roterar den inbyggda skärmkonfigurationen" -#: ../src/ui/theme.c:2246 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "Koordinatuttrycket slutade med en operator istället för en operand" +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Växla till VT 1" -#: ../src/ui/theme.c:2256 -#, c-format -msgid "Coordinate expression has operator \"%c\" following operator \"%c\" with no operand in between" -msgstr "Koordinatuttrycket har en operator \"%c\" som följer på operatorn \"%c\" utan någon operand imellan" +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Växla till VT 2" -#: ../src/ui/theme.c:2407 -#: ../src/ui/theme.c:2452 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "Koordinatuttrycket hade en okänd variabel eller konstant \"%s\"" +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Växla till VT 3" -#: ../src/ui/theme.c:2506 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "Koordinatuttryckstolkaren överflödade sin buffert." +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Växla till VT 4" -#: ../src/ui/theme.c:2535 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "Koordinatuttrycket hade en stängningsparentes utan någon öppningsparentes" +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Växla till VT 5" -#: ../src/ui/theme.c:2599 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "Koordinatuttrycket hade en öppningsparentes utan någon stängningsparentes" +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Växla till VT 6" -#: ../src/ui/theme.c:2610 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "Koordinatuttrycket verkar inte ha några operatorer eller operander" +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Växla till VT 7" -#: ../src/ui/theme.c:2822 -#: ../src/ui/theme.c:2842 -#: ../src/ui/theme.c:2862 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "Temat innehöll ett uttryck som resulterade i ett fel: %s\n" +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Växla till VT 8" -#: ../src/ui/theme.c:4533 -#, c-format -msgid "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be specified for this frame style" -msgstr "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> måste anges för denna ramtyp" +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Växla till VT 9" -#: ../src/ui/theme.c:5066 -#: ../src/ui/theme.c:5091 -#, c-format -msgid "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "<frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/> saknas" +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Växla till VT 10" -#: ../src/ui/theme.c:5139 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Misslyckades med att läsa in temat \"%s\": %s\n" - -#: ../src/ui/theme.c:5275 -#: ../src/ui/theme.c:5282 -#: ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 -#: ../src/ui/theme.c:5303 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "Inget <%s> angivet för temat \"%s\"" +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Växla till VT 11" -#: ../src/ui/theme.c:5311 -#, c-format -msgid "No frame style set for window type \"%s\" in theme \"%s\", add a <window type=\"%s\" style_set=\"whatever\"/> element" -msgstr "Ingen ramstil angiven för fönstertypen \"%s\" i temat \"%s\", lägg till ett <window type=\"%s\" style_set=\"whatever\"/>-element" +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Växla till VT 12" -#: ../src/ui/theme.c:5709 -#: ../src/ui/theme.c:5771 -#: ../src/ui/theme.c:5834 -#, c-format -msgid "User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "Användardefinierade konstanter måste börja med en stor bokstav; \"%s\" gör det inte" +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "Återaktivera genvägar" -#: ../src/ui/theme.c:5717 -#: ../src/ui/theme.c:5779 -#: ../src/ui/theme.c:5842 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "Konstanten \"%s\" har redan definierats" +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow X11 grabs to lock keyboard focus with Xwayland" +msgstr "Tillåt X11-fångster att låsa tangentbordsfokus med Xwayland" -# SUN CHANGED MESSAGE -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 +msgid "" +"Allow all keyboard events to be routed to X11 “override redirect” windows " +"with a grab when running in Xwayland. This option is to support X11 clients " +"which map an “override redirect” window (which do not receive keyboard " +"focus) and issue a keyboard grab to force all keyboard events to that " +"window. This option is seldom used and has no effect on regular X11 windows " +"which can receive keyboard focus under normal circumstances. For a X11 grab " +"to be taken into account under Wayland, the client must also either send a " +"specific X11 ClientMessage to the root window or be among the applications " +"white-listed in key “xwayland-grab-access-rules”." +msgstr "" +"Tillåt alla tangentbordshändelser att ledas till ”override redirect”-fönster " +"i X11 med en fångst vid körning i Xwayland. Detta alternativ är för att " +"stödja X11-klienter som mappar ett ”override redirect”-fönster (som inte " +"erhåller tangentbordsfokus) och utfärda en tangentbordsfångst för att tvinga " +"alla tangentbordshändelser till det fönstret. Detta alternativ används " +"sällan och har ingen effekt på vanliga X11-fönster som kan erhålla " +"tangentbordsfokus under normala förhållanden. För att en X11-fångst ska tas " +"i beräkning under Wayland måste klienten också antingen sända ett specifikt " +"X11-ClientMessage till root-fönstret eller finnas bland programmen som " +"vitlistats i nyckeln ”xwayland-grab-access-rules”." + +#: data/org.gnome.mutter.wayland.gschema.xml.in:84 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "Xwayland-program tillåts utfärda tangentbordsfångster" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:85 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "" +"Lista resursnamnen eller resursklassen för X11-fönster som antingen tillåts " +"eller inte tillåts att utfärda X11-tangentbordsfångster under Xwayland. " +"Resursnamnet eller resursklassen för ett givet X11-fönster kan erhållas " +"genom att använda kommandot ”xprop WM_CLASS”. Stöd finns för att använda " +"jokertecknen ”*” och ”?” i värdena. Värden som startar med ”!” svartlistas, " +"vilket företräde över vitlistan, för att upphäva program i " +"standardsystemlistan. Standardsystemlistan innehåller följande program: " +"”@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Användare kan bryta en befintlig " +"fångst genom att använda den specifika tangentbordsgenvägen som definieras " +"av tangentbindningsnyckeln ”restore-shortcuts”." + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. #. -#: ../src/ui/theme-parser.c:236 +#: src/backends/meta-input-settings.c:2567 #, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "Inget \"%s\"-attribut i element <%s>" +msgid "Mode Switch (Group %d)" +msgstr "Lägesväxel (grupp %d)" -#: ../src/ui/theme-parser.c:265 -#: ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Rad %d tecken %d: %s" - -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "Attributet \"%s\" upprepat två gånger på samma <%s>-element" - -# SUN CHANGED MESSAGE -#: ../src/ui/theme-parser.c:503 -#: ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "Attributet \"%s\" är ogiltigt i <%s>-element i detta sammanhang" - -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "Kunde inte tolka \"%s\" som ett heltal" - -#: ../src/ui/theme-parser.c:603 -#: ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "Förstod inte de avslutande tecknen \"%s\" i strängen \"%s\"" - -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "Heltalet %ld måste vara positivt" - -# SUN CHANGED MESSAGE -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "Heltalet %ld är för stort, aktuellt maxvärde är %d" - -#: ../src/ui/theme-parser.c:649 -#: ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "Kunde inte tolka \"%s\" som ett flyttal" - -#: ../src/ui/theme-parser.c:680 -#: ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "Booleska värden måste vara \"true\" eller \"false\", inte \"%s\"" - -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "Vinkeln måste vara mellan 0,0 och 360,0, var %g\n" - -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "Alfavärdet måste vara mellan 0,0 (osynligt) och 1,0 (helt synligt), var %g\n" - -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium,large,x-large,xx-large)\n" -msgstr "Ogiltig titelskala \"%s\" (måste vara ett av xx-small,x-small,small,medium,large,x-large,xx-large)\n" - -#: ../src/ui/theme-parser.c:1019 -#: ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 -#: ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s>-namnet \"%s\" använt en andra gång" - -#: ../src/ui/theme-parser.c:1031 -#: ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "<%s>-föräldern \"%s\" har inte definierats" - -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "<%s>-geometrin \"%s\" har inte definierats" - -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "<%s> måste ange antingen en geometri eller en förälder som har en geometri" - -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "Du måste ange en bakgrund för att ett alfavärde ska vara meningsfullt" - -# SUN CHANGED MESSAGE -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Okänd typ \"%s\" i <%s>-element" - -# SUN CHANGED MESSAGE -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "Okänt style_set \"%s\" i <%s>-element" - -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "Fönstertypen \"%s\" har redan tilldelats en stilsamling" - -#: ../src/ui/theme-parser.c:1313 -#: ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 -#: ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 -#: ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 -#: ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 -#: ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "Elementet <%s> är inte tillåtet under <%s>" - -#: ../src/ui/theme-parser.c:1427 -#: ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" for buttons" -msgstr "Kan inte ange både \"button_width\"/\"button_height\" och \"aspect_ratio\" för knappar" - -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "Avståndet \"%s\" är okänt" - -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "Förhållandet \"%s\" är okänt" - -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "Ramen \"%s\" är okänd" - -# SUN CHANGED MESSAGE -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "Inget \"start_angle\"- eller \"from\"-attribut i element <%s>" - -# SUN CHANGED MESSAGE -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "Inget \"extent_angle\"- eller \"to\"-attribut i element <%s>" - -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "Förstod inte värdet \"%s\" för toningstyp" - -#: ../src/ui/theme-parser.c:2193 -#: ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "Förstod inte fyllnadstypen \"%s\" för <%s>-element" - -#: ../src/ui/theme-parser.c:2360 -#: ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "Förstod inte tillståndet \"%s\" för <%s>-element" - -#: ../src/ui/theme-parser.c:2370 -#: ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "Förstod inte skuggan \"%s\" för <%s>-element" - -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "Förstod inte pilen \"%s\" för <%s>-element" - -#: ../src/ui/theme-parser.c:2694 -#: ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "Inget <draw_ops> anropat \"%s\" har definierats" - -#: ../src/ui/theme-parser.c:2706 -#: ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "Att inkludera draw_ops \"%s\" här skulle skapa en cirkulärreferens" - -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Okänd position \"%s\" för ramdel" - -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "Ramstilen har redan en del vid position %s" - -#: ../src/ui/theme-parser.c:2942 -#: ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "Inget <draw_ops> med namnet \"%s\" har definierats" - -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Okänd funktion \"%s\" för knapp" - -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "Knappfunktionen \"%s\" finns inte i den här versionen (%d, behöver %d)" - -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Okänt tillstånd \"%s\" för knapp" +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2590 +msgid "Switch monitor" +msgstr "Växla skärm" -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "Ramstilen har redan en knapp för funktionen %s tillstånd %s" +#: src/backends/meta-input-settings.c:2592 +msgid "Show on-screen help" +msgstr "Visa hjälp på skärmen" -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "\"%s\" är inte ett tillåtet värde för fokusattribut" +#: src/backends/meta-monitor.c:223 +msgid "Built-in display" +msgstr "Inbyggd display" -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "\"%s\" är inte ett giltigt värde på tillståndsattribut" +#: src/backends/meta-monitor.c:252 +msgid "Unknown" +msgstr "Okänd" -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "En stil med namnet \"%s\" har inte definierats" +#: src/backends/meta-monitor.c:254 +msgid "Unknown Display" +msgstr "Okänd display" -#: ../src/ui/theme-parser.c:3113 -#: ../src/ui/theme-parser.c:3136 +#: src/backends/meta-monitor.c:262 #, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "\"%s\" är inte ett giltigt värde för storleksändringsattribut" +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" -# SUN CHANGED MESSAGE -#: ../src/ui/theme-parser.c:3147 +#: src/backends/meta-monitor.c:270 #, c-format -msgid "Should not have \"resize\" attribute on <%s> element for maximized/shaded states" -msgstr "Bör inte ha \"resize\"-attribut i <%s>-element för maximerad/upprullat tillstånd" +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" -# SUN CHANGED MESSAGE -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "Bör inte ha \"resize\"-attribut i <%s>-element för maximerade tillstånd" +#. Translators: this string will appear in Sysprof +#: src/backends/meta-profiler.c:79 +msgid "Compositor" +msgstr "Kompositionshanterare" -#: ../src/ui/theme-parser.c:3175 -#: ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "Stilen har redan angivits för tillståndet %s storleksändring %s fokus %s" - -#: ../src/ui/theme-parser.c:3186 -#: ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 -#: ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 -#: ../src/ui/theme-parser.c:3255 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:533 #, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "Stilen har redan angivits för tillståndet %s fokus %s" - -#: ../src/ui/theme-parser.c:3294 -msgid "Can't have a two draw_ops for a <piece> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "Kan inte ha två draw_ops för ett <piece>-element (temat angav ett draw_ops-attribut och även ett <draw_ops>-element, eller angav två element)" - -#: ../src/ui/theme-parser.c:3332 -msgid "Can't have a two draw_ops for a <button> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "Kan inte ha två draw_ops för ett <button>-element (temat angav ett draw_ops-attribut och även ett <draw_ops>-element, eller angav två element)" - -#: ../src/ui/theme-parser.c:3370 -msgid "Can't have a two draw_ops for a <menu_icon> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "Kan inte ha två draw_ops för ett <menu_icon>-element (temat angav ett draw_ops-attribut och även ett <draw_ops>-element, eller angav två element)" +msgid "" +"Another compositing manager is already running on screen %i on display “%s”." +msgstr "En annan kompositionshanterare körs redan på skärm %i på display ”%s”." -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "Felaktig versionsangivelse \"%s\"" +#: src/core/bell.c:192 +msgid "Bell event" +msgstr "Ljudsignalhändelse" -#: ../src/ui/theme-parser.c:3507 -msgid "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-theme-2.xml" -msgstr "\"version\"-attribut får inte användas i metacity-theme-1.xml eller metacity-theme-2.xml" +#: src/core/main.c:190 +msgid "Disable connection to session manager" +msgstr "Inaktivera anslutning till sessionshanteraren" -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "Temat kräver version %s men senaste temaversionen som stöds är %d.%d" +#: src/core/main.c:196 +msgid "Replace the running window manager" +msgstr "Ersätt körande fönsterhanteraren" -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "Yttersta elementet i temat måste vara <metacity_theme>, inte <%s>" +#: src/core/main.c:202 +msgid "Specify session management ID" +msgstr "Ange sessionshanteringsid" -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "Element <%s> is not allowed inside a name/author/date/description element" -msgstr "Elementet <%s> är inte tillåtet inuti ett namn-/författare-/datum-/beskrivningselement" +#: src/core/main.c:207 +msgid "X Display to use" +msgstr "X-display att använda" -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "Elementet <%s> är inte tillåtet inuti ett <constant>-element" +#: src/core/main.c:213 +msgid "Initialize session from savefile" +msgstr "Initiera session från sparandefil" -#: ../src/ui/theme-parser.c:3599 -#, c-format -msgid "Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "Elementet <%s> är inte tillåtet inuti ett avstånds-/ram-/förhållandeelement" +#: src/core/main.c:219 +msgid "Make X calls synchronous" +msgstr "Gör X-anrop synkrona" -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "Elementet <%s> är inte tillåtet inuti ett ritningsåtgärdselement" +#: src/core/main.c:226 +msgid "Run as a wayland compositor" +msgstr "Kör som en wayland-kompositionshanterare" -#: ../src/ui/theme-parser.c:3631 -#: ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 -#: ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "Elementet <%s> är inte tillåtet inuti ett <%s>-element" +#: src/core/main.c:232 +msgid "Run as a nested compositor" +msgstr "Kör som en nästlad kompositionshanterare" -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "Inget draw_ops tillhandahålls för ramdel" +#: src/core/main.c:238 +msgid "Run wayland compositor without starting Xwayland" +msgstr "Kör wayland-kompositionshanteraren utan att starta Xwayland" -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "Inget draw_ops tillhandahålls för knappen" +#: src/core/main.c:246 +msgid "Run as a full display server, rather than nested" +msgstr "Kör som en full display-tjänst, i stället för nästlad" -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "Ingen text är tillåten inuti elementet <%s>" - -#: ../src/ui/theme-parser.c:4026 -#: ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 -#: ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "<%s> är angiven två gånger för detta tema" +#: src/core/main.c:252 +msgid "Run with X11 backend" +msgstr "Kör med X11-gränssnitt" -#: ../src/ui/theme-parser.c:4348 +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:151 #, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Misslyckades med att hitta en giltig fil för temat %s\n" - -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "_Fönster" - -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "_Dialogruta" - -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "_Modalt dialogfönster" - -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "Ver_ktyg" - -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "_Startbild" - -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "_Övre docka" - -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "_Nedre docka" - -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "_Vänster docka" - -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "_Höger docka" - -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "_Alla dockor" - -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "Skriv_bord" +msgid "“%s” is not responding." +msgstr "”%s” svarar inte." -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "Öppna ytterligare ett över dessa fönster" +#: src/core/meta-close-dialog-default.c:153 +msgid "Application is not responding." +msgstr "Programmet svarar inte." -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "Detta är en exempelknapp med en \"öppna\"-ikon" +#: src/core/meta-close-dialog-default.c:158 +msgid "" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." +msgstr "" +"Du kan välja att vänta en kort stund på det för att fortsätta eller tvinga " +"programmet att helt avslutas." -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "Detta är en exempelknapp med en \"avsluta\"-ikon" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Force Quit" +msgstr "_Tvinga avslut" -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "Detta är ett exempelmeddelande i en exempelkatalog" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Wait" +msgstr "_Vänta" -#: ../src/ui/theme-viewer.c:328 +#: src/core/mutter.c:38 #, c-format -msgid "Fake menu item %d\n" -msgstr "Falskt menyobjekt %d\n" - -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "Fönster med endast ram" - -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "Rad" - -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "Normalt programfönster" - -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "Dialogruta" - -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "Modalt dialogfönster" - -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "Verktygspalett" - -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "Avtagen meny" - -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "Ram" +msgid "" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" +msgstr "" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc. och andra\n" +"Det här är fri programvara; se källkoden för kopieringsvillkor.\n" +"Det finns INGA garantier; inte ens för SÄLJBARHET eller LÄMPLIGHET FÖR NÅGOT " +"SPECIELLT ÄNDAMÅL.\n" -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "Bifogat modalt dialogfönster" +#: src/core/mutter.c:52 +msgid "Print version" +msgstr "Skriv ut version" -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "Test %d av knapplayout" +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "Mutter-insticksmodul att använda" -#: ../src/ui/theme-viewer.c:768 +#: src/core/prefs.c:1911 #, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g millisekunder för att rita en fönsterram" +msgid "Workspace %d" +msgstr "Arbetsyta %d" -#: ../src/ui/theme-viewer.c:813 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Användning: metacity-theme-viewer [TEMANAMN]\n" +#: src/core/util.c:122 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter kompilerades utan stöd för utförligt läge\n" -#: ../src/ui/theme-viewer.c:820 +#: src/wayland/meta-wayland-tablet-pad.c:568 #, c-format -msgid "Error loading theme: %s\n" -msgstr "Fel vid inläsning av tema: %s\n" +msgid "Mode Switch: Mode %d" +msgstr "Lägesväxel: Läge %d" -#: ../src/ui/theme-viewer.c:826 +#: src/x11/meta-x11-display.c:676 #, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "Läste in temat \"%s\" på %g sekunder\n" - -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "Normalt titeltypsnitt" - -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "Litet titeltypsnitt" - -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "Stort titeltypsnitt" - -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "Knapplayouter" - -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "Prestandatest" - -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "Fönstertitel hamnar här" - -#: ../src/ui/theme-viewer.c:1047 -#, c-format -msgid "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g seconds wall clock time including X server resources (%g milliseconds per frame)\n" -msgstr "Ritade %d ramar på %g sekunder på klientsidan (%g millisekunder per ram) och %g sekunder väggklockstid inklusive X-serverresurser (%g millisekunder per ram)\n" - -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "test av positionsuttryck returnerade SANT men satte fel" - -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "test av positionsuttryck returnerade FALSKT men satte inte fel" +msgid "" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." +msgstr "" +"Display ”%s” har redan en fönsterhanterare; försök med flaggan --replace för " +"att ersätta den aktuella fönsterhanteraren." -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "Fel förväntades men gavs inte" +#: src/x11/meta-x11-display.c:1089 +msgid "Failed to initialize GDK\n" +msgstr "Misslyckades med att initiera GDK\n" -#: ../src/ui/theme-viewer.c:1274 +#: src/x11/meta-x11-display.c:1113 #, c-format -msgid "Error %d was expected but %d given" -msgstr "Fel %d förväntades men %d givet" +msgid "Failed to open X Window System display “%s”\n" +msgstr "Misslyckades med att öppna X Window System-displayen ”%s”\n" -#: ../src/ui/theme-viewer.c:1280 +#: src/x11/meta-x11-display.c:1196 #, c-format -msgid "Error not expected but one was returned: %s" -msgstr "Fel förväntades inte men ett returnerades: %s" +msgid "Screen %d on display “%s” is invalid\n" +msgstr "Skärm %d på display ”%s” är ogiltig\n" -#: ../src/ui/theme-viewer.c:1284 +#: src/x11/meta-x11-selection-input-stream.c:460 #, c-format -msgid "x value was %d, %d was expected" -msgstr "x-värdet var %d, %d förväntades" +msgid "Format %s not supported" +msgstr "Formatet %s stöds ej" -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "y-värdet var %d, %d förväntades" +#: src/x11/session.c:1821 +msgid "" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." +msgstr "" +"Dessa fönster saknar stöd för ”spara nuvarande inställningar” och kommer att " +"behöva startas om manuellt nästa gång du loggar in." -#: ../src/ui/theme-viewer.c:1352 +#: src/x11/window-props.c:569 #, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "%d koordinatuttryck tolkades på %g sekunder (%g sekunder i medelvärde)\n" - -#~ msgid "Switch to workspace 1" -#~ msgstr "Växla till arbetsyta 1" - -#~ msgid "Switch to workspace 2" -#~ msgstr "Växla till arbetsyta 2" - -#~ msgid "Switch to workspace 3" -#~ msgstr "Växla till arbetsyta 3" - -#~ msgid "Switch to workspace 4" -#~ msgstr "Växla till arbetsyta 4" - -#~ msgid "Switch to workspace 5" -#~ msgstr "Växla till arbetsyta 5" - -#~ msgid "Switch to workspace 6" -#~ msgstr "Växla till arbetsyta 6" - -#~ msgid "Switch to workspace 7" -#~ msgstr "Växla till arbetsyta 7" - -#~ msgid "Switch to workspace 8" -#~ msgstr "Växla till arbetsyta 8" - -#~ msgid "Switch to workspace 9" -#~ msgstr "Växla till arbetsyta 9" - -#~ msgid "Switch to workspace 10" -#~ msgstr "Växla till arbetsyta 10" - -#~ msgid "Switch to workspace 11" -#~ msgstr "Växla till arbetsyta 11" - -#~ msgid "Switch to workspace 12" -#~ msgstr "Växla till arbetsyta 12" - -#~ msgid "Switch to workspace on the left of the current workspace" -#~ msgstr "Växla till arbetsytan till vänster om den aktuella arbetsytan" - -#~ msgid "Switch to workspace on the right of the current workspace" -#~ msgstr "Växla till arbetsytan till höger om den aktuella arbetsytan" - -#~ msgid "Switch to workspace above the current workspace" -#~ msgstr "Växla till arbetsytan ovanför den aktuella arbetsytan" - -#~ msgid "Switch to workspace below the current workspace" -#~ msgstr "Växla till arbetsytan nedanför den aktuella arbetsytan" - -#~ msgid "Move between windows of an application, using a popup window" -#~ msgstr "Flytta mellan ett programs fönster med ett popupfönster" - -#~ msgid "" -#~ "Move backward between windows of an application, using a popup window" -#~ msgstr "" -#~ "Flytta baklänges mellan ett programs fönster, med hjälp av ett " -#~ "popupfönster" - -#~ msgid "Move between windows, using a popup window" -#~ msgstr "Flytta mellan fönster genom ett popupfönster" - -#~ msgid "Move backward between windows, using a popup window" -#~ msgstr "Flytta baklänges mellan fönster, med hjälp av ett popupfönster" - -#~ msgid "Move between panels and the desktop, using a popup window" -#~ msgstr "Flytta mellan paneler och skrivbordet med ett popupfönster" - -#~ msgid "Move backward between panels and the desktop, using a popup window" -#~ msgstr "" -#~ "Flytta baklänges mellan paneler och skrivbordet, med hjälp av ett " -#~ "popupfönster" - -#~ msgid "Move between windows of an application immediately" -#~ msgstr "Flytta mellan ett programs fönster omedelbart" - -#~ msgid "Move backward between windows of an application immediately" -#~ msgstr "Flytta baklänges mellan ett programs fönster omedelbart" - -#~ msgid "Move between windows immediately" -#~ msgstr "Flytta mellan fönster omedelbart" - -#~ msgid "Move backward between windows immediately" -#~ msgstr "Flytta baklänges mellan fönster omedelbart" - -#~ msgid "Move between panels and the desktop immediately" -#~ msgstr "Flytta mellan paneler och skrivbordet omedelbart" - -#~ msgid "Move backward between panels and the desktop immediately" -#~ msgstr "Flytta baklänges mellan paneler och skrivbordet omedelbart" - -#~ msgid "Hide all normal windows and set focus to the desktop" -#~ msgstr "Dölj alla normala fönster och fokusera skrivbordet" - -#~ msgid "Show the panel's main menu" -#~ msgstr "Visa panelens huvudmeny" - -#~ msgid "Show the panel's \"Run Application\" dialog box" -#~ msgstr "Visa panelens \"Kör program\"-dialogruta" - -#~ msgid "Start or stop recording the session" -#~ msgstr "Starta eller stoppa inspelning av sessionen" - -#~ msgid "Take a screenshot" -#~ msgstr "Ta en skärmdump" - -#~ msgid "Take a screenshot of a window" -#~ msgstr "Ta en skärmdump av ett fönster" - -#~ msgid "Run a terminal" -#~ msgstr "Kör en terminal" - -#~ msgid "Activate the window menu" -#~ msgstr "Aktivera fönstermenyn" - -#~ msgid "Toggle fullscreen mode" -#~ msgstr "Växla helskärmsläge" - -#~ msgid "Toggle maximization state" -#~ msgstr "Växla maximeringstillstånd" - -#~ msgid "Toggle whether a window will always be visible over other windows" -#~ msgstr "" -#~ "Växla huruvida ett fönster alltid kommer att vara synlig över andra " -#~ "fönster" - -#~ msgid "Maximize window" -#~ msgstr "Maximera fönster" - -#~ msgid "Restore window" -#~ msgstr "Återställ fönster" - -#~ msgid "Toggle shaded state" -#~ msgstr "Växla upprullat tillstånd" - -#~ msgid "Minimize window" -#~ msgstr "Minimera fönster" - -#~ msgid "Close window" -#~ msgstr "Stäng fönster" - -#~ msgid "Move window" -#~ msgstr "Flytta fönster" - -#~ msgid "Resize window" -#~ msgstr "Ändra storlek på fönster" - -#~ msgid "Toggle whether window is on all workspaces or just one" -#~ msgstr "Växla huruvida fönstret finns på alla arbetsytor eller bara en" - -#~ msgid "Move window to workspace 1" -#~ msgstr "Flytta fönster till arbetsyta 1" - -#~ msgid "Move window to workspace 2" -#~ msgstr "Flytta fönster till arbetsyta 2" - -#~ msgid "Move window to workspace 3" -#~ msgstr "Flytta fönster till arbetsyta 3" - -#~ msgid "Move window to workspace 4" -#~ msgstr "Flytta fönster till arbetsyta 4" - -#~ msgid "Move window to workspace 5" -#~ msgstr "Flytta fönster till arbetsyta 5" - -#~ msgid "Move window to workspace 6" -#~ msgstr "Flytta fönster till arbetsyta 6" - -#~ msgid "Move window to workspace 7" -#~ msgstr "Flytta fönster till arbetsyta 7" - -#~ msgid "Move window to workspace 8" -#~ msgstr "Flytta fönster till arbetsyta 8" - -#~ msgid "Move window to workspace 9" -#~ msgstr "Flytta fönster till arbetsyta 9" - -#~ msgid "Move window to workspace 10" -#~ msgstr "Flytta fönster till arbetsyta 10" - -#~ msgid "Move window to workspace 11" -#~ msgstr "Flytta fönster till arbetsyta 11" - -#~ msgid "Move window to workspace 12" -#~ msgstr "Flytta fönster till arbetsyta 12" +msgid "%s (on %s)" +msgstr "%s (på %s)" #~ msgid "Move window one workspace to the left" #~ msgstr "Flytta fönster en arbetsyta åt vänster" @@ -1673,160 +774,11 @@ msgstr "%d koordinatuttryck tolkades på %g sekunder (%g sekunder i medelvärde) #~ msgid "Move window one workspace to the right" #~ msgstr "Flytta fönster en arbetsyta åt höger" -#~ msgid "Move window one workspace up" -#~ msgstr "Flytta fönster en arbetsyta uppåt" - -#~ msgid "Move window one workspace down" -#~ msgstr "Flytta fönster en arbetsyta nedåt" - -#~ msgid "Raise window if it's covered by another window, otherwise lower it" -#~ msgstr "Höj fönstret om det skyms av ett annat fönster, sänk det annars" - -#~ msgid "Raise window above other windows" -#~ msgstr "Höj fönstret över andra fönster" +#~ msgid "Move to workspace left" +#~ msgstr "Flytta till arbetsyta till vänster" -#~ msgid "Lower window below other windows" -#~ msgstr "Sänk fönster under andra fönster" - -#~ msgid "Maximize window vertically" -#~ msgstr "Maximera fönster vertikalt" +#~ msgid "Move to workspace right" +#~ msgstr "Flytta till arbetsyta till höger" -#~ msgid "Maximize window horizontally" -#~ msgstr "Maximera fönster horisontellt" - -#~ msgid "Move window to north-west (top left) corner" -#~ msgstr "Flytta fönstret till nordvästra (övre vänstra) hörnet" - -#~ msgid "Move window to north-east (top right) corner" -#~ msgstr "Flytta fönstret till nordöstra (övre högra) hörnet" - -#~ msgid "Move window to south-west (bottom left) corner" -#~ msgstr "Flytta fönstret till sydvästra (nedre vänstra) hörnet" - -#~ msgid "Move window to south-east (bottom right) corner" -#~ msgstr "Flytta fönstret till sydöstra (nedre högra) hörnet" - -#~ msgid "Move window to north (top) side of screen" -#~ msgstr "Flytta fönstret till norra (övre) sidan av skärmen" - -#~ msgid "Move window to south (bottom) side of screen" -#~ msgstr "Flytta fönstret till södra (nedre) sidan av skärmen" - -#~ msgid "Move window to east (right) side of screen" -#~ msgstr "Flytta fönstret till östra (högra) sidan av skärmen" - -#~ msgid "Move window to west (left) side of screen" -#~ msgstr "Flytta fönstret till västra (vänster) sidan av skärmen" - -#~ msgid "Move window to center of screen" -#~ msgstr "Flytta fönstret till mitten av skärmen" - -#~ msgid "" -#~ "There was an error running <tt>%s</tt>:\n" -#~ "\n" -#~ "%s" -#~ msgstr "" -#~ "Ett fel uppstod vid körning av <tt>%s</tt>:\n" -#~ "\n" -#~ "%s" - -#~ msgid "No command %d has been defined.\n" -#~ msgstr "Inget kommando %d har definierats.\n" - -#~ msgid "No terminal command has been defined.\n" -#~ msgstr "Inget terminalkommando har definierats.\n" - -#~ msgid "GConf key '%s' is set to an invalid value\n" -#~ msgstr "GConf-nyckeln \"%s\" är satt till ett ogiltigt värde\n" - -#~ msgid "%d stored in GConf key %s is out of range %d to %d\n" -#~ msgstr "%d lagrad i GConf-nyckeln %s är inte i intervallet %d till %d\n" - -# SUN CHANGED MESSAGE -#~ msgid "GConf key \"%s\" is set to an invalid type\n" -#~ msgstr "GConf-nyckeln \"%s\" är satt till en ogiltig typ\n" -#~ msgid "GConf key %s is already in use and can't be used to override %s\n" -#~ msgstr "" -#~ "GConf-nyckeln %s används redan och kan inte användas för att åsidosätta " -#~ "%s\n" -#~ msgid "Can't override GConf key, %s not found\n" -#~ msgstr "Kan inte åsidosätta GConf-nyckeln, %s hittades inte\n" -#~ msgid "Error setting number of workspaces to %d: %s\n" -#~ msgstr "Fel vid inställning av antalet arbetsytor till %d: %s\n" -#~ msgid "Error setting name for workspace %d to \"%s\": %s\n" -#~ msgstr "Fel vid inställning av namnet på arbetsyta %d till \"%s\": %s\n" -#~ msgid "Error setting live hidden windows status status: %s\n" -#~ msgstr "Fel vid inställning av status för levande, dolda fönster: %s\n" -#~ msgid "Error setting no tab popup status: %s\n" -#~ msgstr "Fel vid inställning av status för ingen flik-popup: %s\n" -#~ msgid "Failed to restart: %s\n" -#~ msgstr "Misslyckades med att starta om: %s\n" -#, fuzzy -#~ msgid "Error setting clutter plugin list: %s\n" -#~ msgstr "Fel vid inställning av status för compositor: %s\n" - -#~ msgid "Clutter Plugins" -#~ msgstr "Clutter-insticksmoduler" - -#~ msgid "Turn compositing on" -#~ msgstr "Slå på compositing" - -#~ msgid "Turn compositing off" -#~ msgstr "Stäng av compositing" - -#~ msgid "Error setting compositor status: %s\n" -#~ msgstr "Fel vid inställning av status för compositor: %s\n" - -#~ msgid "Failed to get hostname: %s\n" -#~ msgstr "Misslyckades med att få tag i värdnamn: %s\n" - -#~ msgid "" -#~ "Lost connection to the display '%s';\n" -#~ "most likely the X server was shut down or you killed/destroyed\n" -#~ "the window manager.\n" -#~ msgstr "" -#~ "Tappade anslutningen till displayen \"%s\";\n" -#~ "troligtvis stängdes X-servern ner, eller så dödade/förstörde du\n" -#~ "fönsterhanteraren.\n" - -#~ msgid "Fatal IO error %d (%s) on display '%s'.\n" -#~ msgstr "Ödesdigert IO-fel %d (%s) på display \"%s\".\n" - -#~ msgid "Failed to read saved session file %s: %s\n" -#~ msgstr "Misslyckades med att läsa sparad sessionsfil %s: %s\n" - -#~ msgid "<author> specified twice for this theme" -#~ msgstr "<author> är angiven två gånger för detta tema" - -#~ msgid "<copyright> specified twice for this theme" -#~ msgstr "<copyright> är angivet två gånger för detta tema" - -#~ msgid "<date> specified twice for this theme" -#~ msgstr "<date> är angivet två gånger för detta tema" - -#~ msgid "<description> specified twice for this theme" -#~ msgstr "<description> är angivet två gånger för detta tema" - -#~ msgid "Theme file %s did not contain a root <metacity_theme> element" -#~ msgstr "Temafilen %s innehöll inte ett <metacity_theme>-rotelement" - -#~ msgid "/Windows/tearoff" -#~ msgstr "/Fönster/avskiljare" - -#~ msgid "/Windows/_Dialog" -#~ msgstr "/Fönster/_Dialogruta" - -#~ msgid "/Windows/_Modal dialog" -#~ msgstr "/Fönster/_Modal dialogruta" - -#~ msgid "/Windows/Des_ktop" -#~ msgstr "/Fönster/S_krivbord" - -#~ msgid "Window Management" -#~ msgstr "Fönsterhantering" - -#~ msgid "Failed to parse message \"%s\" from dialog process\n" -#~ msgstr "Misslyckades med att tolka meddelandet \"%s\" från dialogprocess\n" - -#~ msgid "Error reading from dialog display process: %s\n" -#~ msgstr "Fel vid läsning från dialogvisningsprocess: %s\n" +#~ msgid "Toggle shaded state" +#~ msgstr "Växla upprullat tillstånd" diff --git a/po/ta.po b/po/ta.po index fadbafc70..a276fc013 100644 --- a/po/ta.po +++ b/po/ta.po @@ -7,197 +7,618 @@ # Dinesh Nadarajah <n_dinesh@yahoo.com>, 2003. # Jayaradha N <jaya@pune.redhat.com>, 2004. # Felix <ifelix@redhat.com>, 2006. -# Dr.T.Vasudevan <agnihot3@gmail.com>, 2007, 2010, 2011, 2012. +# Dr.T.Vasudevan <agnihot3@gmail.com>, 2007, 2010, 2011, 2012, 2013. # Dr.T.vasudevan <agnihot3@gmail.com>, 2009. # I. Felix <ifelix@redhat.com>, 2009, 2011. +# Shantha kumar <shkumar@redhat.com>, 2014. msgid "" msgstr "" "Project-Id-Version: metacity.gnome-2-26.ta\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-02-28 14:25+0530\n" -"PO-Revision-Date: 2012-02-28 14:33+0530\n" -"Last-Translator: Dr.T.Vasudevan <agnihot3@gmail.com>\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=mutter&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2014-09-14 09:55+0000\n" +"PO-Revision-Date: 2014-09-15 01:22+0630\n" +"Last-Translator: Shantha kumar <shkumar@redhat.com>\n" "Language-Team: American English <kde-i18n-doc@kde.org>\n" -"Language: \n" +"Language: ta\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"0500\n" -"X-Generator: Lokalize 1.1\n" +"X-Generator: Lokalize 1.5\n" "Plural-Forms: nplurals=2; plural=(n!=1);\\n" "\n" "\n" "\n" -#: ../src/50-muffin-windows.xml.in.h:1 +#: ../data/50-mutter-navigation.xml.in.h:1 +msgid "Navigation" +msgstr "திசையறிதல்" + +#: ../data/50-mutter-navigation.xml.in.h:2 +msgid "Move window to workspace 1" +msgstr "பணியிடம் 1 க்கு சாளரத்தை நகர்த்தவும்" + +#: ../data/50-mutter-navigation.xml.in.h:3 +msgid "Move window to workspace 2" +msgstr "பணியிடம் 2 க்கு சாளரத்தை நகர்த்தவும்" + +#: ../data/50-mutter-navigation.xml.in.h:4 +msgid "Move window to workspace 3" +msgstr "பணியிடம் 3 க்கு சாளரத்தை நகர்த்தவும்" + +#: ../data/50-mutter-navigation.xml.in.h:5 +msgid "Move window to workspace 4" +msgstr "பணியிடம் 4 க்கு சாளரத்தை நகர்த்தவும்" + +#: ../data/50-mutter-navigation.xml.in.h:6 +#| msgid "Move window to workspace 1" +msgid "Move window to last workspace" +msgstr "சாளரத்தை கடைசி பணியிடத்திற்கு நகர்த்தவும்" + +#: ../data/50-mutter-navigation.xml.in.h:7 +msgid "Move window one workspace to the left" +msgstr "ஒருபணியிடத்திற்கு இடது பக்கம் சாளரத்தை நகர்த்தவும்" + +#: ../data/50-mutter-navigation.xml.in.h:8 +msgid "Move window one workspace to the right" +msgstr "ஒருபணியிடத்திற்கு வலதுபக்கம் சாளரத்தை நகர்த்தவும்" + +#: ../data/50-mutter-navigation.xml.in.h:9 +msgid "Move window one workspace up" +msgstr "ஒருபணியிடத்திற்கு மேலே சாளரத்தை நகர்த்தவும்" + +#: ../data/50-mutter-navigation.xml.in.h:10 +msgid "Move window one workspace down" +msgstr "ஒருபணியிடத்திற்கு கீழே சாளரத்தை நகர்த்தவும்" + +#: ../data/50-mutter-navigation.xml.in.h:11 +#| msgid "Move window one workspace to the left" +msgid "Move window one monitor to the left" +msgstr "சாளரத்தை ஒரு திரை இடப்புறம் நகர்த்தவும்" + +#: ../data/50-mutter-navigation.xml.in.h:12 +#| msgid "Move window one workspace to the right" +msgid "Move window one monitor to the right" +msgstr "சாளரத்தை ஒரு திரை வலப்புறம் நகர்த்தவும்" + +#: ../data/50-mutter-navigation.xml.in.h:13 +#| msgid "Move window one workspace up" +msgid "Move window one monitor up" +msgstr "சாளரத்தை ஒரு திரை மேலே நகர்த்தவும்" + +#: ../data/50-mutter-navigation.xml.in.h:14 +#| msgid "Move window one workspace down" +msgid "Move window one monitor down" +msgstr "சாளரத்தை ஒரு திரை கீழே நகர்த்தவும்" + +#: ../data/50-mutter-navigation.xml.in.h:15 +msgid "Switch applications" +msgstr "பயன்பாடுகளுக்கிடையே மாறவும்" + +#: ../data/50-mutter-navigation.xml.in.h:16 +#| msgid "Switch applications" +msgid "Switch to previous application" +msgstr "முந்தைய பயன்பாட்டுக்கு மாறவும்" + +#: ../data/50-mutter-navigation.xml.in.h:17 +msgid "Switch windows" +msgstr "சாளரத்தை மாற்றுக" + +#: ../data/50-mutter-navigation.xml.in.h:18 +#| msgid "Switch windows" +msgid "Switch to previous window" +msgstr "முந்தைய சாளரத்திற்கு மாறவும்" + +#: ../data/50-mutter-navigation.xml.in.h:19 +msgid "Switch windows of an application" +msgstr "ஒரு பயன்பாட்டின் சாளரங்களிடையே மாறவும்" + +#: ../data/50-mutter-navigation.xml.in.h:20 +#| msgid "Switch windows of an application" +msgid "Switch to previous window of an application" +msgstr "ஒரு பயன்பாட்டின் முந்தைய சாளரத்திற்கு மாறவும்" + +#: ../data/50-mutter-navigation.xml.in.h:21 +msgid "Switch system controls" +msgstr "கணினி கட்டுப்பாடுகளை மாற்றுதல்" + +#: ../data/50-mutter-navigation.xml.in.h:22 +#| msgid "Switch system controls" +msgid "Switch to previous system control" +msgstr "முந்தைய கணினி கட்டுப்பாட்டுக்கு மாறவும்" + +#: ../data/50-mutter-navigation.xml.in.h:23 +msgid "Switch windows directly" +msgstr "சாளரங்களிடையே உடனடியாக நகரவும்" + +#: ../data/50-mutter-navigation.xml.in.h:24 +msgid "Switch directly to previous window" +msgstr "நேரடியாக முந்தைய சாளரத்திற்கு மாறவும்" + +#: ../data/50-mutter-navigation.xml.in.h:25 +msgid "Switch windows of an app directly" +msgstr "ஒரு பயன்பாட்டின் சாளரங்களிடையே நேரடியாக நகரவும்" + +#: ../data/50-mutter-navigation.xml.in.h:26 +#| msgid "Switch windows of an application" +msgid "Switch directly to previous window of an app" +msgstr "நேரடியாக ஒரு பயன்பாட்டின் முந்தைய சாளரத்திற்கு மாறவும்" + +#: ../data/50-mutter-navigation.xml.in.h:27 +msgid "Switch system controls directly" +msgstr "கணினி கட்டுப்பாடுகளை நேரடியாக மாற்றவும்" + +#: ../data/50-mutter-navigation.xml.in.h:28 +#| msgid "Switch system controls" +msgid "Switch directly to previous system control" +msgstr "நேரடியாக முந்தைய கணினி கட்டுப்பாட்டுக்கு மாறவும்" + +#: ../data/50-mutter-navigation.xml.in.h:29 +msgid "Hide all normal windows" +msgstr "எல்லா வழக்கமான சாளரங்களையும் மறை" + +#: ../data/50-mutter-navigation.xml.in.h:30 +msgid "Switch to workspace 1" +msgstr "பணியிடம் 1க்கு மாறு" + +#: ../data/50-mutter-navigation.xml.in.h:31 +msgid "Switch to workspace 2" +msgstr "பணியிடம் 2 க்கு மாறு" + +#: ../data/50-mutter-navigation.xml.in.h:32 +msgid "Switch to workspace 3" +msgstr "பணியிடம் 3 க்கு மாறு" + +#: ../data/50-mutter-navigation.xml.in.h:33 +msgid "Switch to workspace 4" +msgstr "பணியிடம் 4 க்கு மாறு" + +#: ../data/50-mutter-navigation.xml.in.h:34 +#| msgid "Switch to workspace 1" +msgid "Switch to last workspace" +msgstr "கடைசி பணியிடத்திற்கு மாறவும்" + +#: ../data/50-mutter-navigation.xml.in.h:35 +msgid "Move to workspace left" +msgstr "வேலையிடத்தை இடப்பக்கத்திற்கு நகர்த்தவும்" + +#: ../data/50-mutter-navigation.xml.in.h:36 +msgid "Move to workspace right" +msgstr "வேலையிடத்தை வலப்பக்கத்திற்கு நகர்த்தவும்" + +#: ../data/50-mutter-navigation.xml.in.h:37 +msgid "Move to workspace above" +msgstr "வேலையிடத்தை மேல்பக்கத்திற்கு நகர்த்தவும்" + +#: ../data/50-mutter-navigation.xml.in.h:38 +msgid "Move to workspace below" +msgstr "வேலையிடத்தை கீழே நகர்த்தவும் " + +#: ../data/50-mutter-system.xml.in.h:1 +msgid "System" +msgstr "கணினி" + +#: ../data/50-mutter-system.xml.in.h:2 +msgid "Show the run command prompt" +msgstr "இயக்கு கட்டளையின் தூண்டலைக் காட்டு" + +#: ../data/50-mutter-system.xml.in.h:3 +msgid "Show the activities overview" +msgstr "செயல்பாடுகளின் மேல் பார்வையை காட்டுக" + +#: ../data/50-mutter-windows.xml.in.h:1 +msgid "Windows" +msgstr "சாளரங்கள்" + +#: ../data/50-mutter-windows.xml.in.h:2 +msgid "Activate the window menu" +msgstr "சாளர பட்டியலை செயல்படுத்து " + +#: ../data/50-mutter-windows.xml.in.h:3 +msgid "Toggle fullscreen mode" +msgstr "எப்போதும் முழுதிரை பாங்கிற்கு செல்" + +#: ../data/50-mutter-windows.xml.in.h:4 +msgid "Toggle maximization state" +msgstr "எப்போதும் பெரிய சாளர நிலைக்கு செல்" + +#: ../data/50-mutter-windows.xml.in.h:5 +msgid "Maximize window" +msgstr "சாளரத்தை பெரிதாக்கு" + +#: ../data/50-mutter-windows.xml.in.h:6 +msgid "Restore window" +msgstr "சாளரத்தை மீட்டமை" + +#: ../data/50-mutter-windows.xml.in.h:7 +msgid "Toggle shaded state" +msgstr "எப்போதும் நிழை நிலைக்கு செல்" + +#: ../data/50-mutter-windows.xml.in.h:8 +msgid "Close window" +msgstr "சாளரம் மூடவும்" + +#: ../data/50-mutter-windows.xml.in.h:9 +msgid "Hide window" +msgstr "சாளரத்தை மறை " + +#: ../data/50-mutter-windows.xml.in.h:10 +msgid "Move window" +msgstr "சாளரத்தை நகர்த்தவும்" + +#: ../data/50-mutter-windows.xml.in.h:11 +msgid "Resize window" +msgstr "சாளரத்தின் அளவை மாற்று" + +#: ../data/50-mutter-windows.xml.in.h:12 +msgid "Toggle window on all workspaces or one" +msgstr "" +"சாளரம் அனைத்து பணியிடங்களிலும் இருக்குமா அல்லது ஒரே பணியிடத்திலா என்பதை நிலை " + +#: ../data/50-mutter-windows.xml.in.h:13 +msgid "Raise window if covered, otherwise lower it" +msgstr "" +"வேறொரு சாளரத்தால் மறைக்கப்பட்டிருந்தால் சாளரத்தை உயர்த்து, அல்லது கீழிறக்கு" + +#: ../data/50-mutter-windows.xml.in.h:14 +msgid "Raise window above other windows" +msgstr "மற்ற சாளரத்திற்கு மேல் இந்த சாளரத்தை உயர்த்து" + +#: ../data/50-mutter-windows.xml.in.h:15 +msgid "Lower window below other windows" +msgstr "மற்ற சாளரத்திற்கு கீழே சாளரத்தை வைக்கவும்" + +#: ../data/50-mutter-windows.xml.in.h:16 +msgid "Maximize window vertically" +msgstr "சாளரத்தை இடவலமாக பெரிதாக்கு " + +#: ../data/50-mutter-windows.xml.in.h:17 +msgid "Maximize window horizontally" +msgstr "சாளரத்தை செங்குத்தாக பெரிதாக்கு " + +#: ../data/50-mutter-windows.xml.in.h:18 msgid "View split on left" msgstr "இடது பக்கத்தில் பிளந்து பார்" -#: ../src/50-muffin-windows.xml.in.h:2 +#: ../data/50-mutter-windows.xml.in.h:19 msgid "View split on right" msgstr "வலது பக்கத்தில் பிளந்து பார்" -#: ../src/50-muffin-windows.xml.in.h:3 -msgid "Windows" -msgstr "சாளரங்கள்" +#: ../data/mutter.desktop.in.h:1 +msgid "Mutter" +msgstr "மட்டர்" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:1 +msgid "Modifier to use for extended window management operations" +msgstr "நீட்டிக்கப்பட்ட சாளர மேலாண்மை செயல்பாடுகளுக்கு பயன்பட வேண்டிய மாற்றி" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:2 +msgid "" +"This key will initiate the \"overlay\", which is a combination window " +"overview and application launching system. The default is intended to be the " +"\"Windows key\" on PC hardware. It's expected that this binding either the " +"default or set to the empty string." +msgstr "" +"இந்த விசை \"overlay\", இது ஒரு சாளர மேல்நோக்கு பயன்பாடு துவக்க அமைப்பு. இதன் " +"முன்னிருப்பு கணினி வன்பொருட்களின் சாளர விசையாக யோசிக்கப்படுகிறது. இந்த " +"பிணைப்பை " +"முன்னிருப்பாகவோ காலி சரமாகவோ அமைக்கவும்." + +#: ../data/org.gnome.mutter.gschema.xml.in.h:3 +msgid "Attach modal dialogs" +msgstr "மாதிரி உரையாடல்களை இணை" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:4 +msgid "" +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." +msgstr "" +"உண்மை எனில் சுதந்திர தனி தலைப்பு பட்டைகளுக்கு பதில் மாதிரி உரையாடல்கள் " +"முதன்மை " +"சாளரத்தின் தலைப்பு பட்டயுடன் இணைத்து இருக்கும்; இவை முதன்மை சாளரத்துடனே " +"நகர்த்தப்படும்." + +#: ../data/org.gnome.mutter.gschema.xml.in.h:5 +msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "திரை விளிம்பில் சாரளங்களை விட்டால் விளிம்பு சாய்வதை செயலாக்குகிறது" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:6 +msgid "" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." +msgstr "" +"செயலாக்கினால் செங்குத்தான திரை விளிம்பில் சாரளங்களை விட்டால் அவை சென்குத்தாக " +"அதிகப்படுத்தப்படும்; கிடைமட்டத்தில் கிடைக்கும் இடத்தில் பாதியை " +"ஆக்கிரமிக்கும். திரையின் " +"மேல் விளிம்பில் விட அவை முழுமையாக அதிகரிக்கப்படும்." + +#: ../data/org.gnome.mutter.gschema.xml.in.h:7 +msgid "Workspaces are managed dynamically" +msgstr "பணியிடங்கள் இயக்கநிலையில் மேலாளப்படும்" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:8 +msgid "" +"Determines whether workspaces are managed dynamically or whether there's a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." +msgstr "" +"பணியிடங்கள் இயங்கு நிலையில் மேலாளப்படுமா அல்லது நிலையான பணியிடங்கள் இருக்க " +"வேன்டுமா என " +"நிர்ணயிக்கிறது. (org.gnome.desktop.wm.விருப்பங்களில் நிர்ணயித்த பணியிடங்கள் " +"எண்ணிக்கையால்)." + +#: ../data/org.gnome.mutter.gschema.xml.in.h:9 +msgid "Workspaces only on primary" +msgstr "வேலைக்களங்கள் முதன்மையில் மட்டும்" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:10 +msgid "" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." +msgstr "" +"வேலைக்கள் மாற்றம் எல்லா திரைகளிலும் உள்ள சாளரங்களுக்குமா அல்லது முதன்மை திரை " +"சாளரத்துக்கு " +"மட்டுமா என தீர்மானிக்கிறது" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:11 +msgid "No tab popup" +msgstr "கீற்று துள்ளல் இல்லை" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:12 +msgid "" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." +msgstr "" +"சாளரங்கள் சுழற்சிக்கு துள்ளுவதையும் சட்டத்தை சிறப்பாக காட்டுவதையும் " +"பயன்படுத்த வேண்டுமா என " +"நிர்ணயிக்கிறது" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:13 +msgid "Delay focus changes until the pointer stops moving" +msgstr "பாயின்ட்டர் நகர்வது நிற்கும் வரை குவிய மாற்றங்களைத் தாமதமாக்கவும்" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:14 +msgid "" +"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " +"the focus will not be changed immediately when entering a window, but only " +"after the pointer stops moving." +msgstr "" +"ஆம் என அமைக்கப்பட்டால், குவியும் பயன்முறையானது \"சாய்ந்த\" அல்லது \"மவுஸ்\" " +"என " +"அமைக்கப்பட்டு ஒரு சாளரத்தில் நுழையும் போது குவியம் உடனடியாக மாற்றப்படாது, " +"மாறாக " +"பாயின்ட்டர் நகர்வது நின்ற பிறகே குவியம் மாறும்." + +#: ../data/org.gnome.mutter.gschema.xml.in.h:15 +msgid "Draggable border width" +msgstr "இழுக்கக்கூடிய விளிம்பின் அகலம்" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:16 +msgid "" +"The amount of total draggable borders. If the theme's visible borders are " +"not enough, invisible borders will be added to meet this value." +msgstr "" +"இழுக்கக்கூடிய விளிம்புகளின் மொத்த அளவு. கருத்தின் தெரியும் விளிம்புகள் " +"போதவில்லை எனில் " +"இந்த மதிப்பை அடைய மறை விளிம்பு சேர்க்கப்படும்." + +#: ../data/org.gnome.mutter.gschema.xml.in.h:17 +msgid "Auto maximize nearly monitor sized windows" +msgstr "ஏறத்தாழ திரை அளவுள்ள சாளரங்களை தானியங்கியாக அதிக பட்ச அளவாக்கு" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:18 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" +"செயலாக்கினால், துவக்கத்தில் ஏறத்தாழ திரை அளவுள்ள புதிய சாளரங்கள் தானியங்கியாக " +"அதிக பட்ச " +"அளவாக்கப்படும்" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:19 +msgid "Place new windows in the center" +msgstr "புதிய சாளரத்தை நடுவில் வைக்கவும்" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:20 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" +"ஆம் என்று அமைக்கப்பட்டால், எப்போதும் புதிய சாளரங்கள் காட்சித் திரையின் " +"செயலிலுள்ள திரையின் மையத்தில் வைக்கப்படும்." + +#: ../data/org.gnome.mutter.gschema.xml.in.h:21 +msgid "Select window from tab popup" +msgstr "கீற்றுத்துள்ளலிருந்து சாளரத்தை தேர்ந்தெடுக்கவும்." + +#: ../data/org.gnome.mutter.gschema.xml.in.h:22 +msgid "Cancel tab popup" +msgstr "கீற்று துள்ளுவதை இரத்து செய்" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:1 +#| msgid "Switch to workspace 1" +msgid "Switch to VT 1" +msgstr "VT 1 க்கு மாறவும்" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:2 +#| msgid "Switch to workspace 2" +msgid "Switch to VT 2" +msgstr "VT 2 க்கு மாறவும்" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:3 +#| msgid "Switch to workspace 3" +msgid "Switch to VT 3" +msgstr "VT 3 க்கு மாறவும்" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:4 +#| msgid "Switch to workspace 4" +msgid "Switch to VT 4" +msgstr "VT 4 க்கு மாறவும்" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:5 +#| msgid "Switch to workspace 5" +msgid "Switch to VT 5" +msgstr "VT 5 க்கு மாறவும்" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:6 +#| msgid "Switch to workspace 6" +msgid "Switch to VT 6" +msgstr "VT 6 க்கு மாறவும்" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:7 +#| msgid "Switch to workspace 7" +msgid "Switch to VT 7" +msgstr "VT 7 க்கு மாறவும்" + +#: ../src/backends/meta-monitor-manager.c:412 +msgid "Built-in display" +msgstr "உள்ளமைக் காட்சி" + +#: ../src/backends/meta-monitor-manager.c:437 +msgid "Unknown" +msgstr "தெரியாத" + +#: ../src/backends/meta-monitor-manager.c:439 +msgid "Unknown Display" +msgstr "தெரியாத காட்சி" + +#. TRANSLATORS: this is a monitor vendor name, followed by a +#. * size in inches, like 'Dell 15"' +#. +#: ../src/backends/meta-monitor-manager.c:447 +#, c-format +msgid "%s %s" +msgstr "%s %s" #. This probably means that a non-WM compositor like xcompmgr is running; #. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 +#: ../src/compositor/compositor.c:443 #, c-format msgid "" "Another compositing manager is already running on screen %i on display \"%s" "\"." -msgstr " %i திரையில் காட்சி \"%s\" இல் இன்னொரு சாளர மேலாளர் இயங்கிக்கொண்டு இருக்கிறது." +msgstr "" +" %i திரையில் காட்சி \"%s\" இல் இன்னொரு சாளர மேலாளர் இயங்கிக்கொண்டு இருக்கிறது." -#: ../src/core/bell.c:307 +#: ../src/core/bell.c:185 msgid "Bell event" msgstr "மணி நிகழ்ச்சி" -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "தெரியாத சாளர தகவல் வேண்டுகோள்: %d" - -#: ../src/core/delete.c:111 +#: ../src/core/delete.c:127 #, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> பதிலளிக்கவில்லை" +msgid "“%s” is not responding." +msgstr "\"%s\" பதிலளிக்கவில்லை" -#: ../src/core/delete.c:114 +#: ../src/core/delete.c:129 msgid "Application is not responding." msgstr "பயன்பாடு இயங்கவில்லை" -#: ../src/core/delete.c:119 +#: ../src/core/delete.c:134 msgid "" "You may choose to wait a short while for it to continue or force the " "application to quit entirely." msgstr "" -"நீங்கள் சிறிது நேரம் பொறுத்து அது தொடர அனுமதிக்கலாம் அல்லது செயல்பாட்டை வன் வெளியேறு " +"நீங்கள் சிறிது நேரம் பொறுத்து அது தொடர அனுமதிக்கலாம் அல்லது செயல்பாட்டை வன் " +"வெளியேறு " "செய்யலாம்." -#: ../src/core/delete.c:126 +#: ../src/core/delete.c:141 msgid "_Wait" msgstr "_காத்திரு" -#: ../src/core/delete.c:126 +#: ../src/core/delete.c:141 msgid "_Force Quit" msgstr "கட்டாய வெளியேற்றம் (_F)" -#: ../src/core/display.c:361 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "நீட்சி %s காணப்படவில்லை பவின் ஆக்கத்துக்கு அது அவசியம்" - -#: ../src/core/display.c:427 +#: ../src/core/display.c:547 #, c-format msgid "Failed to open X Window System display '%s'\n" msgstr "X சாளர காட்சியை திறப்பதில் தோல்வி '%s'\n" -#: ../src/core/keybindings.c:852 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "விசை %s ஐ மாற்றி %x ஓடு இணைத்து வேறு நிரல் பயன்படுத்திக்கொண்டிருக்கிறது\n" - -#: ../src/core/main.c:206 +#: ../src/core/main.c:176 msgid "Disable connection to session manager" msgstr "அமர்வு மேலாளருடன் இருக்கும் இணைப்பை முடக்கு" -#: ../src/core/main.c:212 +#: ../src/core/main.c:182 msgid "Replace the running window manager" msgstr "இயங்கும் சாளர மேலாளரை மாற்றுக" -#: ../src/core/main.c:218 +#: ../src/core/main.c:188 msgid "Specify session management ID" msgstr "அமர்வு மேலாண் எண்ணை குறிப்பிடு" -#: ../src/core/main.c:223 +#: ../src/core/main.c:193 msgid "X Display to use" msgstr "பயன்படுத்த வேண்டிய X காட்சி" -#: ../src/core/main.c:229 +#: ../src/core/main.c:199 msgid "Initialize session from savefile" msgstr "அமர்வை சேவ்பைல் இலிருந்து துவக்கு " -#: ../src/core/main.c:235 +#: ../src/core/main.c:205 msgid "Make X calls synchronous" msgstr "எக்ஸ் அழைப்புகளை ஒத்திசை." -#: ../src/core/main.c:504 +#: ../src/core/main.c:212 +msgid "Run as a wayland compositor" +msgstr "வேலேன்ட் கம்ப்போசிட்டராக இயக்கு" + +#: ../src/core/main.c:220 +msgid "Run as a full display server, rather than nested" +msgstr "உள்ளுக்குள் அமைந்தபடியல்லாமல், முழுக் காட்சி சேவையகமாக இயக்கு" + +#: ../src/core/main.c:451 #, c-format msgid "Failed to scan themes directory: %s\n" msgstr "கருப்பொருள் அடைவை வருடுவதில் தோல்வி: %s\n" -#: ../src/core/main.c:520 +#: ../src/core/main.c:467 #, c-format -msgid "Could not find a theme! Be sure %s exists and contains the usual themes.\n" +msgid "" +"Could not find a theme! Be sure %s exists and contains the usual themes.\n" msgstr "" -"கருப்பொருளை காணவில்லை! %s உள்ளதா எனவும் அதில் பயனுள்ள கருப்பொருள் உள்ளதா எனவும் " +"கருப்பொருளை காணவில்லை! %s உள்ளதா எனவும் அதில் பயனுள்ள கருப்பொருள் உள்ளதா " +"எனவும் " "பார்க்கவும்.\n" -#: ../src/core/muffin.c:40 +#: ../src/core/mutter.c:39 #, c-format msgid "" -"muffin %s\n" +"mutter %s\n" "Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" "This is free software; see the source for copying conditions.\n" "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " "PARTICULAR PURPOSE.\n" msgstr "" "மட்டர் %s\n" -"காப்புரிமை (C) 2001-%d ஹவாக் பென்னிங்க்டன், ரெட் ஹாட்,இன்க், மற்றும் மற்றவர்கள்.\n" +"காப்புரிமை (C) 2001-%d ஹவாக் பென்னிங்க்டன், ரெட் ஹாட்,இன்க், மற்றும் " +"மற்றவர்கள்.\n" "இது இலவச மென்பொருள், பிரதி எடுக்க விதிமுறைகளை மூலத்தில் காண்க.\n" -"விற்க தகுதி அல்லது ஒரு குறிப்பிட்ட செயலுக்கு தகுதி உட்பட எந்த ஒரு ஒரு உத்திரவாதமும் " +"விற்க தகுதி அல்லது ஒரு குறிப்பிட்ட செயலுக்கு தகுதி உட்பட எந்த ஒரு ஒரு " +"உத்திரவாதமும் " "இல்லை.\n" -#: ../src/core/muffin.c:54 +#: ../src/core/mutter.c:53 msgid "Print version" msgstr "அச்சு பதிப்பு" -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "பல்வினையாக்கியின் சொருகிகளின் கமாவால் பிரித்த பட்டியல்." - -#: ../src/core/prefs.c:1069 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"உடைந்த பயன்பாடுகளின் செயல்பாடு தடைசெய்யப்பட்டது, சில பயன்பாடுகள் சரியாக வேலை " -"செய்யாது.\n" - -#: ../src/core/prefs.c:1144 -#, c-format -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "எழுத்துரு விளக்கம் \"%s\" ஐ ஜிசெட்டிங்க்ஸ் விசையிலிருந்து பகுக்க முடியவில்லை %s\n" - -#: ../src/core/prefs.c:1210 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "அமைப்பு பாங்கில் உள்ள \"%s\" சுட்டி பட்டன் மாற்றியில் செல்லாத மதிப்பு\n" - -#: ../src/core/prefs.c:1722 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "\"%s\" அமைப்பு தரவுத்தளத்தில் உள்ள மதிப்பு செல்லாத கீபைன்டிங்\"%s\"\n" +#: ../src/core/mutter.c:59 +msgid "Mutter plugin to use" +msgstr "பயன்படுத்த க்ளட்டர் செருகிகள்" -#: ../src/core/prefs.c:1819 +#: ../src/core/prefs.c:2117 #, c-format msgid "Workspace %d" msgstr "வேலையிடம் %d" -#: ../src/core/screen.c:730 +#: ../src/core/screen.c:543 #, c-format msgid "Screen %d on display '%s' is invalid\n" msgstr "திரை %d காட்சி '%s' இல் செல்லாது\n" -#: ../src/core/screen.c:746 +#: ../src/core/screen.c:559 #, c-format msgid "" "Screen %d on display \"%s\" already has a window manager; try using the --" @@ -206,593 +627,85 @@ msgstr "" "திரை %d காட்சி \"%s\" க்கு சாளர மேலாளர் உள்ளது; --replace தேர்வை பயன்படுத்தி " "தற்போதைய சாளரத்தை மாற்றவும்.\n" -#: ../src/core/screen.c:773 -#, c-format -msgid "Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "திரையில் சாளர மேலாளர் தேர்வை பெறமுடியவில்லை %d காட்சி \"%s\"\n" - -#: ../src/core/screen.c:828 +#: ../src/core/screen.c:652 #, c-format msgid "Screen %d on display \"%s\" already has a window manager\n" msgstr "திரை %d யின் காட்சி \"%s\" க்கு சாளர மேலாளர் ஏற்கெனவே உள்ளது\n" -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "திரை %d ஐ விடுவிக்க முடியவில்லை \"%s\"\n" - -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "அடைவை உருவாக்க முடியவில்லை '%s': %s\n" - -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "அமர்வு கோப்பு '%s' எழுதுவதற்காக திறக்க முடியவில்லை: %s\n" - -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "அமர்வு கோப்பை எழுதுவதில் பிழை '%s': %s\n" - -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "அமர்வுகோப்பை மூடுவதில் பிழை '%s': %s\n" - -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "சேமிக்கப்பட்ட அமர்வு கோப்பை பகுப்பதில் தோல்வி: %s\n" - -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "<muffin_session> பண்பு பார்க்கப்பட்டது ஆனால் இங்கு அமர்வு ID ஏற்கெனவே உள்ளது" - -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "தெரியாத பண்பு %s <%s> உறுப்பில்" - -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "பின்னப்பட்ட <window> குறி" - -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "தெரியாத உறுப்பு %s" - -#: ../src/core/session.c:1809 -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" -" "தற்போதைய அமைப்பை சேமி" செயலுக்கு ஆதரவு இல்லை மேலும் அடுத்த முறை " -"உள்நுழையும் போது நீங்களாக துவக்க வேண்டும்" - -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "பிழைதிருத்த பட்டியலை திறப்பதில் தோல்வி: %s\n" - -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "fdopen() பதிவுக்கோப்பு தோல்வி %s: %s\n" - -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "பதிவுக்கோப்பு திறக்கப்பட்டது %s\n" - -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" +#: ../src/core/util.c:118 +msgid "Mutter was compiled without support for verbose mode\n" msgstr "வெர்போஸ் ஆதரவு இல்லாமல் மட்டர் அமைக்கப்பட்டது\n" -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "சாளர மேலாளர்:" - -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "சாளர மேலாளரில் பிழை" - -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "சாளர மேலாளர் எச்சரிக்கை:" - -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "சாளர மேலாளர் பிழை" - -#. first time through -#: ../src/core/window.c:7224 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"சாளரம் %s SM_CLIENT_ID இன் மேல் உள்ளது, WM_CLIENT_LEADER சாளரத்தில் குறிப்பிட்டது " -"போல் ICCCM.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7887 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size " -"%d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"சாளரம் %s MWM அளவு மாற்ற முடியும் என குறிப்பிடுகிறதும் ஆனால் %d x %d மற்றும் அதிக " -"பட்ச அளவு %d x %d; பொருள் தரும்படி இல்லை.\n" - -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "பயன்பாடு பொய்யான ஒரு _NET_WM_PID %lu ஐ அமைத்தது\n" - -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (%s மீது)" - -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "செல்லாத WM_TRANSIENT_FOR சாளரம் 0x%lx இதற்கு குறிக்கப்பட்டது: %s.\n" - -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "WM_TRANSIENT_FOR சாளரம் 0x%lx %s க்கு சுழல் நிகழ்வை உருவாக்கும்.\n" - -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"சாளரம் 0x%lx பண்பு %s உள்ளது\n" -"இதில் %s வகை %d வடிவமைப்பு எதிர்பார்க்கப்பட்டது\n" -"ஆனால் வகை %s வடிவமைப்பு %d n_items %d முறை உள்ளது.\n" -"இது பயன்பாட்டு பிழையாக இருக்கலாம், சாளர மேலாளர் பிழை இல்லை.\n" -"சாளரத்தில் title=\"%s\" class=\"%s\" name=\"%s\" உள்ளது\n" - -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "பண்பு %s சாளரம் 0x%lx செல்லாத UTF-8 உள்ளது\n" - -#: ../src/core/xprops.c:494 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "பண்பு %s சாளரம் 0x%lx செல்லாத UTF-8 உருப்படி %d பட்டியலில் உள்ளது\n" - -#: ../src/muffin.desktop.in.h:1 ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "மட்டர்" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 -msgid "Attach modal dialogs" -msgstr "மாதிரி உரையாடல்களை இணை" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 -msgid "Cancel tab popup" -msgstr "கீற்று துள்ளுவதை இரத்து செய்" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"மறைந்துள்ள சாளரங்கள் (அதாவது குறூக்கியவை, நடப்பில் இல்லாத வேறு பணிக்களத்தில் உள்ளவை) " -"உயிர்ப்புடன் வைக்கப்பட வேண்டுமா என தீர்மானிக்கிறது." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 -msgid "" -"Determines whether the use of popup and highlight frame should be disabled " -"for window cycling." -msgstr "" -"சாளரங்கள் சுழற்சிக்கு துள்ளுவதையும் சட்டத்தை சிறப்பாக காட்டுவதையும் பயன்படுத்த வேண்டுமா என " -"நிர்ணயிக்கிறது" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -msgid "" -"Determines whether workspace switching should happen for windows on all " -"monitors or only for windows on the primary monitor." -msgstr "" -"வேலைக்கள் மாற்றம் எல்லா திரைகளிலும் உள்ள சாளரங்களுக்குமா அல்லது முதன்மை திரை சாளரத்துக்கு " -"மட்டுமா என தீர்மானிக்கிறது" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 -msgid "Draggable border width" -msgstr "இழுக்கக்கூடிய விளிம்பின் அகலம்" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 -msgid "Enable edge tiling when dropping windows on screen edges" -msgstr "திரை விளிம்பில் சாரளங்களை விட்டால் விளிம்பு சாய்வதை செயலாக்குகிறது" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 -msgid "" -"If enabled, dropping windows on vertical screen edges maximizes them " -"vertically and resizes them horizontally to cover half of the available " -"area. Dropping windows on the top screen edge maximizes them completely." -msgstr "" -"செயலாக்கினால் செங்குத்தான திரை விளிம்பில் சாரளங்களை விட்டால் அவை சென்குத்தாக " -"அதிகப்படுத்தப்படும்; கிடைமட்டத்தில் கிடைக்கும் இடத்தில் பாதியை ஆக்கிரமிக்கும். திரையின் " -"மேல் விளிம்பில் விட அவை முழுமையாக அதிகரிக்கப்படும்." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 -msgid "Live Hidden Windows" -msgstr "உயிர்ப்புள்ள மறைந்த சாளரங்கள்" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 -msgid "Modifier to use for extended window management operations" -msgstr "நீட்டிக்கப்பட்ட சாளர மேலாண்மை செயல்பாடுகளுக்கு பயன்பட வேண்டிய மாற்றி" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 -msgid "No tab popup" -msgstr "கீற்று துள்ளல் இல்லை" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 -msgid "Select window from tab popup" -msgstr "கீற்றுத்துள்ளலிருந்து சாளரத்தை தேர்ந்தெடுக்கவும்." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 -msgid "" -"The amount of total draggable borders. If the theme's visible borders are " -"not enough, invisible borders will be added to meet this value." -msgstr "" -"இழுக்கக்கூடிய விளிம்புகளின் மொத்த அளவு. கருத்தின் தெரியும் விளிம்புகள் போதவில்லை எனில் " -"இந்த மதிப்பை அடைய மறை விளிம்பு சேர்க்கப்படும்." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 -msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." -msgstr "" -"இந்த விசை \"overlay\", இது ஒரு சாளர மேல்நோக்கு பயன்பாடு துவக்க அமைப்பு. இதன் " -"முன்னிருப்பு கணினி வன்பொருட்களின் சாளர விசையாக யோசிக்கப்படுகிறது. இந்த பிணைப்பை " -"முன்னிருப்பாகவோ காலி சரமாகவோ அமைக்கவும்." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 -msgid "" -"When true, instead of having independent titlebars, modal dialogs appear " -"attached to the titlebar of the parent window and are moved together with " -"the parent window." -msgstr "" -"உண்மை எனில் சுதந்திர தனி தலைப்பு பட்டைகளுக்கு பதில் மாதிரி உரையாடல்கள் முதன்மை " -"சாளரத்தின் தலைப்பு பட்டயுடன் இணைத்து இருக்கும்; இவை முதன்மை சாளரத்துடனே நகர்த்தப்படும்." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 -msgid "Workspaces only on primary" -msgstr "வேலைக்களங்கள் முதன்மையில் மட்டும்" - -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "பயன்பாடு: %s\n" - -#: ../src/ui/frames.c:1157 -msgid "Close Window" -msgstr "சாளரம் மூடவும்" - -#: ../src/ui/frames.c:1160 -msgid "Window Menu" -msgstr "சாளர பட்டி" - -#: ../src/ui/frames.c:1163 -msgid "Minimize Window" -msgstr "சாளரத்தை குறுக்கவும்" - -#: ../src/ui/frames.c:1166 -msgid "Maximize Window" -msgstr "சாளரத்தை பெரிதாக்கவும்" - -#: ../src/ui/frames.c:1169 -msgid "Restore Window" -msgstr "சாளரத்தை மீட்டமை" - -#: ../src/ui/frames.c:1172 -msgid "Roll Up Window" -msgstr "சாளரத்தை மேலே சுருட்டு" - -#: ../src/ui/frames.c:1175 -msgid "Unroll Window" -msgstr "சாளரம் விரிக்கவும்" - -#: ../src/ui/frames.c:1178 -msgid "Keep Window On Top" -msgstr "சாளரத்தை மேலே வைத்திரு " - -#: ../src/ui/frames.c:1181 -msgid "Remove Window From Top" -msgstr "மேலிருந்து சாளரத்தை நீக்கு " - -#: ../src/ui/frames.c:1184 -msgid "Always On Visible Workspace" -msgstr "வேலைகளத்தில் எப்போதும் தெரியும் " - -#: ../src/ui/frames.c:1187 -msgid "Put Window On Only One Workspace" -msgstr "சாளரத்தை ஒரே ஒரு பணியிடத்தில் மட்டும் வைக்கவும்" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "குறுக்கவும் (_n)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "பெரிதாக்கவும் (_x)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "பெரிதாக்காத (_x)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "மேலே சுருட்டு" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "கீழ் விரி (_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "நகர்த்தவும் (_M)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "மறுஅளவு (_R)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "தலைப்புப்பட்டையை திரைக்கு நகர்த்தவும் (_s)" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "எப்போதும் மேலே (_T)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "எப்போதும் தெரியும் வேலையிடத்தில் (_A)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "இந்த வேலையிடத்தில் மட்டும் (_O)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "வேலையிடத்தின் இடப்பக்கத்திற்கு நகர்த்தவும் (_L)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "வேலையிடத்தின் வலப்பக்கத்திற்கு நகர்த்தவும் (_i)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "வேலையிடத்தின் மேலே நகர்த்தவும் (_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "வேலையிடத்தின் கீழே நகர்த்தவும் (_D)" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "மூடவும் (_C)" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "பணியிடம் %d%n" - -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "வேலையிடம் 1_0" - -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "வேலையிடம் %s%d" - -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "மற்ற வேலையிடத்திற்கு மாற்றவும் (_W)" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" - #. Translators: This represents the size of a window. The first number is #. * the width of the window and the second is the height. #. -#: ../src/ui/resizepopup.c:113 +#: ../src/ui/resizepopup.c:134 #, c-format msgid "%d x %d" msgstr "%d x %d" -#: ../src/ui/theme.c:253 +#: ../src/ui/theme.c:233 msgid "top" msgstr "மேல்" -#: ../src/ui/theme.c:255 +#: ../src/ui/theme.c:235 msgid "bottom" msgstr "கீழ்" -#: ../src/ui/theme.c:257 +#: ../src/ui/theme.c:237 msgid "left" msgstr "இடது" -#: ../src/ui/theme.c:259 +#: ../src/ui/theme.c:239 msgid "right" msgstr "வலது" -#: ../src/ui/theme.c:286 +#: ../src/ui/theme.c:267 #, c-format msgid "frame geometry does not specify \"%s\" dimension" msgstr "சட்ட வடிவியல் \"%s\" அளவை குறிப்பிடவில்லை" -#: ../src/ui/theme.c:305 +#: ../src/ui/theme.c:286 #, c-format msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" msgstr "\"%s\" ஓரத்திற்கு வடிவியல் \"%s\" அளவை குறிப்பிடவில்லை" -#: ../src/ui/theme.c:342 +#: ../src/ui/theme.c:323 #, c-format msgid "Button aspect ratio %g is not reasonable" msgstr "பட்டன் அளவு விகிதம் %g சரியில்ல" -#: ../src/ui/theme.c:354 +#: ../src/ui/theme.c:335 #, c-format msgid "Frame geometry does not specify size of buttons" msgstr "சட்ட அளவு பட்டன் அளவை குறிப்பிடவில்லை" -#: ../src/ui/theme.c:1067 +#: ../src/ui/theme.c:1061 #, c-format msgid "Gradients should have at least two colors" msgstr "க்ரேடியன்டில் இரண்டு நிறங்களாவது இருக்க வேண்டும்" -#: ../src/ui/theme.c:1219 +#: ../src/ui/theme.c:1211 #, c-format msgid "" "GTK custom color specification must have color name and fallback in " "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" msgstr "" -"GTK தனிப்பயன் வண்ணத்தின் பெயர் வணத்தின் பெயரையும் காப்பை மூடிய அடைப்புக்குறிகளுக்குள்ளும் " +"GTK தனிப்பயன் வண்ணத்தின் பெயர் வணத்தின் பெயரையும் காப்பை மூடிய " +"அடைப்புக்குறிகளுக்குள்ளும் " "கொண்டிருக்க வேண்டும் உம் gtk:custom(foo,bar); \"%s\" ஐ பகுக்க முடியவில்லை" -#: ../src/ui/theme.c:1235 +#: ../src/ui/theme.c:1227 #, c-format msgid "" "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" "_ are valid" msgstr "" -"gtk:custom இன் color_name தருமதிப்பில் செல்லுபடியாகாத எழுத்துரு '%c' A-Za-z0-9-" +"gtk:custom இன் color_name தருமதிப்பில் செல்லுபடியாகாத எழுத்துரு '%c' " +"A-Za-z0-9-" "_ ஆகியன மட்டுமே செல்லுபடியாகும்." -#: ../src/ui/theme.c:1249 +#: ../src/ui/theme.c:1241 #, c-format msgid "" "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " @@ -801,35 +714,37 @@ msgstr "" "ஜிடிகே:தனிப்பயன் ஒழுங்கு \"gtk:custom(color_name,fallback)\", \"%s\" இந்த " "ஒழுங்குக்கு பொருந்தாது" -#: ../src/ui/theme.c:1294 +#: ../src/ui/theme.c:1286 #, c-format msgid "" "GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " "where NORMAL is the state; could not parse \"%s\"" msgstr "" -"GTK வண்ணம் அடைப்புக்குறிகளை கொண்டிருக்க வேண்டும் உம் gtk:fg[NORMAL] NORMAL நிலையை " +"GTK வண்ணம் அடைப்புக்குறிகளை கொண்டிருக்க வேண்டும் உம் gtk:fg[NORMAL] NORMAL " +"நிலையை " "குறிக்கும் பகுக்க முடியாது \"%s\"" -#: ../src/ui/theme.c:1308 +#: ../src/ui/theme.c:1300 #, c-format msgid "" "GTK color specification must have a close bracket after the state, e.g. gtk:" "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" msgstr "" -"GTK வண்ணம் மூடிய அடைப்புக்குறிகளை கொண்டிருக்க வேண்டும் உம் gtk:fg[NORMAL] NORMAL " +"GTK வண்ணம் மூடிய அடைப்புக்குறிகளை கொண்டிருக்க வேண்டும் உம் gtk:fg[NORMAL] " +"NORMAL " "நிலையை குறிக்கும் பகுக்க முடியாது \"%s\"" -#: ../src/ui/theme.c:1319 +#: ../src/ui/theme.c:1311 #, c-format msgid "Did not understand state \"%s\" in color specification" msgstr "நிலை \"%s\" வண்ண குறிப்பில் புரிந்துகொள்ள முடியவில்லை" -#: ../src/ui/theme.c:1332 +#: ../src/ui/theme.c:1324 #, c-format msgid "Did not understand color component \"%s\" in color specification" msgstr "நிலை \"%s\" வண்ண குறிப்பு பொருளில் புரிந்துகொள்ள முடியவில்லை" -#: ../src/ui/theme.c:1361 +#: ../src/ui/theme.c:1352 #, c-format msgid "" "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " @@ -838,153 +753,169 @@ msgstr "" "வளைந்த அமைப்பு \"blend/bg_color/fg_color/alpha\", \"%s\" இந்த வடிவமைப்பிற்கு " "பொருந்தாது" -#: ../src/ui/theme.c:1372 +#: ../src/ui/theme.c:1363 #, c-format msgid "Could not parse alpha value \"%s\" in blended color" msgstr "ஆம்ஃபா மதிப்பை \"%s\" வளைந்த நிறத்தில் பகுக்க முடியவில்லை" -#: ../src/ui/theme.c:1382 +#: ../src/ui/theme.c:1373 #, c-format msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "ஆல்ஃபா மதுப்பு \"%s\"வளைவு நிறத்தில் 0.0 க்கும் 1.0 க்கும் இடையில் இல்லை" +msgstr "" +"ஆல்ஃபா மதுப்பு \"%s\"வளைவு நிறத்தில் 0.0 க்கும் 1.0 க்கும் இடையில் இல்லை" -#: ../src/ui/theme.c:1429 +#: ../src/ui/theme.c:1419 #, c-format -msgid "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "நிழல் வடிவமைப்பு \"shade/base_color/factor\", \"%s\" இந்த அமைப்பிற்கு பொருந்தாது" +msgid "" +"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" +msgstr "" +"நிழல் வடிவமைப்பு \"shade/base_color/factor\", \"%s\" இந்த அமைப்பிற்கு " +"பொருந்தாது" -#: ../src/ui/theme.c:1440 +#: ../src/ui/theme.c:1430 #, c-format msgid "Could not parse shade factor \"%s\" in shaded color" msgstr "நிழல்விகிதத்தை \"%s\" நிறத்தோடு பகுக்க முடியாது" -#: ../src/ui/theme.c:1450 +#: ../src/ui/theme.c:1440 #, c-format msgid "Shade factor \"%s\" in shaded color is negative" msgstr "நிழல் விகிதம் \"%s\" முழுக்களாக உள்ளது " -#: ../src/ui/theme.c:1479 +#: ../src/ui/theme.c:1469 #, c-format msgid "Could not parse color \"%s\"" msgstr "\"%s\" நிறத்தை பகுக்க முடியவில்லை" -#: ../src/ui/theme.c:1790 +#: ../src/ui/theme.c:1778 #, c-format msgid "Coordinate expression contains character '%s' which is not allowed" msgstr "அச்சுக்கள் எழுத்தால் குறிக்கப்பட்டுள்ளது '%s' க்கு அனுமதி இல்லை" -#: ../src/ui/theme.c:1817 +#: ../src/ui/theme.c:1805 #, c-format msgid "" "Coordinate expression contains floating point number '%s' which could not be " "parsed" msgstr "அச்சுக்கள் பின்ன எண்ணால் குறிக்கப்பட்டுள்ளது '%s' ஐ பகுக்க முடியாது" -#: ../src/ui/theme.c:1831 +#: ../src/ui/theme.c:1819 #, c-format msgid "Coordinate expression contains integer '%s' which could not be parsed" msgstr "அச்சுக்கள் இயல் எண்ணால் குறிக்கப்பட்டுள்ளது '%s' ஐ பகுக்க முடியாது" -#: ../src/ui/theme.c:1953 +#: ../src/ui/theme.c:1940 #, c-format msgid "" "Coordinate expression contained unknown operator at the start of this text: " "\"%s\"" -msgstr "உரையின் துவக்கத்தில் அச்சின் கூற்றில் தெரியாத செயல் இடம்பெற்றுள்ளது \"%s\"" +msgstr "" +"உரையின் துவக்கத்தில் அச்சின் கூற்றில் தெரியாத செயல் இடம்பெற்றுள்ளது \"%s\"" -#: ../src/ui/theme.c:2010 +#: ../src/ui/theme.c:1997 #, c-format msgid "Coordinate expression was empty or not understood" msgstr "அச்சு கூற்று காலியாக உள்ளது அல்லது புரியவில்லை" -#: ../src/ui/theme.c:2121 ../src/ui/theme.c:2131 ../src/ui/theme.c:2165 +#: ../src/ui/theme.c:2110 ../src/ui/theme.c:2120 ../src/ui/theme.c:2154 #, c-format msgid "Coordinate expression results in division by zero" msgstr "அச்சு கூற்று பூஜ்ஜியத்தால் வகுத்தல் பிழையை தந்தது" -#: ../src/ui/theme.c:2173 +#: ../src/ui/theme.c:2162 #, c-format -msgid "Coordinate expression tries to use mod operator on a floating-point number" +msgid "" +"Coordinate expression tries to use mod operator on a floating-point number" msgstr "அச்சு கூற்று mod ஆப்பரேட்டரை பின்ன எண்ணில் பயன்படுத்த முயல்கிறது" -#: ../src/ui/theme.c:2229 +#: ../src/ui/theme.c:2218 #, c-format -msgid "Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "அச்சு கூற்றில் ஆப்பரேட்டர் உள்ளது \"%s\" ஆப்பரன் எதிர்பார்க்கப்படுகிறது" +msgid "" +"Coordinate expression has an operator \"%s\" where an operand was expected" +msgstr "" +"அச்சு கூற்றில் ஆப்பரேட்டர் உள்ளது \"%s\" ஆப்பரன் எதிர்பார்க்கப்படுகிறது" -#: ../src/ui/theme.c:2238 +#: ../src/ui/theme.c:2227 #, c-format msgid "Coordinate expression had an operand where an operator was expected" -msgstr "அச்சு கூற்றில் ஆப்பரன்ட் உள்ளது ஆனால் ஆப்பரேட்டர் எதிர்பார்க்கப்படுகிறது" +msgstr "" +"அச்சு கூற்றில் ஆப்பரன்ட் உள்ளது ஆனால் ஆப்பரேட்டர் எதிர்பார்க்கப்படுகிறது" -#: ../src/ui/theme.c:2246 +#: ../src/ui/theme.c:2235 #, c-format msgid "Coordinate expression ended with an operator instead of an operand" msgstr "அச்சு கூற்றில் ஆப்பரன்ட்டுக்கு பதில் ஆப்பரேட்டரால் முடிந்தது" -#: ../src/ui/theme.c:2256 +#: ../src/ui/theme.c:2245 #, c-format msgid "" "Coordinate expression has operator \"%c\" following operator \"%c\" with no " "operand in between" -msgstr "அச்சு கூற்றில் \"%c\" ஆப்பரேட்டர் உள்ளது \"%c\" ஆப்பரேட்டருக்கு ஆப்பரன்ட் இல்லை" +msgstr "" +"அச்சு கூற்றில் \"%c\" ஆப்பரேட்டர் உள்ளது \"%c\" ஆப்பரேட்டருக்கு ஆப்பரன்ட் " +"இல்லை" -#: ../src/ui/theme.c:2407 ../src/ui/theme.c:2452 +#: ../src/ui/theme.c:2396 ../src/ui/theme.c:2441 #, c-format msgid "Coordinate expression had unknown variable or constant \"%s\"" msgstr "அச்சு கூற்றில் செல்லாத மாற்றி மற்றும் கான்ஸ்ட்டன் உள்ளது \"%s\"" -#: ../src/ui/theme.c:2506 +#: ../src/ui/theme.c:2495 #, c-format msgid "Coordinate expression parser overflowed its buffer." msgstr "ஆயத்தொலைவு தெரிவிப்பு பகுப்பி அதன் இடையகத்தை நிரப்பியது" -#: ../src/ui/theme.c:2535 +#: ../src/ui/theme.c:2524 #, c-format msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "அச்சு கூற்றில் மூடிய அடைப்புக்குறி உள்ளது ஆனால் திறந்த அடைப்புகுறி இல்லை" +msgstr "" +"அச்சு கூற்றில் மூடிய அடைப்புக்குறி உள்ளது ஆனால் திறந்த அடைப்புகுறி இல்லை" -#: ../src/ui/theme.c:2599 +#: ../src/ui/theme.c:2588 #, c-format msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "அச்சு கூற்றில் திறந்த அடைப்புக்குறி உள்ளது ஆனால் மூடிய அடைப்புகுறி இல்லை" +msgstr "" +"அச்சு கூற்றில் திறந்த அடைப்புக்குறி உள்ளது ஆனால் மூடிய அடைப்புகுறி இல்லை" -#: ../src/ui/theme.c:2610 +#: ../src/ui/theme.c:2599 #, c-format msgid "Coordinate expression doesn't seem to have any operators or operands" msgstr "அச்சுக்கூற்றில் ஆப்பரன்ட் மற்றும் ஆப்பரேட்டர் காணப்படவில்லை" -#: ../src/ui/theme.c:2822 ../src/ui/theme.c:2842 ../src/ui/theme.c:2862 +#: ../src/ui/theme.c:2812 ../src/ui/theme.c:2832 ../src/ui/theme.c:2852 #, c-format msgid "Theme contained an expression that resulted in an error: %s\n" msgstr "கருப்பொருளில் ஒரு கூற்று இருந்தது. அது பிழையை ஏற்படுத்தியது : %s\n" -#: ../src/ui/theme.c:4533 +#: ../src/ui/theme.c:4455 #, c-format msgid "" "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " "specified for this frame style" msgstr "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> இந்த சட்ட பாணிக்கு " +"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> இந்த சட்ட " +"பாணிக்கு " "குறிப்பிடப்பட வேண்டும்" -#: ../src/ui/theme.c:5066 ../src/ui/theme.c:5091 +#: ../src/ui/theme.c:4970 ../src/ui/theme.c:4995 #, c-format -msgid "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "காணவில்லை <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" +msgid "" +"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" +msgstr "" +"காணவில்லை <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -#: ../src/ui/theme.c:5139 +#: ../src/ui/theme.c:5041 #, c-format msgid "Failed to load theme \"%s\": %s\n" msgstr "கருப்பொருளை ஏற்றுவதில் தோல்வி \"%s\": %s\n" -#: ../src/ui/theme.c:5275 ../src/ui/theme.c:5282 ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 ../src/ui/theme.c:5303 +#: ../src/ui/theme.c:5177 ../src/ui/theme.c:5184 ../src/ui/theme.c:5191 +#: ../src/ui/theme.c:5198 ../src/ui/theme.c:5205 #, c-format msgid "No <%s> set for theme \"%s\"" msgstr "இல்லை<%s> கருப்பொருளுக்காக அமைக்கப்பட்டது \"%s\"" -#: ../src/ui/theme.c:5311 +#: ../src/ui/theme.c:5213 #, c-format msgid "" "No frame style set for window type \"%s\" in theme \"%s\", add a <window " @@ -993,12 +924,15 @@ msgstr "" "சட்ட பாணி சாளர வகை இல்லை\"%s\" கருப்பொருளில் \"%s\", <window type=\"%s\" " "style_set=\"whatever\"/> உறுப்பை சேர்க்கவும்" -#: ../src/ui/theme.c:5709 ../src/ui/theme.c:5771 ../src/ui/theme.c:5834 +#: ../src/ui/theme.c:5620 ../src/ui/theme.c:5682 ../src/ui/theme.c:5745 #, c-format -msgid "User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "பயனீட்டாளர்-குறிப்பிட்ட கான்ஸ்டன் பெரிய எழுத்தில் துவங்க வேண்டும்; \"%s\" இல்லை" +msgid "" +"User-defined constants must begin with a capital letter; \"%s\" does not" +msgstr "" +"பயனீட்டாளர்-குறிப்பிட்ட கான்ஸ்டன் பெரிய எழுத்தில் துவங்க வேண்டும்; \"%s\" " +"இல்லை" -#: ../src/ui/theme.c:5717 ../src/ui/theme.c:5779 ../src/ui/theme.c:5842 +#: ../src/ui/theme.c:5628 ../src/ui/theme.c:5690 ../src/ui/theme.c:5753 #, c-format msgid "Constant \"%s\" has already been defined" msgstr "கான்ஸ்டன் \"%s\" ஏற்கெனவே குறிப்பிடப்பட்டது" @@ -1006,67 +940,67 @@ msgstr "கான்ஸ்டன் \"%s\" ஏற்கெனவே குறி #. Translators: This means that an attribute which should have been found #. * on an XML element was not in fact found. #. -#: ../src/ui/theme-parser.c:236 +#: ../src/ui/theme-parser.c:234 #, c-format msgid "No \"%s\" attribute on element <%s>" msgstr " \"%s\" பண்புகூறு உறுப்பில் இல்லை <%s>" -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 +#: ../src/ui/theme-parser.c:263 ../src/ui/theme-parser.c:281 #, c-format msgid "Line %d character %d: %s" msgstr "வரி %d எழுத்து %d: %s" -#: ../src/ui/theme-parser.c:479 +#: ../src/ui/theme-parser.c:481 #, c-format msgid "Attribute \"%s\" repeated twice on the same <%s> element" msgstr "பண்பு \"%s\" ஒரே உறுப்பில் இரண்டு முறை வந்துள்ளது <%s>" -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 +#: ../src/ui/theme-parser.c:505 ../src/ui/theme-parser.c:554 #, c-format msgid "Attribute \"%s\" is invalid on <%s> element in this context" msgstr "பண்பு \"%s\" <%s> இந்த பயன்பாட்டிற்கு செல்லாது" -#: ../src/ui/theme-parser.c:594 +#: ../src/ui/theme-parser.c:596 #, c-format msgid "Could not parse \"%s\" as an integer" msgstr "\"%s\" ஐ இயல் எண்ணாக பகுக்க முடியாது" -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 +#: ../src/ui/theme-parser.c:605 ../src/ui/theme-parser.c:660 #, c-format msgid "Did not understand trailing characters \"%s\" in string \"%s\"" msgstr "\"%s\" தொடரும் சரத்தில் \"%s\" சரத்தை புரிந்துகொள்ள முடியவில்லை" -#: ../src/ui/theme-parser.c:613 +#: ../src/ui/theme-parser.c:615 #, c-format msgid "Integer %ld must be positive" msgstr "இயல் எண் %ld முழு எண்ணாக இருக்க வேண்டும்" -#: ../src/ui/theme-parser.c:621 +#: ../src/ui/theme-parser.c:623 #, c-format msgid "Integer %ld is too large, current max is %d" msgstr "இயல் எண் %ld பெரிதாக இருக்கிறது, தற்போது அதிகபட்சம் %d" -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 +#: ../src/ui/theme-parser.c:651 ../src/ui/theme-parser.c:767 #, c-format msgid "Could not parse \"%s\" as a floating point number" msgstr "\"%s\" பின்ன எண் பகுக்க முடியாது" -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 +#: ../src/ui/theme-parser.c:682 ../src/ui/theme-parser.c:710 #, c-format msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" msgstr "பூலியன் மதிப்புகள் \"true\" அல்லது \"false\" \"%s\" இல்லை" -#: ../src/ui/theme-parser.c:735 +#: ../src/ui/theme-parser.c:737 #, c-format msgid "Angle must be between 0.0 and 360.0, was %g\n" msgstr "கோணம் 0.0 மற்றும் 360.0, இடைப்பட்டதாக இருக்க வேண்டும் %g\n" -#: ../src/ui/theme-parser.c:798 +#: ../src/ui/theme-parser.c:800 #, c-format msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" msgstr "ஆல்ஃபா 0.0 (பார்வைக்கு) மற்றும் 1.0 (முழுவதும் ஒலிபுகும்), %g\n" -#: ../src/ui/theme-parser.c:863 +#: ../src/ui/theme-parser.c:865 #, c-format msgid "" "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," @@ -1075,58 +1009,59 @@ msgstr "" "செல்லாத தலைப்பு அளவு \"%s\" ( xx-small,x-small,small,medium,large,x-large,xx-" "large)\n" -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 +#: ../src/ui/theme-parser.c:1021 ../src/ui/theme-parser.c:1084 +#: ../src/ui/theme-parser.c:1118 ../src/ui/theme-parser.c:1221 #, c-format msgid "<%s> name \"%s\" used a second time" msgstr "<%s> பெயர் \"%s\" இரண்டாது முறை பயன்படுத்தப்படுகிறது" -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 +#: ../src/ui/theme-parser.c:1033 ../src/ui/theme-parser.c:1130 +#: ../src/ui/theme-parser.c:1233 #, c-format msgid "<%s> parent \"%s\" has not been defined" msgstr "<%s> தாய் \"%s\" குறிப்பிடப்படவில்லை" -#: ../src/ui/theme-parser.c:1141 +#: ../src/ui/theme-parser.c:1143 #, c-format msgid "<%s> geometry \"%s\" has not been defined" msgstr "<%s> வடிவியல் \"%s\" குறிப்பிடப்படவில்லை" -#: ../src/ui/theme-parser.c:1154 +#: ../src/ui/theme-parser.c:1156 #, c-format msgid "<%s> must specify either a geometry or a parent that has a geometry" msgstr "<%s> வடிவியல் அல்லது வடிவியல் உள்ள மூலத்தை குறிப்பிடவேண்டும்" -#: ../src/ui/theme-parser.c:1196 +#: ../src/ui/theme-parser.c:1198 msgid "You must specify a background for an alpha value to be meaningful" -msgstr "ஆல்பா மதிப்பு அர்தமுள்ளதாக இருக்க நீங்கள் ஒரு பின்னணி ஐ குறிப்பிட வேண்டும்." +msgstr "" +"ஆல்பா மதிப்பு அர்தமுள்ளதாக இருக்க நீங்கள் ஒரு பின்னணி ஐ குறிப்பிட வேண்டும்." -#: ../src/ui/theme-parser.c:1264 +#: ../src/ui/theme-parser.c:1266 #, c-format msgid "Unknown type \"%s\" on <%s> element" msgstr "தெரியாத வகை \"%s\" <%s> உறுப்பில்" -#: ../src/ui/theme-parser.c:1275 +#: ../src/ui/theme-parser.c:1277 #, c-format msgid "Unknown style_set \"%s\" on <%s> element" msgstr "(_s)தெரியாத பாணி அமைப்பு \"%s\" <%s> உறுப்பில்" -#: ../src/ui/theme-parser.c:1283 +#: ../src/ui/theme-parser.c:1285 #, c-format msgid "Window type \"%s\" has already been assigned a style set" msgstr "சாளர வகை \"%s\" இந்த பாணிக்கு ஏற்கெனவே குறிப்பிடப்பட்டது" -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 +#: ../src/ui/theme-parser.c:1315 ../src/ui/theme-parser.c:1379 +#: ../src/ui/theme-parser.c:1605 ../src/ui/theme-parser.c:2840 +#: ../src/ui/theme-parser.c:2886 ../src/ui/theme-parser.c:3036 +#: ../src/ui/theme-parser.c:3272 ../src/ui/theme-parser.c:3310 +#: ../src/ui/theme-parser.c:3348 ../src/ui/theme-parser.c:3386 #, c-format msgid "Element <%s> is not allowed below <%s>" msgstr "உறுப்பு <%s> கீழே அனுமதிக்கப்படவில்லை <%s>" -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 +#: ../src/ui/theme-parser.c:1429 ../src/ui/theme-parser.c:1443 +#: ../src/ui/theme-parser.c:1488 msgid "" "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " "for buttons" @@ -1134,461 +1069,689 @@ msgstr "" " \"button_width\"/\"button_height\" மற்றும் \"aspect_ratio\" இரண்மையுமே " "பொத்தான்களுக்கு குறிப்பிட முடியாது." -#: ../src/ui/theme-parser.c:1450 +#: ../src/ui/theme-parser.c:1452 #, c-format msgid "Distance \"%s\" is unknown" msgstr "தூரன் \"%s\" தெரியாது" -#: ../src/ui/theme-parser.c:1495 +#: ../src/ui/theme-parser.c:1497 #, c-format msgid "Aspect ratio \"%s\" is unknown" msgstr "சீராக்க விகிதம் \"%s\" தெரியாது" -#: ../src/ui/theme-parser.c:1557 +#: ../src/ui/theme-parser.c:1559 #, c-format msgid "Border \"%s\" is unknown" msgstr "ஓரம் \"%s\" தெரியாது" -#: ../src/ui/theme-parser.c:1868 +#: ../src/ui/theme-parser.c:1870 #, c-format msgid "No \"start_angle\" or \"from\" attribute on element <%s>" msgstr "உறுப்பு <%s> இல் \"start_angle\" அல்லது \"from\" மதிப்புரு இல்லை " -#: ../src/ui/theme-parser.c:1875 +#: ../src/ui/theme-parser.c:1877 #, c-format msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" msgstr "உறுப்பு <%s> இல் \"extent_angle\" அல்லது \"to\" மதிப்புரு இல்லை " -#: ../src/ui/theme-parser.c:2115 +#: ../src/ui/theme-parser.c:2117 #, c-format msgid "Did not understand value \"%s\" for type of gradient" msgstr "இந்த ஒலிவிளைவிற்கான மதிப்பு \"%s\" ஐ புரிந்துகொள்ள முடியவில்லை" -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 +#: ../src/ui/theme-parser.c:2195 ../src/ui/theme-parser.c:2570 #, c-format msgid "Did not understand fill type \"%s\" for <%s> element" msgstr "இந்த உறுப்பிற்கான <%s> நிரப்பல் வகை \"%s\" ஐ புரிந்துகொள்ள முடியவில்லை" -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 +#: ../src/ui/theme-parser.c:2362 ../src/ui/theme-parser.c:2445 +#: ../src/ui/theme-parser.c:2508 #, c-format msgid "Did not understand state \"%s\" for <%s> element" msgstr "இந்த உறுப்பிற்கான <%s> நிலை \"%s\" ஐ புரிந்துகொள்ள முடியவில்லை" -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 +#: ../src/ui/theme-parser.c:2372 ../src/ui/theme-parser.c:2455 #, c-format msgid "Did not understand shadow \"%s\" for <%s> element" msgstr "இந்த உறுப்பிற்கான <%s> நிழல் \"%s\" ஐ புரிந்துகொள்ள முடியவில்லை" -#: ../src/ui/theme-parser.c:2380 +#: ../src/ui/theme-parser.c:2382 #, c-format msgid "Did not understand arrow \"%s\" for <%s> element" msgstr "இந்த உறுப்பிற்கான <%s> அம்புக்குறி \"%s\" ஐ புரிந்துகொள்ள முடியவில்லை" -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 +#: ../src/ui/theme-parser.c:2696 ../src/ui/theme-parser.c:2792 #, c-format msgid "No <draw_ops> called \"%s\" has been defined" msgstr "இல்லை <draw_ops> அழைக்கப்பட்ட \"%s\" குறிப்பிடப்பட்டது" -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 +#: ../src/ui/theme-parser.c:2708 ../src/ui/theme-parser.c:2804 #, c-format msgid "Including draw_ops \"%s\" here would create a circular reference" msgstr "draw_ops உம் சேர்த்து \"%s\" முழு குறிப்பை உருவாக்கும்" -#: ../src/ui/theme-parser.c:2917 +#: ../src/ui/theme-parser.c:2919 #, c-format msgid "Unknown position \"%s\" for frame piece" msgstr "சட்டம் ்தில் \"%s\" தெரியாத நிலை" -#: ../src/ui/theme-parser.c:2925 +#: ../src/ui/theme-parser.c:2927 #, c-format msgid "Frame style already has a piece at position %s" msgstr "%s இட சட்டம் ஏற்கெனவே உள்ளது" -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 +#: ../src/ui/theme-parser.c:2944 ../src/ui/theme-parser.c:3021 #, c-format msgid "No <draw_ops> with the name \"%s\" has been defined" msgstr "இல்லை <draw_ops> இந்த பெயர் \"%s\" எற்கெனவே குறிப்பிடப்பட்டது" -#: ../src/ui/theme-parser.c:2972 +#: ../src/ui/theme-parser.c:2974 #, c-format msgid "Unknown function \"%s\" for button" msgstr "\"%s\" பட்டனுக்கு தெரியாத செயல்" -#: ../src/ui/theme-parser.c:2982 +#: ../src/ui/theme-parser.c:2984 #, c-format msgid "Button function \"%s\" does not exist in this version (%d, need %d)" msgstr "பொத்தான் தொழிற்பாடு \"%s\" இந்த வடிவ நிலையில் இல்லை (%d, தேவை %d)" -#: ../src/ui/theme-parser.c:2994 +#: ../src/ui/theme-parser.c:2996 #, c-format msgid "Unknown state \"%s\" for button" msgstr "\"%s\" பட்டனுக்கு தெரியாத நிலை" -#: ../src/ui/theme-parser.c:3002 +#: ../src/ui/theme-parser.c:3004 #, c-format msgid "Frame style already has a button for function %s state %s" msgstr "%s நிலை %s இல் ஏற்கெனவே பட்டன் அல்லது செயல் உள்ளது" -#: ../src/ui/theme-parser.c:3073 +#: ../src/ui/theme-parser.c:3075 #, c-format msgid "\"%s\" is not a valid value for focus attribute" msgstr "\"%s\" குறிப்பு பண்பிற்கு இது செல்லாத மதிப்பு" -#: ../src/ui/theme-parser.c:3082 +#: ../src/ui/theme-parser.c:3084 #, c-format msgid "\"%s\" is not a valid value for state attribute" msgstr "\"%s\" நிலை பண்பிற்கு இது செல்லாத மதிப்பு" -#: ../src/ui/theme-parser.c:3092 +#: ../src/ui/theme-parser.c:3094 #, c-format msgid "A style called \"%s\" has not been defined" msgstr "பாணி \"%s\" குறிப்பிடப்படவில்லை" -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 +#: ../src/ui/theme-parser.c:3115 ../src/ui/theme-parser.c:3138 #, c-format msgid "\"%s\" is not a valid value for resize attribute" msgstr "\"%s\" அளவுமாற்ற ப்பு பண்பிற்கு இது செல்லாத மதிப்பு" -#: ../src/ui/theme-parser.c:3147 +#: ../src/ui/theme-parser.c:3149 #, c-format msgid "" "Should not have \"resize\" attribute on <%s> element for maximized/shaded " "states" -msgstr "<%s> உறுப்பில் பெரிதாக்கு/சிறிதாக்கு நிலையில் \"அளவு மாற்ற\" பண்பு இருக்கக்கூடாது" +msgstr "" +"<%s> உறுப்பில் பெரிதாக்கு/சிறிதாக்கு நிலையில் \"அளவு மாற்ற\" பண்பு " +"இருக்கக்கூடாது" -#: ../src/ui/theme-parser.c:3161 +#: ../src/ui/theme-parser.c:3163 #, c-format -msgid "Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "பெரிதாக்கிய நிலையில் <%s> உறுப்பு க்கு \"resize\" மதிப்புரு இருக்கக்கூடாது." +msgid "" +"Should not have \"resize\" attribute on <%s> element for maximized states" +msgstr "" +"பெரிதாக்கிய நிலையில் <%s> உறுப்பு க்கு \"resize\" மதிப்புரு இருக்கக்கூடாது." -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 +#: ../src/ui/theme-parser.c:3177 ../src/ui/theme-parser.c:3221 #, c-format msgid "Style has already been specified for state %s resize %s focus %s" -msgstr " %s அளவுமாற்று %s குறி %s ஆகியவைகளின் நிலை ஏற்கெனவே குறிப்பிடப்பட்டுள்ளது" +msgstr "" +" %s அளவுமாற்று %s குறி %s ஆகியவைகளின் நிலை ஏற்கெனவே குறிப்பிடப்பட்டுள்ளது" -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 +#: ../src/ui/theme-parser.c:3188 ../src/ui/theme-parser.c:3199 +#: ../src/ui/theme-parser.c:3210 ../src/ui/theme-parser.c:3232 +#: ../src/ui/theme-parser.c:3243 ../src/ui/theme-parser.c:3254 #, c-format msgid "Style has already been specified for state %s focus %s" msgstr "%s குறி %s ஆகியவைகளின் நிலை ஏற்கெனவே குறிப்பிடப்பட்டுள்ளது" -#: ../src/ui/theme-parser.c:3294 +#: ../src/ui/theme-parser.c:3293 msgid "" "Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " "attribute and also a <draw_ops> element, or specified two elements)" msgstr "" -"இரண்டு draw_ops கள் <piece> உறுப்பிற்கு இருக்கக்கூடாது (draw_ops ஐ குறிப்பிடும் " +"இரண்டு draw_ops கள் <piece> உறுப்பிற்கு இருக்கக்கூடாது (draw_ops ஐ " +"குறிப்பிடும் " "கருப்பொருள் மற்றும் அதன் பண்புகள் <draw_ops> அல்லது இரண்டும்)" -#: ../src/ui/theme-parser.c:3332 +#: ../src/ui/theme-parser.c:3331 msgid "" "Can't have a two draw_ops for a <button> element (theme specified a draw_ops " "attribute and also a <draw_ops> element, or specified two elements)" msgstr "" -"இரண்டு draw_ops கள் <button> உறுப்பிற்கு இருக்கக்கூடாது (draw_ops ஐ குறிப்பிடும் " +"இரண்டு draw_ops கள் <button> உறுப்பிற்கு இருக்கக்கூடாது (draw_ops ஐ " +"குறிப்பிடும் " "கருப்பொருள் மற்றும் அதன் பண்புகள் <draw_ops> அல்லது இரண்டும்)" -#: ../src/ui/theme-parser.c:3370 +#: ../src/ui/theme-parser.c:3369 msgid "" "Can't have a two draw_ops for a <menu_icon> element (theme specified a " "draw_ops attribute and also a <draw_ops> element, or specified two elements)" msgstr "" -"இரண்டு draw_ops கள் <menu_icon> உறுப்பிற்கு இருக்கக்கூடாது (draw_ops ஐ குறிப்பிடும் " +"இரண்டு draw_ops கள் <menu_icon> உறுப்பிற்கு இருக்கக்கூடாது (draw_ops ஐ " +"குறிப்பிடும் " "கருப்பொருள் மற்றும் அதன் பண்புகள் <draw_ops> அல்லது இரண்டும்)" -#: ../src/ui/theme-parser.c:3434 +#: ../src/ui/theme-parser.c:3433 #, c-format msgid "Bad version specification '%s'" msgstr "மோசமான பதிப்பு குறிப்பு '%s'" -#: ../src/ui/theme-parser.c:3507 +#: ../src/ui/theme-parser.c:3506 msgid "" "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" "theme-2.xml" msgstr "" -"\"பதிப்பு\" என்ற பண்புக்கூற்றை மெடாசிடி-கருத்து-1.xml அல்லது மெடாசிடி-கருத்து-2." +"\"பதிப்பு\" என்ற பண்புக்கூற்றை மெடாசிடி-கருத்து-1.xml அல்லது " +"மெடாசிடி-கருத்து-2." "xml இவற்றில் பயன்படுத்த முடியாது." -#: ../src/ui/theme-parser.c:3530 +#: ../src/ui/theme-parser.c:3529 #, c-format msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "கருத்துக்கு பதிப்பு %s தேவை. ஆனால் சமீபத்தில் ஆதரவு உள்ள கருத்து பதிப்பு %d.%d" +msgstr "" +"கருத்துக்கு பதிப்பு %s தேவை. ஆனால் சமீபத்தில் ஆதரவு உள்ள கருத்து பதிப்பு %d.%" +"d" -#: ../src/ui/theme-parser.c:3562 +#: ../src/ui/theme-parser.c:3561 #, c-format msgid "Outermost element in theme must be <metacity_theme> not <%s>" msgstr "கருப்பொருளின் மேம்பட்ட உறுப்பு<metacity_theme> <%s> இல்லை" -#: ../src/ui/theme-parser.c:3582 +#: ../src/ui/theme-parser.c:3581 #, c-format -msgid "Element <%s> is not allowed inside a name/author/date/description element" +msgid "" +"Element <%s> is not allowed inside a name/author/date/description element" msgstr "உறுப்பு <%s> name/author/date/description க்குள் அனுமதி இல்லை" -#: ../src/ui/theme-parser.c:3587 +#: ../src/ui/theme-parser.c:3586 #, c-format msgid "Element <%s> is not allowed inside a <constant> element" msgstr "உறுப்பு <%s> க்கு <constant> உறுப்பில் அனுமதி இல்லை" -#: ../src/ui/theme-parser.c:3599 +#: ../src/ui/theme-parser.c:3598 #, c-format -msgid "Element <%s> is not allowed inside a distance/border/aspect_ratio element" +msgid "" +"Element <%s> is not allowed inside a distance/border/aspect_ratio element" msgstr "உறுப்பு <%s> க்கு distance/border/aspect_ratio உறுப்பில் அனுமதி இல்லை" -#: ../src/ui/theme-parser.c:3621 +#: ../src/ui/theme-parser.c:3620 #, c-format msgid "Element <%s> is not allowed inside a draw operation element" msgstr "உறுப்பு <%s> க்கு வரையும் செயல்பாட்டில் பில் அனுமதி இல்லை" -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 +#: ../src/ui/theme-parser.c:3630 ../src/ui/theme-parser.c:3660 +#: ../src/ui/theme-parser.c:3665 ../src/ui/theme-parser.c:3670 #, c-format msgid "Element <%s> is not allowed inside a <%s> element" msgstr "உறுப்பு <%s> க்கு <%s> உறுப்பில் அனுமதி இல்லை" -#: ../src/ui/theme-parser.c:3899 +#: ../src/ui/theme-parser.c:3898 msgid "No draw_ops provided for frame piece" msgstr "சட்டத்திற்கு draw_ops தரப்படவில்லை" -#: ../src/ui/theme-parser.c:3914 +#: ../src/ui/theme-parser.c:3913 msgid "No draw_ops provided for button" msgstr "பட்டனுக்கு ்திற்கு draw_ops தரப்படவில்லை" -#: ../src/ui/theme-parser.c:3968 +#: ../src/ui/theme-parser.c:3967 #, c-format msgid "No text is allowed inside element <%s>" msgstr "உறுப்பிற்குள் உரை அனுமதி இல்லை<%s>" -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 +#: ../src/ui/theme-parser.c:4025 ../src/ui/theme-parser.c:4037 +#: ../src/ui/theme-parser.c:4049 ../src/ui/theme-parser.c:4061 +#: ../src/ui/theme-parser.c:4073 #, c-format msgid "<%s> specified twice for this theme" msgstr "<%s> இந்த கருப்பொருளுக்கு இரண்டுமுறை குறிப்பிட்டுள்ளது" -#: ../src/ui/theme-parser.c:4348 +#: ../src/ui/theme-parser.c:4335 #, c-format msgid "Failed to find a valid file for theme %s\n" msgstr "%s கருத்துக்கு செல்லுபடியாகும் கோப்பு கண்டுபிடித்தல் தோல்வியுற்றது \n" -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "_W சாளரங்கள்" +#: ../src/x11/session.c:1815 +msgid "" +"These windows do not support "save current setup" and will have to " +"be restarted manually next time you log in." +msgstr "" +" "தற்போதைய அமைப்பை சேமி" செயலுக்கு ஆதரவு இல்லை மேலும் அடுத்த முறை " +"உள்நுழையும் போது நீங்களாக துவக்க வேண்டும்" -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "_D உரையாடல்" +#: ../src/x11/window-props.c:515 +#, c-format +msgid "%s (on %s)" +msgstr "%s (%s மீது)" -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "_M மாதிரி உரையாடல்" +#~ msgid "background texture could not be created from file" +#~ msgstr "கோப்பிலிருந்து பின் புல இழை நய அமைப்பை உருவாக்க முடியவில்லை." -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "_U பயன்பாடு" +#~ msgid "Unknown window information request: %d" +#~ msgstr "தெரியாத சாளர தகவல் வேண்டுகோள்: %d" -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "_S துவக்கத் திரை" +#~ msgid "Missing %s extension required for compositing" +#~ msgstr "நீட்சி %s காணப்படவில்லை பவின் ஆக்கத்துக்கு அது அவசியம்" -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "_T மேல் துறை " +#~ msgid "" +#~ "Some other program is already using the key %s with modifiers %x as a " +#~ "binding\n" +#~ msgstr "விசை %s ஐ மாற்றி %x ஓடு இணைத்து வேறு நிரல் பயன்படுத்திக்கொண்டிருக்கிறது\n" -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "_B கீழ் துறை" +#~ msgid "\"%s\" is not a valid accelerator\n" +#~ msgstr "\"%s\" செல்லாத முடுக்கி\n" -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "_L இடது துறை " +#~ msgid "" +#~ "Workarounds for broken applications disabled. Some applications may not " +#~ "behave properly.\n" +#~ msgstr "" +#~ "உடைந்த பயன்பாடுகளின் செயல்பாடு தடைசெய்யப்பட்டது, சில பயன்பாடுகள் சரியாக வேலை " +#~ "செய்யாது.\n" -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "_R வலது துறை" +#~ msgid "Could not parse font description \"%s\" from GSettings key %s\n" +#~ msgstr "" +#~ "எழுத்துரு விளக்கம் \"%s\" ஐ ஜிசெட்டிங்க்ஸ் விசையிலிருந்து பகுக்க முடியவில்லை %s\n" -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "_A எல்லாத் துறைகளும்" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" +#~ msgstr "அமைப்பு பாங்கில் உள்ள \"%s\" சுட்டி பட்டன் மாற்றியில் செல்லாத மதிப்பு\n" -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "_k மேல்மேசை" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for " +#~ "keybinding \"%s\"\n" +#~ msgstr "\"%s\" அமைப்பு தரவுத்தளத்தில் உள்ள மதிப்பு செல்லாத கீபைன்டிங்\"%s\"\n" -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "இந்த சாளரத்தின் மற்றுமொரு சாளரம்" +#~ msgid "" +#~ "Could not acquire window manager selection on screen %d display \"%s\"\n" +#~ msgstr "திரையில் சாளர மேலாளர் தேர்வை பெறமுடியவில்லை %d காட்சி \"%s\"\n" -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "இது திற சின்னத்தோடு கூடிய சோதனை பட்டன்" +#~ msgid "Could not release screen %d on display \"%s\"\n" +#~ msgstr "திரை %d ஐ விடுவிக்க முடியவில்லை \"%s\"\n" -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "இது 'வெளிச்செல்' சின்னத்தோடு கூடிய சோதனை பட்டன்" +#~ msgid "Could not create directory '%s': %s\n" +#~ msgstr "அடைவை உருவாக்க முடியவில்லை '%s': %s\n" -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "இது உதாரண உரையாடல் பெட்டியில் உள்ள உதாரண செய்தி" +#~ msgid "Could not open session file '%s' for writing: %s\n" +#~ msgstr "அமர்வு கோப்பு '%s' எழுதுவதற்காக திறக்க முடியவில்லை: %s\n" -#: ../src/ui/theme-viewer.c:328 -#, c-format -msgid "Fake menu item %d\n" -msgstr "பெய்யான மெனு உருப்படி %d\n" +#~ msgid "Error writing session file '%s': %s\n" +#~ msgstr "அமர்வு கோப்பை எழுதுவதில் பிழை '%s': %s\n" -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "ஓரம்-மட்டும் சாளரம்" +#~ msgid "Error closing session file '%s': %s\n" +#~ msgstr "அமர்வுகோப்பை மூடுவதில் பிழை '%s': %s\n" -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "பட்டி" +#~ msgid "Failed to parse saved session file: %s\n" +#~ msgstr "சேமிக்கப்பட்ட அமர்வு கோப்பை பகுப்பதில் தோல்வி: %s\n" -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "தவறான சாளர பயன்பாடு" +#~ msgid "<mutter_session> attribute seen but we already have the session ID" +#~ msgstr "<mutter_session> பண்பு பார்க்கப்பட்டது ஆனால் இங்கு அமர்வு ID ஏற்கெனவே உள்ளது" -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "உரையாடல் பெட்டி" +#~ msgid "Unknown attribute %s on <%s> element" +#~ msgstr "தெரியாத பண்பு %s <%s> உறுப்பில்" -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "மாதிரி உரையாடல் பெட்டி" +#~ msgid "nested <window> tag" +#~ msgstr "பின்னப்பட்ட <window> குறி" -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "பயன்பாடு மாதிரி" +#~ msgid "Unknown element %s" +#~ msgstr "தெரியாத உறுப்பு %s" -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "Torn-off மெனு" +#~ msgid "Failed to open debug log: %s\n" +#~ msgstr "பிழைதிருத்த பட்டியலை திறப்பதில் தோல்வி: %s\n" -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "ஓரம்" +#~ msgid "Failed to fdopen() log file %s: %s\n" +#~ msgstr "fdopen() பதிவுக்கோப்பு தோல்வி %s: %s\n" -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "இணைத்த மாதிரி உரையாடல்" +#~ msgid "Opened log file %s\n" +#~ msgstr "பதிவுக்கோப்பு திறக்கப்பட்டது %s\n" -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "பட்டன் உருவரை சோதனை %d" +#~ msgid "Window manager: " +#~ msgstr "சாளர மேலாளர்:" -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g சாளரத்தை வரைய மில்லிசெக்கண்டு" +#~ msgid "Bug in window manager: " +#~ msgstr "சாளர மேலாளரில் பிழை" -#: ../src/ui/theme-viewer.c:813 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "பயன்பாடு: metacity-theme-viewer [THEMENAME]\n" +#~ msgid "Window manager warning: " +#~ msgstr "சாளர மேலாளர் எச்சரிக்கை:" -#: ../src/ui/theme-viewer.c:820 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "கருப்பொருளை ஏற்றுவதில் பிழை: %s\n" +#~ msgid "Window manager error: " +#~ msgstr "சாளர மேலாளர் பிழை" -#: ../src/ui/theme-viewer.c:826 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "கருப்பொருள் \"%s\" %g செகண்டில்\n" +#~ msgid "" +#~ "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " +#~ "window as specified in the ICCCM.\n" +#~ msgstr "" +#~ "சாளரம் %s SM_CLIENT_ID இன் மேல் உள்ளது, WM_CLIENT_LEADER சாளரத்தில் குறிப்பிட்டது " +#~ "போல் ICCCM.\n" -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "இயல்பான தலைப்பு எழுத்துரு" +#~ msgid "" +#~ "Window %s sets an MWM hint indicating it isn't resizable, but sets min " +#~ "size %d x %d and max size %d x %d; this doesn't make much sense.\n" +#~ msgstr "" +#~ "சாளரம் %s MWM அளவு மாற்ற முடியும் என குறிப்பிடுகிறதும் ஆனால் %d x %d மற்றும் அதிக " +#~ "பட்ச அளவு %d x %d; பொருள் தரும்படி இல்லை.\n" -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "சிறிய தலைப்பு எழுத்துரு" +#~ msgid "Application set a bogus _NET_WM_PID %lu\n" +#~ msgstr "பயன்பாடு பொய்யான ஒரு _NET_WM_PID %lu ஐ அமைத்தது\n" -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "பெரிய தலைப்பு எழுத்துரு" +#~ msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +#~ msgstr "செல்லாத WM_TRANSIENT_FOR சாளரம் 0x%lx இதற்கு குறிக்கப்பட்டது: %s.\n" -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "பட்டன் உருவரை" +#~ msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" +#~ msgstr "WM_TRANSIENT_FOR சாளரம் 0x%lx %s க்கு சுழல் நிகழ்வை உருவாக்கும்.\n" -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "நிர்ணயம்" +#~ msgid "" +#~ "Window 0x%lx has property %s\n" +#~ "that was expected to have type %s format %d\n" +#~ "and actually has type %s format %d n_items %d.\n" +#~ "This is most likely an application bug, not a window manager bug.\n" +#~ "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +#~ msgstr "" +#~ "சாளரம் 0x%lx பண்பு %s உள்ளது\n" +#~ "இதில் %s வகை %d வடிவமைப்பு எதிர்பார்க்கப்பட்டது\n" +#~ "ஆனால் வகை %s வடிவமைப்பு %d n_items %d முறை உள்ளது.\n" +#~ "இது பயன்பாட்டு பிழையாக இருக்கலாம், சாளர மேலாளர் பிழை இல்லை.\n" +#~ "சாளரத்தில் title=\"%s\" class=\"%s\" name=\"%s\" உள்ளது\n" -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "சாளர தலைப்பு இங்கே" +#~ msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +#~ msgstr "பண்பு %s சாளரம் 0x%lx செல்லாத UTF-8 உள்ளது\n" -#: ../src/ui/theme-viewer.c:1047 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"%d சட்டங்கள் %g புரவலனில் செகண்டிலும் (%g சட்டத்தின் மில்லி செக்கண்டு ) %g X சேவகனின் " -"மூலத்தில் (%g மில்லி செகண்ட் சட்டத்திற்கு)\n" +#~ msgid "" +#~ "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the " +#~ "list\n" +#~ msgstr "பண்பு %s சாளரம் 0x%lx செல்லாத UTF-8 உருப்படி %d பட்டியலில் உள்ளது\n" -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "நிலை கூற்று சோதனை உண்மையை தந்தது ஆனால் பிழை" +#~ msgid "Usage: %s\n" +#~ msgstr "பயன்பாடு: %s\n" -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "நிலை கூற்று சோதனை பொய்யை தந்தது ஆனால் பிழை" +#~ msgid "Mi_nimize" +#~ msgstr "குறுக்கவும் (_n)" -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "பிழை எதிர்பார்க்கப்பட்டடு ஆனால் தரப்படவில்லை" +#~ msgid "Ma_ximize" +#~ msgstr "பெரிதாக்கவும் (_x)" -#: ../src/ui/theme-viewer.c:1274 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "பிழை %d எதிர்பார்க்கப்பட்டது %d தரப்படவில்லை" +#~ msgid "Unma_ximize" +#~ msgstr "பெரிதாக்காத (_x)" -#: ../src/ui/theme-viewer.c:1280 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "பிழை எதிர்பார்க்கப்பட்டடு ஆனால் தரப்படவில்லை: %s" +#~ msgid "Roll _Up" +#~ msgstr "மேலே சுருட்டு" -#: ../src/ui/theme-viewer.c:1284 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "x மதிப்பு %d, %d எதிர்பார்க்கப்பட்டது" +#~ msgid "_Unroll" +#~ msgstr "கீழ் விரி (_U)" -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "y மதிப்பு %d, %d எதிர்பார்க்கப்பட்டது" +#~ msgid "_Move" +#~ msgstr "நகர்த்தவும் (_M)" -#: ../src/ui/theme-viewer.c:1352 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "%d அச்சு கூற்று பகுக்கப்பட்டது %g செகண்டில் (%g சராசரி செகண்ட்)\n" +#~ msgid "_Resize" +#~ msgstr "மறுஅளவு (_R)" + +#~ msgid "Move Titlebar On_screen" +#~ msgstr "தலைப்புப்பட்டையை திரைக்கு நகர்த்தவும் (_s)" + +#~ msgid "Always on _Top" +#~ msgstr "எப்போதும் மேலே (_T)" + +#~ msgid "_Always on Visible Workspace" +#~ msgstr "எப்போதும் தெரியும் வேலையிடத்தில் (_A)" + +#~ msgid "_Only on This Workspace" +#~ msgstr "இந்த வேலையிடத்தில் மட்டும் (_O)" + +#~ msgid "Move to Workspace _Left" +#~ msgstr "வேலையிடத்தின் இடப்பக்கத்திற்கு நகர்த்தவும் (_L)" + +#~ msgid "Move to Workspace R_ight" +#~ msgstr "வேலையிடத்தின் வலப்பக்கத்திற்கு நகர்த்தவும் (_i)" + +#~ msgid "Move to Workspace _Up" +#~ msgstr "வேலையிடத்தின் மேலே நகர்த்தவும் (_U)" + +#~ msgid "Move to Workspace _Down" +#~ msgstr "வேலையிடத்தின் கீழே நகர்த்தவும் (_D)" + +#~ msgid "_Close" +#~ msgstr "மூடவும் (_C)" + +#~ msgid "Workspace %d%n" +#~ msgstr "பணியிடம் %d%n" + +#~ msgid "Workspace 1_0" +#~ msgstr "வேலையிடம் 1_0" + +#~ msgid "Workspace %s%d" +#~ msgstr "வேலையிடம் %s%d" + +#~ msgid "Move to Another _Workspace" +#~ msgstr "மற்ற வேலையிடத்திற்கு மாற்றவும் (_W)" + +#~ msgid "Shift" +#~ msgstr "Shift" + +#~ msgid "Ctrl" +#~ msgstr "Ctrl" + +#~ msgid "Alt" +#~ msgstr "Alt" + +#~ msgid "Meta" +#~ msgstr "Meta" + +#~ msgid "Super" +#~ msgstr "Super" + +#~ msgid "Hyper" +#~ msgstr "Hyper" + +#~ msgid "Mod2" +#~ msgstr "Mod2" + +#~ msgid "Mod3" +#~ msgstr "Mod3" + +#~ msgid "Mod4" +#~ msgstr "Mod4" + +#~ msgid "Mod5" +#~ msgstr "Mod5" + +#~ msgid "_Windows" +#~ msgstr "_W சாளரங்கள்" + +#~ msgid "_Dialog" +#~ msgstr "_D உரையாடல்" + +#~ msgid "_Modal dialog" +#~ msgstr "_M மாதிரி உரையாடல்" + +#~ msgid "_Utility" +#~ msgstr "_U பயன்பாடு" + +#~ msgid "_Splashscreen" +#~ msgstr "_S துவக்கத் திரை" + +#~ msgid "_Top dock" +#~ msgstr "_T மேல் துறை " + +#~ msgid "_Bottom dock" +#~ msgstr "_B கீழ் துறை" + +#~ msgid "_Left dock" +#~ msgstr "_L இடது துறை " + +#~ msgid "_Right dock" +#~ msgstr "_R வலது துறை" + +#~ msgid "_All docks" +#~ msgstr "_A எல்லாத் துறைகளும்" + +#~ msgid "Des_ktop" +#~ msgstr "_k மேல்மேசை" + +#~ msgid "Open another one of these windows" +#~ msgstr "இந்த சாளரத்தின் மற்றுமொரு சாளரம்" + +#~ msgid "This is a demo button with an 'open' icon" +#~ msgstr "இது திற சின்னத்தோடு கூடிய சோதனை பட்டன்" + +#~ msgid "This is a demo button with a 'quit' icon" +#~ msgstr "இது 'வெளிச்செல்' சின்னத்தோடு கூடிய சோதனை பட்டன்" + +#~ msgid "This is a sample message in a sample dialog" +#~ msgstr "இது உதாரண உரையாடல் பெட்டியில் உள்ள உதாரண செய்தி" + +#~ msgid "Fake menu item %d\n" +#~ msgstr "பெய்யான மெனு உருப்படி %d\n" + +#~ msgid "Border-only window" +#~ msgstr "ஓரம்-மட்டும் சாளரம்" + +#~ msgid "Bar" +#~ msgstr "பட்டி" + +#~ msgid "Normal Application Window" +#~ msgstr "தவறான சாளர பயன்பாடு" + +#~ msgid "Dialog Box" +#~ msgstr "உரையாடல் பெட்டி" + +#~ msgid "Modal Dialog Box" +#~ msgstr "மாதிரி உரையாடல் பெட்டி" + +#~ msgid "Utility Palette" +#~ msgstr "பயன்பாடு மாதிரி" + +#~ msgid "Torn-off Menu" +#~ msgstr "Torn-off மெனு" + +#~ msgid "Border" +#~ msgstr "ஓரம்" + +#~ msgid "Attached Modal Dialog" +#~ msgstr "இணைத்த மாதிரி உரையாடல்" + +#~ msgid "Button layout test %d" +#~ msgstr "பட்டன் உருவரை சோதனை %d" + +#~ msgid "%g milliseconds to draw one window frame" +#~ msgstr "%g சாளரத்தை வரைய மில்லிசெக்கண்டு" + +#~ msgid "Usage: metacity-theme-viewer [THEMENAME]\n" +#~ msgstr "பயன்பாடு: metacity-theme-viewer [THEMENAME]\n" + +#~ msgid "Error loading theme: %s\n" +#~ msgstr "கருப்பொருளை ஏற்றுவதில் பிழை: %s\n" + +#~ msgid "Loaded theme \"%s\" in %g seconds\n" +#~ msgstr "கருப்பொருள் \"%s\" %g செகண்டில்\n" + +#~ msgid "Normal Title Font" +#~ msgstr "இயல்பான தலைப்பு எழுத்துரு" + +#~ msgid "Small Title Font" +#~ msgstr "சிறிய தலைப்பு எழுத்துரு" + +#~ msgid "Large Title Font" +#~ msgstr "பெரிய தலைப்பு எழுத்துரு" -#~ msgid "Switch to workspace 1" -#~ msgstr "பணியிடம் 1க்கு மாறு" +#~ msgid "Button Layouts" +#~ msgstr "பட்டன் உருவரை" -#~ msgid "Switch to workspace 2" -#~ msgstr "பணியிடம் 2 க்கு மாறு" +#~ msgid "Benchmark" +#~ msgstr "நிர்ணயம்" -#~ msgid "Switch to workspace 3" -#~ msgstr "பணியிடம் 3 க்கு மாறு" +#~ msgid "Window Title Goes Here" +#~ msgstr "சாளர தலைப்பு இங்கே" -#~ msgid "Switch to workspace 4" -#~ msgstr "பணியிடம் 4 க்கு மாறு" +#~ msgid "" +#~ "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and " +#~ "%g seconds wall clock time including X server resources (%g milliseconds " +#~ "per frame)\n" +#~ msgstr "" +#~ "%d சட்டங்கள் %g புரவலனில் செகண்டிலும் (%g சட்டத்தின் மில்லி செக்கண்டு ) %g X சேவகனின் " +#~ "மூலத்தில் (%g மில்லி செகண்ட் சட்டத்திற்கு)\n" + +#~ msgid "position expression test returned TRUE but set error" +#~ msgstr "நிலை கூற்று சோதனை உண்மையை தந்தது ஆனால் பிழை" + +#~ msgid "position expression test returned FALSE but didn't set error" +#~ msgstr "நிலை கூற்று சோதனை பொய்யை தந்தது ஆனால் பிழை" + +#~ msgid "Error was expected but none given" +#~ msgstr "பிழை எதிர்பார்க்கப்பட்டடு ஆனால் தரப்படவில்லை" + +#~ msgid "Error %d was expected but %d given" +#~ msgstr "பிழை %d எதிர்பார்க்கப்பட்டது %d தரப்படவில்லை" + +#~ msgid "Error not expected but one was returned: %s" +#~ msgstr "பிழை எதிர்பார்க்கப்பட்டடு ஆனால் தரப்படவில்லை: %s" + +#~ msgid "x value was %d, %d was expected" +#~ msgstr "x மதிப்பு %d, %d எதிர்பார்க்கப்பட்டது" + +#~ msgid "y value was %d, %d was expected" +#~ msgstr "y மதிப்பு %d, %d எதிர்பார்க்கப்பட்டது" + +#~ msgid "" +#~ "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" +#~ msgstr "%d அச்சு கூற்று பகுக்கப்பட்டது %g செகண்டில் (%g சராசரி செகண்ட்)\n" + +#~ msgid "Minimize window" +#~ msgstr "சாளரத்தை சிறிதாக்கு" + +#~ msgid "Comma-separated list of compositor plugins" +#~ msgstr "பல்வினையாக்கியின் சொருகிகளின் கமாவால் பிரித்த பட்டியல்." -#~ msgid "Switch to workspace 5" -#~ msgstr "பணியிடம் 5 க்கு மாறு" +#~ msgid "" +#~ "Determines whether hidden windows (i.e., minimized windows and windows on " +#~ "other workspaces than the current one) should be kept alive." +#~ msgstr "" +#~ "மறைந்துள்ள சாளரங்கள் (அதாவது குறூக்கியவை, நடப்பில் இல்லாத வேறு பணிக்களத்தில் உள்ளவை) " +#~ "உயிர்ப்புடன் வைக்கப்பட வேண்டுமா என தீர்மானிக்கிறது." + +#~ msgid "Live Hidden Windows" +#~ msgstr "உயிர்ப்புள்ள மறைந்த சாளரங்கள்" + +#~ msgid "Close Window" +#~ msgstr "சாளரம் மூடவும்" + +#~ msgid "Window Menu" +#~ msgstr "சாளர பட்டி" -#~ msgid "Switch to workspace 6" -#~ msgstr "பணியிடம் 6 க்கு மாறு" +#~ msgid "Minimize Window" +#~ msgstr "சாளரத்தை குறுக்கவும்" -#~ msgid "Switch to workspace 7" -#~ msgstr "பணியிடம் 7 க்கு மாறு" +#~ msgid "Maximize Window" +#~ msgstr "சாளரத்தை பெரிதாக்கவும்" + +#~ msgid "Restore Window" +#~ msgstr "சாளரத்தை மீட்டமை" + +#~ msgid "Roll Up Window" +#~ msgstr "சாளரத்தை மேலே சுருட்டு" + +#~ msgid "Unroll Window" +#~ msgstr "சாளரம் விரிக்கவும்" + +#~ msgid "Keep Window On Top" +#~ msgstr "சாளரத்தை மேலே வைத்திரு " + +#~ msgid "Remove Window From Top" +#~ msgstr "மேலிருந்து சாளரத்தை நீக்கு " + +#~ msgid "Always On Visible Workspace" +#~ msgstr "வேலைகளத்தில் எப்போதும் தெரியும் " + +#~ msgid "Put Window On Only One Workspace" +#~ msgstr "சாளரத்தை ஒரே ஒரு பணியிடத்தில் மட்டும் வைக்கவும்" #~ msgid "Switch to workspace 8" #~ msgstr "பணியிடம் 8 க்கு மாறு" @@ -1675,55 +1838,13 @@ msgstr "%d அச்சு கூற்று பகுக்கப்பட் #~ msgid "Run a terminal" #~ msgstr "முனையம் ஒன்றை இயக்கு" -#~ msgid "Activate the window menu" -#~ msgstr "சாளர பட்டியலை செயல்படுத்து " - -#~ msgid "Toggle fullscreen mode" -#~ msgstr "எப்போதும் முழுதிரை பாங்கிற்கு செல்" - -#~ msgid "Toggle maximization state" -#~ msgstr "எப்போதும் பெரிய சாளர நிலைக்கு செல்" - #~ msgid "Toggle whether a window will always be visible over other windows" #~ msgstr "ஒரு சாளரம் மற்றவற்றின் மேலே எப்போதும் இருக்குமா என்பதை நிலைமாற்று" -#~ msgid "Maximize window" -#~ msgstr "சாளரத்தை பெரிதாக்கு" - -#~ msgid "Restore window" -#~ msgstr "சாளரத்தை மீட்டமை" - -#~ msgid "Toggle shaded state" -#~ msgstr "எப்போதும் நிழை நிலைக்கு செல்" - -#~ msgid "Minimize window" -#~ msgstr "சாளரத்தை சிறிதாக்கு" - -#~ msgid "Close window" -#~ msgstr "சாளரம் மூடவும்" - -#~ msgid "Move window" -#~ msgstr "சாளரத்தை நகர்த்தவும்" - -#~ msgid "Resize window" -#~ msgstr "சாளரத்தின் அளவை மாற்று" - #~ msgid "Toggle whether window is on all workspaces or just one" #~ msgstr "" #~ "சாளரம் எல்லா பணியிடங்களிலும் இருக்குமா அல்லது ஒள்றில் மட்டுமா என்பதை நிலைமாற்று" -#~ msgid "Move window to workspace 1" -#~ msgstr "பணியிடம் 1 க்கு சாளரத்தை நகர்த்தவும்" - -#~ msgid "Move window to workspace 2" -#~ msgstr "பணியிடம் 2 க்கு சாளரத்தை நகர்த்தவும்" - -#~ msgid "Move window to workspace 3" -#~ msgstr "பணியிடம் 3 க்கு சாளரத்தை நகர்த்தவும்" - -#~ msgid "Move window to workspace 4" -#~ msgstr "பணியிடம் 4 க்கு சாளரத்தை நகர்த்தவும்" - #~ msgid "Move window to workspace 5" #~ msgstr "பணியிடம் 5 க்கு சாளரத்தை நகர்த்தவும்" @@ -1748,33 +1869,9 @@ msgstr "%d அச்சு கூற்று பகுக்கப்பட் #~ msgid "Move window to workspace 12" #~ msgstr "பணியிடம் 12 க்கு சாளரத்தை நகர்த்தவும்" -#~ msgid "Move window one workspace to the left" -#~ msgstr "ஒருபணியிடத்திற்கு இடது பக்கம் சாளரத்தை நகர்த்தவும்" - -#~ msgid "Move window one workspace to the right" -#~ msgstr "ஒருபணியிடத்திற்கு வலதுபக்கம் சாளரத்தை நகர்த்தவும்" - -#~ msgid "Move window one workspace up" -#~ msgstr "ஒருபணியிடத்திற்கு மேலே சாளரத்தை நகர்த்தவும்" - -#~ msgid "Move window one workspace down" -#~ msgstr "ஒருபணியிடத்திற்கு கீழே சாளரத்தை நகர்த்தவும்" - #~ msgid "Raise window if it's covered by another window, otherwise lower it" #~ msgstr "வேறு சாளரத்தால் சாளரம் மூடப்பட்டு இருந்தால் அதை உயர்த்து இல்லையானால் தாழ்த்து" -#~ msgid "Raise window above other windows" -#~ msgstr "மற்ற சாளரத்திற்கு மேல் இந்த சாளரத்தை உயர்த்து" - -#~ msgid "Lower window below other windows" -#~ msgstr "மற்ற சாளரத்திற்கு கீழே சாளரத்தை வைக்கவும்" - -#~ msgid "Maximize window vertically" -#~ msgstr "சாளரத்தை இடவலமாக பெரிதாக்கு " - -#~ msgid "Maximize window horizontally" -#~ msgstr "சாளரத்தை செங்குத்தாக பெரிதாக்கு " - #~ msgid "Move window to north-west (top left) corner" #~ msgstr "சாளரத்தை வடமேற்கே (மேல் இடது) மூலைக்கு நகர்த்து " @@ -1884,9 +1981,6 @@ msgstr "%d அச்சு கூற்று பகுக்கப்பட் #~ msgid "Error setting clutter plugin list: %s\n" #~ msgstr "க்ளட்டர் சொருகிகளை அமைப்பதில் பிழை: %s\n" -#~ msgid "Clutter Plugins" -#~ msgstr "க்ளட்டர் செருகிகள்" - #~ msgid "Plugins to load for the Clutter-based compositing manager." #~ msgstr "க்ளட்டர் அடிப்பைடையிலான பலவின்ஆக்க மேலாளர் க்கு ஏற்ற வேண்டிய சொருகிகள்" @@ -2074,17 +2168,6 @@ msgstr "%d அச்சு கூற்று பகுக்கப்பட் #~ msgid "Enable Visual Bell" #~ msgstr "்சி மணகாட்சியாக ியை செயல்படுத்து" -#~ msgid "" -#~ "If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " -#~ "the focused window will be automatically raised after a delay specified " -#~ "by the auto_raise_delay key. This is not related to clicking on a window " -#~ "to raise it, nor to entering a window during drag-and-drop." -#~ msgstr "" -#~ "உண்மையெனில், குவியும் பாணி \"sloppy\" அல்லது \"mouse\" எனில் சிறிது தாமதத்திற்கு " -#~ "பிறகு சாளரம் தானாக மேலெழும் (தாமதம் auto_raise_delay விசையால் குறிக்கப்படும்). " -#~ "இதற்கும் ஒரு சாளரத்தை சொடுக்கி மேலெழச் செய்வதற்கும் அல்லது இழுத்து விடுதலில் ஒரு " -#~ "சாளரத்தில் நுழைவதற்கும் சம்பந்தமில்லை." - #~ msgid "" #~ "If true, ignore the titlebar_font option, and use the standard " #~ "application font for window titles." diff --git a/po/te.po b/po/te.po index 85c134cfa..1dd970e92 100644 --- a/po/te.po +++ b/po/te.po @@ -2,978 +2,936 @@ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Copyright (C) 2011 Swecha Telugu Localisation Team <localization@swecha.net>. +# # A Mohan Vamsee(Swecha Team)) <mohan.arza@ymail.com>, 2011, 2012. -# Sasi Bhushan Boddepalli <sasi@swecha.net>, 2012 +# Sasi Bhushan Boddepalli <sasi@swecha.net>, 2012. +# Praveen Illa <mail2ipn@gmail.com>, 2012. +# Krishnababu Krothapalli <kkrothap@redhat.com>, 2012, 2013, 2014. msgid "" msgstr "" "Project-Id-Version: metacity.gnome-2-26\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" "product=mutter&keywords=I18N+L10N&component=general\n" -"POT-Creation-Date: 2012-03-15 21:29+0000\n" -"PO-Revision-Date: 2012-03-16 17:03+0530\n" -"Last-Translator: Sasi Bhushan Boddepalli <sasi@swecha.net>\n" -"Language-Team: Telugu <indlinux-telugu@lists.sourceforge.net>\n" +"POT-Creation-Date: 2014-09-23 09:59+0000\n" +"PO-Revision-Date: 2014-09-23 17:35+0530\n" +"Last-Translator: Krishnababu Krothapalli <kkrothap@redhat.com>\n" +"Language-Team: Telugu <kde-i18n-doc@kde.org>\n" +"Language: te\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Language: te\n" -"X-Generator: KBabel 1.11.4\n" +"X-Generator: Lokalize 1.5\n" "Plural-Forms: nplurals=2; plural=(n!=1);\n" -"\n" -#: ../src/50-muffin-windows.xml.in.h:1 -#| msgid "_Windows" +#: ../data/50-mutter-navigation.xml.in.h:1 +msgid "Navigation" +msgstr "విహారణ" + +#: ../data/50-mutter-navigation.xml.in.h:2 +msgid "Move window to workspace 1" +msgstr "విండోని పనిప్రదేశము 1 నకు జరుపుము" + +#: ../data/50-mutter-navigation.xml.in.h:3 +msgid "Move window to workspace 2" +msgstr "విండోని పనిప్రదేశము 2 నకు జరుపుము" + +#: ../data/50-mutter-navigation.xml.in.h:4 +msgid "Move window to workspace 3" +msgstr "విండోని పనిప్రదేశము 3 నకు జరుపుము" + +#: ../data/50-mutter-navigation.xml.in.h:5 +msgid "Move window to workspace 4" +msgstr "విండోని పనిప్రదేశము 4 నకు జరుపుము" + +#: ../data/50-mutter-navigation.xml.in.h:6 +#| msgid "Move window to workspace 1" +msgid "Move window to last workspace" +msgstr "విండోను ఆఖరి పనిస్థలముకు కదుపుము" + +#: ../data/50-mutter-navigation.xml.in.h:7 +msgid "Move window one workspace to the left" +msgstr "విండో ఒక పనిప్రదేశమును ఎడమ వైపునకు జరుపుము" + +#: ../data/50-mutter-navigation.xml.in.h:8 +msgid "Move window one workspace to the right" +msgstr "విండో ఒక పనిప్రదేశమును కుడి వైపునకు జరుపుము" + +#: ../data/50-mutter-navigation.xml.in.h:9 +msgid "Move window one workspace up" +msgstr "విండో ఒక పనిప్రదేశమును పై వైపునకు జరుపుము" + +#: ../data/50-mutter-navigation.xml.in.h:10 +msgid "Move window one workspace down" +msgstr "విండో ఒక పనిప్రదేశమును కింది వైపునకు జరుపుము" + +#: ../data/50-mutter-navigation.xml.in.h:11 +#| msgid "Move window one workspace to the left" +msgid "Move window one monitor to the left" +msgstr "విండో ఒక మానిటర్ ఎడమ వైపునకు జరుపుము" + +#: ../data/50-mutter-navigation.xml.in.h:12 +#| msgid "Move window one workspace to the right" +msgid "Move window one monitor to the right" +msgstr "విండోను ఒక మానిటర్ కుడివైపు జరుపుము" + +#: ../data/50-mutter-navigation.xml.in.h:13 +#| msgid "Move window one workspace up" +msgid "Move window one monitor up" +msgstr "విండోను ఒక మానిటర్ పైకు జరుపుము" + +#: ../data/50-mutter-navigation.xml.in.h:14 +#| msgid "Move window one workspace down" +msgid "Move window one monitor down" +msgstr "విండోను ఒక మానిటర్ కిందకు జరుపుము" + +#: ../data/50-mutter-navigation.xml.in.h:15 +msgid "Switch applications" +msgstr "అనువర్తనాలను మార్చు" + +#: ../data/50-mutter-navigation.xml.in.h:16 +#| msgid "Switch applications" +msgid "Switch to previous application" +msgstr "మునుపటి అనువర్తనముకు మారుము" + +#: ../data/50-mutter-navigation.xml.in.h:17 +msgid "Switch windows" +msgstr "విండోలను మార్చు" + +#: ../data/50-mutter-navigation.xml.in.h:18 +#| msgid "Switch windows" +msgid "Switch to previous window" +msgstr "మునుపటి విండోకు మారుము" + +#: ../data/50-mutter-navigation.xml.in.h:19 +msgid "Switch windows of an application" +msgstr "అనువర్తనము యొక్క కిటికీల మధ్య మారు" + +#: ../data/50-mutter-navigation.xml.in.h:20 +#| msgid "Switch windows of an application" +msgid "Switch to previous window of an application" +msgstr "అనువర్తనము యొక్క మునుపటి విండోకు మారుము" + +#: ../data/50-mutter-navigation.xml.in.h:21 +msgid "Switch system controls" +msgstr "వ్యవస్థ నియంత్రణల మీట" + +#: ../data/50-mutter-navigation.xml.in.h:22 +#| msgid "Switch system controls" +msgid "Switch to previous system control" +msgstr "మునుపటి వ్యవస్థ నియంత్రికకు మారుము" + +#: ../data/50-mutter-navigation.xml.in.h:23 +msgid "Switch windows directly" +msgstr "సూటిగా కిటికీకు మీట" + +#: ../data/50-mutter-navigation.xml.in.h:24 +msgid "Switch directly to previous window" +msgstr "మునుపటి విండోకు నేరుగా మారు" + +#: ../data/50-mutter-navigation.xml.in.h:25 +msgid "Switch windows of an app directly" +msgstr "అనువర్తనము యొక్క కిటికీలమద్య సూటిగా కదులుము" + +#: ../data/50-mutter-navigation.xml.in.h:26 +#| msgid "Switch windows of an application" +msgid "Switch directly to previous window of an app" +msgstr "అనువర్తనము యొక్క మునుపటి విండోకు నేరుగా మారుము" + +#: ../data/50-mutter-navigation.xml.in.h:27 +msgid "Switch system controls directly" +msgstr "సూటిగా వ్యవస్థ నియంత్రణకు మీట" + +#: ../data/50-mutter-navigation.xml.in.h:28 +#| msgid "Switch system controls" +msgid "Switch directly to previous system control" +msgstr "మునుపటి వ్యవస్థ నియంత్రికకు మారుము" + +#: ../data/50-mutter-navigation.xml.in.h:29 +msgid "Hide all normal windows" +msgstr "అన్ని సాధారణ కిటికీలను దాయి" + +#: ../data/50-mutter-navigation.xml.in.h:30 +msgid "Switch to workspace 1" +msgstr "పనిప్రదేశము 1 కి మారుము" + +#: ../data/50-mutter-navigation.xml.in.h:31 +msgid "Switch to workspace 2" +msgstr "పనిప్రదేశము 2 కి మారుము" + +#: ../data/50-mutter-navigation.xml.in.h:32 +msgid "Switch to workspace 3" +msgstr "పనిప్రదేశము 3 కి మారుము" + +#: ../data/50-mutter-navigation.xml.in.h:33 +msgid "Switch to workspace 4" +msgstr "పనిప్రదేశము 4 కి మారుము" + +#: ../data/50-mutter-navigation.xml.in.h:34 +#| msgid "Switch to workspace 1" +msgid "Switch to last workspace" +msgstr "ఆఖరి పనిప్రదేశముకి మారుము" + +#: ../data/50-mutter-navigation.xml.in.h:35 +msgid "Move to workspace left" +msgstr "కార్యక్షేత్రం నుండి ఎడమవైపుకు కదులు " + +#: ../data/50-mutter-navigation.xml.in.h:36 +msgid "Move to workspace right" +msgstr "కార్యక్షేత్రం నుండి కుడివైపుకు కదులు " + +#: ../data/50-mutter-navigation.xml.in.h:37 +msgid "Move to workspace above" +msgstr "కార్యక్షేత్రం నుండి ఎడమవైపుకు కదులు" + +#: ../data/50-mutter-navigation.xml.in.h:38 +msgid "Move to workspace below" +msgstr "కార్యక్షేత్రం నుండి కదులు " + +#: ../data/50-mutter-system.xml.in.h:1 +msgid "System" +msgstr "వ్యవస్థ" + +#: ../data/50-mutter-system.xml.in.h:2 +msgid "Show the run command prompt" +msgstr "రన్ కమాండు మెనూను చూపించు" + +#: ../data/50-mutter-system.xml.in.h:3 +msgid "Show the activities overview" +msgstr "కార్యకలాపాల పై పై పరిశీలనను చూపించు" + +#: ../data/50-mutter-windows.xml.in.h:1 msgid "Windows" -msgstr "గవాక్షములు" +msgstr "కిటికీలు" -#: ../src/50-muffin-windows.xml.in.h:2 -msgid "View split on left" -msgstr "ఎడమ వైపు స్ప్లిట్ చూడండి" +#: ../data/50-mutter-windows.xml.in.h:2 +msgid "Activate the window menu" +msgstr "విండో జాబితాను క్రియాశీలపరుచుము" -#: ../src/50-muffin-windows.xml.in.h:3 -msgid "View split on right" -msgstr "కుడి వైపు స్ప్లిట్ చూడండి" +#: ../data/50-mutter-windows.xml.in.h:3 +msgid "Toggle fullscreen mode" +msgstr "పూర్తితెర సంవిధానమును మార్చుము" -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format -msgid "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." -msgstr "మరొక కూర్పునకు నిర్వహించేది ప్రదర్శన పై %i తెరపైన ముందుగానే జరుగుచున్నది \"%s\"." +#: ../data/50-mutter-windows.xml.in.h:4 +msgid "Toggle maximization state" +msgstr "గరిష్ట స్థితికి మార్చుము" -#: ../src/core/bell.c:307 -msgid "Bell event" -msgstr "బెళ్ సన్నివేశము" +#: ../data/50-mutter-windows.xml.in.h:5 +msgid "Maximize window" +msgstr "విండోని గరిష్ఠీకరించు" -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "తెలియని విండో సమాచార మనవి: %d" +#: ../data/50-mutter-windows.xml.in.h:6 +msgid "Restore window" +msgstr "విండోని తిరిగివుంచు" -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> చలనంలేదు." +#: ../data/50-mutter-windows.xml.in.h:7 +msgid "Toggle shaded state" +msgstr "షేడెడ్ స్ధితిని మార్చుము" -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "కార్యక్షేత్రం బదులు ఇవ్వడంలేదు." +#: ../data/50-mutter-windows.xml.in.h:8 +msgid "Close window" +msgstr "విండోను మూయుము" -#: ../src/core/delete.c:119 -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "" -"మీరు దానిని కొంత సమయము వరకు కొనసాగించుట ఇస్టపడవచును లేనిచో పూర్తి కార్యక్షేత్రమును బలవంతముగా " -"త్యజించుము" +#: ../data/50-mutter-windows.xml.in.h:9 +msgid "Hide window" +msgstr "విండోని మరగునవుంచు" -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "ఆగుము(_W)" +#: ../data/50-mutter-windows.xml.in.h:10 +msgid "Move window" +msgstr "విండోని జరుపుము" -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "బలవంతముగా త్యజించుము(_F)" +#: ../data/50-mutter-windows.xml.in.h:11 +msgid "Resize window" +msgstr "విండోని పునఃపరిమాణించుము" -#: ../src/core/display.c:387 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "కూర్పునకు తొలిగించిన %s పొడిగింపు అవసరమున్నది" +#: ../data/50-mutter-windows.xml.in.h:12 +msgid "Toggle window on all workspaces or one" +msgstr "కిటికీ అన్ని కార్యక్షేత్రంలపై వన్నా లేక వొకటి వున్నా మార్చుము" -#: ../src/core/display.c:453 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "X విండో సిస్టమ్ ప్రదర్శన '%s'ను తెరుచుట విఫలమైనది\n" +#: ../data/50-mutter-windows.xml.in.h:13 +msgid "Raise window if covered, otherwise lower it" +msgstr "ఒక కిటికీ కప్పివుంటే దానిని వృద్దిచేయుము, లేదా దానిని తగ్గించు" -#: ../src/core/keybindings.c:852 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "కీ %sని ముందుగానే %x మార్పుచేయునవి తో పాటు వేరొక కార్యక్రమము బంధించున్నదిగా ఉపయోగిస్తుంది\n" +#: ../data/50-mutter-windows.xml.in.h:14 +msgid "Raise window above other windows" +msgstr "విండోని ఇతర విండోల పైకి తీసుకొనిరమ్ము" -#: ../src/core/main.c:206 -msgid "Disable connection to session manager" -msgstr "సెషన్ నిర్వాహికకు అనుసంధానమును అచేతనము చేయుము" +#: ../data/50-mutter-windows.xml.in.h:15 +msgid "Lower window below other windows" +msgstr "విండోని ఇతర విండోల కిందికి తీసుకొనివెళ్ళుమ్ము" -#: ../src/core/main.c:212 -msgid "Replace the running window manager" -msgstr "పరుగెడుతున్న విండో నిర్వాహికను పునఃప్రస్ధానము చేయుము" +#: ../data/50-mutter-windows.xml.in.h:16 +msgid "Maximize window vertically" +msgstr "విండోని నిలువుగా గరిష్ఠీకరించు" -#: ../src/core/main.c:218 -msgid "Specify session management ID" -msgstr "సెషన్ నిర్వహణా IDను తెలుపుము" +#: ../data/50-mutter-windows.xml.in.h:17 +msgid "Maximize window horizontally" +msgstr "విండోని అడ్డంగా గరిష్ఠీకరించు" -#: ../src/core/main.c:223 -msgid "X Display to use" -msgstr "X ప్రదర్శనం వుపయోగించుట కొఱకు" +#: ../data/50-mutter-windows.xml.in.h:18 +msgid "View split on left" +msgstr "ఎడమ వైపు స్ప్లిట్ చూడండి" -#: ../src/core/main.c:229 -msgid "Initialize session from savefile" -msgstr "బద్రపరిచిన దస్త్రము నుండి సమావేశమును మొదలుపెట్టుము" +#: ../data/50-mutter-windows.xml.in.h:19 +msgid "View split on right" +msgstr "కుడి వైపు స్ప్లిట్ చూడండి" -#: ../src/core/main.c:235 -msgid "Make X calls synchronous" -msgstr "Xపిలుపులను కాలనియమితం చేయుము" +#: ../data/mutter.desktop.in.h:1 +msgid "Mutter" +msgstr "మట్టర్" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "వైవిద్యాంశముల వివరము: %sను సంశోథించుట విఫలమైనది\n" +#: ../data/org.gnome.mutter.gschema.xml.in.h:1 +msgid "Modifier to use for extended window management operations" +msgstr "" +"పొడిగించినటువంటి కిటికీ నిర్వాహణ కార్యముల కొఱకు మార్చుదానిని ఉపయోగించెదము" -#: ../src/core/main.c:520 -#, c-format +#: ../data/org.gnome.mutter.gschema.xml.in.h:2 msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" +"This key will initiate the \"overlay\", which is a combination window " +"overview and application launching system. The default is intended to be the " +"\"Windows key\" on PC hardware. It's expected that this binding either the " +"default or set to the empty string." msgstr "" -"వైవిద్యాంశమును కనుగొనలేకపోవుచున్నది! %s మరియు సాధారణ వైవిద్యాంశములు కలిగివున్నవో లేవో " -"నిర్దారించుకొనుము.\n" +"ఈ కీ కిటికీ సంగ్రహముమరియు అనువర్తనముని ఉపయోగించు సిస్టమ్‌ల కలయికైన " +"\"ఒవర్‌లే\"ను ప్రారంభించుతుంది." +"PC హార్డ్ వేర్ పై \"కిటికీస్ కీ\"అనునిది అప్రమేయముగా వుండుటకు ఆశ " +"చూపుతున్నది.ఈ బంధనమును " +"అప్రమేయముగా లేక ఖాళీ పదబంధముగా అమర్చుటకు ఊహించబడినది" -#: ../src/core/muffin.c:40 -#, c-format +#: ../data/org.gnome.mutter.gschema.xml.in.h:3 +msgid "Attach modal dialogs" +msgstr "మోడల్ వివరణములను జతచేయుము" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:4 msgid "" -"mutter %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." msgstr "" -"mutter %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" - -#: ../src/core/muffin.c:54 -msgid "Print version" -msgstr "వివరణము ముద్రించు" +"నిజమైనప్పుడు దేనికిదానికి శీర్షికపట్టాలకు బదులుగా మూలపు కిటికీ యొక్క " +"శీర్షికపట్టాకు మోడల్ పట్టాలు జతపరిచినవి " +"దర్శనమిస్తాయిమరియు అవి మూలపు కిటికీతో కలిపి జరపబడెను." -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "కామ-కూర్పుచేయు ప్లగ్ - ఇన్‌ల వేరుచేయబడిన జాబిత" +#: ../data/org.gnome.mutter.gschema.xml.in.h:5 +msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "తెర అంచులలో కిటికీస్ పడుతున్నప్పుడు అంచు దళము పరచుట ప్రారంభించు" -#: ../src/core/prefs.c:1077 +#: ../data/org.gnome.mutter.gschema.xml.in.h:6 msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." msgstr "" -"విరిగిన కార్యక్షేత్రములకు చుట్టుప్రక్కలపనిచేయువాటిని నిరుపయోగపరిచెను. కొన్ని కార్యక్షేత్రములు సరైన రీతిలో " -"వ్యవహరించకపోవచ్చు.\n" +"ఎనేబుల్ చేస్తే, నిలువు తెర అంచులలో కిటికీస్ పడుతున్నపుడు నిలువుగా వాటిని " +"పెంచుకుంటుంది మరియు " +"అందుబాటులో ప్రాంతం సగం కవర్ చేయడానికి అడ్డంగా వాటిని పెంచుకుంటుంది. టాప్ " +"స్క్రీన్ అంచున కిటికీస్ " +"పదుతున్నపుడు పూర్తిగా వాటిని పెంచుకుంటుంది." -#: ../src/core/prefs.c:1152 -#, c-format -#| msgid "Could not parse font description \"%s\" from GConf key %s\n" -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "%s జికాన్‌ఫ్ కీ నుండి \"%s\" పార్స్ అక్షరశైలి వివరించలేకపోవుచున్నది\n" +#: ../data/org.gnome.mutter.gschema.xml.in.h:7 +msgid "Workspaces are managed dynamically" +msgstr "పని చేసే స్థలాలు గతికంగా నిర్వహింపబడ్డాయి." -#: ../src/core/prefs.c:1218 -#, c-format +#: ../data/org.gnome.mutter.gschema.xml.in.h:8 msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "మోస్ బటన్‌ మార్చునదికి రూపకరించిన దత్తాంశస్థానములో కనుగొనిన \"%s\"కు విలువలేదు\n" +"Determines whether workspaces are managed dynamically or whether there's a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." +msgstr "" +"పని చేసేస్థలాలు గతికంగా నిర్వహించారా లేదో లేదా పని చేసేస్థలాలు ఒక స్టాటిక్ " +"సంఖ్య (org.gnome.desktop." +"wm.అభీష్టాల లో num-workspaces కీ ద్వారా గుర్తిస్తారు) ఉందో లేదో " +"నిర్ణయిస్తుంది." -#: ../src/core/prefs.c:1739 -#, c-format +#: ../data/org.gnome.mutter.gschema.xml.in.h:9 +msgid "Workspaces only on primary" +msgstr "కార్యక్షేత్రములు ప్రాథమికము పైనే వుండును" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:10 msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "కీబంధించునదికి రూపకరించిన దత్తాంశస్థానములో కనుగొనిన \"%s\"కు విలువలేదు\"%s\"\n" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." +msgstr "" +"కార్యక్షేత్రములను మార్చుట ప్రాథమిక దర్శిని పై ఉన్న కిటికీలకు మాత్రమేన " +"లేకఅన్ని కార్యక్షేత్రములపైనున్న " +"కిటికీలకు కూడా అమలవుతుందో లేదో అనేది వివరిస్తుంది" -#: ../src/core/prefs.c:1836 -#, c-format -msgid "Workspace %d" -msgstr "%d పనిప్రదేశము" +#: ../data/org.gnome.mutter.gschema.xml.in.h:11 +msgid "No tab popup" +msgstr "పాపప్ టాబ్ లేదు." -#: ../src/core/screen.c:730 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "%d తెర '%s' ప్రదర్శనపై నిస్సారమైనది\n" +#: ../data/org.gnome.mutter.gschema.xml.in.h:12 +msgid "" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." +msgstr "" +"పాప్అప్ మరియు హైలైట్ ఫ్రేమ్ యొక్క ఉపయోగం కిటికీ సైక్లింగ్ కోసం డిసేబుల్ " +"చేయాలి లేదో నిర్ణయిస్తుంది." -#: ../src/core/screen.c:746 -#, c-format +#: ../data/org.gnome.mutter.gschema.xml.in.h:13 +msgid "Delay focus changes until the pointer stops moving" +msgstr "సూచకి కదులుట ఆగునంతవరకు ఫోకస్ మార్పులను జాగుచేయి" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:14 msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" +"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " +"the focus will not be changed immediately when entering a window, but only " +"after the pointer stops moving." msgstr "" -"%d తెర ముందుగానే విండో నిర్వాహిక కలిగివున్న \"%s\" ప్రదర్శనపై ఉన్నది; ప్రస్తుత విండో నిర్వాహికను --" -"పునఃస్థాపించు ఇచ్చాపూర్వకముచేత పునఃస్థాపించుటకు ప్రయత్నించుము.\n" +"true కు అమర్చితే, మరియు ఫోకస్ రీతి \"sloppy\" లేదా \"mouse\" అయితే అప్పుడు " +"విండోకు " +"ప్రవేశించునప్పుడు ఫోకస్ తక్షణమే మారబోదు, అయితే సూచకి కదులుట ఆగిన తరువాత " +"మాత్రమే మారును." -#: ../src/core/screen.c:773 -#, c-format +#: ../data/org.gnome.mutter.gschema.xml.in.h:15 +msgid "Draggable border width" +msgstr "కదుల్చుటకు వీలుగా ఉన్న సరిహద్దు వెడల్పు" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:16 msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "%d తెర పై \"%s\" ప్రదర్శనపు విండో నిర్వాహికను ఎంపిక సంపాదించుటలేదు\n" +"The amount of total draggable borders. If the theme's visible borders are " +"not enough, invisible borders will be added to meet this value." +msgstr "" +"అన్ని కదల్చబడుటకు వీలుగావున్న సరిహద్దుల మొత్తం. వైవిద్వాంశముపు దర్శనీయమైన " +"సరిహద్దులుసరిపోనిచో, ఈ " +"విలువకు చేరుటకు అగోచరమైన సరిహద్దులను జోడించబడును" -#: ../src/core/screen.c:828 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "%d తెర \"%s\" ప్రదర్శనపై ముందుగానే ఒక విండో నిర్వాహికను కలిగివున్నది\n" +#: ../data/org.gnome.mutter.gschema.xml.in.h:17 +msgid "Auto maximize nearly monitor sized windows" +msgstr "దాదాపు మానిటర్ పరిమాణపు విండోలను స్వయంచాలకంగా పెద్దవిచేయి" -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "%d తెరని \"%s\" ప్రదర్శనపై విడుదలచేయబడుటలేదు\n" +#: ../data/org.gnome.mutter.gschema.xml.in.h:18 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" +"చేతనం చేస్తే, ప్రాధమికంగా మానిటర్ పరిమాణంలో వున్న కొత్త విండోలు స్వయంచాలకంగా " +"పెద్దవి చేయబడతాయి." -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "'%s' వివరమును స్రుష్టించబడుటలేదు: %s\n" +#: ../data/org.gnome.mutter.gschema.xml.in.h:19 +msgid "Place new windows in the center" +msgstr "కొత్త విండోలను మధ్యలో ఉంచు" -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "'%s' వివరణ దస్త్రమును వ్రాయుట కొఱకు తెరవబడుటలేదు: %s\n" +#: ../data/org.gnome.mutter.gschema.xml.in.h:20 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "true అయినప్పుడు, కొత్త విండోలు మానిటర్ తెర మద్యలో ఉంచబడును." -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "'%s'వివరణ దస్త్రమును వ్రాయుచున్నప్పుడు కలిగిన దోషము: %s\n" +#: ../data/org.gnome.mutter.gschema.xml.in.h:21 +msgid "Select window from tab popup" +msgstr "పాప్అప్ టాబ్ నుండి కిటికీ ఎంచుకోండి" -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "'%s'వివరణ దస్త్రమును మూయుచున్నప్పుడు కలిగిన దోషము: %s\n" +#: ../data/org.gnome.mutter.gschema.xml.in.h:22 +msgid "Cancel tab popup" +msgstr "టాబ్ పాప్అప్ రద్దు" -#: ../src/core/session.c:1136 +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:1 +#| msgid "Switch to workspace 1" +msgid "Switch to VT 1" +msgstr "VT 1 కు మారు" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:2 +#| msgid "Switch to workspace 2" +msgid "Switch to VT 2" +msgstr "VT 2 కు మారు" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:3 +#| msgid "Switch to workspace 3" +msgid "Switch to VT 3" +msgstr "VT 3 కు మారు" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:4 +#| msgid "Switch to workspace 4" +msgid "Switch to VT 4" +msgstr "VT 4 కు మారు" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:5 +#| msgid "Switch to workspace 5" +msgid "Switch to VT 5" +msgstr "VT 5 కు మారు" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:6 +#| msgid "Switch to workspace 6" +msgid "Switch to VT 6" +msgstr "VT 6 కు మారు" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:7 +#| msgid "Switch to workspace 7" +msgid "Switch to VT 7" +msgstr "VT 7 కు మారు" + +#: ../src/backends/meta-monitor-manager.c:412 +msgid "Built-in display" +msgstr "అంతర్-నిర్మిత ప్రదర్శన" + +#: ../src/backends/meta-monitor-manager.c:437 +msgid "Unknown" +msgstr "తెలియని" + +#: ../src/backends/meta-monitor-manager.c:439 +msgid "Unknown Display" +msgstr "తెలియని ప్రదర్శన" + +#. TRANSLATORS: this is a monitor vendor name, followed by a +#. * size in inches, like 'Dell 15"' +#. +#: ../src/backends/meta-monitor-manager.c:447 #, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "భద్రపరిచిన వివరణ దస్త్రమును పార్స్ చేయుట విఫలమైనది: %s\n" +msgid "%s %s" +msgstr "%s %s" -#: ../src/core/session.c:1185 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: ../src/compositor/compositor.c:443 #, c-format -msgid "<mutter_session> attribute seen but we already have the session ID" +msgid "" +"Another compositing manager is already running on screen %i on display \"%s" +"\"." msgstr "" -"<ముట్టర్ వివరణము> ఆట్రిబ్యూట్‌ని చూపించబడినది కాని మనకు ముందుగానే వివరణపు ఐడి కలగివుంది(_s)" +"మరొక కూర్పునకు నిర్వాహకం ప్రదర్శన పై %i తెరపైన ముందుగానే జరుగుచున్నది \"%" +"s\"." -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "%s అను తెలియని ఆట్రిబ్యూట్ <%s> మూలకముపై ఉన్నది" +#: ../src/core/bell.c:185 +msgid "Bell event" +msgstr "బెల్ సన్నివేశము" -#: ../src/core/session.c:1215 +#: ../src/core/delete.c:127 #, c-format -msgid "nested <window> tag" -msgstr "మెలికలుపడివున్న <విండో>(window) ట్యాగ్" +msgid "“%s” is not responding." +msgstr "“%s” స్పందించుటలేదు." -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "%s అను తెలియని మూలకము" +#: ../src/core/delete.c:129 +msgid "Application is not responding." +msgstr "అనువర్తనం స్పందించుటలేదు." -#: ../src/core/session.c:1809 +#: ../src/core/delete.c:134 msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." msgstr "" -"ఈ విండోలు కోట్(&q)ని సహకరించటలేదు; ప్రస్తుత అమరికను కోట్(&q)గా భద్రపరుచుము; మరియు మళ్ళీ " -"ప్రవేశించినప్పుడుస్వయముగా పునఃప్రారంభించబడవలెను" - -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "%s అను లోపనిర్మూలన నమోదును తెరవబడుట విఫలమైనది\n" +"మీరు దానిని కొంత సమయము వరకు కొనసాగించుట ఇస్టపడవచును లేనిచో పూర్తి " +"అనువర్తనమును బలవంతముగా " +"త్యజించుము" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "%s అను నమోదు దస్త్రం ఎఫ్‌డిఒపెన్()చేయుట విఫలమైనది: %s\n" +#: ../src/core/delete.c:141 +msgid "_Wait" +msgstr "నిరీక్షించండి (_W)" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "%s అను నమోదు దస్త్రమును తెరివబడెను\n" +#: ../src/core/delete.c:141 +msgid "_Force Quit" +msgstr "బలవంతముగా త్యజించు (_F)" -#: ../src/core/util.c:146 ../src/tools/mutter-message.c:149 +#: ../src/core/display.c:547 #, c-format -msgid "Mutter was compiled without support for verbose mode\n" -msgstr "మట్టర్ వెర్‌బోస్ విధమునకు సహకారము కల్పించకుండా క్రోడీకరించబడినది\n" +msgid "Failed to open X Window System display '%s'\n" +msgstr "X కిటికీ సిస్టమ్ ప్రదర్శన '%s'ను తెరుచుట విఫలమైనది\n" -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "విండో నిర్వాహిక: " +#: ../src/core/main.c:176 +msgid "Disable connection to session manager" +msgstr "సెషన్ నిర్వాహకానికి అనుసంధానమును అచేతనము చేయుము" -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "విండో నిర్వాహికలో లోపము: " +#: ../src/core/main.c:182 +msgid "Replace the running window manager" +msgstr "పరుగెడుతున్న కిటికీ నిర్వాహకంను పునఃప్రస్ధానము చేయుము" -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "విండో నిర్వాహిక హెచ్చరిక: " +#: ../src/core/main.c:188 +msgid "Specify session management ID" +msgstr "సెషన్ నిర్వహణా IDను తెలుపుము" -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "విండో నిర్వాహిక దోషము: " +#: ../src/core/main.c:193 +msgid "X Display to use" +msgstr "X ప్రదర్శనం వుపయోగించుట కొఱకు" -#. first time through -#: ../src/core/window.c:7269 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"%s విండో ICCCMలో నిర్దేశించిన విధముగా WM_CLIENT_LEADER విండోకి బదులు(_C)(_L)SM_CLIENT_IDని " -"స్వయముగా అమర్చెను(_C)(_I).\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7932 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %" -"d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"%s విండోని పునఃపరిమానించుట కుదరదని తెలియజేయుటకు MWM సూచనను అమర్చినది, కాని కనిష్ఠ పరిమాణం %d x %" -"d మరియు గనిష్ఠ పరిమాణం %d x %d ను అమర్చినది; ఇది అర్దవంతమైనదికాదు.\n" +#: ../src/core/main.c:199 +msgid "Initialize session from savefile" +msgstr "బద్రపరిచిన దస్త్రము నుండి సమావేశమును మొదలుపెట్టుము" -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "కార్యక్షేత్రమును నకిలీ _NET_WM_PID %luను అమర్చెను\n" +#: ../src/core/main.c:205 +msgid "Make X calls synchronous" +msgstr "Xపిలుపులను కాలనియమితం చేయుము" -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (%s పై)" +#: ../src/core/main.c:212 +msgid "Run as a wayland compositor" +msgstr "వేలాండ్ కంపోజిటర్ వలె నడుపుము" -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "నిస్సారమైన WM_TRANSIENT_FOR విండో 0x%lxని %s కొఱకు పేర్కొనబడినది.\n" +#: ../src/core/main.c:220 +msgid "Run as a full display server, rather than nested" +msgstr "పూర్తి ప్రదర్శన సేవిక వలె నడుపుము, నెస్టెట్ బదులుగా" -#: ../src/core/window-props.c:1492 +#: ../src/core/main.c:451 #, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "WM_TRANSIENT_FOR విండో 0x%lx %s కొఱకు లూప్‌ని స్రుష్ఠించును.\n" +msgid "Failed to scan themes directory: %s\n" +msgstr "వైవిద్యాంశముల వివరము: %sను సంశోథించుట విఫలమైనది\n" -#: ../src/core/xprops.c:155 +#: ../src/core/main.c:467 #, c-format msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +"Could not find a theme! Be sure %s exists and contains the usual themes.\n" msgstr "" -"విండో 0x%lx నకు %s గుణము కలదు \n" -" %s రూపకముతో కూడిన %d రకమును పొందుటకు ఊహించబడినది\n" -"మరియు నిజముగా %s రకము %d రూపకం %d న్ అంశములు(_i) కలిగివున్నవి.\n" -"ఇది కార్యక్షేత్రపు తప్పిదముగా అనిపించుచున్నది, కాని విండో నిర్వాహిక తప్పిదము కాదు.\n" -"విండోకి శీర్షిక=\"%s\" తరగతి=\"%s\" నామము=\"%s\" అని కలవు\n" - -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "%sఅను గుణము విండో 0x%lx పై నిస్సారమైన UTF-8 ని కలిగివుండెను\n" +"వైవిద్యాంశమును కనుగొనలేకపోవుచున్నది! %s మరియు సాధారణ వైవిద్యాంశములు " +"కలిగివున్నవో లేవో " +"నిర్దారించుకొనుము.\n" -#: ../src/core/xprops.c:494 +#: ../src/core/mutter.c:39 #, c-format msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"%s అను గుణము విండో 0x%lx పై జాబితాలోని %d అంశము కోఱకు నిస్సారమైన UTF-8 ని కలిగివుండెను\n" - -#: ../src/mutter.desktop.in.h:1 ../src/mutter-wm.desktop.in.h:1 -msgid "Mutter" -msgstr "మట్టర్" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 -msgid "Modifier to use for extended window management operations" -msgstr "పొడిగించినటువంటి విండో నిర్వాహణ కార్యముల కొఱకు మార్చుదానిని ఉపయోగించెదము" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 -msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." -msgstr "" -"ఈ కీ విండో సంగ్రహముమరియు కార్యక్షేత్రముని ఉపయోగించు సిస్టమ్‌ల కలయికైన \"ఒవర్‌లే\"ను ప్రారంభించుతుంది." -"PC హార్డ్ వేర్ పై \"విండోస్ కీ\"అనునిది అప్రమేయముగా వుండుటకు ఆశ చూపుతున్నది.ఈ బంధనమును " -"అప్రమేయముగా లేక ఖాళీ పదబంధముగా అమర్చుటకు ఊహించబడినది" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 -msgid "Attach modal dialogs" -msgstr "మోడల్ వివరణములను జతచేయుము" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 -msgid "" -"When true, instead of having independent titlebars, modal dialogs appear " -"attached to the titlebar of the parent window and are moved together with " -"the parent window." -msgstr "" -"నిజమైనప్పుడు దేనికిదానికి శీర్షికపట్టాలకు బదులుగా మూలపు విండో యొక్క శీర్షికపట్టాకు మోడల్ పట్టాలు జతపరిచినవి " -"దర్శనమిస్తాయిమరియు అవి మూలపు విండోతో కలిపి జరపబడెను." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -msgid "Live Hidden Windows" -msgstr "చలనం కలిగిన దాగిన విండోలు" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"దాగివున్న విండోలను (అనగా చిన్నవిగా చేసిన విండోలు మరియువేరొక పనిప్రదేశముల పైనున్న విండోలు) వెలికి " -"తీయవలయునోలేదో వివరిస్తుంది." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 -msgid "Enable edge tiling when dropping windows on screen edges" -msgstr "తెర అంచులలో విండోస్ పడుతున్నప్పుడు అంచు దళము పరచుట ప్రారంభించు" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 -msgid "" -"If enabled, dropping windows on vertical screen edges maximizes them " -"vertically and resizes them horizontally to cover half of the available " -"area. Dropping windows on the top screen edge maximizes them completely." +"mutter %s\n" +"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" msgstr "" -"ఎనేబుల్ చేస్తే, నిలువు తెర అంచులలో విండోస్ పడుతున్నపుడు నిలువుగా వాటిని పెంచుకుంటుంది మరియు " -"అందుబాటులో ప్రాంతం సగం కవర్ చేయడానికి అడ్డంగా వాటిని పెంచుకుంటుంది. టాప్ స్క్రీన్ అంచున విండోస్ " -"పదుతున్నపుడు పూర్తిగా వాటిని పెంచుకుంటుంది." +"మట్టర్ %s\n" +"కాపీహక్కులు (C) 2001-%d హేవోక్ పెన్నింగ్టన్, రెడ్ హ్యాట్, Inc., మరియు ఇతరులు\n" +"ఇది ఒక ఫ్రీ సాఫ్ట్‍వేర్, నకలు షరతులకు మూలాన్ని చూడండి.\n" +"సమాజానికి ఉపయోగపడుతుంది అనే ఆశతో, ఏవిధమైన పూచీకత్తులు లేకుండా, కనీసం " +"వ్యాపారానికి గాని లేదా ఒక ఖచ్చితమైన " +"ప్రయోజనానికి ఉపయోగించవచ్చని భావించిన పూచీకత్తులు కూడా లేకుండా పంచబడుతుంది.\n" + +#: ../src/core/mutter.c:53 +msgid "Print version" +msgstr "వివరణము ముద్రించు" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 -msgid "Workspaces are managed dynamically" -msgstr "పని చేసే స్థలాలు గతికంగా నిర్వహింపబడ్డాయి." +#: ../src/core/mutter.c:59 +msgid "Mutter plugin to use" +msgstr "ఉపయోగించుటకు మట్టర్ చొప్పింత" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 -msgid "" -"Determines whether workspaces are managed dynamically or whether there's a " -"static number of workspaces (determined by the num-workspaces key in org." -"gnome.desktop.wm.preferences)." -msgstr "" -"పని చేసేస్థలాలు గతికంగా నిర్వహించారా లేదో లేదా పని చేసేస్థలాలు ఒక స్టాటిక్ సంఖ్య (org.cinnamon.desktop." -"wm.అభీష్టాల లో num-workspaces కీ ద్వారా గుర్తిస్తారు) ఉందో లేదో నిర్ణయిస్తుంది." +#: ../src/core/prefs.c:2065 +#, c-format +msgid "Workspace %d" +msgstr "%d కార్యక్షేత్రము" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 -msgid "Workspaces only on primary" -msgstr "పనిప్రదేశములు ప్రాథమికము పైనే వుండును" +#: ../src/core/screen.c:543 +#, c-format +msgid "Screen %d on display '%s' is invalid\n" +msgstr "%d తెర '%s' ప్రదర్శనపై నిస్సారమైనది\n" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 +#: ../src/core/screen.c:559 +#, c-format msgid "" -"Determines whether workspace switching should happen for windows on all " -"monitors or only for windows on the primary monitor." +"Screen %d on display \"%s\" already has a window manager; try using the --" +"replace option to replace the current window manager.\n" msgstr "" -"పనిప్రదేశములను మార్చుట ప్రాథమిక దర్శిని పై ఉన్న విండోలకు మాత్రమేన లేకఅన్ని పనిప్రదేశములపైనున్న విండోలకు " -"కూడా అమలవుతుందో లేదో అనేది వివరిస్తుంది" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 -msgid "No tab popup" -msgstr "పాపప్ టాబ్ లేదు." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 -msgid "" -"Determines whether the use of popup and highlight frame should be disabled " -"for window cycling." -msgstr "పాప్అప్ మరియు హైలైట్ ఫ్రేమ్ యొక్క ఉపయోగం విండో సైక్లింగ్ కోసం డిసేబుల్ చేయాలి లేదో నిర్ణయిస్తుంది." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 -msgid "Draggable border width" -msgstr "కదుల్చుటకు వీలుగా ఉన్న సరిహద్దు వెడల్పు" +"%d తెర ముందుగానే కిటికీ నిర్వాహకం కలిగివున్న \"%s\" ప్రదర్శనపై ఉన్నది; " +"ప్రస్తుత కిటికీ నిర్వాహకంను --" +"పునఃస్థాపించు ఇచ్చాపూర్వకముచేత పునఃస్థాపించుటకు ప్రయత్నించుము.\n" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 -msgid "" -"The amount of total draggable borders. If the theme's visible borders are " -"not enough, invisible borders will be added to meet this value." +#: ../src/core/screen.c:652 +#, c-format +msgid "Screen %d on display \"%s\" already has a window manager\n" msgstr "" -"అన్ని కదల్చబడుటకు వీలుగావున్న సరిహద్దుల మొత్తం. వైవిద్వాంశముపు దర్శనీయమైన సరిహద్దులుసరిపోనిచో, ఈ " -"విలువకు చేరుటకు అగోచరమైన సరిహద్దులను జోడించబడును" +"%d తెర \"%s\" ప్రదర్శనపై ముందుగానే ఒక కిటికీ నిర్వాహకంను కలిగివున్నది\n" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:17 -#| msgid "Remove Window From Top" -msgid "Select window from tab popup" -msgstr "పాప్అప్ టాబ్ నుండి విండో ఎంచుకోండి" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:18 -msgid "Cancel tab popup" -msgstr "టాబ్ పాప్అప్ రద్దు" - -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "వుపయోగించుము: %s\n" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "కనిష్టీకరించు (_n)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "గరిష్టీకరించు" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "గరిష్టీకరించకు" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "ఎగువకు మడువుము(_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "మడవవద్దు(_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "జరుపు(_M)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "పున: పరిమాణము(_R)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "శీర్షిక పట్టాను తెరపైకి జరుపుము(_S)" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "ఎల్లప్పుడూ పైనే" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "ఎల్లప్పుడూ గోచరించు పనిప్రదేశముపైనే(_A)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "ఈ పనిప్రదేశము మాత్రము పైనే(_O)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "పనిచేస్తున్న చోటునుండీ ఎడమవైపుకు కదులు" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "పనిచేస్తున్న చోటునుండీ కుడివైపుకు కదులు" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "పనిచేస్తున్న చోటునుండీ పైకి కదులు" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "పనిచేస్తున్న చోటునుండీ కిందకు కదులు" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "మూయుము (_C)" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "పనిప్రదేశము %d%n" - -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "పనిప్రదేశము 1_0" - -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "పనిప్రదేశము %s%d" - -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "వేరే పనిచేసెచోటుకి కదులు" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "ఆల్ట్" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "సూపర్" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "హైపర్" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "మాడ్ 2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "మాడ్ 3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "మాడ్ 4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "మాడ్ 5" +#: ../src/core/util.c:118 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "మట్టర్ వెర్‌బోస్ విధమునకు సహకారము కల్పించకుండా క్రోడీకరించబడినది\n" #. Translators: This represents the size of a window. The first number is #. * the width of the window and the second is the height. #. -#: ../src/ui/resizepopup.c:113 +#: ../src/ui/resizepopup.c:134 #, c-format msgid "%d x %d" msgstr "%d x %d" -#: ../src/ui/theme.c:253 +#: ../src/ui/theme.c:233 msgid "top" msgstr "పైన" -#: ../src/ui/theme.c:255 +#: ../src/ui/theme.c:235 msgid "bottom" msgstr "క్రింద" -#: ../src/ui/theme.c:257 +#: ../src/ui/theme.c:237 msgid "left" msgstr "ఎడమ" -#: ../src/ui/theme.c:259 +#: ../src/ui/theme.c:239 msgid "right" msgstr "కుడి" -#: ../src/ui/theme.c:286 +#: ../src/ui/theme.c:267 #, c-format msgid "frame geometry does not specify \"%s\" dimension" msgstr "చట్రపు క్షేత్రగణితం \"%s\"అను తలమును నిర్దేశించలేదు" -#: ../src/ui/theme.c:305 +#: ../src/ui/theme.c:286 #, c-format msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "చట్రపు క్షేత్రగణితం \"%s\"అను తలమును \"%s\" సరిహద్దు కొఱకు నిర్దేశించలేదు" +msgstr "" +"చట్రపు క్షేత్రగణితం \"%s\"అను తలమును \"%s\" సరిహద్దు కొఱకు నిర్దేశించలేదు" -#: ../src/ui/theme.c:342 +#: ../src/ui/theme.c:323 #, c-format msgid "Button aspect ratio %g is not reasonable" msgstr "బటన్ దృశ్య నిష్పత్తి %g సరైనవిధముగా లేదు" -#: ../src/ui/theme.c:354 +#: ../src/ui/theme.c:335 #, c-format msgid "Frame geometry does not specify size of buttons" msgstr "చట్రపు క్షేత్రగణితం బటన్‌ల పరిమాణమును పేర్కొనబడలేదు" -#: ../src/ui/theme.c:1067 +#: ../src/ui/theme.c:1061 #, c-format msgid "Gradients should have at least two colors" msgstr "పాతములకు కనీసం రెండు వర్ణములైన వుండవలెను" -#: ../src/ui/theme.c:1219 +#: ../src/ui/theme.c:1211 #, c-format msgid "" "GTK custom color specification must have color name and fallback in " "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" msgstr "" -"GTK మలచిన వర్ణము నిర్దేశించుటకు వర్ణము పేరు మరియు పారంతసిస్‌లలోభద్రపరుచుము, ఉదాహరణ gtk: మలచిన" -"(ఫు,బార్);\"%s\"ని పార్స్ చేయబడుటలేదు" +"GTK మలచిన వర్ణము నిర్దేశించుటకు వర్ణము పేరు మరియు పారంతసిస్‌లలోభద్రపరుచుము, " +"ఉదాహరణ gtk: " +"మలచిన(ఫు,బార్);\"%s\"ని పార్స్ చేయబడుటలేదు" -#: ../src/ui/theme.c:1235 +#: ../src/ui/theme.c:1227 #, c-format msgid "" "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" "_ are valid" msgstr "" -"gtk యొక్క వర్ణపు పేరు పరామితిలో'%c'అను నిస్సారమైన అక్షరము:మలచుట, A-Za-z0-9-(_n)_ మాత్రమే " +"gtk యొక్క వర్ణపు పేరు పరామితిలో'%c'అను నిస్సారమైన అక్షరము:మలచుట, " +"A-Za-z0-9-(_n)_ మాత్రమే " "వర్తించును" -#: ../src/ui/theme.c:1249 +#: ../src/ui/theme.c:1241 #, c-format msgid "" "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " "fit the format" msgstr "" -"Gtk: మలచిన చట్రము \"gtk:మలచిన(వర్ణనామము(_n),భద్రపరుచుట )\",\"%s\" రూపలావణ్యమును " +"Gtk: మలచిన చట్రము \"gtk:మలచిన(వర్ణనామము(_n),భద్రపరుచుట )\",\"%s\" " +"రూపలావణ్యమును " "అమర్చబడలేదు" -#: ../src/ui/theme.c:1294 +#: ../src/ui/theme.c:1286 #, c-format msgid "" "GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " "where NORMAL is the state; could not parse \"%s\"" msgstr "" -"GTK వర్ణము నిర్దేశించుటకు బ్రాకెట్‌లలో స్థితిని కలిగివుండాలి, ఉదాహరణ gtk:fg[NORMAL]NORMAL అనునది " +"GTK వర్ణము నిర్దేశించుటకు బ్రాకెట్‌లలో స్థితిని కలిగివుండాలి, ఉదాహరణ " +"gtk:fg[NORMAL]NORMAL అనునది " "ఒక స్థితి; \"%s\"ను పార్స్ చేయబడదు" -#: ../src/ui/theme.c:1308 +#: ../src/ui/theme.c:1300 #, c-format msgid "" "GTK color specification must have a close bracket after the state, e.g. gtk:" "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" msgstr "" -"GTK వర్ణము నిర్దేశించుటకుస్థితి తర్వాతనే మూసివున్న బ్రాకెట్‌ కలిగివుండాలి, ఉదాహరణ gtk:fg[NORMAL]" -"NORMAL అనునది ఒక స్థితి; \"%s\"ను పార్స్ చేయబడదు" +"GTK వర్ణము నిర్దేశించుటకుస్థితి తర్వాతనే మూసివున్న బ్రాకెట్‌ కలిగివుండాలి, " +"ఉదాహరణ gtk:" +"fg[NORMAL]NORMAL అనునది ఒక స్థితి; \"%s\"ను పార్స్ చేయబడదు" -#: ../src/ui/theme.c:1319 +#: ../src/ui/theme.c:1311 #, c-format msgid "Did not understand state \"%s\" in color specification" msgstr "వర్ణము నిర్దేశించుటలో \"%s\"అను స్థితిని గ్రహించలేకపోయెను" -#: ../src/ui/theme.c:1332 +#: ../src/ui/theme.c:1324 #, c-format msgid "Did not understand color component \"%s\" in color specification" msgstr "వర్ణము నిర్దేశించుటలో \"%s\"అను వర్ణము భాగముని గ్రహించలేకపోయెను" -#: ../src/ui/theme.c:1361 +#: ../src/ui/theme.c:1352 #, c-format msgid "" "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " "format" msgstr "" -"\"కలుపుట/bg వరణం/fg వర్ణం/ఆల్ఫ\"అనునది కలిపేటి రూపలావణ్యము,\"%s\"రూపలావణ్యములో అమర్చబడలేదు" +"\"కలుపుట/bg వరణం/fg వర్ణం/ఆల్ఫ\"అనునది కలిపేటి రూపలావణ్యము,\"%" +"s\"రూపలావణ్యములో అమర్చబడలేదు" -#: ../src/ui/theme.c:1372 +#: ../src/ui/theme.c:1363 #, c-format msgid "Could not parse alpha value \"%s\" in blended color" msgstr "కలిపేటి వర్ణములోవున్న \"%s\"అను ఆల్ఫా విలువను పార్స్ చేయబడదు" -#: ../src/ui/theme.c:1382 +#: ../src/ui/theme.c:1373 #, c-format msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" msgstr "కలిపేటి వర్ణములోవున్న \"%s\"అను ఆల్ఫా విలువ 0.0 మరియు 1.0 మథ్యలో ఉండదు" -#: ../src/ui/theme.c:1429 +#: ../src/ui/theme.c:1419 #, c-format msgid "" "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" msgstr "" -"\"మాయుట/మూలపు వర్ణం/కారకం\"అనునది మాయు రూపలావణ్యము, \"%s\" రూపలావణ్యములో అమర్చబడదు" +"\"మాయుట/మూలపు వర్ణం/కారకం\"అనునది మాయు రూపలావణ్యము, \"%s\" రూపలావణ్యములో " +"అమర్చబడదు" -#: ../src/ui/theme.c:1440 +#: ../src/ui/theme.c:1430 #, c-format msgid "Could not parse shade factor \"%s\" in shaded color" msgstr "మాయు వర్ణములో \"%s\"అను మాయు కారకం పార్స్ చేయబడలేదు" -#: ../src/ui/theme.c:1450 +#: ../src/ui/theme.c:1440 #, c-format msgid "Shade factor \"%s\" in shaded color is negative" msgstr "మాయు వర్ణములో \"%s\"అను మాయు కారకం కాదనెడిది" -#: ../src/ui/theme.c:1479 +#: ../src/ui/theme.c:1469 #, c-format msgid "Could not parse color \"%s\"" msgstr "వర్ణమును ప్పార్స్ చేయుబడుటలేదు\"%s\"" -#: ../src/ui/theme.c:1790 +#: ../src/ui/theme.c:1778 #, c-format msgid "Coordinate expression contains character '%s' which is not allowed" msgstr "సమాంతరపు వైఖరి అంగీకరించబడని '%s'అను అక్షరమును కలిగివున్నది" -#: ../src/ui/theme.c:1817 +#: ../src/ui/theme.c:1805 #, c-format msgid "" "Coordinate expression contains floating point number '%s' which could not be " "parsed" -msgstr "సమాంతరపు వైఖరి పార్సించబడలేని '%s'అను ఫ్లోటింగ్ సూచించు సంఖ్యను కలిగివున్నది" +msgstr "" +"సమాంతరపు వైఖరి పార్సించబడలేని '%s'అను ఫ్లోటింగ్ సూచించు సంఖ్యను కలిగివున్నది" -#: ../src/ui/theme.c:1831 +#: ../src/ui/theme.c:1819 #, c-format msgid "Coordinate expression contains integer '%s' which could not be parsed" msgstr "సమాంతరపు వైఖరి పార్సించబడని '%s'అను పూర్ణాంకమును కలిగివున్నది" -#: ../src/ui/theme.c:1953 +#: ../src/ui/theme.c:1940 #, c-format msgid "" "Coordinate expression contained unknown operator at the start of this text: " "\"%s\"" -msgstr "సమాంతరపు వైఖరి ఈ పాఠ్యాంశము మొదటిలో తెలియని నిర్వాహిక:\"%s\"ను కలిగివుండెను" +msgstr "" +"సమాంతరపు వైఖరి ఈ పాఠ్యాంశము మొదటిలో తెలియని నిర్వాహకం:\"%s\"ను కలిగివుండెను" -#: ../src/ui/theme.c:2010 +#: ../src/ui/theme.c:1997 #, c-format msgid "Coordinate expression was empty or not understood" msgstr "సమాంతరపు వైఖరి ఖాళీగా లేక గ్రహించలేకుండెను" -#: ../src/ui/theme.c:2121 ../src/ui/theme.c:2131 ../src/ui/theme.c:2165 +#: ../src/ui/theme.c:2110 ../src/ui/theme.c:2120 ../src/ui/theme.c:2154 #, c-format msgid "Coordinate expression results in division by zero" msgstr "సమాంతరపు వైఖరి సున్నాతో భాగించుటలో ఫలితమిచ్చింది" -#: ../src/ui/theme.c:2173 +#: ../src/ui/theme.c:2162 #, c-format msgid "" "Coordinate expression tries to use mod operator on a floating-point number" -msgstr "సమాంతరపు వైఖరి మాడ్ నిర్వాహికను ఫ్లోటింగ్ సూచించు సంఖ్యపై ఉపయోగించుటకు ప్రయత్నిస్తుంది" +msgstr "" +"సమాంతరపు వైఖరి మాడ్ నిర్వాహకంను ఫ్లోటింగ్ సూచించు సంఖ్యపై ఉపయోగించుటకు " +"ప్రయత్నిస్తుంది" -#: ../src/ui/theme.c:2229 +#: ../src/ui/theme.c:2218 #, c-format msgid "" "Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "సమాంతరపు వైఖరి ఊహించబడిన నిర్వాహణ కర్మకు \"%s\"అను నిర్వాహికను కలిగివున్నది" +msgstr "" +"సమాంతరపు వైఖరి ఊహించబడిన నిర్వాహణ కర్మకు \"%s\"అను నిర్వాహకంను కలిగివున్నది" -#: ../src/ui/theme.c:2238 +#: ../src/ui/theme.c:2227 #, c-format msgid "Coordinate expression had an operand where an operator was expected" -msgstr "సమాంతరపు వైఖరి ఊహించబడిన నిర్వాహికకు నిర్వాహణ కర్మని కలిగివుండెను" +msgstr "సమాంతరపు వైఖరి ఊహించబడిన నిర్వాహకానికి నిర్వాహణ కర్మని కలిగివుండెను" -#: ../src/ui/theme.c:2246 +#: ../src/ui/theme.c:2235 #, c-format msgid "Coordinate expression ended with an operator instead of an operand" msgstr "సమాంతరపు వైఖరి నిర్వాహణ కర్మకు బదులుగా నిర్వాహకతో ముగించెను" -#: ../src/ui/theme.c:2256 +#: ../src/ui/theme.c:2245 #, c-format msgid "" "Coordinate expression has operator \"%c\" following operator \"%c\" with no " "operand in between" msgstr "" -"సమాంతరపు వైఖరి \"%c\"అను నిర్వాహికను అనుసరించేటి \"%c\"అను నిర్వాహికకు మధ్యలోఎలాంటి నిర్వాహణ " +"సమాంతరపు వైఖరి \"%c\"అను నిర్వాహకంను అనుసరించేటి \"%c\"అను నిర్వాహకానికి " +"మధ్యలోఎలాంటి నిర్వాహణ " "కర్మలు లేకుండా కలిగెను" -#: ../src/ui/theme.c:2407 ../src/ui/theme.c:2452 +#: ../src/ui/theme.c:2396 ../src/ui/theme.c:2441 #, c-format msgid "Coordinate expression had unknown variable or constant \"%s\"" msgstr "సమాంతరపు వైఖరి తెలియని చెరరాశి లేక \"%s\"అను స్థిరరాశి కలిగివుండెను" -#: ../src/ui/theme.c:2506 +#: ../src/ui/theme.c:2495 #, c-format msgid "Coordinate expression parser overflowed its buffer." msgstr "సమాంతరపు వైఖరి పార్స్ ర్ తన బఫర్‌ను అథికముగా ప్రసరించెను." -#: ../src/ui/theme.c:2535 +#: ../src/ui/theme.c:2524 #, c-format msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "సమాంతరపు వైఖరి తెరిచివున్న పారన్‌తిసిస్ కాకుండ మూసివున్న పారన్‌తిసిస్‌ని కలిగివుండెను" +msgstr "" +"సమాంతరపు వైఖరి తెరిచివున్న పారన్‌తిసిస్ కాకుండ మూసివున్న పారన్‌తిసిస్‌ని " +"కలిగివుండెను" -#: ../src/ui/theme.c:2599 +#: ../src/ui/theme.c:2588 #, c-format msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "సమాంతరపు వైఖరి మూసివున్న పారన్‌తిసిస్ కాకుండ తెరిచివున్న పారన్‌తిసిస్‌ని కలిగివుండెను" +msgstr "" +"సమాంతరపు వైఖరి మూసివున్న పారన్‌తిసిస్ కాకుండ తెరిచివున్న పారన్‌తిసిస్‌ని " +"కలిగివుండెను" -#: ../src/ui/theme.c:2610 +#: ../src/ui/theme.c:2599 #, c-format msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "సమాంతరపు వైఖరి నిర్వాహికలు లేక నిర్వాహణ కర్మలును కలిగివుండలేదు అని అనిపిస్తోంది" +msgstr "" +"సమాంతరపు వైఖరి నిర్వాహకంలు లేక నిర్వాహణ కర్మలును కలిగివుండలేదు అని " +"అనిపిస్తోంది" -#: ../src/ui/theme.c:2822 ../src/ui/theme.c:2842 ../src/ui/theme.c:2862 +#: ../src/ui/theme.c:2812 ../src/ui/theme.c:2832 ../src/ui/theme.c:2852 #, c-format msgid "Theme contained an expression that resulted in an error: %s\n" msgstr "వైఖరిని కలిగివిన్న వైవిద్వాంశము %s దోషముగా ఫలితమిచ్చినది\n" -#: ../src/ui/theme.c:4533 +#: ../src/ui/theme.c:4455 #, c-format msgid "" "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " "specified for this frame style" msgstr "" -"<ఈ చట్రపు శైలి కొఱకు బటన్ ప్రక్రియ=\"%s\" స్థితి=\"%s\" డ్రా ఆప్‌లు=\"ఏదేమైన\">నుతప్పనిసరై " +"<ఈ చట్రపు శైలి కొఱకు బటన్ ప్రక్రియ=\"%s\" స్థితి=\"%s\" డ్రా " +"ఆప్‌లు=\"ఏదేమైన\">నుతప్పనిసరై " "పేర్కొనవలెను " -#: ../src/ui/theme.c:5066 ../src/ui/theme.c:5091 +#: ../src/ui/theme.c:4970 ../src/ui/theme.c:4995 #, c-format msgid "" "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "<చట్రపు స్థితి=\"%s\" పునఃపరిమాణించు=\"%s\" కేంద్రము=\"%s\" శైలి=\"ఏదేమైన\">" +msgstr "" +"<చట్రపు స్థితి=\"%s\" పునఃపరిమాణించు=\"%s\" కేంద్రము=\"%s\" శైలి=\"ఏదేమైన\">" -#: ../src/ui/theme.c:5139 +#: ../src/ui/theme.c:5041 #, c-format msgid "Failed to load theme \"%s\": %s\n" msgstr "\"%s\"వైవిధ్యాంశమును భర్తీ చేయుట విఫలమైనది: %s\n" -#: ../src/ui/theme.c:5275 ../src/ui/theme.c:5282 ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 ../src/ui/theme.c:5303 +#: ../src/ui/theme.c:5177 ../src/ui/theme.c:5184 ../src/ui/theme.c:5191 +#: ../src/ui/theme.c:5198 ../src/ui/theme.c:5205 #, c-format msgid "No <%s> set for theme \"%s\"" msgstr "\"%s\"వైవిధ్యాంశము కొఱకు ఏ <%s>ని అమర్చలేదు" -#: ../src/ui/theme.c:5311 +#: ../src/ui/theme.c:5213 #, c-format msgid "" "No frame style set for window type \"%s\" in theme \"%s\", add a <window " "type=\"%s\" style_set=\"whatever\"/> element" msgstr "" -"\"%s\"అను వైవిద్వాంశములో \"%s\"విండో రకము కొఱకు ఎలాంటి చట్రపు శైలిని ఆమోదించలేదు, ఒక <విండోరకము=" +"\"%s\"అను వైవిద్వాంశములో \"%s\"కిటికీ రకము కొఱకు ఎలాంటి చట్రపు శైలిని " +"ఆమోదించలేదు, ఒక <కిటికీరకము=" "\"%s\"ఆమోదించు శైలి= \"ఏదేమైన\"/>మూలాంకము" -#: ../src/ui/theme.c:5709 ../src/ui/theme.c:5771 ../src/ui/theme.c:5834 +#: ../src/ui/theme.c:5620 ../src/ui/theme.c:5682 ../src/ui/theme.c:5745 #, c-format msgid "" "User-defined constants must begin with a capital letter; \"%s\" does not" msgstr "" -"వినియోగదారు నిర్వచించిన స్థిరరాశులు ప్రధానమైన అక్షరములతో మొదలుపెట్తుము; \"%s\"నకు అవసరములేదు" +"వినియోగదారు నిర్వచించిన స్థిరరాశులు ప్రధానమైన అక్షరములతో మొదలుపెట్తుము; \"%" +"s\"నకు అవసరములేదు" -#: ../src/ui/theme.c:5717 ../src/ui/theme.c:5779 ../src/ui/theme.c:5842 +#: ../src/ui/theme.c:5628 ../src/ui/theme.c:5690 ../src/ui/theme.c:5753 #, c-format msgid "Constant \"%s\" has already been defined" msgstr "\"%s\" అను స్థిరరాశి ముందుగానే నిర్వచించబడినది" @@ -981,594 +939,814 @@ msgstr "\"%s\" అను స్థిరరాశి ముందుగానే #. Translators: This means that an attribute which should have been found #. * on an XML element was not in fact found. #. -#: ../src/ui/theme-parser.c:236 +#: ../src/ui/theme-parser.c:234 #, c-format msgid "No \"%s\" attribute on element <%s>" msgstr "ఎటువంటి \"%s\" మూల వస్తువు పై ఆపాదించు <%s>" -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 +#: ../src/ui/theme-parser.c:263 ../src/ui/theme-parser.c:281 #, c-format msgid "Line %d character %d: %s" msgstr "గీత %d అక్షరం %d: %s" -#: ../src/ui/theme-parser.c:479 +#: ../src/ui/theme-parser.c:481 #, c-format msgid "Attribute \"%s\" repeated twice on the same <%s> element" msgstr "ఆపాదించుట \"%s\" ఒక దానిపై రెండుసార్లు మళ్ళీచేయబడిన <%s> మూల వస్తువు" -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 +#: ../src/ui/theme-parser.c:505 ../src/ui/theme-parser.c:554 #, c-format msgid "Attribute \"%s\" is invalid on <%s> element in this context" msgstr "ఆపాదించుట \"%s\" పై నిస్సారము <%s> ఈ సంధర్భంలో మూల వాక్యము" -#: ../src/ui/theme-parser.c:594 +#: ../src/ui/theme-parser.c:596 #, c-format msgid "Could not parse \"%s\" as an integer" msgstr "\"%s\"ను పూర్ణాంకముగా పార్స్ చేయబడుటలేదు" -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 +#: ../src/ui/theme-parser.c:605 ../src/ui/theme-parser.c:660 #, c-format msgid "Did not understand trailing characters \"%s\" in string \"%s\"" msgstr "" -"\"%s\"పదబంధములోవున్న \"%s\"అను అడుగు జాడల మార్గము అనుసరించు అక్షరములను గ్రహించలేకున్నది" +"\"%s\"పదబంధములోవున్న \"%s\"అను అడుగు జాడల మార్గము అనుసరించు అక్షరములను " +"గ్రహించలేకున్నది" -#: ../src/ui/theme-parser.c:613 +#: ../src/ui/theme-parser.c:615 #, c-format msgid "Integer %ld must be positive" msgstr "%ld అను పూర్ణాంకము నిశ్చయమైనదిగా అవవలెను" -#: ../src/ui/theme-parser.c:621 +#: ../src/ui/theme-parser.c:623 #, c-format msgid "Integer %ld is too large, current max is %d" msgstr "%ld అను పూర్ణాంకము చాలా పెద్దది, ప్రస్తుత గనిష్ఠము %d" -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 +#: ../src/ui/theme-parser.c:651 ../src/ui/theme-parser.c:767 #, c-format msgid "Could not parse \"%s\" as a floating point number" msgstr "\"%s\"ను ఫ్లోటింగ్‌ను సూచించు సంఖ్యగా పార్స్ చేయబడదు" -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 +#: ../src/ui/theme-parser.c:682 ../src/ui/theme-parser.c:710 #, c-format msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" msgstr "భూలియన్ విలువలు \"ఒప్పు\" లేక \"తప్పు\" కావలెను కాని \"%s\" కాకూడదు" -#: ../src/ui/theme-parser.c:735 +#: ../src/ui/theme-parser.c:737 #, c-format msgid "Angle must be between 0.0 and 360.0, was %g\n" msgstr "కోణం 0.0 మరియు 360.0 మధ్యలో ఉండవలెను, అది %g\n" -#: ../src/ui/theme-parser.c:798 +#: ../src/ui/theme-parser.c:800 #, c-format msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" msgstr "" -"ఆల్ఫ అనునది 0.0(అగోచరమైన) మరియు 1.0(పూర్తిగా వెలుగుచొరనివ్వని) మధ్యలో ఉండవలెను, అది %g\n" +"ఆల్ఫ అనునది 0.0(అగోచరమైన) మరియు 1.0(పూర్తిగా వెలుగుచొరనివ్వని) మధ్యలో " +"ఉండవలెను, అది %g\n" -#: ../src/ui/theme-parser.c:863 +#: ../src/ui/theme-parser.c:865 #, c-format msgid "" "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," "large,x-large,xx-large)\n" msgstr "" -"\"%s\"అను నిస్సారమైన శీర్షిక (చిన్న-xx,చిన్న-x,చిన్నది,మధ్యమము,పెద్దది,పెద్ద-x,పెద్ద-xxలలో ఒకటి " +"\"%s\"అను నిస్సారమైన శీర్షిక (చిన్న-xx,చిన్న-x,చిన్నది,మధ్యమము,పెద్దది,పెద్ద-x" +",పెద్ద-xxలలో ఒకటి " "అవవలెను)\n" -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 +#: ../src/ui/theme-parser.c:1021 ../src/ui/theme-parser.c:1084 +#: ../src/ui/theme-parser.c:1118 ../src/ui/theme-parser.c:1221 #, c-format msgid "<%s> name \"%s\" used a second time" -msgstr "<%s> నామము \"%s\" రెండోవసారి ఉపయోగించబడినది" +msgstr "<%s> పేరు \"%s\" రెండోవసారి ఉపయోగించబడినది" -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 +#: ../src/ui/theme-parser.c:1033 ../src/ui/theme-parser.c:1130 +#: ../src/ui/theme-parser.c:1233 #, c-format msgid "<%s> parent \"%s\" has not been defined" msgstr "<%s> మూలము \"%s\" నిర్వచించబడలేదు" -#: ../src/ui/theme-parser.c:1141 +#: ../src/ui/theme-parser.c:1143 #, c-format msgid "<%s> geometry \"%s\" has not been defined" msgstr "<%s> క్షేత్రగణితం \"%s\" నిర్వచించబడలేదు" -#: ../src/ui/theme-parser.c:1154 +#: ../src/ui/theme-parser.c:1156 #, c-format msgid "<%s> must specify either a geometry or a parent that has a geometry" msgstr "<%s> అనునిదిక్షేత్రగణితమును లేక క్షేత్రగణితపు మూలమును పేర్కొనవలెను" -#: ../src/ui/theme-parser.c:1196 +#: ../src/ui/theme-parser.c:1198 msgid "You must specify a background for an alpha value to be meaningful" msgstr "మీరు ఆల్ఫా విలువని అర్దవంతమైనదిగా చేయుటకు పూర్వరంగమును నిర్దేశించవలెను" -#: ../src/ui/theme-parser.c:1264 +#: ../src/ui/theme-parser.c:1266 #, c-format msgid "Unknown type \"%s\" on <%s> element" msgstr "<%s>అను మూలకము పై \"%s\" తెలియని రకము " -#: ../src/ui/theme-parser.c:1275 +#: ../src/ui/theme-parser.c:1277 #, c-format msgid "Unknown style_set \"%s\" on <%s> element" msgstr "<%s>అను మూలకము పై \"%s\" తెలియని రకమును అమర్చెను" -#: ../src/ui/theme-parser.c:1283 +#: ../src/ui/theme-parser.c:1285 #, c-format msgid "Window type \"%s\" has already been assigned a style set" -msgstr "విండోరకం \"%s\" ముందుగానే ఒక శైలి అమరికకు స్థానం ఇచ్చివుండినది" +msgstr "కిటికీరకం \"%s\" ముందుగానే ఒక శైలి అమరికకు స్థానం ఇచ్చివుండినది" -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 +#: ../src/ui/theme-parser.c:1315 ../src/ui/theme-parser.c:1379 +#: ../src/ui/theme-parser.c:1605 ../src/ui/theme-parser.c:2840 +#: ../src/ui/theme-parser.c:2886 ../src/ui/theme-parser.c:3036 +#: ../src/ui/theme-parser.c:3272 ../src/ui/theme-parser.c:3310 +#: ../src/ui/theme-parser.c:3348 ../src/ui/theme-parser.c:3386 #, c-format msgid "Element <%s> is not allowed below <%s>" msgstr "<%s> మూల వస్తువు <%s> క్రింద అనుమతించబడవు" -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 +#: ../src/ui/theme-parser.c:1429 ../src/ui/theme-parser.c:1443 +#: ../src/ui/theme-parser.c:1488 msgid "" "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " "for buttons" msgstr "" -"బటన్ ల కొఱకు \"బటన్ వెడల్పు\"(_w)/\"బటన్ ఎత్తు\"(_h) మరియు \"దృశ్య నిష్పత్తి\"ని నిర్దేశించబడవు" +"బటన్ ల కొఱకు \"బటన్ వెడల్పు\"(_w)/\"బటన్ ఎత్తు\"(_h) మరియు \"దృశ్య " +"నిష్పత్తి\"ని నిర్దేశించబడవు" -#: ../src/ui/theme-parser.c:1450 +#: ../src/ui/theme-parser.c:1452 #, c-format msgid "Distance \"%s\" is unknown" -msgstr "\"%s\" దూరము అపరిచితము" +msgstr "\"%s\" దూరము తెలియదు" -#: ../src/ui/theme-parser.c:1495 +#: ../src/ui/theme-parser.c:1497 #, c-format msgid "Aspect ratio \"%s\" is unknown" -msgstr "\"%s\" దృశ్య నిష్పత్తి అపరిచితము" +msgstr "\"%s\" దృశ్య నిష్పత్తి తెలియదు" -#: ../src/ui/theme-parser.c:1557 +#: ../src/ui/theme-parser.c:1559 #, c-format msgid "Border \"%s\" is unknown" -msgstr "\"%s\"సరిహద్దు అపరిచితము" +msgstr "\"%s\"సరిహద్దు తెలియదు" -#: ../src/ui/theme-parser.c:1868 +#: ../src/ui/theme-parser.c:1870 #, c-format msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "<%s>అను మూలాంకముపై ఎలాంటి \"ఎక్షటెంట్ కోణము\" లేక \"నుండి\" ఆట్రిబ్యూట్‌ని పొందదు" +msgstr "" +"<%s>అను మూలాంకముపై ఎలాంటి \"ఎక్షటెంట్ కోణము\" లేక \"నుండి\" ఆట్రిబ్యూట్‌ని " +"పొందదు" -#: ../src/ui/theme-parser.c:1875 +#: ../src/ui/theme-parser.c:1877 #, c-format msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "<%s>అను మూలాంకముపై ఎలాంటి \"ఎక్షటెంట్ కోణము\" లేక \"కొఱకు\" ఆట్రిబ్యూట్‌ని పొందదు" +msgstr "" +"<%s>అను మూలాంకముపై ఎలాంటి \"ఎక్షటెంట్ కోణము\" లేక \"కొఱకు\" ఆట్రిబ్యూట్‌ని " +"పొందదు" -#: ../src/ui/theme-parser.c:2115 +#: ../src/ui/theme-parser.c:2117 #, c-format msgid "Did not understand value \"%s\" for type of gradient" msgstr "మూలాంకము కొఱకు \"%s\"అను పాతమును గ్రహించబడలేదు" -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 +#: ../src/ui/theme-parser.c:2195 ../src/ui/theme-parser.c:2570 #, c-format msgid "Did not understand fill type \"%s\" for <%s> element" msgstr "<%s> మూలాంకము కొఱకు \"%s\"అను భర్తీచేయు రకమును గ్రహించబడలేదు" -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 +#: ../src/ui/theme-parser.c:2362 ../src/ui/theme-parser.c:2445 +#: ../src/ui/theme-parser.c:2508 #, c-format msgid "Did not understand state \"%s\" for <%s> element" msgstr "<%s> మూలాంకము కొఱకు \"%s\"అను స్థితిని గ్రహించబడలేదు" -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 +#: ../src/ui/theme-parser.c:2372 ../src/ui/theme-parser.c:2455 #, c-format msgid "Did not understand shadow \"%s\" for <%s> element" msgstr "<%s> మూలాంకము కొఱకు \"%s\"అనుప్రతిబింబమును గ్రహించబడలేదు" -#: ../src/ui/theme-parser.c:2380 +#: ../src/ui/theme-parser.c:2382 #, c-format msgid "Did not understand arrow \"%s\" for <%s> element" msgstr "<%s> మూలాంకము కొఱకు \"%s\"అను బాణమును గ్రహించబడలేదు" -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 +#: ../src/ui/theme-parser.c:2696 ../src/ui/theme-parser.c:2792 #, c-format msgid "No <draw_ops> called \"%s\" has been defined" msgstr "\"%s\"అను నామముగల <డ్రా అప్>లను వివరించబడలేదు" -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 +#: ../src/ui/theme-parser.c:2708 ../src/ui/theme-parser.c:2804 #, c-format msgid "Including draw_ops \"%s\" here would create a circular reference" msgstr "\"%s\"డ్రా ఆప్‌లతో సహా ఇక్కడ ఒక వ్రుత్తాంతపు నివేదనను స్రుష్ఠించబడును" -#: ../src/ui/theme-parser.c:2917 +#: ../src/ui/theme-parser.c:2919 #, c-format msgid "Unknown position \"%s\" for frame piece" msgstr "చట్రము శైలి కొఱకు \"%s\"అనునది తెలియని స్థితి " -#: ../src/ui/theme-parser.c:2925 +#: ../src/ui/theme-parser.c:2927 #, c-format msgid "Frame style already has a piece at position %s" msgstr "చట్రము శైలి %s స్థితి దగ్గర ఒక తునకను ముందుగానే కలిగివున్నది" -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 +#: ../src/ui/theme-parser.c:2944 ../src/ui/theme-parser.c:3021 #, c-format msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "\"%s\"అను నామముగల <డ్రా అప్>లను వివరించబడలేదు" +msgstr "\"%s\"అను పేరుగల <draw_ops>లను వివరించబడలేదు" -#: ../src/ui/theme-parser.c:2972 +#: ../src/ui/theme-parser.c:2974 #, c-format msgid "Unknown function \"%s\" for button" msgstr "బటన్ కొఱకు \"%s\"అనునది తెలియని ప్రక్రియ" -#: ../src/ui/theme-parser.c:2982 +#: ../src/ui/theme-parser.c:2984 #, c-format msgid "Button function \"%s\" does not exist in this version (%d, need %d)" msgstr "\"%s\"అను బటన్ ప్రక్రియ (%d,%d అవసరం)వైవిద్వాంశములో నివసించదు" -#: ../src/ui/theme-parser.c:2994 +#: ../src/ui/theme-parser.c:2996 #, c-format msgid "Unknown state \"%s\" for button" msgstr "బటన్ కొఱకు \"%s\"అనునది తెలియని స్థితి" -#: ../src/ui/theme-parser.c:3002 +#: ../src/ui/theme-parser.c:3004 #, c-format msgid "Frame style already has a button for function %s state %s" -msgstr "చట్రము శైలి ముందుగానే ప్రక్రియ %s స్థితి %s నకు ఒక బటన్ ను కలిగివున్నది" +msgstr "" +"చట్రము శైలి ముందుగానే ప్రక్రియ %s స్థితి %s నకు ఒక బటన్ ను కలిగివున్నది" -#: ../src/ui/theme-parser.c:3073 +#: ../src/ui/theme-parser.c:3075 #, c-format msgid "\"%s\" is not a valid value for focus attribute" msgstr "కేంద్రము ఆట్రిబ్యూట్ కొఱకు \"%s\" విలువ వర్తించబడదు" -#: ../src/ui/theme-parser.c:3082 +#: ../src/ui/theme-parser.c:3084 #, c-format msgid "\"%s\" is not a valid value for state attribute" msgstr "స్థితి ఆట్రిబ్యూట్ కొఱకు \"%s\" విలువ వర్తించబడదు" -#: ../src/ui/theme-parser.c:3092 +#: ../src/ui/theme-parser.c:3094 #, c-format msgid "A style called \"%s\" has not been defined" msgstr "\"%s\"అను పిలువబడు శైలిని వివరించబడలేదు" -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 +#: ../src/ui/theme-parser.c:3115 ../src/ui/theme-parser.c:3138 #, c-format msgid "\"%s\" is not a valid value for resize attribute" msgstr "పునఃపరిమాణం ఆట్రిబ్యూట్ కొఱకు \"%s\" విలువ వర్తించబడదు" -#: ../src/ui/theme-parser.c:3147 +#: ../src/ui/theme-parser.c:3149 #, c-format msgid "" "Should not have \"resize\" attribute on <%s> element for maximized/shaded " "states" msgstr "" -"గనిష్ఠ/మూసివున్న స్థితిల కొఱకు <%s> మూలాంకముపైన \"పునఃపరిమాణం\" ఆట్రిబ్యూట్‌ని కలిగివుండకూడదు" +"గనిష్ఠ/మూసివున్న స్థితిల కొఱకు <%s> మూలాంకముపైన \"పునఃపరిమాణం\" " +"ఆట్రిబ్యూట్‌ని కలిగివుండకూడదు" -#: ../src/ui/theme-parser.c:3161 +#: ../src/ui/theme-parser.c:3163 #, c-format msgid "" "Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "గనిష్ఠ స్థితిల కొఱకు <%s> మూలాంకముపైన \"పునఃపరిమాణం\" ఆట్రిబ్యూట్‌ని కలిగివుండకూడదు" +msgstr "" +"గనిష్ఠ స్థితిల కొఱకు <%s> మూలాంకముపైన \"పునఃపరిమాణం\" ఆట్రిబ్యూట్‌ని " +"కలిగివుండకూడదు" -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 +#: ../src/ui/theme-parser.c:3177 ../src/ui/theme-parser.c:3221 #, c-format msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "కేంద్రము %s పునఃపరిమాణించటము %s స్థితి %s కొఱకు శైలిని ముందుగానే నిర్దేశించబడినది" +msgstr "" +"కేంద్రము %s పునఃపరిమాణించటము %s స్థితి %s కొఱకు శైలిని ముందుగానే " +"నిర్దేశించబడినది" -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 +#: ../src/ui/theme-parser.c:3188 ../src/ui/theme-parser.c:3199 +#: ../src/ui/theme-parser.c:3210 ../src/ui/theme-parser.c:3232 +#: ../src/ui/theme-parser.c:3243 ../src/ui/theme-parser.c:3254 #, c-format msgid "Style has already been specified for state %s focus %s" msgstr "కేంద్రము %s స్థితి %s కొఱకు శైలిని ముందుగానే నిర్దేశించబడినది" -#: ../src/ui/theme-parser.c:3294 +#: ../src/ui/theme-parser.c:3293 msgid "" "Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " "attribute and also a <draw_ops> element, or specified two elements)" msgstr "" -"ఒక <తునక> మూలాంకమునకు రెండు డ్రా ఆప్‌లు(_o) ఉండుట సాధ్యపడదు(వైవిద్వంశము డ్రా ఆప్‌ల(_o)" -"ఆట్రిబ్యూట్‌నిమరియు <డ్రా ఆప్‌ల>(_o)మూలాంకమును నిర్దేశించినది, లేక రెండు మాలాంకములను నిర్దేశించినది)" +"ఒక <తునక> మూలాంకమునకు రెండు డ్రా ఆప్‌లు(_o) ఉండుట సాధ్యపడదు(వైవిద్వంశము డ్రా " +"ఆప్‌ల(_o)ఆట్రిబ్యూట్‌నిమరియు <డ్రా ఆప్‌ల>(_o)మూలాంకమును నిర్దేశించినది, లేక " +"రెండు మాలాంకములను " +"నిర్దేశించినది)" -#: ../src/ui/theme-parser.c:3332 +#: ../src/ui/theme-parser.c:3331 msgid "" "Can't have a two draw_ops for a <button> element (theme specified a draw_ops " "attribute and also a <draw_ops> element, or specified two elements)" msgstr "" -"ఒక <బటన్> మూలాంకమునకు రెండు డ్రా ఆప్‌లు(_o) ఉండుట సాధ్యపడదు(వైవిద్వంశము డ్రా ఆప్‌ల(_o)" -"ఆట్రిబ్యూట్‌నిమరియు <డ్రా ఆప్‌ల>(_o)మూలాంకమును నిర్దేశించినది, లేక రెండు మాలాంకములను నిర్దేశించినది)" +"ఒక <బటన్> మూలాంకమునకు రెండు డ్రా ఆప్‌లు(_o) ఉండుట సాధ్యపడదు(వైవిద్వంశము డ్రా " +"ఆప్‌ల(_o)ఆట్రిబ్యూట్‌నిమరియు <డ్రా ఆప్‌ల>(_o)మూలాంకమును నిర్దేశించినది, లేక " +"రెండు మాలాంకములను " +"నిర్దేశించినది)" -#: ../src/ui/theme-parser.c:3370 +#: ../src/ui/theme-parser.c:3369 msgid "" "Can't have a two draw_ops for a <menu_icon> element (theme specified a " "draw_ops attribute and also a <draw_ops> element, or specified two elements)" msgstr "" -"ఒక <జాబితా ప్రతిమ>(_i) మూలాంకమునకు రెండు డ్రా ఆప్‌లు(_o) ఉండుట సాధ్యపడదు(వైవిద్వంశము డ్రా ఆప్‌ల" -"(_o)ఆట్రిబ్యూట్‌నిమరియు <డ్రా ఆప్‌ల>(_o)మూలాంకమును నిర్దేశించినది, లేక రెండు మాలాంకములను నిర్దేశించినది)" +"ఒక <జాబితా ప్రతిమ>(_i) మూలాంకమునకు రెండు డ్రా ఆప్‌లు(_o) ఉండుట " +"సాధ్యపడదు(వైవిద్వంశము డ్రా " +"ఆప్‌ల(_o)ఆట్రిబ్యూట్‌నిమరియు <డ్రా ఆప్‌ల>(_o)మూలాంకమును నిర్దేశించినది, లేక " +"రెండు మాలాంకములను " +"నిర్దేశించినది)" -#: ../src/ui/theme-parser.c:3434 +#: ../src/ui/theme-parser.c:3433 #, c-format msgid "Bad version specification '%s'" msgstr "చెడు వైవిద్వాంశమును నిర్దేశించుట'%s'" -#: ../src/ui/theme-parser.c:3507 +#: ../src/ui/theme-parser.c:3506 msgid "" "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" "theme-2.xml" msgstr "" -"\"వివరణము\" ఆట్రిబ్యూట్‌ని మెటాసిటీ-వైవిద్వాంశము-1.xml లేక మెటాసిటీ-వైవిద్వాంశము-2.xmlలకు ఉపయోగించబడదు" +"\"వివరణము\" ఆట్రిబ్యూట్‌ని మెటాసిటీ-వైవిద్వాంశము-1.xml లేక " +"మెటాసిటీ-వైవిద్వాంశము-2.xmlలకు ఉపయోగించబడదు" -#: ../src/ui/theme-parser.c:3530 +#: ../src/ui/theme-parser.c:3529 #, c-format msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "వైవిద్వాంశము %s వివరణము కోరుచున్నది కాని సరిక్రొత్త సహకరించు వైవిద్వాంశపు వివరణము %d.%d" +msgstr "" +"వైవిద్వాంశము %s వివరణము కోరుచున్నది కాని సరిక్రొత్త సహకరించు వైవిద్వాంశపు " +"వివరణము %d.%d" -#: ../src/ui/theme-parser.c:3562 +#: ../src/ui/theme-parser.c:3561 #, c-format msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "వైవిద్వాంశములోవున్న ఆఖరి భాగపు మూలాంకము <మెటాసిటీ వైవిద్వాంశము> కావలెను కాని <%s> కాకూడదు" +msgstr "" +"వైవిద్వాంశములోవున్న ఆఖరి భాగపు మూలాంకము <మెటాసిటీ వైవిద్వాంశము> కావలెను కాని " +"<%s> కాకూడదు" -#: ../src/ui/theme-parser.c:3582 +#: ../src/ui/theme-parser.c:3581 #, c-format msgid "" "Element <%s> is not allowed inside a name/author/date/description element" -msgstr "నామము/మూలకర్త/తేది/వివరణ మూల వస్తువు లోపలికి ఒక <%s> మూల వస్తువును అనుమతించబడదు" +msgstr "" +"నామము/మూలకర్త/తేది/వివరణ మూల వస్తువు లోపలికి ఒక <%s> మూల వస్తువును " +"అనుమతించబడదు" -#: ../src/ui/theme-parser.c:3587 +#: ../src/ui/theme-parser.c:3586 #, c-format msgid "Element <%s> is not allowed inside a <constant> element" msgstr "<స్థిరరాశి> మూల వస్తువు లోపలికి ఒక <%s> మూల వస్తువును అనుమతించబడదు" -#: ../src/ui/theme-parser.c:3599 +#: ../src/ui/theme-parser.c:3598 #, c-format msgid "" "Element <%s> is not allowed inside a distance/border/aspect_ratio element" msgstr "" -"దూరపు/సరిహద్దు/దృశ్య నిష్పత్తి మూల వస్తువు లోపలికి ఒక <%s> మూల వస్తువును అనుమతించబడదు" +"దూరపు/సరిహద్దు/దృశ్య నిష్పత్తి మూల వస్తువు లోపలికి ఒక <%s> మూల వస్తువును " +"అనుమతించబడదు" -#: ../src/ui/theme-parser.c:3621 +#: ../src/ui/theme-parser.c:3620 #, c-format msgid "Element <%s> is not allowed inside a draw operation element" msgstr "గీయు కార్యపు మూల వస్తువు లోపలికి ఒక <%s> మూల వస్తువును అనుమతించబడదు" -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 +#: ../src/ui/theme-parser.c:3630 ../src/ui/theme-parser.c:3660 +#: ../src/ui/theme-parser.c:3665 ../src/ui/theme-parser.c:3670 #, c-format msgid "Element <%s> is not allowed inside a <%s> element" msgstr "మూల వస్తువు <%s> లోపలికి ఒక <%s> మూల వస్తువుని అనుమతించబడదు " -#: ../src/ui/theme-parser.c:3899 +#: ../src/ui/theme-parser.c:3898 msgid "No draw_ops provided for frame piece" msgstr "చట్రపు తునక కొఱకు ఎలాంటి డ్రా ఆప్లను పొందుపరచలేదు(_o)" -#: ../src/ui/theme-parser.c:3914 +#: ../src/ui/theme-parser.c:3913 msgid "No draw_ops provided for button" msgstr "బటన్ కొఱకు ఎలాంటి డ్రా ఆప్లను పొందుపరచలేదు(_o)" -#: ../src/ui/theme-parser.c:3968 +#: ../src/ui/theme-parser.c:3967 #, c-format msgid "No text is allowed inside element <%s>" msgstr "<%s> మూల వస్తువు లోపల ఎటువంటి పాఠం అనుమతించబడదు" -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 +#: ../src/ui/theme-parser.c:4025 ../src/ui/theme-parser.c:4037 +#: ../src/ui/theme-parser.c:4049 ../src/ui/theme-parser.c:4061 +#: ../src/ui/theme-parser.c:4073 #, c-format msgid "<%s> specified twice for this theme" msgstr "ఈ వైవిద్వాంశమునకు <%s>ను రెండు మార్లు పేర్కొనబడినవి" -#: ../src/ui/theme-parser.c:4348 +#: ../src/ui/theme-parser.c:4335 #, c-format msgid "Failed to find a valid file for theme %s\n" msgstr "%s అను వైవిద్వాంశమునకు ఒక స్థిరీకరించు దస్త్రమును కనుగొనుట విఫలమైనది\n" -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "గవాక్షములు(_W)" +#: ../src/x11/session.c:1815 +msgid "" +"These windows do not support "save current setup" and will have to " +"be restarted manually next time you log in." +msgstr "" +"ఈ కిటికీలు కోట్(&q)ని సహకరించటలేదు; ప్రస్తుత అమరికను కోట్(&q)గా భద్రపరుచుము; " +"మరియు మళ్ళీ " +"ప్రవేశించినప్పుడుస్వయముగా పునఃప్రారంభించబడవలెను" -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "వివరణ(_D)" +#: ../src/x11/window-props.c:558 +#, c-format +msgid "%s (on %s)" +msgstr "%s (%s పై)" -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "మోడల్ వివరణ(_M)" +#~ msgid "background texture could not be created from file" +#~ msgstr "ఫైలు నుండి బ్యాక్‌గ్రౌండ్ టెక్చర్ సృష్టించబడలేక పోయింది" -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "సౌలభ్యం(_U)" +#~ msgid "Unknown window information request: %d" +#~ msgstr "తెలియని కిటికీ సమాచార మనవి: %d" -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "చెదిరిన తెర(_S)" +#~ msgid "Missing %s extension required for compositing" +#~ msgstr "కూర్పునకు తొలిగించిన %s పొడిగింపు అవసరమున్నది" -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "పైన డాక్(_T)" +#~ msgid "" +#~ "Some other program is already using the key %s with modifiers %x as a " +#~ "binding\n" +#~ msgstr "" +#~ "కీ %sని ముందుగానే %x మార్పుచేయునవి తో పాటు వేరొక కార్యక్రమము బంధించున్నదిగా ఉపయోగిస్తుంది\n" -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "క్రింది డాక్(_B)" +#~| msgid "\"%s\" is not a valid value for focus attribute" +#~ msgid "\"%s\" is not a valid accelerator\n" +#~ msgstr "\"%s\" చెల్లునటువంచి ఏగ్జలరేటర్ కాదు\n" -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "ఎడమ డాక్(_L)" +#~ msgid "" +#~ "Workarounds for broken applications disabled. Some applications may not " +#~ "behave properly.\n" +#~ msgstr "" +#~ "విరిగిన అనువర్తనములకు చుట్టుప్రక్కలపనిచేయువాటిని నిరుపయోగపరిచెను. కొన్ని అనువర్తనములు సరైన రీతిలో " +#~ "వ్యవహరించకపోవచ్చు.\n" -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "కుడి డాక్(_R)" +#~ msgid "Could not parse font description \"%s\" from GSettings key %s\n" +#~ msgstr "%s జికాన్‌ఫ్ కీ నుండి \"%s\" పార్స్ ఖతి వివరించలేకపోవుచున్నది\n" -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "అన్ని డాక్‌లు(_A)" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" +#~ msgstr "మోస్ బటన్‌ మార్చునదికి రూపకరించిన దత్తాంశస్థానములో కనుగొనిన \"%s\"కు విలువలేదు\n" -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "రంగస్థలం(_k)" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for " +#~ "keybinding \"%s\"\n" +#~ msgstr "కీబంధించునదికి రూపకరించిన దత్తాంశస్థానములో కనుగొనిన \"%s\"కు విలువలేదు\"%s\"\n" -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "ఈ విండోలలో ఒకదానిని తెరువుము" +#~ msgid "" +#~ "Could not acquire window manager selection on screen %d display \"%s\"\n" +#~ msgstr "%d తెర పై \"%s\" ప్రదర్శనపు కిటికీ నిర్వాహకంను ఎంపిక సంపాదించుటలేదు\n" -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "ఇది 'తెరువుము'అను ప్రతిమతో కూడివున్న మచ్చునకు ఒక బటన్" +#~ msgid "Could not release screen %d on display \"%s\"\n" +#~ msgstr "%d తెరని \"%s\" ప్రదర్శనపై విడుదలచేయబడుటలేదు\n" -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "ఇది 'త్యజించు'అను ప్రతిమతో కూడివున్న మచ్చునకు ఒక బటన్" +#~ msgid "Could not create directory '%s': %s\n" +#~ msgstr "'%s' వివరమును స్రుష్టించబడుటలేదు: %s\n" -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "ఇది మచ్చుకకు ఒక వివిరణములో మచ్చుకకు ఒక సందేశం" +#~ msgid "Could not open session file '%s' for writing: %s\n" +#~ msgstr "'%s' వివరణ దస్త్రమును వ్రాయుట కొఱకు తెరవబడుటలేదు: %s\n" -#: ../src/ui/theme-viewer.c:328 -#, c-format -msgid "Fake menu item %d\n" -msgstr "జాబితాలోని బూటకపు అంశము %d\n" +#~ msgid "Error writing session file '%s': %s\n" +#~ msgstr "'%s'వివరణ దస్త్రమును వ్రాయుచున్నప్పుడు కలిగిన దోషము: %s\n" -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "సరిహద్దు మాత్రమే కలిగిన విండో" +#~ msgid "Error closing session file '%s': %s\n" +#~ msgstr "'%s'వివరణ దస్త్రమును మూయుచున్నప్పుడు కలిగిన దోషము: %s\n" -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "పట్టీ" +#~ msgid "Failed to parse saved session file: %s\n" +#~ msgstr "భద్రపరిచిన వివరణ దస్త్రమును పార్స్ చేయుట విఫలమైనది: %s\n" -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "సాధారణ కార్యక్షేత్రపు విండో" +#~ msgid "<mutter_session> attribute seen but we already have the session ID" +#~ msgstr "" +#~ "<ముట్టర్ వివరణము> ఆట్రిబ్యూట్‌ని చూపించబడినది కాని మనకు ముందుగానే వివరణపు ఐడి కలగివుంది(_s)" -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "వివరణ పేటిక" +#~ msgid "Unknown attribute %s on <%s> element" +#~ msgstr "%s అను తెలియని ఆట్రిబ్యూట్ <%s> మూలకముపై ఉన్నది" -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "మోడల్ వివరణ పేటిక" +#~ msgid "nested <window> tag" +#~ msgstr "మెలికలుపడివున్న <కిటికీ>(window) ట్యాగ్" -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "వర్ణపలకపు సౌలభ్యం" +#~ msgid "Unknown element %s" +#~ msgstr "%s అను తెలియని మూలకము" -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "మూసివేయు జాబితా" +#~ msgid "Failed to open debug log: %s\n" +#~ msgstr "%s అను లోపనిర్మూలన నమోదును తెరవబడుట విఫలమైనది\n" -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "సరిహద్దు" +#~ msgid "Failed to fdopen() log file %s: %s\n" +#~ msgstr "%s అను నమోదు దస్త్రం ఎఫ్‌డిఒపెన్()చేయుట విఫలమైనది: %s\n" -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "జోడించిన మోడల్ వివరణ" +#~ msgid "Opened log file %s\n" +#~ msgstr "%s అను నమోదు దస్త్రమును తెరివబడెను\n" -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "బటన్ కూర్పు పరీక్ష %d" +#~ msgid "Window manager: " +#~ msgstr "కిటికీ నిర్వాహకం: " -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "ఒక విండో చట్రమును గీయుట కొఱకు %g మిల్లిసెకన్‌ల సమయము పడుతుంది" +#~ msgid "Bug in window manager: " +#~ msgstr "కిటికీ నిర్వాహకంలో లోపము: " -#: ../src/ui/theme-viewer.c:813 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "ఉపయోగం: మెటాసిటీ-వైవిద్వాంశం-చూపించునది [THEMENAME]\n" +#~ msgid "Window manager warning: " +#~ msgstr "కిటికీ నిర్వాహకం హెచ్చరిక: " -#: ../src/ui/theme-viewer.c:820 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "వైవిద్వాంశమును బర్తీచేయుచున్నప్పుడు కలిగిన దోషము: %s\n" +#~ msgid "Window manager error: " +#~ msgstr "కిటికీ నిర్వాహకం దోషము: " -#: ../src/ui/theme-viewer.c:826 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "\"%s\" అను వైవిద్వాంశము %g సెకన్‌లలో బర్తీచేయబడినది\n" +#~ msgid "" +#~ "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " +#~ "window as specified in the ICCCM.\n" +#~ msgstr "" +#~ "%s కిటికీ ICCCMలో నిర్దేశించిన విధముగా WM_CLIENT_LEADER కిటికీకి బదులు(_C)" +#~ "(_L)SM_CLIENT_IDని స్వయముగా అమర్చెను(_C)(_I).\n" -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "సాధారణ శీర్షిక అక్షరశైలి" +#~ msgid "" +#~ "Window %s sets an MWM hint indicating it isn't resizable, but sets min " +#~ "size %d x %d and max size %d x %d; this doesn't make much sense.\n" +#~ msgstr "" +#~ "%s కిటికీని పునఃపరిమానించుట కుదరదని తెలియజేయుటకు MWM సూచనను అమర్చినది, కాని కనిష్ఠ పరిమాణం %d " +#~ "x %d మరియు గనిష్ఠ పరిమాణం %d x %d ను అమర్చినది; ఇది అర్దవంతమైనదికాదు.\n" -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "చిన్న శీర్షిక అక్షరశైలి" +#~ msgid "Application set a bogus _NET_WM_PID %lu\n" +#~ msgstr "అనువర్తనమును నకిలీ _NET_WM_PID %luను అమర్చెను\n" -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "పెద్ద శీర్షిక అక్షరశైలి" +#~ msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +#~ msgstr "నిస్సారమైన WM_TRANSIENT_FOR కిటికీ 0x%lxని %s కొఱకు పేర్కొనబడినది.\n" -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "బటన్ కూర్పులు" +#~ msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" +#~ msgstr "WM_TRANSIENT_FOR కిటికీ 0x%lx %s కొఱకు లూప్‌ని స్రుష్ఠించును.\n" -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "బెంచ్‌మార్క్" +#~ msgid "" +#~ "Window 0x%lx has property %s\n" +#~ "that was expected to have type %s format %d\n" +#~ "and actually has type %s format %d n_items %d.\n" +#~ "This is most likely an application bug, not a window manager bug.\n" +#~ "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +#~ msgstr "" +#~ "కిటికీ 0x%lx నకు %s గుణము కలదు \n" +#~ " %s రూపకముతో కూడిన %d రకమును పొందుటకు ఊహించబడినది\n" +#~ "మరియు నిజముగా %s రకము %d రూపకం %d అంశములు(_i) కలిగివున్నవి.\n" +#~ "ఇది అనువర్తనపు తప్పిదముగా అనిపించుచున్నది, కాని కిటికీ నిర్వాహకం తప్పిదము కాదు.\n" +#~ "కిటికీ శీర్షిక=\"%s\" తరగతి=\"%s\" పేరు=\"%s\" అని కలవు\n" -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "విండో శీర్షిక ఇక్కడ నడుస్తోంది" +#~ msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +#~ msgstr "%sఅను గుణము కిటికీ 0x%lx పై నిస్సారమైన UTF-8 ని కలిగివుండెను\n" -#: ../src/ui/theme-viewer.c:1047 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"%d చట్రములను %g క్లైంట్ భాగపు సెకన్‌లలో(ఒక చట్రమునకు %g సెకన్‌లు)మరియు %g సెకన్‌ల గోడపు గడియారము " -"సమయము తో పాటుగా x సేవిక వనరులను చిత్రీకరించెను(ఒక చట్రమునకు %g సెకన్‌లు)\n" +#~ msgid "" +#~ "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the " +#~ "list\n" +#~ msgstr "" +#~ "%s అను గుణము కిటికీ 0x%lx పై జాబితాలోని %d అంశము కోఱకు నిస్సారమైన UTF-8 ని కలిగివుండెను\n" -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "స్థానపు వైఖరి పరీక్ష TRUE అని తేల్చినది కాని దోషమును చూపించలేదు" +#~ msgid "Usage: %s\n" +#~ msgstr "వుపయోగించుము: %s\n" -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "స్థానపు వైఖరి పరీక్ష FALSE అని తేల్చినది కాని దోషమును చూపించలేదు" +#~ msgid "Mi_nimize" +#~ msgstr "కనిష్టీకరించు (_n)" -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "దోషమును ఊహించెను కాని ఏమి ఇవ్వలేదు" +#~ msgid "Ma_ximize" +#~ msgstr "గరిష్టీకరించు (_x)" -#: ../src/ui/theme-viewer.c:1274 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "%d దోషమును ఊహించెను కాని %d ఇచ్చినది" +#~ msgid "Unma_ximize" +#~ msgstr "గరిష్టీకరించవద్దు (_x)" -#: ../src/ui/theme-viewer.c:1280 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "దోషమును ఊహించలేదు కాని ఒకటటి పునరాగమించినది: %s" +#~ msgid "Roll _Up" +#~ msgstr "ఎగువకు మడువుము(_U)" -#: ../src/ui/theme-viewer.c:1284 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "x విలువ %d అని ఉండెడది, %d ఊహించబడినది" +#~ msgid "_Unroll" +#~ msgstr "మడవవద్దు(_U)" -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "y విలువ %d అని ఉండెడది, %d ఊహించబడినది" +#~ msgid "_Move" +#~ msgstr "జరుపు (_M)" -#: ../src/ui/theme-viewer.c:1352 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "%d అనుకరించు వైఖరిలను %g సెకన్‌లలో పార్స్ చేయబడినవి(సగటుగా %g సెకన్‌లు)\n" +#~ msgid "_Resize" +#~ msgstr "పరిమాణం మార్చు (_R)" + +#~ msgid "Move Titlebar On_screen" +#~ msgstr "శీర్షిక పట్టాను తెరపైకి జరుపుము(_S)" + +#~ msgid "Always on _Top" +#~ msgstr "ఎల్లప్పుడూ పైనే" + +#~ msgid "_Always on Visible Workspace" +#~ msgstr "ఎల్లప్పుడూ గోచరించు కార్యక్షేత్రముపైనే(_A)" + +#~ msgid "_Only on This Workspace" +#~ msgstr "ఈ కార్యక్షేత్రము మాత్రము పైనే(_O)" + +#~ msgid "Move to Workspace _Left" +#~ msgstr "కార్యక్షేత్రం నుండి ఎడమవైపుకు కదులు (_L)" + +#~ msgid "Move to Workspace R_ight" +#~ msgstr "కార్యక్షేత్రం నుండి కుడివైపుకు కదులు (_R)" + +#~ msgid "Move to Workspace _Up" +#~ msgstr "కార్యక్షేత్రం నుండి పైకి కదులు (_U)" + +#~ msgid "Move to Workspace _Down" +#~ msgstr "కార్యక్షేత్రం నుండి క్రిందికి కదులు (_D)" + +#~ msgid "_Close" +#~ msgstr "మూసివేయి (_C)" + +#~ msgid "Workspace %d%n" +#~ msgstr "కార్యక్షేత్రము %d%n" + +#~ msgid "Workspace 1_0" +#~ msgstr "కార్యక్షేత్రము 1_0" + +#~ msgid "Workspace %s%d" +#~ msgstr "కార్యక్షేత్రము %s%d" + +#~ msgid "Move to Another _Workspace" +#~ msgstr "వేరే కార్యక్షేత్రానికి కదులు (_W)" + +#~ msgid "Shift" +#~ msgstr "Shift" + +#~ msgid "Ctrl" +#~ msgstr "Ctrl" + +#~ msgid "Alt" +#~ msgstr "Alt" + +#~ msgid "Meta" +#~ msgstr "Meta" + +#~ msgid "Super" +#~ msgstr "సూపర్" + +#~ msgid "Hyper" +#~ msgstr "హైపర్" + +#~ msgid "Mod2" +#~ msgstr "మాడ్ 2" + +#~ msgid "Mod3" +#~ msgstr "మాడ్ 3" + +#~ msgid "Mod4" +#~ msgstr "మాడ్ 4" + +#~ msgid "Mod5" +#~ msgstr "మాడ్ 5" + +#~ msgid "_Windows" +#~ msgstr "కిటికీలు (_W)" + +#~ msgid "_Dialog" +#~ msgstr "సంవాదం (_D)" + +#~ msgid "_Modal dialog" +#~ msgstr "మోడల్ సంవాదం (_M)" + +#~ msgid "_Utility" +#~ msgstr "సౌలభ్యం (_U)" + +#~ msgid "_Splashscreen" +#~ msgstr "చెదిరిన తెర (_S)" + +#~ msgid "_Top dock" +#~ msgstr "పైన డాక్ (_T)" + +#~ msgid "_Bottom dock" +#~ msgstr "క్రింది డాక్ (_B)" + +#~ msgid "_Left dock" +#~ msgstr "ఎడమ డాక్ (_L)" + +#~ msgid "_Right dock" +#~ msgstr "కుడి డాక్ (_R)" + +#~ msgid "_All docks" +#~ msgstr "అన్ని డాక్‌లు(_A)" + +#~ msgid "Des_ktop" +#~ msgstr "డెస్క్‍టాప్ (_k)" + +#~ msgid "Open another one of these windows" +#~ msgstr "ఈ కిటికీలలో ఒకదానిని తెరువు" + +#~ msgid "This is a demo button with an 'open' icon" +#~ msgstr "ఇది 'తెరువు'అను ప్రతిమతో కూడివున్న మచ్చునకు ఒక బటన్" + +#~ msgid "This is a demo button with a 'quit' icon" +#~ msgstr "ఇది 'నిష్క్రమించు'అను ప్రతిమతో కూడివున్న మచ్చునకు ఒక బటన్" + +#~ msgid "This is a sample message in a sample dialog" +#~ msgstr "ఇది మచ్చుకకు ఒక వివిరణములో మచ్చుకకు ఒక సందేశం" + +#~ msgid "Fake menu item %d\n" +#~ msgstr "జాబితాలోని బూటకపు అంశము %d\n" + +#~ msgid "Border-only window" +#~ msgstr "సరిహద్దు మాత్రమే కలిగిన కిటికీ" -#~ msgid "Switch to workspace 1" -#~ msgstr "పనిప్రదేశము 1 కి మారుము" +#~ msgid "Bar" +#~ msgstr "పట్టీ" -#~ msgid "Switch to workspace 2" -#~ msgstr "పనిప్రదేశము 2 కి మారుము" +#~ msgid "Normal Application Window" +#~ msgstr "సాధారణ కార్యక్షేత్రపు కిటికీ" -#~ msgid "Switch to workspace 3" -#~ msgstr "పనిప్రదేశము 3 కి మారుము" +#~ msgid "Dialog Box" +#~ msgstr "వివరణ పేటిక" -#~ msgid "Switch to workspace 4" -#~ msgstr "పనిప్రదేశము 4 కి మారుము" +#~ msgid "Modal Dialog Box" +#~ msgstr "మోడల్ వివరణ పేటిక" -#~ msgid "Switch to workspace 5" -#~ msgstr "పనిప్రదేశము 5 కి మారుము" +#~ msgid "Utility Palette" +#~ msgstr "వర్ణపలకపు సౌలభ్యం" -#~ msgid "Switch to workspace 6" -#~ msgstr "పనిప్రదేశము 6 కి మారుము" +#~ msgid "Torn-off Menu" +#~ msgstr "మూసివేయు జాబితా" -#~ msgid "Switch to workspace 7" -#~ msgstr "పనిప్రదేశము 7 కి మారుము" +#~ msgid "Border" +#~ msgstr "సరిహద్దు" + +#~ msgid "Attached Modal Dialog" +#~ msgstr "జోడించిన మోడల్ వివరణ" + +#~ msgid "Button layout test %d" +#~ msgstr "బటన్ కూర్పు పరీక్ష %d" + +#~ msgid "%g milliseconds to draw one window frame" +#~ msgstr "ఒక కిటికీ చట్రమును గీయుట కొఱకు %g మిల్లిసెకన్‌ల సమయము పడుతుంది" + +#~ msgid "Usage: metacity-theme-viewer [THEMENAME]\n" +#~ msgstr "ఉపయోగం: మెటాసిటీ-వైవిద్వాంశం-చూపించునది [THEMENAME]\n" + +#~ msgid "Error loading theme: %s\n" +#~ msgstr "వైవిద్వాంశమును బర్తీచేయుచున్నప్పుడు కలిగిన దోషము: %s\n" + +#~ msgid "Loaded theme \"%s\" in %g seconds\n" +#~ msgstr "\"%s\" అను వైవిద్వాంశము %g సెకన్‌లలో బర్తీచేయబడినది\n" + +#~ msgid "Normal Title Font" +#~ msgstr "సాధారణ శీర్షిక ఖతి" + +#~ msgid "Small Title Font" +#~ msgstr "చిన్న శీర్షిక ఖతి" + +#~ msgid "Large Title Font" +#~ msgstr "పెద్ద శీర్షిక ఖతి" + +#~ msgid "Button Layouts" +#~ msgstr "బటన్ కూర్పులు" + +#~ msgid "Benchmark" +#~ msgstr "బెంచ్‌మార్క్" + +#~ msgid "Window Title Goes Here" +#~ msgstr "కిటికీ శీర్షిక ఇక్కడ నడుస్తోంది" + +#~ msgid "" +#~ "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and " +#~ "%g seconds wall clock time including X server resources (%g milliseconds " +#~ "per frame)\n" +#~ msgstr "" +#~ "%d చట్రములను %g క్లైంట్ భాగపు సెకన్‌లలో(ఒక చట్రమునకు %g సెకన్‌లు)మరియు %g సెకన్‌ల గోడపు " +#~ "గడియారము సమయము తో పాటుగా x సేవిక వనరులను చిత్రీకరించెను(ఒక చట్రమునకు %g సెకన్‌లు)\n" + +#~ msgid "position expression test returned TRUE but set error" +#~ msgstr "స్థానపు వైఖరి పరీక్ష TRUE అని తేల్చినది కాని దోషమును చూపించలేదు" + +#~ msgid "position expression test returned FALSE but didn't set error" +#~ msgstr "స్థానపు వైఖరి పరీక్ష FALSE అని తేల్చినది కాని దోషమును చూపించలేదు" + +#~ msgid "Error was expected but none given" +#~ msgstr "దోషమును ఊహించెను కాని ఏమి ఇవ్వలేదు" + +#~ msgid "Error %d was expected but %d given" +#~ msgstr "%d దోషమును ఊహించెను కాని %d ఇచ్చినది" + +#~ msgid "Error not expected but one was returned: %s" +#~ msgstr "దోషమును ఊహించలేదు కాని ఒకటటి పునరాగమించినది: %s" + +#~ msgid "x value was %d, %d was expected" +#~ msgstr "x విలువ %d అని ఉండెడది, %d ఊహించబడినది" + +#~ msgid "y value was %d, %d was expected" +#~ msgstr "y విలువ %d అని ఉండెడది, %d ఊహించబడినది" + +#~ msgid "" +#~ "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" +#~ msgstr "%d అనుకరించు వైఖరిలను %g సెకన్‌లలో పార్స్ చేయబడినవి(సగటుగా %g సెకన్‌లు)\n" + +#, fuzzy +#~ msgid "Minimize window" +#~ msgstr "" +#~ "#-#-#-#-# te.po (metacity.gnome-2-26) #-#-#-#-#\n" +#~ "విండోని చిన్నదిగా చేయుము\n" +#~ "#-#-#-#-# te.po (metacity.gnome-2-26) #-#-#-#-#\n" +#~ "కిటికీ చిన్నదిచేయి" + +#~ msgid "Comma-separated list of compositor plugins" +#~ msgstr "కామ-కూర్పుచేయు ప్లగ్ - ఇన్‌ల వేరుచేయబడిన జాబిత" + +#~ msgid "Live Hidden Windows" +#~ msgstr "చలనం కలిగిన దాగిన కిటికీలు" + +#~ msgid "" +#~ "Determines whether hidden windows (i.e., minimized windows and windows on " +#~ "other workspaces than the current one) should be kept alive." +#~ msgstr "" +#~ "దాగివున్న కిటికీలను (అనగా చిన్నవిగా చేసిన కిటికీలు మరియువేరొక కార్యక్షేత్రముల పైనున్న కిటికీలు) వెలికి " +#~ "తీయవలయునోలేదో వివరిస్తుంది." #~ msgid "Switch to workspace 8" #~ msgstr "పనిప్రదేశము 8 కి మారుము" @@ -1655,54 +1833,12 @@ msgstr "%d అనుకరించు వైఖరిలను %g సెకన #~ msgid "Run a terminal" #~ msgstr "అగ్రమును నడుపుము" -#~ msgid "Activate the window menu" -#~ msgstr "విండో జాబితాను క్రియాశీలపరుచుము" - -#~ msgid "Toggle fullscreen mode" -#~ msgstr "పూర్తితెర సంవిధానమును మార్చుము" - -#~ msgid "Toggle maximization state" -#~ msgstr "పెద్దదిగాచేయు స్థితిని మార్చుము" - #~ msgid "Toggle whether a window will always be visible over other windows" #~ msgstr "ఒక విండో ఇతర విండోలపై గోచరించునో లేదో మార్చి చూడుము" -#~ msgid "Maximize window" -#~ msgstr "విండోని పెద్దదిగా చేయుము" - -#~ msgid "Restore window" -#~ msgstr "విండోని పునఃస్ధాపించు" - -#~ msgid "Toggle shaded state" -#~ msgstr "మూసివున్న స్ధితిని మార్చుము" - -#~ msgid "Minimize window" -#~ msgstr "విండోని చిన్నదిగా చేయుము" - -#~ msgid "Close window" -#~ msgstr "గవాక్షమును మూయుము" - -#~ msgid "Move window" -#~ msgstr "విండోని జరుపుము" - -#~ msgid "Resize window" -#~ msgstr "విండోని పునఃపరిమాణించుము" - #~ msgid "Toggle whether window is on all workspaces or just one" #~ msgstr "విండో అన్ని పనిప్రదేశములపైన లేక ఒకదానిపైన మాత్రమే ఉన్నదా లేదా మార్చి చుడుము" -#~ msgid "Move window to workspace 1" -#~ msgstr "విండోని పనిప్రదేశము 1 నకు జరుపుము" - -#~ msgid "Move window to workspace 2" -#~ msgstr "విండోని పనిప్రదేశము 2 నకు జరుపుము" - -#~ msgid "Move window to workspace 3" -#~ msgstr "విండోని పనిప్రదేశము 3 నకు జరుపుము" - -#~ msgid "Move window to workspace 4" -#~ msgstr "విండోని పనిప్రదేశము 4 నకు జరుపుము" - #~ msgid "Move window to workspace 5" #~ msgstr "విండోని పనిప్రదేశము 5 నకు జరుపుము" @@ -1727,34 +1863,10 @@ msgstr "%d అనుకరించు వైఖరిలను %g సెకన #~ msgid "Move window to workspace 12" #~ msgstr "విండోని పనిప్రదేశము 12 నకు జరుపుము" -#~ msgid "Move window one workspace to the left" -#~ msgstr "విండో ఒక పనిప్రదేశమును ఎడమ భాగమునకు జరుపుము" - -#~ msgid "Move window one workspace to the right" -#~ msgstr "విండో ఒక పనిప్రదేశమును కుడి భాగమునకు జరుపుము" - -#~ msgid "Move window one workspace up" -#~ msgstr "విండో ఒక పనిప్రదేశమును పై భాగమునకు జరుపుము" - -#~ msgid "Move window one workspace down" -#~ msgstr "విండో ఒక పనిప్రదేశమును క్రింది భాగమునకు జరుపుము" - #~ msgid "Raise window if it's covered by another window, otherwise lower it" #~ msgstr "" #~ "ఒకవేళ విండోను వేరొక విండో చేత మూసివున్నచో దానిని వెలుపలికి తీసుకురమ్ము లేనిచో లోనికి తీసుకువెళ్ళుము" -#~ msgid "Raise window above other windows" -#~ msgstr "విండోని ఇతర విండోల వెలుపలికి తీసుకొనిరమ్ము" - -#~ msgid "Lower window below other windows" -#~ msgstr "విండోని ఇతర విండోల లోపలికి తీసుకొనివెళ్ళుమ్ము" - -#~ msgid "Maximize window vertically" -#~ msgstr "విండోని నిలువుగా పెద్దది చేయుము" - -#~ msgid "Maximize window horizontally" -#~ msgstr "విండోని అడ్డంగా పెద్దది చేయుము" - #~ msgid "Move window to north-west (top left) corner" #~ msgstr "విండోని ఉత్తర-పడమర (ఎడమ పైభాగము)పు మూలలోనికి జరుపుము" diff --git a/po/tg.po b/po/tg.po new file mode 100644 index 000000000..120ff67df --- /dev/null +++ b/po/tg.po @@ -0,0 +1,1663 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Victor Ibragimov <victor.ibragimov@gmail.com>, 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: Tajik Gnome\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=mutter&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2013-03-18 22:16+0000\n" +"PO-Revision-Date: 2013-01-21 16:12+0500\n" +"Last-Translator: Victor Ibragimov <victor.ibragimov@gmail.com>\n" +"Language-Team: \n" +"Language: tg\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.5.4\n" + +#: ../src/50-mutter-navigation.xml.in.h:1 +msgid "Navigation" +msgstr "Паймоиш" + +#: ../src/50-mutter-navigation.xml.in.h:2 +msgid "Move window to workspace 1" +msgstr "Интиқол додани равзана ба фазои кории 1" + +#: ../src/50-mutter-navigation.xml.in.h:3 +msgid "Move window to workspace 2" +msgstr "Интиқол додани равзана ба фазои кории 2" + +#: ../src/50-mutter-navigation.xml.in.h:4 +msgid "Move window to workspace 3" +msgstr "Интиқол додани равзана ба фазои кории 3" + +#: ../src/50-mutter-navigation.xml.in.h:5 +msgid "Move window to workspace 4" +msgstr "Интиқол додани равзана ба фазои кории 4" + +#: ../src/50-mutter-navigation.xml.in.h:6 +msgid "Move window one workspace to the left" +msgstr "" + +#: ../src/50-mutter-navigation.xml.in.h:7 +msgid "Move window one workspace to the right" +msgstr "" + +#: ../src/50-mutter-navigation.xml.in.h:8 +msgid "Move window one workspace up" +msgstr "" + +#: ../src/50-mutter-navigation.xml.in.h:9 +msgid "Move window one workspace down" +msgstr "" + +#: ../src/50-mutter-navigation.xml.in.h:10 +msgid "Switch applications" +msgstr "" + +#: ../src/50-mutter-navigation.xml.in.h:11 +msgid "Switch windows" +msgstr "" + +#: ../src/50-mutter-navigation.xml.in.h:12 +msgid "Switch windows of an application" +msgstr "" + +#: ../src/50-mutter-navigation.xml.in.h:13 +msgid "Switch system controls" +msgstr "" + +#: ../src/50-mutter-navigation.xml.in.h:14 +msgid "Switch windows directly" +msgstr "" + +#: ../src/50-mutter-navigation.xml.in.h:15 +msgid "Switch windows of an app directly" +msgstr "" + +#: ../src/50-mutter-navigation.xml.in.h:16 +msgid "Switch system controls directly" +msgstr "" + +#: ../src/50-mutter-navigation.xml.in.h:17 +msgid "Hide all normal windows" +msgstr "" + +#: ../src/50-mutter-navigation.xml.in.h:18 +msgid "Switch to workspace 1" +msgstr "" + +#: ../src/50-mutter-navigation.xml.in.h:19 +msgid "Switch to workspace 2" +msgstr "" + +#: ../src/50-mutter-navigation.xml.in.h:20 +msgid "Switch to workspace 3" +msgstr "" + +#: ../src/50-mutter-navigation.xml.in.h:21 +msgid "Switch to workspace 4" +msgstr "" + +#: ../src/50-mutter-navigation.xml.in.h:22 +msgid "Move to workspace left" +msgstr "" + +#: ../src/50-mutter-navigation.xml.in.h:23 +msgid "Move to workspace right" +msgstr "" + +#: ../src/50-mutter-navigation.xml.in.h:24 +msgid "Move to workspace above" +msgstr "" + +#: ../src/50-mutter-navigation.xml.in.h:25 +msgid "Move to workspace below" +msgstr "" + +#: ../src/50-mutter-system.xml.in.h:1 +msgid "System" +msgstr "Система" + +#: ../src/50-mutter-system.xml.in.h:2 +msgid "Show the run command prompt" +msgstr "" + +#: ../src/50-mutter-system.xml.in.h:3 +msgid "Show the activities overview" +msgstr "" + +#: ../src/50-mutter-windows.xml.in.h:1 +msgid "Windows" +msgstr "Равзанаҳо" + +#: ../src/50-mutter-windows.xml.in.h:2 +msgid "Activate the window menu" +msgstr "" + +#: ../src/50-mutter-windows.xml.in.h:3 +msgid "Toggle fullscreen mode" +msgstr "" + +#: ../src/50-mutter-windows.xml.in.h:4 +msgid "Toggle maximization state" +msgstr "" + +#: ../src/50-mutter-windows.xml.in.h:5 +msgid "Maximize window" +msgstr "" + +#: ../src/50-mutter-windows.xml.in.h:6 +msgid "Restore window" +msgstr "" + +#: ../src/50-mutter-windows.xml.in.h:7 +msgid "Toggle shaded state" +msgstr "" + +#: ../src/50-mutter-windows.xml.in.h:8 +msgid "Close window" +msgstr "Пӯшидани равзана" + +#: ../src/50-mutter-windows.xml.in.h:9 +msgid "Hide window" +msgstr "" + +#: ../src/50-mutter-windows.xml.in.h:10 +msgid "Move window" +msgstr "" + +#: ../src/50-mutter-windows.xml.in.h:11 +msgid "Resize window" +msgstr "" + +#: ../src/50-mutter-windows.xml.in.h:12 +msgid "Toggle window on all workspaces or one" +msgstr "" + +#: ../src/50-mutter-windows.xml.in.h:13 +msgid "Raise window if covered, otherwise lower it" +msgstr "" + +#: ../src/50-mutter-windows.xml.in.h:14 +msgid "Raise window above other windows" +msgstr "" + +#: ../src/50-mutter-windows.xml.in.h:15 +msgid "Lower window below other windows" +msgstr "" + +#: ../src/50-mutter-windows.xml.in.h:16 +msgid "Maximize window vertically" +msgstr "" + +#: ../src/50-mutter-windows.xml.in.h:17 +msgid "Maximize window horizontally" +msgstr "" + +#: ../src/50-mutter-windows.xml.in.h:18 +msgid "View split on left" +msgstr "" + +#: ../src/50-mutter-windows.xml.in.h:19 +msgid "View split on right" +msgstr "" + +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: ../src/compositor/compositor.c:568 +#, c-format +msgid "" +"Another compositing manager is already running on screen %i on display \"%s" +"\"." +msgstr "" + +#: ../src/compositor/meta-background.c:1191 +msgid "background texture could not be created from file" +msgstr "" + +#: ../src/core/bell.c:322 +msgid "Bell event" +msgstr "" + +#: ../src/core/core.c:157 +#, c-format +msgid "Unknown window information request: %d" +msgstr "" + +#: ../src/core/delete.c:111 +#, c-format +msgid "“%s” is not responding." +msgstr "" + +#: ../src/core/delete.c:113 +msgid "Application is not responding." +msgstr "" + +#: ../src/core/delete.c:118 +msgid "" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." +msgstr "" + +#: ../src/core/delete.c:125 +msgid "_Wait" +msgstr "_Интизор шавед" + +#: ../src/core/delete.c:125 +msgid "_Force Quit" +msgstr "" + +#: ../src/core/display.c:401 +#, c-format +msgid "Missing %s extension required for compositing" +msgstr "" + +#: ../src/core/display.c:493 +#, c-format +msgid "Failed to open X Window System display '%s'\n" +msgstr "" + +#: ../src/core/keybindings.c:935 +#, c-format +msgid "" +"Some other program is already using the key %s with modifiers %x as a " +"binding\n" +msgstr "" + +#: ../src/core/keybindings.c:1135 +#, c-format +msgid "\"%s\" is not a valid accelerator\n" +msgstr "" + +#: ../src/core/main.c:197 +msgid "Disable connection to session manager" +msgstr "" + +#: ../src/core/main.c:203 +msgid "Replace the running window manager" +msgstr "" + +#: ../src/core/main.c:209 +msgid "Specify session management ID" +msgstr "" + +#: ../src/core/main.c:214 +msgid "X Display to use" +msgstr "" + +#: ../src/core/main.c:220 +msgid "Initialize session from savefile" +msgstr "" + +#: ../src/core/main.c:226 +msgid "Make X calls synchronous" +msgstr "" + +#: ../src/core/main.c:534 +#, c-format +msgid "Failed to scan themes directory: %s\n" +msgstr "" + +#: ../src/core/main.c:550 +#, c-format +msgid "" +"Could not find a theme! Be sure %s exists and contains the usual themes.\n" +msgstr "" + +#: ../src/core/mutter.c:40 +#, c-format +msgid "" +"mutter %s\n" +"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" +msgstr "" + +#: ../src/core/mutter.c:54 +msgid "Print version" +msgstr "" + +#: ../src/core/mutter.c:60 +msgid "Mutter plugin to use" +msgstr "" + +#: ../src/core/prefs.c:1095 +msgid "" +"Workarounds for broken applications disabled. Some applications may not " +"behave properly.\n" +msgstr "" + +#: ../src/core/prefs.c:1170 +#, c-format +msgid "Could not parse font description \"%s\" from GSettings key %s\n" +msgstr "" + +#: ../src/core/prefs.c:1236 +#, c-format +msgid "" +"\"%s\" found in configuration database is not a valid value for mouse button " +"modifier\n" +msgstr "" + +#: ../src/core/prefs.c:1788 +#, c-format +msgid "" +"\"%s\" found in configuration database is not a valid value for keybinding " +"\"%s\"\n" +msgstr "" + +#: ../src/core/prefs.c:1887 +#, c-format +msgid "Workspace %d" +msgstr "Фазои кории %d" + +#: ../src/core/screen.c:691 +#, c-format +msgid "Screen %d on display '%s' is invalid\n" +msgstr "" + +#: ../src/core/screen.c:707 +#, c-format +msgid "" +"Screen %d on display \"%s\" already has a window manager; try using the --" +"replace option to replace the current window manager.\n" +msgstr "" + +#: ../src/core/screen.c:734 +#, c-format +msgid "" +"Could not acquire window manager selection on screen %d display \"%s\"\n" +msgstr "" + +#: ../src/core/screen.c:812 +#, c-format +msgid "Screen %d on display \"%s\" already has a window manager\n" +msgstr "" + +#: ../src/core/screen.c:998 +#, c-format +msgid "Could not release screen %d on display \"%s\"\n" +msgstr "" + +#: ../src/core/session.c:843 ../src/core/session.c:850 +#, c-format +msgid "Could not create directory '%s': %s\n" +msgstr "" + +#: ../src/core/session.c:860 +#, c-format +msgid "Could not open session file '%s' for writing: %s\n" +msgstr "" + +#: ../src/core/session.c:1001 +#, c-format +msgid "Error writing session file '%s': %s\n" +msgstr "" + +#: ../src/core/session.c:1006 +#, c-format +msgid "Error closing session file '%s': %s\n" +msgstr "" + +#: ../src/core/session.c:1136 +#, c-format +msgid "Failed to parse saved session file: %s\n" +msgstr "" + +#: ../src/core/session.c:1185 +#, c-format +msgid "<mutter_session> attribute seen but we already have the session ID" +msgstr "" + +#: ../src/core/session.c:1198 ../src/core/session.c:1273 +#: ../src/core/session.c:1305 ../src/core/session.c:1377 +#: ../src/core/session.c:1437 +#, c-format +msgid "Unknown attribute %s on <%s> element" +msgstr "" + +#: ../src/core/session.c:1215 +#, c-format +msgid "nested <window> tag" +msgstr "" + +#: ../src/core/session.c:1457 +#, c-format +msgid "Unknown element %s" +msgstr "" + +#: ../src/core/session.c:1809 +msgid "" +"These windows do not support "save current setup" and will have to " +"be restarted manually next time you log in." +msgstr "" + +#: ../src/core/util.c:84 +#, c-format +msgid "Failed to open debug log: %s\n" +msgstr "" + +#: ../src/core/util.c:94 +#, c-format +msgid "Failed to fdopen() log file %s: %s\n" +msgstr "" + +#: ../src/core/util.c:100 +#, c-format +msgid "Opened log file %s\n" +msgstr "" + +#: ../src/core/util.c:119 ../src/tools/mutter-message.c:149 +#, c-format +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "" + +#: ../src/core/util.c:264 +msgid "Window manager: " +msgstr "" + +#: ../src/core/util.c:412 +msgid "Bug in window manager: " +msgstr "" + +#: ../src/core/util.c:443 +msgid "Window manager warning: " +msgstr "" + +#: ../src/core/util.c:471 +msgid "Window manager error: " +msgstr "" + +#. first time through +#: ../src/core/window.c:7596 +#, c-format +msgid "" +"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " +"window as specified in the ICCCM.\n" +msgstr "" + +#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the +#. * authoritative source for that info. Some apps such as mplayer or +#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that +#. * leads to e.g. us not fullscreening their windows. Apps that set +#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain +#. * about these apps but make them work. +#. +#: ../src/core/window.c:8320 +#, c-format +msgid "" +"Window %s sets an MWM hint indicating it isn't resizable, but sets min size " +"%d x %d and max size %d x %d; this doesn't make much sense.\n" +msgstr "" + +#: ../src/core/window-props.c:318 +#, c-format +msgid "Application set a bogus _NET_WM_PID %lu\n" +msgstr "" + +#: ../src/core/window-props.c:434 +#, c-format +msgid "%s (on %s)" +msgstr "%s (дар %s)" + +#: ../src/core/window-props.c:1517 +#, c-format +msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +msgstr "" + +#: ../src/core/window-props.c:1528 +#, c-format +msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" +msgstr "" + +#: ../src/core/xprops.c:155 +#, c-format +msgid "" +"Window 0x%lx has property %s\n" +"that was expected to have type %s format %d\n" +"and actually has type %s format %d n_items %d.\n" +"This is most likely an application bug, not a window manager bug.\n" +"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +msgstr "" + +#: ../src/core/xprops.c:411 +#, c-format +msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +msgstr "" + +#: ../src/core/xprops.c:494 +#, c-format +msgid "" +"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" +msgstr "" + +#: ../src/mutter.desktop.in.h:1 ../src/mutter-wm.desktop.in.h:1 +msgid "Mutter" +msgstr "" + +#: ../src/org.gnome.mutter.gschema.xml.in.h:1 +msgid "Modifier to use for extended window management operations" +msgstr "" + +#: ../src/org.gnome.mutter.gschema.xml.in.h:2 +msgid "" +"This key will initiate the \"overlay\", which is a combination window " +"overview and application launching system. The default is intended to be the " +"\"Windows key\" on PC hardware. It's expected that this binding either the " +"default or set to the empty string." +msgstr "" + +#: ../src/org.gnome.mutter.gschema.xml.in.h:3 +msgid "Attach modal dialogs" +msgstr "" + +#: ../src/org.gnome.mutter.gschema.xml.in.h:4 +msgid "" +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." +msgstr "" + +#: ../src/org.gnome.mutter.gschema.xml.in.h:5 +msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "" + +#: ../src/org.gnome.mutter.gschema.xml.in.h:6 +msgid "" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." +msgstr "" + +#: ../src/org.gnome.mutter.gschema.xml.in.h:7 +msgid "Workspaces are managed dynamically" +msgstr "" + +#: ../src/org.gnome.mutter.gschema.xml.in.h:8 +msgid "" +"Determines whether workspaces are managed dynamically or whether there's a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." +msgstr "" + +#: ../src/org.gnome.mutter.gschema.xml.in.h:9 +msgid "Workspaces only on primary" +msgstr "" + +#: ../src/org.gnome.mutter.gschema.xml.in.h:10 +msgid "" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." +msgstr "" + +#: ../src/org.gnome.mutter.gschema.xml.in.h:11 +msgid "No tab popup" +msgstr "" + +#: ../src/org.gnome.mutter.gschema.xml.in.h:12 +msgid "" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." +msgstr "" + +#: ../src/org.gnome.mutter.gschema.xml.in.h:13 +msgid "Delay focus changes until the pointer stops moving" +msgstr "" + +#: ../src/org.gnome.mutter.gschema.xml.in.h:14 +msgid "" +"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " +"the focus will not be changed immediately when entering a window, but only " +"after the pointer stops moving." +msgstr "" + +#: ../src/org.gnome.mutter.gschema.xml.in.h:15 +msgid "Draggable border width" +msgstr "" + +#: ../src/org.gnome.mutter.gschema.xml.in.h:16 +msgid "" +"The amount of total draggable borders. If the theme's visible borders are " +"not enough, invisible borders will be added to meet this value." +msgstr "" + +#: ../src/org.gnome.mutter.gschema.xml.in.h:17 +msgid "Auto maximize nearly monitor sized windows" +msgstr "" + +#: ../src/org.gnome.mutter.gschema.xml.in.h:18 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" + +#: ../src/org.gnome.mutter.gschema.xml.in.h:19 +msgid "Select window from tab popup" +msgstr "" + +#: ../src/org.gnome.mutter.gschema.xml.in.h:20 +msgid "Cancel tab popup" +msgstr "" + +#: ../src/tools/mutter-message.c:123 +#, c-format +msgid "Usage: %s\n" +msgstr "Истифодабарӣ: %s\n" + +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:69 +msgid "Mi_nimize" +msgstr "" + +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:71 +msgid "Ma_ximize" +msgstr "" + +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:73 +msgid "Unma_ximize" +msgstr "" + +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:75 +msgid "Roll _Up" +msgstr "" + +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:77 +msgid "_Unroll" +msgstr "" + +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:79 +msgid "_Move" +msgstr "_Интиқол додан" + +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:81 +msgid "_Resize" +msgstr "_Тағйир додани андоза" + +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:83 +msgid "Move Titlebar On_screen" +msgstr "" + +#. separator +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 +msgid "Always on _Top" +msgstr "" + +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:90 +msgid "_Always on Visible Workspace" +msgstr "" + +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:92 +msgid "_Only on This Workspace" +msgstr "" + +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:94 +msgid "Move to Workspace _Left" +msgstr "" + +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:96 +msgid "Move to Workspace R_ight" +msgstr "" + +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:98 +msgid "Move to Workspace _Up" +msgstr "" + +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:100 +msgid "Move to Workspace _Down" +msgstr "" + +#. separator +#. Translators: Translate this string the same way as you do in libwnck! +#: ../src/ui/menu.c:104 +msgid "_Close" +msgstr "_Пӯшидан" + +#: ../src/ui/menu.c:204 +#, c-format +msgid "Workspace %d%n" +msgstr "Фазои кории %d%n" + +#: ../src/ui/menu.c:214 +#, c-format +msgid "Workspace 1_0" +msgstr "Фазои кории 1_0" + +#: ../src/ui/menu.c:216 +#, c-format +msgid "Workspace %s%d" +msgstr "Фазои кории %s%d" + +#: ../src/ui/menu.c:397 +msgid "Move to Another _Workspace" +msgstr "" + +#. This is the text that should appear next to menu accelerators +#. * that use the shift key. If the text on this key isn't typically +#. * translated on keyboards used for your language, don't translate +#. * this. +#. +#: ../src/ui/metaaccellabel.c:77 +msgid "Shift" +msgstr "Shift" + +#. This is the text that should appear next to menu accelerators +#. * that use the control key. If the text on this key isn't typically +#. * translated on keyboards used for your language, don't translate +#. * this. +#. +#: ../src/ui/metaaccellabel.c:83 +msgid "Ctrl" +msgstr "Ctrl" + +#. This is the text that should appear next to menu accelerators +#. * that use the alt key. If the text on this key isn't typically +#. * translated on keyboards used for your language, don't translate +#. * this. +#. +#: ../src/ui/metaaccellabel.c:89 +msgid "Alt" +msgstr "Alt" + +#. This is the text that should appear next to menu accelerators +#. * that use the meta key. If the text on this key isn't typically +#. * translated on keyboards used for your language, don't translate +#. * this. +#. +#: ../src/ui/metaaccellabel.c:95 +msgid "Meta" +msgstr "Мета" + +#. This is the text that should appear next to menu accelerators +#. * that use the super key. If the text on this key isn't typically +#. * translated on keyboards used for your language, don't translate +#. * this. +#. +#: ../src/ui/metaaccellabel.c:101 +msgid "Super" +msgstr "Супер" + +#. This is the text that should appear next to menu accelerators +#. * that use the hyper key. If the text on this key isn't typically +#. * translated on keyboards used for your language, don't translate +#. * this. +#. +#: ../src/ui/metaaccellabel.c:107 +msgid "Hyper" +msgstr "" + +#. This is the text that should appear next to menu accelerators +#. * that use the mod2 key. If the text on this key isn't typically +#. * translated on keyboards used for your language, don't translate +#. * this. +#. +#: ../src/ui/metaaccellabel.c:113 +msgid "Mod2" +msgstr "" + +#. This is the text that should appear next to menu accelerators +#. * that use the mod3 key. If the text on this key isn't typically +#. * translated on keyboards used for your language, don't translate +#. * this. +#. +#: ../src/ui/metaaccellabel.c:119 +msgid "Mod3" +msgstr "" + +#. This is the text that should appear next to menu accelerators +#. * that use the mod4 key. If the text on this key isn't typically +#. * translated on keyboards used for your language, don't translate +#. * this. +#. +#: ../src/ui/metaaccellabel.c:125 +msgid "Mod4" +msgstr "" + +#. This is the text that should appear next to menu accelerators +#. * that use the mod5 key. If the text on this key isn't typically +#. * translated on keyboards used for your language, don't translate +#. * this. +#. +#: ../src/ui/metaaccellabel.c:131 +msgid "Mod5" +msgstr "" + +#. Translators: This represents the size of a window. The first number is +#. * the width of the window and the second is the height. +#. +#: ../src/ui/resizepopup.c:136 +#, c-format +msgid "%d x %d" +msgstr "" + +#: ../src/ui/theme.c:236 +msgid "top" +msgstr "боло" + +#: ../src/ui/theme.c:238 +msgid "bottom" +msgstr "поён" + +#: ../src/ui/theme.c:240 +msgid "left" +msgstr "чап" + +#: ../src/ui/theme.c:242 +msgid "right" +msgstr "рост" + +#: ../src/ui/theme.c:270 +#, c-format +msgid "frame geometry does not specify \"%s\" dimension" +msgstr "" + +#: ../src/ui/theme.c:289 +#, c-format +msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" +msgstr "" + +#: ../src/ui/theme.c:326 +#, c-format +msgid "Button aspect ratio %g is not reasonable" +msgstr "" + +#: ../src/ui/theme.c:338 +#, c-format +msgid "Frame geometry does not specify size of buttons" +msgstr "" + +#: ../src/ui/theme.c:1051 +#, c-format +msgid "Gradients should have at least two colors" +msgstr "" + +#: ../src/ui/theme.c:1203 +#, c-format +msgid "" +"GTK custom color specification must have color name and fallback in " +"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" +msgstr "" + +#: ../src/ui/theme.c:1219 +#, c-format +msgid "" +"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" +"_ are valid" +msgstr "" + +#: ../src/ui/theme.c:1233 +#, c-format +msgid "" +"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " +"fit the format" +msgstr "" + +#: ../src/ui/theme.c:1278 +#, c-format +msgid "" +"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " +"where NORMAL is the state; could not parse \"%s\"" +msgstr "" + +#: ../src/ui/theme.c:1292 +#, c-format +msgid "" +"GTK color specification must have a close bracket after the state, e.g. gtk:" +"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +msgstr "" + +#: ../src/ui/theme.c:1303 +#, c-format +msgid "Did not understand state \"%s\" in color specification" +msgstr "" + +#: ../src/ui/theme.c:1316 +#, c-format +msgid "Did not understand color component \"%s\" in color specification" +msgstr "" + +#: ../src/ui/theme.c:1345 +#, c-format +msgid "" +"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " +"format" +msgstr "" + +#: ../src/ui/theme.c:1356 +#, c-format +msgid "Could not parse alpha value \"%s\" in blended color" +msgstr "" + +#: ../src/ui/theme.c:1366 +#, c-format +msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" +msgstr "" + +#: ../src/ui/theme.c:1413 +#, c-format +msgid "" +"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" +msgstr "" + +#: ../src/ui/theme.c:1424 +#, c-format +msgid "Could not parse shade factor \"%s\" in shaded color" +msgstr "" + +#: ../src/ui/theme.c:1434 +#, c-format +msgid "Shade factor \"%s\" in shaded color is negative" +msgstr "" + +#: ../src/ui/theme.c:1463 +#, c-format +msgid "Could not parse color \"%s\"" +msgstr "" + +#: ../src/ui/theme.c:1780 +#, c-format +msgid "Coordinate expression contains character '%s' which is not allowed" +msgstr "" + +#: ../src/ui/theme.c:1807 +#, c-format +msgid "" +"Coordinate expression contains floating point number '%s' which could not be " +"parsed" +msgstr "" + +#: ../src/ui/theme.c:1821 +#, c-format +msgid "Coordinate expression contains integer '%s' which could not be parsed" +msgstr "" + +#: ../src/ui/theme.c:1942 +#, c-format +msgid "" +"Coordinate expression contained unknown operator at the start of this text: " +"\"%s\"" +msgstr "" + +#: ../src/ui/theme.c:1999 +#, c-format +msgid "Coordinate expression was empty or not understood" +msgstr "" + +#: ../src/ui/theme.c:2112 ../src/ui/theme.c:2122 ../src/ui/theme.c:2156 +#, c-format +msgid "Coordinate expression results in division by zero" +msgstr "" + +#: ../src/ui/theme.c:2164 +#, c-format +msgid "" +"Coordinate expression tries to use mod operator on a floating-point number" +msgstr "" + +#: ../src/ui/theme.c:2220 +#, c-format +msgid "" +"Coordinate expression has an operator \"%s\" where an operand was expected" +msgstr "" + +#: ../src/ui/theme.c:2229 +#, c-format +msgid "Coordinate expression had an operand where an operator was expected" +msgstr "" + +#: ../src/ui/theme.c:2237 +#, c-format +msgid "Coordinate expression ended with an operator instead of an operand" +msgstr "" + +#: ../src/ui/theme.c:2247 +#, c-format +msgid "" +"Coordinate expression has operator \"%c\" following operator \"%c\" with no " +"operand in between" +msgstr "" + +#: ../src/ui/theme.c:2398 ../src/ui/theme.c:2443 +#, c-format +msgid "Coordinate expression had unknown variable or constant \"%s\"" +msgstr "" + +#: ../src/ui/theme.c:2497 +#, c-format +msgid "Coordinate expression parser overflowed its buffer." +msgstr "" + +#: ../src/ui/theme.c:2526 +#, c-format +msgid "Coordinate expression had a close parenthesis with no open parenthesis" +msgstr "" + +#: ../src/ui/theme.c:2590 +#, c-format +msgid "Coordinate expression had an open parenthesis with no close parenthesis" +msgstr "" + +#: ../src/ui/theme.c:2601 +#, c-format +msgid "Coordinate expression doesn't seem to have any operators or operands" +msgstr "" + +#: ../src/ui/theme.c:2814 ../src/ui/theme.c:2834 ../src/ui/theme.c:2854 +#, c-format +msgid "Theme contained an expression that resulted in an error: %s\n" +msgstr "" + +#: ../src/ui/theme.c:4500 +#, c-format +msgid "" +"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " +"specified for this frame style" +msgstr "" + +#: ../src/ui/theme.c:5011 ../src/ui/theme.c:5036 +#, c-format +msgid "" +"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" +msgstr "" + +#: ../src/ui/theme.c:5084 +#, c-format +msgid "Failed to load theme \"%s\": %s\n" +msgstr "" + +#: ../src/ui/theme.c:5220 ../src/ui/theme.c:5227 ../src/ui/theme.c:5234 +#: ../src/ui/theme.c:5241 ../src/ui/theme.c:5248 +#, c-format +msgid "No <%s> set for theme \"%s\"" +msgstr "" + +#: ../src/ui/theme.c:5256 +#, c-format +msgid "" +"No frame style set for window type \"%s\" in theme \"%s\", add a <window " +"type=\"%s\" style_set=\"whatever\"/> element" +msgstr "" + +#: ../src/ui/theme.c:5663 ../src/ui/theme.c:5725 ../src/ui/theme.c:5788 +#, c-format +msgid "" +"User-defined constants must begin with a capital letter; \"%s\" does not" +msgstr "" + +#: ../src/ui/theme.c:5671 ../src/ui/theme.c:5733 ../src/ui/theme.c:5796 +#, c-format +msgid "Constant \"%s\" has already been defined" +msgstr "" + +#. Translators: This means that an attribute which should have been found +#. * on an XML element was not in fact found. +#. +#: ../src/ui/theme-parser.c:236 +#, c-format +msgid "No \"%s\" attribute on element <%s>" +msgstr "" + +#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 +#, c-format +msgid "Line %d character %d: %s" +msgstr "" + +#: ../src/ui/theme-parser.c:479 +#, c-format +msgid "Attribute \"%s\" repeated twice on the same <%s> element" +msgstr "" + +#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 +#, c-format +msgid "Attribute \"%s\" is invalid on <%s> element in this context" +msgstr "" + +#: ../src/ui/theme-parser.c:594 +#, c-format +msgid "Could not parse \"%s\" as an integer" +msgstr "" + +#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 +#, c-format +msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +msgstr "" + +#: ../src/ui/theme-parser.c:613 +#, c-format +msgid "Integer %ld must be positive" +msgstr "" + +#: ../src/ui/theme-parser.c:621 +#, c-format +msgid "Integer %ld is too large, current max is %d" +msgstr "" + +#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 +#, c-format +msgid "Could not parse \"%s\" as a floating point number" +msgstr "" + +#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 +#, c-format +msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" +msgstr "" + +#: ../src/ui/theme-parser.c:735 +#, c-format +msgid "Angle must be between 0.0 and 360.0, was %g\n" +msgstr "" + +#: ../src/ui/theme-parser.c:798 +#, c-format +msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" +msgstr "" + +#: ../src/ui/theme-parser.c:863 +#, c-format +msgid "" +"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," +"large,x-large,xx-large)\n" +msgstr "" + +#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 +#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 +#, c-format +msgid "<%s> name \"%s\" used a second time" +msgstr "" + +#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 +#: ../src/ui/theme-parser.c:1231 +#, c-format +msgid "<%s> parent \"%s\" has not been defined" +msgstr "" + +#: ../src/ui/theme-parser.c:1141 +#, c-format +msgid "<%s> geometry \"%s\" has not been defined" +msgstr "" + +#: ../src/ui/theme-parser.c:1154 +#, c-format +msgid "<%s> must specify either a geometry or a parent that has a geometry" +msgstr "" + +#: ../src/ui/theme-parser.c:1196 +msgid "You must specify a background for an alpha value to be meaningful" +msgstr "" + +#: ../src/ui/theme-parser.c:1264 +#, c-format +msgid "Unknown type \"%s\" on <%s> element" +msgstr "" + +#: ../src/ui/theme-parser.c:1275 +#, c-format +msgid "Unknown style_set \"%s\" on <%s> element" +msgstr "" + +#: ../src/ui/theme-parser.c:1283 +#, c-format +msgid "Window type \"%s\" has already been assigned a style set" +msgstr "" + +#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 +#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 +#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 +#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 +#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 +#, c-format +msgid "Element <%s> is not allowed below <%s>" +msgstr "" + +#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 +#: ../src/ui/theme-parser.c:1486 +msgid "" +"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " +"for buttons" +msgstr "" + +#: ../src/ui/theme-parser.c:1450 +#, c-format +msgid "Distance \"%s\" is unknown" +msgstr "" + +#: ../src/ui/theme-parser.c:1495 +#, c-format +msgid "Aspect ratio \"%s\" is unknown" +msgstr "" + +#: ../src/ui/theme-parser.c:1557 +#, c-format +msgid "Border \"%s\" is unknown" +msgstr "" + +#: ../src/ui/theme-parser.c:1868 +#, c-format +msgid "No \"start_angle\" or \"from\" attribute on element <%s>" +msgstr "" + +#: ../src/ui/theme-parser.c:1875 +#, c-format +msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" +msgstr "" + +#: ../src/ui/theme-parser.c:2115 +#, c-format +msgid "Did not understand value \"%s\" for type of gradient" +msgstr "" + +#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 +#, c-format +msgid "Did not understand fill type \"%s\" for <%s> element" +msgstr "" + +#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 +#: ../src/ui/theme-parser.c:2506 +#, c-format +msgid "Did not understand state \"%s\" for <%s> element" +msgstr "" + +#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 +#, c-format +msgid "Did not understand shadow \"%s\" for <%s> element" +msgstr "" + +#: ../src/ui/theme-parser.c:2380 +#, c-format +msgid "Did not understand arrow \"%s\" for <%s> element" +msgstr "" + +#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 +#, c-format +msgid "No <draw_ops> called \"%s\" has been defined" +msgstr "" + +#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 +#, c-format +msgid "Including draw_ops \"%s\" here would create a circular reference" +msgstr "" + +#: ../src/ui/theme-parser.c:2917 +#, c-format +msgid "Unknown position \"%s\" for frame piece" +msgstr "" + +#: ../src/ui/theme-parser.c:2925 +#, c-format +msgid "Frame style already has a piece at position %s" +msgstr "" + +#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 +#, c-format +msgid "No <draw_ops> with the name \"%s\" has been defined" +msgstr "" + +#: ../src/ui/theme-parser.c:2972 +#, c-format +msgid "Unknown function \"%s\" for button" +msgstr "" + +#: ../src/ui/theme-parser.c:2982 +#, c-format +msgid "Button function \"%s\" does not exist in this version (%d, need %d)" +msgstr "" + +#: ../src/ui/theme-parser.c:2994 +#, c-format +msgid "Unknown state \"%s\" for button" +msgstr "" + +#: ../src/ui/theme-parser.c:3002 +#, c-format +msgid "Frame style already has a button for function %s state %s" +msgstr "" + +#: ../src/ui/theme-parser.c:3073 +#, c-format +msgid "\"%s\" is not a valid value for focus attribute" +msgstr "" + +#: ../src/ui/theme-parser.c:3082 +#, c-format +msgid "\"%s\" is not a valid value for state attribute" +msgstr "" + +#: ../src/ui/theme-parser.c:3092 +#, c-format +msgid "A style called \"%s\" has not been defined" +msgstr "" + +#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 +#, c-format +msgid "\"%s\" is not a valid value for resize attribute" +msgstr "" + +#: ../src/ui/theme-parser.c:3147 +#, c-format +msgid "" +"Should not have \"resize\" attribute on <%s> element for maximized/shaded " +"states" +msgstr "" + +#: ../src/ui/theme-parser.c:3161 +#, c-format +msgid "" +"Should not have \"resize\" attribute on <%s> element for maximized states" +msgstr "" + +#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 +#, c-format +msgid "Style has already been specified for state %s resize %s focus %s" +msgstr "" + +#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 +#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 +#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 +#, c-format +msgid "Style has already been specified for state %s focus %s" +msgstr "" + +#: ../src/ui/theme-parser.c:3294 +msgid "" +"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " +"attribute and also a <draw_ops> element, or specified two elements)" +msgstr "" + +#: ../src/ui/theme-parser.c:3332 +msgid "" +"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " +"attribute and also a <draw_ops> element, or specified two elements)" +msgstr "" + +#: ../src/ui/theme-parser.c:3370 +msgid "" +"Can't have a two draw_ops for a <menu_icon> element (theme specified a " +"draw_ops attribute and also a <draw_ops> element, or specified two elements)" +msgstr "" + +#: ../src/ui/theme-parser.c:3434 +#, c-format +msgid "Bad version specification '%s'" +msgstr "" + +#: ../src/ui/theme-parser.c:3507 +msgid "" +"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" +"theme-2.xml" +msgstr "" + +#: ../src/ui/theme-parser.c:3530 +#, c-format +msgid "Theme requires version %s but latest supported theme version is %d.%d" +msgstr "" + +#: ../src/ui/theme-parser.c:3562 +#, c-format +msgid "Outermost element in theme must be <metacity_theme> not <%s>" +msgstr "" + +#: ../src/ui/theme-parser.c:3582 +#, c-format +msgid "" +"Element <%s> is not allowed inside a name/author/date/description element" +msgstr "" + +#: ../src/ui/theme-parser.c:3587 +#, c-format +msgid "Element <%s> is not allowed inside a <constant> element" +msgstr "" + +#: ../src/ui/theme-parser.c:3599 +#, c-format +msgid "" +"Element <%s> is not allowed inside a distance/border/aspect_ratio element" +msgstr "" + +#: ../src/ui/theme-parser.c:3621 +#, c-format +msgid "Element <%s> is not allowed inside a draw operation element" +msgstr "" + +#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 +#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 +#, c-format +msgid "Element <%s> is not allowed inside a <%s> element" +msgstr "" + +#: ../src/ui/theme-parser.c:3899 +msgid "No draw_ops provided for frame piece" +msgstr "" + +#: ../src/ui/theme-parser.c:3914 +msgid "No draw_ops provided for button" +msgstr "" + +#: ../src/ui/theme-parser.c:3968 +#, c-format +msgid "No text is allowed inside element <%s>" +msgstr "" + +#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 +#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 +#: ../src/ui/theme-parser.c:4074 +#, c-format +msgid "<%s> specified twice for this theme" +msgstr "" + +#: ../src/ui/theme-parser.c:4336 +#, c-format +msgid "Failed to find a valid file for theme %s\n" +msgstr "" + +#: ../src/ui/theme-viewer.c:99 +msgid "_Windows" +msgstr "_Равзанаҳо" + +#: ../src/ui/theme-viewer.c:100 +msgid "_Dialog" +msgstr "_Равзанаи гуфтугӯ" + +#: ../src/ui/theme-viewer.c:101 +msgid "_Modal dialog" +msgstr "" + +#: ../src/ui/theme-viewer.c:102 +msgid "_Utility" +msgstr "" + +#: ../src/ui/theme-viewer.c:103 +msgid "_Splashscreen" +msgstr "" + +#: ../src/ui/theme-viewer.c:104 +msgid "_Top dock" +msgstr "" + +#: ../src/ui/theme-viewer.c:105 +msgid "_Bottom dock" +msgstr "" + +#: ../src/ui/theme-viewer.c:106 +msgid "_Left dock" +msgstr "" + +#: ../src/ui/theme-viewer.c:107 +msgid "_Right dock" +msgstr "" + +#: ../src/ui/theme-viewer.c:108 +msgid "_All docks" +msgstr "" + +#: ../src/ui/theme-viewer.c:109 +msgid "Des_ktop" +msgstr "Мизи _корӣ" + +#: ../src/ui/theme-viewer.c:115 +msgid "Open another one of these windows" +msgstr "" + +#: ../src/ui/theme-viewer.c:117 +msgid "This is a demo button with an 'open' icon" +msgstr "" + +#: ../src/ui/theme-viewer.c:119 +msgid "This is a demo button with a 'quit' icon" +msgstr "" + +#: ../src/ui/theme-viewer.c:248 +msgid "This is a sample message in a sample dialog" +msgstr "" + +#: ../src/ui/theme-viewer.c:328 +#, c-format +msgid "Fake menu item %d\n" +msgstr "" + +#: ../src/ui/theme-viewer.c:363 +msgid "Border-only window" +msgstr "" + +#: ../src/ui/theme-viewer.c:365 +msgid "Bar" +msgstr "Навор" + +#: ../src/ui/theme-viewer.c:382 +msgid "Normal Application Window" +msgstr "" + +#: ../src/ui/theme-viewer.c:386 +msgid "Dialog Box" +msgstr "" + +#: ../src/ui/theme-viewer.c:390 +msgid "Modal Dialog Box" +msgstr "" + +#: ../src/ui/theme-viewer.c:394 +msgid "Utility Palette" +msgstr "" + +#: ../src/ui/theme-viewer.c:398 +msgid "Torn-off Menu" +msgstr "" + +#: ../src/ui/theme-viewer.c:402 +msgid "Border" +msgstr "Марз" + +#: ../src/ui/theme-viewer.c:406 +msgid "Attached Modal Dialog" +msgstr "" + +#: ../src/ui/theme-viewer.c:737 +#, c-format +msgid "Button layout test %d" +msgstr "" + +#: ../src/ui/theme-viewer.c:766 +#, c-format +msgid "%g milliseconds to draw one window frame" +msgstr "" + +#: ../src/ui/theme-viewer.c:811 +#, c-format +msgid "Usage: metacity-theme-viewer [THEMENAME]\n" +msgstr "" + +#: ../src/ui/theme-viewer.c:818 +#, c-format +msgid "Error loading theme: %s\n" +msgstr "" + +#: ../src/ui/theme-viewer.c:824 +#, c-format +msgid "Loaded theme \"%s\" in %g seconds\n" +msgstr "" + +#: ../src/ui/theme-viewer.c:869 +msgid "Normal Title Font" +msgstr "" + +#: ../src/ui/theme-viewer.c:875 +msgid "Small Title Font" +msgstr "" + +#: ../src/ui/theme-viewer.c:881 +msgid "Large Title Font" +msgstr "" + +#: ../src/ui/theme-viewer.c:886 +msgid "Button Layouts" +msgstr "" + +#: ../src/ui/theme-viewer.c:891 +msgid "Benchmark" +msgstr "" + +#: ../src/ui/theme-viewer.c:947 +msgid "Window Title Goes Here" +msgstr "" + +#: ../src/ui/theme-viewer.c:1053 +#, c-format +msgid "" +"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " +"seconds wall clock time including X server resources (%g milliseconds per " +"frame)\n" +msgstr "" + +#: ../src/ui/theme-viewer.c:1273 +msgid "position expression test returned TRUE but set error" +msgstr "" + +#: ../src/ui/theme-viewer.c:1275 +msgid "position expression test returned FALSE but didn't set error" +msgstr "" + +#: ../src/ui/theme-viewer.c:1279 +msgid "Error was expected but none given" +msgstr "" + +#: ../src/ui/theme-viewer.c:1281 +#, c-format +msgid "Error %d was expected but %d given" +msgstr "" + +#: ../src/ui/theme-viewer.c:1287 +#, c-format +msgid "Error not expected but one was returned: %s" +msgstr "" + +#: ../src/ui/theme-viewer.c:1291 +#, c-format +msgid "x value was %d, %d was expected" +msgstr "" + +#: ../src/ui/theme-viewer.c:1294 +#, c-format +msgid "y value was %d, %d was expected" +msgstr "" + +#: ../src/ui/theme-viewer.c:1359 +#, c-format +msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" +msgstr "" diff --git a/po/th.po b/po/th.po index e09a111a8..aefdbe162 100644 --- a/po/th.po +++ b/po/th.po @@ -1,649 +1,592 @@ -# Thai translation for muffin. -# Copyright (C) 2003-2011 Free Software Foundation, Inc. -# This file is distributed under the same license as the muffin package. +# Thai translation for mutter. +# Copyright (C) 2003-2016 Free Software Foundation, Inc. +# This file is distributed under the same license as the mutter package. # # Phakhinee Thangnithirat <sc442535@angsila.compsci.buu.ac.th>, 2003 # Chanchai Junlouchai <taz@opentle.org>, 2003 # Paisa Seeluangsawat <paisa@users.sf.net>, 2004. -# Theppitak Karoonboonyanan <thep@linux.thai.net>, 2004-2011. +# Theppitak Karoonboonyanan <theppitak@gmail.com>, 2004-2012, 2016. +# Akom Chotiphantawanon <knight2000@gmail.com>, 2015. # msgid "" msgstr "" -"Project-Id-Version: muffin\n" +"Project-Id-Version: mutter\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" -"product=muffin&keywords=I18N+L10N&component=general\n" -"POT-Creation-Date: 2011-08-10 12:42+0000\n" -"PO-Revision-Date: 2011-08-14 21:02+0700\n" -"Last-Translator: Theppitak Karoonboonyanan <thep@linux.thai.net>\n" +"product=mutter&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2015-07-18 22:50+0000\n" +"PO-Revision-Date: 2016-10-13 11:22+0700\n" +"Last-Translator: Theppitak Karoonboonyanan <theppitak@gmail.com>\n" "Language-Team: Thai <thai-l10n@googlegroups.com>\n" +"Language: th\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Gtranslator 2.91.6\n" -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:487 -#, c-format -msgid "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." -msgstr "มีโปรแกรมจัดการ composite ทำงานอยู่แล้วที่สกรีน %i ดิสเพลย์ \"%s\"" +#: ../data/50-mutter-navigation.xml.in.h:1 +msgid "Navigation" +msgstr "ท่องย้าย" -#: ../src/core/all-keybindings.h:88 -msgid "Switch to workspace 1" -msgstr "สลับไปพื้นที่ทำงาน 1" +#: ../data/50-mutter-navigation.xml.in.h:2 +msgid "Move window to workspace 1" +msgstr "ย้ายหน้าต่างไปพื้นที่ทำงาน 1" -#: ../src/core/all-keybindings.h:90 -msgid "Switch to workspace 2" -msgstr "สลับไปพื้นที่ทำงาน 2" +#: ../data/50-mutter-navigation.xml.in.h:3 +msgid "Move window to workspace 2" +msgstr "ย้ายหน้าต่างไปพื้นที่ทำงาน 2" -#: ../src/core/all-keybindings.h:92 -msgid "Switch to workspace 3" -msgstr "สลับไปพื้นที่ทำงาน 3" +#: ../data/50-mutter-navigation.xml.in.h:4 +msgid "Move window to workspace 3" +msgstr "ย้ายหน้าต่างไปพื้นที่ทำงาน 3" -#: ../src/core/all-keybindings.h:94 -msgid "Switch to workspace 4" -msgstr "สลับไปพื้นที่ทำงาน 4" +#: ../data/50-mutter-navigation.xml.in.h:5 +msgid "Move window to workspace 4" +msgstr "ย้ายหน้าต่างไปพื้นที่ทำงาน 4" + +#: ../data/50-mutter-navigation.xml.in.h:6 +msgid "Move window to last workspace" +msgstr "ย้ายหน้าต่างไปพื้นที่ทำงานสุดท้าย" + +#: ../data/50-mutter-navigation.xml.in.h:7 +msgid "Move window one workspace to the left" +msgstr "ย้ายหน้าต่างไปพื้นที่ทำงานด้านซ้าย" + +#: ../data/50-mutter-navigation.xml.in.h:8 +msgid "Move window one workspace to the right" +msgstr "ย้ายหน้าต่างไปพื้นที่ทำงานด้านขวา" + +#: ../data/50-mutter-navigation.xml.in.h:9 +msgid "Move window one workspace up" +msgstr "ย้ายหน้าต่างไปพื้นที่ทำงานด้านบน" + +#: ../data/50-mutter-navigation.xml.in.h:10 +msgid "Move window one workspace down" +msgstr "ย้ายหน้าต่างไปพื้นที่ทำงานด้านล่าง" -#: ../src/core/all-keybindings.h:96 -msgid "Switch to workspace 5" -msgstr "สลับไปพื้นที่ทำงาน 5" +#: ../data/50-mutter-navigation.xml.in.h:11 +msgid "Move window one monitor to the left" +msgstr "ย้ายหน้าต่างไปจอภาพด้านซ้าย" -#: ../src/core/all-keybindings.h:98 -msgid "Switch to workspace 6" -msgstr "สลับไปพื้นที่ทำงาน 6" +#: ../data/50-mutter-navigation.xml.in.h:12 +msgid "Move window one monitor to the right" +msgstr "ย้ายหน้าต่างไปจอภาพด้านขวา" -#: ../src/core/all-keybindings.h:100 -msgid "Switch to workspace 7" -msgstr "สลับไปพื้นที่ทำงาน 7" +#: ../data/50-mutter-navigation.xml.in.h:13 +msgid "Move window one monitor up" +msgstr "ย้ายหน้าต่างไปจอภาพด้านบน" -#: ../src/core/all-keybindings.h:102 -msgid "Switch to workspace 8" -msgstr "สลับไปพื้นที่ทำงาน 8" +#: ../data/50-mutter-navigation.xml.in.h:14 +msgid "Move window one monitor down" +msgstr "ย้ายหน้าต่างไปจอภาพด้านล่าง" -#: ../src/core/all-keybindings.h:104 -msgid "Switch to workspace 9" -msgstr "สลับไปพื้นที่ทำงาน 9" +#: ../data/50-mutter-navigation.xml.in.h:15 +msgid "Switch applications" +msgstr "สลับโปรแกรม" -#: ../src/core/all-keybindings.h:106 -msgid "Switch to workspace 10" -msgstr "สลับไปพื้นที่ทำงาน 10" +#: ../data/50-mutter-navigation.xml.in.h:16 +msgid "Switch to previous application" +msgstr "สลับไปโปรแกรมก่อนหน้า" -#: ../src/core/all-keybindings.h:108 -msgid "Switch to workspace 11" -msgstr "สลับไปพื้นที่ทำงาน 11" +#: ../data/50-mutter-navigation.xml.in.h:17 +msgid "Switch windows" +msgstr "สลับหน้าต่าง" -#: ../src/core/all-keybindings.h:110 -msgid "Switch to workspace 12" -msgstr "สลับไปพื้นที่ทำงาน 12" +#: ../data/50-mutter-navigation.xml.in.h:18 +msgid "Switch to previous window" +msgstr "สลับไปหน้าต่างก่อนหน้า" -#: ../src/core/all-keybindings.h:122 -msgid "Switch to workspace on the left of the current workspace" -msgstr "สลับไปพื้นที่ทำงานด้านซ้ายของพื้นที่ทำงานปัจจุบัน" +#: ../data/50-mutter-navigation.xml.in.h:19 +msgid "Switch windows of an application" +msgstr "สลับหน้าต่างภายในโปรแกรม" -#: ../src/core/all-keybindings.h:126 -msgid "Switch to workspace on the right of the current workspace" -msgstr "สลับไปพื้นที่ทำงานด้านขวาของพื้นที่ทำงานปัจจุบัน" +#: ../data/50-mutter-navigation.xml.in.h:20 +msgid "Switch to previous window of an application" +msgstr "สลับไปหน้าต่างก่อนหน้าภายในโปรแกรม" -#: ../src/core/all-keybindings.h:130 -msgid "Switch to workspace above the current workspace" -msgstr "สลับไปพื้นที่ทำงานด้านบนของพื้นที่ทำงานปัจจุบัน" +#: ../data/50-mutter-navigation.xml.in.h:21 +msgid "Switch system controls" +msgstr "สลับส่วนควบคุมระบบ" -#: ../src/core/all-keybindings.h:134 -msgid "Switch to workspace below the current workspace" -msgstr "สลับไปพื้นที่ทำงานด้านล่างของพื้นที่ทำงานปัจจุบัน" +#: ../data/50-mutter-navigation.xml.in.h:22 +msgid "Switch to previous system control" +msgstr "สลับไปส่วนควบคุมระบบก่อนหน้า" -#: ../src/core/all-keybindings.h:150 -msgid "Move between windows of an application, using a popup window" -msgstr "ย้ายโฟกัสระหว่างหน้าต่างทั้งหลายของโปรแกรมประยุกต์โดยใช้หน้าต่างผุดขึ้น" +#: ../data/50-mutter-navigation.xml.in.h:23 +msgid "Switch windows directly" +msgstr "สลับหน้าต่างโดยตรง" -#: ../src/core/all-keybindings.h:153 -msgid "Move backward between windows of an application, using a popup window" -msgstr "ย้ายโฟกัสย้อนหลังระหว่างหน้าต่างทั้งหลายของโปรแกรมประยุกต์โดยใช้หน้าต่างผุดขึ้น" +#: ../data/50-mutter-navigation.xml.in.h:24 +msgid "Switch directly to previous window" +msgstr "สลับโดยตรงไปหน้าต่างก่อนหน้า" -#: ../src/core/all-keybindings.h:157 -msgid "Move between windows, using a popup window" -msgstr "ย้ายโฟกัสระหว่างหน้าต่างโดยใช้หน้าต่างผุดขึ้น" +#: ../data/50-mutter-navigation.xml.in.h:25 +msgid "Switch windows of an app directly" +msgstr "สลับหน้าต่างภายในโปรแกรมโดยตรง" -#: ../src/core/all-keybindings.h:160 -msgid "Move backward between windows, using a popup window" -msgstr "ย้ายโฟกัสย้อนหลังระหว่างหน้าต่างโดยใช้หน้าต่างผุดขึ้น" +#: ../data/50-mutter-navigation.xml.in.h:26 +msgid "Switch directly to previous window of an app" +msgstr "สลับโดยตรงไปหน้าต่างก่อนหน้าภายในโปรแกรม" -#: ../src/core/all-keybindings.h:163 -msgid "Move between panels and the desktop, using a popup window" -msgstr "ย้ายโฟกัสระหว่างพาเนลและพื้นโต๊ะโดยใช้หน้าต่างผุดขึ้น" +#: ../data/50-mutter-navigation.xml.in.h:27 +msgid "Switch system controls directly" +msgstr "สลับส่วนควบคุมระบบโดยตรง" -#: ../src/core/all-keybindings.h:166 -msgid "Move backward between panels and the desktop, using a popup window" -msgstr "ย้ายโฟกัสย้อนหลังระหว่างพาเนลและพื้นโต๊ะโดยใช้หน้าต่างผุดขึ้น" +#: ../data/50-mutter-navigation.xml.in.h:28 +msgid "Switch directly to previous system control" +msgstr "สลับโดยตรงไปส่วนควบคุมระบบก่อนหน้า" -#: ../src/core/all-keybindings.h:171 -msgid "Move between windows of an application immediately" -msgstr "ย้ายโฟกัสระหว่างหน้าต่างทั้งหลายของโปรแกรมประยุกต์โดยทันที" +#: ../data/50-mutter-navigation.xml.in.h:29 +msgid "Hide all normal windows" +msgstr "ซ่อนหน้าต่างทั้งหมด" -#: ../src/core/all-keybindings.h:174 -msgid "Move backward between windows of an application immediately" -msgstr "ย้ายโฟกัสย้อนหลังระหว่างหน้าต่างทั้งหลายของโปรแกรมประยุกต์โดยทันที" +#: ../data/50-mutter-navigation.xml.in.h:30 +msgid "Switch to workspace 1" +msgstr "สลับไปพื้นที่ทำงาน 1" + +#: ../data/50-mutter-navigation.xml.in.h:31 +msgid "Switch to workspace 2" +msgstr "สลับไปพื้นที่ทำงาน 2" -#: ../src/core/all-keybindings.h:177 -msgid "Move between windows immediately" -msgstr "ย้ายโฟกัสระหว่างหน้าต่างโดยทันที" +#: ../data/50-mutter-navigation.xml.in.h:32 +msgid "Switch to workspace 3" +msgstr "สลับไปพื้นที่ทำงาน 3" -#: ../src/core/all-keybindings.h:180 -msgid "Move backward between windows immediately" -msgstr "ย้ายโฟกัสย้อนหลังระหว่างหน้าต่างโดยทันที" +#: ../data/50-mutter-navigation.xml.in.h:33 +msgid "Switch to workspace 4" +msgstr "สลับไปพื้นที่ทำงาน 4" -#: ../src/core/all-keybindings.h:183 -msgid "Move between panels and the desktop immediately" -msgstr "ย้ายโฟกัสระหว่างพาเนลและพื้นโต๊ะโดยทันที" +#: ../data/50-mutter-navigation.xml.in.h:34 +msgid "Switch to last workspace" +msgstr "สลับไปพื้นที่ทำงานสุดท้าย" -#: ../src/core/all-keybindings.h:186 -msgid "Move backward between panels and the desktop immediately" -msgstr "ย้ายโฟกัสย้อนหลังระหว่างพาเนลและพื้นโต๊ะโดยทันที" +#: ../data/50-mutter-navigation.xml.in.h:35 +msgid "Move to workspace left" +msgstr "ย้ายไปพื้นที่ทำงานซ้าย" -#: ../src/core/all-keybindings.h:203 -msgid "Hide all normal windows and set focus to the desktop" -msgstr "ซ่อนหน้าต่างทั้งหมดแล้วโฟกัสไปยังพื้นโต๊ะ" +#: ../data/50-mutter-navigation.xml.in.h:36 +msgid "Move to workspace right" +msgstr "ย้ายไปพื้นที่ทำงานขวา" -#: ../src/core/all-keybindings.h:206 -msgid "Show the panel's main menu" -msgstr "แสดงเมนูหลักของพาเนล" +#: ../data/50-mutter-navigation.xml.in.h:37 +msgid "Move to workspace above" +msgstr "ย้ายไปพื้นที่ทำงานบน" -# Can omit the word panel without losing the core meaning. -#: ../src/core/all-keybindings.h:209 -msgid "Show the panel's \"Run Application\" dialog box" -msgstr "เปิดกล่องโต้ตอบ \"เรียกโปรแกรม\"" +#: ../data/50-mutter-navigation.xml.in.h:38 +msgid "Move to workspace below" +msgstr "ย้ายไปพื้นที่ทำงานล่าง" -#: ../src/core/all-keybindings.h:211 -msgid "Start or stop recording the session" -msgstr "เริ่มหรือหยุดการอัดบันทึกวาระ" +#: ../data/50-mutter-system.xml.in.h:1 +msgid "System" +msgstr "ระบบ" -#: ../src/core/all-keybindings.h:252 -msgid "Take a screenshot" -msgstr "จับภาพหน้าจอ" +#: ../data/50-mutter-system.xml.in.h:2 +msgid "Show the run command prompt" +msgstr "แสดงกล่องเรียกคำสั่ง" -#: ../src/core/all-keybindings.h:254 -msgid "Take a screenshot of a window" -msgstr "จับภาพหน้าต่าง" +#: ../data/50-mutter-system.xml.in.h:3 +msgid "Show the activities overview" +msgstr "แสดงภาพรวมของกิจกรรมต่างๆ" -#: ../src/core/all-keybindings.h:256 -msgid "Run a terminal" -msgstr "เปิดเทอร์มินัล" +#: ../data/50-mutter-windows.xml.in.h:1 +msgid "Windows" +msgstr "หน้าต่าง" -#: ../src/core/all-keybindings.h:271 +#: ../data/50-mutter-windows.xml.in.h:2 msgid "Activate the window menu" msgstr "เปิดเมนูหน้าต่าง" -#: ../src/core/all-keybindings.h:274 +#: ../data/50-mutter-windows.xml.in.h:3 msgid "Toggle fullscreen mode" msgstr "สลับโหมดเต็มหน้าจอ" -#: ../src/core/all-keybindings.h:276 +#: ../data/50-mutter-windows.xml.in.h:4 msgid "Toggle maximization state" msgstr "สลับสถานะขยายแผ่" -#: ../src/core/all-keybindings.h:278 -msgid "Toggle whether a window will always be visible over other windows" -msgstr "สลับสถานะหน้าต่าง ว่าค้างอยู่บนสุดเหนือหน้าต่างอื่นหรือไม่" - -#: ../src/core/all-keybindings.h:280 +#: ../data/50-mutter-windows.xml.in.h:5 msgid "Maximize window" msgstr "ขยายแผ่หน้าต่างเต็มพื้นโต๊ะ" -#: ../src/core/all-keybindings.h:282 +#: ../data/50-mutter-windows.xml.in.h:6 msgid "Restore window" msgstr "คืนขนาดหน้าต่าง" -#: ../src/core/all-keybindings.h:284 +#: ../data/50-mutter-windows.xml.in.h:7 msgid "Toggle shaded state" msgstr "ม้วน/คลี่หน้าต่าง" -#: ../src/core/all-keybindings.h:286 -msgid "Minimize window" -msgstr "ย่อเก็บหน้าต่าง" - -#: ../src/core/all-keybindings.h:288 +#: ../data/50-mutter-windows.xml.in.h:8 msgid "Close window" msgstr "ปิดหน้าต่าง" -#: ../src/core/all-keybindings.h:290 +#: ../data/50-mutter-windows.xml.in.h:9 +msgid "Hide window" +msgstr "ซ่อนหน้าต่าง" + +#: ../data/50-mutter-windows.xml.in.h:10 msgid "Move window" msgstr "ย้ายหน้าต่าง" -#: ../src/core/all-keybindings.h:292 +#: ../data/50-mutter-windows.xml.in.h:11 msgid "Resize window" msgstr "ปรับขนาดหน้าต่าง" -#: ../src/core/all-keybindings.h:295 -msgid "Toggle whether window is on all workspaces or just one" -msgstr "สลับสถานะหน้าต่าง ว่าแสดงบนทุกพื้นที่ทำงาน หรือแค่พื้นที่ทำงานเดียว" +#: ../data/50-mutter-windows.xml.in.h:12 +msgid "Toggle window on all workspaces or one" +msgstr "สลับการแสดงหน้าต่างบนทุกพื้นที่ทำงานกับบนพื้นที่เดียว" -#: ../src/core/all-keybindings.h:299 -msgid "Move window to workspace 1" -msgstr "ย้ายหน้าต่างไปพื้นที่ทำงาน 1" +#: ../data/50-mutter-windows.xml.in.h:13 +msgid "Raise window if covered, otherwise lower it" +msgstr "ยกหน้าต่างขึ้นถ้าถูกบัง มิฉะนั้นก็เอาลงด้านหลัง" -#: ../src/core/all-keybindings.h:302 -msgid "Move window to workspace 2" -msgstr "ย้ายหน้าต่างไปพื้นที่ทำงาน 2" +#: ../data/50-mutter-windows.xml.in.h:14 +msgid "Raise window above other windows" +msgstr "ยกหน้าต่างขึ้นมาไว้หน้าหน้าต่างอื่นๆ" -#: ../src/core/all-keybindings.h:305 -msgid "Move window to workspace 3" -msgstr "ย้ายหน้าต่างไปพื้นที่ทำงาน 3" +#: ../data/50-mutter-windows.xml.in.h:15 +msgid "Lower window below other windows" +msgstr "ถอยหน้าต่างลงไปใว้หลังหน้าต่างอื่น" -#: ../src/core/all-keybindings.h:308 -msgid "Move window to workspace 4" -msgstr "ย้ายหน้าต่างไปพื้นที่ทำงาน 4" +#: ../data/50-mutter-windows.xml.in.h:16 +msgid "Maximize window vertically" +msgstr "ขยายแผ่หน้าต่างเต็มด้านสูง" + +#: ../data/50-mutter-windows.xml.in.h:17 +msgid "Maximize window horizontally" +msgstr "ขยายแผ่หน้าต่างเต็มด้านกว้าง" -#: ../src/core/all-keybindings.h:311 -msgid "Move window to workspace 5" -msgstr "ย้ายหน้าต่างไปพื้นที่ทำงาน 5" +#: ../data/50-mutter-windows.xml.in.h:18 +msgid "View split on left" +msgstr "แบ่งจอแสดงที่ครึ่งซ้าย" -#: ../src/core/all-keybindings.h:314 -msgid "Move window to workspace 6" -msgstr "ย้ายหน้าต่างไปพื้นที่ทำงาน 6" +#: ../data/50-mutter-windows.xml.in.h:19 +msgid "View split on right" +msgstr "แบ่งจอแสดงที่ครึ่งขวา" -#: ../src/core/all-keybindings.h:317 -msgid "Move window to workspace 7" -msgstr "ย้ายหน้าต่างไปพื้นที่ทำงาน 7" +#: ../data/mutter.desktop.in.h:1 +msgid "Mutter" +msgstr "Mutter" -#: ../src/core/all-keybindings.h:320 -msgid "Move window to workspace 8" -msgstr "ย้ายหน้าต่างไปพื้นที่ทำงาน 8" +#: ../data/org.gnome.mutter.gschema.xml.in.h:1 +msgid "Modifier to use for extended window management operations" +msgstr "ปุ่ม modifier เพื่อใช้เข้าสู่การจัดการหน้าต่างแบบพิเศษ" -#: ../src/core/all-keybindings.h:323 -msgid "Move window to workspace 9" -msgstr "ย้ายหน้าต่างไปพื้นที่ทำงาน 9" +#: ../data/org.gnome.mutter.gschema.xml.in.h:2 +msgid "" +"This key will initiate the \"overlay\", which is a combination window " +"overview and application launching system. The default is intended to be the " +"\"Windows key\" on PC hardware. It's expected that this binding either the " +"default or set to the empty string." +msgstr "" +"ปุ่มนี้จะสร้าง \"ภาพซ้อน (overlay)\" ซึ่งประกอบด้วยภาพรวมของหน้าต่างและระบบเรียกโปรแกรม " +"ปุ่มปริยายเจตนาให้เป็นปุ่ม \"วินโดวส์\" ในเครื่องพีซีทั่วไป " +"และคาดหมายว่าค่านี้จะเป็นค่าปริยายดังกล่าว หรือมิฉะนั้นก็เป็นสตริงว่างเปล่า" -#: ../src/core/all-keybindings.h:326 -msgid "Move window to workspace 10" -msgstr "ย้ายหน้าต่างไปพื้นที่ทำงาน 10" +#: ../data/org.gnome.mutter.gschema.xml.in.h:3 +msgid "Attach modal dialogs" +msgstr "แนบกล่องโต้ตอบแบบโมดัล" -#: ../src/core/all-keybindings.h:329 -msgid "Move window to workspace 11" -msgstr "ย้ายหน้าต่างไปพื้นที่ทำงาน 11" +#: ../data/org.gnome.mutter.gschema.xml.in.h:4 +msgid "" +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." +msgstr "" +"ถ้ากำหนดเป็นค่าจริง แทนที่กล่องโต้ตอบโมดัลจะมีแถบหัวหน้าต่างเป็นของตัวเอง " +"ก็จะแนบติดไปกับแถบหัวหน้าต่างของหน้าต่างแม่ และจะเคลื่อนไปพร้อมกับหน้าต่างแม่ด้วย" -#: ../src/core/all-keybindings.h:332 -msgid "Move window to workspace 12" -msgstr "ย้ายหน้าต่างไปพื้นที่ทำงาน 12" +#: ../data/org.gnome.mutter.gschema.xml.in.h:5 +msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "เปิดใช้การปูหน้าต่างชิดขอบเมื่อวางหน้าต่างที่ขอบหน้าจอ" -#: ../src/core/all-keybindings.h:344 -msgid "Move window one workspace to the left" -msgstr "ย้ายหน้าต่างไปพื้นที่ทำงานด้านซ้าย" +#: ../data/org.gnome.mutter.gschema.xml.in.h:6 +msgid "" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." +msgstr "" +"ถ้าเปิดใช้ จะทำให้การวางหน้าต่างที่ขอบหน้าจอด้านแนวตั้งกลายเป็นการขยายแผ่หน้าต่างเต็มแนวตั้ง " +"และปรับขนาดให้วางปิดครึ่งหนึ่งของหน้าจอในแนวนอน " +"และการวางหน้าต่างที่ขอบหน้าจอด้านบนจะขยายแผ่หน้าต่างเต็มที่" -#: ../src/core/all-keybindings.h:347 -msgid "Move window one workspace to the right" -msgstr "ย้ายหน้าต่างไปพื้นที่ทำงานด้านขวา" +#: ../data/org.gnome.mutter.gschema.xml.in.h:7 +msgid "Workspaces are managed dynamically" +msgstr "จัดการพื้นที่ทำงานตามการใช้งานจริง" -#: ../src/core/all-keybindings.h:350 -msgid "Move window one workspace up" -msgstr "ย้ายหน้าต่างไปพื้นที่ทำงานด้านบน" +#: ../data/org.gnome.mutter.gschema.xml.in.h:8 +msgid "" +"Determines whether workspaces are managed dynamically or whether there's a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." +msgstr "" +"กำหนดว่าจะจัดการพื้นที่ทำงานแบบปรับเปลี่ยนตามการใช้งานจริง หรือจะให้มีจำนวนพื้นที่ทำงานตายตัว " +"(กำหนดโดยคีย์ num-workspaces ใน org.gnome.desktop.wm.preferences)" -#: ../src/core/all-keybindings.h:353 -msgid "Move window one workspace down" -msgstr "ย้ายหน้าต่างไปพื้นที่ทำงานด้านล่าง" +#: ../data/org.gnome.mutter.gschema.xml.in.h:9 +msgid "Workspaces only on primary" +msgstr "พื้นที่ทำงานอยู่บนจอภาพหลักเท่านั้น" -# Note: This is the longest description in "Shortcut" menu. -# Should keep it as short as possible, so it doesn't pad the -# dialog out too wide. -# -# The next entry in the list will make this entry clear. -#: ../src/core/all-keybindings.h:356 -msgid "Raise window if it's covered by another window, otherwise lower it" -msgstr "ยกหน้าต่างขึ้นถ้าถูกบัง มิฉะนั้นก็เอาลงด้านหลัง" +#: ../data/org.gnome.mutter.gschema.xml.in.h:10 +msgid "" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." +msgstr "" +"กำหนดว่าการสลับพื้นที่ทำงานควรเกิดเฉพาะกับหน้าต่างบนจอภาพทั้งหมด " +"หรือเฉพาะหน้าต่างบนจอภาพหลักเท่านั้น" -#: ../src/core/all-keybindings.h:358 -msgid "Raise window above other windows" -msgstr "ยกหน้าต่างขึ้นมาไว้หน้าหน้าต่างอื่นๆ" +#: ../data/org.gnome.mutter.gschema.xml.in.h:11 +msgid "No tab popup" +msgstr "ไม่ใช้กล่องผุดขึ้นของปุ่มแท็บ" -#: ../src/core/all-keybindings.h:360 -msgid "Lower window below other windows" -msgstr "ถอยหน้าต่างลงไปใว้หลังหน้าต่างอื่น" +#: ../data/org.gnome.mutter.gschema.xml.in.h:12 +msgid "" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." +msgstr "กำหนดว่าจะปิดการใช้กล่องผุดขึ้นและการเน้นกรอบหน้าต่างสำหรับการสลับหน้าต่างหรือไม่" -#: ../src/core/all-keybindings.h:364 -msgid "Maximize window vertically" -msgstr "ขยายแผ่หน้าต่างเต็มด้านสูง" +#: ../data/org.gnome.mutter.gschema.xml.in.h:13 +msgid "Delay focus changes until the pointer stops moving" +msgstr "ชะลอการย้ายโฟกัสจนกว่าเคอร์เซอร์เมาส์จะหยุดเคลื่อน" -#: ../src/core/all-keybindings.h:368 -msgid "Maximize window horizontally" -msgstr "ขยายแผ่หน้าต่างเต็มด้านกว้าง" +#: ../data/org.gnome.mutter.gschema.xml.in.h:14 +msgid "" +"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " +"the focus will not be changed immediately when entering a window, but only " +"after the pointer stops moving." +msgstr "" +"ถ้ามีค่าเป็นจริง และโหมดโฟกัสเป็น \"sloppy\" หรือ \"mouse\" อย่างใดอย่างหนึ่งแล้ว " +"ก็จะไม่ย้ายโฟกัสหน้าต่างทันทีทันใดเมื่อเข้าสู่หน้าต่าง จนกว่าเคอร์เซอร์เมาส์จะหยุดเคลื่อนที่" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:15 +msgid "Draggable border width" +msgstr "ความกว้างของขอบหน้าต่างส่วนที่ลากได้" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:16 +msgid "" +"The amount of total draggable borders. If the theme's visible borders are " +"not enough, invisible borders will be added to meet this value." +msgstr "" +"ขนาดของขอบหน้าต่างส่วนที่ลากได้ ถ้าขอบหน้าต่างส่วนที่ปรากฏของชุดตกแต่งกว้างไม่พอ " +"ก็จะเพิ่มขอบส่วนที่มองไม่เห็นเพื่อให้ได้เท่ากับความกว้างนี้" -#: ../src/core/all-keybindings.h:372 -msgid "Move window to north-west (top left) corner" -msgstr "ย้ายหน้าต่างไปที่มุมบนซ้ายของหน้าจอ" +#: ../data/org.gnome.mutter.gschema.xml.in.h:17 +msgid "Auto maximize nearly monitor sized windows" +msgstr "ขยายแผ่หน้าต่างที่มีขนาดใกล้เคียงกับจอภาพโดยอัตโนมัติ" -#: ../src/core/all-keybindings.h:375 -msgid "Move window to north-east (top right) corner" -msgstr "ย้ายหน้าต่างไปที่มุมบนขวาของหน้าจอ" +#: ../data/org.gnome.mutter.gschema.xml.in.h:18 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "ถ้าเปิดใช้ หน้าต่างใหม่ที่มีขนาดเริ่มแรกเท่ากับจอภาพจะขยายแผ่โดยอัตโนมัติ" -#: ../src/core/all-keybindings.h:378 -msgid "Move window to south-west (bottom left) corner" -msgstr "ย้ายหน้าต่างไปที่มุมล่างซ้ายของหน้าจอ" +#: ../data/org.gnome.mutter.gschema.xml.in.h:19 +msgid "Place new windows in the center" +msgstr "วางหน้าต่างใหม่กลางหน้าจอ" -#: ../src/core/all-keybindings.h:381 -msgid "Move window to south-east (bottom right) corner" -msgstr "ย้ายหน้าต่างไปที่มุมล่างขวาของหน้าจอ" +#: ../data/org.gnome.mutter.gschema.xml.in.h:20 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "ถ้าเป็นจริง จะวางหน้าต่างใหม่ที่กลางหน้าจอที่จอภาพแสดงอยู่เสมอ" -#: ../src/core/all-keybindings.h:385 -msgid "Move window to north (top) side of screen" -msgstr "ย้ายหน้าต่างไปที่ขอบด้านบนของหน้าจอ" +#: ../data/org.gnome.mutter.gschema.xml.in.h:21 +msgid "Select window from tab popup" +msgstr "เลือกหน้าต่างจากกล่องผุดขึ้นของปุ่มแท็บ" -#: ../src/core/all-keybindings.h:388 -msgid "Move window to south (bottom) side of screen" -msgstr "ย้ายหน้าต่างไปที่ขอบด้านล่างของหน้าจอ" +#: ../data/org.gnome.mutter.gschema.xml.in.h:22 +msgid "Cancel tab popup" +msgstr "ยกเลิกกล่องผุดขึ้นของปุ่มแท็บ" -#: ../src/core/all-keybindings.h:391 -msgid "Move window to east (right) side of screen" -msgstr "ย้ายหน้าต่างไปที่ขอบด้านขวาของหน้าจอ" +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:1 +msgid "Switch to VT 1" +msgstr "สลับไป VT 1" -#: ../src/core/all-keybindings.h:394 -msgid "Move window to west (left) side of screen" -msgstr "ย้ายหน้าต่างไปที่ขอบด้านซ้ายของหน้าจอ" +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:2 +msgid "Switch to VT 2" +msgstr "สลับไป VT 2" -#: ../src/core/all-keybindings.h:397 -msgid "Move window to center of screen" -msgstr "ย้ายหน้าต่างไปที่กลางหน้าจอ" +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:3 +msgid "Switch to VT 3" +msgstr "สลับไป VT 3" -#: ../src/core/bell.c:310 -msgid "Bell event" -msgstr "เหตุการณ์กระดิ่ง" +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:4 +msgid "Switch to VT 4" +msgstr "สลับไป VT 4" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:5 +msgid "Switch to VT 5" +msgstr "สลับไป VT 5" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:6 +msgid "Switch to VT 6" +msgstr "สลับไป VT 6" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:7 +msgid "Switch to VT 7" +msgstr "สลับไป VT 7" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:8 +msgid "Switch to VT 8" +msgstr "สลับไป VT 8" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:9 +msgid "Switch to VT 9" +msgstr "สลับไป VT 9" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:10 +msgid "Switch to VT 10" +msgstr "สลับไป VT 10" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:11 +msgid "Switch to VT 11" +msgstr "สลับไป VT 11" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:12 +msgid "Switch to VT 12" +msgstr "สลับไป VT 12" + +#: ../src/backends/meta-monitor-manager.c:500 +msgid "Built-in display" +msgstr "จอแสดงผลในตัว" + +#: ../src/backends/meta-monitor-manager.c:526 +msgid "Unknown" +msgstr "ไม่ทราบยี่ห้อ" + +#: ../src/backends/meta-monitor-manager.c:528 +msgid "Unknown Display" +msgstr "จอแสดงผลไม่ทราบรุ่น" -#: ../src/core/core.c:157 +#. TRANSLATORS: this is a monitor vendor name, followed by a +#. * size in inches, like 'Dell 15"' +#. +#: ../src/backends/meta-monitor-manager.c:536 +#, c-format +msgid "%s %s" +msgstr "%s %s" + +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: ../src/compositor/compositor.c:451 #, c-format -msgid "Unknown window information request: %d" -msgstr "คำร้องขอข้อมูลหน้าต่างที่ไม่รู้จัก: %d" +msgid "" +"Another compositing manager is already running on screen %i on display \"%s" +"\"." +msgstr "มีโปรแกรมจัดการ composite ทำงานอยู่แล้วที่สกรีน %i ดิสเพลย์ \"%s\"" + +#: ../src/core/bell.c:185 +msgid "Bell event" +msgstr "เหตุการณ์กระดิ่ง" -#: ../src/core/delete.c:111 +#: ../src/core/delete.c:127 #, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> ไม่ตอบสนอง" +msgid "“%s” is not responding." +msgstr "“%s” ไม่ตอบสนอง" -#: ../src/core/delete.c:114 +#: ../src/core/delete.c:129 msgid "Application is not responding." msgstr "โปรแกรมไม่ตอบสนอง" -#: ../src/core/delete.c:119 +#: ../src/core/delete.c:134 msgid "" "You may choose to wait a short while for it to continue or force the " "application to quit entirely." msgstr "คุณอาจเลือกที่จะรอสักครู่ เพื่อให้โปรแกรมทำงานต่อ หรือจะบังคับโปรแกรมออกทันทีเลยก็ได้" -#: ../src/core/delete.c:126 +#: ../src/core/delete.c:141 msgid "_Wait" msgstr "_รอ" -#: ../src/core/delete.c:126 +#: ../src/core/delete.c:141 msgid "_Force Quit" msgstr "_บังคับออก" -#: ../src/core/display.c:365 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "ไม่มีส่วนขยาย %s ซึ่งจำเป็นต่อการทำ composite" - -#: ../src/core/display.c:431 +#: ../src/core/display.c:563 #, c-format msgid "Failed to open X Window System display '%s'\n" msgstr "ไม่สามารถเปิดดิสเพลย์ '%s' ของระบบ X Window\n" -#: ../src/core/keybindings.c:759 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "โปรแกรมอื่นกำลังใช้ปุ่ม %s ร่วมกับปุ่ม %x เป็นปุ่มลัดอยู่แล้ว\n" - -#. Displayed when a keybinding which is -#. * supposed to launch a program fails. -#. -#: ../src/core/keybindings.c:2523 -#, c-format -msgid "" -"There was an error running <tt>%s</tt>:\n" -"\n" -"%s" -msgstr "" -"เกิดข้อผิดพลาดขณะเรียก <tt>%s</tt>:\n" -"\n" -"%s" - -#: ../src/core/keybindings.c:2613 -#, c-format -msgid "No command %d has been defined.\n" -msgstr "คำสั่ง %d ยังไม่ได้ถูกกำหนด\n" - -#: ../src/core/keybindings.c:3625 -#, c-format -msgid "No terminal command has been defined.\n" -msgstr "คำสั่งเปิดเทอร์มินัลยังไม่ได้ถูกกำหนด\n" - -#: ../src/core/main.c:206 +#: ../src/core/main.c:176 msgid "Disable connection to session manager" msgstr "ปิดการเชื่อมต่อไปยังโปรแกรมจัดการวาระ" -#: ../src/core/main.c:212 +#: ../src/core/main.c:182 msgid "Replace the running window manager" msgstr "แทนที่โปรแกรมจัดการหน้าต่างที่กำลังทำงานอยู่" -#: ../src/core/main.c:218 +#: ../src/core/main.c:188 msgid "Specify session management ID" msgstr "ระบุ ID ของการจัดการวาระ" -#: ../src/core/main.c:223 +#: ../src/core/main.c:193 msgid "X Display to use" msgstr "ดิสเพลย์ X ที่จะใช้" -#: ../src/core/main.c:229 +#: ../src/core/main.c:199 msgid "Initialize session from savefile" msgstr "ใช้ค่าเริ่มต้นของวาระจากแฟ้มที่บันทึกไว้" -#: ../src/core/main.c:235 +#: ../src/core/main.c:205 msgid "Make X calls synchronous" msgstr "ให้การเรียกฟังก์ชัน X เป็นแบบซิงโครนัส" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "ไม่สามารถอ่านโฟลเดอร์ชุดตกแต่ง: %s\n" +#: ../src/core/main.c:212 +msgid "Run as a wayland compositor" +msgstr "เรียกทำงานในฐานะ compositor ของ wayland" -#: ../src/core/main.c:520 -#, c-format -msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "ไม่พบชุดตกแต่ง โปรดตรวจดูว่า %s มีอยู่จริง และบรรจุชุดตกแต่งที่ควรจะมี\n" +#: ../src/core/main.c:220 +msgid "Run as a full display server, rather than nested" +msgstr "เรียกทำงานในฐานเซิร์ฟเวอร์แสดงผลเต็มขั้น ไม่ใช่ซ้อนในเซิร์ฟเวอร์อื่น" # FIXME: Get a lawer to translate the legal clause. -#: ../src/core/muffin.c:42 +#: ../src/core/mutter.c:39 #, c-format msgid "" -"muffin %s\n" +"mutter %s\n" "Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" "This is free software; see the source for copying conditions.\n" "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " "PARTICULAR PURPOSE.\n" msgstr "" -"muffin %s\n" +"mutter %s\n" "Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" "นี่เป็นซอฟต์แวร์เสรี อ่านเงื่อนไขลิขสิทธิ์ได้ในโค้ดต้นฉบับ\n" "ไม่รับผิดชอบข้อเสียหายใดๆ " "ไม่รับประกันความเหมาะสมในเชิงพาณิชย์หรือการใช้งานเฉพาะทางอย่างหนึ่งอย่างใด\n" -#: ../src/core/muffin.c:56 +#: ../src/core/mutter.c:53 msgid "Print version" msgstr "แสดงเลขรุ่น" -#: ../src/core/muffin.c:62 -msgid "Comma-separated list of compositor plugins" -msgstr "รายชื่อของปลั๊กอิน composite คั่นด้วยจุลภาค" - -#. -#. * We found it, but it was invalid. Complain. -#. * -#. * FIXME: This replicates the original behaviour, but in the future -#. * we might consider reverting invalid keys to their original values. -#. * (We know the old value, so we can look up a suitable string in -#. * the symtab.) -#. * -#. * (Empty comment follows so the translators don't see this.) -#. -#. -#: ../src/core/prefs.c:550 ../src/core/prefs.c:711 -#, c-format -msgid "GConf key '%s' is set to an invalid value\n" -msgstr "คีย์ GConf '%s' ถูกตั้งค่าเป็นค่าที่ใช้ไม่ได้\n" - -#: ../src/core/prefs.c:637 ../src/core/prefs.c:880 -#, c-format -msgid "%d stored in GConf key %s is out of range %d to %d\n" -msgstr "%d ในคีย์ GConf %s ต้องอยู่ระหว่าง %d และ %d\n" - -#: ../src/core/prefs.c:681 ../src/core/prefs.c:758 ../src/core/prefs.c:806 -#: ../src/core/prefs.c:870 ../src/core/prefs.c:1331 ../src/core/prefs.c:1347 -#: ../src/core/prefs.c:1364 ../src/core/prefs.c:1380 -#, c-format -msgid "GConf key \"%s\" is set to an invalid type\n" -msgstr "คีย์ GConf \"%s\" ถูกตั้งค่าเป็นชนิดที่ใช้ไม่ได้\n" - -#: ../src/core/prefs.c:1210 -#, c-format -msgid "GConf key %s is already in use and can't be used to override %s\n" -msgstr "คีย์ GConf %s ถูกใช้งานอยู่ และไม่สามารถใช้ทับค่า %s ได้\n" - -#: ../src/core/prefs.c:1269 -#, c-format -msgid "Can't override GConf key, %s not found\n" -msgstr "ไม่สามารถทับค่าคีย์ GConf ได้ ไม่พบ %s\n" - -#: ../src/core/prefs.c:1454 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"ปิดการแก้ขัดที่เตรียมไว้สำหรับโปรแกรมเสียๆ บางโปรแกรมแล้ว " -"ซึ่งอาจทำให้โปรแกรมเหล่านี้ทำงานไม่ปกติ\n" - -#: ../src/core/prefs.c:1531 -#, c-format -msgid "Could not parse font description \"%s\" from GConf key %s\n" -msgstr "ไม่เข้าใจคำบรรยายแบบตัวอักษร \"%s\" จากคีย์ GConf %s\n" - -#: ../src/core/prefs.c:1593 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "\"%s\" ที่พบในฐานข้อมูลข้อปรับแต่ง ใช้เป็นปุ่มใช้ร่วมสำหรับเมาส์ไม่ได้\n" +#: ../src/core/mutter.c:59 +msgid "Mutter plugin to use" +msgstr "ปลั๊กอินของ mutter ที่จะใช้" -#: ../src/core/prefs.c:2028 -#, c-format -msgid "Error setting number of workspaces to %d: %s\n" -msgstr "ไม่สามารถตั้งจำนวนพื้นที่ทำงานเป็น %d: %s\n" - -#: ../src/core/prefs.c:2212 ../src/core/prefs.c:2714 +#: ../src/core/prefs.c:2004 #, c-format msgid "Workspace %d" msgstr "พื้นที่ทำงาน %d" -#: ../src/core/prefs.c:2244 ../src/core/prefs.c:2422 +#: ../src/core/screen.c:525 #, c-format msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "\"%s\" ที่พบในฐานข้อมูลค่าปรับแต่ง ไม่สามารถใช้เป็นปุ่มลัด \"%s\"\n" - -#: ../src/core/prefs.c:2795 -#, c-format -msgid "Error setting name for workspace %d to \"%s\": %s\n" -msgstr "ไม่สามารถตั้งชื่อพื้นที่ทำงาน %d เป็น %s: %s\n" - -#: ../src/core/prefs.c:3009 -#, c-format -msgid "Error setting live hidden windows status status: %s\n" -msgstr "เกิดข้อผิดพลาดขณะกำหนดสถานะของหน้าต่างซ่อนที่ยังทำงาน: %s\n" - -#: ../src/core/prefs.c:3044 -#, c-format -msgid "Error setting no tab popup status: %s\n" -msgstr "เกิดข้อผิดพลาดขณะกำหนดสถานะการไม่ผุดหน้าต่างในแท็บ: %s\n" +"Display \"%s\" already has a window manager; try using the --replace option " +"to replace the current window manager." +msgstr "" +"ดิสเพลย์ \"%s\" มีโปรแกรมจัดการหน้าต่างอยู่แล้ว ลองใช้ตัวเลือก --replace " +"ถ้าต้องการแทนที่โปรแกรมจัดการหน้าต่างปัจจุบัน" -#: ../src/core/screen.c:663 +#: ../src/core/screen.c:607 #, c-format msgid "Screen %d on display '%s' is invalid\n" msgstr "สกรีน %d ที่ดิสเพลย์ '%s' ใช้ไม่ได้\n" -#: ../src/core/screen.c:679 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"สกรีน %d ที่ดิสเพลย์ \"%s\" มีโปรแกรมจัดการหน้าต่างอยู่แล้ว ลองใช้ตัวเลือก --replace " -"ถ้าต้องการแทนที่โปรแกรมจัดการหน้าต่างปัจจุบัน\n" - -#: ../src/core/screen.c:706 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "ไม่สามารถอ่านค่าโปรแกรมจัดการหน้าต่างจากสกรีน %d ดิสเพลย์ \"%s\" ได้\n" - -#: ../src/core/screen.c:761 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "สกรีน %d ที่ดิสเพลย์ \"%s\" มีโปรแกรมจัดการหน้าต่างอยู่แล้ว\n" - -#: ../src/core/screen.c:946 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "ไม่สามารถปล่อยการควบคุมสกรีน %d ที่ดิสเพลย์ \"%s\"\n" - -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "ไม่สามารถสร้างโฟลเดอร์ '%s': %s\n" - -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "ไม่สามารถเปิดแฟ้มวาระ '%s' สำหรับเขียน: %s\n" - -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "ไม่สามารถเขียนลงแฟ้มวาระ '%s': %s\n" - -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "ไม่สามารถปิดแฟ้มวาระ '%s': %s\n" - -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "ไม่เข้าใจแฟ้มวาระที่บันทึกไว้: %s\n" - -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "พบแอตทริบิวต์ <muffin_session> แต่ว่ามี ID วาระอยู่แล้ว" - -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "ไม่รู้จักแอตทริบิวต์ %s ในอิลิเมนต์ <%s>" - -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "มีแท็ก <window> ซ้อนด้านใน" - -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "ไม่รู้จักอิลิเมนต์ %s" +#: ../src/core/util.c:118 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter ถูกคอมไพล์โดยไม่ได้เลือกรองรับโหมดข้อความละเอียด\n" -#: ../src/core/session.c:1809 +#: ../src/x11/session.c:1815 msgid "" "These windows do not support "save current setup" and will have to " "be restarted manually next time you log in." @@ -651,2951 +594,8 @@ msgstr "" "หน้าต่างเหล่านี้ไม่รองรับการ "บันทึกค่าตั้งปัจจุบัน" " "และคุณต้องกำหนดใหม่เองเมื่อเข้าสู่ระบบครั้งต่อไป" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "เปิดแฟ้มปูมการดีบั๊กไม่สำเร็จ: %s\n" - -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "fdopen() แฟ้มปูม %s ไม่สำเร็จ: %s\n" - -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "เปิดแฟ้มปูม %s เรียบร้อยแล้ว\n" - -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "Muffin ถูกคอมไพล์โดยไม่ได้เลือกรองรับโหมดข้อความละเอียด\n" - -#: ../src/core/util.c:286 -msgid "Window manager: " -msgstr "โปรแกรมจัดการหน้าต่าง: " - -#: ../src/core/util.c:434 -msgid "Bug in window manager: " -msgstr "บั๊กในโปรแกรมจัดการหน้าต่าง: " - -#: ../src/core/util.c:467 -msgid "Window manager warning: " -msgstr "คำเตือนในโปรแกรมจัดการหน้าต่าง: " - -#: ../src/core/util.c:495 -msgid "Window manager error: " -msgstr "เกิดข้อผิดพลาดในโปรแกรมจัดการหน้าต่าง: " - -#. Translators: This is the title used on dialog boxes -#: ../src/core/util.c:632 ../src/muffin.desktop.in.h:1 -#: ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" - -#. first time through -#: ../src/core/window.c:6959 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"หน้าต่าง %s ตั้งค่า SM_CLIENT_ID มาที่ตัวเอง แทนที่จะอ้างไปถึงหน้าต่างของ WM_CLIENT_LEADER " -"ตามที่กำหนดไว้ใน ICCCM\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7622 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %" -"d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"หน้าต่าง %s ตั้งค่า MWM hint ไว้ว่าเป็นหน้าต่างที่เปลี่ยนขนาดไม่ได้ แต่กลับตั้งค่าขนาดต่ำสุด %d x %" -"d และขนาดสูงสุด %d x %d ไว้ ซึ่งไม่สมเหตุสมผลเท่าไรนัก\n" - -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "โปรแกรมประยุกต์ตั้งค่า _NET_WM_PID เป็น %lu ซึ่งไม่มีอยู่จริง\n" - -#: ../src/core/window-props.c:426 +#: ../src/x11/window-props.c:549 #, c-format msgid "%s (on %s)" msgstr "%s (ที่เครื่อง %s)" -#: ../src/core/window-props.c:1488 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "หน้าต่าง WM_TRANSIENT_FOR 0x%lx ที่กำหนดให้กับ %s เป็นค่าที่ใช้ไม่ได้\n" - -#: ../src/core/window-props.c:1500 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "หน้าต่าง WM_TRANSIENT_FOR 0x%lx สำหรับ %s จะทำให้เกิดวงวน\n" - -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"หน้าต่าง 0x%lx มีคุณสมบัติ %s\n" -"ที่คาดหวังว่าจะมีชนิด %s และรูปแบบ %d\n" -"แต่กลับมีชนิด %s รูปแบบ %d และ n_items %d\n" -"โดยมากแล้ว นี่ถือเป็นบั๊กของโปรแกรม ไม่ใช่ของโปรแกรมจัดการหน้าต่าง\n" -"หน้าต่างที่มีปัญหามีหัวเรื่อง=\"%s\" คลาส=\"%s\" ชื่อ=\"%s\"\n" - -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "คุณสมบัติ %s ของหน้าต่าง 0x%lx มีค่าที่ไม่ใช่ UTF-8 ที่ถูกต้อง\n" - -#: ../src/core/xprops.c:494 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"คุณสมบัติ %s ของหน้าต่าง 0x%lx มีค่าที่ไม่ใช่ UTF-8 ที่ถูกต้องสำหรับหัวข้อที่ %d ในรายการ\n" - -#: ../src/muffin.schemas.in.h:1 -msgid "Attach modal dialogs" -msgstr "แนบกล่องโต้ตอบแบบโมดัล" - -#: ../src/muffin.schemas.in.h:2 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"กำหนดว่าควรจะเก็บรักษาหน้าต่างที่ถูกซ่อน (กล่าวคือ หน้าต่างที่ถูกย่อเก็บ " -"และหน้าต่างที่อยู่บนพื้นที่ทำงานอื่นที่ไม่ใช่พื้นที่ทำงานปัจจุบัน) ให้ยังทำงานอยู่หรือไม่" - -#: ../src/muffin.schemas.in.h:3 -msgid "" -"Determines whether workspace switching should happen for windows on all " -"monitors or only for windows on the primary monitor." -msgstr "" -"กำหนดว่าการสลับพื้นที่ทำงานควรเกิดเฉพาะกับหน้าต่างบนจอภาพทั้งหมด " -"หรือเฉพาะหน้าต่างบนจอภาพหลักเท่านั้น" - -#: ../src/muffin.schemas.in.h:4 -msgid "Draggable border width" -msgstr "ความกว้างของขอบหน้าต่างส่วนที่ลากได้" - -#: ../src/muffin.schemas.in.h:5 -msgid "Live Hidden Windows" -msgstr "รักษาหน้าต่างซ่อนให้ทำงานอยู่" - -#: ../src/muffin.schemas.in.h:6 -msgid "Modifier to use for extended window management operations" -msgstr "ปุ่ม modifier เพื่อใช้เข้าสู่การจัดการหน้าต่างแบบพิเศษ" - -#: ../src/muffin.schemas.in.h:7 -msgid "" -"The amount of total draggable borders. If the theme's visible borders are " -"not enough, invisible borders will be added to meet this value." -msgstr "" -"ขนาดของขอบหน้าต่างส่วนที่ลากได้ ถ้าขอบหน้าต่างส่วนที่ปรากฏของชุดตกแต่งกว้างไม่พอ " -"ก็จะเพิ่มขอบส่วนที่มองไม่เห็นเพื่อให้ได้เท่ากับความกว้างนี้" - -#: ../src/muffin.schemas.in.h:8 -msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." -msgstr "" -"ปุ่มนี้จะสร้าง \"ภาพซ้อน (overlay)\" ซึ่งประกอบด้วยภาพรวมของหน้าต่างและระบบเรียกโปรแกรม " -"ปุ่มปริยายเจตนาให้เป็นปุ่ม \"วินโดวส์\" ในเครื่องพีซีทั่วไป " -"และคาดหมายว่าค่านี้จะเป็นค่าปริยายดังกล่าว หรือมิฉะนั้นก็เป็นสตริงว่างเปล่า" - -#: ../src/muffin.schemas.in.h:9 -msgid "" -"When true, instead of having independent titlebars, modal dialogs appear " -"attached to the titlebar of the parent window and are moved together with " -"the parent window." -msgstr "" -"ถ้ากำหนดเป็นค่าจริง แทนที่กล่องโต้ตอบโมดัลจะมีแถบหัวหน้าต่างเป็นของตัวเอง " -"ก็จะแนบติดไปกับแถบหัวหน้าต่างของหน้าต่างแม่ และจะเคลื่อนไปพร้อมกับหน้าต่างแม่ด้วย" - -#: ../src/muffin.schemas.in.h:10 -msgid "Workspaces only on primary" -msgstr "พื้นที่ทำงานอยู่บนจอภาพหลักเท่านั้น" - -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "วิธีใช้: %s\n" - -#: ../src/ui/frames.c:1123 -msgid "Close Window" -msgstr "ปิดหน้าต่าง" - -#: ../src/ui/frames.c:1126 -msgid "Window Menu" -msgstr "เมนูหน้าต่าง" - -#: ../src/ui/frames.c:1129 -msgid "Minimize Window" -msgstr "ย่อเก็บหน้าต่าง" - -#: ../src/ui/frames.c:1132 -msgid "Maximize Window" -msgstr "ขยายแผ่หน้าต่าง" - -#: ../src/ui/frames.c:1135 -msgid "Restore Window" -msgstr "คืนขนาดหน้าต่าง" - -#: ../src/ui/frames.c:1138 -msgid "Roll Up Window" -msgstr "_ม้วนหน้าต่างขึ้น" - -#: ../src/ui/frames.c:1141 -msgid "Unroll Window" -msgstr "คลี่หน้าต่างกลับ" - -#: ../src/ui/frames.c:1144 -msgid "Keep Window On Top" -msgstr "วางหน้าต่างไว้บนสุด" - -#: ../src/ui/frames.c:1147 -msgid "Remove Window From Top" -msgstr "เลิกวางหน้าต่างไว้บนสุด" - -#: ../src/ui/frames.c:1150 -msgid "Always On Visible Workspace" -msgstr "แสดงบนพื้นที่ทำงานเสมอ" - -#: ../src/ui/frames.c:1153 -msgid "Put Window On Only One Workspace" -msgstr "วางหน้าต่างบนพื้นที่ทำงานเดียวเท่านั้น" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "ย่_อเก็บ" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "ขย_ายแผ่" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "เลิกขย_ายแผ่" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "_ม้วนขึ้น" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "_คลี่กลับ" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "_ย้าย" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "_ปรับขนาด" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "ย้ายแถบหัวเรื่องกลับเข้า_จอ" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "อยู่_บนสุด" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "แสดงบนพื้นที่ทำงานเ_สมอ" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "แสดงบนพื้นที่ทำงาน_นี้เท่านั้น" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "ย้ายไปพื้นที่ทำงานซ้_าย" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "ย้ายไปพื้นที่ทำงานข_วา" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "ย้ายไปพื้นที่ทำงาน_บน" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "ย้ายไปพื้นที่ทำงาน_ล่าง" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "ปิ_ด" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "พื้นที่ทำงาน %d%n" - -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "พื้นที่ทำงาน 1_0" - -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "พื้นที่ทำงาน %s%d" - -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "ย้ายไป_พื้นที่ทำงานอื่น" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" - -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" - -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "บน" - -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "ล่าง" - -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "ซ้าย" - -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "ขวา" - -#: ../src/ui/theme.c:286 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "ค่าเรขาคณิตของเฟรมไม่ได้ระบุขนาด \"%s\"" - -#: ../src/ui/theme.c:305 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "ค่าเรขาคณิตของเฟรมไม่ได้ระบุขนาด \"%s\" สำหรับกรอบ \"%s\"" - -#: ../src/ui/theme.c:342 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "ค่า aspect ratio %g ของปุ่มไม่สมเหตุสมผล" - -#: ../src/ui/theme.c:354 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "ค่าเรขาคณิตของเฟรมไม่ได้ระบุขนาดของปุ่ม" - -#: ../src/ui/theme.c:1060 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "การไล่สีควรใช้อย่างน้อยสองสี" - -#: ../src/ui/theme.c:1205 -#, c-format -msgid "" -"GTK custom color specification must have color name and fallback in " -"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" -msgstr "" -"การกำหนดสี GTK แบบปรับเอง ต้องประกอบด้วยชื่อสีและค่าสำรองในวงเล็บ เช่น " -"gtk:custom(foo,bar); ไม่สามารถแจงค่า \"%s\"" - -#: ../src/ui/theme.c:1221 -#, c-format -msgid "" -"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" -"_ are valid" -msgstr "" -"อักขระ '%c' ใช้ไม่ได้ในพารามิเตอร์ color_name ของ gtk:custom สามารถใช้ได้แค่ " -"A-Za-z0-9-_ เท่านั้น" - -#: ../src/ui/theme.c:1235 -#, c-format -msgid "" -"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " -"fit the format" -msgstr "" -"รูปแบบของ Gtk:custom คือ \"gtk:custom(color_name,fallback)\", \"%s\" " -"ไม่ตรงกับรูปแบบ" - -#: ../src/ui/theme.c:1271 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"การกำหนดสี GTK ต้องเขียนสถานะในวงเล็บเหลี่ยม เช่น gtk:fg[NORMAL] เมื่อ NORMAL " -"เป็นสถานะ; ไม่สามารถแจงค่า \"%s\"" - -#: ../src/ui/theme.c:1285 -#, c-format -msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"การกำหนดสี GTK ต้องมีวงเล็บเหลี่ยมปิดหลังสถานะด้วย เช่น gtk:fg[NORMAL] เมื่อ NORMAL " -"เป็นสถานะ; ไม่สามารถแจงค่า \"%s\"" - -#: ../src/ui/theme.c:1296 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "ไม่เข้าใจสถานะ \"%s\" ในการระบุสี" - -#: ../src/ui/theme.c:1309 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "ไม่เข้าใจองค์ประกอบ \"%s\" ในการระบุสี" - -#: ../src/ui/theme.c:1339 -#, c-format -msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" -msgstr "" -"รูปแบบการเกลี่ยสีคือ \"blend/bg_color/fg_color/alpha\", ค่า \"%s\" ไม่ตรงกับรูปแบบ" - -#: ../src/ui/theme.c:1350 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "ไม่สามารถแจงค่าอัลฟา \"%s\" ในการเกลี่ยสี" - -#: ../src/ui/theme.c:1360 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "ค่าอัลฟา \"%s\" ในการเกลี่ยสีไม่อยู่ระหว่าง 0.0 และ 1.0" - -#: ../src/ui/theme.c:1407 -#, c-format -msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "รูปแบบของเฉดสีคือ \"shade/base_color/factor \", \"%s\" ไม่ตรงกับรูปแบบ" - -#: ../src/ui/theme.c:1418 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "ไม่สามารถแจงค่าตัวคูณของเฉด \"%s\" ในเฉดสี" - -#: ../src/ui/theme.c:1428 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "ตัวคูณเฉดสี \"%s\" ในเฉดสีเป็นค่าลบ" - -#: ../src/ui/theme.c:1457 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "ไม่เข้าใจสี \"%s\"" - -#: ../src/ui/theme.c:1768 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "นิพจน์พิกัดมีอักขระ'%s' ซึ่งไม่อนุญาตให้ใช้" - -#: ../src/ui/theme.c:1795 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "นิพจน์พิกัดมีเลขจุดทศนิยม '%s' ที่แจงค่าไม่ได้" - -#: ../src/ui/theme.c:1809 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "นิพจน์พิกัดมีเลขจำนวนเต็ม '%s' ที่แจงค่าไม่ได้" - -#: ../src/ui/theme.c:1931 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "นิพจน์พิกัดมีเครื่องหมายดำเนินการที่ไม่รู้จัก เริ่มจากตำแหน่ง \"%s\"" - -#: ../src/ui/theme.c:1988 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "นิพจน์พิกัดว่างเปล่าหรือไม่สามารถเข้าใจ" - -#: ../src/ui/theme.c:2099 ../src/ui/theme.c:2109 ../src/ui/theme.c:2143 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "นิพจน์พิกัดมีผลลัพธ์ที่เป็นการหารด้วยศูนย์" - -#: ../src/ui/theme.c:2151 -#, c-format -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "นิพจน์พิกัดพยายามใช้ตัวดำเนินการ mod กับตัวเลขจุดทศนิยม" - -#: ../src/ui/theme.c:2207 -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "นิพจน์พิกัดมีตัวดำเนินการ\"%s\" ในที่ที่ควรจะเป็นตัวถูกดำเนินการ" - -#: ../src/ui/theme.c:2216 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "นิพจน์พิกัดมีตัวถูกดำเนินการในที่ที่ควรจะเป็นตัวดำเนินการ" - -#: ../src/ui/theme.c:2224 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "นิพจน์พิกัดจบด้วยตัวดำเนินการแทนที่จะเป็นตัวถูกดำเนินการ" - -#: ../src/ui/theme.c:2234 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" -"นิพจน์พิกัดมีตัวดำเนินการ\"%c\" ตามหลังตัวดำเนินการ \"%c\" โดยไม่มีตัวถูกดำเนินการคั่นกลาง" - -#: ../src/ui/theme.c:2385 ../src/ui/theme.c:2430 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "นิพจน์พิกัดมีตัวแปรหรือค่าคงที่ \"%s\" ที่ไม่รู้จัก" - -#: ../src/ui/theme.c:2484 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "ตัวแจงค่านิพจน์พิกัดทำข้อมูลล้น" - -#: ../src/ui/theme.c:2513 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "นิพจน์พิกัดมีวงเล็บปิดโดยไม่มีวงเล็บเปิด" - -#: ../src/ui/theme.c:2577 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "นิพจน์พิกัดมีวงเล็บเปิดโดยไม่มีวงเล็บปิด" - -#: ../src/ui/theme.c:2588 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "นิพจน์พิกัดท่าทางจะไม่มีตัวดำเนินการหรือตัวถูกดำเนินการเลย" - -#: ../src/ui/theme.c:2800 ../src/ui/theme.c:2820 ../src/ui/theme.c:2840 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "ชุดตกแต่งมีนิพจน์ซึ่งทำให้เกิดข้อผิดพลาด: %s\n" - -#: ../src/ui/theme.c:4511 -#, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" -"ต้องระบุ <button function =\"%s\" state=\"%s\" draw_ops=\"อะไรก็ตามแต่\"/> " -"สำหรับรูปแบบเฟรมด้วย" - -#: ../src/ui/theme.c:5044 ../src/ui/theme.c:5069 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" -"ขาด <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"อะไรก็ตามแต่\"/>" - -#: ../src/ui/theme.c:5117 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "โหลดชุดตกแต่ง \"%s\" ล้มเหลว: %s\n" - -#: ../src/ui/theme.c:5253 ../src/ui/theme.c:5260 ../src/ui/theme.c:5267 -#: ../src/ui/theme.c:5274 ../src/ui/theme.c:5281 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "ไม่ได้กำหนดค่า <%s> สำหรับชุดตกแต่ง \"%s\"" - -#: ../src/ui/theme.c:5289 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" -"ไม่ได้กำหนดรูปแบบเฟรมสำหรับชนิดหน้าต่าง \"%s\" ในชุดตกแต่ง \"%s\", กรุณาเพิ่มอิลิเมนต์ " -"<window type=\"%s\" style_set=\"อะไรก็ตามแต่\"/>" - -#: ../src/ui/theme.c:5728 ../src/ui/theme.c:5790 ../src/ui/theme.c:5853 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "ค่าคงที่ที่ผู้ใช้กำหนดเองต้องเริ่มต้นด้วยอักษรตัวใหญ่; แต่ \"%s\" ไม่ได้เป็นตามนั้น" - -#: ../src/ui/theme.c:5736 ../src/ui/theme.c:5798 ../src/ui/theme.c:5861 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "ค่าคงที่ \"%s\" ถูกกำหนดไว้แล้ว" - -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. -#. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "ขาดแอตทริบิวต์ \"%s\" ในอิลิเมนต์ <%s>" - -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "บรรทัด %d อักขระ %d: %s" - -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "มีแอตทริบิวต์ \"%s\" ซ้ำสองอันในอิลิเมนต์ <%s> เดียวกัน" - -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "ใช้แอตทริบิวต์ \"%s\" ในอิลิเมนต์ <%s> ไม่ได้ตรงนี้" - -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "ไม่สามารถแปลง \"%s\" เป็นเลขจำนวนเต็ม" - -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "ไม่เข้าใจตัวอักษร \"%s\" ที่ข้างท้ายข้อความ \"%s\"" - -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "จำนวนเต็ม %ld ต้องเป็นบวก" - -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "จำนวนเต็ม %ld ใหญ่เกินไป ตั้งได้สูงสุดเป็น %d" - -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "แปลง \"%s\" เป็นเลขจุดทศนิยมไม่สำเร็จ" - -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "ค่าตรรกะต้องเป็น \"true\" หรือ \"false\" ไม่ใช่ \"%s\"" - -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "มุมต้องอยู่ระหว่าง 0.0 และ 360.0 ไม่ใช่ %g\n" - -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "ค่าอัลฟาต้องอยู่ระหว่าง 0.0 (โปร่งใส) และ 1.0 (ทึบ) ไม่ใช่ %g\n" - -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"ขนาดหัวหน้าต่าง \"%s\" ใช้ไม่ได้ ตั้งได้เป็น xx-small, x-small, small, medium, large, " -"x-large, หรือ xx-large\n" - -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s> ชื่อ \"%s\" ถูกใช้เป็นครั้งที่สอง" - -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "<%s>: พาเรนต์ \"%s\" ไม่ได้ระบุ" - -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "<%s>: ค่าเรขาคณิต \"%s\" ไม่ได้ระบุ" - -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "<%s> ต้องกำหนดตำแหน่งและขนาด หรือพาเรนต์ที่มี่ตำแหน่งขนาด" - -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "คุณต้องกำหนดสีพื้นหลังเพื่อให้ค่าอัลฟามีความหมาย" - -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "ไม่รู้จักชนิด \"%s\" สำหรับอิลิเมนต์ <%s>" - -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "ไม่รู้จัก style_set \"%s\" สำหรับอิลิเมนต์ <%s>" - -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "ชนิดหน้าต่าง \"%s\" ถูกตั้ง style set ไว้อยู่แล้ว" - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "ไม่อนุญาตให้มีอิลิเมนต์ <%s> ภายใน <%s>" - -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" -msgstr "" -"ไม่สามารถกำหนดทั้ง \"button_width\"/\"button_height\" กับ \"aspect_ratio\" " -"ของปุ่มพร้อมกันได้" - -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "ไม่รู้จักระยะทาง \"%s\"" - -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "ไม่รู้จัก aspect ratio \"%s\"" - -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "ไม่รู้จักเส้นขอบ \"%s\"" - -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "ขาดแอตทริบิวต์ \"start_angle\" หรือ \"from\" ในอิลิเมนต์ <%s>" - -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "ขาดแอตทริบิวต์ \"extent_angle\" หรือ \"to\" ในอิลิเมนต์ <%s>" - -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "ไม่เข้าใจค่า \"%s\" สำหรับชนิดของการไล่ระดับสี" - -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "ไม่เข้าใจชนิดการเติม \"%s\" สำหรับอิลิเมนต์ <%s>" - -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "ไม่เข้าใจค่า state \"%s\" สำหรับอิลิเมนต์ <%s>" - -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "ไม่เข้าใจค่า shadow \"%s\" สำหรับอิลิเมนต์ <%s>" - -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "ไม่เข้าใจค่า arrow \"%s\" สำหรับอิลิเมนต์ <%s>" - -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "ไม่มี <draw_ops> ที่ชื่อ \"%s\" กำหนดไว้" - -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "การรวม draw_ops \"%s\" ที่นี่จะทำให้เกิดการอ้างอิงแบบวนรอบ" - -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "ไม่รู้จักค่า position \"%s\" สำหรับชิ้นส่วนเฟรม" - -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "มีรูปแบบเฟรมที่ตำแหน่ง %s อยู่ก่อนแล้ว" - -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "ยังไม่ได้กำหนด <draw_ops> ชื่อ \"%s\"" - -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "ไม่รู้จักฟังก์ชัน \"%s\" สำหรับปุ่ม" - -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "ไม่มีฟังก์ชันปุ่ม \"%s\" ในรุ่นนี้ (%d, ต้องเป็นรุ่น %d ขึ้นไป)" - -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "ไม่รู้สถานะ \"%s\" สำหรับปุ่ม" - -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "รูปแบบเฟรมมีปุ่มสำหรับฟังก์ชัน %s สถานะ %s อยู่ก่อนแล้ว" - -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "\"%s\" ไม่ใช่ค่าที่ใช้ได้สำหรับแอตทริบิวต์ focus" - -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "\"%s\" ไม่ใช่ค่าที่ใช้ได้สำหรับแอตทริบิวต์ state" - -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "ไม่มีรูปแบบที่ชื่อ \"%s\" กำหนดไว้" - -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "\"%s\" ไม่ใช่ค่าที่ใช้ได้สำหรับแอตทริบิวต์ resize" - -#: ../src/ui/theme-parser.c:3147 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "ไม่ควรมีแอตทริบิวต์ \"resize\" ในอิลิเมนต์ <%s> สำหรับสถานะขยายแผ่/ม้วนเก็บ" - -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "ไม่ควรมีแอตทริบิวต์ \"resize\" ในอิลิเมนต์ <%s> สำหรับสถานะขยายแผ่" - -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "มีรูปแบบสำหรับ state %s resize %s focus %s กำหนดไว้ก่อนแล้ว" - -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "มีรูปแบบสำหรับ state %s focus %s กำหนดไว้ก่อนแล้ว" - -#: ../src/ui/theme-parser.c:3294 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"ไม่สามารถมี draw_ops ซ้อนกันสองค่าสำหรับอิลิเมนต์ <piece> " -"(ชุดตกแต่งอาจมีการกำหนดทั้งแอตทริบิวต์ draw_ops และอิลิเมนต์ <draw_ops> " -"หรือไม่ก็กำหนดอิลิเมนต์ซ้อนกันสองตัว)" - -#: ../src/ui/theme-parser.c:3332 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"ไม่สามารถมี draw_ops ซ้อนกันสองค่าสำหรับอิลิเมนต์ <button> " -"(ชุดตกแต่งอาจมีการกำหนดทั้งแอตทริบิวต์ draw_ops และอิลิเมนต์ <draw_ops> " -"หรือไม่ก็กำหนดอิลิเมนต์ซ้อนกันสองตัว)" - -#: ../src/ui/theme-parser.c:3370 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"ไม่สามารถมี draw_ops ซ้อนกันสองค่าสำหรับอิลิเมนต์ <menu_icon> " -"(ชุดตกแต่งอาจมีการกำหนดทั้งแอตทริบิวต์ draw_ops และอิลิเมนต์ <draw_ops> " -"หรือไม่ก็กำหนดอิลิเมนต์ซ้อนกันสองตัว)" - -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "การกำหนดรุ่น '%s' ไม่ถูกต้อง" - -#: ../src/ui/theme-parser.c:3507 -msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" -msgstr "" -"ไม่สามารถใช้แอตทริบิวต์ \"version\" ใน metacity-theme-1.xml หรือ metacity-theme-2." -"xml" - -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "ชุดตกแต่งต้องการรุ่น %s แต่รุ่นสูงสุดที่ระบบนี้รองรับคือ %d.%d" - -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "อิลิเมนต์ชั้นนอกสุดของชุดตกแต่งต้องเป็น <metacity_theme> ไม่ใช่ <%s>" - -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "ไม่อนุญาตให้มีอิลิเมนต์ <%s> ภายในอิลิเมนต์ name/author/date/description" - -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "ไม่อนุญาตให้มีอิลิเมนต์ <%s> ภายในอิลิเมนต์ <constant>" - -#: ../src/ui/theme-parser.c:3599 -#, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "ไม่อนุญาตให้มีอิลิเมนต์ <%s> ภายในอิลิเมนต์ distance/border/aspect_ratio" - -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "ไม่อนุญาตให้มีอิลิเมนต์ <%s> ภายในอิลิเมนต์เกี่ยวกับคำสั่งวาด" - -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "ไม่อนุญาตให้มีอิลิเมนต์ <%s> ภายในอิลิเมนต์ <%s>" - -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "ขาด draw_ops สำหรับชิ้นส่วนเฟรม" - -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "ขาด draw_ops สำหรับปุ่ม" - -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "ไม่อนุญาตให้มีข้อความภายในอิลิเมนต์ <%s>" - -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "<%s> ถูกระบุซ้ำในชุดตกแต่งนี้" - -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "หาแฟ้มที่ใช้การได้สำหรับชุดตกแต่ง %s ไม่พบ\n" - -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "_หน้าต่าง" - -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "_กล่องโต้ตอบ" - -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "กล่องโต้ตอบแบบโ_มดัล" - -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "_อรรถประโยชน์" - -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "_ภาพเริ่มโปรแกรม" - -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "Dock ด้าน_บน" - -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "Dock ด้าน_ล่าง" - -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "Dock ด้านซ้า_ย" - -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "Dock ด้าน_ขวา" - -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "Dock _ทั้งหมด" - -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "_พื้นโต๊ะ" - -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "เปิดหน้าต่างอย่างนี้อีกบาน" - -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "นี่เป็นปุ่มตัวอย่างพร้อมกับไอคอน 'เปิด'" - -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "นี่เป็นปุ่มตัวอย่างพร้อมกับไอคอน 'ออก'" - -#: ../src/ui/theme-viewer.c:253 -msgid "This is a sample message in a sample dialog" -msgstr "นี่เป็นข้อความตัวอย่างในกล่องโต้ตอบตัวอย่าง" - -#: ../src/ui/theme-viewer.c:336 -#, c-format -msgid "Fake menu item %d\n" -msgstr "รายการเมนูตัวอย่าง %d\n" - -#: ../src/ui/theme-viewer.c:371 -msgid "Border-only window" -msgstr "หน้าต่างที่มีแต่ขอบ" - -#: ../src/ui/theme-viewer.c:373 -msgid "Bar" -msgstr "แถบ" - -#: ../src/ui/theme-viewer.c:390 -msgid "Normal Application Window" -msgstr "หน้าต่างโปรแกรมปกติ" - -#: ../src/ui/theme-viewer.c:394 -msgid "Dialog Box" -msgstr "กล่องโต้ตอบ" - -#: ../src/ui/theme-viewer.c:398 -msgid "Modal Dialog Box" -msgstr "กล่องโต้ตอบแบบโมดัล" - -#: ../src/ui/theme-viewer.c:402 -msgid "Utility Palette" -msgstr "แผงอุปกรณ์" - -#: ../src/ui/theme-viewer.c:406 -msgid "Torn-off Menu" -msgstr "เมนูที่ฉีกออกมา" - -#: ../src/ui/theme-viewer.c:410 -msgid "Border" -msgstr "ขอบ" - -#: ../src/ui/theme-viewer.c:414 -msgid "Attached Modal Dialog" -msgstr "กล่องโต้ตอบแบบโมดัลแบบแนบ" - -#: ../src/ui/theme-viewer.c:747 -#, c-format -msgid "Button layout test %d" -msgstr "ทดสอบการเรียงปุ่มครั้งที่ %d" - -#: ../src/ui/theme-viewer.c:776 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "ใช้เวลา %g มิลลิวินาทีในการวาดหนึ่งเฟรมหน้าต่าง" - -#: ../src/ui/theme-viewer.c:821 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "วิธีใช้: metacity-theme-viewer [ชื่อชุดตกแต่ง]\n" - -#: ../src/ui/theme-viewer.c:828 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "ไม่สามารถโหลดชุดตกแต่ง: %s\n" - -#: ../src/ui/theme-viewer.c:834 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "อ่านชุดตกแต่ง \"%s\" เสร็จใน %g วินาที\n" - -#: ../src/ui/theme-viewer.c:878 -msgid "Normal Title Font" -msgstr "อักษรหัวหน้าต่างปกติ" - -#: ../src/ui/theme-viewer.c:884 -msgid "Small Title Font" -msgstr "อักษรหัวหน้าต่างเล็ก" - -#: ../src/ui/theme-viewer.c:890 -msgid "Large Title Font" -msgstr "อักษรหัวหน้าต่างใหญ่" - -#: ../src/ui/theme-viewer.c:895 -msgid "Button Layouts" -msgstr "การจัดเรียงปุ่ม" - -#: ../src/ui/theme-viewer.c:900 -msgid "Benchmark" -msgstr "ความเร็ว" - -#: ../src/ui/theme-viewer.c:952 -msgid "Window Title Goes Here" -msgstr "ชื่อหน้าต่างอยู่ตรงนี้" - -#: ../src/ui/theme-viewer.c:1055 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"วาด %d เฟรม โดยใช้เวลาที่ไคลเอนท์ทั้งหมด %g วินาที (%g มิลลิวินาทีต่อเฟรม) และ %g " -"วินาทีตามเวลานาฬิกาจริงซึ่งรวมการติดต่อกับ X เซิร์ฟเวอร์ด้วย (%g มิลลิวินาทีต่อเฟรม)\n" - -#: ../src/ui/theme-viewer.c:1274 -msgid "position expression test returned TRUE but set error" -msgstr "การทดสอบนิพจน์ตำแหน่งให้ค่าจริง แต่มีรหัสข้อผิดพลาด" - -#: ../src/ui/theme-viewer.c:1276 -msgid "position expression test returned FALSE but didn't set error" -msgstr "การทดสอบนิพจน์ตำแหน่งให้ค่าเท็จ แต่ไม่มีรหัสข้อผิดพลาด" - -#: ../src/ui/theme-viewer.c:1280 -msgid "Error was expected but none given" -msgstr "คาดหวังว่าจะเจอข้อผิดพลาด แต่ก็ไม่มีข้อมูล" - -#: ../src/ui/theme-viewer.c:1282 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "คาดหวังว่าจะเจอข้อผิดพลาด %d แต่พบข้อผิดพลาด %d แทน" - -#: ../src/ui/theme-viewer.c:1288 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "ไม่ได้คาดหวังว่าจะเจอข้อผิดพลาด แต่กลับมี: %s" - -#: ../src/ui/theme-viewer.c:1292 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "ค่าของ x เป็น %d แต่ที่คาดหวังไว้น่าจะเป็น %d" - -#: ../src/ui/theme-viewer.c:1295 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "ค่าของ y เป็น %d แต่ที่คาดหวังไว้น่าจะเป็น %d" - -#: ../src/ui/theme-viewer.c:1360 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "แจงค่านิพจน์พิกัดทั้งหมด %d นิพจน์ ในเวลา %g วินาที (%g วินาทีโดยเฉลี่ย)\n" - -#~ msgid "Window Management" -#~ msgstr "การจัดการหน้าต่าง" - -#~ msgid "Failed to parse message \"%s\" from dialog process\n" -#~ msgstr "ไม่เข้าใจข้อความ \"%s\" จากโพรเซสกล่องโต้ตอบ\n" - -#~ msgid "Error reading from dialog display process: %s\n" -#~ msgstr "เกิดข้อผิดพลาดขณะอ่านจากโพรเซสกล่องโต้ตอบ: %s\n" - -#~ msgid "" -#~ "Error launching metacity-dialog to ask about killing an application: %s\n" -#~ msgstr "เกิดข้อผิดพลาด ขณะเปิดหน้าต่าง ถามการฆ่าโปรแกรม: %s\n" - -#~ msgid "Failed to get hostname: %s\n" -#~ msgstr "ไม่สามารถอ่านชื่อโฮสต์: %s\n" - -#~ msgid "" -#~ "Lost connection to the display '%s';\n" -#~ "most likely the X server was shut down or you killed/destroyed\n" -#~ "the window manager.\n" -#~ msgstr "" -#~ "ขาดการติดต่อจากดิสเพลย์ '%s';\n" -#~ "X เซิร์ฟเวอร์อาจจะถูกปิด หรือคุณอาจฆ่าโปรแกรมจัดการหน้าต่างไป\n" - -#~ msgid "Fatal IO error %d (%s) on display '%s'.\n" -#~ msgstr "เกิดข้อผิดพลาดร้ายแรง %d (%s) ในการอ่านเขียนข้อมูลจากดิสเพลย์'%s'\n" - -#~ msgid "Turn compositing on" -#~ msgstr "เปิดใช้การ composite" - -#~ msgid "Turn compositing off" -#~ msgstr "ปิดการ composite" - -#~ msgid "Failed to restart: %s\n" -#~ msgstr "ไม่สามารถเริ่มการทำงานใหม่ของ: %s\n" - -#~ msgid "" -#~ "The format looks like \"<Control>a\" or <Shift><Alt>F1\".\n" -#~ "\n" -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "รูปแบบจะคล้ายกับ \"<Control>a\" หรือ \"<Shift><Alt>F1\"\n" -#~ "\n" -#~ "ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ \"<Ctrl>" -#~ "\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The format looks like \"<Control>a\" or <Shift><Alt>F1\".\n" -#~ "\n" -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action.\n" -#~ "\n" -#~ "This keybinding may be reversed by holding down the \"shift\" key; " -#~ "therefore, \"shift\" cannot be one of the keys it uses." -#~ msgstr "" -#~ "รูปแบบจะคล้ายกับ \"<Control>a\" หรือ \"<Shift><Alt>F1\"\n" -#~ "\n" -#~ "ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ \"<Ctrl>" -#~ "\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้\n" -#~ "\n" -#~ "ปุ่มลัดนี้สามารถย้อนคืนได้ด้วยการกดปุ่ม \"shift\" ค้างไว้; ดังนั้น จึงไม่สามารถใช้ \"shift\" " -#~ "ประกอบในปุ่มลัดที่ตั้งนี้ได้" - -#~ msgid "Failed to read saved session file %s: %s\n" -#~ msgstr "ไม่สามารถอ่านแฟ้มวาระที่บันทึกไว้ %s: %s\n" - -#~ msgid "" -#~ "Error launching metacity-dialog to warn about apps that don't support " -#~ "session management: %s\n" -#~ msgstr "" -#~ "ไม่สามารถเปิดกล่องโต้ตอบ เพื่อเตือนเกี่ยวกับโปรแกรมซึ่งไม่รองรับการจัดการวาระ: %s\n" - -#~ msgid "Metacity" -#~ msgstr "Metacity" - -#~ msgid "" -#~ "(Not implemented) Navigation works in terms of applications not windows" -#~ msgstr "(ยังใช้ไม่ได้) เคลื่อนย้ายระหว่างโปรแกรม แทนระหว่างหน้าต่าง" - -#~ msgid "" -#~ "A font description string describing a font for window titlebars. The " -#~ "size from the description will only be used if the titlebar_font_size " -#~ "option is set to 0. Also, this option is disabled if the " -#~ "titlebar_uses_desktop_font option is set to true." -#~ msgstr "" -#~ "คำบรรยายแบบอักษรสำหรับแถบหัวเรื่องของหน้าต่าง " -#~ "ขนาดตัวอักษรในคำบรรยายนี้จะมีผลก็ต่อเมื่อตัวเลือก titlebar_font_size มีค่าเป็น 0 " -#~ "นอกจากนี้ ค่าตัวเลือกนี้จะไม่มีผลถ้าตัวเลือก titlebar_uses_desktop_font มีค่าเป็นจริง" - -#~ msgid "Action on title bar double-click" -#~ msgstr "การกระทำเมื่อดับเบิลคลิกที่แถบหัวหน้าต่าง" - -#~ msgid "Action on title bar middle-click" -#~ msgstr "การกระทำเมื่อคลิกเมาส์ปุ่มกลางที่แถบหัวหน้าต่าง" - -#~ msgid "Action on title bar right-click" -#~ msgstr "การกระทำเมื่อคลิกเมาส์ปุ่มขวาที่แถบหัวหน้าต่าง" - -#~ msgid "Arrangement of buttons on the titlebar" -#~ msgstr "การจัดเรียงปุ่มบนแถบหัวหน้าต่าง" - -#~ msgid "" -#~ "Arrangement of buttons on the titlebar. The value should be a string, " -#~ "such as \"menu:minimize,maximize,spacer,close\"; the colon separates the " -#~ "left corner of the window from the right corner, and the button names are " -#~ "comma-separated. Duplicate buttons are not allowed. Unknown button names " -#~ "are silently ignored so that buttons can be added in future metacity " -#~ "versions without breaking older versions. A special spacer tag can be " -#~ "used to insert some space between two adjacent buttons." -#~ msgstr "" -#~ "การจัดเรียงปุ่มบนแถบหัวหน้าต่าง ค่าของคีย์ควรเป็นข้อความ ตัวอย่างเช่น \"menu:minimize," -#~ "maximize,spacer,close\" โดย colon จะแบ่งมุมซ้ายกับมุมขวาของหน้าต่างออกจากกัน " -#~ "และปุ่มต่างๆ จะคั่นด้วยจุลภาค ห้ามใช้ปุ่มซ้ำกัน ปุ่มที่ไม่รู้จักจะถูกข้ามไป " -#~ "เพื่อรองรับการเพิ่มปุ่มใหม่ในอนาคตได้โดยไม่ขัดกับ metacity รุ่นเก่า คุณสามารถใช้แท็กพิเศษ " -#~ "\"spacer\" ในการแทรกช่องว่างระหว่างปุ่มที่อยู่ติดกันได้" - -#~ msgid "Automatically raises the focused window" -#~ msgstr "ยกหน้าต่างที่ถูกโฟกัสขึ้นมาด้านหน้าโดยอัตโนมัติ" - -#~ msgid "" -#~ "Clicking a window while holding down this modifier key will move the " -#~ "window (left click), resize the window (middle click), or show the window " -#~ "menu (right click). The left and right operations may be swapped using " -#~ "the \"mouse_button_resize\" key. Modifier is expressed as \"<Alt>\" " -#~ "or \"<Super>\" for example." -#~ msgstr "" -#~ "การคลิกเมาส์บนหน้าต่างพร้อมกับกดปุ่ม modifier นี้ค้างไว้จะเริ่มย้ายหน้าต่าง (ปุ่มซ้าย) " -#~ "เปลี่ยนขนาดหน้าต่าง (ปุ่มกลาง) หรือแสดงเมนูหน้าต่าง (ปุ่มขวา) " -#~ "การใช้ปุ่มกลางหรือขวาอาจสลับได้โดยใช้คีย์ \"resize_with_right_button\" " -#~ "ตัวอย่างการระบุปุ่ม modifier: \"<Alt>\" or \"<Super>\"" - -#~ msgid "Commands to run in response to keybindings" -#~ msgstr "คำสั่งที่จะกระทำเมื่อมีการกดปุ่มตาม keybinding ที่กำหนด" - -#~ msgid "Compositing Manager" -#~ msgstr "จัดการ Composite" - -#~ msgid "Control how new windows get focus" -#~ msgstr "ควบคุมการโฟกัสหน้าต่างใหม่" - -#~ msgid "Current theme" -#~ msgstr "ธีมปัจจุบัน" - -#~ msgid "Delay in milliseconds for the auto raise option" -#~ msgstr "การหน่วงเวลาในหน่วยมิลลิวินาทีสำหรับการยกหน้าต่างมาด้านหน้าโดยอัตโนมัติ" - -#~ msgid "Determines whether Metacity is a compositing manager." -#~ msgstr "กำหนดว่า จะให้ Metacity เป็นผู้จัดการ composite หรือไม่" - -#~ msgid "" -#~ "Determines whether applications or the system can generate audible " -#~ "'beeps'; may be used in conjunction with 'visual bell' to allow silent " -#~ "'beeps'." -#~ msgstr "" -#~ "ระบุว่าจะให้โปรแกรมหรือระบบส่งเสียง 'บี๊ป' หรือไม่ สามารถใช้ร่วมกับ 'ระฆังภาพ' เพื่อใช้ " -#~ "'บี๊ป' แบบเงียบได้" - -#~ msgid "Disable misfeatures that are required by old or broken applications" -#~ msgstr "ปิดคุณสมบัติแก้ขัดที่แก้ปัญหาให้กับโปรแกรมประยุกต์ที่เก่าหรือไม่ทำงาน" - -#~ msgid "Enable Visual Bell" -#~ msgstr "ใช้ระฆังภาพ" - -#~ msgid "" -#~ "If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " -#~ "the focused window will be automatically raised after a delay specified " -#~ "by the auto_raise_delay key. This is not related to clicking on a window " -#~ "to raise it, nor to entering a window during drag-and-drop." -#~ msgstr "" -#~ "ถ้ามีค่าเป็นจริง และโหมดโฟกัสเป็น \"sloppy\" หรือ \"mouse\" อย่างใดอย่างหนึ่งแล้ว " -#~ "จะยกหน้าต่างที่ได้โฟกัสขึ้นมาโดยอัตโนมัติ หลังจากหน่วงเวลาเป็นระยะเวลาตามที่ระบุในคีย์ " -#~ "auto_raise_delay การยกหน้าต่างดังกล่าว ไม่เกี่ยวกับการคลิกบนหน้าต่างเพื่อยกหน้าต่างขึ้น " -#~ "หรือการเลื่อนเมาส์เข้าสู่หน้าต่างระหว่างการลากวางแต่อย่างใด" - -#~ msgid "" -#~ "If true, ignore the titlebar_font option, and use the standard " -#~ "application font for window titles." -#~ msgstr "" -#~ "ถ้าเป็นจริง จะละเว้นตัวเลือก titlebar_font และใช้แบบอักษรมาตรฐาน " -#~ "สำหรับแถบหัวเรื่องของหน้าต่าง" - -#~ msgid "" -#~ "If true, metacity will give the user less feedback by using wireframes, " -#~ "avoiding animations, or other means. This is a significant reduction in " -#~ "usability for many users, but may allow legacy applications to continue " -#~ "working, and may also be a useful tradeoff for terminal servers. However, " -#~ "the wireframe feature is disabled when accessibility is on." -#~ msgstr "" -#~ "ถ้าเป็นจริง metacity จะตอบสนองผู้ใช้น้อยลง โดยใช้ wireframe ใช้ภาพเคลื่อนไหวน้อยลง " -#~ "หรืออะไรก็ตาม ซึ่งอาจดูใช้ยากขึ้นสำหรับผู้ใช้หลายๆ คน แต่จะช่วยให้โปรแกรมเก่าๆ ยังทำงานได้ " -#~ "และอาจช่วยให้การใช้เทอร์มินัลเซิร์ฟเวอร์คล่องตัวขึ้น อย่างไรก็ดี metacity จะไม่ใช้ " -#~ "wireframe เมื่อเปิดระบบอำนวยการใช้งาน" - -#~ msgid "" -#~ "If true, then Metacity works in terms of applications rather than " -#~ "windows. The concept is a bit abstract, but in general an application-" -#~ "based setup is more like the Mac and less like Windows. When you focus a " -#~ "window in application-based mode, all the windows in the application will " -#~ "be raised. Also, in application-based mode, focus clicks are not passed " -#~ "through to windows in other applications. Application-based mode is, " -#~ "however, largely unimplemented at the moment." -#~ msgstr "" -#~ "ถ้าเป็นจริง Metacity จะทำงานในหน่วยของโปรแกรมประยุกต์แทนหน่วยของหน้าต่าง " -#~ "แนวคิดนี้ค่อนข้างเป็นนามธรรม แต่โดยทั่วไปการตั้งค่าแบบนี้จะคล้าย Mac และต่างจากวินโดวส์ " -#~ "เมื่อคุณโฟกัสหน้าต่างหนึ่งในโหมดโปรแกรมประยุกต์ " -#~ "หน้าต่างทั้งหมดในโปรแกรมประยุกต์เดียวกันจะถูกยกขึ้นพร้อมกัน นอกจากนี้ " -#~ "ในโหมดโปรแกรมประยุกต์นี้ " -#~ "การคลิกเพื่อโฟกัสจะไม่ถูกส่งผ่านไปยังหน้าต่างของโปรแกรมประยุกต์อื่นด้วย อย่างไรก็ดี " -#~ "โหมดโปรแกรมประยุกต์ยังใช้การไม่ได้ในขณะนี้" - -#~ msgid "If true, trade off usability for less resource usage" -#~ msgstr "ถ้าตั้ง จะสละความง่ายในการใช้เพื่อประหยัดทรัพยากร" - -#~ msgid "Name of workspace" -#~ msgstr "ชื่อของพื้นที่ทำงาน" - -#~ msgid "Number of workspaces" -#~ msgstr "จำนวนพื้นที่ทำงาน" - -#~ msgid "" -#~ "Number of workspaces. Must be more than zero, and has a fixed maximum to " -#~ "prevent making the desktop unusable by accidentally asking for too many " -#~ "workspaces." -#~ msgstr "" -#~ "จำนวนพื้นที่ทำงาน ต้องมากกว่าศูนย์ และมีขีดจำกัดตายตัวอยู่ " -#~ "เพื่อป้องกันการทำให้เดสก์ท็อปใช้การไม่ได้ด้วยการร้องขอพื้นที่ทำงานมากเกินไปโดยไม่เจตนา" - -#~ msgid "Run a defined command" -#~ msgstr "เรียกใช้คำสั่งที่กำหนดไว้" - -#~ msgid "" -#~ "Set this to true to resize with the right button and show a menu with the " -#~ "middle button while holding down the key given in \"mouse_button_modifier" -#~ "\"; set it to false to make it work the opposite way around." -#~ msgstr "" -#~ "กำหนดค่านี้เป็นจริงหากต้องการให้ใช้เมาส์ปุ่มขวาปรับขนาดหน้าต่าง และใช้ปุ่มกลางเปิดเมนู " -#~ "ในขณะที่กดปุ่มที่กำหนดใน \"mouse_button_modifier\" ค้างไว้; " -#~ "กำหนดค่านี้เป็นเท็จถ้าต้องการให้ทำในทางกลับกัน" - -#~ msgid "" -#~ "Setting this option to false can lead to buggy behavior, so users are " -#~ "strongly discouraged from changing it from the default of true. Many " -#~ "actions (e.g. clicking in the client area, moving or resizing the window) " -#~ "normally raise the window as a side-effect. Setting this option to false, " -#~ "which is strongly discouraged, will decouple raising from other user " -#~ "actions, and ignore raise requests generated by applications. See http://" -#~ "bugzilla.gnome.org/show_bug.cgi?id=445447#c6. Even when this option is " -#~ "false, windows can still be raised by an alt-left-click anywhere on the " -#~ "window, a normal click on the window decorations, or by special messages " -#~ "from pagers, such as activation requests from tasklist applets. This " -#~ "option is currently disabled in click-to-focus mode. Note that the list " -#~ "of ways to raise windows when raise_on_click is false does not include " -#~ "programmatic requests from applications to raise windows; such requests " -#~ "will be ignored regardless of the reason for the request. If you are an " -#~ "application developer and have a user complaining that your application " -#~ "does not work with this setting disabled, tell them it is _their_ fault " -#~ "for breaking their window manager and that they need to change this " -#~ "option back to true or live with the \"bug\" they requested." -#~ msgstr "" -#~ "การกำหนดตัวเลือกนี้เป็นเท็จ อาจทำให้การทำงานผิดพลาด ดังนั้น " -#~ "จึงไม่ขอแนะนำให้เปลี่ยนค่าจากค่าปกติที่เป็นค่าจริง โดยปกติ ปฏิบัติการหลายอย่าง (เช่น " -#~ "การคลิกบนพื้นที่ภายในหน้าต่าง การย้ายหรือปรับขนาดหน้าต่าง) จะยกหน้าต่างขึ้นด้วย " -#~ "ถ้ากำหนดตัวเลือกนี้เป็นเท็จ ซึ่งไม่ขอแนะนำเป็นอย่างยิ่ง จะไม่ยกหน้าต่างเมื่อมีปฏิสัมพันธ์กับผู้ใช้ " -#~ "และจะไม่สนใจการร้องขอให้ยกหน้าต่างขึ้นจากโปรแกรมต่างๆ ดู http://bugzilla.gnome.org/" -#~ "show_bug.cgi?id=445447#c6 แต่แม้ตัวเลือกนี้จะเป็นเท็จ ก็ยังสามารถยกหน้าต่างขึ้นได้โดย " -#~ "alt-คลิกซ้าย ภายในพื้นที่หน้าต่าง หรือคลิกแบบธรรมดาที่กรอบหน้าต่าง " -#~ "หรือโดยข้อความพิเศษจากโปรแกรมจัดหน้าพื้นโต๊ะ เช่น " -#~ "การร้องขอกระตุ้นหน้าต่างจากแอพเพล็ตรายการงาน ขณะนี้ " -#~ "ตัวเลือกนี้จะไม่มีผลถ้าอยู่ในโหมดโฟกัสด้วยการคลิก สังเกตว่า วิธีการต่างๆ ที่จะยกหน้าต่างขึ้นเมื่อ " -#~ "raise_on_click เป็นเท็จนี้ ไม่นับรวมการร้องขอจากโปรแกรมเพื่อขอยกหน้าต่างขึ้น " -#~ "การร้องขอดังกล่าวจะถูกปฏิเสธไม่ว่ากรณีใดๆ ถ้าคุณเป็นนักพัฒนาโปรแกรม " -#~ "และมีผู้ใช้บ่นว่าโปรแกรมของคุณทำงานผิดพลาดเมื่อปิดค่านี้ ก็บอกเขาได้เลย ว่าเป็นความผิด " -#~ "_ของเขาเอง_ ที่ทำให้โปรแกรมจัดการหน้าต่างรวน และเขาต้องเปลี่ยนตัวเลือกนี้กลับเป็นค่าจริง " -#~ "มิฉะนั้น ก็จะต้องอยู่กับ \"บั๊ก\" ที่เขาเรียกร้องต่อไป" - -#~ msgid "" -#~ "Some applications disregard specifications in ways that result in window " -#~ "manager misfeatures. This option puts Metacity in a rigorously correct " -#~ "mode, which gives a more consistent user interface, provided one does not " -#~ "need to run any misbehaving applications." -#~ msgstr "" -#~ "โปรแกรมบางตัวไม่สนใจข้อกำหนด โดยทำให้โปรแกรมจัดการหน้าต่างต้องทำงานแก้ขัด " -#~ "ตัวเลือกนี้จะกำหนดให้ Metacity เข้าสู่โหมดการทำงานที่ถูกหลักเกณฑ์อย่างเข้มงวด " -#~ "ซึ่งจะทำให้การติดต่อผู้ใช้คงเส้นคงวายิ่งขึ้น โดยถือว่าผู้ใช้ไม่จำเป็นต้องเรียกโปรแกรมใดๆ " -#~ "ที่ประพฤติผิดหลักเกณฑ์" - -#~ msgid "System Bell is Audible" -#~ msgstr "เปิดเล่นเสียงระฆังระบบ" - -#~ msgid "" -#~ "Tells Metacity how to implement the visual indication that the system " -#~ "bell or another application 'bell' indicator has been rung. Currently " -#~ "there are two valid values, \"fullscreen\", which causes a fullscreen " -#~ "white-black flash, and \"frame_flash\" which causes the titlebar of the " -#~ "application which sent the bell signal to flash. If the application which " -#~ "sent the bell is unknown (as is usually the case for the default \"system " -#~ "beep\"), the currently focused window's titlebar is flashed." -#~ msgstr "" -#~ "บอก metacity " -#~ "ว่าจะแสดงออกทางจอภาพอย่างไรเมื่อมีการสั่นระฆังของระบบหรือโปรแกรมประยุกต์ ค่าที่เป็นไปได้ " -#~ "ณ ขณะนี้มีสองค่า คือ \"fullscreen\" ซึ่งจะวาบจอภาพทั้งจอ และ \"frame_flash\" " -#~ "ซึ่งจะวาบแถบหัวหน้าต่างของโปรแกรมที่สั่นระฆัง หรือถ้าไม่ปรากฏโปรแกรมที่สั่นระฆัง " -#~ "(ซึ่งเป็นปกติสำหรับ \"เสียงบี๊ปของระบบ\") ก็จะวาบแถบหัวหน้าต่างของโปรแกรมที่ได้โฟกัสอยู่" - -#~ msgid "" -#~ "The /apps/metacity/global_keybindings/run_command_N keys define " -#~ "keybindings that correspond to these commands. Pressing the keybinding " -#~ "for run_command_N will execute command_N." -#~ msgstr "" -#~ "กำหนดคำสั่งที่จะเรียกจากการกดปุ่มลัดที่กำหนดในคีย์ /apps/metacity/global_keybindings/" -#~ "run_command_N การกดปุ่มลัดใน run_command_N จะเรียกคำสั่ง command_N" - -#~ msgid "" -#~ "The /apps/metacity/global_keybindings/run_command_screenshot key defines " -#~ "a keybinding which causes the command specified by this setting to be " -#~ "invoked." -#~ msgstr "" -#~ "กำหนดคำสั่งที่จะเรียกจากการกดปุ่มลัดที่กำหนดในคีย์ /apps/metacity/global_keybindings/" -#~ "run_command_screenshot" - -#~ msgid "" -#~ "The /apps/metacity/global_keybindings/run_command_window_screenshot key " -#~ "defines a keybinding which causes the command specified by this setting " -#~ "to be invoked." -#~ msgstr "" -#~ "กำหนดคำสั่งที่จะเรียกจากการกดปุ่มลัดที่กำหนดในคีย์ /apps/metacity/global_keybindings/" -#~ "run_command_window_screenshot" - -#~ msgid "" -#~ "The keybinding that runs the correspondingly-numbered command in /apps/" -#~ "metacity/keybinding_commands The format looks like \"<Control>a\" " -#~ "or \"<Shift><Alt>F1\". The parser is fairly liberal and " -#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" -#~ "\" and \"<Ctrl>\". If you set the option to the special string " -#~ "\"disabled\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับเรียกคำสั่งใน /apps/metacity/keybinding_commands รูปแบบคือ \"<" -#~ "Control>a\" หรือ \"<Shift><Alt>F1\" " -#~ "ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ " -#~ "\"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ " -#~ "ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "The name of a workspace." -#~ msgstr "ชื่อของพื้นที่ทำงาน" - -#~ msgid "The screenshot command" -#~ msgstr "คำสั่งจับภาพหน้าจอ" - -#~ msgid "" -#~ "The theme determines the appearance of window borders, titlebar, and so " -#~ "forth." -#~ msgstr "ชุดตกแต่งนี้จะกำหนดลักษณะขอบหน้าต่าง หัวหน้าต่าง ฯลฯ" - -#~ msgid "" -#~ "The time delay before raising a window if auto_raise is set to true. The " -#~ "delay is given in thousandths of a second." -#~ msgstr "" -#~ "ระยะเวลารอก่อนยกหน้าต่างขึ้นมาด้านหน้า ใช้ถ้า auto_raise ถูกตั้ง ระบุเวลาเป็นมิลลิวินาที" - -#~ msgid "" -#~ "The window focus mode indicates how windows are activated. It has three " -#~ "possible values; \"click\" means windows must be clicked in order to " -#~ "focus them, \"sloppy\" means windows are focused when the mouse enters " -#~ "the window, and \"mouse\" means windows are focused when the mouse enters " -#~ "the window and unfocused when the mouse leaves the window." -#~ msgstr "" -#~ "โหมดโฟกัสหน้าต่างกำหนดวิธีการโฟกัสหน้าต่างเพื่อใช้งาน ค่าที่เป็นไปได้มีสามค่า คือ \"click\" " -#~ "หมายถึงการโฟกัสหน้าต่างด้วยการคลิก, \"sloppy\" " -#~ "หมายความว่าหน้าต่างจะได้โฟกัสก็ต่อเมื่อเมาส์เคลื่อนเข้าสู่หน้าต่าง, และ\"mouse\" " -#~ "หมายความว่าหน้าต่างจะได้โฟกัสเมื่อเมาส์เคลื่อนเข้าสู่หน้าต่าง " -#~ "และเสียโฟกัสเมื่อเมาส์เคลื่อนออกจากหน้าต่าง" - -#~ msgid "The window screenshot command" -#~ msgstr "คำสั่งจับภาพหน้าต่าง" - -#~ msgid "" -#~ "This option determines the effects of double-clicking on the title bar. " -#~ "Current valid options are 'toggle_shade', which will shade/unshade the " -#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " -#~ "will maximize/unmaximize the window in that direction only, 'minimize' " -#~ "which will minimize the window, 'shade' which will roll the window up, " -#~ "'menu' which will display the window menu, 'lower' which will put the " -#~ "window behind all the others, and 'none' which will not do anything." -#~ msgstr "" -#~ "ตัวเลือกนี้เลือกการปฏิบัติเมื่อดับเบิลคลิกที่แถบหัวหน้าต่าง ค่าตัวเลือกที่เป็นไปได้ในขณะนี้คือ " -#~ "'toggle_shade' ซึ่งจะม้วนหรือคลี่หน้าต่าง, 'toggle_maximize' " -#~ "ซึ่งจะขยายแผ่หรือยกเลิกการขยายแผ่หน้าต่างให้เต็มพื้นโต๊ะ, " -#~ "'toggle_maximize_horizontally' และ 'toggle_maximize_vertically' " -#~ "ซึ่งจะขยายแผ่หรือยกเลิกการขยายแผ่หน้าต่างในทิศทางที่กำหนดเท่านั้น, 'minimize' " -#~ "ซึ่งจะย่อเก็บหน้าต่าง, 'shade' ซึ่งจะม้วนเก็บหน้าต่าง, 'menu' ซึ่งจะแสดงเมนูหน้าต่าง, " -#~ "'lower' ซึ่งจะนำหน้าต่างลงไปอยู่หลังหน้าต่างอื่นทั้งหมด, และ 'none' ซึ่งจะไม่ทำอะไรเลย" - -#~ msgid "" -#~ "This option determines the effects of middle-clicking on the title bar. " -#~ "Current valid options are 'toggle_shade', which will shade/unshade the " -#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " -#~ "will maximize/unmaximize the window in that direction only, 'minimize' " -#~ "which will minimize the window, 'shade' which will roll the window up, " -#~ "'menu' which will display the window menu, 'lower' which will put the " -#~ "window behind all the others, and 'none' which will not do anything." -#~ msgstr "" -#~ "ตัวเลือกนี้เลือกการปฏิบัติเมื่อคลิกเมาส์ปุ่มกลางที่แถบหัวหน้าต่าง ค่าตัวเลือกที่เป็นไปได้ในขณะนี้คือ " -#~ "'toggle_shade' ซึ่งจะม้วนหรือคลี่หน้าต่าง, 'toggle_maximize' " -#~ "ซึ่งจะขยายแผ่หรือยกเลิกการขยายแผ่หน้าต่างให้เต็มพื้นโต๊ะ, " -#~ "'toggle_maximize_horizontally' และ 'toggle_maximize_vertically' " -#~ "ซึ่งจะขยายแผ่หรือยกเลิกการขยายแผ่หน้าต่างในทิศทางที่กำหนดเท่านั้น, 'minimize' " -#~ "ซึ่งจะย่อเก็บหน้าต่าง, 'shade' ซึ่งจะม้วนเก็บหน้าต่าง, 'menu' ซึ่งจะแสดงเมนูหน้าต่าง, " -#~ "'lower' ซึ่งจะนำหน้าต่างลงไปอยู่หลังหน้าต่างอื่นทั้งหมด, และ 'none' ซึ่งจะไม่ทำอะไรเลย" - -#~ msgid "" -#~ "This option determines the effects of right-clicking on the title bar. " -#~ "Current valid options are 'toggle_shade', which will shade/unshade the " -#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " -#~ "will maximize/unmaximize the window in that direction only, 'minimize' " -#~ "which will minimize the window, 'shade' which will roll the window up, " -#~ "'menu' which will display the window menu, 'lower' which will put the " -#~ "window behind all the others, and 'none' which will not do anything." -#~ msgstr "" -#~ "ตัวเลือกนี้เลือกการปฏิบัติเมื่อคลิกเมาส์ปุ่มขวาที่แถบหัวหน้าต่าง ค่าตัวเลือกที่เป็นไปได้ในขณะนี้คือ " -#~ "'toggle_shade' ซึ่งจะม้วนหรือคลี่หน้าต่าง, 'toggle_maximize' " -#~ "ซึ่งจะขยายแผ่หรือยกเลิกการขยายแผ่หน้าต่างให้เต็มพื้นโต๊ะ, " -#~ "'toggle_maximize_horizontally' และ 'toggle_maximize_vertically' " -#~ "ซึ่งจะขยายแผ่หรือยกเลิกการขยายแผ่หน้าต่างในทิศทางที่กำหนดเท่านั้น, 'minimize' " -#~ "ซึ่งจะย่อเก็บหน้าต่าง, 'shade' ซึ่งจะม้วนเก็บหน้าต่าง, 'menu' ซึ่งจะแสดงเมนูหน้าต่าง, " -#~ "'lower' ซึ่งจะนำหน้าต่างลงไปอยู่หลังหน้าต่างอื่นทั้งหมด, และ 'none' ซึ่งจะไม่ทำอะไรเลย" - -#~ msgid "" -#~ "This option provides additional control over how newly created windows " -#~ "get focus. It has two possible values; \"smart\" applies the user's " -#~ "normal focus mode, and \"strict\" results in windows started from a " -#~ "terminal not being given focus." -#~ msgstr "" -#~ "ตัวเลือกนี้เพิ่มการควบคุมการโฟกัสหน้าต่างที่สร้างใหม่ ค่าที่เป็นไปได้มีสองค่า คือ \"smart\" " -#~ "ซึ่งจะใช้วิธีโฟกัสตามปกติของผู้ใช้ และ \"strict\" ซึ่งจะไม่โฟกัสหน้าต่างที่เรียกจากเทอร์มินัล" - -#~ msgid "" -#~ "Turns on a visual indication when an application or the system issues a " -#~ "'bell' or 'beep'; useful for the hard-of-hearing and for use in noisy " -#~ "environments." -#~ msgstr "" -#~ "เปิดใช้การส่งสัญญาณทางภาพเมื่อโปรแกรมหรือระบบสั่นระฆังหรือส่งเสียงบี๊ป " -#~ "ซึ่งจะมีประโยชน์สำหรับผู้ที่มีปัญหาเรื่องการฟัง หรือใช้ในสภาวะที่จอแจ" - -#~ msgid "Use standard system font in window titles" -#~ msgstr "ใช้แบบตัวอักษรปกติของระบบสำหรับหัวหน้าต่าง" - -#~ msgid "Visual Bell Type" -#~ msgstr "ชนิดของระฆังภาพ" - -#~ msgid "Whether raising should be a side-effect of other user interactions" -#~ msgstr "กำหนดว่าควรยกหน้าต่างขึ้นเมื่อมีปฏิสัมพันธ์กับผู้ใช้หรือไม่" - -#~ msgid "Whether to resize with the right button" -#~ msgstr "กำหนดว่าจะปรับขนาดด้วยปุ่มขวาหรือไม่" - -#~ msgid "Window focus mode" -#~ msgstr "โหมดโฟกัสหน้าต่าง" - -#~ msgid "Window title font" -#~ msgstr "แบบอักษรหัวหน้าต่าง" - -#~ msgid "Title" -#~ msgstr "หัวหน้าต่าง" - -#~ msgid "Class" -#~ msgstr "คลาส" - -#~ msgid "" -#~ "There was an error running \"%s\":\n" -#~ "%s." -#~ msgstr "" -#~ "เกิดข้อผิดพลาดขณะใช้ \"%s\":\n" -#~ "%s." - -#~ msgid "<author> specified twice for this theme" -#~ msgstr "มีการระบุ <author> ซ้ำในชุดตกแต่งนี้" - -#~ msgid "<copyright> specified twice for this theme" -#~ msgstr "<copyright> ถูกระบุซ้ำในชุดตกแต่งนี้" - -#~ msgid "<date> specified twice for this theme" -#~ msgstr "<date> ถูกระบุซ้ำในชุดตกแต่งนี้" - -#~ msgid "<description> specified twice for this theme" -#~ msgstr "<description> ถูกระบุซ้ำในชุดตกแต่งนี้" - -#~ msgid "Theme file %s did not contain a root <metacity_theme> element" -#~ msgstr "แฟ้มชุดตกแต่ง %s ไม่มีอิลิเมนต์ราก <metacity_theme>" - -#~ msgid "/Windows/tearoff" -#~ msgstr "/หน้าต่าง/ฉีกออก" - -#~ msgid "/Windows/_Dialog" -#~ msgstr "/หน้าต่าง/โ_ต้ตอบ" - -#~ msgid "/Windows/_Modal dialog" -#~ msgstr "/หน้าต่าง/โต้ตอบแบบโ_มดอล" - -#~ msgid "/Windows/Des_ktop" -#~ msgstr "/หน้าต่าง/_พื้นโต๊ะ" - -#~ msgid "" -#~ "Error launching metacity-dialog to print an error about a command: %s\n" -#~ msgstr "ไม่สามารถเปิดกล่องโต้ตอบ เพื่อแสดงข้อผิดพลาดของคำสั่ง: %s\n" - -#~ msgid "" -#~ "Holding the \"shift\" key while using this binding reverses the direction " -#~ "of movement." -#~ msgstr "กดปุ่ม \"shift\" ค้างไว้ขณะกดปุ่มลัดนี้ จะเคลื่อนที่ในทิศย้อนกลับ" - -#~ msgid "" -#~ "Holding the \"shift\" key while using this binding makes the direction go " -#~ "forward again." -#~ msgstr "กดปุ่ม \"shift\" ค้างไว้ขณะกดปุ่มลัดนี้ จะเคลื่อนที่ในทิศเดิมอีกครั้ง" - -#~ msgid "Unknown attribute %s on <metacity_session> element" -#~ msgstr "ไม่รู้จักแอตทริบิวต์ %s ในอิลิเมนต์ <metacity_session>" - -#~ msgid "Unknown attribute %s on <maximized> element" -#~ msgstr "ไม่รู้จักแอตทริบิวต์ %s ในอิลิเมนต์ <maximized>" - -#~ msgid "Unknown attribute %s on <geometry> element" -#~ msgstr "ไม่รู้จักแอตทริบิวต์ %s ในอิลิเมนต์ <geometry>" - -#~ msgid "The keybinding used to activate the window menu." -#~ msgstr "ปุ่มลัดสำหรับเปิดเมนูหน้าต่าง" - -#~ msgid "The keybinding used to toggle fullscreen mode." -#~ msgstr "ปุ่มลัดสำหรับสลับโหมดเต็มหน้าจอ" - -#~ msgid "The keybinding used to toggle maximization." -#~ msgstr "ปุ่มลัดสำหรับสลับสถานะขยายเต็ม" - -#~ msgid "Toggle always on top state" -#~ msgstr "สลับการค้างอยู่บนสุด" - -#~ msgid "" -#~ "The keybinding used to toggle always on top. A window that is always on " -#~ "top will always be visible over other overlapping windows." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับสลับการค้างอยู่บนสุด หน้าต่างที่ค้างอยู่บนสุดจะปรากฏอยู่เหนือหน้าต่างอื่นๆ " -#~ "ที่ซ้อนทับกันเสมอ" - -#~ msgid "The keybinding used to maximize a window." -#~ msgstr "ปุ่มลัดสำหรับขยายหน้าต่างเต็มจอ" - -#~ msgid "Unmaximize window" -#~ msgstr "เลิกขยายแผ่หน้าต่าง" - -#~ msgid "The keybinding used to unmaximize a window." -#~ msgstr "ปุ่มลัดสำหรับเลิกขยายหน้าต่างเต็ม" - -#~ msgid "The keybinding used to toggle shaded/unshaded state." -#~ msgstr "ปุ่มลัดสำหรับม้วน/คลี่หน้าต่าง" - -#~ msgid "The keybinding used to minimize a window." -#~ msgstr "ปุ่มลัดสำหรับย่อเก็บหน้าต่าง" - -#~ msgid "The keybinding used to close a window." -#~ msgstr "ปุ่มลัดสำหรับปิดหน้าต่าง" - -#~ msgid "" -#~ "The keybinding used to enter \"move mode\" and begin moving a window " -#~ "using the keyboard." -#~ msgstr "ปุ่มลัดสำหรับเข้าสู่ \"โหมดเคลื่อนย้าย\" และเริ่มการย้ายหน้าต่างด้วยแป้นพิมพ์" - -#~ msgid "Toggle window on all workspaces" -#~ msgstr "สลับการแสดงหน้าต่างบนทุกพื้นที่ทำงาน" - -#~ msgid "The keybinding used to move a window to workspace 1." -#~ msgstr "ปุ่มลัดสำหรับย้ายหน้าต่างไปพื้นที่ทำงาน 1" - -#~ msgid "The keybinding used to move a window one workspace to the left." -#~ msgstr "ปุ่มลัดสำหรับย้ายหน้าต่างไปพื้นที่ทำงานด้านซ้าย" - -#~ msgid "The keybinding used to move a window one workspace to the right." -#~ msgstr "ปุ่มลัดสำหรับย้ายหน้าต่างไปพื้นที่ทำงานด้านขวา" - -#~ msgid "The keybinding used to move a window one workspace up." -#~ msgstr "ปุ่มลัดสำหรับย้ายหน้าต่างไปพื้นที่ทำงานด้านบน" - -#~ msgid "The keybinding used to move a window one workspace down." -#~ msgstr "ปุ่มลัดสำหรับย้ายหน้าต่างไปพื้นที่ทำงานด้านล่าง" - -#~ msgid "" -#~ "This keybinding changes whether a window is above or below other " -#~ "windows. If the window is covered by another one, it raises the window " -#~ "above all others, and if the window is already fully visible, it lowers " -#~ "it below all others." -#~ msgstr "" -#~ "ปุ่มลัดนี้เปลี่ยนสถานะหน้าต่าง ว่าอยู่หน้าหรือหลังหน้าต่างอื่นๆ ถ้าหน้าต่างถูกหน้าต่างอื่นบังอยู่ " -#~ "จะยกหน้าต่างขึ้นมาหน้าสุด และถ้าหน้าต่างอยู่หน้าสุดอยู่แล้ว ก็จะถอยหน้าต่างลงไปอยู่หลังสุด" - -#~ msgid "This keybinding raises the window above other windows." -#~ msgstr "ปุ่มลัดนี้ยกหน้าต่างขึ้นมาไว้หน้าหน้าต่างอื่นๆ" - -#~ msgid "This keybinding lowers a window below other windows." -#~ msgstr "ปุ่มลัดนี้ถอยหน้าต่างลงไปใว้หลังหน้าต่างอื่น" - -#~ msgid "This keybinding resizes a window to fill available vertical space." -#~ msgstr "ปุ่มลัดนี้ขยายหน้าต่างเพื่อให้เต็มความสูงของหน้าจอ" - -#~ msgid "This keybinding resizes a window to fill available horizontal space." -#~ msgstr "ปุ่มลัดนี้ขยายหน้าต่างเพื่อให้เต็มความกว้างของหน้าจอ" - -#~ msgid "" -#~ "This keybinding moves a window into the north-west (top left) corner of " -#~ "the screen." -#~ msgstr "ปุ่มลัดนี้ย้ายหน้าต่างไปที่มุมตะวันตกเฉียงเหนือ (บนซ้าย) ของหน้าจอ" - -#~ msgid "" -#~ "This keybinding moves a window into the north-east (top right) corner of " -#~ "the screen." -#~ msgstr "ปุ่มลัดนี้ย้ายหน้าต่างไปที่มุมตะวันออกเฉียงเหนือ (บนขวา) ของหน้าจอ" - -#~ msgid "" -#~ "This keybinding moves a window into the north-east (bottom left) corner " -#~ "of the screen." -#~ msgstr "ปุ่มลัดนี้ย้ายหน้าต่างไปที่มุมตะวันตกเฉียงใต้ (ล่างซ้าย) ของหน้าจอ" - -#~ msgid "" -#~ "This keybinding moves a window into the north-east (bottom right) corner " -#~ "of the screen." -#~ msgstr "ปุ่มลัดนี้ย้ายหน้าต่างไปที่มุมตะวันออกเฉียงใต้ (ล่างขวา) ของหน้าจอ" - -#~ msgid "" -#~ "This keybinding moves a window against the north (top) side of the screen." -#~ msgstr "ปุ่มลัดนี้ย้ายหน้าต่างไปที่ขอบด้านเหนือ (บนสุด) ของหน้าจอ" - -#~ msgid "" -#~ "This keybinding moves a window against the south (bottom) side of the " -#~ "screen." -#~ msgstr "ปุ่มลัดนี้ย้ายหน้าต่างไปที่ขอบด้านใต้ (ล่างสุด) ของหน้าจอ" - -#~ msgid "" -#~ "This keybinding moves a window against the east (right) side of the " -#~ "screen." -#~ msgstr "ปุ่มลัดนี้ย้ายหน้าต่างไปที่ขอบด้านตะวันออก (ขวาสุด) ของหน้าจอ" - -#~ msgid "" -#~ "This keybinding moves a window against the west (left) side of the screen." -#~ msgstr "ย้ายหน้าต่างไปที่ขอบด้านตะวันตก (ซ้ายสุด) ของหน้าจอ" - -#~ msgid "This keybinding moves a window into the center of the screen." -#~ msgstr "ปุ่มลัดนี้ย้ายหน้าต่างไปที่กลางหน้าจอ" - -#~ msgid "" -#~ "Many actions (e.g. clicking in the client area, moving or resizing the " -#~ "window) normally raise the window as a side-effect. Setting this option " -#~ "to false, which is strongly discouraged, will decouple raising from other " -#~ "user actions, and ignore raise requests generated by applications. See " -#~ "http://bugzilla.gnome.org/show_bug.cgi?id=445447#c6." -#~ msgstr "" -#~ "โดยปกติ ปฏิบัติการหลายอย่าง (เช่น การคลิกบนพื้นที่ภายในหน้าต่าง " -#~ "การย้ายหรือปรับขนาดหน้าต่าง) จะยกหน้าต่างขึ้นด้วย ถ้ากำหนดตัวเลือกนี้เป็นเท็จ " -#~ "(ซึ่งไม่ขอแนะนำ) จะไม่ยกหน้าต่างเมื่อมีการโต้ตอบอย่างอื่นกับผู้ใช้ " -#~ "และจะไม่ตอบสนองการร้องขอการยกหน้าต่างจากโปรแกรมอื่นๆ ด้วย ดูรายละเอียดได้ที่ http://" -#~ "bugzilla.gnome.org/show_bug.cgi?id=445447#c6." - -#~ msgid "" -#~ "The keybinding that switches to the workspace above the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับสลับไปยังพื้นที่ทำงานที่อยู่ด้านบนพื้นที่ทำงานปัจจุบัน รูปแบบคือ \"<Control>a" -#~ "\" หรือ \"<Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก " -#~ "และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ \"<Ctrl>\" " -#~ "คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding that switches to the workspace below the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับสลับไปยังพื้นที่ทำงานที่อยู่ด้านล่างพื้นที่ทำงานปัจจุบัน รูปแบบคือ \"<Control>a" -#~ "\" หรือ \"<Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก " -#~ "และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ \"<Ctrl>\" " -#~ "คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding that switches to the workspace on the left of the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับสลับไปยังพื้นที่ทำงานที่อยู่ด้านซ้ายของพื้นที่ทำงานปัจจุบัน รูปแบบคือ \"<" -#~ "Control>a\" หรือ \"<Shift><Alt>F1\" " -#~ "ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ " -#~ "\"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ " -#~ "ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding that switches to the workspace on the right of the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับสลับไปยังพื้นที่ทำงานที่อยู่ด้านขวาของพื้นที่ทำงานปัจจุบัน รูปแบบคือ \"<" -#~ "Control>a\" หรือ \"<Shift><Alt>F1\" " -#~ "ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ " -#~ "\"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ " -#~ "ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding that switches to workspace 1. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับสลับไปยังพื้นที่ทำงาน 1 รูปแบบคือ \"<Control>a\" หรือ \"<" -#~ "Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ " -#~ "เช่น \"<Ctl>\" และ \"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled" -#~ "\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding that switches to workspace 10. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับสลับไปยังพื้นที่ทำงาน 10 รูปแบบคือ \"<Control>a\" หรือ \"<" -#~ "Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ " -#~ "เช่น \"<Ctl>\" และ \"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled" -#~ "\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding that switches to workspace 11. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับสลับไปยังพื้นที่ทำงาน 11 รูปแบบคือ \"<Control>a\" หรือ \"<" -#~ "Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ " -#~ "เช่น \"<Ctl>\" และ \"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled" -#~ "\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding that switches to workspace 12. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับสลับไปยังพื้นที่ทำงาน 12 รูปแบบคือ \"<Control>a\" หรือ \"<" -#~ "Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ " -#~ "เช่น \"<Ctl>\" และ \"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled" -#~ "\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding that switches to workspace 2. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับสลับไปยังพื้นที่ทำงาน 2 รูปแบบคือ \"<Control>a\" หรือ \"<" -#~ "Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ " -#~ "เช่น \"<Ctl>\" และ \"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled" -#~ "\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding that switches to workspace 3. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับสลับไปยังพื้นที่ทำงาน 3 รูปแบบคือ \"<Control>a\" หรือ \"<" -#~ "Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ " -#~ "เช่น \"<Ctl>\" และ \"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled" -#~ "\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding that switches to workspace 4. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับสลับไปยังพื้นที่ทำงาน 4 รูปแบบคือ \"<Control>a\" หรือ \"<" -#~ "Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ " -#~ "เช่น \"<Ctl>\" และ \"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled" -#~ "\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding that switches to workspace 5. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับสลับไปยังพื้นที่ทำงาน 5 รูปแบบคือ \"<Control>a\" หรือ \"<" -#~ "Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ " -#~ "เช่น \"<Ctl>\" และ \"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled" -#~ "\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding that switches to workspace 6. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับสลับไปยังพื้นที่ทำงาน 6 รูปแบบคือ \"<Control>a\" หรือ \"<" -#~ "Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ " -#~ "เช่น \"<Ctl>\" และ \"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled" -#~ "\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding that switches to workspace 7. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับสลับไปยังพื้นที่ทำงาน 7 รูปแบบคือ \"<Control>a\" หรือ \"<" -#~ "Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ " -#~ "เช่น \"<Ctl>\" และ \"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled" -#~ "\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding that switches to workspace 8. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับสลับไปยังพื้นที่ทำงาน 8 รูปแบบคือ \"<Control>a\" หรือ \"<" -#~ "Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ " -#~ "เช่น \"<Ctl>\" และ \"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled" -#~ "\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding that switches to workspace 9. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับสลับไปยังพื้นที่ทำงาน 9 รูปแบบคือ \"<Control>a\" หรือ \"<" -#~ "Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ " -#~ "เช่น \"<Ctl>\" และ \"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled" -#~ "\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding used to activate the window menu. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับเรียกเมนูหน้าต่าง รูปแบบคือ \"<Control>a\" หรือ \"<Shift>" -#~ "<Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ เช่น " -#~ "\"<Ctl>\" และ \"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" " -#~ "ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding used to close a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับปิดหน้าต่าง รูปแบบคือ \"<Control>a\" หรือ \"<Shift><" -#~ "Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ เช่น \"<" -#~ "Ctl>\" และ \"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ " -#~ "ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding used to enter \"move mode\" and begin moving a window " -#~ "using the keyboard. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับ \"โหมดเคลื่อนย้าย\" ซึ่งยอมให้คุณใช้แป้นพิมพ์เคลื่อนย้ายหน้าต่าง รูปแบบคือ \"<" -#~ "Control>a\" หรือ \"<Shift><Alt>F1\" " -#~ "ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ " -#~ "\"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ " -#~ "ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding used to enter \"resize mode\" and begin resizing a window " -#~ "using the keyboard. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับ \"โหมดปรับขนาด\" ซึ่งยอมให้คุณใช้แป้นพิมพ์ปรับขนาดหน้าต่าง รูปแบบคือ \"<" -#~ "Control>a\" หรือ \"<Shift><Alt>F1\" " -#~ "ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ " -#~ "\"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ " -#~ "ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding used to hide all normal windows and set the focus to the " -#~ "desktop background. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับซ่อนหน้าต่างทั้งหมดและโฟกัสไปที่พื้นโต๊ะ รูปแบบคือ \"<Control>a\" หรือ " -#~ "\"<Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก " -#~ "และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ \"<Ctrl>\" " -#~ "คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding used to maximize a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับขยายแผ่หน้าต่าง รูปแบบคือ \"<Control>a\" หรือ \"<Shift><" -#~ "Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ เช่น \"<" -#~ "Ctl>\" และ \"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ " -#~ "ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding used to minimize a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับย่อเก็บหน้าต่าง รูปแบบคือ \"<Control>a\" หรือ \"<Shift><" -#~ "Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ เช่น \"<" -#~ "Ctl>\" และ \"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ " -#~ "ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding used to move a window one workspace down. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับย้ายหน้าต่างลงไปยังพื้นที่ทำงานถัดลงไปด้านล่าง รูปแบบคือ \"<Control>a" -#~ "\" หรือ \"<Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก " -#~ "และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ \"<Ctrl>\" " -#~ "คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding used to move a window one workspace to the left. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับย้ายหน้าต่างไปยังพื้นที่ทำงานถัดไปด้านซ้าย รูปแบบคือ \"<Control>a\" " -#~ "หรือ \"<Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก " -#~ "และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ \"<Ctrl>\" " -#~ "คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding used to move a window one workspace to the right. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับย้ายหน้าต่างไปยังพื้นที่ทำงานถัดไปด้านขวา รูปแบบคือ \"<Control>a\" " -#~ "หรือ \"<Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก " -#~ "และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ \"<Ctrl>\" " -#~ "คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding used to move a window one workspace up. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับย้ายหน้าต่างขึ้นไปยังพื้นที่ทำงานถัดขึ้นไปด้านบน รูปแบบคือ \"<Control>a\" " -#~ "หรือ \"<Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก " -#~ "และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ \"<Ctrl>\" " -#~ "คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding used to move a window to workspace 1. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับย้ายหน้าต่างไปยังพื้นที่ทำงาน 1 รูปแบบคือ \"<Control>a\" หรือ \"<" -#~ "Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ " -#~ "เช่น \"<Ctl>\" และ \"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled" -#~ "\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding used to move focus backwards between panels and the " -#~ "desktop, using a popup window. The format looks like \"<Control>a\" " -#~ "or \"<Shift><Alt>F1\". The parser is fairly liberal and " -#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" -#~ "\" and \"<Ctrl>\". If you set the option to the special string " -#~ "\"disabled\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับวนโฟกัสไปยังพาเนลต่างๆ และพื้นโต๊ะ ในทิศย้อนกลับ โดยใช้หน้าต่างป๊อปอัพช่วย " -#~ "รูปแบบคือ \"<Control>a\" หรือ \"<Shift><Alt>F1\" " -#~ "ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ " -#~ "\"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ " -#~ "ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding used to move focus backwards between panels and the " -#~ "desktop, without a popup window. The format looks like \"<Control>a" -#~ "\" or \"<Shift><Alt>F1\". The parser is fairly liberal and " -#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" -#~ "\" and \"<Ctrl>\". If you set the option to the special string " -#~ "\"disabled\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับวนโฟกัสไปยังพาเนลต่างๆ และพื้นโต๊ะ ในทิศย้อนกลับ โดยไม่ใช้หน้าต่างป๊อปอัพช่วย " -#~ "รูปแบบคือ \"<Control>a\" หรือ \"<Shift><Alt>F1\" " -#~ "ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ " -#~ "\"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ " -#~ "ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding used to move focus backwards between windows of an " -#~ "application without a popup window. Holding \"shift\" together with this " -#~ "binding makes the direction go forward again. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับวนโฟกัส ระหว่างหน้าต่างทั้งหลายของโปรแกรมประยุกต์ในทิศย้อนกลับ " -#~ "โดยไม่ใช้หน้าต่างป๊อปอัพช่วย กด \"shift\" พร้อมกับปุ่มลัดนี้ถ้าต้องการวนให้ไปข้างหน้า " -#~ "รูปแบบคือ \"<Control>a\" หรือ \"<Shift><Alt>F1\" " -#~ "ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ " -#~ "\"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ " -#~ "ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding used to move focus backwards between windows of an " -#~ "application, using a popup window. Holding \"shift\" together with this " -#~ "binding makes the direction go forward again. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับวนโฟกัส ระหว่างหน้าต่างทั้งหลายของโปรแกรมประยุกต์ในทิศย้อนกลับ " -#~ "โดยใช้หน้าต่างป๊อปอัพช่วย กด \"shift\" พร้อมกับปุ่มลัดนี้ถ้าต้องการวนให้ไปข้างหน้า " -#~ "รูปแบบคือ \"<Control>a\" หรือ \"<Shift><Alt>F1\" " -#~ "ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ " -#~ "\"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ " -#~ "ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding used to move focus backwards between windows without a " -#~ "popup window. Holding \"shift\" together with this binding makes the " -#~ "direction go forward again. The format looks like \"<Control>a\" or " -#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " -#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" -#~ "\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับวนโฟกัส ระหว่างหน้าต่างต่างๆในทิศย้อนกลับ โดยไม่ใช้หน้าต่างป๊อปอัพช่วย กด " -#~ "\"shift\" พร้อมกับปุ่มลัดนี้ถ้าต้องการวนให้ไปข้างหน้า รูปแบบคือ \"<Control>a\" " -#~ "หรือ \"<Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก " -#~ "และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ \"<Ctrl>\" " -#~ "คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding used to move focus backwards between windows, using a " -#~ "popup window. Holding \"shift\" together with this binding makes the " -#~ "direction go forward again. The format looks like \"<Control>a\" or " -#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " -#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" -#~ "\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับวนโฟกัส ระหว่างหน้าต่างต่างๆในทิศย้อนกลับ โดยใช้หน้าต่างป๊อปอัพช่วย กด \"shift" -#~ "\" พร้อมกับปุ่มลัดนี้ถ้าต้องการวนให้ไปข้างหน้า รูปแบบคือ \"<Control>a\" หรือ " -#~ "\"<Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก " -#~ "และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ \"<Ctrl>\" " -#~ "คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding used to move focus between panels and the desktop, using a " -#~ "popup window. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับวนโฟกัสไปยังพาเนลต่างๆ และพื้นโต๊ะ โดยใช้หน้าต่างป๊อปอัพช่วย รูปแบบคือ \"<" -#~ "Control>a\" หรือ \"<Shift><Alt>F1\" " -#~ "ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ " -#~ "\"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ " -#~ "ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding used to move focus between panels and the desktop, without " -#~ "a popup window. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับวนโฟกัสไปยังพาเนลต่างๆ และพื้นโต๊ะ โดยไม่ใช้หน้าต่างป๊อปอัพช่วย รูปแบบคือ " -#~ "\"<Control>a\" หรือ \"<Shift><Alt>F1\" " -#~ "ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ " -#~ "\"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ " -#~ "ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding used to move focus between windows of an application " -#~ "without a popup window. Holding the \"shift\" key while using this " -#~ "binding reverses the direction of movement. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับวนโฟกัส ระหว่างหน้าต่างทั้งหลายของโปรแกรมประยุกต์โดยไม่ใช้หน้าต่างป๊อปอัพช่วย " -#~ "กด \"shift\" พร้อมกับปุ่มลัดนี้ถ้าต้องการวนให้กลับคนละทาง รูปแบบคือ \"<Control>a" -#~ "\" หรือ \"<Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก " -#~ "และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ \"<Ctrl>\" " -#~ "คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding used to move focus between windows of an application, " -#~ "using a popup window. (Traditionally <Alt>F6) Holding the \"shift\" " -#~ "key while using this binding reverses the direction of movement. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับวนโฟกัส ระหว่างหน้าต่างทั้งหลายของโปรแกรมประยุกต์โดยใช้หน้าต่างป๊อปอัพช่วย " -#~ "(โดยทั่วไปแล้วใช้ <Alt>F6) กด \"shift\" " -#~ "พร้อมกับปุ่มลัดนี้ถ้าต้องการวนให้กลับคนละทาง รูปแบบคือ \"<Control>a\" หรือ \"<" -#~ "Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ " -#~ "เช่น \"<Ctl>\" และ \"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled" -#~ "\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding used to move focus between windows without a popup window. " -#~ "(Traditionally <Alt>Escape) Holding the \"shift\" key while using " -#~ "this binding reverses the direction of movement. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับวนโฟกัส ระหว่างหน้าต่างต่างๆ โดยไม่ใช้หน้าต่างป๊อปอัพช่วย (ทั่วไปแล้วใช้ <" -#~ "Alt>Escape) กด \"shift\" พร้อมกับปุ่มลัดนี้ถ้าต้องการวนให้กลับคนละทาง รูปแบบคือ " -#~ "\"<Control>a\" หรือ \"<Shift><Alt>F1\" " -#~ "ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ " -#~ "\"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ " -#~ "ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding used to move focus between windows, using a popup window. " -#~ "(Traditionally <Alt>Tab) Holding the \"shift\" key while using this " -#~ "binding reverses the direction of movement. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับวนโฟกัส ระหว่างหน้าต่างต่างๆ โดยใช้หน้าต่างป๊อปอัพช่วย (ทั่วไปแล้วใช้ <" -#~ "Alt>Tab) กด \"shift\" พร้อมกับปุ่มลัดนี้ถ้าต้องการวนให้กลับคนละทาง รูปแบบคือ " -#~ "\"<Control>a\" หรือ \"<Shift><Alt>F1\" " -#~ "ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ " -#~ "\"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ " -#~ "ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding used to toggle always on top. A window that is always on " -#~ "top will always be visible over other overlapping windows. The format " -#~ "looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -#~ "parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับสลับการค้างอยู่บนสุด หน้าต่างที่ค้างอยู่บนสุดจะปรากฏอยู่หน้าหน้าต่างอื่นๆเสมอ " -#~ "รูปแบบคือ \"<Control>a\" หรือ \"<Shift><Alt>F1\" " -#~ "ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ " -#~ "\"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ " -#~ "ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding used to toggle fullscreen mode. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับสลับโหมดเต็มหน้าจอ รูปแบบคือ \"<Control>a\" หรือ \"<Shift>" -#~ "<Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ เช่น " -#~ "\"<Ctl>\" และ \"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" " -#~ "ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding used to toggle maximization. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับสลับสถานะขยายแผ่ รูปแบบคือ \"<Control>a\" หรือ \"<Shift>" -#~ "<Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ เช่น " -#~ "\"<Ctl>\" และ \"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" " -#~ "ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding used to toggle shaded/unshaded state. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับสลับสถานะม้วนเก็บ/คลี่ออก รูปแบบคือ \"<Control>a\" หรือ \"<" -#~ "Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ " -#~ "เช่น \"<Ctl>\" และ \"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled" -#~ "\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding used to toggle whether the window is on all workspaces or " -#~ "just one. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับสลับ ว่าจะแสดงหน้าต่างบนทุกพื้นที่ทำงาน หรือบนพื้นที่ทำงานเดียว รูปแบบคือ \"<" -#~ "Control>a\" หรือ \"<Shift><Alt>F1\" " -#~ "ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ " -#~ "\"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ " -#~ "ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding used to unmaximize a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับยกเลิกการขยายแผ่หน้าต่างเต็มพื้นโต๊ะ รูปแบบคือ \"<Control>a\" หรือ " -#~ "\"<Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก " -#~ "และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ \"<Ctrl>\" " -#~ "คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding which display's the panel's \"Run Application\" dialog " -#~ "box. The format looks like \"<Control>a\" or \"<Shift><" -#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If " -#~ "you set the option to the special string \"disabled\", then there will be " -#~ "no keybinding for this action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับเปิดกล่องโต้ตอบ \"เรียกโปรแกรม\" ของพาเนล รูปแบบคือ \"<Control>a" -#~ "\" หรือ \"<Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก " -#~ "และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ \"<Ctrl>\" " -#~ "คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding which invokes a terminal. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับเปิดเทอร์มินัล รูปแบบคือ \"<Control>a\" หรือ \"<Shift><" -#~ "Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ เช่น \"<" -#~ "Ctl>\" และ \"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ " -#~ "ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding which invokes the panel's screenshot utility to take a " -#~ "screenshot of a window. The format looks like \"<Control>a\" or " -#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " -#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" -#~ "\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับเรียกโปรแกรมจับภาพของพาเนล เพื่อจับภาพหน้าต่างที่ต้องการ รูปแบบคือ \"<" -#~ "Control>a\" หรือ \"<Shift><Alt>F1\" " -#~ "ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ " -#~ "\"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ " -#~ "ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding which invokes the panel's screenshot utility. The format " -#~ "looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -#~ "parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับเรียกโปรแกรมจับภาพหน้าจอของพาเนล รูปแบบคือ \"<Control>a\" หรือ " -#~ "\"<Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก " -#~ "และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ \"<Ctrl>\" " -#~ "คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "The keybinding which shows the panel's main menu. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "ปุ่มลัดสำหรับเปิดเมนูหลักของพาเนล รูปแบบคือ \"<Control>a\" หรือ \"<" -#~ "Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ " -#~ "เช่น \"<Ctl>\" และ \"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled" -#~ "\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "This keybinding changes whether a window is above or below other windows. " -#~ "If the window is covered by another one, it raises the window above all " -#~ "others, and if the window is already fully visible, it lowers it below " -#~ "all others. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "ปุ่มลัดนี้ใช้ปรับว่าหน้าต่างจะอยู่ข้างบนหรือล่างหน้าต่างอื่น ถ้าหน้าต่างนั้นถูกหน้าต่างอื่นบังอยู่ " -#~ "ก็จะถูกยกขึ้นมาไว้บนสุด แต่ถ้าหน้าต่างนั้นไม่ถูกบังอยู่ ก็จะถูกเอาไปไว้หลังสุด รูปแบบคือ \"<" -#~ "Control>a\" หรือ \"<Shift><Alt>F1\" " -#~ "ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ " -#~ "\"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ " -#~ "ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "This keybinding lowers a window below other windows. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "ปุ่มลัดนี้เอาหน้าต่างลงไปอยู่หลังหน้าต่างอื่นๆ รูปแบบคือ \"<Control>a\" หรือ \"<" -#~ "Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ " -#~ "เช่น \"<Ctl>\" และ \"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled" -#~ "\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "This keybinding moves a window against the north (top) side of the " -#~ "screen. The format looks like \"<Control>a\" or \"<Shift><" -#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If " -#~ "you set the option to the special string \"disabled\", then there will be " -#~ "no keybinding for this action." -#~ msgstr "" -#~ "ปุ่มลัดนี้ย้ายหน้าต่างไปที่ขอบทางเหนือ (ด้านบน) ของหน้าจอ รูปแบบคือ \"<Control>a" -#~ "\" หรือ \"<Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก " -#~ "และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ \"<Ctrl>\" " -#~ "คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "This keybinding moves a window into the center of the screen. The format " -#~ "looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -#~ "parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "ปุ่มลัดนี้ย้ายหน้าต่างไปที่กลางหน้าจอ รูปแบบคือ \"<Control>a\" หรือ \"<" -#~ "Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ " -#~ "เช่น \"<Ctl>\" และ \"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled" -#~ "\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "This keybinding moves a window into the east (right) side of the screen. " -#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -#~ "\". The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "ปุ่มลัดนี้ย้ายหน้าต่างไปที่ขอบทางตะวันออก (ด้านขวา) ของหน้าจอ รูปแบบคือ \"<" -#~ "Control>a\" หรือ \"<Shift><Alt>F1\" " -#~ "ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ " -#~ "\"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ " -#~ "ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "This keybinding moves a window into the north-east (top right) corner of " -#~ "the screen. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "ปุ่มลัดนี้ย้ายหน้าต่างไปที่มุมตะวันออกเฉียงเหนือ (ด้านบนขวา) ของหน้าจอ รูปแบบคือ \"<" -#~ "Control>a\" หรือ \"<Shift><Alt>F1\" " -#~ "ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ " -#~ "\"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ " -#~ "ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "This keybinding moves a window into the north-west (top left) corner of " -#~ "the screen. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "ปุ่มลัดนี้ย้ายหน้าต่างไปที่มุมตะวันตกเฉียงเหนือ (ด้านบนซ้าย) ของหน้าจอ รูปแบบคือ \"<" -#~ "Control>a\" หรือ \"<Shift><Alt>F1\" " -#~ "ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ " -#~ "\"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ " -#~ "ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "This keybinding moves a window into the south (bottom) side of the " -#~ "screen. The format looks like \"<Control>a\" or \"<Shift><" -#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If " -#~ "you set the option to the special string \"disabled\", then there will be " -#~ "no keybinding for this action." -#~ msgstr "" -#~ "ปุ่มลัดนี้ย้ายหน้าต่างไปที่ขอบทางใต้ (ด้านล่าง) ของหน้าจอ รูปแบบคือ \"<Control>a\" " -#~ "หรือ \"<Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก " -#~ "และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ \"<Ctrl>\" " -#~ "คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "This keybinding moves a window into the south-east (bottom right) corner " -#~ "of the screen. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "ปุ่มลัดนี้ย้ายหน้าต่างไปที่มุมตะวันออกเฉียงใต้ (ด้านล่างขวา) ของหน้าจอ รูปแบบคือ \"<" -#~ "Control>a\" หรือ \"<Shift><Alt>F1\" " -#~ "ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ " -#~ "\"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ " -#~ "ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "This keybinding moves a window into the south-west (bottom left) corner " -#~ "of the screen. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "ปุ่มลัดนี้ย้ายหน้าต่างไปที่มุมตะวันตกเฉียงใต้ (ด้านล่างซ้าย) ของหน้าจอ รูปแบบคือ \"<" -#~ "Control>a\" หรือ \"<Shift><Alt>F1\" " -#~ "ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ " -#~ "\"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ " -#~ "ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "This keybinding moves a window into the west (left) side of the screen. " -#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -#~ "\". The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "ปุ่มลัดนี้ย้ายหน้าต่างไปที่ขอบทางตะวันตก (ด้านซ้าย) ของหน้าจอ รูปแบบคือ \"<Control>" -#~ "a\" หรือ \"<Shift><Alt>F1\" " -#~ "ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ " -#~ "\"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ " -#~ "ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "This keybinding raises the window above other windows. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "ปุ่มลัดนี้ยกหน้าต่างขึ้นมาอยู่หน้าหน้าต่างอื่นๆ รูปแบบคือ \"<Control>a\" หรือ \"<" -#~ "Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก และเข้าใจชื่อย่อ " -#~ "เช่น \"<Ctl>\" และ \"<Ctrl>\" คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled" -#~ "\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "This keybinding resizes a window to fill available horizontal space. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "ปุ่มลัดนี้ใช้ขยายแผ่หน้าต่างเต็มความกว้างของพื้นโต๊ะ รูปแบบคือ \"<Control>a\" หรือ " -#~ "\"<Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก " -#~ "และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ \"<Ctrl>\" " -#~ "คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "" -#~ "This keybinding resizes a window to fill available vertical space. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "ปุ่มลัดนี้ใช้ขยายแผ่หน้าต่างเต็มความสูงของพื้นโต๊ะ รูปแบบคือ \"<Control>a\" หรือ " -#~ "\"<Shift><Alt>F1\" ตัวอ่านค่าคีย์ไม่สนใจว่าเป็นตัวพิมพ์ใหญ่หรือเล็ก " -#~ "และเข้าใจชื่อย่อ เช่น \"<Ctl>\" และ \"<Ctrl>\" " -#~ "คุณสามารถตั้งค่าตัวเลือกเป็น \"disabled\" ได้ ถ้าไม่ต้องการปุ่มลัดสำหรับปฏิบัติการนี้" - -#~ msgid "Unmaximize Window" -#~ msgstr "เลิกขยายแผ่หน้าต่าง" - -#~ msgid "No \"%s\" attribute on <%s> element" -#~ msgstr "ขาดแอตทริบิวต์ \"%s\" ในอิลิเมนต์ <%s>" - -#~ msgid "Theme already has a fallback icon" -#~ msgstr "ชุดตกแต่งมีไอคอนสำรองอยู่แล้ว" - -#~ msgid "Theme already has a fallback mini_icon" -#~ msgstr "ชุดตกแต่งมีไอคอนเล็กสำรองอยู่แล้ว" - -#~ msgid "Type of %s was not integer" -#~ msgstr "ชนิดของ %s ไม่ใช่จำนวนเต็ม" - -#~ msgid "" -#~ "%d stored in GConf key %s is not a reasonable cursor_size; must be in the " -#~ "range 1..128\n" -#~ msgstr "" -#~ "%d ในคีย์ GConf %s ไม่ใช่ขนาดเคอร์เซอร์ที่สมเหตุสมผล ค่าดังกล่าวควรอยู่ในช่วง 1..128\n" - -#~ msgid "" -#~ "%d stored in GConf key %s is not a reasonable number of workspaces, " -#~ "current maximum is %d\n" -#~ msgstr "" -#~ "%d ในคีย์ GConf %s ไม่ใช่จำนวนพื้นที่ทำงานที่สมเหตุสมผล สามารถตั้งได้มากสุดเป็น %d\n" - -#~ msgid "On _Top" -#~ msgstr "_บนสุด" - -#~ msgid "" -#~ "Forcing this application to quit will cause you to lose any unsaved " -#~ "changes." -#~ msgstr "ถ้าบังคับออกจากโปรแกรมนี้ ข้อมูลที่ยังไม่ได้ถูกบันทึกจะสูญหาย" - -#~ msgid "Unknown function \"%s\" for menu icon" -#~ msgstr "ไม่รู้จักฟังก์ชัน \"%s\" สำหรับไอคอนเมนู" - -#~ msgid "Unknown state \"%s\" for menu icon" -#~ msgstr "ไม่รู้จักสถานะ \"%s\" สำหรับไอคอนเมนู" - -#~ msgid "Theme already has a menu icon for function %s state %s" -#~ msgstr "ชุดตกแต่งมีไอคอนเมนูสำหรับฟังก์ชัน %s สถานะ %s อยู่แล้ว" - -#~ msgid "No draw_ops provided for menu icon" -#~ msgstr "ขาด draw_ops สำหรับไอคอนเมนู" - -#~ msgid "Failed to read theme from file %s: %s\n" -#~ msgstr "ไม่สามารถอ่านชุดตกแต่งจากแฟ้ม %s: %s\n" - -#~ msgid "" -#~ "<menu_icon function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -#~ "specified for this theme" -#~ msgstr "" -#~ "ต้องระบุ <menu_icon function=\"%s\" state=\"%s\" draw_ops=\"อะไรก็ตามแต่\"/> " -#~ "สำหรับชุดตกแต่งนี้" - -#~ msgid "" -#~ "If true, and the focus mode is either \"sloppy\" or \"mouse\" then the " -#~ "focused window will be automatically raised after a delay (the delay is " -#~ "specified by the auto_raise_delay key). This preference is poorly named, " -#~ "but kept for backwards compatibility. To try to be more clear (at least " -#~ "to the technically inclined), its meaning is \"automatically raise the " -#~ "window following a timeout which is triggered by non-grabbed mouse entry " -#~ "in sloppy or mouse focus modes\". It is unrelated to clicking behavior (i." -#~ "e. this is not related to raise-on-click/orthogonal-raise). It is " -#~ "unrelated to entering a window during drag and drop (because that results " -#~ "in the application grabbing the mouse)" -#~ msgstr "" -#~ "ถ้าเป็นจริง และโหมดโฟกัสหน้าต่างเป็น \"sloppy\" หรือ \"mouse\" " -#~ "จะยกหน้าต่างที่ได้โฟกัสขึ้นมาโดยอัตโนมัติหลังจากหน่วงเวลาระยะหนึ่ง (กำหนดเวลาที่หน่วงโดยคีย์ " -#~ "auto_raise_delay) ค่าตั้งนี้ตั้งชื่อค่อนข้างแย่ แต่ก็เก็บชื่อไว้เพื่อความเข้ากันได้กับรุ่นเก่า " -#~ "ถ้าจะให้ชัดเจนกว่านี้ (อย่างน้อยก็สำหรับผู้มีความรู้ทางเทคนิค) ความหมายของมันก็คือ " -#~ "\"ยกหน้าต่างขึ้นมาโดยอัตโนมัติหลังการหน่วงเวลา " -#~ "ซึ่งเริ่มจับเวลาเมื่อมีการเลื่อนเมาส์เข้ามาในหน้าต่างขณะใช้โหมดโฟกัสหน้าต่างแบบ sloppy หรือ " -#~ "mouse โดยขณะนั้นไม่มีหน้าต่างอื่นยึดเมาส์อยู่\" การยกหน้าต่างดังกล่าว " -#~ "ไม่เกี่ยวกับพฤติกรรมการคลิก (กล่าวคือ ไม่เกี่ยวกับการยกหน้าต่างขึ้นเมื่อถูกคลิก " -#~ "หรือการยกหน้าต่างขึ้นตามลำดับ) และไม่เกี่ยวกับการเลื่อนเมาส์เข้าสู่หน้าต่างระหว่างการลากวาง " -#~ "(เพราะนั่นหมายความว่าโปรแกรมหนึ่งกำลังยึดเมาส์ไว้ใช้อยู่)" - -#~ msgid "" -#~ "Some applications break specifications in ways that result in window " -#~ "manager misfeatures. For example, ideally Metacity would place all " -#~ "dialogs in a consistent position with respect to their parent window. " -#~ "This requires ignoring application-specified positions for dialogs. But " -#~ "some versions of Java/Swing mark their popup menus as dialogs, so " -#~ "Metacity has to disable dialog positioning to allow menus to work in " -#~ "broken Java applications. There are several other examples like this. " -#~ "This option puts Metacity in full-on Correct mode, which perhaps gives a " -#~ "moderately nicer UI if you don't need to run any broken apps. Sadly, " -#~ "workarounds must be enabled by default; the real world is an ugly place. " -#~ "Some of the workarounds are workarounds for limitations in the " -#~ "specifications themselves, so sometimes a bug in no-workarounds mode " -#~ "won't be fixable without amending a spec." -#~ msgstr "" -#~ "โปรแกรมบางตัวละเมิดข้อกำหนดโดยทำให้โปรแกรมจัดการหน้าต่างต้องทำงานแก้ขัด ตัวอย่างเช่น " -#~ "ในอุดมคติแล้ว metacity จะเปิดกล่องโต้ตอบทั้งหลาย ณ ตำแหน่งคงที่เทียบกับหน้าต่างแม่ " -#~ "ซี่งจำเป็นต้องละเลยตำแหน่งที่โปรแกรมระบุมา แต่ Java/Swing " -#~ "บางรุ่นใช้กล่องโต้ตอบในการเปิดเมนูป๊อปอัพ ทำให้ metacity " -#~ "จำต้องงดการวางตำแหน่งกล่องโต้ตอบ เพื่อให้เมนูในโปรแกรมจาวาเสียๆ เหล่านี้ทำงานได้ " -#~ "และยังมีตัวอย่างทำนองนี้อีกมากมาย ตัวเลือกนี้จะตั้งให้ metacity " -#~ "เข้าสู่โหมดการทำงานที่ถูกหลักเกณฑ์ทุกประการ ซึ่งอาจจะให้ UI ที่ดีกว่า " -#~ "ถ้าคุณไม่ต้องการรันโปรแกรมที่เสียๆ แต่น่าเศร้าที่ต้องเปิดการแก้ขัดนี้ไว้ก่อน " -#~ "โลกแห่งความเป็นจริงช่างโสมม การแก้ขัดบางอย่างก็เป็นเพราะข้อจำกัดในข้อกำหนดมาตรฐานเอง " -#~ "ทำให้บั๊กในโหมดที่ปราศจากการแก้ขัดไม่สามารถแก้ได้โดยไม่แก้มาตรฐาน" - -#~ msgid "" -#~ "Coordinate expression parser overflowed its buffer, this is really a " -#~ "Metacity bug, but are you sure you need a huge expression like that?" -#~ msgstr "" -#~ "ตัวแจงค่านิพจน์พิกัดทำข้อมูลล้น ความจริงแล้วนี่ถือเป็นบั๊กของ Metacity " -#~ "แต่คุณแน่ใจหรือว่าคุณต้องการนิพจน์ที่ใหญ่มหึมาเช่นนี้?" diff --git a/po/tk.po b/po/tk.po index 14012d2c7..10df24b56 100644 --- a/po/tk.po +++ b/po/tk.po @@ -12,6 +12,7 @@ msgstr "" "PO-Revision-Date: 2004-08-13 03:30+0330\n" "Last-Translator: Gurban Mühemmet Tewekgeli <gmtavakkoli@yahoo.com>\n" "Language-Team: Turkmen <kakilikgroup@yahoo.com>\n" +"Language: tk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" diff --git a/po/tr.po b/po/tr.po index 1601245a7..f7ec83495 100644 --- a/po/tr.po +++ b/po/tr.po @@ -1,454 +1,297 @@ -# Turkish translation of muffin. +# Turkish translation of mutter. # Copyright (C) 2003, 2004, 2005, 2008, 2009, 2011 Free Software Foundation. -# This file is distributed under the same license as the muffin package. +# This file is distributed under the same license as the mutter package. # # Sinan İmamoğlu <sinan@myrealbox.com>, 2003. # Baris Cicek <baris@teamforce.name.tr>, 2004, 2005, 2008, 2009. # İlker DAĞLI <ilker@ilkerdagli.info>, 2011. # Muhammed EKEN <gnome@m-eken.com>, 2011. -# Muhammet Kara <muhammet.k@gmail.com>, 2011, 2012. +# Furkan Ahmet Kara <furkanahmetkara.fk@gmail.com>, 2017. +# Muhammet Kara <muhammetk@gmail.com>, 2011, 2012, 2014, 2015, 2016, 2017. +# Emin Tufan Çetin <etcetin@gmail.com>, 2017-2020. +# msgid "" msgstr "" -"Project-Id-Version: muffin master\n" -"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" -"product=muffin&keywords=I18N+L10N&component=general\n" -"POT-Creation-Date: 2012-03-15 21:29+0000\n" -"PO-Revision-Date: 2012-03-23 21:56+0000\n" -"Last-Translator: Muhammet Kara <muhammet.k@gmail.com>\n" -"Language-Team: Turkish <gnome-turk@gnome.org>\n" +"Project-Id-Version: mutter master\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2020-02-23 17:41+0000\n" +"PO-Revision-Date: 2020-02-24 17:57+0300\n" +"Last-Translator: Emin Tufan Çetin <etcetin@gmail.com>\n" +"Language-Team: Türkçe <gnome-turk@gnome.org>\n" +"Language: tr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Lokalize 1.2\n" "Plural-Forms: nplurals=1; plural=0;\n" -"Language: tr\n" +"X-DamnedLies-Scope: partial\n" +"X-Generator: Poedit 2.2.3\n" -#: ../src/50-muffin-windows.xml.in.h:1 -msgid "Windows" -msgstr "Pencereler" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Gezinme" -#: ../src/50-muffin-windows.xml.in.h:2 -msgid "View split on left" -msgstr "Solda bölünmüş olarak göster" +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Pencereyi çalışma alanı 1’e taşı" -#: ../src/50-muffin-windows.xml.in.h:3 -msgid "View split on right" -msgstr "Sağda bölünmüş olarak göster" +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Pencereyi çalışma alanı 2’ye taşı" -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format -msgid "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." -msgstr "" -"\"%2$s\" monitöründeki %1$i ekranında zaten başka bir birleştirme yöneticisi " -"çalışıyor." +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Pencereyi çalışma alanı 3’e taşı" -#: ../src/core/bell.c:307 -msgid "Bell event" -msgstr "Etkinlik zili" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Pencereyi çalışma alanı 4’e taşı" -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Bilinmeyen pencere bilgi isteği: %d" +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Pencereyi son çalışma alanına taşı" -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> cevap vermiyor." +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "Pencereyi üstteki çalışma alanına taşı" -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "Uygulama cevap vermiyor" +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "Pencereyi alttaki çalışma alanına taşı" -#: ../src/core/delete.c:119 -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "" -"Uygulamanın devam etmesi için bir müddet bekleyi seçebilirsiniz ya d a " -"uygulamanın tamamen çıkması için onu zorlayabilirsiniz." +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "Pencereyi soldaki monitöre taşı" -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "_Bekle" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "Pencereyi sağdaki monitöre taşı" -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "_Sonlandır" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "Pencereyi üstteki monitöre taşı" -#: ../src/core/display.c:387 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "Kompozisyon için gerekli olan %s eklentisi eksik" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "Pencereyi alttaki monitöre taşı" -#: ../src/core/display.c:453 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "X Pencere Sistemi '%s' ekranı açılamadı\n" +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "Uygulamalar arasında geçiş yap" -#: ../src/core/keybindings.c:852 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "" -"%s tuşu %x değiştiricileriyle birlikte başka bir uygulama tarafından tuş " -"bağıolarak kullanılıyor\n" +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "Önceki uygulamaya geç" -#: ../src/core/main.c:206 -msgid "Disable connection to session manager" -msgstr "Ortam yöneticisine olan bağlantıyı kapat" +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "Pencereler arasında geçiş yap" -#: ../src/core/main.c:212 -msgid "Replace the running window manager" -msgstr "Çalışan pencere yöneticisinin yerini al" +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "Önceki pencereye geç" -#: ../src/core/main.c:218 -msgid "Specify session management ID" -msgstr "Ortam yönetim ID'sini belirtin" +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "Uygulamanın pencereleri arasında geçiş yap" -#: ../src/core/main.c:223 -msgid "X Display to use" -msgstr "Kullanılacak X Ekranı" +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "Uygulamanın bir önceki penceresine geç" -#: ../src/core/main.c:229 -msgid "Initialize session from savefile" -msgstr "Ortamı kayıtlı dosyadan başlat" +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "Sistem denetimleri arasında geçiş yap" -#: ../src/core/main.c:235 -msgid "Make X calls synchronous" -msgstr "X çağrılarını eşazamanlı yap" +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "Önceki sistem denetimine geç" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Tema dizini taranırken hata oluştu: %s\n" +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "Pencereler arasında doğrudan geçiş yap" -#: ../src/core/main.c:520 -#, c-format -msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "" -"Hiç tema bulunamadı! %s varlığından ve bildiğimiz temaları içerdiğinden emin " -"olun.\n" +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "Önceki pencereye doğrudan geç" -#: ../src/core/muffin.c:40 -#, c-format -msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" -"muffin %s\n" -"Telif Hakkı (C) 2001-%d Havoc Pennington, Red Hat, Inc., ve diğerleri\n" -"Bu bir özgür yazılımdır; telif koşullarını öğrenmek için kaynak koda bakın.\n" -"Hiç bir garantisi, BELİRLİ BİR AMACA UYGUNLUĞU için dahi, YOKTUR.\n" +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "Uygulamanın pencereleri arasında anında geçiş yap" -#: ../src/core/muffin.c:54 -msgid "Print version" -msgstr "Sürümü yazdır" +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "Bir uygulamanın önceki penceresine doğrudan geç" -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "Kompozisyon eklentilerinin listesi (virgül ile ayrılmış)" +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "Sistem denetimleri arasında doğrudan geçiş yap" -#: ../src/core/prefs.c:1077 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"Hatalı uygulamalara yönelik çözümler devre dışı. Bazı uygulamalar düzgün " -"işlemeyebilir.\n" +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "Önceki sistem denetimine doğrudan geç" -#: ../src/core/prefs.c:1152 -#, c-format -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "" -"\"%s\" yazıtipi tanımlaması, %s GSettings anahtarından ayrıştırılamadı\n" +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "Tüm normal pencereleri gizle" -#: ../src/core/prefs.c:1218 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"Yapılandırma veritabanında bulunan \"%s\", fare düğme düzenleyicisi olarak " -"geçerli bir değer değil\n" +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "Çalışma alanı 1’e geç" -#: ../src/core/prefs.c:1739 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "" -"Yapılandırma veritabanında bulunan \"%s\", \"%s\" tuş bağı olarak geçerli " -"bir değer değil\n" +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "Çalışma alanı 2’ye geç" -#: ../src/core/prefs.c:1836 -#, c-format -msgid "Workspace %d" -msgstr "Çalışma Alanı %d" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "Çalışma alanı 3’e geç" -#: ../src/core/screen.c:730 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "'%2$s' X oturumundaki ekran %1$d geçersiz\n" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "Çalışma alanı 4’e geç" -#: ../src/core/screen.c:746 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"\"%2$s\" X oturumundaki ekran %1$d bir pencere yöneticisine zaten sahip; " -"geçerli pencere yöneticisinin yerine bir başkasını koymak için --replace " -"seçeneğini kullanmayı deneyin.\n" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "Son çalışma alanına geç" -#: ../src/core/screen.c:773 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "" -"\"%2$s\" X oturumundaki ekran %1$d hangi pencere yöneticisine " -"sahipöğrenilemedi\n" - -#: ../src/core/screen.c:828 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "" -"\"%2$s\" X oturumundaki ekran %1$d bir pencere yöneticisine zaten sahip\n" - -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "\"%2$s\" X oturumundaki ekran %1$d serberst bırakılamadı\"\n" +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "Üstteki çalışma alanına taşı" -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "'%s' dizini oluşturulamadı: %s\n" +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "Alttaki çalışma alanına taşı" -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "'%s' oturum dosyası yazma için açılamadı: %s\n" +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "Sistem" -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "'%s' oturum dosyasına yazmada hata: %s\n" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Komut çalıştırma istemini göster" -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "'%s' oturum dosyasını kapamada hata: %s\n" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Etkinlik genel görünümünü göster" -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Kaydedilmiş oturum dosyası ayrıştırırken hata: %s\n" +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Klavye kısayollarını geri yükle" -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "" -"Geçerli bir oturum kimliği bulunmasına karşın <metacity_session> " -"özniteliğiyle karşılaşıldı" - -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Bilinmeyen öznitelik %2$s üzerinde <%1$s> öğesi" - -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "iç içe <window> imi" - -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "Bilinmeyen öğe %s" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Pencereler" -#: ../src/core/session.c:1809 -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" -"Bu pencereler, "geçerli ayarları kaydet" özelliğini desteklemiyor " -"ve bir dahaki girişinizde elle yeniden başlatmanız gerekecek." +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "Pencere menüsünü etkinleştir" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Hata ayıklama günlüğü açılamadı: %s\n" +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Tam ekran kipini değiştir" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "fdopen() günlük dosyası %s açılamadı: %s\n" +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "Ekranı kaplama durumunu değiştir" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "%s günlük dosyası açıldı\n" +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "Bencereyi büyült" -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "Muffin, ayrıntılı kip desteği olmadan derlenmiş\n" +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Pencereyi eski haline getir" -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "Pencere yöneticisi: " +#: data/50-mutter-windows.xml:18 +msgid "Close window" +msgstr "Pencereyi kapat" -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "Pencere yöneticisinde hata: " +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "Pencereyi gizle" -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "Pencere yöneticisi uyarısı: " +#: data/50-mutter-windows.xml:22 +msgid "Move window" +msgstr "Pencere taşı" -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "Pencere yöneticisi hatası: " +#: data/50-mutter-windows.xml:24 +msgid "Resize window" +msgstr "Pencereyi yeniden boyutlandır" -#. first time through -#: ../src/core/window.c:7269 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"%s penceresi SM_CLIENT_ID'yi ICCCM tarafından belirtilen WM_CLIENT_LEADER'a " -"değil kendine atadı.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7932 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %" -"d x %d and max size %d x %d; this doesn't make much sense.\n" +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" msgstr "" -"%s penceresi bir yandan yeniden boyutlandırılamaz olduğunu gösteren bir MWM " -"ipucu verirken anlamsız bir biçimde en küçük (%d x %d) ve en büyük (%d x %d) " -"boyut sınırlarını da atıyor.\n" +"Pencerenin tüm çalışma alanlarında veya yalnızca bir tanesi üzerinde " +"olmasını seç" -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "Uygulama geçersiz _NET_WM_PID %lu atadı\n" +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "Pencere altta kalmışsa yükselt, aksi halde alçalt" -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (%s üzerinde)" +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "Pencereyi diğerlerinin üstüne çıkar" -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "Geçersiz WM_TRANSIENT_FOR pencere 0x%lx belirtilen %s.\n" +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "Pencereyi diğerlerinin altına gönder" -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "WM_TRANSIENT_FOR penceresi 0x%lx (%s için) döngü oluşturacak.\n" +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "Pencereyi dikey olarak büyült" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"0x%lx penceresinin %s özelliği beklenen\n" -"%s türü ve %d biçimi yerine %s türü, %d biçimi,\n" -"%d n_items'e sahip.\n" -"Bu büyük olasılıkla uygulamanın bir hatası, pencere yöneticisinin değil.\n" -"Pencerenin başlığı=\"%s\", sınıfı=\"%s\", adı=\"%s\"\n" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "Pencereyi yatay olarak büyült" -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "0x%2$lx penceresinin %1$s özelliği geçersiz UTF-8 içeriyor\n" +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "Solda bölünmüş olarak göster" -#: ../src/core/xprops.c:494 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"0x%2$lx penceresinin %1$s özelliği listedeki öğe %3$d için geçersiz UTF-8 " -"içeriyor\n" +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "Sağda bölünmüş olarak göster" -#: ../src/muffin.desktop.in.h:1 ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 +#: data/org.gnome.mutter.gschema.xml.in:7 msgid "Modifier to use for extended window management operations" msgstr "Genişletilmiş pencere yönetimi işlemleri için kullanılacak değiştirici" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 +#: data/org.gnome.mutter.gschema.xml.in:8 msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." msgstr "" -"Bu anahtar, pencere genel görünümü ve uygulama başlatma sisteminin bir " -"birleşimi olan \"bindirme\" işlemini başlatır. Öntanımlı olarak PC " -"donanımındaki \"windows tuşu\" olması tasarlanmıştır. Bağlayıcı varsayılan " -"olarak veya boş dize olarak ayarlanması beklenir." +"Bu tuş, pencere genel görünümü ve uygulama başlatma sisteminin bir birleşimi " +"olan “bindirme” işlemini başlatır. Öntanımlı olarak PC donanımındaki " +"“Windows tuşu” olması tasarlanmıştır. Bu bağlayıcının öntanımlı veya boş " +"dizge olarak ayarlanması beklenir." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 +#: data/org.gnome.mutter.gschema.xml.in:20 msgid "Attach modal dialogs" msgstr "Yardımcı diyalogları ekle" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 +#: data/org.gnome.mutter.gschema.xml.in:21 msgid "" "When true, instead of having independent titlebars, modal dialogs appear " "attached to the titlebar of the parent window and are moved together with " "the parent window." msgstr "" -"Eğer \"doğru\" ise, bağımsız başlık çubuklarına sahip olduğundan, yardım " -"diyalogları üst pencerenin başlık çubuğunda ekli gözükür ve üst pencere ile " -"birlikte hareket eder." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -msgid "Live Hidden Windows" -msgstr "Çalışır Durumdaki Gizli Pencereler" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"Gizli pencerelerin (ö.r. küçültülmüş pencereler ve diğer çalışma alanındaki " -"pencereler) çalışır bırakılıp bırakılmayacağını belirler." +"Seçili olduğunda, bağımsız başlık çubuklarına sahip olmak yerine, kipsel " +"diyaloglar üst pencerenin başlık çubuğunda ekli gözükür ve üst pencere ile " +"birlikte hareket ettirilebilirler." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 +#: data/org.gnome.mutter.gschema.xml.in:30 msgid "Enable edge tiling when dropping windows on screen edges" msgstr "" -"Pencereler ekran kenarlarında bırakıldığında kenar döşemeyi etkinleştir." +"Pencereler ekran kenarlarında bırakıldığında kenar döşemeyi etkinleştir" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 +#: data/org.gnome.mutter.gschema.xml.in:31 msgid "" "If enabled, dropping windows on vertical screen edges maximizes them " "vertically and resizes them horizontally to cover half of the available " @@ -459,38 +302,37 @@ msgstr "" "şekilde yeniden boyutlandırılır. Ekranın tepedeki kenarına bırakılan " "pencereler ekranı tamamen kaplar." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 +#: data/org.gnome.mutter.gschema.xml.in:40 msgid "Workspaces are managed dynamically" msgstr "Çalışma alanları dinamik olarak yönetilir" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 +#: data/org.gnome.mutter.gschema.xml.in:41 msgid "" -"Determines whether workspaces are managed dynamically or whether there's a " +"Determines whether workspaces are managed dynamically or whether there’s a " "static number of workspaces (determined by the num-workspaces key in org." "gnome.desktop.wm.preferences)." msgstr "" "Çalışma alanlarının dinamik olarak mı yönetileceğini yoksa sabit sayıda " -"çalışma alanı mı olacağını " -"belirler (org.cinnamon.desktop.wm.preferences içindeki num-workspaces değişkeni " -"tarafından belirlenir)." +"çalışma alanı mı olacağını belirler (org.gnome.desktop.wm.preferences " +"içindeki num-workspaces değişkeni tarafından belirlenir)." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 +#: data/org.gnome.mutter.gschema.xml.in:50 msgid "Workspaces only on primary" -msgstr "Sadece birincil monitördeki çalışma alanları" +msgstr "Yalnızca birincil monitördeki çalışma alanları" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 +#: data/org.gnome.mutter.gschema.xml.in:51 msgid "" "Determines whether workspace switching should happen for windows on all " "monitors or only for windows on the primary monitor." msgstr "" "Çalışma alanı değiştirilmesinin, tüm monitörlerdeki pencerelerde mi yoksa " -"sadece birincil monitördekilerde mi gerçekleşeceğini belirler." +"yalnızca birincil monitördekilerde mi gerçekleşeceğini belirler." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 +#: data/org.gnome.mutter.gschema.xml.in:59 msgid "No tab popup" msgstr "Sekme açılır penceresi yok" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 +#: data/org.gnome.mutter.gschema.xml.in:60 msgid "" "Determines whether the use of popup and highlight frame should be disabled " "for window cycling." @@ -498,1101 +340,1317 @@ msgstr "" "Pencere geçişinde çerçeve vurgulanması ve açılır pencere kullanımının " "kapatılıp kapatılmayacağını belirler." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Odak değişikliklerini işaretçi hareketi durana kadar ertele" + +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" +"Eğer seçiliyse ve odaklama kipi “sloppy” yada “mouse” ise bir pencereye " +"geçişte odak hemen değil, yanlızca işaretçi hareket etmeyi bıraktığında " +"değişir." + +#: data/org.gnome.mutter.gschema.xml.in:79 msgid "Draggable border width" msgstr "Sürüklenebilir kenarlık genişliği" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 +#: data/org.gnome.mutter.gschema.xml.in:80 msgid "" -"The amount of total draggable borders. If the theme's visible borders are " +"The amount of total draggable borders. If the theme’s visible borders are " "not enough, invisible borders will be added to meet this value." msgstr "" "Sürüklenebilir kenarlıkların toplam miktarı. Eğer temanın görünür " "kenarlıkları yetersiz gelirse, bu değere ulaşmak için görünmez kenarlıklar " "eklenir." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:17 +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "Ekran boyutuna yakın pencereleri kendiliğinden ekranı kaplattır" + +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" +"Etkinleştirildiğinde ekran boyutunda başlayan yeni pencereler kendiliğinden " +"ekranı kaplar." + +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Yeni pencereleri ekranın ortasına yerleştir" + +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" +"Etkinleştirildiğinde, yeni pencereler her zaman monitörün etkin ekranında " +"ortaya yerleştirilir." + +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Deneysel özellikleri etkinleştir" + +#: data/org.gnome.mutter.gschema.xml.in:108 +msgid "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes " +"mutter request a low priority real-time scheduling. The executable or user " +"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — " +"initializes Xwayland lazily if there are X11 clients. Requires restart." +msgstr "" +"Deneysel özellikleri etkinleştirmek için özelliğin anahtar sözcüğünü listeye " +"ekleyin. Özelliğin yeniden başlatmayı gerektirip gerektirmeyeceği verilen " +"özelliğe bağlıdır. Hiçbir deneysel özellik hala kullanılabilir veya " +"yapılandırılabilir olmak zorunda değildir. Bu ayara eklenecek herhangi bir " +"şeyin gelecekte olabilecek değişikliklerden etkilenmeyeceğini düşünmeyin. Şu " +"anda kullanılabilir anahtar sözcükler: • “scale-monitor-framebuffer” — " +"mutter’in HiDPI monitörleri yönetmesi için pencere içeriği yerine monitör " +"çerçeve arabelleğini ölçeklendirirken, mantıksal monitörleri mantıksal " +"piksel koordinat aralığına yerleştirmesini öntanımlı yapar. Yeniden başlatma " +"gerektirmez. • “rt-scheduler” — mutter isteğini bir düşük öncelikli gerçek " +"zamanlı sıralandırma yapar. Çalıştırılabilir (executable) veya kullanıcı " +"CAP_SYS_NICE’ye sahip olmalıdır. Yeniden başlatma gerektirir. • “autostart-" +"xwayland” — eğer X11 istemcileri varsa Xwayland’i miskin miskin başlatır. " +"Yeniden başlatma gerektirir." + +#: data/org.gnome.mutter.gschema.xml.in:134 +msgid "Modifier to use to locate the pointer" +msgstr "İşaretçiyi konumlamada kullanılacak değiştirici" + +#: data/org.gnome.mutter.gschema.xml.in:135 +msgid "This key will initiate the “locate pointer” action." +msgstr "Bu anahtar “işaretçiyi konumla” eylemini başlatacak." + +#: data/org.gnome.mutter.gschema.xml.in:142 +msgid "Timeout for check-alive ping" +msgstr "Canlılık denetim pingi için zaman aşımı" + +#: data/org.gnome.mutter.gschema.xml.in:143 +msgid "" +"Number of milliseconds a client has to respond to a ping request in order to " +"not be detected as frozen. Using 0 will disable the alive check completely." +msgstr "" +"İstemcinin donuk olarak saptanmaması için ping istemini yanıtlaması gereken " +"milisaniye sayısı. 0 kullanmak canlılık denetimini tümüyle devre dışı bırakır." + +#: data/org.gnome.mutter.gschema.xml.in:165 msgid "Select window from tab popup" msgstr "Pencereyi, sekme açılır penceresinden seç" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:18 +#: data/org.gnome.mutter.gschema.xml.in:170 msgid "Cancel tab popup" msgstr "Sekmeyi yeni pencerede açmayı iptal et" -#: ../src/tools/muffin-message.c:123 +#: data/org.gnome.mutter.gschema.xml.in:175 +msgid "Switch monitor configurations" +msgstr "Monitör yapılandırmaları arasında geçiş yap" + +#: data/org.gnome.mutter.gschema.xml.in:180 +msgid "Rotates the built-in monitor configuration" +msgstr "Yerleşik monitör yapılandırmaları arasında geçiş yapar" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "VT 1’e geç" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "VT 2’ye geç" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "VT 3’e geç" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "VT 4’e geç" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "VT 5’e geç" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "VT 6’ya geç" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "VT 7’ye geç" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "VT 8’e geç" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "VT 9’a geç" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "VT 10’a geç" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "VT 11’e geç" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "VT 12’ye geç" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "Kısayolları yeniden etkinleştir" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow X11 grabs to lock keyboard focus with Xwayland" +msgstr "X11 yakalamalarının Xwayland ile klavye odağı kilitlemesine izin ver" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 +msgid "" +"Allow all keyboard events to be routed to X11 “override redirect” windows " +"with a grab when running in Xwayland. This option is to support X11 clients " +"which map an “override redirect” window (which do not receive keyboard " +"focus) and issue a keyboard grab to force all keyboard events to that " +"window. This option is seldom used and has no effect on regular X11 windows " +"which can receive keyboard focus under normal circumstances. For a X11 grab " +"to be taken into account under Wayland, the client must also either send a " +"specific X11 ClientMessage to the root window or be among the applications " +"white-listed in key “xwayland-grab-access-rules”." +msgstr "" +"Xwayland içinde çalışırken tüm klavye etkinlikleri yakalamalı X11 “override " +"redirect” pencerelerine yönlendirilecek. Bu seçenek, “override redirect” " +"penceresi çizen (klavye odağı almayan) X11 istemcilerini desteklemek ve bu " +"istemcilerin tüm klavye etkinliklerini bu pencereye zorlayan klavye " +"yakalaması yayımlamasını sağlar. Bu seçenek nadiren kullanılır ve sıradan " +"koşullar altında klavye odağı alan sıradan X11 pencerelerinde etkisi yoktur. " +"Bir X11 yakalamasının Wayland altında hesaba katılması için istemci ya kök " +"pencereye belirli X11 ClientMessage’ı göndermeli ya da “xwayland-grab-access-" +"rules” anahtarındaki beyaz listeli uygulamalar arasında olmalıdır." + +#: data/org.gnome.mutter.wayland.gschema.xml.in:84 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "Klavye yakalamaları yapabilen Xwayland uygulamaları" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:85 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "" +"Xwayland altında X11 klavye yakalamaları yapmak için izin verilsin veya " +"verilmesin tüm X11 pencerelerinin kaynak adlarını veya kaynak sınıfını " +"listele. Verilen bir X11 penceresinin kaynak adı veya kaynak sınıfı “xprop " +"WM_CLASS” komutuyla elde edilebilir. Değerlerde “*” joker karakteri ve “?” " +"değiştirilebilir damga kullanımı desteklenmektedir. “!” ile başlayan " +"değerler, uygulamaları öntanımlı sistem listesinden feshetmek için beyaz " +"listeden önceliği olan kara listeye alınmıştır. Öntanımlı sistem listesi şu " +"uygulamaları içerir: “@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Kullanıcılar, " +"“restore-shortcuts” anahtar bağlama anahtarıyla tanımlanmış özel klavye " +"kısayolunu kullanarak var olan yakalamayı kırabilir." + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. +#. +#: src/backends/meta-input-settings.c:2567 #, c-format -msgid "Usage: %s\n" -msgstr "Kullanım: %s\n" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "_Küçült" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "_Büyült" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "Büyült_meyi Geri Al" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "Yukarı _Sar" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "_Sarmayı Geri Al" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "_Taşı" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "_Yeniden Boyutlandır" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "Başlık Çubuğunu _Ekranda Taşı" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "Her Zaman Ü_stte" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "Her Zaman _Görünen Çalışma Alanında" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "Yalnız _Bu Çalışma Alanında" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "_Soldaki Çalışma Alanına Taşı" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "S_ağdaki Çalışma Alanına Taşı" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "_Yukarıdaki Çalışma Alanına Taşı" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "_Aşağıdaki Çalışma Alanına Taşı" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "_Kapat" - -#: ../src/ui/menu.c:204 +msgid "Mode Switch (Group %d)" +msgstr "Kip anahtarı (Küme %d)" + +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2590 +msgid "Switch monitor" +msgstr "Monitör değiştir" + +#: src/backends/meta-input-settings.c:2592 +msgid "Show on-screen help" +msgstr "Ekranda yardımı göster" + +#: src/backends/meta-monitor.c:223 +msgid "Built-in display" +msgstr "Yerleşik ekran" + +#: src/backends/meta-monitor.c:252 +msgid "Unknown" +msgstr "Bilinmiyor" + +#: src/backends/meta-monitor.c:254 +msgid "Unknown Display" +msgstr "Bilinmeyen Ekran" + +#: src/backends/meta-monitor.c:262 #, c-format -msgid "Workspace %d%n" -msgstr "Çalışma Alanı %d%n" +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/menu.c:214 +#: src/backends/meta-monitor.c:270 #, c-format -msgid "Workspace 1_0" -msgstr "Çalışma Alanı 1_0" +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/menu.c:216 +#. Translators: this string will appear in Sysprof +#: src/backends/meta-profiler.c:79 +msgid "Compositor" +msgstr "Dizgici" + +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:533 #, c-format -msgid "Workspace %s%d" -msgstr "Çalışma Alanı %s%d" +msgid "" +"Another compositing manager is already running on screen %i on display “%s”." +msgstr "" +"“%2$s” monitöründeki %1$i ekranında zaten başka bir birleştirme yöneticisi " +"çalışıyor." -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "Başka Bir Çalışma Ala_nına Taşı" +#: src/core/bell.c:192 +msgid "Bell event" +msgstr "Etkinlik zili" -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" +#: src/core/main.c:190 +msgid "Disable connection to session manager" +msgstr "Ortam yöneticisine olan bağlantıyı kapat" -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" +#: src/core/main.c:196 +msgid "Replace the running window manager" +msgstr "Çalışan pencere yöneticisinin yerini al" + +#: src/core/main.c:202 +msgid "Specify session management ID" +msgstr "Ortam yönetim ID’sini belirt" + +#: src/core/main.c:207 +msgid "X Display to use" +msgstr "Kullanılacak X Ekranı" -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "üst" +#: src/core/main.c:213 +msgid "Initialize session from savefile" +msgstr "Ortamı kayıtlı dosyadan başlat" + +#: src/core/main.c:219 +msgid "Make X calls synchronous" +msgstr "X çağrılarını eşzamanlı yap" -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "alt" +#: src/core/main.c:226 +msgid "Run as a wayland compositor" +msgstr "Wayland dizgici olarak çalıştır" -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "sol" +#: src/core/main.c:232 +msgid "Run as a nested compositor" +msgstr "Yuvalanmış dizgici olarak çalıştır" -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "sağ" +#: src/core/main.c:238 +msgid "Run wayland compositor without starting Xwayland" +msgstr "Xwayland’i çalıştırmadan Wayland dizgici çalıştır" -#: ../src/ui/theme.c:286 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "çerçeve geometrisi \"%s\" boyutunu tanımlamıyor" +#: src/core/main.c:246 +msgid "Run as a full display server, rather than nested" +msgstr "İç içe değil tam ekran sunucusu olarak çalıştır" + +#: src/core/main.c:252 +msgid "Run with X11 backend" +msgstr "X11 arkayüzüyle çalıştır" -#: ../src/ui/theme.c:305 +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:151 #, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" +msgid "“%s” is not responding." +msgstr "“%s” yanıt vermiyor." + +#: src/core/meta-close-dialog-default.c:153 +msgid "Application is not responding." +msgstr "Uygulama yanıt vermiyor." + +#: src/core/meta-close-dialog-default.c:158 +msgid "" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." msgstr "" -"çerçeve geometrisi \"%s\" boyutunu \"%s\" pencere kenarı için tanımlamıyor" +"Uygulamanın devam etmesi için bir süre beklemeyi seçebilir veya tümüyle " +"çıkması için zorlayabilirsiniz." -#: ../src/ui/theme.c:342 +#: src/core/meta-close-dialog-default.c:165 +msgid "_Force Quit" +msgstr "_Zorla Çık" + +#: src/core/meta-close-dialog-default.c:165 +msgid "_Wait" +msgstr "_Bekle" + +#: src/core/mutter.c:38 #, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "%g kabul edilebilir bir düğme en-boy oranı değil" +msgid "" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" +msgstr "" +"mutter %s\n" +"Telif Hakkı © 2001-%d Havoc Pennington, Red Hat, Inc., ve diğerleri\n" +"Bu bir özgür yazılımdır; kopyalama koşullarını öğrenmek için kaynağa bakın.\n" +"Hiçbir garanti YOK; BELİRLİ BİR AMACA UYGUNLUK ya da SATILABİLİRLİK için " +"dahi.\n" + +#: src/core/mutter.c:52 +msgid "Print version" +msgstr "Sürümü yazdır" + +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "Kullanılacak Mutter eklentisi" -#: ../src/ui/theme.c:354 +#: src/core/prefs.c:1911 #, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "Çerçeve geometrisi düğmelerin boyutunu tanımlamıyor" +msgid "Workspace %d" +msgstr "Çalışma Alanı %d" + +#: src/core/util.c:122 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter, ayrıntılı kip desteği olmadan derlenmiş\n" -#: ../src/ui/theme.c:1067 +#: src/wayland/meta-wayland-tablet-pad.c:568 #, c-format -msgid "Gradients should have at least two colors" -msgstr "Renk geçişlerinde en az iki renk olmalı" +msgid "Mode Switch: Mode %d" +msgstr "Kip Anahtarı: Kip %d" -#: ../src/ui/theme.c:1219 +#: src/x11/meta-x11-display.c:676 #, c-format msgid "" -"GTK custom color specification must have color name and fallback in " -"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." msgstr "" -"GTK özel renk belirtiminde parantez içinde renk adı ve fallback kelimesi yer " -"almalıdır; örneğin, gtk:custom[foo,bar]; \"%s\" ayrıştırılamadı" +"“%s” ekranı zaten bir pencere yöneticisine sahip; geçerli pencere " +"yöneticisinin yerine bir başkasını koymak için --replace seçeneğini " +"kullanmayı deneyin." + +#: src/x11/meta-x11-display.c:1089 +msgid "Failed to initialize GDK\n" +msgstr "GDK ilklendirilemedi\n" -#: ../src/ui/theme.c:1235 +#: src/x11/meta-x11-display.c:1113 #, c-format +msgid "Failed to open X Window System display “%s”\n" +msgstr "X Pencere Sistemi “%s” ekranı açılamadı\n" + +#: src/x11/meta-x11-display.c:1196 +#, c-format +msgid "Screen %d on display “%s” is invalid\n" +msgstr "“%2$s” monitöründeki %1$d ekranı geçersiz\n" + +#: src/x11/meta-x11-selection-input-stream.c:460 +#, c-format +msgid "Format %s not supported" +msgstr "%s biçimi desteklenmiyor" + +#: src/x11/session.c:1821 msgid "" -"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" -"_ are valid" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." msgstr "" -"gtk:custom color_name parametresinin adında geçersiz karakter '%c'; sadece A-" -"Za-z0-9-_ karakterleri geçerlidir" +"Bu pencereler, “geçerli ayarları kaydet” özelliğini desteklemiyor ve bir " +"dahaki girişinizde elle yeniden başlatılmak zorundadır." + +#: src/x11/window-props.c:569 +#, c-format +msgid "%s (on %s)" +msgstr "%s (%s üzerinde)" + +#~ msgid "Move window one workspace to the left" +#~ msgstr "Pencereyi soldaki çalışma alanına taşı" + +#~ msgid "Move window one workspace to the right" +#~ msgstr "Pencereyi sağdaki çalışma alanına taşı" + +#~ msgid "Move to workspace left" +#~ msgstr "Soldaki çalışma alanına taşı" + +#~ msgid "Move to workspace right" +#~ msgstr "Sağdaki çalışma alanına taşı" + +#~ msgid "Toggle shaded state" +#~ msgstr "Toplanmış durumu değiştir" + +#~ msgid "Failed to scan themes directory: %s\n" +#~ msgstr "Tema dizini taranırken hata oluştu: %s\n" + +#~ msgid "" +#~ "Could not find a theme! Be sure %s exists and contains the usual themes.\n" +#~ msgstr "" +#~ "Hiç tema bulunamadı! %s varlığından ve bildiğimiz temaları içerdiğinden " +#~ "emin olun.\n" + +#~ msgid "Screen %d on display \"%s\" already has a window manager\n" +#~ msgstr "" +#~ "\"%2$s\" X oturumundaki ekran %1$d bir pencere yöneticisine zaten sahip\n" + +#~ msgid "%d x %d" +#~ msgstr "%d x %d" + +#~ msgid "top" +#~ msgstr "üst" + +#~ msgid "bottom" +#~ msgstr "alt" + +#~ msgid "left" +#~ msgstr "sol" + +#~ msgid "right" +#~ msgstr "sağ" + +#~ msgid "frame geometry does not specify \"%s\" dimension" +#~ msgstr "çerçeve geometrisi \"%s\" boyutunu tanımlamıyor" + +#~ msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" +#~ msgstr "" +#~ "çerçeve geometrisi \"%s\" boyutunu \"%s\" pencere kenarı için tanımlamıyor" + +#~ msgid "Button aspect ratio %g is not reasonable" +#~ msgstr "%g kabul edilebilir bir düğme en-boy oranı değil" + +#~ msgid "Frame geometry does not specify size of buttons" +#~ msgstr "Çerçeve geometrisi düğmelerin boyutunu tanımlamıyor" + +#~ msgid "Gradients should have at least two colors" +#~ msgstr "Renk geçişlerinde en az iki renk olmalı" + +#~ msgid "" +#~ "GTK custom color specification must have color name and fallback in " +#~ "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" +#~ msgstr "" +#~ "GTK özel renk belirtiminde parantez içinde renk adı ve fallback kelimesi " +#~ "yer almalıdır; örneğin, gtk:custom[foo,bar]; \"%s\" ayrıştırılamadı" + +#~ msgid "" +#~ "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-" +#~ "z0-9-_ are valid" +#~ msgstr "" +#~ "gtk:custom color_name parametresinin adında geçersiz karakter '%c'; " +#~ "sadece A-Za-z0-9-_ karakterleri geçerlidir" + +#~ msgid "" +#~ "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " +#~ "fit the format" +#~ msgstr "" +#~ "Gtk:custom biçimi \"gtk:custom(color_name,fallback)\" şeklindedir; \"%s\" " +#~ "biçime uymuyor" + +#~ msgid "" +#~ "GTK color specification must have the state in brackets, e.g. gtk:" +#~ "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "GTK renk belirtiminde köşeli parantezler arasında durum verilmelidir; " +#~ "örneğin, gtk:fg[NORMAL] belirtiminde NORMAL, durumu gösterir; \"%s\" " +#~ "ayrıştırılamadı" + +#~ msgid "" +#~ "GTK color specification must have a close bracket after the state, e.g. " +#~ "gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "GTK renk belirtiminde durumdan sonra sağ köşeli parantezleri gelmelidir; " +#~ "örneğin, gtk:fg[NORMAL] belirtiminde NORMAL, durumu gösterir; \"%s\" " +#~ "ayrıştırılamadı" + +#~ msgid "Did not understand state \"%s\" in color specification" +#~ msgstr "Renk belirtimindeki \"%s\" durumu anlaşılamadı" + +#~ msgid "Did not understand color component \"%s\" in color specification" +#~ msgstr "Renk belirtimindeki \"%s\" renk bileşeni anlaşılamadı" + +#~ msgid "" +#~ "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit " +#~ "the format" +#~ msgstr "" +#~ "Renk karışımının doğru biçimi \"blend/bg_color/fg_color/alpha\"dır; \"%s" +#~ "\" bu biçime uymuyor" + +#~ msgid "Could not parse alpha value \"%s\" in blended color" +#~ msgstr "Renk karışımındaki \"%s\" alfa değeri ayrıştırılamadı" + +#~ msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" +#~ msgstr "Renk karışımının alfa değeri \"%s\", 0.0 ile 1.0 arasında değil" + +#~ msgid "" +#~ "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the " +#~ "format" +#~ msgstr "" +#~ "Gölgelendirmenin doğru biçimi \"shade/bas_color/factor\"dır; \"%s\" bu " +#~ "biçime uymuyor" + +#~ msgid "Could not parse shade factor \"%s\" in shaded color" +#~ msgstr "Gölgeli rengin gölge katsayısı olan \"%s\" ayrıştırılamadı" + +#~ msgid "Shade factor \"%s\" in shaded color is negative" +#~ msgstr "Gölgeli rengin gölge katsayısı olan \"%s\", negatif" + +#~ msgid "Could not parse color \"%s\"" +#~ msgstr "\"%s\" rengi ayrıştırılamadı" + +#~ msgid "Coordinate expression contains character '%s' which is not allowed" +#~ msgstr "Kordinat ifadesi izin verilmeyen '%s' karakterini içeriyor" + +#~ msgid "" +#~ "Coordinate expression contains floating point number '%s' which could not " +#~ "be parsed" +#~ msgstr "" +#~ "Kordinat ifadesi '%s' gerçel sayısını içeriyor ve bu sayı ayrıştırılamıyor" + +#~ msgid "" +#~ "Coordinate expression contains integer '%s' which could not be parsed" +#~ msgstr "Kordinat ifadesi ayrıştırılamayan '%s' tamsayısını içeriyor" + +#~ msgid "" +#~ "Coordinate expression contained unknown operator at the start of this " +#~ "text: \"%s\"" +#~ msgstr "" +#~ "Kordinat ifadesi bu metnin başında bilinmeyen bir işleç içeriyor: \"%s\"" + +#~ msgid "Coordinate expression was empty or not understood" +#~ msgstr "Kordinat ifadesi boş ya da anlaşılamadı" + +#~ msgid "Coordinate expression results in division by zero" +#~ msgstr "Kordinat ifadesi sıfıra bölümle sonuçlanıyor" + +#~ msgid "" +#~ "Coordinate expression tries to use mod operator on a floating-point number" +#~ msgstr "" +#~ "Kordinat ifadesi bir gerçel sayı üzerinde mod (kalan bulma) işlecini " +#~ "kullanmaya çalıştı" + +#~ msgid "" +#~ "Coordinate expression has an operator \"%s\" where an operand was expected" +#~ msgstr "Kordinat ifadesi işleneni beklenen \"%s\", işlecini içeriyor" + +#~ msgid "Coordinate expression had an operand where an operator was expected" +#~ msgstr "Kordinat ifadesi işleci beklenen bir işlenen içeriyor" + +#~ msgid "Coordinate expression ended with an operator instead of an operand" +#~ msgstr "Kordinat ifadesi bir işlenen yerine işleçle bitiyor" + +#~ msgid "" +#~ "Coordinate expression has operator \"%c\" following operator \"%c\" with " +#~ "no operand in between" +#~ msgstr "" +#~ "Kordinat ifadesi birbirlerinin izleyen ve aralarında işlenen olmayan " +#~ "\"%2$c\" ve \"%1$c\" işleçlerini içeriyor" + +#~ msgid "Coordinate expression had unknown variable or constant \"%s\"" +#~ msgstr "" +#~ "Kordinat ifadesi bilinmeyen bir değişken ya da sabit olan \"%s\" içeriyor" + +#~ msgid "Coordinate expression parser overflowed its buffer." +#~ msgstr "Kordinat belirtim ayrıştırıcısı tamponundan taştı." + +#~ msgid "" +#~ "Coordinate expression had a close parenthesis with no open parenthesis" +#~ msgstr "Kordinat ifadesi sol parantezi olmayan bir sağ parantez içeriyor" + +#~ msgid "" +#~ "Coordinate expression had an open parenthesis with no close parenthesis" +#~ msgstr "Kordinat ifadesi sağ parantezi olmayan bir sol parantez içeriyor" + +#~ msgid "Coordinate expression doesn't seem to have any operators or operands" +#~ msgstr "" +#~ "Kordinat ifadesi göründüğü kadarıyla ne işleç ne de işlenen içeriyor" + +#~ msgid "Theme contained an expression that resulted in an error: %s\n" +#~ msgstr "Tema bir hata ile sonuçlanan ifadeye sahip: %s\n" + +#~ msgid "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " +#~ "specified for this frame style" +#~ msgstr "" +#~ "Bu çerçeve biçeminde <button function=\"%s\" state=\"%s\" draw_ops=\"her " +#~ "neyse\"/> belirtilmek zorunda" + +#~ msgid "" +#~ "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/" +#~ ">" +#~ msgstr "" +#~ "Eksik <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"her neyse\"/>" + +#~ msgid "Failed to load theme \"%s\": %s\n" +#~ msgstr "\"%s\" teması yüklenemedi: %s\n" + +#~ msgid "No <%s> set for theme \"%s\"" +#~ msgstr "\"%2$s\" temasında hiç <%1$s> atanmamış" + +#~ msgid "" +#~ "No frame style set for window type \"%s\" in theme \"%s\", add a <window " +#~ "type=\"%s\" style_set=\"whatever\"/> element" +#~ msgstr "" +#~ "\"%2$s\" temasında \"%1$s\" pencere türüne çerçeve biçemi atanmamış, bir " +#~ "<window type=\"%3$s\" style_set=\"her neyse\"/> öğesi ekleyin" + +#~ msgid "" +#~ "User-defined constants must begin with a capital letter; \"%s\" does not" +#~ msgstr "" +#~ "Kullanıcı tanımlı sabitler büyük harfle başlamalıdır; \"%s\" buna uymuyor" + +#~ msgid "Constant \"%s\" has already been defined" +#~ msgstr "\"%s\" sabit değeri zaten tanımlanmış" + +#~ msgid "No \"%s\" attribute on element <%s>" +#~ msgstr "Hibir \"%s\" özniteliği <%s> öğesi üzerinde yok" + +#~ msgid "Line %d character %d: %s" +#~ msgstr "Satır %d karakter %d: %s" + +#~ msgid "Attribute \"%s\" repeated twice on the same <%s> element" +#~ msgstr "\"%s\" özniteliği aynı <%s> öğesinde iki kez kullanılmış" + +#~ msgid "Attribute \"%s\" is invalid on <%s> element in this context" +#~ msgstr "\"%s\" özniteliği bu içerikte <%s> öğesi için geçersiz" + +#~ msgid "Could not parse \"%s\" as an integer" +#~ msgstr "\"%s\" bir tamsayı olarak ayrıştırılamadı" + +#~ msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +#~ msgstr "\"%2$s\" dizgisinin sonundaki \"%1$s\" karakterleri anlaşılmadı" + +#~ msgid "Integer %ld must be positive" +#~ msgstr "%ld tamsayısı pozitif olmalı" + +#~ msgid "Integer %ld is too large, current max is %d" +#~ msgstr "%ld tamsayısı çok büyük, şu anda üst sınır %d" + +#~ msgid "Could not parse \"%s\" as a floating point number" +#~ msgstr "\"%s\" bir gerçel sayı olarak ayrıştırılamadı" + +#~ msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" +#~ msgstr "" +#~ "Mantıksal değerler ancak \"true\" (doğru) ya da \"false\" (yanlış) " +#~ "değerlerini alabilir; \"%s\" olamaz" + +#~ msgid "Angle must be between 0.0 and 360.0, was %g\n" +#~ msgstr "Açı 0.0 ile 360.0 arasında olmalı, %g verilmiş\n" + +#~ msgid "" +#~ "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" +#~ msgstr "" +#~ "Alfa 0.0 (görünmez) ile 1.0 (düz renk) arasında olmalıydı ama %g " +#~ "verilmiş\n" + +#~ msgid "" +#~ "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," +#~ "large,x-large,xx-large)\n" +#~ msgstr "" +#~ "Geçersiz öğe ölçüsü \"%s\" (şunlardan biri olmalıdır: xx-small,x-small," +#~ "small,medium,large,x-large,xx-large)\n" + +#~ msgid "<%s> name \"%s\" used a second time" +#~ msgstr "<%s> adı \"%s\" ikinci kez kullanılmış" + +#~ msgid "<%s> parent \"%s\" has not been defined" +#~ msgstr "<%s> üst değeri \"%s\" tanımlanmamış" + +#~ msgid "<%s> geometry \"%s\" has not been defined" +#~ msgstr "<%s> geometrisi \"%s\" tanımlanmamış" + +#~ msgid "<%s> must specify either a geometry or a parent that has a geometry" +#~ msgstr "<%s>, ya bir geometri ya da geometrisi olan bir üst öğe belirtmeli" + +#~ msgid "You must specify a background for an alpha value to be meaningful" +#~ msgstr "" +#~ "Arkaplanı anlamlı olabilmesi için bir alfa değeri ile belirtmelisiniz" + +#~ msgid "Unknown type \"%s\" on <%s> element" +#~ msgstr "<%2$s> öğesinde bilinmeyen type \"%1$s\"" + +#~ msgid "Unknown style_set \"%s\" on <%s> element" +#~ msgstr "<%2$s> öğesinde bilinmeyen style_set \"%1$s\"" + +#~ msgid "Window type \"%s\" has already been assigned a style set" +#~ msgstr "\"%s\" pencere türünün önceden atanmış bir biçem kümesi var" + +#~ msgid "Element <%s> is not allowed below <%s>" +#~ msgstr "<%s> öğesi <%s> altında kullanılamaz" + +#~ msgid "" +#~ "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio" +#~ "\" for buttons" +#~ msgstr "" +#~ "Düğmeler için hem \"button_width\"/\"button_height \" hem \"aspect_ratio" +#~ "\" belirtilemiyor" + +#~ msgid "Distance \"%s\" is unknown" +#~ msgstr "\"%s\" uzaklığı bilinmiyor" + +#~ msgid "Aspect ratio \"%s\" is unknown" +#~ msgstr "\"%s\" en-boy oranı bilinmiyor" + +#~ msgid "Border \"%s\" is unknown" +#~ msgstr "\"%s\" pencere kenarı bilinmiyor" + +#~ msgid "No \"start_angle\" or \"from\" attribute on element <%s>" +#~ msgstr "" +#~ "<%s> öğesinde \"start_angle\" (başlama açısı) ya da \"from\" özniteliği " +#~ "yok" + +#~ msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" +#~ msgstr "" +#~ "<%s> öğesinde \"extent_angle\" (genişletme açısı) ya da \"to\" özniteliği " +#~ "yok" -#: ../src/ui/theme.c:1249 -#, c-format -msgid "" -"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " -"fit the format" -msgstr "" -"Gtk:custom biçimi \"gtk:custom(color_name,fallback)\" şeklindedir; \"%s\" " -"biçime uymuyor" +#~ msgid "Did not understand value \"%s\" for type of gradient" +#~ msgstr "Renk geçişi türü olarak verilen \"%s\" değeri anlaşılamadı" -#: ../src/ui/theme.c:1294 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"GTK renk belirtiminde köşeli parantezler arasında durum verilmelidir; " -"örneğin, gtk:fg[NORMAL] belirtiminde NORMAL, durumu gösterir; \"%s\" " -"ayrıştırılamadı" +#~ msgid "Did not understand fill type \"%s\" for <%s> element" +#~ msgstr "<%2$s> öğesinin doldurma türü \"%1$s\" anlaşılamadı" -#: ../src/ui/theme.c:1308 -#, c-format -msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"GTK renk belirtiminde durumdan sonra sağ köşeli parantezleri gelmelidir; " -"örneğin, gtk:fg[NORMAL] belirtiminde NORMAL, durumu gösterir; \"%s\" " -"ayrıştırılamadı" +#~ msgid "Did not understand state \"%s\" for <%s> element" +#~ msgstr "<%2$s> öğesi için \"%1$s\" durumu anlaşılamadı" -#: ../src/ui/theme.c:1319 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "Renk belirtimindeki \"%s\" durumu anlaşılamadı" +#~ msgid "Did not understand shadow \"%s\" for <%s> element" +#~ msgstr "<%2$s> öğesi için \"%1$s\" gölgesi anlaşılamadı" -#: ../src/ui/theme.c:1332 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "Renk belirtimindeki \"%s\" renk bileşeni anlaşılamadı" +#~ msgid "Did not understand arrow \"%s\" for <%s> element" +#~ msgstr "<%2$s> öğesi için \"%1$s\" oku anlaşılamadı" -#: ../src/ui/theme.c:1361 -#, c-format -msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" -msgstr "" -"Renk karışımının doğru biçimi \"blend/bg_color/fg_color/alpha\"dır; \"%s\" " -"bu biçime uymuyor" +#~ msgid "No <draw_ops> called \"%s\" has been defined" +#~ msgstr "\"%s\" adında hiç <draw_ops> tanımlanmamış" -#: ../src/ui/theme.c:1372 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "Renk karışımındaki \"%s\" alfa değeri ayrıştırılamadı" +#~ msgid "Including draw_ops \"%s\" here would create a circular reference" +#~ msgstr "Burada \"%s\" draw_ops'unu içermek çevrimsel gönderime yol açar" -#: ../src/ui/theme.c:1382 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "Renk karışımının alfa değeri \"%s\", 0.0 ile 1.0 arasında değil" +#~ msgid "Unknown position \"%s\" for frame piece" +#~ msgstr "Çerçeve parçası için bilinmeyen konum \"%s\"" -#: ../src/ui/theme.c:1429 -#, c-format -msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "" -"Gölgelendirmenin doğru biçimi \"shade/bas_color/factor\"dır; \"%s\" bu " -"biçime uymuyor" +#~ msgid "Frame style already has a piece at position %s" +#~ msgstr "Çerçeve biçeminin %s konumunda zaten bir parça var" -#: ../src/ui/theme.c:1440 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "Gölgeli rengin gölge katsayısı olan \"%s\" ayrıştırılamadı" +#~ msgid "No <draw_ops> with the name \"%s\" has been defined" +#~ msgstr "\"%s\" adında hiç <draw_ops> tanımlanmamış" -#: ../src/ui/theme.c:1450 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "Gölgeli rengin gölge katsayısı olan \"%s\", negatif" +#~ msgid "Unknown function \"%s\" for button" +#~ msgstr "Düğme için geçersiz işlev \"%s\"" -#: ../src/ui/theme.c:1479 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "\"%s\" rengi ayrıştırılamadı" +#~ msgid "Button function \"%s\" does not exist in this version (%d, need %d)" +#~ msgstr "Düğme işlevi \"%s\" bu sürümde mevcut değil (%d, gereken %d)" -#: ../src/ui/theme.c:1790 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "Kordinat ifadesi izin verilmeyen '%s' karakterini içeriyor" +#~ msgid "Unknown state \"%s\" for button" +#~ msgstr "Düğme için geçersiz durum \"%s\"" -#: ../src/ui/theme.c:1817 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "" -"Kordinat ifadesi '%s' gerçel sayısını içeriyor ve bu sayı ayrıştırılamıyor" +#~ msgid "Frame style already has a button for function %s state %s" +#~ msgstr "Çerçeve biçeminde %s işlevi, %s durumu için zaten bir düğme var" -#: ../src/ui/theme.c:1831 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "Kordinat ifadesi ayrıştırılamayan '%s' tamsayısını içeriyor" +#~ msgid "\"%s\" is not a valid value for focus attribute" +#~ msgstr "\"%s\", odak özniteliği için geçerli bir değer değil" -#: ../src/ui/theme.c:1953 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "" -"Kordinat ifadesi bu metnin başında bilinmeyen bir işleç içeriyor: \"%s\"" +#~ msgid "\"%s\" is not a valid value for state attribute" +#~ msgstr "\"%s\", durum özniteliği için geçerli bir değer değil" -#: ../src/ui/theme.c:2010 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "Kordinat ifadesi boş ya da anlaşılamadı" +#~ msgid "A style called \"%s\" has not been defined" +#~ msgstr "\"%s\" adlı bir biçem tanımlanmamış" -#: ../src/ui/theme.c:2121 ../src/ui/theme.c:2131 ../src/ui/theme.c:2165 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "Kordinat ifadesi sıfıra bölümle sonuçlanıyor" +#~ msgid "\"%s\" is not a valid value for resize attribute" +#~ msgstr "" +#~ "\"%s\", yeniden boyutlandırma özniteliği için geçerli bir değer değil" -#: ../src/ui/theme.c:2173 -#, c-format -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "" -"Kordinat ifadesi bir gerçel sayı üzerinde mod (kalan bulma) işlecini " -"kullanmaya çalıştı" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized/shaded " +#~ "states" +#~ msgstr "" +#~ "<%s> öğesinin büyütülmüş/toplanmış durumlarında \"resize\" özniteliği " +#~ "bulunmamalı" -#: ../src/ui/theme.c:2229 -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "Kordinat ifadesi işleneni beklenen \"%s\", işlecini içeriyor" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized states" +#~ msgstr "" +#~ "<%s> öğesinin büyütülmüş durumlarında \"resize\" özniteliği bulunmamalı" -#: ../src/ui/theme.c:2238 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "Kordinat ifadesi işleci beklenen bir işlenen içeriyor" +#~ msgid "Style has already been specified for state %s resize %s focus %s" +#~ msgstr "" +#~ "%s durumu, %s yeniden boyutlandırma, %s odak için biçem zaten belirtilmiş" -#: ../src/ui/theme.c:2246 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "Kordinat ifadesi bir işlenen yerine işleçle bitiyor" +#~ msgid "Style has already been specified for state %s focus %s" +#~ msgstr "%s durumu, odak %s için biçem zaten belirtilmiş" -#: ../src/ui/theme.c:2256 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" -"Kordinat ifadesi birbirlerinin izleyen ve aralarında işlenen olmayan \"%2$c" -"\" ve \"%1$c\" işleçlerini içeriyor" +#~ msgid "" +#~ "Can't have a two draw_ops for a <piece> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Bir <piece> öğesi içinde iki draw_ops olamaz (tema, ya bir draw_ops " +#~ "özniteliğiyle bir <draw_ops> öğesi, ya da iki öğe belirtmiş)" -#: ../src/ui/theme.c:2407 ../src/ui/theme.c:2452 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "" -"Kordinat ifadesi bilinmeyen bir değişken ya da sabit olan \"%s\" içeriyor" +#~ msgid "" +#~ "Can't have a two draw_ops for a <button> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Bir <button> öğesi içinde iki draw_ops olamaz (tema, ya bir draw_ops " +#~ "özniteliğiyle bir <draw_ops> öğesi, ya da iki öğe belirtmiş)" -#: ../src/ui/theme.c:2506 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "Kordinat belirtim ayrıştırıcısı tamponundan taştı." +#~ msgid "" +#~ "Can't have a two draw_ops for a <menu_icon> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "Bir <menu_icon> öğesi içinde iki draw_ops olamaz (tema, ya bir draw_ops " +#~ "özniteliğiyle bir <draw_ops> öğesi, ya da iki öğe belirtmiş)" -#: ../src/ui/theme.c:2535 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "Kordinat ifadesi sol parantezi olmayan bir sağ parantez içeriyor" +#~ msgid "Bad version specification '%s'" +#~ msgstr "Kötü Sürüm Belirtimi '%s'" -#: ../src/ui/theme.c:2599 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "Kordinat ifadesi sağ parantezi olmayan bir sol parantez içeriyor" +#~ msgid "" +#~ "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" +#~ "theme-2.xml" +#~ msgstr "" +#~ "\"version\" özniteliği metacity-theme-1.xml veya metacity-theme-2.xml " +#~ "içerisinde kullanılamaz" -#: ../src/ui/theme.c:2610 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "Kordinat ifadesi göründüğü kadarıyla ne işleç ne de işlenen içeriyor" +#~ msgid "" +#~ "Theme requires version %s but latest supported theme version is %d.%d" +#~ msgstr "" +#~ "Tema için %s sürümü gerekli ancak en son desteklenen tema sürümü %d.%d" -#: ../src/ui/theme.c:2822 ../src/ui/theme.c:2842 ../src/ui/theme.c:2862 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "Tema bir hata ile sonuçlanan ifadeye sahip: %s\n" +#~ msgid "Outermost element in theme must be <metacity_theme> not <%s>" +#~ msgstr "Temanın en dış öğesi <%s> değil <metacity_theme> olmalıdır" -#: ../src/ui/theme.c:4533 -#, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" -"Bu çerçeve biçeminde <button function=\"%s\" state=\"%s\" draw_ops=\"her " -"neyse\"/> belirtilmek zorunda" +#~ msgid "" +#~ "Element <%s> is not allowed inside a name/author/date/description element" +#~ msgstr "" +#~ "name/author/date/description öğelerinin içinde <%s> öğesi bulunmamalıdır" -#: ../src/ui/theme.c:5066 ../src/ui/theme.c:5091 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" -"Eksik <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"her neyse\"/>" +#~ msgid "Element <%s> is not allowed inside a <constant> element" +#~ msgstr "<constant> öğesinin içinde <%s> öğesi bulunmamalıdır" -#: ../src/ui/theme.c:5139 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "\"%s\" teması yüklenemedi: %s\n" +#~ msgid "" +#~ "Element <%s> is not allowed inside a distance/border/aspect_ratio element" +#~ msgstr "" +#~ "distance/border/aspect_ratio öğelerinin içinde <%s> öğesi bulunmamalıdır" -#: ../src/ui/theme.c:5275 ../src/ui/theme.c:5282 ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 ../src/ui/theme.c:5303 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "\"%2$s\" temasında hiç <%1$s> atanmamış" +#~ msgid "Element <%s> is not allowed inside a draw operation element" +#~ msgstr "draw operation öğesinin içinde <%s> öğesi bulunmamalıdır" -#: ../src/ui/theme.c:5311 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" -"\"%2$s\" temasında \"%1$s\" pencere türüne çerçeve biçemi atanmamış, bir " -"<window type=\"%3$s\" style_set=\"her neyse\"/> öğesi ekleyin" +#~ msgid "Element <%s> is not allowed inside a <%s> element" +#~ msgstr "<%2$s> öğesinin içinde <%1$s> öğesi bulunmamalıdır" -#: ../src/ui/theme.c:5709 ../src/ui/theme.c:5771 ../src/ui/theme.c:5834 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" -"Kullanıcı tanımlı sabitler büyük harfle başlamalıdır; \"%s\" buna uymuyor" +#~ msgid "No draw_ops provided for frame piece" +#~ msgstr "Çerçeve parçası için hiç draw_ops sağlanmamış" -#: ../src/ui/theme.c:5717 ../src/ui/theme.c:5779 ../src/ui/theme.c:5842 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "\"%s\" sabit değeri zaten tanımlanmış" +#~ msgid "No draw_ops provided for button" +#~ msgstr "Düğme için hiç draw_ops sağlanmamış" -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. -#. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "Hibir \"%s\" özniteliği <%s> öğesi üzerinde yok" +#~ msgid "No text is allowed inside element <%s>" +#~ msgstr "<%s> öğesinin içinde metin bulunmamalıdır" -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Satır %d karakter %d: %s" +#~ msgid "<%s> specified twice for this theme" +#~ msgstr "Bu tema için <%s> iki kez belirtilmiş" -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "\"%s\" özniteliği aynı <%s> öğesinde iki kez kullanılmış" +#~ msgid "Failed to find a valid file for theme %s\n" +#~ msgstr "Tema %s için geçerli bir dosya bulunamadı\n" -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "\"%s\" özniteliği bu içerikte <%s> öğesi için geçersiz" +#~ msgid "Unknown window information request: %d" +#~ msgstr "Bilinmeyen pencere bilgi isteği: %d" -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "\"%s\" bir tamsayı olarak ayrıştırılamadı" +#~ msgid "Missing %s extension required for compositing" +#~ msgstr "Kompozisyon için gerekli olan %s eklentisi eksik" -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "\"%2$s\" dizgisinin sonundaki \"%1$s\" karakterleri anlaşılmadı" +#~ msgid "" +#~ "Some other program is already using the key %s with modifiers %x as a " +#~ "binding\n" +#~ msgstr "" +#~ "%s tuşu %x değiştiricileriyle birlikte başka bir uygulama tarafından tuş " +#~ "bağıolarak kullanılıyor\n" -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "%ld tamsayısı pozitif olmalı" +#~ msgid "" +#~ "Workarounds for broken applications disabled. Some applications may not " +#~ "behave properly.\n" +#~ msgstr "" +#~ "Hatalı uygulamalara yönelik çözümler devre dışı. Bazı uygulamalar düzgün " +#~ "işlemeyebilir.\n" -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "%ld tamsayısı çok büyük, şu anda üst sınır %d" +#~ msgid "Could not parse font description \"%s\" from GSettings key %s\n" +#~ msgstr "" +#~ "\"%s\" yazıtipi tanımlaması, %s GSettings anahtarından ayrıştırılamadı\n" -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "\"%s\" bir gerçel sayı olarak ayrıştırılamadı" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" +#~ msgstr "" +#~ "Yapılandırma veritabanında bulunan \"%s\", fare düğme düzenleyicisi " +#~ "olarak geçerli bir değer değil\n" -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "" -"Mantıksal değerler ancak \"true\" (doğru) ya da \"false\" (yanlış) " -"değerlerini alabilir; \"%s\" olamaz" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for " +#~ "keybinding \"%s\"\n" +#~ msgstr "" +#~ "Yapılandırma veritabanında bulunan \"%s\", \"%s\" tuş bağı olarak geçerli " +#~ "bir değer değil\n" -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "Açı 0.0 ile 360.0 arasında olmalı, %g verilmiş\n" +#~ msgid "" +#~ "Could not acquire window manager selection on screen %d display \"%s\"\n" +#~ msgstr "" +#~ "\"%2$s\" X oturumundaki ekran %1$d hangi pencere yöneticisine " +#~ "sahipöğrenilemedi\n" -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" -"Alfa 0.0 (görünmez) ile 1.0 (düz renk) arasında olmalıydı ama %g verilmiş\n" +#~ msgid "Could not release screen %d on display \"%s\"\n" +#~ msgstr "\"%2$s\" X oturumundaki ekran %1$d serberst bırakılamadı\"\n" -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"Geçersiz öğe ölçüsü \"%s\" (şunlardan biri olmalıdır: xx-small,x-small,small," -"medium,large,x-large,xx-large)\n" +#~ msgid "Could not create directory '%s': %s\n" +#~ msgstr "'%s' dizini oluşturulamadı: %s\n" -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s> adı \"%s\" ikinci kez kullanılmış" +#~ msgid "Could not open session file '%s' for writing: %s\n" +#~ msgstr "'%s' oturum dosyası yazma için açılamadı: %s\n" -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "<%s> üst değeri \"%s\" tanımlanmamış" +#~ msgid "Error writing session file '%s': %s\n" +#~ msgstr "'%s' oturum dosyasına yazmada hata: %s\n" -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "<%s> geometrisi \"%s\" tanımlanmamış" +#~ msgid "Error closing session file '%s': %s\n" +#~ msgstr "'%s' oturum dosyasını kapamada hata: %s\n" -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "<%s>, ya bir geometri ya da geometrisi olan bir üst öğe belirtmeli" +#~ msgid "Failed to parse saved session file: %s\n" +#~ msgstr "Kaydedilmiş oturum dosyası ayrıştırırken hata: %s\n" -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "Arkaplanı anlamlı olabilmesi için bir alfa değeri ile belirtmelisiniz" +#~ msgid "<mutter_session> attribute seen but we already have the session ID" +#~ msgstr "" +#~ "Geçerli bir oturum kimliği bulunmasına karşın <metacity_session> " +#~ "özniteliğiyle karşılaşıldı" -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "<%2$s> öğesinde bilinmeyen type \"%1$s\"" +#~ msgid "Unknown attribute %s on <%s> element" +#~ msgstr "Bilinmeyen öznitelik %2$s üzerinde <%1$s> öğesi" -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "<%2$s> öğesinde bilinmeyen style_set \"%1$s\"" +#~ msgid "nested <window> tag" +#~ msgstr "iç içe <window> imi" -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "\"%s\" pencere türünün önceden atanmış bir biçem kümesi var" - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "<%s> öğesi <%s> altında kullanılamaz" +#~ msgid "Unknown element %s" +#~ msgstr "Bilinmeyen öğe %s" -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" -msgstr "" -"Düğmeler için hem \"button_width\"/\"button_height \" hem \"aspect_ratio\" " -"belirtilemiyor" +#~ msgid "Failed to open debug log: %s\n" +#~ msgstr "Hata ayıklama günlüğü açılamadı: %s\n" -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "\"%s\" uzaklığı bilinmiyor" +#~ msgid "Failed to fdopen() log file %s: %s\n" +#~ msgstr "fdopen() günlük dosyası %s açılamadı: %s\n" -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "\"%s\" en-boy oranı bilinmiyor" +#~ msgid "Opened log file %s\n" +#~ msgstr "%s günlük dosyası açıldı\n" -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "\"%s\" pencere kenarı bilinmiyor" +#~ msgid "Window manager: " +#~ msgstr "Pencere yöneticisi: " -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "" -"<%s> öğesinde \"start_angle\" (başlama açısı) ya da \"from\" özniteliği yok" +#~ msgid "Bug in window manager: " +#~ msgstr "Pencere yöneticisinde hata: " -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "" -"<%s> öğesinde \"extent_angle\" (genişletme açısı) ya da \"to\" özniteliği yok" +#~ msgid "Window manager warning: " +#~ msgstr "Pencere yöneticisi uyarısı: " -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "Renk geçişi türü olarak verilen \"%s\" değeri anlaşılamadı" +#~ msgid "Window manager error: " +#~ msgstr "Pencere yöneticisi hatası: " -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "<%2$s> öğesinin doldurma türü \"%1$s\" anlaşılamadı" +#~ msgid "" +#~ "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " +#~ "window as specified in the ICCCM.\n" +#~ msgstr "" +#~ "%s penceresi SM_CLIENT_ID'yi ICCCM tarafından belirtilen " +#~ "WM_CLIENT_LEADER'a değil kendine atadı.\n" -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "<%2$s> öğesi için \"%1$s\" durumu anlaşılamadı" +#~ msgid "" +#~ "Window %s sets an MWM hint indicating it isn't resizable, but sets min " +#~ "size %d x %d and max size %d x %d; this doesn't make much sense.\n" +#~ msgstr "" +#~ "%s penceresi bir yandan yeniden boyutlandırılamaz olduğunu gösteren bir " +#~ "MWM ipucu verirken anlamsız bir biçimde en küçük (%d x %d) ve en büyük " +#~ "(%d x %d) boyut sınırlarını da atıyor.\n" -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "<%2$s> öğesi için \"%1$s\" gölgesi anlaşılamadı" +#~ msgid "Application set a bogus _NET_WM_PID %lu\n" +#~ msgstr "Uygulama geçersiz _NET_WM_PID %lu atadı\n" -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "<%2$s> öğesi için \"%1$s\" oku anlaşılamadı" +#~ msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +#~ msgstr "Geçersiz WM_TRANSIENT_FOR pencere 0x%lx belirtilen %s.\n" -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "\"%s\" adında hiç <draw_ops> tanımlanmamış" +#~ msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" +#~ msgstr "WM_TRANSIENT_FOR penceresi 0x%lx (%s için) döngü oluşturacak.\n" -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "Burada \"%s\" draw_ops'unu içermek çevrimsel gönderime yol açar" +#~ msgid "" +#~ "Window 0x%lx has property %s\n" +#~ "that was expected to have type %s format %d\n" +#~ "and actually has type %s format %d n_items %d.\n" +#~ "This is most likely an application bug, not a window manager bug.\n" +#~ "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +#~ msgstr "" +#~ "0x%lx penceresinin %s özelliği beklenen\n" +#~ "%s türü ve %d biçimi yerine %s türü, %d biçimi,\n" +#~ "%d n_items'e sahip.\n" +#~ "Bu büyük olasılıkla uygulamanın bir hatası, pencere yöneticisinin değil.\n" +#~ "Pencerenin başlığı=\"%s\", sınıfı=\"%s\", adı=\"%s\"\n" -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Çerçeve parçası için bilinmeyen konum \"%s\"" +#~ msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +#~ msgstr "0x%2$lx penceresinin %1$s özelliği geçersiz UTF-8 içeriyor\n" -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "Çerçeve biçeminin %s konumunda zaten bir parça var" +#~ msgid "" +#~ "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the " +#~ "list\n" +#~ msgstr "" +#~ "0x%2$lx penceresinin %1$s özelliği listedeki öğe %3$d için geçersiz UTF-8 " +#~ "içeriyor\n" -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "\"%s\" adında hiç <draw_ops> tanımlanmamış" +#~ msgid "Usage: %s\n" +#~ msgstr "Kullanım: %s\n" -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Düğme için geçersiz işlev \"%s\"" +#~ msgid "Mi_nimize" +#~ msgstr "_Küçült" -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "Düğme işlevi \"%s\" bu sürümde mevcut değil (%d, gereken %d)" +#~ msgid "Ma_ximize" +#~ msgstr "_Büyült" -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Düğme için geçersiz durum \"%s\"" +#~ msgid "Unma_ximize" +#~ msgstr "Büyült_meyi Geri Al" -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "Çerçeve biçeminde %s işlevi, %s durumu için zaten bir düğme var" +#~ msgid "Roll _Up" +#~ msgstr "Yukarı _Sar" -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "\"%s\", odak özniteliği için geçerli bir değer değil" +#~ msgid "_Unroll" +#~ msgstr "_Sarmayı Geri Al" -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "\"%s\", durum özniteliği için geçerli bir değer değil" +#~ msgid "_Move" +#~ msgstr "_Taşı" -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "\"%s\" adlı bir biçem tanımlanmamış" +#~ msgid "_Resize" +#~ msgstr "_Yeniden Boyutlandır" -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "\"%s\", yeniden boyutlandırma özniteliği için geçerli bir değer değil" +#~ msgid "Move Titlebar On_screen" +#~ msgstr "Başlık Çubuğunu _Ekranda Taşı" -#: ../src/ui/theme-parser.c:3147 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" -"<%s> öğesinin büyütülmüş/toplanmış durumlarında \"resize\" özniteliği " -"bulunmamalı" +#~ msgid "Always on _Top" +#~ msgstr "Her Zaman Ü_stte" -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "" -"<%s> öğesinin büyütülmüş durumlarında \"resize\" özniteliği bulunmamalı" +#~ msgid "_Always on Visible Workspace" +#~ msgstr "Her Zaman _Görünen Çalışma Alanında" -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "" -"%s durumu, %s yeniden boyutlandırma, %s odak için biçem zaten belirtilmiş" +#~ msgid "_Only on This Workspace" +#~ msgstr "Yalnız _Bu Çalışma Alanında" -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "%s durumu, odak %s için biçem zaten belirtilmiş" +#~ msgid "Move to Workspace _Up" +#~ msgstr "_Yukarıdaki Çalışma Alanına Taşı" -#: ../src/ui/theme-parser.c:3294 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Bir <piece> öğesi içinde iki draw_ops olamaz (tema, ya bir draw_ops " -"özniteliğiyle bir <draw_ops> öğesi, ya da iki öğe belirtmiş)" +#~ msgid "_Close" +#~ msgstr "_Kapat" -#: ../src/ui/theme-parser.c:3332 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Bir <button> öğesi içinde iki draw_ops olamaz (tema, ya bir draw_ops " -"özniteliğiyle bir <draw_ops> öğesi, ya da iki öğe belirtmiş)" +#~ msgid "Workspace %d%n" +#~ msgstr "Çalışma Alanı %d%n" -#: ../src/ui/theme-parser.c:3370 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Bir <menu_icon> öğesi içinde iki draw_ops olamaz (tema, ya bir draw_ops " -"özniteliğiyle bir <draw_ops> öğesi, ya da iki öğe belirtmiş)" +#~ msgid "Workspace 1_0" +#~ msgstr "Çalışma Alanı 1_0" -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "Kötü Sürüm Belirtimi '%s'" +#~ msgid "Workspace %s%d" +#~ msgstr "Çalışma Alanı %s%d" -#: ../src/ui/theme-parser.c:3507 -msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" -msgstr "" -"\"version\" özniteliği metacity-theme-1.xml veya metacity-theme-2.xml " -"içerisinde kullanılamaz" +#~ msgid "Move to Another _Workspace" +#~ msgstr "Başka Bir Çalışma Ala_nına Taşı" -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "Tema için %s sürümü gerekli ancak en son desteklenen tema sürümü %d.%d" +#~ msgid "Shift" +#~ msgstr "Shift" -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "Temanın en dış öğesi <%s> değil <metacity_theme> olmalıdır" +#~ msgid "Ctrl" +#~ msgstr "Ctrl" -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "" -"name/author/date/description öğelerinin içinde <%s> öğesi bulunmamalıdır" +#~ msgid "Alt" +#~ msgstr "Alt" -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "<constant> öğesinin içinde <%s> öğesi bulunmamalıdır" +#~ msgid "Meta" +#~ msgstr "Meta" -#: ../src/ui/theme-parser.c:3599 -#, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "" -"distance/border/aspect_ratio öğelerinin içinde <%s> öğesi bulunmamalıdır" +#~ msgid "Super" +#~ msgstr "Super" -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "draw operation öğesinin içinde <%s> öğesi bulunmamalıdır" +#~ msgid "Hyper" +#~ msgstr "Hyper" -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "<%2$s> öğesinin içinde <%1$s> öğesi bulunmamalıdır" +#~ msgid "Mod2" +#~ msgstr "Mod2" -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "Çerçeve parçası için hiç draw_ops sağlanmamış" +#~ msgid "Mod3" +#~ msgstr "Mod3" -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "Düğme için hiç draw_ops sağlanmamış" +#~ msgid "Mod4" +#~ msgstr "Mod4" -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "<%s> öğesinin içinde metin bulunmamalıdır" +#~ msgid "Mod5" +#~ msgstr "Mod5" -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "Bu tema için <%s> iki kez belirtilmiş" +#~ msgid "_Windows" +#~ msgstr "_Pencereler" -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Tema %s için geçerli bir dosya bulunamadı\n" +#~ msgid "_Dialog" +#~ msgstr "_İletişim Penceresi" -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "_Pencereler" +#~ msgid "_Modal dialog" +#~ msgstr "_Yardımcı İletişim Penceresi" -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "_İletişim Penceresi" +#~ msgid "_Utility" +#~ msgstr "_Araçlar" -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "_Yardımcı İletişim Penceresi" +#~ msgid "_Splashscreen" +#~ msgstr "_Başlangıç görüntüsü" -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "_Araçlar" +#~ msgid "_Top dock" +#~ msgstr "_Üste sabitle" -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "_Başlangıç görüntüsü" +#~ msgid "_Bottom dock" +#~ msgstr "_Alta sabitle" -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "_Üste sabitle" +#~ msgid "_Left dock" +#~ msgstr "_Sola sabitle" -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "_Alta sabitle" +#~ msgid "_Right dock" +#~ msgstr "_Sağa sabitle" -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "_Sola sabitle" +#~ msgid "_All docks" +#~ msgstr "_Tüm sabitlemeler" -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "_Sağa sabitle" +#~ msgid "Des_ktop" +#~ msgstr "Masa_üstü" -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "_Tüm sabitlemeler" +#~ msgid "Open another one of these windows" +#~ msgstr "Bu pencerelerden başka bir tane aç" -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "Masa_üstü" +#~ msgid "This is a demo button with an 'open' icon" +#~ msgstr "Bu 'aç' simgesi olan gösterim düğmesidir" -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "Bu pencerelerden başka bir tane aç" +#~ msgid "This is a demo button with a 'quit' icon" +#~ msgstr "Bu 'çık' simgesi olan gösterim düğmesidir" -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "Bu 'aç' simgesi olan gösterim düğmesidir" +#~ msgid "This is a sample message in a sample dialog" +#~ msgstr "Bu örnek iletişim penceresi için örnek bir iletidir" -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "Bu 'çık' simgesi olan gösterim düğmesidir" +#~ msgid "Fake menu item %d\n" +#~ msgstr "Sahte menü öğesi %d\n" -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "Bu örnek iletişim penceresi için örnek bir iletidir" +#~ msgid "Border-only window" +#~ msgstr "Sadece kenarı olan pencere" -#: ../src/ui/theme-viewer.c:328 -#, c-format -msgid "Fake menu item %d\n" -msgstr "Sahte menü öğesi %d\n" +#~ msgid "Bar" +#~ msgstr "Çubuk" -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "Sadece kenarı olan pencere" +#~ msgid "Normal Application Window" +#~ msgstr "Normal Uygulama Penceresi" -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "Çubuk" +#~ msgid "Dialog Box" +#~ msgstr "İletişim Kutusu" -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "Normal Uygulama Penceresi" +#~ msgid "Modal Dialog Box" +#~ msgstr "Yardımcı İletişim Kutusu" -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "İletişim Kutusu" +#~ msgid "Utility Palette" +#~ msgstr "Araç Paleti" -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "Yardımcı İletişim Kutusu" +#~ msgid "Torn-off Menu" +#~ msgstr "Kesilebilir Menü" -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "Araç Paleti" +#~ msgid "Border" +#~ msgstr "Kenarlık" -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "Kesilebilir Menü" +#~ msgid "Attached Modal Dialog" +#~ msgstr "İlişik Yardımcı İletişim Penceresi" -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "Kenarlık" +#~ msgid "Button layout test %d" +#~ msgstr "Düğme düzeni testi %d" -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "İlişik Yardımcı İletişim Penceresi" +#~ msgid "%g milliseconds to draw one window frame" +#~ msgstr "bir pencere çerçevesi çizmek için %g milisaniye" -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "Düğme düzeni testi %d" +#~ msgid "Usage: metacity-theme-viewer [THEMENAME]\n" +#~ msgstr "Kullanım: metacity-theme-viewer [TEMAİSMİ]\n" -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "bir pencere çerçevesi çizmek için %g milisaniye" +#~ msgid "Error loading theme: %s\n" +#~ msgstr "Tema yüklenirken hata: %s\n" -#: ../src/ui/theme-viewer.c:813 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Kullanım: metacity-theme-viewer [TEMAİSMİ]\n" +#~ msgid "Loaded theme \"%s\" in %g seconds\n" +#~ msgstr "\"%s\" teması %g saniye içerisinde yüklendi\n" -#: ../src/ui/theme-viewer.c:820 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "Tema yüklenirken hata: %s\n" +#~ msgid "Normal Title Font" +#~ msgstr "Normal Başlık Yazıtipi" -#: ../src/ui/theme-viewer.c:826 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "\"%s\" teması %g saniye içerisinde yüklendi\n" +#~ msgid "Small Title Font" +#~ msgstr "Küçük Başlık Yazıtipi" -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "Normal Başlık Yazıtipi" +#~ msgid "Large Title Font" +#~ msgstr "Büyük Başlık Yazıtipi" -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "Küçük Başlık Yazıtipi" +#~ msgid "Button Layouts" +#~ msgstr "Düğme Düzenleri" -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "Büyük Başlık Yazıtipi" +#~ msgid "Benchmark" +#~ msgstr "Karşılaştırma" -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "Düğme Düzenleri" +#~ msgid "Window Title Goes Here" +#~ msgstr "Pencere Başlığı Buraya Gelir" -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "Karşılaştırma" +#~ msgid "" +#~ "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and " +#~ "%g seconds wall clock time including X server resources (%g milliseconds " +#~ "per frame)\n" +#~ msgstr "" +#~ "%d çerçeve %g istemci taraflı saniyede (%g milisaniye başına çerçeve) ve " +#~ "X sunucu kaynaları ile saat saniyesi olarak %g saniye (%g milisaniye " +#~ "başına çerçeve) içinde çizildi.\n" -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "Pencere Başlığı Buraya Gelir" +#~ msgid "position expression test returned TRUE but set error" +#~ msgstr "konum ifadesi testi TRUE olarak döndü ama hata belirtti" -#: ../src/ui/theme-viewer.c:1047 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"%d çerçeve %g istemci taraflı saniyede (%g milisaniye başına çerçeve) ve X " -"sunucu kaynaları ile saat saniyesi olarak %g saniye (%g milisaniye başına " -"çerçeve) içinde çizildi.\n" +#~ msgid "position expression test returned FALSE but didn't set error" +#~ msgstr "konum ifadesi testi FALSE olarak döndü ama hata belirtmedi" -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "konum ifadesi testi TRUE olarak döndü ama hata belirtti" +#~ msgid "Error was expected but none given" +#~ msgstr "Hata beklendi ancak hiç bir hata verilmedi" -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "konum ifadesi testi FALSE olarak döndü ama hata belirtmedi" +#~ msgid "Error %d was expected but %d given" +#~ msgstr "Hata %d beklendi ancak %d verildi" -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "Hata beklendi ancak hiç bir hata verilmedi" +#~ msgid "Error not expected but one was returned: %s" +#~ msgstr "Hata beklenmedi ancak bir hata görüldü: %s" -#: ../src/ui/theme-viewer.c:1274 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "Hata %d beklendi ancak %d verildi" +#~ msgid "x value was %d, %d was expected" +#~ msgstr "x değeri %d, fakat beklenen değer %d" -#: ../src/ui/theme-viewer.c:1280 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "Hata beklenmedi ancak bir hata görüldü: %s" +#~ msgid "y value was %d, %d was expected" +#~ msgstr "y değeri %d, fakat beklenen değer %d" -#: ../src/ui/theme-viewer.c:1284 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "x değeri %d, fakat beklenen değer %d" +#~ msgid "" +#~ "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" +#~ msgstr "" +#~ "%d kordinat ifadesi %g saniye içinde ayrıştırıldı (%g saniye ortalama " +#~ "ile)\n" -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "y değeri %d, fakat beklenen değer %d" +#~ msgid "Comma-separated list of compositor plugins" +#~ msgstr "Kompozisyon eklentilerinin listesi (virgül ile ayrılmış)" -#: ../src/ui/theme-viewer.c:1352 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "" -"%d kordinat ifadesi %g saniye içinde ayrıştırıldı (%g saniye ortalama ile)\n" +#~ msgid "Live Hidden Windows" +#~ msgstr "Çalışır Durumdaki Gizli Pencereler" + +#~ msgid "" +#~ "Determines whether hidden windows (i.e., minimized windows and windows on " +#~ "other workspaces than the current one) should be kept alive." +#~ msgstr "" +#~ "Gizli pencerelerin (ö.r. küçültülmüş pencereler ve diğer çalışma " +#~ "alanındaki pencereler) çalışır bırakılıp bırakılmayacağını belirler." #~ msgid "Close Window" #~ msgstr "Pencereyi Kapat" @@ -1627,27 +1685,6 @@ msgstr "" #~ msgid "Put Window On Only One Workspace" #~ msgstr "Pencereyi Sadece Bir Çalışma Alanına Yerleştir" -#~ msgid "Switch to workspace 1" -#~ msgstr "Çalışma alanı 1'e geç" - -#~ msgid "Switch to workspace 2" -#~ msgstr "Çalışma alanı 2'ye geç" - -#~ msgid "Switch to workspace 3" -#~ msgstr "Çalışma alanı 3'e geç" - -#~ msgid "Switch to workspace 4" -#~ msgstr "Çalışma alanı 4'e geç" - -#~ msgid "Switch to workspace 5" -#~ msgstr "Çalışma alanı 5'e geç" - -#~ msgid "Switch to workspace 6" -#~ msgstr "Çalışma alanı 6'ya geç" - -#~ msgid "Switch to workspace 7" -#~ msgstr "Çalışma alanı 7'ye geç" - #~ msgid "Switch to workspace 8" #~ msgstr "Çalışma alanı 8'e geç" @@ -1699,9 +1736,6 @@ msgstr "" #~ msgstr "" #~ "Açılır pencere kullanarak, paneller ve masaüstü arasında geriye dönük taşı" -#~ msgid "Move between windows of an application immediately" -#~ msgstr "Uygulamanın pencereleri arsında anında geç" - #~ msgid "Move backward between windows of an application immediately" #~ msgstr "Bir uygulama pencereleri arasında geriye dönük hemen taşı" @@ -1717,12 +1751,6 @@ msgstr "" #~ msgid "Move backward between panels and the desktop immediately" #~ msgstr "Panellerle masaüstü arasındaki geri geçişi anında yap" -#~ msgid "Hide all normal windows and set focus to the desktop" -#~ msgstr "Normal tüm pencereleri gizle ve odağı masaüstü olara ayarla" - -#~ msgid "Show the panel's main menu" -#~ msgstr "Panelin ana menüsünü göster" - #~ msgid "Show the panel's \"Run Application\" dialog box" #~ msgstr "Panelin \"Uygulama Çalıştır\" penceresini göster" @@ -1738,57 +1766,13 @@ msgstr "" #~ msgid "Run a terminal" #~ msgstr "Bir terminal çalıştır" -#~ msgid "Activate the window menu" -#~ msgstr "Pencere menüsünü etkinleştir" - -#~ msgid "Toggle fullscreen mode" -#~ msgstr "Tam ekran kipini aç veya kapat" - -#~ msgid "Toggle maximization state" -#~ msgstr "Ekranı kaplama durumunu aç veya kapat" - #~ msgid "Toggle whether a window will always be visible over other windows" #~ msgstr "" #~ "Bir pencerenin her zaman diğer pencerelerin üzerinde görünür olmasını seç" -#~ msgid "Maximize window" -#~ msgstr "Bencereyi büyült" - -#~ msgid "Restore window" -#~ msgstr "Pencereyi geri al" - -#~ msgid "Toggle shaded state" -#~ msgstr "Toplanmış durumu aç veya kapat" - #~ msgid "Minimize window" #~ msgstr "Pencereyi küçült" -#~ msgid "Close window" -#~ msgstr "Pencereyi kapat" - -#~ msgid "Move window" -#~ msgstr "Pencere taşı" - -#~ msgid "Resize window" -#~ msgstr "Pencereyi yeniden boyutlandır" - -#~ msgid "Toggle whether window is on all workspaces or just one" -#~ msgstr "" -#~ "Pencerenin tüm çalışma alanlarında veya sadece bir tanesi üzerinde " -#~ "olmasını seç" - -#~ msgid "Move window to workspace 1" -#~ msgstr "Pencereyi çalışma alanı 1'e taşı" - -#~ msgid "Move window to workspace 2" -#~ msgstr "Pencereyi çalışma alanı 2'ye taşı" - -#~ msgid "Move window to workspace 3" -#~ msgstr "Pencereyi çalışma alanı 3'e taşı" - -#~ msgid "Move window to workspace 4" -#~ msgstr "Pencereyi çalışma alanı 4'e taşı" - #~ msgid "Move window to workspace 5" #~ msgstr "Pencereyi çalışma alanı 5'e taşı" @@ -1813,35 +1797,6 @@ msgstr "" #~ msgid "Move window to workspace 12" #~ msgstr "Pencereyi çalışma alanı 12'ye taşı" -#~ msgid "Move window one workspace to the left" -#~ msgstr "Pencereyi soldaki çalışma alanına taşı" - -#~ msgid "Move window one workspace to the right" -#~ msgstr "Pencereyi sağdaki çalışma alanına taşı" - -#~ msgid "Move window one workspace up" -#~ msgstr "Pencereyi üstteki çalışma alanına taşı" - -#~ msgid "Move window one workspace down" -#~ msgstr "Pencereyi alttaki çalışma alanına taşı" - -#~ msgid "Raise window if it's covered by another window, otherwise lower it" -#~ msgstr "" -#~ "Pencere eğer başkası tarafından kapatılmışsa yukarı çıkar, yoksa aşağıya " -#~ "it" - -#~ msgid "Raise window above other windows" -#~ msgstr "Pencereyi diğerlerinin üstüne çıkar" - -#~ msgid "Lower window below other windows" -#~ msgstr "Pencereyi diğerlerinin altına gönder" - -#~ msgid "Maximize window vertically" -#~ msgstr "Pencereyi dikey olarak büyült" - -#~ msgid "Maximize window horizontally" -#~ msgstr "Pencereyi yatay olarak büyült" - #~ msgid "Move window to north-west (top left) corner" #~ msgstr "Pencereyi kuzey-batı (sol üst) köşeye taşı" @@ -2070,9 +2025,6 @@ msgstr "" #~ msgid "Commands to run in response to keybindings" #~ msgstr "Tuş bağlarına yanıt olarak çalıştırılacak komutlar" -#~ msgid "Compositing Manager" -#~ msgstr "Kompozisyon Yöneticisi" - #~ msgid "Control how new windows get focus" #~ msgstr "Yeni pencerelerin nasıl odaklanacağının kontrolü" @@ -2101,18 +2053,6 @@ msgstr "" #~ msgid "Enable Visual Bell" #~ msgstr "Görsel Zili Etkinleştir" -#~ msgid "" -#~ "If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " -#~ "the focused window will be automatically raised after a delay specified " -#~ "by the auto_raise_delay key. This is not related to clicking on a window " -#~ "to raise it, nor to entering a window during drag-and-drop." -#~ msgstr "" -#~ "Eğer seçiliyse, ve odaklama kipi \"sloppy\" ya da \"mouse\" ise odaklanan " -#~ "pencere belirli bir süre sonra kendiliğinden üste çıkar (bu süre " -#~ "auto_raise_delay anahtarıyla belirlenir). Bu bir pencereye üste çıkarmak " -#~ "için tıklamak ya da sürükle ve bırak sırasında pencere sınırlarına girmek " -#~ "ile alakalı değildir." - #~ msgid "" #~ "If true, ignore the titlebar_font option, and use the standard " #~ "application font for window titles." diff --git a/po/ug.po b/po/ug.po index 3acc672d3..84bbe58cb 100644 --- a/po/ug.po +++ b/po/ug.po @@ -1,4 +1,4 @@ -# Uyghur translation for muffin. +# Uyghur translation for mutter. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Gheyret Kenji<gheyret@yahoo.com>,2010. @@ -7,648 +7,416 @@ # msgid "" msgstr "" -"Project-Id-Version: muffin\n" -"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" -"product=muffin&keywords=I18N+L10N&component=general\n" -"POT-Creation-Date: 2011-08-27 17:13+0000\n" -"PO-Revision-Date: 2011-08-08 16:52+0600\n" -"Last-Translator: Sahran <sahran.ug@gmail.com>\n" +"Project-Id-Version: mutter\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=mutter&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2013-03-31 13:47+0000\n" +"PO-Revision-Date: 2013-04-06 18:40+0900\n" +"Last-Translator: Gheyret Kenji <gheyret@gmail.com>\n" "Language-Team: Uyghur Computer Science Association <UKIJ@yahoogroups.com>\n" +"Language: ug\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:487 -#, c-format -msgid "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." -msgstr "" -"كۆرسەتكۈچ \"%2$s\" نىڭدىكى ئېكران %1$d دا بۆلەك باشقۇرغۇچ ئىجرا قىلىنىۋاتىدۇ." - -#: ../src/core/all-keybindings.h:88 -msgid "Switch to workspace 1" -msgstr "1-خىزمەت رايونىغا ئالماش" - -#: ../src/core/all-keybindings.h:90 -msgid "Switch to workspace 2" -msgstr "2-خىزمەت رايونىغا ئالماش" - -#: ../src/core/all-keybindings.h:92 -msgid "Switch to workspace 3" -msgstr "3-خىزمەت رايونىغا ئالماش" - -#: ../src/core/all-keybindings.h:94 -msgid "Switch to workspace 4" -msgstr "4-خىزمەت رايونىغا ئالماش" +#: ../src/50-mutter-navigation.xml.in.h:1 +msgid "Navigation" +msgstr "يولباشچى" -#: ../src/core/all-keybindings.h:96 -msgid "Switch to workspace 5" -msgstr "5-خىزمەت رايونىغا ئالماش" - -#: ../src/core/all-keybindings.h:98 -msgid "Switch to workspace 6" -msgstr "6-خىزمەت رايونىغا ئالماش" - -#: ../src/core/all-keybindings.h:100 -msgid "Switch to workspace 7" -msgstr "7-خىزمەت رايونىغا ئالماش" - -#: ../src/core/all-keybindings.h:102 -msgid "Switch to workspace 8" -msgstr "8-خىزمەت رايونىغا ئالماش" +#: ../src/50-mutter-navigation.xml.in.h:2 +msgid "Move window to workspace 1" +msgstr "كۆزنەكنى 1-خىزمەت رايونىغا يۆتكە" -#: ../src/core/all-keybindings.h:104 -msgid "Switch to workspace 9" -msgstr "9-خىزمەت رايونىغا ئالماش" +#: ../src/50-mutter-navigation.xml.in.h:3 +msgid "Move window to workspace 2" +msgstr "كۆزنەكنى 2-خىزمەت رايونىغا يۆتكە" -#: ../src/core/all-keybindings.h:106 -msgid "Switch to workspace 10" -msgstr "10-خىزمەت رايونىغا ئالماش" +#: ../src/50-mutter-navigation.xml.in.h:4 +msgid "Move window to workspace 3" +msgstr "كۆزنەكنى 3-خىزمەت رايونىغا يۆتكە" -#: ../src/core/all-keybindings.h:108 -msgid "Switch to workspace 11" -msgstr "11- خىزمەت رايونىغا ئالماش" +#: ../src/50-mutter-navigation.xml.in.h:5 +msgid "Move window to workspace 4" +msgstr "كۆزنەكنى 4-خىزمەت رايونىغا يۆتكە" -#: ../src/core/all-keybindings.h:110 -msgid "Switch to workspace 12" -msgstr "12- خىزمەت رايونىغا ئالماش" +#: ../src/50-mutter-navigation.xml.in.h:6 +msgid "Move window one workspace to the left" +msgstr "كۆزنەكنى سولدىكى خىزمەت رايونىغا يۆتكەش" -#: ../src/core/all-keybindings.h:122 -msgid "Switch to workspace on the left of the current workspace" -msgstr "سولدىكى خىزمەت رايونىغا ئالمىشىدۇ" +#: ../src/50-mutter-navigation.xml.in.h:7 +msgid "Move window one workspace to the right" +msgstr "كۆزنەكنى ئوڭدىكى خىزمەت رايونىغا يۆتكەش" -#: ../src/core/all-keybindings.h:126 -msgid "Switch to workspace on the right of the current workspace" -msgstr "ئوڭدىكى خىزمەت مۇھىتىغا ئالمىشىدۇ" +#: ../src/50-mutter-navigation.xml.in.h:8 +msgid "Move window one workspace up" +msgstr "كۆزنەكنى يۇقىرىدىكى خىزمەت رايونىغا يۆتكەش" -#: ../src/core/all-keybindings.h:130 -msgid "Switch to workspace above the current workspace" -msgstr "ئۇستىكى خىزمەت مۇھىتىغا ئالمىشىدۇ" +#: ../src/50-mutter-navigation.xml.in.h:9 +msgid "Move window one workspace down" +msgstr "كۆزنەكنى تۆۋەندىكى خىزمەت رايونىغا يۆتكەش" -#: ../src/core/all-keybindings.h:134 -msgid "Switch to workspace below the current workspace" -msgstr "ئاستىدىكى خىزمەت مۇھىتىغا ئالمىشىدۇ" +#: ../src/50-mutter-navigation.xml.in.h:10 +msgid "Switch applications" +msgstr "پروگراممىلارنى ئالماشتۇرۇش" -#: ../src/core/all-keybindings.h:150 -msgid "Move between windows of an application, using a popup window" -msgstr "" -"قوللىنىشچان پىروگرامما كۆزنىكى ئارىسىدا يۆتكىلىپ، قاڭقىش كۆزنىكى ئىشلىتىدۇ" +#: ../src/50-mutter-navigation.xml.in.h:11 +msgid "Switch windows" +msgstr "كۆزنەكلەرنى ئالماشتۇرۇش" -#: ../src/core/all-keybindings.h:153 -msgid "Move backward between windows of an application, using a popup window" -msgstr "" -"قوللىنىشچان پىروگرامما كۆزنىكى ئارىسىدا ئەكسىچە يۆتكىلىپ، قاڭقىش كۆزنىكى " -"ئىشلىتىدۇ" +#: ../src/50-mutter-navigation.xml.in.h:12 +msgid "Switch windows of an application" +msgstr "پروگراممىنىڭ كۆزنىكىنى ئالماشتۇرۇش" -#: ../src/core/all-keybindings.h:157 -msgid "Move between windows, using a popup window" -msgstr "كۆزنەك ئارىسىدا يۆتكىلىپ، قاڭقىش كۆزنىكى ئىشلىتىدۇ" +#: ../src/50-mutter-navigation.xml.in.h:13 +msgid "Switch system controls" +msgstr "سىستېما تىزگىنلىرىنى ئالماشتۇرۇش" -#: ../src/core/all-keybindings.h:160 -msgid "Move backward between windows, using a popup window" -msgstr "كۆزنەك ئارىسىدا ئەكسىچە يۆتكىلىپ، قاڭقىش كۆزنىكى ئىشلىتىدۇ" +#: ../src/50-mutter-navigation.xml.in.h:14 +msgid "Switch windows directly" +msgstr "كۆزنەكلەرنى بىۋاسىتە ئالماشتۇرۇش" -#: ../src/core/all-keybindings.h:163 -msgid "Move between panels and the desktop, using a popup window" -msgstr "تاختا ۋە ئۈستەلئۈستى ئارىسىدا يۆتكىلىپ، قاڭقىش كۆزنىكى ئىشلىتىدۇ" +#: ../src/50-mutter-navigation.xml.in.h:15 +msgid "Switch windows of an app directly" +msgstr "بىر پروگراممىنىڭ كۆزنەكلىرىنى بىۋاسىتە ئالماشتۇرۇش" -#: ../src/core/all-keybindings.h:166 -msgid "Move backward between panels and the desktop, using a popup window" -msgstr "" -"تاختا ۋە ئۈستەلئۈستى ئارىسىدا ئەكسىچە يۆتكىلىپ، قاڭقىش كۆزنىكى ئىشلىتىدۇ" +#: ../src/50-mutter-navigation.xml.in.h:16 +msgid "Switch system controls directly" +msgstr "سىستېما تىزگىنلىرىنى بىۋاسىتە ئالماشتۇرۇش" -#: ../src/core/all-keybindings.h:171 -msgid "Move between windows of an application immediately" -msgstr "پروگراممىنىڭ كۆزنەكلىرى ئارىسىدا دەرھال يۆتكىلىدۇ" +#: ../src/50-mutter-navigation.xml.in.h:17 +msgid "Hide all normal windows" +msgstr "بارلىق نورمال كۆزنەكلەرنى يوشۇرۇش" -#: ../src/core/all-keybindings.h:174 -msgid "Move backward between windows of an application immediately" -msgstr "" -"قوللىنىشچان پروگراممىنىڭ كۆزنىكى ئارىسىدا ئەكسىچە دەرھال تەتۈر يۆتكىلىدۇ" +#: ../src/50-mutter-navigation.xml.in.h:18 +msgid "Switch to workspace 1" +msgstr "1-خىزمەت رايونىغا ئالمىشىش" -#: ../src/core/all-keybindings.h:177 -msgid "Move between windows immediately" -msgstr "كۆزنەك ئارىسىدا دەرھال يۆتكىلىدۇ" +#: ../src/50-mutter-navigation.xml.in.h:19 +msgid "Switch to workspace 2" +msgstr "2-خىزمەت رايونىغا ئالمىشىش" -#: ../src/core/all-keybindings.h:180 -msgid "Move backward between windows immediately" -msgstr "كۆزنەك ئارىسىدا ئەكسىچە دەرھال يۆتكىلىدۇ" +#: ../src/50-mutter-navigation.xml.in.h:20 +msgid "Switch to workspace 3" +msgstr "3-خىزمەت رايونىغا ئالمىشىش" -#: ../src/core/all-keybindings.h:183 -msgid "Move between panels and the desktop immediately" -msgstr "تاختايلار ۋە ئۈستەلئۈستى ئارىسىدا دەرھال يۆتكىلىش" +#: ../src/50-mutter-navigation.xml.in.h:21 +msgid "Switch to workspace 4" +msgstr "4-خىزمەت رايونىغا ئالمىشىش" -#: ../src/core/all-keybindings.h:186 -msgid "Move backward between panels and the desktop immediately" -msgstr "تاختايلار ۋە ئۈستەلئۈستى ئارىسىدا دەرھال تەتۈر يۆتكىلىش" +#: ../src/50-mutter-navigation.xml.in.h:22 +msgid "Move to workspace left" +msgstr "سولدىكى خىزمەت رايونىغا يۆتكەش" -#: ../src/core/all-keybindings.h:203 -msgid "Hide all normal windows and set focus to the desktop" -msgstr "ھەممە كۆزنەكنى يوشۇرۇپ فوكۇسنى ئۈستەلئۈستىگە توغرىلا" +#: ../src/50-mutter-navigation.xml.in.h:23 +msgid "Move to workspace right" +msgstr "ئوڭدىكى خىزمەت رايونىغا يۆتكەش" -#: ../src/core/all-keybindings.h:206 -msgid "Show the panel's main menu" -msgstr "تاختاينىڭ ئاساسىي تىزىملىكى كۆرسىتىدۇ" +#: ../src/50-mutter-navigation.xml.in.h:24 +msgid "Move to workspace above" +msgstr "ئۇستىدىكى خىزمەت رايونىغا يۆتكەش" -#: ../src/core/all-keybindings.h:209 -msgid "Show the panel's \"Run Application\" dialog box" -msgstr "تاختاينىڭ «پروگرامما ئىجرا قىل» سۆزلەشكۈسىنى كۆرسىتىدۇ" +#: ../src/50-mutter-navigation.xml.in.h:25 +msgid "Move to workspace below" +msgstr "تۆۋەندىكى خىزمەت رايونىغا يۆتكەش" -#: ../src/core/all-keybindings.h:211 -msgid "Start or stop recording the session" -msgstr "مەزكۇر ئەڭگىمەنى خاتىرىلەشنى توختىتىدۇ ياكى باشلايدۇ" +#: ../src/50-mutter-system.xml.in.h:1 +msgid "System" +msgstr "سىستېما" -#: ../src/core/all-keybindings.h:252 -msgid "Take a screenshot" -msgstr "ئېكران كەسمىسى تۇت" +#: ../src/50-mutter-system.xml.in.h:2 +msgid "Show the run command prompt" +msgstr "بۇيرۇق قۇرىنى كۆرسىتىدۇ" -#: ../src/core/all-keybindings.h:254 -msgid "Take a screenshot of a window" -msgstr "كۆزنەكنىڭ كۆرۈنۈشىنى رەسىمگە ئالىدۇ" +#: ../src/50-mutter-system.xml.in.h:3 +msgid "Show the activities overview" +msgstr "پائالىيەتلەرنىڭ قىسقىچە بايانىنى كۆرسىتىدۇ" -#: ../src/core/all-keybindings.h:256 -msgid "Run a terminal" -msgstr "تېرمىنالنى ئىجرا قىل" +#: ../src/50-mutter-windows.xml.in.h:1 +msgid "Windows" +msgstr "كۆزنەكلەر" -#: ../src/core/all-keybindings.h:271 +#: ../src/50-mutter-windows.xml.in.h:2 msgid "Activate the window menu" -msgstr "كۆزنەك تىزىملىكىنى ئاكتىپلاۋاتىدۇ" +msgstr "كۆزنەك تىزىملىكىنى ئاكتىپلاش" -#: ../src/core/all-keybindings.h:274 +#: ../src/50-mutter-windows.xml.in.h:3 msgid "Toggle fullscreen mode" -msgstr "پۈتۈن ئېكران شەكلىگە ئالماش" +msgstr "پۈتۈن ئېكران شەكلىگە ئالمىشىش" -#: ../src/core/all-keybindings.h:276 +#: ../src/50-mutter-windows.xml.in.h:4 msgid "Toggle maximization state" -msgstr "ئەڭ چوڭ ھالەتكە ئالماش" - -#: ../src/core/all-keybindings.h:278 -msgid "Toggle whether a window will always be visible over other windows" -msgstr "" -"كۆزنەك ھەمىشە باشقا ھەممە كۆزنەكلەرنىڭ ئۈستىدە تۇرۇشنى ئالماشتۇرامدۇ يوق" +msgstr "ئەڭ چوڭ ھالەتكە ئالمىشىش" -#: ../src/core/all-keybindings.h:280 +#: ../src/50-mutter-windows.xml.in.h:5 msgid "Maximize window" -msgstr "كۆزنەكنى چوڭايت" +msgstr "كۆزنەكنى چوڭايتىش" -#: ../src/core/all-keybindings.h:282 +#: ../src/50-mutter-windows.xml.in.h:6 msgid "Restore window" -msgstr "كۆزنەكنى ئەسلىگە كەلتۈر" +msgstr "كۆزنەكنى ئەسلىگە كەلتۈرۈش" -#: ../src/core/all-keybindings.h:284 +#: ../src/50-mutter-windows.xml.in.h:7 msgid "Toggle shaded state" -msgstr "سايىلىك ھالەتكە ئالماش" - -#: ../src/core/all-keybindings.h:286 -msgid "Minimize window" -msgstr "كۆزنەكنى كىچىكلەت" +msgstr "سايىلىك ھالەتكە ئالمىشىش" -#: ../src/core/all-keybindings.h:288 +#: ../src/50-mutter-windows.xml.in.h:8 msgid "Close window" msgstr "كۆزنەك ياپ" -#: ../src/core/all-keybindings.h:290 +#: ../src/50-mutter-windows.xml.in.h:9 +msgid "Hide window" +msgstr "كۆزنەكنى يوشۇرۇش" + +#: ../src/50-mutter-windows.xml.in.h:10 msgid "Move window" -msgstr "كۆزنەكنى يۆتكە" +msgstr "كۆزنەكنى يۆتكەش" -#: ../src/core/all-keybindings.h:292 +#: ../src/50-mutter-windows.xml.in.h:11 msgid "Resize window" -msgstr "كۆزنەك چوڭلۇقىنى ئۆزگەرت" - -#: ../src/core/all-keybindings.h:295 -msgid "Toggle whether window is on all workspaces or just one" -msgstr "كۆزنەك ھەممە ياكى پەقەت بىرلا خىزمەت رايونىدا ئالمىشىدۇ" - -#: ../src/core/all-keybindings.h:299 -msgid "Move window to workspace 1" -msgstr "كۆزنەكنى 1-خىزمەت رايونىغا يۆتكە" - -#: ../src/core/all-keybindings.h:302 -msgid "Move window to workspace 2" -msgstr "كۆزنەكنى 2-خىزمەت رايونىغا يۆتكە" - -#: ../src/core/all-keybindings.h:305 -msgid "Move window to workspace 3" -msgstr "كۆزنەكنى 3-خىزمەت رايونىغا يۆتكە" - -#: ../src/core/all-keybindings.h:308 -msgid "Move window to workspace 4" -msgstr "كۆزنەكنى 4-خىزمەت رايونىغا يۆتكە" - -#: ../src/core/all-keybindings.h:311 -msgid "Move window to workspace 5" -msgstr "كۆزنەكنى 5-خىزمەت رايونىغا يۆتكە" - -#: ../src/core/all-keybindings.h:314 -msgid "Move window to workspace 6" -msgstr "كۆزنەكنى 6-خىزمەت رايونىغا يۆتكە" - -#: ../src/core/all-keybindings.h:317 -msgid "Move window to workspace 7" -msgstr "كۆزنەكنى 7-خىزمەت رايونىغا يۆتكە" - -#: ../src/core/all-keybindings.h:320 -msgid "Move window to workspace 8" -msgstr "كۆزنەكنى 8-خىزمەت رايونىغا يۆتكە" +msgstr "كۆزنەك چوڭلۇقىنى ئۆزگەرتىش" -#: ../src/core/all-keybindings.h:323 -msgid "Move window to workspace 9" -msgstr "كۆزنەكنى 9-خىزمەت رايونىغا يۆتكە" +#: ../src/50-mutter-windows.xml.in.h:12 +msgid "Toggle window on all workspaces or one" +msgstr "كۆزنەكنى بارلىق خىزمەت رايونى ياكى بىرىگىلا ئالماشتۇرۇش" -#: ../src/core/all-keybindings.h:326 -msgid "Move window to workspace 10" -msgstr "كۆزنەكنى 10-خىزمەت رايونىغا يۆتكە" +#: ../src/50-mutter-windows.xml.in.h:13 +msgid "Raise window if covered, otherwise lower it" +msgstr "كۆزنەك توسۇلۇپ قالغان بولسا كۆتۈرسۇن، بولمىسا پەسلەتسۇن" -#: ../src/core/all-keybindings.h:329 -msgid "Move window to workspace 11" -msgstr "كۆزنەكنى 11- خىزمەت رايونىغا يۆتكە" - -#: ../src/core/all-keybindings.h:332 -msgid "Move window to workspace 12" -msgstr "كۆزنەكنى 12- خىزمەت رايونىغا يۆتكە" - -#: ../src/core/all-keybindings.h:344 -msgid "Move window one workspace to the left" -msgstr "كۆزنەكنى سولدىكى خىزمەت رايونىغا يۆتكە" - -#: ../src/core/all-keybindings.h:347 -msgid "Move window one workspace to the right" -msgstr "كۆزنەكنى ئوڭدىكى خىزمەت رايونىغا يۆتكە" - -#: ../src/core/all-keybindings.h:350 -msgid "Move window one workspace up" -msgstr "كۆزنەكنى يۇقىرىدىكى خىزمەت رايونىغا يۆتكە" - -#: ../src/core/all-keybindings.h:353 -msgid "Move window one workspace down" -msgstr "كۆزنەكنى تۆۋەندىكى خىزمەت رايونىغا يۆتكە" - -#: ../src/core/all-keybindings.h:356 -msgid "Raise window if it's covered by another window, otherwise lower it" -msgstr "" -"ئەگەر كۆزنەك باشقا كۆزنەك تەرىپىدىن توسۇلسا ئۇنداقتا ئۇنى ئۆرلەت بولمىسا " -"ئۇنى تۆۋەنلەت" - -#: ../src/core/all-keybindings.h:358 +#: ../src/50-mutter-windows.xml.in.h:14 msgid "Raise window above other windows" -msgstr "كۆزنەكنى باشقا كۆزنەكنىڭ ئۈستىگە ئۆرلەت" +msgstr "كۆزنەكنى باشقا كۆزنەكنىڭ ئۈستىگە كۆتۈرۈش" -#: ../src/core/all-keybindings.h:360 +#: ../src/50-mutter-windows.xml.in.h:15 msgid "Lower window below other windows" -msgstr "كۆزنەكنى باشقا كۆزنەكنىڭ ئاستىغا تۆۋەنلەت" +msgstr "كۆزنەكنى باشقا كۆزنەكنىڭ ئاستىغا تۆۋەنلىتىش" -#: ../src/core/all-keybindings.h:364 +#: ../src/50-mutter-windows.xml.in.h:16 msgid "Maximize window vertically" -msgstr "كۆزنەكنى بويىغا چوڭايت" +msgstr "كۆزنەكنى تىك يۆنىلىشتە چوڭايتىش" -#: ../src/core/all-keybindings.h:368 +#: ../src/50-mutter-windows.xml.in.h:17 msgid "Maximize window horizontally" -msgstr "كۆزنەكنى توغرىسىغا چوڭايت" - -#: ../src/core/all-keybindings.h:372 -msgid "Move window to north-west (top left) corner" -msgstr "كۆزنەكنى ئېكراننىڭ غەربى-شىمالى(سول يۇقىرى)غا يۆتكە" - -#: ../src/core/all-keybindings.h:375 -msgid "Move window to north-east (top right) corner" -msgstr "كۆزنەكنى ئېكراننىڭ شەرقى-شىمالى(ئوڭ يۇقىرى)غا يۆتكە" - -#: ../src/core/all-keybindings.h:378 -msgid "Move window to south-west (bottom left) corner" -msgstr "كۆزنەكنى ئېكراننىڭ غەربى-جەنۇبى(سول پەسكە)غا يۆتكە" +msgstr "كۆزنەكنى توغرا يۆنىلىشتە چوڭايتىش" -#: ../src/core/all-keybindings.h:381 -msgid "Move window to south-east (bottom right) corner" -msgstr "كۆزنەكنى ئېكراننىڭ غەربى-شىمالى(سول يۇقىرى)غا يۆتكە" +#: ../src/50-mutter-windows.xml.in.h:18 +msgid "View split on left" +msgstr "كۆزنەكنىڭ سول تەرىپىدە كۆرسەتسۇن" -#: ../src/core/all-keybindings.h:385 -msgid "Move window to north (top) side of screen" -msgstr "كۆزنەكنى ئېكراننىڭ شىمالى(ئۇستى)غا يۆتكە" +#: ../src/50-mutter-windows.xml.in.h:19 +msgid "View split on right" +msgstr "كۆزنەكنىڭ ئوڭ تەرىپىدە كۆرسەتسۇن" -#: ../src/core/all-keybindings.h:388 -msgid "Move window to south (bottom) side of screen" -msgstr "كۆزنەكنى ئېكراننىڭ جەنۇبى(ئاستى)غا يۆتكە" - -#: ../src/core/all-keybindings.h:391 -msgid "Move window to east (right) side of screen" -msgstr "كۆزنەكنى ئېكراننىڭ شەرقى(ئوڭ تەرەپ)گە يۆتكە" - -#: ../src/core/all-keybindings.h:394 -msgid "Move window to west (left) side of screen" -msgstr "كۆزنەكنى ئېكراننىڭ غەربى(سول تەرەپ)گە يۆتكە" +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: ../src/compositor/compositor.c:568 +#, c-format +msgid "" +"Another compositing manager is already running on screen %i on display \"%s" +"\"." +msgstr "كۆرسەتكۈچ «%2$s» نىڭدىكى ئېكران %1$i دا بۆلەك باشقۇرغۇچ ئىجرا قىلىنىۋاتىدۇ." -#: ../src/core/all-keybindings.h:397 -msgid "Move window to center of screen" -msgstr "كۆزنەكنى ئېكراننىڭ مەركىزىگە يۆتكەيدۇ" +#: ../src/compositor/meta-background.c:1064 +msgid "background texture could not be created from file" +msgstr "ھۆججەتتىن تەگلىك texture نى قۇرغىلى بولمايدۇ" -#: ../src/core/bell.c:310 +#: ../src/core/bell.c:322 msgid "Bell event" msgstr "قوڭغۇراق ھادىسىسى" #: ../src/core/core.c:157 #, c-format msgid "Unknown window information request: %d" -msgstr "نامەلۇم كۆزنەك ئۇچۇرى ئىلتىماسى:%d" +msgstr "نامەلۇم كۆزنەك ئۇچۇرى ئىلتىماسى:%d" #: ../src/core/delete.c:111 #, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> جاۋاب قايتۇرمايۋاتىدۇ." +msgid "“%s” is not responding." +msgstr "%s نىڭدىن جاۋاب كەلمەيۋاتىدۇ." -#: ../src/core/delete.c:114 +#: ../src/core/delete.c:113 msgid "Application is not responding." -msgstr "پىروگراممىدا ئىنكاس يوق." +msgstr "پروگراممىدا ئىنكاس يوق." -#: ../src/core/delete.c:119 +#: ../src/core/delete.c:118 msgid "" "You may choose to wait a short while for it to continue or force the " "application to quit entirely." -msgstr "سەل كۈتۈشنى ياكى پروگراممىنى مەجبۇرى چېكىندۈرۈشنى تاللىسىڭىز بولىدۇ." +msgstr "داۋاملاشتۇرۇش ئۈچۈن كۈتۈشنى ياكى پروگراممىنى تولۇق ئاخىرلاشتۇرۇش ئۈچۈن مەجبۇرىينى تاللىسىڭىز بولىدۇ." -#: ../src/core/delete.c:126 +#: ../src/core/delete.c:125 msgid "_Wait" msgstr "كۈت(_W)" -#: ../src/core/delete.c:126 +#: ../src/core/delete.c:125 msgid "_Force Quit" -msgstr "مەجبۇرى چېكىن(_F)" +msgstr "مەجبۇرى ئاخىرلاشتۇر(_F)" -#: ../src/core/display.c:365 +#: ../src/core/display.c:401 #, c-format msgid "Missing %s extension required for compositing" -msgstr "ئارىلاش كۆزنەك باشقۇرغۇچ ئېھتىياجلىق كېڭەيتىلمە كەم:%s" +msgstr "بىرىكتۈرۈش ئۈچۈن زۆرۈر بولغان كېڭەيتىلمە %s يوق" -#: ../src/core/display.c:431 +#: ../src/core/display.c:493 #, c-format msgid "Failed to open X Window System display '%s'\n" -msgstr "X Window System نى ئېچىپ كۆرسەتكىلى بولمىدى“%s”\n" +msgstr "‏X كۆزنەك سىستېمىسى كۆرسەتكۈچى ‹%s› نى ئېچىش مەغلۇپ بولدى\n" -#: ../src/core/keybindings.c:759 +#: ../src/core/keybindings.c:935 #, c-format msgid "" "Some other program is already using the key %s with modifiers %x as a " "binding\n" -msgstr "" -"مەلۇم باشقا پروگرامما %s كۇنۇپكىسى بىلەن تۈزەش كۇنۇپكىسى %x نى بىللە " -"ئىشلىتىشنىڭ بىرىكمىسى\n" - -#. Displayed when a keybinding which is -#. * supposed to launch a program fails. -#. -#: ../src/core/keybindings.c:2523 -#, c-format -msgid "" -"There was an error running <tt>%s</tt>:\n" -"\n" -"%s" -msgstr "" -"<tt>%s</tt> نى ئىجرا قىلىۋاتقاندا خاتالىق كۆرۈلدى:\n" -"\n" -"%s" +msgstr "باشقا پروگرامما %s كۇنۇپكىسى بىلەن سۈپەتلىگۈچى كۇنۇپكا %x نىڭ بىرىكمىسىنى ئىشلىتىۋاتىدۇ\n" -#: ../src/core/keybindings.c:2613 +#: ../src/core/keybindings.c:1135 #, c-format -msgid "No command %d has been defined.\n" -msgstr "بۇيرۇق %d بېكىتىلمىگەن.\n" +#| msgid "\"%s\" is not a valid value for focus attribute" +msgid "\"%s\" is not a valid accelerator\n" +msgstr "«%s» ئىناۋەتلىك تېزلەتكۈچ ئەمەس\n" -#: ../src/core/keybindings.c:3625 -#, c-format -msgid "No terminal command has been defined.\n" -msgstr "تېرمىنال بۇيرۇققا ئېنىقلىما بېرىلمىگەن .\n" - -#: ../src/core/main.c:206 +#: ../src/core/main.c:197 msgid "Disable connection to session manager" -msgstr "ئەڭگىمە باشقۇرغۇچقا باغلىنىشنى چەكلە" +msgstr "ئەڭگىمە باشقۇرغۇچقا باغلىنىشنى ئىناۋەتسىز قىل" -#: ../src/core/main.c:212 +#: ../src/core/main.c:203 msgid "Replace the running window manager" msgstr "ئىجرا قىلىنىۋاتقان كۆزنەك باشقۇرغۇچنى ئالماشتۇر" -#: ../src/core/main.c:218 +#: ../src/core/main.c:209 msgid "Specify session management ID" msgstr "ئەڭگىمە باشقۇرغۇ ID سېنى بەلگىلە" -#: ../src/core/main.c:223 +#: ../src/core/main.c:214 msgid "X Display to use" -msgstr "ئىشلىتىدىغان X نى كۆرسىتىش" +msgstr "ئىشلىتىدىغان X كۆرسەتكۈچى" -#: ../src/core/main.c:229 +#: ../src/core/main.c:220 msgid "Initialize session from savefile" msgstr "ساقلانغان ھۆججەتتىن ئەڭگىمەنى دەسلەپلەشتۈرۈش" -#: ../src/core/main.c:235 +#: ../src/core/main.c:226 msgid "Make X calls synchronous" msgstr "X نى قەدەمداش قىلىپ ئىشلەت" -#: ../src/core/main.c:504 +#: ../src/core/main.c:534 #, c-format msgid "Failed to scan themes directory: %s\n" -msgstr "تېما مۇندەرىجىسىنى ئىزدەش مەغلۇپ بولدى:%s\n" +msgstr "ئۆرنەكلەر مۇندەرىجىسىنى ئىزدەش مەغلۇپ بولدى: %s\n" -#: ../src/core/main.c:520 +#: ../src/core/main.c:550 #, c-format msgid "" "Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "" -"بىرەر تېما تېپىلمىدى. %s نىڭ مەۋجۇتلۇقى ھەم ئىشلىتىشكە بولىدىغان تېمىنى ئۆز " -"ئىچىگە ئالغانلىقىنى جەزملەڭ.\n" +msgstr "بىرەر ئۆرنەك تېپىلمىدى. %s نىڭ مەۋجۇتلۇقى ھەم ئىشلىتىشكە بولىدىغان ئۆرنەكنى ئۆز ئىچىگە ئالغانلىقىنى جەزملەڭ.\n" -#: ../src/core/muffin.c:42 +#: ../src/core/mutter.c:40 #, c-format msgid "" -"muffin %s\n" +"mutter %s\n" "Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" "This is free software; see the source for copying conditions.\n" "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " "PARTICULAR PURPOSE.\n" -msgstr "" -"muffin %s\n" +msgstr "mutter %s\n" "نەشر ھوقۇقى (C) 2001-%d Havoc Pennington, Red Hat, Inc., ۋە باشقىلارغا تەۋە\n" "بۇ ھەقسىز دېتال؛ كۆچۈرۈش شەرتلىرىنى مەنبە كودىدىن كۆرۈڭ.\n" "مەيلى قانداق مەقسەتتە ئىشلەتمەڭ، ھېچقانداق كاپالەت يوق؛\n" -#: ../src/core/muffin.c:56 +#: ../src/core/mutter.c:54 msgid "Print version" msgstr "نەشرىنى باس" -#: ../src/core/muffin.c:62 -msgid "Comma-separated list of compositor plugins" -msgstr "پەش بىلەن ئايرىلغان تىزىم ۋە بىرىكمە رەڭلىگۈچ قىستۇرمىلىرى" - -#. -#. * We found it, but it was invalid. Complain. -#. * -#. * FIXME: This replicates the original behaviour, but in the future -#. * we might consider reverting invalid keys to their original values. -#. * (We know the old value, so we can look up a suitable string in -#. * the symtab.) -#. * -#. * (Empty comment follows so the translators don't see this.) -#. -#. -#: ../src/core/prefs.c:550 ../src/core/prefs.c:711 -#, c-format -msgid "GConf key '%s' is set to an invalid value\n" -msgstr "" -"GConf نىڭ ئاچقۇچ سۆزى“%s” ئۈنۈمسىز \n" -" قىلىپ تەڭشەلگەن\n" +#: ../src/core/mutter.c:60 +msgid "Mutter plugin to use" +msgstr "ئىشلىتىدىغان Mutter قىستۇرمىسى" -#: ../src/core/prefs.c:637 ../src/core/prefs.c:880 -#, c-format -msgid "%d stored in GConf key %s is out of range %d to %d\n" -msgstr "" -"GConf نىڭ %2$s ئاچقۇچىنىڭ قىممىتى %1$d نىڭ دائىرىسى %3$d〜%4$d نىڭ ئىچىدە " -"ئەمەس\n" - -#: ../src/core/prefs.c:681 ../src/core/prefs.c:758 ../src/core/prefs.c:806 -#: ../src/core/prefs.c:870 ../src/core/prefs.c:1331 ../src/core/prefs.c:1347 -#: ../src/core/prefs.c:1364 ../src/core/prefs.c:1380 -#, c-format -msgid "GConf key \"%s\" is set to an invalid type\n" -msgstr "" -"GConf نىڭ ئاچقۇچلۇق سۆزى “%s” ئۈنۈمسىز تىپتىكى \n" -" قىلىپ تەڭشەلگەن\n" - -#: ../src/core/prefs.c:1210 -#, c-format -msgid "GConf key %s is already in use and can't be used to override %s\n" -msgstr "" -"GConf ئاچقۇچى %s ئىشلىتىلىۋاتىدۇ، شۇڭا %s نى قاپلاشقا ئىشلەتكىلى بولمايدۇ\n" - -#: ../src/core/prefs.c:1269 -#, c-format -msgid "Can't override GConf key, %s not found\n" -msgstr "GConf ئاچقۇچىنى قاپلىغىلى بولمىدى، %s تېپىلمىدى\n" - -#: ../src/core/prefs.c:1454 +#: ../src/core/prefs.c:1095 msgid "" "Workarounds for broken applications disabled. Some applications may not " "behave properly.\n" -msgstr "" -"بۇزۇلغان پروگراممىلارنى تۈزىتىش-ياخشىلاش قوزغىتىلمىغان. بەزى پروگراممىلار " -"نورمال ئىشلىمەسلىكى مۇمكىن.\n" +msgstr "بۇزۇلغان پروگراممىلارنى تۈزىتىش-ياخشىلاش ئىناۋەتسىز قىلىنغان. بەزى پروگراممىلار نورمال ئىشلىمەسلىكى مۇمكىن.\n" -#: ../src/core/prefs.c:1531 +#: ../src/core/prefs.c:1170 #, c-format -msgid "Could not parse font description \"%s\" from GConf key %s\n" -msgstr "" -"خەت نۇسخىسىنىڭ چۈشەندۈرۈلۈشىنى ئانالىز قىلغىلى بولمىدى “%s” ( GConf دىكى " -"ئاچقۇچلۇق سۆز %s )\n" +msgid "Could not parse font description \"%s\" from GSettings key %s\n" +msgstr "GSettings ئاچقۇچى %s نىڭ تەركىبىدىكى فونت چۈشەندۈرۈشى «%s»نى تەھلىل قىلغىنى بولمىدى\n" -#: ../src/core/prefs.c:1593 +#: ../src/core/prefs.c:1236 #, c-format msgid "" "\"%s\" found in configuration database is not a valid value for mouse button " "modifier\n" -msgstr "" -"سەپلىمە سانداندىن تېپىلغان “%s” چاشقىنەك كۇنۇپكىسى سۈپەتلىگۈچىسى ئۈچۈن " -"ئۈنۈملۈك قىممەت \n" -" ئەمەس\n" - -#: ../src/core/prefs.c:2028 -#, c-format -msgid "Error setting number of workspaces to %d: %s\n" -msgstr "خىزمەت رايونى سانىنى %d قىلىپ تەڭشەشتە كۆرۈلگەن خاتالىق :%s\n" - -#: ../src/core/prefs.c:2212 ../src/core/prefs.c:2714 -#, c-format -msgid "Workspace %d" -msgstr "خىزمەت بوشلۇقى %d" +msgstr "سەپلىمە سانداندىن تېپىلغان «%s» چاشقىنەك توپچىسىنىڭ سۈپەتلىگۈچىسى ئۈچۈن ئىناۋەتسىز\n" -#: ../src/core/prefs.c:2244 ../src/core/prefs.c:2422 +#: ../src/core/prefs.c:1788 #, c-format msgid "" "\"%s\" found in configuration database is not a valid value for keybinding " "\"%s\"\n" -msgstr "" -"سەپلىمە ساندانىدىن تېپىلغان \"%s\"، \"%s\" كۇنۇپكا باغلانمىسىنىڭ ئىناۋەتلىك " -"قىممىتى ئەمەس\n" - -#: ../src/core/prefs.c:2795 -#, c-format -msgid "Error setting name for workspace %d to \"%s\": %s\n" -msgstr "خىزمەت مۇھىتى %d غا \"%s\" دەپ ئائىت قويۇشتا خاتالىق كۆرۈلدى: %s\n" - -#: ../src/core/prefs.c:3009 -#, c-format -msgid "Error setting live hidden windows status status: %s\n" -msgstr "" -"شۇئان يوشۇرۇنىدىغان كۆزنەك ھالىتىنى تەڭشەۋاتقاندا خاتالىق كۆرۈلدى: %s\n" +msgstr "سەپلىمە ساندىنىدىن تېپىلغان «%s»، «%s» كۇنۇپكا باغلانمىسىنىڭ ئىناۋەتلىك قىممىتى ئەمەس\n" -#: ../src/core/prefs.c:3044 +#: ../src/core/prefs.c:1887 #, c-format -msgid "Error setting no tab popup status: %s\n" -msgstr "بەتكۈچ يوق قاڭقىش ھالىتىنى تەڭشەۋەتقاندا خاتالىق كۆرۈلدى: %s\n" +msgid "Workspace %d" +msgstr "خىزمەت بوشلۇقى %d" -#: ../src/core/screen.c:663 +#: ../src/core/screen.c:691 #, c-format msgid "Screen %d on display '%s' is invalid\n" -msgstr "“%2$s” دىكى %1$d ئېكراننى كۆرسىتىش ئۈنۈمسىز\n" +msgstr "كۆرسەتكۈچ ‹%2$s› دىكى ئېكران %1$d ئىناۋەتسىز\n" -#: ../src/core/screen.c:679 +#: ../src/core/screen.c:707 #, c-format msgid "" "Screen %d on display \"%s\" already has a window manager; try using the --" "replace option to replace the current window manager.\n" -msgstr "" -"كۆرسەتكۈچ «%2$s» دىكى ئېكران %1$d نىڭ كۆزنەك باشقۇرغۇچىسى بار؛ ھازىرقى كۆزنەك " -"باشقۇرغۇچنى ئالماشتۇرۇش ئۈچۈن --replace تاللانمىسىنى ئىشلىتىپ كۆرۈپ بېقىڭ.\n" +msgstr "كۆرسەتكۈچ «%2$s» دىكى ئېكران %1$d نىڭ كۆزنەك باشقۇرغۇسى بار؛ ھازىرقى كۆزنەك باشقۇرغۇنى ئالماشتۇرۇش ئۈچۈن --replace تاللانمىسىنى ئىشلىتىپ كۆرۈپ بېقىڭ.\n" -#: ../src/core/screen.c:706 +#: ../src/core/screen.c:734 #, c-format msgid "" "Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "" -"كۆرسەتكۈچ \"%2$s\" نىڭدىكى ئېكران %1$d دا كۆزنەك باشقۇرغۇنىڭ تاللانمىسىنى " -"ئالغىلى بولمىدى\n" +msgstr "كۆرسەتكۈچ «%2$s» نىڭدىكى ئېكران %1$d دا كۆزنەك باشقۇرغۇنىڭ تاللانمىسىنى ئالغىلى بولمىدى\n" -#: ../src/core/screen.c:761 +#: ../src/core/screen.c:812 #, c-format msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "" -"“%2$s” دىكى %1$d ئېكراندا بىر كۆزنەك باشقۇرغۇچ \n" -" بار\n" +msgstr "«%2$s» دىكى %1$d ئېكراندا بىر كۆزنەك باشقۇرغۇ بار\n" -#: ../src/core/screen.c:946 +#: ../src/core/screen.c:998 #, c-format msgid "Could not release screen %d on display \"%s\"\n" -msgstr "" -"“%2$s” دىكى %1$d\n" -" ئېكراننى بوشاتقىلى بولمىدى\n" +msgstr "«%2$s» دىكى %1$d ئېكراننى بوشاتقىلى بولمىدى\n" #: ../src/core/session.c:843 ../src/core/session.c:850 #, c-format msgid "Could not create directory '%s': %s\n" -msgstr "“%s” مۇندەرىجىنى قۇرغىلى بولمىدى :%s\n" +msgstr "مۇندەرىجە ‹%s› نى قۇرغىلى بولمىدى :%s\n" #: ../src/core/session.c:860 #, c-format msgid "Could not open session file '%s' for writing: %s\n" -msgstr "ئەڭگىمە ھۆججىتى“%s”نى ئېچىپ تۆۋەندىكىنى يازغىلى بولمىدى:%s\n" +msgstr "ئەڭگىمە ھۆججىتى ‹%s› نى يېزىش ئۈچۈن ئاچقىلى بولمىدى:%s\n" #: ../src/core/session.c:1001 #, c-format msgid "Error writing session file '%s': %s\n" -msgstr "ئەڭگىمە ھۆججىتى “%s”نى يېزىشتا خاتالىق كۆرۈلدى:%s\n" +msgstr "ئەڭگىمە ھۆججىتى ‹%s› نى يېزىشتا خاتالىق كۆرۈلدى:%s\n" #: ../src/core/session.c:1006 #, c-format msgid "Error closing session file '%s': %s\n" -msgstr "ئەڭگىمە ھۆججىتى“%s”نى تاقاشتا خاتالىق كۆرۈلدى:%s\n" +msgstr "ئەڭگىمە ھۆججىتى ‹%s› نى تاقاشتا خاتالىق كۆرۈلدى:%s\n" #: ../src/core/session.c:1136 #, c-format msgid "Failed to parse saved session file: %s\n" -msgstr "ئىزاھلاپ ساقلىغىلى بولمايدىغان ئەڭگىمە ھۆججىتى:%s\n" +msgstr "ئەڭگىمە ھۆججىتى تەھلىل قىلىش مەغلۇپ بولدى: %s\n" #: ../src/core/session.c:1185 #, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "" -"<muffin_session> دېگەن خاسلىق بايقالدى، بىراق بىزدە ئەڭگىمە ID سى بار ئىدى." +msgid "<mutter_session> attribute seen but we already have the session ID" +msgstr "<mutter_session> دېگەن خاسلىق بايقالدى، بىراق بىزدە ئەڭگىمە ID سى بار ئىدى." #: ../src/core/session.c:1198 ../src/core/session.c:1273 #: ../src/core/session.c:1305 ../src/core/session.c:1377 @@ -665,67 +433,57 @@ msgstr "<window> بىلەن گىرەلىشىش بەلگىسى" #: ../src/core/session.c:1457 #, c-format msgid "Unknown element %s" -msgstr "يوچۇن ئېلېمېنت %s" +msgstr "نامەلۇم ئېلېمېنت %s" #: ../src/core/session.c:1809 msgid "" "These windows do not support "save current setup" and will have to " "be restarted manually next time you log in." -msgstr "" -"بۇ كۆزنەكلەردە «ھازىرقى تەڭشەكنى ساقلاش» ئىقتىدارىنى ئىشلەتكىلى بولمايدۇ. " -"كېيىن تىزىمغا كىرگەندە يەنە قوزغىتىڭ." +msgstr "بۇ كۆزنەكلەردە «ھازىرقى تەڭشەكنى ساقلاش» ئىقتىدارىنى ئىشلەتكىلى بولمايدۇ. كېيىن كىرگەندە يەنە قوزغىتىڭ." -#: ../src/core/util.c:111 +#: ../src/core/util.c:84 #, c-format msgid "Failed to open debug log: %s\n" -msgstr "تەڭشەلگەن خاتىرىنى ئاچقىلى بولمىدى:%s\n" +msgstr "سازلاش خاتىرىسىنى ئېچىش مەغلۇپ بولدى:%s\n" -#: ../src/core/util.c:121 +#: ../src/core/util.c:94 #, c-format msgid "Failed to fdopen() log file %s: %s\n" -msgstr "خاتىرە ھۆججىتى %s غا fdopen() مەشغۇلاتى قىلغىلى بولمىدى:%s\n" +msgstr "خاتىرە ھۆججىتى %s غا fdopen() مەشغۇلاتى قىلغىلى بولمىدى:%s\n" -#: ../src/core/util.c:127 +#: ../src/core/util.c:100 #, c-format msgid "Opened log file %s\n" -msgstr "ئاچقان خاتىرە ھۆججىتى %s\n" +msgstr "ئاچقان خاتىرە ھۆججەت %s\n" -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 +#: ../src/core/util.c:119 ../src/tools/mutter-message.c:149 #, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "Muffin تەرجىمە-تەھرىرلىگەندە تەپسىلات قوللاش ھالىتى قوشۇلمىغان\n" +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter تەرجىمە-تەھرىرلىگەندە تەپسىلات قوللاش ھالىتى قوشۇلمىغان\n" -#: ../src/core/util.c:286 +#: ../src/core/util.c:264 msgid "Window manager: " -msgstr "كۆزنەك باشقۇرغۇچ: " +msgstr "كۆزنەك باشقۇرغۇ: " -#: ../src/core/util.c:434 +#: ../src/core/util.c:412 msgid "Bug in window manager: " -msgstr "كۆزنەك باشقۇرغۇچتىكى خاتالىق: " +msgstr "كۆزنەك باشقۇرغۇدىكى كەمتۈك: " -#: ../src/core/util.c:467 +#: ../src/core/util.c:443 msgid "Window manager warning: " -msgstr "كۆزنەك باشقۇرغۇچ سىگنالى: " +msgstr "كۆزنەك باشقۇرغۇ ئاگاھلاندۇرۇشى: " -#: ../src/core/util.c:495 +#: ../src/core/util.c:471 msgid "Window manager error: " -msgstr "كۆزنەك باشقۇرغۇچ خاتالىقى: " - -#. Translators: This is the title used on dialog boxes -#: ../src/core/util.c:632 ../src/muffin.desktop.in.h:1 -#: ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" +msgstr "كۆزنەك باشقۇرغۇ خاتالىقى: " #. first time through -#: ../src/core/window.c:7019 +#: ../src/core/window.c:7596 #, c-format msgid "" "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " "window as specified in the ICCCM.\n" -msgstr "" -"%s كۆزنەك ئۆزىدە SM_CLIENT_ID نى تەڭشەيدۇ، ICCCM دا بەلگىلەنگەندەك، " -"WM_CLIENT_LEADER كۆزنەكتە تەڭشەيدۇ\n" +msgstr "كۆزنەك %s بەلگىلىمە ICCCM دا بەلگىلەنگەن WM_CLIENT_LEADER كۆزنەكنى ئەمەس SM_CLIENT_ID نى ئۆزى بەلگىلىۋېلىپتۇ.\n" #. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the #. * authoritative source for that info. Some apps such as mplayer or @@ -734,35 +492,29 @@ msgstr "" #. * MWM but not WM_NORMAL_HINTS are basically broken. We complain #. * about these apps but make them work. #. -#: ../src/core/window.c:7682 +#: ../src/core/window.c:8320 #, c-format msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %" -"d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"%s كۆزنەك MWM ئەسكەرتىشىدىن بىرنى تەڭشىدى، ئۇنىڭ چوڭلۇقىنى تەڭشىگىلى " -"بولمايدىغانلىقىنى ئىپادىلەيدۇ ئەمما تەڭشەلگەن ئەڭ كىچىك چوڭلۇقى %dx%d، ئەڭ " -"چوڭ چوڭلۇقى %dx%d؛ بۇنىڭ ھېچقانداق مەنىسى يوق.\n" +"Window %s sets an MWM hint indicating it isn't resizable, but sets min size " +"%d x %d and max size %d x %d; this doesn't make much sense.\n" +msgstr "كۆزنەك %s نىڭدا MWM بەلگىلەنگەن بولۇپ، بۇ كۆزنەك چوڭلۇقىنى ئۆزگەرتكىلى بولمايدۇ دېگەن مەنىدە. بىراق ئەڭ كىچىك چوڭلۇقى%d x %d، ۋە ئەڭ كىچىك چوڭلۇقى %d x %d قىلىپ بەلگىلىنىپتۇ. بۇنىڭ ھېچقانداق ئەھمىيىتى يوق.\n" -#: ../src/core/window-props.c:309 +#: ../src/core/window-props.c:318 #, c-format msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "" -"پروگرامما بىر ساختا _NET_WM_PID %lu\n" -" نى تەڭشىدى\n" +msgstr "پروگرامما بىر ساختا _NET_WM_PID نى بەلگىلىدى%lu\n" -#: ../src/core/window-props.c:426 +#: ../src/core/window-props.c:434 #, c-format msgid "%s (on %s)" -msgstr "%s (ھەققىدە %s)" +msgstr "%s (ھازىر %s نىڭ ئۈستىدە)" -#: ../src/core/window-props.c:1481 +#: ../src/core/window-props.c:1517 #, c-format msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "" -"%2$s گە بەلگىلەنگەن ئۈنۈمسىز WM_TRANSIENT_FOR كۆزنەك 0x%1$lx بولىدۇ.\n" +msgstr "%2$s گە بەلگىلەنگەن ئۈنۈمسىز WM_TRANSIENT_FOR كۆزنەك 0x%1$lx بولىدۇ.\n" -#: ../src/core/window-props.c:1492 +#: ../src/core/window-props.c:1528 #, c-format msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" msgstr "%2$s نىڭ WM_TRANSIENT_FOR كۆزنەك0x%1$lx دەۋرىيلىك قۇرۇشى مۇمكىن.\n" @@ -775,13 +527,11 @@ msgid "" "and actually has type %s format %d n_items %d.\n" "This is most likely an application bug, not a window manager bug.\n" "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"0x%lx كۆزنەكنىڭ خاسلىقى %s\n" -"نىڭ ئۈمىد قىلىنغان تىپى%s پىچىمى %d\n" -"ئەمما ئەمەلىي تىپى %s، پىچىمى %d، n_items %d\n" -"بۇ بەلكىم قوللىنىشچان پىروگراممىنىڭ خاتالىقى بولۇشى مۇمكىن، كۆزنەك " -"باشقۇرغۇچنىڭ خاتالىقى ئەمەس.\n" -"كۆزنەكنىڭ ماۋزۇسى \"%s\"، خىلى \"%s\"، ئاتى \"%s\"\n" +msgstr "كۆزنەك 0x%1$lx نىڭدا type %5$s format %6$d n_items %7$d دېگەن \n" +"خاسلىقنىڭ %2$s كۆرسىتىلگەن، ئەمەلىيەتتە type %3$s format %4$d بولۇشى \n" +"تەلەپ قىلىناتتى. بۇ كۆپ ھاللاردا ئەپنىڭ كەمتۈكى بولۇپ،\n" +"كۆزنەك باشقۇرغۇنىڭ كەمتۈكى ئەمەس.\n" +"كۆزنەك خاسلىقى title=\"%8$s\" class=\"%9$s\" name=\"%10$s\" .\n" #: ../src/core/xprops.c:411 #, c-format @@ -792,121 +542,120 @@ msgstr "خاسلىق %s (كۆزنەك 0x%lx) دا ئىناۋەتسىز UTF-8 ب #, c-format msgid "" "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"خاسلىق %s (كۆزنەك 0x%lx) دىكى تىزىم تۇرى %d نىڭ تەركىبىدە ئىناۋەتسىز UTF-8 " -"بار\n" - -#: ../src/muffin.schemas.in.h:1 -msgid "Attach modal dialogs" -msgstr "قوشۇلغان مودېل سۆزلەشكۈ" +msgstr "خاسلىق %s (كۆزنەك 0x%lx) دىكى تىزىمنىڭ %d تۈرى تەركىبىدە ئىناۋەتسىز UTF-8 بار\n" -#: ../src/muffin.schemas.in.h:2 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"يوشۇرۇن كۆزنەك (مەسىلەن، كىچىكلىتىلگەن ۋە باشقا خىزمەت رايونىدىكى كۆزنەك)نىڭ " -"ھالىتىنى ساقلاش ياكى ساقلىماسلىقنى جەزملەيدۇ." +#: ../src/mutter.desktop.in.h:1 ../src/mutter-wm.desktop.in.h:1 +msgid "Mutter" +msgstr "Mutter" -#: ../src/muffin.schemas.in.h:3 -msgid "" -"Determines whether workspace switching should happen for windows on all " -"monitors or only for windows on the primary monitor." -msgstr "" -"خىزمەت رايونى ئالماشتۇرۇشنىڭ ھەممە ئېكراندىكى كۆزنەككىمۇ ياكى ئاساسىي " -"ئېكرانغىلا قارىتىلغانلىقىنى جەزملەيدۇ." - -#: ../src/muffin.schemas.in.h:4 -msgid "Draggable border width" -msgstr "" - -#: ../src/muffin.schemas.in.h:5 -msgid "Live Hidden Windows" -msgstr "شۇئان يوشۇرۇنىدىغان كۆزنەكلەر" - -#: ../src/muffin.schemas.in.h:6 +#: ../src/org.gnome.mutter.gschema.xml.in.h:1 msgid "Modifier to use for extended window management operations" msgstr "كېڭەيتىلگەن كۆزنەك باشقۇرۇش مەشغۇلاتىغا ئىشلىتىلىدىغان ئۆزگەرتىش" -#: ../src/muffin.schemas.in.h:7 -msgid "" -"The amount of total draggable borders. If the theme's visible borders are " -"not enough, invisible borders will be added to meet this value." -msgstr "" - -#: ../src/muffin.schemas.in.h:8 +#: ../src/org.gnome.mutter.gschema.xml.in.h:2 msgid "" "This key will initiate the \"overlay\", which is a combination window " "overview and application launching system. The default is intended to be the " "\"Windows key\" on PC hardware. It's expected that this binding either the " "default or set to the empty string." -msgstr "" -"بۇ كۇنۇپكا كۆرسەتكەن «قاپلا» بىر خىل ئارىلاش كۆزنەك چۈشەندۈرۈشى ۋە " -"قوللىنىشچان پىروگرامما ئىجرا قىلىنىدىغان سىستېمىنى كۆرسىتىدۇ. كۆڭۈلدىكى " -"ئەھۋالدا يەككە كومپيۇتېردىكى \"Windows key\" كۇنۇپكىسىنى ئىشلىتىشنى تەلەپ " -"قىلىدۇ. بەلكىم كۆڭۈلدىكى ياكى بوش تىزىقنى ئىشلىتىدۇ." +msgstr "بۇ كۇنۇپكا كۆرسەتكەن «قاپلا» بىر خىل ئارىلاش كۆزنەك چۈشەندۈرۈشى ۋە قوللىنىشچان پروگرامما ئىجرا قىلىنىدىغان سىستېمىنى كۆرسىتىدۇ. كۆڭۈلدىكى ئەھۋالدا يەككە كومپيۇتېردىكى \"Windows key\" كۇنۇپكىسىنى ئىشلىتىشنى تەلەپ قىلىدۇ. بەلكىم كۆڭۈلدىكى ياكى بوش تىزىقنى ئىشلىتىدۇ." + +#: ../src/org.gnome.mutter.gschema.xml.in.h:3 +msgid "Attach modal dialogs" +msgstr "قوشۇلغان مودېل سۆزلەشكۈ" -#: ../src/muffin.schemas.in.h:9 +#: ../src/org.gnome.mutter.gschema.xml.in.h:4 msgid "" "When true, instead of having independent titlebars, modal dialogs appear " "attached to the titlebar of the parent window and are moved together with " "the parent window." +msgstr "true بولغاندا مودېل سۆزلەشكۈ ئاتا كۆزنەكنىڭ ماۋزۇ بالداققا يېپىشىپ كۆرۈنىدۇ ھەمدە ئاتا كۆزنەككە ئەگىشىپ يۆتكىلىدۇ، ئايرىم ماۋزۇ بالدىقى بولمايدۇ." + +#: ../src/org.gnome.mutter.gschema.xml.in.h:5 +msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "" + +#: ../src/org.gnome.mutter.gschema.xml.in.h:6 +msgid "" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." msgstr "" -"true بولغاندا مودېل سۆزلەشكۈ ئاتا كۆزنەكنىڭ ماۋزۇ بالداققا يېپىشىپ كۆرۈنىدۇ " -"ھەمدە ئاتا كۆزنەككە ئەگىشىپ يۆتكىلىدۇ، ئايرىم ماۋزۇ بالدىقى بولمايدۇ." -#: ../src/muffin.schemas.in.h:10 +#: ../src/org.gnome.mutter.gschema.xml.in.h:7 +msgid "Workspaces are managed dynamically" +msgstr "خىزمەت رايونلىرى جانلىق باشقۇرۇلسۇن" + +#: ../src/org.gnome.mutter.gschema.xml.in.h:8 +msgid "" +"Determines whether workspaces are managed dynamically or whether there's a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." +msgstr "خىزمەت رايونلىرى جانلىق باشقۇرۇلامدۇ ياكى خىزمەت رايونلىرىنىڭ سانى مۇقىم بولامدۇ بەلگىلەيدۇ(خىزمەت رايونلىرىنىڭ سانى org.gnome.desktop.wm.preferences دېگەن ئاچقۇچتا بەلگىلىنىدۇ)" + +#: ../src/org.gnome.mutter.gschema.xml.in.h:9 msgid "Workspaces only on primary" msgstr "ئاساسىي كۆزەتكۈچتىكى خىزمەت رايونىغىلا" -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "ئىشلىتىش ئۇسۇلى:%s\n" +#: ../src/org.gnome.mutter.gschema.xml.in.h:10 +msgid "" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." +msgstr "خىزمەت رايونى ئالماشتۇرۇشنىڭ ھەممە ئېكراندىكى كۆزنەككىمۇ ياكى ئاساسىي ئېكرانغىلا قارىتىلغانلىقىنى جەزملەيدۇ." -#: ../src/ui/frames.c:1157 -msgid "Close Window" -msgstr "كۆزنەك ياپ" +#: ../src/org.gnome.mutter.gschema.xml.in.h:11 +msgid "No tab popup" +msgstr "بەتكۈچ سەكرىمىسۇن" -#: ../src/ui/frames.c:1160 -msgid "Window Menu" -msgstr "كۆزنەك تىزىملىكى" +#: ../src/org.gnome.mutter.gschema.xml.in.h:12 +msgid "" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." +msgstr "" -#: ../src/ui/frames.c:1163 -msgid "Minimize Window" -msgstr "كۆزنەكنى كىچىكلەت" +#: ../src/org.gnome.mutter.gschema.xml.in.h:13 +msgid "Delay focus changes until the pointer stops moving" +msgstr "" -#: ../src/ui/frames.c:1166 -msgid "Maximize Window" -msgstr "كۆزنەكنى چوڭايت" +#: ../src/org.gnome.mutter.gschema.xml.in.h:14 +msgid "" +"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " +"the focus will not be changed immediately when entering a window, but only " +"after the pointer stops moving." +msgstr "" -#: ../src/ui/frames.c:1169 -msgid "Restore Window" -msgstr "كۆزنەكنى ئەسلىگە كەلتۈر" +#: ../src/org.gnome.mutter.gschema.xml.in.h:15 +msgid "Draggable border width" +msgstr "سۆرەشكە بولىدىغان گىرۋەكنىڭ كەڭلىكى" -#: ../src/ui/frames.c:1172 -msgid "Roll Up Window" -msgstr "كۆزنەكنى تۈر" +#: ../src/org.gnome.mutter.gschema.xml.in.h:16 +msgid "" +"The amount of total draggable borders. If the theme's visible borders are " +"not enough, invisible borders will be added to meet this value." +msgstr "سۆرەشكە بولىدىغان گىرۋەكنىڭ كەڭلىكى. ئۆرنەكتە كۆرسىتىلىۋاتقان گىرۋەكنىڭ كەڭلىكى بۇنىڭدىن كىچىك بولسا، كۆرسەتكىلى بولمايدىغان گىرۋەككە مۇشۇ قىممەتكە ماس كېلىدىغان قىلىپ قىممەت قوشۇلىدۇ." -#: ../src/ui/frames.c:1175 -msgid "Unroll Window" -msgstr "كۆزنەكنى تۈرمە" +#: ../src/org.gnome.mutter.gschema.xml.in.h:17 +msgid "Auto maximize nearly monitor sized windows" +msgstr "" -#: ../src/ui/frames.c:1178 -msgid "Keep Window On Top" -msgstr "كۆزنەكنى چوققىلاشنى ساقلا" +#: ../src/org.gnome.mutter.gschema.xml.in.h:18 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" -#: ../src/ui/frames.c:1181 -msgid "Remove Window From Top" -msgstr "كۆزنەكنى چوققىلاشنى بىكار قىلىش" +#: ../src/org.gnome.mutter.gschema.xml.in.h:19 +msgid "Select window from tab popup" +msgstr "سەكرەپ چىققان بەتكۈچتىن كۆزنەك تاللىسۇن" -#: ../src/ui/frames.c:1184 -msgid "Always On Visible Workspace" -msgstr "خىزمەت رايونىدا ئىزچىل كۆرۈنسۇن" +#: ../src/org.gnome.mutter.gschema.xml.in.h:20 +msgid "Cancel tab popup" +msgstr "سەكرەپ چىققان بەتكۈچنى ئەمەلدىن قالدۇر" -#: ../src/ui/frames.c:1187 -msgid "Put Window On Only One Workspace" -msgstr "بىر خىزمەت رايونىغا ئورۇنلاشتۇرۇش" +#: ../src/tools/mutter-message.c:123 +#, c-format +msgid "Usage: %s\n" +msgstr "ئىشلىتىش ئۇسۇلى: %s\n" #. Translators: Translate this string the same way as you do in libwnck! #: ../src/ui/menu.c:69 @@ -931,7 +680,7 @@ msgstr "تۈر(_U)" #. Translators: Translate this string the same way as you do in libwnck! #: ../src/ui/menu.c:77 msgid "_Unroll" -msgstr "ياي(_U)" +msgstr "تۈرمە(_U)" #. Translators: Translate this string the same way as you do in libwnck! #: ../src/ui/menu.c:79 @@ -946,13 +695,13 @@ msgstr "چوڭلۇقىنى ئۆزگەرت(_R)" #. Translators: Translate this string the same way as you do in libwnck! #: ../src/ui/menu.c:83 msgid "Move Titlebar On_screen" -msgstr "تېما ئىستونىنى ئېكرانغا يۆتكەش (_S)" +msgstr "ماۋزۇ بالدىقىنى ئېكرانغا يۆتكە(_S)" #. separator #. Translators: Translate this string the same way as you do in libwnck! #: ../src/ui/menu.c:86 ../src/ui/menu.c:88 msgid "Always on _Top" -msgstr "ھەمىشە چوققىدا (_T)" +msgstr "دائىم چوققىدا تۇرغۇز(_T)" #. Translators: Translate this string the same way as you do in libwnck! #: ../src/ui/menu.c:90 @@ -993,7 +742,7 @@ msgstr "ياپ(_C)" #: ../src/ui/menu.c:204 #, c-format msgid "Workspace %d%n" -msgstr "خىزمەت مۇھىتى %d%n" +msgstr "خىزمەت رايونى %d%n" #: ../src/ui/menu.c:214 #, c-format @@ -1102,304 +851,269 @@ msgstr "Mod5" #. Translators: This represents the size of a window. The first number is #. * the width of the window and the second is the height. #. -#: ../src/ui/resizepopup.c:113 +#: ../src/ui/resizepopup.c:136 #, c-format msgid "%d x %d" msgstr "%d x %d" -#: ../src/ui/theme.c:253 +#: ../src/ui/theme.c:236 msgid "top" msgstr "چوققا" -#: ../src/ui/theme.c:255 +#: ../src/ui/theme.c:238 msgid "bottom" msgstr "ئاستى" -#: ../src/ui/theme.c:257 +#: ../src/ui/theme.c:240 msgid "left" msgstr "سول" -#: ../src/ui/theme.c:259 +#: ../src/ui/theme.c:242 msgid "right" msgstr "ئوڭ" -#: ../src/ui/theme.c:286 +#: ../src/ui/theme.c:270 #, c-format msgid "frame geometry does not specify \"%s\" dimension" -msgstr "كاندۇك گىيومېتىرىك جايلاشتۇرۇش \"%s\" نىڭ چوڭلۇقىنى بەلگىلىمىگەن" +msgstr "كاندۇكنىڭ گېئومېتىرىيىلىك شەكلى «%s» ئۆلچەمنى ئىپادىلىمەيدۇ" -#: ../src/ui/theme.c:305 +#: ../src/ui/theme.c:289 #, c-format msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "" -"كاندۇك گىيومېتىرىك جايلاشتۇرۇش \"%s\" نىڭ چوڭلۇقىنى بەلگىلىمىگەن(\"%s\" " -"گىرۋىكىگە بەلگىلەنگەن)" +msgstr "كاندۇكنىڭ گېئومېتىرىيىلىك شەكلى گىرۋەك «%2$s» نىڭ ئۆلچىمى «%1$s» ئىپادىلىمەيدۇ" -#: ../src/ui/theme.c:342 +#: ../src/ui/theme.c:326 #, c-format msgid "Button aspect ratio %g is not reasonable" -msgstr "كۇنۇپكا ئۇزۇنلۇق كەڭلىك نىسبىتى %g غا ماس كەلمەيدۇ" +msgstr "توپچىنىڭ ئېگىزلىك ۋە كەڭلىك نىسبىتى %g مۇۋاپىق ئەمەس" -#: ../src/ui/theme.c:354 +#: ../src/ui/theme.c:338 #, c-format msgid "Frame geometry does not specify size of buttons" -msgstr "كاندۇك گىيومېتىرىك جايلاشتۇرۇشتا تۈگمە چوڭلۇقى بەلگىلەنمىگەن" +msgstr "كاندۇكنىڭ گېئومېتىرىيىلىك شەكلى توپچىلارنىڭ چوڭلۇقىنى ئىپادىلىمەيدۇ" -#: ../src/ui/theme.c:1060 +#: ../src/ui/theme.c:1051 #, c-format msgid "Gradients should have at least two colors" msgstr "تەدرىجىي ئۆزگىرىشتە ئاز دېگەندە ئىككى خىل رەڭ بولۇش كېرەك" -#: ../src/ui/theme.c:1212 +#: ../src/ui/theme.c:1203 #, c-format msgid "" "GTK custom color specification must have color name and fallback in " "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" -msgstr "" -"GTK رەڭ ئۆلچىمىدە ھالەتتىن كېيىن چوقۇم رەڭ ئاتى ۋە زاپاس بولۇشى لازىم، " -"مەسىلەن، gtk:custom(foo,bar) ھالەت؛ \"%s\" نى تەھلىل قىلالمايدۇ" +msgstr "GTK رەڭ ئۆلچىمىدە ھالەتتىن كېيىن چوقۇم رەڭ ئاتى ۋە زاپاس بولۇشى لازىم، مەسىلەن، gtk:custom(foo,bar) ھالەت؛ «%s» نى تەھلىل قىلالمايدۇ" -#: ../src/ui/theme.c:1228 +#: ../src/ui/theme.c:1219 #, c-format msgid "" "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" "_ are valid" -msgstr "" -"gtk:custom نىڭ color_name پارامېتىرىدىكى ئىناۋەتسىز ھەرپ '%c'، پەقەت A-Za-z0-" -"9-_ نىلا ئىشلەتكىلى بولىدۇ" +msgstr "gtk:custom نىڭ color_name پارامېتىرىدىكى ئىناۋەتسىز ھەرپ '%c'، پەقەت A-Za-z0-9-_ نىلا ئىشلەتكىلى بولىدۇ" -#: ../src/ui/theme.c:1242 +#: ../src/ui/theme.c:1233 #, c-format msgid "" "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " "fit the format" -msgstr "" -"Gtk:custom نىڭ پىچىمى \"gtk:custom(color_name,fallback)\" بولۇپ، \"%s\" " -"پىچىمغا توغرا كەلمەيدۇ" +msgstr "Gtk:custom نىڭ پىچىمى \"gtk:custom(color_name,fallback)\" بولۇپ، «%s» پىچىمغا توغرا كەلمەيدۇ" -#: ../src/ui/theme.c:1287 +#: ../src/ui/theme.c:1278 #, c-format msgid "" "GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " "where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"GTK رەڭ ئۆلچىمىدە ھالەت چوقۇم ئوتتۇرا تىرناققا ئېلىنىشى لازىم، مەسىلەن، gtk:" -"fg[NORMAL] بۇنىڭدىكى NORMAL ھالەت؛ \"%s\" نى تەھلىل قىلالمايدۇ" +msgstr "GTK رەڭ بەلگىلىمىسىنىڭ ھالىتى چوقۇم gtk:fg[NORMAL] نىڭدەك تىرناق ئىچىگە ئېلىنىشى كېرەك؛ «%s» نى تەھلىل قىلغىلى بولمىدى." -#: ../src/ui/theme.c:1301 +#: ../src/ui/theme.c:1292 #, c-format msgid "" "GTK color specification must have a close bracket after the state, e.g. gtk:" "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"GTK رەڭ ئۆلچىمىدە ھالەتتىن كېيىن چوقۇم ئوتتۇرا تىرناق يېپىلىشى لازىم، " -"مەسىلەن، gtk:fg[NORMAL] بۇنىڭدىكى NORMAL ھالەت؛ \"%s\" نى تەھلىل قىلالمايدۇ" +msgstr "GTK رەڭ بەلگىلىمىسىنىڭ ھالىتىنىڭ ئارقىسىغا سول تىرناق يېزىلىشى كېرەك. مەسىلەن gtk:fg[NORMAL] نىڭدەك بۇ يەردىكى «NORMAL» ھالەتنى بىلدۈرىدۇ؛ «%s» نى تەھلىل قىلغىلى بولمىدى." -#: ../src/ui/theme.c:1312 +#: ../src/ui/theme.c:1303 #, c-format msgid "Did not understand state \"%s\" in color specification" msgstr "رەڭ بەلگىلىمىسىدىكى «%s» ھالەتنى چۈشەنگىلى بولمىدى" -#: ../src/ui/theme.c:1325 +#: ../src/ui/theme.c:1316 #, c-format msgid "Did not understand color component \"%s\" in color specification" msgstr "رەڭ بەلگىلىمىسىدىكى «%s» رەڭ بۆلىكىنى چۈشەنگىلى بولمىدى" -#: ../src/ui/theme.c:1355 +#: ../src/ui/theme.c:1345 #, c-format msgid "" "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " "format" -msgstr "" -"بىرىكمە رەڭنىڭ فورماتى \"blend/bg_color/fg_color/alpha\"، \"%s\" بۇ " -"فورماتقا ماس كەلمىدى" +msgstr "بىرىكمە رەڭنىڭ فورماتى \"blend/bg_color/fg_color/alpha\"، «%s» بۇ پىچىمغا ماس كەلمىدى" -#: ../src/ui/theme.c:1366 +#: ../src/ui/theme.c:1356 #, c-format msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "بىرىكمە رەڭدىكى ئالفا قىممىتى \"%s\" نى تەھلىل قىلغىلى بولمىدى" +msgstr "بىرىكمە رەڭدىكى ئالفا قىممىتى «%s» نى تەھلىل قىلغىلى بولمىدى" -#: ../src/ui/theme.c:1376 +#: ../src/ui/theme.c:1366 #, c-format msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "" -"بىرىكمە رەڭنىڭ ئالفا قىممىتى \"%s\" نىڭ دائىرىسى 0.0 ~1.0 ئىچىدە ئەمەس" +msgstr "بىرىكمە رەڭنىڭ ئالفا قىممىتى «%s» نىڭ دائىرىسى 0.0 ~1.0 ئىچىدە ئەمەس" -#: ../src/ui/theme.c:1423 +#: ../src/ui/theme.c:1413 #, c-format msgid "" "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "سايە پىچىمى \"shade/base_color/factor\"، \"%s\" پىچىمغا توغرا كەلمەيدۇ" +msgstr "سايە پىچىمى «shade/base_color/factor»، «%s» بۇ پىچىمغا ماسلاشمىدى" -#: ../src/ui/theme.c:1434 +#: ../src/ui/theme.c:1424 #, c-format msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "سايە رەڭگىدىكى سايە فاكتور «%s»نى تەھلىل قىلغىلى بولمىدى" +msgstr "سايە رەڭگىدىكى سايە فاكتور «%s» نى تەھلىل قىلغىلى بولمىدى" -#: ../src/ui/theme.c:1444 +#: ../src/ui/theme.c:1434 #, c-format msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "سايە رەڭگىدىكى سايە فاكتور “%s” مەنپىي سان" +msgstr "سايە رەڭگىدىكى سايە فاكتورى «%s» مەنپىي سان" -#: ../src/ui/theme.c:1473 +#: ../src/ui/theme.c:1463 #, c-format msgid "Could not parse color \"%s\"" -msgstr "رەڭنى تەھلىل قىلغىلى بولمىدى“%s”" +msgstr "رەڭ «%s» نى ئانالىز قىلغىلى بولمىدى" -#: ../src/ui/theme.c:1784 +#: ../src/ui/theme.c:1780 #, c-format msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "كوئوردېنات ئىپادىسىنىڭ تەركىبىدە رۇخسەت قىلىنمىغان تېكىست '%s' بار" +msgstr "كوئوردېنات ئىپادىسىنىڭ تەركىبىدە رۇخسەت قىلىنمىغان ھەرپ '‹%s› بار" -#: ../src/ui/theme.c:1811 +#: ../src/ui/theme.c:1807 #, c-format msgid "" "Coordinate expression contains floating point number '%s' which could not be " "parsed" -msgstr "" -"كوئوردېنات ئىپادىسىنىڭ تەركىبىدە تەھلىل قىلغىلى بولمايدىغان كەسىر سان '%s' " -"بار" +msgstr "كوئوردېنات ئىپادىسىنىڭ تەركىبىدە تەھلىل قىلغىلى بولمايدىغان كەسىر سان ‹%s› بار" -#: ../src/ui/theme.c:1825 +#: ../src/ui/theme.c:1821 #, c-format msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "" -"كوئوردېنات ئىپادىسىنىڭ تەركىبىدە تەھلىل قىلغىلى بولمايدىغان پۈتۈن سان '%s' " -"بار" +msgstr "كوئوردېنات ئىپادىسىنىڭ تەركىبىدە تەھلىل قىلغىلى بولمايدىغان پۈتۈن سان ‹%s› بار" -#: ../src/ui/theme.c:1947 +#: ../src/ui/theme.c:1942 #, c-format msgid "" "Coordinate expression contained unknown operator at the start of this text: " "\"%s\"" msgstr "كوئوردېنات ئىپادىسىنىڭ بېشىدا نامەلۇم ئەمەل بار: «%s»" -#: ../src/ui/theme.c:2004 +#: ../src/ui/theme.c:1999 #, c-format msgid "Coordinate expression was empty or not understood" -msgstr "كوئوردېناتنىڭ ئىپادىلەش شەكلى قۇرۇق ياكى چۈشىنىكسىز" +msgstr "كوئوردېنات ئىپادىسى قۇرۇق ياكى چۈشىنىكسىز" -#: ../src/ui/theme.c:2115 ../src/ui/theme.c:2125 ../src/ui/theme.c:2159 +#: ../src/ui/theme.c:2112 ../src/ui/theme.c:2122 ../src/ui/theme.c:2156 #, c-format msgid "Coordinate expression results in division by zero" -msgstr "كوئوردېناتنىڭ ئىپادىلەش شەكلى 0 نى بۆلگۈچ قىلغان" +msgstr "كوئوردېنات ئىپادىسى 0 نى بۆلگۈچى قىلغان" -#: ../src/ui/theme.c:2167 +#: ../src/ui/theme.c:2164 #, c-format msgid "" "Coordinate expression tries to use mod operator on a floating-point number" msgstr "كوئوردېنات ئىپادىسى كەسىر سانغا mod ئەمىلىنى ئىشلەتمەكچى" -#: ../src/ui/theme.c:2223 +#: ../src/ui/theme.c:2220 #, c-format msgid "" "Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "" -"كوئوردېنات ئىپادىسىنىڭ تەركىبىدە سان كېلىدىغان يەردە ئەمەل \"%s\" بار ئىكەن" +msgstr "كوئوردېنات ئىپادىسىنىڭ تەركىبىدە سان كېلىدىغان يەردە ئەمەل «%s» بار ئىكەن" -#: ../src/ui/theme.c:2232 +#: ../src/ui/theme.c:2229 #, c-format msgid "Coordinate expression had an operand where an operator was expected" msgstr "كوئوردېنات ئىپادىسىنىڭ تەركىبىدە ئەمەل كېلىدىغان يەردە سان بار ئىكەن" -#: ../src/ui/theme.c:2240 +#: ../src/ui/theme.c:2237 #, c-format msgid "Coordinate expression ended with an operator instead of an operand" msgstr "كوئوردېنات ئىپادىسى سان بىلەن ئاياغلاشماي ئەمەل بىلەن ئاياغلاشقان" -#: ../src/ui/theme.c:2250 +#: ../src/ui/theme.c:2247 #, c-format msgid "" "Coordinate expression has operator \"%c\" following operator \"%c\" with no " "operand in between" -msgstr "" -"كوئوردېنات ئىپادىسىنىڭ تەركىبىدە ئەمەل \"%2$c\" نىڭ ئارقىسىدىن ئەمەل \"%1$c" -"\" كېلىپتۇ، ئارىلىقتا سان يوق ئىكەن" +msgstr "كوئوردېنات ئىپادىسىنىڭ تەركىبىدە ئەمەل «%2$c» نىڭ ئارقىسىدىن ئەمەل «%1$c» كېلىپتۇ، ئارىلىقتا سان يوق ئىكەن" -#: ../src/ui/theme.c:2401 ../src/ui/theme.c:2446 +#: ../src/ui/theme.c:2398 ../src/ui/theme.c:2443 #, c-format msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "" -"كوئوردېنات ئىپادىسىنىڭ تەركىبىدە نامەلۇم ئۆزگەرگۈچى ياكى تۇراقلىق سان \"%s\" " -"بار ئىكەن" +msgstr "كوئوردېنات ئىپادىسىنىڭ تەركىبىدە نامەلۇم ئۆزگەرگۈچى ياكى تۇراقلىق سان «%s» بار ئىكەن" -#: ../src/ui/theme.c:2500 +#: ../src/ui/theme.c:2497 #, c-format msgid "Coordinate expression parser overflowed its buffer." msgstr "كوئوردېنات ئىپادىسىنى تەھلىل قىلىۋاتقاندا يىغلەك تېشىپ كەتتى." -#: ../src/ui/theme.c:2529 +#: ../src/ui/theme.c:2526 #, c-format msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "" -"كوئوردېنات ئىپادىسىنىڭ تەركىبىدىكى يېپىلغان تىرناققا ماس كېلىدىغان ئېچىلغان " -"تىرناق يوق" +msgstr "كوئوردېنات ئىپادىسىنىڭ تەركىبىدىكى يېپىلغان تىرناققا ماس كېلىدىغان ئېچىلغان تىرناق يوق" -#: ../src/ui/theme.c:2593 +#: ../src/ui/theme.c:2590 #, c-format msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "" -"كوئوردېنات ئىپادىسىنىڭ تەركىبىدىكى ئېچىلغان تىرناققا ماس كېلىدىغان يېپىلغان " -"تىرناق يوق" +msgstr "كوئوردېنات ئىپادىسىنىڭ تەركىبىدىكى ئېچىلغان تىرناققا ماس كېلىدىغان يېپىلغان تىرناق يوق" -#: ../src/ui/theme.c:2604 +#: ../src/ui/theme.c:2601 #, c-format msgid "Coordinate expression doesn't seem to have any operators or operands" msgstr "كوئوردېنات ئىپادىسىنىڭ تەركىبىدە ئەمەل(قوشۇش، ئېلىش...) ياكى سان يوق" -#: ../src/ui/theme.c:2816 ../src/ui/theme.c:2836 ../src/ui/theme.c:2856 +#: ../src/ui/theme.c:2814 ../src/ui/theme.c:2834 ../src/ui/theme.c:2854 #, c-format msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "تېما تەركىبىدە خاتالىق چىقىرىدىغان ئىپادە بار: %s\n" +msgstr "ئۆرنەك تەركىبىدە خاتالىق چىقىرىدىغان ئىپادە بار: %s\n" -#: ../src/ui/theme.c:4527 +#: ../src/ui/theme.c:4500 #, c-format msgid "" "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " "specified for this frame style" -msgstr "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/>بۇ كۆزنەكنىڭ " -"ئۇسلۇبى ئۈچۈن بەلگىلىنىشى زۆرۈر" +msgstr "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/>بۇ كۆزنەكنىڭ ئۇسلۇبى ئۈچۈن بەلگىلىنىشى زۆرۈر" -#: ../src/ui/theme.c:5060 ../src/ui/theme.c:5085 +#: ../src/ui/theme.c:5011 ../src/ui/theme.c:5036 #, c-format msgid "" "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" -"<frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/> يوق" +msgstr "<frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/> يوق" -#: ../src/ui/theme.c:5133 +#: ../src/ui/theme.c:5084 #, c-format msgid "Failed to load theme \"%s\": %s\n" -msgstr "تېما “%s” نى كىرگۈزگىلى بولمىدى:%s\n" +msgstr "ئۆرنەك «%s» نى ئوقۇش مەغلۇپ بولدى: %s\n" -#: ../src/ui/theme.c:5269 ../src/ui/theme.c:5276 ../src/ui/theme.c:5283 -#: ../src/ui/theme.c:5290 ../src/ui/theme.c:5297 +#: ../src/ui/theme.c:5220 ../src/ui/theme.c:5227 ../src/ui/theme.c:5234 +#: ../src/ui/theme.c:5241 ../src/ui/theme.c:5248 #, c-format msgid "No <%s> set for theme \"%s\"" -msgstr "ئۇسلۇب \"%1$s\" نىڭ <%2$s> ئى بەلگىلەنمىگەن" +msgstr "ئۆرنەك «%2$s» نىڭ <%1$s> ئى بەلگىلەنمىگەن" -#: ../src/ui/theme.c:5305 +#: ../src/ui/theme.c:5256 #, c-format msgid "" "No frame style set for window type \"%s\" in theme \"%s\", add a <window " "type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" -"كۆزنەك تىپى \"%s\" (\"%s\" تېمىدا)غا كاندۇك كۆزنەك تەڭشەلمىگەن، بىر <window " -"type=\"%s\" style_set=\"whatever\"/> ئېلېمېنتى قوشۇڭ" +msgstr "ئۆرنەك «%2$s» نىڭ ئىچىدىكى كۆزنەك تىپى <%1$s> نىڭ كاندۇك ئۇسلۇبى بەلگىلەنمىگەن. بىر <window type=\"%3$s\" style_set=\"whatever\"/> ئېلېمېنتى قوشۇڭ" -#: ../src/ui/theme.c:5744 ../src/ui/theme.c:5806 ../src/ui/theme.c:5869 +#: ../src/ui/theme.c:5663 ../src/ui/theme.c:5725 ../src/ui/theme.c:5788 #, c-format msgid "" "User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" -"ئىشلەتكۈچى بەلگىلىگەن تۇراقلىق مىقدار چوقۇم چوڭ ھەرپ بىلەن باشلانسۇن؛ «%s» " -"بولمايدۇ" +msgstr "ئىشلەتكۈچى بەلگىلىگەن تۇراقلىق مىقدار چوقۇم چوڭ ھەرپ بىلەن باشلانسۇن؛ «%s» بولمايدۇ" -#: ../src/ui/theme.c:5752 ../src/ui/theme.c:5814 ../src/ui/theme.c:5877 +#: ../src/ui/theme.c:5671 ../src/ui/theme.c:5733 ../src/ui/theme.c:5796 #, c-format msgid "Constant \"%s\" has already been defined" -msgstr "تۇراقلىق سان “%s” غا ئېنىقلىما بېرىلگەن" +msgstr "تۇراقلىق سان «%s» غا ئېنىقلىما بېرىلگەن" #. Translators: This means that an attribute which should have been found #. * on an XML element was not in fact found. @@ -1417,22 +1131,22 @@ msgstr "%d قۇردىكى %d ھېرىپ بەلگە: %s" #: ../src/ui/theme-parser.c:479 #, c-format msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "خاسلىق \"%s\" ئوخشاش بىر <%s> ئېلېمېنتتا ئىككى قېتىم تەكرارلاندى" +msgstr "خاسلىق «%s» ئوخشاش بىر <%s> ئېلېمېنتتا ئىككى قېتىم تەكرارلاندى" #: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 #, c-format msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "بۇ تىل مۇھىتىدا \"%s\" خاسلىق <%s> ئېلېمېنتقا نىسبەتەن ئىناۋەتسىز" +msgstr "بۇ تىل مۇھىتىدا «%s» خاسلىق <%s> ئېلېمېنتقا نىسبەتەن ئىناۋەتسىز" #: ../src/ui/theme-parser.c:594 #, c-format msgid "Could not parse \"%s\" as an integer" -msgstr "“%s” نى پۈتۈنلىگىلى بولمىدى" +msgstr "«%s» نى پۈتۈن سان سۈپىتىدە تەھلىل قىلغىلى بولمىدى" #: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 #, c-format msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "چۈشىنىكسىز ئاخىرلاشتۇرغۇچى بەلگە “%s” ( ھېرىپ بەلگە تىزىقى “%s” دا)" +msgstr "چۈشىنىكسىز ئاخىرلاشتۇرغۇچى بەلگە «%s» ( تېكىست «%s» دا)" #: ../src/ui/theme-parser.c:613 #, c-format @@ -1447,12 +1161,12 @@ msgstr "پۈتۈن سان %ld بەك چوڭ، نۆۋەتتىكى ئەڭ چوڭ #: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 #, c-format msgid "Could not parse \"%s\" as a floating point number" -msgstr "“%s” نى ھەرىكەتچان نۇقتا قىلغىلى بولمىدى" +msgstr "«%s» نى ھەرىكەتچان نۇقتا قىلغىلى بولمىدى" #: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 #, c-format msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "Bool قىممىتى «راست» ياكى «يالغان» بولسۇن، “%s” بولسا بولمايدۇ" +msgstr "Bool قىممىتى «true» ياكى «false» بولسۇن، «%s» بولسا بولمايدۇ" #: ../src/ui/theme-parser.c:735 #, c-format @@ -1462,56 +1176,50 @@ msgstr "بۇلۇڭ قىممىتى 0.0 دىن 360.0 غىچە بولسۇن، ھا #: ../src/ui/theme-parser.c:798 #, c-format msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" -"Alpha قىممىتى 0.0 (كۆرۈنمەيدۇ) دىن 360.0 (سۈزۈك ئەمەس)غىچە بولسۇن، " -"ھازىرقىسى %g\n" +msgstr "Alpha قىممىتى 0.0 (كۆرۈنمەيدۇ) دىن 360.0 (سۈزۈك ئەمەس)غىچە بولسۇن، ھازىرقىسى %g\n" #: ../src/ui/theme-parser.c:863 #, c-format msgid "" "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," "large,x-large,xx-large)\n" -msgstr "" -"ئۈنۈمسىز ماۋزۇ نىسبىتى “%s” ( چوقۇم xx-small、x-small、small、medium、" -"large、x-large、xx-large لارنىڭ بىرى بۆلىشى كېرەك)\n" +msgstr "ئىناۋەتسىز ماۋزۇ نىسبىتى «%s» ( چوقۇم xx-small، x-small، small، medium، large، x-large، xx-large لارنىڭ بىرى بولۇشى كېرەك)\n" #: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 #: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 #, c-format msgid "<%s> name \"%s\" used a second time" -msgstr "<%s> قايتا ئىشلىتىلدى، نامى “%s”" +msgstr "<%s> قايتا ئىشلىتىلدى، نامى «%s»" #: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 #: ../src/ui/theme-parser.c:1231 #, c-format msgid "<%s> parent \"%s\" has not been defined" -msgstr "<%s> ئاتا \"%s\" بەلگىلەنمىگەن" +msgstr "<%s> ئاتا «%s» بەلگىلەنمىگەن" #: ../src/ui/theme-parser.c:1141 #, c-format msgid "<%s> geometry \"%s\" has not been defined" -msgstr "<%s> نىڭ گېئومېتىرىيىلىك ئورۇنلاشتۇرۇلۇشى “%s” غا ئېنىقلىما بېرىلمىگەن" +msgstr "<%s> نىڭ گېئومېتىرىيىلىك شەكلى «%s» بەلگىلەنمىگەن" #: ../src/ui/theme-parser.c:1154 #, c-format msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "" -"<%s> بىر گېيومېتىرىيىلىك ئورۇنلاشتۇرۇش ياكى گېيومېتىرىيىلىك ئورۇنلاشتۇرۇشى " -"بار ئاتا دەرىجىدىن بىرنى بەلگىلەش زۆرۈر" +msgstr "<%s> چوقۇم بىر گېئومېتىرىيىلىك شەكىلنى كۆرسىتىشى ياكى گېئومېتىرىيىلىك شەكلى بار ئاتىنى ئىپادىلىشى كېرەك" #: ../src/ui/theme-parser.c:1196 msgid "You must specify a background for an alpha value to be meaningful" -msgstr "alpha قىممىتىنىڭ مەنىسى بولۇشى ئۈچۈن، چوقۇم تەگلىك بەلگىلىشىڭىز لازىم" +msgstr "سىز تەگلىكنىڭ ئالفا قىممىتىگە مەنىلىك قىممەت بېرىشىڭىز كېرەك" #: ../src/ui/theme-parser.c:1264 #, c-format msgid "Unknown type \"%s\" on <%s> element" -msgstr "<%2$s> ئېلېمېنتتا نامەلۇم تىپ \"%1$s\" بار" +msgstr "<%2$s> ئېلېمېنتتا نامەلۇم تىپ «%1$s» بار" #: ../src/ui/theme-parser.c:1275 #, c-format msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "<%2$s> ئېلېمېنتتا نامەلۇم style_set \"%1$s\" بار" +msgstr "<%2$s> ئېلېمېنتتا نامەلۇم style_set «%1$s» بار" #: ../src/ui/theme-parser.c:1283 #, c-format @@ -1532,179 +1240,166 @@ msgstr "<%s> ئېلېمېنت <%s> ئاستىدا بولۇشقا يول قويۇ msgid "" "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " "for buttons" -msgstr "" -"بىر قانچە توپچىغا \"button_width\"/\"button_height\" ۋە \"aspect_ratio\" " -"دېگەن ئىككى خاسلىقنى قوشۇشقا بولمايدۇ" +msgstr "بىر قانچە توپچىغا «button_width»/«button_height» ۋە «aspect_ratio» دېگەن ئىككى خاسلىقنى قوشۇشقا بولمايدۇ" #: ../src/ui/theme-parser.c:1450 #, c-format msgid "Distance \"%s\" is unknown" -msgstr "ئارىلىق “%s” نامەلۇم" +msgstr "ئارىلىق «%s» نامەلۇم" #: ../src/ui/theme-parser.c:1495 #, c-format msgid "Aspect ratio \"%s\" is unknown" -msgstr "تەرەپلەر نىسبىتى \"%s\" نامەلۇم" +msgstr "تەرەپلەر نىسبىتى «%s» نامەلۇم" #: ../src/ui/theme-parser.c:1557 #, c-format msgid "Border \"%s\" is unknown" -msgstr "گىرۋەك \"%s\" نامەلۇم" +msgstr "گىرۋەك «%s» نامەلۇم" #: ../src/ui/theme-parser.c:1868 #, c-format msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "ئېلېمېنت <%s> نىڭ \"start_angle\" ياكى \"from\" دەيدىغان خاسلىقى يوق" +msgstr "ئېلېمېنت <%s> نىڭ «start_angle» ياكى «from» دەيدىغان خاسلىقى يوق" #: ../src/ui/theme-parser.c:1875 #, c-format msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "ئېلېمېنت <%s> نىڭ \"extent_angle\" ياكى \"to\" دەيدىغان خاسلىقى يوق" +msgstr "ئېلېمېنت <%s> نىڭ «extent_angle» ياكى «to» دەيدىغان خاسلىقى يوق" #: ../src/ui/theme-parser.c:2115 #, c-format msgid "Did not understand value \"%s\" for type of gradient" -msgstr "كونۇسلۇق دەرىجىسىنىڭ تىپىنى چۈشەنگىلى بولمايدىغان قىممەت “%s”" +msgstr "كونۇسلۇق دەرىجىسىنىڭ تىپىنى چۈشەنگىلى بولمايدىغان قىممەت «%s»" #: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 #, c-format msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "<%2$s>ئېلېمېنتتىكى تولدۇرۇش تىپى \"%1$s\" نى چۈشەنگىلى بولمىدى" +msgstr "<%2$s>ئېلېمېنتتىكى تولدۇرۇش تىپى «%1$s» نى چۈشەنگىلى بولمىدى" #: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 #: ../src/ui/theme-parser.c:2506 #, c-format msgid "Did not understand state \"%s\" for <%s> element" -msgstr "<%2$s> ئېلېمېنتتىكى ھالەت \"%1$s\" نى چۈشەنگىلى بولمىدى" +msgstr "<%2$s> ئېلېمېنتتىكى ھالەت «%1$s» نى چۈشەنگىلى بولمىدى" #: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 #, c-format msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "<%2$s> ئېلېمېنتتىكى سايە \"%1$s\" نى چۈشەنگىلى بولمىدى" +msgstr "<%2$s> ئېلېمېنتتىكى سايە «%1$s» نى چۈشەنگىلى بولمىدى" #: ../src/ui/theme-parser.c:2380 #, c-format msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "<%2$s> ئېلېمېنتتىكى ياق ئوق بەلگىسى \"%1$s\" نى چۈشەنگىلى بولمىدى" +msgstr "<%2$s> ئېلېمېنتتىكى ياق ئوق بەلگىسى «%1$s» نى چۈشەنگىلى بولمىدى" #: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 #, c-format msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "\"%s\" دېگەن <draw_ops> بېكىتىلمىگەن" +msgstr "«%s» دېگەن <draw_ops> بېكىتىلمىگەن" #: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 #, c-format msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "بۇ جاي draw_ops \"%s\" نى ئۆز ئىچىگە ئالسا بىر دەۋرىي نەقىل قۇرۇلىدۇ" +msgstr "بۇ يەرگە draw_ops «%s» كەلسە دەۋرىي پايدىلىنىش قۇرۇلىدۇ" #: ../src/ui/theme-parser.c:2917 #, c-format msgid "Unknown position \"%s\" for frame piece" -msgstr "كاندۇك ئورنى “%s” نامەلۇم" +msgstr "كاندۇك ئورنى «%s» نامەلۇم" #: ../src/ui/theme-parser.c:2925 #, c-format msgid "Frame style already has a piece at position %s" -msgstr "%s ئورۇندا بىر بۆلەك كاندۇك ئۇسلۇبى بار" +msgstr "كۆزنەك ئۇسلۇبىنىڭ %s ئورۇندا ئاللىقاچان پارچىسى بار" #: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 #, c-format msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "ئاتى \"%s\" بولغان <draw_ops> بېكىتىلمىگەن" +msgstr "ئاتى «%s» بولغان <draw_ops> بېكىتىلمىگەن" #: ../src/ui/theme-parser.c:2972 #, c-format msgid "Unknown function \"%s\" for button" -msgstr "كۇنۇپكىنىڭ فۇنكسىيىسى “%s” نامەلۇم" +msgstr "توپچىنىڭ فۇنكسىيىسى «%s» نامەلۇم" #: ../src/ui/theme-parser.c:2982 #, c-format msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "بۇ نەشرىدە \"%s\" دېگەن توپچىنىڭ ئىقتىدارى يوق (ھازىر %d، زۆرۈر %d)" +msgstr "بۇ نەشرىدە «%s» دېگەن توپچىنىڭ ئىقتىدارى يوق (ھازىر %d، زۆرۈر %d)" #: ../src/ui/theme-parser.c:2994 #, c-format msgid "Unknown state \"%s\" for button" -msgstr "توپچىنىڭ ھالىتى \"%s\" نامەلۇم" +msgstr "توپچىنىڭ ھالىتى «%s» نامەلۇم" #: ../src/ui/theme-parser.c:3002 #, c-format msgid "Frame style already has a button for function %s state %s" -msgstr "كاندۇك ئۇسلۇبىنىڭ %s فونكسىيە، %s ھالىتى بولغان تۈگمە بار" +msgstr "فۇنكسىيە %s ھالەت %s ئۈچۈن كاندۇك ئۇسلۇبىدا بىر توپچا بار" #: ../src/ui/theme-parser.c:3073 #, c-format msgid "\"%s\" is not a valid value for focus attribute" -msgstr "\"%s\" توغرا بولغان فوكۇس خاسلىق قىممىتى ئەمەس" +msgstr "«%s» توغرا بولغان فوكۇس خاسلىق قىممىتى ئەمەس" #: ../src/ui/theme-parser.c:3082 #, c-format msgid "\"%s\" is not a valid value for state attribute" -msgstr "\"%s\" توغرا بولغان ھالەت خاسلىق قىممىتى ئەمەس" +msgstr "«%s» توغرا بولغان ھالەت خاسلىق قىممىتى ئەمەس" #: ../src/ui/theme-parser.c:3092 #, c-format msgid "A style called \"%s\" has not been defined" -msgstr "\"%s\" دېگەن ئۇسلۇب بېكىتىلمىگەن" +msgstr "«%s» دېگەن ئۇسلۇب بېكىتىلمىگەن" #: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 #, c-format msgid "\"%s\" is not a valid value for resize attribute" -msgstr "\"%s\" توغرا بولغان resize خاسلىق قىممىتى ئەمەس" +msgstr "«%s» توغرا بولغان resize خاسلىق قىممىتى ئەمەس" #: ../src/ui/theme-parser.c:3147 #, c-format msgid "" "Should not have \"resize\" attribute on <%s> element for maximized/shaded " "states" -msgstr "" -"ئەڭ چوڭ ياكى سايىلىك ھالەتكە نىسبەتەن ئېلېمېنت <%s> دا \"resize\" خاسلىقى " -"بولسا بولمايدۇ" +msgstr "ئەڭ چوڭ ياكى سايىلىك ھالەتكە نىسبەتەن ئېلېمېنت <%s> دا «resize» خاسلىقى بولسا بولمايدۇ" #: ../src/ui/theme-parser.c:3161 #, c-format msgid "" "Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "" -"ئەڭ چوڭ ھالەتكە نىسبەتەن ئېلېمېنت <%s> دا \"resize\" خاسلىقى بولسا بولمايدۇ" +msgstr "ئەڭ چوڭ ھالەتكە نىسبەتەن ئېلېمېنت <%s> دا «resize» خاسلىقى بولسا بولمايدۇ" #: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 #, c-format msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "%s ھالىتى، %s چوڭلۇقى، %s فوكۇسى ئۈچۈن ئۇسلۇب بەلگىلەندى" +msgstr "ئۇسلۇب ئاللىقاچان ھالەت %s resize %s فوكۇس %s ئۈچۈن بەلگىلىنىپ بولغان" #: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 #: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 #: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 #, c-format msgid "Style has already been specified for state %s focus %s" -msgstr "%s ھالىتى، %s فوكۇسى ئۈچۈن ئۇسلۇپ بەلگىلەندى" +msgstr "ئۇسلۇب ئاللىقاچان ھالەت %s فوكۇس %s ئۈچۈن بەلگىلىنىپ بولغان" #: ../src/ui/theme-parser.c:3294 msgid "" "Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " "attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"<piece> ئېلېمېنتىدا draw_ops بولسا بولمايدۇ (ئۇسۇلۇپتا draw_ops خاسلىق بىلەن " -"<draw_ops> ئېلېمېنتى كۆرسىتىلگەن، ياكى ئىككى دانە ئېلېمېنت كۆرسىتىلگەن)" +msgstr "<piece> ئېلېمېنتىدا draw_ops بولسا بولمايدۇ (ئۇسۇلۇپتا draw_ops خاسلىق بىلەن <draw_ops> ئېلېمېنتى كۆرسىتىلگەن، ياكى ئىككى دانە ئېلېمېنت كۆرسىتىلگەن)" #: ../src/ui/theme-parser.c:3332 msgid "" "Can't have a two draw_ops for a <button> element (theme specified a draw_ops " "attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"<button> ئېلېمېنتىدا draw_ops بولسا بولمايدۇ (ئۇسۇلۇپتا draw_ops خاسلىق " -"بىلەن <draw_ops> ئېلېمېنتى كۆرسىتىلگەن، ياكى ئىككى دانە ئېلېمېنت " -"كۆرسىتىلگەن)" +msgstr "<button> ئېلېمېنتىدا draw_ops بولسا بولمايدۇ (ئۇسۇلۇپتا draw_ops خاسلىق بىلەن <draw_ops> ئېلېمېنتى كۆرسىتىلگەن، ياكى ئىككى دانە ئېلېمېنت كۆرسىتىلگەن)" #: ../src/ui/theme-parser.c:3370 msgid "" "Can't have a two draw_ops for a <menu_icon> element (theme specified a " "draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"<menu_icon> ئېلېمېنتىدا draw_ops بولسا بولمايدۇ (ئۇسۇلۇپتا draw_ops خاسلىق " -"بىلەن <draw_ops> ئېلېمېنتى كۆرسىتىلگەن، ياكى ئىككى دانە ئېلېمېنت " -"كۆرسىتىلگەن)" +msgstr "<menu_icon> ئېلېمېنتىدا draw_ops بولسا بولمايدۇ (ئۇسۇلۇپتا draw_ops خاسلىق بىلەن <draw_ops> ئېلېمېنتى كۆرسىتىلگەن، ياكى ئىككى دانە ئېلېمېنت كۆرسىتىلگەن)" #: ../src/ui/theme-parser.c:3434 #, c-format @@ -1715,9 +1410,7 @@ msgstr "نەشر بەلگىلىمىسى «%s» توغرا ئەمەس" msgid "" "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" "theme-2.xml" -msgstr "" -"\"version\" خاسلىقىنى metacity-theme-1.xml ياكى metacity-theme-2.xml دا " -"ئىشلەتكىلى بولمايدۇ" +msgstr "\"version\" خاسلىقىنى metacity-theme-1.xml ياكى metacity-theme-2.xml دا ئىشلەتكىلى بولمايدۇ" #: ../src/ui/theme-parser.c:3530 #, c-format @@ -1727,17 +1420,13 @@ msgstr "تېما تەلەپ قىلىدىغان نەشرى %s ئەمما قولل #: ../src/ui/theme-parser.c:3562 #, c-format msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "" -"ئۇسلۇبنىڭ ئەڭ سىرتىدىكى ئېلېمېنت چوقۇم <metacity_theme> بولۇشى كېرەك، <%s> " -"بولسا بولمايدۇ" +msgstr "ئۆرنەكنىڭ ئەڭ سىرتىدىكى ئېلېمېنت چوقۇم <metacity_theme> بولۇشى كېرەك، <%s> بولسا بولمايدۇ" #: ../src/ui/theme-parser.c:3582 #, c-format msgid "" "Element <%s> is not allowed inside a name/author/date/description element" -msgstr "" -"ئېلېمېنت <%s> نى ئېلېمېنت name/author/date/description لارنىڭ ئارىسىدا " -"ئىشلىتىشكە بولمايدۇ" +msgstr "ئېلېمېنت <%s> نى ئېلېمېنت name/author/date/description لارنىڭ ئارىسىدا ئىشلىتىشكە بولمايدۇ" #: ../src/ui/theme-parser.c:3587 #, c-format @@ -1748,16 +1437,12 @@ msgstr "ئېلېمېنت <%s> نى ئېلېمېنت <constant> نىڭ ئارىس #, c-format msgid "" "Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "" -"ئېلېمېنت <%s> نى ئېلېمېنت distance/border/aspect_ratio لارنىڭ ئارىسىدا " -"ئىشلىتىشكە بولمايدۇ" +msgstr "ئېلېمېنت <%s> نى ئېلېمېنت distance/border/aspect_ratio لارنىڭ ئارىسىدا ئىشلىتىشكە بولمايدۇ" #: ../src/ui/theme-parser.c:3621 #, c-format msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "" -"ئېلېمېنت <%s> نى سىزىش مەشغۇلاتى ئېلىپ بارىدىغان ئېلېمېنتنىڭ ئارىسىدا " -"ئىشلىتىشكە بولمايدۇ" +msgstr "ئېلېمېنت <%s> نى سىزىش مەشغۇلاتى ئېلىپ بارىدىغان ئېلېمېنتنىڭ ئارىسىدا ئىشلىتىشكە بولمايدۇ" #: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 #: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 @@ -1771,7 +1456,7 @@ msgstr "كاندۇكقا draw_ops تەمىنلەنمىگەن" #: ../src/ui/theme-parser.c:3914 msgid "No draw_ops provided for button" -msgstr "كۇنۇپكىغا draw_ops تەمىنلەنمىگەن" +msgstr "توپچا ئۈچۈن draw_ops تەمىنلەنمىگەن" #: ../src/ui/theme-parser.c:3968 #, c-format @@ -1783,12 +1468,12 @@ msgstr "ئېلېمېنت <%s> نىڭ ئىچىدە تېكىست بولسا بول #: ../src/ui/theme-parser.c:4074 #, c-format msgid "<%s> specified twice for this theme" -msgstr "<%s> بۇ ئۇسلۇب ئۈچۈن ئىككى قېتىم بەلگىلەنگەن" +msgstr "بۇ ئۆرنەك ئۈچۈن <%s> ئىككى قېتىم بەلگىلەنگەن" -#: ../src/ui/theme-parser.c:4348 +#: ../src/ui/theme-parser.c:4336 #, c-format msgid "Failed to find a valid file for theme %s\n" -msgstr "تېما %s نىڭ ئۈنۈملۈك ھۆججەتلىرىنى تاپالمىدى\n" +msgstr "ئۆرنەك %s ئۈچۈن ئىناۋەتلىك ھۆججەتنى تېپىش مەغلۇپ بولدى\n" #: ../src/ui/theme-viewer.c:99 msgid "_Windows" @@ -1800,7 +1485,7 @@ msgstr "سۆزلەشكۈ(_D)" #: ../src/ui/theme-viewer.c:101 msgid "_Modal dialog" -msgstr "Modal لىق سۆزلەشكۈ(_M)" +msgstr "جاھىل سۆزلەشكۈ(_M)" #: ../src/ui/theme-viewer.c:102 msgid "_Utility" @@ -1808,27 +1493,27 @@ msgstr "قورال(_U)" #: ../src/ui/theme-viewer.c:103 msgid "_Splashscreen" -msgstr "قوزغىلىش ئېكرانى(_S)" +msgstr "باشلىنىش ئېكرانى(_S)" #: ../src/ui/theme-viewer.c:104 msgid "_Top dock" -msgstr "ئۈستىدە توختات(_T)" +msgstr "ئۈستى قونداق(_T)" #: ../src/ui/theme-viewer.c:105 msgid "_Bottom dock" -msgstr "ئاستىدا توختات(_B)" +msgstr "ئاستى قونداق(_B)" #: ../src/ui/theme-viewer.c:106 msgid "_Left dock" -msgstr "سولدا توختات(_L)" +msgstr "سول قونداق(_L)" #: ../src/ui/theme-viewer.c:107 msgid "_Right dock" -msgstr "ئوڭغا توختات(_R)" +msgstr "ئوڭ قونداق(_R)" #: ../src/ui/theme-viewer.c:108 msgid "_All docks" -msgstr "ھەممە توختاش نۇقتىسى(_A)" +msgstr "بارلىق قونداق(_A)" #: ../src/ui/theme-viewer.c:109 msgid "Des_ktop" @@ -1836,158 +1521,403 @@ msgstr "ئۈستەلئۈستى(_K)" #: ../src/ui/theme-viewer.c:115 msgid "Open another one of these windows" -msgstr "بۇ كۆزنەكلەرنىڭ ئىچىدىكى بىرەرىنى ئاچىدۇ" +msgstr "بۇ كۆزنەكلەردىكى باشقا بىرىنى ئېچىش" #: ../src/ui/theme-viewer.c:117 msgid "This is a demo button with an 'open' icon" -msgstr "بۇ 'ئاچ' سىنبەلگىسى بار ئۈلگە(demo) توپچىسى" +msgstr "بۇ مەشىق كۇنۇپكىسى، «ئېچىش» سىنبەلگىسى بار" #: ../src/ui/theme-viewer.c:119 msgid "This is a demo button with a 'quit' icon" -msgstr "بۇ 'ئاخىرلاشتۇر' سىنبەلگىسى بار ئۈلگە(demo) توپچىسى" +msgstr "بۇ مەشىق كۇنۇپكىسى، «چېكىنىش» سىنبەلگىسى بار" -#: ../src/ui/theme-viewer.c:253 +#: ../src/ui/theme-viewer.c:248 msgid "This is a sample message in a sample dialog" msgstr "بۇ ئۈلگە سۆزلەشكۈسىدىكى مىسال ئۇچۇرى" -#: ../src/ui/theme-viewer.c:336 +#: ../src/ui/theme-viewer.c:328 #, c-format msgid "Fake menu item %d\n" msgstr "مەۋھۇم تىزىملىك تۈرى %d\n" -#: ../src/ui/theme-viewer.c:371 +#: ../src/ui/theme-viewer.c:363 msgid "Border-only window" msgstr "گىرۋەكلىك كۆزنەك" -#: ../src/ui/theme-viewer.c:373 +#: ../src/ui/theme-viewer.c:365 msgid "Bar" msgstr "تۈۋرۈكسىمان دىئاگرامما" -#: ../src/ui/theme-viewer.c:390 +#: ../src/ui/theme-viewer.c:382 msgid "Normal Application Window" msgstr "ئادەتتىكى پروگرامما كۆزنىكى" -#: ../src/ui/theme-viewer.c:394 +#: ../src/ui/theme-viewer.c:386 msgid "Dialog Box" -msgstr "سۆزلەشكۈ كۆزنەكچىسى" +msgstr "سۆزلەشكۈ رامكىسى" -#: ../src/ui/theme-viewer.c:398 +#: ../src/ui/theme-viewer.c:390 msgid "Modal Dialog Box" -msgstr "ھالەت سۆزلەشكۈ رامكىسى" +msgstr "ھالەت سۆزلەشكۈ كۆزنەكچىسى" -#: ../src/ui/theme-viewer.c:402 +#: ../src/ui/theme-viewer.c:394 msgid "Utility Palette" -msgstr "قورال كۇنۇپكىسى" +msgstr "قورال كۆزنەكچە" -#: ../src/ui/theme-viewer.c:406 +#: ../src/ui/theme-viewer.c:398 msgid "Torn-off Menu" -msgstr "بۆلىۋالغان تىزىملىك" +msgstr "يىرتىلغان تىزىملىك" -#: ../src/ui/theme-viewer.c:410 +#: ../src/ui/theme-viewer.c:402 msgid "Border" msgstr "گىرۋەك" -#: ../src/ui/theme-viewer.c:414 +#: ../src/ui/theme-viewer.c:406 msgid "Attached Modal Dialog" msgstr "قوشۇلغان Modal سۆزلەشكۈ" -#: ../src/ui/theme-viewer.c:747 +#: ../src/ui/theme-viewer.c:737 #, c-format msgid "Button layout test %d" -msgstr "كۇنۇپكا ئورۇنلاشتۇرۇلۇشىنى سىناش %d" +msgstr "توپچا ئورۇنلاشتۇرۇلۇشىنى سىناش %d" -#: ../src/ui/theme-viewer.c:776 +#: ../src/ui/theme-viewer.c:766 #, c-format msgid "%g milliseconds to draw one window frame" -msgstr "%g مىللىسېكۇنت(بىر كۆزنەك كاندۇكىنى سىزىشقا كەتكەن ۋاقىت)" +msgstr "بىر كۆزنەك كاندۇكىنى سىزىشقا كەتكەن ۋاقىت %g مىللىسېكۇنت" -#: ../src/ui/theme-viewer.c:821 +#: ../src/ui/theme-viewer.c:811 #, c-format msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "ئىشلىتىش ئۇسۇلى: metacity-theme-viewer [ئۇسلۇب ئاتى]\n" +msgstr "ئىشلىتىش ئۇسۇلى: metacity-theme-viewer [ئۆرنەك ئاتى]\n" -#: ../src/ui/theme-viewer.c:828 +#: ../src/ui/theme-viewer.c:818 #, c-format msgid "Error loading theme: %s\n" -msgstr "تېما قاچىلاشتا خاتالىق كۆرۈلدى:%s\n" +msgstr "ئۆرنەك ئوقۇشتا خاتالىق كۆرۈلدى: %s\n" -#: ../src/ui/theme-viewer.c:834 +#: ../src/ui/theme-viewer.c:824 #, c-format msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "\"%s\" دېگەن ئۇسلۇبنى %g سېكۇنتتا ئوقۇدى\n" +msgstr "«%s» دېگەن ئۆرنەكنى %g سېكۇنتتا ئوقۇدى\n" -#: ../src/ui/theme-viewer.c:878 +#: ../src/ui/theme-viewer.c:869 msgid "Normal Title Font" msgstr "ئادەتتىكى ماۋزۇ خەت نۇسخىسى" -#: ../src/ui/theme-viewer.c:884 +#: ../src/ui/theme-viewer.c:875 msgid "Small Title Font" msgstr "تارماق ماۋزۇ خەت نۇسخىسى" -#: ../src/ui/theme-viewer.c:890 +#: ../src/ui/theme-viewer.c:881 msgid "Large Title Font" msgstr "ماۋزۇ خەت نۇسخىسى" -#: ../src/ui/theme-viewer.c:895 +#: ../src/ui/theme-viewer.c:886 msgid "Button Layouts" -msgstr "كۇنۇپكا ئورۇنلاشتۇرۇلۇشى" +msgstr "توپچا جايلاشتۇرۇشلىرى" -#: ../src/ui/theme-viewer.c:900 +#: ../src/ui/theme-viewer.c:891 msgid "Benchmark" -msgstr "ئاساسىي ئۆلچەم" +msgstr "ئاساسىي كۆرسەتكۈچ" -#: ../src/ui/theme-viewer.c:952 +#: ../src/ui/theme-viewer.c:947 msgid "Window Title Goes Here" msgstr "بۇ يەردە كۆزنەك ماۋزۇسى كۆرسىتىلىدۇ" -#: ../src/ui/theme-viewer.c:1055 +#: ../src/ui/theme-viewer.c:1053 #, c-format msgid "" "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " "seconds wall clock time including X server resources (%g milliseconds per " "frame)\n" -msgstr "" -"%2$g دىكى خېرىدار تەرەپ سېكۇنت (ھەر كاندۇك %3$g مىللىسېكۇنت) ۋە X " -"مۇلازىمېتىر مەنبەسى ئىچىدىكى %4$g سېكۇنت ۋاقىت (ھەر بىر كاندۇك %5$g " -"مىللىسېكۇنت) ئىچىدە %1$d كاندۇك سىزىدۇ\n" +msgstr "%d دانە كاندۇك خېرىدار تەرەپتە %g سېكۇنتتا سىزىلدى(بىر كاندۇك ئۈچۈن %g مىللىسېكۇنت). ئەمەلىيەتتە X مۇلازىمېتىرىنىڭ مەنبەلىرىنىمۇ قوشۇپ %g سېكۇنت(بىر كاندۇكنى %g مىللىسېكۇنت) ۋاقىتتا سىزدى.\n" -#: ../src/ui/theme-viewer.c:1274 +#: ../src/ui/theme-viewer.c:1273 msgid "position expression test returned TRUE but set error" msgstr "ئورۇن ئىپادىسىنى سىناشتا TRUE قايتتى بىراق خاتالىق كۆرۈلدى" -#: ../src/ui/theme-viewer.c:1276 +#: ../src/ui/theme-viewer.c:1275 msgid "position expression test returned FALSE but didn't set error" msgstr "ئورۇن ئىپادىسىنى سىناشتا FALSE قايتتى بىراق خاتالىق كۆرۈلمىدى" -#: ../src/ui/theme-viewer.c:1280 +#: ../src/ui/theme-viewer.c:1279 msgid "Error was expected but none given" msgstr "خاتالىق چىقىدىغان يەردە خاتالىق چىقمىدى" -#: ../src/ui/theme-viewer.c:1282 +#: ../src/ui/theme-viewer.c:1281 #, c-format msgid "Error %d was expected but %d given" msgstr "خاتالىق %d چىقىدىغان يەردە %d چىقتى" -#: ../src/ui/theme-viewer.c:1288 +#: ../src/ui/theme-viewer.c:1287 #, c-format msgid "Error not expected but one was returned: %s" msgstr "خاتالىق چىقمايدىغان يەردە بىر خاتالىق چىقىپ قالدى: %s" -#: ../src/ui/theme-viewer.c:1292 +#: ../src/ui/theme-viewer.c:1291 #, c-format msgid "x value was %d, %d was expected" msgstr "x نىڭ قىممىتى %d ئىكەن، ئەسلى %d بولسا بولاتتى" -#: ../src/ui/theme-viewer.c:1295 +#: ../src/ui/theme-viewer.c:1294 #, c-format msgid "y value was %d, %d was expected" msgstr "y نىڭ قىممىتى %d ئىكەن، ئەسلى %d بولسا بولاتتى" -#: ../src/ui/theme-viewer.c:1360 +#: ../src/ui/theme-viewer.c:1359 #, c-format msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "" -"%d كوئوردېنات ئىپادىسى %g سېكۇنتتا تەھلىل قىلىندى(%g ئوتتۇرىچە سېكۇنت)\n" +msgstr "%d كوئوردېنات ئىپادىسى %g سېكۇنتتا تەھلىل قىلىندى(%g ئوتتۇرىچە سېكۇنت)\n" + +#~ msgid "Switch to workspace 5" +#~ msgstr "5-خىزمەت رايونىغا ئالماش" + +#~ msgid "Switch to workspace 6" +#~ msgstr "6-خىزمەت رايونىغا ئالماش" + +#~ msgid "Switch to workspace 7" +#~ msgstr "7-خىزمەت رايونىغا ئالماش" + +#~ msgid "Switch to workspace 8" +#~ msgstr "8-خىزمەت رايونىغا ئالماش" + +#~ msgid "Switch to workspace 9" +#~ msgstr "9-خىزمەت رايونىغا ئالماش" + +#~ msgid "Switch to workspace 10" +#~ msgstr "10-خىزمەت رايونىغا ئالماش" + +#~ msgid "Switch to workspace 11" +#~ msgstr "11- خىزمەت رايونىغا ئالماش" + +#~ msgid "Switch to workspace 12" +#~ msgstr "12- خىزمەت رايونىغا ئالماش" + +#~ msgid "Switch to workspace on the left of the current workspace" +#~ msgstr "سولدىكى خىزمەت رايونىغا ئالمىشىدۇ" + +#~ msgid "Switch to workspace on the right of the current workspace" +#~ msgstr "ئوڭدىكى خىزمەت مۇھىتىغا ئالمىشىدۇ" + +#~ msgid "Switch to workspace above the current workspace" +#~ msgstr "ئۇستىكى خىزمەت مۇھىتىغا ئالمىشىدۇ" + +#~ msgid "Switch to workspace below the current workspace" +#~ msgstr "ئاستىدىكى خىزمەت مۇھىتىغا ئالمىشىدۇ" + +#~ msgid "Move between windows of an application, using a popup window" +#~ msgstr "" +#~ "قوللىنىشچان پروگرامما كۆزنىكى ئارىسىدا يۆتكىلىپ، قاڭقىش كۆزنىكى ئىشلىتىدۇ" + +#~ msgid "" +#~ "Move backward between windows of an application, using a popup window" +#~ msgstr "" +#~ "قوللىنىشچان پروگرامما كۆزنىكى ئارىسىدا ئەكسىچە يۆتكىلىپ، قاڭقىش كۆزنىكى " +#~ "ئىشلىتىدۇ" + +#~ msgid "Move between windows, using a popup window" +#~ msgstr "كۆزنەك ئارىسىدا يۆتكىلىپ، قاڭقىش كۆزنىكى ئىشلىتىدۇ" + +#~ msgid "Move backward between windows, using a popup window" +#~ msgstr "كۆزنەك ئارىسىدا ئەكسىچە يۆتكىلىپ، قاڭقىش كۆزنىكى ئىشلىتىدۇ" + +#~ msgid "Move between panels and the desktop, using a popup window" +#~ msgstr "تاختا ۋە ئۈستەلئۈستى ئارىسىدا يۆتكىلىپ، قاڭقىش كۆزنىكى ئىشلىتىدۇ" + +#~ msgid "Move backward between panels and the desktop, using a popup window" +#~ msgstr "" +#~ "تاختا ۋە ئۈستەلئۈستى ئارىسىدا ئەكسىچە يۆتكىلىپ، قاڭقىش كۆزنىكى ئىشلىتىدۇ" + +#~ msgid "Move backward between windows of an application immediately" +#~ msgstr "" +#~ "قوللىنىشچان پروگراممىنىڭ كۆزنىكى ئارىسىدا ئەكسىچە دەرھال تەتۈر يۆتكىلىدۇ" + +#~ msgid "Move between windows immediately" +#~ msgstr "كۆزنەك ئارىسىدا دەرھال يۆتكىلىدۇ" + +#~ msgid "Move backward between windows immediately" +#~ msgstr "كۆزنەك ئارىسىدا ئەكسىچە دەرھال يۆتكىلىدۇ" + +#~ msgid "Move between panels and the desktop immediately" +#~ msgstr "تاختايلار ۋە ئۈستەلئۈستى ئارىسىدا دەرھال يۆتكىلىش" + +#~ msgid "Move backward between panels and the desktop immediately" +#~ msgstr "تاختايلار ۋە ئۈستەلئۈستى ئارىسىدا دەرھال تەتۈر يۆتكىلىش" + +#~ msgid "Show the panel's \"Run Application\" dialog box" +#~ msgstr "تاختاينىڭ «پروگرامما ئىجرا قىل» سۆزلەشكۈسىنى كۆرسىتىدۇ" + +#~ msgid "Start or stop recording the session" +#~ msgstr "مەزكۇر ئەڭگىمەنى خاتىرىلەشنى توختىتىدۇ ياكى باشلايدۇ" + +#~ msgid "Take a screenshot" +#~ msgstr "ئېكران كەسمىسى تۇت" + +#~ msgid "Take a screenshot of a window" +#~ msgstr "كۆزنەكنىڭ كۆرۈنۈشىنى رەسىمگە ئالىدۇ" + +#~ msgid "Run a terminal" +#~ msgstr "تېرمىنالنى ئىجرا قىل" + +#~ msgid "Toggle whether a window will always be visible over other windows" +#~ msgstr "" +#~ "كۆزنەك ھەمىشە باشقا ھەممە كۆزنەكلەرنىڭ ئۈستىدە تۇرۇشنى ئالماشتۇرامدۇ يوق" + +#~ msgid "Minimize window" +#~ msgstr "كۆزنەكنى كىچىكلەت" + +#~ msgid "Move window to workspace 5" +#~ msgstr "كۆزنەكنى 5-خىزمەت رايونىغا يۆتكە" + +#~ msgid "Move window to workspace 6" +#~ msgstr "كۆزنەكنى 6-خىزمەت رايونىغا يۆتكە" + +#~ msgid "Move window to workspace 7" +#~ msgstr "كۆزنەكنى 7-خىزمەت رايونىغا يۆتكە" + +#~ msgid "Move window to workspace 8" +#~ msgstr "كۆزنەكنى 8-خىزمەت رايونىغا يۆتكە" + +#~ msgid "Move window to workspace 9" +#~ msgstr "كۆزنەكنى 9-خىزمەت رايونىغا يۆتكە" + +#~ msgid "Move window to workspace 10" +#~ msgstr "كۆزنەكنى 10-خىزمەت رايونىغا يۆتكە" + +#~ msgid "Move window to workspace 11" +#~ msgstr "كۆزنەكنى 11- خىزمەت رايونىغا يۆتكە" + +#~ msgid "Move window to workspace 12" +#~ msgstr "كۆزنەكنى 12- خىزمەت رايونىغا يۆتكە" + +#~ msgid "Move window to north-west (top left) corner" +#~ msgstr "كۆزنەكنى ئېكراننىڭ غەربى-شىمالى(سول يۇقىرى)غا يۆتكە" + +#~ msgid "Move window to north-east (top right) corner" +#~ msgstr "كۆزنەكنى ئېكراننىڭ شەرقى-شىمالى(ئوڭ يۇقىرى)غا يۆتكە" + +#~ msgid "Move window to south-west (bottom left) corner" +#~ msgstr "كۆزنەكنى ئېكراننىڭ غەربى-جەنۇبى(سول پەسكە)غا يۆتكە" + +#~ msgid "Move window to south-east (bottom right) corner" +#~ msgstr "كۆزنەكنى ئېكراننىڭ غەربى-شىمالى(سول يۇقىرى)غا يۆتكە" + +#~ msgid "Move window to north (top) side of screen" +#~ msgstr "كۆزنەكنى ئېكراننىڭ شىمالى(ئۇستى)غا يۆتكە" + +#~ msgid "Move window to south (bottom) side of screen" +#~ msgstr "كۆزنەكنى ئېكراننىڭ جەنۇبى(ئاستى)غا يۆتكە" + +#~ msgid "Move window to east (right) side of screen" +#~ msgstr "كۆزنەكنى ئېكراننىڭ شەرقى(ئوڭ تەرەپ)گە يۆتكە" + +#~ msgid "Move window to west (left) side of screen" +#~ msgstr "كۆزنەكنى ئېكراننىڭ غەربى(سول تەرەپ)گە يۆتكە" + +#~ msgid "Move window to center of screen" +#~ msgstr "كۆزنەكنى ئېكراننىڭ مەركىزىگە يۆتكەيدۇ" + +#~ msgid "" +#~ "There was an error running <tt>%s</tt>:\n" +#~ "\n" +#~ "%s" +#~ msgstr "" +#~ "<tt>%s</tt> نى ئىجرا قىلىۋاتقاندا خاتالىق كۆرۈلدى:\n" +#~ "\n" +#~ "%s" + +#~ msgid "No command %d has been defined.\n" +#~ msgstr "بۇيرۇق %d بېكىتىلمىگەن.\n" + +#~ msgid "No terminal command has been defined.\n" +#~ msgstr "تېرمىنال بۇيرۇققا ئېنىقلىما بېرىلمىگەن .\n" + +#~ msgid "Comma-separated list of compositor plugins" +#~ msgstr "پەش بىلەن ئايرىلغان تىزىم ۋە بىرىكمە رەڭلىگۈچ قىستۇرمىلىرى" + +#~ msgid "GConf key '%s' is set to an invalid value\n" +#~ msgstr "" +#~ "GConf نىڭ ئاچقۇچ سۆزى“%s” ئۈنۈمسىز \n" +#~ " قىلىپ تەڭشەلگەن\n" + +#~ msgid "%d stored in GConf key %s is out of range %d to %d\n" +#~ msgstr "" +#~ "GConf نىڭ %2$s ئاچقۇچىنىڭ قىممىتى %1$d نىڭ دائىرىسى %3$d〜%4$d نىڭ " +#~ "ئىچىدە ئەمەس\n" + +#~ msgid "GConf key \"%s\" is set to an invalid type\n" +#~ msgstr "" +#~ "GConf نىڭ ئاچقۇچلۇق سۆزى “%s” ئۈنۈمسىز تىپتىكى \n" +#~ " قىلىپ تەڭشەلگەن\n" + +#~ msgid "GConf key %s is already in use and can't be used to override %s\n" +#~ msgstr "" +#~ "GConf ئاچقۇچى %s ئىشلىتىلىۋاتىدۇ، شۇڭا %s نى قاپلاشقا ئىشلەتكىلى " +#~ "بولمايدۇ\n" + +#~ msgid "Can't override GConf key, %s not found\n" +#~ msgstr "GConf ئاچقۇچىنى قاپلىغىلى بولمىدى، %s تېپىلمىدى\n" + +#~ msgid "Error setting number of workspaces to %d: %s\n" +#~ msgstr "خىزمەت رايونى سانىنى %d قىلىپ تەڭشەشتە كۆرۈلگەن خاتالىق :%s\n" + +#~ msgid "Error setting name for workspace %d to \"%s\": %s\n" +#~ msgstr "" +#~ "خىزمەت مۇھىتى %d غا \"%s\" دەپ ئائىت قويۇشتا خاتالىق كۆرۈلدى: %s\n" + +#~ msgid "Error setting live hidden windows status status: %s\n" +#~ msgstr "" +#~ "شۇئان يوشۇرۇنىدىغان كۆزنەك ھالىتىنى تەڭشەۋاتقاندا خاتالىق كۆرۈلدى: %s\n" + +#~ msgid "Error setting no tab popup status: %s\n" +#~ msgstr "بەتكۈچ يوق قاڭقىش ھالىتىنى تەڭشەۋاتقاندا خاتالىق كۆرۈلدى: %s\n" + +#~ msgid "" +#~ "Determines whether hidden windows (i.e., minimized windows and windows on " +#~ "other workspaces than the current one) should be kept alive." +#~ msgstr "" +#~ "يوشۇرۇن كۆزنەك (مەسىلەن، كىچىكلىتىلگەن ۋە باشقا خىزمەت رايونىدىكى كۆزنەك)" +#~ "نىڭ ھالىتىنى ساقلاش ياكى ساقلىماسلىقنى جەزملەيدۇ." + +#~ msgid "Live Hidden Windows" +#~ msgstr "شۇئان يوشۇرۇنىدىغان كۆزنەكلەر" + +#~ msgid "Close Window" +#~ msgstr "كۆزنەك ياپ" + +#~ msgid "Window Menu" +#~ msgstr "كۆزنەك تىزىملىكى" + +#~ msgid "Minimize Window" +#~ msgstr "كۆزنەكنى كىچىكلەت" + +#~ msgid "Maximize Window" +#~ msgstr "كۆزنەكنى چوڭايت" + +#~ msgid "Restore Window" +#~ msgstr "كۆزنەكنى ئەسلىگە كەلتۈر" + +#~ msgid "Roll Up Window" +#~ msgstr "كۆزنەكنى تۈر" + +#~ msgid "Unroll Window" +#~ msgstr "كۆزنەكنى تۈرمە" + +#~ msgid "Keep Window On Top" +#~ msgstr "كۆزنەكنى چوققىلاشنى ساقلا" + +#~ msgid "Always On Visible Workspace" +#~ msgstr "خىزمەت رايونىدا ئىزچىل كۆرۈنسۇن" + +#~ msgid "Put Window On Only One Workspace" +#~ msgstr "بىر خىزمەت رايونىغا ئورۇنلاشتۇرۇش" + +#~ msgid "Launchers" +#~ msgstr "ئىجراچىلار" + +#~ msgid "Screenshots" +#~ msgstr "ئېكران كۆرۈنۈشلىرى" #~ msgid "Failed to retrieve color %s[%s] from GTK+ theme.\n" #~ msgstr "GTK+ ئۆرنەكتىن رەڭ %s[%s] نى ئىزدىيەلمىدى\n" diff --git a/po/uk.po b/po/uk.po index ae9a0459a..25cf4a9ae 100644 --- a/po/uk.po +++ b/po/uk.po @@ -1,412 +1,280 @@ # Copyright (C) 2001 Free Software Foundation, Inc. # Yuriy Syrota <rasta@renome.rovno.ua>, 2001, 2002. -# Maxim Dziumanenko <dziumanenko@gmail.com>, 2004-2008 -# Korostil Daniel <ted.korostiled@gmail.com>, 2011, 2012. +# Maxim Dziumanenko <dziumanenko@gmail.com>, 2004-2008. +# Daniel Korostil <ted.korostiled@gmail.com>, 2014, 2015. +# Yuri Chornoivan <yurchor@ukr.net>, 2020. msgid "" msgstr "" "Project-Id-Version: metacity\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-03-18 17:38+0200\n" -"PO-Revision-Date: 2012-03-18 17:42+0300\n" -"Last-Translator: Korostil Daniel <ted.korostiled@gmail.com>\n" -"Language-Team: translation@linux.org.ua\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2020-02-23 17:41+0000\n" +"PO-Revision-Date: 2020-03-03 19:30+0200\n" +"Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n" +"Language-Team: Ukrainian <kde-i18n-uk@kde.org>\n" "Language: uk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%" -"10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -"X-Generator: Virtaal 0.7.1\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<" +"=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Lokalize 20.03.70\n" +"X-Project-Style: gnome\n" -#: ../src/50-muffin-windows.xml.in.h:1 -msgid "Windows" -msgstr "Вікна" - -#: ../src/50-muffin-windows.xml.in.h:2 -msgid "View split on left" -msgstr "Перегляд розділити ліворуч" - -#: ../src/50-muffin-windows.xml.in.h:3 -msgid "View split on right" -msgstr "Перегляд розділити праворуч" - -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format -msgid "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." -msgstr "Уже запущено інший композитний менеджер на екрані %i через показ «%s»." - -#: ../src/core/bell.c:307 -msgid "Bell event" -msgstr "Подія гудка" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Навігація" -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Запит інформації невідомого вікна: %d" +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Перемістити вікно на робочий простір 1" -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> не відповідає." +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Перемістити вікно на робочий простір 2" -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "Програма не відповідає." +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Перемістити вікно на робочий простір 3" -#: ../src/core/delete.c:119 -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "" -"Можете трошки зачекати відновлення активності або примусово закрити програму." +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Перемістити вікно на робочий простір 4" -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "_Зачекати" +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Перемістити вікно на останній робочий простір" -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "_Завершити примусово" +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "Перемістити вікно на робочий простір вище" -#: ../src/core/display.c:387 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "Нема розширення %s, яке потрібне для композитного режиму" +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "Перемістити вікно на робочий простір нижче" -#: ../src/core/display.c:453 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Не вдалось відкрити дисплей віконної системи X «%s»\n" +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "Перемістити вікно на монітор ліворуч" -#: ../src/core/keybindings.c:852 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "Клавішу «%s» з модифікаторами «%x» вже використовує інша програма\n" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "Перемістити вікно на монітор праворуч" -#: ../src/core/main.c:206 -msgid "Disable connection to session manager" -msgstr "Вимкнути з'єднання з менеджером сеансу" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "Перемістити вікно на монітор вище" -#: ../src/core/main.c:212 -msgid "Replace the running window manager" -msgstr "Замінити запущений віконний менеджер" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "Перемістити вікно на монітор нижче" -#: ../src/core/main.c:218 -msgid "Specify session management ID" -msgstr "Вказати ідентифікатор сеансу" +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "Перемкнути програми" -#: ../src/core/main.c:223 -msgid "X Display to use" -msgstr "Дисплей X" +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "Перемкнути до попередньої програми" -#: ../src/core/main.c:229 -msgid "Initialize session from savefile" -msgstr "Розпочати сеанс зі збереженого файла" +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "Перемкнути вікна" -#: ../src/core/main.c:235 -msgid "Make X calls synchronous" -msgstr "Зробити виклики X синхронними" +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "Перемкнути до попереднього вікна" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Помилка зчитування каталогу тем: %s\n" +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "Перемкнути вікна програм" -#: ../src/core/main.c:520 -#, c-format -msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "" -"Не вдалось знайти тему! Перевірте, чи існує %s та чи містить він звичайну " -"тему.\n" +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "Перемкнути до попереднього вікна програми" -#: ../src/core/muffin.c:40 -#, c-format -msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" -"Muffin %s\n" -"© 2001-%d Havoc Pennington, Red Hat, Inc., та інші\n" -"Це — вільне програмний засіб; умови копіювання дивіться в коді програми.\n" -"Не надається НІЯКИХ гарантій; навіть ПРИДАТНОСТІ ДЛЯ ПРОДАЖУ чи " -"ВІДПОВІДНОСТІ ПЕВНІЙ МЕТІ.\n" +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "Перемкнути системні керування" -#: ../src/core/muffin.c:54 -msgid "Print version" -msgstr "Показати версію" +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "Перемкнути до переднього системного керування" -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "Список композитних додатків розділених комою" +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "Перемкнути вікна напряму" -#: ../src/core/prefs.c:1077 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"Обхід для роботи із зіпсованими програмами вимкнено. Деякі додатки можуть " -"працювати некоректно.\n" +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "Перемкнути напряму до попереднього вікна" -#: ../src/core/prefs.c:1152 -#, c-format -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "Неможливо проаналізувати опис шрифту «%s» у ключі GSettings %s\n" +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "Перемкнути вікна програм напряму" -#: ../src/core/prefs.c:1218 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"У базі даних налаштування знайдено «%s» — що не є правильним значенням " -"модифікатора клавіші миші.\n" +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "Перемкнути напряму до попереднього вікна програми" -#: ../src/core/prefs.c:1739 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "" -"Знайдене у базі даних налаштування значення «%s» не є правильним записом " -"прив'язки клавіш «%s»\n" +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "Перемкнути системні керування напряму" -#: ../src/core/prefs.c:1836 -#, c-format -msgid "Workspace %d" -msgstr "Робочий простір %d" +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "Перемкнути напряму до переднього системного керування" -#: ../src/core/screen.c:730 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "Екран %d на дисплеї «%s» не правильний\n" +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "Сховати всі звичайні вікна" -#: ../src/core/screen.c:746 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"Екран %d на дисплеї «%s» вже має менеджера вікон; спробуйте вказати параметр " -"--replace, щоб замінити поточний менеджер вікон.\n" +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "Перейти до робочого простору 1" -#: ../src/core/screen.c:773 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "" -"Не вдалось одержати функцію виділення менеджеру вікон на екрані %d дисплею " -"«%s»\n" +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "Перейти до робочого простору 2" -#: ../src/core/screen.c:828 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "Екран %d на дисплеї «%s» вже має менеджера вікон\n" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "Перейти до робочого простору 3" -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "Не вдалось відпустити екран %d на дисплеї «%s»\n" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "Перейти до робочого простору 4" -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Не вдалось створити каталог «%s»: %s\n" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "Перейти до останнього робочого простору" -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "Не вдалось відкрити для запису файл сеансу «%s»: %s\n" +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "Перейти до робочого простору вище" -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Помилка запису файла сеансу \"%s\": %s\n" +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "Перейти до робочого простору знизу" -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Помилка закриття файла сеансу «%s»: %s\n" +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "Система" -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Збій аналізування збереженого файла сеансу: %s\n" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Показати запуск командного рядка" -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "Прочитано атрибут <muffin_session>, але вже є ідентифікатор сеансу" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Показати огляд активності" -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Невідомий атрибут %s у елементі <%s>" +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Відновити клавіатурні скорочення" -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "вкладена мітка <window>" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Вікна" -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "Невідомий елемент %s" +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "Активувати меню вікна" -#: ../src/core/session.c:1809 -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" -"Ці вікна не підтримують "збереження поточних параметрів" і при " -"наступному входженні їх треба запустити власноруч." +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Перемикання повноекранного режиму" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Збій відкриття журналу зневадження: %s\n" +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "Перемкнути стан розгортання вікна на весь екран" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Збій виконання fdopen() для журналу %s: %s\n" +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "Розгорнути вікно" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "Відкрито журнал %s\n" +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Відновити вікно" -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "Muffin зібрано без підтримки докладного режиму\n" +#: data/50-mutter-windows.xml:18 +msgid "Close window" +msgstr "Закрити вікно" -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "Віконний менеджер:" +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "Сховати вікно" -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "Вада у віконному менеджері:" +#: data/50-mutter-windows.xml:22 +msgid "Move window" +msgstr "Перемістити вікно" -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "Попередження віконного менеджера:" +#: data/50-mutter-windows.xml:24 +msgid "Resize window" +msgstr "Змінити розміри вікна" -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "Помилка віконного менеджера:" +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "Перемикання вікна на всі робочі простори або один" -#. first time through -#: ../src/core/window.c:7266 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"Вікно %s встановило значення SM_CLIENT_ID на себе, замість вікна зі " -"значенням WM_CLIENT_LEADER, як це вказано в ICCCM.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7931 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size " -"%d x %d and max size %d x %d; this doesn't make much sense.\n" +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" msgstr "" -"Вікно %s встановило підказку MWM, яка вказує, що його розмір не може " -"змінюватись, але встановило мінімальний розмір %d x %d та максимальний %d x " -"%d;, в чому не має сенсу.\n" - -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "Програма встановила неправильне значення параметра _NET_WM_PID %lu\n" +"Підняти вікно на передній план, якщо воно прикрите іншим, інакше опустити " -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (на %s)" +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "Підняти вікно над іншими" -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "Неправильний параметр WM_TRANSIENT_FOR вікна 0x%lx вказано для %s.\n" +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "Перемістити вікна нижче усіх вікон" -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "Вікно WM_TRANSIENT_FOR 0x%lx для %s створило б петлю.\n" +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "Розгорнути вікно на весь екран вертикально" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"Вікно 0x%lx має властивість %s,\n" -"тип якої очікувався %s у форматі %d\n" -"але насправді має тип %s формат %d n_items %d.\n" -"Найімовірніше, це вада програми, а не менеджера вікон.\n" -"Вікно має title=\"%s\" class=\"%s\" name=\"%s\"\n" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "Розгорнути вікно на весь екран горизонтально" -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "Властивість %s вікна 0x%lx містить неправильний UTF-8\n" +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "Перегляд розділити ліворуч" -#: ../src/core/xprops.c:494 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"Властивість %s вікна 0x%lx містить неправильний UTF-8 у пункті %d списку\n" +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "Перегляд розділити праворуч" -#: ../src/muffin.desktop.in.h:1 ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 +#: data/org.gnome.mutter.gschema.xml.in:7 msgid "Modifier to use for extended window management operations" msgstr "" "Модифікатор, що використовується для розширених дій віконного менеджера" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 +#: data/org.gnome.mutter.gschema.xml.in:8 +#| msgid "" +#| "This key will initiate the \"overlay\", which is a combination window " +#| "overview and application launching system. The default is intended to be " +#| "the \"Windows key\" on PC hardware. It's expected that this binding " +#| "either the default or set to the empty string." msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." msgstr "" "Ця клавіша ініціює «накладання», яке є поєднанням огляду вікон і системою " "запуску програм. Типово на це призначено клавішу «Win» в обладнанні. " "Очікується, що це буде прив'язка або типова, або порожній рядок." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 +#: data/org.gnome.mutter.gschema.xml.in:20 msgid "Attach modal dialogs" msgstr "Долучити модальні вікна" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 +#: data/org.gnome.mutter.gschema.xml.in:21 msgid "" "When true, instead of having independent titlebars, modal dialogs appear " "attached to the titlebar of the parent window and are moved together with " @@ -416,23 +284,11 @@ msgstr "" "долучено до батьківського вікна заголовка і пересунуто разом з батьківських " "вікном." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -msgid "Live Hidden Windows" -msgstr "Активувати сховані вікна" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"Визначає, чи сховані вікна (наприклад, згорнуті вікна та вікна на інших " -"робочих просторах) слід утримувати активними." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 +#: data/org.gnome.mutter.gschema.xml.in:30 msgid "Enable edge tiling when dropping windows on screen edges" msgstr "Увімкнути розбиття країв, коли кладуться вікна на краї екрана" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 +#: data/org.gnome.mutter.gschema.xml.in:31 msgid "" "If enabled, dropping windows on vertical screen edges maximizes them " "vertically and resizes them horizontally to cover half of the available " @@ -442,25 +298,29 @@ msgstr "" "змінить їхній розмір горизонтально, щоб покрити половину доступної ділянки. " "Перекидання вікон на верхівку екрана розгорне їх повністю." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 +#: data/org.gnome.mutter.gschema.xml.in:40 msgid "Workspaces are managed dynamically" msgstr "Робочі простори організовуються динамічно" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 +#: data/org.gnome.mutter.gschema.xml.in:41 +#| msgid "" +#| "Determines whether workspaces are managed dynamically or whether there's " +#| "a static number of workspaces (determined by the num-workspaces key in " +#| "org.gnome.desktop.wm.preferences)." msgid "" -"Determines whether workspaces are managed dynamically or whether there's a " +"Determines whether workspaces are managed dynamically or whether there’s a " "static number of workspaces (determined by the num-workspaces key in org." "gnome.desktop.wm.preferences)." msgstr "" "Визначає, чи робочі простори керуються динамічно, чи є певна статична " -"кількість просторів (визначено ключем num-workspaces у " -"org.cinnamon.desktop.wm.preferences)." +"кількість просторів (визначено ключем num-workspaces у org.gnome.desktop.wm." +"preferences)." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 +#: data/org.gnome.mutter.gschema.xml.in:50 msgid "Workspaces only on primary" msgstr "Робочий простір лише на первинному" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 +#: data/org.gnome.mutter.gschema.xml.in:51 msgid "" "Determines whether workspace switching should happen for windows on all " "monitors or only for windows on the primary monitor." @@ -468,11 +328,11 @@ msgstr "" "Визначає, чи перемикання робочого простору повинно здійснюватись для вікон " "на всіх моніторах, чи лише для вікон на первинному моніторі." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 +#: data/org.gnome.mutter.gschema.xml.in:59 msgid "No tab popup" msgstr "Без контекстних вкладок" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 +#: data/org.gnome.mutter.gschema.xml.in:60 msgid "" "Determines whether the use of popup and highlight frame should be disabled " "for window cycling." @@ -480,3201 +340,474 @@ msgstr "" "Визначає, чи слід вимкнути виринання і підкреслювання рамки для повторюваних " "вікон. " -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Затримувати зміни фокусу, поки вказівник не перестане рухатись" + +#: data/org.gnome.mutter.gschema.xml.in:69 +#| msgid "" +#| "If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " +#| "the focus will not be changed immediately when entering a window, but " +#| "only after the pointer stops moving." +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" +"Якщо вказано та фокусний режим «за вказівником» або «миша», то зміни не " +"будуть негайні, коли переходите на вікно, але тільки після того, як " +"вказівник не рухатиметься." + +#: data/org.gnome.mutter.gschema.xml.in:79 msgid "Draggable border width" msgstr "Перетяжна ширина меж" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 +#: data/org.gnome.mutter.gschema.xml.in:80 +#| msgid "" +#| "The amount of total draggable borders. If the theme's visible borders are " +#| "not enough, invisible borders will be added to meet this value." msgid "" -"The amount of total draggable borders. If the theme's visible borders are " +"The amount of total draggable borders. If the theme’s visible borders are " "not enough, invisible borders will be added to meet this value." msgstr "" "Загальний об'єм перетяжних меж. Якщо видимих меж теми не вистачає, буде " "використано це значення з невидимих меж." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:17 +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "Автоматично розгортати вікна з розміром екрана" + +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" +"Якщо вказано, нові вікна, які запущено в розмірі екрана, автоматично " +"розгортаються на ввесь екран." + +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Помістити нове вікно в центр" + +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "Якщо вказано, нові вікна будуть завжди в центрі чинного екрана." + +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Увімкнути експериментальні можливості" + +#: data/org.gnome.mutter.gschema.xml.in:108 +msgid "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes " +"mutter request a low priority real-time scheduling. The executable or user " +"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — " +"initializes Xwayland lazily if there are X11 clients. Requires restart." +msgstr "" +"Щоб увімкнути експериментальну можливість, додайте до списку ключове слово" +" можливості. Те, чи потребуватиме вмикання можливості перезапуску" +" композитора, залежить від типу можливості. Експериментальні можливості не" +" обов'язково завжди доступні чи придатні до налаштовування. Не слід" +" очікувати, що у майбутніх версіях обов'язково буде збережено якусь із" +" експериментальних можливостей. У поточній версії передбачено такі ключові" +" слова: • «scale-monitor-framebuffer» — наказує mutter типово розташовувати" +" логічні монітори у координатному просторі логічних пікселів, масштабуючи" +" буфери кадрів моніторів, замість вмісту вікон. Призначено для роботи із" +" моніторами із високою роздільною здатністю. Не потребує перезапуску" +" композитора. • «rt-scheduler» — наказати mutter надсилати до системи запит" +" щодо низькопріоритетного планування режиму реального часу. Для виконуваного" +" файла або запису користувача має бути встановлено CAP_SYS_NICE. Потребує" +" перезапуску композитора. • «autostart-xwayland» — лінива ініціалізація" +" Xwayland, якщо виявлено клієнти X11. Потребує перезапуску композитора." + +#: data/org.gnome.mutter.gschema.xml.in:134 +msgid "Modifier to use to locate the pointer" +msgstr "Модифікатор для пошуку вказівника" + +#: data/org.gnome.mutter.gschema.xml.in:135 +msgid "This key will initiate the “locate pointer” action." +msgstr "Ця комбінація ініціює дію «встановити розташування вказівника»" + +#: data/org.gnome.mutter.gschema.xml.in:142 +msgid "Timeout for check-alive ping" +msgstr "Інтервал між послідовними перевірками працездатності" + +#: data/org.gnome.mutter.gschema.xml.in:143 +msgid "" +"Number of milliseconds a client has to respond to a ping request in order to " +"not be detected as frozen. Using 0 will disable the alive check completely." +msgstr "" +"Проміжок часу у мілісекундах, протягом якого клієнт має відповісти на" +" луна-запит, щоб вважатися працездатним. Скористайтеся значенням 0, щоб" +" повністю вимкнути перевірку працездатності." + +#: data/org.gnome.mutter.gschema.xml.in:165 msgid "Select window from tab popup" msgstr "Вибрати вікно з контекстних вкладок" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:18 +#: data/org.gnome.mutter.gschema.xml.in:170 msgid "Cancel tab popup" msgstr "Скасувати контекстні вкладки" -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "Використання: %s\n" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "З_горнути" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "_Розгорнути" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "Відновити п_опередній розмір" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "_Скотити" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "Роз_котити" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "Пере_містити" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "Змінити _розмір" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "Перемістити заголовок на _екран" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "Завжди звер_ху" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "Зав_жди на видимому робочому просторі" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "_Лише на цьому робочому просторі" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "Перемістити у робочий простір _ліворуч" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "Перемістити у робочий простір _праворуч" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "Перемістити у робочий простір з_верху" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "Перемістити у робочу область з_низу" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "_Закрити" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "Робочий простір %d%n" - -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "Робочий простір 1_0" - -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "Робочий простір %s%d" - -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "Перемістити у ін_ший робочий простір" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" - -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. +#: data/org.gnome.mutter.gschema.xml.in:175 +#| msgid "Switch applications" +msgid "Switch monitor configurations" +msgstr "Перемкнути налаштування монітора" + +#: data/org.gnome.mutter.gschema.xml.in:180 +msgid "Rotates the built-in monitor configuration" +msgstr "Зміна конфігурації вбудованого монітора" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Перейти до VT 1" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Перейти до VT 2" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Перейти до VT 3" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Перейти до VT 4" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Перейти до VT 5" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Перейти до VT 6" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Перейти до VT 7" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Перейти до VT 8" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Перейти до VT 9" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Перейти до VT 10" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Перейти до VT 11" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Перейти до VT 12" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "Повторно увімкнути клавіатурні скорочення" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow X11 grabs to lock keyboard focus with Xwayland" +msgstr "" +"Дозволити захопленням у X11 блокувати зміну фокусування клавіатури з Xwayland" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 +msgid "" +"Allow all keyboard events to be routed to X11 “override redirect” windows " +"with a grab when running in Xwayland. This option is to support X11 clients " +"which map an “override redirect” window (which do not receive keyboard " +"focus) and issue a keyboard grab to force all keyboard events to that " +"window. This option is seldom used and has no effect on regular X11 windows " +"which can receive keyboard focus under normal circumstances. For a X11 grab " +"to be taken into account under Wayland, the client must also either send a " +"specific X11 ClientMessage to the root window or be among the applications " +"white-listed in key “xwayland-grab-access-rules”." +msgstr "" +"Дозволяє маршрутизацію усіх подій клавіатури до вікон X11 із «перевизначенням" +" переспрямовування», які захоплюють клавіатуру, коли їх запущено у Xwayland." +" Цей параметр призначено для реалізації підтримки клієнтів X11, які" +" здійснюють відображення вікна із «перевизначенням переспрямовування» (вікна," +" яке не отримує фокусування клавіатури) і видають сигнал щодо захоплення" +" клавіатури, щоб примусово переспрямувати усі події з клавіатури у відповідне" +" вікно. Використання цього параметра є рідкісним. Воно не впливає на звичайні" +" вікна X11, які можуть отримувати фокусування клавіатури за звичних обставин." +" Щоб захоплення клавіатури X11 бралося до уваги у Wayland, клієнтська" +" програма також має або надіслати специфічне ClientMessage X11 до кореневого" +" вікна, або мати свій пункт у «білому» списку ключа" +" «xwayland-grab-access-rules»." + +#: data/org.gnome.mutter.wayland.gschema.xml.in:84 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "" +"Програми Xwayland, яким дозволено надсилати запит щодо захоплення клавіатури" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:85 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "" +"Список назв ресурсів або клас ресурсів вікон X11, яким дозволено або" +" заборонено видавати запити на захоплення фокусу клавіатури X11 у Xwayland." +" Назву ресурсу або клас ресурсу певного вікна X11 можна визначити за" +" допомогою команди «xprop WM_CLASS». Передбачено підтримку" +" символів-замінників «*» і «?» у записах. Значення, які починатимуться з «!»," +" буде додано до «чорного» списку, який матиме пріоритет над «білим» списком," +" щоб програми можна було вилучати із типового загальносистемного списку." +" Типовий загальносистемний список містить записи таких програм:" +" «@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@». Користувачі можуть усувати наявне" +" захоплення фокуса за допомогою певного клавіатурного скорочення, яке" +" визначається ключем «restore-" +"shortcuts»." + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. #. -#: ../src/ui/resizepopup.c:113 +#: src/backends/meta-input-settings.c:2567 #, c-format -msgid "%d x %d" -msgstr "%d x %d" - -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "top" - -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "bottom" +msgid "Mode Switch (Group %d)" +msgstr "Перемкнути режим (група %d)" -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "left" - -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "right" +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2590 +#| msgid "Switch system controls" +msgid "Switch monitor" +msgstr "Перемкнути монітор" + +#: src/backends/meta-input-settings.c:2592 +msgid "Show on-screen help" +msgstr "Показати довідку на екрані" + +#: src/backends/meta-monitor.c:223 +msgid "Built-in display" +msgstr "Вбудований екран" + +#: src/backends/meta-monitor.c:252 +msgid "Unknown" +msgstr "Невідомо" + +#: src/backends/meta-monitor.c:254 +msgid "Unknown Display" +msgstr "Невідомий екран" + +#: src/backends/meta-monitor.c:262 +#, c-format +#| msgid "%s %s" +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" + +#: src/backends/meta-monitor.c:270 +#, c-format +#| msgid "%s %s" +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" + +#. Translators: this string will appear in Sysprof +#: src/backends/meta-profiler.c:79 +#| msgid "Compositing Manager" +msgid "Compositor" +msgstr "Композитор" -#: ../src/ui/theme.c:286 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:533 #, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "геометрія рамки не визначає розмір «%s»" +#| msgid "" +#| "Another compositing manager is already running on screen %i on display " +#| "\"%s\"." +msgid "" +"Another compositing manager is already running on screen %i on display “%s”." +msgstr "Уже запущено інший композитний менеджер на екрані %i через показ «%s»." -#: ../src/ui/theme.c:305 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "геометрія рамки не визначає розмір «%s» рамки «%s»" +#: src/core/bell.c:192 +msgid "Bell event" +msgstr "Подія гудка" -#: ../src/ui/theme.c:342 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "Неприпустимий коефіцієнт пропорційності %g" +#: src/core/main.c:190 +msgid "Disable connection to session manager" +msgstr "Вимкнути з'єднання з менеджером сеансу" -#: ../src/ui/theme.c:354 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "Геометрія рамки не визначає розміри кнопок" +#: src/core/main.c:196 +msgid "Replace the running window manager" +msgstr "Замінити запущений віконний менеджер" -#: ../src/ui/theme.c:1067 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "Градієнти повинні мати принаймні два кольори" +#: src/core/main.c:202 +msgid "Specify session management ID" +msgstr "Вказати ідентифікатор сеансу" -#: ../src/ui/theme.c:1219 -#, c-format -msgid "" -"GTK custom color specification must have color name and fallback in " -"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" -msgstr "" -"Специфікації власного кольору GTK повинні мати назву кольору і запас у " -"дужках, наприклад, gtk:custom(foo,bar); неможливо розібрати «%s»" +#: src/core/main.c:207 +msgid "X Display to use" +msgstr "Дисплей X" -#: ../src/ui/theme.c:1235 -#, c-format -msgid "" -"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" -"_ are valid" -msgstr "" -"Неправильний символ «%c» у параметрі color_name для gtk:custom, дозволено " -"тільки A-Za-z0-9-_" +#: src/core/main.c:213 +msgid "Initialize session from savefile" +msgstr "Розпочати сеанс зі збереженого файла" -#: ../src/ui/theme.c:1249 -#, c-format -msgid "" -"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " -"fit the format" -msgstr "" -"Формат Gtk:custom — «gtk:custom(color_name,fallback)», «%s» не відповідає " -"формату" +#: src/core/main.c:219 +msgid "Make X calls synchronous" +msgstr "Зробити виклики X синхронними" -#: ../src/ui/theme.c:1294 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"При визначенні кольору GTK потрібно вказувати режим у прямокутних дужках, " -"наприклад, gtk:fg[NORMAL], де NORMAL — режим; неможливо розібрати «%s»" +#: src/core/main.c:226 +msgid "Run as a wayland compositor" +msgstr "запустити як композитор wayland" -#: ../src/ui/theme.c:1308 -#, c-format -msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"При визначенні кольору GTK після вказування режиму повинна бути завершальна " -"прямокутна дужка, наприклад, gtk:fg[NORMAL], де NORMAL — режим; неможливо " -"розібрати «%s»" +#: src/core/main.c:232 +#| msgid "Run as a wayland compositor" +msgid "Run as a nested compositor" +msgstr "Запустити як вкладений композитор" -#: ../src/ui/theme.c:1319 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "Неможливо розпізнати режим «%s» у визначенні кольору" +#: src/core/main.c:238 +msgid "Run wayland compositor without starting Xwayland" +msgstr "Запустити композитор wayland без запуску Xwayland" -#: ../src/ui/theme.c:1332 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "Неможливо розпізнати компонент кольору «%s» у визначенні кольору" +#: src/core/main.c:246 +msgid "Run as a full display server, rather than nested" +msgstr "Запусти як повноцінний сервер, а не вкладений" -#: ../src/ui/theme.c:1361 -#, c-format -msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" -msgstr "" -"Формат визначення змішаного кольору такий — «blend/bg_color/fg_color/alpha», " -"«%s» не відповідає формату" +#: src/core/main.c:252 +msgid "Run with X11 backend" +msgstr "Запустити із модулем X11" -#: ../src/ui/theme.c:1372 +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:151 #, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "Неможливо розібрати значення альфа «%s» у змішаному кольорі" +msgid "“%s” is not responding." +msgstr "«%s» не відповідає." -#: ../src/ui/theme.c:1382 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "Значення альфа «%s» у змішаному кольорі поза межами 0.0 — 1.0" +#: src/core/meta-close-dialog-default.c:153 +msgid "Application is not responding." +msgstr "Програма не відповідає." -#: ../src/ui/theme.c:1429 -#, c-format +#: src/core/meta-close-dialog-default.c:158 msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." msgstr "" -"Формат тіні такий — «shade/base_color/factor», «%s» не відповідає формату" - -#: ../src/ui/theme.c:1440 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "Не вдалось проаналізувати компонент тіні «%s» у затіненому кольорі" - -#: ../src/ui/theme.c:1450 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "Компонент тіні «%s» у затіненому кольорі від'ємний" +"Можете трошки зачекати відновлення активності або примусово закрити програму." -#: ../src/ui/theme.c:1479 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Не вдалось проаналізувати колір «%s»" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Force Quit" +msgstr "_Завершити примусово" -#: ../src/ui/theme.c:1790 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "Вираз координати містить заборонений символ «%s»" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Wait" +msgstr "_Зачекати" -#: ../src/ui/theme.c:1817 +#: src/core/mutter.c:38 #, c-format +#| msgid "" +#| "mutter %s\n" +#| "Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +#| "This is free software; see the source for copying conditions.\n" +#| "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +#| "PARTICULAR PURPOSE.\n" msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" msgstr "" -"Вираз координати містить число з рухомою комою «%s», яке не вдалось розібрати" - -#: ../src/ui/theme.c:1831 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "Вираз координати містить ціле число «%s», яке не вдалось розібрати" - -#: ../src/ui/theme.c:1953 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "Вираз координати містить невідомий оператор на початку тексту: «%s»" - -#: ../src/ui/theme.c:2010 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "Вираз координати був пустий або його неможливо розпізнати" +"Mutter %s\n" +"© 2001-%d Havoc Pennington, Red Hat, Inc., та інші\n" +"Це — вільне програмний засіб; умови копіювання дивіться в коді програми.\n" +"Не надається НІЯКИХ гарантій; навіть ПРИДАТНОСТІ ДЛЯ ПРОДАЖУ чи " +"ВІДПОВІДНОСТІ ПЕВНІЙ МЕТІ.\n" -#: ../src/ui/theme.c:2121 ../src/ui/theme.c:2131 ../src/ui/theme.c:2165 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "Вираз координати призвів до ділення на нуль" +#: src/core/mutter.c:52 +msgid "Print version" +msgstr "Показати версію" -#: ../src/ui/theme.c:2173 -#, c-format -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "" -"Вираз координати намагається використати оператор знаходження залишку від " -"ділення для числа з рухомою комою" +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "Додатки Clutter для використання" -#: ../src/ui/theme.c:2229 +#: src/core/prefs.c:1911 #, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "Вираз координати містить оператор «%s», там де очікувався операнд" +msgid "Workspace %d" +msgstr "Робочий простір %d" -#: ../src/ui/theme.c:2238 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "Вираз координати містить оператор, там де очікувався оператор" +#: src/core/util.c:122 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter зібрано без підтримки докладного режиму\n" -#: ../src/ui/theme.c:2246 +#: src/wayland/meta-wayland-tablet-pad.c:568 #, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "Вираз координати закінчується оператором замість операнда" +msgid "Mode Switch: Mode %d" +msgstr "Перемикання режимів: режим %d" -#: ../src/ui/theme.c:2256 +#: src/x11/meta-x11-display.c:676 #, c-format +#| msgid "" +#| "Display \"%s\" already has a window manager; try using the --replace " +#| "option to replace the current window manager." msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." msgstr "" -"Вираз координати містить оператор «%c», за яким йде оператор «%c» без " -"операнду між ними" - -#: ../src/ui/theme.c:2407 ../src/ui/theme.c:2452 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "Вираз координати містить невідому змінну або константу «%s»" - -#: ../src/ui/theme.c:2506 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "Переповнення буфера обробника координат." - -#: ../src/ui/theme.c:2535 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "Вираз координати містить завершальну дужку без відповідної починальної" +"Екран «%s» вже має менеджера вікон; спробуйте вказати параметр --replace, " +"щоб замінити поточний менеджер вікон." -#: ../src/ui/theme.c:2599 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "Вираз координати містить починальну дужку без відповідної завершальної" +#: src/x11/meta-x11-display.c:1089 +msgid "Failed to initialize GDK\n" +msgstr "Не вдалося ініціалізувати GDK\n" -#: ../src/ui/theme.c:2610 +#: src/x11/meta-x11-display.c:1113 #, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "Здається, вираз координати не містить жодного оператора чи операнду" +#| msgid "Failed to open X Window System display '%s'\n" +msgid "Failed to open X Window System display “%s”\n" +msgstr "Не вдалось відкрити дисплей віконної системи X «%s»\n" -#: ../src/ui/theme.c:2822 ../src/ui/theme.c:2842 ../src/ui/theme.c:2862 +#: src/x11/meta-x11-display.c:1196 #, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "Тема містить вираз, що призводить до помилки: %s\n" +#| msgid "Screen %d on display '%s' is invalid\n" +msgid "Screen %d on display “%s” is invalid\n" +msgstr "Екран %d на дисплеї «%s» не правильний\n" -#: ../src/ui/theme.c:4533 +#: src/x11/meta-x11-selection-input-stream.c:460 #, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" -"для цього стилю рамки треба вказати <button function=\"%s\" state=\"%s\" " -"draw_ops=\"будь-що\"/>" +msgid "Format %s not supported" +msgstr "Підтримки формату %s не передбачено" -#: ../src/ui/theme.c:5066 ../src/ui/theme.c:5091 -#, c-format +#: src/x11/session.c:1821 +#| msgid "" +#| "These windows do not support "save current setup" and will have " +#| "to be restarted manually next time you log in." msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." msgstr "" -"Нема <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"будь-що\"/>" - -#: ../src/ui/theme.c:5139 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Не вдалось завантажити тему «%s»: %s\n" +"Ці вікна не підтримують «збереження поточних параметрів», і при " +"наступному входженні їх треба запустити власноруч." -#: ../src/ui/theme.c:5275 ../src/ui/theme.c:5282 ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 ../src/ui/theme.c:5303 +#: src/x11/window-props.c:569 #, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "Не встановлено <%s> для теми «%s»" - -#: ../src/ui/theme.c:5311 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" -"Немає стилю рамки для вікна типу «%s» у темі «%s», додайте елемент <window " -"type=\"%s\" style_set=\"будь-що\"/> " - -#: ../src/ui/theme.c:5709 ../src/ui/theme.c:5771 ../src/ui/theme.c:5834 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "" -"Визначені користувачем константи повинні починатись з великої літери; «%s» " -"не починається з великої літери" - -#: ../src/ui/theme.c:5717 ../src/ui/theme.c:5779 ../src/ui/theme.c:5842 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "Константу «%s» вже визначено" - -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. -#. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "Немає атрибута «%s» у елементі <%s>" - -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Рядок %d, символ %d: %s" - -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "Атрибут «%s» двічі повторюється у тому самому елементі <%s>" - -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "Неправильний атрибут «%s» у елементі <%s> в цьому контексті" - -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "Не вдалось проаналізувати як ціле «%s»" - -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "Не вдалось розпізнати останні символи «%s» у рядку «%s»" - -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "Значення цілого %ld має бути додатнім" - -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "Значення цілого %ld надто велике, максимумом є %d" - -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "Неможливо проаналізувати «%s» як число з рухомою комою" - -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "Логічні значення повинні бути «true» або «false», а не «%s»" - -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "Кут повинен бути між 0.0 та 360.0, вказано %g\n" - -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" -"Альфа повинен бути у межах 0.0 (невидимість) та 1.0 (повна непрозорість), " -"було %g\n" - -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"Неприпустимий масштаб заголовка «%s» (можливі значення: xx-small,x-small," -"small,medium,large,x-large,xx-large)\n" - -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "у елементі <%s> назву «%s» використано вдруге" - -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "у елементі <%s> не визначено батьківський елемент «%s»" - -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "у елементі <%s> не визначено геометрію «%s»" - -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "" -"<%s> повинен або визначати геометрію, або вказувати на батьківський елемент, " -"який містить геометрію" - -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "Слід вказати тло для значення альфа" - -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Невідомий тип «%s» у елементі <%s>" - -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "Невідомий параметр style_set «%s» у елементі <%s>" - -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "Типу вікна «%s» вже визначено набір стилів" - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "Не допускається використання елементу <%s> нижче <%s>" - -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" -msgstr "" -"Неможливо вказати і «button_width\"/\"button_height», і «aspect_ratio» для " -"кнопок" - -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "Невідома відстань «%s»" - -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "Невідомий коефіцієнт пропорційності «%s»" - -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "Межа «%s» невідома" - -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "Немає атрибуту «start_angle» або «from» у елементі <%s>" - -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "Немає атрибуту «extent_angle» або «to» у елементі <%s>" - -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "Не вдалось розпізнати значення «%s» типу градієнту" - -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "Не вдалось розпізнати тип заповнення «%s» у елементі <%s>" - -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "Не вдалось розпізнати стан «%s» у елементі <%s>" - -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "Не вдалось розпізнати тінь «%s» у елементі <%s>" - -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "Не вдалось розпізнати стрілку «%s» у елементі <%s>" - -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "Параметр <draw_ops> з назвою «%s» не визначено" - -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "" -"Вставлення сюди draw_ops «%s» призведе до створення циклічного посилання" - -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Невідома позиція «%s» частки рамки" - -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "У стилю рамки вже є частка рамки у позиції %s" - -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "Не визначено параметра <draw_ops> з назвою «%s»" - -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Невідома функція кнопки — «%s»" - -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "Функція кнопки «%s» не існує для цієї версії (%d, потрібно %d)" - -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Невідомий стан кнопки — «%s»" - -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "Стиль рамки вже містить кнопку для функції %s зі станом %s" - -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "«%s» — не є правильною назвою атрибута «focus»" - -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "«%s» — не є правильним станом атрибута «state»" - -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "Стиль «%s» не визначено" - -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "«%s» — не є правильним значенням атрибуту «resize»" - -#: ../src/ui/theme-parser.c:3147 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" -"Не слід використовувати атрибут «resize» у елементі <%s> для розгорнутого та " -"згорнутого стану" - -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "" -"Не слід використовувати атрибут «resize» у елементі <%s> для розгорнутого " -"стану" - -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "Стиль уже визначено для станів state %s resize %s focus %s" - -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "Стиль уже визначено для станів state %s focus %s" - -#: ../src/ui/theme-parser.c:3294 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Неможливо використовувати два параметра draw_ops у одному елементі <piece> " -"(у темі вказано атрибут draw_ops та елемент <draw_ops>, або вказано два " -"елементи)" - -#: ../src/ui/theme-parser.c:3332 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Неможливо використовувати два параметра draw_ops у одному елементі <button> " -"(у темі вказано атрибут draw_ops та елемент <draw_ops>, або вказано два " -"елементи)" - -#: ../src/ui/theme-parser.c:3370 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Неможливо використовувати два параметра draw_ops у одному елементі " -"<menu_icon> (у темі вказано атрибут draw_ops та елемент <draw_ops>, або " -"вказано два елементи)" - -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "Погана версія специфікацій «%s»" - -#: ../src/ui/theme-parser.c:3507 -msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" -msgstr "" -"Атрибут «version» неможливо використати в metacity-theme-1.xml або metacity-" -"theme-2.xml" - -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "Потрібна версія теми — %s, однак остання підтримувана версія — %d.%d" - -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "Найвищим елементом в темі має бути <metacity_theme>, не <%s>" - -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "" -"Елемент <%s> не дозволяється у елементах <name>, <author>, <date> і " -"<description>" - -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "Елемент <%s> не дозволяється у елементі <constant>" - -#: ../src/ui/theme-parser.c:3599 -#, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "" -"Елемент <%s> не дозволяється у елементах <distance>, <border>, <aspect_ratio>" - -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "Елемент <%s> не дозволяється у елементі операції малювання" - -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "Елемент <%s> не дозволяється у елементі <%s>" - -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "Для частини рамки не визначено параметр draw_ops" - -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "Для кнопки не визначено параметр draw_ops" - -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "Текст не дозволяється у елементі <%s>" - -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "<%s> в цій темі вказано двічі" - -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Не вдалось знайти коректний файл для теми %s\n" - -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "_Вікна" - -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "_Діалог" - -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "_Модальне вікно" - -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "_Засіб" - -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "За_ставка" - -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "В_ерхня панель" - -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "Н_ижня панель" - -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "_Ліва панель" - -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "_Права панель" - -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "_Усі панелі" - -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "С_тільниця" - -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "Відкрити інше вікно" - -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "Це демонстраційна кнопка з піктограмою відкривання" - -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "Це демонстраційна кнопка з піктограмою виходу" - -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "Це зразок повідомлення у зразковому діалозі" - -#: ../src/ui/theme-viewer.c:328 -#, c-format -msgid "Fake menu item %d\n" -msgstr "Фальшивий елемент меню %d\n" - -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "Вікно лише з рамкою" - -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "Прямокутник" - -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "Звичайне вікно програми" - -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "Діалог" - -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "Модальне вікно" - -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "Допоміжна палітра" - -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "Відірване меню" - -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "Рамка" - -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "Долучене модальне вікно" - -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "Випробування компонування кнопок %d" - -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g мілісекунд для малювання однієї рамки вікна" - -#: ../src/ui/theme-viewer.c:813 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Використання: metacity-theme-viewer [НАЗВА_ТЕМИ]\n" - -#: ../src/ui/theme-viewer.c:820 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "Помилка завантаження теми: %s\n" - -#: ../src/ui/theme-viewer.c:826 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "Завантажено тему «%s» за %g секунд\n" - -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "Звичайний шрифт заголовка" - -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "Малий шрифт заголовка" - -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "Великий шрифт заголовка" - -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "Компонування кнопок" - -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "Продуктивність" - -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "Тут буде заголовок вікна" - -#: ../src/ui/theme-viewer.c:1047 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"Намальовано %d рамок за %g секунд клієнтського часу (%g мс на рамку) і %g " -"секунд календарного часу, враховуючи ресурси сервера X Window (%g мілісекунд " -"на кадр)\n" - -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "" -"випробування виразу позиції повернула значення TRUE, але встановило помилку" - -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "" -"випробування виразу позиції повернула значення FALSE, але не встановило " -"помилку" - -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "Очікувалась помилка, але її не трапилось" - -#: ../src/ui/theme-viewer.c:1274 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "Очікувалась помилка %d, але трапилась помилка %d" - -#: ../src/ui/theme-viewer.c:1280 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "Помилка не очікувалась, але її повернуто: %s" - -#: ../src/ui/theme-viewer.c:1284 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "Значення X було %d, а очікувалось ― %d" - -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "Значення Y було %d, а очікувалось ― %d" - -#: ../src/ui/theme-viewer.c:1352 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "" -"%d координатних виразів проаналізовано за %g секунд (середнє значення: %g " -"секунд)\n" - -#~ msgid "Close Window" -#~ msgstr "Закрити вікно" - -#~ msgid "Window Menu" -#~ msgstr "Меню вікна" - -#~ msgid "Minimize Window" -#~ msgstr "Згорнути вікно" - -#~ msgid "Maximize Window" -#~ msgstr "Розгорнути вікно" - -#~ msgid "Restore Window" -#~ msgstr "Відновити вікно" - -#~ msgid "Roll Up Window" -#~ msgstr "Скотити вікно" - -#~ msgid "Unroll Window" -#~ msgstr "Розкотити вікно" - -#~ msgid "Keep Window On Top" -#~ msgstr "Тримати вікно нагорі" - -#~ msgid "Remove Window From Top" -#~ msgstr "Прибрати вікно з гори" - -#~ msgid "Always On Visible Workspace" -#~ msgstr "Завжди на видимому робочому просторі" - -#~ msgid "Put Window On Only One Workspace" -#~ msgstr "Розміщувати вікно лише на одному робочому просторі" - -#~ msgid "Switch to workspace 1" -#~ msgstr "Перейти на робочий простір 1" - -#~ msgid "Switch to workspace 2" -#~ msgstr "Перейти на робочий простір 2" - -#~ msgid "Switch to workspace 3" -#~ msgstr "Перейти на робочий простір 3" - -#~ msgid "Switch to workspace 4" -#~ msgstr "Перейти на робочий простір 4" - -#~ msgid "Switch to workspace 5" -#~ msgstr "Перейти на робочий простір 5" - -#~ msgid "Switch to workspace 6" -#~ msgstr "Перейти на робочий простір 6" - -#~ msgid "Switch to workspace 7" -#~ msgstr "Перейти на робочий простір 7" - -#~ msgid "Switch to workspace 8" -#~ msgstr "Перейти на робочий простір 8" - -#~ msgid "Switch to workspace 9" -#~ msgstr "Перейти на робочий простір 9" - -#~ msgid "Switch to workspace 10" -#~ msgstr "Перейти на робочий простір 10" - -#~ msgid "Switch to workspace 11" -#~ msgstr "Перейти на робочий простір 11" - -#~ msgid "Switch to workspace 12" -#~ msgstr "Перейти на робочий простір 12" - -#~ msgid "Switch to workspace on the left of the current workspace" -#~ msgstr "Перейти на робочий простір, що зліва від поточного" - -#~ msgid "Switch to workspace on the right of the current workspace" -#~ msgstr "Перейти на робочий простір, що справа від поточного" - -#~ msgid "Switch to workspace above the current workspace" -#~ msgstr "Перейти на робочий простір, що зверху від поточного" - -#~ msgid "Switch to workspace below the current workspace" -#~ msgstr "Перейти на робочий простір, що знизу від поточного" - -#~ msgid "Move between windows of an application, using a popup window" -#~ msgstr "Перейти між вікнами програми, використовуючи контекстне вікно" - -#~ msgid "" -#~ "Move backward between windows of an application, using a popup window" -#~ msgstr "" -#~ "Повернутись назад між вікнами програми, використовуючи контекстне вікно" - -#~ msgid "Move between windows, using a popup window" -#~ msgstr "Перейти між вікнами, використовуючи контекстне вікно" - -#~ msgid "Move backward between windows, using a popup window" -#~ msgstr "Повернутись назад між вікнами, використовуючи контекстне вікно" - -#~ msgid "Move between panels and the desktop, using a popup window" -#~ msgstr "Перейти між панелями та стільницею, використовуючи контекстне вікно" - -#~ msgid "Move backward between panels and the desktop, using a popup window" -#~ msgstr "" -#~ "Повернутись назад між панелями і стільницею, використовуючи контекстне " -#~ "вікно" - -#~ msgid "Move between windows of an application immediately" -#~ msgstr "Негайно перейти між вікнами програми" - -#~ msgid "Move backward between windows of an application immediately" -#~ msgstr "Негайно повернутись назад між вікнами програми" - -#~ msgid "Move between windows immediately" -#~ msgstr "Негайно перейти між вікнами" - -#~ msgid "Move backward between windows immediately" -#~ msgstr "Негайно повернутись назад між вікнами" - -#~ msgid "Move between panels and the desktop immediately" -#~ msgstr "Негайний перейти між панелями та стільницею" - -#~ msgid "Move backward between panels and the desktop immediately" -#~ msgstr "Негайно перейти між панелями та стільницею" - -#~ msgid "Hide all normal windows and set focus to the desktop" -#~ msgstr "Сховати всі звичайні вікна та перейти до стільниці" - -#~ msgid "Show the panel's main menu" -#~ msgstr "Показати головне меню панелі" - -#~ msgid "Show the panel's \"Run Application\" dialog box" -#~ msgstr "Показати вікно панелі запуску програм" - -#~ msgid "Start or stop recording the session" -#~ msgstr "Почати або зупинити запис сеансу" - -#~ msgid "Take a screenshot" -#~ msgstr "Зробити знімок екрана" - -#~ msgid "Take a screenshot of a window" -#~ msgstr "Зробити знімок вікна" - -#~ msgid "Run a terminal" -#~ msgstr "Запустити термінал" - -#~ msgid "Activate the window menu" -#~ msgstr "Активувати меню вікна" - -#~ msgid "Toggle fullscreen mode" -#~ msgstr "Перемикання повноекранного режиму" - -#~ msgid "Toggle maximization state" -#~ msgstr "Перемикання стану розгортання" - -#~ msgid "Toggle whether a window will always be visible over other windows" -#~ msgstr "Перемикання видимості вікна над усіма іншими вікнами назавжди" - -#~ msgid "Maximize window" -#~ msgstr "Розгорнути вікно" - -#~ msgid "Restore window" -#~ msgstr "Відновити вікно" - -#~ msgid "Toggle shaded state" -#~ msgstr "Перемикання стану згорнутості" - -#~ msgid "Minimize window" -#~ msgstr "Згорнути вікно" - -#~ msgid "Close window" -#~ msgstr "Закрити вікно" - -#~ msgid "Move window" -#~ msgstr "Перемістити вікно" - -#~ msgid "Resize window" -#~ msgstr "Змінити розмір вікна" - -#~ msgid "Toggle whether window is on all workspaces or just one" -#~ msgstr "Перемикання розміщення вікна всіх робочих просторах або одному " - -#~ msgid "Move window to workspace 1" -#~ msgstr "Перемістити вікно на робочий простір 1" - -#~ msgid "Move window to workspace 2" -#~ msgstr "Перемістити вікно на робочий простір 2" - -#~ msgid "Move window to workspace 3" -#~ msgstr "Перемістити вікно на робочий простір 3" - -#~ msgid "Move window to workspace 4" -#~ msgstr "Перемістити вікно на робочий простір 4" - -#~ msgid "Move window to workspace 5" -#~ msgstr "Перемістити вікно на робочий простір 5" - -#~ msgid "Move window to workspace 6" -#~ msgstr "Перемістити вікно на робочий простір 6" - -#~ msgid "Move window to workspace 7" -#~ msgstr "Перемістити вікно на робочий простір 7" - -#~ msgid "Move window to workspace 8" -#~ msgstr "Перемістити вікно на робочий простір 8" - -#~ msgid "Move window to workspace 9" -#~ msgstr "Перемістити вікно на робочий простір 9" - -#~ msgid "Move window to workspace 10" -#~ msgstr "Перемістити вікно на робочий простір 10" - -#~ msgid "Move window to workspace 11" -#~ msgstr "Перемістити вікно на робочий простір 11" - -#~ msgid "Move window to workspace 12" -#~ msgstr "Перемістити вікно на робочий простір 12" - -#~ msgid "Move window one workspace to the left" -#~ msgstr "Перемістити вікно у робочий простір ліворуч" - -#~ msgid "Move window one workspace to the right" -#~ msgstr "Перемістити вікно у робочий простір праворуч" - -#~ msgid "Move window one workspace up" -#~ msgstr "Перемістити вікно на робочий простір вище" - -#~ msgid "Move window one workspace down" -#~ msgstr "Перемістити вікно на робочий простір нижче" - -#~ msgid "Raise window if it's covered by another window, otherwise lower it" -#~ msgstr "Підняти вікно, якщо його покрито іншим, інакше опустити його" - -#~ msgid "Raise window above other windows" -#~ msgstr "Підняти вікно над іншими" - -#~ msgid "Lower window below other windows" -#~ msgstr "Перемістити вікна нижче усіх вікон" - -#~ msgid "Maximize window vertically" -#~ msgstr "Розгорнути вікно на весь екран вертикально" - -#~ msgid "Maximize window horizontally" -#~ msgstr "Розгорнути вікно на весь екран горизонтально" - -#~ msgid "Move window to north-west (top left) corner" -#~ msgstr "Перемістити вікно у верхній лівий край" - -#~ msgid "Move window to north-east (top right) corner" -#~ msgstr "Перемістити вікно у верхній правий край" - -#~ msgid "Move window to south-west (bottom left) corner" -#~ msgstr "Перемістити вікно у нижній лівий край" - -#~ msgid "Move window to south-east (bottom right) corner" -#~ msgstr "Перемістити вікно у нижній правий край" - -#~ msgid "Move window to north (top) side of screen" -#~ msgstr "Перемістити вікно у верхній бік екрана" - -#~ msgid "Move window to south (bottom) side of screen" -#~ msgstr "Перемістити вікно у нижній бік екрана" - -#~ msgid "Move window to east (right) side of screen" -#~ msgstr "Перемістити вікно у правий бік екрана" - -#~ msgid "Move window to west (left) side of screen" -#~ msgstr "Перемістити вікно у лівий бік екрана" - -#~ msgid "Move window to center of screen" -#~ msgstr "Перемістити вікно у центр екрана" - -#~ msgid "" -#~ "There was an error running <tt>%s</tt>:\n" -#~ "\n" -#~ "%s" -#~ msgstr "" -#~ "Виникла помила при запуску <tt>%s</tt>:\n" -#~ "\n" -#~ "%s" - -#~ msgid "No command %d has been defined.\n" -#~ msgstr "Команду %d не визначено.\n" - -#~ msgid "No terminal command has been defined.\n" -#~ msgstr "Команду термінала не визначено.\n" - -#~ msgid "GConf key '%s' is set to an invalid value\n" -#~ msgstr "Ключ GConf «%s» встановлено у неправильний тип\n" - -#~ msgid "%d stored in GConf key %s is out of range %d to %d\n" -#~ msgstr "Значення %d збережене в ключі GConf %s виходить за межі %d ― %d\n" - -#~ msgid "GConf key \"%s\" is set to an invalid type\n" -#~ msgstr "Ключу GConf «%s» вказано неправильний тип\n" - -#~ msgid "GConf key %s is already in use and can't be used to override %s\n" -#~ msgstr "Ключ GConf %s вже використовується і неможливо перевизначити %s\n" - -#~ msgid "Can't override GConf key, %s not found\n" -#~ msgstr "Неможливо перевизначити ключ GConf, %s не знайдено\n" - -#~ msgid "Error setting number of workspaces to %d: %s\n" -#~ msgstr "Помилка налаштування кількості робочих просторів у %d: %s\n" - -#~ msgid "Error setting name for workspace %d to \"%s\": %s\n" -#~ msgstr "Помилка налаштуванні назви робочих просторів %d у «%s»: %s\n" - -#~ msgid "Error setting live hidden windows status status: %s\n" -#~ msgstr "Помилка налаштування стану схованих вікон: %s\n" - -#~ msgid "Error setting no tab popup status: %s\n" -#~ msgstr "Помилка налаштування стану контекстних вкладок: %s\n" - -#~ msgid "" -#~ "Don't make fullscreen windows that are maximized and have no decorations" -#~ msgstr "Не робити повноекранні вікна, які розгорнуто і не мають рамки" - -#~ msgid "Whether window popup/frame should be shown when cycling windows." -#~ msgstr "Чи показувати циклічні вікна." - -#~ msgid "Internal argument for GObject introspection" -#~ msgstr "Внутрішній аргумент для самоаналізу GObject" - -#~ msgid "Failed to restart: %s\n" -#~ msgstr "Збій перезапуску: %s\n" - -#~ msgid "Error setting clutter plugin list: %s\n" -#~ msgstr "Помилка налаштування списку додатків Clutter: %s\n" - -#~ msgid "Clutter Plugins" -#~ msgstr "Додатки Clutter" - -#~ msgid "Plugins to load for the Clutter-based compositing manager." -#~ msgstr "" -#~ "Додатки для завантаження композитного менеджера основаного на Clutter." - -#~ msgid "Window Management" -#~ msgstr "Керування вікнами" - -#~ msgid "Failed to parse message \"%s\" from dialog process\n" -#~ msgstr "Помилка при аналізі повідомлення \"%s\" від діалогового процесу\n" - -#~ msgid "Error reading from dialog display process: %s\n" -#~ msgstr "Помилка при зчитуванні з діалогового процесу: %s\n" - -#~ msgid "" -#~ "Error launching metacity-dialog to ask about killing an application: %s\n" -#~ msgstr "Помилка при відкриванні діалогу закриття програми: %s\n" - -#~ msgid "Failed to get hostname: %s\n" -#~ msgstr "Помилка при отриманні назви комп'ютера: %s\n" - -#~ msgid "" -#~ "Lost connection to the display '%s';\n" -#~ "most likely the X server was shut down or you killed/destroyed\n" -#~ "the window manager.\n" -#~ msgstr "" -#~ "Втрачено з'єднання з дисплеєм \"%s\";\n" -#~ "очевидно було зупинено X-сервер, або в віконний менеджер\n" -#~ "був знищений.\n" - -#~ msgid "Fatal IO error %d (%s) on display '%s'.\n" -#~ msgstr "Фатальна помилка вводу-виводу %d (%s) на дисплеї \"%s\".\n" - -#~ msgid "" -#~ "Error launching metacity-dialog to print an error about a command: %s\n" -#~ msgstr "" -#~ "Помилка при відкриванні діалогу виводу повідомлення про помилку у " -#~ "команді: %s\n" - -#~ msgid "Type of %s was not integer" -#~ msgstr "Значення %s має відмінний тип від цілого числа" - -#~ msgid "" -#~ "%d stored in GConf key %s is not a reasonable cursor_size; must be in the " -#~ "range 1..128\n" -#~ msgstr "" -#~ "Значення %d встановлено у ключі GCong %s є неприпустимим для cursor_size; " -#~ "має бути у межах 1..128\n" - -#~ msgid "" -#~ "%d stored in GConf key %s is not a reasonable number of workspaces, " -#~ "current maximum is %d\n" -#~ msgstr "" -#~ "Значення %d встановлено у ключі GCong %s ― що не є припустимим значенням " -#~ "кількості робочих областей, поточний максимум рівний %d\n" - -#~ msgid "Failed to read saved session file %s: %s\n" -#~ msgstr "Збій під час зчитування збереженого файлу сеансу \"%s\": %s\n" - -#~ msgid "Unknown attribute %s on <metacity_session> element" -#~ msgstr "Невідома ознака %s у елементі <metacity_session>" - -#~ msgid "Unknown attribute %s on <maximized> element" -#~ msgstr "Невідома ознака %s у елементі <maximized>" - -#~ msgid "Unknown attribute %s on <geometry> element" -#~ msgstr "Невідома ознака %s у елементі <geometry>" - -#~ msgid "" -#~ "Error launching metacity-dialog to warn about apps that don't support " -#~ "session management: %s\n" -#~ msgstr "" -#~ "Помилка запуску діалогового вікна Метасіті із застереженням про те, що " -#~ "додаток не має підтримки сеансів: %s\n" - -#~ msgid "Metacity" -#~ msgstr "Метасіті" - -#~ msgid "" -#~ "(Not implemented) Navigation works in terms of applications not windows" -#~ msgstr "(Не реалізовано) Навігація працює лише по програмам, а не по вікнам" - -#~ msgid "" -#~ "A font description string describing a font for window titlebars. The " -#~ "size from the description will only be used if the titlebar_font_size " -#~ "option is set to 0. Also, this option is disabled if the " -#~ "titlebar_uses_desktop_font option is set to true." -#~ msgstr "" -#~ "Рядок опису шрифту для заголовку вікна. Розмір з опису буде використано " -#~ "лише коли параметр \"titlebar_font_size\" має значення у 0. Цей параметр " -#~ "також вимкнений, якщо параметр \"titlebar_uses_desktop_font\" має " -#~ "значення Істина(true)." - -#~ msgid "Action on title bar double-click" -#~ msgstr "Дія при подвійному клацанні на заголовку вікна" - -#~ msgid "Action on title bar middle-click" -#~ msgstr "Дія при клацанні середньою кнопкою на заголовку вікна" - -#~ msgid "Action on title bar right-click" -#~ msgstr "Дія при клацанні правою кнопкою на заголовку вікна" - -#~ msgid "Arrangement of buttons on the titlebar" -#~ msgstr "Вирівнювання кнопок у заголовку вікна." - -#~ msgid "" -#~ "Arrangement of buttons on the titlebar. The value should be a string, " -#~ "such as \"menu:minimize,maximize,spacer,close\"; the colon separates the " -#~ "left corner of the window from the right corner, and the button names are " -#~ "comma-separated. Duplicate buttons are not allowed. Unknown button names " -#~ "are silently ignored so that buttons can be added in future metacity " -#~ "versions without breaking older versions. A special spacer tag can be " -#~ "used to insert some space between two adjacent buttons." -#~ msgstr "" -#~ "Вирівнювання кнопок у заголовку вікна. Значення має бути рядком, " -#~ "наприклад \"menu:minimize,maximize,spacer,close\"; де двокрапка " -#~ "відокремлює лівий кут вікна від правого, а назви кнопок розділяються " -#~ "комами. Дублікати кнопок не дозволяються. Невідомі назви кнопок просто " -#~ "ігноруються, таким чином можна додавати кнопки з майбутніх версій " -#~ "Метасіті без впливу на старі версії." - -#~ msgid "Automatically raises the focused window" -#~ msgstr "Автоматично піднімати вікно з фокусом вводу" - -#~ msgid "" -#~ "Clicking a window while holding down this modifier key will move the " -#~ "window (left click), resize the window (middle click), or show the window " -#~ "menu (right click). Modifier is expressed as \"<Alt>\" or \"<" -#~ "Super>\" for example." -#~ msgstr "" -#~ "Клацання кнопкою миші по вікну з утриманням натиснутою клавіші-" -#~ "модифікатора призведе до пересування вікна(лівою кнопкою), зміни розмірів " -#~ "(середньою кнопкою), або показу меню вікна (правою кнопкою). Модифікатор " -#~ "записується наприклад так \"<Alt>\" або \"<Super>\"" - -#~ msgid "Commands to run in response to keybindings" -#~ msgstr "Команди призначені комбінаціям клавіш" - -#~ msgid "Compositing Manager" -#~ msgstr "Менеджер композиції" - -#~ msgid "Control how new windows get focus" -#~ msgstr "Визначає, як нове вікно отримує фокус" - -#~ msgid "Current theme" -#~ msgstr "Поточна тема" - -#~ msgid "Delay in milliseconds for the auto raise option" -#~ msgstr "" -#~ "Затримка у мілісекундах для параметру автоматичного піднімання вікна" - -#~ msgid "Determines whether Metacity is a compositing manager." -#~ msgstr "Визначає, чи є Metacity менеджером композиції." - -#~ msgid "" -#~ "Determines whether applications or the system can generate audible " -#~ "'beeps'; may be used in conjunction with 'visual bell' to allow silent " -#~ "'beeps'." -#~ msgstr "" -#~ "Визначає, чи система і програми можуть генерувати озвучений системний " -#~ "гудок. Може використовуватись із \"візуальним системним гудком\", щоб " -#~ "увімкнути тихі системні гудки." - -#~ msgid "Disable misfeatures that are required by old or broken applications" -#~ msgstr "" -#~ "Вимкнути неправильні функції, що потрібні лише старим поламаним програмам" - -#~ msgid "Enable Visual Bell" -#~ msgstr "Увімкнути візуальний системний гудок" - -#~ msgid "" -#~ "If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " -#~ "the focused window will be automatically raised after a delay specified " -#~ "by the auto_raise_delay key. This is not related to clicking on a window " -#~ "to raise it, nor to entering a window during drag-and-drop." -#~ msgstr "" -#~ "Якщо встановлено, та для режиму передачі фокусу вибрано або \"за " -#~ "вказівником\", або \"миша\" тоді вікно з фокусом буде автоматично піднято " -#~ "після затримки, що визначається параметром auto_raise_delay. Це не " -#~ "пов'язано з клацанням на вікні для його підняття, ані з входом у вікно " -#~ "при перетягуванні (drag-and-drop)." - -#~ msgid "" -#~ "If true, ignore the titlebar_font option, and use the standard " -#~ "application font for window titles." -#~ msgstr "" -#~ "Якщо встановлено, параметр titlebar_font ігнорується, та використовується " -#~ "стандартний шрифт для заголовків вікон." - -#~ msgid "" -#~ "If true, metacity will give the user less feedback by using wireframes, " -#~ "avoiding animations, or other means. This is a significant reduction in " -#~ "usability for many users, but may allow legacy applications to continue " -#~ "working, and may also be a useful tradeoff for terminal servers. However, " -#~ "the wireframe feature is disabled when accessibility is on." -#~ msgstr "" -#~ "Якщо встановлено, то metacity надає користувачу менший зворотний зв'язок " -#~ "та менше відчуття \"безпосереднього керування\" за рахунок використання " -#~ "контурних рамок, відключення анімації та іншими шляхами. Це суттєве " -#~ "зменшення зручності у використанні для багатьох користувачів, але може " -#~ "подовжити термін служби старих програм і термінальних серверів. Слід " -#~ "зауважити, що функція відображення контурної рамки вимикається при " -#~ "увімкненні спеціальних можливостей." - -#~ msgid "" -#~ "If true, then Metacity works in terms of applications rather than " -#~ "windows. The concept is a bit abstract, but in general an application-" -#~ "based setup is more like the Mac and less like Windows. When you focus a " -#~ "window in application-based mode, all the windows in the application will " -#~ "be raised. Also, in application-based mode, focus clicks are not passed " -#~ "through to windows in other applications. Application-based mode is, " -#~ "however, largely unimplemented at the moment." -#~ msgstr "" -#~ "Якщо встановлено, Метасіті працює лише з програмами, а не з вікнами. " -#~ "Концепція трошки абстрактна, але в цілому робота з додатками більше схожа " -#~ "на Mac, ніж на Windows. При активації вікна у режимі роботи з додатками, " -#~ "піднімаються всі вікна цієї програми. Крім того, в режимі роботи з " -#~ "додатками, клацання мишею не передається вікнам інших програм. Реалізація " -#~ "режиму роботи з додатками, здебільшого, ще не завершена." - -#~ msgid "If true, trade off usability for less resource usage" -#~ msgstr "" -#~ "Якщо встановлено, зменшує зручність використання для зменшення " -#~ "використання ресурсів" - -#~ msgid "" -#~ "Many actions (e.g. clicking in the client area, moving or resizing the " -#~ "window) normally raise the window as a side-effect. Setting this option " -#~ "to false, which is strongly discouraged, will decouple raising from other " -#~ "user actions, and ignore raise requests generated by applications. See " -#~ "http://bugzilla.gnome.org/show_bug.cgi?id=445447#c6." -#~ msgstr "" -#~ "Багато дій (наприклад, клацання на області клієнту, переміщення або зміна " -#~ "розмірів вікна) зазвичай мають побічній ефект піднімання вікна на " -#~ "передній план. Встановлення значення цього параметра у \"false\", що дуже " -#~ "не рекомендується, призводить до відділення підйом від усіх інших " -#~ "операцій, та ігнорування запитів на підйом від програм. Докладнішу " -#~ "інформацію дивіться за посиланням http://bugzilla.gnome.org/show_bug.cgi?" -#~ "id=445447#c6." - -#~ msgid "Name of workspace" -#~ msgstr "Назва робочої області" - -#~ msgid "Number of workspaces" -#~ msgstr "Кількість робочих областей" - -#~ msgid "" -#~ "Number of workspaces. Must be more than zero, and has a fixed maximum to " -#~ "prevent making the desktop unusable by accidentally asking for too many " -#~ "workspaces." -#~ msgstr "" -#~ "Кількість робочих областей. Повинно бути більшим за нуль, та має " -#~ "визначений максимум для упередження руйнування робочого столу кількістю " -#~ "робочих областей." - -#~ msgid "Run a defined command" -#~ msgstr "Запустити зазначену команду" - -#~ msgid "" -#~ "Some applications disregard specifications in ways that result in window " -#~ "manager misfeatures. This option puts Metacity in a rigorously correct " -#~ "mode, which gives a more consistent user interface, provided one does not " -#~ "need to run any misbehaving applications." -#~ msgstr "" -#~ "Деякі програми ігнорують специфікації, що може призвести до неправильної " -#~ "поведінки віконного менеджера. Цей параметр переводить Metacity у режим " -#~ "суворої відповідності специфікаціям інтерфейсу, що забезпечує усім " -#~ "програмам стандартний зовнішній вигляд. При цьому звичайна робота " -#~ "програм, що не відповідають специфікаціям, не гарантується." - -#~ msgid "System Bell is Audible" -#~ msgstr "Системний гудок озвучується" - -#~ msgid "" -#~ "Tells Metacity how to implement the visual indication that the system " -#~ "bell or another application 'bell' indicator has been rung. Currently " -#~ "there are two valid values, \"fullscreen\", which causes a fullscreen " -#~ "white-black flash, and \"frame_flash\" which causes the titlebar of the " -#~ "application which sent the bell signal to flash. If the application which " -#~ "sent the bell is unknown (as is usually the case for the default \"system " -#~ "beep\"), the currently focused window's titlebar is flashed." -#~ msgstr "" -#~ "Вказує \"Метасіті\", як реалізувати візуальну індикацію системного гудка. " -#~ "На даний момент, доступні два значення: \"fullscreen\", що спричиняє " -#~ "короткочасне перемикання екрану в чорно-білий режим, і \"frame_flash\", " -#~ "що спричиняє блимання заголовка програми, що викликала гудок. Якщо не " -#~ "відомо, яка програма викликала гудок, що часто буває для типових " -#~ "системних гудків, відбувається блимання заголовка сфокусованого вікна." - -#~ msgid "" -#~ "The /apps/metacity/global_keybindings/run_command_N keys define " -#~ "keybindings that correspond to these commands. Pressing the keybinding " -#~ "for run_command_N will execute command_N." -#~ msgstr "" -#~ "Ключі /apps/metacity/global_keybindings/run_command_N визначають " -#~ "комбінації клавіш, що відповідають цим командам. Натискання комбінації " -#~ "клавіш run_command_N призводить до виконання command_N" - -#~ msgid "" -#~ "The /apps/metacity/global_keybindings/run_command_screenshot key defines " -#~ "a keybinding which causes the command specified by this setting to be " -#~ "invoked." -#~ msgstr "" -#~ "Ключ /apps/metacity/global_keybindings/run_command_screenshot визначає " -#~ "комбінацію клавіш, що викликає команду вказану в цьому параметрі." - -#~ msgid "" -#~ "The /apps/metacity/global_keybindings/run_command_window_screenshot key " -#~ "defines a keybinding which causes the command specified by this setting " -#~ "to be invoked." -#~ msgstr "" -#~ "Ключ /apps/metacity/global_keybindings/run_command_window_screenshot " -#~ "визначає комбінацію клавіш, що викликає команду вказану в цьому " -#~ "параметрі. " - -#~ msgid "" -#~ "The keybinding that runs the correspondingly-numbered command in /apps/" -#~ "metacity/keybinding_commands The format looks like \"<Control>a\" " -#~ "or \"<Shift><Alt>F1\". The parser is fairly liberal and " -#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" -#~ "\" and \"<Ctrl>\". If you set the option to the special string " -#~ "\"disabled\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "Комбінація клавіш для запуску команд з відповідним номером у ключі /apps/" -#~ "metacity/keybinding_commands Використовується формат \"<Control>a\" " -#~ "або \"<Shift><Alt>F1\". Аналізатор досить гнучкий та дозволяє " -#~ "використання верхнього та нижнього регістру та скорочень, наприклад \"<" -#~ "Ctl>\" та \"<Ctrl>\". Якщо цей параметр встановити у спеціальне " -#~ "значення \"disabled\", то для цієї дії не буде призначено комбінації " -#~ "клавіш." - -#~ msgid "" -#~ "The keybinding that switches to the workspace above the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Комбінація клавіш, що перемикає на робочу область розташовану вище " -#~ "поточної. Використовується формат \"<Control>a\" або \"<Shift>" -#~ "<Alt>F1\". Аналізатор досить гнучкий та дозволяє використання " -#~ "верхнього та нижнього регістру та скорочень, наприклад \"<Ctl>\" та " -#~ "\"<Ctrl>\". Якщо цей параметр встановити у спеціальне значення " -#~ "\"disabled\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding that switches to the workspace below the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Комбінація клавіш, що перемикає на робочу область розташовану нижче " -#~ "поточної. Використовується формат \"<Control>a\" або \"<Shift>" -#~ "<Alt>F1\". Аналізатор досить гнучкий та дозволяє використання " -#~ "верхнього та нижнього регістру та скорочень, наприклад \"<Ctl>\" та " -#~ "\"<Ctrl>\". Якщо цей параметр встановити у спеціальне значення " -#~ "\"disabled\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding that switches to the workspace on the left of the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Комбінація клавіш, що перемикає на робочу область розташовану ліворуч " -#~ "поточної. Використовується формат \"<Control>a\" або \"<Shift>" -#~ "<Alt>F1\". Аналізатор досить гнучкий та дозволяє використання " -#~ "верхнього та нижнього регістру та скорочень, наприклад \"<Ctl>\" та " -#~ "\"<Ctrl>\". Якщо цей параметр встановити у спеціальне значення " -#~ "\"disabled\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding that switches to the workspace on the right of the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Комбінація клавіш, що перемикає на робочу область розташовану праворуч " -#~ "поточної. Використовується формат \"<Control>a\" або \"<Shift>" -#~ "<Alt>F1\". Аналізатор досить гнучкий та дозволяє використання " -#~ "верхнього та нижнього регістру та скорочень, наприклад \"<Ctl>\" та " -#~ "\"<Ctrl>\". Якщо цей параметр встановити у спеціальне значення " -#~ "\"disabled\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding that switches to workspace 1. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбінація клавіш, що перемикає на робочу область з номером 1. " -#~ "Використовується формат \"<Control>a\" або \"<Shift><" -#~ "Alt>F1\". Аналізатор досить гнучкий та дозволяє використання верхнього " -#~ "та нижнього регістру та скорочень, наприклад \"<Ctl>\" та \"<" -#~ "Ctrl>\". Якщо цей параметр встановити у спеціальне значення \"disabled" -#~ "\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding that switches to workspace 10. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбінація клавіш, що перемикає на робочу область з номером 10. " -#~ "Використовується формат \"<Control>a\" або \"<Shift><" -#~ "Alt>F1\". Аналізатор досить гнучкий та дозволяє використання верхнього " -#~ "та нижнього регістру та скорочень, наприклад \"<Ctl>\" та \"<" -#~ "Ctrl>\". Якщо цей параметр встановити у спеціальне значення \"disabled" -#~ "\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding that switches to workspace 11. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбінація клавіш, що перемикає на робочу область з номером 11. " -#~ "Використовується формат \"<Control>a\" або \"<Shift><" -#~ "Alt>F1\". Аналізатор досить гнучкий та дозволяє використання верхнього " -#~ "та нижнього регістру та скорочень, наприклад \"<Ctl>\" та \"<" -#~ "Ctrl>\". Якщо цей параметр встановити у спеціальне значення \"disabled" -#~ "\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding that switches to workspace 12. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбінація клавіш, що перемикає на робочу область з номером 12. " -#~ "Використовується формат \"<Control>a\" або \"<Shift><" -#~ "Alt>F1\". Аналізатор досить гнучкий та дозволяє використання верхнього " -#~ "та нижнього регістру та скорочень, наприклад \"<Ctl>\" та \"<" -#~ "Ctrl>\". Якщо цей параметр встановити у спеціальне значення \"disabled" -#~ "\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding that switches to workspace 2. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбінація клавіш, що перемикає на робочу область з номером 2. " -#~ "Використовується формат \"<Control>a\" або \"<Shift><" -#~ "Alt>F1\". Аналізатор досить гнучкий та дозволяє використання верхнього " -#~ "та нижнього регістру та скорочень, наприклад \"<Ctl>\" та \"<" -#~ "Ctrl>\". Якщо цей параметр встановити у спеціальне значення \"disabled" -#~ "\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding that switches to workspace 3. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбінація клавіш, що перемикає на робочу область з номером 3. " -#~ "Використовується формат \"<Control>a\" або \"<Shift><" -#~ "Alt>F1\". Аналізатор досить гнучкий та дозволяє використання верхнього " -#~ "та нижнього регістру та скорочень, наприклад \"<Ctl>\" та \"<" -#~ "Ctrl>\". Якщо цей параметр встановити у спеціальне значення \"disabled" -#~ "\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding that switches to workspace 4. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбінація клавіш, що перемикає на робочу область з номером 4. " -#~ "Використовується формат \"<Control>a\" або \"<Shift><" -#~ "Alt>F1\". Аналізатор досить гнучкий та дозволяє використання верхнього " -#~ "та нижнього регістру та скорочень, наприклад \"<Ctl>\" та \"<" -#~ "Ctrl>\". Якщо цей параметр встановити у спеціальне значення \"disabled" -#~ "\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding that switches to workspace 5. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбінація клавіш, що перемикає на робочу область з номером 5. " -#~ "Використовується формат \"<Control>a\" або \"<Shift><" -#~ "Alt>F1\". Аналізатор досить гнучкий та дозволяє використання верхнього " -#~ "та нижнього регістру та скорочень, наприклад \"<Ctl>\" та \"<" -#~ "Ctrl>\". Якщо цей параметр встановити у спеціальне значення \"disabled" -#~ "\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding that switches to workspace 6. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбінація клавіш, що перемикає на робочу область з номером 6. " -#~ "Використовується формат \"<Control>a\" або \"<Shift><" -#~ "Alt>F1\". Аналізатор досить гнучкий та дозволяє використання верхнього " -#~ "та нижнього регістру та скорочень, наприклад \"<Ctl>\" та \"<" -#~ "Ctrl>\". Якщо цей параметр встановити у спеціальне значення \"disabled" -#~ "\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding that switches to workspace 7. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбінація клавіш, що перемикає на робочу область з номером 7. " -#~ "Використовується формат \"<Control>a\" або \"<Shift><" -#~ "Alt>F1\". Аналізатор досить гнучкий та дозволяє використання верхнього " -#~ "та нижнього регістру та скорочень, наприклад \"<Ctl>\" та \"<" -#~ "Ctrl>\". Якщо цей параметр встановити у спеціальне значення \"disabled" -#~ "\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding that switches to workspace 8. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбінація клавіш, що перемикає на робочу область з номером 8. " -#~ "Використовується формат \"<Control>a\" або \"<Shift><" -#~ "Alt>F1\". Аналізатор досить гнучкий та дозволяє використання верхнього " -#~ "та нижнього регістру та скорочень, наприклад \"<Ctl>\" та \"<" -#~ "Ctrl>\". Якщо цей параметр встановити у спеціальне значення \"disabled" -#~ "\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding that switches to workspace 9. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбінація клавіш, що перемикає на робочу область з номером 9. " -#~ "Використовується формат \"<Control>a\" або \"<Shift><" -#~ "Alt>F1\". Аналізатор досить гнучкий та дозволяє використання верхнього " -#~ "та нижнього регістру та скорочень, наприклад \"<Ctl>\" та \"<" -#~ "Ctrl>\". Якщо цей параметр встановити у спеціальне значення \"disabled" -#~ "\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to activate the window menu. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбінація клавіш активації меню вікна. Використовується формат \"<" -#~ "Control>a\" або \"<Shift><Alt>F1\". Аналізатор достатньо " -#~ "гнучкий та дозволяє використання верхнього та нижнього регістру та " -#~ "скорочень, наприклад \"<Ctl>\" та \"<Ctrl>\". Якщо цей " -#~ "параметр встановити у спеціальне значення \"disabled\", то для цієї дії " -#~ "не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to close a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбінація клавіш закривання вікна. Використовується формат \"<" -#~ "Control>a\" або \"<Shift><Alt>F1\". Аналізатор досить " -#~ "гнучкий та дозволяє використання верхнього та нижнього регістру та " -#~ "скорочень, наприклад \"<Ctl>\" та \"<Ctrl>\". Якщо цей " -#~ "параметр встановити у спеціальне значення \"disabled\", то для цієї дії " -#~ "не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to enter \"move mode\" and begin moving a window " -#~ "using the keyboard. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "Комбінація клавіш переходу у режим \"переміщення\", у цьому режимі вікно " -#~ "переміщується клавішами клавіатури. Використовується формат \"<" -#~ "Control>a\" або \"<Shift><Alt>F1\". Аналізатор досить " -#~ "гнучкий та дозволяє використання верхнього та нижнього регістру та " -#~ "скорочень, наприклад \"<Ctl>\" та \"<Ctrl>\". Якщо цей " -#~ "параметр встановити у спеціальне значення \"disabled\", то для цієї дії " -#~ "не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to enter \"resize mode\" and begin resizing a window " -#~ "using the keyboard. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "Комбінація клавіш переходу у режим \"зміни розмірів\", у цьому режимі " -#~ "клавішами клавіатури змінюється розмір вікна. Використовується формат " -#~ "\"<Control>a\" або \"<Shift><Alt>F1\". Аналізатор " -#~ "достатньо гнучкий та дозволяє використання верхнього та нижнього регістру " -#~ "та скорочень, наприклад \"<Ctl>\" та \"<Ctrl>\". Якщо цей " -#~ "параметр встановити у спеціальне значення \"disabled\", то для цієї дії " -#~ "не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to hide all normal windows and set the focus to the " -#~ "desktop background. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "Комбінація клавіш приховування всіх звичайних вікон та передачі фокусу " -#~ "вводу робочого столу. Використовується формат \"<Control>a\" або " -#~ "\"<Shift><Alt>F1\". Аналізатор досить гнучкий та дозволяє " -#~ "використання верхнього та нижнього регістру та скорочень, наприклад \"<" -#~ "Ctl>\" та \"<Ctrl>\". Якщо цей параметр встановити у спеціальне " -#~ "значення \"disabled\", то для цієї дії не буде призначено комбінації " -#~ "клавіш." - -#~ msgid "" -#~ "The keybinding used to maximize a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбінація клавіш розгортання вікна. Використовується формат \"<" -#~ "Control>a\" або \"<Shift><Alt>F1\". Аналізатор достатньо " -#~ "гнучкий та дозволяє використання верхнього та нижнього регістру та " -#~ "скорочень, наприклад \"<Ctl>\" та \"<Ctrl>\". Якщо цей " -#~ "параметр встановити у спеціальне значення \"disabled\", то для цієї дії " -#~ "не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to minimize a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбінація клавіш згортання вікна. Використовується формат \"<" -#~ "Control>a\" або \"<Shift><Alt>F1\". Аналізатор достатньо " -#~ "гнучкий та дозволяє використання верхнього та нижнього регістру та " -#~ "скорочень, наприклад \"<Ctl>\" та \"<Ctrl>\". Якщо цей " -#~ "параметр встановити у спеціальне значення \"disabled\", то для цієї дії " -#~ "не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to move a window one workspace down. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбінація клавіш переміщення вікна до робочої області розташованої під " -#~ "поточною. Використовується формат \"<Control>a\" або \"<Shift>" -#~ "<Alt>F1\". Аналізатор досить гнучкий та дозволяє використання " -#~ "верхнього та нижнього регістру та скорочень, наприклад \"<Ctl>\" та " -#~ "\"<Ctrl>\". Якщо цей параметр встановити у спеціальне значення " -#~ "\"disabled\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to move a window one workspace to the left. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Комбінація клавіш переміщення вікна до робочої області розташованої " -#~ "ліворуч поточної. Використовується формат \"<Control>a\" або \"<" -#~ "Shift><Alt>F1\". Аналізатор досить гнучкий та дозволяє " -#~ "використання верхнього та нижнього регістру та скорочень, наприклад \"<" -#~ "Ctl>\" та \"<Ctrl>\". Якщо цей параметр встановити у спеціальне " -#~ "значення \"disabled\", то для цієї дії не буде призначено комбінації " -#~ "клавіш." - -#~ msgid "" -#~ "The keybinding used to move a window one workspace to the right. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Комбінація клавіш переміщення вікна до робочої області розташованої " -#~ "праворуч поточної. Використовується формат \"<Control>a\" або \"<" -#~ "Shift><Alt>F1\". Аналізатор досить гнучкий та дозволяє " -#~ "використання верхнього та нижнього регістру та скорочень, наприклад \"<" -#~ "Ctl>\" та \"<Ctrl>\". Якщо цей параметр встановити у спеціальне " -#~ "значення \"disabled\", то для цієї дії не буде призначено комбінації " -#~ "клавіш." - -#~ msgid "" -#~ "The keybinding used to move a window one workspace up. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбінація клавіш переміщення вікна до робочої області розташованої над " -#~ "поточною. Використовується формат \"<Control>a\" або \"<Shift>" -#~ "<Alt>F1\". Аналізатор досить гнучкий та дозволяє використання " -#~ "верхнього та нижнього регістру та скорочень, наприклад \"<Ctl>\" та " -#~ "\"<Ctrl>\". Якщо цей параметр встановити у спеціальне значення " -#~ "\"disabled\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to move a window to workspace 1. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбінація клавіш переміщення вікна до робочої області з номером 1. " -#~ "Використовується формат \"<Control>a\" або \"<Shift><" -#~ "Alt>F1\". Аналізатор досить гнучкий та дозволяє використання верхнього " -#~ "та нижнього регістру та скорочень, наприклад \"<Ctl>\" та \"<" -#~ "Ctrl>\". Якщо цей параметр встановити у спеціальне значення \"disabled" -#~ "\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to move a window to workspace 10. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбінація клавіш переміщення вікна до робочої області з номером 10. " -#~ "Використовується формат \"<Control>a\" або \"<Shift><" -#~ "Alt>F1\". Аналізатор досить гнучкий та дозволяє використання верхнього " -#~ "та нижнього регістру та скорочень, наприклад \"<Ctl>\" та \"<" -#~ "Ctrl>\". Якщо цей параметр встановити у спеціальне значення \"disabled" -#~ "\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to move a window to workspace 11. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбінація клавіш переміщення вікна до робочої області з номером 11. " -#~ "Використовується формат \"<Control>a\" або \"<Shift><" -#~ "Alt>F1\". Аналізатор досить гнучкий та дозволяє використання верхнього " -#~ "та нижнього регістру та скорочень, наприклад \"<Ctl>\" та \"<" -#~ "Ctrl>\". Якщо цей параметр встановити у спеціальне значення \"disabled" -#~ "\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to move a window to workspace 12. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбінація клавіш переміщення вікна до робочої області з номером 12. " -#~ "Використовується формат \"<Control>a\" або \"<Shift><" -#~ "Alt>F1\". Аналізатор досить гнучкий та дозволяє використання верхнього " -#~ "та нижнього регістру та скорочень, наприклад \"<Ctl>\" та \"<" -#~ "Ctrl>\". Якщо цей параметр встановити у спеціальне значення \"disabled" -#~ "\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to move a window to workspace 2. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбінація клавіш переміщення вікна до робочої області з номером 2. " -#~ "Використовується формат \"<Control>a\" або \"<Shift><" -#~ "Alt>F1\". Аналізатор досить гнучкий та дозволяє використання верхнього " -#~ "та нижнього регістру та скорочень, наприклад \"<Ctl>\" та \"<" -#~ "Ctrl>\". Якщо цей параметр встановити у спеціальне значення \"disabled" -#~ "\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to move a window to workspace 3. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбінація клавіш переміщення вікна до робочої області з номером 3. " -#~ "Використовується формат \"<Control>a\" або \"<Shift><" -#~ "Alt>F1\". Аналізатор досить гнучкий та дозволяє використання верхнього " -#~ "та нижнього регістру та скорочень, наприклад \"<Ctl>\" та \"<" -#~ "Ctrl>\". Якщо цей параметр встановити у спеціальне значення \"disabled" -#~ "\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to move a window to workspace 4. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбінація клавіш переміщення вікна до робочої області з номером 4. " -#~ "Використовується формат \"<Control>a\" або \"<Shift><" -#~ "Alt>F1\". Аналізатор досить гнучкий та дозволяє використання верхнього " -#~ "та нижнього регістру та скорочень, наприклад \"<Ctl>\" та \"<" -#~ "Ctrl>\". Якщо цей параметр встановити у спеціальне значення \"disabled" -#~ "\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to move a window to workspace 5. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбінація клавіш переміщення вікна до робочої області з номером 5. " -#~ "Використовується формат \"<Control>a\" або \"<Shift><" -#~ "Alt>F1\". Аналізатор досить гнучкий та дозволяє використання верхнього " -#~ "та нижнього регістру та скорочень, наприклад \"<Ctl>\" та \"<" -#~ "Ctrl>\". Якщо цей параметр встановити у спеціальне значення \"disabled" -#~ "\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to move a window to workspace 6. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбінація клавіш переміщення вікна до робочої області з номером 6. " -#~ "Використовується формат \"<Control>a\" або \"<Shift><" -#~ "Alt>F1\". Аналізатор досить гнучкий та дозволяє використання верхнього " -#~ "та нижнього регістру та скорочень, наприклад \"<Ctl>\" та \"<" -#~ "Ctrl>\". Якщо цей параметр встановити у спеціальне значення \"disabled" -#~ "\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to move a window to workspace 7. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбінація клавіш переміщення вікна до робочої області з номером 7. " -#~ "Використовується формат \"<Control>a\" або \"<Shift><" -#~ "Alt>F1\". Аналізатор досить гнучкий та дозволяє використання верхнього " -#~ "та нижнього регістру та скорочень, наприклад \"<Ctl>\" та \"<" -#~ "Ctrl>\". Якщо цей параметр встановити у спеціальне значення \"disabled" -#~ "\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to move a window to workspace 8. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбінація клавіш переміщення вікна до робочої області з номером 8. " -#~ "Використовується формат \"<Control>a\" або \"<Shift><" -#~ "Alt>F1\". Аналізатор досить гнучкий та дозволяє використання верхнього " -#~ "та нижнього регістру та скорочень, наприклад \"<Ctl>\" та \"<" -#~ "Ctrl>\". Якщо цей параметр встановити у спеціальне значення \"disabled" -#~ "\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to move a window to workspace 9. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбінація клавіш переміщення вікна до робочої області з номером 9. " -#~ "Використовується формат \"<Control>a\" або \"<Shift><" -#~ "Alt>F1\". Аналізатор досить гнучкий та дозволяє використання верхнього " -#~ "та нижнього регістру та скорочень, наприклад \"<Ctl>\" та \"<" -#~ "Ctrl>\". Якщо цей параметр встановити у спеціальне значення \"disabled" -#~ "\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to move focus backwards between panels and the " -#~ "desktop, using a popup window. The format looks like \"<Control>a\" " -#~ "or \"<Shift><Alt>F1\". The parser is fairly liberal and " -#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" -#~ "\" and \"<Ctrl>\". If you set the option to the special string " -#~ "\"disabled\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "Комбінація клавіш передачі фокусу вводу у зворотному напрямку між " -#~ "панелями та робочим столом з появою меню. Використовується формат \"<" -#~ "Control>a\" або \"<Shift><Alt>F1\". Аналізатор досить " -#~ "гнучкий та дозволяє використання верхнього та нижнього регістру та " -#~ "скорочень, наприклад \"<Ctl>\" та \"<Ctrl>\". Якщо цей " -#~ "параметр встановити у спеціальне значення \"disabled\", то для цієї дії " -#~ "не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to move focus backwards between panels and the " -#~ "desktop, without a popup window. The format looks like \"<Control>a" -#~ "\" or \"<Shift><Alt>F1\". The parser is fairly liberal and " -#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" -#~ "\" and \"<Ctrl>\". If you set the option to the special string " -#~ "\"disabled\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "Комбінація клавіш передачі фокусу вводу у зворотному напрямку між " -#~ "панелями та робочим столом без появи меню. Використовується формат \"<" -#~ "Control>a\" або \"<Shift><Alt>F1\". Аналізатор досить " -#~ "гнучкий та дозволяє використання верхнього та нижнього регістру та " -#~ "скорочень, наприклад \"<Ctl>\" та \"<Ctrl>\". Якщо цей " -#~ "параметр встановити у спеціальне значення \"disabled\", то для цієї дії " -#~ "не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to move focus backwards between windows of an " -#~ "application without a popup window. Holding \"shift\" together with this " -#~ "binding makes the direction go forward again. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбінація клавіш передачі фокусу вводу у зворотному напрямку між вікнами " -#~ "без появи меню. При утримуванні \"Shift\" разом з цією комбінацією " -#~ "напрямок перемикається на прямий.Використовується формат \"<Control>" -#~ "a\" або \"<Shift><Alt>F1\". Аналізатор досить гнучкий та " -#~ "дозволяє використання верхнього та нижнього регістру та скорочень, " -#~ "наприклад \"<Ctl>\" та \"<Ctrl>\". Якщо цей параметр " -#~ "встановити у спеціальне значення \"disabled\", то для цієї дії не буде " -#~ "призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to move focus backwards between windows of an " -#~ "application, using a popup window. Holding \"shift\" together with this " -#~ "binding makes the direction go forward again. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбінація клавіш передачі фокусу вводу у зворотному напрямку між вікнами " -#~ "з появою меню. При утримуванні \"Shift\" разом з цією комбінацією " -#~ "напрямок перемикається на прямий.Використовується формат \"<Control>" -#~ "a\" або \"<Shift><Alt>F1\". Аналізатор досить гнучкий та " -#~ "дозволяє використання верхнього та нижнього регістру та скорочень, " -#~ "наприклад \"<Ctl>\" та \"<Ctrl>\". Якщо цей параметр " -#~ "встановити у спеціальне значення \"disabled\", то для цієї дії не буде " -#~ "призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to move focus backwards between windows without a " -#~ "popup window. Holding \"shift\" together with this binding makes the " -#~ "direction go forward again. The format looks like \"<Control>a\" or " -#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " -#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" -#~ "\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "Комбінація клавіш передачі фокусу вводу у зворотному напрямку між вікнами " -#~ "без появи меню. При утримуванні \"Shift\" разом з цією комбінацією " -#~ "напрямок перемикається на прямий.Використовується формат \"<Control>" -#~ "a\" або \"<Shift><Alt>F1\". Аналізатор досить гнучкий та " -#~ "дозволяє використання верхнього та нижнього регістру та скорочень, " -#~ "наприклад \"<Ctl>\" та \"<Ctrl>\". Якщо цей параметр " -#~ "встановити у спеціальне значення \"disabled\", то для цієї дії не буде " -#~ "призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to move focus backwards between windows, using a " -#~ "popup window. Holding \"shift\" together with this binding makes the " -#~ "direction go forward again. The format looks like \"<Control>a\" or " -#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " -#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" -#~ "\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "Комбінація клавіш передачі фокусу вводу у зворотному напрямку між вікнами " -#~ "з появою меню. При утримуванні \"Shift\" разом з цією комбінацією " -#~ "напрямок перемикається на прямий.Використовується формат \"<Control>" -#~ "a\" або \"<Shift><Alt>F1\". Аналізатор досить гнучкий та " -#~ "дозволяє використання верхнього та нижнього регістру та скорочень, " -#~ "наприклад \"<Ctl>\" та \"<Ctrl>\". Якщо цей параметр " -#~ "встановити у спеціальне значення \"disabled\", то для цієї дії не буде " -#~ "призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to move focus between panels and the desktop, using a " -#~ "popup window. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "Комбінація клавіш передачі фокусу вводу у прямому напрямку між панелями " -#~ "та робочим столом з появою меню. Використовується формат \"<Control>" -#~ "a\" або \"<Shift><Alt>F1\". Аналізатор досить гнучкий та " -#~ "дозволяє використання верхнього та нижнього регістру та скорочень, " -#~ "наприклад \"<Ctl>\" та \"<Ctrl>\". Якщо цей параметр " -#~ "встановити у спеціальне значення \"disabled\", то для цієї дії не буде " -#~ "призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to move focus between panels and the desktop, without " -#~ "a popup window. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "Комбінація клавіш передачі фокусу вводу у прямому напрямку між панелями " -#~ "та робочим столом без появи меню. Використовується формат \"<" -#~ "Control>a\" або \"<Shift><Alt>F1\". Аналізатор досить " -#~ "гнучкий та дозволяє використання верхнього та нижнього регістру та " -#~ "скорочень, наприклад \"<Ctl>\" та \"<Ctrl>\". Якщо цей " -#~ "параметр встановити у спеціальне значення \"disabled\", то для цієї дії " -#~ "не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to move focus between windows of an application " -#~ "without a popup window. Holding the \"shift\" key while using this " -#~ "binding reverses the direction of movement. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбінація клавіш передачі фокусу вводу у прямому напрямку між вікнами " -#~ "без появи меню. (Зазвичай це <Alt>Escape) При утримуванні \"Shift\" " -#~ "разом з цією комбінацією напрямок перемикається на зворотний." -#~ "Використовується формат \"<Control>a\" або \"<Shift><" -#~ "Alt>F1\". Аналізатор досить гнучкий та дозволяє використання верхнього " -#~ "та нижнього регістру та скорочень, наприклад \"<Ctl>\" та \"<" -#~ "Ctrl>\". Якщо цей параметр встановити у спеціальне значення \"disabled" -#~ "\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to move focus between windows of an application, " -#~ "using a popup window. (Traditionally <Alt>F6) Holding the \"shift\" " -#~ "key while using this binding reverses the direction of movement. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Комбінація клавіш передачі фокусу вводу у прямому напрямку між вікнами з " -#~ "появою меню. (Зазвичай це <Alt>Tab) При утримуванні \"Shift\" разом " -#~ "з цією комбінацією напрямок перемикається на зворотний.Використовується " -#~ "формат \"<Control>a\" або \"<Shift><Alt>F1\". " -#~ "Аналізатор досить гнучкий та дозволяє використання верхнього та нижнього " -#~ "регістру та скорочень, наприклад \"<Ctl>\" та \"<Ctrl>\". " -#~ "Якщо цей параметр встановити у спеціальне значення \"disabled\", то для " -#~ "цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to move focus between windows without a popup window. " -#~ "(Traditionally <Alt>Escape) Holding the \"shift\" key while using " -#~ "this binding reverses the direction of movement. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбінація клавіш передачі фокусу вводу у прямому напрямку між вікнами " -#~ "без появи меню. (Зазвичай це <Alt>Escape) При утримуванні \"Shift\" " -#~ "разом з цією комбінацією напрямок перемикається на зворотний." -#~ "Використовується формат \"<Control>a\" або \"<Shift><" -#~ "Alt>F1\". Аналізатор досить гнучкий та дозволяє використання верхнього " -#~ "та нижнього регістру та скорочень, наприклад \"<Ctl>\" та \"<" -#~ "Ctrl>\". Якщо цей параметр встановити у спеціальне значення \"disabled" -#~ "\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to move focus between windows, using a popup window. " -#~ "(Traditionally <Alt>Tab) Holding the \"shift\" key while using this " -#~ "binding reverses the direction of movement. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбінація клавіш передачі фокусу вводу у прямому напрямку між вікнами з " -#~ "появою меню. (Зазвичай це <Alt>Tab) При утримуванні \"Shift\" разом " -#~ "з цією комбінацією напрямок перемикається на зворотний.Використовується " -#~ "формат \"<Control>a\" або \"<Shift><Alt>F1\". " -#~ "Аналізатор досить гнучкий та дозволяє використання верхнього та нижнього " -#~ "регістру та скорочень, наприклад \"<Ctl>\" та \"<Ctrl>\". " -#~ "Якщо цей параметр встановити у спеціальне значення \"disabled\", то для " -#~ "цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to toggle always on top. A window that is always on " -#~ "top will always be visible over other overlapping windows. The format " -#~ "looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -#~ "parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Комбінація клавіш перемикання стану чи показувати вікно завжди на верху. " -#~ "Використовується формат \"<Control>a\" або \"<Shift><" -#~ "Alt>F1\". Аналізатор досить гнучкий та дозволяє використання верхнього " -#~ "та нижнього регістру та скорочень, наприклад \"<Ctl>\" та \"<" -#~ "Ctrl>\". Якщо цей параметр встановити у спеціальне значення \"disabled" -#~ "\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to toggle fullscreen mode. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбінація клавіш перемикання у повноекранний режим. Використовується " -#~ "формат \"<Control>a\" або \"<Shift><Alt>F1\". " -#~ "Аналізатор досить гнучкий та дозволяє використання верхнього та нижнього " -#~ "регістру та скорочень, наприклад \"<Ctl>\" та \"<Ctrl>\". " -#~ "Якщо цей параметр встановити у спеціальне значення \"disabled\", то для " -#~ "цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to toggle maximization. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбінація клавіш перемикання розгортання вікна. Використовується формат " -#~ "\"<Control>a\" або \"<Shift><Alt>F1\". Аналізатор " -#~ "достатньо гнучкий та дозволяє використання верхнього та нижнього регістру " -#~ "та скорочень, наприклад \"<Ctl>\" та \"<Ctrl>\". Якщо цей " -#~ "параметр встановити у спеціальне значення \"disabled\", то для цієї дії " -#~ "не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to toggle shaded/unshaded state. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбінація клавіш перемикання стану згорнутості. Використовується формат " -#~ "\"<Control>a\" або \"<Shift><Alt>F1\". Аналізатор " -#~ "досить гнучкий та дозволяє використання верхнього та нижнього регістру та " -#~ "скорочень, наприклад \"<Ctl>\" та \"<Ctrl>\". Якщо цей " -#~ "параметр встановити у спеціальне значення \"disabled\", то для цієї дії " -#~ "не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding used to toggle whether the window is on all workspaces or " -#~ "just one. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Комбінація клавіш перемикання стану чи показувати вікно на усіх робочих " -#~ "областях, чи лише на одній. Використовується формат \"<Control>a\" " -#~ "або \"<Shift><Alt>F1\". Аналізатор досить гнучкий та дозволяє " -#~ "використання верхнього та нижнього регістру та скорочень, наприклад \"<" -#~ "Ctl>\" та \"<Ctrl>\". Якщо цей параметр встановити у спеціальне " -#~ "значення \"disabled\", то для цієї дії не буде призначено комбінації " -#~ "клавіш." - -#~ msgid "" -#~ "The keybinding used to unmaximize a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбінація клавіш перемикання розгортання вікна на весь екран. " -#~ "Використовується формат \"<Control>a\" або \"<Shift><" -#~ "Alt>F1\". Аналізатор досить гнучкий та дозволяє використання верхнього " -#~ "та нижнього регістру та скорочень, наприклад \"<Ctl>\" та \"<" -#~ "Ctrl>\". Якщо цей параметр встановити у спеціальне значення \"disabled" -#~ "\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding which display's the panel's \"Run Application\" dialog " -#~ "box. The format looks like \"<Control>a\" or \"<Shift><" -#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If " -#~ "you set the option to the special string \"disabled\", then there will be " -#~ "no keybinding for this action." -#~ msgstr "" -#~ "Комбінація клавіш, що викликає діалог панелі для запуску програм. " -#~ "Використовується формат \"<Control>a\" або \"<Shift><" -#~ "Alt>F1\". Аналізатор досить гнучкий та дозволяє використання верхнього " -#~ "та нижнього регістру та скорочень, наприклад \"<Ctl>\" та \"<" -#~ "Ctrl>\". Якщо цей параметр встановити у спеціальне значення \"disabled" -#~ "\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding which invokes a terminal. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Комбінація клавіш, що запускає термінал. Використовується формат \"<" -#~ "Control>a\" або \"<Shift><Alt>F1\". Аналізатор досить " -#~ "гнучкий та дозволяє використання верхнього і нижнього регістру та " -#~ "скорочень, наприклад \"<Ctl>\" та \"<Ctrl>\". Якщо цей " -#~ "параметр встановити у спеціальне значення \"disabled\", то для цієї дії " -#~ "не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding which invokes the panel's screenshot utility to take a " -#~ "screenshot of a window. The format looks like \"<Control>a\" or " -#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " -#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" -#~ "\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "Комбінація клавіш, що викликає утиліту панелі для створення знімку вікна. " -#~ "Використовується формат \"<Control>a\" або \"<Shift><" -#~ "Alt>F1\". Аналізатор досить гнучкий та дозволяє використання верхнього " -#~ "та нижнього регістру та скорочень, наприклад \"<Ctl>\" та \"<" -#~ "Ctrl>\". Якщо цей параметр встановити у спеціальне значення \"disabled" -#~ "\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding which invokes the panel's screenshot utility. The format " -#~ "looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -#~ "parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Комбінація клавіш, що викликає утиліту панелі для створення знімку " -#~ "екрана. Використовується формат \"<Control>a\" або \"<Shift>" -#~ "<Alt>F1\". Аналізатор досить гнучкий та дозволяє використання " -#~ "верхнього та нижнього регістру та скорочень, наприклад \"<Ctl>\" та " -#~ "\"<Ctrl>\". Якщо цей параметр встановити у спеціальне значення " -#~ "\"disabled\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "The keybinding which shows the panel's main menu. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбінація клавіш, що показує головне меню панелі. Використовується " -#~ "формат \"<Control>a\" або \"<Shift><Alt>F1\". " -#~ "Аналізатор досить гнучкий та дозволяє використання верхнього і нижнього " -#~ "регістру та скорочень, наприклад \"<Ctl>\" та \"<Ctrl>\". " -#~ "Якщо цей параметр встановити у спеціальне значення \"disabled\", то для " -#~ "цієї дії не буде призначено комбінації клавіш." - -#~ msgid "The name of a workspace." -#~ msgstr "Назва робочої області" - -#~ msgid "The screenshot command" -#~ msgstr "Команда створення знімку екрану" - -#~ msgid "" -#~ "The theme determines the appearance of window borders, titlebar, and so " -#~ "forth." -#~ msgstr "Тема визначає вигляд рамки вікна, заголовку та таке інше." - -#~ msgid "" -#~ "The time delay before raising a window if auto_raise is set to true. The " -#~ "delay is given in thousandths of a second." -#~ msgstr "" -#~ "Затримка перед підніманням вікна, якщо встановлено параметр auto_raise. " -#~ "Затримка вказується у тисячних долях секунди." - -#~ msgid "" -#~ "The window focus mode indicates how windows are activated. It has three " -#~ "possible values; \"click\" means windows must be clicked in order to " -#~ "focus them, \"sloppy\" means windows are focused when the mouse enters " -#~ "the window, and \"mouse\" means windows are focused when the mouse enters " -#~ "the window and unfocused when the mouse leaves the window." -#~ msgstr "" -#~ "Режим передачі фокусу вікна визначає як слід активувати вікно. Можливі " -#~ "три значення \"click\" означає, що для передачі фокусу вікну потрібно " -#~ "клацнути по ньому; \"sloppy\" означає, що вікно отримуватиме фокус коли " -#~ "вказівник миші входить у межі вікна; \"mouse\" означає, що вікно " -#~ "отримуватиме фокус коли вказівник миші входить у межі вікна і втрачає " -#~ "фокус, коли виходить з вікна;" - -#~ msgid "The window screenshot command" -#~ msgstr "Команда створення знімку вікна" - -#~ msgid "" -#~ "This keybinding changes whether a window is above or below other windows. " -#~ "If the window is covered by another one, it raises the window above all " -#~ "others, and if the window is already fully visible, it lowers it below " -#~ "all others. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Комбінація клавіш що визначає, чи вікно розташовується над чи під іншими " -#~ "вікнами. Якщо вікно перекрите іншим вікном, вона піднімає вікно над " -#~ "іншими вікнами. Якщо вікно не перекрите ніякими вікнами - опускає нижче " -#~ "інших вікон. Використовується формат \"<Control>a\" або \"<" -#~ "Shift><Alt>F1\". Аналізатор досить гнучкий та дозволяє " -#~ "використання верхнього та нижнього регістру та скорочень, наприклад \"<" -#~ "Ctl>\" та \"<Ctrl>\". Якщо цей параметр встановити у спеціальне " -#~ "значення \"disabled\", то для цієї дії не буде призначено комбінації " -#~ "клавіш." - -#~ msgid "" -#~ "This keybinding lowers a window below other windows. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбінація клавіш, що опускає вікно нижче інших вікон. Використовується " -#~ "формат \"<Control>a\" або \"<Shift><Alt>F1\". " -#~ "Аналізатор досить гнучкий та дозволяє використання верхнього та нижнього " -#~ "регістру та скорочень, наприклад \"<Ctl>\" та \"<Ctrl>\". " -#~ "Якщо цей параметр встановити у спеціальне значення \"disabled\", то для " -#~ "цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "This keybinding moves a window against the north (top) side of the " -#~ "screen. The format looks like \"<Control>a\" or \"<Shift><" -#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If " -#~ "you set the option to the special string \"disabled\", then there will be " -#~ "no keybinding for this action." -#~ msgstr "" -#~ "Комбінація клавіш, що переміщує вікно до північного (верхнього) боку " -#~ "екрану. Використовується формат \"<Control>a\" або \"<Shift>" -#~ "<Alt>F1\". Аналізатор досить гнучкий та дозволяє використання " -#~ "верхнього та нижнього регістру та скорочень, наприклад \"<Ctl>\" та " -#~ "\"<Ctrl>\". Якщо цей параметр встановити у спеціальне значення " -#~ "\"disabled\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "This keybinding moves a window into the east (right) side of the screen. " -#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>" -#~ "F1\". The parser is fairly liberal and allows lower or upper case, and " -#~ "also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -#~ "set the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Комбінація клавіш, що переміщує вікно до східного (правого) боку екрану. " -#~ "Використовується формат \"<Control>a\" або \"<Shift><" -#~ "Alt>F1\". Аналізатор досить гнучкий та дозволяє використання верхнього " -#~ "та нижнього регістру та скорочень, наприклад \"<Ctl>\" та \"<" -#~ "Ctrl>\". Якщо цей параметр встановити у спеціальне значення \"disabled" -#~ "\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "This keybinding moves a window into the north-east (top right) corner of " -#~ "the screen. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Комбінація клавіш, що переміщує вікно у північно-східний (верхній правий) " -#~ "кут екрану. Використовується формат \"<Control>a\" або \"<" -#~ "Shift><Alt>F1\". Аналізатор досить гнучкий та дозволяє " -#~ "використання верхнього та нижнього регістру та скорочень, наприклад \"<" -#~ "Ctl>\" та \"<Ctrl>\". Якщо цей параметр встановити у спеціальне " -#~ "значення \"disabled\", то для цієї дії не буде призначено комбінації " -#~ "клавіш." - -#~ msgid "" -#~ "This keybinding moves a window into the north-west (top left) corner of " -#~ "the screen. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Комбінація клавіш, що переміщує вікно у північно-західний (верхній лівий) " -#~ "кут екрану. Використовується формат \"<Control>a\" або \"<" -#~ "Shift><Alt>F1\". Аналізатор досить гнучкий та дозволяє " -#~ "використання верхнього та нижнього регістру та скорочень, наприклад \"<" -#~ "Ctl>\" та \"<Ctrl>\". Якщо цей параметр встановити у спеціальне " -#~ "значення \"disabled\", то для цієї дії не буде призначено комбінації " -#~ "клавіш." - -#~ msgid "" -#~ "This keybinding moves a window into the south (bottom) side of the " -#~ "screen. The format looks like \"<Control>a\" or \"<Shift><" -#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If " -#~ "you set the option to the special string \"disabled\", then there will be " -#~ "no keybinding for this action." -#~ msgstr "" -#~ "Комбінація клавіш, що переміщує вікно до південного (нижнього) боку " -#~ "екрану. Використовується формат \"<Control>a\" або \"<Shift>" -#~ "<Alt>F1\". Аналізатор досить гнучкий та дозволяє використання " -#~ "верхнього та нижнього регістру та скорочень, наприклад \"<Ctl>\" та " -#~ "\"<Ctrl>\". Якщо цей параметр встановити у спеціальне значення " -#~ "\"disabled\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "This keybinding moves a window into the south-east (bottom right) corner " -#~ "of the screen. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "Комбінація клавіш, що переміщує вікно у південно-східний (нижній правий) " -#~ "кут екрану. Використовується формат \"<Control>a\" або \"<" -#~ "Shift><Alt>F1\". Аналізатор досить гнучкий та дозволяє " -#~ "використання верхнього та нижнього регістру та скорочень, наприклад \"<" -#~ "Ctl>\" та \"<Ctrl>\". Якщо цей параметр встановити у спеціальне " -#~ "значення \"disabled\", то для цієї дії не буде призначено комбінації " -#~ "клавіш." - -#~ msgid "" -#~ "This keybinding moves a window into the south-west (bottom left) corner " -#~ "of the screen. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "Комбінація клавіш, що переміщує вікно у південно-західний (нижній лівий) " -#~ "кут екрану. Використовується формат \"<Control>a\" або \"<" -#~ "Shift><Alt>F1\". Аналізатор досить гнучкий та дозволяє " -#~ "використання верхнього та нижнього регістру та скорочень, наприклад \"<" -#~ "Ctl>\" та \"<Ctrl>\". Якщо цей параметр встановити у спеціальне " -#~ "значення \"disabled\", то для цієї дії не буде призначено комбінації " -#~ "клавіш." - -#~ msgid "" -#~ "This keybinding moves a window into the west (left) side of the screen. " -#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>" -#~ "F1\". The parser is fairly liberal and allows lower or upper case, and " -#~ "also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -#~ "set the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Комбінація клавіш, що переміщує вікно на східну (ліву) сторону екрану. " -#~ "Використовується формат \"<Control>a\" або \"<Shift><" -#~ "Alt>F1\". Аналізатор досить гнучкий та дозволяє використання верхнього " -#~ "та нижнього регістру та скорочень, наприклад \"<Ctl>\" та \"<" -#~ "Ctrl>\". Якщо цей параметр встановити у спеціальне значення \"disabled" -#~ "\", то для цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "This keybinding raises the window above other windows. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Комбінація клавіш, що піднімає вікно над іншими вікнами. Використовується " -#~ "формат \"<Control>a\" або \"<Shift><Alt>F1\". " -#~ "Аналізатор досить гнучкий та дозволяє використання верхнього та нижнього " -#~ "регістру та скорочень, наприклад \"<Ctl>\" та \"<Ctrl>\". " -#~ "Якщо цей параметр встановити у спеціальне значення \"disabled\", то для " -#~ "цієї дії не буде призначено комбінації клавіш." - -#~ msgid "" -#~ "This keybinding resizes a window to fill available horizontal space. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Комбінація клавіш, що змінює розмір вікна, щоб заповнити весь " -#~ "горизонтальний простір. Використовується формат \"<Control>a\" або " -#~ "\"<Shift><Alt>F1\". Аналізатор досить гнучкий та дозволяє " -#~ "використання верхнього та нижнього регістру та скорочень, наприклад \"<" -#~ "Ctl>\" та \"<Ctrl>\". Якщо цей параметр встановити у спеціальне " -#~ "значення \"disabled\", то для цієї дії не буде призначено комбінації " -#~ "клавіш." - -#~ msgid "" -#~ "This keybinding resizes a window to fill available vertical space. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Комбінація клавіш, що змінює розмір вікна, щоб заповнити весь " -#~ "вертикальний простір. Використовується формат \"<Control>a\" або " -#~ "\"<Shift><Alt>F1\". Аналізатор досить гнучкий та дозволяє " -#~ "використання верхнього та нижнього регістру та скорочень, наприклад \"<" -#~ "Ctl>\" та \"<Ctrl>\". Якщо цей параметр встановити у спеціальне " -#~ "значення \"disabled\", то для цієї дії не буде призначено комбінації " -#~ "клавіш." - -#~ msgid "" -#~ "This option determines the effects of double-clicking on the title bar. " -#~ "Current valid options are 'toggle_shade', which will shade/unshade the " -#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " -#~ "will maximize/unmaximize the window in that direction only, 'minimize' " -#~ "which will minimize the window, 'shade' which will roll the window up, " -#~ "'menu' which will display the window menu, 'lower' which will put the " -#~ "window behind all the others, and 'none' which will not do anything." -#~ msgstr "" -#~ "Цей параметр визначає ефект від подвійного клацання по заголовку вікна. " -#~ "Поточними можливими значеннями є 'toggle_shade' - перемикає тіньовий стан " -#~ "вікна, 'toggle_maximize' - розгортає та відновлює вікно, " -#~ "'toggle_maximize_horizontally' та 'toggle_maximize_vertically' - " -#~ "розгортання/згортання вікна лише у цьому напрямку, 'minimize' - згортання " -#~ "вікна, 'shade'- згортання вікна вгору, 'menu' - відображення меню вікна, " -#~ "'lower' - переміщенні вікна на самий нижній рівень, під усі вікна, та " -#~ "'none' - немає дії." - -#~ msgid "" -#~ "This option determines the effects of middle-clicking on the title bar. " -#~ "Current valid options are 'toggle_shade', which will shade/unshade the " -#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " -#~ "will maximize/unmaximize the window in that direction only, 'minimize' " -#~ "which will minimize the window, 'shade' which will roll the window up, " -#~ "'menu' which will display the window menu, 'lower' which will put the " -#~ "window behind all the others, and 'none' which will not do anything." -#~ msgstr "" -#~ "Цей параметр визначає ефект від клацання середньою кнопкою по заголовку " -#~ "вікна. Поточними можливими значеннями є 'toggle_shade' - перемикає " -#~ "тіньовий стан вікна, 'toggle_maximize' - розгортає та відновлює вікно, " -#~ "'toggle_maximize_horizontally' та 'toggle_maximize_vertically' - " -#~ "розгортання/згортання вікна лише у цьому напрямку, 'minimize' - згортання " -#~ "вікна, 'shade'- згортання вікна вгору, 'menu' - відображення меню вікна, " -#~ "'lower' - переміщенні вікна на самий нижній рівень, під усі вікна, та " -#~ "'none' - немає дії." - -#~ msgid "" -#~ "This option determines the effects of right-clicking on the title bar. " -#~ "Current valid options are 'toggle_shade', which will shade/unshade the " -#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " -#~ "will maximize/unmaximize the window in that direction only, 'minimize' " -#~ "which will minimize the window, 'shade' which will roll the window up, " -#~ "'menu' which will display the window menu, 'lower' which will put the " -#~ "window behind all the others, and 'none' which will not do anything." -#~ msgstr "" -#~ "Цей параметр визначає ефект від клацання правою кнопкою по заголовку " -#~ "вікна. Поточними можливими значеннями є 'toggle_shade' - перемикає " -#~ "тіньовий стан вікна, 'toggle_maximize' - розгортає та відновлює вікно, " -#~ "'toggle_maximize_horizontally' та 'toggle_maximize_vertically' - " -#~ "розгортання/згортання вікна лише у цьому напрямку, 'minimize' - згортання " -#~ "вікна, 'shade'- згортання вікна вгору, 'menu' - відображення меню вікна, " -#~ "'lower' - переміщенні вікна на самий нижній рівень, під усі вікна, та " -#~ "'none' - немає дії." - -#~ msgid "" -#~ "This option provides additional control over how newly created windows " -#~ "get focus. It has two possible values; \"smart\" applies the user's " -#~ "normal focus mode, and \"strict\" results in windows started from a " -#~ "terminal not being given focus." -#~ msgstr "" -#~ "Цей параметр надає додаткове керування тим, як нові вікна отримують " -#~ "фокус. Він має два можливих значення. Значення \"smart\" застосовує " -#~ "звичайний режим фокусу користувача, а \"strict\" призводить до того, що " -#~ "запущені з терміналу вікна, не отримують фокус." - -#~ msgid "Toggle always on top state" -#~ msgstr "Перемикання стану завжди на верху" - -#~ msgid "" -#~ "Turns on a visual indication when an application or the system issues a " -#~ "'bell' or 'beep'; useful for the hard-of-hearing and for use in noisy " -#~ "environments." -#~ msgstr "" -#~ "Увімкнути візуальну індикацію системного гудка, корисно для людей з " -#~ "вадами слуху, чи у шумному середовищі." - -#~ msgid "Unmaximize window" -#~ msgstr "Відновити попередній розмір вікна вікна" - -#~ msgid "Use standard system font in window titles" -#~ msgstr "Використання стандартного шрифту у заголовках вікон" - -#~ msgid "Visual Bell Type" -#~ msgstr "Тип візуального гудка" - -#~ msgid "Whether raising should be a side-effect of other user interactions" -#~ msgstr "Чи піднімання вікна має бути побічним ефектом інших дій користувача" - -#~ msgid "Window focus mode" -#~ msgstr "Режим отримання фокусу вікном" - -#~ msgid "Window title font" -#~ msgstr "Шрифт заголовка вікна" - -#~ msgid "Unmaximize Window" -#~ msgstr "Відновити попередній розмір" - -#~ msgid "Title" -#~ msgstr "Заголовок" - -#~ msgid "Class" -#~ msgstr "Клас" - -#~ msgid "No \"%s\" attribute on <%s> element" -#~ msgstr "Немає ознаки \"%s\" елементі <%s>" - -#~ msgid "Theme already has a fallback icon" -#~ msgstr "Тема вже містить запасний значок" - -#~ msgid "Theme already has a fallback mini_icon" -#~ msgstr "Тема вже містить аварійний міні_значок" - -#~ msgid "No \"name\" attribute on element <%s>" -#~ msgstr "Немає ознаки \"name\" елементі <%s>" - -#~ msgid "No \"value\" attribute on element <%s>" -#~ msgstr "Немає ознаки \"value\" у елементі <%s>" - -#~ msgid "No \"top\" attribute on element <%s>" -#~ msgstr "Немає ознаки \"top\" у елементі <%s>" - -#~ msgid "No \"bottom\" attribute on element <%s>" -#~ msgstr "Немає ознаки \"bottom\" у елементі <%s>" - -#~ msgid "No \"left\" attribute on element <%s>" -#~ msgstr "Немає ознаки \"left\" у елементі <%s>" - -#~ msgid "No \"right\" attribute on element <%s>" -#~ msgstr "Немає ознаки \"right\" у елементі <%s>" - -#~ msgid "No \"color\" attribute on element <%s>" -#~ msgstr "Немає ознаки \"color\" у елементі <%s>" - -#~ msgid "No \"x1\" attribute on element <%s>" -#~ msgstr "Немає ознаки \"x1\" у елементі <%s>" - -#~ msgid "No \"y1\" attribute on element <%s>" -#~ msgstr "Немає ознаки \"y1\" у елементі <%s>" - -#~ msgid "No \"x2\" attribute on element <%s>" -#~ msgstr "Немає ознаки \"x2\" у елементі <%s>" - -#~ msgid "No \"y2\" attribute on element <%s>" -#~ msgstr "Немає ознаки \"y2\" у елементі <%s>" - -#~ msgid "No \"y\" attribute on element <%s>" -#~ msgstr "Немає ознаки \"y\" у елементі <%s>" - -#~ msgid "No \"width\" attribute on element <%s>" -#~ msgstr "Немає ознаки \"width\" у елементі <%s>" - -#~ msgid "No \"height\" attribute on element <%s>" -#~ msgstr "Немає ознаки \"height\" у елементі <%s>" - -#~ msgid "No \"start_angle\" attribute on element <%s>" -#~ msgstr "Немає ознаки \"start_angle\" у елементі <%s>" - -#~ msgid "No \"extent_angle\" attribute on element <%s>" -#~ msgstr "Немає ознаки \"extent_angle\" у елементі <%s>" - -#~ msgid "No \"alpha\" attribute on element <%s>" -#~ msgstr "Немає ознаки \"alpha\" у елементі <%s>" - -#~ msgid "No \"type\" attribute on element <%s>" -#~ msgstr "Немає ознаки \"type\" у елементі <%s>" - -#~ msgid "No \"filename\" attribute on element <%s>" -#~ msgstr "Немає ознаки \"filename\" у елементі <%s>" - -#~ msgid "No \"state\" attribute on element <%s>" -#~ msgstr "Немає ознаки \"state\" у елементі <%s>" - -#~ msgid "No \"shadow\" attribute on element <%s>" -#~ msgstr "Немає ознаки \"shadow\" у елементі <%s>" - -#~ msgid "No \"arrow\" attribute on element <%s>" -#~ msgstr "Немає ознаки \"arrow\" елементі <%s>" - -#~ msgid "No \"value\" attribute on <%s> element" -#~ msgstr "Немає ознаки \"value\" елементі <%s>" - -#~ msgid "No \"position\" attribute on <%s> element" -#~ msgstr "Немає ознаки \"position\" елементі <%s>" - -#~ msgid "No \"function\" attribute on <%s> element" -#~ msgstr "Немає ознаки \"function\" елементі <%s>" - -#~ msgid "No \"state\" attribute on <%s> element" -#~ msgstr "Немає ознаки \"state\" елементі <%s>" - -#~ msgid "No \"focus\" attribute on <%s> element" -#~ msgstr "Немає ознаки \"focus\" елементі <%s>" - -#~ msgid "No \"style\" attribute on <%s> element" -#~ msgstr "Немає ознаки \"style\" елементі <%s>" - -#~ msgid "No \"resize\" attribute on <%s> element" -#~ msgstr "Немає ознаки \"resize\" у елементі <%s>" - -#~ msgid "<author> specified twice for this theme" -#~ msgstr "<author> в цій темі вказано двічі" - -#~ msgid "<copyright> specified twice for this theme" -#~ msgstr "<copyright> в цій темі вказано двічі" - -#~ msgid "<date> specified twice for this theme" -#~ msgstr "<date> в цій темі вказано двічі" - -#~ msgid "<description> specified twice for this theme" -#~ msgstr "<description> в цій темі вказано двічі" - -#~ msgid "Theme file %s did not contain a root <metacity_theme> element" -#~ msgstr "Файл теми %s не містить елемента <metacity_theme>" - -#~ msgid "/Windows/tearoff" -#~ msgstr "/Вікна/відрив" - -#~ msgid "/Windows/_Dialog" -#~ msgstr "/Вікна/_Діалог" - -#~ msgid "/Windows/_Modal dialog" -#~ msgstr "/Вікна/_Модальний діалог" - -#~ msgid "/Windows/Des_ktop" -#~ msgstr "/Вікна/_Робочий стіл" +msgid "%s (on %s)" +msgstr "%s (на %s)" diff --git a/po/vi.po b/po/vi.po index 2dfde94e0..b632ee389 100644 --- a/po/vi.po +++ b/po/vi.po @@ -1,441 +1,287 @@ # Vietnamese translation for Metacity. -# Copyright © 2009 GNOME i18n Project for Vietnamese. -# Nguyễn Thái Ngọc Duy <pclouds@gmail.com>, 2002-2004, 2007, 2008, 2011-2012. +# Copyright © 2016 GNOME i18n Project for Vietnamese. +# This file is distributed under the same license as the Metacity package. +# Nguyễn Thái Ngọc Duy <pclouds@gmail.com>, 2002-2004, 2007, 2008, 2011-2013. # Clytie Siddall <clytie@riverland.net.au>, 2005-2009. +# Trần Ngọc Quân <vnwildman@gmail.com>, 2014, 2015, 2016, 2017, 2018, 2019. # msgid "" msgstr "" -"Project-Id-Version: metacity GNOME 2.26\n" -"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" -"product=muffin&keywords=I18N+L10N&component=general\n" -"POT-Creation-Date: 2012-03-15 21:29+0000\n" -"PO-Revision-Date: 2012-03-22 10:45+0700\n" -"Last-Translator: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n" -"Language-Team: Vietnamese <vi-VN@googlegroups.com>\n" +"Project-Id-Version: metacity master\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2019-08-27 21:40+0000\n" +"PO-Revision-Date: 2019-08-28 14:04+0700\n" +"Last-Translator: Trần Ngọc Quân <vnwildman@gmail.com>\n" +"Language-Team: Vietnamese <gnome-vi-list@gnome.org>\n" +"Language: vi\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Language: vi\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: LocFactoryEditor 1.8\n" - -#: ../src/50-muffin-windows.xml.in.h:1 -msgid "Windows" -msgstr "Cửa sổ" - -#: ../src/50-muffin-windows.xml.in.h:2 -msgid "View split on left" -msgstr "Phân đôi bên trái" - -#: ../src/50-muffin-windows.xml.in.h:3 -msgid "View split on right" -msgstr "Phân đôi bên phải" - -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format -msgid "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." -msgstr "" -"Bộ quản lý cửa sổ đã đang chạy trên Màn hình %i trên bộ trình bày \"%s\"" - -#: ../src/core/bell.c:307 -msgid "Bell event" -msgstr "Sự kiện chuông" +"X-Generator: Gtranslator 2.91.7\n" -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "Yêu cầu thông tin cửa sổ không rõ: %d" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Điều hướng" -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> không trả lời." +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Chuyển cửa sổ sang không gian làm việc 1" -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "Ứng dụng không trả lời." +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Chuyển cửa sổ sang không gian làm việc 2" -#: ../src/core/delete.c:119 -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "Bạn có thể chọn chờ một lúc trước khi buộc chấm dứt ứng dụng." +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Chuyển cửa sổ sang không gian làm việc 3" -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "_Chờ" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Chuyển cửa sổ sang không gian làm việc 4" -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "_Buộc thoát" +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Chuyển cửa sổ sang không gian làm việc cuối" -#: ../src/core/display.c:387 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "Thiếu phần mở rộng %s cần thiết để tổng hợp" +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "Chuyển cửa sổ lên một không gian làm việc" -#: ../src/core/display.c:453 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "Lỗi mở bộ trình bày Hệ thống Cửa sổ X \"%s\".\n" +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "Chuyển cửa sổ xuống một không gian làm việc" -#: ../src/core/keybindings.c:852 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "" -"Một chương trình khác đã dùng phím « %s » với phím bổ trợ «%x» như là tổ " -"hợp.\n" +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "Chuyển cửa sổ sang trái một màn hình" -#: ../src/core/main.c:206 -msgid "Disable connection to session manager" -msgstr "Vô hiệu hóa kết nối với bộ quản lý phiên làm việc" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "Chuyển cửa sổ sang phải một màn hình" -#: ../src/core/main.c:212 -msgid "Replace the running window manager" -msgstr "Thay thế bộ quản lý cửa sổ đang chạy" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "Chuyển cửa sổ lên một màn hình" -#: ../src/core/main.c:218 -msgid "Specify session management ID" -msgstr "Ghi rõ ID quản lý phiên làm việc" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "Chuyển cửa sổ xuống một màn hình" -#: ../src/core/main.c:223 -msgid "X Display to use" -msgstr "Bộ trình bày X cần dùng" +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "Chuyển ứng dụng" -#: ../src/core/main.c:229 -msgid "Initialize session from savefile" -msgstr "Khởi động phiên làm việc từ tập tin lưu" +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "Chuyển sang ứng dụng kế trước" -#: ../src/core/main.c:235 -msgid "Make X calls synchronous" -msgstr "Khiến các lời gọi X đồng bộ với nhau" +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "Chuyển cửa sổ" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "Lỗi quét thư mục sắc thái: %s\n" +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "Chuyển sang cửa sổ kế trước" -#: ../src/core/main.c:520 -#, c-format -msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "" -"Không tìm thấy sắc thái. Hãy bảo đảm %s tồn tại và chứa những sắc thái bình " -"thường.\n" +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "Chuyển cửa sổ của một ứng dụng" -#: ../src/core/muffin.c:40 -#, c-format -msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" -"muffin %s\n" -"Tác quyền © 2001-%d của Havoc Pennington, Red Hat, Inc., và những người " -"khác.\n" -"Chương trình này là phần mềm tự do; xem mã nguồn để tìm điều kiện sao chép.\n" -"KHÔNG CÓ BẢO HÀNH GÌ CẢ, THẬM CHÍ KHÔNG CÓ BẢO ĐẢM ĐƯỢC NGỤ Ý KHẢ NĂNG BÁN " -"HAY KHẢ NĂNG LÀM ĐƯỢC VIỆC DỨT KHOÁT.\n" +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "Chuyển sang cửa sổ kế trước của một ứng dụng" -#: ../src/core/muffin.c:54 -msgid "Print version" -msgstr "In phiên bản" +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "Chuyển điều khiển hệ thống" -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "Danh sách phần bổ sung tổng hợp cách nhau bằng dấu phẩy" +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "Chuyển đến điều khiển hệ thống kế trước" -#: ../src/core/prefs.c:1077 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "" -"Khả năng chỉnh sửa cho các ứng dụng không theo chuẩn đã đã tắt. Vài ứng dụng " -"có thể sẽ xử sự không đúng.\n" +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "Chuyển cửa sổ trực tiếp" -#: ../src/core/prefs.c:1152 -#, c-format -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "Không thể phân tích mô tả phông \"%s\" từ khóa GSettings \"%s\"\n" +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "Chuyển trực tiếp đến cửa sổ kế trước" -#: ../src/core/prefs.c:1218 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "" -"Tìm thấy « %s » trong cơ sở dữ liệu cấu hình không phải giá trị hợp lệ cho " -"bộ biến đổi nút chuột.\n" +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "Chuyển trực tiếp cửa sổ của một ứng dụng" -#: ../src/core/prefs.c:1739 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "" -"Tìm thấy « %s » trong cơ sở dữ liệu cấu hình không phải giá trị hợp lệ cho " -"tổ hợp phím « %s ».\n" +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "Chuyển trực tiếp đến cửa sổ kế trước của một ứng dụng" -#: ../src/core/prefs.c:1836 -#, c-format -msgid "Workspace %d" -msgstr "Vùng làm việc %d" +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "Chuyển điều khiển hệ thống trực tiếp" -#: ../src/core/screen.c:730 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "Màn hình %d trên bộ trình bày « %s » không hợp lệ.\n" +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "Chuyển trực tiếp đến điều khiển hệ thống kế trước" -#: ../src/core/screen.c:746 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"Màn hình %d trên bộ trình bày « %s » đã có bộ quản lý cửa sổ rồi; hãy thử " -"dùng tùy chọn «--replace» để _thay thế_ bộ quản lý cửa sổ đang dùng.\n" +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "Ẩn mọi cửa sổ thường" -#: ../src/core/screen.c:773 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "" -"Không thể lấy vùng chọn bộ quản lý cửa sổ trên Màn hình %d trên bộ trình bày " -"« %s ».\n" +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "Chuyển sang không gian làm việc 1" -#: ../src/core/screen.c:828 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "Màn hình %d trên bộ trình bày « %s » đã có bộ quản lý cửa sổ.\n" +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "Chuyển sang không gian làm việc 2" -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "Không thể giải phóng Màn hình %d trên bộ trình bày « %s ».\n" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "Chuyển sang không gian làm việc 3" -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "Không thể tạo thư mục « %s »: %s\n" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "Chuyển sang không gian làm việc 4" -#: ../src/core/session.c:854 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "Không thể mở tập tin phiên làm việc « %s » để ghi: %s\n" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "Chuyển sang không gian làm việc cuối" -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "Gặp lỗi khi ghi tập tin phiên làm việc « %s »: %s\n" +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "Chuyển sang không gian làm việc trên" -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "Gặp lỗi khi đóng tập tin phiên làm việc « %s »: %s\n" +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "Chuyển sang không gian làm việc dưới" -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "Lỗi phân tích tập tin phiên làm việc đã lưu: %s\n" +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "Hệ thống" -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "Thấy thuộc tính <muffin_session>, nhưng đã có session ID" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Hiện dấu nhắc dòng lệnh" -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "Không nhận ra thuộc tính %s trên phần tử <%s>" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "Hiện tổng quan hoạt động" -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "thẻ <window> lồng nhau" +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Hoàn nguyên lại các phím tắt" -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "Phần tử lạ « %s »" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Cửa sổ" -#: ../src/core/session.c:1809 -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" -"Những cửa sổ này không hỗ trợ "lưu thiết lập hiện thời" và sẽ phải " -"khởi động lại bằng tay lần kế bạn đăng nhập." +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "Kích hoạt trình đơn cửa sổ" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "Lỗi mở bản ghi gỡ lỗi: %s\n" +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Bật/tắt toàn màn hình" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "Lỗi fdopen() tập tin ghi lưu %s: %s\n" +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "Bật/tắt trạng thái to hết cỡ" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "Đã mở tập tin ghi lưu %s.\n" +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "Phóng to cửa sổ hết cỡ" -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "Muffin đã được biên dịch không hỗ trợ chế độ chi tiết\n" +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Phục hồi cửa sổ" -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "Bộ quản lý cửa sổ: " +#: data/50-mutter-windows.xml:18 +msgid "Close window" +msgstr "Đóng cửa sổ" -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "Lỗi trong bộ quản lý cửa sổ: " +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "Ẩn cửa sổ" -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "Cảnh báo bộ quản lý cửa sổ: " +#: data/50-mutter-windows.xml:22 +msgid "Move window" +msgstr "Di chuyển cửa sổ" -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "Lỗi bộ quản lý cửa sổ: " +#: data/50-mutter-windows.xml:24 +msgid "Resize window" +msgstr "Co giãn cửa sổ" -#. first time through -#: ../src/core/window.c:7269 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"Cửa sổ « %s » tự đặt « SM_CLIENT_ID » cho chính nó, thay vì đặt trên cửa sổ " -"« WM_CLIENT_LEADER » như quy định trong ICCCM.\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7932 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size " -"%d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"Cửa sổ %s đặt gợi ý MWM rằng nó không thể bị thay đổi kích thước, nhưng đặt " -"kích thước tối thiểu %d x %d và tối đa %d x %d; không hợp lý lắm.\n" +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "Dùng cửa sổ trên một/mọi không gian làm việc" -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "Ứng dụng đã đặt « _NET_WM_PID » giả %lu.\n" +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "Nâng cửa sổ nếu bị che, không thì hạ xuống" -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (trên %s)" +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "Nâng cửa sổ trên các cửa sổ khác" -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "Cửa sổ « WM_TRANSIENT_FOR » không hợp lệ 0x%lx được xác định cho %s.\n" +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "Hạ cửa sổ dưới các cửa sổ khác" -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "Cửa sổ WM_TRANSIENT_FOR 0x%lx cho %s tạo vòng lặp.\n" +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "Phóng to cửa sổ theo chiều dọc" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"Cửa sổ 0x%lx có thuộc tính « %s »\n" -"mà lẽ ra phải có kiểu « %s » dạng thức %d\n" -"và thực sự là kiểu « %s » dạng thức «%d n_items %d».\n" -"Chắc là có một ứng dụng bị lỗi, không phải lỗi trình quản lý cửa sổ.\n" -"Cửa sổ có « title=\"%s\" class=\"%s\" name=\"%s\" »\n" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "Phóng to cửa sổ theo chiều ngang" -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "Thuộc tính « %s » trên cửa sổ « 0x%lx » chứa chuỗi UTF-8 sai.\n" +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "Phân đôi bên trái" -#: ../src/core/xprops.c:494 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "" -"Thuộc tính « %s » trên cửa sổ « 0x%lx » chứa chuỗi UTF-8 sai cho mục %d " -"trong danh sách.\n" +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "Phân đôi bên phải" -#: ../src/muffin.desktop.in.h:1 ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 +#: data/org.gnome.mutter.gschema.xml.in:7 msgid "Modifier to use for extended window management operations" msgstr "Phím bổ trợ dùng cho chức năng quản lý cửa sổ mở rộng" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 +#: data/org.gnome.mutter.gschema.xml.in:8 msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." msgstr "" -"Phím này kích hoạt \"overlay\", một tổ hợp tổng quát cửa sổ và hệ thống chạy " -"ứng dụng. Mặc định là \"phím Windows\" trên phần cứng PC. Chứa một tổ hợp " -"phím, hoặc mặc định, hoặc chuỗi rỗng." +"Phím này khởi tạo “overlay”, cái mà phối hợp tổng quan cửa sổ và hệ thống " +"chạy ứng dụng. Mặc định là \"phím Windows\" trên phần cứng PC. Nó được kỳ " +"vọng rằng tổ hợp hoặc là mặc định, hoặc chuỗi rỗng." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 +#: data/org.gnome.mutter.gschema.xml.in:20 msgid "Attach modal dialogs" msgstr "Gắn hộp thoại cách thức" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 +#: data/org.gnome.mutter.gschema.xml.in:21 msgid "" "When true, instead of having independent titlebars, modal dialogs appear " "attached to the titlebar of the parent window and are moved together with " "the parent window." msgstr "" -"Nếu đúng (true), thay vì hiện thanh tiêu đề độc lập, hộp thoại cách thức sẽ " +"Nếu được đặt, thay vì hiện thanh tiêu đề độc lập, hộp thoại cách thức sẽ " "xuất hiện gắn với thanh tiêu đề của cửa sổ cha và được di chuyển cùng với " "cửa sổ cha." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -msgid "Live Hidden Windows" -msgstr "Cửa sổ ẩn sống" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"Xác định có giữ cửa sổ ẩn (ví dụ cửa sổ thu nhỏ, và cửa sổ ở vùng làm việc " -"khác) không." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 +#: data/org.gnome.mutter.gschema.xml.in:30 msgid "Enable edge tiling when dropping windows on screen edges" msgstr "Bật lợp cạnh khi thả cửa sổ trên cạnh màn hình" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 +#: data/org.gnome.mutter.gschema.xml.in:31 msgid "" "If enabled, dropping windows on vertical screen edges maximizes them " "vertically and resizes them horizontally to cover half of the available " @@ -445,3418 +291,1160 @@ msgstr "" "dọc và điều chỉnh chiều ngang phủ hết nửa màn hình. Thả cửa sổ trên đỉnh màn " "hình sẽ phóng to toàn màn hình." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 +#: data/org.gnome.mutter.gschema.xml.in:40 msgid "Workspaces are managed dynamically" -msgstr "Vùng làm việc được quản lý động" +msgstr "Không gian làm việc được quản lý động" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 +#: data/org.gnome.mutter.gschema.xml.in:41 msgid "" -"Determines whether workspaces are managed dynamically or whether there's a " +"Determines whether workspaces are managed dynamically or whether there’s a " "static number of workspaces (determined by the num-workspaces key in org." "gnome.desktop.wm.preferences)." msgstr "" -"Xác định vùng làm việc được quản lý động, hay cố định số vùng làm việc, xác " -"định bởi khoá num-workspaces trong org.cinnamon.desktop.wm.preferences." +"Xác định không gian làm việc được quản lý động, hay cố định số không gian " +"làm việc (xác định bởi khóa num-workspaces trong org.gnome.desktop.wm." +"preferences)." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 +#: data/org.gnome.mutter.gschema.xml.in:50 msgid "Workspaces only on primary" -msgstr "Vùng làm việc chỉ trên màn hình chính" +msgstr "Không gian làm việc chỉ trên màn hình chính" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 +#: data/org.gnome.mutter.gschema.xml.in:51 msgid "" "Determines whether workspace switching should happen for windows on all " "monitors or only for windows on the primary monitor." msgstr "" -"Xác định chuyển vùng làm việc cho cửa sổ trên mọi màn hình hay chỉ trên màn " -"hình chính." +"Xác định chuyển không gian làm việc cho cửa sổ trên mọi màn hình hay chỉ " +"trên màn hình chính." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 +#: data/org.gnome.mutter.gschema.xml.in:59 msgid "No tab popup" msgstr "Không tab popup" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 +#: data/org.gnome.mutter.gschema.xml.in:60 msgid "" "Determines whether the use of popup and highlight frame should be disabled " "for window cycling." msgstr "Xác định có bỏ qua popup và khung tô sáng khi xoay vòng cửa sổ không." -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 -msgid "Draggable border width" -msgstr "Độ rông biên có thể kéo" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 -msgid "" -"The amount of total draggable borders. If the theme's visible borders are " -"not enough, invisible borders will be added to meet this value." -msgstr "" -"Kích thước biên có thể kéo. Nếu biên thấy được của sắc thái không đủ, biên " -"vô hình sẽ được thêm vào để thoả mãn giá trị này." - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:17 -msgid "Select window from tab popup" -msgstr "Chọn cửa sổ từ tab popup" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:18 -msgid "Cancel tab popup" -msgstr "Huỷ tab popup" - -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "Cách dùng: %s\n" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "Th_u nhỏ" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "_Phóng to" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "_Bỏ phóng to" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "Cuộn _lên" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "_Bỏ cuộn" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "_Di chuyển" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "_Co giãn" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "Chuyển Thanh Tựa Đề trên _màn hình" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "Luôn ở _trên" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "_Chỉ trong vùng làm việc có thể thấy" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "Chỉ trong vùng làm việc _này" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "Chuyển sang vùng làm việc bên t_rái" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "Chuyển sang vùng làm việc bên _phải" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "Chuyển sang vùng làm việc bên _trên" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "Chuyển sang vùng làm việc bên _dưới" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "Đón_g" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "Vùng làm việc %d%n" - -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "Vùng làm việc 1_0" - -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "Vùng làm việc «%s%d»" - -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "Chuyển sang Vùng làm việc _khác" - -# Name: don't translate / Tên: đừng dịch -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -# Name: don't translate / Tên: đừng dịch -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -# Name: don't translate / Tên: đừng dịch -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -# Name: don't translate / Tên: đừng dịch -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Cao cấp" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Cao" - -# Name: don't translate / Tên: đừng dịch -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -# Name: don't translate / Tên: đừng dịch -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -# Name: don't translate / Tên: đừng dịch -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -# Name: don't translate / Tên: đừng dịch -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" - -# Variable: don't translate / Biến: đừng dịch -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" - -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "đỉnh" - -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "đáy" - -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "trái" - -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "phải" - -#: ../src/ui/theme.c:286 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "tọa độ khung không xác định chiều « %s »." - -#: ../src/ui/theme.c:305 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "tọa độ khung không xác định chiều « %s » cho biên « %s »." - -#: ../src/ui/theme.c:342 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "Tỷ lệ hình thể nút «%g» không hợp lý." - -#: ../src/ui/theme.c:354 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "Toạ độ khung không xác định kích thước nút." - -#: ../src/ui/theme.c:1067 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "Thang độ nên có ít nhất hai màu." +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Khoảng chờ con trỏ dừng di chuyển trước khi thay đổi tiêu điểm" -#: ../src/ui/theme.c:1219 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:69 msgid "" -"GTK custom color specification must have color name and fallback in " -"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." msgstr "" -"Đặc tả màu tự chọn GTK phải có tên màu nằm và fallback trong dấu ngoặc, ví " -"dụ gtk:custom(foo,bar); không thể phân tích \"%s\"" +"Nếu bật, và chế độ kích hoạt là “sloppy” hay “mouse” thì sự kích hoạt sẽ " +"không thay đổi tức thì khi vào cửa sổ, mà chỉ sau khi con trỏ ngừng di " +"chuyển." -#: ../src/ui/theme.c:1235 -#, c-format -msgid "" -"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" -"_ are valid" -msgstr "" -"Ký tự không hợp lệ '%c' trong tham số color_name của gtk:custom, chỉ chấp " -"nhận A-Za-z0-9-_" +#: data/org.gnome.mutter.gschema.xml.in:79 +msgid "Draggable border width" +msgstr "Độ rộng biên có thể kéo" -#: ../src/ui/theme.c:1249 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:80 msgid "" -"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " -"fit the format" +"The amount of total draggable borders. If the theme’s visible borders are " +"not enough, invisible borders will be added to meet this value." msgstr "" -"Định dạng Gtk:custom là \"gtk:custom(color_name,fallback)\", \"%s\" không " -"tuân theo định dạng này" +"Kích thước biên có thể kéo. Nếu biên thấy được của chủ đề không đủ, biên vô " +"hình sẽ được thêm vào để thỏa mãn giá trị này." -#: ../src/ui/theme.c:1294 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"Lời ghi rõ màu GTK phải có trạng thái nằm trong ngoặc, v.d. «gtk:fg" -"[NORMAL]», NORMAL (bình thường) là trạng thái; không thể phân tích « %s »." +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "Tự động phóng to cửa sổ gần bằng màn hình" -#: ../src/ui/theme.c:1308 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:90 msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"Lời ghi rõ màu GTK phải có dấu đóng ngoặc sau trạng thái, v.d. «fg[NORMAL]», " -"NORMAL (bình thường) là trạng thái; không thể phân tích « %s »." +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "Nếu bật, sẽ tự động phóng to cửa sổ mới với kích thước tối đa." -#: ../src/ui/theme.c:1319 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "Không hiểu trạng thái « %s » trong lời ghi rõ màu." - -#: ../src/ui/theme.c:1332 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "Không hiểu thành phần màu « %s » trong lời ghi rõ màu." +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "Đặt cửa sổ mới ở chính giữa" -#: ../src/ui/theme.c:1361 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:99 msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." msgstr "" -"Dạng pha trộn là «blend/bg_color/fg_color/alpha», « %s » không tuân theo " -"dạng thức đó." +"Nếu chọn, các cửa sổ mới sẽ luôn được đặt tại trung tâm của màn hình đang " +"hoạt động của màn hình." -#: ../src/ui/theme.c:1372 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "Không thể phân tích giá trị alpha « %s » trong màu pha trộn." - -#: ../src/ui/theme.c:1382 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "Giá trị alpha « %s » trong màu pha trộn không nằm giữa 0.0 và 1.0." +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Bật các tính băng thử nghiệm" -#: ../src/ui/theme.c:1429 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:108 msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes " +"mutter request a low priority real-time scheduling. The executable or user " +"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — " +"initializes Xwayland lazily if there are X11 clients. Requires restart." msgstr "" -"Dạng thức bóng là « shade/base_color/factor » (bóng/màu cơ bản/hệ số), « %s " -"» không tuân theo dạng thức đó." - -#: ../src/ui/theme.c:1440 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "Không thể phân tích hệ số bóng « %s » trong màu bóng." - -#: ../src/ui/theme.c:1450 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "Có hệ số bóng âm « %s » trong màu bóng." - -#: ../src/ui/theme.c:1479 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "Không thể phân tích màu « %s »." +"Để bật các tính năng thử nghiệm, thêm các từ khóa tính năng vào danh sách. " +"Việc tính năng mới có yêu cầu khởi động lại hay không là phụ thuộc vào tính " +"năng đã cho. Bất kỳ tính năng thử nghiệp nào sẽ không được yêu cầu cho đến " +"khi nó sẵn có, hoặc cấu hình được. Đừng cho rằng thêm bất kỳ thứ gì trong " +"cài đặt này thử nghiệm trong tương lai. Các từ khóa hiện có thể là: • “scale-" +"monitor-framebuffer” — làm cho mutter mặc định bố trí các màn hình lôgíc " +"trong một không gian tọa độ điểm ảnh lôgíc, trong khi co giãn các bộ đệm " +"khung màn hình thay vì nội dụng của cửa sổ, để quản lý các màn hình HiDPI. " +"Không yêu cầu khởi động lại. • “rt-scheduler” — làm mutter yêu cầu một lịch " +"trình thời gian thực ưu tiên thấp. Thực thi hoặc người dùng phải có " +"CAP_SYS_NICE. Phải khởi động lại. • “autostart-xwayland” — khởi tạo Xwayland " +"lờ đờ nếu ở đây có các máy khách X11. Phải khởi động lại." + +#: data/org.gnome.mutter.gschema.xml.in:134 +msgid "Modifier to use to locate the pointer" +msgstr "Chỉnh sửa để dùng để địa phương con trỏ" + +#: data/org.gnome.mutter.gschema.xml.in:135 +msgid "This key will initiate the “locate pointer” action." +msgstr "Khóa này sẽ khởi tạo thao tác “locate pointer”." + +#: data/org.gnome.mutter.gschema.xml.in:155 +msgid "Select window from tab popup" +msgstr "Chọn cửa sổ từ thanh nổi lên" -#: ../src/ui/theme.c:1790 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "Biểu thức tọa độ chứa ký tự « %s » không được phép." +#: data/org.gnome.mutter.gschema.xml.in:160 +msgid "Cancel tab popup" +msgstr "Hủy thanh nổi lên" -#: ../src/ui/theme.c:1817 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "Biểu thức tọa độ chứa số với điểm phù động « %s » không thể phân tích." +#: data/org.gnome.mutter.gschema.xml.in:165 +msgid "Switch monitor configurations" +msgstr "Chuyển các cấu hình màn hình" -#: ../src/ui/theme.c:1831 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "Biểu thức tọa độ chứa số nguyên « %s » không thể phân tích." +#: data/org.gnome.mutter.gschema.xml.in:170 +msgid "Rotates the built-in monitor configuration" +msgstr "Quay cấu hình màn hình tích hợp" -#: ../src/ui/theme.c:1953 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "" -"Biểu thức tọa độ chứa toán tử lạ tại đầu văn bản: \n" -"« %s »" +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "Chuyển sang VT 1" -#: ../src/ui/theme.c:2010 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "Biểu thức tọa độ rỗng hoặc không thể hiểu." +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "Chuyển sang VT 2" -#: ../src/ui/theme.c:2121 ../src/ui/theme.c:2131 ../src/ui/theme.c:2165 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "Biểu thức tọa độ gây ra lỗi chia cho không." +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "Chuyển sang VT 3" -#: ../src/ui/theme.c:2173 -#, c-format -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "Biểu thức tọa độ thử dùng toán tử «mod» với số với điểm phụ động." +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "Chuyển sang VT 4" -#: ../src/ui/theme.c:2229 -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "Biểu thức tọa độ có toán tử « %s », nơi lẽ ra phải là một toán hạng." +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "Chuyển sang VT 5" -#: ../src/ui/theme.c:2238 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "Biểu thức tọa đổ có toán hạng nơi lẽ ra phải là toán tử." +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "Chuyển sang VT 6" -#: ../src/ui/theme.c:2246 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "" -"Biểu thức tọa độ kết thúc bằng toán tử trong khi lẽ ra phải là toán hạng." +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "Chuyển sang VT 7" -#: ../src/ui/theme.c:2256 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "" -"Biểu thức tọa độ có toán tử «%c» theo sau toán tử «%c» mà không có toán hạng " -"ở giữa." +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "Chuyển sang VT 8" -#: ../src/ui/theme.c:2407 ../src/ui/theme.c:2452 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "Biểu thức tọa độ có biến hoặc hằng lạ « %s »." +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "Chuyển sang VT 9" -#: ../src/ui/theme.c:2506 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "Bộ phân tích biểu thức tọa độ đã tràn bộ đệm." +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "Chuyển sang VT 10" -#: ../src/ui/theme.c:2535 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "Biểu thức tọa độ có dấu đóng ngoặc mà thiếu dấu mở ngoặc." +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "Chuyển sang VT 11" -#: ../src/ui/theme.c:2599 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "Biểu thức tọa độ có dấu mở ngoặc nhưng thiếu dấu đóng ngoặc." +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "Chuyển sang VT 12" -#: ../src/ui/theme.c:2610 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "Biểu thức tọa độ không có bất kỳ toán tử hay toán hạng nào." +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "Bật-lại phím tắt" -#: ../src/ui/theme.c:2822 ../src/ui/theme.c:2842 ../src/ui/theme.c:2862 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "Sắc thái chứa một biểu thức gây ra lỗi: %s\n" +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow X11 grabs to lock keyboard focus with Xwayland" +msgstr "Cho phép X11 bắt dính để khóa tiêu điểm bàn phím với Xwayland" -#: ../src/ui/theme.c:4533 -#, c-format +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" +"Allow all keyboard events to be routed to X11 “override redirect” windows " +"with a grab when running in Xwayland. This option is to support X11 clients " +"which map an “override redirect” window (which do not receive keyboard " +"focus) and issue a keyboard grab to force all keyboard events to that " +"window. This option is seldom used and has no effect on regular X11 windows " +"which can receive keyboard focus under normal circumstances. For a X11 grab " +"to be taken into account under Wayland, the client must also either send a " +"specific X11 ClientMessage to the root window or be among the applications " +"white-listed in key “xwayland-grab-access-rules”." msgstr "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"gì đó\"/> phải xác định cho " -"kiểu dáng khung này." - -#: ../src/ui/theme.c:5066 ../src/ui/theme.c:5091 -#, c-format +"Cho phép bắt dính mọi sự kiện bàn phím xuất được điều hướng đến các cửa sổ " +"“override redirect” X11 khi chạy trong Xwayland. Tùy chọn này hỗ trợ các máy " +"khách X11 cái mà ánh xạ một cửa sổ “override redirect” (cái mà không nhận " +"tiêu điểm bàn phím) và xuất một dính bàn phím để buộc mọi sự kiện bàn phím " +"cho cửa sổ đó. Tùy chọn này hiến khi được sử dụng và không hiệu quả trên các " +"cửa sổ X11 thông thường cái mà có thể nhận tiêu điểm bàn phím dưới các tình " +"huống thông thường. Với một bắt X11 được lấy vào tài khoản dưới Wayland, máy " +"khách cũng đồng thời phải gửi một X11 ClientMessage đặc biệt đến cửa sổ gốc " +"hoặc trong số các ứng dụng danh-sách-trắng trong khóa “xwayland-grab-access-" +"rules”." + +#: data/org.gnome.mutter.wayland.gschema.xml.in:84 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "Các ứng dụng Xwayland cho phép phát ra các bắt dính bàn phím" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:85 msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "Thiếu <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"gì đó\"/>" - -#: ../src/ui/theme.c:5139 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "Lỗi nạp sắc thái « %s »: %s\n" - -#: ../src/ui/theme.c:5275 ../src/ui/theme.c:5282 ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 ../src/ui/theme.c:5303 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "Chưa đặt <%s> cho sắc thái « %s »." - -#: ../src/ui/theme.c:5311 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." msgstr "" -"Chưa đặt kiểu khung cho loại cửa sổ « %s » trong sắc thái « %s », hãy thêm " -"phần tử <window type=\"%s\" style_set=\"gì đó\"/>." - -#: ../src/ui/theme.c:5709 ../src/ui/theme.c:5771 ../src/ui/theme.c:5834 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "Hằng tự định nghĩa phải bắt đầu bằng ký tự hoa; « %s » không phải." - -#: ../src/ui/theme.c:5717 ../src/ui/theme.c:5779 ../src/ui/theme.c:5842 +"Liệt kê các tên tài nguyên hoặc lớp tài nguyên của các cửa sổ X11 hoặc là " +"cho phép hoặc là không có phép phát bắt bàn phím dưới Xwayland. Tên tài " +"nguyên hoặc lớp tài nguyên của cửa số X11 đã cho có thể kiếm được bằng cách " +"chạy lệnh “xprop WM_CLASS”. Các ký tự địa diện “*” và jokers “?” trong giá " +"trị được hỗ trợ. Giá trị bắt đầu bằng “!” là danh sách bị cấm, những thứ có " +"quyền ưu tiên cao hơn danh sách trắng, để thu hồi ứng dụng từ danh sách hệ " +"thống mặc định. Danh sách hệ thống mặc định bao gồm các ứng dụng sau đây: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Người dùng có thể ngắt một bắt sẵn có " +"bằng cách sử dụng phím tắt đặc biệt được định nghĩa bằng cách ràng buộc phím " +"“restore-shortcuts”." + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. +#. +#: src/backends/meta-input-settings.c:2531 #, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "Hằng « %s » đã được định nghĩa." +msgid "Mode Switch (Group %d)" +msgstr "Chuyển chế độ (Nhóm %d)" -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. #. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "Không có thuộc tính « %s » trong phần tử <%s>" +#: src/backends/meta-input-settings.c:2554 +msgid "Switch monitor" +msgstr "Chuyển màn hình" -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "Dòng %d ký tự %d: %s" +#: src/backends/meta-input-settings.c:2556 +msgid "Show on-screen help" +msgstr "Hiển thị trợ giúp trên-màn-hình" -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "Thuộc tính « %s » lặp hai lần trên cùng phần tử <%s>." +#: src/backends/meta-monitor.c:223 +msgid "Built-in display" +msgstr "Màn hình tích hợp" -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "Thuộc tính « %s » không hợp lệ trên phần tử <%s> trong ngữ cảnh này." +#: src/backends/meta-monitor.c:252 +msgid "Unknown" +msgstr "Không rõ" -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "Không thể phân tích \"%s\" thành một số nguyên." +#: src/backends/meta-monitor.c:254 +msgid "Unknown Display" +msgstr "Không hiểu màn hình" -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 +#: src/backends/meta-monitor.c:262 #, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "Không thể hiểu ký tự đuôi \"%s\" trong chuỗi \"%s\"." +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme-parser.c:613 +#: src/backends/meta-monitor.c:270 #, c-format -msgid "Integer %ld must be positive" -msgstr "Số nguyên %ld phải là số dương" +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "Số nguyên %ld quá lớn, giá trị tối đa hiện thời là %d" +#. Translators: this string will appear in Sysprof +#: src/backends/meta-profiler.c:82 +msgid "Compositor" +msgstr "Compositor" -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:508 #, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "Không thể phân tích « %s » thành số với điểm phù động." +msgid "" +"Another compositing manager is already running on screen %i on display “%s”." +msgstr "Bộ quản lý cửa sổ đã đang chạy trên màn hình %i trên bộ hiển thị “%s”." -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "" -"Giá trị luận lý phải là « đúng » (true) hoặc « sai » (false), không thể là « " -"%s »." +#: src/core/bell.c:192 +msgid "Bell event" +msgstr "Sự kiện chuông" -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "Góc phải nằm giữa 0.0 và 360.0, hiện là %g\n" +#: src/core/main.c:186 +msgid "Disable connection to session manager" +msgstr "Vô hiệu hóa kết nối với bộ quản lý phiên làm việc" -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "" -"Alpha phải nằm giữa 0.0 (không thấy) và 1.0 (đục hoàn toàn), hiện là %g\n" +#: src/core/main.c:192 +msgid "Replace the running window manager" +msgstr "Thay thế bộ quản lý cửa sổ đang chạy" -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"Tỷ lệ tựa đề « %s » không hợp lệ. Nó phải là một điều của những điều này:\n" -" • xx-small\t\ttí tị\n" -" • x-small\t\tnhỏ lắm\n" -" • small\t\t\tnhỏ\n" -" • medium\t\tvừa\n" -" • large\t\t\tlớn\n" -" • x-large\t\tlớn lắm\n" -" • xx-large\t\tto lớn.\n" - -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s> tên « %s » được dùng lần hai" - -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "<%s> chưa định nghĩa mẹ « %s »." - -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "<%s> chưa định nghĩa tọa độ « %s »" - -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "<%s> phải xác định hoặc tọa độ hoặc mẹ có tọa độ." - -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "Bạn phải xác định nền thì giá trị alpha mới có ý nghĩa" - -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "Loại lạ « %s » trong phần tử <%s>." - -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "«style_set» lạ « %s » trong phần tử <%s>." - -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "Loại cửa sổ « %s » đã được gán một tập kiểu." - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "Không cho phép phần tử <%s> dưới <%s>." - -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" -msgstr "" -"Không thể xác định cả hai \"button_width\"/\"button_height\" (chiều rộng/cao " -"của cái nút) và \"aspect_ratio\" (tỷ lệ hình thể) cho cái nút" - -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "Khoảng cách « %s » không biết." - -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "Tỷ lệ hình thể « %s » không biết." - -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "Biên « %s » không biết." - -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "" -"Không có thuộc tính \"start_angle\" (góc bắt đầu) hoặc \"from\" (từ) trong " -"phần tử <%s>." - -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "" -"Không có thuộc tính \"extent_angle\" (góc phạm vi) hoặc \"to\" (đến) trong " -"phần tử <%s>." - -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "Không thể hiểu giá trị « %s » (loại thang độ)." - -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "Không hiểu loại tô « %s » cho phần tử <%s>." - -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "Không hiểu trạng thái « %s » của phần tử <%s>." - -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "Không hiểu bóng « %s » của phần tử <%s>." - -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "Không hiểu mũi tên « %s » của phần tử <%s>." - -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "Không có <draw_ops> nào gọi là « %s » được định nghĩa." - -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "Bao gồm |draw_ops| « %s » ở đây sẽ tạo tham chiếu vòng." - -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "Vị trí lạ « %s » trong phần khung." - -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "Kiểu khung đã có một phần tại vị trí %s." - -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "Chưa định nghĩa <draw_ops> với tên « %s »." - -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "Hàm lạ « %s » trong nút." - -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "Hàm nút \"%s\" không tồn tại trong phiên bản này (%d, cần %d)" - -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "Trạng thái lạ « %s » trong nút." - -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "Kiểu khung đã có nút cho hàm « %s » trạng thái « %s »." - -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "« %s » không phải là giá trị tiêu điểm hợp lệ." - -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "« %s » không phải là giá trị trạng thái hợp lệ." - -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "Chưa định nghĩa kiểu dáng « %s »." - -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "« %s » không phải là giá trị đổi cỡ hợp lệ." - -#: ../src/ui/theme-parser.c:3147 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "" -"Nên có thuộc tính «resize» (đổi cỡ) trên phần tử <%s> cho trạng thái phóng " -"to/đánh bóng." - -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "" -"Nên có thuộc tính \"resize\" (đổi cỡ) trên phần tử <%s> cho trạng thái phóng " -"to." - -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "" -"Kiểu dạng đã được xác định cho trạng thái « %s » đổi cỡ « %s » tiêu điểm « " -"%s »." - -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "Kiểu dạng đã được xác định cho trạng thái « %s » tiêu điểm « %s »." - -#: ../src/ui/theme-parser.c:3294 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Không thể có hai draw_ops cho một phần tử <piece> (sắc thái xác định một " -"draw_ops và thêm một phần tử <draw_ops>, hoặc sắc thái xác định cả hai phần " -"tử)." - -#: ../src/ui/theme-parser.c:3332 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Không thể có hai «draw_ops» trong một phần tử <button> (sắc thái xác định " -"một «draw_ops» và có một phần tử <draw_ops>, hoặc xác định cả hai phần tử)." - -#: ../src/ui/theme-parser.c:3370 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"Không thể có hai «draw_ops» cho phần tử <menu_icon> (sắc thái xác định thuộc " -"tính «draw_ops» và một phần tử <draw_ops>, hoặc xác định cả hai phần tử)." - -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "Đặc tả phiên bản '%s' sai" - -#: ../src/ui/theme-parser.c:3507 -msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" -msgstr "" -"Không thể dùng thuộc tính \"version\" trong metacity-theme-1.xml hoặc " -"metacity-theme-2.xml" - -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "" -"Sắc thái này yêu cầu phiên bản %s nhưng chỉ hỗ trợ tối đa phiên bản %d.%d" - -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "Phần tử ngoài cùng phải là <metacity_theme>, không phải <%s>." - -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "" -"Không cho phép phần tử <%s> nằm trong phần tử « name/author/date/description " -"» (tên/tác giả/ngày/mô tả)." - -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "Không cho phép phần tử <%s> nằm trong phần tử <constant>." - -#: ../src/ui/theme-parser.c:3599 -#, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "" -"Không cho phép phần tử <%s> nằm trong phần tử « distance/border/aspect_ratio " -"» (khoảng cách/viền/tỷ lệ hình thể)." - -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "Không cho phép phần tử <%s> nằm trong phần tử thao tác vẽ." - -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "Không cho phép phần tử <%s> nằm trong phần tử <%s>." - -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "Không có «draw_ops» cho phần khung." - -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "Không có «draw_ops» cho nút." - -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "Không cho phép chữ nằm trong <%s>." - -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "<%s> được xác định hai lần trong sắc thái này" - -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "Lỗi tìm tập tin hợp lệ của sắc thái %s\n" - -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "_Cửa sổ" - -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "_Hộp thoại" - -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "Hộp _thoại cách thức" - -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "_Tiện ích" - -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "_Màn hình giật gân" - -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "Neo đỉ_nh" - -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "Neo đá_y" - -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "Neo t_rái" - -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "Neo _phải" - -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "_Mọi neo" - -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "_Màn hình nền" - -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "Mở cái khác trong những cửa sổ này" - -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "Đây là nút biểu diễn với biểu tượng «mở»" - -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "Đây là nút biểu diễn với biểu tượng «thoát»" - -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "Đây là thông điệp mẫu trong hộp thoại mẫu" - -#: ../src/ui/theme-viewer.c:328 -#, c-format -msgid "Fake menu item %d\n" -msgstr "Mục trình đơn giả %d\n" - -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "Cửa sổ chỉ có viền" - -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "Thanh" - -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "Cửa sổ ứng dụng thông thường" - -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "Hộp thoại" - -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "Hộp thoại cách thức" - -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "Bảng chọn tiện ích" - -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "Trình đơn tách rời" - -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "Viền" - -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "Hộp thoại cách thức đính kèm" - -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "Thử Bố cục nút %d" - -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g mili giây để vẽ một khung cửa sổ" - -#: ../src/ui/theme-viewer.c:813 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "Cách dùng: metacity-theme-viewer [TÊN_SẮC_THÁI]\n" - -#: ../src/ui/theme-viewer.c:820 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "Gặp lỗi khi tải sắc thái: %s\n" - -#: ../src/ui/theme-viewer.c:826 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "Tải sắc thái « %s » trong %g giây.\n" - -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "Phông chữ Tựa đề thường" - -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "Phông chữ Tựa đề nhỏ" - -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "Phông chữ Tựa đề lớn" - -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "Bố cục nút" - -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "Điểm chuẩn" - -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "Tựa đề Cửa sổ ở đây" - -#: ../src/ui/theme-viewer.c:1047 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"Vẽ %d khung trong vòng %g giây bên khách (%g mili giây cho mỗi khung) và %g " -"giây thời gian đồng hồ tường gồm tiềm năng trình phục vụ X (%g mili giây cho " -"mỗi khung).\n" - -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "việc thử ra biểu thức vị trí đã trả lời ĐÚNG nhưng đặt lỗi" - -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "việc thử ra biểu thức vị trí đã trả lời KHÔNG ĐÚNG nhưng không đặt lỗi" - -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "Ngờ lỗi nhưng không có" - -#: ../src/ui/theme-viewer.c:1274 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "Ngờ lỗi «%d» nhưng có «%d»" - -#: ../src/ui/theme-viewer.c:1280 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "Gặp lỗi « %s » bất ngờ" - -#: ../src/ui/theme-viewer.c:1284 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "giá trị x là«%d», mong đợi giá trị «%d»" - -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "giá trị y là «%d», mong đợi giá trị «%d»" - -#: ../src/ui/theme-viewer.c:1352 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "" -"phân tích \"%d\" biểu thức tọa độ trong vòng %g giây (%g giây trung bình).\n" - -#~ msgid "Close Window" -#~ msgstr "Đóng cửa sổ" - -#~ msgid "Window Menu" -#~ msgstr "Trình đơn cửa sổ" - -#~ msgid "Minimize Window" -#~ msgstr "Thu nhỏ cửa sổ" - -#~ msgid "Maximize Window" -#~ msgstr "Phóng to cửa sổ" - -#~ msgid "Restore Window" -#~ msgstr "Phục hồi Cửa sổ" - -#~ msgid "Roll Up Window" -#~ msgstr "Cuộn cửa sổ lên" - -#~ msgid "Unroll Window" -#~ msgstr "Thả cửa sổ xuống" - -#~ msgid "Keep Window On Top" -#~ msgstr "Giữ cửa sổ ở trên cùng" - -#~ msgid "Remove Window From Top" -#~ msgstr "Thôi giữ cửa sổ ở trên cùng" - -#~ msgid "Always On Visible Workspace" -#~ msgstr "Luôn nằm trong vùng làm việc có thể thấy" - -#~ msgid "Put Window On Only One Workspace" -#~ msgstr "Đặt cửa sổ trên chỉ một vùng làm việc" - -#~ msgid "Switch to workspace 1" -#~ msgstr "Chuyển sang vùng làm việc 1" - -#~ msgid "Switch to workspace 2" -#~ msgstr "Chuyển sang vùng làm việc 2" - -#~ msgid "Switch to workspace 3" -#~ msgstr "Chuyển sang vùng làm việc 3" - -#~ msgid "Switch to workspace 4" -#~ msgstr "Chuyển sang vùng làm việc 4" - -#~ msgid "Switch to workspace 5" -#~ msgstr "Chuyển sang vùng làm việc 5" - -#~ msgid "Switch to workspace 6" -#~ msgstr "Chuyển sang vùng làm việc 6" - -#~ msgid "Switch to workspace 7" -#~ msgstr "Chuyển sang vùng làm việc 7" - -#~ msgid "Switch to workspace 8" -#~ msgstr "Chuyển sang vùng làm việc 8" - -#~ msgid "Switch to workspace 9" -#~ msgstr "Chuyển sang vùng làm việc 9" - -#~ msgid "Switch to workspace 10" -#~ msgstr "Chuyển sang vùng làm việc 10" - -#~ msgid "Switch to workspace 11" -#~ msgstr "Chuyển sang vùng làm việc 11" - -#~ msgid "Switch to workspace 12" -#~ msgstr "Chuyển sang vùng làm việc 12" - -#~ msgid "Switch to workspace on the left of the current workspace" -#~ msgstr "Chuyển sang vùng làm việc bên trái vùng làm việc hiện thời" - -#~ msgid "Switch to workspace on the right of the current workspace" -#~ msgstr "Chuyển sang vùng làm việc bên phải vùng làm việc hiện thời" - -#~ msgid "Switch to workspace above the current workspace" -#~ msgstr "Chuyển sang vùng làm việc bên trên vùng làm việc hiện thời" - -#~ msgid "Switch to workspace below the current workspace" -#~ msgstr "Chuyển sang vùng làm việc bên dưới vùng làm việc hiện thời" - -#~ msgid "Move between windows of an application, using a popup window" -#~ msgstr "" -#~ "Chuyển giữa các cửa sổ khác nhau của ứng dụng, dùng một cửa sổ tự mở" - -#~ msgid "" -#~ "Move backward between windows of an application, using a popup window" -#~ msgstr "" -#~ "Chuyển ngược giữa các cửa sổ khác nhau của ứng dụng, dùng một cửa sổ tự mở" - -#~ msgid "Move between windows, using a popup window" -#~ msgstr "Chuyển giữa các cửa sổ khác nhau, dùng một cửa sổ tự mở" - -#~ msgid "Move backward between windows, using a popup window" -#~ msgstr "Chuyển ngược giữa các cửa sổ khác nhau, dùng một cửa sổ tự mở" - -#~ msgid "Move between panels and the desktop, using a popup window" -#~ msgstr "Chuyển giữa các bảng và màn hình nền, dùng một cửa sổ tự mở" - -#~ msgid "Move backward between panels and the desktop, using a popup window" -#~ msgstr "Chuyển ngược giữa các bảng và màn hình nền, dùng một cửa sổ tự mở" - -#~ msgid "Move between windows of an application immediately" -#~ msgstr "Di chuyển ngay giữa các cửa sổ của ứng dụng" - -#~ msgid "Move backward between windows of an application immediately" -#~ msgstr "Chuyển ngược ngay giữa các cửa sổ của ứng dụng" - -#~ msgid "Move between windows immediately" -#~ msgstr "Di chuyển giữa các cửa sổ ngay" - -#~ msgid "Move backward between windows immediately" -#~ msgstr "Chuyển ngược ngay giữa các cửa sổ" - -#~ msgid "Move between panels and the desktop immediately" -#~ msgstr "Di chuyển giữa các bảng và màn hình nền ngay" - -#~ msgid "Move backward between panels and the desktop immediately" -#~ msgstr "Di chuyển lùi lại giữa các bảng và màn hình nền ngay" - -#~ msgid "Hide all normal windows and set focus to the desktop" -#~ msgstr "Ẩn mọi của sổ thông thường và đặt tiêu điểm vào màn hình nền" - -#~ msgid "Show the panel's main menu" -#~ msgstr "Hiện trình đơn chính của Bảng" - -#~ msgid "Show the panel's \"Run Application\" dialog box" -#~ msgstr "Hiện hộp thoại « Chạy ứng dụng » của Bảng" - -#~ msgid "Start or stop recording the session" -#~ msgstr "Bắt đầu hoặc ngừng thu phiên làm việc" - -#~ msgid "Take a screenshot" -#~ msgstr "Chụp hình" - -#~ msgid "Take a screenshot of a window" -#~ msgstr "Chụp hình cửa sổ" - -#~ msgid "Run a terminal" -#~ msgstr "Chạy thiết bị cuối" - -#~ msgid "Activate the window menu" -#~ msgstr "Kích hoạt trình đơn cửa sổ" - -#~ msgid "Toggle fullscreen mode" -#~ msgstr "Bật/Tắt Chế độ Toàn màn hình" - -#~ msgid "Toggle maximization state" -#~ msgstr "Bật tắt trạng thái phóng to" - -#~ msgid "Toggle whether a window will always be visible over other windows" -#~ msgstr "" -#~ "Bật/tắt nếu một cửa sổ nào đó lúc nào cũng hiển thị phía trước các cửa sổ " -#~ "khác" - -#~ msgid "Maximize window" -#~ msgstr "Phóng to cửa sổ" - -#~ msgid "Restore window" -#~ msgstr "Phục hồi cửa sổ" - -#~ msgid "Toggle shaded state" -#~ msgstr "Bật tắt trạng thái đánh bóng" - -#~ msgid "Minimize window" -#~ msgstr "Thu nhỏ cửa sổ" - -#~ msgid "Close window" -#~ msgstr "Đóng cửa sổ" - -#~ msgid "Move window" -#~ msgstr "Di chuyển cửa sổ" - -#~ msgid "Resize window" -#~ msgstr "Co giãn cửa sổ" - -#~ msgid "Toggle whether window is on all workspaces or just one" -#~ msgstr "Bật/tắt nếu cửa sổ nằm trên mọi vùng làm việc, hay chỉ trên một" - -#~ msgid "Move window to workspace 1" -#~ msgstr "Chuyển cửa sổ sang vùng làm việc 1" - -#~ msgid "Move window to workspace 2" -#~ msgstr "Chuyển cửa sổ sang vùng làm việc 2" - -#~ msgid "Move window to workspace 3" -#~ msgstr "Chuyển cửa sổ sang vùng làm việc 3" - -#~ msgid "Move window to workspace 4" -#~ msgstr "Chuyển cửa sổ sang vùng làm việc 4" - -#~ msgid "Move window to workspace 5" -#~ msgstr "Chuyển cửa sổ sang vùng làm việc 5" - -#~ msgid "Move window to workspace 6" -#~ msgstr "Chuyển cửa sổ sang vùng làm việc 6" - -#~ msgid "Move window to workspace 7" -#~ msgstr "Chuyển cửa sổ sang vùng làm việc 7" - -#~ msgid "Move window to workspace 8" -#~ msgstr "Chuyển cửa sổ sang vùng làm việc 8" - -#~ msgid "Move window to workspace 9" -#~ msgstr "Chuyển cửa sổ sang vùng làm việc 9" - -#~ msgid "Move window to workspace 10" -#~ msgstr "Chuyển cửa sổ sang vùng làm việc 10" +#: src/core/main.c:198 +msgid "Specify session management ID" +msgstr "Ghi rõ mã số quản lý phiên làm việc" -#~ msgid "Move window to workspace 11" -#~ msgstr "Chuyển cửa sổ sang vùng làm việc 11" +#: src/core/main.c:203 +msgid "X Display to use" +msgstr "Màn hình X cần dùng" -#~ msgid "Move window to workspace 12" -#~ msgstr "Chuyển cửa sổ sang vùng làm việc 12" +#: src/core/main.c:209 +msgid "Initialize session from savefile" +msgstr "Khởi động phiên làm việc từ tập tin lưu" -#~ msgid "Move window one workspace to the left" -#~ msgstr "Chuyển cửa sổ sang vùng làm việc bên trái" +#: src/core/main.c:215 +msgid "Make X calls synchronous" +msgstr "Khiến các cú gọi X đồng bộ với nhau" -#~ msgid "Move window one workspace to the right" -#~ msgstr "Chuyển cửa sổ sang vùng làm việc bên phải" +#: src/core/main.c:222 +msgid "Run as a wayland compositor" +msgstr "Chạy như là một “wayland compositor”" -#~ msgid "Move window one workspace up" -#~ msgstr "Chuyển cửa sổ lên vùng làm việc trên" +#: src/core/main.c:228 +msgid "Run as a nested compositor" +msgstr "Chạy như là một “nested compositor”" -#~ msgid "Move window one workspace down" -#~ msgstr "Chuyển cửa sổ xuống vùng làm việc dưới" +#: src/core/main.c:234 +msgid "Run wayland compositor without starting Xwayland" +msgstr "Chạy bộ sắp xếp wayland mà không khởi chạy Xwayland" -#~ msgid "Raise window if it's covered by another window, otherwise lower it" -#~ msgstr "Nâng cửa sổ bị cửa sổ khác lấp, không bị lấp thì hạ nó xuống" +#: src/core/main.c:242 +msgid "Run as a full display server, rather than nested" +msgstr "Chạy như là một dịch vụ hiển thị đầy đủ, thay cho lồng nhau" -#~ msgid "Raise window above other windows" -#~ msgstr "Nâng cửa sổ lên trên các cửa sổ khác" +#: src/core/main.c:248 +msgid "Run with X11 backend" +msgstr "Chạy với ứng dụng chạy phía sau X11" -#~ msgid "Lower window below other windows" -#~ msgstr "Hạ thấp cửa sổ xuống dưới các cửa sổ khác" +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:151 +#, c-format +msgid "“%s” is not responding." +msgstr "“%s” không phản ứng." -#~ msgid "Maximize window vertically" -#~ msgstr "Phóng to cửa sổ theo chiều dọc" +#: src/core/meta-close-dialog-default.c:153 +msgid "Application is not responding." +msgstr "Ứng dụng không phản ứng gì." -#~ msgid "Maximize window horizontally" -#~ msgstr "Phóng to cửa sổ theo chiều ngang" +#: src/core/meta-close-dialog-default.c:158 +msgid "" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." +msgstr "" +"Bạn có thể chọn chờ một lát để nó có thể tiếp tục chạy hoặc buộc chấm dứt " +"hoàn toàn ứng dụng." -#~ msgid "Move window to north-west (top left) corner" -#~ msgstr "Chuyển cửa sổ sang góc tây bắc (trái trên)" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Force Quit" +msgstr "_Buộc thoát" -#~ msgid "Move window to north-east (top right) corner" -#~ msgstr "Chuyển cửa sổ sang góc đông bắc (phải trên)" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Wait" +msgstr "_Chờ" -#~ msgid "Move window to south-west (bottom left) corner" -#~ msgstr "Chuyển cửa sổ sang góc tây nam (trái dưới)" +#: src/core/mutter.c:38 +#, c-format +msgid "" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" +msgstr "" +"mutter %s\n" +"Tác quyền © 2001-%d của Havoc Pennington, Red Hat, Inc., và những người " +"khác.\n" +"Chương trình này là phần mềm tự do; xem mã nguồn để tìm điều kiện sao chép.\n" +"KHÔNG CÓ BẢO HÀNH GÌ CẢ, THẬM CHÍ KHÔNG CÓ BẢO ĐẢM ĐƯỢC NGỤ Ý KHẢ NĂNG BÁN " +"HAY KHẢ NĂNG LÀM ĐƯỢC VIỆC DỨT KHOÁT.\n" -#~ msgid "Move window to south-east (bottom right) corner" -#~ msgstr "Chuyển cửa sổ sang góc đông nam (phải dưới)" +#: src/core/mutter.c:52 +msgid "Print version" +msgstr "Hiển thị phiên bản" -#~ msgid "Move window to north (top) side of screen" -#~ msgstr "Chuyển cửa sổ sang phía bắc (trên) màn hình" +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "Phần bổ sung Mutter cần dùng" -#~ msgid "Move window to south (bottom) side of screen" -#~ msgstr "Chuyển cửa sổ sang phía nam (dưới) màn hình" +#: src/core/prefs.c:1849 +#, c-format +msgid "Workspace %d" +msgstr "Không gian làm việc %d" -#~ msgid "Move window to east (right) side of screen" -#~ msgstr "Chuyển cửa sổ sang phía đông (phải) màn hình" +#: src/core/util.c:121 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter đã được biên dịch không hỗ trợ chế độ chi tiết\n" -#~ msgid "Move window to west (left) side of screen" -#~ msgstr "Chuyển cửa sổ sang phía tây (trái) màn hình" +#: src/wayland/meta-wayland-tablet-pad.c:568 +#, c-format +msgid "Mode Switch: Mode %d" +msgstr "Chuyển chế độ: Chế độ %d" -#~ msgid "Move window to center of screen" -#~ msgstr "Chuyển cửa sổ vào trung tâm của màn hình" +#: src/x11/meta-x11-display.c:679 +#, c-format +msgid "" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." +msgstr "" +"Màn hình “%s” đã có bộ quản lý cửa sổ rồi; hãy thử dùng tùy chọn --replace " +"để thay thế bộ quản lý cửa sổ đang dùng." -#~ msgid "" -#~ "There was an error running <tt>%s</tt>:\n" -#~ "\n" -#~ "%s" -#~ msgstr "" -#~ "Gặp lỗi khi chạy <tt>%s</tt>:\n" -#~ "\n" -#~ "%s" +#: src/x11/meta-x11-display.c:1040 +msgid "Failed to initialize GDK\n" +msgstr "Gặp lỗi khi khởi tạo GDK\n" -#~ msgid "No command %d has been defined.\n" -#~ msgstr "Không có lệnh \"%d\" nào được định nghĩa.\n" +#: src/x11/meta-x11-display.c:1064 +#, c-format +msgid "Failed to open X Window System display “%s”\n" +msgstr "Gặp lỗi khi mở bộ hiển thị Hệ thống Cửa sổ X “%s”\n" -#~ msgid "No terminal command has been defined.\n" -#~ msgstr "Không có lệnh thiết bị cuối nào được định nghĩa.\n" +#: src/x11/meta-x11-display.c:1147 +#, c-format +msgid "Screen %d on display “%s” is invalid\n" +msgstr "Màn hình %d trên bộ hiển thị “%s” không hợp lệ.\n" -#~ msgid "GConf key '%s' is set to an invalid value\n" -#~ msgstr "Khóa GConf « %s » được đặt giá trị không hợp lệ\n" +#: src/x11/meta-x11-selection-input-stream.c:445 +#, c-format +msgid "Format %s not supported" +msgstr "Không hỗ trợ định dạng %s" -#~ msgid "%d stored in GConf key %s is out of range %d to %d\n" -#~ msgstr "%d được lưu trong khoá GConf %s nằm ở ngoại phạm vi %d đến %d\n" +#: src/x11/session.c:1821 +msgid "" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." +msgstr "" +"Những cửa sổ này không hỗ trợ “lưu cài đặt hiện tại” và sẽ phải khởi động " +"lại bằng tay lần kế bạn đăng nhập." -#~ msgid "GConf key \"%s\" is set to an invalid type\n" -#~ msgstr "Khóa GConf « %s » được đặt kiểu sai\n" +#: src/x11/window-props.c:569 +#, c-format +msgid "%s (on %s)" +msgstr "%s (trên %s)" -#~ msgid "GConf key %s is already in use and can't be used to override %s\n" -#~ msgstr "Khoá GConf %s đã được dùng và không thể ghi đè %s\n" +#~ msgid "Move window one workspace to the left" +#~ msgstr "Chuyển cửa sổ sang không gian làm việc bên trái" -#~ msgid "Can't override GConf key, %s not found\n" -#~ msgstr "Không thể ghi đè khoá GConf, không tìm thấy %s\n" +#~ msgid "Move window one workspace to the right" +#~ msgstr "Chuyển cửa sổ sang không gian làm việc bên phải" -#~ msgid "Error setting number of workspaces to %d: %s\n" -#~ msgstr "Gặp lỗi khi đặt số vùng làm việc là %d: %s\n" +#~ msgid "Move to workspace left" +#~ msgstr "Chuyển sang không gian làm việc trái" -#~ msgid "Error setting name for workspace %d to \"%s\": %s\n" -#~ msgstr "Gặp lỗi khi đặt tên cho vùng làm việc %d thành « %s »: %s\n" +#~ msgid "Move to workspace right" +#~ msgstr "Chuyển sang không gian làm việc phải" -#~ msgid "Error setting live hidden windows status status: %s\n" -#~ msgstr "Lỗi đặt trạng thái cửa sổ ẩn sống: %s\n" +#~ msgid "Toggle shaded state" +#~ msgstr "Bật tắt trạng thái đánh bóng" -#~ msgid "Error setting no tab popup status: %s\n" -#~ msgstr "Lỗi đặt trạng thái không tab tự mở: %s\n" +#~ msgid "Failed to scan themes directory: %s\n" +#~ msgstr "Gặp lỗi khi quét thư mục lưu chủ đề: %s\n" #~ msgid "" -#~ "Don't make fullscreen windows that are maximized and have no decorations" +#~ "Could not find a theme! Be sure %s exists and contains the usual themes.\n" #~ msgstr "" -#~ "Đừng đối xử cửa sổ phóng to hết cỡ và không có viền như cửa sổ toàn màn " -#~ "hình" +#~ "Không tìm thấy chủ đề nào cả! Hãy bảo đảm %s tồn tại và chứa những chủ đề " +#~ "thông thường.\n" -#~ msgid "Whether window popup/frame should be shown when cycling windows." -#~ msgstr "Có hiện khung/cửa sổ tự mở khi xoay vòng cửa sổ không." +#~ msgid "Screen %d on display \"%s\" already has a window manager\n" +#~ msgstr "Màn hình %d trên bộ trình bày \"%s\" đã có bộ quản lý cửa sổ.\n" -#~ msgid "Internal argument for GObject introspection" -#~ msgstr "Đối số nội bộ cho GObject introspection" +#~ msgid "%d x %d" +#~ msgstr "%d x %d" -#~ msgid "Failed to restart: %s\n" -#~ msgstr "Lỗi khởi động lại: %s\n" +#~ msgid "top" +#~ msgstr "đỉnh" -#~ msgid "Error setting clutter plugin list: %s\n" -#~ msgstr "Lỗi đặt danh sách phần bổ sung clutter: %s\n" +#~ msgid "bottom" +#~ msgstr "đáy" -#~ msgid "Clutter Plugins" -#~ msgstr "Phần bổ sung Clutter" +#~ msgid "left" +#~ msgstr "trái" -#~ msgid "Plugins to load for the Clutter-based compositing manager." -#~ msgstr "Phần bổ sung cần nạp cho trình quản lý tổng hợp dựa trên Clutter." +#~ msgid "right" +#~ msgstr "phải" -#~ msgid "Window Management" -#~ msgstr "Quản lý cửa sổ" +#~ msgid "frame geometry does not specify \"%s\" dimension" +#~ msgstr "tọa độ khung không xác định chiều \"%s\"." -#~ msgid "Failed to parse message \"%s\" from dialog process\n" -#~ msgstr "Lỗi phân tích thông điệp « %s » từ tiến trình hội thoại.\n" +#~ msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" +#~ msgstr "tọa độ khung không xác định chiều \"%s\" cho biên \"%s\"." -#~ msgid "Error reading from dialog display process: %s\n" -#~ msgstr "Gặp lỗi khi đọc từ tiến trình hiển thị hộp thoại: %s\n" +#~ msgid "Button aspect ratio %g is not reasonable" +#~ msgstr "Tỷ lệ hình thể nút “%g” không hợp lý." -#~ msgid "" -#~ "Error launching metacity-dialog to ask about killing an application: %s\n" -#~ msgstr "" -#~ "Lỗi chạy « metacity-dialog » (hộp thoại) để hỏi về việc buộc kết thúc ứng " -#~ "dụng: %s\n" +#~ msgid "Frame geometry does not specify size of buttons" +#~ msgstr "Tọa độ khung không xác định kích thước nút." -#~ msgid "Failed to get hostname: %s\n" -#~ msgstr "Lỗi lấy tên máy: %s\n" +#~ msgid "Gradients should have at least two colors" +#~ msgstr "Thang độ nên có ít nhất hai màu." #~ msgid "" -#~ "Lost connection to the display '%s';\n" -#~ "most likely the X server was shut down or you killed/destroyed\n" -#~ "the window manager.\n" +#~ "GTK custom color specification must have color name and fallback in " +#~ "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" #~ msgstr "" -#~ "Mất liên kết với bộ trình bày « %s »;\n" -#~ "thường là do trình phục vụ X bị ngừng hoạt động hoặc \n" -#~ "bạn đã buộc chấm dứt hoạt động bộ quản lý cửa sổ.\n" - -#~ msgid "Fatal IO error %d (%s) on display '%s'.\n" -#~ msgstr "Lỗi gõ/xuất nghiêm trọng %d (%s) trên bộ trình bày « %s ».\n" - -#~| msgid "Compositing Manager" -#~ msgid "Turn compositing on" -#~ msgstr "Bật sắp thành phần" - -#~ msgid "Turn compositing off" -#~ msgstr "Tắt sắp thành phần" - -#~| msgid "" -#~| "The keybinding used to close a window. The format looks like \"<" -#~| "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~| "liberal and allows lower or upper case, and also abbreviations such as " -#~| "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~| "special string \"disabled\", then there will be no keybinding for this " -#~| "action." -#~ msgid "" -#~ "The format looks like \"<Control>a\" or <Shift><Alt>F1\".\n" -#~ "\n" -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Định dạng hình như \"<Control>a\" or <Shift><Alt>F1\".\n" -#~ ".\n" -#~ "Bộ phân tích cú pháp hiểu cả hai chữ hoa và chữ thường, và cả những từ " -#~ "viết tắt như \"<Ctl>\" and \"<Ctrl>\". Nếu bạn đặt tùy chọn này là chuỗi " -#~ "đặc biệt « disabled » thì sẽ không có tổ hợp phím nào thực hiện hành động " -#~ "này." - -#~| msgid "" -#~| "The keybinding used to close a window. The format looks like \"<" -#~| "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~| "liberal and allows lower or upper case, and also abbreviations such as " -#~| "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~| "special string \"disabled\", then there will be no keybinding for this " -#~| "action." -#~ msgid "" -#~ "The format looks like \"<Control>a\" or <Shift><Alt>F1\".\n" -#~ "\n" -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action.\n" -#~ "\n" -#~ "This keybinding may be reversed by holding down the \"shift\" key; " -#~ "therefore, \"shift\" cannot be one of the keys it uses." -#~ msgstr "" -#~ "Định dạng hình như \"<Control>a\" or <Shift><Alt>F1\".\n" -#~ ".\n" -#~ "Bộ phân tích cú pháp hiểu cả hai chữ hoa và chữ thường, và cả những từ " -#~ "viết tắt như \"<Ctl>\" and \"<Ctrl>\". Nếu bạn đặt tùy chọn này là chuỗi " -#~ "đặc biệt « disabled » thì sẽ không có tổ hợp phím nào thực hiện hành động " -#~ "này.\n" -#~ "\n" -#~ "Cũng có thể đảo ngược tổ hợp phím này bằng cách ấn giữ phím « shift » thì " -#~ "nó không thể sử dụng phím « shift »." - -#~ msgid "Failed to read saved session file %s: %s\n" -#~ msgstr "Lỗi đọc tập tin phiên làm việc đã lưu %s: %s\n" +#~ "Đặc tả màu tự chọn GTK phải có tên màu nằm và fallback trong dấu ngoặc, " +#~ "ví dụ gtk:custom(foo,bar); không thể phân tích \"%s\"" #~ msgid "" -#~ "Error launching metacity-dialog to warn about apps that don't support " -#~ "session management: %s\n" +#~ "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-" +#~ "z0-9-_ are valid" #~ msgstr "" -#~ "Gặp lỗi khi chạy «metacity-dialog» để cảnh báo về ứng dụng không hỗ trợ " -#~ "quản lý phiên làm việc: %s\n" - -# Name: don't translate / Tên: đừng dịch -#~ msgid "Metacity" -#~ msgstr "Metacity" +#~ "Ký tự không hợp lệ “%c” trong tham số color_name của gtk:custom, chỉ chấp " +#~ "nhận A-Za-z0-9-_" #~ msgid "" -#~ "(Not implemented) Navigation works in terms of applications not windows" +#~ "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " +#~ "fit the format" #~ msgstr "" -#~ "Việc duyệt (chưa thực hiện) làm việc theo các điều khoản của ứng dụng, " -#~ "không phải cửa sổ." +#~ "Định dạng Gtk:custom là \"gtk:custom(color_name,fallback)\", \"%s\" không " +#~ "tuân theo định dạng này" #~ msgid "" -#~ "A font description string describing a font for window titlebars. The " -#~ "size from the description will only be used if the titlebar_font_size " -#~ "option is set to 0. Also, this option is disabled if the " -#~ "titlebar_uses_desktop_font option is set to true." +#~ "GTK color specification must have the state in brackets, e.g. gtk:" +#~ "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" #~ msgstr "" -#~ "Chuỗi mô tả phông chữ mô tả phông chữ cho tựa đề cửa sổ. Tuy nhiên kích " -#~ "thước theo mô tả này sẽ chỉ được dùng nếu tùy chọn « titlebar_font_size " -#~ "» (kích thước phông chữ thanh tựa đề) được đặt là 0. Ngoài ra, tùy chọn " -#~ "này sẽ tắt nếu tùy chọn « titlebar_uses_desktop_font » (thanh đựa đề dùng " -#~ "phông chữ của màn hình làm việc) bật." - -#~ msgid "Action on title bar double-click" -#~ msgstr "Hành động khi nhấn đúp chuột lên thanh tiêu đề" - -#~ msgid "Action on title bar middle-click" -#~ msgstr "Hành động khi nhấn-đúp chuột lên thanh tựa" - -#~ msgid "Action on title bar right-click" -#~ msgstr "Hành động khi nhấn-phải chuột lên thanh tựa" +#~ "Lời ghi rõ màu GTK phải có trạng thái nằm trong ngoặc, v.d. “gtk:" +#~ "fg[NORMAL]”, NORMAL (bình thường) là trạng thái; không thể phân tích \"%s" +#~ "\"." -#~ msgid "Arrangement of buttons on the titlebar" -#~ msgstr "Sự bố trí các nút trên thanh tiêu đề" - -#~ msgid "" -#~ "Arrangement of buttons on the titlebar. The value should be a string, " -#~ "such as \"menu:minimize,maximize,spacer,close\"; the colon separates the " -#~ "left corner of the window from the right corner, and the button names are " -#~ "comma-separated. Duplicate buttons are not allowed. Unknown button names " -#~ "are silently ignored so that buttons can be added in future metacity " -#~ "versions without breaking older versions. A special spacer tag can be " -#~ "used to insert some space between two adjacent buttons." -#~ msgstr "" -#~ "Bố trí các nút trên thanh tiêu đề. Giá trị nên là một chuỗi như là « menu:" -#~ "minimize,maximize,close » (trình đơn:cực tiểu hóa,cực đại hóa,đóng), dấu " -#~ "hai chấm tách góc trái ra khỏi góc phải cửa sổ, tên các nút được cách " -#~ "nhau bởi dấu phẩy. Không cho phép nút đúp nào. Tên nút không rõ sẽ được " -#~ "bỏ qua để cho các nút tiếp tục được bổ sung vào các phiên bản tiếp theo " -#~ "của metacity mà không phá vỡ phiên bản cũ. Một thẻ phân cách đặc biệt có " -#~ "thể được dùng để chèn khoảng cách vào giữa hai nút kề nhau." - -#~ msgid "Automatically raises the focused window" -#~ msgstr "Tự động hiển thị cửa sổ có tiêu điểm" - -#~| msgid "" -#~| "Clicking a window while holding down this modifier key will move the " -#~| "window (left click), resize the window (middle click), or show the " -#~| "window menu (right click). Modifier is expressed as \"<Alt>\" or " -#~| "\"<Super>\" for example." #~ msgid "" -#~ "Clicking a window while holding down this modifier key will move the " -#~ "window (left click), resize the window (middle click), or show the window " -#~ "menu (right click). The left and right operations may be swapped using " -#~ "the \"mouse_button_resize\" key. Modifier is expressed as \"<Alt>\" " -#~ "or \"<Super>\" for example." +#~ "GTK color specification must have a close bracket after the state, e.g. " +#~ "gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" #~ msgstr "" -#~ "Nhấn chuột lên một cửa sổ trong khi ấn giữ phím biến đổi này sẽ di chuyển " -#~ "cửa sổ (nhấn-trái), đặt lại kích cỡ cửa sổ (nhấn-giữa), hoặc hiển thị " -#~ "trình đơn cửa sổ (nhấn-phải). Hai thao tác bên trái và bên phải cũng có " -#~ "thể trao đổi với nhau, dùng khoá « mouse_button_resize ». Phím biến đổi " -#~ "được đại diện như \"<Alt>\" hay \"<Super>\" để làm ví dụ." - -#~ msgid "Commands to run in response to keybindings" -#~ msgstr "Lệnh cần chạy khi nhấn phím tổ hợp" +#~ "Lời ghi rõ màu GTK phải có dấu đóng ngoặc sau trạng thái, v.d. " +#~ "“fg[NORMAL]”, NORMAL (bình thường) là trạng thái; không thể phân tích \"%s" +#~ "\"." -#~ msgid "Compositing Manager" -#~ msgstr "Bộ Quản lý Sắp Thành Phần" +#~ msgid "Did not understand state \"%s\" in color specification" +#~ msgstr "Không hiểu trạng thái \"%s\" trong đặc tả màu." -#~ msgid "Control how new windows get focus" -#~ msgstr "Điều khiển cách gán tiêu điểm cho cửa sổ mới" - -#~ msgid "Current theme" -#~ msgstr "Sắc thái hiện tại" - -#~ msgid "Delay in milliseconds for the auto raise option" -#~ msgstr "Khoảng chờ (mili giây) cho tùy chọn tự động hiện" - -#~ msgid "Determines whether Metacity is a compositing manager." -#~ msgstr "" -#~ "Quyết định nếu trình Metacity là bộ quản lý sắp thành phần hay không." +#~ msgid "Did not understand color component \"%s\" in color specification" +#~ msgstr "Không hiểu thành phần màu \"%s\" trong đặc tả màu." #~ msgid "" -#~ "Determines whether applications or the system can generate audible " -#~ "'beeps'; may be used in conjunction with 'visual bell' to allow silent " -#~ "'beeps'." +#~ "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit " +#~ "the format" #~ msgstr "" -#~ "Xác định ứng dụng hoặc hệ thống có thể phát sinh tiến «bíp» hay không; có " -#~ "thể dùng chung với «cái chuông hình» để cho phép «bíp» câm." +#~ "Dạng pha trộn là “blend/bg_color/fg_color/alpha”, \"%s\" không tuân theo " +#~ "dạng thức đó." -#~ msgid "Disable misfeatures that are required by old or broken applications" -#~ msgstr "" -#~ "Tắt «tính năng sai» là cần thiết đối với các ứng dụng cũ hay bị hỏng" - -#~ msgid "Enable Visual Bell" -#~ msgstr "Bật Chuông hình" - -#~ msgid "" -#~ "If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " -#~ "the focused window will be automatically raised after a delay specified " -#~ "by the auto_raise_delay key. This is not related to clicking on a window " -#~ "to raise it, nor to entering a window during drag-and-drop." -#~ msgstr "" -#~ "Nếu bật, và chế độ tiêu điểm hoạc là « sloppy » (luộm thuộm) hay « mouse " -#~ "» (con chuột) thì cửa sổ có tiêu điểm sẽ được nâng lên tự động, sau một " -#~ "thời gian hoãn được xác định bởi khoá « auto_raise_delay » (hoãn nâng lên " -#~ "tự động). Cái này không liên quan đến việc nhắp vào cửa sổ để nâng nó " -#~ "lên, cũng không liên quan đến việc vào cửa sổ trong khi kéo và thả." +#~ msgid "Could not parse alpha value \"%s\" in blended color" +#~ msgstr "Không thể phân tích giá trị alpha \"%s\" trong màu pha trộn." -#~ msgid "" -#~ "If true, ignore the titlebar_font option, and use the standard " -#~ "application font for window titles." -#~ msgstr "" -#~ "Nếu bật, bỏ qua tùy chọn «titlebar_font», và dùng phông chữ ứng dụng " -#~ "chuẩn cho tựa đề cửa sổ." +#~ msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" +#~ msgstr "Giá trị alpha \"%s\" trong màu pha trộn không nằm giữa 0.0 và 1.0." #~ msgid "" -#~ "If true, metacity will give the user less feedback by using wireframes, " -#~ "avoiding animations, or other means. This is a significant reduction in " -#~ "usability for many users, but may allow legacy applications to continue " -#~ "working, and may also be a useful tradeoff for terminal servers. However, " -#~ "the wireframe feature is disabled when accessibility is on." +#~ "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the " +#~ "format" #~ msgstr "" -#~ "Nếu bật thì trình metacity sẽ cho người dùng xem phản hồi ít hơn bằng " -#~ "cách dùng đường viền, tránh hoạt ảnh, hoặc bằng cách khác. Phần lớn người " -#~ "dùng sẽ thấy biết tính hữu dụng đã giảm xuống, nhưng mà có lẽ tùy chọn " -#~ "này sẽ cho phép ứng dụng cũ hơn tiếp tục hoạt động, và có lẽ cũng là thoả " -#~ "hiệp có ích cho trình phục vụ thiết bị cuỗi. Tuy nhiên, tính năng đường " -#~ "viền đã tắt khi khả năng truy cập được bật." +#~ "Dạng thức bóng là \"shade/base_color/factor\" (bóng/màu cơ bản/hệ số), " +#~ "“%s” không tuân theo dạng thức đó." -#~ msgid "" -#~ "If true, then Metacity works in terms of applications rather than " -#~ "windows. The concept is a bit abstract, but in general an application-" -#~ "based setup is more like the Mac and less like Windows. When you focus a " -#~ "window in application-based mode, all the windows in the application will " -#~ "be raised. Also, in application-based mode, focus clicks are not passed " -#~ "through to windows in other applications. Application-based mode is, " -#~ "however, largely unimplemented at the moment." -#~ msgstr "" -#~ "Nếu bật thì trình Metacity hoạt động như theo ứng dụng hơn là theo cửa " -#~ "sổ. Khái niệm này hơi trừu tượng, nhưng nói chung một thiết lập dựa trên " -#~ "ứng dụng thì giống như Mac hơn Windows. Khi bạn đặt tiêu điểm lên một cửa " -#~ "sổ trong chế độ dựa trên ứng dụng, mọi cửa sổ trong ứng dụng đó sẽ được " -#~ "hiển thị. Ngoài ra, trong chế độ dựa trên ứng dụng, nhấn tiêu điểm không " -#~ "được chuyển cho cửa sổ của ứng dụng khác. Ngoài ra chế độ dựa trên ứng " -#~ "dụng chưa được làm tại thời điểm này." +#~ msgid "Could not parse shade factor \"%s\" in shaded color" +#~ msgstr "Không thể phân tích hệ số bóng \"%s\" trong màu bóng." -#~ msgid "If true, trade off usability for less resource usage" -#~ msgstr "Nếu đúng, thoả hiệp giữa tính hữu dụng và dùng ít tài nguyên" +#~ msgid "Shade factor \"%s\" in shaded color is negative" +#~ msgstr "Có hệ số bóng âm \"%s\" trong màu bóng." -#~ msgid "Name of workspace" -#~ msgstr "Tên vùng làm việc" +#~ msgid "Could not parse color \"%s\"" +#~ msgstr "Không thể phân tích màu \"%s\"." -#~ msgid "Number of workspaces" -#~ msgstr "Số vùng làm việc" +#~ msgid "Coordinate expression contains character '%s' which is not allowed" +#~ msgstr "Biểu thức tọa độ chứa ký tự \"%s\" không được phép." #~ msgid "" -#~ "Number of workspaces. Must be more than zero, and has a fixed maximum to " -#~ "prevent making the desktop unusable by accidentally asking for too many " -#~ "workspaces." +#~ "Coordinate expression contains floating point number '%s' which could not " +#~ "be parsed" #~ msgstr "" -#~ "Số vùng làm việc. Phải là số lớn hơn số không, và có giới hạn cố định lớn " -#~ "nhất (để tránh việc hủy màn hình nền một cách bất ngờ bởi vì một yêu cầu " -#~ "34 tỉ vùng làm việc)." - -#~ msgid "Run a defined command" -#~ msgstr "Chạy lệnh đã định nghĩa" +#~ "Biểu thức tọa độ chứa số với điểm phù động \"%s\" không thể phân tích." #~ msgid "" -#~ "Set this to true to resize with the right button and show a menu with the " -#~ "middle button while holding down the key given in \"mouse_button_modifier" -#~ "\"; set it to false to make it work the opposite way around." -#~ msgstr "" -#~ "Đặt giá trị này thành Đúng (true) để thay đổi kích cỡ dùng cái nút bên " -#~ "phải, và hiển thị trình đơn dùng cái nút ở giữa trong khi ấn giữ phím đặt " -#~ "trong khoá « mouse_button_modifier »; đặt thành Sai (false) thì ngược lại." +#~ "Coordinate expression contains integer '%s' which could not be parsed" +#~ msgstr "Biểu thức tọa độ chứa số nguyên \"%s\" không thể phân tích." #~ msgid "" -#~ "Setting this option to false can lead to buggy behavior, so users are " -#~ "strongly discouraged from changing it from the default of true. Many " -#~ "actions (e.g. clicking in the client area, moving or resizing the window) " -#~ "normally raise the window as a side-effect. Setting this option to false, " -#~ "which is strongly discouraged, will decouple raising from other user " -#~ "actions, and ignore raise requests generated by applications. See http://" -#~ "bugzilla.gnome.org/show_bug.cgi?id=445447#c6. Even when this option is " -#~ "false, windows can still be raised by an alt-left-click anywhere on the " -#~ "window, a normal click on the window decorations, or by special messages " -#~ "from pagers, such as activation requests from tasklist applets. This " -#~ "option is currently disabled in click-to-focus mode. Note that the list " -#~ "of ways to raise windows when raise_on_click is false does not include " -#~ "programmatic requests from applications to raise windows; such requests " -#~ "will be ignored regardless of the reason for the request. If you are an " -#~ "application developer and have a user complaining that your application " -#~ "does not work with this setting disabled, tell them it is _their_ fault " -#~ "for breaking their window manager and that they need to change this " -#~ "option back to true or live with the \"bug\" they requested." -#~ msgstr "" -#~ "Đặt tuỳ chọn này thành Sai (false) có thể dẫn tới ứng xử bị lỗi, do đó " -#~ "rất khuyên người dùng không sửa đổi giá trị mặc định (Đúng: true). Rất " -#~ "nhiều hành vi khác nhau (v.d. nhấn vào vùng khách, di chuyển hay thay đổi " -#~ "kích cỡ của cửa sổ) bình thường cũng nâng cửa sổ lên (như một hiệu ứng " -#~ "khác). Đặt tuỳ chọn này thành sai sẽ tháo chức năng nâng lên ra các hành " -#~ "vi người dùng khác, và bỏ qua các yêu cầu nâng lên của ứng dụng. Xem lỗi " -#~ "« http://bugzilla.gnome.org/show_bug.cgi?id=445447#c6 ». Ngay cả khi tuỳ " -#~ "chọn này bị sai, cửa sổ vẫn còn có thể được nâng lên bằng cách Alt-nhấn " -#~ "vào bất cứ nơi nào trên cửa sổ, bằng cách nhấn vào một cách thông thường " -#~ "vào trang trí cửa sổ, hoặc do thông điệp đặc biệt từ bộ dàn trang, v.d. " -#~ "yêu cầu kích hoạt từ tiểu dụng danh sách công việc. Tuỳ chọn này hiện " -#~ "thời bị tắt trong chế độ nhấn-để-đặt-tiêu-điểm. Ghi chú rằng danh sách " -#~ "các phương pháp nâng cửa sổ lên khi « raise_on_click » bị sai không bao " -#~ "gồm yêu cầu nâng cửa sổ lên kiểu lập trình từ ứng dụng: yêu cầu như vậy " -#~ "sẽ bị bỏ qua bất chấp lý do gửi yêu cầu. Nếu bạn phát triển ứng dụng và " -#~ "một người dùng than phiền vì ứng dụng không chạy được với thiết lập này " -#~ "bị tắt, hãy báo họ vấn đề này do lỗi của họ, vì họ đã phá vỡ trình quản " -#~ "lý cửa sổ, và họ cần phải phục hồi tuỳ chọn này về Đúng (true), nếu không " -#~ "thì cứ sử dụng máy tính với « lỗi » này." +#~ "Coordinate expression contained unknown operator at the start of this " +#~ "text: \"%s\"" +#~ msgstr "Biểu thức tọa độ chứa toán tử lạ tại đầu văn bản: \"%s\"" -#~ msgid "" -#~ "Some applications disregard specifications in ways that result in window " -#~ "manager misfeatures. This option puts Metacity in a rigorously correct " -#~ "mode, which gives a more consistent user interface, provided one does not " -#~ "need to run any misbehaving applications." -#~ msgstr "" -#~ "Một số ứng dụng riêng bỏ qua đặc tả, gây ra bộ quản lý cửa sổ không hoạt " -#~ "động cho đúng. Tùy chọn này đặt Metacity trong chế độ đúng chính xác, mà " -#~ "bảo tồn một giao diện người dùng thống nhất hơn, nếu bạn không cần chạy " -#~ "ứng dụng nào chạy sai." +#~ msgid "Coordinate expression was empty or not understood" +#~ msgstr "Biểu thức tọa độ rỗng hoặc không thể hiểu" -#~ msgid "System Bell is Audible" -#~ msgstr "Chuông hệ thống có thể nghe rõ" +#~ msgid "Coordinate expression results in division by zero" +#~ msgstr "Biểu thức tọa độ gây ra lỗi chia cho không" #~ msgid "" -#~ "Tells Metacity how to implement the visual indication that the system " -#~ "bell or another application 'bell' indicator has been rung. Currently " -#~ "there are two valid values, \"fullscreen\", which causes a fullscreen " -#~ "white-black flash, and \"frame_flash\" which causes the titlebar of the " -#~ "application which sent the bell signal to flash. If the application which " -#~ "sent the bell is unknown (as is usually the case for the default \"system " -#~ "beep\"), the currently focused window's titlebar is flashed." -#~ msgstr "" -#~ "Cho Metacity biết cách thực hiện cái hiển thị khi có chuông từ hệ thống " -#~ "hoặc từ ứng dụng khác. Hiện thời chỉ có hai gia trị hợp lệ là " -#~ "«fullscreen» (toàn màn hình), làm chớp trắng-đen toàn màn hình, và " -#~ "«frame_flash» (khung chớp) làm chớp thanh tựa đề của ứng dụng rung " -#~ "chuông. Nếu không biết ứng dụng nào rung chuông (trường hợp thường khi là " -#~ "«chuông hệ thống»), tựa đề ứng dụng đang có tiêu điểm sẽ chớp." +#~ "Coordinate expression tries to use mod operator on a floating-point number" +#~ msgstr "Biểu thức tọa độ thử dùng toán tử “mod” với số thực dấu chấm động" #~ msgid "" -#~ "The /apps/metacity/global_keybindings/run_command_N keys define " -#~ "keybindings that correspond to these commands. Pressing the keybinding " -#~ "for run_command_N will execute command_N." +#~ "Coordinate expression has an operator \"%s\" where an operand was expected" #~ msgstr "" -#~ "Những khóa «/apps/metacity/global_keybindings/run_command_N» định nghĩa " -#~ "tổ hợp phím tương ứng với những lệnh này. Hãy nhấn phím tổ hợp của " -#~ "«run_command_N» để thực hiện «command_N»." +#~ "Biểu thức tọa độ có toán tử \"%s\", nơi lẽ ra phải là một toán hạng." -#~ msgid "" -#~ "The /apps/metacity/global_keybindings/run_command_screenshot key defines " -#~ "a keybinding which causes the command specified by this setting to be " -#~ "invoked." -#~ msgstr "" -#~ "Những khóa «/apps/metacity/global_keybindings/run_command_screenshot» " -#~ "định nghĩa tổ hợp phím, khi được nhấn, sẽ thực hiện lệnh được ghi trong " -#~ "khóa này." +#~ msgid "Coordinate expression had an operand where an operator was expected" +#~ msgstr "Biểu thức tọa đổ có toán hạng nơi lẽ ra phải là toán tử." -#~ msgid "" -#~ "The /apps/metacity/global_keybindings/run_command_window_screenshot key " -#~ "defines a keybinding which causes the command specified by this setting " -#~ "to be invoked." +#~ msgid "Coordinate expression ended with an operator instead of an operand" #~ msgstr "" -#~ "Những khóa «/apps/metacity/global_keybindings/" -#~ "run_command_window_screenshot» định nghĩa tổ hợp phím, khi được nhấn, sẽ " -#~ "thực hiện lệnh được ghi trong khóa này." +#~ "Biểu thức tọa độ kết thúc bằng toán tử trong khi lẽ ra phải là toán hạng." #~ msgid "" -#~ "The keybinding that runs the correspondingly-numbered command in /apps/" -#~ "metacity/keybinding_commands The format looks like \"<Control>a\" " -#~ "or \"<Shift><Alt>F1\". The parser is fairly liberal and " -#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" -#~ "\" and \"<Ctrl>\". If you set the option to the special string " -#~ "\"disabled\", then there will be no keybinding for this action." +#~ "Coordinate expression has operator \"%c\" following operator \"%c\" with " +#~ "no operand in between" #~ msgstr "" -#~ "Tổ hợp phím chạy lệnh đánh số tương ứng trong «/apps/metacity/" -#~ "keybinding_commands». Dạng thức tương tự như \"<Control>a\" hoặc " -#~ "\"<Shift><Alt>F1\". Bộ phân tích hiểu cả chữ hoa lẫn chữ " -#~ "thường, và cả những từ viết tắt như \"<Ctl>\" và \"<Ctrl>\". " -#~ "Nếu bạn đặt tùy chọn là chuỗi đặc biệt «disabled» thì sẽ không có tổ hợp " -#~ "phím nào thực hiện hành động này." +#~ "Biểu thức tọa độ có toán tử “%c” theo sau toán tử “%c” mà không có toán " +#~ "hạng ở giữa." -#~ msgid "The name of a workspace." -#~ msgstr "Tên của vùng làm việc." +#~ msgid "Coordinate expression had unknown variable or constant \"%s\"" +#~ msgstr "Biểu thức tọa độ có biến hoặc hằng lạ \"%s\"." -#~ msgid "The screenshot command" -#~ msgstr "Lệnh chụp hình" +#~ msgid "Coordinate expression parser overflowed its buffer." +#~ msgstr "Bộ phân tích biểu thức tọa độ đã tràn bộ đệm." #~ msgid "" -#~ "The theme determines the appearance of window borders, titlebar, and so " -#~ "forth." -#~ msgstr "" -#~ "Sắc thái xác định diện mạo của đường viền cửa sổ, thanh tựa đề, và nhiều " -#~ "thứ khác." +#~ "Coordinate expression had a close parenthesis with no open parenthesis" +#~ msgstr "Biểu thức tọa độ có dấu đóng ngoặc mà thiếu dấu mở ngoặc." #~ msgid "" -#~ "The time delay before raising a window if auto_raise is set to true. The " -#~ "delay is given in thousandths of a second." -#~ msgstr "" -#~ "Khoảng chờ trước khi hiện cửa sổ nếu đặt «auto_raise». Khoảng chờ tính " -#~ "theo số phần ngàn giây." +#~ "Coordinate expression had an open parenthesis with no close parenthesis" +#~ msgstr "Biểu thức tọa độ có dấu mở ngoặc nhưng thiếu dấu đóng ngoặc." -#~ msgid "" -#~ "The window focus mode indicates how windows are activated. It has three " -#~ "possible values; \"click\" means windows must be clicked in order to " -#~ "focus them, \"sloppy\" means windows are focused when the mouse enters " -#~ "the window, and \"mouse\" means windows are focused when the mouse enters " -#~ "the window and unfocused when the mouse leaves the window." -#~ msgstr "" -#~ "Chế độ tiêu điểm cửa sổ chỉ ra cách cửa sổ được kích hoạt. Nó có thể có " -#~ "ba giá trị sau: «nhắp» (click) nghĩa là cửa sổ được nhấn để nhận tiêu " -#~ "điểm, «luộn thuộm» (sloppy) nghĩa là cửa sổ nhận tiêu điểm nếu con chuột " -#~ "đi ngang qua cửa sổ, và «chuột» (mouse) nghĩa là cửa sổ nhận tiêu điểm " -#~ "khi con chuột đi vào cửa sổ và mất tiêu điểm khi con chuột rời khỏi cửa " -#~ "sổ." +#~ msgid "Coordinate expression doesn't seem to have any operators or operands" +#~ msgstr "Biểu thức tọa độ không có bất kỳ toán tử hay toán hạng nào." -#~ msgid "The window screenshot command" -#~ msgstr "Lệnh chụp hình cửa sổ" +#~ msgid "Theme contained an expression that resulted in an error: %s\n" +#~ msgstr "Chủ đề chứa một biểu thức gây ra lỗi: %s\n" #~ msgid "" -#~ "This option determines the effects of double-clicking on the title bar. " -#~ "Current valid options are 'toggle_shade', which will shade/unshade the " -#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " -#~ "will maximize/unmaximize the window in that direction only, 'minimize' " -#~ "which will minimize the window, 'shade' which will roll the window up, " -#~ "'menu' which will display the window menu, 'lower' which will put the " -#~ "window behind all the others, and 'none' which will not do anything." +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " +#~ "specified for this frame style" #~ msgstr "" -#~ "Tùy chọn này quyết định tác dụng của việc nhấn đúp chuột trên thanh tiêu " -#~ "đề. Tùy chọn hợp lệ hiện thời là:\n" -#~ " • toggle_shade\t\ttạo bóng/thôi tạo bóng cửa sổ\n" -#~ " • toggle_maximize\tphóng to/thôi phóng to cửa sổ\n" -#~ " • toggle_maximize_horizontally\t\tphóng to cửa sổ theo chiều ngang\n" -#~ " • toggle_maximize_vertically\t\tphóng to cửa sổ theo chiều dọc\n" -#~ " • minimize\t\t\tthu nhỏ cửa sổ\n" -#~ " • shade\t\t\t\t\t\tcuộn cửa sổ lên\n" -#~ " • menu\t\t\t\t\t\thiển thị trình đơn cửa sổ\n" -#~ " • lower\t\t\t\t\t\tđặt cửa sổ vào nền sau các cửa sổ khác\n" -#~ " • none\t\t\t\tkhông làm gì." +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"gì đó\"/> phải xác định " +#~ "cho kiểu dáng khung này." #~ msgid "" -#~ "This option determines the effects of middle-clicking on the title bar. " -#~ "Current valid options are 'toggle_shade', which will shade/unshade the " -#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " -#~ "will maximize/unmaximize the window in that direction only, 'minimize' " -#~ "which will minimize the window, 'shade' which will roll the window up, " -#~ "'menu' which will display the window menu, 'lower' which will put the " -#~ "window behind all the others, and 'none' which will not do anything." +#~ "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/" +#~ ">" #~ msgstr "" -#~ "Tùy chọn này quyết định tác dụng của việc nhấn-giữa chuột trên thanh tiêu " -#~ "đề. Tùy chọn hợp lệ hiện thời là:\n" -#~ " • toggle_shade\t\ttạo bóng/thôi tạo bóng cửa sổ\n" -#~ " • toggle_maximize\tphóng to/thôi phóng to cửa sổ\n" -#~ " • toggle_maximize_horizontally\t\tphóng to cửa sổ theo chiều ngang\n" -#~ " • toggle_maximize_vertically\t\tphóng to cửa sổ theo chiều dọc\n" -#~ " • minimize\t\t\tthu nhỏ cửa sổ\n" -#~ " • shade\t\t\t\t\t\tcuộn cửa sổ lên\n" -#~ " • menu\t\t\t\t\t\thiển thị trình đơn cửa sổ\n" -#~ " • lower\t\t\t\t\t\tđặt cửa sổ vào nền sau các cửa sổ khác\n" -#~ " • none\t\t\t\tkhông làm gì." +#~ "Thiếu <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"gì đó\"/>" -#~ msgid "" -#~ "This option determines the effects of right-clicking on the title bar. " -#~ "Current valid options are 'toggle_shade', which will shade/unshade the " -#~ "window, 'toggle_maximize' which will maximize/unmaximize the window, " -#~ "'toggle_maximize_horizontally' and 'toggle_maximize_vertically' which " -#~ "will maximize/unmaximize the window in that direction only, 'minimize' " -#~ "which will minimize the window, 'shade' which will roll the window up, " -#~ "'menu' which will display the window menu, 'lower' which will put the " -#~ "window behind all the others, and 'none' which will not do anything." -#~ msgstr "" -#~ "Tùy chọn này quyết định tác dụng của việc nhấn-giữa chuột trên thanh tựa. " -#~ "Tùy chọn hợp lệ hiện thời là:\n" -#~ " • toggle_shade\t\ttạo bóng/thôi tạo bóng cửa sổ\n" -#~ " • toggle_maximize\tphóng to/thôi phóng to cửa sổ\n" -#~ " • toggle_maximize_horizontally\t\tphóng to cửa sổ theo chiều ngang\n" -#~ " • toggle_maximize_vertically\t\tphóng to cửa sổ theo chiều dọc\n" -#~ " • minimize\t\t\tthu nhỏ cửa sổ\n" -#~ " • shade\t\t\t\t\t\tcuộn cửa sổ lên\n" -#~ " • menu\t\t\t\t\t\thiển thị trình đơn cửa sổ\n" -#~ " • lower\t\t\t\t\t\tđặt cửa sổ vào nền sau các cửa sổ khác\n" -#~ " • none\t\t\t\tkhông làm gì." +#~ msgid "Failed to load theme \"%s\": %s\n" +#~ msgstr "Gặp lỗi khi nạp chủ đề \"%s\": %s\n" -#~ msgid "" -#~ "This option provides additional control over how newly created windows " -#~ "get focus. It has two possible values; \"smart\" applies the user's " -#~ "normal focus mode, and \"strict\" results in windows started from a " -#~ "terminal not being given focus." -#~ msgstr "" -#~ "Tùy chọn này cung cấp khả năng thêm điều khiển cách gán tiêu điểm cho cửa " -#~ "sổ mới tạo. Nó có hai giá trị có thể :\n" -#~ " • smart\t\táp dụng chế độ tiêu điểm bình thường của người dùng đó,\n" -#~ " • strict\t\tgây ra cửa sổ không có tiêu điểm nếu được tạo từ thiết bị " -#~ "cuối." +#~ msgid "No <%s> set for theme \"%s\"" +#~ msgstr "Chưa đặt <%s> cho chủ đề \"%s\"." #~ msgid "" -#~ "Turns on a visual indication when an application or the system issues a " -#~ "'bell' or 'beep'; useful for the hard-of-hearing and for use in noisy " -#~ "environments." -#~ msgstr "" -#~ "Bật chỉ thị trực quan khi ứng dụng hoặc hệ thống rung chuông; rất hữu " -#~ "dụng trong môi trường ồn ào hoặc không nghe rõ." - -#~ msgid "Use standard system font in window titles" -#~ msgstr "Dùng phông chữ hệ thống chuẩn cho tựa đề cửa sổ" - -#~ msgid "Visual Bell Type" -#~ msgstr "Kiểu Chuông hình" - -#~ msgid "Whether raising should be a side-effect of other user interactions" +#~ "No frame style set for window type \"%s\" in theme \"%s\", add a <window " +#~ "type=\"%s\" style_set=\"whatever\"/> element" #~ msgstr "" -#~ "Việc nâng lên có nên là hiệu ứng khác của việc tương tác người dùng khác " -#~ "hay không." - -#~ msgid "Whether to resize with the right button" -#~ msgstr "Có nên thay đổi kích cỡ dùng cái nút bên phải hay không" - -#~ msgid "Window focus mode" -#~ msgstr "Chế độ tiêu điểm cửa sổ" +#~ "Chưa đặt kiểu khung cho loại cửa sổ \"%s\" trong chủ đề \"%s\", hãy thêm " +#~ "phần tử <window type=\"%s\" style_set=\"gì đó\"/>." -#~ msgid "Window title font" -#~ msgstr "Phông chữ tựa đề cửa sổ" +#~ msgid "" +#~ "User-defined constants must begin with a capital letter; \"%s\" does not" +#~ msgstr "Hằng tự định nghĩa phải bắt đầu bằng ký tự hoa; \"%s\" không phải." -#~ msgid "Title" -#~ msgstr "Tựa đề" +#~ msgid "Constant \"%s\" has already been defined" +#~ msgstr "Hằng \"%s\" đã được định nghĩa." -#~ msgid "Class" -#~ msgstr "Hàng" +#~ msgid "No \"%s\" attribute on element <%s>" +#~ msgstr "Không có thuộc tính \"%s\" trong phần tử <%s>" -#~ msgid "" -#~ "There was an error running \"%s\":\n" -#~ "%s." -#~ msgstr "" -#~ "Gặp lỗi khi chạy « %s »:\n" -#~ "%s." +#~ msgid "Line %d character %d: %s" +#~ msgstr "Dòng %d ký tự %d: %s" -#~ msgid "<author> specified twice for this theme" -#~ msgstr "<author> (tác giả) được xác định hai lần trong sắc thái này." +#~ msgid "Attribute \"%s\" repeated twice on the same <%s> element" +#~ msgstr "Thuộc tính \"%s\" lặp hai lần trên cùng phần tử <%s>." -#~ msgid "<copyright> specified twice for this theme" +#~ msgid "Attribute \"%s\" is invalid on <%s> element in this context" #~ msgstr "" -#~ "<copyright> (quyền sở hữu) được xác định hai lần trong sắc thái này." - -#~ msgid "<date> specified twice for this theme" -#~ msgstr "<date> (ngày) được xác định hai lần trong sắc thái này." +#~ "Thuộc tính \"%s\" không hợp lệ trên phần tử <%s> trong ngữ cảnh này." -#~ msgid "<description> specified twice for this theme" -#~ msgstr "<description> (mô tả) được xác định hai lần trong sắc thái này." +#~ msgid "Could not parse \"%s\" as an integer" +#~ msgstr "Không thể phân tích \"%s\" thành một số nguyên." -#~ msgid "Theme file %s did not contain a root <metacity_theme> element" -#~ msgstr "Tập tin sắc thái « %s » không chứa phần tử gốc <metacity_theme>." +#~ msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +#~ msgstr "Không thể hiểu ký tự đuôi \"%s\" trong chuỗi \"%s\"." -#~ msgid "/Windows/tearoff" -#~ msgstr "/Cửa sổ/chia cắt" +#~ msgid "Integer %ld must be positive" +#~ msgstr "Số nguyên %ld phải là số dương" -#~ msgid "/Windows/_Dialog" -#~ msgstr "/Cửa sổ/_Hộp thoại" +#~ msgid "Integer %ld is too large, current max is %d" +#~ msgstr "Số nguyên %ld quá lớn, giá trị tối đa hiện thời là %d" -#~ msgid "/Windows/_Modal dialog" -#~ msgstr "/Cửa sổ/Hộp thoại _cách thức" +#~ msgid "Could not parse \"%s\" as a floating point number" +#~ msgstr "Không thể phân tích \"%s\" thành số với điểm phù động." -#~ msgid "/Windows/Des_ktop" -#~ msgstr "/Cửa sổ/Màn hình _nền" - -#~ msgid "" -#~ "Error launching metacity-dialog to print an error about a command: %s\n" +#~ msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" #~ msgstr "" -#~ "Gặp lỗi khi khởi chạy «metacity-dialog» để in thông báo lỗi về lệnh: %s\n" +#~ "Giá trị luận lý phải là \"đúng\" (true) hoặc \"sai\" (false), không thể " +#~ "là \"%s\"." -#~ msgid "Type of %s was not integer" -#~ msgstr "%s có kiểu không phải số nguyên" +#~ msgid "Angle must be between 0.0 and 360.0, was %g\n" +#~ msgstr "Góc phải nằm giữa 0.0 và 360.0, hiện là %g\n" #~ msgid "" -#~ "%d stored in GConf key %s is not a reasonable cursor_size; must be in the " -#~ "range 1..128\n" +#~ "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" #~ msgstr "" -#~ "« %d » được lưu trong khóa GConf « %s » không phải là một « cursor_size " -#~ "» (kích cỡ con chạy) hợp lý; phải nằm trong phạm vi (1..128)\n" +#~ "Alpha phải nằm giữa 0.0 (trong suốt) và 1.0 (đục hoàn toàn), hiện là %g\n" #~ msgid "" -#~ "%d stored in GConf key %s is not a reasonable number of workspaces, " -#~ "current maximum is %d\n" +#~ "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," +#~ "large,x-large,xx-large)\n" #~ msgstr "" -#~ "«%d» được lưu trong khóa GConf « %s » không phải là một con số hợp lý cho " -#~ "số vùng làm việc, hiện thời tối đa là «%d».\n" +#~ "Tỷ lệ tựa đề \"%s\" không hợp lệ. Nó phải là một điều của những điều " +#~ "này:\n" +#~ " * xx-small\t\ttí tị\n" +#~ " * x-small\t\tnhỏ lắm\n" +#~ " * small\t\t\tnhỏ\n" +#~ " * medium\t\tvừa\n" +#~ " * large\t\t\tlớn\n" +#~ " * x-large\t\tlớn lắm\n" +#~ " * xx-large\t\tto lớn.\n" -#~ msgid "%d stored in GConf key %s is out of range 0 to %d\n" -#~ msgstr "" -#~ "«%d» được lưu trong khóa GConf « %s » nằm ngoài phạm vi từ 0 tới «%d».\n" +#~ msgid "<%s> name \"%s\" used a second time" +#~ msgstr "<%s> tên \"%s\" được dùng lần hai" -#~ msgid "Unknown attribute %s on <metacity_session> element" -#~ msgstr "Thuộc tính lạ « %s » trên phần tử <metacity_session>." +#~ msgid "<%s> parent \"%s\" has not been defined" +#~ msgstr "<%s> chưa định nghĩa mẹ \"%s\"." -#~ msgid "Unknown attribute %s on <window> element" -#~ msgstr "Thuộc tính lạ « %s » trên phần tử <window>" +#~ msgid "<%s> geometry \"%s\" has not been defined" +#~ msgstr "<%s> chưa định nghĩa tọa độ \"%s\"" -#~ msgid "Unknown attribute %s on <maximized> element" -#~ msgstr "Thuộc tính lạ « %s » trên phần tử <maximized>" +#~ msgid "<%s> must specify either a geometry or a parent that has a geometry" +#~ msgstr "<%s> phải xác định hoặc tọa độ hoặc mẹ có tọa độ." -#~ msgid "Unknown attribute %s on <geometry> element" -#~ msgstr "Thuộc tính lạ « %s » trên phần tử <geometry>" +#~ msgid "You must specify a background for an alpha value to be meaningful" +#~ msgstr "Bạn phải xác định nền thì giá trị alpha mới có ý nghĩa" -#~ msgid "Activate window menu" -#~ msgstr "Kích hoạt trình đơn cửa sổ" +#~ msgid "Unknown type \"%s\" on <%s> element" +#~ msgstr "Loại lạ \"%s\" trong phần tử <%s>." -#~ msgid "" -#~ "Clicking a window while holding down this modifier key will move the " -#~ "window (left click), resize the window (middle click), or show the window " -#~ "menu (right click). Modifier is expressed as \"<Alt>\" or \"<" -#~ "Super>\" for example." -#~ msgstr "" -#~ "Nhấn chuột lên một cửa sổ trong khi đang giữ phím biến đổi này sẽ di " -#~ "chuyển cửa sổ (nút chuột trái), đặt lại kích thước cửa sổ (nút chuột " -#~ "giữa), hoặc hiện trình đơn cửa sổ (nút chuột phải). Phím biến đổi được " -#~ "tạo như \"<Alt>\" hay \"<Super>\" để làm ví dụ." +#~ msgid "Unknown style_set \"%s\" on <%s> element" +#~ msgstr "“style_set” lạ \"%s\" trong phần tử <%s>." + +#~ msgid "Window type \"%s\" has already been assigned a style set" +#~ msgstr "Loại cửa sổ \"%s\" đã được gán một tập kiểu." -#~ msgid "Hide all windows and focus desktop" -#~ msgstr "Ẩn mọi của sổ và màn hình nền có tiêu điểm" +#~ msgid "Element <%s> is not allowed below <%s>" +#~ msgstr "Không cho phép phần tử <%s> dưới <%s>." #~ msgid "" -#~ "Many actions (e.g. clicking in the client area, moving or resizing the " -#~ "window) normally raise the window as a side-effect. Setting this option " -#~ "to false, which is strongly discouraged, will decouple raising from other " -#~ "user actions, and ignore raise requests generated by applications. See " -#~ "http://bugzilla.gnome.org/show_bug.cgi?id=445447#c6." +#~ "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio" +#~ "\" for buttons" #~ msgstr "" -#~ "Nhiều hành động (v.d. nhấn vào vùng khách, di chuyển hoặc thay đổi kích " -#~ "cỡ của cửa sổ) bình thường có hiệu ứng khác là nâng cửa sổ lên. Rất " -#~ "khuyên bạn không đặt tùy chọn này thành sai (false), mà sẽ gỡ hành động " -#~ "nâng lên ra các hành động người dùng khác, và bỏ qua các yêu cầu nâng lên " -#~ "được làm bởi ứng dụng. Xem vấn đề « http://bugzilla.gnome.org/show_bug." -#~ "cgi?id=445447#c6 »." - -#~ msgid "Move backwards between panels and the desktop with popup" -#~ msgstr "Di chuyển lùi lại giữa các bảng và màn hình nền với cửa sổ bật lên" - -#~ msgid "Move backwards between windows immediately" -#~ msgstr "Di chuyển lùi lại giữa các cửa sổ ngay" - -#~ msgid "Move backwards between windows of an application immediately" -#~ msgstr "Di chuyển ngay lùi lại giữa các cửa sổ của ứng dụng" - -#~ msgid "Move backwards between windows of an application with popup" -#~ msgstr "Di chuyển lùi lại giữa các cửa sổ của ứng dụng với điều bật lên" - -#~ msgid "Move between panels and the desktop with popup" -#~ msgstr "Di chuyển giữa các bảng và màn hình nền với cửa sổ bật lên" - -#~ msgid "Move between windows of an application with popup" -#~ msgstr "Di chuyển giữa các cửa sổ của ứng dụng với điều bật lên" +#~ "Không thể xác định cả hai \"button_width\"/\"button_height\" (chiều rộng/" +#~ "cao của cái nút) và \"aspect_ratio\" (tỷ lệ hình thể) cho cái nút" -#~ msgid "Move focus backwards between windows using popup display" -#~ msgstr "Di chuyển tiêu điểm lùi lại giữa các cửa sổ dùng hiển thị bật lên" +#~ msgid "Distance \"%s\" is unknown" +#~ msgstr "Khoảng cách \"%s\" không biết." -#~ msgid "Move window to east side of screen" -#~ msgstr "Chuyển cửa sổ sang phía đông màn hình" +#~ msgid "Aspect ratio \"%s\" is unknown" +#~ msgstr "Tỷ lệ hình thể \"%s\" không biết." -#~ msgid "Move window to north side of screen" -#~ msgstr "Chuyển cửa sổ sang phía bắc màn hình" - -#~ msgid "Move window to north-east corner" -#~ msgstr "Chuyển cửa sổ sang góc đông bắc" - -#~ msgid "Move window to north-west corner" -#~ msgstr "Chuyển cửa sổ sang góc tây bắc" - -#~ msgid "Move window to south side of screen" -#~ msgstr "Chuyển cửa sổ sang phía nam màn hình" - -#~ msgid "Move window to south-east corner" -#~ msgstr "Chuyển cửa sổ sang góc đông nam" - -#~ msgid "Move window to south-west corner" -#~ msgstr "Chuyển cửa sổ sang góc tây nam" - -#~ msgid "Move window to west side of screen" -#~ msgstr "Chuyển cửa sổ sang phía tây màn hình" - -#~ msgid "Raise obscured window, otherwise lower" -#~ msgstr "Nâng cửa sổ bị lấp, nếu không thì hạ nó xuống" - -#~ msgid "Show the panel menu" -#~ msgstr "Hiện trình đơn Bảng điều khiển" - -#~ msgid "Show the panel run application dialog" -#~ msgstr "Hiện hộp thoại «Chạy ứng dụng» của Bảng" - -#~ msgid "Switch to workspace above this one" -#~ msgstr "Chuyển sang vùng làm việc ở trên cái này" - -#~ msgid "Switch to workspace below this one" -#~ msgstr "Chuyển sang vùng làm việc ở dưới cái này" - -#~ msgid "Switch to workspace on the left" -#~ msgstr "Chuyển sang vùng làm việc bên trái" - -#~ msgid "Switch to workspace on the right" -#~ msgstr "Chuyển sang vùng làm việc bên phải" - -#~ msgid "" -#~ "The keybinding that switches to the workspace above the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Tổ hợp phím để chuyển qua vùng làm việc trên vùng làm việc hiện thời. " -#~ "Dạng thức tương tự như \"<Control>a\" hoặc \"<Shift><" -#~ "Alt>F1\". Bộ phân tích hiểu cả chữ hoa lẫn chữ thường, và cả những từ " -#~ "viết tắt như \"<Ctl>\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn là " -#~ "chuỗi đặc biệt «disabled» thì sẽ không có tổ hợp phím nào thực hiện hành " -#~ "động này." +#~ msgid "Border \"%s\" is unknown" +#~ msgstr "Biên \"%s\" không biết." -#~ msgid "" -#~ "The keybinding that switches to the workspace below the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." +#~ msgid "No \"start_angle\" or \"from\" attribute on element <%s>" #~ msgstr "" -#~ "Tổ hợp phím chuyển qua vùng làm việc dưới vùng làm việc hiện thời. Dạng " -#~ "thức tương tự như \"<Control>a\" hoặc \"<Shift><Alt>" -#~ "F1\". Bộ phân tích hiểu cả chữ hoa lẫn chữ thường, và cả những từ viết " -#~ "tắt như \"<Ctl>\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn là " -#~ "chuỗi đặc biệt «disabled» thì sẽ không có tổ hợp phím nào thực hiện hành " -#~ "động này." +#~ "Không có thuộc tính \"start_angle\" (góc bắt đầu) hoặc \"from\" (từ) " +#~ "trong phần tử <%s>." -#~ msgid "" -#~ "The keybinding that switches to the workspace on the left of the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." +#~ msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" #~ msgstr "" -#~ "Tổ hợp phím chuyển qua vùng làm việc bên trái vùng làm việc hiện thời. " -#~ "Dạng thức tương tự như \"<Control>a\" hoặc \"<Shift><" -#~ "Alt>F1\". Bộ phân tích hiểu cả chữ hoa lẫn chữ thường, và cả những từ " -#~ "viết tắt như \"<Ctl>\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn là " -#~ "chuỗi đặc biệt «disabled» thì sẽ không có tổ hợp phím nào thực hiện hành " -#~ "động này." +#~ "Không có thuộc tính \"extent_angle\" (góc phạm vi) hoặc \"to\" (đến) " +#~ "trong phần tử <%s>." -#~ msgid "" -#~ "The keybinding that switches to the workspace on the right of the current " -#~ "workspace. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Tổ hợp phím chuyển qua vùng làm việc bên phải vùng làm việc hiện thời. " -#~ "Dạng thức tương tự như \"<Control>a\" hoặc \"<Shift><" -#~ "Alt>F1\". Bộ phân tích hiểu cả chữ hoa lẫn chữ thường, và cả những từ " -#~ "viết tắt như \"<Ctl>\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn là " -#~ "chuỗi đặc biệt «disabled» thì sẽ không có tổ hợp phím nào thực hiện hành " -#~ "động này." +#~ msgid "Did not understand value \"%s\" for type of gradient" +#~ msgstr "Không thể hiểu giá trị \"%s\" (loại thang độ)." -#~ msgid "" -#~ "The keybinding that switches to workspace 1. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Tổ hợp phím chuyển qua vùng làm việc 1. Dạng thức tương tự như \"<" -#~ "Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân tích hiểu cả " -#~ "chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>\" và " -#~ "\"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi đặc biệt «disabled» thì " -#~ "sẽ không có tổ hợp phím nào thực hiện hành động này." +#~ msgid "Did not understand fill type \"%s\" for <%s> element" +#~ msgstr "Không hiểu loại tô \"%s\" cho phần tử <%s>." -#~ msgid "" -#~ "The keybinding that switches to workspace 10. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Tổ hợp phím chuyển qua vùng làm việc 10. Dạng thức tương tự như \"<" -#~ "Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân tích hiểu cả " -#~ "chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>\" và " -#~ "\"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi đặc biệt «disabled» thì " -#~ "sẽ không có tổ hợp phím nào thực hiện hành động này." +#~ msgid "Did not understand state \"%s\" for <%s> element" +#~ msgstr "Không hiểu trạng thái \"%s\" của phần tử <%s>." -#~ msgid "" -#~ "The keybinding that switches to workspace 11. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Tổ hợp phím chuyển qua vùng làm việc 11. Dạng thức tương tự như \"<" -#~ "Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân tích hiểu cả " -#~ "chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>\" và " -#~ "\"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi đặc biệt «disabled» thì " -#~ "sẽ không có tổ hợp phím nào thực hiện hành động này." +#~ msgid "Did not understand shadow \"%s\" for <%s> element" +#~ msgstr "Không hiểu bóng \"%s\" của phần tử <%s>." -#~ msgid "" -#~ "The keybinding that switches to workspace 12. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Tổ hợp phím chuyển qua vùng làm việc 12. Dạng thức tương tự như \"<" -#~ "Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân tích hiểu cả " -#~ "chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>\" và " -#~ "\"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi đặc biệt «disabled» thì " -#~ "sẽ không có tổ hợp phím nào thực hiện hành động này." +#~ msgid "Did not understand arrow \"%s\" for <%s> element" +#~ msgstr "Không hiểu mũi tên \"%s\" của phần tử <%s>." -#~ msgid "" -#~ "The keybinding that switches to workspace 2. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Tổ hợp phím chuyển qua vùng làm việc 2. Dạng thức tương tự như \"<" -#~ "Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân tích hiểu cả " -#~ "chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>\" và " -#~ "\"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi đặc biệt «disabled» thì " -#~ "sẽ không có tổ hợp phím nào thực hiện hành động này." +#~ msgid "No <draw_ops> called \"%s\" has been defined" +#~ msgstr "Không có <draw_ops> nào gọi là \"%s\" được định nghĩa." -#~ msgid "" -#~ "The keybinding that switches to workspace 3. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Tổ hợp phím chuyển qua vùng làm việc 3. Dạng thức tương tự như \"<" -#~ "Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân tích hiểu cả " -#~ "chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>\" và " -#~ "\"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi đặc biệt «disabled» thì " -#~ "sẽ không có tổ hợp phím nào thực hiện hành động này." +#~ msgid "Including draw_ops \"%s\" here would create a circular reference" +#~ msgstr "Bao gồm |draw_ops| \"%s\" ở đây sẽ tạo tham chiếu vòng." -#~ msgid "" -#~ "The keybinding that switches to workspace 4. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Tổ hợp phím chuyển qua vùng làm việc 4. Dạng thức tương tự như \"<" -#~ "Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân tích hiểu cả " -#~ "chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>\" và " -#~ "\"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi đặc biệt «disabled» thì " -#~ "sẽ không có tổ hợp phím nào thực hiện hành động này." +#~ msgid "Unknown position \"%s\" for frame piece" +#~ msgstr "Vị trí lạ \"%s\" trong phần khung." -#~ msgid "" -#~ "The keybinding that switches to workspace 5. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Tổ hợp phím chuyển qua vùng làm việc 5. Dạng thức tương tự như \"<" -#~ "Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân tích hiểu cả " -#~ "chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>\" và " -#~ "\"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi đặc biệt «disabled» thì " -#~ "sẽ không có tổ hợp phím nào thực hiện hành động này." +#~ msgid "Frame style already has a piece at position %s" +#~ msgstr "Kiểu khung đã sẵn có một phần tại vị trí %s." -#~ msgid "" -#~ "The keybinding that switches to workspace 6. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Tổ hợp phím chuyển qua vùng làm việc 6. Dạng thức tương tự như \"<" -#~ "Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân tích hiểu cả " -#~ "chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>\" và " -#~ "\"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi đặc biệt «disabled» thì " -#~ "sẽ không có tổ hợp phím nào thực hiện hành động này." +#~ msgid "No <draw_ops> with the name \"%s\" has been defined" +#~ msgstr "Chưa định nghĩa <draw_ops> với tên \"%s\"." -#~ msgid "" -#~ "The keybinding that switches to workspace 7. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Tổ hợp phím chuyển qua vùng làm việc 7. Dạng thức tương tự như \"<" -#~ "Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân tích hiểu cả " -#~ "chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>\" và " -#~ "\"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi đặc biệt «disabled» thì " -#~ "sẽ không có tổ hợp phím nào thực hiện hành động này." +#~ msgid "Unknown function \"%s\" for button" +#~ msgstr "Hàm lạ \"%s\" trong nút." -#~ msgid "" -#~ "The keybinding that switches to workspace 8. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Tổ hợp phím chuyển qua vùng làm việc 8. Dạng thức tương tự như \"<" -#~ "Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân tích hiểu cả " -#~ "chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>\" và " -#~ "\"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi đặc biệt «disabled» thì " -#~ "sẽ không có tổ hợp phím nào thực hiện hành động này." +#~ msgid "Button function \"%s\" does not exist in this version (%d, need %d)" +#~ msgstr "Hàm nút \"%s\" không tồn tại trong phiên bản này (%d, cần %d)" -#~ msgid "" -#~ "The keybinding that switches to workspace 9. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Tổ hợp phím chuyển qua vùng làm việc 9. Dạng thức tương tự như \"<" -#~ "Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân tích hiểu cả " -#~ "chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>\" và " -#~ "\"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi đặc biệt «disabled» thì " -#~ "sẽ không có tổ hợp phím nào thực hiện hành động này." +#~ msgid "Unknown state \"%s\" for button" +#~ msgstr "Trạng thái lạ \"%s\" trong nút." -#~ msgid "" -#~ "The keybinding used to activate the window menu. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Tổ hợp phím hoạt hóa trình đơn cửa sổ. Dạng thức tương tự như \"<" -#~ "Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân tích hiểu cả " -#~ "chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>\" và " -#~ "\"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi đặc biệt «disabled» thì " -#~ "sẽ không có tổ hợp phím nào thực hiện hành động này." +#~ msgid "Frame style already has a button for function %s state %s" +#~ msgstr "Kiểu khung đã có nút cho hàm \"%s\" trạng thái \"%s\"." -#~ msgid "" -#~ "The keybinding used to close a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Tổ hợp phím dùng để đóng cửa sổ. Dạng thức tương tự như \"<Control>a" -#~ "\" hoặc \"<Shift><Alt>F1\". Bộ phân tích hiểu cả chữ hoa lẫn " -#~ "chữ thường, và cả những từ viết tắt như \"<Ctl>\" và \"<Ctrl>" -#~ "\". Nếu bạn đặt tùy chọn là chuỗi đặc biệt «disabled» thì sẽ không có tổ " -#~ "hợp phím nào thực hiện hành động này." +#~ msgid "\"%s\" is not a valid value for focus attribute" +#~ msgstr "\"%s\" không phải là giá trị tiêu điểm hợp lệ." -#~ msgid "" -#~ "The keybinding used to enter \"move mode\" and begin moving a window " -#~ "using the keyboard. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "Tổ hợp phím để vào «chế độ di chuyển» và bắt đầu di chuyển cửa sổ bằng " -#~ "bàn phím. Dạng thức tương tự như \"<Control>a\" hoặc \"<Shift>" -#~ "<Alt>F1\". Bộ phân tích hiểu cả chữ hoa lẫn chữ thường, và cả những " -#~ "từ viết tắt như \"<Ctl>\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn " -#~ "là chuỗi đặc biệt «disabled» thì sẽ không có tổ hợp phím nào thực hiện " -#~ "hành động này." +#~ msgid "\"%s\" is not a valid value for state attribute" +#~ msgstr "\"%s\" không phải là giá trị trạng thái hợp lệ." -#~ msgid "" -#~ "The keybinding used to enter \"resize mode\" and begin resizing a window " -#~ "using the keyboard. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "Tổ hợp phím để vào «chế độ đổi kích thước» và bắt đầu thay đổi kích thước " -#~ "cửa sổ bằng bàn phím. Dạng thức tương tự như \"<Control>a\" hoặc " -#~ "\"<Shift><Alt>F1\". Bộ phân tích hiểu cả chữ hoa lẫn chữ " -#~ "thường, và cả những từ viết tắt như \"<Ctl>\" và \"<Ctrl>\". " -#~ "Nếu bạn đặt tùy chọn là chuỗi đặc biệt «disabled» thì sẽ không có tổ hợp " -#~ "phím nào thực hiện hành động này." +#~ msgid "A style called \"%s\" has not been defined" +#~ msgstr "Chưa định nghĩa kiểu dáng \"%s\"." -#~ msgid "" -#~ "The keybinding used to hide all normal windows and set the focus to the " -#~ "desktop background. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "Tổ hợp phím dùng để ẩn mọi cửa sổ thường và đặt tiêu điểm cho nền. Dạng " -#~ "thức tương tự như \"<Control>a\" hoặc \"<Shift><Alt>" -#~ "F1\". Bộ phân tích hiểu cả chữ hoa lẫn chữ thường, và cả những từ viết " -#~ "tắt như \"<Ctl>\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn là " -#~ "chuỗi đặc biệt «disabled» thì sẽ không có tổ hợp phím nào thực hiện hành " -#~ "động này." +#~ msgid "\"%s\" is not a valid value for resize attribute" +#~ msgstr "\"%s\" không phải là giá trị đổi cỡ hợp lệ." #~ msgid "" -#~ "The keybinding used to maximize a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "Should not have \"resize\" attribute on <%s> element for maximized/shaded " +#~ "states" #~ msgstr "" -#~ "Tổ hợp phím dùng để phóng to cửa sổ. Dạng thức tương tự như \"<" -#~ "Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân tích hiểu cả " -#~ "chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>\" và " -#~ "\"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi đặc biệt «disabled» thì " -#~ "sẽ không có tổ hợp phím nào thực hiện hành động này." +#~ "Nên có thuộc tính “resize” (đổi cỡ) trên phần tử <%s> cho trạng thái " +#~ "phóng to/đánh bóng." #~ msgid "" -#~ "The keybinding used to minimize a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "Should not have \"resize\" attribute on <%s> element for maximized states" #~ msgstr "" -#~ "Tổ hợp phím dùng để thu nhỏ cửa sổ. Dạng thức tương tự như \"<" -#~ "Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân tích hiểu cả " -#~ "chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>\" và " -#~ "\"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi đặc biệt «disabled» thì " -#~ "sẽ không có tổ hợp phím nào thực hiện hành động này." +#~ "Nên có thuộc tính \"resize\" (đổi cỡ) trên phần tử <%s> cho trạng thái " +#~ "phóng to." -#~ msgid "" -#~ "The keybinding used to move a window one workspace down. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ msgid "Style has already been specified for state %s resize %s focus %s" #~ msgstr "" -#~ "Tổ hợp phím dùng để di chuyển cửa sổ xuống vùng làm việc dưới. Dạng thức " -#~ "tương tự như \"<Control>a\" hoặc \"<Shift><Alt>F1\". Bộ " -#~ "phân tích hiểu cả chữ hoa lẫn chữ thường, và cả những từ viết tắt như " -#~ "\"<Ctl>\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi đặc " -#~ "biệt «disabled» thì sẽ không có tổ hợp phím nào thực hiện hành động này." +#~ "Kiểu dạng đã được xác định cho trạng thái %s đổi cỡ %s tiêu điểm %s." -#~ msgid "" -#~ "The keybinding used to move a window one workspace to the left. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Tổ hợp phím dùng để di chuyển cửa sổ qua vùng làm việc bên trái. Dạng " -#~ "thức tương tự như \"<Control>a\" hoặc \"<Shift><Alt>" -#~ "F1\". Bộ phân tích hiểu cả chữ hoa lẫn chữ thường, và cả những từ viết " -#~ "tắt như \"<Ctl>\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn là " -#~ "chuỗi đặc biệt «disabled» thì sẽ không có tổ hợp phím nào thực hiện hành " -#~ "động này." +#~ msgid "Style has already been specified for state %s focus %s" +#~ msgstr "Kiểu dạng đã được xác định cho trạng thái %s tiêu điểm %s." #~ msgid "" -#~ "The keybinding used to move a window one workspace to the right. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." +#~ "Can't have a two draw_ops for a <piece> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" #~ msgstr "" -#~ "Tổ hợp phím dùng để di chuyển cửa sổ qua vùng làm việc bên phải. Dạng " -#~ "thức tương tự như \"<Control>a\" hoặc \"<Shift><Alt>" -#~ "F1\". Bộ phân tích hiểu cả chữ hoa lẫn chữ thường, và cả những từ viết " -#~ "tắt như \"<Ctl>\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn là " -#~ "chuỗi đặc biệt «disabled» thì sẽ không có tổ hợp phím nào thực hiện hành " -#~ "động này." +#~ "Không thể có hai draw_ops cho một phần tử <piece> (chủ đề xác định một " +#~ "draw_ops và thêm một phần tử <draw_ops>, hoặc chủ đề xác định cả hai phần " +#~ "tử)." #~ msgid "" -#~ "The keybinding used to move a window one workspace up. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "Can't have a two draw_ops for a <button> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" #~ msgstr "" -#~ "Tổ hợp phím để di chuyển cửa sổ lên vùng làm việc bên trên. Dạng thức " -#~ "tương tự như \"<Control>a\" hoặc \"<Shift><Alt>F1\". Bộ " -#~ "phân tích hiểu cả chữ hoa lẫn chữ thường, và cả những từ viết tắt như " -#~ "\"<Ctl>\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi đặc " -#~ "biệt «disabled» thì sẽ không có tổ hợp phím nào thực hiện hành động này." +#~ "Không thể có hai “draw_ops” trong một phần tử <button> (chủ đề xác định " +#~ "một “draw_ops” và có một phần tử <draw_ops>, hoặc xác định cả hai phần " +#~ "tử)." #~ msgid "" -#~ "The keybinding used to move a window to workspace 1. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "Can't have a two draw_ops for a <menu_icon> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" #~ msgstr "" -#~ "Tổ hợp phím để di chuyển cửa sổ sang vùng làm việc 1. Dạng thức tương tự " -#~ "như \"<Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân " -#~ "tích hiểu cả chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<" -#~ "Ctl>\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi đặc biệt " -#~ "«disabled» thì sẽ không có phím nóng nào thực hiện hành động này." +#~ "Không thể có hai “draw_ops” cho phần tử <menu_icon> (chủ đề xác định " +#~ "thuộc tính “draw_ops” và một phần tử <draw_ops>, hoặc xác định cả hai " +#~ "phần tử)." -#~ msgid "" -#~ "The keybinding used to move a window to workspace 10. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Tổ hợp phím để di chuyển cửa sổ sang vùng làm việc 10. Dạng thức tương tự " -#~ "như \"<Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân " -#~ "tích hiểu cả chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<" -#~ "Ctl>\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi đặc biệt " -#~ "«disabled» thì sẽ không có tổ hợp phím nào thực hiện hành động này." +#~ msgid "Bad version specification '%s'" +#~ msgstr "Đặc tả phiên bản “%s” sai" #~ msgid "" -#~ "The keybinding used to move a window to workspace 11. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" +#~ "theme-2.xml" #~ msgstr "" -#~ "Phím nóng để di chuyển cửa sổ sang workspace 11. Dạng thức tương tự như " -#~ "\"<Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân tích " -#~ "hiểu cả chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>" -#~ "\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi \"disabled\" thì sẽ " -#~ "không có phím nóng nào thực hiện hành động này." +#~ "Không thể dùng thuộc tính \"version\" trong metacity-theme-1.xml hoặc " +#~ "metacity-theme-2.xml" #~ msgid "" -#~ "The keybinding used to move a window to workspace 12. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Phím nóng để di chuyển cửa sổ sang workspace 12. Dạng thức tương tự như " -#~ "\"<Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân tích " -#~ "hiểu cả chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>" -#~ "\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi \"disabled\" thì sẽ " -#~ "không có phím nóng nào thực hiện hành động này." +#~ "Theme requires version %s but latest supported theme version is %d.%d" +#~ msgstr "Chủ đề yêu cầu phiên bản %s nhưng chỉ hỗ trợ tối đa phiên bản %d.%d" -#~ msgid "" -#~ "The keybinding used to move a window to workspace 2. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Phím nóng để di chuyển cửa sổ sang workspace 2. Dạng thức tương tự như " -#~ "\"<Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân tích " -#~ "hiểu cả chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>" -#~ "\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi \"disabled\" thì sẽ " -#~ "không có phím nóng nào thực hiện hành động này." +#~ msgid "Outermost element in theme must be <metacity_theme> not <%s>" +#~ msgstr "Phần tử ngoài cùng phải là <metacity_theme>, không phải <%s>." #~ msgid "" -#~ "The keybinding used to move a window to workspace 3. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "Element <%s> is not allowed inside a name/author/date/description element" #~ msgstr "" -#~ "Phím nóng để di chuyển cửa sổ sang workspace 3. Dạng thức tương tự như " -#~ "\"<Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân tích " -#~ "hiểu cả chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>" -#~ "\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi \"disabled\" thì sẽ " -#~ "không có phím nóng nào thực hiện hành động này." +#~ "Không cho phép phần tử <%s> nằm trong phần tử “name/author/date/" +#~ "description” (tên/tác giả/ngày/mô tả)." -#~ msgid "" -#~ "The keybinding used to move a window to workspace 4. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Phím nóng để di chuyển cửa sổ sang workspace 4. Dạng thức tương tự như " -#~ "\"<Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân tích " -#~ "hiểu cả chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>" -#~ "\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi \"disabled\" thì sẽ " -#~ "không có phím nóng nào thực hiện hành động này." +#~ msgid "Element <%s> is not allowed inside a <constant> element" +#~ msgstr "Không cho phép phần tử <%s> nằm trong phần tử <constant>." #~ msgid "" -#~ "The keybinding used to move a window to workspace 5. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "Element <%s> is not allowed inside a distance/border/aspect_ratio element" #~ msgstr "" -#~ "Phím nóng để di chuyển cửa sổ sang workspace 5. Dạng thức tương tự như " -#~ "\"<Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân tích " -#~ "hiểu cả chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>" -#~ "\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi \"disabled\" thì sẽ " -#~ "không có phím nóng nào thực hiện hành động này." +#~ "Không cho phép phần tử <%s> nằm trong phần tử “distance/border/" +#~ "aspect_ratio” (khoảng cách/viền/tỷ lệ hình thể)." -#~ msgid "" -#~ "The keybinding used to move a window to workspace 6. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Phím nóng để di chuyển cửa sổ sang workspace 6. Dạng thức tương tự như " -#~ "\"<Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân tích " -#~ "hiểu cả chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>" -#~ "\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi \"disabled\" thì sẽ " -#~ "không có phím nóng nào thực hiện hành động này." +#~ msgid "Element <%s> is not allowed inside a draw operation element" +#~ msgstr "Không cho phép phần tử <%s> nằm trong phần tử thao tác vẽ." -#~ msgid "" -#~ "The keybinding used to move a window to workspace 7. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Phím nóng để di chuyển cửa sổ sang workspace 7. Dạng thức tương tự như " -#~ "\"<Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân tích " -#~ "hiểu cả chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>" -#~ "\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi \"disabled\" thì sẽ " -#~ "không có phím nóng nào thực hiện hành động này." +#~ msgid "Element <%s> is not allowed inside a <%s> element" +#~ msgstr "Không cho phép phần tử <%s> nằm trong phần tử <%s>." -#~ msgid "" -#~ "The keybinding used to move a window to workspace 8. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Phím nóng để di chuyển cửa sổ sang workspace 8. Dạng thức tương tự như " -#~ "\"<Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân tích " -#~ "hiểu cả chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>" -#~ "\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi \"disabled\" thì sẽ " -#~ "không có phím nóng nào thực hiện hành động này." +#~ msgid "No draw_ops provided for frame piece" +#~ msgstr "Không có “draw_ops” cho phần khung." -#~ msgid "" -#~ "The keybinding used to move a window to workspace 9. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Phím nóng để di chuyển cửa sổ sang workspace 9. Dạng thức tương tự như " -#~ "\"<Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân tích " -#~ "hiểu cả chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>" -#~ "\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi \"disabled\" thì sẽ " -#~ "không có phím nóng nào thực hiện hành động này." +#~ msgid "No draw_ops provided for button" +#~ msgstr "Không có “draw_ops” cho nút." -#~ msgid "" -#~ "The keybinding used to move focus backwards between panels and the " -#~ "desktop, using a popup window. The format looks like \"<Control>a\" " -#~ "or \"<Shift><Alt>F1\". The parser is fairly liberal and " -#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" -#~ "\" and \"<Ctrl>\". If you set the option to the special string " -#~ "\"disabled\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "Tổ hợp phím dùng để di chuyển tiêu điểm lùi lại giữa các bảng điều khiển " -#~ "và màn hình làm việc, dùng cửa sổ bật lên. Dạng thức kiểu như \"<" -#~ "Control>a\" hoặc \"<Shift><Alt>F1\". Trình phân tích hiểu " -#~ "cả chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>\" và " -#~ "\"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi đặc biệt «disabled» thì " -#~ "sẽ không có tổ hợp phím nào thực hiện hành động này." +#~ msgid "No text is allowed inside element <%s>" +#~ msgstr "Không cho phép chữ nằm trong <%s>." -#~ msgid "" -#~ "The keybinding used to move focus backwards between panels and the " -#~ "desktop, without a popup window. The format looks like \"<Control>a" -#~ "\" or \"<Shift><Alt>F1\". The parser is fairly liberal and " -#~ "allows lower or upper case, and also abbreviations such as \"<Ctl>" -#~ "\" and \"<Ctrl>\". If you set the option to the special string " -#~ "\"disabled\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "Tổ hợp phím dùng để di chuyển focus lùi lại giữa các bảng điều khiển và " -#~ "màn hình làm việc, không dùng cửa sổ bật lên. Dạng thức kiểu như \"<" -#~ "Control>a\" hoặc \"<Shift><Alt>F1\". Trình phân tích hiểu " -#~ "cả chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>\" và " -#~ "\"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi đặc biệt «disabled» thì " -#~ "sẽ không có tổ hợp phím nào thực hiện hành động này." +#~ msgid "<%s> specified twice for this theme" +#~ msgstr "<%s> được định nghĩa hai lần trong chủ đề này" -#~ msgid "" -#~ "The keybinding used to move focus backwards between windows of an " -#~ "application without a popup window. Holding \"shift\" together with this " -#~ "binding makes the direction go forward again. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Tổ hợp phím dùng để chuyển tiêu điểm lùi lại giữa các cửa sổ của ứng " -#~ "dụng, không có cửa sổ bật lên. Giữ phím Shift cùng với tổ hợp này thì sẽ " -#~ "chuyển lại thành hướng tiến lên. Dạng thức tương tự như \"<Control>a" -#~ "\" hoặc \"<Shift><Alt>F1\". Trình phân tách hiểu cả chữ hoa " -#~ "lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>\" và \"<" -#~ "Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi đặc biệt « disabled » (tắt) thì " -#~ "sẽ không có tổ hợp phím nào thực hiện hành động này." +#~ msgid "Failed to find a valid file for theme %s\n" +#~ msgstr "Gặp lỗi khi tìm tập tin hợp lệ của chủ đề %s\n" -#~ msgid "" -#~ "The keybinding used to move focus backwards between windows of an " -#~ "application, using a popup window. Holding \"shift\" together with this " -#~ "binding makes the direction go forward again. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Phím nóng dùng để chuyển tiêu điểm lùi lại giữa các cửa sổ của ứng dụng, " -#~ "dùng cửa sổ bật lên. Giữ phím Shift cùng tổ hợp này sẽ tạo lại hướng tiến " -#~ "lên. Dạng thức tương tự như \"<Control>a\" hoặc \"<Shift><" -#~ "Alt>F1\". Bộ phân tích hiểu cả chữ hoa lẫn chữ thường, và cả những từ " -#~ "viết tắt như \"<Ctl>\" và \"<Ctrl >\". Nếu bạn đặt tùy chọn " -#~ "là chuỗi « disabled » (tắt) thì sẽ không có phím nóng nào thực hiện hành " -#~ "động này." +#~ msgid "background texture could not be created from file" +#~ msgstr "không thể tạo ảnh nền từ tập tin" -#~ msgid "" -#~ "The keybinding used to move focus backwards between windows without a " -#~ "popup window. Holding \"shift\" together with this binding makes the " -#~ "direction go forward again. The format looks like \"<Control>a\" or " -#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " -#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" -#~ "\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "Tổ hợp phím dùng để chuyển focus lùi lại giữa các cửa sổ, không có cửa sổ " -#~ "bật lên. Giữ \"shift\" cùng với tổ hợp này thì sẽ chuyển thành hướng tiến " -#~ "lên. Dạng thức tương tự như \"<Control>a\" hoặc \"<Shift><" -#~ "Alt>F1\". Trình phân tích hiểu cả chữ hoa lẫn chữ thường, và cả những " -#~ "từ viết tắt như \"<Ctl>\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn " -#~ "là chuỗi đặc biệt«disabled» thì sẽ không có tổ hợp phím nào thực hiện " -#~ "hành động này." +#~ msgid "Unknown window information request: %d" +#~ msgstr "Yêu cầu thông tin cửa sổ không rõ: %d" -#~ msgid "" -#~ "The keybinding used to move focus backwards between windows, using a " -#~ "popup window. Holding \"shift\" together with this binding makes the " -#~ "direction go forward again. The format looks like \"<Control>a\" or " -#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " -#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" -#~ "\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "Phím nóng dùng để chuyển focus lùi lại giữa các cửa sổ, dùng cửa sổ bật " -#~ "lên. Giữ \"shift\" cùng tổ hợp này sẽ tạo lại hướng tiến lên. Dạng thức " -#~ "tương tự như \"<Control>a\" hoặc \"<Shift><Alt>F1\". Bộ " -#~ "phân tích hiểu cả chữ hoa lẫn chữ thường, và cả những từ viết tắt như " -#~ "\"<Ctl>\" và \"<Ctrl >\". Nếu bạn đặt tùy chọn là chuỗi " -#~ "\"disabled\" thì sẽ không có phím nóng nào thực hiện hành động này." +#~ msgid "Missing %s extension required for compositing" +#~ msgstr "Thiếu phần mở rộng %s cần thiết để tổng hợp" #~ msgid "" -#~ "The keybinding used to move focus between panels and the desktop, using a " -#~ "popup window. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." +#~ "Some other program is already using the key %s with modifiers %x as a " +#~ "binding\n" #~ msgstr "" -#~ "Tổ hợp phím để di chuyển tiêu điểm giữa bảng điều khiển và màn hình làm " -#~ "việc, bằng của sổ bật lên. Dạng thức tương tự như \"<Control>a\" " -#~ "hoặc \"<Shift><Alt>F1\". Bộ phân tích hiểu cả chữ hoa lẫn chữ " -#~ "thường, và cả những từ viết tắt như \"<Ctl>\" và \"<Ctrl>\". " -#~ "Nếu bạn đặt tùy chọn là chuỗi đặc biệt «disabled» thì sẽ không có tổ hợp " -#~ "phím nào thực hiện hành động này." +#~ "Một chương trình khác đã dùng phím %s với phím bổ trợ “%x” như là tổ " +#~ "hợp.\n" -#~ msgid "" -#~ "The keybinding used to move focus between panels and the desktop, without " -#~ "a popup window. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." -#~ msgstr "" -#~ "Tổ hợp phím dùng để di chuyển tiêu điểm giữa bảng điều khiển và màn hình " -#~ "làm việc, không dùng cửa sổ bật lên. Dạng thức tương tự như \"<" -#~ "Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân tích hiểu cả " -#~ "chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>\" và " -#~ "\"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi đặc biệt «disabled» thì " -#~ "sẽ không có tổ hợp phím nào thực hiện hành động này." +#~ msgid "\"%s\" is not a valid accelerator\n" +#~ msgstr "\"%s\" không phải là phím tắt hợp lệ\n" #~ msgid "" -#~ "The keybinding used to move focus between windows of an application " -#~ "without a popup window. Holding the \"shift\" key while using this " -#~ "binding reverses the direction of movement. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "Workarounds for broken applications disabled. Some applications may not " +#~ "behave properly.\n" #~ msgstr "" -#~ "Phím nóng để chuyển tiêu điểm giữa các cửa sổ của ứng dụng, không hiện " -#~ "cửa sổ bật lên. Giữ phím Shift cùng tổ hợp này sẽ đảo hướng di chuyển. " -#~ "Dạng thức tương tự như \"<Control>a\" hoặc \"<Shift><" -#~ "Alt>F1\". Bộ phân tách hiểu cả chữ hoa lẫn chữ thường, và cả những từ " -#~ "viết tắt như \"<Ctl>\" và \"<Ctrl>\". Nếu bạn đặt tùychọn là " -#~ "chuỗi « disabled » (tắt) thì sẽ không có phím nóng nào thực hiện hành " -#~ "động này." +#~ "Khả năng chỉnh sửa cho các ứng dụng không theo chuẩn đã đã tắt. Vài ứng " +#~ "dụng có thể sẽ xử sự không đúng.\n" -#~ msgid "" -#~ "The keybinding used to move focus between windows of an application, " -#~ "using a popup window. (Traditionally <Alt>F6) Holding the \"shift\" " -#~ "key while using this binding reverses the direction of movement. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Phím nóng để chuyển focus giữa các cửa sổ, dùng cửa sổ bật lên. (Thường " -#~ "là <Alt>Tab). Giữ phím Shift khi dùng tổ hợp này sẽ đảo hướng " -#~ "chuyển động. Dạng thức tương tự như \"<Control>a\" hoặc \"<" -#~ "Shift><Alt>F1\". Bộ phân tách hiểu cả chữ hoa lẫn chữ thường, và " -#~ "cả những từ viết tắt như \"<Ctl>\" và \"<Ctrl>\". Nếu bạn đặt " -#~ "tùy chọn là chuỗi « disabled » (tắt) thì sẽ không có phím nóng nào thực " -#~ "hiện hành động này." +#~ msgid "Could not parse font description \"%s\" from GSettings key %s\n" +#~ msgstr "Không thể phân tích mô tả phông \"%s\" từ khóa GSettings \"%s\"\n" #~ msgid "" -#~ "The keybinding used to move focus between windows without a popup window. " -#~ "(Traditionally <Alt>Escape) Holding the \"shift\" key while using " -#~ "this binding reverses the direction of movement. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" #~ msgstr "" -#~ "Phím nóng để chuyển focus giữa các cửa sổ, không hiện cửa sổ bật lên. " -#~ "(Thường là <Alt>Escape). Giữ phím \"shift\" cùng tổ hợp này sẽ đảo " -#~ "hướng di chuyển. Dạng thức tương tự như \"<Control>a\" hoặc \"<" -#~ "Shift><Alt>F1\". Bộ phân tích hiểu cả chữ hoa lẫn chữ thường, " -#~ "và cả những từ viết tắt như \"<Ctl>\" và \"<Ctrl>\". Nếu bạn " -#~ "đặt tùychọn là chuỗi \"disabled\" thì sẽ không có phím nóng nào thực hiện " -#~ "hành động này." +#~ "Tìm thấy \"%s\" trong cơ sở dữ liệu cấu hình không phải giá trị hợp lệ " +#~ "cho bộ biến đổi nút chuột.\n" #~ msgid "" -#~ "The keybinding used to move focus between windows, using a popup window. " -#~ "(Traditionally <Alt>Tab) Holding the \"shift\" key while using this " -#~ "binding reverses the direction of movement. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." +#~ "\"%s\" found in configuration database is not a valid value for " +#~ "keybinding \"%s\"\n" #~ msgstr "" -#~ "Phím nóng để chuyển focus giữa các cửa sổ, dùng cửa sổ bật lên. (Thường " -#~ "là <Alt>Tab). Giữ phím \"shift\" khi dùng tổ hợp này sẽ đảo hướng " -#~ "chuyển động. Dạng thức tương tự như \"<Control>a\" hoặc \"<" -#~ "Shift><Alt>F1\". Trình phân tích hiểu cả chữ hoa lẫn chữ " -#~ "thường, và cả những từ viết tắt như \"<Ctl>\" và \"<Ctrl>\". " -#~ "Nếu bạn đặt tùy chọn là chuỗi \"disabled\" thì sẽ không có phím nóng nào " -#~ "thực hiện hành động này." +#~ "Tìm thấy \"%s\" trong cơ sở dữ liệu cấu hình không phải giá trị hợp lệ " +#~ "cho tổ hợp phím \"%s\".\n" #~ msgid "" -#~ "The keybinding used to toggle always on top. A window that is always on " -#~ "top will always be visible over other overlapping windows. The format " -#~ "looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -#~ "parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." +#~ "Could not acquire window manager selection on screen %d display \"%s\"\n" #~ msgstr "" -#~ "Tổ hợp phím để bật tắt hiện cửa sổ ở trên cùng. Cửa sổ đó sẽ hiện bên " -#~ "trên tất cả các cửa sổ khác. Dạng thức tương tự như \"<Control>a\" " -#~ "hoặc \"<Shift><Alt>F1\". Bộ phân tích hiểu cả chữ hoa lẫn chữ " -#~ "thường, và cả những từ viết tắt như \"<Ctl>\" và \"<Ctrl>\". " -#~ "Nếu bạn đặt tùy chọn là chuỗi đặc biệt «disabled» thì sẽ không có tổ hợp " -#~ "phím nào thực hiện hành động này." +#~ "Không thể lấy vùng chọn bộ quản lý cửa sổ trên Màn hình %d trên bộ trình " +#~ "bày \"%s\".\n" -#~ msgid "" -#~ "The keybinding used to toggle fullscreen mode. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Phím nóng để bật tắt chế độ toàn màn hình. Dạng thức tương tự như \"<" -#~ "Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân tích hiểu cả " -#~ "chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>\" và " -#~ "\"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi \"disabled\" thì sẽ không " -#~ "có phím nóng nào thực hiện hành động này." +#~ msgid "Could not release screen %d on display \"%s\"\n" +#~ msgstr "Không thể giải phóng Màn hình %d trên bộ trình bày \"%s\".\n" -#~ msgid "" -#~ "The keybinding used to toggle maximization. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Phím nóng để bật tắt phóng to. Dạng thức tương tự như \"<Control>a" -#~ "\" hoặc \"<Shift><Alt>F1\". Bộ phân tích hiểu cả chữ hoa lẫn " -#~ "chữ thường, và cả những từ viết tắt như \"<Ctl>\" và \"<Ctrl>" -#~ "\". Nếu bạn đặt tùy chọn là chuỗi \"disabled\" thì sẽ không có phím nóng " -#~ "nào thực hiện hành động này." +#~ msgid "Could not create directory '%s': %s\n" +#~ msgstr "Không thể tạo thư mục \"%s\": %s\n" -#~ msgid "" -#~ "The keybinding used to toggle shaded/unshaded state. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Tổ hợp phím để bật tắt trạng thái đánh bóng. Dạng thức tương tự như \"<" -#~ "Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân tích hiểu cả " -#~ "chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>\" và " -#~ "\"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi đặc biệt «disabled» thì " -#~ "sẽ không có phím nóng nào thực hiện hành động này." +#~ msgid "Could not open session file '%s' for writing: %s\n" +#~ msgstr "Không thể mở tập tin phiên làm việc \"%s\" để ghi: %s\n" -#~ msgid "" -#~ "The keybinding used to toggle whether the window is on all workspaces or " -#~ "just one. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Phím tắt để bật tắt việc cửa sổ hiện trên mọi vùng làm việc hay chỉ một " -#~ "vùng làm việc. Dạng thức tương tự như \"<Control>a\" hoặc \"<" -#~ "Shift><Alt>F1\". Bộ phân tích hiểu cả chữ hoa lẫn chữ thường, và " -#~ "cả những từ viết tắt như \"<Ctl>\" và \"<Ctrl>\". Nếu bạn đặt " -#~ "tùy chọn là chuỗi đặc biệt «disabled» thì sẽ không có tổ hợp phím nào " -#~ "thực hiện hành động này." +#~ msgid "Error writing session file '%s': %s\n" +#~ msgstr "Gặp lỗi khi ghi tập tin phiên làm việc \"%s\": %s\n" -#~ msgid "" -#~ "The keybinding used to unmaximize a window. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Phím tắt để bỏ phóng to cửa sổ. Dạng thức tương tự như \"<Control>a" -#~ "\" hoặc \"<Shift><Alt>F1\". Bộ phân tích hiểu cả chữ hoa lẫn " -#~ "chữ thường, và cả những từ viết tắt như \"<Ctl>\" và \"<Ctrl>" -#~ "\". Nếu bạn đặt tùy chọn là chuỗi \"disabled\" thì sẽ không có phím nóng " -#~ "nào thực hiện hành động này." +#~ msgid "Error closing session file '%s': %s\n" +#~ msgstr "Gặp lỗi khi đóng tập tin phiên làm việc \"%s\": %s\n" -#~ msgid "" -#~ "The keybinding which display's the panel's \"Run Application\" dialog " -#~ "box. The format looks like \"<Control>a\" or \"<Shift><" -#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If " -#~ "you set the option to the special string \"disabled\", then there will be " -#~ "no keybinding for this action." -#~ msgstr "" -#~ "Tổ hợp phím dùng để hiện hộp thoại «Chạy chương trình» của bảng điều " -#~ "khiển. Dạng thức tương tự như \"<Control>a\" hoặc \"<Shift>" -#~ "<Alt>F1\". Bộ phân tích hiểu cả chữ hoa lẫn chữ thường, và cả những " -#~ "từ viết tắt như \"<Ctl>\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn " -#~ "là chuỗi đặc biệt «disabled» thì sẽ không có tổ hợp phím nào thực hiện " -#~ "hành động này." +#~ msgid "Failed to parse saved session file: %s\n" +#~ msgstr "Lỗi phân tích tập tin phiên làm việc đã lưu: %s\n" -#~ msgid "" -#~ "The keybinding which invokes a terminal. The format looks like \"<" -#~ "Control>a\" or \"<Shift><Alt>F1\". The parser is fairly " -#~ "liberal and allows lower or upper case, and also abbreviations such as " -#~ "\"<Ctl>\" and \"<Ctrl>\". If you set the option to the " -#~ "special string \"disabled\", then there will be no keybinding for this " -#~ "action." -#~ msgstr "" -#~ "Tổ hợp phím dùng để gọi một thiết bị cuối. Dạng thức tương tự như \"<" -#~ "Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân tích hiểu cả " -#~ "chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>\" và " -#~ "\"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi đặc biệt «disabled» thì " -#~ "sẽ không có tổ hợp phím nào thực hiện hành động này." +#~ msgid "<mutter_session> attribute seen but we already have the session ID" +#~ msgstr "Thấy thuộc tính <mutter_session>, nhưng đã có session ID" -#~ msgid "" -#~ "The keybinding which invokes the panel's screenshot utility to take a " -#~ "screenshot of a window. The format looks like \"<Control>a\" or " -#~ "\"<Shift><Alt>F1\". The parser is fairly liberal and allows " -#~ "lower or upper case, and also abbreviations such as \"<Ctl>\" and " -#~ "\"<Ctrl>\". If you set the option to the special string \"disabled" -#~ "\", then there will be no keybinding for this action." -#~ msgstr "" -#~ "Phím nóng dùng để chụp hình cửa sổ. Dạng thức tương tự như \"<" -#~ "Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân tích hiểu cả " -#~ "chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>\" và " -#~ "\"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi \"disabled\" thì sẽ không " -#~ "có phím nóng nào thực hiện hành động này." +#~ msgid "Unknown attribute %s on <%s> element" +#~ msgstr "Không nhận ra thuộc tính %s trên phần tử <%s>" -#~ msgid "" -#~ "The keybinding which invokes the panel's screenshot utility. The format " -#~ "looks like \"<Control>a\" or \"<Shift><Alt>F1\". The " -#~ "parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Phím nóng dùng để gọi tiện ích chụp hình. Dạng thức tương tự như \"<" -#~ "Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân tích hiểu cả " -#~ "chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>\" và " -#~ "\"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi \"disabled\" thì sẽ không " -#~ "có phím nóng nào thực hiện hành động này." +#~ msgid "nested <window> tag" +#~ msgstr "thẻ <window> lồng nhau" -#~ msgid "" -#~ "The keybinding which shows the panel's main menu. The format looks like " -#~ "\"<Control>a\" or \"<Shift><Alt>F1\". The parser is " -#~ "fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Tổ hợp phím dùng để hiện trình đơn chính của bảng điều khiển. Dạng thức " -#~ "tương tự như \"<Control>a\" hoặc \"<Shift><Alt>F1\". Bộ " -#~ "phân tích hiểu cả chữ hoa lẫn chữ thường, và cả những từ viết tắt như " -#~ "\"<Ctl>\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi đặc " -#~ "biệt «disabled» thì sẽ không có phím nóng nào thực hiện hành động này." +#~ msgid "Unknown element %s" +#~ msgstr "Phần tử lạ %s" -#~ msgid "" -#~ "This keybinding changes whether a window is above or below other windows. " -#~ "If the window is covered by another one, it raises the window above all " -#~ "others, and if the window is already fully visible, it lowers it below " -#~ "all others. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Tổ hợp phím để đặt cửa sổ ở trên hay ở dưới cửa sổ khác. Nếu cửa sổ bị " -#~ "che bởi cửa sổ khác, nó sẽ được đặt lên trên. Nếu cửa sổ đã nằm trên, nó " -#~ "sẽ được đặt xuống dưới các cửa sổ khác. Dạng thức tương tự như \"<" -#~ "Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân tách hiểu cả " -#~ "chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>\" và " -#~ "\"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi đặc biệt « disabled " -#~ "» (tắt) thì sẽ không có phím nóng nào thực hiện hành động này." +#~ msgid "Failed to open debug log: %s\n" +#~ msgstr "Lỗi mở bản ghi gỡ lỗi: %s\n" -#~ msgid "" -#~ "This keybinding lowers a window below other windows. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Phím tắt để đặt cửa sổ ở dưới các cửa sổ khác. Dạng thức tương tự như " -#~ "\"<Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân tích " -#~ "hiểu cả chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>" -#~ "\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi \"disabled\" thì sẽ " -#~ "không có phím nóng nào thực hiện hành động này." +#~ msgid "Failed to fdopen() log file %s: %s\n" +#~ msgstr "Lỗi fdopen() tập tin ghi lưu %s: %s\n" -#~ msgid "" -#~ "This keybinding moves a window against the north (top) side of the " -#~ "screen. The format looks like \"<Control>a\" or \"<Shift><" -#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If " -#~ "you set the option to the special string \"disabled\", then there will be " -#~ "no keybinding for this action." -#~ msgstr "" -#~ "Phím tắt để đặt cửa sổ theo hướng bắc (đỉnh) màn hình. Dạng thức tương tự " -#~ "như \"<Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân " -#~ "tích hiểu cả chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<" -#~ "Ctl>\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi \"disabled\" " -#~ "thì sẽ không có phím nóng nào thực hiện hành động này." +#~ msgid "Opened log file %s\n" +#~ msgstr "Đã mở tập tin ghi lưu %s.\n" -#~ msgid "" -#~ "This keybinding moves a window into the east (right) side of the screen. " -#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>" -#~ "F1\". The parser is fairly liberal and allows lower or upper case, and " -#~ "also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -#~ "set the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Phím tắt để đặt cửa sổ theo hướng đông (bên phải) màn hình. Dạng thức " -#~ "tương tự như \"<Control>a\" hoặc \"<Shift><Alt>F1\". Bộ " -#~ "phân tích hiểu cả chữ hoa lẫn chữ thường, và cả những từ viết tắt như " -#~ "\"<Ctl>\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi " -#~ "\"disabled\" thì sẽ không có phím nóng nào thực hiện hành động này." +#~ msgid "Window manager: " +#~ msgstr "Bộ quản lý cửa sổ: " -#~ msgid "" -#~ "This keybinding moves a window into the north-east (top right) corner of " -#~ "the screen. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Phím tắt để đặt cửa sổ theo hướng đông bắc (góc trên bên phải) màn hình. " -#~ "Dạng thức tương tự như \"<Control>a\" hoặc \"<Shift><" -#~ "Alt>F1\". Bộ phân tích hiểu cả chữ hoa lẫn chữ thường, và cả những từ " -#~ "viết tắt như \"<Ctl>\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn là " -#~ "chuỗi \"disabled\" thì sẽ không có phím nóng nào thực hiện hành động này." +#~ msgid "Bug in window manager: " +#~ msgstr "Lỗi trong bộ quản lý cửa sổ: " -#~ msgid "" -#~ "This keybinding moves a window into the north-west (top left) corner of " -#~ "the screen. The format looks like \"<Control>a\" or \"<Shift>" -#~ "<Alt>F1\". The parser is fairly liberal and allows lower or upper " -#~ "case, and also abbreviations such as \"<Ctl>\" and \"<Ctrl>" -#~ "\". If you set the option to the special string \"disabled\", then there " -#~ "will be no keybinding for this action." -#~ msgstr "" -#~ "Phím tắt để đặt cửa sổ theo hướng tây bắc (góc trên bên trái) màn hình. " -#~ "Dạng thức tương tự như \"<Control>a\" hoặc \"<Shift><" -#~ "Alt>F1\". Bộ phân tích hiểu cả chữ hoa lẫn chữ thường, và cả những từ " -#~ "viết tắt như \"<Ctl>\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn là " -#~ "chuỗi \"disabled\" thì sẽ không có phím nóng nào thực hiện hành động này." +#~ msgid "Window manager warning: " +#~ msgstr "Cảnh báo bộ quản lý cửa sổ: " -#~ msgid "" -#~ "This keybinding moves a window into the south (bottom) side of the " -#~ "screen. The format looks like \"<Control>a\" or \"<Shift><" -#~ "Alt>F1\". The parser is fairly liberal and allows lower or upper case, " -#~ "and also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If " -#~ "you set the option to the special string \"disabled\", then there will be " -#~ "no keybinding for this action." -#~ msgstr "" -#~ "Phím tắt để đặt cửa sổ theo hướng nam (đáy) màn hình. Dạng thức tương tự " -#~ "như \"<Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân " -#~ "tích hiểu cả chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<" -#~ "Ctl>\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi \"disabled\" " -#~ "thì sẽ không có phím nóng nào thực hiện hành động này." +#~ msgid "Window manager error: " +#~ msgstr "Lỗi bộ quản lý cửa sổ: " #~ msgid "" -#~ "This keybinding moves a window into the south-east (bottom right) corner " -#~ "of the screen. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." +#~ "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " +#~ "window as specified in the ICCCM.\n" #~ msgstr "" -#~ "Phím tắt để đặt cửa sổ theo hướng đông nam (góc dưới bên phải) màn hình. " -#~ "Dạng thức tương tự như \"<Control>a\" hoặc \"<Shift><" -#~ "Alt>F1\". Bộ phân tích hiểu cả chữ hoa lẫn chữ thường, và cả những từ " -#~ "viết tắt như \"<Ctl>\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn là " -#~ "chuỗi \"disabled\" thì sẽ không có phím nóng nào thực hiện hành động này." +#~ "Cửa sổ %s tự đặt SM_CLIENT_ID cho chính nó, thay vì đặt trên cửa sổ " +#~ "WM_CLIENT_LEADER như quy định trong ICCCM.\n" #~ msgid "" -#~ "This keybinding moves a window into the south-west (bottom left) corner " -#~ "of the screen. The format looks like \"<Control>a\" or \"<" -#~ "Shift><Alt>F1\". The parser is fairly liberal and allows lower " -#~ "or upper case, and also abbreviations such as \"<Ctl>\" and \"<" -#~ "Ctrl>\". If you set the option to the special string \"disabled\", " -#~ "then there will be no keybinding for this action." +#~ "Window %s sets an MWM hint indicating it isn't resizable, but sets min " +#~ "size %d x %d and max size %d x %d; this doesn't make much sense.\n" #~ msgstr "" -#~ "Phím tắt để đặt cửa sổ theo hướng tây nam (góc dưới bên trái) màn hình. " -#~ "Dạng thức tương tự như \"<Control>a\" hoặc \"<Shift><" -#~ "Alt>F1\". Bộ phân tích hiểu cả chữ hoa lẫn chữ thường, và cả những từ " -#~ "viết tắt như \"<Ctl>\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn là " -#~ "chuỗi \"disabled\" thì sẽ không có phím nóng nào thực hiện hành động này." +#~ "Cửa sổ %s đặt gợi ý MWM rằng nó không thể bị thay đổi kích thước, nhưng " +#~ "đặt kích thước tối thiểu %d x %d và tối đa %d x %d; không hợp lý lắm.\n" -#~ msgid "" -#~ "This keybinding moves a window into the west (left) side of the screen. " -#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>" -#~ "F1\". The parser is fairly liberal and allows lower or upper case, and " -#~ "also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " -#~ "set the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Phím tắt để đặt cửa sổ theo hướng tây (bên trái) màn hình. Dạng thức " -#~ "tương tự như \"<Control>a\" hoặc \"<Shift><Alt>F1\". Bộ " -#~ "phân tích hiểu cả chữ hoa lẫn chữ thường, và cả những từ viết tắt như " -#~ "\"<Ctl>\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi " -#~ "\"disabled\" thì sẽ không có phím nóng nào thực hiện hành động này." +#~ msgid "Application set a bogus _NET_WM_PID %lu\n" +#~ msgstr "Ứng dụng đã đặt _NET_WM_PID giả %lu.\n" -#~ msgid "" -#~ "This keybinding raises the window above other windows. The format looks " -#~ "like \"<Control>a\" or \"<Shift><Alt>F1\". The parser " -#~ "is fairly liberal and allows lower or upper case, and also abbreviations " -#~ "such as \"<Ctl>\" and \"<Ctrl>\". If you set the option to " -#~ "the special string \"disabled\", then there will be no keybinding for " -#~ "this action." -#~ msgstr "" -#~ "Phím tắt để đặt cửa sổ ở trên các cửa sổ khác. Dạng thức tương tự như " -#~ "\"<Control>a\" hoặc \"<Shift><Alt>F1\". Bộ phân tích " -#~ "hiểu cả chữ hoa lẫn chữ thường, và cả những từ viết tắt như \"<Ctl>" -#~ "\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi \"disabled\" thì sẽ " -#~ "không có phím nóng nào thực hiện hành động này." +#~ msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +#~ msgstr "Cửa sổ WM_TRANSIENT_FOR không hợp lệ 0x%lx được xác định cho %s.\n" -#~ msgid "" -#~ "This keybinding resizes a window to fill available horizontal space. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." -#~ msgstr "" -#~ "Tổ hợp phím này dùng để giãn cửa sổ hết chiều ngang hiện có. Dạng thức " -#~ "tương tự như \"<Control>a\" hoặc \"<Shift><Alt>F1\". " -#~ "Trình phân tích hiểu cả chữ hoa lẫn chữ thường, và cả những từ viết tắt " -#~ "như \"<Ctl>\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi " -#~ "đặc biệt «disabled» thì sẽ không có tổ hợp phím nào thực hiện hành động " -#~ "này." +#~ msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" +#~ msgstr "Cửa sổ WM_TRANSIENT_FOR 0x%lx cho %s tạo vòng lặp.\n" #~ msgid "" -#~ "This keybinding resizes a window to fill available vertical space. The " -#~ "format looks like \"<Control>a\" or \"<Shift><Alt>F1\". " -#~ "The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " -#~ "keybinding for this action." +#~ "Window 0x%lx has property %s\n" +#~ "that was expected to have type %s format %d\n" +#~ "and actually has type %s format %d n_items %d.\n" +#~ "This is most likely an application bug, not a window manager bug.\n" +#~ "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" #~ msgstr "" -#~ "Tổ hợp phím này dùng để giãn cửa sổ hết chiều dọc hiện có. Dạng thức " -#~ "tương tự như \"<Control>a\" hoặc \"<Shift><Alt>F1\". " -#~ "Trình phân tích hiểu cả chữ hoa lẫn chữ thường, và cả những từ viết tắt " -#~ "như \"<Ctl>\" và \"<Ctrl>\". Nếu bạn đặt tùy chọn là chuỗi " -#~ "đặc biệt «disabled» thì sẽ không có tổ hợp phím nào thực hiện hành động " -#~ "này." +#~ "Cửa sổ 0x%lx có thuộc tính %s\n" +#~ "mà lẽ ra phải có kiểu %s dạng thức %d\n" +#~ "và thực sự là kiểu %s dạng thức “%d n_items %d”.\n" +#~ "Chắc là có một ứng dụng bị lỗi, không phải lỗi trình quản lý cửa sổ.\n" +#~ "Cửa sổ có title=\"%s\" class=\"%s\" name=\"%s\"\n" -#~ msgid "Toggle always on top state" -#~ msgstr "Bật/Tắt trạng thái luôn nổi" - -#~ msgid "Toggle window on all workspaces" -#~ msgstr "Chốt cửa sổ trên mọi vùng làm việc" - -#~ msgid "Unmaximize window" -#~ msgstr "Bỏ phóng to cửa sổ" - -#~ msgid "Unmaximize Window" -#~ msgstr "Bỏ phóng to cửa sổ" - -#~ msgid "No \"%s\" attribute on <%s> element" -#~ msgstr "Không có thuộc tính « %s » trong phần tử <%s>." - -#~ msgid "Theme already has a fallback icon" -#~ msgstr "Sắc thái đã có biểu tượng dự phòng" - -#~ msgid "Theme already has a fallback mini_icon" -#~ msgstr "Sắc thái đã có biểu tượng mini dự phòng" - -#~ msgid "No \"name\" attribute on element <%s>" -#~ msgstr "Không có thuộc tính «name» (tên) trong phần tử <%s>." - -#~ msgid "No \"value\" attribute on element <%s>" -#~ msgstr "Không có thuộc tính «value» (giá trị) trong phần tử <%s>." +#~ msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +#~ msgstr "Thuộc tính %s trên cửa sổ 0x%lx chứa chuỗi UTF-8 sai.\n" #~ msgid "" -#~ "Cannot specify both button_width/button_height and aspect ratio for " -#~ "buttons" +#~ "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the " +#~ "list\n" #~ msgstr "" -#~ "Không thể xác định cả « button_width/button_height » (rộng/cao nút) lẫn " -#~ "tỷ lệ hình thể đều của cái nút." +#~ "Thuộc tính %s trên cửa sổ 0x%lx chứa chuỗi UTF-8 sai cho mục %d trong " +#~ "danh sách.\n" -#~ msgid "No \"top\" attribute on element <%s>" -#~ msgstr "Không có thuộc tính «top» (đính) trong phần tử <%s>." +#~ msgid "Usage: %s\n" +#~ msgstr "Cách dùng: %s\n" -#~ msgid "No \"bottom\" attribute on element <%s>" -#~ msgstr "Không có thuộc tính «bottom» (đáy) trong phần tử <%s>." +#~ msgid "Mi_nimize" +#~ msgstr "Th_u nhỏ" -#~ msgid "No \"left\" attribute on element <%s>" -#~ msgstr "Không có thuộc tính «left» (bên trái) trong phần tử <%s>." +#~ msgid "Ma_ximize" +#~ msgstr "_Phóng to" -#~ msgid "No \"right\" attribute on element <%s>" -#~ msgstr "Không có thuộc tính «right» (bên phải) trong phần tử <%s>." +#~ msgid "Unma_ximize" +#~ msgstr "_Bỏ phóng to" -#~ msgid "No \"color\" attribute on element <%s>" -#~ msgstr "Không có thuộc tính «color» (màu) trong phần tử <%s>." +#~ msgid "Roll _Up" +#~ msgstr "Cuộn _lên" -#~ msgid "No \"x1\" attribute on element <%s>" -#~ msgstr "Không có thuộc tính «x1» trong phần tử <%s>." +#~ msgid "_Unroll" +#~ msgstr "_Bỏ cuộn" -#~ msgid "No \"y1\" attribute on element <%s>" -#~ msgstr "Không có thuộc tính «y1» trong phần tử <%s>" +#~ msgid "_Move" +#~ msgstr "D_i chuyển" -#~ msgid "No \"x2\" attribute on element <%s>" -#~ msgstr "Không có thuộc tính «x2» trong phần tử <%s>" - -#~ msgid "No \"y2\" attribute on element <%s>" -#~ msgstr "Không có thuộc tính «y2» trong phần tử <%s>." - -#~ msgid "No \"x\" attribute on element <%s>" -#~ msgstr "Không có thuộc tính «x» trong phần tử <%s>." - -#~ msgid "No \"y\" attribute on element <%s>" -#~ msgstr "Không có thuộc tính «y» trong phần tử <%s>." - -#~ msgid "No \"width\" attribute on element <%s>" -#~ msgstr "Không có thuộc tính «width» (độ rộng) trong phần tử <%s>." - -#~ msgid "No \"height\" attribute on element <%s>" -#~ msgstr "Không có thuộc tính «height» (độ cao) trong phần tử <%s>." - -#~ msgid "No \"start_angle\" attribute on element <%s>" -#~ msgstr "Không có thuộc tính «start_angle» (góc bắt đầu) trong phần tử <%s>." - -#~ msgid "No \"extent_angle\" attribute on element <%s>" -#~ msgstr "" -#~ "Không có thuộc tính «extent_angle» (góc phạm vi) trong phần tử <%s>." +#~ msgid "_Resize" +#~ msgstr "C_o giãn" -#~ msgid "No \"alpha\" attribute on element <%s>" -#~ msgstr "Không có thuộc tính «alpha» (anfa) trong phần tử <%s>." +#~ msgid "Move Titlebar On_screen" +#~ msgstr "Chuyển Thanh Tựa Đề trên _màn hình" -#~ msgid "No \"type\" attribute on element <%s>" -#~ msgstr "Không có thuộc tính «type» (loại) trong phần tử <%s>." +#~ msgid "Always on _Top" +#~ msgstr "_Luôn ở trên" -#~ msgid "No \"filename\" attribute on element <%s>" -#~ msgstr "Không có thuộc tính «filename» (tên tập tin) trong phần tử <%s>." +#~ msgid "_Always on Visible Workspace" +#~ msgstr "Chỉ trong vùng làm việc có thể thấ_y" -#~ msgid "No \"state\" attribute on element <%s>" -#~ msgstr "Không có thuộc tính «state» (tính trạng) trong phần tử <%s>." +#~ msgid "_Only on This Workspace" +#~ msgstr "Chỉ trong vùng làm việc _này" -#~ msgid "No \"shadow\" attribute on element <%s>" -#~ msgstr "Không có thuộc tính «shadow» trong phần tử <%s>" +#~ msgid "Move to Workspace _Left" +#~ msgstr "Chuyển sang vùng làm việc bên t_rái" -#~ msgid "No \"arrow\" attribute on element <%s>" -#~ msgstr "Không có thuộc tính «arrow» (mũi tên) trong phần tử <%s>." +#~ msgid "Move to Workspace R_ight" +#~ msgstr "Chuyển sang vùng làm việc bên _phải" -#~ msgid "No \"value\" attribute on <%s> element" -#~ msgstr "Không có thuộc tính «value» (giá trị) trong phần tử <%s>." +#~ msgid "Move to Workspace _Up" +#~ msgstr "Chuyển sang vùng làm việc bên _trên" -#~ msgid "No \"position\" attribute on <%s> element" -#~ msgstr "Không có thuộc tính «position» (vị trí) trong phần tử <%s>." +#~ msgid "Move to Workspace _Down" +#~ msgstr "Chuyển sang vùng làm việc bên _dưới" -#~ msgid "No \"function\" attribute on <%s> element" -#~ msgstr "Không có thuộc tính «function» (chức năng) trong phần tử <%s>." +#~ msgid "_Close" +#~ msgstr "Đón_g" -#~ msgid "No \"state\" attribute on <%s> element" -#~ msgstr "Không có thuộc tính «state» (tính trạng) trong phần tử <%s>." +#~ msgid "Workspace %d%n" +#~ msgstr "Vùng làm việc %d%n" -#~ msgid "No \"focus\" attribute on <%s> element" -#~ msgstr "Không có thuộc tính «focus» (tiêu điểm) trong phần tử <%s>." +#~ msgid "Workspace 1_0" +#~ msgstr "Vùng làm việc 1_0" -#~ msgid "No \"style\" attribute on <%s> element" -#~ msgstr "Không có thuộc tính «style» (kiểu dáng) trong phần tử <%s>." +#~ msgid "Workspace %s%d" +#~ msgstr "Vùng làm việc %s%d" -#~ msgid "No \"resize\" attribute on <%s> element" -#~ msgstr "Không có thuộc tính «resize» (đổi cỡ) trong phần tử <%s>." +#~ msgid "Move to Another _Workspace" +#~ msgstr "Chuyển sang vùng làm việc _khác" diff --git a/po/wa.po b/po/wa.po index 9ed11d857..ab97c9958 100644 --- a/po/wa.po +++ b/po/wa.po @@ -15,6 +15,7 @@ msgstr "" "PO-Revision-Date: 2003-07-12 14:51+0200\n" "Last-Translator: Pablo Saratxaga <pablo@mandrakesoft.com>\n" "Language-Team: Walon <linux-wa@walon.org>\n" +"Language: wa\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" diff --git a/po/xh.po b/po/xh.po index 6e012c61f..1fc6ab6ec 100644 --- a/po/xh.po +++ b/po/xh.po @@ -12,6 +12,7 @@ msgstr "" "PO-Revision-Date: 2005-03-22 18:03+0200\n" "Last-Translator: Canonical Ltd <translations@canonical.com>\n" "Language-Team: Xhosa <xh-translate@ubuntu.com>\n" +"Language: xh\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" diff --git a/po/yo.po b/po/yo.po index 8b4640666..857f9c45b 100644 --- a/po/yo.po +++ b/po/yo.po @@ -7,6 +7,7 @@ msgstr "" "PO-Revision-Date: 2006-08-09 13:26+0100\n" "Last-Translator: Fajuyitan, Sunday Ayo <ayo@wazobialinux.com>\n" "Language-Team: Yoruba\n" +"Language: yo\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" diff --git a/po/zh_CN.po b/po/zh_CN.po index 5a9f4054a..47f6d2c0b 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -1,6 +1,6 @@ -# translation of muffin.po to zh_CN -# Simplified Chinese translation of muffin. -# Copyright (C) 2002, 2003, 2004, 2009, 2010 Free Software Foundation, Inc. +# Simplified Chinese translation of mutter. +# Copyright (C) 2012-2019 mutter's COPYRIGHT HOLDER +# This file is distributed under the same license as the mutter package. # Sun G11n <gnome_int_l10n@ireland.sun.com>, 2002. # He Qiangqiang <carton@linux.net.cn>, 2002 # Xiong Jiang <jxiong@offtopic.org>, 2003 @@ -10,1539 +10,1556 @@ # Yinghua Wang <wantinghard@gmail.com>, 2010. # Lele Long <schemacs@gmail.com>, 2011. # YunQiang Su <wzssyqa@gmail.com>, 2011, 2012. +# Tong Hui <tonghuix@gmail.com>, 2014. +# Mandy Wang <wangmychn@gmail.com>, 2017. +# Mingcong Bai <jeffbai@aosc.xyz>, 2017. +# liushuyu <liushuyu011@gmail.com>, 2018. +# Dingzhong Chen <wsxy162@gmail.com>, 2017-2019. # msgid "" msgstr "" -"Project-Id-Version: muffin master\n" -"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" -"product=muffin&keywords=I18N+L10N&component=general\n" -"POT-Creation-Date: 2012-03-19 15:55+0000\n" -"PO-Revision-Date: 2012-03-20 17:10+0000\n" -"Last-Translator: YunQiang Su <wzssyqa@gmail.com>\n" -"Language-Team: Chinese (simplified) <i18n-zh@googlegroups.com>\n" +"Project-Id-Version: mutter master\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2019-08-31 12:39+0000\n" +"PO-Revision-Date: 2019-09-11 00:10+0800\n" +"Last-Translator: Dingzhong Chen <wsxy162@gmail.com>\n" +"Language-Team: Chinese (China) <i18n-zh@googlegroups.com>\n" +"Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bits\n" +"Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Gtranslator 3.32.1\n" -#: ../src/50-muffin-windows.xml.in.h:1 +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "导航" + +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "将窗口移到工作区 1" + +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "将窗口移到工作区 2" + +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "将窗口移到工作区 3" + +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "将窗口移到工作区 4" + +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "将窗口移到最后一个工作区" + +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "将窗口上移一个工作区" + +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "将窗口下移一个工作区" + +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "将窗口左移一个显示器" + +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "将窗口右移一个显示器" + +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "将窗口上移一个显示器" + +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "将窗口下移一个显示器" + +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "切换应用程序" + +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "切换到前一个应用程序" + +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "切换窗口" + +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "切换到前一个窗口" + +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "在应用程序的窗口之间切换窗口" + +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "切换到一个应用程序的前一个窗口" + +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "切换系统控制" + +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "切换到前一个系统控制" + +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "直接切换窗口" + +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "直接切换到前一个窗口" + +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "在应用程序窗口间直接移动焦点" + +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "直接切换到一个应用程序的前一个窗口" + +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "直接切换系统控制" + +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "直接切换到前一个系统控制" + +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "隐藏所有正常窗口" + +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "切换到工作区 1" + +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "切换到工作区 2" + +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "切换到工作区 3" + +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "切换到工作区 4" + +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "切换到最后一个工作区" + +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "移动到上层工作区" + +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "移动到下层工作区" + +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "系统" + +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "显示运行命令提示符" + +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "显示活动视图" + +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "还原键盘快捷键" + +#: data/50-mutter-windows.xml:6 msgid "Windows" msgstr "窗口" -#: ../src/50-muffin-windows.xml.in.h:2 +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "激活窗口菜单" + +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "切换全屏模式" + +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "切换最大化状态" + +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "最大化窗口" + +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "恢复窗口" + +#: data/50-mutter-windows.xml:18 +msgid "Close window" +msgstr "关闭窗口" + +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "隐藏窗口" + +#: data/50-mutter-windows.xml:22 +msgid "Move window" +msgstr "移动窗口" + +#: data/50-mutter-windows.xml:24 +msgid "Resize window" +msgstr "改变窗口大小" + +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "在位于所有或仅一个工作区的窗口间切换" + +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "如果窗口被其他窗口遮盖,则提升它,否则降低它" + +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "将窗口提升到其它窗口之上" + +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "将窗口降低到其它窗口之下" + +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "垂直最大化窗口" + +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "水平最大化窗口" + +#: data/50-mutter-windows.xml:41 msgid "View split on left" -msgstr "" +msgstr "在左侧查看分割" -#: ../src/50-muffin-windows.xml.in.h:3 +#: data/50-mutter-windows.xml:45 msgid "View split on right" +msgstr "在右侧查看分割" + +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" + +#: data/org.gnome.mutter.gschema.xml.in:7 +msgid "Modifier to use for extended window management operations" +msgstr "用于修改窗口点击动作的修饰键 met" + +#: data/org.gnome.mutter.gschema.xml.in:8 +msgid "" +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." msgstr "" +"这个键指出的“覆盖”是一种混合窗口概述和应用程序运行的系统。默认要求使用 " +"“Super 键”。可能使用默认或者空白。" -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:20 +msgid "Attach modal dialogs" +msgstr "依附模态对话框" + +#: data/org.gnome.mutter.gschema.xml.in:21 msgid "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." -msgstr "DISPLAY %2$s 的屏幕 %1$i 上已有另外一个混成窗口管理器正在运行。" +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." +msgstr "" +"当为 true 时,模态对话框会依附在父窗口的标题栏出现,并随父窗口移动,而不使用" +"单独的标题栏。" -#: ../src/core/bell.c:307 -msgid "Bell event" -msgstr "响铃事件" +#: data/org.gnome.mutter.gschema.xml.in:30 +msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "当窗口位于屏幕边缘时,启用边缘平铺" -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "未知的窗口信息请求:%d" +#: data/org.gnome.mutter.gschema.xml.in:31 +msgid "" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." +msgstr "" +"如果启用,将窗口拖放到屏幕竖直边缘时会将窗口纵向最大化、横向占据半屏;将窗口" +"拖放到屏幕上边缘时会将窗口最大化。" -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> 未响应。" +#: data/org.gnome.mutter.gschema.xml.in:40 +msgid "Workspaces are managed dynamically" +msgstr "动态管理工作区" -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "应用程序未响应。" +#: data/org.gnome.mutter.gschema.xml.in:41 +msgid "" +"Determines whether workspaces are managed dynamically or whether there’s a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." +msgstr "" +"决定工作区动态管理还是静态数量的工作区(由 org.gnome.desktop.wm.preferences " +"中的 num-workspaces 键确定)。" -#: ../src/core/delete.c:119 +# 或者 只在主显示器上显示工作区 +#: data/org.gnome.mutter.gschema.xml.in:50 +msgid "Workspaces only on primary" +msgstr "只对主显示器上的工作区" + +# monitors 是否该翻译为 屏幕? +#: data/org.gnome.mutter.gschema.xml.in:51 msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "您可以选择稍等一会儿,或者强制退出该应用程序。" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." +msgstr "决定工作区切换对所有显示器上的窗口还是只对主显示器上的有效。" -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "等待(_W)" +#: data/org.gnome.mutter.gschema.xml.in:59 +msgid "No tab popup" +msgstr "TAB轮换不弹出" -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "强制退出(_F)" +#: data/org.gnome.mutter.gschema.xml.in:60 +msgid "" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." +msgstr "决定窗口轮换时是否禁用弹出和高亮边框。" + +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "将焦点改变推迟到光标停止移动之后" + +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" +"如果为 true,而聚焦模式为“sloppy”或“mouse”,那么进入某个窗口时焦点将不会立即" +"改变,而是等到光标停止移动之后。" + +#: data/org.gnome.mutter.gschema.xml.in:79 +msgid "Draggable border width" +msgstr "可拖拽的边界宽度" + +#: data/org.gnome.mutter.gschema.xml.in:80 +msgid "" +"The amount of total draggable borders. If the theme’s visible borders are " +"not enough, invisible borders will be added to meet this value." +msgstr "" +"可拖拽的边界总数。如果主题的可见边界不足,将添加不可见的边界来满足此值。" + +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "自动最大化接近显示器大小的窗口" + +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "如果启用,初始时为显示器大小的新窗口将自动最大化。" + +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "将窗口置于中央" + +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "为 true 时,新窗口将总是置于此显示器已激活屏幕的中央。" + +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "开启实验性功能" + +#: data/org.gnome.mutter.gschema.xml.in:108 +msgid "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes " +"mutter request a low priority real-time scheduling. The executable or user " +"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — " +"initializes Xwayland lazily if there are X11 clients. Requires restart." +msgstr "" +"要启用实验性功能,请将如下功能关键字添加到列表中。功能是否要重启合成器取决于" +"功能本身。任何实验性功能都不一定仍旧可用和可配置。请不要期望此设置中的实验性" +"功能将来有所保障。当前可用的关键字:•“scale-monitor-framebuffer”——让 Mutter " +"默认基于逻辑像素座标排布多屏幕,并同时缩放监视器帧缓冲器而不是窗口内容,以便" +"管理 HiDPI 监视器。该功能不需要重启来生效。•“rt-scheduler”——让 Mutter 请求低" +"优先级的实时调度。可执行文件或用户必须有 CAP_SYS_NICE。需要重启。•“autostart-" +"xwayland”——如果存在 X11 客户端则延迟初始化 Xwayland。需要重启。" + +#: data/org.gnome.mutter.gschema.xml.in:134 +msgid "Modifier to use to locate the pointer" +msgstr "用来定位指针的修饰键" + +#: data/org.gnome.mutter.gschema.xml.in:135 +msgid "This key will initiate the “locate pointer” action." +msgstr "此按键将启动“定位指针”操作。" + +#: data/org.gnome.mutter.gschema.xml.in:155 +msgid "Select window from tab popup" +msgstr "从 Tab 轮换弹出界面选择窗口" + +#: data/org.gnome.mutter.gschema.xml.in:160 +msgid "Cancel tab popup" +msgstr "取消 Tab 轮换弹出" + +#: data/org.gnome.mutter.gschema.xml.in:165 +msgid "Switch monitor configurations" +msgstr "切换显示器配置" + +#: data/org.gnome.mutter.gschema.xml.in:170 +msgid "Rotates the built-in monitor configuration" +msgstr "旋转内置显示器配置" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "切换到 VT 1" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "切换到 VT 2" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "切换到 VT 3" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "切换到 VT 4" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "切换到 VT 5" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "切换到 VT 6" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "切换到 VT 7" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "切换到 VT 8" -#: ../src/core/display.c:387 +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "切换到 VT 9" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "切换到 VT 10" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "切换到 VT 11" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "切换到 VT 12" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "重新启用快捷键" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +msgid "Allow X11 grabs to lock keyboard focus with Xwayland" +msgstr "允许 X11 捕获以锁定 Xwayland 的键盘焦点" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 +msgid "" +"Allow all keyboard events to be routed to X11 “override redirect” windows " +"with a grab when running in Xwayland. This option is to support X11 clients " +"which map an “override redirect” window (which do not receive keyboard " +"focus) and issue a keyboard grab to force all keyboard events to that " +"window. This option is seldom used and has no effect on regular X11 windows " +"which can receive keyboard focus under normal circumstances. For a X11 grab " +"to be taken into account under Wayland, the client must also either send a " +"specific X11 ClientMessage to the root window or be among the applications " +"white-listed in key “xwayland-grab-access-rules”." +msgstr "" +"当运行在 Xwayland 下时,允许通过捕获,发送所有的键盘事件到 X11“覆盖重定向”窗" +"口。此选项是为了支持(收不到键盘焦点的)“覆盖重定向”窗口所映射的 X11 客户端," +"并发起键盘捕获强制所有键盘事件进到那个窗口。此选项比较少用,并且对常规 X11 窗" +"口没有影响,这些窗口在正常情况下可以收到键盘焦点。在 Wayland 下,为了 X11 捕" +"获能够工作,客户端也必须发送一个指定的 X11 ClientMessage 到根窗口,或是包含" +"进“xwayland-grab-access-rules”键成为其中一个白名单应用程序。" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:84 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "允许发起键盘捕获的 Xwayland 应用程序" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:85 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "" +"Xwayland 下允许或不允许发起 X11 键盘捕获的 X11 窗口,其资源名或资源类的列表。" +"给定 X11 窗口的资源名或资源类可以使用“xprop WM_CLASS”命令获取。支持在键值中使" +"用通配符“*”和“?”。以“!”开头的键值会列入黑名单,它们的优先级高于白名单,用来撤" +"销默认系统列表中的应用程序。默认系统列表包含了下列应用程" +"序:“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” 用户可以使用键绑定键“restore-" +"shortcuts”定义的键盘快捷键来中断进行中的捕获。" + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. +#. +#: src/backends/meta-input-settings.c:2531 #, c-format -msgid "Missing %s extension required for compositing" -msgstr "缺少复合效果所需的 %s 扩展" +msgid "Mode Switch (Group %d)" +msgstr "模式切换(组别 %d)" -#: ../src/core/display.c:453 +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2554 +msgid "Switch monitor" +msgstr "切换显示器" + +#: src/backends/meta-input-settings.c:2556 +msgid "Show on-screen help" +msgstr "显示在屏帮助" + +#: src/backends/meta-monitor.c:223 +msgid "Built-in display" +msgstr "内置显示器" + +#: src/backends/meta-monitor.c:252 +msgid "Unknown" +msgstr "未知" + +#: src/backends/meta-monitor.c:254 +msgid "Unknown Display" +msgstr "未知的 Display" + +#: src/backends/meta-monitor.c:262 +#, c-format +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" + +#: src/backends/meta-monitor.c:270 #, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "无法打开 X Window System 显示“%s”\n" +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" -#: ../src/core/keybindings.c:852 +#. Translators: this string will appear in Sysprof +#: src/backends/meta-profiler.c:82 +msgid "Compositor" +msgstr "合成器" + +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:509 #, c-format msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "某个其它程序已经将按键 %s 和修饰键 %x 配合使用作为一种组合\n" +"Another compositing manager is already running on screen %i on display “%s”." +msgstr "显示器 %2$s 的屏幕 %1$i 上已有另外一个混成窗口管理器正在运行。" + +#: src/core/bell.c:192 +msgid "Bell event" +msgstr "响铃事件" -#: ../src/core/main.c:206 +#: src/core/main.c:186 msgid "Disable connection to session manager" msgstr "禁止连接到会话管理器" -#: ../src/core/main.c:212 +#: src/core/main.c:192 msgid "Replace the running window manager" msgstr "替换正在运行的窗口管理器" -#: ../src/core/main.c:218 +#: src/core/main.c:198 msgid "Specify session management ID" msgstr "指定会话管理 ID" -#: ../src/core/main.c:223 +#: src/core/main.c:203 msgid "X Display to use" -msgstr "要使用的 X 显示" +msgstr "要使用的 X Display" -#: ../src/core/main.c:229 +#: src/core/main.c:209 msgid "Initialize session from savefile" msgstr "从保存文件中初始化会话" -#: ../src/core/main.c:235 +#: src/core/main.c:215 msgid "Make X calls synchronous" msgstr "使 X 调用同步" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "扫描主题目录失败:%s\n" +#: src/core/main.c:222 +msgid "Run as a wayland compositor" +msgstr "以 wayland 合成器运行" + +#: src/core/main.c:228 +msgid "Run as a nested compositor" +msgstr "以嵌套合成器运行" -#: ../src/core/main.c:520 +#: src/core/main.c:234 +msgid "Run wayland compositor without starting Xwayland" +msgstr "运行 wayland 合成器但不启动 Xwayland" + +#: src/core/main.c:242 +msgid "Run as a full display server, rather than nested" +msgstr "以完整显示服务器方式运行,而不是以嵌套方式" + +#: src/core/main.c:248 +msgid "Run with X11 backend" +msgstr "以 X11 后端运行" + +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:151 #, c-format +msgid "“%s” is not responding." +msgstr "“%s” 未响应。" + +#: src/core/meta-close-dialog-default.c:153 +msgid "Application is not responding." +msgstr "应用程序未响应。" + +#: src/core/meta-close-dialog-default.c:158 msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "无法找到主题!请确认 %s 存在并且含有正常的主题。\n" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." +msgstr "您可以选择稍等一会儿,或者强制退出该应用程序。" + +#: src/core/meta-close-dialog-default.c:165 +msgid "_Force Quit" +msgstr "强制退出(_F)" + +#: src/core/meta-close-dialog-default.c:165 +msgid "_Wait" +msgstr "等待(_W)" -#: ../src/core/muffin.c:40 +#: src/core/mutter.c:38 #, c-format msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" "This is free software; see the source for copying conditions.\n" "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " "PARTICULAR PURPOSE.\n" msgstr "" -"muffin %s\n" -"版权所有 (C) 2001-%d Havoc Pennington, Red Hat, Inc., 以及其他\n" -"本软件为自由软件:版权条款请参见源码\n" -"不存在任何保证:即便是对商业性或者特定目的的适应性也不作保证。\n" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., 以及其他\n" +"本软件为自由软件;版权条款请参见源码\n" +"不存在任何保证;即便是对商业性或者特定目的的适应性也不作保证。\n" -#: ../src/core/muffin.c:54 +#: src/core/mutter.c:52 msgid "Print version" msgstr "打印版本" -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "逗号分开 列表和混合渲染器插件" - -#: ../src/core/prefs.c:1077 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "有缺陷的应用程序的工作区已禁用。某些应用程序可能无法正常运行。\n" +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "要使用的 Mutter 插件" -#: ../src/core/prefs.c:1152 +#: src/core/prefs.c:1849 #, c-format -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "无法解析字体说明“%s”(来自 GSettings 键 %s)\n" +msgid "Workspace %d" +msgstr "工作区 %d" + +#: src/core/util.c:122 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "Mutter 编译的时候没有加入详细模式的支持\n" -#: ../src/core/prefs.c:1218 +#: src/wayland/meta-wayland-tablet-pad.c:568 #, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "在配置数据库中找到的“%s”不是鼠标按钮修饰键的有效值\n" +msgid "Mode Switch: Mode %d" +msgstr "模式切换:%d 模式" -#: ../src/core/prefs.c:1739 +#: src/x11/meta-x11-display.c:679 #, c-format msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "在配置数据库中找到的“%s”不是按键组合“%s”的有效值\n" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." +msgstr "" +"Display“%s”已经有一个窗口管理器;请尝试使用 --replace 选项替换当前的窗口管理" +"器。" + +#: src/x11/meta-x11-display.c:1040 +msgid "Failed to initialize GDK\n" +msgstr "初始化 GDK 失败\n" -#: ../src/core/prefs.c:1836 +#: src/x11/meta-x11-display.c:1064 #, c-format -msgid "Workspace %d" -msgstr "工作区 %d" +msgid "Failed to open X Window System display “%s”\n" +msgstr "无法打开 X Window System 显示器“%s”\n" -#: ../src/core/screen.c:730 +#: src/x11/meta-x11-display.c:1147 #, c-format -msgid "Screen %d on display '%s' is invalid\n" +msgid "Screen %d on display “%s” is invalid\n" msgstr "显示“%2$s”上的屏幕 %1$d 无效\n" -#: ../src/core/screen.c:746 +#: src/x11/meta-x11-selection-input-stream.c:445 #, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"显示“%2$s”上的屏幕 %1$d 已经有一个窗口管理器;请尝试使用 --replace 选项替换当" -"前的窗口管理器。\n" +msgid "Format %s not supported" +msgstr "不支持 %s 格式" -#: ../src/core/screen.c:773 -#, c-format +#: src/x11/session.c:1821 msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "无法获得显示“%2$s”上的屏幕 %1$d 的窗口管理器选定项\n" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." +msgstr "这些窗口不支持“保存当前设置”,并且在您下次登录时,必须手动重启它们。" -#: ../src/core/screen.c:828 +#: src/x11/window-props.c:569 #, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "在显示“%2$s”上的 %1$d 屏幕已经有一个窗口管理器\n" +msgid "%s (on %s)" +msgstr "%s(于 %s)" -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "无法释放显示“%2$s”上的屏幕 %1$d\n" +#~ msgid "Move window one workspace to the left" +#~ msgstr "将窗口左移一个工作区" -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "无法创建目录“%s”:%s\n" +#~ msgid "Move window one workspace to the right" +#~ msgstr "将窗口右移一个工作区" -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "无法打开会话文件“%s”进行写入:%s\n" +#~ msgid "Move to workspace left" +#~ msgstr "移动到左侧工作区" -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "写入会话文件“%s”时出错:%s\n" +#~ msgid "Move to workspace right" +#~ msgstr "移动到右侧工作区" -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "关闭会话文件“%s”时出错:%s\n" +#~ msgid "Toggle shaded state" +#~ msgstr "切换卷起状态" -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "无法解析保存的会话文件:%s\n" +#~ msgid "Failed to scan themes directory: %s\n" +#~ msgstr "扫描主题目录失败:%s\n" -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "<muffin_session> 属性已看到,但我们已经拥有该会话 ID" +#~ msgid "" +#~ "Could not find a theme! Be sure %s exists and contains the usual themes.\n" +#~ msgstr "无法找到主题!请确认 %s 存在并且含有正常的主题。\n" -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "<%2$s> 元素上未知的属性 %1$s" +#~ msgid "Screen %d on display \"%s\" already has a window manager\n" +#~ msgstr "在显示“%2$s”上的 %1$d 屏幕已经有一个窗口管理器\n" -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "嵌套 <window> 标记" +#~ msgid "%d x %d" +#~ msgstr "%d x %d" -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "未知的元素 %s" +#~ msgid "top" +#~ msgstr "上" -#: ../src/core/session.c:1809 -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "" -"这些窗口不支持 "保存当前设置 " 您在下次登录时,必须手动重启动它" -"们。" +#~ msgid "bottom" +#~ msgstr "下" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "无法打开调试日志:%s\n" +#~ msgid "left" +#~ msgstr "左" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "无法对日志文件 %s 进行 fdopen() 操作:%s\n" +#~ msgid "right" +#~ msgstr "右" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "打开的日志文件 %s\n" +#~ msgid "frame geometry does not specify \"%s\" dimension" +#~ msgstr "框架几何布局没有指定“%s”尺寸" -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "Muffin 编译的时候没有加入详细模式的支持\n" +#~ msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" +#~ msgstr "框架几何布局没有指定“%s”尺寸(该尺寸是为边框“%s”指定的)" -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "窗口管理器:" +#~ msgid "Button aspect ratio %g is not reasonable" +#~ msgstr "按钮长宽比 %g 不合理" -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "窗口管理器中的错误:" +#~ msgid "Frame geometry does not specify size of buttons" +#~ msgstr "框架几何布局没有指定按钮大小" -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "窗口管理器警告:" +#~ msgid "Gradients should have at least two colors" +#~ msgstr "渐变应至少有两种颜色" -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "窗口管理器错误:" +#~ msgid "" +#~ "GTK custom color specification must have color name and fallback in " +#~ "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" +#~ msgstr "" +#~ "GTK 颜色规范要求色彩名称和其后备值必须在随后的圆括号内,例如 gtk:" +#~ "custom(foo,bar);无法解析“%s”" -#. first time through -#: ../src/core/window.c:7266 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"窗口 %s 在它自身上设置 SM_CLIENT_ID,而不是按照 ICCCM 规定的那样,设置在 " -"WM_CLIENT_LEADER 窗口上。\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7931 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %" -"d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"窗口 %s 设置了一个 MWM 提示,表明它是不可改变大小的,但设置最小尺寸为 %d x %" -"d,最大尺寸为 %d x %d;这没有任何意义。\n" +#~ msgid "" +#~ "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-" +#~ "z0-9-_ are valid" +#~ msgstr "gtk:custom 中包含无效的字符 %c,仅允许使用 A-Za-z0-9-_" -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "应用程序设置一个假的 _NET_WM_PID %lu\n" +#~ msgid "" +#~ "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " +#~ "fit the format" +#~ msgstr "" +#~ "Gtk:custom 的格式为 gtk:custom(color_name,fallback),“%s”不符合该格式" -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s (于 %s)" +#~ msgid "" +#~ "GTK color specification must have the state in brackets, e.g. gtk:" +#~ "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "GTK 颜色规范必须将状态包含在方括号中,例如 gtk:fg[NORMAL]其中 NORMAL 是状" +#~ "态;无法解析“%s”" -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "为 %2$s 指定了无效的 WM_TRANSIENT_FOR 窗口 0x%1$lx。\n" +#~ msgid "" +#~ "GTK color specification must have a close bracket after the state, e.g. " +#~ "gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "GTK 颜色规范必须在状态后有一个闭方括号,例如 gtk:fg[NORMAL],其中 NORMAL " +#~ "是状态;无法解析“%s”" -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "为 %2$s 指定的 WM_TRANSIENT_FOR 窗口 0x%1$lx 将导致循环。\n" +#~ msgid "Did not understand state \"%s\" in color specification" +#~ msgstr "不理解颜色规范中的状态“%s”" -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"窗口 0x%lx 的属性 %s\n" -"的期望类型为 %s、格式为 %d,\n" -"而实际类型为 %s、格式为 %d、n_items 为 %d。\n" -"这很可能是应用程序的错误,不是窗口管理器的错误。\n" -"窗口的标题为“%s”,类别为“%s”,名称为“%s”\n" +#~ msgid "Did not understand color component \"%s\" in color specification" +#~ msgstr "不理解颜色规范中的颜色组成部分“%s”" -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "窗口 0x%2$lx 上的属性 %1$s 包含无效的 UTF-8\n" +#~ msgid "" +#~ "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit " +#~ "the format" +#~ msgstr "混合格式为“blend/bg_color/fg_color/alpha”,“%s”不符合该格式" -#: ../src/core/xprops.c:494 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "窗口 0x%2$lx 上的属性 %1$s 为列表中的条目 %3$d 包含无效的 UTF-8\n" +#~ msgid "Could not parse alpha value \"%s\" in blended color" +#~ msgstr "无法解析混合色中的 Alpha 值“%s”" -#: ../src/muffin.desktop.in.h:1 ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" +#~ msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" +#~ msgstr "混合色中的 Alpha 值“%s”不在 0.0 到 1.0 之间" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 -msgid "Modifier to use for extended window management operations" -msgstr "用于修改窗口点击动作的修饰键 met" +#~ msgid "" +#~ "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the " +#~ "format" +#~ msgstr "阴影格式为“shade/base_color/factor”,“%s”不符合该格式" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 -msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." -msgstr "" -"这个键指出的“覆盖”是一种混合窗口概述和应用程序运行的系统。默认要求使用 " -"“Super 键”。可能使用默认或者空白。" +#~ msgid "Could not parse shade factor \"%s\" in shaded color" +#~ msgstr "无法解析阴影色中的阴影因子“%s”" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 -msgid "Attach modal dialogs" -msgstr "依附模态对话框" +#~ msgid "Shade factor \"%s\" in shaded color is negative" +#~ msgstr "阴影色中的阴影因子“%s”为负数" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 -msgid "" -"When true, instead of having independent titlebars, modal dialogs appear " -"attached to the titlebar of the parent window and are moved together with " -"the parent window." -msgstr "" -"当为 true 时,模态对话框会依附在父窗口的标题栏出现,并随父窗口移动,而不使用" -"单独的标题栏。" +#~ msgid "Could not parse color \"%s\"" +#~ msgstr "无法解析颜色“%s”" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -msgid "Live Hidden Windows" -msgstr "实时隐藏窗口" +#~ msgid "Coordinate expression contains character '%s' which is not allowed" +#~ msgstr "坐标表达式包含不允许的字符“%s”" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "判断是否隐藏的窗口(比如,最小化窗口和其他工作区的窗口)应该保持状态。" +#~ msgid "" +#~ "Coordinate expression contains floating point number '%s' which could not " +#~ "be parsed" +#~ msgstr "坐标表达式包含无法解析的浮点数“%s”" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 -msgid "Enable edge tiling when dropping windows on screen edges" -msgstr "当窗口位于屏幕边缘时,启用边缘平铺" +#~ msgid "" +#~ "Coordinate expression contains integer '%s' which could not be parsed" +#~ msgstr "坐标表达式包含无法解析的整数“%s”" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 -msgid "" -"If enabled, dropping windows on vertical screen edges maximizes them " -"vertically and resizes them horizontally to cover half of the available " -"area. Dropping windows on the top screen edge maximizes them completely." -msgstr "" +#~ msgid "" +#~ "Coordinate expression contained unknown operator at the start of this " +#~ "text: \"%s\"" +#~ msgstr "坐标表达式在该文本开始处包含未知的运算符:“%s”" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 -msgid "Workspaces are managed dynamically" -msgstr "动态管理工作区" +#~ msgid "Coordinate expression was empty or not understood" +#~ msgstr "坐标表达式为空或无法理解" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 -msgid "" -"Determines whether workspaces are managed dynamically or whether there's a " -"static number of workspaces (determined by the num-workspaces key in org." -"gnome.desktop.wm.preferences)." -msgstr "" -"决定工作区动态管理还是静态数量的工作区(由 org.cinnamon.desktop.wm.preferences 中" -"的 num-workspaces 键确定)。" +#~ msgid "Coordinate expression results in division by zero" +#~ msgstr "坐标表达式用零做除数" -# 或者 只在主显示器上显示工作区 -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 -msgid "Workspaces only on primary" -msgstr "只对主显示器上的工作区" +#~ msgid "" +#~ "Coordinate expression tries to use mod operator on a floating-point number" +#~ msgstr "坐标表达式试图对浮点数使用 mod 运算符" -# monitors 是否该翻译为 屏幕? -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 -msgid "" -"Determines whether workspace switching should happen for windows on all " -"monitors or only for windows on the primary monitor." -msgstr "决定工作区切换对所有显示器上的窗口还是只对主显示器上的有效。" +#~ msgid "" +#~ "Coordinate expression has an operator \"%s\" where an operand was expected" +#~ msgstr "坐标表达式的运算符“%s”应该是一个操作数" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 -msgid "No tab popup" -msgstr "" +#~ msgid "Coordinate expression had an operand where an operator was expected" +#~ msgstr "坐标表达式的某个操作数应该是运算符" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 -msgid "" -"Determines whether the use of popup and highlight frame should be disabled " -"for window cycling." -msgstr "" +#~ msgid "Coordinate expression ended with an operator instead of an operand" +#~ msgstr "坐标表达式以运算符结尾,而不是以操作数结尾" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 -msgid "Draggable border width" -msgstr "可拖拽的边界宽度" +#~ msgid "" +#~ "Coordinate expression has operator \"%c\" following operator \"%c\" with " +#~ "no operand in between" +#~ msgstr "坐标表达式的运算符“%c”后面跟着运算符“%c”,之间没有操作数" + +#~ msgid "Coordinate expression had unknown variable or constant \"%s\"" +#~ msgstr "坐标表达式有未知的变量或常数“%s”" + +#~ msgid "Coordinate expression parser overflowed its buffer." +#~ msgstr "坐标表达式溢出了其缓冲区。" + +#~ msgid "" +#~ "Coordinate expression had a close parenthesis with no open parenthesis" +#~ msgstr "坐标表达式有一个闭括号,而没有开括号" + +#~ msgid "" +#~ "Coordinate expression had an open parenthesis with no close parenthesis" +#~ msgstr "坐标表达式有一个开括号,而没有闭括号" + +#~ msgid "Coordinate expression doesn't seem to have any operators or operands" +#~ msgstr "坐标表达式似乎没有任何运算符或操作数" + +#~ msgid "Theme contained an expression that resulted in an error: %s\n" +#~ msgstr "主题包含的一个表达式产生错误:%s\n" + +#~ msgid "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " +#~ "specified for this frame style" +#~ msgstr "" +#~ "必须为该框架风格指定<button function=\"%s\" state=\"%s\" draw_ops=" +#~ "\"whatever\"/>" + +#~ msgid "" +#~ "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/" +#~ ">" +#~ msgstr "" +#~ "缺少 <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" + +#~ msgid "Failed to load theme \"%s\": %s\n" +#~ msgstr "无法载入主题“%s”:%s\n" + +#~ msgid "No <%s> set for theme \"%s\"" +#~ msgstr "没有为主题“%2$s”设置 <%1$s>" + +#~ msgid "" +#~ "No frame style set for window type \"%s\" in theme \"%s\", add a <window " +#~ "type=\"%s\" style_set=\"whatever\"/> element" +#~ msgstr "" +#~ "没有为窗口类型“%s”(在主题“%s”中)设置框架风格,请添加一个 <window type=\"%s" +#~ "\" style_set=\"whatever\"/> 元素" + +#~ msgid "" +#~ "User-defined constants must begin with a capital letter; \"%s\" does not" +#~ msgstr "用户定义的常数必须以大写字母开头;而“%s”却不必" + +#~ msgid "Constant \"%s\" has already been defined" +#~ msgstr "常数“%s”已被定义" + +#~ msgid "No \"%s\" attribute on element <%s>" +#~ msgstr "元素 <%2$s> 上没有 \"%1$s\" 属性" + +#~ msgid "Line %d character %d: %s" +#~ msgstr "行 %d 字符 %d:%s" + +#~ msgid "Attribute \"%s\" repeated twice on the same <%s> element" +#~ msgstr "属性“%s”在同一个 <%s> 元素上重复了两次" + +#~ msgid "Attribute \"%s\" is invalid on <%s> element in this context" +#~ msgstr "在该上下文中,属性“%s”对 <%s> 元素无效" + +#~ msgid "Could not parse \"%s\" as an integer" +#~ msgstr "无法将 \"%s\" 解析为整数" + +#~ msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +#~ msgstr "不理解结尾字符 \"%1$s\" (位于字符串 \"%2$s\"中)" + +#~ msgid "Integer %ld must be positive" +#~ msgstr "整数 %ld 必须是正数" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 -msgid "" -"The amount of total draggable borders. If the theme's visible borders are " -"not enough, invisible borders will be added to meet this value." -msgstr "" -"可拖拽的边界总数。如果主题的可见边界不足,将添加不可见的边界来满足此值。" +#~ msgid "Integer %ld is too large, current max is %d" +#~ msgstr "整数 %ld 过大,当前最大值为 %d" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:17 -#, fuzzy -#| msgid "Remove Window From Top" -msgid "Select window from tab popup" -msgstr "取消窗口常居顶端" +#~ msgid "Could not parse \"%s\" as a floating point number" +#~ msgstr "无法将“%s”解析为浮点数" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:18 -msgid "Cancel tab popup" -msgstr "" +#~ msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" +#~ msgstr "布尔值必须为“true”或“false”,不能为“%s”" -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "用法:%s\n" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "最小化(_N)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "最大化(_X)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "取消最大化(_X)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "卷起(_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "展开(_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "移动(_M)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "改变大小(_R)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "将标题栏上移动到屏幕上(_S)" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "常居顶端(_T)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "总在可见工作区(_A)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "只在此工作区(_O)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "移动到左侧工作区(_L)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "移动到右侧工作区(_I)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "移动到上侧工作区(_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "移动到下侧工作区(_D)" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "关闭(_C)" - -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "工作区 %d%n" +#~ msgid "Angle must be between 0.0 and 360.0, was %g\n" +#~ msgstr "角度值必须界于 0.0 到 360.0 之间,现在是 %g\n" -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "工作区 1_0" +#~ msgid "" +#~ "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" +#~ msgstr "Alpha 值必须界于 0.0(不可见)到 1.0(完全不透明)之间,现在是 %g\n" -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "工作区 %s%d" +#~ msgid "" +#~ "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," +#~ "large,x-large,xx-large)\n" +#~ msgstr "" +#~ "无效的标题比例“%s”(必须是 xx-small、x-small、small、medium、large、x-" +#~ "large、xx-large 中的一个)\n" -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "移动到另外的工作区(_W)" +#~ msgid "<%s> name \"%s\" used a second time" +#~ msgstr "再次使用了 <%s> 名称“%s”" -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" +#~ msgid "<%s> parent \"%s\" has not been defined" +#~ msgstr "<%s> 父级“%s”尚未定义" -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. -#. -#: ../src/ui/resizepopup.c:113 -#, c-format -msgid "%d x %d" -msgstr "%d x %d" +#~ msgid "<%s> geometry \"%s\" has not been defined" +#~ msgstr "<%s> 几何布局“%s”尚未定义" -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "上" +#~ msgid "<%s> must specify either a geometry or a parent that has a geometry" +#~ msgstr "<%s> 必须指定一个几何布局或者一个带有几何布局的父级" -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "下" +#~ msgid "You must specify a background for an alpha value to be meaningful" +#~ msgstr "要让 alpha 值有意义,您必须指定背景" -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "左" +#~ msgid "Unknown type \"%s\" on <%s> element" +#~ msgstr "未知的类型“%s”在元素 <%s> 上" -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "右" +#~ msgid "Unknown style_set \"%s\" on <%s> element" +#~ msgstr "未知的 style_set“%s”在元素 <%s> 上" -#: ../src/ui/theme.c:286 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "框架几何布局没有指定“%s”尺寸" +#~ msgid "Window type \"%s\" has already been assigned a style set" +#~ msgstr "已经为窗口类型“%s”指定了一种风格设置" -#: ../src/ui/theme.c:305 -#, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "框架几何布局没有指定“%s”尺寸(该尺寸是为边框“%s”指定的)" +#~ msgid "Element <%s> is not allowed below <%s>" +#~ msgstr "不允许元素 <%s> 在 <%s> 下方" -#: ../src/ui/theme.c:342 -#, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "按钮长宽比 %g 不合理" +#~ msgid "" +#~ "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio" +#~ "\" for buttons" +#~ msgstr "" +#~ "不能同时指定按钮的 \"button_width\"/\"button_height\" 和 \"aspect_ratio\"" -#: ../src/ui/theme.c:354 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "框架几何布局没有指定按钮大小" +#~ msgid "Distance \"%s\" is unknown" +#~ msgstr "距离“%s”未知" -#: ../src/ui/theme.c:1067 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "渐变应至少有两种颜色" +#~ msgid "Aspect ratio \"%s\" is unknown" +#~ msgstr "长宽比“%s”未知" -#: ../src/ui/theme.c:1219 -#, c-format -msgid "" -"GTK custom color specification must have color name and fallback in " -"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" -msgstr "" -"GTK 颜色规范要求色彩名称和其后备值必须在随后的圆括号内,例如 gtk:custom(foo," -"bar);无法解析“%s”" +#~ msgid "Border \"%s\" is unknown" +#~ msgstr "边框“%s”未知" -#: ../src/ui/theme.c:1235 -#, c-format -msgid "" -"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" -"_ are valid" -msgstr "gtk:custom 中包含无效的字符 %c,仅允许使用 A-Za-z0-9-_" +#~ msgid "No \"start_angle\" or \"from\" attribute on element <%s>" +#~ msgstr "元素 <%s> 上没有“start_angle”或“from”属性" -#: ../src/ui/theme.c:1249 -#, c-format -msgid "" -"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " -"fit the format" -msgstr "Gtk:custom 的格式为 gtk:custom(color_name,fallback),“%s”不符合该格式" +#~ msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" +#~ msgstr "元素 <%s> 上没有“extent_angle”或“to”属性" -#: ../src/ui/theme.c:1294 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"GTK 颜色规范必须将状态包含在方括号中,例如 gtk:fg[NORMAL]其中 NORMAL 是状态;" -"无法解析“%s”" +#~ msgid "Did not understand value \"%s\" for type of gradient" +#~ msgstr "不理解梯度类型的值“%s”" -#: ../src/ui/theme.c:1308 -#, c-format -msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"GTK 颜色规范必须在状态后有一个闭方括号,例如 gtk:fg[NORMAL],其中 NORMAL 是状" -"态;无法解析“%s”" +#~ msgid "Did not understand fill type \"%s\" for <%s> element" +#~ msgstr "不理解填充类型“%s”(用于 <%s> 元素)" -#: ../src/ui/theme.c:1319 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "不理解颜色规范中的状态“%s”" +#~ msgid "Did not understand state \"%s\" for <%s> element" +#~ msgstr "不理解状态“%s”(用于 <%s> 元素)" -#: ../src/ui/theme.c:1332 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "不理解颜色规范中的颜色组成部分“%s”" +#~ msgid "Did not understand shadow \"%s\" for <%s> element" +#~ msgstr "不理解阴影“%s”(用于 <%s> 元素)" -#: ../src/ui/theme.c:1361 -#, c-format -msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" -msgstr "混合格式为“blend/bg_color/fg_color/alpha”,“%s”不符合该格式" +#~ msgid "Did not understand arrow \"%s\" for <%s> element" +#~ msgstr "不理解箭头“%s”(用于 <%s> 元素)" -#: ../src/ui/theme.c:1372 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "无法解析混合色中的 Alpha 值“%s”" +#~ msgid "No <draw_ops> called \"%s\" has been defined" +#~ msgstr "尚未定义名为“%s”的 <draw_ops>" -#: ../src/ui/theme.c:1382 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "混合色中的 Alpha 值“%s”不在 0.0 到 1.0 之间" +#~ msgid "Including draw_ops \"%s\" here would create a circular reference" +#~ msgstr "此处包括 draw_ops“%s”将创建一个循环引用" -#: ../src/ui/theme.c:1429 -#, c-format -msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "阴影格式为“shade/base_color/factor”,“%s”不符合该格式" +#~ msgid "Unknown position \"%s\" for frame piece" +#~ msgstr "框架段的位置“%s”未知" -#: ../src/ui/theme.c:1440 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "无法解析阴影色中的阴影因子“%s”" +#~ msgid "Frame style already has a piece at position %s" +#~ msgstr "在位置 %s 处已经有一段框架风格" -#: ../src/ui/theme.c:1450 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "阴影色中的阴影因子“%s”为负数" +#~ msgid "No <draw_ops> with the name \"%s\" has been defined" +#~ msgstr "尚未定义名为“%s”的 <draw_ops>" -#: ../src/ui/theme.c:1479 -#, c-format -msgid "Could not parse color \"%s\"" -msgstr "无法解析颜色“%s”" +#~ msgid "Unknown function \"%s\" for button" +#~ msgstr "按钮的函数“%s”未知" -#: ../src/ui/theme.c:1790 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "坐标表达式包含不允许的字符“%s”" +#~ msgid "Button function \"%s\" does not exist in this version (%d, need %d)" +#~ msgstr "按钮函数“%s”在此版本(%d,需要的是 %d)中不存在" -#: ../src/ui/theme.c:1817 -#, c-format -msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "坐标表达式包含无法解析的浮点数“%s”" +#~ msgid "Unknown state \"%s\" for button" +#~ msgstr "按钮的状态“%s”未知" -#: ../src/ui/theme.c:1831 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "坐标表达式包含无法解析的整数“%s”" +#~ msgid "Frame style already has a button for function %s state %s" +#~ msgstr "框架风格已经有一个函数为 %s、状态为 %s 的按钮" -#: ../src/ui/theme.c:1953 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "坐标表达式在该文本开始处包含未知的运算符:“%s”" +#~ msgid "\"%s\" is not a valid value for focus attribute" +#~ msgstr "“%s”不是 focus 属性的有效值" -#: ../src/ui/theme.c:2010 -#, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "坐标表达式为空或无法理解" +#~ msgid "\"%s\" is not a valid value for state attribute" +#~ msgstr "“%s”不是 state 属性的有效值" -#: ../src/ui/theme.c:2121 ../src/ui/theme.c:2131 ../src/ui/theme.c:2165 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "坐标表达式用零做除数" +#~ msgid "A style called \"%s\" has not been defined" +#~ msgstr "尚未定义名为“%s”的风格" -#: ../src/ui/theme.c:2173 -#, c-format -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "坐标表达式试图对浮点数使用 mod 运算符" +#~ msgid "\"%s\" is not a valid value for resize attribute" +#~ msgstr "“%s”不是 resize 属性的有效值" -#: ../src/ui/theme.c:2229 -#, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "坐标表达式的运算符“%s”应该是一个操作数" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized/shaded " +#~ "states" +#~ msgstr "状态为 maximized/shaded 的 <%s> 元素不应有“resize”属性" -#: ../src/ui/theme.c:2238 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "坐标表达式的某个操作数应该是运算符" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized states" +#~ msgstr "状态为 maximized 的 <%s> 元素不应有“resize”属性" -#: ../src/ui/theme.c:2246 -#, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "坐标表达式以运算符结尾,而不是以操作数结尾" +#~ msgid "Style has already been specified for state %s resize %s focus %s" +#~ msgstr "已经为 state 属性 %s、resize 属性 %s、focus 属性 %s 指定了风格" -#: ../src/ui/theme.c:2256 -#, c-format -msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "坐标表达式的运算符“%c”后面跟着运算符“%c”,之间没有操作数" +#~ msgid "Style has already been specified for state %s focus %s" +#~ msgstr "已经为 state 属性 %s、focus 属性 %s 指定了风格" -#: ../src/ui/theme.c:2407 ../src/ui/theme.c:2452 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "坐标表达式有未知的变量或常数“%s”" +#~ msgid "" +#~ "Can't have a two draw_ops for a <piece> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "一个 <piece> 元素不能有两个 draw_ops(主题指定了一个 draw_ops属性和一个 " +#~ "<draw_ops> 元素,或者指定了两个元素)" -#: ../src/ui/theme.c:2506 -#, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "坐标表达式溢出了其缓冲区。" +#~ msgid "" +#~ "Can't have a two draw_ops for a <button> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "一个 <button> 元素不能有两个 draw_ops(主题指定了一个 draw_ops属性和一个 " +#~ "<draw_ops> 元素,或者指定了两个元素)" -#: ../src/ui/theme.c:2535 -#, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "坐标表达式有一个闭括号,而没有开括号" +#~ msgid "" +#~ "Can't have a two draw_ops for a <menu_icon> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "一个 <menu_icon> 元素不能有两个 draw_ops(主题指定了一个draw_ops 属性和一" +#~ "个 <draw_ops> 元素,或者指定了两个元素)" -#: ../src/ui/theme.c:2599 -#, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "坐标表达式有一个开括号,而没有闭括号" +#~ msgid "Bad version specification '%s'" +#~ msgstr "版本描述 %s 不正确" -#: ../src/ui/theme.c:2610 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "坐标表达式似乎没有任何运算符或操作数" +#~ msgid "" +#~ "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" +#~ "theme-2.xml" +#~ msgstr "“version”属性不能用于 metacity-theme-1.xml 和 metacity-theme-2.xml" -#: ../src/ui/theme.c:2822 ../src/ui/theme.c:2842 ../src/ui/theme.c:2862 -#, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "主题包含的一个表达式产生错误:%s\n" +#~ msgid "" +#~ "Theme requires version %s but latest supported theme version is %d.%d" +#~ msgstr "主题要求版本为 %s,但所支持的主题版本最新为 %d.%d" -#: ../src/ui/theme.c:4533 -#, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" -"必须为该框架风格指定<button function=\"%s\" state=\"%s\" draw_ops=\"whatever" -"\"/>" +#~ msgid "Outermost element in theme must be <metacity_theme> not <%s>" +#~ msgstr "主题中最外面的元素必须是 <metacity_theme>,而不能是 <%s>" -#: ../src/ui/theme.c:5066 ../src/ui/theme.c:5091 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" -"缺少 <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" +#~ msgid "" +#~ "Element <%s> is not allowed inside a name/author/date/description element" +#~ msgstr "name/author/date/description 元素中不允许有元素 <%s>" -#: ../src/ui/theme.c:5139 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "无法载入主题“%s”:%s\n" +#~ msgid "Element <%s> is not allowed inside a <constant> element" +#~ msgstr "<constant> 元素中不允许有元素 <%s>" -#: ../src/ui/theme.c:5275 ../src/ui/theme.c:5282 ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 ../src/ui/theme.c:5303 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "没有为主题“%2$s”设置 <%1$s>" +#~ msgid "" +#~ "Element <%s> is not allowed inside a distance/border/aspect_ratio element" +#~ msgstr "distance/border/aspect_ratio 元素中不允许有元素 <%s>" -#: ../src/ui/theme.c:5311 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" -"没有为窗口类型“%s”(在主题“%s”中)设置框架风格,请添加一个 <window type=\"%s\" " -"style_set=\"whatever\"/> 元素" +#~ msgid "Element <%s> is not allowed inside a draw operation element" +#~ msgstr "draw operation 元素中不允许有元素 <%s>" -#: ../src/ui/theme.c:5709 ../src/ui/theme.c:5771 ../src/ui/theme.c:5834 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "用户定义的常数必须以大写字母开头;而“%s”却不必" +#~ msgid "Element <%s> is not allowed inside a <%s> element" +#~ msgstr "元素 <%s> 不允许出现在 <%s> 元素内" -#: ../src/ui/theme.c:5717 ../src/ui/theme.c:5779 ../src/ui/theme.c:5842 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "常数“%s”已被定义" +#~ msgid "No draw_ops provided for frame piece" +#~ msgstr "没有为框架段提供 draw_ops" -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. -#. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "元素 <%2$s> 上没有 \"%1$s\" 属性" +#~ msgid "No draw_ops provided for button" +#~ msgstr "没有为按钮提供 draw_ops" -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "行 %d 字符 %d:%s" +#~ msgid "No text is allowed inside element <%s>" +#~ msgstr "元素 <%s> 中不允许有文本" -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "属性“%s”在同一个 <%s> 元素上重复了两次" +#~ msgid "<%s> specified twice for this theme" +#~ msgstr "为此主题指定了两次 <%s>" -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "在该上下文中,属性“%s”对 <%s> 元素无效" +#~ msgid "Failed to find a valid file for theme %s\n" +#~ msgstr "找不到主题 %s 的有效文件\n" -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "无法将 \"%s\" 解析为整数" +#~ msgid "background texture could not be created from file" +#~ msgstr "无法从文件创建背景纹理" -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "不理解结尾字符 \"%1$s\" (位于字符串 \"%2$s\"中)" +#~ msgid "Unknown window information request: %d" +#~ msgstr "未知的窗口信息请求:%d" -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "整数 %ld 必须是正数" +#~ msgid "Missing %s extension required for compositing" +#~ msgstr "缺少复合效果所需的 %s 扩展" -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "整数 %ld 过大,当前最大值为 %d" +#~ msgid "" +#~ "Some other program is already using the key %s with modifiers %x as a " +#~ "binding\n" +#~ msgstr "某个其它程序已经将按键 %s 和修饰键 %x 配合使用作为一种组合\n" -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "无法将“%s”解析为浮点数" +#~ msgid "\"%s\" is not a valid accelerator\n" +#~ msgstr "“%s” 不是一个有效的加速器\n" -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "布尔值必须为“true”或“false”,不能为“%s”" +#~ msgid "" +#~ "Workarounds for broken applications disabled. Some applications may not " +#~ "behave properly.\n" +#~ msgstr "有缺陷的应用程序的工作区已禁用。某些应用程序可能无法正常运行。\n" -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "角度值必须界于 0.0 到 360.0 之间,现在是 %g\n" +#~ msgid "Could not parse font description \"%s\" from GSettings key %s\n" +#~ msgstr "无法解析字体说明“%s”(来自 GSettings 键 %s)\n" -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "Alpha 值必须界于 0.0(不可见)到 1.0(完全不透明)之间,现在是 %g\n" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" +#~ msgstr "在配置数据库中找到的“%s”不是鼠标按钮修饰键的有效值\n" -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"无效的标题比例“%s”(必须是 xx-small、x-small、small、medium、large、x-large、" -"xx-large 中的一个)\n" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for " +#~ "keybinding \"%s\"\n" +#~ msgstr "在配置数据库中找到的“%s”不是按键组合“%s”的有效值\n" -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "再次使用了 <%s> 名称“%s”" +#~ msgid "" +#~ "Could not acquire window manager selection on screen %d display \"%s\"\n" +#~ msgstr "无法获得显示“%2$s”上的屏幕 %1$d 的窗口管理器选定项\n" -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "<%s> 父级“%s”尚未定义" +#~ msgid "Could not release screen %d on display \"%s\"\n" +#~ msgstr "无法释放显示“%2$s”上的屏幕 %1$d\n" -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "<%s> 几何布局“%s”尚未定义" +#~ msgid "Could not create directory '%s': %s\n" +#~ msgstr "无法创建目录“%s”:%s\n" -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "<%s> 必须指定一个几何布局或者一个带有几何布局的父级" +#~ msgid "Could not open session file '%s' for writing: %s\n" +#~ msgstr "无法打开会话文件“%s”进行写入:%s\n" -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "要让 alpha 值有意义,您必须指定背景" +#~ msgid "Error writing session file '%s': %s\n" +#~ msgstr "写入会话文件“%s”时出错:%s\n" -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "未知的类型“%s”在元素 <%s> 上" +#~ msgid "Error closing session file '%s': %s\n" +#~ msgstr "关闭会话文件“%s”时出错:%s\n" -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "未知的 style_set“%s”在元素 <%s> 上" +#~ msgid "Failed to parse saved session file: %s\n" +#~ msgstr "无法解析保存的会话文件:%s\n" -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "已经为窗口类型“%s”指定了一种风格设置" - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "不允许元素 <%s> 在 <%s> 下方" +#~ msgid "<mutter_session> attribute seen but we already have the session ID" +#~ msgstr "<mutter_session> 属性已看到,但我们已经拥有该会话 ID" -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" -msgstr "" -"不能同时指定按钮的 \"button_width\"/\"button_height\" 和 \"aspect_ratio\"" +#~ msgid "Unknown attribute %s on <%s> element" +#~ msgstr "<%2$s> 元素上未知的属性 %1$s" -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "距离“%s”未知" +#~ msgid "nested <window> tag" +#~ msgstr "嵌套 <window> 标记" -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "长宽比“%s”未知" +#~ msgid "Unknown element %s" +#~ msgstr "未知的元素 %s" -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "边框“%s”未知" +#~ msgid "Failed to open debug log: %s\n" +#~ msgstr "无法打开调试日志:%s\n" -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "元素 <%s> 上没有“start_angle”或“from”属性" +#~ msgid "Failed to fdopen() log file %s: %s\n" +#~ msgstr "无法对日志文件 %s 进行 fdopen() 操作:%s\n" -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "元素 <%s> 上没有“extent_angle”或“to”属性" +#~ msgid "Opened log file %s\n" +#~ msgstr "打开的日志文件 %s\n" -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "不理解梯度类型的值“%s”" +#~ msgid "Window manager: " +#~ msgstr "窗口管理器:" -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "不理解填充类型“%s”(用于 <%s> 元素)" +#~ msgid "Bug in window manager: " +#~ msgstr "窗口管理器中的错误:" -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "不理解状态“%s”(用于 <%s> 元素)" +#~ msgid "Window manager warning: " +#~ msgstr "窗口管理器警告:" -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "不理解阴影“%s”(用于 <%s> 元素)" +#~ msgid "Window manager error: " +#~ msgstr "窗口管理器错误:" -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "不理解箭头“%s”(用于 <%s> 元素)" +#~ msgid "" +#~ "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " +#~ "window as specified in the ICCCM.\n" +#~ msgstr "" +#~ "窗口 %s 在它自身上设置 SM_CLIENT_ID,而不是按照 ICCCM 规定的那样,设置在 " +#~ "WM_CLIENT_LEADER 窗口上。\n" -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "尚未定义名为“%s”的 <draw_ops>" +#~ msgid "" +#~ "Window %s sets an MWM hint indicating it isn't resizable, but sets min " +#~ "size %d x %d and max size %d x %d; this doesn't make much sense.\n" +#~ msgstr "" +#~ "窗口 %s 设置了一个 MWM 提示,表明它是不可改变大小的,但设置最小尺寸为 %d " +#~ "x %d,最大尺寸为 %d x %d;这没有任何意义。\n" -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "此处包括 draw_ops“%s”将创建一个循环引用" +#~ msgid "Application set a bogus _NET_WM_PID %lu\n" +#~ msgstr "应用程序设置一个假的 _NET_WM_PID %lu\n" -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "框架段的位置“%s”未知" +#~ msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" +#~ msgstr "为 %2$s 指定了无效的 WM_TRANSIENT_FOR 窗口 0x%1$lx。\n" -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "在位置 %s 处已经有一段框架风格" +#~ msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" +#~ msgstr "为 %2$s 指定的 WM_TRANSIENT_FOR 窗口 0x%1$lx 将导致循环。\n" -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "尚未定义名为“%s”的 <draw_ops>" +#~ msgid "" +#~ "Window 0x%lx has property %s\n" +#~ "that was expected to have type %s format %d\n" +#~ "and actually has type %s format %d n_items %d.\n" +#~ "This is most likely an application bug, not a window manager bug.\n" +#~ "The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +#~ msgstr "" +#~ "窗口 0x%lx 的属性 %s\n" +#~ "的期望类型为 %s、格式为 %d,\n" +#~ "而实际类型为 %s、格式为 %d、n_items 为 %d。\n" +#~ "这很可能是应用程序的错误,不是窗口管理器的错误。\n" +#~ "窗口的标题为“%s”,类别为“%s”,名称为“%s”\n" -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "按钮的函数“%s”未知" +#~ msgid "Property %s on window 0x%lx contained invalid UTF-8\n" +#~ msgstr "窗口 0x%2$lx 上的属性 %1$s 包含无效的 UTF-8\n" -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "按钮函数“%s”在此版本(%d,需要的是 %d)中不存在" +#~ msgid "" +#~ "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the " +#~ "list\n" +#~ msgstr "窗口 0x%2$lx 上的属性 %1$s 为列表中的条目 %3$d 包含无效的 UTF-8\n" -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "按钮的状态“%s”未知" +#~ msgid "Mi_nimize" +#~ msgstr "最小化(_N)" -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "框架风格已经有一个函数为 %s、状态为 %s 的按钮" +#~ msgid "Ma_ximize" +#~ msgstr "最大化(_X)" -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "“%s”不是 focus 属性的有效值" +#~ msgid "Unma_ximize" +#~ msgstr "取消最大化(_X)" -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "“%s”不是 state 属性的有效值" +#~ msgid "Roll _Up" +#~ msgstr "卷起(_U)" -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "尚未定义名为“%s”的风格" +#~ msgid "_Unroll" +#~ msgstr "展开(_U)" -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "“%s”不是 resize 属性的有效值" +#~ msgid "_Move" +#~ msgstr "移动(_M)" -#: ../src/ui/theme-parser.c:3147 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "状态为 maximized/shaded 的 <%s> 元素不应有“resize”属性" +#~ msgid "_Resize" +#~ msgstr "改变大小(_R)" -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "状态为 maximized 的 <%s> 元素不应有“resize”属性" +#~ msgid "Move Titlebar On_screen" +#~ msgstr "将标题栏上移动到屏幕上(_S)" -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "已经为 state 属性 %s、resize 属性 %s、focus 属性 %s 指定了风格" +#~ msgid "Always on _Top" +#~ msgstr "常居顶端(_T)" -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "已经为 state 属性 %s、focus 属性 %s 指定了风格" +#~ msgid "_Always on Visible Workspace" +#~ msgstr "总在可见工作区(_A)" -#: ../src/ui/theme-parser.c:3294 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"一个 <piece> 元素不能有两个 draw_ops(主题指定了一个 draw_ops属性和一个 " -"<draw_ops> 元素,或者指定了两个元素)" +#~ msgid "_Only on This Workspace" +#~ msgstr "只在此工作区(_O)" -#: ../src/ui/theme-parser.c:3332 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"一个 <button> 元素不能有两个 draw_ops(主题指定了一个 draw_ops属性和一个 " -"<draw_ops> 元素,或者指定了两个元素)" +#~ msgid "Move to Workspace _Left" +#~ msgstr "移动到左侧工作区(_L)" -#: ../src/ui/theme-parser.c:3370 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"一个 <menu_icon> 元素不能有两个 draw_ops(主题指定了一个draw_ops 属性和一个 " -"<draw_ops> 元素,或者指定了两个元素)" +#~ msgid "Move to Workspace R_ight" +#~ msgstr "移动到右侧工作区(_I)" -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "版本描述 %s 不正确" +#~ msgid "Move to Workspace _Up" +#~ msgstr "移动到上侧工作区(_U)" -#: ../src/ui/theme-parser.c:3507 -msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" -msgstr "“version”属性不能用于 metacity-theme-1.xml 和 metacity-theme-2.xml" +#~ msgid "Move to Workspace _Down" +#~ msgstr "移动到下侧工作区(_D)" -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "主题要求版本为 %s,但所支持的主题版本最新为 %d.%d" +#~ msgid "_Close" +#~ msgstr "关闭(_C)" -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "主题中最外面的元素必须是 <metacity_theme>,而不能是 <%s>" +#~ msgid "Workspace %d%n" +#~ msgstr "工作区 %d%n" -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "name/author/date/description 元素中不允许有元素 <%s>" +#~ msgid "Workspace 1_0" +#~ msgstr "工作区 1_0" -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "<constant> 元素中不允许有元素 <%s>" +#~ msgid "Workspace %s%d" +#~ msgstr "工作区 %s%d" -#: ../src/ui/theme-parser.c:3599 -#, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "distance/border/aspect_ratio 元素中不允许有元素 <%s>" +#~ msgid "Move to Another _Workspace" +#~ msgstr "移动到另外的工作区(_W)" -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "draw operation 元素中不允许有元素 <%s>" +#~ msgid "Shift" +#~ msgstr "Shift" -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "元素 <%s> 不允许出现在 <%s> 元素内" +#~ msgid "Ctrl" +#~ msgstr "Ctrl" -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "没有为框架段提供 draw_ops" +#~ msgid "Alt" +#~ msgstr "Alt" -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "没有为按钮提供 draw_ops" +#~ msgid "Meta" +#~ msgstr "Meta" -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "元素 <%s> 中不允许有文本" +#~ msgid "Super" +#~ msgstr "Super" -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "为此主题指定了两次 <%s>" +#~ msgid "Hyper" +#~ msgstr "Hyper" -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "找不到主题 %s 的有效文件\n" +#~ msgid "Mod2" +#~ msgstr "Mod2" -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "窗口(_W)" +#~ msgid "Mod3" +#~ msgstr "Mod3" -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "对话框(_D)" +#~ msgid "Mod4" +#~ msgstr "Mod4" -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "模态对话框(_M)" +#~ msgid "Mod5" +#~ msgstr "Mod5" -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "工具(_U)" +#~ msgid "Comma-separated list of compositor plugins" +#~ msgstr "逗号分开 列表和混合渲染器插件" -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "启动屏幕(_S)" +#~ msgid "Live Hidden Windows" +#~ msgstr "实时隐藏窗口" -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "上侧停靠(_T)" +#~ msgid "" +#~ "Determines whether hidden windows (i.e., minimized windows and windows on " +#~ "other workspaces than the current one) should be kept alive." +#~ msgstr "" +#~ "判断是否隐藏的窗口(比如,最小化窗口和其他工作区的窗口)应该保持状态。" -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "下侧停靠(_B)" +#~ msgid "Usage: %s\n" +#~ msgstr "用法:%s\n" -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "左侧停靠(_L)" +#~ msgid "_Windows" +#~ msgstr "窗口(_W)" -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "右侧停靠(_R)" +#~ msgid "_Dialog" +#~ msgstr "对话框(_D)" -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "全部停靠点(_A)" +#~ msgid "_Modal dialog" +#~ msgstr "模态对话框(_M)" -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "桌面(_K)" +#~ msgid "_Utility" +#~ msgstr "工具(_U)" -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "打开这些窗口中的另外一个" +#~ msgid "_Splashscreen" +#~ msgstr "启动屏幕(_S)" -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "这是一个演示按钮,带有“打开”图标" +#~ msgid "_Top dock" +#~ msgstr "上侧停靠(_T)" -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "这是一个演示按钮,带有“退出”图标" +#~ msgid "_Bottom dock" +#~ msgstr "下侧停靠(_B)" -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "这是示例对话框中的示例消息" +#~ msgid "_Left dock" +#~ msgstr "左侧停靠(_L)" -#: ../src/ui/theme-viewer.c:328 -#, c-format -msgid "Fake menu item %d\n" -msgstr "虚假菜单项 %d\n" +#~ msgid "_Right dock" +#~ msgstr "右侧停靠(_R)" -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "只有边框的窗口" +#~ msgid "_All docks" +#~ msgstr "全部停靠点(_A)" -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "栏" +#~ msgid "Des_ktop" +#~ msgstr "桌面(_K)" -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "普通的应用程序窗口" +#~ msgid "Open another one of these windows" +#~ msgstr "打开这些窗口中的另外一个" -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "对话框" +#~ msgid "This is a demo button with an 'open' icon" +#~ msgstr "这是一个演示按钮,带有“打开”图标" -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "模态对话框" +#~ msgid "This is a demo button with a 'quit' icon" +#~ msgstr "这是一个演示按钮,带有“退出”图标" -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "工具盘" +#~ msgid "This is a sample message in a sample dialog" +#~ msgstr "这是示例对话框中的示例消息" -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "撕下的菜单" +#~ msgid "Fake menu item %d\n" +#~ msgstr "虚假菜单项 %d\n" -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "边框" +#~ msgid "Border-only window" +#~ msgstr "只有边框的窗口" -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "依附的模态对话框" +#~ msgid "Bar" +#~ msgstr "栏" -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "按钮布局测试 %d" +#~ msgid "Normal Application Window" +#~ msgstr "普通的应用程序窗口" -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "%g 毫秒用来绘制一个窗口框架" +#~ msgid "Dialog Box" +#~ msgstr "对话框" -#: ../src/ui/theme-viewer.c:813 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "用法:metacity-theme-viewer [主题名称]\n" +#~ msgid "Modal Dialog Box" +#~ msgstr "模态对话框" -#: ../src/ui/theme-viewer.c:820 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "载入主题出错:%s\n" +#~ msgid "Utility Palette" +#~ msgstr "工具盘" -#: ../src/ui/theme-viewer.c:826 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "在 %2$g 秒内载入主题“%1$s”\n" +#~ msgid "Torn-off Menu" +#~ msgstr "撕下的菜单" -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "普通标题字体" +#~ msgid "Border" +#~ msgstr "边框" -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "小标题字体" +#~ msgid "Attached Modal Dialog" +#~ msgstr "依附的模态对话框" -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "大标题字体" +#~ msgid "Button layout test %d" +#~ msgstr "按钮布局测试 %d" -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "按钮布局" +#~ msgid "%g milliseconds to draw one window frame" +#~ msgstr "%g 毫秒用来绘制一个窗口框架" -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "基准" +#~ msgid "Usage: metacity-theme-viewer [THEMENAME]\n" +#~ msgstr "用法:metacity-theme-viewer [主题名称]\n" -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "窗口标题在这里" +#~ msgid "Error loading theme: %s\n" +#~ msgstr "载入主题出错:%s\n" -#: ../src/ui/theme-viewer.c:1047 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"在 %2$g 的客户端秒(每帧 %3$g 毫秒)和包括 X 服务器资源在内的 %4$g 秒时钟时间" -"(每帧 %5$g 毫秒)内绘制 %1$d 帧\n" +#~ msgid "Loaded theme \"%s\" in %g seconds\n" +#~ msgstr "在 %2$g 秒内载入主题“%1$s”\n" -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "位置表达式测试返回了 TRUE 但设置错误" +#~ msgid "Normal Title Font" +#~ msgstr "普通标题字体" -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "位置表达式测试返回了 FALSE 但并没有设置错误" +#~ msgid "Small Title Font" +#~ msgstr "小标题字体" -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "期待错误但没有给出错误" +#~ msgid "Large Title Font" +#~ msgstr "大标题字体" -#: ../src/ui/theme-viewer.c:1274 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "期待错误 %d,但给出了 %d" +#~ msgid "Button Layouts" +#~ msgstr "按钮布局" -#: ../src/ui/theme-viewer.c:1280 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "未期待错误,但返回了错误:%s" +#~ msgid "Benchmark" +#~ msgstr "基准" -#: ../src/ui/theme-viewer.c:1284 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "x 值为 %d,但应该为 %d" +#~ msgid "Window Title Goes Here" +#~ msgstr "窗口标题在这里" -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "y 值为 %d,但应该为 %d " +#~ msgid "" +#~ "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and " +#~ "%g seconds wall clock time including X server resources (%g milliseconds " +#~ "per frame)\n" +#~ msgstr "" +#~ "在 %2$g 的客户端秒(每帧 %3$g 毫秒)和包括 X 服务器资源在内的 %4$g 秒时钟时" +#~ "间(每帧 %5$g 毫秒)内绘制 %1$d 帧\n" -#: ../src/ui/theme-viewer.c:1352 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "在 %2$g 秒内处理了 %1$d 个坐标表达式(平均 %3$g 秒)\n" +#~ msgid "position expression test returned TRUE but set error" +#~ msgstr "位置表达式测试返回了 TRUE 但设置错误" -#~ msgid "Switch to workspace 1" -#~ msgstr "切换到工作区 1" +#~ msgid "position expression test returned FALSE but didn't set error" +#~ msgstr "位置表达式测试返回了 FALSE 但并没有设置错误" -#~ msgid "Switch to workspace 2" -#~ msgstr "切换到工作区 2" +#~ msgid "Error was expected but none given" +#~ msgstr "期待错误但没有给出错误" -#~ msgid "Switch to workspace 3" -#~ msgstr "切换到工作区 3" +#~ msgid "Error %d was expected but %d given" +#~ msgstr "期待错误 %d,但给出了 %d" -#~ msgid "Switch to workspace 4" -#~ msgstr "切换到工作区 4" +#~ msgid "Error not expected but one was returned: %s" +#~ msgstr "未期待错误,但返回了错误:%s" -#~ msgid "Switch to workspace 5" -#~ msgstr "切换到工作区 5" +#~ msgid "x value was %d, %d was expected" +#~ msgstr "x 值为 %d,但应该为 %d" -#~ msgid "Switch to workspace 6" -#~ msgstr "切换到工作区 6" +#~ msgid "y value was %d, %d was expected" +#~ msgstr "y 值为 %d,但应该为 %d " + +#~ msgid "" +#~ "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" +#~ msgstr "在 %2$g 秒内处理了 %1$d 个坐标表达式(平均 %3$g 秒)\n" -#~ msgid "Switch to workspace 7" -#~ msgstr "切换到工作区 7" +#~ msgid "Minimize window" +#~ msgstr "最小化窗口" #~ msgid "Switch to workspace 8" #~ msgstr "切换到工作区 8" @@ -1629,54 +1646,12 @@ msgstr "在 %2$g 秒内处理了 %1$d 个坐标表达式(平均 %3$g 秒)\n" #~ msgid "Run a terminal" #~ msgstr "运行终端" -#~ msgid "Activate the window menu" -#~ msgstr "激活窗口菜单" - -#~ msgid "Toggle fullscreen mode" -#~ msgstr "切换全屏模式" - -#~ msgid "Toggle maximization state" -#~ msgstr "切换最大化状态" - #~ msgid "Toggle whether a window will always be visible over other windows" #~ msgstr "在窗口是否永远可见于其它窗口之上间切换" -#~ msgid "Maximize window" -#~ msgstr "最大化窗口" - -#~ msgid "Restore window" -#~ msgstr "恢复窗口" - -#~ msgid "Toggle shaded state" -#~ msgstr "切换卷起状态" - -#~ msgid "Minimize window" -#~ msgstr "最小化窗口" - -#~ msgid "Close window" -#~ msgstr "关闭窗口" - -#~ msgid "Move window" -#~ msgstr "移动窗口" - -#~ msgid "Resize window" -#~ msgstr "改变窗口大小" - #~ msgid "Toggle whether window is on all workspaces or just one" #~ msgstr "在窗口位于所有或仅一个工作区间切换" -#~ msgid "Move window to workspace 1" -#~ msgstr "将窗口移到工作区 1" - -#~ msgid "Move window to workspace 2" -#~ msgstr "将窗口移到工作区 2" - -#~ msgid "Move window to workspace 3" -#~ msgstr "将窗口移到工作区 3" - -#~ msgid "Move window to workspace 4" -#~ msgstr "将窗口移到工作区 4" - #~ msgid "Move window to workspace 5" #~ msgstr "将窗口移到工作区 5" @@ -1701,33 +1676,9 @@ msgstr "在 %2$g 秒内处理了 %1$d 个坐标表达式(平均 %3$g 秒)\n" #~ msgid "Move window to workspace 12" #~ msgstr "将窗口移到工作区 12" -#~ msgid "Move window one workspace to the left" -#~ msgstr "将窗口左移一个工作区" - -#~ msgid "Move window one workspace to the right" -#~ msgstr "将窗口右移一个工作区" - -#~ msgid "Move window one workspace up" -#~ msgstr "将窗口上移一个工作区" - -#~ msgid "Move window one workspace down" -#~ msgstr "将窗口下移一个工作区" - #~ msgid "Raise window if it's covered by another window, otherwise lower it" #~ msgstr "如果窗口被其他窗口遮盖,则提升它,否则降低它" -#~ msgid "Raise window above other windows" -#~ msgstr "将窗口提升到其它窗口之上" - -#~ msgid "Lower window below other windows" -#~ msgstr "将窗口降低到其它窗口之下" - -#~ msgid "Maximize window vertically" -#~ msgstr "垂直最大化窗口" - -#~ msgid "Maximize window horizontally" -#~ msgstr "水平最大化窗口" - #~ msgid "Move window to north-west (top left) corner" #~ msgstr "将窗口移到西北(左上)角" @@ -1843,9 +1794,6 @@ msgstr "在 %2$g 秒内处理了 %1$d 个坐标表达式(平均 %3$g 秒)\n" #~ msgid "Error setting clutter plugin list: %s\n" #~ msgstr "设置clutter插件列表时出错:%s\n" -#~ msgid "Clutter Plugins" -#~ msgstr "Clutter 插件" - #~ msgid "Plugins to load for the Clutter-based compositing manager." #~ msgstr "插件载入到基于 Clutter 的混合管理器。" @@ -2010,9 +1958,6 @@ msgstr "在 %2$g 秒内处理了 %1$d 个坐标表达式(平均 %3$g 秒)\n" #~ msgid "Commands to run in response to keybindings" #~ msgstr "按键组合对应的执行命令" -#~ msgid "Compositing Manager" -#~ msgstr "复合管理器" - #~ msgid "Control how new windows get focus" #~ msgstr "控制新窗口如何获得窗口" @@ -2039,16 +1984,6 @@ msgstr "在 %2$g 秒内处理了 %1$d 个坐标表达式(平均 %3$g 秒)\n" #~ msgid "Enable Visual Bell" #~ msgstr "启用视觉铃声" -#~ msgid "" -#~ "If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " -#~ "the focused window will be automatically raised after a delay specified " -#~ "by the auto_raise_delay key. This is not related to clicking on a window " -#~ "to raise it, nor to entering a window during drag-and-drop." -#~ msgstr "" -#~ "如果为 true,而聚焦模式为“sloppy”或“mouse”,那么聚焦的窗口将会在指定延迟后" -#~ "自动升起,延迟的时间由 auto_raise_delay 键指定。此选项与单击行为并没有什么" -#~ "关系,它也与拖放时进入窗口无关。" - #~ msgid "" #~ "If true, ignore the titlebar_font option, and use the standard " #~ "application font for window titles." @@ -3212,10 +3147,10 @@ msgstr "在 %2$g 秒内处理了 %1$d 个坐标表达式(平均 %3$g 秒)\n" #~ msgid "" #~ "This keybinding moves a window into the east (right) side of the screen. " -#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -#~ "\". The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " +#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>" +#~ "F1\". The parser is fairly liberal and allows lower or upper case, and " +#~ "also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " +#~ "set the option to the special string \"disabled\", then there will be no " #~ "keybinding for this action." #~ msgstr "" #~ "用于将窗口移到屏幕右侧的按键组合。其格式类似于“<Control>a”或“<" @@ -3290,10 +3225,10 @@ msgstr "在 %2$g 秒内处理了 %1$d 个坐标表达式(平均 %3$g 秒)\n" #~ msgid "" #~ "This keybinding moves a window into the west (left) side of the screen. " -#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>F1" -#~ "\". The parser is fairly liberal and allows lower or upper case, and also " -#~ "abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you set " -#~ "the option to the special string \"disabled\", then there will be no " +#~ "The format looks like \"<Control>a\" or \"<Shift><Alt>" +#~ "F1\". The parser is fairly liberal and allows lower or upper case, and " +#~ "also abbreviations such as \"<Ctl>\" and \"<Ctrl>\". If you " +#~ "set the option to the special string \"disabled\", then there will be no " #~ "keybinding for this action." #~ msgstr "" #~ "用于将窗口移到屏幕左侧的按键组合。其格式类似于“<Control>a”或“<" diff --git a/po/zh_HK.po b/po/zh_HK.po index e24084451..dd88c473f 100644 --- a/po/zh_HK.po +++ b/po/zh_HK.po @@ -8,934 +8,841 @@ msgid "" msgstr "" "Project-Id-Version: metacity 3.3.4\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-03-19 23:54+0800\n" -"PO-Revision-Date: 2012-03-19 23:55+0800\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=mutter&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2014-08-19 09:51+0000\n" +"PO-Revision-Date: 2014-08-21 18:55+0800\n" "Last-Translator: Chao-Hsiung Liao <j_h_liau@yahoo.com.tw>\n" "Language-Team: Chinese (Hong Kong) <community@linuxhall.org>\n" -"Language: \n" +"Language: zh_HK\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 1.6.5\n" + +#: ../data/50-mutter-navigation.xml.in.h:1 +msgid "Navigation" +msgstr "導航" + +#: ../data/50-mutter-navigation.xml.in.h:2 +msgid "Move window to workspace 1" +msgstr "將視窗移至第 1 個工作區" + +#: ../data/50-mutter-navigation.xml.in.h:3 +msgid "Move window to workspace 2" +msgstr "將視窗移至第 2 個工作區" + +#: ../data/50-mutter-navigation.xml.in.h:4 +msgid "Move window to workspace 3" +msgstr "將視窗移至第 3 個工作區" + +#: ../data/50-mutter-navigation.xml.in.h:5 +msgid "Move window to workspace 4" +msgstr "將視窗移至第 4 個工作區" + +#: ../data/50-mutter-navigation.xml.in.h:6 +#| msgid "Move window to workspace 1" +msgid "Move window to last workspace" +msgstr "將視窗移至上一個工作區" + +#: ../data/50-mutter-navigation.xml.in.h:7 +msgid "Move window one workspace to the left" +msgstr "將視窗移至左方的工作區" + +#: ../data/50-mutter-navigation.xml.in.h:8 +msgid "Move window one workspace to the right" +msgstr "將視窗移至右方的工作區" + +#: ../data/50-mutter-navigation.xml.in.h:9 +msgid "Move window one workspace up" +msgstr "將視窗移至上方的工作區" + +#: ../data/50-mutter-navigation.xml.in.h:10 +msgid "Move window one workspace down" +msgstr "將視窗移至下方的工作區" + +#: ../data/50-mutter-navigation.xml.in.h:11 +msgid "Move window one monitor to the left" +msgstr "將視窗移至左方的螢幕" + +#: ../data/50-mutter-navigation.xml.in.h:12 +msgid "Move window one monitor to the right" +msgstr "將視窗移至右方的螢幕" + +#: ../data/50-mutter-navigation.xml.in.h:13 +msgid "Move window one monitor up" +msgstr "將視窗移至上方的螢幕" + +#: ../data/50-mutter-navigation.xml.in.h:14 +msgid "Move window one monitor down" +msgstr "將視窗移至下方的螢幕" + +#: ../data/50-mutter-navigation.xml.in.h:15 +msgid "Switch applications" +msgstr "切換程式" + +#: ../data/50-mutter-navigation.xml.in.h:16 +#| msgid "Switch applications" +msgid "Switch to previous application" +msgstr "切換至上一個應用程式" + +#: ../data/50-mutter-navigation.xml.in.h:17 +msgid "Switch windows" +msgstr "切換視窗" + +#: ../data/50-mutter-navigation.xml.in.h:18 +#| msgid "Switch windows" +msgid "Switch to previous window" +msgstr "切換至上一個視窗" + +#: ../data/50-mutter-navigation.xml.in.h:19 +msgid "Switch windows of an application" +msgstr "切換程式的視窗" + +#: ../data/50-mutter-navigation.xml.in.h:20 +#| msgid "Switch windows of an application" +msgid "Switch to previous window of an application" +msgstr "切換至上一個應用程式的視窗" + +#: ../data/50-mutter-navigation.xml.in.h:21 +msgid "Switch system controls" +msgstr "切換系統控制" + +#: ../data/50-mutter-navigation.xml.in.h:22 +#| msgid "Switch system controls" +msgid "Switch to previous system control" +msgstr "切換至上一個系統控制" + +#: ../data/50-mutter-navigation.xml.in.h:23 +msgid "Switch windows directly" +msgstr "直接切換視窗" + +#: ../data/50-mutter-navigation.xml.in.h:24 +msgid "Switch directly to previous window" +msgstr "直接切換至上一個視窗" + +#: ../data/50-mutter-navigation.xml.in.h:25 +msgid "Switch windows of an app directly" +msgstr "直接切換程式的視窗" + +#: ../data/50-mutter-navigation.xml.in.h:26 +#| msgid "Switch windows of an application" +msgid "Switch directly to previous window of an app" +msgstr "直接切換至上一個程式視窗" + +#: ../data/50-mutter-navigation.xml.in.h:27 +msgid "Switch system controls directly" +msgstr "直接切換系統控制" + +#: ../data/50-mutter-navigation.xml.in.h:28 +#| msgid "Switch system controls" +msgid "Switch directly to previous system control" +msgstr "直接切換至上一個系統控制" + +#: ../data/50-mutter-navigation.xml.in.h:29 +msgid "Hide all normal windows" +msgstr "隱藏所有一般視窗" + +#: ../data/50-mutter-navigation.xml.in.h:30 +msgid "Switch to workspace 1" +msgstr "切換至第 1 個工作區" + +#: ../data/50-mutter-navigation.xml.in.h:31 +msgid "Switch to workspace 2" +msgstr "切換至第 2 個工作區" + +#: ../data/50-mutter-navigation.xml.in.h:32 +msgid "Switch to workspace 3" +msgstr "切換至第 3 個工作區" + +#: ../data/50-mutter-navigation.xml.in.h:33 +msgid "Switch to workspace 4" +msgstr "切換至第 4 個工作區" + +#: ../data/50-mutter-navigation.xml.in.h:34 +#| msgid "Switch to workspace 1" +msgid "Switch to last workspace" +msgstr "切換至上一個工作區" + +#: ../data/50-mutter-navigation.xml.in.h:35 +msgid "Move to workspace left" +msgstr "移至左方的工作區" + +#: ../data/50-mutter-navigation.xml.in.h:36 +msgid "Move to workspace right" +msgstr "移至右方的工作區" + +#: ../data/50-mutter-navigation.xml.in.h:37 +msgid "Move to workspace above" +msgstr "移至上方的工作區" + +#: ../data/50-mutter-navigation.xml.in.h:38 +msgid "Move to workspace below" +msgstr "移至下方的工作區" + +#: ../data/50-mutter-system.xml.in.h:1 +msgid "System" +msgstr "系統" + +#: ../data/50-mutter-system.xml.in.h:2 +msgid "Show the run command prompt" +msgstr "顯示執行指令提示" + +#: ../data/50-mutter-system.xml.in.h:3 +msgid "Show the activities overview" +msgstr "顯示活動概覽" + +#: ../data/50-mutter-windows.xml.in.h:1 +msgid "Windows" +msgstr "視窗" + +#: ../data/50-mutter-windows.xml.in.h:2 +msgid "Activate the window menu" +msgstr "使用視窗選單" + +#: ../data/50-mutter-windows.xml.in.h:3 +msgid "Toggle fullscreen mode" +msgstr "切換全螢幕模式" + +#: ../data/50-mutter-windows.xml.in.h:4 +msgid "Toggle maximization state" +msgstr "切換最大化狀態" + +#: ../data/50-mutter-windows.xml.in.h:5 +msgid "Maximize window" +msgstr "視窗最大化" + +#: ../data/50-mutter-windows.xml.in.h:6 +msgid "Restore window" +msgstr "還原視窗" + +#: ../data/50-mutter-windows.xml.in.h:7 +msgid "Toggle shaded state" +msgstr "切換視窗捲起/放下狀態" + +#: ../data/50-mutter-windows.xml.in.h:8 +msgid "Close window" +msgstr "關閉視窗" + +#: ../data/50-mutter-windows.xml.in.h:9 +msgid "Hide window" +msgstr "隱藏視窗" + +#: ../data/50-mutter-windows.xml.in.h:10 +msgid "Move window" +msgstr "移動視窗" + +#: ../data/50-mutter-windows.xml.in.h:11 +msgid "Resize window" +msgstr "調整視窗大小" -#: ../src/50-muffin-windows.xml.in.h:1 +#: ../data/50-mutter-windows.xml.in.h:12 +msgid "Toggle window on all workspaces or one" +msgstr "切換視窗顯示在所有工作區或是只顯示於其中之一" + +#: ../data/50-mutter-windows.xml.in.h:13 +msgid "Raise window if covered, otherwise lower it" +msgstr "若被其他視窗遮蔽就抬升它,否則將它降下" + +#: ../data/50-mutter-windows.xml.in.h:14 +msgid "Raise window above other windows" +msgstr "令某個視窗覆蓋其它視窗" + +#: ../data/50-mutter-windows.xml.in.h:15 +msgid "Lower window below other windows" +msgstr "遮蔽某個視窗" + +#: ../data/50-mutter-windows.xml.in.h:16 +msgid "Maximize window vertically" +msgstr "將視窗縱向最大化" + +#: ../data/50-mutter-windows.xml.in.h:17 +msgid "Maximize window horizontally" +msgstr "將視窗橫向最大化" + +#: ../data/50-mutter-windows.xml.in.h:18 msgid "View split on left" msgstr "檢視分割於左側" -#: ../src/50-muffin-windows.xml.in.h:2 +#: ../data/50-mutter-windows.xml.in.h:19 msgid "View split on right" msgstr "檢視分割於右側" -#: ../src/50-muffin-windows.xml.in.h:3 -msgid "Windows" -msgstr "視窗" +#: ../data/mutter.desktop.in.h:1 +msgid "Mutter" +msgstr "Mutter" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:1 +msgid "Modifier to use for extended window management operations" +msgstr "用於延伸視窗管理操作程序的特殊按鍵" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:2 +msgid "" +"This key will initiate the \"overlay\", which is a combination window " +"overview and application launching system. The default is intended to be the " +"\"Windows key\" on PC hardware. It's expected that this binding either the " +"default or set to the empty string." +msgstr "這個設定鍵會初始化「overlay」,這是一個複合視窗概覽與應用程式執行系統。預設是要成為 PC 硬件上的「Windows key」。預期這個按鍵組含不是預設值就是設定為空字串。" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:3 +msgid "Attach modal dialogs" +msgstr "附加模態對話盒" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:4 +msgid "" +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." +msgstr "當設為「true」,將不會有獨立的標題列,模態對話盒會附加在上層視窗的標題列並與上層視窗一起移動。" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:5 +msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "在螢幕邊緣放下視窗時啟用邊緣拼貼" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:6 +msgid "" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." +msgstr "如果啟用,將視窗拖放到螢幕垂直邊緣時會讓它們垂直最大化並調整水平方向大小覆蓋可用區域的一半。拖放視窗到螢幕頂端邊緣則會讓它們完全最大化。" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:7 +msgid "Workspaces are managed dynamically" +msgstr "工作區以動態方式管理" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:8 +msgid "" +"Determines whether workspaces are managed dynamically or whether there's a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." +msgstr "決定工作區以動態方式管理或是有固定數量的工作區 (以 org.gnome.desktop.wm.preferences 中的 num-workspaces 鍵值來決定)。" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:9 +msgid "Workspaces only on primary" +msgstr "只有主要螢幕的工作區" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:10 +msgid "" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." +msgstr "決定工作區切換是否使用於所有螢幕的視窗或只用於主要螢幕的視窗。" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:11 +msgid "No tab popup" +msgstr "沒有分頁彈出項" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:12 +msgid "" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." +msgstr "決定當視窗輪換時是否使用彈出式和強調框架。" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:13 +msgid "Delay focus changes until the pointer stops moving" +msgstr "延遲焦點的改變直到指標停止移動" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:14 +msgid "" +"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then " +"the focus will not be changed immediately when entering a window, but only " +"after the pointer stops moving." +msgstr "如果設為 true,焦點模式為「sloppy」或「mouse」,則焦點不會在進入視窗時立即改變,而是在指標停止移動之後才改變。" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:15 +msgid "Draggable border width" +msgstr "可拖曳邊框闊度" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:16 +msgid "" +"The amount of total draggable borders. If the theme's visible borders are " +"not enough, invisible borders will be added to meet this value." +msgstr "所有可拖曳邊框的總數。如果布景的可視邊框不夠,會加入隱形邊框來符合這個數值。" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:17 +msgid "Auto maximize nearly monitor sized windows" +msgstr "自動最大化接近螢幕大小的視窗" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:18 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "如果啟用,初始大小為螢幕大小的新視窗會自動最大化。" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:19 +msgid "Place new windows in the center" +msgstr "將新視窗放置於中央" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:20 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "當設定為「true」時,新視窗會永遠置於使用中螢幕畫面的正中央。" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:21 +msgid "Select window from tab popup" +msgstr "從分頁彈出項選擇視窗" + +#: ../data/org.gnome.mutter.gschema.xml.in.h:22 +msgid "Cancel tab popup" +msgstr "取消分頁彈出項" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:1 +#| msgid "Switch to workspace 1" +msgid "Switch to VT 1" +msgstr "切換至 VT 1" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:2 +#| msgid "Switch to workspace 2" +msgid "Switch to VT 2" +msgstr "切換至 VT 2" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:3 +#| msgid "Switch to workspace 3" +msgid "Switch to VT 3" +msgstr "切換至 VT 3" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:4 +#| msgid "Switch to workspace 4" +msgid "Switch to VT 4" +msgstr "切換至 VT 4" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:5 +#| msgid "Switch to workspace 1" +msgid "Switch to VT 5" +msgstr "切換至 VT 5" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:6 +#| msgid "Switch to workspace 1" +msgid "Switch to VT 6" +msgstr "切換至 VT 6" + +#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:7 +#| msgid "Switch to workspace 1" +msgid "Switch to VT 7" +msgstr "切換至 VT 7" + +#: ../src/backends/meta-monitor-manager.c:412 +msgid "Built-in display" +msgstr "內置顯示" + +#: ../src/backends/meta-monitor-manager.c:437 +msgid "Unknown" +msgstr "不明" + +#: ../src/backends/meta-monitor-manager.c:439 +msgid "Unknown Display" +msgstr "不明的顯示器" + +#. TRANSLATORS: this is a monitor vendor name, followed by a +#. * size in inches, like 'Dell 15"' +#. +#: ../src/backends/meta-monitor-manager.c:447 +#, c-format +msgid "%s %s" +msgstr "%s %s" # FIXME: I'm still unclear about the meaning of XGetSelectionOwner -- Abel #. This probably means that a non-WM compositor like xcompmgr is running; #. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 +#: ../src/compositor/compositor.c:441 #, c-format msgid "" "Another compositing manager is already running on screen %i on display \"%s" "\"." msgstr "在畫面「%2$s」中的第 %1$i 個螢幕中已啟動另一個組合視窗管理員。" -#: ../src/core/bell.c:307 +#: ../src/compositor/meta-background.c:1044 +msgid "background texture could not be created from file" +msgstr "背景材質無法從檔案建立" + +#: ../src/core/bell.c:185 msgid "Bell event" msgstr "響鈴事件" -#: ../src/core/core.c:157 +#: ../src/core/delete.c:127 #, c-format -msgid "Unknown window information request: %d" -msgstr "未知的視窗資訊要求:%d" +msgid "“%s” is not responding." +msgstr "“%s”沒有回應。" -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> 沒有回應。" - -#: ../src/core/delete.c:114 +#: ../src/core/delete.c:129 msgid "Application is not responding." msgstr "應用程式沒有回應。" -#: ../src/core/delete.c:119 +#: ../src/core/delete.c:134 msgid "" "You may choose to wait a short while for it to continue or force the " "application to quit entirely." msgstr "你可以選擇稍等一下,或者強制程式立即結束。" -#: ../src/core/delete.c:126 +#: ../src/core/delete.c:141 msgid "_Wait" msgstr "等待(_W)" -#: ../src/core/delete.c:126 +#: ../src/core/delete.c:141 msgid "_Force Quit" msgstr "強制結束(_F)" -#: ../src/core/display.c:387 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "遺失複合視窗管理所需的 %s 延伸功能" - -#: ../src/core/display.c:453 +#: ../src/core/display.c:547 #, c-format msgid "Failed to open X Window System display '%s'\n" msgstr "無法開啟 X Window 畫面‘%s’\n" -#: ../src/core/keybindings.c:852 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "其它程式已經使用了按鍵 %s 加上特殊按鍵 %x 作為按鍵組合\n" - -#: ../src/core/main.c:206 +#: ../src/core/main.c:176 msgid "Disable connection to session manager" msgstr "停用到作業階段管理程式的連線" -#: ../src/core/main.c:212 +#: ../src/core/main.c:182 msgid "Replace the running window manager" msgstr "取代執行中的視窗管理員" -#: ../src/core/main.c:218 +#: ../src/core/main.c:188 msgid "Specify session management ID" msgstr "指定作業階段管理 ID" -#: ../src/core/main.c:223 +#: ../src/core/main.c:193 msgid "X Display to use" msgstr "使用的 X 畫面" -#: ../src/core/main.c:229 +#: ../src/core/main.c:199 msgid "Initialize session from savefile" msgstr "以 savefile 初始化作業階段" -#: ../src/core/main.c:235 +#: ../src/core/main.c:205 msgid "Make X calls synchronous" msgstr "使用同步方式調用 X 函數" -#: ../src/core/main.c:504 +#: ../src/core/main.c:212 +msgid "Run as a wayland compositor" +msgstr "以 wayland 組合器執行" + +#: ../src/core/main.c:220 +msgid "Run as a full display server, rather than nested" +msgstr "以完全顯示伺服器執行,而非巢狀" + +#: ../src/core/main.c:459 #, c-format msgid "Failed to scan themes directory: %s\n" msgstr "找不到佈景主題目錄:%s\n" -#: ../src/core/main.c:520 +#: ../src/core/main.c:475 #, c-format msgid "" "Could not find a theme! Be sure %s exists and contains the usual themes.\n" msgstr "找不到任何佈景主題!請確定 %s 存在及其中存放了平常使用的佈景主題。\n" -#: ../src/core/muffin.c:40 +#: ../src/core/mutter.c:39 #, c-format msgid "" -"muffin %s\n" +"mutter %s\n" "Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" "This is free software; see the source for copying conditions.\n" "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " "PARTICULAR PURPOSE.\n" msgstr "" -"muffin %s\n" +"mutter %s\n" "版權所有 (C) 2001-%d Havoc Pennington, Red Hat, Inc. 及其它開發者\n" "本程式是自由軟件;有關版權的詳情請參考源程式碼。\n" "本程式不負任何擔保責任;亦無對適售性或特定目的適用性所為的默示性擔保。\n" -#: ../src/core/muffin.c:54 +#: ../src/core/mutter.c:53 msgid "Print version" msgstr "顯示版本" -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "以逗號分隔的複合視窗外掛程式清單" - -#: ../src/core/prefs.c:1077 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "關閉了對不合規格的程式的支援。某些程式可能無法正常運作。\n" - -#: ../src/core/prefs.c:1152 -#, c-format -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "無法從 GSettings 設定鍵 %2$s 分析字型描述文字「%1$s」\n" - -#: ../src/core/prefs.c:1218 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "組態資料庫中的“%s”設定值不是有效的滑鼠按鈕修改功能鍵\n" - -#: ../src/core/prefs.c:1739 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "組態資料庫中的“%s”不是按鍵組合“%s”的有效設定值\n" +#: ../src/core/mutter.c:59 +msgid "Mutter plugin to use" +msgstr "要使用的 Mutter 外掛程式" # (Abel) take care of the same string in libwnck -#: ../src/core/prefs.c:1836 +#: ../src/core/prefs.c:2100 #, c-format msgid "Workspace %d" msgstr "工作區 %d" -#: ../src/core/screen.c:730 +#: ../src/core/screen.c:548 #, c-format msgid "Screen %d on display '%s' is invalid\n" msgstr "畫面‘%2$s’中的第 %1$d 個螢幕無效\n" -#: ../src/core/screen.c:746 +#: ../src/core/screen.c:564 #, c-format msgid "" "Screen %d on display \"%s\" already has a window manager; try using the --" "replace option to replace the current window manager.\n" msgstr "畫面‘%2$s’中的第 %1$d 個螢幕已經有了視窗管理員;請嘗試使用 --replace 選項來替換目前的視窗管理員。\n" -# FIXME: I'm still unclear about the meaning of XGetSelectionOwner -- Abel -#: ../src/core/screen.c:773 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "無法在畫面“%2$s”中的第 %1$d 個螢幕進行視窗管理員選擇程序\n" - -#: ../src/core/screen.c:828 +#: ../src/core/screen.c:657 #, c-format msgid "Screen %d on display \"%s\" already has a window manager\n" msgstr "畫面“%2$s”中的第 %1$d 個螢幕已經有了視窗總管\n" -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "無法釋放畫面“%2$s”中的第 %1$d 個螢幕\n" - -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "無法建立目錄‘%s’:%s\n" - -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "無法開啟作業階段檔案‘%s’以供寫入資料:%s\n" - -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "無法寫入作業階段檔案‘%s’:%s\n" - -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "無法關閉作業階段檔案‘%s’:%s\n" - -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "無法分析已儲存的作業階段檔案:%s\n" - -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "出現了 <metacity_session> 的屬性,但作業階段 ID 已經存在" - -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "<%2$s> 元素中出現不明的屬性 %1$s" - -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "重疊的 <window> 區域" - -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "不明的元素 %s" - -#: ../src/core/session.c:1809 -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "這些視窗不支援 "儲存目前的設定" ,必須在下次登入後自行啟動。" - -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "無法開啟偵錯記錄檔:%s\n" - -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "無法 fdopen() 記錄檔 %s:%s\n" - -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "已開啟記錄檔 %s\n" - -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "編譯 Muffin 時並沒有加入詳細偵錯模式的支援\n" - -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "視窗管理員:" - -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "視窗總管出現錯誤:" - -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "視窗總管警告:" - -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "視窗總管錯誤:" - -#. first time through -#: ../src/core/window.c:7266 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "視窗 %s 將 SM_CLIENT_ID 設定為該視窗本身,而不是 ICCCM 規格中指定的 WM_CLIENT_LEADER 視窗。\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7931 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size " -"%d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "視窗 %s 設定了 MWM 提示,表示它不可以調整大小,但又將大小下限定為 %d×%d 及將大小上限定為 %d×%d;這種做法不符合常理。\n" - -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "程式設定了多餘的 _NET_WM_PID %lu\n" - -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s(在 %s)" - -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "%2$s 指定了無效的 WM_TRANSIENT_FOR 視窗 0x%1$lx。\n" - -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "%2$s 的 WM_TRANSIENT_FOR 視窗 0x%1$lx 會造成迴圈。\n" - -#: ../src/core/xprops.c:155 -#, c-format -msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" -msgstr "" -"視窗 0x%lx 的 %s 屬性應該是\n" -"type %s format %d,但實際上是\n" -"type %s format %d n_items %d。\n" -"這極可能是程式方面的漏洞,而不是視窗總管的漏洞。\n" -"該視窗的其它屬性為 title=\"%s\" class=\"%s\" name=\"%s\"\n" - -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "視窗 0x%2$lx 的屬性 %1$s 中含有無效的 UTF-8 資料\n" - -#: ../src/core/xprops.c:494 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "視窗 0x%2$lx 的屬性清單 %1$s 的第 %3$d 個項目含有無效的 UTF-8 資料\n" - -#: ../src/muffin.desktop.in.h:1 ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 -msgid "Attach modal dialogs" -msgstr "附加模態對話盒" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 -msgid "Cancel tab popup" -msgstr "取消分頁彈出項" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "決定隱藏的視窗(如最小化的視窗和位於目前以外工作區的視窗)是否保持活動。" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 -msgid "" -"Determines whether the use of popup and highlight frame should be disabled " -"for window cycling." -msgstr "決定當視窗輪換時是否使用彈出式和強調框架。" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -msgid "" -"Determines whether workspace switching should happen for windows on all " -"monitors or only for windows on the primary monitor." -msgstr "決定工作區切換是否使用於所有螢幕的視窗或只用於主要螢幕的視窗。" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 -msgid "" -"Determines whether workspaces are managed dynamically or whether there's a " -"static number of workspaces (determined by the num-workspaces key in org." -"gnome.desktop.wm.preferences)." -msgstr "決定工作區以動態方式管理或是有固定數量的工作區 (以 org.cinnamon.desktop.wm.preferences 中的 num-workspaces 鍵值來決定)。" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 -msgid "Draggable border width" -msgstr "可拖曳邊框闊度" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 -msgid "Enable edge tiling when dropping windows on screen edges" -msgstr "在螢幕邊緣放下視窗時啟用邊緣拼貼" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 -msgid "" -"If enabled, dropping windows on vertical screen edges maximizes them " -"vertically and resizes them horizontally to cover half of the available " -"area. Dropping windows on the top screen edge maximizes them completely." -msgstr "如果啟用,將視窗拖放到螢幕垂直邊緣時會讓它們垂直最大化並調整水平方向大小覆蓋可用區域的一半。拖放視窗到螢幕頂端邊緣則會讓它們完全最大化。" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 -msgid "Live Hidden Windows" -msgstr "活動中的隱藏 Windows" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 -msgid "Modifier to use for extended window management operations" -msgstr "用於延伸視窗管理操作程序的特殊按鍵" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 -msgid "No tab popup" -msgstr "沒有分頁彈出項" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 -msgid "Select window from tab popup" -msgstr "從分頁彈出項選擇視窗" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 -msgid "" -"The amount of total draggable borders. If the theme's visible borders are " -"not enough, invisible borders will be added to meet this value." -msgstr "所有可拖曳邊框的總數。如果布景的可視邊框不夠,會加入隱形邊框來符合這個數值。" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 -msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." -msgstr "這個設定鍵會初始化「overlay」,這是一個複合視窗概覽與應用程式執行系統。預設是要成為 PC 硬件上的「Windows key」。預期這個按鍵組含不是預設值就是設定為空字串。" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 -msgid "" -"When true, instead of having independent titlebars, modal dialogs appear " -"attached to the titlebar of the parent window and are moved together with " -"the parent window." -msgstr "當設為「true」,將不會有獨立的標題列,模態對話盒會附加在上層視窗的標題列並與上層視窗一起移動。" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:17 -msgid "Workspaces are managed dynamically" -msgstr "工作區以動態方式管理" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:18 -msgid "Workspaces only on primary" -msgstr "只有主要螢幕的工作區" - -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "用法:%s\n" - -# (Abel) take care of the same string in libwnck -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "最小化(_N)" - -# (Abel) take care of the same string in libwnck -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "最大化(_X)" - -# (Abel) take care of the same string in libwnck -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "取消最大化(_X)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "捲起(_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "放下(_U)" - -# (Abel) take care of the same string in libwnck -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "移動(_M)" - -# (Abel) take care of the same string in libwnck -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "調整大小(_R)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "在畫面上移動標題列(_S)" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "總是在最上層(_T)" - -# (Abel) take care of the same string in libwnck -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "在所有工作區顯示(_A)" - -# (Abel) take care of the same string in libwnck -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "只在本工作區顯示(_O)" - -# (Abel) take care of the same string in libwnck -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "移至左方的工作區(_L)" - -# (Abel) take care of the same string in libwnck -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "移至右方的工作區(_I)" - -# (Abel) take care of the same string in libwnck -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "移至上方的工作區(_U)" - -# (Abel) take care of the same string in libwnck -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "移至下方的工作區(_D)" - -# (Abel) take care of the same string in libwnck -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "關閉(_C)" - -# (Abel) take care of the same string in libwnck -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "工作區 %d%n" - -# (Abel) take care of the same string in libwnck -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "工作區 1_0" - -# (Abel) take care of the same string in libwnck -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "工作區 %s%d" - -# (Abel) take care of the same string in libwnck -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "移至另一個工作區(_W)" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" +#: ../src/core/util.c:118 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "編譯 Mutter 時並沒有加入詳細偵錯模式的支援\n" #. Translators: This represents the size of a window. The first number is #. * the width of the window and the second is the height. #. -#: ../src/ui/resizepopup.c:113 +#: ../src/ui/resizepopup.c:134 #, c-format msgid "%d x %d" msgstr "%d x %d" -#: ../src/ui/theme.c:253 +#: ../src/ui/theme.c:233 msgid "top" msgstr "頂" -#: ../src/ui/theme.c:255 +#: ../src/ui/theme.c:235 msgid "bottom" msgstr "底" -#: ../src/ui/theme.c:257 +#: ../src/ui/theme.c:237 msgid "left" msgstr "左" -#: ../src/ui/theme.c:259 +#: ../src/ui/theme.c:239 msgid "right" msgstr "右" -#: ../src/ui/theme.c:286 +#: ../src/ui/theme.c:267 #, c-format msgid "frame geometry does not specify \"%s\" dimension" msgstr "邊框的位置大小中沒有指定“%s”部分的大小" -#: ../src/ui/theme.c:305 +#: ../src/ui/theme.c:286 #, c-format msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" msgstr "邊框的位置大小中沒有指定“%2$s”邊框中的“%1$s”部分" -#: ../src/ui/theme.c:342 +#: ../src/ui/theme.c:323 #, c-format msgid "Button aspect ratio %g is not reasonable" msgstr "按鈕的長寬比 %g 不合理" -#: ../src/ui/theme.c:354 +#: ../src/ui/theme.c:335 #, c-format msgid "Frame geometry does not specify size of buttons" msgstr "邊框的位置大小規格內未有指定按鈕的大小" -#: ../src/ui/theme.c:1067 +#: ../src/ui/theme.c:1061 #, c-format msgid "Gradients should have at least two colors" msgstr "漸變色至少應該有兩種顏色" -#: ../src/ui/theme.c:1219 +#: ../src/ui/theme.c:1211 #, c-format msgid "" "GTK custom color specification must have color name and fallback in " "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" msgstr "GTK 自選顏色規格規定必須有顏色名稱並加上封閉括號,例如 gtk:custom(foo,bar);無法分析「%s」" -#: ../src/ui/theme.c:1235 +#: ../src/ui/theme.c:1227 #, c-format msgid "" "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" "_ are valid" msgstr "gtk:custom 的 color_name 參數 '%c' 中有無效字符,只能使用 A-Za-z0-9-_ " -#: ../src/ui/theme.c:1249 +#: ../src/ui/theme.c:1241 #, c-format msgid "" "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " "fit the format" msgstr "Gtk:custom 的格式是「gtk:custom(color_name,fallback)」,但「%s」不符合格式" -#: ../src/ui/theme.c:1294 +#: ../src/ui/theme.c:1286 #, c-format msgid "" "GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " "where NORMAL is the state; could not parse \"%s\"" msgstr "GTK 色彩規格規定必須在狀態外加上方括號,例如 gtk:fg[NORMAL],這裏 NORMAL 表示狀態;無法分析“%s”" -#: ../src/ui/theme.c:1308 +#: ../src/ui/theme.c:1300 #, c-format msgid "" "GTK color specification must have a close bracket after the state, e.g. gtk:" "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" msgstr "GTK 色彩規格規定必須在狀態後加上閉方括號,例如 gtk:fg[NORMAL],這裏 NORMAL 表示狀態;無法分析“%s”" -#: ../src/ui/theme.c:1319 +#: ../src/ui/theme.c:1311 #, c-format msgid "Did not understand state \"%s\" in color specification" msgstr "無法將“%s”理解為色彩規格中的狀態" -#: ../src/ui/theme.c:1332 +#: ../src/ui/theme.c:1324 #, c-format msgid "Did not understand color component \"%s\" in color specification" msgstr "無法將“%s”理解為色彩規格中的色彩部分" -#: ../src/ui/theme.c:1361 +#: ../src/ui/theme.c:1352 #, c-format msgid "" "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " "format" msgstr "指定混色的格式是“blend/背景顏色/前景顏色/透明度”,“%s”不符合規格" -#: ../src/ui/theme.c:1372 +#: ../src/ui/theme.c:1363 #, c-format msgid "Could not parse alpha value \"%s\" in blended color" msgstr "無法理解“%s”作為混色的透明度數值" -#: ../src/ui/theme.c:1382 +#: ../src/ui/theme.c:1373 #, c-format msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" msgstr "混色的透明度數值“%s”不是在 0.0 至 1.0 之間" -#: ../src/ui/theme.c:1429 +#: ../src/ui/theme.c:1419 #, c-format msgid "" "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" msgstr "陰影的格式是“shade/基本顏色/比重”,但“%s”不符合格式" -#: ../src/ui/theme.c:1440 +#: ../src/ui/theme.c:1430 #, c-format msgid "Could not parse shade factor \"%s\" in shaded color" msgstr "在陰影顏色中無法將“%s”理解為陰影比重" -#: ../src/ui/theme.c:1450 +#: ../src/ui/theme.c:1440 #, c-format msgid "Shade factor \"%s\" in shaded color is negative" msgstr "在陰影顏色中陰影比重“%s”是負數" -#: ../src/ui/theme.c:1479 +#: ../src/ui/theme.c:1469 #, c-format msgid "Could not parse color \"%s\"" msgstr "無法分析顏色“%s”" -#: ../src/ui/theme.c:1790 +#: ../src/ui/theme.c:1778 #, c-format msgid "Coordinate expression contains character '%s' which is not allowed" msgstr "座標表達式中出現不可接受的字符‘%s’" -#: ../src/ui/theme.c:1817 +#: ../src/ui/theme.c:1805 #, c-format msgid "" "Coordinate expression contains floating point number '%s' which could not be " "parsed" msgstr "座標表達式中出現無法分析的浮點小數‘%s’" -#: ../src/ui/theme.c:1831 +#: ../src/ui/theme.c:1819 #, c-format msgid "Coordinate expression contains integer '%s' which could not be parsed" msgstr "座標表達式中出現無法分析的整數‘%s’" -#: ../src/ui/theme.c:1953 +#: ../src/ui/theme.c:1940 #, c-format msgid "" "Coordinate expression contained unknown operator at the start of this text: " "\"%s\"" msgstr "在座標表達式中,以下文字的開始部分含有不明的運算符:“%s”" -#: ../src/ui/theme.c:2010 +#: ../src/ui/theme.c:1997 #, c-format msgid "Coordinate expression was empty or not understood" msgstr "座標表達式是空白的或是無法分析" -#: ../src/ui/theme.c:2121 ../src/ui/theme.c:2131 ../src/ui/theme.c:2165 +#: ../src/ui/theme.c:2110 ../src/ui/theme.c:2120 ../src/ui/theme.c:2154 #, c-format msgid "Coordinate expression results in division by zero" msgstr "座標表達式中出現被 0 整除的錯誤" -#: ../src/ui/theme.c:2173 +#: ../src/ui/theme.c:2162 #, c-format msgid "" "Coordinate expression tries to use mod operator on a floating-point number" msgstr "座標表達式中出現將浮點數使用於餘數運算符 (mod) 的錯誤" -#: ../src/ui/theme.c:2229 +#: ../src/ui/theme.c:2218 #, c-format msgid "" "Coordinate expression has an operator \"%s\" where an operand was expected" msgstr "在座標表達式中,應該有運算子的地方出現了運算符“%s”" -#: ../src/ui/theme.c:2238 +#: ../src/ui/theme.c:2227 #, c-format msgid "Coordinate expression had an operand where an operator was expected" msgstr "在座標表達式中,應該有運算符的地方出現了運算子" -#: ../src/ui/theme.c:2246 +#: ../src/ui/theme.c:2235 #, c-format msgid "Coordinate expression ended with an operator instead of an operand" msgstr "結束座標表達式的是一個運算符而非運算子" -#: ../src/ui/theme.c:2256 +#: ../src/ui/theme.c:2245 #, c-format msgid "" "Coordinate expression has operator \"%c\" following operator \"%c\" with no " "operand in between" msgstr "在座標表達式中,運算符“%c”緊隨運算符“%c”出現,但中間沒有任何運算子" -#: ../src/ui/theme.c:2407 ../src/ui/theme.c:2452 +#: ../src/ui/theme.c:2396 ../src/ui/theme.c:2441 #, c-format msgid "Coordinate expression had unknown variable or constant \"%s\"" msgstr "座標表達式中出現不明的變數或常數“%s”" -#: ../src/ui/theme.c:2506 +#: ../src/ui/theme.c:2495 #, c-format msgid "Coordinate expression parser overflowed its buffer." msgstr "座標表達式分析器令緩衝溢位。" -#: ../src/ui/theme.c:2535 +#: ../src/ui/theme.c:2524 #, c-format msgid "Coordinate expression had a close parenthesis with no open parenthesis" msgstr "座標表達式中的閉括號沒有相應的開括號" -#: ../src/ui/theme.c:2599 +#: ../src/ui/theme.c:2588 #, c-format msgid "Coordinate expression had an open parenthesis with no close parenthesis" msgstr "座標表達式中的開括號沒有相應的閉括號" -#: ../src/ui/theme.c:2610 +#: ../src/ui/theme.c:2599 #, c-format msgid "Coordinate expression doesn't seem to have any operators or operands" msgstr "座標表達式中似乎沒有任何運算符或運算子" -#: ../src/ui/theme.c:2822 ../src/ui/theme.c:2842 ../src/ui/theme.c:2862 +#: ../src/ui/theme.c:2812 ../src/ui/theme.c:2832 ../src/ui/theme.c:2852 #, c-format msgid "Theme contained an expression that resulted in an error: %s\n" msgstr "佈景主題中含有引致錯誤的表達式:%s\n" -#: ../src/ui/theme.c:4533 +#: ../src/ui/theme.c:4455 #, c-format msgid "" "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " "specified for this frame style" msgstr "此邊框款式必須指定 <button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/>" -#: ../src/ui/theme.c:5066 ../src/ui/theme.c:5091 +#: ../src/ui/theme.c:4970 ../src/ui/theme.c:4995 #, c-format msgid "" "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" msgstr "缺少了 <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -#: ../src/ui/theme.c:5139 +#: ../src/ui/theme.c:5041 #, c-format msgid "Failed to load theme \"%s\": %s\n" msgstr "無法載入佈景主題“%s”:%s\n" -#: ../src/ui/theme.c:5275 ../src/ui/theme.c:5282 ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 ../src/ui/theme.c:5303 +#: ../src/ui/theme.c:5177 ../src/ui/theme.c:5184 ../src/ui/theme.c:5191 +#: ../src/ui/theme.c:5198 ../src/ui/theme.c:5205 #, c-format msgid "No <%s> set for theme \"%s\"" msgstr "佈景主題“%s”未指定 <%s>" -#: ../src/ui/theme.c:5311 +#: ../src/ui/theme.c:5213 #, c-format msgid "" "No frame style set for window type \"%s\" in theme \"%s\", add a <window " "type=\"%s\" style_set=\"whatever\"/> element" msgstr "在佈景主題“%2$s”中,視窗類型“%1$s”沒有指定任何邊框款式。請加上 <window type=\"%3$s\" style_set=\"whatever\"/> 元素" -#: ../src/ui/theme.c:5709 ../src/ui/theme.c:5771 ../src/ui/theme.c:5834 +#: ../src/ui/theme.c:5620 ../src/ui/theme.c:5682 ../src/ui/theme.c:5745 #, c-format msgid "" "User-defined constants must begin with a capital letter; \"%s\" does not" msgstr "自行定義的常數必須以大寫字母開始;但“%s”不是" -#: ../src/ui/theme.c:5717 ../src/ui/theme.c:5779 ../src/ui/theme.c:5842 +#: ../src/ui/theme.c:5628 ../src/ui/theme.c:5690 ../src/ui/theme.c:5753 #, c-format msgid "Constant \"%s\" has already been defined" msgstr "已定義了“%s”常數" @@ -943,67 +850,67 @@ msgstr "已定義了“%s”常數" #. Translators: This means that an attribute which should have been found #. * on an XML element was not in fact found. #. -#: ../src/ui/theme-parser.c:236 +#: ../src/ui/theme-parser.c:234 #, c-format msgid "No \"%s\" attribute on element <%s>" msgstr "在元素 <%2$s> 中沒有「%1$s」屬性" -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 +#: ../src/ui/theme-parser.c:263 ../src/ui/theme-parser.c:281 #, c-format msgid "Line %d character %d: %s" msgstr "第 %d 列第 %d 字:%s" -#: ../src/ui/theme-parser.c:479 +#: ../src/ui/theme-parser.c:481 #, c-format msgid "Attribute \"%s\" repeated twice on the same <%s> element" msgstr "屬性「%s」在同一個 <%s> 元素中重複了兩次" -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 +#: ../src/ui/theme-parser.c:505 ../src/ui/theme-parser.c:554 #, c-format msgid "Attribute \"%s\" is invalid on <%s> element in this context" msgstr "在此關聯選單中,屬性「%s」在 <%s> 元素中是無效的" -#: ../src/ui/theme-parser.c:594 +#: ../src/ui/theme-parser.c:596 #, c-format msgid "Could not parse \"%s\" as an integer" msgstr "無法以整數的方式分析“%s”" -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 +#: ../src/ui/theme-parser.c:605 ../src/ui/theme-parser.c:660 #, c-format msgid "Did not understand trailing characters \"%s\" in string \"%s\"" msgstr "無法理解字串“%2$s”中的結束字符“%1$s”" -#: ../src/ui/theme-parser.c:613 +#: ../src/ui/theme-parser.c:615 #, c-format msgid "Integer %ld must be positive" msgstr "整數 %ld 必須為正數" -#: ../src/ui/theme-parser.c:621 +#: ../src/ui/theme-parser.c:623 #, c-format msgid "Integer %ld is too large, current max is %d" msgstr "整數 %ld 太大,目前可接受的最大值為 %d" -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 +#: ../src/ui/theme-parser.c:651 ../src/ui/theme-parser.c:767 #, c-format msgid "Could not parse \"%s\" as a floating point number" msgstr "無法以浮點小數的方式分析“%s”" -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 +#: ../src/ui/theme-parser.c:682 ../src/ui/theme-parser.c:710 #, c-format msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" msgstr "邏輯值必須為“true”或“false”,不是“%s”" -#: ../src/ui/theme-parser.c:735 +#: ../src/ui/theme-parser.c:737 #, c-format msgid "Angle must be between 0.0 and 360.0, was %g\n" msgstr "角度必須在 0.0 至 360.0 之間,此處的值為 %g\n" -#: ../src/ui/theme-parser.c:798 +#: ../src/ui/theme-parser.c:800 #, c-format msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" msgstr "透明度必須在 0.0(完全透明)至 1.0(完全不透明)之間,此處的值為 %g\n" -#: ../src/ui/theme-parser.c:863 +#: ../src/ui/theme-parser.c:865 #, c-format msgid "" "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," @@ -1012,517 +919,335 @@ msgstr "" "無效的標題大小“%s”(必須為 xx-small、x-small、small、medium、large、\n" "x-large、xx-large 其中一個)\n" -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 +#: ../src/ui/theme-parser.c:1021 ../src/ui/theme-parser.c:1084 +#: ../src/ui/theme-parser.c:1118 ../src/ui/theme-parser.c:1221 #, c-format msgid "<%s> name \"%s\" used a second time" msgstr "<%s> 的 name 屬性“%s”用了超過一次" -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 +#: ../src/ui/theme-parser.c:1033 ../src/ui/theme-parser.c:1130 +#: ../src/ui/theme-parser.c:1233 #, c-format msgid "<%s> parent \"%s\" has not been defined" msgstr "<%s> 的主元素“%s”沒有任何定義" -#: ../src/ui/theme-parser.c:1141 +#: ../src/ui/theme-parser.c:1143 #, c-format msgid "<%s> geometry \"%s\" has not been defined" msgstr "<%s> 元素的位置大小“%s”沒有任何定義" -#: ../src/ui/theme-parser.c:1154 +#: ../src/ui/theme-parser.c:1156 #, c-format msgid "<%s> must specify either a geometry or a parent that has a geometry" msgstr "<%s> 必須自己指定位置大小或指定有位置大小的主元素" -#: ../src/ui/theme-parser.c:1196 +#: ../src/ui/theme-parser.c:1198 msgid "You must specify a background for an alpha value to be meaningful" msgstr "必須指定背景使得透明 ( alpha) 值的變得有意義" -#: ../src/ui/theme-parser.c:1264 +#: ../src/ui/theme-parser.c:1266 #, c-format msgid "Unknown type \"%s\" on <%s> element" msgstr "<%2$s> 元素之內出現不明的類型“%1$s”" -#: ../src/ui/theme-parser.c:1275 +#: ../src/ui/theme-parser.c:1277 #, c-format msgid "Unknown style_set \"%s\" on <%s> element" msgstr "<%2$s> 元素之內出現不明的 style_set“%1$s”" -#: ../src/ui/theme-parser.c:1283 +#: ../src/ui/theme-parser.c:1285 #, c-format msgid "Window type \"%s\" has already been assigned a style set" msgstr "視窗類型“%s”已經分配了 style set" -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 +#: ../src/ui/theme-parser.c:1315 ../src/ui/theme-parser.c:1379 +#: ../src/ui/theme-parser.c:1605 ../src/ui/theme-parser.c:2840 +#: ../src/ui/theme-parser.c:2886 ../src/ui/theme-parser.c:3036 +#: ../src/ui/theme-parser.c:3272 ../src/ui/theme-parser.c:3310 +#: ../src/ui/theme-parser.c:3348 ../src/ui/theme-parser.c:3386 #, c-format msgid "Element <%s> is not allowed below <%s>" msgstr "元素 <%s> 不允許在 <%s> 之下" -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 +#: ../src/ui/theme-parser.c:1429 ../src/ui/theme-parser.c:1443 +#: ../src/ui/theme-parser.c:1488 msgid "" "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " "for buttons" msgstr "不可能同時指定按鈕的闊度/長度 (button_width/button_height) 及長寬比(aspect_ratio)" -#: ../src/ui/theme-parser.c:1450 +#: ../src/ui/theme-parser.c:1452 #, c-format msgid "Distance \"%s\" is unknown" msgstr "不明的距離“%s”" -#: ../src/ui/theme-parser.c:1495 +#: ../src/ui/theme-parser.c:1497 #, c-format msgid "Aspect ratio \"%s\" is unknown" msgstr "不明的長寬比“%s”" -#: ../src/ui/theme-parser.c:1557 +#: ../src/ui/theme-parser.c:1559 #, c-format msgid "Border \"%s\" is unknown" msgstr "不明的邊框“%s”" -#: ../src/ui/theme-parser.c:1868 +#: ../src/ui/theme-parser.c:1870 #, c-format msgid "No \"start_angle\" or \"from\" attribute on element <%s>" msgstr "元素 <%s> 中沒有“start_angle”或“from”屬性" -#: ../src/ui/theme-parser.c:1875 +#: ../src/ui/theme-parser.c:1877 #, c-format msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" msgstr "元素 <%s> 中沒有“extent_angle”或“to”屬性" -#: ../src/ui/theme-parser.c:2115 +#: ../src/ui/theme-parser.c:2117 #, c-format msgid "Did not understand value \"%s\" for type of gradient" msgstr "無法將“%s”理解為漸變色的樣式" -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 +#: ../src/ui/theme-parser.c:2195 ../src/ui/theme-parser.c:2570 #, c-format msgid "Did not understand fill type \"%s\" for <%s> element" msgstr "無法理解 <%2$s> 元素中的填充類型“%1$s”" -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 +#: ../src/ui/theme-parser.c:2362 ../src/ui/theme-parser.c:2445 +#: ../src/ui/theme-parser.c:2508 #, c-format msgid "Did not understand state \"%s\" for <%s> element" msgstr "無法將“%s”理解為 <%s> 元素的狀態" -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 +#: ../src/ui/theme-parser.c:2372 ../src/ui/theme-parser.c:2455 #, c-format msgid "Did not understand shadow \"%s\" for <%s> element" msgstr "無法將“%s”理解為 <%s> 元素的陰影" -#: ../src/ui/theme-parser.c:2380 +#: ../src/ui/theme-parser.c:2382 #, c-format msgid "Did not understand arrow \"%s\" for <%s> element" msgstr "無法將“%s”理解為 <%s> 元素的箭頭" -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 +#: ../src/ui/theme-parser.c:2696 ../src/ui/theme-parser.c:2792 #, c-format msgid "No <draw_ops> called \"%s\" has been defined" msgstr "沒有定義任何名稱為“%s”的 <draw_ops>" -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 +#: ../src/ui/theme-parser.c:2708 ../src/ui/theme-parser.c:2804 #, c-format msgid "Including draw_ops \"%s\" here would create a circular reference" msgstr "這裏的 draw_ops“%s”會造成循環" -#: ../src/ui/theme-parser.c:2917 +#: ../src/ui/theme-parser.c:2919 #, c-format msgid "Unknown position \"%s\" for frame piece" msgstr "邊框組件指定了不明的位置“%s”" -#: ../src/ui/theme-parser.c:2925 +#: ../src/ui/theme-parser.c:2927 #, c-format msgid "Frame style already has a piece at position %s" msgstr "邊框款式已經在位置 %s 中指定了一件邊框組件" -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 +#: ../src/ui/theme-parser.c:2944 ../src/ui/theme-parser.c:3021 #, c-format msgid "No <draw_ops> with the name \"%s\" has been defined" msgstr "沒有定義任何名稱為“%s”的 <draw_ops>" -#: ../src/ui/theme-parser.c:2972 +#: ../src/ui/theme-parser.c:2974 #, c-format msgid "Unknown function \"%s\" for button" msgstr "按鈕擁有不明的功能“%s”" -#: ../src/ui/theme-parser.c:2982 +#: ../src/ui/theme-parser.c:2984 #, c-format msgid "Button function \"%s\" does not exist in this version (%d, need %d)" msgstr "按鈕功能“%s”不存在於這個 版本(%d,要求 %d)" -#: ../src/ui/theme-parser.c:2994 +#: ../src/ui/theme-parser.c:2996 #, c-format msgid "Unknown state \"%s\" for button" msgstr "無法理解“%s”為按鈕的狀態" -#: ../src/ui/theme-parser.c:3002 +#: ../src/ui/theme-parser.c:3004 #, c-format msgid "Frame style already has a button for function %s state %s" msgstr "邊框款式已經指定了一個擁有 %s 功能及 %s 狀態的按鈕" -#: ../src/ui/theme-parser.c:3073 +#: ../src/ui/theme-parser.c:3075 #, c-format msgid "\"%s\" is not a valid value for focus attribute" msgstr "“%s”不是 focus 屬性的有效設定值" -#: ../src/ui/theme-parser.c:3082 +#: ../src/ui/theme-parser.c:3084 #, c-format msgid "\"%s\" is not a valid value for state attribute" msgstr "“%s”不是 state 屬性的有效設定值" -#: ../src/ui/theme-parser.c:3092 +#: ../src/ui/theme-parser.c:3094 #, c-format msgid "A style called \"%s\" has not been defined" msgstr "沒有定義任何稱為“%s”的款式" -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 +#: ../src/ui/theme-parser.c:3115 ../src/ui/theme-parser.c:3138 #, c-format msgid "\"%s\" is not a valid value for resize attribute" msgstr "“%s”不是 resize 屬性的有效設定值" -#: ../src/ui/theme-parser.c:3147 +#: ../src/ui/theme-parser.c:3149 #, c-format msgid "" "Should not have \"resize\" attribute on <%s> element for maximized/shaded " "states" msgstr "元素 <%s> 不應在最大化或捲起的狀態中指定“resize”屬性" -#: ../src/ui/theme-parser.c:3161 +#: ../src/ui/theme-parser.c:3163 #, c-format msgid "" "Should not have \"resize\" attribute on <%s> element for maximized states" msgstr "不應在元素 <%s> 最大化的狀態中指定“resize”屬性" -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 +#: ../src/ui/theme-parser.c:3177 ../src/ui/theme-parser.c:3221 #, c-format msgid "Style has already been specified for state %s resize %s focus %s" msgstr "當 state=%s resize=%s focus=%s 時,樣式早已經被指定了" -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 +#: ../src/ui/theme-parser.c:3188 ../src/ui/theme-parser.c:3199 +#: ../src/ui/theme-parser.c:3210 ../src/ui/theme-parser.c:3232 +#: ../src/ui/theme-parser.c:3243 ../src/ui/theme-parser.c:3254 #, c-format msgid "Style has already been specified for state %s focus %s" msgstr "當 state=%s focus=%s 時,樣式早已經被指定了" -#: ../src/ui/theme-parser.c:3294 +#: ../src/ui/theme-parser.c:3293 msgid "" "Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " "attribute and also a <draw_ops> element, or specified two elements)" msgstr "一個 <piece> 元素不可同時使用兩個 draw_ops (佈景主題同時指定了一個 draw_ops 屬性及一個 <draw_ops> 元素,或是指定了兩個元素)" -#: ../src/ui/theme-parser.c:3332 +#: ../src/ui/theme-parser.c:3331 msgid "" "Can't have a two draw_ops for a <button> element (theme specified a draw_ops " "attribute and also a <draw_ops> element, or specified two elements)" msgstr "一個 <button> 元素不可同時使用兩個 draw_ops (佈景主題同時指定了一個 draw_ops 屬性及一個 <draw_ops> 元素,或是指定了兩個元素)" -#: ../src/ui/theme-parser.c:3370 +#: ../src/ui/theme-parser.c:3369 msgid "" "Can't have a two draw_ops for a <menu_icon> element (theme specified a " "draw_ops attribute and also a <draw_ops> element, or specified two elements)" msgstr "一個 <menu_icon> 元素不可同時使用兩個 draw_ops (佈景主題同時指定了一個 draw_ops 屬性及一個 <draw_ops> 元素,或是指定了兩個元素)" -#: ../src/ui/theme-parser.c:3434 +#: ../src/ui/theme-parser.c:3433 #, c-format msgid "Bad version specification '%s'" msgstr "不正確的版本規格「%s」" -#: ../src/ui/theme-parser.c:3507 +#: ../src/ui/theme-parser.c:3506 msgid "" "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" "theme-2.xml" msgstr "「version」屬性不能用在 metacity-theme-1.xml 或 metacity-theme-2.xml" -#: ../src/ui/theme-parser.c:3530 +#: ../src/ui/theme-parser.c:3529 #, c-format msgid "Theme requires version %s but latest supported theme version is %d.%d" msgstr "佈景主題需要 %s 版但是最新支援的佈景主題版本為 %d.%d" -#: ../src/ui/theme-parser.c:3562 +#: ../src/ui/theme-parser.c:3561 #, c-format msgid "Outermost element in theme must be <metacity_theme> not <%s>" msgstr "佈景主題中最外層的元素必須為 <metacity_theme> 而不是 <%s>" -#: ../src/ui/theme-parser.c:3582 +#: ../src/ui/theme-parser.c:3581 #, c-format msgid "" "Element <%s> is not allowed inside a name/author/date/description element" msgstr "元素 <%s> 不許在名稱/作者/日期/描述元素內出現" -#: ../src/ui/theme-parser.c:3587 +#: ../src/ui/theme-parser.c:3586 #, c-format msgid "Element <%s> is not allowed inside a <constant> element" msgstr "<%s> 元素不可出現在 <constant> 元素內" -#: ../src/ui/theme-parser.c:3599 +#: ../src/ui/theme-parser.c:3598 #, c-format msgid "" "Element <%s> is not allowed inside a distance/border/aspect_ratio element" msgstr "<%s> 元素不可出現於 distance/border/aspect_ratio 元素之內" -#: ../src/ui/theme-parser.c:3621 +#: ../src/ui/theme-parser.c:3620 #, c-format msgid "Element <%s> is not allowed inside a draw operation element" msgstr "元素 <%s> 不允許在有關繪圖操作的元素內出現" -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 +#: ../src/ui/theme-parser.c:3630 ../src/ui/theme-parser.c:3660 +#: ../src/ui/theme-parser.c:3665 ../src/ui/theme-parser.c:3670 #, c-format msgid "Element <%s> is not allowed inside a <%s> element" msgstr "<%s> 元素不可出現在 <%s> 元素內" -#: ../src/ui/theme-parser.c:3899 +#: ../src/ui/theme-parser.c:3898 msgid "No draw_ops provided for frame piece" msgstr "邊框沒有提供任何 draw_ops 屬性" -#: ../src/ui/theme-parser.c:3914 +#: ../src/ui/theme-parser.c:3913 msgid "No draw_ops provided for button" msgstr "按鈕沒有提供任何 draw_ops 屬性" -#: ../src/ui/theme-parser.c:3968 +#: ../src/ui/theme-parser.c:3967 #, c-format msgid "No text is allowed inside element <%s>" msgstr "<%s> 元素內不可出現任何文字" -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 +#: ../src/ui/theme-parser.c:4025 ../src/ui/theme-parser.c:4037 +#: ../src/ui/theme-parser.c:4049 ../src/ui/theme-parser.c:4061 +#: ../src/ui/theme-parser.c:4073 #, c-format msgid "<%s> specified twice for this theme" msgstr "<%s> 指定了這個佈景主題兩次" -#: ../src/ui/theme-parser.c:4348 +#: ../src/ui/theme-parser.c:4335 #, c-format msgid "Failed to find a valid file for theme %s\n" msgstr "無法佈景主題的有效檔案 %s\n" -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "視窗(_W)" - -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "對話盒(_D)" - -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "模態對話盒(_M)" - -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "公用程式(_U)" - -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "啟動畫面(_S)" - -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "頂端浮動列(_T)" - -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "底部浮動列(_B)" - -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "左側浮動列(_L)" - -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "右側浮動列(_R)" - -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "所有浮動列(_A)" - -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "桌面(_K)" - -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "開啟一個同樣的視窗" - -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "這是有開啟圖示的展示用按鈕" - -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "這是有離開圖示的展示用按鈕" - -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "這是在樣版對話視窗中的樣版訊息" - -#: ../src/ui/theme-viewer.c:328 -#, c-format -msgid "Fake menu item %d\n" -msgstr "假的選單項目 %d\n" - -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "只有邊框的視窗" - -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "列" - -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "正常的程式視窗" - -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "對話盒" - -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "模態對話盒" - -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "公用程式控制板" - -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "關閉選單" - -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "邊框" - -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "附加的模態對話盒" - -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "按鈕配置測試 %d" - -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "繪畫一個視窗需時 %g 毫秒" - -#: ../src/ui/theme-viewer.c:813 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "用法: metacity-theme-viewer [佈景主題名稱]\n" - -#: ../src/ui/theme-viewer.c:820 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "載入佈景主題失敗 %s\n" - -#: ../src/ui/theme-viewer.c:826 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "載入佈景主題 “%s” 需時 %g 秒\n" - -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "正常標題列字型" - -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "小標題列字型" - -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "大標題列字型" - -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "按鈕配置" - -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "速度測試" - -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "這裏是視窗標題" - -#: ../src/ui/theme-viewer.c:1047 -#, c-format +#: ../src/x11/session.c:1815 msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"繪畫 %d 幀需時:\n" -"在客戶端是 %g 秒(每幀 %g 毫秒)\n" -"包括 X 伺服器資源的實際消耗時間是 %g 秒(每幀 %g 毫秒)\n" - -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "位置表現測試返回值是「正確」,但有 set error" - -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "位置表現測試返回值是「錯誤」,但沒有 set error" - -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "預期會發生錯誤,但結果並沒錯誤發生" - -#: ../src/ui/theme-viewer.c:1274 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "預期會發生錯誤 %d ,但結果卻出現 %d" - -#: ../src/ui/theme-viewer.c:1280 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "預期不會發生錯誤,但結果返回了一個:%s" - -#: ../src/ui/theme-viewer.c:1284 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "x 的數值是 %d,%d是預期中的數值" - -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "y 的數值是 %d,%d是預期中的數值" +"These windows do not support "save current setup" and will have to " +"be restarted manually next time you log in." +msgstr "這些視窗不支援 "儲存目前的設定" ,必須在下次登入後自行啟動。" -#: ../src/ui/theme-viewer.c:1352 +#: ../src/x11/window-props.c:515 #, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "分析 %d 座標表現需時 %g 秒(平均 %g 秒)\n" - -#~ msgid "Close Window" -#~ msgstr "關閉視窗" +msgid "%s (on %s)" +msgstr "%s(在 %s)" -#~ msgid "Window Menu" -#~ msgstr "視窗選單" +#~ msgid "Unknown window information request: %d" +#~ msgstr "未知的視窗資訊要求:%d" -#~ msgid "Minimize Window" -#~ msgstr "視窗最小化" +#~ msgid "Missing %s extension required for compositing" +#~ msgstr "遺失複合視窗管理所需的 %s 延伸功能" -#~ msgid "Maximize Window" -#~ msgstr "視窗最大化" +#~ msgid "" +#~ "Some other program is already using the key %s with modifiers %x as a " +#~ "binding\n" +#~ msgstr "其它程式已經使用了按鍵 %s 加上特殊按鍵 %x 作為按鍵組合\n" -#~ msgid "Restore Window" -#~ msgstr "還原視窗" +#~ msgid "\"%s\" is not a valid accelerator\n" +#~ msgstr "「%s」不是有效的捷徑鍵\n" -#~ msgid "Roll Up Window" -#~ msgstr "捲起視窗(_U)" +#~ msgid "" +#~ "Workarounds for broken applications disabled. Some applications may not " +#~ "behave properly.\n" +#~ msgstr "關閉了對不合規格的程式的支援。某些程式可能無法正常運作。\n" -#~ msgid "Unroll Window" -#~ msgstr "放下視窗" +#~ msgid "Could not parse font description \"%s\" from GSettings key %s\n" +#~ msgstr "無法從 GSettings 設定鍵 %2$s 分析字型描述文字「%1$s」\n" -#~ msgid "Keep Window On Top" -#~ msgstr "視窗保留在最上層" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" +#~ msgstr "組態資料庫中的“%s”設定值不是有效的滑鼠按鈕修改功能鍵\n" -#~ msgid "Remove Window From Top" -#~ msgstr "視窗移離最上層" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for " +#~ "keybinding \"%s\"\n" +#~ msgstr "組態資料庫中的“%s”不是按鍵組合“%s”的有效設定值\n" diff --git a/po/zh_TW.po b/po/zh_TW.po index b6e44d4cb..ac1d9b3ea 100644 --- a/po/zh_TW.po +++ b/po/zh_TW.po @@ -1,424 +1,287 @@ # Chinese (Taiwan) translation of metacity. # Copyright (C) 2002-07 Free Software Foundation, Inc. +# # Abel Cheung <abel@oaka.org>, 2002-2003. # Woodman Tuen <wmtuen@gmail.com>, 2004-07. # Chao-Hsiung Liao <j_h_liau@yahoo.com.tw>, 2010. # Wei-Lun Chao <chaoweilun@gmail.com>, 2010. -# +# pan93412 <pan93412@gmail.com>, 2019. msgid "" msgstr "" "Project-Id-Version: metacity 3.3.4\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-03-19 23:54+0800\n" -"PO-Revision-Date: 2012-03-19 12:19+0800\n" -"Last-Translator: Chao-Hsiung Liao <j_h_liau@yahoo.com.tw>\n" -"Language-Team: Chinese (Taiwan) <zh-l10n@lists.linux.org.tw>\n" -"Language: \n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +"POT-Creation-Date: 2019-11-21 15:22+0000\n" +"PO-Revision-Date: 2019-11-23 13:58+0800\n" +"Last-Translator: pan93412 <pan93412@gmail.com>\n" +"Language-Team: Chinese <zh-l10n@linux.org.tw>\n" +"Language: zh_TW\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Lokalize 19.11.80\n" -#: ../src/50-muffin-windows.xml.in.h:1 -msgid "View split on left" -msgstr "檢視分割於左側" +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "導航" -#: ../src/50-muffin-windows.xml.in.h:2 -msgid "View split on right" -msgstr "檢視分割於右側" +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "將視窗移至第 1 個工作區" -#: ../src/50-muffin-windows.xml.in.h:3 -msgid "Windows" -msgstr "視窗" +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "將視窗移至第 2 個工作區" -# FIXME: I'm still unclear about the meaning of XGetSelectionOwner -- Abel -#. This probably means that a non-WM compositor like xcompmgr is running; -#. * we have no way to get it to exit -#: ../src/compositor/compositor.c:492 -#, c-format -msgid "" -"Another compositing manager is already running on screen %i on display \"%s" -"\"." -msgstr "在畫面「%2$s」中的第 %1$i 個螢幕中已啟動另一個組合視窗管理員。" +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "將視窗移至第 3 個工作區" -#: ../src/core/bell.c:307 -msgid "Bell event" -msgstr "響鈴事件" +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "將視窗移至第 4 個工作區" -#: ../src/core/core.c:157 -#, c-format -msgid "Unknown window information request: %d" -msgstr "未知的視窗資訊要求:%d" +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "將視窗移至上一個工作區" -#: ../src/core/delete.c:111 -#, c-format -msgid "<tt>%s</tt> is not responding." -msgstr "<tt>%s</tt> 沒有回應。" +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace up" +msgstr "將視窗移至上方的工作區" -#: ../src/core/delete.c:114 -msgid "Application is not responding." -msgstr "應用程式沒有回應。" +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace down" +msgstr "將視窗移至下方的工作區" -#: ../src/core/delete.c:119 -msgid "" -"You may choose to wait a short while for it to continue or force the " -"application to quit entirely." -msgstr "您可以選擇稍等一下,或者強制程式立即結束。" +#: data/50-mutter-navigation.xml:30 +msgid "Move window one monitor to the left" +msgstr "將視窗移至左方的螢幕" -#: ../src/core/delete.c:126 -msgid "_Wait" -msgstr "等待(_W)" +#: data/50-mutter-navigation.xml:33 +msgid "Move window one monitor to the right" +msgstr "將視窗移至右方的螢幕" -#: ../src/core/delete.c:126 -msgid "_Force Quit" -msgstr "強制結束(_F)" +#: data/50-mutter-navigation.xml:36 +msgid "Move window one monitor up" +msgstr "將視窗移至上方的螢幕" -#: ../src/core/display.c:387 -#, c-format -msgid "Missing %s extension required for compositing" -msgstr "遺失複合視窗管理所需的 %s 延伸功能" +#: data/50-mutter-navigation.xml:39 +msgid "Move window one monitor down" +msgstr "將視窗移至下方的螢幕" -#: ../src/core/display.c:453 -#, c-format -msgid "Failed to open X Window System display '%s'\n" -msgstr "無法開啟 X Window 畫面‘%s’\n" +#: data/50-mutter-navigation.xml:43 +msgid "Switch applications" +msgstr "切換程式" -#: ../src/core/keybindings.c:852 -#, c-format -msgid "" -"Some other program is already using the key %s with modifiers %x as a " -"binding\n" -msgstr "其它程式已經使用了按鍵 %s 加上特殊按鍵 %x 作為按鍵組合\n" +#: data/50-mutter-navigation.xml:48 +msgid "Switch to previous application" +msgstr "切換至上一個應用程式" -#: ../src/core/main.c:206 -msgid "Disable connection to session manager" -msgstr "停用到作業階段管理程式的連線" +#: data/50-mutter-navigation.xml:52 +msgid "Switch windows" +msgstr "切換視窗" -#: ../src/core/main.c:212 -msgid "Replace the running window manager" -msgstr "取代執行中的視窗管理員" +#: data/50-mutter-navigation.xml:57 +msgid "Switch to previous window" +msgstr "切換至上一個視窗" -#: ../src/core/main.c:218 -msgid "Specify session management ID" -msgstr "指定作業階段管理 ID" +#: data/50-mutter-navigation.xml:61 +msgid "Switch windows of an application" +msgstr "切換程式的視窗" -#: ../src/core/main.c:223 -msgid "X Display to use" -msgstr "使用的 X 畫面" +#: data/50-mutter-navigation.xml:66 +msgid "Switch to previous window of an application" +msgstr "切換至上一個應用程式的視窗" -#: ../src/core/main.c:229 -msgid "Initialize session from savefile" -msgstr "以 savefile 初始化作業階段" +#: data/50-mutter-navigation.xml:70 +msgid "Switch system controls" +msgstr "切換系統控制" -#: ../src/core/main.c:235 -msgid "Make X calls synchronous" -msgstr "使用同步方式調用 X 函式" +#: data/50-mutter-navigation.xml:75 +msgid "Switch to previous system control" +msgstr "切換至上一個系統控制" -#: ../src/core/main.c:504 -#, c-format -msgid "Failed to scan themes directory: %s\n" -msgstr "找不到佈景主題目錄:%s\n" +#: data/50-mutter-navigation.xml:79 +msgid "Switch windows directly" +msgstr "直接切換視窗" -#: ../src/core/main.c:520 -#, c-format -msgid "" -"Could not find a theme! Be sure %s exists and contains the usual themes.\n" -msgstr "找不到任何佈景主題!請確定 %s 存在及其中存放了平常使用的佈景主題。\n" +#: data/50-mutter-navigation.xml:84 +msgid "Switch directly to previous window" +msgstr "直接切換至上一個視窗" -#: ../src/core/muffin.c:40 -#, c-format -msgid "" -"muffin %s\n" -"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" -"This is free software; see the source for copying conditions.\n" -"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " -"PARTICULAR PURPOSE.\n" -msgstr "" -"muffin %s\n" -"版權所有 (C) 2001-%d Havoc Pennington, Red Hat, Inc. 及其它開發者\n" -"本程式是自由軟體;有關版權的詳情請參考源程式碼。\n" -"本程式不負任何擔保責任;亦無對適售性或特定目的適用性所為的默示性擔保。\n" +#: data/50-mutter-navigation.xml:88 +msgid "Switch windows of an app directly" +msgstr "直接切換程式的視窗" -#: ../src/core/muffin.c:54 -msgid "Print version" -msgstr "顯示版本" +#: data/50-mutter-navigation.xml:93 +msgid "Switch directly to previous window of an app" +msgstr "直接切換至上一個程式視窗" -#: ../src/core/muffin.c:60 -msgid "Comma-separated list of compositor plugins" -msgstr "以逗號分隔的複合視窗外掛程式清單" +#: data/50-mutter-navigation.xml:97 +msgid "Switch system controls directly" +msgstr "直接切換系統控制" -#: ../src/core/prefs.c:1077 -msgid "" -"Workarounds for broken applications disabled. Some applications may not " -"behave properly.\n" -msgstr "關閉了對不合規格的程式的支援。某些程式可能無法正常運作。\n" +#: data/50-mutter-navigation.xml:102 +msgid "Switch directly to previous system control" +msgstr "直接切換至上一個系統控制" -#: ../src/core/prefs.c:1152 -#, c-format -msgid "Could not parse font description \"%s\" from GSettings key %s\n" -msgstr "無法從 GSettings 設定鍵 %2$s 分析字型描述文字「%1$s」\n" +#: data/50-mutter-navigation.xml:105 +msgid "Hide all normal windows" +msgstr "隱藏所有一般視窗" -#: ../src/core/prefs.c:1218 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for mouse button " -"modifier\n" -msgstr "組態資料庫中的“%s”設定值不是有效的滑鼠按鈕修改功能鍵\n" +#: data/50-mutter-navigation.xml:108 +msgid "Switch to workspace 1" +msgstr "切換至第 1 個工作區" -#: ../src/core/prefs.c:1739 -#, c-format -msgid "" -"\"%s\" found in configuration database is not a valid value for keybinding " -"\"%s\"\n" -msgstr "組態資料庫中的“%s”不是按鍵組合“%s”的有效設定值\n" +#: data/50-mutter-navigation.xml:111 +msgid "Switch to workspace 2" +msgstr "切換至第 2 個工作區" -# (Abel) take care of the same string in libwnck -#: ../src/core/prefs.c:1836 -#, c-format -msgid "Workspace %d" -msgstr "工作區 %d" +#: data/50-mutter-navigation.xml:114 +msgid "Switch to workspace 3" +msgstr "切換至第 3 個工作區" -#: ../src/core/screen.c:730 -#, c-format -msgid "Screen %d on display '%s' is invalid\n" -msgstr "畫面‘%2$s’中的第 %1$d 個螢幕無效\n" +#: data/50-mutter-navigation.xml:117 +msgid "Switch to workspace 4" +msgstr "切換至第 4 個工作區" -#: ../src/core/screen.c:746 -#, c-format -msgid "" -"Screen %d on display \"%s\" already has a window manager; try using the --" -"replace option to replace the current window manager.\n" -msgstr "" -"畫面‘%2$s’中的第 %1$d 個螢幕已經有了視窗管理員;請嘗試使用 --replace 選項來替" -"換目前的視窗管理員。\n" +#: data/50-mutter-navigation.xml:120 +msgid "Switch to last workspace" +msgstr "切換至上一個工作區" -# FIXME: I'm still unclear about the meaning of XGetSelectionOwner -- Abel -#: ../src/core/screen.c:773 -#, c-format -msgid "" -"Could not acquire window manager selection on screen %d display \"%s\"\n" -msgstr "無法在畫面“%2$s”中的第 %1$d 個螢幕進行視窗管理員選擇程序\n" +#: data/50-mutter-navigation.xml:123 +msgid "Move to workspace above" +msgstr "移至上方的工作區" -#: ../src/core/screen.c:828 -#, c-format -msgid "Screen %d on display \"%s\" already has a window manager\n" -msgstr "畫面“%2$s”中的第 %1$d 個螢幕已經有了視窗總管\n" +#: data/50-mutter-navigation.xml:126 +msgid "Move to workspace below" +msgstr "移至下方的工作區" -#: ../src/core/screen.c:1013 -#, c-format -msgid "Could not release screen %d on display \"%s\"\n" -msgstr "無法釋放畫面“%2$s”中的第 %1$d 個螢幕\n" +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "系統" -#: ../src/core/session.c:843 ../src/core/session.c:850 -#, c-format -msgid "Could not create directory '%s': %s\n" -msgstr "無法建立目錄‘%s’:%s\n" +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "顯示執行指令提示" -#: ../src/core/session.c:860 -#, c-format -msgid "Could not open session file '%s' for writing: %s\n" -msgstr "無法開啟作業階段檔案‘%s’以供寫入資料:%s\n" +#: data/50-mutter-system.xml:10 +msgid "Show the activities overview" +msgstr "顯示活動概覽" -#: ../src/core/session.c:1001 -#, c-format -msgid "Error writing session file '%s': %s\n" -msgstr "無法寫入作業階段檔案‘%s’:%s\n" +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "重設鍵盤快捷鍵" -#: ../src/core/session.c:1006 -#, c-format -msgid "Error closing session file '%s': %s\n" -msgstr "無法關閉作業階段檔案‘%s’:%s\n" +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "視窗" -#: ../src/core/session.c:1136 -#, c-format -msgid "Failed to parse saved session file: %s\n" -msgstr "無法分析已儲存的作業階段檔案:%s\n" +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "使用視窗選單" -#: ../src/core/session.c:1185 -#, c-format -msgid "<muffin_session> attribute seen but we already have the session ID" -msgstr "出現了 <metacity_session> 的屬性,但作業階段 ID 已經存在" +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "切換全螢幕模式" -#: ../src/core/session.c:1198 ../src/core/session.c:1273 -#: ../src/core/session.c:1305 ../src/core/session.c:1377 -#: ../src/core/session.c:1437 -#, c-format -msgid "Unknown attribute %s on <%s> element" -msgstr "<%2$s> 元素中出現不明的屬性 %1$s" +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "切換最大化狀態" -#: ../src/core/session.c:1215 -#, c-format -msgid "nested <window> tag" -msgstr "重疊的 <window> 區域" +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "視窗最大化" -#: ../src/core/session.c:1457 -#, c-format -msgid "Unknown element %s" -msgstr "不明的元素 %s" +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "還原視窗" -#: ../src/core/session.c:1809 -msgid "" -"These windows do not support "save current setup" and will have to " -"be restarted manually next time you log in." -msgstr "這些視窗不支援 "儲存目前的設定" ,必須在下次登入後自行啟動。" +#: data/50-mutter-windows.xml:18 +msgid "Close window" +msgstr "關閉視窗" -#: ../src/core/util.c:111 -#, c-format -msgid "Failed to open debug log: %s\n" -msgstr "無法開啟偵錯記錄檔:%s\n" +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "隱藏視窗" -#: ../src/core/util.c:121 -#, c-format -msgid "Failed to fdopen() log file %s: %s\n" -msgstr "無法 fdopen() 記錄檔 %s:%s\n" +#: data/50-mutter-windows.xml:22 +msgid "Move window" +msgstr "移動視窗" -#: ../src/core/util.c:127 -#, c-format -msgid "Opened log file %s\n" -msgstr "已開啟記錄檔 %s\n" +#: data/50-mutter-windows.xml:24 +msgid "Resize window" +msgstr "調整視窗大小" -#: ../src/core/util.c:146 ../src/tools/muffin-message.c:149 -#, c-format -msgid "Muffin was compiled without support for verbose mode\n" -msgstr "編譯 Muffin 時並沒有加入詳細偵錯模式的支援\n" +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "切換視窗顯示在所有工作區或是只顯示於其中之一" -#: ../src/core/util.c:290 -msgid "Window manager: " -msgstr "視窗管理員:" +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "若被其他視窗遮蔽就抬升它,否則將它降下" -#: ../src/core/util.c:438 -msgid "Bug in window manager: " -msgstr "視窗總管出現錯誤:" +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "令某個視窗覆蓋其它視窗" -#: ../src/core/util.c:471 -msgid "Window manager warning: " -msgstr "視窗總管警告:" +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "遮蔽某個視窗" -#: ../src/core/util.c:499 -msgid "Window manager error: " -msgstr "視窗總管錯誤:" +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "將視窗縱向最大化" -#. first time through -#: ../src/core/window.c:7266 -#, c-format -msgid "" -"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " -"window as specified in the ICCCM.\n" -msgstr "" -"視窗 %s 將 SM_CLIENT_ID 設定為該視窗本身,而不是 ICCCM 規格中指定的 " -"WM_CLIENT_LEADER 視窗。\n" - -#. We ignore mwm_has_resize_func because WM_NORMAL_HINTS is the -#. * authoritative source for that info. Some apps such as mplayer or -#. * xine disable resize via MWM but not WM_NORMAL_HINTS, but that -#. * leads to e.g. us not fullscreening their windows. Apps that set -#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain -#. * about these apps but make them work. -#. -#: ../src/core/window.c:7931 -#, c-format -msgid "" -"Window %s sets an MWM hint indicating it isn't resizable, but sets min size " -"%d x %d and max size %d x %d; this doesn't make much sense.\n" -msgstr "" -"視窗 %s 設定了 MWM 提示,表示它不可以調整大小,但又將大小下限定為 %d×%d 及將" -"大小上限定為 %d×%d;這種做法不符合常理。\n" +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "將視窗橫向最大化" -#: ../src/core/window-props.c:309 -#, c-format -msgid "Application set a bogus _NET_WM_PID %lu\n" -msgstr "程式設定了多餘的 _NET_WM_PID %lu\n" +#: data/50-mutter-windows.xml:41 +msgid "View split on left" +msgstr "檢視分割於左側" -#: ../src/core/window-props.c:426 -#, c-format -msgid "%s (on %s)" -msgstr "%s(在 %s)" +#: data/50-mutter-windows.xml:45 +msgid "View split on right" +msgstr "檢視分割於右側" -#: ../src/core/window-props.c:1481 -#, c-format -msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" -msgstr "%2$s 指定了無效的 WM_TRANSIENT_FOR 視窗 0x%1$lx。\n" +#: data/mutter.desktop.in:4 +msgid "Mutter" +msgstr "Mutter" -#: ../src/core/window-props.c:1492 -#, c-format -msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" -msgstr "%2$s 的 WM_TRANSIENT_FOR 視窗 0x%1$lx 會造成迴圈。\n" +#: data/org.gnome.mutter.gschema.xml.in:7 +msgid "Modifier to use for extended window management operations" +msgstr "用於延伸視窗管理操作程序的特殊按鍵" -#: ../src/core/xprops.c:155 -#, c-format +#: data/org.gnome.mutter.gschema.xml.in:8 msgid "" -"Window 0x%lx has property %s\n" -"that was expected to have type %s format %d\n" -"and actually has type %s format %d n_items %d.\n" -"This is most likely an application bug, not a window manager bug.\n" -"The window has title=\"%s\" class=\"%s\" name=\"%s\"\n" +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." msgstr "" -"視窗 0x%lx 的 %s 屬性應該是\n" -"type %s format %d,但實際上是\n" -"type %s format %d n_items %d。\n" -"這極可能是程式方面的漏洞,而不是視窗總管的漏洞。\n" -"該視窗的其它屬性為 title=\"%s\" class=\"%s\" name=\"%s\"\n" - -#: ../src/core/xprops.c:411 -#, c-format -msgid "Property %s on window 0x%lx contained invalid UTF-8\n" -msgstr "視窗 0x%2$lx 的屬性 %1$s 中含有無效的 UTF-8 資料\n" - -#: ../src/core/xprops.c:494 -#, c-format -msgid "" -"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" -msgstr "視窗 0x%2$lx 的屬性清單 %1$s 的第 %3$d 個項目含有無效的 UTF-8 資料\n" - -#: ../src/muffin.desktop.in.h:1 ../src/muffin-wm.desktop.in.h:1 -msgid "Muffin" -msgstr "Muffin" +"這個設定鍵會初始化「overlay」,這是一個複合視窗概覽與應用程式執行系統。預設是" +"要成為 PC 硬體上的「Windows key」。預期這個按鍵組含不是預設值就是設定為空字" +"串。" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:1 +#: data/org.gnome.mutter.gschema.xml.in:20 msgid "Attach modal dialogs" msgstr "附加模態對話盒" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:2 -msgid "Cancel tab popup" -msgstr "取消分頁彈出項" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:3 -msgid "" -"Determines whether hidden windows (i.e., minimized windows and windows on " -"other workspaces than the current one) should be kept alive." -msgstr "" -"決定隱藏的視窗(如最小化的視窗和位於目前以外工作區的視窗)是否保持活動。" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:4 -msgid "" -"Determines whether the use of popup and highlight frame should be disabled " -"for window cycling." -msgstr "決定當視窗輪換時是否使用彈出式和強調框架。" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:5 -msgid "" -"Determines whether workspace switching should happen for windows on all " -"monitors or only for windows on the primary monitor." -msgstr "決定工作區切換是否使用於所有螢幕的視窗或只用於主要螢幕的視窗。" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:6 +#: data/org.gnome.mutter.gschema.xml.in:21 msgid "" -"Determines whether workspaces are managed dynamically or whether there's a " -"static number of workspaces (determined by the num-workspaces key in org." -"gnome.desktop.wm.preferences)." +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." msgstr "" -"決定工作區以動態方式管理或是有固定數量的工作區 (以 org.cinnamon.desktop.wm." -"preferences 中的 num-workspaces 鍵值來決定)。" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:7 -msgid "Draggable border width" -msgstr "可拖曳邊框寬度" +"當設為「true」,將不會有獨立的標題列,模態對話盒會附加在上層視窗的標題列並與" +"上層視窗一起移動。" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:8 +#: data/org.gnome.mutter.gschema.xml.in:30 msgid "Enable edge tiling when dropping windows on screen edges" msgstr "在螢幕邊緣放下視窗時啟用邊緣拼貼" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:9 +#: data/org.gnome.mutter.gschema.xml.in:31 msgid "" "If enabled, dropping windows on vertical screen edges maximizes them " "vertically and resizes them horizontally to cover half of the available " @@ -427,1139 +290,937 @@ msgstr "" "如果啟用,將視窗拖放到螢幕垂直邊緣時會讓它們垂直最大化並調整水平方向大小覆蓋" "可用區域的一半。拖放視窗到螢幕頂端邊緣則會讓它們完全最大化。" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:10 -msgid "Live Hidden Windows" -msgstr "活動中的隱藏 Windows" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:11 -msgid "Modifier to use for extended window management operations" -msgstr "用於延伸視窗管理操作程序的特殊按鍵" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:12 -msgid "No tab popup" -msgstr "沒有分頁彈出項" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:13 -msgid "Select window from tab popup" -msgstr "從分頁彈出項選擇視窗" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:14 -msgid "" -"The amount of total draggable borders. If the theme's visible borders are " -"not enough, invisible borders will be added to meet this value." -msgstr "" -"所有可拖曳邊框的總數。如果布景的可視邊框不夠,會加入隱形邊框來符合這個數值。" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:15 -msgid "" -"This key will initiate the \"overlay\", which is a combination window " -"overview and application launching system. The default is intended to be the " -"\"Windows key\" on PC hardware. It's expected that this binding either the " -"default or set to the empty string." -msgstr "" -"這個設定鍵會初始化「overlay」,這是一個複合視窗概覽與應用程式執行系統。預設是" -"要成為 PC 硬體上的「Windows key」。預期這個按鍵組含不是預設值就是設定為空字" -"串。" +#: data/org.gnome.mutter.gschema.xml.in:40 +msgid "Workspaces are managed dynamically" +msgstr "工作區以動態方式管理" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:16 +#: data/org.gnome.mutter.gschema.xml.in:41 msgid "" -"When true, instead of having independent titlebars, modal dialogs appear " -"attached to the titlebar of the parent window and are moved together with " -"the parent window." +"Determines whether workspaces are managed dynamically or whether there’s a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." msgstr "" -"當設為「true」,將不會有獨立的標題列,模態對話盒會附加在上層視窗的標題列並與" -"上層視窗一起移動。" - -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:17 -msgid "Workspaces are managed dynamically" -msgstr "工作區以動態方式管理" +"決定工作區以動態方式管理或是有固定數量的工作區 (以 org.gnome.desktop.wm." +"preferences 中的 num-workspaces 鍵值來決定)。" -#: ../src/org.cinnamon.muffin.gschema.xml.in.h:18 +#: data/org.gnome.mutter.gschema.xml.in:50 msgid "Workspaces only on primary" msgstr "只有主要螢幕的工作區" -#: ../src/tools/muffin-message.c:123 -#, c-format -msgid "Usage: %s\n" -msgstr "用法:%s\n" - -# (Abel) take care of the same string in libwnck -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:69 -msgid "Mi_nimize" -msgstr "最小化(_N)" - -# (Abel) take care of the same string in libwnck -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:71 -msgid "Ma_ximize" -msgstr "最大化(_X)" - -# (Abel) take care of the same string in libwnck -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:73 -msgid "Unma_ximize" -msgstr "取消最大化(_X)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:75 -msgid "Roll _Up" -msgstr "捲起(_U)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:77 -msgid "_Unroll" -msgstr "放下(_U)" +#: data/org.gnome.mutter.gschema.xml.in:51 +msgid "" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." +msgstr "決定工作區切換是否使用於所有螢幕的視窗或只用於主要螢幕的視窗。" -# (Abel) take care of the same string in libwnck -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:79 -msgid "_Move" -msgstr "移動(_M)" +#: data/org.gnome.mutter.gschema.xml.in:59 +msgid "No tab popup" +msgstr "沒有分頁彈出項" -# (Abel) take care of the same string in libwnck -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:81 -msgid "_Resize" -msgstr "調整大小(_R)" - -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:83 -msgid "Move Titlebar On_screen" -msgstr "在畫面上移動標題列(_S)" - -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:86 ../src/ui/menu.c:88 -msgid "Always on _Top" -msgstr "總是在最上層(_T)" +#: data/org.gnome.mutter.gschema.xml.in:60 +msgid "" +"Determines whether the use of popup and highlight frame should be disabled " +"for window cycling." +msgstr "決定當視窗輪換時是否使用彈出式和強調框架。" -# (Abel) take care of the same string in libwnck -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:90 -msgid "_Always on Visible Workspace" -msgstr "在所有工作區顯示(_A)" +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "Delay focus changes until the pointer stops moving" +msgstr "延遲焦點的改變直到指標停止移動" -# (Abel) take care of the same string in libwnck -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:92 -msgid "_Only on This Workspace" -msgstr "只在本工作區顯示(_O)" +#: data/org.gnome.mutter.gschema.xml.in:69 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" +"如果設為 true,焦點模式為「sloppy」或「mouse」,則焦點不會在進入視窗時立即改" +"變,而是在指標停止移動之後才改變。" -# (Abel) take care of the same string in libwnck -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:94 -msgid "Move to Workspace _Left" -msgstr "移至左方的工作區(_L)" +#: data/org.gnome.mutter.gschema.xml.in:79 +msgid "Draggable border width" +msgstr "可拖曳邊框寬度" -# (Abel) take care of the same string in libwnck -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:96 -msgid "Move to Workspace R_ight" -msgstr "移至右方的工作區(_I)" +#: data/org.gnome.mutter.gschema.xml.in:80 +msgid "" +"The amount of total draggable borders. If the theme’s visible borders are " +"not enough, invisible borders will be added to meet this value." +msgstr "所有可拖曳邊框的總數。如果布景的可視邊框不夠,會加入隱形邊框來符合這個數值。" -# (Abel) take care of the same string in libwnck -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:98 -msgid "Move to Workspace _Up" -msgstr "移至上方的工作區(_U)" +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "Auto maximize nearly monitor sized windows" +msgstr "自動最大化接近螢幕大小的視窗" -# (Abel) take care of the same string in libwnck -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:100 -msgid "Move to Workspace _Down" -msgstr "移至下方的工作區(_D)" +#: data/org.gnome.mutter.gschema.xml.in:90 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "如果啟用,初始大小為螢幕大小的新視窗會自動最大化。" -# (Abel) take care of the same string in libwnck -#. separator -#. Translators: Translate this string the same way as you do in libwnck! -#: ../src/ui/menu.c:104 -msgid "_Close" -msgstr "關閉(_C)" +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "Place new windows in the center" +msgstr "將新視窗放置於中央" -# (Abel) take care of the same string in libwnck -#: ../src/ui/menu.c:204 -#, c-format -msgid "Workspace %d%n" -msgstr "工作區 %d%n" +#: data/org.gnome.mutter.gschema.xml.in:99 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "當設定為「true」時,新視窗會永遠置於使用中螢幕畫面的正中央。" + +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "啟用試驗性功能" + +#: data/org.gnome.mutter.gschema.xml.in:108 +#| msgid "" +#| "To enable experimental features, add the feature keyword to the list. " +#| "Whether the feature requires restarting the compositor depends on the " +#| "given feature. Any experimental feature is not required to still be " +#| "available, or configurable. Don’t expect adding anything in this setting " +#| "to be future proof. Currently possible keywords: • “scale-monitor-" +#| "framebuffer” — makes mutter default to layout logical monitors in a " +#| "logical pixel coordinate space, while scaling monitor framebuffers " +#| "instead of window content, to manage HiDPI monitors. Does not require a " +#| "restart." +msgid "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes " +"mutter default to layout logical monitors in a logical pixel coordinate " +"space, while scaling monitor framebuffers instead of window content, to " +"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes " +"mutter request a low priority real-time scheduling. The executable or user " +"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — " +"initializes Xwayland lazily if there are X11 clients. Requires restart." +msgstr "" +"若要啟用實驗性功能,請將功能關鍵字加入列表中。置於該功能是否須要重新啟動混成" +"器則視給予的功能而定。任何實驗性功能不一定能用、或是可以調整設定。請不要預期" +"在此設定中加入的任何東西未來都能存在。目前可用的關鍵字有:" +"• 「scale-monitor-framebuffer」— 讓 mutter 預設採用邏輯像素座標空間的" +"配置邏輯螢幕,而縮放螢幕 framebuffer 則取代視窗內容以管理 HiDPI 螢幕。不需要重新啟動。" +"• 「rt-scheduler」— 讓 mutter 請求低優先級的即時排程。可執行檔或使用者必須要有" +"CAP_SYS_NICE。需要重新啟動。" +"• 「autostart-xwayland」— 如果有 X11 用戶端就延遲初始化 Xwayland。需要重新啟動。" + +#: data/org.gnome.mutter.gschema.xml.in:134 +msgid "Modifier to use to locate the pointer" +msgstr "要用來定位指標的輔助鍵" + +#: data/org.gnome.mutter.gschema.xml.in:135 +msgid "This key will initiate the “locate pointer” action." +msgstr "這個按鍵將會「定位指標」。" + +#: data/org.gnome.mutter.gschema.xml.in:155 +msgid "Select window from tab popup" +msgstr "從分頁彈出項選擇視窗" -# (Abel) take care of the same string in libwnck -#: ../src/ui/menu.c:214 -#, c-format -msgid "Workspace 1_0" -msgstr "工作區 1_0" +#: data/org.gnome.mutter.gschema.xml.in:160 +msgid "Cancel tab popup" +msgstr "取消分頁彈出項" -# (Abel) take care of the same string in libwnck -#: ../src/ui/menu.c:216 -#, c-format -msgid "Workspace %s%d" -msgstr "工作區 %s%d" +#: data/org.gnome.mutter.gschema.xml.in:165 +msgid "Switch monitor configurations" +msgstr "切換螢幕組態" + +#: data/org.gnome.mutter.gschema.xml.in:170 +msgid "Rotates the built-in monitor configuration" +msgstr "旋轉切換內建螢幕組態" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:6 +msgid "Switch to VT 1" +msgstr "切換至 VT 1" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:10 +msgid "Switch to VT 2" +msgstr "切換至 VT 2" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:14 +msgid "Switch to VT 3" +msgstr "切換至 VT 3" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:18 +msgid "Switch to VT 4" +msgstr "切換至 VT 4" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:22 +msgid "Switch to VT 5" +msgstr "切換至 VT 5" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:26 +msgid "Switch to VT 6" +msgstr "切換至 VT 6" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:30 +msgid "Switch to VT 7" +msgstr "切換至 VT 7" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:34 +msgid "Switch to VT 8" +msgstr "切換至 VT 8" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:38 +msgid "Switch to VT 9" +msgstr "切換至 VT 9" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:42 +msgid "Switch to VT 10" +msgstr "切換至 VT 10" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:46 +msgid "Switch to VT 11" +msgstr "切換至 VT 11" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:50 +msgid "Switch to VT 12" +msgstr "切換至 VT 12" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:54 +msgid "Re-enable shortcuts" +msgstr "重新啟用快捷鍵" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:64 +#| msgid "Allow grabs with Xwayland" +msgid "Allow X11 grabs to lock keyboard focus with Xwayland" +msgstr "允許 X11 抓取以使用 Xwayland 鎖定鍵盤焦點" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:65 +#, fuzzy +#| msgid "" +#| "Allow keyboard grabs issued by X11 applications running in Xwayland to be " +#| "taken into account. For a X11 grab to be taken into account under " +#| "Wayland, the client must also either send a specific X11 ClientMessage to " +#| "the root window or be among the applications white-listed in key " +#| "“xwayland-grab-access-rules”." +msgid "" +"Allow all keyboard events to be routed to X11 “override redirect” windows " +"with a grab when running in Xwayland. This option is to support X11 clients " +"which map an “override redirect” window (which do not receive keyboard " +"focus) and issue a keyboard grab to force all keyboard events to that " +"window. This option is seldom used and has no effect on regular X11 windows " +"which can receive keyboard focus under normal circumstances. For a X11 grab " +"to be taken into account under Wayland, the client must also either send a " +"specific X11 ClientMessage to the root window or be among the applications " +"white-listed in key “xwayland-grab-access-rules”." +msgstr "" +"考慮到在 Xwayland 中執行的 X11 應用程序發出的鍵盤抓取。對於在 Wayland 下考慮" +"的 X11 抓取,客戶端也必須送出一個特定的 X11 ClientMessage 到 root 視窗或者在 " +"xwayland-grab-access-rules 鍵白名單其中的應用程式" -# (Abel) take care of the same string in libwnck -#: ../src/ui/menu.c:397 -msgid "Move to Another _Workspace" -msgstr "移至另一個工作區(_W)" - -#. This is the text that should appear next to menu accelerators -#. * that use the shift key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:77 -msgid "Shift" -msgstr "Shift" - -#. This is the text that should appear next to menu accelerators -#. * that use the control key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:83 -msgid "Ctrl" -msgstr "Ctrl" - -#. This is the text that should appear next to menu accelerators -#. * that use the alt key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:89 -msgid "Alt" -msgstr "Alt" - -#. This is the text that should appear next to menu accelerators -#. * that use the meta key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:95 -msgid "Meta" -msgstr "Meta" - -#. This is the text that should appear next to menu accelerators -#. * that use the super key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:101 -msgid "Super" -msgstr "Super" - -#. This is the text that should appear next to menu accelerators -#. * that use the hyper key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:107 -msgid "Hyper" -msgstr "Hyper" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod2 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:113 -msgid "Mod2" -msgstr "Mod2" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod3 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:119 -msgid "Mod3" -msgstr "Mod3" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod4 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:125 -msgid "Mod4" -msgstr "Mod4" - -#. This is the text that should appear next to menu accelerators -#. * that use the mod5 key. If the text on this key isn't typically -#. * translated on keyboards used for your language, don't translate -#. * this. -#. -#: ../src/ui/metaaccellabel.c:131 -msgid "Mod5" -msgstr "Mod5" +#: data/org.gnome.mutter.wayland.gschema.xml.in:84 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "Xwayland 應用程式允許發出鍵盤抓取" -#. Translators: This represents the size of a window. The first number is -#. * the width of the window and the second is the height. +#: data/org.gnome.mutter.wayland.gschema.xml.in:85 +msgid "" +"List the resource names or resource class of X11 windows either allowed or " +"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are blacklisted, which has precedence over the " +"whitelist, to revoke applications from the default system list. The default " +"system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "" +"列出在 X11 視窗中的這些資源名稱或資源 class 允許或不允許在 Xwayland 底下發出 " +"X11 鍵盤抓取。在已提供的 X11 視窗中的資源名稱或資源 class 可以獲得,只要使用" +"這個指令 xprop WM_CLASS。在數值內的 Wildcard \"*\" 或 joker \"?\" 是受支援" +"的。開始於 \"!\" 的數值會被加入黑名單,優先於白名單,去取消授權來自預設系統清" +"單的應用程式。這個預設的系統清單包含了以下的應用程" +"序:“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@”,用戶可以取消一個存在的抓取,透過" +"使用一個具體的鍵盤快捷鍵定義透過這個綁定鍵 restore-shortcuts。" + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. #. -#: ../src/ui/resizepopup.c:113 +#: src/backends/meta-input-settings.c:2532 #, c-format -msgid "%d x %d" -msgstr "%d x %d" +msgid "Mode Switch (Group %d)" +msgstr "模式切換( 群組 %d)" -#: ../src/ui/theme.c:253 -msgid "top" -msgstr "頂" +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/backends/meta-input-settings.c:2555 +msgid "Switch monitor" +msgstr "切換螢幕" -#: ../src/ui/theme.c:255 -msgid "bottom" -msgstr "底" +#: src/backends/meta-input-settings.c:2557 +msgid "Show on-screen help" +msgstr "顯示螢幕求助" -#: ../src/ui/theme.c:257 -msgid "left" -msgstr "左" +#: src/backends/meta-monitor.c:223 +msgid "Built-in display" +msgstr "內建顯示" -#: ../src/ui/theme.c:259 -msgid "right" -msgstr "右" +#: src/backends/meta-monitor.c:252 +msgid "Unknown" +msgstr "不明" -#: ../src/ui/theme.c:286 -#, c-format -msgid "frame geometry does not specify \"%s\" dimension" -msgstr "邊框的位置大小中沒有指定“%s”部分的大小" +#: src/backends/meta-monitor.c:254 +msgid "Unknown Display" +msgstr "不明的顯示器" -#: ../src/ui/theme.c:305 +#: src/backends/meta-monitor.c:262 #, c-format -msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" -msgstr "邊框的位置大小中沒有指定“%2$s”邊框中的“%1$s”部分" +msgctxt "" +"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme.c:342 +#: src/backends/meta-monitor.c:270 #, c-format -msgid "Button aspect ratio %g is not reasonable" -msgstr "按鈕的長寬比 %g 不合理" +msgctxt "" +"This is a monitor vendor name followed by product/model name where size in " +"inches could not be calculated, e.g. Dell U2414H" +msgid "%s %s" +msgstr "%s %s" -#: ../src/ui/theme.c:354 -#, c-format -msgid "Frame geometry does not specify size of buttons" -msgstr "邊框的位置大小規格內未有指定按鈕的大小" +#. Translators: this string will appear in Sysprof +#: src/backends/meta-profiler.c:82 +msgid "Compositor" +msgstr "合成器" -#: ../src/ui/theme.c:1067 -#, c-format -msgid "Gradients should have at least two colors" -msgstr "漸層至少應該有兩種顏色" - -#: ../src/ui/theme.c:1219 +# FIXME: I'm still unclear about the meaning of XGetSelectionOwner -- Abel +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/compositor/compositor.c:509 #, c-format msgid "" -"GTK custom color specification must have color name and fallback in " -"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" -msgstr "" -"GTK 自訂顏色規格規定必須有顏色名稱並加上封閉括號,例如 gtk:custom(foo,bar);" -"無法分析「%s」" +"Another compositing manager is already running on screen %i on display “%s”." +msgstr "在畫面「%2$s」中的第 %1$i 個螢幕中已啟動另一個組合視窗管理員。" -#: ../src/ui/theme.c:1235 -#, c-format -msgid "" -"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" -"_ are valid" -msgstr "gtk:custom 的 color_name 參數 '%c' 中有無效字元,只能使用 A-Za-z0-9-_ " +#: src/core/bell.c:192 +msgid "Bell event" +msgstr "響鈴事件" -#: ../src/ui/theme.c:1249 -#, c-format -msgid "" -"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " -"fit the format" -msgstr "" -"Gtk:custom 的格式是「gtk:custom(color_name,fallback)」,但「%s」不符合格式" +#: src/core/main.c:190 +msgid "Disable connection to session manager" +msgstr "停用到作業階段管理員的連線" -#: ../src/ui/theme.c:1294 -#, c-format -msgid "" -"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] " -"where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"GTK 色彩規格規定必須在狀態外加上方括號,例如 gtk:fg[NORMAL],這裡 NORMAL 表示" -"狀態;無法分析“%s”" +#: src/core/main.c:196 +msgid "Replace the running window manager" +msgstr "取代執行中的視窗管理員" -#: ../src/ui/theme.c:1308 -#, c-format -msgid "" -"GTK color specification must have a close bracket after the state, e.g. gtk:" -"fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" -msgstr "" -"GTK 色彩規格規定必須在狀態後加上閉方括號,例如 gtk:fg[NORMAL],這裡 NORMAL 表" -"示狀態;無法分析“%s”" +#: src/core/main.c:202 +msgid "Specify session management ID" +msgstr "指定作業階段管理 ID" -#: ../src/ui/theme.c:1319 -#, c-format -msgid "Did not understand state \"%s\" in color specification" -msgstr "無法將“%s”理解為色彩規格中的狀態" +#: src/core/main.c:207 +msgid "X Display to use" +msgstr "使用的 X 畫面" -#: ../src/ui/theme.c:1332 -#, c-format -msgid "Did not understand color component \"%s\" in color specification" -msgstr "無法將“%s”理解為色彩規格中的色彩部分" +#: src/core/main.c:213 +msgid "Initialize session from savefile" +msgstr "以 savefile 初始化作業階段" -#: ../src/ui/theme.c:1361 -#, c-format -msgid "" -"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the " -"format" -msgstr "指定混色的格式是“blend/背景顏色/前景顏色/透明度”,“%s”不符合規格" +#: src/core/main.c:219 +msgid "Make X calls synchronous" +msgstr "使用同步方式調用 X 函式" -#: ../src/ui/theme.c:1372 -#, c-format -msgid "Could not parse alpha value \"%s\" in blended color" -msgstr "無法理解“%s”作為混色的透明度數值" +#: src/core/main.c:226 +msgid "Run as a wayland compositor" +msgstr "以 wayland 組合器執行" -#: ../src/ui/theme.c:1382 -#, c-format -msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" -msgstr "混色的透明度數值“%s”不是在 0.0 至 1.0 之間" +#: src/core/main.c:232 +msgid "Run as a nested compositor" +msgstr "以巢狀組合器執行" -#: ../src/ui/theme.c:1429 -#, c-format -msgid "" -"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format" -msgstr "陰影的格式是“shade/基本顏色/比重”,但“%s”不符合格式" +#: src/core/main.c:238 +msgid "Run wayland compositor without starting Xwayland" +msgstr "在不啟動 Xwayland 的情況下開啟 Wayland 合成器" -#: ../src/ui/theme.c:1440 -#, c-format -msgid "Could not parse shade factor \"%s\" in shaded color" -msgstr "在陰影顏色中無法將“%s”理解為陰影比重" +#: src/core/main.c:246 +msgid "Run as a full display server, rather than nested" +msgstr "以完全顯示伺服器執行,而非巢狀" -#: ../src/ui/theme.c:1450 -#, c-format -msgid "Shade factor \"%s\" in shaded color is negative" -msgstr "在陰影顏色中陰影比重“%s”是負數" +#: src/core/main.c:252 +msgid "Run with X11 backend" +msgstr "透過 X11 後端執行" -#: ../src/ui/theme.c:1479 +#. Translators: %s is a window title +#: src/core/meta-close-dialog-default.c:151 #, c-format -msgid "Could not parse color \"%s\"" -msgstr "無法分析顏色“%s”" +msgid "“%s” is not responding." +msgstr "「%s」沒有回應。" -#: ../src/ui/theme.c:1790 -#, c-format -msgid "Coordinate expression contains character '%s' which is not allowed" -msgstr "座標表達式中出現不可接受的字元‘%s’" +#: src/core/meta-close-dialog-default.c:153 +msgid "Application is not responding." +msgstr "應用程式沒有回應。" -#: ../src/ui/theme.c:1817 -#, c-format +#: src/core/meta-close-dialog-default.c:158 msgid "" -"Coordinate expression contains floating point number '%s' which could not be " -"parsed" -msgstr "座標表達式中出現無法分析的浮點小數‘%s’" +"You may choose to wait a short while for it to continue or force the " +"application to quit entirely." +msgstr "您可以選擇稍等一下讓它繼續,或者強制完全退出程式。" -#: ../src/ui/theme.c:1831 -#, c-format -msgid "Coordinate expression contains integer '%s' which could not be parsed" -msgstr "座標表達式中出現無法分析的整數‘%s’" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Force Quit" +msgstr "強制退出(_F)" -#: ../src/ui/theme.c:1953 -#, c-format -msgid "" -"Coordinate expression contained unknown operator at the start of this text: " -"\"%s\"" -msgstr "在座標表達式中,以下文字的開始部分含有不明的運算符:“%s”" +#: src/core/meta-close-dialog-default.c:165 +msgid "_Wait" +msgstr "等待(_W)" -#: ../src/ui/theme.c:2010 +#: src/core/mutter.c:38 #, c-format -msgid "Coordinate expression was empty or not understood" -msgstr "座標表達式是空白的或是無法分析" +msgid "" +"mutter %s\n" +"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" +"This is free software; see the source for copying conditions.\n" +"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A " +"PARTICULAR PURPOSE.\n" +msgstr "" +"mutter %s\n" +"著作權所有 (C) 2001-%d Havoc Pennington, Red Hat, Inc. 及其它開發者\n" +"本程式是自由軟體;有關著作權的詳情請參考源始程式碼。\n" +"本程式不負任何擔保責任;亦無對適售性或特定目的適用性所為的默示性擔保。\n" -#: ../src/ui/theme.c:2121 ../src/ui/theme.c:2131 ../src/ui/theme.c:2165 -#, c-format -msgid "Coordinate expression results in division by zero" -msgstr "座標表達式中出現被 0 整除的錯誤" +#: src/core/mutter.c:52 +msgid "Print version" +msgstr "顯示版本" -#: ../src/ui/theme.c:2173 -#, c-format -msgid "" -"Coordinate expression tries to use mod operator on a floating-point number" -msgstr "座標表達式中出現將浮點數使用於餘數運算符 (mod) 的錯誤" +#: src/core/mutter.c:58 +msgid "Mutter plugin to use" +msgstr "要使用的 Mutter 外掛程式" -#: ../src/ui/theme.c:2229 +# (Abel) take care of the same string in libwnck +#: src/core/prefs.c:1849 #, c-format -msgid "" -"Coordinate expression has an operator \"%s\" where an operand was expected" -msgstr "在座標表達式中,應該有運算子的地方出現了運算符“%s”" +msgid "Workspace %d" +msgstr "工作區 %d" -#: ../src/ui/theme.c:2238 -#, c-format -msgid "Coordinate expression had an operand where an operator was expected" -msgstr "在座標表達式中,應該有運算符的地方出現了運算子" +#: src/core/util.c:122 +msgid "Mutter was compiled without support for verbose mode\n" +msgstr "編譯 Mutter 時並沒有加入詳細偵錯模式的支援\n" -#: ../src/ui/theme.c:2246 +#: src/wayland/meta-wayland-tablet-pad.c:568 #, c-format -msgid "Coordinate expression ended with an operator instead of an operand" -msgstr "結束座標表達式的是一個運算符而非運算子" +msgid "Mode Switch: Mode %d" +msgstr "模式切換:模式 %d" -#: ../src/ui/theme.c:2256 +#: src/x11/meta-x11-display.c:679 #, c-format msgid "" -"Coordinate expression has operator \"%c\" following operator \"%c\" with no " -"operand in between" -msgstr "在座標表達式中,運算符“%c”緊隨運算符“%c”出現,但中間沒有任何運算子" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." +msgstr "" +"畫面「%s」已經有了視窗管理員;請嘗試使用 --replace 選項來替換目前的視窗管理" +"員。" -#: ../src/ui/theme.c:2407 ../src/ui/theme.c:2452 -#, c-format -msgid "Coordinate expression had unknown variable or constant \"%s\"" -msgstr "座標表達式中出現不明的變數或常數“%s”" +#: src/x11/meta-x11-display.c:1040 +msgid "Failed to initialize GDK\n" +msgstr "無法初始化 GDK\n" -#: ../src/ui/theme.c:2506 +#: src/x11/meta-x11-display.c:1064 #, c-format -msgid "Coordinate expression parser overflowed its buffer." -msgstr "座標表達式分析器令緩衝溢位。" +msgid "Failed to open X Window System display “%s”\n" +msgstr "無法開啟 X Window 系統畫面「%s」\n" -#: ../src/ui/theme.c:2535 +#: src/x11/meta-x11-display.c:1147 #, c-format -msgid "Coordinate expression had a close parenthesis with no open parenthesis" -msgstr "座標表達式中的閉括號沒有相應的開括號" +msgid "Screen %d on display “%s” is invalid\n" +msgstr "畫面「%2$s」中的第 %1$d 個螢幕無效\n" -#: ../src/ui/theme.c:2599 +#: src/x11/meta-x11-selection-input-stream.c:445 #, c-format -msgid "Coordinate expression had an open parenthesis with no close parenthesis" -msgstr "座標表達式中的開括號沒有相應的閉括號" +msgid "Format %s not supported" +msgstr "不支援 %s 格式" -#: ../src/ui/theme.c:2610 -#, c-format -msgid "Coordinate expression doesn't seem to have any operators or operands" -msgstr "座標表達式中似乎沒有任何運算符或運算子" +#: src/x11/session.c:1821 +msgid "" +"These windows do not support “save current setup” and will have to be " +"restarted manually next time you log in." +msgstr "這些視窗不支援「儲存目前的設定」,必須在下次登入後自行啟動。" -#: ../src/ui/theme.c:2822 ../src/ui/theme.c:2842 ../src/ui/theme.c:2862 +#: src/x11/window-props.c:569 #, c-format -msgid "Theme contained an expression that resulted in an error: %s\n" -msgstr "佈景主題中含有引致錯誤的表達式:%s\n" +msgid "%s (on %s)" +msgstr "%s(在 %s)" -#: ../src/ui/theme.c:4533 -#, c-format -msgid "" -"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " -"specified for this frame style" -msgstr "" -"此邊框款式必須指定 <button function=\"%s\" state=\"%s\" draw_ops=\"whatever" -"\"/>" +#~ msgid "Move window one workspace to the left" +#~ msgstr "將視窗移至左方的工作區" -#: ../src/ui/theme.c:5066 ../src/ui/theme.c:5091 -#, c-format -msgid "" -"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -msgstr "" -"缺少了 <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" +#~ msgid "Move window one workspace to the right" +#~ msgstr "將視窗移至右方的工作區" -#: ../src/ui/theme.c:5139 -#, c-format -msgid "Failed to load theme \"%s\": %s\n" -msgstr "無法載入佈景主題“%s”:%s\n" +#~ msgid "Move to workspace left" +#~ msgstr "移至左方的工作區" -#: ../src/ui/theme.c:5275 ../src/ui/theme.c:5282 ../src/ui/theme.c:5289 -#: ../src/ui/theme.c:5296 ../src/ui/theme.c:5303 -#, c-format -msgid "No <%s> set for theme \"%s\"" -msgstr "佈景主題“%s”未指定 <%s>" +#~ msgid "Move to workspace right" +#~ msgstr "移至右方的工作區" -#: ../src/ui/theme.c:5311 -#, c-format -msgid "" -"No frame style set for window type \"%s\" in theme \"%s\", add a <window " -"type=\"%s\" style_set=\"whatever\"/> element" -msgstr "" -"在佈景主題“%2$s”中,視窗類型“%1$s”沒有指定任何邊框款式。請加上 <window type=" -"\"%3$s\" style_set=\"whatever\"/> 元素" +#~ msgid "Toggle shaded state" +#~ msgstr "切換視窗捲起/放下狀態" -#: ../src/ui/theme.c:5709 ../src/ui/theme.c:5771 ../src/ui/theme.c:5834 -#, c-format -msgid "" -"User-defined constants must begin with a capital letter; \"%s\" does not" -msgstr "自行定義的常數必須以大寫字母開始;但“%s”不是" +#~ msgid "background texture could not be created from file" +#~ msgstr "背景材質無法從檔案建立" -#: ../src/ui/theme.c:5717 ../src/ui/theme.c:5779 ../src/ui/theme.c:5842 -#, c-format -msgid "Constant \"%s\" has already been defined" -msgstr "已定義了“%s”常數" +#~ msgid "Failed to scan themes directory: %s\n" +#~ msgstr "找不到佈景主題目錄:%s\n" -#. Translators: This means that an attribute which should have been found -#. * on an XML element was not in fact found. -#. -#: ../src/ui/theme-parser.c:236 -#, c-format -msgid "No \"%s\" attribute on element <%s>" -msgstr "在元素 <%2$s> 中沒有「%1$s」屬性" +#~ msgid "" +#~ "Could not find a theme! Be sure %s exists and contains the usual themes.\n" +#~ msgstr "" +#~ "找不到任何佈景主題!請確定 %s 存在及其中存放了平常使用的佈景主題。\n" -#: ../src/ui/theme-parser.c:265 ../src/ui/theme-parser.c:283 -#, c-format -msgid "Line %d character %d: %s" -msgstr "第 %d 列第 %d 字:%s" +#~ msgid "Screen %d on display \"%s\" already has a window manager\n" +#~ msgstr "畫面“%2$s”中的第 %1$d 個螢幕已經有了視窗總管\n" -#: ../src/ui/theme-parser.c:479 -#, c-format -msgid "Attribute \"%s\" repeated twice on the same <%s> element" -msgstr "屬性「%s」在同一個 <%s> 元素中重複了兩次" +#~ msgid "%d x %d" +#~ msgstr "%d x %d" -#: ../src/ui/theme-parser.c:503 ../src/ui/theme-parser.c:552 -#, c-format -msgid "Attribute \"%s\" is invalid on <%s> element in this context" -msgstr "在此關聯選單中,屬性「%s」在 <%s> 元素中是無效的" +#~ msgid "top" +#~ msgstr "頂" -#: ../src/ui/theme-parser.c:594 -#, c-format -msgid "Could not parse \"%s\" as an integer" -msgstr "無法以整數的方式分析“%s”" +#~ msgid "bottom" +#~ msgstr "底" -#: ../src/ui/theme-parser.c:603 ../src/ui/theme-parser.c:658 -#, c-format -msgid "Did not understand trailing characters \"%s\" in string \"%s\"" -msgstr "無法理解字串“%2$s”中的結束字元“%1$s”" +#~ msgid "left" +#~ msgstr "左" -#: ../src/ui/theme-parser.c:613 -#, c-format -msgid "Integer %ld must be positive" -msgstr "整數 %ld 必須為正數" +#~ msgid "right" +#~ msgstr "右" -#: ../src/ui/theme-parser.c:621 -#, c-format -msgid "Integer %ld is too large, current max is %d" -msgstr "整數 %ld 太大,目前可接受的最大值為 %d" +#~ msgid "frame geometry does not specify \"%s\" dimension" +#~ msgstr "邊框的位置大小中沒有指定“%s”部分的大小" -#: ../src/ui/theme-parser.c:649 ../src/ui/theme-parser.c:765 -#, c-format -msgid "Could not parse \"%s\" as a floating point number" -msgstr "無法以浮點小數的方式分析“%s”" +#~ msgid "frame geometry does not specify dimension \"%s\" for border \"%s\"" +#~ msgstr "邊框的位置大小中沒有指定“%2$s”邊框中的“%1$s”部分" -#: ../src/ui/theme-parser.c:680 ../src/ui/theme-parser.c:708 -#, c-format -msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" -msgstr "布林值必須為“true”或“false”,不是“%s”" +#~ msgid "Button aspect ratio %g is not reasonable" +#~ msgstr "按鈕的長寬比 %g 不合理" -#: ../src/ui/theme-parser.c:735 -#, c-format -msgid "Angle must be between 0.0 and 360.0, was %g\n" -msgstr "角度必須在 0.0 至 360.0 之間,此處的值為 %g\n" +#~ msgid "Frame geometry does not specify size of buttons" +#~ msgstr "邊框的位置大小規格內未有指定按鈕的大小" -#: ../src/ui/theme-parser.c:798 -#, c-format -msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" -msgstr "透明度必須在 0.0(完全透明)至 1.0(完全不透明)之間,此處的值為 %g\n" +#~ msgid "Gradients should have at least two colors" +#~ msgstr "漸層至少應該有兩種顏色" -#: ../src/ui/theme-parser.c:863 -#, c-format -msgid "" -"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," -"large,x-large,xx-large)\n" -msgstr "" -"無效的標題大小“%s”(必須為 xx-small、x-small、small、medium、large、\n" -"x-large、xx-large 其中一個)\n" +#~ msgid "" +#~ "GTK custom color specification must have color name and fallback in " +#~ "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\"" +#~ msgstr "" +#~ "GTK 自訂顏色規格規定必須有顏色名稱並加上封閉括號,例如 gtk:custom(foo," +#~ "bar);無法分析「%s」" -#: ../src/ui/theme-parser.c:1019 ../src/ui/theme-parser.c:1082 -#: ../src/ui/theme-parser.c:1116 ../src/ui/theme-parser.c:1219 -#, c-format -msgid "<%s> name \"%s\" used a second time" -msgstr "<%s> 的 name 屬性“%s”用了超過一次" +#~ msgid "" +#~ "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-" +#~ "z0-9-_ are valid" +#~ msgstr "" +#~ "gtk:custom 的 color_name 參數 '%c' 中有無效字元,只能使用 A-Za-z0-9-_ " -#: ../src/ui/theme-parser.c:1031 ../src/ui/theme-parser.c:1128 -#: ../src/ui/theme-parser.c:1231 -#, c-format -msgid "<%s> parent \"%s\" has not been defined" -msgstr "<%s> 的主元素“%s”沒有任何定義" +#~ msgid "" +#~ "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " +#~ "fit the format" +#~ msgstr "" +#~ "Gtk:custom 的格式是「gtk:custom(color_name,fallback)」,但「%s」不符合格式" -#: ../src/ui/theme-parser.c:1141 -#, c-format -msgid "<%s> geometry \"%s\" has not been defined" -msgstr "<%s> 元素的位置大小“%s”沒有任何定義" +#~ msgid "" +#~ "GTK color specification must have the state in brackets, e.g. gtk:" +#~ "fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "GTK 色彩規格規定必須在狀態外加上方括號,例如 gtk:fg[NORMAL],這裡 NORMAL " +#~ "表示狀態;無法分析“%s”" -#: ../src/ui/theme-parser.c:1154 -#, c-format -msgid "<%s> must specify either a geometry or a parent that has a geometry" -msgstr "<%s> 必須自己指定位置大小或指定有位置大小的主元素" +#~ msgid "" +#~ "GTK color specification must have a close bracket after the state, e.g. " +#~ "gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\"" +#~ msgstr "" +#~ "GTK 色彩規格規定必須在狀態後加上閉方括號,例如 gtk:fg[NORMAL],這裡 " +#~ "NORMAL 表示狀態;無法分析“%s”" -#: ../src/ui/theme-parser.c:1196 -msgid "You must specify a background for an alpha value to be meaningful" -msgstr "必須指定背景使得透明 ( alpha) 值的變得有意義" +#~ msgid "Did not understand state \"%s\" in color specification" +#~ msgstr "無法將“%s”理解為色彩規格中的狀態" -#: ../src/ui/theme-parser.c:1264 -#, c-format -msgid "Unknown type \"%s\" on <%s> element" -msgstr "<%2$s> 元素之內出現不明的類型“%1$s”" +#~ msgid "Did not understand color component \"%s\" in color specification" +#~ msgstr "無法將“%s”理解為色彩規格中的色彩部分" -#: ../src/ui/theme-parser.c:1275 -#, c-format -msgid "Unknown style_set \"%s\" on <%s> element" -msgstr "<%2$s> 元素之內出現不明的 style_set“%1$s”" +#~ msgid "" +#~ "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit " +#~ "the format" +#~ msgstr "指定混色的格式是“blend/背景顏色/前景顏色/透明度”,“%s”不符合規格" -#: ../src/ui/theme-parser.c:1283 -#, c-format -msgid "Window type \"%s\" has already been assigned a style set" -msgstr "視窗類型“%s”已經分配了 style set" - -#: ../src/ui/theme-parser.c:1313 ../src/ui/theme-parser.c:1377 -#: ../src/ui/theme-parser.c:1603 ../src/ui/theme-parser.c:2838 -#: ../src/ui/theme-parser.c:2884 ../src/ui/theme-parser.c:3034 -#: ../src/ui/theme-parser.c:3273 ../src/ui/theme-parser.c:3311 -#: ../src/ui/theme-parser.c:3349 ../src/ui/theme-parser.c:3387 -#, c-format -msgid "Element <%s> is not allowed below <%s>" -msgstr "元素 <%s> 不允許在 <%s> 之下" +#~ msgid "Could not parse alpha value \"%s\" in blended color" +#~ msgstr "無法理解“%s”作為混色的透明度數值" -#: ../src/ui/theme-parser.c:1427 ../src/ui/theme-parser.c:1441 -#: ../src/ui/theme-parser.c:1486 -msgid "" -"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" " -"for buttons" -msgstr "" -"不可能同時指定按鈕的寬度/長度 (button_width/button_height) 及長寬比" -"(aspect_ratio)" +#~ msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0" +#~ msgstr "混色的透明度數值“%s”不是在 0.0 至 1.0 之間" -#: ../src/ui/theme-parser.c:1450 -#, c-format -msgid "Distance \"%s\" is unknown" -msgstr "不明的距離“%s”" +#~ msgid "" +#~ "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the " +#~ "format" +#~ msgstr "陰影的格式是“shade/基本顏色/比重”,但“%s”不符合格式" -#: ../src/ui/theme-parser.c:1495 -#, c-format -msgid "Aspect ratio \"%s\" is unknown" -msgstr "不明的長寬比“%s”" +#~ msgid "Could not parse shade factor \"%s\" in shaded color" +#~ msgstr "在陰影顏色中無法將“%s”理解為陰影比重" -#: ../src/ui/theme-parser.c:1557 -#, c-format -msgid "Border \"%s\" is unknown" -msgstr "不明的邊框“%s”" +#~ msgid "Shade factor \"%s\" in shaded color is negative" +#~ msgstr "在陰影顏色中陰影比重“%s”是負數" -#: ../src/ui/theme-parser.c:1868 -#, c-format -msgid "No \"start_angle\" or \"from\" attribute on element <%s>" -msgstr "元素 <%s> 中沒有“start_angle”或“from”屬性" +#~ msgid "Could not parse color \"%s\"" +#~ msgstr "無法分析顏色“%s”" -#: ../src/ui/theme-parser.c:1875 -#, c-format -msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" -msgstr "元素 <%s> 中沒有“extent_angle”或“to”屬性" +#~ msgid "Coordinate expression contains character '%s' which is not allowed" +#~ msgstr "座標表達式中出現不可接受的字元‘%s’" -#: ../src/ui/theme-parser.c:2115 -#, c-format -msgid "Did not understand value \"%s\" for type of gradient" -msgstr "無法將“%s”理解為漸層的樣式" +#~ msgid "" +#~ "Coordinate expression contains floating point number '%s' which could not " +#~ "be parsed" +#~ msgstr "座標表達式中出現無法分析的浮點小數‘%s’" -#: ../src/ui/theme-parser.c:2193 ../src/ui/theme-parser.c:2568 -#, c-format -msgid "Did not understand fill type \"%s\" for <%s> element" -msgstr "無法理解 <%2$s> 元素中的填充類型“%1$s”" +#~ msgid "" +#~ "Coordinate expression contains integer '%s' which could not be parsed" +#~ msgstr "座標表達式中出現無法分析的整數‘%s’" -#: ../src/ui/theme-parser.c:2360 ../src/ui/theme-parser.c:2443 -#: ../src/ui/theme-parser.c:2506 -#, c-format -msgid "Did not understand state \"%s\" for <%s> element" -msgstr "無法將“%s”理解為 <%s> 元素的狀態" +#~ msgid "" +#~ "Coordinate expression contained unknown operator at the start of this " +#~ "text: \"%s\"" +#~ msgstr "在座標表達式中,以下文字的開始部分含有不明的運算符:“%s”" -#: ../src/ui/theme-parser.c:2370 ../src/ui/theme-parser.c:2453 -#, c-format -msgid "Did not understand shadow \"%s\" for <%s> element" -msgstr "無法將“%s”理解為 <%s> 元素的陰影" +#~ msgid "Coordinate expression was empty or not understood" +#~ msgstr "座標表達式是空白的或是無法分析" -#: ../src/ui/theme-parser.c:2380 -#, c-format -msgid "Did not understand arrow \"%s\" for <%s> element" -msgstr "無法將“%s”理解為 <%s> 元素的箭頭" +#~ msgid "Coordinate expression results in division by zero" +#~ msgstr "座標表達式中出現被 0 整除的錯誤" -#: ../src/ui/theme-parser.c:2694 ../src/ui/theme-parser.c:2790 -#, c-format -msgid "No <draw_ops> called \"%s\" has been defined" -msgstr "沒有定義任何名稱為“%s”的 <draw_ops>" +#~ msgid "" +#~ "Coordinate expression tries to use mod operator on a floating-point number" +#~ msgstr "座標表達式中出現將浮點數使用於餘數運算符 (mod) 的錯誤" -#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802 -#, c-format -msgid "Including draw_ops \"%s\" here would create a circular reference" -msgstr "這裡的 draw_ops“%s”會造成循環" +#~ msgid "" +#~ "Coordinate expression has an operator \"%s\" where an operand was expected" +#~ msgstr "在座標表達式中,應該有運算子的地方出現了運算符“%s”" -#: ../src/ui/theme-parser.c:2917 -#, c-format -msgid "Unknown position \"%s\" for frame piece" -msgstr "邊框組件指定了不明的位置“%s”" +#~ msgid "Coordinate expression had an operand where an operator was expected" +#~ msgstr "在座標表達式中,應該有運算符的地方出現了運算子" -#: ../src/ui/theme-parser.c:2925 -#, c-format -msgid "Frame style already has a piece at position %s" -msgstr "邊框款式已經在位置 %s 中指定了一件邊框組件" +#~ msgid "Coordinate expression ended with an operator instead of an operand" +#~ msgstr "結束座標表達式的是一個運算符而非運算子" -#: ../src/ui/theme-parser.c:2942 ../src/ui/theme-parser.c:3019 -#, c-format -msgid "No <draw_ops> with the name \"%s\" has been defined" -msgstr "沒有定義任何名稱為“%s”的 <draw_ops>" +#~ msgid "" +#~ "Coordinate expression has operator \"%c\" following operator \"%c\" with " +#~ "no operand in between" +#~ msgstr "在座標表達式中,運算符“%c”緊隨運算符“%c”出現,但中間沒有任何運算子" -#: ../src/ui/theme-parser.c:2972 -#, c-format -msgid "Unknown function \"%s\" for button" -msgstr "按鈕擁有不明的功能“%s”" +#~ msgid "Coordinate expression had unknown variable or constant \"%s\"" +#~ msgstr "座標表達式中出現不明的變數或常數“%s”" -#: ../src/ui/theme-parser.c:2982 -#, c-format -msgid "Button function \"%s\" does not exist in this version (%d, need %d)" -msgstr "按鈕功能“%s”不存在於這個 版本(%d,要求 %d)" +#~ msgid "Coordinate expression parser overflowed its buffer." +#~ msgstr "座標表達式分析器令緩衝溢位。" -#: ../src/ui/theme-parser.c:2994 -#, c-format -msgid "Unknown state \"%s\" for button" -msgstr "無法理解“%s”為按鈕的狀態" +#~ msgid "" +#~ "Coordinate expression had a close parenthesis with no open parenthesis" +#~ msgstr "座標表達式中的閉括號沒有相應的開括號" -#: ../src/ui/theme-parser.c:3002 -#, c-format -msgid "Frame style already has a button for function %s state %s" -msgstr "邊框款式已經指定了一個擁有 %s 功能及 %s 狀態的按鈕" +#~ msgid "" +#~ "Coordinate expression had an open parenthesis with no close parenthesis" +#~ msgstr "座標表達式中的開括號沒有相應的閉括號" -#: ../src/ui/theme-parser.c:3073 -#, c-format -msgid "\"%s\" is not a valid value for focus attribute" -msgstr "“%s”不是 focus 屬性的有效設定值" +#~ msgid "Coordinate expression doesn't seem to have any operators or operands" +#~ msgstr "座標表達式中似乎沒有任何運算符或運算子" -#: ../src/ui/theme-parser.c:3082 -#, c-format -msgid "\"%s\" is not a valid value for state attribute" -msgstr "“%s”不是 state 屬性的有效設定值" +#~ msgid "Theme contained an expression that resulted in an error: %s\n" +#~ msgstr "佈景主題中含有引致錯誤的表達式:%s\n" -#: ../src/ui/theme-parser.c:3092 -#, c-format -msgid "A style called \"%s\" has not been defined" -msgstr "沒有定義任何稱為“%s”的款式" +#~ msgid "" +#~ "<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be " +#~ "specified for this frame style" +#~ msgstr "" +#~ "此邊框款式必須指定 <button function=\"%s\" state=\"%s\" draw_ops=" +#~ "\"whatever\"/>" -#: ../src/ui/theme-parser.c:3113 ../src/ui/theme-parser.c:3136 -#, c-format -msgid "\"%s\" is not a valid value for resize attribute" -msgstr "“%s”不是 resize 屬性的有效設定值" +#~ msgid "" +#~ "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/" +#~ ">" +#~ msgstr "" +#~ "缺少了 <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" -#: ../src/ui/theme-parser.c:3147 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized/shaded " -"states" -msgstr "元素 <%s> 不應在最大化或捲起的狀態中指定“resize”屬性" +#~ msgid "Failed to load theme \"%s\": %s\n" +#~ msgstr "無法載入佈景主題“%s”:%s\n" -#: ../src/ui/theme-parser.c:3161 -#, c-format -msgid "" -"Should not have \"resize\" attribute on <%s> element for maximized states" -msgstr "不應在元素 <%s> 最大化的狀態中指定“resize”屬性" +#~ msgid "No <%s> set for theme \"%s\"" +#~ msgstr "佈景主題“%s”未指定 <%s>" -#: ../src/ui/theme-parser.c:3175 ../src/ui/theme-parser.c:3222 -#, c-format -msgid "Style has already been specified for state %s resize %s focus %s" -msgstr "當 state=%s resize=%s focus=%s 時,樣式早已經被指定了" +#~ msgid "" +#~ "No frame style set for window type \"%s\" in theme \"%s\", add a <window " +#~ "type=\"%s\" style_set=\"whatever\"/> element" +#~ msgstr "" +#~ "在佈景主題“%2$s”中,視窗類型“%1$s”沒有指定任何邊框款式。請加上 <window " +#~ "type=\"%3$s\" style_set=\"whatever\"/> 元素" -#: ../src/ui/theme-parser.c:3186 ../src/ui/theme-parser.c:3197 -#: ../src/ui/theme-parser.c:3208 ../src/ui/theme-parser.c:3233 -#: ../src/ui/theme-parser.c:3244 ../src/ui/theme-parser.c:3255 -#, c-format -msgid "Style has already been specified for state %s focus %s" -msgstr "當 state=%s focus=%s 時,樣式早已經被指定了" +#~ msgid "" +#~ "User-defined constants must begin with a capital letter; \"%s\" does not" +#~ msgstr "自行定義的常數必須以大寫字母開始;但“%s”不是" -#: ../src/ui/theme-parser.c:3294 -msgid "" -"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"一個 <piece> 元素不可同時使用兩個 draw_ops (佈景主題同時指定了一個 draw_ops " -"屬性及一個 <draw_ops> 元素,或是指定了兩個元素)" +#~ msgid "Constant \"%s\" has already been defined" +#~ msgstr "已定義了“%s”常數" -#: ../src/ui/theme-parser.c:3332 -msgid "" -"Can't have a two draw_ops for a <button> element (theme specified a draw_ops " -"attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"一個 <button> 元素不可同時使用兩個 draw_ops (佈景主題同時指定了一個 draw_ops " -"屬性及一個 <draw_ops> 元素,或是指定了兩個元素)" +#~ msgid "No \"%s\" attribute on element <%s>" +#~ msgstr "在元素 <%2$s> 中沒有「%1$s」屬性" -#: ../src/ui/theme-parser.c:3370 -msgid "" -"Can't have a two draw_ops for a <menu_icon> element (theme specified a " -"draw_ops attribute and also a <draw_ops> element, or specified two elements)" -msgstr "" -"一個 <menu_icon> 元素不可同時使用兩個 draw_ops (佈景主題同時指定了一個 " -"draw_ops 屬性及一個 <draw_ops> 元素,或是指定了兩個元素)" +#~ msgid "Line %d character %d: %s" +#~ msgstr "第 %d 列第 %d 字:%s" -#: ../src/ui/theme-parser.c:3434 -#, c-format -msgid "Bad version specification '%s'" -msgstr "不正確的版本規格「%s」" +#~ msgid "Attribute \"%s\" repeated twice on the same <%s> element" +#~ msgstr "屬性「%s」在同一個 <%s> 元素中重複了兩次" -#: ../src/ui/theme-parser.c:3507 -msgid "" -"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" -"theme-2.xml" -msgstr "「version」屬性不能用在 metacity-theme-1.xml 或 metacity-theme-2.xml" +#~ msgid "Attribute \"%s\" is invalid on <%s> element in this context" +#~ msgstr "在此關聯選單中,屬性「%s」在 <%s> 元素中是無效的" -#: ../src/ui/theme-parser.c:3530 -#, c-format -msgid "Theme requires version %s but latest supported theme version is %d.%d" -msgstr "佈景主題需要 %s 版但是最新支援的佈景主題版本為 %d.%d" +#~ msgid "Could not parse \"%s\" as an integer" +#~ msgstr "無法以整數的方式分析“%s”" -#: ../src/ui/theme-parser.c:3562 -#, c-format -msgid "Outermost element in theme must be <metacity_theme> not <%s>" -msgstr "佈景主題中最外層的元素必須為 <metacity_theme> 而不是 <%s>" +#~ msgid "Did not understand trailing characters \"%s\" in string \"%s\"" +#~ msgstr "無法理解字串“%2$s”中的結束字元“%1$s”" -#: ../src/ui/theme-parser.c:3582 -#, c-format -msgid "" -"Element <%s> is not allowed inside a name/author/date/description element" -msgstr "元素 <%s> 不許在名稱/作者/日期/描述元素內出現" +#~ msgid "Integer %ld must be positive" +#~ msgstr "整數 %ld 必須為正數" -#: ../src/ui/theme-parser.c:3587 -#, c-format -msgid "Element <%s> is not allowed inside a <constant> element" -msgstr "<%s> 元素不可出現在 <constant> 元素內" +#~ msgid "Integer %ld is too large, current max is %d" +#~ msgstr "整數 %ld 太大,目前可接受的最大值為 %d" -#: ../src/ui/theme-parser.c:3599 -#, c-format -msgid "" -"Element <%s> is not allowed inside a distance/border/aspect_ratio element" -msgstr "<%s> 元素不可出現於 distance/border/aspect_ratio 元素之內" +#~ msgid "Could not parse \"%s\" as a floating point number" +#~ msgstr "無法以浮點小數的方式分析“%s”" -#: ../src/ui/theme-parser.c:3621 -#, c-format -msgid "Element <%s> is not allowed inside a draw operation element" -msgstr "元素 <%s> 不允許在有關繪圖操作的元素內出現" +#~ msgid "Boolean values must be \"true\" or \"false\" not \"%s\"" +#~ msgstr "布林值必須為“true”或“false”,不是“%s”" -#: ../src/ui/theme-parser.c:3631 ../src/ui/theme-parser.c:3661 -#: ../src/ui/theme-parser.c:3666 ../src/ui/theme-parser.c:3671 -#, c-format -msgid "Element <%s> is not allowed inside a <%s> element" -msgstr "<%s> 元素不可出現在 <%s> 元素內" +#~ msgid "Angle must be between 0.0 and 360.0, was %g\n" +#~ msgstr "角度必須在 0.0 至 360.0 之間,此處的值為 %g\n" -#: ../src/ui/theme-parser.c:3899 -msgid "No draw_ops provided for frame piece" -msgstr "邊框沒有提供任何 draw_ops 屬性" +#~ msgid "" +#~ "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n" +#~ msgstr "" +#~ "透明度必須在 0.0(完全透明)至 1.0(完全不透明)之間,此處的值為 %g\n" -#: ../src/ui/theme-parser.c:3914 -msgid "No draw_ops provided for button" -msgstr "按鈕沒有提供任何 draw_ops 屬性" +#~ msgid "" +#~ "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium," +#~ "large,x-large,xx-large)\n" +#~ msgstr "" +#~ "無效的標題大小“%s”(必須為 xx-small、x-small、small、medium、large、\n" +#~ "x-large、xx-large 其中一個)\n" -#: ../src/ui/theme-parser.c:3968 -#, c-format -msgid "No text is allowed inside element <%s>" -msgstr "<%s> 元素內不可出現任何文字" +#~ msgid "<%s> name \"%s\" used a second time" +#~ msgstr "<%s> 的 name 屬性“%s”用了超過一次" -#: ../src/ui/theme-parser.c:4026 ../src/ui/theme-parser.c:4038 -#: ../src/ui/theme-parser.c:4050 ../src/ui/theme-parser.c:4062 -#: ../src/ui/theme-parser.c:4074 -#, c-format -msgid "<%s> specified twice for this theme" -msgstr "<%s> 指定了這個佈景主題兩次" +#~ msgid "<%s> parent \"%s\" has not been defined" +#~ msgstr "<%s> 的主元素“%s”沒有任何定義" -#: ../src/ui/theme-parser.c:4348 -#, c-format -msgid "Failed to find a valid file for theme %s\n" -msgstr "無法佈景主題的有效檔案 %s\n" +#~ msgid "<%s> geometry \"%s\" has not been defined" +#~ msgstr "<%s> 元素的位置大小“%s”沒有任何定義" -#: ../src/ui/theme-viewer.c:99 -msgid "_Windows" -msgstr "視窗(_W)" +#~ msgid "<%s> must specify either a geometry or a parent that has a geometry" +#~ msgstr "<%s> 必須自己指定位置大小或指定有位置大小的主元素" -#: ../src/ui/theme-viewer.c:100 -msgid "_Dialog" -msgstr "對話盒(_D)" +#~ msgid "You must specify a background for an alpha value to be meaningful" +#~ msgstr "必須指定背景使得透明 ( alpha) 值的變得有意義" -#: ../src/ui/theme-viewer.c:101 -msgid "_Modal dialog" -msgstr "模態對話盒(_M)" +#~ msgid "Unknown type \"%s\" on <%s> element" +#~ msgstr "<%2$s> 元素之內出現不明的類型“%1$s”" -#: ../src/ui/theme-viewer.c:102 -msgid "_Utility" -msgstr "公用程式(_U)" +#~ msgid "Unknown style_set \"%s\" on <%s> element" +#~ msgstr "<%2$s> 元素之內出現不明的 style_set“%1$s”" -#: ../src/ui/theme-viewer.c:103 -msgid "_Splashscreen" -msgstr "啟動畫面(_S)" +#~ msgid "Window type \"%s\" has already been assigned a style set" +#~ msgstr "視窗類型“%s”已經分配了 style set" -#: ../src/ui/theme-viewer.c:104 -msgid "_Top dock" -msgstr "頂端浮動列(_T)" +#~ msgid "Element <%s> is not allowed below <%s>" +#~ msgstr "元素 <%s> 不允許在 <%s> 之下" -#: ../src/ui/theme-viewer.c:105 -msgid "_Bottom dock" -msgstr "底部浮動列(_B)" +#~ msgid "" +#~ "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio" +#~ "\" for buttons" +#~ msgstr "" +#~ "不可能同時指定按鈕的寬度/長度 (button_width/button_height) 及長寬比" +#~ "(aspect_ratio)" -#: ../src/ui/theme-viewer.c:106 -msgid "_Left dock" -msgstr "左側浮動列(_L)" +#~ msgid "Distance \"%s\" is unknown" +#~ msgstr "不明的距離“%s”" -#: ../src/ui/theme-viewer.c:107 -msgid "_Right dock" -msgstr "右側浮動列(_R)" +#~ msgid "Aspect ratio \"%s\" is unknown" +#~ msgstr "不明的長寬比“%s”" -#: ../src/ui/theme-viewer.c:108 -msgid "_All docks" -msgstr "所有浮動列(_A)" +#~ msgid "Border \"%s\" is unknown" +#~ msgstr "不明的邊框“%s”" -#: ../src/ui/theme-viewer.c:109 -msgid "Des_ktop" -msgstr "桌面(_K)" +#~ msgid "No \"start_angle\" or \"from\" attribute on element <%s>" +#~ msgstr "元素 <%s> 中沒有“start_angle”或“from”屬性" -#: ../src/ui/theme-viewer.c:115 -msgid "Open another one of these windows" -msgstr "開啟一個同樣的視窗" +#~ msgid "No \"extent_angle\" or \"to\" attribute on element <%s>" +#~ msgstr "元素 <%s> 中沒有“extent_angle”或“to”屬性" -#: ../src/ui/theme-viewer.c:117 -msgid "This is a demo button with an 'open' icon" -msgstr "這是有開啟圖示的展示用按鈕" +#~ msgid "Did not understand value \"%s\" for type of gradient" +#~ msgstr "無法將“%s”理解為漸層的樣式" -#: ../src/ui/theme-viewer.c:119 -msgid "This is a demo button with a 'quit' icon" -msgstr "這是有離開圖示的展示用按鈕" +#~ msgid "Did not understand fill type \"%s\" for <%s> element" +#~ msgstr "無法理解 <%2$s> 元素中的填充類型“%1$s”" -#: ../src/ui/theme-viewer.c:248 -msgid "This is a sample message in a sample dialog" -msgstr "這是在樣版對話視窗中的樣版訊息" +#~ msgid "Did not understand state \"%s\" for <%s> element" +#~ msgstr "無法將“%s”理解為 <%s> 元素的狀態" -#: ../src/ui/theme-viewer.c:328 -#, c-format -msgid "Fake menu item %d\n" -msgstr "假的選單項目 %d\n" +#~ msgid "Did not understand shadow \"%s\" for <%s> element" +#~ msgstr "無法將“%s”理解為 <%s> 元素的陰影" -#: ../src/ui/theme-viewer.c:363 -msgid "Border-only window" -msgstr "只有邊框的視窗" +#~ msgid "Did not understand arrow \"%s\" for <%s> element" +#~ msgstr "無法將“%s”理解為 <%s> 元素的箭頭" -#: ../src/ui/theme-viewer.c:365 -msgid "Bar" -msgstr "列" +#~ msgid "No <draw_ops> called \"%s\" has been defined" +#~ msgstr "沒有定義任何名稱為“%s”的 <draw_ops>" -#: ../src/ui/theme-viewer.c:382 -msgid "Normal Application Window" -msgstr "正常的程式視窗" +#~ msgid "Including draw_ops \"%s\" here would create a circular reference" +#~ msgstr "這裡的 draw_ops“%s”會造成循環" -#: ../src/ui/theme-viewer.c:386 -msgid "Dialog Box" -msgstr "對話盒" +#~ msgid "Unknown position \"%s\" for frame piece" +#~ msgstr "邊框組件指定了不明的位置“%s”" -#: ../src/ui/theme-viewer.c:390 -msgid "Modal Dialog Box" -msgstr "模態對話盒" +#~ msgid "Frame style already has a piece at position %s" +#~ msgstr "邊框款式已經在位置 %s 中指定了一件邊框組件" -#: ../src/ui/theme-viewer.c:394 -msgid "Utility Palette" -msgstr "公用程式控制板" +#~ msgid "No <draw_ops> with the name \"%s\" has been defined" +#~ msgstr "沒有定義任何名稱為“%s”的 <draw_ops>" -#: ../src/ui/theme-viewer.c:398 -msgid "Torn-off Menu" -msgstr "關閉選單" +#~ msgid "Unknown function \"%s\" for button" +#~ msgstr "按鈕擁有不明的功能“%s”" -#: ../src/ui/theme-viewer.c:402 -msgid "Border" -msgstr "邊框" +#~ msgid "Button function \"%s\" does not exist in this version (%d, need %d)" +#~ msgstr "按鈕功能“%s”不存在於這個 版本(%d,要求 %d)" -#: ../src/ui/theme-viewer.c:406 -msgid "Attached Modal Dialog" -msgstr "附加的模態對話盒" +#~ msgid "Unknown state \"%s\" for button" +#~ msgstr "無法理解“%s”為按鈕的狀態" -#: ../src/ui/theme-viewer.c:739 -#, c-format -msgid "Button layout test %d" -msgstr "按鈕配置測試 %d" +#~ msgid "Frame style already has a button for function %s state %s" +#~ msgstr "邊框款式已經指定了一個擁有 %s 功能及 %s 狀態的按鈕" -#: ../src/ui/theme-viewer.c:768 -#, c-format -msgid "%g milliseconds to draw one window frame" -msgstr "繪畫一個視窗需時 %g 毫秒" +#~ msgid "\"%s\" is not a valid value for focus attribute" +#~ msgstr "“%s”不是 focus 屬性的有效設定值" -#: ../src/ui/theme-viewer.c:813 -#, c-format -msgid "Usage: metacity-theme-viewer [THEMENAME]\n" -msgstr "用法: metacity-theme-viewer [佈景主題名稱]\n" +#~ msgid "\"%s\" is not a valid value for state attribute" +#~ msgstr "“%s”不是 state 屬性的有效設定值" -#: ../src/ui/theme-viewer.c:820 -#, c-format -msgid "Error loading theme: %s\n" -msgstr "載入佈景主題失敗 %s\n" +#~ msgid "A style called \"%s\" has not been defined" +#~ msgstr "沒有定義任何稱為“%s”的款式" -#: ../src/ui/theme-viewer.c:826 -#, c-format -msgid "Loaded theme \"%s\" in %g seconds\n" -msgstr "載入佈景主題 “%s” 需時 %g 秒\n" +#~ msgid "\"%s\" is not a valid value for resize attribute" +#~ msgstr "“%s”不是 resize 屬性的有效設定值" -#: ../src/ui/theme-viewer.c:870 -msgid "Normal Title Font" -msgstr "正常標題列字型" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized/shaded " +#~ "states" +#~ msgstr "元素 <%s> 不應在最大化或捲起的狀態中指定“resize”屬性" -#: ../src/ui/theme-viewer.c:876 -msgid "Small Title Font" -msgstr "小標題列字型" +#~ msgid "" +#~ "Should not have \"resize\" attribute on <%s> element for maximized states" +#~ msgstr "不應在元素 <%s> 最大化的狀態中指定“resize”屬性" -#: ../src/ui/theme-viewer.c:882 -msgid "Large Title Font" -msgstr "大標題列字型" +#~ msgid "Style has already been specified for state %s resize %s focus %s" +#~ msgstr "當 state=%s resize=%s focus=%s 時,樣式早已經被指定了" -#: ../src/ui/theme-viewer.c:887 -msgid "Button Layouts" -msgstr "按鈕配置" +#~ msgid "Style has already been specified for state %s focus %s" +#~ msgstr "當 state=%s focus=%s 時,樣式早已經被指定了" -#: ../src/ui/theme-viewer.c:892 -msgid "Benchmark" -msgstr "速度測試" +#~ msgid "" +#~ "Can't have a two draw_ops for a <piece> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "一個 <piece> 元素不可同時使用兩個 draw_ops (佈景主題同時指定了一個 " +#~ "draw_ops 屬性及一個 <draw_ops> 元素,或是指定了兩個元素)" -#: ../src/ui/theme-viewer.c:944 -msgid "Window Title Goes Here" -msgstr "這裡是視窗標題" +#~ msgid "" +#~ "Can't have a two draw_ops for a <button> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "一個 <button> 元素不可同時使用兩個 draw_ops (佈景主題同時指定了一個 " +#~ "draw_ops 屬性及一個 <draw_ops> 元素,或是指定了兩個元素)" -#: ../src/ui/theme-viewer.c:1047 -#, c-format -msgid "" -"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " -"seconds wall clock time including X server resources (%g milliseconds per " -"frame)\n" -msgstr "" -"繪畫 %d 幀需時:\n" -"在客戶端是 %g 秒(每幀 %g 毫秒)\n" -"包括 X 伺服器資源的實際消耗時間是 %g 秒(每幀 %g 毫秒)\n" +#~ msgid "" +#~ "Can't have a two draw_ops for a <menu_icon> element (theme specified a " +#~ "draw_ops attribute and also a <draw_ops> element, or specified two " +#~ "elements)" +#~ msgstr "" +#~ "一個 <menu_icon> 元素不可同時使用兩個 draw_ops (佈景主題同時指定了一個 " +#~ "draw_ops 屬性及一個 <draw_ops> 元素,或是指定了兩個元素)" -#: ../src/ui/theme-viewer.c:1266 -msgid "position expression test returned TRUE but set error" -msgstr "位置表現測試返回值是「正確」,但有 set error" +#~ msgid "Bad version specification '%s'" +#~ msgstr "不正確的版本規格「%s」" -#: ../src/ui/theme-viewer.c:1268 -msgid "position expression test returned FALSE but didn't set error" -msgstr "位置表現測試返回值是「錯誤」,但沒有 set error" +#~ msgid "" +#~ "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-" +#~ "theme-2.xml" +#~ msgstr "" +#~ "「version」屬性不能用在 metacity-theme-1.xml 或 metacity-theme-2.xml" -#: ../src/ui/theme-viewer.c:1272 -msgid "Error was expected but none given" -msgstr "預期會發生錯誤,但結果並沒錯誤發生" +#~ msgid "" +#~ "Theme requires version %s but latest supported theme version is %d.%d" +#~ msgstr "佈景主題需要 %s 版但是最新支援的佈景主題版本為 %d.%d" -#: ../src/ui/theme-viewer.c:1274 -#, c-format -msgid "Error %d was expected but %d given" -msgstr "預期會發生錯誤 %d ,但結果卻出現 %d" +#~ msgid "Outermost element in theme must be <metacity_theme> not <%s>" +#~ msgstr "佈景主題中最外層的元素必須為 <metacity_theme> 而不是 <%s>" -#: ../src/ui/theme-viewer.c:1280 -#, c-format -msgid "Error not expected but one was returned: %s" -msgstr "預期不會發生錯誤,但結果返回了一個:%s" +#~ msgid "" +#~ "Element <%s> is not allowed inside a name/author/date/description element" +#~ msgstr "元素 <%s> 不許在名稱/作者/日期/描述元素內出現" -#: ../src/ui/theme-viewer.c:1284 -#, c-format -msgid "x value was %d, %d was expected" -msgstr "x 的數值是 %d,%d是預期中的數值" +#~ msgid "Element <%s> is not allowed inside a <constant> element" +#~ msgstr "<%s> 元素不可出現在 <constant> 元素內" -#: ../src/ui/theme-viewer.c:1287 -#, c-format -msgid "y value was %d, %d was expected" -msgstr "y 的數值是 %d,%d是預期中的數值" +#~ msgid "" +#~ "Element <%s> is not allowed inside a distance/border/aspect_ratio element" +#~ msgstr "<%s> 元素不可出現於 distance/border/aspect_ratio 元素之內" -#: ../src/ui/theme-viewer.c:1352 -#, c-format -msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" -msgstr "分析 %d 座標表現需時 %g 秒(平均 %g 秒)\n" +#~ msgid "Element <%s> is not allowed inside a draw operation element" +#~ msgstr "元素 <%s> 不允許在有關繪圖操作的元素內出現" + +#~ msgid "Element <%s> is not allowed inside a <%s> element" +#~ msgstr "<%s> 元素不可出現在 <%s> 元素內" -#~ msgid "Close Window" -#~ msgstr "關閉視窗" +#~ msgid "No draw_ops provided for frame piece" +#~ msgstr "邊框沒有提供任何 draw_ops 屬性" -#~ msgid "Window Menu" -#~ msgstr "視窗選單" +#~ msgid "No draw_ops provided for button" +#~ msgstr "按鈕沒有提供任何 draw_ops 屬性" -#~ msgid "Minimize Window" -#~ msgstr "視窗最小化" +#~ msgid "No text is allowed inside element <%s>" +#~ msgstr "<%s> 元素內不可出現任何文字" -#~ msgid "Maximize Window" -#~ msgstr "視窗最大化" +#~ msgid "<%s> specified twice for this theme" +#~ msgstr "<%s> 指定了這個佈景主題兩次" -#~ msgid "Restore Window" -#~ msgstr "還原視窗" +#~ msgid "Failed to find a valid file for theme %s\n" +#~ msgstr "無法佈景主題的有效檔案 %s\n" -#~ msgid "Roll Up Window" -#~ msgstr "捲起視窗(_U)" +#~ msgid "Unknown window information request: %d" +#~ msgstr "未知的視窗資訊要求:%d" -#~ msgid "Unroll Window" -#~ msgstr "放下視窗" +#~ msgid "Missing %s extension required for compositing" +#~ msgstr "遺失複合視窗管理所需的 %s 延伸功能" -#~ msgid "Keep Window On Top" -#~ msgstr "視窗保留在最上層" +#~ msgid "" +#~ "Some other program is already using the key %s with modifiers %x as a " +#~ "binding\n" +#~ msgstr "其它程式已經使用了按鍵 %s 加上特殊按鍵 %x 作為按鍵組合\n" + +#~ msgid "\"%s\" is not a valid accelerator\n" +#~ msgstr "「%s」不是有效的捷徑鍵\n" + +#~ msgid "" +#~ "Workarounds for broken applications disabled. Some applications may not " +#~ "behave properly.\n" +#~ msgstr "關閉了對不合規格的程式的支援。某些程式可能無法正常運作。\n" + +#~ msgid "Could not parse font description \"%s\" from GSettings key %s\n" +#~ msgstr "無法從 GSettings 設定鍵 %2$s 分析字型描述文字「%1$s」\n" -#~ msgid "Remove Window From Top" -#~ msgstr "視窗移離最上層" +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for mouse " +#~ "button modifier\n" +#~ msgstr "設定資料庫中的“%s”設定值不是有效的滑鼠按鈕修改功能鍵\n" + +#~ msgid "" +#~ "\"%s\" found in configuration database is not a valid value for " +#~ "keybinding \"%s\"\n" +#~ msgstr "設定資料庫中的“%s”不是按鍵組合“%s”的有效設定值\n" diff --git a/src/Makefile.am b/src/Makefile.am deleted file mode 100644 index b75b1879f..000000000 --- a/src/Makefile.am +++ /dev/null @@ -1,391 +0,0 @@ -# Flag build for parallelism; see https://savannah.gnu.org/patch/?6905 -.AUTOPARALLEL: - -lib_LTLIBRARIES = libmuffin.la - -SUBDIRS=wm-tester tools - -NULL = - -AM_CPPFLAGS= \ - -DCLUTTER_ENABLE_COMPOSITOR_API \ - -DCLUTTER_ENABLE_EXPERIMENTAL_API \ - -DCOGL_ENABLE_EXPERIMENTAL_API \ - -DCOGL_ENABLE_EXPERIMENTAL_2_0_API \ - -DCOGL_ENABLE_MUFFIN_API \ - $(WARN_CFLAGS) \ - $(MUFFIN_CFLAGS) \ - -I$(srcdir) \ - -I$(srcdir)/core \ - -I$(srcdir)/ui \ - -I$(srcdir)/compositor \ - -I$(top_srcdir)/cogl \ - -I$(top_srcdir)/cogl/cogl \ - -I$(top_srcdir)/cogl/cogl/winsys \ - -I$(top_builddir)/cogl/cogl \ - -I$(top_builddir)/cogl \ - -I$(top_srcdir)/clutter \ - -I$(top_srcdir)/clutter/clutter \ - -I$(top_builddir)/clutter \ - -I$(top_builddir)/clutter/clutter \ - -DMUFFIN_LIBEXECDIR=\"$(libexecdir)\" \ - -DHOST_ALIAS=\"@HOST_ALIAS@\" \ - -DMUFFIN_LOCALEDIR=\"$(prefix)/@DATADIRNAME@/locale\" \ - -DMUFFIN_PKGDATADIR=\"$(pkgdatadir)\" \ - -DMUFFIN_DATADIR=\"$(datadir)\" \ - -DG_LOG_DOMAIN=\"muffin\" \ - -DSN_API_NOT_YET_FROZEN=1 \ - -DMUFFIN_MAJOR_VERSION=$(MUFFIN_MAJOR_VERSION) \ - -DMUFFIN_MINOR_VERSION=$(MUFFIN_MINOR_VERSION) \ - -DMUFFIN_MICRO_VERSION=$(MUFFIN_MICRO_VERSION) \ - -DMUFFIN_PLUGIN_API_VERSION=$(MUFFIN_PLUGIN_API_VERSION) \ - -DMUFFIN_PKGLIBDIR=\"$(pkglibdir)\" \ - -DMUFFIN_PLUGIN_DIR=\"@MUFFIN_PLUGIN_DIR@\" \ - -DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\" - -muffin_built_sources = \ - muffin-enum-types.h \ - muffin-enum-types.c - -libmuffin_la_SOURCES = \ - core/async-getprop.c \ - core/async-getprop.h \ - core/bell.c \ - core/bell.h \ - core/boxes.c \ - core/boxes-private.h \ - meta/boxes.h \ - compositor/clutter-utils.c \ - compositor/clutter-utils.h \ - compositor/cogl-utils.c \ - compositor/cogl-utils.h \ - compositor/compositor.c \ - compositor/compositor-private.h \ - compositor/meta-background.c \ - compositor/meta-background.h \ - compositor/meta-background-actor.c \ - compositor/meta-background-actor-private.h \ - compositor/meta-module.c \ - compositor/meta-module.h \ - compositor/meta-plugin.c \ - compositor/meta-plugin-manager.c \ - compositor/meta-plugin-manager.h \ - compositor/meta-shadow-factory.c \ - compositor/meta-shadow-factory-private.h \ - compositor/meta-shaped-texture.c \ - compositor/meta-shaped-texture-private.h \ - compositor/meta-sync-ring.c \ - compositor/meta-sync-ring.h \ - compositor/meta-texture-rectangle.c \ - compositor/meta-texture-rectangle.h \ - compositor/meta-texture-tower.c \ - compositor/meta-texture-tower.h \ - compositor/meta-window-actor.c \ - compositor/meta-window-actor-private.h \ - compositor/meta-window-group.c \ - compositor/meta-window-group.h \ - compositor/meta-window-shape.c \ - compositor/meta-window-shape.h \ - compositor/region-utils.c \ - compositor/region-utils.h \ - meta/compositor.h \ - meta/meta-background-actor.h \ - meta/meta-plugin.h \ - meta/meta-shadow-factory.h \ - meta/meta-window-actor.h \ - meta/compositor-muffin.h \ - core/above-tab-keycode.c \ - core/constraints.c \ - core/constraints.h \ - core/core.c \ - core/delete.c \ - core/display.c \ - core/display-private.h \ - meta/display.h \ - ui/draw-workspace.c \ - ui/draw-workspace.h \ - core/edge-resistance.c \ - core/edge-resistance.h \ - core/errors.c \ - meta/errors.h \ - core/eventqueue.c \ - core/eventqueue.h \ - core/frame.c \ - core/frame.h \ - ui/gradient.c \ - meta/gradient.h \ - core/group-private.h \ - core/group-props.c \ - core/group-props.h \ - core/group.c \ - meta/group.h \ - core/iconcache.c \ - core/iconcache.h \ - core/keybindings.c \ - core/keybindings-private.h \ - core/main.c \ - core/muffin-Xatomtype.h \ - core/place.c \ - core/place.h \ - core/prefs.c \ - meta/prefs.h \ - core/screen.c \ - core/screen-private.h \ - meta/screen.h \ - meta/types.h \ - core/session.c \ - core/session.h \ - core/restart.c \ - core/stack.c \ - core/stack.h \ - core/stack-tracker.c \ - core/stack-tracker.h \ - core/util.c \ - meta/util.h \ - meta/util-private.h \ - core/window-props.c \ - core/window-props.h \ - core/window.c \ - core/window-private.h \ - meta/window.h \ - core/workspace.c \ - core/workspace-private.h \ - core/xprops.c \ - core/xprops.h \ - meta/common.h \ - core/core.h \ - ui/ui.h \ - inlinepixbufs.h \ - ui/frames.c \ - ui/frames.h \ - ui/menu.c \ - ui/menu.h \ - ui/metaaccellabel.c \ - ui/metaaccellabel.h \ - ui/resizepopup.c \ - ui/resizepopup.h \ - ui/theme-parser.c \ - ui/theme.c \ - meta/theme.h \ - ui/theme-private.h \ - ui/ui.c \ - meta/preview-widget.h \ - ui/preview-widget.c \ - $(muffin_built_sources) \ - $(NULL) - -libmuffin_la_LDFLAGS = $(WARN_LDFLAGS) -no-undefined -export-symbols-regex "^(meta|ag)_.*" -libmuffin_la_LIBADD = \ - $(MUFFIN_LIBS) \ - $(top_builddir)/clutter/clutter/libmuffin-clutter-$(MUFFIN_PLUGIN_API_VERSION).la \ - $(top_builddir)/cogl/cogl/libmuffin-cogl-$(MUFFIN_PLUGIN_API_VERSION).la \ - $(top_builddir)/cogl/cogl-pango/libmuffin-cogl-pango-$(MUFFIN_PLUGIN_API_VERSION).la \ - $(top_builddir)/cogl/cogl-path/libmuffin-cogl-path-$(MUFFIN_PLUGIN_API_VERSION).la \ - -lm \ - -lglib-2.0 \ - $(NULL) - -# Headers installed for plugins; introspected information will -# be extracted into Muffin-<version>.gir -libmuffininclude_base_headers = \ - meta/boxes.h \ - meta/common.h \ - meta/compositor-muffin.h \ - meta/compositor.h \ - meta/display.h \ - meta/errors.h \ - meta/gradient.h \ - meta/group.h \ - meta/keybindings.h \ - meta/main.h \ - meta/meta-background-actor.h \ - meta/meta-plugin.h \ - meta/meta-shaped-texture.h \ - meta/meta-shadow-factory.h \ - meta/meta-window-actor.h \ - meta/prefs.h \ - meta/screen.h \ - meta/theme.h \ - meta/types.h \ - meta/util.h \ - meta/window.h \ - meta/workspace.h - -# Excluded from scanning for introspection but installed -# atomnames.h: macros cause problems for scanning process -libmuffininclude_extra_headers = \ - meta/preview-widget.h \ - meta/atomnames.h - -libmuffinincludedir = $(includedir)/muffin/meta - -libmuffininclude_HEADERS = \ - $(libmuffininclude_base_headers) \ - $(libmuffininclude_extra_headers) - -muffin_theme_viewer_SOURCES= \ - ui/theme-viewer.c - -bin_PROGRAMS=muffin muffin-theme-viewer - -muffin_SOURCES = core/muffin.c -muffin_LDADD = $(MUFFIN_LIBS) libmuffin.la - -libexec_PROGRAMS = muffin-restart-helper -muffin_restart_helper_SOURCES = core/restart-helper.c -muffin_restart_helper_LDADD = $(MUFFIN_LIBS) - -if HAVE_INTROSPECTION -include $(INTROSPECTION_MAKEFILE) - -# Since we don't make any guarantees about stability and we don't support -# parallel install, there's no real reason to change directories, filenames, -# etc. as we change the Muffin tarball version. -# -# Change the api_version to a muffin specific number since setting it to -# 3.0 causes major dependency issues with muffin on distributions which -# auto generate typelib dependencies in RPMS -api_version = Muffin.0 -#api_version = 3.0 - -# These files are in package-private directories, even though they may be used -# by plugins. If you're writing a plugin, use g-ir-compiler --add-include-path -# and g-ir-compiler --includedir. -girdir = $(pkglibdir) -gir_DATA = Meta-$(api_version).gir - -typelibdir = $(pkglibdir) -typelib_DATA = Meta-$(api_version).typelib - -INTROSPECTION_GIRS = Meta-$(api_version).gir -INTROSPECTION_SCANNER_ARGS = \ - --add-include-path=$(top_builddir)/clutter/clutter \ - --add-include-path=$(top_builddir)/cogl/cogl \ - --add-include-path=$(top_builddir)/cogl/cogl-pango \ - --add-include-path=$(top_builddir)/cogl/cogl-path \ - $(NULL) -INTROSPECTION_COMPILER_ARGS = \ - --includedir=$(top_builddir)/clutter/clutter \ - --includedir=$(top_builddir)/cogl/cogl \ - --includedir=$(top_builddir)/cogl/cogl-pango \ - --includedir=$(top_builddir)/cogl/cogl-path \ - $(NULL) -INTROSPECTION_SCANNER_ENV = \ - PKG_CONFIG_PATH=$(top_builddir)/clutter/clutter/:$(top_builddir)/cogl/cogl/:$(top_builddir)/cogl/cogl-pango/:$(top_builddir)/cogl/cogl-path/:$${PKG_CONFIG_PATH} - -Meta-$(api_version).gir: libmuffin.la -@META_GIR@_INCLUDES = GObject-2.0 CDesktopEnums-3.0 Gdk-3.0 Gtk-3.0 Cogl-$(MUFFIN_PLUGIN_API_VERSION) Clutter-$(MUFFIN_PLUGIN_API_VERSION) xlib-2.0 xfixes-4.0 -@META_GIR@_PACKAGES = gtk+-3.0 -@META_GIR@_CFLAGS = $(AM_CPPFLAGS) -@META_GIR@_LIBS = \ - libmuffin.la \ - $(top_builddir)/clutter/clutter/libmuffin-clutter-@MUFFIN_PLUGIN_API_VERSION@.la \ - $(top_builddir)/cogl/cogl/libmuffin-cogl-@MUFFIN_PLUGIN_API_VERSION@.la \ - $(top_builddir)/cogl/cogl-pango/libmuffin-cogl-pango-@MUFFIN_PLUGIN_API_VERSION@.la \ - $(top_builddir)/cogl/cogl-path/libmuffin-cogl-path-@MUFFIN_PLUGIN_API_VERSION@.la -@META_GIR@_FILES = \ - muffin-enum-types.h \ - $(libmuffininclude_base_headers) \ - $(filter %.c,$(libmuffin_la_SOURCES)) -@META_GIR@_SCANNERFLAGS = $(WARN_SCANNERFLAGS) --warn-all --warn-error --identifier-prefix=Meta - -endif - -muffin_theme_viewer_LDADD= $(MUFFIN_LIBS) libmuffin.la - -testboxes_SOURCES = core/testboxes.c core/boxes.c core/util.c -testgradient_SOURCES = ui/testgradient.c -testasyncgetprop_SOURCES = core/testasyncgetprop.c core/async-getprop.c - -# NO-OP: work around the fact that source code tested by the programs are -# compiled for library -testasyncgetprop_CFLAGS = $(WARN_CFLAGS) $(AM_CFLAGS) -testboxes_CFLAGS = $(WARN_CFLAGS) $(AM_CFLAGS) - -noinst_PROGRAMS=testboxes testgradient testasyncgetprop - -testboxes_LDADD = $(MUFFIN_LIBS) $(top_builddir)/clutter/clutter/libmuffin-clutter-$(MUFFIN_PLUGIN_API_VERSION).la -testgradient_LDADD = $(MUFFIN_LIBS) libmuffin.la -testasyncgetprop_LDADD = $(MUFFIN_LIBS) - - -@INTLTOOL_DESKTOP_RULE@ - -desktopfilesdir=$(datadir)/applications -desktopfiles_in_files=muffin.desktop.in -desktopfiles_files=$(desktopfiles_in_files:.desktop.in=.desktop) -desktopfiles_DATA = $(desktopfiles_files) - -gsettings_SCHEMAS = org.cinnamon.muffin.gschema.xml -@INTLTOOL_XML_NOMERGE_RULE@ -@GSETTINGS_RULES@ - -IMAGES=stock_maximize.png stock_minimize.png stock_delete.png -VARIABLES=stock_maximize_data $(srcdir)/stock_maximize.png \ - stock_minimize_data $(srcdir)/stock_minimize.png \ - stock_delete_data $(srcdir)/stock_delete.png - -BUILT_SOURCES = inlinepixbufs.h -CLEANFILES = \ - inlinepixbufs.h \ - muffin.desktop \ - org.cinnamon.muffin.gschema.xml \ - $(xml_DATA) \ - $(muffin_built_sources) \ - $(typelib_DATA) \ - $(gir_DATA) - -inlinepixbufs.h: $(IMAGES) - $(GDK_PIXBUF_CSOURCE) --raw --build-list $(VARIABLES) >$(srcdir)/inlinepixbufs.h - -pkgconfigdir = $(libdir)/pkgconfig - -pkgconfig_DATA = libmuffin.pc muffin-plugins.pc - -EXTRA_DIST=$(desktopfiles_files) \ - $(IMAGES) \ - $(desktopfiles_in_files) \ - $(xml_in_files) \ - org.cinnamon.muffin.gschema.xml.in \ - libmuffin.pc.in \ - muffin-plugins.pc.in \ - muffin-enum-types.h.in \ - muffin-enum-types.c.in - -BUILT_SOURCES += $(muffin_built_sources) -MUFFIN_STAMP_FILES = stamp-muffin-enum-types.h -CLEANFILES += $(MUFFIN_STAMP_FILES) - -muffin-enum-types.h: stamp-muffin-enum-types.h Makefile - @true -stamp-muffin-enum-types.h: $(libmuffininclude_base_headers) muffin-enum-types.h.in - $(AM_V_GEN) ( cd $(srcdir) && \ - $(GLIB_MKENUMS) \ - --template muffin-enum-types.h.in \ - $(libmuffininclude_base_headers) ) >> xgen-teth && \ - (cmp -s xgen-teth muffin-enum-types.h || cp xgen-teth muffin-enum-types.h) && \ - rm -f xgen-teth && \ - echo timestamp > $(@F) - -muffin-enum-types.c: stamp-muffin-enum-types.h muffin-enum-types.c.in - $(AM_V_GEN) ( cd $(srcdir) && \ - $(GLIB_MKENUMS) \ - --template muffin-enum-types.c.in \ - $(libmuffininclude_base_headers) ) >> xgen-tetc && \ - cp xgen-tetc muffin-enum-types.c && \ - rm -f xgen-tetc - -compat_libs="clutter cogl cogl-pango cogl-path" - -install-exec-local: - test -z "$(pkglibdir)" || $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" - for lib in `echo $(compat_libs)`; do \ - (cd $(DESTDIR)$(libdir) && \ - rm -f libmuffin-$$lib-0.so; \ - ) ; \ - (cd $(DESTDIR)$(libdir) && \ - { ln -s -f muffin/libmuffin-$$lib-0.so libmuffin-$$lib-0.so || \ - { rm -f libmuffin-$$lib-0.so && ln -s muffin/libmuffin-$$lib-0.so libmuffin-$$lib-0.so; }; \ - } \ - ) ; \ - done diff --git a/src/backends/edid-parse.c b/src/backends/edid-parse.c new file mode 100644 index 000000000..a7b9fd225 --- /dev/null +++ b/src/backends/edid-parse.c @@ -0,0 +1,542 @@ +/* + * Copyright 2007 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* Author: Soren Sandmann <sandmann@redhat.com> */ + +#include "config.h" + +#include <stdlib.h> +#include <string.h> +#include <math.h> +#include <glib.h> + +#include "backends/edid.h" + +static int +get_bit (int in, int bit) +{ + return (in & (1 << bit)) >> bit; +} + +static int +get_bits (int in, int begin, int end) +{ + int mask = (1 << (end - begin + 1)) - 1; + + return (in >> begin) & mask; +} + +static int +decode_header (const uchar *edid) +{ + if (memcmp (edid, "\x00\xff\xff\xff\xff\xff\xff\x00", 8) == 0) + return TRUE; + return FALSE; +} + +static int +decode_vendor_and_product_identification (const uchar *edid, MonitorInfo *info) +{ + int is_model_year; + + /* Manufacturer Code */ + info->manufacturer_code[0] = get_bits (edid[0x08], 2, 6); + info->manufacturer_code[1] = get_bits (edid[0x08], 0, 1) << 3; + info->manufacturer_code[1] |= get_bits (edid[0x09], 5, 7); + info->manufacturer_code[2] = get_bits (edid[0x09], 0, 4); + info->manufacturer_code[3] = '\0'; + + info->manufacturer_code[0] += 'A' - 1; + info->manufacturer_code[1] += 'A' - 1; + info->manufacturer_code[2] += 'A' - 1; + + /* Product Code */ + info->product_code = edid[0x0b] << 8 | edid[0x0a]; + + /* Serial Number */ + info->serial_number = + edid[0x0c] | edid[0x0d] << 8 | edid[0x0e] << 16 | edid[0x0f] << 24; + + /* Week and Year */ + is_model_year = FALSE; + switch (edid[0x10]) + { + case 0x00: + info->production_week = -1; + break; + + case 0xff: + info->production_week = -1; + is_model_year = TRUE; + break; + + default: + info->production_week = edid[0x10]; + break; + } + + if (is_model_year) + { + info->production_year = -1; + info->model_year = 1990 + edid[0x11]; + } + else + { + info->production_year = 1990 + edid[0x11]; + info->model_year = -1; + } + + return TRUE; +} + +static int +decode_edid_version (const uchar *edid, MonitorInfo *info) +{ + info->major_version = edid[0x12]; + info->minor_version = edid[0x13]; + + return TRUE; +} + +static int +decode_display_parameters (const uchar *edid, MonitorInfo *info) +{ + /* Digital vs Analog */ + info->is_digital = get_bit (edid[0x14], 7); + + if (info->is_digital) + { + int bits; + + static const int bit_depth[8] = + { + -1, 6, 8, 10, 12, 14, 16, -1 + }; + + static const Interface interfaces[6] = + { + UNDEFINED, DVI, HDMI_A, HDMI_B, MDDI, DISPLAY_PORT + }; + + bits = get_bits (edid[0x14], 4, 6); + info->connector.digital.bits_per_primary = bit_depth[bits]; + + bits = get_bits (edid[0x14], 0, 3); + + if (bits <= 5) + info->connector.digital.interface = interfaces[bits]; + else + info->connector.digital.interface = UNDEFINED; + } + else + { + int bits = get_bits (edid[0x14], 5, 6); + + static const double levels[][3] = + { + { 0.7, 0.3, 1.0 }, + { 0.714, 0.286, 1.0 }, + { 1.0, 0.4, 1.4 }, + { 0.7, 0.0, 0.7 }, + }; + + info->connector.analog.video_signal_level = levels[bits][0]; + info->connector.analog.sync_signal_level = levels[bits][1]; + info->connector.analog.total_signal_level = levels[bits][2]; + + info->connector.analog.blank_to_black = get_bit (edid[0x14], 4); + + info->connector.analog.separate_hv_sync = get_bit (edid[0x14], 3); + info->connector.analog.composite_sync_on_h = get_bit (edid[0x14], 2); + info->connector.analog.composite_sync_on_green = get_bit (edid[0x14], 1); + + info->connector.analog.serration_on_vsync = get_bit (edid[0x14], 0); + } + + /* Screen Size / Aspect Ratio */ + if (edid[0x15] == 0 && edid[0x16] == 0) + { + info->width_mm = -1; + info->height_mm = -1; + info->aspect_ratio = -1.0; + } + else if (edid[0x16] == 0) + { + info->width_mm = -1; + info->height_mm = -1; + info->aspect_ratio = 100.0 / (edid[0x15] + 99); + } + else if (edid[0x15] == 0) + { + info->width_mm = -1; + info->height_mm = -1; + info->aspect_ratio = 100.0 / (edid[0x16] + 99); + info->aspect_ratio = 1/info->aspect_ratio; /* portrait */ + } + else + { + info->width_mm = 10 * edid[0x15]; + info->height_mm = 10 * edid[0x16]; + } + + /* Gamma */ + if (edid[0x17] == 0xFF) + info->gamma = -1.0; + else + info->gamma = (edid[0x17] + 100.0) / 100.0; + + /* Features */ + info->standby = get_bit (edid[0x18], 7); + info->suspend = get_bit (edid[0x18], 6); + info->active_off = get_bit (edid[0x18], 5); + + if (info->is_digital) + { + info->connector.digital.rgb444 = TRUE; + if (get_bit (edid[0x18], 3)) + info->connector.digital.ycrcb444 = 1; + if (get_bit (edid[0x18], 4)) + info->connector.digital.ycrcb422 = 1; + } + else + { + int bits = get_bits (edid[0x18], 3, 4); + ColorType color_type[4] = + { + MONOCHROME, RGB, OTHER_COLOR, UNDEFINED_COLOR + }; + + info->connector.analog.color_type = color_type[bits]; + } + + info->srgb_is_standard = get_bit (edid[0x18], 2); + + /* In 1.3 this is called "has preferred timing" */ + info->preferred_timing_includes_native = get_bit (edid[0x18], 1); + + /* FIXME: In 1.3 this indicates whether the monitor accepts GTF */ + info->continuous_frequency = get_bit (edid[0x18], 0); + return TRUE; +} + +static double +decode_fraction (int high, int low) +{ + double result = 0.0; + int i; + + high = (high << 2) | low; + + for (i = 0; i < 10; ++i) + result += get_bit (high, i) * pow (2, i - 10); + + return result; +} + +static int +decode_color_characteristics (const uchar *edid, MonitorInfo *info) +{ + info->red_x = decode_fraction (edid[0x1b], get_bits (edid[0x19], 6, 7)); + info->red_y = decode_fraction (edid[0x1c], get_bits (edid[0x19], 5, 4)); + info->green_x = decode_fraction (edid[0x1d], get_bits (edid[0x19], 2, 3)); + info->green_y = decode_fraction (edid[0x1e], get_bits (edid[0x19], 0, 1)); + info->blue_x = decode_fraction (edid[0x1f], get_bits (edid[0x1a], 6, 7)); + info->blue_y = decode_fraction (edid[0x20], get_bits (edid[0x1a], 4, 5)); + info->white_x = decode_fraction (edid[0x21], get_bits (edid[0x1a], 2, 3)); + info->white_y = decode_fraction (edid[0x22], get_bits (edid[0x1a], 0, 1)); + + return TRUE; +} + +static int +decode_established_timings (const uchar *edid, MonitorInfo *info) +{ + static const Timing established[][8] = + { + { + { 800, 600, 60 }, + { 800, 600, 56 }, + { 640, 480, 75 }, + { 640, 480, 72 }, + { 640, 480, 67 }, + { 640, 480, 60 }, + { 720, 400, 88 }, + { 720, 400, 70 } + }, + { + { 1280, 1024, 75 }, + { 1024, 768, 75 }, + { 1024, 768, 70 }, + { 1024, 768, 60 }, + { 1024, 768, 87 }, + { 832, 624, 75 }, + { 800, 600, 75 }, + { 800, 600, 72 } + }, + { + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 1152, 870, 75 } + }, + }; + + int i, j, idx; + + idx = 0; + for (i = 0; i < 3; ++i) + { + for (j = 0; j < 8; ++j) + { + int byte = edid[0x23 + i]; + + if (get_bit (byte, j) && established[i][j].frequency != 0) + info->established[idx++] = established[i][j]; + } + } + return TRUE; +} + +static int +decode_standard_timings (const uchar *edid, MonitorInfo *info) +{ + int i; + + for (i = 0; i < 8; i++) + { + int first = edid[0x26 + 2 * i]; + int second = edid[0x27 + 2 * i]; + + if (first != 0x01 && second != 0x01) + { + int w = 8 * (first + 31); + int h = 0; + + switch (get_bits (second, 6, 7)) + { + case 0x00: h = (w / 16) * 10; break; + case 0x01: h = (w / 4) * 3; break; + case 0x02: h = (w / 5) * 4; break; + case 0x03: h = (w / 16) * 9; break; + } + + info->standard[i].width = w; + info->standard[i].height = h; + info->standard[i].frequency = get_bits (second, 0, 5) + 60; + } + } + + return TRUE; +} + +static void +decode_lf_string (const uchar *s, int n_chars, char *result) +{ + int i; + for (i = 0; i < n_chars; ++i) + { + if (s[i] == 0x0a) + { + *result++ = '\0'; + break; + } + else if (s[i] == 0x00) + { + /* Convert embedded 0's to spaces */ + *result++ = ' '; + } + else + { + *result++ = s[i]; + } + } +} + +static void +decode_display_descriptor (const uchar *desc, + MonitorInfo *info) +{ + switch (desc[0x03]) + { + case 0xFC: + decode_lf_string (desc + 5, 13, info->dsc_product_name); + break; + case 0xFF: + decode_lf_string (desc + 5, 13, info->dsc_serial_number); + break; + case 0xFE: + decode_lf_string (desc + 5, 13, info->dsc_string); + break; + case 0xFD: + /* Range Limits */ + break; + case 0xFB: + /* Color Point */ + break; + case 0xFA: + /* Timing Identifications */ + break; + case 0xF9: + /* Color Management */ + break; + case 0xF8: + /* Timing Codes */ + break; + case 0xF7: + /* Established Timings */ + break; + case 0x10: + break; + } +} + +static void +decode_detailed_timing (const uchar *timing, + DetailedTiming *detailed) +{ + int bits; + StereoType stereo[] = + { + NO_STEREO, NO_STEREO, FIELD_RIGHT, FIELD_LEFT, + TWO_WAY_RIGHT_ON_EVEN, TWO_WAY_LEFT_ON_EVEN, + FOUR_WAY_INTERLEAVED, SIDE_BY_SIDE + }; + + detailed->pixel_clock = (timing[0x00] | timing[0x01] << 8) * 10000; + detailed->h_addr = timing[0x02] | ((timing[0x04] & 0xf0) << 4); + detailed->h_blank = timing[0x03] | ((timing[0x04] & 0x0f) << 8); + detailed->v_addr = timing[0x05] | ((timing[0x07] & 0xf0) << 4); + detailed->v_blank = timing[0x06] | ((timing[0x07] & 0x0f) << 8); + detailed->h_front_porch = timing[0x08] | get_bits (timing[0x0b], 6, 7) << 8; + detailed->h_sync = timing[0x09] | get_bits (timing[0x0b], 4, 5) << 8; + detailed->v_front_porch = + get_bits (timing[0x0a], 4, 7) | get_bits (timing[0x0b], 2, 3) << 4; + detailed->v_sync = + get_bits (timing[0x0a], 0, 3) | get_bits (timing[0x0b], 0, 1) << 4; + detailed->width_mm = timing[0x0c] | get_bits (timing[0x0e], 4, 7) << 8; + detailed->height_mm = timing[0x0d] | get_bits (timing[0x0e], 0, 3) << 8; + detailed->right_border = timing[0x0f]; + detailed->top_border = timing[0x10]; + + detailed->interlaced = get_bit (timing[0x11], 7); + + /* Stereo */ + bits = get_bits (timing[0x11], 5, 6) << 1 | get_bit (timing[0x11], 0); + detailed->stereo = stereo[bits]; + + /* Sync */ + bits = timing[0x11]; + + detailed->digital_sync = get_bit (bits, 4); + if (detailed->digital_sync) + { + detailed->connector.digital.composite = !get_bit (bits, 3); + + if (detailed->connector.digital.composite) + { + detailed->connector.digital.serrations = get_bit (bits, 2); + detailed->connector.digital.negative_vsync = FALSE; + } + else + { + detailed->connector.digital.serrations = FALSE; + detailed->connector.digital.negative_vsync = !get_bit (bits, 2); + } + + detailed->connector.digital.negative_hsync = !get_bit (bits, 0); + } + else + { + detailed->connector.analog.bipolar = get_bit (bits, 3); + detailed->connector.analog.serrations = get_bit (bits, 2); + detailed->connector.analog.sync_on_green = !get_bit (bits, 1); + } +} + +static int +decode_descriptors (const uchar *edid, MonitorInfo *info) +{ + int i; + int timing_idx; + + timing_idx = 0; + + for (i = 0; i < 4; ++i) + { + int index = 0x36 + i * 18; + + if (edid[index + 0] == 0x00 && edid[index + 1] == 0x00) + { + decode_display_descriptor (edid + index, info); + } + else + { + decode_detailed_timing (edid + index, &(info->detailed_timings[timing_idx++])); + } + } + + info->n_detailed_timings = timing_idx; + + return TRUE; +} + +static void +decode_check_sum (const uchar *edid, + MonitorInfo *info) +{ + int i; + uchar check = 0; + + for (i = 0; i < 128; ++i) + check += edid[i]; + + info->checksum = check; +} + +MonitorInfo * +decode_edid (const uchar *edid) +{ + MonitorInfo *info = g_new0 (MonitorInfo, 1); + + decode_check_sum (edid, info); + + if (decode_header (edid) + && decode_vendor_and_product_identification (edid, info) + && decode_edid_version (edid, info) + && decode_display_parameters (edid, info) + && decode_color_characteristics (edid, info) + && decode_established_timings (edid, info) + && decode_standard_timings (edid, info) + && decode_descriptors (edid, info)) + { + return info; + } + else + { + g_free (info); + return NULL; + } +} diff --git a/src/backends/edid.h b/src/backends/edid.h new file mode 100644 index 000000000..f07fd9e55 --- /dev/null +++ b/src/backends/edid.h @@ -0,0 +1,193 @@ +/* edid.h + * + * Copyright 2007, 2008, Red Hat, Inc. + * + * This file is part of the Gnome Library. + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * Author: Soren Sandmann <sandmann@redhat.com> + */ + +#ifndef EDID_H +#define EDID_H + +typedef unsigned char uchar; +typedef struct MonitorInfo MonitorInfo; +typedef struct Timing Timing; +typedef struct DetailedTiming DetailedTiming; + +typedef enum +{ + UNDEFINED, + DVI, + HDMI_A, + HDMI_B, + MDDI, + DISPLAY_PORT +} Interface; + +typedef enum +{ + UNDEFINED_COLOR, + MONOCHROME, + RGB, + OTHER_COLOR +} ColorType; + +typedef enum +{ + NO_STEREO, + FIELD_RIGHT, + FIELD_LEFT, + TWO_WAY_RIGHT_ON_EVEN, + TWO_WAY_LEFT_ON_EVEN, + FOUR_WAY_INTERLEAVED, + SIDE_BY_SIDE +} StereoType; + +struct Timing +{ + int width; + int height; + int frequency; +}; + +struct DetailedTiming +{ + int pixel_clock; + int h_addr; + int h_blank; + int h_sync; + int h_front_porch; + int v_addr; + int v_blank; + int v_sync; + int v_front_porch; + int width_mm; + int height_mm; + int right_border; + int top_border; + int interlaced; + StereoType stereo; + + int digital_sync; + union + { + struct + { + int bipolar; + int serrations; + int sync_on_green; + } analog; + + struct + { + int composite; + int serrations; + int negative_vsync; + int negative_hsync; + } digital; + } connector; +}; + +struct MonitorInfo +{ + int checksum; + char manufacturer_code[4]; + int product_code; + unsigned int serial_number; + + int production_week; /* -1 if not specified */ + int production_year; /* -1 if not specified */ + int model_year; /* -1 if not specified */ + + int major_version; + int minor_version; + + int is_digital; + + union + { + struct + { + int bits_per_primary; + Interface interface; + int rgb444; + int ycrcb444; + int ycrcb422; + } digital; + + struct + { + double video_signal_level; + double sync_signal_level; + double total_signal_level; + + int blank_to_black; + + int separate_hv_sync; + int composite_sync_on_h; + int composite_sync_on_green; + int serration_on_vsync; + ColorType color_type; + } analog; + } connector; + + int width_mm; /* -1 if not specified */ + int height_mm; /* -1 if not specified */ + double aspect_ratio; /* -1.0 if not specififed */ + + double gamma; /* -1.0 if not specified */ + + int standby; + int suspend; + int active_off; + + int srgb_is_standard; + int preferred_timing_includes_native; + int continuous_frequency; + + double red_x; + double red_y; + double green_x; + double green_y; + double blue_x; + double blue_y; + double white_x; + double white_y; + + Timing established[24]; /* Terminated by 0x0x0 */ + Timing standard[8]; + + int n_detailed_timings; + DetailedTiming detailed_timings[4]; /* If monitor has a preferred + * mode, it is the first one + * (whether it has, is + * determined by the + * preferred_timing_includes + * bit. + */ + + /* Optional product description */ + char dsc_serial_number[14]; + char dsc_product_name[14]; + char dsc_string[14]; /* Unspecified ASCII data */ +}; + +MonitorInfo *decode_edid (const uchar *data); + +#endif diff --git a/src/backends/gsm-inhibitor-flag.h b/src/backends/gsm-inhibitor-flag.h new file mode 100644 index 000000000..40698f96a --- /dev/null +++ b/src/backends/gsm-inhibitor-flag.h @@ -0,0 +1,36 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __GSM_INHIBITOR_FLAG_H__ +#define __GSM_INHIBITOR_FLAG_H__ + +#include <glib-object.h> + +G_BEGIN_DECLS + +typedef enum { + GSM_INHIBITOR_FLAG_LOGOUT = 1 << 0, + GSM_INHIBITOR_FLAG_SWITCH_USER = 1 << 1, + GSM_INHIBITOR_FLAG_SUSPEND = 1 << 2, + GSM_INHIBITOR_FLAG_IDLE = 1 << 3, + GSM_INHIBITOR_FLAG_AUTOMOUNT = 1 << 4 +} GsmInhibitorFlag; + +G_END_DECLS + +#endif /* __GSM_INHIBITOR_FLAG_H__ */ diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h new file mode 100644 index 000000000..5b0c849ec --- /dev/null +++ b/src/backends/meta-backend-private.h @@ -0,0 +1,197 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jasper St. Pierre <jstpierre@mecheye.net> + */ + + +#ifndef META_BACKEND_PRIVATE_H +#define META_BACKEND_PRIVATE_H + +#include <glib-object.h> +#include <xkbcommon/xkbcommon.h> + +#include "meta/meta-backend.h" +#include "meta/meta-idle-monitor.h" +#include "backends/meta-backend-types.h" +#include "backends/meta-cursor-renderer.h" +#include "backends/meta-egl.h" +#include "backends/meta-input-settings-private.h" +#include "backends/meta-monitor-manager-private.h" +#include "backends/meta-orientation-manager.h" +#include "backends/meta-pointer-constraint.h" +#include "backends/meta-renderer.h" +#include "backends/meta-settings-private.h" +#include "core/util-private.h" + +#ifdef HAVE_REMOTE_DESKTOP +#include "backends/meta-remote-desktop.h" +#endif + +#define DEFAULT_XKB_RULES_FILE "evdev" +#define DEFAULT_XKB_MODEL "pc105+inet" + +typedef enum +{ + META_SEQUENCE_NONE, + META_SEQUENCE_ACCEPTED, + META_SEQUENCE_REJECTED, + META_SEQUENCE_PENDING_END +} MetaSequenceState; + +struct _MetaBackendClass +{ + GObjectClass parent_class; + + ClutterBackend * (* create_clutter_backend) (MetaBackend *backend); + + void (* post_init) (MetaBackend *backend); + + MetaMonitorManager * (* create_monitor_manager) (MetaBackend *backend, + GError **error); + MetaCursorRenderer * (* create_cursor_renderer) (MetaBackend *backend); + MetaRenderer * (* create_renderer) (MetaBackend *backend, + GError **error); + MetaInputSettings * (* create_input_settings) (MetaBackend *backend); + + gboolean (* grab_device) (MetaBackend *backend, + int device_id, + uint32_t timestamp); + gboolean (* ungrab_device) (MetaBackend *backend, + int device_id, + uint32_t timestamp); + + void (* finish_touch_sequence) (MetaBackend *backend, + ClutterEventSequence *sequence, + MetaSequenceState state); + MetaLogicalMonitor * (* get_current_logical_monitor) (MetaBackend *backend); + + void (* set_keymap) (MetaBackend *backend, + const char *layouts, + const char *variants, + const char *options); + + gboolean (* is_lid_closed) (MetaBackend *backend); + + struct xkb_keymap * (* get_keymap) (MetaBackend *backend); + + xkb_layout_index_t (* get_keymap_layout_group) (MetaBackend *backend); + + void (* lock_layout_group) (MetaBackend *backend, + guint idx); + + void (* update_screen_size) (MetaBackend *backend, int width, int height); + void (* select_stage_events) (MetaBackend *backend); + + void (* set_numlock) (MetaBackend *backend, + gboolean numlock_state); + +}; + +void meta_init_backend (GType backend_gtype); + +#ifdef HAVE_WAYLAND +MetaWaylandCompositor * meta_backend_get_wayland_compositor (MetaBackend *backend); + +void meta_backend_init_wayland_display (MetaBackend *backend); + +void meta_backend_init_wayland (MetaBackend *backend); +#endif + +ClutterBackend * meta_backend_get_clutter_backend (MetaBackend *backend); + +MetaIdleMonitor * meta_backend_get_idle_monitor (MetaBackend *backend, + ClutterInputDevice *device); +void meta_backend_foreach_device_monitor (MetaBackend *backend, + GFunc func, + gpointer user_data); + +META_EXPORT_TEST +MetaMonitorManager * meta_backend_get_monitor_manager (MetaBackend *backend); +MetaOrientationManager * meta_backend_get_orientation_manager (MetaBackend *backend); +MetaCursorTracker * meta_backend_get_cursor_tracker (MetaBackend *backend); +MetaCursorRenderer * meta_backend_get_cursor_renderer (MetaBackend *backend); +META_EXPORT_TEST +MetaRenderer * meta_backend_get_renderer (MetaBackend *backend); +MetaEgl * meta_backend_get_egl (MetaBackend *backend); + +#ifdef HAVE_REMOTE_DESKTOP +MetaRemoteDesktop * meta_backend_get_remote_desktop (MetaBackend *backend); +#endif + +gboolean meta_backend_grab_device (MetaBackend *backend, + int device_id, + uint32_t timestamp); +gboolean meta_backend_ungrab_device (MetaBackend *backend, + int device_id, + uint32_t timestamp); + +void meta_backend_finish_touch_sequence (MetaBackend *backend, + ClutterEventSequence *sequence, + MetaSequenceState state); + +MetaLogicalMonitor * meta_backend_get_current_logical_monitor (MetaBackend *backend); + +struct xkb_keymap * meta_backend_get_keymap (MetaBackend *backend); + +xkb_layout_index_t meta_backend_get_keymap_layout_group (MetaBackend *backend); + +gboolean meta_backend_is_lid_closed (MetaBackend *backend); + +void meta_backend_freeze_updates (MetaBackend *backend); + +void meta_backend_thaw_updates (MetaBackend *backend); + +void meta_backend_update_last_device (MetaBackend *backend, + ClutterInputDevice *device); + +MetaPointerConstraint * meta_backend_get_client_pointer_constraint (MetaBackend *backend); +void meta_backend_set_client_pointer_constraint (MetaBackend *backend, + MetaPointerConstraint *constraint); + +void meta_backend_monitors_changed (MetaBackend *backend); + +META_EXPORT_TEST +gboolean meta_is_stage_views_enabled (void); + +gboolean meta_is_stage_views_scaled (void); + +MetaInputSettings *meta_backend_get_input_settings (MetaBackend *backend); + +void meta_backend_notify_keymap_changed (MetaBackend *backend); + +void meta_backend_notify_keymap_layout_group_changed (MetaBackend *backend, + unsigned int locked_group); + +void meta_backend_notify_ui_scaling_factor_changed (MetaBackend *backend); + +META_EXPORT_TEST +void meta_backend_add_gpu (MetaBackend *backend, + MetaGpu *gpu); + +META_EXPORT_TEST +GList * meta_backend_get_gpus (MetaBackend *backend); + +#ifdef HAVE_LIBWACOM +WacomDeviceDatabase * meta_backend_get_wacom_database (MetaBackend *backend); +#endif + +#endif /* META_BACKEND_PRIVATE_H */ diff --git a/src/backends/meta-backend-types.h b/src/backends/meta-backend-types.h new file mode 100644 index 000000000..c463821fb --- /dev/null +++ b/src/backends/meta-backend-types.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2001 Havoc Pennington + * Copyright (C) 2003 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * Copyright (C) 2013-2018 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef META_BACKEND_TYPE_H +#define META_BACKEND_TYPE_H + +typedef struct _MetaMonitorManager MetaMonitorManager; + +typedef struct _MetaMonitorConfigManager MetaMonitorConfigManager; +typedef struct _MetaMonitorConfigStore MetaMonitorConfigStore; +typedef struct _MetaMonitorsConfig MetaMonitorsConfig; + +typedef struct _MetaMonitor MetaMonitor; +typedef struct _MetaMonitorNormal MetaMonitorNormal; +typedef struct _MetaMonitorTiled MetaMonitorTiled; +typedef struct _MetaMonitorSpec MetaMonitorSpec; +typedef struct _MetaLogicalMonitor MetaLogicalMonitor; + +typedef enum _MetaMonitorTransform MetaMonitorTransform; + +typedef struct _MetaMonitorMode MetaMonitorMode; + +typedef struct _MetaGpu MetaGpu; + +typedef struct _MetaCrtc MetaCrtc; +typedef struct _MetaOutput MetaOutput; +typedef struct _MetaCrtcMode MetaCrtcMode; +typedef struct _MetaCrtcInfo MetaCrtcInfo; +typedef struct _MetaOutputInfo MetaOutputInfo; +typedef struct _MetaTileInfo MetaTileInfo; + +typedef struct _MetaRenderer MetaRenderer; +typedef struct _MetaRendererView MetaRendererView; + +typedef struct _MetaScreenCast MetaScreenCast; +typedef struct _MetaScreenCastSession MetaScreenCastSession; +typedef struct _MetaScreenCastStream MetaScreenCastStream; + +typedef struct _MetaWaylandCompositor MetaWaylandCompositor; + +#endif /* META_BACKEND_TYPE_H */ diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c new file mode 100644 index 000000000..06d388154 --- /dev/null +++ b/src/backends/meta-backend.c @@ -0,0 +1,1496 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jasper St. Pierre <jstpierre@mecheye.net> + */ + +/** + * SECTION:meta-backend + * @title: MetaBackend + * @short_description: Handles monitor config, modesetting, cursor sprites, ... + * + * MetaBackend is the abstraction that deals with several things like: + * - Modesetting (depending on the backend, this can be done either by X or KMS) + * - Initializing the #MetaSettings + * - Setting up Monitor configuration + * - Input device configuration (using the #ClutterDeviceManager) + * - Creating the #MetaRenderer + * - Setting up the stage of the scene graph (using #MetaStage) + * - Creating the object that deals wih the cursor (using #MetaCursorTracker) + * and its possible pointer constraint (using #MetaPointerConstraint) + * - Setting the cursor sprite (using #MetaCursorRenderer) + * - Interacting with logind (using the appropriate D-Bus interface) + * - Querying UPower (over D-Bus) to know when the lid is closed + * - Setup Remote Desktop / Screencasting (#MetaRemoteDesktop) + * - Setup the #MetaEgl object + * + * Note that the #MetaBackend is not a subclass of #ClutterBackend. It is + * responsible for creating the correct one, based on the backend that is + * used (#MetaBackendNative or #MetaBackendX11). + */ + +#include "config.h" + +#include "backends/meta-backend-private.h" + +#include <stdlib.h> + +#include "backends/meta-cursor-tracker-private.h" +#include "backends/meta-idle-monitor-private.h" +#include "backends/meta-input-settings-private.h" +#include "backends/meta-logical-monitor.h" +#include "backends/meta-monitor-manager-dummy.h" +#include "backends/meta-settings-private.h" +#include "backends/meta-stage-private.h" +#include "backends/x11/meta-backend-x11.h" +#include "clutter/clutter-mutter.h" +#include "meta/main.h" +#include "meta/meta-backend.h" +#include "meta/util.h" + +#ifdef HAVE_PROFILER +#include "backends/meta-profiler.h" +#endif + +#ifdef HAVE_REMOTE_DESKTOP +#include "backends/meta-dbus-session-watcher.h" +#include "backends/meta-remote-access-controller-private.h" +#include "backends/meta-remote-desktop.h" +#include "backends/meta-screen-cast.h" +#endif + +#ifdef HAVE_NATIVE_BACKEND +#include "backends/native/meta-backend-native.h" +#endif + +#ifdef HAVE_WAYLAND +#include "wayland/meta-wayland.h" +#endif + +enum +{ + KEYMAP_CHANGED, + KEYMAP_LAYOUT_GROUP_CHANGED, + LAST_DEVICE_CHANGED, + LID_IS_CLOSED_CHANGED, + GPU_ADDED, + + N_SIGNALS +}; + +static guint signals[N_SIGNALS]; + +static MetaBackend *_backend; + +static gboolean stage_views_disabled = FALSE; + +/** + * meta_get_backend: + * + * Accessor for the singleton MetaBackend. + * + * Returns: (transfer none): The only #MetaBackend there is. + */ +MetaBackend * +meta_get_backend (void) +{ + return _backend; +} + +struct _MetaBackendPrivate +{ + MetaMonitorManager *monitor_manager; + MetaOrientationManager *orientation_manager; + MetaCursorTracker *cursor_tracker; + MetaCursorRenderer *cursor_renderer; + MetaInputSettings *input_settings; + MetaRenderer *renderer; +#ifdef HAVE_EGL + MetaEgl *egl; +#endif + MetaSettings *settings; +#ifdef HAVE_REMOTE_DESKTOP + MetaRemoteAccessController *remote_access_controller; + MetaDbusSessionWatcher *dbus_session_watcher; + MetaScreenCast *screen_cast; + MetaRemoteDesktop *remote_desktop; +#endif + +#ifdef HAVE_WAYLAND + MetaWaylandCompositor *wayland_compositor; +#endif + +#ifdef HAVE_PROFILER + MetaProfiler *profiler; +#endif + +#ifdef HAVE_LIBWACOM + WacomDeviceDatabase *wacom_db; +#endif + + ClutterBackend *clutter_backend; + ClutterActor *stage; + + GList *gpus; + + gboolean is_pointer_position_initialized; + + guint device_update_idle_id; + gulong keymap_state_changed_id; + + GHashTable *device_monitors; + + ClutterInputDevice *current_device; + + MetaPointerConstraint *client_pointer_constraint; + MetaDnd *dnd; + + guint upower_watch_id; + GDBusProxy *upower_proxy; + gboolean lid_is_closed; + + guint sleep_signal_id; + GCancellable *cancellable; + GDBusConnection *system_bus; + + gboolean was_headless; +}; +typedef struct _MetaBackendPrivate MetaBackendPrivate; + +static void +initable_iface_init (GInitableIface *initable_iface); + +G_DEFINE_ABSTRACT_TYPE_WITH_CODE (MetaBackend, meta_backend, G_TYPE_OBJECT, + G_ADD_PRIVATE (MetaBackend) + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + initable_iface_init)); + +static void +meta_backend_finalize (GObject *object) +{ + MetaBackend *backend = META_BACKEND (object); + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + if (priv->keymap_state_changed_id) + { + ClutterSeat *seat; + ClutterKeymap *keymap; + + seat = clutter_backend_get_default_seat (priv->clutter_backend); + keymap = clutter_seat_get_keymap (seat); + g_clear_signal_handler (&priv->keymap_state_changed_id, keymap); + } + + g_list_free_full (priv->gpus, g_object_unref); + + g_clear_object (&priv->current_device); + g_clear_object (&priv->monitor_manager); + g_clear_object (&priv->orientation_manager); + g_clear_object (&priv->input_settings); +#ifdef HAVE_REMOTE_DESKTOP + g_clear_object (&priv->remote_desktop); + g_clear_object (&priv->screen_cast); + g_clear_object (&priv->dbus_session_watcher); + g_clear_object (&priv->remote_access_controller); +#endif + +#ifdef HAVE_LIBWACOM + g_clear_pointer (&priv->wacom_db, libwacom_database_destroy); +#endif + + if (priv->sleep_signal_id) + g_dbus_connection_signal_unsubscribe (priv->system_bus, priv->sleep_signal_id); + if (priv->upower_watch_id) + g_bus_unwatch_name (priv->upower_watch_id); + g_cancellable_cancel (priv->cancellable); + g_clear_object (&priv->cancellable); + g_clear_object (&priv->system_bus); + g_clear_object (&priv->upower_proxy); + + g_clear_handle_id (&priv->device_update_idle_id, g_source_remove); + + g_hash_table_destroy (priv->device_monitors); + + g_clear_object (&priv->settings); + +#ifdef HAVE_PROFILER + g_clear_object (&priv->profiler); +#endif + + G_OBJECT_CLASS (meta_backend_parent_class)->finalize (object); +} + +static void +meta_backend_sync_screen_size (MetaBackend *backend) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + int width, height; + + meta_monitor_manager_get_screen_size (priv->monitor_manager, &width, &height); + + META_BACKEND_GET_CLASS (backend)->update_screen_size (backend, width, height); +} + +static void +reset_pointer_position (MetaBackend *backend) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + MetaMonitorManager *monitor_manager = priv->monitor_manager; + ClutterSeat *seat = clutter_backend_get_default_seat (priv->clutter_backend); + MetaLogicalMonitor *primary; + + primary = + meta_monitor_manager_get_primary_logical_monitor (monitor_manager); + + /* Move the pointer out of the way to avoid hovering over reactive + * elements (e.g. users list at login) causing undesired behaviour. */ + clutter_seat_warp_pointer (seat, + primary->rect.x + primary->rect.width * 0.9, + primary->rect.y + primary->rect.height * 0.9); +} + +void +meta_backend_monitors_changed (MetaBackend *backend) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + ClutterSeat *seat = clutter_backend_get_default_seat (priv->clutter_backend); + ClutterInputDevice *device = clutter_seat_get_pointer (seat); + graphene_point_t point; + + meta_backend_sync_screen_size (backend); + + if (clutter_input_device_get_coords (device, NULL, &point)) + { + /* If we're outside all monitors, warp the pointer back inside */ + if ((!meta_monitor_manager_get_logical_monitor_at (monitor_manager, + point.x, point.y) || + !priv->is_pointer_position_initialized) && + !meta_monitor_manager_is_headless (monitor_manager)) + { + reset_pointer_position (backend); + priv->is_pointer_position_initialized = TRUE; + } + } + + meta_cursor_renderer_force_update (priv->cursor_renderer); + + if (meta_monitor_manager_is_headless (priv->monitor_manager) && + !priv->was_headless) + { + clutter_stage_freeze_updates (CLUTTER_STAGE (priv->stage)); + priv->was_headless = TRUE; + } + else if (!meta_monitor_manager_is_headless (priv->monitor_manager) && + priv->was_headless) + { + clutter_stage_thaw_updates (CLUTTER_STAGE (priv->stage)); + priv->was_headless = FALSE; + } +} + +void +meta_backend_foreach_device_monitor (MetaBackend *backend, + GFunc func, + gpointer user_data) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + GHashTableIter iter; + gpointer value; + + g_hash_table_iter_init (&iter, priv->device_monitors); + while (g_hash_table_iter_next (&iter, NULL, &value)) + { + MetaIdleMonitor *device_monitor = META_IDLE_MONITOR (value); + + func (device_monitor, user_data); + } +} + +static MetaIdleMonitor * +meta_backend_create_idle_monitor (MetaBackend *backend, + ClutterInputDevice *device) +{ + return g_object_new (META_TYPE_IDLE_MONITOR, + "device", device, + NULL); +} + +static void +create_device_monitor (MetaBackend *backend, + ClutterInputDevice *device) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + MetaIdleMonitor *idle_monitor; + + if (g_hash_table_contains (priv->device_monitors, device)) + return; + + idle_monitor = meta_backend_create_idle_monitor (backend, device); + g_hash_table_insert (priv->device_monitors, device, idle_monitor); +} + +static void +destroy_device_monitor (MetaBackend *backend, + ClutterInputDevice *device) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + g_hash_table_remove (priv->device_monitors, device); +} + +static void +meta_backend_monitor_device (MetaBackend *backend, + ClutterInputDevice *device) +{ + create_device_monitor (backend, device); +} + +static inline gboolean +device_is_slave_touchscreen (ClutterInputDevice *device) +{ + return (clutter_input_device_get_device_mode (device) != CLUTTER_INPUT_MODE_MASTER && + clutter_input_device_get_device_type (device) == CLUTTER_TOUCHSCREEN_DEVICE); +} + +static inline gboolean +check_has_pointing_device (ClutterSeat *seat) +{ + GList *l, *devices; + gboolean found = FALSE; + + devices = clutter_seat_list_devices (seat); + + for (l = devices; l; l = l->next) + { + ClutterInputDevice *device = l->data; + + if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER) + continue; + if (clutter_input_device_get_device_type (device) == CLUTTER_TOUCHSCREEN_DEVICE || + clutter_input_device_get_device_type (device) == CLUTTER_KEYBOARD_DEVICE) + continue; + + found = TRUE; + break; + } + + g_list_free (devices); + + return found; +} + +static inline gboolean +check_has_slave_touchscreen (ClutterSeat *seat) +{ + GList *l, *devices; + gboolean found = FALSE; + + devices = clutter_seat_list_devices (seat); + + for (l = devices; l; l = l->next) + { + ClutterInputDevice *device = l->data; + + if (clutter_input_device_get_device_mode (device) != CLUTTER_INPUT_MODE_MASTER && + clutter_input_device_get_device_type (device) == CLUTTER_TOUCHSCREEN_DEVICE) + { + found = TRUE; + break; + } + } + + g_list_free (devices); + + return found; +} + +static void +on_device_added (ClutterSeat *seat, + ClutterInputDevice *device, + gpointer user_data) +{ + MetaBackend *backend = META_BACKEND (user_data); + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + create_device_monitor (backend, device); + + if (device_is_slave_touchscreen (device)) + meta_cursor_tracker_set_pointer_visible (priv->cursor_tracker, FALSE); +} + +static void +on_device_removed (ClutterSeat *seat, + ClutterInputDevice *device, + gpointer user_data) +{ + MetaBackend *backend = META_BACKEND (user_data); + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + destroy_device_monitor (backend, device); + + /* If the device the user last interacted goes away, check again pointer + * visibility. + */ + if (priv->current_device == device) + { + MetaCursorTracker *cursor_tracker = priv->cursor_tracker; + gboolean has_touchscreen, has_pointing_device; + ClutterInputDeviceType device_type; + + g_clear_object (&priv->current_device); + g_clear_handle_id (&priv->device_update_idle_id, g_source_remove); + + device_type = clutter_input_device_get_device_type (device); + has_touchscreen = check_has_slave_touchscreen (seat); + + if (device_type == CLUTTER_TOUCHSCREEN_DEVICE && has_touchscreen) + { + /* There's more touchscreens left, keep the pointer hidden */ + meta_cursor_tracker_set_pointer_visible (cursor_tracker, FALSE); + } + else if (device_type != CLUTTER_KEYBOARD_DEVICE) + { + has_pointing_device = check_has_pointing_device (seat); + meta_cursor_tracker_set_pointer_visible (cursor_tracker, + has_pointing_device && + !has_touchscreen); + } + } + + if (priv->current_device == device) + meta_backend_update_last_device (backend, NULL); +} + +static void +create_device_monitors (MetaBackend *backend, + ClutterSeat *seat) +{ + GList *l, *devices; + + create_device_monitor (backend, clutter_seat_get_pointer (seat)); + create_device_monitor (backend, clutter_seat_get_keyboard (seat)); + + devices = clutter_seat_list_devices (seat); + for (l = devices; l; l = l->next) + { + ClutterInputDevice *device = l->data; + + meta_backend_monitor_device (backend, device); + } + + g_list_free (devices); +} + +static MetaInputSettings * +meta_backend_create_input_settings (MetaBackend *backend) +{ + return META_BACKEND_GET_CLASS (backend)->create_input_settings (backend); +} + +static void +meta_backend_real_post_init (MetaBackend *backend) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + ClutterSeat *seat = clutter_backend_get_default_seat (priv->clutter_backend); + ClutterKeymap *keymap = clutter_seat_get_keymap (seat); + + priv->stage = meta_stage_new (backend); + clutter_actor_realize (priv->stage); + META_BACKEND_GET_CLASS (backend)->select_stage_events (backend); + + meta_monitor_manager_setup (priv->monitor_manager); + + meta_backend_sync_screen_size (backend); + + priv->cursor_renderer = META_BACKEND_GET_CLASS (backend)->create_cursor_renderer (backend); + + priv->device_monitors = + g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) g_object_unref); + + create_device_monitors (backend, seat); + + g_signal_connect_object (seat, "device-added", + G_CALLBACK (on_device_added), backend, 0); + g_signal_connect_object (seat, "device-removed", + G_CALLBACK (on_device_removed), backend, + G_CONNECT_AFTER); + + priv->input_settings = meta_backend_create_input_settings (backend); + + if (priv->input_settings) + { + priv->keymap_state_changed_id = + g_signal_connect_swapped (keymap, "state-changed", + G_CALLBACK (meta_input_settings_maybe_save_numlock_state), + priv->input_settings); + meta_input_settings_maybe_restore_numlock_state (priv->input_settings); + } + +#ifdef HAVE_REMOTE_DESKTOP + priv->remote_access_controller = + g_object_new (META_TYPE_REMOTE_ACCESS_CONTROLLER, NULL); + priv->dbus_session_watcher = g_object_new (META_TYPE_DBUS_SESSION_WATCHER, NULL); + priv->screen_cast = meta_screen_cast_new (backend, + priv->dbus_session_watcher); + priv->remote_desktop = meta_remote_desktop_new (priv->dbus_session_watcher); +#endif /* HAVE_REMOTE_DESKTOP */ + + if (!meta_monitor_manager_is_headless (priv->monitor_manager)) + { + reset_pointer_position (backend); + priv->is_pointer_position_initialized = TRUE; + } +} + +static MetaCursorRenderer * +meta_backend_real_create_cursor_renderer (MetaBackend *backend) +{ + return meta_cursor_renderer_new (); +} + +static gboolean +meta_backend_real_grab_device (MetaBackend *backend, + int device_id, + uint32_t timestamp) +{ + /* Do nothing */ + return TRUE; +} + +static gboolean +meta_backend_real_ungrab_device (MetaBackend *backend, + int device_id, + uint32_t timestamp) +{ + /* Do nothing */ + return TRUE; +} + +static void +meta_backend_real_select_stage_events (MetaBackend *backend) +{ + /* Do nothing */ +} + +static gboolean +meta_backend_real_is_lid_closed (MetaBackend *backend) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + return priv->lid_is_closed; +} + +gboolean +meta_backend_is_lid_closed (MetaBackend *backend) +{ + return META_BACKEND_GET_CLASS (backend)->is_lid_closed (backend); +} + +static void +upower_properties_changed (GDBusProxy *proxy, + GVariant *changed_properties, + GStrv invalidated_properties, + gpointer user_data) +{ + MetaBackend *backend = user_data; + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + GVariant *v; + gboolean lid_is_closed; + + v = g_variant_lookup_value (changed_properties, + "LidIsClosed", + G_VARIANT_TYPE_BOOLEAN); + if (!v) + return; + + lid_is_closed = g_variant_get_boolean (v); + g_variant_unref (v); + + if (lid_is_closed == priv->lid_is_closed) + return; + + priv->lid_is_closed = lid_is_closed; + g_signal_emit (backend, signals[LID_IS_CLOSED_CHANGED], 0, + priv->lid_is_closed); + + if (lid_is_closed) + return; + + meta_idle_monitor_reset_idletime (meta_idle_monitor_get_core ()); +} + +static void +upower_ready_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + MetaBackend *backend; + MetaBackendPrivate *priv; + GDBusProxy *proxy; + GError *error = NULL; + GVariant *v; + + proxy = g_dbus_proxy_new_finish (res, &error); + if (!proxy) + { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("Failed to create UPower proxy: %s", error->message); + g_error_free (error); + return; + } + + backend = META_BACKEND (user_data); + priv = meta_backend_get_instance_private (backend); + + priv->upower_proxy = proxy; + g_signal_connect (proxy, "g-properties-changed", + G_CALLBACK (upower_properties_changed), backend); + + v = g_dbus_proxy_get_cached_property (proxy, "LidIsClosed"); + if (!v) + return; + priv->lid_is_closed = g_variant_get_boolean (v); + g_variant_unref (v); + + if (priv->lid_is_closed) + { + g_signal_emit (backend, signals[LID_IS_CLOSED_CHANGED], 0, + priv->lid_is_closed); + } +} + +static void +upower_appeared (GDBusConnection *connection, + const gchar *name, + const gchar *name_owner, + gpointer user_data) +{ + MetaBackend *backend = META_BACKEND (user_data); + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + g_dbus_proxy_new (connection, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "org.freedesktop.UPower", + "/org/freedesktop/UPower", + "org.freedesktop.UPower", + priv->cancellable, + upower_ready_cb, + backend); +} + +static void +upower_vanished (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + MetaBackend *backend = META_BACKEND (user_data); + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + g_clear_object (&priv->upower_proxy); +} + +static void +meta_backend_constructed (GObject *object) +{ + MetaBackend *backend = META_BACKEND (object); + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + MetaBackendClass *backend_class = + META_BACKEND_GET_CLASS (backend); + +#ifdef HAVE_LIBWACOM + priv->wacom_db = libwacom_database_new (); + if (!priv->wacom_db) + { + g_warning ("Could not create database of Wacom devices, " + "expect tablets to misbehave"); + } +#endif + + if (backend_class->is_lid_closed != meta_backend_real_is_lid_closed) + return; + + priv->upower_watch_id = g_bus_watch_name (G_BUS_TYPE_SYSTEM, + "org.freedesktop.UPower", + G_BUS_NAME_WATCHER_FLAGS_NONE, + upower_appeared, + upower_vanished, + backend, + NULL); +} + +static void +meta_backend_class_init (MetaBackendClass *klass) +{ + const gchar *mutter_stage_views; + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_backend_finalize; + object_class->constructed = meta_backend_constructed; + + klass->post_init = meta_backend_real_post_init; + klass->create_cursor_renderer = meta_backend_real_create_cursor_renderer; + klass->grab_device = meta_backend_real_grab_device; + klass->ungrab_device = meta_backend_real_ungrab_device; + klass->select_stage_events = meta_backend_real_select_stage_events; + klass->is_lid_closed = meta_backend_real_is_lid_closed; + + signals[KEYMAP_CHANGED] = + g_signal_new ("keymap-changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); + signals[KEYMAP_LAYOUT_GROUP_CHANGED] = + g_signal_new ("keymap-layout-group-changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 1, G_TYPE_UINT); + signals[LAST_DEVICE_CHANGED] = + g_signal_new ("last-device-changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 1, CLUTTER_TYPE_INPUT_DEVICE); + signals[LID_IS_CLOSED_CHANGED] = + g_signal_new ("lid-is-closed-changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 1, G_TYPE_BOOLEAN); + /** + * MetaBackend::gpu-added: (skip) + * @backend: the #MetaBackend + * @gpu: the #MetaGpu + */ + signals[GPU_ADDED] = + g_signal_new ("gpu-added", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 1, META_TYPE_GPU); + + mutter_stage_views = g_getenv ("MUTTER_STAGE_VIEWS"); + stage_views_disabled = g_strcmp0 (mutter_stage_views, "0") == 0; +} + +static MetaMonitorManager * +meta_backend_create_monitor_manager (MetaBackend *backend, + GError **error) +{ + if (g_getenv ("META_DUMMY_MONITORS")) + return g_object_new (META_TYPE_MONITOR_MANAGER_DUMMY, NULL); + + return META_BACKEND_GET_CLASS (backend)->create_monitor_manager (backend, + error); +} + +static MetaRenderer * +meta_backend_create_renderer (MetaBackend *backend, + GError **error) +{ + return META_BACKEND_GET_CLASS (backend)->create_renderer (backend, error); +} + +static void +prepare_for_sleep_cb (GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + gboolean suspending; + + g_variant_get (parameters, "(b)", &suspending); + if (suspending) + return; + meta_idle_monitor_reset_idletime (meta_idle_monitor_get_core ()); +} + +static void +system_bus_gotten_cb (GObject *object, + GAsyncResult *res, + gpointer user_data) +{ + MetaBackendPrivate *priv; + GDBusConnection *bus; + + bus = g_bus_get_finish (res, NULL); + if (!bus) + return; + + priv = meta_backend_get_instance_private (user_data); + priv->system_bus = bus; + priv->sleep_signal_id = + g_dbus_connection_signal_subscribe (priv->system_bus, + "org.freedesktop.login1", + "org.freedesktop.login1.Manager", + "PrepareForSleep", + "/org/freedesktop/login1", + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + prepare_for_sleep_cb, + NULL, + NULL); +} + +#ifdef HAVE_WAYLAND +MetaWaylandCompositor * +meta_backend_get_wayland_compositor (MetaBackend *backend) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + return priv->wayland_compositor; +} + +void +meta_backend_init_wayland_display (MetaBackend *backend) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + priv->wayland_compositor = meta_wayland_compositor_new (backend); +} + +void +meta_backend_init_wayland (MetaBackend *backend) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + meta_wayland_compositor_setup (priv->wayland_compositor); +} +#endif + +/* Mutter is responsible for pulling events off the X queue, so Clutter + * doesn't need (and shouldn't) run its normal event source which polls + * the X fd, but we do have to deal with dispatching events that accumulate + * in the clutter queue. This happens, for example, when clutter generate + * enter/leave events on mouse motion - several events are queued in the + * clutter queue but only one dispatched. It could also happen because of + * explicit calls to clutter_event_put(). We add a very simple custom + * event loop source which is simply responsible for pulling events off + * of the queue and dispatching them before we block for new events. + */ + +static gboolean +clutter_source_prepare (GSource *source, + int *timeout) +{ + *timeout = -1; + + return clutter_events_pending (); +} + +static gboolean +clutter_source_check (GSource *source) +{ + return clutter_events_pending (); +} + +static gboolean +clutter_source_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + ClutterEvent *event = clutter_event_get (); + + if (event) + { + clutter_do_event (event); + clutter_event_free (event); + } + + return TRUE; +} + +static GSourceFuncs clutter_source_funcs = { + clutter_source_prepare, + clutter_source_check, + clutter_source_dispatch +}; + +static ClutterBackend * +meta_get_clutter_backend (void) +{ + MetaBackend *backend = meta_get_backend (); + + return meta_backend_get_clutter_backend (backend); +} + +static gboolean +init_clutter (MetaBackend *backend, + GError **error) +{ + GSource *source; + + clutter_set_custom_backend_func (meta_get_clutter_backend); + + if (clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Unable to initialize Clutter"); + return FALSE; + } + + source = g_source_new (&clutter_source_funcs, sizeof (GSource)); + g_source_attach (source, NULL); + g_source_unref (source); + + return TRUE; +} + +static void +meta_backend_post_init (MetaBackend *backend) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + META_BACKEND_GET_CLASS (backend)->post_init (backend); + + meta_settings_post_init (priv->settings); +} + +static gboolean +meta_backend_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + MetaBackend *backend = META_BACKEND (initable); + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + priv->settings = meta_settings_new (backend); + +#ifdef HAVE_EGL + priv->egl = g_object_new (META_TYPE_EGL, NULL); +#endif + + priv->orientation_manager = g_object_new (META_TYPE_ORIENTATION_MANAGER, NULL); + + priv->monitor_manager = meta_backend_create_monitor_manager (backend, error); + if (!priv->monitor_manager) + return FALSE; + + priv->renderer = meta_backend_create_renderer (backend, error); + if (!priv->renderer) + return FALSE; + + priv->cursor_tracker = g_object_new (META_TYPE_CURSOR_TRACKER, NULL); + + priv->dnd = g_object_new (META_TYPE_DND, NULL); + + priv->cancellable = g_cancellable_new (); + g_bus_get (G_BUS_TYPE_SYSTEM, + priv->cancellable, + system_bus_gotten_cb, + backend); + +#ifdef HAVE_PROFILER + priv->profiler = meta_profiler_new (); +#endif + + if (!init_clutter (backend, error)) + return FALSE; + + meta_backend_post_init (backend); + + return TRUE; +} + +static void +initable_iface_init (GInitableIface *initable_iface) +{ + initable_iface->init = meta_backend_initable_init; +} + +static void +meta_backend_init (MetaBackend *backend) +{ + _backend = backend; +} + +/** + * meta_backend_get_idle_monitor: (skip) + */ +MetaIdleMonitor * +meta_backend_get_idle_monitor (MetaBackend *backend, + ClutterInputDevice *device) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + return g_hash_table_lookup (priv->device_monitors, device); +} + +/** + * meta_backend_get_monitor_manager: (skip) + */ +MetaMonitorManager * +meta_backend_get_monitor_manager (MetaBackend *backend) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + return priv->monitor_manager; +} + +/** + * meta_backend_get_orientation_manager: (skip) + */ +MetaOrientationManager * +meta_backend_get_orientation_manager (MetaBackend *backend) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + return priv->orientation_manager; +} + +MetaCursorTracker * +meta_backend_get_cursor_tracker (MetaBackend *backend) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + return priv->cursor_tracker; +} + +/** + * meta_backend_get_cursor_renderer: (skip) + */ +MetaCursorRenderer * +meta_backend_get_cursor_renderer (MetaBackend *backend) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + return priv->cursor_renderer; +} + +/** + * meta_backend_get_renderer: (skip) + */ +MetaRenderer * +meta_backend_get_renderer (MetaBackend *backend) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + return priv->renderer; +} + +#ifdef HAVE_EGL +/** + * meta_backend_get_egl: (skip) + */ +MetaEgl * +meta_backend_get_egl (MetaBackend *backend) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + return priv->egl; +} +#endif /* HAVE_EGL */ + +/** + * meta_backend_get_settings: (skip) + */ +MetaSettings * +meta_backend_get_settings (MetaBackend *backend) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + return priv->settings; +} + +#ifdef HAVE_REMOTE_DESKTOP +/** + * meta_backend_get_remote_desktop: (skip) + */ +MetaRemoteDesktop * +meta_backend_get_remote_desktop (MetaBackend *backend) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + return priv->remote_desktop; +} +#endif /* HAVE_REMOTE_DESKTOP */ + +/** + * meta_backend_get_remote_access_controller: + * @backend: A #MetaBackend + * + * Return Value: (transfer none): The #MetaRemoteAccessController + */ +MetaRemoteAccessController * +meta_backend_get_remote_access_controller (MetaBackend *backend) +{ +#ifdef HAVE_REMOTE_DESKTOP + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + return priv->remote_access_controller; +#else + return NULL; +#endif +} + +/** + * meta_backend_is_rendering_hardware_accelerated: + * @backend: A #MetaBackend + * + * Returns: %TRUE if the rendering is hardware accelerated, otherwise + * %FALSE. + */ +gboolean +meta_backend_is_rendering_hardware_accelerated (MetaBackend *backend) +{ + MetaRenderer *renderer = meta_backend_get_renderer (backend); + + return meta_renderer_is_hardware_accelerated (renderer); +} + +/** + * meta_backend_grab_device: (skip) + */ +gboolean +meta_backend_grab_device (MetaBackend *backend, + int device_id, + uint32_t timestamp) +{ + return META_BACKEND_GET_CLASS (backend)->grab_device (backend, device_id, timestamp); +} + +/** + * meta_backend_ungrab_device: (skip) + */ +gboolean +meta_backend_ungrab_device (MetaBackend *backend, + int device_id, + uint32_t timestamp) +{ + return META_BACKEND_GET_CLASS (backend)->ungrab_device (backend, device_id, timestamp); +} + +/** + * meta_backend_finish_touch_sequence: (skip) + */ +void +meta_backend_finish_touch_sequence (MetaBackend *backend, + ClutterEventSequence *sequence, + MetaSequenceState state) +{ + if (META_BACKEND_GET_CLASS (backend)->finish_touch_sequence) + META_BACKEND_GET_CLASS (backend)->finish_touch_sequence (backend, + sequence, + state); +} + +MetaLogicalMonitor * +meta_backend_get_current_logical_monitor (MetaBackend *backend) +{ + return META_BACKEND_GET_CLASS (backend)->get_current_logical_monitor (backend); +} + +void +meta_backend_set_keymap (MetaBackend *backend, + const char *layouts, + const char *variants, + const char *options) +{ + META_BACKEND_GET_CLASS (backend)->set_keymap (backend, layouts, variants, options); +} + +/** + * meta_backend_get_keymap: (skip) + */ +struct xkb_keymap * +meta_backend_get_keymap (MetaBackend *backend) + +{ + return META_BACKEND_GET_CLASS (backend)->get_keymap (backend); +} + +xkb_layout_index_t +meta_backend_get_keymap_layout_group (MetaBackend *backend) +{ + return META_BACKEND_GET_CLASS (backend)->get_keymap_layout_group (backend); +} + +void +meta_backend_lock_layout_group (MetaBackend *backend, + guint idx) +{ + META_BACKEND_GET_CLASS (backend)->lock_layout_group (backend, idx); +} + +void +meta_backend_set_numlock (MetaBackend *backend, + gboolean numlock_state) +{ + META_BACKEND_GET_CLASS (backend)->set_numlock (backend, numlock_state); +} + + +/** + * meta_backend_get_stage: + * @backend: A #MetaBackend + * + * Gets the global #ClutterStage that's managed by this backend. + * + * Returns: (transfer none): the #ClutterStage + */ +ClutterActor * +meta_backend_get_stage (MetaBackend *backend) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + return priv->stage; +} + +void +meta_backend_freeze_updates (MetaBackend *backend) +{ + ClutterStage *stage; + + stage = CLUTTER_STAGE (meta_backend_get_stage (backend)); + clutter_stage_freeze_updates (stage); +} + +void +meta_backend_thaw_updates (MetaBackend *backend) +{ + ClutterStage *stage; + + stage = CLUTTER_STAGE (meta_backend_get_stage (backend)); + clutter_stage_thaw_updates (stage); +} + +static gboolean +update_last_device (MetaBackend *backend) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + MetaCursorTracker *cursor_tracker = priv->cursor_tracker; + ClutterInputDeviceType device_type; + + priv->device_update_idle_id = 0; + device_type = clutter_input_device_get_device_type (priv->current_device); + + g_signal_emit (backend, signals[LAST_DEVICE_CHANGED], 0, + priv->current_device); + + switch (device_type) + { + case CLUTTER_KEYBOARD_DEVICE: + break; + case CLUTTER_TOUCHSCREEN_DEVICE: + meta_cursor_tracker_set_pointer_visible (cursor_tracker, FALSE); + break; + default: + meta_cursor_tracker_set_pointer_visible (cursor_tracker, TRUE); + break; + } + + return G_SOURCE_REMOVE; +} + +void +meta_backend_update_last_device (MetaBackend *backend, + ClutterInputDevice *device) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + if (priv->current_device == device) + return; + + if (!device || + clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER) + return; + + g_set_object (&priv->current_device, device); + + if (priv->device_update_idle_id == 0) + { + priv->device_update_idle_id = + g_idle_add ((GSourceFunc) update_last_device, backend); + g_source_set_name_by_id (priv->device_update_idle_id, + "[mutter] update_last_device"); + } +} + +MetaPointerConstraint * +meta_backend_get_client_pointer_constraint (MetaBackend *backend) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + return priv->client_pointer_constraint; +} + +/** + * meta_backend_set_client_pointer_constraint: + * @backend: a #MetaBackend object. + * @constraint: (nullable): the client constraint to follow. + * + * Sets the current pointer constraint and removes (and unrefs) the previous + * one. If @constrant is %NULL, this means that there is no + * #MetaPointerConstraint active. + */ +void +meta_backend_set_client_pointer_constraint (MetaBackend *backend, + MetaPointerConstraint *constraint) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + g_assert (!constraint || !priv->client_pointer_constraint); + + g_clear_object (&priv->client_pointer_constraint); + if (constraint) + priv->client_pointer_constraint = g_object_ref (constraint); +} + +ClutterBackend * +meta_backend_get_clutter_backend (MetaBackend *backend) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + if (!priv->clutter_backend) + { + priv->clutter_backend = + META_BACKEND_GET_CLASS (backend)->create_clutter_backend (backend); + } + + return priv->clutter_backend; +} + +void +meta_init_backend (GType backend_gtype) +{ + MetaBackend *backend; + GError *error = NULL; + + /* meta_backend_init() above install the backend globally so + * so meta_get_backend() works even during initialization. */ + backend = g_object_new (backend_gtype, NULL); + if (!g_initable_init (G_INITABLE (backend), NULL, &error)) + { + g_warning ("Failed to create backend: %s", error->message); + meta_exit (META_EXIT_ERROR); + } +} + +/** + * meta_is_stage_views_enabled: + * + * Returns whether the #ClutterStage can be rendered using multiple stage views. + * In practice, this means we can define a separate framebuffer for each + * #MetaLogicalMonitor, rather than rendering everything into a single + * framebuffer. For example: in X11, onle one single framebuffer is allowed. + */ +gboolean +meta_is_stage_views_enabled (void) +{ + if (!meta_is_wayland_compositor ()) + return FALSE; + + return !stage_views_disabled; +} + +gboolean +meta_is_stage_views_scaled (void) +{ + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaLogicalMonitorLayoutMode layout_mode; + + if (!meta_is_stage_views_enabled ()) + return FALSE; + + layout_mode = monitor_manager->layout_mode; + + return layout_mode == META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL; +} + +MetaInputSettings * +meta_backend_get_input_settings (MetaBackend *backend) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + return priv->input_settings; +} + +/** + * meta_backend_get_dnd: + * @backend: A #MetaDnd + * + * Gets the global #MetaDnd that's managed by this backend. + * + * Returns: (transfer none): the #MetaDnd + */ +MetaDnd * +meta_backend_get_dnd (MetaBackend *backend) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + return priv->dnd; +} + +void +meta_backend_notify_keymap_changed (MetaBackend *backend) +{ + g_signal_emit (backend, signals[KEYMAP_CHANGED], 0); +} + +void +meta_backend_notify_keymap_layout_group_changed (MetaBackend *backend, + unsigned int locked_group) +{ + g_signal_emit (backend, signals[KEYMAP_LAYOUT_GROUP_CHANGED], 0, + locked_group); +} + +void +meta_backend_add_gpu (MetaBackend *backend, + MetaGpu *gpu) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + priv->gpus = g_list_append (priv->gpus, gpu); + + g_signal_emit (backend, signals[GPU_ADDED], 0, gpu); +} + +GList * +meta_backend_get_gpus (MetaBackend *backend) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + return priv->gpus; +} + +#ifdef HAVE_LIBWACOM +WacomDeviceDatabase * +meta_backend_get_wacom_database (MetaBackend *backend) +{ + MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); + + return priv->wacom_db; +} +#endif diff --git a/src/backends/meta-barrier-private.h b/src/backends/meta-barrier-private.h new file mode 100644 index 000000000..d0483e43c --- /dev/null +++ b/src/backends/meta-barrier-private.h @@ -0,0 +1,66 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014-2015 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jasper St. Pierre <jstpierre@mecheye.net> + * Jonas Ådahl <jadahl@gmail.com> + */ + +#ifndef META_BARRIER_PRIVATE_H +#define META_BARRIER_PRIVATE_H + +#include "core/meta-border.h" +#include "meta/barrier.h" + +G_BEGIN_DECLS + +#define META_TYPE_BARRIER_IMPL (meta_barrier_impl_get_type ()) +G_DECLARE_DERIVABLE_TYPE (MetaBarrierImpl, + meta_barrier_impl, + META, BARRIER_IMPL, + GObject) + +struct _MetaBarrierImplClass +{ + GObjectClass parent_class; + + gboolean (*is_active) (MetaBarrierImpl *barrier); + void (*release) (MetaBarrierImpl *barrier, + MetaBarrierEvent *event); + void (*destroy) (MetaBarrierImpl *barrier); +}; + +void _meta_barrier_emit_hit_signal (MetaBarrier *barrier, + MetaBarrierEvent *event); +void _meta_barrier_emit_left_signal (MetaBarrier *barrier, + MetaBarrierEvent *event); + +void meta_barrier_event_unref (MetaBarrierEvent *event); + +G_END_DECLS + +struct _MetaBarrierPrivate +{ + MetaDisplay *display; + MetaBorder border; + MetaBarrierImpl *impl; +}; + +#endif /* META_BARRIER_PRIVATE_H */ diff --git a/src/backends/meta-barrier.c b/src/backends/meta-barrier.c new file mode 100644 index 000000000..71536c3d7 --- /dev/null +++ b/src/backends/meta-barrier.c @@ -0,0 +1,361 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; c-basic-offset: 2; -*- */ + +/** + * SECTION:barrier + * @Title: MetaBarrier + * @Short_Description: Pointer barriers + */ + +#include "config.h" + +#include "meta/barrier.h" +#include "backends/meta-barrier-private.h" + +#include <glib-object.h> + +#include "backends/x11/meta-backend-x11.h" +#include "backends/x11/meta-barrier-x11.h" +#include "meta/meta-enum-types.h" +#include "meta/util.h" + +#ifdef HAVE_NATIVE_BACKEND +#include "backends/native/meta-backend-native.h" +#include "backends/native/meta-barrier-native.h" +#endif + +G_DEFINE_TYPE_WITH_PRIVATE (MetaBarrier, meta_barrier, G_TYPE_OBJECT) +G_DEFINE_TYPE (MetaBarrierImpl, meta_barrier_impl, G_TYPE_OBJECT) + +enum +{ + PROP_0, + + PROP_DISPLAY, + + PROP_X1, + PROP_Y1, + PROP_X2, + PROP_Y2, + PROP_DIRECTIONS, + + PROP_LAST, +}; + +static GParamSpec *obj_props[PROP_LAST]; + +enum +{ + HIT, + LEFT, + + LAST_SIGNAL, +}; + +static guint obj_signals[LAST_SIGNAL]; + + +static void +meta_barrier_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaBarrier *barrier = META_BARRIER (object); + MetaBarrierPrivate *priv = barrier->priv; + switch (prop_id) + { + case PROP_DISPLAY: + g_value_set_object (value, priv->display); + break; + case PROP_X1: + g_value_set_int (value, priv->border.line.a.x); + break; + case PROP_Y1: + g_value_set_int (value, priv->border.line.a.y); + break; + case PROP_X2: + g_value_set_int (value, priv->border.line.b.x); + break; + case PROP_Y2: + g_value_set_int (value, priv->border.line.b.y); + break; + case PROP_DIRECTIONS: + g_value_set_flags (value, + meta_border_get_allows_directions (&priv->border)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_barrier_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaBarrier *barrier = META_BARRIER (object); + MetaBarrierPrivate *priv = barrier->priv; + switch (prop_id) + { + case PROP_DISPLAY: + priv->display = g_value_get_object (value); + break; + case PROP_X1: + priv->border.line.a.x = g_value_get_int (value); + break; + case PROP_Y1: + priv->border.line.a.y = g_value_get_int (value); + break; + case PROP_X2: + priv->border.line.b.x = g_value_get_int (value); + break; + case PROP_Y2: + priv->border.line.b.y = g_value_get_int (value); + break; + case PROP_DIRECTIONS: + meta_border_set_allows_directions (&priv->border, + g_value_get_flags (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_barrier_dispose (GObject *object) +{ + MetaBarrier *barrier = META_BARRIER (object); + MetaBarrierPrivate *priv = barrier->priv; + + if (meta_barrier_is_active (barrier)) + { + meta_bug ("MetaBarrier %p was destroyed while it was still active.", + barrier); + } + + g_clear_object (&priv->impl); + + G_OBJECT_CLASS (meta_barrier_parent_class)->dispose (object); +} + +gboolean +meta_barrier_is_active (MetaBarrier *barrier) +{ + MetaBarrierImpl *impl = barrier->priv->impl; + + if (impl) + return META_BARRIER_IMPL_GET_CLASS (impl)->is_active (impl); + else + return FALSE; +} + +/** + * meta_barrier_release: + * @barrier: The barrier to release + * @event: The event to release the pointer for + * + * In XI2.3, pointer barriers provide a feature where they can + * be temporarily released so that the pointer goes through + * them. Pass a #MetaBarrierEvent to release the barrier for + * this event sequence. + */ +void +meta_barrier_release (MetaBarrier *barrier, + MetaBarrierEvent *event) +{ + MetaBarrierImpl *impl = barrier->priv->impl; + + if (impl) + META_BARRIER_IMPL_GET_CLASS (impl)->release (impl, event); +} + +static void +meta_barrier_constructed (GObject *object) +{ + MetaBarrier *barrier = META_BARRIER (object); + MetaBarrierPrivate *priv = barrier->priv; + + g_return_if_fail (priv->border.line.a.x == priv->border.line.b.x || + priv->border.line.a.y == priv->border.line.b.y); + +#if defined(HAVE_NATIVE_BACKEND) + if (META_IS_BACKEND_NATIVE (meta_get_backend ())) + priv->impl = meta_barrier_impl_native_new (barrier); +#endif + if (META_IS_BACKEND_X11 (meta_get_backend ()) && + !meta_is_wayland_compositor ()) + priv->impl = meta_barrier_impl_x11_new (barrier); + + if (priv->impl == NULL) + g_warning ("Created a non-working barrier"); + + /* Take a ref that we'll release in destroy() so that the object stays + * alive while active. */ + g_object_ref (barrier); + + G_OBJECT_CLASS (meta_barrier_parent_class)->constructed (object); +} + +static void +meta_barrier_class_init (MetaBarrierClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = meta_barrier_get_property; + object_class->set_property = meta_barrier_set_property; + object_class->dispose = meta_barrier_dispose; + object_class->constructed = meta_barrier_constructed; + + obj_props[PROP_DISPLAY] = + g_param_spec_object ("display", + "Display", + "The display to construct the pointer barrier on", + META_TYPE_DISPLAY, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + obj_props[PROP_X1] = + g_param_spec_int ("x1", + "X1", + "The first X coordinate of the barrier", + 0, G_MAXSHORT, 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + obj_props[PROP_Y1] = + g_param_spec_int ("y1", + "Y1", + "The first Y coordinate of the barrier", + 0, G_MAXSHORT, 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + obj_props[PROP_X2] = + g_param_spec_int ("x2", + "X2", + "The second X coordinate of the barrier", + 0, G_MAXSHORT, G_MAXSHORT, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + obj_props[PROP_Y2] = + g_param_spec_int ("y2", + "Y2", + "The second Y coordinate of the barrier", + 0, G_MAXSHORT, G_MAXSHORT, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + obj_props[PROP_DIRECTIONS] = + g_param_spec_flags ("directions", + "Directions", + "A set of directions to let the pointer through", + META_TYPE_BARRIER_DIRECTION, + 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, PROP_LAST, obj_props); + + /** + * MetaBarrier::hit: + * @barrier: The #MetaBarrier that was hit + * @event: A #MetaBarrierEvent that has the details of how + * the barrier was hit. + * + * When a pointer barrier is hit, this will trigger. This + * requires an XI2-enabled server. + */ + obj_signals[HIT] = + g_signal_new ("hit", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 1, + META_TYPE_BARRIER_EVENT); + + /** + * MetaBarrier::left: + * @barrier: The #MetaBarrier that was left + * @event: A #MetaBarrierEvent that has the details of how + * the barrier was left. + * + * When a pointer barrier hitbox was left, this will trigger. + * This requires an XI2-enabled server. + */ + obj_signals[LEFT] = + g_signal_new ("left", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 1, + META_TYPE_BARRIER_EVENT); +} + +void +meta_barrier_destroy (MetaBarrier *barrier) +{ + MetaBarrierImpl *impl = barrier->priv->impl; + + if (impl) + META_BARRIER_IMPL_GET_CLASS (impl)->destroy (impl); + + g_object_unref (barrier); +} + +static void +meta_barrier_init (MetaBarrier *barrier) +{ + barrier->priv = meta_barrier_get_instance_private (barrier); +} + +void +_meta_barrier_emit_hit_signal (MetaBarrier *barrier, + MetaBarrierEvent *event) +{ + g_signal_emit (barrier, obj_signals[HIT], 0, event); +} + +void +_meta_barrier_emit_left_signal (MetaBarrier *barrier, + MetaBarrierEvent *event) +{ + g_signal_emit (barrier, obj_signals[LEFT], 0, event); +} + +static void +meta_barrier_impl_class_init (MetaBarrierImplClass *klass) +{ + klass->is_active = NULL; + klass->release = NULL; + klass->destroy = NULL; +} + +static void +meta_barrier_impl_init (MetaBarrierImpl *impl) +{ +} + +static MetaBarrierEvent * +meta_barrier_event_ref (MetaBarrierEvent *event) +{ + g_return_val_if_fail (event != NULL, NULL); + g_return_val_if_fail (event->ref_count > 0, NULL); + + g_atomic_int_inc ((volatile int *)&event->ref_count); + return event; +} + +void +meta_barrier_event_unref (MetaBarrierEvent *event) +{ + g_return_if_fail (event != NULL); + g_return_if_fail (event->ref_count > 0); + + if (g_atomic_int_dec_and_test ((volatile int *)&event->ref_count)) + g_slice_free (MetaBarrierEvent, event); +} + +G_DEFINE_BOXED_TYPE (MetaBarrierEvent, + meta_barrier_event, + meta_barrier_event_ref, + meta_barrier_event_unref) diff --git a/src/backends/meta-crtc.c b/src/backends/meta-crtc.c new file mode 100644 index 000000000..7a38f5692 --- /dev/null +++ b/src/backends/meta-crtc.c @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "backends/meta-crtc.h" + +G_DEFINE_TYPE (MetaCrtc, meta_crtc, G_TYPE_OBJECT) + +G_DEFINE_TYPE (MetaCrtcMode, meta_crtc_mode, G_TYPE_OBJECT) + +MetaGpu * +meta_crtc_get_gpu (MetaCrtc *crtc) +{ + return crtc->gpu; +} + +void +meta_crtc_set_config (MetaCrtc *crtc, + graphene_rect_t *layout, + MetaCrtcMode *mode, + MetaMonitorTransform transform) +{ + MetaCrtcConfig *config; + + meta_crtc_unset_config (crtc); + + config = g_new0 (MetaCrtcConfig, 1); + config->layout = *layout; + config->mode = mode; + config->transform = transform; + + crtc->config = config; +} + +void +meta_crtc_unset_config (MetaCrtc *crtc) +{ + g_clear_pointer (&crtc->config, g_free); +} + +static void +meta_crtc_finalize (GObject *object) +{ + MetaCrtc *crtc = META_CRTC (object); + + if (crtc->driver_notify) + crtc->driver_notify (crtc); + + g_clear_pointer (&crtc->config, g_free); + + G_OBJECT_CLASS (meta_crtc_parent_class)->finalize (object); +} + +static void +meta_crtc_init (MetaCrtc *crtc) +{ +} + +static void +meta_crtc_class_init (MetaCrtcClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_crtc_finalize; +} + +static void +meta_crtc_mode_finalize (GObject *object) +{ + MetaCrtcMode *crtc_mode = META_CRTC_MODE (object); + + if (crtc_mode->driver_notify) + crtc_mode->driver_notify (crtc_mode); + + g_clear_pointer (&crtc_mode->name, g_free); + + G_OBJECT_CLASS (meta_crtc_mode_parent_class)->finalize (object); +} + +static void +meta_crtc_mode_init (MetaCrtcMode *crtc_mode) +{ +} + +static void +meta_crtc_mode_class_init (MetaCrtcModeClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_crtc_mode_finalize; +} diff --git a/src/backends/meta-crtc.h b/src/backends/meta-crtc.h new file mode 100644 index 000000000..7acab08fb --- /dev/null +++ b/src/backends/meta-crtc.h @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_CRTC_H +#define META_CRTC_H + +#include <glib-object.h> + +#include "backends/meta-backend-types.h" +#include "backends/meta-monitor-transform.h" +#include "core/util-private.h" +#include "meta/boxes.h" + +/* Same as KMS mode flags and X11 randr flags */ +typedef enum _MetaCrtcModeFlag +{ + META_CRTC_MODE_FLAG_NONE = 0, + META_CRTC_MODE_FLAG_PHSYNC = (1 << 0), + META_CRTC_MODE_FLAG_NHSYNC = (1 << 1), + META_CRTC_MODE_FLAG_PVSYNC = (1 << 2), + META_CRTC_MODE_FLAG_NVSYNC = (1 << 3), + META_CRTC_MODE_FLAG_INTERLACE = (1 << 4), + META_CRTC_MODE_FLAG_DBLSCAN = (1 << 5), + META_CRTC_MODE_FLAG_CSYNC = (1 << 6), + META_CRTC_MODE_FLAG_PCSYNC = (1 << 7), + META_CRTC_MODE_FLAG_NCSYNC = (1 << 8), + META_CRTC_MODE_FLAG_HSKEW = (1 << 9), + META_CRTC_MODE_FLAG_BCAST = (1 << 10), + META_CRTC_MODE_FLAG_PIXMUX = (1 << 11), + META_CRTC_MODE_FLAG_DBLCLK = (1 << 12), + META_CRTC_MODE_FLAG_CLKDIV2 = (1 << 13), + + META_CRTC_MODE_FLAG_MASK = 0x3fff +} MetaCrtcModeFlag; + +typedef struct _MetaCrtcConfig +{ + graphene_rect_t layout; + MetaMonitorTransform transform; + MetaCrtcMode *mode; +} MetaCrtcConfig; + +struct _MetaCrtc +{ + GObject parent; + + MetaGpu *gpu; + + glong crtc_id; + unsigned int all_transforms; + float scale; + + MetaCrtcConfig *config; + + /* Used when changing configuration */ + gboolean is_dirty; + + /* Used by cursor renderer backend */ + void *cursor_renderer_private; + + gpointer driver_private; + GDestroyNotify driver_notify; +}; + +struct _MetaCrtcMode +{ + GObject parent; + + /* The low-level ID of this mode, used to apply back configuration */ + glong mode_id; + char *name; + + int width; + int height; + float refresh_rate; + MetaCrtcModeFlag flags; + + gpointer driver_private; + GDestroyNotify driver_notify; +}; + +#define META_TYPE_CRTC (meta_crtc_get_type ()) +META_EXPORT_TEST G_DECLARE_FINAL_TYPE (MetaCrtc, meta_crtc, META, CRTC, GObject) + +#define META_TYPE_CRTC_MODE (meta_crtc_mode_get_type ()) +META_EXPORT_TEST G_DECLARE_FINAL_TYPE (MetaCrtcMode, meta_crtc_mode, META, CRTC_MODE, GObject) + +MetaGpu * meta_crtc_get_gpu (MetaCrtc *crtc); + +META_EXPORT_TEST +void meta_crtc_set_config (MetaCrtc *crtc, + graphene_rect_t *layout, + MetaCrtcMode *mode, + MetaMonitorTransform transform); + +META_EXPORT_TEST +void meta_crtc_unset_config (MetaCrtc *crtc); + +#endif /* META_CRTC_H */ diff --git a/src/backends/meta-cursor-renderer.c b/src/backends/meta-cursor-renderer.c new file mode 100644 index 000000000..b342a98f3 --- /dev/null +++ b/src/backends/meta-cursor-renderer.c @@ -0,0 +1,378 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jasper St. Pierre <jstpierre@mecheye.net> + */ + +#include "config.h" + +#include "backends/meta-cursor-renderer.h" + +#include <math.h> + +#include "backends/meta-stage-private.h" +#include "clutter/clutter.h" +#include "clutter/clutter-mutter.h" +#include "cogl/cogl.h" +#include "meta/meta-backend.h" +#include "meta/util.h" + +G_DEFINE_INTERFACE (MetaHwCursorInhibitor, meta_hw_cursor_inhibitor, + G_TYPE_OBJECT) + +struct _MetaCursorRendererPrivate +{ + float current_x; + float current_y; + + MetaCursorSprite *displayed_cursor; + MetaOverlay *stage_overlay; + gboolean handled_by_backend; + guint post_paint_func_id; + + GList *hw_cursor_inhibitors; +}; +typedef struct _MetaCursorRendererPrivate MetaCursorRendererPrivate; + +enum +{ + CURSOR_PAINTED, + LAST_SIGNAL +}; +static guint signals[LAST_SIGNAL]; + +G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorRenderer, meta_cursor_renderer, G_TYPE_OBJECT); + +static gboolean +meta_hw_cursor_inhibitor_is_cursor_sprite_inhibited (MetaHwCursorInhibitor *inhibitor, + MetaCursorSprite *cursor_sprite) +{ + MetaHwCursorInhibitorInterface *iface = + META_HW_CURSOR_INHIBITOR_GET_IFACE (inhibitor); + + return iface->is_cursor_sprite_inhibited (inhibitor, cursor_sprite); +} + +static void +meta_hw_cursor_inhibitor_default_init (MetaHwCursorInhibitorInterface *iface) +{ +} + +void +meta_cursor_renderer_emit_painted (MetaCursorRenderer *renderer, + MetaCursorSprite *cursor_sprite) +{ + g_signal_emit (renderer, signals[CURSOR_PAINTED], 0, cursor_sprite); +} + +static void +align_cursor_position (MetaCursorRenderer *renderer, + graphene_rect_t *rect) +{ + MetaCursorRendererPrivate *priv = + meta_cursor_renderer_get_instance_private (renderer); + MetaBackend *backend = meta_get_backend (); + ClutterActor *stage = meta_backend_get_stage (backend); + ClutterStageView *view; + cairo_rectangle_int_t view_layout; + float view_scale; + + view = clutter_stage_get_view_at (CLUTTER_STAGE (stage), + priv->current_x, + priv->current_y); + if (!view) + return; + + clutter_stage_view_get_layout (view, &view_layout); + view_scale = clutter_stage_view_get_scale (view); + + graphene_rect_offset (rect, -view_layout.x, -view_layout.y); + rect->origin.x = floorf (rect->origin.x * view_scale) / view_scale; + rect->origin.y = floorf (rect->origin.y * view_scale) / view_scale; + graphene_rect_offset (rect, view_layout.x, view_layout.y); +} + +static void +queue_redraw (MetaCursorRenderer *renderer, + MetaCursorSprite *cursor_sprite) +{ + MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer); + MetaBackend *backend = meta_get_backend (); + ClutterActor *stage = meta_backend_get_stage (backend); + CoglTexture *texture; + graphene_rect_t rect = GRAPHENE_RECT_INIT_ZERO; + + /* During early initialization, we can have no stage */ + if (!stage) + return; + + if (cursor_sprite) + { + rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite); + align_cursor_position (renderer, &rect); + } + + if (!priv->stage_overlay) + priv->stage_overlay = meta_stage_create_cursor_overlay (META_STAGE (stage)); + + if (cursor_sprite && !priv->handled_by_backend) + texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite); + else + texture = NULL; + + meta_stage_update_cursor_overlay (META_STAGE (stage), priv->stage_overlay, + texture, &rect); +} + +static gboolean +meta_cursor_renderer_post_paint (gpointer data) +{ + MetaCursorRenderer *renderer = META_CURSOR_RENDERER (data); + MetaCursorRendererPrivate *priv = + meta_cursor_renderer_get_instance_private (renderer); + + if (priv->displayed_cursor && !priv->handled_by_backend) + meta_cursor_renderer_emit_painted (renderer, priv->displayed_cursor); + + return TRUE; +} + +static gboolean +meta_cursor_renderer_real_update_cursor (MetaCursorRenderer *renderer, + MetaCursorSprite *cursor_sprite) +{ + if (cursor_sprite) + meta_cursor_sprite_realize_texture (cursor_sprite); + + return FALSE; +} + +static void +meta_cursor_renderer_finalize (GObject *object) +{ + MetaCursorRenderer *renderer = META_CURSOR_RENDERER (object); + MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer); + MetaBackend *backend = meta_get_backend (); + ClutterActor *stage = meta_backend_get_stage (backend); + + if (priv->stage_overlay) + meta_stage_remove_cursor_overlay (META_STAGE (stage), priv->stage_overlay); + + clutter_threads_remove_repaint_func (priv->post_paint_func_id); + + G_OBJECT_CLASS (meta_cursor_renderer_parent_class)->finalize (object); +} + +static void +meta_cursor_renderer_class_init (MetaCursorRendererClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_cursor_renderer_finalize; + klass->update_cursor = meta_cursor_renderer_real_update_cursor; + + signals[CURSOR_PAINTED] = g_signal_new ("cursor-painted", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 1, + G_TYPE_POINTER); +} + +static void +meta_cursor_renderer_init (MetaCursorRenderer *renderer) +{ + MetaCursorRendererPrivate *priv = + meta_cursor_renderer_get_instance_private (renderer); + + priv->post_paint_func_id = + clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_POST_PAINT, + meta_cursor_renderer_post_paint, + renderer, + NULL); +} + +graphene_rect_t +meta_cursor_renderer_calculate_rect (MetaCursorRenderer *renderer, + MetaCursorSprite *cursor_sprite) +{ + MetaCursorRendererPrivate *priv = + meta_cursor_renderer_get_instance_private (renderer); + CoglTexture *texture; + int hot_x, hot_y; + int width, height; + float texture_scale; + + texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite); + if (!texture) + return (graphene_rect_t) GRAPHENE_RECT_INIT_ZERO; + + meta_cursor_sprite_get_hotspot (cursor_sprite, &hot_x, &hot_y); + texture_scale = meta_cursor_sprite_get_texture_scale (cursor_sprite); + width = cogl_texture_get_width (texture); + height = cogl_texture_get_height (texture); + + return (graphene_rect_t) { + .origin = { + .x = priv->current_x - (hot_x * texture_scale), + .y = priv->current_y - (hot_y * texture_scale) + }, + .size = { + .width = width * texture_scale, + .height = height * texture_scale + } + }; +} + +static void +meta_cursor_renderer_update_cursor (MetaCursorRenderer *renderer, + MetaCursorSprite *cursor_sprite) +{ + MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer); + gboolean handled_by_backend; + gboolean should_redraw = FALSE; + + if (cursor_sprite) + meta_cursor_sprite_prepare_at (cursor_sprite, + (int) priv->current_x, + (int) priv->current_y); + + handled_by_backend = + META_CURSOR_RENDERER_GET_CLASS (renderer)->update_cursor (renderer, + cursor_sprite); + if (handled_by_backend != priv->handled_by_backend) + { + priv->handled_by_backend = handled_by_backend; + should_redraw = TRUE; + } + + if (!handled_by_backend) + should_redraw = TRUE; + + if (should_redraw) + queue_redraw (renderer, cursor_sprite); +} + +MetaCursorRenderer * +meta_cursor_renderer_new (void) +{ + return g_object_new (META_TYPE_CURSOR_RENDERER, NULL); +} + +void +meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer, + MetaCursorSprite *cursor_sprite) +{ + MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer); + + if (priv->displayed_cursor == cursor_sprite) + return; + priv->displayed_cursor = cursor_sprite; + + meta_cursor_renderer_update_cursor (renderer, cursor_sprite); +} + +void +meta_cursor_renderer_force_update (MetaCursorRenderer *renderer) +{ + MetaCursorRendererPrivate *priv = + meta_cursor_renderer_get_instance_private (renderer); + + meta_cursor_renderer_update_cursor (renderer, priv->displayed_cursor); +} + +void +meta_cursor_renderer_set_position (MetaCursorRenderer *renderer, + float x, + float y) +{ + MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer); + + g_assert (meta_is_wayland_compositor ()); + + priv->current_x = x; + priv->current_y = y; + + meta_cursor_renderer_update_cursor (renderer, priv->displayed_cursor); +} + +graphene_point_t +meta_cursor_renderer_get_position (MetaCursorRenderer *renderer) +{ + MetaCursorRendererPrivate *priv = + meta_cursor_renderer_get_instance_private (renderer); + + return (graphene_point_t) { + .x = priv->current_x, + .y = priv->current_y + }; +} + +MetaCursorSprite * +meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer) +{ + MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer); + + return priv->displayed_cursor; +} + +void +meta_cursor_renderer_add_hw_cursor_inhibitor (MetaCursorRenderer *renderer, + MetaHwCursorInhibitor *inhibitor) +{ + MetaCursorRendererPrivate *priv = + meta_cursor_renderer_get_instance_private (renderer); + + priv->hw_cursor_inhibitors = g_list_prepend (priv->hw_cursor_inhibitors, + inhibitor); +} + +void +meta_cursor_renderer_remove_hw_cursor_inhibitor (MetaCursorRenderer *renderer, + MetaHwCursorInhibitor *inhibitor) +{ + MetaCursorRendererPrivate *priv = + meta_cursor_renderer_get_instance_private (renderer); + + priv->hw_cursor_inhibitors = g_list_remove (priv->hw_cursor_inhibitors, + inhibitor); +} + +gboolean +meta_cursor_renderer_is_hw_cursors_inhibited (MetaCursorRenderer *renderer, + MetaCursorSprite *cursor_sprite) +{ + MetaCursorRendererPrivate *priv = + meta_cursor_renderer_get_instance_private (renderer); + GList *l; + + for (l = priv->hw_cursor_inhibitors; l; l = l->next) + { + MetaHwCursorInhibitor *inhibitor = l->data; + + if (meta_hw_cursor_inhibitor_is_cursor_sprite_inhibited (inhibitor, + cursor_sprite)) + return TRUE; + } + + return FALSE; +} diff --git a/src/backends/meta-cursor-renderer.h b/src/backends/meta-cursor-renderer.h new file mode 100644 index 000000000..852551355 --- /dev/null +++ b/src/backends/meta-cursor-renderer.h @@ -0,0 +1,85 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jasper St. Pierre <jstpierre@mecheye.net> + */ + +#ifndef META_CURSOR_RENDERER_H +#define META_CURSOR_RENDERER_H + +#include <glib-object.h> + +#include "backends/meta-backend-types.h" +#include "backends/meta-cursor.h" + +#define META_TYPE_HW_CURSOR_INHIBITOR (meta_hw_cursor_inhibitor_get_type ()) +G_DECLARE_INTERFACE (MetaHwCursorInhibitor, meta_hw_cursor_inhibitor, + META, HW_CURSOR_INHIBITOR, GObject) + +struct _MetaHwCursorInhibitorInterface +{ + GTypeInterface parent_iface; + + gboolean (* is_cursor_sprite_inhibited) (MetaHwCursorInhibitor *inhibitor, + MetaCursorSprite *cursor_sprite); +}; + +#define META_TYPE_CURSOR_RENDERER (meta_cursor_renderer_get_type ()) +G_DECLARE_DERIVABLE_TYPE (MetaCursorRenderer, meta_cursor_renderer, + META, CURSOR_RENDERER, GObject); + +struct _MetaCursorRendererClass +{ + GObjectClass parent_class; + + gboolean (* update_cursor) (MetaCursorRenderer *renderer, + MetaCursorSprite *cursor_sprite); +}; + +MetaCursorRenderer * meta_cursor_renderer_new (void); + +void meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer, + MetaCursorSprite *cursor_sprite); + +void meta_cursor_renderer_set_position (MetaCursorRenderer *renderer, + float x, + float y); +graphene_point_t meta_cursor_renderer_get_position (MetaCursorRenderer *renderer); +void meta_cursor_renderer_force_update (MetaCursorRenderer *renderer); + +MetaCursorSprite * meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer); + +void meta_cursor_renderer_add_hw_cursor_inhibitor (MetaCursorRenderer *renderer, + MetaHwCursorInhibitor *inhibitor); + +void meta_cursor_renderer_remove_hw_cursor_inhibitor (MetaCursorRenderer *renderer, + MetaHwCursorInhibitor *inhibitor); + +gboolean meta_cursor_renderer_is_hw_cursors_inhibited (MetaCursorRenderer *renderer, + MetaCursorSprite *cursor_sprite); + +graphene_rect_t meta_cursor_renderer_calculate_rect (MetaCursorRenderer *renderer, + MetaCursorSprite *cursor_sprite); + +void meta_cursor_renderer_emit_painted (MetaCursorRenderer *renderer, + MetaCursorSprite *cursor_sprite); + +#endif /* META_CURSOR_RENDERER_H */ diff --git a/src/backends/meta-cursor-sprite-xcursor.c b/src/backends/meta-cursor-sprite-xcursor.c new file mode 100644 index 000000000..df49b7ab8 --- /dev/null +++ b/src/backends/meta-cursor-sprite-xcursor.c @@ -0,0 +1,322 @@ +/* + * Copyright 2013, 2018 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include "backends/meta-cursor-sprite-xcursor.h" + +#include "backends/meta-cursor.h" +#include "backends/meta-cursor-renderer.h" +#include "clutter/clutter.h" +#include "cogl/cogl.h" +#include "meta/prefs.h" +#include "meta/util.h" + +struct _MetaCursorSpriteXcursor +{ + MetaCursorSprite parent; + + MetaCursor cursor; + + int current_frame; + XcursorImages *xcursor_images; + + int theme_scale; + gboolean theme_dirty; +}; + +G_DEFINE_TYPE (MetaCursorSpriteXcursor, meta_cursor_sprite_xcursor, + META_TYPE_CURSOR_SPRITE) + +static const char * +translate_meta_cursor (MetaCursor cursor) +{ + switch (cursor) + { + case META_CURSOR_DEFAULT: + return "left_ptr"; + case META_CURSOR_NORTH_RESIZE: + return "top_side"; + case META_CURSOR_SOUTH_RESIZE: + return "bottom_side"; + case META_CURSOR_WEST_RESIZE: + return "left_side"; + case META_CURSOR_EAST_RESIZE: + return "right_side"; + case META_CURSOR_SE_RESIZE: + return "bottom_right_corner"; + case META_CURSOR_SW_RESIZE: + return "bottom_left_corner"; + case META_CURSOR_NE_RESIZE: + return "top_right_corner"; + case META_CURSOR_NW_RESIZE: + return "top_left_corner"; + case META_CURSOR_MOVE_OR_RESIZE_WINDOW: + return "fleur"; + case META_CURSOR_BUSY: + return "watch"; + case META_CURSOR_DND_IN_DRAG: + return "dnd-none"; + case META_CURSOR_DND_MOVE: + return "dnd-move"; + case META_CURSOR_DND_COPY: + return "dnd-copy"; + case META_CURSOR_DND_UNSUPPORTED_TARGET: + return "dnd-none"; + case META_CURSOR_POINTING_HAND: + return "hand2"; + case META_CURSOR_CROSSHAIR: + return "crosshair"; + case META_CURSOR_IBEAM: + return "xterm"; + case META_CURSOR_NONE: + case META_CURSOR_LAST: + break; + } + + g_assert_not_reached (); + return NULL; +} + +MetaCursor +meta_cursor_sprite_xcursor_get_cursor (MetaCursorSpriteXcursor *sprite_xcursor) +{ + return sprite_xcursor->cursor; +} + +Cursor +meta_create_x_cursor (Display *xdisplay, + MetaCursor cursor) +{ + return XcursorLibraryLoadCursor (xdisplay, translate_meta_cursor (cursor)); +} + +static XcursorImages * +load_cursor_on_client (MetaCursor cursor, int scale) +{ + XcursorImages *xcursor_images; + int fallback_size; + + xcursor_images = + XcursorLibraryLoadImages (translate_meta_cursor (cursor), + meta_prefs_get_cursor_theme (), + meta_prefs_get_cursor_size () * scale); + if (xcursor_images) + return xcursor_images; + + g_warning ("No cursor theme available, please install a cursor theme"); + + fallback_size = 24 * scale; + xcursor_images = XcursorImagesCreate (1); + xcursor_images->images[0] = XcursorImageCreate (fallback_size, fallback_size); + xcursor_images->images[0]->xhot = 0; + xcursor_images->images[0]->yhot = 0; + memset (xcursor_images->images[0]->pixels, 0xc0, + fallback_size * fallback_size * sizeof (int32_t)); + return xcursor_images; +} + +static void +load_from_current_xcursor_image (MetaCursorSpriteXcursor *sprite_xcursor) +{ + MetaCursorSprite *sprite = META_CURSOR_SPRITE (sprite_xcursor); + XcursorImage *xc_image; + int width, height, rowstride; + CoglPixelFormat cogl_format; + ClutterBackend *clutter_backend; + CoglContext *cogl_context; + CoglTexture2D *texture; + GError *error = NULL; + int hotspot_x, hotspot_y; + + g_assert (!meta_cursor_sprite_get_cogl_texture (sprite)); + + xc_image = meta_cursor_sprite_xcursor_get_current_image (sprite_xcursor); + width = (int) xc_image->width; + height = (int) xc_image->height; + rowstride = width * 4; + +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + cogl_format = COGL_PIXEL_FORMAT_BGRA_8888; +#else + cogl_format = COGL_PIXEL_FORMAT_ARGB_8888; +#endif + + clutter_backend = clutter_get_default_backend (); + cogl_context = clutter_backend_get_cogl_context (clutter_backend); + texture = cogl_texture_2d_new_from_data (cogl_context, + width, height, + cogl_format, + rowstride, + (uint8_t *) xc_image->pixels, + &error); + if (!texture) + { + g_warning ("Failed to allocate cursor texture: %s\n", error->message); + g_error_free (error); + } + + if (meta_is_wayland_compositor ()) + { + hotspot_x = ((int) (xc_image->xhot / sprite_xcursor->theme_scale) * + sprite_xcursor->theme_scale); + hotspot_y = ((int) (xc_image->yhot / sprite_xcursor->theme_scale) * + sprite_xcursor->theme_scale); + } + else + { + hotspot_x = xc_image->xhot; + hotspot_y = xc_image->yhot; + } + meta_cursor_sprite_set_texture (sprite, + COGL_TEXTURE (texture), + hotspot_x, hotspot_y); + + g_clear_pointer (&texture, cogl_object_unref); +} + +void +meta_cursor_sprite_xcursor_set_theme_scale (MetaCursorSpriteXcursor *sprite_xcursor, + int theme_scale) +{ + if (sprite_xcursor->theme_scale != theme_scale) + sprite_xcursor->theme_dirty = TRUE; + sprite_xcursor->theme_scale = theme_scale; +} + +static gboolean +meta_cursor_sprite_xcursor_is_animated (MetaCursorSprite *sprite) +{ + MetaCursorSpriteXcursor *sprite_xcursor = META_CURSOR_SPRITE_XCURSOR (sprite); + + return (sprite_xcursor->xcursor_images && + sprite_xcursor->xcursor_images->nimage > 1); +} + +XcursorImage * +meta_cursor_sprite_xcursor_get_current_image (MetaCursorSpriteXcursor *sprite_xcursor) +{ + return sprite_xcursor->xcursor_images->images[sprite_xcursor->current_frame]; +} + +static void +meta_cursor_sprite_xcursor_tick_frame (MetaCursorSprite *sprite) +{ + MetaCursorSpriteXcursor *sprite_xcursor = META_CURSOR_SPRITE_XCURSOR (sprite); + + if (!meta_cursor_sprite_is_animated (sprite)) + return; + + sprite_xcursor->current_frame++; + + if (sprite_xcursor->current_frame >= sprite_xcursor->xcursor_images->nimage) + sprite_xcursor->current_frame = 0; + + meta_cursor_sprite_clear_texture (sprite); + load_from_current_xcursor_image (sprite_xcursor); +} + +static unsigned int +meta_cursor_sprite_xcursor_get_current_frame_time (MetaCursorSprite *sprite) +{ + MetaCursorSpriteXcursor *sprite_xcursor = META_CURSOR_SPRITE_XCURSOR (sprite); + XcursorImages *xcursor_images; + + g_return_val_if_fail (meta_cursor_sprite_is_animated (sprite), 0); + + xcursor_images = sprite_xcursor->xcursor_images; + return xcursor_images->images[sprite_xcursor->current_frame]->delay; +} + +static void +load_cursor_from_theme (MetaCursorSprite *sprite) +{ + MetaCursorSpriteXcursor *sprite_xcursor = META_CURSOR_SPRITE_XCURSOR (sprite); + + g_assert (sprite_xcursor->cursor != META_CURSOR_NONE); + + sprite_xcursor->theme_dirty = FALSE; + + /* We might be reloading with a different scale. If so clear the old data. */ + if (sprite_xcursor->xcursor_images) + { + meta_cursor_sprite_clear_texture (sprite); + XcursorImagesDestroy (sprite_xcursor->xcursor_images); + } + + sprite_xcursor->current_frame = 0; + sprite_xcursor->xcursor_images = + load_cursor_on_client (sprite_xcursor->cursor, + sprite_xcursor->theme_scale); + + load_from_current_xcursor_image (sprite_xcursor); +} + +static void +meta_cursor_sprite_xcursor_realize_texture (MetaCursorSprite *sprite) +{ + MetaCursorSpriteXcursor *sprite_xcursor = META_CURSOR_SPRITE_XCURSOR (sprite); + + if (sprite_xcursor->theme_dirty) + load_cursor_from_theme (sprite); +} + +MetaCursorSpriteXcursor * +meta_cursor_sprite_xcursor_new (MetaCursor cursor) +{ + MetaCursorSpriteXcursor *sprite_xcursor; + + sprite_xcursor = g_object_new (META_TYPE_CURSOR_SPRITE_XCURSOR, NULL); + sprite_xcursor->cursor = cursor; + + return sprite_xcursor; +} + +static void +meta_cursor_sprite_xcursor_finalize (GObject *object) +{ + MetaCursorSpriteXcursor *sprite_xcursor = META_CURSOR_SPRITE_XCURSOR (object); + + g_clear_pointer (&sprite_xcursor->xcursor_images, + XcursorImagesDestroy); + + G_OBJECT_CLASS (meta_cursor_sprite_xcursor_parent_class)->finalize (object); +} + +static void +meta_cursor_sprite_xcursor_init (MetaCursorSpriteXcursor *sprite_xcursor) +{ + sprite_xcursor->theme_scale = 1; + sprite_xcursor->theme_dirty = TRUE; +} + +static void +meta_cursor_sprite_xcursor_class_init (MetaCursorSpriteXcursorClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MetaCursorSpriteClass *cursor_sprite_class = META_CURSOR_SPRITE_CLASS (klass); + + object_class->finalize = meta_cursor_sprite_xcursor_finalize; + + cursor_sprite_class->realize_texture = + meta_cursor_sprite_xcursor_realize_texture; + cursor_sprite_class->is_animated = meta_cursor_sprite_xcursor_is_animated; + cursor_sprite_class->tick_frame = meta_cursor_sprite_xcursor_tick_frame; + cursor_sprite_class->get_current_frame_time = + meta_cursor_sprite_xcursor_get_current_frame_time; +} diff --git a/src/backends/meta-cursor-sprite-xcursor.h b/src/backends/meta-cursor-sprite-xcursor.h new file mode 100644 index 000000000..dbc927484 --- /dev/null +++ b/src/backends/meta-cursor-sprite-xcursor.h @@ -0,0 +1,43 @@ +/* + * Copyright 2013, 2018 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + */ + +#ifndef META_CURSOR_SPRITE_XCURSOR_H +#define META_CURSOR_SPRITE_XCURSOR_H + +#include <glib-object.h> +#include <X11/Xcursor/Xcursor.h> + +#include "backends/meta-cursor.h" + +#define META_TYPE_CURSOR_SPRITE_XCURSOR meta_cursor_sprite_xcursor_get_type () +G_DECLARE_FINAL_TYPE (MetaCursorSpriteXcursor, meta_cursor_sprite_xcursor, + META, CURSOR_SPRITE_XCURSOR, MetaCursorSprite) + +MetaCursorSpriteXcursor * meta_cursor_sprite_xcursor_new (MetaCursor cursor); + +void meta_cursor_sprite_xcursor_set_theme_scale (MetaCursorSpriteXcursor *sprite_xcursor, + int scale); + +MetaCursor meta_cursor_sprite_xcursor_get_cursor (MetaCursorSpriteXcursor *sprite_xcusror); + +XcursorImage * meta_cursor_sprite_xcursor_get_current_image (MetaCursorSpriteXcursor *sprite_xcursor); + +Cursor meta_create_x_cursor (Display *xdisplay, + MetaCursor cursor); + +#endif /* META_CURSOR_SPRITE_XCURSOR_H */ diff --git a/src/backends/meta-cursor-tracker-private.h b/src/backends/meta-cursor-tracker-private.h new file mode 100644 index 000000000..29ee94044 --- /dev/null +++ b/src/backends/meta-cursor-tracker-private.h @@ -0,0 +1,67 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright 2013 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: Giovanni Campagna <gcampagn@redhat.com> + */ + +#ifndef META_CURSOR_TRACKER_PRIVATE_H +#define META_CURSOR_TRACKER_PRIVATE_H + +#include "backends/meta-cursor.h" +#include "backends/meta-cursor-renderer.h" +#include "backends/x11/cm/meta-cursor-sprite-xfixes.h" +#include "meta/meta-cursor-tracker.h" + +struct _MetaCursorTracker { + GObject parent_instance; + + gboolean is_showing; + + MetaCursorSprite *effective_cursor; /* May be NULL when hidden */ + MetaCursorSprite *displayed_cursor; + + /* Wayland clients can set a NULL buffer as their cursor + * explicitly, which means that we shouldn't display anything. + * So, we can't simply store a NULL in window_cursor to + * determine an unset window cursor; we need an extra boolean. + */ + gboolean has_window_cursor; + MetaCursorSprite *window_cursor; + + MetaCursorSprite *root_cursor; + + /* The cursor from the X11 server. */ + MetaCursorSpriteXfixes *xfixes_cursor; +}; + +gboolean meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker, + XEvent *xevent); + +void meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker, + MetaCursorSprite *cursor_sprite); +void meta_cursor_tracker_unset_window_cursor (MetaCursorTracker *tracker); +void meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker, + MetaCursorSprite *cursor_sprite); + +void meta_cursor_tracker_update_position (MetaCursorTracker *tracker, + float new_x, + float new_y); + +MetaCursorSprite * meta_cursor_tracker_get_displayed_cursor (MetaCursorTracker *tracker); + +#endif diff --git a/src/backends/meta-cursor-tracker.c b/src/backends/meta-cursor-tracker.c new file mode 100644 index 000000000..c2dff032e --- /dev/null +++ b/src/backends/meta-cursor-tracker.c @@ -0,0 +1,464 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright 2013 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: Giovanni Campagna <gcampagn@redhat.com> + */ + +/** + * SECTION:cursor-tracker + * @title: MetaCursorTracker + * @short_description: Mutter cursor tracking helper. Originally only + * tracking the cursor image, now more of a "core + * pointer abstraction" + */ + +#include "config.h" + +#include "backends/meta-cursor-tracker-private.h" + +#include <gdk/gdk.h> +#include <gdk/gdkx.h> +#include <string.h> + +#include "backends/meta-backend-private.h" +#include "backends/x11/cm/meta-cursor-sprite-xfixes.h" +#include "cogl/cogl.h" +#include "clutter/clutter.h" +#include "meta-marshal.h" +#include "meta/main.h" +#include "meta/meta-x11-errors.h" +#include "meta/util.h" +#include "x11/meta-x11-display-private.h" + +G_DEFINE_TYPE (MetaCursorTracker, meta_cursor_tracker, G_TYPE_OBJECT); + +enum +{ + CURSOR_CHANGED, + CURSOR_MOVED, + VISIBILITY_CHANGED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL]; + +static void +cursor_texture_updated (MetaCursorSprite *cursor, + MetaCursorTracker *tracker) +{ + g_signal_emit (tracker, signals[CURSOR_CHANGED], 0); +} + +static gboolean +update_displayed_cursor (MetaCursorTracker *tracker) +{ + MetaDisplay *display = meta_get_display (); + MetaCursorSprite *cursor = NULL; + + if (display && meta_display_windows_are_interactable (display) && + tracker->has_window_cursor) + cursor = tracker->window_cursor; + else + cursor = tracker->root_cursor; + + if (tracker->displayed_cursor == cursor) + return FALSE; + + if (tracker->displayed_cursor) + { + g_signal_handlers_disconnect_by_func (tracker->displayed_cursor, + cursor_texture_updated, + tracker); + } + + g_set_object (&tracker->displayed_cursor, cursor); + + if (cursor) + { + g_signal_connect (cursor, "texture-changed", + G_CALLBACK (cursor_texture_updated), tracker); + } + + return TRUE; +} + +static gboolean +update_effective_cursor (MetaCursorTracker *tracker) +{ + MetaCursorSprite *cursor = NULL; + + if (tracker->is_showing) + cursor = tracker->displayed_cursor; + + return g_set_object (&tracker->effective_cursor, cursor); +} + +static void +change_cursor_renderer (MetaCursorTracker *tracker) +{ + MetaBackend *backend = meta_get_backend (); + MetaCursorRenderer *cursor_renderer = + meta_backend_get_cursor_renderer (backend); + + meta_cursor_renderer_set_cursor (cursor_renderer, tracker->effective_cursor); +} + +static void +sync_cursor (MetaCursorTracker *tracker) +{ + gboolean cursor_changed = FALSE; + + cursor_changed = update_displayed_cursor (tracker); + + if (update_effective_cursor (tracker)) + change_cursor_renderer (tracker); + + if (cursor_changed) + g_signal_emit (tracker, signals[CURSOR_CHANGED], 0); +} + +static void +meta_cursor_tracker_init (MetaCursorTracker *self) +{ + self->is_showing = TRUE; +} + +static void +meta_cursor_tracker_finalize (GObject *object) +{ + MetaCursorTracker *self = META_CURSOR_TRACKER (object); + + if (self->effective_cursor) + g_object_unref (self->effective_cursor); + if (self->displayed_cursor) + g_object_unref (self->displayed_cursor); + if (self->root_cursor) + g_object_unref (self->root_cursor); + + G_OBJECT_CLASS (meta_cursor_tracker_parent_class)->finalize (object); +} + +static void +meta_cursor_tracker_class_init (MetaCursorTrackerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_cursor_tracker_finalize; + + signals[CURSOR_CHANGED] = g_signal_new ("cursor-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); + + /** + * MetaCursorTracker::cursor-moved: + * @cursor: The #MetaCursorTracker + * @x: The new X coordinate of the cursor + * @y: The new Y coordinate of the cursor + * + * Notifies when the cursor has moved to a new location. + */ + signals[CURSOR_MOVED] = g_signal_new ("cursor-moved", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + meta_marshal_VOID__FLOAT_FLOAT, + G_TYPE_NONE, 2, + G_TYPE_FLOAT, + G_TYPE_FLOAT); + g_signal_set_va_marshaller (signals[CURSOR_MOVED], + G_TYPE_FROM_CLASS (klass), + meta_marshal_VOID__FLOAT_FLOATv); + + signals[VISIBILITY_CHANGED] = g_signal_new ("visibility-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 0); +} + +/** + * meta_cursor_tracker_get_for_display: + * @display: the #MetaDisplay + * + * Retrieves the cursor tracker object for @display. + * + * Returns: (transfer none): + */ +MetaCursorTracker * +meta_cursor_tracker_get_for_display (MetaDisplay *display) +{ + MetaBackend *backend = meta_get_backend (); + MetaCursorTracker *tracker = meta_backend_get_cursor_tracker (backend); + + g_assert (tracker); + + return tracker; +} + +static void +set_window_cursor (MetaCursorTracker *tracker, + gboolean has_cursor, + MetaCursorSprite *cursor_sprite) +{ + g_clear_object (&tracker->window_cursor); + if (cursor_sprite) + tracker->window_cursor = g_object_ref (cursor_sprite); + tracker->has_window_cursor = has_cursor; + sync_cursor (tracker); +} + +gboolean +meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker, + XEvent *xevent) +{ + MetaX11Display *x11_display = meta_get_display ()->x11_display; + XFixesCursorNotifyEvent *notify_event; + + if (meta_is_wayland_compositor ()) + return FALSE; + + if (xevent->xany.type != x11_display->xfixes_event_base + XFixesCursorNotify) + return FALSE; + + notify_event = (XFixesCursorNotifyEvent *)xevent; + if (notify_event->subtype != XFixesDisplayCursorNotify) + return FALSE; + + g_clear_object (&tracker->xfixes_cursor); + g_signal_emit (tracker, signals[CURSOR_CHANGED], 0); + + return TRUE; +} + +static void +ensure_xfixes_cursor (MetaCursorTracker *tracker) +{ + MetaDisplay *display = meta_get_display (); + g_autoptr (GError) error = NULL; + + if (tracker->xfixes_cursor) + return; + + tracker->xfixes_cursor = meta_cursor_sprite_xfixes_new (display, &error); + if (!tracker->xfixes_cursor) + g_warning ("Failed to create XFIXES cursor: %s", error->message); +} + +/** + * meta_cursor_tracker_get_sprite: + * + * Returns: (transfer none): + */ +CoglTexture * +meta_cursor_tracker_get_sprite (MetaCursorTracker *tracker) +{ + MetaCursorSprite *cursor_sprite; + + g_return_val_if_fail (META_IS_CURSOR_TRACKER (tracker), NULL); + + if (meta_is_wayland_compositor ()) + { + cursor_sprite = tracker->displayed_cursor; + } + else + { + ensure_xfixes_cursor (tracker); + cursor_sprite = META_CURSOR_SPRITE (tracker->xfixes_cursor); + } + + if (cursor_sprite) + { + meta_cursor_sprite_realize_texture (cursor_sprite); + return meta_cursor_sprite_get_cogl_texture (cursor_sprite); + } + else + { + return NULL; + } +} + +/** + * meta_cursor_tracker_get_hot: + * @tracker: + * @x: (out): + * @y: (out): + * + */ +void +meta_cursor_tracker_get_hot (MetaCursorTracker *tracker, + int *x, + int *y) +{ + MetaCursorSprite *cursor_sprite; + + g_return_if_fail (META_IS_CURSOR_TRACKER (tracker)); + + if (meta_is_wayland_compositor ()) + { + cursor_sprite = tracker->displayed_cursor; + } + else + { + ensure_xfixes_cursor (tracker); + cursor_sprite = META_CURSOR_SPRITE (tracker->xfixes_cursor); + } + + if (cursor_sprite) + meta_cursor_sprite_get_hotspot (cursor_sprite, x, y); + else + { + if (x) + *x = 0; + if (y) + *y = 0; + } +} + +void +meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker, + MetaCursorSprite *cursor_sprite) +{ + set_window_cursor (tracker, TRUE, cursor_sprite); +} + +void +meta_cursor_tracker_unset_window_cursor (MetaCursorTracker *tracker) +{ + set_window_cursor (tracker, FALSE, NULL); +} + +/** + * meta_cursor_tracker_set_root_cursor: + * @tracker: a #MetaCursorTracker object. + * @cursor_sprite: (transfer none): the new root cursor + * + * Sets the root cursor (the cursor that is shown if not modified by a window). + * The #MetaCursorTracker will take a strong reference to the sprite. + */ +void +meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker, + MetaCursorSprite *cursor_sprite) +{ + g_clear_object (&tracker->root_cursor); + if (cursor_sprite) + tracker->root_cursor = g_object_ref (cursor_sprite); + + sync_cursor (tracker); +} + +void +meta_cursor_tracker_update_position (MetaCursorTracker *tracker, + float new_x, + float new_y) +{ + MetaBackend *backend = meta_get_backend (); + MetaCursorRenderer *cursor_renderer = + meta_backend_get_cursor_renderer (backend); + + g_assert (meta_is_wayland_compositor ()); + + meta_cursor_renderer_set_position (cursor_renderer, new_x, new_y); + + g_signal_emit (tracker, signals[CURSOR_MOVED], 0, new_x, new_y); +} + +static void +get_pointer_position_gdk (int *x, + int *y, + int *mods) +{ + GdkSeat *gseat; + GdkDevice *gdevice; + GdkScreen *gscreen; + + gseat = gdk_display_get_default_seat (gdk_display_get_default ()); + gdevice = gdk_seat_get_pointer (gseat); + + gdk_device_get_position (gdevice, &gscreen, x, y); + if (mods) + gdk_device_get_state (gdevice, + gdk_screen_get_root_window (gscreen), + NULL, (GdkModifierType*)mods); +} + +static void +get_pointer_position_clutter (int *x, + int *y, + int *mods) +{ + ClutterSeat *seat; + ClutterInputDevice *cdevice; + graphene_point_t point; + + seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); + cdevice = clutter_seat_get_pointer (seat); + + clutter_input_device_get_coords (cdevice, NULL, &point); + if (x) + *x = point.x; + if (y) + *y = point.y; + if (mods) + *mods = clutter_input_device_get_modifier_state (cdevice); +} + +void +meta_cursor_tracker_get_pointer (MetaCursorTracker *tracker, + int *x, + int *y, + ClutterModifierType *mods) +{ + /* We can't use the clutter interface when not running as a wayland compositor, + because we need to query the server, rather than using the last cached value. + OTOH, on wayland we can't use GDK, because that only sees the events + we forward to xwayland. + */ + if (meta_is_wayland_compositor ()) + get_pointer_position_clutter (x, y, (int*)mods); + else + get_pointer_position_gdk (x, y, (int*)mods); +} + +gboolean +meta_cursor_tracker_get_pointer_visible (MetaCursorTracker *tracker) +{ + return tracker->is_showing; +} + +void +meta_cursor_tracker_set_pointer_visible (MetaCursorTracker *tracker, + gboolean visible) +{ + if (visible == tracker->is_showing) + return; + tracker->is_showing = visible; + + sync_cursor (tracker); + + g_signal_emit (tracker, signals[VISIBILITY_CHANGED], 0); +} + +MetaCursorSprite * +meta_cursor_tracker_get_displayed_cursor (MetaCursorTracker *tracker) +{ + return tracker->displayed_cursor; +} diff --git a/src/backends/meta-cursor.c b/src/backends/meta-cursor.c new file mode 100644 index 000000000..f6b207762 --- /dev/null +++ b/src/backends/meta-cursor.c @@ -0,0 +1,241 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright 2013 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: Giovanni Campagna <gcampagn@redhat.com> + */ + +#include "config.h" + +#include "backends/meta-cursor.h" + +#include "backends/meta-backend-private.h" +#include "cogl/cogl.h" +#include "meta/common.h" + +enum +{ + PREPARE_AT, + TEXTURE_CHANGED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL]; + +typedef struct _MetaCursorSpritePrivate +{ + GObject parent; + + CoglTexture2D *texture; + float texture_scale; + MetaMonitorTransform texture_transform; + int hot_x, hot_y; +} MetaCursorSpritePrivate; + +G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaCursorSprite, + meta_cursor_sprite, + G_TYPE_OBJECT) + +gboolean +meta_cursor_sprite_is_animated (MetaCursorSprite *sprite) +{ + MetaCursorSpriteClass *klass = META_CURSOR_SPRITE_GET_CLASS (sprite); + + if (klass->is_animated) + return klass->is_animated (sprite); + else + return FALSE; +} + +void +meta_cursor_sprite_tick_frame (MetaCursorSprite *sprite) +{ + return META_CURSOR_SPRITE_GET_CLASS (sprite)->tick_frame (sprite); +} + +unsigned int +meta_cursor_sprite_get_current_frame_time (MetaCursorSprite *sprite) +{ + return META_CURSOR_SPRITE_GET_CLASS (sprite)->get_current_frame_time (sprite); +} + +void +meta_cursor_sprite_clear_texture (MetaCursorSprite *sprite) +{ + MetaCursorSpritePrivate *priv = + meta_cursor_sprite_get_instance_private (sprite); + + g_clear_pointer (&priv->texture, cogl_object_unref); +} + +void +meta_cursor_sprite_set_texture (MetaCursorSprite *sprite, + CoglTexture *texture, + int hot_x, + int hot_y) +{ + MetaCursorSpritePrivate *priv = + meta_cursor_sprite_get_instance_private (sprite); + + g_clear_pointer (&priv->texture, cogl_object_unref); + if (texture) + priv->texture = cogl_object_ref (texture); + priv->hot_x = hot_x; + priv->hot_y = hot_y; + + g_signal_emit (sprite, signals[TEXTURE_CHANGED], 0); +} + +void +meta_cursor_sprite_set_texture_scale (MetaCursorSprite *sprite, + float scale) +{ + MetaCursorSpritePrivate *priv = + meta_cursor_sprite_get_instance_private (sprite); + + priv->texture_scale = scale; +} + +void +meta_cursor_sprite_set_texture_transform (MetaCursorSprite *sprite, + MetaMonitorTransform transform) +{ + MetaCursorSpritePrivate *priv = + meta_cursor_sprite_get_instance_private (sprite); + + priv->texture_transform = transform; +} + +CoglTexture * +meta_cursor_sprite_get_cogl_texture (MetaCursorSprite *sprite) +{ + MetaCursorSpritePrivate *priv = + meta_cursor_sprite_get_instance_private (sprite); + + return COGL_TEXTURE (priv->texture); +} + +void +meta_cursor_sprite_get_hotspot (MetaCursorSprite *sprite, + int *hot_x, + int *hot_y) +{ + MetaCursorSpritePrivate *priv = + meta_cursor_sprite_get_instance_private (sprite); + + *hot_x = priv->hot_x; + *hot_y = priv->hot_y; +} + +int +meta_cursor_sprite_get_width (MetaCursorSprite *sprite) +{ + CoglTexture *texture; + + texture = meta_cursor_sprite_get_cogl_texture (sprite); + return cogl_texture_get_width (texture); +} + +int +meta_cursor_sprite_get_height (MetaCursorSprite *sprite) +{ + CoglTexture *texture; + + texture = meta_cursor_sprite_get_cogl_texture (sprite); + return cogl_texture_get_height (texture); +} + +float +meta_cursor_sprite_get_texture_scale (MetaCursorSprite *sprite) +{ + MetaCursorSpritePrivate *priv = + meta_cursor_sprite_get_instance_private (sprite); + + return priv->texture_scale; +} + +MetaMonitorTransform +meta_cursor_sprite_get_texture_transform (MetaCursorSprite *sprite) +{ + MetaCursorSpritePrivate *priv = + meta_cursor_sprite_get_instance_private (sprite); + + return priv->texture_transform; +} + +void +meta_cursor_sprite_prepare_at (MetaCursorSprite *sprite, + int x, + int y) +{ + g_signal_emit (sprite, signals[PREPARE_AT], 0, x, y); +} + +void +meta_cursor_sprite_realize_texture (MetaCursorSprite *sprite) +{ + MetaCursorSpriteClass *klass = META_CURSOR_SPRITE_GET_CLASS (sprite); + + if (klass->realize_texture) + klass->realize_texture (sprite); +} + +static void +meta_cursor_sprite_init (MetaCursorSprite *sprite) +{ + MetaCursorSpritePrivate *priv = + meta_cursor_sprite_get_instance_private (sprite); + + priv->texture_scale = 1.0f; + priv->texture_transform = META_MONITOR_TRANSFORM_NORMAL; +} + +static void +meta_cursor_sprite_finalize (GObject *object) +{ + MetaCursorSprite *sprite = META_CURSOR_SPRITE (object); + MetaCursorSpritePrivate *priv = + meta_cursor_sprite_get_instance_private (sprite); + + g_clear_pointer (&priv->texture, cogl_object_unref); + + G_OBJECT_CLASS (meta_cursor_sprite_parent_class)->finalize (object); +} + +static void +meta_cursor_sprite_class_init (MetaCursorSpriteClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_cursor_sprite_finalize; + + signals[PREPARE_AT] = g_signal_new ("prepare-at", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 2, + G_TYPE_INT, + G_TYPE_INT); + signals[TEXTURE_CHANGED] = g_signal_new ("texture-changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); +} diff --git a/src/backends/meta-cursor.h b/src/backends/meta-cursor.h new file mode 100644 index 000000000..80eaa313c --- /dev/null +++ b/src/backends/meta-cursor.h @@ -0,0 +1,84 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright 2013 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: Giovanni Campagna <gcampagn@redhat.com> + */ + +#ifndef META_CURSOR_H +#define META_CURSOR_H + +#include "backends/meta-backend-types.h" +#include "meta/common.h" +#include "meta/boxes.h" + +#define META_TYPE_CURSOR_SPRITE (meta_cursor_sprite_get_type ()) +G_DECLARE_DERIVABLE_TYPE (MetaCursorSprite, + meta_cursor_sprite, + META, CURSOR_SPRITE, + GObject) + +struct _MetaCursorSpriteClass +{ + GObjectClass parent_class; + + void (* realize_texture) (MetaCursorSprite *sprite); + gboolean (* is_animated) (MetaCursorSprite *sprite); + void (* tick_frame) (MetaCursorSprite *sprite); + unsigned int (* get_current_frame_time) (MetaCursorSprite *sprite); +}; + +void meta_cursor_sprite_prepare_at (MetaCursorSprite *sprite, + int x, + int y); + +void meta_cursor_sprite_realize_texture (MetaCursorSprite *sprite); + +void meta_cursor_sprite_clear_texture (MetaCursorSprite *sprite); + +void meta_cursor_sprite_set_texture (MetaCursorSprite *sprite, + CoglTexture *texture, + int hot_x, + int hot_y); + +void meta_cursor_sprite_set_texture_scale (MetaCursorSprite *sprite, + float scale); + +void meta_cursor_sprite_set_texture_transform (MetaCursorSprite *sprite, + MetaMonitorTransform transform); + +CoglTexture *meta_cursor_sprite_get_cogl_texture (MetaCursorSprite *sprite); + +void meta_cursor_sprite_get_hotspot (MetaCursorSprite *sprite, + int *hot_x, + int *hot_y); + +int meta_cursor_sprite_get_width (MetaCursorSprite *sprite); + +int meta_cursor_sprite_get_height (MetaCursorSprite *sprite); + +float meta_cursor_sprite_get_texture_scale (MetaCursorSprite *sprite); + +MetaMonitorTransform meta_cursor_sprite_get_texture_transform (MetaCursorSprite *sprite); + +gboolean meta_cursor_sprite_is_animated (MetaCursorSprite *sprite); + +void meta_cursor_sprite_tick_frame (MetaCursorSprite *sprite); + +unsigned int meta_cursor_sprite_get_current_frame_time (MetaCursorSprite *sprite); + +#endif /* META_CURSOR_H */ diff --git a/src/backends/meta-dbus-session-watcher.c b/src/backends/meta-dbus-session-watcher.c new file mode 100644 index 000000000..a885b423b --- /dev/null +++ b/src/backends/meta-dbus-session-watcher.c @@ -0,0 +1,237 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2015-2017 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#include "config.h" + +#include "backends/meta-dbus-session-watcher.h" + +#include <gio/gio.h> + +enum +{ + SESSION_SIGNAL_SESSION_CLOSED, + + N_SESSION_SIGNALS +}; + +static guint session_signals[N_SESSION_SIGNALS]; + +G_DEFINE_INTERFACE (MetaDbusSession, meta_dbus_session, G_TYPE_OBJECT) + +struct _MetaDbusSessionWatcher +{ + GObject parent; + + GHashTable *clients; +}; + +G_DEFINE_TYPE (MetaDbusSessionWatcher, + meta_dbus_session_watcher, + G_TYPE_OBJECT) + +typedef struct _MetaDbusSessionClient +{ + MetaDbusSessionWatcher *session_watcher; + MetaDbusSession *session; + char *dbus_name; + guint name_watcher_id; + GList *sessions; +} MetaDbusSessionClient; + +static void +meta_dbus_session_client_vanished (MetaDbusSession *session) +{ + META_DBUS_SESSION_GET_IFACE (session)->client_vanished (session); +} + +static void +meta_dbus_session_client_destroy (MetaDbusSessionClient *client) +{ + while (TRUE) + { + GList *l; + MetaDbusSession *session; + + l = client->sessions; + if (!l) + break; + + session = l->data; + + /* + * This will invoke on_session_closed which removes the session from the + * list. + */ + meta_dbus_session_client_vanished (session); + } + + if (client->name_watcher_id) + g_bus_unwatch_name (client->name_watcher_id); + + g_free (client->dbus_name); + g_free (client); +} + +static void +meta_dbus_session_watcher_destroy_client (MetaDbusSessionWatcher *session_watcher, + MetaDbusSessionClient *client) +{ + g_hash_table_remove (session_watcher->clients, client->dbus_name); +} + +static void +name_vanished_callback (GDBusConnection *connection, + const char *name, + gpointer user_data) +{ + MetaDbusSessionClient *client = user_data; + + g_warning ("D-Bus client with active sessions vanished"); + + client->name_watcher_id = 0; + + meta_dbus_session_watcher_destroy_client (client->session_watcher, client); +} + +static MetaDbusSessionClient * +meta_dbus_session_client_new (MetaDbusSessionWatcher *session_watcher, + MetaDbusSession *session, + const char *dbus_name) +{ + GDBusInterfaceSkeleton *interface_skeleton = + G_DBUS_INTERFACE_SKELETON (session); + GDBusConnection *connection = + g_dbus_interface_skeleton_get_connection (interface_skeleton); + MetaDbusSessionClient *client; + + client = g_new0 (MetaDbusSessionClient, 1); + client->session_watcher = session_watcher; + client->session = session; + client->dbus_name = g_strdup (dbus_name); + + client->name_watcher_id = + g_bus_watch_name_on_connection (connection, + dbus_name, + G_BUS_NAME_WATCHER_FLAGS_NONE, + NULL, + name_vanished_callback, + client, + NULL); + + return client; +} + +static void +on_session_closed (MetaDbusSession *session, + MetaDbusSessionClient *client) +{ + client->sessions = g_list_remove (client->sessions, session); + + if (!client->sessions) + meta_dbus_session_watcher_destroy_client (client->session_watcher, client); +} + +static void +meta_dbus_session_client_add_session (MetaDbusSessionClient *client, + MetaDbusSession *session) +{ + client->sessions = g_list_append (client->sessions, session); + + g_signal_connect (session, "session-closed", + G_CALLBACK (on_session_closed), + client); +} + +static MetaDbusSessionClient * +meta_dbus_session_watcher_get_client (MetaDbusSessionWatcher *session_watcher, + const char *dbus_name) +{ + return g_hash_table_lookup (session_watcher->clients, dbus_name); +} + +void +meta_dbus_session_watcher_watch_session (MetaDbusSessionWatcher *session_watcher, + const char *client_dbus_name, + MetaDbusSession *session) +{ + MetaDbusSessionClient *client; + + client = meta_dbus_session_watcher_get_client (session_watcher, + client_dbus_name); + if (!client) + { + client = meta_dbus_session_client_new (session_watcher, + session, + client_dbus_name); + g_hash_table_insert (session_watcher->clients, + g_strdup (client_dbus_name), + client); + } + + meta_dbus_session_client_add_session (client, session); +} + +void +meta_dbus_session_notify_closed (MetaDbusSession *session) +{ + g_signal_emit (session, session_signals[SESSION_SIGNAL_SESSION_CLOSED], 0); +} + +static void +meta_dbus_session_default_init (MetaDbusSessionInterface *iface) +{ + session_signals[SESSION_SIGNAL_SESSION_CLOSED] = + g_signal_new ("session-closed", + G_TYPE_FROM_INTERFACE (iface), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); +} + +static void +meta_dbus_session_watcher_finalize (GObject *object) +{ + MetaDbusSessionWatcher *session_watcher = META_DBUS_SESSION_WATCHER (object); + + g_hash_table_destroy (session_watcher->clients); + + G_OBJECT_CLASS (meta_dbus_session_watcher_parent_class)->finalize (object); +} + +static void +meta_dbus_session_watcher_init (MetaDbusSessionWatcher *session_watcher) +{ + session_watcher->clients = + g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + (GDestroyNotify) meta_dbus_session_client_destroy); +} + +static void +meta_dbus_session_watcher_class_init (MetaDbusSessionWatcherClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_dbus_session_watcher_finalize; +} diff --git a/src/backends/meta-dbus-session-watcher.h b/src/backends/meta-dbus-session-watcher.h new file mode 100644 index 000000000..06d3e1ff9 --- /dev/null +++ b/src/backends/meta-dbus-session-watcher.h @@ -0,0 +1,52 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#ifndef META_DBUS_SESSION_WATCHER_H +#define META_DBUS_SESSION_WATCHER_H + +#include <glib-object.h> + +#define META_TYPE_DBUS_SESSION (meta_dbus_session_get_type ()) +G_DECLARE_INTERFACE (MetaDbusSession, meta_dbus_session, + META, DBUS_SESSION, + GObject) + +struct _MetaDbusSessionInterface +{ + GTypeInterface parent_iface; + + void (* client_vanished) (MetaDbusSession *session); +}; + +#define META_TYPE_DBUS_SESSION_WATCHER (meta_dbus_session_watcher_get_type ()) +G_DECLARE_FINAL_TYPE (MetaDbusSessionWatcher, + meta_dbus_session_watcher, + META, DBUS_SESSION_WATCHER, + GObject) + +void meta_dbus_session_watcher_watch_session (MetaDbusSessionWatcher *session_watcher, + const char *client_dbus_name, + MetaDbusSession *session); + +void meta_dbus_session_notify_closed (MetaDbusSession *session); + +#endif /* META_DBUS_SESSION_WATCHER_H */ diff --git a/src/backends/meta-display-config-shared.h b/src/backends/meta-display-config-shared.h new file mode 100644 index 000000000..f037dac83 --- /dev/null +++ b/src/backends/meta-display-config-shared.h @@ -0,0 +1,39 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * Copyright (C) 2013 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +/* This file is shared between mutter (src/core/meta-display-config-shared.h) + and gnome-desktop (libgnome-desktop/meta-xrandr-shared.h). + + The canonical place for all changes is mutter. + + There should be no includes in this file. +*/ + +#ifndef META_DISPLAY_CONFIG_SHARED_H +#define META_DISPLAY_CONFIG_SHARED_H + +typedef enum +{ + META_POWER_SAVE_UNSUPPORTED = -1, + META_POWER_SAVE_ON = 0, + META_POWER_SAVE_STANDBY, + META_POWER_SAVE_SUSPEND, + META_POWER_SAVE_OFF, +} MetaPowerSave; + +#endif /* META_DISPLAY_CONFIG_SHARED_H */ diff --git a/src/backends/meta-dnd-private.h b/src/backends/meta-dnd-private.h new file mode 100644 index 000000000..0cfb3d788 --- /dev/null +++ b/src/backends/meta-dnd-private.h @@ -0,0 +1,41 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Hyungwon Hwang + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef META_DND_PRIVATE__H +#define META_DND_PRIVATE__H + +#include <glib.h> +#include <X11/Xlib.h> + +#include "backends/meta-backend-private.h" +#include "compositor/meta-compositor-x11.h" + +gboolean meta_dnd_handle_xdnd_event (MetaBackend *backend, + MetaCompositorX11 *compositor_x11, + Display *xdisplay, + XEvent *xev); + +void meta_dnd_init_xdnd (MetaX11Display *x11_display); + +#ifdef HAVE_WAYLAND +void meta_dnd_wayland_handle_begin_modal (MetaCompositor *compositor); +void meta_dnd_wayland_handle_end_modal (MetaCompositor *compositor); +#endif + +#endif /* META_DND_PRIVATE_H */ diff --git a/src/backends/meta-egl-ext.h b/src/backends/meta-egl-ext.h new file mode 100644 index 000000000..db0b74f76 --- /dev/null +++ b/src/backends/meta-egl-ext.h @@ -0,0 +1,103 @@ +/* + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef META_EGL_EXT_H +#define META_EGL_EXT_H + +#include <EGL/egl.h> +#include <EGL/eglext.h> +#include <EGL/eglmesaext.h> + +/* + * This is a little different to the tests shipped with EGL implementations, + * which wrap the entire thing in #ifndef EGL_WL_bind_wayland_display, then go + * on to define both BindWaylandDisplay and QueryWaylandBuffer. + * + * Unfortunately, some implementations (particularly the version of Mesa shipped + * in Ubuntu 12.04) define EGL_WL_bind_wayland_display, but then only provide + * prototypes for (Un)BindWaylandDisplay, completely omitting + * QueryWaylandBuffer. + * + * Detect this, and provide our own definitions if necessary. + */ +#ifndef EGL_WAYLAND_BUFFER_WL +#define EGL_WAYLAND_BUFFER_WL 0x31D5 /* eglCreateImageKHR target */ +#define EGL_WAYLAND_PLANE_WL 0x31D6 /* eglCreateImageKHR target */ + +#define EGL_TEXTURE_Y_U_V_WL 0x31D7 +#define EGL_TEXTURE_Y_UV_WL 0x31D8 +#define EGL_TEXTURE_Y_XUXV_WL 0x31D9 +#define EGL_TEXTURE_EXTERNAL_WL 0x31DA + +struct wl_resource; +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value); +#endif +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYWAYLANDBUFFERWL) (EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value); +#endif + +/* + * FIXME: Remove both EGL_EXT_stream_acquire_mode and + * EGL_NV_output_drm_flip_event definitions below once both extensions + * get published by Khronos and incorportated into Khronos' header files + */ +#ifndef EGL_EXT_stream_acquire_mode +#define EGL_EXT_stream_acquire_mode 1 +#define EGL_CONSUMER_AUTO_ACQUIRE_EXT 0x332B +#define EGL_RESOURCE_BUSY_EXT 0x3353 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREATTRIBEXTPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerAcquireAttribEXT (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); +#endif +#endif /* EGL_EXT_stream_acquire_mode */ + +#ifndef EGL_NV_output_drm_flip_event +#define EGL_NV_output_drm_flip_event 1 +#define EGL_DRM_FLIP_EVENT_DATA_NV 0x333E +#endif /* EGL_NV_output_drm_flip_event */ + +#ifndef EGL_NV_stream_attrib +#define EGL_NV_stream_attrib 1 +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamAttribNV(EGLDisplay dpy, const EGLAttrib *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglSetStreamAttribNV(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib value); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamAttribNV(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib *value); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerAcquireAttribNV(EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerReleaseAttribNV(EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); +#endif +typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMATTRIBNVPROC) (EGLDisplay dpy, const EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETSTREAMATTRIBNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMATTRIBNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib *value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREATTRIBNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERRELEASEATTRIBNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); +#endif /* EGL_NV_stream_attrib */ + +#ifndef EGL_WL_wayland_eglstream +#define EGL_WL_wayland_eglstream 1 +#define EGL_WAYLAND_EGLSTREAM_WL 0x334B +#endif /* EGL_WL_wayland_eglstream */ + +#endif /* META_EGL_EXT_H */ diff --git a/src/backends/meta-egl.c b/src/backends/meta-egl.c new file mode 100644 index 000000000..fdeff4f77 --- /dev/null +++ b/src/backends/meta-egl.c @@ -0,0 +1,1120 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016, 2017 Red Hat Inc. + * Copyright (C) 2018, 2019 DisplayLink (UK) Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +#include "config.h" + +#include <EGL/egl.h> +#include <EGL/eglext.h> +#include <EGL/eglmesaext.h> +#include <gio/gio.h> +#include <glib.h> +#include <glib-object.h> + +#include "backends/meta-backend-private.h" +#include "backends/meta-egl.h" +#include "backends/meta-egl-ext.h" +#include "meta/util.h" + +struct _MetaEgl +{ + GObject parent; + + PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT; + + PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR; + PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR; + + PFNEGLQUERYWAYLANDBUFFERWL eglQueryWaylandBufferWL; + + PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT; + PFNEGLQUERYDEVICESTRINGEXTPROC eglQueryDeviceStringEXT; + + PFNEGLGETOUTPUTLAYERSEXTPROC eglGetOutputLayersEXT; + PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC eglQueryOutputLayerAttribEXT; + + PFNEGLCREATESTREAMKHRPROC eglCreateStreamKHR; + PFNEGLDESTROYSTREAMKHRPROC eglDestroyStreamKHR; + PFNEGLQUERYSTREAMKHRPROC eglQueryStreamKHR; + + PFNEGLCREATESTREAMATTRIBNVPROC eglCreateStreamAttribNV; + + PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC eglCreateStreamProducerSurfaceKHR; + + PFNEGLSTREAMCONSUMEROUTPUTEXTPROC eglStreamConsumerOutputEXT; + + PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC eglStreamConsumerGLTextureExternalKHR; + + PFNEGLSTREAMCONSUMERACQUIREKHRPROC eglStreamConsumerAcquireKHR; + PFNEGLSTREAMCONSUMERACQUIREATTRIBNVPROC eglStreamConsumerAcquireAttribNV; + + PFNEGLQUERYDMABUFFORMATSEXTPROC eglQueryDmaBufFormatsEXT; + PFNEGLQUERYDMABUFMODIFIERSEXTPROC eglQueryDmaBufModifiersEXT; +}; + +G_DEFINE_TYPE (MetaEgl, meta_egl, G_TYPE_OBJECT) + +G_DEFINE_QUARK (-meta-egl-error-quark, meta_egl_error) + +static const char * +get_egl_error_str (EGLint error_number) +{ + switch (error_number) + { + case EGL_SUCCESS: + return "The last function succeeded without error."; + break; + case EGL_NOT_INITIALIZED: + return "EGL is not initialized, or could not be initialized, for the specified EGL display connection."; + break; + case EGL_BAD_ACCESS: + return "EGL cannot access a requested resource (for example a context is bound in another thread)."; + break; + case EGL_BAD_ALLOC: + return "EGL failed to allocate resources for the requested operation."; + break; + case EGL_BAD_ATTRIBUTE: + return "An unrecognized attribute or attribute value was passed in the attribute list."; + break; + case EGL_BAD_CONTEXT: + return "An EGLContext argument does not name a valid EGL rendering context."; + break; + case EGL_BAD_CONFIG: + return "An EGLConfig argument does not name a valid EGL frame buffer configuration."; + break; + case EGL_BAD_CURRENT_SURFACE: + return "The current surface of the calling thread is a window, pixel buffer or pixmap that is no longer valid."; + break; + case EGL_BAD_DISPLAY: + return "An EGLDisplay argument does not name a valid EGL display connection."; + break; + case EGL_BAD_SURFACE: + return "An EGLSurface argument does not name a valid surface (window, pixel buffer or pixmap) configured for GL rendering."; + break; + case EGL_BAD_MATCH: + return "Arguments are inconsistent (for example, a valid context requires buffers not supplied by a valid surface)."; + break; + case EGL_BAD_PARAMETER: + return "One or more argument values are invalid."; + break; + case EGL_BAD_NATIVE_PIXMAP: + return "A NativePixmapType argument does not refer to a valid native pixmap."; + break; + case EGL_BAD_NATIVE_WINDOW: + return "A NativeWindowType argument does not refer to a valid native window."; + break; + case EGL_CONTEXT_LOST: + return "A power management event has occurred. The application must destroy all contexts and reinitialise OpenGL ES state and objects to continue rendering. "; + break; + case EGL_BAD_STREAM_KHR: + return "An EGLStreamKHR argument does not name a valid EGL stream."; + break; + case EGL_BAD_STATE_KHR: + return "An EGLStreamKHR argument is not in a valid state"; + break; + case EGL_BAD_DEVICE_EXT: + return "An EGLDeviceEXT argument does not name a valid EGL device."; + break; + case EGL_BAD_OUTPUT_LAYER_EXT: + return "An EGLOutputLayerEXT argument does not name a valid EGL output layer."; + case EGL_RESOURCE_BUSY_EXT: + return "The operation could not be completed on the requested resource because it is temporary unavailable."; + default: + return "Unknown error"; + break; + } +} + +static void +set_egl_error (GError **error) +{ + EGLint error_number; + const char *error_str; + + if (!error) + return; + + error_number = eglGetError (); + error_str = get_egl_error_str (error_number); + g_set_error_literal (error, META_EGL_ERROR, + error_number, + error_str); +} + +gboolean +meta_extensions_string_has_extensions_valist (const char *extensions_str, + const char ***missing_extensions, + const char *first_extension, + va_list var_args) +{ + char **extensions; + const char *extension; + size_t num_missing_extensions = 0; + + if (missing_extensions) + *missing_extensions = NULL; + + extensions = g_strsplit (extensions_str, " ", -1); + + extension = first_extension; + while (extension) + { + if (!g_strv_contains ((const char * const *) extensions, extension)) + { + num_missing_extensions++; + if (missing_extensions) + { + *missing_extensions = g_realloc_n (*missing_extensions, + num_missing_extensions + 1, + sizeof (const char *)); + (*missing_extensions)[num_missing_extensions - 1] = extension; + (*missing_extensions)[num_missing_extensions] = NULL; + } + else + { + break; + } + } + extension = va_arg (var_args, char *); + } + + g_strfreev (extensions); + + return num_missing_extensions == 0; +} + +gboolean +meta_egl_has_extensions (MetaEgl *egl, + EGLDisplay display, + const char ***missing_extensions, + const char *first_extension, + ...) +{ + va_list var_args; + const char *extensions_str; + gboolean has_extensions; + + extensions_str = (const char *) eglQueryString (display, EGL_EXTENSIONS); + if (!extensions_str) + { + g_warning ("Failed to query string: %s", + get_egl_error_str (eglGetError ())); + return FALSE; + } + + va_start (var_args, first_extension); + has_extensions = + meta_extensions_string_has_extensions_valist (extensions_str, + missing_extensions, + first_extension, + var_args); + va_end (var_args); + + return has_extensions; +} + +gboolean +meta_egl_initialize (MetaEgl *egl, + EGLDisplay display, + GError **error) +{ + if (!eglInitialize (display, NULL, NULL)) + { + set_egl_error (error); + return FALSE; + } + + return TRUE; +} + +gpointer +meta_egl_get_proc_address (MetaEgl *egl, + const char *procname, + GError **error) +{ + gpointer func; + + func = (gpointer) eglGetProcAddress (procname); + if (!func) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Could not load symbol '%s': Not found", + procname); + return NULL; + } + + return func; +} + +gboolean +meta_egl_get_config_attrib (MetaEgl *egl, + EGLDisplay display, + EGLConfig config, + EGLint attribute, + EGLint *value, + GError **error) +{ + if (!eglGetConfigAttrib (display, + config, + attribute, + value)) + { + set_egl_error (error); + return FALSE; + } + + return TRUE; +} + +EGLConfig * +meta_egl_choose_all_configs (MetaEgl *egl, + EGLDisplay display, + const EGLint *attrib_list, + EGLint *out_num_configs, + GError **error) +{ + EGLint num_configs; + EGLConfig *configs; + EGLint num_matches; + + if (!eglGetConfigs (display, NULL, 0, &num_configs)) + { + set_egl_error (error); + return FALSE; + } + + if (num_configs < 1) + { + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_FAILED, + "No EGL configurations available"); + return FALSE; + } + + configs = g_new0 (EGLConfig, num_configs); + + if (!eglChooseConfig (display, attrib_list, configs, num_configs, &num_matches)) + { + g_free (configs); + set_egl_error (error); + return FALSE; + } + + if (num_matches == 0) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "No matching EGL configs"); + g_free (configs); + return NULL; + } + + *out_num_configs = num_configs; + return configs; +} + +gboolean +meta_egl_choose_first_config (MetaEgl *egl, + EGLDisplay display, + const EGLint *attrib_list, + EGLConfig *chosen_config, + GError **error) +{ + EGLint num_configs; + EGLConfig *configs; + EGLint num_matches; + + if (!eglGetConfigs (display, NULL, 0, &num_configs)) + { + set_egl_error (error); + return FALSE; + } + + if (num_configs < 1) + { + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_FAILED, + "No EGL configurations available"); + return FALSE; + } + + configs = g_new0 (EGLConfig, num_configs); + + if (!eglChooseConfig (display, attrib_list, configs, num_configs, &num_matches)) + { + g_free (configs); + set_egl_error (error); + return FALSE; + } + + if (num_matches == 0) + { + g_free (configs); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "No matching EGLConfig found"); + return FALSE; + } + + /* + * We don't have any preference specified yet, so lets choose the first one. + */ + *chosen_config = configs[0]; + + g_free (configs); + + return TRUE; +} + +EGLSurface +meta_egl_create_window_surface (MetaEgl *egl, + EGLDisplay display, + EGLConfig config, + EGLNativeWindowType native_window_type, + const EGLint *attrib_list, + GError **error) +{ + EGLSurface surface; + + surface = eglCreateWindowSurface (display, config, + native_window_type, attrib_list); + if (surface == EGL_NO_SURFACE) + { + set_egl_error (error); + return EGL_NO_SURFACE; + } + + return surface; +} + +EGLSurface +meta_egl_create_pbuffer_surface (MetaEgl *egl, + EGLDisplay display, + EGLConfig config, + const EGLint *attrib_list, + GError **error) +{ + EGLSurface surface; + + surface = eglCreatePbufferSurface (display, config, attrib_list); + if (surface == EGL_NO_SURFACE) + { + set_egl_error (error); + return EGL_NO_SURFACE; + } + + return surface; +} + +gboolean +meta_egl_destroy_surface (MetaEgl *egl, + EGLDisplay display, + EGLSurface surface, + GError **error) +{ + if (!eglDestroySurface (display, surface)) + { + set_egl_error (error); + return FALSE; + } + + return TRUE; +} + +static gboolean +is_egl_proc_valid_real (void *proc, + const char *proc_name, + GError **error) +{ + if (!proc) + { + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_FAILED, + "EGL proc '%s' not resolved", + proc_name); + return FALSE; + } + + return TRUE; +} + +#define is_egl_proc_valid(proc, error) \ + is_egl_proc_valid_real (proc, #proc, error) + +EGLDisplay +meta_egl_get_platform_display (MetaEgl *egl, + EGLenum platform, + void *native_display, + const EGLint *attrib_list, + GError **error) +{ + EGLDisplay display; + + if (!is_egl_proc_valid (egl->eglGetPlatformDisplayEXT, error)) + return EGL_NO_DISPLAY; + + display = egl->eglGetPlatformDisplayEXT (platform, + native_display, + attrib_list); + if (display == EGL_NO_DISPLAY) + { + set_egl_error (error); + return EGL_NO_DISPLAY; + } + + return display; +} + +gboolean +meta_egl_terminate (MetaEgl *egl, + EGLDisplay display, + GError **error) +{ + if (!eglTerminate (display)) + { + set_egl_error (error); + return FALSE; + } + + return TRUE; +} + +EGLContext +meta_egl_create_context (MetaEgl *egl, + EGLDisplay display, + EGLConfig config, + EGLContext share_context, + const EGLint *attrib_list, + GError **error) +{ + EGLContext context; + + context = eglCreateContext (display, config, share_context, attrib_list); + if (context == EGL_NO_CONTEXT) + { + set_egl_error (error); + return EGL_NO_CONTEXT; + } + + return context; +} + +gboolean +meta_egl_destroy_context (MetaEgl *egl, + EGLDisplay display, + EGLContext context, + GError **error) +{ + if (!eglDestroyContext (display, context)) + { + set_egl_error (error); + return FALSE; + } + + return TRUE; +} + +EGLImageKHR +meta_egl_create_image (MetaEgl *egl, + EGLDisplay display, + EGLContext context, + EGLenum target, + EGLClientBuffer buffer, + const EGLint *attrib_list, + GError **error) +{ + EGLImageKHR image; + + if (!is_egl_proc_valid (egl->eglCreateImageKHR, error)) + return EGL_NO_IMAGE_KHR; + + image = egl->eglCreateImageKHR (display, context, + target, buffer, attrib_list); + if (image == EGL_NO_IMAGE_KHR) + { + set_egl_error (error); + return EGL_NO_IMAGE_KHR; + } + + return image; +} + +gboolean +meta_egl_destroy_image (MetaEgl *egl, + EGLDisplay display, + EGLImageKHR image, + GError **error) +{ + if (!is_egl_proc_valid (egl->eglDestroyImageKHR, error)) + return FALSE; + + if (!egl->eglDestroyImageKHR (display, image)) + { + set_egl_error (error); + return FALSE; + } + + return TRUE; +} + +EGLImageKHR +meta_egl_create_dmabuf_image (MetaEgl *egl, + EGLDisplay egl_display, + unsigned int width, + unsigned int height, + uint32_t drm_format, + uint32_t n_planes, + const int *fds, + const uint32_t *strides, + const uint32_t *offsets, + const uint64_t *modifiers, + GError **error) +{ + EGLint attribs[37]; + int atti = 0; + + /* This requires the Mesa commit in + * Mesa 10.3 (08264e5dad4df448e7718e782ad9077902089a07) or + * Mesa 10.2.7 (55d28925e6109a4afd61f109e845a8a51bd17652). + * Otherwise Mesa closes the fd behind our back and re-importing + * will fail. + * https://bugs.freedesktop.org/show_bug.cgi?id=76188 + */ + + attribs[atti++] = EGL_WIDTH; + attribs[atti++] = width; + attribs[atti++] = EGL_HEIGHT; + attribs[atti++] = height; + attribs[atti++] = EGL_LINUX_DRM_FOURCC_EXT; + attribs[atti++] = drm_format; + + if (n_planes > 0) + { + attribs[atti++] = EGL_DMA_BUF_PLANE0_FD_EXT; + attribs[atti++] = fds[0]; + attribs[atti++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT; + attribs[atti++] = offsets[0]; + attribs[atti++] = EGL_DMA_BUF_PLANE0_PITCH_EXT; + attribs[atti++] = strides[0]; + if (modifiers) + { + attribs[atti++] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT; + attribs[atti++] = modifiers[0] & 0xFFFFFFFF; + attribs[atti++] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT; + attribs[atti++] = modifiers[0] >> 32; + } + } + + if (n_planes > 1) + { + attribs[atti++] = EGL_DMA_BUF_PLANE1_FD_EXT; + attribs[atti++] = fds[1]; + attribs[atti++] = EGL_DMA_BUF_PLANE1_OFFSET_EXT; + attribs[atti++] = offsets[1]; + attribs[atti++] = EGL_DMA_BUF_PLANE1_PITCH_EXT; + attribs[atti++] = strides[1]; + if (modifiers) + { + attribs[atti++] = EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT; + attribs[atti++] = modifiers[1] & 0xFFFFFFFF; + attribs[atti++] = EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT; + attribs[atti++] = modifiers[1] >> 32; + } + } + + if (n_planes > 2) + { + attribs[atti++] = EGL_DMA_BUF_PLANE2_FD_EXT; + attribs[atti++] = fds[2]; + attribs[atti++] = EGL_DMA_BUF_PLANE2_OFFSET_EXT; + attribs[atti++] = offsets[2]; + attribs[atti++] = EGL_DMA_BUF_PLANE2_PITCH_EXT; + attribs[atti++] = strides[2]; + if (modifiers) + { + attribs[atti++] = EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT; + attribs[atti++] = modifiers[2] & 0xFFFFFFFF; + attribs[atti++] = EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT; + attribs[atti++] = modifiers[2] >> 32; + } + } + + attribs[atti++] = EGL_NONE; + g_assert (atti <= G_N_ELEMENTS (attribs)); + + return meta_egl_create_image (egl, egl_display, EGL_NO_CONTEXT, + EGL_LINUX_DMA_BUF_EXT, NULL, + attribs, + error); +} + +gboolean +meta_egl_make_current (MetaEgl *egl, + EGLDisplay display, + EGLSurface draw, + EGLSurface read, + EGLContext context, + GError **error) +{ + if (!eglMakeCurrent (display, draw, read, context)) + { + set_egl_error (error); + return FALSE; + } + + return TRUE; +} + +gboolean +meta_egl_swap_buffers (MetaEgl *egl, + EGLDisplay display, + EGLSurface surface, + GError **error) +{ + if (!eglSwapBuffers (display, surface)) + { + set_egl_error (error); + return FALSE; + } + + return TRUE; +} + +gboolean +meta_egl_query_wayland_buffer (MetaEgl *egl, + EGLDisplay display, + struct wl_resource *buffer, + EGLint attribute, + EGLint *value, + GError **error) +{ + if (!is_egl_proc_valid (egl->eglQueryWaylandBufferWL, error)) + return FALSE; + + if (!egl->eglQueryWaylandBufferWL (display, buffer, attribute, value)) + { + set_egl_error (error); + return FALSE; + } + + return TRUE; +} + +gboolean +meta_egl_query_devices (MetaEgl *egl, + EGLint max_devices, + EGLDeviceEXT *devices, + EGLint *num_devices, + GError **error) +{ + if (!is_egl_proc_valid (egl->eglQueryDevicesEXT, error)) + return FALSE; + + if (!egl->eglQueryDevicesEXT (max_devices, + devices, + num_devices)) + { + set_egl_error (error); + return FALSE; + } + + return TRUE; +} + +const char * +meta_egl_query_device_string (MetaEgl *egl, + EGLDeviceEXT device, + EGLint name, + GError **error) +{ + const char *device_string; + + if (!is_egl_proc_valid (egl->eglQueryDeviceStringEXT, error)) + return NULL; + + device_string = egl->eglQueryDeviceStringEXT (device, name); + if (!device_string) + { + set_egl_error (error); + return NULL; + } + + return device_string; +} + +gboolean +meta_egl_egl_device_has_extensions (MetaEgl *egl, + EGLDeviceEXT device, + const char ***missing_extensions, + const char *first_extension, + ...) +{ + va_list var_args; + const char *extensions_str; + gboolean has_extensions; + GError *error = NULL; + + extensions_str = meta_egl_query_device_string (egl, device, EGL_EXTENSIONS, + &error); + if (!extensions_str) + { + g_warning ("Failed to query device string: %s", error->message); + g_error_free (error); + return FALSE; + } + + va_start (var_args, first_extension); + has_extensions = + meta_extensions_string_has_extensions_valist (extensions_str, + missing_extensions, + first_extension, + var_args); + va_end (var_args); + + return has_extensions; +} + +gboolean +meta_egl_get_output_layers (MetaEgl *egl, + EGLDisplay display, + const EGLAttrib *attrib_list, + EGLOutputLayerEXT *layers, + EGLint max_layers, + EGLint *num_layers, + GError **error) +{ + if (!is_egl_proc_valid (egl->eglGetOutputLayersEXT, error)) + return FALSE; + + if (!egl->eglGetOutputLayersEXT (display, + attrib_list, + layers, + max_layers, + num_layers)) + { + set_egl_error (error); + return FALSE; + } + + return TRUE; +} + +gboolean +meta_egl_query_output_layer_attrib (MetaEgl *egl, + EGLDisplay display, + EGLOutputLayerEXT layer, + EGLint attribute, + EGLAttrib *value, + GError **error) +{ + if (!is_egl_proc_valid (egl->eglQueryOutputLayerAttribEXT, error)) + return FALSE; + + if (!egl->eglQueryOutputLayerAttribEXT (display, layer, + attribute, value)) + { + set_egl_error (error); + return FALSE; + } + + return TRUE; +} + +EGLStreamKHR +meta_egl_create_stream (MetaEgl *egl, + EGLDisplay display, + const EGLint *attrib_list, + GError **error) +{ + EGLStreamKHR stream; + + if (!is_egl_proc_valid (egl->eglCreateStreamKHR, error)) + return EGL_NO_STREAM_KHR; + + stream = egl->eglCreateStreamKHR (display, attrib_list); + if (stream == EGL_NO_STREAM_KHR) + { + set_egl_error (error); + return EGL_NO_STREAM_KHR; + } + + return stream; +} + +gboolean +meta_egl_destroy_stream (MetaEgl *egl, + EGLDisplay display, + EGLStreamKHR stream, + GError **error) +{ + if (!is_egl_proc_valid (egl->eglDestroyStreamKHR, error)) + return FALSE; + + if (!egl->eglDestroyStreamKHR (display, stream)) + { + set_egl_error (error); + return FALSE; + } + + return TRUE; +} + +gboolean +meta_egl_query_stream (MetaEgl *egl, + EGLDisplay display, + EGLStreamKHR stream, + EGLenum attribute, + EGLint *value, + GError **error) +{ + if (!is_egl_proc_valid (egl->eglQueryStreamKHR, error)) + return FALSE; + + if (!egl->eglQueryStreamKHR (display, stream, attribute, value)) + { + set_egl_error (error); + return FALSE; + } + + return TRUE; +} + +EGLStreamKHR +meta_egl_create_stream_attrib (MetaEgl *egl, + EGLDisplay display, + const EGLAttrib *attrib_list, + GError **error) +{ + EGLStreamKHR stream; + + if (!is_egl_proc_valid (egl->eglCreateStreamAttribNV, error)) + return FALSE; + + stream = egl->eglCreateStreamAttribNV (display, attrib_list); + if (stream == EGL_NO_STREAM_KHR) + { + set_egl_error (error); + return EGL_NO_STREAM_KHR; + } + + return stream; +} + +EGLSurface +meta_egl_create_stream_producer_surface (MetaEgl *egl, + EGLDisplay display, + EGLConfig config, + EGLStreamKHR stream, + const EGLint *attrib_list, + GError **error) +{ + EGLSurface surface; + + if (!is_egl_proc_valid (egl->eglCreateStreamProducerSurfaceKHR, error)) + return EGL_NO_SURFACE; + + surface = egl->eglCreateStreamProducerSurfaceKHR (display, + config, + stream, + attrib_list); + if (surface == EGL_NO_SURFACE) + { + set_egl_error (error); + return EGL_NO_SURFACE; + } + + return surface; +} + +gboolean +meta_egl_stream_consumer_output (MetaEgl *egl, + EGLDisplay display, + EGLStreamKHR stream, + EGLOutputLayerEXT layer, + GError **error) +{ + if (!is_egl_proc_valid (egl->eglStreamConsumerOutputEXT, error)) + return FALSE; + + if (!egl->eglStreamConsumerOutputEXT (display, stream, layer)) + { + set_egl_error (error); + return FALSE; + } + + return TRUE; +} + +gboolean +meta_egl_stream_consumer_acquire_attrib (MetaEgl *egl, + EGLDisplay display, + EGLStreamKHR stream, + EGLAttrib *attrib_list, + GError **error) +{ + if (!is_egl_proc_valid (egl->eglStreamConsumerAcquireAttribNV, error)) + return FALSE; + + if (!egl->eglStreamConsumerAcquireAttribNV (display, stream, attrib_list)) + { + set_egl_error (error); + return FALSE; + } + + return TRUE; +} + +gboolean +meta_egl_stream_consumer_gl_texture_external (MetaEgl *egl, + EGLDisplay display, + EGLStreamKHR stream, + GError **error) +{ + if (!is_egl_proc_valid (egl->eglStreamConsumerGLTextureExternalKHR, error)) + return FALSE; + + if (!egl->eglStreamConsumerGLTextureExternalKHR (display, stream)) + { + set_egl_error (error); + return FALSE; + } + + return TRUE; +} + +gboolean +meta_egl_stream_consumer_acquire (MetaEgl *egl, + EGLDisplay display, + EGLStreamKHR stream, + GError **error) +{ + if (!is_egl_proc_valid (egl->eglStreamConsumerAcquireKHR, error)) + return FALSE; + + if (!egl->eglStreamConsumerAcquireKHR (display, stream)) + { + set_egl_error (error); + return FALSE; + } + + return TRUE; +} + +gboolean +meta_egl_query_dma_buf_formats (MetaEgl *egl, + EGLDisplay display, + EGLint max_formats, + EGLint *formats, + EGLint *num_formats, + GError **error) +{ + if (!is_egl_proc_valid (egl->eglQueryDmaBufFormatsEXT, error)) + return FALSE; + + if (!egl->eglQueryDmaBufFormatsEXT (display, max_formats, formats, + num_formats)) + { + set_egl_error (error); + return FALSE; + } + + return TRUE; +} + +gboolean +meta_egl_query_dma_buf_modifiers (MetaEgl *egl, + EGLDisplay display, + EGLint format, + EGLint max_modifiers, + EGLuint64KHR *modifiers, + EGLBoolean *external_only, + EGLint *num_modifiers, + GError **error) +{ + if (!is_egl_proc_valid (egl->eglQueryDmaBufModifiersEXT, error)) + return FALSE; + + if (!egl->eglQueryDmaBufModifiersEXT (display, format, max_modifiers, + modifiers, external_only, + num_modifiers)) + { + set_egl_error (error); + return FALSE; + } + + return TRUE; +} + +#define GET_EGL_PROC_ADDR(proc) \ + egl->proc = (void *) eglGetProcAddress (#proc); + +static void +meta_egl_constructed (GObject *object) +{ + MetaEgl *egl = META_EGL (object); + + GET_EGL_PROC_ADDR (eglGetPlatformDisplayEXT); + + GET_EGL_PROC_ADDR (eglCreateImageKHR); + GET_EGL_PROC_ADDR (eglDestroyImageKHR); + + GET_EGL_PROC_ADDR (eglQueryWaylandBufferWL); + + GET_EGL_PROC_ADDR (eglQueryDevicesEXT); + GET_EGL_PROC_ADDR (eglQueryDeviceStringEXT); + + GET_EGL_PROC_ADDR (eglGetOutputLayersEXT); + GET_EGL_PROC_ADDR (eglQueryOutputLayerAttribEXT); + + GET_EGL_PROC_ADDR (eglCreateStreamKHR); + GET_EGL_PROC_ADDR (eglDestroyStreamKHR); + GET_EGL_PROC_ADDR (eglQueryStreamKHR); + + GET_EGL_PROC_ADDR (eglCreateStreamAttribNV); + + GET_EGL_PROC_ADDR (eglCreateStreamProducerSurfaceKHR); + + GET_EGL_PROC_ADDR (eglStreamConsumerOutputEXT); + + GET_EGL_PROC_ADDR (eglStreamConsumerGLTextureExternalKHR); + + GET_EGL_PROC_ADDR (eglStreamConsumerAcquireKHR); + GET_EGL_PROC_ADDR (eglStreamConsumerAcquireAttribNV); + + GET_EGL_PROC_ADDR (eglQueryDmaBufFormatsEXT); + GET_EGL_PROC_ADDR (eglQueryDmaBufModifiersEXT); +} + +#undef GET_EGL_PROC_ADDR + +static void +meta_egl_init (MetaEgl *egl) +{ +} + +static void +meta_egl_class_init (MetaEglClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->constructed = meta_egl_constructed; +} diff --git a/src/backends/meta-egl.h b/src/backends/meta-egl.h new file mode 100644 index 000000000..4591e7d85 --- /dev/null +++ b/src/backends/meta-egl.h @@ -0,0 +1,263 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat Inc. + * Copyright (C) 2019 DisplayLink (UK) Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +#ifndef META_EGL_H +#define META_EGL_H + +#include <EGL/egl.h> +#include <EGL/eglext.h> +#include <EGL/eglmesaext.h> +#include <glib-object.h> + +#define META_EGL_ERROR meta_egl_error_quark () + +#define META_TYPE_EGL (meta_egl_get_type ()) +G_DECLARE_FINAL_TYPE (MetaEgl, meta_egl, META, EGL, GObject) + +GQuark meta_egl_error_quark (void); + +gboolean +meta_extensions_string_has_extensions_valist (const char *extensions_str, + const char ***missing_extensions, + const char *first_extension, + va_list var_args); + +gboolean meta_egl_has_extensions (MetaEgl *egl, + EGLDisplay display, + const char ***missing_extensions, + const char *first_extension, + ...); + +gboolean meta_egl_initialize (MetaEgl *egl, + EGLDisplay display, + GError **error); + +gpointer meta_egl_get_proc_address (MetaEgl *egl, + const char *procname, + GError **error); + +gboolean meta_egl_choose_first_config (MetaEgl *egl, + EGLDisplay display, + const EGLint *attrib_list, + EGLConfig *chosen_config, + GError **error); + +gboolean meta_egl_get_config_attrib (MetaEgl *egl, + EGLDisplay display, + EGLConfig config, + EGLint attribute, + EGLint *value, + GError **error); + +EGLConfig * meta_egl_choose_all_configs (MetaEgl *egl, + EGLDisplay display, + const EGLint *attrib_list, + EGLint *out_num_configs, + GError **error); + +EGLContext meta_egl_create_context (MetaEgl *egl, + EGLDisplay display, + EGLConfig config, + EGLContext share_context, + const EGLint *attrib_list, + GError **error); + +gboolean meta_egl_destroy_context (MetaEgl *egl, + EGLDisplay display, + EGLContext context, + GError **error); + +EGLImageKHR meta_egl_create_image (MetaEgl *egl, + EGLDisplay display, + EGLContext context, + EGLenum target, + EGLClientBuffer buffer, + const EGLint *attrib_list, + GError **error); + +gboolean meta_egl_destroy_image (MetaEgl *egl, + EGLDisplay display, + EGLImageKHR image, + GError **error); + +EGLImageKHR meta_egl_create_dmabuf_image (MetaEgl *egl, + EGLDisplay egl_display, + unsigned int width, + unsigned int height, + uint32_t drm_format, + uint32_t n_planes, + const int *fds, + const uint32_t *strides, + const uint32_t *offsets, + const uint64_t *modifiers, + GError **error); + +EGLSurface meta_egl_create_window_surface (MetaEgl *egl, + EGLDisplay display, + EGLConfig config, + EGLNativeWindowType native_window_type, + const EGLint *attrib_list, + GError **error); + +EGLSurface meta_egl_create_pbuffer_surface (MetaEgl *egl, + EGLDisplay display, + EGLConfig config, + const EGLint *attrib_list, + GError **error); + +gboolean meta_egl_destroy_surface (MetaEgl *egl, + EGLDisplay display, + EGLSurface surface, + GError **error); + +EGLDisplay meta_egl_get_platform_display (MetaEgl *egl, + EGLenum platform, + void *native_display, + const EGLint *attrib_list, + GError **error); + +gboolean meta_egl_terminate (MetaEgl *egl, + EGLDisplay display, + GError **error); + +gboolean meta_egl_make_current (MetaEgl *egl, + EGLDisplay display, + EGLSurface draw, + EGLSurface read, + EGLContext context, + GError **error); + +gboolean meta_egl_swap_buffers (MetaEgl *egl, + EGLDisplay display, + EGLSurface surface, + GError **error); + +gboolean meta_egl_query_wayland_buffer (MetaEgl *egl, + EGLDisplay display, + struct wl_resource *buffer, + EGLint attribute, + EGLint *value, + GError **error); + +gboolean meta_egl_query_devices (MetaEgl *egl, + EGLint max_devices, + EGLDeviceEXT *devices, + EGLint *num_devices, + GError **error); + +const char * meta_egl_query_device_string (MetaEgl *egl, + EGLDeviceEXT device, + EGLint name, + GError **error); + +gboolean meta_egl_egl_device_has_extensions (MetaEgl *egl, + EGLDeviceEXT device, + const char ***missing_extensions, + const char *first_extension, + ...); + +gboolean meta_egl_get_output_layers (MetaEgl *egl, + EGLDisplay display, + const EGLAttrib *attrib_list, + EGLOutputLayerEXT *layers, + EGLint max_layers, + EGLint *num_layers, + GError **error); + +gboolean meta_egl_query_output_layer_attrib (MetaEgl *egl, + EGLDisplay display, + EGLOutputLayerEXT layer, + EGLint attribute, + EGLAttrib *value, + GError **error); + +EGLStreamKHR meta_egl_create_stream (MetaEgl *egl, + EGLDisplay display, + const EGLint *attrib_list, + GError **error); + +gboolean meta_egl_destroy_stream (MetaEgl *egl, + EGLDisplay display, + EGLStreamKHR stream, + GError **error); + +gboolean meta_egl_query_stream (MetaEgl *egl, + EGLDisplay display, + EGLStreamKHR stream, + EGLenum attribute, + EGLint *value, + GError **error); + +EGLStreamKHR meta_egl_create_stream_attrib (MetaEgl *egl, + EGLDisplay display, + const EGLAttrib *attrib_list, + GError **error); + +EGLSurface meta_egl_create_stream_producer_surface (MetaEgl *egl, + EGLDisplay display, + EGLConfig config, + EGLStreamKHR stream, + const EGLint *attrib_list, + GError **error); + +gboolean meta_egl_stream_consumer_output (MetaEgl *egl, + EGLDisplay display, + EGLStreamKHR stream, + EGLOutputLayerEXT layer, + GError **error); + +gboolean meta_egl_stream_consumer_acquire_attrib (MetaEgl *egl, + EGLDisplay display, + EGLStreamKHR stream, + EGLAttrib *attrib_list, + GError **error); + +gboolean meta_egl_stream_consumer_acquire (MetaEgl *egl, + EGLDisplay display, + EGLStreamKHR stream, + GError **error); + +gboolean meta_egl_stream_consumer_gl_texture_external (MetaEgl *egl, + EGLDisplay display, + EGLStreamKHR stream, + GError **error); + +gboolean meta_egl_query_dma_buf_formats (MetaEgl *egl, + EGLDisplay display, + EGLint max_formats, + EGLint *formats, + EGLint *num_formats, + GError **error); + +gboolean meta_egl_query_dma_buf_modifiers (MetaEgl *egl, + EGLDisplay display, + EGLint format, + EGLint max_modifiers, + EGLuint64KHR *modifiers, + EGLBoolean *external_only, + EGLint *num_formats, + GError **error); + +#endif /* META_EGL_H */ diff --git a/src/backends/meta-gles3-table.h b/src/backends/meta-gles3-table.h new file mode 100644 index 000000000..4cc866060 --- /dev/null +++ b/src/backends/meta-gles3-table.h @@ -0,0 +1,36 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#ifndef META_GLES3_TABLE_H +#define META_GLES3_TABLE_H + +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> +#include <GLES3/gl3.h> + +typedef struct _MetaGles3Table +{ + void (* glEGLImageTargetTexture2DOES) (GLenum target, + GLeglImageOES image); +} MetaGles3Table; + +#endif /* META_GLES3_TABLE */ diff --git a/src/backends/meta-gles3.c b/src/backends/meta-gles3.c new file mode 100644 index 000000000..727b3c125 --- /dev/null +++ b/src/backends/meta-gles3.c @@ -0,0 +1,163 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ +#include <stdio.h> + +#include "config.h" + +#include "backends/meta-gles3.h" + +#include <dlfcn.h> +#include <gio/gio.h> + +#include "backends/meta-gles3-table.h" + +struct _MetaGles3 +{ + GObject parent; + + MetaEgl *egl; + + MetaGles3Table table; +}; + +G_DEFINE_TYPE (MetaGles3, meta_gles3, G_TYPE_OBJECT) + +MetaGles3Table * +meta_gles3_get_table (MetaGles3 *gles3) +{ + return &gles3->table; +} + +void +meta_gles3_ensure_loaded (MetaGles3 *gles3, + gpointer *func, + const char *name) +{ + GError *error = NULL; + + if (*func) + return; + + *func = meta_egl_get_proc_address (gles3->egl, name, &error); + if (!*func) + g_error ("Failed to load GLES3 symbol: %s", error->message); +} + +static const char * +get_gl_error_str (GLenum gl_error) +{ + switch (gl_error) + { + case GL_NO_ERROR: + return "No error has been recorded."; + case GL_INVALID_ENUM: + return "An unacceptable value is specified for an enumerated argument."; + case GL_INVALID_VALUE: + return "A numeric argument is out of range."; + case GL_INVALID_OPERATION: + return "The specified operation is not allowed in the current state."; + case GL_INVALID_FRAMEBUFFER_OPERATION: + return "The framebuffer object is not complete."; + case GL_OUT_OF_MEMORY: + return "There is not enough memory left to execute the command."; + default: + return "Unknown error"; + } +} + +void +meta_gles3_clear_error (MetaGles3 *gles3) +{ + while (TRUE) + { + GLenum gl_error = glGetError (); + + if (gl_error == GL_NO_ERROR) + break; + } +} + +gboolean +meta_gles3_validate (MetaGles3 *gles3, + GError **error) +{ + GLenum gl_error; + + gl_error = glGetError (); + if (gl_error != GL_NO_ERROR) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, + get_gl_error_str (gl_error)); + return FALSE; + } + + return TRUE; +} + +gboolean +meta_gles3_has_extensions (MetaGles3 *gles3, + const char ***missing_extensions, + const char *first_extension, + ...) +{ + va_list var_args; + const char *extensions_str; + gboolean has_extensions; + + extensions_str = (const char *) glGetString (GL_EXTENSIONS); + if (!extensions_str) + { + g_warning ("Failed to get string: %s", get_gl_error_str (glGetError ())); + return FALSE; + } + + va_start (var_args, first_extension); + has_extensions = + meta_extensions_string_has_extensions_valist (extensions_str, + missing_extensions, + first_extension, + var_args); + va_end (var_args); + + return has_extensions; +} + +MetaGles3 * +meta_gles3_new (MetaEgl *egl) +{ + MetaGles3 *gles3; + + gles3 = g_object_new (META_TYPE_GLES3, NULL); + gles3->egl = egl; + + return gles3; +} + +static void +meta_gles3_init (MetaGles3 *gles3) +{ +} + +static void +meta_gles3_class_init (MetaGles3Class *klass) +{ +} diff --git a/src/backends/meta-gles3.h b/src/backends/meta-gles3.h new file mode 100644 index 000000000..89206cc8f --- /dev/null +++ b/src/backends/meta-gles3.h @@ -0,0 +1,83 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#ifndef META_GLES3_H +#define META_GLES3_H + +#include <glib-object.h> + +#include "backends/meta-egl.h" + +typedef struct _MetaGles3Table MetaGles3Table; + +#define META_TYPE_GLES3 (meta_gles3_get_type ()) +G_DECLARE_FINAL_TYPE (MetaGles3, meta_gles3, META, GLES3, GObject) + +MetaGles3Table * meta_gles3_get_table (MetaGles3 *gles3); + +void meta_gles3_clear_error (MetaGles3 *gles3); + +gboolean meta_gles3_validate (MetaGles3 *gles3, + GError **error); + +void meta_gles3_ensure_loaded (MetaGles3 *gles, + gpointer *func, + const char *name); + +gboolean meta_gles3_has_extensions (MetaGles3 *gles3, + const char ***missing_extensions, + const char *first_extension, + ...); + +MetaGles3 * meta_gles3_new (MetaEgl *egl); + +#define GLBAS(gles3, func, args) \ +{ \ + GError *_error = NULL; \ + \ + func args; \ + \ + if (!meta_gles3_validate (gles3, &_error)) \ + { \ + g_warning ("%s %s failed: %s", #func, #args, _error->message); \ + g_error_free (_error); \ + } \ +} + +#define GLEXT(gles3, func, args) \ +{ \ + GError *_error = NULL; \ + MetaGles3Table *table; \ + \ + table = meta_gles3_get_table (gles3); \ + meta_gles3_ensure_loaded (gles3, (gpointer *) &table->func, #func); \ + \ + table->func args; \ + \ + if (!meta_gles3_validate (gles3, &_error)) \ + { \ + g_warning ("%s %s failed: %s", #func, #args, _error->message); \ + g_error_free (_error); \ + } \ +} + +#endif /* META_GLES3_H */ diff --git a/src/backends/meta-gpu.c b/src/backends/meta-gpu.c new file mode 100644 index 000000000..cc67fa718 --- /dev/null +++ b/src/backends/meta-gpu.c @@ -0,0 +1,225 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "backends/meta-gpu.h" + +#include "backends/meta-backend-private.h" +#include "backends/meta-output.h" + +enum +{ + PROP_0, + + PROP_BACKEND, + + PROP_LAST +}; + +static GParamSpec *obj_props[PROP_LAST]; + +typedef struct _MetaGpuPrivate +{ + MetaBackend *backend; + + GList *outputs; + GList *crtcs; + GList *modes; +} MetaGpuPrivate; + +G_DEFINE_TYPE_WITH_PRIVATE (MetaGpu, meta_gpu, G_TYPE_OBJECT) + +gboolean +meta_gpu_has_hotplug_mode_update (MetaGpu *gpu) +{ + MetaGpuPrivate *priv = meta_gpu_get_instance_private (gpu); + GList *l; + + for (l = priv->outputs; l; l = l->next) + { + MetaOutput *output = l->data; + + if (output->hotplug_mode_update) + return TRUE; + } + + return FALSE; +} + +gboolean +meta_gpu_read_current (MetaGpu *gpu, + GError **error) +{ + MetaGpuPrivate *priv = meta_gpu_get_instance_private (gpu); + gboolean ret; + GList *old_outputs; + GList *old_crtcs; + GList *old_modes; + + /* TODO: Get rid of this when objects incref:s what they need instead */ + old_outputs = priv->outputs; + old_crtcs = priv->crtcs; + old_modes = priv->modes; + + ret = META_GPU_GET_CLASS (gpu)->read_current (gpu, error); + + g_list_free_full (old_outputs, g_object_unref); + g_list_free_full (old_modes, g_object_unref); + g_list_free_full (old_crtcs, g_object_unref); + + return ret; +} + +MetaBackend * +meta_gpu_get_backend (MetaGpu *gpu) +{ + MetaGpuPrivate *priv = meta_gpu_get_instance_private (gpu); + + return priv->backend; +} + +GList * +meta_gpu_get_outputs (MetaGpu *gpu) +{ + MetaGpuPrivate *priv = meta_gpu_get_instance_private (gpu); + + return priv->outputs; +} + +GList * +meta_gpu_get_crtcs (MetaGpu *gpu) +{ + MetaGpuPrivate *priv = meta_gpu_get_instance_private (gpu); + + return priv->crtcs; +} + +GList * +meta_gpu_get_modes (MetaGpu *gpu) +{ + MetaGpuPrivate *priv = meta_gpu_get_instance_private (gpu); + + return priv->modes; +} + +void +meta_gpu_take_outputs (MetaGpu *gpu, + GList *outputs) +{ + MetaGpuPrivate *priv = meta_gpu_get_instance_private (gpu); + + priv->outputs = outputs; +} + +void +meta_gpu_take_crtcs (MetaGpu *gpu, + GList *crtcs) +{ + MetaGpuPrivate *priv = meta_gpu_get_instance_private (gpu); + + priv->crtcs = crtcs; +} + +void +meta_gpu_take_modes (MetaGpu *gpu, + GList *modes) +{ + MetaGpuPrivate *priv = meta_gpu_get_instance_private (gpu); + + priv->modes = modes; +} + +static void +meta_gpu_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaGpu *gpu = META_GPU (object); + MetaGpuPrivate *priv = meta_gpu_get_instance_private (gpu); + + switch (prop_id) + { + case PROP_BACKEND: + priv->backend = g_value_get_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_gpu_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaGpu *gpu = META_GPU (object); + MetaGpuPrivate *priv = meta_gpu_get_instance_private (gpu); + + switch (prop_id) + { + case PROP_BACKEND: + g_value_set_object (value, priv->backend); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_gpu_finalize (GObject *object) +{ + MetaGpu *gpu = META_GPU (object); + MetaGpuPrivate *priv = meta_gpu_get_instance_private (gpu); + + g_list_free_full (priv->outputs, g_object_unref); + g_list_free_full (priv->modes, g_object_unref); + g_list_free_full (priv->crtcs, g_object_unref); + + G_OBJECT_CLASS (meta_gpu_parent_class)->finalize (object); +} + +static void +meta_gpu_init (MetaGpu *gpu) +{ +} + +static void +meta_gpu_class_init (MetaGpuClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->set_property = meta_gpu_set_property; + object_class->get_property = meta_gpu_get_property; + object_class->finalize = meta_gpu_finalize; + + obj_props[PROP_BACKEND] = + g_param_spec_object ("backend", + "backend", + "MetaBackend", + META_TYPE_BACKEND, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + g_object_class_install_properties (object_class, PROP_LAST, obj_props); +} diff --git a/src/backends/meta-gpu.h b/src/backends/meta-gpu.h new file mode 100644 index 000000000..9d12f95a7 --- /dev/null +++ b/src/backends/meta-gpu.h @@ -0,0 +1,72 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_GPU_H +#define META_GPU_H + +#include <glib-object.h> + +#include "backends/meta-monitor-manager-private.h" + +#define META_TYPE_GPU (meta_gpu_get_type ()) +META_EXPORT_TEST +G_DECLARE_DERIVABLE_TYPE (MetaGpu, meta_gpu, META, GPU, GObject) + +struct _MetaGpuClass +{ + GObjectClass parent_class; + + gboolean (* read_current) (MetaGpu *gpu, + GError **error); +}; + +META_EXPORT_TEST +gboolean meta_gpu_read_current (MetaGpu *gpu, + GError **error); + +META_EXPORT_TEST +gboolean meta_gpu_has_hotplug_mode_update (MetaGpu *gpu); + +META_EXPORT_TEST +MetaBackend * meta_gpu_get_backend (MetaGpu *gpu); + +META_EXPORT_TEST +GList * meta_gpu_get_outputs (MetaGpu *gpu); + +META_EXPORT_TEST +GList * meta_gpu_get_crtcs (MetaGpu *gpu); + +META_EXPORT_TEST +GList * meta_gpu_get_modes (MetaGpu *gpu); + +META_EXPORT_TEST +void meta_gpu_take_outputs (MetaGpu *gpu, + GList *outputs); + +META_EXPORT_TEST +void meta_gpu_take_crtcs (MetaGpu *gpu, + GList *crtcs); + +META_EXPORT_TEST +void meta_gpu_take_modes (MetaGpu *gpu, + GList *modes); + +#endif /* META_GPU_H */ diff --git a/src/backends/meta-idle-monitor-dbus.c b/src/backends/meta-idle-monitor-dbus.c new file mode 100644 index 000000000..3fa0018bd --- /dev/null +++ b/src/backends/meta-idle-monitor-dbus.c @@ -0,0 +1,266 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright 2013 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Adapted from gnome-session/gnome-session/gs-idle-monitor.c and + * from gnome-desktop/libgnome-desktop/gnome-idle-monitor.c + */ + +#include "config.h" + +#include "backends/meta-idle-monitor-dbus.h" + +#include "backends/meta-idle-monitor-private.h" +#include "clutter/clutter.h" +#include "meta/main.h" +#include "meta/meta-idle-monitor.h" +#include "meta/util.h" + +#include "meta-dbus-idle-monitor.h" + +static gboolean +handle_get_idletime (MetaDBusIdleMonitor *skeleton, + GDBusMethodInvocation *invocation, + MetaIdleMonitor *monitor) +{ + guint64 idletime; + + idletime = meta_idle_monitor_get_idletime (monitor); + meta_dbus_idle_monitor_complete_get_idletime (skeleton, invocation, idletime); + + return TRUE; +} + +static gboolean +handle_reset_idletime (MetaDBusIdleMonitor *skeleton, + GDBusMethodInvocation *invocation, + MetaIdleMonitor *monitor) +{ + if (!g_getenv ("MUTTER_DEBUG_RESET_IDLETIME")) + { + g_dbus_method_invocation_return_error_literal (invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_UNKNOWN_METHOD, + "This method is for testing purposes only. MUTTER_DEBUG_RESET_IDLETIME must be set to use it"); + return TRUE; + } + + meta_idle_monitor_reset_idletime (meta_idle_monitor_get_core ()); + meta_dbus_idle_monitor_complete_reset_idletime (skeleton, invocation); + + return TRUE; +} + +typedef struct { + MetaDBusIdleMonitor *dbus_monitor; + MetaIdleMonitor *monitor; + char *dbus_name; + guint watch_id; + guint name_watcher_id; +} DBusWatch; + +static void +destroy_dbus_watch (gpointer data) +{ + DBusWatch *watch = data; + + g_object_unref (watch->dbus_monitor); + g_object_unref (watch->monitor); + g_free (watch->dbus_name); + g_bus_unwatch_name (watch->name_watcher_id); + + g_slice_free (DBusWatch, watch); +} + +static void +dbus_idle_callback (MetaIdleMonitor *monitor, + guint watch_id, + gpointer user_data) +{ + DBusWatch *watch = user_data; + GDBusInterfaceSkeleton *skeleton = G_DBUS_INTERFACE_SKELETON (watch->dbus_monitor); + + g_dbus_connection_emit_signal (g_dbus_interface_skeleton_get_connection (skeleton), + watch->dbus_name, + g_dbus_interface_skeleton_get_object_path (skeleton), + "org.gnome.Mutter.IdleMonitor", + "WatchFired", + g_variant_new ("(u)", watch_id), + NULL); +} + +static void +name_vanished_callback (GDBusConnection *connection, + const char *name, + gpointer user_data) +{ + DBusWatch *watch = user_data; + + meta_idle_monitor_remove_watch (watch->monitor, watch->watch_id); +} + +static DBusWatch * +make_dbus_watch (MetaDBusIdleMonitor *skeleton, + GDBusMethodInvocation *invocation, + MetaIdleMonitor *monitor) +{ + DBusWatch *watch; + + watch = g_slice_new (DBusWatch); + watch->dbus_monitor = g_object_ref (skeleton); + watch->monitor = g_object_ref (monitor); + watch->dbus_name = g_strdup (g_dbus_method_invocation_get_sender (invocation)); + watch->name_watcher_id = g_bus_watch_name_on_connection (g_dbus_method_invocation_get_connection (invocation), + watch->dbus_name, + G_BUS_NAME_WATCHER_FLAGS_NONE, + NULL, /* appeared */ + name_vanished_callback, + watch, NULL); + + return watch; +} + +static gboolean +handle_add_idle_watch (MetaDBusIdleMonitor *skeleton, + GDBusMethodInvocation *invocation, + guint64 interval, + MetaIdleMonitor *monitor) +{ + DBusWatch *watch; + + watch = make_dbus_watch (skeleton, invocation, monitor); + watch->watch_id = meta_idle_monitor_add_idle_watch (monitor, interval, + dbus_idle_callback, watch, destroy_dbus_watch); + + meta_dbus_idle_monitor_complete_add_idle_watch (skeleton, invocation, watch->watch_id); + + return TRUE; +} + +static gboolean +handle_add_user_active_watch (MetaDBusIdleMonitor *skeleton, + GDBusMethodInvocation *invocation, + MetaIdleMonitor *monitor) +{ + DBusWatch *watch; + + watch = make_dbus_watch (skeleton, invocation, monitor); + watch->watch_id = meta_idle_monitor_add_user_active_watch (monitor, + dbus_idle_callback, watch, + destroy_dbus_watch); + + meta_dbus_idle_monitor_complete_add_user_active_watch (skeleton, invocation, watch->watch_id); + + return TRUE; +} + +static gboolean +handle_remove_watch (MetaDBusIdleMonitor *skeleton, + GDBusMethodInvocation *invocation, + guint id, + MetaIdleMonitor *monitor) +{ + meta_idle_monitor_remove_watch (monitor, id); + meta_dbus_idle_monitor_complete_remove_watch (skeleton, invocation); + + return TRUE; +} + +static void +create_monitor_skeleton (GDBusObjectManagerServer *manager, + MetaIdleMonitor *monitor, + const char *path) +{ + MetaDBusIdleMonitor *skeleton; + MetaDBusObjectSkeleton *object; + + skeleton = meta_dbus_idle_monitor_skeleton_new (); + g_signal_connect_object (skeleton, "handle-add-idle-watch", + G_CALLBACK (handle_add_idle_watch), monitor, 0); + g_signal_connect_object (skeleton, "handle-add-user-active-watch", + G_CALLBACK (handle_add_user_active_watch), monitor, 0); + g_signal_connect_object (skeleton, "handle-remove-watch", + G_CALLBACK (handle_remove_watch), monitor, 0); + g_signal_connect_object (skeleton, "handle-reset-idletime", + G_CALLBACK (handle_reset_idletime), monitor, 0); + g_signal_connect_object (skeleton, "handle-get-idletime", + G_CALLBACK (handle_get_idletime), monitor, 0); + + object = meta_dbus_object_skeleton_new (path); + meta_dbus_object_skeleton_set_idle_monitor (object, skeleton); + + g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (object)); + + g_object_unref (skeleton); + g_object_unref (object); +} + +static void +on_bus_acquired (GDBusConnection *connection, + const char *name, + gpointer user_data) +{ + GDBusObjectManagerServer *manager; + MetaIdleMonitor *monitor; + char *path; + + manager = g_dbus_object_manager_server_new ("/org/gnome/Mutter/IdleMonitor"); + + /* We never clear the core monitor, as that's supposed to cumulate idle times from + all devices */ + monitor = meta_idle_monitor_get_core (); + path = g_strdup ("/org/gnome/Mutter/IdleMonitor/Core"); + create_monitor_skeleton (manager, monitor, path); + g_free (path); + + g_dbus_object_manager_server_set_connection (manager, connection); +} + +static void +on_name_acquired (GDBusConnection *connection, + const char *name, + gpointer user_data) +{ + meta_verbose ("Acquired name %s\n", name); +} + +static void +on_name_lost (GDBusConnection *connection, + const char *name, + gpointer user_data) +{ + meta_verbose ("Lost or failed to acquire name %s\n", name); +} + +void +meta_idle_monitor_init_dbus (void) +{ + static int dbus_name_id; + + if (dbus_name_id > 0) + return; + + dbus_name_id = g_bus_own_name (G_BUS_TYPE_SESSION, + "org.gnome.Mutter.IdleMonitor", + G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT | + (meta_get_replace_current_wm () ? + G_BUS_NAME_OWNER_FLAGS_REPLACE : 0), + on_bus_acquired, + on_name_acquired, + on_name_lost, + NULL, NULL); +} diff --git a/src/backends/meta-idle-monitor-dbus.h b/src/backends/meta-idle-monitor-dbus.h new file mode 100644 index 000000000..a0d703f0e --- /dev/null +++ b/src/backends/meta-idle-monitor-dbus.h @@ -0,0 +1,28 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright 2013 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Adapted from gnome-session/gnome-session/gs-idle-monitor.c and + * from gnome-desktop/libgnome-desktop/gnome-idle-monitor.c + */ + +#ifndef META_IDLE_MONITOR_DBUS_H +#define META_IDLE_MONITOR_DBUS_H + +void meta_idle_monitor_init_dbus (void); + +#endif diff --git a/src/backends/meta-idle-monitor-private.h b/src/backends/meta-idle-monitor-private.h new file mode 100644 index 000000000..d498f13f9 --- /dev/null +++ b/src/backends/meta-idle-monitor-private.h @@ -0,0 +1,59 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright 2013 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Adapted from gnome-session/gnome-session/gs-idle-monitor.c and + * from gnome-desktop/libgnome-desktop/gnome-idle-monitor.c + */ + +#ifndef META_IDLE_MONITOR_PRIVATE_H +#define META_IDLE_MONITOR_PRIVATE_H + +#include "core/display-private.h" +#include "meta/meta-idle-monitor.h" + +typedef struct +{ + MetaIdleMonitor *monitor; + guint id; + MetaIdleMonitorWatchFunc callback; + gpointer user_data; + GDestroyNotify notify; + guint64 timeout_msec; + int idle_source_id; + GSource *timeout_source; +} MetaIdleMonitorWatch; + +struct _MetaIdleMonitor +{ + GObject parent_instance; + + GDBusProxy *session_proxy; + gboolean inhibited; + GHashTable *watches; + ClutterInputDevice *device; + guint64 last_event_time; +}; + +struct _MetaIdleMonitorClass +{ + GObjectClass parent_class; +}; + +void meta_idle_monitor_reset_idletime (MetaIdleMonitor *monitor); + +#endif /* META_IDLE_MONITOR_PRIVATE_H */ diff --git a/src/backends/meta-idle-monitor.c b/src/backends/meta-idle-monitor.c new file mode 100644 index 000000000..f2c6c75db --- /dev/null +++ b/src/backends/meta-idle-monitor.c @@ -0,0 +1,515 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright 2013 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Adapted from gnome-session/gnome-session/gs-idle-monitor.c and + * from gnome-desktop/libgnome-desktop/gnome-idle-monitor.c + */ + +/** + * SECTION:idle-monitor + * @title: MetaIdleMonitor + * @short_description: Mutter idle counter (similar to X's IDLETIME) + */ + +#include "config.h" + +#include <string.h> +#include <X11/Xlib.h> +#include <X11/extensions/sync.h> + +#include "backends/gsm-inhibitor-flag.h" +#include "backends/meta-backend-private.h" +#include "backends/meta-idle-monitor-private.h" +#include "backends/meta-idle-monitor-dbus.h" +#include "clutter/clutter.h" +#include "meta/main.h" +#include "meta/meta-idle-monitor.h" +#include "meta/util.h" + +G_STATIC_ASSERT(sizeof(unsigned long) == sizeof(gpointer)); + +enum +{ + PROP_0, + PROP_DEVICE, + PROP_LAST, +}; + +static GParamSpec *obj_props[PROP_LAST]; + +G_DEFINE_TYPE (MetaIdleMonitor, meta_idle_monitor, G_TYPE_OBJECT) + +static void +meta_idle_monitor_watch_fire (MetaIdleMonitorWatch *watch) +{ + MetaIdleMonitor *monitor; + guint id; + gboolean is_user_active_watch; + + monitor = watch->monitor; + g_object_ref (monitor); + + g_clear_handle_id (&watch->idle_source_id, g_source_remove); + + id = watch->id; + is_user_active_watch = (watch->timeout_msec == 0); + + if (watch->callback) + watch->callback (monitor, id, watch->user_data); + + if (is_user_active_watch) + meta_idle_monitor_remove_watch (monitor, id); + + g_object_unref (monitor); +} + +static void +meta_idle_monitor_dispose (GObject *object) +{ + MetaIdleMonitor *monitor = META_IDLE_MONITOR (object); + + g_clear_pointer (&monitor->watches, g_hash_table_destroy); + g_clear_object (&monitor->session_proxy); + + G_OBJECT_CLASS (meta_idle_monitor_parent_class)->dispose (object); +} + +static void +meta_idle_monitor_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaIdleMonitor *monitor = META_IDLE_MONITOR (object); + + switch (prop_id) + { + case PROP_DEVICE: + g_value_set_object (value, monitor->device); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_idle_monitor_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaIdleMonitor *monitor = META_IDLE_MONITOR (object); + switch (prop_id) + { + case PROP_DEVICE: + monitor->device = g_value_get_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_idle_monitor_class_init (MetaIdleMonitorClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = meta_idle_monitor_dispose; + object_class->get_property = meta_idle_monitor_get_property; + object_class->set_property = meta_idle_monitor_set_property; + + /** + * MetaIdleMonitor:device: + * + * The device to listen to idletime on. + */ + obj_props[PROP_DEVICE] = + g_param_spec_object ("device", + "Device", + "The device to listen to idletime on", + CLUTTER_TYPE_INPUT_DEVICE, + G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + + g_object_class_install_property (object_class, PROP_DEVICE, obj_props[PROP_DEVICE]); +} + +static void +free_watch (gpointer data) +{ + MetaIdleMonitorWatch *watch = (MetaIdleMonitorWatch *) data; + MetaIdleMonitor *monitor = watch->monitor; + + g_object_ref (monitor); + + g_clear_handle_id (&watch->idle_source_id, g_source_remove); + + if (watch->notify != NULL) + watch->notify (watch->user_data); + + if (watch->timeout_source != NULL) + g_source_destroy (watch->timeout_source); + + g_object_unref (monitor); + g_slice_free (MetaIdleMonitorWatch, watch); +} + +static void +update_inhibited_watch (gpointer key, + gpointer value, + gpointer user_data) +{ + MetaIdleMonitor *monitor = user_data; + MetaIdleMonitorWatch *watch = value; + + if (!watch->timeout_source) + return; + + if (monitor->inhibited) + { + g_source_set_ready_time (watch->timeout_source, -1); + } + else + { + g_source_set_ready_time (watch->timeout_source, + monitor->last_event_time + + watch->timeout_msec * 1000); + } +} + +static void +update_inhibited (MetaIdleMonitor *monitor, + gboolean inhibited) +{ + if (inhibited == monitor->inhibited) + return; + + monitor->inhibited = inhibited; + + g_hash_table_foreach (monitor->watches, + update_inhibited_watch, + monitor); +} + +static void +meta_idle_monitor_inhibited_actions_changed (GDBusProxy *session, + GVariant *changed, + char **invalidated, + gpointer user_data) +{ + MetaIdleMonitor *monitor = user_data; + GVariant *v; + + v = g_variant_lookup_value (changed, "InhibitedActions", G_VARIANT_TYPE_UINT32); + if (v) + { + gboolean inhibited; + + inhibited = !!(g_variant_get_uint32 (v) & GSM_INHIBITOR_FLAG_IDLE); + g_variant_unref (v); + + if (!inhibited) + monitor->last_event_time = g_get_monotonic_time (); + update_inhibited (monitor, inhibited); + } +} + +static void +meta_idle_monitor_init (MetaIdleMonitor *monitor) +{ + GVariant *v; + + monitor->watches = g_hash_table_new_full (NULL, NULL, NULL, free_watch); + monitor->last_event_time = g_get_monotonic_time (); + + /* Monitor inhibitors */ + monitor->session_proxy = + g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS | + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, + "org.gnome.SessionManager", + "/org/gnome/SessionManager", + "org.gnome.SessionManager", + NULL, + NULL); + if (!monitor->session_proxy) + return; + + g_signal_connect (monitor->session_proxy, "g-properties-changed", + G_CALLBACK (meta_idle_monitor_inhibited_actions_changed), + monitor); + + v = g_dbus_proxy_get_cached_property (monitor->session_proxy, + "InhibitedActions"); + if (v) + { + monitor->inhibited = !!(g_variant_get_uint32 (v) & + GSM_INHIBITOR_FLAG_IDLE); + g_variant_unref (v); + } +} + +/** + * meta_idle_monitor_get_core: + * + * Returns: (transfer none): the #MetaIdleMonitor that tracks the server-global + * idletime for all devices. + */ +MetaIdleMonitor * +meta_idle_monitor_get_core (void) +{ + MetaBackend *backend = meta_get_backend (); + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + ClutterSeat *seat = clutter_backend_get_default_seat (clutter_backend); + + return meta_backend_get_idle_monitor (backend, clutter_seat_get_pointer (seat)); +} + +static guint32 +get_next_watch_serial (void) +{ + static guint32 serial = 0; + + g_atomic_int_inc (&serial); + + return serial; +} + +static gboolean +idle_monitor_dispatch_timeout (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + MetaIdleMonitorWatch *watch = (MetaIdleMonitorWatch *) user_data; + int64_t now; + int64_t ready_time; + + now = g_source_get_time (source); + ready_time = g_source_get_ready_time (source); + if (ready_time > now) + return G_SOURCE_CONTINUE; + + g_source_set_ready_time (watch->timeout_source, -1); + + meta_idle_monitor_watch_fire (watch); + + return G_SOURCE_CONTINUE; +} + +static GSourceFuncs idle_monitor_source_funcs = { + .prepare = NULL, + .check = NULL, + .dispatch = idle_monitor_dispatch_timeout, + .finalize = NULL, +}; + +static MetaIdleMonitorWatch * +make_watch (MetaIdleMonitor *monitor, + guint64 timeout_msec, + MetaIdleMonitorWatchFunc callback, + gpointer user_data, + GDestroyNotify notify) +{ + MetaIdleMonitorWatch *watch; + + watch = g_slice_new0 (MetaIdleMonitorWatch); + + watch->monitor = monitor; + watch->id = get_next_watch_serial (); + watch->callback = callback; + watch->user_data = user_data; + watch->notify = notify; + watch->timeout_msec = timeout_msec; + + if (timeout_msec != 0) + { + GSource *source = g_source_new (&idle_monitor_source_funcs, + sizeof (GSource)); + + g_source_set_callback (source, NULL, watch, NULL); + if (!monitor->inhibited) + { + g_source_set_ready_time (source, + monitor->last_event_time + + timeout_msec * 1000); + } + g_source_attach (source, NULL); + g_source_unref (source); + + watch->timeout_source = source; + } + + g_hash_table_insert (monitor->watches, + GUINT_TO_POINTER (watch->id), + watch); + return watch; +} + +/** + * meta_idle_monitor_add_idle_watch: + * @monitor: A #MetaIdleMonitor + * @interval_msec: The idletime interval, in milliseconds + * @callback: (nullable): The callback to call when the user has + * accumulated @interval_msec milliseconds of idle time. + * @user_data: (nullable): The user data to pass to the callback + * @notify: A #GDestroyNotify + * + * Returns: a watch id + * + * Adds a watch for a specific idle time. The callback will be called + * when the user has accumulated @interval_msec milliseconds of idle time. + * This function will return an ID that can either be passed to + * meta_idle_monitor_remove_watch(), or can be used to tell idle time + * watches apart if you have more than one. + * + * Also note that this function will only care about positive transitions + * (user's idle time exceeding a certain time). If you want to know about + * when the user has become active, use + * meta_idle_monitor_add_user_active_watch(). + */ +guint +meta_idle_monitor_add_idle_watch (MetaIdleMonitor *monitor, + guint64 interval_msec, + MetaIdleMonitorWatchFunc callback, + gpointer user_data, + GDestroyNotify notify) +{ + MetaIdleMonitorWatch *watch; + + g_return_val_if_fail (META_IS_IDLE_MONITOR (monitor), 0); + g_return_val_if_fail (interval_msec > 0, 0); + + watch = make_watch (monitor, + interval_msec, + callback, + user_data, + notify); + + return watch->id; +} + +/** + * meta_idle_monitor_add_user_active_watch: + * @monitor: A #MetaIdleMonitor + * @callback: (nullable): The callback to call when the user is + * active again. + * @user_data: (nullable): The user data to pass to the callback + * @notify: A #GDestroyNotify + * + * Returns: a watch id + * + * Add a one-time watch to know when the user is active again. + * Note that this watch is one-time and will de-activate after the + * function is called, for efficiency purposes. It's most convenient + * to call this when an idle watch, as added by + * meta_idle_monitor_add_idle_watch(), has triggered. + */ +guint +meta_idle_monitor_add_user_active_watch (MetaIdleMonitor *monitor, + MetaIdleMonitorWatchFunc callback, + gpointer user_data, + GDestroyNotify notify) +{ + MetaIdleMonitorWatch *watch; + + g_return_val_if_fail (META_IS_IDLE_MONITOR (monitor), 0); + + watch = make_watch (monitor, + 0, + callback, + user_data, + notify); + + return watch->id; +} + +/** + * meta_idle_monitor_remove_watch: + * @monitor: A #MetaIdleMonitor + * @id: A watch ID + * + * Removes an idle time watcher, previously added by + * meta_idle_monitor_add_idle_watch() or + * meta_idle_monitor_add_user_active_watch(). + */ +void +meta_idle_monitor_remove_watch (MetaIdleMonitor *monitor, + guint id) +{ + g_return_if_fail (META_IS_IDLE_MONITOR (monitor)); + + g_object_ref (monitor); + g_hash_table_remove (monitor->watches, + GUINT_TO_POINTER (id)); + g_object_unref (monitor); +} + +/** + * meta_idle_monitor_get_idletime: + * @monitor: A #MetaIdleMonitor + * + * Returns: The current idle time, in milliseconds, or -1 for not supported + */ +gint64 +meta_idle_monitor_get_idletime (MetaIdleMonitor *monitor) +{ + return (g_get_monotonic_time () - monitor->last_event_time) / 1000; +} + +void +meta_idle_monitor_reset_idletime (MetaIdleMonitor *monitor) +{ + GList *node, *watch_ids; + + monitor->last_event_time = g_get_monotonic_time (); + + watch_ids = g_hash_table_get_keys (monitor->watches); + + for (node = watch_ids; node != NULL; node = node->next) + { + guint watch_id = GPOINTER_TO_UINT (node->data); + MetaIdleMonitorWatch *watch; + + watch = g_hash_table_lookup (monitor->watches, + GUINT_TO_POINTER (watch_id)); + if (!watch) + continue; + + if (watch->timeout_msec == 0) + { + meta_idle_monitor_watch_fire (watch); + } + else + { + if (monitor->inhibited) + { + g_source_set_ready_time (watch->timeout_source, -1); + } + else + { + g_source_set_ready_time (watch->timeout_source, + monitor->last_event_time + + watch->timeout_msec * 1000); + } + } + } + + g_list_free (watch_ids); +} diff --git a/src/backends/meta-input-device-private.h b/src/backends/meta-input-device-private.h new file mode 100644 index 000000000..a2cbd4864 --- /dev/null +++ b/src/backends/meta-input-device-private.h @@ -0,0 +1,48 @@ +/* + * Copyright © 2020 Red Hat Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ +#ifndef META_INPUT_DEVICE_H +#define META_INPUT_DEVICE_H + +#include <glib-object.h> + +#ifdef HAVE_LIBWACOM +#include <libwacom/libwacom.h> +#endif + +#include "clutter/clutter-mutter.h" + +typedef struct _MetaInputDeviceClass MetaInputDeviceClass; +typedef struct _MetaInputDevice MetaInputDevice; + +struct _MetaInputDeviceClass +{ + ClutterInputDeviceClass parent_class; +}; + +#define META_TYPE_INPUT_DEVICE (meta_input_device_get_type ()) +G_DECLARE_DERIVABLE_TYPE (MetaInputDevice, + meta_input_device, + META, INPUT_DEVICE, + ClutterInputDevice) + +#ifdef HAVE_LIBWACOM +WacomDevice * meta_input_device_get_wacom_device (MetaInputDevice *input_device); +#endif + +#endif /* META_INPUT_DEVICE_H */ diff --git a/src/backends/meta-input-device.c b/src/backends/meta-input-device.c new file mode 100644 index 000000000..e05c024e3 --- /dev/null +++ b/src/backends/meta-input-device.c @@ -0,0 +1,137 @@ +/* + * Copyright © 2020 Red Hat Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#include "config.h" + +#include "backends/meta-backend-private.h" +#include "meta-input-device-private.h" + +typedef struct _MetaInputDevicePrivate MetaInputDevicePrivate; + +struct _MetaInputDevicePrivate +{ +#ifdef HAVE_LIBWACOM + WacomDevice *wacom_device; +#else + /* Just something to have non-zero sized struct otherwise */ + gpointer wacom_device; +#endif +}; + +enum +{ + PROP_WACOM_DEVICE = 1, + N_PROPS +}; + +static GParamSpec *props[N_PROPS] = { 0 }; + +G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaInputDevice, + meta_input_device, + CLUTTER_TYPE_INPUT_DEVICE) + +static void +meta_input_device_init (MetaInputDevice *input_device) +{ +} + +static void +meta_input_device_constructed (GObject *object) +{ + MetaInputDevice *input_device = META_INPUT_DEVICE (object); +#ifdef HAVE_LIBWACOM + WacomDeviceDatabase *wacom_db; + MetaInputDevicePrivate *priv; + const char *node; +#endif + + G_OBJECT_CLASS (meta_input_device_parent_class)->constructed (object); + +#ifdef HAVE_LIBWACOM + priv = meta_input_device_get_instance_private (input_device); + wacom_db = meta_backend_get_wacom_database (meta_get_backend ()); + node = clutter_input_device_get_device_node (CLUTTER_INPUT_DEVICE (input_device)); + priv->wacom_device = libwacom_new_from_path (wacom_db, node, + WFALLBACK_NONE, NULL); +#endif /* HAVE_LIBWACOM */ +} + +static void +meta_input_device_finalize (GObject *object) +{ +#ifdef HAVE_LIBWACOM + MetaInputDevicePrivate *priv; + + priv = meta_input_device_get_instance_private (META_INPUT_DEVICE (object)); + + g_clear_pointer (&priv->wacom_device, libwacom_destroy); +#endif /* HAVE_LIBWACOM */ + + G_OBJECT_CLASS (meta_input_device_parent_class)->finalize (object); +} + +static void +meta_input_device_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaInputDevicePrivate *priv; + + priv = meta_input_device_get_instance_private (META_INPUT_DEVICE (object)); + + switch (prop_id) + { + case PROP_WACOM_DEVICE: + g_value_set_pointer (value, priv->wacom_device); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_input_device_class_init (MetaInputDeviceClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->constructed = meta_input_device_constructed; + object_class->finalize = meta_input_device_finalize; + object_class->get_property = meta_input_device_get_property; + + props[PROP_WACOM_DEVICE] = + g_param_spec_pointer ("wacom-device", + "Wacom device", + "Wacom device", + G_PARAM_READABLE); + + g_object_class_install_properties (object_class, N_PROPS, props); +} + +#ifdef HAVE_LIBWACOM +WacomDevice * +meta_input_device_get_wacom_device (MetaInputDevice *input_device) +{ + MetaInputDevicePrivate *priv; + + priv = meta_input_device_get_instance_private (input_device); + + return priv->wacom_device; +} +#endif /* HAVE_LIBWACOM */ diff --git a/src/backends/meta-input-mapper-private.h b/src/backends/meta-input-mapper-private.h new file mode 100644 index 000000000..cdfdccde9 --- /dev/null +++ b/src/backends/meta-input-mapper-private.h @@ -0,0 +1,49 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright 2018 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef META_INPUT_MAPPER_H +#define META_INPUT_MAPPER_H + +#include <clutter/clutter.h> +#include "meta-monitor-manager-private.h" + +#define META_TYPE_INPUT_MAPPER (meta_input_mapper_get_type ()) + +G_DECLARE_FINAL_TYPE (MetaInputMapper, meta_input_mapper, + META, INPUT_MAPPER, GObject) + +MetaInputMapper * meta_input_mapper_new (void); + +void meta_input_mapper_add_device (MetaInputMapper *mapper, + ClutterInputDevice *device, + gboolean builtin); +void meta_input_mapper_remove_device (MetaInputMapper *mapper, + ClutterInputDevice *device); + +ClutterInputDevice * +meta_input_mapper_get_logical_monitor_device (MetaInputMapper *mapper, + MetaLogicalMonitor *logical_monitor, + ClutterInputDeviceType device_type); +MetaLogicalMonitor * +meta_input_mapper_get_device_logical_monitor (MetaInputMapper *mapper, + ClutterInputDevice *device); + +#endif /* META_INPUT_MAPPER_H */ diff --git a/src/backends/meta-input-mapper.c b/src/backends/meta-input-mapper.c new file mode 100644 index 000000000..a241af3f5 --- /dev/null +++ b/src/backends/meta-input-mapper.c @@ -0,0 +1,703 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * Copyright 2018 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#include "config.h" + +#ifdef HAVE_LIBGUDEV +#include <gudev/gudev.h> +#endif + +#include "meta-input-mapper-private.h" +#include "meta-monitor-manager-private.h" +#include "meta-logical-monitor.h" +#include "meta-backend-private.h" + +#define MAX_SIZE_MATCH_DIFF 0.05 + +typedef struct _MetaMapperInputInfo MetaMapperInputInfo; +typedef struct _MetaMapperOutputInfo MetaMapperOutputInfo; +typedef struct _MappingHelper MappingHelper; +typedef struct _DeviceCandidates DeviceCandidates; + +struct _MetaInputMapper +{ + GObject parent_instance; + MetaMonitorManager *monitor_manager; + ClutterSeat *seat; + GHashTable *input_devices; /* ClutterInputDevice -> MetaMapperInputInfo */ + GHashTable *output_devices; /* MetaLogicalMonitor -> MetaMapperOutputInfo */ +#ifdef HAVE_LIBGUDEV + GUdevClient *udev_client; +#endif +}; + +typedef enum +{ + META_INPUT_CAP_TOUCH = 1 << 0, /* touch device, either touchscreen or tablet */ + META_INPUT_CAP_STYLUS = 1 << 1, /* tablet pen */ + META_INPUT_CAP_ERASER = 1 << 2, /* tablet eraser */ + META_INPUT_CAP_PAD = 1 << 3, /* pad device, most usually in tablets */ + META_INPUT_CAP_CURSOR = 1 << 4 /* pointer-like device in tablets */ +} MetaInputCapabilityFlags; + +typedef enum +{ + META_MATCH_IS_BUILTIN, /* Output is builtin, applies mainly to system-integrated devices */ + META_MATCH_SIZE, /* Size from input device and output match */ + META_MATCH_EDID_FULL, /* Full EDID model match, eg. "Cintiq 12WX" */ + META_MATCH_EDID_PARTIAL, /* Partial EDID model match, eg. "Cintiq" */ + META_MATCH_EDID_VENDOR, /* EDID vendor match, eg. "WAC" for Wacom */ + N_OUTPUT_MATCHES +} MetaOutputMatchType; + +struct _MetaMapperInputInfo +{ + ClutterInputDevice *device; + MetaInputMapper *mapper; + MetaMapperOutputInfo *output; + guint builtin : 1; +}; + +struct _MetaMapperOutputInfo +{ + MetaLogicalMonitor *logical_monitor; + GList *input_devices; + MetaInputCapabilityFlags attached_caps; +}; + +struct _MappingHelper +{ + GArray *device_maps; +}; + +struct _DeviceCandidates +{ + MetaMapperInputInfo *input; + + MetaMonitor *candidates[N_OUTPUT_MATCHES]; + + MetaOutputMatchType best; +}; + +enum +{ + DEVICE_MAPPED, + N_SIGNALS +}; + +static guint signals[N_SIGNALS] = { 0, }; + +G_DEFINE_TYPE (MetaInputMapper, meta_input_mapper, G_TYPE_OBJECT) + +static MetaMapperInputInfo * +mapper_input_info_new (ClutterInputDevice *device, + MetaInputMapper *mapper, + gboolean builtin) +{ + MetaMapperInputInfo *info; + + info = g_new0 (MetaMapperInputInfo, 1); + info->mapper = mapper; + info->device = device; + info->builtin = builtin; + + return info; +} + +static void +mapper_input_info_free (MetaMapperInputInfo *info) +{ + g_free (info); +} + +static MetaMapperOutputInfo * +mapper_output_info_new (MetaLogicalMonitor *logical_monitor) +{ + MetaMapperOutputInfo *info; + + info = g_new0 (MetaMapperOutputInfo, 1); + info->logical_monitor = logical_monitor; + + return info; +} + +static void +mapper_output_info_free (MetaMapperOutputInfo *info) +{ + g_free (info); +} + +static MetaInputCapabilityFlags +mapper_input_info_get_caps (MetaMapperInputInfo *info) +{ + ClutterInputDeviceType type; + + type = clutter_input_device_get_device_type (info->device); + + switch (type) + { + case CLUTTER_TOUCHSCREEN_DEVICE: + return META_INPUT_CAP_TOUCH; + case CLUTTER_TABLET_DEVICE: + case CLUTTER_PEN_DEVICE: + return META_INPUT_CAP_STYLUS; + case CLUTTER_ERASER_DEVICE: + return META_INPUT_CAP_ERASER; + case CLUTTER_CURSOR_DEVICE: + return META_INPUT_CAP_CURSOR; + case CLUTTER_PAD_DEVICE: + return META_INPUT_CAP_PAD; + default: + return 0; + } +} + +static void +mapper_input_info_set_output (MetaMapperInputInfo *input, + MetaMapperOutputInfo *output, + MetaMonitor *monitor) +{ + if (input->output == output) + return; + + input->output = output; + g_signal_emit (input->mapper, signals[DEVICE_MAPPED], 0, + input->device, + output ? output->logical_monitor : NULL, monitor); +} + +static void +mapper_output_info_add_input (MetaMapperOutputInfo *output, + MetaMapperInputInfo *input, + MetaMonitor *monitor) +{ + g_assert (input->output == NULL); + + output->input_devices = g_list_prepend (output->input_devices, input); + output->attached_caps |= mapper_input_info_get_caps (input); + + mapper_input_info_set_output (input, output, monitor); +} + +static void +mapper_output_info_remove_input (MetaMapperOutputInfo *output, + MetaMapperInputInfo *input) +{ + GList *l; + + g_assert (input->output == output); + + output->input_devices = g_list_remove (output->input_devices, input); + output->attached_caps = 0; + + for (l = output->input_devices; l; l = l->next) + output->attached_caps |= mapper_input_info_get_caps (l->data); + + mapper_input_info_set_output (input, NULL, NULL); +} + +static void +mapper_output_info_clear_inputs (MetaMapperOutputInfo *output) +{ + while (output->input_devices) + { + MetaMapperInputInfo *input = output->input_devices->data; + + mapper_input_info_set_output (input, NULL, NULL); + output->input_devices = g_list_remove (output->input_devices, input); + } + + output->attached_caps = 0; +} + +static void +mapping_helper_init (MappingHelper *helper) +{ + helper->device_maps = g_array_new (FALSE, FALSE, sizeof (DeviceCandidates)); +} + +static void +mapping_helper_release (MappingHelper *helper) +{ + g_array_unref (helper->device_maps); +} + +static gboolean +match_edid (MetaMapperInputInfo *input, + MetaMonitor *monitor, + MetaOutputMatchType *match_type) +{ + const gchar *dev_name; + + dev_name = clutter_input_device_get_device_name (input->device); + + if (strcasestr (dev_name, meta_monitor_get_vendor (monitor)) == NULL) + return FALSE; + + *match_type = META_MATCH_EDID_VENDOR; + + if (strcasestr (dev_name, meta_monitor_get_product (monitor)) != NULL) + { + *match_type = META_MATCH_EDID_FULL; + } + else + { + int i; + g_auto (GStrv) split = NULL; + + split = g_strsplit (meta_monitor_get_product (monitor), " ", -1); + + for (i = 0; split[i]; i++) + { + if (strcasestr (dev_name, split[i]) != NULL) + { + *match_type = META_MATCH_EDID_PARTIAL; + break; + } + } + } + + return TRUE; +} + +static gboolean +input_device_get_physical_size (MetaInputMapper *mapper, + ClutterInputDevice *device, + double *width, + double *height) +{ +#ifdef HAVE_LIBGUDEV + g_autoptr (GUdevDevice) udev_device = NULL; + const char *node; + + node = clutter_input_device_get_device_node (device); + udev_device = g_udev_client_query_by_device_file (mapper->udev_client, node); + + if (udev_device && + g_udev_device_has_property (udev_device, "ID_INPUT_WIDTH_MM")) + { + *width = g_udev_device_get_property_as_double (udev_device, + "ID_INPUT_WIDTH_MM"); + *height = g_udev_device_get_property_as_double (udev_device, + "ID_INPUT_HEIGHT_MM"); + return TRUE; + } +#endif + + return FALSE; +} + +static gboolean +find_size_match (MetaMapperInputInfo *input, + GList *monitors, + MetaMonitor **matched_monitor) +{ + double min_w_diff, min_h_diff; + double i_width, i_height; + gboolean found = FALSE; + GList *l; + + min_w_diff = min_h_diff = MAX_SIZE_MATCH_DIFF; + + if (!input_device_get_physical_size (input->mapper, input->device, + &i_width, &i_height)) + return FALSE; + + for (l = monitors; l; l = l->next) + { + MetaMonitor *monitor = l->data; + double w_diff, h_diff; + int o_width, o_height; + + meta_monitor_get_physical_dimensions (monitor, &o_width, &o_height); + w_diff = ABS (1 - ((double) o_width / i_width)); + h_diff = ABS (1 - ((double) o_height / i_height)); + + if (w_diff >= min_w_diff || h_diff >= min_h_diff) + continue; + + *matched_monitor = monitor; + min_w_diff = w_diff; + min_h_diff = h_diff; + found = TRUE; + } + + return found; +} + +static gboolean +find_builtin_output (MetaInputMapper *mapper, + MetaMonitor **matched_monitor) +{ + MetaMonitor *panel; + + panel = meta_monitor_manager_get_laptop_panel (mapper->monitor_manager); + *matched_monitor = panel; + return panel != NULL; +} + +static void +guess_candidates (MetaInputMapper *mapper, + MetaMapperInputInfo *input, + DeviceCandidates *info) +{ + MetaOutputMatchType best = N_OUTPUT_MATCHES; + GList *monitors, *l; + MetaMonitor *matched_monitor = NULL; + + monitors = meta_monitor_manager_get_monitors (mapper->monitor_manager); + + for (l = monitors; l; l = l->next) + { + MetaOutputMatchType edid_match; + + if (match_edid (input, l->data, &edid_match)) + { + best = MIN (best, edid_match); + info->candidates[edid_match] = l->data; + } + } + + if (find_size_match (input, monitors, &matched_monitor)) + { + best = MIN (best, META_MATCH_SIZE); + info->candidates[META_MATCH_SIZE] = matched_monitor; + } + + if (input->builtin || best == N_OUTPUT_MATCHES) + { + best = MIN (best, META_MATCH_IS_BUILTIN); + find_builtin_output (mapper, &info->candidates[META_MATCH_IS_BUILTIN]); + } + + info->best = best; +} + +static void +mapping_helper_add (MappingHelper *helper, + MetaMapperInputInfo *input, + MetaInputMapper *mapper) +{ + DeviceCandidates info = { 0, }; + guint i, pos = 0; + + info.input = input; + + guess_candidates (mapper, input, &info); + + for (i = 0; i < helper->device_maps->len; i++) + { + DeviceCandidates *elem; + + elem = &g_array_index (helper->device_maps, DeviceCandidates, i); + + if (elem->best < info.best) + pos = i; + } + + if (pos >= helper->device_maps->len) + g_array_append_val (helper->device_maps, info); + else + g_array_insert_val (helper->device_maps, pos, info); +} + +static void +mapping_helper_apply (MappingHelper *helper, + MetaInputMapper *mapper) +{ + guint i; + + /* Now, decide which input claims which output */ + for (i = 0; i < helper->device_maps->len; i++) + { + MetaMapperOutputInfo *output; + DeviceCandidates *info; + MetaOutputMatchType j; + + info = &g_array_index (helper->device_maps, DeviceCandidates, i); + + for (j = 0; j < N_OUTPUT_MATCHES; j++) + { + MetaLogicalMonitor *logical_monitor; + + if (!info->candidates[j]) + continue; + + logical_monitor = + meta_monitor_get_logical_monitor (info->candidates[j]); + output = g_hash_table_lookup (mapper->output_devices, + logical_monitor); + + if (!output) + continue; + + if (output->attached_caps & mapper_input_info_get_caps (info->input)) + continue; + + mapper_output_info_add_input (output, info->input, + info->candidates[j]); + break; + } + } +} + +static void +mapper_recalculate_candidates (MetaInputMapper *mapper) +{ + MetaMapperInputInfo *input; + MappingHelper helper; + GHashTableIter iter; + + mapping_helper_init (&helper); + g_hash_table_iter_init (&iter, mapper->input_devices); + + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &input)) + mapping_helper_add (&helper, input, mapper); + + mapping_helper_apply (&helper, mapper); + mapping_helper_release (&helper); +} + +static void +mapper_recalculate_input (MetaInputMapper *mapper, + MetaMapperInputInfo *input) +{ + MappingHelper helper; + + mapping_helper_init (&helper); + mapping_helper_add (&helper, input, mapper); + mapping_helper_apply (&helper, mapper); + mapping_helper_release (&helper); +} + +static void +mapper_update_outputs (MetaInputMapper *mapper) +{ + MetaMapperOutputInfo *output; + GList *logical_monitors, *l; + GHashTableIter iter; + + g_hash_table_iter_init (&iter, mapper->output_devices); + + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &output)) + { + mapper_output_info_clear_inputs (output); + g_hash_table_iter_remove (&iter); + } + + logical_monitors = + meta_monitor_manager_get_logical_monitors (mapper->monitor_manager); + + for (l = logical_monitors; l; l = l->next) + { + MetaLogicalMonitor *logical_monitor = l->data; + MetaMapperOutputInfo *info; + + info = mapper_output_info_new (logical_monitor); + g_hash_table_insert (mapper->output_devices, logical_monitor, info); + } + + mapper_recalculate_candidates (mapper); +} + +static void +input_mapper_monitors_changed_cb (MetaMonitorManager *monitor_manager, + MetaInputMapper *mapper) +{ + mapper_update_outputs (mapper); +} + +static void +input_mapper_device_removed_cb (ClutterSeat *seat, + ClutterInputDevice *device, + MetaInputMapper *mapper) +{ + meta_input_mapper_remove_device (mapper, device); +} + +static void +meta_input_mapper_finalize (GObject *object) +{ + MetaInputMapper *mapper = META_INPUT_MAPPER (object); + + g_signal_handlers_disconnect_by_func (mapper->monitor_manager, + input_mapper_monitors_changed_cb, + mapper); + g_signal_handlers_disconnect_by_func (mapper->seat, + input_mapper_device_removed_cb, + mapper); + + g_hash_table_unref (mapper->input_devices); + g_hash_table_unref (mapper->output_devices); +#ifdef HAVE_LIBGUDEV + g_clear_object (&mapper->udev_client); +#endif + + G_OBJECT_CLASS (meta_input_mapper_parent_class)->finalize (object); +} + +static void +meta_input_mapper_constructed (GObject *object) +{ +#ifdef HAVE_LIBGUDEV + const char *udev_subsystems[] = { "input", NULL }; +#endif + MetaInputMapper *mapper = META_INPUT_MAPPER (object); + MetaBackend *backend; + + G_OBJECT_CLASS (meta_input_mapper_parent_class)->constructed (object); + +#ifdef HAVE_LIBGUDEV + mapper->udev_client = g_udev_client_new (udev_subsystems); +#endif + + mapper->seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); + g_signal_connect (mapper->seat, "device-removed", + G_CALLBACK (input_mapper_device_removed_cb), mapper); + + backend = meta_get_backend (); + mapper->monitor_manager = meta_backend_get_monitor_manager (backend); + g_signal_connect (mapper->monitor_manager, "monitors-changed-internal", + G_CALLBACK (input_mapper_monitors_changed_cb), mapper); + + mapper_update_outputs (mapper); +} + +static void +meta_input_mapper_class_init (MetaInputMapperClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->constructed = meta_input_mapper_constructed; + object_class->finalize = meta_input_mapper_finalize; + + signals[DEVICE_MAPPED] = + g_signal_new ("device-mapped", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 3, + CLUTTER_TYPE_INPUT_DEVICE, + G_TYPE_POINTER, G_TYPE_POINTER); +} + +static void +meta_input_mapper_init (MetaInputMapper *mapper) +{ + mapper->input_devices = + g_hash_table_new_full (NULL, NULL, NULL, + (GDestroyNotify) mapper_input_info_free); + mapper->output_devices = + g_hash_table_new_full (NULL, NULL, NULL, + (GDestroyNotify) mapper_output_info_free); +} + +MetaInputMapper * +meta_input_mapper_new (void) +{ + return g_object_new (META_TYPE_INPUT_MAPPER, NULL); +} + +void +meta_input_mapper_add_device (MetaInputMapper *mapper, + ClutterInputDevice *device, + gboolean builtin) +{ + MetaMapperInputInfo *info; + + g_return_if_fail (mapper != NULL); + g_return_if_fail (device != NULL); + + if (g_hash_table_contains (mapper->input_devices, device)) + return; + + info = mapper_input_info_new (device, mapper, builtin); + g_hash_table_insert (mapper->input_devices, device, info); + mapper_recalculate_input (mapper, info); +} + +void +meta_input_mapper_remove_device (MetaInputMapper *mapper, + ClutterInputDevice *device) +{ + MetaMapperInputInfo *input; + + g_return_if_fail (mapper != NULL); + g_return_if_fail (device != NULL); + + input = g_hash_table_lookup (mapper->input_devices, device); + + if (input) + { + if (input->output) + mapper_output_info_remove_input (input->output, input); + g_hash_table_remove (mapper->input_devices, device); + } +} + +ClutterInputDevice * +meta_input_mapper_get_logical_monitor_device (MetaInputMapper *mapper, + MetaLogicalMonitor *logical_monitor, + ClutterInputDeviceType device_type) +{ + MetaMapperOutputInfo *output; + GList *l; + + output = g_hash_table_lookup (mapper->output_devices, logical_monitor); + if (!output) + return NULL; + + for (l = output->input_devices; l; l = l->next) + { + MetaMapperInputInfo *input = l->data; + + if (clutter_input_device_get_device_type (input->device) == device_type) + return input->device; + } + + return NULL; +} + +MetaLogicalMonitor * +meta_input_mapper_get_device_logical_monitor (MetaInputMapper *mapper, + ClutterInputDevice *device) +{ + MetaMapperOutputInfo *output; + MetaLogicalMonitor *logical_monitor; + GHashTableIter iter; + GList *l; + + g_hash_table_iter_init (&iter, mapper->output_devices); + + while (g_hash_table_iter_next (&iter, (gpointer *) &logical_monitor, + (gpointer *) &output)) + { + for (l = output->input_devices; l; l = l->next) + { + MetaMapperInputInfo *input = l->data; + + if (input->device == device) + return logical_monitor; + } + } + + return NULL; +} diff --git a/src/backends/meta-input-settings-private.h b/src/backends/meta-input-settings-private.h new file mode 100644 index 000000000..176eb8a83 --- /dev/null +++ b/src/backends/meta-input-settings-private.h @@ -0,0 +1,156 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright 2014 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef META_INPUT_SETTINGS_PRIVATE_H +#define META_INPUT_SETTINGS_PRIVATE_H + +#include <libcinnamon-desktop/cdesktop-enums.h> + +#ifdef HAVE_LIBWACOM +#include <libwacom/libwacom.h> +#endif + +#include "backends/meta-backend-types.h" +#include "clutter/clutter.h" +#include "meta/display.h" + +#define META_TYPE_INPUT_SETTINGS (meta_input_settings_get_type ()) +G_DECLARE_DERIVABLE_TYPE (MetaInputSettings, meta_input_settings, + META, INPUT_SETTINGS, GObject) + +struct _MetaInputSettingsClass +{ + GObjectClass parent_class; + + void (* set_send_events) (MetaInputSettings *settings, + ClutterInputDevice *device, + CDesktopDeviceSendEvents mode); + void (* set_matrix) (MetaInputSettings *settings, + ClutterInputDevice *device, + gfloat matrix[6]); + void (* set_speed) (MetaInputSettings *settings, + ClutterInputDevice *device, + gdouble speed); + void (* set_left_handed) (MetaInputSettings *settings, + ClutterInputDevice *device, + gboolean enabled); + void (* set_tap_enabled) (MetaInputSettings *settings, + ClutterInputDevice *device, + gboolean enabled); + void (* set_tap_and_drag_enabled) (MetaInputSettings *settings, + ClutterInputDevice *device, + gboolean enabled); + void (* set_disable_while_typing) (MetaInputSettings *settings, + ClutterInputDevice *device, + gboolean enabled); + void (* set_invert_scroll) (MetaInputSettings *settings, + ClutterInputDevice *device, + gboolean inverted); + void (* set_edge_scroll) (MetaInputSettings *settings, + ClutterInputDevice *device, + gboolean enabled); + void (* set_two_finger_scroll) (MetaInputSettings *settings, + ClutterInputDevice *device, + gboolean enabled); + void (* set_scroll_button) (MetaInputSettings *settings, + ClutterInputDevice *device, + guint button); + + void (* set_click_method) (MetaInputSettings *settings, + ClutterInputDevice *device, + CDesktopTouchpadClickMethod mode); + + void (* set_keyboard_repeat) (MetaInputSettings *settings, + gboolean repeat, + guint delay, + guint interval); + + void (* set_tablet_mapping) (MetaInputSettings *settings, + ClutterInputDevice *device, + CDesktopTabletMapping mapping); + void (* set_tablet_keep_aspect) (MetaInputSettings *settings, + ClutterInputDevice *device, + MetaLogicalMonitor *logical_monitor, + gboolean keep_aspect); + void (* set_tablet_area) (MetaInputSettings *settings, + ClutterInputDevice *device, + gdouble padding_left, + gdouble padding_right, + gdouble padding_top, + gdouble padding_bottom); + + void (* set_mouse_accel_profile) (MetaInputSettings *settings, + ClutterInputDevice *device, + CDesktopPointerAccelProfile profile); + void (* set_trackball_accel_profile) (MetaInputSettings *settings, + ClutterInputDevice *device, + CDesktopPointerAccelProfile profile); + + void (* set_stylus_pressure) (MetaInputSettings *settings, + ClutterInputDevice *device, + ClutterInputDeviceTool *tool, + const gint32 curve[4]); + void (* set_stylus_button_map) (MetaInputSettings *settings, + ClutterInputDevice *device, + ClutterInputDeviceTool *tool, + CDesktopStylusButtonAction primary, + CDesktopStylusButtonAction secondary, + CDesktopStylusButtonAction tertiary); + + void (* set_mouse_middle_click_emulation) (MetaInputSettings *settings, + ClutterInputDevice *device, + gboolean enabled); + void (* set_touchpad_middle_click_emulation) (MetaInputSettings *settings, + ClutterInputDevice *device, + gboolean enabled); + void (* set_trackball_middle_click_emulation) (MetaInputSettings *settings, + ClutterInputDevice *device, + gboolean enabled); + + gboolean (* has_two_finger_scroll) (MetaInputSettings *settings, + ClutterInputDevice *device); + gboolean (* is_trackball_device) (MetaInputSettings *settings, + ClutterInputDevice *device); +}; + +GSettings * meta_input_settings_get_tablet_settings (MetaInputSettings *settings, + ClutterInputDevice *device); +MetaLogicalMonitor * meta_input_settings_get_tablet_logical_monitor (MetaInputSettings *settings, + ClutterInputDevice *device); + +CDesktopTabletMapping meta_input_settings_get_tablet_mapping (MetaInputSettings *settings, + ClutterInputDevice *device); + +gboolean meta_input_settings_is_pad_button_grabbed (MetaInputSettings *input_settings, + ClutterInputDevice *pad, + guint button); + +gboolean meta_input_settings_handle_pad_event (MetaInputSettings *input_settings, + const ClutterEvent *event); +gchar * meta_input_settings_get_pad_action_label (MetaInputSettings *input_settings, + ClutterInputDevice *pad, + MetaPadActionType action, + guint number); + +void meta_input_settings_maybe_save_numlock_state (MetaInputSettings *input_settings); +void meta_input_settings_maybe_restore_numlock_state (MetaInputSettings *input_settings); + +#endif /* META_INPUT_SETTINGS_PRIVATE_H */ diff --git a/src/backends/meta-input-settings.c b/src/backends/meta-input-settings.c new file mode 100644 index 000000000..240efc9fb --- /dev/null +++ b/src/backends/meta-input-settings.c @@ -0,0 +1,2743 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright 2014 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +/** + * SECTION:input-settings + * @title: MetaInputSettings + * @short_description: Mutter input device configuration + */ + +#include "config.h" + +#include <glib/gi18n-lib.h> +#include <string.h> + +#include "backends/meta-backend-private.h" +#include "backends/meta-input-device-private.h" +#include "backends/meta-input-settings-private.h" +#include "backends/meta-input-mapper-private.h" +#include "backends/meta-logical-monitor.h" +#include "backends/meta-monitor.h" +#include "core/display-private.h" +#include "meta/util.h" + +static GQuark quark_tool_settings = 0; + +typedef struct _MetaInputSettingsPrivate MetaInputSettingsPrivate; +typedef struct _DeviceMappingInfo DeviceMappingInfo; +typedef struct _CurrentToolInfo CurrentToolInfo; + +struct _CurrentToolInfo +{ + MetaInputSettings *input_settings; + ClutterInputDevice *device; + ClutterInputDeviceTool *tool; + GSettings *settings; + gulong changed_id; +}; + +struct _DeviceMappingInfo +{ + MetaInputSettings *input_settings; + ClutterInputDevice *device; + GSettings *settings; + gulong changed_id; + guint *group_modes; +}; + +struct _MetaInputSettingsPrivate +{ + ClutterSeat *seat; + MetaMonitorManager *monitor_manager; + gulong monitors_changed_id; + + GSettings *mouse_settings; + GSettings *touchpad_settings; + GSettings *trackball_settings; + GSettings *keyboard_settings; + GSettings *keyboard_a11y_settings; + GSettings *mouse_a11y_settings; + + GHashTable *mappable_devices; + + GHashTable *current_tools; + + ClutterVirtualInputDevice *virtual_pad_keyboard; + + GHashTable *two_finger_devices; + + /* Pad ring/strip emission */ + struct { + ClutterInputDevice *pad; + MetaPadActionType action; + guint number; + gdouble value; + } last_pad_action_info; + + /* For absolute devices with no mapping in settings */ + MetaInputMapper *input_mapper; +}; + +typedef gboolean (* ConfigBoolMappingFunc) (MetaInputSettings *input_settings, + ClutterInputDevice *device, + gboolean value); + +typedef void (*ConfigBoolFunc) (MetaInputSettings *input_settings, + ClutterInputDevice *device, + gboolean setting); +typedef void (*ConfigDoubleFunc) (MetaInputSettings *input_settings, + ClutterInputDevice *device, + gdouble value); +typedef void (*ConfigUintFunc) (MetaInputSettings *input_settings, + ClutterInputDevice *device, + guint value); + +typedef enum +{ + META_PAD_DIRECTION_NONE = -1, + META_PAD_DIRECTION_UP = 0, + META_PAD_DIRECTION_DOWN, + META_PAD_DIRECTION_CW, + META_PAD_DIRECTION_CCW, +} MetaPadDirection; + +G_DEFINE_TYPE_WITH_PRIVATE (MetaInputSettings, meta_input_settings, G_TYPE_OBJECT) + +static GSList * +meta_input_settings_get_devices (MetaInputSettings *settings, + ClutterInputDeviceType type) +{ + MetaInputSettingsPrivate *priv; + GList *l, *devices; + GSList *list = NULL; + + priv = meta_input_settings_get_instance_private (settings); + devices = clutter_seat_list_devices (priv->seat); + + for (l = devices; l; l = l->next) + { + ClutterInputDevice *device = l->data; + + if (clutter_input_device_get_device_type (device) == type && + clutter_input_device_get_device_mode (device) != CLUTTER_INPUT_MODE_MASTER) + list = g_slist_prepend (list, device); + } + + g_list_free (devices); + + return list; +} + +static void +meta_input_settings_dispose (GObject *object) +{ + MetaInputSettings *settings = META_INPUT_SETTINGS (object); + MetaInputSettingsPrivate *priv = meta_input_settings_get_instance_private (settings); + + g_clear_object (&priv->virtual_pad_keyboard); + + g_clear_object (&priv->mouse_settings); + g_clear_object (&priv->touchpad_settings); + g_clear_object (&priv->trackball_settings); + g_clear_object (&priv->keyboard_settings); + g_clear_object (&priv->keyboard_a11y_settings); + g_clear_object (&priv->mouse_a11y_settings); + g_clear_object (&priv->input_mapper); + g_clear_pointer (&priv->mappable_devices, g_hash_table_unref); + g_clear_pointer (&priv->current_tools, g_hash_table_unref); + + if (priv->monitor_manager) + g_clear_signal_handler (&priv->monitors_changed_id, priv->monitor_manager); + + g_clear_object (&priv->monitor_manager); + + g_clear_pointer (&priv->two_finger_devices, g_hash_table_destroy); + + G_OBJECT_CLASS (meta_input_settings_parent_class)->dispose (object); +} + +static void +settings_device_set_bool_setting (MetaInputSettings *input_settings, + ClutterInputDevice *device, + ConfigBoolFunc func, + gboolean enabled) +{ + func (input_settings, device, enabled); +} + +static void +settings_set_bool_setting (MetaInputSettings *input_settings, + ClutterInputDeviceType type, + ConfigBoolMappingFunc mapping_func, + ConfigBoolFunc func, + gboolean enabled) +{ + GSList *devices, *l; + + devices = meta_input_settings_get_devices (input_settings, type); + + for (l = devices; l; l = l->next) + { + gboolean value = enabled; + + if (mapping_func) + value = mapping_func (input_settings, l->data, value); + settings_device_set_bool_setting (input_settings, l->data, func, value); + } + + g_slist_free (devices); +} + +static void +settings_device_set_double_setting (MetaInputSettings *input_settings, + ClutterInputDevice *device, + ConfigDoubleFunc func, + gdouble value) +{ + func (input_settings, device, value); +} + +static void +settings_set_double_setting (MetaInputSettings *input_settings, + ClutterInputDeviceType type, + ConfigDoubleFunc func, + gdouble value) +{ + GSList *devices, *d; + + devices = meta_input_settings_get_devices (input_settings, type); + + for (d = devices; d; d = d->next) + settings_device_set_double_setting (input_settings, d->data, func, value); + + g_slist_free (devices); +} + +static void +settings_device_set_uint_setting (MetaInputSettings *input_settings, + ClutterInputDevice *device, + ConfigUintFunc func, + guint value) +{ + (func) (input_settings, device, value); +} + +static void +settings_set_uint_setting (MetaInputSettings *input_settings, + ClutterInputDeviceType type, + ConfigUintFunc func, + guint value) +{ + GSList *devices, *d; + + devices = meta_input_settings_get_devices (input_settings, type); + + for (d = devices; d; d = d->next) + settings_device_set_uint_setting (input_settings, d->data, func, value); + + g_slist_free (devices); +} + +static void +update_touchpad_left_handed (MetaInputSettings *input_settings, + ClutterInputDevice *device) +{ + MetaInputSettingsClass *input_settings_class; + CDesktopTouchpadHandedness handedness; + MetaInputSettingsPrivate *priv; + gboolean enabled = FALSE; + + if (device && + clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE) + return; + + priv = meta_input_settings_get_instance_private (input_settings); + input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings); + handedness = g_settings_get_enum (priv->touchpad_settings, "left-handed"); + + switch (handedness) + { + case C_DESKTOP_TOUCHPAD_HANDEDNESS_RIGHT: + enabled = FALSE; + break; + case C_DESKTOP_TOUCHPAD_HANDEDNESS_LEFT: + enabled = TRUE; + break; + case C_DESKTOP_TOUCHPAD_HANDEDNESS_MOUSE: + enabled = g_settings_get_boolean (priv->mouse_settings, "left-handed"); + break; + default: + g_assert_not_reached (); + } + + if (device) + { + settings_device_set_bool_setting (input_settings, device, + input_settings_class->set_left_handed, + enabled); + } + else + { + settings_set_bool_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE, NULL, + input_settings_class->set_left_handed, + enabled); + } +} + +static void +update_mouse_left_handed (MetaInputSettings *input_settings, + ClutterInputDevice *device) +{ + MetaInputSettingsClass *input_settings_class; + MetaInputSettingsPrivate *priv; + gboolean enabled; + + if (device && + clutter_input_device_get_device_type (device) != CLUTTER_POINTER_DEVICE) + return; + + priv = meta_input_settings_get_instance_private (input_settings); + input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings); + enabled = g_settings_get_boolean (priv->mouse_settings, "left-handed"); + + if (device) + { + settings_device_set_bool_setting (input_settings, device, + input_settings_class->set_left_handed, + enabled); + } + else + { + CDesktopTouchpadHandedness touchpad_handedness; + + settings_set_bool_setting (input_settings, CLUTTER_POINTER_DEVICE, NULL, + input_settings_class->set_left_handed, + enabled); + + touchpad_handedness = g_settings_get_enum (priv->touchpad_settings, + "left-handed"); + + /* Also update touchpads if they're following mouse settings */ + if (touchpad_handedness == C_DESKTOP_TOUCHPAD_HANDEDNESS_MOUSE) + update_touchpad_left_handed (input_settings, NULL); + } +} + +static void +do_update_pointer_accel_profile (MetaInputSettings *input_settings, + GSettings *settings, + ClutterInputDevice *device, + CDesktopPointerAccelProfile profile) +{ + MetaInputSettingsPrivate *priv = + meta_input_settings_get_instance_private (input_settings); + MetaInputSettingsClass *input_settings_class = + META_INPUT_SETTINGS_GET_CLASS (input_settings); + + if (settings == priv->mouse_settings) + input_settings_class->set_mouse_accel_profile (input_settings, + device, + profile); + else if (settings == priv->trackball_settings) + input_settings_class->set_trackball_accel_profile (input_settings, + device, + profile); +} + +static void +update_pointer_accel_profile (MetaInputSettings *input_settings, + GSettings *settings, + ClutterInputDevice *device) +{ + CDesktopPointerAccelProfile profile; + + profile = g_settings_get_enum (settings, "accel-profile"); + + if (device) + { + do_update_pointer_accel_profile (input_settings, settings, + device, profile); + } + else + { + MetaInputSettingsPrivate *priv = + meta_input_settings_get_instance_private (input_settings); + GList *l, *devices; + + devices = clutter_seat_list_devices (priv->seat); + for (l = devices; l; l = l->next) + { + device = l->data; + + if (clutter_input_device_get_device_mode (device) == + CLUTTER_INPUT_MODE_MASTER) + continue; + + do_update_pointer_accel_profile (input_settings, settings, + device, profile); + } + + g_list_free (devices); + } +} + +static GSettings * +get_settings_for_device_type (MetaInputSettings *input_settings, + ClutterInputDeviceType type) +{ + MetaInputSettingsPrivate *priv; + priv = meta_input_settings_get_instance_private (input_settings); + switch (type) + { + case CLUTTER_POINTER_DEVICE: + return priv->mouse_settings; + case CLUTTER_TOUCHPAD_DEVICE: + return priv->touchpad_settings; + default: + return NULL; + } +} + +static void +update_middle_click_emulation (MetaInputSettings *input_settings, + GSettings *settings, + ClutterInputDevice *device) +{ + ConfigBoolFunc func; + const gchar *key = "middle-click-emulation"; + MetaInputSettingsPrivate *priv = meta_input_settings_get_instance_private (input_settings); + + if (!settings) + return; + + if (settings == priv->mouse_settings) + func = META_INPUT_SETTINGS_GET_CLASS (input_settings)->set_mouse_middle_click_emulation; + else if (settings == priv->touchpad_settings) + func = META_INPUT_SETTINGS_GET_CLASS (input_settings)->set_touchpad_middle_click_emulation; + else if (settings == priv->trackball_settings) + func = META_INPUT_SETTINGS_GET_CLASS (input_settings)->set_trackball_middle_click_emulation; + else + return; + + if (device) + { + settings_device_set_bool_setting (input_settings, device, func, + g_settings_get_boolean (settings, key)); + } + else + { + settings_set_bool_setting (input_settings, CLUTTER_POINTER_DEVICE, + NULL, func, + g_settings_get_boolean (settings, key)); + } +} + +static void +update_device_speed (MetaInputSettings *input_settings, + ClutterInputDevice *device) +{ + GSettings *settings; + ConfigDoubleFunc func; + const gchar *key = "speed"; + + func = META_INPUT_SETTINGS_GET_CLASS (input_settings)->set_speed; + + if (device) + { + settings = get_settings_for_device_type (input_settings, + clutter_input_device_get_device_type (device)); + if (!settings) + return; + + settings_device_set_double_setting (input_settings, device, func, + g_settings_get_double (settings, key)); + } + else + { + settings = get_settings_for_device_type (input_settings, CLUTTER_POINTER_DEVICE); + settings_set_double_setting (input_settings, CLUTTER_POINTER_DEVICE, func, + g_settings_get_double (settings, key)); + settings = get_settings_for_device_type (input_settings, CLUTTER_TOUCHPAD_DEVICE); + settings_set_double_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE, func, + g_settings_get_double (settings, key)); + } +} + +static void +update_device_natural_scroll (MetaInputSettings *input_settings, + ClutterInputDevice *device) +{ + GSettings *settings; + ConfigBoolFunc func; + const gchar *key = "natural-scroll"; + + func = META_INPUT_SETTINGS_GET_CLASS (input_settings)->set_invert_scroll; + + if (device) + { + settings = get_settings_for_device_type (input_settings, + clutter_input_device_get_device_type (device)); + if (!settings) + return; + + settings_device_set_bool_setting (input_settings, device, func, + g_settings_get_boolean (settings, key)); + } + else + { + settings = get_settings_for_device_type (input_settings, CLUTTER_POINTER_DEVICE); + settings_set_bool_setting (input_settings, CLUTTER_POINTER_DEVICE, + NULL, func, + g_settings_get_boolean (settings, key)); + settings = get_settings_for_device_type (input_settings, CLUTTER_TOUCHPAD_DEVICE); + settings_set_bool_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE, + NULL, func, + g_settings_get_boolean (settings, key)); + } +} + +static void +update_touchpad_disable_while_typing (MetaInputSettings *input_settings, + ClutterInputDevice *device) +{ + GSettings *settings; + MetaInputSettingsClass *input_settings_class; + MetaInputSettingsPrivate *priv; + gboolean enabled; + const gchar *key = "disable-while-typing"; + + if (device && + clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE) + return; + + priv = meta_input_settings_get_instance_private (input_settings); + input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings); + enabled = g_settings_get_boolean (priv->touchpad_settings, key); + + if (device) + { + settings = get_settings_for_device_type (input_settings, + clutter_input_device_get_device_type (device)); + + if (!settings) + return; + + settings_device_set_bool_setting (input_settings, device, + input_settings_class->set_disable_while_typing, + enabled); + } + else + { + settings_set_bool_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE, NULL, + input_settings_class->set_disable_while_typing, + enabled); + } +} + +static gboolean +device_is_tablet_touchpad (MetaInputSettings *input_settings, + ClutterInputDevice *device) +{ +#ifdef HAVE_LIBWACOM + WacomIntegrationFlags flags = 0; + WacomDevice *wacom_device; + + if (clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE) + return FALSE; + + wacom_device = meta_input_device_get_wacom_device (META_INPUT_DEVICE (device)); + + if (wacom_device) + { + flags = libwacom_get_integration_flags (wacom_device); + + if ((flags & (WACOM_DEVICE_INTEGRATED_SYSTEM | + WACOM_DEVICE_INTEGRATED_DISPLAY)) == 0) + return TRUE; + } +#endif + + return FALSE; +} + +static gboolean +force_enable_on_tablet (MetaInputSettings *input_settings, + ClutterInputDevice *device, + gboolean value) +{ + return device_is_tablet_touchpad (input_settings, device) || value; +} + +static void +update_touchpad_tap_enabled (MetaInputSettings *input_settings, + ClutterInputDevice *device) +{ + MetaInputSettingsClass *input_settings_class; + MetaInputSettingsPrivate *priv; + gboolean enabled; + + if (device && + clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE) + return; + + priv = meta_input_settings_get_instance_private (input_settings); + input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings); + enabled = g_settings_get_boolean (priv->touchpad_settings, "tap-to-click"); + + if (device) + { + enabled = force_enable_on_tablet (input_settings, device, enabled); + settings_device_set_bool_setting (input_settings, device, + input_settings_class->set_tap_enabled, + enabled); + } + else + { + settings_set_bool_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE, + force_enable_on_tablet, + input_settings_class->set_tap_enabled, + enabled); + } +} + +static void +update_touchpad_tap_and_drag_enabled (MetaInputSettings *input_settings, + ClutterInputDevice *device) +{ + MetaInputSettingsClass *input_settings_class; + MetaInputSettingsPrivate *priv; + gboolean enabled; + + if (device && + clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE) + return; + + priv = meta_input_settings_get_instance_private (input_settings); + input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings); + enabled = g_settings_get_boolean (priv->touchpad_settings, "tap-and-drag"); + + if (device) + { + enabled = force_enable_on_tablet (input_settings, device, enabled); + settings_device_set_bool_setting (input_settings, device, + input_settings_class->set_tap_and_drag_enabled, + enabled); + } + else + { + settings_set_bool_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE, + force_enable_on_tablet, + input_settings_class->set_tap_and_drag_enabled, + enabled); + } +} + +static void +update_touchpad_edge_scroll (MetaInputSettings *input_settings, + ClutterInputDevice *device) +{ + MetaInputSettingsClass *input_settings_class; + gboolean edge_scroll_enabled; + gboolean two_finger_scroll_enabled; + gboolean two_finger_scroll_available; + MetaInputSettingsPrivate *priv; + + if (device && + clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE) + return; + + priv = meta_input_settings_get_instance_private (input_settings); + input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings); + edge_scroll_enabled = g_settings_get_boolean (priv->touchpad_settings, "edge-scrolling-enabled"); + two_finger_scroll_enabled = g_settings_get_boolean (priv->touchpad_settings, "two-finger-scrolling-enabled"); + two_finger_scroll_available = g_hash_table_size (priv->two_finger_devices) > 0; + + /* If both are enabled we prefer two finger. */ + if (edge_scroll_enabled && two_finger_scroll_enabled && two_finger_scroll_available) + edge_scroll_enabled = FALSE; + + if (device) + { + settings_device_set_bool_setting (input_settings, device, + input_settings_class->set_edge_scroll, + edge_scroll_enabled); + } + else + { + settings_set_bool_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE, NULL, + (ConfigBoolFunc) input_settings_class->set_edge_scroll, + edge_scroll_enabled); + } +} + +static void +update_touchpad_two_finger_scroll (MetaInputSettings *input_settings, + ClutterInputDevice *device) +{ + MetaInputSettingsClass *input_settings_class; + gboolean two_finger_scroll_enabled; + MetaInputSettingsPrivate *priv; + + if (device && + clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE) + return; + + priv = meta_input_settings_get_instance_private (input_settings); + input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings); + two_finger_scroll_enabled = g_settings_get_boolean (priv->touchpad_settings, "two-finger-scrolling-enabled"); + + /* Disable edge since they can't both be set. */ + if (two_finger_scroll_enabled) + update_touchpad_edge_scroll (input_settings, device); + + if (device) + { + settings_device_set_bool_setting (input_settings, device, + input_settings_class->set_two_finger_scroll, + two_finger_scroll_enabled); + } + else + { + settings_set_bool_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE, NULL, + (ConfigBoolFunc) input_settings_class->set_two_finger_scroll, + two_finger_scroll_enabled); + } + + /* Edge might have been disabled because two finger was on. */ + if (!two_finger_scroll_enabled) + update_touchpad_edge_scroll (input_settings, device); +} + +static void +update_touchpad_click_method (MetaInputSettings *input_settings, + ClutterInputDevice *device) +{ + MetaInputSettingsClass *input_settings_class; + CDesktopTouchpadClickMethod method; + MetaInputSettingsPrivate *priv; + + if (device && + clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE) + return; + + priv = meta_input_settings_get_instance_private (input_settings); + input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings); + method = g_settings_get_enum (priv->touchpad_settings, "click-method"); + + if (device) + { + settings_device_set_uint_setting (input_settings, device, + input_settings_class->set_click_method, + method); + } + else + { + settings_set_uint_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE, + (ConfigUintFunc) input_settings_class->set_click_method, + method); + } +} + +static void +update_touchpad_send_events (MetaInputSettings *input_settings, + ClutterInputDevice *device) +{ + MetaInputSettingsClass *input_settings_class; + MetaInputSettingsPrivate *priv; + CDesktopDeviceSendEvents mode; + + if (device && + clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE) + return; + + priv = meta_input_settings_get_instance_private (input_settings); + input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings); + mode = g_settings_get_enum (priv->touchpad_settings, "send-events"); + + if (device) + { + settings_device_set_uint_setting (input_settings, device, + input_settings_class->set_send_events, + mode); + } + else + { + settings_set_uint_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE, + input_settings_class->set_send_events, + mode); + } +} + +static void +update_trackball_scroll_button (MetaInputSettings *input_settings, + ClutterInputDevice *device) +{ + MetaInputSettingsClass *input_settings_class; + MetaInputSettingsPrivate *priv; + guint button; + + priv = meta_input_settings_get_instance_private (input_settings); + input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings); + + if (device && !input_settings_class->is_trackball_device (input_settings, device)) + return; + + /* This key is 'i' in the schema but it also specifies a minimum + * range of 0 so the cast here is safe. */ + button = (guint) g_settings_get_int (priv->trackball_settings, "scroll-wheel-emulation-button"); + + if (device) + { + input_settings_class->set_scroll_button (input_settings, device, button); + } + else if (!device) + { + GList *l, *devices; + + devices = clutter_seat_list_devices (priv->seat); + + for (l = devices; l; l = l->next) + { + device = l->data; + + if (input_settings_class->is_trackball_device (input_settings, device)) + input_settings_class->set_scroll_button (input_settings, device, button); + } + + g_list_free (devices); + } +} + +static void +update_keyboard_repeat (MetaInputSettings *input_settings) +{ + MetaInputSettingsClass *input_settings_class; + MetaInputSettingsPrivate *priv; + guint delay, interval; + gboolean repeat; + + priv = meta_input_settings_get_instance_private (input_settings); + repeat = g_settings_get_boolean (priv->keyboard_settings, "repeat"); + delay = g_settings_get_uint (priv->keyboard_settings, "delay"); + interval = g_settings_get_uint (priv->keyboard_settings, "repeat-interval"); + + delay = MAX (1, delay); + interval = MAX (1, interval); + + input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings); + input_settings_class->set_keyboard_repeat (input_settings, + repeat, delay, interval); +} + +static MetaMonitor * +logical_monitor_find_monitor (MetaLogicalMonitor *logical_monitor, + const char *vendor, + const char *product, + const char *serial) +{ + GList *monitors; + GList *l; + + monitors = meta_logical_monitor_get_monitors (logical_monitor); + for (l = monitors; l; l = l->next) + { + MetaMonitor *monitor = l->data; + + if (g_strcmp0 (meta_monitor_get_vendor (monitor), vendor) == 0 && + g_strcmp0 (meta_monitor_get_product (monitor), product) == 0 && + g_strcmp0 (meta_monitor_get_serial (monitor), serial) == 0) + return monitor; + } + + return NULL; +} + +static void +meta_input_settings_find_monitor (MetaInputSettings *input_settings, + GSettings *settings, + ClutterInputDevice *device, + MetaMonitor **out_monitor, + MetaLogicalMonitor **out_logical_monitor) +{ + MetaInputSettingsPrivate *priv; + MetaMonitorManager *monitor_manager; + MetaMonitor *monitor; + guint n_values; + GList *logical_monitors; + GList *l; + gchar **edid; + + priv = meta_input_settings_get_instance_private (input_settings); + edid = g_settings_get_strv (settings, "output"); + n_values = g_strv_length (edid); + + if (n_values != 3) + { + g_warning ("EDID configuration for device '%s' " + "is incorrect, must have 3 values", + clutter_input_device_get_device_name (device)); + goto out; + } + + if (!*edid[0] && !*edid[1] && !*edid[2]) + goto out; + + monitor_manager = priv->monitor_manager; + logical_monitors = + meta_monitor_manager_get_logical_monitors (monitor_manager); + for (l = logical_monitors; l; l = l->next) + { + MetaLogicalMonitor *logical_monitor = l->data; + + monitor = logical_monitor_find_monitor (logical_monitor, + edid[0], edid[1], edid[2]); + if (monitor) + { + if (out_monitor) + *out_monitor = monitor; + if (out_logical_monitor) + *out_logical_monitor = logical_monitor; + break; + } + } + +out: + g_strfreev (edid); +} + +static gboolean +meta_input_settings_delegate_on_mapper (MetaInputSettings *input_settings, + ClutterInputDevice *device) +{ + MetaInputSettingsPrivate *priv; + gboolean builtin = FALSE; + + priv = meta_input_settings_get_instance_private (input_settings); + +#ifdef HAVE_LIBWACOM + if (clutter_input_device_get_device_type (device) != CLUTTER_TOUCHSCREEN_DEVICE) + { + WacomDevice *wacom_device; + WacomIntegrationFlags flags = 0; + + wacom_device = + meta_input_device_get_wacom_device (META_INPUT_DEVICE (device)); + + if (wacom_device) + { + flags = libwacom_get_integration_flags (wacom_device); + + if ((flags & (WACOM_DEVICE_INTEGRATED_SYSTEM | + WACOM_DEVICE_INTEGRATED_DISPLAY)) == 0) + return FALSE; + + builtin = (flags & WACOM_DEVICE_INTEGRATED_SYSTEM) != 0; + } + } +#endif + + meta_input_mapper_add_device (priv->input_mapper, device, builtin); + return TRUE; +} + +static void +update_tablet_keep_aspect (MetaInputSettings *input_settings, + GSettings *settings, + ClutterInputDevice *device) +{ + MetaInputSettingsClass *input_settings_class; + MetaLogicalMonitor *logical_monitor = NULL; + gboolean keep_aspect; + + if (clutter_input_device_get_device_type (device) != CLUTTER_TABLET_DEVICE && + clutter_input_device_get_device_type (device) != CLUTTER_PEN_DEVICE && + clutter_input_device_get_device_type (device) != CLUTTER_ERASER_DEVICE) + return; + +#ifdef HAVE_LIBWACOM + { + WacomDevice *wacom_device; + + wacom_device = meta_input_device_get_wacom_device (META_INPUT_DEVICE (device)); + + /* Keep aspect only makes sense in external tablets */ + if (wacom_device && + libwacom_get_integration_flags (wacom_device) != WACOM_DEVICE_INTEGRATED_NONE) + return; + } +#endif + + input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings); + + if (clutter_input_device_get_mapping_mode (device) == + CLUTTER_INPUT_DEVICE_MAPPING_ABSOLUTE) + { + keep_aspect = g_settings_get_boolean (settings, "keep-aspect"); + meta_input_settings_find_monitor (input_settings, settings, device, + NULL, &logical_monitor); + } + else + { + keep_aspect = FALSE; + } + + input_settings_class->set_tablet_keep_aspect (input_settings, device, + logical_monitor, keep_aspect); +} + +static void +update_device_display (MetaInputSettings *input_settings, + GSettings *settings, + ClutterInputDevice *device) +{ + MetaInputSettingsClass *input_settings_class; + MetaInputSettingsPrivate *priv; + gfloat matrix[6] = { 1, 0, 0, 0, 1, 0 }; + MetaMonitor *monitor = NULL; + MetaLogicalMonitor *logical_monitor = NULL; + + if (clutter_input_device_get_device_type (device) != CLUTTER_TABLET_DEVICE && + clutter_input_device_get_device_type (device) != CLUTTER_PEN_DEVICE && + clutter_input_device_get_device_type (device) != CLUTTER_ERASER_DEVICE && + clutter_input_device_get_device_type (device) != CLUTTER_TOUCHSCREEN_DEVICE) + return; + + priv = meta_input_settings_get_instance_private (input_settings); + input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings); + + /* If mapping is relative, the device can move on all displays */ + if (clutter_input_device_get_device_type (device) == CLUTTER_TOUCHSCREEN_DEVICE || + clutter_input_device_get_mapping_mode (device) == + CLUTTER_INPUT_DEVICE_MAPPING_ABSOLUTE) + { + meta_input_settings_find_monitor (input_settings, settings, device, + &monitor, &logical_monitor); + if (monitor) + { + meta_input_mapper_remove_device (priv->input_mapper, device); + meta_monitor_manager_get_monitor_matrix (priv->monitor_manager, + monitor, logical_monitor, matrix); + } + else + { + if (meta_input_settings_delegate_on_mapper (input_settings, device)) + return; + } + } + + input_settings_class->set_matrix (input_settings, device, matrix); + + /* Ensure the keep-aspect mapping is updated */ + update_tablet_keep_aspect (input_settings, settings, device); +} + +static void +update_tablet_mapping (MetaInputSettings *input_settings, + GSettings *settings, + ClutterInputDevice *device) +{ + MetaInputSettingsClass *input_settings_class; + CDesktopTabletMapping mapping; + + if (clutter_input_device_get_device_type (device) != CLUTTER_TABLET_DEVICE && + clutter_input_device_get_device_type (device) != CLUTTER_PEN_DEVICE && + clutter_input_device_get_device_type (device) != CLUTTER_ERASER_DEVICE) + return; + +#ifdef HAVE_LIBWACOM + { + WacomDevice *wacom_device; + + wacom_device = meta_input_device_get_wacom_device (META_INPUT_DEVICE (device)); + + /* Tablet mapping only makes sense on external tablets */ + if (wacom_device && + (libwacom_get_integration_flags (wacom_device) != WACOM_DEVICE_INTEGRATED_NONE)) + return; + } +#endif + + input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings); + mapping = g_settings_get_enum (settings, "mapping"); + + settings_device_set_uint_setting (input_settings, device, + input_settings_class->set_tablet_mapping, + mapping); + + /* Relative mapping disables keep-aspect/display */ + update_tablet_keep_aspect (input_settings, settings, device); + update_device_display (input_settings, settings, device); +} + +static void +update_tablet_area (MetaInputSettings *input_settings, + GSettings *settings, + ClutterInputDevice *device) +{ + MetaInputSettingsClass *input_settings_class; + GVariant *variant; + const gdouble *area; + gsize n_elems; + + if (clutter_input_device_get_device_type (device) != CLUTTER_TABLET_DEVICE && + clutter_input_device_get_device_type (device) != CLUTTER_PEN_DEVICE && + clutter_input_device_get_device_type (device) != CLUTTER_ERASER_DEVICE) + return; + +#ifdef HAVE_LIBWACOM + { + WacomDevice *wacom_device; + + wacom_device = meta_input_device_get_wacom_device (META_INPUT_DEVICE (device)); + + /* Tablet area only makes sense on system/display integrated tablets */ + if (wacom_device && + (libwacom_get_integration_flags (wacom_device) & + (WACOM_DEVICE_INTEGRATED_SYSTEM | WACOM_DEVICE_INTEGRATED_DISPLAY)) == 0) + return; + } +#endif + + input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings); + variant = g_settings_get_value (settings, "area"); + + area = g_variant_get_fixed_array (variant, &n_elems, sizeof (gdouble)); + if (n_elems == 4) + { + input_settings_class->set_tablet_area (input_settings, device, + area[0], area[1], + area[2], area[3]); + } + + g_variant_unref (variant); +} + +static void +update_tablet_left_handed (MetaInputSettings *input_settings, + GSettings *settings, + ClutterInputDevice *device) +{ + MetaInputSettingsClass *input_settings_class; + gboolean enabled; + + if (clutter_input_device_get_device_type (device) != CLUTTER_TABLET_DEVICE && + clutter_input_device_get_device_type (device) != CLUTTER_PEN_DEVICE && + clutter_input_device_get_device_type (device) != CLUTTER_ERASER_DEVICE && + clutter_input_device_get_device_type (device) != CLUTTER_PAD_DEVICE) + return; + +#ifdef HAVE_LIBWACOM + { + WacomDevice *wacom_device; + + wacom_device = meta_input_device_get_wacom_device (META_INPUT_DEVICE (device)); + + /* Left handed mode only makes sense on external tablets */ + if (wacom_device && + (libwacom_get_integration_flags (wacom_device) != WACOM_DEVICE_INTEGRATED_NONE)) + return; + } +#endif + + input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings); + enabled = g_settings_get_boolean (settings, "left-handed"); + + settings_device_set_bool_setting (input_settings, device, + input_settings_class->set_left_handed, + enabled); +} + +static void +meta_input_settings_changed_cb (GSettings *settings, + const char *key, + gpointer user_data) +{ + MetaInputSettings *input_settings = META_INPUT_SETTINGS (user_data); + MetaInputSettingsPrivate *priv = meta_input_settings_get_instance_private (input_settings); + + if (settings == priv->mouse_settings) + { + if (strcmp (key, "left-handed") == 0) + update_mouse_left_handed (input_settings, NULL); + else if (strcmp (key, "speed") == 0) + update_device_speed (input_settings, NULL); + else if (strcmp (key, "natural-scroll") == 0) + update_device_natural_scroll (input_settings, NULL); + else if (strcmp (key, "accel-profile") == 0) + update_pointer_accel_profile (input_settings, settings, NULL); + else if (strcmp (key, "middle-click-emulation") == 0) + update_middle_click_emulation (input_settings, settings, NULL); + } + else if (settings == priv->touchpad_settings) + { + if (strcmp (key, "left-handed") == 0) + update_touchpad_left_handed (input_settings, NULL); + else if (strcmp (key, "speed") == 0) + update_device_speed (input_settings, NULL); + else if (strcmp (key, "natural-scroll") == 0) + update_device_natural_scroll (input_settings, NULL); + else if (strcmp (key, "tap-to-click") == 0) + update_touchpad_tap_enabled (input_settings, NULL); + else if (strcmp (key, "tap-and-drag") == 0) + update_touchpad_tap_and_drag_enabled (input_settings, NULL); + else if (strcmp(key, "disable-while-typing") == 0) + update_touchpad_disable_while_typing (input_settings, NULL); + else if (strcmp (key, "send-events") == 0) + update_touchpad_send_events (input_settings, NULL); + else if (strcmp (key, "edge-scrolling-enabled") == 0) + update_touchpad_edge_scroll (input_settings, NULL); + else if (strcmp (key, "two-finger-scrolling-enabled") == 0) + update_touchpad_two_finger_scroll (input_settings, NULL); + else if (strcmp (key, "click-method") == 0) + update_touchpad_click_method (input_settings, NULL); + else if (strcmp (key, "middle-click-emulation") == 0) + update_middle_click_emulation (input_settings, settings, NULL); + } + else if (settings == priv->trackball_settings) + { + if (strcmp (key, "scroll-wheel-emulation-button") == 0) + update_trackball_scroll_button (input_settings, NULL); + else if (strcmp (key, "accel-profile") == 0) + update_pointer_accel_profile (input_settings, settings, NULL); + else if (strcmp (key, "middle-click-emulation") == 0) + update_middle_click_emulation (input_settings, settings, NULL); + } + else if (settings == priv->keyboard_settings) + { + if (strcmp (key, "repeat") == 0 || + strcmp (key, "repeat-interval") == 0 || + strcmp (key, "delay") == 0) + update_keyboard_repeat (input_settings); + else if (strcmp (key, "remember-numlock-state") == 0) + meta_input_settings_maybe_save_numlock_state (input_settings); + } +} + +static void +mapped_device_changed_cb (GSettings *settings, + const gchar *key, + DeviceMappingInfo *info) +{ + if (strcmp (key, "output") == 0) + update_device_display (info->input_settings, settings, info->device); + else if (strcmp (key, "mapping") == 0) + update_tablet_mapping (info->input_settings, settings, info->device); + else if (strcmp (key, "area") == 0) + update_tablet_area (info->input_settings, settings, info->device); + else if (strcmp (key, "keep-aspect") == 0) + update_tablet_keep_aspect (info->input_settings, settings, info->device); + else if (strcmp (key, "left-handed") == 0) + update_tablet_left_handed (info->input_settings, settings, info->device); +} + +static void +apply_mappable_device_settings (MetaInputSettings *input_settings, + DeviceMappingInfo *info) +{ + ClutterInputDeviceType device_type; + + update_device_display (input_settings, info->settings, info->device); + device_type = clutter_input_device_get_device_type (info->device); + + if (device_type == CLUTTER_TABLET_DEVICE || + device_type == CLUTTER_PEN_DEVICE || + device_type == CLUTTER_ERASER_DEVICE || + device_type == CLUTTER_PAD_DEVICE) + { + update_tablet_mapping (input_settings, info->settings, info->device); + update_tablet_area (input_settings, info->settings, info->device); + update_tablet_keep_aspect (input_settings, info->settings, info->device); + update_tablet_left_handed (input_settings, info->settings, info->device); + } +} + +struct _keyboard_a11y_settings_flags_pair { + const char *name; + ClutterKeyboardA11yFlags flag; +} keyboard_a11y_settings_flags_pair[] = { + { "enable", CLUTTER_A11Y_KEYBOARD_ENABLED }, + { "timeout-enable", CLUTTER_A11Y_TIMEOUT_ENABLED }, + { "mousekeys-enable", CLUTTER_A11Y_MOUSE_KEYS_ENABLED }, + { "slowkeys-enable", CLUTTER_A11Y_SLOW_KEYS_ENABLED }, + { "slowkeys-beep-press", CLUTTER_A11Y_SLOW_KEYS_BEEP_PRESS }, + { "slowkeys-beep-accept", CLUTTER_A11Y_SLOW_KEYS_BEEP_ACCEPT }, + { "slowkeys-beep-reject", CLUTTER_A11Y_SLOW_KEYS_BEEP_REJECT }, + { "bouncekeys-enable", CLUTTER_A11Y_BOUNCE_KEYS_ENABLED }, + { "bouncekeys-beep-reject", CLUTTER_A11Y_BOUNCE_KEYS_BEEP_REJECT }, + { "togglekeys-enable", CLUTTER_A11Y_TOGGLE_KEYS_ENABLED }, + { "stickykeys-enable", CLUTTER_A11Y_STICKY_KEYS_ENABLED }, + { "stickykeys-modifier-beep", CLUTTER_A11Y_STICKY_KEYS_BEEP }, + { "stickykeys-two-key-off", CLUTTER_A11Y_STICKY_KEYS_TWO_KEY_OFF }, + { "feature-state-change-beep", CLUTTER_A11Y_FEATURE_STATE_CHANGE_BEEP }, +}; + +static void +load_keyboard_a11y_settings (MetaInputSettings *input_settings, + ClutterInputDevice *device) +{ + MetaInputSettingsPrivate *priv = meta_input_settings_get_instance_private (input_settings); + ClutterKbdA11ySettings kbd_a11y_settings = { 0 }; + ClutterInputDevice *core_keyboard; + ClutterBackend *backend = clutter_get_default_backend (); + ClutterSeat *seat = clutter_backend_get_default_seat (backend); + guint i; + + core_keyboard = clutter_seat_get_keyboard (priv->seat); + if (device && device != core_keyboard) + return; + + kbd_a11y_settings.controls = 0; + for (i = 0; i < G_N_ELEMENTS (keyboard_a11y_settings_flags_pair); i++) + { + if (g_settings_get_boolean (priv->keyboard_a11y_settings, keyboard_a11y_settings_flags_pair[i].name)) + kbd_a11y_settings.controls |= keyboard_a11y_settings_flags_pair[i].flag; + } + + kbd_a11y_settings.timeout_delay = g_settings_get_int (priv->keyboard_a11y_settings, + "disable-timeout"); + kbd_a11y_settings.slowkeys_delay = g_settings_get_int (priv->keyboard_a11y_settings, + "slowkeys-delay"); + kbd_a11y_settings.debounce_delay = g_settings_get_int (priv->keyboard_a11y_settings, + "bouncekeys-delay"); + kbd_a11y_settings.mousekeys_init_delay = g_settings_get_int (priv->keyboard_a11y_settings, + "mousekeys-init-delay"); + kbd_a11y_settings.mousekeys_max_speed = g_settings_get_int (priv->keyboard_a11y_settings, + "mousekeys-max-speed"); + kbd_a11y_settings.mousekeys_accel_time = g_settings_get_int (priv->keyboard_a11y_settings, + "mousekeys-accel-time"); + + clutter_seat_set_kbd_a11y_settings (seat, &kbd_a11y_settings); +} + +static void +on_keyboard_a11y_settings_changed (ClutterSeat *seat, + ClutterKeyboardA11yFlags new_flags, + ClutterKeyboardA11yFlags what_changed, + MetaInputSettings *input_settings) +{ + MetaInputSettingsPrivate *priv = meta_input_settings_get_instance_private (input_settings); + guint i; + + for (i = 0; i < G_N_ELEMENTS (keyboard_a11y_settings_flags_pair); i++) + { + if (keyboard_a11y_settings_flags_pair[i].flag & what_changed) + g_settings_set_boolean (priv->keyboard_a11y_settings, + keyboard_a11y_settings_flags_pair[i].name, + (new_flags & keyboard_a11y_settings_flags_pair[i].flag) ? TRUE : FALSE); + } +} + +static void +meta_input_keyboard_a11y_settings_changed (GSettings *settings, + const char *key, + gpointer user_data) +{ + MetaInputSettings *input_settings = META_INPUT_SETTINGS (user_data); + + load_keyboard_a11y_settings (input_settings, NULL); +} + +struct _pointer_a11y_settings_flags_pair { + const char *name; + ClutterPointerA11yFlags flag; +} pointer_a11y_settings_flags_pair[] = { + { "secondary-click-enabled", CLUTTER_A11Y_SECONDARY_CLICK_ENABLED }, + { "dwell-click-enabled", CLUTTER_A11Y_DWELL_ENABLED }, +}; + +static ClutterPointerA11yDwellDirection +pointer_a11y_dwell_direction_from_setting (MetaInputSettings *input_settings, + const char *key) +{ + MetaInputSettingsPrivate *priv = meta_input_settings_get_instance_private (input_settings); + CDesktopMouseDwellDirection dwell_gesture_direction; + + dwell_gesture_direction = g_settings_get_enum (priv->mouse_a11y_settings, key); + switch (dwell_gesture_direction) + { + case C_DESKTOP_MOUSE_DWELL_DIRECTION_LEFT: + return CLUTTER_A11Y_DWELL_DIRECTION_LEFT; + break; + case C_DESKTOP_MOUSE_DWELL_DIRECTION_RIGHT: + return CLUTTER_A11Y_DWELL_DIRECTION_RIGHT; + break; + case C_DESKTOP_MOUSE_DWELL_DIRECTION_UP: + return CLUTTER_A11Y_DWELL_DIRECTION_UP; + break; + case C_DESKTOP_MOUSE_DWELL_DIRECTION_DOWN: + return CLUTTER_A11Y_DWELL_DIRECTION_DOWN; + break; + default: + break; + } + return CLUTTER_A11Y_DWELL_DIRECTION_NONE; +} + +static void +load_pointer_a11y_settings (MetaInputSettings *input_settings, + ClutterInputDevice *device) +{ + MetaInputSettingsPrivate *priv = meta_input_settings_get_instance_private (input_settings); + ClutterPointerA11ySettings pointer_a11y_settings; + ClutterInputDevice *core_pointer; + CDesktopMouseDwellMode dwell_mode; + guint i; + + core_pointer = clutter_seat_get_pointer (priv->seat); + if (device && device != core_pointer) + return; + + clutter_seat_get_pointer_a11y_settings (CLUTTER_SEAT (priv->seat), + &pointer_a11y_settings); + pointer_a11y_settings.controls = 0; + for (i = 0; i < G_N_ELEMENTS (pointer_a11y_settings_flags_pair); i++) + { + if (g_settings_get_boolean (priv->mouse_a11y_settings, pointer_a11y_settings_flags_pair[i].name)) + pointer_a11y_settings.controls |= pointer_a11y_settings_flags_pair[i].flag; + } + + /* "secondary-click-time" is expressed in seconds */ + pointer_a11y_settings.secondary_click_delay = + (1000 * g_settings_get_double (priv->mouse_a11y_settings, "secondary-click-time")); + /* "dwell-time" is expressed in seconds */ + pointer_a11y_settings.dwell_delay = + (1000 * g_settings_get_double (priv->mouse_a11y_settings, "dwell-time")); + pointer_a11y_settings.dwell_threshold = g_settings_get_int (priv->mouse_a11y_settings, + "dwell-threshold"); + + dwell_mode = g_settings_get_enum (priv->mouse_a11y_settings, "dwell-mode"); + if (dwell_mode == C_DESKTOP_MOUSE_DWELL_MODE_WINDOW) + pointer_a11y_settings.dwell_mode = CLUTTER_A11Y_DWELL_MODE_WINDOW; + else + pointer_a11y_settings.dwell_mode = CLUTTER_A11Y_DWELL_MODE_GESTURE; + + pointer_a11y_settings.dwell_gesture_single = + pointer_a11y_dwell_direction_from_setting (input_settings, "dwell-gesture-single"); + pointer_a11y_settings.dwell_gesture_double = + pointer_a11y_dwell_direction_from_setting (input_settings, "dwell-gesture-double"); + pointer_a11y_settings.dwell_gesture_drag = + pointer_a11y_dwell_direction_from_setting (input_settings, "dwell-gesture-drag"); + pointer_a11y_settings.dwell_gesture_secondary = + pointer_a11y_dwell_direction_from_setting (input_settings, "dwell-gesture-secondary"); + + clutter_seat_set_pointer_a11y_settings (CLUTTER_SEAT (priv->seat), + &pointer_a11y_settings); +} + +static void +meta_input_mouse_a11y_settings_changed (GSettings *settings, + const char *key, + gpointer user_data) +{ + MetaInputSettings *input_settings = META_INPUT_SETTINGS (user_data); + + load_pointer_a11y_settings (input_settings, NULL); +} + +static GSettings * +lookup_device_settings (ClutterInputDevice *device) +{ + const gchar *group, *schema, *vendor, *product; + ClutterInputDeviceType type; + GSettings *settings; + gchar *path; + + type = clutter_input_device_get_device_type (device); + + if (type == CLUTTER_TOUCHSCREEN_DEVICE) + { + group = "touchscreens"; + schema = "org.cinnamon.desktop.peripherals.touchscreen"; + } + else if (type == CLUTTER_TABLET_DEVICE || + type == CLUTTER_PEN_DEVICE || + type == CLUTTER_ERASER_DEVICE || + type == CLUTTER_CURSOR_DEVICE || + type == CLUTTER_PAD_DEVICE) + { + group = "tablets"; + schema = "org.cinnamon.desktop.peripherals.tablet"; + } + else + return NULL; + + vendor = clutter_input_device_get_vendor_id (device); + product = clutter_input_device_get_product_id (device); + path = g_strdup_printf ("/org/cinnamon/desktop/peripherals/%s/%s:%s/", + group, vendor, product); + + settings = g_settings_new_with_path (schema, path); + g_free (path); + + return settings; +} + +static GSettings * +lookup_tool_settings (ClutterInputDeviceTool *tool, + ClutterInputDevice *device) +{ + GSettings *tool_settings; + guint64 serial; + gchar *path; + + tool_settings = g_object_get_qdata (G_OBJECT (tool), quark_tool_settings); + if (tool_settings) + return tool_settings; + + serial = clutter_input_device_tool_get_serial (tool); + + /* The Wacom driver uses serial 1 for serial-less devices but 1 is not a + * real serial, so let's custom-case this */ + if (serial == 0 || serial == 1) + { + path = g_strdup_printf ("/org/cinnamon/desktop/peripherals/stylus/default-%s:%s/", + clutter_input_device_get_vendor_id (device), + clutter_input_device_get_product_id (device)); + } + else + { + path = g_strdup_printf ("/org/cinnamon/desktop/peripherals/stylus/%" G_GINT64_MODIFIER "x/", + serial); + } + + tool_settings = + g_settings_new_with_path ("org.cinnamon.desktop.peripherals.tablet.stylus", + path); + g_object_set_qdata_full (G_OBJECT (tool), quark_tool_settings, tool_settings, + (GDestroyNotify) g_object_unref); + g_free (path); + + return tool_settings; +} + +static GSettings * +lookup_pad_action_settings (ClutterInputDevice *device, + MetaPadActionType action, + guint number, + MetaPadDirection direction, + gint mode) +{ + const gchar *vendor, *product, *action_type, *detail_type = NULL; + GSettings *settings; + GString *path; + gchar action_label; + + vendor = clutter_input_device_get_vendor_id (device); + product = clutter_input_device_get_product_id (device); + + action_label = 'A' + number; + + switch (action) + { + case META_PAD_ACTION_BUTTON: + action_type = "button"; + break; + case META_PAD_ACTION_RING: + g_assert (direction == META_PAD_DIRECTION_CW || + direction == META_PAD_DIRECTION_CCW); + action_type = "ring"; + detail_type = (direction == META_PAD_DIRECTION_CW) ? "cw" : "ccw"; + break; + case META_PAD_ACTION_STRIP: + g_assert (direction == META_PAD_DIRECTION_UP || + direction == META_PAD_DIRECTION_DOWN); + action_type = "strip"; + detail_type = (direction == META_PAD_DIRECTION_UP) ? "up" : "down"; + break; + default: + return NULL; + } + + path = g_string_new (NULL); + g_string_append_printf (path, "/org/cinnamon/desktop/peripherals/tablets/%s:%s/%s%c", + vendor, product, action_type, action_label); + + if (detail_type) + g_string_append_printf (path, "-%s", detail_type); + + if (mode >= 0) + g_string_append_printf (path, "-mode-%d", mode); + + g_string_append_c (path, '/'); + + settings = g_settings_new_with_path ("org.cinnamon.desktop.peripherals.tablet.pad-button", + path->str); + g_string_free (path, TRUE); + + return settings; +} + +static void +monitors_changed_cb (MetaMonitorManager *monitor_manager, + MetaInputSettings *input_settings) +{ + MetaInputSettingsPrivate *priv; + ClutterInputDevice *device; + DeviceMappingInfo *info; + GHashTableIter iter; + + priv = meta_input_settings_get_instance_private (input_settings); + g_hash_table_iter_init (&iter, priv->mappable_devices); + + while (g_hash_table_iter_next (&iter, (gpointer *) &device, + (gpointer *) &info)) + update_device_display (input_settings, info->settings, device); +} + +static void +input_mapper_device_mapped_cb (MetaInputMapper *mapper, + ClutterInputDevice *device, + MetaLogicalMonitor *logical_monitor, + MetaMonitor *monitor, + MetaInputSettings *input_settings) +{ + MetaInputSettingsPrivate *priv; + float matrix[6] = { 1, 0, 0, 0, 1, 0 }; + + priv = meta_input_settings_get_instance_private (input_settings); + + if (monitor && logical_monitor) + { + meta_monitor_manager_get_monitor_matrix (priv->monitor_manager, + monitor, logical_monitor, + matrix); + } + + META_INPUT_SETTINGS_GET_CLASS (input_settings)->set_matrix (input_settings, + device, matrix); +} + +static void +device_mapping_info_free (DeviceMappingInfo *info) +{ + g_clear_signal_handler (&info->changed_id, info->settings); + g_object_unref (info->settings); + g_free (info->group_modes); + g_slice_free (DeviceMappingInfo, info); +} + +static gboolean +check_add_mappable_device (MetaInputSettings *input_settings, + ClutterInputDevice *device) +{ + MetaInputSettingsPrivate *priv; + DeviceMappingInfo *info; + ClutterInputDeviceType device_type; + GSettings *settings; + + device_type = clutter_input_device_get_device_type (device); + + if ((device_type == CLUTTER_TABLET_DEVICE || + device_type == CLUTTER_PEN_DEVICE || + device_type == CLUTTER_ERASER_DEVICE || + device_type == CLUTTER_PAD_DEVICE) && + g_getenv ("MUTTER_DISABLE_WACOM_CONFIGURATION") != NULL) + return FALSE; + + settings = lookup_device_settings (device); + + if (!settings) + return FALSE; + + priv = meta_input_settings_get_instance_private (input_settings); + + info = g_slice_new0 (DeviceMappingInfo); + info->input_settings = input_settings; + info->device = device; + info->settings = settings; + + if (device_type == CLUTTER_PAD_DEVICE) + { + info->group_modes = + g_new0 (guint, clutter_input_device_get_n_mode_groups (device)); + } + + info->changed_id = g_signal_connect (settings, "changed", + G_CALLBACK (mapped_device_changed_cb), + info); + + g_hash_table_insert (priv->mappable_devices, device, info); + + apply_mappable_device_settings (input_settings, info); + + return TRUE; +} + +static void +apply_device_settings (MetaInputSettings *input_settings, + ClutterInputDevice *device) +{ + MetaInputSettingsPrivate *priv = + meta_input_settings_get_instance_private (input_settings); + + update_device_speed (input_settings, device); + update_device_natural_scroll (input_settings, device); + + update_mouse_left_handed (input_settings, device); + update_pointer_accel_profile (input_settings, + priv->mouse_settings, + device); + + update_touchpad_left_handed (input_settings, device); + update_touchpad_tap_enabled (input_settings, device); + update_touchpad_tap_and_drag_enabled (input_settings, device); + update_touchpad_disable_while_typing (input_settings, device); + update_touchpad_send_events (input_settings, device); + update_touchpad_two_finger_scroll (input_settings, device); + update_touchpad_edge_scroll (input_settings, device); + update_touchpad_click_method (input_settings, device); + + update_trackball_scroll_button (input_settings, device); + update_pointer_accel_profile (input_settings, + priv->trackball_settings, + device); + load_keyboard_a11y_settings (input_settings, device); + load_pointer_a11y_settings (input_settings, device); + + update_middle_click_emulation (input_settings, priv->mouse_settings, device); + update_middle_click_emulation (input_settings, priv->touchpad_settings, device); + update_middle_click_emulation (input_settings, priv->trackball_settings, device); +} + +static void +update_stylus_pressure (MetaInputSettings *input_settings, + ClutterInputDevice *device, + ClutterInputDeviceTool *tool) +{ + MetaInputSettingsClass *input_settings_class; + GSettings *tool_settings; + const gint32 *curve; + GVariant *variant; + gsize n_elems; + + if (clutter_input_device_get_device_type (device) != CLUTTER_TABLET_DEVICE && + clutter_input_device_get_device_type (device) != CLUTTER_PEN_DEVICE && + clutter_input_device_get_device_type (device) != CLUTTER_ERASER_DEVICE) + return; + + if (!tool) + return; + + tool_settings = lookup_tool_settings (tool, device); + + if (clutter_input_device_tool_get_tool_type (tool) == + CLUTTER_INPUT_DEVICE_TOOL_ERASER) + variant = g_settings_get_value (tool_settings, "eraser-pressure-curve"); + else + variant = g_settings_get_value (tool_settings, "pressure-curve"); + + curve = g_variant_get_fixed_array (variant, &n_elems, sizeof (gint32)); + if (n_elems != 4) + return; + + input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings); + input_settings_class->set_stylus_pressure (input_settings, device, tool, curve); +} + +static void +update_stylus_buttonmap (MetaInputSettings *input_settings, + ClutterInputDevice *device, + ClutterInputDeviceTool *tool) +{ + MetaInputSettingsClass *input_settings_class; + CDesktopStylusButtonAction primary, secondary, tertiary; + GSettings *tool_settings; + + if (clutter_input_device_get_device_type (device) != CLUTTER_TABLET_DEVICE && + clutter_input_device_get_device_type (device) != CLUTTER_PEN_DEVICE && + clutter_input_device_get_device_type (device) != CLUTTER_ERASER_DEVICE) + return; + + if (!tool) + return; + + tool_settings = lookup_tool_settings (tool, device); + + primary = g_settings_get_enum (tool_settings, "button-action"); + secondary = g_settings_get_enum (tool_settings, "secondary-button-action"); + tertiary = g_settings_get_enum (tool_settings, "tertiary-button-action"); + + input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings); + input_settings_class->set_stylus_button_map (input_settings, device, tool, + primary, secondary, tertiary); +} + +static void +apply_stylus_settings (MetaInputSettings *input_settings, + ClutterInputDevice *device, + ClutterInputDeviceTool *tool) +{ + update_stylus_pressure (input_settings, device, tool); + update_stylus_buttonmap (input_settings, device, tool); +} + +static void +evaluate_two_finger_scrolling (MetaInputSettings *input_settings, + ClutterInputDevice *device) +{ + MetaInputSettingsClass *klass; + MetaInputSettingsPrivate *priv; + + if (clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE) + return; + + klass = META_INPUT_SETTINGS_GET_CLASS (input_settings); + priv = meta_input_settings_get_instance_private (input_settings); + + if (klass->has_two_finger_scroll (input_settings, device)) + g_hash_table_add (priv->two_finger_devices, device); +} + +static void +meta_input_settings_device_added (ClutterSeat *seat, + ClutterInputDevice *device, + MetaInputSettings *input_settings) +{ + if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER) + return; + + evaluate_two_finger_scrolling (input_settings, device); + + apply_device_settings (input_settings, device); + check_add_mappable_device (input_settings, device); +} + +static void +meta_input_settings_device_removed (ClutterSeat *seat, + ClutterInputDevice *device, + MetaInputSettings *input_settings) +{ + MetaInputSettingsPrivate *priv; + + priv = meta_input_settings_get_instance_private (input_settings); + meta_input_mapper_remove_device (priv->input_mapper, device); + g_hash_table_remove (priv->mappable_devices, device); + g_hash_table_remove (priv->current_tools, device); + + if (g_hash_table_remove (priv->two_finger_devices, device) && + g_hash_table_size (priv->two_finger_devices) == 0) + apply_device_settings (input_settings, NULL); +} + +static void +current_tool_changed_cb (GSettings *settings, + const char *key, + gpointer user_data) +{ + CurrentToolInfo *info = user_data; + + apply_stylus_settings (info->input_settings, info->device, info->tool); +} + +static CurrentToolInfo * +current_tool_info_new (MetaInputSettings *input_settings, + ClutterInputDevice *device, + ClutterInputDeviceTool *tool) +{ + CurrentToolInfo *info; + + info = g_new0 (CurrentToolInfo, 1); + info->input_settings = input_settings; + info->device = device; + info->tool = tool; + info->settings = lookup_tool_settings (tool, device); + info->changed_id = + g_signal_connect (info->settings, "changed", + G_CALLBACK (current_tool_changed_cb), + info); + return info; +} + +static void +current_tool_info_free (CurrentToolInfo *info) +{ + g_clear_signal_handler (&info->changed_id, info->settings); + g_free (info); +} + +static void +meta_input_settings_tool_changed (ClutterSeat *seat, + ClutterInputDevice *device, + ClutterInputDeviceTool *tool, + MetaInputSettings *input_settings) +{ + MetaInputSettingsPrivate *priv; + + priv = meta_input_settings_get_instance_private (input_settings); + + if (tool) + { + CurrentToolInfo *current_tool; + + current_tool = current_tool_info_new (input_settings, device, tool); + g_hash_table_insert (priv->current_tools, device, current_tool); + apply_stylus_settings (input_settings, device, tool); + } + else + { + g_hash_table_remove (priv->current_tools, device); + } +} + +static void +check_mappable_devices (MetaInputSettings *input_settings) +{ + MetaInputSettingsPrivate *priv; + GList *l, *devices; + + priv = meta_input_settings_get_instance_private (input_settings); + devices = clutter_seat_list_devices (priv->seat); + + for (l = devices; l; l = l->next) + { + ClutterInputDevice *device = l->data; + + if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER) + continue; + + check_add_mappable_device (input_settings, device); + } + + g_list_free (devices); +} + +static void +power_save_mode_changed_cb (MetaMonitorManager *manager, + gpointer user_data) +{ + MetaInputSettingsPrivate *priv; + ClutterInputDevice *device; + MetaLogicalMonitor *logical_monitor; + MetaMonitor *builtin; + MetaPowerSave power_save_mode; + gboolean on; + + power_save_mode = meta_monitor_manager_get_power_save_mode (manager); + on = power_save_mode == META_POWER_SAVE_ON; + priv = meta_input_settings_get_instance_private (user_data); + + builtin = meta_monitor_manager_get_laptop_panel (manager); + if (!builtin) + return; + + logical_monitor = meta_monitor_get_logical_monitor (builtin); + if (!logical_monitor) + return; + + device = + meta_input_mapper_get_logical_monitor_device (priv->input_mapper, + logical_monitor, + CLUTTER_TOUCHSCREEN_DEVICE); + if (!device) + return; + + clutter_input_device_set_enabled (device, on); +} + +static void +meta_input_settings_constructed (GObject *object) +{ + MetaInputSettings *input_settings = META_INPUT_SETTINGS (object); + GSList *devices, *d; + + devices = meta_input_settings_get_devices (input_settings, CLUTTER_TOUCHPAD_DEVICE); + for (d = devices; d; d = d->next) + evaluate_two_finger_scrolling (input_settings, d->data); + + g_slist_free (devices); + + apply_device_settings (input_settings, NULL); + update_keyboard_repeat (input_settings); + check_mappable_devices (input_settings); +} + +static void +meta_input_settings_class_init (MetaInputSettingsClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = meta_input_settings_dispose; + object_class->constructed = meta_input_settings_constructed; + + quark_tool_settings = + g_quark_from_static_string ("meta-input-settings-tool-settings"); +} + +static void +meta_input_settings_init (MetaInputSettings *settings) +{ + MetaInputSettingsPrivate *priv; + + priv = meta_input_settings_get_instance_private (settings); + priv->seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); + g_signal_connect (priv->seat, "device-added", + G_CALLBACK (meta_input_settings_device_added), settings); + g_signal_connect (priv->seat, "device-removed", + G_CALLBACK (meta_input_settings_device_removed), settings); + g_signal_connect (priv->seat, "tool-changed", + G_CALLBACK (meta_input_settings_tool_changed), settings); + + priv->mouse_settings = g_settings_new ("org.cinnamon.desktop.peripherals.mouse"); + g_signal_connect (priv->mouse_settings, "changed", + G_CALLBACK (meta_input_settings_changed_cb), settings); + + priv->touchpad_settings = g_settings_new ("org.cinnamon.desktop.peripherals.touchpad"); + g_signal_connect (priv->touchpad_settings, "changed", + G_CALLBACK (meta_input_settings_changed_cb), settings); + + priv->trackball_settings = g_settings_new ("org.cinnamon.desktop.peripherals.trackball"); + g_signal_connect (priv->trackball_settings, "changed", + G_CALLBACK (meta_input_settings_changed_cb), settings); + + priv->keyboard_settings = g_settings_new ("org.cinnamon.desktop.peripherals.keyboard"); + g_signal_connect (priv->keyboard_settings, "changed", + G_CALLBACK (meta_input_settings_changed_cb), settings); + + priv->keyboard_a11y_settings = g_settings_new ("org.cinnamon.desktop.a11y.keyboard"); + g_signal_connect (priv->keyboard_a11y_settings, "changed", + G_CALLBACK (meta_input_keyboard_a11y_settings_changed), settings); + g_signal_connect (priv->seat, "kbd-a11y-flags-changed", + G_CALLBACK (on_keyboard_a11y_settings_changed), settings); + + priv->mouse_a11y_settings = g_settings_new ("org.cinnamon.desktop.a11y.mouse"); + g_signal_connect (priv->mouse_a11y_settings, "changed", + G_CALLBACK (meta_input_mouse_a11y_settings_changed), settings); + + priv->mappable_devices = + g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) device_mapping_info_free); + + priv->current_tools = + g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) current_tool_info_free); + + priv->monitor_manager = g_object_ref (meta_monitor_manager_get ()); + g_signal_connect (priv->monitor_manager, "monitors-changed-internal", + G_CALLBACK (monitors_changed_cb), settings); + g_signal_connect (priv->monitor_manager, "power-save-mode-changed", + G_CALLBACK (power_save_mode_changed_cb), settings); + + priv->two_finger_devices = g_hash_table_new (NULL, NULL); + + priv->input_mapper = meta_input_mapper_new (); + g_signal_connect (priv->input_mapper, "device-mapped", + G_CALLBACK (input_mapper_device_mapped_cb), settings); +} + +GSettings * +meta_input_settings_get_tablet_settings (MetaInputSettings *settings, + ClutterInputDevice *device) +{ + MetaInputSettingsPrivate *priv; + DeviceMappingInfo *info; + + g_return_val_if_fail (META_IS_INPUT_SETTINGS (settings), NULL); + g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL); + + priv = meta_input_settings_get_instance_private (settings); + info = g_hash_table_lookup (priv->mappable_devices, device); + + return info ? g_object_ref (info->settings) : NULL; +} + +static ClutterInputDevice * +find_grouped_pen (MetaInputSettings *settings, + ClutterInputDevice *device) +{ + MetaInputSettingsPrivate *priv; + GList *l, *devices; + ClutterInputDeviceType device_type; + ClutterInputDevice *pen = NULL; + + device_type = clutter_input_device_get_device_type (device); + + if (device_type == CLUTTER_TABLET_DEVICE || + device_type == CLUTTER_PEN_DEVICE) + return device; + + priv = meta_input_settings_get_instance_private (settings); + devices = clutter_seat_list_devices (priv->seat); + + for (l = devices; l; l = l->next) + { + ClutterInputDevice *other_device = l->data; + + device_type = clutter_input_device_get_device_type (other_device); + + if ((device_type == CLUTTER_TABLET_DEVICE || + device_type == CLUTTER_PEN_DEVICE) && + clutter_input_device_is_grouped (device, other_device)) + { + pen = other_device; + break; + } + } + + g_list_free (devices); + + return pen; +} + +MetaLogicalMonitor * +meta_input_settings_get_tablet_logical_monitor (MetaInputSettings *settings, + ClutterInputDevice *device) +{ + MetaLogicalMonitor *logical_monitor = NULL; + MetaInputSettingsPrivate *priv; + DeviceMappingInfo *info; + + g_return_val_if_fail (META_IS_INPUT_SETTINGS (settings), NULL); + g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL); + + if (clutter_input_device_get_device_type (device) == CLUTTER_PAD_DEVICE) + { + device = find_grouped_pen (settings, device); + if (!device) + return NULL; + } + + priv = meta_input_settings_get_instance_private (settings); + info = g_hash_table_lookup (priv->mappable_devices, device); + if (!info) + return NULL; + + logical_monitor = + meta_input_mapper_get_device_logical_monitor (priv->input_mapper, device); + + if (!logical_monitor) + { + meta_input_settings_find_monitor (settings, info->settings, device, + NULL, &logical_monitor); + } + + return logical_monitor; +} + +CDesktopTabletMapping +meta_input_settings_get_tablet_mapping (MetaInputSettings *settings, + ClutterInputDevice *device) +{ + MetaInputSettingsPrivate *priv; + DeviceMappingInfo *info; + + g_return_val_if_fail (META_IS_INPUT_SETTINGS (settings), + C_DESKTOP_TABLET_MAPPING_ABSOLUTE); + g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), + C_DESKTOP_TABLET_MAPPING_ABSOLUTE); + + priv = meta_input_settings_get_instance_private (settings); + info = g_hash_table_lookup (priv->mappable_devices, device); + g_return_val_if_fail (info != NULL, C_DESKTOP_TABLET_MAPPING_ABSOLUTE); + + return g_settings_get_enum (info->settings, "mapping"); +} + +static CDesktopPadButtonAction +meta_input_settings_get_pad_button_action (MetaInputSettings *input_settings, + ClutterInputDevice *pad, + guint button) +{ + CDesktopPadButtonAction action; + GSettings *settings; + + g_return_val_if_fail (META_IS_INPUT_SETTINGS (input_settings), + C_DESKTOP_PAD_BUTTON_ACTION_NONE); + g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (pad), + C_DESKTOP_PAD_BUTTON_ACTION_NONE); + + settings = lookup_pad_action_settings (pad, META_PAD_ACTION_BUTTON, + button, META_PAD_DIRECTION_NONE, -1); + action = g_settings_get_enum (settings, "action"); + g_object_unref (settings); + + return action; +} + +static gboolean +cycle_logical_monitors (MetaInputSettings *settings, + MetaLogicalMonitor *current_logical_monitor, + MetaLogicalMonitor **next_logical_monitor) +{ + MetaInputSettingsPrivate *priv = + meta_input_settings_get_instance_private (settings); + MetaMonitorManager *monitor_manager = priv->monitor_manager; + GList *logical_monitors; + + /* We cycle between: + * - the span of all monitors (current_output = NULL) + * - each monitor individually. + */ + + logical_monitors = + meta_monitor_manager_get_logical_monitors (monitor_manager); + + if (!current_logical_monitor) + { + *next_logical_monitor = logical_monitors->data; + } + else + { + GList *l; + + l = g_list_find (logical_monitors, current_logical_monitor); + if (l->next) + *next_logical_monitor = l->next->data; + else + *next_logical_monitor = NULL; + } + + return TRUE; +} + +static void +meta_input_settings_cycle_tablet_output (MetaInputSettings *input_settings, + ClutterInputDevice *device) +{ + MetaInputSettingsPrivate *priv; + DeviceMappingInfo *info; + MetaLogicalMonitor *logical_monitor = NULL; + const gchar *edid[4] = { 0 }, *pretty_name = NULL; +#ifdef HAVE_LIBWACOM + WacomDevice *wacom_device; +#endif + + g_return_if_fail (META_IS_INPUT_SETTINGS (input_settings)); + g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device)); + g_return_if_fail (clutter_input_device_get_device_type (device) == CLUTTER_TABLET_DEVICE || + clutter_input_device_get_device_type (device) == CLUTTER_PAD_DEVICE); + + priv = meta_input_settings_get_instance_private (input_settings); + info = g_hash_table_lookup (priv->mappable_devices, device); + g_return_if_fail (info != NULL); + +#ifdef HAVE_LIBWACOM + wacom_device = meta_input_device_get_wacom_device (META_INPUT_DEVICE (device)); + + if (wacom_device) + { + /* Output rotation only makes sense on external tablets */ + if (libwacom_get_integration_flags (wacom_device) != WACOM_DEVICE_INTEGRATED_NONE) + return; + + pretty_name = libwacom_get_name (wacom_device); + } +#endif + + meta_input_settings_find_monitor (input_settings, info->settings, device, + NULL, &logical_monitor); + + if (!cycle_logical_monitors (input_settings, + logical_monitor, + &logical_monitor)) + return; + + if (logical_monitor) + { + MetaMonitor *monitor; + + /* Pick an arbitrary monitor in the logical monitor to represent it. */ + monitor = meta_logical_monitor_get_monitors (logical_monitor)->data; + edid[0] = meta_monitor_get_vendor (monitor); + edid[1] = meta_monitor_get_product (monitor); + edid[2] = meta_monitor_get_serial (monitor); + } + else + { + edid[0] = ""; + edid[1] = ""; + edid[2] = ""; + } + g_settings_set_strv (info->settings, "output", edid); + + meta_display_show_tablet_mapping_notification (meta_get_display (), + device, pretty_name); +} + +static void +emulate_modifiers (ClutterVirtualInputDevice *device, + ClutterModifierType mods, + ClutterKeyState state) +{ + guint i; + struct { + ClutterModifierType mod; + guint keyval; + } mod_map[] = { + { CLUTTER_SHIFT_MASK, CLUTTER_KEY_Shift_L }, + { CLUTTER_CONTROL_MASK, CLUTTER_KEY_Control_L }, + { CLUTTER_MOD1_MASK, CLUTTER_KEY_Meta_L } + }; + + for (i = 0; i < G_N_ELEMENTS (mod_map); i++) + { + if ((mods & mod_map[i].mod) == 0) + continue; + + clutter_virtual_input_device_notify_keyval (device, + clutter_get_current_event_time (), + mod_map[i].keyval, state); + } +} + +static void +meta_input_settings_emulate_keybinding (MetaInputSettings *input_settings, + const gchar *accel, + gboolean is_press) +{ + MetaInputSettingsPrivate *priv; + ClutterKeyState state; + guint key, mods; + + if (!accel || !*accel) + return; + + priv = meta_input_settings_get_instance_private (input_settings); + + /* FIXME: This is appalling */ + gtk_accelerator_parse (accel, &key, &mods); + + if (!priv->virtual_pad_keyboard) + { + ClutterBackend *backend; + ClutterSeat *seat; + + backend = clutter_get_default_backend (); + seat = clutter_backend_get_default_seat (backend); + + priv->virtual_pad_keyboard = + clutter_seat_create_virtual_device (seat, + CLUTTER_KEYBOARD_DEVICE); + } + + state = is_press ? CLUTTER_KEY_STATE_PRESSED : CLUTTER_KEY_STATE_RELEASED; + + if (is_press) + emulate_modifiers (priv->virtual_pad_keyboard, mods, state); + + clutter_virtual_input_device_notify_keyval (priv->virtual_pad_keyboard, + clutter_get_current_event_time (), + key, state); + if (!is_press) + emulate_modifiers (priv->virtual_pad_keyboard, mods, state); +} + +gboolean +meta_input_settings_is_pad_button_grabbed (MetaInputSettings *input_settings, + ClutterInputDevice *pad, + guint button) +{ + g_return_val_if_fail (META_IS_INPUT_SETTINGS (input_settings), FALSE); + g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (pad), FALSE); + g_return_val_if_fail (clutter_input_device_get_device_type (pad) == + CLUTTER_PAD_DEVICE, FALSE); + + return (meta_input_settings_get_pad_button_action (input_settings, pad, button) != + C_DESKTOP_PAD_BUTTON_ACTION_NONE); +} + +static gboolean +meta_input_settings_handle_pad_button (MetaInputSettings *input_settings, + ClutterInputDevice *pad, + const ClutterPadButtonEvent *event) +{ + CDesktopPadButtonAction action; + gint button, group, mode; + gboolean is_press; + GSettings *settings; + gchar *accel; + + g_return_val_if_fail (META_IS_INPUT_SETTINGS (input_settings), FALSE); + g_return_val_if_fail (event->type == CLUTTER_PAD_BUTTON_PRESS || + event->type == CLUTTER_PAD_BUTTON_RELEASE, FALSE); + + button = event->button; + mode = event->mode; + group = clutter_input_device_get_mode_switch_button_group (pad, button); + is_press = event->type == CLUTTER_PAD_BUTTON_PRESS; + + if (is_press && group >= 0) + { + guint n_modes = clutter_input_device_get_group_n_modes (pad, group); + const gchar *pretty_name = NULL; + MetaInputSettingsPrivate *priv; + DeviceMappingInfo *info; +#ifdef HAVE_LIBWACOM + WacomDevice *wacom_device; +#endif + + priv = meta_input_settings_get_instance_private (input_settings); + info = g_hash_table_lookup (priv->mappable_devices, pad); + +#ifdef HAVE_LIBWACOM + wacom_device = meta_input_device_get_wacom_device (META_INPUT_DEVICE (pad)); + + if (wacom_device) + pretty_name = libwacom_get_name (wacom_device); +#endif + meta_display_notify_pad_group_switch (meta_get_display (), pad, + pretty_name, group, mode, n_modes); + info->group_modes[group] = mode; + } + + action = meta_input_settings_get_pad_button_action (input_settings, pad, button); + + switch (action) + { + case C_DESKTOP_PAD_BUTTON_ACTION_SWITCH_MONITOR: + if (is_press) + meta_input_settings_cycle_tablet_output (input_settings, pad); + return TRUE; + case C_DESKTOP_PAD_BUTTON_ACTION_HELP: + if (is_press) + meta_display_request_pad_osd (meta_get_display (), pad, FALSE); + return TRUE; + case C_DESKTOP_PAD_BUTTON_ACTION_KEYBINDING: + settings = lookup_pad_action_settings (pad, META_PAD_ACTION_BUTTON, + button, META_PAD_DIRECTION_NONE, -1); + accel = g_settings_get_string (settings, "keybinding"); + meta_input_settings_emulate_keybinding (input_settings, accel, is_press); + g_object_unref (settings); + g_free (accel); + return TRUE; + case C_DESKTOP_PAD_BUTTON_ACTION_NONE: + default: + return FALSE; + } +} + +static gboolean +meta_input_settings_handle_pad_action (MetaInputSettings *input_settings, + ClutterInputDevice *pad, + MetaPadActionType action, + guint number, + MetaPadDirection direction, + guint mode) +{ + GSettings *settings; + gboolean handled = FALSE; + gchar *accel; + + settings = lookup_pad_action_settings (pad, action, number, direction, mode); + accel = g_settings_get_string (settings, "keybinding"); + + if (accel && *accel) + { + meta_input_settings_emulate_keybinding (input_settings, accel, TRUE); + meta_input_settings_emulate_keybinding (input_settings, accel, FALSE); + handled = TRUE; + } + + g_object_unref (settings); + g_free (accel); + + return handled; +} + +static gboolean +meta_input_settings_get_pad_action_direction (MetaInputSettings *input_settings, + const ClutterEvent *event, + MetaPadDirection *direction) +{ + MetaInputSettingsPrivate *priv; + ClutterInputDevice *pad = clutter_event_get_device (event); + MetaPadActionType pad_action; + gboolean has_direction = FALSE; + MetaPadDirection inc_dir, dec_dir; + guint number; + gdouble value; + + priv = meta_input_settings_get_instance_private (input_settings); + *direction = META_PAD_DIRECTION_NONE; + + switch (event->type) + { + case CLUTTER_PAD_RING: + pad_action = META_PAD_ACTION_RING; + number = event->pad_ring.ring_number; + value = event->pad_ring.angle; + inc_dir = META_PAD_DIRECTION_CW; + dec_dir = META_PAD_DIRECTION_CCW; + break; + case CLUTTER_PAD_STRIP: + pad_action = META_PAD_ACTION_STRIP; + number = event->pad_strip.strip_number; + value = event->pad_strip.value; + inc_dir = META_PAD_DIRECTION_DOWN; + dec_dir = META_PAD_DIRECTION_UP; + break; + default: + return FALSE; + } + + if (priv->last_pad_action_info.pad == pad && + priv->last_pad_action_info.action == pad_action && + priv->last_pad_action_info.number == number && + value >= 0 && priv->last_pad_action_info.value >= 0) + { + *direction = (value - priv->last_pad_action_info.value) > 0 ? + inc_dir : dec_dir; + has_direction = TRUE; + } + + priv->last_pad_action_info.pad = pad; + priv->last_pad_action_info.action = pad_action; + priv->last_pad_action_info.number = number; + priv->last_pad_action_info.value = value; + return has_direction; +} + +gboolean +meta_input_settings_handle_pad_event (MetaInputSettings *input_settings, + const ClutterEvent *event) +{ + ClutterInputDevice *pad; + MetaPadDirection direction = META_PAD_DIRECTION_NONE; + + pad = clutter_event_get_source_device ((ClutterEvent *) event); + + switch (event->type) + { + case CLUTTER_PAD_BUTTON_PRESS: + case CLUTTER_PAD_BUTTON_RELEASE: + return meta_input_settings_handle_pad_button (input_settings, pad, + &event->pad_button); + case CLUTTER_PAD_RING: + if (!meta_input_settings_get_pad_action_direction (input_settings, + event, &direction)) + return FALSE; + return meta_input_settings_handle_pad_action (input_settings, pad, + META_PAD_ACTION_RING, + event->pad_ring.ring_number, + direction, + event->pad_ring.mode); + case CLUTTER_PAD_STRIP: + if (!meta_input_settings_get_pad_action_direction (input_settings, + event, &direction)) + return FALSE; + return meta_input_settings_handle_pad_action (input_settings, pad, + META_PAD_ACTION_STRIP, + event->pad_strip.strip_number, + direction, + event->pad_strip.mode); + default: + return FALSE; + } +} + +static gchar * +compose_directional_action_label (GSettings *direction1, + GSettings *direction2) +{ + gchar *accel1, *accel2, *str = NULL; + + accel1 = g_settings_get_string (direction1, "keybinding"); + accel2 = g_settings_get_string (direction2, "keybinding"); + + if (accel1 && *accel1 && accel2 && *accel2) + str = g_strdup_printf ("%s / %s", accel1, accel2); + + g_free (accel1); + g_free (accel2); + + return str; +} + +static gchar * +meta_input_settings_get_ring_label (MetaInputSettings *settings, + ClutterInputDevice *pad, + guint number, + guint mode) +{ + GSettings *settings1, *settings2; + gchar *label; + + /* We only allow keybinding actions with those */ + settings1 = lookup_pad_action_settings (pad, META_PAD_ACTION_RING, number, + META_PAD_DIRECTION_CW, mode); + settings2 = lookup_pad_action_settings (pad, META_PAD_ACTION_RING, number, + META_PAD_DIRECTION_CCW, mode); + label = compose_directional_action_label (settings1, settings2); + g_object_unref (settings1); + g_object_unref (settings2); + + return label; +} + +static gchar * +meta_input_settings_get_strip_label (MetaInputSettings *settings, + ClutterInputDevice *pad, + guint number, + guint mode) +{ + GSettings *settings1, *settings2; + gchar *label; + + /* We only allow keybinding actions with those */ + settings1 = lookup_pad_action_settings (pad, META_PAD_ACTION_STRIP, number, + META_PAD_DIRECTION_UP, mode); + settings2 = lookup_pad_action_settings (pad, META_PAD_ACTION_STRIP, number, + META_PAD_DIRECTION_DOWN, mode); + label = compose_directional_action_label (settings1, settings2); + g_object_unref (settings1); + g_object_unref (settings2); + + return label; +} + +static gchar * +meta_input_settings_get_button_label (MetaInputSettings *input_settings, + ClutterInputDevice *pad, + guint button) +{ + CDesktopPadButtonAction action; + gint group; + + g_return_val_if_fail (META_IS_INPUT_SETTINGS (input_settings), NULL); + g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (pad), NULL); + g_return_val_if_fail (clutter_input_device_get_device_type (pad) == + CLUTTER_PAD_DEVICE, NULL); + + group = clutter_input_device_get_mode_switch_button_group (pad, button); + + if (group >= 0) + { + /* TRANSLATORS: This string refers to a button that switches between + * different modes. + */ + return g_strdup_printf (_("Mode Switch (Group %d)"), group); + } + + action = meta_input_settings_get_pad_button_action (input_settings, pad, button); + + switch (action) + { + case C_DESKTOP_PAD_BUTTON_ACTION_KEYBINDING: + { + GSettings *settings; + gchar *accel; + + settings = lookup_pad_action_settings (pad, META_PAD_ACTION_BUTTON, + button, META_PAD_DIRECTION_NONE, -1); + accel = g_settings_get_string (settings, "keybinding"); + g_object_unref (settings); + + return accel; + } + case C_DESKTOP_PAD_BUTTON_ACTION_SWITCH_MONITOR: + /* TRANSLATORS: This string refers to an action, cycles drawing tablets' + * mapping through the available outputs. + */ + return g_strdup (_("Switch monitor")); + case C_DESKTOP_PAD_BUTTON_ACTION_HELP: + return g_strdup (_("Show on-screen help")); + case C_DESKTOP_PAD_BUTTON_ACTION_NONE: + default: + return NULL; + } +} + +static guint +get_current_pad_mode (MetaInputSettings *input_settings, + ClutterInputDevice *pad, + MetaPadActionType action_type, + guint number) +{ + MetaInputSettingsPrivate *priv; + DeviceMappingInfo *info; + guint group = 0, n_groups; + + priv = meta_input_settings_get_instance_private (input_settings); + info = g_hash_table_lookup (priv->mappable_devices, pad); + n_groups = clutter_input_device_get_n_mode_groups (pad); + + if (!info->group_modes || n_groups == 0) + return 0; + + if (action_type == META_PAD_ACTION_RING || + action_type == META_PAD_ACTION_STRIP) + { + /* Assume features are evenly distributed in groups */ + group = number % n_groups; + } + + return info->group_modes[group]; +} + +gchar * +meta_input_settings_get_pad_action_label (MetaInputSettings *input_settings, + ClutterInputDevice *pad, + MetaPadActionType action_type, + guint number) +{ + guint mode; + + switch (action_type) + { + case META_PAD_ACTION_BUTTON: + return meta_input_settings_get_button_label (input_settings, pad, number); + case META_PAD_ACTION_RING: + mode = get_current_pad_mode (input_settings, pad, action_type, number); + return meta_input_settings_get_ring_label (input_settings, pad, + number, mode); + case META_PAD_ACTION_STRIP: + mode = get_current_pad_mode (input_settings, pad, action_type, number); + return meta_input_settings_get_strip_label (input_settings, pad, + number, mode); + } + + return NULL; +} + +void +meta_input_settings_maybe_save_numlock_state (MetaInputSettings *input_settings) +{ + MetaInputSettingsPrivate *priv; + ClutterSeat *seat; + ClutterKeymap *keymap; + gboolean numlock_state; + + priv = meta_input_settings_get_instance_private (input_settings); + + if (!g_settings_get_boolean (priv->keyboard_settings, "remember-numlock-state")) + return; + + seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); + keymap = clutter_seat_get_keymap (seat); + numlock_state = clutter_keymap_get_num_lock_state (keymap); + + if (numlock_state == g_settings_get_boolean (priv->keyboard_settings, "numlock-state")) + return; + + g_settings_set_boolean (priv->keyboard_settings, "numlock-state", numlock_state); +} + +void +meta_input_settings_maybe_restore_numlock_state (MetaInputSettings *input_settings) +{ + MetaInputSettingsPrivate *priv; + gboolean numlock_state; + + priv = meta_input_settings_get_instance_private (input_settings); + + if (!g_settings_get_boolean (priv->keyboard_settings, "remember-numlock-state")) + return; + + numlock_state = g_settings_get_boolean (priv->keyboard_settings, "numlock-state"); + meta_backend_set_numlock (meta_get_backend (), numlock_state); +} diff --git a/src/backends/meta-logical-monitor.c b/src/backends/meta-logical-monitor.c new file mode 100644 index 000000000..15a918103 --- /dev/null +++ b/src/backends/meta-logical-monitor.c @@ -0,0 +1,338 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +/** + * SECTION:meta-logical-monitor + * @title: MetaLogicalMonitor + * @short_description: An abstraction for a monitor(set) and its configuration. + * + * A logical monitor is a group of one or more physical monitors that + * must behave and be treated as single one. This happens, for example, + * when 2 monitors are mirrored. Each physical monitor is represented + * by a #MetaMonitor. + * + * #MetaLogicalMonitor has a single viewport, with its owns transformations + * (such as scaling), that are applied to all the #MetaMonitor<!-- -->s that + * are grouped by it. + * + * #MetaLogicalMonitor provides an abstraction that makes it easy to handle + * the specifics of setting up different #MetaMonitor<!-- -->s. It then can + * be used more easily by #MetaRendererView. + */ + +#include "config.h" + +#include "backends/meta-logical-monitor.h" + +#include "backends/meta-backend-private.h" +#include "backends/meta-crtc.h" +#include "backends/meta-output.h" + +G_DEFINE_TYPE (MetaLogicalMonitor, meta_logical_monitor, G_TYPE_OBJECT) + +static MetaMonitor * +get_first_monitor (MetaMonitorManager *monitor_manager, + GList *monitor_configs) +{ + MetaMonitorConfig *first_monitor_config; + MetaMonitorSpec *first_monitor_spec; + + first_monitor_config = g_list_first (monitor_configs)->data; + first_monitor_spec = first_monitor_config->monitor_spec; + + return meta_monitor_manager_get_monitor_from_spec (monitor_manager, + first_monitor_spec); +} + +typedef struct +{ + MetaMonitorManager *monitor_manager; + MetaLogicalMonitor *logical_monitor; +} AddMonitorFromConfigData; + +static void +add_monitor_from_config (MetaMonitorConfig *monitor_config, + AddMonitorFromConfigData *data) +{ + MetaMonitorSpec *monitor_spec; + MetaMonitor *monitor; + + monitor_spec = monitor_config->monitor_spec; + monitor = meta_monitor_manager_get_monitor_from_spec (data->monitor_manager, + monitor_spec); + + meta_logical_monitor_add_monitor (data->logical_monitor, monitor); +} + +MetaLogicalMonitor * +meta_logical_monitor_new (MetaMonitorManager *monitor_manager, + MetaLogicalMonitorConfig *logical_monitor_config, + int monitor_number) +{ + MetaLogicalMonitor *logical_monitor; + GList *monitor_configs; + MetaMonitor *first_monitor; + MetaOutput *main_output; + + logical_monitor = g_object_new (META_TYPE_LOGICAL_MONITOR, NULL); + + monitor_configs = logical_monitor_config->monitor_configs; + first_monitor = get_first_monitor (monitor_manager, monitor_configs); + main_output = meta_monitor_get_main_output (first_monitor); + + logical_monitor->number = monitor_number; + logical_monitor->winsys_id = main_output->winsys_id; + logical_monitor->scale = logical_monitor_config->scale; + logical_monitor->transform = logical_monitor_config->transform; + logical_monitor->in_fullscreen = -1; + logical_monitor->rect = logical_monitor_config->layout; + + logical_monitor->is_presentation = TRUE; + g_list_foreach (monitor_configs, (GFunc) add_monitor_from_config, + &(AddMonitorFromConfigData) { + .monitor_manager = monitor_manager, + .logical_monitor = logical_monitor + }); + + return logical_monitor; +} + +static MetaMonitorTransform +derive_monitor_transform (MetaMonitor *monitor) +{ + MetaOutput *main_output; + MetaMonitorTransform transform; + + main_output = meta_monitor_get_main_output (monitor); + transform = meta_output_get_assigned_crtc (main_output)->config->transform; + + return meta_monitor_crtc_to_logical_transform (monitor, transform); +} + +MetaLogicalMonitor * +meta_logical_monitor_new_derived (MetaMonitorManager *monitor_manager, + MetaMonitor *monitor, + MetaRectangle *layout, + float scale, + int monitor_number) +{ + MetaLogicalMonitor *logical_monitor; + MetaOutput *main_output; + MetaMonitorTransform transform; + + logical_monitor = g_object_new (META_TYPE_LOGICAL_MONITOR, NULL); + + transform = derive_monitor_transform (monitor); + + main_output = meta_monitor_get_main_output (monitor); + logical_monitor->number = monitor_number; + logical_monitor->winsys_id = main_output->winsys_id; + logical_monitor->scale = scale; + logical_monitor->transform = transform; + logical_monitor->in_fullscreen = -1; + logical_monitor->rect = *layout; + + logical_monitor->is_presentation = TRUE; + meta_logical_monitor_add_monitor (logical_monitor, monitor); + + return logical_monitor; +} + +void +meta_logical_monitor_add_monitor (MetaLogicalMonitor *logical_monitor, + MetaMonitor *monitor) +{ + GList *l; + gboolean is_presentation; + + is_presentation = logical_monitor->is_presentation; + logical_monitor->monitors = g_list_append (logical_monitor->monitors, + g_object_ref (monitor)); + + for (l = logical_monitor->monitors; l; l = l->next) + { + MetaMonitor *monitor = l->data; + GList *outputs; + GList *l_output; + + outputs = meta_monitor_get_outputs (monitor); + for (l_output = outputs; l_output; l_output = l_output->next) + { + MetaOutput *output = l_output->data; + + is_presentation = is_presentation && output->is_presentation; + } + } + + logical_monitor->is_presentation = is_presentation; + + meta_monitor_set_logical_monitor (monitor, logical_monitor); +} + +gboolean +meta_logical_monitor_is_primary (MetaLogicalMonitor *logical_monitor) +{ + return logical_monitor->is_primary; +} + +void +meta_logical_monitor_make_primary (MetaLogicalMonitor *logical_monitor) +{ + logical_monitor->is_primary = TRUE; +} + +float +meta_logical_monitor_get_scale (MetaLogicalMonitor *logical_monitor) +{ + return logical_monitor->scale; +} + +MetaMonitorTransform +meta_logical_monitor_get_transform (MetaLogicalMonitor *logical_monitor) +{ + return logical_monitor->transform; +} + +MetaRectangle +meta_logical_monitor_get_layout (MetaLogicalMonitor *logical_monitor) +{ + return logical_monitor->rect; +} + +GList * +meta_logical_monitor_get_monitors (MetaLogicalMonitor *logical_monitor) +{ + return logical_monitor->monitors; +} + +typedef struct _ForeachCrtcData +{ + MetaLogicalMonitor *logical_monitor; + MetaLogicalMonitorCrtcFunc func; + gpointer user_data; +} ForeachCrtcData; + +static gboolean +foreach_crtc (MetaMonitor *monitor, + MetaMonitorMode *mode, + MetaMonitorCrtcMode *monitor_crtc_mode, + gpointer user_data, + GError **error) +{ + ForeachCrtcData *data = user_data; + + data->func (data->logical_monitor, + monitor, + monitor_crtc_mode->output, + meta_output_get_assigned_crtc (monitor_crtc_mode->output), + data->user_data); + + return TRUE; +} + +void +meta_logical_monitor_foreach_crtc (MetaLogicalMonitor *logical_monitor, + MetaLogicalMonitorCrtcFunc func, + gpointer user_data) +{ + GList *l; + + for (l = logical_monitor->monitors; l; l = l->next) + { + MetaMonitor *monitor = l->data; + MetaMonitorMode *mode; + ForeachCrtcData data = { + .logical_monitor = logical_monitor, + .func = func, + .user_data = user_data + }; + + mode = meta_monitor_get_current_mode (monitor); + meta_monitor_mode_foreach_crtc (monitor, mode, foreach_crtc, &data, NULL); + } +} + +static void +meta_logical_monitor_init (MetaLogicalMonitor *logical_monitor) +{ +} + +static void +meta_logical_monitor_dispose (GObject *object) +{ + MetaLogicalMonitor *logical_monitor = META_LOGICAL_MONITOR (object); + + if (logical_monitor->monitors) + { + g_list_free_full (logical_monitor->monitors, g_object_unref); + logical_monitor->monitors = NULL; + } + + G_OBJECT_CLASS (meta_logical_monitor_parent_class)->dispose (object); +} + +static void +meta_logical_monitor_class_init (MetaLogicalMonitorClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = meta_logical_monitor_dispose; +} + +gboolean +meta_logical_monitor_has_neighbor (MetaLogicalMonitor *logical_monitor, + MetaLogicalMonitor *neighbor, + MetaDisplayDirection neighbor_direction) +{ + switch (neighbor_direction) + { + case META_DISPLAY_RIGHT: + if (neighbor->rect.x == (logical_monitor->rect.x + + logical_monitor->rect.width) && + meta_rectangle_vert_overlap (&neighbor->rect, + &logical_monitor->rect)) + return TRUE; + break; + case META_DISPLAY_LEFT: + if (logical_monitor->rect.x == (neighbor->rect.x + + neighbor->rect.width) && + meta_rectangle_vert_overlap (&neighbor->rect, + &logical_monitor->rect)) + return TRUE; + break; + case META_DISPLAY_UP: + if (logical_monitor->rect.y == (neighbor->rect.y + + neighbor->rect.height) && + meta_rectangle_horiz_overlap (&neighbor->rect, + &logical_monitor->rect)) + return TRUE; + break; + case META_DISPLAY_DOWN: + if (neighbor->rect.y == (logical_monitor->rect.y + + logical_monitor->rect.height) && + meta_rectangle_horiz_overlap (&neighbor->rect, + &logical_monitor->rect)) + return TRUE; + break; + } + + return FALSE; +} diff --git a/src/backends/meta-logical-monitor.h b/src/backends/meta-logical-monitor.h new file mode 100644 index 000000000..8cddc6b05 --- /dev/null +++ b/src/backends/meta-logical-monitor.h @@ -0,0 +1,106 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_LOGICAL_MONITOR_H +#define META_LOGICAL_MONITOR_H + +#include <glib-object.h> + +#include "backends/meta-monitor.h" +#include "backends/meta-monitor-config-manager.h" +#include "backends/meta-monitor-manager-private.h" +#include "core/util-private.h" +#include "meta/boxes.h" + +#define META_MAX_OUTPUTS_PER_MONITOR 4 + +struct _MetaLogicalMonitor +{ + GObject parent; + + int number; + MetaRectangle rect; + gboolean is_primary; + gboolean is_presentation; /* XXX: not yet used */ + gboolean in_fullscreen; + float scale; + MetaMonitorTransform transform; + + /* The primary or first output for this monitor, 0 if we can't figure out. + It can be matched to a winsys_id of a MetaOutput. + + This is used as an opaque token on reconfiguration when switching from + clone to extened, to decide on what output the windows should go next + (it's an attempt to keep windows on the same monitor, and preferably on + the primary one). + */ + uint64_t winsys_id; + + GList *monitors; +}; + +#define META_TYPE_LOGICAL_MONITOR (meta_logical_monitor_get_type ()) +G_DECLARE_FINAL_TYPE (MetaLogicalMonitor, meta_logical_monitor, + META, LOGICAL_MONITOR, + GObject) + +typedef void (* MetaLogicalMonitorCrtcFunc) (MetaLogicalMonitor *logical_monitor, + MetaMonitor *monitor, + MetaOutput *output, + MetaCrtc *crtc, + gpointer user_data); + +MetaLogicalMonitor * meta_logical_monitor_new (MetaMonitorManager *monitor_manager, + MetaLogicalMonitorConfig *logical_monitor_config, + int monitor_number); + +MetaLogicalMonitor * meta_logical_monitor_new_derived (MetaMonitorManager *monitor_manager, + MetaMonitor *monitor, + MetaRectangle *layout, + float scale, + int monitor_number); + +void meta_logical_monitor_add_monitor (MetaLogicalMonitor *logical_monitor, + MetaMonitor *monitor); + +META_EXPORT_TEST +gboolean meta_logical_monitor_is_primary (MetaLogicalMonitor *logical_monitor); + +void meta_logical_monitor_make_primary (MetaLogicalMonitor *logical_monitor); + +float meta_logical_monitor_get_scale (MetaLogicalMonitor *logical_monitor); + +MetaMonitorTransform meta_logical_monitor_get_transform (MetaLogicalMonitor *logical_monitor); + +MetaRectangle meta_logical_monitor_get_layout (MetaLogicalMonitor *logical_monitor); + +META_EXPORT_TEST +GList * meta_logical_monitor_get_monitors (MetaLogicalMonitor *logical_monitor); + +gboolean meta_logical_monitor_has_neighbor (MetaLogicalMonitor *logical_monitor, + MetaLogicalMonitor *neighbor, + MetaDisplayDirection neighbor_dir); + +void meta_logical_monitor_foreach_crtc (MetaLogicalMonitor *logical_monitor, + MetaLogicalMonitorCrtcFunc func, + gpointer user_data); + +#endif /* META_LOGICAL_MONITOR_H */ diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c new file mode 100644 index 000000000..d8646fab6 --- /dev/null +++ b/src/backends/meta-monitor-config-manager.c @@ -0,0 +1,2035 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat + * Copyright (c) 2018 DisplayLink (UK) Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "backends/meta-monitor-config-manager.h" + +#include "backends/meta-backend-private.h" +#include "backends/meta-monitor-config-migration.h" +#include "backends/meta-monitor-config-store.h" +#include "backends/meta-monitor-manager-private.h" +#include "backends/meta-output.h" +#include "core/boxes-private.h" + +#define CONFIG_HISTORY_MAX_SIZE 3 + +struct _MetaMonitorConfigManager +{ + GObject parent; + + MetaMonitorManager *monitor_manager; + + MetaMonitorConfigStore *config_store; + + MetaMonitorsConfig *current_config; + GQueue config_history; +}; + +G_DEFINE_TYPE (MetaMonitorConfigManager, meta_monitor_config_manager, + G_TYPE_OBJECT) + +G_DEFINE_TYPE (MetaMonitorsConfig, meta_monitors_config, + G_TYPE_OBJECT) + +static void +meta_crtc_info_free (MetaCrtcInfo *info); + +static void +meta_output_info_free (MetaOutputInfo *info); + +MetaMonitorConfigManager * +meta_monitor_config_manager_new (MetaMonitorManager *monitor_manager) +{ + MetaMonitorConfigManager *config_manager; + + config_manager = g_object_new (META_TYPE_MONITOR_CONFIG_MANAGER, NULL); + config_manager->monitor_manager = monitor_manager; + config_manager->config_store = + meta_monitor_config_store_new (monitor_manager); + + return config_manager; +} + +MetaMonitorConfigStore * +meta_monitor_config_manager_get_store (MetaMonitorConfigManager *config_manager) +{ + return config_manager->config_store; +} + +static gboolean +is_crtc_reserved (MetaCrtc *crtc, + GArray *reserved_crtcs) +{ + unsigned int i; + + for (i = 0; i < reserved_crtcs->len; i++) + { + glong id = g_array_index (reserved_crtcs, glong, i); + if (id == crtc->crtc_id) + return TRUE; + } + + return FALSE; +} + +static gboolean +is_crtc_assigned (MetaCrtc *crtc, + GPtrArray *crtc_infos) +{ + unsigned int i; + + for (i = 0; i < crtc_infos->len; i++) + { + MetaCrtcInfo *assigned_crtc_info = g_ptr_array_index (crtc_infos, i); + + if (assigned_crtc_info->crtc == crtc) + return TRUE; + } + + return FALSE; +} + +static MetaCrtc * +find_unassigned_crtc (MetaOutput *output, + GPtrArray *crtc_infos, + GArray *reserved_crtcs) +{ + MetaCrtc *crtc; + unsigned int i; + + crtc = meta_output_get_assigned_crtc (output); + if (crtc && !is_crtc_assigned (crtc, crtc_infos)) + return crtc; + + /* then try to assign a CRTC that wasn't used */ + for (i = 0; i < output->n_possible_crtcs; i++) + { + crtc = output->possible_crtcs[i]; + + if (is_crtc_assigned (crtc, crtc_infos)) + continue; + + if (is_crtc_reserved (crtc, reserved_crtcs)) + continue; + + return crtc; + } + + /* finally just give a CRTC that we haven't assigned */ + for (i = 0; i < output->n_possible_crtcs; i++) + { + crtc = output->possible_crtcs[i]; + + if (is_crtc_assigned (crtc, crtc_infos)) + continue; + + return crtc; + } + + return NULL; +} + +typedef struct +{ + MetaMonitorManager *monitor_manager; + MetaMonitorsConfig *config; + MetaLogicalMonitorConfig *logical_monitor_config; + MetaMonitorConfig *monitor_config; + GPtrArray *crtc_infos; + GPtrArray *output_infos; + GArray *reserved_crtcs; +} MonitorAssignmentData; + +static gboolean +assign_monitor_crtc (MetaMonitor *monitor, + MetaMonitorMode *mode, + MetaMonitorCrtcMode *monitor_crtc_mode, + gpointer user_data, + GError **error) +{ + MonitorAssignmentData *data = user_data; + MetaOutput *output; + MetaCrtc *crtc; + MetaMonitorTransform transform; + MetaMonitorTransform crtc_transform; + MetaMonitorTransform crtc_hw_transform; + int crtc_x, crtc_y; + float x_offset, y_offset; + float scale = 0.0; + float width, height; + MetaCrtcMode *crtc_mode; + graphene_rect_t crtc_layout; + MetaCrtcInfo *crtc_info; + MetaOutputInfo *output_info; + MetaMonitorConfig *first_monitor_config; + gboolean assign_output_as_primary; + gboolean assign_output_as_presentation; + + output = monitor_crtc_mode->output; + + crtc = find_unassigned_crtc (output, data->crtc_infos, data->reserved_crtcs); + + if (!crtc) + { + MetaMonitorSpec *monitor_spec = meta_monitor_get_spec (monitor); + + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "No available CRTC for monitor '%s %s' not found", + monitor_spec->vendor, monitor_spec->product); + return FALSE; + } + + transform = data->logical_monitor_config->transform; + crtc_transform = meta_monitor_logical_to_crtc_transform (monitor, transform); + if (meta_monitor_manager_is_transform_handled (data->monitor_manager, + crtc, + crtc_transform)) + crtc_hw_transform = crtc_transform; + else + crtc_hw_transform = META_MONITOR_TRANSFORM_NORMAL; + + scale = data->logical_monitor_config->scale; + if (!meta_monitor_manager_is_scale_supported (data->monitor_manager, + data->config->layout_mode, + monitor, mode, scale)) + { + scale = roundf (scale); + if (!meta_monitor_manager_is_scale_supported (data->monitor_manager, + data->config->layout_mode, + monitor, mode, scale)) + scale = 1.0f; + } + + meta_monitor_calculate_crtc_pos (monitor, mode, output, crtc_transform, + &crtc_x, &crtc_y); + + x_offset = data->logical_monitor_config->layout.x; + y_offset = data->logical_monitor_config->layout.y; + + switch (data->config->layout_mode) + { + case META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL: + scale = data->logical_monitor_config->scale; + break; + case META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL: + scale = 1.0; + break; + case META_LOGICAL_MONITOR_LAYOUT_MODE_GLOBAL_UI_LOGICAL: + break; + } + + crtc_mode = monitor_crtc_mode->crtc_mode; + + if (meta_monitor_transform_is_rotated (crtc_transform)) + { + width = crtc_mode->height / scale; + height = crtc_mode->width / scale; + } + else + { + width = crtc_mode->width / scale; + height = crtc_mode->height / scale; + } + + crtc_layout = GRAPHENE_RECT_INIT (x_offset + (crtc_x / scale), + y_offset + (crtc_y / scale), + width, + height); + + crtc_info = g_slice_new0 (MetaCrtcInfo); + *crtc_info = (MetaCrtcInfo) { + .crtc = crtc, + .mode = crtc_mode, + .layout = crtc_layout, + .transform = crtc_hw_transform, + .scale = scale, + .outputs = g_ptr_array_new () + }; + g_ptr_array_add (crtc_info->outputs, output); + + /* + * Only one output can be marked as primary (due to Xrandr limitation), + * so only mark the main output of the first monitor in the logical monitor + * as such. + */ + first_monitor_config = data->logical_monitor_config->monitor_configs->data; + if (data->logical_monitor_config->is_primary && + data->monitor_config == first_monitor_config && + meta_monitor_get_main_output (monitor) == output) + assign_output_as_primary = TRUE; + else + assign_output_as_primary = FALSE; + + if (data->logical_monitor_config->is_presentation) + assign_output_as_presentation = TRUE; + else + assign_output_as_presentation = FALSE; + + output_info = g_slice_new0 (MetaOutputInfo); + *output_info = (MetaOutputInfo) { + .output = output, + .is_primary = assign_output_as_primary, + .is_presentation = assign_output_as_presentation, + .is_underscanning = data->monitor_config->enable_underscanning + }; + + g_ptr_array_add (data->crtc_infos, crtc_info); + g_ptr_array_add (data->output_infos, output_info); + + return TRUE; +} + +static gboolean +assign_monitor_crtcs (MetaMonitorManager *manager, + MetaMonitorsConfig *config, + MetaLogicalMonitorConfig *logical_monitor_config, + MetaMonitorConfig *monitor_config, + GPtrArray *crtc_infos, + GPtrArray *output_infos, + GArray *reserved_crtcs, + GError **error) +{ + MetaMonitorSpec *monitor_spec = monitor_config->monitor_spec; + MetaMonitorModeSpec *monitor_mode_spec = monitor_config->mode_spec; + MetaMonitor *monitor; + MetaMonitorMode *monitor_mode; + MonitorAssignmentData data; + + monitor = meta_monitor_manager_get_monitor_from_spec (manager, monitor_spec); + if (!monitor) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Configured monitor '%s %s' not found", + monitor_spec->vendor, monitor_spec->product); + return FALSE; + } + + monitor_mode = meta_monitor_get_mode_from_spec (monitor, monitor_mode_spec); + if (!monitor_mode) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Invalid mode %dx%d (%f) for monitor '%s %s'", + monitor_mode_spec->width, monitor_mode_spec->height, + monitor_mode_spec->refresh_rate, + monitor_spec->vendor, monitor_spec->product); + return FALSE; + } + + data = (MonitorAssignmentData) { + .monitor_manager = manager, + .config = config, + .logical_monitor_config = logical_monitor_config, + .monitor_config = monitor_config, + .crtc_infos = crtc_infos, + .output_infos = output_infos, + .reserved_crtcs = reserved_crtcs + }; + if (!meta_monitor_mode_foreach_crtc (monitor, monitor_mode, + assign_monitor_crtc, + &data, + error)) + return FALSE; + + return TRUE; +} + +static gboolean +assign_logical_monitor_crtcs (MetaMonitorManager *manager, + MetaMonitorsConfig *config, + MetaLogicalMonitorConfig *logical_monitor_config, + GPtrArray *crtc_infos, + GPtrArray *output_infos, + GArray *reserved_crtcs, + GError **error) +{ + GList *l; + + for (l = logical_monitor_config->monitor_configs; l; l = l->next) + { + MetaMonitorConfig *monitor_config = l->data; + + if (!assign_monitor_crtcs (manager, + config, + logical_monitor_config, + monitor_config, + crtc_infos, output_infos, + reserved_crtcs, error)) + return FALSE; + } + + return TRUE; +} + +gboolean +meta_monitor_config_manager_assign (MetaMonitorManager *manager, + MetaMonitorsConfig *config, + GPtrArray **out_crtc_infos, + GPtrArray **out_output_infos, + GError **error) +{ + GPtrArray *crtc_infos; + GPtrArray *output_infos; + GArray *reserved_crtcs; + GList *l; + + crtc_infos = + g_ptr_array_new_with_free_func ((GDestroyNotify) meta_crtc_info_free); + output_infos = + g_ptr_array_new_with_free_func ((GDestroyNotify) meta_output_info_free); + reserved_crtcs = g_array_new (FALSE, FALSE, sizeof (glong)); + + for (l = config->logical_monitor_configs; l; l = l->next) + { + MetaLogicalMonitorConfig *logical_monitor_config = l->data; + GList *k; + + for (k = logical_monitor_config->monitor_configs; k; k = k->next) + { + MetaMonitorConfig *monitor_config = k->data; + MetaMonitorSpec *monitor_spec = monitor_config->monitor_spec; + MetaMonitor *monitor; + GList *o; + + monitor = meta_monitor_manager_get_monitor_from_spec (manager, monitor_spec); + + for (o = meta_monitor_get_outputs (monitor); o; o = o->next) + { + MetaOutput *output = o->data; + MetaCrtc *crtc; + + crtc = meta_output_get_assigned_crtc (output); + if (crtc) + g_array_append_val (reserved_crtcs, crtc->crtc_id); + } + } + } + + for (l = config->logical_monitor_configs; l; l = l->next) + { + MetaLogicalMonitorConfig *logical_monitor_config = l->data; + + if (!assign_logical_monitor_crtcs (manager, + config, logical_monitor_config, + crtc_infos, output_infos, + reserved_crtcs, error)) + { + g_ptr_array_free (crtc_infos, TRUE); + g_ptr_array_free (output_infos, TRUE); + g_array_free (reserved_crtcs, TRUE); + return FALSE; + } + } + + g_array_free (reserved_crtcs, TRUE); + + *out_crtc_infos = crtc_infos; + *out_output_infos = output_infos; + + return TRUE; +} + +static gboolean +is_lid_closed (MetaMonitorManager *monitor_manager) +{ + MetaBackend *backend; + + backend = meta_monitor_manager_get_backend (monitor_manager); + return meta_backend_is_lid_closed (backend); +} + +MetaMonitorsConfigKey * +meta_create_monitors_config_key_for_current_state (MetaMonitorManager *monitor_manager) +{ + MetaMonitorsConfigKey *config_key; + MetaMonitorSpec *laptop_monitor_spec; + GList *l; + GList *monitor_specs; + + laptop_monitor_spec = NULL; + monitor_specs = NULL; + for (l = monitor_manager->monitors; l; l = l->next) + { + MetaMonitor *monitor = l->data; + MetaMonitorSpec *monitor_spec; + + if (meta_monitor_is_laptop_panel (monitor)) + { + laptop_monitor_spec = meta_monitor_get_spec (monitor); + + if (is_lid_closed (monitor_manager)) + continue; + } + + monitor_spec = meta_monitor_spec_clone (meta_monitor_get_spec (monitor)); + monitor_specs = g_list_prepend (monitor_specs, monitor_spec); + } + + if (!monitor_specs && laptop_monitor_spec) + { + monitor_specs = + g_list_prepend (NULL, meta_monitor_spec_clone (laptop_monitor_spec)); + } + + if (!monitor_specs) + return NULL; + + monitor_specs = g_list_sort (monitor_specs, + (GCompareFunc) meta_monitor_spec_compare); + + config_key = g_new0 (MetaMonitorsConfigKey, 1); + *config_key = (MetaMonitorsConfigKey) { + .monitor_specs = monitor_specs + }; + + return config_key; +} + +MetaMonitorsConfig * +meta_monitor_config_manager_get_stored (MetaMonitorConfigManager *config_manager) +{ + MetaMonitorManager *monitor_manager = config_manager->monitor_manager; + MetaMonitorsConfigKey *config_key; + MetaMonitorsConfig *config; + GError *error = NULL; + + config_key = + meta_create_monitors_config_key_for_current_state (monitor_manager); + if (!config_key) + return NULL; + + config = meta_monitor_config_store_lookup (config_manager->config_store, + config_key); + meta_monitors_config_key_free (config_key); + + if (!config) + return NULL; + + if (config->flags & META_MONITORS_CONFIG_FLAG_MIGRATED) + { + if (!meta_finish_monitors_config_migration (monitor_manager, config, + &error)) + { + g_warning ("Failed to finish monitors config migration: %s", + error->message); + g_error_free (error); + meta_monitor_config_store_remove (config_manager->config_store, config); + return NULL; + } + } + + return config; +} + +typedef enum _MonitorMatchRule +{ + MONITOR_MATCH_ALL = 0, + MONITOR_MATCH_EXTERNAL = (1 << 0), + MONITOR_MATCH_BUILTIN = (1 << 1), + MONITOR_MATCH_PRIMARY = (1 << 2), + MONITOR_MATCH_VISIBLE = (1 << 3), + MONITOR_MATCH_WITH_POSITION = (1 << 4), +} MonitorMatchRule; + +static MetaMonitor * +find_monitor_with_highest_preferred_resolution (MetaMonitorManager *monitor_manager, + MonitorMatchRule match_rule) +{ + GList *monitors; + GList *l; + int largest_area = 0; + MetaMonitor *largest_monitor = NULL; + + monitors = meta_monitor_manager_get_monitors (monitor_manager); + for (l = monitors; l; l = l->next) + { + MetaMonitor *monitor = l->data; + MetaMonitorMode *mode; + int width, height; + int area; + + if (match_rule & MONITOR_MATCH_EXTERNAL) + { + if (meta_monitor_is_laptop_panel (monitor)) + continue; + } + + mode = meta_monitor_get_preferred_mode (monitor); + meta_monitor_mode_get_resolution (mode, &width, &height); + area = width * height; + + if (area > largest_area) + { + largest_area = area; + largest_monitor = monitor; + } + } + + return largest_monitor; +} + +/* + * Try to find the primary monitor. The priority of classification is: + * + * 1. Find the primary monitor as reported by the underlying system, + * 2. Find the laptop panel + * 3. Find the external monitor with highest resolution + * + * If the laptop lid is closed, exclude the laptop panel from possible + * alternatives, except if no other alternatives exist. + */ +static MetaMonitor * +find_primary_monitor (MetaMonitorManager *monitor_manager) +{ + MetaMonitor *monitor; + + if (is_lid_closed (monitor_manager)) + { + monitor = meta_monitor_manager_get_primary_monitor (monitor_manager); + if (monitor && !meta_monitor_is_laptop_panel (monitor)) + return monitor; + + monitor = + find_monitor_with_highest_preferred_resolution (monitor_manager, + MONITOR_MATCH_EXTERNAL); + if (monitor) + return monitor; + + return find_monitor_with_highest_preferred_resolution (monitor_manager, + MONITOR_MATCH_ALL); + } + else + { + monitor = meta_monitor_manager_get_primary_monitor (monitor_manager); + if (monitor) + return monitor; + + monitor = meta_monitor_manager_get_laptop_panel (monitor_manager); + if (monitor) + return monitor; + + return find_monitor_with_highest_preferred_resolution (monitor_manager, + MONITOR_MATCH_ALL); + } +} + +static MetaMonitorConfig * +create_monitor_config (MetaMonitor *monitor, + MetaMonitorMode *mode) +{ + MetaMonitorSpec *monitor_spec; + MetaMonitorModeSpec *mode_spec; + MetaMonitorConfig *monitor_config; + + monitor_spec = meta_monitor_get_spec (monitor); + mode_spec = meta_monitor_mode_get_spec (mode); + + monitor_config = g_new0 (MetaMonitorConfig, 1); + *monitor_config = (MetaMonitorConfig) { + .monitor_spec = meta_monitor_spec_clone (monitor_spec), + .mode_spec = g_memdup (mode_spec, sizeof (MetaMonitorModeSpec)), + .enable_underscanning = meta_monitor_is_underscanning (monitor) + }; + + return monitor_config; +} + +static MetaMonitorTransform +get_monitor_transform (MetaMonitorManager *monitor_manager, + MetaMonitor *monitor) +{ + MetaOrientationManager *orientation_manager; + MetaBackend *backend; + + if (!meta_monitor_is_laptop_panel (monitor)) + return META_MONITOR_TRANSFORM_NORMAL; + + backend = meta_monitor_manager_get_backend (monitor_manager); + orientation_manager = meta_backend_get_orientation_manager (backend); + + switch (meta_orientation_manager_get_orientation (orientation_manager)) + { + case META_ORIENTATION_BOTTOM_UP: + return META_MONITOR_TRANSFORM_180; + case META_ORIENTATION_LEFT_UP: + return META_MONITOR_TRANSFORM_90; + case META_ORIENTATION_RIGHT_UP: + return META_MONITOR_TRANSFORM_270; + case META_ORIENTATION_UNDEFINED: + case META_ORIENTATION_NORMAL: + default: + return META_MONITOR_TRANSFORM_NORMAL; + } +} + +static float +get_preferred_preferred_max_scale (MetaMonitorManager *monitor_manager, + MetaLogicalMonitorLayoutMode layout_mode, + MonitorMatchRule match_rule) +{ + float scale = 1.0f; + GList *monitors, *l; + + monitors = meta_monitor_manager_get_monitors (monitor_manager); + + for (l = monitors; l; l = l->next) + { + float s; + MetaMonitor *monitor = l->data; + MetaMonitorMode *mode = meta_monitor_get_preferred_mode (monitor); + + if (match_rule & MONITOR_MATCH_PRIMARY) + { + if (!meta_monitor_is_primary (monitor)) + continue; + } + + if (match_rule & MONITOR_MATCH_BUILTIN) + { + if (!meta_monitor_is_laptop_panel (monitor)) + continue; + } + else if (match_rule & MONITOR_MATCH_EXTERNAL) + { + if (meta_monitor_is_laptop_panel (monitor)) + continue; + } + + if (match_rule & MONITOR_MATCH_VISIBLE) + { + if (meta_monitor_is_laptop_panel (monitor) && + is_lid_closed (monitor_manager)) + continue; + } + + if (match_rule & MONITOR_MATCH_WITH_POSITION) + { + if (!meta_monitor_get_suggested_position (monitor, NULL, NULL)) + continue; + } + + s = meta_monitor_manager_calculate_monitor_mode_scale (monitor_manager, + layout_mode, + monitor, + mode); + scale = MAX (scale, s); + } + + return scale; +} + +static MetaLogicalMonitorConfig * +create_preferred_logical_monitor_config (MetaMonitorManager *monitor_manager, + MetaMonitor *monitor, + int x, + int y, + float max_scale, + MetaLogicalMonitorConfig *primary_logical_monitor_config, + MetaLogicalMonitorLayoutMode layout_mode) +{ + MetaMonitorMode *mode; + int width, height; + float scale; + MetaMonitorTransform transform; + MetaMonitorConfig *monitor_config; + MetaLogicalMonitorConfig *logical_monitor_config; + + mode = meta_monitor_get_preferred_mode (monitor); + meta_monitor_mode_get_resolution (mode, &width, &height); + + if ((meta_monitor_manager_get_capabilities (monitor_manager) & + META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED) && + primary_logical_monitor_config) + scale = primary_logical_monitor_config->scale; + else + scale = meta_monitor_manager_calculate_monitor_mode_scale (monitor_manager, + monitor_manager->layout_mode, + monitor, + mode); + + switch (layout_mode) + { + case META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL: + width = (int) roundf (width / scale); + height = (int) roundf (height / scale); + break; + case META_LOGICAL_MONITOR_LAYOUT_MODE_GLOBAL_UI_LOGICAL: + { + float ui_scale = scale / ceilf (max_scale); + width = (int) roundf (width / ui_scale); + height = (int) roundf (height / ui_scale); + } + break; + case META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL: + break; + } + + monitor_config = create_monitor_config (monitor, mode); + + transform = get_monitor_transform (monitor_manager, monitor); + if (meta_monitor_transform_is_rotated (transform)) + { + int temp = width; + width = height; + height = temp; + } + + logical_monitor_config = g_new0 (MetaLogicalMonitorConfig, 1); + *logical_monitor_config = (MetaLogicalMonitorConfig) { + .layout = (MetaRectangle) { + .x = x, + .y = y, + .width = width, + .height = height + }, + .transform = transform, + .scale = scale, + .monitor_configs = g_list_append (NULL, monitor_config) + }; + + return logical_monitor_config; +} + +MetaMonitorsConfig * +meta_monitor_config_manager_create_linear (MetaMonitorConfigManager *config_manager) +{ + MetaMonitorManager *monitor_manager = config_manager->monitor_manager; + GList *logical_monitor_configs; + MetaMonitor *primary_monitor; + MetaLogicalMonitorLayoutMode layout_mode; + MetaLogicalMonitorConfig *primary_logical_monitor_config; + float max_scale = 1.0f; + int x; + GList *monitors; + GList *l; + + primary_monitor = find_primary_monitor (monitor_manager); + if (!primary_monitor) + return NULL; + + layout_mode = meta_monitor_manager_get_default_layout_mode (monitor_manager); + + if (layout_mode == META_LOGICAL_MONITOR_LAYOUT_MODE_GLOBAL_UI_LOGICAL) + max_scale = get_preferred_preferred_max_scale (monitor_manager, + layout_mode, + MONITOR_MATCH_VISIBLE); + + primary_logical_monitor_config = + create_preferred_logical_monitor_config (monitor_manager, + primary_monitor, + 0, 0, + max_scale, + NULL, + layout_mode); + primary_logical_monitor_config->is_primary = TRUE; + logical_monitor_configs = g_list_append (NULL, + primary_logical_monitor_config); + + x = primary_logical_monitor_config->layout.width; + monitors = meta_monitor_manager_get_monitors (monitor_manager); + for (l = monitors; l; l = l->next) + { + MetaMonitor *monitor = l->data; + MetaLogicalMonitorConfig *logical_monitor_config; + + if (monitor == primary_monitor) + continue; + + if (meta_monitor_is_laptop_panel (monitor) && + is_lid_closed (monitor_manager)) + continue; + + logical_monitor_config = + create_preferred_logical_monitor_config (monitor_manager, + monitor, + x, 0, + max_scale, + primary_logical_monitor_config, + layout_mode); + logical_monitor_configs = g_list_append (logical_monitor_configs, + logical_monitor_config); + + x += logical_monitor_config->layout.width; + } + + return meta_monitors_config_new (monitor_manager, + logical_monitor_configs, + layout_mode, + META_MONITORS_CONFIG_FLAG_NONE); +} + +MetaMonitorsConfig * +meta_monitor_config_manager_create_fallback (MetaMonitorConfigManager *config_manager) +{ + MetaMonitorManager *monitor_manager = config_manager->monitor_manager; + MetaMonitor *primary_monitor; + GList *logical_monitor_configs; + MetaLogicalMonitorLayoutMode layout_mode; + MetaLogicalMonitorConfig *primary_logical_monitor_config; + float max_scale = 1.0f; + + primary_monitor = find_primary_monitor (monitor_manager); + if (!primary_monitor) + return NULL; + + layout_mode = meta_monitor_manager_get_default_layout_mode (monitor_manager); + + if (layout_mode == META_LOGICAL_MONITOR_LAYOUT_MODE_GLOBAL_UI_LOGICAL) + max_scale = get_preferred_preferred_max_scale (monitor_manager, + layout_mode, + MONITOR_MATCH_PRIMARY); + + primary_logical_monitor_config = + create_preferred_logical_monitor_config (monitor_manager, + primary_monitor, + 0, 0, + max_scale, + NULL, + layout_mode); + primary_logical_monitor_config->is_primary = TRUE; + logical_monitor_configs = g_list_append (NULL, + primary_logical_monitor_config); + + return meta_monitors_config_new (monitor_manager, + logical_monitor_configs, + layout_mode, + META_MONITORS_CONFIG_FLAG_NONE); +} + +MetaMonitorsConfig * +meta_monitor_config_manager_create_suggested (MetaMonitorConfigManager *config_manager) +{ + MetaMonitorManager *monitor_manager = config_manager->monitor_manager; + MetaLogicalMonitorConfig *primary_logical_monitor_config = NULL; + MetaMonitor *primary_monitor; + MetaLogicalMonitorLayoutMode layout_mode; + GList *logical_monitor_configs; + GList *region; + int x, y; + float max_scale = 1; + GList *monitors; + GList *l; + + primary_monitor = find_primary_monitor (monitor_manager); + if (!primary_monitor) + return NULL; + + if (!meta_monitor_get_suggested_position (primary_monitor, &x, &y)) + return NULL; + + layout_mode = meta_monitor_manager_get_default_layout_mode (monitor_manager); + + if (layout_mode == META_LOGICAL_MONITOR_LAYOUT_MODE_GLOBAL_UI_LOGICAL) + max_scale = get_preferred_preferred_max_scale (monitor_manager, + layout_mode, + MONITOR_MATCH_WITH_POSITION); + + primary_logical_monitor_config = + create_preferred_logical_monitor_config (monitor_manager, + primary_monitor, + x, y, + max_scale, + NULL, + layout_mode); + primary_logical_monitor_config->is_primary = TRUE; + logical_monitor_configs = g_list_append (NULL, + primary_logical_monitor_config); + region = g_list_prepend (NULL, &primary_logical_monitor_config->layout); + + monitors = meta_monitor_manager_get_monitors (monitor_manager); + for (l = monitors; l; l = l->next) + { + MetaMonitor *monitor = l->data; + MetaLogicalMonitorConfig *logical_monitor_config; + + if (monitor == primary_monitor) + continue; + + if (!meta_monitor_get_suggested_position (monitor, &x, &y)) + continue; + + logical_monitor_config = + create_preferred_logical_monitor_config (monitor_manager, + monitor, + x, y, + max_scale, + primary_logical_monitor_config, + layout_mode); + logical_monitor_configs = g_list_append (logical_monitor_configs, + logical_monitor_config); + + if (meta_rectangle_overlaps_with_region (region, + &logical_monitor_config->layout)) + { + g_warning ("Suggested monitor config has overlapping region, rejecting"); + g_list_free (region); + g_list_free_full (logical_monitor_configs, + (GDestroyNotify) meta_logical_monitor_config_free); + return NULL; + } + + region = g_list_prepend (region, &logical_monitor_config->layout); + } + + for (l = region; region->next && l; l = l->next) + { + MetaRectangle *rect = l->data; + + if (!meta_rectangle_has_adjacent_in_region (region, rect)) + { + g_warning ("Suggested monitor config has monitors with no neighbors, " + "rejecting"); + g_list_free (region); + g_list_free_full (logical_monitor_configs, + (GDestroyNotify) meta_logical_monitor_config_free); + return NULL; + } + } + + g_list_free (region); + + if (!logical_monitor_configs) + return NULL; + + return meta_monitors_config_new (monitor_manager, + logical_monitor_configs, + layout_mode, + META_MONITORS_CONFIG_FLAG_NONE); +} + +static GList * +clone_monitor_config_list (GList *monitor_configs_in) +{ + MetaMonitorConfig *monitor_config_in; + MetaMonitorConfig *monitor_config_out; + GList *monitor_configs_out = NULL; + GList *l; + + for (l = monitor_configs_in; l; l = l->next) + { + monitor_config_in = l->data; + monitor_config_out = g_new0 (MetaMonitorConfig, 1); + *monitor_config_out = (MetaMonitorConfig) { + .monitor_spec = meta_monitor_spec_clone (monitor_config_in->monitor_spec), + .mode_spec = g_memdup (monitor_config_in->mode_spec, + sizeof (MetaMonitorModeSpec)), + .enable_underscanning = monitor_config_in->enable_underscanning + }; + monitor_configs_out = + g_list_append (monitor_configs_out, monitor_config_out); + } + + return monitor_configs_out; +} + +static GList * +clone_logical_monitor_config_list (GList *logical_monitor_configs_in) +{ + MetaLogicalMonitorConfig *logical_monitor_config_in; + MetaLogicalMonitorConfig *logical_monitor_config_out; + GList *logical_monitor_configs_out = NULL; + GList *l; + + for (l = logical_monitor_configs_in; l; l = l->next) + { + logical_monitor_config_in = l->data; + + logical_monitor_config_out = + g_memdup (logical_monitor_config_in, sizeof (MetaLogicalMonitorConfig)); + logical_monitor_config_out->monitor_configs = + clone_monitor_config_list (logical_monitor_config_in->monitor_configs); + + logical_monitor_configs_out = + g_list_append (logical_monitor_configs_out, logical_monitor_config_out); + } + + return logical_monitor_configs_out; +} + +static MetaLogicalMonitorConfig * +find_logical_config_for_builtin_display_rotation (MetaMonitorConfigManager *config_manager, + GList *logical_monitor_configs) +{ + MetaLogicalMonitorConfig *logical_monitor_config; + MetaMonitorConfig *monitor_config; + MetaMonitor *panel; + GList *l; + + panel = meta_monitor_manager_get_laptop_panel (config_manager->monitor_manager); + if (panel && meta_monitor_is_active (panel)) + { + for (l = logical_monitor_configs; l; l = l->next) + { + logical_monitor_config = l->data; + /* + * We only want to return the config for the panel if it is + * configured on its own, so we skip configs which contain clones. + */ + if (g_list_length (logical_monitor_config->monitor_configs) != 1) + continue; + + monitor_config = logical_monitor_config->monitor_configs->data; + if (meta_monitor_spec_equals (meta_monitor_get_spec (panel), + monitor_config->monitor_spec)) + return logical_monitor_config; + } + } + + return NULL; +} + +static MetaMonitorsConfig * +create_for_builtin_display_rotation (MetaMonitorConfigManager *config_manager, + gboolean rotate, + MetaMonitorTransform transform) +{ + MetaMonitorManager *monitor_manager = config_manager->monitor_manager; + MetaLogicalMonitorConfig *logical_monitor_config; + MetaLogicalMonitorConfig *current_logical_monitor_config; + GList *logical_monitor_configs, *current_configs; + MetaLogicalMonitorLayoutMode layout_mode; + + if (!config_manager->current_config) + return NULL; + + current_configs = config_manager->current_config->logical_monitor_configs; + current_logical_monitor_config = + find_logical_config_for_builtin_display_rotation (config_manager, + current_configs); + if (!current_logical_monitor_config) + return NULL; + + if (rotate) + transform = (current_logical_monitor_config->transform + 1) % META_MONITOR_TRANSFORM_FLIPPED; + else + { + /* + * The transform coming from the accelerometer should be applied to + * the crtc as is, without taking panel-orientation into account, this + * is done so that non panel-orientation aware desktop environments do the + * right thing. Mutter corrects for panel-orientation when applying the + * transform from a logical-monitor-config, so we must convert here. + */ + MetaMonitor *panel = + meta_monitor_manager_get_laptop_panel (config_manager->monitor_manager); + + transform = meta_monitor_crtc_to_logical_transform (panel, transform); + } + + if (current_logical_monitor_config->transform == transform) + return NULL; + + logical_monitor_configs = + clone_logical_monitor_config_list (config_manager->current_config->logical_monitor_configs); + logical_monitor_config = + find_logical_config_for_builtin_display_rotation (config_manager, logical_monitor_configs); + logical_monitor_config->transform = transform; + + if (meta_monitor_transform_is_rotated (current_logical_monitor_config->transform) != + meta_monitor_transform_is_rotated (logical_monitor_config->transform)) + { + int temp = logical_monitor_config->layout.width; + logical_monitor_config->layout.width = logical_monitor_config->layout.height; + logical_monitor_config->layout.height = temp; + } + + layout_mode = config_manager->current_config->layout_mode; + return meta_monitors_config_new (monitor_manager, + logical_monitor_configs, + layout_mode, + META_MONITORS_CONFIG_FLAG_NONE); +} + +MetaMonitorsConfig * +meta_monitor_config_manager_create_for_orientation (MetaMonitorConfigManager *config_manager, + MetaMonitorTransform transform) +{ + return create_for_builtin_display_rotation (config_manager, FALSE, transform); +} + +MetaMonitorsConfig * +meta_monitor_config_manager_create_for_rotate_monitor (MetaMonitorConfigManager *config_manager) +{ + return create_for_builtin_display_rotation (config_manager, TRUE, META_MONITOR_TRANSFORM_NORMAL); +} + +MetaMonitorsConfig * +meta_monitor_config_manager_create_for_layout (MetaMonitorConfigManager *config_manager, + MetaMonitorsConfig *config, + MetaLogicalMonitorLayoutMode layout_mode) +{ + MetaMonitorManager *monitor_manager = config_manager->monitor_manager; + GList *logical_monitor_configs; + GList *l; + + if (!config) + return NULL; + + if (config->layout_mode == layout_mode) + return g_object_ref (config); + + logical_monitor_configs = + clone_logical_monitor_config_list (config->logical_monitor_configs); + + if (layout_mode == META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL) + { + for (l = logical_monitor_configs; l; l = l->next) + { + MetaLogicalMonitorConfig *monitor_config = l->data; + monitor_config->scale = roundf (monitor_config->scale); + } + } + + return meta_monitors_config_new (monitor_manager, + logical_monitor_configs, + layout_mode, + META_MONITORS_CONFIG_FLAG_NONE); +} + +static MetaMonitorsConfig * +create_for_switch_config_all_mirror (MetaMonitorConfigManager *config_manager) +{ + MetaMonitorManager *monitor_manager = config_manager->monitor_manager; + MetaLogicalMonitorLayoutMode layout_mode; + MetaLogicalMonitorConfig *logical_monitor_config = NULL; + GList *logical_monitor_configs; + GList *monitor_configs = NULL; + gint common_mode_w = 0, common_mode_h = 0; + float best_scale = 1.0; + MetaMonitor *monitor; + GList *modes; + GList *monitors; + GList *l; + + monitors = meta_monitor_manager_get_monitors (monitor_manager); + monitor = monitors->data; + modes = meta_monitor_get_modes (monitor); + for (l = modes; l; l = l->next) + { + MetaMonitorMode *mode = l->data; + gboolean common_mode_size = TRUE; + gint mode_w, mode_h; + GList *ll; + + meta_monitor_mode_get_resolution (mode, &mode_w, &mode_h); + + for (ll = monitors->next; ll; ll = ll->next) + { + MetaMonitor *monitor_b = ll->data; + gboolean have_same_mode_size = FALSE; + GList *mm; + + for (mm = meta_monitor_get_modes (monitor_b); mm; mm = mm->next) + { + MetaMonitorMode *mode_b = mm->data; + gint mode_b_w, mode_b_h; + + meta_monitor_mode_get_resolution (mode_b, &mode_b_w, &mode_b_h); + + if (mode_w == mode_b_w && + mode_h == mode_b_h) + { + have_same_mode_size = TRUE; + break; + } + } + + if (!have_same_mode_size) + { + common_mode_size = FALSE; + break; + } + } + + if (common_mode_size && + common_mode_w * common_mode_h < mode_w * mode_h) + { + common_mode_w = mode_w; + common_mode_h = mode_h; + } + } + + if (common_mode_w == 0 || common_mode_h == 0) + return NULL; + + for (l = monitors; l; l = l->next) + { + MetaMonitor *monitor = l->data; + MetaMonitorMode *mode = NULL; + GList *ll; + float scale; + + for (ll = meta_monitor_get_modes (monitor); ll; ll = ll->next) + { + gint mode_w, mode_h; + + mode = ll->data; + meta_monitor_mode_get_resolution (mode, &mode_w, &mode_h); + + if (mode_w == common_mode_w && mode_h == common_mode_h) + break; + } + + if (!mode) + continue; + + scale = meta_monitor_manager_calculate_monitor_mode_scale (monitor_manager, + monitor_manager->layout_mode, + monitor, mode); + best_scale = MAX (best_scale, scale); + monitor_configs = g_list_prepend (monitor_configs, create_monitor_config (monitor, mode)); + } + + logical_monitor_config = g_new0 (MetaLogicalMonitorConfig, 1); + *logical_monitor_config = (MetaLogicalMonitorConfig) { + .layout = (MetaRectangle) { + .x = 0, + .y = 0, + .width = common_mode_w, + .height = common_mode_h + }, + .scale = best_scale, + .monitor_configs = monitor_configs + }; + + logical_monitor_configs = g_list_append (NULL, logical_monitor_config); + layout_mode = meta_monitor_manager_get_default_layout_mode (monitor_manager); + return meta_monitors_config_new (monitor_manager, + logical_monitor_configs, + layout_mode, + META_MONITORS_CONFIG_FLAG_NONE); +} + +static MetaMonitorsConfig * +create_for_switch_config_external (MetaMonitorConfigManager *config_manager) +{ + MetaMonitorManager *monitor_manager = config_manager->monitor_manager; + GList *logical_monitor_configs = NULL; + int x = 0; + float max_scale = 1.0f; + MetaLogicalMonitorLayoutMode layout_mode; + GList *monitors; + GList *l; + + layout_mode = meta_monitor_manager_get_default_layout_mode (monitor_manager); + + if (layout_mode == META_LOGICAL_MONITOR_LAYOUT_MODE_GLOBAL_UI_LOGICAL) + max_scale = get_preferred_preferred_max_scale (monitor_manager, + layout_mode, + MONITOR_MATCH_EXTERNAL); + + monitors = meta_monitor_manager_get_monitors (monitor_manager); + for (l = monitors; l; l = l->next) + { + MetaMonitor *monitor = l->data; + MetaLogicalMonitorConfig *logical_monitor_config; + + if (meta_monitor_is_laptop_panel (monitor)) + continue; + + logical_monitor_config = + create_preferred_logical_monitor_config (monitor_manager, + monitor, + x, 0, + max_scale, + NULL, + layout_mode); + logical_monitor_configs = g_list_append (logical_monitor_configs, + logical_monitor_config); + + if (x == 0) + logical_monitor_config->is_primary = TRUE; + + x += logical_monitor_config->layout.width; + } + + return meta_monitors_config_new (monitor_manager, + logical_monitor_configs, + layout_mode, + META_MONITORS_CONFIG_FLAG_NONE); +} + +static MetaMonitorsConfig * +create_for_switch_config_builtin (MetaMonitorConfigManager *config_manager) +{ + MetaMonitorManager *monitor_manager = config_manager->monitor_manager; + MetaLogicalMonitorLayoutMode layout_mode; + GList *logical_monitor_configs; + MetaLogicalMonitorConfig *primary_logical_monitor_config; + MetaMonitor *monitor; + float max_scale = 1.0f; + + monitor = meta_monitor_manager_get_laptop_panel (monitor_manager); + if (!monitor) + return NULL; + + layout_mode = meta_monitor_manager_get_default_layout_mode (monitor_manager); + + if (layout_mode == META_LOGICAL_MONITOR_LAYOUT_MODE_GLOBAL_UI_LOGICAL) + max_scale = get_preferred_preferred_max_scale (monitor_manager, + layout_mode, + MONITOR_MATCH_BUILTIN); + + primary_logical_monitor_config = + create_preferred_logical_monitor_config (monitor_manager, + monitor, + 0, 0, + max_scale, + NULL, + layout_mode); + primary_logical_monitor_config->is_primary = TRUE; + logical_monitor_configs = g_list_append (NULL, + primary_logical_monitor_config); + + return meta_monitors_config_new (monitor_manager, + logical_monitor_configs, + layout_mode, + META_MONITORS_CONFIG_FLAG_NONE); +} + +MetaMonitorsConfig * +meta_monitor_config_manager_create_for_switch_config (MetaMonitorConfigManager *config_manager, + MetaMonitorSwitchConfigType config_type) +{ + MetaMonitorManager *monitor_manager = config_manager->monitor_manager; + MetaMonitorsConfig *config; + + if (!meta_monitor_manager_can_switch_config (monitor_manager)) + return NULL; + + switch (config_type) + { + case META_MONITOR_SWITCH_CONFIG_ALL_MIRROR: + config = create_for_switch_config_all_mirror (config_manager); + break; + case META_MONITOR_SWITCH_CONFIG_ALL_LINEAR: + config = meta_monitor_config_manager_create_linear (config_manager); + break; + case META_MONITOR_SWITCH_CONFIG_EXTERNAL: + config = create_for_switch_config_external (config_manager); + break; + case META_MONITOR_SWITCH_CONFIG_BUILTIN: + config = create_for_switch_config_builtin (config_manager); + break; + case META_MONITOR_SWITCH_CONFIG_UNKNOWN: + default: + g_warn_if_reached (); + return NULL; + } + + if (config) + meta_monitors_config_set_switch_config (config, config_type); + + return config; +} + +void +meta_monitor_config_manager_set_current (MetaMonitorConfigManager *config_manager, + MetaMonitorsConfig *config) +{ + if (config_manager->current_config) + { + g_queue_push_head (&config_manager->config_history, + g_object_ref (config_manager->current_config)); + if (g_queue_get_length (&config_manager->config_history) > + CONFIG_HISTORY_MAX_SIZE) + g_object_unref (g_queue_pop_tail (&config_manager->config_history)); + } + + g_set_object (&config_manager->current_config, config); +} + +void +meta_monitor_config_manager_save_current (MetaMonitorConfigManager *config_manager) +{ + g_return_if_fail (config_manager->current_config); + + meta_monitor_config_store_add (config_manager->config_store, + config_manager->current_config); +} + +MetaMonitorsConfig * +meta_monitor_config_manager_get_current (MetaMonitorConfigManager *config_manager) +{ + return config_manager->current_config; +} + +MetaMonitorsConfig * +meta_monitor_config_manager_pop_previous (MetaMonitorConfigManager *config_manager) +{ + return g_queue_pop_head (&config_manager->config_history); +} + +MetaMonitorsConfig * +meta_monitor_config_manager_get_previous (MetaMonitorConfigManager *config_manager) +{ + return g_queue_peek_head (&config_manager->config_history); +} + +void +meta_monitor_config_manager_clear_history (MetaMonitorConfigManager *config_manager) +{ + g_queue_foreach (&config_manager->config_history, (GFunc) g_object_unref, NULL); + g_queue_clear (&config_manager->config_history); +} + +static void +meta_monitor_config_manager_dispose (GObject *object) +{ + MetaMonitorConfigManager *config_manager = + META_MONITOR_CONFIG_MANAGER (object); + + g_clear_object (&config_manager->current_config); + meta_monitor_config_manager_clear_history (config_manager); + + G_OBJECT_CLASS (meta_monitor_config_manager_parent_class)->dispose (object); +} + +static void +meta_monitor_config_manager_init (MetaMonitorConfigManager *config_manager) +{ + g_queue_init (&config_manager->config_history); +} + +static void +meta_monitor_config_manager_class_init (MetaMonitorConfigManagerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = meta_monitor_config_manager_dispose; +} + +void +meta_monitor_config_free (MetaMonitorConfig *monitor_config) +{ + meta_monitor_spec_free (monitor_config->monitor_spec); + g_free (monitor_config->mode_spec); + g_free (monitor_config); +} + +void +meta_logical_monitor_config_free (MetaLogicalMonitorConfig *logical_monitor_config) +{ + g_list_free_full (logical_monitor_config->monitor_configs, + (GDestroyNotify) meta_monitor_config_free); + g_free (logical_monitor_config); +} + +static MetaMonitorsConfigKey * +meta_monitors_config_key_new (GList *logical_monitor_configs, + GList *disabled_monitor_specs) +{ + MetaMonitorsConfigKey *config_key; + GList *monitor_specs; + GList *l; + + monitor_specs = NULL; + for (l = logical_monitor_configs; l; l = l->next) + { + MetaLogicalMonitorConfig *logical_monitor_config = l->data; + GList *k; + + for (k = logical_monitor_config->monitor_configs; k; k = k->next) + { + MetaMonitorConfig *monitor_config = k->data; + MetaMonitorSpec *monitor_spec; + + monitor_spec = meta_monitor_spec_clone (monitor_config->monitor_spec); + monitor_specs = g_list_prepend (monitor_specs, monitor_spec); + } + } + + for (l = disabled_monitor_specs; l; l = l->next) + { + MetaMonitorSpec *monitor_spec = l->data; + + monitor_spec = meta_monitor_spec_clone (monitor_spec); + monitor_specs = g_list_prepend (monitor_specs, monitor_spec); + } + + monitor_specs = g_list_sort (monitor_specs, + (GCompareFunc) meta_monitor_spec_compare); + + config_key = g_new0 (MetaMonitorsConfigKey, 1); + *config_key = (MetaMonitorsConfigKey) { + .monitor_specs = monitor_specs + }; + + return config_key; +} + +void +meta_monitors_config_key_free (MetaMonitorsConfigKey *config_key) +{ + g_list_free_full (config_key->monitor_specs, + (GDestroyNotify) meta_monitor_spec_free); + g_free (config_key); +} + +unsigned int +meta_monitors_config_key_hash (gconstpointer data) +{ + const MetaMonitorsConfigKey *config_key = data; + GList *l; + unsigned long hash; + + hash = 0; + for (l = config_key->monitor_specs; l; l = l->next) + { + MetaMonitorSpec *monitor_spec = l->data; + + hash ^= (g_str_hash (monitor_spec->connector) ^ + g_str_hash (monitor_spec->vendor) ^ + g_str_hash (monitor_spec->product) ^ + g_str_hash (monitor_spec->serial)); + } + + return hash; +} + +gboolean +meta_monitors_config_key_equal (gconstpointer data_a, + gconstpointer data_b) +{ + const MetaMonitorsConfigKey *config_key_a = data_a; + const MetaMonitorsConfigKey *config_key_b = data_b; + GList *l_a, *l_b; + + for (l_a = config_key_a->monitor_specs, l_b = config_key_b->monitor_specs; + l_a && l_b; + l_a = l_a->next, l_b = l_b->next) + { + MetaMonitorSpec *monitor_spec_a = l_a->data; + MetaMonitorSpec *monitor_spec_b = l_b->data; + + if (!meta_monitor_spec_equals (monitor_spec_a, monitor_spec_b)) + return FALSE; + } + + if (l_a || l_b) + return FALSE; + + return TRUE; +} + +MetaMonitorSwitchConfigType +meta_monitors_config_get_switch_config (MetaMonitorsConfig *config) +{ + return config->switch_config; +} + +void +meta_monitors_config_set_switch_config (MetaMonitorsConfig *config, + MetaMonitorSwitchConfigType switch_config) +{ + config->switch_config = switch_config; +} + +MetaMonitorsConfig * +meta_monitors_config_new_full (GList *logical_monitor_configs, + GList *disabled_monitor_specs, + MetaLogicalMonitorLayoutMode layout_mode, + MetaMonitorsConfigFlag flags) +{ + MetaMonitorsConfig *config; + + config = g_object_new (META_TYPE_MONITORS_CONFIG, NULL); + config->logical_monitor_configs = logical_monitor_configs; + config->disabled_monitor_specs = disabled_monitor_specs; + config->key = meta_monitors_config_key_new (logical_monitor_configs, + disabled_monitor_specs); + config->layout_mode = layout_mode; + config->flags = flags; + config->switch_config = META_MONITOR_SWITCH_CONFIG_UNKNOWN; + + return config; +} + +MetaMonitorsConfig * +meta_monitors_config_new (MetaMonitorManager *monitor_manager, + GList *logical_monitor_configs, + MetaLogicalMonitorLayoutMode layout_mode, + MetaMonitorsConfigFlag flags) +{ + GList *disabled_monitor_specs = NULL; + GList *monitors; + GList *l; + + monitors = meta_monitor_manager_get_monitors (monitor_manager); + for (l = monitors; l; l = l->next) + { + MetaMonitor *monitor = l->data; + MetaMonitorSpec *monitor_spec; + + if (is_lid_closed (monitor_manager) && + meta_monitor_is_laptop_panel (monitor)) + continue; + + monitor_spec = meta_monitor_get_spec (monitor); + if (meta_logical_monitor_configs_have_monitor (logical_monitor_configs, + monitor_spec)) + continue; + + disabled_monitor_specs = + g_list_prepend (disabled_monitor_specs, + meta_monitor_spec_clone (monitor_spec)); + } + + return meta_monitors_config_new_full (logical_monitor_configs, + disabled_monitor_specs, + layout_mode, + flags); +} + +static void +meta_monitors_config_finalize (GObject *object) +{ + MetaMonitorsConfig *config = META_MONITORS_CONFIG (object); + + meta_monitors_config_key_free (config->key); + g_list_free_full (config->logical_monitor_configs, + (GDestroyNotify) meta_logical_monitor_config_free); + g_list_free_full (config->disabled_monitor_specs, + (GDestroyNotify) meta_monitor_spec_free); + + G_OBJECT_CLASS (meta_monitors_config_parent_class)->finalize (object); +} + +static void +meta_monitors_config_init (MetaMonitorsConfig *config) +{ +} + +static void +meta_monitors_config_class_init (MetaMonitorsConfigClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_monitors_config_finalize; +} + +static void +meta_crtc_info_free (MetaCrtcInfo *info) +{ + g_ptr_array_free (info->outputs, TRUE); + g_slice_free (MetaCrtcInfo, info); +} + +static void +meta_output_info_free (MetaOutputInfo *info) +{ + g_slice_free (MetaOutputInfo, info); +} + +gboolean +meta_verify_monitor_mode_spec (MetaMonitorModeSpec *monitor_mode_spec, + GError **error) +{ + if (monitor_mode_spec->width > 0 && + monitor_mode_spec->height > 0 && + monitor_mode_spec->refresh_rate > 0.0f) + { + return TRUE; + } + else + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Monitor mode invalid"); + return FALSE; + } +} + +gboolean +meta_verify_monitor_spec (MetaMonitorSpec *monitor_spec, + GError **error) +{ + if (monitor_spec->connector && + monitor_spec->vendor && + monitor_spec->product && + monitor_spec->serial) + { + return TRUE; + } + else + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Monitor spec incomplete"); + return FALSE; + } +} + +gboolean +meta_verify_monitor_config (MetaMonitorConfig *monitor_config, + GError **error) +{ + if (monitor_config->monitor_spec && monitor_config->mode_spec) + { + return TRUE; + } + else + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Monitor config incomplete"); + return FALSE; + } +} + +gboolean +meta_verify_logical_monitor_config (MetaLogicalMonitorConfig *logical_monitor_config, + MetaLogicalMonitorLayoutMode layout_mode, + MetaMonitorManager *monitor_manager, + float max_scale, + GError **error) +{ + GList *l; + int expected_mode_width = 0; + int expected_mode_height = 0; + + if (logical_monitor_config->layout.x < 0 || + logical_monitor_config->layout.y < 0) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Invalid logical monitor position (%d, %d)", + logical_monitor_config->layout.x, + logical_monitor_config->layout.y); + return FALSE; + } + + if (!logical_monitor_config->monitor_configs) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Logical monitor is empty"); + return FALSE; + } + + if (meta_monitor_transform_is_rotated (logical_monitor_config->transform)) + { + expected_mode_width = logical_monitor_config->layout.height; + expected_mode_height = logical_monitor_config->layout.width; + } + else + { + expected_mode_width = logical_monitor_config->layout.width; + expected_mode_height = logical_monitor_config->layout.height; + } + + switch (layout_mode) + { + case META_LOGICAL_MONITOR_LAYOUT_MODE_GLOBAL_UI_LOGICAL: + expected_mode_width /= ceilf (max_scale); + expected_mode_height /= ceilf (max_scale); + /* fall through! */ + case META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL: + expected_mode_width = roundf (expected_mode_width * + logical_monitor_config->scale); + expected_mode_height = roundf (expected_mode_height * + logical_monitor_config->scale); + break; + case META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL: + break; + } + + for (l = logical_monitor_config->monitor_configs; l; l = l->next) + { + MetaMonitorConfig *monitor_config = l->data; + + if (monitor_config->mode_spec->width != expected_mode_width || + monitor_config->mode_spec->height != expected_mode_height) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Monitor modes in logical monitor conflict"); + return FALSE; + } + } + + return TRUE; +} + +static gboolean +has_adjacent_neighbour (MetaMonitorsConfig *config, + MetaLogicalMonitorConfig *logical_monitor_config) +{ + GList *l; + + if (!config->logical_monitor_configs->next) + { + g_assert (config->logical_monitor_configs->data == + logical_monitor_config); + return TRUE; + } + + for (l = config->logical_monitor_configs; l; l = l->next) + { + MetaLogicalMonitorConfig *other_logical_monitor_config = l->data; + + if (logical_monitor_config == other_logical_monitor_config) + continue; + + if (meta_rectangle_is_adjacent_to (&logical_monitor_config->layout, + &other_logical_monitor_config->layout)) + return TRUE; + } + + return FALSE; +} + +gboolean +meta_logical_monitor_configs_have_monitor (GList *logical_monitor_configs, + MetaMonitorSpec *monitor_spec) +{ + GList *l; + + for (l = logical_monitor_configs; l; l = l->next) + { + MetaLogicalMonitorConfig *logical_monitor_config = l->data; + GList *k; + + for (k = logical_monitor_config->monitor_configs; k; k = k->next) + { + MetaMonitorConfig *monitor_config = k->data; + + if (meta_monitor_spec_equals (monitor_spec, + monitor_config->monitor_spec)) + return TRUE; + } + } + + return FALSE; +} + +static gboolean +meta_monitors_config_is_monitor_enabled (MetaMonitorsConfig *config, + MetaMonitorSpec *monitor_spec) +{ + return meta_logical_monitor_configs_have_monitor (config->logical_monitor_configs, + monitor_spec); +} + +gboolean +meta_verify_monitors_config (MetaMonitorsConfig *config, + MetaMonitorManager *monitor_manager, + GError **error) +{ + int min_x, min_y; + gboolean has_primary; + GList *region; + GList *l; + gboolean global_scale_required; + + if (!config->logical_monitor_configs) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Monitors config incomplete"); + return FALSE; + } + + global_scale_required = + !!(meta_monitor_manager_get_capabilities (monitor_manager) & + META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED); + + min_x = INT_MAX; + min_y = INT_MAX; + region = NULL; + has_primary = FALSE; + for (l = config->logical_monitor_configs; l; l = l->next) + { + MetaLogicalMonitorConfig *logical_monitor_config = l->data; + + if (global_scale_required) + { + MetaLogicalMonitorConfig *prev_logical_monitor_config = + l->prev ? l->prev->data : NULL; + + if (prev_logical_monitor_config && + (prev_logical_monitor_config->scale != + logical_monitor_config->scale)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Logical monitor scales must be identical"); + return FALSE; + } + } + + if (meta_rectangle_overlaps_with_region (region, + &logical_monitor_config->layout)) + { + g_list_free (region); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Logical monitors overlap"); + return FALSE; + } + + if (has_primary && logical_monitor_config->is_primary) + { + g_list_free (region); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Config contains multiple primary logical monitors"); + return FALSE; + } + else if (logical_monitor_config->is_primary) + { + has_primary = TRUE; + } + + if (!has_adjacent_neighbour (config, logical_monitor_config)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Logical monitors not adjacent"); + return FALSE; + } + + min_x = MIN (logical_monitor_config->layout.x, min_x); + min_y = MIN (logical_monitor_config->layout.y, min_y); + + region = g_list_prepend (region, &logical_monitor_config->layout); + } + + g_list_free (region); + + for (l = config->disabled_monitor_specs; l; l = l->next) + { + MetaMonitorSpec *monitor_spec = l->data; + + if (meta_monitors_config_is_monitor_enabled (config, monitor_spec)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Assigned monitor explicitly disabled"); + return FALSE; + } + } + + if (min_x != 0 || min_y != 0) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Logical monitors positions are offset"); + return FALSE; + } + + if (!has_primary) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Config is missing primary logical"); + return FALSE; + } + + return TRUE; +} diff --git a/src/backends/meta-monitor-config-manager.h b/src/backends/meta-monitor-config-manager.h new file mode 100644 index 000000000..c337a34fa --- /dev/null +++ b/src/backends/meta-monitor-config-manager.h @@ -0,0 +1,206 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_MONITOR_CONFIG_MANAGER_H +#define META_MONITOR_CONFIG_MANAGER_H + +#include "backends/meta-monitor.h" +#include "backends/meta-monitor-manager-private.h" + +#define META_TYPE_MONITOR_CONFIG_MANAGER (meta_monitor_config_manager_get_type ()) +G_DECLARE_FINAL_TYPE (MetaMonitorConfigManager, meta_monitor_config_manager, + META, MONITOR_CONFIG_MANAGER, GObject) + +typedef struct _MetaMonitorConfig +{ + MetaMonitorSpec *monitor_spec; + MetaMonitorModeSpec *mode_spec; + gboolean enable_underscanning; +} MetaMonitorConfig; + +typedef struct _MetaLogicalMonitorConfig +{ + MetaRectangle layout; + GList *monitor_configs; + MetaMonitorTransform transform; + float scale; + gboolean is_primary; + gboolean is_presentation; +} MetaLogicalMonitorConfig; + +typedef struct _MetaMonitorsConfigKey +{ + GList *monitor_specs; +} MetaMonitorsConfigKey; + +typedef enum _MetaMonitorsConfigFlag +{ + META_MONITORS_CONFIG_FLAG_NONE = 0, + META_MONITORS_CONFIG_FLAG_MIGRATED = (1 << 0), + META_MONITORS_CONFIG_FLAG_SYSTEM_CONFIG = (1 << 1), +} MetaMonitorsConfigFlag; + +struct _MetaMonitorsConfig +{ + GObject parent; + + MetaMonitorsConfigKey *key; + GList *logical_monitor_configs; + + GList *disabled_monitor_specs; + + MetaMonitorsConfigFlag flags; + + MetaLogicalMonitorLayoutMode layout_mode; + + MetaMonitorSwitchConfigType switch_config; +}; + +#define META_TYPE_MONITORS_CONFIG (meta_monitors_config_get_type ()) +G_DECLARE_FINAL_TYPE (MetaMonitorsConfig, meta_monitors_config, + META, MONITORS_CONFIG, GObject) + +META_EXPORT_TEST +MetaMonitorConfigManager * meta_monitor_config_manager_new (MetaMonitorManager *monitor_manager); + +META_EXPORT_TEST +MetaMonitorConfigStore * meta_monitor_config_manager_get_store (MetaMonitorConfigManager *config_manager); + +META_EXPORT_TEST +gboolean meta_monitor_config_manager_assign (MetaMonitorManager *manager, + MetaMonitorsConfig *config, + GPtrArray **crtc_infos, + GPtrArray **output_infos, + GError **error); + +META_EXPORT_TEST +MetaMonitorsConfig * meta_monitor_config_manager_get_stored (MetaMonitorConfigManager *config_manager); + +META_EXPORT_TEST +MetaMonitorsConfig * meta_monitor_config_manager_create_linear (MetaMonitorConfigManager *config_manager); + +META_EXPORT_TEST +MetaMonitorsConfig * meta_monitor_config_manager_create_fallback (MetaMonitorConfigManager *config_manager); + +META_EXPORT_TEST +MetaMonitorsConfig * meta_monitor_config_manager_create_suggested (MetaMonitorConfigManager *config_manager); + +META_EXPORT_TEST +MetaMonitorsConfig * meta_monitor_config_manager_create_for_orientation (MetaMonitorConfigManager *config_manager, + MetaMonitorTransform transform); + +META_EXPORT_TEST +MetaMonitorsConfig * meta_monitor_config_manager_create_for_rotate_monitor (MetaMonitorConfigManager *config_manager); + +MetaMonitorsConfig * meta_monitor_config_manager_create_for_layout (MetaMonitorConfigManager *config_manager, + MetaMonitorsConfig *config, + MetaLogicalMonitorLayoutMode layout_mode); + +META_EXPORT_TEST +MetaMonitorsConfig * meta_monitor_config_manager_create_for_switch_config (MetaMonitorConfigManager *config_manager, + MetaMonitorSwitchConfigType config_type); + +META_EXPORT_TEST +void meta_monitor_config_manager_set_current (MetaMonitorConfigManager *config_manager, + MetaMonitorsConfig *config); + +META_EXPORT_TEST +MetaMonitorsConfig * meta_monitor_config_manager_get_current (MetaMonitorConfigManager *config_manager); + +META_EXPORT_TEST +MetaMonitorsConfig * meta_monitor_config_manager_pop_previous (MetaMonitorConfigManager *config_manager); + +META_EXPORT_TEST +MetaMonitorsConfig * meta_monitor_config_manager_get_previous (MetaMonitorConfigManager *config_manager); + +META_EXPORT_TEST +void meta_monitor_config_manager_clear_history (MetaMonitorConfigManager *config_manager); + +META_EXPORT_TEST +void meta_monitor_config_manager_save_current (MetaMonitorConfigManager *config_manager); + +META_EXPORT_TEST +MetaMonitorsConfig * meta_monitors_config_new_full (GList *logical_monitor_configs, + GList *disabled_monitors, + MetaLogicalMonitorLayoutMode layout_mode, + MetaMonitorsConfigFlag flags); + +META_EXPORT_TEST +MetaMonitorsConfig * meta_monitors_config_new (MetaMonitorManager *monitor_manager, + GList *logical_monitor_configs, + MetaLogicalMonitorLayoutMode layout_mode, + MetaMonitorsConfigFlag flags); + +META_EXPORT_TEST +MetaMonitorSwitchConfigType meta_monitors_config_get_switch_config (MetaMonitorsConfig *config); + +META_EXPORT_TEST +void meta_monitors_config_set_switch_config (MetaMonitorsConfig *config, + MetaMonitorSwitchConfigType switch_config); + +META_EXPORT_TEST +unsigned int meta_monitors_config_key_hash (gconstpointer config_key); + +META_EXPORT_TEST +gboolean meta_monitors_config_key_equal (gconstpointer config_key_a, + gconstpointer config_key_b); + +META_EXPORT_TEST +void meta_monitors_config_key_free (MetaMonitorsConfigKey *config_key); + +META_EXPORT_TEST +void meta_logical_monitor_config_free (MetaLogicalMonitorConfig *logical_monitor_config); + +META_EXPORT_TEST +void meta_monitor_config_free (MetaMonitorConfig *monitor_config); + +META_EXPORT_TEST +MetaMonitorsConfigKey * meta_create_monitors_config_key_for_current_state (MetaMonitorManager *monitor_manager); + +META_EXPORT_TEST +gboolean meta_logical_monitor_configs_have_monitor (GList *logical_monitor_configs, + MetaMonitorSpec *monitor_spec); + +META_EXPORT_TEST +gboolean meta_verify_monitor_mode_spec (MetaMonitorModeSpec *monitor_mode_spec, + GError **error); + +META_EXPORT_TEST +gboolean meta_verify_monitor_spec (MetaMonitorSpec *monitor_spec, + GError **error); + +META_EXPORT_TEST +gboolean meta_verify_monitor_config (MetaMonitorConfig *monitor_config, + GError **error); + +META_EXPORT_TEST +gboolean meta_verify_logical_monitor_config (MetaLogicalMonitorConfig *logical_monitor_config, + MetaLogicalMonitorLayoutMode layout_mode, + MetaMonitorManager *monitor_manager, + float max_scale, + GError **error); + +META_EXPORT_TEST +gboolean meta_verify_monitors_config (MetaMonitorsConfig *config, + MetaMonitorManager *monitor_manager, + GError **error); + +#endif /* META_MONITOR_CONFIG_MANAGER_H */ diff --git a/src/backends/meta-monitor-config-migration.c b/src/backends/meta-monitor-config-migration.c new file mode 100644 index 000000000..69c426cd7 --- /dev/null +++ b/src/backends/meta-monitor-config-migration.c @@ -0,0 +1,1236 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001, 2002 Havoc Pennington + * Copyright (C) 2002, 2003 Red Hat Inc. + * Some ICCCM manager selection code derived from fvwm2, + * Copyright (C) 2001 Dominik Vogt, Matthias Clasen, and fvwm2 team + * Copyright (C) 2003 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * Copyright (C) 2013, 2017 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +/* + * Portions of this file are derived from gnome-desktop/libgnome-desktop/gnome-rr-config.c + * + * Copyright 2007, 2008, Red Hat, Inc. + * Copyright 2010 Giovanni Campagna + * + * Author: Soren Sandmann <sandmann@redhat.com> + */ + +#include "config.h" + +#include "backends/meta-monitor-config-migration.h" + +#include <gio/gio.h> +#include <string.h> + +#include "backends/meta-monitor-config-manager.h" +#include "backends/meta-monitor-config-store.h" +#include "backends/meta-monitor-manager-private.h" +#include "meta/boxes.h" + +#define META_MONITORS_CONFIG_MIGRATION_ERROR (meta_monitors_config_migration_error_quark ()) +static GQuark meta_monitors_config_migration_error_quark (void); + +G_DEFINE_QUARK (meta-monitors-config-migration-error-quark, + meta_monitors_config_migration_error) + +enum _MetaConfigMigrationError +{ + META_MONITORS_CONFIG_MIGRATION_ERROR_NOT_TILED, + META_MONITORS_CONFIG_MIGRATION_ERROR_NOT_MAIN_TILE +} MetaConfigMigrationError; + +typedef struct +{ + char *connector; + char *vendor; + char *product; + char *serial; +} MetaOutputKey; + +typedef struct +{ + gboolean enabled; + MetaRectangle rect; + float refresh_rate; + MetaMonitorTransform transform; + + gboolean is_primary; + gboolean is_presentation; + gboolean is_underscanning; +} MetaOutputConfig; + +typedef struct _MetaLegacyMonitorsConfig +{ + MetaOutputKey *keys; + MetaOutputConfig *outputs; + unsigned int n_outputs; +} MetaLegacyMonitorsConfig; + +typedef enum +{ + STATE_INITIAL, + STATE_MONITORS, + STATE_CONFIGURATION, + STATE_OUTPUT, + STATE_OUTPUT_FIELD, + STATE_CLONE +} ParserState; + +typedef struct +{ + ParserState state; + int unknown_count; + + GArray *key_array; + GArray *output_array; + MetaOutputKey key; + MetaOutputConfig output; + + char *output_field; + + GHashTable *configs; +} ConfigParser; + +static MetaLegacyMonitorsConfig * +legacy_config_new (void) +{ + return g_new0 (MetaLegacyMonitorsConfig, 1); +} + +static void +legacy_config_free (gpointer data) +{ + MetaLegacyMonitorsConfig *config = data; + + g_free (config->keys); + g_free (config->outputs); + g_free (config); +} + +static unsigned long +output_key_hash (const MetaOutputKey *key) +{ + return (g_str_hash (key->connector) ^ + g_str_hash (key->vendor) ^ + g_str_hash (key->product) ^ + g_str_hash (key->serial)); +} + +static gboolean +output_key_equal (const MetaOutputKey *one, + const MetaOutputKey *two) +{ + return (strcmp (one->connector, two->connector) == 0 && + strcmp (one->vendor, two->vendor) == 0 && + strcmp (one->product, two->product) == 0 && + strcmp (one->serial, two->serial) == 0); +} + +static unsigned int +legacy_config_hash (gconstpointer data) +{ + const MetaLegacyMonitorsConfig *config = data; + unsigned int i, hash; + + hash = 0; + for (i = 0; i < config->n_outputs; i++) + hash ^= output_key_hash (&config->keys[i]); + + return hash; +} + +static gboolean +legacy_config_equal (gconstpointer one, + gconstpointer two) +{ + const MetaLegacyMonitorsConfig *c_one = one; + const MetaLegacyMonitorsConfig *c_two = two; + unsigned int i; + gboolean ok; + + if (c_one->n_outputs != c_two->n_outputs) + return FALSE; + + ok = TRUE; + for (i = 0; i < c_one->n_outputs && ok; i++) + ok = output_key_equal (&c_one->keys[i], + &c_two->keys[i]); + + return ok; +} + +static void +free_output_key (MetaOutputKey *key) +{ + g_free (key->connector); + g_free (key->vendor); + g_free (key->product); + g_free (key->serial); +} + +static void +handle_start_element (GMarkupParseContext *context, + const char *element_name, + const char **attribute_names, + const char **attribute_values, + gpointer user_data, + GError **error) +{ + ConfigParser *parser = user_data; + + switch (parser->state) + { + case STATE_INITIAL: + { + char *version; + + if (strcmp (element_name, "monitors") != 0) + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, + "Invalid document element %s", element_name); + return; + } + + if (!g_markup_collect_attributes (element_name, + attribute_names, + attribute_values, + error, + G_MARKUP_COLLECT_STRING, + "version", &version, + G_MARKUP_COLLECT_INVALID)) + return; + + if (strcmp (version, "1") != 0) + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + "Invalid or unsupported version %s", version); + return; + } + + parser->state = STATE_MONITORS; + return; + } + + case STATE_MONITORS: + { + if (strcmp (element_name, "configuration") != 0) + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, + "Invalid toplevel element %s", element_name); + return; + } + + parser->key_array = g_array_new (FALSE, FALSE, + sizeof (MetaOutputKey)); + parser->output_array = g_array_new (FALSE, FALSE, + sizeof (MetaOutputConfig)); + parser->state = STATE_CONFIGURATION; + return; + } + + case STATE_CONFIGURATION: + { + if (strcmp (element_name, "clone") == 0 && + parser->unknown_count == 0) + { + parser->state = STATE_CLONE; + } + else if (strcmp (element_name, "output") == 0 && + parser->unknown_count == 0) + { + char *name; + + if (!g_markup_collect_attributes (element_name, + attribute_names, + attribute_values, + error, + G_MARKUP_COLLECT_STRING, + "name", &name, + G_MARKUP_COLLECT_INVALID)) + return; + + memset (&parser->key, 0, sizeof (MetaOutputKey)); + memset (&parser->output, 0, sizeof (MetaOutputConfig)); + + parser->key.connector = g_strdup (name); + parser->state = STATE_OUTPUT; + } + else + { + parser->unknown_count++; + } + + return; + } + + case STATE_OUTPUT: + { + if ((strcmp (element_name, "vendor") == 0 || + strcmp (element_name, "product") == 0 || + strcmp (element_name, "serial") == 0 || + strcmp (element_name, "width") == 0 || + strcmp (element_name, "height") == 0 || + strcmp (element_name, "rate") == 0 || + strcmp (element_name, "x") == 0 || + strcmp (element_name, "y") == 0 || + strcmp (element_name, "rotation") == 0 || + strcmp (element_name, "reflect_x") == 0 || + strcmp (element_name, "reflect_y") == 0 || + strcmp (element_name, "primary") == 0 || + strcmp (element_name, "presentation") == 0 || + strcmp (element_name, "underscanning") == 0) && + parser->unknown_count == 0) + { + parser->state = STATE_OUTPUT_FIELD; + + parser->output_field = g_strdup (element_name); + } + else + { + parser->unknown_count++; + } + + return; + } + + case STATE_CLONE: + case STATE_OUTPUT_FIELD: + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + "Unexpected element %s", element_name); + return; + } + + default: + g_assert_not_reached (); + } +} + +static void +handle_end_element (GMarkupParseContext *context, + const char *element_name, + gpointer user_data, + GError **error) +{ + ConfigParser *parser = user_data; + + switch (parser->state) + { + case STATE_MONITORS: + { + parser->state = STATE_INITIAL; + return; + } + + case STATE_CONFIGURATION: + { + if (strcmp (element_name, "configuration") == 0 && + parser->unknown_count == 0) + { + MetaLegacyMonitorsConfig *config = legacy_config_new (); + + g_assert (parser->key_array->len == parser->output_array->len); + + config->n_outputs = parser->key_array->len; + config->keys = (void*)g_array_free (parser->key_array, FALSE); + config->outputs = (void*)g_array_free (parser->output_array, FALSE); + + g_hash_table_replace (parser->configs, config, config); + + parser->key_array = NULL; + parser->output_array = NULL; + parser->state = STATE_MONITORS; + } + else + { + parser->unknown_count--; + + g_assert (parser->unknown_count >= 0); + } + + return; + } + + case STATE_OUTPUT: + { + if (strcmp (element_name, "output") == 0 && parser->unknown_count == 0) + { + if (parser->key.vendor == NULL || + parser->key.product == NULL || + parser->key.serial == NULL) + { + /* Disconnected output, ignore */ + free_output_key (&parser->key); + } + else + { + if (parser->output.rect.width == 0 || + parser->output.rect.height == 0) + parser->output.enabled = FALSE; + else + parser->output.enabled = TRUE; + + g_array_append_val (parser->key_array, parser->key); + g_array_append_val (parser->output_array, parser->output); + } + + memset (&parser->key, 0, sizeof (MetaOutputKey)); + memset (&parser->output, 0, sizeof (MetaOutputConfig)); + + parser->state = STATE_CONFIGURATION; + } + else + { + parser->unknown_count--; + + g_assert (parser->unknown_count >= 0); + } + + return; + } + + case STATE_CLONE: + { + parser->state = STATE_CONFIGURATION; + return; + } + + case STATE_OUTPUT_FIELD: + { + g_free (parser->output_field); + parser->output_field = NULL; + + parser->state = STATE_OUTPUT; + return; + } + + case STATE_INITIAL: + default: + g_assert_not_reached (); + } +} + +static void +read_int (const char *text, + gsize text_len, + gint *field, + GError **error) +{ + char buf[64]; + gint64 v; + char *end; + + strncpy (buf, text, text_len); + buf[MIN (63, text_len)] = 0; + + v = g_ascii_strtoll (buf, &end, 10); + + /* Limit reasonable values (actual limits are a lot smaller that these) */ + if (*end || v < 0 || v > G_MAXINT16) + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + "Expected a number, got %s", buf); + else + *field = v; +} + +static void +read_float (const char *text, + gsize text_len, + gfloat *field, + GError **error) +{ + char buf[64]; + gfloat v; + char *end; + + strncpy (buf, text, text_len); + buf[MIN (63, text_len)] = 0; + + v = g_ascii_strtod (buf, &end); + + /* Limit reasonable values (actual limits are a lot smaller that these) */ + if (*end) + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + "Expected a number, got %s", buf); + else + *field = v; +} + +static gboolean +read_bool (const char *text, + gsize text_len, + GError **error) +{ + if (strncmp (text, "no", text_len) == 0) + return FALSE; + else if (strncmp (text, "yes", text_len) == 0) + return TRUE; + else + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + "Invalid boolean value %.*s", (int)text_len, text); + + return FALSE; +} + +static gboolean +is_all_whitespace (const char *text, + gsize text_len) +{ + gsize i; + + for (i = 0; i < text_len; i++) + if (!g_ascii_isspace (text[i])) + return FALSE; + + return TRUE; +} + +static void +handle_text (GMarkupParseContext *context, + const gchar *text, + gsize text_len, + gpointer user_data, + GError **error) +{ + ConfigParser *parser = user_data; + + switch (parser->state) + { + case STATE_MONITORS: + { + if (!is_all_whitespace (text, text_len)) + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + "Unexpected content at this point"); + return; + } + + case STATE_CONFIGURATION: + { + if (parser->unknown_count == 0) + { + if (!is_all_whitespace (text, text_len)) + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + "Unexpected content at this point"); + } + else + { + /* Handling unknown element, ignore */ + } + + return; + } + + case STATE_OUTPUT: + { + if (parser->unknown_count == 0) + { + if (!is_all_whitespace (text, text_len)) + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + "Unexpected content at this point"); + } + else + { + /* Handling unknown element, ignore */ + } + return; + } + + case STATE_CLONE: + { + /* Ignore the clone flag */ + return; + } + + case STATE_OUTPUT_FIELD: + { + if (strcmp (parser->output_field, "vendor") == 0) + parser->key.vendor = g_strndup (text, text_len); + else if (strcmp (parser->output_field, "product") == 0) + parser->key.product = g_strndup (text, text_len); + else if (strcmp (parser->output_field, "serial") == 0) + parser->key.serial = g_strndup (text, text_len); + else if (strcmp (parser->output_field, "width") == 0) + read_int (text, text_len, &parser->output.rect.width, error); + else if (strcmp (parser->output_field, "height") == 0) + read_int (text, text_len, &parser->output.rect.height, error); + else if (strcmp (parser->output_field, "rate") == 0) + read_float (text, text_len, &parser->output.refresh_rate, error); + else if (strcmp (parser->output_field, "x") == 0) + read_int (text, text_len, &parser->output.rect.x, error); + else if (strcmp (parser->output_field, "y") == 0) + read_int (text, text_len, &parser->output.rect.y, error); + else if (strcmp (parser->output_field, "rotation") == 0) + { + if (strncmp (text, "normal", text_len) == 0) + parser->output.transform = META_MONITOR_TRANSFORM_NORMAL; + else if (strncmp (text, "left", text_len) == 0) + parser->output.transform = META_MONITOR_TRANSFORM_90; + else if (strncmp (text, "upside_down", text_len) == 0) + parser->output.transform = META_MONITOR_TRANSFORM_180; + else if (strncmp (text, "right", text_len) == 0) + parser->output.transform = META_MONITOR_TRANSFORM_270; + else + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + "Invalid rotation type %.*s", (int)text_len, text); + } + else if (strcmp (parser->output_field, "reflect_x") == 0) + parser->output.transform += read_bool (text, text_len, error) ? + META_MONITOR_TRANSFORM_FLIPPED : 0; + else if (strcmp (parser->output_field, "reflect_y") == 0) + { + if (read_bool (text, text_len, error)) + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + "Y reflection is not supported"); + } + else if (strcmp (parser->output_field, "primary") == 0) + parser->output.is_primary = read_bool (text, text_len, error); + else if (strcmp (parser->output_field, "presentation") == 0) + parser->output.is_presentation = read_bool (text, text_len, error); + else if (strcmp (parser->output_field, "underscanning") == 0) + parser->output.is_underscanning = read_bool (text, text_len, error); + else + g_assert_not_reached (); + return; + } + + case STATE_INITIAL: + default: + g_assert_not_reached (); + } +} + +static const GMarkupParser config_parser = { + .start_element = handle_start_element, + .end_element = handle_end_element, + .text = handle_text, +}; + +static GHashTable * +load_config_file (GFile *file, + GError **error) +{ + g_autofree char *contents = NULL; + gsize size; + g_autoptr (GMarkupParseContext) context = NULL; + ConfigParser parser = { 0 }; + + if (!g_file_load_contents (file, NULL, &contents, &size, NULL, error)) + return FALSE; + + parser.configs = g_hash_table_new_full (legacy_config_hash, + legacy_config_equal, + legacy_config_free, + NULL); + parser.state = STATE_INITIAL; + + context = g_markup_parse_context_new (&config_parser, + G_MARKUP_TREAT_CDATA_AS_TEXT | + G_MARKUP_PREFIX_ERROR_POSITION, + &parser, NULL); + if (!g_markup_parse_context_parse (context, contents, size, error)) + { + if (parser.key_array) + g_array_free (parser.key_array, TRUE); + if (parser.output_array) + g_array_free (parser.output_array, TRUE); + + free_output_key (&parser.key); + g_free (parser.output_field); + g_hash_table_destroy (parser.configs); + + return NULL; + } + + return parser.configs; +} + +static MetaMonitorConfig * +create_monitor_config (MetaOutputKey *output_key, + MetaOutputConfig *output_config, + int mode_width, + int mode_height, + GError **error) +{ + MetaMonitorModeSpec *mode_spec; + MetaMonitorSpec *monitor_spec; + MetaMonitorConfig *monitor_config; + + mode_spec = g_new0 (MetaMonitorModeSpec, 1); + *mode_spec = (MetaMonitorModeSpec) { + .width = mode_width, + .height = mode_height, + .refresh_rate = output_config->refresh_rate + }; + + if (!meta_verify_monitor_mode_spec (mode_spec, error)) + { + g_free (mode_spec); + return NULL; + } + + monitor_spec = g_new0 (MetaMonitorSpec, 1); + *monitor_spec = (MetaMonitorSpec) { + .connector = output_key->connector, + .vendor = output_key->vendor, + .product = output_key->product, + .serial = output_key->serial + }; + + monitor_config = g_new0 (MetaMonitorConfig, 1); + *monitor_config = (MetaMonitorConfig) { + .monitor_spec = monitor_spec, + .mode_spec = mode_spec, + .enable_underscanning = output_config->is_underscanning + }; + + if (!meta_verify_monitor_config (monitor_config, error)) + { + meta_monitor_config_free (monitor_config); + return NULL; + } + + return monitor_config; +} + +typedef struct _MonitorTile +{ + MetaOutputKey *output_key; + MetaOutputConfig *output_config; +} MonitorTile; + +static MetaMonitorConfig * +try_derive_tiled_monitor_config (MetaLegacyMonitorsConfig *config, + MetaOutputKey *output_key, + MetaOutputConfig *output_config, + MetaMonitorConfigStore *config_store, + MetaRectangle *out_layout, + GError **error) +{ + MonitorTile top_left_tile = { 0 }; + MonitorTile top_right_tile = { 0 }; + MonitorTile bottom_left_tile = { 0 }; + MonitorTile bottom_right_tile = { 0 }; + MonitorTile origin_tile = { 0 }; + MetaMonitorTransform transform = output_config->transform; + unsigned int i; + int max_x = 0; + int min_x = INT_MAX; + int max_y = 0; + int min_y = INT_MAX; + int mode_width = 0; + int mode_height = 0; + MetaMonitorConfig *monitor_config; + + /* + * In order to derive a monitor configuration for a tiled monitor, + * try to find the origin tile, then combine the discovered output + * tiles to given the configured transform a monitor mode. + * + * If the origin tile is not the main tile (tile always enabled + * even for non-tiled modes), this will fail, but since infermation + * about tiling is lost, there is no way to discover it. + */ + + for (i = 0; i < config->n_outputs; i++) + { + MetaOutputKey *other_output_key = &config->keys[i]; + MetaOutputConfig *other_output_config = &config->outputs[i]; + MetaRectangle *rect; + + if (strcmp (output_key->vendor, other_output_key->vendor) != 0 || + strcmp (output_key->product, other_output_key->product) != 0 || + strcmp (output_key->serial, other_output_key->serial) != 0) + continue; + + rect = &other_output_config->rect; + min_x = MIN (min_x, rect->x); + min_y = MIN (min_y, rect->y); + max_x = MAX (max_x, rect->x + rect->width); + max_y = MAX (max_y, rect->y + rect->height); + + if (min_x == rect->x && + min_y == rect->y) + { + top_left_tile = (MonitorTile) { + .output_key = other_output_key, + .output_config = other_output_config + }; + } + if (max_x == rect->x + rect->width && + min_y == rect->y) + { + top_right_tile = (MonitorTile) { + .output_key = other_output_key, + .output_config = other_output_config + }; + } + if (min_x == rect->x && + max_y == rect->y + rect->height) + { + bottom_left_tile = (MonitorTile) { + .output_key = other_output_key, + .output_config = other_output_config + }; + } + if (max_x == rect->x + rect->width && + max_y == rect->y + rect->height) + { + bottom_right_tile = (MonitorTile) { + .output_key = other_output_key, + .output_config = other_output_config + }; + } + } + + if (top_left_tile.output_key == bottom_right_tile.output_key) + { + g_set_error_literal (error, + META_MONITORS_CONFIG_MIGRATION_ERROR, + META_MONITORS_CONFIG_MIGRATION_ERROR_NOT_TILED, + "Not a tiled monitor"); + return NULL; + } + + switch (transform) + { + case META_MONITOR_TRANSFORM_NORMAL: + origin_tile = top_left_tile; + mode_width = max_x - min_x; + mode_height = max_y - min_y; + break; + case META_MONITOR_TRANSFORM_90: + origin_tile = bottom_left_tile; + mode_width = max_y - min_y; + mode_height = max_x - min_x; + break; + case META_MONITOR_TRANSFORM_180: + origin_tile = bottom_right_tile; + mode_width = max_x - min_x; + mode_height = max_y - min_y; + break; + case META_MONITOR_TRANSFORM_270: + origin_tile = top_right_tile; + mode_width = max_y - min_y; + mode_height = max_x - min_x; + break; + case META_MONITOR_TRANSFORM_FLIPPED: + origin_tile = bottom_left_tile; + mode_width = max_x - min_x; + mode_height = max_y - min_y; + break; + case META_MONITOR_TRANSFORM_FLIPPED_90: + origin_tile = bottom_right_tile; + mode_width = max_y - min_y; + mode_height = max_x - min_x; + break; + case META_MONITOR_TRANSFORM_FLIPPED_180: + origin_tile = top_right_tile; + mode_width = max_x - min_x; + mode_height = max_y - min_y; + break; + case META_MONITOR_TRANSFORM_FLIPPED_270: + origin_tile = top_left_tile; + mode_width = max_y - min_y; + mode_height = max_x - min_x; + break; + } + + g_assert (origin_tile.output_key); + g_assert (origin_tile.output_config); + + if (origin_tile.output_key != output_key) + { + g_set_error_literal (error, + META_MONITORS_CONFIG_MIGRATION_ERROR, + META_MONITORS_CONFIG_MIGRATION_ERROR_NOT_MAIN_TILE, + "Not the main tile"); + return NULL; + } + + monitor_config = create_monitor_config (origin_tile.output_key, + origin_tile.output_config, + mode_width, mode_height, + error); + if (!monitor_config) + return NULL; + + *out_layout = (MetaRectangle) { + .x = min_x, + .y = min_y, + .width = max_x - min_x, + .height = max_y - min_y + }; + + return monitor_config; +} + +static MetaMonitorConfig * +derive_monitor_config (MetaOutputKey *output_key, + MetaOutputConfig *output_config, + MetaRectangle *out_layout, + GError **error) +{ + int mode_width; + int mode_height; + MetaMonitorConfig *monitor_config; + + if (meta_monitor_transform_is_rotated (output_config->transform)) + { + mode_width = output_config->rect.height; + mode_height = output_config->rect.width; + } + else + { + mode_width = output_config->rect.width; + mode_height = output_config->rect.height; + } + + monitor_config = create_monitor_config (output_key, output_config, + mode_width, mode_height, + error); + if (!monitor_config) + return NULL; + + *out_layout = output_config->rect; + + return monitor_config; +} + +static MetaLogicalMonitorConfig * +ensure_logical_monitor (GList **logical_monitor_configs, + MetaOutputConfig *output_config, + MetaRectangle *layout) +{ + MetaLogicalMonitorConfig *new_logical_monitor_config; + GList *l; + + for (l = *logical_monitor_configs; l; l = l->next) + { + MetaLogicalMonitorConfig *logical_monitor_config = l->data; + + if (meta_rectangle_equal (&logical_monitor_config->layout, layout)) + return logical_monitor_config; + } + + new_logical_monitor_config = g_new0 (MetaLogicalMonitorConfig, 1); + *new_logical_monitor_config = (MetaLogicalMonitorConfig) { + .layout = *layout, + .is_primary = output_config->is_primary, + .is_presentation = output_config->is_presentation, + .transform = output_config->transform, + .scale = -1.0, + }; + + *logical_monitor_configs = g_list_append (*logical_monitor_configs, + new_logical_monitor_config); + + return new_logical_monitor_config; +} + +static GList * +derive_logical_monitor_configs (MetaLegacyMonitorsConfig *config, + MetaMonitorConfigStore *config_store, + GError **error) +{ + GList *logical_monitor_configs = NULL; + unsigned int i; + + for (i = 0; i < config->n_outputs; i++) + { + MetaOutputKey *output_key = &config->keys[i]; + MetaOutputConfig *output_config = &config->outputs[i]; + MetaMonitorConfig *monitor_config = NULL; + MetaRectangle layout; + MetaLogicalMonitorConfig *logical_monitor_config; + + if (!output_config->enabled) + continue; + + if (output_key->vendor && + g_strcmp0 (output_key->vendor, "unknown") != 0 && + output_key->product && + g_strcmp0 (output_key->product, "unknown") != 0 && + output_key->serial && + g_strcmp0 (output_key->serial, "unknown") != 0) + { + monitor_config = try_derive_tiled_monitor_config (config, + output_key, + output_config, + config_store, + &layout, + error); + if (!monitor_config) + { + if ((*error)->domain == META_MONITORS_CONFIG_MIGRATION_ERROR) + { + int error_code = (*error)->code; + + g_clear_error (error); + + switch (error_code) + { + case META_MONITORS_CONFIG_MIGRATION_ERROR_NOT_TILED: + break; + case META_MONITORS_CONFIG_MIGRATION_ERROR_NOT_MAIN_TILE: + continue; + } + } + else + { + g_list_free_full (logical_monitor_configs, + (GDestroyNotify) meta_logical_monitor_config_free); + return NULL; + } + } + } + + if (!monitor_config) + monitor_config = derive_monitor_config (output_key, output_config, + &layout, + error); + + if (!monitor_config) + { + g_list_free_full (logical_monitor_configs, + (GDestroyNotify) meta_logical_monitor_config_free); + return NULL; + } + + logical_monitor_config = + ensure_logical_monitor (&logical_monitor_configs, + output_config, &layout); + + logical_monitor_config->monitor_configs = + g_list_append (logical_monitor_config->monitor_configs, monitor_config); + } + + if (!logical_monitor_configs) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Empty configuration"); + return NULL; + } + + return logical_monitor_configs; +} + +static char * +generate_config_name (MetaLegacyMonitorsConfig *config) +{ + char **output_strings; + unsigned int i; + char *key_name; + + output_strings = g_new0 (char *, config->n_outputs + 1); + for (i = 0; i < config->n_outputs; i++) + { + MetaOutputKey *output_key = &config->keys[i]; + + output_strings[i] = g_strdup_printf ("%s:%s:%s:%s", + output_key->connector, + output_key->vendor, + output_key->product, + output_key->serial); + } + + key_name = g_strjoinv (", ", output_strings); + + g_strfreev (output_strings); + + return key_name; +} + +static GList * +find_disabled_monitor_specs (MetaLegacyMonitorsConfig *legacy_config) +{ + GList *disabled_monitors = NULL; + unsigned int i; + + for (i = 0; i < legacy_config->n_outputs; i++) + { + MetaOutputKey *output_key = &legacy_config->keys[i]; + MetaOutputConfig *output_config = &legacy_config->outputs[i]; + MetaMonitorSpec *monitor_spec; + + if (output_config->enabled) + continue; + + monitor_spec = g_new0 (MetaMonitorSpec, 1); + *monitor_spec = (MetaMonitorSpec) { + .connector = output_key->connector, + .vendor = output_key->vendor, + .product = output_key->product, + .serial = output_key->serial + }; + + disabled_monitors = g_list_prepend (disabled_monitors, monitor_spec); + } + + return disabled_monitors; +} + +static void +migrate_config (gpointer key, + gpointer value, + gpointer user_data) +{ + MetaLegacyMonitorsConfig *legacy_config = key; + MetaMonitorConfigStore *config_store = user_data; + MetaMonitorManager *monitor_manager = + meta_monitor_config_store_get_monitor_manager (config_store); + GList *logical_monitor_configs; + MetaLogicalMonitorLayoutMode layout_mode; + GError *error = NULL; + GList *disabled_monitor_specs; + MetaMonitorsConfig *config; + + logical_monitor_configs = derive_logical_monitor_configs (legacy_config, + config_store, + &error); + if (!logical_monitor_configs) + { + g_autofree char *config_name = NULL; + + config_name = generate_config_name (legacy_config); + g_warning ("Failed to migrate monitor configuration for %s: %s", + config_name, error->message); + return; + } + + disabled_monitor_specs = find_disabled_monitor_specs (legacy_config); + + layout_mode = META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL; + config = meta_monitors_config_new_full (logical_monitor_configs, + disabled_monitor_specs, + layout_mode, + META_MONITORS_CONFIG_FLAG_MIGRATED); + if (!meta_verify_monitors_config (config, monitor_manager, &error)) + { + g_autofree char *config_name = NULL; + + config_name = generate_config_name (legacy_config); + g_warning ("Ignoring invalid monitor configuration for %s: %s", + config_name, error->message); + g_object_unref (config); + return; + } + + meta_monitor_config_store_add (config_store, config); +} + +gboolean +meta_migrate_old_monitors_config (MetaMonitorConfigStore *config_store, + GFile *in_file, + GError **error) +{ + g_autoptr (GHashTable) configs = NULL; + + configs = load_config_file (in_file, error); + if (!configs) + return FALSE; + + g_hash_table_foreach (configs, migrate_config, config_store); + + return TRUE; +} + +gboolean +meta_migrate_old_user_monitors_config (MetaMonitorConfigStore *config_store, + GError **error) +{ + g_autofree char *backup_path = NULL; + g_autoptr (GFile) backup_file = NULL; + g_autofree char *user_file_path = NULL; + g_autoptr (GFile) user_file = NULL; + + user_file_path = g_build_filename (g_get_user_config_dir (), + "monitors.xml", + NULL); + user_file = g_file_new_for_path (user_file_path); + backup_path = g_build_filename (g_get_user_config_dir (), + "monitors-v1-backup.xml", + NULL); + backup_file = g_file_new_for_path (backup_path); + + if (!g_file_copy (user_file, backup_file, + G_FILE_COPY_OVERWRITE | G_FILE_COPY_BACKUP, + NULL, NULL, NULL, + error)) + { + g_warning ("Failed to make a backup of monitors.xml: %s", + (*error)->message); + g_clear_error (error); + } + + return meta_migrate_old_monitors_config (config_store, user_file, error); +} + +gboolean +meta_finish_monitors_config_migration (MetaMonitorManager *monitor_manager, + MetaMonitorsConfig *config, + GError **error) +{ + MetaMonitorConfigManager *config_manager = monitor_manager->config_manager; + MetaMonitorConfigStore *config_store = + meta_monitor_config_manager_get_store (config_manager); + GList *l; + MetaLogicalMonitorLayoutMode layout_mode; + + layout_mode = meta_monitor_manager_get_default_layout_mode (monitor_manager); + + for (l = config->logical_monitor_configs; l; l = l->next) + { + MetaLogicalMonitorConfig *logical_monitor_config = l->data; + MetaMonitorConfig *monitor_config; + MetaMonitorSpec *monitor_spec; + MetaMonitor *monitor; + MetaMonitorModeSpec *monitor_mode_spec; + MetaMonitorMode *monitor_mode; + + monitor_config = logical_monitor_config->monitor_configs->data; + monitor_spec = monitor_config->monitor_spec; + monitor = meta_monitor_manager_get_monitor_from_spec (monitor_manager, + monitor_spec); + monitor_mode_spec = monitor_config->mode_spec; + monitor_mode = meta_monitor_get_mode_from_spec (monitor, + monitor_mode_spec); + if (!monitor_mode) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Mode not available on monitor"); + return FALSE; + } + + logical_monitor_config->scale = + meta_monitor_manager_calculate_monitor_mode_scale (monitor_manager, + layout_mode, + monitor, + monitor_mode); + } + + config->layout_mode = layout_mode; + config->flags &= ~META_MONITORS_CONFIG_FLAG_MIGRATED; + + if (!meta_verify_monitors_config (config, monitor_manager, error)) + return FALSE; + + meta_monitor_config_store_add (config_store, config); + + return TRUE; +} diff --git a/src/backends/meta-monitor-config-migration.h b/src/backends/meta-monitor-config-migration.h new file mode 100644 index 000000000..7b338ace2 --- /dev/null +++ b/src/backends/meta-monitor-config-migration.h @@ -0,0 +1,41 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_MONITOR_CONFIG_MIGRATION_H +#define META_MONITOR_CONFIG_MIGRATION_H + +#include "backends/meta-monitor-manager-private.h" + +META_EXPORT_TEST +gboolean meta_migrate_old_monitors_config (MetaMonitorConfigStore *config_store, + GFile *in_file, + GError **error); + +META_EXPORT_TEST +gboolean meta_migrate_old_user_monitors_config (MetaMonitorConfigStore *config_store, + GError **error); + +META_EXPORT_TEST +gboolean meta_finish_monitors_config_migration (MetaMonitorManager *monitor_manager, + MetaMonitorsConfig *config, + GError **error); + +#endif /* META_MONITOR_CONFIG_MIGRATION_H */ diff --git a/src/backends/meta-monitor-config-store.c b/src/backends/meta-monitor-config-store.c new file mode 100644 index 000000000..16cfc132b --- /dev/null +++ b/src/backends/meta-monitor-config-store.c @@ -0,0 +1,1685 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "backends/meta-monitor-config-store.h" + +#include <gio/gio.h> +#include <string.h> + +#include "backends/meta-monitor-config-manager.h" +#include "backends/meta-monitor-config-migration.h" + +#define MONITORS_CONFIG_XML_FORMAT_VERSION 2 + +#define QUOTE1(a) #a +#define QUOTE(a) QUOTE1(a) + +/* + * Example configuration: + * + * <monitors version="2"> + * <configuration> + * <logicalmonitor> + * <x>0</x> + * <y>0</y> + * <scale>1</scale> + * <monitor> + * <monitorspec> + * <connector>LVDS1</connector> + * <vendor>Vendor A</vendor> + * <product>Product A</product> + * <serial>Serial A</serial> + * </monitorspec> + * <mode> + * <width>1920</width> + * <height>1080</height> + * <rate>60.049972534179688</rate> + * <flag>interlace</flag> + * </mode> + * </monitor> + * <transform> + * <rotation>right</rotation> + * <flipped>no</flipped> + * </transform> + * <primary>yes</primary> + * <presentation>no</presentation> + * </logicalmonitor> + * <logicalmonitor> + * <x>1920</x> + * <y>1080</y> + * <monitor> + * <monitorspec> + * <connector>LVDS2</connector> + * <vendor>Vendor B</vendor> + * <product>Product B</product> + * <serial>Serial B</serial> + * </monitorspec> + * <mode> + * <width>1920</width> + * <height>1080</height> + * <rate>60.049972534179688</rate> + * </mode> + * <underscanning>yes</underscanning> + * </monitor> + * <presentation>yes</presentation> + * </logicalmonitor> + * <disabled> + * <monitorspec> + * <connector>LVDS3</connector> + * <vendor>Vendor C</vendor> + * <product>Product C</product> + * <serial>Serial C</serial> + * </monitorspec> + * </disabled> + * </configuration> + * </monitors> + * + */ + +enum +{ + PROP_0, + + PROP_MONITOR_MANAGER, + + PROP_LAST +}; + +static GParamSpec *obj_props[PROP_LAST]; + +struct _MetaMonitorConfigStore +{ + GObject parent; + + MetaMonitorManager *monitor_manager; + + GHashTable *configs; + + GCancellable *save_cancellable; + + GFile *user_file; + GFile *custom_read_file; + GFile *custom_write_file; +}; + +#define META_MONITOR_CONFIG_STORE_ERROR (meta_monitor_config_store_error_quark ()) +static GQuark meta_monitor_config_store_error_quark (void); + +enum +{ + META_MONITOR_CONFIG_STORE_ERROR_NEEDS_MIGRATION +}; + +G_DEFINE_QUARK (meta-monitor-config-store-error-quark, + meta_monitor_config_store_error) + +typedef enum +{ + STATE_INITIAL, + STATE_MONITORS, + STATE_CONFIGURATION, + STATE_MIGRATED, + STATE_LOGICAL_MONITOR, + STATE_LOGICAL_MONITOR_X, + STATE_LOGICAL_MONITOR_Y, + STATE_LOGICAL_MONITOR_PRIMARY, + STATE_LOGICAL_MONITOR_PRESENTATION, + STATE_LOGICAL_MONITOR_SCALE, + STATE_TRANSFORM, + STATE_TRANSFORM_ROTATION, + STATE_TRANSFORM_FLIPPED, + STATE_MONITOR, + STATE_MONITOR_SPEC, + STATE_MONITOR_SPEC_CONNECTOR, + STATE_MONITOR_SPEC_VENDOR, + STATE_MONITOR_SPEC_PRODUCT, + STATE_MONITOR_SPEC_SERIAL, + STATE_MONITOR_MODE, + STATE_MONITOR_MODE_WIDTH, + STATE_MONITOR_MODE_HEIGHT, + STATE_MONITOR_MODE_RATE, + STATE_MONITOR_MODE_FLAG, + STATE_MONITOR_UNDERSCANNING, + STATE_DISABLED, +} ParserState; + +typedef struct +{ + ParserState state; + MetaMonitorConfigStore *config_store; + + ParserState monitor_spec_parent_state; + + gboolean current_was_migrated; + GList *current_logical_monitor_configs; + MetaMonitorSpec *current_monitor_spec; + gboolean current_transform_flipped; + MetaMonitorTransform current_transform; + MetaMonitorModeSpec *current_monitor_mode_spec; + MetaMonitorConfig *current_monitor_config; + MetaLogicalMonitorConfig *current_logical_monitor_config; + GList *current_disabled_monitor_specs; + + MetaMonitorsConfigFlag extra_config_flags; +} ConfigParser; + +G_DEFINE_TYPE (MetaMonitorConfigStore, meta_monitor_config_store, + G_TYPE_OBJECT) + +static void +handle_start_element (GMarkupParseContext *context, + const char *element_name, + const char **attribute_names, + const char **attribute_values, + gpointer user_data, + GError **error) +{ + ConfigParser *parser = user_data; + + switch (parser->state) + { + case STATE_INITIAL: + { + char *version; + + if (!g_str_equal (element_name, "monitors")) + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, + "Invalid document element '%s'", element_name); + return; + } + + if (!g_markup_collect_attributes (element_name, attribute_names, attribute_values, + error, + G_MARKUP_COLLECT_STRING, "version", &version, + G_MARKUP_COLLECT_INVALID)) + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + "Missing config file format version"); + } + + if (g_str_equal (version, "1")) + { + g_set_error_literal (error, + META_MONITOR_CONFIG_STORE_ERROR, + META_MONITOR_CONFIG_STORE_ERROR_NEEDS_MIGRATION, + "monitors.xml has the old format"); + return; + } + + if (!g_str_equal (version, QUOTE (MONITORS_CONFIG_XML_FORMAT_VERSION))) + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + "Invalid or unsupported version '%s'", version); + return; + } + + parser->state = STATE_MONITORS; + return; + } + + case STATE_MONITORS: + { + if (!g_str_equal (element_name, "configuration")) + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, + "Invalid toplevel element '%s'", element_name); + return; + } + + parser->state = STATE_CONFIGURATION; + parser->current_was_migrated = FALSE; + + return; + } + + case STATE_CONFIGURATION: + { + if (g_str_equal (element_name, "logicalmonitor")) + { + parser->current_logical_monitor_config = + g_new0 (MetaLogicalMonitorConfig, 1); + + parser->state = STATE_LOGICAL_MONITOR; + } + else if (g_str_equal (element_name, "migrated")) + { + parser->current_was_migrated = TRUE; + + parser->state = STATE_MIGRATED; + } + else if (g_str_equal (element_name, "disabled")) + { + parser->state = STATE_DISABLED; + } + else + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, + "Invalid configuration element '%s'", element_name); + return; + } + + return; + } + + case STATE_MIGRATED: + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, + "Unexpected element '%s'", element_name); + return; + } + + case STATE_LOGICAL_MONITOR: + { + if (g_str_equal (element_name, "x")) + { + parser->state = STATE_LOGICAL_MONITOR_X; + } + else if (g_str_equal (element_name, "y")) + { + parser->state = STATE_LOGICAL_MONITOR_Y; + } + else if (g_str_equal (element_name, "scale")) + { + parser->state = STATE_LOGICAL_MONITOR_SCALE; + } + else if (g_str_equal (element_name, "primary")) + { + parser->state = STATE_LOGICAL_MONITOR_PRIMARY; + } + else if (g_str_equal (element_name, "presentation")) + { + parser->state = STATE_LOGICAL_MONITOR_PRESENTATION; + } + else if (g_str_equal (element_name, "transform")) + { + parser->state = STATE_TRANSFORM; + } + else if (g_str_equal (element_name, "monitor")) + { + parser->current_monitor_config = g_new0 (MetaMonitorConfig, 1);; + + parser->state = STATE_MONITOR; + } + else + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, + "Invalid monitor logicalmonitor element '%s'", element_name); + return; + } + + return; + } + + case STATE_LOGICAL_MONITOR_X: + case STATE_LOGICAL_MONITOR_Y: + case STATE_LOGICAL_MONITOR_SCALE: + case STATE_LOGICAL_MONITOR_PRIMARY: + case STATE_LOGICAL_MONITOR_PRESENTATION: + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, + "Invalid logical monitor element '%s'", element_name); + return; + } + + case STATE_TRANSFORM: + { + if (g_str_equal (element_name, "rotation")) + { + parser->state = STATE_TRANSFORM_ROTATION; + } + else if (g_str_equal (element_name, "flipped")) + { + parser->state = STATE_TRANSFORM_FLIPPED; + } + + return; + } + + case STATE_TRANSFORM_ROTATION: + case STATE_TRANSFORM_FLIPPED: + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, + "Invalid transform element '%s'", element_name); + return; + } + + case STATE_MONITOR: + { + if (g_str_equal (element_name, "monitorspec")) + { + parser->current_monitor_spec = g_new0 (MetaMonitorSpec, 1); + parser->monitor_spec_parent_state = STATE_MONITOR; + parser->state = STATE_MONITOR_SPEC; + } + else if (g_str_equal (element_name, "mode")) + { + parser->current_monitor_mode_spec = g_new0 (MetaMonitorModeSpec, 1); + + parser->state = STATE_MONITOR_MODE; + } + else if (g_str_equal (element_name, "underscanning")) + { + parser->state = STATE_MONITOR_UNDERSCANNING; + } + else + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, + "Invalid monitor element '%s'", element_name); + return; + } + + return; + } + + case STATE_MONITOR_SPEC: + { + if (g_str_equal (element_name, "connector")) + { + parser->state = STATE_MONITOR_SPEC_CONNECTOR; + } + else if (g_str_equal (element_name, "vendor")) + { + parser->state = STATE_MONITOR_SPEC_VENDOR; + } + else if (g_str_equal (element_name, "product")) + { + parser->state = STATE_MONITOR_SPEC_PRODUCT; + } + else if (g_str_equal (element_name, "serial")) + { + parser->state = STATE_MONITOR_SPEC_SERIAL; + } + else + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, + "Invalid monitor spec element '%s'", element_name); + return; + } + + return; + } + + case STATE_MONITOR_SPEC_CONNECTOR: + case STATE_MONITOR_SPEC_VENDOR: + case STATE_MONITOR_SPEC_PRODUCT: + case STATE_MONITOR_SPEC_SERIAL: + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, + "Invalid monitor spec element '%s'", element_name); + return; + } + + case STATE_MONITOR_MODE: + { + if (g_str_equal (element_name, "width")) + { + parser->state = STATE_MONITOR_MODE_WIDTH; + } + else if (g_str_equal (element_name, "height")) + { + parser->state = STATE_MONITOR_MODE_HEIGHT; + } + else if (g_str_equal (element_name, "rate")) + { + parser->state = STATE_MONITOR_MODE_RATE; + } + else if (g_str_equal (element_name, "flag")) + { + parser->state = STATE_MONITOR_MODE_FLAG; + } + else + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, + "Invalid mode element '%s'", element_name); + return; + } + + return; + } + + case STATE_MONITOR_MODE_WIDTH: + case STATE_MONITOR_MODE_HEIGHT: + case STATE_MONITOR_MODE_RATE: + case STATE_MONITOR_MODE_FLAG: + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, + "Invalid mode sub element '%s'", element_name); + return; + } + + case STATE_MONITOR_UNDERSCANNING: + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, + "Invalid element '%s' under underscanning", element_name); + return; + } + + case STATE_DISABLED: + { + if (!g_str_equal (element_name, "monitorspec")) + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, + "Invalid element '%s' under disabled", element_name); + return; + } + + parser->current_monitor_spec = g_new0 (MetaMonitorSpec, 1); + parser->monitor_spec_parent_state = STATE_DISABLED; + parser->state = STATE_MONITOR_SPEC; + + return; + } + } +} + +static gboolean +derive_logical_monitor_layout (MetaLogicalMonitorConfig *logical_monitor_config, + MetaLogicalMonitorLayoutMode layout_mode, + float max_scale, + GError **error) +{ + MetaMonitorConfig *monitor_config; + int mode_width, mode_height; + int width = 0, height = 0; + GList *l; + + monitor_config = logical_monitor_config->monitor_configs->data; + mode_width = monitor_config->mode_spec->width; + mode_height = monitor_config->mode_spec->height; + + for (l = logical_monitor_config->monitor_configs->next; l; l = l->next) + { + monitor_config = l->data; + + if (monitor_config->mode_spec->width != mode_width || + monitor_config->mode_spec->height != mode_height) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Monitors in logical monitor incompatible"); + return FALSE; + } + } + + if (meta_monitor_transform_is_rotated (logical_monitor_config->transform)) + { + width = mode_height; + height = mode_width; + } + else + { + width = mode_width; + height = mode_height; + } + + switch (layout_mode) + { + case META_LOGICAL_MONITOR_LAYOUT_MODE_GLOBAL_UI_LOGICAL: + width *= ceilf (max_scale); + height *= ceilf (max_scale); + /* fall through! */ + case META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL: + width = roundf (width / logical_monitor_config->scale); + height = roundf (height / logical_monitor_config->scale); + break; + case META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL: + break; + } + + logical_monitor_config->layout.width = width; + logical_monitor_config->layout.height = height; + + return TRUE; +} + +static void +finish_monitor_spec (ConfigParser *parser) +{ + switch (parser->monitor_spec_parent_state) + { + case STATE_MONITOR: + { + parser->current_monitor_config->monitor_spec = + parser->current_monitor_spec; + parser->current_monitor_spec = NULL; + + return; + } + case STATE_DISABLED: + { + parser->current_disabled_monitor_specs = + g_list_prepend (parser->current_disabled_monitor_specs, + parser->current_monitor_spec); + parser->current_monitor_spec = NULL; + + return; + } + + default: + g_assert_not_reached (); + } +} + +static void +handle_end_element (GMarkupParseContext *context, + const char *element_name, + gpointer user_data, + GError **error) +{ + ConfigParser *parser = user_data; + + switch (parser->state) + { + case STATE_LOGICAL_MONITOR_X: + case STATE_LOGICAL_MONITOR_Y: + case STATE_LOGICAL_MONITOR_SCALE: + case STATE_LOGICAL_MONITOR_PRIMARY: + case STATE_LOGICAL_MONITOR_PRESENTATION: + { + parser->state = STATE_LOGICAL_MONITOR; + return; + } + + case STATE_TRANSFORM: + { + g_assert (g_str_equal (element_name, "transform")); + + parser->current_logical_monitor_config->transform = + parser->current_transform; + if (parser->current_transform_flipped) + { + parser->current_logical_monitor_config->transform += + META_MONITOR_TRANSFORM_FLIPPED; + } + + parser->current_transform = META_MONITOR_TRANSFORM_NORMAL; + parser->current_transform_flipped = FALSE; + + parser->state = STATE_LOGICAL_MONITOR; + return; + } + + case STATE_TRANSFORM_ROTATION: + case STATE_TRANSFORM_FLIPPED: + { + parser->state = STATE_TRANSFORM; + return; + } + + case STATE_MONITOR_SPEC_CONNECTOR: + case STATE_MONITOR_SPEC_VENDOR: + case STATE_MONITOR_SPEC_PRODUCT: + case STATE_MONITOR_SPEC_SERIAL: + { + parser->state = STATE_MONITOR_SPEC; + return; + } + + case STATE_MONITOR_SPEC: + { + g_assert (g_str_equal (element_name, "monitorspec")); + + if (!meta_verify_monitor_spec (parser->current_monitor_spec, error)) + return; + + finish_monitor_spec (parser); + + parser->state = parser->monitor_spec_parent_state; + return; + } + + case STATE_MONITOR_MODE_WIDTH: + case STATE_MONITOR_MODE_HEIGHT: + case STATE_MONITOR_MODE_RATE: + case STATE_MONITOR_MODE_FLAG: + { + parser->state = STATE_MONITOR_MODE; + return; + } + + case STATE_MONITOR_MODE: + { + g_assert (g_str_equal (element_name, "mode")); + + if (!meta_verify_monitor_mode_spec (parser->current_monitor_mode_spec, + error)) + return; + + parser->current_monitor_config->mode_spec = + parser->current_monitor_mode_spec; + parser->current_monitor_mode_spec = NULL; + + parser->state = STATE_MONITOR; + return; + } + + case STATE_MONITOR_UNDERSCANNING: + { + g_assert (g_str_equal (element_name, "underscanning")); + + parser->state = STATE_MONITOR; + return; + } + + case STATE_MONITOR: + { + MetaLogicalMonitorConfig *logical_monitor_config; + + g_assert (g_str_equal (element_name, "monitor")); + + if (!meta_verify_monitor_config (parser->current_monitor_config, error)) + return; + + logical_monitor_config = parser->current_logical_monitor_config; + + logical_monitor_config->monitor_configs = + g_list_append (logical_monitor_config->monitor_configs, + parser->current_monitor_config); + parser->current_monitor_config = NULL; + + parser->state = STATE_LOGICAL_MONITOR; + return; + } + + case STATE_LOGICAL_MONITOR: + { + MetaLogicalMonitorConfig *logical_monitor_config = + parser->current_logical_monitor_config; + + g_assert (g_str_equal (element_name, "logicalmonitor")); + + if (parser->current_was_migrated) + logical_monitor_config->scale = -1; + else if (logical_monitor_config->scale == 0) + logical_monitor_config->scale = 1; + + parser->current_logical_monitor_configs = + g_list_append (parser->current_logical_monitor_configs, + logical_monitor_config); + parser->current_logical_monitor_config = NULL; + + parser->state = STATE_CONFIGURATION; + return; + } + + case STATE_MIGRATED: + { + g_assert (g_str_equal (element_name, "migrated")); + + parser->state = STATE_CONFIGURATION; + return; + } + + case STATE_DISABLED: + { + g_assert (g_str_equal (element_name, "disabled")); + + parser->state = STATE_CONFIGURATION; + return; + } + + case STATE_CONFIGURATION: + { + MetaMonitorConfigStore *store = parser->config_store; + MetaMonitorsConfig *config; + GList *l; + MetaLogicalMonitorLayoutMode layout_mode; + MetaMonitorsConfigFlag config_flags = META_MONITORS_CONFIG_FLAG_NONE; + float max_scale = 1.0f; + + g_assert (g_str_equal (element_name, "configuration")); + + if (parser->current_was_migrated) + layout_mode = META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL; + else + layout_mode = + meta_monitor_manager_get_default_layout_mode (store->monitor_manager); + + if (layout_mode == META_LOGICAL_MONITOR_LAYOUT_MODE_GLOBAL_UI_LOGICAL) + { + for (l = parser->current_logical_monitor_configs; l; l = l->next) + { + MetaLogicalMonitorConfig *logical_monitor_config = l->data; + max_scale = MAX (max_scale, logical_monitor_config->scale); + } + } + + for (l = parser->current_logical_monitor_configs; l; l = l->next) + { + MetaLogicalMonitorConfig *logical_monitor_config = l->data; + + if (!derive_logical_monitor_layout (logical_monitor_config, + layout_mode, + max_scale, + error)) + return; + + if (!meta_verify_logical_monitor_config (logical_monitor_config, + layout_mode, + store->monitor_manager, + max_scale, + error)) + return; + } + + if (parser->current_was_migrated) + config_flags |= META_MONITORS_CONFIG_FLAG_MIGRATED; + + config_flags |= parser->extra_config_flags; + + config = + meta_monitors_config_new_full (parser->current_logical_monitor_configs, + parser->current_disabled_monitor_specs, + layout_mode, + config_flags); + + parser->current_logical_monitor_configs = NULL; + parser->current_disabled_monitor_specs = NULL; + + if (!meta_verify_monitors_config (config, store->monitor_manager, + error)) + { + g_object_unref (config); + return; + } + + g_hash_table_replace (parser->config_store->configs, + config->key, config); + + parser->state = STATE_MONITORS; + return; + } + + case STATE_MONITORS: + { + g_assert (g_str_equal (element_name, "monitors")); + + parser->state = STATE_INITIAL; + return; + } + + case STATE_INITIAL: + { + g_assert_not_reached (); + } + } +} + +static gboolean +read_int (const char *text, + gsize text_len, + gint *out_value, + GError **error) +{ + char buf[64]; + int64_t value; + char *end; + + strncpy (buf, text, text_len); + buf[MIN (63, text_len)] = 0; + + value = g_ascii_strtoll (buf, &end, 10); + + if (*end || value < 0 || value > G_MAXINT16) + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + "Expected a number, got %s", buf); + return FALSE; + } + else + { + *out_value = value; + return TRUE; + } +} + +static gboolean +read_float (const char *text, + gsize text_len, + float *out_value, + GError **error) +{ + char buf[64]; + float value; + char *end; + + strncpy (buf, text, text_len); + buf[MIN (63, text_len)] = 0; + + value = g_ascii_strtod (buf, &end); + + if (*end) + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + "Expected a number, got %s", buf); + return FALSE; + } + else + { + *out_value = value; + return TRUE; + } +} + +static gboolean +read_bool (const char *text, + gsize text_len, + gboolean *out_value, + GError **error) +{ + if (strncmp (text, "no", text_len) == 0) + { + *out_value = FALSE; + return TRUE; + } + else if (strncmp (text, "yes", text_len) == 0) + { + *out_value = TRUE; + return TRUE; + } + else + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + "Invalid boolean value '%.*s'", (int) text_len, text); + return FALSE; + } +} + +static gboolean +is_all_whitespace (const char *text, + gsize text_len) +{ + gsize i; + + for (i = 0; i < text_len; i++) + if (!g_ascii_isspace (text[i])) + return FALSE; + + return TRUE; +} + +static void +handle_text (GMarkupParseContext *context, + const gchar *text, + gsize text_len, + gpointer user_data, + GError **error) +{ + ConfigParser *parser = user_data; + + switch (parser->state) + { + case STATE_INITIAL: + case STATE_MONITORS: + case STATE_CONFIGURATION: + case STATE_MIGRATED: + case STATE_LOGICAL_MONITOR: + case STATE_MONITOR: + case STATE_MONITOR_SPEC: + case STATE_MONITOR_MODE: + case STATE_TRANSFORM: + case STATE_DISABLED: + { + if (!is_all_whitespace (text, text_len)) + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + "Unexpected content at this point"); + return; + } + + case STATE_MONITOR_SPEC_CONNECTOR: + { + parser->current_monitor_spec->connector = g_strndup (text, text_len); + return; + } + + case STATE_MONITOR_SPEC_VENDOR: + { + parser->current_monitor_spec->vendor = g_strndup (text, text_len); + return; + } + + case STATE_MONITOR_SPEC_PRODUCT: + { + parser->current_monitor_spec->product = g_strndup (text, text_len); + return; + } + + case STATE_MONITOR_SPEC_SERIAL: + { + parser->current_monitor_spec->serial = g_strndup (text, text_len); + return; + } + + case STATE_LOGICAL_MONITOR_X: + { + read_int (text, text_len, + &parser->current_logical_monitor_config->layout.x, error); + return; + } + + case STATE_LOGICAL_MONITOR_Y: + { + read_int (text, text_len, + &parser->current_logical_monitor_config->layout.y, error); + return; + } + + case STATE_LOGICAL_MONITOR_SCALE: + { + if (!read_float (text, text_len, + &parser->current_logical_monitor_config->scale, error)) + return; + + if (parser->current_logical_monitor_config->scale <= 0.0) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Logical monitor scale '%g' invalid", + parser->current_logical_monitor_config->scale); + return; + } + + return; + } + + case STATE_LOGICAL_MONITOR_PRIMARY: + { + read_bool (text, text_len, + &parser->current_logical_monitor_config->is_primary, + error); + return; + } + + case STATE_LOGICAL_MONITOR_PRESENTATION: + { + read_bool (text, text_len, + &parser->current_logical_monitor_config->is_presentation, + error); + return; + } + + case STATE_TRANSFORM_ROTATION: + { + if (strncmp (text, "normal", text_len) == 0) + parser->current_transform = META_MONITOR_TRANSFORM_NORMAL; + else if (strncmp (text, "left", text_len) == 0) + parser->current_transform = META_MONITOR_TRANSFORM_90; + else if (strncmp (text, "upside_down", text_len) == 0) + parser->current_transform = META_MONITOR_TRANSFORM_180; + else if (strncmp (text, "right", text_len) == 0) + parser->current_transform = META_MONITOR_TRANSFORM_270; + else + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + "Invalid rotation type %.*s", (int)text_len, text); + + return; + } + + case STATE_TRANSFORM_FLIPPED: + { + read_bool (text, text_len, + &parser->current_transform_flipped, + error); + return; + } + + case STATE_MONITOR_MODE_WIDTH: + { + read_int (text, text_len, + &parser->current_monitor_mode_spec->width, + error); + return; + } + + case STATE_MONITOR_MODE_HEIGHT: + { + read_int (text, text_len, + &parser->current_monitor_mode_spec->height, + error); + return; + } + + case STATE_MONITOR_MODE_RATE: + { + read_float (text, text_len, + &parser->current_monitor_mode_spec->refresh_rate, + error); + return; + } + + case STATE_MONITOR_MODE_FLAG: + { + if (strncmp (text, "interlace", text_len) == 0) + { + parser->current_monitor_mode_spec->flags |= + META_CRTC_MODE_FLAG_INTERLACE; + } + else + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + "Invalid mode flag %.*s", (int) text_len, text); + } + + return; + } + + case STATE_MONITOR_UNDERSCANNING: + { + read_bool (text, text_len, + &parser->current_monitor_config->enable_underscanning, + error); + return; + } + } +} + +static const GMarkupParser config_parser = { + .start_element = handle_start_element, + .end_element = handle_end_element, + .text = handle_text +}; + +static gboolean +read_config_file (MetaMonitorConfigStore *config_store, + GFile *file, + MetaMonitorsConfigFlag extra_config_flags, + GError **error) +{ + char *buffer; + gsize size; + ConfigParser parser; + GMarkupParseContext *parse_context; + + if (!g_file_load_contents (file, NULL, &buffer, &size, NULL, error)) + return FALSE; + + parser = (ConfigParser) { + .state = STATE_INITIAL, + .config_store = config_store, + .extra_config_flags = extra_config_flags, + }; + + parse_context = g_markup_parse_context_new (&config_parser, + G_MARKUP_TREAT_CDATA_AS_TEXT | + G_MARKUP_PREFIX_ERROR_POSITION, + &parser, NULL); + if (!g_markup_parse_context_parse (parse_context, buffer, size, error)) + { + g_list_free_full (parser.current_logical_monitor_configs, + (GDestroyNotify) meta_logical_monitor_config_free); + g_clear_pointer (&parser.current_monitor_spec, + meta_monitor_spec_free); + g_free (parser.current_monitor_mode_spec); + g_clear_pointer (&parser.current_monitor_config, + meta_monitor_config_free); + g_clear_pointer (&parser.current_logical_monitor_config, + meta_logical_monitor_config_free); + return FALSE; + } + + g_markup_parse_context_free (parse_context); + g_free (buffer); + + return TRUE; +} + +MetaMonitorsConfig * +meta_monitor_config_store_lookup (MetaMonitorConfigStore *config_store, + MetaMonitorsConfigKey *key) +{ + return META_MONITORS_CONFIG (g_hash_table_lookup (config_store->configs, + key)); +} + +static void +append_monitor_spec (GString *buffer, + MetaMonitorSpec *monitor_spec, + const char *indentation) +{ + g_string_append_printf (buffer, "%s<monitorspec>\n", indentation); + g_string_append_printf (buffer, "%s <connector>%s</connector>\n", + indentation, + monitor_spec->connector); + g_string_append_printf (buffer, "%s <vendor>%s</vendor>\n", + indentation, + monitor_spec->vendor); + g_string_append_printf (buffer, "%s <product>%s</product>\n", + indentation, + monitor_spec->product); + g_string_append_printf (buffer, "%s <serial>%s</serial>\n", + indentation, + monitor_spec->serial); + g_string_append_printf (buffer, "%s</monitorspec>\n", indentation); +} + +static void +append_monitors (GString *buffer, + GList *monitor_configs) +{ + GList *l; + + for (l = monitor_configs; l; l = l->next) + { + MetaMonitorConfig *monitor_config = l->data; + char rate_str[G_ASCII_DTOSTR_BUF_SIZE]; + + g_ascii_dtostr (rate_str, sizeof (rate_str), + monitor_config->mode_spec->refresh_rate); + + g_string_append (buffer, " <monitor>\n"); + append_monitor_spec (buffer, monitor_config->monitor_spec, " "); + g_string_append (buffer, " <mode>\n"); + g_string_append_printf (buffer, " <width>%d</width>\n", + monitor_config->mode_spec->width); + g_string_append_printf (buffer, " <height>%d</height>\n", + monitor_config->mode_spec->height); + g_string_append_printf (buffer, " <rate>%s</rate>\n", + rate_str); + if (monitor_config->mode_spec->flags & META_CRTC_MODE_FLAG_INTERLACE) + g_string_append_printf (buffer, " <flag>interlace</flag>\n"); + g_string_append (buffer, " </mode>\n"); + if (monitor_config->enable_underscanning) + g_string_append (buffer, " <underscanning>yes</underscanning>\n"); + g_string_append (buffer, " </monitor>\n"); + } +} + +static const char * +bool_to_string (gboolean value) +{ + return value ? "yes" : "no"; +} + +static void +append_transform (GString *buffer, + MetaMonitorTransform transform) +{ + const char *rotation = NULL; + gboolean flipped = FALSE; + + switch (transform) + { + case META_MONITOR_TRANSFORM_NORMAL: + return; + case META_MONITOR_TRANSFORM_90: + rotation = "left"; + break; + case META_MONITOR_TRANSFORM_180: + rotation = "upside_down"; + break; + case META_MONITOR_TRANSFORM_270: + rotation = "right"; + break; + case META_MONITOR_TRANSFORM_FLIPPED: + rotation = "normal"; + flipped = TRUE; + break; + case META_MONITOR_TRANSFORM_FLIPPED_90: + rotation = "left"; + flipped = TRUE; + break; + case META_MONITOR_TRANSFORM_FLIPPED_180: + rotation = "upside_down"; + flipped = TRUE; + break; + case META_MONITOR_TRANSFORM_FLIPPED_270: + rotation = "right"; + flipped = TRUE; + break; + } + + g_string_append (buffer, " <transform>\n"); + g_string_append_printf (buffer, " <rotation>%s</rotation>\n", + rotation); + g_string_append_printf (buffer, " <flipped>%s</flipped>\n", + bool_to_string (flipped)); + g_string_append (buffer, " </transform>\n"); +} + +static void +append_logical_monitor_xml (GString *buffer, + MetaMonitorsConfig *config, + MetaLogicalMonitorConfig *logical_monitor_config) +{ + char scale_str[G_ASCII_DTOSTR_BUF_SIZE]; + + g_string_append (buffer, " <logicalmonitor>\n"); + g_string_append_printf (buffer, " <x>%d</x>\n", + logical_monitor_config->layout.x); + g_string_append_printf (buffer, " <y>%d</y>\n", + logical_monitor_config->layout.y); + g_ascii_dtostr (scale_str, G_ASCII_DTOSTR_BUF_SIZE, + logical_monitor_config->scale); + if ((config->flags & META_MONITORS_CONFIG_FLAG_MIGRATED) == 0) + g_string_append_printf (buffer, " <scale>%s</scale>\n", + scale_str); + if (logical_monitor_config->is_primary) + g_string_append (buffer, " <primary>yes</primary>\n"); + if (logical_monitor_config->is_presentation) + g_string_append (buffer, " <presentation>yes</presentation>\n"); + append_transform (buffer, logical_monitor_config->transform); + append_monitors (buffer, logical_monitor_config->monitor_configs); + g_string_append (buffer, " </logicalmonitor>\n"); +} + +static GString * +generate_config_xml (MetaMonitorConfigStore *config_store) +{ + GString *buffer; + GHashTableIter iter; + MetaMonitorsConfig *config; + + buffer = g_string_new (""); + g_string_append_printf (buffer, "<monitors version=\"%d\">\n", + MONITORS_CONFIG_XML_FORMAT_VERSION); + + g_hash_table_iter_init (&iter, config_store->configs); + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &config)) + { + GList *l; + + if (config->flags & META_MONITORS_CONFIG_FLAG_SYSTEM_CONFIG) + continue; + + g_string_append (buffer, " <configuration>\n"); + + if (config->flags & META_MONITORS_CONFIG_FLAG_MIGRATED) + g_string_append (buffer, " <migrated/>\n"); + + for (l = config->logical_monitor_configs; l; l = l->next) + { + MetaLogicalMonitorConfig *logical_monitor_config = l->data; + + append_logical_monitor_xml (buffer, config, logical_monitor_config); + } + + if (config->disabled_monitor_specs) + { + g_string_append (buffer, " <disabled>\n"); + for (l = config->disabled_monitor_specs; l; l = l->next) + { + MetaMonitorSpec *monitor_spec = l->data; + + append_monitor_spec (buffer, monitor_spec, " "); + } + g_string_append (buffer, " </disabled>\n"); + } + + g_string_append (buffer, " </configuration>\n"); + } + + g_string_append (buffer, "</monitors>\n"); + + return buffer; +} + +typedef struct _SaveData +{ + MetaMonitorConfigStore *config_store; + GString *buffer; +} SaveData; + +static void +saved_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + SaveData *data = user_data; + GError *error = NULL; + + if (!g_file_replace_contents_finish (G_FILE (object), result, NULL, &error)) + { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + { + g_warning ("Saving monitor configuration failed: %s\n", error->message); + g_clear_object (&data->config_store->save_cancellable); + } + + g_error_free (error); + } + else + { + g_clear_object (&data->config_store->save_cancellable); + } + + g_clear_object (&data->config_store); + g_string_free (data->buffer, TRUE); + g_free (data); +} + +static void +meta_monitor_config_store_save_sync (MetaMonitorConfigStore *config_store) +{ + GError *error = NULL; + GFile *file; + GString *buffer; + + if (config_store->custom_write_file) + file = config_store->custom_write_file; + else + file = config_store->user_file; + + buffer = generate_config_xml (config_store); + + if (!g_file_replace_contents (file, + buffer->str, buffer->len, + NULL, + FALSE, + G_FILE_CREATE_REPLACE_DESTINATION, + NULL, + NULL, + &error)) + { + g_warning ("Saving monitor configuration failed: %s\n", + error->message); + g_error_free (error); + } + + g_string_free (buffer, TRUE); +} + +static void +meta_monitor_config_store_save (MetaMonitorConfigStore *config_store) +{ + GString *buffer; + SaveData *data; + + if (config_store->save_cancellable) + { + g_cancellable_cancel (config_store->save_cancellable); + g_clear_object (&config_store->save_cancellable); + } + + /* + * Custom write file is only ever used by the test suite, and the test suite + * will want to have be able to read back the content immediately, so for + * custom write files, do the content replacement synchronously. + */ + if (config_store->custom_write_file) + { + meta_monitor_config_store_save_sync (config_store); + return; + } + + config_store->save_cancellable = g_cancellable_new (); + + buffer = generate_config_xml (config_store); + + data = g_new0 (SaveData, 1); + *data = (SaveData) { + .config_store = g_object_ref (config_store), + .buffer = buffer + }; + + g_file_replace_contents_async (config_store->user_file, + buffer->str, buffer->len, + NULL, + TRUE, + G_FILE_CREATE_REPLACE_DESTINATION, + config_store->save_cancellable, + saved_cb, data); +} + +static void +maybe_save_configs (MetaMonitorConfigStore *config_store) +{ + /* + * If a custom file is used, it means we are run by the test suite. When this + * is done, avoid replacing the user configuration file with test data, + * except if a custom write file is set as well. + */ + if (!config_store->custom_read_file || config_store->custom_write_file) + meta_monitor_config_store_save (config_store); +} + +static gboolean +is_system_config (MetaMonitorsConfig *config) +{ + return !!(config->flags & META_MONITORS_CONFIG_FLAG_SYSTEM_CONFIG); +} + +void +meta_monitor_config_store_add (MetaMonitorConfigStore *config_store, + MetaMonitorsConfig *config) +{ + g_hash_table_replace (config_store->configs, + config->key, g_object_ref (config)); + + if (!is_system_config (config)) + maybe_save_configs (config_store); +} + +void +meta_monitor_config_store_remove (MetaMonitorConfigStore *config_store, + MetaMonitorsConfig *config) +{ + g_hash_table_remove (config_store->configs, config->key); + + if (!is_system_config (config)) + maybe_save_configs (config_store); +} + +gboolean +meta_monitor_config_store_set_custom (MetaMonitorConfigStore *config_store, + const char *read_path, + const char *write_path, + GError **error) +{ + g_clear_object (&config_store->custom_read_file); + g_clear_object (&config_store->custom_write_file); + g_hash_table_remove_all (config_store->configs); + + config_store->custom_read_file = g_file_new_for_path (read_path); + if (write_path) + config_store->custom_write_file = g_file_new_for_path (write_path); + + return read_config_file (config_store, + config_store->custom_read_file, + META_MONITORS_CONFIG_FLAG_NONE, + error); +} + +int +meta_monitor_config_store_get_config_count (MetaMonitorConfigStore *config_store) +{ + return (int) g_hash_table_size (config_store->configs); +} + +MetaMonitorManager * +meta_monitor_config_store_get_monitor_manager (MetaMonitorConfigStore *config_store) +{ + return config_store->monitor_manager; +} + +MetaMonitorConfigStore * +meta_monitor_config_store_new (MetaMonitorManager *monitor_manager) +{ + return g_object_new (META_TYPE_MONITOR_CONFIG_STORE, + "monitor-manager", monitor_manager, + NULL); +} + +static void +meta_monitor_config_store_constructed (GObject *object) +{ + MetaMonitorConfigStore *config_store = META_MONITOR_CONFIG_STORE (object); + const char * const *system_dirs; + char *user_file_path; + GError *error = NULL; + + for (system_dirs = g_get_system_config_dirs (); + system_dirs && *system_dirs; + system_dirs++) + { + g_autofree char *system_file_path = NULL; + + system_file_path = g_build_filename (*system_dirs, "monitors.xml", NULL); + if (g_file_test (system_file_path, G_FILE_TEST_EXISTS)) + { + g_autoptr (GFile) system_file = NULL; + + system_file = g_file_new_for_path (system_file_path); + if (!read_config_file (config_store, + system_file, + META_MONITORS_CONFIG_FLAG_SYSTEM_CONFIG, + &error)) + { + if (g_error_matches (error, + META_MONITOR_CONFIG_STORE_ERROR, + META_MONITOR_CONFIG_STORE_ERROR_NEEDS_MIGRATION)) + g_warning ("System monitor configuration file (%s) is " + "incompatible; ask your administrator to migrate " + "the system monitor configuation.", + system_file_path); + else + g_warning ("Failed to read monitors config file '%s': %s", + system_file_path, error->message); + g_clear_error (&error); + } + } + } + + user_file_path = g_build_filename (g_get_user_config_dir (), + "monitors.xml", + NULL); + config_store->user_file = g_file_new_for_path (user_file_path); + + if (g_file_test (user_file_path, G_FILE_TEST_EXISTS)) + { + if (!read_config_file (config_store, + config_store->user_file, + META_MONITORS_CONFIG_FLAG_NONE, + &error)) + { + if (error->domain == META_MONITOR_CONFIG_STORE_ERROR && + error->code == META_MONITOR_CONFIG_STORE_ERROR_NEEDS_MIGRATION) + { + g_clear_error (&error); + if (!meta_migrate_old_user_monitors_config (config_store, &error)) + { + g_warning ("Failed to migrate old monitors config file: %s", + error->message); + g_error_free (error); + } + } + else + { + g_warning ("Failed to read monitors config file '%s': %s", + user_file_path, error->message); + g_error_free (error); + } + } + } + + g_free (user_file_path); + + G_OBJECT_CLASS (meta_monitor_config_store_parent_class)->constructed (object); +} + +static void +meta_monitor_config_store_dispose (GObject *object) +{ + MetaMonitorConfigStore *config_store = META_MONITOR_CONFIG_STORE (object); + + if (config_store->save_cancellable) + { + g_cancellable_cancel (config_store->save_cancellable); + g_clear_object (&config_store->save_cancellable); + + meta_monitor_config_store_save_sync (config_store); + } + + g_clear_pointer (&config_store->configs, g_hash_table_destroy); + + g_clear_object (&config_store->user_file); + g_clear_object (&config_store->custom_read_file); + g_clear_object (&config_store->custom_write_file); + + G_OBJECT_CLASS (meta_monitor_config_store_parent_class)->dispose (object); +} + +static void +meta_monitor_config_store_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaMonitorConfigStore *config_store = META_MONITOR_CONFIG_STORE (object); + + switch (prop_id) + { + case PROP_MONITOR_MANAGER: + g_value_set_object (value, &config_store->monitor_manager); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_monitor_config_store_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaMonitorConfigStore *config_store = META_MONITOR_CONFIG_STORE (object); + + switch (prop_id) + { + case PROP_MONITOR_MANAGER: + config_store->monitor_manager = g_value_get_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_monitor_config_store_init (MetaMonitorConfigStore *config_store) +{ + config_store->configs = g_hash_table_new_full (meta_monitors_config_key_hash, + meta_monitors_config_key_equal, + NULL, + g_object_unref); +} + +static void +meta_monitor_config_store_class_init (MetaMonitorConfigStoreClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->constructed = meta_monitor_config_store_constructed; + object_class->dispose = meta_monitor_config_store_dispose; + object_class->get_property = meta_monitor_config_store_get_property; + object_class->set_property = meta_monitor_config_store_set_property; + + obj_props[PROP_MONITOR_MANAGER] = + g_param_spec_object ("monitor-manager", + "MetaMonitorManager", + "MetaMonitorManager", + META_TYPE_MONITOR_MANAGER, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS | + G_PARAM_CONSTRUCT_ONLY); + + g_object_class_install_properties (object_class, PROP_LAST, obj_props); +} diff --git a/src/backends/meta-monitor-config-store.h b/src/backends/meta-monitor-config-store.h new file mode 100644 index 000000000..92c24ecaa --- /dev/null +++ b/src/backends/meta-monitor-config-store.h @@ -0,0 +1,60 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_MONITOR_CONFIG_STORE_H +#define META_MONITOR_CONFIG_STORE_H + +#include <glib-object.h> + +#include "backends/meta-monitor-config-manager.h" + +#define META_TYPE_MONITOR_CONFIG_STORE (meta_monitor_config_store_get_type ()) +G_DECLARE_FINAL_TYPE (MetaMonitorConfigStore, meta_monitor_config_store, + META, MONITOR_CONFIG_STORE, GObject) + +META_EXPORT_TEST +MetaMonitorConfigStore * meta_monitor_config_store_new (MetaMonitorManager *monitor_manager); + +META_EXPORT_TEST +MetaMonitorsConfig * meta_monitor_config_store_lookup (MetaMonitorConfigStore *config_store, + MetaMonitorsConfigKey *key); + +META_EXPORT_TEST +void meta_monitor_config_store_add (MetaMonitorConfigStore *config_store, + MetaMonitorsConfig *config); + +META_EXPORT_TEST +void meta_monitor_config_store_remove (MetaMonitorConfigStore *config_store, + MetaMonitorsConfig *config); + +META_EXPORT_TEST +gboolean meta_monitor_config_store_set_custom (MetaMonitorConfigStore *config_store, + const char *read_path, + const char *write_path, + GError **error); + +META_EXPORT_TEST +int meta_monitor_config_store_get_config_count (MetaMonitorConfigStore *config_store); + +META_EXPORT_TEST +MetaMonitorManager * meta_monitor_config_store_get_monitor_manager (MetaMonitorConfigStore *config_store); + +#endif /* META_MONITOR_CONFIG_STORE_H */ diff --git a/src/backends/meta-monitor-manager-dummy.c b/src/backends/meta-monitor-manager-dummy.c new file mode 100644 index 000000000..fc29b454a --- /dev/null +++ b/src/backends/meta-monitor-manager-dummy.c @@ -0,0 +1,827 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001, 2002 Havoc Pennington + * Copyright (C) 2002, 2003 Red Hat Inc. + * Some ICCCM manager selection code derived from fvwm2, + * Copyright (C) 2001 Dominik Vogt, Matthias Clasen, and fvwm2 team + * Copyright (C) 2003 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * Copyright (C) 2013 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include "backends/meta-monitor-manager-dummy.h" + +#include <stdlib.h> + +#include "backends/meta-backend-private.h" +#include "backends/meta-crtc.h" +#include "backends/meta-monitor.h" +#include "backends/meta-monitor-config-manager.h" +#include "backends/meta-output.h" +#include "meta/util.h" + +#define ALL_TRANSFORMS ((1 << (META_MONITOR_TRANSFORM_FLIPPED_270 + 1)) - 1) + +#define MAX_MONITORS 5 +#define MAX_OUTPUTS (MAX_MONITORS * 2) +#define MAX_CRTCS (MAX_MONITORS * 2) +#define MAX_MODES (MAX_MONITORS * 4) + +struct _MetaMonitorManagerDummy +{ + MetaMonitorManager parent_instance; + + gboolean is_transform_handled; +}; + +struct _MetaMonitorManagerDummyClass +{ + MetaMonitorManagerClass parent_class; +}; + +typedef struct _MetaOutputDummy +{ + float scale; +} MetaOutputDummy; + +G_DEFINE_TYPE (MetaMonitorManagerDummy, meta_monitor_manager_dummy, META_TYPE_MONITOR_MANAGER); + +struct _MetaGpuDummy +{ + MetaGpu parent; +}; + +G_DEFINE_TYPE (MetaGpuDummy, meta_gpu_dummy, META_TYPE_GPU) + +static void +meta_output_dummy_notify_destroy (MetaOutput *output); + +typedef struct _CrtcModeSpec +{ + int width; + int height; + float refresh_rate; +} CrtcModeSpec; +G_DEFINE_AUTOPTR_CLEANUP_FUNC(CrtcModeSpec, g_free); + +static MetaCrtcMode * +create_mode (CrtcModeSpec *spec, + long mode_id) +{ + MetaCrtcMode *mode; + + mode = g_object_new (META_TYPE_CRTC_MODE, NULL); + + mode->mode_id = mode_id; + mode->width = spec->width; + mode->height = spec->height; + mode->refresh_rate = spec->refresh_rate; + + return mode; +} + +static MetaGpu * +get_gpu (MetaMonitorManager *manager) +{ + MetaBackend *backend = meta_monitor_manager_get_backend (manager); + + return META_GPU (meta_backend_get_gpus (backend)->data); +} + +static void +append_monitor (MetaMonitorManager *manager, + GList **modes, + GList **crtcs, + GList **outputs, + float scale) +{ + MetaGpu *gpu = get_gpu (manager); + CrtcModeSpec default_specs[] = { + { + .width = 800, + .height = 600, + .refresh_rate = 60.0 + }, + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0 + }, + { + .width = 1440, + .height = 900, + .refresh_rate = 60.0 + }, + { + .width = 1600, + .height = 920, + .refresh_rate = 60.0 + }, + }; + g_autolist (CrtcModeSpec) mode_specs = NULL; + unsigned int n_mode_specs = 0; + GList *new_modes = NULL; + MetaCrtc *crtc; + MetaOutputDummy *output_dummy; + MetaOutput *output; + unsigned int i; + unsigned int number; + const char *mode_specs_str; + GList *l; + + mode_specs_str = getenv ("MUTTER_DEBUG_DUMMY_MODE_SPECS"); + if (mode_specs_str && *mode_specs_str != '\0') + { + g_auto (GStrv) specs = g_strsplit (mode_specs_str, ":", -1); + for (i = 0; specs[i]; ++i) + { + int width, height; + float refresh_rate = 60.0; + + if (sscanf (specs[i], "%dx%d@%f", + &width, &height, &refresh_rate) == 3 || + sscanf (specs[i], "%dx%d", + &width, &height) == 2) + { + CrtcModeSpec *spec; + + if (width < META_MONITOR_MANAGER_MIN_SCREEN_WIDTH || + height < META_MONITOR_MANAGER_MIN_SCREEN_HEIGHT) + continue; + + spec = g_new0 (CrtcModeSpec, 1); + spec->width = width; + spec->height = height; + spec->refresh_rate = refresh_rate; + mode_specs = g_list_prepend (mode_specs, spec); + } + } + } + else + { + for (i = 0; i < G_N_ELEMENTS (default_specs); i++) + { + CrtcModeSpec *spec; + + spec = g_memdup (&default_specs[i], sizeof (CrtcModeSpec)); + mode_specs = g_list_prepend (mode_specs, spec); + } + } + + for (l = mode_specs; l; l = l->next) + { + CrtcModeSpec *spec = l->data; + long mode_id; + MetaCrtcMode *mode; + + mode_id = g_list_length (*modes) + n_mode_specs + 1; + mode = create_mode (spec, mode_id); + + new_modes = g_list_append (new_modes, mode); + n_mode_specs++; + } + *modes = g_list_concat (*modes, new_modes); + + crtc = g_object_new (META_TYPE_CRTC, NULL); + crtc->crtc_id = g_list_length (*crtcs) + 1; + crtc->all_transforms = ALL_TRANSFORMS; + *crtcs = g_list_append (*crtcs, crtc); + + output = g_object_new (META_TYPE_OUTPUT, NULL); + + output_dummy = g_new0 (MetaOutputDummy, 1); + *output_dummy = (MetaOutputDummy) { + .scale = scale + }; + + number = g_list_length (*outputs) + 1; + + output->gpu = gpu; + output->winsys_id = number; + output->name = g_strdup_printf ("LVDS%d", number); + output->vendor = g_strdup ("MetaProducts Inc."); + output->product = g_strdup ("MetaMonitor"); + output->serial = g_strdup_printf ("0xC0FFEE-%d", number); + output->suggested_x = -1; + output->suggested_y = -1; + output->width_mm = 222; + output->height_mm = 125; + output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN; + output->preferred_mode = g_list_last (*modes)->data; + output->n_possible_clones = 0; + output->backlight = -1; + output->connector_type = META_CONNECTOR_TYPE_LVDS; + output->driver_private = output_dummy; + output->driver_notify = + (GDestroyNotify) meta_output_dummy_notify_destroy; + + output->modes = g_new0 (MetaCrtcMode *, n_mode_specs); + for (l = new_modes, i = 0; l; l = l->next, i++) + { + MetaCrtcMode *mode = l->data; + + output->modes[i] = mode; + } + output->n_modes = n_mode_specs; + output->possible_crtcs = g_new0 (MetaCrtc *, 1); + output->possible_crtcs[0] = g_list_last (*crtcs)->data; + output->n_possible_crtcs = 1; + + *outputs = g_list_append (*outputs, output); +} + +static void +append_tiled_monitor (MetaMonitorManager *manager, + GList **modes, + GList **crtcs, + GList **outputs, + int scale) +{ + MetaGpu *gpu = get_gpu (manager); + CrtcModeSpec mode_specs[] = { + { + .width = 800, + .height = 600, + .refresh_rate = 60.0 + }, + { + .width = 512, + .height = 768, + .refresh_rate = 60.0 + } + }; + unsigned int n_tiles = 2; + GList *new_modes = NULL; + GList *new_crtcs = NULL; + MetaOutput *output; + unsigned int i; + uint32_t tile_group_id; + + for (i = 0; i < G_N_ELEMENTS (mode_specs); i++) + { + long mode_id; + MetaCrtcMode *mode; + + mode_id = g_list_length (*modes) + i + 1; + mode = create_mode (&mode_specs[i], mode_id); + + new_modes = g_list_append (new_modes, mode); + } + *modes = g_list_concat (*modes, new_modes); + + for (i = 0; i < n_tiles; i++) + { + MetaCrtc *crtc; + + crtc = g_object_new (META_TYPE_CRTC, NULL); + crtc->gpu = gpu; + crtc->crtc_id = g_list_length (*crtcs) + i + 1; + crtc->all_transforms = ALL_TRANSFORMS; + new_crtcs = g_list_append (new_crtcs, crtc); + } + *crtcs = g_list_concat (*crtcs, new_crtcs); + + tile_group_id = g_list_length (*outputs) + 1; + for (i = 0; i < n_tiles; i++) + { + MetaOutputDummy *output_dummy; + MetaCrtcMode *preferred_mode; + unsigned int j; + unsigned int number; + GList *l; + + output_dummy = g_new0 (MetaOutputDummy, 1); + *output_dummy = (MetaOutputDummy) { + .scale = scale + }; + + /* Arbitrary ID unique for this output */ + number = g_list_length (*outputs) + 1; + + preferred_mode = g_list_last (*modes)->data; + + output = g_object_new (META_TYPE_OUTPUT, NULL); + + output->gpu = gpu; + output->winsys_id = number; + output->name = g_strdup_printf ("LVDS%d", number); + output->vendor = g_strdup ("MetaProducts Inc."); + output->product = g_strdup ("MetaMonitor"); + output->serial = g_strdup_printf ("0xC0FFEE-%d", number); + output->suggested_x = -1; + output->suggested_y = -1; + output->width_mm = 222; + output->height_mm = 125; + output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN; + output->preferred_mode = preferred_mode; + output->n_possible_clones = 0; + output->backlight = -1; + output->connector_type = META_CONNECTOR_TYPE_LVDS; + output->tile_info = (MetaTileInfo) { + .group_id = tile_group_id, + .max_h_tiles = n_tiles, + .max_v_tiles = 1, + .loc_h_tile = i, + .loc_v_tile = 0, + .tile_w = preferred_mode->width, + .tile_h = preferred_mode->height + }, + output->driver_private = output_dummy; + output->driver_notify = + (GDestroyNotify) meta_output_dummy_notify_destroy; + + output->modes = g_new0 (MetaCrtcMode *, G_N_ELEMENTS (mode_specs)); + for (l = new_modes, j = 0; l; l = l->next, j++) + { + MetaCrtcMode *mode = l->data; + + output->modes[j] = mode; + } + output->n_modes = G_N_ELEMENTS (mode_specs); + + output->possible_crtcs = g_new0 (MetaCrtc *, n_tiles); + for (l = new_crtcs, j = 0; l; l = l->next, j++) + { + MetaCrtc *crtc = l->data; + + output->possible_crtcs[j] = crtc; + } + output->n_possible_crtcs = n_tiles; + + *outputs = g_list_append (*outputs, output); + } +} + +static void +meta_output_dummy_notify_destroy (MetaOutput *output) +{ + g_clear_pointer (&output->driver_private, g_free); +} + +static gboolean +has_tiled_monitors (void) +{ + const char *tiled_monitors_str; + + tiled_monitors_str = g_getenv ("MUTTER_DEBUG_TILED_DUMMY_MONITORS"); + return g_strcmp0 (tiled_monitors_str, "1") == 0; +} + +static void +meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager) +{ + MetaGpu *gpu = get_gpu (manager); + unsigned int num_monitors = 1; + float *monitor_scales = NULL; + const char *num_monitors_str; + const char *monitor_scales_str; + gboolean tiled_monitors; + unsigned int i; + GList *outputs; + GList *crtcs; + GList *modes; + + /* To control what monitor configuration is generated, there are two available + * environmental variables that can be used: + * + * MUTTER_DEBUG_NUM_DUMMY_MONITORS + * + * Specifies the number of dummy monitors to include in the stage. Every + * monitor is 1024x786 pixels and they are placed on a horizontal row. + * + * MUTTER_DEBUG_DUMMY_MODE_SPECS + * + * A colon separated list of mode specifications that can be used to + * configure the monitor via dbus API. Setting this environment variable + * overrides the default set of modes available. + * Format should be WWxHH:WWxHH@RR + * + * MUTTER_DEBUG_DUMMY_MONITOR_SCALES + * + * A comma separated list that specifies the scales of the dummy monitors. + * + * MUTTER_DEBUG_TILED_DUMMY_MONITORS + * + * If set to "1" the dummy monitors will emulate being tiled, i.e. each have a + * unique tile group id, made up of multiple outputs and CRTCs. + * + * For example the following configuration results in two monitors, where the + * first one has the monitor scale 1, and the other the monitor scale 2. + * + * MUTTER_DEBUG_NUM_DUMMY_MONITORS=2 + * MUTTER_DEBUG_DUMMY_MONITOR_SCALES=1,2 + * MUTTER_DEBUG_TILED_DUMMY_MONITORS=1 + */ + num_monitors_str = getenv ("MUTTER_DEBUG_NUM_DUMMY_MONITORS"); + if (num_monitors_str) + { + num_monitors = g_ascii_strtoll (num_monitors_str, NULL, 10); + if (num_monitors <= 0) + { + meta_warning ("Invalid number of dummy monitors"); + num_monitors = 1; + } + + if (num_monitors > MAX_MONITORS) + { + meta_warning ("Clamping monitor count to max (%d)", + MAX_MONITORS); + num_monitors = MAX_MONITORS; + } + } + + monitor_scales = g_newa (typeof (*monitor_scales), num_monitors); + for (i = 0; i < num_monitors; i++) + monitor_scales[i] = 1.0; + + monitor_scales_str = getenv ("MUTTER_DEBUG_DUMMY_MONITOR_SCALES"); + if (monitor_scales_str) + { + gchar **scales_str_list; + + scales_str_list = g_strsplit (monitor_scales_str, ",", -1); + if (g_strv_length (scales_str_list) != num_monitors) + meta_warning ("Number of specified monitor scales differ from number " + "of monitors (defaults to 1).\n"); + for (i = 0; i < num_monitors && scales_str_list[i]; i++) + { + float scale = g_ascii_strtod (scales_str_list[i], NULL); + + monitor_scales[i] = scale; + } + g_strfreev (scales_str_list); + } + + tiled_monitors = has_tiled_monitors (); + + modes = NULL; + crtcs = NULL; + outputs = NULL; + + for (i = 0; i < num_monitors; i++) + { + if (tiled_monitors) + append_tiled_monitor (manager, + &modes, &crtcs, &outputs, monitor_scales[i]); + else + append_monitor (manager, &modes, &crtcs, &outputs, monitor_scales[i]); + } + + meta_gpu_take_modes (gpu, modes); + meta_gpu_take_crtcs (gpu, crtcs); + meta_gpu_take_outputs (gpu, outputs); +} + +static void +meta_monitor_manager_dummy_ensure_initial_config (MetaMonitorManager *manager) +{ + MetaMonitorsConfig *config; + + config = meta_monitor_manager_ensure_configured (manager); + + if (meta_is_stage_views_enabled ()) + meta_monitor_manager_update_logical_state (manager, config); + else + meta_monitor_manager_update_logical_state_derived (manager, NULL); +} + +static void +apply_crtc_assignments (MetaMonitorManager *manager, + MetaCrtcInfo **crtcs, + unsigned int n_crtcs, + MetaOutputInfo **outputs, + unsigned int n_outputs) +{ + GList *l; + unsigned i; + + for (i = 0; i < n_crtcs; i++) + { + MetaCrtcInfo *crtc_info = crtcs[i]; + MetaCrtc *crtc = crtc_info->crtc; + crtc->is_dirty = TRUE; + + if (crtc_info->mode == NULL) + { + meta_crtc_unset_config (crtc); + } + else + { + MetaOutput *output; + unsigned int j; + + meta_crtc_set_config (crtc, + &crtc_info->layout, + crtc_info->mode, + crtc_info->transform); + + for (j = 0; j < crtc_info->outputs->len; j++) + { + output = ((MetaOutput**)crtc_info->outputs->pdata)[j]; + + output->is_dirty = TRUE; + meta_output_assign_crtc (output, crtc); + } + } + } + + for (i = 0; i < n_outputs; i++) + { + MetaOutputInfo *output_info = outputs[i]; + MetaOutput *output = output_info->output; + + output->is_primary = output_info->is_primary; + output->is_presentation = output_info->is_presentation; + } + + /* Disable CRTCs not mentioned in the list */ + for (l = meta_gpu_get_crtcs (get_gpu (manager)); l; l = l->next) + { + MetaCrtc *crtc = l->data; + + if (crtc->is_dirty) + { + crtc->is_dirty = FALSE; + continue; + } + + meta_crtc_unset_config (crtc); + } + + /* Disable outputs not mentioned in the list */ + for (l = meta_gpu_get_outputs (get_gpu (manager)); l; l = l->next) + { + MetaOutput *output = l->data; + + if (output->is_dirty) + { + output->is_dirty = FALSE; + continue; + } + + meta_output_unassign_crtc (output); + output->is_primary = FALSE; + } +} + +static void +update_screen_size (MetaMonitorManager *manager, + MetaMonitorsConfig *config) +{ + GList *l; + int screen_width = 0; + int screen_height = 0; + + for (l = config->logical_monitor_configs; l; l = l->next) + { + MetaLogicalMonitorConfig *logical_monitor_config = l->data; + int right_edge; + int bottom_edge; + + right_edge = (logical_monitor_config->layout.width + + logical_monitor_config->layout.x); + if (right_edge > screen_width) + screen_width = right_edge; + + bottom_edge = (logical_monitor_config->layout.height + + logical_monitor_config->layout.y); + if (bottom_edge > screen_height) + screen_height = bottom_edge; + } + + manager->screen_width = screen_width; + manager->screen_height = screen_height; +} + +static gboolean +meta_monitor_manager_dummy_apply_monitors_config (MetaMonitorManager *manager, + MetaMonitorsConfig *config, + MetaMonitorsConfigMethod method, + GError **error) +{ + GPtrArray *crtc_infos; + GPtrArray *output_infos; + + if (!config) + { + manager->screen_width = META_MONITOR_MANAGER_MIN_SCREEN_WIDTH; + manager->screen_height = META_MONITOR_MANAGER_MIN_SCREEN_HEIGHT; + + meta_monitor_manager_rebuild (manager, NULL); + return TRUE; + } + + if (!meta_monitor_config_manager_assign (manager, config, + &crtc_infos, &output_infos, + error)) + return FALSE; + + if (method == META_MONITORS_CONFIG_METHOD_VERIFY) + { + g_ptr_array_free (crtc_infos, TRUE); + g_ptr_array_free (output_infos, TRUE); + return TRUE; + } + + apply_crtc_assignments (manager, + (MetaCrtcInfo **) crtc_infos->pdata, + crtc_infos->len, + (MetaOutputInfo **) output_infos->pdata, + output_infos->len); + + g_ptr_array_free (crtc_infos, TRUE); + g_ptr_array_free (output_infos, TRUE); + + update_screen_size (manager, config); + meta_monitor_manager_rebuild (manager, config); + + return TRUE; +} + +static gboolean +meta_monitor_manager_dummy_is_transform_handled (MetaMonitorManager *manager, + MetaCrtc *crtc, + MetaMonitorTransform transform) +{ + MetaMonitorManagerDummy *manager_dummy = META_MONITOR_MANAGER_DUMMY (manager); + + return manager_dummy->is_transform_handled; +} + +static float +meta_monitor_manager_dummy_calculate_monitor_mode_scale (MetaMonitorManager *manager, + MetaLogicalMonitorLayoutMode layout_mode, + MetaMonitor *monitor, + MetaMonitorMode *monitor_mode) +{ + MetaOutput *output; + MetaOutputDummy *output_dummy; + + output = meta_monitor_get_main_output (monitor); + output_dummy = output->driver_private; + + return output_dummy->scale; +} + +static float * +meta_monitor_manager_dummy_calculate_supported_scales (MetaMonitorManager *manager, + MetaLogicalMonitorLayoutMode layout_mode, + MetaMonitor *monitor, + MetaMonitorMode *monitor_mode, + int *n_supported_scales) +{ + MetaMonitorScalesConstraint constraints = + META_MONITOR_SCALES_CONSTRAINT_NONE; + + switch (layout_mode) + { + case META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL: + case META_LOGICAL_MONITOR_LAYOUT_MODE_GLOBAL_UI_LOGICAL: + break; + case META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL: + constraints |= META_MONITOR_SCALES_CONSTRAINT_NO_FRAC; + break; + } + + return meta_monitor_calculate_supported_scales (monitor, monitor_mode, + constraints, + n_supported_scales); +} + +static gboolean +is_monitor_framebuffers_scaled (void) +{ + MetaBackend *backend = meta_get_backend (); + MetaSettings *settings = meta_backend_get_settings (backend); + + return meta_settings_is_experimental_feature_enabled ( + settings, + META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER); +} + +static MetaMonitorManagerCapability +meta_monitor_manager_dummy_get_capabilities (MetaMonitorManager *manager) +{ + MetaBackend *backend = meta_get_backend (); + MetaSettings *settings = meta_backend_get_settings (backend); + MetaMonitorManagerCapability capabilities = + META_MONITOR_MANAGER_CAPABILITY_NONE; + + if (has_tiled_monitors ()) + capabilities |= META_MONITOR_MANAGER_CAPABILITY_TILING; + + if (meta_settings_is_experimental_feature_enabled ( + settings, + META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER)) + capabilities |= META_MONITOR_MANAGER_CAPABILITY_LAYOUT_MODE; + + return capabilities; +} + +static gboolean +meta_monitor_manager_dummy_get_max_screen_size (MetaMonitorManager *manager, + int *max_width, + int *max_height) +{ + if (meta_is_stage_views_enabled ()) + return FALSE; + + *max_width = 65535; + *max_height = 65535; + + return TRUE; +} + +static MetaLogicalMonitorLayoutMode +meta_monitor_manager_dummy_get_default_layout_mode (MetaMonitorManager *manager) +{ + if (!meta_is_stage_views_enabled ()) + return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL; + + if (is_monitor_framebuffers_scaled ()) + return META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL; + else + return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL; +} + +static void +meta_monitor_manager_dummy_constructed (GObject *object) +{ + MetaMonitorManagerDummy *manager_dummy = META_MONITOR_MANAGER_DUMMY (object); + const char *nested_offscreen_transform; + GObjectClass *parent_object_class = + G_OBJECT_CLASS (meta_monitor_manager_dummy_parent_class); + + parent_object_class->constructed (object); + + nested_offscreen_transform = + g_getenv ("MUTTER_DEBUG_NESTED_OFFSCREEN_TRANSFORM"); + if (g_strcmp0 (nested_offscreen_transform, "1") == 0) + manager_dummy->is_transform_handled = FALSE; + else + manager_dummy->is_transform_handled = TRUE; +} + +static void +meta_monitor_manager_dummy_class_init (MetaMonitorManagerDummyClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MetaMonitorManagerClass *manager_class = META_MONITOR_MANAGER_CLASS (klass); + + object_class->constructed = meta_monitor_manager_dummy_constructed; + + manager_class->ensure_initial_config = meta_monitor_manager_dummy_ensure_initial_config; + manager_class->apply_monitors_config = meta_monitor_manager_dummy_apply_monitors_config; + manager_class->is_transform_handled = meta_monitor_manager_dummy_is_transform_handled; + manager_class->calculate_monitor_mode_scale = meta_monitor_manager_dummy_calculate_monitor_mode_scale; + manager_class->calculate_supported_scales = meta_monitor_manager_dummy_calculate_supported_scales; + manager_class->get_capabilities = meta_monitor_manager_dummy_get_capabilities; + manager_class->get_max_screen_size = meta_monitor_manager_dummy_get_max_screen_size; + manager_class->get_default_layout_mode = meta_monitor_manager_dummy_get_default_layout_mode; +} + +static void +meta_monitor_manager_dummy_init (MetaMonitorManagerDummy *manager_dummy) +{ +} + +static gboolean +meta_gpu_dummy_read_current (MetaGpu *gpu, + GError **error) +{ + MetaBackend *backend = meta_gpu_get_backend (gpu); + MetaMonitorManager *manager = meta_backend_get_monitor_manager (backend); + + meta_monitor_manager_dummy_read_current (manager); + + return TRUE; +} + +static void +meta_gpu_dummy_init (MetaGpuDummy *gpu_dummy) +{ +} + +static void +meta_gpu_dummy_class_init (MetaGpuDummyClass *klass) +{ + MetaGpuClass *gpu_class = META_GPU_CLASS (klass); + + gpu_class->read_current = meta_gpu_dummy_read_current; +} diff --git a/src/backends/meta-monitor-manager-dummy.h b/src/backends/meta-monitor-manager-dummy.h new file mode 100644 index 000000000..d00cc824c --- /dev/null +++ b/src/backends/meta-monitor-manager-dummy.h @@ -0,0 +1,36 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001 Havoc Pennington + * Copyright (C) 2003 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * Copyright (C) 2013 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef META_MONITOR_MANAGER_DUMMY_H +#define META_MONITOR_MANAGER_DUMMY_H + +#include "backends/meta-gpu.h" +#include "backends/meta-monitor-manager-private.h" + +#define META_TYPE_MONITOR_MANAGER_DUMMY (meta_monitor_manager_dummy_get_type ()) +G_DECLARE_FINAL_TYPE (MetaMonitorManagerDummy, meta_monitor_manager_dummy, + META, MONITOR_MANAGER_DUMMY, MetaMonitorManager) + +#define META_TYPE_GPU_DUMMY (meta_gpu_dummy_get_type ()) +G_DECLARE_FINAL_TYPE (MetaGpuDummy, meta_gpu_dummy, META, GPU_DUMMY, MetaGpu) + +#endif /* META_MONITOR_MANAGER_DUMMY_H */ diff --git a/src/backends/meta-monitor-manager-private.h b/src/backends/meta-monitor-manager-private.h new file mode 100644 index 000000000..f86abe938 --- /dev/null +++ b/src/backends/meta-monitor-manager-private.h @@ -0,0 +1,408 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001 Havoc Pennington + * Copyright (C) 2003 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * Copyright (C) 2013 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef META_MONITOR_MANAGER_PRIVATE_H +#define META_MONITOR_MANAGER_PRIVATE_H + +#include <cogl/cogl.h> +#include <graphene.h> +#include <libcinnamon-desktop/gnome-pnp-ids.h> + +#include "backends/meta-backend-private.h" +#include "backends/meta-cursor.h" +#include "backends/meta-display-config-shared.h" +#include "backends/meta-monitor-transform.h" +#include "core/util-private.h" +#include "meta/display.h" +#include "meta/meta-monitor-manager.h" + +#include "meta-dbus-display-config.h" + +#define META_MONITOR_MANAGER_MIN_SCREEN_WIDTH 640 +#define META_MONITOR_MANAGER_MIN_SCREEN_HEIGHT 480 + +typedef enum _MetaMonitorManagerCapability +{ + META_MONITOR_MANAGER_CAPABILITY_NONE = 0, + META_MONITOR_MANAGER_CAPABILITY_LAYOUT_MODE = (1 << 0), + META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED = (1 << 1), + META_MONITOR_MANAGER_CAPABILITY_TILING = (1 << 2), + META_MONITOR_MANAGER_CAPABILITY_NATIVE_OUTPUT_SCALING = (1 << 3), +} MetaMonitorManagerCapability; + +/* Equivalent to the 'method' enum in org.gnome.Mutter.DisplayConfig */ +typedef enum _MetaMonitorsConfigMethod +{ + META_MONITORS_CONFIG_METHOD_VERIFY = 0, + META_MONITORS_CONFIG_METHOD_TEMPORARY = 1, + META_MONITORS_CONFIG_METHOD_PERSISTENT = 2 +} MetaMonitorsConfigMethod; + +/* Equivalent to the 'layout-mode' enum in org.gnome.Mutter.DisplayConfig */ +typedef enum _MetaLogicalMonitorLayoutMode +{ + META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL = 1, + META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL = 2, + META_LOGICAL_MONITOR_LAYOUT_MODE_GLOBAL_UI_LOGICAL = 3 +} MetaLogicalMonitorLayoutMode; + +/* + * MetaCrtcInfo: + * + * A representation of a CRTC configuration, generated by + * MetaMonitorConfigManager. + */ +struct _MetaCrtcInfo +{ + MetaCrtc *crtc; + MetaCrtcMode *mode; + graphene_rect_t layout; + float scale; + MetaMonitorTransform transform; + GPtrArray *outputs; +}; + +/* + * MetaOutputInfo: + * + * A representation of a connector configuration, generated by + * MetaMonitorConfigManager. + */ +struct _MetaOutputInfo +{ + MetaOutput *output; + gboolean is_primary; + gboolean is_presentation; + gboolean is_underscanning; +}; + +#define META_TYPE_MONITOR_MANAGER (meta_monitor_manager_get_type ()) +#define META_MONITOR_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MONITOR_MANAGER, MetaMonitorManager)) +#define META_MONITOR_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_MONITOR_MANAGER, MetaMonitorManagerClass)) +#define META_IS_MONITOR_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_MONITOR_MANAGER)) +#define META_IS_MONITOR_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_MONITOR_MANAGER)) +#define META_MONITOR_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_MONITOR_MANAGER, MetaMonitorManagerClass)) + +G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaMonitorManager, g_object_unref) + +struct _MetaMonitorManager +{ + GObject parent_instance; + + MetaDBusDisplayConfig *display_config; + + MetaBackend *backend; + + /* XXX: this structure is very badly + packed, but I like the logical organization + of fields */ + + gboolean in_init; + unsigned int serial; + + MetaLogicalMonitorLayoutMode layout_mode; + + int screen_width; + int screen_height; + + GList *monitors; + GList *scale_override_monitors; + + GList *logical_monitors; + MetaLogicalMonitor *primary_logical_monitor; + + int dbus_name_id; + + int persistent_timeout_id; + + MetaMonitorConfigManager *config_manager; + + GnomePnpIds *pnp_ids; + + gulong experimental_features_changed_handler_id; + + MetaMonitorSwitchConfigType current_switch_config; +}; + +/** + * MetaMonitorManagerClass: + * + * @read_edid: Returns the raw Extended Display Identification Data (EDID) + * for the given #MetaOutput object. Use meta_output_parse_edid() to parse + * afterwards. + * + * @ensure_initial_config: Called on setup. Makes sure an initial config + * is loaded. + * + * @apply_monitors_config: Tries to apply the given config using the given + * method. Throws an error if something went wrong. + * + * @update_screen_size_derived: Computes the screen size for derived + * configuration. + * + * @set_power_save_mode: Sets the #MetaPowerSave mode (for all displays). + * + * @change_backlight: Changes the backlight intensity to the given value (in + * percent). + * + * @get_crtc_gamma: Queries and returns the gamma rampQueries and returns the + * gamma ramp. + * + * @set_crtc_gamma: Sets custom display LUT (look up table) for each primary + * color. Each table is indexed by a value that represents input intensity, + * and yields a value that represents output intensity. + * + * @tiled_monitor_added: Should be called by a #MetaMonitor when it is created. + * + * @tiled_monitor_removed: Should be called by a #MetaMonitor when it is + * destroyed. + * + * @is_transform_handled: vfunc for + * meta_monitor_manager_is_transform_handled(). + * @calculate_monitor_mode_scale: vfunc for + * meta_monitor_manager_calculate_monitor_mode_scale(). + * @calculate_supported_scales: vfunc for + * meta_monitor_manager_calculate_supported_scales(). + * @get_capabilities: vfunc for meta_monitor_manager_get_capabilities(). + * @get_max_screen_size: vfunc for meta_monitor_manager_get_max_screen_size(). + * @get_default_layout_mode: vfunc for meta_monitor_manager_get_default_layout_mode(). + * + * The base class for a #MetaMonitorManager. + */ +struct _MetaMonitorManagerClass +{ + MetaDBusDisplayConfigSkeletonClass parent_class; + + GBytes* (*read_edid) (MetaMonitorManager *, + MetaOutput *); + + void (*read_current_state) (MetaMonitorManager *); + + void (*ensure_initial_config) (MetaMonitorManager *); + + gboolean (*apply_monitors_config) (MetaMonitorManager *, + MetaMonitorsConfig *, + MetaMonitorsConfigMethod , + GError **); + + void (*update_screen_size_derived) (MetaMonitorManager *, + MetaMonitorsConfig *); + + void (*set_power_save_mode) (MetaMonitorManager *, + MetaPowerSave); + + void (*change_backlight) (MetaMonitorManager *, + MetaOutput *, + int); + + void (*get_crtc_gamma) (MetaMonitorManager *, + MetaCrtc *, + gsize *, + unsigned short **, + unsigned short **, + unsigned short **); + void (*set_crtc_gamma) (MetaMonitorManager *, + MetaCrtc *, + gsize , + unsigned short *, + unsigned short *, + unsigned short *); + + void (*tiled_monitor_added) (MetaMonitorManager *, + MetaMonitor *); + + void (*tiled_monitor_removed) (MetaMonitorManager *, + MetaMonitor *); + + gboolean (*is_transform_handled) (MetaMonitorManager *, + MetaCrtc *, + MetaMonitorTransform); + + float (*calculate_monitor_mode_scale) (MetaMonitorManager *, + MetaLogicalMonitorLayoutMode , + MetaMonitor *, + MetaMonitorMode *); + + float * (*calculate_supported_scales) (MetaMonitorManager *, + MetaLogicalMonitorLayoutMode , + MetaMonitor *, + MetaMonitorMode *, + int *); + + MetaMonitorManagerCapability (*get_capabilities) (MetaMonitorManager *); + + gboolean (*get_max_screen_size) (MetaMonitorManager *, + int *, + int *); + + MetaLogicalMonitorLayoutMode (*get_default_layout_mode) (MetaMonitorManager *); +}; + +META_EXPORT_TEST +MetaBackend * meta_monitor_manager_get_backend (MetaMonitorManager *manager); + +void meta_monitor_manager_setup (MetaMonitorManager *manager); + +META_EXPORT_TEST +void meta_monitor_manager_rebuild (MetaMonitorManager *manager, + MetaMonitorsConfig *config); + +META_EXPORT_TEST +void meta_monitor_manager_rebuild_derived (MetaMonitorManager *manager, + MetaMonitorsConfig *config); + +META_EXPORT_TEST +int meta_monitor_manager_get_num_logical_monitors (MetaMonitorManager *manager); + +META_EXPORT_TEST +GList * meta_monitor_manager_get_logical_monitors (MetaMonitorManager *manager); + +MetaLogicalMonitor *meta_monitor_manager_get_logical_monitor_from_number (MetaMonitorManager *manager, + int number); + +MetaLogicalMonitor *meta_monitor_manager_get_primary_logical_monitor (MetaMonitorManager *manager); + +MetaLogicalMonitor *meta_monitor_manager_get_logical_monitor_at (MetaMonitorManager *manager, + float x, + float y); + +MetaLogicalMonitor *meta_monitor_manager_get_logical_monitor_from_rect (MetaMonitorManager *manager, + MetaRectangle *rect); + +MetaLogicalMonitor *meta_monitor_manager_get_logical_monitor_neighbor (MetaMonitorManager *manager, + MetaLogicalMonitor *logical_monitor, + MetaDisplayDirection direction); + +MetaMonitor * meta_monitor_manager_get_primary_monitor (MetaMonitorManager *manager); + +MetaMonitor * meta_monitor_manager_get_laptop_panel (MetaMonitorManager *manager); + +MetaMonitor * meta_monitor_manager_get_monitor_from_spec (MetaMonitorManager *manager, + MetaMonitorSpec *monitor_spec); + +MetaMonitor * meta_monitor_manager_get_monitor_from_connector (MetaMonitorManager *manager, + const char *connector); + +META_EXPORT_TEST +GList * meta_monitor_manager_get_monitors (MetaMonitorManager *manager); + +void meta_monitor_manager_get_screen_size (MetaMonitorManager *manager, + int *width, + int *height); + +MetaPowerSave meta_monitor_manager_get_power_save_mode (MetaMonitorManager *manager); + +void meta_monitor_manager_power_save_mode_changed (MetaMonitorManager *manager, + MetaPowerSave mode); + +void meta_monitor_manager_confirm_configuration (MetaMonitorManager *manager, + gboolean ok); + +void meta_output_parse_edid (MetaOutput *output, + GBytes *edid); +gboolean meta_output_is_laptop (MetaOutput *output); + +gboolean meta_monitor_manager_has_hotplug_mode_update (MetaMonitorManager *manager); + +META_EXPORT_TEST +void meta_monitor_manager_read_current_state (MetaMonitorManager *manager); + +META_EXPORT_TEST +void meta_monitor_manager_on_hotplug (MetaMonitorManager *manager); + +gboolean meta_monitor_manager_get_monitor_matrix (MetaMonitorManager *manager, + MetaMonitor *monitor, + MetaLogicalMonitor *logical_monitor, + gfloat matrix[6]); + +void meta_monitor_manager_tiled_monitor_added (MetaMonitorManager *manager, + MetaMonitor *monitor); +void meta_monitor_manager_tiled_monitor_removed (MetaMonitorManager *manager, + MetaMonitor *monitor); + +gboolean meta_monitor_manager_is_transform_handled (MetaMonitorManager *manager, + MetaCrtc *crtc, + MetaMonitorTransform transform); + +META_EXPORT_TEST +MetaMonitorsConfig * meta_monitor_manager_ensure_configured (MetaMonitorManager *manager); + +META_EXPORT_TEST +void meta_monitor_manager_update_logical_state (MetaMonitorManager *manager, + MetaMonitorsConfig *config); + +META_EXPORT_TEST +void meta_monitor_manager_update_logical_state_derived (MetaMonitorManager *manager, + MetaMonitorsConfig *config); + +META_EXPORT_TEST +void meta_monitor_manager_lid_is_closed_changed (MetaMonitorManager *manager); + +gboolean meta_monitor_manager_is_headless (MetaMonitorManager *manager); + +float meta_monitor_manager_calculate_monitor_mode_scale (MetaMonitorManager *manager, + MetaLogicalMonitorLayoutMode layout_mode, + MetaMonitor *monitor, + MetaMonitorMode *monitor_mode); + +float * meta_monitor_manager_calculate_supported_scales (MetaMonitorManager *, + MetaLogicalMonitorLayoutMode , + MetaMonitor *, + MetaMonitorMode *, + int *); + +gboolean meta_monitor_manager_is_scale_supported (MetaMonitorManager *manager, + MetaLogicalMonitorLayoutMode layout_mode, + MetaMonitor *monitor, + MetaMonitorMode *monitor_mode, + float scale); + +float meta_monitor_manager_get_maximum_crtc_scale (MetaMonitorManager *manager); + +gboolean meta_monitor_manager_disable_scale_for_monitor (MetaMonitorManager *manager, + MetaLogicalMonitor *monitor); + +MetaMonitorManagerCapability + meta_monitor_manager_get_capabilities (MetaMonitorManager *manager); + +gboolean meta_monitor_manager_get_max_screen_size (MetaMonitorManager *manager, + int *max_width, + int *max_height); + +MetaLogicalMonitorLayoutMode + meta_monitor_manager_get_default_layout_mode (MetaMonitorManager *manager); + +MetaMonitorConfigManager * + meta_monitor_manager_get_config_manager (MetaMonitorManager *manager); + +void meta_monitor_manager_rotate_monitor (MetaMonitorManager *manager); + +void meta_monitor_manager_clear_output (MetaOutput *output); +void meta_monitor_manager_clear_mode (MetaCrtcMode *mode); +void meta_monitor_manager_clear_crtc (MetaCrtc *crtc); + +gboolean meta_monitor_has_aspect_as_size (MetaMonitor *monitor); + +char * meta_monitor_manager_get_vendor_name (MetaMonitorManager *manager, + const char *vendor); + +#endif /* META_MONITOR_MANAGER_PRIVATE_H */ diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c new file mode 100644 index 000000000..98ea9def4 --- /dev/null +++ b/src/backends/meta-monitor-manager.c @@ -0,0 +1,3561 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001, 2002 Havoc Pennington + * Copyright (C) 2002, 2003 Red Hat Inc. + * Some ICCCM manager selection code derived from fvwm2, + * Copyright (C) 2001 Dominik Vogt, Matthias Clasen, and fvwm2 team + * Copyright (C) 2003 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * Copyright (C) 2013 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +/** + * SECTION:meta-monitor-manager + * @title: MetaMonitorManager + * @short_description: A manager for multiple monitors + * + * #MetaMonitorManager is an abstract class which contains methods to handle + * multiple monitors (both #MetaMonitor and #MetaLogicalMonitor) and GPU's + * (#MetaGpu). Its functions include reading and/or changing the current + * configuration and available capabiliies. + * + * The #MetaMonitorManager also provides the "org.gnome.Mutter.DisplayConfig" + * DBus service, so apps like GNOME Settings can use this functionality. + */ + +#include "config.h" + +#include "backends/meta-monitor-manager-private.h" + +#include <string.h> +#include <math.h> +#include <stdlib.h> + +#include "backends/edid.h" +#include "backends/meta-backend-private.h" +#include "backends/meta-crtc.h" +#include "backends/meta-logical-monitor.h" +#include "backends/meta-monitor.h" +#include "backends/meta-monitor-config-manager.h" +#include "backends/meta-orientation-manager.h" +#include "backends/meta-output.h" +#include "backends/x11/meta-monitor-manager-xrandr.h" +#include "clutter/clutter.h" +#include "core/main-private.h" +#include "core/util-private.h" +#include "meta/main.h" +#include "meta/meta-x11-errors.h" + +#define DEFAULT_DISPLAY_CONFIGURATION_TIMEOUT 20 + +enum +{ + PROP_0, + + PROP_BACKEND, + + PROP_LAST +}; + +static GParamSpec *obj_props[PROP_LAST]; + +enum +{ + MONITORS_CHANGED, + MONITORS_CHANGED_INTERNAL, + POWER_SAVE_MODE_CHANGED, + CONFIRM_DISPLAY_CHANGE, + SIGNALS_LAST +}; + +/* Array index matches MetaMonitorTransform */ +static gfloat transform_matrices[][6] = { + { 1, 0, 0, 0, 1, 0 }, /* normal */ + { 0, -1, 1, 1, 0, 0 }, /* 90° */ + { -1, 0, 1, 0, -1, 1 }, /* 180° */ + { 0, 1, 0, -1, 0, 1 }, /* 270° */ + { -1, 0, 1, 0, 1, 0 }, /* normal flipped */ + { 0, 1, 0, 1, 0, 0 }, /* 90° flipped */ + { 1, 0, 0, 0, -1, 1 }, /* 180° flipped */ + { 0, -1, 1, -1, 0, 1 }, /* 270° flipped */ +}; + +static int signals[SIGNALS_LAST]; + +typedef struct _MetaMonitorManagerPrivate +{ + MetaPowerSave power_save_mode; +} MetaMonitorManagerPrivate; + +G_DEFINE_TYPE_WITH_PRIVATE (MetaMonitorManager, meta_monitor_manager, + G_TYPE_OBJECT) + +static void initialize_dbus_interface (MetaMonitorManager *manager); +static void monitor_manager_setup_dbus_config_handlers (MetaMonitorManager *manager); + +static gboolean +meta_monitor_manager_is_config_complete (MetaMonitorManager *manager, + MetaMonitorsConfig *config); + +static gboolean +is_global_scale_matching_in_config (MetaMonitorsConfig *config, + float scale); + +static gboolean +meta_monitor_manager_is_scale_supported_with_threshold (MetaMonitorManager *manager, + MetaLogicalMonitorLayoutMode layout_mode, + MetaMonitor *monitor, + MetaMonitorMode *monitor_mode, + float scale, + float threshold, + float *out_scale); + +static void +meta_monitor_manager_real_read_current_state (MetaMonitorManager *manager); + +MetaBackend * +meta_monitor_manager_get_backend (MetaMonitorManager *manager) +{ + return manager->backend; +} + +static void +meta_monitor_manager_init (MetaMonitorManager *manager) +{ +} + +static void +meta_monitor_manager_set_primary_logical_monitor (MetaMonitorManager *manager, + MetaLogicalMonitor *logical_monitor) +{ + manager->primary_logical_monitor = logical_monitor; + if (logical_monitor) + meta_logical_monitor_make_primary (logical_monitor); +} + +static gboolean +is_main_tiled_monitor_output (MetaOutput *output) +{ + return output->tile_info.loc_h_tile == 0 && output->tile_info.loc_v_tile == 0; +} + +static MetaLogicalMonitor * +logical_monitor_from_layout (MetaMonitorManager *manager, + GList *logical_monitors, + MetaRectangle *layout) +{ + GList *l; + + for (l = logical_monitors; l; l = l->next) + { + MetaLogicalMonitor *logical_monitor = l->data; + + if (meta_rectangle_equal (layout, &logical_monitor->rect)) + return logical_monitor; + } + + return NULL; +} + +static void +meta_monitor_manager_rebuild_logical_monitors (MetaMonitorManager *manager, + MetaMonitorsConfig *config) +{ + GList *logical_monitor_configs; + GList *logical_monitors = NULL; + GList *l; + int monitor_number = 0; + MetaLogicalMonitor *primary_logical_monitor = NULL; + + logical_monitor_configs = config ? config->logical_monitor_configs : NULL; + for (l = logical_monitor_configs; l; l = l->next) + { + MetaLogicalMonitorConfig *logical_monitor_config = l->data; + MetaLogicalMonitor *logical_monitor; + + logical_monitor = meta_logical_monitor_new (manager, + logical_monitor_config, + monitor_number); + monitor_number++; + + if (logical_monitor_config->is_primary) + primary_logical_monitor = logical_monitor; + + logical_monitors = g_list_append (logical_monitors, logical_monitor); + } + + /* + * If no monitor was marked as primary, fall back on marking the first + * logical monitor the primary one. + */ + if (!primary_logical_monitor && logical_monitors) + primary_logical_monitor = g_list_first (logical_monitors)->data; + + manager->logical_monitors = logical_monitors; + meta_monitor_manager_set_primary_logical_monitor (manager, + primary_logical_monitor); +} + +float +meta_monitor_manager_get_maximum_crtc_scale (MetaMonitorManager *manager) +{ + GList *l; + float scale; + + scale = 1.0f; + for (l = manager->monitors; l != NULL; l = l->next) + { + MetaMonitor *monitor = l->data; + MetaOutput *output = meta_monitor_get_main_output (monitor); + MetaCrtc *crtc = meta_output_get_assigned_crtc (output); + + if (crtc) + scale = MAX (scale, crtc->scale); + } + + return scale; +} + +static float +derive_configured_global_scale (MetaMonitorManager *manager, + MetaMonitorsConfig *config) +{ + GList *l; + + for (l = config->logical_monitor_configs; l; l = l->next) + { + MetaLogicalMonitorConfig *monitor_config = l->data; + + if (is_global_scale_matching_in_config (config, monitor_config->scale)) + return monitor_config->scale; + } + + return 1.0f; +} + +static float +calculate_monitor_scale (MetaMonitorManager *manager, + MetaMonitor *monitor) +{ + MetaMonitorMode *monitor_mode; + + monitor_mode = meta_monitor_get_current_mode (monitor); + return meta_monitor_manager_calculate_monitor_mode_scale (manager, + manager->layout_mode, + monitor, + monitor_mode); +} + +static gboolean +meta_monitor_manager_is_scale_supported_by_other_monitors (MetaMonitorManager *manager, + MetaMonitor *not_this_one, + float scale) +{ + GList *l; + + for (l = manager->monitors; l; l = l->next) + { + MetaMonitor *monitor = l->data; + MetaMonitorMode *mode; + + if (monitor == not_this_one || !meta_monitor_is_active (monitor)) + continue; + + mode = meta_monitor_get_current_mode (monitor); + if (!meta_monitor_manager_is_scale_supported (manager, manager->layout_mode, + monitor, mode, scale)) + return FALSE; + } + + return TRUE; +} + +static float +derive_calculated_global_scale (MetaMonitorManager *manager) +{ + MetaMonitor *monitor = NULL; + float scale; + GList *l; + + scale = 1.0f; + monitor = meta_monitor_manager_get_primary_monitor (manager); + + if (monitor && meta_monitor_is_active (monitor)) + { + scale = calculate_monitor_scale (manager, monitor); + if (meta_monitor_manager_is_scale_supported_by_other_monitors (manager, + monitor, + scale)) + return scale; + } + + for (l = manager->monitors; l; l = l->next) + { + MetaMonitor *other_monitor = l->data; + float monitor_scale; + + if (other_monitor == monitor || !meta_monitor_is_active (other_monitor)) + continue; + + monitor_scale = calculate_monitor_scale (manager, other_monitor); + if (meta_monitor_manager_is_scale_supported_by_other_monitors (manager, + other_monitor, + monitor_scale)) + scale = MAX (scale, monitor_scale); + } + + return scale; +} + +static float +derive_scale_from_config (MetaMonitorManager *manager, + MetaMonitorsConfig *config, + MetaRectangle *layout) +{ + GList *l; + + for (l = config->logical_monitor_configs; l; l = l->next) + { + MetaLogicalMonitorConfig *logical_monitor_config = l->data; + + if (meta_rectangle_equal (layout, &logical_monitor_config->layout)) + return logical_monitor_config->scale; + } + + g_warning ("Missing logical monitor, using scale 1"); + return 1.0; +} + +static gboolean +derive_scale_from_crtc (MetaMonitorManager *manager, + MetaMonitor *monitor, + float *scale) +{ + MetaMonitorManagerCapability capabilities; + MetaMonitorMode *monitor_mode; + float threshold; + MetaOutput *output; + MetaCrtc *crtc; + + capabilities = meta_monitor_manager_get_capabilities (manager); + + if (!(capabilities & META_MONITOR_MANAGER_CAPABILITY_NATIVE_OUTPUT_SCALING)) + return FALSE; + + if (!(capabilities & META_MONITOR_MANAGER_CAPABILITY_LAYOUT_MODE)) + return FALSE; + + output = meta_monitor_get_main_output (monitor); + crtc = meta_output_get_assigned_crtc (output); + + if (!crtc) + return FALSE; + + /* Due to integer and possibly inverse scaling applied to the output the + * result could not match exactly, so we apply a more relaxed threshold + * in this case. */ + threshold = 0.001f; + + monitor_mode = meta_monitor_get_current_mode (monitor); + if (meta_monitor_manager_is_scale_supported_with_threshold (manager, + manager->layout_mode, + monitor, + monitor_mode, + crtc->scale, + threshold, + scale)) + return TRUE; + + return FALSE; +} + +static void +meta_monitor_manager_rebuild_logical_monitors_derived (MetaMonitorManager *manager, + MetaMonitorsConfig *config) +{ + GList *logical_monitors = NULL; + GList *l; + int monitor_number; + MetaLogicalMonitor *primary_logical_monitor = NULL; + gboolean use_global_scale; + float global_scale = 0.0; + MetaMonitorManagerCapability capabilities; + + monitor_number = 0; + + capabilities = meta_monitor_manager_get_capabilities (manager); + use_global_scale = + !!(capabilities & META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED); + + if (use_global_scale) + { + if (config) + global_scale = derive_configured_global_scale (manager, config); + else + global_scale = derive_calculated_global_scale (manager); + } + + for (l = manager->monitors; l; l = l->next) + { + MetaMonitor *monitor = l->data; + MetaLogicalMonitor *logical_monitor; + MetaRectangle layout; + + if (!meta_monitor_is_active (monitor)) + continue; + + meta_monitor_derive_layout (monitor, &layout); + logical_monitor = logical_monitor_from_layout (manager, logical_monitors, + &layout); + if (logical_monitor) + { + meta_logical_monitor_add_monitor (logical_monitor, monitor); + } + else + { + float scale; + + if (use_global_scale) + scale = roundf (global_scale); + else + { + if (!derive_scale_from_crtc (manager, monitor, &scale)) + { + if (config) + scale = derive_scale_from_config (manager, config, &layout); + else + scale = calculate_monitor_scale (manager, monitor); + } + } + + g_assert (scale > 0); + + logical_monitor = meta_logical_monitor_new_derived (manager, + monitor, + &layout, + scale, + monitor_number); + logical_monitors = g_list_append (logical_monitors, logical_monitor); + monitor_number++; + } + + if (meta_monitor_is_primary (monitor)) + primary_logical_monitor = logical_monitor; + } + + manager->logical_monitors = logical_monitors; + + /* + * If no monitor was marked as primary, fall back on marking the first + * logical monitor the primary one. + */ + if (!primary_logical_monitor && manager->logical_monitors) + primary_logical_monitor = g_list_first (manager->logical_monitors)->data; + + meta_monitor_manager_set_primary_logical_monitor (manager, + primary_logical_monitor); +} + +void +meta_monitor_manager_power_save_mode_changed (MetaMonitorManager *manager, + MetaPowerSave mode) +{ + MetaMonitorManagerPrivate *priv = + meta_monitor_manager_get_instance_private (manager); + + if (priv->power_save_mode == mode) + return; + + priv->power_save_mode = mode; + g_signal_emit (manager, signals[POWER_SAVE_MODE_CHANGED], 0); +} + +static void +power_save_mode_changed (MetaMonitorManager *manager, + GParamSpec *pspec, + gpointer user_data) +{ + MetaMonitorManagerPrivate *priv = + meta_monitor_manager_get_instance_private (manager); + MetaMonitorManagerClass *klass; + int mode = meta_dbus_display_config_get_power_save_mode (manager->display_config); + + if (mode == META_POWER_SAVE_UNSUPPORTED) + return; + + /* If DPMS is unsupported, force the property back. */ + if (priv->power_save_mode == META_POWER_SAVE_UNSUPPORTED) + { + meta_dbus_display_config_set_power_save_mode (manager->display_config, META_POWER_SAVE_UNSUPPORTED); + return; + } + + klass = META_MONITOR_MANAGER_GET_CLASS (manager); + if (klass->set_power_save_mode) + klass->set_power_save_mode (manager, mode); + + meta_monitor_manager_power_save_mode_changed (manager, mode); +} + +void +meta_monitor_manager_lid_is_closed_changed (MetaMonitorManager *manager) +{ + meta_monitor_manager_ensure_configured (manager); +} + +static void +lid_is_closed_changed (MetaBackend *backend, + gboolean lid_is_closed, + gpointer user_data) +{ + MetaMonitorManager *manager = user_data; + meta_monitor_manager_lid_is_closed_changed (manager); +} + +/** + * meta_monitor_manager_is_headless: + * @manager: A #MetaMonitorManager object + * + * Returns whether the monitor manager is headless, i.e. without + * any #MetaLogicalMonitor<!-- -->s attached to it. + * + * Returns: %TRUE if no monitors are attached, %FALSE otherwise. + */ +gboolean +meta_monitor_manager_is_headless (MetaMonitorManager *manager) +{ + return !manager->logical_monitors; +} + +float +meta_monitor_manager_calculate_monitor_mode_scale (MetaMonitorManager *manager, + MetaLogicalMonitorLayoutMode layout_mode, + MetaMonitor *monitor, + MetaMonitorMode *monitor_mode) +{ + float scale; + MetaMonitorManagerClass *manager_class = + META_MONITOR_MANAGER_GET_CLASS (manager); + + scale = manager_class->calculate_monitor_mode_scale (manager, + layout_mode, + monitor, + monitor_mode); + + if (g_list_find (manager->scale_override_monitors, monitor)) + return ceilf (scale); + + return scale; +} + +float * +meta_monitor_manager_calculate_supported_scales (MetaMonitorManager *manager, + MetaLogicalMonitorLayoutMode layout_mode, + MetaMonitor *monitor, + MetaMonitorMode *monitor_mode, + int *n_supported_scales) +{ + MetaMonitorManagerClass *manager_class = + META_MONITOR_MANAGER_GET_CLASS (manager); + + return manager_class->calculate_supported_scales (manager, + layout_mode, + monitor, + monitor_mode, + n_supported_scales); +} + +/** + * meta_monitor_manager_get_capabilities: + * @manager: A #MetaMonitorManager object + * + * Queries the capabilities of the monitor manager. + * + * Returns: #MetaMonitorManagerCapability flags representing the capabilities. + */ +MetaMonitorManagerCapability +meta_monitor_manager_get_capabilities (MetaMonitorManager *manager) +{ + MetaMonitorManagerClass *manager_class = + META_MONITOR_MANAGER_GET_CLASS (manager); + + return manager_class->get_capabilities (manager); +} + +gboolean +meta_monitor_manager_get_max_screen_size (MetaMonitorManager *manager, + int *max_width, + int *max_height) +{ + MetaMonitorManagerClass *manager_class = + META_MONITOR_MANAGER_GET_CLASS (manager); + + return manager_class->get_max_screen_size (manager, max_width, max_height); +} + + +MetaLogicalMonitorLayoutMode +meta_monitor_manager_get_default_layout_mode (MetaMonitorManager *manager) +{ + MetaMonitorManagerClass *manager_class = + META_MONITOR_MANAGER_GET_CLASS (manager); + + return manager_class->get_default_layout_mode (manager); +} + +static void +meta_monitor_manager_ensure_initial_config (MetaMonitorManager *manager) +{ + META_MONITOR_MANAGER_GET_CLASS (manager)->ensure_initial_config (manager); +} + +static gboolean +meta_monitor_manager_apply_monitors_config (MetaMonitorManager *manager, + MetaMonitorsConfig *config, + MetaMonitorsConfigMethod method, + GError **error) +{ + MetaMonitorManagerClass *manager_class = + META_MONITOR_MANAGER_GET_CLASS (manager); + + g_assert (!config || + !(config->flags & META_MONITORS_CONFIG_FLAG_MIGRATED)); + + if (!manager_class->apply_monitors_config (manager, config, method, error)) + return FALSE; + + switch (method) + { + case META_MONITORS_CONFIG_METHOD_TEMPORARY: + case META_MONITORS_CONFIG_METHOD_PERSISTENT: + meta_monitor_config_manager_set_current (manager->config_manager, config); + break; + case META_MONITORS_CONFIG_METHOD_VERIFY: + break; + } + + return TRUE; +} + +gboolean +meta_monitor_manager_has_hotplug_mode_update (MetaMonitorManager *manager) +{ + GList *gpus; + GList *l; + + gpus = meta_backend_get_gpus (manager->backend); + for (l = gpus; l; l = l->next) + { + MetaGpu *gpu = l->data; + + if (meta_gpu_has_hotplug_mode_update (gpu)) + return TRUE; + } + + return FALSE; +} + +static gboolean +should_use_stored_config (MetaMonitorManager *manager) +{ + return (manager->in_init || + (!manager->scale_override_monitors && + !meta_monitor_manager_has_hotplug_mode_update (manager))); +} + +MetaMonitorsConfig * +meta_monitor_manager_ensure_configured (MetaMonitorManager *manager) +{ + MetaMonitorsConfig *config = NULL; + GError *error = NULL; + gboolean use_stored_config; + MetaMonitorsConfigMethod method; + MetaMonitorsConfigMethod fallback_method = + META_MONITORS_CONFIG_METHOD_TEMPORARY; + MetaLogicalMonitorLayoutMode layout_mode = + meta_monitor_manager_get_default_layout_mode (manager); + + use_stored_config = should_use_stored_config (manager); + if (use_stored_config) + method = META_MONITORS_CONFIG_METHOD_PERSISTENT; + else + method = META_MONITORS_CONFIG_METHOD_TEMPORARY; + + if (use_stored_config) + { + g_autoptr(MetaMonitorsConfig) new_config = NULL; + + config = meta_monitor_config_manager_get_stored (manager->config_manager); + if (config && config->layout_mode != layout_mode) + { + new_config = + meta_monitor_config_manager_create_for_layout (manager->config_manager, + config, + layout_mode); + config = new_config; + } + + if (config) + { + if (!meta_monitor_manager_apply_monitors_config (manager, + config, + method, + &error)) + { + config = NULL; + g_warning ("Failed to use stored monitor configuration: %s", + error->message); + g_clear_error (&error); + } + else + { + g_object_ref (config); + goto done; + } + } + } + + config = meta_monitor_config_manager_create_suggested (manager->config_manager); + if (config) + { + if (!meta_monitor_manager_apply_monitors_config (manager, + config, + method, + &error)) + { + g_clear_object (&config); + g_warning ("Failed to use suggested monitor configuration: %s", + error->message); + g_clear_error (&error); + } + else + { + goto done; + } + } + + config = meta_monitor_config_manager_get_previous (manager->config_manager); + if (config) + { + config = g_object_ref (config); + + if (config && config->layout_mode != layout_mode) + { + MetaMonitorsConfig *new_config = + meta_monitor_config_manager_create_for_layout (manager->config_manager, + config, + layout_mode); + g_object_unref (config); + config = new_config; + } + + if (meta_monitor_manager_is_config_complete (manager, config)) + { + if (!meta_monitor_manager_apply_monitors_config (manager, + config, + method, + &error)) + { + g_warning ("Failed to use suggested monitor configuration: %s", + error->message); + g_clear_error (&error); + } + else + { + goto done; + } + } + + g_clear_object (&config); + } + + config = meta_monitor_config_manager_create_linear (manager->config_manager); + if (config) + { + if (!meta_monitor_manager_apply_monitors_config (manager, + config, + method, + &error)) + { + g_clear_object (&config); + g_warning ("Failed to use linear monitor configuration: %s", + error->message); + g_clear_error (&error); + } + else + { + goto done; + } + } + + config = meta_monitor_config_manager_create_fallback (manager->config_manager); + if (config) + { + if (!meta_monitor_manager_apply_monitors_config (manager, + config, + fallback_method, + &error)) + { + g_clear_object (&config); + g_warning ("Failed to use fallback monitor configuration: %s", + error->message); + g_clear_error (&error); + } + else + { + goto done; + } + } + +done: + if (!config) + { + meta_monitor_manager_apply_monitors_config (manager, + NULL, + fallback_method, + &error); + return NULL; + } + + g_object_unref (config); + + return config; +} + +static void +orientation_changed (MetaOrientationManager *orientation_manager, + MetaMonitorManager *manager) +{ + MetaMonitorTransform transform; + GError *error = NULL; + MetaMonitorsConfig *config; + + switch (meta_orientation_manager_get_orientation (orientation_manager)) + { + case META_ORIENTATION_NORMAL: + transform = META_MONITOR_TRANSFORM_NORMAL; + break; + case META_ORIENTATION_BOTTOM_UP: + transform = META_MONITOR_TRANSFORM_180; + break; + case META_ORIENTATION_LEFT_UP: + transform = META_MONITOR_TRANSFORM_90; + break; + case META_ORIENTATION_RIGHT_UP: + transform = META_MONITOR_TRANSFORM_270; + break; + + case META_ORIENTATION_UNDEFINED: + default: + return; + } + + config = + meta_monitor_config_manager_create_for_orientation (manager->config_manager, + transform); + if (!config) + return; + + if (!meta_monitor_manager_apply_monitors_config (manager, + config, + META_MONITORS_CONFIG_METHOD_TEMPORARY, + &error)) + { + g_warning ("Failed to use orientation monitor configuration: %s", + error->message); + g_error_free (error); + } + g_object_unref (config); +} + +static gboolean +apply_x11_fractional_scaling_config (MetaMonitorManager *manager) +{ + g_autoptr(GError) error = NULL; + g_autoptr(MetaMonitorsConfig) config = NULL; + MetaMonitorsConfig *applied_config; + MetaLogicalMonitorLayoutMode layout_mode = + meta_monitor_manager_get_default_layout_mode (manager); + + if (!META_IS_MONITOR_MANAGER_XRANDR (manager)) + return TRUE; + + applied_config = + meta_monitor_config_manager_get_current (manager->config_manager); + config = + meta_monitor_config_manager_create_for_layout (manager->config_manager, + applied_config, + layout_mode); + if (!config) + return FALSE; + + if (meta_monitor_manager_apply_monitors_config (manager, + config, + META_MONITORS_CONFIG_METHOD_PERSISTENT, + &error)) + { + if (config != applied_config && manager->persistent_timeout_id) + { + if (G_UNLIKELY (applied_config != + meta_monitor_config_manager_get_previous (manager->config_manager))) + { + g_warning ("The removed configuration doesn't match the " + "previously applied one, reverting may not work"); + } + else + { + g_autoptr(MetaMonitorsConfig) previous_config = NULL; + + /* The previous config we applied was just a temporary one that + * GNOME control center passed us while toggling the fractional + * scaling. So, in such case, once the configuration with the + * correct layout has been applied, we need to ignore the + * temporary one. */ + previous_config = + meta_monitor_config_manager_pop_previous (manager->config_manager); + + g_assert_true (applied_config == previous_config); + } + } + } + else + { + g_warning ("Impossible to apply the layout config %s\n", + error->message); + return FALSE; + } + + return TRUE; +} + +static void +experimental_features_changed (MetaSettings *settings, + MetaExperimentalFeature old_experimental_features, + MetaMonitorManager *manager) +{ + gboolean was_stage_views_scaled; + gboolean is_stage_views_scaled; + gboolean was_x11_scaling; + gboolean x11_scaling; + gboolean should_reconfigure = FALSE; + + was_stage_views_scaled = + !!(old_experimental_features & + META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER); + is_stage_views_scaled = + meta_settings_is_experimental_feature_enabled ( + settings, + META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER); + was_x11_scaling = + !!(old_experimental_features & + META_EXPERIMENTAL_FEATURE_X11_RANDR_FRACTIONAL_SCALING); + x11_scaling = + meta_settings_is_experimental_feature_enabled ( + settings, + META_EXPERIMENTAL_FEATURE_X11_RANDR_FRACTIONAL_SCALING); + + if (is_stage_views_scaled != was_stage_views_scaled) + should_reconfigure = TRUE; + + if (was_x11_scaling != x11_scaling) + { + if (!apply_x11_fractional_scaling_config (manager)) + should_reconfigure = TRUE; + } + + if (should_reconfigure) + meta_monitor_manager_on_hotplug (manager); + + meta_settings_update_ui_scaling_factor (settings); +} + +void +meta_monitor_manager_setup (MetaMonitorManager *manager) +{ + manager->in_init = TRUE; + + manager->config_manager = meta_monitor_config_manager_new (manager); + + meta_monitor_manager_read_current_state (manager); + + meta_monitor_manager_ensure_initial_config (manager); + + manager->in_init = FALSE; +} + +static void +meta_monitor_manager_constructed (GObject *object) +{ + MetaMonitorManager *manager = META_MONITOR_MANAGER (object); + MetaBackend *backend = manager->backend; + MetaSettings *settings = meta_backend_get_settings (backend); + + manager->display_config = meta_dbus_display_config_skeleton_new (); + + manager->experimental_features_changed_handler_id = + g_signal_connect (settings, + "experimental-features-changed", + G_CALLBACK (experimental_features_changed), + manager); + + monitor_manager_setup_dbus_config_handlers (manager); + + g_signal_connect_object (manager->display_config, "notify::power-save-mode", + G_CALLBACK (power_save_mode_changed), manager, + G_CONNECT_SWAPPED); + + g_signal_connect_object (meta_backend_get_orientation_manager (backend), + "orientation-changed", + G_CALLBACK (orientation_changed), + manager, 0); + + g_signal_connect_object (backend, + "lid-is-closed-changed", + G_CALLBACK (lid_is_closed_changed), + manager, 0); + + manager->current_switch_config = META_MONITOR_SWITCH_CONFIG_UNKNOWN; + + initialize_dbus_interface (manager); +} + +static void +meta_monitor_manager_finalize (GObject *object) +{ + MetaMonitorManager *manager = META_MONITOR_MANAGER (object); + + g_list_free_full (manager->logical_monitors, g_object_unref); + + g_clear_signal_handler (&manager->experimental_features_changed_handler_id, + manager->backend); + + G_OBJECT_CLASS (meta_monitor_manager_parent_class)->finalize (object); +} + +static void +meta_monitor_manager_dispose (GObject *object) +{ + MetaMonitorManager *manager = META_MONITOR_MANAGER (object); + + if (manager->dbus_name_id != 0) + { + g_bus_unown_name (manager->dbus_name_id); + manager->dbus_name_id = 0; + } + + g_clear_object (&manager->display_config); + g_clear_object (&manager->config_manager); + + G_OBJECT_CLASS (meta_monitor_manager_parent_class)->dispose (object); +} + +static GBytes * +meta_monitor_manager_real_read_edid (MetaMonitorManager *manager, + MetaOutput *output) +{ + return NULL; +} + +static void +meta_monitor_manager_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaMonitorManager *manager = META_MONITOR_MANAGER (object); + + switch (prop_id) + { + case PROP_BACKEND: + manager->backend = g_value_get_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_monitor_manager_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaMonitorManager *manager = META_MONITOR_MANAGER (object); + + switch (prop_id) + { + case PROP_BACKEND: + g_value_set_object (value, manager->backend); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_monitor_manager_class_init (MetaMonitorManagerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->constructed = meta_monitor_manager_constructed; + object_class->dispose = meta_monitor_manager_dispose; + object_class->finalize = meta_monitor_manager_finalize; + object_class->get_property = meta_monitor_manager_get_property; + object_class->set_property = meta_monitor_manager_set_property; + + klass->read_edid = meta_monitor_manager_real_read_edid; + klass->read_current_state = meta_monitor_manager_real_read_current_state; + + signals[MONITORS_CHANGED] = + g_signal_new ("monitors-changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); + + signals[MONITORS_CHANGED_INTERNAL] = + g_signal_new ("monitors-changed-internal", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); + + signals[POWER_SAVE_MODE_CHANGED] = + g_signal_new ("power-save-mode-changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); + + signals[CONFIRM_DISPLAY_CHANGE] = + g_signal_new ("confirm-display-change", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); + + obj_props[PROP_BACKEND] = + g_param_spec_object ("backend", + "backend", + "MetaBackend", + META_TYPE_BACKEND, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + g_object_class_install_properties (object_class, PROP_LAST, obj_props); +} + +gboolean +meta_monitor_has_aspect_as_size (MetaMonitor *monitor) +{ + int width_mm; + int height_mm; + + meta_monitor_get_physical_dimensions (monitor, &width_mm, &height_mm); + + return (width_mm == 1600 && height_mm == 900) || + (width_mm == 1600 && height_mm == 1000) || + (width_mm == 160 && height_mm == 90) || + (width_mm == 160 && height_mm == 100) || + (width_mm == 16 && height_mm == 9) || + (width_mm == 16 && height_mm == 10); +} + +static const char * +get_connector_type_name (MetaConnectorType connector_type) +{ + switch (connector_type) + { + case META_CONNECTOR_TYPE_Unknown: return "Unknown"; + case META_CONNECTOR_TYPE_VGA: return "VGA"; + case META_CONNECTOR_TYPE_DVII: return "DVII"; + case META_CONNECTOR_TYPE_DVID: return "DVID"; + case META_CONNECTOR_TYPE_DVIA: return "DVIA"; + case META_CONNECTOR_TYPE_Composite: return "Composite"; + case META_CONNECTOR_TYPE_SVIDEO: return "SVIDEO"; + case META_CONNECTOR_TYPE_LVDS: return "LVDS"; + case META_CONNECTOR_TYPE_Component: return "Component"; + case META_CONNECTOR_TYPE_9PinDIN: return "9PinDIN"; + case META_CONNECTOR_TYPE_DisplayPort: return "DisplayPort"; + case META_CONNECTOR_TYPE_HDMIA: return "HDMIA"; + case META_CONNECTOR_TYPE_HDMIB: return "HDMIB"; + case META_CONNECTOR_TYPE_TV: return "TV"; + case META_CONNECTOR_TYPE_eDP: return "eDP"; + case META_CONNECTOR_TYPE_VIRTUAL: return "VIRTUAL"; + case META_CONNECTOR_TYPE_DSI: return "DSI"; + default: g_assert_not_reached (); + } + return NULL; +} + +static GList * +combine_gpu_lists (MetaMonitorManager *manager, + GList * (*list_getter) (MetaGpu *gpu)) +{ + GList *gpus; + GList *list = NULL; + GList *l; + + gpus = meta_backend_get_gpus (manager->backend); + for (l = gpus; l; l = l->next) + { + MetaGpu *gpu = l->data; + + list = g_list_concat (list, g_list_copy (list_getter (gpu))); + } + + return list; +} + +static gboolean +meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton, + GDBusMethodInvocation *invocation, + MetaMonitorManager *manager) +{ + MetaMonitorManagerClass *manager_class = META_MONITOR_MANAGER_GET_CLASS (manager); + GList *combined_modes; + GList *combined_outputs; + GList *combined_crtcs; + GVariantBuilder crtc_builder, output_builder, mode_builder; + GList *l; + unsigned int i, j; + int max_screen_width; + int max_screen_height; + + combined_modes = combine_gpu_lists (manager, meta_gpu_get_modes); + combined_outputs = combine_gpu_lists (manager, meta_gpu_get_outputs); + combined_crtcs = combine_gpu_lists (manager, meta_gpu_get_crtcs); + + g_variant_builder_init (&crtc_builder, G_VARIANT_TYPE ("a(uxiiiiiuaua{sv})")); + g_variant_builder_init (&output_builder, G_VARIANT_TYPE ("a(uxiausauaua{sv})")); + g_variant_builder_init (&mode_builder, G_VARIANT_TYPE ("a(uxuudu)")); + + for (l = combined_crtcs, i = 0; l; l = l->next, i++) + { + MetaCrtc *crtc = l->data; + GVariantBuilder transforms; + MetaCrtcConfig *crtc_config; + + g_variant_builder_init (&transforms, G_VARIANT_TYPE ("au")); + for (j = 0; j <= META_MONITOR_TRANSFORM_FLIPPED_270; j++) + if (crtc->all_transforms & (1 << j)) + g_variant_builder_add (&transforms, "u", j); + + crtc_config = crtc->config; + + if (crtc_config) + { + int current_mode_index; + + current_mode_index = g_list_index (combined_modes, crtc_config->mode); + g_variant_builder_add (&crtc_builder, "(uxiiiiiuaua{sv})", + i, /* ID */ + (int64_t) crtc->crtc_id, + (int) roundf (crtc_config->layout.origin.x), + (int) roundf (crtc_config->layout.origin.y), + (int) roundf (crtc_config->layout.size.width), + (int) roundf (crtc_config->layout.size.height), + current_mode_index, + (uint32_t) crtc_config->transform, + &transforms, + NULL /* properties */); + } + else + { + g_variant_builder_add (&crtc_builder, "(uxiiiiiuaua{sv})", + i, /* ID */ + (int64_t) crtc->crtc_id, + 0, + 0, + 0, + 0, + -1, + (uint32_t) META_MONITOR_TRANSFORM_NORMAL, + &transforms, + NULL /* properties */); + } + } + + for (l = combined_outputs, i = 0; l; l = l->next, i++) + { + MetaOutput *output = l->data; + GVariantBuilder crtcs, modes, clones, properties; + GBytes *edid; + MetaCrtc *crtc; + int crtc_index; + + g_variant_builder_init (&crtcs, G_VARIANT_TYPE ("au")); + for (j = 0; j < output->n_possible_crtcs; j++) + { + MetaCrtc *possible_crtc = output->possible_crtcs[j]; + unsigned possible_crtc_index; + + possible_crtc_index = g_list_index (combined_crtcs, possible_crtc); + g_variant_builder_add (&crtcs, "u", possible_crtc_index); + } + + g_variant_builder_init (&modes, G_VARIANT_TYPE ("au")); + for (j = 0; j < output->n_modes; j++) + { + unsigned mode_index; + + mode_index = g_list_index (combined_modes, output->modes[j]); + g_variant_builder_add (&modes, "u", mode_index); + } + + g_variant_builder_init (&clones, G_VARIANT_TYPE ("au")); + for (j = 0; j < output->n_possible_clones; j++) + { + unsigned int possible_clone_index; + + possible_clone_index = g_list_index (combined_outputs, + output->possible_clones[j]); + g_variant_builder_add (&clones, "u", possible_clone_index); + } + + g_variant_builder_init (&properties, G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_add (&properties, "{sv}", "vendor", + g_variant_new_string (output->vendor)); + g_variant_builder_add (&properties, "{sv}", "product", + g_variant_new_string (output->product)); + g_variant_builder_add (&properties, "{sv}", "serial", + g_variant_new_string (output->serial)); + g_variant_builder_add (&properties, "{sv}", "width-mm", + g_variant_new_int32 (output->width_mm)); + g_variant_builder_add (&properties, "{sv}", "height-mm", + g_variant_new_int32 (output->height_mm)); + g_variant_builder_add (&properties, "{sv}", "display-name", + g_variant_new_string (output->name)); + g_variant_builder_add (&properties, "{sv}", "backlight", + g_variant_new_int32 (output->backlight)); + g_variant_builder_add (&properties, "{sv}", "min-backlight-step", + g_variant_new_int32 ((output->backlight_max - output->backlight_min) ? + 100 / (output->backlight_max - output->backlight_min) : -1)); + g_variant_builder_add (&properties, "{sv}", "primary", + g_variant_new_boolean (output->is_primary)); + g_variant_builder_add (&properties, "{sv}", "presentation", + g_variant_new_boolean (output->is_presentation)); + g_variant_builder_add (&properties, "{sv}", "connector-type", + g_variant_new_string (get_connector_type_name (output->connector_type))); + g_variant_builder_add (&properties, "{sv}", "underscanning", + g_variant_new_boolean (output->is_underscanning)); + g_variant_builder_add (&properties, "{sv}", "supports-underscanning", + g_variant_new_boolean (output->supports_underscanning)); + + edid = manager_class->read_edid (manager, output); + if (edid) + { + g_variant_builder_add (&properties, "{sv}", "edid", + g_variant_new_from_bytes (G_VARIANT_TYPE ("ay"), + edid, TRUE)); + g_bytes_unref (edid); + } + + if (output->tile_info.group_id) + { + g_variant_builder_add (&properties, "{sv}", "tile", + g_variant_new ("(uuuuuuuu)", + output->tile_info.group_id, + output->tile_info.flags, + output->tile_info.max_h_tiles, + output->tile_info.max_v_tiles, + output->tile_info.loc_h_tile, + output->tile_info.loc_v_tile, + output->tile_info.tile_w, + output->tile_info.tile_h)); + } + + crtc = meta_output_get_assigned_crtc (output); + crtc_index = crtc ? g_list_index (combined_crtcs, crtc) : -1; + g_variant_builder_add (&output_builder, "(uxiausauaua{sv})", + i, /* ID */ + (gint64)output->winsys_id, + crtc_index, + &crtcs, + output->name, + &modes, + &clones, + &properties); + } + + for (l = combined_modes, i = 0; l; l = l->next, i++) + { + MetaCrtcMode *mode = l->data; + + g_variant_builder_add (&mode_builder, "(uxuudu)", + i, /* ID */ + (gint64)mode->mode_id, + (guint32)mode->width, + (guint32)mode->height, + (double)mode->refresh_rate, + (guint32)mode->flags); + } + + if (!meta_monitor_manager_get_max_screen_size (manager, + &max_screen_width, + &max_screen_height)) + { + /* No max screen size, just send something large */ + max_screen_width = 65535; + max_screen_height = 65535; + } + + meta_dbus_display_config_complete_get_resources (skeleton, + invocation, + manager->serial, + g_variant_builder_end (&crtc_builder), + g_variant_builder_end (&output_builder), + g_variant_builder_end (&mode_builder), + max_screen_width, + max_screen_height); + + g_list_free (combined_modes); + g_list_free (combined_outputs); + g_list_free (combined_crtcs); + + return TRUE; +} + +static void +restore_previous_experimental_config (MetaMonitorManager *manager, + MetaMonitorsConfig *previous_config) +{ + MetaBackend *backend = manager->backend; + MetaSettings *settings = meta_backend_get_settings (backend); + gboolean was_fractional; + + if (!META_IS_MONITOR_MANAGER_XRANDR (manager)) + return; + + was_fractional = + previous_config->layout_mode != META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL; + + if (meta_settings_is_experimental_feature_enabled (settings, + META_EXPERIMENTAL_FEATURE_X11_RANDR_FRACTIONAL_SCALING) == was_fractional) + return; + + g_signal_handler_block (settings, + manager->experimental_features_changed_handler_id); + + meta_settings_enable_x11_fractional_scaling (settings, was_fractional); + + g_signal_handler_unblock (settings, + manager->experimental_features_changed_handler_id); +} + +static void +restore_previous_config (MetaMonitorManager *manager) +{ + MetaMonitorsConfig *previous_config; + GError *error = NULL; + + previous_config = + meta_monitor_config_manager_pop_previous (manager->config_manager); + + if (previous_config) + { + MetaMonitorsConfigMethod method; + + restore_previous_experimental_config (manager, previous_config); + + method = META_MONITORS_CONFIG_METHOD_TEMPORARY; + if (meta_monitor_manager_apply_monitors_config (manager, + previous_config, + method, + &error)) + { + g_object_unref (previous_config); + return; + } + else + { + g_object_unref (previous_config); + g_warning ("Failed to restore previous configuration: %s", + error->message); + g_error_free (error); + } + } + + meta_monitor_manager_ensure_configured (manager); +} + +gint +meta_monitor_manager_get_display_configuration_timeout (void) +{ + return DEFAULT_DISPLAY_CONFIGURATION_TIMEOUT; +} + +static gboolean +save_config_timeout (gpointer user_data) +{ + MetaMonitorManager *manager = user_data; + + restore_previous_config (manager); + manager->persistent_timeout_id = 0; + + return G_SOURCE_REMOVE; +} + +static void +cancel_persistent_confirmation (MetaMonitorManager *manager) +{ + g_clear_handle_id (&manager->persistent_timeout_id, g_source_remove); +} + +static void +request_persistent_confirmation (MetaMonitorManager *manager) +{ + manager->persistent_timeout_id = g_timeout_add_seconds (meta_monitor_manager_get_display_configuration_timeout (), + save_config_timeout, + manager); + g_source_set_name_by_id (manager->persistent_timeout_id, + "[mutter] save_config_timeout"); + + g_signal_emit (manager, signals[CONFIRM_DISPLAY_CHANGE], 0); +} + +gboolean +meta_monitor_manager_disable_scale_for_monitor (MetaMonitorManager *manager, + MetaLogicalMonitor *monitor) +{ + switch (manager->layout_mode) + { + case META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL: + case META_LOGICAL_MONITOR_LAYOUT_MODE_GLOBAL_UI_LOGICAL: + break; + default: + return FALSE; + } + + if (monitor && fmodf (monitor->scale, 1.0) != 0.0f) + { + if (manager->scale_override_monitors) + { + g_clear_pointer (&manager->scale_override_monitors, g_list_free); + g_object_unref (meta_monitor_config_manager_pop_previous (manager->config_manager)); + } + + manager->scale_override_monitors = g_list_copy (monitor->monitors); + meta_monitor_manager_ensure_configured (manager); + return TRUE; + } + + if (manager->scale_override_monitors) + { + g_clear_pointer (&manager->scale_override_monitors, g_list_free); + restore_previous_config (manager); + } + + return FALSE; +} + +#define META_DISPLAY_CONFIG_MODE_FLAGS_PREFERRED (1 << 0) +#define META_DISPLAY_CONFIG_MODE_FLAGS_CURRENT (1 << 1) + +#define MODE_FORMAT "(siiddada{sv})" +#define MODES_FORMAT "a" MODE_FORMAT +#define MONITOR_SPEC_FORMAT "(ssss)" +#define MONITOR_FORMAT "(" MONITOR_SPEC_FORMAT MODES_FORMAT "a{sv})" +#define MONITORS_FORMAT "a" MONITOR_FORMAT + +#define LOGICAL_MONITOR_MONITORS_FORMAT "a" MONITOR_SPEC_FORMAT +#define LOGICAL_MONITOR_FORMAT "(iidub" LOGICAL_MONITOR_MONITORS_FORMAT "a{sv})" +#define LOGICAL_MONITORS_FORMAT "a" LOGICAL_MONITOR_FORMAT + +static gboolean +meta_monitor_manager_handle_get_current_state (MetaDBusDisplayConfig *skeleton, + GDBusMethodInvocation *invocation, + MetaMonitorManager *manager) +{ + MetaSettings *settings = meta_backend_get_settings (manager->backend); + GVariantBuilder monitors_builder; + GVariantBuilder logical_monitors_builder; + GVariantBuilder properties_builder; + GList *l; + int i; + MetaMonitorManagerCapability capabilities; + int ui_scaling_factor; + int max_screen_width, max_screen_height; + char *renderer; + + g_variant_builder_init (&monitors_builder, + G_VARIANT_TYPE (MONITORS_FORMAT)); + g_variant_builder_init (&logical_monitors_builder, + G_VARIANT_TYPE (LOGICAL_MONITORS_FORMAT)); + + for (l = manager->monitors; l; l = l->next) + { + MetaMonitor *monitor = l->data; + MetaMonitorSpec *monitor_spec = meta_monitor_get_spec (monitor); + MetaMonitorMode *current_mode; + MetaMonitorMode *preferred_mode; + GVariantBuilder modes_builder; + GVariantBuilder monitor_properties_builder; + GList *k; + gboolean is_builtin; + const char *display_name; + + current_mode = meta_monitor_get_current_mode (monitor); + preferred_mode = meta_monitor_get_preferred_mode (monitor); + + g_variant_builder_init (&modes_builder, G_VARIANT_TYPE (MODES_FORMAT)); + for (k = meta_monitor_get_modes (monitor); k; k = k->next) + { + MetaMonitorMode *monitor_mode = k->data; + GVariantBuilder supported_scales_builder; + const char *mode_id; + int mode_width, mode_height; + float refresh_rate; + float preferred_scale; + float *supported_scales; + int n_supported_scales; + GVariantBuilder mode_properties_builder; + MetaCrtcModeFlag mode_flags; + + if (!meta_monitor_mode_should_be_advertised (monitor_mode)) + continue; + + mode_id = meta_monitor_mode_get_id (monitor_mode); + meta_monitor_mode_get_resolution (monitor_mode, + &mode_width, &mode_height); + + refresh_rate = meta_monitor_mode_get_refresh_rate (monitor_mode); + + preferred_scale = + meta_monitor_manager_calculate_monitor_mode_scale (manager, + manager->layout_mode, + monitor, + monitor_mode); + + g_variant_builder_init (&supported_scales_builder, + G_VARIANT_TYPE ("ad")); + supported_scales = + meta_monitor_manager_calculate_supported_scales (manager, + manager->layout_mode, + monitor, + monitor_mode, + &n_supported_scales); + for (i = 0; i < n_supported_scales; i++) + g_variant_builder_add (&supported_scales_builder, "d", + (double) supported_scales[i]); + g_free (supported_scales); + + mode_flags = meta_monitor_mode_get_flags (monitor_mode); + + g_variant_builder_init (&mode_properties_builder, + G_VARIANT_TYPE ("a{sv}")); + if (monitor_mode == current_mode) + g_variant_builder_add (&mode_properties_builder, "{sv}", + "is-current", + g_variant_new_boolean (TRUE)); + if (monitor_mode == preferred_mode) + g_variant_builder_add (&mode_properties_builder, "{sv}", + "is-preferred", + g_variant_new_boolean (TRUE)); + if (mode_flags & META_CRTC_MODE_FLAG_INTERLACE) + g_variant_builder_add (&mode_properties_builder, "{sv}", + "is-interlaced", + g_variant_new_boolean (TRUE)); + + g_variant_builder_add (&modes_builder, MODE_FORMAT, + mode_id, + mode_width, + mode_height, + refresh_rate, + (double) preferred_scale, + &supported_scales_builder, + &mode_properties_builder); + } + + g_variant_builder_init (&monitor_properties_builder, + G_VARIANT_TYPE ("a{sv}")); + if (meta_monitor_supports_underscanning (monitor)) + { + gboolean is_underscanning = meta_monitor_is_underscanning (monitor); + + g_variant_builder_add (&monitor_properties_builder, "{sv}", + "is-underscanning", + g_variant_new_boolean (is_underscanning)); + } + + is_builtin = meta_monitor_is_laptop_panel (monitor); + g_variant_builder_add (&monitor_properties_builder, "{sv}", + "is-builtin", + g_variant_new_boolean (is_builtin)); + + display_name = meta_monitor_get_display_name (monitor); + g_variant_builder_add (&monitor_properties_builder, "{sv}", + "display-name", + g_variant_new_string (display_name)); + + g_variant_builder_add (&monitors_builder, MONITOR_FORMAT, + monitor_spec->connector, + monitor_spec->vendor, + monitor_spec->product, + monitor_spec->serial, + &modes_builder, + &monitor_properties_builder); + } + + for (l = manager->logical_monitors; l; l = l->next) + { + MetaLogicalMonitor *logical_monitor = l->data; + GVariantBuilder logical_monitor_monitors_builder; + GList *k; + + g_variant_builder_init (&logical_monitor_monitors_builder, + G_VARIANT_TYPE (LOGICAL_MONITOR_MONITORS_FORMAT)); + + for (k = logical_monitor->monitors; k; k = k->next) + { + MetaMonitor *monitor = k->data; + MetaMonitorSpec *monitor_spec = meta_monitor_get_spec (monitor); + + g_variant_builder_add (&logical_monitor_monitors_builder, + MONITOR_SPEC_FORMAT, + monitor_spec->connector, + monitor_spec->vendor, + monitor_spec->product, + monitor_spec->serial); + } + + g_variant_builder_add (&logical_monitors_builder, + LOGICAL_MONITOR_FORMAT, + logical_monitor->rect.x, + logical_monitor->rect.y, + (double) logical_monitor->scale, + logical_monitor->transform, + logical_monitor->is_primary, + &logical_monitor_monitors_builder, + NULL); + } + + g_variant_builder_init (&properties_builder, G_VARIANT_TYPE ("a{sv}")); + + renderer = g_ascii_strdown (G_OBJECT_TYPE_NAME (manager) + + strlen (g_type_name (g_type_parent (G_OBJECT_TYPE (manager)))), + -1); + g_variant_builder_add (&properties_builder, "{sv}", + "renderer", + g_variant_new_take_string (renderer)); + + capabilities = meta_monitor_manager_get_capabilities (manager); + + g_variant_builder_add (&properties_builder, "{sv}", + "layout-mode", + g_variant_new_uint32 (manager->layout_mode)); + if (capabilities & META_MONITOR_MANAGER_CAPABILITY_LAYOUT_MODE) + { + g_variant_builder_add (&properties_builder, "{sv}", + "supports-changing-layout-mode", + g_variant_new_boolean (TRUE)); + } + + if (capabilities & META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED) + { + g_variant_builder_add (&properties_builder, "{sv}", + "global-scale-required", + g_variant_new_boolean (TRUE)); + } + else if (META_IS_MONITOR_MANAGER_XRANDR (manager) && + (capabilities & META_MONITOR_MANAGER_CAPABILITY_NATIVE_OUTPUT_SCALING) && + (capabilities & META_MONITOR_MANAGER_CAPABILITY_LAYOUT_MODE)) + { + g_variant_builder_add (&properties_builder, "{sv}", + "x11-fractional-scaling", + g_variant_new_boolean (TRUE)); + } + + ui_scaling_factor = meta_settings_get_ui_scaling_factor (settings); + g_variant_builder_add (&properties_builder, "{sv}", + "legacy-ui-scaling-factor", + g_variant_new_int32 (ui_scaling_factor)); + + if (meta_monitor_manager_get_max_screen_size (manager, + &max_screen_width, + &max_screen_height)) + { + GVariantBuilder max_screen_size_builder; + + g_variant_builder_init (&max_screen_size_builder, + G_VARIANT_TYPE ("(ii)")); + g_variant_builder_add (&max_screen_size_builder, "i", + max_screen_width); + g_variant_builder_add (&max_screen_size_builder, "i", + max_screen_height); + + g_variant_builder_add (&properties_builder, "{sv}", + "max-screen-size", + g_variant_builder_end (&max_screen_size_builder)); + } + + meta_dbus_display_config_complete_get_current_state ( + skeleton, + invocation, + manager->serial, + g_variant_builder_end (&monitors_builder), + g_variant_builder_end (&logical_monitors_builder), + g_variant_builder_end (&properties_builder)); + + return TRUE; +} + +#undef MODE_FORMAT +#undef MODES_FORMAT +#undef MONITOR_SPEC_FORMAT +#undef MONITOR_FORMAT +#undef MONITORS_FORMAT +#undef LOGICAL_MONITOR_MONITORS_FORMAT +#undef LOGICAL_MONITOR_FORMAT +#undef LOGICAL_MONITORS_FORMAT + +static gboolean +meta_monitor_manager_is_scale_supported_with_threshold (MetaMonitorManager *manager, + MetaLogicalMonitorLayoutMode layout_mode, + MetaMonitor *monitor, + MetaMonitorMode *monitor_mode, + float scale, + float threshold, + float *out_scale) +{ + g_autofree float *supported_scales = NULL; + int n_supported_scales; + int i; + + supported_scales = + meta_monitor_manager_calculate_supported_scales (manager, + layout_mode, + monitor, + monitor_mode, + &n_supported_scales); + for (i = 0; i < n_supported_scales; i++) + { + if (fabs (supported_scales[i] - scale) < threshold) + { + if (out_scale) + *out_scale = supported_scales[i]; + + return TRUE; + } + } + + return FALSE; +} + +gboolean +meta_monitor_manager_is_scale_supported (MetaMonitorManager *manager, + MetaLogicalMonitorLayoutMode layout_mode, + MetaMonitor *monitor, + MetaMonitorMode *monitor_mode, + float scale) +{ + return meta_monitor_manager_is_scale_supported_with_threshold (manager, + layout_mode, + monitor, + monitor_mode, + scale, + FLT_EPSILON, + NULL); +} + +static gboolean +is_global_scale_matching_in_config (MetaMonitorsConfig *config, + float scale) +{ + GList *l; + + for (l = config->logical_monitor_configs; l; l = l->next) + { + MetaLogicalMonitorConfig *logical_monitor_config = l->data; + + if (fabs (logical_monitor_config->scale - scale) > FLT_EPSILON) + return FALSE; + } + + return TRUE; +} + +static gboolean +meta_monitor_manager_is_scale_supported_for_config (MetaMonitorManager *manager, + MetaMonitorsConfig *config, + MetaMonitor *monitor, + MetaMonitorMode *monitor_mode, + float scale) +{ + if (meta_monitor_manager_is_scale_supported (manager, config->layout_mode, + monitor, monitor_mode, scale)) + { + if (meta_monitor_manager_get_capabilities (manager) & + META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED) + return is_global_scale_matching_in_config (config, scale); + + return TRUE; + } + + return FALSE; +} + +static gboolean +meta_monitor_manager_is_config_applicable (MetaMonitorManager *manager, + MetaMonitorsConfig *config, + GError **error) +{ + GList *l; + + for (l = config->logical_monitor_configs; l; l = l->next) + { + MetaLogicalMonitorConfig *logical_monitor_config = l->data; + float scale = logical_monitor_config->scale; + GList *k; + + for (k = logical_monitor_config->monitor_configs; k; k = k->next) + { + MetaMonitorConfig *monitor_config = k->data; + MetaMonitorSpec *monitor_spec = monitor_config->monitor_spec; + MetaMonitorModeSpec *mode_spec = monitor_config->mode_spec; + MetaMonitor *monitor; + MetaMonitorMode *monitor_mode; + + monitor = meta_monitor_manager_get_monitor_from_spec (manager, + monitor_spec); + if (!monitor) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Specified monitor not found"); + return FALSE; + } + + monitor_mode = meta_monitor_get_mode_from_spec (monitor, mode_spec); + if (!monitor_mode) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Specified monitor mode not available"); + return FALSE; + } + + if (!meta_monitor_manager_is_scale_supported_for_config (manager, + config, + monitor, + monitor_mode, + scale)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Scale not supported by backend"); + return FALSE; + } + + if (meta_monitor_is_laptop_panel (monitor) && + meta_backend_is_lid_closed (manager->backend)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Refusing to activate a closed laptop panel"); + return FALSE; + } + } + } + + return TRUE; +} + +static gboolean +meta_monitor_manager_is_config_complete (MetaMonitorManager *manager, + MetaMonitorsConfig *config) +{ + MetaMonitorsConfigKey *current_state_key; + gboolean is_config_complete; + + current_state_key = + meta_create_monitors_config_key_for_current_state (manager); + if (!current_state_key) + return FALSE; + + is_config_complete = meta_monitors_config_key_equal (current_state_key, + config->key); + meta_monitors_config_key_free (current_state_key); + + if (!is_config_complete) + return FALSE; + + return meta_monitor_manager_is_config_applicable (manager, config, NULL); +} + +static MetaMonitor * +find_monitor_from_connector (MetaMonitorManager *manager, + char *connector) +{ + GList *monitors; + GList *l; + + if (!connector) + return NULL; + + monitors = meta_monitor_manager_get_monitors (manager); + for (l = monitors; l; l = l->next) + { + MetaMonitor *monitor = l->data; + MetaMonitorSpec *monitor_spec = meta_monitor_get_spec (monitor); + + if (g_str_equal (connector, monitor_spec->connector)) + return monitor; + } + + return NULL; +} + +#define MONITOR_CONFIG_FORMAT "(ssa{sv})" +#define MONITOR_CONFIGS_FORMAT "a" MONITOR_CONFIG_FORMAT + +#define LOGICAL_MONITOR_CONFIG_FORMAT "(iidub" MONITOR_CONFIGS_FORMAT ")" + +static MetaMonitorConfig * +create_monitor_config_from_variant (MetaMonitorManager *manager, + GVariant *monitor_config_variant, + GError **error) +{ + + MetaMonitorConfig *monitor_config = NULL; + g_autofree char *connector = NULL; + g_autofree char *mode_id = NULL; + MetaMonitorMode *monitor_mode; + MetaMonitor *monitor; + MetaMonitorSpec *monitor_spec; + MetaMonitorModeSpec *monitor_mode_spec; + g_autoptr (GVariant) properties_variant = NULL; + gboolean enable_underscanning = FALSE; + gboolean set_underscanning = FALSE; + + g_variant_get (monitor_config_variant, "(ss@a{sv})", + &connector, + &mode_id, + &properties_variant); + + monitor = find_monitor_from_connector (manager, connector); + if (!monitor) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Invalid connector '%s' specified", connector); + return NULL; + } + + monitor_mode = meta_monitor_get_mode_from_id (monitor, mode_id); + if (!monitor_mode) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Invalid mode '%s' specified", mode_id); + return NULL; + } + + set_underscanning = + g_variant_lookup (properties_variant, "underscanning", "b", + &enable_underscanning); + if (set_underscanning) + { + if (enable_underscanning && !meta_monitor_supports_underscanning (monitor)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Underscanning requested but unsupported"); + return NULL; + } + } + + monitor_spec = meta_monitor_spec_clone (meta_monitor_get_spec (monitor)); + + monitor_mode_spec = g_new0 (MetaMonitorModeSpec, 1); + *monitor_mode_spec = *meta_monitor_mode_get_spec (monitor_mode); + + monitor_config = g_new0 (MetaMonitorConfig, 1); + *monitor_config = (MetaMonitorConfig) { + .monitor_spec = monitor_spec, + .mode_spec = monitor_mode_spec, + .enable_underscanning = enable_underscanning + }; + + return monitor_config; +} + +static gboolean +find_monitor_mode_scale (MetaMonitorManager *manager, + MetaLogicalMonitorLayoutMode layout_mode, + MetaMonitorConfig *monitor_config, + float scale, + float *out_scale, + GError **error) +{ + MetaMonitorSpec *monitor_spec; + MetaMonitor *monitor; + MetaMonitorModeSpec *monitor_mode_spec; + MetaMonitorMode *monitor_mode; + g_autofree float *supported_scales = NULL; + int n_supported_scales; + int i; + + monitor_spec = monitor_config->monitor_spec; + monitor = meta_monitor_manager_get_monitor_from_spec (manager, + monitor_spec); + if (!monitor) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Monitor not found"); + return FALSE; + } + + monitor_mode_spec = monitor_config->mode_spec; + monitor_mode = meta_monitor_get_mode_from_spec (monitor, + monitor_mode_spec); + if (!monitor_mode) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Monitor mode not found"); + return FALSE; + } + + supported_scales = + meta_monitor_manager_calculate_supported_scales (manager, layout_mode, + monitor, monitor_mode, + &n_supported_scales); + + for (i = 0; i < n_supported_scales; i++) + { + float supported_scale = supported_scales[i]; + + if (fabsf (supported_scale - scale) < FLT_EPSILON) + { + *out_scale = supported_scale; + return TRUE; + } + } + + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Scale %g not valid for resolution %dx%d", + scale, + monitor_mode_spec->width, + monitor_mode_spec->height); + return FALSE; +} + +static gboolean +derive_logical_monitor_size (MetaMonitorConfig *monitor_config, + int *out_width, + int *out_height, + float scale, + MetaMonitorTransform transform, + MetaLogicalMonitorLayoutMode layout_mode, + GError **error) +{ + int width, height; + + if (meta_monitor_transform_is_rotated (transform)) + { + width = monitor_config->mode_spec->height; + height = monitor_config->mode_spec->width; + } + else + { + width = monitor_config->mode_spec->width; + height = monitor_config->mode_spec->height; + } + + switch (layout_mode) + { + case META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL: + case META_LOGICAL_MONITOR_LAYOUT_MODE_GLOBAL_UI_LOGICAL: + width = roundf (width / scale); + height = roundf (height / scale); + break; + case META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL: + break; + } + + *out_width = width; + *out_height = height; + + return TRUE; +} + +static MetaLogicalMonitorConfig * +create_logical_monitor_config_from_variant (MetaMonitorManager *manager, + GVariant *logical_monitor_config_variant, + MetaLogicalMonitorLayoutMode layout_mode, + GError **error) +{ + MetaLogicalMonitorConfig *logical_monitor_config; + int x, y, width, height; + double scale_d; + float scale; + MetaMonitorTransform transform; + gboolean is_primary; + GVariantIter *monitor_configs_iter; + GList *monitor_configs = NULL; + MetaMonitorConfig *monitor_config; + + g_variant_get (logical_monitor_config_variant, LOGICAL_MONITOR_CONFIG_FORMAT, + &x, + &y, + &scale_d, + &transform, + &is_primary, + &monitor_configs_iter); + scale = (float) scale_d; + + while (TRUE) + { + GVariant *monitor_config_variant = + g_variant_iter_next_value (monitor_configs_iter); + MetaMonitorConfig *monitor_config; + + if (!monitor_config_variant) + break; + + monitor_config = + create_monitor_config_from_variant (manager, + monitor_config_variant, error); + g_variant_unref (monitor_config_variant); + + if (!monitor_config) + goto err; + + if (!meta_verify_monitor_config (monitor_config, error)) + { + meta_monitor_config_free (monitor_config); + goto err; + } + + monitor_configs = g_list_append (monitor_configs, monitor_config); + } + g_variant_iter_free (monitor_configs_iter); + + if (!monitor_configs) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Empty logical monitor"); + goto err; + } + + monitor_config = monitor_configs->data; + if (!find_monitor_mode_scale (manager, + layout_mode, + monitor_config, + scale, + &scale, + error)) + goto err; + + if (!derive_logical_monitor_size (monitor_config, &width, &height, + scale, transform, layout_mode, error)) + goto err; + + logical_monitor_config = g_new0 (MetaLogicalMonitorConfig, 1); + *logical_monitor_config = (MetaLogicalMonitorConfig) { + .layout = { + .x = x, + .y = y, + .width = width, + .height = height + }, + .transform = transform, + .scale = scale, + .is_primary = is_primary, + .monitor_configs = monitor_configs + }; + + if (layout_mode != META_LOGICAL_MONITOR_LAYOUT_MODE_GLOBAL_UI_LOGICAL && + !meta_verify_logical_monitor_config (logical_monitor_config, + layout_mode, + manager, + 1.0f, + error)) + { + meta_logical_monitor_config_free (logical_monitor_config); + return NULL; + } + + return logical_monitor_config; + +err: + g_list_free_full (monitor_configs, (GDestroyNotify) meta_monitor_config_free); + return NULL; +} + +static gboolean +is_valid_layout_mode (MetaLogicalMonitorLayoutMode layout_mode) +{ + switch (layout_mode) + { + case META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL: + case META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL: + case META_LOGICAL_MONITOR_LAYOUT_MODE_GLOBAL_UI_LOGICAL: + return TRUE; + } + + return FALSE; +} + +static gboolean +meta_monitor_manager_handle_apply_monitors_config (MetaDBusDisplayConfig *skeleton, + GDBusMethodInvocation *invocation, + guint serial, + guint method, + GVariant *logical_monitor_configs_variant, + GVariant *properties_variant, + MetaMonitorManager *manager) +{ + MetaMonitorManagerCapability capabilities; + GVariant *layout_mode_variant = NULL; + MetaLogicalMonitorLayoutMode layout_mode; + GVariantIter logical_monitor_configs_iter; + MetaMonitorsConfig *config; + GList *logical_monitor_configs = NULL; + GError *error = NULL; + float max_scale = 1.0f; + + if (serial != manager->serial) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_ACCESS_DENIED, + "The requested configuration is based on stale information"); + return TRUE; + } + + capabilities = meta_monitor_manager_get_capabilities (manager); + + if (properties_variant) + layout_mode_variant = g_variant_lookup_value (properties_variant, + "layout-mode", + G_VARIANT_TYPE ("u")); + + if (layout_mode_variant && + capabilities & META_MONITOR_MANAGER_CAPABILITY_LAYOUT_MODE) + { + g_variant_get (layout_mode_variant, "u", &layout_mode); + } + else if (!layout_mode_variant) + { + layout_mode = + meta_monitor_manager_get_default_layout_mode (manager); + } + else + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_INVALID_ARGS, + "Can't set layout mode"); + return TRUE; + } + + if (!is_valid_layout_mode (layout_mode)) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_ACCESS_DENIED, + "Invalid layout mode specified"); + return TRUE; + } + + g_variant_iter_init (&logical_monitor_configs_iter, + logical_monitor_configs_variant); + while (TRUE) + { + GVariant *logical_monitor_config_variant = + g_variant_iter_next_value (&logical_monitor_configs_iter); + MetaLogicalMonitorConfig *logical_monitor_config; + + if (!logical_monitor_config_variant) + break; + + logical_monitor_config = + create_logical_monitor_config_from_variant (manager, + logical_monitor_config_variant, + layout_mode, + &error); + g_variant_unref (logical_monitor_config_variant); + + if (!logical_monitor_config) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_INVALID_ARGS, + "%s", error->message); + g_error_free (error); + g_list_free_full (logical_monitor_configs, + (GDestroyNotify) meta_logical_monitor_config_free); + return TRUE; + } + + max_scale = MAX (max_scale, logical_monitor_config->scale); + logical_monitor_configs = g_list_append (logical_monitor_configs, + logical_monitor_config); + } + + if (manager->layout_mode == META_LOGICAL_MONITOR_LAYOUT_MODE_GLOBAL_UI_LOGICAL) + { + GList *l; + int ui_scale = ceilf (max_scale); + + for (l = logical_monitor_configs; l; l = l->next) + { + MetaLogicalMonitorConfig *logical_monitor_config = l->data; + + logical_monitor_config->layout.width = + roundf (logical_monitor_config->layout.width * ui_scale); + logical_monitor_config->layout.height = + roundf (logical_monitor_config->layout.height * ui_scale); + + if (!meta_verify_logical_monitor_config (logical_monitor_config, + manager->layout_mode, + manager, + ui_scale, + &error)) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_INVALID_ARGS, + "%s", error->message); + g_error_free (error); + g_list_free_full (logical_monitor_configs, + (GDestroyNotify) meta_logical_monitor_config_free); + return TRUE; + } + } + } + + config = meta_monitors_config_new (manager, + logical_monitor_configs, + layout_mode, + META_MONITORS_CONFIG_FLAG_NONE); + if (!meta_verify_monitors_config (config, manager, &error)) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_INVALID_ARGS, + "%s", error->message); + g_error_free (error); + g_object_unref (config); + return TRUE; + } + + if (!meta_monitor_manager_is_config_applicable (manager, config, &error)) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_INVALID_ARGS, + "%s", error->message); + g_error_free (error); + g_object_unref (config); + return TRUE; + } + + if (manager->persistent_timeout_id && + method != META_MONITORS_CONFIG_METHOD_VERIFY) + cancel_persistent_confirmation (manager); + + if (!meta_monitor_manager_apply_monitors_config (manager, + config, + method, + &error)) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_INVALID_ARGS, + "%s", error->message); + g_error_free (error); + g_object_unref (config); + return TRUE; + } + + if (method == META_MONITORS_CONFIG_METHOD_PERSISTENT) + request_persistent_confirmation (manager); + + meta_dbus_display_config_complete_apply_monitors_config (skeleton, invocation); + + return TRUE; +} + +#undef MONITOR_MODE_SPEC_FORMAT +#undef MONITOR_CONFIG_FORMAT +#undef MONITOR_CONFIGS_FORMAT +#undef LOGICAL_MONITOR_CONFIG_FORMAT + +static void +confirm_configuration (MetaMonitorManager *manager, + gboolean confirmed) +{ + if (confirmed) + meta_monitor_config_manager_save_current (manager->config_manager); + else + restore_previous_config (manager); +} + +void +meta_monitor_manager_confirm_configuration (MetaMonitorManager *manager, + gboolean ok) +{ + if (!manager->persistent_timeout_id) + { + /* too late */ + return; + } + + cancel_persistent_confirmation (manager); + confirm_configuration (manager, ok); +} + +static gboolean +meta_monitor_manager_handle_change_backlight (MetaDBusDisplayConfig *skeleton, + GDBusMethodInvocation *invocation, + guint serial, + guint output_index, + gint value, + MetaMonitorManager *manager) +{ + GList *combined_outputs; + MetaOutput *output; + + if (serial != manager->serial) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_ACCESS_DENIED, + "The requested configuration is based on stale information"); + return TRUE; + } + + combined_outputs = combine_gpu_lists (manager, meta_gpu_get_outputs); + + if (output_index >= g_list_length (combined_outputs)) + { + g_list_free (combined_outputs); + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_INVALID_ARGS, + "Invalid output id"); + return TRUE; + } + output = g_list_nth_data (combined_outputs, output_index); + g_list_free (combined_outputs); + + if (value < 0 || value > 100) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_INVALID_ARGS, + "Invalid backlight value"); + return TRUE; + } + + if (output->backlight == -1 || + (output->backlight_min == 0 && output->backlight_max == 0)) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_INVALID_ARGS, + "Output does not support changing backlight"); + return TRUE; + } + + META_MONITOR_MANAGER_GET_CLASS (manager)->change_backlight (manager, output, value); + + meta_dbus_display_config_complete_change_backlight (skeleton, invocation, output->backlight); + return TRUE; +} + +static gboolean +meta_monitor_manager_handle_get_crtc_gamma (MetaDBusDisplayConfig *skeleton, + GDBusMethodInvocation *invocation, + guint serial, + guint crtc_id, + MetaMonitorManager *manager) +{ + MetaMonitorManagerClass *klass; + GList *combined_crtcs; + MetaCrtc *crtc; + gsize size; + unsigned short *red; + unsigned short *green; + unsigned short *blue; + GBytes *red_bytes, *green_bytes, *blue_bytes; + GVariant *red_v, *green_v, *blue_v; + + if (serial != manager->serial) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_ACCESS_DENIED, + "The requested configuration is based on stale information"); + return TRUE; + } + + combined_crtcs = combine_gpu_lists (manager, meta_gpu_get_crtcs); + if (crtc_id >= g_list_length (combined_crtcs)) + { + g_list_free (combined_crtcs); + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_INVALID_ARGS, + "Invalid crtc id"); + return TRUE; + } + + crtc = g_list_nth_data (combined_crtcs, crtc_id); + g_list_free (combined_crtcs); + + klass = META_MONITOR_MANAGER_GET_CLASS (manager); + if (klass->get_crtc_gamma) + klass->get_crtc_gamma (manager, crtc, &size, &red, &green, &blue); + else + { + size = 0; + red = green = blue = NULL; + } + + red_bytes = g_bytes_new_take (red, size * sizeof (unsigned short)); + green_bytes = g_bytes_new_take (green, size * sizeof (unsigned short)); + blue_bytes = g_bytes_new_take (blue, size * sizeof (unsigned short)); + + red_v = g_variant_new_from_bytes (G_VARIANT_TYPE ("aq"), red_bytes, TRUE); + green_v = g_variant_new_from_bytes (G_VARIANT_TYPE ("aq"), green_bytes, TRUE); + blue_v = g_variant_new_from_bytes (G_VARIANT_TYPE ("aq"), blue_bytes, TRUE); + + meta_dbus_display_config_complete_get_crtc_gamma (skeleton, invocation, + red_v, green_v, blue_v); + + g_bytes_unref (red_bytes); + g_bytes_unref (green_bytes); + g_bytes_unref (blue_bytes); + + return TRUE; +} + +static gboolean +meta_monitor_manager_handle_set_crtc_gamma (MetaDBusDisplayConfig *skeleton, + GDBusMethodInvocation *invocation, + guint serial, + guint crtc_id, + GVariant *red_v, + GVariant *green_v, + GVariant *blue_v, + MetaMonitorManager *manager) +{ + MetaMonitorManagerClass *klass; + GList *combined_crtcs; + MetaCrtc *crtc; + gsize size, dummy; + unsigned short *red; + unsigned short *green; + unsigned short *blue; + GBytes *red_bytes, *green_bytes, *blue_bytes; + + if (serial != manager->serial) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_ACCESS_DENIED, + "The requested configuration is based on stale information"); + return TRUE; + } + + combined_crtcs = combine_gpu_lists (manager, meta_gpu_get_crtcs); + + if (crtc_id >= g_list_length (combined_crtcs)) + { + g_list_free (combined_crtcs); + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_INVALID_ARGS, + "Invalid crtc id"); + return TRUE; + } + + crtc = g_list_nth_data (combined_crtcs, crtc_id); + g_list_free (combined_crtcs); + + red_bytes = g_variant_get_data_as_bytes (red_v); + green_bytes = g_variant_get_data_as_bytes (green_v); + blue_bytes = g_variant_get_data_as_bytes (blue_v); + + size = g_bytes_get_size (red_bytes) / sizeof (unsigned short); + red = (unsigned short*) g_bytes_get_data (red_bytes, &dummy); + green = (unsigned short*) g_bytes_get_data (green_bytes, &dummy); + blue = (unsigned short*) g_bytes_get_data (blue_bytes, &dummy); + + klass = META_MONITOR_MANAGER_GET_CLASS (manager); + if (klass->set_crtc_gamma) + klass->set_crtc_gamma (manager, crtc, size, red, green, blue); + meta_dbus_display_config_complete_set_crtc_gamma (skeleton, invocation); + + g_bytes_unref (red_bytes); + g_bytes_unref (green_bytes); + g_bytes_unref (blue_bytes); + + return TRUE; +} + +static void +monitor_manager_setup_dbus_config_handlers (MetaMonitorManager *manager) +{ + g_signal_connect_object (manager->display_config, "handle-get-resources", + G_CALLBACK (meta_monitor_manager_handle_get_resources), + manager, 0); + g_signal_connect_object (manager->display_config, "handle-change-backlight", + G_CALLBACK (meta_monitor_manager_handle_change_backlight), + manager, 0); + g_signal_connect_object (manager->display_config, "handle-get-crtc-gamma", + G_CALLBACK (meta_monitor_manager_handle_get_crtc_gamma), + manager, 0); + g_signal_connect_object (manager->display_config, "handle-set-crtc-gamma", + G_CALLBACK (meta_monitor_manager_handle_set_crtc_gamma), + manager, 0); + g_signal_connect_object (manager->display_config, "handle-get-current-state", + G_CALLBACK (meta_monitor_manager_handle_get_current_state), + manager, 0); + g_signal_connect_object (manager->display_config, "handle-apply-monitors-config", + G_CALLBACK (meta_monitor_manager_handle_apply_monitors_config), + manager, 0); +} + +static void +on_bus_acquired (GDBusConnection *connection, + const char *name, + gpointer user_data) +{ + MetaMonitorManager *manager = user_data; + + g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (manager->display_config), + connection, + "/org/gnome/Mutter/DisplayConfig", + NULL); +} + +static void +on_name_acquired (GDBusConnection *connection, + const char *name, + gpointer user_data) +{ + meta_topic (META_DEBUG_DBUS, "Acquired name %s\n", name); +} + +static void +on_name_lost (GDBusConnection *connection, + const char *name, + gpointer user_data) +{ + meta_topic (META_DEBUG_DBUS, "Lost or failed to acquire name %s\n", name); +} + +static void +initialize_dbus_interface (MetaMonitorManager *manager) +{ + manager->dbus_name_id = g_bus_own_name (G_BUS_TYPE_SESSION, + "org.gnome.Mutter.DisplayConfig", + G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT | + (meta_get_replace_current_wm () ? + G_BUS_NAME_OWNER_FLAGS_REPLACE : 0), + on_bus_acquired, + on_name_acquired, + on_name_lost, + g_object_ref (manager), + g_object_unref); +} + +/** + * meta_monitor_manager_get: + * + * Accessor for the singleton MetaMonitorManager. + * + * Returns: (transfer none): The only #MetaMonitorManager there is. + */ +MetaMonitorManager * +meta_monitor_manager_get (void) +{ + MetaBackend *backend = meta_get_backend (); + + return meta_backend_get_monitor_manager (backend); +} + +/** + * meta_monitor_manager_get_num_logical_monitors: + * @manager: A #MetaMonitorManager object + * + * Returns the number of #MetaLogicalMonitor<!-- -->s (can be 0 in case of a + * headless setup). + * + * Returns: the total number of #MetaLogicalMonitor<!-- -->s. + */ +int +meta_monitor_manager_get_num_logical_monitors (MetaMonitorManager *manager) +{ + return g_list_length (manager->logical_monitors); +} + +/** + * meta_monitor_manager_get_logical_monitors: + * @manager: A #MetaMonitorManager object + * + * Returns the list of #MetaLogicalMonitor<!-- -->s that is handled. See also + * meta_monitor_manager_get_num_logical_monitors() if you only need the size of + * the list. + * + * Returns: (transfer none) (nullable): the list of logical monitors. + */ +GList * +meta_monitor_manager_get_logical_monitors (MetaMonitorManager *manager) +{ + return manager->logical_monitors; +} + +MetaLogicalMonitor * +meta_monitor_manager_get_logical_monitor_from_number (MetaMonitorManager *manager, + int number) +{ + g_return_val_if_fail ((unsigned int) number < g_list_length (manager->logical_monitors), NULL); + + return g_list_nth (manager->logical_monitors, number)->data; +} + +MetaLogicalMonitor * +meta_monitor_manager_get_primary_logical_monitor (MetaMonitorManager *manager) +{ + return manager->primary_logical_monitor; +} + +static MetaMonitor * +find_monitor (MetaMonitorManager *monitor_manager, + gboolean (*match_func) (MetaMonitor *monitor)) +{ + GList *monitors; + GList *l; + + monitors = meta_monitor_manager_get_monitors (monitor_manager); + for (l = monitors; l; l = l->next) + { + MetaMonitor *monitor = l->data; + + if (match_func (monitor)) + return monitor; + } + + return NULL; +} + +/** + * meta_monitor_manager_get_primary_monitor: + * @manager: A #MetaMonitorManager object + * + * Returns the primary monitor. This can be %NULL (e.g. when running headless). + * + * Returns: (transfer none) (nullable): The primary #MetaMonitor, or %NULL if + * none. + */ +MetaMonitor * +meta_monitor_manager_get_primary_monitor (MetaMonitorManager *manager) +{ + return find_monitor (manager, meta_monitor_is_primary); +} + +/** + * meta_monitor_manager_get_laptop_panel: + * @manager: A #MetaMonitorManager object + * + * Returns the #MetaMonitor that represents the built-in laptop panel (if + * applicable). + * + * Returns: (transfer none) (nullable): The laptop panel, or %NULL if none. + */ +MetaMonitor * +meta_monitor_manager_get_laptop_panel (MetaMonitorManager *manager) +{ + return find_monitor (manager, meta_monitor_is_laptop_panel); +} + +MetaMonitor * +meta_monitor_manager_get_monitor_from_connector (MetaMonitorManager *manager, + const char *connector) +{ + GList *l; + + for (l = manager->monitors; l; l = l->next) + { + MetaMonitor *monitor = l->data; + + if (g_str_equal (meta_monitor_get_connector (monitor), + connector)) + return monitor; + } + + return NULL; +} + +MetaMonitor * +meta_monitor_manager_get_monitor_from_spec (MetaMonitorManager *manager, + MetaMonitorSpec *monitor_spec) +{ + GList *l; + + for (l = manager->monitors; l; l = l->next) + { + MetaMonitor *monitor = l->data; + + if (meta_monitor_spec_equals (meta_monitor_get_spec (monitor), + monitor_spec)) + return monitor; + } + + return NULL; +} + +/** + * meta_monitor_manager_get_logical_monitor_at: + * @manager: A #MetaMonitorManager object + * @x: The x-coordinate + * @y: The y-coordinate + * + * Finds the #MetaLogicalMonitor at the given @x and @y coordinates in the + * total layout. + * + * Returns: (transfer none) (nullable): The #MetaLogicalMonitor at the given + * point, or %NULL if none. + */ +MetaLogicalMonitor * +meta_monitor_manager_get_logical_monitor_at (MetaMonitorManager *manager, + float x, + float y) +{ + GList *l; + + for (l = manager->logical_monitors; l; l = l->next) + { + MetaLogicalMonitor *logical_monitor = l->data; + + if (META_POINT_IN_RECT (x, y, logical_monitor->rect)) + return logical_monitor; + } + + return NULL; +} + +/** + * meta_monitor_manager_get_logical_monitor_from_rect: + * @manager: A #MetaMonitorManager object + * @rect: The rectangle + * + * Finds the #MetaLogicalMonitor which has the largest area in common with the + * given @rect in the total layout. + * + * Returns: (transfer none) (nullable): The #MetaLogicalMonitor which + * corresponds the most to the given @rect, or %NULL if none. + */ +MetaLogicalMonitor * +meta_monitor_manager_get_logical_monitor_from_rect (MetaMonitorManager *manager, + MetaRectangle *rect) +{ + MetaLogicalMonitor *best_logical_monitor; + int best_logical_monitor_area; + GList *l; + + best_logical_monitor = NULL; + best_logical_monitor_area = 0; + + for (l = manager->logical_monitors; l; l = l->next) + { + MetaLogicalMonitor *logical_monitor = l->data; + MetaRectangle intersection; + int intersection_area; + + if (!meta_rectangle_intersect (&logical_monitor->rect, + rect, + &intersection)) + continue; + + intersection_area = meta_rectangle_area (&intersection); + + if (intersection_area > best_logical_monitor_area) + { + best_logical_monitor = logical_monitor; + best_logical_monitor_area = intersection_area; + } + } + + if (!best_logical_monitor && (rect->width == 0 || rect->height == 0)) + best_logical_monitor = + meta_monitor_manager_get_logical_monitor_at (manager, rect->x, rect->y); + + if (!best_logical_monitor) + best_logical_monitor = manager->primary_logical_monitor; + + return best_logical_monitor; +} + +MetaLogicalMonitor * +meta_monitor_manager_get_logical_monitor_neighbor (MetaMonitorManager *manager, + MetaLogicalMonitor *logical_monitor, + MetaDisplayDirection direction) +{ + GList *l; + + for (l = manager->logical_monitors; l; l = l->next) + { + MetaLogicalMonitor *other = l->data; + + if (meta_logical_monitor_has_neighbor (logical_monitor, other, direction)) + return other; + } + + return NULL; +} + +/** + * meta_monitor_manager_get_monitors: + * @manager: A #MetaMonitorManager object + * + * Returns the list of #MetaMonitor<!-- -->s. See also + * meta_monitor_manager_get_logical_monitors() for a list of + * #MetaLogicalMonitor<!-- -->s. + * + * Returns: (transfer none) (nullable): the list of #MetaMonitor<!-- -->s. + */ +GList * +meta_monitor_manager_get_monitors (MetaMonitorManager *manager) +{ + return manager->monitors; +} + +void +meta_monitor_manager_get_screen_size (MetaMonitorManager *manager, + int *width, + int *height) +{ + *width = manager->screen_width; + *height = manager->screen_height; +} + +MetaPowerSave +meta_monitor_manager_get_power_save_mode (MetaMonitorManager *manager) +{ + MetaMonitorManagerPrivate *priv = + meta_monitor_manager_get_instance_private (manager); + + return priv->power_save_mode; +} + +static void +rebuild_monitors (MetaMonitorManager *manager) +{ + GList *gpus; + GList *l; + gboolean has_tiling; + + has_tiling = meta_monitor_manager_get_capabilities (manager) & + META_MONITOR_MANAGER_CAPABILITY_TILING; + + if (manager->monitors) + { + g_list_free_full (manager->monitors, g_object_unref); + manager->monitors = NULL; + } + + gpus = meta_backend_get_gpus (manager->backend); + for (l = gpus; l; l = l->next) + { + MetaGpu *gpu = l->data; + GList *k; + + for (k = meta_gpu_get_outputs (gpu); k; k = k->next) + { + MetaOutput *output = k->data; + + if (has_tiling && output->tile_info.group_id) + { + if (is_main_tiled_monitor_output (output)) + { + MetaMonitorTiled *monitor_tiled; + + monitor_tiled = meta_monitor_tiled_new (gpu, manager, output); + manager->monitors = g_list_append (manager->monitors, + monitor_tiled); + } + } + else + { + MetaMonitorNormal *monitor_normal; + + monitor_normal = meta_monitor_normal_new (gpu, manager, output); + manager->monitors = g_list_append (manager->monitors, + monitor_normal); + } + } + } +} + +void +meta_monitor_manager_tiled_monitor_added (MetaMonitorManager *manager, + MetaMonitor *monitor) +{ + MetaMonitorManagerClass *manager_class = + META_MONITOR_MANAGER_GET_CLASS (manager); + + if (manager_class->tiled_monitor_added) + manager_class->tiled_monitor_added (manager, monitor); +} + +void +meta_monitor_manager_tiled_monitor_removed (MetaMonitorManager *manager, + MetaMonitor *monitor) +{ + MetaMonitorManagerClass *manager_class = + META_MONITOR_MANAGER_GET_CLASS (manager); + + if (manager_class->tiled_monitor_removed) + manager_class->tiled_monitor_removed (manager, monitor); +} + +gboolean +meta_monitor_manager_is_transform_handled (MetaMonitorManager *manager, + MetaCrtc *crtc, + MetaMonitorTransform transform) +{ + MetaMonitorManagerClass *manager_class = + META_MONITOR_MANAGER_GET_CLASS (manager); + + return manager_class->is_transform_handled (manager, crtc, transform); +} + +static void +meta_monitor_manager_real_read_current_state (MetaMonitorManager *manager) +{ + GList *l; + + manager->serial++; + + for (l = meta_backend_get_gpus (manager->backend); l; l = l->next) + { + MetaGpu *gpu = l->data; + GError *error = NULL; + + if (!meta_gpu_read_current (gpu, &error)) + { + g_warning ("Failed to read current KMS state: %s", error->message); + g_clear_error (&error); + } + } + + rebuild_monitors (manager); +} + +void +meta_monitor_manager_read_current_state (MetaMonitorManager *manager) +{ + MetaMonitorManagerClass *manager_class = + META_MONITOR_MANAGER_GET_CLASS (manager); + + manager_class->read_current_state (manager); +} + +static void +meta_monitor_manager_notify_monitors_changed (MetaMonitorManager *manager) +{ + meta_backend_monitors_changed (manager->backend); + + g_signal_emit (manager, signals[MONITORS_CHANGED_INTERNAL], 0); + g_signal_emit (manager, signals[MONITORS_CHANGED], 0); + + meta_dbus_display_config_emit_monitors_changed (manager->display_config); +} + +static void +set_logical_monitor_modes (MetaMonitorManager *manager, + MetaLogicalMonitorConfig *logical_monitor_config) +{ + GList *l; + + for (l = logical_monitor_config->monitor_configs; l; l = l->next) + { + MetaMonitorConfig *monitor_config = l->data; + MetaMonitorSpec *monitor_spec; + MetaMonitor *monitor; + MetaMonitorModeSpec *monitor_mode_spec; + MetaMonitorMode *monitor_mode; + + monitor_spec = monitor_config->monitor_spec; + monitor = meta_monitor_manager_get_monitor_from_spec (manager, + monitor_spec); + monitor_mode_spec = monitor_config->mode_spec; + monitor_mode = meta_monitor_get_mode_from_spec (monitor, + monitor_mode_spec); + + meta_monitor_set_current_mode (monitor, monitor_mode); + } +} + +static void +meta_monitor_manager_update_monitor_modes (MetaMonitorManager *manager, + MetaMonitorsConfig *config) +{ + GList *logical_monitor_configs; + GList *l; + + g_list_foreach (manager->monitors, + (GFunc) meta_monitor_set_current_mode, + NULL); + + logical_monitor_configs = config ? config->logical_monitor_configs : NULL; + for (l = logical_monitor_configs; l; l = l->next) + { + MetaLogicalMonitorConfig *logical_monitor_config = l->data; + + set_logical_monitor_modes (manager, logical_monitor_config); + } +} + +void +meta_monitor_manager_update_logical_state (MetaMonitorManager *manager, + MetaMonitorsConfig *config) +{ + if (config) + { + manager->layout_mode = config->layout_mode; + manager->current_switch_config = + meta_monitors_config_get_switch_config (config); + } + else + { + manager->layout_mode = + meta_monitor_manager_get_default_layout_mode (manager); + manager->current_switch_config = META_MONITOR_SWITCH_CONFIG_UNKNOWN; + } + + meta_monitor_manager_rebuild_logical_monitors (manager, config); +} + +void +meta_monitor_manager_rebuild (MetaMonitorManager *manager, + MetaMonitorsConfig *config) +{ + GList *old_logical_monitors; + + meta_monitor_manager_update_monitor_modes (manager, config); + + if (manager->in_init) + return; + + old_logical_monitors = manager->logical_monitors; + + meta_monitor_manager_update_logical_state (manager, config); + + meta_monitor_manager_notify_monitors_changed (manager); + + g_list_free_full (old_logical_monitors, g_object_unref); +} + +static void +meta_monitor_manager_update_monitor_modes_derived (MetaMonitorManager *manager) +{ + GList *l; + + for (l = manager->monitors; l; l = l->next) + { + MetaMonitor *monitor = l->data; + + meta_monitor_derive_current_mode (monitor); + } +} + +void +meta_monitor_manager_update_logical_state_derived (MetaMonitorManager *manager, + MetaMonitorsConfig *config) +{ + if (config) + manager->current_switch_config = + meta_monitors_config_get_switch_config (config); + else + manager->current_switch_config = META_MONITOR_SWITCH_CONFIG_UNKNOWN; + + manager->layout_mode = meta_monitor_manager_get_default_layout_mode (manager); + + meta_monitor_manager_rebuild_logical_monitors_derived (manager, config); +} + +void +meta_monitor_manager_rebuild_derived (MetaMonitorManager *manager, + MetaMonitorsConfig *config) +{ + MetaMonitorManagerClass *klass = META_MONITOR_MANAGER_GET_CLASS (manager); + GList *old_logical_monitors; + + meta_monitor_manager_update_monitor_modes_derived (manager); + + if (klass->update_screen_size_derived) + klass->update_screen_size_derived (manager, config); + + if (manager->in_init) + return; + + old_logical_monitors = manager->logical_monitors; + + meta_monitor_manager_update_logical_state_derived (manager, config); + + meta_monitor_manager_notify_monitors_changed (manager); + + g_list_free_full (old_logical_monitors, g_object_unref); +} + +void +meta_output_parse_edid (MetaOutput *output, + GBytes *edid) +{ + MonitorInfo *parsed_edid; + gsize len; + + if (!edid) + goto out; + + parsed_edid = decode_edid (g_bytes_get_data (edid, &len)); + + if (parsed_edid) + { + output->vendor = g_strndup (parsed_edid->manufacturer_code, 4); + if (!g_utf8_validate (output->vendor, -1, NULL)) + g_clear_pointer (&output->vendor, g_free); + + output->product = g_strndup (parsed_edid->dsc_product_name, 14); + if (!g_utf8_validate (output->product, -1, NULL) || + output->product[0] == '\0') + { + g_clear_pointer (&output->product, g_free); + output->product = g_strdup_printf ("0x%04x", (unsigned) parsed_edid->product_code); + } + + output->serial = g_strndup (parsed_edid->dsc_serial_number, 14); + if (!g_utf8_validate (output->serial, -1, NULL) || + output->serial[0] == '\0') + { + g_clear_pointer (&output->serial, g_free); + output->serial = g_strdup_printf ("0x%08x", parsed_edid->serial_number); + } + + g_free (parsed_edid); + } + + out: + if (!output->vendor) + output->vendor = g_strdup ("unknown"); + if (!output->product) + output->product = g_strdup ("unknown"); + if (!output->serial) + output->serial = g_strdup ("unknown"); +} + +gboolean +meta_output_is_laptop (MetaOutput *output) +{ + /* FIXME: extend with better heuristics */ + switch (output->connector_type) + { + case META_CONNECTOR_TYPE_eDP: + case META_CONNECTOR_TYPE_LVDS: + case META_CONNECTOR_TYPE_DSI: + return TRUE; + default: + return FALSE; + } +} + +void +meta_monitor_manager_on_hotplug (MetaMonitorManager *manager) +{ + meta_monitor_manager_ensure_configured (manager); +} + +static gboolean +calculate_viewport_matrix (MetaMonitorManager *manager, + MetaLogicalMonitor *logical_monitor, + gfloat viewport[6]) +{ + gfloat x, y, width, height; + + x = (float) logical_monitor->rect.x / manager->screen_width; + y = (float) logical_monitor->rect.y / manager->screen_height; + width = (float) logical_monitor->rect.width / manager->screen_width; + height = (float) logical_monitor->rect.height / manager->screen_height; + + viewport[0] = width; + viewport[1] = 0.0f; + viewport[2] = x; + viewport[3] = 0.0f; + viewport[4] = height; + viewport[5] = y; + + return TRUE; +} + +static inline void +multiply_matrix (float a[6], + float b[6], + float res[6]) +{ + res[0] = a[0] * b[0] + a[1] * b[3]; + res[1] = a[0] * b[1] + a[1] * b[4]; + res[2] = a[0] * b[2] + a[1] * b[5] + a[2]; + res[3] = a[3] * b[0] + a[4] * b[3]; + res[4] = a[3] * b[1] + a[4] * b[4]; + res[5] = a[3] * b[2] + a[4] * b[5] + a[5]; +} + +gboolean +meta_monitor_manager_get_monitor_matrix (MetaMonitorManager *manager, + MetaMonitor *monitor, + MetaLogicalMonitor *logical_monitor, + gfloat matrix[6]) +{ + MetaMonitorTransform transform; + gfloat viewport[9]; + + if (!calculate_viewport_matrix (manager, logical_monitor, viewport)) + return FALSE; + + /* Get transform corrected for LCD panel-orientation. */ + transform = logical_monitor->transform; + transform = meta_monitor_logical_to_crtc_transform (monitor, transform); + multiply_matrix (viewport, transform_matrices[transform], + matrix); + return TRUE; +} + +/** + * meta_monitor_manager_get_monitor_for_connector: + * @manager: A #MetaMonitorManager + * @connector: A valid connector name + * + * Returns: The monitor index or -1 if @id isn't valid or the connector + * isn't associated with a logical monitor. + */ +gint +meta_monitor_manager_get_monitor_for_connector (MetaMonitorManager *manager, + const char *connector) +{ + GList *l; + + for (l = manager->monitors; l; l = l->next) + { + MetaMonitor *monitor = l->data; + + if (meta_monitor_is_active (monitor) && + g_str_equal (connector, meta_monitor_get_connector (monitor))) + return meta_monitor_get_logical_monitor (monitor)->number; + } + + return -1; +} + +/** + * meta_monitor_manager_get_is_builtin_display_on: + * @manager: A #MetaMonitorManager object + * + * Returns whether the built-in display (i.e. a laptop panel) is turned on. + */ +gboolean +meta_monitor_manager_get_is_builtin_display_on (MetaMonitorManager *manager) +{ + MetaMonitor *laptop_panel; + + g_return_val_if_fail (META_IS_MONITOR_MANAGER (manager), FALSE); + + laptop_panel = meta_monitor_manager_get_laptop_panel (manager); + if (!laptop_panel) + return FALSE; + + return meta_monitor_is_active (laptop_panel); +} + +void +meta_monitor_manager_rotate_monitor (MetaMonitorManager *manager) +{ + GError *error = NULL; + MetaMonitorsConfig *config = + meta_monitor_config_manager_create_for_rotate_monitor (manager->config_manager); + + if (!config) + return; + + if (!meta_monitor_manager_apply_monitors_config (manager, + config, + META_MONITORS_CONFIG_METHOD_TEMPORARY, + &error)) + { + g_warning ("Failed to use rotate monitor configuration: %s", + error->message); + g_error_free (error); + } + g_object_unref (config); +} + +void +meta_monitor_manager_switch_config (MetaMonitorManager *manager, + MetaMonitorSwitchConfigType config_type) +{ + GError *error = NULL; + MetaMonitorsConfig *config; + + g_return_if_fail (config_type != META_MONITOR_SWITCH_CONFIG_UNKNOWN); + + config = + meta_monitor_config_manager_create_for_switch_config (manager->config_manager, + config_type); + if (!config) + return; + + if (!meta_monitor_manager_apply_monitors_config (manager, + config, + META_MONITORS_CONFIG_METHOD_TEMPORARY, + &error)) + { + g_warning ("Failed to use switch monitor configuration: %s", + error->message); + g_error_free (error); + } + else + { + manager->current_switch_config = config_type; + } + g_object_unref (config); +} + +gboolean +meta_monitor_manager_can_switch_config (MetaMonitorManager *manager) +{ + return (!meta_backend_is_lid_closed (manager->backend) && + g_list_length (manager->monitors) > 1); +} + +MetaMonitorSwitchConfigType +meta_monitor_manager_get_switch_config (MetaMonitorManager *manager) +{ + return manager->current_switch_config; +} + +MetaMonitorConfigManager * +meta_monitor_manager_get_config_manager (MetaMonitorManager *manager) +{ + return manager->config_manager; +} + +/** + * meta_monitor_manager_get_vendor_name: + * @manager: A #MetaMonitorManager object + * @vendor: the PNP ID of the monitor + * + * Find the full vendor name from the given monitor PNP ID. + * + * Returns: (transfer full): A string containing the vendor name, + * or NULL when not found. + */ +char * +meta_monitor_manager_get_vendor_name (MetaMonitorManager *manager, + const char *vendor) +{ + if (!manager->pnp_ids) + manager->pnp_ids = gnome_pnp_ids_new (); + + return gnome_pnp_ids_get_pnp_id (manager->pnp_ids, vendor); +} diff --git a/src/backends/meta-monitor-transform.c b/src/backends/meta-monitor-transform.c new file mode 100644 index 000000000..d6b1f8b45 --- /dev/null +++ b/src/backends/meta-monitor-transform.c @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2018 Robert Mader + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include "backends/meta-monitor-transform.h" + +MetaMonitorTransform +meta_monitor_transform_invert (MetaMonitorTransform transform) +{ + switch (transform) + { + case META_MONITOR_TRANSFORM_90: + return META_MONITOR_TRANSFORM_270; + case META_MONITOR_TRANSFORM_270: + return META_MONITOR_TRANSFORM_90; + case META_MONITOR_TRANSFORM_NORMAL: + case META_MONITOR_TRANSFORM_180: + case META_MONITOR_TRANSFORM_FLIPPED: + case META_MONITOR_TRANSFORM_FLIPPED_90: + case META_MONITOR_TRANSFORM_FLIPPED_180: + case META_MONITOR_TRANSFORM_FLIPPED_270: + return transform; + } + g_assert_not_reached (); + return 0; +} + +MetaMonitorTransform +meta_monitor_transform_transform (MetaMonitorTransform transform, + MetaMonitorTransform other) +{ + MetaMonitorTransform new_transform; + + new_transform = (transform + other) % META_MONITOR_TRANSFORM_FLIPPED; + if (meta_monitor_transform_is_flipped (transform) != + meta_monitor_transform_is_flipped (other)) + new_transform += META_MONITOR_TRANSFORM_FLIPPED; + + return new_transform; +} + +/** + * meta_monitor_transform_relative_transform: + * @transform: The transform to start from + * @other: The transform to go to + * + * Return value: a transform to get from @transform to @other + */ +MetaMonitorTransform +meta_monitor_transform_relative_transform (MetaMonitorTransform transform, + MetaMonitorTransform other) +{ + MetaMonitorTransform relative_transform; + + relative_transform = ((other % META_MONITOR_TRANSFORM_FLIPPED - + transform % META_MONITOR_TRANSFORM_FLIPPED) % + META_MONITOR_TRANSFORM_FLIPPED); + + if (meta_monitor_transform_is_flipped (transform) != + meta_monitor_transform_is_flipped (other)) + { + relative_transform = (meta_monitor_transform_invert (relative_transform) + + META_MONITOR_TRANSFORM_FLIPPED); + } + + return relative_transform; +} + +void +meta_monitor_transform_transform_point (MetaMonitorTransform transform, + int area_width, + int area_height, + int x, + int y, + int *out_x, + int *out_y) +{ + switch (transform) + { + case META_MONITOR_TRANSFORM_NORMAL: + *out_x = x; + *out_y = y; + break; + case META_MONITOR_TRANSFORM_90: + *out_x = area_width - y; + *out_y = x; + break; + case META_MONITOR_TRANSFORM_180: + *out_x = area_width - x; + *out_y = area_height - y; + break; + case META_MONITOR_TRANSFORM_270: + *out_x = y, + *out_y = area_height - x; + break; + case META_MONITOR_TRANSFORM_FLIPPED: + *out_x = area_width - x; + *out_y = y; + break; + case META_MONITOR_TRANSFORM_FLIPPED_90: + *out_x = area_width - y; + *out_y = area_height - x; + break; + case META_MONITOR_TRANSFORM_FLIPPED_180: + *out_x = x; + *out_y = area_height - y; + break; + case META_MONITOR_TRANSFORM_FLIPPED_270: + *out_x = y; + *out_y = x; + break; + } +} diff --git a/src/backends/meta-monitor-transform.h b/src/backends/meta-monitor-transform.h new file mode 100644 index 000000000..6fca0a4e3 --- /dev/null +++ b/src/backends/meta-monitor-transform.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2013 Red Hat Inc. + * Copyright (C) 2018 Robert Mader + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef META_MONITOR_TRANSFORM_H +#define META_MONITOR_TRANSFORM_H + +#include <glib-object.h> + +#include "backends/meta-backend-types.h" +#include "core/util-private.h" + +enum _MetaMonitorTransform +{ + META_MONITOR_TRANSFORM_NORMAL, + META_MONITOR_TRANSFORM_90, + META_MONITOR_TRANSFORM_180, + META_MONITOR_TRANSFORM_270, + META_MONITOR_TRANSFORM_FLIPPED, + META_MONITOR_TRANSFORM_FLIPPED_90, + META_MONITOR_TRANSFORM_FLIPPED_180, + META_MONITOR_TRANSFORM_FLIPPED_270, +}; +#define META_MONITOR_N_TRANSFORMS (META_MONITOR_TRANSFORM_FLIPPED_270 + 1) + +/* Returns true if transform causes width and height to be inverted + This is true for the odd transforms in the enum */ +static inline gboolean +meta_monitor_transform_is_rotated (MetaMonitorTransform transform) +{ + return (transform % 2); +} + +/* Returns true if transform involves flipping */ +static inline gboolean +meta_monitor_transform_is_flipped (MetaMonitorTransform transform) +{ + return (abs(transform) >= META_MONITOR_TRANSFORM_FLIPPED); +} + +MetaMonitorTransform meta_monitor_transform_invert (MetaMonitorTransform transform); + +META_EXPORT_TEST +MetaMonitorTransform meta_monitor_transform_transform (MetaMonitorTransform transform, + MetaMonitorTransform other); + +MetaMonitorTransform meta_monitor_transform_relative_transform (MetaMonitorTransform transform, + MetaMonitorTransform other); + +void meta_monitor_transform_transform_point (MetaMonitorTransform transform, + int area_width, + int area_height, + int x, + int y, + int *out_x, + int *out_y); + +#endif /* META_MONITOR_TRANSFORM_H */ diff --git a/src/backends/meta-monitor.c b/src/backends/meta-monitor.c new file mode 100644 index 000000000..bd6da5c6e --- /dev/null +++ b/src/backends/meta-monitor.c @@ -0,0 +1,1912 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "backends/meta-monitor.h" + +#include "backends/meta-backend-private.h" +#include "backends/meta-crtc.h" +#include "backends/meta-gpu.h" +#include "backends/meta-monitor-manager-private.h" +#include "backends/meta-settings-private.h" +#include "backends/meta-output.h" +#include "core/boxes-private.h" + +#define SCALE_FACTORS_PER_INTEGER 4 +#define SCALE_FACTORS_STEPS (1.0 / (float) SCALE_FACTORS_PER_INTEGER) +#define MINIMUM_SCALE_FACTOR 1.0f +#define MAXIMUM_SCALE_FACTOR 4.0f +#define MINIMUM_LOGICAL_AREA (800 * 480) +#define MAXIMUM_REFRESH_RATE_DIFF 0.001 + +typedef struct _MetaMonitorMode +{ + MetaMonitor *monitor; + char *id; + MetaMonitorModeSpec spec; + MetaMonitorCrtcMode *crtc_modes; +} MetaMonitorMode; + +typedef struct _MetaMonitorModeTiled +{ + MetaMonitorMode parent; + + gboolean is_tiled; +} MetaMonitorModeTiled; + +typedef struct _MetaMonitorPrivate +{ + MetaGpu *gpu; + + GList *outputs; + GList *modes; + GHashTable *mode_ids; + + MetaMonitorMode *preferred_mode; + MetaMonitorMode *current_mode; + + MetaMonitorSpec *spec; + + MetaLogicalMonitor *logical_monitor; + + /* + * The primary or first output for this monitor, 0 if we can't figure out. + * It can be matched to a winsys_id of a MetaOutput. + * + * This is used as an opaque token on reconfiguration when switching from + * clone to extened, to decide on what output the windows should go next + * (it's an attempt to keep windows on the same monitor, and preferably on + * the primary one). + */ + uint64_t winsys_id; + + char *display_name; +} MetaMonitorPrivate; + +G_DEFINE_TYPE_WITH_PRIVATE (MetaMonitor, meta_monitor, G_TYPE_OBJECT) + +struct _MetaMonitorNormal +{ + MetaMonitor parent; +}; + +G_DEFINE_TYPE (MetaMonitorNormal, meta_monitor_normal, META_TYPE_MONITOR) + +struct _MetaMonitorTiled +{ + MetaMonitor parent; + + MetaMonitorManager *monitor_manager; + + uint32_t tile_group_id; + + /* The tile (0, 0) output. */ + MetaOutput *origin_output; + + /* The output enabled even when a non-tiled mode is used. */ + MetaOutput *main_output; +}; + +G_DEFINE_TYPE (MetaMonitorTiled, meta_monitor_tiled, META_TYPE_MONITOR) + +static void +meta_monitor_mode_free (MetaMonitorMode *mode); + +MetaMonitorSpec * +meta_monitor_spec_clone (MetaMonitorSpec *monitor_spec) +{ + MetaMonitorSpec *new_monitor_spec; + + new_monitor_spec = g_new0 (MetaMonitorSpec, 1); + *new_monitor_spec = (MetaMonitorSpec) { + .connector = g_strdup (monitor_spec->connector), + .vendor = g_strdup (monitor_spec->vendor), + .product = g_strdup (monitor_spec->product), + .serial = g_strdup (monitor_spec->serial), + }; + + return new_monitor_spec; +} + +gboolean +meta_monitor_spec_equals (MetaMonitorSpec *monitor_spec, + MetaMonitorSpec *other_monitor_spec) +{ + return (g_str_equal (monitor_spec->connector, other_monitor_spec->connector) && + g_str_equal (monitor_spec->vendor, other_monitor_spec->vendor) && + g_str_equal (monitor_spec->product, other_monitor_spec->product) && + g_str_equal (monitor_spec->serial, other_monitor_spec->serial)); +} + +int +meta_monitor_spec_compare (MetaMonitorSpec *monitor_spec_a, + MetaMonitorSpec *monitor_spec_b) +{ + int ret; + + ret = strcmp (monitor_spec_a->connector, monitor_spec_b->connector); + if (ret != 0) + return ret; + + ret = strcmp (monitor_spec_a->vendor, monitor_spec_b->vendor); + if (ret != 0) + return ret; + + ret = strcmp (monitor_spec_a->product, monitor_spec_b->product); + if (ret != 0) + return ret; + + return strcmp (monitor_spec_a->serial, monitor_spec_b->serial); +} + +void +meta_monitor_spec_free (MetaMonitorSpec *monitor_spec) +{ + g_free (monitor_spec->connector); + g_free (monitor_spec->vendor); + g_free (monitor_spec->product); + g_free (monitor_spec->serial); + g_free (monitor_spec); +} + +static void +meta_monitor_generate_spec (MetaMonitor *monitor) +{ + MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor); + MetaOutput *output = meta_monitor_get_main_output (monitor); + MetaMonitorSpec *monitor_spec; + + monitor_spec = g_new0 (MetaMonitorSpec, 1); + *monitor_spec = (MetaMonitorSpec) { + .connector = g_strdup (output->name), + .vendor = g_strdup (output->vendor), + .product = g_strdup (output->product), + .serial = g_strdup (output->serial), + }; + + priv->spec = monitor_spec; +} + +static const double known_diagonals[] = { + 12.1, + 13.3, + 15.6 +}; + +static char * +diagonal_to_str (double d) +{ + unsigned int i; + + for (i = 0; i < G_N_ELEMENTS (known_diagonals); i++) + { + double delta; + + delta = fabs(known_diagonals[i] - d); + if (delta < 0.1) + return g_strdup_printf ("%0.1lf\"", known_diagonals[i]); + } + + return g_strdup_printf ("%d\"", (int) (d + 0.5)); +} + +static char * +meta_monitor_make_display_name (MetaMonitor *monitor, + MetaMonitorManager *monitor_manager) +{ + g_autofree char *inches = NULL; + g_autofree char *vendor_name = NULL; + const char *vendor = NULL; + const char *product_name = NULL; + int width_mm; + int height_mm; + + meta_monitor_get_physical_dimensions (monitor, &width_mm, &height_mm); + + if (meta_monitor_is_laptop_panel (monitor)) + return g_strdup (_("Built-in display")); + + if (width_mm > 0 && height_mm > 0) + { + if (!meta_monitor_has_aspect_as_size (monitor)) + { + double d = sqrt (width_mm * width_mm + + height_mm * height_mm); + inches = diagonal_to_str (d / 25.4); + } + else + { + product_name = meta_monitor_get_product (monitor); + } + } + + vendor = meta_monitor_get_vendor (monitor); + + if (g_strcmp0 (vendor, "unknown") != 0) + { + vendor_name = meta_monitor_manager_get_vendor_name (monitor_manager, + vendor); + + if (!vendor_name) + vendor_name = g_strdup (vendor); + } + else + { + if (inches != NULL) + vendor_name = g_strdup (_("Unknown")); + else + vendor_name = g_strdup (_("Unknown Display")); + } + + if (inches != NULL) + { + /**/ + return g_strdup_printf (C_("This is a monitor vendor name, followed by a " + "size in inches, like 'Dell 15\"'", + "%s %s"), + vendor_name, inches); + } + else if (product_name != NULL) + { + return g_strdup_printf (C_("This is a monitor vendor name followed by " + "product/model name where size in inches " + "could not be calculated, e.g. Dell U2414H", + "%s %s"), + vendor_name, product_name); + } + else + { + return g_strdup (vendor_name); + } +} + +MetaGpu * +meta_monitor_get_gpu (MetaMonitor *monitor) +{ + MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor); + + return priv->gpu; +} + +GList * +meta_monitor_get_outputs (MetaMonitor *monitor) +{ + MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor); + + return priv->outputs; +} + +MetaOutput * +meta_monitor_get_main_output (MetaMonitor *monitor) +{ + return META_MONITOR_GET_CLASS (monitor)->get_main_output (monitor); +} + +gboolean +meta_monitor_is_active (MetaMonitor *monitor) +{ + MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor); + + return !!priv->current_mode; +} + +gboolean +meta_monitor_is_primary (MetaMonitor *monitor) +{ + MetaOutput *output; + + output = meta_monitor_get_main_output (monitor); + + return output->is_primary; +} + +gboolean +meta_monitor_supports_underscanning (MetaMonitor *monitor) +{ + MetaOutput *output; + + output = meta_monitor_get_main_output (monitor); + + return output->supports_underscanning; +} + +gboolean +meta_monitor_is_underscanning (MetaMonitor *monitor) +{ + MetaOutput *output; + + output = meta_monitor_get_main_output (monitor); + + return output->is_underscanning; +} + +gboolean +meta_monitor_is_laptop_panel (MetaMonitor *monitor) +{ + MetaOutput *output; + + output = meta_monitor_get_main_output (monitor); + + switch (output->connector_type) + { + case META_CONNECTOR_TYPE_eDP: + case META_CONNECTOR_TYPE_LVDS: + case META_CONNECTOR_TYPE_DSI: + return TRUE; + default: + return FALSE; + } +} + +gboolean +meta_monitor_is_same_as (MetaMonitor *monitor, + MetaMonitor *other_monitor) +{ + MetaMonitorPrivate *priv = + meta_monitor_get_instance_private (monitor); + MetaMonitorPrivate *other_priv = + meta_monitor_get_instance_private (other_monitor); + + return priv->winsys_id == other_priv->winsys_id; +} + +void +meta_monitor_get_current_resolution (MetaMonitor *monitor, + int *width, + int *height) +{ + MetaMonitorMode *mode = meta_monitor_get_current_mode (monitor); + + *width = mode->spec.width; + *height = mode->spec.height; +} + +void +meta_monitor_derive_layout (MetaMonitor *monitor, + MetaRectangle *layout) +{ + META_MONITOR_GET_CLASS (monitor)->derive_layout (monitor, layout); +} + +void +meta_monitor_get_physical_dimensions (MetaMonitor *monitor, + int *width_mm, + int *height_mm) +{ + MetaOutput *output; + + output = meta_monitor_get_main_output (monitor); + *width_mm = output->width_mm; + *height_mm = output->height_mm; +} + +CoglSubpixelOrder +meta_monitor_get_subpixel_order (MetaMonitor *monitor) +{ + MetaOutput *output; + + output = meta_monitor_get_main_output (monitor); + return output->subpixel_order; +} + +const char * +meta_monitor_get_connector (MetaMonitor *monitor) +{ + MetaOutput *output; + + output = meta_monitor_get_main_output (monitor); + return output->name; +} + +const char * +meta_monitor_get_vendor (MetaMonitor *monitor) +{ + MetaOutput *output; + + output = meta_monitor_get_main_output (monitor); + return output->vendor; +} + +const char * +meta_monitor_get_product (MetaMonitor *monitor) +{ + MetaOutput *output; + + output = meta_monitor_get_main_output (monitor); + return output->product; +} + +const char * +meta_monitor_get_serial (MetaMonitor *monitor) +{ + MetaOutput *output; + + output = meta_monitor_get_main_output (monitor); + return output->serial; +} + +MetaConnectorType +meta_monitor_get_connector_type (MetaMonitor *monitor) +{ + MetaOutput *output; + + output = meta_monitor_get_main_output (monitor); + return output->connector_type; +} + +MetaMonitorTransform +meta_monitor_logical_to_crtc_transform (MetaMonitor *monitor, + MetaMonitorTransform transform) +{ + MetaOutput *output = meta_monitor_get_main_output (monitor); + + return meta_output_logical_to_crtc_transform (output, transform); +} + +MetaMonitorTransform +meta_monitor_crtc_to_logical_transform (MetaMonitor *monitor, + MetaMonitorTransform transform) +{ + MetaOutput *output = meta_monitor_get_main_output (monitor); + + return meta_output_crtc_to_logical_transform (output, transform); +} + +static void +meta_monitor_dispose (GObject *object) +{ + MetaMonitor *monitor = META_MONITOR (object); + MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor); + + if (priv->outputs) + { + g_list_free_full (priv->outputs, g_object_unref); + priv->outputs = NULL; + } + + G_OBJECT_CLASS (meta_monitor_parent_class)->dispose (object); +} + +static void +meta_monitor_finalize (GObject *object) +{ + MetaMonitor *monitor = META_MONITOR (object); + MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor); + + g_hash_table_destroy (priv->mode_ids); + g_list_free_full (priv->modes, (GDestroyNotify) meta_monitor_mode_free); + meta_monitor_spec_free (priv->spec); + g_free (priv->display_name); + + G_OBJECT_CLASS (meta_monitor_parent_class)->finalize (object); +} + +static void +meta_monitor_init (MetaMonitor *monitor) +{ + MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor); + + priv->mode_ids = g_hash_table_new (g_str_hash, g_str_equal); +} + +static void +meta_monitor_class_init (MetaMonitorClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = meta_monitor_dispose; + object_class->finalize = meta_monitor_finalize; +} + +static char * +generate_mode_id (MetaMonitorModeSpec *monitor_mode_spec) +{ + gboolean is_interlaced; + char refresh_rate_str[G_ASCII_DTOSTR_BUF_SIZE]; + + is_interlaced = !!(monitor_mode_spec->flags & META_CRTC_MODE_FLAG_INTERLACE); + g_ascii_dtostr (refresh_rate_str, G_ASCII_DTOSTR_BUF_SIZE, + monitor_mode_spec->refresh_rate); + + return g_strdup_printf ("%dx%d%s@%s", + monitor_mode_spec->width, + monitor_mode_spec->height, + is_interlaced ? "i" : "", + refresh_rate_str); +} + +static gboolean +meta_monitor_add_mode (MetaMonitor *monitor, + MetaMonitorMode *monitor_mode, + gboolean replace) +{ + MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor); + MetaMonitorMode *existing_mode; + + existing_mode = g_hash_table_lookup (priv->mode_ids, + meta_monitor_mode_get_id (monitor_mode)); + if (existing_mode && !replace) + return FALSE; + + if (existing_mode) + priv->modes = g_list_remove (priv->modes, existing_mode); + + priv->modes = g_list_append (priv->modes, monitor_mode); + g_hash_table_replace (priv->mode_ids, monitor_mode->id, monitor_mode); + + return TRUE; +} + +static MetaMonitorModeSpec +meta_monitor_create_spec (MetaMonitor *monitor, + int width, + int height, + MetaCrtcMode *crtc_mode) +{ + MetaOutput *output = meta_monitor_get_main_output (monitor); + + if (meta_monitor_transform_is_rotated (output->panel_orientation_transform)) + { + int temp = width; + width = height; + height = temp; + } + + return (MetaMonitorModeSpec) { + .width = width, + .height = height, + .refresh_rate = crtc_mode->refresh_rate, + .flags = crtc_mode->flags & HANDLED_CRTC_MODE_FLAGS + }; +} + +static void +meta_monitor_normal_generate_modes (MetaMonitorNormal *monitor_normal) +{ + MetaMonitor *monitor = META_MONITOR (monitor_normal); + MetaMonitorPrivate *monitor_priv = + meta_monitor_get_instance_private (monitor); + MetaOutput *output; + MetaCrtcModeFlag preferred_mode_flags; + unsigned int i; + + output = meta_monitor_get_main_output (monitor); + preferred_mode_flags = output->preferred_mode->flags; + + for (i = 0; i < output->n_modes; i++) + { + MetaCrtcMode *crtc_mode = output->modes[i]; + MetaCrtc *crtc; + MetaMonitorMode *mode; + gboolean replace; + + mode = g_new0 (MetaMonitorMode, 1); + mode->monitor = monitor; + mode->spec = meta_monitor_create_spec (monitor, + crtc_mode->width, + crtc_mode->height, + crtc_mode); + mode->id = generate_mode_id (&mode->spec); + mode->crtc_modes = g_new (MetaMonitorCrtcMode, 1); + mode->crtc_modes[0] = (MetaMonitorCrtcMode) { + .output = output, + .crtc_mode = crtc_mode + }; + + /* + * We don't distinguish between all available mode flags, just the ones + * that are configurable. We still need to pick some mode though, so + * prefer ones that has the same set of flags as the preferred mode; + * otherwise take the first one in the list. This guarantees that the + * preferred mode is always added. + */ + replace = crtc_mode->flags == preferred_mode_flags; + + if (!meta_monitor_add_mode (monitor, mode, replace)) + { + g_assert (crtc_mode != output->preferred_mode); + meta_monitor_mode_free (mode); + continue; + } + + if (crtc_mode == output->preferred_mode) + monitor_priv->preferred_mode = mode; + + crtc = meta_output_get_assigned_crtc (output); + if (crtc && crtc->config && crtc_mode == crtc->config->mode) + monitor_priv->current_mode = mode; + } +} + +MetaMonitorNormal * +meta_monitor_normal_new (MetaGpu *gpu, + MetaMonitorManager *monitor_manager, + MetaOutput *output) +{ + MetaMonitorNormal *monitor_normal; + MetaMonitor *monitor; + MetaMonitorPrivate *monitor_priv; + + monitor_normal = g_object_new (META_TYPE_MONITOR_NORMAL, NULL); + monitor = META_MONITOR (monitor_normal); + monitor_priv = meta_monitor_get_instance_private (monitor); + + monitor_priv->gpu = gpu; + + monitor_priv->outputs = g_list_append (NULL, g_object_ref (output)); + monitor_priv->winsys_id = output->winsys_id; + meta_monitor_generate_spec (monitor); + + meta_monitor_normal_generate_modes (monitor_normal); + + monitor_priv->display_name = meta_monitor_make_display_name (monitor, + monitor_manager); + + return monitor_normal; +} + +static MetaOutput * +meta_monitor_normal_get_main_output (MetaMonitor *monitor) +{ + MetaMonitorPrivate *monitor_priv = + meta_monitor_get_instance_private (monitor); + + return monitor_priv->outputs->data; +} + +static void +meta_monitor_normal_derive_layout (MetaMonitor *monitor, + MetaRectangle *layout) +{ + MetaOutput *output; + MetaCrtc *crtc; + MetaCrtcConfig *crtc_config; + + output = meta_monitor_get_main_output (monitor); + crtc = meta_output_get_assigned_crtc (output); + crtc_config = crtc->config; + + g_return_if_fail (crtc_config); + + meta_rectangle_from_graphene_rect (&crtc_config->layout, + META_ROUNDING_STRATEGY_ROUND, + layout); +} + +static gboolean +meta_monitor_normal_get_suggested_position (MetaMonitor *monitor, + int *x, + int *y) +{ + MetaOutput *output; + + output = meta_monitor_get_main_output (monitor); + if (output->suggested_x < 0 && output->suggested_y < 0) + return FALSE; + + if (x) + *x = output->suggested_x; + + if (y) + *y = output->suggested_y; + + return TRUE; +} + +static void +meta_monitor_normal_calculate_crtc_pos (MetaMonitor *monitor, + MetaMonitorMode *monitor_mode, + MetaOutput *output, + MetaMonitorTransform crtc_transform, + int *out_x, + int *out_y) +{ + *out_x = 0; + *out_y = 0; +} + +static void +meta_monitor_normal_init (MetaMonitorNormal *monitor) +{ +} + +static void +meta_monitor_normal_class_init (MetaMonitorNormalClass *klass) +{ + MetaMonitorClass *monitor_class = META_MONITOR_CLASS (klass); + + monitor_class->get_main_output = meta_monitor_normal_get_main_output; + monitor_class->derive_layout = meta_monitor_normal_derive_layout; + monitor_class->calculate_crtc_pos = meta_monitor_normal_calculate_crtc_pos; + monitor_class->get_suggested_position = meta_monitor_normal_get_suggested_position; +} + +uint32_t +meta_monitor_tiled_get_tile_group_id (MetaMonitorTiled *monitor_tiled) +{ + return monitor_tiled->tile_group_id; +} + +gboolean +meta_monitor_get_suggested_position (MetaMonitor *monitor, + int *x, + int *y) +{ + return META_MONITOR_GET_CLASS (monitor)->get_suggested_position (monitor, + x, y); +} + +static void +add_tiled_monitor_outputs (MetaGpu *gpu, + MetaMonitorTiled *monitor_tiled) +{ + MetaMonitorPrivate *monitor_priv = + meta_monitor_get_instance_private (META_MONITOR (monitor_tiled)); + GList *outputs; + GList *l; + + outputs = meta_gpu_get_outputs (gpu); + for (l = outputs; l; l = l->next) + { + MetaOutput *output = l->data; + + if (output->tile_info.group_id != monitor_tiled->tile_group_id) + continue; + + g_warn_if_fail (output->subpixel_order == + monitor_tiled->origin_output->subpixel_order); + + monitor_priv->outputs = g_list_append (monitor_priv->outputs, + g_object_ref (output)); + } +} + +static void +calculate_tile_coordinate (MetaMonitor *monitor, + MetaOutput *output, + MetaMonitorTransform crtc_transform, + int *out_x, + int *out_y) +{ + MetaMonitorPrivate *monitor_priv = + meta_monitor_get_instance_private (monitor); + GList *l; + int x = 0; + int y = 0; + + for (l = monitor_priv->outputs; l; l = l->next) + { + MetaOutput *other_output = l->data; + + switch (crtc_transform) + { + case META_MONITOR_TRANSFORM_NORMAL: + case META_MONITOR_TRANSFORM_FLIPPED: + if (other_output->tile_info.loc_v_tile == output->tile_info.loc_v_tile && + other_output->tile_info.loc_h_tile < output->tile_info.loc_h_tile) + x += other_output->tile_info.tile_w; + if (other_output->tile_info.loc_h_tile == output->tile_info.loc_h_tile && + other_output->tile_info.loc_v_tile < output->tile_info.loc_v_tile) + y += other_output->tile_info.tile_h; + break; + case META_MONITOR_TRANSFORM_180: + case META_MONITOR_TRANSFORM_FLIPPED_180: + if (other_output->tile_info.loc_v_tile == output->tile_info.loc_v_tile && + other_output->tile_info.loc_h_tile > output->tile_info.loc_h_tile) + x += other_output->tile_info.tile_w; + if (other_output->tile_info.loc_h_tile == output->tile_info.loc_h_tile && + other_output->tile_info.loc_v_tile > output->tile_info.loc_v_tile) + y += other_output->tile_info.tile_h; + break; + case META_MONITOR_TRANSFORM_270: + case META_MONITOR_TRANSFORM_FLIPPED_270: + if (other_output->tile_info.loc_v_tile == output->tile_info.loc_v_tile && + other_output->tile_info.loc_h_tile > output->tile_info.loc_h_tile) + y += other_output->tile_info.tile_w; + if (other_output->tile_info.loc_h_tile == output->tile_info.loc_h_tile && + other_output->tile_info.loc_v_tile > output->tile_info.loc_v_tile) + x += other_output->tile_info.tile_h; + break; + case META_MONITOR_TRANSFORM_90: + case META_MONITOR_TRANSFORM_FLIPPED_90: + if (other_output->tile_info.loc_v_tile == output->tile_info.loc_v_tile && + other_output->tile_info.loc_h_tile < output->tile_info.loc_h_tile) + y += other_output->tile_info.tile_w; + if (other_output->tile_info.loc_h_tile == output->tile_info.loc_h_tile && + other_output->tile_info.loc_v_tile < output->tile_info.loc_v_tile) + x += other_output->tile_info.tile_h; + break; + } + } + + *out_x = x; + *out_y = y; +} + +static void +meta_monitor_tiled_calculate_tiled_size (MetaMonitor *monitor, + int *out_width, + int *out_height) +{ + MetaMonitorPrivate *monitor_priv = + meta_monitor_get_instance_private (monitor); + GList *l; + int width; + int height; + + width = 0; + height = 0; + for (l = monitor_priv->outputs; l; l = l->next) + { + MetaOutput *output = l->data; + + if (output->tile_info.loc_v_tile == 0) + width += output->tile_info.tile_w; + + if (output->tile_info.loc_h_tile == 0) + height += output->tile_info.tile_h; + } + + *out_width = width; + *out_height = height; +} + +static gboolean +is_monitor_mode_assigned (MetaMonitor *monitor, + MetaMonitorMode *mode) +{ + MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor); + GList *l; + int i; + + for (l = priv->outputs, i = 0; l; l = l->next, i++) + { + MetaOutput *output = l->data; + MetaMonitorCrtcMode *monitor_crtc_mode = &mode->crtc_modes[i]; + MetaCrtc *crtc; + + crtc = meta_output_get_assigned_crtc (output); + if (monitor_crtc_mode->crtc_mode && + (!crtc || !crtc->config || + crtc->config->mode != monitor_crtc_mode->crtc_mode)) + return FALSE; + else if (!monitor_crtc_mode->crtc_mode && crtc) + return FALSE; + } + + return TRUE; +} + +static gboolean +is_crtc_mode_tiled (MetaOutput *output, + MetaCrtcMode *crtc_mode) +{ + return (crtc_mode->width == (int) output->tile_info.tile_w && + crtc_mode->height == (int) output->tile_info.tile_h); +} + +static MetaCrtcMode * +find_tiled_crtc_mode (MetaOutput *output, + MetaCrtcMode *reference_crtc_mode) +{ + MetaCrtcMode *crtc_mode; + unsigned int i; + + crtc_mode = output->preferred_mode; + if (is_crtc_mode_tiled (output, crtc_mode)) + return crtc_mode; + + for (i = 0; i < output->n_modes; i++) + { + crtc_mode = output->modes[i]; + + if (!is_crtc_mode_tiled (output, crtc_mode)) + continue; + + if (crtc_mode->refresh_rate != reference_crtc_mode->refresh_rate) + continue; + + if (crtc_mode->flags != reference_crtc_mode->flags) + continue; + + return crtc_mode; + } + + return NULL; +} + +static MetaMonitorMode * +create_tiled_monitor_mode (MetaMonitorTiled *monitor_tiled, + MetaCrtcMode *reference_crtc_mode, + gboolean *out_is_preferred) +{ + MetaMonitor *monitor = META_MONITOR (monitor_tiled); + MetaMonitorPrivate *monitor_priv = + meta_monitor_get_instance_private (monitor); + MetaMonitorModeTiled *mode; + int width, height; + GList *l; + unsigned int i; + gboolean is_preferred = TRUE; + + mode = g_new0 (MetaMonitorModeTiled, 1); + mode->is_tiled = TRUE; + meta_monitor_tiled_calculate_tiled_size (monitor, &width, &height); + mode->parent.monitor = monitor; + mode->parent.spec = + meta_monitor_create_spec (monitor, width, height, reference_crtc_mode); + mode->parent.id = generate_mode_id (&mode->parent.spec); + + mode->parent.crtc_modes = g_new0 (MetaMonitorCrtcMode, + g_list_length (monitor_priv->outputs)); + for (l = monitor_priv->outputs, i = 0; l; l = l->next, i++) + { + MetaOutput *output = l->data; + MetaCrtcMode *tiled_crtc_mode; + + tiled_crtc_mode = find_tiled_crtc_mode (output, reference_crtc_mode); + if (!tiled_crtc_mode) + { + g_warning ("No tiled mode found on %s", output->name); + meta_monitor_mode_free ((MetaMonitorMode *) mode); + return NULL; + } + + mode->parent.crtc_modes[i] = (MetaMonitorCrtcMode) { + .output = output, + .crtc_mode = tiled_crtc_mode + }; + + is_preferred = is_preferred && tiled_crtc_mode == output->preferred_mode; + } + + *out_is_preferred = is_preferred; + + return (MetaMonitorMode *) mode; +} + +static void +generate_tiled_monitor_modes (MetaMonitorTiled *monitor_tiled) +{ + MetaMonitor *monitor = META_MONITOR (monitor_tiled); + MetaMonitorPrivate *monitor_priv = + meta_monitor_get_instance_private (monitor); + MetaOutput *main_output; + GList *tiled_modes = NULL; + unsigned int i; + MetaMonitorMode *best_mode = NULL; + GList *l; + + main_output = meta_monitor_get_main_output (META_MONITOR (monitor_tiled)); + + for (i = 0; i < main_output->n_modes; i++) + { + MetaCrtcMode *reference_crtc_mode = main_output->modes[i]; + MetaMonitorMode *mode; + gboolean is_preferred; + + if (!is_crtc_mode_tiled (main_output, reference_crtc_mode)) + continue; + + mode = create_tiled_monitor_mode (monitor_tiled, reference_crtc_mode, + &is_preferred); + if (!mode) + continue; + + tiled_modes = g_list_append (tiled_modes, mode); + + if (is_monitor_mode_assigned (monitor, mode)) + monitor_priv->current_mode = mode; + + if (is_preferred) + monitor_priv->preferred_mode = mode; + } + + while ((l = tiled_modes)) + { + MetaMonitorMode *mode = l->data; + + tiled_modes = g_list_remove_link (tiled_modes, l); + + if (!meta_monitor_add_mode (monitor, mode, FALSE)) + { + meta_monitor_mode_free (mode); + continue; + } + + if (!monitor_priv->preferred_mode) + { + if (!best_mode || + mode->spec.refresh_rate > best_mode->spec.refresh_rate) + best_mode = mode; + } + } + + if (best_mode) + monitor_priv->preferred_mode = best_mode; +} + +static MetaMonitorMode * +create_untiled_monitor_mode (MetaMonitorTiled *monitor_tiled, + MetaOutput *main_output, + MetaCrtcMode *crtc_mode) +{ + MetaMonitor *monitor = META_MONITOR (monitor_tiled); + MetaMonitorPrivate *monitor_priv = + meta_monitor_get_instance_private (monitor); + MetaMonitorModeTiled *mode; + GList *l; + int i; + + if (is_crtc_mode_tiled (main_output, crtc_mode)) + return NULL; + + mode = g_new0 (MetaMonitorModeTiled, 1); + mode->is_tiled = FALSE; + mode->parent.monitor = monitor; + mode->parent.spec = meta_monitor_create_spec (monitor, + crtc_mode->width, + crtc_mode->height, + crtc_mode); + mode->parent.id = generate_mode_id (&mode->parent.spec); + mode->parent.crtc_modes = g_new0 (MetaMonitorCrtcMode, + g_list_length (monitor_priv->outputs)); + + for (l = monitor_priv->outputs, i = 0; l; l = l->next, i++) + { + MetaOutput *output = l->data; + + if (output == main_output) + { + mode->parent.crtc_modes[i] = (MetaMonitorCrtcMode) { + .output = output, + .crtc_mode = crtc_mode + }; + } + else + { + mode->parent.crtc_modes[i] = (MetaMonitorCrtcMode) { + .output = output, + .crtc_mode = NULL + }; + } + } + + return &mode->parent; +} + +static int +count_untiled_crtc_modes (MetaOutput *output) +{ + int count; + unsigned int i; + + count = 0; + for (i = 0; i < output->n_modes; i++) + { + MetaCrtcMode *crtc_mode = output->modes[i]; + + if (!is_crtc_mode_tiled (output, crtc_mode)) + count++; + } + + return count; +} + +static MetaOutput * +find_untiled_output (MetaMonitorTiled *monitor_tiled) +{ + MetaMonitor *monitor = META_MONITOR (monitor_tiled); + MetaMonitorPrivate *monitor_priv = + meta_monitor_get_instance_private (monitor); + MetaOutput *best_output; + int best_untiled_crtc_mode_count; + GList *l; + + best_output = monitor_tiled->origin_output; + best_untiled_crtc_mode_count = + count_untiled_crtc_modes (monitor_tiled->origin_output); + + for (l = monitor_priv->outputs; l; l = l->next) + { + MetaOutput *output = l->data; + int untiled_crtc_mode_count; + + if (output == monitor_tiled->origin_output) + continue; + + untiled_crtc_mode_count = count_untiled_crtc_modes (output); + if (untiled_crtc_mode_count > best_untiled_crtc_mode_count) + { + best_untiled_crtc_mode_count = untiled_crtc_mode_count; + best_output = output; + } + } + + return best_output; +} + +static void +generate_untiled_monitor_modes (MetaMonitorTiled *monitor_tiled) +{ + MetaMonitor *monitor = META_MONITOR (monitor_tiled); + MetaMonitorPrivate *monitor_priv = + meta_monitor_get_instance_private (monitor); + MetaOutput *main_output; + unsigned int i; + + main_output = meta_monitor_get_main_output (monitor); + + for (i = 0; i < main_output->n_modes; i++) + { + MetaCrtcMode *crtc_mode = main_output->modes[i]; + MetaMonitorMode *mode; + + mode = create_untiled_monitor_mode (monitor_tiled, + main_output, + crtc_mode); + if (!mode) + continue; + + if (!meta_monitor_add_mode (monitor, mode, FALSE)) + { + meta_monitor_mode_free (mode); + continue; + } + + if (is_monitor_mode_assigned (monitor, mode)) + { + g_assert (!monitor_priv->current_mode); + monitor_priv->current_mode = mode; + } + + if (!monitor_priv->preferred_mode && + crtc_mode == main_output->preferred_mode) + monitor_priv->preferred_mode = mode; + } +} + +static MetaMonitorMode * +find_best_mode (MetaMonitor *monitor) +{ + MetaMonitorPrivate *monitor_priv = + meta_monitor_get_instance_private (monitor); + MetaMonitorMode *best_mode = NULL; + GList *l; + + for (l = monitor_priv->modes; l; l = l->next) + { + MetaMonitorMode *mode = l->data; + int area, best_area; + + if (!best_mode) + { + best_mode = mode; + continue; + } + + area = mode->spec.width * mode->spec.height; + best_area = best_mode->spec.width * best_mode->spec.height; + if (area > best_area) + { + best_mode = mode; + continue; + } + + if (mode->spec.refresh_rate > best_mode->spec.refresh_rate) + { + best_mode = mode; + continue; + } + } + + return best_mode; +} + +static void +meta_monitor_tiled_generate_modes (MetaMonitorTiled *monitor_tiled) +{ + MetaMonitor *monitor = META_MONITOR (monitor_tiled); + MetaMonitorPrivate *monitor_priv = + meta_monitor_get_instance_private (monitor); + + /* + * Tiled monitors may look a bit different from each other, depending on the + * monitor itself, the driver, etc. + * + * On some, the tiled modes will be the preferred CRTC modes, and running + * untiled is done by only enabling (0, 0) tile. In this case, things are + * pretty straight forward. + * + * Other times a monitor may have some bogus mode preferred on the main tile, + * and an untiled mode preferred on the non-main tile, and there seems to be + * no guarantee that the (0, 0) tile is the one that should drive the + * non-tiled mode. + * + * To handle both these cases, the following hueristics are implemented: + * + * 1) Find all the tiled CRTC modes of the (0, 0) tile, and create tiled + * monitor modes for all tiles based on these. + * 2) If there is any tiled monitor mode combination where all CRTC modes + * are the preferred ones, that one is marked as preferred. + * 3) If there is no preferred mode determined so far, assume the tiled + * monitor mode with the highest refresh rate is preferred. + * 4) Find the tile with highest number of untiled CRTC modes available, + * assume this is the one driving the monitor in untiled mode, and + * create monitor modes for all untiled CRTC modes of that tile. If + * there is still no preferred mode, set any untiled mode as preferred + * if the CRTC mode is marked as such. + * 5) If at this point there is still no preferred mode, just pick the one + * with the highest number of pixels and highest refresh rate. + * + * Note that this ignores the preference if the preference is a non-tiled + * mode. This seems to be the case on some systems, where the user tends to + * manually set up the tiled mode anyway. + */ + + generate_tiled_monitor_modes (monitor_tiled); + + if (!monitor_priv->preferred_mode) + g_warning ("Tiled monitor on %s didn't have any tiled modes", + monitor_priv->spec->connector); + + generate_untiled_monitor_modes (monitor_tiled); + + if (!monitor_priv->preferred_mode) + { + g_warning ("Tiled monitor on %s didn't have a valid preferred mode", + monitor_priv->spec->connector); + monitor_priv->preferred_mode = find_best_mode (monitor); + } +} + +MetaMonitorTiled * +meta_monitor_tiled_new (MetaGpu *gpu, + MetaMonitorManager *monitor_manager, + MetaOutput *output) +{ + MetaMonitorTiled *monitor_tiled; + MetaMonitor *monitor; + MetaMonitorPrivate *monitor_priv; + + monitor_tiled = g_object_new (META_TYPE_MONITOR_TILED, NULL); + monitor = META_MONITOR (monitor_tiled); + monitor_priv = meta_monitor_get_instance_private (monitor); + + monitor_priv->gpu = gpu; + + monitor_tiled->tile_group_id = output->tile_info.group_id; + monitor_priv->winsys_id = output->winsys_id; + + monitor_tiled->origin_output = output; + add_tiled_monitor_outputs (gpu, monitor_tiled); + + monitor_tiled->main_output = find_untiled_output (monitor_tiled); + + meta_monitor_generate_spec (monitor); + + monitor_tiled->monitor_manager = monitor_manager; + meta_monitor_manager_tiled_monitor_added (monitor_manager, + META_MONITOR (monitor_tiled)); + + meta_monitor_tiled_generate_modes (monitor_tiled); + + monitor_priv->display_name = meta_monitor_make_display_name (monitor, + monitor_manager); + + return monitor_tiled; +} + +static MetaOutput * +meta_monitor_tiled_get_main_output (MetaMonitor *monitor) +{ + MetaMonitorTiled *monitor_tiled = META_MONITOR_TILED (monitor); + + return monitor_tiled->main_output; +} + +static void +meta_monitor_tiled_derive_layout (MetaMonitor *monitor, + MetaRectangle *layout) +{ + MetaMonitorPrivate *monitor_priv = + meta_monitor_get_instance_private (monitor); + GList *l; + float min_x, min_y, max_x, max_y; + + min_x = FLT_MAX; + min_y = FLT_MAX; + max_x = 0.0; + max_y = 0.0; + for (l = monitor_priv->outputs; l; l = l->next) + { + MetaOutput *output = l->data; + MetaCrtc *crtc; + MetaCrtcConfig *crtc_config; + graphene_rect_t *crtc_layout; + + crtc = meta_output_get_assigned_crtc (output); + if (!crtc) + continue; + + crtc_config = crtc->config; + g_return_if_fail (crtc_config); + + crtc_layout = &crtc_config->layout; + + min_x = MIN (crtc_layout->origin.x, min_x); + min_y = MIN (crtc_layout->origin.y, min_y); + max_x = MAX (crtc_layout->origin.x + crtc_layout->size.width, max_x); + max_y = MAX (crtc_layout->origin.y + crtc_layout->size.height, max_y); + } + + *layout = (MetaRectangle) { + .x = roundf (min_x), + .y = roundf (min_y), + .width = roundf (max_x - min_x), + .height = roundf (max_y - min_y) + }; +} + +static gboolean +meta_monitor_tiled_get_suggested_position (MetaMonitor *monitor, + int *x, + int *y) +{ + return FALSE; +} + +static void +meta_monitor_tiled_calculate_crtc_pos (MetaMonitor *monitor, + MetaMonitorMode *monitor_mode, + MetaOutput *output, + MetaMonitorTransform crtc_transform, + int *out_x, + int *out_y) +{ + MetaMonitorModeTiled *mode_tiled = (MetaMonitorModeTiled *) monitor_mode; + + if (mode_tiled->is_tiled) + { + calculate_tile_coordinate (monitor, output, crtc_transform, + out_x, out_y); + } + else + { + *out_x = 0; + *out_y = 0; + } +} + +static void +meta_monitor_tiled_finalize (GObject *object) +{ + MetaMonitorTiled *monitor_tiled = META_MONITOR_TILED (object); + + meta_monitor_manager_tiled_monitor_removed (monitor_tiled->monitor_manager, + META_MONITOR (monitor_tiled)); + + G_OBJECT_CLASS (meta_monitor_tiled_parent_class)->finalize (object); +} + +static void +meta_monitor_tiled_init (MetaMonitorTiled *monitor) +{ +} + +static void +meta_monitor_tiled_class_init (MetaMonitorTiledClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MetaMonitorClass *monitor_class = META_MONITOR_CLASS (klass); + + object_class->finalize = meta_monitor_tiled_finalize; + + monitor_class->get_main_output = meta_monitor_tiled_get_main_output; + monitor_class->derive_layout = meta_monitor_tiled_derive_layout; + monitor_class->calculate_crtc_pos = meta_monitor_tiled_calculate_crtc_pos; + monitor_class->get_suggested_position = meta_monitor_tiled_get_suggested_position; +} + +static void +meta_monitor_mode_free (MetaMonitorMode *monitor_mode) +{ + g_free (monitor_mode->id); + g_free (monitor_mode->crtc_modes); + g_free (monitor_mode); +} + +MetaMonitorSpec * +meta_monitor_get_spec (MetaMonitor *monitor) +{ + MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor); + + return priv->spec; +} + +MetaLogicalMonitor * +meta_monitor_get_logical_monitor (MetaMonitor *monitor) +{ + MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor); + + return priv->logical_monitor; +} + +MetaMonitorMode * +meta_monitor_get_mode_from_id (MetaMonitor *monitor, + const char *monitor_mode_id) +{ + MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor); + + return g_hash_table_lookup (priv->mode_ids, monitor_mode_id); +} + +static gboolean +meta_monitor_mode_spec_equals (MetaMonitorModeSpec *monitor_mode_spec, + MetaMonitorModeSpec *other_monitor_mode_spec) +{ + return (monitor_mode_spec->width == other_monitor_mode_spec->width && + monitor_mode_spec->height == other_monitor_mode_spec->height && + ABS (monitor_mode_spec->refresh_rate - + other_monitor_mode_spec->refresh_rate) < MAXIMUM_REFRESH_RATE_DIFF && + monitor_mode_spec->flags == other_monitor_mode_spec->flags); +} + +MetaMonitorMode * +meta_monitor_get_mode_from_spec (MetaMonitor *monitor, + MetaMonitorModeSpec *monitor_mode_spec) +{ + MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor); + GList *l; + + for (l = priv->modes; l; l = l->next) + { + MetaMonitorMode *monitor_mode = l->data; + + if (meta_monitor_mode_spec_equals (monitor_mode_spec, + &monitor_mode->spec)) + return monitor_mode; + } + + return NULL; +} + +MetaMonitorMode * +meta_monitor_get_preferred_mode (MetaMonitor *monitor) +{ + MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor); + + return priv->preferred_mode; +} + +MetaMonitorMode * +meta_monitor_get_current_mode (MetaMonitor *monitor) +{ + MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor); + + return priv->current_mode; +} + +static gboolean +is_current_mode_known (MetaMonitor *monitor) +{ + MetaOutput *output; + MetaCrtc *crtc; + + output = meta_monitor_get_main_output (monitor); + crtc = meta_output_get_assigned_crtc (output); + + return meta_monitor_is_active (monitor) == (crtc && crtc->config); +} + +void +meta_monitor_derive_current_mode (MetaMonitor *monitor) +{ + MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor); + MetaMonitorMode *current_mode = NULL; + GList *l; + + for (l = priv->modes; l; l = l->next) + { + MetaMonitorMode *mode = l->data; + + if (is_monitor_mode_assigned (monitor, mode)) + { + current_mode = mode; + break; + } + } + + priv->current_mode = current_mode; + + g_warn_if_fail (is_current_mode_known (monitor)); +} + +void +meta_monitor_set_current_mode (MetaMonitor *monitor, + MetaMonitorMode *mode) +{ + MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor); + + priv->current_mode = mode; +} + +GList * +meta_monitor_get_modes (MetaMonitor *monitor) +{ + MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor); + + return priv->modes; +} + +void +meta_monitor_calculate_crtc_pos (MetaMonitor *monitor, + MetaMonitorMode *monitor_mode, + MetaOutput *output, + MetaMonitorTransform crtc_transform, + int *out_x, + int *out_y) +{ + META_MONITOR_GET_CLASS (monitor)->calculate_crtc_pos (monitor, + monitor_mode, + output, + crtc_transform, + out_x, + out_y); +} + +/* The minimum resolution at which we turn on a window-scale of 2 */ +#define HIDPI_LIMIT 192 + +/* + * The minimum screen height at which we turn on a window-scale of 2; + * below this there just isn't enough vertical real estate for GNOME + * apps to work, and it's better to just be tiny + */ +#define HIDPI_MIN_HEIGHT 1200 + +/* From http://en.wikipedia.org/wiki/4K_resolution#Resolutions_of_common_formats */ +#define SMALLEST_4K_WIDTH 3656 + +static float +calculate_scale (MetaMonitor *monitor, + MetaMonitorMode *monitor_mode, + MetaMonitorScalesConstraint constraints) +{ + int resolution_width, resolution_height; + int width_mm, height_mm; + int scale; + + scale = 1.0; + + meta_monitor_mode_get_resolution (monitor_mode, + &resolution_width, + &resolution_height); + + if (resolution_height < HIDPI_MIN_HEIGHT) + goto out; + + /* 4K TV */ + switch (meta_monitor_get_connector_type (monitor)) + { + case META_CONNECTOR_TYPE_HDMIA: + case META_CONNECTOR_TYPE_HDMIB: + if (resolution_width < SMALLEST_4K_WIDTH) + goto out; + break; + default: + break; + } + + meta_monitor_get_physical_dimensions (monitor, &width_mm, &height_mm); + + /* + * Somebody encoded the aspect ratio (16/9 or 16/10) instead of the physical + * size. + */ + if (meta_monitor_has_aspect_as_size (monitor)) + goto out; + + if (width_mm > 0 && height_mm > 0) + { + double dpi_x, dpi_y; + + dpi_x = (double) resolution_width / (width_mm / 25.4); + dpi_y = (double) resolution_height / (height_mm / 25.4); + + /* + * We don't completely trust these values so both must be high, and never + * pick higher ratio than 2 automatically. + */ + if (dpi_x > HIDPI_LIMIT && dpi_y > HIDPI_LIMIT) + scale = 2.0; + } + +out: + return scale; +} + +float +meta_monitor_calculate_mode_scale (MetaMonitor *monitor, + MetaMonitorMode *monitor_mode, + MetaMonitorScalesConstraint constraints) +{ + MetaBackend *backend = meta_get_backend (); + MetaSettings *settings = meta_backend_get_settings (backend); + int global_scaling_factor; + + if (meta_settings_get_global_scaling_factor (settings, + &global_scaling_factor)) + return global_scaling_factor; + + return calculate_scale (monitor, monitor_mode, constraints); +} + +static gboolean +is_logical_size_large_enough (int width, + int height) +{ + return width * height >= MINIMUM_LOGICAL_AREA; +} + +static gboolean +is_scale_valid_for_size (float width, + float height, + float scale) +{ + return scale >= MINIMUM_SCALE_FACTOR && + scale <= MAXIMUM_SCALE_FACTOR && + is_logical_size_large_enough (floorf (width/scale), floorf (width/scale)); +} + +gboolean +meta_monitor_mode_should_be_advertised (MetaMonitorMode *monitor_mode) +{ + MetaMonitorMode *preferred_mode; + + g_return_val_if_fail (monitor_mode != NULL, FALSE); + + preferred_mode = meta_monitor_get_preferred_mode (monitor_mode->monitor); + if (monitor_mode->spec.width == preferred_mode->spec.width && + monitor_mode->spec.height == preferred_mode->spec.height) + return TRUE; + + return is_logical_size_large_enough (monitor_mode->spec.width, + monitor_mode->spec.height); +} + +static float +get_closest_scale_factor_for_resolution (float width, + float height, + float scale) +{ + unsigned int i, j; + float scaled_h; + float scaled_w; + float best_scale; + int base_scaled_w; + gboolean found_one; + + best_scale = 0; + + if (!is_scale_valid_for_size (width, height, scale)) + goto out; + + if (fmodf (width, scale) == 0.0 && fmodf (height, scale) == 0.0) + return scale; + + i = 0; + found_one = FALSE; + base_scaled_w = floorf (width / scale); + do + { + for (j = 0; j < 2; j++) + { + float current_scale; + int offset = i * (j ? 1 : -1); + + scaled_w = base_scaled_w + offset; + current_scale = width / scaled_w; + scaled_h = height / current_scale; + + if (current_scale >= scale + SCALE_FACTORS_STEPS || + current_scale <= scale - SCALE_FACTORS_STEPS || + current_scale < MINIMUM_SCALE_FACTOR || + current_scale > MAXIMUM_SCALE_FACTOR) + { + goto out; + } + + if (floorf (scaled_h) == scaled_h) + { + found_one = TRUE; + + if (fabsf (current_scale - scale) < fabsf (best_scale - scale)) + best_scale = current_scale; + } + } + + i++; + } + while (!found_one); + +out: + return best_scale; +} + +float * +meta_monitor_calculate_supported_scales (MetaMonitor *monitor, + MetaMonitorMode *monitor_mode, + MetaMonitorScalesConstraint constraints, + int *n_supported_scales) +{ + unsigned int i, j; + int width, height; + GArray *supported_scales; + + supported_scales = g_array_new (FALSE, FALSE, sizeof (float)); + + meta_monitor_mode_get_resolution (monitor_mode, &width, &height); + + for (i = floorf (MINIMUM_SCALE_FACTOR); + i <= ceilf (MAXIMUM_SCALE_FACTOR); + i++) + { + for (j = 0; j < SCALE_FACTORS_PER_INTEGER; j++) + { + float scale; + float scale_value = i + j * SCALE_FACTORS_STEPS; + + if (constraints & META_MONITOR_SCALES_CONSTRAINT_NO_FRAC) + { + if (fmodf (scale_value, 1.0) != 0.0) + continue; + } + + if ((constraints & META_MONITOR_SCALES_CONSTRAINT_NO_FRAC) || + (constraints & META_MONITOR_SCALES_CONSTRAINT_NO_LOGICAL)) + { + if (!is_scale_valid_for_size (width, height, scale_value)) + continue; + + scale = scale_value; + } + else + scale = get_closest_scale_factor_for_resolution (width, + height, + scale_value); + if (scale > 0.0f) + g_array_append_val (supported_scales, scale); + } + } + + if (supported_scales->len == 0) + { + float fallback_scale; + + fallback_scale = 1.0; + g_array_append_val (supported_scales, fallback_scale); + } + + *n_supported_scales = supported_scales->len; + return (float *) g_array_free (supported_scales, FALSE); +} + +MetaMonitorModeSpec * +meta_monitor_mode_get_spec (MetaMonitorMode *monitor_mode) +{ + return &monitor_mode->spec; +} + +const char * +meta_monitor_mode_get_id (MetaMonitorMode *monitor_mode) +{ + return monitor_mode->id; +} + +void +meta_monitor_mode_get_resolution (MetaMonitorMode *monitor_mode, + int *width, + int *height) +{ + *width = monitor_mode->spec.width; + *height = monitor_mode->spec.height; +} + +float +meta_monitor_mode_get_refresh_rate (MetaMonitorMode *monitor_mode) +{ + return monitor_mode->spec.refresh_rate; +} + +MetaCrtcModeFlag +meta_monitor_mode_get_flags (MetaMonitorMode *monitor_mode) +{ + return monitor_mode->spec.flags; +} + +gboolean +meta_monitor_mode_foreach_crtc (MetaMonitor *monitor, + MetaMonitorMode *mode, + MetaMonitorModeFunc func, + gpointer user_data, + GError **error) +{ + MetaMonitorPrivate *monitor_priv = + meta_monitor_get_instance_private (monitor); + GList *l; + int i; + + for (l = monitor_priv->outputs, i = 0; l; l = l->next, i++) + { + MetaMonitorCrtcMode *monitor_crtc_mode = &mode->crtc_modes[i]; + + if (!monitor_crtc_mode->crtc_mode) + continue; + + if (!func (monitor, mode, monitor_crtc_mode, user_data, error)) + return FALSE; + } + + return TRUE; +} + +gboolean +meta_monitor_mode_foreach_output (MetaMonitor *monitor, + MetaMonitorMode *mode, + MetaMonitorModeFunc func, + gpointer user_data, + GError **error) +{ + MetaMonitorPrivate *monitor_priv = + meta_monitor_get_instance_private (monitor); + GList *l; + int i; + + for (l = monitor_priv->outputs, i = 0; l; l = l->next, i++) + { + MetaMonitorCrtcMode *monitor_crtc_mode = &mode->crtc_modes[i]; + + if (!func (monitor, mode, monitor_crtc_mode, user_data, error)) + return FALSE; + } + + return TRUE; +} + +const char * +meta_monitor_get_display_name (MetaMonitor *monitor) +{ + MetaMonitorPrivate *monitor_priv = + meta_monitor_get_instance_private (monitor); + + return monitor_priv->display_name; +} + +void +meta_monitor_set_logical_monitor (MetaMonitor *monitor, + MetaLogicalMonitor *logical_monitor) +{ + MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor); + + priv->logical_monitor = logical_monitor; +} diff --git a/src/backends/meta-monitor.h b/src/backends/meta-monitor.h new file mode 100644 index 000000000..7b68a57e8 --- /dev/null +++ b/src/backends/meta-monitor.h @@ -0,0 +1,291 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_MONITOR_H +#define META_MONITOR_H + +#include <glib-object.h> + +#include "backends/meta-backend-types.h" +#include "backends/meta-crtc.h" +#include "backends/meta-output.h" + +typedef struct _MetaMonitorSpec +{ + char *connector; + char *vendor; + char *product; + char *serial; +} MetaMonitorSpec; + +typedef struct _MetaMonitorModeSpec +{ + int width; + int height; + float refresh_rate; + MetaCrtcModeFlag flags; +} MetaMonitorModeSpec; + +typedef struct _MetaMonitorCrtcMode +{ + MetaOutput *output; + MetaCrtcMode *crtc_mode; +} MetaMonitorCrtcMode; + +#define HANDLED_CRTC_MODE_FLAGS (META_CRTC_MODE_FLAG_INTERLACE) + +typedef gboolean (* MetaMonitorModeFunc) (MetaMonitor *monitor, + MetaMonitorMode *mode, + MetaMonitorCrtcMode *monitor_crtc_mode, + gpointer user_data, + GError **error); + +typedef enum _MetaMonitorScalesConstraint +{ + META_MONITOR_SCALES_CONSTRAINT_NONE = 0, + META_MONITOR_SCALES_CONSTRAINT_NO_FRAC = (1 << 0), + META_MONITOR_SCALES_CONSTRAINT_NO_LOGICAL = (1 << 1), +} MetaMonitorScalesConstraint; + +#define META_TYPE_MONITOR (meta_monitor_get_type ()) +G_DECLARE_DERIVABLE_TYPE (MetaMonitor, meta_monitor, META, MONITOR, GObject) + +struct _MetaMonitorClass +{ + GObjectClass parent_class; + + MetaOutput * (* get_main_output) (MetaMonitor *monitor); + void (* derive_layout) (MetaMonitor *monitor, + MetaRectangle *layout); + void (* calculate_crtc_pos) (MetaMonitor *monitor, + MetaMonitorMode *monitor_mode, + MetaOutput *output, + MetaMonitorTransform crtc_transform, + int *out_x, + int *out_y); + gboolean (* get_suggested_position) (MetaMonitor *monitor, + int *width, + int *height); +}; + +#define META_TYPE_MONITOR_NORMAL (meta_monitor_normal_get_type ()) +G_DECLARE_FINAL_TYPE (MetaMonitorNormal, meta_monitor_normal, + META, MONITOR_NORMAL, + MetaMonitor) + +#define META_TYPE_MONITOR_TILED (meta_monitor_tiled_get_type ()) +G_DECLARE_FINAL_TYPE (MetaMonitorTiled, meta_monitor_tiled, + META, MONITOR_TILED, + MetaMonitor) + +META_EXPORT_TEST +MetaMonitorTiled * meta_monitor_tiled_new (MetaGpu *gpu, + MetaMonitorManager *monitor_manager, + MetaOutput *output); + +META_EXPORT_TEST +MetaMonitorNormal * meta_monitor_normal_new (MetaGpu *gpu, + MetaMonitorManager *monitor_manager, + MetaOutput *output); + +META_EXPORT_TEST +MetaMonitorSpec * meta_monitor_get_spec (MetaMonitor *monitor); + +META_EXPORT_TEST +MetaGpu * meta_monitor_get_gpu (MetaMonitor *monitor); + +META_EXPORT_TEST +gboolean meta_monitor_is_active (MetaMonitor *monitor); + +META_EXPORT_TEST +MetaOutput * meta_monitor_get_main_output (MetaMonitor *monitor); + +META_EXPORT_TEST +gboolean meta_monitor_is_primary (MetaMonitor *monitor); + +META_EXPORT_TEST +gboolean meta_monitor_supports_underscanning (MetaMonitor *monitor); + +META_EXPORT_TEST +gboolean meta_monitor_is_underscanning (MetaMonitor *monitor); + +META_EXPORT_TEST +gboolean meta_monitor_is_laptop_panel (MetaMonitor *monitor); + +META_EXPORT_TEST +gboolean meta_monitor_is_same_as (MetaMonitor *monitor, + MetaMonitor *other_monitor); + +META_EXPORT_TEST +GList * meta_monitor_get_outputs (MetaMonitor *monitor); + +META_EXPORT_TEST +void meta_monitor_get_current_resolution (MetaMonitor *monitor, + int *width, + int *height); + +META_EXPORT_TEST +void meta_monitor_derive_layout (MetaMonitor *monitor, + MetaRectangle *layout); + +META_EXPORT_TEST +void meta_monitor_get_physical_dimensions (MetaMonitor *monitor, + int *width_mm, + int *height_mm); + +META_EXPORT_TEST +CoglSubpixelOrder meta_monitor_get_subpixel_order (MetaMonitor *monitor); + +META_EXPORT_TEST +const char * meta_monitor_get_connector (MetaMonitor *monitor); + +META_EXPORT_TEST +const char * meta_monitor_get_vendor (MetaMonitor *monitor); + +META_EXPORT_TEST +const char * meta_monitor_get_product (MetaMonitor *monitor); + +META_EXPORT_TEST +const char * meta_monitor_get_serial (MetaMonitor *monitor); + +META_EXPORT_TEST +MetaConnectorType meta_monitor_get_connector_type (MetaMonitor *monitor); + +/* This function returns the transform corrected for the panel orientation */ +META_EXPORT_TEST +MetaMonitorTransform meta_monitor_logical_to_crtc_transform (MetaMonitor *monitor, + MetaMonitorTransform transform); +/* + * This function converts a transform corrected for the panel orientation + * to its logical (user-visible) transform. + */ +META_EXPORT_TEST +MetaMonitorTransform meta_monitor_crtc_to_logical_transform (MetaMonitor *monitor, + MetaMonitorTransform transform); + +META_EXPORT_TEST +uint32_t meta_monitor_tiled_get_tile_group_id (MetaMonitorTiled *monitor_tiled); + +META_EXPORT_TEST +gboolean meta_monitor_get_suggested_position (MetaMonitor *monitor, + int *x, + int *y); + +META_EXPORT_TEST +MetaLogicalMonitor * meta_monitor_get_logical_monitor (MetaMonitor *monitor); + +META_EXPORT_TEST +MetaMonitorMode * meta_monitor_get_mode_from_id (MetaMonitor *monitor, + const char *monitor_mode_id); + +META_EXPORT_TEST +MetaMonitorMode * meta_monitor_get_mode_from_spec (MetaMonitor *monitor, + MetaMonitorModeSpec *monitor_mode_spec); + +META_EXPORT_TEST +MetaMonitorMode * meta_monitor_get_preferred_mode (MetaMonitor *monitor); + +META_EXPORT_TEST +MetaMonitorMode * meta_monitor_get_current_mode (MetaMonitor *monitor); + +META_EXPORT_TEST +void meta_monitor_derive_current_mode (MetaMonitor *monitor); + +META_EXPORT_TEST +void meta_monitor_set_current_mode (MetaMonitor *monitor, + MetaMonitorMode *mode); + +META_EXPORT_TEST +GList * meta_monitor_get_modes (MetaMonitor *monitor); + +META_EXPORT_TEST +void meta_monitor_calculate_crtc_pos (MetaMonitor *monitor, + MetaMonitorMode *monitor_mode, + MetaOutput *output, + MetaMonitorTransform crtc_transform, + int *out_x, + int *out_y); + +META_EXPORT_TEST +float meta_monitor_calculate_mode_scale (MetaMonitor *monitor, + MetaMonitorMode *monitor_mode, + MetaMonitorScalesConstraint constraints); + +META_EXPORT_TEST +float * meta_monitor_calculate_supported_scales (MetaMonitor *monitor, + MetaMonitorMode *monitor_mode, + MetaMonitorScalesConstraint constraints, + int *n_supported_scales); + +META_EXPORT_TEST +const char * meta_monitor_mode_get_id (MetaMonitorMode *monitor_mode); + +META_EXPORT_TEST +MetaMonitorModeSpec * meta_monitor_mode_get_spec (MetaMonitorMode *monitor_mode); + +META_EXPORT_TEST +void meta_monitor_mode_get_resolution (MetaMonitorMode *monitor_mode, + int *width, + int *height); + +META_EXPORT_TEST +float meta_monitor_mode_get_refresh_rate (MetaMonitorMode *monitor_mode); + +META_EXPORT_TEST +MetaCrtcModeFlag meta_monitor_mode_get_flags (MetaMonitorMode *monitor_mode); + +META_EXPORT_TEST +gboolean meta_monitor_mode_foreach_crtc (MetaMonitor *monitor, + MetaMonitorMode *mode, + MetaMonitorModeFunc func, + gpointer user_data, + GError **error); + +META_EXPORT_TEST +gboolean meta_monitor_mode_foreach_output (MetaMonitor *monitor, + MetaMonitorMode *mode, + MetaMonitorModeFunc func, + gpointer user_data, + GError **error); + +META_EXPORT_TEST +gboolean meta_monitor_mode_should_be_advertised (MetaMonitorMode *monitor_mode); + +META_EXPORT_TEST +MetaMonitorSpec * meta_monitor_spec_clone (MetaMonitorSpec *monitor_id); + +META_EXPORT_TEST +gboolean meta_monitor_spec_equals (MetaMonitorSpec *monitor_id, + MetaMonitorSpec *other_monitor_id); + +META_EXPORT_TEST +int meta_monitor_spec_compare (MetaMonitorSpec *monitor_spec_a, + MetaMonitorSpec *monitor_spec_b); + +META_EXPORT_TEST +void meta_monitor_spec_free (MetaMonitorSpec *monitor_id); + +const char * meta_monitor_get_display_name (MetaMonitor *monitor); + +void meta_monitor_set_logical_monitor (MetaMonitor *monitor, + MetaLogicalMonitor *logical_monitor); + +#endif /* META_MONITOR_H */ diff --git a/src/backends/meta-orientation-manager.c b/src/backends/meta-orientation-manager.c new file mode 100644 index 000000000..b09a2a647 --- /dev/null +++ b/src/backends/meta-orientation-manager.c @@ -0,0 +1,280 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "backends/meta-orientation-manager.h" + +#include <gio/gio.h> + +enum +{ + ORIENTATION_CHANGED, + + N_SIGNALS +}; + +static guint signals[N_SIGNALS]; + +struct _MetaOrientationManager +{ + GObject parent_instance; + + GCancellable *cancellable; + + guint iio_watch_id; + GDBusProxy *iio_proxy; + MetaOrientation prev_orientation; + MetaOrientation curr_orientation; + + GSettings *settings; +}; + +G_DEFINE_TYPE (MetaOrientationManager, meta_orientation_manager, G_TYPE_OBJECT) + +#define CONF_SCHEMA "org.cinnamon.settings-daemon.peripherals.touchscreen" +#define ORIENTATION_LOCK_KEY "orientation-lock" + +static MetaOrientation +orientation_from_string (const char *orientation) +{ + if (g_strcmp0 (orientation, "normal") == 0) + return META_ORIENTATION_NORMAL; + if (g_strcmp0 (orientation, "bottom-up") == 0) + return META_ORIENTATION_BOTTOM_UP; + if (g_strcmp0 (orientation, "left-up") == 0) + return META_ORIENTATION_LEFT_UP; + if (g_strcmp0 (orientation, "right-up") == 0) + return META_ORIENTATION_RIGHT_UP; + + return META_ORIENTATION_UNDEFINED; +} + +static void +read_iio_proxy (MetaOrientationManager *self) +{ + gboolean has_accel = FALSE; + GVariant *v; + + self->curr_orientation = META_ORIENTATION_UNDEFINED; + + if (!self->iio_proxy) + return; + + v = g_dbus_proxy_get_cached_property (self->iio_proxy, "HasAccelerometer"); + if (v) + { + has_accel = g_variant_get_boolean (v); + g_variant_unref (v); + } + + if (has_accel) + { + v = g_dbus_proxy_get_cached_property (self->iio_proxy, "AccelerometerOrientation"); + if (v) + { + self->curr_orientation = orientation_from_string (g_variant_get_string (v, NULL)); + g_variant_unref (v); + } + } +} + +static void +sync_state (MetaOrientationManager *self) +{ + if (g_settings_get_boolean (self->settings, ORIENTATION_LOCK_KEY)) + return; + + read_iio_proxy (self); + + if (self->prev_orientation == self->curr_orientation) + return; + + self->prev_orientation = self->curr_orientation; + + if (self->curr_orientation == META_ORIENTATION_UNDEFINED) + return; + + g_signal_emit (self, signals[ORIENTATION_CHANGED], 0); +} + +static void +orientation_lock_changed (GSettings *settings, + gchar *key, + gpointer user_data) +{ + MetaOrientationManager *self = user_data; + sync_state (self); +} + +static void +iio_properties_changed (GDBusProxy *proxy, + GVariant *changed_properties, + GStrv invalidated_properties, + gpointer user_data) +{ + MetaOrientationManager *self = user_data; + sync_state (self); +} + +static void +accelerometer_claimed (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + MetaOrientationManager *self = user_data; + GVariant *v; + GError *error = NULL; + + v = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), res, &error); + if (!v) + { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("Failed to claim accelerometer: %s", error->message); + g_error_free (error); + return; + } + + g_variant_unref (v); + + sync_state (self); +} + +static void +iio_proxy_ready (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + MetaOrientationManager *self = user_data; + GDBusProxy *proxy; + GError *error = NULL; + + proxy = g_dbus_proxy_new_finish (res, &error); + if (!proxy) + { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("Failed to obtain IIO DBus proxy: %s", error->message); + g_error_free (error); + return; + } + + self->iio_proxy = proxy; + g_signal_connect_object (self->iio_proxy, "g-properties-changed", + G_CALLBACK (iio_properties_changed), self, 0); + g_dbus_proxy_call (self->iio_proxy, + "ClaimAccelerometer", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + self->cancellable, + accelerometer_claimed, + self); +} + +static void +iio_sensor_appeared_cb (GDBusConnection *connection, + const gchar *name, + const gchar *name_owner, + gpointer user_data) +{ + MetaOrientationManager *self = user_data; + + self->cancellable = g_cancellable_new (); + g_dbus_proxy_new (connection, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "net.hadess.SensorProxy", + "/net/hadess/SensorProxy", + "net.hadess.SensorProxy", + self->cancellable, + iio_proxy_ready, + self); +} + +static void +iio_sensor_vanished_cb (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + MetaOrientationManager *self = user_data; + + g_cancellable_cancel (self->cancellable); + g_clear_object (&self->cancellable); + + g_clear_object (&self->iio_proxy); + + sync_state (self); +} + +static void +meta_orientation_manager_init (MetaOrientationManager *self) +{ + self->iio_watch_id = g_bus_watch_name (G_BUS_TYPE_SYSTEM, + "net.hadess.SensorProxy", + G_BUS_NAME_WATCHER_FLAGS_NONE, + iio_sensor_appeared_cb, + iio_sensor_vanished_cb, + self, + NULL); + + self->settings = g_settings_new (CONF_SCHEMA); + g_signal_connect_object (self->settings, "changed::"ORIENTATION_LOCK_KEY, + G_CALLBACK (orientation_lock_changed), self, 0); + sync_state (self); +} + +static void +meta_orientation_manager_finalize (GObject *object) +{ + MetaOrientationManager *self = META_ORIENTATION_MANAGER (object); + + g_cancellable_cancel (self->cancellable); + g_clear_object (&self->cancellable); + + g_bus_unwatch_name (self->iio_watch_id); + g_clear_object (&self->iio_proxy); + + g_clear_object (&self->settings); + + G_OBJECT_CLASS (meta_orientation_manager_parent_class)->finalize (object); +} + +static void +meta_orientation_manager_class_init (MetaOrientationManagerClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = meta_orientation_manager_finalize; + + signals[ORIENTATION_CHANGED] = + g_signal_new ("orientation-changed", + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); +} + +MetaOrientation +meta_orientation_manager_get_orientation (MetaOrientationManager *self) +{ + return self->curr_orientation; +} diff --git a/src/backends/meta-orientation-manager.h b/src/backends/meta-orientation-manager.h new file mode 100644 index 000000000..58a84368f --- /dev/null +++ b/src/backends/meta-orientation-manager.h @@ -0,0 +1,42 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_ORIENTATION_MANAGER_H +#define META_ORIENTATION_MANAGER_H + +#include <glib-object.h> + +typedef enum +{ + META_ORIENTATION_UNDEFINED, + META_ORIENTATION_NORMAL, + META_ORIENTATION_BOTTOM_UP, + META_ORIENTATION_LEFT_UP, + META_ORIENTATION_RIGHT_UP +} MetaOrientation; + +#define META_TYPE_ORIENTATION_MANAGER (meta_orientation_manager_get_type ()) +G_DECLARE_FINAL_TYPE (MetaOrientationManager, meta_orientation_manager, + META, ORIENTATION_MANAGER, GObject) + +MetaOrientation meta_orientation_manager_get_orientation (MetaOrientationManager *self); + +#endif /* META_ORIENTATION_MANAGER_H */ diff --git a/src/backends/meta-output.c b/src/backends/meta-output.c new file mode 100644 index 000000000..6a1e7c803 --- /dev/null +++ b/src/backends/meta-output.c @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "backends/meta-output.h" + +typedef struct _MetaOutputPrivate +{ + /* The CRTC driving this output, NULL if the output is not enabled */ + MetaCrtc *crtc; +} MetaOutputPrivate; + +G_DEFINE_TYPE_WITH_PRIVATE (MetaOutput, meta_output, G_TYPE_OBJECT) + +MetaGpu * +meta_output_get_gpu (MetaOutput *output) +{ + return output->gpu; +} + +void +meta_output_assign_crtc (MetaOutput *output, + MetaCrtc *crtc) +{ + MetaOutputPrivate *priv = meta_output_get_instance_private (output); + + g_assert (crtc); + + g_set_object (&priv->crtc, crtc); +} + +void +meta_output_unassign_crtc (MetaOutput *output) +{ + MetaOutputPrivate *priv = meta_output_get_instance_private (output); + + g_clear_object (&priv->crtc); +} + +MetaCrtc * +meta_output_get_assigned_crtc (MetaOutput *output) +{ + MetaOutputPrivate *priv = meta_output_get_instance_private (output); + + return priv->crtc; +} + +MetaMonitorTransform +meta_output_logical_to_crtc_transform (MetaOutput *output, + MetaMonitorTransform transform) +{ + MetaMonitorTransform panel_orientation_transform; + + panel_orientation_transform = output->panel_orientation_transform; + return meta_monitor_transform_transform (transform, + panel_orientation_transform); +} + +MetaMonitorTransform +meta_output_crtc_to_logical_transform (MetaOutput *output, + MetaMonitorTransform transform) +{ + MetaMonitorTransform inverted_panel_orientation_transform; + + inverted_panel_orientation_transform = + meta_monitor_transform_invert (output->panel_orientation_transform); + return meta_monitor_transform_transform (transform, + inverted_panel_orientation_transform); +} + +static void +meta_output_dispose (GObject *object) +{ + MetaOutput *output = META_OUTPUT (object); + MetaOutputPrivate *priv = meta_output_get_instance_private (output); + + g_clear_object (&priv->crtc); + + G_OBJECT_CLASS (meta_output_parent_class)->dispose (object); +} + +static void +meta_output_finalize (GObject *object) +{ + MetaOutput *output = META_OUTPUT (object); + + g_free (output->name); + g_free (output->vendor); + g_free (output->product); + g_free (output->serial); + g_free (output->modes); + g_free (output->possible_crtcs); + g_free (output->possible_clones); + + if (output->driver_notify) + output->driver_notify (output); + + G_OBJECT_CLASS (meta_output_parent_class)->finalize (object); +} + +static void +meta_output_init (MetaOutput *output) +{ +} + +static void +meta_output_class_init (MetaOutputClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = meta_output_dispose; + object_class->finalize = meta_output_finalize; +} diff --git a/src/backends/meta-output.h b/src/backends/meta-output.h new file mode 100644 index 000000000..1c62fc1d4 --- /dev/null +++ b/src/backends/meta-output.h @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_OUTPUT_H +#define META_OUTPUT_H + +#include <glib-object.h> + +#include "backends/meta-backend-types.h" +#include "backends/meta-gpu.h" +#include "core/util-private.h" + +struct _MetaTileInfo +{ + guint32 group_id; + guint32 flags; + guint32 max_h_tiles; + guint32 max_v_tiles; + guint32 loc_h_tile; + guint32 loc_v_tile; + guint32 tile_w; + guint32 tile_h; +}; + +/* This matches the values in drm_mode.h */ +typedef enum +{ + META_CONNECTOR_TYPE_Unknown = 0, + META_CONNECTOR_TYPE_VGA = 1, + META_CONNECTOR_TYPE_DVII = 2, + META_CONNECTOR_TYPE_DVID = 3, + META_CONNECTOR_TYPE_DVIA = 4, + META_CONNECTOR_TYPE_Composite = 5, + META_CONNECTOR_TYPE_SVIDEO = 6, + META_CONNECTOR_TYPE_LVDS = 7, + META_CONNECTOR_TYPE_Component = 8, + META_CONNECTOR_TYPE_9PinDIN = 9, + META_CONNECTOR_TYPE_DisplayPort = 10, + META_CONNECTOR_TYPE_HDMIA = 11, + META_CONNECTOR_TYPE_HDMIB = 12, + META_CONNECTOR_TYPE_TV = 13, + META_CONNECTOR_TYPE_eDP = 14, + META_CONNECTOR_TYPE_VIRTUAL = 15, + META_CONNECTOR_TYPE_DSI = 16, +} MetaConnectorType; + +struct _MetaOutput +{ + GObject parent; + + MetaGpu *gpu; + + /* The low-level ID of this output, used to apply back configuration */ + uint64_t winsys_id; + char *name; + char *vendor; + char *product; + char *serial; + int width_mm; + int height_mm; + CoglSubpixelOrder subpixel_order; + + MetaConnectorType connector_type; + MetaMonitorTransform panel_orientation_transform; + + MetaCrtcMode *preferred_mode; + MetaCrtcMode **modes; + unsigned int n_modes; + + MetaCrtc **possible_crtcs; + unsigned int n_possible_crtcs; + + MetaOutput **possible_clones; + unsigned int n_possible_clones; + + int backlight; + int backlight_min; + int backlight_max; + + /* Used when changing configuration */ + gboolean is_dirty; + + gboolean is_primary; + gboolean is_presentation; + + gboolean is_underscanning; + gboolean supports_underscanning; + + gpointer driver_private; + GDestroyNotify driver_notify; + + /* + * Get a new preferred mode on hotplug events, to handle dynamic guest + * resizing. + */ + gboolean hotplug_mode_update; + gint suggested_x; + gint suggested_y; + + MetaTileInfo tile_info; +}; + +#define META_TYPE_OUTPUT (meta_output_get_type ()) +META_EXPORT_TEST G_DECLARE_FINAL_TYPE (MetaOutput, meta_output, META, OUTPUT, GObject) + +META_EXPORT_TEST +MetaGpu * meta_output_get_gpu (MetaOutput *output); + +META_EXPORT_TEST +void meta_output_assign_crtc (MetaOutput *output, + MetaCrtc *crtc); + +META_EXPORT_TEST +void meta_output_unassign_crtc (MetaOutput *output); + +META_EXPORT_TEST +MetaCrtc * meta_output_get_assigned_crtc (MetaOutput *output); + +MetaMonitorTransform meta_output_logical_to_crtc_transform (MetaOutput *output, + MetaMonitorTransform transform); + +MetaMonitorTransform meta_output_crtc_to_logical_transform (MetaOutput *output, + MetaMonitorTransform transform); + +#endif /* META_OUTPUT_H */ diff --git a/src/backends/meta-pointer-constraint.c b/src/backends/meta-pointer-constraint.c new file mode 100644 index 000000000..55ca9f023 --- /dev/null +++ b/src/backends/meta-pointer-constraint.c @@ -0,0 +1,83 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2015 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +/** + * SECTION:meta-pointer-constraint + * @title: MetaPointerConstraint + * @short_description: Pointer client constraints. + * + * A MetaPointerConstraint can be used to implement any kind of pointer + * constraint as requested by a client, such as cursor lock. + * + * Examples of pointer constraints are "pointer confinement" and "pointer + * locking" (as defined in the wayland pointer constraint protocol extension), + * which restrict movement in relation to a given client. + */ + +#include "config.h" + +#include "backends/meta-pointer-constraint.h" + +#include <glib-object.h> + +G_DEFINE_TYPE (MetaPointerConstraint, meta_pointer_constraint, G_TYPE_OBJECT); + +static void +meta_pointer_constraint_init (MetaPointerConstraint *constraint) +{ +} + +static void +meta_pointer_constraint_class_init (MetaPointerConstraintClass *klass) +{ +} + +/** + * meta_pointer_constraint_constrain: + * @constraint: a #MetaPointerConstraint. + * @device; the device of the pointer. + * @time: the timestamp (in ms) of the event. + * @prev_x: X-coordinate of the previous pointer position. + * @prev_y: Y-coordinate of the previous pointer position. + * @x: The modifiable X-coordinate to which the pointer would like to go to. + * @y: The modifiable Y-coordinate to which the pointer would like to go to. + * + * Constrains the pointer movement from point (@prev_x, @prev_y) to (@x, @y), + * if needed. + */ +void +meta_pointer_constraint_constrain (MetaPointerConstraint *constraint, + ClutterInputDevice *device, + guint32 time, + float prev_x, + float prev_y, + float *x, + float *y) +{ + META_POINTER_CONSTRAINT_GET_CLASS (constraint)->constrain (constraint, + device, + time, + prev_x, prev_y, + x, y); +} diff --git a/src/backends/meta-pointer-constraint.h b/src/backends/meta-pointer-constraint.h new file mode 100644 index 000000000..ed0b025b5 --- /dev/null +++ b/src/backends/meta-pointer-constraint.h @@ -0,0 +1,66 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2015 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +#ifndef META_POINTER_CONSTRAINT_H +#define META_POINTER_CONSTRAINT_H + +#include <glib-object.h> + +#include "clutter/clutter.h" + +G_BEGIN_DECLS + +#define META_TYPE_POINTER_CONSTRAINT (meta_pointer_constraint_get_type ()) +G_DECLARE_DERIVABLE_TYPE (MetaPointerConstraint, meta_pointer_constraint, + META, POINTER_CONSTRAINT, GObject); + +/** + * MetaPointerConstraintClass: + * @constrain: the virtual function pointer for + * meta_pointer_constraint_constrain(). + */ +struct _MetaPointerConstraintClass +{ + GObjectClass parent_class; + + void (*constrain) (MetaPointerConstraint *constraint, + ClutterInputDevice *device, + guint32 time, + float prev_x, + float prev_y, + float *x, + float *y); +}; + +void meta_pointer_constraint_constrain (MetaPointerConstraint *constraint, + ClutterInputDevice *device, + guint32 time, + float prev_x, + float prev_y, + float *x, + float *y); + +G_END_DECLS + +#endif /* META_POINTER_CONSTRAINT_H */ diff --git a/src/backends/meta-profiler.c b/src/backends/meta-profiler.c new file mode 100644 index 000000000..43e49aa38 --- /dev/null +++ b/src/backends/meta-profiler.c @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2019 Endless, Inc + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "src/backends/meta-profiler.h" + +#include <glib-unix.h> +#include <glib/gi18n.h> +#include <gio/gunixfdlist.h> + +#include "cogl/cogl.h" + +#define META_SYSPROF_PROFILER_DBUS_PATH "/org/gnome/Sysprof3/Profiler" + +struct _MetaProfiler +{ + MetaDBusSysprof3ProfilerSkeleton parent_instance; + + GDBusConnection *connection; + GCancellable *cancellable; + + gboolean running; +}; + +static void +meta_sysprof_capturer_init_iface (MetaDBusSysprof3ProfilerIface *iface); + +G_DEFINE_TYPE_WITH_CODE (MetaProfiler, + meta_profiler, + META_DBUS_TYPE_SYSPROF3_PROFILER_SKELETON, + G_IMPLEMENT_INTERFACE (META_DBUS_TYPE_SYSPROF3_PROFILER, + meta_sysprof_capturer_init_iface)) + +static gboolean +handle_start (MetaDBusSysprof3Profiler *dbus_profiler, + GDBusMethodInvocation *invocation, + GUnixFDList *fd_list, + GVariant *options, + GVariant *fd_variant) +{ + MetaProfiler *profiler = META_PROFILER (dbus_profiler); + GMainContext *main_context = g_main_context_default (); + const char *group_name; + int position; + int fd = -1; + + if (profiler->running) + { + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_FAILED, + "Profiler already running"); + return TRUE; + } + + g_variant_get (fd_variant, "h", &position); + + if (fd_list) + fd = g_unix_fd_list_get (fd_list, position, NULL); + + /* Translators: this string will appear in Sysprof */ + group_name = _("Compositor"); + + if (fd != -1) + { + cogl_set_tracing_enabled_on_thread_with_fd (main_context, + group_name, + fd); + } + else + { + cogl_set_tracing_enabled_on_thread (main_context, + group_name, + "mutter-profile.syscap"); + } + + profiler->running = TRUE; + + g_debug ("Profiler running"); + + meta_dbus_sysprof3_profiler_complete_start (dbus_profiler, invocation, NULL); + return TRUE; +} + +static gboolean +handle_stop (MetaDBusSysprof3Profiler *dbus_profiler, + GDBusMethodInvocation *invocation) +{ + MetaProfiler *profiler = META_PROFILER (dbus_profiler); + + if (!profiler->running) + { + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_FAILED, + "Profiler not running"); + return TRUE; + } + + cogl_set_tracing_disabled_on_thread (g_main_context_default ()); + profiler->running = FALSE; + + g_debug ("Stopping profiler"); + + meta_dbus_sysprof3_profiler_complete_stop (dbus_profiler, invocation); + return TRUE; +} + +static void +meta_sysprof_capturer_init_iface (MetaDBusSysprof3ProfilerIface *iface) +{ + iface->handle_start = handle_start; + iface->handle_stop = handle_stop; +} + +static void +on_bus_acquired_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + g_autoptr (GDBusConnection) connection = NULL; + GDBusInterfaceSkeleton *interface_skeleton; + g_autoptr (GError) error = NULL; + MetaProfiler *profiler; + + connection = g_bus_get_finish (result, &error); + + if (error) + { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("Failed to get session bus: %s\n", error->message); + return; + } + + profiler = META_PROFILER (user_data); + interface_skeleton = G_DBUS_INTERFACE_SKELETON (profiler); + + if (!g_dbus_interface_skeleton_export (interface_skeleton, + connection, + META_SYSPROF_PROFILER_DBUS_PATH, + &error)) + { + g_warning ("Failed to export profiler object: %s\n", error->message); + return; + } + + profiler->connection = g_steal_pointer (&connection); +} + +static void +meta_profiler_finalize (GObject *object) +{ + MetaProfiler *self = (MetaProfiler *)object; + + g_cancellable_cancel (self->cancellable); + + g_clear_object (&self->cancellable); + g_clear_object (&self->connection); + + G_OBJECT_CLASS (meta_profiler_parent_class)->finalize (object); +} + +static void +meta_profiler_class_init (MetaProfilerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_profiler_finalize; +} + +static void +meta_profiler_init (MetaProfiler *self) +{ + self->cancellable = g_cancellable_new (); + + g_bus_get (G_BUS_TYPE_SESSION, + self->cancellable, + on_bus_acquired_cb, + self); +} + +MetaProfiler * +meta_profiler_new (void) +{ + return g_object_new (META_TYPE_PROFILER, NULL); +} diff --git a/src/backends/meta-profiler.h b/src/backends/meta-profiler.h new file mode 100644 index 000000000..aa0d72640 --- /dev/null +++ b/src/backends/meta-profiler.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2019 Endless, Inc + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_PROFILER_H +#define META_PROFILER_H + +#include <glib-object.h> + +#include "meta-dbus-sysprof3-profiler.h" + +G_BEGIN_DECLS + +#define META_TYPE_PROFILER (meta_profiler_get_type()) + +G_DECLARE_FINAL_TYPE (MetaProfiler, + meta_profiler, + META, + PROFILER, + MetaDBusSysprof3ProfilerSkeleton) + +MetaProfiler * meta_profiler_new (void); + +G_END_DECLS + +#endif /* META_PROFILER_H */ diff --git a/src/backends/meta-remote-access-controller-private.h b/src/backends/meta-remote-access-controller-private.h new file mode 100644 index 000000000..81477057c --- /dev/null +++ b/src/backends/meta-remote-access-controller-private.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2018 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#ifndef META_REMOTE_ACCESS_CONTROLLER_PRIVATE_H +#define META_REMOTE_ACCESS_CONTROLLER_PRIVATE_H + +#include "meta/meta-remote-access-controller.h" + +void meta_remote_access_controller_notify_new_handle (MetaRemoteAccessController *controller, + MetaRemoteAccessHandle *handle); + +void meta_remote_access_handle_notify_stopped (MetaRemoteAccessHandle *handle); + +void meta_remote_access_handle_set_disable_animations (MetaRemoteAccessHandle *handle, + gboolean disable_animations); + +#endif /* META_REMOTE_ACCESS_CONTROLLER_PRIVATE_H */ diff --git a/src/backends/meta-remote-access-controller.c b/src/backends/meta-remote-access-controller.c new file mode 100644 index 000000000..e9b2a70f6 --- /dev/null +++ b/src/backends/meta-remote-access-controller.c @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2018 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#include "config.h" + +#include "backends/meta-remote-access-controller-private.h" + +enum +{ + HANDLE_STOPPED, + + N_HANDLE_SIGNALS +}; + +static int handle_signals[N_HANDLE_SIGNALS]; + +enum +{ + CONTROLLER_NEW_HANDLE, + + N_CONTROLLER_SIGNALS +}; + +static int controller_signals[N_CONTROLLER_SIGNALS]; + +typedef struct _MetaRemoteAccessHandlePrivate +{ + gboolean has_stopped; + + gboolean disable_animations; +} MetaRemoteAccessHandlePrivate; + +G_DEFINE_TYPE_WITH_PRIVATE (MetaRemoteAccessHandle, + meta_remote_access_handle, + G_TYPE_OBJECT) + +struct _MetaRemoteAccessController +{ + GObject parent; +}; + +G_DEFINE_TYPE (MetaRemoteAccessController, + meta_remote_access_controller, + G_TYPE_OBJECT) + +/** + * meta_remote_access_handle_stop: + * @handle: A #MetaRemoteAccessHandle + * + * Stop the associated remote access session. + */ +void +meta_remote_access_handle_stop (MetaRemoteAccessHandle *handle) +{ + MetaRemoteAccessHandlePrivate *priv = + meta_remote_access_handle_get_instance_private (handle); + + if (priv->has_stopped) + return; + + META_REMOTE_ACCESS_HANDLE_GET_CLASS (handle)->stop (handle); +} + +/** + * meta_remote_access_get_disable_animations: + * @handle: A #MetaRemoteAccessHandle + * + * Returns: %TRUE if the remote access requested that animations should be + * disabled. + */ +gboolean +meta_remote_access_handle_get_disable_animations (MetaRemoteAccessHandle *handle) +{ + MetaRemoteAccessHandlePrivate *priv = + meta_remote_access_handle_get_instance_private (handle); + + return priv->disable_animations; +} + +void +meta_remote_access_handle_set_disable_animations (MetaRemoteAccessHandle *handle, + gboolean disable_animations) +{ + MetaRemoteAccessHandlePrivate *priv = + meta_remote_access_handle_get_instance_private (handle); + + priv->disable_animations = disable_animations; +} + +void +meta_remote_access_handle_notify_stopped (MetaRemoteAccessHandle *handle) +{ + MetaRemoteAccessHandlePrivate *priv = + meta_remote_access_handle_get_instance_private (handle); + + priv->has_stopped = TRUE; + g_signal_emit (handle, handle_signals[HANDLE_STOPPED], 0); +} + +void +meta_remote_access_controller_notify_new_handle (MetaRemoteAccessController *controller, + MetaRemoteAccessHandle *handle) +{ + g_signal_emit (controller, controller_signals[CONTROLLER_NEW_HANDLE], 0, + handle); +} + +static void +meta_remote_access_handle_init (MetaRemoteAccessHandle *handle) +{ +} + +static void +meta_remote_access_handle_class_init (MetaRemoteAccessHandleClass *klass) +{ + handle_signals[HANDLE_STOPPED] = + g_signal_new ("stopped", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); +} + +static void +meta_remote_access_controller_init (MetaRemoteAccessController *controller) +{ +} + +static void +meta_remote_access_controller_class_init (MetaRemoteAccessControllerClass *klass) +{ + controller_signals[CONTROLLER_NEW_HANDLE] = + g_signal_new ("new-handle", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 1, + META_TYPE_REMOTE_ACCESS_HANDLE); +} diff --git a/src/backends/meta-remote-desktop-session.c b/src/backends/meta-remote-desktop-session.c new file mode 100644 index 000000000..28191a1e0 --- /dev/null +++ b/src/backends/meta-remote-desktop-session.c @@ -0,0 +1,837 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2015-2017 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#include "config.h" + +#include "backends/meta-remote-desktop-session.h" + +#include <linux/input.h> +#include <xkbcommon/xkbcommon.h> +#include <stdlib.h> + +#include "backends/meta-dbus-session-watcher.h" +#include "backends/meta-screen-cast-session.h" +#include "backends/meta-remote-access-controller-private.h" +#include "backends/x11/meta-backend-x11.h" +#include "cogl/cogl.h" +#include "meta/meta-backend.h" + +#include "meta-dbus-remote-desktop.h" + +#define META_REMOTE_DESKTOP_SESSION_DBUS_PATH "/org/gnome/Mutter/RemoteDesktop/Session" + +enum _MetaRemoteDesktopNotifyAxisFlags +{ + META_REMOTE_DESKTOP_NOTIFY_AXIS_FLAGS_FINISH = 1 << 0, +} MetaRemoteDesktopNotifyAxisFlags; + +struct _MetaRemoteDesktopSession +{ + MetaDBusRemoteDesktopSessionSkeleton parent; + + char *peer_name; + + char *session_id; + char *object_path; + + MetaScreenCastSession *screen_cast_session; + gulong screen_cast_session_closed_handler_id; + guint started : 1; + + ClutterVirtualInputDevice *virtual_pointer; + ClutterVirtualInputDevice *virtual_keyboard; + ClutterVirtualInputDevice *virtual_touchscreen; + + MetaRemoteDesktopSessionHandle *handle; +}; + +static void +meta_remote_desktop_session_init_iface (MetaDBusRemoteDesktopSessionIface *iface); + +static void +meta_dbus_session_init_iface (MetaDbusSessionInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (MetaRemoteDesktopSession, + meta_remote_desktop_session, + META_DBUS_TYPE_REMOTE_DESKTOP_SESSION_SKELETON, + G_IMPLEMENT_INTERFACE (META_DBUS_TYPE_REMOTE_DESKTOP_SESSION, + meta_remote_desktop_session_init_iface) + G_IMPLEMENT_INTERFACE (META_TYPE_DBUS_SESSION, + meta_dbus_session_init_iface)) + +struct _MetaRemoteDesktopSessionHandle +{ + MetaRemoteAccessHandle parent; + + MetaRemoteDesktopSession *session; +}; + +G_DEFINE_TYPE (MetaRemoteDesktopSessionHandle, + meta_remote_desktop_session_handle, + META_TYPE_REMOTE_ACCESS_HANDLE) + +static MetaRemoteDesktopSessionHandle * +meta_remote_desktop_session_handle_new (MetaRemoteDesktopSession *session); + +static gboolean +meta_remote_desktop_session_is_running (MetaRemoteDesktopSession *session) +{ + return !!session->virtual_pointer; +} + +static void +init_remote_access_handle (MetaRemoteDesktopSession *session) +{ + MetaBackend *backend = meta_get_backend (); + MetaRemoteAccessController *remote_access_controller; + MetaRemoteAccessHandle *remote_access_handle; + + session->handle = meta_remote_desktop_session_handle_new (session); + + remote_access_controller = meta_backend_get_remote_access_controller (backend); + remote_access_handle = META_REMOTE_ACCESS_HANDLE (session->handle); + meta_remote_access_controller_notify_new_handle (remote_access_controller, + remote_access_handle); +} + +static gboolean +meta_remote_desktop_session_start (MetaRemoteDesktopSession *session, + GError **error) +{ + ClutterBackend *backend = clutter_get_default_backend (); + ClutterSeat *seat = clutter_backend_get_default_seat (backend); + + g_assert (!session->started); + + if (session->screen_cast_session) + { + if (!meta_screen_cast_session_start (session->screen_cast_session, error)) + return FALSE; + } + + session->virtual_pointer = + clutter_seat_create_virtual_device (seat, CLUTTER_POINTER_DEVICE); + session->virtual_keyboard = + clutter_seat_create_virtual_device (seat, CLUTTER_KEYBOARD_DEVICE); + session->virtual_touchscreen = + clutter_seat_create_virtual_device (seat, CLUTTER_TOUCHSCREEN_DEVICE); + + init_remote_access_handle (session); + session->started = TRUE; + + return TRUE; +} + +void +meta_remote_desktop_session_close (MetaRemoteDesktopSession *session) +{ + MetaDBusRemoteDesktopSession *skeleton = + META_DBUS_REMOTE_DESKTOP_SESSION (session); + + session->started = FALSE; + + if (session->screen_cast_session) + { + g_clear_signal_handler (&session->screen_cast_session_closed_handler_id, + session->screen_cast_session); + meta_screen_cast_session_close (session->screen_cast_session); + session->screen_cast_session = NULL; + } + + g_clear_object (&session->virtual_pointer); + g_clear_object (&session->virtual_keyboard); + g_clear_object (&session->virtual_touchscreen); + + meta_dbus_session_notify_closed (META_DBUS_SESSION (session)); + meta_dbus_remote_desktop_session_emit_closed (skeleton); + g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (session)); + + if (session->handle) + { + MetaRemoteAccessHandle *remote_access_handle = + META_REMOTE_ACCESS_HANDLE (session->handle); + + meta_remote_access_handle_notify_stopped (remote_access_handle); + } + + g_object_unref (session); +} + +char * +meta_remote_desktop_session_get_object_path (MetaRemoteDesktopSession *session) +{ + return session->object_path; +} + +char * +meta_remote_desktop_session_get_session_id (MetaRemoteDesktopSession *session) +{ + return session->session_id; +} + +static void +on_screen_cast_session_closed (MetaScreenCastSession *screen_cast_session, + MetaRemoteDesktopSession *session) +{ + session->screen_cast_session = NULL; + meta_remote_desktop_session_close (session); +} + +gboolean +meta_remote_desktop_session_register_screen_cast (MetaRemoteDesktopSession *session, + MetaScreenCastSession *screen_cast_session, + GError **error) +{ + if (session->screen_cast_session) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Remote desktop session already have an associated " + "screen cast session"); + return FALSE; + } + + session->screen_cast_session = screen_cast_session; + session->screen_cast_session_closed_handler_id = + g_signal_connect (screen_cast_session, "session-closed", + G_CALLBACK (on_screen_cast_session_closed), + session); + + return TRUE; +} + +MetaRemoteDesktopSession * +meta_remote_desktop_session_new (MetaRemoteDesktop *remote_desktop, + const char *peer_name, + GError **error) +{ + GDBusInterfaceSkeleton *interface_skeleton; + MetaRemoteDesktopSession *session; + GDBusConnection *connection; + + session = g_object_new (META_TYPE_REMOTE_DESKTOP_SESSION, NULL); + + session->peer_name = g_strdup (peer_name); + + interface_skeleton = G_DBUS_INTERFACE_SKELETON (session); + connection = meta_remote_desktop_get_connection (remote_desktop); + if (!g_dbus_interface_skeleton_export (interface_skeleton, + connection, + session->object_path, + error)) + { + g_object_unref (session); + return NULL; + } + + return session; +} + +static gboolean +check_permission (MetaRemoteDesktopSession *session, + GDBusMethodInvocation *invocation) +{ + return g_strcmp0 (session->peer_name, + g_dbus_method_invocation_get_sender (invocation)) == 0; +} + +static gboolean +meta_remote_desktop_session_check_can_notify (MetaRemoteDesktopSession *session, + GDBusMethodInvocation *invocation) +{ + if (!session->started) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_FAILED, + "Session not started"); + return FALSE; + } + + if (!check_permission (session, invocation)) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_ACCESS_DENIED, + "Permission denied"); + return FALSE; + } + + return TRUE; +} + +static gboolean +handle_start (MetaDBusRemoteDesktopSession *skeleton, + GDBusMethodInvocation *invocation) +{ + MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton); + GError *error = NULL; + + if (session->started) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_FAILED, + "Already started"); + return TRUE; + } + + if (!check_permission (session, invocation)) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_ACCESS_DENIED, + "Permission denied"); + return TRUE; + } + + if (!meta_remote_desktop_session_start (session, &error)) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_FAILED, + "Failed to start remote desktop: %s", + error->message); + g_error_free (error); + + meta_remote_desktop_session_close (session); + + return TRUE; + } + + meta_dbus_remote_desktop_session_complete_start (skeleton, invocation); + + return TRUE; +} + +static gboolean +handle_stop (MetaDBusRemoteDesktopSession *skeleton, + GDBusMethodInvocation *invocation) +{ + MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton); + + if (!session->started) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_FAILED, + "Session not started"); + return TRUE; + } + + if (!check_permission (session, invocation)) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_ACCESS_DENIED, + "Permission denied"); + return TRUE; + } + + meta_remote_desktop_session_close (session); + + meta_dbus_remote_desktop_session_complete_stop (skeleton, invocation); + + return TRUE; +} + +static gboolean +handle_notify_keyboard_keycode (MetaDBusRemoteDesktopSession *skeleton, + GDBusMethodInvocation *invocation, + unsigned int keycode, + gboolean pressed) +{ + MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton); + ClutterKeyState state; + + if (!meta_remote_desktop_session_check_can_notify (session, invocation)) + return TRUE; + + if (pressed) + state = CLUTTER_KEY_STATE_PRESSED; + else + state = CLUTTER_KEY_STATE_RELEASED; + + clutter_virtual_input_device_notify_key (session->virtual_keyboard, + CLUTTER_CURRENT_TIME, + keycode, + state); + + meta_dbus_remote_desktop_session_complete_notify_keyboard_keycode (skeleton, + invocation); + return TRUE; +} + +static gboolean +handle_notify_keyboard_keysym (MetaDBusRemoteDesktopSession *skeleton, + GDBusMethodInvocation *invocation, + unsigned int keysym, + gboolean pressed) +{ + MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton); + ClutterKeyState state; + + if (!meta_remote_desktop_session_check_can_notify (session, invocation)) + return TRUE; + + if (pressed) + state = CLUTTER_KEY_STATE_PRESSED; + else + state = CLUTTER_KEY_STATE_RELEASED; + + clutter_virtual_input_device_notify_keyval (session->virtual_keyboard, + CLUTTER_CURRENT_TIME, + keysym, + state); + + meta_dbus_remote_desktop_session_complete_notify_keyboard_keysym (skeleton, + invocation); + return TRUE; +} + +/* Translation taken from the clutter evdev backend. */ +static int +translate_to_clutter_button (int button) +{ + switch (button) + { + case BTN_LEFT: + return CLUTTER_BUTTON_PRIMARY; + case BTN_RIGHT: + return CLUTTER_BUTTON_SECONDARY; + case BTN_MIDDLE: + return CLUTTER_BUTTON_MIDDLE; + default: + /* + * For compatibility reasons, all additional buttons go after the old + * 4-7 scroll ones. + */ + return button - (BTN_LEFT - 1) + 4; + } +} + +static gboolean +handle_notify_pointer_button (MetaDBusRemoteDesktopSession *skeleton, + GDBusMethodInvocation *invocation, + int button_code, + gboolean pressed) +{ + MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton); + uint32_t button; + ClutterButtonState state; + + if (!meta_remote_desktop_session_check_can_notify (session, invocation)) + return TRUE; + + button = translate_to_clutter_button (button_code); + + if (pressed) + state = CLUTTER_BUTTON_STATE_PRESSED; + else + state = CLUTTER_BUTTON_STATE_RELEASED; + + clutter_virtual_input_device_notify_button (session->virtual_pointer, + CLUTTER_CURRENT_TIME, + button, + state); + + meta_dbus_remote_desktop_session_complete_notify_pointer_button (skeleton, + invocation); + + return TRUE; +} + +static gboolean +handle_notify_pointer_axis (MetaDBusRemoteDesktopSession *skeleton, + GDBusMethodInvocation *invocation, + double dx, + double dy, + uint32_t flags) +{ + MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton); + ClutterScrollFinishFlags finish_flags = CLUTTER_SCROLL_FINISHED_NONE; + + if (!meta_remote_desktop_session_check_can_notify (session, invocation)) + return TRUE; + + if (flags & META_REMOTE_DESKTOP_NOTIFY_AXIS_FLAGS_FINISH) + { + finish_flags |= (CLUTTER_SCROLL_FINISHED_HORIZONTAL | + CLUTTER_SCROLL_FINISHED_VERTICAL); + } + + clutter_virtual_input_device_notify_scroll_continuous (session->virtual_pointer, + CLUTTER_CURRENT_TIME, + dx, dy, + CLUTTER_SCROLL_SOURCE_FINGER, + finish_flags); + + meta_dbus_remote_desktop_session_complete_notify_pointer_axis (skeleton, + invocation); + + return TRUE; +} + +static ClutterScrollDirection +discrete_steps_to_scroll_direction (unsigned int axis, + int steps) +{ + if (axis == 0 && steps < 0) + return CLUTTER_SCROLL_UP; + if (axis == 0 && steps > 0) + return CLUTTER_SCROLL_DOWN; + if (axis == 1 && steps < 0) + return CLUTTER_SCROLL_LEFT; + if (axis == 1 && steps > 0) + return CLUTTER_SCROLL_RIGHT; + + g_assert_not_reached (); + return 0; +} + +static gboolean +handle_notify_pointer_axis_discrete (MetaDBusRemoteDesktopSession *skeleton, + GDBusMethodInvocation *invocation, + unsigned int axis, + int steps) +{ + MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton); + ClutterScrollDirection direction; + int step_count; + + if (!meta_remote_desktop_session_check_can_notify (session, invocation)) + return TRUE; + + if (axis > 1) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_FAILED, + "Invalid axis value"); + return TRUE; + } + + if (steps == 0) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_FAILED, + "Invalid axis steps value"); + return TRUE; + } + + /* + * We don't have the actual scroll source, but only know they should be + * considered as discrete steps. The device that produces such scroll events + * is the scroll wheel, so pretend that is the scroll source. + */ + direction = discrete_steps_to_scroll_direction (axis, steps); + + for (step_count = 0; step_count < abs (steps); step_count++) + clutter_virtual_input_device_notify_discrete_scroll (session->virtual_pointer, + CLUTTER_CURRENT_TIME, + direction, + CLUTTER_SCROLL_SOURCE_WHEEL); + + meta_dbus_remote_desktop_session_complete_notify_pointer_axis_discrete (skeleton, + invocation); + + return TRUE; +} + +static gboolean +handle_notify_pointer_motion_relative (MetaDBusRemoteDesktopSession *skeleton, + GDBusMethodInvocation *invocation, + double dx, + double dy) +{ + MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton); + + if (!meta_remote_desktop_session_check_can_notify (session, invocation)) + return TRUE; + + clutter_virtual_input_device_notify_relative_motion (session->virtual_pointer, + CLUTTER_CURRENT_TIME, + dx, dy); + + meta_dbus_remote_desktop_session_complete_notify_pointer_motion_relative (skeleton, + invocation); + + return TRUE; +} + +static gboolean +handle_notify_pointer_motion_absolute (MetaDBusRemoteDesktopSession *skeleton, + GDBusMethodInvocation *invocation, + const char *stream_path, + double x, + double y) +{ + MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton); + MetaScreenCastStream *stream; + double abs_x, abs_y; + + if (!meta_remote_desktop_session_check_can_notify (session, invocation)) + return TRUE; + + + if (!session->screen_cast_session) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_FAILED, + "No screen cast active"); + return TRUE; + } + + stream = meta_screen_cast_session_get_stream (session->screen_cast_session, + stream_path); + if (!stream) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_FAILED, + "Unknown stream"); + return TRUE; + } + + meta_screen_cast_stream_transform_position (stream, x, y, &abs_x, &abs_y); + + clutter_virtual_input_device_notify_absolute_motion (session->virtual_pointer, + CLUTTER_CURRENT_TIME, + abs_x, abs_y); + + meta_dbus_remote_desktop_session_complete_notify_pointer_motion_absolute (skeleton, + invocation); + + return TRUE; +} + +static gboolean +handle_notify_touch_down (MetaDBusRemoteDesktopSession *skeleton, + GDBusMethodInvocation *invocation, + const char *stream_path, + unsigned int slot, + double x, + double y) +{ + MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton); + MetaScreenCastStream *stream; + double abs_x, abs_y; + + if (!meta_remote_desktop_session_check_can_notify (session, invocation)) + return TRUE; + + if (!session->screen_cast_session) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_FAILED, + "No screen cast active"); + return TRUE; + } + + stream = meta_screen_cast_session_get_stream (session->screen_cast_session, + stream_path); + if (!stream) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_FAILED, + "Unknown stream"); + return TRUE; + } + + meta_screen_cast_stream_transform_position (stream, x, y, &abs_x, &abs_y); + + clutter_virtual_input_device_notify_touch_down (session->virtual_touchscreen, + CLUTTER_CURRENT_TIME, + slot, + abs_x, abs_y); + + meta_dbus_remote_desktop_session_complete_notify_touch_down (skeleton, + invocation); + + return TRUE; +} + +static gboolean +handle_notify_touch_motion (MetaDBusRemoteDesktopSession *skeleton, + GDBusMethodInvocation *invocation, + const char *stream_path, + unsigned int slot, + double x, + double y) +{ + MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton); + MetaScreenCastStream *stream; + double abs_x, abs_y; + + if (!meta_remote_desktop_session_check_can_notify (session, invocation)) + return TRUE; + + + if (!session->screen_cast_session) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_FAILED, + "No screen cast active"); + return TRUE; + } + + stream = meta_screen_cast_session_get_stream (session->screen_cast_session, + stream_path); + if (!stream) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_FAILED, + "Unknown stream"); + return TRUE; + } + + meta_screen_cast_stream_transform_position (stream, x, y, &abs_x, &abs_y); + + clutter_virtual_input_device_notify_touch_motion (session->virtual_touchscreen, + CLUTTER_CURRENT_TIME, + slot, + abs_x, abs_y); + + meta_dbus_remote_desktop_session_complete_notify_touch_motion (skeleton, + invocation); + + return TRUE; +} + +static gboolean +handle_notify_touch_up (MetaDBusRemoteDesktopSession *skeleton, + GDBusMethodInvocation *invocation, + unsigned int slot) +{ + MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton); + + if (!meta_remote_desktop_session_check_can_notify (session, invocation)) + return TRUE; + + clutter_virtual_input_device_notify_touch_up (session->virtual_touchscreen, + CLUTTER_CURRENT_TIME, + slot); + + meta_dbus_remote_desktop_session_complete_notify_touch_up (skeleton, + invocation); + + return TRUE; +} + +static void +meta_remote_desktop_session_init_iface (MetaDBusRemoteDesktopSessionIface *iface) +{ + iface->handle_start = handle_start; + iface->handle_stop = handle_stop; + iface->handle_notify_keyboard_keycode = handle_notify_keyboard_keycode; + iface->handle_notify_keyboard_keysym = handle_notify_keyboard_keysym; + iface->handle_notify_pointer_button = handle_notify_pointer_button; + iface->handle_notify_pointer_axis = handle_notify_pointer_axis; + iface->handle_notify_pointer_axis_discrete = handle_notify_pointer_axis_discrete; + iface->handle_notify_pointer_motion_relative = handle_notify_pointer_motion_relative; + iface->handle_notify_pointer_motion_absolute = handle_notify_pointer_motion_absolute; + iface->handle_notify_touch_down = handle_notify_touch_down; + iface->handle_notify_touch_motion = handle_notify_touch_motion; + iface->handle_notify_touch_up = handle_notify_touch_up; +} + +static void +meta_remote_desktop_session_client_vanished (MetaDbusSession *dbus_session) +{ + meta_remote_desktop_session_close (META_REMOTE_DESKTOP_SESSION (dbus_session)); +} + +static void +meta_dbus_session_init_iface (MetaDbusSessionInterface *iface) +{ + iface->client_vanished = meta_remote_desktop_session_client_vanished; +} + +static void +meta_remote_desktop_session_finalize (GObject *object) +{ + MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (object); + + g_assert (!meta_remote_desktop_session_is_running (session)); + + g_clear_object (&session->handle); + g_free (session->peer_name); + g_free (session->session_id); + g_free (session->object_path); + + G_OBJECT_CLASS (meta_remote_desktop_session_parent_class)->finalize (object); +} + +static void +meta_remote_desktop_session_init (MetaRemoteDesktopSession *session) +{ + MetaDBusRemoteDesktopSession *skeleton = + META_DBUS_REMOTE_DESKTOP_SESSION (session); + GRand *rand; + static unsigned int global_session_number = 0; + + rand = g_rand_new (); + session->session_id = meta_generate_random_id (rand, 32); + g_rand_free (rand); + + meta_dbus_remote_desktop_session_set_session_id (skeleton, session->session_id); + + session->object_path = + g_strdup_printf (META_REMOTE_DESKTOP_SESSION_DBUS_PATH "/u%u", + ++global_session_number); +} + +static void +meta_remote_desktop_session_class_init (MetaRemoteDesktopSessionClass *klass) +{ + + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_remote_desktop_session_finalize; +} + +static MetaRemoteDesktopSessionHandle * +meta_remote_desktop_session_handle_new (MetaRemoteDesktopSession *session) +{ + MetaRemoteDesktopSessionHandle *handle; + + handle = g_object_new (META_TYPE_REMOTE_DESKTOP_SESSION_HANDLE, NULL); + handle->session = session; + + return handle; +} + +static void +meta_remote_desktop_session_handle_stop (MetaRemoteAccessHandle *handle) +{ + MetaRemoteDesktopSession *session; + + session = META_REMOTE_DESKTOP_SESSION_HANDLE (handle)->session; + if (!session) + return; + + meta_remote_desktop_session_close (session); +} + +static void +meta_remote_desktop_session_handle_init (MetaRemoteDesktopSessionHandle *handle) +{ +} + +static void +meta_remote_desktop_session_handle_class_init (MetaRemoteDesktopSessionHandleClass *klass) +{ + MetaRemoteAccessHandleClass *remote_access_handle_class = + META_REMOTE_ACCESS_HANDLE_CLASS (klass); + + remote_access_handle_class->stop = meta_remote_desktop_session_handle_stop; +} diff --git a/src/backends/meta-remote-desktop-session.h b/src/backends/meta-remote-desktop-session.h new file mode 100644 index 000000000..1edb3739b --- /dev/null +++ b/src/backends/meta-remote-desktop-session.h @@ -0,0 +1,56 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2015-2017 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#ifndef META_REMOTE_DESKTOP_SESSION_H +#define META_REMOTE_DESKTOP_SESSION_H + +#include <glib-object.h> + +#include "backends/meta-remote-desktop.h" +#include "backends/meta-screen-cast-session.h" + +#define META_TYPE_REMOTE_DESKTOP_SESSION (meta_remote_desktop_session_get_type ()) +G_DECLARE_FINAL_TYPE (MetaRemoteDesktopSession, meta_remote_desktop_session, + META, REMOTE_DESKTOP_SESSION, + MetaDBusRemoteDesktopSessionSkeleton) + +#define META_TYPE_REMOTE_DESKTOP_SESSION_HANDLE (meta_remote_desktop_session_handle_get_type ()) +G_DECLARE_FINAL_TYPE (MetaRemoteDesktopSessionHandle, + meta_remote_desktop_session_handle, + META, REMOTE_DESKTOP_SESSION_HANDLE, + MetaRemoteAccessHandle) + +char * meta_remote_desktop_session_get_object_path (MetaRemoteDesktopSession *session); + +char * meta_remote_desktop_session_get_session_id (MetaRemoteDesktopSession *session); + +gboolean meta_remote_desktop_session_register_screen_cast (MetaRemoteDesktopSession *session, + MetaScreenCastSession *screen_cast_session, + GError **error); + +void meta_remote_desktop_session_close (MetaRemoteDesktopSession *session); + +MetaRemoteDesktopSession * meta_remote_desktop_session_new (MetaRemoteDesktop *remote_desktop, + const char *peer_name, + GError **error); + +#endif /* META_REMOTE_DESKTOP_SESSION_H */ diff --git a/src/backends/meta-remote-desktop.c b/src/backends/meta-remote-desktop.c new file mode 100644 index 000000000..b94055885 --- /dev/null +++ b/src/backends/meta-remote-desktop.c @@ -0,0 +1,276 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2015-2017 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#include "config.h" + +#include "backends/meta-remote-desktop.h" + +#include <errno.h> +#include <glib.h> +#include <fcntl.h> +#include <stdlib.h> +#include <string.h> + +#include "backends/meta-backend-private.h" +#include "backends/meta-cursor-renderer.h" +#include "backends/meta-remote-desktop-session.h" +#include "backends/native/meta-cursor-renderer-native.h" +#include "meta/meta-backend.h" + +#include "meta-dbus-remote-desktop.h" + +#define META_REMOTE_DESKTOP_DBUS_SERVICE "org.gnome.Mutter.RemoteDesktop" +#define META_REMOTE_DESKTOP_DBUS_PATH "/org/gnome/Mutter/RemoteDesktop" +#define META_REMOTE_DESKTOP_API_VERSION 1 + +typedef enum _MetaRemoteDesktopDeviceTypes +{ + META_REMOTE_DESKTOP_DEVICE_TYPE_NONE = 0, + META_REMOTE_DESKTOP_DEVICE_TYPE_KEYBOARD = 1 << 0, + META_REMOTE_DESKTOP_DEVICE_TYPE_POINTER = 1 << 1, + META_REMOTE_DESKTOP_DEVICE_TYPE_TOUCHSCREEN = 1 << 2, +} MetaRemoteDesktopDeviceTypes; + +struct _MetaRemoteDesktop +{ + MetaDBusRemoteDesktopSkeleton parent; + + int dbus_name_id; + + GHashTable *sessions; + + MetaDbusSessionWatcher *session_watcher; +}; + +static void +meta_remote_desktop_init_iface (MetaDBusRemoteDesktopIface *iface); + +G_DEFINE_TYPE_WITH_CODE (MetaRemoteDesktop, + meta_remote_desktop, + META_DBUS_TYPE_REMOTE_DESKTOP_SKELETON, + G_IMPLEMENT_INTERFACE (META_DBUS_TYPE_REMOTE_DESKTOP, + meta_remote_desktop_init_iface)); + +GDBusConnection * +meta_remote_desktop_get_connection (MetaRemoteDesktop *remote_desktop) +{ + GDBusInterfaceSkeleton *interface_skeleton = + G_DBUS_INTERFACE_SKELETON (remote_desktop); + + return g_dbus_interface_skeleton_get_connection (interface_skeleton); +} + +MetaRemoteDesktopSession * +meta_remote_desktop_get_session (MetaRemoteDesktop *remote_desktop, + const char *session_id) +{ + return g_hash_table_lookup (remote_desktop->sessions, session_id); +} + +static void +on_session_closed (MetaRemoteDesktopSession *session, + MetaRemoteDesktop *remote_desktop) +{ + char *session_id; + + session_id = meta_remote_desktop_session_get_session_id (session); + g_hash_table_remove (remote_desktop->sessions, session_id); +} + +static gboolean +handle_create_session (MetaDBusRemoteDesktop *skeleton, + GDBusMethodInvocation *invocation) +{ + MetaRemoteDesktop *remote_desktop = META_REMOTE_DESKTOP (skeleton); + const char *peer_name; + MetaRemoteDesktopSession *session; + GError *error = NULL; + char *session_id; + char *session_path; + const char *client_dbus_name; + + peer_name = g_dbus_method_invocation_get_sender (invocation); + session = meta_remote_desktop_session_new (remote_desktop, + peer_name, + &error); + if (!session) + { + g_warning ("Failed to create remote desktop session: %s", + error->message); + + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_FAILED, + "Failed to create session: %s", + error->message); + g_error_free (error); + + return TRUE; + } + + session_id = meta_remote_desktop_session_get_session_id (session); + g_hash_table_insert (remote_desktop->sessions, + session_id, + session); + + client_dbus_name = g_dbus_method_invocation_get_sender (invocation); + meta_dbus_session_watcher_watch_session (remote_desktop->session_watcher, + client_dbus_name, + META_DBUS_SESSION (session)); + + session_path = meta_remote_desktop_session_get_object_path (session); + meta_dbus_remote_desktop_complete_create_session (skeleton, + invocation, + session_path); + + g_signal_connect (session, "session-closed", + G_CALLBACK (on_session_closed), + remote_desktop); + + return TRUE; +} + +static void +meta_remote_desktop_init_iface (MetaDBusRemoteDesktopIface *iface) +{ + iface->handle_create_session = handle_create_session; +} + +static void +on_bus_acquired (GDBusConnection *connection, + const char *name, + gpointer user_data) +{ + MetaRemoteDesktop *remote_desktop = user_data; + GDBusInterfaceSkeleton *interface_skeleton = + G_DBUS_INTERFACE_SKELETON (remote_desktop); + GError *error = NULL; + + if (!g_dbus_interface_skeleton_export (interface_skeleton, + connection, + META_REMOTE_DESKTOP_DBUS_PATH, + &error)) + g_warning ("Failed to export remote desktop object: %s\n", error->message); +} + +static void +on_name_acquired (GDBusConnection *connection, + const char *name, + gpointer user_data) +{ + g_info ("Acquired name %s\n", name); +} + +static void +on_name_lost (GDBusConnection *connection, + const char *name, + gpointer user_data) +{ + g_warning ("Lost or failed to acquire name %s\n", name); +} + +static void +meta_remote_desktop_constructed (GObject *object) +{ + MetaRemoteDesktop *remote_desktop = META_REMOTE_DESKTOP (object); + + remote_desktop->dbus_name_id = + g_bus_own_name (G_BUS_TYPE_SESSION, + META_REMOTE_DESKTOP_DBUS_SERVICE, + G_BUS_NAME_OWNER_FLAGS_NONE, + on_bus_acquired, + on_name_acquired, + on_name_lost, + remote_desktop, + NULL); +} + +static void +meta_remote_desktop_finalize (GObject *object) +{ + MetaRemoteDesktop *remote_desktop = META_REMOTE_DESKTOP (object); + GList *sessions; + + if (remote_desktop->dbus_name_id != 0) + g_bus_unown_name (remote_desktop->dbus_name_id); + + sessions = g_list_copy (g_hash_table_get_values (remote_desktop->sessions)); + g_list_free_full (sessions, + (GDestroyNotify) meta_remote_desktop_session_close); + g_hash_table_destroy (remote_desktop->sessions); + + G_OBJECT_CLASS (meta_remote_desktop_parent_class)->finalize (object); +} + +MetaRemoteDesktop * +meta_remote_desktop_new (MetaDbusSessionWatcher *session_watcher) +{ + MetaRemoteDesktop *remote_desktop; + + remote_desktop = g_object_new (META_TYPE_REMOTE_DESKTOP, NULL); + remote_desktop->session_watcher = session_watcher; + + return remote_desktop; +} + +static MetaRemoteDesktopDeviceTypes +calculate_supported_device_types (void) +{ + ClutterBackend *backend = clutter_get_default_backend (); + ClutterSeat *seat = clutter_backend_get_default_seat (backend); + ClutterVirtualDeviceType device_types; + MetaRemoteDesktopDeviceTypes supported_devices = + META_REMOTE_DESKTOP_DEVICE_TYPE_NONE; + + device_types = + clutter_seat_get_supported_virtual_device_types (seat); + + if (device_types & CLUTTER_VIRTUAL_DEVICE_TYPE_KEYBOARD) + supported_devices |= META_REMOTE_DESKTOP_DEVICE_TYPE_KEYBOARD; + if (device_types & CLUTTER_VIRTUAL_DEVICE_TYPE_POINTER) + supported_devices |= META_REMOTE_DESKTOP_DEVICE_TYPE_POINTER; + if (device_types & CLUTTER_VIRTUAL_DEVICE_TYPE_TOUCHSCREEN) + supported_devices |= META_REMOTE_DESKTOP_DEVICE_TYPE_TOUCHSCREEN; + + return supported_devices; +} + +static void +meta_remote_desktop_init (MetaRemoteDesktop *remote_desktop) +{ + remote_desktop->sessions = g_hash_table_new (g_str_hash, g_str_equal); + + meta_dbus_remote_desktop_set_supported_device_types ( + META_DBUS_REMOTE_DESKTOP (remote_desktop), + calculate_supported_device_types ()); + meta_dbus_remote_desktop_set_version ( + META_DBUS_REMOTE_DESKTOP (remote_desktop), + META_REMOTE_DESKTOP_API_VERSION); +} + +static void +meta_remote_desktop_class_init (MetaRemoteDesktopClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->constructed = meta_remote_desktop_constructed; + object_class->finalize = meta_remote_desktop_finalize; +} diff --git a/src/backends/meta-remote-desktop.h b/src/backends/meta-remote-desktop.h new file mode 100644 index 000000000..3eebc13d5 --- /dev/null +++ b/src/backends/meta-remote-desktop.h @@ -0,0 +1,46 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2015-2017 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#ifndef META_REMOTE_DESKTOP_H +#define META_REMOTE_DESKTOP_H + +#include <glib-object.h> + +#include "backends/meta-dbus-session-watcher.h" + +#include "meta-dbus-remote-desktop.h" + +typedef struct _MetaRemoteDesktopSession MetaRemoteDesktopSession; + +#define META_TYPE_REMOTE_DESKTOP (meta_remote_desktop_get_type ()) +G_DECLARE_FINAL_TYPE (MetaRemoteDesktop, meta_remote_desktop, + META, REMOTE_DESKTOP, + MetaDBusRemoteDesktopSkeleton) + +MetaRemoteDesktopSession * meta_remote_desktop_get_session (MetaRemoteDesktop *remote_desktop, + const char *session_id); + +GDBusConnection * meta_remote_desktop_get_connection (MetaRemoteDesktop *remote_desktop); + +MetaRemoteDesktop * meta_remote_desktop_new (MetaDbusSessionWatcher *session_watcher); + +#endif /* META_REMOTE_DESKTOP_H */ diff --git a/src/backends/meta-renderer-view.c b/src/backends/meta-renderer-view.c new file mode 100644 index 000000000..ae771f2de --- /dev/null +++ b/src/backends/meta-renderer-view.c @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2016 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * SECTION:meta-renderer-view + * @title: MetaRendererView + * @short_description: Renders (a part of) the global stage. + * + * A MetaRendererView object is responsible for rendering (a part of) the + * global stage, or more precisely: the part that matches what can be seen on a + * #MetaLogicalMonitor. By splitting up the rendering into different parts and + * attaching it to a #MetaLogicalMonitor, we can do the rendering so that each + * renderer view is responsible for applying the right #MetaMonitorTransform + * and the right scaling. + */ + +#include "config.h" + +#include "backends/meta-renderer-view.h" + +#include "backends/meta-renderer.h" +#include "clutter/clutter-mutter.h" + +enum +{ + PROP_0, + + PROP_TRANSFORM, + + PROP_LAST +}; + +static GParamSpec *obj_props[PROP_LAST]; + +struct _MetaRendererView +{ + ClutterStageViewCogl parent; + + MetaMonitorTransform transform; +}; + +G_DEFINE_TYPE (MetaRendererView, meta_renderer_view, + CLUTTER_TYPE_STAGE_VIEW_COGL) + +MetaMonitorTransform +meta_renderer_view_get_transform (MetaRendererView *view) +{ + return view->transform; +} + +static void +meta_renderer_view_get_offscreen_transformation_matrix (ClutterStageView *view, + CoglMatrix *matrix) +{ + MetaRendererView *renderer_view = META_RENDERER_VIEW (view); + + cogl_matrix_init_identity (matrix); + + switch (renderer_view->transform) + { + case META_MONITOR_TRANSFORM_NORMAL: + break; + case META_MONITOR_TRANSFORM_90: + cogl_matrix_rotate (matrix, 90, 0, 0, 1); + cogl_matrix_translate (matrix, 0, -1, 0); + break; + case META_MONITOR_TRANSFORM_180: + cogl_matrix_rotate (matrix, 180, 0, 0, 1); + cogl_matrix_translate (matrix, -1, -1, 0); + break; + case META_MONITOR_TRANSFORM_270: + cogl_matrix_rotate (matrix, 270, 0, 0, 1); + cogl_matrix_translate (matrix, -1, 0, 0); + break; + case META_MONITOR_TRANSFORM_FLIPPED: + cogl_matrix_scale (matrix, -1, 1, 1); + cogl_matrix_translate (matrix, -1, 0, 0); + break; + case META_MONITOR_TRANSFORM_FLIPPED_90: + cogl_matrix_scale (matrix, -1, 1, 1); + cogl_matrix_rotate (matrix, 90, 0, 0, 1); + break; + case META_MONITOR_TRANSFORM_FLIPPED_180: + cogl_matrix_scale (matrix, -1, 1, 1); + cogl_matrix_rotate (matrix, 180, 0, 0, 1); + cogl_matrix_translate (matrix, 0, -1, 0); + break; + case META_MONITOR_TRANSFORM_FLIPPED_270: + cogl_matrix_scale (matrix, -1, 1, 1); + cogl_matrix_rotate (matrix, 270, 0, 0, 1); + cogl_matrix_translate (matrix, -1, -1, 0); + break; + } +} + +static void +meta_renderer_view_setup_offscreen_blit_pipeline (ClutterStageView *view, + CoglPipeline *pipeline) +{ + CoglMatrix matrix; + + meta_renderer_view_get_offscreen_transformation_matrix (view, &matrix); + cogl_pipeline_set_layer_matrix (pipeline, 0, &matrix); +} + +static void +meta_renderer_view_set_transform (MetaRendererView *view, + MetaMonitorTransform transform) +{ + if (view->transform == transform) + return; + + view->transform = transform; + clutter_stage_view_invalidate_offscreen_blit_pipeline (CLUTTER_STAGE_VIEW (view)); +} + +static void +meta_renderer_view_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaRendererView *view = META_RENDERER_VIEW (object); + + switch (prop_id) + { + case PROP_TRANSFORM: + g_value_set_uint (value, view->transform); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_renderer_view_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaRendererView *view = META_RENDERER_VIEW (object); + + switch (prop_id) + { + case PROP_TRANSFORM: + meta_renderer_view_set_transform (view, g_value_get_uint (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_renderer_view_init (MetaRendererView *view) +{ +} + +static void +meta_renderer_view_class_init (MetaRendererViewClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + ClutterStageViewClass *view_class = CLUTTER_STAGE_VIEW_CLASS (klass); + + view_class->setup_offscreen_blit_pipeline = + meta_renderer_view_setup_offscreen_blit_pipeline; + view_class->get_offscreen_transformation_matrix = + meta_renderer_view_get_offscreen_transformation_matrix; + + object_class->get_property = meta_renderer_view_get_property; + object_class->set_property = meta_renderer_view_set_property; + + obj_props[PROP_TRANSFORM] = + g_param_spec_uint ("transform", + "Transform", + "Transform to apply to the view", + META_MONITOR_TRANSFORM_NORMAL, + META_MONITOR_TRANSFORM_FLIPPED_270, + META_MONITOR_TRANSFORM_NORMAL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, PROP_LAST, obj_props); +} diff --git a/src/backends/meta-renderer-view.h b/src/backends/meta-renderer-view.h new file mode 100644 index 000000000..f601de534 --- /dev/null +++ b/src/backends/meta-renderer-view.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2016 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef META_RENDERER_VIEW_H +#define META_RENDERER_VIEW_H + +#include "backends/meta-monitor-manager-private.h" +#include "clutter/clutter-mutter.h" + +#define META_TYPE_RENDERER_VIEW (meta_renderer_view_get_type ()) +G_DECLARE_FINAL_TYPE (MetaRendererView, meta_renderer_view, + META, RENDERER_VIEW, + ClutterStageViewCogl) + +MetaMonitorTransform meta_renderer_view_get_transform (MetaRendererView *view); + +#endif /* META_RENDERER_VIEW_H */ diff --git a/src/backends/meta-renderer.c b/src/backends/meta-renderer.c new file mode 100644 index 000000000..983a570e1 --- /dev/null +++ b/src/backends/meta-renderer.c @@ -0,0 +1,293 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +/** + * SECTION:meta-renderer + * @title: MetaRenderer + * @short_description: Keeps track of the different renderer views. + * + * A MetaRenderer object has 2 functions: + * + * 1) Keeping a list of #MetaRendererView<!-- -->s, each responsible for + * rendering a part of the stage, corresponding to each #MetaLogicalMonitor. It + * keeps track of this list by querying the list of logical monitors in the + * #MetaBackend's #MetaMonitorManager, and creating a renderer view for each + * logical monitor it encounters. + * + * 2) Creating and setting up an appropriate #CoglRenderer. For example, a + * #MetaRenderer might call cogl_renderer_set_custom_winsys() to tie the + * backend-specific mechanisms into Cogl. + */ + +#include "config.h" + +#include "backends/meta-renderer.h" + +#include <glib-object.h> + +#include "backends/meta-backend-private.h" +#include "backends/meta-logical-monitor.h" + +enum +{ + PROP_0, + + PROP_BACKEND, + + N_PROPS +}; + +static GParamSpec *obj_props[N_PROPS]; + +typedef struct _MetaRendererPrivate +{ + MetaBackend *backend; + GList *views; +} MetaRendererPrivate; + +G_DEFINE_TYPE_WITH_PRIVATE (MetaRenderer, meta_renderer, G_TYPE_OBJECT) + +MetaBackend * +meta_renderer_get_backend (MetaRenderer *renderer) +{ + MetaRendererPrivate *priv = meta_renderer_get_instance_private (renderer); + + return priv->backend; +} + +/** + * meta_renderer_create_cogl_renderer: + * @renderer: a #MetaRenderer object + * + * Creates a #CoglRenderer that is appropriate for a certain backend. For + * example, a #MetaRenderer might call cogl_renderer_set_custom_winsys() to tie + * the backend-specific mechanisms (such as swapBuffers and vsync) into Cogl. + * + * Returns: (transfer full): a newly made #CoglRenderer. + */ +CoglRenderer * +meta_renderer_create_cogl_renderer (MetaRenderer *renderer) +{ + return META_RENDERER_GET_CLASS (renderer)->create_cogl_renderer (renderer); +} + +static MetaRendererView * +meta_renderer_create_view (MetaRenderer *renderer, + MetaLogicalMonitor *logical_monitor, + MetaOutput *output, + MetaCrtc *crtc) +{ + return META_RENDERER_GET_CLASS (renderer)->create_view (renderer, + logical_monitor, + output, + crtc); +} + +/** + * meta_renderer_rebuild_views: + * @renderer: a #MetaRenderer object + * + * Rebuilds the internal list of #MetaRendererView objects by querying the + * current #MetaBackend's #MetaMonitorManager. + * + * This also leads to the original list of monitors being unconditionally freed. + */ +void +meta_renderer_rebuild_views (MetaRenderer *renderer) +{ + return META_RENDERER_GET_CLASS (renderer)->rebuild_views (renderer); +} + +static void +create_crtc_view (MetaLogicalMonitor *logical_monitor, + MetaMonitor *monitor, + MetaOutput *output, + MetaCrtc *crtc, + gpointer user_data) +{ + MetaRenderer *renderer = user_data; + MetaRendererPrivate *priv = meta_renderer_get_instance_private (renderer); + MetaRendererView *view; + + view = meta_renderer_create_view (renderer, logical_monitor, output, crtc); + priv->views = g_list_append (priv->views, view); +} + +static void +meta_renderer_real_rebuild_views (MetaRenderer *renderer) +{ + MetaRendererPrivate *priv = meta_renderer_get_instance_private (renderer); + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + GList *logical_monitors, *l; + + g_list_free_full (priv->views, g_object_unref); + priv->views = NULL; + + logical_monitors = + meta_monitor_manager_get_logical_monitors (monitor_manager); + + for (l = logical_monitors; l; l = l->next) + { + MetaLogicalMonitor *logical_monitor = l->data; + + meta_logical_monitor_foreach_crtc (logical_monitor, + create_crtc_view, + renderer); + } +} + +void +meta_renderer_add_view (MetaRenderer *renderer, + MetaRendererView *view) +{ + MetaRendererPrivate *priv = meta_renderer_get_instance_private (renderer); + + priv->views = g_list_append (priv->views, view); +} + +/** + * meta_renderer_get_views: + * @renderer: a #MetaRenderer object + * + * Returns a list of #MetaRendererView objects, each dealing with a part of the + * stage. + * + * Returns: (transfer none) (element-type MetaRendererView): a list of + * #MetaRendererView objects. + */ +GList * +meta_renderer_get_views (MetaRenderer *renderer) +{ + MetaRendererPrivate *priv = meta_renderer_get_instance_private (renderer); + + return priv->views; +} + +gboolean +meta_renderer_is_hardware_accelerated (MetaRenderer *renderer) +{ + MetaRendererPrivate *priv = meta_renderer_get_instance_private (renderer); + MetaBackend *backend = priv->backend; + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + CoglContext *cogl_context = + clutter_backend_get_cogl_context (clutter_backend); + CoglGpuInfo *info = &cogl_context->gpu; + + switch (info->architecture) + { + case COGL_GPU_INFO_ARCHITECTURE_UNKNOWN: + case COGL_GPU_INFO_ARCHITECTURE_SANDYBRIDGE: + case COGL_GPU_INFO_ARCHITECTURE_SGX: + case COGL_GPU_INFO_ARCHITECTURE_MALI: + return TRUE; + case COGL_GPU_INFO_ARCHITECTURE_LLVMPIPE: + case COGL_GPU_INFO_ARCHITECTURE_SOFTPIPE: + case COGL_GPU_INFO_ARCHITECTURE_SWRAST: + return FALSE; + } + + g_assert_not_reached (); + return FALSE; +} + +static void +meta_renderer_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaRenderer *renderer = META_RENDERER (object); + MetaRendererPrivate *priv = meta_renderer_get_instance_private (renderer); + + switch (prop_id) + { + case PROP_BACKEND: + g_value_set_object (value, priv->backend); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_renderer_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaRenderer *renderer = META_RENDERER (object); + MetaRendererPrivate *priv = meta_renderer_get_instance_private (renderer); + + switch (prop_id) + { + case PROP_BACKEND: + priv->backend = g_value_get_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_renderer_finalize (GObject *object) +{ + MetaRenderer *renderer = META_RENDERER (object); + MetaRendererPrivate *priv = meta_renderer_get_instance_private (renderer); + + g_list_free_full (priv->views, g_object_unref); + priv->views = NULL; + + G_OBJECT_CLASS (meta_renderer_parent_class)->finalize (object); +} + +static void +meta_renderer_init (MetaRenderer *renderer) +{ +} + +static void +meta_renderer_class_init (MetaRendererClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = meta_renderer_get_property; + object_class->set_property = meta_renderer_set_property; + object_class->finalize = meta_renderer_finalize; + + klass->rebuild_views = meta_renderer_real_rebuild_views; + + obj_props[PROP_BACKEND] = + g_param_spec_object ("backend", + "backend", + "MetaBackend", + META_TYPE_BACKEND, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + g_object_class_install_properties (object_class, N_PROPS, obj_props); +} diff --git a/src/backends/meta-renderer.h b/src/backends/meta-renderer.h new file mode 100644 index 000000000..247d2c2aa --- /dev/null +++ b/src/backends/meta-renderer.h @@ -0,0 +1,65 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +#ifndef META_RENDERER_H +#define META_RENDERER_H + +#include <glib-object.h> + +#include "backends/meta-monitor-manager-private.h" +#include "backends/meta-renderer-view.h" +#include "core/util-private.h" +#include "clutter/clutter-mutter.h" +#include "cogl/cogl.h" + +#define META_TYPE_RENDERER (meta_renderer_get_type ()) +G_DECLARE_DERIVABLE_TYPE (MetaRenderer, meta_renderer, META, RENDERER, GObject) + +struct _MetaRendererClass +{ + GObjectClass parent_class; + + CoglRenderer * (* create_cogl_renderer) (MetaRenderer *renderer); + MetaRendererView * (* create_view) (MetaRenderer *renderer, + MetaLogicalMonitor *logical_monitor, + MetaOutput *output, + MetaCrtc *crtc); + void (* rebuild_views) (MetaRenderer *renderer); +}; + +MetaBackend * meta_renderer_get_backend (MetaRenderer *renderer); + +CoglRenderer * meta_renderer_create_cogl_renderer (MetaRenderer *renderer); + +void meta_renderer_rebuild_views (MetaRenderer *renderer); + +void meta_renderer_add_view (MetaRenderer *renderer, + MetaRendererView *view); + +META_EXPORT_TEST +GList * meta_renderer_get_views (MetaRenderer *renderer); + +gboolean meta_renderer_is_hardware_accelerated (MetaRenderer *renderer); + +#endif /* META_RENDERER_H */ diff --git a/src/backends/meta-screen-cast-monitor-stream-src.c b/src/backends/meta-screen-cast-monitor-stream-src.c new file mode 100644 index 000000000..7c35b3c76 --- /dev/null +++ b/src/backends/meta-screen-cast-monitor-stream-src.c @@ -0,0 +1,609 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#include "config.h" + +#include "backends/meta-screen-cast-monitor-stream-src.h" + +#include <spa/buffer/meta.h> + +#include "backends/meta-backend-private.h" +#include "backends/meta-cursor-tracker-private.h" +#include "backends/meta-logical-monitor.h" +#include "backends/meta-monitor.h" +#include "backends/meta-screen-cast-monitor-stream.h" +#include "backends/meta-screen-cast-session.h" +#include "backends/meta-stage-private.h" +#include "clutter/clutter.h" +#include "clutter/clutter-mutter.h" +#include "core/boxes-private.h" + +struct _MetaScreenCastMonitorStreamSrc +{ + MetaScreenCastStreamSrc parent; + + gboolean cursor_bitmap_invalid; + gboolean hw_cursor_inhibited; + + GList *watches; + + gulong cursor_moved_handler_id; + gulong cursor_changed_handler_id; +}; + +static void +hw_cursor_inhibitor_iface_init (MetaHwCursorInhibitorInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (MetaScreenCastMonitorStreamSrc, + meta_screen_cast_monitor_stream_src, + META_TYPE_SCREEN_CAST_STREAM_SRC, + G_IMPLEMENT_INTERFACE (META_TYPE_HW_CURSOR_INHIBITOR, + hw_cursor_inhibitor_iface_init)) + +static ClutterStage * +get_stage (MetaScreenCastMonitorStreamSrc *monitor_src) +{ + MetaScreenCastStreamSrc *src; + MetaScreenCastStream *stream; + MetaScreenCastMonitorStream *monitor_stream; + + src = META_SCREEN_CAST_STREAM_SRC (monitor_src); + stream = meta_screen_cast_stream_src_get_stream (src); + monitor_stream = META_SCREEN_CAST_MONITOR_STREAM (stream); + + return meta_screen_cast_monitor_stream_get_stage (monitor_stream); +} + +static MetaMonitor * +get_monitor (MetaScreenCastMonitorStreamSrc *monitor_src) +{ + MetaScreenCastStreamSrc *src; + MetaScreenCastStream *stream; + MetaScreenCastMonitorStream *monitor_stream; + + src = META_SCREEN_CAST_STREAM_SRC (monitor_src); + stream = meta_screen_cast_stream_src_get_stream (src); + monitor_stream = META_SCREEN_CAST_MONITOR_STREAM (stream); + + return meta_screen_cast_monitor_stream_get_monitor (monitor_stream); +} + +static void +meta_screen_cast_monitor_stream_src_get_specs (MetaScreenCastStreamSrc *src, + int *width, + int *height, + float *frame_rate) +{ + MetaScreenCastMonitorStreamSrc *monitor_src = + META_SCREEN_CAST_MONITOR_STREAM_SRC (src); + MetaMonitor *monitor; + MetaLogicalMonitor *logical_monitor; + float scale; + MetaMonitorMode *mode; + + monitor = get_monitor (monitor_src); + logical_monitor = meta_monitor_get_logical_monitor (monitor); + mode = meta_monitor_get_current_mode (monitor); + + if (meta_is_stage_views_scaled ()) + scale = logical_monitor->scale; + else + scale = 1.0; + + *width = (int) roundf (logical_monitor->rect.width * scale); + *height = (int) roundf (logical_monitor->rect.height * scale); + *frame_rate = meta_monitor_mode_get_refresh_rate (mode); +} + +static void +stage_painted (MetaStage *stage, + ClutterStageView *view, + ClutterPaintContext *paint_context, + gpointer user_data) +{ + MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (user_data); + MetaScreenCastRecordFlag flags; + + flags = META_SCREEN_CAST_RECORD_FLAG_NONE; + meta_screen_cast_stream_src_maybe_record_frame (src, flags); +} + +static MetaBackend * +get_backend (MetaScreenCastMonitorStreamSrc *monitor_src) +{ + MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (monitor_src); + MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src); + MetaScreenCastSession *session = meta_screen_cast_stream_get_session (stream); + MetaScreenCast *screen_cast = + meta_screen_cast_session_get_screen_cast (session); + + return meta_screen_cast_get_backend (screen_cast); +} + +static gboolean +is_cursor_in_stream (MetaScreenCastMonitorStreamSrc *monitor_src) +{ + MetaBackend *backend = get_backend (monitor_src); + MetaCursorRenderer *cursor_renderer = + meta_backend_get_cursor_renderer (backend); + MetaMonitor *monitor; + MetaLogicalMonitor *logical_monitor; + MetaRectangle logical_monitor_layout; + graphene_rect_t logical_monitor_rect; + MetaCursorSprite *cursor_sprite; + + monitor = get_monitor (monitor_src); + logical_monitor = meta_monitor_get_logical_monitor (monitor); + logical_monitor_layout = meta_logical_monitor_get_layout (logical_monitor); + logical_monitor_rect = + meta_rectangle_to_graphene_rect (&logical_monitor_layout); + + cursor_sprite = meta_cursor_renderer_get_cursor (cursor_renderer); + if (cursor_sprite) + { + graphene_rect_t cursor_rect; + + cursor_rect = meta_cursor_renderer_calculate_rect (cursor_renderer, + cursor_sprite); + return graphene_rect_intersection (&cursor_rect, + &logical_monitor_rect, + NULL); + } + else + { + graphene_point_t cursor_position; + + cursor_position = meta_cursor_renderer_get_position (cursor_renderer); + return graphene_rect_contains_point (&logical_monitor_rect, + &cursor_position); + } +} + +static void +sync_cursor_state (MetaScreenCastMonitorStreamSrc *monitor_src) +{ + MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (monitor_src); + ClutterStage *stage = get_stage (monitor_src); + MetaScreenCastRecordFlag flags; + + if (clutter_stage_is_redraw_queued (stage)) + return; + + if (meta_screen_cast_stream_src_pending_follow_up_frame (src)) + return; + + flags = META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY; + meta_screen_cast_stream_src_maybe_record_frame (src, flags); +} + +static void +cursor_moved (MetaCursorTracker *cursor_tracker, + float x, + float y, + MetaScreenCastMonitorStreamSrc *monitor_src) +{ + sync_cursor_state (monitor_src); +} + +static void +cursor_changed (MetaCursorTracker *cursor_tracker, + MetaScreenCastMonitorStreamSrc *monitor_src) +{ + monitor_src->cursor_bitmap_invalid = TRUE; + sync_cursor_state (monitor_src); +} + +static MetaCursorRenderer * +get_cursor_renderer (MetaScreenCastMonitorStreamSrc *monitor_src) +{ + MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (monitor_src); + MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src); + MetaScreenCastSession *session = meta_screen_cast_stream_get_session (stream); + MetaScreenCast *screen_cast = + meta_screen_cast_session_get_screen_cast (session); + MetaBackend *backend = meta_screen_cast_get_backend (screen_cast); + + return meta_backend_get_cursor_renderer (backend); +} + +static void +inhibit_hw_cursor (MetaScreenCastMonitorStreamSrc *monitor_src) +{ + MetaCursorRenderer *cursor_renderer; + MetaHwCursorInhibitor *inhibitor; + + g_return_if_fail (!monitor_src->hw_cursor_inhibited); + + cursor_renderer = get_cursor_renderer (monitor_src); + inhibitor = META_HW_CURSOR_INHIBITOR (monitor_src); + meta_cursor_renderer_add_hw_cursor_inhibitor (cursor_renderer, inhibitor); + + monitor_src->hw_cursor_inhibited = TRUE; +} + +static void +uninhibit_hw_cursor (MetaScreenCastMonitorStreamSrc *monitor_src) +{ + MetaCursorRenderer *cursor_renderer; + MetaHwCursorInhibitor *inhibitor; + + g_return_if_fail (monitor_src->hw_cursor_inhibited); + + cursor_renderer = get_cursor_renderer (monitor_src); + inhibitor = META_HW_CURSOR_INHIBITOR (monitor_src); + meta_cursor_renderer_remove_hw_cursor_inhibitor (cursor_renderer, inhibitor); + + monitor_src->hw_cursor_inhibited = FALSE; +} + +static void +add_view_painted_watches (MetaScreenCastMonitorStreamSrc *monitor_src, + MetaStageWatchPhase watch_phase) +{ + MetaBackend *backend = get_backend (monitor_src); + MetaRenderer *renderer = meta_backend_get_renderer (backend); + ClutterStage *stage; + MetaStage *meta_stage; + MetaMonitor *monitor; + MetaLogicalMonitor *logical_monitor; + MetaRectangle logical_monitor_layout; + GList *l; + + stage = get_stage (monitor_src); + meta_stage = META_STAGE (stage); + monitor = get_monitor (monitor_src); + logical_monitor = meta_monitor_get_logical_monitor (monitor); + logical_monitor_layout = meta_logical_monitor_get_layout (logical_monitor); + + for (l = meta_renderer_get_views (renderer); l; l = l->next) + { + MetaRendererView *view = l->data; + MetaRectangle view_layout; + + clutter_stage_view_get_layout (CLUTTER_STAGE_VIEW (view), &view_layout); + if (meta_rectangle_overlap (&logical_monitor_layout, &view_layout)) + { + MetaStageWatch *watch; + + watch = meta_stage_watch_view (meta_stage, + CLUTTER_STAGE_VIEW (view), + watch_phase, + stage_painted, + monitor_src); + + monitor_src->watches = g_list_prepend (monitor_src->watches, watch); + } + } +} + +static void +meta_screen_cast_monitor_stream_src_enable (MetaScreenCastStreamSrc *src) +{ + MetaScreenCastMonitorStreamSrc *monitor_src = + META_SCREEN_CAST_MONITOR_STREAM_SRC (src); + MetaBackend *backend = get_backend (monitor_src); + MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend); + ClutterStage *stage; + MetaScreenCastStream *stream; + + stream = meta_screen_cast_stream_src_get_stream (src); + stage = get_stage (monitor_src); + + switch (meta_screen_cast_stream_get_cursor_mode (stream)) + { + case META_SCREEN_CAST_CURSOR_MODE_METADATA: + monitor_src->cursor_moved_handler_id = + g_signal_connect_after (cursor_tracker, "cursor-moved", + G_CALLBACK (cursor_moved), + monitor_src); + monitor_src->cursor_changed_handler_id = + g_signal_connect_after (cursor_tracker, "cursor-changed", + G_CALLBACK (cursor_changed), + monitor_src); + G_GNUC_FALLTHROUGH; + case META_SCREEN_CAST_CURSOR_MODE_HIDDEN: + add_view_painted_watches (monitor_src, + META_STAGE_WATCH_AFTER_ACTOR_PAINT); + break; + case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED: + inhibit_hw_cursor (monitor_src); + add_view_painted_watches (monitor_src, + META_STAGE_WATCH_AFTER_PAINT); + break; + } + + clutter_actor_queue_redraw (CLUTTER_ACTOR (stage)); +} + +static void +meta_screen_cast_monitor_stream_src_disable (MetaScreenCastStreamSrc *src) +{ + MetaScreenCastMonitorStreamSrc *monitor_src = + META_SCREEN_CAST_MONITOR_STREAM_SRC (src); + MetaBackend *backend = get_backend (monitor_src); + MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend); + ClutterStage *stage; + MetaStage *meta_stage; + GList *l; + + stage = get_stage (monitor_src); + meta_stage = META_STAGE (stage); + + for (l = monitor_src->watches; l; l = l->next) + { + MetaStageWatch *watch = l->data; + + meta_stage_remove_watch (meta_stage, watch); + } + g_clear_pointer (&monitor_src->watches, g_list_free); + + if (monitor_src->hw_cursor_inhibited) + uninhibit_hw_cursor (monitor_src); + + g_clear_signal_handler (&monitor_src->cursor_moved_handler_id, + cursor_tracker); + g_clear_signal_handler (&monitor_src->cursor_changed_handler_id, + cursor_tracker); +} + +static gboolean +meta_screen_cast_monitor_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src, + uint8_t *data, + GError **error) +{ + MetaScreenCastMonitorStreamSrc *monitor_src = + META_SCREEN_CAST_MONITOR_STREAM_SRC (src); + ClutterStage *stage; + MetaMonitor *monitor; + MetaLogicalMonitor *logical_monitor; + + stage = get_stage (monitor_src); + monitor = get_monitor (monitor_src); + logical_monitor = meta_monitor_get_logical_monitor (monitor); + clutter_stage_capture_into (stage, FALSE, &logical_monitor->rect, data); + + return TRUE; +} + +static gboolean +meta_screen_cast_monitor_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src, + CoglFramebuffer *framebuffer, + GError **error) +{ + MetaScreenCastMonitorStreamSrc *monitor_src = + META_SCREEN_CAST_MONITOR_STREAM_SRC (src); + MetaBackend *backend = get_backend (monitor_src); + MetaRenderer *renderer = meta_backend_get_renderer (backend); + MetaMonitor *monitor; + MetaLogicalMonitor *logical_monitor; + MetaRectangle logical_monitor_layout; + GList *l; + float view_scale; + + monitor = get_monitor (monitor_src); + logical_monitor = meta_monitor_get_logical_monitor (monitor); + logical_monitor_layout = meta_logical_monitor_get_layout (logical_monitor); + + if (meta_is_stage_views_scaled ()) + view_scale = meta_logical_monitor_get_scale (logical_monitor); + else + view_scale = 1.0; + + for (l = meta_renderer_get_views (renderer); l; l = l->next) + { + ClutterStageView *view = CLUTTER_STAGE_VIEW (l->data); + CoglFramebuffer *view_framebuffer; + MetaRectangle view_layout; + int x, y; + + clutter_stage_view_get_layout (view, &view_layout); + + if (!meta_rectangle_overlap (&logical_monitor_layout, &view_layout)) + continue; + + view_framebuffer = clutter_stage_view_get_framebuffer (view); + + x = (int) roundf ((view_layout.x - logical_monitor_layout.x) * view_scale); + y = (int) roundf ((view_layout.y - logical_monitor_layout.y) * view_scale); + + if (!cogl_blit_framebuffer (view_framebuffer, + framebuffer, + 0, 0, + x, y, + cogl_framebuffer_get_width (view_framebuffer), + cogl_framebuffer_get_height (view_framebuffer), + error)) + return FALSE; + } + + cogl_framebuffer_finish (framebuffer); + + return TRUE; +} + +static void +meta_screen_cast_monitor_stream_record_follow_up (MetaScreenCastStreamSrc *src) +{ + MetaScreenCastMonitorStreamSrc *monitor_src = + META_SCREEN_CAST_MONITOR_STREAM_SRC (src); + MetaBackend *backend = get_backend (monitor_src); + MetaRenderer *renderer = meta_backend_get_renderer (backend); + ClutterStage *stage = get_stage (monitor_src); + MetaMonitor *monitor; + MetaLogicalMonitor *logical_monitor; + MetaRectangle logical_monitor_layout; + GList *l; + + monitor = get_monitor (monitor_src); + logical_monitor = meta_monitor_get_logical_monitor (monitor); + logical_monitor_layout = meta_logical_monitor_get_layout (logical_monitor); + + for (l = meta_renderer_get_views (renderer); l; l = l->next) + { + MetaRendererView *view = l->data; + MetaRectangle view_layout; + MetaRectangle damage; + + clutter_stage_view_get_layout (CLUTTER_STAGE_VIEW (view), &view_layout); + + if (!meta_rectangle_overlap (&logical_monitor_layout, &view_layout)) + continue; + + damage = (cairo_rectangle_int_t) { + .x = view_layout.x, + .y = view_layout.y, + .width = 1, + .height = 1, + }; + clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stage), &damage); + } +} + +static void +meta_screen_cast_monitor_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc *src, + struct spa_meta_cursor *spa_meta_cursor) +{ + MetaScreenCastMonitorStreamSrc *monitor_src = + META_SCREEN_CAST_MONITOR_STREAM_SRC (src); + MetaBackend *backend = get_backend (monitor_src); + MetaCursorRenderer *cursor_renderer = + meta_backend_get_cursor_renderer (backend); + MetaCursorSprite *cursor_sprite; + MetaMonitor *monitor; + MetaLogicalMonitor *logical_monitor; + MetaRectangle logical_monitor_layout; + graphene_rect_t logical_monitor_rect; + float view_scale; + graphene_point_t cursor_position; + int x, y; + + cursor_sprite = meta_cursor_renderer_get_cursor (cursor_renderer); + + if (!is_cursor_in_stream (monitor_src)) + { + meta_screen_cast_stream_src_unset_cursor_metadata (src, + spa_meta_cursor); + return; + } + + monitor = get_monitor (monitor_src); + logical_monitor = meta_monitor_get_logical_monitor (monitor); + logical_monitor_layout = meta_logical_monitor_get_layout (logical_monitor); + logical_monitor_rect = + meta_rectangle_to_graphene_rect (&logical_monitor_layout); + + if (meta_is_stage_views_scaled ()) + view_scale = meta_logical_monitor_get_scale (logical_monitor); + else + view_scale = 1.0; + + cursor_position = meta_cursor_renderer_get_position (cursor_renderer); + cursor_position.x -= logical_monitor_rect.origin.x; + cursor_position.y -= logical_monitor_rect.origin.y; + cursor_position.x *= view_scale; + cursor_position.y *= view_scale; + + x = (int) roundf (cursor_position.x); + y = (int) roundf (cursor_position.y); + + if (monitor_src->cursor_bitmap_invalid) + { + if (cursor_sprite) + { + float cursor_scale; + float scale; + + cursor_scale = meta_cursor_sprite_get_texture_scale (cursor_sprite); + scale = view_scale * cursor_scale; + meta_screen_cast_stream_src_set_cursor_sprite_metadata (src, + spa_meta_cursor, + cursor_sprite, + x, y, + scale); + } + else + { + meta_screen_cast_stream_src_set_empty_cursor_sprite_metadata (src, + spa_meta_cursor, + x, y); + } + + monitor_src->cursor_bitmap_invalid = FALSE; + } + else + { + meta_screen_cast_stream_src_set_cursor_position_metadata (src, + spa_meta_cursor, + x, y); + } +} + +static gboolean +meta_screen_cast_monitor_stream_src_is_cursor_sprite_inhibited (MetaHwCursorInhibitor *inhibitor, + MetaCursorSprite *cursor_sprite) +{ + MetaScreenCastMonitorStreamSrc *monitor_src = + META_SCREEN_CAST_MONITOR_STREAM_SRC (inhibitor); + + return is_cursor_in_stream (monitor_src); +} + +static void +hw_cursor_inhibitor_iface_init (MetaHwCursorInhibitorInterface *iface) +{ + iface->is_cursor_sprite_inhibited = + meta_screen_cast_monitor_stream_src_is_cursor_sprite_inhibited; +} + +MetaScreenCastMonitorStreamSrc * +meta_screen_cast_monitor_stream_src_new (MetaScreenCastMonitorStream *monitor_stream, + GError **error) +{ + return g_initable_new (META_TYPE_SCREEN_CAST_MONITOR_STREAM_SRC, NULL, error, + "stream", monitor_stream, + NULL); +} + +static void +meta_screen_cast_monitor_stream_src_init (MetaScreenCastMonitorStreamSrc *monitor_src) +{ + monitor_src->cursor_bitmap_invalid = TRUE; +} + +static void +meta_screen_cast_monitor_stream_src_class_init (MetaScreenCastMonitorStreamSrcClass *klass) +{ + MetaScreenCastStreamSrcClass *src_class = + META_SCREEN_CAST_STREAM_SRC_CLASS (klass); + + src_class->get_specs = meta_screen_cast_monitor_stream_src_get_specs; + src_class->enable = meta_screen_cast_monitor_stream_src_enable; + src_class->disable = meta_screen_cast_monitor_stream_src_disable; + src_class->record_to_buffer = + meta_screen_cast_monitor_stream_src_record_to_buffer; + src_class->record_to_framebuffer = + meta_screen_cast_monitor_stream_src_record_to_framebuffer; + src_class->record_follow_up = + meta_screen_cast_monitor_stream_record_follow_up; + src_class->set_cursor_metadata = + meta_screen_cast_monitor_stream_src_set_cursor_metadata; +} diff --git a/src/backends/meta-screen-cast-monitor-stream-src.h b/src/backends/meta-screen-cast-monitor-stream-src.h new file mode 100644 index 000000000..7417a81e0 --- /dev/null +++ b/src/backends/meta-screen-cast-monitor-stream-src.h @@ -0,0 +1,40 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#ifndef META_SCREEN_CAST_MONITOR_STREAM_SRC_H +#define META_SCREEN_CAST_MONITOR_STREAM_SRC_H + +#include "backends/meta-monitor-manager-private.h" +#include "backends/meta-screen-cast-stream-src.h" + +typedef struct _MetaScreenCastMonitorStream MetaScreenCastMonitorStream; + +#define META_TYPE_SCREEN_CAST_MONITOR_STREAM_SRC (meta_screen_cast_monitor_stream_src_get_type ()) +G_DECLARE_FINAL_TYPE (MetaScreenCastMonitorStreamSrc, + meta_screen_cast_monitor_stream_src, + META, SCREEN_CAST_MONITOR_STREAM_SRC, + MetaScreenCastStreamSrc) + +MetaScreenCastMonitorStreamSrc * meta_screen_cast_monitor_stream_src_new (MetaScreenCastMonitorStream *monitor_stream, + GError **error); + +#endif /* META_SCREEN_CAST_MONITOR_STREAM_SRC_H */ diff --git a/src/backends/meta-screen-cast-monitor-stream.c b/src/backends/meta-screen-cast-monitor-stream.c new file mode 100644 index 000000000..4de430a25 --- /dev/null +++ b/src/backends/meta-screen-cast-monitor-stream.c @@ -0,0 +1,286 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#include "config.h" + +#include "backends/meta-screen-cast-monitor-stream.h" + +#include "backends/meta-logical-monitor.h" +#include "backends/meta-screen-cast-monitor-stream-src.h" + +enum +{ + PROP_0, + + PROP_MONITOR, +}; + +struct _MetaScreenCastMonitorStream +{ + MetaScreenCastStream parent; + + ClutterStage *stage; + + MetaMonitor *monitor; + MetaLogicalMonitor *logical_monitor; +}; + +G_DEFINE_TYPE (MetaScreenCastMonitorStream, + meta_screen_cast_monitor_stream, + META_TYPE_SCREEN_CAST_STREAM) + +static gboolean +update_monitor (MetaScreenCastMonitorStream *monitor_stream, + MetaMonitor *new_monitor) +{ + MetaLogicalMonitor *new_logical_monitor; + + new_logical_monitor = meta_monitor_get_logical_monitor (new_monitor); + if (!new_logical_monitor) + return FALSE; + + if (!meta_rectangle_equal (&new_logical_monitor->rect, + &monitor_stream->logical_monitor->rect)) + return FALSE; + + g_set_object (&monitor_stream->monitor, new_monitor); + g_set_object (&monitor_stream->logical_monitor, new_logical_monitor); + + return TRUE; +} + +static void +on_monitors_changed (MetaMonitorManager *monitor_manager, + MetaScreenCastMonitorStream *monitor_stream) +{ + MetaMonitor *new_monitor = NULL; + GList *monitors; + GList *l; + + monitors = meta_monitor_manager_get_monitors (monitor_manager); + for (l = monitors; l; l = l->next) + { + MetaMonitor *other_monitor = l->data; + + if (meta_monitor_is_same_as (monitor_stream->monitor, other_monitor)) + { + new_monitor = other_monitor; + break; + } + } + + if (!new_monitor || !update_monitor (monitor_stream, new_monitor)) + meta_screen_cast_stream_close (META_SCREEN_CAST_STREAM (monitor_stream)); +} + +ClutterStage * +meta_screen_cast_monitor_stream_get_stage (MetaScreenCastMonitorStream *monitor_stream) +{ + return monitor_stream->stage; +} + +MetaMonitor * +meta_screen_cast_monitor_stream_get_monitor (MetaScreenCastMonitorStream *monitor_stream) +{ + return monitor_stream->monitor; +} + +MetaScreenCastMonitorStream * +meta_screen_cast_monitor_stream_new (MetaScreenCastSession *session, + GDBusConnection *connection, + MetaMonitor *monitor, + ClutterStage *stage, + MetaScreenCastCursorMode cursor_mode, + GError **error) +{ + MetaGpu *gpu = meta_monitor_get_gpu (monitor); + MetaBackend *backend = meta_gpu_get_backend (gpu); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaScreenCastMonitorStream *monitor_stream; + + if (!meta_monitor_is_active (monitor)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Monitor not active"); + return NULL; + } + + monitor_stream = g_initable_new (META_TYPE_SCREEN_CAST_MONITOR_STREAM, + NULL, + error, + "session", session, + "connection", connection, + "cursor-mode", cursor_mode, + "monitor", monitor, + NULL); + if (!monitor_stream) + return NULL; + + monitor_stream->stage = stage; + + g_signal_connect_object (monitor_manager, "monitors-changed-internal", + G_CALLBACK (on_monitors_changed), + monitor_stream, 0); + + return monitor_stream; +} + +static MetaScreenCastStreamSrc * +meta_screen_cast_monitor_stream_create_src (MetaScreenCastStream *stream, + GError **error) +{ + MetaScreenCastMonitorStream *monitor_stream = + META_SCREEN_CAST_MONITOR_STREAM (stream); + MetaScreenCastMonitorStreamSrc *monitor_stream_src; + + monitor_stream_src = meta_screen_cast_monitor_stream_src_new (monitor_stream, + error); + if (!monitor_stream_src) + return NULL; + + return META_SCREEN_CAST_STREAM_SRC (monitor_stream_src); +} + +static void +meta_screen_cast_monitor_stream_set_parameters (MetaScreenCastStream *stream, + GVariantBuilder *parameters_builder) +{ + MetaScreenCastMonitorStream *monitor_stream = + META_SCREEN_CAST_MONITOR_STREAM (stream); + MetaRectangle logical_monitor_layout; + + logical_monitor_layout = + meta_logical_monitor_get_layout (monitor_stream->logical_monitor); + + g_variant_builder_add (parameters_builder, "{sv}", + "position", + g_variant_new ("(ii)", + logical_monitor_layout.x, + logical_monitor_layout.y)); + g_variant_builder_add (parameters_builder, "{sv}", + "size", + g_variant_new ("(ii)", + logical_monitor_layout.width, + logical_monitor_layout.height)); +} + +static void +meta_screen_cast_monitor_stream_transform_position (MetaScreenCastStream *stream, + double stream_x, + double stream_y, + double *x, + double *y) +{ + MetaScreenCastMonitorStream *monitor_stream = + META_SCREEN_CAST_MONITOR_STREAM (stream); + MetaRectangle logical_monitor_layout; + + logical_monitor_layout = + meta_logical_monitor_get_layout (monitor_stream->logical_monitor); + + *x = logical_monitor_layout.x + stream_x; + *y = logical_monitor_layout.y + stream_y; +} + +static void +meta_screen_cast_monitor_stream_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaScreenCastMonitorStream *monitor_stream = + META_SCREEN_CAST_MONITOR_STREAM (object); + MetaLogicalMonitor *logical_monitor; + + switch (prop_id) + { + case PROP_MONITOR: + g_set_object (&monitor_stream->monitor, g_value_get_object (value)); + logical_monitor = meta_monitor_get_logical_monitor (monitor_stream->monitor); + g_set_object (&monitor_stream->logical_monitor, logical_monitor); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_screen_cast_monitor_stream_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaScreenCastMonitorStream *monitor_stream = + META_SCREEN_CAST_MONITOR_STREAM (object); + + switch (prop_id) + { + case PROP_MONITOR: + g_value_set_object (value, monitor_stream->monitor); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_screen_cast_monitor_stream_finalize (GObject *object) +{ + MetaScreenCastMonitorStream *monitor_stream = + META_SCREEN_CAST_MONITOR_STREAM (object); + + g_clear_object (&monitor_stream->monitor); + g_clear_object (&monitor_stream->logical_monitor); + + G_OBJECT_CLASS (meta_screen_cast_monitor_stream_parent_class)->finalize (object); +} + +static void +meta_screen_cast_monitor_stream_init (MetaScreenCastMonitorStream *monitor_stream) +{ +} + +static void +meta_screen_cast_monitor_stream_class_init (MetaScreenCastMonitorStreamClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MetaScreenCastStreamClass *stream_class = + META_SCREEN_CAST_STREAM_CLASS (klass); + + object_class->set_property = meta_screen_cast_monitor_stream_set_property; + object_class->get_property = meta_screen_cast_monitor_stream_get_property; + object_class->finalize = meta_screen_cast_monitor_stream_finalize; + + stream_class->create_src = meta_screen_cast_monitor_stream_create_src; + stream_class->set_parameters = meta_screen_cast_monitor_stream_set_parameters; + stream_class->transform_position = meta_screen_cast_monitor_stream_transform_position; + + g_object_class_install_property (object_class, + PROP_MONITOR, + g_param_spec_object ("monitor", + "monitor", + "MetaMonitor", + META_TYPE_MONITOR, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); +} diff --git a/src/backends/meta-screen-cast-monitor-stream.h b/src/backends/meta-screen-cast-monitor-stream.h new file mode 100644 index 000000000..f8dc04181 --- /dev/null +++ b/src/backends/meta-screen-cast-monitor-stream.h @@ -0,0 +1,49 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#ifndef META_SCREEN_CAST_MONITOR_STREAM_H +#define META_SCREEN_CAST_MONITOR_STREAM_H + +#include <glib-object.h> + +#include "backends/meta-monitor-manager-private.h" +#include "backends/meta-screen-cast-stream.h" +#include "backends/meta-screen-cast.h" + +#define META_TYPE_SCREEN_CAST_MONITOR_STREAM (meta_screen_cast_monitor_stream_get_type ()) +G_DECLARE_FINAL_TYPE (MetaScreenCastMonitorStream, + meta_screen_cast_monitor_stream, + META, SCREEN_CAST_MONITOR_STREAM, + MetaScreenCastStream) + +MetaScreenCastMonitorStream * meta_screen_cast_monitor_stream_new (MetaScreenCastSession *session, + GDBusConnection *connection, + MetaMonitor *monitor, + ClutterStage *stage, + MetaScreenCastCursorMode cursor_mode, + GError **error); + +ClutterStage * meta_screen_cast_monitor_stream_get_stage (MetaScreenCastMonitorStream *monitor_stream); + +MetaMonitor * meta_screen_cast_monitor_stream_get_monitor (MetaScreenCastMonitorStream *monitor_stream); + +#endif /* META_SCREEN_CAST_MONITOR_STREAM_H */ diff --git a/src/backends/meta-screen-cast-session.c b/src/backends/meta-screen-cast-session.c new file mode 100644 index 000000000..7a1b8e07a --- /dev/null +++ b/src/backends/meta-screen-cast-session.c @@ -0,0 +1,599 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2015-2017 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#include "config.h" + +#include "backends/meta-screen-cast-session.h" + +#include "backends/meta-backend-private.h" +#include "backends/meta-dbus-session-watcher.h" +#include "backends/meta-remote-access-controller-private.h" +#include "backends/meta-screen-cast-monitor-stream.h" +#include "backends/meta-screen-cast-stream.h" +#include "backends/meta-screen-cast-window-stream.h" +#include "core/display-private.h" + +#define META_SCREEN_CAST_SESSION_DBUS_PATH "/org/gnome/Mutter/ScreenCast/Session" + +struct _MetaScreenCastSession +{ + MetaDBusScreenCastSessionSkeleton parent; + + MetaScreenCast *screen_cast; + + char *peer_name; + + MetaScreenCastSessionType session_type; + char *object_path; + + GList *streams; + + MetaScreenCastSessionHandle *handle; + + gboolean disable_animations; +}; + +static void +meta_screen_cast_session_init_iface (MetaDBusScreenCastSessionIface *iface); + +static void +meta_dbus_session_init_iface (MetaDbusSessionInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (MetaScreenCastSession, + meta_screen_cast_session, + META_DBUS_TYPE_SCREEN_CAST_SESSION_SKELETON, + G_IMPLEMENT_INTERFACE (META_DBUS_TYPE_SCREEN_CAST_SESSION, + meta_screen_cast_session_init_iface) + G_IMPLEMENT_INTERFACE (META_TYPE_DBUS_SESSION, + meta_dbus_session_init_iface)) + +struct _MetaScreenCastSessionHandle +{ + MetaRemoteAccessHandle parent; + + MetaScreenCastSession *session; +}; + +G_DEFINE_TYPE (MetaScreenCastSessionHandle, + meta_screen_cast_session_handle, + META_TYPE_REMOTE_ACCESS_HANDLE) + +static MetaScreenCastSessionHandle * +meta_screen_cast_session_handle_new (MetaScreenCastSession *session); + +static void +init_remote_access_handle (MetaScreenCastSession *session) +{ + MetaBackend *backend = meta_get_backend (); + MetaRemoteAccessController *remote_access_controller; + MetaRemoteAccessHandle *remote_access_handle; + + session->handle = meta_screen_cast_session_handle_new (session); + + remote_access_controller = meta_backend_get_remote_access_controller (backend); + remote_access_handle = META_REMOTE_ACCESS_HANDLE (session->handle); + + meta_remote_access_handle_set_disable_animations (remote_access_handle, + session->disable_animations); + + meta_remote_access_controller_notify_new_handle (remote_access_controller, + remote_access_handle); +} + +gboolean +meta_screen_cast_session_start (MetaScreenCastSession *session, + GError **error) +{ + GList *l; + + for (l = session->streams; l; l = l->next) + { + MetaScreenCastStream *stream = l->data; + + if (!meta_screen_cast_stream_start (stream, error)) + return FALSE; + } + + init_remote_access_handle (session); + + return TRUE; +} + +void +meta_screen_cast_session_close (MetaScreenCastSession *session) +{ + MetaDBusScreenCastSession *skeleton = META_DBUS_SCREEN_CAST_SESSION (session); + + g_list_free_full (session->streams, g_object_unref); + + meta_dbus_session_notify_closed (META_DBUS_SESSION (session)); + + switch (session->session_type) + { + case META_SCREEN_CAST_SESSION_TYPE_NORMAL: + meta_dbus_screen_cast_session_emit_closed (skeleton); + break; + case META_SCREEN_CAST_SESSION_TYPE_REMOTE_DESKTOP: + break; + } + + g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (session)); + + if (session->handle) + { + MetaRemoteAccessHandle *remote_access_handle = + META_REMOTE_ACCESS_HANDLE (session->handle); + + meta_remote_access_handle_notify_stopped (remote_access_handle); + } + + g_object_unref (session); +} + +MetaScreenCastStream * +meta_screen_cast_session_get_stream (MetaScreenCastSession *session, + const char *path) +{ + GList *l; + + for (l = session->streams; l; l = l->next) + { + MetaScreenCastStream *stream = l->data; + + if (g_strcmp0 (meta_screen_cast_stream_get_object_path (stream), + path) == 0) + return stream; + } + + return NULL; +} + +MetaScreenCast * +meta_screen_cast_session_get_screen_cast (MetaScreenCastSession *session) +{ + return session->screen_cast; +} + +void +meta_screen_cast_session_set_disable_animations (MetaScreenCastSession *session, + gboolean disable_animations) +{ + session->disable_animations = disable_animations; +} + +char * +meta_screen_cast_session_get_object_path (MetaScreenCastSession *session) +{ + return session->object_path; +} + +char * +meta_screen_cast_session_get_peer_name (MetaScreenCastSession *session) +{ + return session->peer_name; +} + +static gboolean +check_permission (MetaScreenCastSession *session, + GDBusMethodInvocation *invocation) +{ + return g_strcmp0 (session->peer_name, + g_dbus_method_invocation_get_sender (invocation)) == 0; +} + +static gboolean +handle_start (MetaDBusScreenCastSession *skeleton, + GDBusMethodInvocation *invocation) +{ + MetaScreenCastSession *session = META_SCREEN_CAST_SESSION (skeleton); + GError *error = NULL; + + if (!check_permission (session, invocation)) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_ACCESS_DENIED, + "Permission denied"); + return TRUE; + } + + switch (session->session_type) + { + case META_SCREEN_CAST_SESSION_TYPE_NORMAL: + break; + case META_SCREEN_CAST_SESSION_TYPE_REMOTE_DESKTOP: + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_FAILED, + "Must be started from remote desktop session"); + return TRUE; + } + + if (!meta_screen_cast_session_start (session, &error)) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_FAILED, + "Failed to start screen cast: %s", + error->message); + g_error_free (error); + + return TRUE; + } + + meta_dbus_screen_cast_session_complete_start (skeleton, invocation); + + return TRUE; +} + +static gboolean +handle_stop (MetaDBusScreenCastSession *skeleton, + GDBusMethodInvocation *invocation) +{ + MetaScreenCastSession *session = META_SCREEN_CAST_SESSION (skeleton); + + if (!check_permission (session, invocation)) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_ACCESS_DENIED, + "Permission denied"); + return TRUE; + } + + switch (session->session_type) + { + case META_SCREEN_CAST_SESSION_TYPE_NORMAL: + break; + case META_SCREEN_CAST_SESSION_TYPE_REMOTE_DESKTOP: + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_FAILED, + "Must be stopped from remote desktop session"); + return TRUE; + } + + meta_screen_cast_session_close (session); + + meta_dbus_screen_cast_session_complete_stop (skeleton, invocation); + + return TRUE; +} + +static void +on_stream_closed (MetaScreenCastStream *stream, + MetaScreenCastSession *session) +{ + meta_screen_cast_session_close (session); +} + +static gboolean +is_valid_cursor_mode (MetaScreenCastCursorMode cursor_mode) +{ + switch (cursor_mode) + { + case META_SCREEN_CAST_CURSOR_MODE_HIDDEN: + case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED: + case META_SCREEN_CAST_CURSOR_MODE_METADATA: + return TRUE; + } + + return FALSE; +} + +static gboolean +handle_record_monitor (MetaDBusScreenCastSession *skeleton, + GDBusMethodInvocation *invocation, + const char *connector, + GVariant *properties_variant) +{ + MetaScreenCastSession *session = META_SCREEN_CAST_SESSION (skeleton); + GDBusInterfaceSkeleton *interface_skeleton; + GDBusConnection *connection; + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaMonitor *monitor; + MetaScreenCastCursorMode cursor_mode; + ClutterStage *stage; + GError *error = NULL; + MetaScreenCastMonitorStream *monitor_stream; + MetaScreenCastStream *stream; + char *stream_path; + + if (!check_permission (session, invocation)) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_ACCESS_DENIED, + "Permission denied"); + return TRUE; + } + + interface_skeleton = G_DBUS_INTERFACE_SKELETON (skeleton); + connection = g_dbus_interface_skeleton_get_connection (interface_skeleton); + + if (g_str_equal (connector, "")) + monitor = meta_monitor_manager_get_primary_monitor (monitor_manager); + else + monitor = meta_monitor_manager_get_monitor_from_connector (monitor_manager, + connector); + + if (!monitor) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_FAILED, + "Unknown monitor"); + return TRUE; + } + + if (!g_variant_lookup (properties_variant, "cursor-mode", "u", &cursor_mode)) + { + cursor_mode = META_SCREEN_CAST_CURSOR_MODE_HIDDEN; + } + else + { + if (!is_valid_cursor_mode (cursor_mode)) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_FAILED, + "Unknown cursor mode"); + return TRUE; + } + } + + stage = CLUTTER_STAGE (meta_backend_get_stage (backend)); + + monitor_stream = meta_screen_cast_monitor_stream_new (session, + connection, + monitor, + stage, + cursor_mode, + &error); + if (!monitor_stream) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_FAILED, + "Failed to record monitor: %s", + error->message); + g_error_free (error); + return TRUE; + } + + stream = META_SCREEN_CAST_STREAM (monitor_stream); + stream_path = meta_screen_cast_stream_get_object_path (stream); + + session->streams = g_list_append (session->streams, stream); + + g_signal_connect (stream, "closed", G_CALLBACK (on_stream_closed), session); + + meta_dbus_screen_cast_session_complete_record_monitor (skeleton, + invocation, + stream_path); + + return TRUE; +} + +static gboolean +handle_record_window (MetaDBusScreenCastSession *skeleton, + GDBusMethodInvocation *invocation, + GVariant *properties_variant) +{ + MetaScreenCastSession *session = META_SCREEN_CAST_SESSION (skeleton); + GDBusInterfaceSkeleton *interface_skeleton; + GDBusConnection *connection; + MetaWindow *window; + MetaScreenCastCursorMode cursor_mode; + GError *error = NULL; + MetaDisplay *display; + GVariant *window_id_variant = NULL; + MetaScreenCastWindowStream *window_stream; + MetaScreenCastStream *stream; + char *stream_path; + + if (!check_permission (session, invocation)) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_ACCESS_DENIED, + "Permission denied"); + return TRUE; + } + + if (properties_variant) + window_id_variant = g_variant_lookup_value (properties_variant, + "window-id", + G_VARIANT_TYPE ("t")); + + display = meta_get_display (); + if (window_id_variant) + { + uint64_t window_id; + + g_variant_get (window_id_variant, "t", &window_id); + window = meta_display_get_window_from_id (display, window_id); + } + else + { + window = meta_display_get_focus_window (display); + } + + if (!window) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_FAILED, + "Window not found"); + return TRUE; + } + + if (!g_variant_lookup (properties_variant, "cursor-mode", "u", &cursor_mode)) + { + cursor_mode = META_SCREEN_CAST_CURSOR_MODE_HIDDEN; + } + else + { + if (!is_valid_cursor_mode (cursor_mode)) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_FAILED, + "Unknown cursor mode"); + return TRUE; + } + } + + interface_skeleton = G_DBUS_INTERFACE_SKELETON (skeleton); + connection = g_dbus_interface_skeleton_get_connection (interface_skeleton); + + window_stream = meta_screen_cast_window_stream_new (session, + connection, + window, + cursor_mode, + &error); + if (!window_stream) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_FAILED, + "Failed to record window: %s", + error->message); + g_error_free (error); + return TRUE; + } + + stream = META_SCREEN_CAST_STREAM (window_stream); + stream_path = meta_screen_cast_stream_get_object_path (stream); + + session->streams = g_list_append (session->streams, stream); + + g_signal_connect (stream, "closed", G_CALLBACK (on_stream_closed), session); + + meta_dbus_screen_cast_session_complete_record_window (skeleton, + invocation, + stream_path); + + return TRUE; +} + +static void +meta_screen_cast_session_init_iface (MetaDBusScreenCastSessionIface *iface) +{ + iface->handle_start = handle_start; + iface->handle_stop = handle_stop; + iface->handle_record_monitor = handle_record_monitor; + iface->handle_record_window = handle_record_window; +} + +static void +meta_screen_cast_session_client_vanished (MetaDbusSession *dbus_session) +{ + meta_screen_cast_session_close (META_SCREEN_CAST_SESSION (dbus_session)); +} + +static void +meta_dbus_session_init_iface (MetaDbusSessionInterface *iface) +{ + iface->client_vanished = meta_screen_cast_session_client_vanished; +} + +MetaScreenCastSession * +meta_screen_cast_session_new (MetaScreenCast *screen_cast, + MetaScreenCastSessionType session_type, + const char *peer_name, + GError **error) +{ + GDBusInterfaceSkeleton *interface_skeleton; + MetaScreenCastSession *session; + GDBusConnection *connection; + static unsigned int global_session_number = 0; + + session = g_object_new (META_TYPE_SCREEN_CAST_SESSION, NULL); + session->screen_cast = screen_cast; + session->session_type = session_type; + session->peer_name = g_strdup (peer_name); + session->object_path = + g_strdup_printf (META_SCREEN_CAST_SESSION_DBUS_PATH "/u%u", + ++global_session_number); + + interface_skeleton = G_DBUS_INTERFACE_SKELETON (session); + connection = meta_screen_cast_get_connection (screen_cast); + if (!g_dbus_interface_skeleton_export (interface_skeleton, + connection, + session->object_path, + error)) + return NULL; + + return session; +} + +static void +meta_screen_cast_session_finalize (GObject *object) +{ + MetaScreenCastSession *session = META_SCREEN_CAST_SESSION (object); + + g_clear_object (&session->handle); + g_free (session->peer_name); + g_free (session->object_path); + + G_OBJECT_CLASS (meta_screen_cast_session_parent_class)->finalize (object); +} + +static void +meta_screen_cast_session_init (MetaScreenCastSession *session) +{ +} + +static void +meta_screen_cast_session_class_init (MetaScreenCastSessionClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_screen_cast_session_finalize; +} + +static MetaScreenCastSessionHandle * +meta_screen_cast_session_handle_new (MetaScreenCastSession *session) +{ + MetaScreenCastSessionHandle *handle; + + handle = g_object_new (META_TYPE_SCREEN_CAST_SESSION_HANDLE, NULL); + handle->session = session; + + return handle; +} + +static void +meta_screen_cast_session_handle_stop (MetaRemoteAccessHandle *handle) +{ + MetaScreenCastSession *session; + + session = META_SCREEN_CAST_SESSION_HANDLE (handle)->session; + if (!session) + return; + + meta_screen_cast_session_close (session); +} + +static void +meta_screen_cast_session_handle_init (MetaScreenCastSessionHandle *handle) +{ +} + +static void +meta_screen_cast_session_handle_class_init (MetaScreenCastSessionHandleClass *klass) +{ + MetaRemoteAccessHandleClass *remote_access_handle_class = + META_REMOTE_ACCESS_HANDLE_CLASS (klass); + + remote_access_handle_class->stop = meta_screen_cast_session_handle_stop; +} diff --git a/src/backends/meta-screen-cast-session.h b/src/backends/meta-screen-cast-session.h new file mode 100644 index 000000000..3bab3486b --- /dev/null +++ b/src/backends/meta-screen-cast-session.h @@ -0,0 +1,70 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2015-2017 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#ifndef META_SCREEN_CAST_SESSION_H +#define META_SCREEN_CAST_SESSION_H + +#include "backends/meta-screen-cast.h" + +#include "backends/meta-screen-cast-stream.h" +#include "meta/meta-remote-access-controller.h" + +typedef enum _MetaScreenCastSessionType +{ + META_SCREEN_CAST_SESSION_TYPE_NORMAL, + META_SCREEN_CAST_SESSION_TYPE_REMOTE_DESKTOP, +} MetaScreenCastSessionType; + +#define META_TYPE_SCREEN_CAST_SESSION (meta_screen_cast_session_get_type ()) +G_DECLARE_FINAL_TYPE (MetaScreenCastSession, meta_screen_cast_session, + META, SCREEN_CAST_SESSION, + MetaDBusScreenCastSessionSkeleton) + +#define META_TYPE_SCREEN_CAST_SESSION_HANDLE (meta_screen_cast_session_handle_get_type ()) +G_DECLARE_FINAL_TYPE (MetaScreenCastSessionHandle, + meta_screen_cast_session_handle, + META, SCREEN_CAST_SESSION_HANDLE, + MetaRemoteAccessHandle) + +char * meta_screen_cast_session_get_object_path (MetaScreenCastSession *session); + +char * meta_screen_cast_session_get_peer_name (MetaScreenCastSession *session); + +MetaScreenCastSession * meta_screen_cast_session_new (MetaScreenCast *screen_cast, + MetaScreenCastSessionType session_type, + const char *peer_name, + GError **error); + +gboolean meta_screen_cast_session_start (MetaScreenCastSession *session, + GError **error); + +void meta_screen_cast_session_close (MetaScreenCastSession *session); + +MetaScreenCastStream * meta_screen_cast_session_get_stream (MetaScreenCastSession *session, + const char *path); + +MetaScreenCast * meta_screen_cast_session_get_screen_cast (MetaScreenCastSession *session); + +void meta_screen_cast_session_set_disable_animations (MetaScreenCastSession *session, + gboolean disable_animations); + +#endif /* META_SCREEN_CAST_SESSION_H */ diff --git a/src/backends/meta-screen-cast-stream-src.c b/src/backends/meta-screen-cast-stream-src.c new file mode 100644 index 000000000..7eb99f70d --- /dev/null +++ b/src/backends/meta-screen-cast-stream-src.c @@ -0,0 +1,1170 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2015-2017 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#include "config.h" + +#include "backends/meta-screen-cast-stream-src.h" + +#include <errno.h> +#include <fcntl.h> +#include <pipewire/pipewire.h> +#include <spa/param/props.h> +#include <spa/param/format-utils.h> +#include <spa/param/video/format-utils.h> +#include <spa/utils/result.h> +#include <stdint.h> +#include <sys/mman.h> + +#include "backends/meta-screen-cast-session.h" +#include "backends/meta-screen-cast-stream.h" +#include "clutter/clutter-mutter.h" +#include "core/meta-fraction.h" +#include "meta/boxes.h" + +#define PRIVATE_OWNER_FROM_FIELD(TypeName, field_ptr, field_name) \ + (TypeName *)((guint8 *)(field_ptr) - G_PRIVATE_OFFSET (TypeName, field_name)) + +#define CURSOR_META_SIZE(width, height) \ + (sizeof (struct spa_meta_cursor) + \ + sizeof (struct spa_meta_bitmap) + width * height * 4) + +enum +{ + PROP_0, + + PROP_STREAM, +}; + +enum +{ + READY, + CLOSED, + + N_SIGNALS +}; + +static guint signals[N_SIGNALS]; + +typedef struct _MetaPipeWireSource +{ + GSource base; + + MetaScreenCastStreamSrc *src; + struct pw_loop *pipewire_loop; +} MetaPipeWireSource; + +typedef struct _MetaScreenCastStreamSrcPrivate +{ + MetaScreenCastStream *stream; + + struct pw_context *pipewire_context; + struct pw_core *pipewire_core; + MetaPipeWireSource *pipewire_source; + struct spa_hook pipewire_core_listener; + + gboolean is_enabled; + gboolean emit_closed_after_dispatch; + + struct pw_stream *pipewire_stream; + struct spa_hook pipewire_stream_listener; + uint32_t node_id; + + struct spa_video_info_raw video_format; + int video_stride; + + int64_t last_frame_timestamp_us; + guint follow_up_frame_source_id; + + GHashTable *dmabuf_handles; + + int stream_width; + int stream_height; +} MetaScreenCastStreamSrcPrivate; + +static void +meta_screen_cast_stream_src_init_initable_iface (GInitableIface *iface); + +G_DEFINE_TYPE_WITH_CODE (MetaScreenCastStreamSrc, + meta_screen_cast_stream_src, + G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + meta_screen_cast_stream_src_init_initable_iface) + G_ADD_PRIVATE (MetaScreenCastStreamSrc)) + +static inline uint32_t +us2ms (uint64_t us) +{ + return (uint32_t) (us / 1000); +} + +static void +meta_screen_cast_stream_src_get_specs (MetaScreenCastStreamSrc *src, + int *width, + int *height, + float *frame_rate) +{ + MetaScreenCastStreamSrcClass *klass = + META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src); + + klass->get_specs (src, width, height, frame_rate); +} + +static gboolean +meta_screen_cast_stream_src_get_videocrop (MetaScreenCastStreamSrc *src, + MetaRectangle *crop_rect) +{ + MetaScreenCastStreamSrcClass *klass = + META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src); + + if (klass->get_videocrop) + return klass->get_videocrop (src, crop_rect); + + return FALSE; +} + +static gboolean +meta_screen_cast_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src, + uint8_t *data, + GError **error) +{ + MetaScreenCastStreamSrcClass *klass = + META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src); + + return klass->record_to_buffer (src, data, error); +} + +static gboolean +meta_screen_cast_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src, + CoglFramebuffer *framebuffer, + GError **error) +{ + MetaScreenCastStreamSrcClass *klass = + META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src); + + return klass->record_to_framebuffer (src, framebuffer, error); +} + +static void +meta_screen_cast_stream_src_record_follow_up (MetaScreenCastStreamSrc *src) +{ + MetaScreenCastStreamSrcClass *klass = + META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src); + + klass->record_follow_up (src); +} + +static void +meta_screen_cast_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc *src, + struct spa_meta_cursor *spa_meta_cursor) +{ + MetaScreenCastStreamSrcClass *klass = + META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src); + + if (klass->set_cursor_metadata) + klass->set_cursor_metadata (src, spa_meta_cursor); +} + +static gboolean +draw_cursor_sprite_via_offscreen (MetaScreenCastStreamSrc *src, + CoglTexture *cursor_texture, + int bitmap_width, + int bitmap_height, + uint8_t *bitmap_data, + GError **error) +{ + MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src); + MetaScreenCastSession *session = meta_screen_cast_stream_get_session (stream); + MetaScreenCast *screen_cast = + meta_screen_cast_session_get_screen_cast (session); + MetaBackend *backend = meta_screen_cast_get_backend (screen_cast); + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + CoglContext *cogl_context = + clutter_backend_get_cogl_context (clutter_backend); + CoglTexture2D *bitmap_texture; + CoglOffscreen *offscreen; + CoglFramebuffer *fb; + CoglPipeline *pipeline; + CoglColor clear_color; + + bitmap_texture = cogl_texture_2d_new_with_size (cogl_context, + bitmap_width, bitmap_height); + cogl_primitive_texture_set_auto_mipmap (COGL_PRIMITIVE_TEXTURE (bitmap_texture), + FALSE); + if (!cogl_texture_allocate (COGL_TEXTURE (bitmap_texture), error)) + { + cogl_object_unref (bitmap_texture); + return FALSE; + } + + offscreen = cogl_offscreen_new_with_texture (COGL_TEXTURE (bitmap_texture)); + fb = COGL_FRAMEBUFFER (offscreen); + cogl_object_unref (bitmap_texture); + if (!cogl_framebuffer_allocate (fb, error)) + { + cogl_object_unref (fb); + return FALSE; + } + + pipeline = cogl_pipeline_new (cogl_context); + cogl_pipeline_set_layer_texture (pipeline, 0, cursor_texture); + cogl_pipeline_set_layer_filters (pipeline, 0, + COGL_PIPELINE_FILTER_LINEAR, + COGL_PIPELINE_FILTER_LINEAR); + cogl_color_init_from_4ub (&clear_color, 0, 0, 0, 0); + cogl_framebuffer_clear (fb, COGL_BUFFER_BIT_COLOR, &clear_color); + cogl_framebuffer_draw_rectangle (fb, pipeline, + -1, 1, 1, -1); + cogl_object_unref (pipeline); + + cogl_framebuffer_read_pixels (fb, + 0, 0, + bitmap_width, bitmap_height, + COGL_PIXEL_FORMAT_RGBA_8888_PRE, + bitmap_data); + cogl_object_unref (fb); + + return TRUE; +} + +gboolean +meta_screen_cast_stream_src_draw_cursor_into (MetaScreenCastStreamSrc *src, + CoglTexture *cursor_texture, + float scale, + uint8_t *data, + GError **error) +{ + int texture_width, texture_height; + int width, height; + + texture_width = cogl_texture_get_width (cursor_texture); + texture_height = cogl_texture_get_height (cursor_texture); + width = texture_width * scale; + height = texture_height * scale; + + if (texture_width == width && + texture_height == height) + { + cogl_texture_get_data (cursor_texture, + COGL_PIXEL_FORMAT_RGBA_8888_PRE, + texture_width * 4, + data); + } + else + { + if (!draw_cursor_sprite_via_offscreen (src, + cursor_texture, + width, + height, + data, + error)) + return FALSE; + } + + return TRUE; +} + +void +meta_screen_cast_stream_src_unset_cursor_metadata (MetaScreenCastStreamSrc *src, + struct spa_meta_cursor *spa_meta_cursor) +{ + spa_meta_cursor->id = 0; +} + +void +meta_screen_cast_stream_src_set_cursor_position_metadata (MetaScreenCastStreamSrc *src, + struct spa_meta_cursor *spa_meta_cursor, + int x, + int y) +{ + spa_meta_cursor->id = 1; + spa_meta_cursor->position.x = x; + spa_meta_cursor->position.y = y; + spa_meta_cursor->hotspot.x = 0; + spa_meta_cursor->hotspot.y = 0; + spa_meta_cursor->bitmap_offset = 0; +} + +void +meta_screen_cast_stream_src_set_empty_cursor_sprite_metadata (MetaScreenCastStreamSrc *src, + struct spa_meta_cursor *spa_meta_cursor, + int x, + int y) +{ + struct spa_meta_bitmap *spa_meta_bitmap; + + spa_meta_cursor->id = 1; + spa_meta_cursor->position.x = x; + spa_meta_cursor->position.y = y; + + spa_meta_cursor->bitmap_offset = sizeof (struct spa_meta_cursor); + + spa_meta_bitmap = SPA_MEMBER (spa_meta_cursor, + spa_meta_cursor->bitmap_offset, + struct spa_meta_bitmap); + spa_meta_bitmap->format = SPA_VIDEO_FORMAT_RGBA; + spa_meta_bitmap->offset = sizeof (struct spa_meta_bitmap); + + spa_meta_cursor->hotspot.x = 0; + spa_meta_cursor->hotspot.y = 0; + + *spa_meta_bitmap = (struct spa_meta_bitmap) { 0 }; +} + +void +meta_screen_cast_stream_src_set_cursor_sprite_metadata (MetaScreenCastStreamSrc *src, + struct spa_meta_cursor *spa_meta_cursor, + MetaCursorSprite *cursor_sprite, + int x, + int y, + float scale) +{ + CoglTexture *cursor_texture; + struct spa_meta_bitmap *spa_meta_bitmap; + int hotspot_x, hotspot_y; + int texture_width, texture_height; + int bitmap_width, bitmap_height; + uint8_t *bitmap_data; + GError *error = NULL; + + cursor_texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite); + if (!cursor_texture) + { + meta_screen_cast_stream_src_set_empty_cursor_sprite_metadata (src, + spa_meta_cursor, + x, y); + return; + } + + spa_meta_cursor->id = 1; + spa_meta_cursor->position.x = x; + spa_meta_cursor->position.y = y; + + spa_meta_cursor->bitmap_offset = sizeof (struct spa_meta_cursor); + + spa_meta_bitmap = SPA_MEMBER (spa_meta_cursor, + spa_meta_cursor->bitmap_offset, + struct spa_meta_bitmap); + spa_meta_bitmap->format = SPA_VIDEO_FORMAT_RGBA; + spa_meta_bitmap->offset = sizeof (struct spa_meta_bitmap); + + meta_cursor_sprite_get_hotspot (cursor_sprite, &hotspot_x, &hotspot_y); + spa_meta_cursor->hotspot.x = (int32_t) roundf (hotspot_x * scale); + spa_meta_cursor->hotspot.y = (int32_t) roundf (hotspot_y * scale); + + texture_width = cogl_texture_get_width (cursor_texture); + texture_height = cogl_texture_get_height (cursor_texture); + bitmap_width = texture_width * scale; + bitmap_height = texture_height * scale; + + spa_meta_bitmap->size.width = bitmap_width; + spa_meta_bitmap->size.height = bitmap_height; + spa_meta_bitmap->stride = bitmap_width * 4; + + bitmap_data = SPA_MEMBER (spa_meta_bitmap, + spa_meta_bitmap->offset, + uint8_t); + + if (!meta_screen_cast_stream_src_draw_cursor_into (src, + cursor_texture, + scale, + bitmap_data, + &error)) + { + g_warning ("Failed to draw cursor: %s", error->message); + g_error_free (error); + spa_meta_cursor->id = 0; + } +} + +static void +add_cursor_metadata (MetaScreenCastStreamSrc *src, + struct spa_buffer *spa_buffer) +{ + struct spa_meta_cursor *spa_meta_cursor; + + spa_meta_cursor = spa_buffer_find_meta_data (spa_buffer, SPA_META_Cursor, + sizeof (*spa_meta_cursor)); + if (spa_meta_cursor) + meta_screen_cast_stream_src_set_cursor_metadata (src, spa_meta_cursor); +} + +static void +maybe_record_cursor (MetaScreenCastStreamSrc *src, + struct spa_buffer *spa_buffer) +{ + MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src); + + switch (meta_screen_cast_stream_get_cursor_mode (stream)) + { + case META_SCREEN_CAST_CURSOR_MODE_HIDDEN: + case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED: + return; + case META_SCREEN_CAST_CURSOR_MODE_METADATA: + add_cursor_metadata (src, spa_buffer); + return; + } + + g_assert_not_reached (); +} + +static gboolean +do_record_frame (MetaScreenCastStreamSrc *src, + struct spa_buffer *spa_buffer, + uint8_t *data, + GError **error) +{ + MetaScreenCastStreamSrcPrivate *priv = + meta_screen_cast_stream_src_get_instance_private (src); + + if (spa_buffer->datas[0].data || + spa_buffer->datas[0].type == SPA_DATA_MemFd) + { + return meta_screen_cast_stream_src_record_to_buffer (src, data, error); + } + else if (spa_buffer->datas[0].type == SPA_DATA_DmaBuf) + { + CoglDmaBufHandle *dmabuf_handle = + g_hash_table_lookup (priv->dmabuf_handles, + GINT_TO_POINTER (spa_buffer->datas[0].fd)); + CoglFramebuffer *dmabuf_fbo = + cogl_dma_buf_handle_get_framebuffer (dmabuf_handle); + + return meta_screen_cast_stream_src_record_to_framebuffer (src, + dmabuf_fbo, + error); + } + + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Unknown SPA buffer type %u", spa_buffer->datas[0].type); + return FALSE; +} + +gboolean +meta_screen_cast_stream_src_pending_follow_up_frame (MetaScreenCastStreamSrc *src) +{ + MetaScreenCastStreamSrcPrivate *priv = + meta_screen_cast_stream_src_get_instance_private (src); + + return priv->follow_up_frame_source_id != 0; +} + +static gboolean +follow_up_frame_cb (gpointer user_data) +{ + MetaScreenCastStreamSrc *src = user_data; + MetaScreenCastStreamSrcPrivate *priv = + meta_screen_cast_stream_src_get_instance_private (src); + + priv->follow_up_frame_source_id = 0; + meta_screen_cast_stream_src_record_follow_up (src); + + return G_SOURCE_REMOVE; +} + +static void +maybe_schedule_follow_up_frame (MetaScreenCastStreamSrc *src, + int64_t timeout_us) +{ + MetaScreenCastStreamSrcPrivate *priv = + meta_screen_cast_stream_src_get_instance_private (src); + + if (priv->follow_up_frame_source_id) + return; + + priv->follow_up_frame_source_id = g_timeout_add (us2ms (timeout_us), + follow_up_frame_cb, + src); +} + +void +meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src, + MetaScreenCastRecordFlag flags) +{ + MetaScreenCastStreamSrcPrivate *priv = + meta_screen_cast_stream_src_get_instance_private (src); + MetaRectangle crop_rect; + struct pw_buffer *buffer; + struct spa_buffer *spa_buffer; + uint8_t *data = NULL; + uint64_t now_us; + g_autoptr (GError) error = NULL; + + now_us = g_get_monotonic_time (); + if (priv->video_format.max_framerate.num > 0 && + priv->last_frame_timestamp_us != 0) + { + int64_t min_interval_us; + int64_t time_since_last_frame_us; + + min_interval_us = + ((G_USEC_PER_SEC * priv->video_format.max_framerate.denom) / + priv->video_format.max_framerate.num); + + time_since_last_frame_us = now_us - priv->last_frame_timestamp_us; + if (time_since_last_frame_us < min_interval_us) + { + int64_t timeout_us; + + timeout_us = min_interval_us - time_since_last_frame_us; + maybe_schedule_follow_up_frame (src, timeout_us); + return; + } + } + + if (!priv->pipewire_stream) + return; + + buffer = pw_stream_dequeue_buffer (priv->pipewire_stream); + if (!buffer) + return; + + spa_buffer = buffer->buffer; + data = spa_buffer->datas[0].data; + + if (spa_buffer->datas[0].type != SPA_DATA_DmaBuf && !data) + { + g_critical ("Invalid buffer data"); + return; + } + + if (!(flags & META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY)) + { + g_clear_handle_id (&priv->follow_up_frame_source_id, g_source_remove); + if (do_record_frame (src, spa_buffer, data, &error)) + { + struct spa_meta_region *spa_meta_video_crop; + + spa_buffer->datas[0].chunk->size = spa_buffer->datas[0].maxsize; + spa_buffer->datas[0].chunk->stride = priv->video_stride; + + /* Update VideoCrop if needed */ + spa_meta_video_crop = + spa_buffer_find_meta_data (spa_buffer, SPA_META_VideoCrop, + sizeof (*spa_meta_video_crop)); + if (spa_meta_video_crop) + { + if (meta_screen_cast_stream_src_get_videocrop (src, &crop_rect)) + { + spa_meta_video_crop->region.position.x = crop_rect.x; + spa_meta_video_crop->region.position.y = crop_rect.y; + spa_meta_video_crop->region.size.width = crop_rect.width; + spa_meta_video_crop->region.size.height = crop_rect.height; + } + else + { + spa_meta_video_crop->region.position.x = 0; + spa_meta_video_crop->region.position.y = 0; + spa_meta_video_crop->region.size.width = priv->stream_width; + spa_meta_video_crop->region.size.height = priv->stream_height; + } + } + } + else + { + g_warning ("Failed to record screen cast frame: %s", error->message); + spa_buffer->datas[0].chunk->size = 0; + } + } + else + { + spa_buffer->datas[0].chunk->size = 0; + } + + maybe_record_cursor (src, spa_buffer); + + priv->last_frame_timestamp_us = now_us; + + pw_stream_queue_buffer (priv->pipewire_stream, buffer); +} + +static gboolean +meta_screen_cast_stream_src_is_enabled (MetaScreenCastStreamSrc *src) +{ + MetaScreenCastStreamSrcPrivate *priv = + meta_screen_cast_stream_src_get_instance_private (src); + + return priv->is_enabled; +} + +static void +meta_screen_cast_stream_src_enable (MetaScreenCastStreamSrc *src) +{ + MetaScreenCastStreamSrcPrivate *priv = + meta_screen_cast_stream_src_get_instance_private (src); + + META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src)->enable (src); + + priv->is_enabled = TRUE; +} + +static void +meta_screen_cast_stream_src_disable (MetaScreenCastStreamSrc *src) +{ + MetaScreenCastStreamSrcPrivate *priv = + meta_screen_cast_stream_src_get_instance_private (src); + + META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src)->disable (src); + + g_clear_handle_id (&priv->follow_up_frame_source_id, g_source_remove); + + priv->is_enabled = FALSE; +} + +static void +on_stream_state_changed (void *data, + enum pw_stream_state old, + enum pw_stream_state state, + const char *error_message) +{ + MetaScreenCastStreamSrc *src = data; + MetaScreenCastStreamSrcPrivate *priv = + meta_screen_cast_stream_src_get_instance_private (src); + + switch (state) + { + case PW_STREAM_STATE_ERROR: + g_warning ("pipewire stream error: %s", error_message); + if (meta_screen_cast_stream_src_is_enabled (src)) + meta_screen_cast_stream_src_disable (src); + priv->emit_closed_after_dispatch = TRUE; + break; + case PW_STREAM_STATE_PAUSED: + if (priv->node_id == SPA_ID_INVALID && priv->pipewire_stream) + { + priv->node_id = pw_stream_get_node_id (priv->pipewire_stream); + g_signal_emit (src, signals[READY], 0, (unsigned int) priv->node_id); + } + if (meta_screen_cast_stream_src_is_enabled (src)) + meta_screen_cast_stream_src_disable (src); + break; + case PW_STREAM_STATE_STREAMING: + if (!meta_screen_cast_stream_src_is_enabled (src)) + meta_screen_cast_stream_src_enable (src); + break; + case PW_STREAM_STATE_UNCONNECTED: + case PW_STREAM_STATE_CONNECTING: + break; + } +} + +static void +on_stream_param_changed (void *data, + uint32_t id, + const struct spa_pod *format) +{ + MetaScreenCastStreamSrc *src = data; + MetaScreenCastStreamSrcPrivate *priv = + meta_screen_cast_stream_src_get_instance_private (src); + uint8_t params_buffer[1024]; + int32_t width, height, stride, size; + struct spa_pod_builder pod_builder; + const struct spa_pod *params[3]; + const int bpp = 4; + + if (!format || id != SPA_PARAM_Format) + return; + + spa_format_video_raw_parse (format, + &priv->video_format); + + width = priv->video_format.size.width; + height = priv->video_format.size.height; + stride = SPA_ROUND_UP_N (width * bpp, 4); + size = height * stride; + + priv->video_stride = stride; + + pod_builder = SPA_POD_BUILDER_INIT (params_buffer, sizeof (params_buffer)); + + params[0] = spa_pod_builder_add_object ( + &pod_builder, + SPA_TYPE_OBJECT_ParamBuffers, SPA_PARAM_Buffers, + SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int (16, 2, 16), + SPA_PARAM_BUFFERS_blocks, SPA_POD_Int (1), + SPA_PARAM_BUFFERS_size, SPA_POD_Int (size), + SPA_PARAM_BUFFERS_stride, SPA_POD_Int (stride), + SPA_PARAM_BUFFERS_align, SPA_POD_Int (16)); + + params[1] = spa_pod_builder_add_object ( + &pod_builder, + SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta, + SPA_PARAM_META_type, SPA_POD_Id (SPA_META_VideoCrop), + SPA_PARAM_META_size, SPA_POD_Int (sizeof (struct spa_meta_region))); + + params[2] = spa_pod_builder_add_object ( + &pod_builder, + SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta, + SPA_PARAM_META_type, SPA_POD_Id (SPA_META_Cursor), + SPA_PARAM_META_size, SPA_POD_Int (CURSOR_META_SIZE (64, 64))); + + pw_stream_update_params (priv->pipewire_stream, params, G_N_ELEMENTS (params)); +} + +static void +on_stream_add_buffer (void *data, + struct pw_buffer *buffer) +{ + MetaScreenCastStreamSrc *src = data; + MetaScreenCastStreamSrcPrivate *priv = + meta_screen_cast_stream_src_get_instance_private (src); + CoglContext *context = + clutter_backend_get_cogl_context (clutter_get_default_backend ()); + CoglRenderer *renderer = cogl_context_get_renderer (context); + g_autoptr (GError) error = NULL; + CoglDmaBufHandle *dmabuf_handle; + struct spa_buffer *spa_buffer = buffer->buffer; + struct spa_data *spa_data = spa_buffer->datas; + const int bpp = 4; + int stride; + + stride = SPA_ROUND_UP_N (priv->video_format.size.width * bpp, 4); + + spa_data[0].mapoffset = 0; + spa_data[0].maxsize = stride * priv->video_format.size.height; + + dmabuf_handle = cogl_renderer_create_dma_buf (renderer, + priv->stream_width, + priv->stream_height, + &error); + + if (error) + g_debug ("Error exporting DMA buffer handle: %s", error->message); + + if (dmabuf_handle) + { + spa_data[0].type = SPA_DATA_DmaBuf; + spa_data[0].flags = SPA_DATA_FLAG_READWRITE; + spa_data[0].fd = cogl_dma_buf_handle_get_fd (dmabuf_handle); + spa_data[0].data = NULL; + + g_hash_table_insert (priv->dmabuf_handles, + GINT_TO_POINTER (spa_data[0].fd), + dmabuf_handle); + } + else + { + unsigned int seals; + + /* Fallback to a memfd buffer */ + spa_data[0].type = SPA_DATA_MemFd; + spa_data[0].flags = SPA_DATA_FLAG_READWRITE; + spa_data[0].fd = memfd_create ("mutter-screen-cast-memfd", + MFD_CLOEXEC | MFD_ALLOW_SEALING); + if (spa_data[0].fd == -1) + { + g_critical ("Can't create memfd: %m"); + return; + } + spa_data[0].mapoffset = 0; + spa_data[0].maxsize = stride * priv->video_format.size.height; + + if (ftruncate (spa_data[0].fd, spa_data[0].maxsize) < 0) + { + g_critical ("Can't truncate to %d: %m", spa_data[0].maxsize); + return; + } + + seals = F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL; + if (fcntl (spa_data[0].fd, F_ADD_SEALS, seals) == -1) + g_warning ("Failed to add seals: %m"); + + spa_data[0].data = mmap (NULL, + spa_data[0].maxsize, + PROT_READ | PROT_WRITE, + MAP_SHARED, + spa_data[0].fd, + spa_data[0].mapoffset); + if (spa_data[0].data == MAP_FAILED) + { + g_critical ("Failed to mmap memory: %m"); + return; + } + } +} + +static void +on_stream_remove_buffer (void *data, + struct pw_buffer *buffer) +{ + MetaScreenCastStreamSrc *src = data; + MetaScreenCastStreamSrcPrivate *priv = + meta_screen_cast_stream_src_get_instance_private (src); + struct spa_buffer *spa_buffer = buffer->buffer; + struct spa_data *spa_data = spa_buffer->datas; + + if (spa_data[0].type == SPA_DATA_DmaBuf) + { + if (!g_hash_table_remove (priv->dmabuf_handles, GINT_TO_POINTER (spa_data[0].fd))) + g_critical ("Failed to remove non-exported DMA buffer"); + } + else if (spa_data[0].type == SPA_DATA_MemFd) + { + munmap (spa_data[0].data, spa_data[0].maxsize); + close (spa_data[0].fd); + } +} + +static const struct pw_stream_events stream_events = { + PW_VERSION_STREAM_EVENTS, + .state_changed = on_stream_state_changed, + .param_changed = on_stream_param_changed, + .add_buffer = on_stream_add_buffer, + .remove_buffer = on_stream_remove_buffer, +}; + +static struct pw_stream * +create_pipewire_stream (MetaScreenCastStreamSrc *src, + GError **error) +{ + MetaScreenCastStreamSrcPrivate *priv = + meta_screen_cast_stream_src_get_instance_private (src); + struct pw_stream *pipewire_stream; + uint8_t buffer[1024]; + struct spa_pod_builder pod_builder = + SPA_POD_BUILDER_INIT (buffer, sizeof (buffer)); + float frame_rate; + MetaFraction frame_rate_fraction; + struct spa_fraction max_framerate; + struct spa_fraction min_framerate; + const struct spa_pod *params[1]; + int result; + + priv->node_id = SPA_ID_INVALID; + + pipewire_stream = pw_stream_new (priv->pipewire_core, + "meta-screen-cast-src", + NULL); + if (!pipewire_stream) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Failed to create PipeWire stream: %s", + strerror (errno)); + return NULL; + } + + meta_screen_cast_stream_src_get_specs (src, + &priv->stream_width, + &priv->stream_height, + &frame_rate); + frame_rate_fraction = meta_fraction_from_double (frame_rate); + + min_framerate = SPA_FRACTION (1, 1); + max_framerate = SPA_FRACTION (frame_rate_fraction.num, + frame_rate_fraction.denom); + + params[0] = spa_pod_builder_add_object ( + &pod_builder, + SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat, + SPA_FORMAT_mediaType, SPA_POD_Id (SPA_MEDIA_TYPE_video), + SPA_FORMAT_mediaSubtype, SPA_POD_Id (SPA_MEDIA_SUBTYPE_raw), + SPA_FORMAT_VIDEO_format, SPA_POD_Id (SPA_VIDEO_FORMAT_BGRx), + SPA_FORMAT_VIDEO_size, SPA_POD_Rectangle (&SPA_RECTANGLE (priv->stream_width, + priv->stream_height)), + SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction (&SPA_FRACTION (0, 1)), + SPA_FORMAT_VIDEO_maxFramerate, SPA_POD_CHOICE_RANGE_Fraction (&max_framerate, + &min_framerate, + &max_framerate)); + + pw_stream_add_listener (pipewire_stream, + &priv->pipewire_stream_listener, + &stream_events, + src); + + result = pw_stream_connect (pipewire_stream, + PW_DIRECTION_OUTPUT, + SPA_ID_INVALID, + (PW_STREAM_FLAG_DRIVER | + PW_STREAM_FLAG_ALLOC_BUFFERS), + params, G_N_ELEMENTS (params)); + if (result != 0) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Could not connect: %s", spa_strerror (result)); + return NULL; + } + + return pipewire_stream; +} + +static void +on_core_error (void *data, + uint32_t id, + int seq, + int res, + const char *message) +{ + MetaScreenCastStreamSrc *src = data; + MetaScreenCastStreamSrcPrivate *priv = + meta_screen_cast_stream_src_get_instance_private (src); + + g_warning ("pipewire remote error: id:%u %s", id, message); + + if (id == PW_ID_CORE && res == -EPIPE) + { + if (meta_screen_cast_stream_src_is_enabled (src)) + meta_screen_cast_stream_src_disable (src); + priv->emit_closed_after_dispatch = TRUE; + } +} + +static gboolean +pipewire_loop_source_prepare (GSource *base, + int *timeout) +{ + *timeout = -1; + return FALSE; +} + +static gboolean +pipewire_loop_source_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + MetaPipeWireSource *pipewire_source = (MetaPipeWireSource *) source; + MetaScreenCastStreamSrc *src = pipewire_source->src; + MetaScreenCastStreamSrcPrivate *priv = + meta_screen_cast_stream_src_get_instance_private (src); + int result; + + result = pw_loop_iterate (pipewire_source->pipewire_loop, 0); + if (result < 0) + g_warning ("pipewire_loop_iterate failed: %s", spa_strerror (result)); + + if (priv->emit_closed_after_dispatch) + g_signal_emit (src, signals[CLOSED], 0); + + return TRUE; +} + +static void +pipewire_loop_source_finalize (GSource *source) +{ + MetaPipeWireSource *pipewire_source = (MetaPipeWireSource *) source; + + pw_loop_leave (pipewire_source->pipewire_loop); + pw_loop_destroy (pipewire_source->pipewire_loop); +} + +static GSourceFuncs pipewire_source_funcs = +{ + pipewire_loop_source_prepare, + NULL, + pipewire_loop_source_dispatch, + pipewire_loop_source_finalize +}; + +static MetaPipeWireSource * +create_pipewire_source (MetaScreenCastStreamSrc *src) +{ + MetaPipeWireSource *pipewire_source; + + pipewire_source = + (MetaPipeWireSource *) g_source_new (&pipewire_source_funcs, + sizeof (MetaPipeWireSource)); + pipewire_source->src = src; + pipewire_source->pipewire_loop = pw_loop_new (NULL); + if (!pipewire_source->pipewire_loop) + { + g_source_unref ((GSource *) pipewire_source); + return NULL; + } + + g_source_add_unix_fd (&pipewire_source->base, + pw_loop_get_fd (pipewire_source->pipewire_loop), + G_IO_IN | G_IO_ERR); + + pw_loop_enter (pipewire_source->pipewire_loop); + g_source_attach (&pipewire_source->base, NULL); + + return pipewire_source; +} + +static const struct pw_core_events core_events = { + PW_VERSION_CORE_EVENTS, + .error = on_core_error, +}; + +static gboolean +meta_screen_cast_stream_src_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (initable); + MetaScreenCastStreamSrcPrivate *priv = + meta_screen_cast_stream_src_get_instance_private (src); + + priv->pipewire_source = create_pipewire_source (src); + if (!priv->pipewire_source) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Failed to create PipeWire source"); + return FALSE; + } + + priv->pipewire_context = pw_context_new (priv->pipewire_source->pipewire_loop, + NULL, 0); + if (!priv->pipewire_context) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Failed to create pipewire context"); + return FALSE; + } + + priv->pipewire_core = pw_context_connect (priv->pipewire_context, NULL, 0); + if (!priv->pipewire_core) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Couldn't connect pipewire context"); + return FALSE; + } + + pw_core_add_listener (priv->pipewire_core, + &priv->pipewire_core_listener, + &core_events, + src); + + priv->pipewire_stream = create_pipewire_stream (src, error); + if (!priv->pipewire_stream) + return FALSE; + + return TRUE; +} + +static void +meta_screen_cast_stream_src_init_initable_iface (GInitableIface *iface) +{ + iface->init = meta_screen_cast_stream_src_initable_init; +} + +MetaScreenCastStream * +meta_screen_cast_stream_src_get_stream (MetaScreenCastStreamSrc *src) +{ + MetaScreenCastStreamSrcPrivate *priv = + meta_screen_cast_stream_src_get_instance_private (src); + + return priv->stream; +} + +static void +meta_screen_cast_stream_src_finalize (GObject *object) +{ + MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (object); + MetaScreenCastStreamSrcPrivate *priv = + meta_screen_cast_stream_src_get_instance_private (src); + + if (meta_screen_cast_stream_src_is_enabled (src)) + meta_screen_cast_stream_src_disable (src); + + g_clear_pointer (&priv->pipewire_stream, pw_stream_destroy); + g_clear_pointer (&priv->dmabuf_handles, g_hash_table_destroy); + g_clear_pointer (&priv->pipewire_core, pw_core_disconnect); + g_clear_pointer (&priv->pipewire_context, pw_context_destroy); + g_source_destroy (&priv->pipewire_source->base); + g_source_unref (&priv->pipewire_source->base); + + G_OBJECT_CLASS (meta_screen_cast_stream_src_parent_class)->finalize (object); +} + +static void +meta_screen_cast_stream_src_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (object); + MetaScreenCastStreamSrcPrivate *priv = + meta_screen_cast_stream_src_get_instance_private (src); + + switch (prop_id) + { + case PROP_STREAM: + priv->stream = g_value_get_object (value); + break;; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_screen_cast_stream_src_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (object); + MetaScreenCastStreamSrcPrivate *priv = + meta_screen_cast_stream_src_get_instance_private (src); + + switch (prop_id) + { + case PROP_STREAM: + g_value_set_object (value, priv->stream); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_screen_cast_stream_src_init (MetaScreenCastStreamSrc *src) +{ + MetaScreenCastStreamSrcPrivate *priv = + meta_screen_cast_stream_src_get_instance_private (src); + + priv->dmabuf_handles = + g_hash_table_new_full (NULL, NULL, NULL, + (GDestroyNotify) cogl_dma_buf_handle_free); +} + +static void +meta_screen_cast_stream_src_class_init (MetaScreenCastStreamSrcClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_screen_cast_stream_src_finalize; + object_class->set_property = meta_screen_cast_stream_src_set_property; + object_class->get_property = meta_screen_cast_stream_src_get_property; + + g_object_class_install_property (object_class, + PROP_STREAM, + g_param_spec_object ("stream", + "stream", + "MetaScreenCastStream", + META_TYPE_SCREEN_CAST_STREAM, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + signals[READY] = g_signal_new ("ready", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 1, + G_TYPE_UINT); + signals[CLOSED] = g_signal_new ("closed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); +} diff --git a/src/backends/meta-screen-cast-stream-src.h b/src/backends/meta-screen-cast-stream-src.h new file mode 100644 index 000000000..81ea20b17 --- /dev/null +++ b/src/backends/meta-screen-cast-stream-src.h @@ -0,0 +1,109 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2015-2017 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#ifndef META_SCREEN_CAST_STREAM_SRC_H +#define META_SCREEN_CAST_STREAM_SRC_H + +#include <glib-object.h> +#include <spa/param/video/format-utils.h> +#include <spa/buffer/meta.h> + +#include "backends/meta-backend-private.h" +#include "backends/meta-cursor-renderer.h" +#include "backends/meta-cursor.h" +#include "backends/meta-renderer.h" +#include "clutter/clutter.h" +#include "cogl/cogl.h" +#include "meta/boxes.h" + +typedef struct _MetaScreenCastStream MetaScreenCastStream; + +typedef enum _MetaScreenCastRecordFlag +{ + META_SCREEN_CAST_RECORD_FLAG_NONE = 0, + META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY = 1 << 0, +} MetaScreenCastRecordFlag; + +#define META_TYPE_SCREEN_CAST_STREAM_SRC (meta_screen_cast_stream_src_get_type ()) +G_DECLARE_DERIVABLE_TYPE (MetaScreenCastStreamSrc, + meta_screen_cast_stream_src, + META, SCREEN_CAST_STREAM_SRC, + GObject) + +struct _MetaScreenCastStreamSrcClass +{ + GObjectClass parent_class; + + void (* get_specs) (MetaScreenCastStreamSrc *src, + int *width, + int *height, + float *frame_rate); + void (* enable) (MetaScreenCastStreamSrc *src); + void (* disable) (MetaScreenCastStreamSrc *src); + gboolean (* record_to_buffer) (MetaScreenCastStreamSrc *src, + uint8_t *data, + GError **error); + gboolean (* record_to_framebuffer) (MetaScreenCastStreamSrc *src, + CoglFramebuffer *framebuffer, + GError **error); + void (* record_follow_up) (MetaScreenCastStreamSrc *src); + + gboolean (* get_videocrop) (MetaScreenCastStreamSrc *src, + MetaRectangle *crop_rect); + void (* set_cursor_metadata) (MetaScreenCastStreamSrc *src, + struct spa_meta_cursor *spa_meta_cursor); +}; + +void meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src, + MetaScreenCastRecordFlag flags); + +gboolean meta_screen_cast_stream_src_pending_follow_up_frame (MetaScreenCastStreamSrc *src); + +MetaScreenCastStream * meta_screen_cast_stream_src_get_stream (MetaScreenCastStreamSrc *src); + +gboolean meta_screen_cast_stream_src_draw_cursor_into (MetaScreenCastStreamSrc *src, + CoglTexture *cursor_texture, + float scale, + uint8_t *data, + GError **error); + +void meta_screen_cast_stream_src_unset_cursor_metadata (MetaScreenCastStreamSrc *src, + struct spa_meta_cursor *spa_meta_cursor); + +void meta_screen_cast_stream_src_set_cursor_position_metadata (MetaScreenCastStreamSrc *src, + struct spa_meta_cursor *spa_meta_cursor, + int x, + int y); + +void meta_screen_cast_stream_src_set_empty_cursor_sprite_metadata (MetaScreenCastStreamSrc *src, + struct spa_meta_cursor *spa_meta_cursor, + int x, + int y); + +void meta_screen_cast_stream_src_set_cursor_sprite_metadata (MetaScreenCastStreamSrc *src, + struct spa_meta_cursor *spa_meta_cursor, + MetaCursorSprite *cursor_sprite, + int x, + int y, + float scale); + +#endif /* META_SCREEN_CAST_STREAM_SRC_H */ diff --git a/src/backends/meta-screen-cast-stream.c b/src/backends/meta-screen-cast-stream.c new file mode 100644 index 000000000..e7bc7f216 --- /dev/null +++ b/src/backends/meta-screen-cast-stream.c @@ -0,0 +1,346 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#include "config.h" + +#include "backends/meta-screen-cast-stream.h" + +#include "backends/meta-screen-cast-session.h" + +#define META_SCREEN_CAST_STREAM_DBUS_IFACE "org.gnome.Mutter.ScreenCast.Stream" +#define META_SCREEN_CAST_STREAM_DBUS_PATH "/org/gnome/Mutter/ScreenCast/Stream" + +enum +{ + PROP_0, + + PROP_SESSION, + PROP_CONNECTION, + PROP_CURSOR_MODE, +}; + +enum +{ + CLOSED, + + N_SIGNALS +}; + +static guint signals[N_SIGNALS]; + +typedef struct _MetaScreenCastStreamPrivate +{ + MetaScreenCastSession *session; + + GDBusConnection *connection; + char *object_path; + + MetaScreenCastCursorMode cursor_mode; + + MetaScreenCastStreamSrc *src; +} MetaScreenCastStreamPrivate; + +static void +meta_screen_cast_stream_init_initable_iface (GInitableIface *iface); + +G_DEFINE_TYPE_WITH_CODE (MetaScreenCastStream, + meta_screen_cast_stream, + META_DBUS_TYPE_SCREEN_CAST_STREAM_SKELETON, + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + meta_screen_cast_stream_init_initable_iface) + G_ADD_PRIVATE (MetaScreenCastStream)) + +static MetaScreenCastStreamSrc * +meta_screen_cast_stream_create_src (MetaScreenCastStream *stream, + GError **error) +{ + return META_SCREEN_CAST_STREAM_GET_CLASS (stream)->create_src (stream, + error); +} + +static void +meta_screen_cast_stream_set_parameters (MetaScreenCastStream *stream, + GVariantBuilder *parameters_builder) +{ + META_SCREEN_CAST_STREAM_GET_CLASS (stream)->set_parameters (stream, + parameters_builder); +} + +static void +on_stream_src_closed (MetaScreenCastStreamSrc *src, + MetaScreenCastStream *stream) +{ + MetaScreenCastStreamPrivate *priv = + meta_screen_cast_stream_get_instance_private (stream); + + if (priv->src) + meta_screen_cast_stream_close (stream); +} + +static void +on_stream_src_ready (MetaScreenCastStreamSrc *src, + uint32_t node_id, + MetaScreenCastStream *stream) +{ + MetaScreenCastStreamPrivate *priv = + meta_screen_cast_stream_get_instance_private (stream); + GDBusConnection *connection = priv->connection; + char *peer_name; + + peer_name = meta_screen_cast_session_get_peer_name (priv->session); + g_dbus_connection_emit_signal (connection, + peer_name, + priv->object_path, + META_SCREEN_CAST_STREAM_DBUS_IFACE, + "PipeWireStreamAdded", + g_variant_new ("(u)", node_id), + NULL); +} + +MetaScreenCastSession * +meta_screen_cast_stream_get_session (MetaScreenCastStream *stream) +{ + MetaScreenCastStreamPrivate *priv = + meta_screen_cast_stream_get_instance_private (stream); + + return priv->session; +} + +gboolean +meta_screen_cast_stream_start (MetaScreenCastStream *stream, + GError **error) +{ + MetaScreenCastStreamPrivate *priv = + meta_screen_cast_stream_get_instance_private (stream); + MetaScreenCastStreamSrc *src; + + src = meta_screen_cast_stream_create_src (stream, error); + if (!src) + return FALSE; + + priv->src = src; + g_signal_connect (src, "ready", G_CALLBACK (on_stream_src_ready), stream); + g_signal_connect (src, "closed", G_CALLBACK (on_stream_src_closed), stream); + + return TRUE; +} + +void +meta_screen_cast_stream_close (MetaScreenCastStream *stream) +{ + MetaScreenCastStreamPrivate *priv = + meta_screen_cast_stream_get_instance_private (stream); + + g_clear_object (&priv->src); + + g_signal_emit (stream, signals[CLOSED], 0); +} + +char * +meta_screen_cast_stream_get_object_path (MetaScreenCastStream *stream) +{ + MetaScreenCastStreamPrivate *priv = + meta_screen_cast_stream_get_instance_private (stream); + + return priv->object_path; +} + +void +meta_screen_cast_stream_transform_position (MetaScreenCastStream *stream, + double stream_x, + double stream_y, + double *x, + double *y) +{ + META_SCREEN_CAST_STREAM_GET_CLASS (stream)->transform_position (stream, + stream_x, + stream_y, + x, + y); +} + +MetaScreenCastCursorMode +meta_screen_cast_stream_get_cursor_mode (MetaScreenCastStream *stream) +{ + MetaScreenCastStreamPrivate *priv = + meta_screen_cast_stream_get_instance_private (stream); + + return priv->cursor_mode; +} + +static void +meta_screen_cast_stream_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaScreenCastStream *stream = META_SCREEN_CAST_STREAM (object); + MetaScreenCastStreamPrivate *priv = + meta_screen_cast_stream_get_instance_private (stream); + + switch (prop_id) + { + case PROP_SESSION: + priv->session = g_value_get_object (value); + break; + case PROP_CONNECTION: + priv->connection = g_value_get_object (value); + break; + case PROP_CURSOR_MODE: + priv->cursor_mode = g_value_get_uint (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_screen_cast_stream_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaScreenCastStream *stream = META_SCREEN_CAST_STREAM (object); + MetaScreenCastStreamPrivate *priv = + meta_screen_cast_stream_get_instance_private (stream); + + switch (prop_id) + { + case PROP_SESSION: + g_value_set_object (value, priv->session); + break; + case PROP_CONNECTION: + g_value_set_object (value, priv->connection); + break; + case PROP_CURSOR_MODE: + g_value_set_uint (value, priv->cursor_mode); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_screen_cast_stream_finalize (GObject *object) +{ + MetaScreenCastStream *stream = META_SCREEN_CAST_STREAM (object); + MetaScreenCastStreamPrivate *priv = + meta_screen_cast_stream_get_instance_private (stream); + + if (priv->src) + meta_screen_cast_stream_close (stream); + + g_clear_pointer (&priv->object_path, g_free); + + G_OBJECT_CLASS (meta_screen_cast_stream_parent_class)->finalize (object); +} + +static gboolean +meta_screen_cast_stream_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + MetaScreenCastStream *stream = META_SCREEN_CAST_STREAM (initable); + MetaDBusScreenCastStream *skeleton = META_DBUS_SCREEN_CAST_STREAM (stream); + MetaScreenCastStreamPrivate *priv = + meta_screen_cast_stream_get_instance_private (stream); + GVariantBuilder parameters_builder; + GVariant *parameters_variant; + static unsigned int global_stream_number = 0; + + g_variant_builder_init (¶meters_builder, G_VARIANT_TYPE_VARDICT); + meta_screen_cast_stream_set_parameters (stream, ¶meters_builder); + + parameters_variant = g_variant_builder_end (¶meters_builder); + meta_dbus_screen_cast_stream_set_parameters (skeleton, parameters_variant); + + priv->object_path = + g_strdup_printf (META_SCREEN_CAST_STREAM_DBUS_PATH "/u%u", + ++global_stream_number); + if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (stream), + priv->connection, + priv->object_path, + error)) + return FALSE; + + return TRUE; +} + +static void +meta_screen_cast_stream_init_initable_iface (GInitableIface *iface) +{ + iface->init = meta_screen_cast_stream_initable_init; +} + +static void +meta_screen_cast_stream_init (MetaScreenCastStream *stream) +{ +} + +static void +meta_screen_cast_stream_class_init (MetaScreenCastStreamClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_screen_cast_stream_finalize; + object_class->set_property = meta_screen_cast_stream_set_property; + object_class->get_property = meta_screen_cast_stream_get_property; + + g_object_class_install_property (object_class, + PROP_SESSION, + g_param_spec_object ("session", + "session", + "MetaScreenSession", + META_TYPE_SCREEN_CAST_SESSION, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, + PROP_CONNECTION, + g_param_spec_object ("connection", + "connection", + "GDBus connection", + G_TYPE_DBUS_CONNECTION, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, + PROP_CURSOR_MODE, + g_param_spec_uint ("cursor-mode", + "cursor-mode", + "Cursor mode", + META_SCREEN_CAST_CURSOR_MODE_HIDDEN, + META_SCREEN_CAST_CURSOR_MODE_METADATA, + META_SCREEN_CAST_CURSOR_MODE_HIDDEN, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + signals[CLOSED] = g_signal_new ("closed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); +} diff --git a/src/backends/meta-screen-cast-stream.h b/src/backends/meta-screen-cast-stream.h new file mode 100644 index 000000000..4fc10869d --- /dev/null +++ b/src/backends/meta-screen-cast-stream.h @@ -0,0 +1,70 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#ifndef META_SCREEN_CAST_STREAM_H +#define META_SCREEN_CAST_STREAM_H + +#include <glib-object.h> + +#include "backends/meta-screen-cast-stream-src.h" +#include "backends/meta-screen-cast.h" + +#include "meta-dbus-screen-cast.h" + +#define META_TYPE_SCREEN_CAST_STREAM (meta_screen_cast_stream_get_type ()) +G_DECLARE_DERIVABLE_TYPE (MetaScreenCastStream, meta_screen_cast_stream, + META, SCREEN_CAST_STREAM, + MetaDBusScreenCastStreamSkeleton) + +struct _MetaScreenCastStreamClass +{ + MetaDBusScreenCastStreamSkeletonClass parent_class; + + MetaScreenCastStreamSrc * (* create_src) (MetaScreenCastStream *stream, + GError **error); + void (* set_parameters) (MetaScreenCastStream *stream, + GVariantBuilder *parameters_builder); + void (* transform_position) (MetaScreenCastStream *stream, + double stream_x, + double stream_y, + double *x, + double *y); +}; + +MetaScreenCastSession * meta_screen_cast_stream_get_session (MetaScreenCastStream *stream); + +gboolean meta_screen_cast_stream_start (MetaScreenCastStream *stream, + GError **error); + +void meta_screen_cast_stream_close (MetaScreenCastStream *stream); + +char * meta_screen_cast_stream_get_object_path (MetaScreenCastStream *stream); + +void meta_screen_cast_stream_transform_position (MetaScreenCastStream *stream, + double stream_x, + double stream_y, + double *x, + double *y); + +MetaScreenCastCursorMode meta_screen_cast_stream_get_cursor_mode (MetaScreenCastStream *stream); + +#endif /* META_SCREEN_CAST_STREAM_H */ diff --git a/src/backends/meta-screen-cast-window-stream-src.c b/src/backends/meta-screen-cast-window-stream-src.c new file mode 100644 index 000000000..1d5301bcb --- /dev/null +++ b/src/backends/meta-screen-cast-window-stream-src.c @@ -0,0 +1,587 @@ +/* + * Copyright (C) 2018 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#include "config.h" + +#include "backends/meta-screen-cast-window-stream-src.h" + +#include "backends/meta-backend-private.h" +#include "backends/meta-screen-cast-session.h" +#include "backends/meta-screen-cast-window.h" +#include "backends/meta-screen-cast-window-stream.h" +#include "compositor/meta-window-actor-private.h" + +struct _MetaScreenCastWindowStreamSrc +{ + MetaScreenCastStreamSrc parent; + + MetaScreenCastWindow *screen_cast_window; + + unsigned long screen_cast_window_damaged_handler_id; + unsigned long screen_cast_window_destroyed_handler_id; + unsigned long cursor_moved_handler_id; + unsigned long cursor_changed_handler_id; + + gboolean cursor_bitmap_invalid; +}; + +G_DEFINE_TYPE (MetaScreenCastWindowStreamSrc, + meta_screen_cast_window_stream_src, + META_TYPE_SCREEN_CAST_STREAM_SRC) + +static MetaBackend * +get_backend (MetaScreenCastWindowStreamSrc *window_src) +{ + MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (window_src); + MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src); + MetaScreenCastSession *session = meta_screen_cast_stream_get_session (stream); + MetaScreenCast *screen_cast = + meta_screen_cast_session_get_screen_cast (session); + + return meta_screen_cast_get_backend (screen_cast); +} + +static MetaScreenCastWindowStream * +get_window_stream (MetaScreenCastWindowStreamSrc *window_src) +{ + MetaScreenCastStreamSrc *src; + MetaScreenCastStream *stream; + + src = META_SCREEN_CAST_STREAM_SRC (window_src); + stream = meta_screen_cast_stream_src_get_stream (src); + + return META_SCREEN_CAST_WINDOW_STREAM (stream); +} + +static MetaWindow * +get_window (MetaScreenCastWindowStreamSrc *window_src) +{ + MetaScreenCastWindowStream *window_stream; + + window_stream = get_window_stream (window_src); + + return meta_screen_cast_window_stream_get_window (window_stream); +} + +static int +get_stream_width (MetaScreenCastWindowStreamSrc *window_src) +{ + MetaScreenCastWindowStream *window_stream; + + window_stream = get_window_stream (window_src); + + return meta_screen_cast_window_stream_get_width (window_stream); +} + +static int +get_stream_height (MetaScreenCastWindowStreamSrc *window_src) +{ + MetaScreenCastWindowStream *window_stream; + + window_stream = get_window_stream (window_src); + + return meta_screen_cast_window_stream_get_height (window_stream); +} + +static void +maybe_draw_cursor_sprite (MetaScreenCastWindowStreamSrc *window_src, + uint8_t *data, + MetaRectangle *stream_rect) +{ + MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (window_src); + MetaBackend *backend = get_backend (window_src); + MetaCursorRenderer *cursor_renderer = + meta_backend_get_cursor_renderer (backend); + MetaCursorSprite *cursor_sprite; + CoglTexture *cursor_texture; + MetaScreenCastWindow *screen_cast_window; + graphene_point_t cursor_position; + graphene_point_t relative_cursor_position; + cairo_surface_t *cursor_surface; + uint8_t *cursor_surface_data; + GError *error = NULL; + cairo_surface_t *stream_surface; + int width, height; + float scale; + int hotspot_x, hotspot_y; + cairo_t *cr; + + cursor_sprite = meta_cursor_renderer_get_cursor (cursor_renderer); + if (!cursor_sprite) + return; + + cursor_texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite); + if (!cursor_texture) + return; + + screen_cast_window = window_src->screen_cast_window; + cursor_position = meta_cursor_renderer_get_position (cursor_renderer); + if (!meta_screen_cast_window_transform_cursor_position (screen_cast_window, + cursor_sprite, + &cursor_position, + &scale, + &relative_cursor_position)) + return; + + meta_cursor_sprite_get_hotspot (cursor_sprite, &hotspot_x, &hotspot_y); + + width = cogl_texture_get_width (cursor_texture) * scale; + height = cogl_texture_get_height (cursor_texture) * scale; + cursor_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, + width, height); + + cursor_surface_data = cairo_image_surface_get_data (cursor_surface); + if (!meta_screen_cast_stream_src_draw_cursor_into (src, + cursor_texture, + scale, + cursor_surface_data, + &error)) + { + g_warning ("Failed to draw cursor: %s", error->message); + g_error_free (error); + cairo_surface_destroy (cursor_surface); + return; + } + + stream_surface = + cairo_image_surface_create_for_data (data, CAIRO_FORMAT_ARGB32, + stream_rect->width, + stream_rect->height, + stream_rect->width * 4); + + cr = cairo_create (stream_surface); + cairo_surface_mark_dirty (cursor_surface); + cairo_surface_flush (cursor_surface); + cairo_set_source_surface (cr, cursor_surface, + relative_cursor_position.x - hotspot_x * scale, + relative_cursor_position.y - hotspot_y * scale); + cairo_paint (cr); + cairo_destroy (cr); + cairo_surface_destroy (stream_surface); + cairo_surface_destroy (cursor_surface); +} + +static void +maybe_blit_cursor_sprite (MetaScreenCastWindowStreamSrc *window_src, + CoglFramebuffer *framebuffer, + MetaRectangle *stream_rect) +{ + MetaBackend *backend = get_backend (window_src); + CoglContext *cogl_context = + clutter_backend_get_cogl_context (clutter_get_default_backend ()); + MetaCursorRenderer *cursor_renderer = + meta_backend_get_cursor_renderer (backend); + MetaScreenCastWindow *screen_cast_window; + MetaCursorSprite *cursor_sprite; + graphene_point_t relative_cursor_position; + graphene_point_t cursor_position; + CoglTexture *cursor_texture; + CoglPipeline *pipeline; + int width, height; + float scale; + int hotspot_x, hotspot_y; + float x, y; + + cursor_sprite = meta_cursor_renderer_get_cursor (cursor_renderer); + if (!cursor_sprite) + return; + + cursor_texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite); + if (!cursor_texture) + return; + + screen_cast_window = window_src->screen_cast_window; + cursor_position = meta_cursor_renderer_get_position (cursor_renderer); + if (!meta_screen_cast_window_transform_cursor_position (screen_cast_window, + cursor_sprite, + &cursor_position, + &scale, + &relative_cursor_position)) + return; + + meta_cursor_sprite_get_hotspot (cursor_sprite, &hotspot_x, &hotspot_y); + + x = (relative_cursor_position.x - hotspot_x) * scale; + y = (relative_cursor_position.y - hotspot_y) * scale; + width = cogl_texture_get_width (cursor_texture); + height = cogl_texture_get_height (cursor_texture); + + pipeline = cogl_pipeline_new (cogl_context); + cogl_pipeline_set_layer_texture (pipeline, 0, cursor_texture); + cogl_pipeline_set_layer_filters (pipeline, 0, + COGL_PIPELINE_FILTER_LINEAR, + COGL_PIPELINE_FILTER_LINEAR); + + cogl_framebuffer_draw_rectangle (framebuffer, + pipeline, + x, y, + x + width, y + height); + + cogl_object_unref (pipeline); +} + +static gboolean +capture_into (MetaScreenCastWindowStreamSrc *window_src, + uint8_t *data) +{ + MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (window_src); + MetaRectangle stream_rect; + MetaScreenCastStream *stream; + + stream_rect.x = 0; + stream_rect.y = 0; + stream_rect.width = get_stream_width (window_src); + stream_rect.height = get_stream_height (window_src); + + meta_screen_cast_window_capture_into (window_src->screen_cast_window, + &stream_rect, data); + + stream = meta_screen_cast_stream_src_get_stream (src); + switch (meta_screen_cast_stream_get_cursor_mode (stream)) + { + case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED: + maybe_draw_cursor_sprite (window_src, data, &stream_rect); + break; + case META_SCREEN_CAST_CURSOR_MODE_METADATA: + case META_SCREEN_CAST_CURSOR_MODE_HIDDEN: + break; + } + + return TRUE; +} + +static void +meta_screen_cast_window_stream_src_get_specs (MetaScreenCastStreamSrc *src, + int *width, + int *height, + float *frame_rate) +{ + MetaScreenCastWindowStreamSrc *window_src = + META_SCREEN_CAST_WINDOW_STREAM_SRC (src); + + *width = get_stream_width (window_src); + *height = get_stream_height (window_src); + *frame_rate = 60.0f; +} + +static gboolean +meta_screen_cast_window_stream_src_get_videocrop (MetaScreenCastStreamSrc *src, + MetaRectangle *crop_rect) +{ + MetaScreenCastWindowStreamSrc *window_src = + META_SCREEN_CAST_WINDOW_STREAM_SRC (src); + MetaRectangle stream_rect; + + meta_screen_cast_window_get_buffer_bounds (window_src->screen_cast_window, + crop_rect); + + stream_rect.x = 0; + stream_rect.y = 0; + stream_rect.width = get_stream_width (window_src); + stream_rect.height = get_stream_height (window_src); + + meta_rectangle_intersect (crop_rect, &stream_rect, crop_rect); + + return TRUE; +} + +static void +meta_screen_cast_window_stream_src_stop (MetaScreenCastWindowStreamSrc *window_src) + +{ + MetaBackend *backend = get_backend (window_src); + MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend); + + if (!window_src->screen_cast_window) + return; + + g_clear_signal_handler (&window_src->screen_cast_window_damaged_handler_id, + window_src->screen_cast_window); + g_clear_signal_handler (&window_src->screen_cast_window_destroyed_handler_id, + window_src->screen_cast_window); + g_clear_signal_handler (&window_src->cursor_moved_handler_id, + cursor_tracker); + g_clear_signal_handler (&window_src->cursor_changed_handler_id, + cursor_tracker); +} + +static void +screen_cast_window_damaged (MetaWindowActor *actor, + MetaScreenCastWindowStreamSrc *window_src) +{ + MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (window_src); + MetaScreenCastRecordFlag flags; + + flags = META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY; + meta_screen_cast_stream_src_maybe_record_frame (src, flags); +} + +static void +screen_cast_window_destroyed (MetaWindowActor *actor, + MetaScreenCastWindowStreamSrc *window_src) +{ + meta_screen_cast_window_stream_src_stop (window_src); + window_src->screen_cast_window = NULL; +} + +static void +sync_cursor_state (MetaScreenCastWindowStreamSrc *window_src) +{ + MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (window_src); + MetaScreenCastRecordFlag flags; + + if (meta_screen_cast_window_has_damage (window_src->screen_cast_window)) + return; + + flags = META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY; + meta_screen_cast_stream_src_maybe_record_frame (src, flags); +} + +static void +cursor_moved (MetaCursorTracker *cursor_tracker, + float x, + float y, + MetaScreenCastWindowStreamSrc *window_src) +{ + sync_cursor_state (window_src); +} + +static void +cursor_changed (MetaCursorTracker *cursor_tracker, + MetaScreenCastWindowStreamSrc *window_src) +{ + window_src->cursor_bitmap_invalid = TRUE; + sync_cursor_state (window_src); +} + +static void +meta_screen_cast_window_stream_src_enable (MetaScreenCastStreamSrc *src) +{ + MetaScreenCastWindowStreamSrc *window_src = + META_SCREEN_CAST_WINDOW_STREAM_SRC (src); + MetaBackend *backend = get_backend (window_src); + MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend); + MetaWindowActor *window_actor; + MetaScreenCastStream *stream; + MetaScreenCastRecordFlag flags; + + window_actor = meta_window_actor_from_window (get_window (window_src)); + if (!window_actor) + return; + + window_src->screen_cast_window = META_SCREEN_CAST_WINDOW (window_actor); + + window_src->screen_cast_window_damaged_handler_id = + g_signal_connect (window_src->screen_cast_window, + "damaged", + G_CALLBACK (screen_cast_window_damaged), + window_src); + + window_src->screen_cast_window_destroyed_handler_id = + g_signal_connect (window_src->screen_cast_window, + "destroy", + G_CALLBACK (screen_cast_window_destroyed), + window_src); + + stream = meta_screen_cast_stream_src_get_stream (src); + switch (meta_screen_cast_stream_get_cursor_mode (stream)) + { + case META_SCREEN_CAST_CURSOR_MODE_METADATA: + case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED: + window_src->cursor_moved_handler_id = + g_signal_connect_after (cursor_tracker, "cursor-moved", + G_CALLBACK (cursor_moved), + window_src); + window_src->cursor_changed_handler_id = + g_signal_connect_after (cursor_tracker, "cursor-changed", + G_CALLBACK (cursor_changed), + window_src); + break; + case META_SCREEN_CAST_CURSOR_MODE_HIDDEN: + break; + } + + flags = META_SCREEN_CAST_RECORD_FLAG_NONE; + meta_screen_cast_stream_src_maybe_record_frame (src, flags); +} + +static void +meta_screen_cast_window_stream_src_disable (MetaScreenCastStreamSrc *src) +{ + MetaScreenCastWindowStreamSrc *window_src = + META_SCREEN_CAST_WINDOW_STREAM_SRC (src); + + meta_screen_cast_window_stream_src_stop (window_src); +} + +static gboolean +meta_screen_cast_window_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src, + uint8_t *data, + GError **error) +{ + MetaScreenCastWindowStreamSrc *window_src = + META_SCREEN_CAST_WINDOW_STREAM_SRC (src); + + capture_into (window_src, data); + + return TRUE; +} + +static gboolean +meta_screen_cast_window_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src, + CoglFramebuffer *framebuffer, + GError **error) +{ + MetaScreenCastWindowStreamSrc *window_src = + META_SCREEN_CAST_WINDOW_STREAM_SRC (src); + MetaScreenCastStream *stream; + MetaRectangle stream_rect; + + stream_rect.x = 0; + stream_rect.y = 0; + stream_rect.width = get_stream_width (window_src); + stream_rect.height = get_stream_height (window_src); + + if (!meta_screen_cast_window_blit_to_framebuffer (window_src->screen_cast_window, + &stream_rect, + framebuffer)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Failed to blit window content to framebuffer"); + return FALSE; + } + + stream = meta_screen_cast_stream_src_get_stream (src); + switch (meta_screen_cast_stream_get_cursor_mode (stream)) + { + case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED: + maybe_blit_cursor_sprite (window_src, framebuffer, &stream_rect); + break; + case META_SCREEN_CAST_CURSOR_MODE_METADATA: + case META_SCREEN_CAST_CURSOR_MODE_HIDDEN: + break; + } + + cogl_framebuffer_finish (framebuffer); + + return TRUE; +} + +static void +meta_screen_cast_window_stream_record_follow_up (MetaScreenCastStreamSrc *src) +{ + MetaScreenCastRecordFlag flags; + + flags = META_SCREEN_CAST_RECORD_FLAG_NONE; + meta_screen_cast_stream_src_maybe_record_frame (src, flags); +} + +static void +meta_screen_cast_window_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc *src, + struct spa_meta_cursor *spa_meta_cursor) +{ + MetaScreenCastWindowStreamSrc *window_src = + META_SCREEN_CAST_WINDOW_STREAM_SRC (src); + MetaBackend *backend = get_backend (window_src); + MetaCursorRenderer *cursor_renderer = + meta_backend_get_cursor_renderer (backend); + MetaScreenCastWindow *screen_cast_window = window_src->screen_cast_window; + MetaCursorSprite *cursor_sprite; + graphene_point_t cursor_position; + float scale; + graphene_point_t relative_cursor_position; + int x, y; + + cursor_sprite = meta_cursor_renderer_get_cursor (cursor_renderer); + cursor_position = meta_cursor_renderer_get_position (cursor_renderer); + + if (!meta_screen_cast_window_transform_cursor_position (screen_cast_window, + cursor_sprite, + &cursor_position, + &scale, + &relative_cursor_position)) + { + meta_screen_cast_stream_src_unset_cursor_metadata (src, + spa_meta_cursor); + return; + } + + x = (int) roundf (relative_cursor_position.x); + y = (int) roundf (relative_cursor_position.y); + + if (window_src->cursor_bitmap_invalid) + { + if (cursor_sprite) + { + meta_screen_cast_stream_src_set_cursor_sprite_metadata (src, + spa_meta_cursor, + cursor_sprite, + x, y, + scale); + } + else + { + meta_screen_cast_stream_src_set_empty_cursor_sprite_metadata (src, + spa_meta_cursor, + x, y); + } + window_src->cursor_bitmap_invalid = FALSE; + } + else + { + meta_screen_cast_stream_src_set_cursor_position_metadata (src, + spa_meta_cursor, + x, y); + } +} + +MetaScreenCastWindowStreamSrc * +meta_screen_cast_window_stream_src_new (MetaScreenCastWindowStream *window_stream, + GError **error) +{ + return g_initable_new (META_TYPE_SCREEN_CAST_WINDOW_STREAM_SRC, NULL, error, + "stream", window_stream, + NULL); +} + +static void +meta_screen_cast_window_stream_src_init (MetaScreenCastWindowStreamSrc *window_src) +{ + window_src->cursor_bitmap_invalid = TRUE; +} + +static void +meta_screen_cast_window_stream_src_class_init (MetaScreenCastWindowStreamSrcClass *klass) +{ + MetaScreenCastStreamSrcClass *src_class = + META_SCREEN_CAST_STREAM_SRC_CLASS (klass); + + src_class->get_specs = meta_screen_cast_window_stream_src_get_specs; + src_class->enable = meta_screen_cast_window_stream_src_enable; + src_class->disable = meta_screen_cast_window_stream_src_disable; + src_class->record_to_buffer = + meta_screen_cast_window_stream_src_record_to_buffer; + src_class->record_to_framebuffer = + meta_screen_cast_window_stream_src_record_to_framebuffer; + src_class->record_follow_up = + meta_screen_cast_window_stream_record_follow_up; + src_class->get_videocrop = meta_screen_cast_window_stream_src_get_videocrop; + src_class->set_cursor_metadata = meta_screen_cast_window_stream_src_set_cursor_metadata; +} diff --git a/src/backends/meta-screen-cast-window-stream-src.h b/src/backends/meta-screen-cast-window-stream-src.h new file mode 100644 index 000000000..37f786979 --- /dev/null +++ b/src/backends/meta-screen-cast-window-stream-src.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2018 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#ifndef META_SCREEN_CAST_WINDOW_STREAM_SRC_H +#define META_SCREEN_CAST_WINDOW_STREAM_SRC_H + +#include "backends/meta-screen-cast-stream-src.h" + +typedef struct _MetaScreenCastWindowStream MetaScreenCastWindowStream; + +#define META_TYPE_SCREEN_CAST_WINDOW_STREAM_SRC (meta_screen_cast_window_stream_src_get_type ()) +G_DECLARE_FINAL_TYPE (MetaScreenCastWindowStreamSrc, + meta_screen_cast_window_stream_src, + META, SCREEN_CAST_WINDOW_STREAM_SRC, + MetaScreenCastStreamSrc) + +MetaScreenCastWindowStreamSrc * meta_screen_cast_window_stream_src_new (MetaScreenCastWindowStream *window_stream, + GError **error); + +#endif /* META_SCREEN_CAST_WINDOW_STREAM_SRC_H */ diff --git a/src/backends/meta-screen-cast-window-stream.c b/src/backends/meta-screen-cast-window-stream.c new file mode 100644 index 000000000..493a0b3f4 --- /dev/null +++ b/src/backends/meta-screen-cast-window-stream.c @@ -0,0 +1,282 @@ +/* + * Copyright (C) 2018 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#include "config.h" + +#include "backends/meta-screen-cast-window-stream.h" + +#include "backends/meta-logical-monitor.h" +#include "backends/meta-monitor-manager-private.h" +#include "backends/meta-screen-cast-window.h" +#include "backends/meta-screen-cast-window-stream-src.h" +#include "compositor/meta-window-actor-private.h" +#include "core/window-private.h" + +enum +{ + PROP_0, + + PROP_WINDOW, +}; + +struct _MetaScreenCastWindowStream +{ + MetaScreenCastStream parent; + + MetaWindow *window; + + int stream_width; + int stream_height; + int logical_width; + int logical_height; + + unsigned long window_unmanaged_handler_id; +}; + +static GInitableIface *initable_parent_iface; + +static void +meta_screen_cast_window_stream_init_initable_iface (GInitableIface *iface); + +G_DEFINE_TYPE_WITH_CODE (MetaScreenCastWindowStream, + meta_screen_cast_window_stream, + META_TYPE_SCREEN_CAST_STREAM, + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + meta_screen_cast_window_stream_init_initable_iface)) + +MetaWindow * +meta_screen_cast_window_stream_get_window (MetaScreenCastWindowStream *window_stream) +{ + return window_stream->window; +} + +int +meta_screen_cast_window_stream_get_width (MetaScreenCastWindowStream *window_stream) +{ + return window_stream->stream_width; +} + +int +meta_screen_cast_window_stream_get_height (MetaScreenCastWindowStream *window_stream) +{ + return window_stream->stream_height; +} + +MetaScreenCastWindowStream * +meta_screen_cast_window_stream_new (MetaScreenCastSession *session, + GDBusConnection *connection, + MetaWindow *window, + MetaScreenCastCursorMode cursor_mode, + GError **error) +{ + return g_initable_new (META_TYPE_SCREEN_CAST_WINDOW_STREAM, + NULL, + error, + "session", session, + "connection", connection, + "cursor-mode", cursor_mode, + "window", window, + NULL); +} + +static MetaScreenCastStreamSrc * +meta_screen_cast_window_stream_create_src (MetaScreenCastStream *stream, + GError **error) +{ + MetaScreenCastWindowStream *window_stream = + META_SCREEN_CAST_WINDOW_STREAM (stream); + MetaScreenCastWindowStreamSrc *window_stream_src; + + window_stream_src = meta_screen_cast_window_stream_src_new (window_stream, + error); + if (!window_stream_src) + return NULL; + + return META_SCREEN_CAST_STREAM_SRC (window_stream_src); +} + +static void +meta_screen_cast_window_stream_set_parameters (MetaScreenCastStream *stream, + GVariantBuilder *parameters_builder) +{ + MetaScreenCastWindowStream *window_stream = + META_SCREEN_CAST_WINDOW_STREAM (stream); + + g_variant_builder_add (parameters_builder, "{sv}", + "size", + g_variant_new ("(ii)", + window_stream->logical_width, + window_stream->logical_height)); +} + +static void +meta_screen_cast_window_stream_transform_position (MetaScreenCastStream *stream, + double stream_x, + double stream_y, + double *x, + double *y) +{ + MetaScreenCastWindowStream *window_stream = + META_SCREEN_CAST_WINDOW_STREAM (stream); + MetaScreenCastWindow *screen_cast_window = + META_SCREEN_CAST_WINDOW (meta_window_actor_from_window (window_stream->window)); + + meta_screen_cast_window_transform_relative_position (screen_cast_window, + stream_x, + stream_y, + x, + y); +} + +static void +on_window_unmanaged (MetaScreenCastWindowStream *window_stream) +{ + meta_screen_cast_stream_close (META_SCREEN_CAST_STREAM (window_stream)); +} + +static void +meta_screen_cast_window_stream_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaScreenCastWindowStream *window_stream = + META_SCREEN_CAST_WINDOW_STREAM (object); + + switch (prop_id) + { + case PROP_WINDOW: + window_stream->window = g_value_get_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_screen_cast_window_stream_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaScreenCastWindowStream *window_stream = + META_SCREEN_CAST_WINDOW_STREAM (object); + + switch (prop_id) + { + case PROP_WINDOW: + g_value_set_object (value, window_stream->window); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_screen_cast_window_stream_finalize (GObject *object) +{ + MetaScreenCastWindowStream *window_stream = + META_SCREEN_CAST_WINDOW_STREAM (object); + + g_clear_signal_handler (&window_stream->window_unmanaged_handler_id, + window_stream->window); + + G_OBJECT_CLASS (meta_screen_cast_window_stream_parent_class)->finalize (object); +} + +static gboolean +meta_screen_cast_window_stream_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + MetaScreenCastWindowStream *window_stream = + META_SCREEN_CAST_WINDOW_STREAM (initable); + MetaWindow *window = window_stream->window; + MetaLogicalMonitor *logical_monitor; + int scale; + + logical_monitor = meta_window_get_main_logical_monitor (window); + if (!logical_monitor) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Main logical monitor not found"); + return FALSE; + } + + window_stream->window_unmanaged_handler_id = + g_signal_connect_swapped (window, "unmanaged", + G_CALLBACK (on_window_unmanaged), + window_stream); + + if (meta_is_stage_views_scaled ()) + scale = (int) ceilf (meta_logical_monitor_get_scale (logical_monitor)); + else + scale = 1; + + /* We cannot set the stream size to the exact size of the window, because + * windows can be resized, whereas streams cannot. + * So we set a size equals to the size of the logical monitor for the window. + */ + window_stream->logical_width = logical_monitor->rect.width; + window_stream->logical_height = logical_monitor->rect.height; + window_stream->stream_width = logical_monitor->rect.width * scale; + window_stream->stream_height = logical_monitor->rect.height * scale; + + return initable_parent_iface->init (initable, cancellable, error); +} + +static void +meta_screen_cast_window_stream_init_initable_iface (GInitableIface *iface) +{ + initable_parent_iface = g_type_interface_peek_parent (iface); + + iface->init = meta_screen_cast_window_stream_initable_init; +} + +static void +meta_screen_cast_window_stream_init (MetaScreenCastWindowStream *window_stream) +{ +} + +static void +meta_screen_cast_window_stream_class_init (MetaScreenCastWindowStreamClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MetaScreenCastStreamClass *stream_class = + META_SCREEN_CAST_STREAM_CLASS (klass); + + object_class->set_property = meta_screen_cast_window_stream_set_property; + object_class->get_property = meta_screen_cast_window_stream_get_property; + object_class->finalize = meta_screen_cast_window_stream_finalize; + + stream_class->create_src = meta_screen_cast_window_stream_create_src; + stream_class->set_parameters = meta_screen_cast_window_stream_set_parameters; + stream_class->transform_position = meta_screen_cast_window_stream_transform_position; + + g_object_class_install_property (object_class, + PROP_WINDOW, + g_param_spec_object ("window", + "window", + "MetaWindow", + META_TYPE_WINDOW, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); +} diff --git a/src/backends/meta-screen-cast-window-stream.h b/src/backends/meta-screen-cast-window-stream.h new file mode 100644 index 000000000..6eae74f1c --- /dev/null +++ b/src/backends/meta-screen-cast-window-stream.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2018 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#ifndef META_SCREEN_CAST_WINDOW_STREAM_H +#define META_SCREEN_CAST_WINDOW_STREAM_H + +#include <glib-object.h> + +#include "backends/meta-screen-cast-stream.h" +#include "meta/window.h" + +#define META_TYPE_SCREEN_CAST_WINDOW_STREAM (meta_screen_cast_window_stream_get_type ()) +G_DECLARE_FINAL_TYPE (MetaScreenCastWindowStream, + meta_screen_cast_window_stream, + META, SCREEN_CAST_WINDOW_STREAM, + MetaScreenCastStream) + +MetaScreenCastWindowStream * meta_screen_cast_window_stream_new (MetaScreenCastSession *session, + GDBusConnection *connection, + MetaWindow *window, + MetaScreenCastCursorMode cursor_mode, + GError **error); + +MetaWindow * meta_screen_cast_window_stream_get_window (MetaScreenCastWindowStream *window_stream); +int meta_screen_cast_window_stream_get_width (MetaScreenCastWindowStream *window_stream); +int meta_screen_cast_window_stream_get_height (MetaScreenCastWindowStream *window_stream); + +#endif /* META_SCREEN_CAST_WINDOW_STREAM_H */ diff --git a/src/backends/meta-screen-cast-window.c b/src/backends/meta-screen-cast-window.c new file mode 100644 index 000000000..ab3e4ebe3 --- /dev/null +++ b/src/backends/meta-screen-cast-window.c @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2018 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#include "config.h" + +#include "backends/meta-screen-cast-window.h" + +G_DEFINE_INTERFACE (MetaScreenCastWindow, meta_screen_cast_window, G_TYPE_OBJECT) + +static void +meta_screen_cast_window_default_init (MetaScreenCastWindowInterface *iface) +{ +} + +void +meta_screen_cast_window_get_buffer_bounds (MetaScreenCastWindow *screen_cast_window, + MetaRectangle *bounds) +{ + META_SCREEN_CAST_WINDOW_GET_IFACE (screen_cast_window)->get_buffer_bounds (screen_cast_window, + bounds); +} + +void +meta_screen_cast_window_transform_relative_position (MetaScreenCastWindow *screen_cast_window, + double x, + double y, + double *x_out, + double *y_out) +{ + META_SCREEN_CAST_WINDOW_GET_IFACE (screen_cast_window)->transform_relative_position (screen_cast_window, + x, + y, + x_out, + y_out); +} + +gboolean +meta_screen_cast_window_transform_cursor_position (MetaScreenCastWindow *screen_cast_window, + MetaCursorSprite *cursor_sprite, + graphene_point_t *cursor_position, + float *out_cursor_scale, + graphene_point_t *out_relative_cursor_position) +{ + MetaScreenCastWindowInterface *iface = + META_SCREEN_CAST_WINDOW_GET_IFACE (screen_cast_window); + + return iface->transform_cursor_position (screen_cast_window, + cursor_sprite, + cursor_position, + out_cursor_scale, + out_relative_cursor_position); +} + +void +meta_screen_cast_window_capture_into (MetaScreenCastWindow *screen_cast_window, + MetaRectangle *bounds, + uint8_t *data) +{ + META_SCREEN_CAST_WINDOW_GET_IFACE (screen_cast_window)->capture_into (screen_cast_window, + bounds, + data); +} + +gboolean +meta_screen_cast_window_blit_to_framebuffer (MetaScreenCastWindow *screen_cast_window, + MetaRectangle *bounds, + CoglFramebuffer *framebuffer) +{ + MetaScreenCastWindowInterface *iface = + META_SCREEN_CAST_WINDOW_GET_IFACE (screen_cast_window); + + return iface->blit_to_framebuffer (screen_cast_window, bounds, framebuffer); +} + +gboolean +meta_screen_cast_window_has_damage (MetaScreenCastWindow *screen_cast_window) +{ + MetaScreenCastWindowInterface *iface = + META_SCREEN_CAST_WINDOW_GET_IFACE (screen_cast_window); + + return iface->has_damage (screen_cast_window); +} diff --git a/src/backends/meta-screen-cast-window.h b/src/backends/meta-screen-cast-window.h new file mode 100644 index 000000000..e149646ed --- /dev/null +++ b/src/backends/meta-screen-cast-window.h @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2018 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#ifndef META_SCREEN_CAST_WINDOW_H +#define META_SCREEN_CAST_WINDOW_H + +#include <stdint.h> +#include <glib-object.h> + +#include "backends/meta-cursor.h" +#include "meta/boxes.h" + +G_BEGIN_DECLS + +#define META_TYPE_SCREEN_CAST_WINDOW (meta_screen_cast_window_get_type ()) +G_DECLARE_INTERFACE (MetaScreenCastWindow, meta_screen_cast_window, + META, SCREEN_CAST_WINDOW, GObject) + +struct _MetaScreenCastWindowInterface +{ + GTypeInterface parent_iface; + + void (*get_buffer_bounds) (MetaScreenCastWindow *screen_cast_window, + MetaRectangle *bounds); + + void (*transform_relative_position) (MetaScreenCastWindow *screen_cast_window, + double x, + double y, + double *x_out, + double *y_out); + + gboolean (*transform_cursor_position) (MetaScreenCastWindow *screen_cast_window, + MetaCursorSprite *cursor_sprite, + graphene_point_t *cursor_position, + float *out_cursor_scale, + graphene_point_t *out_relative_cursor_position); + + void (*capture_into) (MetaScreenCastWindow *screen_cast_window, + MetaRectangle *bounds, + uint8_t *data); + + gboolean (*blit_to_framebuffer) (MetaScreenCastWindow *screen_cast_window, + MetaRectangle *bounds, + CoglFramebuffer *framebuffer); + + gboolean (*has_damage) (MetaScreenCastWindow *screen_cast_window); +}; + +void meta_screen_cast_window_get_buffer_bounds (MetaScreenCastWindow *screen_cast_window, + MetaRectangle *bounds); + +void meta_screen_cast_window_transform_relative_position (MetaScreenCastWindow *screen_cast_window, + double x, + double y, + double *x_out, + double *y_out); + +gboolean meta_screen_cast_window_transform_cursor_position (MetaScreenCastWindow *screen_cast_window, + MetaCursorSprite *cursor_sprite, + graphene_point_t *cursor_position, + float *out_cursor_scale, + graphene_point_t *out_relative_cursor_position); + +void meta_screen_cast_window_capture_into (MetaScreenCastWindow *screen_cast_window, + MetaRectangle *bounds, + uint8_t *data); + +gboolean meta_screen_cast_window_blit_to_framebuffer (MetaScreenCastWindow *screen_cast_window, + MetaRectangle *bounds, + CoglFramebuffer *framebuffer); + +gboolean meta_screen_cast_window_has_damage (MetaScreenCastWindow *screen_cast_window); + +G_END_DECLS + +#endif /* META_SCREEN_CAST_WINDOW_H */ diff --git a/src/backends/meta-screen-cast.c b/src/backends/meta-screen-cast.c new file mode 100644 index 000000000..b473aa8eb --- /dev/null +++ b/src/backends/meta-screen-cast.c @@ -0,0 +1,299 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2015-2017 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#include "config.h" + +#include "backends/meta-screen-cast.h" + +#include <pipewire/pipewire.h> + +#include "backends/meta-backend-private.h" +#include "backends/meta-remote-desktop-session.h" +#include "backends/meta-screen-cast-session.h" + +#define META_SCREEN_CAST_DBUS_SERVICE "org.gnome.Mutter.ScreenCast" +#define META_SCREEN_CAST_DBUS_PATH "/org/gnome/Mutter/ScreenCast" +#define META_SCREEN_CAST_API_VERSION 3 + +struct _MetaScreenCast +{ + MetaDBusScreenCastSkeleton parent; + + int dbus_name_id; + + GList *sessions; + + MetaDbusSessionWatcher *session_watcher; + MetaBackend *backend; +}; + +static void +meta_screen_cast_init_iface (MetaDBusScreenCastIface *iface); + +G_DEFINE_TYPE_WITH_CODE (MetaScreenCast, meta_screen_cast, + META_DBUS_TYPE_SCREEN_CAST_SKELETON, + G_IMPLEMENT_INTERFACE (META_DBUS_TYPE_SCREEN_CAST, + meta_screen_cast_init_iface)) + +GDBusConnection * +meta_screen_cast_get_connection (MetaScreenCast *screen_cast) +{ + GDBusInterfaceSkeleton *interface_skeleton = + G_DBUS_INTERFACE_SKELETON (screen_cast); + + return g_dbus_interface_skeleton_get_connection (interface_skeleton); +} + +MetaBackend * +meta_screen_cast_get_backend (MetaScreenCast *screen_cast) +{ + return screen_cast->backend; +} + +static gboolean +register_remote_desktop_screen_cast_session (MetaScreenCastSession *session, + const char *remote_desktop_session_id, + GError **error) +{ + MetaScreenCast *screen_cast = + meta_screen_cast_session_get_screen_cast (session); + MetaBackend *backend = meta_screen_cast_get_backend (screen_cast); + MetaRemoteDesktop *remote_desktop = meta_backend_get_remote_desktop (backend); + MetaRemoteDesktopSession *remote_desktop_session; + + remote_desktop_session = + meta_remote_desktop_get_session (remote_desktop, remote_desktop_session_id); + if (!remote_desktop_session) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "No remote desktop session found"); + return FALSE; + } + + if (!meta_remote_desktop_session_register_screen_cast (remote_desktop_session, + session, + error)) + return FALSE; + + return TRUE; +} + +static void +on_session_closed (MetaScreenCastSession *session, + MetaScreenCast *screen_cast) +{ + screen_cast->sessions = g_list_remove (screen_cast->sessions, session); +} + +static gboolean +handle_create_session (MetaDBusScreenCast *skeleton, + GDBusMethodInvocation *invocation, + GVariant *properties) +{ + MetaScreenCast *screen_cast = META_SCREEN_CAST (skeleton); + const char *peer_name; + MetaScreenCastSession *session; + GError *error = NULL; + const char *session_path; + const char *client_dbus_name; + char *remote_desktop_session_id = NULL; + gboolean disable_animations; + MetaScreenCastSessionType session_type; + + g_variant_lookup (properties, "remote-desktop-session-id", "s", + &remote_desktop_session_id); + + if (remote_desktop_session_id) + session_type = META_SCREEN_CAST_SESSION_TYPE_REMOTE_DESKTOP; + else + session_type = META_SCREEN_CAST_SESSION_TYPE_NORMAL; + + peer_name = g_dbus_method_invocation_get_sender (invocation); + session = meta_screen_cast_session_new (screen_cast, + session_type, + peer_name, + &error); + if (!session) + { + g_warning ("Failed to create screen cast session: %s", + error->message); + + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_FAILED, + "Failed to create session: %s", + error->message); + g_error_free (error); + + return TRUE; + } + + if (remote_desktop_session_id) + { + if (!register_remote_desktop_screen_cast_session (session, + remote_desktop_session_id, + &error)) + { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_FAILED, + "%s", error->message); + g_error_free (error); + g_object_unref (session); + return TRUE; + } + } + + if (g_variant_lookup (properties, "disable-animations", "b", + &disable_animations)) + { + meta_screen_cast_session_set_disable_animations (session, + disable_animations); + } + + client_dbus_name = g_dbus_method_invocation_get_sender (invocation); + meta_dbus_session_watcher_watch_session (screen_cast->session_watcher, + client_dbus_name, + META_DBUS_SESSION (session)); + + session_path = meta_screen_cast_session_get_object_path (session); + meta_dbus_screen_cast_complete_create_session (skeleton, + invocation, + session_path); + + screen_cast->sessions = g_list_append (screen_cast->sessions, session); + + g_signal_connect (session, "session-closed", + G_CALLBACK (on_session_closed), + screen_cast); + + return TRUE; +} + +static void +meta_screen_cast_init_iface (MetaDBusScreenCastIface *iface) +{ + iface->handle_create_session = handle_create_session; +} + +static void +on_bus_acquired (GDBusConnection *connection, + const char *name, + gpointer user_data) +{ + MetaScreenCast *screen_cast = user_data; + GDBusInterfaceSkeleton *interface_skeleton = + G_DBUS_INTERFACE_SKELETON (screen_cast); + GError *error = NULL; + + if (!g_dbus_interface_skeleton_export (interface_skeleton, + connection, + META_SCREEN_CAST_DBUS_PATH, + &error)) + g_warning ("Failed to export remote desktop object: %s\n", error->message); +} + +static void +on_name_acquired (GDBusConnection *connection, + const char *name, + gpointer user_data) +{ + g_info ("Acquired name %s\n", name); +} + +static void +on_name_lost (GDBusConnection *connection, + const char *name, + gpointer user_data) +{ + g_warning ("Lost or failed to acquire name %s\n", name); +} + +static void +meta_screen_cast_constructed (GObject *object) +{ + MetaScreenCast *screen_cast = META_SCREEN_CAST (object); + + screen_cast->dbus_name_id = + g_bus_own_name (G_BUS_TYPE_SESSION, + META_SCREEN_CAST_DBUS_SERVICE, + G_BUS_NAME_OWNER_FLAGS_NONE, + on_bus_acquired, + on_name_acquired, + on_name_lost, + screen_cast, + NULL); +} + +static void +meta_screen_cast_finalize (GObject *object) +{ + MetaScreenCast *screen_cast = META_SCREEN_CAST (object); + + if (screen_cast->dbus_name_id) + g_bus_unown_name (screen_cast->dbus_name_id); + + while (screen_cast->sessions) + { + MetaScreenCastSession *session = screen_cast->sessions->data; + + meta_screen_cast_session_close (session); + } + + G_OBJECT_CLASS (meta_screen_cast_parent_class)->finalize (object); +} + +MetaScreenCast * +meta_screen_cast_new (MetaBackend *backend, + MetaDbusSessionWatcher *session_watcher) +{ + MetaScreenCast *screen_cast; + + screen_cast = g_object_new (META_TYPE_SCREEN_CAST, NULL); + screen_cast->backend = backend; + screen_cast->session_watcher = session_watcher; + + return screen_cast; +} + + +static void +meta_screen_cast_init (MetaScreenCast *screen_cast) +{ + static gboolean is_pipewire_initialized = FALSE; + + if (!is_pipewire_initialized) + { + pw_init (NULL, NULL); + is_pipewire_initialized = TRUE; + } + + meta_dbus_screen_cast_set_version (META_DBUS_SCREEN_CAST (screen_cast), + META_SCREEN_CAST_API_VERSION); +} + +static void +meta_screen_cast_class_init (MetaScreenCastClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->constructed = meta_screen_cast_constructed; + object_class->finalize = meta_screen_cast_finalize; +} diff --git a/src/backends/meta-screen-cast.h b/src/backends/meta-screen-cast.h new file mode 100644 index 000000000..994c40c53 --- /dev/null +++ b/src/backends/meta-screen-cast.h @@ -0,0 +1,52 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2015-2017 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#ifndef META_SCREEN_CAST_H +#define META_SCREEN_CAST_H + +#include <glib-object.h> + +#include "backends/meta-backend-private.h" +#include "backends/meta-dbus-session-watcher.h" + +#include "meta-dbus-screen-cast.h" + +typedef enum _MetaScreenCastCursorMode +{ + META_SCREEN_CAST_CURSOR_MODE_HIDDEN = 0, + META_SCREEN_CAST_CURSOR_MODE_EMBEDDED = 1, + META_SCREEN_CAST_CURSOR_MODE_METADATA = 2, +} MetaScreenCastCursorMode; + +#define META_TYPE_SCREEN_CAST (meta_screen_cast_get_type ()) +G_DECLARE_FINAL_TYPE (MetaScreenCast, meta_screen_cast, + META, SCREEN_CAST, + MetaDBusScreenCastSkeleton) + +GDBusConnection * meta_screen_cast_get_connection (MetaScreenCast *screen_cast); + +MetaBackend * meta_screen_cast_get_backend (MetaScreenCast *screen_cast); + +MetaScreenCast * meta_screen_cast_new (MetaBackend *backend, + MetaDbusSessionWatcher *session_watcher); + +#endif /* META_SCREEN_CAST_H */ diff --git a/src/backends/meta-settings-private.h b/src/backends/meta-settings-private.h new file mode 100644 index 000000000..a7241cec7 --- /dev/null +++ b/src/backends/meta-settings-private.h @@ -0,0 +1,85 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_SETTINGS_PRIVATE_H +#define META_SETTINGS_PRIVATE_H + +#include <glib-object.h> + +#include "meta/meta-settings.h" +#include "meta/types.h" +#include "core/util-private.h" + +typedef enum _MetaExperimentalFeature +{ + META_EXPERIMENTAL_FEATURE_NONE = 0, + META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER = (1 << 0), + META_EXPERIMENTAL_FEATURE_KMS_MODIFIERS = (1 << 1), + META_EXPERIMENTAL_FEATURE_RT_SCHEDULER = (1 << 2), + META_EXPERIMENTAL_FEATURE_AUTOSTART_XWAYLAND = (1 << 3), + META_EXPERIMENTAL_FEATURE_X11_RANDR_FRACTIONAL_SCALING = (1 << 4), +} MetaExperimentalFeature; + +typedef enum _MetaX11ScaleMode +{ + META_X11_SCALE_MODE_NONE = 0, + META_X11_SCALE_MODE_UP = 1, + META_X11_SCALE_MODE_UI_DOWN = 2, +} MetaX11ScaleMode; + +#define META_TYPE_SETTINGS (meta_settings_get_type ()) +G_DECLARE_FINAL_TYPE (MetaSettings, meta_settings, + META, SETTINGS, GObject) + +MetaSettings * meta_settings_new (MetaBackend *backend); + +void meta_settings_post_init (MetaSettings *settings); + +void meta_settings_update_ui_scaling_factor (MetaSettings *settings); + +gboolean meta_settings_get_global_scaling_factor (MetaSettings *settings, + int *scaing_factor); + +META_EXPORT_TEST +gboolean meta_settings_is_experimental_feature_enabled (MetaSettings *settings, + MetaExperimentalFeature feature); + +MetaExperimentalFeature meta_settings_get_experimental_features (MetaSettings *settings); + +META_EXPORT_TEST +void meta_settings_override_experimental_features (MetaSettings *settings); + +META_EXPORT_TEST +void meta_settings_enable_experimental_feature (MetaSettings *settings, + MetaExperimentalFeature feature); + +void meta_settings_get_xwayland_grab_patterns (MetaSettings *settings, + GPtrArray **whitelist_patterns, + GPtrArray **blacklist_patterns); + +gboolean meta_settings_are_xwayland_grabs_allowed (MetaSettings *settings); + +MetaX11ScaleMode meta_settings_get_x11_scale_mode (MetaSettings *settings); + +void meta_settings_enable_x11_fractional_scaling (MetaSettings *settings, + gboolean enabled); + +#endif /* META_SETTINGS_PRIVATE_H */ diff --git a/src/backends/meta-settings.c b/src/backends/meta-settings.c new file mode 100644 index 000000000..e544d6588 --- /dev/null +++ b/src/backends/meta-settings.c @@ -0,0 +1,671 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "backends/meta-settings-private.h" + +#include <gio/gio.h> + +#include "backends/meta-backend-private.h" +#include "backends/meta-logical-monitor.h" +#include "backends/meta-monitor-manager-private.h" +#include "ui/theme-private.h" + +#ifndef XWAYLAND_GRAB_DEFAULT_ACCESS_RULES +# warning "XWAYLAND_GRAB_DEFAULT_ACCESS_RULES is not set" +# define XWAYLAND_GRAB_DEFAULT_ACCESS_RULES "" +#endif + +enum +{ + UI_SCALING_FACTOR_CHANGED, + GLOBAL_SCALING_FACTOR_CHANGED, + FONT_DPI_CHANGED, + X11_SCALE_MODE_CHANGED, + EXPERIMENTAL_FEATURES_CHANGED, + + N_SIGNALS +}; + +static guint signals[N_SIGNALS]; + +struct _MetaSettings +{ + GObject parent; + + MetaBackend *backend; + + GSettings *interface_settings; + GSettings *mutter_settings; + GSettings *wayland_settings; + GSettings *x11_settings; + + int ui_scaling_factor; + int global_scaling_factor; + + int font_dpi; + + MetaExperimentalFeature experimental_features; + gboolean experimental_features_overridden; + + gboolean xwayland_allow_grabs; + GPtrArray *xwayland_grab_whitelist_patterns; + GPtrArray *xwayland_grab_blacklist_patterns; + + MetaX11ScaleMode x11_scale_mode; +}; + +G_DEFINE_TYPE (MetaSettings, meta_settings, G_TYPE_OBJECT) + +static int +calculate_ui_scaling_factor (MetaSettings *settings) +{ + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (settings->backend); + + if (!meta_is_wayland_compositor () && + monitor_manager && + (meta_monitor_manager_get_capabilities (monitor_manager) & + META_MONITOR_MANAGER_CAPABILITY_LAYOUT_MODE)) + { + MetaLogicalMonitorLayoutMode layout_mode = + meta_monitor_manager_get_default_layout_mode (monitor_manager); + + if (layout_mode == META_LOGICAL_MONITOR_LAYOUT_MODE_GLOBAL_UI_LOGICAL) + { + return + ceilf (meta_monitor_manager_get_maximum_crtc_scale (monitor_manager)); + } + else if (layout_mode == META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL) + { + return 1.0f; + } + } + + if (monitor_manager) + { + MetaLogicalMonitor *primary_logical_monitor; + + primary_logical_monitor = + meta_monitor_manager_get_primary_logical_monitor (monitor_manager); + if (!primary_logical_monitor) + return 1; + + return (int) meta_logical_monitor_get_scale (primary_logical_monitor); + } + + return 1; +} + +static gboolean +update_ui_scaling_factor (MetaSettings *settings) +{ + int ui_scaling_factor; + + if (meta_is_stage_views_scaled ()) + ui_scaling_factor = 1; + else + ui_scaling_factor = calculate_ui_scaling_factor (settings); + + if (settings->ui_scaling_factor != ui_scaling_factor) + { + settings->ui_scaling_factor = ui_scaling_factor; + return TRUE; + } + else + { + return FALSE; + } +} + +void +meta_settings_update_ui_scaling_factor (MetaSettings *settings) +{ + if (update_ui_scaling_factor (settings)) + g_signal_emit (settings, signals[UI_SCALING_FACTOR_CHANGED], 0); +} + +int +meta_settings_get_ui_scaling_factor (MetaSettings *settings) +{ + g_assert (settings->ui_scaling_factor != 0); + + return settings->ui_scaling_factor; +} + +static gboolean +update_global_scaling_factor (MetaSettings *settings) +{ + int global_scaling_factor; + + global_scaling_factor = + (int) g_settings_get_uint (settings->interface_settings, + "scaling-factor"); + + if (settings->global_scaling_factor != global_scaling_factor) + { + settings->global_scaling_factor = global_scaling_factor; + return TRUE; + } + else + { + return FALSE; + } +} + +gboolean +meta_settings_get_global_scaling_factor (MetaSettings *settings, + int *out_scaling_factor) +{ + if (settings->global_scaling_factor == 0) + return FALSE; + + *out_scaling_factor = settings->global_scaling_factor; + return TRUE; +} + +static gboolean +update_font_dpi (MetaSettings *settings) +{ + double text_scaling_factor; + /* Number of logical pixels on an inch when unscaled */ + const double dots_per_inch = 96; + /* Being based on Xft, API users expect the DPI to be 1/1024th of an inch. */ + const double xft_factor = 1024; + int font_dpi; + + text_scaling_factor = g_settings_get_double (settings->interface_settings, + "text-scaling-factor"); + font_dpi = (int) (text_scaling_factor * + dots_per_inch * + xft_factor * + settings->ui_scaling_factor); + + if (font_dpi != settings->font_dpi) + { + settings->font_dpi = font_dpi; + + g_object_set (clutter_settings_get_default (), + "font-dpi", font_dpi, + NULL); + + return TRUE; + } + else + { + return FALSE; + } +} + +static void +meta_settings_update_font_dpi (MetaSettings *settings) +{ + if (update_font_dpi (settings)) + g_signal_emit (settings, signals[FONT_DPI_CHANGED], 0); +} + +int +meta_settings_get_font_dpi (MetaSettings *settings) +{ + g_assert (settings->font_dpi != 0); + + return settings->font_dpi; +} + +static void +interface_settings_changed (GSettings *interface_settings, + const char *key, + MetaSettings *settings) +{ + if (g_str_equal (key, "scaling-factor")) + { + if (update_global_scaling_factor (settings)) + g_signal_emit (settings, signals[GLOBAL_SCALING_FACTOR_CHANGED], 0); + } + else if (g_str_equal (key, "text-scaling-factor")) + { + meta_settings_update_font_dpi (settings); + } +} + +gboolean +meta_settings_is_experimental_feature_enabled (MetaSettings *settings, + MetaExperimentalFeature feature) +{ + return !!(settings->experimental_features & feature); +} + +void +meta_settings_override_experimental_features (MetaSettings *settings) +{ + settings->experimental_features = META_EXPERIMENTAL_FEATURE_NONE; + settings->experimental_features_overridden = TRUE; +} + +static gboolean +update_x11_scale_mode (MetaSettings *settings) +{ + MetaX11ScaleMode scale_mode; + + if (!(settings->experimental_features & + META_EXPERIMENTAL_FEATURE_X11_RANDR_FRACTIONAL_SCALING)) + { + scale_mode = META_X11_SCALE_MODE_NONE; + } + else + { + scale_mode = + g_settings_get_enum (settings->x11_settings, "fractional-scale-mode"); + } + + if (settings->x11_scale_mode != scale_mode) + { + settings->x11_scale_mode = scale_mode; + return TRUE; + } + + return FALSE; +} + +void meta_settings_enable_x11_fractional_scaling (MetaSettings *settings, + gboolean enable) +{ + g_auto(GStrv) existing_features = NULL; + gboolean have_fractional_scaling = FALSE; + g_autoptr(GVariantBuilder) builder = NULL; + MetaExperimentalFeature old_experimental_features; + + if (enable == meta_settings_is_experimental_feature_enabled (settings, + META_EXPERIMENTAL_FEATURE_X11_RANDR_FRACTIONAL_SCALING)) + return; + + /* Change the internal value now, as we don't want to wait for gsettings */ + old_experimental_features = settings->experimental_features; + settings->experimental_features |= + META_EXPERIMENTAL_FEATURE_X11_RANDR_FRACTIONAL_SCALING; + + update_x11_scale_mode (settings); + + g_signal_emit (settings, signals[EXPERIMENTAL_FEATURES_CHANGED], 0, + (unsigned int) old_experimental_features); + + /* Add or remove the fractional scaling feature from mutter */ + existing_features = g_settings_get_strv (settings->mutter_settings, + "experimental-features"); + builder = g_variant_builder_new (G_VARIANT_TYPE ("as")); + for (int i = 0; existing_features[i] != NULL; i++) + { + if (g_strcmp0 (existing_features[i], "x11-randr-fractional-scaling") == 0) + { + if (enable) + have_fractional_scaling = TRUE; + else + continue; + } + + g_variant_builder_add (builder, "s", existing_features[i]); + } + if (enable && !have_fractional_scaling) + g_variant_builder_add (builder, "s", "x11-randr-fractional-scaling"); + + g_settings_set_value (settings->mutter_settings, "experimental-features", + g_variant_builder_end (builder)); +} + +void +meta_settings_enable_experimental_feature (MetaSettings *settings, + MetaExperimentalFeature feature) +{ + g_assert (settings->experimental_features_overridden); + + settings->experimental_features |= feature; + + if (update_x11_scale_mode (settings)) + g_signal_emit (settings, signals[X11_SCALE_MODE_CHANGED], 0, NULL); +} + +static gboolean +experimental_features_handler (GVariant *features_variant, + gpointer *result, + gpointer data) +{ + MetaSettings *settings = data; + GVariantIter features_iter; + char *feature_str; + MetaExperimentalFeature features = META_EXPERIMENTAL_FEATURE_NONE; + + if (settings->experimental_features_overridden) + { + *result = GINT_TO_POINTER (FALSE); + return TRUE; + } + + g_variant_iter_init (&features_iter, features_variant); + while (g_variant_iter_loop (&features_iter, "s", &feature_str)) + { + MetaExperimentalFeature feature = META_EXPERIMENTAL_FEATURE_NONE; + + if (g_str_equal (feature_str, "scale-monitor-framebuffer")) + feature = META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER; + else if (g_str_equal (feature_str, "kms-modifiers")) + feature = META_EXPERIMENTAL_FEATURE_KMS_MODIFIERS; + else if (g_str_equal (feature_str, "rt-scheduler")) + feature = META_EXPERIMENTAL_FEATURE_RT_SCHEDULER; + else if (g_str_equal (feature_str, "autostart-xwayland")) + feature = META_EXPERIMENTAL_FEATURE_AUTOSTART_XWAYLAND; + else if (g_str_equal (feature_str, "x11-randr-fractional-scaling")) + feature = META_EXPERIMENTAL_FEATURE_X11_RANDR_FRACTIONAL_SCALING; + + if (feature) + g_message ("Enabling experimental feature '%s'", feature_str); + else + g_warning ("Unknown experimental feature '%s'", feature_str); + + features |= feature; + } + + if (features != settings->experimental_features) + { + settings->experimental_features = features; + update_x11_scale_mode (settings); + *result = GINT_TO_POINTER (TRUE); + } + else + { + *result = GINT_TO_POINTER (FALSE); + } + + return TRUE; +} + +static gboolean +update_experimental_features (MetaSettings *settings) +{ + return GPOINTER_TO_INT (g_settings_get_mapped (settings->mutter_settings, + "experimental-features", + experimental_features_handler, + settings)); +} + +static void +mutter_settings_changed (GSettings *mutter_settings, + gchar *key, + MetaSettings *settings) +{ + MetaExperimentalFeature old_experimental_features; + + if (!g_str_equal (key, "experimental-features")) + return; + + old_experimental_features = settings->experimental_features; + if (update_experimental_features (settings)) + g_signal_emit (settings, signals[EXPERIMENTAL_FEATURES_CHANGED], 0, + (unsigned int) old_experimental_features); +} + +static void +xwayland_grab_list_add_item (MetaSettings *settings, + char *item) +{ + /* If first character is '!', it's a blacklisted item */ + if (item[0] != '!') + g_ptr_array_add (settings->xwayland_grab_whitelist_patterns, + g_pattern_spec_new (item)); + else if (item[1] != 0) + g_ptr_array_add (settings->xwayland_grab_blacklist_patterns, + g_pattern_spec_new (&item[1])); +} + +static gboolean +xwayland_grab_access_rules_handler (GVariant *variant, + gpointer *result, + gpointer data) +{ + MetaSettings *settings = data; + GVariantIter iter; + char *item; + + /* Create a GPatternSpec for each element */ + g_variant_iter_init (&iter, variant); + while (g_variant_iter_loop (&iter, "s", &item)) + xwayland_grab_list_add_item (settings, item); + + *result = GINT_TO_POINTER (TRUE); + + return TRUE; +} + +static void +update_xwayland_grab_access_rules (MetaSettings *settings) +{ + gchar **system_defaults; + int i; + + /* Free previous patterns and create new arrays */ + g_clear_pointer (&settings->xwayland_grab_whitelist_patterns, + g_ptr_array_unref); + settings->xwayland_grab_whitelist_patterns = + g_ptr_array_new_with_free_func ((GDestroyNotify) g_pattern_spec_free); + + g_clear_pointer (&settings->xwayland_grab_blacklist_patterns, + g_ptr_array_unref); + settings->xwayland_grab_blacklist_patterns = + g_ptr_array_new_with_free_func ((GDestroyNotify) g_pattern_spec_free); + + /* Add system defaults values */ + system_defaults = g_strsplit (XWAYLAND_GRAB_DEFAULT_ACCESS_RULES, ",", -1); + for (i = 0; system_defaults[i]; i++) + xwayland_grab_list_add_item (settings, system_defaults[i]); + g_strfreev (system_defaults); + + /* Then add gsettings values */ + g_settings_get_mapped (settings->wayland_settings, + "xwayland-grab-access-rules", + xwayland_grab_access_rules_handler, + settings); +} + +static void +update_xwayland_allow_grabs (MetaSettings *settings) +{ + settings->xwayland_allow_grabs = + g_settings_get_boolean (settings->wayland_settings, + "xwayland-allow-grabs"); +} + +static void +wayland_settings_changed (GSettings *wayland_settings, + gchar *key, + MetaSettings *settings) +{ + + if (g_str_equal (key, "xwayland-allow-grabs")) + { + update_xwayland_allow_grabs (settings); + } + else if (g_str_equal (key, "xwayland-grab-access-rules")) + { + update_xwayland_grab_access_rules (settings); + } +} + +static void +x11_settings_changed (GSettings *wayland_settings, + gchar *key, + MetaSettings *settings) +{ + if (g_str_equal (key, "fractional-scale-mode")) + { + if (update_x11_scale_mode (settings)) + g_signal_emit (settings, signals[X11_SCALE_MODE_CHANGED], 0, NULL); + } +} + +void +meta_settings_get_xwayland_grab_patterns (MetaSettings *settings, + GPtrArray **whitelist_patterns, + GPtrArray **blacklist_patterns) +{ + *whitelist_patterns = settings->xwayland_grab_whitelist_patterns; + *blacklist_patterns = settings->xwayland_grab_blacklist_patterns; +} + +gboolean +meta_settings_are_xwayland_grabs_allowed (MetaSettings *settings) +{ + return (settings->xwayland_allow_grabs); +} + +MetaX11ScaleMode +meta_settings_get_x11_scale_mode (MetaSettings *settings) +{ + return settings->x11_scale_mode; +} + +MetaSettings * +meta_settings_new (MetaBackend *backend) +{ + MetaSettings *settings; + + settings = g_object_new (META_TYPE_SETTINGS, NULL); + settings->backend = backend; + + return settings; +} + +static void +meta_settings_dispose (GObject *object) +{ + MetaSettings *settings = META_SETTINGS (object); + + g_clear_object (&settings->mutter_settings); + g_clear_object (&settings->interface_settings); + g_clear_object (&settings->wayland_settings); + g_clear_object (&settings->x11_settings); + g_clear_pointer (&settings->xwayland_grab_whitelist_patterns, + g_ptr_array_unref); + g_clear_pointer (&settings->xwayland_grab_blacklist_patterns, + g_ptr_array_unref); + + G_OBJECT_CLASS (meta_settings_parent_class)->dispose (object); +} + +static void +meta_settings_init (MetaSettings *settings) +{ + settings->interface_settings = g_settings_new ("org.cinnamon.desktop.interface"); + g_signal_connect (settings->interface_settings, "changed", + G_CALLBACK (interface_settings_changed), + settings); + settings->mutter_settings = g_settings_new ("org.cinnamon.muffin"); + g_signal_connect (settings->mutter_settings, "changed", + G_CALLBACK (mutter_settings_changed), + settings); + settings->wayland_settings = g_settings_new ("org.cinnamon.muffin.wayland"); + g_signal_connect (settings->wayland_settings, "changed", + G_CALLBACK (wayland_settings_changed), + settings); + settings->x11_settings = g_settings_new ("org.cinnamon.muffin.x11"); + g_signal_connect (settings->x11_settings, "changed", + G_CALLBACK (x11_settings_changed), + settings); + + /* Chain up inter-dependent settings. */ + g_signal_connect (settings, "global-scaling-factor-changed", + G_CALLBACK (meta_settings_update_ui_scaling_factor), NULL); + g_signal_connect (settings, "ui-scaling-factor-changed", + G_CALLBACK (meta_settings_update_font_dpi), NULL); + + update_global_scaling_factor (settings); + update_experimental_features (settings); + update_xwayland_grab_access_rules (settings); + update_xwayland_allow_grabs (settings); +} + +static void +on_monitors_changed (MetaMonitorManager *monitor_manager, + MetaSettings *settings) +{ + meta_settings_update_ui_scaling_factor (settings); +} + +void +meta_settings_post_init (MetaSettings *settings) +{ + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (settings->backend); + + update_ui_scaling_factor (settings); + update_font_dpi (settings); + + g_signal_connect_object (monitor_manager, "monitors-changed-internal", + G_CALLBACK (on_monitors_changed), + settings, G_CONNECT_AFTER); +} + +static void +meta_settings_class_init (MetaSettingsClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = meta_settings_dispose; + + signals[UI_SCALING_FACTOR_CHANGED] = + g_signal_new ("ui-scaling-factor-changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); + + signals[GLOBAL_SCALING_FACTOR_CHANGED] = + g_signal_new ("global-scaling-factor-changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); + + signals[FONT_DPI_CHANGED] = + g_signal_new ("font-dpi-changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); + + signals[X11_SCALE_MODE_CHANGED] = + g_signal_new ("x11-scale-mode-changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); + + signals[EXPERIMENTAL_FEATURES_CHANGED] = + g_signal_new ("experimental-features-changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 1, G_TYPE_UINT); +} diff --git a/src/backends/meta-stage-private.h b/src/backends/meta-stage-private.h new file mode 100644 index 000000000..6a264637c --- /dev/null +++ b/src/backends/meta-stage-private.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2012 Intel Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_STAGE_PRIVATE_H +#define META_STAGE_PRIVATE_H + +#include "backends/meta-cursor.h" +#include "meta/boxes.h" +#include "meta/meta-stage.h" +#include "meta/types.h" + +G_BEGIN_DECLS + +typedef struct _MetaStageWatch MetaStageWatch; +typedef struct _MetaOverlay MetaOverlay; + +typedef enum +{ + META_STAGE_WATCH_BEFORE_PAINT, + META_STAGE_WATCH_AFTER_ACTOR_PAINT, + META_STAGE_WATCH_AFTER_OVERLAY_PAINT, + META_STAGE_WATCH_AFTER_PAINT, +} MetaStageWatchPhase; + +typedef void (* MetaStageWatchFunc) (MetaStage *stage, + ClutterStageView *view, + ClutterPaintContext *paint_context, + gpointer user_data); + +ClutterActor *meta_stage_new (MetaBackend *backend); + +MetaOverlay *meta_stage_create_cursor_overlay (MetaStage *stage); +void meta_stage_remove_cursor_overlay (MetaStage *stage, + MetaOverlay *overlay); + +void meta_stage_update_cursor_overlay (MetaStage *stage, + MetaOverlay *overlay, + CoglTexture *texture, + graphene_rect_t *rect); + +void meta_stage_set_active (MetaStage *stage, + gboolean is_active); + +MetaStageWatch * meta_stage_watch_view (MetaStage *stage, + ClutterStageView *view, + MetaStageWatchPhase watch_mode, + MetaStageWatchFunc callback, + gpointer user_data); + +void meta_stage_remove_watch (MetaStage *stage, + MetaStageWatch *watch); + +G_END_DECLS + +#endif /* META_STAGE_PRIVATE_H */ diff --git a/src/backends/meta-stage.c b/src/backends/meta-stage.c new file mode 100644 index 000000000..1487d5f5c --- /dev/null +++ b/src/backends/meta-stage.c @@ -0,0 +1,473 @@ +/* + * Copyright (C) 2014 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jasper St. Pierre <jstpierre@mecheye.net> + */ + +#include "config.h" + +#include "backends/meta-stage-private.h" + +#include "backends/meta-backend-private.h" +#include "clutter/clutter-mutter.h" +#include "meta/meta-backend.h" +#include "meta/meta-monitor-manager.h" +#include "meta/util.h" + +#define N_WATCH_MODES 4 + +enum +{ + ACTORS_PAINTED, + + N_SIGNALS +}; + +static guint signals[N_SIGNALS]; + +struct _MetaStageWatch +{ + ClutterStageView *view; + MetaStageWatchFunc callback; + gpointer user_data; +}; + +struct _MetaOverlay +{ + gboolean enabled; + + CoglPipeline *pipeline; + CoglTexture *texture; + + graphene_rect_t current_rect; + graphene_rect_t previous_rect; + gboolean previous_is_valid; +}; + +struct _MetaStage +{ + ClutterStage parent; + + GPtrArray *watchers[N_WATCH_MODES]; + + GList *overlays; + gboolean is_active; +}; + +G_DEFINE_TYPE (MetaStage, meta_stage, CLUTTER_TYPE_STAGE); + +static MetaOverlay * +meta_overlay_new (void) +{ + MetaOverlay *overlay; + CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); + + overlay = g_slice_new0 (MetaOverlay); + overlay->pipeline = cogl_pipeline_new (ctx); + + return overlay; +} + +static void +meta_overlay_free (MetaOverlay *overlay) +{ + if (overlay->pipeline) + cogl_object_unref (overlay->pipeline); + + g_slice_free (MetaOverlay, overlay); +} + +static void +meta_overlay_set (MetaOverlay *overlay, + CoglTexture *texture, + graphene_rect_t *rect) +{ + if (overlay->texture != texture) + { + overlay->texture = texture; + + if (texture) + { + cogl_pipeline_set_layer_texture (overlay->pipeline, 0, texture); + overlay->enabled = TRUE; + } + else + { + cogl_pipeline_set_layer_texture (overlay->pipeline, 0, NULL); + overlay->enabled = FALSE; + } + } + + overlay->current_rect = *rect; +} + +static void +meta_overlay_paint (MetaOverlay *overlay, + ClutterPaintContext *paint_context) +{ + CoglFramebuffer *framebuffer; + + if (!overlay->enabled) + return; + + g_assert (meta_is_wayland_compositor ()); + + framebuffer = clutter_paint_context_get_framebuffer (paint_context); + cogl_framebuffer_draw_rectangle (framebuffer, + overlay->pipeline, + overlay->current_rect.origin.x, + overlay->current_rect.origin.y, + (overlay->current_rect.origin.x + + overlay->current_rect.size.width), + (overlay->current_rect.origin.y + + overlay->current_rect.size.height)); + + if (!graphene_rect_equal (&overlay->previous_rect, &overlay->current_rect)) + { + overlay->previous_rect = overlay->current_rect; + overlay->previous_is_valid = TRUE; + } +} + +static void +meta_stage_finalize (GObject *object) +{ + MetaStage *stage = META_STAGE (object); + GList *l; + int i; + + l = stage->overlays; + while (l) + { + meta_overlay_free (l->data); + l = g_list_delete_link (l, l); + } + + for (i = 0; i < N_WATCH_MODES; i++) + g_clear_pointer (&stage->watchers[i], g_ptr_array_unref); + + G_OBJECT_CLASS (meta_stage_parent_class)->finalize (object); +} + +static void +notify_watchers_for_mode (MetaStage *stage, + ClutterStageView *view, + ClutterPaintContext *paint_context, + MetaStageWatchPhase watch_phase) +{ + GPtrArray *watchers; + int i; + + watchers = stage->watchers[watch_phase]; + + for (i = 0; i < watchers->len; i++) + { + MetaStageWatch *watch = g_ptr_array_index (watchers, i); + + if (watch->view && view != watch->view) + continue; + + watch->callback (stage, view, paint_context, watch->user_data); + } +} + +static void +meta_stage_paint (ClutterActor *actor, + ClutterPaintContext *paint_context) +{ + MetaStage *stage = META_STAGE (actor); + ClutterStageView *view; + GList *l; + + CLUTTER_ACTOR_CLASS (meta_stage_parent_class)->paint (actor, paint_context); + + view = clutter_paint_context_get_stage_view (paint_context); + if (view) + { + notify_watchers_for_mode (stage, view, paint_context, + META_STAGE_WATCH_AFTER_ACTOR_PAINT); + } + + if (!(clutter_paint_context_get_paint_flags (paint_context) & + CLUTTER_PAINT_FLAG_NO_PAINT_SIGNAL)) + g_signal_emit (stage, signals[ACTORS_PAINTED], 0); + + if (!(clutter_paint_context_get_paint_flags (paint_context) & + CLUTTER_PAINT_FLAG_NO_CURSORS)) + { + for (l = stage->overlays; l; l = l->next) + meta_overlay_paint (l->data, paint_context); + } + + if (view) + { + notify_watchers_for_mode (stage, view, paint_context, + META_STAGE_WATCH_AFTER_OVERLAY_PAINT); + } +} + +static void +meta_stage_paint_view (ClutterStage *stage, + ClutterStageView *view, + const cairo_region_t *redraw_clip) +{ + MetaStage *meta_stage = META_STAGE (stage); + + notify_watchers_for_mode (meta_stage, view, NULL, + META_STAGE_WATCH_BEFORE_PAINT); + + CLUTTER_STAGE_CLASS (meta_stage_parent_class)->paint_view (stage, view, + redraw_clip); + + notify_watchers_for_mode (meta_stage, view, NULL, + META_STAGE_WATCH_AFTER_PAINT); +} + +static void +meta_stage_activate (ClutterStage *actor) +{ + MetaStage *stage = META_STAGE (actor); + + CLUTTER_STAGE_CLASS (meta_stage_parent_class)->activate (actor); + + stage->is_active = TRUE; +} + +static void +meta_stage_deactivate (ClutterStage *actor) +{ + MetaStage *stage = META_STAGE (actor); + + CLUTTER_STAGE_CLASS (meta_stage_parent_class)->deactivate (actor); + + stage->is_active = FALSE; +} + +static void +on_power_save_changed (MetaMonitorManager *monitor_manager, + MetaStage *stage) +{ + if (meta_monitor_manager_get_power_save_mode (monitor_manager) == + META_POWER_SAVE_ON) + clutter_actor_queue_redraw (CLUTTER_ACTOR (stage)); +} + +static void +meta_stage_class_init (MetaStageClass *klass) +{ + ClutterStageClass *stage_class = (ClutterStageClass *) klass; + ClutterActorClass *actor_class = (ClutterActorClass *) klass; + GObjectClass *object_class = (GObjectClass *) klass; + + object_class->finalize = meta_stage_finalize; + + actor_class->paint = meta_stage_paint; + + stage_class->activate = meta_stage_activate; + stage_class->deactivate = meta_stage_deactivate; + stage_class->paint_view = meta_stage_paint_view; + + signals[ACTORS_PAINTED] = g_signal_new ("actors-painted", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); +} + +static void +meta_stage_init (MetaStage *stage) +{ + int i; + + for (i = 0; i < N_WATCH_MODES; i++) + stage->watchers[i] = g_ptr_array_new_with_free_func (g_free); +} + +ClutterActor * +meta_stage_new (MetaBackend *backend) +{ + MetaStage *stage; + MetaMonitorManager *monitor_manager; + + stage = g_object_new (META_TYPE_STAGE, + "cursor-visible", FALSE, + NULL); + + monitor_manager = meta_backend_get_monitor_manager (backend); + g_signal_connect (monitor_manager, "power-save-mode-changed", + G_CALLBACK (on_power_save_changed), + stage); + + return CLUTTER_ACTOR (stage); +} + +static void +queue_redraw_clutter_rect (MetaStage *stage, + MetaOverlay *overlay, + graphene_rect_t *rect) +{ + cairo_rectangle_int_t clip = { + .x = floorf (rect->origin.x), + .y = floorf (rect->origin.y), + .width = ceilf (rect->size.width), + .height = ceilf (rect->size.height) + }; + + /* Since we're flooring the coordinates, we need to enlarge the clip by the + * difference between the actual coordinate and the floored value */ + clip.width += ceilf (rect->origin.x - clip.x) * 2; + clip.height += ceilf (rect->origin.y - clip.y) * 2; + + clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stage), &clip); +} + +static void +queue_redraw_for_overlay (MetaStage *stage, + MetaOverlay *overlay) +{ + /* Clear the location the overlay was at before, if we need to. */ + if (overlay->previous_is_valid) + { + queue_redraw_clutter_rect (stage, overlay, &overlay->previous_rect); + overlay->previous_is_valid = FALSE; + } + + /* Draw the overlay at the new position */ + if (overlay->enabled) + queue_redraw_clutter_rect (stage, overlay, &overlay->current_rect); +} + +MetaOverlay * +meta_stage_create_cursor_overlay (MetaStage *stage) +{ + MetaOverlay *overlay; + + overlay = meta_overlay_new (); + stage->overlays = g_list_prepend (stage->overlays, overlay); + + return overlay; +} + +void +meta_stage_remove_cursor_overlay (MetaStage *stage, + MetaOverlay *overlay) +{ + GList *link; + + link = g_list_find (stage->overlays, overlay); + if (!link) + return; + + stage->overlays = g_list_delete_link (stage->overlays, link); + meta_overlay_free (overlay); +} + +void +meta_stage_update_cursor_overlay (MetaStage *stage, + MetaOverlay *overlay, + CoglTexture *texture, + graphene_rect_t *rect) +{ + g_assert (meta_is_wayland_compositor () || texture == NULL); + + meta_overlay_set (overlay, texture, rect); + queue_redraw_for_overlay (stage, overlay); +} + +void +meta_stage_set_active (MetaStage *stage, + gboolean is_active) +{ + ClutterEvent *event; + + /* Used by the native backend to inform accessibility technologies + * about when the stage loses and gains input focus. + * + * For the X11 backend, clutter transparently takes care of this + * for us. + */ + + if (stage->is_active == is_active) + return; + + event = clutter_event_new (CLUTTER_STAGE_STATE); + clutter_event_set_stage (event, CLUTTER_STAGE (stage)); + event->stage_state.changed_mask = CLUTTER_STAGE_STATE_ACTIVATED; + + if (is_active) + event->stage_state.new_state = CLUTTER_STAGE_STATE_ACTIVATED; + + /* Emitting this StageState event will result in the stage getting + * activated or deactivated (with the activated or deactivated signal + * getting emitted from the stage) + * + * FIXME: This won't update ClutterStage's own notion of its + * activeness. For that we would need to somehow trigger a + * _clutter_stage_update_state call, which will probably + * require new API in clutter. In practice, nothing relies + * on the ClutterStage's own notion of activeness when using + * the EGL backend. + * + * See http://bugzilla.gnome.org/746670 + */ + clutter_stage_event (CLUTTER_STAGE (stage), event); + clutter_event_free (event); +} + +MetaStageWatch * +meta_stage_watch_view (MetaStage *stage, + ClutterStageView *view, + MetaStageWatchPhase watch_phase, + MetaStageWatchFunc callback, + gpointer user_data) +{ + MetaStageWatch *watch; + GPtrArray *watchers; + + watch = g_new0 (MetaStageWatch, 1); + watch->view = view; + watch->callback = callback; + watch->user_data = user_data; + + watchers = stage->watchers[watch_phase]; + g_ptr_array_add (watchers, watch); + + return watch; +} + +void +meta_stage_remove_watch (MetaStage *stage, + MetaStageWatch *watch) +{ + GPtrArray *watchers; + gboolean removed = FALSE; + int i; + + for (i = 0; i < N_WATCH_MODES; i++) + { + watchers = stage->watchers[i]; + removed = g_ptr_array_remove_fast (watchers, watch); + + if (removed) + break; + } + + g_assert (removed); +} diff --git a/src/backends/native/dbus-utils.c b/src/backends/native/dbus-utils.c new file mode 100644 index 000000000..79fafe881 --- /dev/null +++ b/src/backends/native/dbus-utils.c @@ -0,0 +1,107 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jasper St. Pierre <jstpierre@mecheye.net> + */ + +#include "config.h" + +#include "backends/native/dbus-utils.h" + +#include <glib.h> + +/* Stolen from tp_escape_as_identifier, from tp-glib, + * which follows the same escaping convention as systemd. + */ +static inline gboolean +_esc_ident_bad (gchar c, gboolean is_first) +{ + return ((c < 'a' || c > 'z') && + (c < 'A' || c > 'Z') && + (c < '0' || c > '9' || is_first)); +} + +static gchar * +escape_dbus_component (const gchar *name) +{ + gboolean bad = FALSE; + size_t len = 0; + GString *op; + const gchar *ptr, *first_ok; + + g_return_val_if_fail (name != NULL, NULL); + + /* fast path for empty name */ + if (name[0] == '\0') + return g_strdup ("_"); + + for (ptr = name; *ptr; ptr++) + { + if (_esc_ident_bad (*ptr, ptr == name)) + { + bad = TRUE; + len += 3; + } + else + len++; + } + + /* fast path if it's clean */ + if (!bad) + return g_strdup (name); + + /* If strictly less than ptr, first_ok is the first uncopied safe character. + */ + first_ok = name; + op = g_string_sized_new (len); + for (ptr = name; *ptr; ptr++) + { + if (_esc_ident_bad (*ptr, ptr == name)) + { + /* copy preceding safe characters if any */ + if (first_ok < ptr) + { + g_string_append_len (op, first_ok, ptr - first_ok); + } + /* escape the unsafe character */ + g_string_append_printf (op, "_%02x", (unsigned char)(*ptr)); + /* restart after it */ + first_ok = ptr + 1; + } + } + /* copy trailing safe characters if any */ + if (first_ok < ptr) + { + g_string_append_len (op, first_ok, ptr - first_ok); + } + return g_string_free (op, FALSE); +} + +char * +get_escaped_dbus_path (const char *prefix, + const char *component) +{ + char *escaped_component = escape_dbus_component (component); + char *path = g_strconcat (prefix, "/", escaped_component, NULL); + + g_free (escaped_component); + return path; +} diff --git a/src/backends/native/dbus-utils.h b/src/backends/native/dbus-utils.h new file mode 100644 index 000000000..ee56c455a --- /dev/null +++ b/src/backends/native/dbus-utils.h @@ -0,0 +1,32 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jasper St. Pierre <jstpierre@mecheye.net> + */ + +#ifndef DBUS_UTILS_H +#define DBUS_UTILS_H + +char * +get_escaped_dbus_path (const char *prefix, + const char *component); + +#endif /* DBUS_UTILS_H */ diff --git a/src/backends/native/gen-default-modes.py b/src/backends/native/gen-default-modes.py new file mode 100755 index 000000000..fed514d45 --- /dev/null +++ b/src/backends/native/gen-default-modes.py @@ -0,0 +1,127 @@ +#!/usr/bin/env python3 + +# Copyright (C) 2016 Red Hat Inc. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +import os +import sys + +if len(sys.argv) != 2: + print("Usage: %s [output file]"%sys.argv[0]) + exit(1) + +common_resolutions = [ + # 4:3 + (800, 600), + (1024, 768), + (1152, 864), + (1280, 960), + (1400, 1050), + (1440, 1080), + (1600, 1200), + (1920, 1440), + (2048, 1536), + # 16:10 + (1280, 800), + (1440, 900), + (1680, 1050), + (1920, 1200), + (2560, 1600), + # 16:9 + (1280, 720), + (1366, 768), + (1600, 900), + (1920, 1080), + (2048, 1152), + (2560, 1440), + (2880, 1620), + (3200, 1800), + (3840, 2160), + (4096, 2304), + (5120, 2880), +] + +output_lines = [ + "/* Generated by gen-default-modes.py */\n", + "static const drmModeModeInfo meta_default_landscape_drm_mode_infos[] = {", +] + +def sync_flags(hsync, vsync): + flags = "DRM_MODE_FLAG_" + flags += "NHSYNC" if hsync[0] == '-' else "PHSYNC" + flags += " | DRM_MODE_FLAG_" + flags += "NVSYNC" if vsync[0] == '-' else "PVSYNC" + return flags + +def drm_mode_info_from_modeline(line): + sline = line.split() + return "{ %d, %d, %d, %d, %d, 0, %d, %d, %d, %d, 0, 0, %s, DRM_MODE_TYPE_DEFAULT, %s }," % \ + (int(float(sline[2]) * 1000), + int(sline[3]), + int(sline[4]), + int(sline[5]), + int(sline[6]), + int(sline[7]), + int(sline[8]), + int(sline[9]), + int(sline[10]), + sync_flags(sline[11], sline[12]), + sline[1]) + +def portrait_drm_mode_info_from_modeline(line): + sline = line.split() + return "{ %d, %d, %d, %d, %d, 0, %d, %d, %d, %d, 0, 0, %s, DRM_MODE_TYPE_DEFAULT, \"%dx%d_60.00\" }," % \ + (int(float(sline[2]) * 1000), + int(sline[7]), + int(sline[8]), + int(sline[9]), + int(sline[10]), + int(sline[3]), + int(sline[4]), + int(sline[5]), + int(sline[6]), + sync_flags(sline[12], sline[11]), + int(sline[7]), int(sline[3])) + +for resolution in common_resolutions: + cvt = os.popen("%s %s %s" % ('cvt', resolution[0], resolution[1])) + cvt.readline() # discard comment line + line = cvt.readline() + output_lines.append(drm_mode_info_from_modeline(line)) + cvt.close() +output_lines.append("};") + +output_lines.append("") +output_lines.append("static const drmModeModeInfo meta_default_portrait_drm_mode_infos[] = {") +for resolution in common_resolutions: + cvt = os.popen("%s %s %s" % ('cvt', resolution[0], resolution[1])) + cvt.readline() # discard comment line + line = cvt.readline() + output_lines.append(portrait_drm_mode_info_from_modeline(line)) + cvt.close() +output_lines.append("};") + +try: + output_file = open(sys.argv[1], 'w') + + for line in output_lines: + output_file.write(line + "\n") + output_file.flush() + output_file.close() +except: + print("Failed to generate modelines:", sys.exc_info()[0]) + exit(1) diff --git a/src/backends/native/meta-backend-native-private.h b/src/backends/native/meta-backend-native-private.h new file mode 100644 index 000000000..04583259e --- /dev/null +++ b/src/backends/native/meta-backend-native-private.h @@ -0,0 +1,32 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2015 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +#ifndef META_BACKEND_NATIVE_PRIVATE_H +#define META_BACKEND_NATIVE_PRIVATE_H + +#include "backends/native/meta-barrier-native.h" + +MetaBarrierManagerNative *meta_backend_native_get_barrier_manager (MetaBackendNative *native); + +#endif /* META_BACKEND_NATIVE_PRIVATE_H */ diff --git a/src/backends/native/meta-backend-native-types.h b/src/backends/native/meta-backend-native-types.h new file mode 100644 index 000000000..3112e915d --- /dev/null +++ b/src/backends/native/meta-backend-native-types.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2019 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#ifndef META_BACKEND_NATIVE_TYPES_H +#define META_BACKEND_NATIVE_TYPES_H + +typedef struct _MetaBackendNative MetaBackendNative; + +#endif /* META_BACKEND_NATIVE_TYPES_H */ diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c new file mode 100644 index 000000000..e5a16f337 --- /dev/null +++ b/src/backends/native/meta-backend-native.c @@ -0,0 +1,831 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jasper St. Pierre <jstpierre@mecheye.net> + */ + +/** + * SECTION:meta-backend-native + * @title: MetaBackendNative + * @short_description: A native (KMS/evdev) MetaBackend + * + * MetaBackendNative is an implementation of #MetaBackend that uses "native" + * technologies like DRM/KMS and libinput/evdev to perform the necessary + * functions. + */ + +#include "config.h" + +#include "backends/native/meta-backend-native.h" +#include "backends/native/meta-backend-native-private.h" + +#include <sched.h> +#include <stdlib.h> + +#include "backends/meta-cursor-tracker-private.h" +#include "backends/meta-idle-monitor-private.h" +#include "backends/meta-logical-monitor.h" +#include "backends/meta-monitor-manager-private.h" +#include "backends/meta-pointer-constraint.h" +#include "backends/meta-settings-private.h" +#include "backends/meta-stage-private.h" +#include "backends/native/meta-barrier-native.h" +#include "backends/native/meta-clutter-backend-native.h" +#include "backends/native/meta-cursor-renderer-native.h" +#include "backends/native/meta-event-native.h" +#include "backends/native/meta-input-settings-native.h" +#include "backends/native/meta-kms.h" +#include "backends/native/meta-kms-device.h" +#include "backends/native/meta-launcher.h" +#include "backends/native/meta-monitor-manager-kms.h" +#include "backends/native/meta-renderer-native.h" +#include "backends/native/meta-seat-native.h" +#include "backends/native/meta-stage-native.h" +#include "cogl/cogl.h" +#include "core/meta-border.h" +#include "meta/main.h" + +struct _MetaBackendNative +{ + MetaBackend parent; + + MetaLauncher *launcher; + MetaUdev *udev; + MetaKms *kms; + MetaBarrierManagerNative *barrier_manager; + + gulong udev_device_added_handler_id; +}; + +static GInitableIface *initable_parent_iface; + +static void +initable_iface_init (GInitableIface *initable_iface); + +G_DEFINE_TYPE_WITH_CODE (MetaBackendNative, meta_backend_native, META_TYPE_BACKEND, + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + initable_iface_init)) + +static void +disconnect_udev_device_added_handler (MetaBackendNative *native); + +static void +meta_backend_native_finalize (GObject *object) +{ + MetaBackendNative *native = META_BACKEND_NATIVE (object); + + if (native->udev_device_added_handler_id) + disconnect_udev_device_added_handler (native); + + g_clear_object (&native->udev); + g_clear_object (&native->kms); + meta_launcher_free (native->launcher); + + G_OBJECT_CLASS (meta_backend_native_parent_class)->finalize (object); +} + +static void +constrain_to_barriers (ClutterInputDevice *device, + guint32 time, + float *new_x, + float *new_y) +{ + MetaBackendNative *native = META_BACKEND_NATIVE (meta_get_backend ()); + + meta_barrier_manager_native_process (native->barrier_manager, + device, + time, + new_x, new_y); +} + +static void +constrain_to_client_constraint (ClutterInputDevice *device, + guint32 time, + float prev_x, + float prev_y, + float *x, + float *y) +{ + MetaBackend *backend = meta_get_backend (); + MetaPointerConstraint *constraint = + meta_backend_get_client_pointer_constraint (backend); + + if (!constraint) + return; + + meta_pointer_constraint_constrain (constraint, device, + time, prev_x, prev_y, x, y); +} + +/* + * The pointer constrain code is mostly a rip-off of the XRandR code from Xorg. + * (from xserver/randr/rrcrtc.c, RRConstrainCursorHarder) + * + * Copyright © 2006 Keith Packard + * Copyright 2010 Red Hat, Inc + * + */ + +static void +constrain_all_screen_monitors (ClutterInputDevice *device, + MetaMonitorManager *monitor_manager, + float *x, + float *y) +{ + graphene_point_t current; + float cx, cy; + GList *logical_monitors, *l; + + clutter_input_device_get_coords (device, NULL, ¤t); + + cx = current.x; + cy = current.y; + + /* if we're trying to escape, clamp to the CRTC we're coming from */ + + logical_monitors = + meta_monitor_manager_get_logical_monitors (monitor_manager); + for (l = logical_monitors; l; l = l->next) + { + MetaLogicalMonitor *logical_monitor = l->data; + int left, right, top, bottom; + + left = logical_monitor->rect.x; + right = left + logical_monitor->rect.width; + top = logical_monitor->rect.y; + bottom = top + logical_monitor->rect.height; + + if ((cx >= left) && (cx < right) && (cy >= top) && (cy < bottom)) + { + if (*x < left) + *x = left; + if (*x >= right) + *x = right - 1; + if (*y < top) + *y = top; + if (*y >= bottom) + *y = bottom - 1; + + return; + } + } +} + +static void +pointer_constrain_callback (ClutterInputDevice *device, + guint32 time, + float prev_x, + float prev_y, + float *new_x, + float *new_y, + gpointer user_data) +{ + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + + /* Constrain to barriers */ + constrain_to_barriers (device, time, new_x, new_y); + + /* Constrain to pointer lock */ + constrain_to_client_constraint (device, time, prev_x, prev_y, new_x, new_y); + + /* if we're moving inside a monitor, we're fine */ + if (meta_monitor_manager_get_logical_monitor_at (monitor_manager, + *new_x, *new_y)) + return; + + /* if we're trying to escape, clamp to the CRTC we're coming from */ + constrain_all_screen_monitors (device, monitor_manager, new_x, new_y); +} + +static void +relative_motion_across_outputs (MetaMonitorManager *monitor_manager, + MetaLogicalMonitor *current, + float cur_x, + float cur_y, + float *dx_inout, + float *dy_inout) +{ + MetaLogicalMonitor *cur = current; + float x = cur_x, y = cur_y; + float target_x = cur_x, target_y = cur_y; + float dx = *dx_inout, dy = *dy_inout; + MetaDisplayDirection direction = -1; + + while (cur) + { + MetaLine2 left, right, top, bottom, motion; + MetaVector2 intersection; + + motion = (MetaLine2) { + .a = { x, y }, + .b = { x + (dx * cur->scale), y + (dy * cur->scale) } + }; + left = (MetaLine2) { + { cur->rect.x, cur->rect.y }, + { cur->rect.x, cur->rect.y + cur->rect.height } + }; + right = (MetaLine2) { + { cur->rect.x + cur->rect.width, cur->rect.y }, + { cur->rect.x + cur->rect.width, cur->rect.y + cur->rect.height } + }; + top = (MetaLine2) { + { cur->rect.x, cur->rect.y }, + { cur->rect.x + cur->rect.width, cur->rect.y } + }; + bottom = (MetaLine2) { + { cur->rect.x, cur->rect.y + cur->rect.height }, + { cur->rect.x + cur->rect.width, cur->rect.y + cur->rect.height } + }; + + target_x = motion.b.x; + target_y = motion.b.y; + + if (direction != META_DISPLAY_RIGHT && + meta_line2_intersects_with (&motion, &left, &intersection)) + direction = META_DISPLAY_LEFT; + else if (direction != META_DISPLAY_LEFT && + meta_line2_intersects_with (&motion, &right, &intersection)) + direction = META_DISPLAY_RIGHT; + else if (direction != META_DISPLAY_DOWN && + meta_line2_intersects_with (&motion, &top, &intersection)) + direction = META_DISPLAY_UP; + else if (direction != META_DISPLAY_UP && + meta_line2_intersects_with (&motion, &bottom, &intersection)) + direction = META_DISPLAY_DOWN; + else + /* We reached the dest logical monitor */ + break; + + x = intersection.x; + y = intersection.y; + dx -= intersection.x - motion.a.x; + dy -= intersection.y - motion.a.y; + + cur = meta_monitor_manager_get_logical_monitor_neighbor (monitor_manager, + cur, direction); + } + + *dx_inout = target_x - cur_x; + *dy_inout = target_y - cur_y; +} + +static void +relative_motion_filter (ClutterInputDevice *device, + float x, + float y, + float *dx, + float *dy, + gpointer user_data) +{ + MetaMonitorManager *monitor_manager = user_data; + MetaLogicalMonitor *logical_monitor, *dest_logical_monitor; + float new_dx, new_dy; + + if (meta_is_stage_views_scaled ()) + return; + + logical_monitor = meta_monitor_manager_get_logical_monitor_at (monitor_manager, + x, y); + if (!logical_monitor) + return; + + new_dx = (*dx) * logical_monitor->scale; + new_dy = (*dy) * logical_monitor->scale; + + dest_logical_monitor = meta_monitor_manager_get_logical_monitor_at (monitor_manager, + x + new_dx, + y + new_dy); + if (dest_logical_monitor && + dest_logical_monitor != logical_monitor) + { + /* If we are crossing monitors, attempt to bisect the distance on each + * axis and apply the relative scale for each of them. + */ + new_dx = *dx; + new_dy = *dy; + relative_motion_across_outputs (monitor_manager, logical_monitor, + x, y, &new_dx, &new_dy); + } + + *dx = new_dx; + *dy = new_dy; +} + +static ClutterBackend * +meta_backend_native_create_clutter_backend (MetaBackend *backend) +{ + return g_object_new (META_TYPE_CLUTTER_BACKEND_NATIVE, NULL); +} + +static void +meta_backend_native_post_init (MetaBackend *backend) +{ + ClutterBackend *clutter_backend = clutter_get_default_backend (); + ClutterSeat *seat = clutter_backend_get_default_seat (clutter_backend); + MetaSettings *settings = meta_backend_get_settings (backend); + + meta_seat_native_set_pointer_constrain_callback (META_SEAT_NATIVE (seat), + pointer_constrain_callback, + NULL, NULL); + meta_seat_native_set_relative_motion_filter (META_SEAT_NATIVE (seat), + relative_motion_filter, + meta_backend_get_monitor_manager (backend)); + + META_BACKEND_CLASS (meta_backend_native_parent_class)->post_init (backend); + + if (meta_settings_is_experimental_feature_enabled (settings, + META_EXPERIMENTAL_FEATURE_RT_SCHEDULER)) + { + int retval; + struct sched_param sp = { + .sched_priority = sched_get_priority_min (SCHED_RR) + }; + + retval = sched_setscheduler (0, SCHED_RR | SCHED_RESET_ON_FORK, &sp); + + if (retval != 0) + g_warning ("Failed to set RT scheduler: %m"); + } + +#ifdef HAVE_WAYLAND + meta_backend_init_wayland (backend); +#endif +} + +static MetaMonitorManager * +meta_backend_native_create_monitor_manager (MetaBackend *backend, + GError **error) +{ + return g_initable_new (META_TYPE_MONITOR_MANAGER_KMS, NULL, error, + "backend", backend, + NULL); +} + +static MetaCursorRenderer * +meta_backend_native_create_cursor_renderer (MetaBackend *backend) +{ + return META_CURSOR_RENDERER (meta_cursor_renderer_native_new (backend)); +} + +static MetaRenderer * +meta_backend_native_create_renderer (MetaBackend *backend, + GError **error) +{ + MetaBackendNative *native = META_BACKEND_NATIVE (backend); + MetaRendererNative *renderer_native; + + renderer_native = meta_renderer_native_new (native, error); + if (!renderer_native) + return NULL; + + return META_RENDERER (renderer_native); +} + +static MetaInputSettings * +meta_backend_native_create_input_settings (MetaBackend *backend) +{ + return g_object_new (META_TYPE_INPUT_SETTINGS_NATIVE, NULL); +} + +static MetaLogicalMonitor * +meta_backend_native_get_current_logical_monitor (MetaBackend *backend) +{ + MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + int x, y; + + meta_cursor_tracker_get_pointer (cursor_tracker, &x, &y, NULL); + return meta_monitor_manager_get_logical_monitor_at (monitor_manager, x, y); +} + +static void +meta_backend_native_set_keymap (MetaBackend *backend, + const char *layouts, + const char *variants, + const char *options) +{ + struct xkb_rule_names names; + struct xkb_keymap *keymap; + struct xkb_context *context; + ClutterSeat *seat; + + names.rules = DEFAULT_XKB_RULES_FILE; + names.model = DEFAULT_XKB_MODEL; + names.layout = layouts; + names.variant = variants; + names.options = options; + + context = xkb_context_new (XKB_CONTEXT_NO_FLAGS); + keymap = xkb_keymap_new_from_names (context, &names, XKB_KEYMAP_COMPILE_NO_FLAGS); + xkb_context_unref (context); + + seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); + meta_seat_native_set_keyboard_map (META_SEAT_NATIVE (seat), keymap); + + meta_backend_notify_keymap_changed (backend); + + xkb_keymap_unref (keymap); +} + +static struct xkb_keymap * +meta_backend_native_get_keymap (MetaBackend *backend) +{ + ClutterSeat *seat; + + seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); + return meta_seat_native_get_keyboard_map (META_SEAT_NATIVE (seat)); +} + +static xkb_layout_index_t +meta_backend_native_get_keymap_layout_group (MetaBackend *backend) +{ + ClutterSeat *seat; + + seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); + return meta_seat_native_get_keyboard_layout_index (META_SEAT_NATIVE (seat)); +} + +static void +meta_backend_native_lock_layout_group (MetaBackend *backend, + guint idx) +{ + xkb_layout_index_t old_idx; + ClutterSeat *seat; + + old_idx = meta_backend_native_get_keymap_layout_group (backend); + if (old_idx == idx) + return; + + seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); + meta_seat_native_set_keyboard_layout_index (META_SEAT_NATIVE (seat), idx); + meta_backend_notify_keymap_layout_group_changed (backend, idx); +} + +static void +meta_backend_native_set_numlock (MetaBackend *backend, + gboolean numlock_state) +{ + ClutterSeat *seat; + + seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); + meta_seat_native_set_keyboard_numlock (META_SEAT_NATIVE (seat), + numlock_state); +} + +static void +meta_backend_native_update_screen_size (MetaBackend *backend, + int width, int height) +{ + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + MetaStageNative *stage_native; + ClutterActor *stage = meta_backend_get_stage (backend); + + stage_native = meta_clutter_backend_native_get_stage_native (clutter_backend); + meta_stage_native_rebuild_views (stage_native); + + clutter_actor_set_size (stage, width, height); +} + +static MetaGpuKms * +create_gpu_from_udev_device (MetaBackendNative *native, + GUdevDevice *device, + GError **error) +{ + MetaKmsDeviceFlag flags = META_KMS_DEVICE_FLAG_NONE; + const char *device_path; + MetaKmsDevice *kms_device; + + if (meta_is_udev_device_platform_device (device)) + flags |= META_KMS_DEVICE_FLAG_PLATFORM_DEVICE; + + if (meta_is_udev_device_boot_vga (device)) + flags |= META_KMS_DEVICE_FLAG_BOOT_VGA; + + device_path = g_udev_device_get_device_file (device); + + kms_device = meta_kms_create_device (native->kms, device_path, flags, + error); + if (!kms_device) + return NULL; + + return meta_gpu_kms_new (native, kms_device, error); +} + +static void +on_udev_device_added (MetaUdev *udev, + GUdevDevice *device, + MetaBackendNative *native) +{ + MetaBackend *backend = META_BACKEND (native); + g_autoptr (GError) error = NULL; + const char *device_path; + MetaGpuKms *new_gpu_kms; + GList *gpus, *l; + + if (!meta_udev_is_drm_device (udev, device)) + return; + + device_path = g_udev_device_get_device_file (device); + + gpus = meta_backend_get_gpus (backend);; + for (l = gpus; l; l = l->next) + { + MetaGpuKms *gpu_kms = l->data; + + if (!g_strcmp0 (device_path, meta_gpu_kms_get_file_path (gpu_kms))) + { + g_warning ("Failed to hotplug secondary gpu '%s': %s", + device_path, "device already present"); + return; + } + } + + new_gpu_kms = create_gpu_from_udev_device (native, device, &error); + if (!new_gpu_kms) + { + g_warning ("Failed to hotplug secondary gpu '%s': %s", + device_path, error->message); + return; + } + + meta_backend_add_gpu (backend, META_GPU (new_gpu_kms)); +} + +static void +connect_udev_device_added_handler (MetaBackendNative *native) +{ + native->udev_device_added_handler_id = + g_signal_connect (native->udev, "device-added", + G_CALLBACK (on_udev_device_added), native); +} + +static void +disconnect_udev_device_added_handler (MetaBackendNative *native) +{ + g_clear_signal_handler (&native->udev_device_added_handler_id, native->udev); +} + +static gboolean +init_gpus (MetaBackendNative *native, + GError **error) +{ + MetaBackend *backend = META_BACKEND (native); + MetaUdev *udev = meta_backend_native_get_udev (native); + GList *devices; + GList *l; + + devices = meta_udev_list_drm_devices (udev, error); + if (!devices) + return FALSE; + + for (l = devices; l; l = l->next) + { + GUdevDevice *device = l->data; + MetaGpuKms *gpu_kms; + GError *local_error = NULL; + + gpu_kms = create_gpu_from_udev_device (native, device, &local_error); + + if (!gpu_kms) + { + g_warning ("Failed to open gpu '%s': %s", + g_udev_device_get_device_file (device), + local_error->message); + g_clear_error (&local_error); + continue; + } + + meta_backend_add_gpu (backend, META_GPU (gpu_kms)); + } + + g_list_free_full (devices, g_object_unref); + + if (g_list_length (meta_backend_get_gpus (backend)) == 0) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, + "No GPUs found"); + return FALSE; + } + + connect_udev_device_added_handler (native); + + return TRUE; +} + +static gboolean +meta_backend_native_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + MetaBackendNative *native = META_BACKEND_NATIVE (initable); + + if (!meta_is_stage_views_enabled ()) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "The native backend requires stage views"); + return FALSE; + } + + native->launcher = meta_launcher_new (error); + if (!native->launcher) + return FALSE; + +#ifdef HAVE_WAYLAND + meta_backend_init_wayland_display (META_BACKEND (native)); +#endif + + native->udev = meta_udev_new (native); + native->barrier_manager = meta_barrier_manager_native_new (); + + native->kms = meta_kms_new (META_BACKEND (native), error); + if (!native->kms) + return FALSE; + + if (!init_gpus (native, error)) + return FALSE; + + return initable_parent_iface->init (initable, cancellable, error); +} + +static void +initable_iface_init (GInitableIface *initable_iface) +{ + initable_parent_iface = g_type_interface_peek_parent (initable_iface); + + initable_iface->init = meta_backend_native_initable_init; +} + +static void +meta_backend_native_class_init (MetaBackendNativeClass *klass) +{ + MetaBackendClass *backend_class = META_BACKEND_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_backend_native_finalize; + + backend_class->create_clutter_backend = meta_backend_native_create_clutter_backend; + + backend_class->post_init = meta_backend_native_post_init; + + backend_class->create_monitor_manager = meta_backend_native_create_monitor_manager; + backend_class->create_cursor_renderer = meta_backend_native_create_cursor_renderer; + backend_class->create_renderer = meta_backend_native_create_renderer; + backend_class->create_input_settings = meta_backend_native_create_input_settings; + + backend_class->get_current_logical_monitor = meta_backend_native_get_current_logical_monitor; + + backend_class->set_keymap = meta_backend_native_set_keymap; + backend_class->get_keymap = meta_backend_native_get_keymap; + backend_class->get_keymap_layout_group = meta_backend_native_get_keymap_layout_group; + backend_class->lock_layout_group = meta_backend_native_lock_layout_group; + backend_class->update_screen_size = meta_backend_native_update_screen_size; + backend_class->set_numlock = meta_backend_native_set_numlock; +} + +static void +meta_backend_native_init (MetaBackendNative *native) +{ +} + +MetaLauncher * +meta_backend_native_get_launcher (MetaBackendNative *native) +{ + return native->launcher; +} + +MetaUdev * +meta_backend_native_get_udev (MetaBackendNative *native) +{ + return native->udev; +} + +MetaKms * +meta_backend_native_get_kms (MetaBackendNative *native) +{ + return native->kms; +} + +gboolean +meta_activate_vt (int vt, GError **error) +{ + MetaBackend *backend = meta_get_backend (); + MetaBackendNative *native = META_BACKEND_NATIVE (backend); + MetaLauncher *launcher = meta_backend_native_get_launcher (native); + + return meta_launcher_activate_vt (launcher, vt, error); +} + +MetaBarrierManagerNative * +meta_backend_native_get_barrier_manager (MetaBackendNative *native) +{ + return native->barrier_manager; +} + +/** + * meta_activate_session: + * + * Tells mutter to activate the session. When mutter is a + * display server, this tells logind to switch over to + * the new session. + */ +gboolean +meta_activate_session (void) +{ + GError *error = NULL; + MetaBackend *backend = meta_get_backend (); + + /* Do nothing. */ + if (!META_IS_BACKEND_NATIVE (backend)) + return TRUE; + + MetaBackendNative *native = META_BACKEND_NATIVE (backend); + + if (!meta_launcher_activate_session (native->launcher, &error)) + { + g_warning ("Could not activate session: %s\n", error->message); + g_error_free (error); + return FALSE; + } + + return TRUE; +} + +void +meta_backend_native_pause (MetaBackendNative *native) +{ + MetaBackend *backend = META_BACKEND (native); + ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend)); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaMonitorManagerKms *monitor_manager_kms = + META_MONITOR_MANAGER_KMS (monitor_manager); + ClutterBackend *clutter_backend = clutter_get_default_backend (); + MetaSeatNative *seat = + META_SEAT_NATIVE (clutter_backend_get_default_seat (clutter_backend)); + + COGL_TRACE_BEGIN_SCOPED (MetaBackendNativePause, + "Backend (pause)"); + + meta_seat_native_release_devices (seat); + clutter_stage_freeze_updates (stage); + + disconnect_udev_device_added_handler (native); + + meta_monitor_manager_kms_pause (monitor_manager_kms); +} + +void meta_backend_native_resume (MetaBackendNative *native) +{ + MetaBackend *backend = META_BACKEND (native); + ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend)); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaMonitorManagerKms *monitor_manager_kms = + META_MONITOR_MANAGER_KMS (monitor_manager); + MetaInputSettings *input_settings; + MetaIdleMonitor *idle_monitor; + ClutterBackend *clutter_backend = clutter_get_default_backend (); + MetaSeatNative *seat = + META_SEAT_NATIVE (clutter_backend_get_default_seat (clutter_backend)); + + COGL_TRACE_BEGIN_SCOPED (MetaBackendNativeResume, + "Backend (resume)"); + + meta_monitor_manager_kms_resume (monitor_manager_kms); + + connect_udev_device_added_handler (native); + + meta_seat_native_reclaim_devices (seat); + clutter_stage_thaw_updates (stage); + + clutter_actor_queue_redraw (CLUTTER_ACTOR (stage)); + + idle_monitor = meta_idle_monitor_get_core (); + meta_idle_monitor_reset_idletime (idle_monitor); + + input_settings = meta_backend_get_input_settings (backend); + meta_input_settings_maybe_restore_numlock_state (input_settings); + + clutter_seat_ensure_a11y_state (CLUTTER_SEAT (seat)); +} diff --git a/src/backends/native/meta-backend-native.h b/src/backends/native/meta-backend-native.h new file mode 100644 index 000000000..29a9b5c1b --- /dev/null +++ b/src/backends/native/meta-backend-native.h @@ -0,0 +1,52 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jasper St. Pierre <jstpierre@mecheye.net> + */ + +#ifndef META_BACKEND_NATIVE_H +#define META_BACKEND_NATIVE_H + +#include "backends/meta-backend-private.h" +#include "backends/native/meta-clutter-backend-native.h" +#include "backends/native/meta-kms-types.h" +#include "backends/native/meta-launcher.h" +#include "backends/native/meta-udev.h" + +#define META_TYPE_BACKEND_NATIVE (meta_backend_native_get_type ()) +G_DECLARE_FINAL_TYPE (MetaBackendNative, meta_backend_native, + META, BACKEND_NATIVE, MetaBackend) + +gboolean meta_activate_vt (int vt, GError **error); + +void meta_backend_native_pause (MetaBackendNative *backend_native); + +void meta_backend_native_resume (MetaBackendNative *backend_native); + +MetaLauncher * meta_backend_native_get_launcher (MetaBackendNative *native); + +MetaUdev * meta_backend_native_get_udev (MetaBackendNative *native); + +MetaKms * meta_backend_native_get_kms (MetaBackendNative *native); + +void meta_backend_native_set_seat_id (const gchar *seat_id); + +#endif /* META_BACKEND_NATIVE_H */ diff --git a/src/backends/native/meta-barrier-native.c b/src/backends/native/meta-barrier-native.c new file mode 100644 index 000000000..260febe8d --- /dev/null +++ b/src/backends/native/meta-barrier-native.c @@ -0,0 +1,602 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2015 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +/** + * SECTION:barrier-native + * @Title: MetaBarrierImplNative + * @Short_Description: Pointer barriers implementation for the native backend + */ + +#include "config.h" + +#include "backends/native/meta-barrier-native.h" + +#include <stdlib.h> + +#include "backends/meta-backend-private.h" +#include "backends/meta-barrier-private.h" +#include "backends/native/meta-backend-native.h" +#include "backends/native/meta-backend-native-private.h" +#include "meta/barrier.h" +#include "meta/util.h" + +struct _MetaBarrierManagerNative +{ + GHashTable *barriers; +}; + +typedef enum +{ + /* The barrier is active and responsive to pointer motion. */ + META_BARRIER_STATE_ACTIVE, + + /* An intermediate state after a pointer hit the pointer barrier. */ + META_BARRIER_STATE_HIT, + + /* The barrier was hit by a pointer and is still within the hit box and + * has not been released.*/ + META_BARRIER_STATE_HELD, + + /* The pointer was released by the user. If the following motion hits + * the barrier, it will pass through. */ + META_BARRIER_STATE_RELEASE, + + /* An intermediate state when the pointer has left the barrier. */ + META_BARRIER_STATE_LEFT, +} MetaBarrierState; + +struct _MetaBarrierImplNative +{ + MetaBarrierImpl parent; + + MetaBarrier *barrier; + MetaBarrierManagerNative *manager; + + gboolean is_active; + MetaBarrierState state; + int trigger_serial; + guint32 last_event_time; + MetaBarrierDirection blocked_dir; +}; + +G_DEFINE_TYPE (MetaBarrierImplNative, + meta_barrier_impl_native, + META_TYPE_BARRIER_IMPL) + +static int +next_serial (void) +{ + static int barrier_serial = 1; + + barrier_serial++; + + /* If it wraps, avoid 0 as it's not a valid serial. */ + if (barrier_serial == 0) + barrier_serial++; + + return barrier_serial; +} + +static gboolean +is_barrier_horizontal (MetaBarrier *barrier) +{ + return meta_border_is_horizontal (&barrier->priv->border); +} + +static gboolean +is_barrier_blocking_directions (MetaBarrier *barrier, + MetaBarrierDirection directions) +{ + return meta_border_is_blocking_directions (&barrier->priv->border, + directions); +} + +static void +dismiss_pointer (MetaBarrierImplNative *self) +{ + self->state = META_BARRIER_STATE_LEFT; +} + +/* + * Calculate the hit box for a held motion. The hit box is a 2 px wide region + * in the opposite direction of every direction the barrier blocks. The purpose + * of this is to allow small movements without receiving a "left" signal. This + * heuristic comes from the X.org pointer barrier implementation. + */ +static MetaLine2 +calculate_barrier_hit_box (MetaBarrier *barrier) +{ + MetaLine2 hit_box = barrier->priv->border.line; + + if (is_barrier_horizontal (barrier)) + { + if (is_barrier_blocking_directions (barrier, + META_BARRIER_DIRECTION_POSITIVE_Y)) + hit_box.a.y -= 2.0f; + if (is_barrier_blocking_directions (barrier, + META_BARRIER_DIRECTION_NEGATIVE_Y)) + hit_box.b.y += 2.0f; + } + else + { + if (is_barrier_blocking_directions (barrier, + META_BARRIER_DIRECTION_POSITIVE_X)) + hit_box.a.x -= 2.0f; + if (is_barrier_blocking_directions (barrier, + META_BARRIER_DIRECTION_NEGATIVE_X)) + hit_box.b.x += 2.0f; + } + + return hit_box; +} + +static gboolean +is_within_box (MetaLine2 box, + MetaVector2 point) +{ + return (point.x >= box.a.x && point.x < box.b.x && + point.y >= box.a.y && point.y < box.b.y); +} + +static void +maybe_release_barrier (gpointer key, + gpointer value, + gpointer user_data) +{ + MetaBarrierImplNative *self = key; + MetaBarrier *barrier = self->barrier; + MetaLine2 *motion = user_data; + MetaLine2 hit_box; + + if (self->state != META_BARRIER_STATE_HELD) + return; + + /* Release if we end up outside barrier end points. */ + if (is_barrier_horizontal (barrier)) + { + if (motion->b.x > MAX (barrier->priv->border.line.a.x, + barrier->priv->border.line.b.x) || + motion->b.x < MIN (barrier->priv->border.line.a.x, + barrier->priv->border.line.b.x)) + { + dismiss_pointer (self); + return; + } + } + else + { + if (motion->b.y > MAX (barrier->priv->border.line.a.y, + barrier->priv->border.line.b.y) || + motion->b.y < MIN (barrier->priv->border.line.a.y, + barrier->priv->border.line.b.y)) + { + dismiss_pointer (self); + return; + } + } + + /* Release if we don't intersect and end up outside of hit box. */ + hit_box = calculate_barrier_hit_box (barrier); + if (!is_within_box (hit_box, motion->b)) + { + dismiss_pointer (self); + return; + } +} + +static void +maybe_release_barriers (MetaBarrierManagerNative *manager, + float prev_x, + float prev_y, + float x, + float y) +{ + MetaLine2 motion = { + .a = { + .x = prev_x, + .y = prev_y, + }, + .b = { + .x = x, + .y = y, + }, + }; + + g_hash_table_foreach (manager->barriers, + maybe_release_barrier, + &motion); +} + +typedef struct _MetaClosestBarrierData +{ + struct + { + MetaLine2 motion; + MetaBarrierDirection directions; + } in; + + struct + { + float closest_distance_2; + MetaBarrierImplNative *barrier_impl; + } out; +} MetaClosestBarrierData; + +static void +update_closest_barrier (gpointer key, + gpointer value, + gpointer user_data) +{ + MetaBarrierImplNative *self = key; + MetaBarrier *barrier = self->barrier; + MetaClosestBarrierData *data = user_data; + MetaVector2 intersection; + float dx, dy; + float distance_2; + + /* Ignore if the barrier is not blocking in any of the motions directions. */ + if (!is_barrier_blocking_directions (barrier, data->in.directions)) + return; + + /* Ignore if the barrier released the pointer. */ + if (self->state == META_BARRIER_STATE_RELEASE) + return; + + /* Ignore if we are moving away from barrier. */ + if (self->state == META_BARRIER_STATE_HELD && + (data->in.directions & self->blocked_dir) == 0) + return; + + /* Check if the motion intersects with the barrier, and retrieve the + * intersection point if any. */ + if (!meta_line2_intersects_with (&barrier->priv->border.line, + &data->in.motion, + &intersection)) + return; + + /* Calculate the distance to the barrier and keep track of the closest + * barrier. */ + dx = intersection.x - data->in.motion.a.x; + dy = intersection.y - data->in.motion.a.y; + distance_2 = dx*dx + dy*dy; + if (data->out.barrier_impl == NULL || + distance_2 < data->out.closest_distance_2) + { + data->out.barrier_impl = self; + data->out.closest_distance_2 = distance_2; + } +} + +static gboolean +get_closest_barrier (MetaBarrierManagerNative *manager, + float prev_x, + float prev_y, + float x, + float y, + MetaBarrierDirection motion_dir, + MetaBarrierImplNative **barrier_impl) +{ + MetaClosestBarrierData closest_barrier_data; + + closest_barrier_data = (MetaClosestBarrierData) { + .in = { + .motion = { + .a = { + .x = prev_x, + .y = prev_y, + }, + .b = { + .x = x, + .y = y, + }, + }, + .directions = motion_dir, + }, + }; + + g_hash_table_foreach (manager->barriers, + update_closest_barrier, + &closest_barrier_data); + + if (closest_barrier_data.out.barrier_impl != NULL) + { + *barrier_impl = closest_barrier_data.out.barrier_impl; + return TRUE; + } + else + { + return FALSE; + } +} + +typedef struct _MetaBarrierEventData +{ + guint32 time; + float prev_x; + float prev_y; + float x; + float y; + float dx; + float dy; +} MetaBarrierEventData; + +static void +emit_barrier_event (MetaBarrierImplNative *self, + guint32 time, + float prev_x, + float prev_y, + float x, + float y, + float dx, + float dy) +{ + MetaBarrier *barrier = self->barrier; + MetaBarrierEvent *event = g_slice_new0 (MetaBarrierEvent); + MetaBarrierState old_state = self->state; + + switch (self->state) + { + case META_BARRIER_STATE_HIT: + self->state = META_BARRIER_STATE_HELD; + self->trigger_serial = next_serial (); + event->dt = 0; + + break; + case META_BARRIER_STATE_RELEASE: + case META_BARRIER_STATE_LEFT: + self->state = META_BARRIER_STATE_ACTIVE; + + G_GNUC_FALLTHROUGH; + case META_BARRIER_STATE_HELD: + event->dt = time - self->last_event_time; + + break; + case META_BARRIER_STATE_ACTIVE: + g_assert_not_reached (); /* Invalid state. */ + } + + event->ref_count = 1; + event->event_id = self->trigger_serial; + event->time = time; + + event->x = x; + event->y = y; + event->dx = dx; + event->dy = dy; + + event->grabbed = self->state == META_BARRIER_STATE_HELD; + event->released = old_state == META_BARRIER_STATE_RELEASE; + + self->last_event_time = time; + + if (self->state == META_BARRIER_STATE_HELD) + _meta_barrier_emit_hit_signal (barrier, event); + else + _meta_barrier_emit_left_signal (barrier, event); + + meta_barrier_event_unref (event); +} + +static void +maybe_emit_barrier_event (gpointer key, gpointer value, gpointer user_data) +{ + MetaBarrierImplNative *self = key; + MetaBarrierEventData *data = user_data; + + switch (self->state) + { + case META_BARRIER_STATE_ACTIVE: + break; + case META_BARRIER_STATE_HIT: + case META_BARRIER_STATE_HELD: + case META_BARRIER_STATE_RELEASE: + case META_BARRIER_STATE_LEFT: + emit_barrier_event (self, + data->time, + data->prev_x, + data->prev_y, + data->x, + data->y, + data->dx, + data->dy); + break; + } +} + +/* Clamp (x, y) to the barrier and remove clamped direction from motion_dir. */ +static void +clamp_to_barrier (MetaBarrierImplNative *self, + MetaBarrierDirection *motion_dir, + float *x, + float *y) +{ + MetaBarrier *barrier = self->barrier; + + if (is_barrier_horizontal (barrier)) + { + if (*motion_dir & META_BARRIER_DIRECTION_POSITIVE_Y) + *y = barrier->priv->border.line.a.y; + else if (*motion_dir & META_BARRIER_DIRECTION_NEGATIVE_Y) + *y = barrier->priv->border.line.a.y; + + self->blocked_dir = *motion_dir & (META_BARRIER_DIRECTION_POSITIVE_Y | + META_BARRIER_DIRECTION_NEGATIVE_Y); + *motion_dir &= ~(META_BARRIER_DIRECTION_POSITIVE_Y | + META_BARRIER_DIRECTION_NEGATIVE_Y); + } + else + { + if (*motion_dir & META_BARRIER_DIRECTION_POSITIVE_X) + *x = barrier->priv->border.line.a.x; + else if (*motion_dir & META_BARRIER_DIRECTION_NEGATIVE_X) + *x = barrier->priv->border.line.a.x; + + self->blocked_dir = *motion_dir & (META_BARRIER_DIRECTION_POSITIVE_X | + META_BARRIER_DIRECTION_NEGATIVE_X); + *motion_dir &= ~(META_BARRIER_DIRECTION_POSITIVE_X | + META_BARRIER_DIRECTION_NEGATIVE_X); + } + + self->state = META_BARRIER_STATE_HIT; +} + +void +meta_barrier_manager_native_process (MetaBarrierManagerNative *manager, + ClutterInputDevice *device, + guint32 time, + float *x, + float *y) +{ + graphene_point_t prev_pos; + float prev_x; + float prev_y; + float orig_x = *x; + float orig_y = *y; + MetaBarrierDirection motion_dir = 0; + MetaBarrierEventData barrier_event_data; + MetaBarrierImplNative *barrier_impl; + + if (!clutter_input_device_get_coords (device, NULL, &prev_pos)) + return; + + prev_x = prev_pos.x; + prev_y = prev_pos.y; + + /* Get the direction of the motion vector. */ + if (prev_x < *x) + motion_dir |= META_BARRIER_DIRECTION_POSITIVE_X; + else if (prev_x > *x) + motion_dir |= META_BARRIER_DIRECTION_NEGATIVE_X; + if (prev_y < *y) + motion_dir |= META_BARRIER_DIRECTION_POSITIVE_Y; + else if (prev_y > *y) + motion_dir |= META_BARRIER_DIRECTION_NEGATIVE_Y; + + /* Clamp to the closest barrier in any direction until either there are no + * more barriers to clamp to or all directions have been clamped. */ + while (motion_dir != 0) + { + if (get_closest_barrier (manager, + prev_x, prev_y, + *x, *y, + motion_dir, + &barrier_impl)) + clamp_to_barrier (barrier_impl, &motion_dir, x, y); + else + break; + } + + /* Potentially release active barrier movements. */ + maybe_release_barriers (manager, prev_x, prev_y, *x, *y); + + /* Initiate or continue barrier interaction. */ + barrier_event_data = (MetaBarrierEventData) { + .time = time, + .prev_x = prev_x, + .prev_y = prev_y, + .x = *x, + .y = *y, + .dx = orig_x - prev_x, + .dy = orig_y - prev_y, + }; + + g_hash_table_foreach (manager->barriers, + maybe_emit_barrier_event, + &barrier_event_data); +} + +static gboolean +_meta_barrier_impl_native_is_active (MetaBarrierImpl *impl) +{ + MetaBarrierImplNative *self = META_BARRIER_IMPL_NATIVE (impl); + + return self->is_active; +} + +static void +_meta_barrier_impl_native_release (MetaBarrierImpl *impl, + MetaBarrierEvent *event) +{ + MetaBarrierImplNative *self = META_BARRIER_IMPL_NATIVE (impl); + + if (self->state == META_BARRIER_STATE_HELD && + event->event_id == self->trigger_serial) + self->state = META_BARRIER_STATE_RELEASE; +} + +static void +_meta_barrier_impl_native_destroy (MetaBarrierImpl *impl) +{ + MetaBarrierImplNative *self = META_BARRIER_IMPL_NATIVE (impl); + + g_hash_table_remove (self->manager->barriers, self); + self->is_active = FALSE; +} + +MetaBarrierImpl * +meta_barrier_impl_native_new (MetaBarrier *barrier) +{ + MetaBarrierImplNative *self; + MetaBackendNative *native; + MetaBarrierManagerNative *manager; + + self = g_object_new (META_TYPE_BARRIER_IMPL_NATIVE, NULL); + + self->barrier = barrier; + self->is_active = TRUE; + + native = META_BACKEND_NATIVE (meta_get_backend ()); + manager = meta_backend_native_get_barrier_manager (native); + self->manager = manager; + g_hash_table_add (manager->barriers, self); + + return META_BARRIER_IMPL (self); +} + +static void +meta_barrier_impl_native_class_init (MetaBarrierImplNativeClass *klass) +{ + MetaBarrierImplClass *impl_class = META_BARRIER_IMPL_CLASS (klass); + + impl_class->is_active = _meta_barrier_impl_native_is_active; + impl_class->release = _meta_barrier_impl_native_release; + impl_class->destroy = _meta_barrier_impl_native_destroy; +} + +static void +meta_barrier_impl_native_init (MetaBarrierImplNative *self) +{ +} + +MetaBarrierManagerNative * +meta_barrier_manager_native_new (void) +{ + MetaBarrierManagerNative *manager; + + manager = g_new0 (MetaBarrierManagerNative, 1); + + manager->barriers = g_hash_table_new (NULL, NULL); + + return manager; +} diff --git a/src/backends/native/meta-barrier-native.h b/src/backends/native/meta-barrier-native.h new file mode 100644 index 000000000..2853cfa80 --- /dev/null +++ b/src/backends/native/meta-barrier-native.h @@ -0,0 +1,52 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2015 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +#ifndef META_BARRIER_NATIVE_H +#define META_BARRIER_NATIVE_H + +#include "backends/meta-barrier-private.h" + +G_BEGIN_DECLS + +#define META_TYPE_BARRIER_IMPL_NATIVE (meta_barrier_impl_native_get_type ()) +G_DECLARE_FINAL_TYPE (MetaBarrierImplNative, + meta_barrier_impl_native, + META, BARRIER_IMPL_NATIVE, + MetaBarrierImpl) + +typedef struct _MetaBarrierManagerNative MetaBarrierManagerNative; + + +MetaBarrierImpl *meta_barrier_impl_native_new (MetaBarrier *barrier); + +MetaBarrierManagerNative *meta_barrier_manager_native_new (void); +void meta_barrier_manager_native_process (MetaBarrierManagerNative *manager, + ClutterInputDevice *device, + guint32 time, + float *x, + float *y); + +G_END_DECLS + +#endif /* META_BARRIER_NATIVE_H */ diff --git a/src/backends/native/meta-clutter-backend-native.c b/src/backends/native/meta-clutter-backend-native.c new file mode 100644 index 000000000..ff3ae1a38 --- /dev/null +++ b/src/backends/native/meta-clutter-backend-native.c @@ -0,0 +1,151 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +/** + * SECTION:meta-clutter-backend-native + * @title: MetaClutterBackendNatve + * @short_description: A native backend which renders using EGL. + * + * MetaClutterBackendNative is the #ClutterBackend which is used by the native + * (as opposed to the X) backend. It creates a stage with #MetaStageNative and + * renders using the #CoglRenderer. + * + * Note that MetaClutterBackendNative is something different than a + * #MetaBackendNative. The former is a #ClutterBackend implementation, while + * the latter is a #MetaBackend implementation. + */ + +#include "config.h" + +#include "backends/native/meta-clutter-backend-native.h" + +#include <glib-object.h> + +#include "backends/meta-backend-private.h" +#include "backends/meta-renderer.h" +#include "backends/native/meta-seat-native.h" +#include "backends/native/meta-stage-native.h" +#include "clutter/clutter.h" +#include "core/bell.h" +#include "meta/meta-backend.h" + +struct _MetaClutterBackendNative +{ + ClutterBackendEglNative parent; + + MetaSeatNative *main_seat; + MetaStageNative *stage_native; +}; + +static gchar *evdev_seat_id; + +G_DEFINE_TYPE (MetaClutterBackendNative, meta_clutter_backend_native, + CLUTTER_TYPE_BACKEND_EGL_NATIVE) + +MetaStageNative * +meta_clutter_backend_native_get_stage_native (ClutterBackend *backend) +{ + MetaClutterBackendNative *clutter_backend_native = + META_CLUTTER_BACKEND_NATIVE (backend); + + return clutter_backend_native->stage_native; +} + +static CoglRenderer * +meta_clutter_backend_native_get_renderer (ClutterBackend *clutter_backend, + GError **error) +{ + MetaBackend *backend = meta_get_backend (); + MetaRenderer *renderer = meta_backend_get_renderer (backend); + + return meta_renderer_create_cogl_renderer (renderer); +} + +static ClutterStageWindow * +meta_clutter_backend_native_create_stage (ClutterBackend *backend, + ClutterStage *wrapper, + GError **error) +{ + MetaClutterBackendNative *clutter_backend_native = + META_CLUTTER_BACKEND_NATIVE (backend); + + g_assert (!clutter_backend_native->stage_native); + + clutter_backend_native->stage_native = g_object_new (META_TYPE_STAGE_NATIVE, + "backend", backend, + "wrapper", wrapper, + NULL); + return CLUTTER_STAGE_WINDOW (clutter_backend_native->stage_native); +} + +static void +meta_clutter_backend_native_init_events (ClutterBackend *backend) +{ + MetaClutterBackendNative *backend_native = META_CLUTTER_BACKEND_NATIVE (backend); + const gchar *seat_id = evdev_seat_id ? evdev_seat_id : "seat0"; + + backend_native->main_seat = g_object_new (META_TYPE_SEAT_NATIVE, + "backend", backend, + "seat-id", seat_id, + NULL); +} + +static ClutterSeat * +meta_clutter_backend_native_get_default_seat (ClutterBackend *backend) +{ + MetaClutterBackendNative *backend_native = META_CLUTTER_BACKEND_NATIVE (backend); + + return CLUTTER_SEAT (backend_native->main_seat); +} + +static void +meta_clutter_backend_native_init (MetaClutterBackendNative *clutter_backend_nativen) +{ +} + +static void +meta_clutter_backend_native_class_init (MetaClutterBackendNativeClass *klass) +{ + ClutterBackendClass *clutter_backend_class = CLUTTER_BACKEND_CLASS (klass); + + clutter_backend_class->get_renderer = meta_clutter_backend_native_get_renderer; + clutter_backend_class->create_stage = meta_clutter_backend_native_create_stage; + clutter_backend_class->init_events = meta_clutter_backend_native_init_events; + clutter_backend_class->get_default_seat = meta_clutter_backend_native_get_default_seat; +} + +/** + * meta_cluter_backend_native_set_seat_id: + * @seat_id: The seat ID + * + * Sets the seat to assign to the libinput context. + * + * For reliable effects, this function must be called before clutter_init(). + */ +void +meta_clutter_backend_native_set_seat_id (const gchar *seat_id) +{ + g_free (evdev_seat_id); + evdev_seat_id = g_strdup (seat_id); +} diff --git a/src/backends/native/meta-clutter-backend-native.h b/src/backends/native/meta-clutter-backend-native.h new file mode 100644 index 000000000..8914f8aa3 --- /dev/null +++ b/src/backends/native/meta-clutter-backend-native.h @@ -0,0 +1,43 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +#ifndef META_CLUTTER_BACKEND_NATIVE_H +#define META_CLUTTER_BACKEND_NATIVE_H + +#include <glib-object.h> + +#include "backends/native/meta-stage-native.h" +#include "clutter/clutter.h" +#include "clutter/egl/clutter-backend-eglnative.h" + +#define META_TYPE_CLUTTER_BACKEND_NATIVE (meta_clutter_backend_native_get_type ()) +G_DECLARE_FINAL_TYPE (MetaClutterBackendNative, meta_clutter_backend_native, + META, CLUTTER_BACKEND_NATIVE, + ClutterBackendEglNative) + +MetaStageNative * meta_clutter_backend_native_get_stage_native (ClutterBackend *backend); + +void meta_clutter_backend_native_set_seat_id (const gchar *seat_id); + +#endif /* META_CLUTTER_BACKEND_NATIVE_H */ diff --git a/src/backends/native/meta-crtc-kms.c b/src/backends/native/meta-crtc-kms.c new file mode 100644 index 000000000..2d570b2de --- /dev/null +++ b/src/backends/native/meta-crtc-kms.c @@ -0,0 +1,302 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2013-2017 Red Hat + * Copyright (C) 2018 DisplayLink (UK) Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "backends/native/meta-crtc-kms.h" + +#include "backends/meta-backend-private.h" +#include "backends/meta-logical-monitor.h" +#include "backends/native/meta-gpu-kms.h" +#include "backends/native/meta-output-kms.h" +#include "backends/native/meta-kms-device.h" +#include "backends/native/meta-kms-plane.h" +#include "backends/native/meta-kms-update.h" + +#define ALL_TRANSFORMS_MASK ((1 << META_MONITOR_N_TRANSFORMS) - 1) + +typedef struct _MetaCrtcKms +{ + MetaKmsCrtc *kms_crtc; + + MetaKmsPlane *primary_plane; +} MetaCrtcKms; + +static GQuark kms_crtc_crtc_kms_quark; + +gboolean +meta_crtc_kms_is_transform_handled (MetaCrtc *crtc, + MetaMonitorTransform transform) +{ + MetaCrtcKms *crtc_kms = crtc->driver_private; + + if (!crtc_kms->primary_plane) + return FALSE; + + return meta_kms_plane_is_transform_handled (crtc_kms->primary_plane, + transform); +} + +void +meta_crtc_kms_apply_transform (MetaCrtc *crtc, + MetaKmsPlaneAssignment *kms_plane_assignment) +{ + MetaCrtcKms *crtc_kms = crtc->driver_private; + MetaMonitorTransform hw_transform; + + hw_transform = crtc->config->transform; + if (!meta_crtc_kms_is_transform_handled (crtc, hw_transform)) + hw_transform = META_MONITOR_TRANSFORM_NORMAL; + if (!meta_crtc_kms_is_transform_handled (crtc, hw_transform)) + return; + + meta_kms_plane_update_set_rotation (crtc_kms->primary_plane, + kms_plane_assignment, + hw_transform); +} + +void +meta_crtc_kms_assign_primary_plane (MetaCrtc *crtc, + uint32_t fb_id, + MetaKmsUpdate *kms_update) +{ + MetaCrtcConfig *crtc_config; + MetaFixed16Rectangle src_rect; + MetaFixed16Rectangle dst_rect; + MetaKmsAssignPlaneFlag flags; + MetaKmsCrtc *kms_crtc; + MetaKmsDevice *kms_device; + MetaKmsPlane *primary_kms_plane; + MetaKmsPlaneAssignment *plane_assignment; + + crtc_config = crtc->config; + + + src_rect = (MetaFixed16Rectangle) { + .x = meta_fixed_16_from_int (0), + .y = meta_fixed_16_from_int (0), + .width = meta_fixed_16_from_int (crtc_config->mode->width), + .height = meta_fixed_16_from_int (crtc_config->mode->height), + }; + dst_rect = (MetaFixed16Rectangle) { + .x = meta_fixed_16_from_int (0), + .y = meta_fixed_16_from_int (0), + .width = meta_fixed_16_from_int (crtc_config->mode->width), + .height = meta_fixed_16_from_int (crtc_config->mode->height), + }; + + flags = META_KMS_ASSIGN_PLANE_FLAG_NONE; + + kms_crtc = meta_crtc_kms_get_kms_crtc (crtc); + kms_device = meta_kms_crtc_get_device (kms_crtc); + primary_kms_plane = meta_kms_device_get_primary_plane_for (kms_device, + kms_crtc); + plane_assignment = meta_kms_update_assign_plane (kms_update, + kms_crtc, + primary_kms_plane, + fb_id, + src_rect, + dst_rect, + flags); + meta_crtc_kms_apply_transform (crtc, plane_assignment); +} + +static GList * +generate_crtc_connector_list (MetaGpu *gpu, + MetaCrtc *crtc) +{ + GList *connectors = NULL; + GList *l; + + for (l = meta_gpu_get_outputs (gpu); l; l = l->next) + { + MetaOutput *output = l->data; + MetaCrtc *assigned_crtc; + + assigned_crtc = meta_output_get_assigned_crtc (output); + if (assigned_crtc == crtc) + { + MetaKmsConnector *kms_connector = + meta_output_kms_get_kms_connector (output); + + connectors = g_list_prepend (connectors, kms_connector); + } + } + + return connectors; +} + +void +meta_crtc_kms_set_mode (MetaCrtc *crtc, + MetaKmsUpdate *kms_update) +{ + MetaCrtcConfig *crtc_config = crtc->config; + MetaGpu *gpu = meta_crtc_get_gpu (crtc); + GList *connectors; + drmModeModeInfo *mode; + + connectors = generate_crtc_connector_list (gpu, crtc); + + if (connectors) + { + mode = crtc_config->mode->driver_private; + + g_debug ("Setting CRTC (%ld) mode to %s", crtc->crtc_id, mode->name); + } + else + { + mode = NULL; + + g_debug ("Unsetting CRTC (%ld) mode", crtc->crtc_id); + } + + meta_kms_update_mode_set (kms_update, + meta_crtc_kms_get_kms_crtc (crtc), + g_steal_pointer (&connectors), + mode); +} + +void +meta_crtc_kms_page_flip (MetaCrtc *crtc, + const MetaKmsPageFlipFeedback *page_flip_feedback, + gpointer user_data, + MetaKmsUpdate *kms_update) +{ + meta_kms_update_page_flip (kms_update, + meta_crtc_kms_get_kms_crtc (crtc), + page_flip_feedback, + user_data); +} + +MetaKmsCrtc * +meta_crtc_kms_get_kms_crtc (MetaCrtc *crtc) +{ + MetaCrtcKms *crtc_kms = crtc->driver_private; + + return crtc_kms->kms_crtc; +} + +/** + * meta_crtc_kms_get_modifiers: + * @crtc: a #MetaCrtc object that has to be a #MetaCrtcKms + * @format: a DRM pixel format + * + * Returns a pointer to a #GArray containing all the supported + * modifiers for the given DRM pixel format on the CRTC's primary + * plane. The array element type is uint64_t. + * + * The caller must not modify or destroy the array or its contents. + * + * Returns NULL if the modifiers are not known or the format is not + * supported. + */ +GArray * +meta_crtc_kms_get_modifiers (MetaCrtc *crtc, + uint32_t format) +{ + MetaCrtcKms *crtc_kms = crtc->driver_private; + + return meta_kms_plane_get_modifiers_for_format (crtc_kms->primary_plane, + format); +} + +/** + * meta_crtc_kms_copy_drm_format_list: + * @crtc: a #MetaCrtc object that has to be a #MetaCrtcKms + * + * Returns a new #GArray that the caller must destroy. The array + * contains all the DRM pixel formats the CRTC supports on + * its primary plane. The array element type is uint32_t. + */ +GArray * +meta_crtc_kms_copy_drm_format_list (MetaCrtc *crtc) +{ + MetaCrtcKms *crtc_kms = crtc->driver_private; + + return meta_kms_plane_copy_drm_format_list (crtc_kms->primary_plane); +} + +/** + * meta_crtc_kms_supports_format: + * @crtc: a #MetaCrtc object that has to be a #MetaCrtcKms + * @drm_format: a DRM pixel format + * + * Returns true if the CRTC supports the format on its primary plane. + */ +gboolean +meta_crtc_kms_supports_format (MetaCrtc *crtc, + uint32_t drm_format) +{ + MetaCrtcKms *crtc_kms = crtc->driver_private; + + return meta_kms_plane_is_format_supported (crtc_kms->primary_plane, + drm_format); +} + +MetaCrtc * +meta_crtc_kms_from_kms_crtc (MetaKmsCrtc *kms_crtc) +{ + return g_object_get_qdata (G_OBJECT (kms_crtc), kms_crtc_crtc_kms_quark); +} + +static void +meta_crtc_destroy_notify (MetaCrtc *crtc) +{ + g_free (crtc->driver_private); +} + +MetaCrtc * +meta_create_kms_crtc (MetaGpuKms *gpu_kms, + MetaKmsCrtc *kms_crtc) +{ + MetaGpu *gpu = META_GPU (gpu_kms); + MetaKmsDevice *kms_device; + MetaCrtc *crtc; + MetaCrtcKms *crtc_kms; + MetaKmsPlane *primary_plane; + + kms_device = meta_gpu_kms_get_kms_device (gpu_kms); + primary_plane = meta_kms_device_get_primary_plane_for (kms_device, + kms_crtc); + crtc = g_object_new (META_TYPE_CRTC, NULL); + crtc->gpu = gpu; + crtc->crtc_id = meta_kms_crtc_get_id (kms_crtc); + crtc->is_dirty = FALSE; + crtc->all_transforms = ALL_TRANSFORMS_MASK; + + crtc_kms = g_new0 (MetaCrtcKms, 1); + crtc_kms->kms_crtc = kms_crtc; + crtc_kms->primary_plane = primary_plane; + + crtc->driver_private = crtc_kms; + crtc->driver_notify = (GDestroyNotify) meta_crtc_destroy_notify; + + if (!kms_crtc_crtc_kms_quark) + { + kms_crtc_crtc_kms_quark = + g_quark_from_static_string ("meta-kms-crtc-crtc-kms-quark"); + } + + g_object_set_qdata (G_OBJECT (kms_crtc), kms_crtc_crtc_kms_quark, crtc); + + return crtc; +} diff --git a/src/backends/native/meta-crtc-kms.h b/src/backends/native/meta-crtc-kms.h new file mode 100644 index 000000000..898622478 --- /dev/null +++ b/src/backends/native/meta-crtc-kms.h @@ -0,0 +1,72 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat + * Copyright (C) 2018 DisplayLink (UK) Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_CRTC_KMS_H +#define META_CRTC_KMS_H + +#include <xf86drm.h> +#include <xf86drmMode.h> + +#include "backends/meta-backend-types.h" +#include "backends/meta-crtc.h" +#include "backends/native/meta-gpu-kms.h" +#include "backends/native/meta-kms-crtc.h" + +gboolean meta_crtc_kms_is_transform_handled (MetaCrtc *crtc, + MetaMonitorTransform transform); + +void meta_crtc_kms_apply_transform (MetaCrtc *crtc, + MetaKmsPlaneAssignment *kms_plane_assignment); + +void meta_crtc_kms_assign_primary_plane (MetaCrtc *crtc, + uint32_t fb_id, + MetaKmsUpdate *kms_update); + +void meta_crtc_kms_set_mode (MetaCrtc *crtc, + MetaKmsUpdate *kms_update); + +void meta_crtc_kms_page_flip (MetaCrtc *crtc, + const MetaKmsPageFlipFeedback *page_flip_feedback, + gpointer user_data, + MetaKmsUpdate *kms_update); + +void meta_crtc_kms_set_is_underscanning (MetaCrtc *crtc, + gboolean is_underscanning); + +MetaKmsCrtc * meta_crtc_kms_get_kms_crtc (MetaCrtc *crtc); + +GArray * meta_crtc_kms_get_modifiers (MetaCrtc *crtc, + uint32_t format); + +GArray * +meta_crtc_kms_copy_drm_format_list (MetaCrtc *crtc); + +gboolean +meta_crtc_kms_supports_format (MetaCrtc *crtc, + uint32_t drm_format); + +MetaCrtc * meta_crtc_kms_from_kms_crtc (MetaKmsCrtc *kms_crtc); + +MetaCrtc * meta_create_kms_crtc (MetaGpuKms *gpu_kms, + MetaKmsCrtc *kms_crtc); + +#endif /* META_CRTC_KMS_H */ diff --git a/src/backends/native/meta-cursor-renderer-native.c b/src/backends/native/meta-cursor-renderer-native.c new file mode 100644 index 000000000..578a9a0a0 --- /dev/null +++ b/src/backends/native/meta-cursor-renderer-native.c @@ -0,0 +1,1744 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat + * Copyright 2020 DisplayLink (UK) Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jasper St. Pierre <jstpierre@mecheye.net> + */ + +#include "config.h" + +#include "backends/native/meta-cursor-renderer-native.h" + +#include <string.h> +#include <gbm.h> +#include <xf86drm.h> +#include <errno.h> + +#include "backends/meta-backend-private.h" +#include "backends/meta-cursor-sprite-xcursor.h" +#include "backends/meta-logical-monitor.h" +#include "backends/meta-monitor.h" +#include "backends/meta-monitor-manager-private.h" +#include "backends/meta-output.h" +#include "backends/native/meta-crtc-kms.h" +#include "backends/native/meta-kms-device.h" +#include "backends/native/meta-kms-update.h" +#include "backends/native/meta-kms.h" +#include "backends/native/meta-renderer-native.h" +#include "core/boxes-private.h" +#include "meta/boxes.h" +#include "meta/meta-backend.h" +#include "meta/util.h" + +#ifdef HAVE_WAYLAND +#include "wayland/meta-cursor-sprite-wayland.h" +#include "wayland/meta-wayland-buffer.h" +#endif + +#ifndef DRM_CAP_CURSOR_WIDTH +#define DRM_CAP_CURSOR_WIDTH 0x8 +#endif +#ifndef DRM_CAP_CURSOR_HEIGHT +#define DRM_CAP_CURSOR_HEIGHT 0x9 +#endif + +/* When animating a cursor, we usually call drmModeSetCursor2 once per frame. + * Though, testing shows that we need to triple buffer the cursor buffer in + * order to avoid glitches when animating the cursor, at least when running on + * Intel. The reason for this might be (but is not confirmed to be) due to + * the user space gbm_bo cache, making us reuse and overwrite the kernel side + * buffer content before it was scanned out. To avoid this, we keep a user space + * reference to each buffer we set until at least one frame after it was drawn. + * In effect, this means we three active cursor gbm_bo's: one that that just has + * been set, one that was previously set and may or may not have been scanned + * out, and one pending that will be replaced if the cursor sprite changes. + */ +#define HW_CURSOR_BUFFER_COUNT 3 + +static GQuark quark_cursor_sprite = 0; + +struct _MetaCursorRendererNative +{ + MetaCursorRenderer parent; +}; + +struct _MetaCursorRendererNativePrivate +{ + MetaBackend *backend; + + gboolean hw_state_invalidated; + gboolean has_hw_cursor; + + MetaCursorSprite *last_cursor; + guint animation_timeout_id; +}; +typedef struct _MetaCursorRendererNativePrivate MetaCursorRendererNativePrivate; + +typedef struct _MetaCursorRendererNativeGpuData +{ + gboolean hw_cursor_broken; + + uint64_t cursor_width; + uint64_t cursor_height; +} MetaCursorRendererNativeGpuData; + +typedef enum _MetaCursorGbmBoState +{ + META_CURSOR_GBM_BO_STATE_NONE, + META_CURSOR_GBM_BO_STATE_SET, + META_CURSOR_GBM_BO_STATE_INVALIDATED, +} MetaCursorGbmBoState; + +typedef struct _MetaCursorNativeGpuState +{ + MetaGpu *gpu; + guint active_bo; + MetaCursorGbmBoState pending_bo_state; + struct gbm_bo *bos[HW_CURSOR_BUFFER_COUNT]; +} MetaCursorNativeGpuState; + +typedef struct _MetaCursorNativePrivate +{ + GHashTable *gpu_states; + + struct { + gboolean can_preprocess; + float current_relative_scale; + MetaMonitorTransform current_relative_transform; + } preprocess_state; +} MetaCursorNativePrivate; + +static GQuark quark_cursor_renderer_native_gpu_data = 0; + +G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorRendererNative, meta_cursor_renderer_native, META_TYPE_CURSOR_RENDERER); + +static void +realize_cursor_sprite (MetaCursorRenderer *renderer, + MetaCursorSprite *cursor_sprite, + GList *gpus); + +static MetaCursorNativeGpuState * +get_cursor_gpu_state (MetaCursorNativePrivate *cursor_priv, + MetaGpuKms *gpu_kms); + +static MetaCursorNativeGpuState * +ensure_cursor_gpu_state (MetaCursorNativePrivate *cursor_priv, + MetaGpuKms *gpu_kms); + +static void +invalidate_cursor_gpu_state (MetaCursorSprite *cursor_sprite); + +static MetaCursorNativePrivate * +ensure_cursor_priv (MetaCursorSprite *cursor_sprite); + +static MetaCursorNativePrivate * +get_cursor_priv (MetaCursorSprite *cursor_sprite); + +static MetaCursorRendererNativeGpuData * +meta_cursor_renderer_native_gpu_data_from_gpu (MetaGpuKms *gpu_kms) +{ + return g_object_get_qdata (G_OBJECT (gpu_kms), + quark_cursor_renderer_native_gpu_data); +} + +static MetaCursorRendererNativeGpuData * +meta_create_cursor_renderer_native_gpu_data (MetaGpuKms *gpu_kms) +{ + MetaCursorRendererNativeGpuData *cursor_renderer_gpu_data; + + cursor_renderer_gpu_data = g_new0 (MetaCursorRendererNativeGpuData, 1); + g_object_set_qdata_full (G_OBJECT (gpu_kms), + quark_cursor_renderer_native_gpu_data, + cursor_renderer_gpu_data, + g_free); + + return cursor_renderer_gpu_data; +} + +static void +meta_cursor_renderer_native_finalize (GObject *object) +{ + MetaCursorRendererNative *renderer = META_CURSOR_RENDERER_NATIVE (object); + MetaCursorRendererNativePrivate *priv = + meta_cursor_renderer_native_get_instance_private (renderer); + + g_clear_handle_id (&priv->animation_timeout_id, g_source_remove); + + G_OBJECT_CLASS (meta_cursor_renderer_native_parent_class)->finalize (object); +} + +static guint +get_pending_cursor_sprite_gbm_bo_index (MetaCursorNativeGpuState *cursor_gpu_state) +{ + return (cursor_gpu_state->active_bo + 1) % HW_CURSOR_BUFFER_COUNT; +} + +static struct gbm_bo * +get_pending_cursor_sprite_gbm_bo (MetaCursorNativeGpuState *cursor_gpu_state) +{ + guint pending_bo; + + pending_bo = get_pending_cursor_sprite_gbm_bo_index (cursor_gpu_state); + return cursor_gpu_state->bos[pending_bo]; +} + +static struct gbm_bo * +get_active_cursor_sprite_gbm_bo (MetaCursorNativeGpuState *cursor_gpu_state) +{ + return cursor_gpu_state->bos[cursor_gpu_state->active_bo]; +} + +static void +set_pending_cursor_sprite_gbm_bo (MetaCursorSprite *cursor_sprite, + MetaGpuKms *gpu_kms, + struct gbm_bo *bo) +{ + MetaCursorNativePrivate *cursor_priv; + MetaCursorNativeGpuState *cursor_gpu_state; + guint pending_bo; + + cursor_priv = ensure_cursor_priv (cursor_sprite); + cursor_gpu_state = ensure_cursor_gpu_state (cursor_priv, gpu_kms); + + pending_bo = get_pending_cursor_sprite_gbm_bo_index (cursor_gpu_state); + cursor_gpu_state->bos[pending_bo] = bo; + cursor_gpu_state->pending_bo_state = META_CURSOR_GBM_BO_STATE_SET; +} + +static void +calculate_crtc_cursor_hotspot (MetaCursorSprite *cursor_sprite, + int *cursor_hotspot_x, + int *cursor_hotspot_y) +{ + MetaCursorNativePrivate *cursor_priv = get_cursor_priv (cursor_sprite); + int hot_x, hot_y; + int width, height; + float scale; + MetaMonitorTransform transform; + + scale = cursor_priv->preprocess_state.current_relative_scale; + transform = cursor_priv->preprocess_state.current_relative_transform; + + meta_cursor_sprite_get_hotspot (cursor_sprite, &hot_x, &hot_y); + width = meta_cursor_sprite_get_width (cursor_sprite); + height = meta_cursor_sprite_get_height (cursor_sprite); + meta_monitor_transform_transform_point (transform, + width, height, + hot_x, hot_y, + &hot_x, &hot_y); + *cursor_hotspot_x = (int) roundf (hot_x * scale); + *cursor_hotspot_y = (int) roundf (hot_y * scale); +} + +static void +set_crtc_cursor (MetaCursorRendererNative *native, + MetaKmsUpdate *kms_update, + MetaCrtc *crtc, + int x, + int y, + MetaCursorSprite *cursor_sprite) +{ + MetaCursorRendererNativePrivate *priv = + meta_cursor_renderer_native_get_instance_private (native); + MetaCursorNativePrivate *cursor_priv = get_cursor_priv (cursor_sprite); + MetaGpuKms *gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc)); + MetaCursorRendererNativeGpuData *cursor_renderer_gpu_data = + meta_cursor_renderer_native_gpu_data_from_gpu (gpu_kms); + MetaCursorNativeGpuState *cursor_gpu_state = + get_cursor_gpu_state (cursor_priv, gpu_kms); + MetaKmsCrtc *kms_crtc; + MetaKmsDevice *kms_device; + MetaKmsPlane *cursor_plane; + struct gbm_bo *bo; + union gbm_bo_handle handle; + int cursor_width, cursor_height; + MetaFixed16Rectangle src_rect; + MetaFixed16Rectangle dst_rect; + MetaKmsAssignPlaneFlag flags; + int cursor_hotspot_x; + int cursor_hotspot_y; + MetaKmsPlaneAssignment *plane_assignment; + + if (cursor_gpu_state->pending_bo_state == META_CURSOR_GBM_BO_STATE_SET) + bo = get_pending_cursor_sprite_gbm_bo (cursor_gpu_state); + else + bo = get_active_cursor_sprite_gbm_bo (cursor_gpu_state); + + kms_crtc = meta_crtc_kms_get_kms_crtc (crtc); + kms_device = meta_kms_crtc_get_device (kms_crtc); + cursor_plane = meta_kms_device_get_cursor_plane_for (kms_device, kms_crtc); + g_return_if_fail (cursor_plane); + + handle = gbm_bo_get_handle (bo); + + cursor_width = cursor_renderer_gpu_data->cursor_width; + cursor_height = cursor_renderer_gpu_data->cursor_height; + src_rect = (MetaFixed16Rectangle) { + .x = meta_fixed_16_from_int (0), + .y = meta_fixed_16_from_int (0), + .width = meta_fixed_16_from_int (cursor_width), + .height = meta_fixed_16_from_int (cursor_height), + }; + dst_rect = (MetaFixed16Rectangle) { + .x = meta_fixed_16_from_int (x), + .y = meta_fixed_16_from_int (y), + .width = meta_fixed_16_from_int (cursor_width), + .height = meta_fixed_16_from_int (cursor_height), + }; + + flags = META_KMS_ASSIGN_PLANE_FLAG_NONE; + if (!priv->hw_state_invalidated && bo == crtc->cursor_renderer_private) + flags |= META_KMS_ASSIGN_PLANE_FLAG_FB_UNCHANGED; + + plane_assignment = meta_kms_update_assign_plane (kms_update, + kms_crtc, + cursor_plane, + handle.u32, + src_rect, + dst_rect, + flags); + + calculate_crtc_cursor_hotspot (cursor_sprite, + &cursor_hotspot_x, + &cursor_hotspot_y); + meta_kms_plane_assignment_set_cursor_hotspot (plane_assignment, + cursor_hotspot_x, + cursor_hotspot_y); + + crtc->cursor_renderer_private = bo; + + if (cursor_gpu_state->pending_bo_state == META_CURSOR_GBM_BO_STATE_SET) + { + cursor_gpu_state->active_bo = + (cursor_gpu_state->active_bo + 1) % HW_CURSOR_BUFFER_COUNT; + cursor_gpu_state->pending_bo_state = META_CURSOR_GBM_BO_STATE_NONE; + } +} + +static void +unset_crtc_cursor (MetaCursorRendererNative *native, + MetaKmsUpdate *kms_update, + MetaCrtc *crtc) +{ + MetaCursorRendererNativePrivate *priv = + meta_cursor_renderer_native_get_instance_private (native); + MetaKmsCrtc *kms_crtc; + MetaKmsDevice *kms_device; + MetaKmsPlane *cursor_plane; + + if (!priv->hw_state_invalidated && !crtc->cursor_renderer_private) + return; + + kms_crtc = meta_crtc_kms_get_kms_crtc (crtc); + kms_device = meta_kms_crtc_get_device (kms_crtc); + cursor_plane = meta_kms_device_get_cursor_plane_for (kms_device, kms_crtc); + + if (cursor_plane) + meta_kms_update_unassign_plane (kms_update, kms_crtc, cursor_plane); + + crtc->cursor_renderer_private = NULL; +} + +static float +calculate_cursor_crtc_sprite_scale (MetaCursorSprite *cursor_sprite, + MetaLogicalMonitor *logical_monitor) +{ + if (meta_is_stage_views_scaled ()) + { + return (meta_logical_monitor_get_scale (logical_monitor) * + meta_cursor_sprite_get_texture_scale (cursor_sprite)); + } + else + { + return 1.0; + } +} + +typedef struct +{ + MetaCursorRendererNative *in_cursor_renderer_native; + MetaLogicalMonitor *in_logical_monitor; + graphene_rect_t in_local_cursor_rect; + MetaCursorSprite *in_cursor_sprite; + MetaKmsUpdate *in_kms_update; + + gboolean out_painted; +} UpdateCrtcCursorData; + +static gboolean +update_monitor_crtc_cursor (MetaMonitor *monitor, + MetaMonitorMode *monitor_mode, + MetaMonitorCrtcMode *monitor_crtc_mode, + gpointer user_data, + GError **error) +{ + UpdateCrtcCursorData *data = user_data; + MetaCursorRendererNative *cursor_renderer_native = + data->in_cursor_renderer_native; + MetaCursorRendererNativePrivate *priv = + meta_cursor_renderer_native_get_instance_private (cursor_renderer_native); + MetaCrtc *crtc; + MetaMonitorTransform transform; + graphene_rect_t scaled_crtc_rect; + float scale; + int crtc_x, crtc_y; + int crtc_width, crtc_height; + + if (meta_is_stage_views_scaled ()) + scale = meta_logical_monitor_get_scale (data->in_logical_monitor); + else + scale = 1.0; + + transform = meta_logical_monitor_get_transform (data->in_logical_monitor); + transform = meta_monitor_logical_to_crtc_transform (monitor, transform); + + meta_monitor_calculate_crtc_pos (monitor, monitor_mode, + monitor_crtc_mode->output, + transform, + &crtc_x, &crtc_y); + + if (meta_monitor_transform_is_rotated (transform)) + { + crtc_width = monitor_crtc_mode->crtc_mode->height; + crtc_height = monitor_crtc_mode->crtc_mode->width; + } + else + { + crtc_width = monitor_crtc_mode->crtc_mode->width; + crtc_height = monitor_crtc_mode->crtc_mode->height; + } + + scaled_crtc_rect = (graphene_rect_t) { + .origin = { + .x = crtc_x / scale, + .y = crtc_y / scale + }, + .size = { + .width = crtc_width / scale, + .height = crtc_height / scale + }, + }; + + crtc = meta_output_get_assigned_crtc (monitor_crtc_mode->output); + + if (priv->has_hw_cursor && + graphene_rect_intersection (&scaled_crtc_rect, + &data->in_local_cursor_rect, + NULL)) + { + MetaMonitorTransform inverted_transform; + MetaRectangle cursor_rect; + CoglTexture *texture; + float crtc_cursor_x, crtc_cursor_y; + float cursor_crtc_scale; + int tex_width, tex_height; + + crtc_cursor_x = (data->in_local_cursor_rect.origin.x - + scaled_crtc_rect.origin.x) * scale; + crtc_cursor_y = (data->in_local_cursor_rect.origin.y - + scaled_crtc_rect.origin.y) * scale; + + texture = meta_cursor_sprite_get_cogl_texture (data->in_cursor_sprite); + tex_width = cogl_texture_get_width (texture); + tex_height = cogl_texture_get_height (texture); + + cursor_crtc_scale = + calculate_cursor_crtc_sprite_scale (data->in_cursor_sprite, + data->in_logical_monitor); + + cursor_rect = (MetaRectangle) { + .x = floorf (crtc_cursor_x), + .y = floorf (crtc_cursor_y), + .width = roundf (tex_width * cursor_crtc_scale), + .height = roundf (tex_height * cursor_crtc_scale) + }; + + inverted_transform = meta_monitor_transform_invert (transform); + meta_rectangle_transform (&cursor_rect, + inverted_transform, + monitor_crtc_mode->crtc_mode->width, + monitor_crtc_mode->crtc_mode->height, + &cursor_rect); + + set_crtc_cursor (data->in_cursor_renderer_native, + data->in_kms_update, + crtc, + cursor_rect.x, + cursor_rect.y, + data->in_cursor_sprite); + + data->out_painted = data->out_painted || TRUE; + } + else + { + unset_crtc_cursor (data->in_cursor_renderer_native, + data->in_kms_update, + crtc); + } + + return TRUE; +} + +static void +disable_hw_cursor_for_crtc (MetaKmsCrtc *kms_crtc, + const GError *error) +{ + MetaCrtc *crtc = meta_crtc_kms_from_kms_crtc (kms_crtc); + MetaGpuKms *gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc)); + MetaCursorRendererNativeGpuData *cursor_renderer_gpu_data = + meta_cursor_renderer_native_gpu_data_from_gpu (gpu_kms); + + g_warning ("Failed to set hardware cursor (%s), " + "using OpenGL from now on", + error->message); + cursor_renderer_gpu_data->hw_cursor_broken = TRUE; +} + +static void +update_hw_cursor (MetaCursorRendererNative *native, + MetaCursorSprite *cursor_sprite) +{ + MetaCursorRendererNativePrivate *priv = + meta_cursor_renderer_native_get_instance_private (native); + MetaCursorRenderer *renderer = META_CURSOR_RENDERER (native); + MetaBackend *backend = priv->backend; + MetaBackendNative *backend_native = META_BACKEND_NATIVE (priv->backend); + MetaKms *kms = meta_backend_native_get_kms (backend_native); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaKmsUpdate *kms_update; + GList *logical_monitors; + GList *l; + graphene_rect_t rect; + gboolean painted = FALSE; + g_autoptr (MetaKmsFeedback) feedback = NULL; + + kms_update = meta_kms_ensure_pending_update (kms); + + if (cursor_sprite) + rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite); + else + rect = GRAPHENE_RECT_INIT_ZERO; + + logical_monitors = + meta_monitor_manager_get_logical_monitors (monitor_manager); + for (l = logical_monitors; l; l = l->next) + { + MetaLogicalMonitor *logical_monitor = l->data; + UpdateCrtcCursorData data; + GList *monitors; + GList *k; + + data = (UpdateCrtcCursorData) { + .in_cursor_renderer_native = native, + .in_logical_monitor = logical_monitor, + .in_local_cursor_rect = (graphene_rect_t) { + .origin = { + .x = rect.origin.x - logical_monitor->rect.x, + .y = rect.origin.y - logical_monitor->rect.y + }, + .size = rect.size + }, + .in_cursor_sprite = cursor_sprite, + .in_kms_update = kms_update, + }; + + monitors = meta_logical_monitor_get_monitors (logical_monitor); + for (k = monitors; k; k = k->next) + { + MetaMonitor *monitor = k->data; + MetaMonitorMode *monitor_mode; + + monitor_mode = meta_monitor_get_current_mode (monitor); + meta_monitor_mode_foreach_crtc (monitor, monitor_mode, + update_monitor_crtc_cursor, + &data, + NULL); + } + + painted = painted || data.out_painted; + } + + feedback = meta_kms_post_pending_update_sync (kms); + if (meta_kms_feedback_get_result (feedback) != META_KMS_FEEDBACK_PASSED) + { + for (l = meta_kms_feedback_get_failed_planes (feedback); l; l = l->next) + { + MetaKmsPlaneFeedback *plane_feedback = l->data; + + if (!g_error_matches (plane_feedback->error, + G_IO_ERROR, + G_IO_ERROR_PERMISSION_DENIED)) + { + disable_hw_cursor_for_crtc (plane_feedback->crtc, + plane_feedback->error); + } + } + + priv->has_hw_cursor = FALSE; + } + + priv->hw_state_invalidated = FALSE; + + if (painted) + meta_cursor_renderer_emit_painted (renderer, cursor_sprite); +} + +static gboolean +has_valid_cursor_sprite_gbm_bo (MetaCursorSprite *cursor_sprite, + MetaGpuKms *gpu_kms) +{ + MetaCursorNativePrivate *cursor_priv; + MetaCursorNativeGpuState *cursor_gpu_state; + + cursor_priv = get_cursor_priv (cursor_sprite); + if (!cursor_priv) + return FALSE; + + cursor_gpu_state = get_cursor_gpu_state (cursor_priv, gpu_kms); + if (!cursor_gpu_state) + return FALSE; + + switch (cursor_gpu_state->pending_bo_state) + { + case META_CURSOR_GBM_BO_STATE_NONE: + return get_active_cursor_sprite_gbm_bo (cursor_gpu_state) != NULL; + case META_CURSOR_GBM_BO_STATE_SET: + return TRUE; + case META_CURSOR_GBM_BO_STATE_INVALIDATED: + return FALSE; + } + + g_assert_not_reached (); + + return FALSE; +} + +static void +set_can_preprocess (MetaCursorSprite *cursor_sprite, + float scale, + MetaMonitorTransform transform) +{ + MetaCursorNativePrivate *cursor_priv = get_cursor_priv (cursor_sprite); + + cursor_priv->preprocess_state.current_relative_scale = scale; + cursor_priv->preprocess_state.current_relative_transform = transform; + cursor_priv->preprocess_state.can_preprocess = TRUE; + + invalidate_cursor_gpu_state (cursor_sprite); +} + +static void +unset_can_preprocess (MetaCursorSprite *cursor_sprite) +{ + MetaCursorNativePrivate *cursor_priv = get_cursor_priv (cursor_sprite); + + memset (&cursor_priv->preprocess_state, + 0, + sizeof (cursor_priv->preprocess_state)); + cursor_priv->preprocess_state.can_preprocess = FALSE; + + invalidate_cursor_gpu_state (cursor_sprite); +} + +static gboolean +get_can_preprocess (MetaCursorSprite *cursor_sprite) +{ + MetaCursorNativePrivate *cursor_priv = get_cursor_priv (cursor_sprite); + + return cursor_priv->preprocess_state.can_preprocess; +} + +static float +get_current_relative_scale (MetaCursorSprite *cursor_sprite) +{ + MetaCursorNativePrivate *cursor_priv = get_cursor_priv (cursor_sprite); + + return cursor_priv->preprocess_state.current_relative_scale; +} + +static MetaMonitorTransform +get_current_relative_transform (MetaCursorSprite *cursor_sprite) +{ + MetaCursorNativePrivate *cursor_priv = get_cursor_priv (cursor_sprite); + + return cursor_priv->preprocess_state.current_relative_transform; +} + +static void +has_cursor_plane (MetaLogicalMonitor *logical_monitor, + MetaMonitor *monitor, + MetaOutput *output, + MetaCrtc *crtc, + gpointer user_data) +{ + gboolean *has_cursor_planes = user_data; + MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc); + MetaKmsDevice *kms_device = meta_kms_crtc_get_device (kms_crtc); + + *has_cursor_planes &= !!meta_kms_device_get_cursor_plane_for (kms_device, + kms_crtc); +} + +static gboolean +crtcs_has_cursor_planes (MetaCursorRenderer *renderer, + MetaCursorSprite *cursor_sprite) +{ + MetaCursorRendererNative *cursor_renderer_native = + META_CURSOR_RENDERER_NATIVE (renderer); + MetaCursorRendererNativePrivate *priv = + meta_cursor_renderer_native_get_instance_private (cursor_renderer_native); + MetaBackend *backend = priv->backend; + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + GList *logical_monitors; + GList *l; + graphene_rect_t cursor_rect; + + cursor_rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite); + + logical_monitors = + meta_monitor_manager_get_logical_monitors (monitor_manager); + for (l = logical_monitors; l; l = l->next) + { + MetaLogicalMonitor *logical_monitor = l->data; + MetaRectangle logical_monitor_layout; + graphene_rect_t logical_monitor_rect; + gboolean has_cursor_planes; + + logical_monitor_layout = + meta_logical_monitor_get_layout (logical_monitor); + logical_monitor_rect = + meta_rectangle_to_graphene_rect (&logical_monitor_layout); + + if (!graphene_rect_intersection (&cursor_rect, &logical_monitor_rect, + NULL)) + continue; + + has_cursor_planes = TRUE; + meta_logical_monitor_foreach_crtc (logical_monitor, + has_cursor_plane, + &has_cursor_planes); + if (!has_cursor_planes) + return FALSE; + } + + return TRUE; +} + +static gboolean +get_common_crtc_sprite_scale_for_logical_monitors (MetaCursorRenderer *renderer, + MetaCursorSprite *cursor_sprite, + float *out_scale) +{ + MetaCursorRendererNative *cursor_renderer_native = + META_CURSOR_RENDERER_NATIVE (renderer); + MetaCursorRendererNativePrivate *priv = + meta_cursor_renderer_native_get_instance_private (cursor_renderer_native); + MetaBackend *backend = priv->backend; + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + graphene_rect_t cursor_rect; + float scale = 1.0; + gboolean has_visible_crtc_sprite = FALSE; + GList *logical_monitors; + GList *l; + + cursor_rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite); + + logical_monitors = + meta_monitor_manager_get_logical_monitors (monitor_manager); + + for (l = logical_monitors; l; l = l->next) + { + MetaLogicalMonitor *logical_monitor = l->data; + graphene_rect_t logical_monitor_rect = + meta_rectangle_to_graphene_rect (&logical_monitor->rect); + float tmp_scale; + + if (!graphene_rect_intersection (&cursor_rect, + &logical_monitor_rect, + NULL)) + continue; + + tmp_scale = + calculate_cursor_crtc_sprite_scale (cursor_sprite, logical_monitor); + + if (has_visible_crtc_sprite && scale != tmp_scale) + return FALSE; + + has_visible_crtc_sprite = TRUE; + scale = tmp_scale; + } + + if (!has_visible_crtc_sprite) + return FALSE; + + *out_scale = scale; + return TRUE; +} + +static gboolean +get_common_crtc_sprite_transform_for_logical_monitors (MetaCursorRenderer *renderer, + MetaCursorSprite *cursor_sprite, + MetaMonitorTransform *out_transform) +{ + MetaCursorRendererNative *cursor_renderer_native = + META_CURSOR_RENDERER_NATIVE (renderer); + MetaCursorRendererNativePrivate *priv = + meta_cursor_renderer_native_get_instance_private (cursor_renderer_native); + MetaBackend *backend = priv->backend; + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + graphene_rect_t cursor_rect; + MetaMonitorTransform transform = META_MONITOR_TRANSFORM_NORMAL; + gboolean has_visible_crtc_sprite = FALSE; + GList *logical_monitors; + GList *l; + + cursor_rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite); + + logical_monitors = + meta_monitor_manager_get_logical_monitors (monitor_manager); + + for (l = logical_monitors; l; l = l->next) + { + MetaLogicalMonitor *logical_monitor = l->data; + graphene_rect_t logical_monitor_rect = + meta_rectangle_to_graphene_rect (&logical_monitor->rect); + MetaMonitorTransform logical_transform, tmp_transform; + GList *monitors, *l_mon; + + if (!graphene_rect_intersection (&cursor_rect, + &logical_monitor_rect, + NULL)) + continue; + + logical_transform = meta_logical_monitor_get_transform (logical_monitor); + monitors = meta_logical_monitor_get_monitors (logical_monitor); + for (l_mon = monitors; l_mon; l_mon = l_mon->next) + { + MetaMonitor *monitor = l_mon->data; + + tmp_transform = meta_monitor_transform_relative_transform ( + meta_cursor_sprite_get_texture_transform (cursor_sprite), + meta_monitor_logical_to_crtc_transform (monitor, logical_transform)); + + if (has_visible_crtc_sprite && transform != tmp_transform) + return FALSE; + + has_visible_crtc_sprite = TRUE; + transform = tmp_transform; + } + } + + if (!has_visible_crtc_sprite) + return FALSE; + + *out_transform = transform; + return TRUE; +} + +static gboolean +should_have_hw_cursor (MetaCursorRenderer *renderer, + MetaCursorSprite *cursor_sprite, + GList *gpus) +{ + CoglTexture *texture; + MetaMonitorTransform transform; + float scale; + GList *l; + + if (!cursor_sprite) + return FALSE; + + if (meta_cursor_renderer_is_hw_cursors_inhibited (renderer, + cursor_sprite)) + return FALSE; + + for (l = gpus; l; l = l->next) + { + MetaGpuKms *gpu_kms = l->data; + MetaCursorRendererNativeGpuData *cursor_renderer_gpu_data; + + cursor_renderer_gpu_data = + meta_cursor_renderer_native_gpu_data_from_gpu (gpu_kms); + if (!cursor_renderer_gpu_data) + return FALSE; + + if (cursor_renderer_gpu_data->hw_cursor_broken) + return FALSE; + + if (!has_valid_cursor_sprite_gbm_bo (cursor_sprite, gpu_kms)) + return FALSE; + } + + if (!crtcs_has_cursor_planes (renderer, cursor_sprite)) + return FALSE; + + texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite); + if (!texture) + return FALSE; + + if (!get_common_crtc_sprite_scale_for_logical_monitors (renderer, + cursor_sprite, + &scale)) + return FALSE; + + if (!get_common_crtc_sprite_transform_for_logical_monitors (renderer, + cursor_sprite, + &transform)) + return FALSE; + + if (G_APPROX_VALUE (scale, 1.f, FLT_EPSILON) && + transform == META_MONITOR_TRANSFORM_NORMAL) + return TRUE; + else + return get_can_preprocess (cursor_sprite); + + return TRUE; +} + +static gboolean +meta_cursor_renderer_native_update_animation (MetaCursorRendererNative *native) +{ + MetaCursorRendererNativePrivate *priv = + meta_cursor_renderer_native_get_instance_private (native); + MetaCursorRenderer *renderer = META_CURSOR_RENDERER (native); + MetaCursorSprite *cursor_sprite = meta_cursor_renderer_get_cursor (renderer); + + priv->animation_timeout_id = 0; + meta_cursor_sprite_tick_frame (cursor_sprite); + meta_cursor_renderer_force_update (renderer); + + return G_SOURCE_REMOVE; +} + +static void +maybe_schedule_cursor_sprite_animation_frame (MetaCursorRendererNative *native, + MetaCursorSprite *cursor_sprite) +{ + MetaCursorRendererNativePrivate *priv = + meta_cursor_renderer_native_get_instance_private (native); + gboolean cursor_change; + guint delay; + + cursor_change = cursor_sprite != priv->last_cursor; + priv->last_cursor = cursor_sprite; + + if (!cursor_change && priv->animation_timeout_id) + return; + + g_clear_handle_id (&priv->animation_timeout_id, g_source_remove); + + if (cursor_sprite && meta_cursor_sprite_is_animated (cursor_sprite)) + { + delay = meta_cursor_sprite_get_current_frame_time (cursor_sprite); + + if (delay == 0) + return; + + priv->animation_timeout_id = + g_timeout_add (delay, + (GSourceFunc) meta_cursor_renderer_native_update_animation, + native); + g_source_set_name_by_id (priv->animation_timeout_id, + "[mutter] meta_cursor_renderer_native_update_animation"); + } +} + +static GList * +calculate_cursor_sprite_gpus (MetaCursorRenderer *renderer, + MetaCursorSprite *cursor_sprite) +{ + MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer); + MetaCursorRendererNativePrivate *priv = + meta_cursor_renderer_native_get_instance_private (native); + MetaBackend *backend = priv->backend; + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + GList *gpus = NULL; + GList *logical_monitors; + GList *l; + graphene_rect_t cursor_rect; + + cursor_rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite); + + logical_monitors = + meta_monitor_manager_get_logical_monitors (monitor_manager); + for (l = logical_monitors; l; l = l->next) + { + MetaLogicalMonitor *logical_monitor = l->data; + MetaRectangle logical_monitor_layout; + graphene_rect_t logical_monitor_rect; + GList *monitors, *l_mon; + + logical_monitor_layout = + meta_logical_monitor_get_layout (logical_monitor); + logical_monitor_rect = + meta_rectangle_to_graphene_rect (&logical_monitor_layout); + + if (!graphene_rect_intersection (&cursor_rect, &logical_monitor_rect, + NULL)) + continue; + + monitors = meta_logical_monitor_get_monitors (logical_monitor); + for (l_mon = monitors; l_mon; l_mon = l_mon->next) + { + MetaMonitor *monitor = l_mon->data; + MetaGpu *gpu; + + gpu = meta_monitor_get_gpu (monitor); + if (!g_list_find (gpus, gpu)) + gpus = g_list_prepend (gpus, gpu); + } + } + + return gpus; +} + +static gboolean +meta_cursor_renderer_native_update_cursor (MetaCursorRenderer *renderer, + MetaCursorSprite *cursor_sprite) +{ + MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer); + MetaCursorRendererNativePrivate *priv = + meta_cursor_renderer_native_get_instance_private (native); + g_autoptr (GList) gpus = NULL; + + if (cursor_sprite) + { + meta_cursor_sprite_realize_texture (cursor_sprite); + gpus = calculate_cursor_sprite_gpus (renderer, cursor_sprite); + realize_cursor_sprite (renderer, cursor_sprite, gpus); + } + + maybe_schedule_cursor_sprite_animation_frame (native, cursor_sprite); + + priv->has_hw_cursor = should_have_hw_cursor (renderer, cursor_sprite, gpus); + update_hw_cursor (native, cursor_sprite); + + return (priv->has_hw_cursor || + !cursor_sprite || + !meta_cursor_sprite_get_cogl_texture (cursor_sprite)); +} + +static void +unset_crtc_cursor_renderer_privates (MetaGpu *gpu, + struct gbm_bo *bo) +{ + GList *l; + + for (l = meta_gpu_get_crtcs (gpu); l; l = l->next) + { + MetaCrtc *crtc = l->data; + + if (bo == crtc->cursor_renderer_private) + crtc->cursor_renderer_private = NULL; + } +} + +static void +cursor_gpu_state_free (MetaCursorNativeGpuState *cursor_gpu_state) +{ + int i; + struct gbm_bo *active_bo; + + active_bo = get_active_cursor_sprite_gbm_bo (cursor_gpu_state); + if (active_bo) + unset_crtc_cursor_renderer_privates (cursor_gpu_state->gpu, active_bo); + + for (i = 0; i < HW_CURSOR_BUFFER_COUNT; i++) + g_clear_pointer (&cursor_gpu_state->bos[i], gbm_bo_destroy); + g_free (cursor_gpu_state); +} + +static MetaCursorNativeGpuState * +get_cursor_gpu_state (MetaCursorNativePrivate *cursor_priv, + MetaGpuKms *gpu_kms) +{ + return g_hash_table_lookup (cursor_priv->gpu_states, gpu_kms); +} + +static MetaCursorNativeGpuState * +ensure_cursor_gpu_state (MetaCursorNativePrivate *cursor_priv, + MetaGpuKms *gpu_kms) +{ + MetaCursorNativeGpuState *cursor_gpu_state; + + cursor_gpu_state = get_cursor_gpu_state (cursor_priv, gpu_kms); + if (cursor_gpu_state) + return cursor_gpu_state; + + cursor_gpu_state = g_new0 (MetaCursorNativeGpuState, 1); + cursor_gpu_state->gpu = META_GPU (gpu_kms); + g_hash_table_insert (cursor_priv->gpu_states, gpu_kms, cursor_gpu_state); + + return cursor_gpu_state; +} + +static void +invalidate_cursor_gpu_state (MetaCursorSprite *cursor_sprite) +{ + MetaCursorNativePrivate *cursor_priv = get_cursor_priv (cursor_sprite); + GHashTableIter iter; + MetaCursorNativeGpuState *cursor_gpu_state; + + g_hash_table_iter_init (&iter, cursor_priv->gpu_states); + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &cursor_gpu_state)) + { + guint pending_bo; + pending_bo = get_pending_cursor_sprite_gbm_bo_index (cursor_gpu_state); + g_clear_pointer (&cursor_gpu_state->bos[pending_bo], + gbm_bo_destroy); + cursor_gpu_state->pending_bo_state = META_CURSOR_GBM_BO_STATE_INVALIDATED; + } +} + +static void +on_cursor_sprite_texture_changed (MetaCursorSprite *cursor_sprite) +{ + invalidate_cursor_gpu_state (cursor_sprite); +} + +static void +cursor_priv_free (MetaCursorNativePrivate *cursor_priv) +{ + g_hash_table_destroy (cursor_priv->gpu_states); + g_free (cursor_priv); +} + +static MetaCursorNativePrivate * +get_cursor_priv (MetaCursorSprite *cursor_sprite) +{ + return g_object_get_qdata (G_OBJECT (cursor_sprite), quark_cursor_sprite); +} + +static MetaCursorNativePrivate * +ensure_cursor_priv (MetaCursorSprite *cursor_sprite) +{ + MetaCursorNativePrivate *cursor_priv; + + cursor_priv = get_cursor_priv (cursor_sprite); + if (cursor_priv) + return cursor_priv; + + cursor_priv = g_new0 (MetaCursorNativePrivate, 1); + cursor_priv->gpu_states = + g_hash_table_new_full (g_direct_hash, + g_direct_equal, + NULL, + (GDestroyNotify) cursor_gpu_state_free); + g_object_set_qdata_full (G_OBJECT (cursor_sprite), + quark_cursor_sprite, + cursor_priv, + (GDestroyNotify) cursor_priv_free); + + g_signal_connect (cursor_sprite, "texture-changed", + G_CALLBACK (on_cursor_sprite_texture_changed), NULL); + + unset_can_preprocess (cursor_sprite); + + return cursor_priv; +} + +static void +load_cursor_sprite_gbm_buffer_for_gpu (MetaCursorRendererNative *native, + MetaGpuKms *gpu_kms, + MetaCursorSprite *cursor_sprite, + uint8_t *pixels, + uint width, + uint height, + int rowstride, + uint32_t gbm_format) +{ + uint64_t cursor_width, cursor_height; + MetaCursorRendererNativeGpuData *cursor_renderer_gpu_data; + struct gbm_device *gbm_device; + + cursor_renderer_gpu_data = + meta_cursor_renderer_native_gpu_data_from_gpu (gpu_kms); + if (!cursor_renderer_gpu_data) + return; + + cursor_width = (uint64_t) cursor_renderer_gpu_data->cursor_width; + cursor_height = (uint64_t) cursor_renderer_gpu_data->cursor_height; + + if (width > cursor_width || height > cursor_height) + { + meta_warning ("Invalid theme cursor size (must be at most %ux%u)\n", + (unsigned int)cursor_width, (unsigned int)cursor_height); + return; + } + + gbm_device = meta_gbm_device_from_gpu (gpu_kms); + if (gbm_device_is_format_supported (gbm_device, gbm_format, + GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE)) + { + struct gbm_bo *bo; + uint8_t buf[4 * cursor_width * cursor_height]; + uint i; + + bo = gbm_bo_create (gbm_device, cursor_width, cursor_height, + gbm_format, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE); + if (!bo) + { + meta_warning ("Failed to allocate HW cursor buffer\n"); + return; + } + + memset (buf, 0, sizeof(buf)); + for (i = 0; i < height; i++) + memcpy (buf + i * 4 * cursor_width, pixels + i * rowstride, width * 4); + if (gbm_bo_write (bo, buf, cursor_width * cursor_height * 4) != 0) + { + meta_warning ("Failed to write cursors buffer data: %s", + g_strerror (errno)); + gbm_bo_destroy (bo); + return; + } + + set_pending_cursor_sprite_gbm_bo (cursor_sprite, gpu_kms, bo); + } + else + { + meta_warning ("HW cursor for format %d not supported\n", gbm_format); + } +} + +static gboolean +is_cursor_hw_state_valid (MetaCursorSprite *cursor_sprite, + MetaGpuKms *gpu_kms) +{ + MetaCursorNativePrivate *cursor_priv; + MetaCursorNativeGpuState *cursor_gpu_state; + + cursor_priv = get_cursor_priv (cursor_sprite); + if (!cursor_priv) + return FALSE; + + cursor_gpu_state = get_cursor_gpu_state (cursor_priv, gpu_kms); + if (!cursor_gpu_state) + return FALSE; + + switch (cursor_gpu_state->pending_bo_state) + { + case META_CURSOR_GBM_BO_STATE_SET: + case META_CURSOR_GBM_BO_STATE_NONE: + return TRUE; + case META_CURSOR_GBM_BO_STATE_INVALIDATED: + return FALSE; + } + + g_assert_not_reached (); + return FALSE; +} + +static gboolean +is_cursor_scale_and_transform_valid (MetaCursorRenderer *renderer, + MetaCursorSprite *cursor_sprite) +{ + MetaMonitorTransform transform; + float scale; + + if (!get_common_crtc_sprite_scale_for_logical_monitors (renderer, + cursor_sprite, + &scale)) + return FALSE; + + if (!get_common_crtc_sprite_transform_for_logical_monitors (renderer, + cursor_sprite, + &transform)) + return FALSE; + + return (scale == get_current_relative_scale (cursor_sprite) && + transform == get_current_relative_transform (cursor_sprite)); +} + +static cairo_surface_t * +scale_and_transform_cursor_sprite_cpu (uint8_t *pixels, + int width, + int height, + int rowstride, + float scale, + MetaMonitorTransform transform) +{ + cairo_t *cr; + cairo_surface_t *source_surface; + cairo_surface_t *target_surface; + int image_width; + int image_height; + + image_width = ceilf (width * scale); + image_height = ceilf (height * scale); + + target_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, + image_width, + image_height); + + cr = cairo_create (target_surface); + if (transform != META_MONITOR_TRANSFORM_NORMAL) + { + cairo_translate (cr, 0.5 * image_width, 0.5 * image_height); + switch (transform) + { + case META_MONITOR_TRANSFORM_90: + cairo_rotate (cr, M_PI * 1.5); + break; + case META_MONITOR_TRANSFORM_180: + cairo_rotate (cr, M_PI); + break; + case META_MONITOR_TRANSFORM_270: + cairo_rotate (cr, M_PI * 0.5); + break; + case META_MONITOR_TRANSFORM_FLIPPED: + cairo_scale (cr, 1, -1); + break; + case META_MONITOR_TRANSFORM_FLIPPED_90: + cairo_rotate (cr, M_PI * 1.5); + cairo_scale (cr, -1, 1); + break; + case META_MONITOR_TRANSFORM_FLIPPED_180: + cairo_rotate (cr, M_PI); + cairo_scale (cr, 1, -1); + break; + case META_MONITOR_TRANSFORM_FLIPPED_270: + cairo_rotate (cr, M_PI * 0.5); + cairo_scale (cr, -1, 1); + break; + case META_MONITOR_TRANSFORM_NORMAL: + g_assert_not_reached (); + } + cairo_translate (cr, -0.5 * image_width, -0.5 * image_height); + } + cairo_scale (cr, scale, scale); + + source_surface = cairo_image_surface_create_for_data (pixels, + CAIRO_FORMAT_ARGB32, + width, + height, + rowstride); + + cairo_set_source_surface (cr, source_surface, 0, 0); + cairo_paint (cr); + cairo_destroy (cr); + cairo_surface_destroy (source_surface); + + return target_surface; +} + +static void +load_scaled_and_transformed_cursor_sprite (MetaCursorRendererNative *native, + MetaGpuKms *gpu_kms, + MetaCursorSprite *cursor_sprite, + float relative_scale, + MetaMonitorTransform relative_transform, + uint8_t *data, + int width, + int height, + int rowstride, + uint32_t gbm_format) +{ + if (!G_APPROX_VALUE (relative_scale, 1.f, FLT_EPSILON) || + relative_transform != META_MONITOR_TRANSFORM_NORMAL) + { + cairo_surface_t *surface; + + surface = scale_and_transform_cursor_sprite_cpu (data, + width, + height, + rowstride, + relative_scale, + relative_transform); + + load_cursor_sprite_gbm_buffer_for_gpu (native, + gpu_kms, + cursor_sprite, + cairo_image_surface_get_data (surface), + cairo_image_surface_get_width (surface), + cairo_image_surface_get_width (surface), + cairo_image_surface_get_stride (surface), + gbm_format); + + cairo_surface_destroy (surface); + } + else + { + load_cursor_sprite_gbm_buffer_for_gpu (native, + gpu_kms, + cursor_sprite, + data, + width, + height, + rowstride, + gbm_format); + } +} + +#ifdef HAVE_WAYLAND +static void +realize_cursor_sprite_from_wl_buffer_for_gpu (MetaCursorRenderer *renderer, + MetaGpuKms *gpu_kms, + MetaCursorSpriteWayland *sprite_wayland) +{ + MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer); + MetaCursorSprite *cursor_sprite = META_CURSOR_SPRITE (sprite_wayland); + MetaCursorRendererNativeGpuData *cursor_renderer_gpu_data; + uint64_t cursor_width, cursor_height; + CoglTexture *texture; + uint width, height; + MetaWaylandBuffer *buffer; + struct wl_resource *buffer_resource; + struct wl_shm_buffer *shm_buffer; + + cursor_renderer_gpu_data = + meta_cursor_renderer_native_gpu_data_from_gpu (gpu_kms); + if (!cursor_renderer_gpu_data || cursor_renderer_gpu_data->hw_cursor_broken) + return; + + if (is_cursor_hw_state_valid (cursor_sprite, gpu_kms) && + is_cursor_scale_and_transform_valid (renderer, cursor_sprite)) + return; + + buffer = meta_cursor_sprite_wayland_get_buffer (sprite_wayland); + if (!buffer) + return; + + buffer_resource = meta_wayland_buffer_get_resource (buffer); + if (!buffer_resource) + return; + + ensure_cursor_priv (cursor_sprite); + + shm_buffer = wl_shm_buffer_get (buffer_resource); + if (shm_buffer) + { + int rowstride = wl_shm_buffer_get_stride (shm_buffer); + uint8_t *buffer_data; + float relative_scale; + MetaMonitorTransform relative_transform; + uint32_t gbm_format; + + if (!get_common_crtc_sprite_scale_for_logical_monitors (renderer, + cursor_sprite, + &relative_scale)) + { + unset_can_preprocess (cursor_sprite); + return; + } + + if (!get_common_crtc_sprite_transform_for_logical_monitors (renderer, + cursor_sprite, + &relative_transform)) + { + unset_can_preprocess (cursor_sprite); + return; + } + + set_can_preprocess (cursor_sprite, + relative_scale, + relative_transform); + + wl_shm_buffer_begin_access (shm_buffer); + buffer_data = wl_shm_buffer_get_data (shm_buffer); + + width = wl_shm_buffer_get_width (shm_buffer); + height = wl_shm_buffer_get_height (shm_buffer); + + switch (wl_shm_buffer_get_format (shm_buffer)) + { + case WL_SHM_FORMAT_ARGB8888: + gbm_format = GBM_FORMAT_ARGB8888; + break; + case WL_SHM_FORMAT_XRGB8888: + gbm_format = GBM_FORMAT_XRGB8888; + break; + default: + g_warn_if_reached (); + gbm_format = GBM_FORMAT_ARGB8888; + } + + load_scaled_and_transformed_cursor_sprite (native, + gpu_kms, + cursor_sprite, + relative_scale, + relative_transform, + buffer_data, + width, + height, + rowstride, + gbm_format); + + wl_shm_buffer_end_access (shm_buffer); + } + else + { + struct gbm_device *gbm_device; + struct gbm_bo *bo; + + /* HW cursors have a predefined size (at least 64x64), which usually is + * bigger than cursor theme size, so themed cursors must be padded with + * transparent pixels to fill the overlay. This is trivial if we have CPU + * access to the data, but it's not possible if the buffer is in GPU + * memory (and possibly tiled too), so if we don't get the right size, we + * fallback to GL. */ + cursor_width = (uint64_t) cursor_renderer_gpu_data->cursor_width; + cursor_height = (uint64_t) cursor_renderer_gpu_data->cursor_height; + + texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite); + width = cogl_texture_get_width (texture); + height = cogl_texture_get_height (texture); + + if (width != cursor_width || height != cursor_height) + { + meta_warning ("Invalid cursor size (must be 64x64), falling back to software (GL) cursors\n"); + return; + } + + gbm_device = meta_gbm_device_from_gpu (gpu_kms); + bo = gbm_bo_import (gbm_device, + GBM_BO_IMPORT_WL_BUFFER, + buffer, + GBM_BO_USE_CURSOR); + if (!bo) + { + meta_warning ("Importing HW cursor from wl_buffer failed\n"); + return; + } + + unset_can_preprocess (cursor_sprite); + + set_pending_cursor_sprite_gbm_bo (cursor_sprite, gpu_kms, bo); + } +} +#endif + +static void +realize_cursor_sprite_from_xcursor_for_gpu (MetaCursorRenderer *renderer, + MetaGpuKms *gpu_kms, + MetaCursorSpriteXcursor *sprite_xcursor) +{ + MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer); + MetaCursorRendererNativeGpuData *cursor_renderer_gpu_data; + MetaCursorSprite *cursor_sprite = META_CURSOR_SPRITE (sprite_xcursor); + XcursorImage *xc_image; + float relative_scale; + MetaMonitorTransform relative_transform; + + ensure_cursor_priv (cursor_sprite); + + cursor_renderer_gpu_data = + meta_cursor_renderer_native_gpu_data_from_gpu (gpu_kms); + if (!cursor_renderer_gpu_data || cursor_renderer_gpu_data->hw_cursor_broken) + return; + + if (is_cursor_hw_state_valid (cursor_sprite, gpu_kms) && + is_cursor_scale_and_transform_valid (renderer, cursor_sprite)) + return; + + if (!get_common_crtc_sprite_scale_for_logical_monitors (renderer, + cursor_sprite, + &relative_scale)) + { + unset_can_preprocess (cursor_sprite); + return; + } + + if (!get_common_crtc_sprite_transform_for_logical_monitors (renderer, + cursor_sprite, + &relative_transform)) + { + unset_can_preprocess (cursor_sprite); + return; + } + + set_can_preprocess (cursor_sprite, + relative_scale, + relative_transform); + + xc_image = meta_cursor_sprite_xcursor_get_current_image (sprite_xcursor); + + load_scaled_and_transformed_cursor_sprite (native, + gpu_kms, + cursor_sprite, + relative_scale, + relative_transform, + (uint8_t *) xc_image->pixels, + xc_image->width, + xc_image->height, + xc_image->width * 4, + GBM_FORMAT_ARGB8888); +} + +static void +realize_cursor_sprite_for_gpu (MetaCursorRenderer *renderer, + MetaGpuKms *gpu_kms, + MetaCursorSprite *cursor_sprite) +{ + if (META_IS_CURSOR_SPRITE_XCURSOR (cursor_sprite)) + { + MetaCursorSpriteXcursor *sprite_xcursor = + META_CURSOR_SPRITE_XCURSOR (cursor_sprite); + + realize_cursor_sprite_from_xcursor_for_gpu (renderer, + gpu_kms, + sprite_xcursor); + } +#ifdef HAVE_WAYLAND + else if (META_IS_CURSOR_SPRITE_WAYLAND (cursor_sprite)) + { + MetaCursorSpriteWayland *sprite_wayland = + META_CURSOR_SPRITE_WAYLAND (cursor_sprite); + + realize_cursor_sprite_from_wl_buffer_for_gpu (renderer, + gpu_kms, + sprite_wayland); + } +#endif +} + +static void +realize_cursor_sprite (MetaCursorRenderer *renderer, + MetaCursorSprite *cursor_sprite, + GList *gpus) +{ + GList *l; + + for (l = gpus; l; l = l->next) + { + MetaGpuKms *gpu_kms = l->data; + + realize_cursor_sprite_for_gpu (renderer, gpu_kms, cursor_sprite); + } +} + +static void +meta_cursor_renderer_native_class_init (MetaCursorRendererNativeClass *klass) +{ + MetaCursorRendererClass *renderer_class = META_CURSOR_RENDERER_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_cursor_renderer_native_finalize; + renderer_class->update_cursor = meta_cursor_renderer_native_update_cursor; + + quark_cursor_sprite = g_quark_from_static_string ("-meta-cursor-native"); + quark_cursor_renderer_native_gpu_data = + g_quark_from_static_string ("-meta-cursor-renderer-native-gpu-data"); +} + +static void +force_update_hw_cursor (MetaCursorRendererNative *native) +{ + MetaCursorRenderer *renderer = META_CURSOR_RENDERER (native); + MetaCursorRendererNativePrivate *priv = + meta_cursor_renderer_native_get_instance_private (native); + + priv->hw_state_invalidated = TRUE; + meta_cursor_renderer_force_update (renderer); +} + +static void +on_monitors_changed (MetaMonitorManager *monitors, + MetaCursorRendererNative *native) +{ + force_update_hw_cursor (native); +} + +static void +init_hw_cursor_support_for_gpu (MetaGpuKms *gpu_kms) +{ + MetaKmsDevice *kms_device = meta_gpu_kms_get_kms_device (gpu_kms); + MetaCursorRendererNativeGpuData *cursor_renderer_gpu_data; + struct gbm_device *gbm_device; + uint64_t width, height; + + gbm_device = meta_gbm_device_from_gpu (gpu_kms); + if (!gbm_device) + return; + + cursor_renderer_gpu_data = + meta_create_cursor_renderer_native_gpu_data (gpu_kms); + + if (!meta_kms_device_get_cursor_size (kms_device, &width, &height)) + { + width = 64; + height = 64; + } + + cursor_renderer_gpu_data->cursor_width = width; + cursor_renderer_gpu_data->cursor_height = height; +} + +static void +on_gpu_added_for_cursor (MetaBackend *backend, + MetaGpuKms *gpu_kms) +{ + init_hw_cursor_support_for_gpu (gpu_kms); +} + +static void +init_hw_cursor_support (MetaCursorRendererNative *cursor_renderer_native) +{ + MetaCursorRendererNativePrivate *priv = + meta_cursor_renderer_native_get_instance_private (cursor_renderer_native); + GList *gpus; + GList *l; + + gpus = meta_backend_get_gpus (priv->backend); + for (l = gpus; l; l = l->next) + { + MetaGpuKms *gpu_kms = l->data; + + init_hw_cursor_support_for_gpu (gpu_kms); + } +} + +MetaCursorRendererNative * +meta_cursor_renderer_native_new (MetaBackend *backend) +{ + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaCursorRendererNative *cursor_renderer_native; + MetaCursorRendererNativePrivate *priv; + + cursor_renderer_native = + g_object_new (META_TYPE_CURSOR_RENDERER_NATIVE, NULL); + priv = + meta_cursor_renderer_native_get_instance_private (cursor_renderer_native); + + g_signal_connect_object (monitor_manager, "monitors-changed-internal", + G_CALLBACK (on_monitors_changed), + cursor_renderer_native, 0); + g_signal_connect (backend, "gpu-added", + G_CALLBACK (on_gpu_added_for_cursor), NULL); + + priv->backend = backend; + priv->hw_state_invalidated = TRUE; + + init_hw_cursor_support (cursor_renderer_native); + + return cursor_renderer_native; +} + +static void +meta_cursor_renderer_native_init (MetaCursorRendererNative *native) +{ +} diff --git a/src/backends/native/meta-cursor-renderer-native.h b/src/backends/native/meta-cursor-renderer-native.h new file mode 100644 index 000000000..d3560e48f --- /dev/null +++ b/src/backends/native/meta-cursor-renderer-native.h @@ -0,0 +1,38 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jasper St. Pierre <jstpierre@mecheye.net> + */ + +#ifndef META_CURSOR_RENDERER_NATIVE_H +#define META_CURSOR_RENDERER_NATIVE_H + +#include "backends/meta-cursor-renderer.h" +#include "meta/meta-backend.h" + +#define META_TYPE_CURSOR_RENDERER_NATIVE (meta_cursor_renderer_native_get_type ()) +G_DECLARE_FINAL_TYPE (MetaCursorRendererNative, meta_cursor_renderer_native, + META, CURSOR_RENDERER_NATIVE, + MetaCursorRenderer) + +MetaCursorRendererNative * meta_cursor_renderer_native_new (MetaBackend *backend); + +#endif /* META_CURSOR_RENDERER_NATIVE_H */ diff --git a/src/backends/native/meta-drm-buffer-dumb.c b/src/backends/native/meta-drm-buffer-dumb.c new file mode 100644 index 000000000..ccf5747f5 --- /dev/null +++ b/src/backends/native/meta-drm-buffer-dumb.c @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2011 Intel Corporation. + * Copyright (C) 2016 Red Hat + * Copyright (C) 2018 DisplayLink (UK) Ltd. + * Copyright (C) 2018 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#include "config.h" + +#include "backends/native/meta-drm-buffer-dumb.h" + +struct _MetaDrmBufferDumb +{ + MetaDrmBuffer parent; + + uint32_t fb_id; +}; + +G_DEFINE_TYPE (MetaDrmBufferDumb, meta_drm_buffer_dumb, META_TYPE_DRM_BUFFER) + +MetaDrmBufferDumb * +meta_drm_buffer_dumb_new (uint32_t dumb_fb_id) +{ + MetaDrmBufferDumb *buffer_dumb; + + buffer_dumb = g_object_new (META_TYPE_DRM_BUFFER_DUMB, NULL); + buffer_dumb->fb_id = dumb_fb_id; + + return buffer_dumb; +} + +static uint32_t +meta_drm_buffer_dumb_get_fb_id (MetaDrmBuffer *buffer) +{ + return META_DRM_BUFFER_DUMB (buffer)->fb_id; +} + +static void +meta_drm_buffer_dumb_init (MetaDrmBufferDumb *buffer_dumb) +{ +} + +static void +meta_drm_buffer_dumb_class_init (MetaDrmBufferDumbClass *klass) +{ + MetaDrmBufferClass *buffer_class = META_DRM_BUFFER_CLASS (klass); + + buffer_class->get_fb_id = meta_drm_buffer_dumb_get_fb_id; +} diff --git a/src/backends/native/meta-drm-buffer-dumb.h b/src/backends/native/meta-drm-buffer-dumb.h new file mode 100644 index 000000000..f8b733f88 --- /dev/null +++ b/src/backends/native/meta-drm-buffer-dumb.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2018 Canonical Ltd. + * Copyright (C) 2019 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#ifndef META_DRM_BUFFER_DUMB_H +#define META_DRM_BUFFER_DUMB_H + +#include "backends/native/meta-drm-buffer.h" + +#define META_TYPE_DRM_BUFFER_DUMB (meta_drm_buffer_dumb_get_type ()) +G_DECLARE_FINAL_TYPE (MetaDrmBufferDumb, + meta_drm_buffer_dumb, + META, DRM_BUFFER_DUMB, + MetaDrmBuffer) + +MetaDrmBufferDumb * meta_drm_buffer_dumb_new (uint32_t dumb_fb_id); + +#endif /* META_DRM_BUFFER_DUMB_H */ diff --git a/src/backends/native/meta-drm-buffer-gbm.c b/src/backends/native/meta-drm-buffer-gbm.c new file mode 100644 index 000000000..b446d64e1 --- /dev/null +++ b/src/backends/native/meta-drm-buffer-gbm.c @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2011 Intel Corporation. + * Copyright (C) 2016 Red Hat + * Copyright (C) 2018 DisplayLink (UK) Ltd. + * Copyright (C) 2018 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#include "config.h" + +#include "backends/native/meta-drm-buffer-gbm.h" + +#include <drm_fourcc.h> +#include <errno.h> +#include <xf86drm.h> +#include <xf86drmMode.h> + +#define INVALID_FB_ID 0U + +struct _MetaDrmBufferGbm +{ + MetaDrmBuffer parent; + + MetaGpuKms *gpu_kms; + + struct gbm_surface *surface; + + struct gbm_bo *bo; + uint32_t fb_id; +}; + +G_DEFINE_TYPE (MetaDrmBufferGbm, meta_drm_buffer_gbm, META_TYPE_DRM_BUFFER) + +struct gbm_bo * +meta_drm_buffer_gbm_get_bo (MetaDrmBufferGbm *buffer_gbm) +{ + return buffer_gbm->bo; +} + +static gboolean +acquire_swapped_buffer (MetaDrmBufferGbm *buffer_gbm, + gboolean use_modifiers, + GError **error) +{ + MetaGpuKmsFBArgs fb_args = { 0, }; + struct gbm_bo *bo; + + bo = gbm_surface_lock_front_buffer (buffer_gbm->surface); + if (!bo) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "gbm_surface_lock_front_buffer failed"); + return FALSE; + } + + if (gbm_bo_get_handle_for_plane (bo, 0).s32 == -1) + { + /* Failed to fetch handle to plane, falling back to old method */ + fb_args.strides[0] = gbm_bo_get_stride (bo); + fb_args.handles[0] = gbm_bo_get_handle (bo).u32; + fb_args.offsets[0] = 0; + fb_args.modifiers[0] = DRM_FORMAT_MOD_INVALID; + } + else + { + int i; + + for (i = 0; i < gbm_bo_get_plane_count (bo); i++) + { + fb_args.strides[i] = gbm_bo_get_stride_for_plane (bo, i); + fb_args.handles[i] = gbm_bo_get_handle_for_plane (bo, i).u32; + fb_args.offsets[i] = gbm_bo_get_offset (bo, i); + fb_args.modifiers[i] = gbm_bo_get_modifier (bo); + } + } + + fb_args.width = gbm_bo_get_width (bo); + fb_args.height = gbm_bo_get_height (bo); + fb_args.format = gbm_bo_get_format (bo); + + if (!meta_gpu_kms_add_fb (buffer_gbm->gpu_kms, + use_modifiers, + &fb_args, + &buffer_gbm->fb_id, error)) + { + gbm_surface_release_buffer (buffer_gbm->surface, bo); + return FALSE; + } + + buffer_gbm->bo = bo; + + return TRUE; +} + +MetaDrmBufferGbm * +meta_drm_buffer_gbm_new (MetaGpuKms *gpu_kms, + struct gbm_surface *gbm_surface, + gboolean use_modifiers, + GError **error) +{ + MetaDrmBufferGbm *buffer_gbm; + + buffer_gbm = g_object_new (META_TYPE_DRM_BUFFER_GBM, NULL); + buffer_gbm->gpu_kms = gpu_kms; + buffer_gbm->surface = gbm_surface; + + if (!acquire_swapped_buffer (buffer_gbm, use_modifiers, error)) + { + g_object_unref (buffer_gbm); + return NULL; + } + + return buffer_gbm; +} + +static uint32_t +meta_drm_buffer_gbm_get_fb_id (MetaDrmBuffer *buffer) +{ + return META_DRM_BUFFER_GBM (buffer)->fb_id; +} + +static void +meta_drm_buffer_gbm_finalize (GObject *object) +{ + MetaDrmBufferGbm *buffer_gbm = META_DRM_BUFFER_GBM (object); + + if (buffer_gbm->fb_id != INVALID_FB_ID) + { + int kms_fd; + + kms_fd = meta_gpu_kms_get_fd (buffer_gbm->gpu_kms); + drmModeRmFB (kms_fd, buffer_gbm->fb_id); + } + + if (buffer_gbm->bo) + gbm_surface_release_buffer (buffer_gbm->surface, buffer_gbm->bo); + + G_OBJECT_CLASS (meta_drm_buffer_gbm_parent_class)->finalize (object); +} + +static void +meta_drm_buffer_gbm_init (MetaDrmBufferGbm *buffer_gbm) +{ +} + +static void +meta_drm_buffer_gbm_class_init (MetaDrmBufferGbmClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MetaDrmBufferClass *buffer_class = META_DRM_BUFFER_CLASS (klass); + + object_class->finalize = meta_drm_buffer_gbm_finalize; + + buffer_class->get_fb_id = meta_drm_buffer_gbm_get_fb_id; +} diff --git a/src/backends/native/meta-drm-buffer-gbm.h b/src/backends/native/meta-drm-buffer-gbm.h new file mode 100644 index 000000000..b48cef06a --- /dev/null +++ b/src/backends/native/meta-drm-buffer-gbm.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2018 Canonical Ltd. + * Copyright (C) 2019 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#ifndef META_DRM_BUFFER_GBM_H +#define META_DRM_BUFFER_GBM_H + +#include <gbm.h> + +#include "backends/native/meta-drm-buffer.h" +#include "backends/native/meta-gpu-kms.h" + +#define META_TYPE_DRM_BUFFER_GBM (meta_drm_buffer_gbm_get_type ()) +G_DECLARE_FINAL_TYPE (MetaDrmBufferGbm, + meta_drm_buffer_gbm, + META, DRM_BUFFER_GBM, + MetaDrmBuffer) + +MetaDrmBufferGbm * meta_drm_buffer_gbm_new (MetaGpuKms *gpu_kms, + struct gbm_surface *gbm_surface, + gboolean use_modifiers, + GError **error); + +struct gbm_bo * meta_drm_buffer_gbm_get_bo (MetaDrmBufferGbm *buffer_gbm); + +#endif /* META_DRM_BUFFER_GBM_H */ diff --git a/src/backends/native/meta-drm-buffer-import.c b/src/backends/native/meta-drm-buffer-import.c new file mode 100644 index 000000000..b9d0e21d2 --- /dev/null +++ b/src/backends/native/meta-drm-buffer-import.c @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2011 Intel Corporation. + * Copyright (C) 2016,2017 Red Hat + * Copyright (C) 2018,2019 DisplayLink (UK) Ltd. + * Copyright (C) 2018 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#include "config.h" + +#include "backends/native/meta-drm-buffer-import.h" + +#include <drm_fourcc.h> +#include <errno.h> +#include <fcntl.h> +#include <xf86drm.h> + +#include "backends/native/meta-drm-buffer-gbm.h" +#include "backends/native/meta-kms-utils.h" +#include "backends/native/meta-renderer-native.h" + +#define INVALID_FB_ID 0U + +struct _MetaDrmBufferImport +{ + MetaDrmBuffer parent; + + MetaGpuKms *gpu_kms; + + MetaDrmBufferGbm *importee; + + uint32_t fb_id; +}; + +G_DEFINE_TYPE (MetaDrmBufferImport, meta_drm_buffer_import, + META_TYPE_DRM_BUFFER) + +static struct gbm_bo * +dmabuf_to_gbm_bo (struct gbm_device *importer, + int dmabuf_fd, + uint32_t width, + uint32_t height, + uint32_t stride, + uint32_t format) +{ + struct gbm_import_fd_data data = { + .fd = dmabuf_fd, + .width = width, + .height = height, + .stride = stride, + .format = format + }; + + return gbm_bo_import (importer, + GBM_BO_IMPORT_FD, + &data, + GBM_BO_USE_SCANOUT); +} + +static gboolean +import_gbm_buffer (MetaDrmBufferImport *buffer_import, + GError **error) +{ + MetaGpuKmsFBArgs fb_args = { 0, }; + struct gbm_bo *primary_bo; + struct gbm_device *importer; + struct gbm_bo *imported_bo; + int dmabuf_fd; + gboolean ret; + + g_assert (buffer_import->fb_id == INVALID_FB_ID); + + importer = meta_gbm_device_from_gpu (buffer_import->gpu_kms); + + primary_bo = meta_drm_buffer_gbm_get_bo (buffer_import->importee); + + dmabuf_fd = gbm_bo_get_fd (primary_bo); + if (dmabuf_fd == -1) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "getting dmabuf fd failed"); + return FALSE; + } + + fb_args.strides[0] = gbm_bo_get_stride (primary_bo); + fb_args.width = gbm_bo_get_width (primary_bo); + fb_args.height = gbm_bo_get_height (primary_bo); + fb_args.format = gbm_bo_get_format (primary_bo); + + imported_bo = dmabuf_to_gbm_bo (importer, + dmabuf_fd, + fb_args.width, + fb_args.height, + fb_args.strides[0], + fb_args.format); + if (!imported_bo) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "importing dmabuf fd failed"); + ret = FALSE; + goto out_close; + } + + fb_args.handles[0] = gbm_bo_get_handle (imported_bo).u32; + + ret = meta_gpu_kms_add_fb (buffer_import->gpu_kms, + FALSE /* use_modifiers */, + &fb_args, + &buffer_import->fb_id, + error); + + gbm_bo_destroy (imported_bo); + +out_close: + close (dmabuf_fd); + + return ret; +} + +MetaDrmBufferImport * +meta_drm_buffer_import_new (MetaGpuKms *gpu_kms, + MetaDrmBufferGbm *buffer_gbm, + GError **error) +{ + MetaDrmBufferImport *buffer_import; + + buffer_import = g_object_new (META_TYPE_DRM_BUFFER_IMPORT, NULL); + buffer_import->gpu_kms = gpu_kms; + g_set_object (&buffer_import->importee, buffer_gbm); + + if (!import_gbm_buffer (buffer_import, error)) + { + g_object_unref (buffer_import); + return NULL; + } + + return buffer_import; +} + +static uint32_t +meta_drm_buffer_import_get_fb_id (MetaDrmBuffer *buffer) +{ + return META_DRM_BUFFER_IMPORT (buffer)->fb_id; +} + +static void +meta_drm_buffer_import_finalize (GObject *object) +{ + MetaDrmBufferImport *buffer_import = META_DRM_BUFFER_IMPORT (object); + + if (buffer_import->fb_id != INVALID_FB_ID) + { + int kms_fd; + + kms_fd = meta_gpu_kms_get_fd (buffer_import->gpu_kms); + drmModeRmFB (kms_fd, buffer_import->fb_id); + } + + g_clear_object (&buffer_import->importee); + + G_OBJECT_CLASS (meta_drm_buffer_import_parent_class)->finalize (object); +} + +static void +meta_drm_buffer_import_init (MetaDrmBufferImport *buffer_import) +{ +} + +static void +meta_drm_buffer_import_class_init (MetaDrmBufferImportClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MetaDrmBufferClass *buffer_class = META_DRM_BUFFER_CLASS (klass); + + object_class->finalize = meta_drm_buffer_import_finalize; + + buffer_class->get_fb_id = meta_drm_buffer_import_get_fb_id; +} diff --git a/src/backends/native/meta-drm-buffer-import.h b/src/backends/native/meta-drm-buffer-import.h new file mode 100644 index 000000000..2c0962e5f --- /dev/null +++ b/src/backends/native/meta-drm-buffer-import.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2018 Canonical Ltd. + * Copyright (C) 2019 Red Hat Inc. + * Copyright (C) 2019 DisplayLink (UK) Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#ifndef META_DRM_BUFFER_IMPORT_H +#define META_DRM_BUFFER_IMPORT_H + +#include <gbm.h> + +#include "backends/native/meta-drm-buffer.h" +#include "backends/native/meta-drm-buffer-gbm.h" +#include "backends/native/meta-gpu-kms.h" + +#define META_TYPE_DRM_BUFFER_IMPORT (meta_drm_buffer_import_get_type ()) +G_DECLARE_FINAL_TYPE (MetaDrmBufferImport, + meta_drm_buffer_import, + META, DRM_BUFFER_IMPORT, + MetaDrmBuffer) + +/* + * MetaDrmBufferImport is a buffer that refers to the storage of a + * MetaDrmBufferGbm buffer on another MetaGpuKms. + * + * When creating an imported buffer, the given GBM buffer is exported + * as a dma_buf and then imported to the given MetaGpuKms. A reference + * is kept to the GBM buffer so that it won't disappear while the + * imported buffer exists. + * + * The import has a high chance of failing under normal operating + * conditions and needs to be handled with fallbacks to something else. + */ +MetaDrmBufferImport * meta_drm_buffer_import_new (MetaGpuKms *gpu_kms, + MetaDrmBufferGbm *buffer_gbm, + GError **error); + +#endif /* META_DRM_BUFFER_IMPORT_H */ diff --git a/src/backends/native/meta-drm-buffer.c b/src/backends/native/meta-drm-buffer.c new file mode 100644 index 000000000..85b520825 --- /dev/null +++ b/src/backends/native/meta-drm-buffer.c @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2011 Intel Corporation. + * Copyright (C) 2016 Red Hat + * Copyright (C) 2018 DisplayLink (UK) Ltd. + * Copyright (C) 2018 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Daniel van Vugt <daniel.van.vugt@canonical.com> + */ + +#include "config.h" + +#include "backends/native/meta-drm-buffer.h" + +G_DEFINE_ABSTRACT_TYPE (MetaDrmBuffer, meta_drm_buffer, G_TYPE_OBJECT) + +uint32_t +meta_drm_buffer_get_fb_id (MetaDrmBuffer *buffer) +{ + return META_DRM_BUFFER_GET_CLASS (buffer)->get_fb_id (buffer); +} + +static void +meta_drm_buffer_init (MetaDrmBuffer *buffer) +{ +} + +static void +meta_drm_buffer_class_init (MetaDrmBufferClass *klass) +{ +} diff --git a/src/backends/native/meta-drm-buffer.h b/src/backends/native/meta-drm-buffer.h new file mode 100644 index 000000000..94873ed40 --- /dev/null +++ b/src/backends/native/meta-drm-buffer.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2018 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Daniel van Vugt <daniel.van.vugt@canonical.com> + */ + +#ifndef META_DRM_BUFFER_H +#define META_DRM_BUFFER_H + +#include <glib-object.h> +#include <stdint.h> + +#define META_TYPE_DRM_BUFFER (meta_drm_buffer_get_type ()) +G_DECLARE_DERIVABLE_TYPE (MetaDrmBuffer, + meta_drm_buffer, + META, DRM_BUFFER, + GObject) + +struct _MetaDrmBufferClass +{ + GObjectClass parent_class; + + uint32_t (* get_fb_id) (MetaDrmBuffer *buffer); +}; + +MetaDrmBuffer * +meta_drm_buffer_new_from_dumb (uint32_t dumb_fb_id); + +uint32_t meta_drm_buffer_get_fb_id (MetaDrmBuffer *buffer); + +#endif /* META_DRM_BUFFER_H */ diff --git a/src/backends/native/meta-event-native.c b/src/backends/native/meta-event-native.c new file mode 100644 index 000000000..61603d19e --- /dev/null +++ b/src/backends/native/meta-event-native.c @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2015 Red Hat + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Authored by: + * Carlos Garnacho <carlosg@gnome.org> + */ + +#include "config.h" + +#include "backends/native/meta-event-native.h" +#include "backends/native/meta-input-device-native.h" +#include "clutter/clutter-mutter.h" + +typedef struct _MetaEventNative MetaEventNative; + +struct _MetaEventNative +{ + uint32_t evcode; + + uint64_t time_usec; + + gboolean has_relative_motion; + double dx; + double dy; + double dx_unaccel; + double dy_unaccel; +}; + +static MetaEventNative * +meta_event_native_new (void) +{ + return g_slice_new0 (MetaEventNative); +} + +MetaEventNative * +meta_event_native_copy (MetaEventNative *event_evdev) +{ + if (event_evdev != NULL) + return g_slice_dup (MetaEventNative, event_evdev); + + return NULL; +} + +void +meta_event_native_free (MetaEventNative *event_evdev) +{ + if (event_evdev != NULL) + g_slice_free (MetaEventNative, event_evdev); +} + +static MetaEventNative * +meta_event_native_ensure_platform_data (ClutterEvent *event) +{ + MetaEventNative *event_evdev = _clutter_event_get_platform_data (event); + + if (!event_evdev) + { + event_evdev = meta_event_native_new (); + _clutter_event_set_platform_data (event, event_evdev); + } + + return event_evdev; +} + +void +meta_event_native_set_event_code (ClutterEvent *event, + uint32_t evcode) +{ + MetaEventNative *event_evdev; + + event_evdev = meta_event_native_ensure_platform_data (event); + event_evdev->evcode = evcode; +} + +void +meta_event_native_set_time_usec (ClutterEvent *event, + uint64_t time_usec) +{ + MetaEventNative *event_evdev; + + event_evdev = meta_event_native_ensure_platform_data (event); + event_evdev->time_usec = time_usec; +} + +void +meta_event_native_set_relative_motion (ClutterEvent *event, + double dx, + double dy, + double dx_unaccel, + double dy_unaccel) +{ + MetaEventNative *event_evdev; + + event_evdev = meta_event_native_ensure_platform_data (event); + event_evdev->dx = dx; + event_evdev->dy = dy; + event_evdev->dx_unaccel = dx_unaccel; + event_evdev->dy_unaccel = dy_unaccel; + event_evdev->has_relative_motion = TRUE; +} + +/** + * meta_event_native_get_event_code: + * @event: a #ClutterEvent + * + * Returns the event code of the original event. See linux/input.h for more + * information. + * + * Returns: The event code. + **/ +uint32_t +meta_event_native_get_event_code (const ClutterEvent *event) +{ + MetaEventNative *event_evdev = _clutter_event_get_platform_data (event); + + if (event_evdev) + return event_evdev->evcode; + + return 0; +} + +/** + * meta_event_native_get_time_usec: + * @event: a #ClutterEvent + * + * Returns the time in microsecond granularity, or 0 if unavailable. + * + * Returns: The time in microsecond granularity, or 0 if unavailable. + */ +uint64_t +meta_event_native_get_time_usec (const ClutterEvent *event) +{ + MetaEventNative *event_evdev = _clutter_event_get_platform_data (event); + + if (event_evdev) + return event_evdev->time_usec; + + return 0; +} + +/** + * meta_event_get_pointer_motion + * @event: a #ClutterEvent + * + * If available, the normal and unaccelerated motion deltas are written + * to the dx, dy, dx_unaccel and dy_unaccel and TRUE is returned. + * + * If unavailable, FALSE is returned. + * + * Returns: TRUE on success, otherwise FALSE. + **/ +gboolean +meta_event_native_get_relative_motion (const ClutterEvent *event, + double *dx, + double *dy, + double *dx_unaccel, + double *dy_unaccel) +{ + MetaEventNative *event_evdev = _clutter_event_get_platform_data (event); + + if (event_evdev && event_evdev->has_relative_motion) + { + if (dx) + *dx = event_evdev->dx; + if (dy) + *dy = event_evdev->dy; + if (dx_unaccel) + *dx_unaccel = event_evdev->dx_unaccel; + if (dy_unaccel) + *dy_unaccel = event_evdev->dy_unaccel; + return TRUE; + } + else + return FALSE; +} + +/** + * meta_event_native_sequence_get_slot: + * @sequence: a #ClutterEventSequence + * + * Retrieves the touch slot triggered by this @sequence + * + * Returns: the libinput touch slot. + * + * Since: 1.20 + * Stability: unstable + **/ +int32_t +meta_event_native_sequence_get_slot (const ClutterEventSequence *sequence) +{ + if (!sequence) + return -1; + + return GPOINTER_TO_INT (sequence) - 1; +} diff --git a/src/backends/native/meta-event-native.h b/src/backends/native/meta-event-native.h new file mode 100644 index 000000000..18405cdfc --- /dev/null +++ b/src/backends/native/meta-event-native.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2015 Red Hat + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Authored by: + * Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef META_EVENT_NATIVE_H +#define META_EVENT_NATIVE_H + +#include "clutter/clutter.h" + +typedef struct _MetaEventNative MetaEventNative; + +MetaEventNative * meta_event_native_copy (MetaEventNative *event_evdev); +void meta_event_native_free (MetaEventNative *event_evdev); + +uint32_t meta_event_native_get_event_code (const ClutterEvent *event); +void meta_event_native_set_event_code (ClutterEvent *event, + uint32_t evcode); +uint64_t meta_event_native_get_time_usec (const ClutterEvent *event); +void meta_event_native_set_time_usec (ClutterEvent *event, + uint64_t time_usec); +void meta_event_native_set_relative_motion (ClutterEvent *event, + double dx, + double dy, + double dx_unaccel, + double dy_unaccel); +gboolean meta_event_native_get_relative_motion (const ClutterEvent *event, + double *dx, + double *dy, + double *dx_unaccel, + double *dy_unaccel); + +int32_t meta_event_native_sequence_get_slot (const ClutterEventSequence *sequence); + +#endif /* META_EVENT_NATIVE_H */ diff --git a/src/backends/native/meta-gpu-kms.c b/src/backends/native/meta-gpu-kms.c new file mode 100644 index 000000000..a475933ad --- /dev/null +++ b/src/backends/native/meta-gpu-kms.c @@ -0,0 +1,643 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat + * Copyright (c) 2018 DisplayLink (UK) Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "backends/native/meta-gpu-kms.h" + +#include <drm.h> +#include <drm_fourcc.h> +#include <errno.h> +#include <poll.h> +#include <string.h> +#include <time.h> +#include <xf86drm.h> +#include <xf86drmMode.h> + +#include "backends/meta-crtc.h" +#include "backends/meta-monitor-manager-private.h" +#include "backends/meta-output.h" +#include "backends/native/meta-backend-native.h" +#include "backends/native/meta-crtc-kms.h" +#include "backends/native/meta-kms-connector.h" +#include "backends/native/meta-kms-device.h" +#include "backends/native/meta-kms-update.h" +#include "backends/native/meta-kms-utils.h" +#include "backends/native/meta-kms.h" +#include "backends/native/meta-launcher.h" +#include "backends/native/meta-output-kms.h" + +#include "meta-default-modes.h" + +struct _MetaGpuKms +{ + MetaGpu parent; + + MetaKmsDevice *kms_device; + + uint32_t id; + int fd; + + clockid_t clock_id; + + gboolean resources_init_failed_before; +}; + +G_DEFINE_TYPE (MetaGpuKms, meta_gpu_kms, META_TYPE_GPU) + +gboolean +meta_gpu_kms_add_fb (MetaGpuKms *gpu_kms, + gboolean use_modifiers, + const MetaGpuKmsFBArgs *args, + uint32_t *fb_id_out, + GError **error) +{ + MetaDrmFormatBuf tmp; + uint32_t fb_id; + + if (use_modifiers && args->modifiers[0] != DRM_FORMAT_MOD_INVALID) + { + if (drmModeAddFB2WithModifiers (gpu_kms->fd, + args->width, + args->height, + args->format, + args->handles, + args->strides, + args->offsets, + args->modifiers, + &fb_id, + DRM_MODE_FB_MODIFIERS)) + { + g_set_error (error, + G_IO_ERROR, + g_io_error_from_errno (errno), + "drmModeAddFB2WithModifiers failed: %s", + g_strerror (errno)); + return FALSE; + } + } + else if (drmModeAddFB2 (gpu_kms->fd, + args->width, + args->height, + args->format, + args->handles, + args->strides, + args->offsets, + &fb_id, + 0)) + { + if (args->format != DRM_FORMAT_XRGB8888) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "drmModeAddFB does not support format '%s' (0x%x)", + meta_drm_format_to_string (&tmp, args->format), + args->format); + return FALSE; + } + + if (drmModeAddFB (gpu_kms->fd, + args->width, + args->height, + 24, + 32, + args->strides[0], + args->handles[0], + &fb_id)) + { + g_set_error (error, + G_IO_ERROR, + g_io_error_from_errno (errno), + "drmModeAddFB failed: %s", + g_strerror (errno)); + return FALSE; + } + } + + *fb_id_out = fb_id; + return TRUE; +} + +gboolean +meta_gpu_kms_is_crtc_active (MetaGpuKms *gpu_kms, + MetaCrtc *crtc) +{ + MetaGpu *gpu = META_GPU (gpu_kms); + MetaBackend *backend = meta_gpu_get_backend (gpu); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + GList *l; + gboolean connected_crtc_found; + + g_assert (meta_crtc_get_gpu (crtc) == META_GPU (gpu_kms)); + + if (meta_monitor_manager_get_power_save_mode (monitor_manager)) + return FALSE; + + connected_crtc_found = FALSE; + for (l = meta_gpu_get_outputs (gpu); l; l = l->next) + { + MetaOutput *output = l->data; + MetaCrtc *assigned_crtc; + + assigned_crtc = meta_output_get_assigned_crtc (output); + if (assigned_crtc == crtc) + { + connected_crtc_found = TRUE; + break; + } + } + + if (!connected_crtc_found) + return FALSE; + + return TRUE; +} + +static int64_t +timespec_to_nanoseconds (const struct timespec *ts) +{ + const int64_t one_billion = 1000000000; + + return ((int64_t) ts->tv_sec) * one_billion + ts->tv_nsec; +} + +gboolean +meta_gpu_kms_wait_for_flip (MetaGpuKms *gpu_kms, + GError **error) +{ + if (meta_kms_device_dispatch_sync (gpu_kms->kms_device, error) < 0) + return FALSE; + + return TRUE; +} + +MetaKmsDevice * +meta_gpu_kms_get_kms_device (MetaGpuKms *gpu_kms) +{ + return gpu_kms->kms_device; +} + +int +meta_gpu_kms_get_fd (MetaGpuKms *gpu_kms) +{ + return gpu_kms->fd; +} + +uint32_t +meta_gpu_kms_get_id (MetaGpuKms *gpu_kms) +{ + return gpu_kms->id; +} + +const char * +meta_gpu_kms_get_file_path (MetaGpuKms *gpu_kms) +{ + return meta_kms_device_get_path (gpu_kms->kms_device); +} + +int64_t +meta_gpu_kms_get_current_time_ns (MetaGpuKms *gpu_kms) +{ + struct timespec ts; + + if (clock_gettime (gpu_kms->clock_id, &ts)) + return 0; + + return timespec_to_nanoseconds (&ts); +} + +void +meta_gpu_kms_set_power_save_mode (MetaGpuKms *gpu_kms, + uint64_t state, + MetaKmsUpdate *kms_update) +{ + MetaGpu *gpu = META_GPU (gpu_kms); + GList *l; + + for (l = meta_gpu_get_outputs (gpu); l; l = l->next) + { + MetaOutput *output = l->data; + + meta_output_kms_set_power_save_mode (output, state, kms_update); + } + + if (state != META_POWER_SAVE_ON) + { + /* Turn off CRTCs for DPMS */ + for (l = meta_gpu_get_crtcs (gpu); l; l = l->next) + { + MetaCrtc *crtc = META_CRTC (l->data); + + meta_kms_update_mode_set (kms_update, + meta_crtc_kms_get_kms_crtc (crtc), + NULL, NULL); + } + } +} + +gboolean +meta_gpu_kms_is_boot_vga (MetaGpuKms *gpu_kms) +{ + MetaKmsDeviceFlag flags; + + flags = meta_kms_device_get_flags (gpu_kms->kms_device); + return !!(flags & META_KMS_DEVICE_FLAG_BOOT_VGA); +} + +gboolean +meta_gpu_kms_is_platform_device (MetaGpuKms *gpu_kms) +{ + MetaKmsDeviceFlag flags; + + flags = meta_kms_device_get_flags (gpu_kms->kms_device); + return !!(flags & META_KMS_DEVICE_FLAG_PLATFORM_DEVICE); +} + +static int +compare_outputs (gconstpointer one, + gconstpointer two) +{ + const MetaOutput *o_one = one, *o_two = two; + + return strcmp (o_one->name, o_two->name); +} + +static void +meta_crtc_mode_destroy_notify (MetaCrtcMode *mode) +{ + g_slice_free (drmModeModeInfo, mode->driver_private); +} + +gboolean +meta_drm_mode_equal (const drmModeModeInfo *one, + const drmModeModeInfo *two) +{ + return (one->clock == two->clock && + one->hdisplay == two->hdisplay && + one->hsync_start == two->hsync_start && + one->hsync_end == two->hsync_end && + one->htotal == two->htotal && + one->hskew == two->hskew && + one->vdisplay == two->vdisplay && + one->vsync_start == two->vsync_start && + one->vsync_end == two->vsync_end && + one->vtotal == two->vtotal && + one->vscan == two->vscan && + one->vrefresh == two->vrefresh && + one->flags == two->flags && + one->type == two->type && + strncmp (one->name, two->name, DRM_DISPLAY_MODE_LEN) == 0); +} + +static guint +drm_mode_hash (gconstpointer ptr) +{ + const drmModeModeInfo *mode = ptr; + guint hash = 0; + + /* + * We don't include the name in the hash because it's generally + * derived from the other fields (hdisplay, vdisplay and flags) + */ + + hash ^= mode->clock; + hash ^= mode->hdisplay ^ mode->hsync_start ^ mode->hsync_end; + hash ^= mode->vdisplay ^ mode->vsync_start ^ mode->vsync_end; + hash ^= mode->vrefresh; + hash ^= mode->flags ^ mode->type; + + return hash; +} + +MetaCrtcMode * +meta_gpu_kms_get_mode_from_drm_mode (MetaGpuKms *gpu_kms, + const drmModeModeInfo *drm_mode) +{ + MetaGpu *gpu = META_GPU (gpu_kms); + GList *l; + + for (l = meta_gpu_get_modes (gpu); l; l = l->next) + { + MetaCrtcMode *mode = l->data; + + if (meta_drm_mode_equal (drm_mode, mode->driver_private)) + return mode; + } + + g_assert_not_reached (); + return NULL; +} + +static MetaCrtcMode * +create_mode (const drmModeModeInfo *drm_mode, + long mode_id) +{ + MetaCrtcMode *mode; + + mode = g_object_new (META_TYPE_CRTC_MODE, NULL); + mode->mode_id = mode_id; + mode->name = g_strndup (drm_mode->name, DRM_DISPLAY_MODE_LEN); + mode->width = drm_mode->hdisplay; + mode->height = drm_mode->vdisplay; + mode->flags = drm_mode->flags; + mode->refresh_rate = meta_calculate_drm_mode_refresh_rate (drm_mode); + mode->driver_private = g_slice_dup (drmModeModeInfo, drm_mode); + mode->driver_notify = (GDestroyNotify) meta_crtc_mode_destroy_notify; + + return mode; +} + +static MetaOutput * +find_output_by_connector_id (GList *outputs, + uint32_t connector_id) +{ + GList *l; + + for (l = outputs; l; l = l->next) + { + MetaOutput *output = l->data; + + if (meta_output_kms_get_connector_id (output) == connector_id) + return output; + } + + return NULL; +} + +static void +setup_output_clones (MetaGpu *gpu) +{ + GList *l; + + for (l = meta_gpu_get_outputs (gpu); l; l = l->next) + { + MetaOutput *output = l->data; + GList *k; + + for (k = meta_gpu_get_outputs (gpu); k; k = k->next) + { + MetaOutput *other_output = k->data; + + if (other_output == output) + continue; + + if (meta_output_kms_can_clone (output, other_output)) + { + output->n_possible_clones++; + output->possible_clones = g_renew (MetaOutput *, + output->possible_clones, + output->n_possible_clones); + output->possible_clones[output->n_possible_clones - 1] = + other_output; + } + } + } +} + +static void +init_modes (MetaGpuKms *gpu_kms) +{ + MetaGpu *gpu = META_GPU (gpu_kms); + GHashTable *modes_table; + GList *l; + GList *modes; + GHashTableIter iter; + drmModeModeInfo *drm_mode; + int i; + long mode_id; + + /* + * Gather all modes on all connected connectors. + */ + modes_table = g_hash_table_new (drm_mode_hash, (GEqualFunc) meta_drm_mode_equal); + for (l = meta_kms_device_get_connectors (gpu_kms->kms_device); l; l = l->next) + { + MetaKmsConnector *kms_connector = l->data; + const MetaKmsConnectorState *state; + + state = meta_kms_connector_get_current_state (kms_connector); + if (!state) + continue; + + for (i = 0; i < state->n_modes; i++) + g_hash_table_add (modes_table, &state->modes[i]); + } + + modes = NULL; + + g_hash_table_iter_init (&iter, modes_table); + mode_id = 0; + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &drm_mode)) + { + MetaCrtcMode *mode; + + mode = create_mode (drm_mode, (long) mode_id); + modes = g_list_append (modes, mode); + + mode_id++; + } + + g_hash_table_destroy (modes_table); + + for (i = 0; i < G_N_ELEMENTS (meta_default_landscape_drm_mode_infos); i++) + { + MetaCrtcMode *mode; + + mode = create_mode (&meta_default_landscape_drm_mode_infos[i], mode_id); + modes = g_list_append (modes, mode); + + mode_id++; + } + + for (i = 0; i < G_N_ELEMENTS (meta_default_portrait_drm_mode_infos); i++) + { + MetaCrtcMode *mode; + + mode = create_mode (&meta_default_portrait_drm_mode_infos[i], mode_id); + modes = g_list_append (modes, mode); + + mode_id++; + } + + meta_gpu_take_modes (gpu, modes); +} + +static void +init_crtcs (MetaGpuKms *gpu_kms) +{ + MetaGpu *gpu = META_GPU (gpu_kms); + MetaKmsDevice *kms_device = gpu_kms->kms_device; + GList *l; + GList *crtcs; + + crtcs = NULL; + + for (l = meta_kms_device_get_crtcs (kms_device); l; l = l->next) + { + MetaKmsCrtc *kms_crtc = l->data; + MetaCrtc *crtc; + + crtc = meta_create_kms_crtc (gpu_kms, kms_crtc); + + crtcs = g_list_append (crtcs, crtc); + } + + meta_gpu_take_crtcs (gpu, crtcs); +} + +static void +init_frame_clock (MetaGpuKms *gpu_kms) +{ + uint64_t uses_monotonic; + + if (drmGetCap (gpu_kms->fd, DRM_CAP_TIMESTAMP_MONOTONIC, &uses_monotonic) != 0) + uses_monotonic = 0; + + gpu_kms->clock_id = uses_monotonic ? CLOCK_MONOTONIC : CLOCK_REALTIME; +} + +static void +init_outputs (MetaGpuKms *gpu_kms) +{ + MetaGpu *gpu = META_GPU (gpu_kms); + GList *old_outputs; + GList *outputs; + GList *l; + + old_outputs = meta_gpu_get_outputs (gpu); + + outputs = NULL; + + for (l = meta_kms_device_get_connectors (gpu_kms->kms_device); l; l = l->next) + { + MetaKmsConnector *kms_connector = l->data; + const MetaKmsConnectorState *connector_state; + MetaOutput *output; + MetaOutput *old_output; + GError *error = NULL; + + connector_state = meta_kms_connector_get_current_state (kms_connector); + if (!connector_state) + continue; + + old_output = + find_output_by_connector_id (old_outputs, + meta_kms_connector_get_id (kms_connector)); + output = meta_create_kms_output (gpu_kms, + kms_connector, + old_output, + &error); + if (!output) + { + g_warning ("Failed to create KMS output: %s", error->message); + g_error_free (error); + } + else + { + outputs = g_list_prepend (outputs, output); + } + } + + + /* Sort the outputs for easier handling in MetaMonitorConfig */ + outputs = g_list_sort (outputs, compare_outputs); + meta_gpu_take_outputs (gpu, outputs); + + setup_output_clones (gpu); +} + +static gboolean +meta_gpu_kms_read_current (MetaGpu *gpu, + GError **error) +{ + MetaGpuKms *gpu_kms = META_GPU_KMS (gpu); + + /* Note: we must not free the public structures (output, crtc, monitor + mode and monitor info) here, they must be kept alive until the API + users are done with them after we emit monitors-changed, and thus + are freed by the platform-independent layer. */ + + init_modes (gpu_kms); + init_crtcs (gpu_kms); + init_outputs (gpu_kms); + init_frame_clock (gpu_kms); + + return TRUE; +} + +gboolean +meta_gpu_kms_can_have_outputs (MetaGpuKms *gpu_kms) +{ + GList *l; + int n_connected_connectors = 0; + + for (l = meta_kms_device_get_connectors (gpu_kms->kms_device); l; l = l->next) + { + MetaKmsConnector *kms_connector = l->data; + + if (meta_kms_connector_get_current_state (kms_connector)) + n_connected_connectors++; + } + + return n_connected_connectors > 0; +} + +MetaGpuKms * +meta_gpu_kms_new (MetaBackendNative *backend_native, + MetaKmsDevice *kms_device, + GError **error) +{ + MetaGpuKms *gpu_kms; + int kms_fd; + + kms_fd = meta_kms_device_leak_fd (kms_device); + + gpu_kms = g_object_new (META_TYPE_GPU_KMS, + "backend", backend_native, + NULL); + + gpu_kms->kms_device = kms_device; + gpu_kms->fd = kms_fd; + + meta_gpu_kms_read_current (META_GPU (gpu_kms), NULL); + + return gpu_kms; +} + +static void +meta_gpu_kms_init (MetaGpuKms *gpu_kms) +{ + static uint32_t id = 0; + + gpu_kms->fd = -1; + gpu_kms->id = ++id; +} + +static void +meta_gpu_kms_class_init (MetaGpuKmsClass *klass) +{ + MetaGpuClass *gpu_class = META_GPU_CLASS (klass); + + gpu_class->read_current = meta_gpu_kms_read_current; +} diff --git a/src/backends/native/meta-gpu-kms.h b/src/backends/native/meta-gpu-kms.h new file mode 100644 index 000000000..f14e385b7 --- /dev/null +++ b/src/backends/native/meta-gpu-kms.h @@ -0,0 +1,97 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat + * Copyright (C) 2018 DisplayLink (UK) Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_GPU_KMS_H +#define META_GPU_KMS_H + +#include <glib-object.h> +#include <xf86drm.h> +#include <xf86drmMode.h> + +#include "backends/meta-gpu.h" +#include "backends/native/meta-backend-native.h" +#include "backends/native/meta-kms-types.h" + +#define META_TYPE_GPU_KMS (meta_gpu_kms_get_type ()) +G_DECLARE_FINAL_TYPE (MetaGpuKms, meta_gpu_kms, META, GPU_KMS, MetaGpu) + +typedef struct _MetaGpuKmsFlipClosureContainer MetaGpuKmsFlipClosureContainer; + +MetaGpuKms * meta_gpu_kms_new (MetaBackendNative *backend_native, + MetaKmsDevice *kms_device, + GError **error); + +gboolean meta_gpu_kms_can_have_outputs (MetaGpuKms *gpu_kms); + +gboolean meta_gpu_kms_is_crtc_active (MetaGpuKms *gpu_kms, + MetaCrtc *crtc); + +gboolean meta_gpu_kms_is_boot_vga (MetaGpuKms *gpu_kms); +gboolean meta_gpu_kms_is_platform_device (MetaGpuKms *gpu_kms); + +gboolean meta_gpu_kms_wait_for_flip (MetaGpuKms *gpu_kms, + GError **error); + +MetaKmsDevice * meta_gpu_kms_get_kms_device (MetaGpuKms *gpu_kms); + +int meta_gpu_kms_get_fd (MetaGpuKms *gpu_kms); + +uint32_t meta_gpu_kms_get_id (MetaGpuKms *gpu_kms); + +const char * meta_gpu_kms_get_file_path (MetaGpuKms *gpu_kms); + +int64_t meta_gpu_kms_get_current_time_ns (MetaGpuKms *gpu_kms); + +void meta_gpu_kms_set_power_save_mode (MetaGpuKms *gpu_kms, + uint64_t state, + MetaKmsUpdate *kms_update); + +MetaCrtcMode * meta_gpu_kms_get_mode_from_drm_mode (MetaGpuKms *gpu_kms, + const drmModeModeInfo *drm_mode); + +gboolean meta_drm_mode_equal (const drmModeModeInfo *one, + const drmModeModeInfo *two); + +MetaGpuKmsFlipClosureContainer * meta_gpu_kms_wrap_flip_closure (MetaGpuKms *gpu_kms, + MetaCrtc *crtc, + GClosure *flip_closure); + +void meta_gpu_kms_flip_closure_container_free (MetaGpuKmsFlipClosureContainer *closure_container); + +typedef struct _MetaGpuKmsFBArgs +{ + uint32_t width; + uint32_t height; + uint32_t format; + uint32_t handles[4]; + uint32_t offsets[4]; + uint32_t strides[4]; + uint64_t modifiers[4]; +} MetaGpuKmsFBArgs; + +gboolean meta_gpu_kms_add_fb (MetaGpuKms *gpu_kms, + gboolean use_modifiers, + const MetaGpuKmsFBArgs *args, + uint32_t *fb_id_out, + GError **error); + +#endif /* META_GPU_KMS_H */ diff --git a/clutter/clutter/evdev/clutter-input-device-evdev.c b/src/backends/native/meta-input-device-native.c similarity index 63% rename from clutter/clutter/evdev/clutter-input-device-evdev.c rename to src/backends/native/meta-input-device-native.c index 4e7e19de4..4b87eb2a0 100644 --- a/clutter/clutter/evdev/clutter-input-device-evdev.c +++ b/src/backends/native/meta-input-device-native.c @@ -1,8 +1,4 @@ /* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * * Copyright (C) 2010 Intel Corp. * Copyright (C) 2014 Jonas Ådahl * @@ -23,32 +19,22 @@ * Author: Jonas Ådahl <jadahl@gmail.com> */ -#ifdef HAVE_CONFIG_H -#include "clutter-build-config.h" -#endif +#include "config.h" #include <math.h> +#include <cairo-gobject.h> -#include "clutter/clutter-device-manager-private.h" -#include "clutter/clutter-event-private.h" -#include "clutter-private.h" -#include "clutter-evdev.h" -#include "clutter-input-device-tool-evdev.h" - -#include "clutter-input-device-evdev.h" -#include "clutter-device-manager-evdev.h" - -#include "cairo-gobject.h" +#include "backends/native/meta-input-device-tool-native.h" +#include "backends/native/meta-input-device-native.h" +#include "backends/native/meta-seat-native.h" +#include "clutter/clutter-mutter.h" -typedef struct _ClutterInputDeviceClass ClutterInputDeviceEvdevClass; +G_DEFINE_TYPE (MetaInputDeviceNative, + meta_input_device_native, + META_TYPE_INPUT_DEVICE) -#define clutter_input_device_evdev_get_type _clutter_input_device_evdev_get_type - -G_DEFINE_TYPE (ClutterInputDeviceEvdev, - clutter_input_device_evdev, - CLUTTER_TYPE_INPUT_DEVICE) - -enum { +enum +{ PROP_0, PROP_DEVICE_MATRIX, PROP_OUTPUT_ASPECT_RATIO, @@ -59,48 +45,50 @@ static GParamSpec *obj_props[N_PROPS] = { 0 }; typedef struct _SlowKeysEventPending { - ClutterInputDeviceEvdev *device; + MetaInputDeviceNative *device; ClutterEvent *event; ClutterEmitInputDeviceEvent emit_event_func; guint timer; } SlowKeysEventPending; -static void clear_slow_keys (ClutterInputDeviceEvdev *device); -static void stop_bounce_keys (ClutterInputDeviceEvdev *device); -static void stop_toggle_slowkeys (ClutterInputDeviceEvdev *device); -static void stop_mousekeys_move (ClutterInputDeviceEvdev *device); +static void clear_slow_keys (MetaInputDeviceNative *device); +static void stop_bounce_keys (MetaInputDeviceNative *device); +static void stop_toggle_slowkeys (MetaInputDeviceNative *device); +static void stop_mousekeys_move (MetaInputDeviceNative *device); static void -clutter_input_device_evdev_finalize (GObject *object) +meta_input_device_native_finalize (GObject *object) { ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (object); - ClutterInputDeviceEvdev *device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (object); - ClutterDeviceManagerEvdev *manager_evdev = - CLUTTER_DEVICE_MANAGER_EVDEV (device->device_manager); + MetaInputDeviceNative *device_evdev = META_INPUT_DEVICE_NATIVE (object); + ClutterBackend *backend; + ClutterSeat *seat; if (device_evdev->libinput_device) libinput_device_unref (device_evdev->libinput_device); - clutter_input_device_evdev_release_touch_slots (device_evdev, - g_get_monotonic_time ()); + meta_input_device_native_release_touch_slots (device_evdev, + g_get_monotonic_time ()); - _clutter_device_manager_evdev_release_device_id (manager_evdev, device); + backend = clutter_get_default_backend (); + seat = clutter_backend_get_default_seat (backend); + meta_seat_native_release_device_id (META_SEAT_NATIVE (seat), device); clear_slow_keys (device_evdev); stop_bounce_keys (device_evdev); stop_toggle_slowkeys (device_evdev); stop_mousekeys_move (device_evdev); - G_OBJECT_CLASS (clutter_input_device_evdev_parent_class)->finalize (object); + G_OBJECT_CLASS (meta_input_device_native_parent_class)->finalize (object); } static void -clutter_input_device_evdev_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) +meta_input_device_native_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) { - ClutterInputDeviceEvdev *device = CLUTTER_INPUT_DEVICE_EVDEV (object); + MetaInputDeviceNative *device = META_INPUT_DEVICE_NATIVE (object); switch (prop_id) { @@ -121,12 +109,12 @@ clutter_input_device_evdev_set_property (GObject *object, } static void -clutter_input_device_evdev_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) +meta_input_device_native_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) { - ClutterInputDeviceEvdev *device = CLUTTER_INPUT_DEVICE_EVDEV (object); + MetaInputDeviceNative *device = META_INPUT_DEVICE_NATIVE (object); switch (prop_id) { @@ -142,9 +130,9 @@ clutter_input_device_evdev_get_property (GObject *object, } static gboolean -clutter_input_device_evdev_keycode_to_evdev (ClutterInputDevice *device, - guint hardware_keycode, - guint *evdev_keycode) +meta_input_device_native_keycode_to_evdev (ClutterInputDevice *device, + uint32_t hardware_keycode, + uint32_t *evdev_keycode) { /* The hardware keycodes from the evdev backend are almost evdev keycodes: we use the evdev keycode file, but xkb rules have an @@ -155,12 +143,12 @@ clutter_input_device_evdev_keycode_to_evdev (ClutterInputDevice *device, } static void -clutter_input_device_evdev_update_from_tool (ClutterInputDevice *device, - ClutterInputDeviceTool *tool) +meta_input_device_native_update_from_tool (ClutterInputDevice *device, + ClutterInputDeviceTool *tool) { - ClutterInputDeviceToolEvdev *evdev_tool; + MetaInputDeviceToolNative *evdev_tool; - evdev_tool = CLUTTER_INPUT_DEVICE_TOOL_EVDEV (tool); + evdev_tool = META_INPUT_DEVICE_TOOL_NATIVE (tool); g_object_freeze_notify (G_OBJECT (device)); @@ -194,69 +182,65 @@ clutter_input_device_evdev_update_from_tool (ClutterInputDevice *device, } static gboolean -clutter_input_device_evdev_is_mode_switch_button (ClutterInputDevice *device, - guint group, - guint button) +meta_input_device_native_is_mode_switch_button (ClutterInputDevice *device, + uint32_t group, + uint32_t button) { struct libinput_device *libinput_device; struct libinput_tablet_pad_mode_group *mode_group; - libinput_device = clutter_evdev_input_device_get_libinput_device (device); + libinput_device = meta_input_device_native_get_libinput_device (device); mode_group = libinput_device_tablet_pad_get_mode_group (libinput_device, group); return libinput_tablet_pad_mode_group_button_is_toggle (mode_group, button) != 0; } -static gint -clutter_input_device_evdev_get_group_n_modes (ClutterInputDevice *device, - gint group) +static int +meta_input_device_native_get_group_n_modes (ClutterInputDevice *device, + int group) { struct libinput_device *libinput_device; struct libinput_tablet_pad_mode_group *mode_group; - libinput_device = clutter_evdev_input_device_get_libinput_device (device); + libinput_device = meta_input_device_native_get_libinput_device (device); mode_group = libinput_device_tablet_pad_get_mode_group (libinput_device, group); return libinput_tablet_pad_mode_group_get_num_modes (mode_group); } static gboolean -clutter_input_device_evdev_is_grouped (ClutterInputDevice *device, - ClutterInputDevice *other_device) +meta_input_device_native_is_grouped (ClutterInputDevice *device, + ClutterInputDevice *other_device) { struct libinput_device *libinput_device, *other_libinput_device; - libinput_device = clutter_evdev_input_device_get_libinput_device (device); - other_libinput_device = clutter_evdev_input_device_get_libinput_device (other_device); + libinput_device = meta_input_device_native_get_libinput_device (device); + other_libinput_device = meta_input_device_native_get_libinput_device (other_device); return libinput_device_get_device_group (libinput_device) == libinput_device_get_device_group (other_libinput_device); } static void -clutter_input_device_evdev_bell_notify (void) +meta_input_device_native_bell_notify (MetaInputDeviceNative *device) { - ClutterBackend *backend; - - backend = clutter_get_default_backend (); - clutter_backend_bell_notify (backend); + clutter_seat_bell_notify (CLUTTER_SEAT (device->seat)); } static void -clutter_input_device_evdev_free_pending_slow_key (gpointer data) +meta_input_device_native_free_pending_slow_key (gpointer data) { SlowKeysEventPending *slow_keys_event = data; clutter_event_free (slow_keys_event->event); - if (slow_keys_event->timer) - g_source_remove (slow_keys_event->timer); - free (slow_keys_event); + g_clear_handle_id (&slow_keys_event->timer, g_source_remove); + g_free (slow_keys_event); } static void -clear_slow_keys (ClutterInputDeviceEvdev *device) +clear_slow_keys (MetaInputDeviceNative *device) { - g_list_free_full (device->slow_keys_list, clutter_input_device_evdev_free_pending_slow_key); + g_list_free_full (device->slow_keys_list, meta_input_device_native_free_pending_slow_key); g_list_free (device->slow_keys_list); device->slow_keys_list = NULL; } @@ -264,10 +248,11 @@ clear_slow_keys (ClutterInputDeviceEvdev *device) static guint get_slow_keys_delay (ClutterInputDevice *device) { + MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (device); ClutterKbdA11ySettings a11y_settings; - clutter_device_manager_get_kbd_a11y_settings (device->device_manager, - &a11y_settings); + clutter_seat_get_kbd_a11y_settings (CLUTTER_SEAT (device_native->seat), + &a11y_settings); /* Settings use int, we use uint, make sure we dont go negative */ return MAX (0, a11y_settings.slowkeys_delay); } @@ -276,7 +261,7 @@ static gboolean trigger_slow_keys (gpointer data) { SlowKeysEventPending *slow_keys_event = data; - ClutterInputDeviceEvdev *device = slow_keys_event->device; + MetaInputDeviceNative *device = slow_keys_event->device; ClutterKeyEvent *key_event = (ClutterKeyEvent *) slow_keys_event->event; /* Alter timestamp and emit the event */ @@ -286,15 +271,15 @@ trigger_slow_keys (gpointer data) /* Then remote the pending event */ device->slow_keys_list = g_list_remove (device->slow_keys_list, slow_keys_event); - clutter_input_device_evdev_free_pending_slow_key (slow_keys_event); + meta_input_device_native_free_pending_slow_key (slow_keys_event); if (device->a11y_flags & CLUTTER_A11Y_SLOW_KEYS_BEEP_ACCEPT) - clutter_input_device_evdev_bell_notify (); + meta_input_device_native_bell_notify (device); return G_SOURCE_REMOVE; } -static gint +static int find_pending_event_by_keycode (gconstpointer a, gconstpointer b) { @@ -306,15 +291,14 @@ find_pending_event_by_keycode (gconstpointer a, } static void -start_slow_keys (ClutterEvent *event, - ClutterInputDeviceEvdev *device, - ClutterEmitInputDeviceEvent emit_event_func) +start_slow_keys (ClutterEvent *event, + MetaInputDeviceNative *device, + ClutterEmitInputDeviceEvent emit_event_func) { SlowKeysEventPending *slow_keys_event; ClutterKeyEvent *key_event = (ClutterKeyEvent *) event; - /* Synthetic key events are for autorepeat, ignore those... */ - if (key_event->flags & CLUTTER_EVENT_FLAG_SYNTHETIC) + if (key_event->flags & CLUTTER_EVENT_FLAG_REPEATED) return; slow_keys_event = g_new0 (SlowKeysEventPending, 1); @@ -328,13 +312,13 @@ start_slow_keys (ClutterEvent *event, device->slow_keys_list = g_list_append (device->slow_keys_list, slow_keys_event); if (device->a11y_flags & CLUTTER_A11Y_SLOW_KEYS_BEEP_PRESS) - clutter_input_device_evdev_bell_notify (); + meta_input_device_native_bell_notify (device); } static void -stop_slow_keys (ClutterEvent *event, - ClutterInputDeviceEvdev *device, - ClutterEmitInputDeviceEvent emit_event_func) +stop_slow_keys (ClutterEvent *event, + MetaInputDeviceNative *device, + ClutterEmitInputDeviceEvent emit_event_func) { GList *item; @@ -345,10 +329,10 @@ stop_slow_keys (ClutterEvent *event, SlowKeysEventPending *slow_keys_event = item->data; device->slow_keys_list = g_list_delete_link (device->slow_keys_list, item); - clutter_input_device_evdev_free_pending_slow_key (slow_keys_event); + meta_input_device_native_free_pending_slow_key (slow_keys_event); if (device->a11y_flags & CLUTTER_A11Y_SLOW_KEYS_BEEP_REJECT) - clutter_input_device_evdev_bell_notify (); + meta_input_device_native_bell_notify (device); return; } @@ -360,10 +344,11 @@ stop_slow_keys (ClutterEvent *event, static guint get_debounce_delay (ClutterInputDevice *device) { + MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (device); ClutterKbdA11ySettings a11y_settings; - clutter_device_manager_get_kbd_a11y_settings (device->device_manager, - &a11y_settings); + clutter_seat_get_kbd_a11y_settings (CLUTTER_SEAT (device_native->seat), + &a11y_settings); /* Settings use int, we use uint, make sure we dont go negative */ return MAX (0, a11y_settings.debounce_delay); } @@ -371,7 +356,7 @@ get_debounce_delay (ClutterInputDevice *device) static gboolean clear_bounce_keys (gpointer data) { - ClutterInputDeviceEvdev *device = data; + MetaInputDeviceNative *device = data; device->debounce_key = 0; device->debounce_timer = 0; @@ -380,8 +365,8 @@ clear_bounce_keys (gpointer data) } static void -start_bounce_keys (ClutterEvent *event, - ClutterInputDeviceEvdev *device) +start_bounce_keys (ClutterEvent *event, + MetaInputDeviceNative *device) { stop_bounce_keys (device); @@ -393,25 +378,21 @@ start_bounce_keys (ClutterEvent *event, } static void -stop_bounce_keys (ClutterInputDeviceEvdev *device) +stop_bounce_keys (MetaInputDeviceNative *device) { - if (device->debounce_timer) - { - g_source_remove (device->debounce_timer); - device->debounce_timer = 0; - } + g_clear_handle_id (&device->debounce_timer, g_source_remove); } static void -notify_bounce_keys_reject (ClutterInputDeviceEvdev *device) +notify_bounce_keys_reject (MetaInputDeviceNative *device) { if (device->a11y_flags & CLUTTER_A11Y_BOUNCE_KEYS_BEEP_REJECT) - clutter_input_device_evdev_bell_notify (); + meta_input_device_native_bell_notify (device); } static gboolean -debounce_key (ClutterEvent *event, - ClutterInputDeviceEvdev *device) +debounce_key (ClutterEvent *event, + MetaInputDeviceNative *device) { return (device->debounce_key == ((ClutterKeyEvent *) event)->hardware_keycode); } @@ -442,20 +423,20 @@ key_event_is_modifier (ClutterEvent *event) } static void -notify_stickykeys_mask (ClutterInputDeviceEvdev *device) +notify_stickykeys_mask (MetaInputDeviceNative *device) { - g_signal_emit_by_name (CLUTTER_INPUT_DEVICE (device)->device_manager, + g_signal_emit_by_name (device->seat, "kbd-a11y-mods-state-changed", device->stickykeys_latched_mask, device->stickykeys_locked_mask); } static void -update_internal_xkb_state (ClutterInputDeviceEvdev *device, - xkb_mod_mask_t new_latched_mask, - xkb_mod_mask_t new_locked_mask) +update_internal_xkb_state (MetaInputDeviceNative *device, + xkb_mod_mask_t new_latched_mask, + xkb_mod_mask_t new_locked_mask) { - ClutterSeatEvdev *seat = device->seat; + MetaSeatNative *seat = device->seat; xkb_mod_mask_t depressed_mods; xkb_mod_mask_t latched_mods; xkb_mod_mask_t locked_mods; @@ -485,12 +466,12 @@ update_internal_xkb_state (ClutterInputDeviceEvdev *device, } static void -update_stickykeys_event (ClutterEvent *event, - ClutterInputDeviceEvdev *device, - xkb_mod_mask_t new_latched_mask, - xkb_mod_mask_t new_locked_mask) +update_stickykeys_event (ClutterEvent *event, + MetaInputDeviceNative *device, + xkb_mod_mask_t new_latched_mask, + xkb_mod_mask_t new_locked_mask) { - ClutterSeatEvdev *seat = device->seat; + MetaSeatNative *seat = device->seat; xkb_mod_mask_t effective_mods; xkb_mod_mask_t latched_mods; xkb_mod_mask_t locked_mods; @@ -510,67 +491,67 @@ update_stickykeys_event (ClutterEvent *event, } static void -notify_stickykeys_change (ClutterInputDeviceEvdev *device) +notify_stickykeys_change (MetaInputDeviceNative *device) { /* Everytime sticky keys setting is changed, clear the masks */ device->stickykeys_depressed_mask = 0; update_internal_xkb_state (device, 0, 0); - g_signal_emit_by_name (CLUTTER_INPUT_DEVICE (device)->device_manager, + g_signal_emit_by_name (CLUTTER_INPUT_DEVICE (device)->seat, "kbd-a11y-flags-changed", device->a11y_flags, CLUTTER_A11Y_STICKY_KEYS_ENABLED); } static void -set_stickykeys_off (ClutterInputDeviceEvdev *device) +set_stickykeys_off (MetaInputDeviceNative *device) { device->a11y_flags &= ~CLUTTER_A11Y_STICKY_KEYS_ENABLED; notify_stickykeys_change (device); } static void -set_stickykeys_on (ClutterInputDeviceEvdev *device) +set_stickykeys_on (MetaInputDeviceNative *device) { device->a11y_flags |= CLUTTER_A11Y_STICKY_KEYS_ENABLED; notify_stickykeys_change (device); } static void -clear_stickykeys_event (ClutterEvent *event, - ClutterInputDeviceEvdev *device) +clear_stickykeys_event (ClutterEvent *event, + MetaInputDeviceNative *device) { set_stickykeys_off (device); update_stickykeys_event (event, device, 0, 0); } static void -set_slowkeys_off (ClutterInputDeviceEvdev *device) +set_slowkeys_off (MetaInputDeviceNative *device) { device->a11y_flags &= ~CLUTTER_A11Y_SLOW_KEYS_ENABLED; - g_signal_emit_by_name (CLUTTER_INPUT_DEVICE (device)->device_manager, + g_signal_emit_by_name (CLUTTER_INPUT_DEVICE (device)->seat, "kbd-a11y-flags-changed", device->a11y_flags, CLUTTER_A11Y_SLOW_KEYS_ENABLED); } static void -set_slowkeys_on (ClutterInputDeviceEvdev *device) +set_slowkeys_on (MetaInputDeviceNative *device) { device->a11y_flags |= CLUTTER_A11Y_SLOW_KEYS_ENABLED; - g_signal_emit_by_name (CLUTTER_INPUT_DEVICE (device)->device_manager, + g_signal_emit_by_name (CLUTTER_INPUT_DEVICE (device)->seat, "kbd-a11y-flags-changed", device->a11y_flags, CLUTTER_A11Y_SLOW_KEYS_ENABLED); } static void -handle_stickykeys_press (ClutterEvent *event, - ClutterInputDeviceEvdev *device) +handle_stickykeys_press (ClutterEvent *event, + MetaInputDeviceNative *device) { - ClutterSeatEvdev *seat = device->seat; + MetaSeatNative *seat = device->seat; xkb_mod_mask_t depressed_mods; xkb_mod_mask_t new_latched_mask; xkb_mod_mask_t new_locked_mask; @@ -615,10 +596,10 @@ handle_stickykeys_press (ClutterEvent *event, } static void -handle_stickykeys_release (ClutterEvent *event, - ClutterInputDeviceEvdev *device) +handle_stickykeys_release (ClutterEvent *event, + MetaInputDeviceNative *device) { - ClutterSeatEvdev *seat = device->seat; + MetaSeatNative *seat = device->seat; device->stickykeys_depressed_mask = xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_DEPRESSED); @@ -626,7 +607,7 @@ handle_stickykeys_release (ClutterEvent *event, if (key_event_is_modifier (event)) { if (device->a11y_flags & CLUTTER_A11Y_STICKY_KEYS_BEEP) - clutter_input_device_evdev_bell_notify (); + meta_input_device_native_bell_notify (device); return; } @@ -640,12 +621,12 @@ handle_stickykeys_release (ClutterEvent *event, static gboolean trigger_toggle_slowkeys (gpointer data) { - ClutterInputDeviceEvdev *device = data; + MetaInputDeviceNative *device = data; device->toggle_slowkeys_timer = 0; if (device->a11y_flags & CLUTTER_A11Y_FEATURE_STATE_CHANGE_BEEP) - clutter_input_device_evdev_bell_notify (); + meta_input_device_native_bell_notify (device); if (device->a11y_flags & CLUTTER_A11Y_SLOW_KEYS_ENABLED) set_slowkeys_off (device); @@ -656,7 +637,7 @@ trigger_toggle_slowkeys (gpointer data) } static void -start_toggle_slowkeys (ClutterInputDeviceEvdev *device) +start_toggle_slowkeys (MetaInputDeviceNative *device) { if (device->toggle_slowkeys_timer != 0) return; @@ -668,18 +649,14 @@ start_toggle_slowkeys (ClutterInputDeviceEvdev *device) } static void -stop_toggle_slowkeys (ClutterInputDeviceEvdev *device) +stop_toggle_slowkeys (MetaInputDeviceNative *device) { - if (device->toggle_slowkeys_timer) - { - g_source_remove (device->toggle_slowkeys_timer); - device->toggle_slowkeys_timer = 0; - } + g_clear_handle_id (&device->toggle_slowkeys_timer, g_source_remove); } static void -handle_togglekeys_press (ClutterEvent *event, - ClutterInputDeviceEvdev *device) +handle_enablekeys_press (ClutterEvent *event, + MetaInputDeviceNative *device) { if (event->key.keyval == XKB_KEY_Shift_L || event->key.keyval == XKB_KEY_Shift_R) { @@ -700,8 +677,8 @@ handle_togglekeys_press (ClutterEvent *event, } static void -handle_togglekeys_release (ClutterEvent *event, - ClutterInputDeviceEvdev *device) +handle_enablekeys_release (ClutterEvent *event, + MetaInputDeviceNative *device) { if (event->key.keyval == XKB_KEY_Shift_L || event->key.keyval == XKB_KEY_Shift_R) { @@ -711,7 +688,7 @@ handle_togglekeys_release (ClutterEvent *event, device->shift_count = 0; if (device->a11y_flags & CLUTTER_A11Y_FEATURE_STATE_CHANGE_BEEP) - clutter_input_device_evdev_bell_notify (); + meta_input_device_native_bell_notify (device); if (device->a11y_flags & CLUTTER_A11Y_STICKY_KEYS_ENABLED) set_stickykeys_off (device); @@ -722,15 +699,15 @@ handle_togglekeys_release (ClutterEvent *event, } static int -get_button_index (gint button) +get_button_index (int button) { switch (button) { - case BTN_LEFT: + case CLUTTER_BUTTON_PRIMARY: return 0; - case BTN_MIDDLE: + case CLUTTER_BUTTON_MIDDLE: return 1; - case BTN_RIGHT: + case CLUTTER_BUTTON_SECONDARY: return 2; default: break; @@ -741,35 +718,37 @@ get_button_index (gint button) } static void -emulate_button_press (ClutterInputDeviceEvdev *device) +emulate_button_press (MetaInputDeviceNative *device_evdev) { - gint btn = device->mousekeys_btn; + ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (device_evdev); + int btn = device_evdev->mousekeys_btn; - if (device->mousekeys_btn_states[get_button_index (btn)]) + if (device_evdev->mousekeys_btn_states[get_button_index (btn)]) return; - clutter_virtual_input_device_notify_button (device->mousekeys_virtual_device, + clutter_virtual_input_device_notify_button (device->accessibility_virtual_device, g_get_monotonic_time (), btn, CLUTTER_BUTTON_STATE_PRESSED); - device->mousekeys_btn_states[get_button_index (btn)] = CLUTTER_BUTTON_STATE_PRESSED; + device_evdev->mousekeys_btn_states[get_button_index (btn)] = CLUTTER_BUTTON_STATE_PRESSED; } static void -emulate_button_release (ClutterInputDeviceEvdev *device) +emulate_button_release (MetaInputDeviceNative *device_evdev) { - gint btn = device->mousekeys_btn; + ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (device_evdev); + int btn = device_evdev->mousekeys_btn; - if (device->mousekeys_btn_states[get_button_index (btn)] == CLUTTER_BUTTON_STATE_RELEASED) + if (device_evdev->mousekeys_btn_states[get_button_index (btn)] == CLUTTER_BUTTON_STATE_RELEASED) return; - clutter_virtual_input_device_notify_button (device->mousekeys_virtual_device, + clutter_virtual_input_device_notify_button (device->accessibility_virtual_device, g_get_monotonic_time (), btn, CLUTTER_BUTTON_STATE_RELEASED); - device->mousekeys_btn_states[get_button_index (btn)] = CLUTTER_BUTTON_STATE_RELEASED; + device_evdev->mousekeys_btn_states[get_button_index (btn)] = CLUTTER_BUTTON_STATE_RELEASED; } static void -emulate_button_click (ClutterInputDeviceEvdev *device) +emulate_button_click (MetaInputDeviceNative *device) { emulate_button_press (device); emulate_button_release (device); @@ -778,8 +757,8 @@ emulate_button_click (ClutterInputDeviceEvdev *device) #define MOUSEKEYS_CURVE (1.0 + (((double) 50.0) * 0.001)) static void -update_mousekeys_params (ClutterInputDeviceEvdev *device, - ClutterKbdA11ySettings *settings) +update_mousekeys_params (MetaInputDeviceNative *device, + ClutterKbdA11ySettings *settings) { /* Prevent us from broken settings values */ device->mousekeys_max_speed = MAX (1, settings->mousekeys_max_speed); @@ -787,18 +766,18 @@ update_mousekeys_params (ClutterInputDeviceEvdev *device, device->mousekeys_init_delay = MAX (0, settings->mousekeys_init_delay); device->mousekeys_curve_factor = - (((gdouble) device->mousekeys_max_speed) / - pow ((gdouble) device->mousekeys_accel_time, MOUSEKEYS_CURVE)); + (((double) device->mousekeys_max_speed) / + pow ((double) device->mousekeys_accel_time, MOUSEKEYS_CURVE)); } -static gdouble -mousekeys_get_speed_factor (ClutterInputDeviceEvdev *device, - gint64 time_us) +static double +mousekeys_get_speed_factor (MetaInputDeviceNative *device, + uint64_t time_us) { - guint32 time; - gint64 delta_t; - gint64 init_time; - gdouble speed; + uint32_t time; + int64_t delta_t; + int64_t init_time; + double speed; time = us2ms (time_us); @@ -832,86 +811,96 @@ mousekeys_get_speed_factor (ClutterInputDeviceEvdev *device, #undef MOUSEKEYS_CURVE static void -emulate_pointer_motion (ClutterInputDeviceEvdev *device, - gint dx, - gint dy) +emulate_pointer_motion (MetaInputDeviceNative *device_evdev, + int dx, + int dy) { - gdouble dx_motion; - gdouble dy_motion; - gdouble speed; - gint64 time_us; + ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (device_evdev); + double dx_motion; + double dy_motion; + double speed; + int64_t time_us; time_us = g_get_monotonic_time (); - speed = mousekeys_get_speed_factor (device, time_us); + speed = mousekeys_get_speed_factor (device_evdev, time_us); if (dx < 0) - dx_motion = floor (((gdouble) dx) * speed); + dx_motion = floor (((double) dx) * speed); else - dx_motion = ceil (((gdouble) dx) * speed); + dx_motion = ceil (((double) dx) * speed); if (dy < 0) - dy_motion = floor (((gdouble) dy) * speed); + dy_motion = floor (((double) dy) * speed); else - dy_motion = ceil (((gdouble) dy) * speed); + dy_motion = ceil (((double) dy) * speed); - clutter_virtual_input_device_notify_relative_motion (device->mousekeys_virtual_device, + clutter_virtual_input_device_notify_relative_motion (device->accessibility_virtual_device, time_us, dx_motion, dy_motion); } +static gboolean +is_numlock_active (MetaInputDeviceNative *device) +{ + MetaSeatNative *seat = device->seat; + return xkb_state_mod_name_is_active (seat->xkb, + "Mod2", + XKB_STATE_MODS_LOCKED); +} static void -enable_mousekeys (ClutterInputDeviceEvdev *device) +enable_mousekeys (MetaInputDeviceNative *device_evdev) { - ClutterDeviceManager *manager; + ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (device_evdev); - device->mousekeys_btn = BTN_LEFT; - device->move_mousekeys_timer = 0; - device->mousekeys_first_motion_time = 0; - device->mousekeys_last_motion_time = 0; - device->last_mousekeys_key = 0; + device_evdev->mousekeys_btn = CLUTTER_BUTTON_PRIMARY; + device_evdev->move_mousekeys_timer = 0; + device_evdev->mousekeys_first_motion_time = 0; + device_evdev->mousekeys_last_motion_time = 0; + device_evdev->last_mousekeys_key = 0; - if (device->mousekeys_virtual_device) + if (device->accessibility_virtual_device) return; - manager = CLUTTER_INPUT_DEVICE (device)->device_manager; - device->mousekeys_virtual_device = - clutter_device_manager_create_virtual_device (manager, - CLUTTER_POINTER_DEVICE); + device->accessibility_virtual_device = + clutter_seat_create_virtual_device (CLUTTER_SEAT (device_evdev->seat), + CLUTTER_POINTER_DEVICE); } static void -disable_mousekeys (ClutterInputDeviceEvdev *device) +disable_mousekeys (MetaInputDeviceNative *device_evdev) { - stop_mousekeys_move (device); + ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (device_evdev); + + stop_mousekeys_move (device_evdev); /* Make sure we don't leave button pressed behind... */ - if (device->mousekeys_btn_states[get_button_index (BTN_LEFT)]) + if (device_evdev->mousekeys_btn_states[get_button_index (CLUTTER_BUTTON_PRIMARY)]) { - device->mousekeys_btn = BTN_LEFT; - emulate_button_release (device); + device_evdev->mousekeys_btn = CLUTTER_BUTTON_PRIMARY; + emulate_button_release (device_evdev); } - if (device->mousekeys_btn_states[get_button_index (BTN_MIDDLE)]) + if (device_evdev->mousekeys_btn_states[get_button_index (CLUTTER_BUTTON_MIDDLE)]) { - device->mousekeys_btn = BTN_MIDDLE; - emulate_button_release (device); + device_evdev->mousekeys_btn = CLUTTER_BUTTON_MIDDLE; + emulate_button_release (device_evdev); } - if (device->mousekeys_btn_states[get_button_index (BTN_RIGHT)]) + if (device_evdev->mousekeys_btn_states[get_button_index (CLUTTER_BUTTON_SECONDARY)]) { - device->mousekeys_btn = BTN_RIGHT; - emulate_button_release (device); + device_evdev->mousekeys_btn = CLUTTER_BUTTON_SECONDARY; + emulate_button_release (device_evdev); } - if (device->mousekeys_virtual_device) - g_clear_object (&device->mousekeys_virtual_device); + if (device->accessibility_virtual_device) + g_clear_object (&device->accessibility_virtual_device); } static gboolean trigger_mousekeys_move (gpointer data) { - ClutterInputDeviceEvdev *device = data; - gint dx = 0; - gint dy = 0; + MetaInputDeviceNative *device = data; + int dx = 0; + int dy = 0; if (device->mousekeys_first_motion_time == 0) { @@ -984,21 +973,17 @@ trigger_mousekeys_move (gpointer data) } static void -stop_mousekeys_move (ClutterInputDeviceEvdev *device) +stop_mousekeys_move (MetaInputDeviceNative *device) { device->mousekeys_first_motion_time = 0; device->mousekeys_last_motion_time = 0; - if (device->move_mousekeys_timer) - { - g_source_remove (device->move_mousekeys_timer); - device->move_mousekeys_timer = 0; - } + g_clear_handle_id (&device->move_mousekeys_timer, g_source_remove); } static void -start_mousekeys_move (ClutterEvent *event, - ClutterInputDeviceEvdev *device) +start_mousekeys_move (ClutterEvent *event, + MetaInputDeviceNative *device) { device->last_mousekeys_key = event->key.keyval; @@ -1009,23 +994,27 @@ start_mousekeys_move (ClutterEvent *event, } static gboolean -handle_mousekeys_press (ClutterEvent *event, - ClutterInputDeviceEvdev *device) +handle_mousekeys_press (ClutterEvent *event, + MetaInputDeviceNative *device) { if (!(event->key.flags & CLUTTER_EVENT_FLAG_SYNTHETIC)) stop_mousekeys_move (device); + /* Do not handle mousekeys if NumLock is ON */ + if (is_numlock_active (device)) + return FALSE; + /* Button selection */ switch (event->key.keyval) { case XKB_KEY_KP_Divide: - device->mousekeys_btn = BTN_LEFT; + device->mousekeys_btn = CLUTTER_BUTTON_PRIMARY; return TRUE; case XKB_KEY_KP_Multiply: - device->mousekeys_btn = BTN_MIDDLE; + device->mousekeys_btn = CLUTTER_BUTTON_MIDDLE; return TRUE; case XKB_KEY_KP_Subtract: - device->mousekeys_btn = BTN_RIGHT; + device->mousekeys_btn = CLUTTER_BUTTON_SECONDARY; return TRUE; default: break; @@ -1083,9 +1072,13 @@ handle_mousekeys_press (ClutterEvent *event, } static gboolean -handle_mousekeys_release (ClutterEvent *event, - ClutterInputDeviceEvdev *device) +handle_mousekeys_release (ClutterEvent *event, + MetaInputDeviceNative *device) { + /* Do not handle mousekeys if NumLock is ON */ + if (is_numlock_active (device)) + return FALSE; + switch (event->key.keyval) { case XKB_KEY_KP_0: @@ -1124,18 +1117,23 @@ handle_mousekeys_release (ClutterEvent *event, } static void -clutter_input_device_evdev_process_kbd_a11y_event (ClutterEvent *event, - ClutterInputDevice *device, - ClutterEmitInputDeviceEvent emit_event_func) +meta_input_device_native_process_kbd_a11y_event (ClutterEvent *event, + ClutterInputDevice *device, + ClutterEmitInputDeviceEvent emit_event_func) { - ClutterInputDeviceEvdev *device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (device); + MetaInputDeviceNative *device_evdev = META_INPUT_DEVICE_NATIVE (device); /* Ignore key events injected from IM */ if (event->key.flags & CLUTTER_EVENT_FLAG_INPUT_METHOD) goto emit_event; - if (!(device_evdev->a11y_flags & CLUTTER_A11Y_KEYBOARD_ENABLED)) - goto emit_event; + if (device_evdev->a11y_flags & CLUTTER_A11Y_KEYBOARD_ENABLED) + { + if (event->type == CLUTTER_KEY_PRESS) + handle_enablekeys_press (event, device_evdev); + else + handle_enablekeys_release (event, device_evdev); + } if (device_evdev->a11y_flags & CLUTTER_A11Y_MOUSE_KEYS_ENABLED) { @@ -1147,14 +1145,6 @@ clutter_input_device_evdev_process_kbd_a11y_event (ClutterEvent *e return; /* swallow event */ } - if (device_evdev->a11y_flags & CLUTTER_A11Y_TOGGLE_KEYS_ENABLED) - { - if (event->type == CLUTTER_KEY_PRESS) - handle_togglekeys_press (event, device_evdev); - else - handle_togglekeys_release (event, device_evdev); - } - if ((device_evdev->a11y_flags & CLUTTER_A11Y_BOUNCE_KEYS_ENABLED) && (get_debounce_delay (device) != 0)) { @@ -1192,8 +1182,8 @@ clutter_input_device_evdev_process_kbd_a11y_event (ClutterEvent *e } void -clutter_input_device_evdev_apply_kbd_a11y_settings (ClutterInputDeviceEvdev *device, - ClutterKbdA11ySettings *settings) +meta_input_device_native_apply_kbd_a11y_settings (MetaInputDeviceNative *device, + ClutterKbdA11ySettings *settings) { ClutterKeyboardA11yFlags changed_flags = (device->a11y_flags ^ settings->controls); @@ -1209,7 +1199,7 @@ clutter_input_device_evdev_apply_kbd_a11y_settings (ClutterInputDeviceEvdev *dev update_internal_xkb_state (device, 0, 0); } - if (changed_flags & (CLUTTER_A11Y_KEYBOARD_ENABLED | CLUTTER_A11Y_TOGGLE_KEYS_ENABLED)) + if (changed_flags & CLUTTER_A11Y_KEYBOARD_ENABLED) { device->toggle_slowkeys_timer = 0; device->shift_count = 0; @@ -1230,22 +1220,29 @@ clutter_input_device_evdev_apply_kbd_a11y_settings (ClutterInputDeviceEvdev *dev device->a11y_flags = settings->controls; } +void +meta_input_device_native_a11y_maybe_notify_toggle_keys (MetaInputDeviceNative *device) +{ + if (device->a11y_flags & CLUTTER_A11Y_TOGGLE_KEYS_ENABLED) + meta_input_device_native_bell_notify (device); +} + static void release_device_touch_slot (gpointer value) { - ClutterTouchState *touch_state = value; + MetaTouchState *touch_state = value; - clutter_seat_evdev_release_touch_state (touch_state->seat, touch_state); + meta_seat_native_release_touch_state (touch_state->seat, touch_state); } -ClutterTouchState * -clutter_input_device_evdev_acquire_touch_state (ClutterInputDeviceEvdev *device, - int device_slot) +MetaTouchState * +meta_input_device_native_acquire_touch_state (MetaInputDeviceNative *device, + int device_slot) { - ClutterTouchState *touch_state; + MetaTouchState *touch_state; - touch_state = clutter_seat_evdev_acquire_touch_state (device->seat, - device_slot); + touch_state = meta_seat_native_acquire_touch_state (device->seat, + device_slot); g_hash_table_insert (device->touches, GINT_TO_POINTER (device_slot), touch_state); @@ -1253,47 +1250,48 @@ clutter_input_device_evdev_acquire_touch_state (ClutterInputDeviceEvdev *device, return touch_state; } -ClutterTouchState * -clutter_input_device_evdev_lookup_touch_state (ClutterInputDeviceEvdev *device, - int device_slot) +MetaTouchState * +meta_input_device_native_lookup_touch_state (MetaInputDeviceNative *device, + int device_slot) { return g_hash_table_lookup (device->touches, GINT_TO_POINTER (device_slot)); } void -clutter_input_device_evdev_release_touch_state (ClutterInputDeviceEvdev *device, - ClutterTouchState *touch_state) +meta_input_device_native_release_touch_state (MetaInputDeviceNative *device, + MetaTouchState *touch_state) { g_hash_table_remove (device->touches, GINT_TO_POINTER (touch_state->device_slot)); } static void -clutter_input_device_evdev_class_init (ClutterInputDeviceEvdevClass *klass) +meta_input_device_native_class_init (MetaInputDeviceNativeClass *klass) { + ClutterInputDeviceClass *device_manager_class = CLUTTER_INPUT_DEVICE_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass); - object_class->finalize = clutter_input_device_evdev_finalize; - object_class->set_property = clutter_input_device_evdev_set_property; - object_class->get_property = clutter_input_device_evdev_get_property; + object_class->finalize = meta_input_device_native_finalize; + object_class->set_property = meta_input_device_native_set_property; + object_class->get_property = meta_input_device_native_get_property; - klass->keycode_to_evdev = clutter_input_device_evdev_keycode_to_evdev; - klass->update_from_tool = clutter_input_device_evdev_update_from_tool; - klass->is_mode_switch_button = clutter_input_device_evdev_is_mode_switch_button; - klass->get_group_n_modes = clutter_input_device_evdev_get_group_n_modes; - klass->is_grouped = clutter_input_device_evdev_is_grouped; - klass->process_kbd_a11y_event = clutter_input_device_evdev_process_kbd_a11y_event; + device_manager_class->keycode_to_evdev = meta_input_device_native_keycode_to_evdev; + device_manager_class->update_from_tool = meta_input_device_native_update_from_tool; + device_manager_class->is_mode_switch_button = meta_input_device_native_is_mode_switch_button; + device_manager_class->get_group_n_modes = meta_input_device_native_get_group_n_modes; + device_manager_class->is_grouped = meta_input_device_native_is_grouped; + device_manager_class->process_kbd_a11y_event = meta_input_device_native_process_kbd_a11y_event; obj_props[PROP_DEVICE_MATRIX] = g_param_spec_boxed ("device-matrix", - P_("Device input matrix"), - P_("Device input matrix"), - CAIRO_GOBJECT_TYPE_MATRIX, - CLUTTER_PARAM_READWRITE); + "Device input matrix", + "Device input matrix", + CAIRO_GOBJECT_TYPE_MATRIX, + CLUTTER_PARAM_READWRITE); obj_props[PROP_OUTPUT_ASPECT_RATIO] = g_param_spec_double ("output-aspect-ratio", - P_("Output aspect ratio"), - P_("Output aspect ratio"), + "Output aspect ratio", + "Output aspect ratio", 0, G_MAXDOUBLE, 0, CLUTTER_PARAM_READWRITE); @@ -1301,7 +1299,7 @@ clutter_input_device_evdev_class_init (ClutterInputDeviceEvdevClass *klass) } static void -clutter_input_device_evdev_init (ClutterInputDeviceEvdev *self) +meta_input_device_native_init (MetaInputDeviceNative *self) { cairo_matrix_init_identity (&self->device_matrix); self->device_aspect_ratio = 0; @@ -1312,7 +1310,7 @@ clutter_input_device_evdev_init (ClutterInputDeviceEvdev *self) } /* - * _clutter_input_device_evdev_new: + * meta_input_device_native_new: * @manager: the device manager * @seat: the seat the device will belong to * @libinput_device: the libinput device @@ -1321,23 +1319,20 @@ clutter_input_device_evdev_init (ClutterInputDeviceEvdev *self) * it with the provided seat. */ ClutterInputDevice * -_clutter_input_device_evdev_new (ClutterDeviceManager *manager, - ClutterSeatEvdev *seat, - struct libinput_device *libinput_device) +meta_input_device_native_new (MetaSeatNative *seat, + struct libinput_device *libinput_device) { - ClutterInputDeviceEvdev *device; + MetaInputDeviceNative *device; ClutterInputDeviceType type; - ClutterDeviceManagerEvdev *manager_evdev; - gchar *vendor, *product; - gint device_id, n_rings = 0, n_strips = 0, n_groups = 1; - gchar *node_path; - gdouble width, height; + char *vendor, *product; + int device_id, n_rings = 0, n_strips = 0, n_groups = 1; + char *node_path; + double width, height; - type = _clutter_input_device_evdev_determine_type (libinput_device); + type = meta_input_device_native_determine_type (libinput_device); vendor = g_strdup_printf ("%.4x", libinput_device_get_id_vendor (libinput_device)); product = g_strdup_printf ("%.4x", libinput_device_get_id_product (libinput_device)); - manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (manager); - device_id = _clutter_device_manager_evdev_acquire_device_id (manager_evdev); + device_id = meta_seat_native_acquire_device_id (seat); node_path = g_strdup_printf ("/dev/input/%s", libinput_device_get_sysname (libinput_device)); if (libinput_device_has_capability (libinput_device, @@ -1348,10 +1343,9 @@ _clutter_input_device_evdev_new (ClutterDeviceManager *manager, n_groups = libinput_device_tablet_pad_get_num_mode_groups (libinput_device); } - device = g_object_new (CLUTTER_TYPE_INPUT_DEVICE_EVDEV, + device = g_object_new (META_TYPE_INPUT_DEVICE_NATIVE, "id", device_id, "name", libinput_device_get_name (libinput_device), - "device-manager", manager, "device-type", type, "device-mode", CLUTTER_INPUT_MODE_SLAVE, "enabled", TRUE, @@ -1361,6 +1355,7 @@ _clutter_input_device_evdev_new (ClutterDeviceManager *manager, "n-strips", n_strips, "n-mode-groups", n_groups, "device-node", node_path, + "seat", seat, NULL); device->seat = seat; @@ -1368,9 +1363,9 @@ _clutter_input_device_evdev_new (ClutterDeviceManager *manager, libinput_device_set_user_data (libinput_device, device); libinput_device_ref (libinput_device); - free (vendor); - free (product); - free (node_path); + g_free (vendor); + g_free (product); + g_free (node_path); if (libinput_device_get_size (libinput_device, &width, &height) == 0) device->device_aspect_ratio = width / height; @@ -1379,23 +1374,20 @@ _clutter_input_device_evdev_new (ClutterDeviceManager *manager, } /* - * _clutter_input_device_evdev_new_virtual: - * @manager: the device manager + * meta_input_device_native_new_virtual: * @seat: the seat the device will belong to * @type: the input device type * * Create a new virtual ClutterInputDevice of the given type. */ ClutterInputDevice * -_clutter_input_device_evdev_new_virtual (ClutterDeviceManager *manager, - ClutterSeatEvdev *seat, - ClutterInputDeviceType type, - ClutterInputMode mode) +meta_input_device_native_new_virtual (MetaSeatNative *seat, + ClutterInputDeviceType type, + ClutterInputMode mode) { - ClutterInputDeviceEvdev *device; - ClutterDeviceManagerEvdev *manager_evdev; + MetaInputDeviceNative *device; const char *name; - gint device_id; + int device_id; switch (type) { @@ -1413,15 +1405,14 @@ _clutter_input_device_evdev_new_virtual (ClutterDeviceManager *manager, break; }; - manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (manager); - device_id = _clutter_device_manager_evdev_acquire_device_id (manager_evdev); - device = g_object_new (CLUTTER_TYPE_INPUT_DEVICE_EVDEV, + device_id = meta_seat_native_acquire_device_id (seat); + device = g_object_new (META_TYPE_INPUT_DEVICE_NATIVE, "id", device_id, "name", name, - "device-manager", manager, "device-type", type, "device-mode", mode, "enabled", TRUE, + "seat", seat, NULL); device->seat = seat; @@ -1429,15 +1420,15 @@ _clutter_input_device_evdev_new_virtual (ClutterDeviceManager *manager, return CLUTTER_INPUT_DEVICE (device); } -ClutterSeatEvdev * -_clutter_input_device_evdev_get_seat (ClutterInputDeviceEvdev *device) +MetaSeatNative * +meta_input_device_native_get_seat (MetaInputDeviceNative *device) { return device->seat; } void -_clutter_input_device_evdev_update_leds (ClutterInputDeviceEvdev *device, - enum libinput_led leds) +meta_input_device_native_update_leds (MetaInputDeviceNative *device, + enum libinput_led leds) { if (!device->libinput_device) return; @@ -1446,7 +1437,7 @@ _clutter_input_device_evdev_update_leds (ClutterInputDeviceEvdev *device, } ClutterInputDeviceType -_clutter_input_device_evdev_determine_type (struct libinput_device *ldev) +meta_input_device_native_determine_type (struct libinput_device *ldev) { /* This setting is specific to touchpads and alike, only in these * devices there is this additional layer of touch event interpretation. @@ -1468,7 +1459,7 @@ _clutter_input_device_evdev_determine_type (struct libinput_device *ldev) } /** - * clutter_evdev_input_device_get_libinput_device: + * meta_input_device_native_get_libinput_device: * @device: a #ClutterInputDevice * * Retrieves the libinput_device struct held in @device. @@ -1479,46 +1470,26 @@ _clutter_input_device_evdev_determine_type (struct libinput_device *ldev) * Stability: unstable **/ struct libinput_device * -clutter_evdev_input_device_get_libinput_device (ClutterInputDevice *device) +meta_input_device_native_get_libinput_device (ClutterInputDevice *device) { - ClutterInputDeviceEvdev *device_evdev; + MetaInputDeviceNative *device_evdev; - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE_EVDEV (device), NULL); + g_return_val_if_fail (META_IS_INPUT_DEVICE_NATIVE (device), NULL); - device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (device); + device_evdev = META_INPUT_DEVICE_NATIVE (device); return device_evdev->libinput_device; } -/** - * clutter_evdev_event_sequence_get_slot: - * @sequence: a #ClutterEventSequence - * - * Retrieves the touch slot triggered by this @sequence - * - * Returns: the libinput touch slot. - * - * Since: 1.20 - * Stability: unstable - **/ -gint32 -clutter_evdev_event_sequence_get_slot (const ClutterEventSequence *sequence) -{ - if (!sequence) - return -1; - - return GPOINTER_TO_INT (sequence) - 1; -} - void -clutter_input_device_evdev_translate_coordinates (ClutterInputDevice *device, - ClutterStage *stage, - gfloat *x, - gfloat *y) +meta_input_device_native_translate_coordinates (ClutterInputDevice *device, + ClutterStage *stage, + float *x, + float *y) { - ClutterInputDeviceEvdev *device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (device); + MetaInputDeviceNative *device_evdev = META_INPUT_DEVICE_NATIVE (device); double min_x = 0, min_y = 0, max_x = 1, max_y = 1; - gdouble stage_width, stage_height; + double stage_width, stage_height; double x_d, y_d; stage_width = clutter_actor_get_width (CLUTTER_ACTOR (stage)); @@ -1530,7 +1501,7 @@ clutter_input_device_evdev_translate_coordinates (ClutterInputDevice *device, if (device_evdev->output_ratio > 0 && device_evdev->device_aspect_ratio > 0) { - gdouble ratio = device_evdev->device_aspect_ratio / device_evdev->output_ratio; + double ratio = device_evdev->device_aspect_ratio / device_evdev->output_ratio; if (ratio > 1) x_d *= ratio; @@ -1547,22 +1518,22 @@ clutter_input_device_evdev_translate_coordinates (ClutterInputDevice *device, } void -clutter_input_device_evdev_release_touch_slots (ClutterInputDeviceEvdev *device_evdev, - uint64_t time_us) +meta_input_device_native_release_touch_slots (MetaInputDeviceNative *device_evdev, + uint64_t time_us) { GHashTableIter iter; - ClutterTouchState *touch_state; + MetaTouchState *touch_state; g_hash_table_iter_init (&iter, device_evdev->touches); while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &touch_state)) { - clutter_seat_evdev_notify_touch_event (touch_state->seat, - CLUTTER_INPUT_DEVICE (device_evdev), - CLUTTER_TOUCH_CANCEL, - time_us, - touch_state->seat_slot, - touch_state->coords.x, - touch_state->coords.y); + meta_seat_native_notify_touch_event (touch_state->seat, + CLUTTER_INPUT_DEVICE (device_evdev), + CLUTTER_TOUCH_CANCEL, + time_us, + touch_state->seat_slot, + touch_state->coords.x, + touch_state->coords.y); g_hash_table_iter_remove (&iter); } } diff --git a/src/backends/native/meta-input-device-native.h b/src/backends/native/meta-input-device-native.h new file mode 100644 index 000000000..59cff51ef --- /dev/null +++ b/src/backends/native/meta-input-device-native.h @@ -0,0 +1,144 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Copyright (C) 2010 Intel Corp. + * Copyright (C) 2014 Jonas Ådahl + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Author: Damien Lespiau <damien.lespiau@intel.com> + * Author: Jonas Ådahl <jadahl@gmail.com> + */ + +#ifndef META_INPUT_DEVICE_NATIVE_H +#define META_INPUT_DEVICE_NATIVE_H + +#include <glib-object.h> + +#include "backends/meta-input-device-private.h" +#include "backends/native/meta-seat-native.h" +#include "clutter/clutter-mutter.h" + +#define META_TYPE_INPUT_DEVICE_NATIVE meta_input_device_native_get_type() + +#define META_INPUT_DEVICE_NATIVE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + META_TYPE_INPUT_DEVICE_NATIVE, MetaInputDeviceNative)) + +#define META_INPUT_DEVICE_NATIVE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), \ + META_TYPE_INPUT_DEVICE_NATIVE, MetaInputDeviceNativeClass)) + +#define META_IS_INPUT_DEVICE_NATIVE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + META_TYPE_INPUT_DEVICE_NATIVE)) + +#define META_IS_INPUT_DEVICE_NATIVE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + META_TYPE_INPUT_DEVICE_NATIVE)) + +#define META_INPUT_DEVICE_NATIVE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + META_TYPE_INPUT_DEVICE_NATIVE, MetaInputDeviceNativeClass)) + +typedef struct _MetaInputDeviceNative MetaInputDeviceNative; +typedef struct _MetaInputDeviceNativeClass MetaInputDeviceNativeClass; + +struct _MetaInputDeviceNative +{ + ClutterInputDevice parent; + + struct libinput_device *libinput_device; + MetaSeatNative *seat; + ClutterInputDeviceTool *last_tool; + + cairo_matrix_t device_matrix; + double device_aspect_ratio; /* w:h */ + double output_ratio; /* w:h */ + + GHashTable *touches; + + /* Keyboard a11y */ + ClutterKeyboardA11yFlags a11y_flags; + GList *slow_keys_list; + guint debounce_timer; + uint16_t debounce_key; + xkb_mod_mask_t stickykeys_depressed_mask; + xkb_mod_mask_t stickykeys_latched_mask; + xkb_mod_mask_t stickykeys_locked_mask; + guint toggle_slowkeys_timer; + uint16_t shift_count; + uint32_t last_shift_time; + int mousekeys_btn; + gboolean mousekeys_btn_states[3]; + uint32_t mousekeys_first_motion_time; /* ms */ + uint32_t mousekeys_last_motion_time; /* ms */ + guint mousekeys_init_delay; + guint mousekeys_accel_time; + guint mousekeys_max_speed; + double mousekeys_curve_factor; + guint move_mousekeys_timer; + uint16_t last_mousekeys_key; +}; + +struct _MetaInputDeviceNativeClass +{ + ClutterInputDeviceClass parent_class; +}; + + +GType meta_input_device_native_get_type (void) G_GNUC_CONST; + +ClutterInputDevice * meta_input_device_native_new (MetaSeatNative *seat, + struct libinput_device *libinput_device); + +ClutterInputDevice * meta_input_device_native_new_virtual (MetaSeatNative *seat, + ClutterInputDeviceType type, + ClutterInputMode mode); + +MetaSeatNative * meta_input_device_native_get_seat (MetaInputDeviceNative *device); + +void meta_input_device_native_update_leds (MetaInputDeviceNative *device, + enum libinput_led leds); + +ClutterInputDeviceType meta_input_device_native_determine_type (struct libinput_device *libinput_device); + + +void meta_input_device_native_translate_coordinates (ClutterInputDevice *device, + ClutterStage *stage, + float *x, + float *y); + +void meta_input_device_native_apply_kbd_a11y_settings (MetaInputDeviceNative *device, + ClutterKbdA11ySettings *settings); + +MetaTouchState * meta_input_device_native_acquire_touch_state (MetaInputDeviceNative *device, + int device_slot); + +MetaTouchState * meta_input_device_native_lookup_touch_state (MetaInputDeviceNative *device, + int device_slot); + +void meta_input_device_native_release_touch_state (MetaInputDeviceNative *device, + MetaTouchState *touch_state); + +void meta_input_device_native_release_touch_slots (MetaInputDeviceNative *device_evdev, + uint64_t time_us); + +void meta_input_device_native_a11y_maybe_notify_toggle_keys (MetaInputDeviceNative *device_evdev); + +struct libinput_device * meta_input_device_native_get_libinput_device (ClutterInputDevice *device); + +#endif /* META_INPUT_DEVICE_NATIVE_H */ diff --git a/clutter/clutter/evdev/clutter-input-device-tool-evdev.c b/src/backends/native/meta-input-device-tool-native.c similarity index 51% rename from clutter/clutter/evdev/clutter-input-device-tool-evdev.c rename to src/backends/native/meta-input-device-tool-native.c index 12106069a..8b540afbb 100644 --- a/clutter/clutter/evdev/clutter-input-device-tool-evdev.c +++ b/src/backends/native/meta-input-device-tool-native.c @@ -1,8 +1,4 @@ /* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * * Copyright © 2009, 2010, 2011 Intel Corp. * * This library is free software; you can redistribute it and/or @@ -21,49 +17,46 @@ * Author: Carlos Garnacho <carlosg@gnome.org> */ -#ifdef HAVE_CONFIG_H -#include "clutter-build-config.h" -#endif +#include "config.h" -#include "clutter-input-device-tool-evdev.h" -#include "clutter-evdev.h" +#include "backends/native/meta-input-device-tool-native.h" -G_DEFINE_TYPE (ClutterInputDeviceToolEvdev, clutter_input_device_tool_evdev, +G_DEFINE_TYPE (MetaInputDeviceToolNative, meta_input_device_tool_native, CLUTTER_TYPE_INPUT_DEVICE_TOOL) static void -clutter_input_device_tool_evdev_finalize (GObject *object) +meta_input_device_tool_native_finalize (GObject *object) { - ClutterInputDeviceToolEvdev *tool = CLUTTER_INPUT_DEVICE_TOOL_EVDEV (object); + MetaInputDeviceToolNative *tool = META_INPUT_DEVICE_TOOL_NATIVE (object); g_hash_table_unref (tool->button_map); libinput_tablet_tool_unref (tool->tool); - G_OBJECT_CLASS (clutter_input_device_tool_evdev_parent_class)->finalize (object); + G_OBJECT_CLASS (meta_input_device_tool_native_parent_class)->finalize (object); } static void -clutter_input_device_tool_evdev_class_init (ClutterInputDeviceToolEvdevClass *klass) +meta_input_device_tool_native_class_init (MetaInputDeviceToolNativeClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - object_class->finalize = clutter_input_device_tool_evdev_finalize; + object_class->finalize = meta_input_device_tool_native_finalize; } static void -clutter_input_device_tool_evdev_init (ClutterInputDeviceToolEvdev *tool) +meta_input_device_tool_native_init (MetaInputDeviceToolNative *tool) { tool->button_map = g_hash_table_new (NULL, NULL); } ClutterInputDeviceTool * -clutter_input_device_tool_evdev_new (struct libinput_tablet_tool *tool, - guint64 serial, - ClutterInputDeviceToolType type) +meta_input_device_tool_native_new (struct libinput_tablet_tool *tool, + uint64_t serial, + ClutterInputDeviceToolType type) { - ClutterInputDeviceToolEvdev *evdev_tool; + MetaInputDeviceToolNative *evdev_tool; - evdev_tool = g_object_new (CLUTTER_TYPE_INPUT_DEVICE_TOOL_EVDEV, + evdev_tool = g_object_new (META_TYPE_INPUT_DEVICE_TOOL_NATIVE, "type", type, "serial", serial, "id", libinput_tablet_tool_get_tool_id (tool), @@ -75,18 +68,18 @@ clutter_input_device_tool_evdev_new (struct libinput_tablet_tool *tool, } void -clutter_evdev_input_device_tool_set_pressure_curve (ClutterInputDeviceTool *tool, - gdouble curve[4]) +meta_input_device_tool_native_set_pressure_curve (ClutterInputDeviceTool *tool, + double curve[4]) { - ClutterInputDeviceToolEvdev *evdev_tool; + MetaInputDeviceToolNative *evdev_tool; - g_return_if_fail (CLUTTER_IS_INPUT_DEVICE_TOOL_EVDEV (tool)); + g_return_if_fail (META_IS_INPUT_DEVICE_TOOL_NATIVE (tool)); g_return_if_fail (curve[0] >= 0 && curve[0] <= 1 && curve[1] >= 0 && curve[1] <= 1 && curve[2] >= 0 && curve[2] <= 1 && curve[3] >= 0 && curve[3] <= 1); - evdev_tool = CLUTTER_INPUT_DEVICE_TOOL_EVDEV (tool); + evdev_tool = META_INPUT_DEVICE_TOOL_NATIVE (tool); evdev_tool->pressure_curve[0] = curve[0]; evdev_tool->pressure_curve[1] = curve[1]; evdev_tool->pressure_curve[2] = curve[2]; @@ -94,15 +87,15 @@ clutter_evdev_input_device_tool_set_pressure_curve (ClutterInputDeviceTool *tool } void -clutter_evdev_input_device_tool_set_button_code (ClutterInputDeviceTool *tool, - guint button, - guint evcode) +meta_input_device_tool_native_set_button_code (ClutterInputDeviceTool *tool, + uint32_t button, + uint32_t evcode) { - ClutterInputDeviceToolEvdev *evdev_tool; + MetaInputDeviceToolNative *evdev_tool; - g_return_if_fail (CLUTTER_IS_INPUT_DEVICE_TOOL_EVDEV (tool)); + g_return_if_fail (META_IS_INPUT_DEVICE_TOOL_NATIVE (tool)); - evdev_tool = CLUTTER_INPUT_DEVICE_TOOL_EVDEV (tool); + evdev_tool = META_INPUT_DEVICE_TOOL_NATIVE (tool); if (evcode == 0) { @@ -115,14 +108,14 @@ clutter_evdev_input_device_tool_set_button_code (ClutterInputDeviceTool *tool, } } -static gdouble -calculate_bezier_position (gdouble pos, - gdouble x1, - gdouble y1, - gdouble x2, - gdouble y2) +static double +calculate_bezier_position (double pos, + double x1, + double y1, + double x2, + double y2) { - gdouble int1_y, int2_y; + double int1_y, int2_y; pos = CLAMP (pos, 0, 1); @@ -136,15 +129,15 @@ calculate_bezier_position (gdouble pos, return (pos * (int2_y - int1_y)) + int1_y; } -gdouble -clutter_input_device_tool_evdev_translate_pressure (ClutterInputDeviceTool *tool, - gdouble pressure) +double +meta_input_device_tool_native_translate_pressure (ClutterInputDeviceTool *tool, + double pressure) { - ClutterInputDeviceToolEvdev *evdev_tool; + MetaInputDeviceToolNative *evdev_tool; - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE_TOOL (tool), pressure); + g_return_val_if_fail (META_IS_INPUT_DEVICE_TOOL_NATIVE (tool), pressure); - evdev_tool = CLUTTER_INPUT_DEVICE_TOOL_EVDEV (tool); + evdev_tool = META_INPUT_DEVICE_TOOL_NATIVE (tool); return calculate_bezier_position (CLAMP (pressure, 0, 1), evdev_tool->pressure_curve[0], @@ -153,15 +146,15 @@ clutter_input_device_tool_evdev_translate_pressure (ClutterInputDeviceTool *tool evdev_tool->pressure_curve[3]); } -guint -clutter_input_device_tool_evdev_get_button_code (ClutterInputDeviceTool *tool, - guint button) +uint32_t +meta_input_device_tool_native_get_button_code (ClutterInputDeviceTool *tool, + uint32_t button) { - ClutterInputDeviceToolEvdev *evdev_tool; + MetaInputDeviceToolNative *evdev_tool; - g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE_TOOL (tool), 0); + g_return_val_if_fail (META_IS_INPUT_DEVICE_TOOL_NATIVE (tool), 0); - evdev_tool = CLUTTER_INPUT_DEVICE_TOOL_EVDEV (tool); + evdev_tool = META_INPUT_DEVICE_TOOL_NATIVE (tool); return GPOINTER_TO_UINT (g_hash_table_lookup (evdev_tool->button_map, GUINT_TO_POINTER (button))); diff --git a/src/backends/native/meta-input-device-tool-native.h b/src/backends/native/meta-input-device-tool-native.h new file mode 100644 index 000000000..83e79930a --- /dev/null +++ b/src/backends/native/meta-input-device-tool-native.h @@ -0,0 +1,86 @@ +/* + * Copyright © 2009, 2010, 2011 Intel Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef META_INPUT_DEVICE_NATIVE_TOOL_H +#define META_INPUT_DEVICE_NATIVE_TOOL_H + +#include <libinput.h> + +#include "clutter/clutter.h" + +G_BEGIN_DECLS + +#define META_TYPE_INPUT_DEVICE_TOOL_NATIVE (meta_input_device_tool_native_get_type ()) + +#define META_INPUT_DEVICE_TOOL_NATIVE(o) \ + (G_TYPE_CHECK_INSTANCE_CAST ((o), \ + META_TYPE_INPUT_DEVICE_TOOL_NATIVE, MetaInputDeviceToolNative)) + +#define META_IS_INPUT_DEVICE_TOOL_NATIVE(o) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((o), \ + META_TYPE_INPUT_DEVICE_TOOL_NATIVE)) + +#define META_INPUT_DEVICE_TOOL_NATIVE_CLASS(c) \ + (G_TYPE_CHECK_CLASS_CAST ((c), \ + META_TYPE_INPUT_DEVICE_TOOL_EVDEV, MetaInputDeviceToolNativeClass)) + +#define META_IS_INPUT_DEVICE_TOOL_NATIVE_CLASS(c) \ + (G_TYPE_CHECK_CLASS_TYPE ((c), \ + META_TYPE_INPUT_DEVICE_TOOL_NATIVE)) + +#define META_INPUT_DEVICE_TOOL_NATIVE_GET_CLASS(o) \ + (G_TYPE_INSTANCE_GET_CLASS ((o), \ + META_TYPE_INPUT_DEVICE_TOOL_NATIVE, MetaInputDeviceToolNativeClass)) + +typedef struct _MetaInputDeviceToolNative MetaInputDeviceToolNative; +typedef struct _MetaInputDeviceToolNativeClass MetaInputDeviceToolNativeClass; + +struct _MetaInputDeviceToolNative +{ + ClutterInputDeviceTool parent_instance; + struct libinput_tablet_tool *tool; + GHashTable *button_map; + double pressure_curve[4]; +}; + +struct _MetaInputDeviceToolNativeClass +{ + ClutterInputDeviceToolClass parent_class; +}; + +GType meta_input_device_tool_native_get_type (void) G_GNUC_CONST; + +ClutterInputDeviceTool * meta_input_device_tool_native_new (struct libinput_tablet_tool *tool, + uint64_t serial, + ClutterInputDeviceToolType type); + +gdouble meta_input_device_tool_native_translate_pressure (ClutterInputDeviceTool *tool, + double pressure); +uint32_t meta_input_device_tool_native_get_button_code (ClutterInputDeviceTool *tool, + uint32_t button); + +void meta_input_device_tool_native_set_pressure_curve (ClutterInputDeviceTool *tool, + double curve[4]); +void meta_input_device_tool_native_set_button_code (ClutterInputDeviceTool *tool, + uint32_t button, + uint32_t evcode); + +G_END_DECLS + +#endif /* META_INPUT_DEVICE_NATIVE_TOOL_H */ diff --git a/src/backends/native/meta-input-settings-native.c b/src/backends/native/meta-input-settings-native.c new file mode 100644 index 000000000..f0ace047b --- /dev/null +++ b/src/backends/native/meta-input-settings-native.c @@ -0,0 +1,666 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#include "config.h" + +#include <linux/input-event-codes.h> +#include <libinput.h> + +#include "backends/meta-logical-monitor.h" +#include "backends/native/meta-backend-native.h" +#include "backends/native/meta-input-device-native.h" +#include "backends/native/meta-input-device-tool-native.h" +#include "backends/native/meta-input-settings-native.h" + +G_DEFINE_TYPE (MetaInputSettingsNative, meta_input_settings_native, META_TYPE_INPUT_SETTINGS) + +static void +meta_input_settings_native_set_send_events (MetaInputSettings *settings, + ClutterInputDevice *device, + CDesktopDeviceSendEvents mode) +{ + enum libinput_config_send_events_mode libinput_mode; + struct libinput_device *libinput_device; + + switch (mode) + { + case C_DESKTOP_DEVICE_SEND_EVENTS_DISABLED: + libinput_mode = LIBINPUT_CONFIG_SEND_EVENTS_DISABLED; + break; + case C_DESKTOP_DEVICE_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE: + libinput_mode = LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE; + break; + case C_DESKTOP_DEVICE_SEND_EVENTS_ENABLED: + libinput_mode = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED; + break; + default: + g_assert_not_reached (); + } + + libinput_device = meta_input_device_native_get_libinput_device (device); + if (!libinput_device) + return; + libinput_device_config_send_events_set_mode (libinput_device, libinput_mode); +} + +static void +meta_input_settings_native_set_matrix (MetaInputSettings *settings, + ClutterInputDevice *device, + gfloat matrix[6]) +{ + cairo_matrix_t dev_matrix; + + cairo_matrix_init (&dev_matrix, matrix[0], matrix[3], matrix[1], + matrix[4], matrix[2], matrix[5]); + g_object_set (device, "device-matrix", &dev_matrix, NULL); +} + +static void +meta_input_settings_native_set_speed (MetaInputSettings *settings, + ClutterInputDevice *device, + gdouble speed) +{ + struct libinput_device *libinput_device; + + libinput_device = meta_input_device_native_get_libinput_device (device); + if (!libinput_device) + return; + libinput_device_config_accel_set_speed (libinput_device, + CLAMP (speed, -1, 1)); +} + +static void +meta_input_settings_native_set_left_handed (MetaInputSettings *settings, + ClutterInputDevice *device, + gboolean enabled) +{ + struct libinput_device *libinput_device; + + libinput_device = meta_input_device_native_get_libinput_device (device); + if (!libinput_device) + return; + + if (libinput_device_config_left_handed_is_available (libinput_device)) + libinput_device_config_left_handed_set (libinput_device, enabled); +} + +static void +meta_input_settings_native_set_tap_enabled (MetaInputSettings *settings, + ClutterInputDevice *device, + gboolean enabled) +{ + struct libinput_device *libinput_device; + + libinput_device = meta_input_device_native_get_libinput_device (device); + if (!libinput_device) + return; + + if (libinput_device_config_tap_get_finger_count (libinput_device) > 0) + libinput_device_config_tap_set_enabled (libinput_device, + enabled ? + LIBINPUT_CONFIG_TAP_ENABLED : + LIBINPUT_CONFIG_TAP_DISABLED); +} + +static void +meta_input_settings_native_set_tap_and_drag_enabled (MetaInputSettings *settings, + ClutterInputDevice *device, + gboolean enabled) +{ + struct libinput_device *libinput_device; + + libinput_device = meta_input_device_native_get_libinput_device (device); + if (!libinput_device) + return; + + if (libinput_device_config_tap_get_finger_count (libinput_device) > 0) + libinput_device_config_tap_set_drag_enabled (libinput_device, + enabled ? + LIBINPUT_CONFIG_DRAG_ENABLED : + LIBINPUT_CONFIG_DRAG_DISABLED); +} + +static void +meta_input_settings_native_set_disable_while_typing (MetaInputSettings *settings, + ClutterInputDevice *device, + gboolean enabled) +{ + struct libinput_device *libinput_device; + + libinput_device = meta_input_device_native_get_libinput_device (device); + + if (!libinput_device) + return; + + if (libinput_device_config_dwt_is_available (libinput_device)) + libinput_device_config_dwt_set_enabled (libinput_device, + enabled ? + LIBINPUT_CONFIG_DWT_ENABLED : + LIBINPUT_CONFIG_DWT_DISABLED); +} + +static void +meta_input_settings_native_set_invert_scroll (MetaInputSettings *settings, + ClutterInputDevice *device, + gboolean inverted) +{ + struct libinput_device *libinput_device; + + libinput_device = meta_input_device_native_get_libinput_device (device); + if (!libinput_device) + return; + + if (libinput_device_config_scroll_has_natural_scroll (libinput_device)) + libinput_device_config_scroll_set_natural_scroll_enabled (libinput_device, + inverted); +} + +static gboolean +device_set_scroll_method (struct libinput_device *libinput_device, + enum libinput_config_scroll_method method) +{ + enum libinput_config_status status = + libinput_device_config_scroll_set_method (libinput_device, method); + return status == LIBINPUT_CONFIG_STATUS_SUCCESS; +} + +static gboolean +device_set_click_method (struct libinput_device *libinput_device, + enum libinput_config_click_method method) +{ + enum libinput_config_status status = + libinput_device_config_click_set_method (libinput_device, method); + return status == LIBINPUT_CONFIG_STATUS_SUCCESS; +} + +static void +meta_input_settings_native_set_edge_scroll (MetaInputSettings *settings, + ClutterInputDevice *device, + gboolean edge_scrolling_enabled) +{ + struct libinput_device *libinput_device; + enum libinput_config_scroll_method current, method; + + libinput_device = meta_input_device_native_get_libinput_device (device); + + method = edge_scrolling_enabled ? LIBINPUT_CONFIG_SCROLL_EDGE : LIBINPUT_CONFIG_SCROLL_NO_SCROLL; + current = libinput_device_config_scroll_get_method (libinput_device); + current &= ~LIBINPUT_CONFIG_SCROLL_EDGE; + + device_set_scroll_method (libinput_device, current | method); +} + +static void +meta_input_settings_native_set_two_finger_scroll (MetaInputSettings *settings, + ClutterInputDevice *device, + gboolean two_finger_scroll_enabled) +{ + struct libinput_device *libinput_device; + enum libinput_config_scroll_method current, method; + + libinput_device = meta_input_device_native_get_libinput_device (device); + + method = two_finger_scroll_enabled ? LIBINPUT_CONFIG_SCROLL_2FG : LIBINPUT_CONFIG_SCROLL_NO_SCROLL; + current = libinput_device_config_scroll_get_method (libinput_device); + current &= ~LIBINPUT_CONFIG_SCROLL_2FG; + + device_set_scroll_method (libinput_device, current | method); +} + +static gboolean +meta_input_settings_native_has_two_finger_scroll (MetaInputSettings *settings, + ClutterInputDevice *device) +{ + struct libinput_device *libinput_device; + + libinput_device = meta_input_device_native_get_libinput_device (device); + if (!libinput_device) + return FALSE; + + return libinput_device_config_scroll_get_methods (libinput_device) & LIBINPUT_CONFIG_SCROLL_2FG; +} + +static void +meta_input_settings_native_set_scroll_button (MetaInputSettings *settings, + ClutterInputDevice *device, + guint button) +{ + struct libinput_device *libinput_device; + enum libinput_config_scroll_method method; + guint evcode; + + libinput_device = meta_input_device_native_get_libinput_device (device); + if (!libinput_device) + return; + + if (button == 0) + { + method = LIBINPUT_CONFIG_SCROLL_NO_SCROLL; + evcode = 0; + } + else + { + /* Compensate for X11 scroll buttons */ + if (button > 7) + button -= 4; + + /* Button is 1-indexed */ + evcode = (BTN_LEFT - 1) + button; + method = LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN; + } + + if (!device_set_scroll_method (libinput_device, method)) + return; + + libinput_device_config_scroll_set_button (libinput_device, evcode); +} + +static void +meta_input_settings_native_set_click_method (MetaInputSettings *settings, + ClutterInputDevice *device, + CDesktopTouchpadClickMethod mode) +{ + enum libinput_config_click_method click_method = 0; + struct libinput_device *libinput_device; + + libinput_device = meta_input_device_native_get_libinput_device (device); + if (!libinput_device) + return; + + switch (mode) + { + case C_DESKTOP_TOUCHPAD_CLICK_METHOD_DEFAULT: + click_method = libinput_device_config_click_get_default_method (libinput_device); + break; + case C_DESKTOP_TOUCHPAD_CLICK_METHOD_NONE: + click_method = LIBINPUT_CONFIG_CLICK_METHOD_NONE; + break; + case C_DESKTOP_TOUCHPAD_CLICK_METHOD_AREAS: + click_method = LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS; + break; + case C_DESKTOP_TOUCHPAD_CLICK_METHOD_FINGERS: + click_method = LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER; + break; + default: + g_assert_not_reached (); + return; + } + + device_set_click_method (libinput_device, click_method); +} + +static void +meta_input_settings_native_set_keyboard_repeat (MetaInputSettings *settings, + gboolean enabled, + guint delay, + guint interval) +{ + ClutterSeat *seat; + + seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); + meta_seat_native_set_keyboard_repeat (META_SEAT_NATIVE (seat), + enabled, delay, interval); +} + +static void +set_device_accel_profile (ClutterInputDevice *device, + CDesktopPointerAccelProfile profile) +{ + struct libinput_device *libinput_device; + enum libinput_config_accel_profile libinput_profile; + uint32_t profiles; + + libinput_device = meta_input_device_native_get_libinput_device (device); + + switch (profile) + { + case C_DESKTOP_POINTER_ACCEL_PROFILE_FLAT: + libinput_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT; + break; + case C_DESKTOP_POINTER_ACCEL_PROFILE_ADAPTIVE: + libinput_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE; + break; + default: + g_warn_if_reached (); + case C_DESKTOP_POINTER_ACCEL_PROFILE_DEFAULT: + libinput_profile = + libinput_device_config_accel_get_default_profile (libinput_device); + } + + profiles = libinput_device_config_accel_get_profiles (libinput_device); + if ((profiles & libinput_profile) == 0) + { + libinput_profile = + libinput_device_config_accel_get_default_profile (libinput_device); + } + + libinput_device_config_accel_set_profile (libinput_device, + libinput_profile); +} + +static gboolean +has_udev_property (ClutterInputDevice *device, + const char *property) +{ + struct libinput_device *libinput_device; + struct udev_device *udev_device; + struct udev_device *parent_udev_device; + + libinput_device = meta_input_device_native_get_libinput_device (device); + if (!libinput_device) + return FALSE; + + udev_device = libinput_device_get_udev_device (libinput_device); + + if (!udev_device) + return FALSE; + + if (NULL != udev_device_get_property_value (udev_device, property)) + { + udev_device_unref (udev_device); + return TRUE; + } + + parent_udev_device = udev_device_get_parent (udev_device); + udev_device_unref (udev_device); + + if (!parent_udev_device) + return FALSE; + + if (NULL != udev_device_get_property_value (parent_udev_device, property)) + return TRUE; + + return FALSE; +} + +static gboolean +is_mouse_device (ClutterInputDevice *device) +{ + return (has_udev_property (device, "ID_INPUT_MOUSE") && + !has_udev_property (device, "ID_INPUT_POINTINGSTICK")); +} + +static gboolean +meta_input_settings_native_is_touchpad_device (MetaInputSettings *settings, + ClutterInputDevice *device) +{ + return has_udev_property (device, "ID_INPUT_TOUCHPAD"); +} + +static gboolean +meta_input_settings_native_is_trackball_device (MetaInputSettings *settings, + ClutterInputDevice *device) +{ + return has_udev_property (device, "ID_INPUT_TRACKBALL"); +} + +static void +meta_input_settings_native_set_mouse_accel_profile (MetaInputSettings *settings, + ClutterInputDevice *device, + CDesktopPointerAccelProfile profile) +{ + if (!is_mouse_device (device)) + return; + + set_device_accel_profile (device, profile); +} + +static void +meta_input_settings_native_set_trackball_accel_profile (MetaInputSettings *settings, + ClutterInputDevice *device, + CDesktopPointerAccelProfile profile) +{ + if (!meta_input_settings_native_is_trackball_device (settings, device)) + return; + + set_device_accel_profile (device, profile); +} + +static void +meta_input_settings_native_set_tablet_mapping (MetaInputSettings *settings, + ClutterInputDevice *device, + CDesktopTabletMapping mapping) +{ + ClutterInputDeviceMapping dev_mapping; + + if (mapping == C_DESKTOP_TABLET_MAPPING_ABSOLUTE) + dev_mapping = CLUTTER_INPUT_DEVICE_MAPPING_ABSOLUTE; + else if (mapping == C_DESKTOP_TABLET_MAPPING_RELATIVE) + dev_mapping = CLUTTER_INPUT_DEVICE_MAPPING_RELATIVE; + else + return; + + clutter_input_device_set_mapping_mode (device, dev_mapping); +} + +static void +meta_input_settings_native_set_tablet_keep_aspect (MetaInputSettings *settings, + ClutterInputDevice *device, + MetaLogicalMonitor *logical_monitor, + gboolean keep_aspect) +{ + double aspect_ratio = 0; + + if (keep_aspect) + { + int width, height; + + if (logical_monitor) + { + width = logical_monitor->rect.width; + height = logical_monitor->rect.height; + } + else + { + MetaMonitorManager *monitor_manager; + MetaBackend *backend; + + backend = meta_get_backend (); + monitor_manager = meta_backend_get_monitor_manager (backend); + meta_monitor_manager_get_screen_size (monitor_manager, + &width, + &height); + } + + aspect_ratio = (double) width / height; + } + + g_object_set (device, "output-aspect-ratio", aspect_ratio, NULL); +} + +static void +meta_input_settings_native_set_tablet_area (MetaInputSettings *settings, + ClutterInputDevice *device, + gdouble padding_left, + gdouble padding_right, + gdouble padding_top, + gdouble padding_bottom) +{ + struct libinput_device *libinput_device; + gfloat scale_x; + gfloat scale_y; + gfloat offset_x; + gfloat offset_y; + + scale_x = 1. / (1. - (padding_left + padding_right)); + scale_y = 1. / (1. - (padding_top + padding_bottom)); + offset_x = -padding_left * scale_x; + offset_y = -padding_top * scale_y; + + gfloat matrix[6] = { scale_x, 0., offset_x, + 0., scale_y, offset_y }; + + libinput_device = meta_input_device_native_get_libinput_device (device); + if (!libinput_device || + !libinput_device_config_calibration_has_matrix (libinput_device)) + return; + + libinput_device_config_calibration_set_matrix (libinput_device, matrix); +} + +static void +meta_input_settings_native_set_stylus_pressure (MetaInputSettings *settings, + ClutterInputDevice *device, + ClutterInputDeviceTool *tool, + const gint curve[4]) +{ + gdouble pressure_curve[4]; + + pressure_curve[0] = (gdouble) curve[0] / 100; + pressure_curve[1] = (gdouble) curve[1] / 100; + pressure_curve[2] = (gdouble) curve[2] / 100; + pressure_curve[3] = (gdouble) curve[3] / 100; + + meta_input_device_tool_native_set_pressure_curve (tool, pressure_curve); +} + +static guint +action_to_evcode (CDesktopStylusButtonAction action) +{ + switch (action) + { + case C_DESKTOP_STYLUS_BUTTON_ACTION_MIDDLE: + return BTN_STYLUS; + case C_DESKTOP_STYLUS_BUTTON_ACTION_RIGHT: + return BTN_STYLUS2; + case C_DESKTOP_STYLUS_BUTTON_ACTION_BACK: + return BTN_BACK; + case C_DESKTOP_STYLUS_BUTTON_ACTION_FORWARD: + return BTN_FORWARD; + case C_DESKTOP_STYLUS_BUTTON_ACTION_DEFAULT: + default: + return 0; + } +} + +static void +meta_input_settings_native_set_stylus_button_map (MetaInputSettings *settings, + ClutterInputDevice *device, + ClutterInputDeviceTool *tool, + CDesktopStylusButtonAction primary, + CDesktopStylusButtonAction secondary, + CDesktopStylusButtonAction tertiary) +{ + meta_input_device_tool_native_set_button_code (tool, CLUTTER_BUTTON_MIDDLE, + action_to_evcode (primary)); + meta_input_device_tool_native_set_button_code (tool, CLUTTER_BUTTON_SECONDARY, + action_to_evcode (secondary)); + meta_input_device_tool_native_set_button_code (tool, 8, /* Back */ + action_to_evcode (tertiary)); +} + +static void +meta_input_settings_native_set_mouse_middle_click_emulation (MetaInputSettings *settings, + ClutterInputDevice *device, + gboolean enabled) +{ + struct libinput_device *libinput_device; + + if (!is_mouse_device (device)) + return; + + libinput_device = meta_input_device_native_get_libinput_device (device); + if (!libinput_device) + return; + + if (libinput_device_config_middle_emulation_is_available (libinput_device)) + libinput_device_config_middle_emulation_set_enabled (libinput_device, enabled); +} + +static void +meta_input_settings_native_set_touchpad_middle_click_emulation (MetaInputSettings *settings, + ClutterInputDevice *device, + gboolean enabled) +{ + struct libinput_device *libinput_device; + + if (!meta_input_settings_native_is_touchpad_device (settings, device)) + return; + + libinput_device = meta_input_device_native_get_libinput_device (device); + if (!libinput_device) + return; + + if (libinput_device_config_middle_emulation_is_available (libinput_device)) + libinput_device_config_middle_emulation_set_enabled (libinput_device, enabled); +} + +static void +meta_input_settings_native_set_trackball_middle_click_emulation (MetaInputSettings *settings, + ClutterInputDevice *device, + gboolean enabled) +{ + struct libinput_device *libinput_device; + + if (!meta_input_settings_native_is_trackball_device (settings, device)) + return; + + libinput_device = meta_input_device_native_get_libinput_device (device); + if (!libinput_device) + return; + + if (libinput_device_config_middle_emulation_is_available (libinput_device)) + libinput_device_config_middle_emulation_set_enabled (libinput_device, enabled); +} + +static void +meta_input_settings_native_class_init (MetaInputSettingsNativeClass *klass) +{ + MetaInputSettingsClass *input_settings_class = META_INPUT_SETTINGS_CLASS (klass); + + input_settings_class->set_send_events = meta_input_settings_native_set_send_events; + input_settings_class->set_matrix = meta_input_settings_native_set_matrix; + input_settings_class->set_speed = meta_input_settings_native_set_speed; + input_settings_class->set_left_handed = meta_input_settings_native_set_left_handed; + input_settings_class->set_tap_enabled = meta_input_settings_native_set_tap_enabled; + input_settings_class->set_tap_and_drag_enabled = meta_input_settings_native_set_tap_and_drag_enabled; + input_settings_class->set_invert_scroll = meta_input_settings_native_set_invert_scroll; + input_settings_class->set_edge_scroll = meta_input_settings_native_set_edge_scroll; + input_settings_class->set_two_finger_scroll = meta_input_settings_native_set_two_finger_scroll; + input_settings_class->set_scroll_button = meta_input_settings_native_set_scroll_button; + input_settings_class->set_click_method = meta_input_settings_native_set_click_method; + input_settings_class->set_keyboard_repeat = meta_input_settings_native_set_keyboard_repeat; + input_settings_class->set_disable_while_typing = meta_input_settings_native_set_disable_while_typing; + + input_settings_class->set_tablet_mapping = meta_input_settings_native_set_tablet_mapping; + input_settings_class->set_tablet_keep_aspect = meta_input_settings_native_set_tablet_keep_aspect; + input_settings_class->set_tablet_area = meta_input_settings_native_set_tablet_area; + + input_settings_class->set_mouse_accel_profile = meta_input_settings_native_set_mouse_accel_profile; + input_settings_class->set_trackball_accel_profile = meta_input_settings_native_set_trackball_accel_profile; + + input_settings_class->set_stylus_pressure = meta_input_settings_native_set_stylus_pressure; + input_settings_class->set_stylus_button_map = meta_input_settings_native_set_stylus_button_map; + + input_settings_class->set_mouse_middle_click_emulation = meta_input_settings_native_set_mouse_middle_click_emulation; + input_settings_class->set_touchpad_middle_click_emulation = meta_input_settings_native_set_touchpad_middle_click_emulation; + input_settings_class->set_trackball_middle_click_emulation = meta_input_settings_native_set_trackball_middle_click_emulation; + + input_settings_class->has_two_finger_scroll = meta_input_settings_native_has_two_finger_scroll; + input_settings_class->is_trackball_device = meta_input_settings_native_is_trackball_device; +} + +static void +meta_input_settings_native_init (MetaInputSettingsNative *settings) +{ +} diff --git a/src/backends/native/meta-input-settings-native.h b/src/backends/native/meta-input-settings-native.h new file mode 100644 index 000000000..ee600d5d8 --- /dev/null +++ b/src/backends/native/meta-input-settings-native.h @@ -0,0 +1,49 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright 2014 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef META_INPUT_SETTINGS_NATIVE_H +#define META_INPUT_SETTINGS_NATIVE_H + +#include "backends/meta-input-settings-private.h" + +#define META_TYPE_INPUT_SETTINGS_NATIVE (meta_input_settings_native_get_type ()) +#define META_INPUT_SETTINGS_NATIVE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_INPUT_SETTINGS_NATIVE, MetaInputSettingsNative)) +#define META_INPUT_SETTINGS_NATIVE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_INPUT_SETTINGS_NATIVE, MetaInputSettingsNativeClass)) +#define META_IS_INPUT_SETTINGS_NATIVE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_INPUT_SETTINGS_NATIVE)) +#define META_IS_INPUT_SETTINGS_NATIVE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_INPUT_SETTINGS_NATIVE)) +#define META_INPUT_SETTINGS_NATIVE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_INPUT_SETTINGS_NATIVE, MetaInputSettingsNativeClass)) + +typedef struct _MetaInputSettingsNative MetaInputSettingsNative; +typedef struct _MetaInputSettingsNativeClass MetaInputSettingsNativeClass; + +struct _MetaInputSettingsNative +{ + MetaInputSettings parent_instance; +}; + +struct _MetaInputSettingsNativeClass +{ + MetaInputSettingsClass parent_class; +}; + +GType meta_input_settings_native_get_type (void) G_GNUC_CONST; + +#endif /* META_INPUT_SETTINGS_NATIVE_H */ diff --git a/src/backends/native/meta-keymap-native.c b/src/backends/native/meta-keymap-native.c new file mode 100644 index 000000000..622cfd354 --- /dev/null +++ b/src/backends/native/meta-keymap-native.c @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2018 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#include "config.h" + +#include "backends/native/meta-keymap-native.h" +#include "backends/native/meta-seat-native.h" + +static const char *option_xkb_layout = "us"; +static const char *option_xkb_variant = ""; +static const char *option_xkb_options = ""; + +typedef struct _MetaKeymapNative MetaKeymapNative; + +struct _MetaKeymapNative +{ + ClutterKeymap parent_instance; + + struct xkb_keymap *keymap; +}; + +G_DEFINE_TYPE (MetaKeymapNative, meta_keymap_native, + CLUTTER_TYPE_KEYMAP) + +static void +meta_keymap_native_finalize (GObject *object) +{ + MetaKeymapNative *keymap = META_KEYMAP_NATIVE (object); + + xkb_keymap_unref (keymap->keymap); + + G_OBJECT_CLASS (meta_keymap_native_parent_class)->finalize (object); +} + +static gboolean +meta_keymap_native_get_num_lock_state (ClutterKeymap *keymap) +{ + struct xkb_state *xkb_state; + ClutterSeat *seat; + + seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); + xkb_state = meta_seat_native_get_xkb_state (META_SEAT_NATIVE (seat)); + + return xkb_state_mod_name_is_active (xkb_state, + XKB_MOD_NAME_NUM, + XKB_STATE_MODS_LATCHED | + XKB_STATE_MODS_LOCKED); +} + +static gboolean +meta_keymap_native_get_caps_lock_state (ClutterKeymap *keymap) +{ + struct xkb_state *xkb_state; + ClutterSeat *seat; + + seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); + xkb_state = meta_seat_native_get_xkb_state (META_SEAT_NATIVE (seat)); + + return xkb_state_mod_name_is_active (xkb_state, + XKB_MOD_NAME_CAPS, + XKB_STATE_MODS_LATCHED | + XKB_STATE_MODS_LOCKED); +} + +static PangoDirection +meta_keymap_native_get_direction (ClutterKeymap *keymap) +{ + return PANGO_DIRECTION_NEUTRAL; +} + +static void +meta_keymap_native_class_init (MetaKeymapNativeClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + ClutterKeymapClass *keymap_class = CLUTTER_KEYMAP_CLASS (klass); + + object_class->finalize = meta_keymap_native_finalize; + + keymap_class->get_num_lock_state = meta_keymap_native_get_num_lock_state; + keymap_class->get_caps_lock_state = meta_keymap_native_get_caps_lock_state; + keymap_class->get_direction = meta_keymap_native_get_direction; +} + +static void +meta_keymap_native_init (MetaKeymapNative *keymap) +{ + struct xkb_context *ctx; + struct xkb_rule_names names; + + names.rules = "evdev"; + names.model = "pc105"; + names.layout = option_xkb_layout; + names.variant = option_xkb_variant; + names.options = option_xkb_options; + + ctx = xkb_context_new (XKB_CONTEXT_NO_FLAGS); + g_assert (ctx); + keymap->keymap = xkb_keymap_new_from_names (ctx, &names, 0); + xkb_context_unref (ctx); +} + +void +meta_keymap_native_set_keyboard_map (MetaKeymapNative *keymap, + struct xkb_keymap *xkb_keymap) +{ + if (keymap->keymap) + xkb_keymap_unref (keymap->keymap); + keymap->keymap = xkb_keymap_ref (xkb_keymap); +} + +struct xkb_keymap * +meta_keymap_native_get_keyboard_map (MetaKeymapNative *keymap) +{ + return keymap->keymap; +} diff --git a/src/backends/native/meta-keymap-native.h b/src/backends/native/meta-keymap-native.h new file mode 100644 index 000000000..27364984c --- /dev/null +++ b/src/backends/native/meta-keymap-native.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2018 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ +#ifndef META_KEYMAP_NATIVE_H +#define META_KEYMAP_NATIVE_H + +#include "backends/native/meta-xkb-utils.h" +#include "clutter/clutter.h" + +#define META_TYPE_KEYMAP_NATIVE (meta_keymap_native_get_type ()) +G_DECLARE_FINAL_TYPE (MetaKeymapNative, meta_keymap_native, + META, KEYMAP_NATIVE, + ClutterKeymap) + +void meta_keymap_native_set_keyboard_map (MetaKeymapNative *keymap, + struct xkb_keymap *xkb_keymap); +struct xkb_keymap * meta_keymap_native_get_keyboard_map (MetaKeymapNative *keymap); + +#endif /* META_KEYMAP_NATIVE_H */ diff --git a/src/backends/native/meta-kms-connector-private.h b/src/backends/native/meta-kms-connector-private.h new file mode 100644 index 000000000..29901c487 --- /dev/null +++ b/src/backends/native/meta-kms-connector-private.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2019 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_KMS_CONNECTOR_PRIVATE_H +#define META_KMS_CONNECTOR_PRIVATE_H + +#include "backends/native/meta-kms-types.h" + +void meta_kms_connector_update_state (MetaKmsConnector *connector, + drmModeRes *drm_resources); + +void meta_kms_connector_predict_state (MetaKmsConnector *connector, + MetaKmsUpdate *update); + +MetaKmsConnector * meta_kms_connector_new (MetaKmsImplDevice *impl_device, + drmModeConnector *drm_connector, + drmModeRes *drm_resources); + +gboolean meta_kms_connector_is_same_as (MetaKmsConnector *connector, + drmModeConnector *drm_connector); + +#endif /* META_KMS_CONNECTOR_PRIVATE_H */ diff --git a/src/backends/native/meta-kms-connector.c b/src/backends/native/meta-kms-connector.c new file mode 100644 index 000000000..ce8d28ae0 --- /dev/null +++ b/src/backends/native/meta-kms-connector.c @@ -0,0 +1,655 @@ +/* + * Copyright (C) 2019 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "backends/native/meta-kms-connector.h" +#include "backends/native/meta-kms-connector-private.h" + +#include <errno.h> + +#include "backends/native/meta-kms-crtc.h" +#include "backends/native/meta-kms-device-private.h" +#include "backends/native/meta-kms-impl-device.h" +#include "backends/native/meta-kms-update-private.h" + +struct _MetaKmsConnector +{ + GObject parent; + + MetaKmsDevice *device; + + uint32_t id; + MetaConnectorType type; + uint32_t type_id; + char *name; + + MetaKmsConnectorState *current_state; + + uint32_t dpms_prop_id; + uint32_t underscan_prop_id; + uint32_t underscan_hborder_prop_id; + uint32_t underscan_vborder_prop_id; + uint32_t edid_blob_id; + uint32_t tile_blob_id; +}; + +G_DEFINE_TYPE (MetaKmsConnector, meta_kms_connector, G_TYPE_OBJECT) + +MetaKmsDevice * +meta_kms_connector_get_device (MetaKmsConnector *connector) +{ + return connector->device; +} + +void +meta_kms_connector_update_set_dpms_state (MetaKmsConnector *connector, + MetaKmsUpdate *update, + uint64_t state) +{ + meta_kms_update_set_connector_property (update, + connector, + connector->dpms_prop_id, + state); +} + +void +meta_kms_connector_set_underscanning (MetaKmsConnector *connector, + MetaKmsUpdate *update, + uint64_t hborder, + uint64_t vborder) +{ + meta_kms_update_set_connector_property (update, + connector, + connector->underscan_prop_id, + 1); + meta_kms_update_set_connector_property (update, + connector, + connector->underscan_hborder_prop_id, + hborder); + meta_kms_update_set_connector_property (update, + connector, + connector->underscan_vborder_prop_id, + vborder); +} + +void +meta_kms_connector_unset_underscanning (MetaKmsConnector *connector, + MetaKmsUpdate *update) +{ + meta_kms_update_set_connector_property (update, + connector, + connector->underscan_prop_id, + 0); +} + +MetaConnectorType +meta_kms_connector_get_connector_type (MetaKmsConnector *connector) +{ + return connector->type; +} + +uint32_t +meta_kms_connector_get_id (MetaKmsConnector *connector) +{ + return connector->id; +} + +const char * +meta_kms_connector_get_name (MetaKmsConnector *connector) +{ + return connector->name; +} + +gboolean +meta_kms_connector_can_clone (MetaKmsConnector *connector, + MetaKmsConnector *other_connector) +{ + MetaKmsConnectorState *state = connector->current_state; + MetaKmsConnectorState *other_state = other_connector->current_state; + + if (state->common_possible_clones == 0 || + other_state->common_possible_clones == 0) + return FALSE; + + if (state->encoder_device_idxs != other_state->encoder_device_idxs) + return FALSE; + + return TRUE; +} + +const MetaKmsConnectorState * +meta_kms_connector_get_current_state (MetaKmsConnector *connector) +{ + return connector->current_state; +} + +gboolean +meta_kms_connector_is_underscanning_supported (MetaKmsConnector *connector) +{ + return connector->underscan_prop_id != 0; +} + +static void +set_panel_orientation (MetaKmsConnectorState *state, + drmModePropertyPtr prop, + uint64_t orientation) +{ + const char *name; + + name = prop->enums[orientation].name; + if (strcmp (name, "Upside Down") == 0) + { + state->panel_orientation_transform = META_MONITOR_TRANSFORM_180; + } + else if (strcmp (name, "Left Side Up") == 0) + { + /* Left side up, rotate 90 degrees counter clockwise to correct */ + state->panel_orientation_transform = META_MONITOR_TRANSFORM_90; + } + else if (strcmp (name, "Right Side Up") == 0) + { + /* Right side up, rotate 270 degrees counter clockwise to correct */ + state->panel_orientation_transform = META_MONITOR_TRANSFORM_270; + } + else + { + state->panel_orientation_transform = META_MONITOR_TRANSFORM_NORMAL; + } +} + +static void +state_set_properties (MetaKmsConnectorState *state, + MetaKmsImplDevice *impl_device, + drmModeConnector *drm_connector) +{ + int fd; + int i; + + fd = meta_kms_impl_device_get_fd (impl_device); + + for (i = 0; i < drm_connector->count_props; i++) + { + drmModePropertyPtr prop; + + prop = drmModeGetProperty (fd, drm_connector->props[i]); + if (!prop) + continue; + + if ((prop->flags & DRM_MODE_PROP_RANGE) && + strcmp (prop->name, "suggested X") == 0) + state->suggested_x = drm_connector->prop_values[i]; + else if ((prop->flags & DRM_MODE_PROP_RANGE) && + strcmp (prop->name, "suggested Y") == 0) + state->suggested_y = drm_connector->prop_values[i]; + else if ((prop->flags & DRM_MODE_PROP_RANGE) && + strcmp (prop->name, "hotplug_mode_update") == 0) + state->hotplug_mode_update = drm_connector->prop_values[i]; + else if (strcmp (prop->name, "scaling mode") == 0) + state->has_scaling = TRUE; + else if ((prop->flags & DRM_MODE_PROP_ENUM) && + strcmp (prop->name, "panel orientation") == 0) + set_panel_orientation (state, prop, drm_connector->prop_values[i]); + + drmModeFreeProperty (prop); + } +} + +static CoglSubpixelOrder +drm_subpixel_order_to_cogl_subpixel_order (drmModeSubPixel subpixel) +{ + switch (subpixel) + { + case DRM_MODE_SUBPIXEL_NONE: + return COGL_SUBPIXEL_ORDER_NONE; + break; + case DRM_MODE_SUBPIXEL_HORIZONTAL_RGB: + return COGL_SUBPIXEL_ORDER_HORIZONTAL_RGB; + break; + case DRM_MODE_SUBPIXEL_HORIZONTAL_BGR: + return COGL_SUBPIXEL_ORDER_HORIZONTAL_BGR; + break; + case DRM_MODE_SUBPIXEL_VERTICAL_RGB: + return COGL_SUBPIXEL_ORDER_VERTICAL_RGB; + break; + case DRM_MODE_SUBPIXEL_VERTICAL_BGR: + return COGL_SUBPIXEL_ORDER_VERTICAL_BGR; + break; + case DRM_MODE_SUBPIXEL_UNKNOWN: + return COGL_SUBPIXEL_ORDER_UNKNOWN; + } + return COGL_SUBPIXEL_ORDER_UNKNOWN; +} + +static void +state_set_edid (MetaKmsConnectorState *state, + MetaKmsConnector *connector, + MetaKmsImplDevice *impl_device, + uint32_t blob_id) +{ + int fd; + drmModePropertyBlobPtr edid_blob; + GBytes *edid_data; + + fd = meta_kms_impl_device_get_fd (impl_device); + edid_blob = drmModeGetPropertyBlob (fd, blob_id); + if (!edid_blob) + { + g_warning ("Failed to read EDID of connector %s: %s", + connector->name, g_strerror (errno)); + return; + } + + edid_data = g_bytes_new (edid_blob->data, edid_blob->length); + drmModeFreePropertyBlob (edid_blob); + + state->edid_data = edid_data; +} + +static void +state_set_tile_info (MetaKmsConnectorState *state, + MetaKmsConnector *connector, + MetaKmsImplDevice *impl_device, + uint32_t blob_id) +{ + int fd; + drmModePropertyBlobPtr tile_blob; + + state->tile_info = (MetaTileInfo) { 0 }; + + fd = meta_kms_impl_device_get_fd (impl_device); + tile_blob = drmModeGetPropertyBlob (fd, blob_id); + if (!tile_blob) + { + g_warning ("Failed to read TILE of connector %s: %s", + connector->name, strerror (errno)); + return; + } + + if (tile_blob->length > 0) + { + if (sscanf ((char *) tile_blob->data, "%d:%d:%d:%d:%d:%d:%d:%d", + &state->tile_info.group_id, + &state->tile_info.flags, + &state->tile_info.max_h_tiles, + &state->tile_info.max_v_tiles, + &state->tile_info.loc_h_tile, + &state->tile_info.loc_v_tile, + &state->tile_info.tile_w, + &state->tile_info.tile_h) != 8) + { + g_warning ("Couldn't understand TILE property blob of connector %s", + connector->name); + state->tile_info = (MetaTileInfo) { 0 }; + } + } + + drmModeFreePropertyBlob (tile_blob); +} + +static void +state_set_blobs (MetaKmsConnectorState *state, + MetaKmsConnector *connector, + MetaKmsImplDevice *impl_device, + drmModeConnector *drm_connector) +{ + int fd; + int i; + + fd = meta_kms_impl_device_get_fd (impl_device); + + for (i = 0; i < drm_connector->count_props; i++) + { + drmModePropertyPtr prop; + + prop = drmModeGetProperty (fd, drm_connector->props[i]); + if (!prop) + continue; + + if (prop->flags & DRM_MODE_PROP_BLOB) + { + uint32_t blob_id; + + blob_id = drm_connector->prop_values[i]; + + if (blob_id) + { + if (strcmp (prop->name, "EDID") == 0) + state_set_edid (state, connector, impl_device, blob_id); + else if (strcmp (prop->name, "TILE") == 0) + state_set_tile_info (state, connector, impl_device, blob_id); + } + } + + drmModeFreeProperty (prop); + } +} + +static void +state_set_physical_dimensions (MetaKmsConnectorState *state, + drmModeConnector *drm_connector) +{ + state->width_mm = drm_connector->mmWidth; + state->height_mm = drm_connector->mmHeight; +} + +static void +state_set_modes (MetaKmsConnectorState *state, + drmModeConnector *drm_connector) +{ + state->modes = + g_memdup (drm_connector->modes, + drm_connector->count_modes * sizeof (drmModeModeInfo)); + state->n_modes = drm_connector->count_modes; +} + +static void +set_encoder_device_idx_bit (uint32_t *encoder_device_idxs, + uint32_t encoder_id, + MetaKmsImplDevice *impl_device, + drmModeRes *drm_resources) +{ + int fd; + int i; + + fd = meta_kms_impl_device_get_fd (impl_device); + + for (i = 0; i < drm_resources->count_encoders; i++) + { + drmModeEncoder *drm_encoder; + + drm_encoder = drmModeGetEncoder (fd, drm_resources->encoders[i]); + if (!drm_encoder) + continue; + + if (drm_encoder->encoder_id == encoder_id) + { + *encoder_device_idxs |= (1 << i); + drmModeFreeEncoder (drm_encoder); + break; + } + + drmModeFreeEncoder (drm_encoder); + } +} + +static void +state_set_crtc_state (MetaKmsConnectorState *state, + drmModeConnector *drm_connector, + MetaKmsImplDevice *impl_device, + drmModeRes *drm_resources) +{ + int fd; + int i; + uint32_t common_possible_crtcs; + uint32_t common_possible_clones; + uint32_t encoder_device_idxs; + + fd = meta_kms_impl_device_get_fd (impl_device); + + common_possible_crtcs = UINT32_MAX; + common_possible_clones = UINT32_MAX; + encoder_device_idxs = 0; + for (i = 0; i < drm_connector->count_encoders; i++) + { + drmModeEncoder *drm_encoder; + + drm_encoder = drmModeGetEncoder (fd, drm_connector->encoders[i]); + if (!drm_encoder) + continue; + + common_possible_crtcs &= drm_encoder->possible_crtcs; + common_possible_clones &= drm_encoder->possible_clones; + + set_encoder_device_idx_bit (&encoder_device_idxs, + drm_encoder->encoder_id, + impl_device, + drm_resources); + + if (drm_connector->encoder_id == drm_encoder->encoder_id) + state->current_crtc_id = drm_encoder->crtc_id; + + drmModeFreeEncoder (drm_encoder); + } + + state->common_possible_crtcs = common_possible_crtcs; + state->common_possible_clones = common_possible_clones; + state->encoder_device_idxs = encoder_device_idxs; +} + +static MetaKmsConnectorState * +meta_kms_connector_state_new (void) +{ + MetaKmsConnectorState *state; + + state = g_new0 (MetaKmsConnectorState, 1); + state->suggested_x = -1; + state->suggested_y = -1; + + return state; +} + +static void +meta_kms_connector_state_free (MetaKmsConnectorState *state) +{ + g_clear_pointer (&state->edid_data, g_bytes_unref); + g_free (state->modes); + g_free (state); +} + +static void +meta_kms_connector_read_state (MetaKmsConnector *connector, + MetaKmsImplDevice *impl_device, + drmModeConnector *drm_connector, + drmModeRes *drm_resources) +{ + MetaKmsConnectorState *state; + + g_clear_pointer (&connector->current_state, meta_kms_connector_state_free); + + if (!drm_connector || drm_connector->connection != DRM_MODE_CONNECTED) + return; + + state = meta_kms_connector_state_new (); + + state_set_blobs (state, connector, impl_device, drm_connector); + + state_set_properties (state, impl_device, drm_connector); + + state->subpixel_order = + drm_subpixel_order_to_cogl_subpixel_order (drm_connector->subpixel); + + state_set_physical_dimensions (state, drm_connector); + + state_set_modes (state, drm_connector); + + state_set_crtc_state (state, drm_connector, impl_device, drm_resources); + + connector->current_state = state; +} + +void +meta_kms_connector_update_state (MetaKmsConnector *connector, + drmModeRes *drm_resources) +{ + MetaKmsImplDevice *impl_device; + drmModeConnector *drm_connector; + + impl_device = meta_kms_device_get_impl_device (connector->device); + drm_connector = drmModeGetConnector (meta_kms_impl_device_get_fd (impl_device), + connector->id); + meta_kms_connector_read_state (connector, impl_device, + drm_connector, + drm_resources); + if (drm_connector) + drmModeFreeConnector (drm_connector); +} + +void +meta_kms_connector_predict_state (MetaKmsConnector *connector, + MetaKmsUpdate *update) +{ + GList *mode_sets; + GList *l; + + if (!connector->current_state) + return; + + mode_sets = meta_kms_update_get_mode_sets (update); + for (l = mode_sets; l; l = l->next) + { + MetaKmsModeSet *mode_set = l->data; + MetaKmsCrtc *crtc; + + if (!g_list_find (mode_set->connectors, connector)) + continue; + + crtc = mode_set->crtc; + if (crtc) + connector->current_state->current_crtc_id = meta_kms_crtc_get_id (crtc); + else + connector->current_state->current_crtc_id = 0; + + break; + } +} + +static void +find_property_ids (MetaKmsConnector *connector, + MetaKmsImplDevice *impl_device, + drmModeConnector *drm_connector) +{ + int fd; + int i; + + fd = meta_kms_impl_device_get_fd (impl_device); + + for (i = 0; i < drm_connector->count_props; i++) + { + drmModePropertyPtr prop; + + prop = drmModeGetProperty (fd, drm_connector->props[i]); + if (!prop) + continue; + + if ((prop->flags & DRM_MODE_PROP_ENUM) && + strcmp (prop->name, "DPMS") == 0) + connector->dpms_prop_id = prop->prop_id; + else if ((prop->flags & DRM_MODE_PROP_ENUM) && + strcmp (prop->name, "underscan") == 0) + connector->underscan_prop_id = prop->prop_id; + else if ((prop->flags & DRM_MODE_PROP_RANGE) && + strcmp (prop->name, "underscan hborder") == 0) + connector->underscan_hborder_prop_id = prop->prop_id; + else if ((prop->flags & DRM_MODE_PROP_RANGE) && + strcmp (prop->name, "underscan vborder") == 0) + connector->underscan_vborder_prop_id = prop->prop_id; + + drmModeFreeProperty (prop); + } +} + +static char * +make_connector_name (drmModeConnector *drm_connector) +{ + static const char * const connector_type_names[] = { + "None", + "VGA", + "DVI-I", + "DVI-D", + "DVI-A", + "Composite", + "SVIDEO", + "LVDS", + "Component", + "DIN", + "DP", + "HDMI", + "HDMI-B", + "TV", + "eDP", + "Virtual", + "DSI", + }; + + if (drm_connector->connector_type < G_N_ELEMENTS (connector_type_names)) + return g_strdup_printf ("%s-%d", + connector_type_names[drm_connector->connector_type], + drm_connector->connector_type_id); + else + return g_strdup_printf ("Unknown%d-%d", + drm_connector->connector_type, + drm_connector->connector_type_id); +} + +gboolean +meta_kms_connector_is_same_as (MetaKmsConnector *connector, + drmModeConnector *drm_connector) +{ + return (connector->id == drm_connector->connector_id && + connector->type == drm_connector->connector_type && + connector->type_id == drm_connector->connector_type_id); +} + +MetaKmsConnector * +meta_kms_connector_new (MetaKmsImplDevice *impl_device, + drmModeConnector *drm_connector, + drmModeRes *drm_resources) +{ + MetaKmsConnector *connector; + + connector = g_object_new (META_TYPE_KMS_CONNECTOR, NULL); + connector->device = meta_kms_impl_device_get_device (impl_device); + connector->id = drm_connector->connector_id; + connector->type = (MetaConnectorType) drm_connector->connector_type; + connector->type_id = drm_connector->connector_type_id; + connector->name = make_connector_name (drm_connector); + + find_property_ids (connector, impl_device, drm_connector); + + meta_kms_connector_read_state (connector, impl_device, + drm_connector, + drm_resources); + + return connector; +} + +static void +meta_kms_connector_finalize (GObject *object) +{ + MetaKmsConnector *connector = META_KMS_CONNECTOR (object); + + g_clear_pointer (&connector->current_state, meta_kms_connector_state_free); + g_free (connector->name); + + G_OBJECT_CLASS (meta_kms_connector_parent_class)->finalize (object); +} + +static void +meta_kms_connector_init (MetaKmsConnector *connector) +{ +} + +static void +meta_kms_connector_class_init (MetaKmsConnectorClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_kms_connector_finalize; +} diff --git a/src/backends/native/meta-kms-connector.h b/src/backends/native/meta-kms-connector.h new file mode 100644 index 000000000..b6198b467 --- /dev/null +++ b/src/backends/native/meta-kms-connector.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2019 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_KMS_CONNECTOR_H +#define META_KMS_CONNECTOR_H + +#include <glib-object.h> +#include <stdint.h> +#include <xf86drmMode.h> + +#include "backends/meta-output.h" +#include "backends/native/meta-kms-types.h" + +#define META_TYPE_KMS_CONNECTOR (meta_kms_connector_get_type ()) +G_DECLARE_FINAL_TYPE (MetaKmsConnector, meta_kms_connector, + META, KMS_CONNECTOR, GObject) + +typedef struct _MetaKmsConnectorState +{ + uint32_t current_crtc_id; + + uint32_t common_possible_crtcs; + uint32_t common_possible_clones; + uint32_t encoder_device_idxs; + + drmModeModeInfo *modes; + int n_modes; + + uint32_t width_mm; + uint32_t height_mm; + + MetaTileInfo tile_info; + GBytes *edid_data; + + gboolean has_scaling; + + CoglSubpixelOrder subpixel_order; + + int suggested_x; + int suggested_y; + gboolean hotplug_mode_update; + + MetaMonitorTransform panel_orientation_transform; +} MetaKmsConnectorState; + +MetaKmsDevice * meta_kms_connector_get_device (MetaKmsConnector *connector); + +void meta_kms_connector_update_set_dpms_state (MetaKmsConnector *connector, + MetaKmsUpdate *update, + uint64_t state); + +void meta_kms_connector_set_underscanning (MetaKmsConnector *connector, + MetaKmsUpdate *update, + uint64_t hborder, + uint64_t vborder); + +void meta_kms_connector_unset_underscanning (MetaKmsConnector *connector, + MetaKmsUpdate *update); + +MetaConnectorType meta_kms_connector_get_connector_type (MetaKmsConnector *connector); + +uint32_t meta_kms_connector_get_id (MetaKmsConnector *connector); + +const char * meta_kms_connector_get_name (MetaKmsConnector *connector); + +gboolean meta_kms_connector_can_clone (MetaKmsConnector *connector, + MetaKmsConnector *other_connector); + +const MetaKmsConnectorState * meta_kms_connector_get_current_state (MetaKmsConnector *connector); + +gboolean meta_kms_connector_is_underscanning_supported (MetaKmsConnector *connector); + +#endif /* META_KMS_CONNECTOR_H */ diff --git a/src/backends/native/meta-kms-crtc-private.h b/src/backends/native/meta-kms-crtc-private.h new file mode 100644 index 000000000..f9a3a6e0a --- /dev/null +++ b/src/backends/native/meta-kms-crtc-private.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2019 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_KMS_CRTC_PRIVATE_H +#define META_KMS_CRTC_PRIVATE_H + +#include <xf86drmMode.h> + +#include "backends/native/meta-kms-types.h" + +MetaKmsCrtc * meta_kms_crtc_new (MetaKmsImplDevice *impl_device, + drmModeCrtc *drm_crtc, + int idx); + +void meta_kms_crtc_update_state (MetaKmsCrtc *crtc); + +void meta_kms_crtc_predict_state (MetaKmsCrtc *crtc, + MetaKmsUpdate *update); + +#endif /* META_KMS_CRTC_PRIVATE_H */ diff --git a/src/backends/native/meta-kms-crtc.c b/src/backends/native/meta-kms-crtc.c new file mode 100644 index 000000000..ebdd8ed9d --- /dev/null +++ b/src/backends/native/meta-kms-crtc.c @@ -0,0 +1,252 @@ +/* + * Copyright (C) 2019 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "backends/native/meta-kms-crtc.h" +#include "backends/native/meta-kms-crtc-private.h" + +#include "backends/native/meta-kms-device-private.h" +#include "backends/native/meta-kms-impl-device.h" +#include "backends/native/meta-kms-update-private.h" + +struct _MetaKmsCrtc +{ + GObject parent; + + MetaKmsDevice *device; + + uint32_t id; + int idx; + + MetaKmsCrtcState current_state; +}; + +G_DEFINE_TYPE (MetaKmsCrtc, meta_kms_crtc, G_TYPE_OBJECT) + +void +meta_kms_crtc_set_gamma (MetaKmsCrtc *crtc, + MetaKmsUpdate *update, + int size, + const uint16_t *red, + const uint16_t *green, + const uint16_t *blue) +{ + meta_kms_update_set_crtc_gamma (update, crtc, size, red, green, blue); +} + +MetaKmsDevice * +meta_kms_crtc_get_device (MetaKmsCrtc *crtc) +{ + return crtc->device; +} + +const MetaKmsCrtcState * +meta_kms_crtc_get_current_state (MetaKmsCrtc *crtc) +{ + return &crtc->current_state; +} + +uint32_t +meta_kms_crtc_get_id (MetaKmsCrtc *crtc) +{ + return crtc->id; +} + +int +meta_kms_crtc_get_idx (MetaKmsCrtc *crtc) +{ + return crtc->idx; +} + +static void +read_gamma_state (MetaKmsCrtc *crtc, + MetaKmsImplDevice *impl_device, + drmModeCrtc *drm_crtc) +{ + MetaKmsCrtcState *current_state = &crtc->current_state; + + if (current_state->gamma.size != drm_crtc->gamma_size) + { + current_state->gamma.size = drm_crtc->gamma_size; + + current_state->gamma.red = g_realloc_n (current_state->gamma.red, + drm_crtc->gamma_size, + sizeof (uint16_t)); + current_state->gamma.green = g_realloc_n (current_state->gamma.green, + drm_crtc->gamma_size, + sizeof (uint16_t)); + current_state->gamma.blue = g_realloc_n (current_state->gamma.blue, + drm_crtc->gamma_size, + sizeof (uint16_t)); + } + + drmModeCrtcGetGamma (meta_kms_impl_device_get_fd (impl_device), + crtc->id, + current_state->gamma.size, + current_state->gamma.red, + current_state->gamma.green, + current_state->gamma.blue); +} + +static void +meta_kms_crtc_read_state (MetaKmsCrtc *crtc, + MetaKmsImplDevice *impl_device, + drmModeCrtc *drm_crtc) +{ + crtc->current_state.rect = (MetaRectangle) { + .x = drm_crtc->x, + .y = drm_crtc->y, + .width = drm_crtc->width, + .height = drm_crtc->height, + }; + + crtc->current_state.is_drm_mode_valid = drm_crtc->mode_valid; + crtc->current_state.drm_mode = drm_crtc->mode; + + read_gamma_state (crtc, impl_device, drm_crtc); +} + +void +meta_kms_crtc_update_state (MetaKmsCrtc *crtc) +{ + MetaKmsImplDevice *impl_device; + drmModeCrtc *drm_crtc; + + impl_device = meta_kms_device_get_impl_device (crtc->device); + drm_crtc = drmModeGetCrtc (meta_kms_impl_device_get_fd (impl_device), + crtc->id); + if (!drm_crtc) + { + crtc->current_state.rect = (MetaRectangle) { }; + crtc->current_state.is_drm_mode_valid = FALSE; + return; + } + + meta_kms_crtc_read_state (crtc, impl_device, drm_crtc); + drmModeFreeCrtc (drm_crtc); +} + +static void +clear_gamma_state (MetaKmsCrtc *crtc) +{ + crtc->current_state.gamma.size = 0; + g_clear_pointer (&crtc->current_state.gamma.red, g_free); + g_clear_pointer (&crtc->current_state.gamma.green, g_free); + g_clear_pointer (&crtc->current_state.gamma.blue, g_free); +} + +void +meta_kms_crtc_predict_state (MetaKmsCrtc *crtc, + MetaKmsUpdate *update) +{ + GList *mode_sets; + GList *crtc_gammas; + GList *l; + + mode_sets = meta_kms_update_get_mode_sets (update); + for (l = mode_sets; l; l = l->next) + { + MetaKmsModeSet *mode_set = l->data; + + if (mode_set->crtc != crtc) + continue; + + if (mode_set->drm_mode) + { + MetaKmsPlaneAssignment *plane_assignment; + + plane_assignment = + meta_kms_update_get_primary_plane_assignment (update, crtc); + + crtc->current_state.rect = + meta_fixed_16_rectangle_to_rectangle (plane_assignment->src_rect); + crtc->current_state.is_drm_mode_valid = TRUE; + crtc->current_state.drm_mode = *mode_set->drm_mode; + } + else + { + crtc->current_state.rect = (MetaRectangle) { 0 }; + crtc->current_state.is_drm_mode_valid = FALSE; + crtc->current_state.drm_mode = (drmModeModeInfo) { 0 }; + } + + break; + } + + crtc_gammas = meta_kms_update_get_crtc_gammas (update); + for (l = crtc_gammas; l; l = l->next) + { + MetaKmsCrtcGamma *gamma = l->data; + + if (gamma->crtc != crtc) + continue; + + clear_gamma_state (crtc); + crtc->current_state.gamma.size = gamma->size; + crtc->current_state.gamma.red = + g_memdup (gamma->red, gamma->size * sizeof (uint16_t)); + crtc->current_state.gamma.green = + g_memdup (gamma->green, gamma->size * sizeof (uint16_t)); + crtc->current_state.gamma.blue = + g_memdup (gamma->blue, gamma->size * sizeof (uint16_t)); + + break; + } +} + +MetaKmsCrtc * +meta_kms_crtc_new (MetaKmsImplDevice *impl_device, + drmModeCrtc *drm_crtc, + int idx) +{ + MetaKmsCrtc *crtc; + + crtc = g_object_new (META_TYPE_KMS_CRTC, NULL); + crtc->device = meta_kms_impl_device_get_device (impl_device); + crtc->id = drm_crtc->crtc_id; + crtc->idx = idx; + + meta_kms_crtc_read_state (crtc, impl_device, drm_crtc); + + return crtc; +} + +static void +meta_kms_crtc_finalize (GObject *object) +{ + MetaKmsCrtc *crtc = META_KMS_CRTC (object); + + clear_gamma_state (crtc); + + G_OBJECT_CLASS (meta_kms_crtc_parent_class)->finalize (object); +} + +static void +meta_kms_crtc_init (MetaKmsCrtc *crtc) +{ +} + +static void +meta_kms_crtc_class_init (MetaKmsCrtcClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_kms_crtc_finalize; +} diff --git a/src/backends/native/meta-kms-crtc.h b/src/backends/native/meta-kms-crtc.h new file mode 100644 index 000000000..fa9938199 --- /dev/null +++ b/src/backends/native/meta-kms-crtc.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2019 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_KMS_CRTC_H +#define META_KMS_CRTC_H + +#include <glib-object.h> +#include <stdint.h> +#include <xf86drmMode.h> + +#include "backends/native/meta-kms-types.h" +#include "meta/boxes.h" + +typedef struct _MetaKmsCrtcState +{ + MetaRectangle rect; + gboolean is_drm_mode_valid; + drmModeModeInfo drm_mode; + + struct { + uint16_t *red; + uint16_t *green; + uint16_t *blue; + + int size; + } gamma; +} MetaKmsCrtcState; + +#define META_TYPE_KMS_CRTC (meta_kms_crtc_get_type ()) +G_DECLARE_FINAL_TYPE (MetaKmsCrtc, meta_kms_crtc, + META, KMS_CRTC, + GObject) + +void meta_kms_crtc_set_gamma (MetaKmsCrtc *crtc, + MetaKmsUpdate *update, + int size, + const uint16_t *red, + const uint16_t *green, + const uint16_t *blue); + +MetaKmsDevice * meta_kms_crtc_get_device (MetaKmsCrtc *crtc); + +const MetaKmsCrtcState * meta_kms_crtc_get_current_state (MetaKmsCrtc *crtc); + +uint32_t meta_kms_crtc_get_id (MetaKmsCrtc *crtc); + +int meta_kms_crtc_get_idx (MetaKmsCrtc *crtc); + +#endif /* META_KMS_CRTC_H */ diff --git a/src/backends/native/meta-kms-device-private.h b/src/backends/native/meta-kms-device-private.h new file mode 100644 index 000000000..41e05a2f7 --- /dev/null +++ b/src/backends/native/meta-kms-device-private.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2019 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_KMS_DEVICE_PRIVATE_H +#define META_KMS_DEVICE_PRIVATE_H + +#include "backends/native/meta-kms-types.h" + +MetaKmsImplDevice * meta_kms_device_get_impl_device (MetaKmsDevice *device); + +void meta_kms_device_update_states_in_impl (MetaKmsDevice *device); + +void meta_kms_device_predict_states_in_impl (MetaKmsDevice *device, + MetaKmsUpdate *update); + +void meta_kms_device_add_fake_plane_in_impl (MetaKmsDevice *device, + MetaKmsPlaneType plane_type, + MetaKmsCrtc *crtc); + +#endif /* META_KMS_DEVICE_PRIVATE_H */ diff --git a/src/backends/native/meta-kms-device.c b/src/backends/native/meta-kms-device.c new file mode 100644 index 000000000..a31dce8bd --- /dev/null +++ b/src/backends/native/meta-kms-device.c @@ -0,0 +1,386 @@ +/* + * Copyright (C) 2019 Red Hat + * Copyright (C) 2019 DisplayLink (UK) Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "backends/native/meta-kms-device-private.h" +#include "backends/native/meta-kms-device.h" + +#include "backends/native/meta-backend-native.h" +#include "backends/native/meta-kms-impl-device.h" +#include "backends/native/meta-kms-impl.h" +#include "backends/native/meta-kms-plane.h" +#include "backends/native/meta-kms-private.h" + +struct _MetaKmsDevice +{ + GObject parent; + + MetaKms *kms; + + MetaKmsImplDevice *impl_device; + + MetaKmsDeviceFlag flags; + char *path; + + GList *crtcs; + GList *connectors; + GList *planes; + + MetaKmsDeviceCaps caps; +}; + +G_DEFINE_TYPE (MetaKmsDevice, meta_kms_device, G_TYPE_OBJECT); + +MetaKmsImplDevice * +meta_kms_device_get_impl_device (MetaKmsDevice *device) +{ + return device->impl_device; +} + +int +meta_kms_device_leak_fd (MetaKmsDevice *device) +{ + return meta_kms_impl_device_leak_fd (device->impl_device); +} + +const char * +meta_kms_device_get_path (MetaKmsDevice *device) +{ + return device->path; +} + +MetaKmsDeviceFlag +meta_kms_device_get_flags (MetaKmsDevice *device) +{ + return device->flags; +} + +gboolean +meta_kms_device_get_cursor_size (MetaKmsDevice *device, + uint64_t *out_cursor_width, + uint64_t *out_cursor_height) +{ + if (device->caps.has_cursor_size) + { + *out_cursor_width = device->caps.cursor_width; + *out_cursor_height = device->caps.cursor_height; + return TRUE; + } + else + { + return FALSE; + } +} + +GList * +meta_kms_device_get_connectors (MetaKmsDevice *device) +{ + return device->connectors; +} + +GList * +meta_kms_device_get_crtcs (MetaKmsDevice *device) +{ + return device->crtcs; +} + +static GList * +meta_kms_device_get_planes (MetaKmsDevice *device) +{ + return device->planes; +} + +static MetaKmsPlane * +get_plane_with_type_for (MetaKmsDevice *device, + MetaKmsCrtc *crtc, + MetaKmsPlaneType type) +{ + GList *l; + + for (l = meta_kms_device_get_planes (device); l; l = l->next) + { + MetaKmsPlane *plane = l->data; + + if (meta_kms_plane_get_plane_type (plane) != type) + continue; + + if (meta_kms_plane_is_usable_with (plane, crtc)) + return plane; + } + + return NULL; +} + +MetaKmsPlane * +meta_kms_device_get_primary_plane_for (MetaKmsDevice *device, + MetaKmsCrtc *crtc) +{ + return get_plane_with_type_for (device, crtc, META_KMS_PLANE_TYPE_PRIMARY); +} + +MetaKmsPlane * +meta_kms_device_get_cursor_plane_for (MetaKmsDevice *device, + MetaKmsCrtc *crtc) +{ + return get_plane_with_type_for (device, crtc, META_KMS_PLANE_TYPE_CURSOR); +} + +void +meta_kms_device_update_states_in_impl (MetaKmsDevice *device) +{ + MetaKmsImplDevice *impl_device = meta_kms_device_get_impl_device (device); + + meta_assert_in_kms_impl (device->kms); + meta_assert_is_waiting_for_kms_impl_task (device->kms); + + meta_kms_impl_device_update_states (impl_device); + + g_list_free (device->crtcs); + device->crtcs = meta_kms_impl_device_copy_crtcs (impl_device); + + g_list_free (device->connectors); + device->connectors = meta_kms_impl_device_copy_connectors (impl_device); + + g_list_free (device->planes); + device->planes = meta_kms_impl_device_copy_planes (impl_device); +} + +void +meta_kms_device_predict_states_in_impl (MetaKmsDevice *device, + MetaKmsUpdate *update) +{ + MetaKmsImplDevice *impl_device = meta_kms_device_get_impl_device (device); + + meta_assert_in_kms_impl (device->kms); + + meta_kms_impl_device_predict_states (impl_device, update); +} + +static gpointer +dispatch_in_impl (MetaKmsImpl *impl, + gpointer user_data, + GError **error) +{ + MetaKmsImplDevice *impl_device = META_KMS_IMPL_DEVICE (user_data); + gboolean ret; + + ret = meta_kms_impl_device_dispatch (impl_device, error); + return GINT_TO_POINTER (ret); +} + +static gpointer +dispatch_idle_in_impl (MetaKmsImpl *impl, + gpointer user_data, + GError **error) +{ + meta_kms_impl_dispatch_idle (impl); + + return GINT_TO_POINTER (TRUE); +} + +int +meta_kms_device_dispatch_sync (MetaKmsDevice *device, + GError **error) +{ + int callback_count; + + if (!meta_kms_run_impl_task_sync (device->kms, + dispatch_idle_in_impl, + device->impl_device, + error)) + return -1; + + callback_count = meta_kms_flush_callbacks (device->kms); + if (callback_count > 0) + return TRUE; + + if (!meta_kms_run_impl_task_sync (device->kms, + dispatch_in_impl, + device->impl_device, + error)) + return -1; + + return meta_kms_flush_callbacks (device->kms); +} + +void +meta_kms_device_add_fake_plane_in_impl (MetaKmsDevice *device, + MetaKmsPlaneType plane_type, + MetaKmsCrtc *crtc) +{ + MetaKmsImplDevice *impl_device = device->impl_device; + MetaKmsPlane *plane; + + meta_assert_in_kms_impl (device->kms); + + plane = meta_kms_impl_device_add_fake_plane (impl_device, + plane_type, + crtc); + device->planes = g_list_append (device->planes, plane); +} + +typedef struct _CreateImplDeviceData +{ + MetaKmsDevice *device; + int fd; + + MetaKmsImplDevice *out_impl_device; + GList *out_crtcs; + GList *out_connectors; + GList *out_planes; + MetaKmsDeviceCaps out_caps; +} CreateImplDeviceData; + +static gpointer +create_impl_device_in_impl (MetaKmsImpl *impl, + gpointer user_data, + GError **error) +{ + CreateImplDeviceData *data = user_data; + MetaKmsImplDevice *impl_device; + + impl_device = meta_kms_impl_device_new (data->device, impl, data->fd, error); + if (!impl_device) + return FALSE; + + data->out_impl_device = impl_device; + data->out_crtcs = meta_kms_impl_device_copy_crtcs (impl_device); + data->out_connectors = meta_kms_impl_device_copy_connectors (impl_device); + data->out_planes = meta_kms_impl_device_copy_planes (impl_device); + data->out_caps = *meta_kms_impl_device_get_caps (impl_device); + + return GINT_TO_POINTER (TRUE); +} + +MetaKmsDevice * +meta_kms_device_new (MetaKms *kms, + const char *path, + MetaKmsDeviceFlag flags, + GError **error) +{ + MetaBackend *backend = meta_kms_get_backend (kms); + MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend); + MetaLauncher *launcher = meta_backend_native_get_launcher (backend_native); + MetaKmsDevice *device; + CreateImplDeviceData data; + int fd; + + fd = meta_launcher_open_restricted (launcher, path, error); + if (fd == -1) + return NULL; + + device = g_object_new (META_TYPE_KMS_DEVICE, NULL); + device->kms = kms; + + data = (CreateImplDeviceData) { + .device = device, + .fd = fd, + }; + if (!meta_kms_run_impl_task_sync (kms, create_impl_device_in_impl, &data, + error)) + { + meta_launcher_close_restricted (launcher, fd); + g_object_unref (device); + return NULL; + } + + device->impl_device = data.out_impl_device; + device->flags = flags; + device->path = g_strdup (path); + device->crtcs = data.out_crtcs; + device->connectors = data.out_connectors; + device->planes = data.out_planes; + device->caps = data.out_caps; + + return device; +} + +typedef struct _FreeImplDeviceData +{ + MetaKmsImplDevice *impl_device; + + int out_fd; +} FreeImplDeviceData; + +static gpointer +free_impl_device_in_impl (MetaKmsImpl *impl, + gpointer user_data, + GError **error) +{ + FreeImplDeviceData *data = user_data; + MetaKmsImplDevice *impl_device = data->impl_device; + int fd; + + fd = meta_kms_impl_device_close (impl_device); + g_object_unref (impl_device); + + data->out_fd = fd; + + return GINT_TO_POINTER (TRUE); +} + +static void +meta_kms_device_finalize (GObject *object) +{ + MetaKmsDevice *device = META_KMS_DEVICE (object); + MetaBackend *backend = meta_kms_get_backend (device->kms); + MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend); + MetaLauncher *launcher = meta_backend_native_get_launcher (backend_native); + + g_free (device->path); + g_list_free (device->crtcs); + g_list_free (device->connectors); + g_list_free (device->planes); + + if (device->impl_device) + { + FreeImplDeviceData data; + GError *error = NULL; + + data = (FreeImplDeviceData) { + .impl_device = device->impl_device, + }; + if (!meta_kms_run_impl_task_sync (device->kms, free_impl_device_in_impl, &data, + &error)) + { + g_warning ("Failed to close KMS impl device: %s", error->message); + g_error_free (error); + } + else + { + meta_launcher_close_restricted (launcher, data.out_fd); + } + } + G_OBJECT_CLASS (meta_kms_device_parent_class)->finalize (object); +} + +static void +meta_kms_device_init (MetaKmsDevice *device) +{ +} + +static void +meta_kms_device_class_init (MetaKmsDeviceClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_kms_device_finalize; +} diff --git a/src/backends/native/meta-kms-device.h b/src/backends/native/meta-kms-device.h new file mode 100644 index 000000000..9f83d3855 --- /dev/null +++ b/src/backends/native/meta-kms-device.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2019 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_KMS_DEVICE_H +#define META_KMS_DEVICE_H + +#include <glib-object.h> + +#include "backends/native/meta-kms-types.h" + +#define META_TYPE_KMS_DEVICE (meta_kms_device_get_type ()) +G_DECLARE_FINAL_TYPE (MetaKmsDevice, meta_kms_device, + META, KMS_DEVICE, + GObject) + +int meta_kms_device_leak_fd (MetaKmsDevice *device); + +const char * meta_kms_device_get_path (MetaKmsDevice *device); + +MetaKmsDeviceFlag meta_kms_device_get_flags (MetaKmsDevice *device); + +gboolean meta_kms_device_get_cursor_size (MetaKmsDevice *device, + uint64_t *out_cursor_width, + uint64_t *out_cursor_height); + +GList * meta_kms_device_get_connectors (MetaKmsDevice *device); + +GList * meta_kms_device_get_crtcs (MetaKmsDevice *device); + +MetaKmsPlane * meta_kms_device_get_primary_plane_for (MetaKmsDevice *device, + MetaKmsCrtc *crtc); + +MetaKmsPlane * meta_kms_device_get_cursor_plane_for (MetaKmsDevice *device, + MetaKmsCrtc *crtc); + +int meta_kms_device_dispatch_sync (MetaKmsDevice *device, + GError **error); + +MetaKmsDevice * meta_kms_device_new (MetaKms *kms, + const char *path, + MetaKmsDeviceFlag flags, + GError **error); + +#endif /* META_KMS_DEVICE_H */ diff --git a/src/backends/native/meta-kms-impl-device.c b/src/backends/native/meta-kms-impl-device.c new file mode 100644 index 000000000..80d7a8b01 --- /dev/null +++ b/src/backends/native/meta-kms-impl-device.c @@ -0,0 +1,503 @@ +/* + * Copyright (C) 2019 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "backends/native/meta-kms-impl-device.h" + +#include <errno.h> +#include <xf86drm.h> + +#include "backends/native/meta-kms-connector-private.h" +#include "backends/native/meta-kms-connector.h" +#include "backends/native/meta-kms-crtc-private.h" +#include "backends/native/meta-kms-crtc.h" +#include "backends/native/meta-kms-impl.h" +#include "backends/native/meta-kms-page-flip-private.h" +#include "backends/native/meta-kms-plane-private.h" +#include "backends/native/meta-kms-plane.h" +#include "backends/native/meta-kms-private.h" +#include "backends/native/meta-kms-update.h" + +struct _MetaKmsImplDevice +{ + GObject parent; + + MetaKmsDevice *device; + MetaKmsImpl *impl; + + int fd; + GSource *fd_source; + + GList *crtcs; + GList *connectors; + GList *planes; + + MetaKmsDeviceCaps caps; +}; + +G_DEFINE_TYPE (MetaKmsImplDevice, meta_kms_impl_device, G_TYPE_OBJECT) + +MetaKmsDevice * +meta_kms_impl_device_get_device (MetaKmsImplDevice *impl_device) +{ + return impl_device->device; +} + +GList * +meta_kms_impl_device_copy_connectors (MetaKmsImplDevice *impl_device) +{ + return g_list_copy (impl_device->connectors); +} + +GList * +meta_kms_impl_device_copy_crtcs (MetaKmsImplDevice *impl_device) +{ + return g_list_copy (impl_device->crtcs); +} + +GList * +meta_kms_impl_device_copy_planes (MetaKmsImplDevice *impl_device) +{ + return g_list_copy (impl_device->planes); +} + +const MetaKmsDeviceCaps * +meta_kms_impl_device_get_caps (MetaKmsImplDevice *impl_device) +{ + return &impl_device->caps; +} + +static void +page_flip_handler (int fd, + unsigned int sequence, + unsigned int sec, + unsigned int usec, + void *user_data) +{ + MetaKmsPageFlipData *page_flip_data = user_data; + MetaKmsImpl *impl; + + meta_kms_page_flip_data_set_timings_in_impl (page_flip_data, + sequence, sec, usec); + + impl = meta_kms_page_flip_data_get_kms_impl (page_flip_data); + meta_kms_impl_handle_page_flip_callback (impl, page_flip_data); +} + +gboolean +meta_kms_impl_device_dispatch (MetaKmsImplDevice *impl_device, + GError **error) +{ + drmEventContext drm_event_context; + + meta_assert_in_kms_impl (meta_kms_impl_get_kms (impl_device->impl)); + + drm_event_context = (drmEventContext) { 0 }; + drm_event_context.version = 2; + drm_event_context.page_flip_handler = page_flip_handler; + + while (TRUE) + { + if (drmHandleEvent (impl_device->fd, &drm_event_context) != 0) + { + struct pollfd pfd; + int ret; + + if (errno != EAGAIN) + { + g_set_error_literal (error, G_IO_ERROR, + g_io_error_from_errno (errno), + strerror (errno)); + return FALSE; + } + + pfd.fd = impl_device->fd; + pfd.events = POLL_IN | POLL_ERR; + do + { + ret = poll (&pfd, 1, -1); + } + while (ret == -1 && errno == EINTR); + } + else + { + break; + } + } + + return TRUE; +} + +static gpointer +kms_event_dispatch_in_impl (MetaKmsImpl *impl, + gpointer user_data, + GError **error) +{ + MetaKmsImplDevice *impl_device = user_data; + gboolean ret; + + ret = meta_kms_impl_device_dispatch (impl_device, error); + return GINT_TO_POINTER (ret); +} + +drmModePropertyPtr +meta_kms_impl_device_find_property (MetaKmsImplDevice *impl_device, + drmModeObjectProperties *props, + const char *prop_name, + int *out_idx) +{ + unsigned int i; + + meta_assert_in_kms_impl (meta_kms_impl_get_kms (impl_device->impl)); + + for (i = 0; i < props->count_props; i++) + { + drmModePropertyPtr prop; + + prop = drmModeGetProperty (impl_device->fd, props->props[i]); + if (!prop) + continue; + + if (strcmp (prop->name, prop_name) == 0) + { + *out_idx = i; + return prop; + } + + drmModeFreeProperty (prop); + } + + return NULL; +} + +static void +init_caps (MetaKmsImplDevice *impl_device) +{ + int fd = impl_device->fd; + uint64_t cursor_width, cursor_height; + + if (drmGetCap (fd, DRM_CAP_CURSOR_WIDTH, &cursor_width) == 0 && + drmGetCap (fd, DRM_CAP_CURSOR_HEIGHT, &cursor_height) == 0) + { + impl_device->caps.has_cursor_size = TRUE; + impl_device->caps.cursor_width = cursor_width; + impl_device->caps.cursor_height = cursor_height; + } +} + +static void +init_crtcs (MetaKmsImplDevice *impl_device, + drmModeRes *drm_resources) +{ + int idx; + + for (idx = 0; idx < drm_resources->count_crtcs; idx++) + { + drmModeCrtc *drm_crtc; + MetaKmsCrtc *crtc; + + drm_crtc = drmModeGetCrtc (impl_device->fd, drm_resources->crtcs[idx]); + crtc = meta_kms_crtc_new (impl_device, drm_crtc, idx); + drmModeFreeCrtc (drm_crtc); + + impl_device->crtcs = g_list_prepend (impl_device->crtcs, crtc); + } + impl_device->crtcs = g_list_reverse (impl_device->crtcs); +} + +static MetaKmsConnector * +find_existing_connector (MetaKmsImplDevice *impl_device, + drmModeConnector *drm_connector) +{ + GList *l; + + for (l = impl_device->connectors; l; l = l->next) + { + MetaKmsConnector *connector = l->data; + + if (meta_kms_connector_is_same_as (connector, drm_connector)) + return connector; + } + + return NULL; +} + +static void +update_connectors (MetaKmsImplDevice *impl_device, + drmModeRes *drm_resources) +{ + GList *connectors = NULL; + unsigned int i; + + for (i = 0; i < drm_resources->count_connectors; i++) + { + drmModeConnector *drm_connector; + MetaKmsConnector *connector; + + drm_connector = drmModeGetConnector (impl_device->fd, + drm_resources->connectors[i]); + if (!drm_connector) + continue; + + connector = find_existing_connector (impl_device, drm_connector); + if (connector) + connector = g_object_ref (connector); + else + connector = meta_kms_connector_new (impl_device, drm_connector, + drm_resources); + drmModeFreeConnector (drm_connector); + + connectors = g_list_prepend (connectors, connector); + } + + g_list_free_full (impl_device->connectors, g_object_unref); + impl_device->connectors = g_list_reverse (connectors); +} + +static MetaKmsPlaneType +get_plane_type (MetaKmsImplDevice *impl_device, + drmModeObjectProperties *props) +{ + drmModePropertyPtr prop; + int idx; + + prop = meta_kms_impl_device_find_property (impl_device, props, "type", &idx); + if (!prop) + return FALSE; + drmModeFreeProperty (prop); + + switch (props->prop_values[idx]) + { + case DRM_PLANE_TYPE_PRIMARY: + return META_KMS_PLANE_TYPE_PRIMARY; + case DRM_PLANE_TYPE_CURSOR: + return META_KMS_PLANE_TYPE_CURSOR; + case DRM_PLANE_TYPE_OVERLAY: + return META_KMS_PLANE_TYPE_OVERLAY; + default: + g_warning ("Unhandled plane type %" G_GUINT64_FORMAT, + props->prop_values[idx]); + return -1; + } +} + +MetaKmsPlane * +meta_kms_impl_device_add_fake_plane (MetaKmsImplDevice *impl_device, + MetaKmsPlaneType plane_type, + MetaKmsCrtc *crtc) +{ + MetaKmsPlane *plane; + + plane = meta_kms_plane_new_fake (plane_type, crtc); + impl_device->planes = g_list_append (impl_device->planes, plane); + + return plane; +} + +static void +init_planes (MetaKmsImplDevice *impl_device) +{ + int fd = impl_device->fd; + drmModePlaneRes *drm_planes; + unsigned int i; + + drm_planes = drmModeGetPlaneResources (fd); + if (!drm_planes) + return; + + for (i = 0; i < drm_planes->count_planes; i++) + { + drmModePlane *drm_plane; + drmModeObjectProperties *props; + + drm_plane = drmModeGetPlane (fd, drm_planes->planes[i]); + if (!drm_plane) + continue; + + props = drmModeObjectGetProperties (fd, + drm_plane->plane_id, + DRM_MODE_OBJECT_PLANE); + if (props) + { + MetaKmsPlaneType plane_type; + + plane_type = get_plane_type (impl_device, props); + if (plane_type != -1) + { + MetaKmsPlane *plane; + + plane = meta_kms_plane_new (plane_type, + impl_device, + drm_plane, props); + + impl_device->planes = g_list_prepend (impl_device->planes, plane); + } + } + + g_clear_pointer (&props, drmModeFreeObjectProperties); + drmModeFreePlane (drm_plane); + } + impl_device->planes = g_list_reverse (impl_device->planes); +} + +void +meta_kms_impl_device_update_states (MetaKmsImplDevice *impl_device) +{ + drmModeRes *drm_resources; + + meta_assert_in_kms_impl (meta_kms_impl_get_kms (impl_device->impl)); + + drm_resources = drmModeGetResources (impl_device->fd); + if (!drm_resources) + { + g_list_free_full (impl_device->planes, g_object_unref); + g_list_free_full (impl_device->crtcs, g_object_unref); + g_list_free_full (impl_device->connectors, g_object_unref); + impl_device->planes = NULL; + impl_device->crtcs = NULL; + impl_device->connectors = NULL; + return; + } + + update_connectors (impl_device, drm_resources); + + g_list_foreach (impl_device->crtcs, (GFunc) meta_kms_crtc_update_state, + NULL); + g_list_foreach (impl_device->connectors, (GFunc) meta_kms_connector_update_state, + drm_resources); + drmModeFreeResources (drm_resources); +} + +void +meta_kms_impl_device_predict_states (MetaKmsImplDevice *impl_device, + MetaKmsUpdate *update) +{ + g_list_foreach (impl_device->crtcs, (GFunc) meta_kms_crtc_predict_state, + update); + g_list_foreach (impl_device->connectors, (GFunc) meta_kms_connector_predict_state, + update); +} + +MetaKmsImplDevice * +meta_kms_impl_device_new (MetaKmsDevice *device, + MetaKmsImpl *impl, + int fd, + GError **error) +{ + MetaKms *kms = meta_kms_impl_get_kms (impl); + MetaKmsImplDevice *impl_device; + int ret; + drmModeRes *drm_resources; + + meta_assert_in_kms_impl (kms); + + ret = drmSetClientCap (fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); + if (ret != 0) + { + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (-ret), + "Failed to activate universal planes: %s", + g_strerror (-ret)); + return NULL; + } + + drm_resources = drmModeGetResources (fd); + if (!drm_resources) + { + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), + "Failed to activate universal planes: %s", + g_strerror (errno)); + return NULL; + } + + impl_device = g_object_new (META_TYPE_KMS_IMPL_DEVICE, NULL); + impl_device->device = device; + impl_device->impl = impl; + impl_device->fd = fd; + + init_caps (impl_device); + + init_crtcs (impl_device, drm_resources); + init_planes (impl_device); + + update_connectors (impl_device, drm_resources); + + drmModeFreeResources (drm_resources); + + impl_device->fd_source = + meta_kms_register_fd_in_impl (kms, fd, + kms_event_dispatch_in_impl, + impl_device); + + return impl_device; +} + +int +meta_kms_impl_device_get_fd (MetaKmsImplDevice *impl_device) +{ + meta_assert_in_kms_impl (meta_kms_impl_get_kms (impl_device->impl)); + + return impl_device->fd; +} + +int +meta_kms_impl_device_leak_fd (MetaKmsImplDevice *impl_device) +{ + return impl_device->fd; +} + +int +meta_kms_impl_device_close (MetaKmsImplDevice *impl_device) +{ + int fd; + + meta_assert_in_kms_impl (meta_kms_impl_get_kms (impl_device->impl)); + + g_clear_pointer (&impl_device->fd_source, g_source_destroy); + fd = impl_device->fd; + impl_device->fd = -1; + + return fd; +} + +static void +meta_kms_impl_device_finalize (GObject *object) +{ + MetaKmsImplDevice *impl_device = META_KMS_IMPL_DEVICE (object); + + g_list_free_full (impl_device->planes, g_object_unref); + g_list_free_full (impl_device->crtcs, g_object_unref); + g_list_free_full (impl_device->connectors, g_object_unref); + + G_OBJECT_CLASS (meta_kms_impl_device_parent_class)->finalize (object); +} + +static void +meta_kms_impl_device_init (MetaKmsImplDevice *device) +{ +} + +static void +meta_kms_impl_device_class_init (MetaKmsImplDeviceClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_kms_impl_device_finalize; +} + diff --git a/src/backends/native/meta-kms-impl-device.h b/src/backends/native/meta-kms-impl-device.h new file mode 100644 index 000000000..e8c08f19f --- /dev/null +++ b/src/backends/native/meta-kms-impl-device.h @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2019 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_KMS_IMPL_DEVICE_H +#define META_KMS_IMPL_DEVICE_H + +#include <glib-object.h> +#include <stdint.h> +#include <xf86drmMode.h> + +#include "backends/native/meta-kms-device.h" +#include "backends/native/meta-kms-types.h" +#include "backends/native/meta-kms-update.h" + +typedef struct _MetaKmsDeviceCaps +{ + gboolean has_cursor_size; + uint64_t cursor_width; + uint64_t cursor_height; +} MetaKmsDeviceCaps; + +#define META_TYPE_KMS_IMPL_DEVICE (meta_kms_impl_device_get_type ()) +G_DECLARE_FINAL_TYPE (MetaKmsImplDevice, meta_kms_impl_device, + META, KMS_IMPL_DEVICE, + GObject) + +MetaKmsDevice * meta_kms_impl_device_get_device (MetaKmsImplDevice *impl_device); + +GList * meta_kms_impl_device_copy_connectors (MetaKmsImplDevice *impl_device); + +GList * meta_kms_impl_device_copy_crtcs (MetaKmsImplDevice *impl_device); + +GList * meta_kms_impl_device_copy_planes (MetaKmsImplDevice *impl_device); + +const MetaKmsDeviceCaps * meta_kms_impl_device_get_caps (MetaKmsImplDevice *impl_device); + +gboolean meta_kms_impl_device_dispatch (MetaKmsImplDevice *impl_device, + GError **error); + +drmModePropertyPtr meta_kms_impl_device_find_property (MetaKmsImplDevice *impl_device, + drmModeObjectProperties *props, + const char *prop_name, + int *idx); + +int meta_kms_impl_device_get_fd (MetaKmsImplDevice *impl_device); + +int meta_kms_impl_device_leak_fd (MetaKmsImplDevice *impl_device); + +void meta_kms_impl_device_update_states (MetaKmsImplDevice *impl_device); + +void meta_kms_impl_device_predict_states (MetaKmsImplDevice *impl_device, + MetaKmsUpdate *update); + +MetaKmsPlane * meta_kms_impl_device_add_fake_plane (MetaKmsImplDevice *impl_device, + MetaKmsPlaneType plane_type, + MetaKmsCrtc *crtc); + +int meta_kms_impl_device_close (MetaKmsImplDevice *impl_device); + +MetaKmsImplDevice * meta_kms_impl_device_new (MetaKmsDevice *device, + MetaKmsImpl *kms_impl, + int fd, + GError **error); + +#endif /* META_KMS_IMPL_DEVICE_H */ diff --git a/src/backends/native/meta-kms-impl-simple.c b/src/backends/native/meta-kms-impl-simple.c new file mode 100644 index 000000000..b5c7bb742 --- /dev/null +++ b/src/backends/native/meta-kms-impl-simple.c @@ -0,0 +1,1104 @@ +/* + * Copyright (C) 2018-2019 Red Hat + * Copyright (C) 2019-2020 DisplayLink (UK) Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "backends/native/meta-kms-impl-simple.h" + +#include <errno.h> +#include <gbm.h> +#include <xf86drmMode.h> + +#include "backends/native/meta-kms-connector.h" +#include "backends/native/meta-kms-crtc.h" +#include "backends/native/meta-kms-device-private.h" +#include "backends/native/meta-kms-page-flip-private.h" +#include "backends/native/meta-kms-plane.h" +#include "backends/native/meta-kms-private.h" +#include "backends/native/meta-kms-update-private.h" +#include "backends/native/meta-kms-utils.h" + +typedef struct _CachedModeSet +{ + GList *connectors; + drmModeModeInfo *drm_mode; +} CachedModeSet; + +struct _MetaKmsImplSimple +{ + MetaKmsImpl parent; + + GSource *mode_set_fallback_feedback_source; + GList *mode_set_fallback_page_flip_datas; + + GList *pending_page_flip_retries; + GSource *retry_page_flips_source; + + GList *postponed_page_flip_datas; + GList *postponed_mode_set_fallback_datas; + + GHashTable *cached_mode_sets; +}; + +G_DEFINE_TYPE (MetaKmsImplSimple, meta_kms_impl_simple, + META_TYPE_KMS_IMPL) + +static void +flush_postponed_page_flip_datas (MetaKmsImplSimple *impl_simple); + +MetaKmsImplSimple * +meta_kms_impl_simple_new (MetaKms *kms, + GError **error) +{ + return g_object_new (META_TYPE_KMS_IMPL_SIMPLE, + "kms", kms, + NULL); +} + +static gboolean +process_connector_property (MetaKmsImpl *impl, + MetaKmsUpdate *update, + gpointer update_entry, + GError **error) +{ + MetaKmsConnectorProperty *connector_property = update_entry; + MetaKmsConnector *connector = connector_property->connector; + MetaKmsDevice *device = meta_kms_connector_get_device (connector); + MetaKmsImplDevice *impl_device = meta_kms_device_get_impl_device (device); + int fd; + int ret; + + fd = meta_kms_impl_device_get_fd (impl_device); + + ret = drmModeObjectSetProperty (fd, + meta_kms_connector_get_id (connector), + DRM_MODE_OBJECT_CONNECTOR, + connector_property->prop_id, + connector_property->value); + if (ret != 0) + { + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (-ret), + "Failed to set connector %u property %u: %s", + meta_kms_connector_get_id (connector), + connector_property->prop_id, + g_strerror (-ret)); + return FALSE; + } + + return TRUE; +} + +static gboolean +process_plane_property (MetaKmsImpl *impl, + MetaKmsPlane *plane, + MetaKmsProperty *prop, + GError **error) +{ + MetaKmsDevice *device = meta_kms_plane_get_device (plane); + MetaKmsImplDevice *impl_device = meta_kms_device_get_impl_device (device); + int fd; + int ret; + + fd = meta_kms_impl_device_get_fd (impl_device); + + ret = drmModeObjectSetProperty (fd, + meta_kms_plane_get_id (plane), + DRM_MODE_OBJECT_PLANE, + prop->prop_id, + prop->value); + if (ret != 0) + { + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (-ret), + "Failed to set plane %u property %u: %s", + meta_kms_plane_get_id (plane), + prop->prop_id, + g_strerror (-ret)); + return FALSE; + } + + return TRUE; +} + +static CachedModeSet * +cached_mode_set_new (GList *connectors, + const drmModeModeInfo *drm_mode) +{ + CachedModeSet *cached_mode_set; + + cached_mode_set = g_new0 (CachedModeSet, 1); + *cached_mode_set = (CachedModeSet) { + .connectors = g_list_copy (connectors), + .drm_mode = g_memdup (drm_mode, sizeof *drm_mode), + }; + + return cached_mode_set; +} + +static void +cached_mode_set_free (CachedModeSet *cached_mode_set) +{ + g_list_free (cached_mode_set->connectors); + g_free (cached_mode_set->drm_mode); + g_free (cached_mode_set); +} + +static void +fill_connector_ids_array (GList *connectors, + uint32_t **out_connectors, + int *out_n_connectors) +{ + GList *l; + int i; + + *out_n_connectors = g_list_length (connectors); + *out_connectors = g_new0 (uint32_t, *out_n_connectors); + i = 0; + for (l = connectors; l; l = l->next) + { + MetaKmsConnector *connector = l->data; + + (*out_connectors)[i++] = meta_kms_connector_get_id (connector); + } +} + +static gboolean +process_mode_set (MetaKmsImpl *impl, + MetaKmsUpdate *update, + gpointer update_entry, + GError **error) +{ + MetaKmsModeSet *mode_set = update_entry; + MetaKmsImplSimple *impl_simple = META_KMS_IMPL_SIMPLE (impl); + MetaKmsCrtc *crtc = mode_set->crtc; + MetaKmsDevice *device = meta_kms_crtc_get_device (crtc); + MetaKmsImplDevice *impl_device = meta_kms_device_get_impl_device (device); + g_autofree uint32_t *connectors = NULL; + int n_connectors; + MetaKmsPlaneAssignment *plane_assignment; + uint32_t x, y; + uint32_t fb_id; + int fd; + int ret; + + crtc = mode_set->crtc; + + if (mode_set->drm_mode) + { + GList *l; + + fill_connector_ids_array (mode_set->connectors, + &connectors, + &n_connectors); + + plane_assignment = meta_kms_update_get_primary_plane_assignment (update, + crtc); + if (!plane_assignment) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Missing primary plane assignment for legacy mode set on CRTC %u", + meta_kms_crtc_get_id (crtc)); + return FALSE; + } + + x = meta_fixed_16_to_int (plane_assignment->src_rect.x); + y = meta_fixed_16_to_int (plane_assignment->src_rect.y); + + for (l = plane_assignment->plane_properties; l; l = l->next) + { + MetaKmsProperty *prop = l->data; + + if (!process_plane_property (impl, plane_assignment->plane, + prop, error)) + return FALSE; + } + + fb_id = plane_assignment->fb_id; + } + else + { + x = y = 0; + n_connectors = 0; + connectors = NULL; + fb_id = 0; + } + + fd = meta_kms_impl_device_get_fd (impl_device); + ret = drmModeSetCrtc (fd, + meta_kms_crtc_get_id (crtc), + fb_id, + x, y, + connectors, n_connectors, + mode_set->drm_mode); + if (ret != 0) + { + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (-ret), + "Failed to set mode %s on CRTC %u: %s", + mode_set->drm_mode ? mode_set->drm_mode->name : "off", + meta_kms_crtc_get_id (crtc), + g_strerror (-ret)); + return FALSE; + } + + if (mode_set->drm_mode) + { + g_hash_table_replace (impl_simple->cached_mode_sets, + crtc, + cached_mode_set_new (mode_set->connectors, + mode_set->drm_mode)); + } + else + { + g_hash_table_remove (impl_simple->cached_mode_sets, crtc); + } + + return TRUE; +} + +static gboolean +process_crtc_gamma (MetaKmsImpl *impl, + MetaKmsUpdate *update, + gpointer update_entry, + GError **error) +{ + MetaKmsCrtcGamma *gamma = update_entry; + MetaKmsCrtc *crtc = gamma->crtc; + MetaKmsDevice *device = meta_kms_crtc_get_device (crtc); + MetaKmsImplDevice *impl_device = meta_kms_device_get_impl_device (device); + int fd; + int ret; + + fd = meta_kms_impl_device_get_fd (impl_device); + ret = drmModeCrtcSetGamma (fd, meta_kms_crtc_get_id (crtc), + gamma->size, + gamma->red, + gamma->green, + gamma->blue); + if (ret != 0) + { + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (-ret), + "drmModeCrtcSetGamma on CRTC %u failed: %s", + meta_kms_crtc_get_id (crtc), + g_strerror (-ret)); + return FALSE; + } + + return TRUE; +} + +static gboolean +is_timestamp_earlier_than (uint64_t ts1, + uint64_t ts2) +{ + if (ts1 == ts2) + return FALSE; + else + return ts2 - ts1 < UINT64_MAX / 2; +} + +typedef struct _RetryPageFlipData +{ + MetaKmsCrtc *crtc; + uint32_t fb_id; + MetaKmsPageFlipData *page_flip_data; + float refresh_rate; + uint64_t retry_time_us; +} RetryPageFlipData; + +static void +retry_page_flip_data_free (RetryPageFlipData *retry_page_flip_data) +{ + g_assert (!retry_page_flip_data->page_flip_data); + g_free (retry_page_flip_data); +} + +static CachedModeSet * +get_cached_mode_set (MetaKmsImplSimple *impl_simple, + MetaKmsCrtc *crtc) +{ + return g_hash_table_lookup (impl_simple->cached_mode_sets, crtc); +} + +static float +get_cached_crtc_refresh_rate (MetaKmsImplSimple *impl_simple, + MetaKmsCrtc *crtc) +{ + CachedModeSet *cached_mode_set; + + cached_mode_set = g_hash_table_lookup (impl_simple->cached_mode_sets, + crtc); + g_assert (cached_mode_set); + + return meta_calculate_drm_mode_refresh_rate (cached_mode_set->drm_mode); +} + +static gboolean +retry_page_flips (gpointer user_data) +{ + MetaKmsImplSimple *impl_simple = META_KMS_IMPL_SIMPLE (user_data); + uint64_t now_us; + GList *l; + + meta_assert_in_kms_impl (meta_kms_impl_get_kms (META_KMS_IMPL (impl_simple))); + + now_us = g_source_get_time (impl_simple->retry_page_flips_source); + + l = impl_simple->pending_page_flip_retries; + while (l) + { + RetryPageFlipData *retry_page_flip_data = l->data; + MetaKmsCrtc *crtc = retry_page_flip_data->crtc; + MetaKmsDevice *device = meta_kms_crtc_get_device (crtc); + MetaKmsImplDevice *impl_device = meta_kms_device_get_impl_device (device); + GList *l_next = l->next; + int fd; + int ret; + MetaKmsPageFlipData *page_flip_data; + + if (is_timestamp_earlier_than (now_us, + retry_page_flip_data->retry_time_us)) + { + l = l_next; + continue; + } + + fd = meta_kms_impl_device_get_fd (impl_device); + ret = drmModePageFlip (fd, + meta_kms_crtc_get_id (crtc), + retry_page_flip_data->fb_id, + DRM_MODE_PAGE_FLIP_EVENT, + retry_page_flip_data->page_flip_data); + if (ret == -EBUSY) + { + float refresh_rate; + + refresh_rate = get_cached_crtc_refresh_rate (impl_simple, crtc); + retry_page_flip_data->retry_time_us += + (uint64_t) (G_USEC_PER_SEC / refresh_rate); + l = l_next; + continue; + } + + impl_simple->pending_page_flip_retries = + g_list_remove_link (impl_simple->pending_page_flip_retries, l); + + page_flip_data = g_steal_pointer (&retry_page_flip_data->page_flip_data); + if (ret != 0) + { + g_autoptr (GError) error = NULL; + + g_set_error (&error, G_IO_ERROR, g_io_error_from_errno (-ret), + "drmModePageFlip on CRTC %u failed: %s", + meta_kms_crtc_get_id (crtc), + g_strerror (-ret)); + if (!g_error_matches (error, + G_IO_ERROR, + G_IO_ERROR_PERMISSION_DENIED)) + g_critical ("Failed to page flip: %s", error->message); + + meta_kms_page_flip_data_discard_in_impl (page_flip_data, error); + } + + retry_page_flip_data_free (retry_page_flip_data); + + l = l_next; + } + + if (impl_simple->pending_page_flip_retries) + { + GList *l; + uint64_t earliest_retry_time_us = 0; + + for (l = impl_simple->pending_page_flip_retries; l; l = l->next) + { + RetryPageFlipData *retry_page_flip_data = l->data; + + if (l == impl_simple->pending_page_flip_retries || + is_timestamp_earlier_than (retry_page_flip_data->retry_time_us, + earliest_retry_time_us)) + earliest_retry_time_us = retry_page_flip_data->retry_time_us; + } + + g_source_set_ready_time (impl_simple->retry_page_flips_source, + earliest_retry_time_us); + return G_SOURCE_CONTINUE; + } + else + { + g_clear_pointer (&impl_simple->retry_page_flips_source, + g_source_unref); + + flush_postponed_page_flip_datas (impl_simple); + + return G_SOURCE_REMOVE; + } +} + +static void +schedule_retry_page_flip (MetaKmsImplSimple *impl_simple, + MetaKmsCrtc *crtc, + uint32_t fb_id, + float refresh_rate, + MetaKmsPageFlipData *page_flip_data) +{ + RetryPageFlipData *retry_page_flip_data; + uint64_t now_us; + uint64_t retry_time_us; + + now_us = g_get_monotonic_time (); + retry_time_us = now_us + (uint64_t) (G_USEC_PER_SEC / refresh_rate); + + retry_page_flip_data = g_new0 (RetryPageFlipData, 1); + *retry_page_flip_data = (RetryPageFlipData) { + .crtc = crtc, + .fb_id = fb_id, + .page_flip_data = meta_kms_page_flip_data_ref (page_flip_data), + .refresh_rate = refresh_rate, + .retry_time_us = retry_time_us, + }; + + if (!impl_simple->retry_page_flips_source) + { + MetaKms *kms = meta_kms_impl_get_kms (META_KMS_IMPL (impl_simple)); + GSource *source; + + source = meta_kms_add_source_in_impl (kms, retry_page_flips, + impl_simple, NULL); + g_source_set_ready_time (source, retry_time_us); + + impl_simple->retry_page_flips_source = source; + } + else + { + GList *l; + + for (l = impl_simple->pending_page_flip_retries; l; l = l->next) + { + RetryPageFlipData *pending_retry_page_flip_data = l->data; + uint64_t pending_retry_time_us = + pending_retry_page_flip_data->retry_time_us; + + if (is_timestamp_earlier_than (retry_time_us, pending_retry_time_us)) + { + g_source_set_ready_time (impl_simple->retry_page_flips_source, + retry_time_us); + break; + } + } + } + + impl_simple->pending_page_flip_retries = + g_list_append (impl_simple->pending_page_flip_retries, + retry_page_flip_data); +} + +static void +invoke_page_flip_datas (GList *page_flip_datas, + MetaPageFlipDataFeedbackFunc func) +{ + g_list_foreach (page_flip_datas, (GFunc) func, NULL); +} + +static void +clear_page_flip_datas (GList **page_flip_datas) +{ + g_list_free_full (*page_flip_datas, + (GDestroyNotify) meta_kms_page_flip_data_unref); + *page_flip_datas = NULL; +} + +static gboolean +mode_set_fallback_feedback_idle (gpointer user_data) +{ + MetaKmsImplSimple *impl_simple = user_data; + + g_clear_pointer (&impl_simple->mode_set_fallback_feedback_source, + g_source_unref); + + if (impl_simple->pending_page_flip_retries) + { + impl_simple->postponed_mode_set_fallback_datas = + g_steal_pointer (&impl_simple->mode_set_fallback_page_flip_datas); + } + else + { + invoke_page_flip_datas (impl_simple->mode_set_fallback_page_flip_datas, + meta_kms_page_flip_data_mode_set_fallback_in_impl); + clear_page_flip_datas (&impl_simple->mode_set_fallback_page_flip_datas); + } + + return G_SOURCE_REMOVE; +} + +static gboolean +mode_set_fallback (MetaKmsImplSimple *impl_simple, + MetaKmsUpdate *update, + MetaKmsPageFlip *page_flip, + MetaKmsPlaneAssignment *plane_assignment, + MetaKmsPageFlipData *page_flip_data, + GError **error) +{ + MetaKms *kms = meta_kms_impl_get_kms (META_KMS_IMPL (impl_simple)); + MetaKmsCrtc *crtc = page_flip->crtc; + MetaKmsDevice *device = meta_kms_crtc_get_device (crtc); + MetaKmsImplDevice *impl_device = meta_kms_device_get_impl_device (device); + CachedModeSet *cached_mode_set; + g_autofree uint32_t *connectors = NULL; + int n_connectors; + uint32_t x, y; + int fd; + int ret; + + cached_mode_set = g_hash_table_lookup (impl_simple->cached_mode_sets, + crtc); + if (!cached_mode_set) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Missing mode set for page flip fallback"); + return FALSE; + } + + fill_connector_ids_array (cached_mode_set->connectors, + &connectors, + &n_connectors); + + x = meta_fixed_16_to_int (plane_assignment->src_rect.x); + y = meta_fixed_16_to_int (plane_assignment->src_rect.y); + + fd = meta_kms_impl_device_get_fd (impl_device); + ret = drmModeSetCrtc (fd, + meta_kms_crtc_get_id (crtc), + plane_assignment->fb_id, + x, y, + connectors, n_connectors, + cached_mode_set->drm_mode); + if (ret != 0) + { + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (-ret), + "drmModeSetCrtc mode '%s' on CRTC %u failed: %s", + cached_mode_set->drm_mode->name, + meta_kms_crtc_get_id (crtc), + g_strerror (-ret)); + return FALSE; + } + + if (!impl_simple->mode_set_fallback_feedback_source) + { + GSource *source; + + source = meta_kms_add_source_in_impl (kms, + mode_set_fallback_feedback_idle, + impl_simple, + NULL); + impl_simple->mode_set_fallback_feedback_source = source; + } + + impl_simple->mode_set_fallback_page_flip_datas = + g_list_prepend (impl_simple->mode_set_fallback_page_flip_datas, + meta_kms_page_flip_data_ref (page_flip_data)); + + return TRUE; +} + +static gboolean +process_page_flip (MetaKmsImpl *impl, + MetaKmsUpdate *update, + gpointer update_entry, + GError **error) +{ + MetaKmsPageFlip *page_flip = update_entry; + MetaKmsImplSimple *impl_simple = META_KMS_IMPL_SIMPLE (impl); + MetaKmsCrtc *crtc; + MetaKmsDevice *device; + MetaKmsImplDevice *impl_device; + MetaKmsPlaneAssignment *plane_assignment; + MetaKmsPageFlipData *page_flip_data; + MetaKmsCustomPageFlipFunc custom_page_flip_func; + int fd; + int ret; + + crtc = page_flip->crtc; + plane_assignment = meta_kms_update_get_primary_plane_assignment (update, + crtc); + + page_flip_data = meta_kms_page_flip_data_new (impl, + crtc, + page_flip->feedback, + page_flip->user_data); + + device = meta_kms_crtc_get_device (crtc); + impl_device = meta_kms_device_get_impl_device (device); + fd = meta_kms_impl_device_get_fd (impl_device); + custom_page_flip_func = page_flip->custom_page_flip_func; + if (custom_page_flip_func) + { + ret = custom_page_flip_func (page_flip->custom_page_flip_user_data, + meta_kms_page_flip_data_ref (page_flip_data)); + } + else + { + ret = drmModePageFlip (fd, + meta_kms_crtc_get_id (crtc), + plane_assignment->fb_id, + DRM_MODE_PAGE_FLIP_EVENT, + meta_kms_page_flip_data_ref (page_flip_data)); + } + + if (ret != 0) + meta_kms_page_flip_data_unref (page_flip_data); + + if (ret == -EBUSY) + { + CachedModeSet *cached_mode_set; + + cached_mode_set = get_cached_mode_set (impl_simple, crtc); + if (cached_mode_set) + { + drmModeModeInfo *drm_mode; + float refresh_rate; + + drm_mode = cached_mode_set->drm_mode; + refresh_rate = meta_calculate_drm_mode_refresh_rate (drm_mode); + schedule_retry_page_flip (impl_simple, + crtc, + plane_assignment->fb_id, + refresh_rate, + page_flip_data); + } + else + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Page flip of %u failed, and no mode set available", + meta_kms_crtc_get_id (crtc)); + meta_kms_page_flip_data_unref (page_flip_data); + return FALSE; + } + } + else if (ret == -EINVAL) + { + if (!mode_set_fallback (impl_simple, + update, + page_flip, + plane_assignment, + page_flip_data, + error)) + { + meta_kms_page_flip_data_unref (page_flip_data); + return FALSE; + } + } + else if (ret != 0) + { + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (-ret), + "drmModePageFlip on CRTC %u failed: %s", + meta_kms_crtc_get_id (crtc), + g_strerror (-ret)); + meta_kms_page_flip_data_unref (page_flip_data); + return FALSE; + } + + meta_kms_page_flip_data_unref (page_flip_data); + return TRUE; +} + +static void +discard_page_flip (MetaKmsImpl *impl, + MetaKmsUpdate *update, + MetaKmsPageFlip *page_flip) +{ + MetaKmsCrtc *crtc; + MetaKmsPageFlipData *page_flip_data; + + crtc = page_flip->crtc; + page_flip_data = meta_kms_page_flip_data_new (impl, + crtc, + page_flip->feedback, + page_flip->user_data); + meta_kms_page_flip_data_discard_in_impl (page_flip_data, NULL); + meta_kms_page_flip_data_unref (page_flip_data); +} + +static gboolean +process_entries (MetaKmsImpl *impl, + MetaKmsUpdate *update, + GList *entries, + gboolean (* func) (MetaKmsImpl *impl, + MetaKmsUpdate *update, + gpointer entry_data, + GError **error), + GError **error) +{ + GList *l; + + for (l = entries; l; l = l->next) + { + if (!func (impl, update, l->data, error)) + return FALSE; + } + + return TRUE; +} + +static gboolean +process_cursor_plane_assignment (MetaKmsImpl *impl, + MetaKmsUpdate *update, + MetaKmsPlaneAssignment *plane_assignment, + GError **error) +{ + MetaKmsPlane *plane; + MetaKmsDevice *device; + MetaKmsImplDevice *impl_device; + int fd; + + plane = plane_assignment->plane; + device = meta_kms_plane_get_device (plane); + impl_device = meta_kms_device_get_impl_device (device); + fd = meta_kms_impl_device_get_fd (impl_device); + + if (!(plane_assignment->flags & META_KMS_ASSIGN_PLANE_FLAG_FB_UNCHANGED)) + { + int width, height; + int ret = -1; + + width = meta_fixed_16_to_int (plane_assignment->dst_rect.width); + height = meta_fixed_16_to_int (plane_assignment->dst_rect.height); + + if (plane_assignment->cursor_hotspot.is_valid) + { + ret = drmModeSetCursor2 (fd, meta_kms_crtc_get_id (plane_assignment->crtc), + plane_assignment->fb_id, + width, height, + plane_assignment->cursor_hotspot.x, + plane_assignment->cursor_hotspot.y); + } + + if (ret != 0) + { + ret = drmModeSetCursor (fd, meta_kms_crtc_get_id (plane_assignment->crtc), + plane_assignment->fb_id, + width, height); + } + + if (ret != 0) + { + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (-ret), + "drmModeSetCursor failed: %s", g_strerror (-ret)); + return FALSE; + } + } + + drmModeMoveCursor (fd, + meta_kms_crtc_get_id (plane_assignment->crtc), + meta_fixed_16_to_int (plane_assignment->dst_rect.x), + meta_fixed_16_to_int (plane_assignment->dst_rect.y)); + + return TRUE; +} + +static gboolean +process_plane_assignment (MetaKmsImpl *impl, + MetaKmsUpdate *update, + MetaKmsPlaneAssignment *plane_assignment, + MetaKmsPlaneFeedback **plane_feedback) +{ + MetaKmsPlane *plane; + MetaKmsPlaneType plane_type; + GError *error = NULL; + + plane = plane_assignment->plane; + plane_type = meta_kms_plane_get_plane_type (plane); + switch (plane_type) + { + case META_KMS_PLANE_TYPE_PRIMARY: + /* Handled as part of the mode-set and page flip. */ + return TRUE; + case META_KMS_PLANE_TYPE_CURSOR: + if (!process_cursor_plane_assignment (impl, update, + plane_assignment, + &error)) + { + *plane_feedback = + meta_kms_plane_feedback_new_take_error (plane, + plane_assignment->crtc, + g_steal_pointer (&error)); + return FALSE; + } + else + { + return TRUE; + } + case META_KMS_PLANE_TYPE_OVERLAY: + error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_FAILED, + "Overlay planes cannot be assigned"); + *plane_feedback = + meta_kms_plane_feedback_new_take_error (plane, + plane_assignment->crtc, + g_steal_pointer (&error)); + return TRUE; + } + + g_assert_not_reached (); +} + +static GList * +process_plane_assignments (MetaKmsImpl *impl, + MetaKmsUpdate *update) +{ + GList *failed_planes = NULL; + GList *l; + + for (l = meta_kms_update_get_plane_assignments (update); l; l = l->next) + { + MetaKmsPlaneAssignment *plane_assignment = l->data; + MetaKmsPlaneFeedback *plane_feedback; + + if (!process_plane_assignment (impl, update, plane_assignment, + &plane_feedback)) + failed_planes = g_list_prepend (failed_planes, plane_feedback); + } + + return failed_planes; +} + +static GList * +generate_all_failed_feedbacks (MetaKmsUpdate *update) +{ + GList *failed_planes = NULL; + GList *l; + + for (l = meta_kms_update_get_plane_assignments (update); l; l = l->next) + { + MetaKmsPlaneAssignment *plane_assignment = l->data; + MetaKmsPlane *plane; + MetaKmsPlaneType plane_type; + MetaKmsPlaneFeedback *plane_feedback; + + plane = plane_assignment->plane; + plane_type = meta_kms_plane_get_plane_type (plane); + switch (plane_type) + { + case META_KMS_PLANE_TYPE_PRIMARY: + continue; + case META_KMS_PLANE_TYPE_CURSOR: + case META_KMS_PLANE_TYPE_OVERLAY: + break; + } + + plane_feedback = + meta_kms_plane_feedback_new_take_error (plane_assignment->plane, + plane_assignment->crtc, + g_error_new (G_IO_ERROR, + G_IO_ERROR_FAILED, + "Discarded")); + failed_planes = g_list_prepend (failed_planes, plane_feedback); + } + + return failed_planes; +} + +static MetaKmsFeedback * +meta_kms_impl_simple_process_update (MetaKmsImpl *impl, + MetaKmsUpdate *update) +{ + GError *error = NULL; + GList *failed_planes; + GList *l; + + meta_assert_in_kms_impl (meta_kms_impl_get_kms (impl)); + + if (!process_entries (impl, + update, + meta_kms_update_get_connector_properties (update), + process_connector_property, + &error)) + goto err_planes_not_assigned; + + if (!process_entries (impl, + update, + meta_kms_update_get_mode_sets (update), + process_mode_set, + &error)) + goto err_planes_not_assigned; + + if (!process_entries (impl, + update, + meta_kms_update_get_crtc_gammas (update), + process_crtc_gamma, + &error)) + goto err_planes_not_assigned; + + failed_planes = process_plane_assignments (impl, update); + if (failed_planes) + { + g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Failed to assign one or more planes"); + goto err_planes_assigned; + } + + if (!process_entries (impl, + update, + meta_kms_update_get_page_flips (update), + process_page_flip, + &error)) + goto err_planes_assigned; + + return meta_kms_feedback_new_passed (); + +err_planes_not_assigned: + failed_planes = generate_all_failed_feedbacks (update); + +err_planes_assigned: + for (l = meta_kms_update_get_page_flips (update); l; l = l->next) + { + MetaKmsPageFlip *page_flip = l->data; + + discard_page_flip (impl, update, page_flip); + } + + return meta_kms_feedback_new_failed (failed_planes, error); +} + +static void +flush_postponed_page_flip_datas (MetaKmsImplSimple *impl_simple) +{ + invoke_page_flip_datas (impl_simple->postponed_page_flip_datas, + meta_kms_page_flip_data_flipped_in_impl); + clear_page_flip_datas (&impl_simple->postponed_page_flip_datas); + + invoke_page_flip_datas (impl_simple->postponed_mode_set_fallback_datas, + meta_kms_page_flip_data_mode_set_fallback_in_impl); + clear_page_flip_datas (&impl_simple->postponed_mode_set_fallback_datas); +} + +static void +meta_kms_impl_simple_handle_page_flip_callback (MetaKmsImpl *impl, + MetaKmsPageFlipData *page_flip_data) +{ + MetaKmsImplSimple *impl_simple = META_KMS_IMPL_SIMPLE (impl); + + if (impl_simple->pending_page_flip_retries) + { + impl_simple->postponed_page_flip_datas = + g_list_append (impl_simple->postponed_page_flip_datas, + meta_kms_page_flip_data_ref (page_flip_data)); + } + else + { + meta_kms_page_flip_data_flipped_in_impl (page_flip_data); + } + + meta_kms_page_flip_data_unref (page_flip_data); +} + +static void +meta_kms_impl_simple_discard_pending_page_flips (MetaKmsImpl *impl) +{ + MetaKmsImplSimple *impl_simple = META_KMS_IMPL_SIMPLE (impl); + GList *l; + + if (!impl_simple->pending_page_flip_retries) + return; + + for (l = impl_simple->pending_page_flip_retries; l; l = l->next) + { + RetryPageFlipData *retry_page_flip_data = l->data; + MetaKmsPageFlipData *page_flip_data; + + page_flip_data = g_steal_pointer (&retry_page_flip_data->page_flip_data); + meta_kms_page_flip_data_discard_in_impl (page_flip_data, NULL); + retry_page_flip_data_free (retry_page_flip_data); + } + g_clear_pointer (&impl_simple->pending_page_flip_retries, g_list_free); + + g_clear_pointer (&impl_simple->retry_page_flips_source, + g_source_destroy); +} + +static void +meta_kms_impl_simple_dispatch_idle (MetaKmsImpl *impl) +{ + MetaKmsImplSimple *impl_simple = META_KMS_IMPL_SIMPLE (impl); + + if (impl_simple->mode_set_fallback_feedback_source) + mode_set_fallback_feedback_idle (impl_simple); +} + +static void +meta_kms_impl_simple_notify_device_created (MetaKmsImpl *impl, + MetaKmsDevice *device) +{ + GList *l; + + for (l = meta_kms_device_get_crtcs (device); l; l = l->next) + { + MetaKmsCrtc *crtc = l->data; + MetaKmsPlane *plane; + + plane = meta_kms_device_get_cursor_plane_for (device, crtc); + if (plane) + continue; + + meta_kms_device_add_fake_plane_in_impl (device, + META_KMS_PLANE_TYPE_CURSOR, + crtc); + } +} + +static void +meta_kms_impl_simple_finalize (GObject *object) +{ + MetaKmsImplSimple *impl_simple = META_KMS_IMPL_SIMPLE (object); + + g_list_free_full (impl_simple->pending_page_flip_retries, + (GDestroyNotify) retry_page_flip_data_free); + g_list_free_full (impl_simple->postponed_page_flip_datas, + (GDestroyNotify) meta_kms_page_flip_data_unref); + g_list_free_full (impl_simple->postponed_mode_set_fallback_datas, + (GDestroyNotify) meta_kms_page_flip_data_unref); + g_clear_pointer (&impl_simple->mode_set_fallback_feedback_source, + g_source_destroy); + g_hash_table_destroy (impl_simple->cached_mode_sets); + + G_OBJECT_CLASS (meta_kms_impl_simple_parent_class)->finalize (object); +} + +static void +meta_kms_impl_simple_init (MetaKmsImplSimple *impl_simple) +{ + impl_simple->cached_mode_sets = + g_hash_table_new_full (NULL, + NULL, + NULL, + (GDestroyNotify) cached_mode_set_free); +} + +static void +meta_kms_impl_simple_class_init (MetaKmsImplSimpleClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MetaKmsImplClass *impl_class = META_KMS_IMPL_CLASS (klass); + + object_class->finalize = meta_kms_impl_simple_finalize; + + impl_class->process_update = meta_kms_impl_simple_process_update; + impl_class->handle_page_flip_callback = meta_kms_impl_simple_handle_page_flip_callback; + impl_class->discard_pending_page_flips = meta_kms_impl_simple_discard_pending_page_flips; + impl_class->dispatch_idle = meta_kms_impl_simple_dispatch_idle; + impl_class->notify_device_created = meta_kms_impl_simple_notify_device_created; +} diff --git a/src/backends/native/meta-kms-impl-simple.h b/src/backends/native/meta-kms-impl-simple.h new file mode 100644 index 000000000..e2cf6296e --- /dev/null +++ b/src/backends/native/meta-kms-impl-simple.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2018 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_KMS_IMPL_SIMPLE_H +#define META_KMS_IMPL_SIMPLE_H + +#include "backends/native/meta-kms-impl.h" + +#define META_TYPE_KMS_IMPL_SIMPLE meta_kms_impl_simple_get_type () +G_DECLARE_FINAL_TYPE (MetaKmsImplSimple, meta_kms_impl_simple, + META, KMS_IMPL_SIMPLE, MetaKmsImpl) + +MetaKmsImplSimple * meta_kms_impl_simple_new (MetaKms *kms, + GError **error); + +#endif /* META_KMS_IMPL_SIMPLE_H */ diff --git a/src/backends/native/meta-kms-impl.c b/src/backends/native/meta-kms-impl.c new file mode 100644 index 000000000..055273d5c --- /dev/null +++ b/src/backends/native/meta-kms-impl.c @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2018 Red Hat + * Copyright (C) 2019 DisplayLink (UK) Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "backends/native/meta-kms-impl.h" + +enum +{ + PROP_0, + + PROP_KMS, +}; + +typedef struct _MetaKmsImplPrivate +{ + MetaKms *kms; +} MetaKmsImplPrivate; + +G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaKmsImpl, meta_kms_impl, G_TYPE_OBJECT) + +MetaKms * +meta_kms_impl_get_kms (MetaKmsImpl *impl) +{ + MetaKmsImplPrivate *priv = meta_kms_impl_get_instance_private (impl); + + return priv->kms; +} + +MetaKmsFeedback * +meta_kms_impl_process_update (MetaKmsImpl *impl, + MetaKmsUpdate *update) +{ + return META_KMS_IMPL_GET_CLASS (impl)->process_update (impl, update); +} + +void +meta_kms_impl_handle_page_flip_callback (MetaKmsImpl *impl, + MetaKmsPageFlipData *page_flip_data) +{ + META_KMS_IMPL_GET_CLASS (impl)->handle_page_flip_callback (impl, + page_flip_data); +} + +void +meta_kms_impl_discard_pending_page_flips (MetaKmsImpl *impl) +{ + META_KMS_IMPL_GET_CLASS (impl)->discard_pending_page_flips (impl); +} + +void +meta_kms_impl_dispatch_idle (MetaKmsImpl *impl) +{ + META_KMS_IMPL_GET_CLASS (impl)->dispatch_idle (impl); +} + +void +meta_kms_impl_notify_device_created (MetaKmsImpl *impl, + MetaKmsDevice *device) +{ + META_KMS_IMPL_GET_CLASS (impl)->notify_device_created (impl, device); +} + +static void +meta_kms_impl_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaKmsImpl *impl = META_KMS_IMPL (object); + MetaKmsImplPrivate *priv = meta_kms_impl_get_instance_private (impl); + + switch (prop_id) + { + case PROP_KMS: + priv->kms = g_value_get_object (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_kms_impl_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaKmsImpl *impl = META_KMS_IMPL (object); + MetaKmsImplPrivate *priv = meta_kms_impl_get_instance_private (impl); + + switch (prop_id) + { + case PROP_KMS: + g_value_set_object (value, priv->kms); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_kms_impl_init (MetaKmsImpl *kms_impl) +{ +} + +static void +meta_kms_impl_class_init (MetaKmsImplClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GParamSpec *pspec; + + object_class->set_property = meta_kms_impl_set_property; + object_class->get_property = meta_kms_impl_get_property; + + pspec = g_param_spec_object ("kms", + "kms", + "MetaKms", + META_TYPE_KMS, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS | + G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (object_class, + PROP_KMS, + pspec); +} diff --git a/src/backends/native/meta-kms-impl.h b/src/backends/native/meta-kms-impl.h new file mode 100644 index 000000000..80ec8a5c2 --- /dev/null +++ b/src/backends/native/meta-kms-impl.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2018 Red Hat + * Copyright (C) 2019 DisplayLink (UK) Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_KMS_IMPL_H +#define META_KMS_IMPL_H + +#include "backends/native/meta-kms-impl-device.h" +#include "backends/native/meta-kms-page-flip-private.h" +#include "backends/native/meta-kms.h" + +#define META_TYPE_KMS_IMPL (meta_kms_impl_get_type ()) +G_DECLARE_DERIVABLE_TYPE (MetaKmsImpl, meta_kms_impl, + META, KMS_IMPL, GObject) + +struct _MetaKmsImplClass +{ + GObjectClass parent_class; + + MetaKmsFeedback * (* process_update) (MetaKmsImpl *impl, + MetaKmsUpdate *update); + void (* handle_page_flip_callback) (MetaKmsImpl *impl, + MetaKmsPageFlipData *page_flip_data); + void (* discard_pending_page_flips) (MetaKmsImpl *impl); + void (* dispatch_idle) (MetaKmsImpl *impl); + void (* notify_device_created) (MetaKmsImpl *impl, + MetaKmsDevice *impl_device); +}; + +MetaKms * meta_kms_impl_get_kms (MetaKmsImpl *impl); + +MetaKmsFeedback * meta_kms_impl_process_update (MetaKmsImpl *impl, + MetaKmsUpdate *update); + +void meta_kms_impl_handle_page_flip_callback (MetaKmsImpl *impl, + MetaKmsPageFlipData *page_flip_data); + +void meta_kms_impl_discard_pending_page_flips (MetaKmsImpl *impl); + +void meta_kms_impl_dispatch_idle (MetaKmsImpl *impl); + +void meta_kms_impl_notify_device_created (MetaKmsImpl *impl, + MetaKmsDevice *impl_device); + +#endif /* META_KMS_IMPL_H */ diff --git a/src/backends/native/meta-kms-page-flip-private.h b/src/backends/native/meta-kms-page-flip-private.h new file mode 100644 index 000000000..ef8faf7ad --- /dev/null +++ b/src/backends/native/meta-kms-page-flip-private.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2019 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_KMS_PAGE_FLIP_H +#define META_KMS_PAGE_FLIP_H + +#include <glib.h> + +#include "backends/native/meta-kms-types.h" + +typedef struct _MetaKmsPageFlipData MetaKmsPageFlipData; + +typedef void (* MetaPageFlipDataFeedbackFunc) (MetaKmsPageFlipData *page_flip_data); + +MetaKmsPageFlipData * meta_kms_page_flip_data_new (MetaKmsImpl *impl, + MetaKmsCrtc *crtc, + const MetaKmsPageFlipFeedback *feedback, + gpointer user_data); + +MetaKmsPageFlipData * meta_kms_page_flip_data_ref (MetaKmsPageFlipData *page_flip_data); + +void meta_kms_page_flip_data_unref (MetaKmsPageFlipData *page_flip_data); + +MetaKmsImpl * meta_kms_page_flip_data_get_kms_impl (MetaKmsPageFlipData *page_flip_data); + +void meta_kms_page_flip_data_set_timings_in_impl (MetaKmsPageFlipData *page_flip_data, + unsigned int sequence, + unsigned int sec, + unsigned int usec); + +void meta_kms_page_flip_data_flipped_in_impl (MetaKmsPageFlipData *page_flip_data); + +void meta_kms_page_flip_data_mode_set_fallback_in_impl (MetaKmsPageFlipData *page_flip_data); + +void meta_kms_page_flip_data_discard_in_impl (MetaKmsPageFlipData *page_flip_data, + const GError *error); + +void meta_kms_page_flip_data_take_error (MetaKmsPageFlipData *page_flip_data, + GError *error); + +#endif /* META_KMS_PAGE_FLIP_H */ diff --git a/src/backends/native/meta-kms-page-flip.c b/src/backends/native/meta-kms-page-flip.c new file mode 100644 index 000000000..997c3fca5 --- /dev/null +++ b/src/backends/native/meta-kms-page-flip.c @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2019 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "backends/native/meta-kms-page-flip-private.h" + +#include "backends/native/meta-kms-impl.h" +#include "backends/native/meta-kms-private.h" +#include "backends/native/meta-kms-update.h" + +struct _MetaKmsPageFlipData +{ + int ref_count; + + MetaKmsImpl *impl; + MetaKmsCrtc *crtc; + + const MetaKmsPageFlipFeedback *feedback; + gpointer user_data; + + unsigned int sequence; + unsigned int sec; + unsigned int usec; + + GError *error; +}; + +MetaKmsPageFlipData * +meta_kms_page_flip_data_new (MetaKmsImpl *impl, + MetaKmsCrtc *crtc, + const MetaKmsPageFlipFeedback *feedback, + gpointer user_data) +{ + MetaKmsPageFlipData *page_flip_data; + + page_flip_data = g_new0 (MetaKmsPageFlipData , 1); + *page_flip_data = (MetaKmsPageFlipData) { + .ref_count = 1, + .impl = impl, + .crtc = crtc, + .feedback = feedback, + .user_data = user_data, + }; + + return page_flip_data; +} + +MetaKmsPageFlipData * +meta_kms_page_flip_data_ref (MetaKmsPageFlipData *page_flip_data) +{ + page_flip_data->ref_count++; + + return page_flip_data; +} + +void +meta_kms_page_flip_data_unref (MetaKmsPageFlipData *page_flip_data) +{ + page_flip_data->ref_count--; + + if (page_flip_data->ref_count == 0) + { + g_clear_error (&page_flip_data->error); + g_free (page_flip_data); + } +} + +MetaKmsImpl * +meta_kms_page_flip_data_get_kms_impl (MetaKmsPageFlipData *page_flip_data) +{ + return page_flip_data->impl; +} + +static void +meta_kms_page_flip_data_flipped (MetaKms *kms, + gpointer user_data) +{ + MetaKmsPageFlipData *page_flip_data = user_data; + + meta_assert_not_in_kms_impl (kms); + + page_flip_data->feedback->flipped (page_flip_data->crtc, + page_flip_data->sequence, + page_flip_data->sec, + page_flip_data->usec, + page_flip_data->user_data); +} + +void +meta_kms_page_flip_data_set_timings_in_impl (MetaKmsPageFlipData *page_flip_data, + unsigned int sequence, + unsigned int sec, + unsigned int usec) +{ + MetaKms *kms = meta_kms_impl_get_kms (page_flip_data->impl); + + meta_assert_in_kms_impl (kms); + + page_flip_data->sequence = sequence; + page_flip_data->sec = sec; + page_flip_data->usec = usec; +} + +void +meta_kms_page_flip_data_flipped_in_impl (MetaKmsPageFlipData *page_flip_data) +{ + MetaKms *kms = meta_kms_impl_get_kms (page_flip_data->impl); + + meta_assert_in_kms_impl (kms); + + meta_kms_queue_callback (kms, + meta_kms_page_flip_data_flipped, + meta_kms_page_flip_data_ref (page_flip_data), + (GDestroyNotify) meta_kms_page_flip_data_unref); +} + +static void +meta_kms_page_flip_data_mode_set_fallback (MetaKms *kms, + gpointer user_data) +{ + MetaKmsPageFlipData *page_flip_data = user_data; + + meta_assert_not_in_kms_impl (kms); + + page_flip_data->feedback->mode_set_fallback (page_flip_data->crtc, + page_flip_data->user_data); +} + +void +meta_kms_page_flip_data_mode_set_fallback_in_impl (MetaKmsPageFlipData *page_flip_data) +{ + MetaKms *kms = meta_kms_impl_get_kms (page_flip_data->impl); + + meta_assert_in_kms_impl (kms); + + meta_kms_queue_callback (kms, + meta_kms_page_flip_data_mode_set_fallback, + meta_kms_page_flip_data_ref (page_flip_data), + (GDestroyNotify) meta_kms_page_flip_data_unref); +} + +static void +meta_kms_page_flip_data_discard (MetaKms *kms, + gpointer user_data) +{ + MetaKmsPageFlipData *page_flip_data = user_data; + + meta_assert_not_in_kms_impl (kms); + + page_flip_data->feedback->discarded (page_flip_data->crtc, + page_flip_data->user_data, + page_flip_data->error); +} + +void +meta_kms_page_flip_data_take_error (MetaKmsPageFlipData *page_flip_data, + GError *error) +{ + g_assert (!page_flip_data->error); + + page_flip_data->error = error; +} + +void +meta_kms_page_flip_data_discard_in_impl (MetaKmsPageFlipData *page_flip_data, + const GError *error) +{ + MetaKms *kms = meta_kms_impl_get_kms (page_flip_data->impl); + + meta_assert_in_kms_impl (kms); + + if (error) + meta_kms_page_flip_data_take_error (page_flip_data, g_error_copy (error)); + + meta_kms_queue_callback (kms, + meta_kms_page_flip_data_discard, + meta_kms_page_flip_data_ref (page_flip_data), + (GDestroyNotify) meta_kms_page_flip_data_unref); +} diff --git a/src/backends/native/meta-kms-plane-private.h b/src/backends/native/meta-kms-plane-private.h new file mode 100644 index 000000000..2a36d4917 --- /dev/null +++ b/src/backends/native/meta-kms-plane-private.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2018-2019 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_KMS_PLANE_PRIVATE_H +#define META_KMS_PLANE_PRIVATE_H + +#include <xf86drm.h> +#include <xf86drmMode.h> + +#include "backends/native/meta-kms-plane.h" +#include "backends/native/meta-kms-types.h" + +MetaKmsPlane * meta_kms_plane_new (MetaKmsPlaneType type, + MetaKmsImplDevice *impl_device, + drmModePlane *drm_plane, + drmModeObjectProperties *drm_plane_props); + +MetaKmsPlane * meta_kms_plane_new_fake (MetaKmsPlaneType type, + MetaKmsCrtc *crtc); + +#endif /* META_KMS_PLANE_PRIVATE_H */ diff --git a/src/backends/native/meta-kms-plane.c b/src/backends/native/meta-kms-plane.c new file mode 100644 index 000000000..152077036 --- /dev/null +++ b/src/backends/native/meta-kms-plane.c @@ -0,0 +1,442 @@ +/* + * Copyright (C) 2013-2019 Red Hat + * Copyright (C) 2018 DisplayLink (UK) Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "backends/native/meta-kms-plane-private.h" + +#include <drm_fourcc.h> +#include <stdio.h> + +#include "backends/meta-monitor-transform.h" +#include "backends/native/meta-kms-crtc.h" +#include "backends/native/meta-kms-impl-device.h" +#include "backends/native/meta-kms-update-private.h" + +struct _MetaKmsPlane +{ + GObject parent; + + MetaKmsPlaneType type; + gboolean is_fake; + + uint32_t id; + + uint32_t possible_crtcs; + + uint32_t rotation_prop_id; + uint32_t rotation_map[META_MONITOR_N_TRANSFORMS]; + uint32_t all_hw_transforms; + + /* + * primary plane's supported formats and maybe modifiers + * key: GUINT_TO_POINTER (format) + * value: owned GArray* (uint64_t modifier), or NULL + */ + GHashTable *formats_modifiers; + + MetaKmsDevice *device; +}; + +G_DEFINE_TYPE (MetaKmsPlane, meta_kms_plane, G_TYPE_OBJECT) + +MetaKmsDevice * +meta_kms_plane_get_device (MetaKmsPlane *plane) +{ + return plane->device; +} + +uint32_t +meta_kms_plane_get_id (MetaKmsPlane *plane) +{ + g_return_val_if_fail (!plane->is_fake, 0); + + return plane->id; +} + +MetaKmsPlaneType +meta_kms_plane_get_plane_type (MetaKmsPlane *plane) +{ + return plane->type; +} + +void +meta_kms_plane_update_set_rotation (MetaKmsPlane *plane, + MetaKmsPlaneAssignment *plane_assignment, + MetaMonitorTransform transform) +{ + g_return_if_fail (meta_kms_plane_is_transform_handled (plane, transform)); + + meta_kms_plane_assignment_set_plane_property (plane_assignment, + plane->rotation_prop_id, + plane->rotation_map[transform]); +} + +gboolean +meta_kms_plane_is_transform_handled (MetaKmsPlane *plane, + MetaMonitorTransform transform) +{ + switch (transform) + { + case META_MONITOR_TRANSFORM_NORMAL: + case META_MONITOR_TRANSFORM_180: + case META_MONITOR_TRANSFORM_FLIPPED: + case META_MONITOR_TRANSFORM_FLIPPED_180: + break; + case META_MONITOR_TRANSFORM_90: + case META_MONITOR_TRANSFORM_270: + case META_MONITOR_TRANSFORM_FLIPPED_90: + case META_MONITOR_TRANSFORM_FLIPPED_270: + /* + * Blacklist these transforms as testing shows that they don't work + * anyway, e.g. due to the wrong buffer modifiers. They might as well be + * less optimal due to the complexity dealing with rotation at scan-out, + * potentially resulting in higher power consumption. + */ + return FALSE; + } + return plane->all_hw_transforms & (1 << transform); +} + +GArray * +meta_kms_plane_get_modifiers_for_format (MetaKmsPlane *plane, + uint32_t format) +{ + return g_hash_table_lookup (plane->formats_modifiers, + GUINT_TO_POINTER (format)); +} + +GArray * +meta_kms_plane_copy_drm_format_list (MetaKmsPlane *plane) +{ + GArray *formats; + GHashTableIter it; + gpointer key; + unsigned int n_formats_modifiers; + + n_formats_modifiers = g_hash_table_size (plane->formats_modifiers); + formats = g_array_sized_new (FALSE, FALSE, + sizeof (uint32_t), + n_formats_modifiers); + g_hash_table_iter_init (&it, plane->formats_modifiers); + while (g_hash_table_iter_next (&it, &key, NULL)) + { + uint32_t drm_format = GPOINTER_TO_UINT (key); + + g_array_append_val (formats, drm_format); + } + + return formats; +} + +gboolean +meta_kms_plane_is_format_supported (MetaKmsPlane *plane, + uint32_t drm_format) +{ + return g_hash_table_lookup_extended (plane->formats_modifiers, + GUINT_TO_POINTER (drm_format), + NULL, NULL); +} + +gboolean +meta_kms_plane_is_usable_with (MetaKmsPlane *plane, + MetaKmsCrtc *crtc) +{ + return !!(plane->possible_crtcs & (1 << meta_kms_crtc_get_idx (crtc))); +} + +static void +parse_rotations (MetaKmsPlane *plane, + MetaKmsImplDevice *impl_device, + drmModePropertyPtr prop) +{ + int i; + + for (i = 0; i < prop->count_enums; i++) + { + MetaMonitorTransform transform = -1; + + if (strcmp (prop->enums[i].name, "rotate-0") == 0) + transform = META_MONITOR_TRANSFORM_NORMAL; + else if (strcmp (prop->enums[i].name, "rotate-90") == 0) + transform = META_MONITOR_TRANSFORM_90; + else if (strcmp (prop->enums[i].name, "rotate-180") == 0) + transform = META_MONITOR_TRANSFORM_180; + else if (strcmp (prop->enums[i].name, "rotate-270") == 0) + transform = META_MONITOR_TRANSFORM_270; + + if (transform != -1) + { + plane->all_hw_transforms |= 1 << transform; + plane->rotation_map[transform] = 1 << prop->enums[i].value; + } + } +} + +static void +init_rotations (MetaKmsPlane *plane, + MetaKmsImplDevice *impl_device, + drmModeObjectProperties *drm_plane_props) +{ + drmModePropertyPtr prop; + int idx; + + prop = meta_kms_impl_device_find_property (impl_device, drm_plane_props, + "rotation", &idx); + if (prop) + { + plane->rotation_prop_id = drm_plane_props->props[idx]; + parse_rotations (plane, impl_device, prop); + drmModeFreeProperty (prop); + } +} + +static inline uint32_t * +drm_formats_ptr (struct drm_format_modifier_blob *blob) +{ + return (uint32_t *) (((char *) blob) + blob->formats_offset); +} + +static inline struct drm_format_modifier * +drm_modifiers_ptr (struct drm_format_modifier_blob *blob) +{ + return (struct drm_format_modifier *) (((char *) blob) + + blob->modifiers_offset); +} + +static void +free_modifier_array (GArray *array) +{ + if (!array) + return; + + g_array_free (array, TRUE); +} + +static void +parse_formats (MetaKmsPlane *plane, + MetaKmsImplDevice *impl_device, + uint32_t blob_id) +{ + int fd; + drmModePropertyBlobPtr blob; + struct drm_format_modifier_blob *blob_fmt; + uint32_t *formats; + struct drm_format_modifier *drm_modifiers; + unsigned int fmt_i, mod_i; + + g_return_if_fail (g_hash_table_size (plane->formats_modifiers) == 0); + + if (blob_id == 0) + return; + + fd = meta_kms_impl_device_get_fd (impl_device); + blob = drmModeGetPropertyBlob (fd, blob_id); + if (!blob) + return; + + if (blob->length < sizeof (struct drm_format_modifier_blob)) + { + drmModeFreePropertyBlob (blob); + return; + } + + blob_fmt = blob->data; + + formats = drm_formats_ptr (blob_fmt); + drm_modifiers = drm_modifiers_ptr (blob_fmt); + + for (fmt_i = 0; fmt_i < blob_fmt->count_formats; fmt_i++) + { + GArray *modifiers = g_array_new (FALSE, FALSE, sizeof (uint64_t)); + + for (mod_i = 0; mod_i < blob_fmt->count_modifiers; mod_i++) + { + struct drm_format_modifier *drm_modifier = &drm_modifiers[mod_i]; + + /* + * The modifier advertisement blob is partitioned into groups of + * 64 formats. + */ + if (fmt_i < drm_modifier->offset || fmt_i > drm_modifier->offset + 63) + continue; + + if (!(drm_modifier->formats & (1 << (fmt_i - drm_modifier->offset)))) + continue; + + g_array_append_val (modifiers, drm_modifier->modifier); + } + + if (modifiers->len == 0) + { + free_modifier_array (modifiers); + modifiers = NULL; + } + + g_hash_table_insert (plane->formats_modifiers, + GUINT_TO_POINTER (formats[fmt_i]), + modifiers); + } + + drmModeFreePropertyBlob (blob); +} + +static void +set_formats_from_array (MetaKmsPlane *plane, + const uint32_t *formats, + size_t n_formats) +{ + size_t i; + + for (i = 0; i < n_formats; i++) + { + g_hash_table_insert (plane->formats_modifiers, + GUINT_TO_POINTER (formats[i]), NULL); + } +} + +/* + * In case the DRM driver does not expose a format list for the + * primary plane (does not support universal planes nor + * IN_FORMATS property), hardcode something that is probably supported. + */ +static const uint32_t drm_default_formats[] = + { + /* The format everything should always support by convention */ + DRM_FORMAT_XRGB8888, +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + /* OpenGL GL_RGBA, GL_UNSIGNED_BYTE format, hopefully supported */ + DRM_FORMAT_XBGR8888 +#endif + }; + +static void +init_formats (MetaKmsPlane *plane, + MetaKmsImplDevice *impl_device, + drmModePlane *drm_plane, + drmModeObjectProperties *drm_plane_props) +{ + drmModePropertyPtr prop; + int idx; + + prop = meta_kms_impl_device_find_property (impl_device, drm_plane_props, + "IN_FORMATS", &idx); + if (prop) + { + uint32_t blob_id; + + blob_id = drm_plane_props->prop_values[idx]; + parse_formats (plane, impl_device, blob_id); + drmModeFreeProperty (prop); + } + + if (g_hash_table_size (plane->formats_modifiers) == 0) + { + set_formats_from_array (plane, + drm_plane->formats, + drm_plane->count_formats); + } + + /* final formats fallback to something hardcoded */ + if (g_hash_table_size (plane->formats_modifiers) == 0) + { + set_formats_from_array (plane, + drm_default_formats, + G_N_ELEMENTS (drm_default_formats)); + } +} + +MetaKmsPlane * +meta_kms_plane_new (MetaKmsPlaneType type, + MetaKmsImplDevice *impl_device, + drmModePlane *drm_plane, + drmModeObjectProperties *drm_plane_props) +{ + MetaKmsPlane *plane; + + plane = g_object_new (META_TYPE_KMS_PLANE, NULL); + plane->type = type; + plane->id = drm_plane->plane_id; + plane->possible_crtcs = drm_plane->possible_crtcs; + plane->device = meta_kms_impl_device_get_device (impl_device); + + init_rotations (plane, impl_device, drm_plane_props); + init_formats (plane, impl_device, drm_plane, drm_plane_props); + + return plane; +} + +MetaKmsPlane * +meta_kms_plane_new_fake (MetaKmsPlaneType type, + MetaKmsCrtc *crtc) +{ + MetaKmsPlane *plane; + + static const uint32_t fake_plane_drm_formats[] = + { + DRM_FORMAT_XRGB8888, + DRM_FORMAT_ARGB8888, +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + /* OpenGL GL_RGBA, GL_UNSIGNED_BYTE format, hopefully supported */ + DRM_FORMAT_XBGR8888, + DRM_FORMAT_ABGR8888 +#endif + }; + + plane = g_object_new (META_TYPE_KMS_PLANE, NULL); + plane->type = type; + plane->is_fake = TRUE; + plane->possible_crtcs = 1 << meta_kms_crtc_get_idx (crtc); + plane->device = meta_kms_crtc_get_device (crtc); + + set_formats_from_array (plane, + fake_plane_drm_formats, + G_N_ELEMENTS (fake_plane_drm_formats)); + + return plane; +} + +static void +meta_kms_plane_finalize (GObject *object) +{ + MetaKmsPlane *plane = META_KMS_PLANE (object); + + g_hash_table_destroy (plane->formats_modifiers); + + G_OBJECT_CLASS (meta_kms_plane_parent_class)->finalize (object); +} + +static void +meta_kms_plane_init (MetaKmsPlane *plane) +{ + plane->formats_modifiers = + g_hash_table_new_full (g_direct_hash, + g_direct_equal, + NULL, + (GDestroyNotify) free_modifier_array); +} + +static void +meta_kms_plane_class_init (MetaKmsPlaneClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_kms_plane_finalize; +} diff --git a/src/backends/native/meta-kms-plane.h b/src/backends/native/meta-kms-plane.h new file mode 100644 index 000000000..941c16680 --- /dev/null +++ b/src/backends/native/meta-kms-plane.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2018 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_KMS_PLANE_H +#define META_KMS_PLANE_H + +#include <glib-object.h> +#include <stdint.h> +#include <xf86drmMode.h> + +#include "backends/native/meta-kms-types.h" +#include "backends/meta-monitor-transform.h" + +enum _MetaKmsPlaneType +{ + META_KMS_PLANE_TYPE_PRIMARY, + META_KMS_PLANE_TYPE_CURSOR, + META_KMS_PLANE_TYPE_OVERLAY, +}; + +#define META_TYPE_KMS_PLANE meta_kms_plane_get_type () +G_DECLARE_FINAL_TYPE (MetaKmsPlane, meta_kms_plane, + META, KMS_PLANE, GObject) + +MetaKmsDevice * meta_kms_plane_get_device (MetaKmsPlane *plane); + +uint32_t meta_kms_plane_get_id (MetaKmsPlane *plane); + +MetaKmsPlaneType meta_kms_plane_get_plane_type (MetaKmsPlane *plane); + +gboolean meta_kms_plane_is_transform_handled (MetaKmsPlane *plane, + MetaMonitorTransform transform); + +GArray * meta_kms_plane_get_modifiers_for_format (MetaKmsPlane *plane, + uint32_t format); + +GArray * meta_kms_plane_copy_drm_format_list (MetaKmsPlane *plane); + +gboolean meta_kms_plane_is_format_supported (MetaKmsPlane *plane, + uint32_t format); + +gboolean meta_kms_plane_is_usable_with (MetaKmsPlane *plane, + MetaKmsCrtc *crtc); + +void meta_kms_plane_update_set_rotation (MetaKmsPlane *plane, + MetaKmsPlaneAssignment *plane_assignment, + MetaMonitorTransform transform); + +#endif /* META_KMS_PLANE_H */ diff --git a/src/backends/native/meta-kms-private.h b/src/backends/native/meta-kms-private.h new file mode 100644 index 000000000..65d441b2b --- /dev/null +++ b/src/backends/native/meta-kms-private.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2019 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_KMS_PRIVATE_H +#define META_KMS_PRIVATE_H + +#include "backends/native/meta-kms.h" + +#include "backends/native/meta-kms-types.h" + +typedef void (* MetaKmsCallback) (MetaKms *kms, + gpointer user_data); + +typedef gpointer (* MetaKmsImplTaskFunc) (MetaKmsImpl *impl, + gpointer user_data, + GError **error); + +void meta_kms_queue_callback (MetaKms *kms, + MetaKmsCallback callback, + gpointer user_data, + GDestroyNotify user_data_destroy); + +int meta_kms_flush_callbacks (MetaKms *kms); + +gpointer meta_kms_run_impl_task_sync (MetaKms *kms, + MetaKmsImplTaskFunc func, + gpointer user_data, + GError **error); + +GSource * meta_kms_add_source_in_impl (MetaKms *kms, + GSourceFunc func, + gpointer user_data, + GDestroyNotify user_data_destroy); + +GSource * meta_kms_register_fd_in_impl (MetaKms *kms, + int fd, + MetaKmsImplTaskFunc dispatch, + gpointer user_data); + +gboolean meta_kms_in_impl_task (MetaKms *kms); + +gboolean meta_kms_is_waiting_for_impl_task (MetaKms *kms); + +#define meta_assert_in_kms_impl(kms) \ + g_assert (meta_kms_in_impl_task (kms)) +#define meta_assert_not_in_kms_impl(kms) \ + g_assert (!meta_kms_in_impl_task (kms)) +#define meta_assert_is_waiting_for_kms_impl_task(kms) \ + g_assert (meta_kms_is_waiting_for_impl_task (kms)) + +#endif /* META_KMS_PRIVATE_H */ diff --git a/src/backends/native/meta-kms-types.h b/src/backends/native/meta-kms-types.h new file mode 100644 index 000000000..ec36d226a --- /dev/null +++ b/src/backends/native/meta-kms-types.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2019 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_KMS_IMPL_TYPES_H +#define META_KMS_IMPL_TYPES_H + +#include <stdint.h> + +typedef struct _MetaKms MetaKms; +typedef struct _MetaKmsDevice MetaKmsDevice; + +typedef struct _MetaKmsPlane MetaKmsPlane; +typedef struct _MetaKmsCrtc MetaKmsCrtc; +typedef struct _MetaKmsConnector MetaKmsConnector; + +typedef struct _MetaKmsUpdate MetaKmsUpdate; +typedef struct _MetaKmsPlaneAssignment MetaKmsPlaneAssignment; +typedef struct _MetaKmsModeSet MetaKmsModeSet; + +typedef struct _MetaKmsFeedback MetaKmsFeedback; + +typedef struct _MetaKmsPageFlipFeedback MetaKmsPageFlipFeedback; + +typedef struct _MetaKmsImpl MetaKmsImpl; +typedef struct _MetaKmsImplDevice MetaKmsImplDevice; + +/* 16:16 fixed point */ +typedef int32_t MetaFixed16; + +typedef struct _MetaFixed16Rectangle +{ + MetaFixed16 x; + MetaFixed16 y; + MetaFixed16 width; + MetaFixed16 height; +} MetaFixed16Rectangle; + +typedef enum _MetaKmsDeviceFlag +{ + META_KMS_DEVICE_FLAG_NONE = 0, + META_KMS_DEVICE_FLAG_BOOT_VGA = 1 << 0, + META_KMS_DEVICE_FLAG_PLATFORM_DEVICE = 1 << 1, +} MetaKmsDeviceFlag; + +typedef enum _MetaKmsPlaneType MetaKmsPlaneType; + +#endif /* META_KMS_IMPL_TYPES_H */ diff --git a/src/backends/native/meta-kms-update-private.h b/src/backends/native/meta-kms-update-private.h new file mode 100644 index 000000000..4d4d4a276 --- /dev/null +++ b/src/backends/native/meta-kms-update-private.h @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2019 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_KMS_UPDATE_PRIVATE_H +#define META_KMS_UPDATE_PRIVATE_H + +#include <glib.h> +#include <stdint.h> + +#include "backends/native/meta-kms-types.h" +#include "backends/native/meta-kms-update.h" + +typedef struct _MetaKmsFeedback +{ + MetaKmsFeedbackResult result; + + GList *failed_planes; + GError *error; +} MetaKmsFeedback; + +typedef struct _MetaKmsProperty +{ + uint32_t prop_id; + uint64_t value; +} MetaKmsProperty; + +typedef struct _MetaKmsPlaneAssignment +{ + MetaKmsUpdate *update; + MetaKmsCrtc *crtc; + MetaKmsPlane *plane; + uint32_t fb_id; + MetaFixed16Rectangle src_rect; + MetaFixed16Rectangle dst_rect; + MetaKmsAssignPlaneFlag flags; + + GList *plane_properties; + + struct { + gboolean is_valid; + int x; + int y; + } cursor_hotspot; +} MetaKmsPlaneAssignment; + +typedef struct _MetaKmsModeSet +{ + MetaKmsCrtc *crtc; + GList *connectors; + drmModeModeInfo *drm_mode; +} MetaKmsModeSet; + +typedef struct _MetaKmsConnectorProperty +{ + MetaKmsDevice *device; + MetaKmsConnector *connector; + uint32_t prop_id; + uint64_t value; +} MetaKmsConnectorProperty; + +typedef struct _MetaKmsCrtcGamma +{ + MetaKmsCrtc *crtc; + int size; + uint16_t *red; + uint16_t *green; + uint16_t *blue; +} MetaKmsCrtcGamma; + +typedef struct _MetaKmsPageFlip +{ + MetaKmsCrtc *crtc; + const MetaKmsPageFlipFeedback *feedback; + gpointer user_data; + MetaKmsCustomPageFlipFunc custom_page_flip_func; + gpointer custom_page_flip_user_data; +} MetaKmsPageFlip; + +void meta_kms_plane_feedback_free (MetaKmsPlaneFeedback *plane_feedback); + +MetaKmsPlaneFeedback * meta_kms_plane_feedback_new_take_error (MetaKmsPlane *plane, + MetaKmsCrtc *crtc, + GError *error); + +MetaKmsFeedback * meta_kms_feedback_new_passed (void); + +MetaKmsFeedback * meta_kms_feedback_new_failed (GList *failed_planes, + GError *error); + +void meta_kms_update_seal (MetaKmsUpdate *update); + +gboolean meta_kms_update_is_sealed (MetaKmsUpdate *update); + +void meta_kms_update_set_connector_property (MetaKmsUpdate *update, + MetaKmsConnector *connector, + uint32_t prop_id, + uint64_t value); + +void meta_kms_update_set_crtc_gamma (MetaKmsUpdate *update, + MetaKmsCrtc *crtc, + int size, + const uint16_t *red, + const uint16_t *green, + const uint16_t *blue); + +void meta_kms_plane_assignment_set_plane_property (MetaKmsPlaneAssignment *plane_assignment, + uint32_t prop_id, + uint64_t value); + +MetaKmsPlaneAssignment * meta_kms_update_get_primary_plane_assignment (MetaKmsUpdate *update, + MetaKmsCrtc *crtc); + +GList * meta_kms_update_get_plane_assignments (MetaKmsUpdate *update); + +GList * meta_kms_update_get_mode_sets (MetaKmsUpdate *update); + +GList * meta_kms_update_get_page_flips (MetaKmsUpdate *update); + +GList * meta_kms_update_get_connector_properties (MetaKmsUpdate *update); + +GList * meta_kms_update_get_crtc_gammas (MetaKmsUpdate *update); + +G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaKmsPlaneFeedback, + meta_kms_plane_feedback_free) + +#endif /* META_KMS_UPDATE_PRIVATE_H */ diff --git a/src/backends/native/meta-kms-update.c b/src/backends/native/meta-kms-update.c new file mode 100644 index 000000000..5ace83021 --- /dev/null +++ b/src/backends/native/meta-kms-update.c @@ -0,0 +1,430 @@ +/* + * Copyright (C) 2018 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "backends/native/meta-kms-update.h" +#include "backends/native/meta-kms-update-private.h" + +#include "backends/meta-display-config-shared.h" +#include "backends/native/meta-kms-plane.h" + +struct _MetaKmsUpdate +{ + gboolean is_sealed; + + MetaPowerSave power_save; + GList *mode_sets; + GList *plane_assignments; + GList *page_flips; + GList *connector_properties; + GList *crtc_gammas; +}; + +void +meta_kms_plane_feedback_free (MetaKmsPlaneFeedback *plane_feedback) +{ + g_error_free (plane_feedback->error); + g_free (plane_feedback); +} + +MetaKmsPlaneFeedback * +meta_kms_plane_feedback_new_take_error (MetaKmsPlane *plane, + MetaKmsCrtc *crtc, + GError *error) +{ + MetaKmsPlaneFeedback *plane_feedback; + + plane_feedback = g_new0 (MetaKmsPlaneFeedback, 1); + *plane_feedback = (MetaKmsPlaneFeedback) { + .plane = plane, + .crtc = crtc, + .error = error, + }; + + return plane_feedback; +} + +MetaKmsFeedback * +meta_kms_feedback_new_passed (void) +{ + MetaKmsFeedback *feedback; + + feedback = g_new0 (MetaKmsFeedback, 1); + *feedback = (MetaKmsFeedback) { + .result = META_KMS_FEEDBACK_PASSED, + }; + + return feedback; +} + +MetaKmsFeedback * +meta_kms_feedback_new_failed (GList *failed_planes, + GError *error) +{ + MetaKmsFeedback *feedback; + + feedback = g_new0 (MetaKmsFeedback, 1); + *feedback = (MetaKmsFeedback) { + .result = META_KMS_FEEDBACK_FAILED, + .error = error, + .failed_planes = failed_planes, + }; + + return feedback; +} + +void +meta_kms_feedback_free (MetaKmsFeedback *feedback) +{ + g_list_free_full (feedback->failed_planes, + (GDestroyNotify) meta_kms_plane_feedback_free); + g_clear_error (&feedback->error); + g_free (feedback); +} + +MetaKmsFeedbackResult +meta_kms_feedback_get_result (MetaKmsFeedback *feedback) +{ + return feedback->result; +} + +GList * +meta_kms_feedback_get_failed_planes (MetaKmsFeedback *feedback) +{ + return feedback->failed_planes; +} + +const GError * +meta_kms_feedback_get_error (MetaKmsFeedback *feedback) +{ + return feedback->error; +} + +static MetaKmsProperty * +meta_kms_property_new (uint32_t prop_id, + uint64_t value) +{ + MetaKmsProperty *prop; + + prop = g_new0 (MetaKmsProperty, 1); + *prop = (MetaKmsProperty) { + .prop_id = prop_id, + .value = value, + }; + + return prop; +} + +static void +meta_kms_property_free (MetaKmsProperty *prop) +{ + g_free (prop); +} + +static void +meta_kms_plane_assignment_free (MetaKmsPlaneAssignment *plane_assignment) +{ + g_list_free_full (plane_assignment->plane_properties, + (GDestroyNotify) meta_kms_property_free); + g_free (plane_assignment); +} + +static void +meta_kms_mode_set_free (MetaKmsModeSet *mode_set) +{ + g_free (mode_set->drm_mode); + g_list_free (mode_set->connectors); + g_free (mode_set); +} + +MetaKmsPlaneAssignment * +meta_kms_update_assign_plane (MetaKmsUpdate *update, + MetaKmsCrtc *crtc, + MetaKmsPlane *plane, + uint32_t fb_id, + MetaFixed16Rectangle src_rect, + MetaFixed16Rectangle dst_rect, + MetaKmsAssignPlaneFlag flags) +{ + MetaKmsPlaneAssignment *plane_assignment; + + g_assert (!meta_kms_update_is_sealed (update)); + + plane_assignment = g_new0 (MetaKmsPlaneAssignment, 1); + *plane_assignment = (MetaKmsPlaneAssignment) { + .update = update, + .crtc = crtc, + .plane = plane, + .fb_id = fb_id, + .src_rect = src_rect, + .dst_rect = dst_rect, + .flags = flags, + }; + + update->plane_assignments = g_list_prepend (update->plane_assignments, + plane_assignment); + + return plane_assignment; +} + +MetaKmsPlaneAssignment * +meta_kms_update_unassign_plane (MetaKmsUpdate *update, + MetaKmsCrtc *crtc, + MetaKmsPlane *plane) +{ + MetaKmsPlaneAssignment *plane_assignment; + + g_assert (!meta_kms_update_is_sealed (update)); + + plane_assignment = g_new0 (MetaKmsPlaneAssignment, 1); + *plane_assignment = (MetaKmsPlaneAssignment) { + .update = update, + .crtc = crtc, + .plane = plane, + .fb_id = 0, + }; + + update->plane_assignments = g_list_prepend (update->plane_assignments, + plane_assignment); + + return plane_assignment; +} + +void +meta_kms_update_mode_set (MetaKmsUpdate *update, + MetaKmsCrtc *crtc, + GList *connectors, + drmModeModeInfo *drm_mode) +{ + MetaKmsModeSet *mode_set; + + g_assert (!meta_kms_update_is_sealed (update)); + + mode_set = g_new0 (MetaKmsModeSet, 1); + *mode_set = (MetaKmsModeSet) { + .crtc = crtc, + .connectors = connectors, + .drm_mode = drm_mode ? g_memdup (drm_mode, sizeof *drm_mode) : NULL, + }; + + update->mode_sets = g_list_prepend (update->mode_sets, mode_set); +} + +void +meta_kms_update_set_connector_property (MetaKmsUpdate *update, + MetaKmsConnector *connector, + uint32_t prop_id, + uint64_t value) +{ + MetaKmsConnectorProperty *prop; + + g_assert (!meta_kms_update_is_sealed (update)); + + prop = g_new0 (MetaKmsConnectorProperty, 1); + *prop = (MetaKmsConnectorProperty) { + .connector = connector, + .prop_id = prop_id, + .value = value, + }; + + update->connector_properties = g_list_prepend (update->connector_properties, + prop); +} + +static void +meta_kms_crtc_gamma_free (MetaKmsCrtcGamma *gamma) +{ + g_free (gamma->red); + g_free (gamma->green); + g_free (gamma->blue); + g_free (gamma); +} + +void +meta_kms_update_set_crtc_gamma (MetaKmsUpdate *update, + MetaKmsCrtc *crtc, + int size, + const uint16_t *red, + const uint16_t *green, + const uint16_t *blue) +{ + MetaKmsCrtcGamma *gamma; + + g_assert (!meta_kms_update_is_sealed (update)); + + gamma = g_new0 (MetaKmsCrtcGamma, 1); + *gamma = (MetaKmsCrtcGamma) { + .crtc = crtc, + .size = size, + .red = g_memdup (red, size * sizeof *red), + .green = g_memdup (green, size * sizeof *green), + .blue = g_memdup (blue, size * sizeof *blue), + }; + + update->crtc_gammas = g_list_prepend (update->crtc_gammas, gamma); +} + +void +meta_kms_update_page_flip (MetaKmsUpdate *update, + MetaKmsCrtc *crtc, + const MetaKmsPageFlipFeedback *feedback, + gpointer user_data) +{ + MetaKmsPageFlip *page_flip; + + g_assert (!meta_kms_update_is_sealed (update)); + + page_flip = g_new0 (MetaKmsPageFlip, 1); + *page_flip = (MetaKmsPageFlip) { + .crtc = crtc, + .feedback = feedback, + .user_data = user_data, + }; + + update->page_flips = g_list_prepend (update->page_flips, page_flip); +} + +void +meta_kms_update_custom_page_flip (MetaKmsUpdate *update, + MetaKmsCrtc *crtc, + const MetaKmsPageFlipFeedback *feedback, + gpointer user_data, + MetaKmsCustomPageFlipFunc custom_page_flip_func, + gpointer custom_page_flip_user_data) +{ + MetaKmsPageFlip *page_flip; + + g_assert (!meta_kms_update_is_sealed (update)); + + page_flip = g_new0 (MetaKmsPageFlip, 1); + *page_flip = (MetaKmsPageFlip) { + .crtc = crtc, + .feedback = feedback, + .user_data = user_data, + .custom_page_flip_func = custom_page_flip_func, + .custom_page_flip_user_data = custom_page_flip_user_data, + }; + + update->page_flips = g_list_prepend (update->page_flips, page_flip); +} + +void +meta_kms_plane_assignment_set_plane_property (MetaKmsPlaneAssignment *plane_assignment, + uint32_t prop_id, + uint64_t value) +{ + MetaKmsProperty *plane_prop; + + g_assert (!meta_kms_update_is_sealed (plane_assignment->update)); + + plane_prop = meta_kms_property_new (prop_id, value); + + plane_assignment->plane_properties = + g_list_prepend (plane_assignment->plane_properties, plane_prop); +} + +void +meta_kms_plane_assignment_set_cursor_hotspot (MetaKmsPlaneAssignment *plane_assignment, + int x, + int y) +{ + plane_assignment->cursor_hotspot.is_valid = TRUE; + plane_assignment->cursor_hotspot.x = x; + plane_assignment->cursor_hotspot.y = y; +} + +MetaKmsPlaneAssignment * +meta_kms_update_get_primary_plane_assignment (MetaKmsUpdate *update, + MetaKmsCrtc *crtc) +{ + GList *l; + + for (l = meta_kms_update_get_plane_assignments (update); l; l = l->next) + { + MetaKmsPlaneAssignment *plane_assignment = l->data; + + if (plane_assignment->crtc == crtc) + return plane_assignment; + } + + return NULL; +} + +GList * +meta_kms_update_get_plane_assignments (MetaKmsUpdate *update) +{ + return update->plane_assignments; +} + +GList * +meta_kms_update_get_mode_sets (MetaKmsUpdate *update) +{ + return update->mode_sets; +} + +GList * +meta_kms_update_get_page_flips (MetaKmsUpdate *update) +{ + return update->page_flips; +} + +GList * +meta_kms_update_get_connector_properties (MetaKmsUpdate *update) +{ + return update->connector_properties; +} + +GList * +meta_kms_update_get_crtc_gammas (MetaKmsUpdate *update) +{ + return update->crtc_gammas; +} + +void +meta_kms_update_seal (MetaKmsUpdate *update) +{ + update->is_sealed = TRUE; +} + +gboolean +meta_kms_update_is_sealed (MetaKmsUpdate *update) +{ + return update->is_sealed; +} + +MetaKmsUpdate * +meta_kms_update_new (void) +{ + return g_new0 (MetaKmsUpdate, 1); +} + +void +meta_kms_update_free (MetaKmsUpdate *update) +{ + g_list_free_full (update->plane_assignments, + (GDestroyNotify) meta_kms_plane_assignment_free); + g_list_free_full (update->mode_sets, + (GDestroyNotify) meta_kms_mode_set_free); + g_list_free_full (update->page_flips, g_free); + g_list_free_full (update->connector_properties, g_free); + g_list_free_full (update->crtc_gammas, (GDestroyNotify) meta_kms_crtc_gamma_free); + + g_free (update); +} diff --git a/src/backends/native/meta-kms-update.h b/src/backends/native/meta-kms-update.h new file mode 100644 index 000000000..13dff16dd --- /dev/null +++ b/src/backends/native/meta-kms-update.h @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2018 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_KMS_UPDATE_H +#define META_KMS_UPDATE_H + +#include <glib-object.h> +#include <glib.h> +#include <stdint.h> +#include <xf86drmMode.h> + +#include "backends/meta-monitor-transform.h" +#include "backends/native/meta-kms-types.h" +#include "meta/boxes.h" + +typedef enum _MetaKmsFeedbackResult +{ + META_KMS_FEEDBACK_PASSED, + META_KMS_FEEDBACK_FAILED, +} MetaKmsFeedbackResult; + +typedef enum _MetaKmsAssignPlaneFlag +{ + META_KMS_ASSIGN_PLANE_FLAG_NONE = 0, + META_KMS_ASSIGN_PLANE_FLAG_FB_UNCHANGED = 1 << 0, +} MetaKmsAssignPlaneFlag; + +struct _MetaKmsPageFlipFeedback +{ + void (* flipped) (MetaKmsCrtc *crtc, + unsigned int sequence, + unsigned int tv_sec, + unsigned int tv_usec, + gpointer user_data); + + void (* mode_set_fallback) (MetaKmsCrtc *crtc, + gpointer user_data); + + void (* discarded) (MetaKmsCrtc *crtc, + gpointer user_data, + const GError *error); +}; + +typedef int (* MetaKmsCustomPageFlipFunc) (gpointer custom_page_flip_data, + gpointer user_data); + +typedef struct _MetaKmsPlaneFeedback +{ + MetaKmsPlane *plane; + MetaKmsCrtc *crtc; + GError *error; +} MetaKmsPlaneFeedback; + +void meta_kms_feedback_free (MetaKmsFeedback *feedback); + +MetaKmsFeedbackResult meta_kms_feedback_get_result (MetaKmsFeedback *feedback); + +GList * meta_kms_feedback_get_failed_planes (MetaKmsFeedback *feedback); + +const GError * meta_kms_feedback_get_error (MetaKmsFeedback *feedback); + +MetaKmsUpdate * meta_kms_update_new (void); + +void meta_kms_update_free (MetaKmsUpdate *update); + +void meta_kms_update_mode_set (MetaKmsUpdate *update, + MetaKmsCrtc *crtc, + GList *connectors, + drmModeModeInfo *drm_mode); + +MetaKmsPlaneAssignment * meta_kms_update_assign_plane (MetaKmsUpdate *update, + MetaKmsCrtc *crtc, + MetaKmsPlane *plane, + uint32_t fb_id, + MetaFixed16Rectangle src_rect, + MetaFixed16Rectangle dst_rect, + MetaKmsAssignPlaneFlag flags); + +MetaKmsPlaneAssignment * meta_kms_update_unassign_plane (MetaKmsUpdate *update, + MetaKmsCrtc *crtc, + MetaKmsPlane *plane); + +void meta_kms_update_page_flip (MetaKmsUpdate *update, + MetaKmsCrtc *crtc, + const MetaKmsPageFlipFeedback *feedback, + gpointer user_data); + +void meta_kms_update_custom_page_flip (MetaKmsUpdate *update, + MetaKmsCrtc *crtc, + const MetaKmsPageFlipFeedback *feedback, + gpointer user_data, + MetaKmsCustomPageFlipFunc custom_page_flip_func, + gpointer custom_page_flip_user_data); + +void meta_kms_plane_assignment_set_cursor_hotspot (MetaKmsPlaneAssignment *plane_assignment, + int x, + int y); + +static inline MetaFixed16 +meta_fixed_16_from_int (int16_t d) +{ + return d * 65536; +} + +static inline int16_t +meta_fixed_16_to_int (MetaFixed16 fixed) +{ + return fixed / 65536; +} + +static inline MetaRectangle +meta_fixed_16_rectangle_to_rectangle (MetaFixed16Rectangle fixed_rect) +{ + return (MetaRectangle) { + .x = meta_fixed_16_to_int (fixed_rect.x), + .y = meta_fixed_16_to_int (fixed_rect.y), + .width = meta_fixed_16_to_int (fixed_rect.width), + .height = meta_fixed_16_to_int (fixed_rect.height), + }; +} + +G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaKmsFeedback, meta_kms_feedback_free) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaKmsUpdate, meta_kms_update_free) + +#endif /* META_KMS_UPDATE_H */ diff --git a/src/backends/native/meta-kms-utils.c b/src/backends/native/meta-kms-utils.c new file mode 100644 index 000000000..11df09be8 --- /dev/null +++ b/src/backends/native/meta-kms-utils.c @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2013-2019 Red Hat + * Copyright (c) 2018 DisplayLink (UK) Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "backends/native/meta-kms-utils.h" + +#include <drm_fourcc.h> +#include <glib.h> + +/* added in libdrm 2.4.95 */ +#ifndef DRM_FORMAT_INVALID +#define DRM_FORMAT_INVALID 0 +#endif + +float +meta_calculate_drm_mode_refresh_rate (const drmModeModeInfo *drm_mode) +{ + float refresh = 0.0; + + if (drm_mode->htotal > 0 && drm_mode->vtotal > 0) + { + /* Calculate refresh rate in milliHz first for extra precision. */ + refresh = (drm_mode->clock * 1000000LL) / drm_mode->htotal; + refresh += (drm_mode->vtotal / 2); + refresh /= drm_mode->vtotal; + if (drm_mode->vscan > 1) + refresh /= drm_mode->vscan; + refresh /= 1000.0; + } + return refresh; +} + +/** + * meta_drm_format_to_string: + * @tmp: temporary buffer + * @drm_format: DRM fourcc pixel format + * + * Returns a pointer to a string naming the given pixel format, + * usually a pointer to the temporary buffer but not always. + * Invalid formats may return nonsense names. + * + * When calling this, allocate one MetaDrmFormatBuf on the stack to + * be used as the temporary buffer. + */ +const char * +meta_drm_format_to_string (MetaDrmFormatBuf *tmp, + uint32_t drm_format) +{ + int i; + + if (drm_format == DRM_FORMAT_INVALID) + return "INVALID"; + + G_STATIC_ASSERT (sizeof (tmp->s) == 5); + for (i = 0; i < 4; i++) + { + char c = (drm_format >> (i * 8)) & 0xff; + tmp->s[i] = g_ascii_isgraph (c) ? c : '.'; + } + + tmp->s[i] = 0; + + return tmp->s; +} + diff --git a/src/backends/native/meta-kms-utils.h b/src/backends/native/meta-kms-utils.h new file mode 100644 index 000000000..7a2fdfd79 --- /dev/null +++ b/src/backends/native/meta-kms-utils.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2018 DisplayLink (UK) Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_KMS_UTILS_H +#define META_KMS_UTILS_H + +#include <stddef.h> +#include <stdint.h> +#include <xf86drmMode.h> + +typedef struct _MetaDrmFormatBuf +{ + char s[5]; +} MetaDrmFormatBuf; + +float meta_calculate_drm_mode_refresh_rate (const drmModeModeInfo *drm_mode); + +const char * meta_drm_format_to_string (MetaDrmFormatBuf *tmp, + uint32_t drm_format); + +#endif /* META_KMS_UTILS_H */ diff --git a/src/backends/native/meta-kms.c b/src/backends/native/meta-kms.c new file mode 100644 index 000000000..80ce4e3c2 --- /dev/null +++ b/src/backends/native/meta-kms.c @@ -0,0 +1,634 @@ +/* + * Copyright (C) 2018 Red Hat + * Copyright 2020 DisplayLink (UK) Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "backends/native/meta-kms-private.h" + +#include "backends/native/meta-backend-native.h" +#include "backends/native/meta-kms-device-private.h" +#include "backends/native/meta-kms-impl.h" +#include "backends/native/meta-kms-impl-simple.h" +#include "backends/native/meta-kms-update-private.h" +#include "backends/native/meta-udev.h" +#include "cogl/cogl.h" + +/** + * SECTION:kms + * @short description: KMS abstraction + * @title: KMS abstraction + * + * The KMS abstraction consists of various building blocks for helping out with + * interacting with the various drm API's, enabling users to use a + * transactional API, aiming to hide all interaction with the underlying APIs. + * + * The subsystem defines two separate contexts, the "main" context, and the + * "impl" context. The main context is the context of which mutter as a whole + * runs in. It uses the main GLib main loop and main context and always runs in + * the main thread. + * + * The impl context is where all underlying API is being executed. While in the + * current state, it always runs in the main thread, the aim is to be able to + * execute the impl context in a dedicated thread. + * + * The public facing MetaKms API is always assumed to be executed from the main + * context. + * + * The KMS abstraction consists of the following public components: + * + * #MetaKms: + * + * Main entry point; used by the native backend to create devices, post updates + * etc. + * + * #MetaKmsDevice: + * + * A device (usually /dev/dri/cardN, where N being a number). Used to get KMS + * objects, such as connectors, CRTCs, planes, as well as basic meta data such + * as device path etc. + * + * #MetaKmsCrtc: + * + * Represents a CRTC. It manages a representation of the current CRTC state, + * including current mode, coordinates, possible clones. + * + * #MetaKmsConnector: + * + * Represents a connector, e.g. a display port connection. It also manages a + * representation of the current state, including meta data such as physical + * dimension of the connected, available modes, EDID, tile info etc. It also + * contains helper functions for configuration, as well as methods for adding + * configuration to a transaction (See #MetaKmsUpdate). + * + * #MetaKmsPlane: + * + * Represents a hardware plane. A plane is used to define the content of what + * should be presented on a CRTC. Planes can either be primary planes, used as + * a backdrop for CRTCs, overlay planes, and cursor planes. + * + * #MetaKmsUpdate: + * + * A KMS transaction object, meant to be processed potentially atomically when + * posted. An update consists of plane assignments, mode sets and KMS object + * property entries. The user adds updates to the object, and then posts it via + * MetaKms. It will then be processed by the MetaKms backend (See + * #MetaKmsImpl), potentially atomically. + * + * + * There are also these private objects, without public facing API: + * + * #MetaKmsImpl: + * + * The KMS backend implementation, running in the impl context. #MetaKmsImpl + * itself is an abstract object, with potentially multiple implementations. + * Currently only #MetaKmsImplSimple exists. + * + * #MetaKmsImplSimple: + * + * A KMS backend implementation using the non-atomic drmMode* API. While it's + * interacted with using the transactional API, the #MetaKmsUpdate is processed + * non-atomically. + * + * #MetaKmsImplDevice: + * + * An object linked to a #MetaKmsDevice, but where it is executed in the impl + * context. It takes care of the updating of the various KMS object (CRTC, + * connector, ..) states. + * + * #MetaKmsPageFlip: + * + * A object representing a page flip. It's created when a page flip is queued, + * and contains information necessary to provide feedback to the one requesting + * the page flip. + * + */ + +enum +{ + RESOURCES_CHANGED, + + N_SIGNALS +}; + +static int signals[N_SIGNALS]; + +typedef struct _MetaKmsCallbackData +{ + MetaKmsCallback callback; + gpointer user_data; + GDestroyNotify user_data_destroy; +} MetaKmsCallbackData; + +typedef struct _MetaKmsSimpleImplSource +{ + GSource source; + MetaKms *kms; +} MetaKmsSimpleImplSource; + +typedef struct _MetaKmsFdImplSource +{ + GSource source; + + gpointer fd_tag; + MetaKms *kms; + + MetaKmsImplTaskFunc dispatch; + gpointer user_data; +} MetaKmsFdImplSource; + +struct _MetaKms +{ + GObject parent; + + MetaBackend *backend; + + gulong hotplug_handler_id; + gulong removed_handler_id; + + MetaKmsImpl *impl; + gboolean in_impl_task; + gboolean waiting_for_impl_task; + + GList *devices; + + MetaKmsUpdate *pending_update; + + GList *pending_callbacks; + guint callback_source_id; +}; + +G_DEFINE_TYPE (MetaKms, meta_kms, G_TYPE_OBJECT) + +MetaKmsUpdate * +meta_kms_ensure_pending_update (MetaKms *kms) +{ + if (!kms->pending_update) + kms->pending_update = meta_kms_update_new (); + + return meta_kms_get_pending_update (kms); +} + +MetaKmsUpdate * +meta_kms_get_pending_update (MetaKms *kms) +{ + return kms->pending_update; +} + +static void +meta_kms_predict_states_in_impl (MetaKms *kms, + MetaKmsUpdate *update) +{ + meta_assert_in_kms_impl (kms); + + g_list_foreach (kms->devices, + (GFunc) meta_kms_device_predict_states_in_impl, + update); +} + +static gpointer +meta_kms_process_update_in_impl (MetaKmsImpl *impl, + gpointer user_data, + GError **error) +{ + g_autoptr (MetaKmsUpdate) update = user_data; + MetaKmsFeedback *feedback; + + feedback = meta_kms_impl_process_update (impl, update); + meta_kms_predict_states_in_impl (meta_kms_impl_get_kms (impl), update); + + return feedback; +} + +static MetaKmsFeedback * +meta_kms_post_update_sync (MetaKms *kms, + MetaKmsUpdate *update) +{ + meta_kms_update_seal (update); + + COGL_TRACE_BEGIN_SCOPED (MetaKmsPostUpdateSync, + "KMS (post update)"); + + return meta_kms_run_impl_task_sync (kms, + meta_kms_process_update_in_impl, + update, + NULL); +} + +MetaKmsFeedback * +meta_kms_post_pending_update_sync (MetaKms *kms) +{ + return meta_kms_post_update_sync (kms, + g_steal_pointer (&kms->pending_update)); +} + +static gpointer +meta_kms_discard_pending_page_flips_in_impl (MetaKmsImpl *impl, + gpointer user_data, + GError **error) +{ + meta_kms_impl_discard_pending_page_flips (impl); + return GINT_TO_POINTER (TRUE); +} + +void +meta_kms_discard_pending_page_flips (MetaKms *kms) +{ + meta_kms_run_impl_task_sync (kms, + meta_kms_discard_pending_page_flips_in_impl, + NULL, + NULL); +} + +static void +meta_kms_callback_data_free (MetaKmsCallbackData *callback_data) +{ + if (callback_data->user_data_destroy) + callback_data->user_data_destroy (callback_data->user_data); + g_slice_free (MetaKmsCallbackData, callback_data); +} + +static int +flush_callbacks (MetaKms *kms) +{ + GList *l; + int callback_count = 0; + + meta_assert_not_in_kms_impl (kms); + + for (l = kms->pending_callbacks; l; l = l->next) + { + MetaKmsCallbackData *callback_data = l->data; + + callback_data->callback (kms, callback_data->user_data); + meta_kms_callback_data_free (callback_data); + callback_count++; + } + + g_list_free (kms->pending_callbacks); + kms->pending_callbacks = NULL; + + return callback_count; +} + +static gboolean +callback_idle (gpointer user_data) +{ + MetaKms *kms = user_data; + + flush_callbacks (kms); + + kms->callback_source_id = 0; + return G_SOURCE_REMOVE; +} + +void +meta_kms_queue_callback (MetaKms *kms, + MetaKmsCallback callback, + gpointer user_data, + GDestroyNotify user_data_destroy) +{ + MetaKmsCallbackData *callback_data; + + callback_data = g_slice_new0 (MetaKmsCallbackData); + *callback_data = (MetaKmsCallbackData) { + .callback = callback, + .user_data = user_data, + .user_data_destroy = user_data_destroy, + }; + kms->pending_callbacks = g_list_append (kms->pending_callbacks, + callback_data); + if (!kms->callback_source_id) + kms->callback_source_id = g_idle_add (callback_idle, kms); +} + +int +meta_kms_flush_callbacks (MetaKms *kms) +{ + int callback_count; + + callback_count = flush_callbacks (kms); + g_clear_handle_id (&kms->callback_source_id, g_source_remove); + + return callback_count; +} + +gpointer +meta_kms_run_impl_task_sync (MetaKms *kms, + MetaKmsImplTaskFunc func, + gpointer user_data, + GError **error) +{ + gpointer ret; + + kms->in_impl_task = TRUE; + kms->waiting_for_impl_task = TRUE; + ret = func (kms->impl, user_data, error); + kms->waiting_for_impl_task = FALSE; + kms->in_impl_task = FALSE; + + return ret; +} + +static gboolean +simple_impl_source_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + MetaKmsSimpleImplSource *simple_impl_source = + (MetaKmsSimpleImplSource *) source; + MetaKms *kms = simple_impl_source->kms; + gboolean ret; + + kms->in_impl_task = TRUE; + ret = callback (user_data); + kms->in_impl_task = FALSE; + + return ret; +} + +static GSourceFuncs simple_impl_source_funcs = { + .dispatch = simple_impl_source_dispatch, +}; + +GSource * +meta_kms_add_source_in_impl (MetaKms *kms, + GSourceFunc func, + gpointer user_data, + GDestroyNotify user_data_destroy) +{ + GSource *source; + MetaKmsSimpleImplSource *simple_impl_source; + + meta_assert_in_kms_impl (kms); + + source = g_source_new (&simple_impl_source_funcs, + sizeof (MetaKmsSimpleImplSource)); + simple_impl_source = (MetaKmsSimpleImplSource *) source; + simple_impl_source->kms = kms; + + g_source_set_callback (source, func, user_data, user_data_destroy); + g_source_set_ready_time (source, 0); + g_source_attach (source, g_main_context_get_thread_default ()); + + return source; +} + +static gboolean +meta_kms_fd_impl_source_check (GSource *source) +{ + MetaKmsFdImplSource *fd_impl_source = (MetaKmsFdImplSource *) source; + + return g_source_query_unix_fd (source, fd_impl_source->fd_tag) & G_IO_IN; +} + +static gboolean +meta_kms_fd_impl_source_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + MetaKmsFdImplSource *fd_impl_source = (MetaKmsFdImplSource *) source; + MetaKms *kms = fd_impl_source->kms; + gpointer ret; + GError *error = NULL; + + kms->in_impl_task = TRUE; + ret = fd_impl_source->dispatch (kms->impl, + fd_impl_source->user_data, + &error); + kms->in_impl_task = FALSE; + + if (!GPOINTER_TO_INT (ret)) + { + g_warning ("Failed to dispatch fd source: %s", error->message); + g_error_free (error); + } + + return G_SOURCE_CONTINUE; +} + +static GSourceFuncs fd_impl_source_funcs = { + NULL, + meta_kms_fd_impl_source_check, + meta_kms_fd_impl_source_dispatch +}; + +GSource * +meta_kms_register_fd_in_impl (MetaKms *kms, + int fd, + MetaKmsImplTaskFunc dispatch, + gpointer user_data) +{ + GSource *source; + MetaKmsFdImplSource *fd_impl_source; + + meta_assert_in_kms_impl (kms); + + source = g_source_new (&fd_impl_source_funcs, sizeof (MetaKmsFdImplSource)); + fd_impl_source = (MetaKmsFdImplSource *) source; + fd_impl_source->dispatch = dispatch; + fd_impl_source->user_data = user_data; + fd_impl_source->kms = kms; + fd_impl_source->fd_tag = g_source_add_unix_fd (source, fd, + G_IO_IN | G_IO_ERR); + + g_source_attach (source, g_main_context_get_thread_default ()); + + return source; +} + +gboolean +meta_kms_in_impl_task (MetaKms *kms) +{ + return kms->in_impl_task; +} + +gboolean +meta_kms_is_waiting_for_impl_task (MetaKms *kms) +{ + return kms->waiting_for_impl_task; +} + +static void +meta_kms_update_states_in_impl (MetaKms *kms) +{ + COGL_TRACE_BEGIN_SCOPED (MetaKmsUpdateStates, + "KMS (update states)"); + + meta_assert_in_kms_impl (kms); + + g_list_foreach (kms->devices, + (GFunc) meta_kms_device_update_states_in_impl, + NULL); +} + +static gpointer +update_states_in_impl (MetaKmsImpl *impl, + gpointer user_data, + GError **error) +{ + MetaKms *kms = meta_kms_impl_get_kms (impl);; + + meta_kms_update_states_in_impl (kms); + + return GINT_TO_POINTER (TRUE); +} + +static gboolean +meta_kms_update_states_sync (MetaKms *kms, + GError **error) +{ + gpointer ret; + + ret = meta_kms_run_impl_task_sync (kms, update_states_in_impl, NULL, error); + return GPOINTER_TO_INT (ret); +} + +static void +handle_hotplug_event (MetaKms *kms) +{ + g_autoptr (GError) error = NULL; + + if (!meta_kms_update_states_sync (kms, &error)) + g_warning ("Updating KMS state failed: %s", error->message); + + g_signal_emit (kms, signals[RESOURCES_CHANGED], 0); +} + +static void +on_udev_hotplug (MetaUdev *udev, + MetaKms *kms) +{ + handle_hotplug_event (kms); +} + +static void +on_udev_device_removed (MetaUdev *udev, + GUdevDevice *device, + MetaKms *kms) +{ + handle_hotplug_event (kms); +} + +MetaBackend * +meta_kms_get_backend (MetaKms *kms) +{ + return kms->backend; +} + +static gpointer +notify_device_created_in_impl (MetaKmsImpl *impl, + gpointer user_data, + GError **error) +{ + MetaKmsDevice *device = user_data; + + meta_kms_impl_notify_device_created (impl, device); + + return GINT_TO_POINTER (TRUE); +} + +MetaKmsDevice * +meta_kms_create_device (MetaKms *kms, + const char *path, + MetaKmsDeviceFlag flags, + GError **error) +{ + MetaKmsDevice *device; + + device = meta_kms_device_new (kms, path, flags, error); + if (!device) + return NULL; + + meta_kms_run_impl_task_sync (kms, notify_device_created_in_impl, + device, NULL); + + kms->devices = g_list_append (kms->devices, device); + + return device; +} + +MetaKms * +meta_kms_new (MetaBackend *backend, + GError **error) +{ + MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend); + MetaUdev *udev = meta_backend_native_get_udev (backend_native); + MetaKms *kms; + + kms = g_object_new (META_TYPE_KMS, NULL); + kms->backend = backend; + kms->impl = META_KMS_IMPL (meta_kms_impl_simple_new (kms, error)); + if (!kms->impl) + { + g_object_unref (kms); + return NULL; + } + + kms->hotplug_handler_id = + g_signal_connect (udev, "hotplug", G_CALLBACK (on_udev_hotplug), kms); + kms->removed_handler_id = + g_signal_connect (udev, "device-removed", + G_CALLBACK (on_udev_device_removed), kms); + + return kms; +} + +static void +meta_kms_finalize (GObject *object) +{ + MetaKms *kms = META_KMS (object); + MetaBackendNative *backend_native = META_BACKEND_NATIVE (kms->backend); + MetaUdev *udev = meta_backend_native_get_udev (backend_native); + GList *l; + + for (l = kms->pending_callbacks; l; l = l->next) + meta_kms_callback_data_free (l->data); + g_list_free (kms->pending_callbacks); + + g_clear_handle_id (&kms->callback_source_id, g_source_remove); + + g_list_free_full (kms->devices, g_object_unref); + + g_clear_signal_handler (&kms->hotplug_handler_id, udev); + g_clear_signal_handler (&kms->removed_handler_id, udev); + + G_OBJECT_CLASS (meta_kms_parent_class)->finalize (object); +} + +static void +meta_kms_init (MetaKms *kms) +{ +} + +static void +meta_kms_class_init (MetaKmsClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_kms_finalize; + + signals[RESOURCES_CHANGED] = + g_signal_new ("resources-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); +} diff --git a/src/backends/native/meta-kms.h b/src/backends/native/meta-kms.h new file mode 100644 index 000000000..ab25b70bd --- /dev/null +++ b/src/backends/native/meta-kms.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2018 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_KMS_H +#define META_KMS_H + +#include <glib-object.h> + +#include "backends/meta-backend-private.h" +#include "backends/native/meta-kms-types.h" + +#define META_TYPE_KMS (meta_kms_get_type ()) +G_DECLARE_FINAL_TYPE (MetaKms, meta_kms, META, KMS, GObject) + +MetaKmsUpdate * meta_kms_ensure_pending_update (MetaKms *kms); + +MetaKmsUpdate * meta_kms_get_pending_update (MetaKms *kms); + +MetaKmsFeedback * meta_kms_post_pending_update_sync (MetaKms *kms); + +void meta_kms_discard_pending_page_flips (MetaKms *kms); + +MetaBackend * meta_kms_get_backend (MetaKms *kms); + +MetaKmsDevice * meta_kms_create_device (MetaKms *kms, + const char *path, + MetaKmsDeviceFlag flags, + GError **error); + +MetaKms * meta_kms_new (MetaBackend *backend, + GError **error); + +#endif /* META_KMS_H */ diff --git a/src/backends/native/meta-launcher.c b/src/backends/native/meta-launcher.c new file mode 100644 index 000000000..61fe19be0 --- /dev/null +++ b/src/backends/native/meta-launcher.c @@ -0,0 +1,572 @@ +/* + * Copyright (C) 2013 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "backends/native/meta-launcher.h" + +#include <gio/gunixfdlist.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/sysmacros.h> +#include <malloc.h> +#include <fcntl.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <systemd/sd-login.h> +#include <gudev/gudev.h> + +#include "backends/meta-backend-private.h" +#include "backends/native/dbus-utils.h" +#include "backends/native/meta-backend-native.h" +#include "backends/native/meta-clutter-backend-native.h" +#include "backends/native/meta-cursor-renderer-native.h" +#include "backends/native/meta-renderer-native.h" +#include "backends/native/meta-seat-native.h" +#include "clutter/clutter.h" + +#include "meta-dbus-login1.h" + +struct _MetaLauncher +{ + Login1Session *session_proxy; + Login1Seat *seat_proxy; + char *seat_id; + + GHashTable *sysfs_fds; + gboolean session_active; +}; + +const char * +meta_launcher_get_seat_id (MetaLauncher *launcher) +{ + return launcher->seat_id; +} + +static gboolean +find_systemd_session (gchar **session_id, + GError **error) +{ + const gchar * const graphical_session_types[] = { "wayland", "x11", "mir", NULL }; + const gchar * const active_states[] = { "active", "online", NULL }; + g_autofree gchar *class = NULL; + g_autofree gchar *local_session_id = NULL; + g_autofree gchar *type = NULL; + g_autofree gchar *state = NULL; + g_auto (GStrv) sessions = NULL; + int n_sessions; + int saved_errno; + + g_assert (session_id != NULL); + g_assert (error == NULL || *error == NULL); + + /* if we are in a logind session, we can trust that value, so use it. This + * happens for example when you run mutter directly from a VT but when + * systemd starts us we will not be in a logind session. */ + saved_errno = sd_pid_get_session (0, &local_session_id); + if (saved_errno < 0) + { + if (saved_errno != -ENODATA) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_NOT_FOUND, + "Failed to get session by pid for user %d (%s)", + getuid (), + g_strerror (-saved_errno)); + return FALSE; + } + } + else + { + *session_id = g_steal_pointer (&local_session_id); + return TRUE; + } + + saved_errno = sd_uid_get_display (getuid (), &local_session_id); + if (saved_errno < 0) + { + /* no session, maybe there's a greeter session */ + if (saved_errno == -ENODATA) + { + n_sessions = sd_uid_get_sessions (getuid (), 1, &sessions); + if (n_sessions < 0) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_NOT_FOUND, + "Failed to get all sessions for user %d (%m)", + getuid ()); + return FALSE; + } + + if (n_sessions == 0) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_NOT_FOUND, + "User %d has no sessions", + getuid ()); + return FALSE; + } + + for (int i = 0; i < n_sessions; ++i) + { + saved_errno = sd_session_get_class (sessions[i], &class); + if (saved_errno < 0) + { + g_warning ("Couldn't get class for session '%d': %s", + i, + g_strerror (-saved_errno)); + continue; + } + + if (g_strcmp0 (class, "greeter") == 0) + { + local_session_id = g_strdup (sessions[i]); + break; + } + } + + if (!local_session_id) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_NOT_FOUND, + "Couldn't find a session or a greeter session for user %d", + getuid ()); + return FALSE; + } + } + else + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_NOT_FOUND, + "Couldn't get display for user %d: %s", + getuid (), + g_strerror (-saved_errno)); + return FALSE; + } + } + + /* sd_uid_get_display will return any session if there is no graphical + * one, so let's check it really is graphical. */ + saved_errno = sd_session_get_type (local_session_id, &type); + if (saved_errno < 0) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_NOT_FOUND, + "Couldn't get type for session '%s': %s", + local_session_id, + g_strerror (-saved_errno)); + return FALSE; + } + + if (!g_strv_contains (graphical_session_types, type)) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_NOT_FOUND, + "Session '%s' is not a graphical session (type: '%s')", + local_session_id, + type); + return FALSE; + } + + /* and display sessions can be 'closing' if they are logged out but + * some processes are lingering; we shouldn't consider these */ + saved_errno = sd_session_get_state (local_session_id, &state); + if (saved_errno < 0) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_NOT_FOUND, + "Couldn't get state for session '%s': %s", + local_session_id, + g_strerror (-saved_errno)); + return FALSE; + } + + if (!g_strv_contains (active_states, state)) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_NOT_FOUND, + "Session '%s' is not active", + local_session_id); + return FALSE; + } + + *session_id = g_steal_pointer (&local_session_id); + + return TRUE; +} + +static Login1Session * +get_session_proxy (GCancellable *cancellable, + GError **error) +{ + g_autofree char *proxy_path = NULL; + g_autofree char *session_id = NULL; + g_autoptr (GError) local_error = NULL; + Login1Session *session_proxy; + + if (!find_systemd_session (&session_id, &local_error)) + { + g_propagate_prefixed_error (error, + g_steal_pointer (&local_error), + "Could not get session ID: "); + return NULL; + } + + proxy_path = get_escaped_dbus_path ("/org/freedesktop/login1/session", session_id); + + session_proxy = login1_session_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + "org.freedesktop.login1", + proxy_path, + cancellable, error); + if (!session_proxy) + g_prefix_error(error, "Could not get session proxy: "); + + return session_proxy; +} + +static Login1Seat * +get_seat_proxy (gchar *seat_id, + GCancellable *cancellable, + GError **error) +{ + g_autofree char *seat_proxy_path = get_escaped_dbus_path ("/org/freedesktop/login1/seat", seat_id); + Login1Seat *seat = login1_seat_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + "org.freedesktop.login1", + seat_proxy_path, + cancellable, error); + if (!seat) + g_prefix_error(error, "Could not get seat proxy: "); + + return seat; +} + +static gboolean +take_device (Login1Session *session_proxy, + int dev_major, + int dev_minor, + int *out_fd, + GCancellable *cancellable, + GError **error) +{ + g_autoptr (GVariant) fd_variant = NULL; + g_autoptr (GUnixFDList) fd_list = NULL; + int fd = -1; + + if (!login1_session_call_take_device_sync (session_proxy, + dev_major, + dev_minor, + NULL, + &fd_variant, + NULL, /* paused */ + &fd_list, + cancellable, + error)) + return FALSE; + + fd = g_unix_fd_list_get (fd_list, g_variant_get_handle (fd_variant), error); + if (fd == -1) + return FALSE; + + *out_fd = fd; + return TRUE; +} + +static gboolean +get_device_info_from_path (const char *path, + int *out_major, + int *out_minor) +{ + int r; + struct stat st; + + r = stat (path, &st); + if (r < 0 || !S_ISCHR (st.st_mode)) + return FALSE; + + *out_major = major (st.st_rdev); + *out_minor = minor (st.st_rdev); + return TRUE; +} + +static gboolean +get_device_info_from_fd (int fd, + int *out_major, + int *out_minor) +{ + int r; + struct stat st; + + r = fstat (fd, &st); + if (r < 0 || !S_ISCHR (st.st_mode)) + return FALSE; + + *out_major = major (st.st_rdev); + *out_minor = minor (st.st_rdev); + return TRUE; +} + +int +meta_launcher_open_restricted (MetaLauncher *launcher, + const char *path, + GError **error) +{ + int fd; + int major, minor; + + if (!get_device_info_from_path (path, &major, &minor)) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_NOT_FOUND, + "Could not get device info for path %s: %m", path); + return -1; + } + + if (!take_device (launcher->session_proxy, major, minor, &fd, NULL, error)) + return -1; + + return fd; +} + +void +meta_launcher_close_restricted (MetaLauncher *launcher, + int fd) +{ + int major, minor; + GError *error = NULL; + + if (!get_device_info_from_fd (fd, &major, &minor)) + { + g_warning ("Could not get device info for fd %d: %m", fd); + goto out; + } + + if (!login1_session_call_release_device_sync (launcher->session_proxy, + major, minor, + NULL, &error)) + { + g_warning ("Could not release device (%d,%d): %s", + major, minor, error->message); + } + +out: + close (fd); +} + +static int +on_evdev_device_open (const char *path, + int flags, + gpointer user_data, + GError **error) +{ + MetaLauncher *self = user_data; + + /* Allow readonly access to sysfs */ + if (g_str_has_prefix (path, "/sys/")) + { + int fd; + + do + { + fd = open (path, flags); + } + while (fd < 0 && errno == EINTR); + + if (fd < 0) + { + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (errno), + "Could not open /sys file: %s: %m", path); + return -1; + } + + g_hash_table_add (self->sysfs_fds, GINT_TO_POINTER (fd)); + return fd; + } + + return meta_launcher_open_restricted (self, path, error); +} + +static void +on_evdev_device_close (int fd, + gpointer user_data) +{ + MetaLauncher *self = user_data; + + if (g_hash_table_lookup (self->sysfs_fds, GINT_TO_POINTER (fd))) + { + /* /sys/ paths just need close() here */ + g_hash_table_remove (self->sysfs_fds, GINT_TO_POINTER (fd)); + close (fd); + return; + } + + meta_launcher_close_restricted (self, fd); +} + +static void +sync_active (MetaLauncher *self) +{ + MetaBackend *backend = meta_get_backend (); + MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend); + gboolean active = login1_session_get_active (LOGIN1_SESSION (self->session_proxy)); + + if (active == self->session_active) + return; + + self->session_active = active; + + if (active) + meta_backend_native_resume (backend_native); + else + meta_backend_native_pause (backend_native); +} + +static void +on_active_changed (Login1Session *session, + GParamSpec *pspec, + gpointer user_data) +{ + MetaLauncher *self = user_data; + sync_active (self); +} + +static gchar * +get_seat_id (GError **error) +{ + g_autoptr (GError) local_error = NULL; + g_autofree char *session_id = NULL; + char *seat_id = NULL; + int r; + + if (!find_systemd_session (&session_id, &local_error)) + { + g_propagate_prefixed_error (error, + g_steal_pointer (&local_error), + "Could not get session ID: "); + return NULL; + } + + r = sd_session_get_seat (session_id, &seat_id); + if (r < 0) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_NOT_FOUND, + "Could not get seat for session: %s", g_strerror (-r)); + return NULL; + } + + return seat_id; +} + +MetaLauncher * +meta_launcher_new (GError **error) +{ + MetaLauncher *self = NULL; + g_autoptr (Login1Session) session_proxy = NULL; + g_autoptr (Login1Seat) seat_proxy = NULL; + g_autofree char *seat_id = NULL; + gboolean have_control = FALSE; + + session_proxy = get_session_proxy (NULL, error); + if (!session_proxy) + goto fail; + + if (!login1_session_call_take_control_sync (session_proxy, FALSE, NULL, error)) + { + g_prefix_error (error, "Could not take control: "); + goto fail; + } + + have_control = TRUE; + + seat_id = get_seat_id (error); + if (!seat_id) + goto fail; + + seat_proxy = get_seat_proxy (seat_id, NULL, error); + if (!seat_proxy) + goto fail; + + self = g_slice_new0 (MetaLauncher); + self->session_proxy = g_object_ref (session_proxy); + self->seat_proxy = g_object_ref (seat_proxy); + self->seat_id = g_steal_pointer (&seat_id); + self->sysfs_fds = g_hash_table_new (NULL, NULL); + self->session_active = TRUE; + + meta_clutter_backend_native_set_seat_id (self->seat_id); + + meta_seat_native_set_device_callbacks (on_evdev_device_open, + on_evdev_device_close, + self); + + g_signal_connect (self->session_proxy, "notify::active", G_CALLBACK (on_active_changed), self); + + return self; + + fail: + if (have_control) + login1_session_call_release_control_sync (session_proxy, NULL, NULL); + return NULL; +} + +void +meta_launcher_free (MetaLauncher *self) +{ + g_free (self->seat_id); + g_object_unref (self->seat_proxy); + g_object_unref (self->session_proxy); + g_hash_table_destroy (self->sysfs_fds); + g_slice_free (MetaLauncher, self); +} + +gboolean +meta_launcher_activate_session (MetaLauncher *launcher, + GError **error) +{ + if (!login1_session_call_activate_sync (launcher->session_proxy, NULL, error)) + return FALSE; + + sync_active (launcher); + return TRUE; +} + +gboolean +meta_launcher_activate_vt (MetaLauncher *launcher, + signed char vt, + GError **error) +{ + return login1_seat_call_switch_to_sync (launcher->seat_proxy, vt, NULL, error); +} diff --git a/src/backends/native/meta-launcher.h b/src/backends/native/meta-launcher.h new file mode 100644 index 000000000..f74e154d5 --- /dev/null +++ b/src/backends/native/meta-launcher.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2013 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_LAUNCHER_H +#define META_LAUNCHER_H + +#include <glib-object.h> + +typedef struct _MetaLauncher MetaLauncher; + +MetaLauncher *meta_launcher_new (GError **error); +void meta_launcher_free (MetaLauncher *self); + +gboolean meta_launcher_activate_session (MetaLauncher *self, + GError **error); + +gboolean meta_launcher_activate_vt (MetaLauncher *self, + signed char vt, + GError **error); + +const char * meta_launcher_get_seat_id (MetaLauncher *launcher); + +int meta_launcher_open_restricted (MetaLauncher *launcher, + const char *path, + GError **error); + +void meta_launcher_close_restricted (MetaLauncher *launcher, + int fd); + + +#endif /* META_LAUNCHER_H */ diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c new file mode 100644 index 000000000..b7d46818b --- /dev/null +++ b/src/backends/native/meta-monitor-manager-kms.c @@ -0,0 +1,668 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2013 Red Hat Inc. + * Copyright (C) 2018 DisplayLink (UK) Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Giovanni Campagna <gcampagn@redhat.com> + */ + +/** + * SECTION:meta-monitor-manager-kms + * @title: MetaMonitorManagerKms + * @short_description: A subclass of #MetaMonitorManager using Linux DRM + * + * #MetaMonitorManagerKms is a subclass of #MetaMonitorManager which + * implements its functionality "natively": it uses the appropriate + * functions of the Linux DRM kernel module and using a udev client. + * + * See also #MetaMonitorManagerXrandr for an implementation using XRandR. + */ + +#include "config.h" + +#include "backends/native/meta-monitor-manager-kms.h" + +#include <drm.h> +#include <errno.h> +#include <gudev/gudev.h> +#include <stdlib.h> +#include <string.h> +#include <sys/ioctl.h> +#include <sys/mman.h> +#include <unistd.h> + +#include "backends/meta-backend-private.h" +#include "backends/meta-crtc.h" +#include "backends/meta-monitor-config-manager.h" +#include "backends/meta-output.h" +#include "backends/native/meta-backend-native.h" +#include "backends/native/meta-crtc-kms.h" +#include "backends/native/meta-gpu-kms.h" +#include "backends/native/meta-kms-update.h" +#include "backends/native/meta-kms.h" +#include "backends/native/meta-launcher.h" +#include "backends/native/meta-output-kms.h" +#include "backends/native/meta-renderer-native.h" +#include "clutter/clutter.h" +#include "meta/main.h" +#include "meta/meta-x11-errors.h" + +typedef struct +{ + GSource source; + + gpointer fd_tag; + MetaMonitorManagerKms *manager_kms; +} MetaKmsSource; + +struct _MetaMonitorManagerKms +{ + MetaMonitorManager parent_instance; + + gulong kms_resources_changed_handler_id; +}; + +struct _MetaMonitorManagerKmsClass +{ + MetaMonitorManagerClass parent_class; +}; + +static void +initable_iface_init (GInitableIface *initable_iface); + +G_DEFINE_TYPE_WITH_CODE (MetaMonitorManagerKms, meta_monitor_manager_kms, + META_TYPE_MONITOR_MANAGER, + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + initable_iface_init)) + +static GBytes * +meta_monitor_manager_kms_read_edid (MetaMonitorManager *manager, + MetaOutput *output) +{ + return meta_output_kms_read_edid (output); +} + +static void +meta_monitor_manager_kms_read_current_state (MetaMonitorManager *manager) +{ + MetaMonitorManagerClass *parent_class = + META_MONITOR_MANAGER_CLASS (meta_monitor_manager_kms_parent_class); + MetaPowerSave power_save_mode; + + power_save_mode = meta_monitor_manager_get_power_save_mode (manager); + if (power_save_mode != META_POWER_SAVE_ON) + meta_monitor_manager_power_save_mode_changed (manager, + META_POWER_SAVE_ON); + + parent_class->read_current_state (manager); +} + +static void +meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager, + MetaPowerSave mode) +{ + MetaBackend *backend = meta_monitor_manager_get_backend (manager); + MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend); + MetaKms *kms = meta_backend_native_get_kms (backend_native); + MetaKmsUpdate *kms_update; + uint64_t state; + GList *l; + g_autoptr (MetaKmsFeedback) kms_feedback = NULL; + + switch (mode) { + case META_POWER_SAVE_ON: + state = DRM_MODE_DPMS_ON; + break; + case META_POWER_SAVE_STANDBY: + state = DRM_MODE_DPMS_STANDBY; + break; + case META_POWER_SAVE_SUSPEND: + state = DRM_MODE_DPMS_SUSPEND; + break; + case META_POWER_SAVE_OFF: + state = DRM_MODE_DPMS_OFF; + break; + default: + return; + } + + kms_update = meta_kms_ensure_pending_update (kms); + for (l = meta_backend_get_gpus (backend); l; l = l->next) + { + MetaGpuKms *gpu_kms = l->data; + + meta_gpu_kms_set_power_save_mode (gpu_kms, state, kms_update); + } + + kms_feedback = meta_kms_post_pending_update_sync (kms); + if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED) + { + g_warning ("Failed to set DPMS: %s", + meta_kms_feedback_get_error (kms_feedback)->message); + } +} + +static void +meta_monitor_manager_kms_ensure_initial_config (MetaMonitorManager *manager) +{ + MetaMonitorsConfig *config; + + config = meta_monitor_manager_ensure_configured (manager); + + meta_monitor_manager_update_logical_state (manager, config); +} + +static void +apply_crtc_assignments (MetaMonitorManager *manager, + MetaCrtcInfo **crtcs, + unsigned int n_crtcs, + MetaOutputInfo **outputs, + unsigned int n_outputs) +{ + MetaBackend *backend = meta_monitor_manager_get_backend (manager); + unsigned i; + GList *gpus; + GList *l; + + for (i = 0; i < n_crtcs; i++) + { + MetaCrtcInfo *crtc_info = crtcs[i]; + MetaCrtc *crtc = crtc_info->crtc; + + crtc->is_dirty = TRUE; + + if (crtc_info->mode == NULL) + { + meta_crtc_unset_config (crtc); + } + else + { + unsigned int j; + + meta_crtc_set_config (crtc, + &crtc_info->layout, + crtc_info->mode, + crtc_info->transform); + + for (j = 0; j < crtc_info->outputs->len; j++) + { + MetaOutput *output = g_ptr_array_index (crtc_info->outputs, j); + + output->is_dirty = TRUE; + meta_output_assign_crtc (output, crtc); + } + } + } + /* Disable CRTCs not mentioned in the list (they have is_dirty == FALSE, + because they weren't seen in the first loop) */ + gpus = meta_backend_get_gpus (backend); + for (l = gpus; l; l = l->next) + { + MetaGpu *gpu = l->data; + GList *k; + + for (k = meta_gpu_get_crtcs (gpu); k; k = k->next) + { + MetaCrtc *crtc = k->data; + + if (crtc->is_dirty) + { + crtc->is_dirty = FALSE; + continue; + } + + meta_crtc_unset_config (crtc); + } + } + + for (i = 0; i < n_outputs; i++) + { + MetaOutputInfo *output_info = outputs[i]; + MetaOutput *output = output_info->output; + + output->is_primary = output_info->is_primary; + output->is_presentation = output_info->is_presentation; + output->is_underscanning = output_info->is_underscanning; + } + + /* Disable outputs not mentioned in the list */ + for (l = gpus; l; l = l->next) + { + MetaGpu *gpu = l->data; + GList *k; + + for (k = meta_gpu_get_outputs (gpu); k; k = k->next) + { + MetaOutput *output = k->data; + + if (output->is_dirty) + { + output->is_dirty = FALSE; + continue; + } + + meta_output_unassign_crtc (output); + output->is_primary = FALSE; + } + } +} + +static void +update_screen_size (MetaMonitorManager *manager, + MetaMonitorsConfig *config) +{ + GList *l; + int screen_width = 0; + int screen_height = 0; + + for (l = config->logical_monitor_configs; l; l = l->next) + { + MetaLogicalMonitorConfig *logical_monitor_config = l->data; + int right_edge; + int bottom_edge; + + right_edge = (logical_monitor_config->layout.width + + logical_monitor_config->layout.x); + if (right_edge > screen_width) + screen_width = right_edge; + + bottom_edge = (logical_monitor_config->layout.height + + logical_monitor_config->layout.y); + if (bottom_edge > screen_height) + screen_height = bottom_edge; + } + + manager->screen_width = screen_width; + manager->screen_height = screen_height; +} + +static gboolean +meta_monitor_manager_kms_apply_monitors_config (MetaMonitorManager *manager, + MetaMonitorsConfig *config, + MetaMonitorsConfigMethod method, + GError **error) +{ + GPtrArray *crtc_infos; + GPtrArray *output_infos; + + if (!config) + { + if (!manager->in_init) + { + MetaBackend *backend = meta_get_backend (); + MetaRenderer *renderer = meta_backend_get_renderer (backend); + + meta_renderer_native_reset_modes (META_RENDERER_NATIVE (renderer)); + } + + manager->screen_width = META_MONITOR_MANAGER_MIN_SCREEN_WIDTH; + manager->screen_height = META_MONITOR_MANAGER_MIN_SCREEN_HEIGHT; + meta_monitor_manager_rebuild (manager, NULL); + return TRUE; + } + + if (!meta_monitor_config_manager_assign (manager, config, + &crtc_infos, &output_infos, + error)) + return FALSE; + + if (method == META_MONITORS_CONFIG_METHOD_VERIFY) + { + g_ptr_array_free (crtc_infos, TRUE); + g_ptr_array_free (output_infos, TRUE); + return TRUE; + } + + apply_crtc_assignments (manager, + (MetaCrtcInfo **) crtc_infos->pdata, + crtc_infos->len, + (MetaOutputInfo **) output_infos->pdata, + output_infos->len); + + g_ptr_array_free (crtc_infos, TRUE); + g_ptr_array_free (output_infos, TRUE); + + update_screen_size (manager, config); + meta_monitor_manager_rebuild (manager, config); + + return TRUE; +} + +static void +meta_monitor_manager_kms_get_crtc_gamma (MetaMonitorManager *manager, + MetaCrtc *crtc, + gsize *size, + unsigned short **red, + unsigned short **green, + unsigned short **blue) +{ + MetaKmsCrtc *kms_crtc; + const MetaKmsCrtcState *crtc_state; + + kms_crtc = meta_crtc_kms_get_kms_crtc (crtc); + crtc_state = meta_kms_crtc_get_current_state (kms_crtc); + + *size = crtc_state->gamma.size; + *red = g_memdup (crtc_state->gamma.red, *size * sizeof **red); + *green = g_memdup (crtc_state->gamma.green, *size * sizeof **green); + *blue = g_memdup (crtc_state->gamma.blue, *size * sizeof **blue); +} + +static char * +generate_gamma_ramp_string (size_t size, + unsigned short *red, + unsigned short *green, + unsigned short *blue) +{ + GString *string; + int color; + + string = g_string_new ("["); + for (color = 0; color < 3; color++) + { + unsigned short **color_ptr; + char color_char; + size_t i; + + switch (color) + { + case 0: + color_ptr = &red; + color_char = 'r'; + break; + case 1: + color_ptr = &green; + color_char = 'g'; + break; + case 2: + color_ptr = &blue; + color_char = 'b'; + break; + } + + g_string_append_printf (string, " %c: ", color_char); + for (i = 0; i < MIN (4, size); i++) + { + int j; + + if (size > 4) + { + if (i == 2) + g_string_append (string, ",..."); + + if (i >= 2) + j = i + (size - 4); + else + j = i; + } + else + { + j = i; + } + g_string_append_printf (string, "%s%hu", + j == 0 ? "" : ",", + (*color_ptr)[i]); + } + } + + g_string_append (string, " ]"); + + return g_string_free (string, FALSE); +} + +static void +meta_monitor_manager_kms_set_crtc_gamma (MetaMonitorManager *manager, + MetaCrtc *crtc, + gsize size, + unsigned short *red, + unsigned short *green, + unsigned short *blue) +{ + MetaBackend *backend = meta_monitor_manager_get_backend (manager); + MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend); + MetaKms *kms = meta_backend_native_get_kms (backend_native); + MetaKmsCrtc *kms_crtc; + g_autofree char *gamma_ramp_string = NULL; + MetaKmsUpdate *kms_update; + g_autoptr (MetaKmsFeedback) kms_feedback = NULL; + + gamma_ramp_string = generate_gamma_ramp_string (size, red, green, blue); + g_debug ("Setting CRTC (%ld) gamma to %s", crtc->crtc_id, gamma_ramp_string); + + kms_update = meta_kms_ensure_pending_update (kms); + + kms_crtc = meta_crtc_kms_get_kms_crtc (crtc); + meta_kms_crtc_set_gamma (kms_crtc, kms_update, + size, red, green, blue); + + kms_feedback = meta_kms_post_pending_update_sync (kms); + if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED) + { + g_warning ("Failed to set CRTC gamma: %s", + meta_kms_feedback_get_error (kms_feedback)->message); + } +} + +static void +handle_hotplug_event (MetaMonitorManager *manager) +{ + meta_monitor_manager_read_current_state (manager); + meta_monitor_manager_on_hotplug (manager); +} + +static void +on_kms_resources_changed (MetaKms *kms, + MetaMonitorManager *manager) +{ + handle_hotplug_event (manager); +} + +static void +meta_monitor_manager_kms_connect_hotplug_handler (MetaMonitorManagerKms *manager_kms) +{ + MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_kms); + MetaBackend *backend = meta_monitor_manager_get_backend (manager); + MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend); + MetaKms *kms = meta_backend_native_get_kms (backend_native); + + manager_kms->kms_resources_changed_handler_id = + g_signal_connect (kms, "resources-changed", + G_CALLBACK (on_kms_resources_changed), manager); +} + +static void +meta_monitor_manager_kms_disconnect_hotplug_handler (MetaMonitorManagerKms *manager_kms) +{ + MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_kms); + MetaBackend *backend = meta_monitor_manager_get_backend (manager); + MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend); + MetaKms *kms = meta_backend_native_get_kms (backend_native); + + g_clear_signal_handler (&manager_kms->kms_resources_changed_handler_id, kms); +} + +void +meta_monitor_manager_kms_pause (MetaMonitorManagerKms *manager_kms) +{ + meta_monitor_manager_kms_disconnect_hotplug_handler (manager_kms); +} + +void +meta_monitor_manager_kms_resume (MetaMonitorManagerKms *manager_kms) +{ + meta_monitor_manager_kms_connect_hotplug_handler (manager_kms); + handle_hotplug_event (META_MONITOR_MANAGER (manager_kms)); +} + +static gboolean +meta_monitor_manager_kms_is_transform_handled (MetaMonitorManager *manager, + MetaCrtc *crtc, + MetaMonitorTransform transform) +{ + return meta_crtc_kms_is_transform_handled (crtc, transform); +} + +static MetaMonitorScalesConstraint +get_monitor_scale_constraints_per_layout_mode (MetaLogicalMonitorLayoutMode layout_mode) +{ + MetaMonitorScalesConstraint constraints = + META_MONITOR_SCALES_CONSTRAINT_NONE; + + switch (layout_mode) + { + case META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL: + case META_LOGICAL_MONITOR_LAYOUT_MODE_GLOBAL_UI_LOGICAL: + break; + case META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL: + constraints |= META_MONITOR_SCALES_CONSTRAINT_NO_FRAC; + break; + } + + return constraints; +} + +static float +meta_monitor_manager_kms_calculate_monitor_mode_scale (MetaMonitorManager *manager, + MetaLogicalMonitorLayoutMode layout_mode, + MetaMonitor *monitor, + MetaMonitorMode *monitor_mode) +{ + MetaMonitorScalesConstraint constraints = + get_monitor_scale_constraints_per_layout_mode (layout_mode); + + return meta_monitor_calculate_mode_scale (monitor, monitor_mode, constraints); +} + +static float * +meta_monitor_manager_kms_calculate_supported_scales (MetaMonitorManager *manager, + MetaLogicalMonitorLayoutMode layout_mode, + MetaMonitor *monitor, + MetaMonitorMode *monitor_mode, + int *n_supported_scales) +{ + MetaMonitorScalesConstraint constraints = + get_monitor_scale_constraints_per_layout_mode (layout_mode); + + return meta_monitor_calculate_supported_scales (monitor, monitor_mode, + constraints, + n_supported_scales); +} + +static MetaMonitorManagerCapability +meta_monitor_manager_kms_get_capabilities (MetaMonitorManager *manager) +{ + MetaBackend *backend = meta_monitor_manager_get_backend (manager); + MetaSettings *settings = meta_backend_get_settings (backend); + MetaMonitorManagerCapability capabilities = + META_MONITOR_MANAGER_CAPABILITY_TILING; + + if (meta_settings_is_experimental_feature_enabled ( + settings, + META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER)) + capabilities |= META_MONITOR_MANAGER_CAPABILITY_LAYOUT_MODE; + + return capabilities; +} + +static gboolean +meta_monitor_manager_kms_get_max_screen_size (MetaMonitorManager *manager, + int *max_width, + int *max_height) +{ + return FALSE; +} + +static MetaLogicalMonitorLayoutMode +meta_monitor_manager_kms_get_default_layout_mode (MetaMonitorManager *manager) +{ + MetaBackend *backend = meta_monitor_manager_get_backend (manager); + MetaSettings *settings = meta_backend_get_settings (backend); + + if (meta_settings_is_experimental_feature_enabled ( + settings, + META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER)) + return META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL; + else + return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL; +} + +static gboolean +meta_monitor_manager_kms_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (initable); + MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_kms); + MetaBackend *backend = meta_monitor_manager_get_backend (manager); + gboolean can_have_outputs; + GList *l; + + meta_monitor_manager_kms_connect_hotplug_handler (manager_kms); + + can_have_outputs = FALSE; + for (l = meta_backend_get_gpus (backend); l; l = l->next) + { + MetaGpuKms *gpu_kms = l->data; + + if (meta_gpu_kms_can_have_outputs (gpu_kms)) + { + can_have_outputs = TRUE; + break; + } + } + if (!can_have_outputs) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, + "No GPUs with outputs found"); + return FALSE; + } + + return TRUE; +} + +static void +initable_iface_init (GInitableIface *initable_iface) +{ + initable_iface->init = meta_monitor_manager_kms_initable_init; +} + +static void +meta_monitor_manager_kms_init (MetaMonitorManagerKms *manager_kms) +{ +} + +static void +meta_monitor_manager_kms_class_init (MetaMonitorManagerKmsClass *klass) +{ + MetaMonitorManagerClass *manager_class = META_MONITOR_MANAGER_CLASS (klass); + + manager_class->read_edid = meta_monitor_manager_kms_read_edid; + manager_class->read_current_state = meta_monitor_manager_kms_read_current_state; + manager_class->ensure_initial_config = meta_monitor_manager_kms_ensure_initial_config; + manager_class->apply_monitors_config = meta_monitor_manager_kms_apply_monitors_config; + manager_class->set_power_save_mode = meta_monitor_manager_kms_set_power_save_mode; + manager_class->get_crtc_gamma = meta_monitor_manager_kms_get_crtc_gamma; + manager_class->set_crtc_gamma = meta_monitor_manager_kms_set_crtc_gamma; + manager_class->is_transform_handled = meta_monitor_manager_kms_is_transform_handled; + manager_class->calculate_monitor_mode_scale = meta_monitor_manager_kms_calculate_monitor_mode_scale; + manager_class->calculate_supported_scales = meta_monitor_manager_kms_calculate_supported_scales; + manager_class->get_capabilities = meta_monitor_manager_kms_get_capabilities; + manager_class->get_max_screen_size = meta_monitor_manager_kms_get_max_screen_size; + manager_class->get_default_layout_mode = meta_monitor_manager_kms_get_default_layout_mode; +} diff --git a/src/backends/native/meta-monitor-manager-kms.h b/src/backends/native/meta-monitor-manager-kms.h new file mode 100644 index 000000000..b7287bc9a --- /dev/null +++ b/src/backends/native/meta-monitor-manager-kms.h @@ -0,0 +1,42 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001 Havoc Pennington + * Copyright (C) 2003 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * Copyright (C) 2013 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef META_MONITOR_MANAGER_KMS_H +#define META_MONITOR_MANAGER_KMS_H + +#include <xf86drm.h> +#include <xf86drmMode.h> + +#include "backends/meta-monitor-manager-private.h" + +typedef struct _MetaGpuKms MetaGpuKms; + +#define META_TYPE_MONITOR_MANAGER_KMS (meta_monitor_manager_kms_get_type ()) +G_DECLARE_FINAL_TYPE (MetaMonitorManagerKms, meta_monitor_manager_kms, + META, MONITOR_MANAGER_KMS, + MetaMonitorManager) + +void meta_monitor_manager_kms_pause (MetaMonitorManagerKms *manager_kms); + +void meta_monitor_manager_kms_resume (MetaMonitorManagerKms *manager_kms); + +#endif /* META_MONITOR_MANAGER_KMS_H */ diff --git a/src/backends/native/meta-output-kms.c b/src/backends/native/meta-output-kms.c new file mode 100644 index 000000000..e552113c0 --- /dev/null +++ b/src/backends/native/meta-output-kms.c @@ -0,0 +1,412 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2013-2017 Red Hat + * Copyright (C) 2018 DisplayLink (UK) Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "backends/native/meta-output-kms.h" + +#include <errno.h> +#include <stdlib.h> +#include <string.h> + +#include "backends/meta-crtc.h" +#include "backends/native/meta-kms-connector.h" +#include "backends/native/meta-kms-utils.h" +#include "backends/native/meta-crtc-kms.h" + +#include "meta-default-modes.h" + +#define SYNC_TOLERANCE 0.01 /* 1 percent */ + +typedef struct _MetaOutputKms +{ + MetaOutput parent; + + MetaKmsConnector *kms_connector; +} MetaOutputKms; + +MetaKmsConnector * +meta_output_kms_get_kms_connector (MetaOutput *output) +{ + MetaOutputKms *output_kms = output->driver_private; + + return output_kms->kms_connector; +} + +void +meta_output_kms_set_underscan (MetaOutput *output, + MetaKmsUpdate *kms_update) +{ + MetaOutputKms *output_kms = output->driver_private; + + if (!output->supports_underscanning) + return; + + if (output->is_underscanning) + { + MetaCrtc *crtc; + MetaCrtcConfig *crtc_config; + uint64_t hborder, vborder; + + crtc = meta_output_get_assigned_crtc (output); + crtc_config = crtc->config; + hborder = MIN (128, (uint64_t) round (crtc_config->mode->width * 0.05)); + vborder = MIN (128, (uint64_t) round (crtc_config->mode->height * 0.05)); + + g_debug ("Setting underscan of connector %s to %" G_GUINT64_FORMAT " x %" G_GUINT64_FORMAT, + meta_kms_connector_get_name (output_kms->kms_connector), + hborder, vborder); + + meta_kms_connector_set_underscanning (output_kms->kms_connector, + kms_update, + hborder, + vborder); + } + else + { + g_debug ("Unsetting underscan of connector %s", + meta_kms_connector_get_name (output_kms->kms_connector)); + + meta_kms_connector_unset_underscanning (output_kms->kms_connector, + kms_update); + } +} + +uint32_t +meta_output_kms_get_connector_id (MetaOutput *output) +{ + MetaOutputKms *output_kms = output->driver_private; + + return meta_kms_connector_get_id (output_kms->kms_connector); +} + +void +meta_output_kms_set_power_save_mode (MetaOutput *output, + uint64_t dpms_state, + MetaKmsUpdate *kms_update) +{ + MetaOutputKms *output_kms = output->driver_private; + + g_debug ("Setting DPMS state of connector %s to %" G_GUINT64_FORMAT, + meta_kms_connector_get_name (output_kms->kms_connector), + dpms_state); + + meta_kms_connector_update_set_dpms_state (output_kms->kms_connector, + kms_update, + dpms_state); +} + +gboolean +meta_output_kms_can_clone (MetaOutput *output, + MetaOutput *other_output) +{ + MetaOutputKms *output_kms = output->driver_private; + MetaOutputKms *other_output_kms = other_output->driver_private; + + return meta_kms_connector_can_clone (output_kms->kms_connector, + other_output_kms->kms_connector); +} + +GBytes * +meta_output_kms_read_edid (MetaOutput *output) +{ + MetaOutputKms *output_kms = output->driver_private; + const MetaKmsConnectorState *connector_state; + GBytes *edid_data; + + connector_state = + meta_kms_connector_get_current_state (output_kms->kms_connector); + edid_data = connector_state->edid_data; + if (!edid_data) + return NULL; + + return g_bytes_new_from_bytes (edid_data, 0, g_bytes_get_size (edid_data)); +} + +static void +meta_output_destroy_notify (MetaOutput *output) +{ + MetaOutputKms *output_kms; + + output_kms = output->driver_private; + + g_slice_free (MetaOutputKms, output_kms); +} + +static void +add_common_modes (MetaOutput *output, + MetaGpuKms *gpu_kms) +{ + const drmModeModeInfo *drm_mode; + MetaCrtcMode *crtc_mode; + GPtrArray *array; + float refresh_rate; + unsigned i; + unsigned max_hdisplay = 0; + unsigned max_vdisplay = 0; + float max_refresh_rate = 0.0; + + for (i = 0; i < output->n_modes; i++) + { + drm_mode = output->modes[i]->driver_private; + refresh_rate = meta_calculate_drm_mode_refresh_rate (drm_mode); + max_hdisplay = MAX (max_hdisplay, drm_mode->hdisplay); + max_vdisplay = MAX (max_vdisplay, drm_mode->vdisplay); + max_refresh_rate = MAX (max_refresh_rate, refresh_rate); + } + + max_refresh_rate = MAX (max_refresh_rate, 60.0); + max_refresh_rate *= (1 + SYNC_TOLERANCE); + + array = g_ptr_array_new (); + if (max_hdisplay > max_vdisplay) + { + for (i = 0; i < G_N_ELEMENTS (meta_default_landscape_drm_mode_infos); i++) + { + drm_mode = &meta_default_landscape_drm_mode_infos[i]; + refresh_rate = meta_calculate_drm_mode_refresh_rate (drm_mode); + if (drm_mode->hdisplay > max_hdisplay || + drm_mode->vdisplay > max_vdisplay || + refresh_rate > max_refresh_rate) + continue; + + crtc_mode = meta_gpu_kms_get_mode_from_drm_mode (gpu_kms, + drm_mode); + g_ptr_array_add (array, crtc_mode); + } + } + else + { + for (i = 0; i < G_N_ELEMENTS (meta_default_portrait_drm_mode_infos); i++) + { + drm_mode = &meta_default_portrait_drm_mode_infos[i]; + refresh_rate = meta_calculate_drm_mode_refresh_rate (drm_mode); + if (drm_mode->hdisplay > max_hdisplay || + drm_mode->vdisplay > max_vdisplay || + refresh_rate > max_refresh_rate) + continue; + + crtc_mode = meta_gpu_kms_get_mode_from_drm_mode (gpu_kms, + drm_mode); + g_ptr_array_add (array, crtc_mode); + } + } + + output->modes = g_renew (MetaCrtcMode *, output->modes, + output->n_modes + array->len); + memcpy (output->modes + output->n_modes, array->pdata, + array->len * sizeof (MetaCrtcMode *)); + output->n_modes += array->len; + + g_ptr_array_free (array, TRUE); +} + +static int +compare_modes (const void *one, + const void *two) +{ + MetaCrtcMode *a = *(MetaCrtcMode **) one; + MetaCrtcMode *b = *(MetaCrtcMode **) two; + + if (a->width != b->width) + return a->width > b->width ? -1 : 1; + if (a->height != b->height) + return a->height > b->height ? -1 : 1; + if (a->refresh_rate != b->refresh_rate) + return a->refresh_rate > b->refresh_rate ? -1 : 1; + + return g_strcmp0 (b->name, a->name); +} + +static gboolean +init_output_modes (MetaOutput *output, + MetaGpuKms *gpu_kms, + GError **error) +{ + MetaOutputKms *output_kms = output->driver_private; + const MetaKmsConnectorState *connector_state; + int i; + + connector_state = + meta_kms_connector_get_current_state (output_kms->kms_connector); + + output->preferred_mode = NULL; + + output->n_modes = connector_state->n_modes; + output->modes = g_new0 (MetaCrtcMode *, output->n_modes); + for (i = 0; i < connector_state->n_modes; i++) + { + drmModeModeInfo *drm_mode = &connector_state->modes[i]; + MetaCrtcMode *crtc_mode; + + crtc_mode = meta_gpu_kms_get_mode_from_drm_mode (gpu_kms, drm_mode); + output->modes[i] = crtc_mode; + if (drm_mode->type & DRM_MODE_TYPE_PREFERRED) + output->preferred_mode = output->modes[i]; + } + + /* FIXME: MSC feature bit? */ + /* Presume that if the output supports scaling, then we have + * a panel fitter capable of adjusting any mode to suit. + */ + if (connector_state->has_scaling) + add_common_modes (output, gpu_kms); + + if (!output->modes) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "No modes available"); + return FALSE; + } + + qsort (output->modes, output->n_modes, + sizeof (MetaCrtcMode *), compare_modes); + + if (!output->preferred_mode) + output->preferred_mode = output->modes[0]; + + return TRUE; +} + +MetaOutput * +meta_create_kms_output (MetaGpuKms *gpu_kms, + MetaKmsConnector *kms_connector, + MetaOutput *old_output, + GError **error) +{ + MetaGpu *gpu = META_GPU (gpu_kms); + MetaOutput *output; + MetaOutputKms *output_kms; + const MetaKmsConnectorState *connector_state; + uint32_t connector_id; + GArray *crtcs; + GList *l; + uint32_t gpu_id; + + output = g_object_new (META_TYPE_OUTPUT, NULL); + + output_kms = g_slice_new0 (MetaOutputKms); + output->driver_private = output_kms; + output->driver_notify = (GDestroyNotify) meta_output_destroy_notify; + + output->gpu = gpu; + output->name = g_strdup (meta_kms_connector_get_name (kms_connector)); + + gpu_id = meta_gpu_kms_get_id (gpu_kms); + connector_id = meta_kms_connector_get_id (kms_connector); + output->winsys_id = ((uint64_t) gpu_id << 32) | connector_id; + + output_kms->kms_connector = kms_connector; + + connector_state = meta_kms_connector_get_current_state (kms_connector); + + output->panel_orientation_transform = + connector_state->panel_orientation_transform; + if (meta_monitor_transform_is_rotated (output->panel_orientation_transform)) + { + output->width_mm = connector_state->height_mm; + output->height_mm = connector_state->width_mm; + } + else + { + output->width_mm = connector_state->width_mm; + output->height_mm = connector_state->height_mm; + } + + if (!init_output_modes (output, gpu_kms, error)) + { + g_object_unref (output); + return NULL; + } + + crtcs = g_array_new (FALSE, FALSE, sizeof (MetaCrtc *)); + + for (l = meta_gpu_get_crtcs (gpu); l; l = l->next) + { + MetaCrtc *crtc = l->data; + MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc); + uint32_t crtc_idx; + + crtc_idx = meta_kms_crtc_get_idx (kms_crtc); + if (connector_state->common_possible_crtcs & (1 << crtc_idx)) + g_array_append_val (crtcs, crtc); + } + + output->n_possible_crtcs = crtcs->len; + output->possible_crtcs = (MetaCrtc **) g_array_free (crtcs, FALSE); + + if (connector_state->current_crtc_id) + { + for (l = meta_gpu_get_crtcs (gpu); l; l = l->next) + { + MetaCrtc *crtc = l->data; + + if (crtc->crtc_id == connector_state->current_crtc_id) + { + meta_output_assign_crtc (output, crtc); + break; + } + } + } + else + { + meta_output_unassign_crtc (output); + } + + if (old_output) + { + output->is_primary = old_output->is_primary; + output->is_presentation = old_output->is_presentation; + } + else + { + output->is_primary = FALSE; + output->is_presentation = FALSE; + } + + output->suggested_x = connector_state->suggested_x; + output->suggested_y = connector_state->suggested_y; + output->hotplug_mode_update = connector_state->hotplug_mode_update; + output->supports_underscanning = + meta_kms_connector_is_underscanning_supported (kms_connector); + + meta_output_parse_edid (output, connector_state->edid_data); + + output->connector_type = meta_kms_connector_get_connector_type (kms_connector); + + output->tile_info = connector_state->tile_info; + + /* FIXME: backlight is a very driver specific thing unfortunately, + every DDX does its own thing, and the dumb KMS API does not include it. + + For example, xf86-video-intel has a list of paths to probe in /sys/class/backlight + (one for each major HW maker, and then some). + We can't do the same because we're not root. + It might be best to leave backlight out of the story and rely on the setuid + helper in gnome-settings-daemon. + */ + output->backlight_min = 0; + output->backlight_max = 0; + output->backlight = -1; + + return output; +} diff --git a/src/backends/native/meta-output-kms.h b/src/backends/native/meta-output-kms.h new file mode 100644 index 000000000..47ce68a3c --- /dev/null +++ b/src/backends/native/meta-output-kms.h @@ -0,0 +1,51 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat + * Copyright (C) 2018 DisplayLink (UK) Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_OUTPUT_KMS_H +#define META_OUTPUT_KMS_H + +#include "backends/meta-output.h" +#include "backends/native/meta-gpu-kms.h" +#include "backends/native/meta-kms-types.h" + +void meta_output_kms_set_power_save_mode (MetaOutput *output, + uint64_t dpms_state, + MetaKmsUpdate *kms_update); + +void meta_output_kms_set_underscan (MetaOutput *output, + MetaKmsUpdate *kms_update); + +gboolean meta_output_kms_can_clone (MetaOutput *output, + MetaOutput *other_output); + +MetaKmsConnector * meta_output_kms_get_kms_connector (MetaOutput *output); + +uint32_t meta_output_kms_get_connector_id (MetaOutput *output); + +GBytes * meta_output_kms_read_edid (MetaOutput *output); + +MetaOutput * meta_create_kms_output (MetaGpuKms *gpu_kms, + MetaKmsConnector *kms_connector, + MetaOutput *old_output, + GError **error); + +#endif /* META_OUTPUT_KMS_H */ diff --git a/src/backends/native/meta-renderer-native-gles3.c b/src/backends/native/meta-renderer-native-gles3.c new file mode 100644 index 000000000..43394cc64 --- /dev/null +++ b/src/backends/native/meta-renderer-native-gles3.c @@ -0,0 +1,160 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat + * Copyright (c) 2018 DisplayLink (UK) Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#include "config.h" + +#define GL_GLEXT_PROTOTYPES + +#include "backends/native/meta-renderer-native-gles3.h" + +#include <GLES3/gl3.h> +#include <drm_fourcc.h> +#include <errno.h> +#include <gio/gio.h> +#include <string.h> + +#include "backends/meta-egl-ext.h" +#include "backends/meta-gles3.h" +#include "backends/meta-gles3-table.h" + +/* + * GL/gl.h being included may conflit with gl3.h on some architectures. + * Make sure that hasn't happened on any architecture. + */ +#ifdef GL_VERSION_1_1 +#error "Somehow included OpenGL headers when we shouldn't have" +#endif + +static void +paint_egl_image (MetaGles3 *gles3, + EGLImageKHR egl_image, + int width, + int height) +{ + GLuint texture; + GLuint framebuffer; + + meta_gles3_clear_error (gles3); + + GLBAS (gles3, glGenFramebuffers, (1, &framebuffer)); + GLBAS (gles3, glBindFramebuffer, (GL_READ_FRAMEBUFFER, framebuffer)); + + GLBAS (gles3, glActiveTexture, (GL_TEXTURE0)); + GLBAS (gles3, glGenTextures, (1, &texture)); + GLBAS (gles3, glBindTexture, (GL_TEXTURE_2D, texture)); + GLEXT (gles3, glEGLImageTargetTexture2DOES, (GL_TEXTURE_2D, egl_image)); + GLBAS (gles3, glTexParameteri, (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, + GL_NEAREST)); + GLBAS (gles3, glTexParameteri, (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_NEAREST)); + GLBAS (gles3, glTexParameteri, (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, + GL_CLAMP_TO_EDGE)); + GLBAS (gles3, glTexParameteri, (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, + GL_CLAMP_TO_EDGE)); + GLBAS (gles3, glTexParameteri, (GL_TEXTURE_2D, GL_TEXTURE_WRAP_R_OES, + GL_CLAMP_TO_EDGE)); + + GLBAS (gles3, glFramebufferTexture2D, (GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, texture, 0)); + + GLBAS (gles3, glBindFramebuffer, (GL_READ_FRAMEBUFFER, framebuffer)); + GLBAS (gles3, glBlitFramebuffer, (0, height, width, 0, + 0, 0, width, height, + GL_COLOR_BUFFER_BIT, + GL_NEAREST)); + + GLBAS (gles3, glDeleteTextures, (1, &texture)); + GLBAS (gles3, glDeleteFramebuffers, (1, &framebuffer)); +} + +gboolean +meta_renderer_native_gles3_blit_shared_bo (MetaEgl *egl, + MetaGles3 *gles3, + EGLDisplay egl_display, + EGLContext egl_context, + EGLSurface egl_surface, + struct gbm_bo *shared_bo, + GError **error) +{ + int shared_bo_fd; + unsigned int width; + unsigned int height; + uint32_t i, n_planes; + uint32_t strides[4] = { 0 }; + uint32_t offsets[4] = { 0 }; + uint64_t modifiers[4] = { 0 }; + int fds[4] = { -1, -1, -1, -1 }; + uint32_t format; + EGLImageKHR egl_image; + gboolean use_modifiers; + + shared_bo_fd = gbm_bo_get_fd (shared_bo); + if (shared_bo_fd < 0) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Failed to export gbm_bo: %s", strerror (errno)); + return FALSE; + } + + width = gbm_bo_get_width (shared_bo); + height = gbm_bo_get_height (shared_bo); + format = gbm_bo_get_format (shared_bo); + + n_planes = gbm_bo_get_plane_count (shared_bo); + for (i = 0; i < n_planes; i++) + { + strides[i] = gbm_bo_get_stride_for_plane (shared_bo, i); + offsets[i] = gbm_bo_get_offset (shared_bo, i); + modifiers[i] = gbm_bo_get_modifier (shared_bo); + fds[i] = shared_bo_fd; + } + + /* Workaround for https://gitlab.gnome.org/GNOME/mutter/issues/18 */ + if (modifiers[0] == DRM_FORMAT_MOD_LINEAR || + modifiers[0] == DRM_FORMAT_MOD_INVALID) + use_modifiers = FALSE; + else + use_modifiers = TRUE; + + egl_image = meta_egl_create_dmabuf_image (egl, + egl_display, + width, + height, + format, + n_planes, + fds, + strides, + offsets, + use_modifiers ? modifiers : NULL, + error); + close (shared_bo_fd); + + if (!egl_image) + return FALSE; + + paint_egl_image (gles3, egl_image, width, height); + + meta_egl_destroy_image (egl, egl_display, egl_image, NULL); + + return TRUE; +} diff --git a/src/backends/native/meta-renderer-native-gles3.h b/src/backends/native/meta-renderer-native-gles3.h new file mode 100644 index 000000000..4e7324c8d --- /dev/null +++ b/src/backends/native/meta-renderer-native-gles3.h @@ -0,0 +1,40 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat + * Copyright (c) 2018 DisplayLink (UK) Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#ifndef META_RENDERER_NATIVE_GLES3_H +#define META_RENDERER_NATIVE_GLES3_H + +#include <gbm.h> + +#include "backends/meta-egl.h" +#include "backends/meta-gles3.h" + +gboolean meta_renderer_native_gles3_blit_shared_bo (MetaEgl *egl, + MetaGles3 *gles3, + EGLDisplay egl_display, + EGLContext egl_context, + EGLSurface egl_surface, + struct gbm_bo *shared_bo, + GError **error); + +#endif /* META_RENDERER_NATIVE_GLES3_H */ diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c new file mode 100644 index 000000000..7e75ab9fd --- /dev/null +++ b/src/backends/native/meta-renderer-native.c @@ -0,0 +1,4001 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2011 Intel Corporation. + * Copyright (C) 2016 Red Hat + * Copyright (c) 2018,2019 DisplayLink (UK) Ltd. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Authors: + * Rob Bradford <rob@linux.intel.com> (from cogl-winsys-egl-kms.c) + * Kristian Høgsberg (from eglkms.c) + * Benjamin Franzke (from eglkms.c) + * Robert Bragg <robert@linux.intel.com> (from cogl-winsys-egl-kms.c) + * Neil Roberts <neil@linux.intel.com> (from cogl-winsys-egl-kms.c) + * Jonas Ådahl <jadahl@redhat.com> + * + */ + +#include "config.h" + +#include <drm_fourcc.h> +#include <errno.h> +#include <fcntl.h> +#include <gbm.h> +#include <gio/gio.h> +#include <glib-object.h> +#include <stdlib.h> +#include <string.h> +#include <sys/mman.h> +#include <unistd.h> +#include <xf86drm.h> + +#include "backends/meta-backend-private.h" +#include "backends/meta-crtc.h" +#include "backends/meta-egl-ext.h" +#include "backends/meta-egl.h" +#include "backends/meta-gles3.h" +#include "backends/meta-logical-monitor.h" +#include "backends/meta-output.h" +#include "backends/meta-renderer-view.h" +#include "backends/native/meta-crtc-kms.h" +#include "backends/native/meta-drm-buffer-dumb.h" +#include "backends/native/meta-drm-buffer-gbm.h" +#include "backends/native/meta-drm-buffer-import.h" +#include "backends/native/meta-drm-buffer.h" +#include "backends/native/meta-gpu-kms.h" +#include "backends/native/meta-kms-update.h" +#include "backends/native/meta-kms-utils.h" +#include "backends/native/meta-kms.h" +#include "backends/native/meta-output-kms.h" +#include "backends/native/meta-renderer-native-gles3.h" +#include "backends/native/meta-renderer-native.h" +//#include "cogl/cogl-framebuffer.h" +#include "cogl/cogl.h" +#include "core/boxes-private.h" + +#ifndef EGL_DRM_MASTER_FD_EXT +#define EGL_DRM_MASTER_FD_EXT 0x333C +#endif + +/* added in libdrm 2.4.95 */ +#ifndef DRM_FORMAT_INVALID +#define DRM_FORMAT_INVALID 0 +#endif + +typedef enum _MetaSharedFramebufferCopyMode +{ + /* Zero-copy: primary GPU exports, secondary GPU imports as KMS FB */ + META_SHARED_FRAMEBUFFER_COPY_MODE_ZERO, + /* the secondary GPU will make the copy */ + META_SHARED_FRAMEBUFFER_COPY_MODE_SECONDARY_GPU, + /* + * The copy is made in the primary GPU rendering context, either + * as a CPU copy through Cogl read-pixels or as primary GPU copy + * using glBlitFramebuffer. + */ + META_SHARED_FRAMEBUFFER_COPY_MODE_PRIMARY +} MetaSharedFramebufferCopyMode; + +typedef struct _MetaRendererNativeGpuData +{ + MetaRendererNative *renderer_native; + + struct { + struct gbm_device *device; + } gbm; + +#ifdef HAVE_EGL_DEVICE + struct { + EGLDeviceEXT device; + } egl; +#endif + + MetaRendererNativeMode mode; + + EGLDisplay egl_display; + + /* + * Fields used for blitting iGPU framebuffer content onto dGPU framebuffers. + */ + struct { + MetaSharedFramebufferCopyMode copy_mode; + gboolean is_hardware_rendering; + gboolean has_EGL_EXT_image_dma_buf_import_modifiers; + + /* For GPU blit mode */ + EGLContext egl_context; + EGLConfig egl_config; + } secondary; +} MetaRendererNativeGpuData; + +typedef struct _MetaDumbBuffer +{ + uint32_t fb_id; + uint32_t handle; + void *map; + uint64_t map_size; + int width; + int height; + int stride_bytes; + uint32_t drm_format; + int dmabuf_fd; +} MetaDumbBuffer; + +typedef enum _MetaSharedFramebufferImportStatus +{ + /* Not tried importing yet. */ + META_SHARED_FRAMEBUFFER_IMPORT_STATUS_NONE, + /* Tried before and failed. */ + META_SHARED_FRAMEBUFFER_IMPORT_STATUS_FAILED, + /* Tried before and succeeded. */ + META_SHARED_FRAMEBUFFER_IMPORT_STATUS_OK +} MetaSharedFramebufferImportStatus; + +typedef struct _MetaOnscreenNativeSecondaryGpuState +{ + MetaGpuKms *gpu_kms; + MetaRendererNativeGpuData *renderer_gpu_data; + + EGLSurface egl_surface; + + struct { + struct gbm_surface *surface; + MetaDrmBuffer *current_fb; + MetaDrmBuffer *next_fb; + } gbm; + + struct { + MetaDumbBuffer *dumb_fb; + MetaDumbBuffer dumb_fbs[2]; + } cpu; + + int pending_flips; + + gboolean noted_primary_gpu_copy_ok; + gboolean noted_primary_gpu_copy_failed; + MetaSharedFramebufferImportStatus import_status; +} MetaOnscreenNativeSecondaryGpuState; + +typedef struct _MetaOnscreenNative +{ + MetaRendererNative *renderer_native; + MetaGpuKms *render_gpu; + MetaOutput *output; + MetaCrtc *crtc; + + MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state; + + struct { + struct gbm_surface *surface; + MetaDrmBuffer *current_fb; + MetaDrmBuffer *next_fb; + } gbm; + +#ifdef HAVE_EGL_DEVICE + struct { + EGLStreamKHR stream; + + MetaDumbBuffer dumb_fb; + } egl; +#endif + + gboolean pending_swap_notify; + + gboolean pending_set_crtc; + + int64_t pending_queue_swap_notify_frame_count; + int64_t pending_swap_notify_frame_count; + + MetaRendererView *view; + int total_pending_flips; +} MetaOnscreenNative; + +struct _MetaRendererNative +{ + MetaRenderer parent; + + MetaGpuKms *primary_gpu_kms; + + MetaGles3 *gles3; + + gboolean use_modifiers; + + GHashTable *gpu_datas; + + CoglClosure *swap_notify_idle; + + int64_t frame_counter; + gboolean pending_unset_disabled_crtcs; + + GList *power_save_page_flip_onscreens; + guint power_save_page_flip_source_id; +}; + +static void +initable_iface_init (GInitableIface *initable_iface); + +G_DEFINE_TYPE_WITH_CODE (MetaRendererNative, + meta_renderer_native, + META_TYPE_RENDERER, + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + initable_iface_init)) + +static const CoglWinsysEGLVtable _cogl_winsys_egl_vtable; +static const CoglWinsysVtable *parent_vtable; + +static void +release_dumb_fb (MetaDumbBuffer *dumb_fb, + MetaGpuKms *gpu_kms); + +static gboolean +init_dumb_fb (MetaDumbBuffer *dumb_fb, + MetaGpuKms *gpu_kms, + int width, + int height, + uint32_t format, + GError **error); + +static int +meta_dumb_buffer_ensure_dmabuf_fd (MetaDumbBuffer *dumb_fb, + MetaGpuKms *gpu_kms); + +static MetaEgl * +meta_renderer_native_get_egl (MetaRendererNative *renderer_native); + +static void +free_current_secondary_bo (CoglOnscreen *onscreen); + +static gboolean +cogl_pixel_format_from_drm_format (uint32_t drm_format, + CoglPixelFormat *out_format, + CoglTextureComponents *out_components); + +static void +meta_renderer_native_queue_modes_reset (MetaRendererNative *renderer_native); + +static void +meta_renderer_native_gpu_data_free (MetaRendererNativeGpuData *renderer_gpu_data) +{ + MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native; + MetaEgl *egl = meta_renderer_native_get_egl (renderer_native); + + if (renderer_gpu_data->egl_display != EGL_NO_DISPLAY) + meta_egl_terminate (egl, renderer_gpu_data->egl_display, NULL); + + g_clear_pointer (&renderer_gpu_data->gbm.device, gbm_device_destroy); + g_free (renderer_gpu_data); +} + +static MetaRendererNativeGpuData * +meta_renderer_native_get_gpu_data (MetaRendererNative *renderer_native, + MetaGpuKms *gpu_kms) +{ + return g_hash_table_lookup (renderer_native->gpu_datas, gpu_kms); +} + +static MetaRendererNative * +meta_renderer_native_from_gpu (MetaGpuKms *gpu_kms) +{ + MetaBackend *backend = meta_gpu_get_backend (META_GPU (gpu_kms)); + + return META_RENDERER_NATIVE (meta_backend_get_renderer (backend)); +} + +struct gbm_device * +meta_gbm_device_from_gpu (MetaGpuKms *gpu_kms) +{ + MetaRendererNative *renderer_native = meta_renderer_native_from_gpu (gpu_kms); + MetaRendererNativeGpuData *renderer_gpu_data; + + renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native, + gpu_kms); + + return renderer_gpu_data->gbm.device; +} + +static MetaRendererNativeGpuData * +meta_create_renderer_native_gpu_data (MetaGpuKms *gpu_kms) +{ + return g_new0 (MetaRendererNativeGpuData, 1); +} + +static MetaEgl * +meta_renderer_native_get_egl (MetaRendererNative *renderer_native) +{ + MetaRenderer *renderer = META_RENDERER (renderer_native); + + return meta_backend_get_egl (meta_renderer_get_backend (renderer)); +} + +static MetaEgl * +meta_onscreen_native_get_egl (MetaOnscreenNative *onscreen_native) +{ + return meta_renderer_native_get_egl (onscreen_native->renderer_native); +} + +static GArray * +get_supported_kms_modifiers (MetaCrtc *crtc, + uint32_t format) +{ + GArray *modifiers; + GArray *crtc_mods; + unsigned int i; + + crtc_mods = meta_crtc_kms_get_modifiers (crtc, format); + if (!crtc_mods) + return NULL; + + modifiers = g_array_new (FALSE, FALSE, sizeof (uint64_t)); + + /* + * For each modifier from base_crtc, check if it's available on all other + * CRTCs. + */ + for (i = 0; i < crtc_mods->len; i++) + { + uint64_t modifier = g_array_index (crtc_mods, uint64_t, i); + + g_array_append_val (modifiers, modifier); + } + + if (modifiers->len == 0) + { + g_array_free (modifiers, TRUE); + return NULL; + } + + return modifiers; +} + +static GArray * +get_supported_egl_modifiers (CoglOnscreen *onscreen, + MetaCrtc *crtc, + uint32_t format) +{ + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; + MetaRendererNative *renderer_native = onscreen_native->renderer_native; + MetaEgl *egl = meta_onscreen_native_get_egl (onscreen_native); + MetaGpu *gpu; + MetaRendererNativeGpuData *renderer_gpu_data; + EGLint num_modifiers; + GArray *modifiers; + GError *error = NULL; + gboolean ret; + + gpu = meta_crtc_get_gpu (crtc); + renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native, + META_GPU_KMS (gpu)); + + if (!meta_egl_has_extensions (egl, renderer_gpu_data->egl_display, NULL, + "EGL_EXT_image_dma_buf_import_modifiers", + NULL)) + return NULL; + + ret = meta_egl_query_dma_buf_modifiers (egl, renderer_gpu_data->egl_display, + format, 0, NULL, NULL, + &num_modifiers, NULL); + if (!ret || num_modifiers == 0) + return NULL; + + modifiers = g_array_sized_new (FALSE, FALSE, sizeof (uint64_t), + num_modifiers); + ret = meta_egl_query_dma_buf_modifiers (egl, renderer_gpu_data->egl_display, + format, num_modifiers, + (EGLuint64KHR *) modifiers->data, NULL, + &num_modifiers, &error); + + if (!ret) + { + g_warning ("Failed to query DMABUF modifiers: %s", error->message); + g_error_free (error); + g_array_free (modifiers, TRUE); + return NULL; + } + + return modifiers; +} + +static GArray * +get_supported_modifiers (CoglOnscreen *onscreen, + uint32_t format) +{ + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; + MetaCrtc *crtc = onscreen_native->crtc; + MetaGpu *gpu; + g_autoptr (GArray) modifiers = NULL; + + gpu = meta_crtc_get_gpu (crtc); + if (gpu == META_GPU (onscreen_native->render_gpu)) + modifiers = get_supported_kms_modifiers (crtc, format); + else + modifiers = get_supported_egl_modifiers (onscreen, crtc, format); + + return g_steal_pointer (&modifiers); +} + +static GArray * +get_supported_kms_formats (CoglOnscreen *onscreen) +{ + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; + MetaCrtc *crtc = onscreen_native->crtc; + + return meta_crtc_kms_copy_drm_format_list (crtc); +} + +static gboolean +init_secondary_gpu_state_gpu_copy_mode (MetaRendererNative *renderer_native, + CoglOnscreen *onscreen, + MetaRendererNativeGpuData *renderer_gpu_data, + GError **error) +{ + CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; + MetaEgl *egl = meta_onscreen_native_get_egl (onscreen_native); + int width, height; + EGLNativeWindowType egl_native_window; + struct gbm_surface *gbm_surface; + EGLSurface egl_surface; + MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state; + MetaGpuKms *gpu_kms; + + width = cogl_framebuffer_get_width (framebuffer); + height = cogl_framebuffer_get_height (framebuffer); + + gbm_surface = gbm_surface_create (renderer_gpu_data->gbm.device, + width, height, + GBM_FORMAT_XRGB8888, + GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); + if (!gbm_surface) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Failed to create gbm_surface: %s", strerror (errno)); + return FALSE; + } + + egl_native_window = (EGLNativeWindowType) gbm_surface; + egl_surface = + meta_egl_create_window_surface (egl, + renderer_gpu_data->egl_display, + renderer_gpu_data->secondary.egl_config, + egl_native_window, + NULL, + error); + if (egl_surface == EGL_NO_SURFACE) + { + gbm_surface_destroy (gbm_surface); + return FALSE; + } + + secondary_gpu_state = g_new0 (MetaOnscreenNativeSecondaryGpuState, 1); + + gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (onscreen_native->crtc)); + secondary_gpu_state->gpu_kms = gpu_kms; + secondary_gpu_state->renderer_gpu_data = renderer_gpu_data; + secondary_gpu_state->gbm.surface = gbm_surface; + secondary_gpu_state->egl_surface = egl_surface; + + onscreen_native->secondary_gpu_state = secondary_gpu_state; + + return TRUE; +} + +static void +secondary_gpu_release_dumb (MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state) +{ + MetaGpuKms *gpu_kms = secondary_gpu_state->gpu_kms; + unsigned i; + + for (i = 0; i < G_N_ELEMENTS (secondary_gpu_state->cpu.dumb_fbs); i++) + release_dumb_fb (&secondary_gpu_state->cpu.dumb_fbs[i], gpu_kms); +} + +static void +secondary_gpu_state_free (MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state) +{ + MetaBackend *backend = meta_get_backend (); + MetaEgl *egl = meta_backend_get_egl (backend); + + if (secondary_gpu_state->egl_surface != EGL_NO_SURFACE) + { + MetaRendererNativeGpuData *renderer_gpu_data; + + renderer_gpu_data = secondary_gpu_state->renderer_gpu_data; + meta_egl_destroy_surface (egl, + renderer_gpu_data->egl_display, + secondary_gpu_state->egl_surface, + NULL); + } + + g_clear_object (&secondary_gpu_state->gbm.current_fb); + g_clear_object (&secondary_gpu_state->gbm.next_fb); + g_clear_pointer (&secondary_gpu_state->gbm.surface, gbm_surface_destroy); + + secondary_gpu_release_dumb (secondary_gpu_state); + + g_free (secondary_gpu_state); +} + +static uint32_t +pick_secondary_gpu_framebuffer_format_for_cpu (CoglOnscreen *onscreen) +{ + /* + * cogl_framebuffer_read_pixels_into_bitmap () supported formats in + * preference order. Ideally these should depend on the render buffer + * format copy_shared_framebuffer_cpu () will be reading from but + * alpha channel ignored. + */ + static const uint32_t preferred_formats[] = + { + /* + * DRM_FORMAT_XBGR8888 a.k.a GL_RGBA, GL_UNSIGNED_BYTE on + * little-endian is possibly the most optimized glReadPixels + * output format. glReadPixels cannot avoid manufacturing an alpha + * channel if the render buffer does not have one and converting + * to ABGR8888 may be more optimized than ARGB8888. + */ + DRM_FORMAT_XBGR8888, + /* The rest are other fairly commonly used formats in OpenGL. */ + DRM_FORMAT_XRGB8888, + }; + g_autoptr (GArray) formats = NULL; + size_t k; + unsigned int i; + uint32_t drm_format; + + formats = get_supported_kms_formats (onscreen); + + /* Check if any of our preferred formats are supported. */ + for (k = 0; k < G_N_ELEMENTS (preferred_formats); k++) + { + g_assert (cogl_pixel_format_from_drm_format (preferred_formats[k], + NULL, + NULL)); + + for (i = 0; i < formats->len; i++) + { + drm_format = g_array_index (formats, uint32_t, i); + + if (drm_format == preferred_formats[k]) + return drm_format; + } + } + + /* + * Otherwise just pick an arbitrary format we recognize. The formats + * list is not in any specific order and we don't know any better + * either. + */ + for (i = 0; i < formats->len; i++) + { + drm_format = g_array_index (formats, uint32_t, i); + + if (cogl_pixel_format_from_drm_format (drm_format, NULL, NULL)) + return drm_format; + } + + return DRM_FORMAT_INVALID; +} + +static gboolean +init_secondary_gpu_state_cpu_copy_mode (MetaRendererNative *renderer_native, + CoglOnscreen *onscreen, + MetaRendererNativeGpuData *renderer_gpu_data, + GError **error) +{ + CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; + MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state; + MetaGpuKms *gpu_kms; + int width, height; + unsigned int i; + uint32_t drm_format; + MetaDrmFormatBuf tmp; + + drm_format = pick_secondary_gpu_framebuffer_format_for_cpu (onscreen); + if (drm_format == DRM_FORMAT_INVALID) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Could not find a suitable pixel format in CPU copy mode"); + return FALSE; + } + + width = cogl_framebuffer_get_width (framebuffer); + height = cogl_framebuffer_get_height (framebuffer); + + gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (onscreen_native->crtc)); + g_debug ("Secondary GPU %s using DRM format '%s' (0x%x) for a %dx%d output.", + meta_gpu_kms_get_file_path (gpu_kms), + meta_drm_format_to_string (&tmp, drm_format), + drm_format, + width, height); + + secondary_gpu_state = g_new0 (MetaOnscreenNativeSecondaryGpuState, 1); + secondary_gpu_state->renderer_gpu_data = renderer_gpu_data; + secondary_gpu_state->gpu_kms = gpu_kms; + secondary_gpu_state->egl_surface = EGL_NO_SURFACE; + + for (i = 0; i < G_N_ELEMENTS (secondary_gpu_state->cpu.dumb_fbs); i++) + { + MetaDumbBuffer *dumb_fb = &secondary_gpu_state->cpu.dumb_fbs[i]; + + if (!init_dumb_fb (dumb_fb, + gpu_kms, + width, height, + drm_format, + error)) + { + secondary_gpu_state_free (secondary_gpu_state); + return FALSE; + } + } + + /* + * This function initializes everything needed for + * META_SHARED_FRAMEBUFFER_COPY_MODE_ZERO as well. + */ + secondary_gpu_state->import_status = + META_SHARED_FRAMEBUFFER_IMPORT_STATUS_NONE; + + onscreen_native->secondary_gpu_state = secondary_gpu_state; + + return TRUE; +} + +static gboolean +init_secondary_gpu_state (MetaRendererNative *renderer_native, + CoglOnscreen *onscreen, + GError **error) +{ + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; + MetaGpu *gpu = meta_crtc_get_gpu (onscreen_native->crtc); + MetaRendererNativeGpuData *renderer_gpu_data; + + renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native, + META_GPU_KMS (gpu)); + + switch (renderer_gpu_data->secondary.copy_mode) + { + case META_SHARED_FRAMEBUFFER_COPY_MODE_SECONDARY_GPU: + if (!init_secondary_gpu_state_gpu_copy_mode (renderer_native, + onscreen, + renderer_gpu_data, + error)) + return FALSE; + break; + case META_SHARED_FRAMEBUFFER_COPY_MODE_ZERO: + /* + * Initialize also the primary copy mode, so that if zero-copy + * path fails, which is quite likely, we can simply continue + * with the primary copy path on the very first frame. + */ + G_GNUC_FALLTHROUGH; + case META_SHARED_FRAMEBUFFER_COPY_MODE_PRIMARY: + if (!init_secondary_gpu_state_cpu_copy_mode (renderer_native, + onscreen, + renderer_gpu_data, + error)) + return FALSE; + break; + } + + return TRUE; +} + +static void +meta_renderer_native_disconnect (CoglRenderer *cogl_renderer) +{ + CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys; + + g_slice_free (CoglRendererEGL, cogl_renderer_egl); +} + +static void +flush_pending_swap_notify (CoglFramebuffer *framebuffer) +{ + if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN) + { + CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer); + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; + + if (onscreen_native->pending_swap_notify) + { + CoglFrameInfo *info; + + while ((info = g_queue_peek_head (&onscreen->pending_frame_infos)) && + info->global_frame_counter <= onscreen_native->pending_swap_notify_frame_count) + { + _cogl_onscreen_notify_frame_sync (onscreen, info); + _cogl_onscreen_notify_complete (onscreen, info); + cogl_object_unref (info); + g_queue_pop_head (&onscreen->pending_frame_infos); + } + + onscreen_native->pending_swap_notify = FALSE; + cogl_object_unref (onscreen); + } + } +} + +static void +flush_pending_swap_notify_idle (void *user_data) +{ + CoglContext *cogl_context = user_data; + CoglRendererEGL *cogl_renderer_egl = cogl_context->display->renderer->winsys; + MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform; + MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native; + GList *l; + + /* This needs to be disconnected before invoking the callbacks in + * case the callbacks cause it to be queued again */ + _cogl_closure_disconnect (renderer_native->swap_notify_idle); + renderer_native->swap_notify_idle = NULL; + + l = cogl_context->framebuffers; + while (l) + { + GList *next = l->next; + CoglFramebuffer *framebuffer = l->data; + + flush_pending_swap_notify (framebuffer); + + l = next; + } +} + +static void +free_current_secondary_bo (CoglOnscreen *onscreen) +{ + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; + MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state; + + secondary_gpu_state = onscreen_native->secondary_gpu_state; + if (!secondary_gpu_state) + return; + + g_clear_object (&secondary_gpu_state->gbm.current_fb); +} + +static void +free_current_bo (CoglOnscreen *onscreen) +{ + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; + + g_clear_object (&onscreen_native->gbm.current_fb); + free_current_secondary_bo (onscreen); +} + +static void +meta_onscreen_native_queue_swap_notify (CoglOnscreen *onscreen) +{ + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; + MetaRendererNative *renderer_native = onscreen_native->renderer_native; + + onscreen_native->pending_swap_notify_frame_count = + onscreen_native->pending_queue_swap_notify_frame_count; + + if (onscreen_native->pending_swap_notify) + return; + + /* We only want to notify that the swap is complete when the + * application calls cogl_context_dispatch so instead of + * immediately notifying we queue an idle callback */ + if (!renderer_native->swap_notify_idle) + { + CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); + CoglContext *cogl_context = framebuffer->context; + CoglRenderer *cogl_renderer = cogl_context->display->renderer; + + renderer_native->swap_notify_idle = + _cogl_poll_renderer_add_idle (cogl_renderer, + flush_pending_swap_notify_idle, + cogl_context, + NULL); + } + + /* + * The framebuffer will have its own referenc while the swap notify is + * pending. Otherwise when destroying the view would drop the pending + * notification with if the destruction happens before the idle callback + * is invoked. + */ + cogl_object_ref (onscreen); + onscreen_native->pending_swap_notify = TRUE; +} + +static gboolean +meta_renderer_native_connect (CoglRenderer *cogl_renderer, + GError **error) +{ + CoglRendererEGL *cogl_renderer_egl; + MetaGpuKms *gpu_kms = cogl_renderer->custom_winsys_user_data; + MetaRendererNative *renderer_native = meta_renderer_native_from_gpu (gpu_kms); + MetaRendererNativeGpuData *renderer_gpu_data; + + cogl_renderer->winsys = g_slice_new0 (CoglRendererEGL); + cogl_renderer_egl = cogl_renderer->winsys; + + renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native, + gpu_kms); + + cogl_renderer_egl->platform_vtable = &_cogl_winsys_egl_vtable; + cogl_renderer_egl->platform = renderer_gpu_data; + cogl_renderer_egl->edpy = renderer_gpu_data->egl_display; + + if (!_cogl_winsys_egl_renderer_connect_common (cogl_renderer, error)) + goto fail; + + return TRUE; + +fail: + meta_renderer_native_disconnect (cogl_renderer); + + return FALSE; +} + +static int +meta_renderer_native_add_egl_config_attributes (CoglDisplay *cogl_display, + CoglFramebufferConfig *config, + EGLint *attributes) +{ + CoglRendererEGL *cogl_renderer_egl = cogl_display->renderer->winsys; + MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform; + int i = 0; + + switch (renderer_gpu_data->mode) + { + case META_RENDERER_NATIVE_MODE_GBM: + attributes[i++] = EGL_SURFACE_TYPE; + attributes[i++] = EGL_WINDOW_BIT; + break; +#ifdef HAVE_EGL_DEVICE + case META_RENDERER_NATIVE_MODE_EGL_DEVICE: + attributes[i++] = EGL_SURFACE_TYPE; + attributes[i++] = EGL_STREAM_BIT_KHR; + break; +#endif + } + + return i; +} + +static gboolean +choose_egl_config_from_gbm_format (MetaEgl *egl, + EGLDisplay egl_display, + const EGLint *attributes, + uint32_t gbm_format, + EGLConfig *out_config, + GError **error) +{ + EGLConfig *egl_configs; + EGLint n_configs; + EGLint i; + + egl_configs = meta_egl_choose_all_configs (egl, egl_display, + attributes, + &n_configs, + error); + if (!egl_configs) + return FALSE; + + for (i = 0; i < n_configs; i++) + { + EGLint visual_id; + + if (!meta_egl_get_config_attrib (egl, egl_display, + egl_configs[i], + EGL_NATIVE_VISUAL_ID, + &visual_id, + error)) + { + g_free (egl_configs); + return FALSE; + } + + if ((uint32_t) visual_id == gbm_format) + { + *out_config = egl_configs[i]; + g_free (egl_configs); + return TRUE; + } + } + + g_free (egl_configs); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "No EGL config matching supported GBM format found"); + return FALSE; +} + +static gboolean +meta_renderer_native_choose_egl_config (CoglDisplay *cogl_display, + EGLint *attributes, + EGLConfig *out_config, + GError **error) +{ + CoglRenderer *cogl_renderer = cogl_display->renderer; + CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys; + MetaBackend *backend = meta_get_backend (); + MetaEgl *egl = meta_backend_get_egl (backend); + MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform; + EGLDisplay egl_display = cogl_renderer_egl->edpy; + + switch (renderer_gpu_data->mode) + { + case META_RENDERER_NATIVE_MODE_GBM: + return choose_egl_config_from_gbm_format (egl, + egl_display, + attributes, + GBM_FORMAT_XRGB8888, + out_config, + error); +#ifdef HAVE_EGL_DEVICE + case META_RENDERER_NATIVE_MODE_EGL_DEVICE: + return meta_egl_choose_first_config (egl, + egl_display, + attributes, + out_config, + error); +#endif + } + + return FALSE; +} + +static gboolean +meta_renderer_native_setup_egl_display (CoglDisplay *cogl_display, + GError **error) +{ + CoglDisplayEGL *cogl_display_egl = cogl_display->winsys; + CoglRendererEGL *cogl_renderer_egl = cogl_display->renderer->winsys; + MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform; + MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native; + + cogl_display_egl->platform = renderer_native; + + /* Force a full modeset / drmModeSetCrtc on + * the first swap buffers call. + */ + meta_renderer_native_queue_modes_reset (renderer_native); + + return TRUE; +} + +static void +meta_renderer_native_destroy_egl_display (CoglDisplay *cogl_display) +{ +} + +static EGLSurface +create_dummy_pbuffer_surface (EGLDisplay egl_display, + GError **error) +{ + MetaBackend *backend = meta_get_backend (); + MetaEgl *egl = meta_backend_get_egl (backend); + EGLConfig pbuffer_config; + static const EGLint pbuffer_config_attribs[] = { + EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, + EGL_RED_SIZE, 1, + EGL_GREEN_SIZE, 1, + EGL_BLUE_SIZE, 1, + EGL_ALPHA_SIZE, 0, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_NONE + }; + static const EGLint pbuffer_attribs[] = { + EGL_WIDTH, 16, + EGL_HEIGHT, 16, + EGL_NONE + }; + + if (!meta_egl_choose_first_config (egl, egl_display, pbuffer_config_attribs, + &pbuffer_config, error)) + return EGL_NO_SURFACE; + + return meta_egl_create_pbuffer_surface (egl, egl_display, + pbuffer_config, pbuffer_attribs, + error); +} + +static gboolean +meta_renderer_native_egl_context_created (CoglDisplay *cogl_display, + GError **error) +{ + CoglDisplayEGL *cogl_display_egl = cogl_display->winsys; + CoglRenderer *cogl_renderer = cogl_display->renderer; + CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys; + + if ((cogl_renderer_egl->private_features & + COGL_EGL_WINSYS_FEATURE_SURFACELESS_CONTEXT) == 0) + { + cogl_display_egl->dummy_surface = + create_dummy_pbuffer_surface (cogl_renderer_egl->edpy, error); + if (cogl_display_egl->dummy_surface == EGL_NO_SURFACE) + return FALSE; + } + + if (!_cogl_winsys_egl_make_current (cogl_display, + cogl_display_egl->dummy_surface, + cogl_display_egl->dummy_surface, + cogl_display_egl->egl_context)) + { + g_set_error (error, COGL_WINSYS_ERROR, + COGL_WINSYS_ERROR_CREATE_CONTEXT, + "Failed to make context current"); + return FALSE; + } + + return TRUE; +} + +static void +meta_renderer_native_egl_cleanup_context (CoglDisplay *cogl_display) +{ + CoglDisplayEGL *cogl_display_egl = cogl_display->winsys; + CoglRenderer *cogl_renderer = cogl_display->renderer; + CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys; + MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform; + MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native; + MetaEgl *egl = meta_renderer_native_get_egl (renderer_native); + + if (cogl_display_egl->dummy_surface != EGL_NO_SURFACE) + { + meta_egl_destroy_surface (egl, + cogl_renderer_egl->edpy, + cogl_display_egl->dummy_surface, + NULL); + cogl_display_egl->dummy_surface = EGL_NO_SURFACE; + } +} + +static void +swap_secondary_drm_fb (CoglOnscreen *onscreen) +{ + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; + MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state; + + secondary_gpu_state = onscreen_native->secondary_gpu_state; + if (!secondary_gpu_state) + return; + + g_set_object (&secondary_gpu_state->gbm.current_fb, + secondary_gpu_state->gbm.next_fb); + g_clear_object (&secondary_gpu_state->gbm.next_fb); +} + +static void +meta_onscreen_native_swap_drm_fb (CoglOnscreen *onscreen) +{ + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; + + free_current_bo (onscreen); + + g_set_object (&onscreen_native->gbm.current_fb, onscreen_native->gbm.next_fb); + g_clear_object (&onscreen_native->gbm.next_fb); + + swap_secondary_drm_fb (onscreen); +} + +static void +notify_view_crtc_presented (MetaRendererView *view, + MetaKmsCrtc *kms_crtc, + int64_t time_ns) +{ + ClutterStageView *stage_view = CLUTTER_STAGE_VIEW (view); + CoglFramebuffer *framebuffer = + clutter_stage_view_get_onscreen (stage_view); + CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer); + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; + MetaRendererNative *renderer_native = onscreen_native->renderer_native; + MetaGpuKms *render_gpu = onscreen_native->render_gpu; + CoglFrameInfo *frame_info; + MetaCrtc *crtc; + float refresh_rate; + MetaGpuKms *gpu_kms; + + /* Only keep the frame info for the fastest CRTC in use, which may not be + * the first one to complete a flip. By only telling the compositor about the + * fastest monitor(s) we direct it to produce new frames fast enough to + * satisfy all monitors. + */ + frame_info = g_queue_peek_tail (&onscreen->pending_frame_infos); + + crtc = meta_crtc_kms_from_kms_crtc (kms_crtc); + refresh_rate = crtc && crtc->config ? + crtc->config->mode->refresh_rate : + 0.0f; + if (refresh_rate >= frame_info->refresh_rate) + { + frame_info->presentation_time = time_ns; + frame_info->refresh_rate = refresh_rate; + } + + gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc)); + if (gpu_kms != render_gpu) + { + MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state = + onscreen_native->secondary_gpu_state; + + secondary_gpu_state->pending_flips--; + } + + onscreen_native->total_pending_flips--; + if (onscreen_native->total_pending_flips == 0) + { + MetaRendererNativeGpuData *renderer_gpu_data; + + meta_onscreen_native_queue_swap_notify (onscreen); + + renderer_gpu_data = + meta_renderer_native_get_gpu_data (renderer_native, + onscreen_native->render_gpu); + switch (renderer_gpu_data->mode) + { + case META_RENDERER_NATIVE_MODE_GBM: + meta_onscreen_native_swap_drm_fb (onscreen); + break; +#ifdef HAVE_EGL_DEVICE + case META_RENDERER_NATIVE_MODE_EGL_DEVICE: + break; +#endif + } + } +} + +static int64_t +timeval_to_nanoseconds (const struct timeval *tv) +{ + int64_t usec = ((int64_t) tv->tv_sec) * G_USEC_PER_SEC + tv->tv_usec; + int64_t nsec = usec * 1000; + + return nsec; +} + +static void +page_flip_feedback_flipped (MetaKmsCrtc *kms_crtc, + unsigned int sequence, + unsigned int tv_sec, + unsigned int tv_usec, + gpointer user_data) +{ + MetaRendererView *view = user_data; + struct timeval page_flip_time; + + page_flip_time = (struct timeval) { + .tv_sec = tv_sec, + .tv_usec = tv_usec, + }; + + notify_view_crtc_presented (view, kms_crtc, + timeval_to_nanoseconds (&page_flip_time)); + + g_object_unref (view); +} + +static void +page_flip_feedback_mode_set_fallback (MetaKmsCrtc *kms_crtc, + gpointer user_data) +{ + MetaRendererView *view = user_data; + MetaCrtc *crtc; + MetaGpuKms *gpu_kms; + int64_t now_ns; + + /* + * We ended up not page flipping, thus we don't have a presentation time to + * use. Lets use the next best thing: the current time. + */ + + crtc = meta_crtc_kms_from_kms_crtc (kms_crtc); + gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc)); + now_ns = meta_gpu_kms_get_current_time_ns (gpu_kms); + + notify_view_crtc_presented (view, kms_crtc, now_ns); + + g_object_unref (view); +} + +static void +page_flip_feedback_discarded (MetaKmsCrtc *kms_crtc, + gpointer user_data, + const GError *error) +{ + MetaRendererView *view = user_data; + MetaCrtc *crtc; + MetaGpuKms *gpu_kms; + int64_t now_ns; + + /* + * Page flipping failed, but we want to fail gracefully, so to avoid freezing + * the frame clack, pretend we flipped. + */ + + if (error) + g_warning ("Page flip discarded: %s", error->message); + + crtc = meta_crtc_kms_from_kms_crtc (kms_crtc); + gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc)); + now_ns = meta_gpu_kms_get_current_time_ns (gpu_kms); + + notify_view_crtc_presented (view, kms_crtc, now_ns); + + g_object_unref (view); +} + +static const MetaKmsPageFlipFeedback page_flip_feedback = { + .flipped = page_flip_feedback_flipped, + .mode_set_fallback = page_flip_feedback_mode_set_fallback, + .discarded = page_flip_feedback_discarded, +}; + +#ifdef HAVE_EGL_DEVICE +static int +custom_egl_stream_page_flip (gpointer custom_page_flip_data, + gpointer user_data) +{ + MetaOnscreenNative *onscreen_native = custom_page_flip_data; + MetaRendererView *view = user_data; + MetaEgl *egl = meta_onscreen_native_get_egl (onscreen_native); + MetaRendererNativeGpuData *renderer_gpu_data; + EGLDisplay *egl_display; + EGLAttrib *acquire_attribs; + g_autoptr (GError) error = NULL; + + acquire_attribs = (EGLAttrib[]) { + EGL_DRM_FLIP_EVENT_DATA_NV, + (EGLAttrib) view, + EGL_NONE + }; + + renderer_gpu_data = + meta_renderer_native_get_gpu_data (onscreen_native->renderer_native, + onscreen_native->render_gpu); + + egl_display = renderer_gpu_data->egl_display; + if (!meta_egl_stream_consumer_acquire_attrib (egl, + egl_display, + onscreen_native->egl.stream, + acquire_attribs, + &error)) + { + if (g_error_matches (error, META_EGL_ERROR, EGL_RESOURCE_BUSY_EXT)) + return -EBUSY; + else + return -EINVAL; + } + + return 0; +} +#endif /* HAVE_EGL_DEVICE */ + +static void +dummy_power_save_page_flip (CoglOnscreen *onscreen) +{ + meta_onscreen_native_swap_drm_fb (onscreen); + meta_onscreen_native_queue_swap_notify (onscreen); +} + +static gboolean +dummy_power_save_page_flip_cb (gpointer user_data) +{ + MetaRendererNative *renderer_native = user_data; + + g_list_foreach (renderer_native->power_save_page_flip_onscreens, + (GFunc) dummy_power_save_page_flip, NULL); + g_list_free_full (renderer_native->power_save_page_flip_onscreens, + (GDestroyNotify) cogl_object_unref); + renderer_native->power_save_page_flip_onscreens = NULL; + renderer_native->power_save_page_flip_source_id = 0; + + return G_SOURCE_REMOVE; +} + +static void +queue_dummy_power_save_page_flip (CoglOnscreen *onscreen) +{ + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; + MetaRendererNative *renderer_native = onscreen_native->renderer_native; + const unsigned int timeout_ms = 100; + + if (!renderer_native->power_save_page_flip_source_id) + { + renderer_native->power_save_page_flip_source_id = + g_timeout_add (timeout_ms, + dummy_power_save_page_flip_cb, + renderer_native); + } + + renderer_native->power_save_page_flip_onscreens = + g_list_prepend (renderer_native->power_save_page_flip_onscreens, + cogl_object_ref (onscreen)); +} + +static void +meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen, + MetaRendererView *view, + MetaCrtc *crtc, + MetaKmsUpdate *kms_update) +{ + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; + MetaRendererNative *renderer_native = onscreen_native->renderer_native; + MetaGpuKms *render_gpu = onscreen_native->render_gpu; + MetaRendererNativeGpuData *renderer_gpu_data; + MetaGpuKms *gpu_kms; + MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state = NULL; + uint32_t fb_id; + + gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc)); + + g_assert (meta_gpu_kms_is_crtc_active (gpu_kms, crtc)); + + renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native, + render_gpu); + switch (renderer_gpu_data->mode) + { + case META_RENDERER_NATIVE_MODE_GBM: + if (gpu_kms == render_gpu) + { + fb_id = meta_drm_buffer_get_fb_id (onscreen_native->gbm.next_fb); + } + else + { + secondary_gpu_state = onscreen_native->secondary_gpu_state; + fb_id = meta_drm_buffer_get_fb_id (secondary_gpu_state->gbm.next_fb); + } + + meta_crtc_kms_assign_primary_plane (crtc, fb_id, kms_update); + meta_crtc_kms_page_flip (crtc, + &page_flip_feedback, + g_object_ref (view), + kms_update); + + onscreen_native->total_pending_flips++; + if (secondary_gpu_state) + secondary_gpu_state->pending_flips++; + + break; +#ifdef HAVE_EGL_DEVICE + case META_RENDERER_NATIVE_MODE_EGL_DEVICE: + meta_kms_update_custom_page_flip (kms_update, + meta_crtc_kms_get_kms_crtc (crtc), + &page_flip_feedback, + g_object_ref (view), + custom_egl_stream_page_flip, + onscreen_native); + onscreen_native->total_pending_flips++; + break; +#endif + } +} + +static void +meta_onscreen_native_set_crtc_mode (CoglOnscreen *onscreen, + MetaRendererNativeGpuData *renderer_gpu_data, + MetaKmsUpdate *kms_update) +{ + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; + + COGL_TRACE_BEGIN_SCOPED (MetaOnscreenNativeSetCrtcModes, + "Onscreen (set CRTC modes)"); + + switch (renderer_gpu_data->mode) + { + case META_RENDERER_NATIVE_MODE_GBM: + break; +#ifdef HAVE_EGL_DEVICE + case META_RENDERER_NATIVE_MODE_EGL_DEVICE: + { + uint32_t fb_id; + + fb_id = onscreen_native->egl.dumb_fb.fb_id; + meta_crtc_kms_assign_primary_plane (onscreen_native->crtc, + fb_id, kms_update); + break; + } +#endif + } + + meta_crtc_kms_set_mode (onscreen_native->crtc, kms_update); + meta_output_kms_set_underscan (onscreen_native->output, kms_update); +} + +static void +meta_onscreen_native_flip_crtcs (CoglOnscreen *onscreen, + MetaKmsUpdate *kms_update) +{ + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; + MetaRendererView *view = onscreen_native->view; + MetaRendererNative *renderer_native = onscreen_native->renderer_native; + MetaRenderer *renderer = META_RENDERER (renderer_native); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (meta_renderer_get_backend (renderer)); + MetaPowerSave power_save_mode; + + COGL_TRACE_BEGIN_SCOPED (MetaOnscreenNativeFlipCrtcs, + "Onscreen (flip CRTCs)"); + + power_save_mode = meta_monitor_manager_get_power_save_mode (monitor_manager); + if (power_save_mode == META_POWER_SAVE_ON) + { + meta_onscreen_native_flip_crtc (onscreen, view, onscreen_native->crtc, + kms_update); + } + else + { + queue_dummy_power_save_page_flip (onscreen); + } +} + +static void +wait_for_pending_flips (CoglOnscreen *onscreen) +{ + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; + MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state; + GError *error = NULL; + + secondary_gpu_state = onscreen_native->secondary_gpu_state; + if (secondary_gpu_state) + { + while (secondary_gpu_state->pending_flips) + { + if (!meta_gpu_kms_wait_for_flip (secondary_gpu_state->gpu_kms, &error)) + { + g_warning ("Failed to wait for flip on secondary GPU: %s", + error->message); + g_clear_error (&error); + break; + } + } + } + + while (onscreen_native->total_pending_flips) + { + if (!meta_gpu_kms_wait_for_flip (onscreen_native->render_gpu, &error)) + { + g_warning ("Failed to wait for flip: %s", error->message); + g_clear_error (&error); + break; + } + } +} + +static gboolean +import_shared_framebuffer (CoglOnscreen *onscreen, + MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state) +{ + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; + MetaDrmBufferGbm *buffer_gbm; + MetaDrmBufferImport *buffer_import; + g_autoptr (GError) error = NULL; + + buffer_gbm = META_DRM_BUFFER_GBM (onscreen_native->gbm.next_fb); + + buffer_import = meta_drm_buffer_import_new (secondary_gpu_state->gpu_kms, + buffer_gbm, + &error); + if (!buffer_import) + { + g_debug ("Zero-copy disabled for %s, meta_drm_buffer_import_new failed: %s", + meta_gpu_kms_get_file_path (secondary_gpu_state->gpu_kms), + error->message); + + g_warn_if_fail (secondary_gpu_state->import_status == + META_SHARED_FRAMEBUFFER_IMPORT_STATUS_NONE); + + /* + * Fall back. If META_SHARED_FRAMEBUFFER_IMPORT_STATUS_NONE is + * in effect, we have COPY_MODE_PRIMARY prepared already, so we + * simply retry with that path. Import status cannot be FAILED, + * because we should not retry if failed once. + * + * If import status is OK, that is unexpected and we do not + * have the fallback path prepared which means this output cannot + * work anymore. + */ + secondary_gpu_state->renderer_gpu_data->secondary.copy_mode = + META_SHARED_FRAMEBUFFER_COPY_MODE_PRIMARY; + + secondary_gpu_state->import_status = + META_SHARED_FRAMEBUFFER_IMPORT_STATUS_FAILED; + return FALSE; + } + + /* + * next_fb may already contain a fallback buffer, so clear it only + * when we are sure to succeed. + */ + g_clear_object (&secondary_gpu_state->gbm.next_fb); + secondary_gpu_state->gbm.next_fb = META_DRM_BUFFER (buffer_import); + + if (secondary_gpu_state->import_status == + META_SHARED_FRAMEBUFFER_IMPORT_STATUS_NONE) + { + /* + * Clean up the cpu-copy part of + * init_secondary_gpu_state_cpu_copy_mode () + */ + secondary_gpu_release_dumb (secondary_gpu_state); + + g_debug ("Using zero-copy for %s succeeded once.", + meta_gpu_kms_get_file_path (secondary_gpu_state->gpu_kms)); + } + + secondary_gpu_state->import_status = + META_SHARED_FRAMEBUFFER_IMPORT_STATUS_OK; + return TRUE; +} + +static void +copy_shared_framebuffer_gpu (CoglOnscreen *onscreen, + MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state, + MetaRendererNativeGpuData *renderer_gpu_data, + gboolean *egl_context_changed) +{ + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; + MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native; + MetaEgl *egl = meta_renderer_native_get_egl (renderer_native); + GError *error = NULL; + MetaDrmBufferGbm *buffer_gbm; + struct gbm_bo *bo; + + COGL_TRACE_BEGIN_SCOPED (CopySharedFramebufferSecondaryGpu, + "FB Copy (secondary GPU)"); + + g_warn_if_fail (secondary_gpu_state->gbm.next_fb == NULL); + g_clear_object (&secondary_gpu_state->gbm.next_fb); + + if (!meta_egl_make_current (egl, + renderer_gpu_data->egl_display, + secondary_gpu_state->egl_surface, + secondary_gpu_state->egl_surface, + renderer_gpu_data->secondary.egl_context, + &error)) + { + g_warning ("Failed to make current: %s", error->message); + g_error_free (error); + return; + } + + *egl_context_changed = TRUE; + + buffer_gbm = META_DRM_BUFFER_GBM (onscreen_native->gbm.next_fb); + bo = meta_drm_buffer_gbm_get_bo (buffer_gbm); + if (!meta_renderer_native_gles3_blit_shared_bo (egl, + renderer_native->gles3, + renderer_gpu_data->egl_display, + renderer_gpu_data->secondary.egl_context, + secondary_gpu_state->egl_surface, + bo, + &error)) + { + g_warning ("Failed to blit shared framebuffer: %s", error->message); + g_error_free (error); + return; + } + + if (!meta_egl_swap_buffers (egl, + renderer_gpu_data->egl_display, + secondary_gpu_state->egl_surface, + &error)) + { + g_warning ("Failed to swap buffers: %s", error->message); + g_error_free (error); + return; + } + + buffer_gbm = meta_drm_buffer_gbm_new (secondary_gpu_state->gpu_kms, + secondary_gpu_state->gbm.surface, + renderer_native->use_modifiers, + &error); + if (!buffer_gbm) + { + g_warning ("meta_drm_buffer_gbm_new failed: %s", + error->message); + g_error_free (error); + return; + } + + secondary_gpu_state->gbm.next_fb = META_DRM_BUFFER (buffer_gbm); +} + +static MetaDumbBuffer * +secondary_gpu_get_next_dumb_buffer (MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state) +{ + MetaDumbBuffer *current_dumb_fb; + + current_dumb_fb = secondary_gpu_state->cpu.dumb_fb; + if (current_dumb_fb == &secondary_gpu_state->cpu.dumb_fbs[0]) + return &secondary_gpu_state->cpu.dumb_fbs[1]; + else + return &secondary_gpu_state->cpu.dumb_fbs[0]; +} + +static CoglContext * +cogl_context_from_renderer_native (MetaRendererNative *renderer_native) +{ + MetaRenderer *renderer = META_RENDERER (renderer_native); + MetaBackend *backend = meta_renderer_get_backend (renderer); + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + + return clutter_backend_get_cogl_context (clutter_backend); +} + +static CoglFramebuffer * +create_dma_buf_framebuffer (MetaRendererNative *renderer_native, + int dmabuf_fd, + uint32_t width, + uint32_t height, + uint32_t stride, + uint32_t offset, + uint64_t modifier, + uint32_t drm_format, + GError **error) +{ + CoglContext *cogl_context = + cogl_context_from_renderer_native (renderer_native); + CoglDisplay *cogl_display = cogl_context->display; + CoglRenderer *cogl_renderer = cogl_display->renderer; + CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys; + EGLDisplay egl_display = cogl_renderer_egl->edpy; + MetaEgl *egl = meta_renderer_native_get_egl (renderer_native); + EGLImageKHR egl_image; + uint32_t strides[1]; + uint32_t offsets[1]; + uint64_t modifiers[1]; + CoglPixelFormat cogl_format; + CoglEglImageFlags flags; + CoglTexture2D *cogl_tex; + CoglOffscreen *cogl_fbo; + int ret; + + ret = cogl_pixel_format_from_drm_format (drm_format, &cogl_format, NULL); + g_assert (ret); + + strides[0] = stride; + offsets[0] = offset; + modifiers[0] = modifier; + egl_image = meta_egl_create_dmabuf_image (egl, + egl_display, + width, + height, + drm_format, + 1 /* n_planes */, + &dmabuf_fd, + strides, + offsets, + modifiers, + error); + if (egl_image == EGL_NO_IMAGE_KHR) + return NULL; + + flags = COGL_EGL_IMAGE_FLAG_NO_GET_DATA; + cogl_tex = cogl_egl_texture_2d_new_from_image (cogl_context, + width, + height, + cogl_format, + egl_image, + flags, + error); + + meta_egl_destroy_image (egl, egl_display, egl_image, NULL); + + if (!cogl_tex) + return NULL; + + cogl_fbo = cogl_offscreen_new_with_texture (COGL_TEXTURE (cogl_tex)); + cogl_object_unref (cogl_tex); + + if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (cogl_fbo), error)) + { + cogl_object_unref (cogl_fbo); + return NULL; + } + + + return COGL_FRAMEBUFFER (cogl_fbo); +} + +static gboolean +copy_shared_framebuffer_primary_gpu (CoglOnscreen *onscreen, + MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state) +{ + CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; + MetaRendererNative *renderer_native = onscreen_native->renderer_native; + MetaRendererNativeGpuData *primary_gpu_data; + MetaDrmBufferDumb *buffer_dumb; + MetaDumbBuffer *dumb_fb; + CoglFramebuffer *dmabuf_fb; + int dmabuf_fd; + g_autoptr (GError) error = NULL; + CoglPixelFormat cogl_format; + int ret; + + COGL_TRACE_BEGIN_SCOPED (CopySharedFramebufferPrimaryGpu, + "FB Copy (primary GPU)"); + + primary_gpu_data = + meta_renderer_native_get_gpu_data (renderer_native, + renderer_native->primary_gpu_kms); + if (!primary_gpu_data->secondary.has_EGL_EXT_image_dma_buf_import_modifiers) + return FALSE; + + dumb_fb = secondary_gpu_get_next_dumb_buffer (secondary_gpu_state); + + g_assert (cogl_framebuffer_get_width (framebuffer) == dumb_fb->width); + g_assert (cogl_framebuffer_get_height (framebuffer) == dumb_fb->height); + + ret = cogl_pixel_format_from_drm_format (dumb_fb->drm_format, + &cogl_format, + NULL); + g_assert (ret); + + dmabuf_fd = meta_dumb_buffer_ensure_dmabuf_fd (dumb_fb, + secondary_gpu_state->gpu_kms); + if (dmabuf_fd == -1) + return FALSE; + + dmabuf_fb = create_dma_buf_framebuffer (renderer_native, + dmabuf_fd, + dumb_fb->width, + dumb_fb->height, + dumb_fb->stride_bytes, + 0, DRM_FORMAT_MOD_LINEAR, + dumb_fb->drm_format, + &error); + + if (error) + { + g_debug ("%s: Failed to blit DMA buffer image: %s", + G_STRFUNC, error->message); + return FALSE; + } + + if (!cogl_blit_framebuffer (framebuffer, COGL_FRAMEBUFFER (dmabuf_fb), + 0, 0, 0, 0, + dumb_fb->width, + dumb_fb->height, + &error)) + { + cogl_object_unref (dmabuf_fb); + return FALSE; + } + + cogl_object_unref (dmabuf_fb); + + g_clear_object (&secondary_gpu_state->gbm.next_fb); + buffer_dumb = meta_drm_buffer_dumb_new (dumb_fb->fb_id); + secondary_gpu_state->gbm.next_fb = META_DRM_BUFFER (buffer_dumb); + secondary_gpu_state->cpu.dumb_fb = dumb_fb; + + return TRUE; +} + +typedef struct _PixelFormatMap { + uint32_t drm_format; + CoglPixelFormat cogl_format; + CoglTextureComponents cogl_components; +} PixelFormatMap; + +static const PixelFormatMap pixel_format_map[] = { +/* DRM formats are defined as little-endian, not machine endian. */ +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + { DRM_FORMAT_RGB565, COGL_PIXEL_FORMAT_RGB_565, COGL_TEXTURE_COMPONENTS_RGB }, + { DRM_FORMAT_ABGR8888, COGL_PIXEL_FORMAT_RGBA_8888_PRE, COGL_TEXTURE_COMPONENTS_RGBA }, + { DRM_FORMAT_XBGR8888, COGL_PIXEL_FORMAT_RGBA_8888_PRE, COGL_TEXTURE_COMPONENTS_RGB }, + { DRM_FORMAT_ARGB8888, COGL_PIXEL_FORMAT_BGRA_8888_PRE, COGL_TEXTURE_COMPONENTS_RGBA }, + { DRM_FORMAT_XRGB8888, COGL_PIXEL_FORMAT_BGRA_8888_PRE, COGL_TEXTURE_COMPONENTS_RGB }, + { DRM_FORMAT_BGRA8888, COGL_PIXEL_FORMAT_ARGB_8888_PRE, COGL_TEXTURE_COMPONENTS_RGBA }, + { DRM_FORMAT_BGRX8888, COGL_PIXEL_FORMAT_ARGB_8888_PRE, COGL_TEXTURE_COMPONENTS_RGB }, + { DRM_FORMAT_RGBA8888, COGL_PIXEL_FORMAT_ABGR_8888_PRE, COGL_TEXTURE_COMPONENTS_RGBA }, + { DRM_FORMAT_RGBX8888, COGL_PIXEL_FORMAT_ABGR_8888_PRE, COGL_TEXTURE_COMPONENTS_RGB }, +#elif G_BYTE_ORDER == G_BIG_ENDIAN + /* DRM_FORMAT_RGB565 cannot be expressed. */ + { DRM_FORMAT_ABGR8888, COGL_PIXEL_FORMAT_ABGR_8888_PRE, COGL_TEXTURE_COMPONENTS_RGBA }, + { DRM_FORMAT_XBGR8888, COGL_PIXEL_FORMAT_ABGR_8888_PRE, COGL_TEXTURE_COMPONENTS_RGB }, + { DRM_FORMAT_ARGB8888, COGL_PIXEL_FORMAT_ARGB_8888_PRE, COGL_TEXTURE_COMPONENTS_RGBA }, + { DRM_FORMAT_XRGB8888, COGL_PIXEL_FORMAT_ARGB_8888_PRE, COGL_TEXTURE_COMPONENTS_RGB }, + { DRM_FORMAT_BGRA8888, COGL_PIXEL_FORMAT_BGRA_8888_PRE, COGL_TEXTURE_COMPONENTS_RGBA }, + { DRM_FORMAT_BGRX8888, COGL_PIXEL_FORMAT_BGRA_8888_PRE, COGL_TEXTURE_COMPONENTS_RGB }, + { DRM_FORMAT_RGBA8888, COGL_PIXEL_FORMAT_RGBA_8888_PRE, COGL_TEXTURE_COMPONENTS_RGBA }, + { DRM_FORMAT_RGBX8888, COGL_PIXEL_FORMAT_RGBA_8888_PRE, COGL_TEXTURE_COMPONENTS_RGB }, +#else +#error "unexpected G_BYTE_ORDER" +#endif +}; + +static gboolean +cogl_pixel_format_from_drm_format (uint32_t drm_format, + CoglPixelFormat *out_format, + CoglTextureComponents *out_components) +{ + const size_t n = G_N_ELEMENTS (pixel_format_map); + size_t i; + + for (i = 0; i < n; i++) + { + if (pixel_format_map[i].drm_format == drm_format) + break; + } + + if (i == n) + return FALSE; + + if (out_format) + *out_format = pixel_format_map[i].cogl_format; + + if (out_components) + *out_components = pixel_format_map[i].cogl_components; + + return TRUE; +} + +static void +copy_shared_framebuffer_cpu (CoglOnscreen *onscreen, + MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state, + MetaRendererNativeGpuData *renderer_gpu_data) +{ + CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); + CoglContext *cogl_context = framebuffer->context; + MetaDumbBuffer *dumb_fb; + CoglBitmap *dumb_bitmap; + CoglPixelFormat cogl_format; + gboolean ret; + MetaDrmBufferDumb *buffer_dumb; + + COGL_TRACE_BEGIN_SCOPED (CopySharedFramebufferCpu, + "FB Copy (CPU)"); + + dumb_fb = secondary_gpu_get_next_dumb_buffer (secondary_gpu_state); + + g_assert (cogl_framebuffer_get_width (framebuffer) == dumb_fb->width); + g_assert (cogl_framebuffer_get_height (framebuffer) == dumb_fb->height); + + ret = cogl_pixel_format_from_drm_format (dumb_fb->drm_format, + &cogl_format, + NULL); + g_assert (ret); + + dumb_bitmap = cogl_bitmap_new_for_data (cogl_context, + dumb_fb->width, + dumb_fb->height, + cogl_format, + dumb_fb->stride_bytes, + dumb_fb->map); + + if (!cogl_framebuffer_read_pixels_into_bitmap (framebuffer, + 0 /* x */, + 0 /* y */, + COGL_READ_PIXELS_COLOR_BUFFER, + dumb_bitmap)) + g_warning ("Failed to CPU-copy to a secondary GPU output"); + + cogl_object_unref (dumb_bitmap); + + g_clear_object (&secondary_gpu_state->gbm.next_fb); + buffer_dumb = meta_drm_buffer_dumb_new (dumb_fb->fb_id); + secondary_gpu_state->gbm.next_fb = META_DRM_BUFFER (buffer_dumb); + secondary_gpu_state->cpu.dumb_fb = dumb_fb; +} + +static void +update_secondary_gpu_state_pre_swap_buffers (CoglOnscreen *onscreen) +{ + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; + MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state; + + COGL_TRACE_BEGIN_SCOPED (MetaRendererNativeGpuStatePreSwapBuffers, + "Onscreen (secondary gpu pre-swap-buffers)"); + + secondary_gpu_state = onscreen_native->secondary_gpu_state; + if (secondary_gpu_state) + { + MetaRendererNativeGpuData *renderer_gpu_data; + + renderer_gpu_data = secondary_gpu_state->renderer_gpu_data; + switch (renderer_gpu_data->secondary.copy_mode) + { + case META_SHARED_FRAMEBUFFER_COPY_MODE_SECONDARY_GPU: + /* Done after eglSwapBuffers. */ + break; + case META_SHARED_FRAMEBUFFER_COPY_MODE_ZERO: + /* Done after eglSwapBuffers. */ + if (secondary_gpu_state->import_status == + META_SHARED_FRAMEBUFFER_IMPORT_STATUS_OK) + break; + /* prepare fallback */ + G_GNUC_FALLTHROUGH; + case META_SHARED_FRAMEBUFFER_COPY_MODE_PRIMARY: + if (!copy_shared_framebuffer_primary_gpu (onscreen, + secondary_gpu_state)) + { + if (!secondary_gpu_state->noted_primary_gpu_copy_failed) + { + g_debug ("Using primary GPU to copy for %s failed once.", + meta_gpu_kms_get_file_path (secondary_gpu_state->gpu_kms)); + secondary_gpu_state->noted_primary_gpu_copy_failed = TRUE; + } + + copy_shared_framebuffer_cpu (onscreen, + secondary_gpu_state, + renderer_gpu_data); + } + else if (!secondary_gpu_state->noted_primary_gpu_copy_ok) + { + g_debug ("Using primary GPU to copy for %s succeeded once.", + meta_gpu_kms_get_file_path (secondary_gpu_state->gpu_kms)); + secondary_gpu_state->noted_primary_gpu_copy_ok = TRUE; + } + break; + } + } +} + +static void +update_secondary_gpu_state_post_swap_buffers (CoglOnscreen *onscreen, + gboolean *egl_context_changed) +{ + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; + MetaRendererNative *renderer_native = onscreen_native->renderer_native; + MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state; + + COGL_TRACE_BEGIN_SCOPED (MetaRendererNativeGpuStatePostSwapBuffers, + "Onscreen (secondary gpu post-swap-buffers)"); + + secondary_gpu_state = onscreen_native->secondary_gpu_state; + if (secondary_gpu_state) + { + MetaRendererNativeGpuData *renderer_gpu_data; + + renderer_gpu_data = + meta_renderer_native_get_gpu_data (renderer_native, + secondary_gpu_state->gpu_kms); +retry: + switch (renderer_gpu_data->secondary.copy_mode) + { + case META_SHARED_FRAMEBUFFER_COPY_MODE_ZERO: + if (!import_shared_framebuffer (onscreen, + secondary_gpu_state)) + goto retry; + break; + case META_SHARED_FRAMEBUFFER_COPY_MODE_SECONDARY_GPU: + copy_shared_framebuffer_gpu (onscreen, + secondary_gpu_state, + renderer_gpu_data, + egl_context_changed); + break; + case META_SHARED_FRAMEBUFFER_COPY_MODE_PRIMARY: + /* Done before eglSwapBuffers. */ + break; + } + } +} + +static MetaKmsUpdate * +unset_disabled_crtcs (MetaBackend *backend, + MetaKms *kms) +{ + MetaKmsUpdate *kms_update = NULL; + GList *l; + + for (l = meta_backend_get_gpus (backend); l; l = l->next) + { + MetaGpu *gpu = l->data; + GList *k; + + for (k = meta_gpu_get_crtcs (gpu); k; k = k->next) + { + MetaCrtc *crtc = k->data; + + if (crtc->config) + continue; + + kms_update = meta_kms_ensure_pending_update (kms); + meta_crtc_kms_set_mode (crtc, kms_update); + } + } + + return kms_update; +} + +static void +post_pending_update (MetaKms *kms) +{ + g_autoptr (MetaKmsFeedback) kms_feedback = NULL; + + kms_feedback = meta_kms_post_pending_update_sync (kms); + if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED) + { + const GError *error = meta_kms_feedback_get_error (kms_feedback); + + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED)) + g_warning ("Failed to post KMS update: %s", error->message); + } +} + +static void +meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, + const int *rectangles, + int n_rectangles) +{ + CoglContext *cogl_context = COGL_FRAMEBUFFER (onscreen)->context; + CoglDisplay *cogl_display = cogl_context_get_display (cogl_context); + CoglRenderer *cogl_renderer = cogl_context->display->renderer; + CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys; + MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform; + MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native; + MetaRenderer *renderer = META_RENDERER (renderer_native); + MetaBackend *backend = meta_renderer_get_backend (renderer); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend); + MetaKms *kms = meta_backend_native_get_kms (backend_native); + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; + MetaGpuKms *render_gpu = onscreen_native->render_gpu; + CoglFrameInfo *frame_info; + gboolean egl_context_changed = FALSE; + MetaKmsUpdate *kms_update; + MetaPowerSave power_save_mode; + g_autoptr (GError) error = NULL; + MetaDrmBufferGbm *buffer_gbm; + g_autoptr (MetaKmsFeedback) kms_feedback = NULL; + + COGL_TRACE_BEGIN_SCOPED (MetaRendererNativeSwapBuffers, + "Onscreen (swap-buffers)"); + + kms_update = meta_kms_ensure_pending_update (kms); + + /* + * Wait for the flip callback before continuing, as we might have started the + * animation earlier due to the animation being driven by some other monitor. + */ + COGL_TRACE_BEGIN (MetaRendererNativeSwapBuffersWait, + "Onscreen (waiting for page flips)"); + wait_for_pending_flips (onscreen); + COGL_TRACE_END (MetaRendererNativeSwapBuffersWait); + + frame_info = g_queue_peek_tail (&onscreen->pending_frame_infos); + frame_info->global_frame_counter = renderer_native->frame_counter; + + update_secondary_gpu_state_pre_swap_buffers (onscreen); + + parent_vtable->onscreen_swap_buffers_with_damage (onscreen, + rectangles, + n_rectangles); + + renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native, + render_gpu); + switch (renderer_gpu_data->mode) + { + case META_RENDERER_NATIVE_MODE_GBM: + g_warn_if_fail (onscreen_native->gbm.next_fb == NULL); + g_clear_object (&onscreen_native->gbm.next_fb); + + buffer_gbm = meta_drm_buffer_gbm_new (render_gpu, + onscreen_native->gbm.surface, + renderer_native->use_modifiers, + &error); + if (!buffer_gbm) + { + g_warning ("meta_drm_buffer_gbm_new failed: %s", + error->message); + return; + } + + onscreen_native->gbm.next_fb = META_DRM_BUFFER (buffer_gbm); + + break; +#ifdef HAVE_EGL_DEVICE + case META_RENDERER_NATIVE_MODE_EGL_DEVICE: + break; +#endif + } + + update_secondary_gpu_state_post_swap_buffers (onscreen, &egl_context_changed); + + /* If this is the first framebuffer to be presented then we now setup the + * crtc modes, else we flip from the previous buffer */ + + power_save_mode = meta_monitor_manager_get_power_save_mode (monitor_manager); + if (onscreen_native->pending_set_crtc && + power_save_mode == META_POWER_SAVE_ON) + { + meta_onscreen_native_set_crtc_mode (onscreen, + renderer_gpu_data, + kms_update); + onscreen_native->pending_set_crtc = FALSE; + } + + onscreen_native->pending_queue_swap_notify_frame_count = renderer_native->frame_counter; + meta_onscreen_native_flip_crtcs (onscreen, kms_update); + + /* + * If we changed EGL context, cogl will have the wrong idea about what is + * current, making it fail to set it when it needs to. Avoid that by making + * EGL_NO_CONTEXT current now, making cogl eventually set the correct + * context. + */ + if (egl_context_changed) + _cogl_winsys_egl_ensure_current (cogl_display); + + COGL_TRACE_BEGIN (MetaRendererNativePostKmsUpdate, + "Onscreen (post pending update)"); + post_pending_update (kms); + COGL_TRACE_END (MetaRendererNativePostKmsUpdate); +} + +static CoglDmaBufHandle * +meta_renderer_native_create_dma_buf (CoglRenderer *cogl_renderer, + int width, + int height, + GError **error) +{ + CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys; + MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform; + MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native; + + switch (renderer_gpu_data->mode) + { + case META_RENDERER_NATIVE_MODE_GBM: + { + CoglFramebuffer *dmabuf_fb; + CoglDmaBufHandle *dmabuf_handle; + struct gbm_bo *new_bo; + int dmabuf_fd = -1; + + new_bo = gbm_bo_create (renderer_gpu_data->gbm.device, + width, height, DRM_FORMAT_XRGB8888, + GBM_BO_USE_RENDERING | GBM_BO_USE_LINEAR); + + if (!new_bo) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Failed to allocate buffer"); + return NULL; + } + + dmabuf_fd = gbm_bo_get_fd (new_bo); + + if (dmabuf_fd == -1) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS, + "Failed to export buffer's DMA fd: %s", + g_strerror (errno)); + return NULL; + } + + dmabuf_fb = create_dma_buf_framebuffer (renderer_native, + dmabuf_fd, + width, height, + gbm_bo_get_stride (new_bo), + gbm_bo_get_offset (new_bo, 0), + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_XRGB8888, + error); + + if (!dmabuf_fb) + return NULL; + + dmabuf_handle = + cogl_dma_buf_handle_new (dmabuf_fb, dmabuf_fd, new_bo, + (GDestroyNotify) gbm_bo_destroy); + cogl_object_unref (dmabuf_fb); + return dmabuf_handle; + } + break; +#ifdef HAVE_EGL_DEVICE + case META_RENDERER_NATIVE_MODE_EGL_DEVICE: + break; +#endif + } + + g_set_error (error, G_IO_ERROR, G_IO_ERROR_UNKNOWN, + "Current mode does not support exporting DMA buffers"); + + return NULL; +} + +static gboolean +meta_renderer_native_init_egl_context (CoglContext *cogl_context, + GError **error) +{ +#ifdef HAVE_EGL_DEVICE + CoglRenderer *cogl_renderer = cogl_context->display->renderer; + CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys; + MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform; +#endif + + COGL_FLAGS_SET (cogl_context->features, + COGL_FEATURE_ID_PRESENTATION_TIME, TRUE); + COGL_FLAGS_SET (cogl_context->features, + COGL_FEATURE_ID_SWAP_BUFFERS_EVENT, TRUE); + /* TODO: remove this deprecated feature */ + COGL_FLAGS_SET (cogl_context->winsys_features, + COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT, + TRUE); + COGL_FLAGS_SET (cogl_context->winsys_features, + COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT, + TRUE); + COGL_FLAGS_SET (cogl_context->winsys_features, + COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN, + TRUE); + + /* COGL_WINSYS_FEATURE_SWAP_THROTTLE is always true for this renderer + * because we have the call to wait_for_pending_flips on every frame. + */ + COGL_FLAGS_SET (cogl_context->winsys_features, + COGL_WINSYS_FEATURE_SWAP_THROTTLE, + TRUE); + +#ifdef HAVE_EGL_DEVICE + if (renderer_gpu_data->mode == META_RENDERER_NATIVE_MODE_EGL_DEVICE) + COGL_FLAGS_SET (cogl_context->features, + COGL_FEATURE_ID_TEXTURE_EGL_IMAGE_EXTERNAL, TRUE); +#endif + + return TRUE; +} + +static gboolean +should_surface_be_sharable (CoglOnscreen *onscreen) +{ + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; + + if (META_GPU_KMS (meta_crtc_get_gpu (onscreen_native->crtc)) == + onscreen_native->render_gpu) + return FALSE; + else + return TRUE; +} + +static gboolean +meta_renderer_native_create_surface_gbm (CoglOnscreen *onscreen, + int width, + int height, + struct gbm_surface **gbm_surface, + EGLSurface *egl_surface, + GError **error) +{ + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; + MetaRendererNative *renderer_native = onscreen_native->renderer_native; + MetaEgl *egl = meta_onscreen_native_get_egl (onscreen_native); + CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); + CoglContext *cogl_context = framebuffer->context; + CoglDisplay *cogl_display = cogl_context->display; + CoglDisplayEGL *cogl_display_egl = cogl_display->winsys; + CoglRenderer *cogl_renderer = cogl_display->renderer; + CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys; + MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform; + struct gbm_surface *new_gbm_surface = NULL; + EGLNativeWindowType egl_native_window; + EGLSurface new_egl_surface; + uint32_t format = GBM_FORMAT_XRGB8888; + GArray *modifiers; + + renderer_gpu_data = + meta_renderer_native_get_gpu_data (renderer_native, + onscreen_native->render_gpu); + + if (renderer_native->use_modifiers) + modifiers = get_supported_modifiers (onscreen, format); + else + modifiers = NULL; + + if (modifiers) + { + new_gbm_surface = + gbm_surface_create_with_modifiers (renderer_gpu_data->gbm.device, + width, height, format, + (uint64_t *) modifiers->data, + modifiers->len); + g_array_free (modifiers, TRUE); + } + + if (!new_gbm_surface) + { + uint32_t flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING; + + if (should_surface_be_sharable (onscreen)) + flags |= GBM_BO_USE_LINEAR; + + new_gbm_surface = gbm_surface_create (renderer_gpu_data->gbm.device, + width, height, + format, + flags); + } + + if (!new_gbm_surface) + { + g_set_error (error, COGL_WINSYS_ERROR, + COGL_WINSYS_ERROR_CREATE_ONSCREEN, + "Failed to allocate surface"); + return FALSE; + } + + egl_native_window = (EGLNativeWindowType) new_gbm_surface; + new_egl_surface = + meta_egl_create_window_surface (egl, + cogl_renderer_egl->edpy, + cogl_display_egl->egl_config, + egl_native_window, + NULL, + error); + if (new_egl_surface == EGL_NO_SURFACE) + { + gbm_surface_destroy (new_gbm_surface); + return FALSE; + } + + *gbm_surface = new_gbm_surface; + *egl_surface = new_egl_surface; + + return TRUE; +} + +#ifdef HAVE_EGL_DEVICE +static gboolean +meta_renderer_native_create_surface_egl_device (CoglOnscreen *onscreen, + int width, + int height, + EGLStreamKHR *out_egl_stream, + EGLSurface *out_egl_surface, + GError **error) +{ + CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; + CoglContext *cogl_context = framebuffer->context; + CoglDisplay *cogl_display = cogl_context->display; + CoglDisplayEGL *cogl_display_egl = cogl_display->winsys; + CoglRenderer *cogl_renderer = cogl_display->renderer; + CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys; + MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform; + MetaEgl *egl = + meta_renderer_native_get_egl (renderer_gpu_data->renderer_native); + EGLDisplay egl_display = renderer_gpu_data->egl_display; + EGLConfig egl_config; + EGLStreamKHR egl_stream; + EGLSurface egl_surface; + EGLint num_layers; + EGLOutputLayerEXT output_layer; + EGLAttrib output_attribs[3]; + EGLint stream_attribs[] = { + EGL_STREAM_FIFO_LENGTH_KHR, 0, + EGL_CONSUMER_AUTO_ACQUIRE_EXT, EGL_FALSE, + EGL_NONE + }; + EGLint stream_producer_attribs[] = { + EGL_WIDTH, width, + EGL_HEIGHT, height, + EGL_NONE + }; + + egl_stream = meta_egl_create_stream (egl, egl_display, stream_attribs, error); + if (egl_stream == EGL_NO_STREAM_KHR) + return FALSE; + + output_attribs[0] = EGL_DRM_CRTC_EXT; + output_attribs[1] = onscreen_native->crtc->crtc_id; + output_attribs[2] = EGL_NONE; + + if (!meta_egl_get_output_layers (egl, egl_display, + output_attribs, + &output_layer, 1, &num_layers, + error)) + { + meta_egl_destroy_stream (egl, egl_display, egl_stream, NULL); + return FALSE; + } + + if (num_layers < 1) + { + meta_egl_destroy_stream (egl, egl_display, egl_stream, NULL); + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_FAILED, + "Unable to find output layers."); + return FALSE; + } + + if (!meta_egl_stream_consumer_output (egl, egl_display, + egl_stream, output_layer, + error)) + { + meta_egl_destroy_stream (egl, egl_display, egl_stream, NULL); + return FALSE; + } + + egl_config = cogl_display_egl->egl_config; + egl_surface = meta_egl_create_stream_producer_surface (egl, + egl_display, + egl_config, + egl_stream, + stream_producer_attribs, + error); + if (egl_surface == EGL_NO_SURFACE) + { + meta_egl_destroy_stream (egl, egl_display, egl_stream, NULL); + return FALSE; + } + + *out_egl_stream = egl_stream; + *out_egl_surface = egl_surface; + + return TRUE; +} +#endif /* HAVE_EGL_DEVICE */ + +static gboolean +init_dumb_fb (MetaDumbBuffer *dumb_fb, + MetaGpuKms *gpu_kms, + int width, + int height, + uint32_t format, + GError **error) +{ + struct drm_mode_create_dumb create_arg; + struct drm_mode_destroy_dumb destroy_arg; + struct drm_mode_map_dumb map_arg; + uint32_t fb_id = 0; + void *map; + int kms_fd; + MetaGpuKmsFBArgs fb_args = { + .width = width, + .height = height, + .format = format, + }; + + kms_fd = meta_gpu_kms_get_fd (gpu_kms); + + create_arg = (struct drm_mode_create_dumb) { + .bpp = 32, /* RGBX8888 */ + .width = width, + .height = height + }; + if (drmIoctl (kms_fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_arg) != 0) + { + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_FAILED, + "Failed to create dumb drm buffer: %s", + g_strerror (errno)); + goto err_ioctl; + } + + fb_args.handles[0] = create_arg.handle; + fb_args.strides[0] = create_arg.pitch; + + if (!meta_gpu_kms_add_fb (gpu_kms, FALSE, &fb_args, &fb_id, error)) + goto err_add_fb; + + map_arg = (struct drm_mode_map_dumb) { + .handle = create_arg.handle + }; + if (drmIoctl (kms_fd, DRM_IOCTL_MODE_MAP_DUMB, + &map_arg) != 0) + { + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_FAILED, + "Failed to map dumb drm buffer: %s", + g_strerror (errno)); + goto err_map_dumb; + } + + map = mmap (NULL, create_arg.size, PROT_WRITE, MAP_SHARED, + kms_fd, map_arg.offset); + if (map == MAP_FAILED) + { + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_FAILED, + "Failed to mmap dumb drm buffer memory: %s", + g_strerror (errno)); + goto err_mmap; + } + + dumb_fb->fb_id = fb_id; + dumb_fb->handle = create_arg.handle; + dumb_fb->map = map; + dumb_fb->map_size = create_arg.size; + dumb_fb->width = width; + dumb_fb->height = height; + dumb_fb->stride_bytes = create_arg.pitch; + dumb_fb->drm_format = format; + dumb_fb->dmabuf_fd = -1; + + return TRUE; + +err_mmap: +err_map_dumb: + drmModeRmFB (kms_fd, fb_id); + +err_add_fb: + destroy_arg = (struct drm_mode_destroy_dumb) { + .handle = create_arg.handle + }; + drmIoctl (kms_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_arg); + +err_ioctl: + return FALSE; +} + +static int +meta_dumb_buffer_ensure_dmabuf_fd (MetaDumbBuffer *dumb_fb, + MetaGpuKms *gpu_kms) +{ + int ret; + int kms_fd; + int dmabuf_fd; + + if (dumb_fb->dmabuf_fd != -1) + return dumb_fb->dmabuf_fd; + + kms_fd = meta_gpu_kms_get_fd (gpu_kms); + + ret = drmPrimeHandleToFD (kms_fd, dumb_fb->handle, DRM_CLOEXEC, + &dmabuf_fd); + if (ret) + { + g_debug ("Failed to export dumb drm buffer: %s", + g_strerror (errno)); + return -1; + } + + dumb_fb->dmabuf_fd = dmabuf_fd; + + return dumb_fb->dmabuf_fd; +} + +static void +release_dumb_fb (MetaDumbBuffer *dumb_fb, + MetaGpuKms *gpu_kms) +{ + struct drm_mode_destroy_dumb destroy_arg; + int kms_fd; + + if (!dumb_fb->map) + return; + + if (dumb_fb->dmabuf_fd != -1) + close (dumb_fb->dmabuf_fd); + + munmap (dumb_fb->map, dumb_fb->map_size); + + kms_fd = meta_gpu_kms_get_fd (gpu_kms); + + drmModeRmFB (kms_fd, dumb_fb->fb_id); + + destroy_arg = (struct drm_mode_destroy_dumb) { + .handle = dumb_fb->handle + }; + drmIoctl (kms_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_arg); + + *dumb_fb = (MetaDumbBuffer) { + .dmabuf_fd = -1, + }; +} + +static gboolean +meta_renderer_native_init_onscreen (CoglOnscreen *onscreen, + GError **error) +{ + CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); + CoglContext *cogl_context = framebuffer->context; + CoglDisplay *cogl_display = cogl_context->display; + CoglDisplayEGL *cogl_display_egl = cogl_display->winsys; + CoglOnscreenEGL *onscreen_egl; + MetaOnscreenNative *onscreen_native; + + g_return_val_if_fail (cogl_display_egl->egl_context, FALSE); + + onscreen->winsys = g_slice_new0 (CoglOnscreenEGL); + onscreen_egl = onscreen->winsys; + + onscreen_native = g_slice_new0 (MetaOnscreenNative); + onscreen_egl->platform = onscreen_native; + + /* + * Don't actually initialize anything here, since we may not have the + * information available yet, and there is no way to pass it at this stage. + * To properly allocate a MetaOnscreenNative, the caller must call + * meta_onscreen_native_allocate() after cogl_framebuffer_allocate(). + * + * TODO: Turn CoglFramebuffer/CoglOnscreen into GObjects, so it's possible + * to add backend specific properties. + */ + + return TRUE; +} + +static gboolean +meta_onscreen_native_allocate (CoglOnscreen *onscreen, + GError **error) +{ + CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; + MetaRendererNativeGpuData *renderer_gpu_data; + struct gbm_surface *gbm_surface; + EGLSurface egl_surface; + int width; + int height; +#ifdef HAVE_EGL_DEVICE + EGLStreamKHR egl_stream; +#endif + + onscreen_native->pending_set_crtc = TRUE; + + /* If a kms_fd is set then the display width and height + * won't be available until meta_renderer_native_set_layout + * is called. In that case, defer creating the surface + * until then. + */ + width = cogl_framebuffer_get_width (framebuffer); + height = cogl_framebuffer_get_height (framebuffer); + if (width == 0 || height == 0) + return TRUE; + + renderer_gpu_data = + meta_renderer_native_get_gpu_data (onscreen_native->renderer_native, + onscreen_native->render_gpu); + switch (renderer_gpu_data->mode) + { + case META_RENDERER_NATIVE_MODE_GBM: + if (!meta_renderer_native_create_surface_gbm (onscreen, + width, height, + &gbm_surface, + &egl_surface, + error)) + return FALSE; + + onscreen_native->gbm.surface = gbm_surface; + onscreen_egl->egl_surface = egl_surface; + break; +#ifdef HAVE_EGL_DEVICE + case META_RENDERER_NATIVE_MODE_EGL_DEVICE: + if (!init_dumb_fb (&onscreen_native->egl.dumb_fb, + onscreen_native->render_gpu, + width, height, + DRM_FORMAT_XRGB8888, + error)) + return FALSE; + + if (!meta_renderer_native_create_surface_egl_device (onscreen, + width, height, + &egl_stream, + &egl_surface, + error)) + return FALSE; + + onscreen_native->egl.stream = egl_stream; + onscreen_egl->egl_surface = egl_surface; + break; +#endif /* HAVE_EGL_DEVICE */ + } + + return TRUE; +} + +static void +destroy_egl_surface (CoglOnscreen *onscreen) +{ + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + + if (onscreen_egl->egl_surface != EGL_NO_SURFACE) + { + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; + MetaEgl *egl = meta_onscreen_native_get_egl (onscreen_native); + CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); + CoglContext *cogl_context = framebuffer->context; + CoglRenderer *cogl_renderer = cogl_context->display->renderer; + CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys; + + meta_egl_destroy_surface (egl, + cogl_renderer_egl->edpy, + onscreen_egl->egl_surface, + NULL); + onscreen_egl->egl_surface = EGL_NO_SURFACE; + } +} + +static void +meta_renderer_native_release_onscreen (CoglOnscreen *onscreen) +{ + CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); + CoglContext *cogl_context = framebuffer->context; + CoglDisplay *cogl_display = cogl_context_get_display (cogl_context); + CoglDisplayEGL *cogl_display_egl = cogl_display->winsys; + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + MetaOnscreenNative *onscreen_native; + MetaRendererNative *renderer_native; + MetaRendererNativeGpuData *renderer_gpu_data; + + /* If we never successfully allocated then there's nothing to do */ + if (onscreen_egl == NULL) + return; + + onscreen_native = onscreen_egl->platform; + renderer_native = onscreen_native->renderer_native; + + if (onscreen_egl->egl_surface != EGL_NO_SURFACE && + (cogl_display_egl->current_draw_surface == onscreen_egl->egl_surface || + cogl_display_egl->current_read_surface == onscreen_egl->egl_surface)) + { + if (!_cogl_winsys_egl_make_current (cogl_display, + cogl_display_egl->dummy_surface, + cogl_display_egl->dummy_surface, + cogl_display_egl->egl_context)) + g_warning ("Failed to clear current context"); + } + + renderer_gpu_data = + meta_renderer_native_get_gpu_data (renderer_native, + onscreen_native->render_gpu); + switch (renderer_gpu_data->mode) + { + case META_RENDERER_NATIVE_MODE_GBM: + /* flip state takes a reference on the onscreen so there should + * never be outstanding flips when we reach here. */ + g_return_if_fail (onscreen_native->gbm.next_fb == NULL); + + free_current_bo (onscreen); + + destroy_egl_surface (onscreen); + + if (onscreen_native->gbm.surface) + { + gbm_surface_destroy (onscreen_native->gbm.surface); + onscreen_native->gbm.surface = NULL; + } + break; +#ifdef HAVE_EGL_DEVICE + case META_RENDERER_NATIVE_MODE_EGL_DEVICE: + release_dumb_fb (&onscreen_native->egl.dumb_fb, + onscreen_native->render_gpu); + + destroy_egl_surface (onscreen); + + if (onscreen_native->egl.stream != EGL_NO_STREAM_KHR) + { + MetaEgl *egl = meta_onscreen_native_get_egl (onscreen_native); + CoglRenderer *cogl_renderer = cogl_context->display->renderer; + CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys; + + meta_egl_destroy_stream (egl, + cogl_renderer_egl->edpy, + onscreen_native->egl.stream, + NULL); + onscreen_native->egl.stream = EGL_NO_STREAM_KHR; + } + break; +#endif /* HAVE_EGL_DEVICE */ + } + + g_clear_pointer (&onscreen_native->secondary_gpu_state, + secondary_gpu_state_free); + + g_slice_free (MetaOnscreenNative, onscreen_native); + g_slice_free (CoglOnscreenEGL, onscreen->winsys); + onscreen->winsys = NULL; +} + +static const CoglWinsysEGLVtable +_cogl_winsys_egl_vtable = { + .add_config_attributes = meta_renderer_native_add_egl_config_attributes, + .choose_config = meta_renderer_native_choose_egl_config, + .display_setup = meta_renderer_native_setup_egl_display, + .display_destroy = meta_renderer_native_destroy_egl_display, + .context_created = meta_renderer_native_egl_context_created, + .cleanup_context = meta_renderer_native_egl_cleanup_context, + .context_init = meta_renderer_native_init_egl_context +}; + +static void +meta_renderer_native_queue_modes_reset (MetaRendererNative *renderer_native) +{ + MetaRenderer *renderer = META_RENDERER (renderer_native); + GList *l; + + for (l = meta_renderer_get_views (renderer); l; l = l->next) + { + ClutterStageView *stage_view = l->data; + CoglFramebuffer *framebuffer = + clutter_stage_view_get_onscreen (stage_view); + CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer); + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; + + onscreen_native->pending_set_crtc = TRUE; + } + + renderer_native->pending_unset_disabled_crtcs = TRUE; +} + +static CoglOnscreen * +meta_renderer_native_create_onscreen (MetaRendererNative *renderer_native, + MetaGpuKms *render_gpu, + MetaOutput *output, + MetaCrtc *crtc, + CoglContext *context, + int width, + int height, + GError **error) +{ + CoglOnscreen *onscreen; + CoglOnscreenEGL *onscreen_egl; + MetaOnscreenNative *onscreen_native; + + onscreen = cogl_onscreen_new (context, width, height); + + if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (onscreen), error)) + { + cogl_object_unref (onscreen); + return NULL; + } + + onscreen_egl = onscreen->winsys; + onscreen_native = onscreen_egl->platform; + onscreen_native->renderer_native = renderer_native; + onscreen_native->render_gpu = render_gpu; + onscreen_native->output = output; + onscreen_native->crtc = crtc; + + if (META_GPU_KMS (meta_crtc_get_gpu (crtc)) != render_gpu) + { + if (!init_secondary_gpu_state (renderer_native, onscreen, error)) + { + cogl_object_unref (onscreen); + return NULL; + } + } + + return onscreen; +} + +static CoglOffscreen * +meta_renderer_native_create_offscreen (MetaRendererNative *renderer, + CoglContext *context, + gint view_width, + gint view_height, + GError **error) +{ + CoglOffscreen *fb; + CoglTexture2D *tex; + + tex = cogl_texture_2d_new_with_size (context, view_width, view_height); + cogl_primitive_texture_set_auto_mipmap (COGL_PRIMITIVE_TEXTURE (tex), FALSE); + + if (!cogl_texture_allocate (COGL_TEXTURE (tex), error)) + { + cogl_object_unref (tex); + return FALSE; + } + + fb = cogl_offscreen_new_with_texture (COGL_TEXTURE (tex)); + cogl_object_unref (tex); + if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (fb), error)) + { + cogl_object_unref (fb); + return FALSE; + } + + return fb; +} + +static int64_t +meta_renderer_native_get_clock_time (CoglContext *context) +{ + CoglRenderer *cogl_renderer = cogl_context_get_renderer (context); + MetaGpuKms *gpu_kms = cogl_renderer->custom_winsys_user_data; + + return meta_gpu_kms_get_current_time_ns (gpu_kms); +} + +static const CoglWinsysVtable * +get_native_cogl_winsys_vtable (CoglRenderer *cogl_renderer) +{ + static gboolean vtable_inited = FALSE; + static CoglWinsysVtable vtable; + + if (!vtable_inited) + { + /* The this winsys is a subclass of the EGL winsys so we + start by copying its vtable */ + + parent_vtable = _cogl_winsys_egl_get_vtable (); + vtable = *parent_vtable; + + vtable.id = COGL_WINSYS_ID_CUSTOM; + vtable.name = "EGL_KMS"; + + vtable.renderer_connect = meta_renderer_native_connect; + vtable.renderer_disconnect = meta_renderer_native_disconnect; + vtable.renderer_create_dma_buf = meta_renderer_native_create_dma_buf; + + vtable.onscreen_init = meta_renderer_native_init_onscreen; + vtable.onscreen_deinit = meta_renderer_native_release_onscreen; + + /* The KMS winsys doesn't support swap region */ + vtable.onscreen_swap_region = NULL; + vtable.onscreen_swap_buffers_with_damage = + meta_onscreen_native_swap_buffers_with_damage; + + vtable.context_get_clock_time = meta_renderer_native_get_clock_time; + + vtable_inited = TRUE; + } + + return &vtable; +} + +static CoglRenderer * +create_cogl_renderer_for_gpu (MetaGpuKms *gpu_kms) +{ + CoglRenderer *cogl_renderer; + + cogl_renderer = cogl_renderer_new (); + cogl_renderer_set_custom_winsys (cogl_renderer, + get_native_cogl_winsys_vtable, + gpu_kms); + + return cogl_renderer; +} + +static CoglRenderer * +meta_renderer_native_create_cogl_renderer (MetaRenderer *renderer) +{ + MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer); + + return create_cogl_renderer_for_gpu (renderer_native->primary_gpu_kms); +} + +static void +meta_onscreen_native_set_view (CoglOnscreen *onscreen, + MetaRendererView *view) +{ + CoglOnscreenEGL *onscreen_egl; + MetaOnscreenNative *onscreen_native; + + onscreen_egl = onscreen->winsys; + onscreen_native = onscreen_egl->platform; + onscreen_native->view = view; +} + +static MetaMonitorTransform +calculate_view_transform (MetaMonitorManager *monitor_manager, + MetaLogicalMonitor *logical_monitor, + MetaOutput *output, + MetaCrtc *crtc) +{ + MetaMonitorTransform crtc_transform; + + crtc = meta_output_get_assigned_crtc (output); + crtc_transform = + meta_output_logical_to_crtc_transform (output, logical_monitor->transform); + + if (meta_monitor_manager_is_transform_handled (monitor_manager, + crtc, + crtc_transform)) + return META_MONITOR_TRANSFORM_NORMAL; + else + return crtc_transform; +} + +static gboolean +should_force_shadow_fb (MetaRendererNative *renderer_native, + MetaGpuKms *primary_gpu) +{ + MetaRenderer *renderer = META_RENDERER (renderer_native); + int kms_fd; + uint64_t prefer_shadow = 0; + + if (meta_renderer_is_hardware_accelerated (renderer)) + return FALSE; + + kms_fd = meta_gpu_kms_get_fd (primary_gpu); + if (drmGetCap (kms_fd, DRM_CAP_DUMB_PREFER_SHADOW, &prefer_shadow) == 0) + { + if (prefer_shadow) + { + static gboolean logged_once = FALSE; + + if (!logged_once) + { + g_message ("Forcing shadow framebuffer"); + logged_once = TRUE; + } + + return TRUE; + } + } + + return FALSE; +} + +static MetaRendererView * +meta_renderer_native_create_view (MetaRenderer *renderer, + MetaLogicalMonitor *logical_monitor, + MetaOutput *output, + MetaCrtc *crtc) +{ + MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer); + MetaBackend *backend = meta_renderer_get_backend (renderer); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + CoglContext *cogl_context = + cogl_context_from_renderer_native (renderer_native); + CoglDisplay *cogl_display = cogl_context_get_display (cogl_context); + CoglDisplayEGL *cogl_display_egl; + CoglOnscreenEGL *onscreen_egl; + MetaCrtcConfig *crtc_config; + MetaMonitorTransform view_transform; + CoglOnscreen *onscreen = NULL; + CoglOffscreen *offscreen = NULL; + CoglOffscreen *shadowfb = NULL; + float scale; + int onscreen_width; + int onscreen_height; + MetaRectangle view_layout; + MetaRendererView *view; + GError *error = NULL; + + crtc_config = crtc->config; + onscreen_width = crtc_config->mode->width; + onscreen_height = crtc_config->mode->height; + + onscreen = meta_renderer_native_create_onscreen (renderer_native, + renderer_native->primary_gpu_kms, + output, + crtc, + cogl_context, + onscreen_width, + onscreen_height, + &error); + if (!onscreen) + g_error ("Failed to allocate onscreen framebuffer: %s", error->message); + + view_transform = calculate_view_transform (monitor_manager, + logical_monitor, + output, + crtc); + if (view_transform != META_MONITOR_TRANSFORM_NORMAL) + { + int offscreen_width; + int offscreen_height; + + if (meta_monitor_transform_is_rotated (view_transform)) + { + offscreen_width = onscreen_height; + offscreen_height = onscreen_width; + } + else + { + offscreen_width = onscreen_width; + offscreen_height = onscreen_height; + } + + offscreen = meta_renderer_native_create_offscreen (renderer_native, + cogl_context, + offscreen_width, + offscreen_height, + &error); + if (!offscreen) + g_error ("Failed to allocate back buffer texture: %s", error->message); + } + + if (should_force_shadow_fb (renderer_native, + renderer_native->primary_gpu_kms)) + { + int shadow_width; + int shadow_height; + + /* The shadowfb must be the same size as the on-screen framebuffer */ + shadow_width = cogl_framebuffer_get_width (COGL_FRAMEBUFFER (onscreen)); + shadow_height = cogl_framebuffer_get_height (COGL_FRAMEBUFFER (onscreen)); + + shadowfb = meta_renderer_native_create_offscreen (renderer_native, + cogl_context, + shadow_width, + shadow_height, + &error); + if (!shadowfb) + g_error ("Failed to allocate shadow buffer texture: %s", error->message); + } + + if (meta_is_stage_views_scaled ()) + scale = meta_logical_monitor_get_scale (logical_monitor); + else + scale = 1.0; + + meta_rectangle_from_graphene_rect (&crtc->config->layout, + META_ROUNDING_STRATEGY_ROUND, + &view_layout); + view = g_object_new (META_TYPE_RENDERER_VIEW, + "layout", &view_layout, + "scale", scale, + "framebuffer", onscreen, + "offscreen", offscreen, + "shadowfb", shadowfb, + "transform", view_transform, + NULL); + g_clear_pointer (&offscreen, cogl_object_unref); + g_clear_pointer (&shadowfb, cogl_object_unref); + + meta_onscreen_native_set_view (onscreen, view); + + if (!meta_onscreen_native_allocate (onscreen, &error)) + { + g_warning ("Could not create onscreen: %s", error->message); + cogl_object_unref (onscreen); + g_object_unref (view); + g_error_free (error); + return NULL; + } + + cogl_object_unref (onscreen); + + /* Ensure we don't point to stale surfaces when creating the offscreen */ + onscreen_egl = onscreen->winsys; + cogl_display_egl = cogl_display->winsys; + _cogl_winsys_egl_make_current (cogl_display, + onscreen_egl->egl_surface, + onscreen_egl->egl_surface, + cogl_display_egl->egl_context); + + return view; +} + +static void +meta_renderer_native_rebuild_views (MetaRenderer *renderer) +{ + MetaBackend *backend = meta_renderer_get_backend (renderer); + MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend); + MetaKms *kms = meta_backend_native_get_kms (backend_native); + MetaRendererClass *parent_renderer_class = + META_RENDERER_CLASS (meta_renderer_native_parent_class); + + meta_kms_discard_pending_page_flips (kms); + + parent_renderer_class->rebuild_views (renderer); + + meta_renderer_native_queue_modes_reset (META_RENDERER_NATIVE (renderer)); +} + +void +meta_renderer_native_finish_frame (MetaRendererNative *renderer_native) +{ + MetaRenderer *renderer = META_RENDERER (renderer_native); + MetaBackend *backend = meta_renderer_get_backend (renderer); + MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend); + MetaKms *kms = meta_backend_native_get_kms (backend_native); + MetaKmsUpdate *kms_update = NULL; + + renderer_native->frame_counter++; + + if (renderer_native->pending_unset_disabled_crtcs) + { + kms_update = unset_disabled_crtcs (backend, kms); + renderer_native->pending_unset_disabled_crtcs = FALSE; + } + + if (kms_update) + post_pending_update (kms); +} + +int64_t +meta_renderer_native_get_frame_counter (MetaRendererNative *renderer_native) +{ + return renderer_native->frame_counter; +} + +static gboolean +create_secondary_egl_config (MetaEgl *egl, + MetaRendererNativeMode mode, + EGLDisplay egl_display, + EGLConfig *egl_config, + GError **error) +{ + EGLint attributes[] = { + EGL_RED_SIZE, 1, + EGL_GREEN_SIZE, 1, + EGL_BLUE_SIZE, 1, + EGL_ALPHA_SIZE, EGL_DONT_CARE, + EGL_BUFFER_SIZE, EGL_DONT_CARE, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT, + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_NONE + }; + + switch (mode) + { + case META_RENDERER_NATIVE_MODE_GBM: + return choose_egl_config_from_gbm_format (egl, + egl_display, + attributes, + GBM_FORMAT_XRGB8888, + egl_config, + error); +#ifdef HAVE_EGL_DEVICE + case META_RENDERER_NATIVE_MODE_EGL_DEVICE: + return meta_egl_choose_first_config (egl, + egl_display, + attributes, + egl_config, + error); +#endif + } + + return FALSE; +} + +static EGLContext +create_secondary_egl_context (MetaEgl *egl, + EGLDisplay egl_display, + EGLConfig egl_config, + GError **error) +{ + EGLint attributes[] = { + EGL_CONTEXT_CLIENT_VERSION, 3, + EGL_NONE + }; + + return meta_egl_create_context (egl, + egl_display, + egl_config, + EGL_NO_CONTEXT, + attributes, + error); +} + +static void +meta_renderer_native_ensure_gles3 (MetaRendererNative *renderer_native) +{ + MetaEgl *egl = meta_renderer_native_get_egl (renderer_native); + + if (renderer_native->gles3) + return; + + renderer_native->gles3 = meta_gles3_new (egl); +} + +static gboolean +init_secondary_gpu_data_gpu (MetaRendererNativeGpuData *renderer_gpu_data, + GError **error) +{ + MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native; + MetaEgl *egl = meta_renderer_native_get_egl (renderer_native); + EGLDisplay egl_display = renderer_gpu_data->egl_display; + EGLConfig egl_config; + EGLContext egl_context; + const char **missing_gl_extensions; + const char *renderer_str; + + if (!create_secondary_egl_config (egl, renderer_gpu_data->mode, egl_display, + &egl_config, error)) + return FALSE; + + egl_context = create_secondary_egl_context (egl, egl_display, egl_config, error); + if (egl_context == EGL_NO_CONTEXT) + return FALSE; + + meta_renderer_native_ensure_gles3 (renderer_native); + + if (!meta_egl_make_current (egl, + egl_display, + EGL_NO_SURFACE, + EGL_NO_SURFACE, + egl_context, + error)) + { + meta_egl_destroy_context (egl, egl_display, egl_context, NULL); + return FALSE; + } + + renderer_str = (const char *) glGetString (GL_RENDERER); + if (g_str_has_prefix (renderer_str, "llvmpipe") || + g_str_has_prefix (renderer_str, "softpipe") || + g_str_has_prefix (renderer_str, "swrast")) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Do not want to use software renderer (%s), falling back to CPU copy path", + renderer_str); + goto out_fail_with_context; + } + + if (!meta_gles3_has_extensions (renderer_native->gles3, + &missing_gl_extensions, + "GL_OES_EGL_image_external", + NULL)) + { + char *missing_gl_extensions_str; + + missing_gl_extensions_str = g_strjoinv (", ", + (char **) missing_gl_extensions); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Missing OpenGL ES extensions: %s", + missing_gl_extensions_str); + g_free (missing_gl_extensions_str); + g_free (missing_gl_extensions); + + goto out_fail_with_context; + } + + renderer_gpu_data->secondary.is_hardware_rendering = TRUE; + renderer_gpu_data->secondary.egl_context = egl_context; + renderer_gpu_data->secondary.egl_config = egl_config; + renderer_gpu_data->secondary.copy_mode = META_SHARED_FRAMEBUFFER_COPY_MODE_SECONDARY_GPU; + + renderer_gpu_data->secondary.has_EGL_EXT_image_dma_buf_import_modifiers = + meta_egl_has_extensions (egl, egl_display, NULL, + "EGL_EXT_image_dma_buf_import_modifiers", + NULL); + + return TRUE; + +out_fail_with_context: + meta_egl_make_current (egl, + egl_display, + EGL_NO_SURFACE, + EGL_NO_SURFACE, + EGL_NO_CONTEXT, + NULL); + meta_egl_destroy_context (egl, egl_display, egl_context, NULL); + + return FALSE; +} + +static void +init_secondary_gpu_data_cpu (MetaRendererNativeGpuData *renderer_gpu_data) +{ + renderer_gpu_data->secondary.is_hardware_rendering = FALSE; + + /* First try ZERO, it automatically falls back to PRIMARY as needed */ + renderer_gpu_data->secondary.copy_mode = + META_SHARED_FRAMEBUFFER_COPY_MODE_ZERO; +} + +static void +init_secondary_gpu_data (MetaRendererNativeGpuData *renderer_gpu_data) +{ + GError *error = NULL; + + if (init_secondary_gpu_data_gpu (renderer_gpu_data, &error)) + return; + + g_warning ("Failed to initialize accelerated iGPU/dGPU framebuffer sharing: %s", + error->message); + g_error_free (error); + + init_secondary_gpu_data_cpu (renderer_gpu_data); +} + +static gboolean +gpu_kms_is_hardware_rendering (MetaRendererNative *renderer_native, + MetaGpuKms *gpu_kms) +{ + MetaRendererNativeGpuData *data; + + data = meta_renderer_native_get_gpu_data (renderer_native, gpu_kms); + return data->secondary.is_hardware_rendering; +} + +static EGLDisplay +init_gbm_egl_display (MetaRendererNative *renderer_native, + struct gbm_device *gbm_device, + GError **error) +{ + MetaEgl *egl = meta_renderer_native_get_egl (renderer_native); + EGLDisplay egl_display; + + if (!meta_egl_has_extensions (egl, EGL_NO_DISPLAY, NULL, + "EGL_MESA_platform_gbm", + NULL) && + !meta_egl_has_extensions (egl, EGL_NO_DISPLAY, NULL, + "EGL_KHR_platform_gbm", + NULL)) + { + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_FAILED, + "Missing extension for GBM renderer: EGL_KHR_platform_gbm"); + return EGL_NO_DISPLAY; + } + + egl_display = meta_egl_get_platform_display (egl, + EGL_PLATFORM_GBM_KHR, + gbm_device, NULL, error); + if (egl_display == EGL_NO_DISPLAY) + return EGL_NO_DISPLAY; + + if (!meta_egl_initialize (egl, egl_display, error)) + return EGL_NO_DISPLAY; + + return egl_display; +} + +static MetaRendererNativeGpuData * +create_renderer_gpu_data_gbm (MetaRendererNative *renderer_native, + MetaGpuKms *gpu_kms, + GError **error) +{ + struct gbm_device *gbm_device; + int kms_fd; + MetaRendererNativeGpuData *renderer_gpu_data; + g_autoptr (GError) local_error = NULL; + + kms_fd = meta_gpu_kms_get_fd (gpu_kms); + + gbm_device = gbm_create_device (kms_fd); + if (!gbm_device) + { + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_FAILED, + "Failed to create gbm device: %s", g_strerror (errno)); + return NULL; + } + + renderer_gpu_data = meta_create_renderer_native_gpu_data (gpu_kms); + renderer_gpu_data->renderer_native = renderer_native; + renderer_gpu_data->gbm.device = gbm_device; + renderer_gpu_data->mode = META_RENDERER_NATIVE_MODE_GBM; + + renderer_gpu_data->egl_display = init_gbm_egl_display (renderer_native, + gbm_device, + &local_error); + if (renderer_gpu_data->egl_display == EGL_NO_DISPLAY) + { + g_debug ("GBM EGL init for %s failed: %s", + meta_gpu_kms_get_file_path (gpu_kms), + local_error->message); + + init_secondary_gpu_data_cpu (renderer_gpu_data); + return renderer_gpu_data; + } + + init_secondary_gpu_data (renderer_gpu_data); + return renderer_gpu_data; +} + +#ifdef HAVE_EGL_DEVICE +static const char * +get_drm_device_file (MetaEgl *egl, + EGLDeviceEXT device, + GError **error) +{ + if (!meta_egl_egl_device_has_extensions (egl, device, + NULL, + "EGL_EXT_device_drm", + NULL)) + { + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_FAILED, + "Missing required EGLDevice extension EGL_EXT_device_drm"); + return NULL; + } + + return meta_egl_query_device_string (egl, device, + EGL_DRM_DEVICE_FILE_EXT, + error); +} + +static EGLDeviceEXT +find_egl_device (MetaRendererNative *renderer_native, + MetaGpuKms *gpu_kms, + GError **error) +{ + MetaEgl *egl = meta_renderer_native_get_egl (renderer_native); + const char **missing_extensions; + EGLint num_devices; + EGLDeviceEXT *devices; + const char *kms_file_path; + EGLDeviceEXT device; + EGLint i; + + if (!meta_egl_has_extensions (egl, + EGL_NO_DISPLAY, + &missing_extensions, + "EGL_EXT_device_base", + NULL)) + { + char *missing_extensions_str; + + missing_extensions_str = g_strjoinv (", ", (char **) missing_extensions); + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_FAILED, + "Missing EGL extensions required for EGLDevice renderer: %s", + missing_extensions_str); + g_free (missing_extensions_str); + g_free (missing_extensions); + return EGL_NO_DEVICE_EXT; + } + + if (!meta_egl_query_devices (egl, 0, NULL, &num_devices, error)) + return EGL_NO_DEVICE_EXT; + + devices = g_new0 (EGLDeviceEXT, num_devices); + if (!meta_egl_query_devices (egl, num_devices, devices, &num_devices, + error)) + { + g_free (devices); + return EGL_NO_DEVICE_EXT; + } + + kms_file_path = meta_gpu_kms_get_file_path (gpu_kms); + + device = EGL_NO_DEVICE_EXT; + for (i = 0; i < num_devices; i++) + { + const char *egl_device_drm_path; + + g_clear_error (error); + + egl_device_drm_path = get_drm_device_file (egl, devices[i], error); + if (!egl_device_drm_path) + continue; + + if (g_str_equal (egl_device_drm_path, kms_file_path)) + { + device = devices[i]; + break; + } + } + g_free (devices); + + if (device == EGL_NO_DEVICE_EXT) + { + if (!*error) + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_FAILED, + "Failed to find matching EGLDeviceEXT"); + return EGL_NO_DEVICE_EXT; + } + + return device; +} + +static EGLDisplay +get_egl_device_display (MetaRendererNative *renderer_native, + MetaGpuKms *gpu_kms, + EGLDeviceEXT egl_device, + GError **error) +{ + MetaEgl *egl = meta_renderer_native_get_egl (renderer_native); + int kms_fd = meta_gpu_kms_get_fd (gpu_kms); + EGLint platform_attribs[] = { + EGL_DRM_MASTER_FD_EXT, kms_fd, + EGL_NONE + }; + + return meta_egl_get_platform_display (egl, EGL_PLATFORM_DEVICE_EXT, + (void *) egl_device, + platform_attribs, + error); +} + +static int +count_drm_devices (MetaRendererNative *renderer_native) +{ + MetaRenderer *renderer = META_RENDERER (renderer_native); + MetaBackend *backend = meta_renderer_get_backend (renderer); + + return g_list_length (meta_backend_get_gpus (backend)); +} + +static MetaRendererNativeGpuData * +create_renderer_gpu_data_egl_device (MetaRendererNative *renderer_native, + MetaGpuKms *gpu_kms, + GError **error) +{ + MetaEgl *egl = meta_renderer_native_get_egl (renderer_native); + const char **missing_extensions; + EGLDeviceEXT egl_device; + EGLDisplay egl_display; + MetaRendererNativeGpuData *renderer_gpu_data; + + if (count_drm_devices (renderer_native) != 1) + { + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_FAILED, + "EGLDevice currently only works with single GPU systems"); + return NULL; + } + + egl_device = find_egl_device (renderer_native, gpu_kms, error); + if (egl_device == EGL_NO_DEVICE_EXT) + return NULL; + + egl_display = get_egl_device_display (renderer_native, gpu_kms, + egl_device, error); + if (egl_display == EGL_NO_DISPLAY) + return NULL; + + if (!meta_egl_initialize (egl, egl_display, error)) + return NULL; + + if (!meta_egl_has_extensions (egl, + egl_display, + &missing_extensions, + "EGL_NV_output_drm_flip_event", + "EGL_EXT_output_base", + "EGL_EXT_output_drm", + "EGL_KHR_stream", + "EGL_KHR_stream_producer_eglsurface", + "EGL_EXT_stream_consumer_egloutput", + "EGL_EXT_stream_acquire_mode", + NULL)) + { + char *missing_extensions_str; + + missing_extensions_str = g_strjoinv (", ", (char **) missing_extensions); + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_FAILED, + "Missing EGL extensions required for EGLDevice renderer: %s", + missing_extensions_str); + meta_egl_terminate (egl, egl_display, NULL); + g_free (missing_extensions_str); + g_free (missing_extensions); + return NULL; + } + + renderer_gpu_data = meta_create_renderer_native_gpu_data (gpu_kms); + renderer_gpu_data->renderer_native = renderer_native; + renderer_gpu_data->egl.device = egl_device; + renderer_gpu_data->mode = META_RENDERER_NATIVE_MODE_EGL_DEVICE; + renderer_gpu_data->egl_display = egl_display; + + return renderer_gpu_data; +} +#endif /* HAVE_EGL_DEVICE */ + +static MetaRendererNativeGpuData * +meta_renderer_native_create_renderer_gpu_data (MetaRendererNative *renderer_native, + MetaGpuKms *gpu_kms, + GError **error) +{ + MetaRendererNativeGpuData *renderer_gpu_data; + GError *gbm_error = NULL; +#ifdef HAVE_EGL_DEVICE + GError *egl_device_error = NULL; +#endif + +#ifdef HAVE_EGL_DEVICE + /* Try to initialize the EGLDevice backend first. Whenever we use a + * non-NVIDIA GPU, the EGLDevice enumeration function won't find a match, and + * we'll fall back to GBM (which will always succeed as it has a software + * rendering fallback) + */ + renderer_gpu_data = create_renderer_gpu_data_egl_device (renderer_native, + gpu_kms, + &egl_device_error); + if (renderer_gpu_data) + return renderer_gpu_data; +#endif + + renderer_gpu_data = create_renderer_gpu_data_gbm (renderer_native, + gpu_kms, + &gbm_error); + if (renderer_gpu_data) + { +#ifdef HAVE_EGL_DEVICE + g_error_free (egl_device_error); +#endif + return renderer_gpu_data; + } + + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_FAILED, + "Failed to initialize renderer: " + "%s" +#ifdef HAVE_EGL_DEVICE + ", %s" +#endif + , gbm_error->message +#ifdef HAVE_EGL_DEVICE + , egl_device_error->message +#endif + ); + + g_error_free (gbm_error); +#ifdef HAVE_EGL_DEVICE + g_error_free (egl_device_error); +#endif + + return NULL; +} + +static gboolean +create_renderer_gpu_data (MetaRendererNative *renderer_native, + MetaGpuKms *gpu_kms, + GError **error) +{ + MetaRendererNativeGpuData *renderer_gpu_data; + + renderer_gpu_data = + meta_renderer_native_create_renderer_gpu_data (renderer_native, + gpu_kms, + error); + if (!renderer_gpu_data) + return FALSE; + + g_hash_table_insert (renderer_native->gpu_datas, + gpu_kms, + renderer_gpu_data); + + return TRUE; +} + +static void +on_gpu_added (MetaBackendNative *backend_native, + MetaGpuKms *gpu_kms, + MetaRendererNative *renderer_native) +{ + MetaBackend *backend = META_BACKEND (backend_native); + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend); + CoglDisplay *cogl_display = cogl_context_get_display (cogl_context); + GError *error = NULL; + + if (!create_renderer_gpu_data (renderer_native, gpu_kms, &error)) + { + g_warning ("on_gpu_added: could not create gpu_data for gpu %s: %s", + meta_gpu_kms_get_file_path (gpu_kms), error->message); + g_clear_error (&error); + } + + _cogl_winsys_egl_ensure_current (cogl_display); +} + +static void +on_power_save_mode_changed (MetaMonitorManager *monitor_manager, + MetaRendererNative *renderer_native) +{ + MetaRenderer *renderer = META_RENDERER (renderer_native); + MetaBackend *backend = meta_renderer_get_backend (renderer); + MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend); + MetaKms *kms = meta_backend_native_get_kms (backend_native); + MetaPowerSave power_save_mode; + + power_save_mode = meta_monitor_manager_get_power_save_mode (monitor_manager); + if (power_save_mode == META_POWER_SAVE_ON) + meta_renderer_native_queue_modes_reset (renderer_native); + else + meta_kms_discard_pending_page_flips (kms); +} + +void +meta_renderer_native_reset_modes (MetaRendererNative *renderer_native) +{ + MetaRenderer *renderer = META_RENDERER (renderer_native); + MetaBackend *backend = meta_renderer_get_backend (renderer); + MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend); + MetaKms *kms = meta_backend_native_get_kms (backend_native); + MetaKmsUpdate *kms_update; + + kms_update = unset_disabled_crtcs (backend, kms); + + if (kms_update) + post_pending_update (kms); +} + +static MetaGpuKms * +choose_primary_gpu_unchecked (MetaBackend *backend, + MetaRendererNative *renderer_native) +{ + GList *gpus = meta_backend_get_gpus (backend); + GList *l; + int allow_sw; + + /* + * Check first hardware rendering devices, and if none found, + * then software rendering devices. + */ + for (allow_sw = 0; allow_sw < 2; allow_sw++) + { + /* Prefer a platform device */ + for (l = gpus; l; l = l->next) + { + MetaGpuKms *gpu_kms = META_GPU_KMS (l->data); + + if (meta_gpu_kms_is_platform_device (gpu_kms) && + (allow_sw == 1 || + gpu_kms_is_hardware_rendering (renderer_native, gpu_kms))) + return gpu_kms; + } + + /* Otherwise a device we booted with */ + for (l = gpus; l; l = l->next) + { + MetaGpuKms *gpu_kms = META_GPU_KMS (l->data); + + if (meta_gpu_kms_is_boot_vga (gpu_kms) && + (allow_sw == 1 || + gpu_kms_is_hardware_rendering (renderer_native, gpu_kms))) + return gpu_kms; + } + + /* Fall back to any device */ + for (l = gpus; l; l = l->next) + { + MetaGpuKms *gpu_kms = META_GPU_KMS (l->data); + + if (allow_sw == 1 || + gpu_kms_is_hardware_rendering (renderer_native, gpu_kms)) + return gpu_kms; + } + } + + g_assert_not_reached (); + return NULL; +} + +static MetaGpuKms * +choose_primary_gpu (MetaBackend *backend, + MetaRendererNative *renderer_native, + GError **error) +{ + MetaGpuKms *gpu_kms; + MetaRendererNativeGpuData *renderer_gpu_data; + + gpu_kms = choose_primary_gpu_unchecked (backend, renderer_native); + renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native, + gpu_kms); + if (renderer_gpu_data->egl_display == EGL_NO_DISPLAY) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "The GPU %s chosen as primary is not supported by EGL.", + meta_gpu_kms_get_file_path (gpu_kms)); + return NULL; + } + + return gpu_kms; +} + +static gboolean +meta_renderer_native_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + MetaRendererNative *renderer_native = META_RENDERER_NATIVE (initable); + MetaRenderer *renderer = META_RENDERER (renderer_native); + MetaBackend *backend = meta_renderer_get_backend (renderer); + GList *gpus; + GList *l; + + gpus = meta_backend_get_gpus (backend); + for (l = gpus; l; l = l->next) + { + MetaGpuKms *gpu_kms = META_GPU_KMS (l->data); + + if (!create_renderer_gpu_data (renderer_native, gpu_kms, error)) + return FALSE; + } + + renderer_native->primary_gpu_kms = choose_primary_gpu (backend, + renderer_native, + error); + if (!renderer_native->primary_gpu_kms) + return FALSE; + + return TRUE; +} + +static void +initable_iface_init (GInitableIface *initable_iface) +{ + initable_iface->init = meta_renderer_native_initable_init; +} + +static void +meta_renderer_native_finalize (GObject *object) +{ + MetaRendererNative *renderer_native = META_RENDERER_NATIVE (object); + + if (renderer_native->power_save_page_flip_onscreens) + { + g_list_free_full (renderer_native->power_save_page_flip_onscreens, + (GDestroyNotify) cogl_object_unref); + g_clear_handle_id (&renderer_native->power_save_page_flip_source_id, + g_source_remove); + } + + g_hash_table_destroy (renderer_native->gpu_datas); + g_clear_object (&renderer_native->gles3); + + G_OBJECT_CLASS (meta_renderer_native_parent_class)->finalize (object); +} + +static void +meta_renderer_native_constructed (GObject *object) +{ + MetaRendererNative *renderer_native = META_RENDERER_NATIVE (object); + MetaRenderer *renderer = META_RENDERER (renderer_native); + MetaBackend *backend = meta_renderer_get_backend (renderer); + MetaSettings *settings = meta_backend_get_settings (backend); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + + if (meta_settings_is_experimental_feature_enabled ( + settings, META_EXPERIMENTAL_FEATURE_KMS_MODIFIERS)) + renderer_native->use_modifiers = TRUE; + + g_signal_connect (backend, "gpu-added", + G_CALLBACK (on_gpu_added), renderer_native); + g_signal_connect (monitor_manager, "power-save-mode-changed", + G_CALLBACK (on_power_save_mode_changed), renderer_native); + + G_OBJECT_CLASS (meta_renderer_native_parent_class)->constructed (object); +} + +static void +meta_renderer_native_init (MetaRendererNative *renderer_native) +{ + renderer_native->gpu_datas = + g_hash_table_new_full (NULL, NULL, + NULL, + (GDestroyNotify) meta_renderer_native_gpu_data_free); +} + +static void +meta_renderer_native_class_init (MetaRendererNativeClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MetaRendererClass *renderer_class = META_RENDERER_CLASS (klass); + + object_class->finalize = meta_renderer_native_finalize; + object_class->constructed = meta_renderer_native_constructed; + + renderer_class->create_cogl_renderer = meta_renderer_native_create_cogl_renderer; + renderer_class->create_view = meta_renderer_native_create_view; + renderer_class->rebuild_views = meta_renderer_native_rebuild_views; +} + +MetaRendererNative * +meta_renderer_native_new (MetaBackendNative *backend_native, + GError **error) +{ + return g_initable_new (META_TYPE_RENDERER_NATIVE, + NULL, + error, + "backend", backend_native, + NULL); +} diff --git a/src/backends/native/meta-renderer-native.h b/src/backends/native/meta-renderer-native.h new file mode 100644 index 000000000..1f61e261f --- /dev/null +++ b/src/backends/native/meta-renderer-native.h @@ -0,0 +1,60 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +#ifndef META_RENDERER_NATIVE_H +#define META_RENDERER_NATIVE_H + +#include <gbm.h> +#include <glib-object.h> +#include <xf86drmMode.h> + +#include "backends/meta-renderer.h" +#include "backends/native/meta-gpu-kms.h" +#include "backends/native/meta-monitor-manager-kms.h" + +#define META_TYPE_RENDERER_NATIVE (meta_renderer_native_get_type ()) +G_DECLARE_FINAL_TYPE (MetaRendererNative, meta_renderer_native, + META, RENDERER_NATIVE, + MetaRenderer) + +typedef enum _MetaRendererNativeMode +{ + META_RENDERER_NATIVE_MODE_GBM, +#ifdef HAVE_EGL_DEVICE + META_RENDERER_NATIVE_MODE_EGL_DEVICE +#endif +} MetaRendererNativeMode; + +MetaRendererNative * meta_renderer_native_new (MetaBackendNative *backend_native, + GError **error); + +struct gbm_device * meta_gbm_device_from_gpu (MetaGpuKms *gpu_kms); + +void meta_renderer_native_finish_frame (MetaRendererNative *renderer_native); + +int64_t meta_renderer_native_get_frame_counter (MetaRendererNative *renderer_native); + +void meta_renderer_native_reset_modes (MetaRendererNative *renderer_native); + +#endif /* META_RENDERER_NATIVE_H */ diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c new file mode 100644 index 000000000..c6b542071 --- /dev/null +++ b/src/backends/native/meta-seat-native.c @@ -0,0 +1,3316 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Copyright (C) 2010 Intel Corp. + * Copyright (C) 2014 Jonas Ådahl + * Copyright (C) 2016 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Author: Damien Lespiau <damien.lespiau@intel.com> + * Author: Jonas Ådahl <jadahl@gmail.com> + */ + +#include "config.h" + +#include <errno.h> +#include <fcntl.h> +#include <libinput.h> +#include <linux/input.h> +#include <math.h> + +#include "backends/meta-cursor-tracker-private.h" +#include "backends/native/meta-seat-native.h" +#include "backends/native/meta-event-native.h" +#include "backends/native/meta-input-device-native.h" +#include "backends/native/meta-input-device-tool-native.h" +#include "backends/native/meta-keymap-native.h" +#include "backends/native/meta-virtual-input-device-native.h" +#include "clutter/clutter-mutter.h" +#include "core/bell.h" + +/* + * Clutter makes the assumption that two core devices have ID's 2 and 3 (core + * pointer and core keyboard). + * + * Since the two first devices that will ever be created will be the virtual + * pointer and virtual keyboard of the first seat, we fulfill the made + * assumptions by having the first device having ID 2 and following 3. + */ +#define INITIAL_DEVICE_ID 2 + +/* Try to keep the pointer inside the stage. Hopefully no one is using + * this backend with stages smaller than this. */ +#define INITIAL_POINTER_X 16 +#define INITIAL_POINTER_Y 16 + +#define AUTOREPEAT_VALUE 2 + +#define DISCRETE_SCROLL_STEP 10.0 + +#ifndef BTN_STYLUS3 +#define BTN_STYLUS3 0x149 /* Linux 4.15 */ +#endif + +typedef struct _MetaEventFilter MetaEventFilter; + +struct _MetaEventFilter +{ + MetaEvdevFilterFunc func; + gpointer data; + GDestroyNotify destroy_notify; +}; + +struct _MetaEventSource +{ + GSource source; + + MetaSeatNative *seat; + GPollFD event_poll_fd; +}; + +static MetaOpenDeviceCallback device_open_callback; +static MetaCloseDeviceCallback device_close_callback; +static gpointer device_callback_data; + +#ifdef CLUTTER_ENABLE_DEBUG +static const char *device_type_str[] = { + "pointer", /* CLUTTER_POINTER_DEVICE */ + "keyboard", /* CLUTTER_KEYBOARD_DEVICE */ + "extension", /* CLUTTER_EXTENSION_DEVICE */ + "joystick", /* CLUTTER_JOYSTICK_DEVICE */ + "tablet", /* CLUTTER_TABLET_DEVICE */ + "touchpad", /* CLUTTER_TOUCHPAD_DEVICE */ + "touchscreen", /* CLUTTER_TOUCHSCREEN_DEVICE */ + "pen", /* CLUTTER_PEN_DEVICE */ + "eraser", /* CLUTTER_ERASER_DEVICE */ + "cursor", /* CLUTTER_CURSOR_DEVICE */ + "pad", /* CLUTTER_PAD_DEVICE */ +}; +#endif /* CLUTTER_ENABLE_DEBUG */ + +enum +{ + PROP_0, + PROP_SEAT_ID, + N_PROPS, + + /* This property is overridden */ + PROP_TOUCH_MODE, +}; + +GParamSpec *props[N_PROPS] = { NULL }; + +G_DEFINE_TYPE (MetaSeatNative, meta_seat_native, CLUTTER_TYPE_SEAT) + +static void process_events (MetaSeatNative *seat); + +void +meta_seat_native_set_libinput_seat (MetaSeatNative *seat, + struct libinput_seat *libinput_seat) +{ + g_assert (seat->libinput_seat == NULL); + + libinput_seat_ref (libinput_seat); + libinput_seat_set_user_data (libinput_seat, seat); + seat->libinput_seat = libinput_seat; +} + +void +meta_seat_native_sync_leds (MetaSeatNative *seat) +{ + GSList *iter; + MetaInputDeviceNative *device_evdev; + int caps_lock, num_lock, scroll_lock; + enum libinput_led leds = 0; + + caps_lock = xkb_state_led_index_is_active (seat->xkb, seat->caps_lock_led); + num_lock = xkb_state_led_index_is_active (seat->xkb, seat->num_lock_led); + scroll_lock = xkb_state_led_index_is_active (seat->xkb, seat->scroll_lock_led); + + if (caps_lock) + leds |= LIBINPUT_LED_CAPS_LOCK; + if (num_lock) + leds |= LIBINPUT_LED_NUM_LOCK; + if (scroll_lock) + leds |= LIBINPUT_LED_SCROLL_LOCK; + + for (iter = seat->devices; iter; iter = iter->next) + { + device_evdev = iter->data; + meta_input_device_native_update_leds (device_evdev, leds); + } +} + +static void +clutter_touch_state_free (MetaTouchState *touch_state) +{ + g_slice_free (MetaTouchState, touch_state); +} + +static void +ensure_seat_slot_allocated (MetaSeatNative *seat, + int seat_slot) +{ + if (seat_slot >= seat->n_alloc_touch_states) + { + const int size_increase = 5; + int i; + + seat->n_alloc_touch_states += size_increase; + seat->touch_states = g_realloc_n (seat->touch_states, + seat->n_alloc_touch_states, + sizeof (MetaTouchState *)); + for (i = 0; i < size_increase; i++) + seat->touch_states[seat->n_alloc_touch_states - (i + 1)] = NULL; + } +} + +MetaTouchState * +meta_seat_native_acquire_touch_state (MetaSeatNative *seat, + int device_slot) +{ + MetaTouchState *touch_state; + int seat_slot; + + for (seat_slot = 0; seat_slot < seat->n_alloc_touch_states; seat_slot++) + { + if (!seat->touch_states[seat_slot]) + break; + } + + ensure_seat_slot_allocated (seat, seat_slot); + + touch_state = g_slice_new0 (MetaTouchState); + *touch_state = (MetaTouchState) { + .seat = seat, + .seat_slot = seat_slot, + .device_slot = device_slot, + }; + + seat->touch_states[seat_slot] = touch_state; + + return touch_state; +} + +void +meta_seat_native_release_touch_state (MetaSeatNative *seat, + MetaTouchState *touch_state) +{ + g_clear_pointer (&seat->touch_states[touch_state->seat_slot], + clutter_touch_state_free); +} + +void +meta_seat_native_clear_repeat_timer (MetaSeatNative *seat) +{ + if (seat->repeat_timer) + { + g_clear_handle_id (&seat->repeat_timer, g_source_remove); + g_clear_object (&seat->repeat_device); + } +} + +static void +dispatch_libinput (MetaSeatNative *seat) +{ + libinput_dispatch (seat->libinput); + process_events (seat); +} + +static gboolean +keyboard_repeat (gpointer data) +{ + MetaSeatNative *seat = data; + GSource *source; + + /* There might be events queued in libinput that could cancel the + repeat timer. */ + dispatch_libinput (seat); + if (!seat->repeat_timer) + return G_SOURCE_REMOVE; + + g_return_val_if_fail (seat->repeat_device != NULL, G_SOURCE_REMOVE); + source = g_main_context_find_source_by_id (NULL, seat->repeat_timer); + + meta_seat_native_notify_key (seat, + seat->repeat_device, + g_source_get_time (source), + seat->repeat_key, + AUTOREPEAT_VALUE, + FALSE); + + return G_SOURCE_CONTINUE; +} + +static void +queue_event (ClutterEvent *event) +{ + _clutter_event_push (event, FALSE); +} + +static int +update_button_count (MetaSeatNative *seat, + uint32_t button, + uint32_t state) +{ + if (state) + { + return ++seat->button_count[button]; + } + else + { + /* Handle cases where we newer saw the initial pressed event. */ + if (seat->button_count[button] == 0) + { + meta_topic (META_DEBUG_INPUT, + "Counting release of key 0x%x and count is already 0\n", + button); + return 0; + } + + return --seat->button_count[button]; + } +} + +void +meta_seat_native_notify_key (MetaSeatNative *seat, + ClutterInputDevice *device, + uint64_t time_us, + uint32_t key, + uint32_t state, + gboolean update_keys) +{ + ClutterStage *stage; + ClutterEvent *event = NULL; + enum xkb_state_component changed_state; + + if (state != AUTOREPEAT_VALUE) + { + /* Drop any repeated button press (for example from virtual devices. */ + int count = update_button_count (seat, key, state); + if ((state && count > 1) || + (!state && count != 0)) + { + meta_topic (META_DEBUG_INPUT, + "Dropping repeated %s of key 0x%x, count %d, state %d\n", + state ? "press" : "release", key, count, state); + return; + } + } + + /* We can drop the event on the floor if no stage has been + * associated with the device yet. */ + stage = _clutter_input_device_get_stage (device); + if (stage == NULL) + { + meta_seat_native_clear_repeat_timer (seat); + return; + } + + event = meta_key_event_new_from_evdev (device, + seat->core_keyboard, + stage, + seat->xkb, + seat->button_state, + us2ms (time_us), key, state); + meta_event_native_set_event_code (event, key); + + /* We must be careful and not pass multiple releases to xkb, otherwise it gets + confused and locks the modifiers */ + if (state != AUTOREPEAT_VALUE) + { + changed_state = xkb_state_update_key (seat->xkb, + event->key.hardware_keycode, + state ? XKB_KEY_DOWN : XKB_KEY_UP); + } + else + { + changed_state = 0; + clutter_event_set_flags (event, CLUTTER_EVENT_FLAG_REPEATED); + } + + queue_event (event); + + if (update_keys && (changed_state & XKB_STATE_LEDS)) + { + g_signal_emit_by_name (seat->keymap, "state-changed"); + meta_seat_native_sync_leds (seat); + meta_input_device_native_a11y_maybe_notify_toggle_keys (META_INPUT_DEVICE_NATIVE (seat->core_keyboard)); + } + + if (state == 0 || /* key release */ + !seat->repeat || + !xkb_keymap_key_repeats (xkb_state_get_keymap (seat->xkb), + event->key.hardware_keycode)) + { + meta_seat_native_clear_repeat_timer (seat); + return; + } + + if (state == 1) /* key press */ + seat->repeat_count = 0; + + seat->repeat_count += 1; + seat->repeat_key = key; + + switch (seat->repeat_count) + { + case 1: + case 2: + { + uint32_t interval; + + meta_seat_native_clear_repeat_timer (seat); + seat->repeat_device = g_object_ref (device); + + if (seat->repeat_count == 1) + interval = seat->repeat_delay; + else + interval = seat->repeat_interval; + + seat->repeat_timer = + clutter_threads_add_timeout_full (CLUTTER_PRIORITY_EVENTS, + interval, + keyboard_repeat, + seat, + NULL); + return; + } + default: + return; + } +} + +static ClutterEvent * +new_absolute_motion_event (MetaSeatNative *seat, + ClutterInputDevice *input_device, + uint64_t time_us, + float x, + float y, + double *axes) +{ + ClutterStage *stage = _clutter_input_device_get_stage (input_device); + ClutterEvent *event; + + event = clutter_event_new (CLUTTER_MOTION); + + if (clutter_input_device_get_device_type (input_device) != CLUTTER_TABLET_DEVICE) + { + meta_seat_native_constrain_pointer (seat, + seat->core_pointer, + time_us, + seat->pointer_x, + seat->pointer_y, + &x, &y); + } + + meta_event_native_set_time_usec (event, time_us); + event->motion.time = us2ms (time_us); + event->motion.stage = stage; + meta_xkb_translate_state (event, seat->xkb, seat->button_state); + event->motion.x = x; + event->motion.y = y; + meta_input_device_native_translate_coordinates (input_device, stage, + &event->motion.x, + &event->motion.y); + event->motion.axes = axes; + clutter_event_set_device (event, seat->core_pointer); + clutter_event_set_source_device (event, input_device); + + if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE) + { + MetaInputDeviceNative *device_evdev = + META_INPUT_DEVICE_NATIVE (input_device); + + clutter_event_set_device_tool (event, device_evdev->last_tool); + clutter_event_set_device (event, input_device); + } + else + { + clutter_event_set_device (event, seat->core_pointer); + } + + _clutter_input_device_set_stage (seat->core_pointer, stage); + + if (clutter_input_device_get_device_type (input_device) != CLUTTER_TABLET_DEVICE) + { + seat->pointer_x = x; + seat->pointer_y = y; + } + + return event; +} + +void +meta_seat_native_notify_relative_motion (MetaSeatNative *seat, + ClutterInputDevice *input_device, + uint64_t time_us, + float dx, + float dy, + float dx_unaccel, + float dy_unaccel) +{ + float new_x, new_y; + ClutterEvent *event; + + /* We can drop the event on the floor if no stage has been + * associated with the device yet. */ + if (!_clutter_input_device_get_stage (input_device)) + return; + + meta_seat_native_filter_relative_motion (seat, + input_device, + seat->pointer_x, + seat->pointer_y, + &dx, + &dy); + + new_x = seat->pointer_x + dx; + new_y = seat->pointer_y + dy; + event = new_absolute_motion_event (seat, input_device, + time_us, new_x, new_y, NULL); + + meta_event_native_set_relative_motion (event, + dx, dy, + dx_unaccel, dy_unaccel); + + queue_event (event); +} + +void +meta_seat_native_notify_absolute_motion (MetaSeatNative *seat, + ClutterInputDevice *input_device, + uint64_t time_us, + float x, + float y, + double *axes) +{ + ClutterEvent *event; + + event = new_absolute_motion_event (seat, input_device, time_us, x, y, axes); + + queue_event (event); +} + +void +meta_seat_native_notify_button (MetaSeatNative *seat, + ClutterInputDevice *input_device, + uint64_t time_us, + uint32_t button, + uint32_t state) +{ + MetaInputDeviceNative *device_evdev = (MetaInputDeviceNative *) input_device; + ClutterStage *stage; + ClutterEvent *event = NULL; + int button_nr; + static int maskmap[8] = + { + CLUTTER_BUTTON1_MASK, CLUTTER_BUTTON3_MASK, CLUTTER_BUTTON2_MASK, + CLUTTER_BUTTON4_MASK, CLUTTER_BUTTON5_MASK, 0, 0, 0 + }; + int button_count; + + /* Drop any repeated button press (for example from virtual devices. */ + button_count = update_button_count (seat, button, state); + if ((state && button_count > 1) || + (!state && button_count != 0)) + { + meta_topic (META_DEBUG_INPUT, + "Dropping repeated %s of button 0x%x, count %d\n", + state ? "press" : "release", button, button_count); + return; + } + + /* We can drop the event on the floor if no stage has been + * associated with the device yet. */ + stage = _clutter_input_device_get_stage (input_device); + if (stage == NULL) + return; + + /* The evdev button numbers don't map sequentially to clutter button + * numbers (the right and middle mouse buttons are in the opposite + * order) so we'll map them directly with a switch statement */ + switch (button) + { + case BTN_LEFT: + case BTN_TOUCH: + button_nr = CLUTTER_BUTTON_PRIMARY; + break; + + case BTN_RIGHT: + case BTN_STYLUS: + button_nr = CLUTTER_BUTTON_SECONDARY; + break; + + case BTN_MIDDLE: + case BTN_STYLUS2: + button_nr = CLUTTER_BUTTON_MIDDLE; + break; + + case 0x149: /* BTN_STYLUS3 */ + button_nr = 8; + break; + + default: + /* For compatibility reasons, all additional buttons go after the old 4-7 scroll ones */ + if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE) + button_nr = button - BTN_TOOL_PEN + 4; + else + button_nr = button - (BTN_LEFT - 1) + 4; + break; + } + + if (button_nr < 1 || button_nr > 12) + { + g_warning ("Unhandled button event 0x%x", button); + return; + } + + if (state) + event = clutter_event_new (CLUTTER_BUTTON_PRESS); + else + event = clutter_event_new (CLUTTER_BUTTON_RELEASE); + + if (button_nr < G_N_ELEMENTS (maskmap)) + { + /* Update the modifiers */ + if (state) + seat->button_state |= maskmap[button_nr - 1]; + else + seat->button_state &= ~maskmap[button_nr - 1]; + } + + meta_event_native_set_time_usec (event, time_us); + event->button.time = us2ms (time_us); + event->button.stage = CLUTTER_STAGE (stage); + meta_xkb_translate_state (event, seat->xkb, seat->button_state); + event->button.button = button_nr; + + if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE) + { + graphene_point_t point; + + clutter_input_device_get_coords (input_device, NULL, &point); + event->button.x = point.x; + event->button.y = point.y; + } + else + { + event->button.x = seat->pointer_x; + event->button.y = seat->pointer_y; + } + + clutter_event_set_device (event, seat->core_pointer); + clutter_event_set_source_device (event, input_device); + + if (device_evdev->last_tool) + { + /* Apply the button event code as per the tool mapping */ + uint32_t mapped_button; + + mapped_button = meta_input_device_tool_native_get_button_code (device_evdev->last_tool, + button_nr); + if (mapped_button != 0) + button = mapped_button; + } + + meta_event_native_set_event_code (event, button); + + if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE) + { + clutter_event_set_device_tool (event, device_evdev->last_tool); + clutter_event_set_device (event, input_device); + } + else + { + clutter_event_set_device (event, seat->core_pointer); + } + + _clutter_input_device_set_stage (seat->core_pointer, stage); + + queue_event (event); +} + +static void +notify_scroll (ClutterInputDevice *input_device, + uint64_t time_us, + double dx, + double dy, + ClutterScrollSource scroll_source, + ClutterScrollFinishFlags flags, + gboolean emulated) +{ + MetaInputDeviceNative *device_evdev; + MetaSeatNative *seat; + ClutterStage *stage; + ClutterEvent *event = NULL; + double scroll_factor; + + /* We can drop the event on the floor if no stage has been + * associated with the device yet. */ + stage = _clutter_input_device_get_stage (input_device); + if (stage == NULL) + return; + + device_evdev = META_INPUT_DEVICE_NATIVE (input_device); + seat = meta_input_device_native_get_seat (device_evdev); + + event = clutter_event_new (CLUTTER_SCROLL); + + meta_event_native_set_time_usec (event, time_us); + event->scroll.time = us2ms (time_us); + event->scroll.stage = CLUTTER_STAGE (stage); + meta_xkb_translate_state (event, seat->xkb, seat->button_state); + + /* libinput pointer axis events are in pointer motion coordinate space. + * To convert to Xi2 discrete step coordinate space, multiply the factor + * 1/10. */ + event->scroll.direction = CLUTTER_SCROLL_SMOOTH; + scroll_factor = 1.0 / DISCRETE_SCROLL_STEP; + clutter_event_set_scroll_delta (event, + scroll_factor * dx, + scroll_factor * dy); + + event->scroll.x = seat->pointer_x; + event->scroll.y = seat->pointer_y; + clutter_event_set_device (event, seat->core_pointer); + clutter_event_set_source_device (event, input_device); + event->scroll.scroll_source = scroll_source; + event->scroll.finish_flags = flags; + + _clutter_event_set_pointer_emulated (event, emulated); + + queue_event (event); +} + +static void +notify_discrete_scroll (ClutterInputDevice *input_device, + uint64_t time_us, + ClutterScrollDirection direction, + ClutterScrollSource scroll_source, + gboolean emulated) +{ + MetaInputDeviceNative *device_evdev; + MetaSeatNative *seat; + ClutterStage *stage; + ClutterEvent *event = NULL; + + if (direction == CLUTTER_SCROLL_SMOOTH) + return; + + /* We can drop the event on the floor if no stage has been + * associated with the device yet. */ + stage = _clutter_input_device_get_stage (input_device); + if (stage == NULL) + return; + + device_evdev = META_INPUT_DEVICE_NATIVE (input_device); + seat = meta_input_device_native_get_seat (device_evdev); + + event = clutter_event_new (CLUTTER_SCROLL); + + meta_event_native_set_time_usec (event, time_us); + event->scroll.time = us2ms (time_us); + event->scroll.stage = CLUTTER_STAGE (stage); + meta_xkb_translate_state (event, seat->xkb, seat->button_state); + + event->scroll.direction = direction; + + event->scroll.x = seat->pointer_x; + event->scroll.y = seat->pointer_y; + clutter_event_set_device (event, seat->core_pointer); + clutter_event_set_source_device (event, input_device); + event->scroll.scroll_source = scroll_source; + + _clutter_event_set_pointer_emulated (event, emulated); + + queue_event (event); +} + +static void +check_notify_discrete_scroll (MetaSeatNative *seat, + ClutterInputDevice *device, + uint64_t time_us, + ClutterScrollSource scroll_source) +{ + int i, n_xscrolls, n_yscrolls; + + n_xscrolls = floor (fabs (seat->accum_scroll_dx) / DISCRETE_SCROLL_STEP); + n_yscrolls = floor (fabs (seat->accum_scroll_dy) / DISCRETE_SCROLL_STEP); + + for (i = 0; i < n_xscrolls; i++) + { + notify_discrete_scroll (device, time_us, + seat->accum_scroll_dx > 0 ? + CLUTTER_SCROLL_RIGHT : CLUTTER_SCROLL_LEFT, + scroll_source, TRUE); + } + + for (i = 0; i < n_yscrolls; i++) + { + notify_discrete_scroll (device, time_us, + seat->accum_scroll_dy > 0 ? + CLUTTER_SCROLL_DOWN : CLUTTER_SCROLL_UP, + scroll_source, TRUE); + } + + seat->accum_scroll_dx = fmodf (seat->accum_scroll_dx, DISCRETE_SCROLL_STEP); + seat->accum_scroll_dy = fmodf (seat->accum_scroll_dy, DISCRETE_SCROLL_STEP); +} + +void +meta_seat_native_notify_scroll_continuous (MetaSeatNative *seat, + ClutterInputDevice *input_device, + uint64_t time_us, + double dx, + double dy, + ClutterScrollSource scroll_source, + ClutterScrollFinishFlags finish_flags) +{ + if (finish_flags & CLUTTER_SCROLL_FINISHED_HORIZONTAL) + seat->accum_scroll_dx = 0; + else + seat->accum_scroll_dx += dx; + + if (finish_flags & CLUTTER_SCROLL_FINISHED_VERTICAL) + seat->accum_scroll_dy = 0; + else + seat->accum_scroll_dy += dy; + + notify_scroll (input_device, time_us, dx, dy, scroll_source, + finish_flags, FALSE); + check_notify_discrete_scroll (seat, input_device, time_us, scroll_source); +} + +static ClutterScrollDirection +discrete_to_direction (double discrete_dx, + double discrete_dy) +{ + if (discrete_dx > 0) + return CLUTTER_SCROLL_RIGHT; + else if (discrete_dx < 0) + return CLUTTER_SCROLL_LEFT; + else if (discrete_dy > 0) + return CLUTTER_SCROLL_DOWN; + else if (discrete_dy < 0) + return CLUTTER_SCROLL_UP; + else + g_assert_not_reached (); + return 0; +} + +void +meta_seat_native_notify_discrete_scroll (MetaSeatNative *seat, + ClutterInputDevice *input_device, + uint64_t time_us, + double discrete_dx, + double discrete_dy, + ClutterScrollSource scroll_source) +{ + notify_scroll (input_device, time_us, + discrete_dx * DISCRETE_SCROLL_STEP, + discrete_dy * DISCRETE_SCROLL_STEP, + scroll_source, CLUTTER_SCROLL_FINISHED_NONE, + TRUE); + notify_discrete_scroll (input_device, time_us, + discrete_to_direction (discrete_dx, discrete_dy), + scroll_source, FALSE); + +} + +void +meta_seat_native_notify_touch_event (MetaSeatNative *seat, + ClutterInputDevice *input_device, + ClutterEventType evtype, + uint64_t time_us, + int slot, + double x, + double y) +{ + ClutterStage *stage; + ClutterEvent *event = NULL; + + /* We can drop the event on the floor if no stage has been + * associated with the device yet. */ + stage = _clutter_input_device_get_stage (input_device); + if (stage == NULL) + return; + + event = clutter_event_new (evtype); + + meta_event_native_set_time_usec (event, time_us); + event->touch.time = us2ms (time_us); + event->touch.stage = CLUTTER_STAGE (stage); + event->touch.x = x; + event->touch.y = y; + meta_input_device_native_translate_coordinates (input_device, stage, + &event->touch.x, + &event->touch.y); + + /* "NULL" sequences are special cased in clutter */ + event->touch.sequence = GINT_TO_POINTER (MAX (1, slot + 1)); + meta_xkb_translate_state (event, seat->xkb, seat->button_state); + + if (evtype == CLUTTER_TOUCH_BEGIN || + evtype == CLUTTER_TOUCH_UPDATE) + event->touch.modifier_state |= CLUTTER_BUTTON1_MASK; + + clutter_event_set_device (event, seat->core_pointer); + clutter_event_set_source_device (event, input_device); + + queue_event (event); +} + + +/* + * MetaEventSource for reading input devices + */ +static gboolean +meta_event_prepare (GSource *source, + gint *timeout) +{ + gboolean retval; + + _clutter_threads_acquire_lock (); + + *timeout = -1; + retval = clutter_events_pending (); + + _clutter_threads_release_lock (); + + return retval; +} + +static gboolean +meta_event_check (GSource *source) +{ + MetaEventSource *event_source = (MetaEventSource *) source; + gboolean retval; + + _clutter_threads_acquire_lock (); + + retval = ((event_source->event_poll_fd.revents & G_IO_IN) || + clutter_events_pending ()); + + _clutter_threads_release_lock (); + + return retval; +} + +void +meta_seat_native_constrain_pointer (MetaSeatNative *seat, + ClutterInputDevice *core_pointer, + uint64_t time_us, + float x, + float y, + float *new_x, + float *new_y) +{ + if (seat->constrain_callback) + { + seat->constrain_callback (core_pointer, + us2ms (time_us), + x, y, + new_x, new_y, + seat->constrain_data); + } + else + { + ClutterActor *stage = CLUTTER_ACTOR (meta_seat_native_get_stage (seat)); + float stage_width = clutter_actor_get_width (stage); + float stage_height = clutter_actor_get_height (stage); + + *new_x = CLAMP (*new_x, 0.f, stage_width - 1); + *new_y = CLAMP (*new_y, 0.f, stage_height - 1); + } +} + +void +meta_seat_native_filter_relative_motion (MetaSeatNative *seat, + ClutterInputDevice *device, + float x, + float y, + float *dx, + float *dy) +{ + if (!seat->relative_motion_filter) + return; + + seat->relative_motion_filter (device, x, y, dx, dy, + seat->relative_motion_filter_user_data); +} + +static void +notify_absolute_motion (ClutterInputDevice *input_device, + uint64_t time_us, + float x, + float y, + double *axes) +{ + MetaSeatNative *seat; + ClutterEvent *event; + + seat = meta_input_device_native_get_seat (META_INPUT_DEVICE_NATIVE (input_device)); + event = new_absolute_motion_event (seat, input_device, time_us, x, y, axes); + + queue_event (event); +} + +static void +notify_relative_tool_motion (ClutterInputDevice *input_device, + uint64_t time_us, + float dx, + float dy, + double *axes) +{ + MetaInputDeviceNative *device_evdev; + ClutterEvent *event; + MetaSeatNative *seat; + gfloat x, y; + + device_evdev = META_INPUT_DEVICE_NATIVE (input_device); + seat = meta_input_device_native_get_seat (device_evdev); + x = input_device->current_x + dx; + y = input_device->current_y + dy; + + meta_seat_native_filter_relative_motion (seat, + input_device, + seat->pointer_x, + seat->pointer_y, + &dx, + &dy); + + event = new_absolute_motion_event (seat, input_device, time_us, x, y, axes); + meta_event_native_set_relative_motion (event, dx, dy, 0, 0); + + queue_event (event); +} + +static void +notify_pinch_gesture_event (ClutterInputDevice *input_device, + ClutterTouchpadGesturePhase phase, + uint64_t time_us, + double dx, + double dy, + double angle_delta, + double scale, + uint32_t n_fingers) +{ + MetaInputDeviceNative *device_evdev; + MetaSeatNative *seat; + ClutterStage *stage; + ClutterEvent *event = NULL; + graphene_point_t pos; + + /* We can drop the event on the floor if no stage has been + * associated with the device yet. */ + stage = _clutter_input_device_get_stage (input_device); + if (stage == NULL) + return; + + device_evdev = META_INPUT_DEVICE_NATIVE (input_device); + seat = meta_input_device_native_get_seat (device_evdev); + + event = clutter_event_new (CLUTTER_TOUCHPAD_PINCH); + + clutter_input_device_get_coords (seat->core_pointer, NULL, &pos); + + meta_event_native_set_time_usec (event, time_us); + event->touchpad_pinch.phase = phase; + event->touchpad_pinch.time = us2ms (time_us); + event->touchpad_pinch.stage = CLUTTER_STAGE (stage); + event->touchpad_pinch.x = pos.x; + event->touchpad_pinch.y = pos.y; + event->touchpad_pinch.dx = dx; + event->touchpad_pinch.dy = dy; + event->touchpad_pinch.angle_delta = angle_delta; + event->touchpad_pinch.scale = scale; + event->touchpad_pinch.n_fingers = n_fingers; + + meta_xkb_translate_state (event, seat->xkb, seat->button_state); + + clutter_event_set_device (event, seat->core_pointer); + clutter_event_set_source_device (event, input_device); + + queue_event (event); +} + +static void +notify_swipe_gesture_event (ClutterInputDevice *input_device, + ClutterTouchpadGesturePhase phase, + uint64_t time_us, + uint32_t n_fingers, + double dx, + double dy) +{ + MetaInputDeviceNative *device_evdev; + MetaSeatNative *seat; + ClutterStage *stage; + ClutterEvent *event = NULL; + graphene_point_t pos; + + /* We can drop the event on the floor if no stage has been + * associated with the device yet. */ + stage = _clutter_input_device_get_stage (input_device); + if (stage == NULL) + return; + + device_evdev = META_INPUT_DEVICE_NATIVE (input_device); + seat = meta_input_device_native_get_seat (device_evdev); + + event = clutter_event_new (CLUTTER_TOUCHPAD_SWIPE); + + meta_event_native_set_time_usec (event, time_us); + event->touchpad_swipe.phase = phase; + event->touchpad_swipe.time = us2ms (time_us); + event->touchpad_swipe.stage = CLUTTER_STAGE (stage); + + clutter_input_device_get_coords (seat->core_pointer, NULL, &pos); + event->touchpad_swipe.x = pos.x; + event->touchpad_swipe.y = pos.y; + event->touchpad_swipe.dx = dx; + event->touchpad_swipe.dy = dy; + event->touchpad_swipe.n_fingers = n_fingers; + + meta_xkb_translate_state (event, seat->xkb, seat->button_state); + + clutter_event_set_device (event, seat->core_pointer); + clutter_event_set_source_device (event, input_device); + + queue_event (event); +} + +static void +notify_proximity (ClutterInputDevice *input_device, + uint64_t time_us, + gboolean in) +{ + MetaInputDeviceNative *device_evdev; + MetaSeatNative *seat; + ClutterStage *stage; + ClutterEvent *event = NULL; + + /* We can drop the event on the floor if no stage has been + * associated with the device yet. */ + stage = _clutter_input_device_get_stage (input_device); + if (stage == NULL) + return; + + device_evdev = META_INPUT_DEVICE_NATIVE (input_device); + seat = meta_input_device_native_get_seat (device_evdev); + + if (in) + event = clutter_event_new (CLUTTER_PROXIMITY_IN); + else + event = clutter_event_new (CLUTTER_PROXIMITY_OUT); + + meta_event_native_set_time_usec (event, time_us); + + event->proximity.time = us2ms (time_us); + event->proximity.stage = CLUTTER_STAGE (stage); + clutter_event_set_device_tool (event, device_evdev->last_tool); + clutter_event_set_device (event, seat->core_pointer); + clutter_event_set_source_device (event, input_device); + + _clutter_input_device_set_stage (seat->core_pointer, stage); + + queue_event (event); +} + +static void +notify_pad_button (ClutterInputDevice *input_device, + uint64_t time_us, + uint32_t button, + uint32_t mode_group, + uint32_t mode, + uint32_t pressed) +{ + MetaInputDeviceNative *device_evdev; + MetaSeatNative *seat; + ClutterStage *stage; + ClutterEvent *event; + + /* We can drop the event on the floor if no stage has been + * associated with the device yet. */ + stage = _clutter_input_device_get_stage (input_device); + if (stage == NULL) + return; + + if (pressed) + event = clutter_event_new (CLUTTER_PAD_BUTTON_PRESS); + else + event = clutter_event_new (CLUTTER_PAD_BUTTON_RELEASE); + + device_evdev = META_INPUT_DEVICE_NATIVE (input_device); + seat = meta_input_device_native_get_seat (device_evdev); + + meta_event_native_set_time_usec (event, time_us); + event->pad_button.stage = stage; + event->pad_button.button = button; + event->pad_button.group = mode_group; + event->pad_button.mode = mode; + clutter_event_set_device (event, input_device); + clutter_event_set_source_device (event, input_device); + clutter_event_set_time (event, us2ms (time_us)); + + _clutter_input_device_set_stage (seat->core_pointer, stage); + + queue_event (event); +} + +static void +notify_pad_strip (ClutterInputDevice *input_device, + uint64_t time_us, + uint32_t strip_number, + uint32_t strip_source, + uint32_t mode_group, + uint32_t mode, + double value) +{ + MetaInputDeviceNative *device_evdev; + ClutterInputDevicePadSource source; + MetaSeatNative *seat; + ClutterStage *stage; + ClutterEvent *event; + + /* We can drop the event on the floor if no stage has been + * associated with the device yet. */ + stage = _clutter_input_device_get_stage (input_device); + if (stage == NULL) + return; + + if (strip_source == LIBINPUT_TABLET_PAD_STRIP_SOURCE_FINGER) + source = CLUTTER_INPUT_DEVICE_PAD_SOURCE_FINGER; + else + source = CLUTTER_INPUT_DEVICE_PAD_SOURCE_UNKNOWN; + + device_evdev = META_INPUT_DEVICE_NATIVE (input_device); + seat = meta_input_device_native_get_seat (device_evdev); + + event = clutter_event_new (CLUTTER_PAD_STRIP); + meta_event_native_set_time_usec (event, time_us); + event->pad_strip.strip_source = source; + event->pad_strip.stage = stage; + event->pad_strip.strip_number = strip_number; + event->pad_strip.value = value; + event->pad_strip.group = mode_group; + event->pad_strip.mode = mode; + clutter_event_set_device (event, input_device); + clutter_event_set_source_device (event, input_device); + clutter_event_set_time (event, us2ms (time_us)); + + _clutter_input_device_set_stage (seat->core_pointer, stage); + + queue_event (event); +} + +static void +notify_pad_ring (ClutterInputDevice *input_device, + uint64_t time_us, + uint32_t ring_number, + uint32_t ring_source, + uint32_t mode_group, + uint32_t mode, + double angle) +{ + MetaInputDeviceNative *device_evdev; + ClutterInputDevicePadSource source; + MetaSeatNative *seat; + ClutterStage *stage; + ClutterEvent *event; + + /* We can drop the event on the floor if no stage has been + * associated with the device yet. */ + stage = _clutter_input_device_get_stage (input_device); + if (stage == NULL) + return; + + if (ring_source == LIBINPUT_TABLET_PAD_RING_SOURCE_FINGER) + source = CLUTTER_INPUT_DEVICE_PAD_SOURCE_FINGER; + else + source = CLUTTER_INPUT_DEVICE_PAD_SOURCE_UNKNOWN; + + device_evdev = META_INPUT_DEVICE_NATIVE (input_device); + seat = meta_input_device_native_get_seat (device_evdev); + + event = clutter_event_new (CLUTTER_PAD_RING); + meta_event_native_set_time_usec (event, time_us); + event->pad_ring.ring_source = source; + event->pad_ring.stage = stage; + event->pad_ring.ring_number = ring_number; + event->pad_ring.angle = angle; + event->pad_ring.group = mode_group; + event->pad_ring.mode = mode; + clutter_event_set_device (event, input_device); + clutter_event_set_source_device (event, input_device); + clutter_event_set_time (event, us2ms (time_us)); + + _clutter_input_device_set_stage (seat->core_pointer, stage); + + queue_event (event); +} + +static gboolean +meta_event_dispatch (GSource *g_source, + GSourceFunc callback, + gpointer user_data) +{ + MetaEventSource *source = (MetaEventSource *) g_source; + MetaSeatNative *seat; + ClutterEvent *event; + + _clutter_threads_acquire_lock (); + + seat = source->seat; + + /* Don't queue more events if we haven't finished handling the previous batch + */ + if (clutter_events_pending ()) + goto queue_event; + + dispatch_libinput (seat); + + queue_event: + event = clutter_event_get (); + + if (event) + { + ClutterModifierType event_state; + ClutterInputDevice *input_device = + clutter_event_get_source_device (event); + MetaInputDeviceNative *device_evdev = + META_INPUT_DEVICE_NATIVE (input_device); + MetaSeatNative *seat = + meta_input_device_native_get_seat (device_evdev); + + /* Drop events if we don't have any stage to forward them to */ + if (!_clutter_input_device_get_stage (input_device)) + goto out; + + /* update the device states *before* the event */ + event_state = seat->button_state | + xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_EFFECTIVE); + _clutter_input_device_set_state (seat->core_pointer, event_state); + _clutter_input_device_set_state (seat->core_keyboard, event_state); + + /* forward the event into clutter for emission etc. */ + _clutter_stage_queue_event (event->any.stage, event, FALSE); + } + +out: + _clutter_threads_release_lock (); + + return TRUE; +} +static GSourceFuncs event_funcs = { + meta_event_prepare, + meta_event_check, + meta_event_dispatch, + NULL +}; + +static MetaEventSource * +meta_event_source_new (MetaSeatNative *seat) +{ + GSource *source; + MetaEventSource *event_source; + gint fd; + + source = g_source_new (&event_funcs, sizeof (MetaEventSource)); + event_source = (MetaEventSource *) source; + + /* setup the source */ + event_source->seat = seat; + + fd = libinput_get_fd (seat->libinput); + event_source->event_poll_fd.fd = fd; + event_source->event_poll_fd.events = G_IO_IN; + + /* and finally configure and attach the GSource */ + g_source_set_priority (source, CLUTTER_PRIORITY_EVENTS); + g_source_add_poll (source, &event_source->event_poll_fd); + g_source_set_can_recurse (source, TRUE); + g_source_attach (source, NULL); + + return event_source; +} + +static void +meta_event_source_free (MetaEventSource *source) +{ + GSource *g_source = (GSource *) source; + + /* ignore the return value of close, it's not like we can do something + * about it */ + close (source->event_poll_fd.fd); + + g_source_destroy (g_source); + g_source_unref (g_source); +} + +static gboolean +has_touchscreen (MetaSeatNative *seat) +{ + GSList *l; + + for (l = seat->devices; l; l = l->next) + { + ClutterInputDeviceType device_type; + + device_type = clutter_input_device_get_device_type (l->data); + + if (device_type == CLUTTER_TOUCHSCREEN_DEVICE) + return TRUE; + } + + return FALSE; +} + +static void +update_touch_mode (MetaSeatNative *seat) +{ + gboolean touch_mode; + + /* No touch mode if we don't have a touchscreen, easy */ + if (!seat->has_touchscreen) + touch_mode = FALSE; + /* If we have a tablet mode switch, honor it being unset */ + else if (seat->has_tablet_switch && !seat->tablet_mode_switch_state) + touch_mode = FALSE; + /* If tablet mode is enabled, or if there is no tablet mode switch + * (eg. kiosk machines), assume touch-mode. + */ + else + touch_mode = TRUE; + + if (seat->touch_mode != touch_mode) + { + seat->touch_mode = touch_mode; + g_object_notify (G_OBJECT (seat), "touch-mode"); + } +} + +static ClutterInputDevice * +evdev_add_device (MetaSeatNative *seat, + struct libinput_device *libinput_device) +{ + ClutterInputDeviceType type; + ClutterInputDevice *device, *master = NULL; + ClutterActor *stage; + + device = meta_input_device_native_new (seat, libinput_device); + stage = CLUTTER_ACTOR (meta_seat_native_get_stage (seat)); + _clutter_input_device_set_stage (device, CLUTTER_STAGE (stage)); + + seat->devices = g_slist_prepend (seat->devices, device); + + /* Clutter assumes that device types are exclusive in the + * ClutterInputDevice API */ + type = meta_input_device_native_determine_type (libinput_device); + + if (type == CLUTTER_KEYBOARD_DEVICE) + master = seat->core_keyboard; + else if (type == CLUTTER_POINTER_DEVICE) + master = seat->core_pointer; + + if (master) + { + _clutter_input_device_set_associated_device (device, master); + _clutter_input_device_add_slave (master, device); + } + + return device; +} + +static void +evdev_remove_device (MetaSeatNative *seat, + MetaInputDeviceNative *device_evdev) +{ + ClutterInputDevice *device; + + device = CLUTTER_INPUT_DEVICE (device_evdev); + seat->devices = g_slist_remove (seat->devices, device); + + g_object_unref (device); +} + +static gboolean +meta_seat_native_handle_device_event (ClutterSeat *seat, + ClutterEvent *event) +{ + MetaSeatNative *seat_native = META_SEAT_NATIVE (seat); + ClutterInputDevice *device = event->device.device; + MetaInputDeviceNative *device_native = META_INPUT_DEVICE_NATIVE (device); + gboolean check_touch_mode; + + check_touch_mode = + clutter_input_device_get_device_type (device) == CLUTTER_TOUCHSCREEN_DEVICE; + + switch (event->type) + { + case CLUTTER_DEVICE_ADDED: + seat_native->has_touchscreen = check_touch_mode; + + if (libinput_device_has_capability (device_native->libinput_device, + LIBINPUT_DEVICE_CAP_SWITCH) && + libinput_device_switch_has_switch (device_native->libinput_device, + LIBINPUT_SWITCH_TABLET_MODE)) + { + seat_native->has_tablet_switch = TRUE; + check_touch_mode = TRUE; + } + break; + + case CLUTTER_DEVICE_REMOVED: + if (check_touch_mode) + seat_native->has_touchscreen = has_touchscreen (seat_native); + + if (seat_native->repeat_timer && seat_native->repeat_device == device) + meta_seat_native_clear_repeat_timer (seat_native); + break; + + default: + break; + } + + if (check_touch_mode) + update_touch_mode (seat_native); + + return TRUE; +} + +static gboolean +process_base_event (MetaSeatNative *seat, + struct libinput_event *event) +{ + ClutterInputDevice *device = NULL; + ClutterEvent *device_event; + struct libinput_device *libinput_device; + + switch (libinput_event_get_type (event)) + { + case LIBINPUT_EVENT_DEVICE_ADDED: + libinput_device = libinput_event_get_device (event); + + device = evdev_add_device (seat, libinput_device); + device_event = clutter_event_new (CLUTTER_DEVICE_ADDED); + clutter_event_set_device (device_event, device); + break; + + case LIBINPUT_EVENT_DEVICE_REMOVED: + libinput_device = libinput_event_get_device (event); + + device = libinput_device_get_user_data (libinput_device); + device_event = clutter_event_new (CLUTTER_DEVICE_REMOVED); + clutter_event_set_device (device_event, device); + evdev_remove_device (seat, + META_INPUT_DEVICE_NATIVE (device)); + break; + + default: + device_event = NULL; + } + + if (device_event) + { + device_event->device.stage = _clutter_input_device_get_stage (device); + queue_event (device_event); + return TRUE; + } + + return FALSE; +} + +static ClutterScrollSource +translate_scroll_source (enum libinput_pointer_axis_source source) +{ + switch (source) + { + case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL: + return CLUTTER_SCROLL_SOURCE_WHEEL; + case LIBINPUT_POINTER_AXIS_SOURCE_FINGER: + return CLUTTER_SCROLL_SOURCE_FINGER; + case LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS: + return CLUTTER_SCROLL_SOURCE_CONTINUOUS; + default: + return CLUTTER_SCROLL_SOURCE_UNKNOWN; + } +} + +static ClutterInputDeviceToolType +translate_tool_type (struct libinput_tablet_tool *libinput_tool) +{ + enum libinput_tablet_tool_type tool; + + tool = libinput_tablet_tool_get_type (libinput_tool); + + switch (tool) + { + case LIBINPUT_TABLET_TOOL_TYPE_PEN: + return CLUTTER_INPUT_DEVICE_TOOL_PEN; + case LIBINPUT_TABLET_TOOL_TYPE_ERASER: + return CLUTTER_INPUT_DEVICE_TOOL_ERASER; + case LIBINPUT_TABLET_TOOL_TYPE_BRUSH: + return CLUTTER_INPUT_DEVICE_TOOL_BRUSH; + case LIBINPUT_TABLET_TOOL_TYPE_PENCIL: + return CLUTTER_INPUT_DEVICE_TOOL_PENCIL; + case LIBINPUT_TABLET_TOOL_TYPE_AIRBRUSH: + return CLUTTER_INPUT_DEVICE_TOOL_AIRBRUSH; + case LIBINPUT_TABLET_TOOL_TYPE_MOUSE: + return CLUTTER_INPUT_DEVICE_TOOL_MOUSE; + case LIBINPUT_TABLET_TOOL_TYPE_LENS: + return CLUTTER_INPUT_DEVICE_TOOL_LENS; + default: + return CLUTTER_INPUT_DEVICE_TOOL_NONE; + } +} + +static void +input_device_update_tool (ClutterInputDevice *input_device, + struct libinput_tablet_tool *libinput_tool) +{ + MetaInputDeviceNative *evdev_device = META_INPUT_DEVICE_NATIVE (input_device); + MetaSeatNative *seat = meta_input_device_native_get_seat (evdev_device); + ClutterInputDeviceTool *tool = NULL; + ClutterInputDeviceToolType tool_type; + uint64_t tool_serial; + + if (libinput_tool) + { + tool_serial = libinput_tablet_tool_get_serial (libinput_tool); + tool_type = translate_tool_type (libinput_tool); + tool = clutter_input_device_lookup_tool (input_device, + tool_serial, tool_type); + + if (!tool) + { + tool = meta_input_device_tool_native_new (libinput_tool, + tool_serial, tool_type); + clutter_input_device_add_tool (input_device, tool); + } + } + + if (evdev_device->last_tool != tool) + { + evdev_device->last_tool = tool; + g_signal_emit_by_name (seat, "tool-changed", input_device, tool); + } +} + +static gdouble * +translate_tablet_axes (struct libinput_event_tablet_tool *tablet_event, + ClutterInputDeviceTool *tool) +{ + GArray *axes = g_array_new (FALSE, FALSE, sizeof (gdouble)); + struct libinput_tablet_tool *libinput_tool; + gdouble value; + + libinput_tool = libinput_event_tablet_tool_get_tool (tablet_event); + + value = libinput_event_tablet_tool_get_x (tablet_event); + g_array_append_val (axes, value); + value = libinput_event_tablet_tool_get_y (tablet_event); + g_array_append_val (axes, value); + + if (libinput_tablet_tool_has_distance (libinput_tool)) + { + value = libinput_event_tablet_tool_get_distance (tablet_event); + g_array_append_val (axes, value); + } + + if (libinput_tablet_tool_has_pressure (libinput_tool)) + { + value = libinput_event_tablet_tool_get_pressure (tablet_event); + value = meta_input_device_tool_native_translate_pressure (tool, value); + g_array_append_val (axes, value); + } + + if (libinput_tablet_tool_has_tilt (libinput_tool)) + { + value = libinput_event_tablet_tool_get_tilt_x (tablet_event); + g_array_append_val (axes, value); + value = libinput_event_tablet_tool_get_tilt_y (tablet_event); + g_array_append_val (axes, value); + } + + if (libinput_tablet_tool_has_rotation (libinput_tool)) + { + value = libinput_event_tablet_tool_get_rotation (tablet_event); + g_array_append_val (axes, value); + } + + if (libinput_tablet_tool_has_slider (libinput_tool)) + { + value = libinput_event_tablet_tool_get_slider_position (tablet_event); + g_array_append_val (axes, value); + } + + if (libinput_tablet_tool_has_wheel (libinput_tool)) + { + value = libinput_event_tablet_tool_get_wheel_delta (tablet_event); + g_array_append_val (axes, value); + } + + if (axes->len == 0) + { + g_array_free (axes, TRUE); + return NULL; + } + else + return (gdouble *) g_array_free (axes, FALSE); +} + +static MetaSeatNative * +seat_from_device (ClutterInputDevice *device) +{ + MetaInputDeviceNative *device_evdev = META_INPUT_DEVICE_NATIVE (device); + + return meta_input_device_native_get_seat (device_evdev); +} + +static void +notify_continuous_axis (MetaSeatNative *seat, + ClutterInputDevice *device, + uint64_t time_us, + ClutterScrollSource scroll_source, + struct libinput_event_pointer *axis_event) +{ + gdouble dx = 0.0, dy = 0.0; + ClutterScrollFinishFlags finish_flags = CLUTTER_SCROLL_FINISHED_NONE; + + if (libinput_event_pointer_has_axis (axis_event, + LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) + { + dx = libinput_event_pointer_get_axis_value ( + axis_event, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL); + + if (fabs (dx) < DBL_EPSILON) + finish_flags |= CLUTTER_SCROLL_FINISHED_HORIZONTAL; + } + if (libinput_event_pointer_has_axis (axis_event, + LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) + { + dy = libinput_event_pointer_get_axis_value ( + axis_event, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); + + if (fabs (dy) < DBL_EPSILON) + finish_flags |= CLUTTER_SCROLL_FINISHED_VERTICAL; + } + + meta_seat_native_notify_scroll_continuous (seat, device, time_us, + dx, dy, + scroll_source, finish_flags); +} + +static void +notify_discrete_axis (MetaSeatNative *seat, + ClutterInputDevice *device, + uint64_t time_us, + ClutterScrollSource scroll_source, + struct libinput_event_pointer *axis_event) +{ + gdouble discrete_dx = 0.0, discrete_dy = 0.0; + + if (libinput_event_pointer_has_axis (axis_event, + LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) + { + discrete_dx = libinput_event_pointer_get_axis_value_discrete ( + axis_event, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL); + } + if (libinput_event_pointer_has_axis (axis_event, + LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) + { + discrete_dy = libinput_event_pointer_get_axis_value_discrete ( + axis_event, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); + } + + meta_seat_native_notify_discrete_scroll (seat, device, + time_us, + discrete_dx, discrete_dy, + scroll_source); +} + +static void +process_tablet_axis (MetaSeatNative *seat, + struct libinput_event *event) +{ + struct libinput_device *libinput_device = libinput_event_get_device (event); + uint64_t time; + double x, y, dx, dy, *axes; + float stage_width, stage_height; + ClutterStage *stage; + ClutterInputDevice *device; + struct libinput_event_tablet_tool *tablet_event = + libinput_event_get_tablet_tool_event (event); + MetaInputDeviceNative *evdev_device; + + device = libinput_device_get_user_data (libinput_device); + evdev_device = META_INPUT_DEVICE_NATIVE (device); + + stage = _clutter_input_device_get_stage (device); + if (!stage) + return; + + axes = translate_tablet_axes (tablet_event, + evdev_device->last_tool); + if (!axes) + return; + + stage_width = clutter_actor_get_width (CLUTTER_ACTOR (stage)); + stage_height = clutter_actor_get_height (CLUTTER_ACTOR (stage)); + + time = libinput_event_tablet_tool_get_time_usec (tablet_event); + + if (clutter_input_device_get_mapping_mode (device) == CLUTTER_INPUT_DEVICE_MAPPING_RELATIVE || + clutter_input_device_tool_get_tool_type (evdev_device->last_tool) == CLUTTER_INPUT_DEVICE_TOOL_MOUSE || + clutter_input_device_tool_get_tool_type (evdev_device->last_tool) == CLUTTER_INPUT_DEVICE_TOOL_LENS) + { + dx = libinput_event_tablet_tool_get_dx (tablet_event); + dy = libinput_event_tablet_tool_get_dy (tablet_event); + notify_relative_tool_motion (device, time, dx, dy, axes); + } + else + { + x = libinput_event_tablet_tool_get_x_transformed (tablet_event, stage_width); + y = libinput_event_tablet_tool_get_y_transformed (tablet_event, stage_height); + notify_absolute_motion (device, time, x, y, axes); + } +} + +static gboolean +process_device_event (MetaSeatNative *seat, + struct libinput_event *event) +{ + gboolean handled = TRUE; + struct libinput_device *libinput_device = libinput_event_get_device(event); + ClutterInputDevice *device; + MetaInputDeviceNative *device_evdev; + + switch (libinput_event_get_type (event)) + { + case LIBINPUT_EVENT_KEYBOARD_KEY: + { + uint32_t key, key_state, seat_key_count; + uint64_t time_us; + struct libinput_event_keyboard *key_event = + libinput_event_get_keyboard_event (event); + + device = libinput_device_get_user_data (libinput_device); + time_us = libinput_event_keyboard_get_time_usec (key_event); + key = libinput_event_keyboard_get_key (key_event); + key_state = libinput_event_keyboard_get_key_state (key_event) == + LIBINPUT_KEY_STATE_PRESSED; + seat_key_count = + libinput_event_keyboard_get_seat_key_count (key_event); + + /* Ignore key events that are not seat wide state changes. */ + if ((key_state == LIBINPUT_KEY_STATE_PRESSED && + seat_key_count != 1) || + (key_state == LIBINPUT_KEY_STATE_RELEASED && + seat_key_count != 0)) + { + meta_topic (META_DEBUG_INPUT, + "Dropping key-%s of key 0x%x because seat-wide " + "key count is %d\n", + key_state == LIBINPUT_KEY_STATE_PRESSED ? "press" : "release", + key, seat_key_count); + break; + } + + meta_seat_native_notify_key (seat_from_device (device), + device, + time_us, key, key_state, TRUE); + + break; + } + + case LIBINPUT_EVENT_POINTER_MOTION: + { + struct libinput_event_pointer *pointer_event = + libinput_event_get_pointer_event (event); + uint64_t time_us; + double dx; + double dy; + double dx_unaccel; + double dy_unaccel; + + device = libinput_device_get_user_data (libinput_device); + time_us = libinput_event_pointer_get_time_usec (pointer_event); + dx = libinput_event_pointer_get_dx (pointer_event); + dy = libinput_event_pointer_get_dy (pointer_event); + dx_unaccel = libinput_event_pointer_get_dx_unaccelerated (pointer_event); + dy_unaccel = libinput_event_pointer_get_dy_unaccelerated (pointer_event); + + meta_seat_native_notify_relative_motion (seat_from_device (device), + device, + time_us, + dx, dy, + dx_unaccel, dy_unaccel); + + break; + } + + case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE: + { + uint64_t time_us; + double x, y; + float stage_width, stage_height; + ClutterStage *stage; + struct libinput_event_pointer *motion_event = + libinput_event_get_pointer_event (event); + device = libinput_device_get_user_data (libinput_device); + + stage = _clutter_input_device_get_stage (device); + if (stage == NULL) + break; + + stage_width = clutter_actor_get_width (CLUTTER_ACTOR (stage)); + stage_height = clutter_actor_get_height (CLUTTER_ACTOR (stage)); + + time_us = libinput_event_pointer_get_time_usec (motion_event); + x = libinput_event_pointer_get_absolute_x_transformed (motion_event, + stage_width); + y = libinput_event_pointer_get_absolute_y_transformed (motion_event, + stage_height); + + meta_seat_native_notify_absolute_motion (seat_from_device (device), + device, + time_us, + x, y, + NULL); + + break; + } + + case LIBINPUT_EVENT_POINTER_BUTTON: + { + uint32_t button, button_state, seat_button_count; + uint64_t time_us; + struct libinput_event_pointer *button_event = + libinput_event_get_pointer_event (event); + device = libinput_device_get_user_data (libinput_device); + + time_us = libinput_event_pointer_get_time_usec (button_event); + button = libinput_event_pointer_get_button (button_event); + button_state = libinput_event_pointer_get_button_state (button_event) == + LIBINPUT_BUTTON_STATE_PRESSED; + seat_button_count = + libinput_event_pointer_get_seat_button_count (button_event); + + /* Ignore button events that are not seat wide state changes. */ + if ((button_state == LIBINPUT_BUTTON_STATE_PRESSED && + seat_button_count != 1) || + (button_state == LIBINPUT_BUTTON_STATE_RELEASED && + seat_button_count != 0)) + { + meta_topic (META_DEBUG_INPUT, + "Dropping button-%s of button 0x%x because seat-wide " + "button count is %d\n", + button_state == LIBINPUT_BUTTON_STATE_PRESSED ? "press" : "release", + button, seat_button_count); + break; + } + + meta_seat_native_notify_button (seat_from_device (device), device, + time_us, button, button_state); + break; + } + + case LIBINPUT_EVENT_POINTER_AXIS: + { + uint64_t time_us; + enum libinput_pointer_axis_source source; + struct libinput_event_pointer *axis_event = + libinput_event_get_pointer_event (event); + MetaSeatNative *seat; + ClutterScrollSource scroll_source; + + device = libinput_device_get_user_data (libinput_device); + seat = meta_input_device_native_get_seat (META_INPUT_DEVICE_NATIVE (device)); + + time_us = libinput_event_pointer_get_time_usec (axis_event); + source = libinput_event_pointer_get_axis_source (axis_event); + scroll_source = translate_scroll_source (source); + + /* libinput < 0.8 sent wheel click events with value 10. Since 0.8 + the value is the angle of the click in degrees. To keep + backwards-compat with existing clients, we just send multiples of + the click count. */ + + switch (scroll_source) + { + case CLUTTER_SCROLL_SOURCE_WHEEL: + notify_discrete_axis (seat, device, time_us, scroll_source, + axis_event); + break; + case CLUTTER_SCROLL_SOURCE_FINGER: + case CLUTTER_SCROLL_SOURCE_CONTINUOUS: + case CLUTTER_SCROLL_SOURCE_UNKNOWN: + notify_continuous_axis (seat, device, time_us, scroll_source, + axis_event); + break; + } + break; + } + + case LIBINPUT_EVENT_TOUCH_DOWN: + { + int device_slot; + uint64_t time_us; + double x, y; + float stage_width, stage_height; + MetaSeatNative *seat; + ClutterStage *stage; + MetaTouchState *touch_state; + struct libinput_event_touch *touch_event = + libinput_event_get_touch_event (event); + + device = libinput_device_get_user_data (libinput_device); + device_evdev = META_INPUT_DEVICE_NATIVE (device); + seat = meta_input_device_native_get_seat (device_evdev); + + stage = _clutter_input_device_get_stage (device); + if (stage == NULL) + break; + + stage_width = clutter_actor_get_width (CLUTTER_ACTOR (stage)); + stage_height = clutter_actor_get_height (CLUTTER_ACTOR (stage)); + + device_slot = libinput_event_touch_get_slot (touch_event); + time_us = libinput_event_touch_get_time_usec (touch_event); + x = libinput_event_touch_get_x_transformed (touch_event, + stage_width); + y = libinput_event_touch_get_y_transformed (touch_event, + stage_height); + + touch_state = + meta_input_device_native_acquire_touch_state (device_evdev, + device_slot); + touch_state->coords.x = x; + touch_state->coords.y = y; + + meta_seat_native_notify_touch_event (seat, device, + CLUTTER_TOUCH_BEGIN, + time_us, + touch_state->seat_slot, + touch_state->coords.x, + touch_state->coords.y); + break; + } + + case LIBINPUT_EVENT_TOUCH_UP: + { + int device_slot; + uint64_t time_us; + MetaSeatNative *seat; + MetaTouchState *touch_state; + struct libinput_event_touch *touch_event = + libinput_event_get_touch_event (event); + + device = libinput_device_get_user_data (libinput_device); + device_evdev = META_INPUT_DEVICE_NATIVE (device); + seat = meta_input_device_native_get_seat (device_evdev); + + device_slot = libinput_event_touch_get_slot (touch_event); + time_us = libinput_event_touch_get_time_usec (touch_event); + touch_state = + meta_input_device_native_lookup_touch_state (device_evdev, + device_slot); + if (!touch_state) + break; + + meta_seat_native_notify_touch_event (seat, device, + CLUTTER_TOUCH_END, time_us, + touch_state->seat_slot, + touch_state->coords.x, + touch_state->coords.y); + meta_input_device_native_release_touch_state (device_evdev, + touch_state); + break; + } + + case LIBINPUT_EVENT_TOUCH_MOTION: + { + int device_slot; + uint64_t time_us; + double x, y; + float stage_width, stage_height; + MetaSeatNative *seat; + ClutterStage *stage; + MetaTouchState *touch_state; + struct libinput_event_touch *touch_event = + libinput_event_get_touch_event (event); + + device = libinput_device_get_user_data (libinput_device); + device_evdev = META_INPUT_DEVICE_NATIVE (device); + seat = meta_input_device_native_get_seat (device_evdev); + + stage = _clutter_input_device_get_stage (device); + if (stage == NULL) + break; + + stage_width = clutter_actor_get_width (CLUTTER_ACTOR (stage)); + stage_height = clutter_actor_get_height (CLUTTER_ACTOR (stage)); + + device_slot = libinput_event_touch_get_slot (touch_event); + time_us = libinput_event_touch_get_time_usec (touch_event); + x = libinput_event_touch_get_x_transformed (touch_event, + stage_width); + y = libinput_event_touch_get_y_transformed (touch_event, + stage_height); + + touch_state = + meta_input_device_native_lookup_touch_state (device_evdev, + device_slot); + if (!touch_state) + break; + + touch_state->coords.x = x; + touch_state->coords.y = y; + + meta_seat_native_notify_touch_event (seat, device, + CLUTTER_TOUCH_UPDATE, + time_us, + touch_state->seat_slot, + touch_state->coords.x, + touch_state->coords.y); + break; + } + case LIBINPUT_EVENT_TOUCH_CANCEL: + { + uint64_t time_us; + struct libinput_event_touch *touch_event = + libinput_event_get_touch_event (event); + + device = libinput_device_get_user_data (libinput_device); + device_evdev = META_INPUT_DEVICE_NATIVE (device); + time_us = libinput_event_touch_get_time_usec (touch_event); + + meta_input_device_native_release_touch_slots (device_evdev, time_us); + + break; + } + case LIBINPUT_EVENT_GESTURE_PINCH_BEGIN: + case LIBINPUT_EVENT_GESTURE_PINCH_END: + { + struct libinput_event_gesture *gesture_event = + libinput_event_get_gesture_event (event); + ClutterTouchpadGesturePhase phase; + uint32_t n_fingers; + uint64_t time_us; + + if (libinput_event_get_type (event) == LIBINPUT_EVENT_GESTURE_PINCH_BEGIN) + phase = CLUTTER_TOUCHPAD_GESTURE_PHASE_BEGIN; + else + phase = libinput_event_gesture_get_cancelled (gesture_event) ? + CLUTTER_TOUCHPAD_GESTURE_PHASE_CANCEL : CLUTTER_TOUCHPAD_GESTURE_PHASE_END; + + n_fingers = libinput_event_gesture_get_finger_count (gesture_event); + device = libinput_device_get_user_data (libinput_device); + time_us = libinput_event_gesture_get_time_usec (gesture_event); + notify_pinch_gesture_event (device, phase, time_us, 0, 0, 0, 0, n_fingers); + break; + } + case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE: + { + struct libinput_event_gesture *gesture_event = + libinput_event_get_gesture_event (event); + gdouble angle_delta, scale, dx, dy; + uint32_t n_fingers; + uint64_t time_us; + + n_fingers = libinput_event_gesture_get_finger_count (gesture_event); + device = libinput_device_get_user_data (libinput_device); + time_us = libinput_event_gesture_get_time_usec (gesture_event); + angle_delta = libinput_event_gesture_get_angle_delta (gesture_event); + scale = libinput_event_gesture_get_scale (gesture_event); + dx = libinput_event_gesture_get_dx (gesture_event); + dy = libinput_event_gesture_get_dy (gesture_event); + + notify_pinch_gesture_event (device, + CLUTTER_TOUCHPAD_GESTURE_PHASE_UPDATE, + time_us, dx, dy, angle_delta, scale, n_fingers); + break; + } + case LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN: + case LIBINPUT_EVENT_GESTURE_SWIPE_END: + { + struct libinput_event_gesture *gesture_event = + libinput_event_get_gesture_event (event); + ClutterTouchpadGesturePhase phase; + uint32_t n_fingers; + uint64_t time_us; + + device = libinput_device_get_user_data (libinput_device); + time_us = libinput_event_gesture_get_time_usec (gesture_event); + n_fingers = libinput_event_gesture_get_finger_count (gesture_event); + + if (libinput_event_get_type (event) == LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN) + phase = CLUTTER_TOUCHPAD_GESTURE_PHASE_BEGIN; + else + phase = libinput_event_gesture_get_cancelled (gesture_event) ? + CLUTTER_TOUCHPAD_GESTURE_PHASE_CANCEL : CLUTTER_TOUCHPAD_GESTURE_PHASE_END; + + notify_swipe_gesture_event (device, phase, time_us, n_fingers, 0, 0); + break; + } + case LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE: + { + struct libinput_event_gesture *gesture_event = + libinput_event_get_gesture_event (event); + uint32_t n_fingers; + uint64_t time_us; + double dx, dy; + + device = libinput_device_get_user_data (libinput_device); + time_us = libinput_event_gesture_get_time_usec (gesture_event); + n_fingers = libinput_event_gesture_get_finger_count (gesture_event); + dx = libinput_event_gesture_get_dx (gesture_event); + dy = libinput_event_gesture_get_dy (gesture_event); + + notify_swipe_gesture_event (device, + CLUTTER_TOUCHPAD_GESTURE_PHASE_UPDATE, + time_us, n_fingers, dx, dy); + break; + } + case LIBINPUT_EVENT_TABLET_TOOL_AXIS: + { + process_tablet_axis (seat, event); + break; + } + case LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY: + { + uint64_t time; + struct libinput_event_tablet_tool *tablet_event = + libinput_event_get_tablet_tool_event (event); + struct libinput_tablet_tool *libinput_tool = NULL; + enum libinput_tablet_tool_proximity_state state; + + state = libinput_event_tablet_tool_get_proximity_state (tablet_event); + time = libinput_event_tablet_tool_get_time_usec (tablet_event); + device = libinput_device_get_user_data (libinput_device); + + libinput_tool = libinput_event_tablet_tool_get_tool (tablet_event); + + if (state == LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN) + input_device_update_tool (device, libinput_tool); + notify_proximity (device, time, state == LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN); + if (state == LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT) + input_device_update_tool (device, NULL); + break; + } + case LIBINPUT_EVENT_TABLET_TOOL_BUTTON: + { + uint64_t time_us; + uint32_t button_state; + struct libinput_event_tablet_tool *tablet_event = + libinput_event_get_tablet_tool_event (event); + uint32_t tablet_button; + + process_tablet_axis (seat, event); + + device = libinput_device_get_user_data (libinput_device); + time_us = libinput_event_tablet_tool_get_time_usec (tablet_event); + tablet_button = libinput_event_tablet_tool_get_button (tablet_event); + + button_state = libinput_event_tablet_tool_get_button_state (tablet_event) == + LIBINPUT_BUTTON_STATE_PRESSED; + + meta_seat_native_notify_button (seat_from_device (device), device, + time_us, tablet_button, button_state); + break; + } + case LIBINPUT_EVENT_TABLET_TOOL_TIP: + { + uint64_t time_us; + uint32_t button_state; + struct libinput_event_tablet_tool *tablet_event = + libinput_event_get_tablet_tool_event (event); + + device = libinput_device_get_user_data (libinput_device); + time_us = libinput_event_tablet_tool_get_time_usec (tablet_event); + + button_state = libinput_event_tablet_tool_get_tip_state (tablet_event) == + LIBINPUT_TABLET_TOOL_TIP_DOWN; + + /* To avoid jumps on tip, notify axes before the tip down event + but after the tip up event */ + if (button_state) + process_tablet_axis (seat, event); + + meta_seat_native_notify_button (seat_from_device (device), device, + time_us, BTN_TOUCH, button_state); + if (!button_state) + process_tablet_axis (seat, event); + break; + } + case LIBINPUT_EVENT_TABLET_PAD_BUTTON: + { + uint64_t time; + uint32_t button_state, button, group, mode; + struct libinput_tablet_pad_mode_group *mode_group; + struct libinput_event_tablet_pad *pad_event = + libinput_event_get_tablet_pad_event (event); + + device = libinput_device_get_user_data (libinput_device); + time = libinput_event_tablet_pad_get_time_usec (pad_event); + + mode_group = libinput_event_tablet_pad_get_mode_group (pad_event); + group = libinput_tablet_pad_mode_group_get_index (mode_group); + mode = libinput_event_tablet_pad_get_mode (pad_event); + + button = libinput_event_tablet_pad_get_button_number (pad_event); + button_state = libinput_event_tablet_pad_get_button_state (pad_event) == + LIBINPUT_BUTTON_STATE_PRESSED; + notify_pad_button (device, time, button, group, mode, button_state); + break; + } + case LIBINPUT_EVENT_TABLET_PAD_STRIP: + { + uint64_t time; + uint32_t number, source, group, mode; + struct libinput_tablet_pad_mode_group *mode_group; + struct libinput_event_tablet_pad *pad_event = + libinput_event_get_tablet_pad_event (event); + double value; + + device = libinput_device_get_user_data (libinput_device); + time = libinput_event_tablet_pad_get_time_usec (pad_event); + number = libinput_event_tablet_pad_get_strip_number (pad_event); + value = libinput_event_tablet_pad_get_strip_position (pad_event); + source = libinput_event_tablet_pad_get_strip_source (pad_event); + + mode_group = libinput_event_tablet_pad_get_mode_group (pad_event); + group = libinput_tablet_pad_mode_group_get_index (mode_group); + mode = libinput_event_tablet_pad_get_mode (pad_event); + + notify_pad_strip (device, time, number, source, group, mode, value); + break; + } + case LIBINPUT_EVENT_TABLET_PAD_RING: + { + uint64_t time; + uint32_t number, source, group, mode; + struct libinput_tablet_pad_mode_group *mode_group; + struct libinput_event_tablet_pad *pad_event = + libinput_event_get_tablet_pad_event (event); + double angle; + + device = libinput_device_get_user_data (libinput_device); + time = libinput_event_tablet_pad_get_time_usec (pad_event); + number = libinput_event_tablet_pad_get_ring_number (pad_event); + angle = libinput_event_tablet_pad_get_ring_position (pad_event); + source = libinput_event_tablet_pad_get_ring_source (pad_event); + + mode_group = libinput_event_tablet_pad_get_mode_group (pad_event); + group = libinput_tablet_pad_mode_group_get_index (mode_group); + mode = libinput_event_tablet_pad_get_mode (pad_event); + + notify_pad_ring (device, time, number, source, group, mode, angle); + break; + } + case LIBINPUT_EVENT_SWITCH_TOGGLE: + { + struct libinput_event_switch *switch_event = + libinput_event_get_switch_event (event); + enum libinput_switch sw = + libinput_event_switch_get_switch (switch_event); + enum libinput_switch_state state = + libinput_event_switch_get_switch_state (switch_event); + + if (sw == LIBINPUT_SWITCH_TABLET_MODE) + { + seat->tablet_mode_switch_state = (state == LIBINPUT_SWITCH_STATE_ON); + update_touch_mode (seat); + } + break; + } + default: + handled = FALSE; + } + + return handled; +} + +static gboolean +filter_event (MetaSeatNative *seat, + struct libinput_event *event) +{ + gboolean retval = CLUTTER_EVENT_PROPAGATE; + MetaEventFilter *filter; + GSList *tmp_list; + + tmp_list = seat->event_filters; + + while (tmp_list) + { + filter = tmp_list->data; + retval = filter->func (event, filter->data); + tmp_list = tmp_list->next; + + if (retval != CLUTTER_EVENT_PROPAGATE) + break; + } + + return retval; +} + +static void +process_event (MetaSeatNative *seat, + struct libinput_event *event) +{ + gboolean retval; + + retval = filter_event (seat, event); + + if (retval != CLUTTER_EVENT_PROPAGATE) + return; + + if (process_base_event (seat, event)) + return; + if (process_device_event (seat, event)) + return; +} + +static void +process_events (MetaSeatNative *seat) +{ + struct libinput_event *event; + + while ((event = libinput_get_event (seat->libinput))) + { + process_event(seat, event); + libinput_event_destroy(event); + } +} + +static int +open_restricted (const char *path, + int flags, + void *user_data) +{ + gint fd; + + if (device_open_callback) + { + GError *error = NULL; + + fd = device_open_callback (path, flags, device_callback_data, &error); + + if (fd < 0) + { + g_warning ("Could not open device %s: %s", path, error->message); + g_error_free (error); + } + } + else + { + fd = open (path, O_RDWR | O_NONBLOCK); + if (fd < 0) + { + g_warning ("Could not open device %s: %s", path, strerror (errno)); + } + } + + return fd; +} + +static void +close_restricted (int fd, + void *user_data) +{ + if (device_close_callback) + device_close_callback (fd, device_callback_data); + else + close (fd); +} + +static const struct libinput_interface libinput_interface = { + open_restricted, + close_restricted +}; + +static void +meta_seat_native_constructed (GObject *object) +{ + MetaSeatNative *seat = META_SEAT_NATIVE (object); + ClutterInputDevice *device; + ClutterStage *stage; + MetaEventSource *source; + struct udev *udev; + struct xkb_keymap *xkb_keymap; + + device = meta_input_device_native_new_virtual ( + seat, CLUTTER_POINTER_DEVICE, + CLUTTER_INPUT_MODE_MASTER); + stage = meta_seat_native_get_stage (seat); + _clutter_input_device_set_stage (device, stage); + seat->pointer_x = INITIAL_POINTER_X; + seat->pointer_y = INITIAL_POINTER_Y; + _clutter_input_device_set_coords (device, NULL, + seat->pointer_x, seat->pointer_y, + NULL); + seat->core_pointer = device; + + device = meta_input_device_native_new_virtual ( + seat, CLUTTER_KEYBOARD_DEVICE, + CLUTTER_INPUT_MODE_MASTER); + _clutter_input_device_set_stage (device, stage); + seat->core_keyboard = device; + + udev = udev_new (); + if (G_UNLIKELY (udev == NULL)) + { + g_warning ("Failed to create udev object"); + return; + } + + seat->libinput = libinput_udev_create_context (&libinput_interface, + seat, udev); + if (seat->libinput == NULL) + { + g_critical ("Failed to create the libinput object."); + return; + } + + if (libinput_udev_assign_seat (seat->libinput, seat->seat_id) == -1) + { + g_critical ("Failed to assign a seat to the libinput object."); + libinput_unref (seat->libinput); + seat->libinput = NULL; + return; + } + + udev_unref (udev); + + seat->udev_client = g_udev_client_new ((const gchar *[]) { "input", NULL }); + + source = meta_event_source_new (seat); + seat->event_source = source; + + seat->keymap = g_object_new (META_TYPE_KEYMAP_NATIVE, NULL); + xkb_keymap = meta_keymap_native_get_keyboard_map (seat->keymap); + + if (xkb_keymap) + { + seat->xkb = xkb_state_new (xkb_keymap); + + seat->caps_lock_led = + xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_CAPS); + seat->num_lock_led = + xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_NUM); + seat->scroll_lock_led = + xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_SCROLL); + } + + seat->has_touchscreen = has_touchscreen (seat); + update_touch_mode (seat); + + if (G_OBJECT_CLASS (meta_seat_native_parent_class)->constructed) + G_OBJECT_CLASS (meta_seat_native_parent_class)->constructed (object); +} + +static void +meta_seat_native_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaSeatNative *seat_native = META_SEAT_NATIVE (object); + + switch (prop_id) + { + case PROP_SEAT_ID: + seat_native->seat_id = g_value_dup_string (value); + break; + case PROP_TOUCH_MODE: + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_seat_native_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaSeatNative *seat_native = META_SEAT_NATIVE (object); + + switch (prop_id) + { + case PROP_SEAT_ID: + g_value_set_string (value, seat_native->seat_id); + break; + case PROP_TOUCH_MODE: + g_value_set_boolean (value, seat_native->touch_mode); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_seat_native_dispose (GObject *object) +{ + MetaSeatNative *seat = META_SEAT_NATIVE (object); + + g_clear_signal_handler (&seat->stage_added_handler, seat->stage_manager); + g_clear_signal_handler (&seat->stage_removed_handler, seat->stage_manager); + + if (seat->stage_manager) + { + g_object_unref (seat->stage_manager); + seat->stage_manager = NULL; + } + + if (seat->libinput) + { + libinput_unref (seat->libinput); + seat->libinput = NULL; + } + + G_OBJECT_CLASS (meta_seat_native_parent_class)->dispose (object); +} + +static void +meta_seat_native_finalize (GObject *object) +{ + MetaSeatNative *seat = META_SEAT_NATIVE (object); + GSList *iter; + + for (iter = seat->devices; iter; iter = g_slist_next (iter)) + { + ClutterInputDevice *device = iter->data; + + g_object_unref (device); + } + g_slist_free (seat->devices); + g_free (seat->touch_states); + + g_object_unref (seat->udev_client); + + meta_event_source_free (seat->event_source); + + xkb_state_unref (seat->xkb); + + meta_seat_native_clear_repeat_timer (seat); + + if (seat->libinput_seat) + libinput_seat_unref (seat->libinput_seat); + + g_list_free (seat->free_device_ids); + + if (seat->constrain_data_notify != NULL) + seat->constrain_data_notify (seat->constrain_data); + + g_free (seat->seat_id); + + G_OBJECT_CLASS (meta_seat_native_parent_class)->finalize (object); +} + +static ClutterInputDevice * +meta_seat_native_get_pointer (ClutterSeat *seat) +{ + MetaSeatNative *seat_native = META_SEAT_NATIVE (seat); + + return seat_native->core_pointer; +} + +static ClutterInputDevice * +meta_seat_native_get_keyboard (ClutterSeat *seat) +{ + MetaSeatNative *seat_native = META_SEAT_NATIVE (seat); + + return seat_native->core_keyboard; +} + +static GList * +meta_seat_native_list_devices (ClutterSeat *seat) +{ + MetaSeatNative *seat_native = META_SEAT_NATIVE (seat); + GList *devices = NULL; + GSList *l; + + for (l = seat_native->devices; l; l = l->next) + devices = g_list_prepend (devices, l->data); + + return devices; +} + +static void +meta_seat_native_bell_notify (ClutterSeat *seat) +{ + MetaDisplay *display = meta_get_display (); + + meta_bell_notify (display, NULL); +} + +static ClutterKeymap * +meta_seat_native_get_keymap (ClutterSeat *seat) +{ + MetaSeatNative *seat_native = META_SEAT_NATIVE (seat); + + return CLUTTER_KEYMAP (seat_native->keymap); +} + +static void +meta_seat_native_copy_event_data (ClutterSeat *seat, + const ClutterEvent *src, + ClutterEvent *dest) +{ + MetaEventNative *event_evdev; + + event_evdev = _clutter_event_get_platform_data (src); + if (event_evdev != NULL) + _clutter_event_set_platform_data (dest, meta_event_native_copy (event_evdev)); +} + +static void +meta_seat_native_free_event_data (ClutterSeat *seat, + ClutterEvent *event) +{ + MetaEventNative *event_evdev; + + event_evdev = _clutter_event_get_platform_data (event); + if (event_evdev != NULL) + meta_event_native_free (event_evdev); +} + +static void +meta_seat_native_apply_kbd_a11y_settings (ClutterSeat *seat, + ClutterKbdA11ySettings *settings) +{ + ClutterInputDevice *device; + + device = clutter_seat_get_keyboard (seat); + if (device) + meta_input_device_native_apply_kbd_a11y_settings (META_INPUT_DEVICE_NATIVE (device), + settings); +} + +static ClutterVirtualInputDevice * +meta_seat_native_create_virtual_device (ClutterSeat *seat, + ClutterInputDeviceType device_type) +{ + return g_object_new (META_TYPE_VIRTUAL_INPUT_DEVICE_NATIVE, + "seat", seat, + "device-type", device_type, + NULL); +} + +static ClutterVirtualDeviceType +meta_seat_native_get_supported_virtual_device_types (ClutterSeat *seat) +{ + return (CLUTTER_VIRTUAL_DEVICE_TYPE_KEYBOARD | + CLUTTER_VIRTUAL_DEVICE_TYPE_POINTER | + CLUTTER_VIRTUAL_DEVICE_TYPE_TOUCHSCREEN); +} + +static void +meta_seat_native_compress_motion (ClutterSeat *seat, + ClutterEvent *event, + const ClutterEvent *to_discard) +{ + double dx, dy; + double dx_unaccel, dy_unaccel; + double dst_dx = 0.0, dst_dy = 0.0; + double dst_dx_unaccel = 0.0, dst_dy_unaccel = 0.0; + + if (!meta_event_native_get_relative_motion (to_discard, + &dx, &dy, + &dx_unaccel, &dy_unaccel)) + return; + + meta_event_native_get_relative_motion (event, + &dst_dx, &dst_dy, + &dst_dx_unaccel, &dst_dy_unaccel); + meta_event_native_set_relative_motion (event, + dx + dst_dx, + dy + dst_dy, + dx_unaccel + dst_dx_unaccel, + dy_unaccel + dst_dy_unaccel); +} + +static void +meta_seat_native_warp_pointer (ClutterSeat *seat, + int x, + int y) +{ + MetaSeatNative *seat_native = META_SEAT_NATIVE (seat); + MetaBackend *backend = meta_get_backend (); + MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend); + + notify_absolute_motion (seat_native->core_pointer, 0, x, y, NULL); + + meta_cursor_tracker_update_position (cursor_tracker, x, y); +} + +static void +meta_seat_native_class_init (MetaSeatNativeClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + ClutterSeatClass *seat_class = CLUTTER_SEAT_CLASS (klass); + + object_class->constructed = meta_seat_native_constructed; + object_class->set_property = meta_seat_native_set_property; + object_class->get_property = meta_seat_native_get_property; + object_class->dispose = meta_seat_native_dispose; + object_class->finalize = meta_seat_native_finalize; + + seat_class->get_pointer = meta_seat_native_get_pointer; + seat_class->get_keyboard = meta_seat_native_get_keyboard; + seat_class->list_devices = meta_seat_native_list_devices; + seat_class->bell_notify = meta_seat_native_bell_notify; + seat_class->get_keymap = meta_seat_native_get_keymap; + seat_class->copy_event_data = meta_seat_native_copy_event_data; + seat_class->free_event_data = meta_seat_native_free_event_data; + seat_class->apply_kbd_a11y_settings = meta_seat_native_apply_kbd_a11y_settings; + seat_class->create_virtual_device = meta_seat_native_create_virtual_device; + seat_class->get_supported_virtual_device_types = meta_seat_native_get_supported_virtual_device_types; + seat_class->compress_motion = meta_seat_native_compress_motion; + seat_class->warp_pointer = meta_seat_native_warp_pointer; + seat_class->handle_device_event = meta_seat_native_handle_device_event; + + props[PROP_SEAT_ID] = + g_param_spec_string ("seat-id", + "Seat ID", + "Seat ID", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY); + + g_object_class_install_properties (object_class, N_PROPS, props); + + g_object_class_override_property (object_class, PROP_TOUCH_MODE, + "touch-mode"); +} + +static void +meta_seat_native_stage_added_cb (ClutterStageManager *manager, + ClutterStage *stage, + MetaSeatNative *seat) +{ + /* NB: Currently we can only associate a single stage with all evdev + * devices. + * + * We save a pointer to the stage so if we release/reclaim input + * devices due to switching virtual terminals then we know what + * stage to re associate the devices with. + */ + meta_seat_native_set_stage (seat, stage); + + /* We only want to do this once so we can catch the default + stage. If the application has multiple stages then it will need + to manage the stage of the input devices itself */ + g_clear_signal_handler (&seat->stage_added_handler, seat->stage_manager); +} + +static void +meta_seat_native_stage_removed_cb (ClutterStageManager *manager, + ClutterStage *stage, + MetaSeatNative *seat) +{ + meta_seat_native_set_stage (seat, NULL); +} + +static void +meta_seat_native_init (MetaSeatNative *seat) +{ + seat->stage_manager = clutter_stage_manager_get_default (); + g_object_ref (seat->stage_manager); + + /* evdev doesn't have any way to link an event to a particular stage + so we'll have to leave it up to applications to set the + corresponding stage for an input device. However to make it + easier for applications that are only using one fullscreen stage + (which is probably the most frequent use-case for the evdev + backend) we'll associate any input devices that don't have a + stage with the first stage created. */ + seat->stage_added_handler = + g_signal_connect (seat->stage_manager, + "stage-added", + G_CALLBACK (meta_seat_native_stage_added_cb), + seat); + seat->stage_removed_handler = + g_signal_connect (seat->stage_manager, + "stage-removed", + G_CALLBACK (meta_seat_native_stage_removed_cb), + seat); + + seat->device_id_next = INITIAL_DEVICE_ID; + + seat->repeat = TRUE; + seat->repeat_delay = 250; /* ms */ + seat->repeat_interval = 33; /* ms */ +} + +ClutterInputDevice * +meta_seat_native_get_device (MetaSeatNative *seat, + int id) +{ + ClutterInputDevice *device; + GSList *l; + + for (l = seat->devices; l; l = l->next) + { + device = l->data; + + if (clutter_input_device_get_device_id (device) == id) + return device; + } + + return NULL; +} + +void +meta_seat_native_set_stage (MetaSeatNative *seat, + ClutterStage *stage) +{ + GSList *l; + + if (seat->stage == stage) + return; + + seat->stage = stage; + _clutter_input_device_set_stage (seat->core_pointer, stage); + _clutter_input_device_set_stage (seat->core_keyboard, stage); + + for (l = seat->devices; l; l = l->next) + { + ClutterInputDevice *device = l->data; + + _clutter_input_device_set_stage (device, stage); + } +} + +ClutterStage * +meta_seat_native_get_stage (MetaSeatNative *seat) +{ + return seat->stage; +} + +/** + * meta_seat_native_set_device_callbacks: (skip) + * @open_callback: the user replacement for open() + * @close_callback: the user replacement for close() + * @user_data: user data for @callback + * + * Through this function, the application can set a custom callback + * to be invoked when Clutter is about to open an evdev device. It can do + * so if special handling is needed, for example to circumvent permission + * problems. + * + * Setting @callback to %NULL will reset the default behavior. + * + * For reliable effects, this function must be called before clutter_init(). + */ +void +meta_seat_native_set_device_callbacks (MetaOpenDeviceCallback open_callback, + MetaCloseDeviceCallback close_callback, + gpointer user_data) +{ + device_open_callback = open_callback; + device_close_callback = close_callback; + device_callback_data = user_data; +} + +/** + * meta_seat_native_set_pointer_constrain_callback: + * @seat: the #ClutterSeat created by the evdev backend + * @callback: the callback + * @user_data: data to pass to the callback + * @user_data_notify: function to be called when removing the callback + * + * Sets a callback to be invoked for every pointer motion. The callback + * can then modify the new pointer coordinates to constrain movement within + * a specific region. + */ +void +meta_seat_native_set_pointer_constrain_callback (MetaSeatNative *seat, + MetaPointerConstrainCallback callback, + gpointer user_data, + GDestroyNotify user_data_notify) +{ + g_return_if_fail (META_IS_SEAT_NATIVE (seat)); + + if (seat->constrain_data_notify) + seat->constrain_data_notify (seat->constrain_data); + + seat->constrain_callback = callback; + seat->constrain_data = user_data; + seat->constrain_data_notify = user_data_notify; +} + +void +meta_seat_native_set_relative_motion_filter (MetaSeatNative *seat, + MetaRelativeMotionFilter filter, + gpointer user_data) +{ + g_return_if_fail (META_IS_SEAT_NATIVE (seat)); + + seat->relative_motion_filter = filter; + seat->relative_motion_filter_user_data = user_data; +} + +/** + * meta_seat_native_add_filter: (skip) + * @func: (closure data): a filter function + * @data: (allow-none): user data to be passed to the filter function, or %NULL + * @destroy_notify: (allow-none): function to call on @data when the filter is removed, or %NULL + * + * Adds an event filter function. + */ +void +meta_seat_native_add_filter (MetaSeatNative *seat, + MetaEvdevFilterFunc func, + gpointer data, + GDestroyNotify destroy_notify) +{ + MetaEventFilter *filter; + + g_return_if_fail (func != NULL); + + filter = g_new0 (MetaEventFilter, 1); + filter->func = func; + filter->data = data; + filter->destroy_notify = destroy_notify; + + seat->event_filters = g_slist_append (seat->event_filters, filter); +} + +/** + * meta_seat_native_remove_filter: (skip) + * @func: a filter function + * @data: (allow-none): user data to be passed to the filter function, or %NULL + * + * Removes the given filter function. + */ +void +meta_seat_native_remove_filter (MetaSeatNative *seat, + MetaEvdevFilterFunc func, + gpointer data) +{ + MetaEventFilter *filter; + GSList *tmp_list; + + g_return_if_fail (func != NULL); + + tmp_list = seat->event_filters; + + while (tmp_list) + { + filter = tmp_list->data; + + if (filter->func == func && filter->data == data) + { + if (filter->destroy_notify) + filter->destroy_notify (filter->data); + g_free (filter); + seat->event_filters = + g_slist_delete_link (seat->event_filters, tmp_list); + return; + } + + tmp_list = tmp_list->next; + } +} + +void +meta_seat_native_update_xkb_state (MetaSeatNative *seat) +{ + xkb_mod_mask_t latched_mods; + xkb_mod_mask_t locked_mods; + struct xkb_keymap *xkb_keymap; + + xkb_keymap = meta_keymap_native_get_keyboard_map (seat->keymap); + + latched_mods = xkb_state_serialize_mods (seat->xkb, + XKB_STATE_MODS_LATCHED); + locked_mods = xkb_state_serialize_mods (seat->xkb, + XKB_STATE_MODS_LOCKED); + xkb_state_unref (seat->xkb); + seat->xkb = xkb_state_new (xkb_keymap); + + xkb_state_update_mask (seat->xkb, + 0, /* depressed */ + latched_mods, + locked_mods, + 0, 0, seat->layout_idx); + + seat->caps_lock_led = xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_CAPS); + seat->num_lock_led = xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_NUM); + seat->scroll_lock_led = xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_SCROLL); + + meta_seat_native_sync_leds (seat); +} + +gint +meta_seat_native_acquire_device_id (MetaSeatNative *seat) +{ + GList *first; + gint next_id; + + if (seat->free_device_ids == NULL) + { + gint i; + + /* We ran out of free ID's, so append 10 new ones. */ + for (i = 0; i < 10; i++) + seat->free_device_ids = + g_list_append (seat->free_device_ids, + GINT_TO_POINTER (seat->device_id_next++)); + } + + first = g_list_first (seat->free_device_ids); + next_id = GPOINTER_TO_INT (first->data); + seat->free_device_ids = g_list_delete_link (seat->free_device_ids, first); + + return next_id; +} + +static int +compare_ids (gconstpointer a, + gconstpointer b) +{ + return GPOINTER_TO_INT (a) - GPOINTER_TO_INT (b); +} + +void +meta_seat_native_release_device_id (MetaSeatNative *seat, + ClutterInputDevice *device) +{ + gint device_id; + + device_id = clutter_input_device_get_device_id (device); + seat->free_device_ids = g_list_insert_sorted (seat->free_device_ids, + GINT_TO_POINTER (device_id), + compare_ids); +} + +/** + * meta_seat_native_release_devices: + * + * Releases all the evdev devices that Clutter is currently managing. This api + * is typically used when switching away from the Clutter application when + * switching tty. The devices can be reclaimed later with a call to + * meta_seat_native_reclaim_devices(). + * + * This function should only be called after clutter has been initialized. + */ +void +meta_seat_native_release_devices (MetaSeatNative *seat) +{ + g_return_if_fail (META_IS_SEAT_NATIVE (seat)); + + if (seat->released) + { + g_warning ("meta_seat_native_release_devices() shouldn't be called " + "multiple times without a corresponding call to " + "meta_seat_native_reclaim_devices() first"); + return; + } + + libinput_suspend (seat->libinput); + process_events (seat); + + seat->released = TRUE; +} + +/** + * meta_seat_native_reclaim_devices: + * + * This causes Clutter to re-probe for evdev devices. This is must only be + * called after a corresponding call to meta_seat_native_release_devices() + * was previously used to release all evdev devices. This API is typically + * used when a clutter application using evdev has regained focus due to + * switching ttys. + * + * This function should only be called after clutter has been initialized. + */ +void +meta_seat_native_reclaim_devices (MetaSeatNative *seat) +{ + if (!seat->released) + { + g_warning ("Spurious call to meta_seat_native_reclaim_devices() without " + "previous call to meta_seat_native_release_devices"); + return; + } + + libinput_resume (seat->libinput); + meta_seat_native_update_xkb_state (seat); + process_events (seat); + + seat->released = FALSE; +} + +/** + * meta_seat_native_set_keyboard_map: (skip) + * @seat: the #ClutterSeat created by the evdev backend + * @keymap: the new keymap + * + * Instructs @evdev to use the speficied keyboard map. This will cause + * the backend to drop the state and create a new one with the new + * map. To avoid state being lost, callers should ensure that no key + * is pressed when calling this function. + */ +void +meta_seat_native_set_keyboard_map (MetaSeatNative *seat, + struct xkb_keymap *xkb_keymap) +{ + ClutterKeymap *keymap; + + g_return_if_fail (META_IS_SEAT_NATIVE (seat)); + + keymap = clutter_seat_get_keymap (CLUTTER_SEAT (seat)); + meta_keymap_native_set_keyboard_map (META_KEYMAP_NATIVE (keymap), + xkb_keymap); + + meta_seat_native_update_xkb_state (seat); +} + +/** + * meta_seat_native_get_keyboard_map: (skip) + * @seat: the #ClutterSeat created by the evdev backend + * + * Retrieves the #xkb_keymap in use by the evdev backend. + * + * Return value: the #xkb_keymap. + */ +struct xkb_keymap * +meta_seat_native_get_keyboard_map (MetaSeatNative *seat) +{ + g_return_val_if_fail (META_IS_SEAT_NATIVE (seat), NULL); + + return xkb_state_get_keymap (seat->xkb); +} + +/** + * meta_seat_native_set_keyboard_layout_index: (skip) + * @seat: the #ClutterSeat created by the evdev backend + * @idx: the xkb layout index to set + * + * Sets the xkb layout index on the backend's #xkb_state . + */ +void +meta_seat_native_set_keyboard_layout_index (MetaSeatNative *seat, + xkb_layout_index_t idx) +{ + xkb_mod_mask_t depressed_mods; + xkb_mod_mask_t latched_mods; + xkb_mod_mask_t locked_mods; + struct xkb_state *state; + + g_return_if_fail (META_IS_SEAT_NATIVE (seat)); + + state = seat->xkb; + + depressed_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_DEPRESSED); + latched_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_LATCHED); + locked_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED); + + xkb_state_update_mask (state, depressed_mods, latched_mods, locked_mods, 0, 0, idx); + + seat->layout_idx = idx; +} + +/** + * meta_seat_native_get_keyboard_layout_index: (skip) + */ +xkb_layout_index_t +meta_seat_native_get_keyboard_layout_index (MetaSeatNative *seat) +{ + return seat->layout_idx; +} + +/** + * meta_seat_native_set_keyboard_numlock: (skip) + * @seat: the #ClutterSeat created by the evdev backend + * @numlock_set: TRUE to set NumLock ON, FALSE otherwise. + * + * Sets the NumLock state on the backend's #xkb_state . + */ +void +meta_seat_native_set_keyboard_numlock (MetaSeatNative *seat, + gboolean numlock_state) +{ + xkb_mod_mask_t depressed_mods; + xkb_mod_mask_t latched_mods; + xkb_mod_mask_t locked_mods; + xkb_mod_mask_t group_mods; + xkb_mod_mask_t numlock; + struct xkb_keymap *xkb_keymap; + ClutterKeymap *keymap; + + g_return_if_fail (META_IS_SEAT_NATIVE (seat)); + + keymap = clutter_seat_get_keymap (CLUTTER_SEAT (seat)); + xkb_keymap = meta_keymap_native_get_keyboard_map (META_KEYMAP_NATIVE (keymap)); + + numlock = (1 << xkb_keymap_mod_get_index (xkb_keymap, "Mod2")); + + depressed_mods = xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_DEPRESSED); + latched_mods = xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_LATCHED); + locked_mods = xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_LOCKED); + group_mods = xkb_state_serialize_layout (seat->xkb, XKB_STATE_LAYOUT_EFFECTIVE); + + if (numlock_state) + locked_mods |= numlock; + else + locked_mods &= ~numlock; + + xkb_state_update_mask (seat->xkb, + depressed_mods, + latched_mods, + locked_mods, + 0, 0, + group_mods); + + meta_seat_native_sync_leds (seat); +} + +/** + * meta_seat_native_set_keyboard_repeat: + * @seat: the #ClutterSeat created by the evdev backend + * @repeat: whether to enable or disable keyboard repeat events + * @delay: the delay in ms between the hardware key press event and + * the first synthetic event + * @interval: the period in ms between consecutive synthetic key + * press events + * + * Enables or disables sythetic key press events, allowing for initial + * delay and interval period to be specified. + */ +void +meta_seat_native_set_keyboard_repeat (MetaSeatNative *seat, + gboolean repeat, + uint32_t delay, + uint32_t interval) +{ + g_return_if_fail (META_IS_SEAT_NATIVE (seat)); + + seat->repeat = repeat; + seat->repeat_delay = delay; + seat->repeat_interval = interval; +} + +struct xkb_state * +meta_seat_native_get_xkb_state (MetaSeatNative *seat) +{ + return seat->xkb; +} diff --git a/src/backends/native/meta-seat-native.h b/src/backends/native/meta-seat-native.h new file mode 100644 index 000000000..61e6ffd30 --- /dev/null +++ b/src/backends/native/meta-seat-native.h @@ -0,0 +1,325 @@ +/* + * Copyright (C) 2010 Intel Corp. + * Copyright (C) 2014 Jonas Ådahl + * Copyright (C) 2016 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Author: Damien Lespiau <damien.lespiau@intel.com> + * Author: Jonas Ådahl <jadahl@gmail.com> + */ + +#ifndef META_SEAT_NATIVE_H +#define META_SEAT_NATIVE_H + +#include <gudev/gudev.h> +#include <libinput.h> +#include <linux/input-event-codes.h> + +#include "backends/native/meta-keymap-native.h" +#include "backends/native/meta-xkb-utils.h" +#include "clutter/clutter.h" + +typedef struct _MetaTouchState MetaTouchState; +typedef struct _MetaSeatNative MetaSeatNative; +typedef struct _MetaEventSource MetaEventSource; + +/** + * MetaPointerConstrainCallback: + * @device: the core pointer device + * @time: the event time in milliseconds + * @x: (inout): the new X coordinate + * @y: (inout): the new Y coordinate + * @user_data: user data passed to this function + * + * This callback will be called for all pointer motion events, and should + * update (@x, @y) to constrain the pointer position appropriately. + * The subsequent motion event will use the updated values as the new coordinates. + * Note that the coordinates are not clamped to the stage size, and the callback + * must make sure that this happens before it returns. + * Also note that the event will be emitted even if the pointer is constrained + * to be in the same position. + */ +typedef void (* MetaPointerConstrainCallback) (ClutterInputDevice *device, + uint32_t time, + float prev_x, + float prev_y, + float *x, + float *y, + gpointer user_data); +typedef void (* MetaRelativeMotionFilter) (ClutterInputDevice *device, + float x, + float y, + float *dx, + float *dy, + gpointer user_data); + +struct _MetaTouchState +{ + MetaSeatNative *seat; + + int device_slot; + int seat_slot; + graphene_point_t coords; +}; + +struct _MetaSeatNative +{ + ClutterSeat parent_instance; + + char *seat_id; + MetaEventSource *event_source; + struct libinput *libinput; + struct libinput_seat *libinput_seat; + + GSList *devices; + + ClutterInputDevice *core_pointer; + ClutterInputDevice *core_keyboard; + + MetaTouchState **touch_states; + int n_alloc_touch_states; + + struct xkb_state *xkb; + xkb_led_index_t caps_lock_led; + xkb_led_index_t num_lock_led; + xkb_led_index_t scroll_lock_led; + xkb_layout_index_t layout_idx; + uint32_t button_state; + int button_count[KEY_CNT]; + + ClutterStage *stage; + ClutterStageManager *stage_manager; + gulong stage_added_handler; + gulong stage_removed_handler; + + int device_id_next; + GList *free_device_ids; + + MetaPointerConstrainCallback constrain_callback; + gpointer constrain_data; + GDestroyNotify constrain_data_notify; + + MetaRelativeMotionFilter relative_motion_filter; + gpointer relative_motion_filter_user_data; + + GSList *event_filters; + + MetaKeymapNative *keymap; + + GUdevClient *udev_client; + guint tablet_mode_switch_state : 1; + guint has_touchscreen : 1; + guint has_tablet_switch : 1; + guint touch_mode : 1; + + /* keyboard repeat */ + gboolean repeat; + uint32_t repeat_delay; + uint32_t repeat_interval; + uint32_t repeat_key; + uint32_t repeat_count; + uint32_t repeat_timer; + ClutterInputDevice *repeat_device; + + float pointer_x; + float pointer_y; + + /* Emulation of discrete scroll events out of smooth ones */ + float accum_scroll_dx; + float accum_scroll_dy; + + gboolean released; +}; + +#define META_TYPE_SEAT_NATIVE meta_seat_native_get_type () +G_DECLARE_FINAL_TYPE (MetaSeatNative, meta_seat_native, + META, SEAT_NATIVE, ClutterSeat) + +static inline uint64_t +us (uint64_t us) +{ + return us; +} + +static inline uint64_t +ms2us (uint64_t ms) +{ + return us (ms * 1000); +} + +static inline uint32_t +us2ms (uint64_t us) +{ + return (uint32_t) (us / 1000); +} + +void meta_seat_native_notify_key (MetaSeatNative *seat, + ClutterInputDevice *device, + uint64_t time_us, + uint32_t key, + uint32_t state, + gboolean update_keys); + +void meta_seat_native_notify_relative_motion (MetaSeatNative *seat_evdev, + ClutterInputDevice *input_device, + uint64_t time_us, + float dx, + float dy, + float dx_unaccel, + float dy_unaccel); + +void meta_seat_native_notify_absolute_motion (MetaSeatNative *seat_evdev, + ClutterInputDevice *input_device, + uint64_t time_us, + float x, + float y, + double *axes); + +void meta_seat_native_notify_button (MetaSeatNative *seat, + ClutterInputDevice *input_device, + uint64_t time_us, + uint32_t button, + uint32_t state); + +void meta_seat_native_notify_scroll_continuous (MetaSeatNative *seat, + ClutterInputDevice *input_device, + uint64_t time_us, + double dx, + double dy, + ClutterScrollSource source, + ClutterScrollFinishFlags flags); + +void meta_seat_native_notify_discrete_scroll (MetaSeatNative *seat, + ClutterInputDevice *input_device, + uint64_t time_us, + double discrete_dx, + double discrete_dy, + ClutterScrollSource source); + +void meta_seat_native_notify_touch_event (MetaSeatNative *seat, + ClutterInputDevice *input_device, + ClutterEventType evtype, + uint64_t time_us, + int slot, + double x, + double y); + +void meta_seat_native_set_libinput_seat (MetaSeatNative *seat, + struct libinput_seat *libinput_seat); + +void meta_seat_native_sync_leds (MetaSeatNative *seat); + +ClutterInputDevice * meta_seat_native_get_device (MetaSeatNative *seat, + int id); + +MetaTouchState * meta_seat_native_acquire_touch_state (MetaSeatNative *seat, + int device_slot); + +void meta_seat_native_release_touch_state (MetaSeatNative *seat, + MetaTouchState *touch_state); + +void meta_seat_native_set_stage (MetaSeatNative *seat, + ClutterStage *stage); +ClutterStage * meta_seat_native_get_stage (MetaSeatNative *seat); + +void meta_seat_native_clear_repeat_timer (MetaSeatNative *seat); + +gint meta_seat_native_acquire_device_id (MetaSeatNative *seat); +void meta_seat_native_release_device_id (MetaSeatNative *seat, + ClutterInputDevice *device); + +void meta_seat_native_update_xkb_state (MetaSeatNative *seat); + +void meta_seat_native_constrain_pointer (MetaSeatNative *seat, + ClutterInputDevice *core_pointer, + uint64_t time_us, + float x, + float y, + float *new_x, + float *new_y); + +void meta_seat_native_filter_relative_motion (MetaSeatNative *seat, + ClutterInputDevice *device, + float x, + float y, + float *dx, + float *dy); + +void meta_seat_native_dispatch (MetaSeatNative *seat); + +/** + * MetaOpenDeviceCallback: + * @path: the device path + * @flags: flags to be passed to open + * + * This callback will be called when Clutter needs to access an input + * device. It should return an open file descriptor for the file at @path, + * or -1 if opening failed. + */ +typedef int (* MetaOpenDeviceCallback) (const char *path, + int flags, + gpointer user_data, + GError **error); +typedef void (* MetaCloseDeviceCallback) (int fd, + gpointer user_data); + +void meta_seat_native_set_device_callbacks (MetaOpenDeviceCallback open_callback, + MetaCloseDeviceCallback close_callback, + gpointer user_data); + +void meta_seat_native_release_devices (MetaSeatNative *seat); +void meta_seat_native_reclaim_devices (MetaSeatNative *seat); + +void meta_seat_native_set_pointer_constrain_callback (MetaSeatNative *seat, + MetaPointerConstrainCallback callback, + gpointer user_data, + GDestroyNotify user_data_notify); + +void meta_seat_native_set_relative_motion_filter (MetaSeatNative *seat, + MetaRelativeMotionFilter filter, + gpointer user_data); + +typedef gboolean (* MetaEvdevFilterFunc) (struct libinput_event *event, + gpointer data); + +void meta_seat_native_add_filter (MetaSeatNative *seat, + MetaEvdevFilterFunc func, + gpointer data, + GDestroyNotify destroy_notify); +void meta_seat_native_remove_filter (MetaSeatNative *seat, + MetaEvdevFilterFunc func, + gpointer data); + +struct xkb_state * meta_seat_native_get_xkb_state (MetaSeatNative *seat); + +void meta_seat_native_set_keyboard_map (MetaSeatNative *seat, + struct xkb_keymap *keymap); + +struct xkb_keymap * meta_seat_native_get_keyboard_map (MetaSeatNative *seat); + +void meta_seat_native_set_keyboard_layout_index (MetaSeatNative *seat, + xkb_layout_index_t idx); + +xkb_layout_index_t meta_seat_native_get_keyboard_layout_index (MetaSeatNative *seat); + +void meta_seat_native_set_keyboard_numlock (MetaSeatNative *seat, + gboolean numlock_state); + +void meta_seat_native_set_keyboard_repeat (MetaSeatNative *seat, + gboolean repeat, + uint32_t delay, + uint32_t interval); + +#endif /* META_SEAT_NATIVE_H */ diff --git a/src/backends/native/meta-stage-native.c b/src/backends/native/meta-stage-native.c new file mode 100644 index 000000000..9b9c45ef3 --- /dev/null +++ b/src/backends/native/meta-stage-native.c @@ -0,0 +1,230 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +#include "config.h" + +#include "backends/native/meta-stage-native.h" + +#include "backends/meta-backend-private.h" +#include "backends/native/meta-renderer-native.h" +#include "meta/meta-backend.h" +#include "meta/meta-monitor-manager.h" +#include "meta/util.h" + +static GQuark quark_view_frame_closure = 0; + +struct _MetaStageNative +{ + ClutterStageCogl parent; + + CoglClosure *frame_closure; + + int64_t presented_frame_counter_sync; + int64_t presented_frame_counter_complete; +}; + +static void +clutter_stage_window_iface_init (ClutterStageWindowInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (MetaStageNative, meta_stage_native, + CLUTTER_TYPE_STAGE_COGL, + G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_STAGE_WINDOW, + clutter_stage_window_iface_init)) + +static void +frame_cb (CoglOnscreen *onscreen, + CoglFrameEvent frame_event, + CoglFrameInfo *frame_info, + void *user_data) + +{ + MetaStageNative *stage_native = user_data; + ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_native); + int64_t global_frame_counter; + int64_t presented_frame_counter; + ClutterFrameInfo clutter_frame_info; + + global_frame_counter = cogl_frame_info_get_global_frame_counter (frame_info); + + switch (frame_event) + { + case COGL_FRAME_EVENT_SYNC: + presented_frame_counter = stage_native->presented_frame_counter_sync; + stage_native->presented_frame_counter_sync = global_frame_counter; + break; + case COGL_FRAME_EVENT_COMPLETE: + presented_frame_counter = stage_native->presented_frame_counter_complete; + stage_native->presented_frame_counter_complete = global_frame_counter; + break; + default: + g_assert_not_reached (); + } + + if (global_frame_counter <= presented_frame_counter) + return; + + clutter_frame_info = (ClutterFrameInfo) { + .frame_counter = global_frame_counter, + .refresh_rate = cogl_frame_info_get_refresh_rate (frame_info), + .presentation_time = cogl_frame_info_get_presentation_time (frame_info) + }; + + _clutter_stage_cogl_presented (stage_cogl, frame_event, &clutter_frame_info); +} + +static void +ensure_frame_callback (MetaStageNative *stage_native, + ClutterStageView *stage_view) +{ + CoglFramebuffer *framebuffer; + CoglOnscreen *onscreen; + CoglClosure *closure; + + closure = g_object_get_qdata (G_OBJECT (stage_view), + quark_view_frame_closure); + if (closure) + return; + + framebuffer = clutter_stage_view_get_onscreen (stage_view); + onscreen = COGL_ONSCREEN (framebuffer); + closure = cogl_onscreen_add_frame_callback (onscreen, + frame_cb, + stage_native, + NULL); + g_object_set_qdata (G_OBJECT (stage_view), + quark_view_frame_closure, + closure); +} + +static void +ensure_frame_callbacks (MetaStageNative *stage_native) +{ + MetaBackend *backend = meta_get_backend (); + MetaRenderer *renderer = meta_backend_get_renderer (backend); + GList *l; + + for (l = meta_renderer_get_views (renderer); l; l = l->next) + { + ClutterStageView *stage_view = l->data; + + ensure_frame_callback (stage_native, stage_view); + } +} + +void +meta_stage_native_rebuild_views (MetaStageNative *stage_native) +{ + MetaBackend *backend = meta_get_backend (); + MetaRenderer *renderer = meta_backend_get_renderer (backend); + ClutterActor *stage = meta_backend_get_stage (backend); + + meta_renderer_rebuild_views (renderer); + clutter_stage_update_resource_scales (CLUTTER_STAGE (stage)); + ensure_frame_callbacks (stage_native); +} + +static gboolean +meta_stage_native_can_clip_redraws (ClutterStageWindow *stage_window) +{ + return TRUE; +} + +static void +meta_stage_native_get_geometry (ClutterStageWindow *stage_window, + cairo_rectangle_int_t *geometry) +{ + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + + if (monitor_manager) + { + int width, height; + + meta_monitor_manager_get_screen_size (monitor_manager, &width, &height); + *geometry = (cairo_rectangle_int_t) { + .width = width, + .height = height, + }; + } + else + { + *geometry = (cairo_rectangle_int_t) { + .width = 1, + .height = 1, + }; + } +} + +static GList * +meta_stage_native_get_views (ClutterStageWindow *stage_window) +{ + MetaBackend *backend = meta_get_backend (); + MetaRenderer *renderer = meta_backend_get_renderer (backend); + + return meta_renderer_get_views (renderer); +} + +static int64_t +meta_stage_native_get_frame_counter (ClutterStageWindow *stage_window) +{ + MetaBackend *backend = meta_get_backend (); + MetaRenderer *renderer = meta_backend_get_renderer (backend); + MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer); + + return meta_renderer_native_get_frame_counter (renderer_native); +} + +static void +meta_stage_native_finish_frame (ClutterStageWindow *stage_window) +{ + MetaBackend *backend = meta_get_backend (); + MetaRenderer *renderer = meta_backend_get_renderer (backend); + + meta_renderer_native_finish_frame (META_RENDERER_NATIVE (renderer)); +} + +static void +meta_stage_native_init (MetaStageNative *stage_native) +{ + stage_native->presented_frame_counter_sync = -1; + stage_native->presented_frame_counter_complete = -1; +} + +static void +meta_stage_native_class_init (MetaStageNativeClass *klass) +{ + quark_view_frame_closure = + g_quark_from_static_string ("-meta-native-stage-view-frame-closure"); +} + +static void +clutter_stage_window_iface_init (ClutterStageWindowInterface *iface) +{ + iface->can_clip_redraws = meta_stage_native_can_clip_redraws; + iface->get_geometry = meta_stage_native_get_geometry; + iface->get_views = meta_stage_native_get_views; + iface->get_frame_counter = meta_stage_native_get_frame_counter; + iface->finish_frame = meta_stage_native_finish_frame; +} diff --git a/src/backends/native/meta-stage-native.h b/src/backends/native/meta-stage-native.h new file mode 100644 index 000000000..f33743f3e --- /dev/null +++ b/src/backends/native/meta-stage-native.h @@ -0,0 +1,36 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +#ifndef META_STAGE_NATIVE_H +#define META_STAGE_NATIVE_H + +#include "clutter/clutter-mutter.h" + +#define META_TYPE_STAGE_NATIVE (meta_stage_native_get_type ()) +G_DECLARE_FINAL_TYPE (MetaStageNative, meta_stage_native, + META, STAGE_NATIVE, ClutterStageCogl) + +void meta_stage_native_rebuild_views (MetaStageNative *stage_native); + +#endif /* META_STAGE_NATIVE_H */ diff --git a/src/backends/native/meta-udev.c b/src/backends/native/meta-udev.c new file mode 100644 index 000000000..2f19c8c9c --- /dev/null +++ b/src/backends/native/meta-udev.c @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2018 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#include "config.h" + +#include "backends/native/meta-udev.h" + +#include "backends/native/meta-backend-native.h" +#include "backends/native/meta-launcher.h" + +#define DRM_CARD_UDEV_DEVICE_TYPE "drm_minor" + +enum +{ + HOTPLUG, + DEVICE_ADDED, + DEVICE_REMOVED, + + N_SIGNALS +}; + +static guint signals[N_SIGNALS]; + +struct _MetaUdev +{ + GObject parent; + + MetaBackendNative *backend_native; + + GUdevClient *gudev_client; + + gulong uevent_handler_id; +}; + +G_DEFINE_TYPE (MetaUdev, meta_udev, G_TYPE_OBJECT) + +gboolean +meta_is_udev_device_platform_device (GUdevDevice *device) +{ + g_autoptr (GUdevDevice) platform_device = NULL; + + platform_device = g_udev_device_get_parent_with_subsystem (device, + "platform", + NULL); + return !!platform_device; +} + +gboolean +meta_is_udev_device_boot_vga (GUdevDevice *device) +{ + g_autoptr (GUdevDevice) pci_device = NULL; + + pci_device = g_udev_device_get_parent_with_subsystem (device, "pci", NULL); + if (!pci_device) + return FALSE; + + return g_udev_device_get_sysfs_attr_as_int (pci_device, "boot_vga") == 1; +} + +gboolean +meta_udev_is_drm_device (MetaUdev *udev, + GUdevDevice *device) +{ + MetaLauncher *launcher = + meta_backend_native_get_launcher (udev->backend_native); + const char *seat_id; + const char *device_type; + const char *device_seat; + + /* Filter out devices that are not character device, like card0-VGA-1. */ + if (g_udev_device_get_device_type (device) != G_UDEV_DEVICE_TYPE_CHAR) + return FALSE; + + device_type = g_udev_device_get_property (device, "DEVTYPE"); + if (g_strcmp0 (device_type, DRM_CARD_UDEV_DEVICE_TYPE) != 0) + return FALSE; + + device_seat = g_udev_device_get_property (device, "ID_SEAT"); + if (!device_seat) + { + /* When ID_SEAT is not set, it means seat0. */ + device_seat = "seat0"; + } + + /* Skip devices that do not belong to our seat. */ + seat_id = meta_launcher_get_seat_id (launcher); + if (g_strcmp0 (seat_id, device_seat)) + return FALSE; + + return TRUE; +} + +GList * +meta_udev_list_drm_devices (MetaUdev *udev, + GError **error) +{ + g_autoptr (GUdevEnumerator) enumerator = NULL; + GList *devices; + GList *l; + + enumerator = g_udev_enumerator_new (udev->gudev_client); + + g_udev_enumerator_add_match_name (enumerator, "card*"); + g_udev_enumerator_add_match_tag (enumerator, "seat"); + + /* + * We need to explicitly match the subsystem for now. + * https://bugzilla.gnome.org/show_bug.cgi?id=773224 + */ + g_udev_enumerator_add_match_subsystem (enumerator, "drm"); + + devices = g_udev_enumerator_execute (enumerator); + if (!devices) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, + "No drm devices found"); + return FALSE; + } + + for (l = devices; l;) + { + GUdevDevice *device = l->data; + GList *l_next = l->next; + + if (!meta_udev_is_drm_device (udev, device)) + { + g_object_unref (device); + devices = g_list_delete_link (devices, l); + } + + l = l_next; + } + + return devices; +} + +static void +on_uevent (GUdevClient *client, + const char *action, + GUdevDevice *device, + gpointer user_data) +{ + MetaUdev *udev = META_UDEV (user_data); + + if (!g_udev_device_get_device_file (device)) + return; + + if (g_str_equal (action, "add")) + g_signal_emit (udev, signals[DEVICE_ADDED], 0, device); + else if (g_str_equal (action, "remove")) + g_signal_emit (udev, signals[DEVICE_REMOVED], 0, device); + + if (g_udev_device_get_property_as_boolean (device, "HOTPLUG")) + g_signal_emit (udev, signals[HOTPLUG], 0); +} + +MetaUdev * +meta_udev_new (MetaBackendNative *backend_native) +{ + MetaUdev *udev; + + udev = g_object_new (META_TYPE_UDEV, NULL); + udev->backend_native = backend_native; + + return udev; +} + +static void +meta_udev_finalize (GObject *object) +{ + MetaUdev *udev = META_UDEV (object); + + g_clear_signal_handler (&udev->uevent_handler_id, udev->gudev_client); + g_clear_object (&udev->gudev_client); + + G_OBJECT_CLASS (meta_udev_parent_class)->finalize (object); +} + +static void +meta_udev_init (MetaUdev *udev) +{ + const char *subsystems[] = { "drm", NULL }; + + udev->gudev_client = g_udev_client_new (subsystems); + udev->uevent_handler_id = g_signal_connect (udev->gudev_client, + "uevent", + G_CALLBACK (on_uevent), udev); +} + +static void +meta_udev_class_init (MetaUdevClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_udev_finalize; + + signals[HOTPLUG] = + g_signal_new ("hotplug", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 0); + signals[DEVICE_ADDED] = + g_signal_new ("device-added", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 1, + G_UDEV_TYPE_DEVICE); + signals[DEVICE_REMOVED] = + g_signal_new ("device-removed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 1, + G_UDEV_TYPE_DEVICE); +} diff --git a/src/backends/native/meta-udev.h b/src/backends/native/meta-udev.h new file mode 100644 index 000000000..cf72acd1b --- /dev/null +++ b/src/backends/native/meta-udev.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2018 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#ifndef META_UDEV_H +#define META_UDEV_H + +#include <gudev/gudev.h> + +#include "backends/native/meta-backend-native-types.h" + +#define META_TYPE_UDEV (meta_udev_get_type ()) +G_DECLARE_FINAL_TYPE (MetaUdev, meta_udev, META, UDEV, GObject) + +gboolean meta_is_udev_device_platform_device (GUdevDevice *device); + +gboolean meta_is_udev_device_boot_vga (GUdevDevice *device); + +gboolean meta_udev_is_drm_device (MetaUdev *udev, + GUdevDevice *device); + +GList * meta_udev_list_drm_devices (MetaUdev *udev, + GError **error); + +MetaUdev * meta_udev_new (MetaBackendNative *backend_native); + +#endif /* META_UDEV_H */ diff --git a/src/backends/native/meta-virtual-input-device-native.c b/src/backends/native/meta-virtual-input-device-native.c new file mode 100644 index 000000000..9e99c3a5f --- /dev/null +++ b/src/backends/native/meta-virtual-input-device-native.c @@ -0,0 +1,761 @@ +/* + * Copyright (C) 2016 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Author: Jonas Ådahl <jadahl@gmail.com> + */ + +#include "config.h" + +#include <glib-object.h> +#include <linux/input.h> + +#include "backends/native/meta-input-device-native.h" +#include "backends/native/meta-keymap-native.h" +#include "backends/native/meta-seat-native.h" +#include "backends/native/meta-virtual-input-device-native.h" +#include "clutter/clutter-mutter.h" +#include "meta/util.h" + +enum +{ + PROP_0, + + PROP_SEAT, + + PROP_LAST +}; + +static GParamSpec *obj_props[PROP_LAST]; + +struct _MetaVirtualInputDeviceNative +{ + ClutterVirtualInputDevice parent; + + ClutterInputDevice *device; + MetaSeatNative *seat; + int button_count[KEY_CNT]; +}; + +G_DEFINE_TYPE (MetaVirtualInputDeviceNative, + meta_virtual_input_device_native, + CLUTTER_TYPE_VIRTUAL_INPUT_DEVICE) + +typedef enum _EvdevButtonType +{ + EVDEV_BUTTON_TYPE_NONE, + EVDEV_BUTTON_TYPE_KEY, + EVDEV_BUTTON_TYPE_BUTTON, +} EvdevButtonType; + +static int +update_button_count (MetaVirtualInputDeviceNative *virtual_evdev, + uint32_t button, + uint32_t state) +{ + if (state) + return ++virtual_evdev->button_count[button]; + else + return --virtual_evdev->button_count[button]; +} + +static EvdevButtonType +get_button_type (uint16_t code) +{ + switch (code) + { + case BTN_TOOL_PEN: + case BTN_TOOL_RUBBER: + case BTN_TOOL_BRUSH: + case BTN_TOOL_PENCIL: + case BTN_TOOL_AIRBRUSH: + case BTN_TOOL_MOUSE: + case BTN_TOOL_LENS: + case BTN_TOOL_QUINTTAP: + case BTN_TOOL_DOUBLETAP: + case BTN_TOOL_TRIPLETAP: + case BTN_TOOL_QUADTAP: + case BTN_TOOL_FINGER: + case BTN_TOUCH: + return EVDEV_BUTTON_TYPE_NONE; + } + + if (code >= KEY_ESC && code <= KEY_MICMUTE) + return EVDEV_BUTTON_TYPE_KEY; + if (code >= BTN_MISC && code <= BTN_GEAR_UP) + return EVDEV_BUTTON_TYPE_BUTTON; + if (code >= KEY_OK && code <= KEY_LIGHTS_TOGGLE) + return EVDEV_BUTTON_TYPE_KEY; + if (code >= BTN_DPAD_UP && code <= BTN_DPAD_RIGHT) + return EVDEV_BUTTON_TYPE_BUTTON; + if (code >= KEY_ALS_TOGGLE && code <= KEY_KBDINPUTASSIST_CANCEL) + return EVDEV_BUTTON_TYPE_KEY; + if (code >= BTN_TRIGGER_HAPPY && code <= BTN_TRIGGER_HAPPY40) + return EVDEV_BUTTON_TYPE_BUTTON; + return EVDEV_BUTTON_TYPE_NONE; +} + +static void +release_pressed_buttons (ClutterVirtualInputDevice *virtual_device) +{ + MetaVirtualInputDeviceNative *virtual_evdev = + META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device); + int code; + uint64_t time_us; + + time_us = g_get_monotonic_time (); + + meta_topic (META_DEBUG_INPUT, + "Releasing pressed buttons while destroying virtual input device " + "(device %p)\n", virtual_device); + + for (code = 0; code < G_N_ELEMENTS (virtual_evdev->button_count); code++) + { + if (virtual_evdev->button_count[code] == 0) + continue; + + switch (get_button_type (code)) + { + case EVDEV_BUTTON_TYPE_KEY: + clutter_virtual_input_device_notify_key (virtual_device, + time_us, + code, + CLUTTER_KEY_STATE_RELEASED); + break; + case EVDEV_BUTTON_TYPE_BUTTON: + clutter_virtual_input_device_notify_button (virtual_device, + time_us, + code, + CLUTTER_BUTTON_STATE_RELEASED); + break; + case EVDEV_BUTTON_TYPE_NONE: + g_assert_not_reached (); + } + } +} + +static void +meta_virtual_input_device_native_notify_relative_motion (ClutterVirtualInputDevice *virtual_device, + uint64_t time_us, + double dx, + double dy) +{ + MetaVirtualInputDeviceNative *virtual_evdev = + META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device); + + g_return_if_fail (virtual_evdev->device != NULL); + + if (time_us == CLUTTER_CURRENT_TIME) + time_us = g_get_monotonic_time (); + + meta_seat_native_notify_relative_motion (virtual_evdev->seat, + virtual_evdev->device, + time_us, + dx, dy, + dx, dy); +} + +static void +meta_virtual_input_device_native_notify_absolute_motion (ClutterVirtualInputDevice *virtual_device, + uint64_t time_us, + double x, + double y) +{ + MetaVirtualInputDeviceNative *virtual_evdev = + META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device); + + g_return_if_fail (virtual_evdev->device != NULL); + + if (time_us == CLUTTER_CURRENT_TIME) + time_us = g_get_monotonic_time (); + + meta_seat_native_notify_absolute_motion (virtual_evdev->seat, + virtual_evdev->device, + time_us, + x, y, + NULL); +} + +static int +translate_to_evdev_button (int clutter_button) +{ + switch (clutter_button) + { + case CLUTTER_BUTTON_PRIMARY: + return BTN_LEFT; + case CLUTTER_BUTTON_SECONDARY: + return BTN_RIGHT; + case CLUTTER_BUTTON_MIDDLE: + return BTN_MIDDLE; + default: + /* + * For compatibility reasons, all additional buttons go after the old + * 4-7 scroll ones. + */ + return clutter_button + (BTN_LEFT - 1) - 4; + } +} + +static void +meta_virtual_input_device_native_notify_button (ClutterVirtualInputDevice *virtual_device, + uint64_t time_us, + uint32_t button, + ClutterButtonState button_state) +{ + MetaVirtualInputDeviceNative *virtual_evdev = + META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device); + int button_count; + int evdev_button; + + g_return_if_fail (virtual_evdev->device != NULL); + + if (time_us == CLUTTER_CURRENT_TIME) + time_us = g_get_monotonic_time (); + + evdev_button = translate_to_evdev_button (button); + + if (get_button_type (evdev_button) != EVDEV_BUTTON_TYPE_BUTTON) + { + g_warning ("Unknown/invalid virtual device button 0x%x pressed", + evdev_button); + return; + } + + button_count = update_button_count (virtual_evdev, evdev_button, button_state); + if (button_count < 0 || button_count > 1) + { + g_warning ("Received multiple virtual 0x%x button %s (ignoring)", evdev_button, + button_state == CLUTTER_BUTTON_STATE_PRESSED ? "presses" : "releases"); + update_button_count (virtual_evdev, evdev_button, 1 - button_state); + return; + } + + meta_topic (META_DEBUG_INPUT, + "Emitting virtual button-%s of button 0x%x (device %p)\n", + button_state == CLUTTER_BUTTON_STATE_PRESSED ? "press" : "release", + evdev_button, virtual_device); + + meta_seat_native_notify_button (virtual_evdev->seat, + virtual_evdev->device, + time_us, + evdev_button, + button_state); +} + +static void +meta_virtual_input_device_native_notify_key (ClutterVirtualInputDevice *virtual_device, + uint64_t time_us, + uint32_t key, + ClutterKeyState key_state) +{ + MetaVirtualInputDeviceNative *virtual_evdev = + META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device); + int key_count; + + g_return_if_fail (virtual_evdev->device != NULL); + + if (time_us == CLUTTER_CURRENT_TIME) + time_us = g_get_monotonic_time (); + + if (get_button_type (key) != EVDEV_BUTTON_TYPE_KEY) + { + g_warning ("Unknown/invalid virtual device key 0x%x pressed\n", key); + return; + } + + key_count = update_button_count (virtual_evdev, key, key_state); + if (key_count < 0 || key_count > 1) + { + g_warning ("Received multiple virtual 0x%x key %s (ignoring)", key, + key_state == CLUTTER_KEY_STATE_PRESSED ? "presses" : "releases"); + update_button_count (virtual_evdev, key, 1 - key_state); + return; + } + + meta_topic (META_DEBUG_INPUT, + "Emitting virtual key-%s of key 0x%x (device %p)\n", + key_state == CLUTTER_KEY_STATE_PRESSED ? "press" : "release", + key, virtual_device); + + meta_seat_native_notify_key (virtual_evdev->seat, + virtual_evdev->device, + time_us, + key, + key_state, + TRUE); +} + +static gboolean +pick_keycode_for_keyval_in_current_group (ClutterVirtualInputDevice *virtual_device, + guint keyval, + guint *keycode_out, + guint *level_out) +{ + MetaVirtualInputDeviceNative *virtual_evdev = + META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device); + ClutterBackend *backend; + ClutterKeymap *keymap; + struct xkb_keymap *xkb_keymap; + struct xkb_state *state; + guint keycode, layout; + xkb_keycode_t min_keycode, max_keycode; + + backend = clutter_get_default_backend (); + keymap = clutter_seat_get_keymap (clutter_backend_get_default_seat (backend)); + xkb_keymap = meta_keymap_native_get_keyboard_map (META_KEYMAP_NATIVE (keymap)); + state = virtual_evdev->seat->xkb; + + layout = xkb_state_serialize_layout (state, XKB_STATE_LAYOUT_EFFECTIVE); + min_keycode = xkb_keymap_min_keycode (xkb_keymap); + max_keycode = xkb_keymap_max_keycode (xkb_keymap); + for (keycode = min_keycode; keycode < max_keycode; keycode++) + { + gint num_levels, level; + num_levels = xkb_keymap_num_levels_for_key (xkb_keymap, keycode, layout); + for (level = 0; level < num_levels; level++) + { + const xkb_keysym_t *syms; + gint num_syms, sym; + num_syms = xkb_keymap_key_get_syms_by_level (xkb_keymap, keycode, layout, level, &syms); + for (sym = 0; sym < num_syms; sym++) + { + if (syms[sym] == keyval) + { + *keycode_out = keycode; + if (level_out) + *level_out = level; + return TRUE; + } + } + } + } + + return FALSE; +} + +static void +apply_level_modifiers (ClutterVirtualInputDevice *virtual_device, + uint64_t time_us, + uint32_t level, + uint32_t key_state) +{ + MetaVirtualInputDeviceNative *virtual_evdev = + META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device); + guint keysym, keycode, evcode; + + if (level == 0) + return; + + if (level == 1) + { + keysym = XKB_KEY_Shift_L; + } + else if (level == 2) + { + keysym = XKB_KEY_ISO_Level3_Shift; + } + else + { + g_warning ("Unhandled level: %d\n", level); + return; + } + + if (!pick_keycode_for_keyval_in_current_group (virtual_device, keysym, + &keycode, NULL)) + return; + + clutter_input_device_keycode_to_evdev (virtual_evdev->device, + keycode, &evcode); + + meta_topic (META_DEBUG_INPUT, + "Emitting virtual key-%s of modifier key 0x%x (device %p)\n", + key_state == CLUTTER_KEY_STATE_PRESSED ? "press" : "release", + evcode, virtual_device); + + meta_seat_native_notify_key (virtual_evdev->seat, + virtual_evdev->device, + time_us, + evcode, + key_state, + TRUE); +} + +static void +meta_virtual_input_device_native_notify_keyval (ClutterVirtualInputDevice *virtual_device, + uint64_t time_us, + uint32_t keyval, + ClutterKeyState key_state) +{ + MetaVirtualInputDeviceNative *virtual_evdev = + META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device); + int key_count; + guint keycode = 0, level = 0, evcode = 0; + + g_return_if_fail (virtual_evdev->device != NULL); + + if (time_us == CLUTTER_CURRENT_TIME) + time_us = g_get_monotonic_time (); + + if (!pick_keycode_for_keyval_in_current_group (virtual_device, + keyval, &keycode, &level)) + { + g_warning ("No keycode found for keyval %x in current group", keyval); + return; + } + + clutter_input_device_keycode_to_evdev (virtual_evdev->device, + keycode, &evcode); + + if (get_button_type (evcode) != EVDEV_BUTTON_TYPE_KEY) + { + g_warning ("Unknown/invalid virtual device key 0x%x pressed\n", evcode); + return; + } + + key_count = update_button_count (virtual_evdev, evcode, key_state); + if (key_count < 0 || key_count > 1) + { + g_warning ("Received multiple virtual 0x%x key %s (ignoring)", evcode, + key_state == CLUTTER_KEY_STATE_PRESSED ? "presses" : "releases"); + update_button_count (virtual_evdev, evcode, 1 - key_state); + return; + } + + meta_topic (META_DEBUG_INPUT, + "Emitting virtual key-%s of key 0x%x with modifier level %d, " + "press count %d (device %p)\n", + key_state == CLUTTER_KEY_STATE_PRESSED ? "press" : "release", + evcode, level, key_count, virtual_device); + + if (key_state) + apply_level_modifiers (virtual_device, time_us, level, key_state); + + meta_seat_native_notify_key (virtual_evdev->seat, + virtual_evdev->device, + time_us, + evcode, + key_state, + TRUE); + + if (!key_state) + apply_level_modifiers (virtual_device, time_us, level, key_state); +} + +static void +direction_to_discrete (ClutterScrollDirection direction, + double *discrete_dx, + double *discrete_dy) +{ + switch (direction) + { + case CLUTTER_SCROLL_UP: + *discrete_dx = 0.0; + *discrete_dy = -1.0; + break; + case CLUTTER_SCROLL_DOWN: + *discrete_dx = 0.0; + *discrete_dy = 1.0; + break; + case CLUTTER_SCROLL_LEFT: + *discrete_dx = -1.0; + *discrete_dy = 0.0; + break; + case CLUTTER_SCROLL_RIGHT: + *discrete_dx = 1.0; + *discrete_dy = 0.0; + break; + case CLUTTER_SCROLL_SMOOTH: + g_assert_not_reached (); + break; + } +} + +static void +meta_virtual_input_device_native_notify_discrete_scroll (ClutterVirtualInputDevice *virtual_device, + uint64_t time_us, + ClutterScrollDirection direction, + ClutterScrollSource scroll_source) +{ + MetaVirtualInputDeviceNative *virtual_evdev = + META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device); + double discrete_dx = 0.0, discrete_dy = 0.0; + + g_return_if_fail (virtual_evdev->device != NULL); + + if (time_us == CLUTTER_CURRENT_TIME) + time_us = g_get_monotonic_time (); + + direction_to_discrete (direction, &discrete_dx, &discrete_dy); + + meta_seat_native_notify_discrete_scroll (virtual_evdev->seat, + virtual_evdev->device, + time_us, + discrete_dx, discrete_dy, + scroll_source); +} + +static void +meta_virtual_input_device_native_notify_scroll_continuous (ClutterVirtualInputDevice *virtual_device, + uint64_t time_us, + double dx, + double dy, + ClutterScrollSource scroll_source, + ClutterScrollFinishFlags finish_flags) +{ + MetaVirtualInputDeviceNative *virtual_evdev = + META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device); + + g_return_if_fail (virtual_evdev->device != NULL); + + if (time_us == CLUTTER_CURRENT_TIME) + time_us = g_get_monotonic_time (); + + meta_seat_native_notify_scroll_continuous (virtual_evdev->seat, + virtual_evdev->device, + time_us, + dx, dy, + scroll_source, + CLUTTER_SCROLL_FINISHED_NONE); +} + +static void +meta_virtual_input_device_native_notify_touch_down (ClutterVirtualInputDevice *virtual_device, + uint64_t time_us, + int device_slot, + double x, + double y) +{ + MetaVirtualInputDeviceNative *virtual_evdev = + META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device); + MetaInputDeviceNative *device_evdev = + META_INPUT_DEVICE_NATIVE (virtual_evdev->device); + MetaTouchState *touch_state; + + g_return_if_fail (virtual_evdev->device != NULL); + + if (time_us == CLUTTER_CURRENT_TIME) + time_us = g_get_monotonic_time (); + + touch_state = meta_input_device_native_acquire_touch_state (device_evdev, + device_slot); + if (!touch_state) + return; + + touch_state->coords.x = x; + touch_state->coords.y = y; + + meta_seat_native_notify_touch_event (virtual_evdev->seat, + virtual_evdev->device, + CLUTTER_TOUCH_BEGIN, + time_us, + touch_state->seat_slot, + touch_state->coords.x, + touch_state->coords.y); +} + +static void +meta_virtual_input_device_native_notify_touch_motion (ClutterVirtualInputDevice *virtual_device, + uint64_t time_us, + int device_slot, + double x, + double y) +{ + MetaVirtualInputDeviceNative *virtual_evdev = + META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device); + MetaInputDeviceNative *device_evdev = + META_INPUT_DEVICE_NATIVE (virtual_evdev->device); + MetaTouchState *touch_state; + + g_return_if_fail (virtual_evdev->device != NULL); + + if (time_us == CLUTTER_CURRENT_TIME) + time_us = g_get_monotonic_time (); + + touch_state = meta_input_device_native_lookup_touch_state (device_evdev, + device_slot); + if (!touch_state) + return; + + touch_state->coords.x = x; + touch_state->coords.y = y; + + meta_seat_native_notify_touch_event (virtual_evdev->seat, + virtual_evdev->device, + CLUTTER_TOUCH_BEGIN, + time_us, + touch_state->seat_slot, + touch_state->coords.x, + touch_state->coords.y); +} + +static void +meta_virtual_input_device_native_notify_touch_up (ClutterVirtualInputDevice *virtual_device, + uint64_t time_us, + int device_slot) +{ + MetaVirtualInputDeviceNative *virtual_evdev = + META_VIRTUAL_INPUT_DEVICE_NATIVE (virtual_device); + MetaInputDeviceNative *device_evdev = + META_INPUT_DEVICE_NATIVE (virtual_evdev->device); + MetaTouchState *touch_state; + + g_return_if_fail (virtual_evdev->device != NULL); + + if (time_us == CLUTTER_CURRENT_TIME) + time_us = g_get_monotonic_time (); + + touch_state = meta_input_device_native_lookup_touch_state (device_evdev, + device_slot); + if (!touch_state) + return; + + meta_seat_native_notify_touch_event (virtual_evdev->seat, + virtual_evdev->device, + CLUTTER_TOUCH_BEGIN, + time_us, + touch_state->seat_slot, + touch_state->coords.x, + touch_state->coords.y); + + meta_input_device_native_release_touch_state (device_evdev, touch_state); +} + +static void +meta_virtual_input_device_native_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaVirtualInputDeviceNative *virtual_evdev = + META_VIRTUAL_INPUT_DEVICE_NATIVE (object); + + switch (prop_id) + { + case PROP_SEAT: + g_value_set_pointer (value, virtual_evdev->seat); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_virtual_input_device_native_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaVirtualInputDeviceNative *virtual_evdev = + META_VIRTUAL_INPUT_DEVICE_NATIVE (object); + + switch (prop_id) + { + case PROP_SEAT: + virtual_evdev->seat = g_value_get_pointer (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_virtual_input_device_native_constructed (GObject *object) +{ + ClutterVirtualInputDevice *virtual_device = + CLUTTER_VIRTUAL_INPUT_DEVICE (object); + MetaVirtualInputDeviceNative *virtual_evdev = + META_VIRTUAL_INPUT_DEVICE_NATIVE (object); + ClutterInputDeviceType device_type; + ClutterStage *stage; + + device_type = clutter_virtual_input_device_get_device_type (virtual_device); + + meta_topic (META_DEBUG_INPUT, + "Creating new virtual input device of type %d (%p)\n", + device_type, virtual_device); + + virtual_evdev->device = + meta_input_device_native_new_virtual (virtual_evdev->seat, + device_type, + CLUTTER_INPUT_MODE_SLAVE); + + stage = meta_seat_native_get_stage (virtual_evdev->seat); + _clutter_input_device_set_stage (virtual_evdev->device, stage); + + g_signal_emit_by_name (virtual_evdev->seat, + "device-added", + virtual_evdev->device); +} + +static void +meta_virtual_input_device_native_dispose (GObject *object) +{ + ClutterVirtualInputDevice *virtual_device = + CLUTTER_VIRTUAL_INPUT_DEVICE (object); + MetaVirtualInputDeviceNative *virtual_evdev = + META_VIRTUAL_INPUT_DEVICE_NATIVE (object); + GObjectClass *object_class = + G_OBJECT_CLASS (meta_virtual_input_device_native_parent_class); + + if (virtual_evdev->device) + { + release_pressed_buttons (virtual_device); + g_signal_emit_by_name (virtual_evdev->seat, + "device-removed", + virtual_evdev->device); + + g_clear_object (&virtual_evdev->device); + } + + object_class->dispose (object); +} + +static void +meta_virtual_input_device_native_init (MetaVirtualInputDeviceNative *virtual_device_evdev) +{ +} + +static void +meta_virtual_input_device_native_class_init (MetaVirtualInputDeviceNativeClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + ClutterVirtualInputDeviceClass *virtual_input_device_class = + CLUTTER_VIRTUAL_INPUT_DEVICE_CLASS (klass); + + object_class->get_property = meta_virtual_input_device_native_get_property; + object_class->set_property = meta_virtual_input_device_native_set_property; + object_class->constructed = meta_virtual_input_device_native_constructed; + object_class->dispose = meta_virtual_input_device_native_dispose; + + virtual_input_device_class->notify_relative_motion = meta_virtual_input_device_native_notify_relative_motion; + virtual_input_device_class->notify_absolute_motion = meta_virtual_input_device_native_notify_absolute_motion; + virtual_input_device_class->notify_button = meta_virtual_input_device_native_notify_button; + virtual_input_device_class->notify_key = meta_virtual_input_device_native_notify_key; + virtual_input_device_class->notify_keyval = meta_virtual_input_device_native_notify_keyval; + virtual_input_device_class->notify_discrete_scroll = meta_virtual_input_device_native_notify_discrete_scroll; + virtual_input_device_class->notify_scroll_continuous = meta_virtual_input_device_native_notify_scroll_continuous; + virtual_input_device_class->notify_touch_down = meta_virtual_input_device_native_notify_touch_down; + virtual_input_device_class->notify_touch_motion = meta_virtual_input_device_native_notify_touch_motion; + virtual_input_device_class->notify_touch_up = meta_virtual_input_device_native_notify_touch_up; + + obj_props[PROP_SEAT] = g_param_spec_pointer ("seat", + "Seat", + "Seat", + CLUTTER_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_properties (object_class, PROP_LAST, obj_props); +} diff --git a/clutter/clutter/x11/clutter-virtual-input-device-x11.h b/src/backends/native/meta-virtual-input-device-native.h similarity index 61% rename from clutter/clutter/x11/clutter-virtual-input-device-x11.h rename to src/backends/native/meta-virtual-input-device-native.h index b1bb101bf..28d218abb 100644 --- a/clutter/clutter/x11/clutter-virtual-input-device-x11.h +++ b/src/backends/native/meta-virtual-input-device-native.h @@ -1,8 +1,4 @@ /* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * * Copyright (C) 2016 Red Hat Inc. * * This library is free software; you can redistribute it and/or @@ -21,15 +17,15 @@ * Author: Jonas Ådahl <jadahl@gmail.com> */ -#ifndef __CLUTTER_VIRTUAL_INPUT_DEVICE_X11_H__ -#define __CLUTTER_VIRTUAL_INPUT_DEVICE_X11_H__ +#ifndef META_VIRTUAL_INPUT_DEVICE_NATIVE_H +#define META_VIRTUAL_INPUT_DEVICE_NATIVE_H -#include "clutter-virtual-input-device.h" +#include "clutter/clutter-virtual-input-device.h" -#define CLUTTER_TYPE_VIRTUAL_INPUT_DEVICE_X11 (clutter_virtual_input_device_x11_get_type ()) -G_DECLARE_FINAL_TYPE (ClutterVirtualInputDeviceX11, - clutter_virtual_input_device_x11, - CLUTTER, VIRTUAL_INPUT_DEVICE_X11, +#define META_TYPE_VIRTUAL_INPUT_DEVICE_NATIVE (meta_virtual_input_device_native_get_type ()) +G_DECLARE_FINAL_TYPE (MetaVirtualInputDeviceNative, + meta_virtual_input_device_native, + META, VIRTUAL_INPUT_DEVICE_NATIVE, ClutterVirtualInputDevice) -#endif /* __CLUTTER_VIRTUAL_INPUT_DEVICE_X11_H__ */ +#endif /* META_VIRTUAL_INPUT_DEVICE_NATIVE_H */ diff --git a/clutter/clutter/evdev/clutter-xkb-utils.c b/src/backends/native/meta-xkb-utils.c similarity index 67% rename from clutter/clutter/evdev/clutter-xkb-utils.c rename to src/backends/native/meta-xkb-utils.c index 7f47682d1..2fcdcf37f 100644 --- a/clutter/clutter/evdev/clutter-xkb-utils.c +++ b/src/backends/native/meta-xkb-utils.c @@ -1,8 +1,4 @@ /* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * * Copyright (C) 2010 Intel Corporation. * * This library is free software; you can redistribute it and/or @@ -23,11 +19,11 @@ * Damien Lespiau <damien.lespiau@intel.com> */ -#include "clutter-build-config.h" +#include "config.h" -#include "clutter-keysyms.h" -#include "clutter-event-private.h" -#include "clutter-xkb-utils.h" +#include "backends/native/meta-xkb-utils.h" +#include "clutter/clutter-keysyms.h" +#include "clutter/clutter-mutter.h" /* * _clutter_event_new_from_evdev: Create a new Clutter ClutterKeyEvent @@ -44,14 +40,14 @@ * Return value: the new #ClutterEvent */ ClutterEvent * -_clutter_key_event_new_from_evdev (ClutterInputDevice *device, - ClutterInputDevice *core_device, - ClutterStage *stage, - struct xkb_state *xkb_state, - uint32_t button_state, - uint32_t _time, - xkb_keycode_t key, - uint32_t state) +meta_key_event_new_from_evdev (ClutterInputDevice *device, + ClutterInputDevice *core_device, + ClutterStage *stage, + struct xkb_state *xkb_state, + uint32_t button_state, + uint32_t _time, + xkb_keycode_t key, + uint32_t state) { ClutterEvent *event; xkb_keysym_t sym; @@ -76,12 +72,12 @@ _clutter_key_event_new_from_evdev (ClutterInputDevice *device, else sym = XKB_KEY_NoSymbol; - event->key.device = core_device; event->key.stage = stage; event->key.time = _time; - _clutter_xkb_translate_state (event, xkb_state, button_state); + meta_xkb_translate_state (event, xkb_state, button_state); event->key.hardware_keycode = key; event->key.keyval = sym; + clutter_event_set_device (event, core_device); clutter_event_set_source_device (event, device); n = xkb_keysym_to_utf8 (sym, buffer, sizeof (buffer)); @@ -102,14 +98,14 @@ _clutter_key_event_new_from_evdev (ClutterInputDevice *device, } void -_clutter_xkb_translate_state (ClutterEvent *event, - struct xkb_state *state, - uint32_t button_state) +meta_xkb_translate_state (ClutterEvent *event, + struct xkb_state *state, + uint32_t button_state) { _clutter_event_set_state_full (event, - button_state, - xkb_state_serialize_mods (state, XKB_STATE_MODS_DEPRESSED), - xkb_state_serialize_mods (state, XKB_STATE_MODS_LATCHED), - xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED), - xkb_state_serialize_mods (state, XKB_STATE_MODS_EFFECTIVE) | button_state); + button_state, + xkb_state_serialize_mods (state, XKB_STATE_MODS_DEPRESSED), + xkb_state_serialize_mods (state, XKB_STATE_MODS_LATCHED), + xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED), + xkb_state_serialize_mods (state, XKB_STATE_MODS_EFFECTIVE) | button_state); } diff --git a/src/backends/native/meta-xkb-utils.h b/src/backends/native/meta-xkb-utils.h new file mode 100644 index 000000000..a4c2de7dc --- /dev/null +++ b/src/backends/native/meta-xkb-utils.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2010 Intel Corporation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + + * Authors: + * Damien Lespiau <damien.lespiau@intel.com> + */ + +#ifndef META_XKB_UTILS_H +#define META_XKB_UTILS_H + +#include <xkbcommon/xkbcommon.h> + +#include "clutter/clutter.h" + +ClutterEvent * meta_key_event_new_from_evdev (ClutterInputDevice *device, + ClutterInputDevice *core_keyboard, + ClutterStage *stage, + struct xkb_state *xkb_state, + uint32_t button_state, + uint32_t _time, + uint32_t key, + uint32_t state); +void meta_xkb_translate_state (ClutterEvent *event, + struct xkb_state *xkb_state, + uint32_t button_state); + +#endif /* META_XKB_UTILS_H */ diff --git a/src/backends/x11/cm/meta-backend-x11-cm.c b/src/backends/x11/cm/meta-backend-x11-cm.c new file mode 100644 index 000000000..e5ebd68f2 --- /dev/null +++ b/src/backends/x11/cm/meta-backend-x11-cm.c @@ -0,0 +1,447 @@ +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "backends/x11/cm/meta-backend-x11-cm.h" + +#include <stdlib.h> +#include <X11/XKBlib.h> +#include <X11/extensions/XKBrules.h> +#include <xkbcommon/xkbcommon-x11.h> + +#include "backends/meta-backend-private.h" +#include "backends/meta-dnd-private.h" +#include "backends/x11/meta-cursor-renderer-x11.h" +#include "backends/x11/meta-gpu-xrandr.h" +#include "backends/x11/meta-input-settings-x11.h" +#include "backends/x11/meta-monitor-manager-xrandr.h" +#include "backends/x11/cm/meta-renderer-x11-cm.h" +#include "compositor/meta-compositor-x11.h" +#include "core/display-private.h" + +struct _MetaBackendX11Cm +{ + MetaBackendX11 parent; + + char *keymap_layouts; + char *keymap_variants; + char *keymap_options; + int locked_group; +}; + +G_DEFINE_TYPE (MetaBackendX11Cm, meta_backend_x11_cm, META_TYPE_BACKEND_X11) + +static void +apply_keymap (MetaBackendX11 *x11); + +static void +take_touch_grab (MetaBackend *backend) +{ + MetaBackendX11 *x11 = META_BACKEND_X11 (backend); + Display *xdisplay = meta_backend_x11_get_xdisplay (x11); + unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; + XIEventMask mask = { META_VIRTUAL_CORE_POINTER_ID, sizeof (mask_bits), mask_bits }; + XIGrabModifiers mods = { XIAnyModifier, 0 }; + + XISetMask (mask.mask, XI_TouchBegin); + XISetMask (mask.mask, XI_TouchUpdate); + XISetMask (mask.mask, XI_TouchEnd); + + XIGrabTouchBegin (xdisplay, META_VIRTUAL_CORE_POINTER_ID, + DefaultRootWindow (xdisplay), + False, &mask, 1, &mods); +} + +static void +on_device_added (ClutterSeat *seat, + ClutterInputDevice *device, + gpointer user_data) +{ + MetaBackendX11 *x11 = META_BACKEND_X11 (user_data); + + if (clutter_input_device_get_device_type (device) == CLUTTER_KEYBOARD_DEVICE) + apply_keymap (x11); +} + +static void +meta_backend_x11_cm_post_init (MetaBackend *backend) +{ + MetaBackendClass *parent_backend_class = + META_BACKEND_CLASS (meta_backend_x11_cm_parent_class); + ClutterSeat *seat; + + parent_backend_class->post_init (backend); + + seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); + g_signal_connect_object (seat, "device-added", + G_CALLBACK (on_device_added), backend, 0); + + take_touch_grab (backend); +} + +static MetaRenderer * +meta_backend_x11_cm_create_renderer (MetaBackend *backend, + GError **error) +{ + return g_object_new (META_TYPE_RENDERER_X11_CM, + "backend", backend, + NULL); +} + +static MetaMonitorManager * +meta_backend_x11_cm_create_monitor_manager (MetaBackend *backend, + GError **error) +{ + return g_object_new (META_TYPE_MONITOR_MANAGER_XRANDR, + "backend", backend, + NULL); +} + +static MetaCursorRenderer * +meta_backend_x11_cm_create_cursor_renderer (MetaBackend *backend) +{ + return g_object_new (META_TYPE_CURSOR_RENDERER_X11, NULL); +} + +static MetaInputSettings * +meta_backend_x11_cm_create_input_settings (MetaBackend *backend) +{ + return g_object_new (META_TYPE_INPUT_SETTINGS_X11, NULL); +} + +static void +meta_backend_x11_cm_update_screen_size (MetaBackend *backend, + int width, + int height) +{ + MetaBackendX11 *x11 = META_BACKEND_X11 (backend); + Display *xdisplay = meta_backend_x11_get_xdisplay (x11); + Window xwin = meta_backend_x11_get_xwindow (x11); + + XResizeWindow (xdisplay, xwin, width, height); +} + +static void +meta_backend_x11_cm_select_stage_events (MetaBackend *backend) +{ + MetaBackendX11 *x11 = META_BACKEND_X11 (backend); + Display *xdisplay = meta_backend_x11_get_xdisplay (x11); + Window xwin = meta_backend_x11_get_xwindow (x11); + unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; + XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; + + XISetMask (mask.mask, XI_KeyPress); + XISetMask (mask.mask, XI_KeyRelease); + XISetMask (mask.mask, XI_ButtonPress); + XISetMask (mask.mask, XI_ButtonRelease); + XISetMask (mask.mask, XI_Enter); + XISetMask (mask.mask, XI_Leave); + XISetMask (mask.mask, XI_FocusIn); + XISetMask (mask.mask, XI_FocusOut); + XISetMask (mask.mask, XI_Motion); + + XISelectEvents (xdisplay, xwin, &mask, 1); +} + +static void +get_xkbrf_var_defs (Display *xdisplay, + const char *layouts, + const char *variants, + const char *options, + char **rules_p, + XkbRF_VarDefsRec *var_defs) +{ + char *rules = NULL; + + /* Get it from the X property or fallback on defaults */ + if (!XkbRF_GetNamesProp (xdisplay, &rules, var_defs) || !rules) + { + rules = strdup (DEFAULT_XKB_RULES_FILE); + var_defs->model = strdup (DEFAULT_XKB_MODEL); + var_defs->layout = NULL; + var_defs->variant = NULL; + var_defs->options = NULL; + } + + /* Swap in our new options... */ + free (var_defs->layout); + var_defs->layout = strdup (layouts); + free (var_defs->variant); + var_defs->variant = strdup (variants); + free (var_defs->options); + var_defs->options = strdup (options); + + /* Sometimes, the property is a file path, and sometimes it's + not. Normalize it so it's always a file path. */ + if (rules[0] == '/') + *rules_p = g_strdup (rules); + else + *rules_p = g_build_filename (XKB_BASE, "rules", rules, NULL); + + free (rules); +} + +static void +free_xkbrf_var_defs (XkbRF_VarDefsRec *var_defs) +{ + free (var_defs->model); + free (var_defs->layout); + free (var_defs->variant); + free (var_defs->options); +} + +static void +free_xkb_component_names (XkbComponentNamesRec *p) +{ + free (p->keymap); + free (p->keycodes); + free (p->types); + free (p->compat); + free (p->symbols); + free (p->geometry); +} + +static void +upload_xkb_description (Display *xdisplay, + const gchar *rules_file_path, + XkbRF_VarDefsRec *var_defs, + XkbComponentNamesRec *comp_names) +{ + XkbDescRec *xkb_desc; + gchar *rules_file; + + /* Upload it to the X server using the same method as setxkbmap */ + xkb_desc = XkbGetKeyboardByName (xdisplay, + XkbUseCoreKbd, + comp_names, + XkbGBN_AllComponentsMask, + XkbGBN_AllComponentsMask & + (~XkbGBN_GeometryMask), True); + if (!xkb_desc) + { + g_warning ("Couldn't upload new XKB keyboard description"); + return; + } + + XkbFreeKeyboard (xkb_desc, 0, True); + + rules_file = g_path_get_basename (rules_file_path); + + if (!XkbRF_SetNamesProp (xdisplay, rules_file, var_defs)) + g_warning ("Couldn't update the XKB root window property"); + + g_free (rules_file); +} + +static void +apply_keymap (MetaBackendX11 *x11) +{ + MetaBackendX11Cm *x11_cm = META_BACKEND_X11_CM (x11); + Display *xdisplay = meta_backend_x11_get_xdisplay (x11); + XkbRF_RulesRec *xkb_rules; + XkbRF_VarDefsRec xkb_var_defs = { 0 }; + char *rules_file_path; + + if (!x11_cm->keymap_layouts || + !x11_cm->keymap_variants || + !x11_cm->keymap_options) + return; + + get_xkbrf_var_defs (xdisplay, + x11_cm->keymap_layouts, + x11_cm->keymap_variants, + x11_cm->keymap_options, + &rules_file_path, + &xkb_var_defs); + + xkb_rules = XkbRF_Load (rules_file_path, NULL, True, True); + if (xkb_rules) + { + XkbComponentNamesRec xkb_comp_names = { 0 }; + + XkbRF_GetComponents (xkb_rules, &xkb_var_defs, &xkb_comp_names); + upload_xkb_description (xdisplay, rules_file_path, &xkb_var_defs, &xkb_comp_names); + + free_xkb_component_names (&xkb_comp_names); + XkbRF_Free (xkb_rules, True); + } + else + { + g_warning ("Couldn't load XKB rules"); + } + + free_xkbrf_var_defs (&xkb_var_defs); + g_free (rules_file_path); +} + +static void +meta_backend_x11_cm_set_keymap (MetaBackend *backend, + const char *layouts, + const char *variants, + const char *options) +{ + MetaBackendX11 *x11 = META_BACKEND_X11 (backend); + MetaBackendX11Cm *x11_cm = META_BACKEND_X11_CM (x11); + + g_free (x11_cm->keymap_layouts); + x11_cm->keymap_layouts = g_strdup (layouts); + g_free (x11_cm->keymap_variants); + x11_cm->keymap_variants = g_strdup (variants); + g_free (x11_cm->keymap_options); + x11_cm->keymap_options = g_strdup (options); + + apply_keymap (x11); +} + +static void +meta_backend_x11_cm_lock_layout_group (MetaBackend *backend, + guint idx) +{ + MetaBackendX11 *x11 = META_BACKEND_X11 (backend); + MetaBackendX11Cm *x11_cm = META_BACKEND_X11_CM (x11); + Display *xdisplay = meta_backend_x11_get_xdisplay (x11); + + x11_cm->locked_group = idx; + XkbLockGroup (xdisplay, XkbUseCoreKbd, idx); +} + +static gboolean +meta_backend_x11_cm_handle_host_xevent (MetaBackendX11 *backend_x11, + XEvent *event) +{ + MetaBackend *backend = META_BACKEND (backend_x11); + MetaBackendX11 *x11 = META_BACKEND_X11 (backend); + MetaBackendX11Cm *x11_cm = META_BACKEND_X11_CM (x11); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaMonitorManagerXrandr *monitor_manager_xrandr = + META_MONITOR_MANAGER_XRANDR (monitor_manager); + Display *xdisplay = meta_backend_x11_get_xdisplay (x11); + gboolean bypass_clutter = FALSE; + MetaDisplay *display; + + display = meta_get_display (); + if (display) + { + MetaCompositor *compositor = display->compositor; + MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (compositor); + Display *xdisplay = meta_backend_x11_get_xdisplay (x11); + + if (meta_dnd_handle_xdnd_event (backend, compositor_x11, + xdisplay, event)) + bypass_clutter = TRUE; + } + + if (event->type == meta_backend_x11_get_xkb_event_base (x11)) + { + XkbEvent *xkb_ev = (XkbEvent *) event; + + if (xkb_ev->any.device == META_VIRTUAL_CORE_KEYBOARD_ID) + { + switch (xkb_ev->any.xkb_type) + { + case XkbStateNotify: + if (xkb_ev->state.changed & XkbGroupLockMask) + { + if (x11_cm->locked_group != xkb_ev->state.locked_group) + XkbLockGroup (xdisplay, XkbUseCoreKbd, + x11_cm->locked_group); + } + break; + default: + break; + } + } + } + + bypass_clutter |= + meta_monitor_manager_xrandr_handle_xevent (monitor_manager_xrandr, event); + + return bypass_clutter; +} + +static void +meta_backend_x11_cm_translate_device_event (MetaBackendX11 *x11, + XIDeviceEvent *device_event) +{ + Window stage_window = meta_backend_x11_get_xwindow (x11); + + if (device_event->event != stage_window) + { + device_event->event = stage_window; + + /* As an X11 compositor, the stage window is always at 0,0, so + * using root coordinates will give us correct stage coordinates + * as well... */ + device_event->event_x = device_event->root_x; + device_event->event_y = device_event->root_y; + } +} + +static void +meta_backend_x11_cm_translate_crossing_event (MetaBackendX11 *x11, + XIEnterEvent *enter_event) +{ + Window stage_window = meta_backend_x11_get_xwindow (x11); + + if (enter_event->event != stage_window) + { + enter_event->event = stage_window; + enter_event->event_x = enter_event->root_x; + enter_event->event_y = enter_event->root_y; + } +} + +static void +meta_backend_x11_cm_init (MetaBackendX11Cm *backend_x11_cm) +{ + MetaGpuXrandr *gpu_xrandr; + + /* + * The X server deals with multiple GPUs for us, so we just see what the X + * server gives us as one single GPU, even though it may actually be backed + * by multiple. + */ + gpu_xrandr = meta_gpu_xrandr_new (META_BACKEND_X11 (backend_x11_cm)); + meta_backend_add_gpu (META_BACKEND (backend_x11_cm), + META_GPU (gpu_xrandr)); +} + +static void +meta_backend_x11_cm_class_init (MetaBackendX11CmClass *klass) +{ + MetaBackendClass *backend_class = META_BACKEND_CLASS (klass); + MetaBackendX11Class *backend_x11_class = META_BACKEND_X11_CLASS (klass); + + backend_class->post_init = meta_backend_x11_cm_post_init; + backend_class->create_renderer = meta_backend_x11_cm_create_renderer; + backend_class->create_monitor_manager = meta_backend_x11_cm_create_monitor_manager; + backend_class->create_cursor_renderer = meta_backend_x11_cm_create_cursor_renderer; + backend_class->create_input_settings = meta_backend_x11_cm_create_input_settings; + backend_class->update_screen_size = meta_backend_x11_cm_update_screen_size; + backend_class->select_stage_events = meta_backend_x11_cm_select_stage_events; + backend_class->lock_layout_group = meta_backend_x11_cm_lock_layout_group; + backend_class->set_keymap = meta_backend_x11_cm_set_keymap; + + backend_x11_class->handle_host_xevent = meta_backend_x11_cm_handle_host_xevent; + backend_x11_class->translate_device_event = meta_backend_x11_cm_translate_device_event; + backend_x11_class->translate_crossing_event = meta_backend_x11_cm_translate_crossing_event; +} + diff --git a/src/backends/x11/cm/meta-backend-x11-cm.h b/src/backends/x11/cm/meta-backend-x11-cm.h new file mode 100644 index 000000000..5332da13d --- /dev/null +++ b/src/backends/x11/cm/meta-backend-x11-cm.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_BACKEND_X11_CM_H +#define META_BACKEND_X11_CM_H + +#include <glib-object.h> + +#include "backends/x11/meta-backend-x11.h" + +#define META_TYPE_BACKEND_X11_CM (meta_backend_x11_cm_get_type ()) +G_DECLARE_FINAL_TYPE (MetaBackendX11Cm, meta_backend_x11_cm, + META, BACKEND_X11_CM, MetaBackendX11) + +#endif /* META_BACKEND_X11_CM_H */ diff --git a/src/backends/x11/cm/meta-cursor-sprite-xfixes.c b/src/backends/x11/cm/meta-cursor-sprite-xfixes.c new file mode 100644 index 000000000..0c524668e --- /dev/null +++ b/src/backends/x11/cm/meta-cursor-sprite-xfixes.c @@ -0,0 +1,231 @@ +/* + * Copyright 2013, 2018 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include "backends/x11/cm/meta-cursor-sprite-xfixes.h" + +#include <X11/extensions/Xfixes.h> + +#include "core/display-private.h" +#include "meta/meta-x11-display.h" + +enum +{ + PROP_0, + + PROP_DISPLAY, + + N_PROPS +}; + +static GParamSpec *obj_props[N_PROPS]; + +struct _MetaCursorSpriteXfixes +{ + MetaCursorSprite parent; + + MetaDisplay *display; +}; + +static void +meta_screen_cast_xfixes_init_initable_iface (GInitableIface *iface); + +G_DEFINE_TYPE_WITH_CODE (MetaCursorSpriteXfixes, + meta_cursor_sprite_xfixes, + META_TYPE_CURSOR_SPRITE, + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + meta_screen_cast_xfixes_init_initable_iface)) + +static void +meta_cursor_sprite_xfixes_realize_texture (MetaCursorSprite *sprite) +{ +} + +static gboolean +meta_cursor_sprite_xfixes_is_animated (MetaCursorSprite *sprite) +{ + return FALSE; +} + +static void +meta_cursor_sprite_xfixes_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaCursorSpriteXfixes *sprite_xfixes = META_CURSOR_SPRITE_XFIXES (object); + + switch (prop_id) + { + case PROP_DISPLAY: + g_value_set_object (value, sprite_xfixes->display); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_cursor_sprite_xfixes_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaCursorSpriteXfixes *sprite_xfixes = META_CURSOR_SPRITE_XFIXES (object); + + switch (prop_id) + { + case PROP_DISPLAY: + sprite_xfixes->display = g_value_get_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +MetaCursorSpriteXfixes * +meta_cursor_sprite_xfixes_new (MetaDisplay *display, + GError **error) +{ + return g_initable_new (META_TYPE_CURSOR_SPRITE_XFIXES, + NULL, error, + "display", display, + NULL); +} + +static gboolean +meta_cursor_sprite_xfixes_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + MetaCursorSpriteXfixes *sprite_xfixes = + META_CURSOR_SPRITE_XFIXES (initable); + MetaCursorSprite *sprite = META_CURSOR_SPRITE (sprite_xfixes); + MetaX11Display *x11_display; + Display *xdisplay; + XFixesCursorImage *cursor_image; + CoglTexture2D *texture; + uint8_t *cursor_data; + gboolean free_cursor_data; + ClutterBackend *clutter_backend; + CoglContext *cogl_context; + + x11_display = meta_display_get_x11_display (sprite_xfixes->display); + xdisplay = meta_x11_display_get_xdisplay (x11_display); + cursor_image = XFixesGetCursorImage (xdisplay); + if (!cursor_image) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Failed to get cursor image"); + return FALSE; + } + + /* + * Like all X APIs, XFixesGetCursorImage() returns arrays of 32-bit + * quantities as arrays of long; we need to convert on 64 bit + */ + if (sizeof (long) == 4) + { + cursor_data = (uint8_t *) cursor_image->pixels; + free_cursor_data = FALSE; + } + else + { + int i, j; + uint32_t *cursor_words; + unsigned long *p; + uint32_t *q; + + cursor_words = g_new (uint32_t, + cursor_image->width * cursor_image->height); + cursor_data = (uint8_t *) cursor_words; + + p = cursor_image->pixels; + q = cursor_words; + for (j = 0; j < cursor_image->height; j++) + { + for (i = 0; i < cursor_image->width; i++) + *(q++) = *(p++); + } + + free_cursor_data = TRUE; + } + + clutter_backend = clutter_get_default_backend (); + cogl_context = clutter_backend_get_cogl_context (clutter_backend); + texture = cogl_texture_2d_new_from_data (cogl_context, + cursor_image->width, + cursor_image->height, + CLUTTER_CAIRO_FORMAT_ARGB32, + cursor_image->width * 4, /* stride */ + cursor_data, + error); + + if (free_cursor_data) + g_free (cursor_data); + + if (!sprite) + return FALSE; + + meta_cursor_sprite_set_texture (sprite, + COGL_TEXTURE (texture), + cursor_image->xhot, + cursor_image->yhot); + cogl_object_unref (texture); + XFree (cursor_image); + + return TRUE; +} + +static void +meta_screen_cast_xfixes_init_initable_iface (GInitableIface *iface) +{ + iface->init = meta_cursor_sprite_xfixes_initable_init; +} + +static void +meta_cursor_sprite_xfixes_init (MetaCursorSpriteXfixes *sprite_xfixes) +{ +} + +static void +meta_cursor_sprite_xfixes_class_init (MetaCursorSpriteXfixesClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MetaCursorSpriteClass *cursor_sprite_class = META_CURSOR_SPRITE_CLASS (klass); + + object_class->get_property = meta_cursor_sprite_xfixes_get_property; + object_class->set_property = meta_cursor_sprite_xfixes_set_property; + + cursor_sprite_class->realize_texture = + meta_cursor_sprite_xfixes_realize_texture; + cursor_sprite_class->is_animated = meta_cursor_sprite_xfixes_is_animated; + + obj_props[PROP_DISPLAY] = + g_param_spec_object ("display", + "display", + "MetaDisplay", + META_TYPE_DISPLAY, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + g_object_class_install_properties (object_class, N_PROPS, obj_props); +} diff --git a/src/backends/x11/cm/meta-cursor-sprite-xfixes.h b/src/backends/x11/cm/meta-cursor-sprite-xfixes.h new file mode 100644 index 000000000..c7073fc2c --- /dev/null +++ b/src/backends/x11/cm/meta-cursor-sprite-xfixes.h @@ -0,0 +1,36 @@ +/* + * Copyright 2013, 2018 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + */ + +#ifndef META_CURSOR_SPRITE_XFIXES_H +#define META_CURSOR_SPRITE_XFIXES_H + +#include <glib-object.h> + +#include "backends/meta-cursor.h" +#include "meta/types.h" + +#define META_TYPE_CURSOR_SPRITE_XFIXES (meta_cursor_sprite_xfixes_get_type ()) +G_DECLARE_FINAL_TYPE (MetaCursorSpriteXfixes, + meta_cursor_sprite_xfixes, + META, CURSOR_SPRITE_XFIXES, + MetaCursorSprite) + +MetaCursorSpriteXfixes * meta_cursor_sprite_xfixes_new (MetaDisplay *display, + GError **error); + +#endif /* META_CURSOR_SPRITE_XFIXES_H */ diff --git a/src/backends/x11/cm/meta-renderer-x11-cm.c b/src/backends/x11/cm/meta-renderer-x11-cm.c new file mode 100644 index 000000000..2490b055d --- /dev/null +++ b/src/backends/x11/cm/meta-renderer-x11-cm.c @@ -0,0 +1,107 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#include "config.h" + +#include "backends/x11/cm/meta-renderer-x11-cm.h" + +#include "backends/meta-renderer-view.h" + +struct _MetaRendererX11Cm +{ + MetaRendererX11 parent; + + MetaRendererView *screen_view; +}; + +G_DEFINE_TYPE (MetaRendererX11Cm, meta_renderer_x11_cm, + META_TYPE_RENDERER_X11) + +void +meta_renderer_x11_cm_ensure_screen_view (MetaRendererX11Cm *renderer_x11_cm, + int width, + int height) +{ + cairo_rectangle_int_t view_layout; + + if (renderer_x11_cm->screen_view) + return; + + view_layout = (cairo_rectangle_int_t) { + .width = width, + .height = height, + }; + renderer_x11_cm->screen_view = g_object_new (META_TYPE_RENDERER_VIEW, + "layout", &view_layout, + NULL); + meta_renderer_add_view (META_RENDERER (renderer_x11_cm), + renderer_x11_cm->screen_view); +} + +void +meta_renderer_x11_cm_resize (MetaRendererX11Cm *renderer_x11_cm, + int width, + int height) +{ + cairo_rectangle_int_t view_layout; + + view_layout = (cairo_rectangle_int_t) { + .width = width, + .height = height, + }; + + g_object_set (G_OBJECT (renderer_x11_cm->screen_view), + "layout", &view_layout, + NULL); +} + +void +meta_renderer_x11_cm_set_onscreen (MetaRendererX11Cm *renderer_x11_cm, + CoglOnscreen *onscreen) +{ + g_object_set (G_OBJECT (renderer_x11_cm->screen_view), + "framebuffer", onscreen, + NULL); +} + +static void +meta_renderer_x11_cm_rebuild_views (MetaRenderer *renderer) +{ + MetaRendererX11Cm *renderer_x11_cm = META_RENDERER_X11_CM (renderer); + + g_return_if_fail (!meta_renderer_get_views (renderer)); + + meta_renderer_add_view (renderer, renderer_x11_cm->screen_view); +} + +static void +meta_renderer_x11_cm_init (MetaRendererX11Cm *renderer_x11_cm) +{ +} + +static void +meta_renderer_x11_cm_class_init (MetaRendererX11CmClass *klass) +{ + MetaRendererClass *renderer_class = META_RENDERER_CLASS (klass); + + renderer_class->rebuild_views = meta_renderer_x11_cm_rebuild_views; +} diff --git a/src/backends/x11/cm/meta-renderer-x11-cm.h b/src/backends/x11/cm/meta-renderer-x11-cm.h new file mode 100644 index 000000000..65c5125bb --- /dev/null +++ b/src/backends/x11/cm/meta-renderer-x11-cm.h @@ -0,0 +1,44 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#ifndef META_RENDERER_X11_CM_H +#define META_RENDERER_X11_CM_H + +#include "backends/x11/meta-renderer-x11.h" + +#define META_TYPE_RENDERER_X11_CM (meta_renderer_x11_cm_get_type ()) +G_DECLARE_FINAL_TYPE (MetaRendererX11Cm, meta_renderer_x11_cm, + META, RENDERER_X11_CM, + MetaRendererX11) + +void meta_renderer_x11_cm_ensure_screen_view (MetaRendererX11Cm *renderer_x11_cm, + int width, + int height); + +void meta_renderer_x11_cm_resize (MetaRendererX11Cm *renderer_x11_cm, + int width, + int height); + +void meta_renderer_x11_cm_set_onscreen (MetaRendererX11Cm *renderer_x11_cm, + CoglOnscreen *onscreen); + +#endif /* META_RENDERER_X11_CM_H */ diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c new file mode 100644 index 000000000..e18e6a1ab --- /dev/null +++ b/src/backends/x11/meta-backend-x11.c @@ -0,0 +1,891 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jasper St. Pierre <jstpierre@mecheye.net> + */ + +/** + * SECTION:meta-backend-x11 + * @title: MetaBackendX11 + * @short_description: A X11 MetaBackend + * + * MetaBackendX11 is an implementation of #MetaBackend using X and X + * extensions, like XInput and XKB. + */ + +#include "config.h" + +#include "backends/x11/meta-backend-x11.h" + +#include <X11/XKBlib.h> +#include <X11/Xlib-xcb.h> +#include <X11/extensions/sync.h> +#include <stdlib.h> +#include <string.h> +#include <xkbcommon/xkbcommon-x11.h> + +#include "backends/meta-idle-monitor-private.h" +#include "backends/meta-stage-private.h" +#include "backends/x11/meta-clutter-backend-x11.h" +#include "backends/x11/meta-event-x11.h" +#include "backends/x11/meta-seat-x11.h" +#include "backends/x11/meta-stage-x11.h" +#include "backends/x11/meta-renderer-x11.h" +#include "clutter/clutter.h" +#include "clutter/x11/clutter-x11.h" +#include "compositor/compositor-private.h" +#include "core/display-private.h" +#include "meta/meta-cursor-tracker.h" +#include "meta/util.h" + +struct _MetaBackendX11Private +{ + /* The host X11 display */ + Display *xdisplay; + xcb_connection_t *xcb; + GSource *source; + + int xsync_event_base; + int xsync_error_base; + XSyncAlarm user_active_alarm; + XSyncCounter counter; + + int current_touch_replay_sync_serial; + int pending_touch_replay_sync_serial; + Atom touch_replay_sync_atom; + + int xinput_opcode; + int xinput_event_base; + int xinput_error_base; + Time latest_evtime; + + uint8_t xkb_event_base; + uint8_t xkb_error_base; + + struct xkb_keymap *keymap; + xkb_layout_index_t keymap_layout_group; + + MetaLogicalMonitor *cached_current_logical_monitor; +}; +typedef struct _MetaBackendX11Private MetaBackendX11Private; + +static GInitableIface *initable_parent_iface; + +static void +initable_iface_init (GInitableIface *initable_iface); + +G_DEFINE_TYPE_WITH_CODE (MetaBackendX11, meta_backend_x11, META_TYPE_BACKEND, + G_ADD_PRIVATE (MetaBackendX11) + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + initable_iface_init)); + + +static void +uint64_to_xsync_value (uint64_t value, + XSyncValue *xsync_value) +{ + XSyncIntsToValue (xsync_value, value & 0xffffffff, value >> 32); +} + +static XSyncAlarm +xsync_user_active_alarm_set (MetaBackendX11Private *priv) +{ + XSyncAlarmAttributes attr; + XSyncValue delta; + unsigned long flags; + + flags = (XSyncCACounter | XSyncCAValueType | XSyncCATestType | + XSyncCAValue | XSyncCADelta | XSyncCAEvents); + + XSyncIntToValue (&delta, 0); + attr.trigger.counter = priv->counter; + attr.trigger.value_type = XSyncAbsolute; + attr.delta = delta; + attr.events = TRUE; + + uint64_to_xsync_value (1, &attr.trigger.wait_value); + + attr.trigger.test_type = XSyncNegativeTransition; + return XSyncCreateAlarm (priv->xdisplay, flags, &attr); +} + +static XSyncCounter +find_idletime_counter (MetaBackendX11Private *priv) +{ + int i; + int n_counters; + XSyncSystemCounter *counters; + XSyncCounter counter = None; + + counters = XSyncListSystemCounters (priv->xdisplay, &n_counters); + for (i = 0; i < n_counters; i++) + { + if (g_strcmp0 (counters[i].name, "IDLETIME") == 0) + { + counter = counters[i].counter; + break; + } + } + XSyncFreeSystemCounterList (counters); + + return counter; +} + +static void +handle_alarm_notify (MetaBackend *backend, + XSyncAlarmNotifyEvent *alarm_event) +{ + MetaBackendX11 *x11 = META_BACKEND_X11 (backend); + MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); + MetaIdleMonitor *idle_monitor; + XSyncAlarmAttributes attr; + ClutterBackend *clutter_backend; + ClutterSeat *seat; + ClutterInputDevice *pointer; + + if (alarm_event->state != XSyncAlarmActive || + alarm_event->alarm != priv->user_active_alarm) + return; + + attr.events = TRUE; + XSyncChangeAlarm (priv->xdisplay, priv->user_active_alarm, + XSyncCAEvents, &attr); + + clutter_backend = meta_backend_get_clutter_backend (backend); + seat = clutter_backend_get_default_seat (clutter_backend); + pointer = clutter_seat_get_pointer (seat); + idle_monitor = meta_backend_get_idle_monitor (backend, pointer); + meta_idle_monitor_reset_idletime (idle_monitor); +} + +static void +meta_backend_x11_translate_device_event (MetaBackendX11 *x11, + XIDeviceEvent *device_event) +{ + MetaBackendX11Class *backend_x11_class = + META_BACKEND_X11_GET_CLASS (x11); + + backend_x11_class->translate_device_event (x11, device_event); +} + +static void +maybe_translate_touch_replay_pointer_event (MetaBackendX11 *x11, + XIDeviceEvent *device_event) +{ + MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); + + if (!device_event->send_event && + device_event->time != META_CURRENT_TIME && + priv->current_touch_replay_sync_serial != + priv->pending_touch_replay_sync_serial && + XSERVER_TIME_IS_BEFORE (device_event->time, priv->latest_evtime)) + { + /* Emulated pointer events received after XIRejectTouch is received + * on a passive touch grab will contain older timestamps, update those + * so we dont get InvalidTime at grabs. + */ + device_event->time = priv->latest_evtime; + } +} + +static void +translate_device_event (MetaBackendX11 *x11, + XIDeviceEvent *device_event) +{ + MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); + + meta_backend_x11_translate_device_event (x11, device_event); + + if (!device_event->send_event && device_event->time != META_CURRENT_TIME) + priv->latest_evtime = device_event->time; +} + +static void +meta_backend_x11_translate_crossing_event (MetaBackendX11 *x11, + XIEnterEvent *enter_event) +{ + MetaBackendX11Class *backend_x11_class = + META_BACKEND_X11_GET_CLASS (x11); + + if (backend_x11_class->translate_crossing_event) + backend_x11_class->translate_crossing_event (x11, enter_event); +} + +static void +translate_crossing_event (MetaBackendX11 *x11, + XIEnterEvent *enter_event) +{ + /* Throw out weird events generated by grabs. */ + if (enter_event->mode == XINotifyGrab || + enter_event->mode == XINotifyUngrab) + { + enter_event->event = None; + return; + } + + meta_backend_x11_translate_crossing_event (x11, enter_event); +} + +static void +handle_device_change (MetaBackendX11 *x11, + XIEvent *event) +{ + XIDeviceChangedEvent *device_changed; + ClutterInputDevice *device; + ClutterBackend *backend; + ClutterSeat *seat; + + if (event->evtype != XI_DeviceChanged) + return; + + device_changed = (XIDeviceChangedEvent *) event; + + if (device_changed->reason != XISlaveSwitch) + return; + + backend = meta_backend_get_clutter_backend (META_BACKEND (x11)); + seat = clutter_backend_get_default_seat (backend); + device = meta_seat_x11_lookup_device_id (META_SEAT_X11 (seat), + device_changed->sourceid); + meta_backend_update_last_device (META_BACKEND (x11), device); +} + +/* Clutter makes the assumption that there is only one X window + * per stage, which is a valid assumption to make for a generic + * application toolkit. As such, it will ignore any events sent + * to the a stage that isn't its X window. + * + * When running as an X window manager, we need to respond to + * events from lots of windows. Trick Clutter into translating + * these events by pretending we got an event on the stage window. + */ +static void +maybe_spoof_event_as_stage_event (MetaBackendX11 *x11, + XIEvent *input_event) +{ + switch (input_event->evtype) + { + case XI_Motion: + case XI_ButtonPress: + case XI_ButtonRelease: + maybe_translate_touch_replay_pointer_event (x11, + (XIDeviceEvent *) input_event); + G_GNUC_FALLTHROUGH; + case XI_KeyPress: + case XI_KeyRelease: + case XI_TouchBegin: + case XI_TouchUpdate: + case XI_TouchEnd: + translate_device_event (x11, (XIDeviceEvent *) input_event); + break; + case XI_Enter: + case XI_Leave: + translate_crossing_event (x11, (XIEnterEvent *) input_event); + break; + default: + break; + } +} + +static void +handle_input_event (MetaBackendX11 *x11, + XEvent *event) +{ + MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); + + if (event->type == GenericEvent && + event->xcookie.extension == priv->xinput_opcode) + { + XIEvent *input_event = (XIEvent *) event->xcookie.data; + + if (input_event->evtype == XI_DeviceChanged) + handle_device_change (x11, input_event); + else + maybe_spoof_event_as_stage_event (x11, input_event); + } +} + +static void +keymap_changed (MetaBackend *backend) +{ + MetaBackendX11 *x11 = META_BACKEND_X11 (backend); + MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); + + if (priv->keymap) + { + xkb_keymap_unref (priv->keymap); + priv->keymap = NULL; + } + + g_signal_emit_by_name (backend, "keymap-changed", 0); +} + +static gboolean +meta_backend_x11_handle_host_xevent (MetaBackendX11 *backend_x11, + XEvent *event) +{ + MetaBackendX11Class *backend_x11_class = + META_BACKEND_X11_GET_CLASS (backend_x11); + + return backend_x11_class->handle_host_xevent (backend_x11, event); +} + +static void +handle_host_xevent (MetaBackend *backend, + XEvent *event) +{ + MetaBackendX11 *x11 = META_BACKEND_X11 (backend); + MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); + gboolean bypass_clutter = FALSE; + MetaDisplay *display; + + switch (event->type) + { + case ClientMessage: + if (event->xclient.window == meta_backend_x11_get_xwindow (x11) && + event->xclient.message_type == priv->touch_replay_sync_atom) + priv->current_touch_replay_sync_serial = event->xclient.data.l[0]; + break; + default: + break; + } + + XGetEventData (priv->xdisplay, &event->xcookie); + + display = meta_get_display (); + if (display) + { + MetaCompositor *compositor = display->compositor; + MetaPluginManager *plugin_mgr = + meta_compositor_get_plugin_manager (compositor); + + if (meta_plugin_manager_xevent_filter (plugin_mgr, event)) + bypass_clutter = TRUE; + } + + bypass_clutter = (meta_backend_x11_handle_host_xevent (x11, event) || + bypass_clutter); + + if (event->type == (priv->xsync_event_base + XSyncAlarmNotify)) + handle_alarm_notify (backend, (XSyncAlarmNotifyEvent *) event); + + if (event->type == priv->xkb_event_base) + { + XkbEvent *xkb_ev = (XkbEvent *) event; + + if (xkb_ev->any.device == META_VIRTUAL_CORE_KEYBOARD_ID) + { + switch (xkb_ev->any.xkb_type) + { + case XkbNewKeyboardNotify: + case XkbMapNotify: + keymap_changed (backend); + break; + case XkbStateNotify: + if (xkb_ev->state.changed & XkbGroupLockMask) + { + int layout_group; + gboolean layout_group_changed; + + layout_group = xkb_ev->state.locked_group; + layout_group_changed = + (int) priv->keymap_layout_group != layout_group; + priv->keymap_layout_group = layout_group; + + if (layout_group_changed) + meta_backend_notify_keymap_layout_group_changed (backend, + layout_group); + } + break; + default: + break; + } + } + } + + if (!bypass_clutter) + { + handle_input_event (x11, event); + meta_x11_handle_event (event); + } + + XFreeEventData (priv->xdisplay, &event->xcookie); +} + +typedef struct { + GSource base; + GPollFD event_poll_fd; + MetaBackend *backend; +} XEventSource; + +static gboolean +x_event_source_prepare (GSource *source, + int *timeout) +{ + XEventSource *x_source = (XEventSource *) source; + MetaBackend *backend = x_source->backend; + MetaBackendX11 *x11 = META_BACKEND_X11 (backend); + MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); + + *timeout = -1; + + return XPending (priv->xdisplay); +} + +static gboolean +x_event_source_check (GSource *source) +{ + XEventSource *x_source = (XEventSource *) source; + MetaBackend *backend = x_source->backend; + MetaBackendX11 *x11 = META_BACKEND_X11 (backend); + MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); + + return XPending (priv->xdisplay); +} + +static gboolean +x_event_source_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + XEventSource *x_source = (XEventSource *) source; + MetaBackend *backend = x_source->backend; + MetaBackendX11 *x11 = META_BACKEND_X11 (backend); + MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); + + while (XPending (priv->xdisplay)) + { + XEvent event; + + XNextEvent (priv->xdisplay, &event); + + handle_host_xevent (backend, &event); + } + + return TRUE; +} + +static GSourceFuncs x_event_funcs = { + x_event_source_prepare, + x_event_source_check, + x_event_source_dispatch, +}; + +static GSource * +x_event_source_new (MetaBackend *backend) +{ + MetaBackendX11 *x11 = META_BACKEND_X11 (backend); + MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); + GSource *source; + XEventSource *x_source; + + source = g_source_new (&x_event_funcs, sizeof (XEventSource)); + x_source = (XEventSource *) source; + x_source->backend = backend; + x_source->event_poll_fd.fd = ConnectionNumber (priv->xdisplay); + x_source->event_poll_fd.events = G_IO_IN; + g_source_add_poll (source, &x_source->event_poll_fd); + + g_source_attach (source, NULL); + return source; +} + +static void +on_monitors_changed (MetaMonitorManager *manager, + MetaBackend *backend) +{ + MetaBackendX11 *x11 = META_BACKEND_X11 (backend); + MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); + + priv->cached_current_logical_monitor = NULL; +} + +static void +meta_backend_x11_post_init (MetaBackend *backend) +{ + MetaBackendX11 *x11 = META_BACKEND_X11 (backend); + MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); + MetaMonitorManager *monitor_manager; + ClutterBackend *clutter_backend; + ClutterSeat *seat; + int major, minor; + gboolean has_xi = FALSE; + + priv->source = x_event_source_new (backend); + + if (!XSyncQueryExtension (priv->xdisplay, &priv->xsync_event_base, &priv->xsync_error_base) || + !XSyncInitialize (priv->xdisplay, &major, &minor)) + meta_fatal ("Could not initialize XSync"); + + priv->counter = find_idletime_counter (priv); + if (priv->counter == None) + meta_fatal ("Could not initialize XSync counter"); + + priv->user_active_alarm = xsync_user_active_alarm_set (priv); + + if (XQueryExtension (priv->xdisplay, + "XInputExtension", + &priv->xinput_opcode, + &priv->xinput_error_base, + &priv->xinput_event_base)) + { + major = 2; minor = 3; + if (XIQueryVersion (priv->xdisplay, &major, &minor) == Success) + { + int version = (major * 10) + minor; + if (version >= 22) + has_xi = TRUE; + } + } + + if (!has_xi) + meta_fatal ("X server doesn't have the XInput extension, version 2.2 or newer\n"); + + if (!xkb_x11_setup_xkb_extension (priv->xcb, + XKB_X11_MIN_MAJOR_XKB_VERSION, + XKB_X11_MIN_MINOR_XKB_VERSION, + XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS, + NULL, NULL, + &priv->xkb_event_base, + &priv->xkb_error_base)) + meta_fatal ("X server doesn't have the XKB extension, version %d.%d or newer\n", + XKB_X11_MIN_MAJOR_XKB_VERSION, XKB_X11_MIN_MINOR_XKB_VERSION); + + META_BACKEND_CLASS (meta_backend_x11_parent_class)->post_init (backend); + + monitor_manager = meta_backend_get_monitor_manager (backend); + g_signal_connect (monitor_manager, "monitors-changed-internal", + G_CALLBACK (on_monitors_changed), backend); + + priv->touch_replay_sync_atom = XInternAtom (priv->xdisplay, + "_MUTTER_TOUCH_SEQUENCE_SYNC", + False); + + clutter_backend = meta_backend_get_clutter_backend (backend); + seat = clutter_backend_get_default_seat (clutter_backend); + meta_seat_x11_notify_devices (META_SEAT_X11 (seat), + CLUTTER_STAGE (meta_backend_get_stage (backend))); +} + +static ClutterBackend * +meta_backend_x11_create_clutter_backend (MetaBackend *backend) +{ + return g_object_new (META_TYPE_CLUTTER_BACKEND_X11, NULL); +} + +static gboolean +meta_backend_x11_grab_device (MetaBackend *backend, + int device_id, + uint32_t timestamp) +{ + MetaBackendX11 *x11 = META_BACKEND_X11 (backend); + MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); + unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; + XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; + int ret; + + if (timestamp != META_CURRENT_TIME && + XSERVER_TIME_IS_BEFORE (timestamp, priv->latest_evtime)) + timestamp = priv->latest_evtime; + + XISetMask (mask.mask, XI_ButtonPress); + XISetMask (mask.mask, XI_ButtonRelease); + XISetMask (mask.mask, XI_Enter); + XISetMask (mask.mask, XI_Leave); + XISetMask (mask.mask, XI_Motion); + XISetMask (mask.mask, XI_KeyPress); + XISetMask (mask.mask, XI_KeyRelease); + + ret = XIGrabDevice (priv->xdisplay, device_id, + meta_backend_x11_get_xwindow (x11), + timestamp, + None, + XIGrabModeAsync, XIGrabModeAsync, + False, /* owner_events */ + &mask); + + return (ret == Success); +} + +static gboolean +meta_backend_x11_ungrab_device (MetaBackend *backend, + int device_id, + uint32_t timestamp) +{ + MetaBackendX11 *x11 = META_BACKEND_X11 (backend); + MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); + int ret; + + ret = XIUngrabDevice (priv->xdisplay, device_id, timestamp); + XFlush (priv->xdisplay); + + return (ret == Success); +} + +static void +meta_backend_x11_finish_touch_sequence (MetaBackend *backend, + ClutterEventSequence *sequence, + MetaSequenceState state) +{ + MetaBackendX11 *x11 = META_BACKEND_X11 (backend); + MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); + int event_mode; + + if (state == META_SEQUENCE_ACCEPTED) + event_mode = XIAcceptTouch; + else if (state == META_SEQUENCE_REJECTED) + event_mode = XIRejectTouch; + else + g_return_if_reached (); + + XIAllowTouchEvents (priv->xdisplay, + META_VIRTUAL_CORE_POINTER_ID, + meta_x11_event_sequence_get_touch_detail (sequence), + DefaultRootWindow (priv->xdisplay), event_mode); + + if (state == META_SEQUENCE_REJECTED) + { + XClientMessageEvent ev; + + ev = (XClientMessageEvent) { + .type = ClientMessage, + .window = meta_backend_x11_get_xwindow (x11), + .message_type = priv->touch_replay_sync_atom, + .format = 32, + .data.l[0] = ++priv->pending_touch_replay_sync_serial, + }; + XSendEvent (priv->xdisplay, meta_backend_x11_get_xwindow (x11), + False, 0, (XEvent *) &ev); + } +} + +static MetaLogicalMonitor * +meta_backend_x11_get_current_logical_monitor (MetaBackend *backend) +{ + MetaBackendX11 *x11 = META_BACKEND_X11 (backend); + MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); + MetaCursorTracker *cursor_tracker; + int x, y; + MetaMonitorManager *monitor_manager; + MetaLogicalMonitor *logical_monitor; + + if (priv->cached_current_logical_monitor) + return priv->cached_current_logical_monitor; + + cursor_tracker = meta_backend_get_cursor_tracker (backend); + meta_cursor_tracker_get_pointer (cursor_tracker, &x, &y, NULL); + monitor_manager = meta_backend_get_monitor_manager (backend); + logical_monitor = + meta_monitor_manager_get_logical_monitor_at (monitor_manager, x, y); + + if (!logical_monitor && monitor_manager->logical_monitors) + logical_monitor = monitor_manager->logical_monitors->data; + + priv->cached_current_logical_monitor = logical_monitor; + return priv->cached_current_logical_monitor; +} + +static struct xkb_keymap * +meta_backend_x11_get_keymap (MetaBackend *backend) +{ + MetaBackendX11 *x11 = META_BACKEND_X11 (backend); + MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); + + if (priv->keymap == NULL) + { + struct xkb_context *context = xkb_context_new (XKB_CONTEXT_NO_FLAGS); + priv->keymap = xkb_x11_keymap_new_from_device (context, + priv->xcb, + xkb_x11_get_core_keyboard_device_id (priv->xcb), + XKB_KEYMAP_COMPILE_NO_FLAGS); + if (priv->keymap == NULL) + priv->keymap = xkb_keymap_new_from_names (context, NULL, XKB_KEYMAP_COMPILE_NO_FLAGS); + + xkb_context_unref (context); + } + + return priv->keymap; +} + +static xkb_layout_index_t +meta_backend_x11_get_keymap_layout_group (MetaBackend *backend) +{ + MetaBackendX11 *x11 = META_BACKEND_X11 (backend); + MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); + + return priv->keymap_layout_group; +} + +static void +meta_backend_x11_set_numlock (MetaBackend *backend, + gboolean numlock_state) +{ + MetaBackendX11 *x11 = META_BACKEND_X11 (backend); + MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); + unsigned int num_mask; + + num_mask = XkbKeysymToModifiers (priv->xdisplay, XK_Num_Lock); + XkbLockModifiers (priv->xdisplay, XkbUseCoreKbd, num_mask, + numlock_state ? num_mask : 0); +} + +void +meta_backend_x11_handle_event (MetaBackendX11 *x11, + XEvent *xevent) +{ + MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); + + priv->cached_current_logical_monitor = NULL; +} + +uint8_t +meta_backend_x11_get_xkb_event_base (MetaBackendX11 *x11) +{ + MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); + + return priv->xkb_event_base; +} + +static void +init_xkb_state (MetaBackendX11 *x11) +{ + MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); + struct xkb_keymap *keymap; + int32_t device_id; + struct xkb_state *state; + + keymap = meta_backend_get_keymap (META_BACKEND (x11)); + + device_id = xkb_x11_get_core_keyboard_device_id (priv->xcb); + state = xkb_x11_state_new_from_device (keymap, priv->xcb, device_id); + + priv->keymap_layout_group = + xkb_state_serialize_layout (state, XKB_STATE_LAYOUT_LOCKED); + + xkb_state_unref (state); +} + +static gboolean +meta_backend_x11_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + MetaBackendX11 *x11 = META_BACKEND_X11 (initable); + MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); + Display *xdisplay; + const char *xdisplay_name; + + xdisplay_name = g_getenv ("DISPLAY"); + if (!xdisplay_name) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Unable to open display, DISPLAY not set"); + return FALSE; + } + + xdisplay = XOpenDisplay (xdisplay_name); + if (!xdisplay) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Unable to open display '%s'", xdisplay_name); + return FALSE; + } + + priv->xdisplay = xdisplay; + priv->xcb = XGetXCBConnection (priv->xdisplay); + clutter_x11_set_display (xdisplay); + + init_xkb_state (x11); + + return initable_parent_iface->init (initable, cancellable, error); +} + +static void +initable_iface_init (GInitableIface *initable_iface) +{ + initable_parent_iface = g_type_interface_peek_parent (initable_iface); + + initable_iface->init = meta_backend_x11_initable_init; +} + +static void +meta_backend_x11_finalize (GObject *object) +{ + MetaBackendX11 *x11 = META_BACKEND_X11 (object); + MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); + + if (priv->user_active_alarm != None) + { + XSyncDestroyAlarm (priv->xdisplay, priv->user_active_alarm); + priv->user_active_alarm = None; + } + + G_OBJECT_CLASS (meta_backend_x11_parent_class)->finalize (object); +} + +static void +meta_backend_x11_class_init (MetaBackendX11Class *klass) +{ + MetaBackendClass *backend_class = META_BACKEND_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_backend_x11_finalize; + backend_class->create_clutter_backend = meta_backend_x11_create_clutter_backend; + backend_class->post_init = meta_backend_x11_post_init; + backend_class->grab_device = meta_backend_x11_grab_device; + backend_class->ungrab_device = meta_backend_x11_ungrab_device; + backend_class->finish_touch_sequence = meta_backend_x11_finish_touch_sequence; + backend_class->get_current_logical_monitor = meta_backend_x11_get_current_logical_monitor; + backend_class->get_keymap = meta_backend_x11_get_keymap; + backend_class->get_keymap_layout_group = meta_backend_x11_get_keymap_layout_group; + backend_class->set_numlock = meta_backend_x11_set_numlock; +} + +static void +meta_backend_x11_init (MetaBackendX11 *x11) +{ + XInitThreads (); +} + +Display * +meta_backend_x11_get_xdisplay (MetaBackendX11 *x11) +{ + MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); + + return priv->xdisplay; +} + +Window +meta_backend_x11_get_xwindow (MetaBackendX11 *x11) +{ + ClutterActor *stage = meta_backend_get_stage (META_BACKEND (x11)); + return meta_x11_get_stage_window (CLUTTER_STAGE (stage)); +} + +void +meta_backend_x11_reload_cursor (MetaBackendX11 *x11) +{ + MetaBackend *backend = META_BACKEND (x11); + MetaCursorRenderer *cursor_renderer = + meta_backend_get_cursor_renderer (backend); + + meta_cursor_renderer_force_update (cursor_renderer); +} diff --git a/src/backends/x11/meta-backend-x11.h b/src/backends/x11/meta-backend-x11.h new file mode 100644 index 000000000..526bf0caa --- /dev/null +++ b/src/backends/x11/meta-backend-x11.h @@ -0,0 +1,61 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jasper St. Pierre <jstpierre@mecheye.net> + */ + +#ifndef META_BACKEND_X11_H +#define META_BACKEND_X11_H + +#include <stdint.h> +#include <X11/Xlib.h> + +#include "backends/meta-backend-private.h" +#include "backends/x11/meta-clutter-backend-x11.h" + +#define META_TYPE_BACKEND_X11 (meta_backend_x11_get_type ()) +G_DECLARE_DERIVABLE_TYPE (MetaBackendX11, meta_backend_x11, + META, BACKEND_X11, MetaBackend) + +struct _MetaBackendX11Class +{ + MetaBackendClass parent_class; + + gboolean (* handle_host_xevent) (MetaBackendX11 *x11, + XEvent *event); + void (* translate_device_event) (MetaBackendX11 *x11, + XIDeviceEvent *device_event); + void (* translate_crossing_event) (MetaBackendX11 *x11, + XIEnterEvent *enter_event); +}; + +Display * meta_backend_x11_get_xdisplay (MetaBackendX11 *backend); + +Window meta_backend_x11_get_xwindow (MetaBackendX11 *backend); + +void meta_backend_x11_handle_event (MetaBackendX11 *x11, + XEvent *xevent); + +uint8_t meta_backend_x11_get_xkb_event_base (MetaBackendX11 *x11); + +void meta_backend_x11_reload_cursor (MetaBackendX11 *x11); + +#endif /* META_BACKEND_X11_H */ diff --git a/src/backends/x11/meta-barrier-x11.c b/src/backends/x11/meta-barrier-x11.c new file mode 100644 index 000000000..4cf58a81a --- /dev/null +++ b/src/backends/x11/meta-barrier-x11.c @@ -0,0 +1,212 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014-2015 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jasper St. Pierre <jstpierre@mecheye.net> + * Jonas Ådahl <jadahl@gmail.com> + */ + +/** + * SECTION:barrier-x11 + * @Title: MetaBarrierImplX11 + * @Short_Description: Pointer barriers implementation for X11 + */ + +#include "config.h" + +#include <glib-object.h> +#include <X11/extensions/XInput2.h> +#include <X11/extensions/Xfixes.h> + +#include "backends/x11/meta-barrier-x11.h" +#include "core/display-private.h" +#include "meta/barrier.h" +#include "x11/meta-x11-display-private.h" + +struct _MetaBarrierImplX11 +{ + MetaBarrierImpl parent; + + MetaBarrier *barrier; + PointerBarrier xbarrier; +}; + +G_DEFINE_TYPE (MetaBarrierImplX11, + meta_barrier_impl_x11, + META_TYPE_BARRIER_IMPL) + +static gboolean +_meta_barrier_impl_x11_is_active (MetaBarrierImpl *impl) +{ + MetaBarrierImplX11 *self = META_BARRIER_IMPL_X11 (impl); + + return self->xbarrier != 0; +} + +static void +_meta_barrier_impl_x11_release (MetaBarrierImpl *impl, + MetaBarrierEvent *event) +{ + MetaBarrierImplX11 *self = META_BARRIER_IMPL_X11 (impl); + MetaDisplay *display = self->barrier->priv->display; + Display *dpy = meta_x11_display_get_xdisplay (display->x11_display); + + if (META_X11_DISPLAY_HAS_XINPUT_23 (display->x11_display)) + { + XIBarrierReleasePointer (dpy, + META_VIRTUAL_CORE_POINTER_ID, + self->xbarrier, event->event_id); + } +} + +static void +_meta_barrier_impl_x11_destroy (MetaBarrierImpl *impl) +{ + MetaBarrierImplX11 *self = META_BARRIER_IMPL_X11 (impl); + MetaDisplay *display = self->barrier->priv->display; + Display *dpy; + + if (display == NULL) + return; + + dpy = meta_x11_display_get_xdisplay (display->x11_display); + + if (!meta_barrier_is_active (self->barrier)) + return; + + XFixesDestroyPointerBarrier (dpy, self->xbarrier); + g_hash_table_remove (display->x11_display->xids, &self->xbarrier); + self->xbarrier = 0; +} + +MetaBarrierImpl * +meta_barrier_impl_x11_new (MetaBarrier *barrier) +{ + MetaBarrierImplX11 *self; + MetaDisplay *display = barrier->priv->display; + Display *dpy; + Window root; + unsigned int allowed_motion_dirs; + + if (display == NULL) + { + g_warning ("A display must be provided when constructing a barrier."); + return NULL; + } + + self = g_object_new (META_TYPE_BARRIER_IMPL_X11, NULL); + self->barrier = barrier; + + dpy = meta_x11_display_get_xdisplay (display->x11_display); + root = DefaultRootWindow (dpy); + + allowed_motion_dirs = + meta_border_get_allows_directions (&barrier->priv->border); + self->xbarrier = XFixesCreatePointerBarrier (dpy, root, + barrier->priv->border.line.a.x, + barrier->priv->border.line.a.y, + barrier->priv->border.line.b.x, + barrier->priv->border.line.b.y, + allowed_motion_dirs, + 0, NULL); + + g_hash_table_insert (display->x11_display->xids, &self->xbarrier, barrier); + + return META_BARRIER_IMPL (self); +} + +static void +meta_barrier_fire_xevent (MetaBarrier *barrier, + XIBarrierEvent *xevent) +{ + MetaBarrierEvent *event = g_slice_new0 (MetaBarrierEvent); + + event->ref_count = 1; + event->event_id = xevent->eventid; + event->time = xevent->time; + event->dt = xevent->dtime; + + event->x = xevent->root_x; + event->y = xevent->root_y; + event->dx = xevent->dx; + event->dy = xevent->dy; + + event->released = (xevent->flags & XIBarrierPointerReleased) != 0; + event->grabbed = (xevent->flags & XIBarrierDeviceIsGrabbed) != 0; + + switch (xevent->evtype) + { + case XI_BarrierHit: + _meta_barrier_emit_hit_signal (barrier, event); + break; + case XI_BarrierLeave: + _meta_barrier_emit_left_signal (barrier, event); + break; + default: + g_assert_not_reached (); + } + + meta_barrier_event_unref (event); +} + +gboolean +meta_x11_display_process_barrier_xevent (MetaX11Display *x11_display, + XIEvent *event) +{ + MetaBarrier *barrier; + XIBarrierEvent *xev; + + if (event == NULL) + return FALSE; + + switch (event->evtype) + { + case XI_BarrierHit: + case XI_BarrierLeave: + break; + default: + return FALSE; + } + + xev = (XIBarrierEvent *) event; + barrier = g_hash_table_lookup (x11_display->xids, &xev->barrier); + if (barrier != NULL) + { + meta_barrier_fire_xevent (barrier, xev); + return TRUE; + } + + return FALSE; +} + +static void +meta_barrier_impl_x11_class_init (MetaBarrierImplX11Class *klass) +{ + MetaBarrierImplClass *impl_class = META_BARRIER_IMPL_CLASS (klass); + + impl_class->is_active = _meta_barrier_impl_x11_is_active; + impl_class->release = _meta_barrier_impl_x11_release; + impl_class->destroy = _meta_barrier_impl_x11_destroy; +} + +static void +meta_barrier_impl_x11_init (MetaBarrierImplX11 *self) +{ +} diff --git a/src/backends/x11/meta-barrier-x11.h b/src/backends/x11/meta-barrier-x11.h new file mode 100644 index 000000000..3562d106f --- /dev/null +++ b/src/backends/x11/meta-barrier-x11.h @@ -0,0 +1,42 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2015 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +#ifndef META_BARRIER_X11_H +#define META_BARRIER_X11_H + +#include "backends/meta-barrier-private.h" + +G_BEGIN_DECLS + +#define META_TYPE_BARRIER_IMPL_X11 (meta_barrier_impl_x11_get_type ()) +G_DECLARE_FINAL_TYPE (MetaBarrierImplX11, + meta_barrier_impl_x11, + META, BARRIER_IMPL_X11, + MetaBarrierImpl) + +MetaBarrierImpl *meta_barrier_impl_x11_new (MetaBarrier *barrier); + +G_END_DECLS + +#endif /* META_BARRIER_X11_H1 */ diff --git a/src/backends/x11/meta-clutter-backend-x11.c b/src/backends/x11/meta-clutter-backend-x11.c new file mode 100644 index 000000000..d2f6136c9 --- /dev/null +++ b/src/backends/x11/meta-clutter-backend-x11.c @@ -0,0 +1,156 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +#include "config.h" + +#include <glib-object.h> + +#include "backends/meta-backend-private.h" +#include "backends/meta-renderer.h" +#include "backends/x11/meta-clutter-backend-x11.h" +#include "backends/x11/meta-keymap-x11.h" +#include "backends/x11/meta-seat-x11.h" +#include "backends/x11/meta-xkb-a11y-x11.h" +#include "backends/x11/nested/meta-stage-x11-nested.h" +#include "clutter/clutter-mutter.h" +#include "clutter/clutter.h" +#include "core/bell.h" +#include "meta/meta-backend.h" + +struct _MetaClutterBackendX11 +{ + ClutterBackendX11 parent; + MetaSeatX11 *core_seat; +}; + +G_DEFINE_TYPE (MetaClutterBackendX11, meta_clutter_backend_x11, + CLUTTER_TYPE_BACKEND_X11) + +static CoglRenderer * +meta_clutter_backend_x11_get_renderer (ClutterBackend *clutter_backend, + GError **error) +{ + MetaBackend *backend = meta_get_backend (); + MetaRenderer *renderer = meta_backend_get_renderer (backend); + + return meta_renderer_create_cogl_renderer (renderer); +} + +static ClutterStageWindow * +meta_clutter_backend_x11_create_stage (ClutterBackend *backend, + ClutterStage *wrapper, + GError **error) +{ + ClutterStageWindow *stage; + GType stage_type; + + if (meta_is_wayland_compositor ()) + stage_type = META_TYPE_STAGE_X11_NESTED; + else + stage_type = META_TYPE_STAGE_X11; + + stage = g_object_new (stage_type, + "backend", backend, + "wrapper", wrapper, + NULL); + return stage; +} + +static gboolean +meta_clutter_backend_x11_translate_event (ClutterBackend *backend, + gpointer native, + ClutterEvent *event) +{ + MetaClutterBackendX11 *backend_x11 = META_CLUTTER_BACKEND_X11 (backend); + MetaStageX11 *stage_x11; + ClutterBackendClass *clutter_backend_class; + + clutter_backend_class = + CLUTTER_BACKEND_CLASS (meta_clutter_backend_x11_parent_class); + if (clutter_backend_class->translate_event (backend, native, event)) + return TRUE; + + stage_x11 = META_STAGE_X11 (clutter_backend_get_stage_window (backend)); + if (meta_stage_x11_translate_event (stage_x11, native, event)) + return TRUE; + + if (meta_seat_x11_translate_event (backend_x11->core_seat, native, event)) + return TRUE; + + return FALSE; +} + +static void +meta_clutter_backend_x11_init_events (ClutterBackend *backend) +{ + MetaClutterBackendX11 *backend_x11 = META_CLUTTER_BACKEND_X11 (backend); + int event_base, first_event, first_error; + + if (XQueryExtension (clutter_x11_get_default_display (), + "XInputExtension", + &event_base, + &first_event, + &first_error)) + { + int major = 2; + int minor = 3; + + if (XIQueryVersion (clutter_x11_get_default_display (), + &major, &minor) != BadRequest) + { + backend_x11->core_seat = + meta_seat_x11_new (event_base, + META_VIRTUAL_CORE_POINTER_ID, + META_VIRTUAL_CORE_KEYBOARD_ID); + } + } + + if (!backend_x11->core_seat) + g_error ("No XInput 2.3 support"); +} + +static ClutterSeat * +meta_clutter_backend_x11_get_default_seat (ClutterBackend *backend) +{ + MetaClutterBackendX11 *backend_x11 = META_CLUTTER_BACKEND_X11 (backend); + + return CLUTTER_SEAT (backend_x11->core_seat); +} + +static void +meta_clutter_backend_x11_init (MetaClutterBackendX11 *clutter_backend_x11) +{ +} + +static void +meta_clutter_backend_x11_class_init (MetaClutterBackendX11Class *klass) +{ + ClutterBackendClass *clutter_backend_class = CLUTTER_BACKEND_CLASS (klass); + + clutter_backend_class->get_renderer = meta_clutter_backend_x11_get_renderer; + clutter_backend_class->create_stage = meta_clutter_backend_x11_create_stage; + clutter_backend_class->translate_event = meta_clutter_backend_x11_translate_event; + clutter_backend_class->init_events = meta_clutter_backend_x11_init_events; + clutter_backend_class->get_default_seat = meta_clutter_backend_x11_get_default_seat; +} diff --git a/src/backends/x11/meta-clutter-backend-x11.h b/src/backends/x11/meta-clutter-backend-x11.h new file mode 100644 index 000000000..4e811e424 --- /dev/null +++ b/src/backends/x11/meta-clutter-backend-x11.h @@ -0,0 +1,38 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +#ifndef META_CLUTTER_BACKEND_X11_H +#define META_CLUTTER_BACKEND_X11_H + +#include <glib-object.h> + +#include "clutter/clutter.h" +#include "clutter/x11/clutter-backend-x11.h" + +#define META_TYPE_CLUTTER_BACKEND_X11 (meta_clutter_backend_x11_get_type ()) +G_DECLARE_FINAL_TYPE (MetaClutterBackendX11, meta_clutter_backend_x11, + META, CLUTTER_BACKEND_X11, + ClutterBackendX11) + +#endif /* META_CLUTTER_BACKEND_X11_H */ diff --git a/src/backends/x11/meta-crtc-xrandr.c b/src/backends/x11/meta-crtc-xrandr.c new file mode 100644 index 000000000..8c875fc5e --- /dev/null +++ b/src/backends/x11/meta-crtc-xrandr.c @@ -0,0 +1,392 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001, 2002 Havoc Pennington + * Copyright (C) 2001, 2002 Havoc Pennington + * Copyright (C) 2002, 2003 Red Hat Inc. + * Some ICCCM manager selection code derived from fvwm2, + * Copyright (C) 2001 Dominik Vogt, Matthias Clasen, and fvwm2 team + * Copyright (C) 2003 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * Copyright (C) 2002, 2003 Red Hat Inc. + * Some ICCCM manager selection code derived from fvwm2, + * Copyright (C) 2001 Dominik Vogt, Matthias Clasen, and fvwm2 team + * Copyright (C) 2003 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * Copyright (C) 2013-2017 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "backends/x11/meta-crtc-xrandr.h" + +#include <X11/Xlib-xcb.h> +#include <X11/extensions/Xrender.h> +#include <stdlib.h> +#include <xcb/randr.h> + +#include "backends/meta-backend-private.h" +#include "backends/meta-crtc.h" +#include "backends/meta-output.h" +#include "backends/x11/meta-crtc-xrandr.h" +#include "backends/x11/meta-gpu-xrandr.h" +#include "backends/x11/meta-monitor-manager-xrandr.h" + +#define ALL_TRANSFORMS ((1 << (META_MONITOR_TRANSFORM_FLIPPED_270 + 1)) - 1) +#define DOUBLE_TO_FIXED(d) ((xcb_render_fixed_t) ((d) * 65536)) + +typedef struct _MetaCrtcXrandr +{ + MetaRectangle rect; + MetaMonitorTransform transform; + MetaCrtcMode *current_mode; +} MetaCrtcXrandr; + +gboolean +meta_crtc_xrandr_set_config (MetaCrtc *crtc, + xcb_randr_crtc_t xrandr_crtc, + xcb_timestamp_t timestamp, + int x, + int y, + xcb_randr_mode_t mode, + xcb_randr_rotation_t rotation, + xcb_randr_output_t *outputs, + int n_outputs, + xcb_timestamp_t *out_timestamp) +{ + MetaGpu *gpu = meta_crtc_get_gpu (crtc); + MetaGpuXrandr *gpu_xrandr = META_GPU_XRANDR (gpu); + MetaBackend *backend = meta_gpu_get_backend (gpu); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaMonitorManagerXrandr *monitor_manager_xrandr = + META_MONITOR_MANAGER_XRANDR (monitor_manager); + Display *xdisplay; + XRRScreenResources *resources; + xcb_connection_t *xcb_conn; + xcb_timestamp_t config_timestamp; + xcb_randr_set_crtc_config_cookie_t cookie; + xcb_randr_set_crtc_config_reply_t *reply; + xcb_generic_error_t *xcb_error = NULL; + + xdisplay = meta_monitor_manager_xrandr_get_xdisplay (monitor_manager_xrandr); + xcb_conn = XGetXCBConnection (xdisplay); + resources = meta_gpu_xrandr_get_resources (gpu_xrandr); + config_timestamp = resources->configTimestamp; + cookie = xcb_randr_set_crtc_config (xcb_conn, + xrandr_crtc, + timestamp, + config_timestamp, + x, y, + mode, + rotation, + n_outputs, + outputs); + reply = xcb_randr_set_crtc_config_reply (xcb_conn, + cookie, + &xcb_error); + if (xcb_error || !reply) + { + free (xcb_error); + free (reply); + return FALSE; + } + + *out_timestamp = reply->timestamp; + free (reply); + + + return TRUE; +} + +gboolean +meta_crtc_xrandr_set_scale (MetaCrtc *crtc, + xcb_randr_crtc_t xrandr_crtc, + float scale) +{ + MetaGpu *gpu = meta_crtc_get_gpu (crtc); + MetaBackend *backend = meta_gpu_get_backend (gpu); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaMonitorManagerXrandr *monitor_manager_xrandr = + META_MONITOR_MANAGER_XRANDR (monitor_manager); + Display *xdisplay; + const char *scale_filter; + xcb_connection_t *xcb_conn; + xcb_void_cookie_t transform_cookie; + xcb_generic_error_t *xcb_error = NULL; + xcb_render_transform_t transformation = { + DOUBLE_TO_FIXED (1), DOUBLE_TO_FIXED (0), DOUBLE_TO_FIXED (0), + DOUBLE_TO_FIXED (0), DOUBLE_TO_FIXED (1), DOUBLE_TO_FIXED (0), + DOUBLE_TO_FIXED (0), DOUBLE_TO_FIXED (0), DOUBLE_TO_FIXED (1) + }; + + if (!(meta_monitor_manager_get_capabilities (monitor_manager) & + META_MONITOR_MANAGER_CAPABILITY_NATIVE_OUTPUT_SCALING)) + return FALSE; + + xdisplay = meta_monitor_manager_xrandr_get_xdisplay (monitor_manager_xrandr); + xcb_conn = XGetXCBConnection (xdisplay); + + if (fabsf (scale - 1.0f) > 0.001) + { + scale_filter = FilterGood; + transformation.matrix11 = DOUBLE_TO_FIXED (1.0 / scale); + transformation.matrix22 = DOUBLE_TO_FIXED (1.0 / scale); + } + else + scale_filter = FilterFast; + + transform_cookie = + xcb_randr_set_crtc_transform_checked (xcb_conn, xrandr_crtc, transformation, + strlen (scale_filter), scale_filter, + 0, NULL); + + xcb_error = xcb_request_check (xcb_conn, transform_cookie); + if (xcb_error) + { + g_warning ("Impossible to set scaling on crtc %u to %f, error id %u", + xrandr_crtc, scale, xcb_error->error_code); + g_clear_pointer (&xcb_error, free); + + return FALSE; + } + + return TRUE; +} + +static MetaMonitorTransform +meta_monitor_transform_from_xrandr (Rotation rotation) +{ + static const MetaMonitorTransform y_reflected_map[4] = { + META_MONITOR_TRANSFORM_FLIPPED_180, + META_MONITOR_TRANSFORM_FLIPPED_90, + META_MONITOR_TRANSFORM_FLIPPED, + META_MONITOR_TRANSFORM_FLIPPED_270 + }; + MetaMonitorTransform ret; + + switch (rotation & 0x7F) + { + default: + case RR_Rotate_0: + ret = META_MONITOR_TRANSFORM_NORMAL; + break; + case RR_Rotate_90: + ret = META_MONITOR_TRANSFORM_90; + break; + case RR_Rotate_180: + ret = META_MONITOR_TRANSFORM_180; + break; + case RR_Rotate_270: + ret = META_MONITOR_TRANSFORM_270; + break; + } + + if (rotation & RR_Reflect_X) + return ret + 4; + else if (rotation & RR_Reflect_Y) + return y_reflected_map[ret]; + else + return ret; +} + +#define ALL_ROTATIONS (RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270) + +static MetaMonitorTransform +meta_monitor_transform_from_xrandr_all (Rotation rotation) +{ + unsigned ret; + + /* Handle the common cases first (none or all) */ + if (rotation == 0 || rotation == RR_Rotate_0) + return (1 << META_MONITOR_TRANSFORM_NORMAL); + + /* All rotations and one reflection -> all of them by composition */ + if ((rotation & ALL_ROTATIONS) && + ((rotation & RR_Reflect_X) || (rotation & RR_Reflect_Y))) + return ALL_TRANSFORMS; + + ret = 1 << META_MONITOR_TRANSFORM_NORMAL; + if (rotation & RR_Rotate_90) + ret |= 1 << META_MONITOR_TRANSFORM_90; + if (rotation & RR_Rotate_180) + ret |= 1 << META_MONITOR_TRANSFORM_180; + if (rotation & RR_Rotate_270) + ret |= 1 << META_MONITOR_TRANSFORM_270; + if (rotation & (RR_Rotate_0 | RR_Reflect_X)) + ret |= 1 << META_MONITOR_TRANSFORM_FLIPPED; + if (rotation & (RR_Rotate_90 | RR_Reflect_X)) + ret |= 1 << META_MONITOR_TRANSFORM_FLIPPED_90; + if (rotation & (RR_Rotate_180 | RR_Reflect_X)) + ret |= 1 << META_MONITOR_TRANSFORM_FLIPPED_180; + if (rotation & (RR_Rotate_270 | RR_Reflect_X)) + ret |= 1 << META_MONITOR_TRANSFORM_FLIPPED_270; + + return ret; +} + +gboolean +meta_crtc_xrandr_is_assignment_changed (MetaCrtc *crtc, + MetaCrtcInfo *crtc_info) +{ + MetaCrtcXrandr *crtc_xrandr = crtc->driver_private; + unsigned int i; + + if (crtc_xrandr->current_mode != crtc_info->mode) + return TRUE; + + if (crtc_xrandr->rect.x != (int) roundf (crtc_info->layout.origin.x)) + return TRUE; + + if (crtc_xrandr->rect.y != (int) roundf (crtc_info->layout.origin.y)) + return TRUE; + + if (crtc_xrandr->transform != crtc_info->transform) + return TRUE; + + for (i = 0; i < crtc_info->outputs->len; i++) + { + MetaOutput *output = ((MetaOutput**) crtc_info->outputs->pdata)[i]; + MetaCrtc *assigned_crtc; + + assigned_crtc = meta_output_get_assigned_crtc (output); + if (assigned_crtc != crtc) + return TRUE; + } + + return FALSE; +} + +MetaCrtcMode * +meta_crtc_xrandr_get_current_mode (MetaCrtc *crtc) +{ + MetaCrtcXrandr *crtc_xrandr = crtc->driver_private; + + return crtc_xrandr->current_mode; +} + +static void +meta_crtc_destroy_notify (MetaCrtc *crtc) +{ + g_free (crtc->driver_private); +} + +static float +meta_monitor_scale_from_transformation (XRRCrtcTransformAttributes *transformation) +{ + XTransform *xt; + float scale; + + if (!transformation) + return 1.0f; + + xt = &transformation->currentTransform; + + if (xt->matrix[0][0] == xt->matrix[1][1]) + scale = XFixedToDouble (xt->matrix[0][0]); + else + scale = XFixedToDouble (xt->matrix[0][0] + xt->matrix[1][1]) / 2.0; + + return 1.0f / scale; +} + +MetaCrtc * +meta_create_xrandr_crtc (MetaGpuXrandr *gpu_xrandr, + XRRCrtcInfo *xrandr_crtc, + RRCrtc crtc_id, + XRRScreenResources *resources, + XRRCrtcTransformAttributes *transform_attributes, + float scale_multiplier) +{ + MetaGpu *gpu = META_GPU (gpu_xrandr); + MetaBackend *backend = meta_gpu_get_backend (gpu); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaMonitorManagerXrandr *monitor_manager_xrandr = + META_MONITOR_MANAGER_XRANDR (monitor_manager); + Display *xdisplay = + meta_monitor_manager_xrandr_get_xdisplay (monitor_manager_xrandr); + MetaCrtc *crtc; + MetaCrtcXrandr *crtc_xrandr; + XRRPanning *panning; + unsigned int i; + GList *modes; + + crtc = g_object_new (META_TYPE_CRTC, NULL); + + crtc_xrandr = g_new0 (MetaCrtcXrandr, 1); + crtc_xrandr->transform = + meta_monitor_transform_from_xrandr (xrandr_crtc->rotation); + + crtc->driver_private = crtc_xrandr; + crtc->driver_notify = (GDestroyNotify) meta_crtc_destroy_notify; + crtc->gpu = META_GPU (gpu_xrandr); + crtc->crtc_id = crtc_id; + + panning = XRRGetPanning (xdisplay, resources, crtc_id); + if (panning && panning->width > 0 && panning->height > 0) + { + crtc_xrandr->rect = (MetaRectangle) { + .x = panning->left, + .y = panning->top, + .width = panning->width, + .height = panning->height, + }; + } + else + { + crtc_xrandr->rect = (MetaRectangle) { + .x = xrandr_crtc->x, + .y = xrandr_crtc->y, + .width = xrandr_crtc->width, + .height = xrandr_crtc->height, + }; + } + + crtc->is_dirty = FALSE; + crtc->all_transforms = + meta_monitor_transform_from_xrandr_all (xrandr_crtc->rotations); + crtc->scale = meta_monitor_scale_from_transformation (transform_attributes); + + if (scale_multiplier > 0.0f) + crtc->scale *= scale_multiplier; + + modes = meta_gpu_get_modes (crtc->gpu); + for (i = 0; i < (unsigned int) resources->nmode; i++) + { + if (resources->modes[i].id == xrandr_crtc->mode) + { + crtc_xrandr->current_mode = g_list_nth_data (modes, i); + break; + } + } + + if (crtc_xrandr->current_mode) + { + meta_crtc_set_config (crtc, + &GRAPHENE_RECT_INIT (crtc_xrandr->rect.x, + crtc_xrandr->rect.y, + crtc_xrandr->rect.width, + crtc_xrandr->rect.height), + crtc_xrandr->current_mode, + crtc_xrandr->transform); + } + + return crtc; +} diff --git a/src/backends/x11/meta-crtc-xrandr.h b/src/backends/x11/meta-crtc-xrandr.h new file mode 100644 index 000000000..c96800406 --- /dev/null +++ b/src/backends/x11/meta-crtc-xrandr.h @@ -0,0 +1,58 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_CRTC_XRANDR_H +#define META_CRTC_XRANDR_H + +#include <X11/extensions/Xrandr.h> +#include <xcb/randr.h> + +#include "backends/meta-crtc.h" +#include "backends/x11/meta-gpu-xrandr.h" + +gboolean meta_crtc_xrandr_set_config (MetaCrtc *crtc, + xcb_randr_crtc_t xrandr_crtc, + xcb_timestamp_t timestamp, + int x, + int y, + xcb_randr_mode_t mode, + xcb_randr_rotation_t rotation, + xcb_randr_output_t *outputs, + int n_outputs, + xcb_timestamp_t *out_timestamp); + +gboolean meta_crtc_xrandr_is_assignment_changed (MetaCrtc *crtc, + MetaCrtcInfo *crtc_info); + +MetaCrtcMode * meta_crtc_xrandr_get_current_mode (MetaCrtc *crtc); + +gboolean meta_crtc_xrandr_set_scale (MetaCrtc *crtc, + xcb_randr_crtc_t xrandr_crtc, + float scale); + +MetaCrtc * meta_create_xrandr_crtc (MetaGpuXrandr *gpu_xrandr, + XRRCrtcInfo *xrandr_crtc, + RRCrtc crtc_id, + XRRScreenResources *resources, + XRRCrtcTransformAttributes *transform_attributes, + float scale_multiplier); + +#endif /* META_CRTC_XRANDR_H */ diff --git a/src/backends/x11/meta-cursor-renderer-x11.c b/src/backends/x11/meta-cursor-renderer-x11.c new file mode 100644 index 000000000..1f198c130 --- /dev/null +++ b/src/backends/x11/meta-cursor-renderer-x11.c @@ -0,0 +1,114 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jasper St. Pierre <jstpierre@mecheye.net> + */ + +#include "config.h" + +#include "backends/x11/meta-cursor-renderer-x11.h" + +#include <X11/extensions/Xfixes.h> + +#include "backends/meta-cursor-sprite-xcursor.h" +#include "backends/meta-stage-private.h" +#include "backends/x11/meta-backend-x11.h" + +struct _MetaCursorRendererX11Private +{ + gboolean server_cursor_visible; +}; +typedef struct _MetaCursorRendererX11Private MetaCursorRendererX11Private; + +G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorRendererX11, meta_cursor_renderer_x11, META_TYPE_CURSOR_RENDERER); + +static gboolean +meta_cursor_renderer_x11_update_cursor (MetaCursorRenderer *renderer, + MetaCursorSprite *cursor_sprite) +{ + MetaCursorRendererX11 *x11 = META_CURSOR_RENDERER_X11 (renderer); + MetaCursorRendererX11Private *priv = meta_cursor_renderer_x11_get_instance_private (x11); + + MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ()); + Window xwindow = meta_backend_x11_get_xwindow (backend); + Display *xdisplay = meta_backend_x11_get_xdisplay (backend); + + if (xwindow == None) + { + if (cursor_sprite) + meta_cursor_sprite_realize_texture (cursor_sprite); + return FALSE; + } + + gboolean has_server_cursor = FALSE; + + if (cursor_sprite && META_IS_CURSOR_SPRITE_XCURSOR (cursor_sprite)) + { + MetaCursorSpriteXcursor *sprite_xcursor = + META_CURSOR_SPRITE_XCURSOR (cursor_sprite); + MetaCursor cursor; + + cursor = meta_cursor_sprite_xcursor_get_cursor (sprite_xcursor); + if (cursor != META_CURSOR_NONE) + { + Cursor xcursor; + + xcursor = meta_create_x_cursor (xdisplay, cursor); + XDefineCursor (xdisplay, xwindow, xcursor); + XFlush (xdisplay); + XFreeCursor (xdisplay, xcursor); + + has_server_cursor = TRUE; + } + } + + if (has_server_cursor != priv->server_cursor_visible) + { + if (has_server_cursor) + XFixesShowCursor (xdisplay, xwindow); + else + XFixesHideCursor (xdisplay, xwindow); + + priv->server_cursor_visible = has_server_cursor; + } + + if (!priv->server_cursor_visible && cursor_sprite) + meta_cursor_sprite_realize_texture (cursor_sprite); + + return priv->server_cursor_visible; +} + +static void +meta_cursor_renderer_x11_class_init (MetaCursorRendererX11Class *klass) +{ + MetaCursorRendererClass *renderer_class = META_CURSOR_RENDERER_CLASS (klass); + + renderer_class->update_cursor = meta_cursor_renderer_x11_update_cursor; +} + +static void +meta_cursor_renderer_x11_init (MetaCursorRendererX11 *x11) +{ + MetaCursorRendererX11Private *priv = meta_cursor_renderer_x11_get_instance_private (x11); + + /* XFixes has no way to retrieve the current cursor visibility. */ + priv->server_cursor_visible = TRUE; +} diff --git a/src/backends/x11/meta-cursor-renderer-x11.h b/src/backends/x11/meta-cursor-renderer-x11.h new file mode 100644 index 000000000..b52834375 --- /dev/null +++ b/src/backends/x11/meta-cursor-renderer-x11.h @@ -0,0 +1,52 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jasper St. Pierre <jstpierre@mecheye.net> + */ + +#ifndef META_CURSOR_RENDERER_X11_H +#define META_CURSOR_RENDERER_X11_H + +#include "backends/meta-cursor-renderer.h" + +#define META_TYPE_CURSOR_RENDERER_X11 (meta_cursor_renderer_x11_get_type ()) +#define META_CURSOR_RENDERER_X11(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_CURSOR_RENDERER_X11, MetaCursorRendererX11)) +#define META_CURSOR_RENDERER_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_CURSOR_RENDERER_X11, MetaCursorRendererX11Class)) +#define META_IS_CURSOR_RENDERER_X11(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_CURSOR_RENDERER_X11)) +#define META_IS_CURSOR_RENDERER_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_CURSOR_RENDERER_X11)) +#define META_CURSOR_RENDERER_X11_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_CURSOR_RENDERER_X11, MetaCursorRendererX11Class)) + +typedef struct _MetaCursorRendererX11 MetaCursorRendererX11; +typedef struct _MetaCursorRendererX11Class MetaCursorRendererX11Class; + +struct _MetaCursorRendererX11 +{ + MetaCursorRenderer parent; +}; + +struct _MetaCursorRendererX11Class +{ + MetaCursorRendererClass parent_class; +}; + +GType meta_cursor_renderer_x11_get_type (void) G_GNUC_CONST; + +#endif /* META_CURSOR_RENDERER_X11_H */ diff --git a/src/backends/x11/meta-event-x11.c b/src/backends/x11/meta-event-x11.c new file mode 100644 index 000000000..19da2235b --- /dev/null +++ b/src/backends/x11/meta-event-x11.c @@ -0,0 +1,173 @@ +/* Copyright (C) 2006, 2007, 2008 OpenedHand Ltd + * Copyright (C) 2009, 2010 Intel Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * + * + * Authored by: + * Matthew Allum <mallum@openedhand.com> + * Emmanuele Bassi <ebassi@linux.intel.com> + */ + +#include "config.h" + +#include <glib.h> +#include <string.h> + +#include "backends/x11/meta-event-x11.h" +#include "clutter/clutter-mutter.h" +#include "clutter/x11/clutter-x11.h" + +MetaEventX11 * +meta_event_x11_new (void) +{ + return g_slice_new0 (MetaEventX11); +} + +MetaEventX11 * +meta_event_x11_copy (MetaEventX11 *event_x11) +{ + if (event_x11 != NULL) + return g_slice_dup (MetaEventX11, event_x11); + + return NULL; +} + +void +meta_event_x11_free (MetaEventX11 *event_x11) +{ + if (event_x11 != NULL) + g_slice_free (MetaEventX11, event_x11); +} + +/** + * meta_x11_handle_event: + * @xevent: pointer to XEvent structure + * + * This function processes a single X event; it can be used to hook + * into external X11 event processing (for example, a GDK filter + * function). + * + * Return value: #ClutterX11FilterReturn. %CLUTTER_X11_FILTER_REMOVE + * indicates that Clutter has internally handled the event and the + * caller should do no further processing. %CLUTTER_X11_FILTER_CONTINUE + * indicates that Clutter is either not interested in the event, + * or has used the event to update internal state without taking + * any exclusive action. %CLUTTER_X11_FILTER_TRANSLATE will not + * occur. + * + * Since: 0.8 + */ +ClutterX11FilterReturn +meta_x11_handle_event (XEvent *xevent) +{ + ClutterX11FilterReturn result; + ClutterBackend *backend; + ClutterEvent *event; + gint spin = 1; + ClutterBackendX11 *backend_x11; + Display *xdisplay; + gboolean allocated_event; + + /* The return values here are someone approximate; we return + * CLUTTER_X11_FILTER_REMOVE if a clutter event is + * generated for the event. This mostly, but not entirely, + * corresponds to whether other event processing should be + * excluded. As long as the stage window is not shared with another + * toolkit it should be safe, and never return + * %CLUTTER_X11_FILTER_REMOVE when more processing is needed. + */ + + result = CLUTTER_X11_FILTER_CONTINUE; + + _clutter_threads_acquire_lock (); + + backend = clutter_get_default_backend (); + + event = clutter_event_new (CLUTTER_NOTHING); + + backend_x11 = CLUTTER_BACKEND_X11 (backend); + xdisplay = backend_x11->xdpy; + + allocated_event = XGetEventData (xdisplay, &xevent->xcookie); + + if (_clutter_backend_translate_event (backend, xevent, event)) + { + _clutter_event_push (event, FALSE); + + result = CLUTTER_X11_FILTER_REMOVE; + } + else + { + clutter_event_free (event); + goto out; + } + + /* + * Motion events can generate synthetic enter and leave events, so if we + * are processing a motion event, we need to spin the event loop at least + * two extra times to pump the enter/leave events through (otherwise they + * just get pushed down the queue and never processed). + */ + if (event->type == CLUTTER_MOTION) + spin += 2; + + while (spin > 0 && (event = clutter_event_get ())) + { + /* forward the event into clutter for emission etc. */ + _clutter_stage_queue_event (event->any.stage, event, FALSE); + --spin; + } + +out: + if (allocated_event) + XFreeEventData (xdisplay, &xevent->xcookie); + + _clutter_threads_release_lock (); + + return result; +} + +Time +meta_x11_get_current_event_time (void) +{ + ClutterBackend *backend = clutter_get_default_backend (); + + return CLUTTER_BACKEND_X11 (backend)->last_event_time; +} + +gint +meta_x11_event_get_key_group (const ClutterEvent *event) +{ + MetaEventX11 *event_x11; + + g_return_val_if_fail (event != NULL, 0); + g_return_val_if_fail (event->type == CLUTTER_KEY_PRESS || + event->type == CLUTTER_KEY_RELEASE, 0); + + event_x11 = _clutter_event_get_platform_data (event); + if (event_x11 == NULL) + return 0; + + return event_x11->key_group; +} + +guint +meta_x11_event_sequence_get_touch_detail (const ClutterEventSequence *sequence) +{ + g_return_val_if_fail (sequence != NULL, 0); + + return GPOINTER_TO_UINT (sequence); +} diff --git a/src/backends/x11/meta-event-x11.h b/src/backends/x11/meta-event-x11.h new file mode 100644 index 000000000..2295ce63a --- /dev/null +++ b/src/backends/x11/meta-event-x11.h @@ -0,0 +1,55 @@ +/* Copyright (C) 2006, 2007, 2008 OpenedHand Ltd + * Copyright (C) 2009, 2010 Intel Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * + * + * Authored by: + * Matthew Allum <mallum@openedhand.com> + * Emmanuele Bassi <ebassi@linux.intel.com> + */ + +#ifndef META_EVENT_X11_H +#define META_EVENT_X11_H + +#include <X11/Xlib.h> + +#include "clutter/x11/clutter-x11.h" + +typedef struct _MetaEventX11 MetaEventX11; + +struct _MetaEventX11 +{ + /* additional fields for Key events */ + gint key_group; + + guint key_is_modifier : 1; + guint num_lock_set : 1; + guint caps_lock_set : 1; +}; + +MetaEventX11 * meta_event_x11_new (void); +MetaEventX11 * meta_event_x11_copy (MetaEventX11 *event_x11); +void meta_event_x11_free (MetaEventX11 *event_x11); + +Time meta_x11_get_current_event_time (void); + +gint meta_x11_event_get_key_group (const ClutterEvent *event); + +guint meta_x11_event_sequence_get_touch_detail (const ClutterEventSequence *sequence); + +ClutterX11FilterReturn meta_x11_handle_event (XEvent *xevent); + +#endif /* META_EVENT_X11_H */ diff --git a/src/backends/x11/meta-gpu-xrandr.c b/src/backends/x11/meta-gpu-xrandr.c new file mode 100644 index 000000000..65a3c30f7 --- /dev/null +++ b/src/backends/x11/meta-gpu-xrandr.c @@ -0,0 +1,366 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001, 2002 Havoc Pennington + * Copyright (C) 2002, 2003 Red Hat Inc. + * Some ICCCM manager selection code derived from fvwm2, + * Copyright (C) 2001 Dominik Vogt, Matthias Clasen, and fvwm2 team + * Copyright (C) 2003 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * Copyright (C) 2013-2017 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include "backends/x11/meta-gpu-xrandr.h" + +#include <string.h> +#include <X11/extensions/dpms.h> +#include <X11/Xlibint.h> + +#include "backends/meta-backend-private.h" +#include "backends/meta-output.h" +#include "backends/x11/meta-backend-x11.h" +#include "backends/x11/meta-crtc-xrandr.h" +#include "backends/x11/meta-monitor-manager-xrandr.h" +#include "backends/x11/meta-output-xrandr.h" + +struct _MetaGpuXrandr +{ + MetaGpu parent; + + XRRScreenResources *resources; + + int min_screen_width; + int min_screen_height; + int max_screen_width; + int max_screen_height; +}; + +G_DEFINE_TYPE (MetaGpuXrandr, meta_gpu_xrandr, META_TYPE_GPU) + +XRRScreenResources * +meta_gpu_xrandr_get_resources (MetaGpuXrandr *gpu_xrandr) +{ + return gpu_xrandr->resources; +} + +void +meta_gpu_xrandr_get_min_screen_size (MetaGpuXrandr *gpu_xrandr, + int *min_width, + int *min_height) +{ + *min_width = gpu_xrandr->min_screen_width; + *min_height = gpu_xrandr->min_screen_height; +} + +void +meta_gpu_xrandr_get_max_screen_size (MetaGpuXrandr *gpu_xrandr, + int *max_width, + int *max_height) +{ + *max_width = gpu_xrandr->max_screen_width; + *max_height = gpu_xrandr->max_screen_height; +} + +static int +compare_outputs (const void *one, + const void *two) +{ + const MetaOutput *o_one = one, *o_two = two; + + return strcmp (o_one->name, o_two->name); +} + +static char * +get_xmode_name (XRRModeInfo *xmode) +{ + int width = xmode->width; + int height = xmode->height; + + return g_strdup_printf ("%dx%d", width, height); +} + +static int +get_current_dpi_scale (MetaMonitorManagerXrandr *manager_xrandr, + MetaGpuXrandr *gpu_xrandr) +{ + Atom actual; + int result, format; + unsigned long n, left; + g_autofree unsigned char *data = NULL; + g_auto(GStrv) resources = NULL; + Display *dpy; + int i; + + if (gpu_xrandr->resources->timestamp == + meta_monitor_manager_xrandr_get_config_timestamp (manager_xrandr)) + { + MetaMonitorManager *monitor_manager = META_MONITOR_MANAGER (manager_xrandr); + MetaBackend *backend = meta_monitor_manager_get_backend (monitor_manager); + MetaSettings *settings = meta_backend_get_settings (backend); + + return meta_settings_get_ui_scaling_factor (settings); + } + + dpy = meta_monitor_manager_xrandr_get_xdisplay (manager_xrandr); + result = XGetWindowProperty (dpy, DefaultRootWindow (dpy), + XA_RESOURCE_MANAGER, 0L, 65536, False, + XA_STRING, &actual, &format, + &n, &left, &data); + + if (result != Success || !data || actual != XA_STRING) + return 1; + + resources = g_strsplit ((char *) data, "\n", -1); + + for (i = 0; resources && resources[i]; ++i) + { + if (g_str_has_prefix (resources[i], "Xft.dpi:")) + { + g_auto(GStrv) res = g_strsplit (resources[i], "\t", 2); + + if (res && res[0] && res[1]) + { + guint64 dpi; + dpi = g_ascii_strtoull (res[1], NULL, 10); + + if (dpi > 0 && dpi < 96 * 10) + return MAX (1, roundf ((float) dpi / 96.0f)); + } + } + } + + return 1; +} + +static gboolean +meta_gpu_xrandr_read_current (MetaGpu *gpu, + GError **error) +{ + MetaGpuXrandr *gpu_xrandr = META_GPU_XRANDR (gpu); + MetaBackend *backend = meta_gpu_get_backend (gpu); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaMonitorManagerXrandr *monitor_manager_xrandr = + META_MONITOR_MANAGER_XRANDR (monitor_manager); + Display *xdisplay = + meta_monitor_manager_xrandr_get_xdisplay (monitor_manager_xrandr); + XRRScreenResources *resources; + RROutput primary_output; + unsigned int i, j; + GList *l; + Screen *screen; + GList *outputs = NULL; + GList *modes = NULL; + GList *crtcs = NULL; + gboolean has_transform; + int dpi_scale = 1; + + if (gpu_xrandr->resources) + XRRFreeScreenResources (gpu_xrandr->resources); + gpu_xrandr->resources = NULL; + + XRRGetScreenSizeRange (xdisplay, DefaultRootWindow (xdisplay), + &gpu_xrandr->min_screen_width, + &gpu_xrandr->min_screen_height, + &gpu_xrandr->max_screen_width, + &gpu_xrandr->max_screen_height); + + screen = ScreenOfDisplay (xdisplay, DefaultScreen (xdisplay)); + /* This is updated because we called XRRUpdateConfiguration. */ + monitor_manager->screen_width = WidthOfScreen (screen); + monitor_manager->screen_height = HeightOfScreen (screen); + + resources = XRRGetScreenResourcesCurrent (xdisplay, + DefaultRootWindow (xdisplay)); + if (!resources) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Failed to retrieve Xrandr screen resources"); + return FALSE; + } + + gpu_xrandr->resources = resources; + + outputs = NULL; + modes = NULL; + crtcs = NULL; + + for (i = 0; i < (unsigned)resources->nmode; i++) + { + XRRModeInfo *xmode = &resources->modes[i]; + MetaCrtcMode *mode; + + mode = g_object_new (META_TYPE_CRTC_MODE, NULL); + + mode->mode_id = xmode->id; + mode->width = xmode->width; + mode->height = xmode->height; + mode->refresh_rate = (xmode->dotClock / + ((float)xmode->hTotal * xmode->vTotal)); + mode->flags = xmode->modeFlags; + mode->name = get_xmode_name (xmode); + + modes = g_list_append (modes, mode); + } + meta_gpu_take_modes (gpu, modes); + + has_transform = !!(meta_monitor_manager_get_capabilities (monitor_manager) & + META_MONITOR_MANAGER_CAPABILITY_NATIVE_OUTPUT_SCALING); + + if (has_transform && + meta_monitor_manager_get_default_layout_mode (monitor_manager) == + META_LOGICAL_MONITOR_LAYOUT_MODE_GLOBAL_UI_LOGICAL) + dpi_scale = get_current_dpi_scale (monitor_manager_xrandr, gpu_xrandr); + + for (i = 0; i < (unsigned)resources->ncrtc; i++) + { + XRRCrtcInfo *xrandr_crtc; + XRRCrtcTransformAttributes *transform_attributes; + RRCrtc crtc_id; + MetaCrtc *crtc; + + crtc_id = resources->crtcs[i]; + xrandr_crtc = XRRGetCrtcInfo (xdisplay, + resources, crtc_id); + if (!has_transform || + !XRRGetCrtcTransform (xdisplay, crtc_id, &transform_attributes)) + transform_attributes = NULL; + + crtc = meta_create_xrandr_crtc (gpu_xrandr, + xrandr_crtc, crtc_id, resources, + transform_attributes, dpi_scale); + XFree (transform_attributes); + XRRFreeCrtcInfo (xrandr_crtc); + + crtcs = g_list_append (crtcs, crtc); + } + + meta_gpu_take_crtcs (gpu, crtcs); + + if (has_transform && dpi_scale == 1 && + meta_monitor_manager_get_default_layout_mode (monitor_manager) == + META_LOGICAL_MONITOR_LAYOUT_MODE_GLOBAL_UI_LOGICAL) + { + dpi_scale = + ceilf (meta_monitor_manager_get_maximum_crtc_scale (monitor_manager)); + + if (dpi_scale > 1) + { + for (l = crtcs; l; l = l->next) + { + MetaCrtc *crtc = l->data; + + crtc->scale *= dpi_scale; + } + } + } + + primary_output = XRRGetOutputPrimary (xdisplay, + DefaultRootWindow (xdisplay)); + + for (i = 0; i < (unsigned)resources->noutput; i++) + { + RROutput output_id; + XRROutputInfo *xrandr_output; + + output_id = resources->outputs[i]; + xrandr_output = XRRGetOutputInfo (xdisplay, + resources, output_id); + if (!xrandr_output) + continue; + + if (xrandr_output->connection != RR_Disconnected) + { + MetaOutput *output; + + output = meta_create_xrandr_output (gpu_xrandr, + xrandr_output, + output_id, + primary_output); + if (output) + outputs = g_list_prepend (outputs, output); + } + + XRRFreeOutputInfo (xrandr_output); + } + + /* Sort the outputs for easier handling in MetaMonitorConfig */ + outputs = g_list_sort (outputs, compare_outputs); + + meta_gpu_take_outputs (gpu, outputs); + + /* Now fix the clones */ + for (l = outputs; l; l = l->next) + { + MetaOutput *output = l->data; + GList *k; + + for (j = 0; j < output->n_possible_clones; j++) + { + RROutput clone = GPOINTER_TO_INT (output->possible_clones[j]); + + for (k = outputs; k; k = k->next) + { + MetaOutput *possible_clone = k->data; + + if (clone == (XID) possible_clone->winsys_id) + { + output->possible_clones[j] = possible_clone; + break; + } + } + } + } + + return TRUE; +} + +MetaGpuXrandr * +meta_gpu_xrandr_new (MetaBackendX11 *backend_x11) +{ + return g_object_new (META_TYPE_GPU_XRANDR, + "backend", backend_x11, + NULL); +} + +static void +meta_gpu_xrandr_finalize (GObject *object) +{ + MetaGpuXrandr *gpu_xrandr = META_GPU_XRANDR (object); + + g_clear_pointer (&gpu_xrandr->resources, + XRRFreeScreenResources); + + G_OBJECT_CLASS (meta_gpu_xrandr_parent_class)->finalize (object); +} + +static void +meta_gpu_xrandr_init (MetaGpuXrandr *gpu_xrandr) +{ +} + +static void +meta_gpu_xrandr_class_init (MetaGpuXrandrClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MetaGpuClass *gpu_class = META_GPU_CLASS (klass); + + object_class->finalize = meta_gpu_xrandr_finalize; + + gpu_class->read_current = meta_gpu_xrandr_read_current; +} diff --git a/src/backends/x11/meta-gpu-xrandr.h b/src/backends/x11/meta-gpu-xrandr.h new file mode 100644 index 000000000..a1f3b48f3 --- /dev/null +++ b/src/backends/x11/meta-gpu-xrandr.h @@ -0,0 +1,46 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_GPU_XRANDR_H +#define META_GPU_XRANDR_H + +#include <glib-object.h> +#include <X11/extensions/Xrandr.h> + +#include "backends/meta-gpu.h" +#include "backends/x11/meta-backend-x11.h" + +#define META_TYPE_GPU_XRANDR (meta_gpu_xrandr_get_type ()) +G_DECLARE_FINAL_TYPE (MetaGpuXrandr, meta_gpu_xrandr, META, GPU_XRANDR, MetaGpu) + +XRRScreenResources * meta_gpu_xrandr_get_resources (MetaGpuXrandr *gpu_xrandr); + +void meta_gpu_xrandr_get_min_screen_size (MetaGpuXrandr *gpu_xrandr, + int *min_width, + int *min_height); + +void meta_gpu_xrandr_get_max_screen_size (MetaGpuXrandr *gpu_xrandr, + int *max_width, + int *max_height); + +MetaGpuXrandr * meta_gpu_xrandr_new (MetaBackendX11 *backend_x11); + +#endif /* META_GPU_XRANDR_H */ diff --git a/clutter/clutter/x11/clutter-input-device-tool-xi2.c b/src/backends/x11/meta-input-device-tool-x11.c similarity index 62% rename from clutter/clutter/x11/clutter-input-device-tool-xi2.c rename to src/backends/x11/meta-input-device-tool-x11.c index 396b84736..0632fea5a 100644 --- a/clutter/clutter/x11/clutter-input-device-tool-xi2.c +++ b/src/backends/x11/meta-input-device-tool-x11.c @@ -1,8 +1,4 @@ /* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * * Copyright © 2016 Red Hat * * This library is free software; you can redistribute it and/or @@ -21,30 +17,28 @@ * Author: Carlos Garnacho <carlosg@gnome.org> */ -#ifdef HAVE_CONFIG_H -#include "clutter-build-config.h" -#endif +#include "config.h" -#include "clutter-input-device-tool-xi2.h" +#include "meta-input-device-tool-x11.h" -G_DEFINE_TYPE (ClutterInputDeviceToolXI2, clutter_input_device_tool_xi2, +G_DEFINE_TYPE (MetaInputDeviceToolX11, meta_input_device_tool_x11, CLUTTER_TYPE_INPUT_DEVICE_TOOL) static void -clutter_input_device_tool_xi2_class_init (ClutterInputDeviceToolXI2Class *klass) +meta_input_device_tool_x11_class_init (MetaInputDeviceToolX11Class *klass) { } static void -clutter_input_device_tool_xi2_init (ClutterInputDeviceToolXI2 *tool) +meta_input_device_tool_x11_init (MetaInputDeviceToolX11 *tool) { } ClutterInputDeviceTool * -clutter_input_device_tool_xi2_new (guint serial, - ClutterInputDeviceToolType type) +meta_input_device_tool_x11_new (guint serial, + ClutterInputDeviceToolType type) { - return g_object_new (CLUTTER_TYPE_INPUT_DEVICE_TOOL_XI2, + return g_object_new (META_TYPE_INPUT_DEVICE_TOOL_X11, "type", type, "serial", serial, NULL); diff --git a/src/backends/x11/meta-input-device-tool-x11.h b/src/backends/x11/meta-input-device-tool-x11.h new file mode 100644 index 000000000..e52803da9 --- /dev/null +++ b/src/backends/x11/meta-input-device-tool-x11.h @@ -0,0 +1,51 @@ +/* + * Copyright © 2016 Red Hat + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef META_INPUT_DEVICE_TOOL_X11_H +#define META_INPUT_DEVICE_TOOL_X11_H + +#include "clutter/clutter.h" + +#define META_TYPE_INPUT_DEVICE_TOOL_X11 (meta_input_device_tool_x11_get_type ()) + +#define META_INPUT_DEVICE_TOOL_X11(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), META_TYPE_INPUT_DEVICE_TOOL_X11, MetaInputDeviceToolX11)) +#define META_IS_INPUT_DEVICE_TOOL_X11(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), META_TYPE_INPUT_DEVICE_TOOL_X11)) +#define META_INPUT_DEVICE_TOOL_X11_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), META_TYPE_INPUT_DEVICE_TOOL_X11, MetaInputDeviceToolX11Class)) +#define META_IS_INPUT_DEVICE_TOOL_X11_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), META_TYPE_INPUT_DEVICE_TOOL_X1)) +#define META_INPUT_DEVICE_TOOL_X11_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), META_TYPE_INPUT_DEVICE_TOOL_X11, MetaInputDeviceToolX11Class)) + +typedef struct _MetaInputDeviceToolX11 MetaInputDeviceToolX11; +typedef struct _MetaInputDeviceToolX11Class MetaInputDeviceToolX11Class; + +struct _MetaInputDeviceToolX11 +{ + ClutterInputDeviceTool parent_instance; +}; + +struct _MetaInputDeviceToolX11Class +{ + ClutterInputDeviceToolClass parent_class; +}; + +GType meta_input_device_tool_x11_get_type (void) G_GNUC_CONST; + +ClutterInputDeviceTool * meta_input_device_tool_x11_new (guint serial, + ClutterInputDeviceToolType type); + +#endif /* META_INPUT_DEVICE_TOOL_X11_H */ diff --git a/src/backends/x11/meta-input-device-x11.c b/src/backends/x11/meta-input-device-x11.c new file mode 100644 index 000000000..6e41ffdaf --- /dev/null +++ b/src/backends/x11/meta-input-device-x11.c @@ -0,0 +1,500 @@ +/* + * Copyright © 2011 Intel Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Author: Emmanuele Bassi <ebassi@linux.intel.com> + */ + +#include "config.h" + +#include <X11/extensions/XInput2.h> + +#include "clutter/clutter-mutter.h" +#include "clutter/x11/clutter-x11.h" +#include "backends/x11/meta-input-device-x11.h" + +struct _MetaInputDeviceX11 +{ + ClutterInputDevice device; + + int32_t device_id; + ClutterInputDeviceTool *current_tool; + + int inhibit_pointer_query_timer; + gboolean query_status; + float current_x; + float current_y; + +#ifdef HAVE_LIBWACOM + GArray *group_modes; +#endif +}; + +struct _MetaInputDeviceX11Class +{ + ClutterInputDeviceClass device_class; +}; + +#define N_BUTTONS 5 + +G_DEFINE_TYPE (MetaInputDeviceX11, + meta_input_device_x11, + META_TYPE_INPUT_DEVICE) + +static void +meta_input_device_x11_constructed (GObject *object) +{ + MetaInputDeviceX11 *device_xi2 = META_INPUT_DEVICE_X11 (object); + + g_object_get (object, "id", &device_xi2->device_id, NULL); + + if (G_OBJECT_CLASS (meta_input_device_x11_parent_class)->constructed) + G_OBJECT_CLASS (meta_input_device_x11_parent_class)->constructed (object); + +#ifdef HAVE_LIBWACOM + if (clutter_input_device_get_device_type (CLUTTER_INPUT_DEVICE (object)) == CLUTTER_PAD_DEVICE) + { + device_xi2->group_modes = g_array_new (FALSE, TRUE, sizeof (uint32_t)); + g_array_set_size (device_xi2->group_modes, + clutter_input_device_get_n_mode_groups (CLUTTER_INPUT_DEVICE (object))); + } +#endif +} + +static gboolean +meta_input_device_x11_keycode_to_evdev (ClutterInputDevice *device, + uint32_t hardware_keycode, + uint32_t *evdev_keycode) +{ + /* When using evdev under X11 the hardware keycodes are the evdev + keycodes plus 8. I haven't been able to find any documentation to + know what the +8 is for. FIXME: This should probably verify that + X server is using evdev. */ + *evdev_keycode = hardware_keycode - 8; + + return TRUE; +} + +static gboolean +meta_input_device_x11_is_grouped (ClutterInputDevice *device, + ClutterInputDevice *other_device) +{ +#ifdef HAVE_LIBWACOM + WacomDevice *wacom_device, *other_wacom_device; + + wacom_device = + meta_input_device_get_wacom_device (META_INPUT_DEVICE (device)); + other_wacom_device = + meta_input_device_get_wacom_device (META_INPUT_DEVICE (other_device)); + + if (wacom_device && other_wacom_device && + libwacom_compare (wacom_device, + other_wacom_device, + WCOMPARE_NORMAL) == 0) + return TRUE; +#endif + + if (clutter_input_device_get_vendor_id (device) && + clutter_input_device_get_product_id (device) && + clutter_input_device_get_vendor_id (other_device) && + clutter_input_device_get_product_id (other_device)) + { + if (strcmp (clutter_input_device_get_vendor_id (device), + clutter_input_device_get_vendor_id (other_device)) == 0 && + strcmp (clutter_input_device_get_product_id (device), + clutter_input_device_get_product_id (other_device)) == 0) + return TRUE; + } + + return FALSE; +} + +static void +meta_input_device_x11_finalize (GObject *object) +{ + MetaInputDeviceX11 *device_xi2 = META_INPUT_DEVICE_X11 (object); + +#ifdef HAVE_LIBWACOM + if (device_xi2->group_modes) + g_array_unref (device_xi2->group_modes); +#endif + + g_clear_handle_id (&device_xi2->inhibit_pointer_query_timer, g_source_remove); + + G_OBJECT_CLASS (meta_input_device_x11_parent_class)->finalize (object); +} + +static int +meta_input_device_x11_get_group_n_modes (ClutterInputDevice *device, + int group) +{ +#ifdef HAVE_LIBWACOM + WacomDevice *wacom_device; + + wacom_device = meta_input_device_get_wacom_device (META_INPUT_DEVICE (device)); + + if (wacom_device) + { + if (group == 0) + { + if (libwacom_has_ring (wacom_device)) + return libwacom_get_ring_num_modes (wacom_device); + else if (libwacom_get_num_strips (wacom_device) >= 1) + return libwacom_get_strips_num_modes (wacom_device); + } + else if (group == 1) + { + if (libwacom_has_ring2 (wacom_device)) + return libwacom_get_ring2_num_modes (wacom_device); + else if (libwacom_get_num_strips (wacom_device) >= 2) + return libwacom_get_strips_num_modes (wacom_device); + } + } +#endif + + return -1; +} + +#ifdef HAVE_LIBWACOM +static int +meta_input_device_x11_get_button_group (ClutterInputDevice *device, + uint32_t button) +{ + WacomDevice *wacom_device; + + wacom_device = meta_input_device_get_wacom_device (META_INPUT_DEVICE (device)); + + if (wacom_device) + { + WacomButtonFlags flags; + + if (button >= libwacom_get_num_buttons (wacom_device)) + return -1; + + flags = libwacom_get_button_flag (wacom_device, 'A' + button); + + if (flags & + (WACOM_BUTTON_RING_MODESWITCH | + WACOM_BUTTON_TOUCHSTRIP_MODESWITCH)) + return 0; + if (flags & + (WACOM_BUTTON_RING2_MODESWITCH | + WACOM_BUTTON_TOUCHSTRIP2_MODESWITCH)) + return 1; + } + + return -1; +} +#endif + +static gboolean +meta_input_device_x11_is_mode_switch_button (ClutterInputDevice *device, + uint32_t group, + uint32_t button) +{ + int button_group = -1; + +#ifdef HAVE_LIBWACOM + button_group = meta_input_device_x11_get_button_group (device, button); +#endif + + return button_group == (int) group; +} + +static void +meta_input_device_x11_class_init (MetaInputDeviceX11Class *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + ClutterInputDeviceClass *device_class = CLUTTER_INPUT_DEVICE_CLASS (klass); + + gobject_class->constructed = meta_input_device_x11_constructed; + gobject_class->finalize = meta_input_device_x11_finalize; + + device_class->keycode_to_evdev = meta_input_device_x11_keycode_to_evdev; + device_class->is_grouped = meta_input_device_x11_is_grouped; + device_class->get_group_n_modes = meta_input_device_x11_get_group_n_modes; + device_class->is_mode_switch_button = meta_input_device_x11_is_mode_switch_button; +} + +static void +meta_input_device_x11_init (MetaInputDeviceX11 *self) +{ +} + +static ClutterModifierType +get_modifier_for_button (int i) +{ + switch (i) + { + case 1: + return CLUTTER_BUTTON1_MASK; + case 2: + return CLUTTER_BUTTON2_MASK; + case 3: + return CLUTTER_BUTTON3_MASK; + case 4: + return CLUTTER_BUTTON4_MASK; + case 5: + return CLUTTER_BUTTON5_MASK; + default: + return 0; + } +} + +void +meta_input_device_x11_translate_state (ClutterEvent *event, + XIModifierState *modifiers_state, + XIButtonState *buttons_state, + XIGroupState *group_state) +{ + uint32_t button = 0; + uint32_t base = 0; + uint32_t latched = 0; + uint32_t locked = 0; + uint32_t effective; + + if (modifiers_state) + { + base = (uint32_t) modifiers_state->base; + latched = (uint32_t) modifiers_state->latched; + locked = (uint32_t) modifiers_state->locked; + } + + if (buttons_state) + { + int len, i; + + len = MIN (N_BUTTONS, buttons_state->mask_len * 8); + + for (i = 0; i < len; i++) + { + if (!XIMaskIsSet (buttons_state->mask, i)) + continue; + + button |= get_modifier_for_button (i); + } + } + + /* The XIButtonState sent in the event specifies the + * state of the buttons before the event. In order to + * get the current state of the buttons, we need to + * filter out the current button. + */ + switch (event->type) + { + case CLUTTER_BUTTON_PRESS: + button |= (get_modifier_for_button (event->button.button)); + break; + case CLUTTER_BUTTON_RELEASE: + button &= ~(get_modifier_for_button (event->button.button)); + break; + default: + break; + } + + effective = button | base | latched | locked; + if (group_state) + effective |= (group_state->effective) << 13; + + _clutter_event_set_state_full (event, button, base, latched, locked, effective); +} + +void +meta_input_device_x11_update_tool (ClutterInputDevice *device, + ClutterInputDeviceTool *tool) +{ + MetaInputDeviceX11 *device_xi2 = META_INPUT_DEVICE_X11 (device); + g_set_object (&device_xi2->current_tool, tool); +} + +ClutterInputDeviceTool * +meta_input_device_x11_get_current_tool (ClutterInputDevice *device) +{ + MetaInputDeviceX11 *device_xi2 = META_INPUT_DEVICE_X11 (device); + return device_xi2->current_tool; +} + +static gboolean +meta_input_device_x11_query_pointer_location (MetaInputDeviceX11 *device_xi2) +{ + Window xroot_window, xchild_window; + double xroot_x, xroot_y, xwin_x, xwin_y; + XIButtonState button_state; + XIModifierState mod_state; + XIGroupState group_state; + int result; + + clutter_x11_trap_x_errors (); + result = XIQueryPointer (clutter_x11_get_default_display (), + device_xi2->device_id, + clutter_x11_get_root_window (), + &xroot_window, + &xchild_window, + &xroot_x, &xroot_y, + &xwin_x, &xwin_y, + &button_state, + &mod_state, + &group_state); + clutter_x11_untrap_x_errors (); + + if (!result) + return FALSE; + + device_xi2->current_x = (float) xroot_x; + device_xi2->current_y = (float) xroot_y; + + return TRUE; +} + +static gboolean +clear_inhibit_pointer_query_cb (gpointer data) +{ + MetaInputDeviceX11 *device_xi2 = META_INPUT_DEVICE_X11 (data); + + device_xi2->inhibit_pointer_query_timer = 0; + + return G_SOURCE_REMOVE; +} + +gboolean +meta_input_device_x11_get_pointer_location (ClutterInputDevice *device, + float *x, + float *y) + +{ + MetaInputDeviceX11 *device_xi2 = META_INPUT_DEVICE_X11 (device); + + g_return_val_if_fail (META_IS_INPUT_DEVICE_X11 (device), FALSE); + g_return_val_if_fail (device->device_type == CLUTTER_POINTER_DEVICE, FALSE); + + /* Throttle XServer queries and roundtrips using an idle timeout */ + if (device_xi2->inhibit_pointer_query_timer == 0) + { + device_xi2->query_status = + meta_input_device_x11_query_pointer_location (device_xi2); + device_xi2->inhibit_pointer_query_timer = + clutter_threads_add_idle (clear_inhibit_pointer_query_cb, device_xi2); + } + + *x = device_xi2->current_x; + *y = device_xi2->current_y; + + return device_xi2->query_status; +} + +#ifdef HAVE_LIBWACOM +uint32_t +meta_input_device_x11_get_pad_group_mode (ClutterInputDevice *device, + uint32_t group) +{ + MetaInputDeviceX11 *device_xi2 = META_INPUT_DEVICE_X11 (device); + + if (group >= device_xi2->group_modes->len) + return 0; + + return g_array_index (device_xi2->group_modes, uint32_t, group); +} + +static gboolean +pad_switch_mode (ClutterInputDevice *device, + uint32_t button, + uint32_t group, + uint32_t *mode) +{ + MetaInputDeviceX11 *device_x11 = META_INPUT_DEVICE_X11 (device); + uint32_t n_buttons, n_modes, button_group, next_mode, i; + WacomDevice *wacom_device; + GList *switch_buttons = NULL; + + wacom_device = + meta_input_device_get_wacom_device (META_INPUT_DEVICE (device)); + n_buttons = libwacom_get_num_buttons (wacom_device); + + for (i = 0; i < n_buttons; i++) + { + button_group = meta_input_device_x11_get_button_group (device, i); + if (button_group == group) + switch_buttons = g_list_prepend (switch_buttons, GINT_TO_POINTER (button)); + } + + switch_buttons = g_list_reverse (switch_buttons); + n_modes = clutter_input_device_get_group_n_modes (device, group); + + if (g_list_length (switch_buttons) > 1) + { + /* If there's multiple switch buttons, we don't toggle but assign a mode + * to each of those buttons. + */ + next_mode = g_list_index (switch_buttons, GINT_TO_POINTER (button)); + } + else if (switch_buttons) + { + uint32_t cur_mode; + + /* If there is a single button, have it toggle across modes */ + cur_mode = g_array_index (device_x11->group_modes, uint32_t, group); + next_mode = (cur_mode + 1) % n_modes; + } + else + { + return FALSE; + } + + g_list_free (switch_buttons); + + if (next_mode < 0 || next_mode > n_modes) + return FALSE; + + *mode = next_mode; + return TRUE; +} + +void +meta_input_device_x11_update_pad_state (ClutterInputDevice *device, + uint32_t button, + uint32_t state, + uint32_t *group, + uint32_t *mode) +{ + MetaInputDeviceX11 *device_xi2 = META_INPUT_DEVICE_X11 (device); + uint32_t button_group, *group_mode; + + button_group = meta_input_device_x11_get_button_group (device, button); + + if (button_group < 0 || button_group >= device_xi2->group_modes->len) + { + if (group) + *group = 0; + if (mode) + *mode = 0; + return; + } + + group_mode = &g_array_index (device_xi2->group_modes, uint32_t, button_group); + + if (state) + { + uint32_t next_mode; + + if (pad_switch_mode (device, button, button_group, &next_mode)) + *group_mode = next_mode; + } + + if (group) + *group = button_group; + if (mode) + *mode = *group_mode; +} +#endif diff --git a/src/backends/x11/meta-input-device-x11.h b/src/backends/x11/meta-input-device-x11.h new file mode 100644 index 000000000..1cbee031a --- /dev/null +++ b/src/backends/x11/meta-input-device-x11.h @@ -0,0 +1,75 @@ +/* + * Copyright © 2011 Intel Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Author: Emmanuele Bassi <ebassi@linux.intel.com> + */ + +#ifndef META_INPUT_DEVICE_X11_H +#define META_INPUT_DEVICE_X11_H + +#include <X11/extensions/XInput2.h> + +#ifdef HAVE_LIBWACOM +#include <libwacom/libwacom.h> +#endif + +#include "backends/meta-input-device-private.h" +#include "clutter/clutter.h" + +G_BEGIN_DECLS + +#define META_TYPE_INPUT_DEVICE_X11 (meta_input_device_x11_get_type ()) +#define META_INPUT_DEVICE_X11(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), META_TYPE_INPUT_DEVICE_X11, MetaInputDeviceX11)) +#define META_IS_INPUT_DEVICE_X11(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), META_TYPE_INPUT_DEVICE_X11)) +#define META_INPUT_DEVICE_X11_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), META_TYPE_INPUT_DEVICE_X11, MetaInputDeviceX11Class)) +#define META_IS_INPUT_DEVICE_X11_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), META_TYPE_INPUT_DEVICE_X11)) +#define META_INPUT_DEVICE_X11_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), META_TYPE_INPUT_DEVICE_X11, MetaInputDeviceX11Class)) + +typedef struct _MetaInputDeviceX11 MetaInputDeviceX11; +typedef struct _MetaInputDeviceX11Class MetaInputDeviceX11Class; + +GType meta_input_device_x11_get_type (void) G_GNUC_CONST; + +void meta_input_device_x11_translate_state (ClutterEvent *event, + XIModifierState *modifiers_state, + XIButtonState *buttons_state, + XIGroupState *group_state); +void meta_input_device_x11_update_tool (ClutterInputDevice *device, + ClutterInputDeviceTool *tool); +ClutterInputDeviceTool * meta_input_device_x11_get_current_tool (ClutterInputDevice *device); + +#ifdef HAVE_LIBWACOM +void meta_input_device_x11_ensure_wacom_info (ClutterInputDevice *device, + WacomDeviceDatabase *wacom_db); + +uint32_t meta_input_device_x11_get_pad_group_mode (ClutterInputDevice *device, + uint32_t group); + +void meta_input_device_x11_update_pad_state (ClutterInputDevice *device, + uint32_t button, + uint32_t state, + uint32_t *group, + uint32_t *mode); + +#endif + +gboolean meta_input_device_x11_get_pointer_location (ClutterInputDevice *device, + float *x, + float *y); + +G_END_DECLS + +#endif /* META_INPUT_DEVICE_X11_H */ diff --git a/src/backends/x11/meta-input-settings-x11.c b/src/backends/x11/meta-input-settings-x11.c new file mode 100644 index 000000000..506966174 --- /dev/null +++ b/src/backends/x11/meta-input-settings-x11.c @@ -0,0 +1,1056 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#include "config.h" + +#include "backends/x11/meta-input-settings-x11.h" + +#include <gdk/gdkx.h> +#include <string.h> +#include <X11/Xatom.h> +#include <X11/extensions/XInput2.h> +#include <X11/XKBlib.h> + +#ifdef HAVE_LIBGUDEV +#include <gudev/gudev.h> +#endif + +#include "backends/meta-logical-monitor.h" +#include "backends/x11/meta-backend-x11.h" +#include "core/display-private.h" +#include "meta/meta-x11-errors.h" + +typedef struct _MetaInputSettingsX11Private +{ +#ifdef HAVE_LIBGUDEV + GUdevClient *udev_client; +#endif +} MetaInputSettingsX11Private; + +G_DEFINE_TYPE_WITH_PRIVATE (MetaInputSettingsX11, meta_input_settings_x11, + META_TYPE_INPUT_SETTINGS) + +enum +{ + SCROLL_METHOD_FIELD_2FG, + SCROLL_METHOD_FIELD_EDGE, + SCROLL_METHOD_FIELD_BUTTON, + SCROLL_METHOD_NUM_FIELDS +}; + +static void +device_free_xdevice (gpointer user_data) +{ + MetaDisplay *display = meta_get_display (); + MetaBackend *backend = meta_get_backend (); + Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); + XDevice *xdev = user_data; + + meta_x11_error_trap_push (display->x11_display); + XCloseDevice (xdisplay, xdev); + meta_x11_error_trap_pop (display->x11_display); +} + +static XDevice * +device_ensure_xdevice (ClutterInputDevice *device) +{ + MetaDisplay *display = meta_get_display (); + MetaBackend *backend = meta_get_backend (); + Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); + int device_id = clutter_input_device_get_device_id (device); + XDevice *xdev = NULL; + + xdev = g_object_get_data (G_OBJECT (device), "meta-input-settings-xdevice"); + if (xdev) + return xdev; + + meta_x11_error_trap_push (display->x11_display); + xdev = XOpenDevice (xdisplay, device_id); + meta_x11_error_trap_pop (display->x11_display); + + if (xdev) + { + g_object_set_data_full (G_OBJECT (device), + "meta-input-settings-xdevice", + xdev, device_free_xdevice); + } + + return xdev; +} + +static void * +get_property (ClutterInputDevice *device, + const gchar *property, + Atom type, + int format, + gulong nitems) +{ + MetaBackend *backend = meta_get_backend (); + Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); + gulong nitems_ret, bytes_after_ret; + int rc, device_id, format_ret; + Atom property_atom, type_ret; + guchar *data_ret = NULL; + + property_atom = XInternAtom (xdisplay, property, True); + if (!property_atom) + return NULL; + + device_id = clutter_input_device_get_device_id (device); + + clutter_x11_trap_x_errors (); + rc = XIGetProperty (xdisplay, device_id, property_atom, + 0, 10, False, type, &type_ret, &format_ret, + &nitems_ret, &bytes_after_ret, &data_ret); + clutter_x11_untrap_x_errors (); + + if (rc == Success && type_ret == type && format_ret == format && nitems_ret >= nitems) + { + if (nitems_ret > nitems) + g_warning ("Property '%s' for device '%s' returned %lu items, expected %lu", + property, clutter_input_device_get_device_name (device), nitems_ret, nitems); + return data_ret; + } + + meta_XFree (data_ret); + return NULL; +} + +static void +change_property (ClutterInputDevice *device, + const gchar *property, + Atom type, + int format, + void *data, + gulong nitems) +{ + MetaBackend *backend = meta_get_backend (); + Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); + int device_id; + Atom property_atom; + guchar *data_ret; + + property_atom = XInternAtom (xdisplay, property, True); + if (!property_atom) + return; + + device_id = clutter_input_device_get_device_id (device); + + data_ret = get_property (device, property, type, format, nitems); + if (!data_ret) + return; + + XIChangeProperty (xdisplay, device_id, property_atom, type, + format, XIPropModeReplace, data, nitems); + meta_XFree (data_ret); +} + +static void +meta_input_settings_x11_set_send_events (MetaInputSettings *settings, + ClutterInputDevice *device, + CDesktopDeviceSendEvents mode) +{ + guchar values[2] = { 0 }; /* disabled, disabled-on-external-mouse */ + guchar *available; + + available = get_property (device, "libinput Send Events Modes Available", + XA_INTEGER, 8, 2); + + switch (mode) + { + case C_DESKTOP_DEVICE_SEND_EVENTS_DISABLED: + values[0] = 1; + break; + case C_DESKTOP_DEVICE_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE: + values[1] = 1; + break; + default: + break; + } + + change_property (device, "Synaptics Off", XA_INTEGER, 8, &values, 1); + + if (!available) + return; + + if ((values[0] && !available[0]) || (values[1] && !available[1])) + g_warning ("Device '%s' does not support sendevents mode %d\n", + clutter_input_device_get_device_name (device), mode); + else + change_property (device, "libinput Send Events Mode Enabled", + XA_INTEGER, 8, &values, 2); + + meta_XFree (available); +} + +static void +meta_input_settings_x11_set_matrix (MetaInputSettings *settings, + ClutterInputDevice *device, + gfloat matrix[6]) +{ + MetaBackend *backend = meta_get_backend (); + Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); + gfloat full_matrix[9] = { matrix[0], matrix[1], matrix[2], + matrix[3], matrix[4], matrix[5], + 0, 0, 1 }; + + change_property (device, "Coordinate Transformation Matrix", + XInternAtom (xdisplay, "FLOAT", False), + 32, &full_matrix, 9); +} + +static void +meta_input_settings_x11_set_speed (MetaInputSettings *settings, + ClutterInputDevice *device, + gdouble speed) +{ + MetaBackend *backend = meta_get_backend (); + Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); + gfloat *accel = get_property (device, "libinput Accel Speed", + XInternAtom (xdisplay, "FLOAT", False), 32, 1); + + if (accel) + { + *accel = speed; /* Sounds confused, but libinput is confused. */ + change_property (device, "libinput Accel Speed", + XInternAtom (xdisplay, "FLOAT", False), 32, accel, 1); + meta_XFree (accel); + } + else + { + gfloat scale = (speed <= -1.0) ? 1.0 : (speed + 1.0) * 12.5; + + change_property (device, "Device Accel Velocity Scaling", + XInternAtom (xdisplay, "FLOAT", False), 32, &scale, 1); + } +} + +static void +meta_input_settings_x11_set_left_handed (MetaInputSettings *settings, + ClutterInputDevice *device, + gboolean enabled) +{ + ClutterInputDeviceType device_type; + guchar value; + + device_type = clutter_input_device_get_device_type (device); + + if (device_type == CLUTTER_TABLET_DEVICE || + device_type == CLUTTER_PEN_DEVICE || + device_type == CLUTTER_ERASER_DEVICE) + { + value = enabled ? 3 : 0; + change_property (device, "Wacom Rotation", + XA_INTEGER, 8, &value, 1); + } + else + { + value = enabled ? 1 : 0; + change_property (device, "libinput Left Handed Enabled", + XA_INTEGER, 8, &value, 1); + } +} + +static void +meta_input_settings_x11_set_disable_while_typing (MetaInputSettings *settings, + ClutterInputDevice *device, + gboolean enabled) +{ + guchar value = (enabled) ? 1 : 0; + + change_property (device, "libinput Disable While Typing Enabled", + XA_INTEGER, 8, &value, 1); + + change_property (device, "Synaptics Palm Detection", + XA_INTEGER, 8, &value, 1); +} + +static void +meta_input_settings_x11_set_tap_enabled (MetaInputSettings *settings, + ClutterInputDevice *device, + gboolean enabled) +{ + guchar value = (enabled) ? 1 : 0; + gint32 tap_time = (enabled) ? 180 : 0; + + change_property (device, "libinput Tapping Enabled", + XA_INTEGER, 8, &value, 1); + + change_property (device, "Synaptics Tap Time", + XA_INTEGER, 32, &tap_time, 1); +} + +static void +meta_input_settings_x11_set_tap_and_drag_enabled (MetaInputSettings *settings, + ClutterInputDevice *device, + gboolean enabled) +{ + guchar value = (enabled) ? 1 : 0; + + change_property (device, "libinput Tapping Drag Enabled", + XA_INTEGER, 8, &value, 1); + + change_property (device, "Synaptics Gestures", + XA_INTEGER, 8, &value, 1); +} + +static void +meta_input_settings_x11_set_invert_scroll (MetaInputSettings *settings, + ClutterInputDevice *device, + gboolean inverted) +{ + gint32 *scroll_dist = get_property (device, "Synaptics Scrolling Distance", + XA_INTEGER, 32, 2); + if (scroll_dist) + { + scroll_dist[0] = inverted ? -ABS (scroll_dist[0]) : ABS (scroll_dist[0]); + change_property (device, "Synaptics Scrolling Distance", + XA_INTEGER, 32, scroll_dist, 2); + meta_XFree (scroll_dist); + } + else + { + guchar value = (inverted) ? 1 : 0; + + change_property (device, "libinput Natural Scrolling Enabled", + XA_INTEGER, 8, &value, 1); + } +} + +static void +meta_input_settings_x11_set_edge_scroll (MetaInputSettings *settings, + ClutterInputDevice *device, + gboolean edge_scroll_enabled) +{ + guchar values[SCROLL_METHOD_NUM_FIELDS] = { 0 }; /* 2fg, edge, button. The last value is unused */ + guchar *current = NULL; + guchar *available = NULL; + + current = get_property (device, "Synaptics Edge Scrolling", + XA_INTEGER, 8, 3); + if (current) + { + current[0] = current[1] = !!edge_scroll_enabled; + change_property (device, "Synaptics Edge Scrolling", + XA_INTEGER, 8, current, 3); + goto out; + } + + available = get_property (device, "libinput Scroll Methods Available", + XA_INTEGER, 8, SCROLL_METHOD_NUM_FIELDS); + if (!available || !available[SCROLL_METHOD_FIELD_EDGE]) + goto out; + + current = get_property (device, "libinput Scroll Method Enabled", + XA_INTEGER, 8, SCROLL_METHOD_NUM_FIELDS); + if (!current) + goto out; + + memcpy (values, current, SCROLL_METHOD_NUM_FIELDS); + + values[SCROLL_METHOD_FIELD_EDGE] = !!edge_scroll_enabled; + change_property (device, "libinput Scroll Method Enabled", + XA_INTEGER, 8, &values, SCROLL_METHOD_NUM_FIELDS); + out: + meta_XFree (current); + meta_XFree (available); +} + +static void +meta_input_settings_x11_set_two_finger_scroll (MetaInputSettings *settings, + ClutterInputDevice *device, + gboolean two_finger_scroll_enabled) +{ + guchar values[SCROLL_METHOD_NUM_FIELDS] = { 0 }; /* 2fg, edge, button. The last value is unused */ + guchar *current = NULL; + guchar *available = NULL; + + current = get_property (device, "Synaptics Two-Finger Scrolling", + XA_INTEGER, 8, 2); + if (current) + { + current[0] = current[1] = !!two_finger_scroll_enabled; + change_property (device, "Synaptics Two-Finger Scrolling", + XA_INTEGER, 8, current, 2); + goto out; + } + + available = get_property (device, "libinput Scroll Methods Available", + XA_INTEGER, 8, SCROLL_METHOD_NUM_FIELDS); + if (!available || !available[SCROLL_METHOD_FIELD_2FG]) + goto out; + + current = get_property (device, "libinput Scroll Method Enabled", + XA_INTEGER, 8, SCROLL_METHOD_NUM_FIELDS); + if (!current) + goto out; + + memcpy (values, current, SCROLL_METHOD_NUM_FIELDS); + + values[SCROLL_METHOD_FIELD_2FG] = !!two_finger_scroll_enabled; + change_property (device, "libinput Scroll Method Enabled", + XA_INTEGER, 8, &values, SCROLL_METHOD_NUM_FIELDS); + out: + meta_XFree (current); + meta_XFree (available); +} + +static gboolean +meta_input_settings_x11_has_two_finger_scroll (MetaInputSettings *settings, + ClutterInputDevice *device) +{ + guchar *available = NULL; + gboolean has_two_finger = TRUE; + + available = get_property (device, "Synaptics Two-Finger Scrolling", + XA_INTEGER, 8, 2); + if (available) + { + has_two_finger = available[0] || available[1]; + } + else + { + available = get_property (device, "libinput Scroll Methods Available", + XA_INTEGER, 8, SCROLL_METHOD_NUM_FIELDS); + if (!available || !available[SCROLL_METHOD_FIELD_2FG]) + has_two_finger = FALSE; + } + + meta_XFree (available); + return has_two_finger; +} + +static void +meta_input_settings_x11_set_scroll_button (MetaInputSettings *settings, + ClutterInputDevice *device, + guint button) +{ + change_property (device, "libinput Button Scrolling Button", + XA_INTEGER, 32, &button, 1); +} + +static void +meta_input_settings_x11_set_click_method_synaptics (MetaInputSettings *settings, + ClutterInputDevice *device, + CDesktopTouchpadClickMethod mode) +{ + /* { RT corner, RB, LT, LB, 1 finger, 2 fingers, 3 fingers } */ + guchar tap_action_default[7] = { 2, 3, 0, 0, 1, 3, 0 }; + guchar tap_action_areas[7] = { 2, 3, 0, 0, 1, 0, 0 }; + guchar tap_action_fingers[7] = { 0, 0, 0, 0, 1, 3, 2 }; + guchar tap_action_none[7] = { 0, 0, 0, 0, 1, 0, 0 }; + guchar *tap_action = tap_action_default; + + /* TODO On startup save the default value of 'Synaptics Soft Button Areas', + but save it where? */ + gint32 zero_button_areas[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + gint32 *button_areas_known = NULL; + + switch (mode) + { + case C_DESKTOP_TOUCHPAD_CLICK_METHOD_DEFAULT: + tap_action = tap_action_default; + /* Doing nothing right now will give the correct default, unless changed + during the session */ + break; + case C_DESKTOP_TOUCHPAD_CLICK_METHOD_NONE: + tap_action = tap_action_none; + button_areas_known = zero_button_areas; + break; + case C_DESKTOP_TOUCHPAD_CLICK_METHOD_AREAS: + tap_action = tap_action_areas; + /* Doing nothing right now will give the correct default, unless changed + during the session */ + break; + case C_DESKTOP_TOUCHPAD_CLICK_METHOD_FINGERS: + tap_action = tap_action_fingers; + button_areas_known = zero_button_areas; + break; + default: + g_assert_not_reached (); + return; + } + + change_property (device, "Synaptics Tap Action", + XA_INTEGER, 8, tap_action, 7); + change_property (device, "Synaptics Click Action", + XA_INTEGER, 8, tap_action + 4, 3); + + if (button_areas_known) + change_property (device, "Synaptics Soft Button Areas", + XA_INTEGER, 32, button_areas_known, 8); +} + +static void +meta_input_settings_x11_set_click_method (MetaInputSettings *settings, + ClutterInputDevice *device, + CDesktopTouchpadClickMethod mode) +{ + guchar values[2] = { 0 }; /* buttonareas, clickfinger */ + guchar *defaults, *available; + + available = get_property (device, "libinput Click Methods Available", + XA_INTEGER, 8, 2); + if (!available) + { + meta_input_settings_x11_set_click_method_synaptics (settings, device, + mode); + return; + } + + switch (mode) + { + case C_DESKTOP_TOUCHPAD_CLICK_METHOD_DEFAULT: + defaults = get_property (device, "libinput Click Method Enabled Default", + XA_INTEGER, 8, 2); + if (!defaults) + break; + memcpy (values, defaults, 2); + meta_XFree (defaults); + break; + case C_DESKTOP_TOUCHPAD_CLICK_METHOD_NONE: + break; + case C_DESKTOP_TOUCHPAD_CLICK_METHOD_AREAS: + values[0] = 1; + break; + case C_DESKTOP_TOUCHPAD_CLICK_METHOD_FINGERS: + values[1] = 1; + break; + default: + g_assert_not_reached (); + return; + } + + if ((values[0] && !available[0]) || (values[1] && !available[1])) + g_warning ("Device '%s' does not support click method %d\n", + clutter_input_device_get_device_name (device), mode); + else + change_property (device, "libinput Click Method Enabled", + XA_INTEGER, 8, &values, 2); + + meta_XFree(available); +} + +static void +meta_input_settings_x11_set_keyboard_repeat (MetaInputSettings *settings, + gboolean enabled, + guint delay, + guint interval) +{ + MetaBackend *backend = meta_get_backend (); + Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); + + if (enabled) + { + XAutoRepeatOn (xdisplay); + XkbSetAutoRepeatRate (xdisplay, XkbUseCoreKbd, delay, interval); + } + else + { + XAutoRepeatOff (xdisplay); + } +} + +static gboolean +has_udev_property (MetaInputSettings *settings, + ClutterInputDevice *device, + const char *property_name) +{ +#ifdef HAVE_LIBGUDEV + MetaInputSettingsX11 *settings_x11 = META_INPUT_SETTINGS_X11 (settings); + MetaInputSettingsX11Private *priv = + meta_input_settings_x11_get_instance_private (settings_x11); + const char *device_node; + GUdevDevice *udev_device = NULL; + GUdevDevice *parent_udev_device = NULL; + + device_node = clutter_input_device_get_device_node (device); + if (!device_node) + return FALSE; + + udev_device = g_udev_client_query_by_device_file (priv->udev_client, + device_node); + if (!udev_device) + return FALSE; + + if (NULL != g_udev_device_get_property (udev_device, property_name)) + { + g_object_unref (udev_device); + return TRUE; + } + + parent_udev_device = g_udev_device_get_parent (udev_device); + g_object_unref (udev_device); + + if (!parent_udev_device) + return FALSE; + + if (NULL != g_udev_device_get_property (parent_udev_device, property_name)) + { + g_object_unref (parent_udev_device); + return TRUE; + } + + g_object_unref (parent_udev_device); + return FALSE; +#else + static gboolean warned_once = FALSE; + + if (!warned_once) + { + g_warning ("Failed to query property: no udev support"); + warned_once = TRUE; + } + + return FALSE; +#endif +} + +static gboolean +is_mouse (MetaInputSettings *settings, + ClutterInputDevice *device) +{ + return (has_udev_property (settings, device, "ID_INPUT_MOUSE") && + !has_udev_property (settings, device, "ID_INPUT_POINTINGSTICK")); +} + +static gboolean +meta_input_settings_x11_is_touchpad_device (MetaInputSettings *settings, + ClutterInputDevice *device) +{ + return has_udev_property (settings, device, "ID_INPUT_TOUCHPAD"); +} + +static gboolean +meta_input_settings_x11_is_trackball_device (MetaInputSettings *settings, + ClutterInputDevice *device) +{ + return has_udev_property (settings, device, "ID_INPUT_TRACKBALL"); +} + +static void +set_device_accel_profile (ClutterInputDevice *device, + CDesktopPointerAccelProfile profile) +{ + guchar *defaults, *available; + guchar values[2] = { 0 }; /* adaptive, flat */ + + defaults = get_property (device, "libinput Accel Profile Enabled Default", + XA_INTEGER, 8, 2); + if (!defaults) + return; + + available = get_property (device, "libinput Accel Profiles Available", + XA_INTEGER, 8, 2); + if (!available) + goto err_available; + + switch (profile) + { + case C_DESKTOP_POINTER_ACCEL_PROFILE_FLAT: + values[0] = 0; + values[1] = 1; + break; + case C_DESKTOP_POINTER_ACCEL_PROFILE_ADAPTIVE: + values[0] = 1; + values[1] = 0; + break; + default: + g_warn_if_reached (); + case C_DESKTOP_POINTER_ACCEL_PROFILE_DEFAULT: + values[0] = defaults[0]; + values[1] = defaults[1]; + break; + } + + change_property (device, "libinput Accel Profile Enabled", + XA_INTEGER, 8, &values, 2); + + meta_XFree (available); + +err_available: + meta_XFree (defaults); +} + +static void +meta_input_settings_x11_set_mouse_accel_profile (MetaInputSettings *settings, + ClutterInputDevice *device, + CDesktopPointerAccelProfile profile) +{ + if (!is_mouse (settings, device)) + return; + + set_device_accel_profile (device, profile); +} + +static void +meta_input_settings_x11_set_trackball_accel_profile (MetaInputSettings *settings, + ClutterInputDevice *device, + CDesktopPointerAccelProfile profile) +{ + if (!meta_input_settings_x11_is_trackball_device (settings, device)) + return; + + set_device_accel_profile (device, profile); +} + +static void +meta_input_settings_x11_set_tablet_mapping (MetaInputSettings *settings, + ClutterInputDevice *device, + CDesktopTabletMapping mapping) +{ + MetaDisplay *display = meta_get_display (); + MetaBackend *backend = meta_get_backend (); + Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); + XDevice *xdev; + + if (!display) + return; + + /* Grab the puke bucket! */ + meta_x11_error_trap_push (display->x11_display); + xdev = device_ensure_xdevice (device); + if (xdev) + { + XSetDeviceMode (xdisplay, xdev, + mapping == C_DESKTOP_TABLET_MAPPING_ABSOLUTE ? + Absolute : Relative); + } + + if (meta_x11_error_trap_pop_with_return (display->x11_display)) + { + g_warning ("Could not set tablet mapping for %s", + clutter_input_device_get_device_name (device)); + } + else + { + ClutterInputDeviceMapping dev_mapping; + + dev_mapping = (mapping == C_DESKTOP_TABLET_MAPPING_ABSOLUTE) ? + CLUTTER_INPUT_DEVICE_MAPPING_ABSOLUTE : + CLUTTER_INPUT_DEVICE_MAPPING_RELATIVE; + clutter_input_device_set_mapping_mode (device, dev_mapping); + } +} + +static gboolean +device_query_area (ClutterInputDevice *device, + gint *x, + gint *y, + gint *width, + gint *height) +{ + MetaBackend *backend = meta_get_backend (); + Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); + gint device_id, n_devices, i; + XIDeviceInfo *info; + Atom abs_x, abs_y; + + *width = *height = 0; + device_id = clutter_input_device_get_device_id (device); + info = XIQueryDevice (xdisplay, device_id, &n_devices); + if (n_devices <= 0 || !info) + return FALSE; + + abs_x = XInternAtom (xdisplay, "Abs X", True); + abs_y = XInternAtom (xdisplay, "Abs Y", True); + + for (i = 0; i < info->num_classes; i++) + { + XIValuatorClassInfo *valuator = (XIValuatorClassInfo *) info->classes[i]; + + if (valuator->type != XIValuatorClass) + continue; + if (valuator->label == abs_x) + { + *x = valuator->min; + *width = valuator->max - valuator->min; + } + else if (valuator->label == abs_y) + { + *y = valuator->min; + *height = valuator->max - valuator->min; + } + } + + XIFreeDeviceInfo (info); + return TRUE; +} + +static void +update_tablet_area (MetaInputSettings *settings, + ClutterInputDevice *device, + gint32 *area) +{ + change_property (device, "Wacom Tablet Area", + XA_INTEGER, 32, area, 4); +} + +static void +meta_input_settings_x11_set_tablet_area (MetaInputSettings *settings, + ClutterInputDevice *device, + gdouble padding_left, + gdouble padding_right, + gdouble padding_top, + gdouble padding_bottom) +{ + gint32 x, y, width, height, area[4] = { 0 }; + + if (!device_query_area (device, &x, &y, &width, &height)) + return; + + area[0] = (width * padding_left) + x; + area[1] = (height * padding_top) + y; + area[2] = width - (width * padding_right) + x; + area[3] = height - (height * padding_bottom) + y; + update_tablet_area (settings, device, area); +} + +static void +meta_input_settings_x11_set_tablet_keep_aspect (MetaInputSettings *settings, + ClutterInputDevice *device, + MetaLogicalMonitor *logical_monitor, + gboolean keep_aspect) +{ + gint32 width, height, dev_x, dev_y, dev_width, dev_height, area[4] = { 0 }; + + if (!device_query_area (device, &dev_x, &dev_y, &dev_width, &dev_height)) + return; + + if (keep_aspect) + { + double aspect_ratio, dev_aspect; + + if (logical_monitor) + { + width = logical_monitor->rect.width; + height = logical_monitor->rect.height; + } + else + { + MetaMonitorManager *monitor_manager; + MetaBackend *backend; + + backend = meta_get_backend (); + monitor_manager = meta_backend_get_monitor_manager (backend); + meta_monitor_manager_get_screen_size (monitor_manager, + &width, &height); + } + + aspect_ratio = (double) width / height; + dev_aspect = (double) dev_width / dev_height; + + if (dev_aspect > aspect_ratio) + dev_width = dev_height * aspect_ratio; + else if (dev_aspect < aspect_ratio) + dev_height = dev_width / aspect_ratio; + } + + area[0] = dev_x; + area[1] = dev_y; + area[2] = dev_width + dev_x; + area[3] = dev_height + dev_y; + update_tablet_area (settings, device, area); +} + +static void +meta_input_settings_x11_dispose (GObject *object) +{ +#ifdef HAVE_LIBGUDEV + MetaInputSettingsX11 *settings_x11 = META_INPUT_SETTINGS_X11 (object); + MetaInputSettingsX11Private *priv = + meta_input_settings_x11_get_instance_private (settings_x11); + + g_clear_object (&priv->udev_client); +#endif + + G_OBJECT_CLASS (meta_input_settings_x11_parent_class)->dispose (object); +} + +static guint +action_to_button (CDesktopStylusButtonAction action, + guint button) +{ + switch (action) + { + case C_DESKTOP_STYLUS_BUTTON_ACTION_MIDDLE: + return CLUTTER_BUTTON_MIDDLE; + case C_DESKTOP_STYLUS_BUTTON_ACTION_RIGHT: + return CLUTTER_BUTTON_SECONDARY; + case C_DESKTOP_STYLUS_BUTTON_ACTION_BACK: + return 8; + case C_DESKTOP_STYLUS_BUTTON_ACTION_FORWARD: + return 9; + case C_DESKTOP_STYLUS_BUTTON_ACTION_DEFAULT: + default: + return button; + } +} + +static void +meta_input_settings_x11_set_stylus_button_map (MetaInputSettings *settings, + ClutterInputDevice *device, + ClutterInputDeviceTool *tool, + CDesktopStylusButtonAction primary, + CDesktopStylusButtonAction secondary, + CDesktopStylusButtonAction tertiary) +{ + MetaDisplay *display = meta_get_display (); + MetaBackend *backend = meta_get_backend (); + Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); + XDevice *xdev; + + if (!display) + return; + + /* Grab the puke bucket! */ + meta_x11_error_trap_push (display->x11_display); + xdev = device_ensure_xdevice (device); + if (xdev) + { + guchar map[8] = { + CLUTTER_BUTTON_PRIMARY, + action_to_button (primary, CLUTTER_BUTTON_MIDDLE), + action_to_button (secondary, CLUTTER_BUTTON_SECONDARY), + 4, + 5, + 6, + 7, + action_to_button (tertiary, 8), /* "Back" */ + }; + + XSetDeviceButtonMapping (xdisplay, xdev, map, G_N_ELEMENTS (map)); + } + + if (meta_x11_error_trap_pop_with_return (display->x11_display)) + { + g_warning ("Could not set stylus button map for %s", + clutter_input_device_get_device_name (device)); + } +} + +static void +meta_input_settings_x11_set_mouse_middle_click_emulation (MetaInputSettings *settings, + ClutterInputDevice *device, + gboolean enabled) +{ + guchar value = enabled ? 1 : 0; + + if (!is_mouse (settings, device)) + return; + + change_property (device, "libinput Middle Click Emulation Enabled", + XA_INTEGER, 8, &value, 1); +} + +static void +meta_input_settings_x11_set_touchpad_middle_click_emulation (MetaInputSettings *settings, + ClutterInputDevice *device, + gboolean enabled) +{ + guchar value = enabled ? 1 : 0; + + if (!meta_input_settings_x11_is_touchpad_device (settings, device)) + return; + + change_property (device, "libinput Middle Click Emulation Enabled", + XA_INTEGER, 8, &value, 1); +} + +static void +meta_input_settings_x11_set_trackball_middle_click_emulation (MetaInputSettings *settings, + ClutterInputDevice *device, + gboolean enabled) +{ + guchar value = enabled ? 1 : 0; + + if (!meta_input_settings_x11_is_trackball_device (settings, device)) + return; + + change_property (device, "libinput Middle Click Emulation Enabled", + XA_INTEGER, 8, &value, 1); +} + +static void +meta_input_settings_x11_set_stylus_pressure (MetaInputSettings *settings, + ClutterInputDevice *device, + ClutterInputDeviceTool *tool, + const gint32 pressure[4]) +{ + guint32 values[4] = { pressure[0], pressure[1], pressure[2], pressure[3] }; + + change_property (device, "Wacom Pressurecurve", XA_INTEGER, 32, + &values, G_N_ELEMENTS (values)); +} + +static void +meta_input_settings_x11_class_init (MetaInputSettingsX11Class *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MetaInputSettingsClass *input_settings_class = META_INPUT_SETTINGS_CLASS (klass); + + object_class->dispose = meta_input_settings_x11_dispose; + + input_settings_class->set_send_events = meta_input_settings_x11_set_send_events; + input_settings_class->set_matrix = meta_input_settings_x11_set_matrix; + input_settings_class->set_speed = meta_input_settings_x11_set_speed; + input_settings_class->set_left_handed = meta_input_settings_x11_set_left_handed; + input_settings_class->set_tap_enabled = meta_input_settings_x11_set_tap_enabled; + input_settings_class->set_tap_and_drag_enabled = meta_input_settings_x11_set_tap_and_drag_enabled; + input_settings_class->set_disable_while_typing = meta_input_settings_x11_set_disable_while_typing; + input_settings_class->set_invert_scroll = meta_input_settings_x11_set_invert_scroll; + input_settings_class->set_edge_scroll = meta_input_settings_x11_set_edge_scroll; + input_settings_class->set_two_finger_scroll = meta_input_settings_x11_set_two_finger_scroll; + input_settings_class->set_scroll_button = meta_input_settings_x11_set_scroll_button; + input_settings_class->set_click_method = meta_input_settings_x11_set_click_method; + input_settings_class->set_keyboard_repeat = meta_input_settings_x11_set_keyboard_repeat; + + input_settings_class->set_tablet_mapping = meta_input_settings_x11_set_tablet_mapping; + input_settings_class->set_tablet_keep_aspect = meta_input_settings_x11_set_tablet_keep_aspect; + input_settings_class->set_tablet_area = meta_input_settings_x11_set_tablet_area; + + input_settings_class->set_mouse_accel_profile = meta_input_settings_x11_set_mouse_accel_profile; + input_settings_class->set_trackball_accel_profile = meta_input_settings_x11_set_trackball_accel_profile; + + input_settings_class->set_stylus_pressure = meta_input_settings_x11_set_stylus_pressure; + input_settings_class->set_stylus_button_map = meta_input_settings_x11_set_stylus_button_map; + + input_settings_class->set_mouse_middle_click_emulation = meta_input_settings_x11_set_mouse_middle_click_emulation; + input_settings_class->set_touchpad_middle_click_emulation = meta_input_settings_x11_set_touchpad_middle_click_emulation; + input_settings_class->set_trackball_middle_click_emulation = meta_input_settings_x11_set_trackball_middle_click_emulation; + + input_settings_class->has_two_finger_scroll = meta_input_settings_x11_has_two_finger_scroll; + input_settings_class->is_trackball_device = meta_input_settings_x11_is_trackball_device; +} + +static void +meta_input_settings_x11_init (MetaInputSettingsX11 *settings) +{ +#ifdef HAVE_LIBGUDEV + MetaInputSettingsX11Private *priv = + meta_input_settings_x11_get_instance_private (settings); + const char *subsystems[] = { NULL }; + + priv->udev_client = g_udev_client_new (subsystems); +#endif +} diff --git a/src/backends/x11/meta-input-settings-x11.h b/src/backends/x11/meta-input-settings-x11.h new file mode 100644 index 000000000..2780bb224 --- /dev/null +++ b/src/backends/x11/meta-input-settings-x11.h @@ -0,0 +1,49 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright 2014 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef META_INPUT_SETTINGS_X11_H +#define META_INPUT_SETTINGS_X11_H + +#include "backends/meta-input-settings-private.h" + +#define META_TYPE_INPUT_SETTINGS_X11 (meta_input_settings_x11_get_type ()) +#define META_INPUT_SETTINGS_X11(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_INPUT_SETTINGS_X11, MetaInputSettingsX11)) +#define META_INPUT_SETTINGS_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_INPUT_SETTINGS_X11, MetaInputSettingsX11Class)) +#define META_IS_INPUT_SETTINGS_X11(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_INPUT_SETTINGS_X11)) +#define META_IS_INPUT_SETTINGS_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_INPUT_SETTINGS_X11)) +#define META_INPUT_SETTINGS_X11_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_INPUT_SETTINGS_X11, MetaInputSettingsX11Class)) + +typedef struct _MetaInputSettingsX11 MetaInputSettingsX11; +typedef struct _MetaInputSettingsX11Class MetaInputSettingsX11Class; + +struct _MetaInputSettingsX11 +{ + MetaInputSettings parent_instance; +}; + +struct _MetaInputSettingsX11Class +{ + MetaInputSettingsClass parent_class; +}; + +GType meta_input_settings_x11_get_type (void) G_GNUC_CONST; + +#endif /* META_INPUT_SETTINGS_X11_H */ diff --git a/src/backends/x11/meta-keymap-x11.c b/src/backends/x11/meta-keymap-x11.c new file mode 100644 index 000000000..ac2b1d787 --- /dev/null +++ b/src/backends/x11/meta-keymap-x11.c @@ -0,0 +1,954 @@ +/* + * Clutter. + * + * An OpenGL based 'interactive canvas' library. + * + * Copyright (C) 2010 Intel Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Author: Emmanuele Bassi <ebassi@linux.intel.com> + */ + +#include "config.h" + +#include <X11/Xatom.h> +#include <X11/XKBlib.h> + +#include "backends/x11/meta-keymap-x11.h" +#include "clutter/clutter.h" +#include "clutter/clutter-mutter.h" +#include "clutter/x11/clutter-x11.h" + +typedef struct _DirectionCacheEntry DirectionCacheEntry; +typedef struct _ClutterKeymapKey ClutterKeymapKey; + +struct _ClutterKeymapKey +{ + uint32_t keycode; + uint32_t group; + uint32_t level; +}; + +struct _DirectionCacheEntry +{ + uint32_t serial; + Atom group_atom; + PangoDirection direction; +}; + +struct _MetaKeymapX11 +{ + ClutterKeymap parent_instance; + + ClutterBackend *backend; + + int min_keycode; + int max_keycode; + + ClutterModifierType modmap[8]; + + ClutterModifierType num_lock_mask; + ClutterModifierType scroll_lock_mask; + ClutterModifierType level3_shift_mask; + + PangoDirection current_direction; + + XkbDescPtr xkb_desc; + int xkb_event_base; + uint32_t xkb_map_serial; + Atom current_group_atom; + uint32_t current_cache_serial; + DirectionCacheEntry group_direction_cache[4]; + int current_group; + + GHashTable *reserved_keycodes; + GQueue *available_keycodes; + + uint32_t keymap_serial; + + uint32_t caps_lock_state : 1; + uint32_t num_lock_state : 1; + uint32_t has_direction : 1; + + uint32_t use_xkb : 1; + uint32_t have_xkb_autorepeat : 1; +}; + +enum +{ + PROP_0, + + PROP_BACKEND, + + PROP_LAST +}; + +static GParamSpec *obj_props[PROP_LAST] = { NULL, }; + +G_DEFINE_TYPE (MetaKeymapX11, meta_keymap_x11, CLUTTER_TYPE_KEYMAP) + +/* code adapted from gdk/x11/gdkkeys-x11.c - update_modmap */ +static void +update_modmap (Display *display, + MetaKeymapX11 *keymap_x11) +{ + static struct { + const char *name; + Atom atom; + ClutterModifierType mask; + } vmods[] = { + { "Meta", 0, CLUTTER_META_MASK }, + { "Super", 0, CLUTTER_SUPER_MASK }, + { "Hyper", 0, CLUTTER_HYPER_MASK }, + { NULL, 0, 0 } + }; + + int i, j, k; + + if (vmods[0].atom == 0) + for (i = 0; vmods[i].name; i++) + vmods[i].atom = XInternAtom (display, vmods[i].name, FALSE); + + for (i = 0; i < 8; i++) + keymap_x11->modmap[i] = 1 << i; + + for (i = 0; i < XkbNumVirtualMods; i++) + { + for (j = 0; vmods[j].atom; j++) + { + if (keymap_x11->xkb_desc->names->vmods[i] == vmods[j].atom) + { + for (k = 0; k < 8; k++) + { + if (keymap_x11->xkb_desc->server->vmods[i] & (1 << k)) + keymap_x11->modmap[k] |= vmods[j].mask; + } + } + } + } +} + +static XkbDescPtr +get_xkb (MetaKeymapX11 *keymap_x11) +{ + Display *xdisplay = clutter_x11_get_default_display (); + + if (keymap_x11->max_keycode == 0) + XDisplayKeycodes (xdisplay, + &keymap_x11->min_keycode, + &keymap_x11->max_keycode); + + if (keymap_x11->xkb_desc == NULL) + { + int flags = XkbKeySymsMask + | XkbKeyTypesMask + | XkbModifierMapMask + | XkbVirtualModsMask; + + keymap_x11->xkb_desc = XkbGetMap (xdisplay, flags, XkbUseCoreKbd); + if (G_UNLIKELY (keymap_x11->xkb_desc == NULL)) + { + g_error ("Failed to get the keymap from XKB"); + return NULL; + } + + flags = XkbGroupNamesMask | XkbVirtualModNamesMask; + XkbGetNames (xdisplay, flags, keymap_x11->xkb_desc); + + update_modmap (xdisplay, keymap_x11); + } + else if (keymap_x11->xkb_map_serial != keymap_x11->keymap_serial) + { + int flags = XkbKeySymsMask + | XkbKeyTypesMask + | XkbModifierMapMask + | XkbVirtualModsMask; + + XkbGetUpdatedMap (xdisplay, flags, keymap_x11->xkb_desc); + + flags = XkbGroupNamesMask | XkbVirtualModNamesMask; + XkbGetNames (xdisplay, flags, keymap_x11->xkb_desc); + + update_modmap (xdisplay, keymap_x11); + + keymap_x11->xkb_map_serial = keymap_x11->keymap_serial; + } + + if (keymap_x11->num_lock_mask == 0) + keymap_x11->num_lock_mask = XkbKeysymToModifiers (xdisplay, XK_Num_Lock); + + if (keymap_x11->scroll_lock_mask == 0) + keymap_x11->scroll_lock_mask = XkbKeysymToModifiers (xdisplay, + XK_Scroll_Lock); + if (keymap_x11->level3_shift_mask == 0) + keymap_x11->level3_shift_mask = XkbKeysymToModifiers (xdisplay, + XK_ISO_Level3_Shift); + + return keymap_x11->xkb_desc; +} + +static void +update_locked_mods (MetaKeymapX11 *keymap_x11, + int locked_mods) +{ + gboolean old_caps_lock_state, old_num_lock_state; + + old_caps_lock_state = keymap_x11->caps_lock_state; + old_num_lock_state = keymap_x11->num_lock_state; + + keymap_x11->caps_lock_state = (locked_mods & CLUTTER_LOCK_MASK) != 0; + keymap_x11->num_lock_state = (locked_mods & keymap_x11->num_lock_mask) != 0; + + g_debug ("Locks state changed - Num: %s, Caps: %s", + keymap_x11->num_lock_state ? "set" : "unset", + keymap_x11->caps_lock_state ? "set" : "unset"); + + if ((keymap_x11->caps_lock_state != old_caps_lock_state) || + (keymap_x11->num_lock_state != old_num_lock_state)) + g_signal_emit_by_name (keymap_x11, "state-changed"); +} + +/* the code to retrieve the keymap direction and cache it + * is taken from GDK: + * gdk/x11/gdkkeys-x11.c + */ +static PangoDirection +get_direction (XkbDescPtr xkb, + int group) +{ + int rtl_minus_ltr = 0; /* total number of RTL keysyms minus LTR ones */ + int code; + + for (code = xkb->min_key_code; + code <= xkb->max_key_code; + code += 1) + { + int level = 0; + KeySym sym = XkbKeySymEntry (xkb, code, level, group); + PangoDirection dir = + _clutter_pango_unichar_direction (clutter_keysym_to_unicode (sym)); + + switch (dir) + { + case PANGO_DIRECTION_RTL: + rtl_minus_ltr++; + break; + + case PANGO_DIRECTION_LTR: + rtl_minus_ltr--; + break; + + default: + break; + } + } + + if (rtl_minus_ltr > 0) + return PANGO_DIRECTION_RTL; + + return PANGO_DIRECTION_LTR; +} + +static PangoDirection +get_direction_from_cache (MetaKeymapX11 *keymap_x11, + XkbDescPtr xkb, + int group) +{ + Atom group_atom = xkb->names->groups[group]; + gboolean cache_hit = FALSE; + DirectionCacheEntry *cache = keymap_x11->group_direction_cache; + PangoDirection direction = PANGO_DIRECTION_NEUTRAL; + int i; + + if (keymap_x11->has_direction) + { + /* look up in the cache */ + for (i = 0; i < G_N_ELEMENTS (keymap_x11->group_direction_cache); i++) + { + if (cache[i].group_atom == group_atom) + { + cache_hit = TRUE; + cache[i].serial = keymap_x11->current_cache_serial++; + direction = cache[i].direction; + group_atom = cache[i].group_atom; + break; + } + } + } + else + { + /* initialize the cache */ + for (i = 0; i < G_N_ELEMENTS (keymap_x11->group_direction_cache); i++) + { + cache[i].group_atom = 0; + cache[i].direction = PANGO_DIRECTION_NEUTRAL; + cache[i].serial = keymap_x11->current_cache_serial; + } + + keymap_x11->current_cache_serial += 1; + } + + /* insert the new entry in the cache */ + if (!cache_hit) + { + int oldest = 0; + + direction = get_direction (xkb, group); + + /* replace the oldest entry */ + for (i = 0; i < G_N_ELEMENTS (keymap_x11->group_direction_cache); i++) + { + if (cache[i].serial < cache[oldest].serial) + oldest = i; + } + + cache[oldest].group_atom = group_atom; + cache[oldest].direction = direction; + cache[oldest].serial = keymap_x11->current_cache_serial++; + } + + return direction; +} + +static void +update_direction (MetaKeymapX11 *keymap_x11, + int group) +{ + XkbDescPtr xkb = get_xkb (keymap_x11); + Atom group_atom; + + group_atom = xkb->names->groups[group]; + + if (!keymap_x11->has_direction || keymap_x11->current_group_atom != group_atom) + { + keymap_x11->current_direction = get_direction_from_cache (keymap_x11, xkb, group); + keymap_x11->current_group_atom = group_atom; + keymap_x11->has_direction = TRUE; + } +} + +static void +meta_keymap_x11_constructed (GObject *object) +{ + MetaKeymapX11 *keymap_x11 = META_KEYMAP_X11 (object); + Display *xdisplay = clutter_x11_get_default_display (); + int xkb_major = XkbMajorVersion; + int xkb_minor = XkbMinorVersion; + + g_assert (keymap_x11->backend != NULL); + + if (XkbLibraryVersion (&xkb_major, &xkb_minor)) + { + xkb_major = XkbMajorVersion; + xkb_minor = XkbMinorVersion; + + if (XkbQueryExtension (xdisplay, + NULL, + &keymap_x11->xkb_event_base, + NULL, + &xkb_major, &xkb_minor)) + { + Bool detectable_autorepeat_supported; + + keymap_x11->use_xkb = TRUE; + + XkbSelectEvents (xdisplay, + XkbUseCoreKbd, + XkbNewKeyboardNotifyMask | XkbMapNotifyMask | XkbStateNotifyMask, + XkbNewKeyboardNotifyMask | XkbMapNotifyMask | XkbStateNotifyMask); + + XkbSelectEventDetails (xdisplay, + XkbUseCoreKbd, XkbStateNotify, + XkbAllStateComponentsMask, + XkbGroupLockMask | XkbModifierLockMask); + + /* enable XKB autorepeat */ + XkbSetDetectableAutoRepeat (xdisplay, + True, + &detectable_autorepeat_supported); + + keymap_x11->have_xkb_autorepeat = detectable_autorepeat_supported; + } + } +} + +static void +meta_keymap_x11_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaKeymapX11 *keymap = META_KEYMAP_X11 (object); + + switch (prop_id) + { + case PROP_BACKEND: + keymap->backend = g_value_get_object (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_keymap_x11_refresh_reserved_keycodes (MetaKeymapX11 *keymap_x11) +{ + Display *dpy = clutter_x11_get_default_display (); + GHashTableIter iter; + gpointer key, value; + + g_hash_table_iter_init (&iter, keymap_x11->reserved_keycodes); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + uint32_t reserved_keycode = GPOINTER_TO_UINT (key); + uint32_t reserved_keysym = GPOINTER_TO_UINT (value); + uint32_t actual_keysym = XkbKeycodeToKeysym (dpy, reserved_keycode, 0, 0); + + /* If an available keycode is no longer mapped to the stored keysym, then + * the keycode should not be considered available anymore and should be + * removed both from the list of available and reserved keycodes. + */ + if (reserved_keysym != actual_keysym) + { + g_hash_table_iter_remove (&iter); + g_queue_remove (keymap_x11->available_keycodes, key); + } + } +} + +static gboolean +meta_keymap_x11_replace_keycode (MetaKeymapX11 *keymap_x11, + KeyCode keycode, + KeySym keysym) +{ + if (keymap_x11->use_xkb) + { + Display *dpy = clutter_x11_get_default_display (); + XkbDescPtr xkb = get_xkb (keymap_x11); + XkbMapChangesRec changes; + + XFlush (dpy); + + xkb->device_spec = XkbUseCoreKbd; + memset (&changes, 0, sizeof(changes)); + + if (keysym != NoSymbol) + { + int types[XkbNumKbdGroups] = { XkbOneLevelIndex }; + XkbChangeTypesOfKey (xkb, keycode, 1, XkbGroup1Mask, types, &changes); + XkbKeySymEntry (xkb, keycode, 0, 0) = keysym; + } + else + { + /* Reset to NoSymbol */ + XkbChangeTypesOfKey (xkb, keycode, 0, XkbGroup1Mask, NULL, &changes); + } + + changes.changed = XkbKeySymsMask | XkbKeyTypesMask; + changes.first_key_sym = keycode; + changes.num_key_syms = 1; + changes.first_type = 0; + changes.num_types = xkb->map->num_types; + XkbChangeMap (dpy, xkb, &changes); + + XFlush (dpy); + + return TRUE; + } + + return FALSE; +} + +static void +meta_keymap_x11_finalize (GObject *object) +{ + MetaKeymapX11 *keymap; + GHashTableIter iter; + gpointer key, value; + + keymap = META_KEYMAP_X11 (object); + + meta_keymap_x11_refresh_reserved_keycodes (keymap); + g_hash_table_iter_init (&iter, keymap->reserved_keycodes); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + uint32_t keycode = GPOINTER_TO_UINT (key); + meta_keymap_x11_replace_keycode (keymap, keycode, NoSymbol); + } + + g_hash_table_destroy (keymap->reserved_keycodes); + g_queue_free (keymap->available_keycodes); + + if (keymap->xkb_desc != NULL) + XkbFreeKeyboard (keymap->xkb_desc, XkbAllComponentsMask, True); + + G_OBJECT_CLASS (meta_keymap_x11_parent_class)->finalize (object); +} + +static gboolean +meta_keymap_x11_get_num_lock_state (ClutterKeymap *keymap) +{ + MetaKeymapX11 *keymap_x11 = META_KEYMAP_X11 (keymap); + + return keymap_x11->num_lock_state; +} + +static gboolean +meta_keymap_x11_get_caps_lock_state (ClutterKeymap *keymap) +{ + MetaKeymapX11 *keymap_x11 = META_KEYMAP_X11 (keymap); + + return keymap_x11->caps_lock_state; +} + +static PangoDirection +meta_keymap_x11_get_direction (ClutterKeymap *keymap) +{ + MetaKeymapX11 *keymap_x11; + + g_return_val_if_fail (META_IS_KEYMAP_X11 (keymap), PANGO_DIRECTION_NEUTRAL); + + keymap_x11 = META_KEYMAP_X11 (keymap); + + if (keymap_x11->use_xkb) + { + if (!keymap_x11->has_direction) + { + XkbStateRec state_rec; + + XkbGetState (clutter_x11_get_default_display (), + XkbUseCoreKbd, &state_rec); + update_direction (keymap_x11, XkbStateGroup (&state_rec)); + } + + return keymap_x11->current_direction; + } + else + { + return PANGO_DIRECTION_NEUTRAL; + } +} + +static void +meta_keymap_x11_class_init (MetaKeymapX11Class *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + ClutterKeymapClass *keymap_class = CLUTTER_KEYMAP_CLASS (klass); + + obj_props[PROP_BACKEND] = + g_param_spec_object ("backend", + "Backend", + "The Clutter backend", + CLUTTER_TYPE_BACKEND, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY); + + gobject_class->constructed = meta_keymap_x11_constructed; + gobject_class->set_property = meta_keymap_x11_set_property; + gobject_class->finalize = meta_keymap_x11_finalize; + + keymap_class->get_num_lock_state = meta_keymap_x11_get_num_lock_state; + keymap_class->get_caps_lock_state = meta_keymap_x11_get_caps_lock_state; + keymap_class->get_direction = meta_keymap_x11_get_direction; + + g_object_class_install_properties (gobject_class, PROP_LAST, obj_props); +} + +static void +meta_keymap_x11_init (MetaKeymapX11 *keymap) +{ + keymap->current_direction = PANGO_DIRECTION_NEUTRAL; + keymap->current_group = -1; + keymap->reserved_keycodes = g_hash_table_new (NULL, NULL); + keymap->available_keycodes = g_queue_new (); +} + +gboolean +meta_keymap_x11_handle_event (MetaKeymapX11 *keymap_x11, + XEvent *xevent) +{ + gboolean retval; + + if (!keymap_x11->use_xkb) + return FALSE; + + retval = FALSE; + + if (xevent->type == keymap_x11->xkb_event_base) + { + XkbEvent *xkb_event = (XkbEvent *) xevent; + + switch (xkb_event->any.xkb_type) + { + case XkbStateNotify: + g_debug ("Updating keyboard state"); + keymap_x11->current_group = XkbStateGroup (&xkb_event->state); + update_direction (keymap_x11, keymap_x11->current_group); + update_locked_mods (keymap_x11, xkb_event->state.locked_mods); + retval = TRUE; + break; + + case XkbNewKeyboardNotify: + case XkbMapNotify: + g_debug ("Updating keyboard mapping"); + XkbRefreshKeyboardMapping (&xkb_event->map); + keymap_x11->keymap_serial += 1; + retval = TRUE; + break; + + default: + break; + } + } + else if (xevent->type == MappingNotify) + { + XRefreshKeyboardMapping (&xevent->xmapping); + keymap_x11->keymap_serial += 1; + retval = TRUE; + } + + return retval; +} + +int +meta_keymap_x11_get_key_group (MetaKeymapX11 *keymap, + ClutterModifierType state) +{ + return XkbGroupForCoreState (state); +} + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + +/* XXX - yes, I know that XKeycodeToKeysym() has been deprecated; hopefully, + * this code will never get run on any decent system that is also able to + * run Clutter. I just don't want to copy the implementation inside GDK for + * a fallback path. + */ +static int +translate_keysym (MetaKeymapX11 *keymap, + uint32_t hardware_keycode) +{ + int retval; + + retval = XKeycodeToKeysym (clutter_x11_get_default_display (), + hardware_keycode, 0); + return retval; +} + +G_GNUC_END_IGNORE_DEPRECATIONS + +int +meta_keymap_x11_translate_key_state (MetaKeymapX11 *keymap, + uint32_t hardware_keycode, + ClutterModifierType *modifier_state_p, + ClutterModifierType *mods_p) +{ + ClutterModifierType unconsumed_modifiers = 0; + ClutterModifierType modifier_state = *modifier_state_p; + int retval; + + g_return_val_if_fail (META_IS_KEYMAP_X11 (keymap), 0); + + if (keymap->use_xkb) + { + XkbDescRec *xkb = get_xkb (keymap); + KeySym tmp_keysym; + + if (XkbTranslateKeyCode (xkb, hardware_keycode, modifier_state, + &unconsumed_modifiers, + &tmp_keysym)) + { + retval = tmp_keysym; + } + else + retval = 0; + } + else + retval = translate_keysym (keymap, hardware_keycode); + + if (mods_p) + *mods_p = unconsumed_modifiers; + + *modifier_state_p = modifier_state & ~(keymap->num_lock_mask | + keymap->scroll_lock_mask | + LockMask); + + return retval; +} + +gboolean +meta_keymap_x11_get_is_modifier (MetaKeymapX11 *keymap, + int keycode) +{ + g_return_val_if_fail (META_IS_KEYMAP_X11 (keymap), FALSE); + + if (keycode < keymap->min_keycode || keycode > keymap->max_keycode) + return FALSE; + + if (keymap->use_xkb) + { + XkbDescRec *xkb = get_xkb (keymap); + + if (xkb->map->modmap && xkb->map->modmap[keycode] != 0) + return TRUE; + } + + return FALSE; +} + +static gboolean +meta_keymap_x11_get_entries_for_keyval (MetaKeymapX11 *keymap_x11, + uint32_t keyval, + ClutterKeymapKey **keys, + int *n_keys) +{ + if (keymap_x11->use_xkb) + { + XkbDescRec *xkb = get_xkb (keymap_x11); + GArray *retval; + int keycode; + + keycode = keymap_x11->min_keycode; + retval = g_array_new (FALSE, FALSE, sizeof (ClutterKeymapKey)); + + while (keycode <= keymap_x11->max_keycode) + { + int max_shift_levels = XkbKeyGroupsWidth (xkb, keycode); + int group = 0; + int level = 0; + int total_syms = XkbKeyNumSyms (xkb, keycode); + int i = 0; + KeySym *entry; + + /* entry is an array with all syms for group 0, all + * syms for group 1, etc. and for each group the + * shift level syms are in order + */ + entry = XkbKeySymsPtr (xkb, keycode); + + while (i < total_syms) + { + g_assert (i == (group * max_shift_levels + level)); + + if (entry[i] == keyval) + { + ClutterKeymapKey key; + + key.keycode = keycode; + key.group = group; + key.level = level; + + g_array_append_val (retval, key); + + g_assert (XkbKeySymEntry (xkb, keycode, level, group) == + keyval); + } + + ++level; + + if (level == max_shift_levels) + { + level = 0; + ++group; + } + + ++i; + } + + ++keycode; + } + + if (retval->len > 0) + { + *keys = (ClutterKeymapKey*) retval->data; + *n_keys = retval->len; + } + else + { + *keys = NULL; + *n_keys = 0; + } + + g_array_free (retval, retval->len > 0 ? FALSE : TRUE); + + return *n_keys > 0; + } + else + { + return FALSE; + } +} + +static uint32_t +meta_keymap_x11_get_available_keycode (MetaKeymapX11 *keymap_x11) +{ + if (keymap_x11->use_xkb) + { + meta_keymap_x11_refresh_reserved_keycodes (keymap_x11); + + if (g_hash_table_size (keymap_x11->reserved_keycodes) < 5) + { + Display *dpy = clutter_x11_get_default_display (); + XkbDescPtr xkb = get_xkb (keymap_x11); + uint32_t i; + + for (i = xkb->max_key_code; i >= xkb->min_key_code; --i) + { + if (XkbKeycodeToKeysym (dpy, i, 0, 0) == NoSymbol) + return i; + } + } + + return GPOINTER_TO_UINT (g_queue_pop_head (keymap_x11->available_keycodes)); + } + + return 0; +} + +gboolean +meta_keymap_x11_reserve_keycode (MetaKeymapX11 *keymap_x11, + uint32_t keyval, + uint32_t *keycode_out) +{ + g_return_val_if_fail (META_IS_KEYMAP_X11 (keymap_x11), FALSE); + g_return_val_if_fail (keyval != 0, FALSE); + g_return_val_if_fail (keycode_out != NULL, FALSE); + + *keycode_out = meta_keymap_x11_get_available_keycode (keymap_x11); + + if (*keycode_out == NoSymbol) + { + g_warning ("Cannot reserve a keycode for keyval %d: no available keycode", keyval); + return FALSE; + } + + if (!meta_keymap_x11_replace_keycode (keymap_x11, *keycode_out, keyval)) + { + g_warning ("Failed to remap keycode %d to keyval %d", *keycode_out, keyval); + return FALSE; + } + + g_hash_table_insert (keymap_x11->reserved_keycodes, GUINT_TO_POINTER (*keycode_out), GUINT_TO_POINTER (keyval)); + g_queue_remove (keymap_x11->available_keycodes, GUINT_TO_POINTER (*keycode_out)); + + return TRUE; +} + +void +meta_keymap_x11_release_keycode_if_needed (MetaKeymapX11 *keymap_x11, + uint32_t keycode) +{ + g_return_if_fail (META_IS_KEYMAP_X11 (keymap_x11)); + + if (!g_hash_table_contains (keymap_x11->reserved_keycodes, GUINT_TO_POINTER (keycode)) || + g_queue_index (keymap_x11->available_keycodes, GUINT_TO_POINTER (keycode)) != -1) + return; + + g_queue_push_tail (keymap_x11->available_keycodes, GUINT_TO_POINTER (keycode)); +} + +void +meta_keymap_x11_latch_modifiers (MetaKeymapX11 *keymap_x11, + uint32_t level, + gboolean enable) +{ + uint32_t modifiers[] = { + 0, + ShiftMask, + keymap_x11->level3_shift_mask, + keymap_x11->level3_shift_mask | ShiftMask, + }; + uint32_t value = 0; + + if (!keymap_x11->use_xkb) + return; + + level = CLAMP (level, 0, G_N_ELEMENTS (modifiers) - 1); + + if (enable) + value = modifiers[level]; + else + value = 0; + + XkbLatchModifiers (clutter_x11_get_default_display (), + XkbUseCoreKbd, modifiers[level], + value); +} + +static uint32_t +meta_keymap_x11_get_current_group (MetaKeymapX11 *keymap_x11) +{ + XkbStateRec state_rec; + + if (keymap_x11->current_group >= 0) + return keymap_x11->current_group; + + XkbGetState (clutter_x11_get_default_display (), + XkbUseCoreKbd, &state_rec); + return XkbStateGroup (&state_rec); +} + +gboolean +meta_keymap_x11_keycode_for_keyval (MetaKeymapX11 *keymap_x11, + uint32_t keyval, + uint32_t *keycode_out, + uint32_t *level_out) +{ + ClutterKeymapKey *keys; + int i, n_keys, group; + gboolean found = FALSE; + + g_return_val_if_fail (keycode_out != NULL, FALSE); + g_return_val_if_fail (level_out != NULL, FALSE); + + group = meta_keymap_x11_get_current_group (keymap_x11); + + if (!meta_keymap_x11_get_entries_for_keyval (keymap_x11, keyval, &keys, &n_keys)) + return FALSE; + + for (i = 0; i < n_keys && !found; i++) + { + if (keys[i].group == group) + { + *keycode_out = keys[i].keycode; + *level_out = keys[i].level; + found = TRUE; + } + } + + if (!found) + { + GHashTableIter iter; + gpointer key, value; + + g_hash_table_iter_init (&iter, keymap_x11->reserved_keycodes); + while (!found && g_hash_table_iter_next (&iter, &key, &value)) + { + uint32_t reserved_keycode = GPOINTER_TO_UINT (key); + uint32_t reserved_keysym = GPOINTER_TO_UINT (value); + + if (keyval == reserved_keysym) + { + *keycode_out = reserved_keycode; + *level_out = 0; + found = TRUE; + } + } + } + + g_free (keys); + return found; +} diff --git a/src/backends/x11/meta-keymap-x11.h b/src/backends/x11/meta-keymap-x11.h new file mode 100644 index 000000000..67a5f8eb9 --- /dev/null +++ b/src/backends/x11/meta-keymap-x11.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2009 Intel Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Author: Emmanuele Bassi <ebassi@linux.intel.com> + */ + +#ifndef META_KEYMAP_X11_H +#define META_KEYMAP_X11_H + +#include <glib-object.h> +#include <pango/pango.h> + +#include "clutter/clutter.h" + +G_BEGIN_DECLS + +#define META_TYPE_KEYMAP_X11 (meta_keymap_x11_get_type ()) +G_DECLARE_FINAL_TYPE (MetaKeymapX11, meta_keymap_x11, + META, KEYMAP_X11, ClutterKeymap) + +int meta_keymap_x11_get_key_group (MetaKeymapX11 *keymap, + ClutterModifierType state); +int meta_keymap_x11_translate_key_state (MetaKeymapX11 *keymap, + guint hardware_keycode, + ClutterModifierType *modifier_state_p, + ClutterModifierType *mods_p); +gboolean meta_keymap_x11_get_is_modifier (MetaKeymapX11 *keymap, + int keycode); + +gboolean meta_keymap_x11_keycode_for_keyval (MetaKeymapX11 *keymap_x11, + guint keyval, + guint *keycode_out, + guint *level_out); +void meta_keymap_x11_latch_modifiers (MetaKeymapX11 *keymap_x11, + uint32_t level, + gboolean enable); +gboolean meta_keymap_x11_reserve_keycode (MetaKeymapX11 *keymap_x11, + guint keyval, + guint *keycode_out); +void meta_keymap_x11_release_keycode_if_needed (MetaKeymapX11 *keymap_x11, + guint keycode); + +gboolean meta_keymap_x11_handle_event (MetaKeymapX11 *keymap_x11, + XEvent *xevent); + +G_END_DECLS + +#endif /* META_KEYMAP_X11_H */ diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c new file mode 100644 index 000000000..0290475a7 --- /dev/null +++ b/src/backends/x11/meta-monitor-manager-xrandr.c @@ -0,0 +1,1446 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001, 2002 Havoc Pennington + * Copyright (C) 2002, 2003 Red Hat Inc. + * Some ICCCM manager selection code derived from fvwm2, + * Copyright (C) 2001 Dominik Vogt, Matthias Clasen, and fvwm2 team + * Copyright (C) 2003 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * Copyright (C) 2013 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +/** + * SECTION:meta-monitor-manager-xrandr + * @title: MetaMonitorManagerXrandr + * @short_description: A subclass of #MetaMonitorManager using XRadR + * + * #MetaMonitorManagerXrandr is a subclass of #MetaMonitorManager which + * implements its functionality using the RandR X protocol. + * + * See also #MetaMonitorManagerKms for a native implementation using Linux DRM + * and udev. + */ + +#include "config.h" + +#include "backends/x11/meta-monitor-manager-xrandr.h" + +#include <math.h> +#include <stdlib.h> +#include <string.h> +#include <X11/Xlib-xcb.h> +#include <X11/Xlibint.h> +#include <X11/extensions/dpms.h> +#include <xcb/randr.h> + +#include "backends/meta-crtc.h" +#include "backends/meta-logical-monitor.h" +#include "backends/meta-monitor-config-manager.h" +#include "backends/meta-output.h" +#include "backends/x11/meta-backend-x11.h" +#include "backends/x11/meta-crtc-xrandr.h" +#include "backends/x11/meta-gpu-xrandr.h" +#include "backends/x11/meta-output-xrandr.h" +#include "clutter/clutter.h" +#include "meta/main.h" +#include "meta/meta-x11-errors.h" + +/* Look for DPI_FALLBACK in: + * http://git.gnome.org/browse/gnome-settings-daemon/tree/plugins/xsettings/gsd-xsettings-manager.c + * for the reasoning */ +#define DPI_FALLBACK 96.0 +#define RANDR_VERSION_FORMAT(major, minor) ((major * 100) + minor) +#define RANDR_TILING_MIN_VERSION RANDR_VERSION_FORMAT (1, 5) +#define RANDR_TRANSFORM_MIN_VERSION RANDR_VERSION_FORMAT (1, 3) + +struct _MetaMonitorManagerXrandr +{ + MetaMonitorManager parent_instance; + + Display *xdisplay; + int rr_event_base; + int rr_error_base; + int randr_version; + + xcb_timestamp_t last_xrandr_set_timestamp; + + GHashTable *tiled_monitor_atoms; + +}; + +static MetaGpu * meta_monitor_manager_xrandr_get_gpu (MetaMonitorManagerXrandr *manager_xrandr); + +struct _MetaMonitorManagerXrandrClass +{ + MetaMonitorManagerClass parent_class; +}; + +G_DEFINE_TYPE (MetaMonitorManagerXrandr, meta_monitor_manager_xrandr, META_TYPE_MONITOR_MANAGER); + +typedef struct _MetaMonitorXrandrData +{ + Atom xrandr_name; +} MetaMonitorXrandrData; + +GQuark quark_meta_monitor_xrandr_data; + +Display * +meta_monitor_manager_xrandr_get_xdisplay (MetaMonitorManagerXrandr *manager_xrandr) +{ + return manager_xrandr->xdisplay; +} + +uint32_t +meta_monitor_manager_xrandr_get_config_timestamp (MetaMonitorManagerXrandr *manager_xrandr) +{ + return manager_xrandr->last_xrandr_set_timestamp; +} + +static GBytes * +meta_monitor_manager_xrandr_read_edid (MetaMonitorManager *manager, + MetaOutput *output) +{ + return meta_output_xrandr_read_edid (output); +} + +static MetaPowerSave +x11_dpms_state_to_power_save (CARD16 dpms_state) +{ + switch (dpms_state) + { + case DPMSModeOn: + return META_POWER_SAVE_ON; + case DPMSModeStandby: + return META_POWER_SAVE_STANDBY; + case DPMSModeSuspend: + return META_POWER_SAVE_SUSPEND; + case DPMSModeOff: + return META_POWER_SAVE_OFF; + default: + return META_POWER_SAVE_UNSUPPORTED; + } +} + +static void +meta_monitor_manager_xrandr_read_current_state (MetaMonitorManager *manager) +{ + MetaMonitorManagerXrandr *manager_xrandr = + META_MONITOR_MANAGER_XRANDR (manager); + MetaMonitorManagerClass *parent_class = + META_MONITOR_MANAGER_CLASS (meta_monitor_manager_xrandr_parent_class); + Display *xdisplay = meta_monitor_manager_xrandr_get_xdisplay (manager_xrandr); + BOOL dpms_capable, dpms_enabled; + CARD16 dpms_state; + MetaPowerSave power_save_mode; + + dpms_capable = DPMSCapable (xdisplay); + + if (dpms_capable && + DPMSInfo (xdisplay, &dpms_state, &dpms_enabled) && + dpms_enabled) + power_save_mode = x11_dpms_state_to_power_save (dpms_state); + else + power_save_mode = META_POWER_SAVE_UNSUPPORTED; + + meta_monitor_manager_power_save_mode_changed (manager, power_save_mode); + + parent_class->read_current_state (manager); +} + +static void +meta_monitor_manager_xrandr_set_power_save_mode (MetaMonitorManager *manager, + MetaPowerSave mode) +{ + MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager); + CARD16 state; + + switch (mode) { + case META_POWER_SAVE_ON: + state = DPMSModeOn; + break; + case META_POWER_SAVE_STANDBY: + state = DPMSModeStandby; + break; + case META_POWER_SAVE_SUSPEND: + state = DPMSModeSuspend; + break; + case META_POWER_SAVE_OFF: + state = DPMSModeOff; + break; + default: + return; + } + + DPMSForceLevel (manager_xrandr->xdisplay, state); + DPMSSetTimeouts (manager_xrandr->xdisplay, 0, 0, 0); +} + +static void +meta_monitor_manager_xrandr_update_screen_size (MetaMonitorManagerXrandr *manager_xrandr, + int width, + int height, + float scale) +{ + MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr); + MetaGpu *gpu = meta_monitor_manager_xrandr_get_gpu (manager_xrandr); + xcb_connection_t *xcb_conn; + xcb_generic_error_t *xcb_error; + xcb_void_cookie_t xcb_cookie; + Screen *screen; + int min_width; + int min_height; + int max_width; + int max_height; + int width_mm; + int height_mm; + + g_assert (width > 0 && height > 0 && scale > 0); + + if (manager->screen_width == width && manager->screen_height == height) + return; + + screen = ScreenOfDisplay (manager_xrandr->xdisplay, + DefaultScreen (manager_xrandr->xdisplay)); + meta_gpu_xrandr_get_min_screen_size (META_GPU_XRANDR (gpu), + &min_width, &min_height); + meta_gpu_xrandr_get_max_screen_size (META_GPU_XRANDR (gpu), + &max_width, &max_height); + width = MIN (MAX (min_width, width), max_width); + height = MIN (MAX (min_height, height), max_height); + + /* The 'physical size' of an X screen is meaningless if that screen can + * consist of many monitors. So just pick a size that make the dpi 96. + * + * Firefox and Evince apparently believe what X tells them. + */ + width_mm = (width / (DPI_FALLBACK * scale)) * 25.4 + 0.5; + height_mm = (height / (DPI_FALLBACK * scale)) * 25.4 + 0.5; + + if (width == WidthOfScreen (screen) && height == HeightOfScreen (screen) && + width_mm == WidthMMOfScreen (screen) && height_mm == HeightMMOfScreen (screen)) + return; + + xcb_conn = XGetXCBConnection (manager_xrandr->xdisplay); + + xcb_grab_server (xcb_conn); + + /* Some drivers (nvidia I look at you!) might no advertise some CRTCs, so in + * such case, we may ignore X errors here */ + xcb_cookie = xcb_randr_set_screen_size_checked (xcb_conn, + DefaultRootWindow (manager_xrandr->xdisplay), + width, height, + width_mm, height_mm); + xcb_error = xcb_request_check (xcb_conn, xcb_cookie); + if (!xcb_error) + { + manager->screen_width = width; + manager->screen_height = height; + } + else + { + gchar buf[64]; + + XGetErrorText (manager_xrandr->xdisplay, xcb_error->error_code, buf, + sizeof (buf) - 1); + g_warning ("Impossible to resize screen at size %dx%d, error id %u: %s", + width, height, xcb_error->error_code, buf); + g_clear_pointer (&xcb_error, free); + } + + xcb_ungrab_server (xcb_conn); +} + +static xcb_randr_rotation_t +meta_monitor_transform_to_xrandr (MetaMonitorTransform transform) +{ + switch (transform) + { + case META_MONITOR_TRANSFORM_NORMAL: + return XCB_RANDR_ROTATION_ROTATE_0; + case META_MONITOR_TRANSFORM_90: + return XCB_RANDR_ROTATION_ROTATE_90; + case META_MONITOR_TRANSFORM_180: + return XCB_RANDR_ROTATION_ROTATE_180; + case META_MONITOR_TRANSFORM_270: + return XCB_RANDR_ROTATION_ROTATE_270; + case META_MONITOR_TRANSFORM_FLIPPED: + return XCB_RANDR_ROTATION_REFLECT_X | XCB_RANDR_ROTATION_ROTATE_0; + case META_MONITOR_TRANSFORM_FLIPPED_90: + return XCB_RANDR_ROTATION_REFLECT_X | XCB_RANDR_ROTATION_ROTATE_90; + case META_MONITOR_TRANSFORM_FLIPPED_180: + return XCB_RANDR_ROTATION_REFLECT_X | XCB_RANDR_ROTATION_ROTATE_180; + case META_MONITOR_TRANSFORM_FLIPPED_270: + return XCB_RANDR_ROTATION_REFLECT_X | XCB_RANDR_ROTATION_ROTATE_270; + } + + g_assert_not_reached (); + return 0; +} + +static gboolean +xrandr_set_crtc_config (MetaMonitorManagerXrandr *manager_xrandr, + MetaCrtc *crtc, + gboolean save_timestamp, + xcb_randr_crtc_t xrandr_crtc, + xcb_timestamp_t timestamp, + int x, + int y, + xcb_randr_mode_t mode, + xcb_randr_rotation_t rotation, + xcb_randr_output_t *outputs, + int n_outputs) +{ + xcb_timestamp_t new_timestamp; + + if (!meta_crtc_xrandr_set_config (crtc, xrandr_crtc, timestamp, + x, y, mode, rotation, + outputs, n_outputs, + &new_timestamp)) + return FALSE; + + if (save_timestamp) + manager_xrandr->last_xrandr_set_timestamp = new_timestamp; + + return TRUE; +} + +static float +get_maximum_crtc_info_scale (MetaCrtcInfo **crtc_infos, + unsigned int n_crtc_infos) +{ + float max_scale = 1.0f; + unsigned int i; + + for (i = 0; i < n_crtc_infos; i++) + { + MetaCrtcInfo *crtc_info = crtc_infos[i]; + + if (crtc_info->mode) + max_scale = MAX (max_scale, crtc_info->scale); + } + + return max_scale; +} + +static gboolean +is_crtc_assignment_changed (MetaMonitorManager *monitor_manager, + MetaCrtc *crtc, + MetaCrtcInfo **crtc_infos, + unsigned int n_crtc_infos, + gboolean *weak_change) +{ + MetaLogicalMonitorLayoutMode layout_mode; + gboolean have_scaling; + float max_crtc_scale = 1.0f; + float max_req_scale = 1.0f; + unsigned int i; + + layout_mode = meta_monitor_manager_get_default_layout_mode (monitor_manager); + have_scaling = meta_monitor_manager_get_capabilities (monitor_manager) & + META_MONITOR_MANAGER_CAPABILITY_NATIVE_OUTPUT_SCALING; + + if (have_scaling && + layout_mode == META_LOGICAL_MONITOR_LAYOUT_MODE_GLOBAL_UI_LOGICAL) + { + max_crtc_scale = + meta_monitor_manager_get_maximum_crtc_scale (monitor_manager); + max_req_scale = + get_maximum_crtc_info_scale (crtc_infos, n_crtc_infos); + } + + for (i = 0; i < n_crtc_infos; i++) + { + MetaCrtcInfo *crtc_info = crtc_infos[i]; + + if (crtc_info->crtc != crtc) + continue; + + if (meta_crtc_xrandr_is_assignment_changed (crtc, crtc_info)) + return TRUE; + + if (have_scaling) + { + float crtc_scale = crtc->scale; + float req_output_scale = crtc_info->scale; + + if (layout_mode == META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL) + { + if (fmodf (crtc_scale, 1.0) == 0.0f) + { + *weak_change = fabsf (crtc_scale - req_output_scale) > 0.001; + return FALSE; + } + } + else if (layout_mode == META_LOGICAL_MONITOR_LAYOUT_MODE_GLOBAL_UI_LOGICAL) + { + /* In scale ui-down mode we need to check if the actual output + * scale that will be applied to the crtc has actually changed + * from the current value, so we need to compare the current crtc + * scale with the scale that will be applied taking care of the + * UI scale (max crtc scale) and of the requested maximum scale. + * If we don't do this, we'd try to call randr calls which won't + * ever trigger a RRScreenChangeNotify, as no actual change is + * needed, and thus we won't ever emit a monitors-changed signal. + */ + crtc_scale /= ceilf (max_crtc_scale); + req_output_scale /= ceilf (max_req_scale); + } + + if (fabsf (crtc_scale - req_output_scale) > 0.001) + return TRUE; + } + + return FALSE; + } + + return !!meta_crtc_xrandr_get_current_mode (crtc); +} + +static gboolean +is_output_assignment_changed (MetaOutput *output, + MetaCrtcInfo **crtc_infos, + unsigned int n_crtc_infos, + MetaOutputInfo **output_infos, + unsigned int n_output_infos) +{ + MetaCrtc *assigned_crtc; + gboolean output_is_found = FALSE; + unsigned int i; + + for (i = 0; i < n_output_infos; i++) + { + MetaOutputInfo *output_info = output_infos[i]; + + if (output_info->output != output) + continue; + + if (output->is_primary != output_info->is_primary) + return TRUE; + + if (output->is_presentation != output_info->is_presentation) + return TRUE; + + if (output->is_underscanning != output_info->is_underscanning) + return TRUE; + + output_is_found = TRUE; + } + + assigned_crtc = meta_output_get_assigned_crtc (output); + + if (!output_is_found) + return assigned_crtc != NULL; + + for (i = 0; i < n_crtc_infos; i++) + { + MetaCrtcInfo *crtc_info = crtc_infos[i]; + unsigned int j; + + for (j = 0; j < crtc_info->outputs->len; j++) + { + MetaOutput *crtc_info_output = + ((MetaOutput**) crtc_info->outputs->pdata)[j]; + + if (crtc_info_output == output && + crtc_info->crtc == assigned_crtc) + return FALSE; + } + } + + return TRUE; +} + +static MetaGpu * +meta_monitor_manager_xrandr_get_gpu (MetaMonitorManagerXrandr *manager_xrandr) +{ + MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr); + MetaBackend *backend = meta_monitor_manager_get_backend (manager); + + return META_GPU (meta_backend_get_gpus (backend)->data); +} + +static gboolean +is_assignments_changed (MetaMonitorManager *manager, + MetaCrtcInfo **crtc_infos, + unsigned int n_crtc_infos, + MetaOutputInfo **output_infos, + unsigned int n_output_infos, + gboolean *weak_change) +{ + MetaMonitorManagerXrandr *manager_xrandr = + META_MONITOR_MANAGER_XRANDR (manager); + MetaGpu *gpu = meta_monitor_manager_xrandr_get_gpu (manager_xrandr); + GList *l; + + for (l = meta_gpu_get_crtcs (gpu); l; l = l->next) + { + MetaCrtc *crtc = l->data; + + if (is_crtc_assignment_changed (manager, crtc, crtc_infos, n_crtc_infos, weak_change)) + return TRUE; + } + + for (l = meta_gpu_get_outputs (gpu); l; l = l->next) + { + MetaOutput *output = l->data; + + if (is_output_assignment_changed (output, + crtc_infos, + n_crtc_infos, + output_infos, + n_output_infos)) + return TRUE; + } + + if (meta_monitor_manager_get_default_layout_mode (manager) == + META_LOGICAL_MONITOR_LAYOUT_MODE_GLOBAL_UI_LOGICAL) + { + /* If nothing has changed, ensure that the crtc logical scaling matches + * with the requested one, as in case of global UI logical layout we might + * assume that it is in fact equal, while it's techincally different. + * Not doing this would then cause a wrong computation of the max crtc + * scale and thus of the UI scaling. */ + for (l = meta_gpu_get_crtcs (gpu); l; l = l->next) + { + MetaCrtc *crtc = l->data; + unsigned int i; + + for (i = 0; i < n_crtc_infos; i++) + { + MetaCrtcInfo *crtc_info = crtc_infos[i]; + + if (crtc_info->crtc == crtc) + { + crtc->scale = crtc_info->scale; + break; + } + } + } + } + + return FALSE; +} + +static void +apply_crtc_assignments (MetaMonitorManager *manager, + gboolean save_timestamp, + MetaCrtcInfo **crtcs, + unsigned int n_crtcs, + MetaOutputInfo **outputs, + unsigned int n_outputs) +{ + MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager); + MetaGpu *gpu = meta_monitor_manager_xrandr_get_gpu (manager_xrandr); + MetaBackend *backend = meta_monitor_manager_get_backend (manager); + MetaSettings *settings = meta_backend_get_settings (backend); + MetaX11ScaleMode scale_mode = meta_settings_get_x11_scale_mode (settings); + unsigned i, valid_crtcs; + GList *l; + int width, height; + float max_scale; + float avg_screen_scale; + gboolean have_scaling; + + XGrabServer (manager_xrandr->xdisplay); + + have_scaling = meta_monitor_manager_get_capabilities (manager) & + META_MONITOR_MANAGER_CAPABILITY_NATIVE_OUTPUT_SCALING; + + /* Compute the new size of the screen (framebuffer) */ + max_scale = get_maximum_crtc_info_scale (crtcs, n_crtcs); + width = 0; height = 0; + avg_screen_scale = 0; + valid_crtcs = 0; + for (i = 0; i < n_crtcs; i++) + { + MetaCrtcInfo *crtc_info = crtcs[i]; + MetaCrtc *crtc = crtc_info->crtc; + float scale = 1.0f; + + crtc->is_dirty = TRUE; + + if (crtc_info->mode == NULL) + continue; + + if (have_scaling && scale_mode == META_X11_SCALE_MODE_UI_DOWN) + scale = (ceilf (max_scale) / crtc_info->scale) * crtc_info->scale; + + width = MAX (width, (int) roundf (crtc_info->layout.origin.x + + crtc_info->layout.size.width * scale)); + height = MAX (height, (int) roundf (crtc_info->layout.origin.y + + crtc_info->layout.size.height * scale)); + + avg_screen_scale += (crtc_info->scale - avg_screen_scale) / + (float) (++valid_crtcs); + } + + /* Second disable all newly disabled CRTCs, or CRTCs that in the previous + configuration would be outside the new framebuffer (otherwise X complains + loudly when resizing) + CRTC will be enabled again after resizing the FB + */ + for (i = 0; i < n_crtcs; i++) + { + MetaCrtcInfo *crtc_info = crtcs[i]; + MetaCrtc *crtc = crtc_info->crtc; + MetaCrtcConfig *crtc_config; + int x2, y2; + + crtc_config = crtc->config; + if (!crtc_config) + continue; + + x2 = (int) roundf (crtc_config->layout.origin.x + + crtc_config->layout.size.width); + y2 = (int) roundf (crtc_config->layout.origin.y + + crtc_config->layout.size.height); + + if (!crtc_info->mode || x2 > width || y2 > height) + { + xrandr_set_crtc_config (manager_xrandr, + crtc, + save_timestamp, + (xcb_randr_crtc_t) crtc->crtc_id, + XCB_CURRENT_TIME, + 0, 0, XCB_NONE, + XCB_RANDR_ROTATION_ROTATE_0, + NULL, 0); + if (have_scaling) + meta_crtc_xrandr_set_scale (crtc, + (xcb_randr_crtc_t) crtc->crtc_id, 1.0f); + + meta_crtc_unset_config (crtc); + crtc->scale = 1.0f; + } + } + + /* Disable CRTCs not mentioned in the list */ + for (l = meta_gpu_get_crtcs (gpu); l; l = l->next) + { + MetaCrtc *crtc = l->data; + + if (crtc->is_dirty) + { + crtc->is_dirty = FALSE; + continue; + } + + if (!crtc->config) + continue; + + xrandr_set_crtc_config (manager_xrandr, + crtc, + save_timestamp, + (xcb_randr_crtc_t) crtc->crtc_id, + XCB_CURRENT_TIME, + 0, 0, XCB_NONE, + XCB_RANDR_ROTATION_ROTATE_0, + NULL, 0); + if (have_scaling) + meta_crtc_xrandr_set_scale (crtc, + (xcb_randr_crtc_t) crtc->crtc_id, 1.0f); + + meta_crtc_unset_config (crtc); + crtc->scale = 1.0f; + } + + if (!n_crtcs) + goto out; + + if (width > manager->screen_width || height > manager->screen_height) + { + meta_monitor_manager_xrandr_update_screen_size (manager_xrandr, + width, height, + avg_screen_scale); + } + + for (i = 0; i < n_crtcs; i++) + { + MetaCrtcInfo *crtc_info = crtcs[i]; + MetaCrtc *crtc = crtc_info->crtc; + + if (crtc_info->mode != NULL) + { + MetaCrtcMode *mode; + g_autofree xcb_randr_output_t *output_ids = NULL; + unsigned int j, n_output_ids; + xcb_randr_rotation_t rotation; + float scale = 1.0f; + + mode = crtc_info->mode; + + n_output_ids = crtc_info->outputs->len; + output_ids = g_new (xcb_randr_output_t, n_output_ids); + + if (have_scaling && scale_mode != META_X11_SCALE_MODE_NONE) + { + scale = crtc_info->scale; + + if (scale_mode == META_X11_SCALE_MODE_UI_DOWN) + scale /= ceilf (max_scale); + } + + for (j = 0; j < n_output_ids; j++) + { + MetaOutput *output; + + output = ((MetaOutput**)crtc_info->outputs->pdata)[j]; + + output->is_dirty = TRUE; + meta_output_assign_crtc (output, crtc); + + output_ids[j] = output->winsys_id; + } + + if (have_scaling) + { + if (!meta_crtc_xrandr_set_scale (crtc, + (xcb_randr_crtc_t) crtc->crtc_id, + scale)) + { + meta_warning ("Scalig CRTC %d at %f failed\n", + (unsigned)crtc->crtc_id, scale); + } + } + + rotation = meta_monitor_transform_to_xrandr (crtc_info->transform); + if (!xrandr_set_crtc_config (manager_xrandr, + crtc, + save_timestamp, + (xcb_randr_crtc_t) crtc->crtc_id, + XCB_CURRENT_TIME, + (int) roundf (crtc_info->layout.origin.x), + (int) roundf (crtc_info->layout.origin.y), + (xcb_randr_mode_t) mode->mode_id, + rotation, + output_ids, n_output_ids)) + { + meta_warning ("Configuring CRTC %d with mode %d (%d x %d @ %f) at position %d, %d and transform %u failed\n", + (unsigned)(crtc->crtc_id), (unsigned)(mode->mode_id), + mode->width, mode->height, (float)mode->refresh_rate, + (int) roundf (crtc_info->layout.origin.x), + (int) roundf (crtc_info->layout.origin.y), + crtc_info->transform); + continue; + } + + meta_crtc_set_config (crtc, + &crtc_info->layout, + mode, + crtc_info->transform); + crtc->scale = crtc_info->scale; + + if (have_scaling && scale_mode == META_X11_SCALE_MODE_UI_DOWN) + { + scale = (ceilf (max_scale) / crtc_info->scale) * crtc_info->scale; + + crtc->config->layout.size.width = + roundf (crtc->config->layout.size.width * scale); + crtc->config->layout.size.height = + roundf (crtc->config->layout.size.height * scale); + } + } + } + + for (i = 0; i < n_outputs; i++) + { + MetaOutputInfo *output_info = outputs[i]; + MetaOutput *output = output_info->output; + + output->is_primary = output_info->is_primary; + output->is_presentation = output_info->is_presentation; + output->is_underscanning = output_info->is_underscanning; + + meta_output_xrandr_apply_mode (output); + } + + /* Disable outputs not mentioned in the list */ + for (l = meta_gpu_get_outputs (gpu); l; l = l->next) + { + MetaOutput *output = l->data; + + if (output->is_dirty) + { + output->is_dirty = FALSE; + continue; + } + + meta_output_unassign_crtc (output); + output->is_primary = FALSE; + } + + if (width > 0 && height > 0) + { + meta_monitor_manager_xrandr_update_screen_size (manager_xrandr, + width, height, + avg_screen_scale); + } + +out: + XUngrabServer (manager_xrandr->xdisplay); + XFlush (manager_xrandr->xdisplay); +} + +static void +meta_monitor_manager_xrandr_ensure_initial_config (MetaMonitorManager *manager) +{ + MetaMonitorConfigManager *config_manager = + meta_monitor_manager_get_config_manager (manager); + MetaMonitorsConfig *config; + + meta_monitor_manager_ensure_configured (manager); + + /* + * Normally we don't rebuild our data structures until we see the + * RRScreenNotify event, but at least at startup we want to have the right + * configuration immediately. + */ + meta_monitor_manager_read_current_state (manager); + + config = meta_monitor_config_manager_get_current (config_manager); + meta_monitor_manager_update_logical_state_derived (manager, config); +} + +static void +meta_monitor_manager_xrandr_update_screen_size_derived (MetaMonitorManager *manager, + MetaMonitorsConfig *config) +{ + MetaMonitorManagerXrandr *manager_xrandr = + META_MONITOR_MANAGER_XRANDR (manager); + MetaBackend *backend = meta_monitor_manager_get_backend (manager); + MetaSettings *settings = meta_backend_get_settings (backend); + MetaX11ScaleMode scale_mode = meta_settings_get_x11_scale_mode (settings); + int screen_width = 0; + int screen_height = 0; + unsigned n_crtcs = 0; + float average_scale = 0; + gboolean have_scaling; + GList *l; + + have_scaling = meta_monitor_manager_get_capabilities (manager) & + META_MONITOR_MANAGER_CAPABILITY_NATIVE_OUTPUT_SCALING; + + /* Compute the new size of the screen (framebuffer) */ + for (l = manager->monitors; l != NULL; l = l->next) + { + MetaMonitor *monitor = l->data; + MetaOutput *output = meta_monitor_get_main_output (monitor); + MetaCrtc *crtc = meta_output_get_assigned_crtc (output); + graphene_rect_t *crtc_layout; + float scale = 1.0f; + + if (!crtc || !crtc->config) + continue; + + if (!have_scaling || scale_mode != META_X11_SCALE_MODE_UI_DOWN) + { + /* When scaling up we should not reduce the screen size, or X will + * fail miserably, while we must do it when scaling down, in order to + * increase the available screen area we can use. */ + scale = crtc->scale > 1.0f ? crtc->scale : 1.0f; + } + + /* When computing the screen size from the crtc rects we don't have to + * use inverted values when monitors are rotated, because this is already + * taken in account in the crtc rectangles */ + crtc_layout = &crtc->config->layout; + screen_width = MAX (screen_width, crtc_layout->origin.x + + roundf (crtc_layout->size.width * scale)); + screen_height = MAX (screen_height, crtc_layout->origin.y + + roundf (crtc_layout->size.height * scale)); + ++n_crtcs; + + /* This value isn't completely exact, since it doesn't take care of the + * actual crtc sizes, however, since w're going to use this only to set + * the MM size of the screen, and given that this value is just an + * estimation, we don't need to be super precise. */ + average_scale += (crtc->scale - average_scale) / (float) n_crtcs; + } + + if (screen_width > 0 && screen_height > 0) + { + meta_monitor_manager_xrandr_update_screen_size (manager_xrandr, + screen_width, + screen_height, + average_scale); + } +} + +static void +maybe_update_ui_scaling_factor (MetaMonitorManager *manager, + MetaMonitorsConfig *config) +{ + if (config->layout_mode == META_LOGICAL_MONITOR_LAYOUT_MODE_GLOBAL_UI_LOGICAL || + manager->layout_mode == META_LOGICAL_MONITOR_LAYOUT_MODE_GLOBAL_UI_LOGICAL) + { + MetaBackend *backend = meta_monitor_manager_get_backend (manager); + MetaSettings *settings = meta_backend_get_settings (backend); + + meta_settings_update_ui_scaling_factor (settings); + } +} + +static gboolean +meta_monitor_manager_xrandr_apply_monitors_config (MetaMonitorManager *manager, + MetaMonitorsConfig *config, + MetaMonitorsConfigMethod method, + GError **error) +{ + GPtrArray *crtc_infos; + GPtrArray *output_infos; + + if (!config) + { + if (!manager->in_init) + apply_crtc_assignments (manager, TRUE, NULL, 0, NULL, 0); + + meta_monitor_manager_rebuild_derived (manager, NULL); + return TRUE; + } + + if (!meta_monitor_config_manager_assign (manager, config, + &crtc_infos, &output_infos, + error)) + return FALSE; + + if (method != META_MONITORS_CONFIG_METHOD_VERIFY) + { + gboolean weak_change = FALSE; + + /* + * If the assignment has not changed, we won't get any notification about + * any new configuration from the X server; but we still need to update + * our own configuration, as something not applicable in Xrandr might + * have changed locally, such as the logical monitors scale. This means we + * must check that our new assignment actually changes anything, otherwise + * just update the logical state. + * If we record a weak change it means that only UI scaling needs to be + * updated and so that we don't have to reconfigure the CRTCs, but still + * need to update the logical state. + */ + if (is_assignments_changed (manager, + (MetaCrtcInfo **) crtc_infos->pdata, + crtc_infos->len, + (MetaOutputInfo **) output_infos->pdata, + output_infos->len, + &weak_change)) + { + apply_crtc_assignments (manager, + TRUE, + (MetaCrtcInfo **) crtc_infos->pdata, + crtc_infos->len, + (MetaOutputInfo **) output_infos->pdata, + output_infos->len); + + maybe_update_ui_scaling_factor (manager, config); + } + else + { + if (weak_change) + maybe_update_ui_scaling_factor (manager, config); + + meta_monitor_manager_rebuild_derived (manager, config); + } + } + + g_ptr_array_free (crtc_infos, TRUE); + g_ptr_array_free (output_infos, TRUE); + + return TRUE; +} + +static void +meta_monitor_manager_xrandr_change_backlight (MetaMonitorManager *manager, + MetaOutput *output, + gint value) +{ + meta_output_xrandr_change_backlight (output, value); +} + +static void +meta_monitor_manager_xrandr_get_crtc_gamma (MetaMonitorManager *manager, + MetaCrtc *crtc, + gsize *size, + unsigned short **red, + unsigned short **green, + unsigned short **blue) +{ + MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager); + XRRCrtcGamma *gamma; + + gamma = XRRGetCrtcGamma (manager_xrandr->xdisplay, (XID)crtc->crtc_id); + + *size = gamma->size; + *red = g_memdup (gamma->red, sizeof (unsigned short) * gamma->size); + *green = g_memdup (gamma->green, sizeof (unsigned short) * gamma->size); + *blue = g_memdup (gamma->blue, sizeof (unsigned short) * gamma->size); + + XRRFreeGamma (gamma); +} + +static void +meta_monitor_manager_xrandr_set_crtc_gamma (MetaMonitorManager *manager, + MetaCrtc *crtc, + gsize size, + unsigned short *red, + unsigned short *green, + unsigned short *blue) +{ + MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager); + XRRCrtcGamma *gamma; + + gamma = XRRAllocGamma (size); + memcpy (gamma->red, red, sizeof (unsigned short) * size); + memcpy (gamma->green, green, sizeof (unsigned short) * size); + memcpy (gamma->blue, blue, sizeof (unsigned short) * size); + + XRRSetCrtcGamma (manager_xrandr->xdisplay, (XID)crtc->crtc_id, gamma); + + XRRFreeGamma (gamma); +} + +static MetaMonitorXrandrData * +meta_monitor_xrandr_data_from_monitor (MetaMonitor *monitor) +{ + MetaMonitorXrandrData *monitor_xrandr_data; + + monitor_xrandr_data = g_object_get_qdata (G_OBJECT (monitor), + quark_meta_monitor_xrandr_data); + if (monitor_xrandr_data) + return monitor_xrandr_data; + + monitor_xrandr_data = g_new0 (MetaMonitorXrandrData, 1); + g_object_set_qdata_full (G_OBJECT (monitor), + quark_meta_monitor_xrandr_data, + monitor_xrandr_data, + g_free); + + return monitor_xrandr_data; +} + +static void +meta_monitor_manager_xrandr_increase_monitor_count (MetaMonitorManagerXrandr *manager_xrandr, + Atom name_atom) +{ + int count; + + count = + GPOINTER_TO_INT (g_hash_table_lookup (manager_xrandr->tiled_monitor_atoms, + GSIZE_TO_POINTER (name_atom))); + + count++; + g_hash_table_insert (manager_xrandr->tiled_monitor_atoms, + GSIZE_TO_POINTER (name_atom), + GINT_TO_POINTER (count)); +} + +static int +meta_monitor_manager_xrandr_decrease_monitor_count (MetaMonitorManagerXrandr *manager_xrandr, + Atom name_atom) +{ + int count; + + count = + GPOINTER_TO_SIZE (g_hash_table_lookup (manager_xrandr->tiled_monitor_atoms, + GSIZE_TO_POINTER (name_atom))); + g_assert (count > 0); + + count--; + g_hash_table_insert (manager_xrandr->tiled_monitor_atoms, + GSIZE_TO_POINTER (name_atom), + GINT_TO_POINTER (count)); + + return count; +} + +static void +meta_monitor_manager_xrandr_tiled_monitor_added (MetaMonitorManager *manager, + MetaMonitor *monitor) +{ + MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager); + MetaMonitorTiled *monitor_tiled = META_MONITOR_TILED (monitor); + const char *product; + char *name; + uint32_t tile_group_id; + MetaMonitorXrandrData *monitor_xrandr_data; + Atom name_atom; + XRRMonitorInfo *xrandr_monitor_info; + GList *outputs; + GList *l; + int i; + + if (!(meta_monitor_manager_get_capabilities (manager) & + META_MONITOR_MANAGER_CAPABILITY_TILING)) + return; + + product = meta_monitor_get_product (monitor); + tile_group_id = meta_monitor_tiled_get_tile_group_id (monitor_tiled); + + if (product) + name = g_strdup_printf ("%s-%d", product, tile_group_id); + else + name = g_strdup_printf ("Tiled-%d", tile_group_id); + + name_atom = XInternAtom (manager_xrandr->xdisplay, name, False); + g_free (name); + + monitor_xrandr_data = meta_monitor_xrandr_data_from_monitor (monitor); + monitor_xrandr_data->xrandr_name = name_atom; + + meta_monitor_manager_xrandr_increase_monitor_count (manager_xrandr, + name_atom); + + outputs = meta_monitor_get_outputs (monitor); + xrandr_monitor_info = XRRAllocateMonitor (manager_xrandr->xdisplay, + g_list_length (outputs)); + xrandr_monitor_info->name = name_atom; + xrandr_monitor_info->primary = meta_monitor_is_primary (monitor); + xrandr_monitor_info->automatic = True; + for (l = outputs, i = 0; l; l = l->next, i++) + { + MetaOutput *output = l->data; + + xrandr_monitor_info->outputs[i] = output->winsys_id; + } + + XRRSetMonitor (manager_xrandr->xdisplay, + DefaultRootWindow (manager_xrandr->xdisplay), + xrandr_monitor_info); + XRRFreeMonitors (xrandr_monitor_info); +} + +static void +meta_monitor_manager_xrandr_tiled_monitor_removed (MetaMonitorManager *manager, + MetaMonitor *monitor) +{ + MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager); + MetaMonitorXrandrData *monitor_xrandr_data; + Atom monitor_name; + + int monitor_count; + + if (!(meta_monitor_manager_get_capabilities (manager) & + META_MONITOR_MANAGER_CAPABILITY_TILING)) + return; + + monitor_xrandr_data = meta_monitor_xrandr_data_from_monitor (monitor); + monitor_name = monitor_xrandr_data->xrandr_name; + monitor_count = + meta_monitor_manager_xrandr_decrease_monitor_count (manager_xrandr, + monitor_name); + + if (monitor_count == 0) + XRRDeleteMonitor (manager_xrandr->xdisplay, + DefaultRootWindow (manager_xrandr->xdisplay), + monitor_name); +} + +static void +meta_monitor_manager_xrandr_init_monitors (MetaMonitorManagerXrandr *manager_xrandr) +{ + MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr); + XRRMonitorInfo *m; + int n, i; + + if (!(meta_monitor_manager_get_capabilities (manager) & + META_MONITOR_MANAGER_CAPABILITY_TILING)) + return; + + /* delete any tiled monitors setup, as mutter will want to recreate + things in its image */ + m = XRRGetMonitors (manager_xrandr->xdisplay, + DefaultRootWindow (manager_xrandr->xdisplay), + FALSE, &n); + if (n == -1) + return; + + for (i = 0; i < n; i++) + { + if (m[i].noutput > 1) + XRRDeleteMonitor (manager_xrandr->xdisplay, + DefaultRootWindow (manager_xrandr->xdisplay), + m[i].name); + } + XRRFreeMonitors (m); +} + +static gboolean +meta_monitor_manager_xrandr_is_transform_handled (MetaMonitorManager *manager, + MetaCrtc *crtc, + MetaMonitorTransform transform) +{ + g_warn_if_fail ((crtc->all_transforms & transform) == transform); + + return TRUE; +} + +static MetaMonitorScalesConstraint +get_scale_constraints (MetaMonitorManager *manager) +{ + MetaMonitorScalesConstraint constraints = 0; + + if (meta_monitor_manager_get_capabilities (manager) & + META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED) + constraints |= META_MONITOR_SCALES_CONSTRAINT_NO_FRAC; + + return constraints; +} + +static float +meta_monitor_manager_xrandr_calculate_monitor_mode_scale (MetaMonitorManager *manager, + MetaLogicalMonitorLayoutMode layout_mode, + MetaMonitor *monitor, + MetaMonitorMode *monitor_mode) +{ + return meta_monitor_calculate_mode_scale (monitor, monitor_mode, + get_scale_constraints (manager)); +} + +static float * +meta_monitor_manager_xrandr_calculate_supported_scales (MetaMonitorManager *manager, + MetaLogicalMonitorLayoutMode layout_mode, + MetaMonitor *monitor, + MetaMonitorMode *monitor_mode, + int *n_supported_scales) +{ + return meta_monitor_calculate_supported_scales (monitor, monitor_mode, + get_scale_constraints (manager), + n_supported_scales); +} + +static MetaMonitorManagerCapability +meta_monitor_manager_xrandr_get_capabilities (MetaMonitorManager *manager) +{ + MetaMonitorManagerCapability capabilities; + MetaMonitorManagerXrandr *xrandr_manager = META_MONITOR_MANAGER_XRANDR (manager); + MetaBackend *backend = meta_monitor_manager_get_backend (manager); + MetaSettings *settings = meta_backend_get_settings (backend); + + capabilities = META_MONITOR_MANAGER_CAPABILITY_NONE; + + if (xrandr_manager->randr_version >= RANDR_TILING_MIN_VERSION) + capabilities |= META_MONITOR_MANAGER_CAPABILITY_TILING; + + if (xrandr_manager->randr_version >= RANDR_TRANSFORM_MIN_VERSION) + capabilities |= META_MONITOR_MANAGER_CAPABILITY_NATIVE_OUTPUT_SCALING; + + if (meta_settings_is_experimental_feature_enabled (settings, + META_EXPERIMENTAL_FEATURE_X11_RANDR_FRACTIONAL_SCALING)) + { + capabilities |= META_MONITOR_MANAGER_CAPABILITY_LAYOUT_MODE; + } + else + { + capabilities |= META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED; + } + + return capabilities; +} + +static gboolean +meta_monitor_manager_xrandr_get_max_screen_size (MetaMonitorManager *manager, + int *max_width, + int *max_height) +{ + MetaMonitorManagerXrandr *manager_xrandr = + META_MONITOR_MANAGER_XRANDR (manager); + MetaGpu *gpu = meta_monitor_manager_xrandr_get_gpu (manager_xrandr); + + meta_gpu_xrandr_get_max_screen_size (META_GPU_XRANDR (gpu), + max_width, max_height); + + return TRUE; +} + +static void +scale_mode_changed (MetaSettings *settings, + MetaMonitorManager *manager) +{ + if (!(meta_monitor_manager_get_capabilities (manager) & + META_MONITOR_MANAGER_CAPABILITY_NATIVE_OUTPUT_SCALING)) + return; + + if (!meta_settings_is_experimental_feature_enabled (settings, + META_EXPERIMENTAL_FEATURE_X11_RANDR_FRACTIONAL_SCALING)) + return; + + meta_monitor_manager_on_hotplug (manager); + meta_settings_update_ui_scaling_factor (settings); +} + +static MetaLogicalMonitorLayoutMode +meta_monitor_manager_xrandr_get_default_layout_mode (MetaMonitorManager *manager) +{ + MetaMonitorManagerCapability capabilities = + meta_monitor_manager_get_capabilities (manager); + + if ((capabilities & META_MONITOR_MANAGER_CAPABILITY_NATIVE_OUTPUT_SCALING) && + (capabilities & META_MONITOR_MANAGER_CAPABILITY_LAYOUT_MODE)) + { + MetaBackend *backend = meta_monitor_manager_get_backend (manager); + MetaSettings *settings = meta_backend_get_settings (backend); + MetaX11ScaleMode scale_mode = meta_settings_get_x11_scale_mode (settings); + + if (scale_mode == META_X11_SCALE_MODE_UI_DOWN) + return META_LOGICAL_MONITOR_LAYOUT_MODE_GLOBAL_UI_LOGICAL; + else if (scale_mode == META_X11_SCALE_MODE_UP) + return META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL; + } + + return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL; +} + +static void +meta_monitor_manager_xrandr_constructed (GObject *object) +{ + MetaMonitorManagerXrandr *manager_xrandr = + META_MONITOR_MANAGER_XRANDR (object); + MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr); + MetaBackend *backend = meta_monitor_manager_get_backend (manager); + MetaBackendX11 *backend_x11 = META_BACKEND_X11 (backend); + MetaSettings *settings = meta_backend_get_settings (backend); + + manager_xrandr->xdisplay = meta_backend_x11_get_xdisplay (backend_x11); + + if (!XRRQueryExtension (manager_xrandr->xdisplay, + &manager_xrandr->rr_event_base, + &manager_xrandr->rr_error_base)) + { + return; + } + else + { + int major_version, minor_version; + /* We only use ScreenChangeNotify, but GDK uses the others, + and we don't want to step on its toes */ + XRRSelectInput (manager_xrandr->xdisplay, + DefaultRootWindow (manager_xrandr->xdisplay), + RRScreenChangeNotifyMask + | RRCrtcChangeNotifyMask + | RROutputPropertyNotifyMask); + + XRRQueryVersion (manager_xrandr->xdisplay, &major_version, + &minor_version); + manager_xrandr->randr_version = RANDR_VERSION_FORMAT (major_version, + minor_version); + if (manager_xrandr->randr_version >= RANDR_TILING_MIN_VERSION) + manager_xrandr->tiled_monitor_atoms = g_hash_table_new (NULL, NULL); + + meta_monitor_manager_xrandr_init_monitors (manager_xrandr); + } + + g_signal_connect_object (settings, "x11-scale-mode-changed", + G_CALLBACK (scale_mode_changed), manager_xrandr, 0); + + G_OBJECT_CLASS (meta_monitor_manager_xrandr_parent_class)->constructed (object); +} + +static void +meta_monitor_manager_xrandr_finalize (GObject *object) +{ + MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (object); + + g_hash_table_destroy (manager_xrandr->tiled_monitor_atoms); + + G_OBJECT_CLASS (meta_monitor_manager_xrandr_parent_class)->finalize (object); +} + +static void +meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr) +{ +} + +static void +meta_monitor_manager_xrandr_class_init (MetaMonitorManagerXrandrClass *klass) +{ + MetaMonitorManagerClass *manager_class = META_MONITOR_MANAGER_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_monitor_manager_xrandr_finalize; + object_class->constructed = meta_monitor_manager_xrandr_constructed; + + manager_class->read_edid = meta_monitor_manager_xrandr_read_edid; + manager_class->read_current_state = meta_monitor_manager_xrandr_read_current_state; + manager_class->ensure_initial_config = meta_monitor_manager_xrandr_ensure_initial_config; + manager_class->apply_monitors_config = meta_monitor_manager_xrandr_apply_monitors_config; + manager_class->update_screen_size_derived = meta_monitor_manager_xrandr_update_screen_size_derived; + manager_class->set_power_save_mode = meta_monitor_manager_xrandr_set_power_save_mode; + manager_class->change_backlight = meta_monitor_manager_xrandr_change_backlight; + manager_class->get_crtc_gamma = meta_monitor_manager_xrandr_get_crtc_gamma; + manager_class->set_crtc_gamma = meta_monitor_manager_xrandr_set_crtc_gamma; + manager_class->tiled_monitor_added = meta_monitor_manager_xrandr_tiled_monitor_added; + manager_class->tiled_monitor_removed = meta_monitor_manager_xrandr_tiled_monitor_removed; + manager_class->is_transform_handled = meta_monitor_manager_xrandr_is_transform_handled; + manager_class->calculate_monitor_mode_scale = meta_monitor_manager_xrandr_calculate_monitor_mode_scale; + manager_class->calculate_supported_scales = meta_monitor_manager_xrandr_calculate_supported_scales; + manager_class->get_capabilities = meta_monitor_manager_xrandr_get_capabilities; + manager_class->get_max_screen_size = meta_monitor_manager_xrandr_get_max_screen_size; + manager_class->get_default_layout_mode = meta_monitor_manager_xrandr_get_default_layout_mode; + + quark_meta_monitor_xrandr_data = + g_quark_from_static_string ("-meta-monitor-xrandr-data"); +} + +gboolean +meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xrandr, + XEvent *event) +{ + MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr); + MetaGpu *gpu = meta_monitor_manager_xrandr_get_gpu (manager_xrandr); + MetaGpuXrandr *gpu_xrandr; + XRRScreenResources *resources; + gboolean is_hotplug; + gboolean is_our_configuration; + + if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify) + return FALSE; + + XRRUpdateConfiguration (event); + + meta_monitor_manager_read_current_state (manager); + + gpu_xrandr = META_GPU_XRANDR (gpu); + resources = meta_gpu_xrandr_get_resources (gpu_xrandr); + + is_hotplug = resources->timestamp < resources->configTimestamp; + is_our_configuration = (resources->timestamp == + manager_xrandr->last_xrandr_set_timestamp); + if (is_hotplug) + { + meta_monitor_manager_on_hotplug (manager); + } + else + { + MetaMonitorsConfig *config; + + if (is_our_configuration) + { + MetaMonitorConfigManager *config_manager = + meta_monitor_manager_get_config_manager (manager); + + config = meta_monitor_config_manager_get_current (config_manager); + } + else + { + config = NULL; + } + + meta_monitor_manager_rebuild_derived (manager, config); + } + + return TRUE; +} diff --git a/src/backends/x11/meta-monitor-manager-xrandr.h b/src/backends/x11/meta-monitor-manager-xrandr.h new file mode 100644 index 000000000..515f93807 --- /dev/null +++ b/src/backends/x11/meta-monitor-manager-xrandr.h @@ -0,0 +1,41 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001 Havoc Pennington + * Copyright (C) 2003 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * Copyright (C) 2013 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef META_MONITOR_MANAGER_XRANDR_H +#define META_MONITOR_MANAGER_XRANDR_H + +#include <X11/extensions/Xrandr.h> + +#include "backends/meta-monitor-manager-private.h" + +#define META_TYPE_MONITOR_MANAGER_XRANDR (meta_monitor_manager_xrandr_get_type ()) +G_DECLARE_FINAL_TYPE (MetaMonitorManagerXrandr, meta_monitor_manager_xrandr, + META, MONITOR_MANAGER_XRANDR, MetaMonitorManager) + +Display * meta_monitor_manager_xrandr_get_xdisplay (MetaMonitorManagerXrandr *manager_xrandr); + +gboolean meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager, + XEvent *event); + +uint32_t meta_monitor_manager_xrandr_get_config_timestamp (MetaMonitorManagerXrandr *manager); + +#endif /* META_MONITOR_MANAGER_XRANDR_H */ diff --git a/src/backends/x11/meta-output-xrandr.c b/src/backends/x11/meta-output-xrandr.c new file mode 100644 index 000000000..c274df2e3 --- /dev/null +++ b/src/backends/x11/meta-output-xrandr.c @@ -0,0 +1,839 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001, 2002 Havoc Pennington + * Copyright (C) 2001, 2002 Havoc Pennington + * Copyright (C) 2002, 2003 Red Hat Inc. + * Some ICCCM manager selection code derived from fvwm2, + * Copyright (C) 2001 Dominik Vogt, Matthias Clasen, and fvwm2 team + * Copyright (C) 2003 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * Copyright (C) 2002, 2003 Red Hat Inc. + * Some ICCCM manager selection code derived from fvwm2, + * Copyright (C) 2001 Dominik Vogt, Matthias Clasen, and fvwm2 team + * Copyright (C) 2003 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * Copyright (C) 2013-2017 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "backends/x11/meta-output-xrandr.h" + +#include <glib.h> +#include <string.h> +#include <X11/Xatom.h> +#include <X11/Xlib-xcb.h> +#include <xcb/randr.h> + +#include "backends/meta-backend-private.h" +#include "backends/meta-crtc.h" +#include "backends/x11/meta-monitor-manager-xrandr.h" +#include "meta/util.h" + +static Display * +xdisplay_from_output (MetaOutput *output) +{ + MetaGpu *gpu = meta_output_get_gpu (output); + MetaBackend *backend = meta_gpu_get_backend (gpu); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaMonitorManagerXrandr *monitor_manager_xrandr = + META_MONITOR_MANAGER_XRANDR (monitor_manager); + + return meta_monitor_manager_xrandr_get_xdisplay (monitor_manager_xrandr); +} + +static void +output_set_presentation_xrandr (MetaOutput *output, + gboolean presentation) +{ + Display *xdisplay = xdisplay_from_output (output); + Atom atom; + int value = presentation; + + atom = XInternAtom (xdisplay, "_MUTTER_PRESENTATION_OUTPUT", False); + + xcb_randr_change_output_property (XGetXCBConnection (xdisplay), + (XID) output->winsys_id, + atom, XCB_ATOM_CARDINAL, 32, + XCB_PROP_MODE_REPLACE, + 1, &value); +} + +static void +output_set_underscanning_xrandr (MetaOutput *output, + gboolean underscanning) +{ + Display *xdisplay = xdisplay_from_output (output); + Atom prop, valueatom; + const char *value; + + prop = XInternAtom (xdisplay, "underscan", False); + + value = underscanning ? "on" : "off"; + valueatom = XInternAtom (xdisplay, value, False); + + xcb_randr_change_output_property (XGetXCBConnection (xdisplay), + (XID) output->winsys_id, + prop, XCB_ATOM_ATOM, 32, + XCB_PROP_MODE_REPLACE, + 1, &valueatom); + + /* Configure the border at the same time. Currently, we use a + * 5% of the width/height of the mode. In the future, we should + * make the border configurable. */ + if (underscanning) + { + MetaCrtc *crtc; + MetaCrtcConfig *crtc_config; + uint32_t border_value; + + crtc = meta_output_get_assigned_crtc (output); + crtc_config = crtc->config; + + prop = XInternAtom (xdisplay, "underscan hborder", False); + border_value = crtc_config->mode->width * 0.05; + + xcb_randr_change_output_property (XGetXCBConnection (xdisplay), + (XID) output->winsys_id, + prop, XCB_ATOM_INTEGER, 32, + XCB_PROP_MODE_REPLACE, + 1, &border_value); + + prop = XInternAtom (xdisplay, "underscan vborder", False); + border_value = crtc_config->mode->height * 0.05; + + xcb_randr_change_output_property (XGetXCBConnection (xdisplay), + (XID) output->winsys_id, + prop, XCB_ATOM_INTEGER, 32, + XCB_PROP_MODE_REPLACE, + 1, &border_value); + } +} + +void +meta_output_xrandr_apply_mode (MetaOutput *output) +{ + Display *xdisplay = xdisplay_from_output (output); + + if (output->is_primary) + { + XRRSetOutputPrimary (xdisplay, DefaultRootWindow (xdisplay), + (XID) output->winsys_id); + } + + output_set_presentation_xrandr (output, output->is_presentation); + + if (output->supports_underscanning) + output_set_underscanning_xrandr (output, output->is_underscanning); +} + +static int +normalize_backlight (MetaOutput *output, + int hw_value) +{ + return round ((double)(hw_value - output->backlight_min) / + (output->backlight_max - output->backlight_min) * 100.0); +} + +void +meta_output_xrandr_change_backlight (MetaOutput *output, + int value) +{ + Display *xdisplay = xdisplay_from_output (output); + Atom atom; + int hw_value; + + hw_value = round ((double) value / 100.0 * output->backlight_max + + output->backlight_min); + + atom = XInternAtom (xdisplay, "Backlight", False); + + xcb_randr_change_output_property (XGetXCBConnection (xdisplay), + (XID)output->winsys_id, + atom, XCB_ATOM_INTEGER, 32, + XCB_PROP_MODE_REPLACE, + 1, &hw_value); + + /* We're not selecting for property notifies, so update the value immediately */ + output->backlight = normalize_backlight (output, hw_value); +} + +static gboolean +output_get_integer_property (MetaOutput *output, + const char *propname, + gint *value) +{ + Display *xdisplay = xdisplay_from_output (output); + gboolean exists = FALSE; + Atom atom, actual_type; + int actual_format; + unsigned long nitems, bytes_after; + unsigned char *buffer; + + atom = XInternAtom (xdisplay, propname, False); + XRRGetOutputProperty (xdisplay, + (XID)output->winsys_id, + atom, + 0, G_MAXLONG, False, False, XA_INTEGER, + &actual_type, &actual_format, + &nitems, &bytes_after, &buffer); + + exists = (actual_type == XA_INTEGER && actual_format == 32 && nitems == 1); + + if (exists && value != NULL) + *value = ((int*)buffer)[0]; + + XFree (buffer); + return exists; +} + +static gboolean +output_get_property_exists (MetaOutput *output, + const char *propname) +{ + Display *xdisplay = xdisplay_from_output (output); + gboolean exists = FALSE; + Atom atom, actual_type; + int actual_format; + unsigned long nitems, bytes_after; + unsigned char *buffer; + + atom = XInternAtom (xdisplay, propname, False); + XRRGetOutputProperty (xdisplay, + (XID)output->winsys_id, + atom, + 0, G_MAXLONG, False, False, AnyPropertyType, + &actual_type, &actual_format, + &nitems, &bytes_after, &buffer); + + exists = (actual_type != None); + + XFree (buffer); + return exists; +} + +static gboolean +output_get_boolean_property (MetaOutput *output, + const char *propname) +{ + Display *xdisplay = xdisplay_from_output (output); + Atom atom, actual_type; + int actual_format; + unsigned long nitems, bytes_after; + g_autofree unsigned char *buffer = NULL; + + atom = XInternAtom (xdisplay, propname, False); + XRRGetOutputProperty (xdisplay, + (XID)output->winsys_id, + atom, + 0, G_MAXLONG, False, False, XA_CARDINAL, + &actual_type, &actual_format, + &nitems, &bytes_after, &buffer); + + if (actual_type != XA_CARDINAL || actual_format != 32 || nitems < 1) + return FALSE; + + return ((int*)buffer)[0]; +} + +static gboolean +output_get_presentation_xrandr (MetaOutput *output) +{ + return output_get_boolean_property (output, "_MUTTER_PRESENTATION_OUTPUT"); +} + +static gboolean +output_get_underscanning_xrandr (MetaOutput *output) +{ + Display *xdisplay = xdisplay_from_output (output); + Atom atom, actual_type; + int actual_format; + unsigned long nitems, bytes_after; + g_autofree unsigned char *buffer = NULL; + g_autofree char *str = NULL; + + atom = XInternAtom (xdisplay, "underscan", False); + XRRGetOutputProperty (xdisplay, + (XID)output->winsys_id, + atom, + 0, G_MAXLONG, False, False, XA_ATOM, + &actual_type, &actual_format, + &nitems, &bytes_after, &buffer); + + if (actual_type != XA_ATOM || actual_format != 32 || nitems < 1) + return FALSE; + + str = XGetAtomName (xdisplay, *(Atom *)buffer); + return (strcmp (str, "on") == 0); +} + +static gboolean +output_get_supports_underscanning_xrandr (MetaOutput *output) +{ + Display *xdisplay = xdisplay_from_output (output); + Atom atom, actual_type; + int actual_format, i; + unsigned long nitems, bytes_after; + g_autofree unsigned char *buffer = NULL; + XRRPropertyInfo *property_info; + Atom *values; + gboolean supports_underscanning = FALSE; + + atom = XInternAtom (xdisplay, "underscan", False); + XRRGetOutputProperty (xdisplay, + (XID)output->winsys_id, + atom, + 0, G_MAXLONG, False, False, XA_ATOM, + &actual_type, &actual_format, + &nitems, &bytes_after, &buffer); + + if (actual_type != XA_ATOM || actual_format != 32 || nitems < 1) + return FALSE; + + property_info = XRRQueryOutputProperty (xdisplay, + (XID) output->winsys_id, + atom); + values = (Atom *) property_info->values; + + for (i = 0; i < property_info->num_values; i++) + { + /* The output supports underscanning if "on" is a valid value + * for the underscan property. + */ + char *name = XGetAtomName (xdisplay, values[i]); + if (strcmp (name, "on") == 0) + supports_underscanning = TRUE; + + XFree (name); + } + + XFree (property_info); + + return supports_underscanning; +} + +static int +output_get_backlight_xrandr (MetaOutput *output) +{ + Display *xdisplay = xdisplay_from_output (output); + int value = -1; + Atom atom, actual_type; + int actual_format; + unsigned long nitems, bytes_after; + g_autofree unsigned char *buffer = NULL; + + atom = XInternAtom (xdisplay, "Backlight", False); + XRRGetOutputProperty (xdisplay, + (XID)output->winsys_id, + atom, + 0, G_MAXLONG, False, False, XA_INTEGER, + &actual_type, &actual_format, + &nitems, &bytes_after, &buffer); + + if (actual_type != XA_INTEGER || actual_format != 32 || nitems < 1) + return FALSE; + + value = ((int*)buffer)[0]; + if (value > 0) + return normalize_backlight (output, value); + else + return -1; +} + +static void +output_get_backlight_limits_xrandr (MetaOutput *output) +{ + Display *xdisplay = xdisplay_from_output (output); + Atom atom; + xcb_connection_t *xcb_conn; + xcb_randr_query_output_property_cookie_t cookie; + g_autofree xcb_randr_query_output_property_reply_t *reply = NULL; + + atom = XInternAtom (xdisplay, "Backlight", False); + + xcb_conn = XGetXCBConnection (xdisplay); + cookie = xcb_randr_query_output_property (xcb_conn, + (xcb_randr_output_t) output->winsys_id, + (xcb_atom_t) atom); + reply = xcb_randr_query_output_property_reply (xcb_conn, + cookie, + NULL); + + /* This can happen on systems without backlights. */ + if (reply == NULL) + return; + + if (!reply->range || reply->length != 2) + { + meta_verbose ("backlight %s was not range\n", output->name); + return; + } + + int32_t *values = xcb_randr_query_output_property_valid_values (reply); + output->backlight_min = values[0]; + output->backlight_max = values[1]; +} + +static guint8 * +get_edid_property (Display *xdisplay, + RROutput output, + Atom atom, + gsize *len) +{ + unsigned char *prop; + int actual_format; + unsigned long nitems, bytes_after; + Atom actual_type; + guint8 *result; + + XRRGetOutputProperty (xdisplay, output, atom, + 0, 100, False, False, + AnyPropertyType, + &actual_type, &actual_format, + &nitems, &bytes_after, &prop); + + if (actual_type == XA_INTEGER && actual_format == 8) + { + result = g_memdup (prop, nitems); + if (len) + *len = nitems; + } + else + { + result = NULL; + } + + XFree (prop); + + return result; +} + +GBytes * +meta_output_xrandr_read_edid (MetaOutput *output) +{ + Display *xdisplay = xdisplay_from_output (output); + Atom edid_atom; + guint8 *result; + gsize len; + + edid_atom = XInternAtom (xdisplay, "EDID", FALSE); + result = get_edid_property (xdisplay, output->winsys_id, edid_atom, &len); + + if (!result) + { + edid_atom = XInternAtom (xdisplay, "EDID_DATA", FALSE); + result = get_edid_property (xdisplay, output->winsys_id, edid_atom, &len); + } + + if (result) + { + if (len > 0 && len % 128 == 0) + return g_bytes_new_take (result, len); + else + g_free (result); + } + + return NULL; +} + +static gboolean +output_get_hotplug_mode_update (MetaOutput *output) +{ + return output_get_property_exists (output, "hotplug_mode_update"); +} + +static gint +output_get_suggested_x (MetaOutput *output) +{ + gint val; + if (output_get_integer_property (output, "suggested X", &val)) + return val; + + return -1; +} + +static gint +output_get_suggested_y (MetaOutput *output) +{ + gint val; + if (output_get_integer_property (output, "suggested Y", &val)) + return val; + + return -1; +} + +static MetaConnectorType +connector_type_from_atom (Display *xdisplay, + Atom atom) +{ + if (atom == XInternAtom (xdisplay, "HDMI", True)) + return META_CONNECTOR_TYPE_HDMIA; + if (atom == XInternAtom (xdisplay, "VGA", True)) + return META_CONNECTOR_TYPE_VGA; + /* Doesn't have a DRM equivalent, but means an internal panel. + * We could pick either LVDS or eDP here. */ + if (atom == XInternAtom (xdisplay, "Panel", True)) + return META_CONNECTOR_TYPE_LVDS; + if (atom == XInternAtom (xdisplay, "DVI", True) || + atom == XInternAtom (xdisplay, "DVI-I", True)) + return META_CONNECTOR_TYPE_DVII; + if (atom == XInternAtom (xdisplay, "DVI-A", True)) + return META_CONNECTOR_TYPE_DVIA; + if (atom == XInternAtom (xdisplay, "DVI-D", True)) + return META_CONNECTOR_TYPE_DVID; + if (atom == XInternAtom (xdisplay, "DisplayPort", True)) + return META_CONNECTOR_TYPE_DisplayPort; + + if (atom == XInternAtom (xdisplay, "TV", True)) + return META_CONNECTOR_TYPE_TV; + if (atom == XInternAtom (xdisplay, "TV-Composite", True)) + return META_CONNECTOR_TYPE_Composite; + if (atom == XInternAtom (xdisplay, "TV-SVideo", True)) + return META_CONNECTOR_TYPE_SVIDEO; + /* Another set of mismatches. */ + if (atom == XInternAtom (xdisplay, "TV-SCART", True)) + return META_CONNECTOR_TYPE_TV; + if (atom == XInternAtom (xdisplay, "TV-C4", True)) + return META_CONNECTOR_TYPE_TV; + + return META_CONNECTOR_TYPE_Unknown; +} + +static MetaConnectorType +output_get_connector_type_from_prop (MetaOutput *output) +{ + Display *xdisplay = xdisplay_from_output (output); + Atom atom, actual_type, connector_type_atom; + int actual_format; + unsigned long nitems, bytes_after; + g_autofree unsigned char *buffer = NULL; + + atom = XInternAtom (xdisplay, "ConnectorType", False); + XRRGetOutputProperty (xdisplay, + (XID)output->winsys_id, + atom, + 0, G_MAXLONG, False, False, XA_ATOM, + &actual_type, &actual_format, + &nitems, &bytes_after, &buffer); + + if (actual_type != XA_ATOM || actual_format != 32 || nitems < 1) + return META_CONNECTOR_TYPE_Unknown; + + connector_type_atom = ((Atom *) buffer)[0]; + return connector_type_from_atom (xdisplay, connector_type_atom); +} + +static MetaConnectorType +output_get_connector_type_from_name (MetaOutput *output) +{ + const char *name = output->name; + + /* drmmode_display.c, which was copy/pasted across all the FOSS + * xf86-video-* drivers, seems to name its outputs based on the + * connector type, so look for that.... + * + * SNA has its own naming scheme, because what else did you expect + * from SNA, but it's not too different, so we can thankfully use + * that with minor changes. + * + * http://cgit.freedesktop.org/xorg/xserver/tree/hw/xfree86/drivers/modesetting/drmmode_display.c#n953 + * http://cgit.freedesktop.org/xorg/driver/xf86-video-intel/tree/src/sna/sna_display.c#n3486 + */ + + if (g_str_has_prefix (name, "DVI")) + return META_CONNECTOR_TYPE_DVII; + if (g_str_has_prefix (name, "LVDS")) + return META_CONNECTOR_TYPE_LVDS; + if (g_str_has_prefix (name, "HDMI")) + return META_CONNECTOR_TYPE_HDMIA; + if (g_str_has_prefix (name, "VGA")) + return META_CONNECTOR_TYPE_VGA; + /* SNA uses DP, not DisplayPort. Test for both. */ + if (g_str_has_prefix (name, "DP") || g_str_has_prefix (name, "DisplayPort")) + return META_CONNECTOR_TYPE_DisplayPort; + if (g_str_has_prefix (name, "eDP")) + return META_CONNECTOR_TYPE_eDP; + if (g_str_has_prefix (name, "Virtual")) + return META_CONNECTOR_TYPE_VIRTUAL; + if (g_str_has_prefix (name, "Composite")) + return META_CONNECTOR_TYPE_Composite; + if (g_str_has_prefix (name, "S-video")) + return META_CONNECTOR_TYPE_SVIDEO; + if (g_str_has_prefix (name, "TV")) + return META_CONNECTOR_TYPE_TV; + if (g_str_has_prefix (name, "CTV")) + return META_CONNECTOR_TYPE_Composite; + if (g_str_has_prefix (name, "DSI")) + return META_CONNECTOR_TYPE_DSI; + if (g_str_has_prefix (name, "DIN")) + return META_CONNECTOR_TYPE_9PinDIN; + + return META_CONNECTOR_TYPE_Unknown; +} + +static MetaConnectorType +output_get_connector_type (MetaOutput *output) +{ + MetaConnectorType ret; + + /* The "ConnectorType" property is considered mandatory since RandR 1.3, + * but none of the FOSS drivers support it, because we're a bunch of + * professional software developers. + * + * Try poking it first, without any expectations that it will work. + * If it's not there, we thankfully have other bonghits to try next. + */ + ret = output_get_connector_type_from_prop (output); + if (ret != META_CONNECTOR_TYPE_Unknown) + return ret; + + /* Fall back to heuristics based on the output name. */ + ret = output_get_connector_type_from_name (output); + if (ret != META_CONNECTOR_TYPE_Unknown) + return ret; + + return META_CONNECTOR_TYPE_Unknown; +} + +static gint +output_get_panel_orientation_transform (MetaOutput *output) +{ + Display *xdisplay = xdisplay_from_output (output); + unsigned long nitems, bytes_after; + Atom atom, actual_type; + int actual_format; + g_autofree unsigned char *buffer = NULL; + g_autofree char *str = NULL; + + atom = XInternAtom (xdisplay, "panel orientation", False); + XRRGetOutputProperty (xdisplay, (XID)output->winsys_id, atom, + 0, G_MAXLONG, False, False, XA_ATOM, + &actual_type, &actual_format, + &nitems, &bytes_after, &buffer); + + if (actual_type != XA_ATOM || actual_format != 32 || nitems < 1) + return META_MONITOR_TRANSFORM_NORMAL; + + str = XGetAtomName (xdisplay, *(Atom *)buffer); + if (strcmp (str, "Upside Down") == 0) + return META_MONITOR_TRANSFORM_180; + + if (strcmp (str, "Left Side Up") == 0) + return META_MONITOR_TRANSFORM_90; + + if (strcmp (str, "Right Side Up") == 0) + return META_MONITOR_TRANSFORM_270; + + return META_MONITOR_TRANSFORM_NORMAL; +} + +static void +output_get_tile_info (MetaOutput *output) +{ + MetaGpu *gpu = meta_output_get_gpu (output); + MetaBackend *backend = meta_gpu_get_backend (gpu); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + Display *xdisplay = xdisplay_from_output (output); + Atom tile_atom; + unsigned char *prop; + unsigned long nitems, bytes_after; + int actual_format; + Atom actual_type; + + if (!(meta_monitor_manager_get_capabilities (monitor_manager) & + META_MONITOR_MANAGER_CAPABILITY_TILING)) + return; + + tile_atom = XInternAtom (xdisplay, "TILE", FALSE); + XRRGetOutputProperty (xdisplay, + output->winsys_id, + tile_atom, 0, 100, False, + False, AnyPropertyType, + &actual_type, &actual_format, + &nitems, &bytes_after, &prop); + + if (actual_type == XA_INTEGER && actual_format == 32 && nitems == 8) + { + long *values = (long *)prop; + output->tile_info.group_id = values[0]; + output->tile_info.flags = values[1]; + output->tile_info.max_h_tiles = values[2]; + output->tile_info.max_v_tiles = values[3]; + output->tile_info.loc_h_tile = values[4]; + output->tile_info.loc_v_tile = values[5]; + output->tile_info.tile_w = values[6]; + output->tile_info.tile_h = values[7]; + } + XFree (prop); +} + + +static void +output_get_modes (MetaOutput *output, + XRROutputInfo *xrandr_output) +{ + MetaGpu *gpu = meta_output_get_gpu (output); + unsigned int i; + unsigned int n_actual_modes; + + output->modes = g_new0 (MetaCrtcMode *, xrandr_output->nmode); + + n_actual_modes = 0; + for (i = 0; i < (unsigned int) xrandr_output->nmode; i++) + { + GList *l; + + for (l = meta_gpu_get_modes (gpu); l; l = l->next) + { + MetaCrtcMode *mode = l->data; + + if (xrandr_output->modes[i] == (XID) mode->mode_id) + { + output->modes[n_actual_modes] = mode; + n_actual_modes += 1; + break; + } + } + } + output->n_modes = n_actual_modes; + if (n_actual_modes > 0) + output->preferred_mode = output->modes[0]; +} + +static void +output_get_crtcs (MetaOutput *output, + XRROutputInfo *xrandr_output) +{ + MetaGpu *gpu = meta_output_get_gpu (output); + unsigned int i; + unsigned int n_actual_crtcs; + GList *l; + + output->possible_crtcs = g_new0 (MetaCrtc *, xrandr_output->ncrtc); + + n_actual_crtcs = 0; + for (i = 0; i < (unsigned int) xrandr_output->ncrtc; i++) + { + for (l = meta_gpu_get_crtcs (gpu); l; l = l->next) + { + MetaCrtc *crtc = l->data; + + if ((XID) crtc->crtc_id == xrandr_output->crtcs[i]) + { + output->possible_crtcs[n_actual_crtcs] = crtc; + n_actual_crtcs += 1; + break; + } + } + } + output->n_possible_crtcs = n_actual_crtcs; + + meta_output_unassign_crtc (output); + for (l = meta_gpu_get_crtcs (gpu); l; l = l->next) + { + MetaCrtc *crtc = l->data; + + if ((XID) crtc->crtc_id == xrandr_output->crtc) + { + meta_output_assign_crtc (output, crtc); + break; + } + } +} + +MetaOutput * +meta_create_xrandr_output (MetaGpuXrandr *gpu_xrandr, + XRROutputInfo *xrandr_output, + RROutput output_id, + RROutput primary_output) +{ + MetaOutput *output; + GBytes *edid; + unsigned int i; + + output = g_object_new (META_TYPE_OUTPUT, NULL); + output->gpu = META_GPU (gpu_xrandr); + output->winsys_id = output_id; + output->name = g_strdup (xrandr_output->name); + + edid = meta_output_xrandr_read_edid (output); + meta_output_parse_edid (output, edid); + g_bytes_unref (edid); + + output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN; + output->hotplug_mode_update = output_get_hotplug_mode_update (output); + output->suggested_x = output_get_suggested_x (output); + output->suggested_y = output_get_suggested_y (output); + output->connector_type = output_get_connector_type (output); + output->panel_orientation_transform = + output_get_panel_orientation_transform (output); + + if (meta_monitor_transform_is_rotated ( + output->panel_orientation_transform)) + { + output->width_mm = xrandr_output->mm_height; + output->height_mm = xrandr_output->mm_width; + } + else + { + output->width_mm = xrandr_output->mm_width; + output->height_mm = xrandr_output->mm_height; + } + + output_get_tile_info (output); + output_get_modes (output, xrandr_output); + output_get_crtcs (output, xrandr_output); + + output->n_possible_clones = xrandr_output->nclone; + output->possible_clones = g_new0 (MetaOutput *, + output->n_possible_clones); + /* + * We can build the list of clones now, because we don't have the list of + * outputs yet, so temporarily set the pointers to the bare XIDs, and then + * we'll fix them in a second pass. + */ + for (i = 0; i < (unsigned int) xrandr_output->nclone; i++) + { + output->possible_clones[i] = GINT_TO_POINTER (xrandr_output->clones[i]); + } + + output->is_primary = ((XID) output->winsys_id == primary_output); + output->is_presentation = output_get_presentation_xrandr (output); + output->is_underscanning = output_get_underscanning_xrandr (output); + output->supports_underscanning = + output_get_supports_underscanning_xrandr (output); + output_get_backlight_limits_xrandr (output); + + if (!(output->backlight_min == 0 && output->backlight_max == 0)) + output->backlight = output_get_backlight_xrandr (output); + else + output->backlight = -1; + + if (output->n_modes == 0 || output->n_possible_crtcs == 0) + { + g_object_unref (output); + return NULL; + } + else + { + return output; + } +} diff --git a/src/backends/x11/meta-output-xrandr.h b/src/backends/x11/meta-output-xrandr.h new file mode 100644 index 000000000..6c97b8486 --- /dev/null +++ b/src/backends/x11/meta-output-xrandr.h @@ -0,0 +1,43 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_OUTPUT_XRANDR +#define META_OUTPUT_XRANDR + +#include <X11/extensions/Xrandr.h> + +#include "backends/meta-output.h" +#include "backends/x11/meta-gpu-xrandr.h" +#include "backends/x11/meta-monitor-manager-xrandr.h" + +void meta_output_xrandr_apply_mode (MetaOutput *output); + +void meta_output_xrandr_change_backlight (MetaOutput *output, + int value); + +GBytes * meta_output_xrandr_read_edid (MetaOutput *output); + +MetaOutput * meta_create_xrandr_output (MetaGpuXrandr *gpu_xrandr, + XRROutputInfo *xrandr_output, + RROutput output_id, + RROutput primary_output); + +#endif /* META_OUTPUT_XRANDR */ diff --git a/src/backends/x11/meta-renderer-x11.c b/src/backends/x11/meta-renderer-x11.c new file mode 100644 index 000000000..96beb4eb8 --- /dev/null +++ b/src/backends/x11/meta-renderer-x11.c @@ -0,0 +1,102 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +#include "config.h" + +#include <glib-object.h> + +#include "backends/meta-backend-private.h" +#include "backends/meta-logical-monitor.h" +#include "backends/meta-renderer-view.h" +#include "backends/meta-renderer.h" +#include "backends/x11/meta-renderer-x11.h" +#include "clutter/x11/clutter-x11.h" +#include "cogl/cogl-xlib.h" +#include "cogl/cogl.h" +#include "cogl/winsys/cogl-winsys-egl-x11-private.h" +#include "cogl/winsys/cogl-winsys-glx-private.h" +#include "core/boxes-private.h" +#include "meta/meta-backend.h" +#include "meta/util.h" + +G_DEFINE_TYPE (MetaRendererX11, meta_renderer_x11, META_TYPE_RENDERER) + +static const CoglWinsysVtable * +get_x11_cogl_winsys_vtable (CoglRenderer *renderer) +{ +#ifdef COGL_HAS_EGL_PLATFORM_XLIB_SUPPORT + if (meta_is_wayland_compositor ()) + return _cogl_winsys_egl_xlib_get_vtable (); +#endif + + switch (renderer->driver) + { + case COGL_DRIVER_GLES2: +#ifdef COGL_HAS_EGL_PLATFORM_XLIB_SUPPORT + return _cogl_winsys_egl_xlib_get_vtable (); +#else + break; +#endif + case COGL_DRIVER_GL: + case COGL_DRIVER_GL3: +#ifdef COGL_HAS_GLX_SUPPORT + return _cogl_winsys_glx_get_vtable (); +#else + break; +#endif + case COGL_DRIVER_ANY: + case COGL_DRIVER_NOP: + break; + } + g_assert_not_reached (); + return NULL; +} + +static CoglRenderer * +meta_renderer_x11_create_cogl_renderer (MetaRenderer *renderer) +{ + CoglRenderer *cogl_renderer; + Display *xdisplay = clutter_x11_get_default_display (); + + cogl_renderer = cogl_renderer_new (); + cogl_renderer_set_custom_winsys (cogl_renderer, get_x11_cogl_winsys_vtable, + NULL); + cogl_xlib_renderer_set_foreign_display (cogl_renderer, xdisplay); + cogl_xlib_renderer_request_reset_on_video_memory_purge (cogl_renderer, TRUE); + + return cogl_renderer; +} + +static void +meta_renderer_x11_init (MetaRendererX11 *renderer_x11) +{ +} + +static void +meta_renderer_x11_class_init (MetaRendererX11Class *klass) +{ + MetaRendererClass *renderer_class = META_RENDERER_CLASS (klass); + + renderer_class->create_cogl_renderer = meta_renderer_x11_create_cogl_renderer; +} diff --git a/src/backends/x11/meta-renderer-x11.h b/src/backends/x11/meta-renderer-x11.h new file mode 100644 index 000000000..5ec0d4bc4 --- /dev/null +++ b/src/backends/x11/meta-renderer-x11.h @@ -0,0 +1,42 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +#ifndef META_RENDERER_X11_H +#define META_RENDERER_X11_H + +#include <glib-object.h> + +#include "backends/meta-renderer.h" + +struct _MetaRendererX11Class +{ + MetaRendererClass parent_class; +}; + +#define META_TYPE_RENDERER_X11 (meta_renderer_x11_get_type ()) +G_DECLARE_DERIVABLE_TYPE (MetaRendererX11, meta_renderer_x11, + META, RENDERER_X11, + MetaRenderer) + +#endif /* META_RENDERER_X11_H */ diff --git a/clutter/clutter/x11/clutter-device-manager-xi2.c b/src/backends/x11/meta-seat-x11.c similarity index 53% rename from clutter/clutter/x11/clutter-device-manager-xi2.c rename to src/backends/x11/meta-seat-x11.c index 34bddb1fd..ff028bfaa 100644 --- a/clutter/clutter/x11/clutter-device-manager-xi2.c +++ b/src/backends/x11/meta-seat-x11.c @@ -1,9 +1,5 @@ /* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright © 2011 Intel Corp. + * Copyright (C) 2019 Red Hat Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,42 +14,56 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see <http://www.gnu.org/licenses/>. * - * Author: Emmanuele Bassi <ebassi@linux.intel.com> + * Author: Carlos Garnacho <carlosg@gnome.org> */ - -#include "clutter-build-config.h" - -#include <stdint.h> - -#include "clutter-device-manager-xi2.h" - -#include "clutter-backend-x11.h" -#include "clutter-input-device-xi2.h" -#include "clutter-input-device-tool-xi2.h" -#include "clutter-virtual-input-device-x11.h" -#include "clutter-stage-x11.h" - -#include "clutter-backend.h" -#include "clutter-debug.h" -#include "clutter-device-manager-private.h" -#include "clutter-event-private.h" -#include "clutter-event-translator.h" -#include "clutter-stage-private.h" -#include "clutter-private.h" -#include "clutter-xkb-a11y-x11.h" +#include "config.h" #include <X11/extensions/XInput2.h> +#include "backends/x11/meta-event-x11.h" +#include "backends/x11/meta-input-device-tool-x11.h" +#include "backends/x11/meta-input-device-x11.h" +#include "backends/x11/meta-keymap-x11.h" +#include "backends/x11/meta-stage-x11.h" +#include "backends/x11/meta-virtual-input-device-x11.h" +#include "backends/x11/meta-xkb-a11y-x11.h" +#include "clutter/clutter-mutter.h" +#include "clutter/x11/clutter-x11.h" +#include "core/bell.h" +#include "meta-seat-x11.h" + enum { PROP_0, - PROP_OPCODE, + PROP_POINTER_ID, + PROP_KEYBOARD_ID, + N_PROPS, + + /* This property is overridden */ + PROP_TOUCH_MODE, +}; - PROP_LAST +struct _MetaSeatX11 +{ + ClutterSeat parent_instance; + ClutterInputDevice *core_pointer; + ClutterInputDevice *core_keyboard; + GList *devices; + GHashTable *devices_by_id; + GHashTable *tools_by_serial; + MetaKeymapX11 *keymap; + + int pointer_id; + int keyboard_id; + int opcode; + guint has_touchscreens : 1; + guint touch_mode : 1; }; -static GParamSpec *obj_props[PROP_LAST] = { NULL, }; +static GParamSpec *props[N_PROPS] = { 0 }; + +G_DEFINE_TYPE (MetaSeatX11, meta_seat_x11, CLUTTER_TYPE_SEAT) static const char *clutter_input_axis_atom_names[] = { "Abs X", /* CLUTTER_INPUT_AXIS_X */ @@ -65,9 +75,26 @@ static const char *clutter_input_axis_atom_names[] = { "Abs Distance", /* CLUTTER_INPUT_AXIS_DISTANCE */ }; -#define N_AXIS_ATOMS G_N_ELEMENTS (clutter_input_axis_atom_names) +static const char *wacom_type_atoms[] = { + "STYLUS", + "CURSOR", + "ERASER", + "PAD", + "TOUCH" +}; +#define N_WACOM_TYPE_ATOMS G_N_ELEMENTS (wacom_type_atoms) + +enum +{ + WACOM_TYPE_STYLUS, + WACOM_TYPE_CURSOR, + WACOM_TYPE_ERASER, + WACOM_TYPE_PAD, + WACOM_TYPE_TOUCH, +}; -enum { +enum +{ PAD_AXIS_FIRST = 3, /* First axes are always x/y/pressure, ignored in pads */ PAD_AXIS_STRIP1 = PAD_AXIS_FIRST, PAD_AXIS_STRIP2, @@ -75,50 +102,9 @@ enum { PAD_AXIS_RING2, }; -static Atom clutter_input_axis_atoms[N_AXIS_ATOMS] = { 0, }; - -static void clutter_event_translator_iface_init (ClutterEventTranslatorIface *iface); -static void clutter_event_extender_iface_init (ClutterEventExtenderInterface *iface); - -#define clutter_device_manager_xi2_get_type _clutter_device_manager_xi2_get_type - -G_DEFINE_TYPE_WITH_CODE (ClutterDeviceManagerXI2, - clutter_device_manager_xi2, - CLUTTER_TYPE_DEVICE_MANAGER, - G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_EVENT_TRANSLATOR, - clutter_event_translator_iface_init) - G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_EVENT_EXTENDER, - clutter_event_extender_iface_init)) - -static void -clutter_device_manager_x11_copy_event_data (ClutterEventExtender *event_extender, - const ClutterEvent *src, - ClutterEvent *dest) -{ - gpointer event_x11; - - event_x11 = _clutter_event_get_platform_data (src); - if (event_x11 != NULL) - _clutter_event_set_platform_data (dest, _clutter_event_x11_copy (event_x11)); -} - -static void -clutter_device_manager_x11_free_event_data (ClutterEventExtender *event_extender, - ClutterEvent *event) -{ - gpointer event_x11; - - event_x11 = _clutter_event_get_platform_data (event); - if (event_x11 != NULL) - _clutter_event_x11_free (event_x11); -} +#define N_AXIS_ATOMS G_N_ELEMENTS (clutter_input_axis_atom_names) -static void -clutter_event_extender_iface_init (ClutterEventExtenderInterface *iface) -{ - iface->copy_event_data = clutter_device_manager_x11_copy_event_data; - iface->free_event_data = clutter_device_manager_x11_free_event_data; -} +static Atom clutter_input_axis_atoms[N_AXIS_ATOMS] = { 0, }; static void translate_valuator_class (Display *xdisplay, @@ -154,22 +140,21 @@ translate_valuator_class (Display *xdisplay, class->max, class->resolution); - CLUTTER_NOTE (BACKEND, - "Added axis '%s' (min:%.2f, max:%.2fd, res:%d) of device %d", - clutter_input_axis_atom_names[axis], - class->min, - class->max, - class->resolution, - device->id); + g_debug ("Added axis '%s' (min:%.2f, max:%.2fd, res:%d) of device %d", + clutter_input_axis_atom_names[axis], + class->min, + class->max, + class->resolution, + device->id); } static void translate_device_classes (Display *xdisplay, ClutterInputDevice *device, XIAnyClassInfo **classes, - guint n_classes) + int n_classes) { - gint i; + int i; for (i = 0; i < n_classes; i++) { @@ -180,7 +165,7 @@ translate_device_classes (Display *xdisplay, case XIKeyClass: { XIKeyClassInfo *key_info = (XIKeyClassInfo *) class_info; - gint j; + int j; _clutter_input_device_set_n_keys (device, key_info->num_keycodes); @@ -199,7 +184,6 @@ translate_device_classes (Display *xdisplay, (XIValuatorClassInfo *) class_info); break; -#ifdef HAVE_XINPUT_2_2 case XIScrollClass: { XIScrollClassInfo *scroll_info = (XIScrollClassInfo *) class_info; @@ -210,12 +194,12 @@ translate_device_classes (Display *xdisplay, else direction = CLUTTER_SCROLL_RIGHT; - CLUTTER_NOTE (BACKEND, "Scroll valuator %d: %s, increment: %f", - scroll_info->number, - scroll_info->scroll_type == XIScrollTypeVertical - ? "vertical" - : "horizontal", - scroll_info->increment); + g_debug ("Scroll valuator %d: %s, increment: %f", + scroll_info->number, + scroll_info->scroll_type == XIScrollTypeVertical + ? "vertical" + : "horizontal", + scroll_info->increment); _clutter_input_device_add_scroll_info (device, scroll_info->number, @@ -223,7 +207,6 @@ translate_device_classes (Display *xdisplay, scroll_info->increment); } break; -#endif /* HAVE_XINPUT_2_2 */ default: break; @@ -233,12 +216,11 @@ translate_device_classes (Display *xdisplay, static gboolean is_touch_device (XIAnyClassInfo **classes, - guint n_classes, + int n_classes, ClutterInputDeviceType *device_type, - guint *n_touch_points) + uint32_t *n_touch_points) { -#ifdef HAVE_XINPUT_2_2 - guint i; + int i; for (i = 0; i < n_classes; i++) { @@ -261,27 +243,26 @@ is_touch_device (XIAnyClassInfo **classes, return TRUE; } } -#endif return FALSE; } static gboolean -is_touchpad_device (ClutterBackendX11 *backend_x11, - XIDeviceInfo *info) +has_8bit_property (XIDeviceInfo *info, + const char *name) { gulong nitems, bytes_after; - guint32 *data = NULL; + uint32_t *data = NULL; int rc, format; Atom type; Atom prop; - prop = XInternAtom (backend_x11->xdpy, "libinput Tapping Enabled", True); + prop = XInternAtom (clutter_x11_get_default_display (), name, True); if (prop == None) return FALSE; clutter_x11_trap_x_errors (); - rc = XIGetProperty (backend_x11->xdpy, + rc = XIGetProperty (clutter_x11_get_default_display (), info->deviceid, prop, 0, 1, False, XA_INTEGER, &type, &format, &nitems, &bytes_after, @@ -298,20 +279,26 @@ is_touchpad_device (ClutterBackendX11 *backend_x11, } static gboolean -get_device_ids (ClutterBackendX11 *backend_x11, - XIDeviceInfo *info, - gchar **vendor_id, - gchar **product_id) +is_touchpad_device (XIDeviceInfo *info) +{ + return has_8bit_property (info, "libinput Tapping Enabled") || + has_8bit_property (info, "Synaptics Off"); +} + +static gboolean +get_device_ids (XIDeviceInfo *info, + char **vendor_id, + char **product_id) { gulong nitems, bytes_after; - guint32 *data = NULL; + uint32_t *data = NULL; int rc, format; Atom type; clutter_x11_trap_x_errors (); - rc = XIGetProperty (backend_x11->xdpy, + rc = XIGetProperty (clutter_x11_get_default_display (), info->deviceid, - XInternAtom (backend_x11->xdpy, "Device Product ID", False), + XInternAtom (clutter_x11_get_default_display (), "Device Product ID", False), 0, 2, False, XA_INTEGER, &type, &format, &nitems, &bytes_after, (guchar **) &data); clutter_x11_untrap_x_errors (); @@ -332,23 +319,22 @@ get_device_ids (ClutterBackendX11 *backend_x11, return TRUE; } -static gchar * -get_device_node_path (ClutterBackendX11 *backend_x11, - XIDeviceInfo *info) +static char * +get_device_node_path (XIDeviceInfo *info) { gulong nitems, bytes_after; guchar *data; int rc, format; Atom prop, type; - gchar *node_path; + char *node_path; - prop = XInternAtom (backend_x11->xdpy, "Device Node", False); + prop = XInternAtom (clutter_x11_get_default_display (), "Device Node", False); if (prop == None) return NULL; clutter_x11_trap_x_errors (); - rc = XIGetProperty (backend_x11->xdpy, + rc = XIGetProperty (clutter_x11_get_default_display (), info->deviceid, prop, 0, 1024, False, XA_STRING, &type, &format, &nitems, &bytes_after, (guchar **) &data); @@ -370,10 +356,10 @@ get_device_node_path (ClutterBackendX11 *backend_x11, static void get_pad_features (XIDeviceInfo *info, - guint *n_rings, - guint *n_strips) + uint32_t *n_rings, + uint32_t *n_strips) { - gint i, rings = 0, strips = 0; + int i, rings = 0, strips = 0; for (i = PAD_AXIS_FIRST; i < info->num_classes; i++) { @@ -398,23 +384,101 @@ get_pad_features (XIDeviceInfo *info, *n_strips = strips; } +/* The Wacom driver exports the tool type as property. Use that over + guessing based on the device name */ +static gboolean +guess_source_from_wacom_type (XIDeviceInfo *info, + ClutterInputDeviceType *source_out) +{ + gulong nitems, bytes_after; + uint32_t *data = NULL; + int rc, format; + Atom type; + Atom prop; + Atom device_type; + Atom types[N_WACOM_TYPE_ATOMS]; + + prop = XInternAtom (clutter_x11_get_default_display (), "Wacom Tool Type", True); + if (prop == None) + return FALSE; + + clutter_x11_trap_x_errors (); + rc = XIGetProperty (clutter_x11_get_default_display (), + info->deviceid, + prop, + 0, 1, False, XA_ATOM, &type, &format, &nitems, &bytes_after, + (guchar **) &data); + clutter_x11_untrap_x_errors (); + + if (rc != Success || type != XA_ATOM || format != 32 || nitems != 1) + { + XFree (data); + return FALSE; + } + + device_type = *data; + XFree (data); + + if (device_type == 0) + return FALSE; + + rc = XInternAtoms (clutter_x11_get_default_display (), + (char **)wacom_type_atoms, + N_WACOM_TYPE_ATOMS, + False, + types); + if (rc == 0) + return FALSE; + + if (device_type == types[WACOM_TYPE_STYLUS]) + { + *source_out = CLUTTER_PEN_DEVICE; + } + else if (device_type == types[WACOM_TYPE_CURSOR]) + { + *source_out = CLUTTER_CURSOR_DEVICE; + } + else if (device_type == types[WACOM_TYPE_ERASER]) + { + *source_out = CLUTTER_ERASER_DEVICE; + } + else if (device_type == types[WACOM_TYPE_PAD]) + { + *source_out = CLUTTER_PAD_DEVICE; + } + else if (device_type == types[WACOM_TYPE_TOUCH]) + { + uint32_t num_touches = 0; + + if (!is_touch_device (info->classes, info->num_classes, + source_out, &num_touches)) + *source_out = CLUTTER_TOUCHSCREEN_DEVICE; + } + else + { + return FALSE; + } + + return TRUE; +} + static ClutterInputDevice * -create_device (ClutterDeviceManagerXI2 *manager_xi2, - ClutterBackendX11 *backend_x11, - XIDeviceInfo *info) +create_device (MetaSeatX11 *seat_x11, + ClutterBackend *backend, + XIDeviceInfo *info) { ClutterInputDeviceType source, touch_source; ClutterInputDevice *retval; ClutterInputMode mode; gboolean is_enabled; - guint num_touches = 0, num_rings = 0, num_strips = 0; - gchar *vendor_id = NULL, *product_id = NULL, *node_path = NULL; + uint32_t num_touches = 0, num_rings = 0, num_strips = 0; + char *vendor_id = NULL, *product_id = NULL, *node_path = NULL; if (info->use == XIMasterKeyboard || info->use == XISlaveKeyboard) { source = CLUTTER_KEYBOARD_DEVICE; } - else if (is_touchpad_device (backend_x11, info)) + else if (is_touchpad_device (info)) { source = CLUTTER_TOUCHPAD_DEVICE; } @@ -425,9 +489,9 @@ create_device (ClutterDeviceManagerXI2 *manager_xi2, { source = touch_source; } - else + else if (!guess_source_from_wacom_type (info, &source)) { - gchar *name; + char *name; name = g_ascii_strdown (info->name, -1); @@ -444,7 +508,7 @@ create_device (ClutterDeviceManagerXI2 *manager_xi2, else source = CLUTTER_POINTER_DEVICE; - free (name); + g_free (name); } switch (info->use) @@ -471,8 +535,8 @@ create_device (ClutterDeviceManagerXI2 *manager_xi2, if (info->use != XIMasterKeyboard && info->use != XIMasterPointer) { - get_device_ids (backend_x11, info, &vendor_id, &product_id); - node_path = get_device_node_path (backend_x11, info); + get_device_ids (info, &vendor_id, &product_id); + node_path = get_device_node_path (info); } if (source == CLUTTER_PAD_DEVICE) @@ -481,14 +545,13 @@ create_device (ClutterDeviceManagerXI2 *manager_xi2, get_pad_features (info, &num_rings, &num_strips); } - retval = g_object_new (CLUTTER_TYPE_INPUT_DEVICE_XI2, + retval = g_object_new (META_TYPE_INPUT_DEVICE_X11, "name", info->name, "id", info->deviceid, "has-cursor", (info->use == XIMasterPointer), - "device-manager", manager_xi2, "device-type", source, "device-mode", mode, - "backend", backend_x11, + "backend", backend, "enabled", is_enabled, "vendor-id", vendor_id, "product-id", product_id, @@ -496,25 +559,21 @@ create_device (ClutterDeviceManagerXI2 *manager_xi2, "n-rings", num_rings, "n-strips", num_strips, "n-mode-groups", MAX (num_rings, num_strips), + "seat", seat_x11, NULL); - translate_device_classes (backend_x11->xdpy, retval, + translate_device_classes (clutter_x11_get_default_display (), retval, info->classes, info->num_classes); -#ifdef HAVE_LIBWACOM - if (source == CLUTTER_PAD_DEVICE) - clutter_input_device_xi2_ensure_wacom_info (retval, manager_xi2->wacom_db); -#endif - - free (vendor_id); - free (product_id); - free (node_path); + g_free (vendor_id); + g_free (product_id); + g_free (node_path); - CLUTTER_NOTE (BACKEND, "Created device '%s' (id: %d, has-cursor: %s)", - info->name, - info->deviceid, - info->use == XIMasterPointer ? "yes" : "no"); + g_debug ("Created device '%s' (id: %d, has-cursor: %s)", + info->name, + info->deviceid, + info->use == XIMasterPointer ? "yes" : "no"); return retval; } @@ -524,7 +583,7 @@ pad_passive_button_grab (ClutterInputDevice *device) { XIGrabModifiers xi_grab_mods = { XIAnyModifier, }; XIEventMask xi_event_mask; - gint device_id, rc; + int device_id, rc; device_id = clutter_input_device_get_device_id (device); @@ -556,42 +615,59 @@ pad_passive_button_grab (ClutterInputDevice *device) clutter_x11_untrap_x_errors (); - free (xi_event_mask.mask); + g_free (xi_event_mask.mask); +} + +static void +update_touch_mode (MetaSeatX11 *seat_x11) +{ + gboolean touch_mode; + + touch_mode = seat_x11->has_touchscreens; + + if (seat_x11->touch_mode == touch_mode) + return; + + seat_x11->touch_mode = touch_mode; + g_object_notify (G_OBJECT (seat_x11), "touch-mode"); } static ClutterInputDevice * -add_device (ClutterDeviceManagerXI2 *manager_xi2, - ClutterBackendX11 *backend_x11, - XIDeviceInfo *info, - gboolean in_construction) +add_device (MetaSeatX11 *seat_x11, + ClutterBackend *backend, + XIDeviceInfo *info, + gboolean in_construction) { ClutterInputDevice *device; - device = create_device (manager_xi2, backend_x11, info); + device = create_device (seat_x11, backend, info); - /* we don't go through the DeviceManager::add_device() vfunc because - * that emits the signal, and we only do it conditionally - */ - g_hash_table_replace (manager_xi2->devices_by_id, + g_hash_table_replace (seat_x11->devices_by_id, GINT_TO_POINTER (info->deviceid), device); - if (info->use == XIMasterPointer || - info->use == XIMasterKeyboard) + if (info->use == XIMasterPointer && + info->deviceid == seat_x11->pointer_id) + { + seat_x11->core_pointer = device; + } + else if (info->use == XIMasterKeyboard && + info->deviceid == seat_x11->keyboard_id) { - manager_xi2->master_devices = - g_list_prepend (manager_xi2->master_devices, device); + seat_x11->core_keyboard = device; } - else if (info->use == XISlavePointer || - info->use == XISlaveKeyboard || - info->use == XIFloatingSlave) + else if ((info->use == XISlavePointer && + info->attachment == seat_x11->pointer_id) || + (info->use == XISlaveKeyboard && + info->attachment == seat_x11->keyboard_id)) { - manager_xi2->slave_devices = - g_list_prepend (manager_xi2->slave_devices, device); + seat_x11->devices = g_list_prepend (seat_x11->devices, device); } else - g_warning ("Unhandled device: %s", - clutter_input_device_get_device_name (device)); + { + g_warning ("Unhandled device: %s", + clutter_input_device_get_device_name (device)); + } if (clutter_input_device_get_device_type (device) == CLUTTER_PAD_DEVICE) pad_passive_button_grab (device); @@ -605,85 +681,196 @@ add_device (ClutterDeviceManagerXI2 *manager_xi2, { ClutterInputDevice *master; - master = g_hash_table_lookup (manager_xi2->devices_by_id, + master = g_hash_table_lookup (seat_x11->devices_by_id, GINT_TO_POINTER (info->attachment)); _clutter_input_device_set_associated_device (device, master); _clutter_input_device_add_slave (master, device); } + } + + return device; +} - /* blow the cache */ - g_slist_free (manager_xi2->all_devices); - manager_xi2->all_devices = NULL; +static gboolean +has_touchscreens (MetaSeatX11 *seat_x11) +{ + GList *l; - g_signal_emit_by_name (manager_xi2, "device-added", device); + for (l = seat_x11->devices; l; l = l->next) + { + if (clutter_input_device_get_device_type (l->data) == CLUTTER_TOUCHSCREEN_DEVICE) + return TRUE; } - return device; + return FALSE; } static void -remove_device (ClutterDeviceManagerXI2 *manager_xi2, - gint device_id) +remove_device (MetaSeatX11 *seat_x11, + ClutterInputDevice *device) { - ClutterInputDevice *device; + if (seat_x11->core_pointer == device) + { + seat_x11->core_pointer = NULL; + } + else if (seat_x11->core_keyboard == device) + { + seat_x11->core_keyboard = NULL; + } + else + { + seat_x11->devices = g_list_remove (seat_x11->devices, device); + } +} + +static gboolean +meta_seat_x11_handle_device_event (ClutterSeat *seat, + ClutterEvent *event) +{ + MetaSeatX11 *seat_x11 = META_SEAT_X11 (seat); + ClutterInputDevice *device = event->device.device; + gboolean is_touch; - device = g_hash_table_lookup (manager_xi2->devices_by_id, - GINT_TO_POINTER (device_id)); + is_touch = + clutter_input_device_get_device_type (device) == CLUTTER_TOUCHSCREEN_DEVICE; - if (device != NULL) + switch (event->type) { - manager_xi2->master_devices = - g_list_remove (manager_xi2->master_devices, device); - manager_xi2->slave_devices = - g_list_remove (manager_xi2->slave_devices, device); + case CLUTTER_DEVICE_ADDED: + seat_x11->has_touchscreens |= is_touch; + break; + case CLUTTER_DEVICE_REMOVED: + if (is_touch) + seat_x11->has_touchscreens = has_touchscreens (seat_x11); + break; + default: + break; + } + + if (is_touch) + update_touch_mode (seat_x11); - /* blow the cache */ - g_slist_free (manager_xi2->all_devices); - manager_xi2->all_devices = NULL; + return TRUE; +} - g_signal_emit_by_name (manager_xi2, "device-removed", device); +static void +relate_masters (gpointer key, + gpointer value, + gpointer data) +{ + MetaSeatX11 *seat_x11 = data; + ClutterInputDevice *device, *relative; - g_object_run_dispose (G_OBJECT (device)); + device = g_hash_table_lookup (seat_x11->devices_by_id, key); + relative = g_hash_table_lookup (seat_x11->devices_by_id, value); - g_hash_table_remove (manager_xi2->devices_by_id, - GINT_TO_POINTER (device_id)); - } + _clutter_input_device_set_associated_device (device, relative); + _clutter_input_device_set_associated_device (relative, device); } static void -translate_hierarchy_event (ClutterBackendX11 *backend_x11, - ClutterDeviceManagerXI2 *manager_xi2, - XIHierarchyEvent *ev) +relate_slaves (gpointer key, + gpointer value, + gpointer data) +{ + MetaSeatX11 *seat_x11 = data; + ClutterInputDevice *master, *slave; + + slave = g_hash_table_lookup (seat_x11->devices_by_id, key); + master = g_hash_table_lookup (seat_x11->devices_by_id, value); + + _clutter_input_device_set_associated_device (slave, master); + _clutter_input_device_add_slave (master, slave); +} + +static uint +device_get_tool_serial (ClutterInputDevice *device) +{ + gulong nitems, bytes_after; + uint32_t *data = NULL; + int serial_id = 0; + int rc, format; + Atom type; + Atom prop; + + prop = XInternAtom (clutter_x11_get_default_display (), "Wacom Serial IDs", True); + if (prop == None) + return 0; + + clutter_x11_trap_x_errors (); + rc = XIGetProperty (clutter_x11_get_default_display (), + clutter_input_device_get_device_id (device), + prop, 0, 4, FALSE, XA_INTEGER, &type, &format, &nitems, &bytes_after, + (guchar **) &data); + clutter_x11_untrap_x_errors (); + + if (rc == Success && type == XA_INTEGER && format == 32 && nitems >= 4) + serial_id = data[3]; + + XFree (data); + + return serial_id; +} + +static gboolean +translate_hierarchy_event (ClutterBackend *backend, + MetaSeatX11 *seat_x11, + XIHierarchyEvent *ev, + ClutterEvent *event) { int i; + gboolean retval = FALSE; for (i = 0; i < ev->num_info; i++) { if (ev->info[i].flags & XIDeviceEnabled && - !g_hash_table_lookup (manager_xi2->devices_by_id, + !g_hash_table_lookup (seat_x11->devices_by_id, GINT_TO_POINTER (ev->info[i].deviceid))) { XIDeviceInfo *info; int n_devices; - CLUTTER_NOTE (EVENT, "Hierarchy event: device enabled"); + g_debug ("Hierarchy event: device enabled"); clutter_x11_trap_x_errors (); - info = XIQueryDevice (backend_x11->xdpy, + info = XIQueryDevice (clutter_x11_get_default_display (), ev->info[i].deviceid, &n_devices); clutter_x11_untrap_x_errors (); if (info != NULL) { - add_device (manager_xi2, backend_x11, &info[0], FALSE); + ClutterInputDevice *device; + + device = add_device (seat_x11, backend, &info[0], FALSE); + + event->any.type = CLUTTER_DEVICE_ADDED; + event->any.time = ev->time; + clutter_event_set_device (event, device); + + retval = TRUE; XIFreeDeviceInfo (info); } } else if (ev->info[i].flags & XIDeviceDisabled) { - CLUTTER_NOTE (EVENT, "Hierarchy event: device disabled"); + g_autoptr (ClutterInputDevice) device = NULL; + g_debug ("Hierarchy event: device disabled"); - remove_device (manager_xi2, ev->info[i].deviceid); + g_hash_table_steal_extended (seat_x11->devices_by_id, + GINT_TO_POINTER (ev->info[i].deviceid), + NULL, + (gpointer) &device); + + if (device != NULL) + { + remove_device (seat_x11, device); + + event->any.type = CLUTTER_DEVICE_REMOVED; + event->any.time = ev->time; + clutter_event_set_device (event, device); + + retval = TRUE; + } } else if ((ev->info[i].flags & XISlaveAttached) || (ev->info[i].flags & XISlaveDetached)) @@ -691,14 +878,13 @@ translate_hierarchy_event (ClutterBackendX11 *backend_x11, ClutterInputDevice *master, *slave; XIDeviceInfo *info; int n_devices; - gboolean send_changed = FALSE; - CLUTTER_NOTE (EVENT, "Hierarchy event: slave %s", - (ev->info[i].flags & XISlaveAttached) - ? "attached" - : "detached"); + g_debug ("Hierarchy event: slave %s", + (ev->info[i].flags & XISlaveAttached) + ? "attached" + : "detached"); - slave = g_hash_table_lookup (manager_xi2->devices_by_id, + slave = g_hash_table_lookup (seat_x11->devices_by_id, GINT_TO_POINTER (ev->info[i].deviceid)); master = clutter_input_device_get_associated_device (slave); @@ -707,75 +893,246 @@ translate_hierarchy_event (ClutterBackendX11 *backend_x11, { _clutter_input_device_remove_slave (master, slave); _clutter_input_device_set_associated_device (slave, NULL); - - send_changed = TRUE; } /* and attach the slave to the new master if needed */ if (ev->info[i].flags & XISlaveAttached) { clutter_x11_trap_x_errors (); - info = XIQueryDevice (backend_x11->xdpy, + info = XIQueryDevice (clutter_x11_get_default_display (), ev->info[i].deviceid, &n_devices); clutter_x11_untrap_x_errors (); if (info != NULL) { - master = g_hash_table_lookup (manager_xi2->devices_by_id, + master = g_hash_table_lookup (seat_x11->devices_by_id, GINT_TO_POINTER (info->attachment)); if (master != NULL) { _clutter_input_device_set_associated_device (slave, master); _clutter_input_device_add_slave (master, slave); - - send_changed = TRUE; } XIFreeDeviceInfo (info); } } + } + } + + return retval; +} + +static void +translate_property_event (MetaSeatX11 *seat_x11, + XIEvent *event) +{ + XIPropertyEvent *xev = (XIPropertyEvent *) event; + Atom serial_ids_prop = XInternAtom (clutter_x11_get_default_display (), "Wacom Serial IDs", True); + ClutterInputDevice *device; + + device = g_hash_table_lookup (seat_x11->devices_by_id, + GINT_TO_POINTER (xev->deviceid)); + if (!device) + return; + + if (xev->property == serial_ids_prop) + { + ClutterInputDeviceTool *tool = NULL; + ClutterInputDeviceToolType type; + int serial_id; - if (send_changed) + serial_id = device_get_tool_serial (device); + + if (serial_id != 0) + { + tool = g_hash_table_lookup (seat_x11->tools_by_serial, + GUINT_TO_POINTER (serial_id)); + if (!tool) { - ClutterStage *stage = _clutter_input_device_get_stage (master); - if (stage != NULL) - _clutter_stage_x11_events_device_changed (CLUTTER_STAGE_X11 (_clutter_stage_get_window (stage)), - master, - CLUTTER_DEVICE_MANAGER (manager_xi2)); + type = clutter_input_device_get_device_type (device) == CLUTTER_ERASER_DEVICE ? + CLUTTER_INPUT_DEVICE_TOOL_ERASER : CLUTTER_INPUT_DEVICE_TOOL_PEN; + tool = meta_input_device_tool_x11_new (serial_id, type); + g_hash_table_insert (seat_x11->tools_by_serial, + GUINT_TO_POINTER (serial_id), + tool); } } + + meta_input_device_x11_update_tool (device, tool); + g_signal_emit_by_name (seat_x11, "tool-changed", device, tool); } } static void -clutter_device_manager_xi2_select_events (ClutterDeviceManager *manager, - Window xwindow, - XIEventMask *event_mask) +translate_raw_event (MetaSeatX11 *seat_x11, + XEvent *xevent) { - Display *xdisplay; + ClutterInputDevice *device; + XGenericEventCookie *cookie; + XIEvent *xi_event; + XIRawEvent *xev; + float x,y; - xdisplay = clutter_x11_get_default_display (); + cookie = &xevent->xcookie; + xi_event = (XIEvent *) cookie->data; + xev = (XIRawEvent *) xi_event; + + device = g_hash_table_lookup (seat_x11->devices_by_id, + GINT_TO_POINTER (xev->deviceid)); + if (device == NULL) + return; + + if (!_clutter_is_input_pointer_a11y_enabled (device)) + return; - XISelectEvents (xdisplay, xwindow, event_mask, 1); + switch (cookie->evtype) + { + case XI_RawMotion: + g_debug ("raw motion: device:%d '%s'", + device->id, + device->device_name); + + /* We don't get actual pointer location with raw events, and we cannot + * rely on `clutter_input_device_get_coords()` either because of + * unreparented toplevels (like all client-side decoration windows), + * so we need to explicitely query the pointer here... + */ + if (meta_input_device_x11_get_pointer_location (device, &x, &y)) + _clutter_input_pointer_a11y_on_motion_event (device, x, y); + break; + case XI_RawButtonPress: + case XI_RawButtonRelease: + g_debug ("raw button %s: device:%d '%s' button %i", + cookie->evtype == XI_RawButtonPress + ? "press " + : "release", + device->id, + device->device_name, + xev->detail); + _clutter_input_pointer_a11y_on_button_event (device, + xev->detail, + (cookie->evtype == XI_RawButtonPress)); + break; + } } -static ClutterStage * -get_event_stage (ClutterEventTranslator *translator, - XIEvent *xi_event) +static gboolean +translate_pad_axis (ClutterInputDevice *device, + XIValuatorState *valuators, + ClutterEventType *evtype, + uint32_t *number, + double *value) { - Window xwindow = None; + double *values; + int i; - switch (xi_event->evtype) - { - case XI_KeyPress: + values = valuators->values; + + for (i = PAD_AXIS_FIRST; i < valuators->mask_len * 8; i++) + { + double val; + uint32_t axis_number = 0; + + if (!XIMaskIsSet (valuators->mask, i)) + continue; + + val = *values++; + if (val <= 0) + continue; + + _clutter_input_device_translate_axis (device, i, val, value); + + if (i == PAD_AXIS_RING1 || i == PAD_AXIS_RING2) + { + *evtype = CLUTTER_PAD_RING; + (*value) *= 360.0; + } + else if (i == PAD_AXIS_STRIP1 || i == PAD_AXIS_STRIP2) + { + *evtype = CLUTTER_PAD_STRIP; + } + else + continue; + + if (i == PAD_AXIS_STRIP2 || i == PAD_AXIS_RING2) + axis_number++; + + *number = axis_number; + return TRUE; + } + + return FALSE; +} + +static gboolean +translate_pad_event (ClutterEvent *event, + XIDeviceEvent *xev, + ClutterInputDevice *device) +{ + double value; + uint32_t number, mode = 0; + + if (!translate_pad_axis (device, &xev->valuators, + &event->any.type, + &number, &value)) + return FALSE; + + /* When touching a ring/strip a first XI_Motion event + * is generated. Use it to reset the pad state, so + * later events actually have a directionality. + */ + if (xev->evtype == XI_Motion) + value = -1; + +#ifdef HAVE_LIBWACOM + mode = meta_input_device_x11_get_pad_group_mode (device, number); +#endif + + if (event->any.type == CLUTTER_PAD_RING) + { + event->pad_ring.ring_number = number; + event->pad_ring.angle = value; + event->pad_ring.mode = mode; + } + else + { + event->pad_strip.strip_number = number; + event->pad_strip.value = value; + event->pad_strip.mode = mode; + } + + event->any.time = xev->time; + clutter_event_set_device (event, device); + clutter_event_set_source_device (event, device); + + g_debug ("%s: win:0x%x, device:%d '%s', time:%d " + "(value:%f)", + event->any.type == CLUTTER_PAD_RING + ? "pad ring " + : "pad strip", + (unsigned int) xev->event, + device->id, + device->device_name, + event->any.time, value); + + return TRUE; +} + +static ClutterStage * +get_event_stage (MetaSeatX11 *seat_x11, + XIEvent *xi_event) +{ + Window xwindow = None; + + switch (xi_event->evtype) + { + case XI_KeyPress: case XI_KeyRelease: case XI_ButtonPress: case XI_ButtonRelease: case XI_Motion: -#ifdef HAVE_XINPUT_2_2 case XI_TouchBegin: case XI_TouchUpdate: case XI_TouchEnd: -#endif /* HAVE_XINPUT_2_2 */ { XIDeviceEvent *xev = (XIDeviceEvent *) xi_event; @@ -794,6 +1151,9 @@ get_event_stage (ClutterEventTranslator *translator, } break; + case XI_HierarchyChanged: + return CLUTTER_STAGE (meta_backend_get_stage (meta_get_backend ())); + default: break; } @@ -801,7 +1161,7 @@ get_event_stage (ClutterEventTranslator *translator, if (xwindow == None) return NULL; - return clutter_x11_get_stage_from_window (xwindow); + return meta_x11_get_stage_from_window (xwindow); } /* @@ -858,24 +1218,24 @@ print_keysym (uint32_t symbol, return 1; } -static gdouble * +static double * translate_axes (ClutterInputDevice *device, - gdouble x, - gdouble y, + double x, + double y, XIValuatorState *valuators) { - guint n_axes = clutter_input_device_get_n_axes (device); - guint i; - gdouble *retval; + uint32_t n_axes = clutter_input_device_get_n_axes (device); + uint32_t i; + double *retval; double *values; - retval = g_new0 (gdouble, n_axes); + retval = g_new0 (double, n_axes); values = valuators->values; for (i = 0; i < valuators->mask_len * 8; i++) { ClutterInputAxis axis; - gdouble val; + double val; if (!XIMaskIsSet (valuators->mask, i)) continue; @@ -902,80 +1262,14 @@ translate_axes (ClutterInputDevice *device, return retval; } -static gboolean -translate_pad_axis (ClutterInputDevice *device, - XIValuatorState *valuators, - ClutterEventType *evtype, - guint *number, - gdouble *value) -{ - double *values; - gint i; - - values = valuators->values; - - for (i = PAD_AXIS_FIRST; i < valuators->mask_len * 8; i++) - { - gdouble val; - guint axis_number = 0; - - if (!XIMaskIsSet (valuators->mask, i)) - continue; - - val = *values++; - if (val <= 0) - continue; - - _clutter_input_device_translate_axis (device, i, val, value); - - if (i == PAD_AXIS_RING1 || i == PAD_AXIS_RING2) - { - *evtype = CLUTTER_PAD_RING; - (*value) *= 360.0; - } - else if (i == PAD_AXIS_STRIP1 || i == PAD_AXIS_STRIP2) - { - *evtype = CLUTTER_PAD_STRIP; - } - else - continue; - - if (i == PAD_AXIS_STRIP2 || i == PAD_AXIS_RING2) - axis_number++; - - *number = axis_number; - return TRUE; - } - - return FALSE; -} - -static void -translate_coords (ClutterStageX11 *stage_x11, - gdouble event_x, - gdouble event_y, - gfloat *x_out, - gfloat *y_out) -{ - ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11); - ClutterActor *stage = CLUTTER_ACTOR (stage_cogl->wrapper); - gfloat stage_width; - gfloat stage_height; - - clutter_actor_get_size (stage, &stage_width, &stage_height); - - *x_out = CLAMP (event_x, 0, stage_width); - *y_out = CLAMP (event_y, 0, stage_height); -} - -static gdouble +static double scroll_valuators_changed (ClutterInputDevice *device, XIValuatorState *valuators, - gdouble *dx_p, - gdouble *dy_p) + double *dx_p, + double *dy_p) { gboolean retval = FALSE; - guint n_axes, n_val, i; + uint32_t n_axes, n_val, i; double *values; n_axes = clutter_input_device_get_n_axes (device); @@ -988,7 +1282,7 @@ scroll_valuators_changed (ClutterInputDevice *device, for (i = 0; i < MIN (valuators->mask_len * 8, n_axes); i++) { ClutterScrollDirection direction; - gdouble delta; + double delta; if (!XIMaskIsSet (valuators->mask, i)) continue; @@ -1014,213 +1308,441 @@ scroll_valuators_changed (ClutterInputDevice *device, } static void -clutter_device_manager_xi2_select_stage_events (ClutterDeviceManager *manager, - ClutterStage *stage) +translate_coords (MetaStageX11 *stage_x11, + double event_x, + double event_y, + float *x_out, + float *y_out) { - ClutterBackendX11 *backend_x11; - ClutterStageX11 *stage_x11; - XIEventMask xi_event_mask; - unsigned char *mask; - int len; + ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11); + ClutterActor *stage = CLUTTER_ACTOR (stage_cogl->wrapper); + float stage_width; + float stage_height; - backend_x11 = CLUTTER_BACKEND_X11 (clutter_get_default_backend ()); - stage_x11 = CLUTTER_STAGE_X11 (_clutter_stage_get_window (stage)); + clutter_actor_get_size (stage, &stage_width, &stage_height); - len = XIMaskLen (XI_LASTEVENT); - mask = g_new0 (unsigned char, len); + *x_out = CLAMP (event_x, 0, stage_width); + *y_out = CLAMP (event_y, 0, stage_height); +} - XISetMask (mask, XI_Motion); - XISetMask (mask, XI_ButtonPress); - XISetMask (mask, XI_ButtonRelease); - XISetMask (mask, XI_KeyPress); - XISetMask (mask, XI_KeyRelease); - XISetMask (mask, XI_Enter); - XISetMask (mask, XI_Leave); +static void +on_keymap_state_change (MetaKeymapX11 *keymap_x11, + gpointer data) +{ + ClutterSeat *seat = CLUTTER_SEAT (data); + ClutterKbdA11ySettings kbd_a11y_settings; + + /* On keymaps state change, just reapply the current settings, it'll + * take care of enabling/disabling mousekeys based on NumLock state. + */ + clutter_seat_get_kbd_a11y_settings (seat, &kbd_a11y_settings); + meta_seat_x11_apply_kbd_a11y_settings (seat, &kbd_a11y_settings); +} -#ifdef HAVE_XINPUT_2_2 - /* enable touch event support if we're running on XInput 2.2 */ - if (backend_x11->xi_minor >= 2) +static void +meta_seat_x11_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaSeatX11 *seat_x11 = META_SEAT_X11 (object); + + switch (prop_id) { - XISetMask (mask, XI_TouchBegin); - XISetMask (mask, XI_TouchUpdate); - XISetMask (mask, XI_TouchEnd); + case PROP_OPCODE: + seat_x11->opcode = g_value_get_int (value); + break; + case PROP_POINTER_ID: + seat_x11->pointer_id = g_value_get_int (value); + break; + case PROP_KEYBOARD_ID: + seat_x11->keyboard_id = g_value_get_int (value); + break; + case PROP_TOUCH_MODE: + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } -#endif /* HAVE_XINPUT_2_2 */ +} - xi_event_mask.deviceid = XIAllMasterDevices; - xi_event_mask.mask = mask; - xi_event_mask.mask_len = len; +static void +meta_seat_x11_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaSeatX11 *seat_x11 = META_SEAT_X11 (object); - XISelectEvents (backend_x11->xdpy, stage_x11->xwin, &xi_event_mask, 1); + switch (prop_id) + { + case PROP_OPCODE: + g_value_set_int (value, seat_x11->opcode); + break; + case PROP_POINTER_ID: + g_value_set_int (value, seat_x11->pointer_id); + break; + case PROP_KEYBOARD_ID: + g_value_set_int (value, seat_x11->keyboard_id); + break; + case PROP_TOUCH_MODE: + g_value_set_boolean (value, seat_x11->touch_mode); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +void +meta_seat_x11_notify_devices (MetaSeatX11 *seat_x11, + ClutterStage *stage) +{ + GHashTableIter iter; + ClutterInputDevice *device; - free (mask); + g_hash_table_iter_init (&iter, seat_x11->devices_by_id); + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &device)) + { + ClutterEvent *event; + + event = clutter_event_new (CLUTTER_DEVICE_ADDED); + clutter_event_set_device (event, device); + clutter_event_set_stage (event, stage); + clutter_do_event (event); + } } -static guint -device_get_tool_serial (ClutterBackendX11 *backend_x11, - ClutterInputDevice *device) +static void +meta_seat_x11_constructed (GObject *object) { - gulong nitems, bytes_after; - guint32 *data = NULL; - guint serial_id = 0; - int rc, format; - Atom type; - Atom prop; + MetaSeatX11 *seat_x11 = META_SEAT_X11 (object); + ClutterBackend *backend = clutter_get_default_backend (); + GHashTable *masters, *slaves; + XIDeviceInfo *info; + XIEventMask event_mask; + unsigned char mask[XIMaskLen(XI_LASTEVENT)] = { 0, }; + int n_devices, i; + Display *xdisplay; - prop = XInternAtom (backend_x11->xdpy, "Wacom Serial IDs", True); - if (prop == None) - return 0; + xdisplay = clutter_x11_get_default_display (); + masters = g_hash_table_new (NULL, NULL); + slaves = g_hash_table_new (NULL, NULL); - clutter_x11_trap_x_errors (); - rc = XIGetProperty (backend_x11->xdpy, - clutter_input_device_get_device_id (device), - prop, 0, 4, FALSE, XA_INTEGER, &type, &format, &nitems, &bytes_after, - (guchar **) &data); - clutter_x11_untrap_x_errors (); + info = XIQueryDevice (clutter_x11_get_default_display (), + XIAllDevices, &n_devices); - if (rc == Success && type == XA_INTEGER && format == 32 && nitems >= 4) - serial_id = data[3]; + for (i = 0; i < n_devices; i++) + { + XIDeviceInfo *xi_device = &info[i]; - XFree (data); + if (!xi_device->enabled) + continue; - return serial_id; + add_device (seat_x11, backend, xi_device, TRUE); + + if (xi_device->use == XIMasterPointer || + xi_device->use == XIMasterKeyboard) + { + g_hash_table_insert (masters, + GINT_TO_POINTER (xi_device->deviceid), + GINT_TO_POINTER (xi_device->attachment)); + } + else if (xi_device->use == XISlavePointer || + xi_device->use == XISlaveKeyboard) + { + g_hash_table_insert (slaves, + GINT_TO_POINTER (xi_device->deviceid), + GINT_TO_POINTER (xi_device->attachment)); + } + } + + XIFreeDeviceInfo (info); + + g_hash_table_foreach (masters, relate_masters, seat_x11); + g_hash_table_destroy (masters); + + g_hash_table_foreach (slaves, relate_slaves, seat_x11); + g_hash_table_destroy (slaves); + + XISetMask (mask, XI_HierarchyChanged); + XISetMask (mask, XI_DeviceChanged); + XISetMask (mask, XI_PropertyEvent); + + event_mask.deviceid = XIAllDevices; + event_mask.mask_len = sizeof (mask); + event_mask.mask = mask; + + XISelectEvents (xdisplay, clutter_x11_get_root_window (), + &event_mask, 1); + + memset(mask, 0, sizeof (mask)); + XISetMask (mask, XI_RawMotion); + XISetMask (mask, XI_RawButtonPress); + XISetMask (mask, XI_RawButtonRelease); + + event_mask.deviceid = XIAllMasterDevices; + event_mask.mask_len = sizeof (mask); + event_mask.mask = mask; + + XISelectEvents (xdisplay, clutter_x11_get_root_window (), + &event_mask, 1); + + XSync (xdisplay, False); + + seat_x11->keymap = g_object_new (META_TYPE_KEYMAP_X11, + "backend", backend, + NULL); + g_signal_connect (seat_x11->keymap, + "state-changed", + G_CALLBACK (on_keymap_state_change), + seat_x11); + + meta_seat_x11_a11y_init (CLUTTER_SEAT (seat_x11)); + + if (G_OBJECT_CLASS (meta_seat_x11_parent_class)->constructed) + G_OBJECT_CLASS (meta_seat_x11_parent_class)->constructed (object); } static void -handle_property_event (ClutterDeviceManagerXI2 *manager_xi2, - XIEvent *event) +meta_seat_x11_finalize (GObject *object) { - XIPropertyEvent *xev = (XIPropertyEvent *) event; - ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (clutter_get_default_backend ()); - Atom serial_ids_prop = XInternAtom (backend_x11->xdpy, "Wacom Serial IDs", True); - ClutterInputDevice *device; + MetaSeatX11 *seat_x11 = META_SEAT_X11 (object); - device = g_hash_table_lookup (manager_xi2->devices_by_id, - GINT_TO_POINTER (xev->deviceid)); - if (!device) - return; + g_hash_table_unref (seat_x11->devices_by_id); + g_hash_table_unref (seat_x11->tools_by_serial); + g_list_free (seat_x11->devices); - if (xev->property == serial_ids_prop) - { - ClutterInputDeviceTool *tool = NULL; - ClutterInputDeviceToolType type; - guint serial_id; + G_OBJECT_CLASS (meta_seat_x11_parent_class)->finalize (object); +} - serial_id = device_get_tool_serial (backend_x11, device); +static ClutterInputDevice * +meta_seat_x11_get_pointer (ClutterSeat *seat) +{ + MetaSeatX11 *seat_x11 = META_SEAT_X11 (seat); - if (serial_id != 0) - { - tool = g_hash_table_lookup (manager_xi2->tools_by_serial, - GUINT_TO_POINTER (serial_id)); - if (!tool) - { - type = clutter_input_device_get_device_type (device) == CLUTTER_ERASER_DEVICE ? - CLUTTER_INPUT_DEVICE_TOOL_ERASER : CLUTTER_INPUT_DEVICE_TOOL_PEN; - tool = clutter_input_device_tool_xi2_new (serial_id, type); - g_hash_table_insert (manager_xi2->tools_by_serial, - GUINT_TO_POINTER (serial_id), - tool); - } - } + return seat_x11->core_pointer; +} + +static ClutterInputDevice * +meta_seat_x11_get_keyboard (ClutterSeat *seat) +{ + MetaSeatX11 *seat_x11 = META_SEAT_X11 (seat); + + return seat_x11->core_keyboard; +} + +static GList * +meta_seat_x11_list_devices (ClutterSeat *seat) +{ + MetaSeatX11 *seat_x11 = META_SEAT_X11 (seat); + GList *retval = NULL, *l; + + for (l = seat_x11->devices; l; l = l->next) + retval = g_list_prepend (retval, l->data); + + return retval; +} + +static void +meta_seat_x11_bell_notify (ClutterSeat *seat) +{ + MetaDisplay *display = meta_get_display (); + + meta_bell_notify (display, NULL); +} + +static ClutterKeymap * +meta_seat_x11_get_keymap (ClutterSeat *seat) +{ + return CLUTTER_KEYMAP (META_SEAT_X11 (seat)->keymap); +} + +static void +meta_seat_x11_copy_event_data (ClutterSeat *seat, + const ClutterEvent *src, + ClutterEvent *dest) +{ + gpointer event_x11; + + event_x11 = _clutter_event_get_platform_data (src); + if (event_x11 != NULL) + _clutter_event_set_platform_data (dest, meta_event_x11_copy (event_x11)); +} + +static void +meta_seat_x11_free_event_data (ClutterSeat *seat, + ClutterEvent *event) +{ + gpointer event_x11; + + event_x11 = _clutter_event_get_platform_data (event); + if (event_x11 != NULL) + meta_event_x11_free (event_x11); +} + +static ClutterVirtualInputDevice * +meta_seat_x11_create_virtual_device (ClutterSeat *seat, + ClutterInputDeviceType device_type) +{ + return g_object_new (META_TYPE_VIRTUAL_INPUT_DEVICE_X11, + "seat", seat, + "device-type", device_type, + NULL); +} - clutter_input_device_xi2_update_tool (device, tool); - g_signal_emit_by_name (manager_xi2, "tool-changed", device, tool); - } +static ClutterVirtualDeviceType +meta_seat_x11_get_supported_virtual_device_types (ClutterSeat *seat) +{ + return (CLUTTER_VIRTUAL_DEVICE_TYPE_KEYBOARD | + CLUTTER_VIRTUAL_DEVICE_TYPE_POINTER); } -static gboolean -translate_pad_event (ClutterEvent *event, - XIDeviceEvent *xev, - ClutterInputDevice *device) +static void +meta_seat_x11_warp_pointer (ClutterSeat *seat, + int x, + int y) { - gdouble value; - guint number, mode = 0; + MetaSeatX11 *seat_x11 = META_SEAT_X11 (seat); + + XIWarpPointer (clutter_x11_get_default_display (), + seat_x11->pointer_id, + None, + clutter_x11_get_root_window (), + 0, 0, 0, 0, + x, y); +} - if (!translate_pad_axis (device, &xev->valuators, - &event->any.type, - &number, &value)) - return FALSE; +static void +meta_seat_x11_class_init (MetaSeatX11Class *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + ClutterSeatClass *seat_class = CLUTTER_SEAT_CLASS (klass); + + object_class->set_property = meta_seat_x11_set_property; + object_class->get_property = meta_seat_x11_get_property; + object_class->constructed = meta_seat_x11_constructed; + object_class->finalize = meta_seat_x11_finalize; + + seat_class->get_pointer = meta_seat_x11_get_pointer; + seat_class->get_keyboard = meta_seat_x11_get_keyboard; + seat_class->list_devices = meta_seat_x11_list_devices; + seat_class->bell_notify = meta_seat_x11_bell_notify; + seat_class->get_keymap = meta_seat_x11_get_keymap; + seat_class->copy_event_data = meta_seat_x11_copy_event_data; + seat_class->free_event_data = meta_seat_x11_free_event_data; + seat_class->apply_kbd_a11y_settings = meta_seat_x11_apply_kbd_a11y_settings; + seat_class->create_virtual_device = meta_seat_x11_create_virtual_device; + seat_class->get_supported_virtual_device_types = meta_seat_x11_get_supported_virtual_device_types; + seat_class->warp_pointer = meta_seat_x11_warp_pointer; + seat_class->handle_device_event = meta_seat_x11_handle_device_event; + + props[PROP_OPCODE] = + g_param_spec_int ("opcode", + "Opcode", + "Opcode", + 0, G_MAXINT, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY); + props[PROP_POINTER_ID] = + g_param_spec_int ("pointer-id", + "Pointer ID", + "Pointer ID", + 2, G_MAXINT, 2, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY); + props[PROP_KEYBOARD_ID] = + g_param_spec_int ("keyboard-id", + "Keyboard ID", + "Keyboard ID", + 2, G_MAXINT, 2, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY); + + g_object_class_install_properties (object_class, N_PROPS, props); + + g_object_class_override_property (object_class, PROP_TOUCH_MODE, + "touch-mode"); +} - /* When touching a ring/strip a first XI_Motion event - * is generated. Use it to reset the pad state, so - * later events actually have a directionality. - */ - if (xev->evtype == XI_Motion) - value = -1; +static void +meta_seat_x11_init (MetaSeatX11 *seat) +{ + seat->devices_by_id = g_hash_table_new_full (NULL, NULL, + NULL, + (GDestroyNotify) g_object_unref); + seat->tools_by_serial = g_hash_table_new_full (NULL, NULL, NULL, + (GDestroyNotify) g_object_unref); +} -#ifdef HAVE_LIBWACOM - mode = clutter_input_device_xi2_get_pad_group_mode (device, number); -#endif +MetaSeatX11 * +meta_seat_x11_new (int opcode, + int master_pointer, + int master_keyboard) +{ + return g_object_new (META_TYPE_SEAT_X11, + "opcode", opcode, + "pointer-id", master_pointer, + "keyboard-id", master_keyboard, + NULL); +} - if (event->any.type == CLUTTER_PAD_RING) - { - event->pad_ring.ring_number = number; - event->pad_ring.angle = value; - event->pad_ring.mode = mode; - } - else - { - event->pad_strip.strip_number = number; - event->pad_strip.value = value; - event->pad_strip.mode = mode; - } +static ClutterInputDevice * +get_source_device_checked (MetaSeatX11 *seat, + XIDeviceEvent *xev) +{ + ClutterInputDevice *source_device; - event->any.time = xev->time; - clutter_event_set_device (event, device); - clutter_event_set_source_device (event, device); + source_device = g_hash_table_lookup (seat->devices_by_id, + GINT_TO_POINTER (xev->sourceid)); - CLUTTER_NOTE (EVENT, - "%s: win:0x%x, device:%d '%s', time:%d " - "(value:%f)", - event->any.type == CLUTTER_PAD_RING - ? "pad ring " - : "pad strip", - (unsigned int) xev->event, - device->id, - device->device_name, - event->any.time, value); - return TRUE; + if (!source_device) + g_warning ("Impossible to get the source device with id %d for event of " + "type %d", xev->sourceid, xev->evtype); + + return source_device; } -static ClutterTranslateReturn -clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator, - gpointer native, - ClutterEvent *event) +gboolean +meta_seat_x11_translate_event (MetaSeatX11 *seat, + XEvent *xevent, + ClutterEvent *event) { - ClutterDeviceManagerXI2 *manager_xi2 = CLUTTER_DEVICE_MANAGER_XI2 (translator); - ClutterTranslateReturn retval = CLUTTER_TRANSLATE_CONTINUE; - ClutterBackendX11 *backend_x11; - ClutterStageX11 *stage_x11 = NULL; + gboolean retval = FALSE; + ClutterBackend *backend = clutter_get_default_backend (); ClutterStage *stage = NULL; + MetaStageX11 *stage_x11 = NULL; ClutterInputDevice *device, *source_device; XGenericEventCookie *cookie; XIEvent *xi_event; - XEvent *xevent; - - backend_x11 = CLUTTER_BACKEND_X11 (clutter_get_default_backend ()); - xevent = native; + if (meta_keymap_x11_handle_event (seat->keymap, xevent)) + return FALSE; cookie = &xevent->xcookie; if (cookie->type != GenericEvent || - cookie->extension != manager_xi2->opcode) - return CLUTTER_TRANSLATE_CONTINUE; + cookie->extension != seat->opcode) + return FALSE; xi_event = (XIEvent *) cookie->data; if (!xi_event) - return CLUTTER_TRANSLATE_REMOVE; + return FALSE; + + if (cookie->evtype == XI_RawMotion || + cookie->evtype == XI_RawButtonPress || + cookie->evtype == XI_RawButtonRelease) + { + translate_raw_event (seat, xevent); + return FALSE; + } - if (!(xi_event->evtype == XI_HierarchyChanged || - xi_event->evtype == XI_DeviceChanged || + if (!(xi_event->evtype == XI_DeviceChanged || xi_event->evtype == XI_PropertyEvent)) { - stage = get_event_stage (translator, xi_event); + stage = get_event_stage (seat, xi_event); if (stage == NULL || CLUTTER_ACTOR_IN_DESTRUCTION (stage)) - return CLUTTER_TRANSLATE_CONTINUE; + return FALSE; else - stage_x11 = CLUTTER_STAGE_X11 (_clutter_stage_get_window (stage)); + stage_x11 = META_STAGE_X11 (_clutter_stage_get_window (stage)); } event->any.stage = stage; @@ -1231,23 +1753,22 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator, { XIHierarchyEvent *xev = (XIHierarchyEvent *) xi_event; - translate_hierarchy_event (backend_x11, manager_xi2, xev); + retval = translate_hierarchy_event (backend, seat, xev, event); } - retval = CLUTTER_TRANSLATE_REMOVE; break; case XI_DeviceChanged: { XIDeviceChangedEvent *xev = (XIDeviceChangedEvent *) xi_event; - device = g_hash_table_lookup (manager_xi2->devices_by_id, + device = g_hash_table_lookup (seat->devices_by_id, GINT_TO_POINTER (xev->deviceid)); - source_device = g_hash_table_lookup (manager_xi2->devices_by_id, + source_device = g_hash_table_lookup (seat->devices_by_id, GINT_TO_POINTER (xev->sourceid)); if (device) { _clutter_input_device_reset_axes (device); - translate_device_classes (backend_x11->xdpy, + translate_device_classes (clutter_x11_get_default_display (), device, xev->classes, xev->num_classes); @@ -1256,56 +1777,65 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator, if (source_device) _clutter_input_device_reset_scroll_info (source_device); } - retval = CLUTTER_TRANSLATE_REMOVE; + retval = FALSE; break; - case XI_KeyPress: case XI_KeyRelease: { XIDeviceEvent *xev = (XIDeviceEvent *) xi_event; - ClutterEventX11 *event_x11; + MetaKeymapX11 *keymap_x11 = seat->keymap; + MetaEventX11 *event_x11; char buffer[7] = { 0, }; gunichar n; + source_device = get_source_device_checked (seat, xev); + if (!source_device) + return FALSE; + event->key.type = event->type = (xev->evtype == XI_KeyPress) ? CLUTTER_KEY_PRESS : CLUTTER_KEY_RELEASE; + if (xev->evtype == XI_KeyPress && xev->flags & XIKeyRepeat) + clutter_event_set_flags (event, CLUTTER_EVENT_FLAG_REPEATED); + event->key.time = xev->time; event->key.stage = stage; - _clutter_input_device_xi2_translate_state (event, &xev->mods, &xev->buttons, &xev->group); + meta_input_device_x11_translate_state (event, &xev->mods, &xev->buttons, &xev->group); event->key.hardware_keycode = xev->detail; /* keyval is the key ignoring all modifiers ('1' vs. '!') */ event->key.keyval = - _clutter_keymap_x11_translate_key_state (backend_x11->keymap, - event->key.hardware_keycode, - &event->key.modifier_state, - NULL); + meta_keymap_x11_translate_key_state (keymap_x11, + event->key.hardware_keycode, + &event->key.modifier_state, + NULL); /* KeyEvents have platform specific data associated to them */ - event_x11 = _clutter_event_x11_new (); + event_x11 = meta_event_x11_new (); _clutter_event_set_platform_data (event, event_x11); event_x11->key_group = - _clutter_keymap_x11_get_key_group (backend_x11->keymap, - event->key.modifier_state); + meta_keymap_x11_get_key_group (keymap_x11, + event->key.modifier_state); event_x11->key_is_modifier = - _clutter_keymap_x11_get_is_modifier (backend_x11->keymap, - event->key.hardware_keycode); + meta_keymap_x11_get_is_modifier (keymap_x11, + event->key.hardware_keycode); event_x11->num_lock_set = - _clutter_keymap_x11_get_num_lock_state (backend_x11->keymap); + clutter_keymap_get_num_lock_state (CLUTTER_KEYMAP (keymap_x11)); event_x11->caps_lock_set = - _clutter_keymap_x11_get_caps_lock_state (backend_x11->keymap); + clutter_keymap_get_caps_lock_state (CLUTTER_KEYMAP (keymap_x11)); - source_device = g_hash_table_lookup (manager_xi2->devices_by_id, - GINT_TO_POINTER (xev->sourceid)); clutter_event_set_source_device (event, source_device); - device = g_hash_table_lookup (manager_xi2->devices_by_id, + device = g_hash_table_lookup (seat->devices_by_id, GINT_TO_POINTER (xev->deviceid)); clutter_event_set_device (event, device); + if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER && + stage != NULL) + _clutter_input_device_set_stage (device, stage); + /* XXX keep this in sync with the evdev device manager */ n = print_keysym (event->key.keyval, buffer, sizeof (buffer)); if (n == 0) @@ -1321,21 +1851,20 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator, event->key.unicode_value = (gunichar) '\0'; } - CLUTTER_NOTE (EVENT, - "%s: win:0x%x device:%d source:%d, key: %12s (%d)", - event->any.type == CLUTTER_KEY_PRESS - ? "key press " - : "key release", - (unsigned int) stage_x11->xwin, - xev->deviceid, - xev->sourceid, - event->key.keyval ? buffer : "(none)", - event->key.keyval); + g_debug ("%s: win:0x%x device:%d source:%d, key: %12s (%d)", + event->any.type == CLUTTER_KEY_PRESS + ? "key press " + : "key release", + (unsigned int) stage_x11->xwin, + xev->deviceid, + xev->sourceid, + event->key.keyval ? buffer : "(none)", + event->key.keyval); if (xi_event->evtype == XI_KeyPress) - _clutter_stage_x11_set_user_time (stage_x11, event->key.time); + meta_stage_x11_set_user_time (stage_x11, event->key.time); - retval = CLUTTER_TRANSLATE_QUEUE; + retval = TRUE; } break; @@ -1344,9 +1873,11 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator, { XIDeviceEvent *xev = (XIDeviceEvent *) xi_event; - source_device = g_hash_table_lookup (manager_xi2->devices_by_id, - GINT_TO_POINTER (xev->sourceid)); - device = g_hash_table_lookup (manager_xi2->devices_by_id, + source_device = get_source_device_checked (seat, xev); + if (!source_device) + return FALSE; + + device = g_hash_table_lookup (seat->devices_by_id, GINT_TO_POINTER (xev->deviceid)); /* Set the stage for core events coming out of nowhere (see bug #684509) */ @@ -1367,11 +1898,11 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator, if (xev->detail >= 4 && xev->detail <= 7) { - retval = CLUTTER_TRANSLATE_REMOVE; + retval = FALSE; if (xi_event->evtype == XI_ButtonPress && translate_pad_event (event, xev, source_device)) - retval = CLUTTER_TRANSLATE_QUEUE; + retval = TRUE; break; } @@ -1390,28 +1921,26 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator, /* Pad buttons are 0-indexed */ event->pad_button.button = xev->detail - 1; #ifdef HAVE_LIBWACOM - clutter_input_device_xi2_update_pad_state (device, - event->pad_button.button, - (xi_event->evtype == XI_ButtonPress), - &event->pad_button.group, - &event->pad_button.mode); + meta_input_device_x11_update_pad_state (device, + event->pad_button.button, + (xi_event->evtype == XI_ButtonPress), + &event->pad_button.group, + &event->pad_button.mode); #endif clutter_event_set_device (event, device); clutter_event_set_source_device (event, source_device); - CLUTTER_NOTE (EVENT, - "%s: win:0x%x, device:%d '%s', time:%d " - "(button:%d)", - event->any.type == CLUTTER_BUTTON_PRESS - ? "pad button press " - : "pad button release", - (unsigned int) stage_x11->xwin, - device->id, - device->device_name, - event->any.time, - event->pad_button.button); - - retval = CLUTTER_TRANSLATE_QUEUE; + g_debug ("%s: win:0x%x, device:%d '%s', time:%d " + "(button:%d)", + event->any.type == CLUTTER_BUTTON_PRESS + ? "pad button press " + : "pad button release", + (unsigned int) stage_x11->xwin, + device->id, + device->device_name, + event->any.time, + event->pad_button.button); + retval = TRUE; break; } @@ -1423,7 +1952,7 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator, case 7: /* we only generate Scroll events on ButtonPress */ if (xi_event->evtype == XI_ButtonRelease) - return CLUTTER_TRANSLATE_REMOVE; + return FALSE; event->scroll.type = event->type = CLUTTER_SCROLL; @@ -1440,10 +1969,10 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator, event->scroll.time = xev->time; translate_coords (stage_x11, xev->event_x, xev->event_y, &event->scroll.x, &event->scroll.y); - _clutter_input_device_xi2_translate_state (event, - &xev->mods, - &xev->buttons, - &xev->group); + meta_input_device_x11_translate_state (event, + &xev->mods, + &xev->buttons, + &xev->group); clutter_event_set_source_device (event, source_device); clutter_event_set_device (event, device); @@ -1452,29 +1981,22 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator, event->scroll.x, event->scroll.y, &xev->valuators); - - CLUTTER_NOTE (EVENT, - "scroll: win:0x%x, device:%d '%s', time:%d " - "(direction:%s, " - "x:%.2f, y:%.2f, " - "emulated:%s)", - (unsigned int) stage_x11->xwin, - device->id, - device->device_name, - event->any.time, - event->scroll.direction == CLUTTER_SCROLL_UP ? "up" : - event->scroll.direction == CLUTTER_SCROLL_DOWN ? "down" : - event->scroll.direction == CLUTTER_SCROLL_LEFT ? "left" : - event->scroll.direction == CLUTTER_SCROLL_RIGHT ? "right" : - "invalid", - event->scroll.x, - event->scroll.y, -#ifdef HAVE_XINPUT_2_2 - (xev->flags & XIPointerEmulated) ? "yes" : "no" -#else - "no" -#endif - ); + g_debug ("scroll: win:0x%x, device:%d '%s', time:%d " + "(direction:%s, " + "x:%.2f, y:%.2f, " + "emulated:%s)", + (unsigned int) stage_x11->xwin, + device->id, + device->device_name, + event->any.time, + event->scroll.direction == CLUTTER_SCROLL_UP ? "up" : + event->scroll.direction == CLUTTER_SCROLL_DOWN ? "down" : + event->scroll.direction == CLUTTER_SCROLL_LEFT ? "left" : + event->scroll.direction == CLUTTER_SCROLL_RIGHT ? "right" : + "invalid", + event->scroll.x, + event->scroll.y, + (xev->flags & XIPointerEmulated) ? "yes" : "no"); break; default: @@ -1487,70 +2009,63 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator, event->button.time = xev->time; translate_coords (stage_x11, xev->event_x, xev->event_y, &event->button.x, &event->button.y); event->button.button = xev->detail; - _clutter_input_device_xi2_translate_state (event, - &xev->mods, - &xev->buttons, - &xev->group); + meta_input_device_x11_translate_state (event, + &xev->mods, + &xev->buttons, + &xev->group); clutter_event_set_source_device (event, source_device); clutter_event_set_device (event, device); clutter_event_set_device_tool (event, - clutter_input_device_xi2_get_current_tool (source_device)); + meta_input_device_x11_get_current_tool (source_device)); event->button.axes = translate_axes (event->button.device, event->button.x, event->button.y, &xev->valuators); - - CLUTTER_NOTE (EVENT, - "%s: win:0x%x, device:%d '%s', time:%d " - "(button:%d, " - "x:%.2f, y:%.2f, " - "axes:%s, " - "emulated:%s)", - event->any.type == CLUTTER_BUTTON_PRESS - ? "button press " - : "button release", - (unsigned int) stage_x11->xwin, - device->id, - device->device_name, - event->any.time, - event->button.button, - event->button.x, - event->button.y, - event->button.axes != NULL ? "yes" : "no", -#ifdef HAVE_XINPUT_2_2 - (xev->flags & XIPointerEmulated) ? "yes" : "no" -#else - "no" -#endif - ); + g_debug ("%s: win:0x%x, device:%d '%s', time:%d " + "(button:%d, " + "x:%.2f, y:%.2f, " + "axes:%s, " + "emulated:%s)", + event->any.type == CLUTTER_BUTTON_PRESS + ? "button press " + : "button release", + (unsigned int) stage_x11->xwin, + device->id, + device->device_name, + event->any.time, + event->button.button, + event->button.x, + event->button.y, + event->button.axes != NULL ? "yes" : "no", + (xev->flags & XIPointerEmulated) ? "yes" : "no"); break; } - if (source_device != NULL && device->stage != NULL) + if (device->stage != NULL) _clutter_input_device_set_stage (source_device, device->stage); -#ifdef HAVE_XINPUT_2_2 if (xev->flags & XIPointerEmulated) _clutter_event_set_pointer_emulated (event, TRUE); -#endif /* HAVE_XINPUT_2_2 */ if (xi_event->evtype == XI_ButtonPress) - _clutter_stage_x11_set_user_time (stage_x11, event->button.time); + meta_stage_x11_set_user_time (stage_x11, event->button.time); - retval = CLUTTER_TRANSLATE_QUEUE; + retval = TRUE; } break; case XI_Motion: { XIDeviceEvent *xev = (XIDeviceEvent *) xi_event; - gdouble delta_x, delta_y; + double delta_x, delta_y; - source_device = g_hash_table_lookup (manager_xi2->devices_by_id, - GINT_TO_POINTER (xev->sourceid)); - device = g_hash_table_lookup (manager_xi2->devices_by_id, + source_device = get_source_device_checked (seat, xev); + if (!source_device) + return FALSE; + + device = g_hash_table_lookup (seat->devices_by_id, GINT_TO_POINTER (xev->deviceid)); if (clutter_input_device_get_device_type (source_device) == CLUTTER_PAD_DEVICE) @@ -1558,7 +2073,7 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator, event->any.stage = stage; if (translate_pad_event (event, xev, source_device)) - retval = CLUTTER_TRANSLATE_QUEUE; + retval = TRUE; break; } @@ -1578,25 +2093,24 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator, event->scroll.stage = stage; event->scroll.time = xev->time; translate_coords (stage_x11, xev->event_x, xev->event_y, &event->scroll.x, &event->scroll.y); - _clutter_input_device_xi2_translate_state (event, - &xev->mods, - &xev->buttons, - &xev->group); + meta_input_device_x11_translate_state (event, + &xev->mods, + &xev->buttons, + &xev->group); clutter_event_set_scroll_delta (event, delta_x, delta_y); clutter_event_set_source_device (event, source_device); clutter_event_set_device (event, device); - CLUTTER_NOTE (EVENT, - "smooth scroll: win:0x%x device:%d '%s' (x:%.2f, y:%.2f, delta:%f, %f)", - (unsigned int) stage_x11->xwin, - event->scroll.device->id, - event->scroll.device->device_name, - event->scroll.x, - event->scroll.y, - delta_x, delta_y); + g_debug ("smooth scroll: win:0x%x device:%d '%s' (x:%.2f, y:%.2f, delta:%f, %f)", + (unsigned int) stage_x11->xwin, + event->scroll.device->id, + event->scroll.device->device_name, + event->scroll.x, + event->scroll.y, + delta_x, delta_y); - retval = CLUTTER_TRANSLATE_QUEUE; + retval = TRUE; break; } @@ -1606,46 +2120,43 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator, event->motion.time = xev->time; translate_coords (stage_x11, xev->event_x, xev->event_y, &event->motion.x, &event->motion.y); - _clutter_input_device_xi2_translate_state (event, - &xev->mods, - &xev->buttons, - &xev->group); + meta_input_device_x11_translate_state (event, + &xev->mods, + &xev->buttons, + &xev->group); clutter_event_set_source_device (event, source_device); clutter_event_set_device (event, device); clutter_event_set_device_tool (event, - clutter_input_device_xi2_get_current_tool (source_device)); + meta_input_device_x11_get_current_tool (source_device)); event->motion.axes = translate_axes (event->motion.device, event->motion.x, event->motion.y, &xev->valuators); - if (source_device != NULL && device->stage != NULL) + if (device->stage != NULL) _clutter_input_device_set_stage (source_device, device->stage); -#ifdef HAVE_XINPUT_2_2 if (xev->flags & XIPointerEmulated) _clutter_event_set_pointer_emulated (event, TRUE); -#endif /* HAVE_XINPUT_2_2 */ - CLUTTER_NOTE (EVENT, "motion: win:0x%x device:%d '%s' (x:%.2f, y:%.2f, axes:%s)", - (unsigned int) stage_x11->xwin, - event->motion.device->id, - event->motion.device->device_name, - event->motion.x, - event->motion.y, - event->motion.axes != NULL ? "yes" : "no"); + g_debug ("motion: win:0x%x device:%d '%s' (x:%.2f, y:%.2f, axes:%s)", + (unsigned int) stage_x11->xwin, + event->motion.device->id, + event->motion.device->device_name, + event->motion.x, + event->motion.y, + event->motion.axes != NULL ? "yes" : "no"); - retval = CLUTTER_TRANSLATE_QUEUE; + retval = TRUE; } break; -#ifdef HAVE_XINPUT_2_2 case XI_TouchBegin: { XIDeviceEvent *xev = (XIDeviceEvent *) xi_event; - device = g_hash_table_lookup (manager_xi2->devices_by_id, + device = g_hash_table_lookup (seat->devices_by_id, GINT_TO_POINTER (xev->deviceid)); if (!_clutter_input_device_get_stage (device)) _clutter_input_device_set_stage (device, stage); @@ -1655,7 +2166,7 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator, { XIDeviceEvent *xev = (XIDeviceEvent *) xi_event; - source_device = g_hash_table_lookup (manager_xi2->devices_by_id, + source_device = g_hash_table_lookup (seat->devices_by_id, GINT_TO_POINTER (xev->sourceid)); if (xi_event->evtype == XI_TouchBegin) @@ -1666,14 +2177,14 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator, event->touch.stage = stage; event->touch.time = xev->time; translate_coords (stage_x11, xev->event_x, xev->event_y, &event->touch.x, &event->touch.y); - _clutter_input_device_xi2_translate_state (event, - &xev->mods, - &xev->buttons, - &xev->group); + meta_input_device_x11_translate_state (event, + &xev->mods, + &xev->buttons, + &xev->group); clutter_event_set_source_device (event, source_device); - device = g_hash_table_lookup (manager_xi2->devices_by_id, + device = g_hash_table_lookup (seat->devices_by_id, GINT_TO_POINTER (xev->deviceid)); clutter_event_set_device (event, device); @@ -1686,7 +2197,7 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator, { event->touch.modifier_state |= CLUTTER_BUTTON1_MASK; - _clutter_stage_x11_set_user_time (stage_x11, event->touch.time); + meta_stage_x11_set_user_time (stage_x11, event->touch.time); } event->touch.sequence = GUINT_TO_POINTER (xev->detail); @@ -1694,17 +2205,17 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator, if (xev->flags & XITouchEmulatingPointer) _clutter_event_set_pointer_emulated (event, TRUE); - CLUTTER_NOTE (EVENT, "touch %s: win:0x%x device:%d '%s' (seq:%d, x:%.2f, y:%.2f, axes:%s)", - event->type == CLUTTER_TOUCH_BEGIN ? "begin" : "end", - (unsigned int) stage_x11->xwin, - event->touch.device->id, - event->touch.device->device_name, - GPOINTER_TO_UINT (event->touch.sequence), - event->touch.x, - event->touch.y, - event->touch.axes != NULL ? "yes" : "no"); - - retval = CLUTTER_TRANSLATE_QUEUE; + g_debug ("touch %s: win:0x%x device:%d '%s' (seq:%d, x:%.2f, y:%.2f, axes:%s)", + event->type == CLUTTER_TOUCH_BEGIN ? "begin" : "end", + (unsigned int) stage_x11->xwin, + event->touch.device->id, + event->touch.device->device_name, + GPOINTER_TO_UINT (event->touch.sequence), + event->touch.x, + event->touch.y, + event->touch.axes != NULL ? "yes" : "no"); + + retval = TRUE; } break; @@ -1712,7 +2223,7 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator, { XIDeviceEvent *xev = (XIDeviceEvent *) xi_event; - source_device = g_hash_table_lookup (manager_xi2->devices_by_id, + source_device = g_hash_table_lookup (seat->devices_by_id, GINT_TO_POINTER (xev->sourceid)); event->touch.type = event->type = CLUTTER_TOUCH_UPDATE; @@ -1723,7 +2234,7 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator, clutter_event_set_source_device (event, source_device); - device = g_hash_table_lookup (manager_xi2->devices_by_id, + device = g_hash_table_lookup (seat->devices_by_id, GINT_TO_POINTER (xev->deviceid)); clutter_event_set_device (event, device); @@ -1732,38 +2243,37 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator, event->motion.y, &xev->valuators); - _clutter_input_device_xi2_translate_state (event, - &xev->mods, - &xev->buttons, - &xev->group); + meta_input_device_x11_translate_state (event, + &xev->mods, + &xev->buttons, + &xev->group); event->touch.modifier_state |= CLUTTER_BUTTON1_MASK; if (xev->flags & XITouchEmulatingPointer) _clutter_event_set_pointer_emulated (event, TRUE); - CLUTTER_NOTE (EVENT, "touch update: win:0x%x device:%d '%s' (seq:%d, x:%.2f, y:%.2f, axes:%s)", - (unsigned int) stage_x11->xwin, - event->touch.device->id, - event->touch.device->device_name, - GPOINTER_TO_UINT (event->touch.sequence), - event->touch.x, - event->touch.y, - event->touch.axes != NULL ? "yes" : "no"); + g_debug ("touch update: win:0x%x device:%d '%s' (seq:%d, x:%.2f, y:%.2f, axes:%s)", + (unsigned int) stage_x11->xwin, + event->touch.device->id, + event->touch.device->device_name, + GPOINTER_TO_UINT (event->touch.sequence), + event->touch.x, + event->touch.y, + event->touch.axes != NULL ? "yes" : "no"); - retval = CLUTTER_TRANSLATE_QUEUE; + retval = TRUE; } break; -#endif /* HAVE_XINPUT_2_2 */ case XI_Enter: case XI_Leave: { XIEnterEvent *xev = (XIEnterEvent *) xi_event; - device = g_hash_table_lookup (manager_xi2->devices_by_id, + device = g_hash_table_lookup (seat->devices_by_id, GINT_TO_POINTER (xev->deviceid)); - source_device = g_hash_table_lookup (manager_xi2->devices_by_id, + source_device = g_hash_table_lookup (seat->devices_by_id, GINT_TO_POINTER (xev->sourceid)); if (xi_event->evtype == XI_Enter) @@ -1776,18 +2286,14 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator, event->crossing.time = xev->time; translate_coords (stage_x11, xev->event_x, xev->event_y, &event->crossing.x, &event->crossing.y); - - _clutter_input_device_set_stage (device, stage); } else { if (device->stage == NULL) { - CLUTTER_NOTE (EVENT, - "Discarding Leave for ButtonRelease " - "event off-stage"); - - retval = CLUTTER_TRANSLATE_REMOVE; + g_debug ("Discarding Leave for ButtonRelease " + "event off-stage"); + retval = FALSE; break; } @@ -1799,8 +2305,6 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator, event->crossing.time = xev->time; translate_coords (stage_x11, xev->event_x, xev->event_y, &event->crossing.x, &event->crossing.y); - - _clutter_input_device_set_stage (device, NULL); } _clutter_input_device_reset_scroll_info (source_device); @@ -1808,292 +2312,63 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator, clutter_event_set_device (event, device); clutter_event_set_source_device (event, source_device); - retval = CLUTTER_TRANSLATE_QUEUE; + retval = TRUE; } break; case XI_FocusIn: case XI_FocusOut: - retval = CLUTTER_TRANSLATE_CONTINUE; + retval = FALSE; break; case XI_PropertyEvent: - handle_property_event (manager_xi2, xi_event); - retval = CLUTTER_TRANSLATE_CONTINUE; + translate_property_event (seat, xi_event); + retval = FALSE; break; } return retval; } -static void -clutter_event_translator_iface_init (ClutterEventTranslatorIface *iface) -{ - iface->translate_event = clutter_device_manager_xi2_translate_event; -} - -static void -clutter_device_manager_xi2_add_device (ClutterDeviceManager *manager, - ClutterInputDevice *device) -{ - /* XXX implement */ -} - -static void -clutter_device_manager_xi2_remove_device (ClutterDeviceManager *manager, - ClutterInputDevice *device) -{ - /* XXX implement */ -} - -static const GSList * -clutter_device_manager_xi2_get_devices (ClutterDeviceManager *manager) -{ - ClutterDeviceManagerXI2 *manager_xi2 = CLUTTER_DEVICE_MANAGER_XI2 (manager); - GSList *all_devices = NULL; - GList *l; - - if (manager_xi2->all_devices != NULL) - return manager_xi2->all_devices; - - for (l = manager_xi2->master_devices; l != NULL; l = l->next) - all_devices = g_slist_prepend (all_devices, l->data); - - for (l = manager_xi2->slave_devices; l != NULL; l = l->next) - all_devices = g_slist_prepend (all_devices, l->data); - - manager_xi2->all_devices = g_slist_reverse (all_devices); - - return manager_xi2->all_devices; -} - -static ClutterInputDevice * -clutter_device_manager_xi2_get_device (ClutterDeviceManager *manager, - gint id) -{ - ClutterDeviceManagerXI2 *manager_xi2 = CLUTTER_DEVICE_MANAGER_XI2 (manager); - - return g_hash_table_lookup (manager_xi2->devices_by_id, - GINT_TO_POINTER (id)); -} - -static ClutterInputDevice * -clutter_device_manager_xi2_get_core_device (ClutterDeviceManager *manager, - ClutterInputDeviceType device_type) -{ - ClutterDeviceManagerXI2 *manager_xi2 = CLUTTER_DEVICE_MANAGER_XI2 (manager); - ClutterInputDevice *pointer = NULL; - GList *l; - - for (l = manager_xi2->master_devices; l != NULL ; l = l->next) - { - ClutterInputDevice *device = l->data; - if (clutter_input_device_get_device_type (device) == CLUTTER_POINTER_DEVICE) - { - pointer = device; - break; - } - } - - if (pointer == NULL) - return NULL; - - switch (device_type) - { - case CLUTTER_POINTER_DEVICE: - return pointer; - - case CLUTTER_KEYBOARD_DEVICE: - return clutter_input_device_get_associated_device (pointer); - - default: - break; - } - - return NULL; -} - -static void -relate_masters (gpointer key, - gpointer value, - gpointer data) -{ - ClutterDeviceManagerXI2 *manager_xi2 = data; - ClutterInputDevice *device, *relative; - - device = g_hash_table_lookup (manager_xi2->devices_by_id, key); - relative = g_hash_table_lookup (manager_xi2->devices_by_id, value); - - _clutter_input_device_set_associated_device (device, relative); - _clutter_input_device_set_associated_device (relative, device); -} - -static void -relate_slaves (gpointer key, - gpointer value, - gpointer data) -{ - ClutterDeviceManagerXI2 *manager_xi2 = data; - ClutterInputDevice *master, *slave; - - slave = g_hash_table_lookup (manager_xi2->devices_by_id, key); - master = g_hash_table_lookup (manager_xi2->devices_by_id, value); - - _clutter_input_device_set_associated_device (slave, master); - _clutter_input_device_add_slave (master, slave); -} - -static void -clutter_device_manager_xi2_constructed (GObject *gobject) +ClutterInputDevice * +meta_seat_x11_lookup_device_id (MetaSeatX11 *seat_x11, + int device_id) { - ClutterDeviceManagerXI2 *manager_xi2 = CLUTTER_DEVICE_MANAGER_XI2 (gobject); - ClutterDeviceManager *manager = CLUTTER_DEVICE_MANAGER (gobject); - ClutterBackendX11 *backend_x11; - GHashTable *masters, *slaves; - XIDeviceInfo *info; - XIEventMask event_mask; - unsigned char mask[2] = { 0, }; - int n_devices, i; - - backend_x11 = - CLUTTER_BACKEND_X11 (_clutter_device_manager_get_backend (manager)); - - masters = g_hash_table_new (NULL, NULL); - slaves = g_hash_table_new (NULL, NULL); - - info = XIQueryDevice (backend_x11->xdpy, XIAllDevices, &n_devices); - - for (i = 0; i < n_devices; i++) - { - XIDeviceInfo *xi_device = &info[i]; - - if (!xi_device->enabled) - continue; - - add_device (manager_xi2, backend_x11, xi_device, TRUE); - - if (xi_device->use == XIMasterPointer || - xi_device->use == XIMasterKeyboard) - { - g_hash_table_insert (masters, - GINT_TO_POINTER (xi_device->deviceid), - GINT_TO_POINTER (xi_device->attachment)); - } - else if (xi_device->use == XISlavePointer || - xi_device->use == XISlaveKeyboard) - { - g_hash_table_insert (slaves, - GINT_TO_POINTER (xi_device->deviceid), - GINT_TO_POINTER (xi_device->attachment)); - } - } - - XIFreeDeviceInfo (info); - - g_hash_table_foreach (masters, relate_masters, manager_xi2); - g_hash_table_destroy (masters); - - g_hash_table_foreach (slaves, relate_slaves, manager_xi2); - g_hash_table_destroy (slaves); - - XISetMask (mask, XI_HierarchyChanged); - XISetMask (mask, XI_DeviceChanged); - XISetMask (mask, XI_PropertyEvent); - - event_mask.deviceid = XIAllDevices; - event_mask.mask_len = sizeof (mask); - event_mask.mask = mask; - - clutter_device_manager_xi2_select_events (manager, - clutter_x11_get_root_window (), - &event_mask); - - XSync (backend_x11->xdpy, False); - - clutter_device_manager_x11_a11y_init (manager); - - if (G_OBJECT_CLASS (clutter_device_manager_xi2_parent_class)->constructed) - G_OBJECT_CLASS (clutter_device_manager_xi2_parent_class)->constructed (gobject); + return g_hash_table_lookup (seat_x11->devices_by_id, + GINT_TO_POINTER (device_id)); } -static void -clutter_device_manager_xi2_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) +void +meta_seat_x11_select_stage_events (MetaSeatX11 *seat, + ClutterStage *stage) { - ClutterDeviceManagerXI2 *manager_xi2 = CLUTTER_DEVICE_MANAGER_XI2 (gobject); - - switch (prop_id) - { - case PROP_OPCODE: - manager_xi2->opcode = g_value_get_int (value); - break; + MetaStageX11 *stage_x11; + XIEventMask xi_event_mask; + unsigned char *mask; + int len; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} + stage_x11 = META_STAGE_X11 (_clutter_stage_get_window (stage)); -static ClutterVirtualInputDevice * -clutter_device_manager_xi2_create_virtual_device (ClutterDeviceManager *manager, - ClutterInputDeviceType device_type) -{ - return g_object_new (CLUTTER_TYPE_VIRTUAL_INPUT_DEVICE_X11, - "device-manager", manager, - "device-type", device_type, - NULL); -} + len = XIMaskLen (XI_LASTEVENT); + mask = g_new0 (unsigned char, len); -static ClutterVirtualDeviceType -clutter_device_manager_xi2_get_supported_virtual_device_types (ClutterDeviceManager *device_manager) -{ - return (CLUTTER_VIRTUAL_DEVICE_TYPE_KEYBOARD | - CLUTTER_VIRTUAL_DEVICE_TYPE_POINTER); -} + XISetMask (mask, XI_Motion); + XISetMask (mask, XI_ButtonPress); + XISetMask (mask, XI_ButtonRelease); + XISetMask (mask, XI_KeyPress); + XISetMask (mask, XI_KeyRelease); + XISetMask (mask, XI_Enter); + XISetMask (mask, XI_Leave); -static void -clutter_device_manager_xi2_class_init (ClutterDeviceManagerXI2Class *klass) -{ - ClutterDeviceManagerClass *manager_class; - GObjectClass *gobject_class; + XISetMask (mask, XI_TouchBegin); + XISetMask (mask, XI_TouchUpdate); + XISetMask (mask, XI_TouchEnd); - obj_props[PROP_OPCODE] = - g_param_spec_int ("opcode", - "Opcode", - "The XI2 opcode", - -1, G_MAXINT, - -1, - CLUTTER_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY); - - gobject_class = G_OBJECT_CLASS (klass); - gobject_class->constructed = clutter_device_manager_xi2_constructed; - gobject_class->set_property = clutter_device_manager_xi2_set_property; - - g_object_class_install_properties (gobject_class, PROP_LAST, obj_props); - - manager_class = CLUTTER_DEVICE_MANAGER_CLASS (klass); - manager_class->add_device = clutter_device_manager_xi2_add_device; - manager_class->remove_device = clutter_device_manager_xi2_remove_device; - manager_class->get_devices = clutter_device_manager_xi2_get_devices; - manager_class->get_core_device = clutter_device_manager_xi2_get_core_device; - manager_class->get_device = clutter_device_manager_xi2_get_device; - manager_class->select_stage_events = clutter_device_manager_xi2_select_stage_events; - manager_class->create_virtual_device = clutter_device_manager_xi2_create_virtual_device; - manager_class->get_supported_virtual_device_types = clutter_device_manager_xi2_get_supported_virtual_device_types; - manager_class->apply_kbd_a11y_settings = clutter_device_manager_x11_apply_kbd_a11y_settings; -} + xi_event_mask.deviceid = XIAllMasterDevices; + xi_event_mask.mask = mask; + xi_event_mask.mask_len = len; -static void -clutter_device_manager_xi2_init (ClutterDeviceManagerXI2 *self) -{ - self->devices_by_id = g_hash_table_new_full (NULL, NULL, - NULL, - (GDestroyNotify) g_object_unref); - self->tools_by_serial = g_hash_table_new_full (NULL, NULL, NULL, - (GDestroyNotify) g_object_unref); + XISelectEvents (clutter_x11_get_default_display (), + stage_x11->xwin, &xi_event_mask, 1); -#ifdef HAVE_LIBWACOM - self->wacom_db = libwacom_database_new (); -#endif + g_free (mask); } diff --git a/src/backends/x11/meta-seat-x11.h b/src/backends/x11/meta-seat-x11.h new file mode 100644 index 000000000..924025802 --- /dev/null +++ b/src/backends/x11/meta-seat-x11.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2019 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ +#ifndef META_SEAT_X11_H +#define META_SEAT_X11_H + +#include "clutter/clutter.h" + +G_BEGIN_DECLS + +#define META_TYPE_SEAT_X11 meta_seat_x11_get_type () +G_DECLARE_FINAL_TYPE (MetaSeatX11, meta_seat_x11, META, SEAT_X11, ClutterSeat) + +MetaSeatX11 * meta_seat_x11_new (int opcode, + int master_pointer, + int master_keyboard); +gboolean meta_seat_x11_translate_event (MetaSeatX11 *seat, + XEvent *xevent, + ClutterEvent *event); +ClutterInputDevice * meta_seat_x11_lookup_device_id (MetaSeatX11 *seat_x11, + int device_id); +void meta_seat_x11_select_stage_events (MetaSeatX11 *seat, + ClutterStage *stage); +void meta_seat_x11_notify_devices (MetaSeatX11 *seat_x11, + ClutterStage *stage); + +G_END_DECLS + +#endif /* META_SEAT_X11_H */ diff --git a/src/backends/x11/meta-stage-x11.c b/src/backends/x11/meta-stage-x11.c new file mode 100644 index 000000000..975ed9301 --- /dev/null +++ b/src/backends/x11/meta-stage-x11.c @@ -0,0 +1,910 @@ +/* + * Authored By Matthew Allum <mallum@openedhand.com> + * Copyright (C) 2006-2007 OpenedHand + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <math.h> +#include <stdlib.h> + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +#include "backends/x11/cm/meta-backend-x11-cm.h" +#include "backends/x11/cm/meta-renderer-x11-cm.h" +#include "backends/x11/meta-backend-x11.h" +#include "backends/x11/meta-seat-x11.h" +#include "backends/x11/meta-stage-x11.h" +#include "clutter/clutter-mutter.h" +#include "clutter/x11/clutter-x11.h" +#include "clutter/x11/clutter-backend-x11.h" +#include "cogl/cogl.h" +#include "core/display-private.h" +#include "meta/meta-x11-errors.h" + +#define STAGE_X11_IS_MAPPED(s) ((((MetaStageX11 *) (s))->wm_state & STAGE_X11_WITHDRAWN) == 0) + +static ClutterStageWindowInterface *clutter_stage_window_parent_iface = NULL; + +static void +clutter_stage_window_iface_init (ClutterStageWindowInterface *iface); + +static ClutterStageCogl *meta_x11_get_stage_window_from_window (Window win); + +static GHashTable *clutter_stages_by_xid = NULL; + +G_DEFINE_TYPE_WITH_CODE (MetaStageX11, + meta_stage_x11, + CLUTTER_TYPE_STAGE_COGL, + G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_STAGE_WINDOW, + clutter_stage_window_iface_init)); + +#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */ +#define _NET_WM_STATE_ADD 1 /* add/set property */ +#define _NET_WM_STATE_TOGGLE 2 /* toggle property */ + +#define META_STAGE_X11_EVENT_MASK \ + StructureNotifyMask | \ + FocusChangeMask | \ + ExposureMask | \ + PropertyChangeMask | \ + EnterWindowMask | \ + LeaveWindowMask | \ + KeyPressMask | \ + KeyReleaseMask | \ + ButtonPressMask | \ + ButtonReleaseMask | \ + PointerMotionMask + +static void +meta_stage_x11_fix_window_size (MetaStageX11 *stage_x11, + int new_width, + int new_height) +{ + ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11); + + if (stage_x11->xwin != None) + { + Display *xdisplay = clutter_x11_get_default_display (); + uint32_t min_width, min_height; + XSizeHints *size_hints; + + size_hints = XAllocSizeHints(); + + clutter_stage_get_minimum_size (stage_cogl->wrapper, + &min_width, + &min_height); + + if (new_width <= 0) + new_width = min_width; + + if (new_height <= 0) + new_height = min_height; + + size_hints->min_width = new_width; + size_hints->min_height = new_height; + size_hints->max_width = new_width; + size_hints->max_height = new_height; + size_hints->flags = PMinSize | PMaxSize; + + XSetWMNormalHints (xdisplay, stage_x11->xwin, size_hints); + + XFree(size_hints); + } +} + +static void +meta_stage_x11_set_wm_protocols (MetaStageX11 *stage_x11) +{ + ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11); + ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend); + Display *xdisplay = clutter_x11_get_default_display (); + Atom protocols[2]; + int n = 0; + + protocols[n++] = backend_x11->atom_WM_DELETE_WINDOW; + protocols[n++] = backend_x11->atom_NET_WM_PING; + + XSetWMProtocols (xdisplay, stage_x11->xwin, protocols, n); +} + +static void +meta_stage_x11_get_geometry (ClutterStageWindow *stage_window, + cairo_rectangle_int_t *geometry) +{ + MetaStageX11 *stage_x11 = META_STAGE_X11 (stage_window); + + geometry->x = geometry->y = 0; + geometry->width = stage_x11->xwin_width; + geometry->height = stage_x11->xwin_height; +} + +static void +meta_stage_x11_resize (ClutterStageWindow *stage_window, + int width, + int height) +{ + MetaStageX11 *stage_x11 = META_STAGE_X11 (stage_window); + + if (width == 0 || height == 0) + { + /* Should not happen, if this turns up we need to debug it and + * determine the cleanest way to fix. + */ + g_warning ("X11 stage not allowed to have 0 width or height"); + width = 1; + height = 1; + } + + if (stage_x11->xwin != None) + { + meta_stage_x11_fix_window_size (stage_x11, width, height); + + if (width != stage_x11->xwin_width || + height != stage_x11->xwin_height) + { + Display *xdisplay = clutter_x11_get_default_display (); + + /* XXX: in this case we can rely on a subsequent + * ConfigureNotify that will result in the stage + * being reallocated so we don't actively do anything + * to affect the stage allocation here. */ + XResizeWindow (xdisplay, + stage_x11->xwin, + width, + height); + } + } + else + { + /* if the backing window hasn't been created yet, we just + * need to store the new window size + */ + stage_x11->xwin_width = width; + stage_x11->xwin_height = height; + } +} + +static inline void +set_wm_pid (MetaStageX11 *stage_x11) +{ + ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11); + ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend); + Display *xdisplay = clutter_x11_get_default_display (); + long pid; + + if (stage_x11->xwin == None) + return; + + /* this will take care of WM_CLIENT_MACHINE and WM_LOCALE_NAME */ + XSetWMProperties (xdisplay, stage_x11->xwin, + NULL, + NULL, + NULL, 0, + NULL, NULL, NULL); + + pid = getpid (); + XChangeProperty (xdisplay, + stage_x11->xwin, + backend_x11->atom_NET_WM_PID, XA_CARDINAL, 32, + PropModeReplace, + (guchar *) &pid, 1); +} + +static inline void +set_wm_title (MetaStageX11 *stage_x11) +{ + ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11); + ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend); + Display *xdisplay = clutter_x11_get_default_display (); + + if (stage_x11->xwin == None) + return; + + if (stage_x11->title == NULL) + { + XDeleteProperty (xdisplay, + stage_x11->xwin, + backend_x11->atom_NET_WM_NAME); + } + else + { + XChangeProperty (xdisplay, + stage_x11->xwin, + backend_x11->atom_NET_WM_NAME, + backend_x11->atom_UTF8_STRING, + 8, + PropModeReplace, + (unsigned char *) stage_x11->title, + (int) strlen (stage_x11->title)); + } +} + +static inline void +set_cursor_visible (MetaStageX11 *stage_x11) +{ + Display *xdisplay = clutter_x11_get_default_display (); + + if (stage_x11->xwin == None) + return; + + g_debug ("setting cursor state ('%s') over stage window (%u)", + stage_x11->is_cursor_visible ? "visible" : "invisible", + (unsigned int) stage_x11->xwin); + + if (stage_x11->is_cursor_visible) + { + XUndefineCursor (xdisplay, stage_x11->xwin); + } + else + { + XColor col; + Pixmap pix; + Cursor curs; + + pix = XCreatePixmap (xdisplay, stage_x11->xwin, 1, 1, 1); + memset (&col, 0, sizeof (col)); + curs = XCreatePixmapCursor (xdisplay, + pix, pix, + &col, &col, + 1, 1); + XFreePixmap (xdisplay, pix); + XDefineCursor (xdisplay, stage_x11->xwin, curs); + } +} + +static void +meta_stage_x11_unrealize (ClutterStageWindow *stage_window) +{ + MetaStageX11 *stage_x11 = META_STAGE_X11 (stage_window); + + if (clutter_stages_by_xid != NULL) + { + g_hash_table_remove (clutter_stages_by_xid, + GINT_TO_POINTER (stage_x11->xwin)); + } + + if (stage_x11->frame_closure) + { + cogl_onscreen_remove_frame_callback (stage_x11->onscreen, + stage_x11->frame_closure); + stage_x11->frame_closure = NULL; + } + + clutter_stage_window_parent_iface->unrealize (stage_window); + + g_clear_pointer (&stage_x11->onscreen, cogl_object_unref); +} + +static void +frame_cb (CoglOnscreen *onscreen, + CoglFrameEvent frame_event, + CoglFrameInfo *frame_info, + void *user_data) + +{ + ClutterStageCogl *stage_cogl = user_data; + ClutterFrameInfo clutter_frame_info = { + .frame_counter = cogl_frame_info_get_frame_counter (frame_info), + .presentation_time = cogl_frame_info_get_presentation_time (frame_info), + .refresh_rate = cogl_frame_info_get_refresh_rate (frame_info) + }; + + _clutter_stage_cogl_presented (stage_cogl, frame_event, &clutter_frame_info); +} + +static gboolean +meta_stage_x11_realize (ClutterStageWindow *stage_window) +{ + MetaStageX11 *stage_x11 = META_STAGE_X11 (stage_window); + ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window); + ClutterBackend *backend = CLUTTER_BACKEND (stage_cogl->backend); + MetaSeatX11 *seat_x11 = META_SEAT_X11 (clutter_backend_get_default_seat (backend)); + Display *xdisplay = clutter_x11_get_default_display (); + float width, height; + GError *error = NULL; + + clutter_actor_get_size (CLUTTER_ACTOR (stage_cogl->wrapper), &width, &height); + + stage_x11->onscreen = cogl_onscreen_new (backend->cogl_context, width, height); + + stage_x11->frame_closure = + cogl_onscreen_add_frame_callback (stage_x11->onscreen, + frame_cb, + stage_cogl, + NULL); + + if (META_IS_BACKEND_X11_CM (stage_x11->backend)) + { + MetaRenderer *renderer = meta_backend_get_renderer (stage_x11->backend); + MetaRendererX11Cm *renderer_x11_cm = META_RENDERER_X11_CM (renderer); + + meta_renderer_x11_cm_set_onscreen (renderer_x11_cm, stage_x11->onscreen); + } + + /* We just created a window of the size of the actor. No need to fix + the size of the stage, just update it. */ + stage_x11->xwin_width = width; + stage_x11->xwin_height = height; + + if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (stage_x11->onscreen), &error)) + { + g_warning ("Failed to allocate stage: %s", error->message); + g_error_free (error); + cogl_object_unref (stage_x11->onscreen); + abort(); + } + + if (!(clutter_stage_window_parent_iface->realize (stage_window))) + return FALSE; + + stage_x11->xwin = cogl_x11_onscreen_get_window_xid (stage_x11->onscreen); + + if (clutter_stages_by_xid == NULL) + clutter_stages_by_xid = g_hash_table_new (NULL, NULL); + + g_hash_table_insert (clutter_stages_by_xid, + GINT_TO_POINTER (stage_x11->xwin), + stage_x11); + + set_wm_pid (stage_x11); + set_wm_title (stage_x11); + set_cursor_visible (stage_x11); + + /* we unconditionally select input events even with event retrieval + * disabled because we need to guarantee that the Clutter internal + * state is maintained when calling clutter_x11_handle_event() without + * requiring applications or embedding toolkits to select events + * themselves. if we did that, we'd have to document the events to be + * selected, and also update applications and embedding toolkits each + * time we added a new mask, or a new class of events. + * + * see: http://bugzilla.clutter-project.org/show_bug.cgi?id=998 + * for the rationale of why we did conditional selection. it is now + * clear that a compositor should clear out the input region, since + * it cannot assume a perfectly clean slate coming from us. + * + * see: http://bugzilla.clutter-project.org/show_bug.cgi?id=2228 + * for an example of things that break if we do conditional event + * selection. + */ + XSelectInput (xdisplay, stage_x11->xwin, META_STAGE_X11_EVENT_MASK); + + meta_seat_x11_select_stage_events (seat_x11, stage_cogl->wrapper); + + meta_stage_x11_fix_window_size (stage_x11, + stage_x11->xwin_width, + stage_x11->xwin_height); + meta_stage_x11_set_wm_protocols (stage_x11); + + return TRUE; +} + +static void +meta_stage_x11_set_cursor_visible (ClutterStageWindow *stage_window, + gboolean cursor_visible) +{ + MetaStageX11 *stage_x11 = META_STAGE_X11 (stage_window); + + stage_x11->is_cursor_visible = !!cursor_visible; + set_cursor_visible (stage_x11); +} + +static void +meta_stage_x11_set_title (ClutterStageWindow *stage_window, + const char *title) +{ + MetaStageX11 *stage_x11 = META_STAGE_X11 (stage_window); + + g_free (stage_x11->title); + stage_x11->title = g_strdup (title); + set_wm_title (stage_x11); +} + +static inline void +update_wm_hints (MetaStageX11 *stage_x11) +{ + Display *xdisplay = clutter_x11_get_default_display (); + XWMHints wm_hints; + + if (stage_x11->wm_state & STAGE_X11_WITHDRAWN) + return; + + wm_hints.flags = StateHint | InputHint; + wm_hints.initial_state = NormalState; + wm_hints.input = stage_x11->accept_focus ? True : False; + + XSetWMHints (xdisplay, stage_x11->xwin, &wm_hints); +} + +static void +meta_stage_x11_set_accept_focus (ClutterStageWindow *stage_window, + gboolean accept_focus) +{ + MetaStageX11 *stage_x11 = META_STAGE_X11 (stage_window); + + stage_x11->accept_focus = !!accept_focus; + update_wm_hints (stage_x11); +} + +static void +set_stage_x11_state (MetaStageX11 *stage_x11, + MetaStageX11State unset_flags, + MetaStageX11State set_flags) +{ + MetaStageX11State new_stage_state, old_stage_state; + + old_stage_state = stage_x11->wm_state; + + new_stage_state = old_stage_state; + new_stage_state |= set_flags; + new_stage_state &= ~unset_flags; + + if (new_stage_state == old_stage_state) + return; + + stage_x11->wm_state = new_stage_state; +} + +static void +meta_stage_x11_show (ClutterStageWindow *stage_window, + gboolean do_raise) +{ + MetaStageX11 *stage_x11 = META_STAGE_X11 (stage_window); + ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11); + + if (stage_x11->xwin != None) + { + Display *xdisplay = clutter_x11_get_default_display (); + + if (do_raise) + { + XRaiseWindow (xdisplay, stage_x11->xwin); + } + + if (!STAGE_X11_IS_MAPPED (stage_x11)) + { + set_stage_x11_state (stage_x11, STAGE_X11_WITHDRAWN, 0); + + update_wm_hints (stage_x11); + } + + g_assert (STAGE_X11_IS_MAPPED (stage_x11)); + + clutter_actor_map (CLUTTER_ACTOR (stage_cogl->wrapper)); + + XMapWindow (xdisplay, stage_x11->xwin); + } +} + +static void +meta_stage_x11_hide (ClutterStageWindow *stage_window) +{ + MetaStageX11 *stage_x11 = META_STAGE_X11 (stage_window); + ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11); + + if (stage_x11->xwin != None) + { + Display *xdisplay = clutter_x11_get_default_display (); + + if (STAGE_X11_IS_MAPPED (stage_x11)) + set_stage_x11_state (stage_x11, 0, STAGE_X11_WITHDRAWN); + + g_assert (!STAGE_X11_IS_MAPPED (stage_x11)); + + clutter_actor_unmap (CLUTTER_ACTOR (stage_cogl->wrapper)); + + XWithdrawWindow (xdisplay, stage_x11->xwin, 0); + } +} + +static gboolean +meta_stage_x11_can_clip_redraws (ClutterStageWindow *stage_window) +{ + MetaStageX11 *stage_x11 = META_STAGE_X11 (stage_window); + + /* while resizing a window, clipped redraws are disabled in order to + * avoid artefacts. + */ + return stage_x11->clipped_redraws_cool_off == 0; +} + +static GList * +meta_stage_x11_get_views (ClutterStageWindow *stage_window) +{ + MetaStageX11 *stage_x11 = META_STAGE_X11 (stage_window); + MetaRenderer *renderer = meta_backend_get_renderer (stage_x11->backend); + + return meta_renderer_get_views (renderer); +} + +static int64_t +meta_stage_x11_get_frame_counter (ClutterStageWindow *stage_window) +{ + MetaStageX11 *stage_x11 = META_STAGE_X11 (stage_window); + + return cogl_onscreen_get_frame_counter (stage_x11->onscreen); +} + +static void +meta_stage_x11_finalize (GObject *object) +{ + MetaStageX11 *stage_x11 = META_STAGE_X11 (object); + + g_free (stage_x11->title); + + G_OBJECT_CLASS (meta_stage_x11_parent_class)->finalize (object); +} + +static void +meta_stage_x11_class_init (MetaStageX11Class *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = meta_stage_x11_finalize; +} + +static void +meta_stage_x11_init (MetaStageX11 *stage) +{ + MetaRenderer *renderer; + MetaRendererX11Cm *renderer_x11_cm; + + stage->xwin = None; + stage->xwin_width = 640; + stage->xwin_height = 480; + + stage->wm_state = STAGE_X11_WITHDRAWN; + + stage->is_cursor_visible = TRUE; + stage->accept_focus = TRUE; + + stage->title = NULL; + + stage->backend = meta_get_backend (); + g_assert (stage->backend); + + if (META_IS_BACKEND_X11_CM (stage->backend)) + { + renderer = meta_backend_get_renderer (stage->backend); + renderer_x11_cm = META_RENDERER_X11_CM (renderer); + + meta_renderer_x11_cm_ensure_screen_view (renderer_x11_cm, + stage->xwin_width, + stage->xwin_height); + } +} + +static void +clutter_stage_window_iface_init (ClutterStageWindowInterface *iface) +{ + clutter_stage_window_parent_iface = g_type_interface_peek_parent (iface); + + iface->set_title = meta_stage_x11_set_title; + iface->set_cursor_visible = meta_stage_x11_set_cursor_visible; + iface->set_accept_focus = meta_stage_x11_set_accept_focus; + iface->show = meta_stage_x11_show; + iface->hide = meta_stage_x11_hide; + iface->resize = meta_stage_x11_resize; + iface->get_geometry = meta_stage_x11_get_geometry; + iface->realize = meta_stage_x11_realize; + iface->unrealize = meta_stage_x11_unrealize; + iface->can_clip_redraws = meta_stage_x11_can_clip_redraws; + iface->get_views = meta_stage_x11_get_views; + iface->get_frame_counter = meta_stage_x11_get_frame_counter; +} + +static inline void +set_user_time (ClutterBackendX11 *backend_x11, + MetaStageX11 *stage_x11, + long timestamp) +{ + if (timestamp != CLUTTER_CURRENT_TIME) + { + Display *xdisplay = clutter_x11_get_default_display (); + + XChangeProperty (xdisplay, + stage_x11->xwin, + backend_x11->atom_NET_WM_USER_TIME, + XA_CARDINAL, 32, + PropModeReplace, + (unsigned char *) ×tamp, 1); + } +} + +static gboolean +handle_wm_protocols_event (ClutterBackendX11 *backend_x11, + MetaStageX11 *stage_x11, + XEvent *xevent) +{ + Atom atom = (Atom) xevent->xclient.data.l[0]; + + if (atom == backend_x11->atom_WM_DELETE_WINDOW && + xevent->xany.window == stage_x11->xwin) + { + set_user_time (backend_x11, stage_x11, xevent->xclient.data.l[1]); + + return TRUE; + } + else if (atom == backend_x11->atom_NET_WM_PING && + xevent->xany.window == stage_x11->xwin) + { + XClientMessageEvent xclient = xevent->xclient; + Display *xdisplay = clutter_x11_get_default_display (); + + xclient.window = backend_x11->xwin_root; + XSendEvent (xdisplay, xclient.window, + False, + SubstructureRedirectMask | SubstructureNotifyMask, + (XEvent *) &xclient); + return FALSE; + } + + /* do not send any of the WM_PROTOCOLS events to the queue */ + return FALSE; +} + +static gboolean +clipped_redraws_cool_off_cb (void *data) +{ + MetaStageX11 *stage_x11 = data; + + stage_x11->clipped_redraws_cool_off = 0; + + return G_SOURCE_REMOVE; +} + +gboolean +meta_stage_x11_translate_event (MetaStageX11 *stage_x11, + XEvent *xevent, + ClutterEvent *event) +{ + ClutterStageCogl *stage_cogl; + gboolean res = FALSE; + ClutterBackendX11 *backend_x11; + ClutterStage *stage; + + stage_cogl = meta_x11_get_stage_window_from_window (xevent->xany.window); + if (stage_cogl == NULL) + return FALSE; + + stage = stage_cogl->wrapper; + backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend); + + switch (xevent->type) + { + case ConfigureNotify: + { + gboolean size_changed = FALSE; + int stage_width; + int stage_height; + + g_debug ("ConfigureNotify[%x] (%d, %d)", + (unsigned int) stage_x11->xwin, + xevent->xconfigure.width, + xevent->xconfigure.height); + + if ((stage_x11->xwin_width != xevent->xconfigure.width) || + (stage_x11->xwin_height != xevent->xconfigure.height)) + { + size_changed = TRUE; + stage_x11->xwin_width = xevent->xconfigure.width; + stage_x11->xwin_height = xevent->xconfigure.height; + } + + stage_width = xevent->xconfigure.width; + stage_height = xevent->xconfigure.height; + clutter_actor_set_size (CLUTTER_ACTOR (stage), stage_width, stage_height); + + if (size_changed) + { + /* XXX: This is a workaround for a race condition when + * resizing windows while there are in-flight + * glXCopySubBuffer blits happening. + * + * The problem stems from the fact that rectangles for the + * blits are described relative to the bottom left of the + * window and because we can't guarantee control over the X + * window gravity used when resizing so the gravity is + * typically NorthWest not SouthWest. + * + * This means if you grow a window vertically the server + * will make sure to place the old contents of the window + * at the top-left/north-west of your new larger window, but + * that may happen asynchronous to GLX preparing to do a + * blit specified relative to the bottom-left/south-west of + * the window (based on the old smaller window geometry). + * + * When the GLX issued blit finally happens relative to the + * new bottom of your window, the destination will have + * shifted relative to the top-left where all the pixels you + * care about are so it will result in a nasty artefact + * making resizing look very ugly! + * + * We can't currently fix this completely, in-part because + * the window manager tends to trample any gravity we might + * set. This workaround instead simply disables blits for a + * while if we are notified of any resizes happening so if + * the user is resizing a window via the window manager then + * they may see an artefact for one frame but then we will + * fallback to redrawing the full stage until the cooling + * off period is over. + */ + g_clear_handle_id (&stage_x11->clipped_redraws_cool_off, + g_source_remove); + + stage_x11->clipped_redraws_cool_off = + clutter_threads_add_timeout (1000, + clipped_redraws_cool_off_cb, + stage_x11); + + /* Queue a relayout - we want glViewport to be called + * with the correct values, and this is done in ClutterStage + * via cogl_onscreen_clutter_backend_set_size (). + * + * We queue a relayout, because if this ConfigureNotify is + * in response to a size we set in the application, the + * set_size() call above is essentially a null-op. + * + * Make sure we do this only when the size has changed, + * otherwise we end up relayouting on window moves. + */ + clutter_actor_queue_relayout (CLUTTER_ACTOR (stage)); + + /* the resize process is complete, so we can ask the stage + * to set up the GL viewport with the new size + */ + clutter_stage_ensure_viewport (stage); + + /* If this was a result of the Xrandr change when running as a + * X11 compositing manager, we need to reset the legacy + * stage view, now that it has a new size. + */ + if (META_IS_BACKEND_X11_CM (stage_x11->backend)) + { + MetaBackend *backend = stage_x11->backend; + MetaRenderer *renderer = meta_backend_get_renderer (backend); + MetaRendererX11Cm *renderer_x11_cm = + META_RENDERER_X11_CM (renderer); + + meta_renderer_x11_cm_resize (renderer_x11_cm, + stage_width, + stage_height); + } + } + } + break; + + case FocusIn: + if (!_clutter_stage_is_activated (stage_cogl->wrapper)) + { + _clutter_stage_update_state (stage_cogl->wrapper, + 0, + CLUTTER_STAGE_STATE_ACTIVATED); + } + break; + + case FocusOut: + if (_clutter_stage_is_activated (stage_cogl->wrapper)) + { + _clutter_stage_update_state (stage_cogl->wrapper, + CLUTTER_STAGE_STATE_ACTIVATED, + 0); + } + break; + + case Expose: + { + XExposeEvent *expose = (XExposeEvent *) xevent; + cairo_rectangle_int_t clip; + + g_debug ("expose for stage: win:0x%x - " + "redrawing area (x: %d, y: %d, width: %d, height: %d)", + (unsigned int) xevent->xany.window, + expose->x, + expose->y, + expose->width, + expose->height); + + clip.x = expose->x; + clip.y = expose->y; + clip.width = expose->width; + clip.height = expose->height; + clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stage), &clip); + } + break; + + case DestroyNotify: + g_debug ("Destroy notification received for stage, win:0x%x", + (unsigned int) xevent->xany.window); + + event->any.type = CLUTTER_DESTROY_NOTIFY; + event->any.stage = stage; + res = TRUE; + break; + + case ClientMessage: + g_debug ("Client message for stage, win:0x%x", + (unsigned int) xevent->xany.window); + + if (xevent->xclient.message_type == backend_x11->atom_WM_PROTOCOLS) + { + if (handle_wm_protocols_event (backend_x11, stage_x11, xevent)) + { + event->any.type = CLUTTER_DELETE; + event->any.stage = stage; + res = TRUE; + } + } + + break; + + default: + res = FALSE; + break; + } + + return res; +} + +Window +meta_x11_get_stage_window (ClutterStage *stage) +{ + ClutterStageWindow *impl; + + g_return_val_if_fail (CLUTTER_IS_STAGE (stage), None); + + impl = _clutter_stage_get_window (stage); + g_assert (META_IS_STAGE_X11 (impl)); + + return META_STAGE_X11 (impl)->xwin; +} + +static ClutterStageCogl * +meta_x11_get_stage_window_from_window (Window win) +{ + if (clutter_stages_by_xid == NULL) + return NULL; + + return g_hash_table_lookup (clutter_stages_by_xid, + GINT_TO_POINTER (win)); +} + +ClutterStage * +meta_x11_get_stage_from_window (Window win) +{ + ClutterStageCogl *stage_cogl; + + stage_cogl = meta_x11_get_stage_window_from_window (win); + + if (stage_cogl != NULL) + return stage_cogl->wrapper; + + return NULL; +} + +void +meta_stage_x11_set_user_time (MetaStageX11 *stage_x11, + uint32_t user_time) +{ + ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_x11); + ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (stage_cogl->backend); + + set_user_time (backend_x11, stage_x11, user_time); +} diff --git a/src/backends/x11/meta-stage-x11.h b/src/backends/x11/meta-stage-x11.h new file mode 100644 index 000000000..f37ec6708 --- /dev/null +++ b/src/backends/x11/meta-stage-x11.h @@ -0,0 +1,98 @@ +/* Clutter. + * An OpenGL based 'interactive canvas' library. + * Authored By Matthew Allum <mallum@openedhand.com> + * Copyright (C) 2006-2007 OpenedHand + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * + */ + +#ifndef META_STAGE_X11_H +#define META_STAGE_X11_H + +#include <X11/Xlib.h> +#include <X11/Xatom.h> + +#include "backends/meta-backend-private.h" +#include "clutter/clutter-mutter.h" +#include "clutter/x11/clutter-x11.h" + +G_BEGIN_DECLS + +#define META_TYPE_STAGE_X11 (meta_stage_x11_get_type ()) +#define META_STAGE_X11(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_STAGE_X11, MetaStageX11)) +#define META_IS_STAGE_X11(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_STAGE_X11)) +#define META_STAGE_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_STAGE_X11, MetaStageX11Class)) +#define META_IS_STAGE_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_STAGE_X11)) +#define META_STAGE_X11_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_STAGE_X11, MetaStageX11Class)) + +typedef struct _MetaStageX11 MetaStageX11; +typedef struct _MetaStageX11Class MetaStageX11Class; + +G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaStageX11, g_object_unref) + +typedef enum +{ + STAGE_X11_WITHDRAWN = 1 << 1 +} MetaStageX11State; + +struct _MetaStageX11 +{ + ClutterStageCogl parent_instance; + + MetaBackend *backend; + + CoglOnscreen *onscreen; + Window xwin; + gint xwin_width; + gint xwin_height; /* FIXME target_width / height */ + + CoglFrameClosure *frame_closure; + + gchar *title; + + guint clipped_redraws_cool_off; + + MetaStageX11State wm_state; + + guint is_cursor_visible : 1; + guint viewport_initialized : 1; + guint accept_focus : 1; +}; + +struct _MetaStageX11Class +{ + ClutterStageCoglClass parent_class; +}; + +CLUTTER_EXPORT +GType meta_stage_x11_get_type (void) G_GNUC_CONST; + +/* Private to subclasses */ +void meta_stage_x11_set_user_time (MetaStageX11 *stage_x11, + guint32 user_time); + +gboolean meta_stage_x11_translate_event (MetaStageX11 *stage_x11, + XEvent *xevent, + ClutterEvent *event); + +ClutterStage *meta_x11_get_stage_from_window (Window win); + +Window meta_x11_get_stage_window (ClutterStage *stage); + + +G_END_DECLS + +#endif /* META_STAGE_H */ diff --git a/src/backends/x11/meta-virtual-input-device-x11.c b/src/backends/x11/meta-virtual-input-device-x11.c new file mode 100644 index 000000000..beeae72b9 --- /dev/null +++ b/src/backends/x11/meta-virtual-input-device-x11.c @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2016 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Author: Jonas Ådahl <jadahl@gmail.com> + */ + +#include "config.h" + +#include <glib-object.h> + +#include <X11/extensions/XTest.h> + +#include "clutter/clutter.h" +#include "clutter/x11/clutter-x11.h" +#include "meta-keymap-x11.h" +#include "meta-virtual-input-device-x11.h" + +struct _MetaVirtualInputDeviceX11 +{ + ClutterVirtualInputDevice parent; +}; + +G_DEFINE_TYPE (MetaVirtualInputDeviceX11, + meta_virtual_input_device_x11, + CLUTTER_TYPE_VIRTUAL_INPUT_DEVICE) + +static void +meta_virtual_input_device_x11_notify_relative_motion (ClutterVirtualInputDevice *virtual_device, + uint64_t time_us, + double dx, + double dy) +{ + XTestFakeRelativeMotionEvent (clutter_x11_get_default_display (), + (int) dx, + (int) dy, + 0); +} + +static void +meta_virtual_input_device_x11_notify_absolute_motion (ClutterVirtualInputDevice *virtual_device, + uint64_t time_us, + double x, + double y) +{ + XTestFakeMotionEvent (clutter_x11_get_default_display (), + clutter_x11_get_default_screen (), + (int) x, + (int) y, + 0); +} + +static void +meta_virtual_input_device_x11_notify_button (ClutterVirtualInputDevice *virtual_device, + uint64_t time_us, + uint32_t button, + ClutterButtonState button_state) +{ + XTestFakeButtonEvent (clutter_x11_get_default_display (), + button, button_state == CLUTTER_BUTTON_STATE_PRESSED, 0); +} + +static void +meta_virtual_input_device_x11_notify_discrete_scroll (ClutterVirtualInputDevice *virtual_device, + uint64_t time_us, + ClutterScrollDirection direction, + ClutterScrollSource scroll_source) +{ + Display *xdisplay = clutter_x11_get_default_display (); + int button; + + switch (direction) + { + case CLUTTER_SCROLL_UP: + button = 4; + break; + case CLUTTER_SCROLL_DOWN: + button = 5; + break; + case CLUTTER_SCROLL_LEFT: + button = 6; + break; + case CLUTTER_SCROLL_RIGHT: + button = 7; + break; + default: + g_warn_if_reached (); + return; + } + + XTestFakeButtonEvent (xdisplay, button, True, 0); + XTestFakeButtonEvent (xdisplay, button, False, 0); +} + +static void +meta_virtual_input_device_x11_notify_scroll_continuous (ClutterVirtualInputDevice *virtual_device, + uint64_t time_us, + double dx, + double dy, + ClutterScrollSource scroll_source, + ClutterScrollFinishFlags finish_flags) +{ +} + +static void +meta_virtual_input_device_x11_notify_key (ClutterVirtualInputDevice *virtual_device, + uint64_t time_us, + uint32_t key, + ClutterKeyState key_state) +{ + XTestFakeKeyEvent (clutter_x11_get_default_display (), + key, key_state == CLUTTER_KEY_STATE_PRESSED, 0); +} + +static void +meta_virtual_input_device_x11_notify_keyval (ClutterVirtualInputDevice *virtual_device, + uint64_t time_us, + uint32_t keyval, + ClutterKeyState key_state) +{ + ClutterBackend *backend = clutter_get_default_backend (); + ClutterSeat *seat = clutter_backend_get_default_seat (backend); + MetaKeymapX11 *keymap = META_KEYMAP_X11 (clutter_seat_get_keymap (seat)); + uint32_t keycode, level; + + if (!meta_keymap_x11_keycode_for_keyval (keymap, keyval, &keycode, &level)) + { + level = 0; + + if (!meta_keymap_x11_reserve_keycode (keymap, keyval, &keycode)) + { + g_warning ("No keycode found for keyval %x in current group", keyval); + return; + } + } + + if (!meta_keymap_x11_get_is_modifier (keymap, keycode) && + key_state == CLUTTER_KEY_STATE_PRESSED) + meta_keymap_x11_latch_modifiers (keymap, level, TRUE); + + XTestFakeKeyEvent (clutter_x11_get_default_display (), + (KeyCode) keycode, + key_state == CLUTTER_KEY_STATE_PRESSED, 0); + + + if (key_state == CLUTTER_KEY_STATE_RELEASED) + { + if (!meta_keymap_x11_get_is_modifier (keymap, keycode)) + meta_keymap_x11_latch_modifiers (keymap, level, FALSE); + meta_keymap_x11_release_keycode_if_needed (keymap, keycode); + } +} + +static void +meta_virtual_input_device_x11_notify_touch_down (ClutterVirtualInputDevice *virtual_device, + uint64_t time_us, + int device_slot, + double x, + double y) +{ + g_warning ("Virtual touch motion not implemented under X11"); +} + +static void +meta_virtual_input_device_x11_notify_touch_motion (ClutterVirtualInputDevice *virtual_device, + uint64_t time_us, + int device_slot, + double x, + double y) +{ + g_warning ("Virtual touch motion not implemented under X11"); +} + +static void +meta_virtual_input_device_x11_notify_touch_up (ClutterVirtualInputDevice *virtual_device, + uint64_t time_us, + int device_slot) +{ + g_warning ("Virtual touch motion not implemented under X11"); +} + +static void +meta_virtual_input_device_x11_init (MetaVirtualInputDeviceX11 *virtual_device_x11) +{ +} + +static void +meta_virtual_input_device_x11_class_init (MetaVirtualInputDeviceX11Class *klass) +{ + ClutterVirtualInputDeviceClass *virtual_input_device_class = + CLUTTER_VIRTUAL_INPUT_DEVICE_CLASS (klass); + + virtual_input_device_class->notify_relative_motion = meta_virtual_input_device_x11_notify_relative_motion; + virtual_input_device_class->notify_absolute_motion = meta_virtual_input_device_x11_notify_absolute_motion; + virtual_input_device_class->notify_button = meta_virtual_input_device_x11_notify_button; + virtual_input_device_class->notify_discrete_scroll = meta_virtual_input_device_x11_notify_discrete_scroll; + virtual_input_device_class->notify_scroll_continuous = meta_virtual_input_device_x11_notify_scroll_continuous; + virtual_input_device_class->notify_key = meta_virtual_input_device_x11_notify_key; + virtual_input_device_class->notify_keyval = meta_virtual_input_device_x11_notify_keyval; + virtual_input_device_class->notify_touch_down = meta_virtual_input_device_x11_notify_touch_down; + virtual_input_device_class->notify_touch_motion = meta_virtual_input_device_x11_notify_touch_motion; + virtual_input_device_class->notify_touch_up = meta_virtual_input_device_x11_notify_touch_up; +} diff --git a/clutter/clutter/evdev/clutter-virtual-input-device-evdev.h b/src/backends/x11/meta-virtual-input-device-x11.h similarity index 60% rename from clutter/clutter/evdev/clutter-virtual-input-device-evdev.h rename to src/backends/x11/meta-virtual-input-device-x11.h index 9bb8db016..88c41ae8d 100644 --- a/clutter/clutter/evdev/clutter-virtual-input-device-evdev.h +++ b/src/backends/x11/meta-virtual-input-device-x11.h @@ -1,8 +1,4 @@ /* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * * Copyright (C) 2016 Red Hat Inc. * * This library is free software; you can redistribute it and/or @@ -21,15 +17,15 @@ * Author: Jonas Ådahl <jadahl@gmail.com> */ -#ifndef __CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV_H__ -#define __CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV_H__ +#ifndef META_VIRTUAL_INPUT_DEVICE_X11_H +#define META_VIRTUAL_INPUT_DEVICE_X11_H -#include "clutter-virtual-input-device.h" +#include "clutter/clutter.h" -#define CLUTTER_TYPE_VIRTUAL_INPUT_DEVICE_EVDEV (clutter_virtual_input_device_evdev_get_type ()) -G_DECLARE_FINAL_TYPE (ClutterVirtualInputDeviceEvdev, - clutter_virtual_input_device_evdev, - CLUTTER, VIRTUAL_INPUT_DEVICE_EVDEV, +#define META_TYPE_VIRTUAL_INPUT_DEVICE_X11 (meta_virtual_input_device_x11_get_type ()) +G_DECLARE_FINAL_TYPE (MetaVirtualInputDeviceX11, + meta_virtual_input_device_x11, + META, VIRTUAL_INPUT_DEVICE_X11, ClutterVirtualInputDevice) -#endif /* __CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV_H__ */ +#endif /* META_VIRTUAL_INPUT_DEVICE_X11_H */ diff --git a/clutter/clutter/x11/clutter-xkb-a11y-x11.c b/src/backends/x11/meta-xkb-a11y-x11.c similarity index 81% rename from clutter/clutter/x11/clutter-xkb-a11y-x11.c rename to src/backends/x11/meta-xkb-a11y-x11.c index 6adde813a..5deb6f3ff 100644 --- a/clutter/clutter/x11/clutter-xkb-a11y-x11.c +++ b/src/backends/x11/meta-xkb-a11y-x11.c @@ -1,5 +1,4 @@ /* - * * Copyright © 2001 Ximian, Inc. * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu> * Copyright (C) 2017 Red Hat @@ -21,12 +20,16 @@ * */ -#include "clutter-device-manager-private.h" -#include "clutter-xkb-a11y-x11.h" +#include "config.h" #include <X11/XKBlib.h> #include <X11/extensions/XKBstr.h> +#include "backends/x11/meta-xkb-a11y-x11.h" +#include "clutter/x11/clutter-x11.h" +#include "core/display-private.h" +#include "meta/meta-x11-errors.h" + #define DEFAULT_XKB_SET_CONTROLS_MASK XkbSlowKeysMask | \ XkbBounceKeysMask | \ XkbStickyKeysMask | \ @@ -40,17 +43,17 @@ static int _xkb_event_base; static XkbDescRec * -get_xkb_desc_rec (ClutterBackendX11 *backend_x11) +get_xkb_desc_rec (Display *xdisplay) { XkbDescRec *desc; Status status = Success; clutter_x11_trap_x_errors (); - desc = XkbGetMap (backend_x11->xdpy, XkbAllMapComponentsMask, XkbUseCoreKbd); + desc = XkbGetMap (xdisplay, XkbAllMapComponentsMask, XkbUseCoreKbd); if (desc != NULL) { desc->ctrls = NULL; - status = XkbGetControls (backend_x11->xdpy, XkbAllControlsMask, desc); + status = XkbGetControls (xdisplay, XkbAllControlsMask, desc); } clutter_x11_untrap_x_errors (); @@ -62,29 +65,28 @@ get_xkb_desc_rec (ClutterBackendX11 *backend_x11) } static void -set_xkb_desc_rec (ClutterBackendX11 *backend_x11, - XkbDescRec *desc) +set_xkb_desc_rec (Display *xdisplay, + XkbDescRec *desc) { clutter_x11_trap_x_errors (); - XkbSetControls (backend_x11->xdpy, DEFAULT_XKB_SET_CONTROLS_MASK, desc); - XSync (backend_x11->xdpy, FALSE); + XkbSetControls (xdisplay, DEFAULT_XKB_SET_CONTROLS_MASK, desc); + XSync (xdisplay, FALSE); clutter_x11_untrap_x_errors (); } static void -check_settings_changed (ClutterDeviceManager *device_manager) +check_settings_changed (ClutterSeat *seat) { - ClutterBackendX11 *backend_x11; + Display *xdisplay = clutter_x11_get_default_display (); ClutterKbdA11ySettings kbd_a11y_settings; ClutterKeyboardA11yFlags what_changed = 0; XkbDescRec *desc; - backend_x11 = CLUTTER_BACKEND_X11 (clutter_get_default_backend ()); - desc = get_xkb_desc_rec (backend_x11); + desc = get_xkb_desc_rec (xdisplay); if (!desc) return; - clutter_device_manager_get_kbd_a11y_settings (device_manager, &kbd_a11y_settings); + clutter_seat_get_kbd_a11y_settings (seat, &kbd_a11y_settings); if (desc->ctrls->enabled_ctrls & XkbSlowKeysMask && !(kbd_a11y_settings.controls & CLUTTER_A11Y_SLOW_KEYS_ENABLED)) @@ -113,7 +115,7 @@ check_settings_changed (ClutterDeviceManager *device_manager) } if (what_changed) - g_signal_emit_by_name (device_manager, + g_signal_emit_by_name (seat, "kbd-a11y-flags-changed", kbd_a11y_settings.controls, what_changed); @@ -126,7 +128,7 @@ xkb_a11y_event_filter (XEvent *xevent, ClutterEvent *clutter_event, gpointer data) { - ClutterDeviceManager *device_manager = CLUTTER_DEVICE_MANAGER (data); + ClutterSeat *seat = CLUTTER_SEAT (data); XkbEvent *xkbev = (XkbEvent *) xevent; /* 'event_type' is set to zero on notifying us of updates in @@ -139,20 +141,20 @@ xkb_a11y_event_filter (XEvent *xevent, */ if (xevent->xany.type == (_xkb_event_base + XkbEventCode) && xkbev->any.xkb_type == XkbControlsNotify && xkbev->ctrls.event_type != 0) - check_settings_changed (device_manager); + check_settings_changed (seat); - return CLUTTER_X11_FILTER_CONTINUE; + return CLUTTER_X11_FILTER_CONTINUE; } static gboolean -is_xkb_available (ClutterBackendX11 *backend_x11) +is_xkb_available (Display *xdisplay) { - gint opcode, error_base, event_base, major, minor; + int opcode, error_base, event_base, major, minor; if (_xkb_event_base) return TRUE; - if (!XkbQueryExtension (backend_x11->xdpy, + if (!XkbQueryExtension (xdisplay, &opcode, &event_base, &error_base, @@ -160,7 +162,7 @@ is_xkb_available (ClutterBackendX11 *backend_x11) &minor)) return FALSE; - if (!XkbUseExtension (backend_x11->xdpy, &major, &minor)) + if (!XkbUseExtension (xdisplay, &major, &minor)) return FALSE; _xkb_event_base = event_base; @@ -192,15 +194,14 @@ set_xkb_ctrl (XkbDescRec *desc, } void -clutter_device_manager_x11_apply_kbd_a11y_settings (ClutterDeviceManager *device_manager, - ClutterKbdA11ySettings *kbd_a11y_settings) +meta_seat_x11_apply_kbd_a11y_settings (ClutterSeat *seat, + ClutterKbdA11ySettings *kbd_a11y_settings) { - ClutterBackendX11 *backend_x11; - XkbDescRec *desc; - gboolean enable_accessX; + Display *xdisplay = clutter_x11_get_default_display (); + XkbDescRec *desc; + gboolean enable_accessX; - backend_x11 = CLUTTER_BACKEND_X11 (clutter_get_default_backend ()); - desc = get_xkb_desc_rec (backend_x11); + desc = get_xkb_desc_rec (xdisplay); if (!desc) return; @@ -241,11 +242,16 @@ clutter_device_manager_x11_apply_kbd_a11y_settings (ClutterDeviceManager *devi } /* mouse keys */ - if (set_xkb_ctrl (desc, kbd_a11y_settings->controls, - CLUTTER_A11Y_MOUSE_KEYS_ENABLED, XkbMouseKeysMask | XkbMouseKeysAccelMask)) + if (clutter_keymap_get_num_lock_state (clutter_seat_get_keymap (seat))) { - gint mk_max_speed; - gint mk_accel_time; + /* Disable mousekeys when NumLock is ON */ + desc->ctrls->enabled_ctrls &= ~(XkbMouseKeysMask | XkbMouseKeysAccelMask); + } + else if (set_xkb_ctrl (desc, kbd_a11y_settings->controls, + CLUTTER_A11Y_MOUSE_KEYS_ENABLED, XkbMouseKeysMask | XkbMouseKeysAccelMask)) + { + int mk_max_speed; + int mk_accel_time; desc->ctrls->mk_interval = 100; /* msec between mousekey events */ desc->ctrls->mk_curve = 50; @@ -302,27 +308,24 @@ clutter_device_manager_x11_apply_kbd_a11y_settings (ClutterDeviceManager *devi set_value_mask (kbd_a11y_settings->controls & CLUTTER_A11Y_TOGGLE_KEYS_ENABLED, desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_IndicatorFBMask); - set_xkb_desc_rec (backend_x11, desc); + set_xkb_desc_rec (xdisplay, desc); XkbFreeKeyboard (desc, XkbAllComponentsMask, TRUE); } gboolean -clutter_device_manager_x11_a11y_init (ClutterDeviceManager *device_manager) +meta_seat_x11_a11y_init (ClutterSeat *seat) { - ClutterBackendX11 *backend_x11; + Display *xdisplay = clutter_x11_get_default_display (); guint event_mask; - backend_x11 = - CLUTTER_BACKEND_X11 (_clutter_device_manager_get_backend (device_manager)); - - if (!is_xkb_available (backend_x11)) + if (!is_xkb_available (xdisplay)) return FALSE; event_mask = XkbControlsNotifyMask | XkbAccessXNotifyMask; - XkbSelectEvents (backend_x11->xdpy, XkbUseCoreKbd, event_mask, event_mask); + XkbSelectEvents (xdisplay, XkbUseCoreKbd, event_mask, event_mask); - clutter_x11_add_filter (xkb_a11y_event_filter, device_manager); + clutter_x11_add_filter (xkb_a11y_event_filter, seat); return TRUE; } diff --git a/clutter/clutter/x11/clutter-xkb-a11y-x11.h b/src/backends/x11/meta-xkb-a11y-x11.h similarity index 66% rename from clutter/clutter/x11/clutter-xkb-a11y-x11.h rename to src/backends/x11/meta-xkb-a11y-x11.h index 8446bc8ca..7f11bf7b0 100644 --- a/clutter/clutter/x11/clutter-xkb-a11y-x11.h +++ b/src/backends/x11/meta-xkb-a11y-x11.h @@ -21,19 +21,18 @@ * */ -#ifndef CLUTTER_XKB_A11Y_X11_H -#define CLUTTER_XKB_A11Y_X11_H - -#include "clutter-device-manager-private.h" -#include "clutter-backend-x11.h" +#ifndef META_XKB_A11Y_X11_H +#define META_XKB_A11Y_X11_H #include <X11/Xlib.h> +#include "clutter/clutter.h" + void -clutter_device_manager_x11_apply_kbd_a11y_settings (ClutterDeviceManager *device_manager, - ClutterKbdA11ySettings *kbd_a11y_settings); +meta_seat_x11_apply_kbd_a11y_settings (ClutterSeat *seat, + ClutterKbdA11ySettings *kbd_a11y_settings); gboolean -clutter_device_manager_x11_a11y_init (ClutterDeviceManager *device_manager); +meta_seat_x11_a11y_init (ClutterSeat *seat); -#endif /* CLUTTER_XKB_A11Y_X11_H */ +#endif /* META_XKB_A11Y_X11_H */ diff --git a/src/backends/x11/nested/meta-backend-x11-nested.c b/src/backends/x11/nested/meta-backend-x11-nested.c new file mode 100644 index 000000000..def74bb74 --- /dev/null +++ b/src/backends/x11/nested/meta-backend-x11-nested.c @@ -0,0 +1,288 @@ +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "backends/x11/nested/meta-backend-x11-nested.h" + +#include "backends/meta-monitor-manager-dummy.h" +#include "backends/x11/nested/meta-backend-x11-nested.h" +#include "backends/x11/nested/meta-cursor-renderer-x11-nested.h" +#include "backends/x11/nested/meta-renderer-x11-nested.h" + +#include "wayland/meta-wayland.h" + +typedef struct _MetaBackendX11NestedPrivate +{ + MetaGpu *gpu; +} MetaBackendX11NestedPrivate; + +static GInitableIface *initable_parent_iface; + +static void +initable_iface_init (GInitableIface *initable_iface); + +G_DEFINE_TYPE_WITH_CODE (MetaBackendX11Nested, meta_backend_x11_nested, + META_TYPE_BACKEND_X11, + G_ADD_PRIVATE (MetaBackendX11Nested) + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + initable_iface_init)); + +static MetaRenderer * +meta_backend_x11_nested_create_renderer (MetaBackend *backend, + GError **error) +{ + return g_object_new (META_TYPE_RENDERER_X11_NESTED, + "backend", backend, + NULL); +} + +static MetaMonitorManager * +meta_backend_x11_nested_create_monitor_manager (MetaBackend *backend, + GError **error) +{ + return g_object_new (META_TYPE_MONITOR_MANAGER_DUMMY, + "backend", backend, + NULL); +} + +static MetaCursorRenderer * +meta_backend_x11_nested_create_cursor_renderer (MetaBackend *backend) +{ + return g_object_new (META_TYPE_CURSOR_RENDERER_X11_NESTED, NULL); +} + +static MetaInputSettings * +meta_backend_x11_nested_create_input_settings (MetaBackend *backend) +{ + return NULL; +} + +static void +meta_backend_x11_nested_update_screen_size (MetaBackend *backend, + int width, + int height) +{ + ClutterActor *stage = meta_backend_get_stage (backend); + MetaRenderer *renderer = meta_backend_get_renderer (backend); + + if (meta_is_stage_views_enabled ()) + { + meta_renderer_rebuild_views (renderer); + clutter_stage_update_resource_scales (CLUTTER_STAGE (stage)); + } + clutter_actor_set_size (stage, width, height); +} + +static void +meta_backend_x11_nested_select_stage_events (MetaBackend *backend) +{ + MetaBackendX11 *x11 = META_BACKEND_X11 (backend); + Display *xdisplay = meta_backend_x11_get_xdisplay (x11); + Window xwin = meta_backend_x11_get_xwindow (x11); + unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; + XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; + + XISetMask (mask.mask, XI_KeyPress); + XISetMask (mask.mask, XI_KeyRelease); + XISetMask (mask.mask, XI_ButtonPress); + XISetMask (mask.mask, XI_ButtonRelease); + XISetMask (mask.mask, XI_Enter); + XISetMask (mask.mask, XI_Leave); + XISetMask (mask.mask, XI_FocusIn); + XISetMask (mask.mask, XI_FocusOut); + XISetMask (mask.mask, XI_Motion); + + /* + * When we're an X11 compositor, we can't take these events or else replaying + * events from our passive root window grab will cause them to come back to + * us. + * + * When we're a nested application, we want to behave like any other + * application, so select these events like normal apps do. + */ + XISetMask (mask.mask, XI_TouchBegin); XISetMask (mask.mask, XI_TouchEnd); + XISetMask (mask.mask, XI_TouchUpdate); + + XISelectEvents (xdisplay, xwin, &mask, 1); + + /* + * We have no way of tracking key changes when the stage doesn't have focus, + * so we select for KeymapStateMask so that we get a complete dump of the + * keyboard state in a KeymapNotify event that immediately follows each + * FocusIn (and EnterNotify, but we ignore that.) + */ + XWindowAttributes xwa; + + XGetWindowAttributes(xdisplay, xwin, &xwa); + XSelectInput(xdisplay, xwin, + xwa.your_event_mask | FocusChangeMask | KeymapStateMask); +} + +static void +meta_backend_x11_nested_lock_layout_group (MetaBackend *backend, + guint idx) +{ +} + +static void +meta_backend_x11_nested_set_keymap (MetaBackend *backend, + const char *layouts, + const char *variants, + const char *options) +{ +} + +static gboolean +meta_backend_x11_nested_is_lid_closed (MetaBackend *backend) +{ + return FALSE; +} + +static gboolean +meta_backend_x11_nested_handle_host_xevent (MetaBackendX11 *x11, + XEvent *event) +{ +#ifdef HAVE_WAYLAND + if (event->type == FocusIn) + { + Window xwin = meta_backend_x11_get_xwindow (x11); + XEvent xev; + + if (event->xfocus.window == xwin) + { + MetaWaylandCompositor *compositor = + meta_wayland_compositor_get_default (); + Display *xdisplay = meta_backend_x11_get_xdisplay (x11); + + /* + * Since we've selected for KeymapStateMask, every FocusIn is + * followed immediately by a KeymapNotify event. + */ + XMaskEvent (xdisplay, KeymapStateMask, &xev); + meta_wayland_compositor_update_key_state (compositor, + xev.xkeymap.key_vector, + 32, 8); + } + } +#endif + + return FALSE; +} + +static void +meta_backend_x11_nested_translate_device_event (MetaBackendX11 *x11, + XIDeviceEvent *device_event) +{ + /* This codepath should only ever trigger as an X11 compositor, + * and never under nested, as under nested all backend events + * should be reported with respect to the stage window. + */ + g_assert (device_event->event == meta_backend_x11_get_xwindow (x11)); +} + +static void +meta_backend_x11_nested_real_init_gpus (MetaBackendX11Nested *backend_x11_nested) +{ + MetaBackendX11NestedPrivate *priv = + meta_backend_x11_nested_get_instance_private (backend_x11_nested); + + priv->gpu = g_object_new (META_TYPE_GPU_DUMMY, + "backend", backend_x11_nested, + NULL); + meta_backend_add_gpu (META_BACKEND (backend_x11_nested), priv->gpu); +} + +static void +meta_backend_x11_nested_post_init (MetaBackend *backend) +{ + MetaBackendClass *backend_class = + META_BACKEND_CLASS (meta_backend_x11_nested_parent_class); + + backend_class->post_init (backend); + +#ifdef HAVE_WAYLAND + meta_backend_init_wayland (backend); +#endif +} + +static gboolean +meta_backend_x11_nested_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ +#ifdef HAVE_WAYLAND + meta_backend_init_wayland_display (META_BACKEND (initable)); +#endif + + return initable_parent_iface->init (initable, cancellable, error); +} + +static void +initable_iface_init (GInitableIface *initable_iface) +{ + initable_parent_iface = g_type_interface_peek_parent (initable_iface); + + initable_iface->init = meta_backend_x11_nested_initable_init; +} + +static void +meta_backend_x11_nested_constructed (GObject *object) +{ + MetaBackendX11Nested *backend_x11_nested = META_BACKEND_X11_NESTED (object); + MetaBackendX11NestedClass *backend_x11_nested_class = + META_BACKEND_X11_NESTED_GET_CLASS (backend_x11_nested); + GObjectClass *parent_class = + G_OBJECT_CLASS (meta_backend_x11_nested_parent_class); + + parent_class->constructed (object); + + backend_x11_nested_class->init_gpus (backend_x11_nested); +} + +static void +meta_backend_x11_nested_init (MetaBackendX11Nested *backend_x11_nested) +{ +} + +static void +meta_backend_x11_nested_class_init (MetaBackendX11NestedClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MetaBackendClass *backend_class = META_BACKEND_CLASS (klass); + MetaBackendX11Class *backend_x11_class = META_BACKEND_X11_CLASS (klass); + + object_class->constructed = meta_backend_x11_nested_constructed; + + backend_class->post_init = meta_backend_x11_nested_post_init; + backend_class->create_renderer = meta_backend_x11_nested_create_renderer; + backend_class->create_monitor_manager = meta_backend_x11_nested_create_monitor_manager; + backend_class->create_cursor_renderer = meta_backend_x11_nested_create_cursor_renderer; + backend_class->create_input_settings = meta_backend_x11_nested_create_input_settings; + backend_class->update_screen_size = meta_backend_x11_nested_update_screen_size; + backend_class->select_stage_events = meta_backend_x11_nested_select_stage_events; + backend_class->lock_layout_group = meta_backend_x11_nested_lock_layout_group; + backend_class->set_keymap = meta_backend_x11_nested_set_keymap; + backend_class->is_lid_closed = meta_backend_x11_nested_is_lid_closed; + + backend_x11_class->handle_host_xevent = meta_backend_x11_nested_handle_host_xevent; + backend_x11_class->translate_device_event = meta_backend_x11_nested_translate_device_event; + + klass->init_gpus = meta_backend_x11_nested_real_init_gpus; +} diff --git a/src/backends/x11/nested/meta-backend-x11-nested.h b/src/backends/x11/nested/meta-backend-x11-nested.h new file mode 100644 index 000000000..4f19ff54a --- /dev/null +++ b/src/backends/x11/nested/meta-backend-x11-nested.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_BACKEND_X11_NESTED_H +#define META_BACKEND_X11_NESTED_H + +#include <glib-object.h> + +#include "backends/x11/meta-backend-x11.h" +#include "core/util-private.h" + +#define META_TYPE_BACKEND_X11_NESTED (meta_backend_x11_nested_get_type ()) +META_EXPORT_TEST +G_DECLARE_DERIVABLE_TYPE (MetaBackendX11Nested, meta_backend_x11_nested, + META, BACKEND_X11_NESTED, MetaBackendX11) + +struct _MetaBackendX11NestedClass +{ + MetaBackendX11Class parent_class; + + void (* init_gpus) (MetaBackendX11Nested *backend_x11_nested); +}; + +#endif /* META_BACKEND_X11_NESTED_H */ diff --git a/src/backends/x11/nested/meta-cursor-renderer-x11-nested.c b/src/backends/x11/nested/meta-cursor-renderer-x11-nested.c new file mode 100644 index 000000000..0daae683c --- /dev/null +++ b/src/backends/x11/nested/meta-cursor-renderer-x11-nested.c @@ -0,0 +1,91 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2015 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +#include "config.h" + +#include "backends/x11/nested/meta-cursor-renderer-x11-nested.h" + +#include <X11/Xcursor/Xcursor.h> + +#include "backends/x11/meta-backend-x11.h" + +struct _MetaCursorRendererX11Nested +{ + MetaCursorRenderer parent; +}; + +G_DEFINE_TYPE (MetaCursorRendererX11Nested, meta_cursor_renderer_x11_nested, + META_TYPE_CURSOR_RENDERER); + +static gboolean +meta_cursor_renderer_x11_nested_update_cursor (MetaCursorRenderer *renderer, + MetaCursorSprite *cursor_sprite) +{ + if (cursor_sprite) + meta_cursor_sprite_realize_texture (cursor_sprite); + return FALSE; +} + +static Cursor +create_empty_cursor (Display *xdisplay) +{ + XcursorImage *image; + XcursorPixel *pixels; + Cursor xcursor; + + image = XcursorImageCreate (1, 1); + if (image == NULL) + return None; + + image->xhot = 0; + image->yhot = 0; + + pixels = image->pixels; + pixels[0] = 0; + + xcursor = XcursorImageLoadCursor (xdisplay, image); + XcursorImageDestroy (image); + + return xcursor; +} + +static void +meta_cursor_renderer_x11_nested_init (MetaCursorRendererX11Nested *x11_nested) +{ + MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ()); + Window xwindow = meta_backend_x11_get_xwindow (backend); + Display *xdisplay = meta_backend_x11_get_xdisplay (backend); + + Cursor empty_xcursor = create_empty_cursor (xdisplay); + XDefineCursor (xdisplay, xwindow, empty_xcursor); + XFreeCursor (xdisplay, empty_xcursor); +} + +static void +meta_cursor_renderer_x11_nested_class_init (MetaCursorRendererX11NestedClass *klass) +{ + MetaCursorRendererClass *renderer_class = META_CURSOR_RENDERER_CLASS (klass); + + renderer_class->update_cursor = meta_cursor_renderer_x11_nested_update_cursor; +} diff --git a/src/backends/x11/nested/meta-cursor-renderer-x11-nested.h b/src/backends/x11/nested/meta-cursor-renderer-x11-nested.h new file mode 100644 index 000000000..32f816629 --- /dev/null +++ b/src/backends/x11/nested/meta-cursor-renderer-x11-nested.h @@ -0,0 +1,38 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2015 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +#ifndef META_CURSOR_RENDERER_X11_NESTED_NESTED_H +#define META_CURSOR_RENDERER_X11_NESTED_NESTED_H + +#include <glib-object.h> + +#include "backends/meta-cursor-renderer.h" + +#define META_TYPE_CURSOR_RENDERER_X11_NESTED (meta_cursor_renderer_x11_nested_get_type ()) +G_DECLARE_FINAL_TYPE (MetaCursorRendererX11Nested, + meta_cursor_renderer_x11_nested, + META, CURSOR_RENDERER_X11_NESTED, + MetaCursorRenderer); + +#endif /* META_CURSOR_RENDERER_X11_NESTED_NESTED_H */ diff --git a/src/backends/x11/nested/meta-renderer-x11-nested.c b/src/backends/x11/nested/meta-renderer-x11-nested.c new file mode 100644 index 000000000..0223fe87e --- /dev/null +++ b/src/backends/x11/nested/meta-renderer-x11-nested.c @@ -0,0 +1,237 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#include "config.h" + +#include "backends/x11/nested/meta-renderer-x11-nested.h" + +#include <glib-object.h> + +#include "clutter/x11/clutter-x11.h" +#include "backends/meta-backend-private.h" +#include "backends/meta-logical-monitor.h" +#include "backends/meta-output.h" +#include "backends/meta-renderer.h" +#include "backends/meta-renderer-view.h" +#include "core/boxes-private.h" +#include "meta/meta-backend.h" +#include "meta/util.h" + +struct _MetaRendererX11Nested +{ + MetaRendererX11 parent; +}; + +G_DEFINE_TYPE (MetaRendererX11Nested, meta_renderer_x11_nested, + META_TYPE_RENDERER_X11) + +static MetaMonitorTransform +calculate_view_transform (MetaMonitorManager *monitor_manager, + MetaLogicalMonitor *logical_monitor) +{ + MetaMonitor *main_monitor; + MetaOutput *main_output; + MetaCrtc *crtc; + MetaMonitorTransform crtc_transform; + + main_monitor = meta_logical_monitor_get_monitors (logical_monitor)->data; + main_output = meta_monitor_get_main_output (main_monitor); + crtc = meta_output_get_assigned_crtc (main_output); + crtc_transform = + meta_monitor_logical_to_crtc_transform (main_monitor, + logical_monitor->transform); + /* + * Pick any monitor and output and check; all CRTCs of a logical monitor will + * always have the same transform assigned to them. + */ + + if (meta_monitor_manager_is_transform_handled (monitor_manager, + crtc, + crtc_transform)) + return META_MONITOR_TRANSFORM_NORMAL; + else + return crtc_transform; +} + +static MetaRendererView * +get_legacy_view (MetaRenderer *renderer) +{ + GList *views; + + views = meta_renderer_get_views (renderer); + if (views) + return META_RENDERER_VIEW (views->data); + else + return NULL; +} + +static CoglOffscreen * +create_offscreen (CoglContext *cogl_context, + int width, + int height) +{ + CoglTexture2D *texture_2d; + CoglOffscreen *offscreen; + GError *error = NULL; + + texture_2d = cogl_texture_2d_new_with_size (cogl_context, width, height); + offscreen = cogl_offscreen_new_with_texture (COGL_TEXTURE (texture_2d)); + + if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (offscreen), &error)) + meta_fatal ("Couldn't allocate framebuffer: %s", error->message); + + return offscreen; +} + +static void +meta_renderer_x11_nested_resize_legacy_view (MetaRendererX11Nested *renderer_x11_nested, + int width, + int height) +{ + MetaRenderer *renderer = META_RENDERER (renderer_x11_nested); + MetaBackend *backend = meta_get_backend (); + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend); + MetaRendererView *legacy_view; + cairo_rectangle_int_t view_layout; + CoglOffscreen *fake_onscreen; + + legacy_view = get_legacy_view (renderer); + + clutter_stage_view_get_layout (CLUTTER_STAGE_VIEW (legacy_view), + &view_layout); + if (view_layout.width == width && + view_layout.height == height) + return; + + view_layout = (cairo_rectangle_int_t) { + .width = width, + .height = height + }; + + fake_onscreen = create_offscreen (cogl_context, width, height); + + g_object_set (G_OBJECT (legacy_view), + "layout", &view_layout, + "framebuffer", COGL_FRAMEBUFFER (fake_onscreen), + NULL); +} + +void +meta_renderer_x11_nested_ensure_legacy_view (MetaRendererX11Nested *renderer_x11_nested, + int width, + int height) +{ + MetaRenderer *renderer = META_RENDERER (renderer_x11_nested); + MetaBackend *backend = meta_get_backend (); + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend); + cairo_rectangle_int_t view_layout; + CoglOffscreen *fake_onscreen; + MetaRendererView *legacy_view; + + if (get_legacy_view (renderer)) + { + meta_renderer_x11_nested_resize_legacy_view (renderer_x11_nested, + width, height); + return; + } + + fake_onscreen = create_offscreen (cogl_context, width, height); + + view_layout = (cairo_rectangle_int_t) { + .width = width, + .height = height + }; + legacy_view = g_object_new (META_TYPE_RENDERER_VIEW, + "layout", &view_layout, + "framebuffer", COGL_FRAMEBUFFER (fake_onscreen), + NULL); + + g_assert (!meta_renderer_get_views (renderer)); + meta_renderer_add_view (renderer, legacy_view); +} + +static MetaRendererView * +meta_renderer_x11_nested_create_view (MetaRenderer *renderer, + MetaLogicalMonitor *logical_monitor, + MetaOutput *output, + MetaCrtc *crtc) +{ + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend); + MetaMonitorTransform view_transform; + float view_scale; + int width, height; + CoglOffscreen *fake_onscreen; + CoglOffscreen *offscreen; + MetaRectangle view_layout; + MetaRendererView *view; + + view_transform = calculate_view_transform (monitor_manager, logical_monitor); + + if (meta_is_stage_views_scaled ()) + view_scale = logical_monitor->scale; + else + view_scale = 1.0; + + width = roundf (crtc->config->layout.size.width * view_scale); + height = roundf (crtc->config->layout.size.height * view_scale); + + fake_onscreen = create_offscreen (cogl_context, width, height); + + if (view_transform != META_MONITOR_TRANSFORM_NORMAL) + offscreen = create_offscreen (cogl_context, width, height); + else + offscreen = NULL; + + meta_rectangle_from_graphene_rect (&crtc->config->layout, + META_ROUNDING_STRATEGY_ROUND, + &view_layout); + + view = g_object_new (META_TYPE_RENDERER_VIEW, + "layout", &view_layout, + "framebuffer", COGL_FRAMEBUFFER (fake_onscreen), + "offscreen", COGL_FRAMEBUFFER (offscreen), + "transform", view_transform, + "scale", view_scale, + NULL); + g_object_set_data (G_OBJECT (view), "crtc", crtc); + + return view; +} + +static void +meta_renderer_x11_nested_init (MetaRendererX11Nested *renderer_x11_nested) +{ +} + +static void +meta_renderer_x11_nested_class_init (MetaRendererX11NestedClass *klass) +{ + MetaRendererClass *renderer_class = META_RENDERER_CLASS (klass); + + renderer_class->create_view = meta_renderer_x11_nested_create_view; +} diff --git a/src/backends/x11/nested/meta-renderer-x11-nested.h b/src/backends/x11/nested/meta-renderer-x11-nested.h new file mode 100644 index 000000000..9fc88e85b --- /dev/null +++ b/src/backends/x11/nested/meta-renderer-x11-nested.h @@ -0,0 +1,37 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#ifndef META_RENDERER_X11_NESTED_H +#define META_RENDERER_X11_NESTED_H + +#include "backends/x11/meta-renderer-x11.h" + +#define META_TYPE_RENDERER_X11_NESTED (meta_renderer_x11_nested_get_type ()) +G_DECLARE_FINAL_TYPE (MetaRendererX11Nested, meta_renderer_x11_nested, + META, RENDERER_X11_NESTED, + MetaRendererX11) + +void meta_renderer_x11_nested_ensure_legacy_view (MetaRendererX11Nested *renderer_x11_nested, + int width, + int height); + +#endif /* META_RENDERER_X11_NESTED_H */ diff --git a/src/backends/x11/nested/meta-stage-x11-nested.c b/src/backends/x11/nested/meta-stage-x11-nested.c new file mode 100644 index 000000000..361f905ed --- /dev/null +++ b/src/backends/x11/nested/meta-stage-x11-nested.c @@ -0,0 +1,229 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +#include "config.h" + +#include "backends/x11/nested/meta-stage-x11-nested.h" + +#include "backends/meta-backend-private.h" +#include "backends/meta-crtc.h" +#include "backends/meta-logical-monitor.h" +#include "backends/meta-monitor.h" +#include "backends/meta-output.h" +#include "backends/meta-renderer.h" +#include "backends/x11/nested/meta-renderer-x11-nested.h" +#include "clutter/clutter-mutter.h" + +static ClutterStageWindowInterface *clutter_stage_window_parent_iface = NULL; + +struct _MetaStageX11Nested +{ + MetaStageX11 parent; + + CoglPipeline *pipeline; +}; + +static void +clutter_stage_window_iface_init (ClutterStageWindowInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (MetaStageX11Nested, meta_stage_x11_nested, + META_TYPE_STAGE_X11, + G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_STAGE_WINDOW, + clutter_stage_window_iface_init)) + +typedef struct _MetaStageX11View +{ + CoglTexture *texture; + ClutterStageViewCogl *view; +} MetaStageX11NestedView; + +static void +meta_stage_x11_nested_resize (ClutterStageWindow *stage_window, + gint width, + gint height) +{ + if (!meta_is_stage_views_enabled ()) + { + MetaBackend *backend = meta_get_backend (); + MetaRenderer *renderer = meta_backend_get_renderer (backend); + MetaRendererX11Nested *renderer_x11_nested = + META_RENDERER_X11_NESTED (renderer); + + meta_renderer_x11_nested_ensure_legacy_view (renderer_x11_nested, + width, height); + } + + clutter_stage_window_parent_iface->resize (stage_window, width, height); +} + +static gboolean +meta_stage_x11_nested_can_clip_redraws (ClutterStageWindow *stage_window) +{ + return FALSE; +} + +static GList * +meta_stage_x11_nested_get_views (ClutterStageWindow *stage_window) +{ + MetaBackend *backend = meta_get_backend (); + MetaRenderer *renderer = meta_backend_get_renderer (backend); + + return meta_renderer_get_views (renderer); +} + +typedef struct +{ + MetaStageX11Nested *stage_nested; + CoglTexture *texture; + ClutterStageView *view; + MetaLogicalMonitor *logical_monitor; +} DrawCrtcData; + +static gboolean +draw_view (MetaStageX11Nested *stage_nested, + MetaRendererView *renderer_view, + CoglTexture *texture) +{ + MetaStageX11 *stage_x11 = META_STAGE_X11 (stage_nested); + CoglFramebuffer *onscreen = COGL_FRAMEBUFFER (stage_x11->onscreen); + ClutterStageView *stage_view = CLUTTER_STAGE_VIEW (renderer_view); + MetaCrtc *crtc; + MetaCrtcConfig *crtc_config; + CoglMatrix projection_matrix; + CoglMatrix transform; + float texture_width, texture_height; + float sample_x, sample_y, sample_width, sample_height; + float s_1, t_1, s_2, t_2; + + texture_width = cogl_texture_get_width (texture); + texture_height = cogl_texture_get_height (texture); + + crtc = g_object_get_data (G_OBJECT (renderer_view), "crtc"); + crtc_config = crtc->config; + + sample_x = 0; + sample_y = 0; + sample_width = texture_width; + sample_height = texture_height; + + clutter_stage_view_get_offscreen_transformation_matrix (stage_view, + &transform); + + cogl_framebuffer_push_matrix (onscreen); + cogl_matrix_init_identity (&projection_matrix); + cogl_matrix_translate (&projection_matrix, -1, 1, 0); + cogl_matrix_scale (&projection_matrix, 2, -2, 0); + + cogl_matrix_multiply (&projection_matrix, &projection_matrix, &transform); + cogl_framebuffer_set_projection_matrix (onscreen, &projection_matrix); + + s_1 = sample_x / texture_width; + t_1 = sample_y / texture_height; + s_2 = (sample_x + sample_width) / texture_width; + t_2 = (sample_y + sample_height) / texture_height; + + cogl_framebuffer_set_viewport (onscreen, + crtc_config->layout.origin.x, + crtc_config->layout.origin.y, + crtc_config->layout.size.width, + crtc_config->layout.size.height); + + cogl_framebuffer_draw_textured_rectangle (onscreen, + stage_nested->pipeline, + 0, 0, 1, 1, + s_1, t_1, s_2, t_2); + + cogl_framebuffer_pop_matrix (onscreen); + return TRUE; +} + +static void +meta_stage_x11_nested_finish_frame (ClutterStageWindow *stage_window) +{ + MetaStageX11Nested *stage_nested = META_STAGE_X11_NESTED (stage_window); + MetaStageX11 *stage_x11 = META_STAGE_X11 (stage_window); + MetaBackend *backend = meta_get_backend (); + MetaRenderer *renderer = meta_backend_get_renderer (backend); + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + CoglFramebuffer *onscreen = COGL_FRAMEBUFFER (stage_x11->onscreen); + GList *l; + + if (!stage_nested->pipeline) + stage_nested->pipeline = cogl_pipeline_new (clutter_backend->cogl_context); + + cogl_framebuffer_clear4f (onscreen, + COGL_BUFFER_BIT_COLOR, + 0.0f, 0.0f, 0.0f, 1.0f); + + for (l = meta_renderer_get_views (renderer); l; l = l->next) + { + ClutterStageView *view = l->data; + MetaRendererView *renderer_view = META_RENDERER_VIEW (view); + CoglFramebuffer *framebuffer; + CoglTexture *texture; + + framebuffer = clutter_stage_view_get_onscreen (view); + texture = cogl_offscreen_get_texture (COGL_OFFSCREEN (framebuffer)); + + cogl_pipeline_set_layer_texture (stage_nested->pipeline, 0, texture); + cogl_pipeline_set_layer_wrap_mode (stage_nested->pipeline, 0, + COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE); + + draw_view (stage_nested, renderer_view, texture); + } + + cogl_onscreen_swap_buffers (stage_x11->onscreen); +} + +static void +meta_stage_x11_nested_unrealize (ClutterStageWindow *stage_window) +{ + MetaStageX11Nested *stage_nested = META_STAGE_X11_NESTED (stage_window); + + g_clear_pointer (&stage_nested->pipeline, cogl_object_unref); + + clutter_stage_window_parent_iface->unrealize (stage_window); +} + +static void +meta_stage_x11_nested_init (MetaStageX11Nested *stage_x11_nested) +{ +} + +static void +meta_stage_x11_nested_class_init (MetaStageX11NestedClass *klass) +{ +} + +static void +clutter_stage_window_iface_init (ClutterStageWindowInterface *iface) +{ + clutter_stage_window_parent_iface = g_type_interface_peek_parent (iface); + + iface->resize = meta_stage_x11_nested_resize; + iface->can_clip_redraws = meta_stage_x11_nested_can_clip_redraws; + iface->unrealize = meta_stage_x11_nested_unrealize; + iface->get_views = meta_stage_x11_nested_get_views; + iface->finish_frame = meta_stage_x11_nested_finish_frame; +} diff --git a/src/backends/x11/nested/meta-stage-x11-nested.h b/src/backends/x11/nested/meta-stage-x11-nested.h new file mode 100644 index 000000000..76678465b --- /dev/null +++ b/src/backends/x11/nested/meta-stage-x11-nested.h @@ -0,0 +1,35 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +#ifndef META_STAGE_X11_NESTED_H +#define META_STAGE_X11_NESTED_H + +#include "clutter/clutter-mutter.h" +#include "backends/x11/meta-stage-x11.h" + +#define META_TYPE_STAGE_X11_NESTED (meta_stage_x11_nested_get_type ()) +G_DECLARE_FINAL_TYPE (MetaStageX11Nested, meta_stage_x11_nested, + META, STAGE_X11_NESTED, MetaStageX11) + +#endif /* META_STAGE_X11_NESTED_H */ diff --git a/src/compositor/README b/src/compositor/README new file mode 100644 index 000000000..93edf8dc9 --- /dev/null +++ b/src/compositor/README @@ -0,0 +1,70 @@ +Intro +===== + +In general, the compositor splits the window from the contents of +the window from the shape of the window. In other words, a window +has contents, and the contents of the window have a shape. This is +represented by the actor hierarchy: + + +--------------------------------------+ + | MetaWindowActor | + | +----------------------------------+ | + | | MetaSurfaceActor | | + | | +------------------------------+ | | + | | | MetaShapedTexture | | | + | | | | | | + | | | | | | + | | | | | | + | | | | | | + | | +------------------------------+ | | + | +----------------------------------+ | + +--------------------------------------+ + +Surfaces may also contain subsurfaces. The MetaWindowActor and +MetaSurfaceActor subclasses that will be created depend on the client +type, and the display server type. + +## Subsurfaces + +Additionally, there is also the case of subsurfaces: surfaces that +are child of other surfaces. That is also represented in the actor +hierarchy by having one or many MetaSurfaceActors (the subsurfaces) +added as children of a parent MetaSurfaceActor. There are no limits +to how many subsurfaces a surface may have. With subsurfaces, the +actor hierarchy looks like this: + + MetaWindowActor + ↳ MetaSurfaceActor (surface) + ↳ MetaShapedTexture + ↳ MetaSurfaceActor (subsurface) + ↳ MetaShapedTexture + ↳ MetaSurfaceActor (sub-subsurface) + ↳ MetaShapedTexture + ↳ MetaSurfaceActor (subsurface) + ↳ MetaShapedTexture + +In this example, the main surface has 2 subsurfaces. One of these +subsurfaces contains a subsurface as well. + +All MetaWindowActors contain at least one MetaSurfaceActor, and all +MetaSurfaceActors contain a MetaShapedTexture. + +## Client and compositor + +MetaWindowActor and its subclasses represent the client window's +type. A X11 client will have a MetaWindowActorX11 representing it, +and a Wayland client will have a MetaWindowActorWayland. + +On the compositor side, the surface where the contents of the window +are drawn into are represented by MetaSurfaceActor subclasses. On a +Wayland session, windows are backed by a MetaSurfaceActorWayland +surface, whereas on X11 sessions, by MetaSurfaceActorX11. + +XWayland windows are X11 client windows (MetaWindowActorX11) backed +by Wayland surfaces (MetaWindowActorWayland). + + +Env Vars +======== + +MUTTER_DISABLE_MIPMAPS - set to disable use of mipmaped windows. \ No newline at end of file diff --git a/src/compositor/clutter-utils.c b/src/compositor/clutter-utils.c index fb74732ce..f05a698f5 100644 --- a/src/compositor/clutter-utils.c +++ b/src/compositor/clutter-utils.c @@ -19,7 +19,10 @@ * along with this program; if not, see <http://www.gnu.org/licenses/>. */ -#include "clutter-utils.h" +#include "config.h" + +#include "compositor/clutter-utils.h" + #include <math.h> /* This file uses pixel-aligned region computation to determine what @@ -63,17 +66,18 @@ round_to_fixed (float x) * in @x_origin and @y_origin. */ gboolean -meta_actor_vertices_are_untransformed (ClutterVertex *verts, - float widthf, - float heightf, - int *x_origin, - int *y_origin) +meta_actor_vertices_are_untransformed (graphene_point3d_t *verts, + float widthf, + float heightf, + int *x_origin, + int *y_origin) { int width, height; int v0x, v0y, v1x, v1y, v2x, v2y, v3x, v3y; int x, y; - width = round_to_fixed (widthf); height = round_to_fixed (heightf); + width = round_to_fixed (widthf); + height = round_to_fixed (heightf); v0x = round_to_fixed (verts[0].x); v0y = round_to_fixed (verts[0].y); v1x = round_to_fixed (verts[1].x); v1y = round_to_fixed (verts[1].y); @@ -107,27 +111,12 @@ meta_actor_vertices_are_untransformed (ClutterVertex *verts, return TRUE; } -/* Check if an actor is "untransformed" - which actually means transformed by - * at most a integer-translation. The integer translation, if any, is returned. - */ -gboolean -meta_actor_is_untransformed (ClutterActor *actor, - int *x_origin, - int *y_origin) -{ - gfloat widthf, heightf; - ClutterVertex verts[4]; - - clutter_actor_get_size (actor, &widthf, &heightf); - clutter_actor_get_abs_allocation_vertices (actor, verts); - - return meta_actor_vertices_are_untransformed (verts, widthf, heightf, x_origin, y_origin); -} - /** * meta_actor_painting_untransformed: * @paint_width: the width of the painted area * @paint_height: the height of the painted area + * @sample_width: the width of the sampled area of the texture + * @sample_height: the height of the sampled area of the texture * @x_origin: if the transform is only an integer translation * then the X coordinate of the location of the origin under the transformation * from drawing space to screen pixel space is returned here. @@ -143,18 +132,21 @@ meta_actor_is_untransformed (ClutterActor *actor, * transform. */ gboolean -meta_actor_painting_untransformed (int paint_width, +meta_actor_painting_untransformed (CoglFramebuffer *fb, + int paint_width, int paint_height, + int sample_width, + int sample_height, int *x_origin, int *y_origin) { CoglMatrix modelview, projection, modelview_projection; - ClutterVertex vertices[4]; + graphene_point3d_t vertices[4]; float viewport[4]; int i; - cogl_get_modelview_matrix (&modelview); - cogl_get_projection_matrix (&projection); + cogl_framebuffer_get_modelview_matrix (fb, &modelview); + cogl_framebuffer_get_projection_matrix (fb, &projection); cogl_matrix_multiply (&modelview_projection, &projection, @@ -173,18 +165,24 @@ meta_actor_painting_untransformed (int paint_width, vertices[3].y = paint_height; vertices[3].z = 0; - cogl_get_viewport (viewport); + cogl_framebuffer_get_viewport4fv (fb, viewport); for (i = 0; i < 4; i++) { float w = 1; - cogl_matrix_transform_point (&modelview_projection, &vertices[i].x, &vertices[i].y, &vertices[i].z, &w); + cogl_matrix_transform_point (&modelview_projection, + &vertices[i].x, + &vertices[i].y, + &vertices[i].z, + &w); vertices[i].x = MTX_GL_SCALE_X (vertices[i].x, w, viewport[2], viewport[0]); vertices[i].y = MTX_GL_SCALE_Y (vertices[i].y, w, viewport[3], viewport[1]); } - return meta_actor_vertices_are_untransformed (vertices, paint_width, paint_height, x_origin, y_origin); + return meta_actor_vertices_are_untransformed (vertices, + sample_width, sample_height, + x_origin, y_origin); } diff --git a/src/compositor/clutter-utils.h b/src/compositor/clutter-utils.h index 36a5925cf..8ed0e2a4d 100644 --- a/src/compositor/clutter-utils.h +++ b/src/compositor/clutter-utils.h @@ -21,19 +21,20 @@ #ifndef __META_CLUTTER_UTILS_H__ #define __META_CLUTTER_UTILS_H__ -#include <clutter/clutter.h> -gboolean meta_actor_vertices_are_untransformed (ClutterVertex *verts, - float widthf, - float heightf, - int *x_origin, - int *y_origin); -gboolean meta_actor_is_untransformed (ClutterActor *actor, - int *x_origin, - int *y_origin); +#include "clutter/clutter.h" -gboolean meta_actor_painting_untransformed (int paint_width, - int paint_height, - int *x_origin, - int *y_origin); +gboolean meta_actor_vertices_are_untransformed (graphene_point3d_t *verts, + float widthf, + float heightf, + int *x_origin, + int *y_origin); + +gboolean meta_actor_painting_untransformed (CoglFramebuffer *fb, + int paint_width, + int paint_height, + int sample_widthf, + int sample_heightf, + int *x_origin, + int *y_origin); #endif /* __META_CLUTTER_UTILS_H__ */ diff --git a/src/compositor/cogl-utils.c b/src/compositor/cogl-utils.c index c4b2ef6b6..0a39755a5 100644 --- a/src/compositor/cogl-utils.c +++ b/src/compositor/cogl-utils.c @@ -16,83 +16,45 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ -#if HAVE_CONFIG_H -#include <config.h> -#endif -#include <clutter/clutter.h> -#include "cogl-utils.h" -#include "meta-sync-ring.h" -#include <meta/errors.h> +#include "config.h" -#include <gdk/gdk.h> +#include "clutter/clutter.h" +#include "compositor/cogl-utils.h" + +/* Based on gnome-shell/src/st/st-private.c:_st_create_texture_material.c */ /** - * meta_create_color_texture_4ub: - * @red: - * @green: - * @blue: - * @alpha: - * @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE; - * %COGL_TEXTURE_NO_SLICING is useful if the texture will be - * repeated to create a constant color fill, since hardware - * repeat can't be used for a sliced texture. + * meta_create_texture_pipeline: + * @src_texture: (nullable): texture to use initially for the layer * - * Creates a texture that is a single pixel with the specified - * unpremultiplied color components. + * Creates a pipeline with a single layer. Using a common template + * makes it easier for Cogl to share a shader for different uses in + * Mutter. * - * Return value: (transfer full): a newly created Cogl texture + * Return value: (transfer full): a newly created #CoglPipeline */ -CoglTexture * -meta_create_color_texture_4ub (guint8 red, - guint8 green, - guint8 blue, - guint8 alpha, - CoglTextureFlags flags) -{ - CoglColor color; - guint8 pixel[4]; - - cogl_color_init_from_4ub (&color, red, green, blue, alpha); - cogl_color_premultiply (&color); - - pixel[0] = cogl_color_get_red_byte (&color); - pixel[1] = cogl_color_get_green_byte (&color); - pixel[2] = cogl_color_get_blue_byte (&color); - pixel[3] = cogl_color_get_alpha_byte (&color); - - return cogl_texture_new_from_data (1, 1, - flags, - COGL_PIXEL_FORMAT_RGBA_8888_PRE, - COGL_PIXEL_FORMAT_ANY, - 4, pixel); -} - CoglPipeline * meta_create_texture_pipeline (CoglTexture *src_texture) { static CoglPipeline *texture_pipeline_template = NULL; CoglPipeline *pipeline; - /* We use a pipeline that has a dummy texture as a base for all - texture pipelines. The idea is that only the Cogl texture object - would be different in the children so it is likely that Cogl will - be able to share GL programs between all the textures. */ + /* The only state used in the pipeline that would affect the shader + generation is the texture type on the layer. Therefore we create + a template pipeline which sets this state and all texture + pipelines are created as a copy of this. That way Cogl can find + the shader state for the pipeline more quickly by looking at the + pipeline ancestry instead of resorting to the shader cache. */ if (G_UNLIKELY (texture_pipeline_template == NULL)) { - CoglTexture *dummy_texture; - - dummy_texture = meta_create_color_texture_4ub (0xff, 0xff, 0xff, 0xff, - COGL_TEXTURE_NONE); + CoglContext *ctx = + clutter_backend_get_cogl_context (clutter_get_default_backend ()); - - texture_pipeline_template = cogl_pipeline_new (meta_compositor_get_cogl_context ()); - cogl_pipeline_set_layer_texture (texture_pipeline_template, 0, dummy_texture); - cogl_object_unref (dummy_texture); + texture_pipeline_template = cogl_pipeline_new (ctx); + cogl_pipeline_set_layer_null_texture (texture_pipeline_template, 0); } pipeline = cogl_pipeline_copy (texture_pipeline_template); @@ -103,141 +65,50 @@ meta_create_texture_pipeline (CoglTexture *src_texture) return pipeline; } -/********************************************************************************************/ -/********************************* CoglTexture2d wrapper ************************************/ - -static gboolean supports_npot = FALSE; -static gboolean npot_sizes_checked = FALSE; - -static gint screen_width = 0; -static gint screen_height = 0; - -gboolean -meta_cogl_hardware_supports_npot_sizes (void) -{ - if (npot_sizes_checked) - return supports_npot; - - supports_npot = cogl_has_feature (meta_compositor_get_cogl_context (), COGL_FEATURE_ID_TEXTURE_NPOT); - npot_sizes_checked = TRUE; - - return supports_npot; -} - -inline static void -clamp_sizes (gint *width, - gint *height) -{ - if (screen_width == 0) - { - GdkScreen *screen = gdk_screen_get_default (); - - screen_width = gdk_screen_get_width (screen); - screen_height = gdk_screen_get_height (screen); - } - - *width = MIN (*width, screen_width * 2); - *height = MIN (*height, screen_height * 2); -} - /** - * meta_cogl_texture_new_from_data_wrapper: (skip) + * meta_create_texture: + * @width: width of the texture to create + * @height: height of the texture to create + * @components; components to store in the texture (color or alpha) + * @flags: flags that affect the allocation behavior + * + * Creates a texture of the given size with the specified components + * for use as a frame buffer object. * - * Decides whether to use the newer (apparently safer) - * cogl_texture_2d_new_from_data or the older cogl_texture_new_from_data - * depending on if the GPU supports it. + * If %META_TEXTURE_ALLOW_SLICING is present in @flags, and the texture + * is larger than the texture size limits of the system, then the texture + * will be created as a sliced texture. This also will cause problems + * with using the texture with GLSL, and is more likely to be an issue + * since all GL implementations have texture size limits, and they can + * be as small as 2048x2048 on reasonably current systems. */ - CoglTexture * -meta_cogl_texture_new_from_data_wrapper (int width, - int height, - CoglTextureFlags flags, - CoglPixelFormat format, - CoglPixelFormat internal_format, - int rowstride, - const uint8_t *data) -{ - CoglTexture *texture = NULL; - - clamp_sizes (&width, &height); - - if (supports_npot) - { - CoglError *error = NULL; - - texture = COGL_TEXTURE (cogl_texture_2d_new_from_data (meta_compositor_get_cogl_context (), width, height, - format, - rowstride, - data, - &error)); - if (error) - { - meta_verbose ("cogl_texture_2d_new_from_data failed: %s\n", error->message); - cogl_error_free (error); - } - } - else - { - texture = cogl_texture_new_from_data (width, - height, - flags, - format, - internal_format, - rowstride, - data); - } - - return texture; -} - -static CoglTexture * -meta_cogl_rectangle_new_compat (unsigned int width, - unsigned int height, - CoglPixelFormat format, - unsigned int rowstride, - const guint8 *data) +meta_create_texture (int width, + int height, + CoglTextureComponents components, + MetaTextureFlags flags) { ClutterBackend *backend = clutter_get_default_backend (); - CoglContext *context = clutter_backend_get_cogl_context (backend); - CoglTextureRectangle *tex_rect; - - tex_rect = cogl_texture_rectangle_new_with_size (context, width, height); - - if (tex_rect == NULL) - return NULL; - - if (data) - cogl_texture_set_region (COGL_TEXTURE (tex_rect), - 0, 0, /* src_x/y */ - 0, 0, /* dst_x/y */ - width, height, /* dst_width/height */ - width, height, /* width/height */ - format, - rowstride, - data); - - return COGL_TEXTURE (tex_rect); -} + CoglContext *ctx = clutter_backend_get_cogl_context (backend); + CoglTexture *texture; -CoglTexture * -meta_cogl_rectangle_new (int width, - int height, - CoglPixelFormat format, - int stride, - const uint8_t *data) -{ - if (!supports_npot) - return meta_cogl_rectangle_new_compat (width, height, format, stride, data); + texture = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx, width, height)); + cogl_texture_set_components (texture, components); - CoglTexture *texture = COGL_TEXTURE (cogl_texture_rectangle_new_with_size (meta_compositor_get_cogl_context (), width, height)); - cogl_texture_set_components (texture, COGL_TEXTURE_COMPONENTS_A); - cogl_texture_set_region (texture, - 0, 0, /* src_x/y */ - 0, 0, /* dst_x/y */ - width, height, /* dst_width/height */ - width, height, /* width/height */ - format, - stride, data); + if ((flags & META_TEXTURE_ALLOW_SLICING) != 0) + { + /* To find out if we need to slice the texture, we have to go ahead and force storage + * to be allocated + */ + GError *catch_error = NULL; + if (!cogl_texture_allocate (texture, &catch_error)) + { + g_error_free (catch_error); + cogl_object_unref (texture); + texture = COGL_TEXTURE (cogl_texture_2d_sliced_new_with_size (ctx, width, height, COGL_TEXTURE_MAX_WASTE)); + cogl_texture_set_components (texture, components); + } + } return texture; } diff --git a/src/compositor/cogl-utils.h b/src/compositor/cogl-utils.h index 435bb60ff..ae7e85176 100644 --- a/src/compositor/cogl-utils.h +++ b/src/compositor/cogl-utils.h @@ -15,40 +15,25 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef __META_COGL_UTILS_H__ #define __META_COGL_UTILS_H__ -#include <cogl/cogl.h> -#include <clutter/clutter.h> -#include <compositor/compositor-private.h> - -CoglTexture * meta_create_color_texture_4ub (guint8 red, - guint8 green, - guint8 blue, - guint8 alpha, - CoglTextureFlags flags); +#include "cogl/cogl.h" CoglPipeline * meta_create_texture_pipeline (CoglTexture *texture); -gboolean meta_cogl_hardware_supports_npot_sizes (void); - -CoglTexture * meta_cogl_texture_new_from_data_wrapper (int width, - int height, - CoglTextureFlags flags, - CoglPixelFormat format, - CoglPixelFormat internal_format, - int rowstride, - const uint8_t *data); +typedef enum +{ + META_TEXTURE_FLAGS_NONE = 0, + META_TEXTURE_ALLOW_SLICING = 1 << 1 +} MetaTextureFlags; -CoglTexture * meta_cogl_rectangle_new (int width, - int height, - CoglPixelFormat format, - int stride, - const uint8_t *data); +CoglTexture *meta_create_texture (int width, + int height, + CoglTextureComponents components, + MetaTextureFlags flags); #endif /* __META_COGL_UTILS_H__ */ diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h index f62013e58..081f93e2c 100644 --- a/src/compositor/compositor-private.h +++ b/src/compositor/compositor-private.h @@ -5,86 +5,102 @@ #include <X11/extensions/Xfixes.h> -#include <meta/compositor.h> -#include <meta/display.h> -#include "meta-plugin-manager.h" -#include "meta-window-actor-private.h" -#include <clutter/clutter.h> +#include "clutter/clutter.h" +#include "compositor/meta-plugin-manager.h" +#include "compositor/meta-window-actor-private.h" +#include "meta/compositor.h" +#include "meta/display.h" -struct _MetaCompositor -{ - MetaDisplay *display; - MetaScreen *screen; +/* Wait 2ms after vblank before starting to draw next frame */ +#define META_SYNC_DELAY 2 - Atom atom_x_root_pixmap; - Atom atom_x_set_root; - Atom atom_net_wm_window_opacity; - guint pre_paint_func_id; - guint post_paint_func_id; +struct _MetaCompositorClass +{ + GObjectClass parent_class; + + void (* manage) (MetaCompositor *compositor); + void (* unmanage) (MetaCompositor *compositor); + void (* pre_paint) (MetaCompositor *compositor); + void (* post_paint) (MetaCompositor *compositor); + void (* remove_window) (MetaCompositor *compositor, + MetaWindow *window); + int64_t (* monotonic_to_high_res_xserver_time) (MetaCompositor *compositor, + int64_t time_us); +}; - ClutterActor *stage, *shadow_src; - ClutterActor *bottom_window_group, *window_group, *overlay_group, *top_window_group; - ClutterActor *background_actor; - ClutterActor *hidden_group; +void meta_compositor_remove_window_actor (MetaCompositor *compositor, + MetaWindowActor *window_actor); - GList *windows; +void meta_switch_workspace_completed (MetaCompositor *compositor); - MetaWindowActor *unredirected_window; +gboolean meta_begin_modal_for_plugin (MetaCompositor *compositor, + MetaPlugin *plugin, + MetaModalOptions options, + guint32 timestamp); +void meta_end_modal_for_plugin (MetaCompositor *compositor, + MetaPlugin *plugin, + guint32 timestamp); - CoglContext *context; +MetaPluginManager * meta_compositor_get_plugin_manager (MetaCompositor *compositor); - Window output; +int64_t meta_compositor_monotonic_to_high_res_xserver_time (MetaCompositor *compositor, + int64_t monotonic_time_us); - /* Used for unredirecting fullscreen windows */ - guint disable_unredirect_count; +void meta_compositor_flash_window (MetaCompositor *compositor, + MetaWindow *window); - /* Before we create the output window */ - XserverRegion pending_input_region; +MetaCloseDialog * meta_compositor_create_close_dialog (MetaCompositor *compositor, + MetaWindow *window); - gint switch_workspace_in_progress; +MetaInhibitShortcutsDialog * meta_compositor_create_inhibit_shortcuts_dialog (MetaCompositor *compositor, + MetaWindow *window); - MetaPluginManager *plugin_mgr; +void meta_compositor_locate_pointer (MetaCompositor *compositor); - MetaPlugin *modal_plugin; +void meta_compositor_redirect_x11_windows (MetaCompositor *compositor); - gint64 server_time_query_time; - gint64 server_time_offset; +gboolean meta_compositor_is_unredirect_inhibited (MetaCompositor *compositor); - guint server_time_is_monotonic_time : 1; - guint show_redraw : 1; - guint debug : 1; - guint no_mipmaps : 1; +MetaDisplay * meta_compositor_get_display (MetaCompositor *compositor); - gboolean frame_has_updated_xsurfaces; - gboolean have_x11_sync_object; -}; +MetaWindowActor * meta_compositor_get_top_window_actor (MetaCompositor *compositor); -/* Wait 2ms after vblank before starting to draw next frame */ -#define META_SYNC_DELAY 0 +ClutterStage * meta_compositor_get_stage (MetaCompositor *compositor); -CoglContext * meta_compositor_get_cogl_context (void); +gboolean meta_compositor_is_switching_workspace (MetaCompositor *compositor); -void meta_switch_workspace_completed (MetaScreen *screen); - -gboolean meta_begin_modal_for_plugin (MetaScreen *screen, - MetaPlugin *plugin, - Window grab_window, - Cursor cursor, - MetaModalOptions options, - guint32 timestamp); -void meta_end_modal_for_plugin (MetaScreen *screen, - MetaPlugin *plugin, - guint32 timestamp); +static inline int64_t +us (int64_t us) +{ + return us; +} -gint64 meta_compositor_monotonic_time_to_server_time (MetaDisplay *display, - gint64 monotonic_time); +static inline int64_t +ms2us (int64_t ms) +{ + return us (ms * 1000); +} -void meta_compositor_grab_op_begin (MetaCompositor *compositor); -void meta_compositor_grab_op_end (MetaCompositor *compositor); +static inline int64_t +s2us (int64_t s) +{ + return ms2us(s * 1000); +} + +/* + * This function takes a 64 bit time stamp from the monotonic clock, and clamps + * it to the scope of the X server clock, without losing the granularity. + */ +static inline int64_t +meta_translate_to_high_res_xserver_time (int64_t time_us) +{ + int64_t us; + int64_t ms; -void meta_check_end_modal (MetaScreen *screen); + us = time_us % 1000; + ms = time_us / 1000; -void meta_compositor_update_sync_state (MetaCompositor *compositor, - MetaSyncMethod method); + return ms2us (ms & 0xffffffff) + us; +} #endif /* META_COMPOSITOR_PRIVATE_H */ diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index c32a1ef13..e56aed0b2 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -2,8 +2,8 @@ /** * SECTION:compositor - * @title: MetaCompositor - * @short_Description: Compositor API + * @Title: MetaCompositor + * @Short_Description: Compositor API * * At a high-level, a window is not-visible or visible. When a * window is added (with meta_compositor_add_window()) it is not visible. @@ -37,374 +37,350 @@ * compositor needs to delay hiding the windows until the switch * workspace animation completes. * - * meta_compositor_maximize_window() and meta_compositor_unmaximize_window() - * are transitions within the visible state. The window is resized __before__ - * the call, so it may be necessary to readjust the display based on the - * old_rect to start the animation. - * * # Containers # * * There's two containers in the stage that are used to place window actors, here * are listed in the order in which they are painted: * - * - window group, accessible with meta_get_window_group_for_screen() - * - top window group, accessible with meta_get_top_window_group_for_screen() + * - window group, accessible with meta_get_window_group_for_display() + * - top window group, accessible with meta_get_top_window_group_for_display() * - * Muffin will place actors representing windows in the window group, except for + * Mutter will place actors representing windows in the window group, except for * override-redirect windows (ie. popups and menus) which will be placed in the * top window group. */ +#include "config.h" + +#include "compositor/compositor-private.h" -#include <config.h> - -#include <clutter/x11/clutter-x11.h> - -#include <meta/screen.h> -#include <meta/errors.h> -#include <meta/window.h> -#include "compositor-private.h" -#include <meta/compositor-muffin.h> -#include "xprops.h" -#include <meta/prefs.h> -#include <meta/main.h> -#include <meta/meta-shadow-factory.h> -#include "meta-window-actor-private.h" -#include "meta-window-group.h" -#include "meta-background-actor-private.h" -#include "window-private.h" /* to check window->hidden */ -#include "display-private.h" /* for meta_display_lookup_x_window() */ -#include "util-private.h" -#include <X11/extensions/shape.h> #include <X11/extensions/Xcomposite.h> -#include "meta-sync-ring.h" -/* #define DEBUG_TRACE g_print */ -#define DEBUG_TRACE(X) +#include "backends/meta-dnd-private.h" +#include "backends/x11/meta-backend-x11.h" +#include "backends/x11/meta-event-x11.h" +#include "backends/x11/meta-stage-x11.h" +#include "clutter/clutter-mutter.h" +#include "cogl/cogl.h" +#include "compositor/meta-window-actor-x11.h" +#include "compositor/meta-window-actor-private.h" +#include "compositor/meta-window-group-private.h" +#include "core/display-private.h" +#include "core/frame.h" +#include "core/util-private.h" +#include "core/window-private.h" +#include "meta/compositor-mutter.h" +#include "meta/main.h" +#include "meta/meta-backend.h" +#include "meta/meta-background-actor.h" +#include "meta/meta-background-group.h" +#include "meta/meta-shadow-factory.h" +#include "meta/meta-x11-errors.h" +#include "meta/prefs.h" +#include "meta/window.h" +#include "x11/meta-x11-display-private.h" + +#ifdef HAVE_WAYLAND +#include "compositor/meta-window-actor-wayland.h" +#include "wayland/meta-wayland-private.h" +#endif + +enum +{ + PROP_0, -static MetaCompositor *compositor_global = NULL; + PROP_DISPLAY, -static void -frame_callback (ClutterStage *stage, - CoglFrameEvent event, - ClutterFrameInfo *frame_info, - MetaCompositor *compositor); + N_PROPS +}; + +static GParamSpec *obj_props[N_PROPS] = { NULL, }; -static inline gboolean -composite_at_least_version (MetaDisplay *display, int maj, int min) +typedef struct _MetaCompositorPrivate { - static int major = -1; - static int minor = -1; + GObject parent; - if (major == -1) - meta_display_get_compositor_version (display, &major, &minor); + MetaDisplay *display; - return (major > maj || (major == maj && minor >= min)); -} + guint pre_paint_func_id; + guint post_paint_func_id; -static void sync_actor_stacking (MetaCompositor *compositor); + gulong stage_presented_id; + gulong stage_after_paint_id; -static void -meta_finish_workspace_switch (MetaCompositor *compositor) -{ - GList *l; + ClutterActor *stage; - /* Finish hiding and showing actors for the new workspace */ - for (l = compositor->windows; l; l = l->next) - meta_window_actor_sync_visibility (l->data); + ClutterActor *window_group; + ClutterActor *top_window_group; + ClutterActor *feedback_group; - /* - * Fix up stacking order in case the plugin messed it up. - */ - sync_actor_stacking (compositor); + GList *windows; -/* printf ("... FINISHED DESKTOP SWITCH\n"); */ + CoglContext *context; -} + MetaWindowActor *top_window_actor; + gulong top_window_actor_destroy_id; -LOCAL_SYMBOL void -meta_switch_workspace_completed (MetaScreen *screen) -{ - MetaCompositor *compositor = screen->display->compositor; + int disable_unredirect_count; - /* FIXME -- must redo stacking order */ - compositor->switch_workspace_in_progress--; - if (compositor->switch_workspace_in_progress < 0) - { - g_warning ("Error in workspace_switch accounting!"); - compositor->switch_workspace_in_progress = 0; - } + int switch_workspace_in_progress; - if (!compositor->switch_workspace_in_progress) - meta_finish_workspace_switch (compositor); -} + MetaPluginManager *plugin_mgr; +} MetaCompositorPrivate; -void -meta_compositor_destroy (MetaCompositor *compositor) -{ - clutter_threads_remove_repaint_func (compositor->pre_paint_func_id); - clutter_threads_remove_repaint_func (compositor->post_paint_func_id); +G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaCompositor, meta_compositor, + G_TYPE_OBJECT) - if (compositor->have_x11_sync_object) - meta_sync_ring_destroy (); -} +static void +on_presented (ClutterStage *stage, + CoglFrameEvent event, + ClutterFrameInfo *frame_info, + MetaCompositor *compositor); static void -add_win (MetaWindow *window) -{ - meta_window_actor_new (window); +on_top_window_actor_destroyed (MetaWindowActor *window_actor, + MetaCompositor *compositor); - sync_actor_stacking (window->screen->display->compositor); +static gboolean +is_modal (MetaDisplay *display) +{ + return display->event_route == META_EVENT_ROUTE_COMPOSITOR_GRAB; } +static void sync_actor_stacking (MetaCompositor *compositor); + static void -process_damage (MetaCompositor *compositor, - XDamageNotifyEvent *event, - MetaWindow *window) +meta_finish_workspace_switch (MetaCompositor *compositor) { - MetaWindowActor *window_actor; - - if (window == NULL) - return; - - window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - if (window_actor == NULL) - return; + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); + GList *l; - meta_window_actor_process_damage (window_actor, event); + /* Finish hiding and showing actors for the new workspace */ + for (l = priv->windows; l; l = l->next) + meta_window_actor_sync_visibility (l->data); - compositor->frame_has_updated_xsurfaces = TRUE; + /* Fix up stacking order. */ + sync_actor_stacking (compositor); } -static void -process_property_notify (MetaCompositor *compositor, - XPropertyEvent *event, - MetaWindow *window) +void +meta_switch_workspace_completed (MetaCompositor *compositor) { - MetaWindowActor *window_actor; - - if (event->atom == compositor->atom_x_root_pixmap) - { - GSList *l; - - for (l = meta_display_get_screens (compositor->display); l; l = l->next) - { - MetaScreen *screen = l->data; - if (event->window == meta_screen_get_xroot (screen)) - { - meta_background_actor_update (screen); - return; - } - } - } - - if (window == NULL) - return; + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); - window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - if (window_actor == NULL) - return; - - /* Check for the opacity changing */ - if (event->atom == compositor->atom_net_wm_window_opacity) + /* FIXME -- must redo stacking order */ + priv->switch_workspace_in_progress--; + if (priv->switch_workspace_in_progress < 0) { - meta_window_actor_update_opacity (window_actor); - DEBUG_TRACE ("process_property_notify: net_wm_window_opacity\n"); - return; + g_warning ("Error in workspace_switch accounting!"); + priv->switch_workspace_in_progress = 0; } - DEBUG_TRACE ("process_property_notify: unknown\n"); + if (!priv->switch_workspace_in_progress) + meta_finish_workspace_switch (compositor); } -static Window -get_output_window (MetaScreen *screen) +void +meta_compositor_destroy (MetaCompositor *compositor) { - MetaDisplay *display = meta_screen_get_display (screen); - Display *xdisplay = meta_display_get_xdisplay (display); - Window output, xroot; - XWindowAttributes attr; - long event_mask; - - xroot = meta_screen_get_xroot (screen); - - event_mask = FocusChangeMask | - ExposureMask | - EnterWindowMask | LeaveWindowMask | - PointerMotionMask | - PropertyChangeMask | - ButtonPressMask | ButtonReleaseMask | - KeyPressMask | KeyReleaseMask; - - output = screen->composite_overlay_window; - - if (XGetWindowAttributes (xdisplay, output, &attr)) - { - event_mask |= attr.your_event_mask; - } - - XSelectInput (xdisplay, output, event_mask); - - return output; + g_object_run_dispose (G_OBJECT (compositor)); + g_object_unref (compositor); } -/** - * meta_get_stage_for_screen: - * @screen: a #MetaScreen - * - * Returns: (transfer none): The #ClutterStage for the screen - */ -ClutterActor * -meta_get_stage_for_screen (MetaScreen *screen) +/* compat helper */ +static MetaCompositor * +get_compositor_for_display (MetaDisplay *display) { - return screen->display->compositor->stage; + return display->compositor; } /** - * meta_get_overlay_group_for_screen: - * @screen: a #MetaScreen + * meta_get_stage_for_display: + * @display: a #MetaDisplay * - * Returns: (transfer none): The overlay group corresponding to @screen + * Returns: (transfer none): The #ClutterStage for the display */ ClutterActor * -meta_get_overlay_group_for_screen (MetaScreen *screen) +meta_get_stage_for_display (MetaDisplay *display) { - return screen->display->compositor->overlay_group; -} + MetaCompositor *compositor; + MetaCompositorPrivate *priv; -/** - * meta_get_window_group_for_screen: - * @screen: a #MetaScreen - * - * Returns: (transfer none): The window group corresponding to @screen - */ -ClutterActor * -meta_get_window_group_for_screen (MetaScreen *screen) -{ - return screen->display->compositor->window_group; + g_return_val_if_fail (display, NULL); + + compositor = get_compositor_for_display (display); + g_return_val_if_fail (compositor, NULL); + priv = meta_compositor_get_instance_private (compositor); + + return priv->stage; } /** - * meta_get_bottom_window_group_for_screen: - * @screen: a #MetaScreen + * meta_get_window_group_for_display: + * @display: a #MetaDisplay * - * Returns: (transfer none): The bottom window group corresponding to @screen + * Returns: (transfer none): The window group corresponding to @display */ ClutterActor * -meta_get_bottom_window_group_for_screen (MetaScreen *screen) +meta_get_window_group_for_display (MetaDisplay *display) { - return screen->display->compositor->bottom_window_group; + MetaCompositor *compositor; + MetaCompositorPrivate *priv; + + g_return_val_if_fail (display, NULL); + + compositor = get_compositor_for_display (display); + g_return_val_if_fail (compositor, NULL); + priv = meta_compositor_get_instance_private (compositor); + + return priv->window_group; } /** - * meta_get_top_window_group_for_screen: - * @screen: a #MetaScreen + * meta_get_top_window_group_for_display: + * @display: a #MetaDisplay * - * Returns: (transfer none): The top window group corresponding to @screen + * Returns: (transfer none): The top window group corresponding to @display */ ClutterActor * -meta_get_top_window_group_for_screen (MetaScreen *screen) +meta_get_top_window_group_for_display (MetaDisplay *display) { - return screen->display->compositor->top_window_group; + MetaCompositor *compositor; + MetaCompositorPrivate *priv; + + g_return_val_if_fail (display, NULL); + + compositor = get_compositor_for_display (display); + g_return_val_if_fail (compositor, NULL); + priv = meta_compositor_get_instance_private (compositor); + + return priv->top_window_group; } /** - * meta_get_background_actor_for_screen: - * @screen: a #MetaScreen - * - * Gets the actor that draws the root window background under the windows. - * The root window background automatically tracks the image or color set - * by the environment. + * meta_get_feedback_group_for_display: + * @display: a #MetaDisplay * - * Returns: (transfer none): The background actor corresponding to @screen + * Returns: (transfer none): The feedback group corresponding to @display */ ClutterActor * -meta_get_background_actor_for_screen (MetaScreen *screen) +meta_get_feedback_group_for_display (MetaDisplay *display) { - return screen->display->compositor->background_actor; + MetaCompositor *compositor; + MetaCompositorPrivate *priv; + + g_return_val_if_fail (display, NULL); + + compositor = get_compositor_for_display (display); + g_return_val_if_fail (compositor, NULL); + priv = meta_compositor_get_instance_private (compositor); + + return priv->feedback_group; } /** * meta_get_window_actors: - * @screen: a #MetaScreen + * @display: a #MetaDisplay * - * Returns: (transfer none) (element-type Clutter.Actor): The set of #MetaWindowActor on @screen + * Returns: (transfer none) (element-type Clutter.Actor): The set of #MetaWindowActor on @display */ GList * -meta_get_window_actors (MetaScreen *screen) +meta_get_window_actors (MetaDisplay *display) { - return screen->display->compositor->windows; + MetaCompositor *compositor; + MetaCompositorPrivate *priv; + + g_return_val_if_fail (display, NULL); + + compositor = get_compositor_for_display (display); + g_return_val_if_fail (compositor, NULL); + priv = meta_compositor_get_instance_private (compositor); + + return priv->windows; } -static void -do_set_stage_input_region (MetaScreen *screen, - XserverRegion region) +void +meta_focus_stage_window (MetaDisplay *display, + guint32 timestamp) { - MetaDisplay *display = screen->display; - MetaCompositor *compositor = display->compositor; - Display *xdpy = display->xdisplay; - Window xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (compositor->stage)); + ClutterStage *stage; + Window window; - XFixesSetWindowShapeRegion (xdpy, xstage, ShapeInput, 0, 0, region); + stage = CLUTTER_STAGE (meta_get_stage_for_display (display)); + if (!stage) + return; - /* It's generally a good heuristic that when a crossing event is generated because - * we reshape the overlay, we don't want it to affect focus-follows-mouse focus - - * it's not the user doing something, it's the environment changing under the user. - */ - meta_display_add_ignored_crossing_serial (display, XNextRequest (xdpy)); - XFixesSetWindowShapeRegion (xdpy, compositor->output, ShapeInput, 0, 0, region); + window = meta_x11_get_stage_window (stage); + + if (window == None) + return; + + meta_x11_display_set_input_focus_xwindow (display->x11_display, + window, + timestamp); } -void -meta_set_stage_input_region (MetaScreen *screen, - XserverRegion region) +gboolean +meta_stage_is_focused (MetaDisplay *display) { - MetaDisplay *display = screen->display; - MetaCompositor *compositor = display->compositor; - Display *xdpy = display->xdisplay; + ClutterStage *stage; + Window window; - if (compositor->stage && compositor->output) - { - do_set_stage_input_region (screen, region); - } - else - { - /* Reset compositor->pending_input_region if one existed before and set the new - * one to use it later. */ - if (compositor->pending_input_region) - { - XFixesDestroyRegion (xdpy, compositor->pending_input_region); - compositor->pending_input_region = None; - } - if (region != None) - { - compositor->pending_input_region = XFixesCreateRegion (xdpy, NULL, 0); - XFixesCopyRegion (xdpy, compositor->pending_input_region, region); - } - } + if (meta_is_wayland_compositor ()) + return TRUE; + + stage = CLUTTER_STAGE (meta_get_stage_for_display (display)); + if (!stage) + return FALSE; + + window = meta_x11_get_stage_window (stage); + + if (window == None) + return FALSE; + + return (display->x11_display->focus_xwindow == window); } -void -meta_empty_stage_input_region (MetaScreen *screen) +static gboolean +grab_devices (MetaModalOptions options, + guint32 timestamp) { - /* Using a static region here is a bit hacky, but Metacity never opens more than - * one XDisplay, so it works fine. */ - static XserverRegion region = None; + MetaBackend *backend = META_BACKEND (meta_get_backend ()); + gboolean pointer_grabbed = FALSE; + gboolean keyboard_grabbed = FALSE; - if (region == None) + if ((options & META_MODAL_POINTER_ALREADY_GRABBED) == 0) + { + if (!meta_backend_grab_device (backend, META_VIRTUAL_CORE_POINTER_ID, timestamp)) + goto fail; + + pointer_grabbed = TRUE; + } + + if ((options & META_MODAL_KEYBOARD_ALREADY_GRABBED) == 0) { - MetaDisplay *display = meta_screen_get_display (screen); - Display *xdpy = meta_display_get_xdisplay (display); - region = XFixesCreateRegion (xdpy, NULL, 0); + if (!meta_backend_grab_device (backend, META_VIRTUAL_CORE_KEYBOARD_ID, timestamp)) + goto fail; + + keyboard_grabbed = TRUE; } - meta_set_stage_input_region (screen, region); + return TRUE; + + fail: + if (pointer_grabbed) + meta_backend_ungrab_device (backend, META_VIRTUAL_CORE_POINTER_ID, timestamp); + if (keyboard_grabbed) + meta_backend_ungrab_device (backend, META_VIRTUAL_CORE_KEYBOARD_ID, timestamp); + + return FALSE; } -LOCAL_SYMBOL gboolean -meta_begin_modal_for_plugin (MetaScreen *screen, +gboolean +meta_begin_modal_for_plugin (MetaCompositor *compositor, MetaPlugin *plugin, - Window grab_window, - Cursor cursor, MetaModalOptions options, guint32 timestamp) { @@ -412,122 +388,113 @@ meta_begin_modal_for_plugin (MetaScreen *screen, * are significant differences in how we handle grabs that make it difficult to * merge the two. */ + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); + MetaDisplay *display = priv->display; - MetaDisplay *display = meta_screen_get_display (screen); - Display *xdpy = meta_display_get_xdisplay (display); - MetaCompositor *compositor = display->compositor; - gboolean pointer_grabbed = FALSE; - int result; +#ifdef HAVE_WAYLAND + if (display->grab_op == META_GRAB_OP_WAYLAND_POPUP) + { + MetaWaylandSeat *seat = meta_wayland_compositor_get_default ()->seat; + meta_wayland_pointer_end_popup_grab (seat->pointer); + } +#endif - if (compositor->modal_plugin != NULL || display->grab_op != META_GRAB_OP_NONE) + if (is_modal (display) || display->grab_op != META_GRAB_OP_NONE) return FALSE; - if ((options & META_MODAL_POINTER_ALREADY_GRABBED) == 0) + if (display->x11_display) { - result = XGrabPointer (xdpy, grab_window, - False, /* owner_events */ - (ButtonPressMask | ButtonReleaseMask | - EnterWindowMask | LeaveWindowMask | PointerMotionMask), - GrabModeAsync, GrabModeAsync, - None, /* confine to */ - cursor, - timestamp); - if (result != Success) - goto fail; - - pointer_grabbed = TRUE; + /* XXX: why is this needed? */ + XIUngrabDevice (display->x11_display->xdisplay, + META_VIRTUAL_CORE_POINTER_ID, + timestamp); + XSync (display->x11_display->xdisplay, False); } - if ((options & META_MODAL_KEYBOARD_ALREADY_GRABBED) == 0) - { - result = XGrabKeyboard (xdpy, grab_window, - False, /* owner_events */ - GrabModeAsync, GrabModeAsync, - timestamp); - - if (result != Success) - goto fail; - } + if (!grab_devices (options, timestamp)) + return FALSE; display->grab_op = META_GRAB_OP_COMPOSITOR; + display->event_route = META_EVENT_ROUTE_COMPOSITOR_GRAB; display->grab_window = NULL; - display->grab_screen = screen; display->grab_have_pointer = TRUE; display->grab_have_keyboard = TRUE; - compositor->modal_plugin = plugin; + g_signal_emit_by_name (display, "grab-op-begin", + meta_plugin_get_display (plugin), + display->grab_window, display->grab_op); - return TRUE; + if (meta_is_wayland_compositor ()) + { + meta_display_sync_wayland_input_focus (display); + meta_display_cancel_touch (display); - fail: - if (pointer_grabbed) - XUngrabPointer (xdpy, timestamp); +#ifdef HAVE_WAYLAND + meta_dnd_wayland_handle_begin_modal (compositor); +#endif + } - return FALSE; + return TRUE; } -LOCAL_SYMBOL void -meta_end_modal_for_plugin (MetaScreen *screen, +void +meta_end_modal_for_plugin (MetaCompositor *compositor, MetaPlugin *plugin, guint32 timestamp) { - MetaDisplay *display = meta_screen_get_display (screen); - Display *xdpy = meta_display_get_xdisplay (display); - MetaCompositor *compositor = display->compositor; - - g_return_if_fail (compositor->modal_plugin == plugin); + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); + MetaDisplay *display = priv->display; + MetaBackend *backend = meta_get_backend (); + MetaWindow *grab_window = display->grab_window; + MetaGrabOp grab_op = display->grab_op; - XUngrabPointer (xdpy, timestamp); - XUngrabKeyboard (xdpy, timestamp); + g_return_if_fail (is_modal (display)); display->grab_op = META_GRAB_OP_NONE; + display->event_route = META_EVENT_ROUTE_NORMAL; display->grab_window = NULL; - display->grab_screen = NULL; display->grab_have_pointer = FALSE; display->grab_have_keyboard = FALSE; - compositor->modal_plugin = NULL; -} - -/* This is used when reloading plugins to make sure we don't have - * a left-over modal grab for this screen. - */ -LOCAL_SYMBOL void -meta_check_end_modal (MetaScreen *screen) -{ - MetaDisplay *display = meta_screen_get_display (screen); - MetaCompositor *compositor = display->compositor; + meta_backend_ungrab_device (backend, META_VIRTUAL_CORE_POINTER_ID, timestamp); + meta_backend_ungrab_device (backend, META_VIRTUAL_CORE_KEYBOARD_ID, timestamp); - if (compositor->modal_plugin && - meta_plugin_get_screen (compositor->modal_plugin) == screen) +#ifdef HAVE_WAYLAND + if (meta_is_wayland_compositor ()) { - meta_end_modal_for_plugin (screen, - compositor->modal_plugin, - CurrentTime); + meta_dnd_wayland_handle_end_modal (compositor); + meta_display_sync_wayland_input_focus (display); } +#endif + + g_signal_emit_by_name (display, "grab-op-end", + meta_plugin_get_display (plugin), + grab_window, grab_op); } static void after_stage_paint (ClutterStage *stage, gpointer data) { - MetaCompositor *compositor = (MetaCompositor*) data; + MetaCompositor *compositor = data; + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); GList *l; - for (l = compositor->windows; l; l = l->next) + for (l = priv->windows; l; l = l->next) meta_window_actor_post_paint (l->data); } static void -redirect_windows (MetaCompositor *compositor, - MetaScreen *screen) +redirect_windows (MetaX11Display *x11_display) { - MetaDisplay *display = meta_screen_get_display (screen); - Display *xdisplay = meta_display_get_xdisplay (display); - Window xroot = meta_screen_get_xroot (screen); - int screen_number = meta_screen_get_screen_number (screen); - guint n_retries; - guint max_retries; + Display *xdisplay = meta_x11_display_get_xdisplay (x11_display); + Window xroot = meta_x11_display_get_xroot (x11_display); + int screen_number = meta_x11_display_get_screen_number (x11_display); + guint n_retries; + guint max_retries; if (meta_get_replace_current_wm ()) max_retries = 5; @@ -536,25 +503,25 @@ redirect_windows (MetaCompositor *compositor, n_retries = 0; - /* Some compositors (like old versions of Muffin) might not properly unredirect + /* Some compositors (like old versions of Mutter) might not properly unredirect * subwindows before destroying the WM selection window; so we wait a while * for such a compositor to exit before giving up. */ while (TRUE) { - meta_error_trap_push_with_return (display); + meta_x11_error_trap_push (x11_display); XCompositeRedirectSubwindows (xdisplay, xroot, CompositeRedirectManual); XSync (xdisplay, FALSE); - if (!meta_error_trap_pop_with_return (display)) + if (!meta_x11_error_trap_pop_with_return (x11_display)) break; if (n_retries == max_retries) { /* This probably means that a non-WM compositor like xcompmgr is running; * we have no way to get it to exit */ - meta_fatal ("Another compositing manager is already running on screen %i on display \"%s\".", - screen_number, display->name); + meta_fatal (_("Another compositing manager is already running on screen %i on display “%s”."), + screen_number, x11_display->name); } n_retries++; @@ -562,244 +529,143 @@ redirect_windows (MetaCompositor *compositor, } } -LOCAL_SYMBOL void -meta_compositor_toggle_send_frame_timings (MetaScreen *screen) +void +meta_compositor_redirect_x11_windows (MetaCompositor *compositor) { - MetaCompositor *compositor = screen->display->compositor; - if (meta_prefs_get_send_frame_timings()) - { - g_signal_connect_after (CLUTTER_STAGE (compositor->stage), "presented", - G_CALLBACK (frame_callback), compositor); - } - else - { - g_signal_handlers_disconnect_by_func (CLUTTER_STAGE (compositor->stage), - frame_callback, NULL); - } + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); + MetaDisplay *display = priv->display; + + if (display->x11_display) + redirect_windows (display->x11_display); } void -meta_compositor_manage_screen (MetaCompositor *compositor, - MetaScreen *screen) -{ - MetaDisplay *display = meta_screen_get_display (screen); - Display *xdisplay = meta_display_get_xdisplay (display); - Window xwin; - gint width, height; - XWindowAttributes attr; - long event_mask; - - redirect_windows (compositor, screen); - - /* - * We use an empty input region for Clutter as a default because that allows - * the user to interact with all the windows displayed on the screen. - * We have to initialize compositor->pending_input_region to an empty region explicitly, - * because None value is used to mean that the whole screen is an input region. +meta_compositor_manage (MetaCompositor *compositor) +{ + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); + MetaDisplay *display = priv->display; + MetaBackend *backend = meta_get_backend (); + + priv->stage = meta_backend_get_stage (backend); + + priv->stage_presented_id = + g_signal_connect (priv->stage, "presented", + G_CALLBACK (on_presented), + compositor); + + /* We use connect_after() here to accomodate code in GNOME Shell that, + * when benchmarking drawing performance, connects to ::after-paint + * and calls glFinish(). The timing information from that will be + * more accurate if we hold off until that completes before we signal + * apps to begin drawing the next frame. If there are no other + * connections to ::after-paint, connect() vs. connect_after() doesn't + * matter. */ - compositor->pending_input_region = XFixesCreateRegion (xdisplay, NULL, 0); - - compositor->screen = screen; - compositor->output = None; - compositor->windows = NULL; - - meta_screen_set_cm_selection (screen); - - compositor->stage = clutter_stage_new (); - - meta_compositor_toggle_send_frame_timings(screen); - - g_signal_connect_after (CLUTTER_STAGE (compositor->stage), "after-paint", - G_CALLBACK (after_stage_paint), compositor); - - clutter_stage_set_sync_delay (CLUTTER_STAGE (compositor->stage), META_SYNC_DELAY); - - meta_screen_get_size (screen, &width, &height); - clutter_actor_realize (compositor->stage); + priv->stage_after_paint_id = + g_signal_connect_after (priv->stage, "after-paint", + G_CALLBACK (after_stage_paint), compositor); - xwin = clutter_x11_get_stage_window (CLUTTER_STAGE (compositor->stage)); + clutter_stage_set_sync_delay (CLUTTER_STAGE (priv->stage), META_SYNC_DELAY); - XResizeWindow (xdisplay, xwin, width, height); + priv->window_group = meta_window_group_new (display); + priv->top_window_group = meta_window_group_new (display); + priv->feedback_group = meta_window_group_new (display); - event_mask = FocusChangeMask | - ExposureMask | - EnterWindowMask | LeaveWindowMask | - PointerMotionMask | - PropertyChangeMask | - ButtonPressMask | ButtonReleaseMask | - KeyPressMask | KeyReleaseMask | - StructureNotifyMask; + clutter_actor_add_child (priv->stage, priv->window_group); + clutter_actor_add_child (priv->stage, priv->top_window_group); + clutter_actor_add_child (priv->stage, priv->feedback_group); - if (XGetWindowAttributes (xdisplay, xwin, &attr)) - { - event_mask |= attr.your_event_mask; - } + META_COMPOSITOR_GET_CLASS (compositor)->manage (compositor); - XSelectInput (xdisplay, xwin, event_mask); - - compositor->window_group = meta_window_group_new (screen); - compositor->background_actor = meta_background_actor_new_for_screen (screen); - compositor->bottom_window_group = clutter_actor_new(); - compositor->overlay_group = clutter_actor_new (); - compositor->top_window_group = meta_window_group_new (screen); - compositor->hidden_group = clutter_actor_new (); - - clutter_actor_add_child (compositor->window_group, compositor->background_actor); - clutter_actor_add_child (compositor->stage, compositor->window_group); - clutter_actor_add_child (compositor->stage, compositor->top_window_group); - clutter_actor_add_child (compositor->stage, compositor->overlay_group); - clutter_actor_add_child (compositor->stage, compositor->hidden_group); - - clutter_actor_hide (compositor->hidden_group); - - compositor->plugin_mgr = meta_plugin_manager_new (screen); - - /* - * Delay the creation of the overlay window as long as we can, to avoid - * blanking out the screen. This means that during the plugin loading, the - * overlay window is not accessible; if the plugin needs to access it - * directly, it should hook into the "show" signal on stage, and do - * its stuff there. - */ - compositor->output = get_output_window (screen); - XReparentWindow (xdisplay, xwin, compositor->output, 0, 0); - - /* Make sure there isn't any left-over output shape on the - * overlay window by setting the whole screen to be an - * output region. - * - * Note: there doesn't seem to be any real chance of that - * because the X server will destroy the overlay window - * when the last client using it exits. - */ - XFixesSetWindowShapeRegion (xdisplay, compositor->output, ShapeBounding, 0, 0, None); - - do_set_stage_input_region (screen, compositor->pending_input_region); - if (compositor->pending_input_region != None) - { - XFixesDestroyRegion (xdisplay, compositor->pending_input_region); - compositor->pending_input_region = None; - } - - clutter_actor_show (compositor->overlay_group); - clutter_actor_show (compositor->stage); - - /* Map overlay window before redirecting windows offscreen so we catch their - * contents until we show the stage. - */ - XMapWindow (xdisplay, compositor->output); - - compositor->have_x11_sync_object = meta_sync_ring_init (xdisplay); + priv->plugin_mgr = meta_plugin_manager_new (compositor); } void -meta_compositor_unmanage_screen (MetaCompositor *compositor, - MetaScreen *screen) +meta_compositor_unmanage (MetaCompositor *compositor) { - MetaDisplay *display = meta_screen_get_display (screen); - Display *xdisplay = meta_display_get_xdisplay (display); - Window xroot = meta_screen_get_xroot (screen); - - /* This is the most important part of cleanup - we have to do this - * before giving up the window manager selection or the next - * window manager won't be able to redirect subwindows */ - XCompositeUnredirectSubwindows (xdisplay, xroot, CompositeRedirectManual); + META_COMPOSITOR_GET_CLASS (compositor)->unmanage (compositor); } -/* - * Shapes the cow so that the given window is exposed, - * when metaWindow is NULL it clears the shape again - */ -static void -meta_shape_cow_for_window (MetaScreen *screen, - MetaWindow *metaWindow) +void +meta_compositor_add_window (MetaCompositor *compositor, + MetaWindow *window) { - MetaDisplay *display = screen->display; - MetaCompositor *compositor = display->compositor; - Display *xdisplay = display->xdisplay; + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); + MetaWindowActor *window_actor; + ClutterActor *window_group; + GType window_actor_type = G_TYPE_INVALID; - if (metaWindow == NULL) - XFixesSetWindowShapeRegion (xdisplay, compositor->output, ShapeBounding, 0, 0, None); - else + switch (window->client_type) { - XserverRegion output_region; - XRectangle screen_rect, window_bounds; - int width, height; - MetaRectangle rect; + case META_WINDOW_CLIENT_TYPE_X11: + window_actor_type = META_TYPE_WINDOW_ACTOR_X11; + break; - meta_window_get_outer_rect (metaWindow, &rect); +#ifdef HAVE_WAYLAND + case META_WINDOW_CLIENT_TYPE_WAYLAND: + window_actor_type = META_TYPE_WINDOW_ACTOR_WAYLAND; + break; +#endif - window_bounds.x = rect.x; - window_bounds.y = rect.y; - window_bounds.width = rect.width; - window_bounds.height = rect.height; + default: + g_return_if_reached (); + } - meta_screen_get_size (screen, &width, &height); - screen_rect.x = 0; - screen_rect.y = 0; - screen_rect.width = width; - screen_rect.height = height; + window_actor = g_object_new (window_actor_type, + "meta-window", window, + "show-on-set-parent", FALSE, + NULL); - output_region = XFixesCreateRegion (xdisplay, &window_bounds, 1); + if (window->layer == META_LAYER_OVERRIDE_REDIRECT) + window_group = priv->top_window_group; + else + window_group = priv->window_group; - XFixesInvertRegion (xdisplay, output_region, &screen_rect, output_region); - XFixesSetWindowShapeRegion (xdisplay, compositor->output, ShapeBounding, 0, 0, output_region); - XFixesDestroyRegion (xdisplay, output_region); - } + clutter_actor_add_child (window_group, CLUTTER_ACTOR (window_actor)); + + /* Initial position in the stack is arbitrary; stacking will be synced + * before we first paint. + */ + priv->windows = g_list_append (priv->windows, window_actor); + sync_actor_stacking (compositor); } -void -meta_compositor_add_window (MetaCompositor *compositor, - MetaWindow *window) +static void +meta_compositor_real_remove_window (MetaCompositor *compositor, + MetaWindow *window) { - MetaScreen *screen = meta_window_get_screen (window); - MetaDisplay *display = meta_screen_get_display (screen); + MetaWindowActor *window_actor = meta_window_actor_from_window (window); - DEBUG_TRACE ("meta_compositor_add_window\n"); - meta_error_trap_push (display); - - add_win (window); - - meta_error_trap_pop (display); + meta_window_actor_queue_destroy (window_actor); } void meta_compositor_remove_window (MetaCompositor *compositor, MetaWindow *window) { - MetaWindowActor *window_actor = NULL; - MetaScreen *screen; - - DEBUG_TRACE ("meta_compositor_remove_window\n"); - window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - if (!window_actor) - return; - - screen = window->screen; + META_COMPOSITOR_GET_CLASS (compositor)->remove_window (compositor, window); +} - if (window_actor == compositor->unredirected_window) - { - meta_window_actor_set_redirected (window_actor, TRUE); - meta_shape_cow_for_window (screen, NULL); - compositor->unredirected_window = NULL; - } +void +meta_compositor_remove_window_actor (MetaCompositor *compositor, + MetaWindowActor *window_actor) +{ + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); - meta_window_actor_destroy (window_actor); + priv->windows = g_list_remove (priv->windows, window_actor); } void -meta_compositor_set_updates_frozen (MetaCompositor *compositor, - MetaWindow *window, - gboolean updates_frozen) +meta_compositor_sync_updates_frozen (MetaCompositor *compositor, + MetaWindow *window) { - MetaWindowActor *window_actor; - - DEBUG_TRACE ("meta_compositor_set_updates_frozen\n"); - window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - if (!window_actor) - return; + MetaWindowActor *window_actor = meta_window_actor_from_window (window); - meta_window_actor_set_updates_frozen (window_actor, updates_frozen); + meta_window_actor_sync_updates_frozen (window_actor); } void @@ -807,123 +673,53 @@ meta_compositor_queue_frame_drawn (MetaCompositor *compositor, MetaWindow *window, gboolean no_delay_frame) { - MetaWindowActor *window_actor; - - DEBUG_TRACE ("meta_compositor_queue_frame_drawn\n"); - window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - if (!window_actor) - return; + MetaWindowActor *window_actor = meta_window_actor_from_window (window); meta_window_actor_queue_frame_drawn (window_actor, no_delay_frame); } -static gboolean -is_grabbed_event (XEvent *event) -{ - switch (event->xany.type) - { - case ButtonPress: - case ButtonRelease: - case EnterNotify: - case LeaveNotify: - case MotionNotify: - case KeyPress: - case KeyRelease: - return TRUE; - } - - return FALSE; -} - void meta_compositor_window_shape_changed (MetaCompositor *compositor, MetaWindow *window) { MetaWindowActor *window_actor; - window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); + + window_actor = meta_window_actor_from_window (window); if (!window_actor) return; - meta_window_actor_update_shape (window_actor); + meta_window_actor_x11_update_shape (META_WINDOW_ACTOR_X11 (window_actor)); } -/** - * meta_compositor_process_event: (skip) - * - */ -gboolean -meta_compositor_process_event (MetaCompositor *compositor, - XEvent *event, - MetaWindow *window) +void +meta_compositor_window_opacity_changed (MetaCompositor *compositor, + MetaWindow *window) { - if (compositor->modal_plugin && is_grabbed_event (event)) - { - MetaPluginClass *klass = META_PLUGIN_GET_CLASS (compositor->modal_plugin); - - if (klass->xevent_filter) - klass->xevent_filter (compositor->modal_plugin, event); - - /* We always consume events even if the plugin says it didn't handle them; - * exclusive is exclusive */ - return TRUE; - } - - if (meta_plugin_manager_xevent_filter (compositor->plugin_mgr, event)) - { - DEBUG_TRACE ("meta_compositor_process_event (filtered,window==NULL)\n"); - return TRUE; - } - - switch (event->type) - { - case PropertyNotify: - process_property_notify (compositor, (XPropertyEvent *) event, window); - break; - - default: - if (event->type == meta_display_get_damage_event_base (compositor->display) + XDamageNotify) - { - /* Core code doesn't handle damage events, so we need to extract the MetaWindow - * ourselves - */ - if (window == NULL) - { - Window xwin = ((XDamageNotifyEvent *) event)->drawable; - window = meta_display_lookup_x_window (compositor->display, xwin); - } - - DEBUG_TRACE ("meta_compositor_process_event (process_damage)\n"); + MetaWindowActor *window_actor; - if (window) - process_damage (compositor, (XDamageNotifyEvent *) event, window); - } - break; - } + window_actor = meta_window_actor_from_window (window); + if (!window_actor) + return; - if (compositor->have_x11_sync_object) - meta_sync_ring_handle_event (event); + meta_window_actor_update_opacity (window_actor); +} - /* Clutter needs to know about MapNotify events otherwise it will - think the stage is invisible */ - if (event->type == MapNotify) - clutter_x11_handle_event (event); +gboolean +meta_compositor_filter_keybinding (MetaCompositor *compositor, + MetaKeyBinding *binding) +{ + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); - /* The above handling is basically just "observing" the events, so we return - * FALSE to indicate that the event should not be filtered out; if we have - * GTK+ windows in the same process, GTK+ needs the ConfigureNotify event, for example. - */ - return FALSE; + return meta_plugin_manager_filter_keybinding (priv->plugin_mgr, binding); } void meta_compositor_show_window (MetaCompositor *compositor, - MetaWindow *window, + MetaWindow *window, MetaCompEffect effect) { - MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - DEBUG_TRACE ("meta_compositor_show_window\n"); - if (!window_actor) - return; + MetaWindowActor *window_actor = meta_window_actor_from_window (window); meta_window_actor_show (window_actor, effect); } @@ -933,64 +729,47 @@ meta_compositor_hide_window (MetaCompositor *compositor, MetaWindow *window, MetaCompEffect effect) { - MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - DEBUG_TRACE ("meta_compositor_hide_window\n"); - if (!window_actor) - return; + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); + MetaWindowActor *window_actor = meta_window_actor_from_window (window); meta_window_actor_hide (window_actor, effect); + meta_stack_tracker_queue_sync_stack (priv->display->stack_tracker); } void -meta_compositor_maximize_window (MetaCompositor *compositor, - MetaWindow *window, - MetaRectangle *old_rect, - MetaRectangle *new_rect) +meta_compositor_size_change_window (MetaCompositor *compositor, + MetaWindow *window, + MetaSizeChange which_change, + MetaRectangle *old_frame_rect, + MetaRectangle *old_buffer_rect) { - MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - DEBUG_TRACE ("meta_compositor_maximize_window\n"); - if (!window_actor) - return; - - meta_window_actor_maximize (window_actor, old_rect, new_rect); -} - -void -meta_compositor_unmaximize_window (MetaCompositor *compositor, - MetaWindow *window, - MetaRectangle *old_rect, - MetaRectangle *new_rect) -{ - MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - DEBUG_TRACE ("meta_compositor_unmaximize_window\n"); - if (!window_actor) - return; + MetaWindowActor *window_actor = meta_window_actor_from_window (window); - meta_window_actor_unmaximize (window_actor, old_rect, new_rect); + meta_window_actor_size_change (window_actor, which_change, old_frame_rect, old_buffer_rect); } void meta_compositor_switch_workspace (MetaCompositor *compositor, - MetaScreen *screen, MetaWorkspace *from, MetaWorkspace *to, MetaMotionDirection direction) { + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); gint to_indx, from_indx; + to_indx = meta_workspace_index (to); from_indx = meta_workspace_index (from); - DEBUG_TRACE ("meta_compositor_switch_workspace\n"); + priv->switch_workspace_in_progress++; - compositor->switch_workspace_in_progress++; - - if (!compositor->plugin_mgr || - !meta_plugin_manager_switch_workspace (compositor->plugin_mgr, + if (!meta_plugin_manager_switch_workspace (priv->plugin_mgr, from_indx, to_indx, direction)) { - compositor->switch_workspace_in_progress--; + priv->switch_workspace_in_progress--; /* We have to explicitely call this to fix up stacking order of the * actors; this is because the abs stacking position of actors does not @@ -1001,26 +780,17 @@ meta_compositor_switch_workspace (MetaCompositor *compositor, } } -void -meta_compositor_tile_window (MetaCompositor *compositor, - MetaWindow *window, - MetaRectangle *old_rect, - MetaRectangle *new_rect) -{ - MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - DEBUG_TRACE ("meta_compositor_tile_window\n"); - if (!window_actor) - return; - - meta_window_actor_tile (window_actor, old_rect, new_rect); -} - static void sync_actor_stacking (MetaCompositor *compositor) { + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); GList *children; + GList *expected_window_node; GList *tmp; GList *old; + GList *backgrounds; + gboolean has_windows; gboolean reordered; /* NB: The first entries in the lists are stacked the lowest */ @@ -1029,75 +799,133 @@ sync_actor_stacking (MetaCompositor *compositor) * little effort to make sure we actually need to restack before * we go ahead and do it */ - children = clutter_actor_get_children (compositor->window_group); + children = clutter_actor_get_children (priv->window_group); + has_windows = FALSE; reordered = FALSE; - old = children; - /* We allow for actors in the window group other than the actors we * know about, but it's up to a plugin to try and keep them stacked correctly * (we really need extra API to make that reliable.) */ - /* Of the actors we know, the bottom actor should be the background actor */ - - while (old && old->data != compositor->background_actor && !META_IS_WINDOW_ACTOR (old->data)) - old = old->next; - if (old == NULL || old->data != compositor->background_actor) - { - reordered = TRUE; - goto done_with_check; - } - - /* Then the window actors should follow in sequence */ - - old = old->next; - for (tmp = compositor->windows; tmp != NULL; tmp = tmp->next) + /* First we collect a list of all backgrounds, and check if they're at the + * bottom. Then we check if the window actors are in the correct sequence */ + backgrounds = NULL; + expected_window_node = priv->windows; + for (old = children; old != NULL; old = old->next) { - while (old && !META_IS_WINDOW_ACTOR (old->data)) - old = old->next; + ClutterActor *actor = old->data; - /* old == NULL: someone reparented a window out of the window group, - * order undefined, always restack */ - if (old == NULL || old->data != tmp->data) + if (META_IS_BACKGROUND_GROUP (actor) || + META_IS_BACKGROUND_ACTOR (actor)) { - reordered = TRUE; - goto done_with_check; + backgrounds = g_list_prepend (backgrounds, actor); + + if (has_windows) + reordered = TRUE; } + else if (META_IS_WINDOW_ACTOR (actor) && !reordered) + { + has_windows = TRUE; - old = old->next; + if (expected_window_node != NULL && actor == expected_window_node->data) + expected_window_node = expected_window_node->next; + else + reordered = TRUE; + } } - done_with_check: - g_list_free (children); if (!reordered) - return; + { + g_list_free (backgrounds); + return; + } + + /* reorder the actors by lowering them in turn to the bottom of the stack. + * windows first, then background. + * + * We reorder the actors even if they're not parented to the window group, + * to allow stacking to work with intermediate actors (eg during effects) + */ + for (tmp = g_list_last (priv->windows); tmp != NULL; tmp = tmp->prev) + { + ClutterActor *actor = tmp->data, *parent; - ClutterActor *parent; + parent = clutter_actor_get_parent (actor); + clutter_actor_set_child_below_sibling (parent, actor, NULL); + } - for (tmp = g_list_last (compositor->windows); tmp != NULL; tmp = tmp->prev) + /* we prepended the backgrounds above so the last actor in the list + * should get lowered to the bottom last. + */ + for (tmp = backgrounds; tmp != NULL; tmp = tmp->next) { - ClutterActor *actor = tmp->data; + ClutterActor *actor = tmp->data, *parent; parent = clutter_actor_get_parent (actor); clutter_actor_set_child_below_sibling (parent, actor, NULL); } + g_list_free (backgrounds); +} + +/* + * Find the top most window that is visible on the screen. The intention of + * this is to avoid offscreen windows that isn't actually part of the visible + * desktop (such as the UI frames override redirect window). + */ +static MetaWindowActor * +get_top_visible_window_actor (MetaCompositor *compositor) +{ + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); + GList *l; + + for (l = g_list_last (priv->windows); l; l = l->prev) + { + MetaWindowActor *window_actor = l->data; + MetaWindow *window = meta_window_actor_get_meta_window (window_actor); + MetaRectangle buffer_rect; + MetaRectangle display_rect = { 0 }; + + if (!window->visible_to_compositor) + continue; + + meta_window_get_buffer_rect (window, &buffer_rect); + meta_display_get_size (priv->display, + &display_rect.width, &display_rect.height); + + if (meta_rectangle_overlap (&display_rect, &buffer_rect)) + return window_actor; + } + + return NULL; +} + +static void +on_top_window_actor_destroyed (MetaWindowActor *window_actor, + MetaCompositor *compositor) +{ + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); + + priv->top_window_actor = NULL; + priv->top_window_actor_destroy_id = 0; + priv->windows = g_list_remove (priv->windows, window_actor); - parent = clutter_actor_get_parent (compositor->background_actor); - clutter_actor_set_child_below_sibling (parent, compositor->background_actor, NULL); + meta_stack_tracker_queue_sync_stack (priv->display->stack_tracker); } void meta_compositor_sync_stack (MetaCompositor *compositor, - MetaScreen *screen, - GList *stack) + GList *stack) { + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); + MetaWindowActor *top_window_actor; GList *old_stack; - DEBUG_TRACE ("meta_compositor_sync_stack\n"); - /* This is painful because hidden windows that we are in the process * of animating out of existence. They'll be at the bottom of the * stack of X windows, but we want to leave them in their old position @@ -1106,8 +934,8 @@ meta_compositor_sync_stack (MetaCompositor *compositor, /* Sources: first window is the highest */ stack = g_list_copy (stack); /* The new stack of MetaWindow */ - old_stack = g_list_reverse (compositor->windows); /* The old stack of MetaWindowActor */ - compositor->windows = NULL; + old_stack = g_list_reverse (priv->windows); /* The old stack of MetaWindowActor */ + priv->windows = NULL; while (TRUE) { @@ -1135,7 +963,7 @@ meta_compositor_sync_stack (MetaCompositor *compositor, while (stack) { stack_window = stack->data; - stack_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (stack_window)); + stack_actor = meta_window_actor_from_window (stack_window); if (!stack_actor) { meta_verbose ("Failed to find corresponding MetaWindowActor " @@ -1171,60 +999,55 @@ meta_compositor_sync_stack (MetaCompositor *compositor, * be at the front of at least one, hopefully it will be * near the front of the other.) */ - compositor->windows = g_list_prepend (compositor->windows, actor); + priv->windows = g_list_prepend (priv->windows, actor); stack = g_list_remove (stack, window); old_stack = g_list_remove (old_stack, actor); } sync_actor_stacking (compositor); -} - -void -meta_compositor_sync_window_geometry (MetaCompositor *compositor, - MetaWindow *window, - gboolean did_placement) -{ - MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - DEBUG_TRACE ("meta_compositor_sync_window_geometry\n"); + top_window_actor = get_top_visible_window_actor (compositor); - if (!window_actor) + if (priv->top_window_actor == top_window_actor) return; - meta_window_actor_sync_actor_geometry (window_actor, did_placement); + g_clear_signal_handler (&priv->top_window_actor_destroy_id, + priv->top_window_actor); + + priv->top_window_actor = top_window_actor; + + if (priv->top_window_actor) + priv->top_window_actor_destroy_id = + g_signal_connect (priv->top_window_actor, "destroy", + G_CALLBACK (on_top_window_actor_destroyed), + compositor); } void -meta_compositor_sync_screen_size (MetaCompositor *compositor, - MetaScreen *screen, - guint width, - guint height) +meta_compositor_sync_window_geometry (MetaCompositor *compositor, + MetaWindow *window, + gboolean did_placement) { - MetaDisplay *display = compositor->display; - Display *xdisplay; - Window xwin; + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); + MetaWindowActor *window_actor = meta_window_actor_from_window (window); + MetaWindowActorChanges changes; - DEBUG_TRACE ("meta_compositor_sync_screen_size\n"); + changes = meta_window_actor_sync_actor_geometry (window_actor, did_placement); - xdisplay = meta_display_get_xdisplay (display); - xwin = clutter_x11_get_stage_window (CLUTTER_STAGE (compositor->stage)); - - XResizeWindow (xdisplay, xwin, width, height); - - meta_background_actor_screen_size_changed (screen); - - meta_verbose ("Changed size for stage on screen %d to %dx%d\n", - meta_screen_get_screen_number (screen), - width, height); + if (changes & META_WINDOW_ACTOR_CHANGE_SIZE) + meta_plugin_manager_event_size_changed (priv->plugin_mgr, window_actor); } static void -frame_callback (ClutterStage *stage, - CoglFrameEvent event, - ClutterFrameInfo *frame_info, - MetaCompositor *compositor) +on_presented (ClutterStage *stage, + CoglFrameEvent event, + ClutterFrameInfo *frame_info, + MetaCompositor *compositor) { + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); GList *l; if (event == COGL_FRAME_EVENT_COMPLETE) @@ -1243,7 +1066,7 @@ frame_callback (ClutterStage *stage, * is fairly fast, so calling it twice and subtracting to get a * nearly-zero number is acceptable, if a litle ugly. */ - gint64 current_cogl_time = cogl_get_clock_time (compositor->context); + gint64 current_cogl_time = cogl_get_clock_time (priv->context); gint64 current_monotonic_time = g_get_monotonic_time (); presentation_time = @@ -1254,115 +1077,61 @@ frame_callback (ClutterStage *stage, presentation_time = 0; } - for (l = compositor->windows; l; l = l->next) + for (l = priv->windows; l; l = l->next) meta_window_actor_frame_complete (l->data, frame_info, presentation_time); } } -static gboolean -meta_pre_paint_func (gpointer data) +static void +meta_compositor_real_pre_paint (MetaCompositor *compositor) { + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); GList *l; - MetaCompositor *compositor = data; - GSList *screens = compositor->display->screens; - MetaWindowActor *top_window = NULL; - MetaWindowActor *expected_unredirected_window = NULL; - - if (compositor->windows == NULL) - return TRUE; - - for (l = g_list_last (compositor->windows); l; l = l->prev) - { - MetaRectangle *rect = &meta_window_actor_get_meta_window (l->data)->rect; - if (rect->x + rect->width > 0 && rect->y + rect->height > 0) - { - top_window = l->data; - break; - } - } - - if (top_window != NULL && - meta_window_actor_should_unredirect (top_window) && - compositor->disable_unredirect_count == 0) - expected_unredirected_window = top_window; - - if (compositor->unredirected_window != expected_unredirected_window) - { - if (compositor->unredirected_window != NULL) - { - meta_window_actor_set_redirected (compositor->unredirected_window, TRUE); - meta_shape_cow_for_window (compositor->display->active_screen, NULL); - } - if (expected_unredirected_window != NULL) - { - meta_shape_cow_for_window (compositor->display->active_screen, - meta_window_actor_get_meta_window (top_window)); - meta_window_actor_set_redirected (top_window, FALSE); - } + for (l = priv->windows; l; l = l->next) + meta_window_actor_pre_paint (l->data); +} - compositor->unredirected_window = expected_unredirected_window; - } +static void +meta_compositor_pre_paint (MetaCompositor *compositor) +{ + COGL_TRACE_BEGIN_SCOPED (MetaCompositorPrePaint, + "Compositor (pre-paint)"); + META_COMPOSITOR_GET_CLASS (compositor)->pre_paint (compositor); +} - for (l = compositor->windows; l; l = l->next) - meta_window_actor_pre_paint (l->data); +static gboolean +meta_pre_paint_func (gpointer data) +{ + MetaCompositor *compositor = data; - if (compositor->frame_has_updated_xsurfaces) - { - /* We need to make sure that any X drawing that happens before - * the XDamageSubtract() for each window above is visible to - * subsequent GL rendering; the standardized way to do this is - * GL_EXT_X11_sync_object. Since this isn't implemented yet in - * mesa, we also have a path that relies on the implementation - * of the open source drivers. - * - * Anything else, we just hope for the best. - * - * Xorg and open source driver specifics: - * - * The X server makes sure to flush drawing to the kernel before - * sending out damage events, but since we use - * DamageReportBoundingBox there may be drawing between the last - * damage event and the XDamageSubtract() that needs to be - * flushed as well. - * - * Xorg always makes sure that drawing is flushed to the kernel - * before writing events or responses to the client, so any - * round trip request at this point is sufficient to flush the - * GLX buffers. - */ - if (compositor->have_x11_sync_object) - compositor->have_x11_sync_object = meta_sync_ring_insert_wait (); - else - XSync (compositor->display->xdisplay, False); - } + meta_compositor_pre_paint (compositor); return TRUE; } -static gboolean -meta_post_paint_func (gpointer data) +static void +meta_compositor_real_post_paint (MetaCompositor *compositor) { - MetaCompositor *compositor = data; + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); CoglGraphicsResetStatus status; - if (compositor->frame_has_updated_xsurfaces) - { - if (compositor->have_x11_sync_object) - compositor->have_x11_sync_object = meta_sync_ring_after_frame (); - - compositor->frame_has_updated_xsurfaces = FALSE; - } +#ifdef HAVE_WAYLAND + if (meta_is_wayland_compositor ()) + meta_wayland_compositor_paint_finished (meta_wayland_compositor_get_default ()); +#endif - status = cogl_get_graphics_reset_status (compositor->context); + status = cogl_get_graphics_reset_status (priv->context); switch (status) { case COGL_GRAPHICS_RESET_STATUS_NO_ERROR: break; case COGL_GRAPHICS_RESET_STATUS_PURGED_CONTEXT_RESET: - g_signal_emit_by_name (compositor->display, "gl-video-memory-purged"); - clutter_actor_queue_redraw (CLUTTER_ACTOR (compositor->stage)); + g_signal_emit_by_name (priv->display, "gl-video-memory-purged"); + clutter_actor_queue_redraw (CLUTTER_ACTOR (priv->stage)); break; default: @@ -1372,114 +1141,197 @@ meta_post_paint_func (gpointer data) restart the process. Obviously we can't do this when we are a wayland compositor but in that case we shouldn't get here since we don't enable robustness in that case. */ - meta_restart (); + g_assert (!meta_is_wayland_compositor ()); + meta_restart (NULL); break; } +} - return TRUE; +static void +meta_compositor_post_paint (MetaCompositor *compositor) +{ + COGL_TRACE_BEGIN_SCOPED (MetaCompositorPostPaint, + "Compositor (post-paint)"); + META_COMPOSITOR_GET_CLASS (compositor)->post_paint (compositor); } -void -meta_compositor_on_shadow_factory_changed (void) +static gboolean +meta_post_paint_func (gpointer data) { - GList *l; + MetaCompositor *compositor = data; - for (l = compositor_global->windows; l; l = l->next) - meta_window_actor_invalidate_shadow (l->data); + meta_compositor_post_paint (compositor); + + return TRUE; } -/** - * meta_compositor_new: (skip) - * - */ -MetaCompositor * -meta_compositor_new (MetaDisplay *display) +static void +meta_compositor_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) { - char *atom_names[] = { - "_XROOTPMAP_ID", - "_XSETROOT_ID", - "_NET_WM_WINDOW_OPACITY", - }; - Atom atoms[G_N_ELEMENTS(atom_names)]; - MetaCompositor *compositor; - Display *xdisplay = meta_display_get_xdisplay (display); + MetaCompositor *compositor = META_COMPOSITOR (object); + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); - if (!composite_at_least_version (display, 0, 3)) - return NULL; - - compositor = g_new0 (MetaCompositor, 1); + switch (prop_id) + { + case PROP_DISPLAY: + priv->display = g_value_get_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} - compositor->display = display; - compositor->context = clutter_backend_get_cogl_context (clutter_get_default_backend ()); +static void +meta_compositor_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaCompositor *compositor = META_COMPOSITOR (object); + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); - if (g_getenv("META_DISABLE_MIPMAPS")) - compositor->no_mipmaps = TRUE; + switch (prop_id) + { + case PROP_DISPLAY: + g_value_set_object (value, priv->display); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} - meta_verbose ("Creating %d atoms\n", (int) G_N_ELEMENTS (atom_names)); - XInternAtoms (xdisplay, atom_names, G_N_ELEMENTS (atom_names), - False, atoms); +static void +meta_compositor_init (MetaCompositor *compositor) +{ + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); + MetaBackend *backend = meta_get_backend (); + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); - compositor->atom_x_root_pixmap = atoms[0]; - compositor->atom_x_set_root = atoms[1]; - compositor->atom_net_wm_window_opacity = atoms[2]; + priv->context = clutter_backend->cogl_context; - compositor->pre_paint_func_id = + priv->pre_paint_func_id = clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_PRE_PAINT, meta_pre_paint_func, compositor, NULL); - compositor->post_paint_func_id = + priv->post_paint_func_id = clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_POST_PAINT, meta_post_paint_func, compositor, NULL); +} + +static void +meta_compositor_dispose (GObject *object) +{ + MetaCompositor *compositor = META_COMPOSITOR (object); + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); + + g_clear_signal_handler (&priv->stage_after_paint_id, priv->stage); + g_clear_signal_handler (&priv->stage_presented_id, priv->stage); + + g_clear_handle_id (&priv->pre_paint_func_id, + clutter_threads_remove_repaint_func); + g_clear_handle_id (&priv->post_paint_func_id, + clutter_threads_remove_repaint_func); + + g_clear_signal_handler (&priv->top_window_actor_destroy_id, + priv->top_window_actor); - compositor_global = compositor; + g_clear_pointer (&priv->window_group, clutter_actor_destroy); + g_clear_pointer (&priv->top_window_group, clutter_actor_destroy); + g_clear_pointer (&priv->feedback_group, clutter_actor_destroy); + g_clear_pointer (&priv->windows, g_list_free); - return compositor; + G_OBJECT_CLASS (meta_compositor_parent_class)->dispose (object); } -/** - * meta_get_overlay_window: (skip) - * - */ -Window -meta_get_overlay_window (MetaScreen *screen) +static void +meta_compositor_class_init (MetaCompositorClass *klass) { - return screen->display->compositor->output; + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->set_property = meta_compositor_set_property; + object_class->get_property = meta_compositor_get_property; + object_class->dispose = meta_compositor_dispose; + + klass->remove_window = meta_compositor_real_remove_window; + klass->pre_paint = meta_compositor_real_pre_paint; + klass->post_paint = meta_compositor_real_post_paint; + + obj_props[PROP_DISPLAY] = + g_param_spec_object ("display", + "display", + "MetaDisplay", + META_TYPE_DISPLAY, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + g_object_class_install_properties (object_class, N_PROPS, obj_props); } /** - * meta_disable_unredirect_for_screen: - * @screen: a #MetaScreen + * meta_disable_unredirect_for_display: + * @display: a #MetaDisplay * * Disables unredirection, can be usefull in situations where having * unredirected windows is undesireable like when recording a video. * */ void -meta_disable_unredirect_for_screen (MetaScreen *screen) +meta_disable_unredirect_for_display (MetaDisplay *display) { - MetaCompositor *compositor = screen->display->compositor; + MetaCompositor *compositor; + MetaCompositorPrivate *priv; + + if (display->closing) + return; + + compositor = get_compositor_for_display (display); + priv = meta_compositor_get_instance_private (compositor); - compositor->disable_unredirect_count = compositor->disable_unredirect_count + 1; + priv->disable_unredirect_count++; } /** - * meta_enable_unredirect_for_screen: - * @screen: a #MetaScreen + * meta_enable_unredirect_for_display: + * @display: a #MetaDisplay * * Enables unredirection which reduces the overhead for apps like games. * */ void -meta_enable_unredirect_for_screen (MetaScreen *screen) +meta_enable_unredirect_for_display (MetaDisplay *display) +{ + MetaCompositor *compositor; + MetaCompositorPrivate *priv; + + if (display->closing) + return; + + compositor = get_compositor_for_display (display); + priv = meta_compositor_get_instance_private (compositor); + + if (priv->disable_unredirect_count == 0) + g_warning ("Called enable_unredirect_for_display while unredirection is enabled."); + if (priv->disable_unredirect_count > 0) + priv->disable_unredirect_count--; +} + +gboolean +meta_compositor_is_unredirect_inhibited (MetaCompositor *compositor) { - MetaCompositor *compositor = screen->display->compositor; - if (compositor->disable_unredirect_count == 0) - g_warning ("Called enable_unredirect_for_screen while unredirection is enabled."); - if (compositor->disable_unredirect_count > 0) - compositor->disable_unredirect_count = compositor->disable_unredirect_count - 1; + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); + + return priv->disable_unredirect_count > 0; } #define FLASH_TIME_MS 50 @@ -1494,15 +1346,15 @@ flash_out_completed (ClutterTimeline *timeline, } void -meta_compositor_flash_screen (MetaCompositor *compositor, - MetaScreen *screen) +meta_compositor_flash_display (MetaCompositor *compositor, + MetaDisplay *display) { ClutterActor *stage; ClutterActor *flash; ClutterTransition *transition; gfloat width, height; - stage = meta_get_stage_for_screen (screen); + stage = meta_get_stage_for_display (display); clutter_actor_get_size (stage, &width, &height); flash = clutter_actor_new (); @@ -1526,48 +1378,50 @@ meta_compositor_flash_screen (MetaCompositor *compositor, clutter_actor_restore_easing_state (flash); } -void -meta_compositor_show_tile_preview (MetaCompositor *compositor, - MetaScreen *screen, - MetaWindow *window, - MetaRectangle *tile_rect, - int tile_monitor_number, - guint snap_queued) +static void +window_flash_out_completed (ClutterTimeline *timeline, + gboolean is_finished, + gpointer user_data) { - meta_plugin_manager_show_tile_preview (compositor->plugin_mgr, - window, tile_rect, tile_monitor_number, - snap_queued); + ClutterActor *flash = CLUTTER_ACTOR (user_data); + clutter_actor_destroy (flash); } void -meta_compositor_hide_tile_preview (MetaCompositor *compositor, - MetaScreen *screen) +meta_compositor_flash_window (MetaCompositor *compositor, + MetaWindow *window) { - meta_plugin_manager_hide_tile_preview (compositor->plugin_mgr); -} + ClutterActor *window_actor = + CLUTTER_ACTOR (meta_window_actor_from_window (window)); + ClutterActor *flash; + ClutterTransition *transition; -void -meta_compositor_show_hud_preview (MetaCompositor *compositor, - MetaScreen *screen, - guint current_proximity_zone, - MetaRectangle *work_area, - guint snap_queued) -{ - meta_plugin_manager_show_hud_preview (compositor->plugin_mgr, - current_proximity_zone, - work_area, - snap_queued); -} + flash = clutter_actor_new (); + clutter_actor_set_background_color (flash, CLUTTER_COLOR_Black); + clutter_actor_set_size (flash, window->rect.width, window->rect.height); + clutter_actor_set_position (flash, + window->custom_frame_extents.left, + window->custom_frame_extents.top); + clutter_actor_set_opacity (flash, 0); + clutter_actor_add_child (window_actor, flash); -void -meta_compositor_hide_hud_preview (MetaCompositor *compositor, - MetaScreen *screen) -{ - meta_plugin_manager_hide_hud_preview (compositor->plugin_mgr); + clutter_actor_save_easing_state (flash); + clutter_actor_set_easing_mode (flash, CLUTTER_EASE_IN_QUAD); + clutter_actor_set_easing_duration (flash, FLASH_TIME_MS); + clutter_actor_set_opacity (flash, 192); + + transition = clutter_actor_get_transition (flash, "opacity"); + clutter_timeline_set_auto_reverse (CLUTTER_TIMELINE (transition), TRUE); + clutter_timeline_set_repeat_count (CLUTTER_TIMELINE (transition), 2); + + g_signal_connect (transition, "stopped", + G_CALLBACK (window_flash_out_completed), flash); + + clutter_actor_restore_easing_state (flash); } /** - * meta_compositor_monotonic_time_to_server_time: + * meta_compositor_monotonic_to_high_res_xserver_time: * @display: a #MetaDisplay * @monotonic_time: time in the units of g_get_monotonic_time() * @@ -1580,64 +1434,134 @@ meta_compositor_hide_hud_preview (MetaCompositor *compositor, * a time representation with high accuracy. If there is not a common * time source, then the time synchronization will be less accurate. */ -gint64 -meta_compositor_monotonic_time_to_server_time (MetaDisplay *display, - gint64 monotonic_time) +int64_t +meta_compositor_monotonic_to_high_res_xserver_time (MetaCompositor *compositor, + int64_t monotonic_time_us) { - MetaCompositor *compositor = display->compositor; + MetaCompositorClass *klass = META_COMPOSITOR_GET_CLASS (compositor); - if (compositor->server_time_query_time == 0 || - (!compositor->server_time_is_monotonic_time && - monotonic_time > compositor->server_time_query_time + 10*1000*1000)) /* 10 seconds */ - { - guint32 server_time = meta_display_get_current_time_roundtrip (display); - gint64 server_time_usec = (gint64)server_time * 1000; - gint64 current_monotonic_time = g_get_monotonic_time (); - compositor->server_time_query_time = current_monotonic_time; - - /* If the server time is within a second of the monotonic time, - * we assume that they are identical. This seems like a big margin, - * but we want to be as robust as possible even if the system - * is under load and our processing of the server response is - * delayed. - */ - if (server_time_usec > current_monotonic_time - 1000*1000 && - server_time_usec < current_monotonic_time + 1000*1000) - compositor->server_time_is_monotonic_time = TRUE; + return klass->monotonic_to_high_res_xserver_time (compositor, monotonic_time_us); +} - compositor->server_time_offset = server_time_usec - current_monotonic_time; - } +void +meta_compositor_show_tile_preview (MetaCompositor *compositor, + MetaWindow *window, + MetaRectangle *tile_rect, + int tile_monitor_number) +{ + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); - if (compositor->server_time_is_monotonic_time) - return monotonic_time; - else - return monotonic_time + compositor->server_time_offset; + meta_plugin_manager_show_tile_preview (priv->plugin_mgr, + window, tile_rect, tile_monitor_number); +} + +void +meta_compositor_hide_tile_preview (MetaCompositor *compositor) +{ + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); + + meta_plugin_manager_hide_tile_preview (priv->plugin_mgr); } void -meta_compositor_grab_op_begin (MetaCompositor *compositor) +meta_compositor_show_window_menu (MetaCompositor *compositor, + MetaWindow *window, + MetaWindowMenuType menu, + int x, + int y) { - // CLUTTER_ACTOR_NO_LAYOUT set on the window group improves responsiveness of windows, - // but causes windows to flicker in and out of view sporadically on some configurations - // while dragging windows. Make sure it is disabled during the grab. - clutter_actor_unset_flags (compositor->window_group, CLUTTER_ACTOR_NO_LAYOUT); + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); + + meta_plugin_manager_show_window_menu (priv->plugin_mgr, window, menu, x, y); } void -meta_compositor_grab_op_end (MetaCompositor *compositor) +meta_compositor_show_window_menu_for_rect (MetaCompositor *compositor, + MetaWindow *window, + MetaWindowMenuType menu, + MetaRectangle *rect) +{ + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); + + meta_plugin_manager_show_window_menu_for_rect (priv->plugin_mgr, window, menu, rect); +} + +MetaCloseDialog * +meta_compositor_create_close_dialog (MetaCompositor *compositor, + MetaWindow *window) { - clutter_actor_set_flags (compositor->window_group, CLUTTER_ACTOR_NO_LAYOUT); + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); + + return meta_plugin_manager_create_close_dialog (priv->plugin_mgr, + window); } -CoglContext * -meta_compositor_get_cogl_context (void) +MetaInhibitShortcutsDialog * +meta_compositor_create_inhibit_shortcuts_dialog (MetaCompositor *compositor, + MetaWindow *window) { - return compositor_global->context; + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); + + return meta_plugin_manager_create_inhibit_shortcuts_dialog (priv->plugin_mgr, + window); } void -meta_compositor_update_sync_state (MetaCompositor *compositor, - MetaSyncMethod method) +meta_compositor_locate_pointer (MetaCompositor *compositor) +{ + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); + + meta_plugin_manager_locate_pointer (priv->plugin_mgr); +} + +MetaPluginManager * +meta_compositor_get_plugin_manager (MetaCompositor *compositor) +{ + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); + + return priv->plugin_mgr; +} + +MetaDisplay * +meta_compositor_get_display (MetaCompositor *compositor) +{ + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); + + return priv->display; +} + +ClutterStage * +meta_compositor_get_stage (MetaCompositor *compositor) +{ + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); + + return CLUTTER_STAGE (priv->stage); +} + +MetaWindowActor * +meta_compositor_get_top_window_actor (MetaCompositor *compositor) +{ + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); + + return priv->top_window_actor; +} + +gboolean +meta_compositor_is_switching_workspace (MetaCompositor *compositor) { - clutter_stage_x11_update_sync_state (compositor->stage, method); + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); + + return priv->switch_workspace_in_progress > 0; } diff --git a/src/compositor/meta-background-actor-private.h b/src/compositor/meta-background-actor-private.h index 531bc4ed5..bdf8c4744 100644 --- a/src/compositor/meta-background-actor-private.h +++ b/src/compositor/meta-background-actor-private.h @@ -3,15 +3,8 @@ #ifndef META_BACKGROUND_ACTOR_PRIVATE_H #define META_BACKGROUND_ACTOR_PRIVATE_H -#include <meta/screen.h> -#include <meta/meta-background-actor.h> -#include "meta-background.h" - -void meta_background_actor_set_visible_region (MetaBackgroundActor *self, - cairo_region_t *visible_region); - -void meta_background_actor_update (MetaScreen *screen); -void meta_background_actor_screen_size_changed (MetaScreen *screen); +#include "meta/meta-background-actor.h" +cairo_region_t *meta_background_actor_get_clip_region (MetaBackgroundActor *self); #endif /* META_BACKGROUND_ACTOR_PRIVATE_H */ diff --git a/src/compositor/meta-background-actor.c b/src/compositor/meta-background-actor.c index 7d2deef9e..628fb3ff3 100644 --- a/src/compositor/meta-background-actor.c +++ b/src/compositor/meta-background-actor.c @@ -1,9 +1,7 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ /* - * meta-background-actor.c: Actor for painting the root window background - * * Copyright 2009 Sander Dijkhuis - * Copyright 2010 Red Hat, Inc. + * Copyright 2014 Red Hat, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -16,9 +14,7 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. * * Portions adapted from gnome-shell/src/shell-global.c */ @@ -27,397 +23,634 @@ * SECTION:meta-background-actor * @title: MetaBackgroundActor * @short_description: Actor for painting the root window background + * */ -#include <config.h> - -#include <cogl/winsys/cogl-texture-pixmap-x11.h> - -#include <clutter/clutter.h> - -#include <X11/Xatom.h> +/* + * The overall model drawing model of this widget is that we have one + * texture, or two interpolated textures, possibly with alpha or + * margins that let the underlying background show through, blended + * over a solid color or a gradient. The result of that combination + * can then be affected by a "vignette" that darkens the background + * away from a central point (or as a no-GLSL fallback, simply darkens + * the background) and by overall opacity. + * + * As of GNOME 3.14, GNOME is only using a fraction of this when the + * user sets the background through the control center - what can be + * set is: + * + * A single image without a border + * An animation of images without a border that blend together, + * with the blend changing every 4-5 minutes + * A solid color with a repeated noise texture blended over it + * + * This all is pretty easy to do in a fragment shader, except when: + * + * A) We don't have GLSL - in this case, the operation of + * interpolating the two textures and blending the result over the + * background can't be expressed with Cogl's fixed-function layer + * combining (which is confined to what GL's texture environment + * combining can do) So we can only handle the above directly if + * there are no margins or alpha. + * + * B) The image textures are sliced. Texture size limits on older + * hardware (pre-965 intel hardware, r300, etc.) is often 2048, + * and it would be common to use a texture larger than this for a + * background and expect it to be scaled down. Cogl can compensate + * for this by breaking the texture up into multiple textures, but + * can't multitexture with sliced textures. So we can only handle + * the above if there's a single texture. + * + * However, even when we *can* represent everything in a single pass, + * it's not necessarily efficient. If we want to draw a 1024x768 + * background, it's pretty inefficient to bilinearly texture from + * two 2560x1440 images and mix that. So the drawing model we take + * here is that MetaBackground generates a single texture (which + * might be a 1x1 texture for a solid color, or a 1x2 texture for a + * gradient, or a repeated texture for wallpaper, or a pre-rendered + * texture the size of the screen), and we draw with that, possibly + * adding the vignette and opacity. + */ -#include "cogl-utils.h" -#include "compositor-private.h" -#include <meta/errors.h> -#include "meta-background-actor-private.h" +#include "config.h" -#define FADE_DURATION 1500 +#include "compositor/meta-background-actor-private.h" -/* We allow creating multiple MetaBackgroundActors for the same MetaScreen to - * allow different rendering options to be set for different copies. - * But we want to share the same underlying CoglTexture for efficiency and - * to avoid driver bugs that might occur if we created multiple CoglTexturePixmaps - * for the same pixmap. - * - * This structure holds common information. - */ -typedef struct _MetaScreenBackground MetaScreenBackground; +#include "clutter/clutter.h" +#include "compositor/clutter-utils.h" +#include "compositor/cogl-utils.h" +#include "compositor/meta-background-private.h" +#include "compositor/meta-cullable.h" +#include "meta/display.h" +#include "meta/meta-x11-errors.h" -struct _MetaScreenBackground +enum { - MetaScreen *screen; - GSList *actors; - - float texture_width; - float texture_height; - CoglTexture *texture; - CoglPipelineWrapMode wrap_mode; - guint have_pixmap : 1; + PROP_META_DISPLAY = 1, + PROP_MONITOR, + PROP_BACKGROUND, + PROP_GRADIENT, + PROP_GRADIENT_HEIGHT, + PROP_GRADIENT_MAX_DARKNESS, + PROP_VIGNETTE, + PROP_VIGNETTE_SHARPNESS, + PROP_VIGNETTE_BRIGHTNESS }; -struct _MetaBackgroundActorPrivate +typedef enum { - MetaScreenBackground *background; - ClutterActor *top_actor; - ClutterActor *bottom_actor; - cairo_region_t *visible_region; - float dim_factor; - gboolean transition_running; -}; + CHANGED_BACKGROUND = 1 << 0, + CHANGED_EFFECTS = 1 << 2, + CHANGED_VIGNETTE_PARAMETERS = 1 << 3, + CHANGED_GRADIENT_PARAMETERS = 1 << 4, + CHANGED_ALL = 0xFFFF +} ChangedFlags; + +#define GRADIENT_VERTEX_SHADER_DECLARATIONS \ +"uniform vec2 scale;\n" \ +"varying vec2 position;\n" \ + +#define GRADIENT_VERTEX_SHADER_CODE \ +"position = cogl_tex_coord0_in.xy * scale;\n" \ + +#define GRADIENT_FRAGMENT_SHADER_DECLARATIONS \ +"uniform float gradient_height_perc;\n" \ +"uniform float gradient_max_darkness;\n" \ +"varying vec2 position;\n" \ + +#define GRADIENT_FRAGMENT_SHADER_CODE \ +"float min_brightness = 1.0 - gradient_max_darkness;\n" \ +"float gradient_y_pos = min(position.y, gradient_height_perc) / gradient_height_perc;\n" \ +"float pixel_brightness = (1.0 - min_brightness) * gradient_y_pos + min_brightness;\n" \ +"cogl_color_out.rgb = cogl_color_out.rgb * pixel_brightness;\n" \ + +#define VIGNETTE_VERTEX_SHADER_DECLARATIONS \ +"uniform vec2 scale;\n" \ +"uniform vec2 offset;\n" \ +"varying vec2 position;\n" \ + +#define VIGNETTE_VERTEX_SHADER_CODE \ +"position = cogl_tex_coord0_in.xy * scale + offset;\n" \ + +#define VIGNETTE_SQRT_2 "1.4142" + +#define VIGNETTE_FRAGMENT_SHADER_DECLARATIONS \ +"uniform float vignette_sharpness;\n" \ +"varying vec2 position;\n" \ +"float rand(vec2 p) { return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453123); }\n" \ + +#define VIGNETTE_FRAGMENT_SHADER_CODE \ +"float t = " VIGNETTE_SQRT_2 " * length(position);\n" \ +"t = min(t, 1.0);\n" \ +"float pixel_brightness = 1.0 - t * vignette_sharpness;\n" \ +"cogl_color_out.rgb = cogl_color_out.rgb * pixel_brightness;\n" \ +"cogl_color_out.rgb += (rand(position) - 0.5) / 255.0;\n" \ + +typedef struct _MetaBackgroundLayer MetaBackgroundLayer; + +typedef enum +{ + PIPELINE_VIGNETTE = (1 << 0), + PIPELINE_BLEND = (1 << 1), + PIPELINE_GRADIENT = (1 << 2), +} PipelineFlags; -enum +struct _MetaBackgroundActor { - PROP_0, + ClutterActor parent; + + MetaDisplay *display; + int monitor; - PROP_DIM_FACTOR, + MetaBackground *background; - PROP_LAST -}; + gboolean gradient; + double gradient_max_darkness; + int gradient_height; -static GParamSpec *obj_props[PROP_LAST]; + gboolean vignette; + double vignette_brightness; + double vignette_sharpness; -G_DEFINE_TYPE (MetaBackgroundActor, meta_background_actor, CLUTTER_TYPE_ACTOR); + ChangedFlags changed; + CoglPipeline *pipeline; + PipelineFlags pipeline_flags; + cairo_rectangle_int_t texture_area; + gboolean force_bilinear; + + cairo_region_t *clip_region; + cairo_region_t *unobscured_region; +}; -static void set_texture (MetaScreenBackground *background, - CoglTexture *texture); -static void set_texture_to_stage_color (MetaScreenBackground *background); +static void cullable_iface_init (MetaCullableInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (MetaBackgroundActor, meta_background_actor, CLUTTER_TYPE_ACTOR, + G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init)); static void -on_notify_stage_color (GObject *stage, - GParamSpec *pspec, - MetaScreenBackground *background) +set_clip_region (MetaBackgroundActor *self, + cairo_region_t *clip_region) { - if (!background->have_pixmap) - set_texture_to_stage_color (background); + g_clear_pointer (&self->clip_region, cairo_region_destroy); + if (clip_region) + { + if (cairo_region_is_empty (clip_region)) + self->clip_region = cairo_region_reference (clip_region); + else + self->clip_region = cairo_region_copy (clip_region); + } } static void -free_screen_background (MetaScreenBackground *background) +set_unobscured_region (MetaBackgroundActor *self, + cairo_region_t *unobscured_region) { - set_texture (background, NULL); - - if (background->screen != NULL) + g_clear_pointer (&self->unobscured_region, cairo_region_destroy); + if (unobscured_region) { - ClutterActor *stage = meta_get_stage_for_screen (background->screen); - g_signal_handlers_disconnect_by_func (stage, - (gpointer) on_notify_stage_color, - background); - background->screen = NULL; + if (cairo_region_is_empty (unobscured_region)) + self->unobscured_region = cairo_region_reference (unobscured_region); + else + self->unobscured_region = cairo_region_copy (unobscured_region); } } -static MetaScreenBackground * -meta_screen_background_get (MetaScreen *screen) +static void +meta_background_actor_dispose (GObject *object) { - MetaScreenBackground *background; + MetaBackgroundActor *self = META_BACKGROUND_ACTOR (object); - background = g_object_get_data (G_OBJECT (screen), "meta-screen-background"); - if (background == NULL) + set_clip_region (self, NULL); + set_unobscured_region (self, NULL); + meta_background_actor_set_background (self, NULL); + if (self->pipeline) { - ClutterActor *stage; - - background = g_new0 (MetaScreenBackground, 1); - - background->screen = screen; - g_object_set_data_full (G_OBJECT (screen), "meta-screen-background", - background, (GDestroyNotify) free_screen_background); - - stage = meta_get_stage_for_screen (screen); - g_signal_connect (stage, "notify::background-color", - G_CALLBACK (on_notify_stage_color), background); - - meta_background_actor_update (screen); + cogl_object_unref (self->pipeline); + self->pipeline = NULL; } - return background; + G_OBJECT_CLASS (meta_background_actor_parent_class)->dispose (object); } static void -update_wrap_mode_of_actor (MetaBackgroundActor *self) +get_preferred_size (MetaBackgroundActor *self, + gfloat *width, + gfloat *height) { - MetaBackgroundActorPrivate *priv = self->priv; + MetaRectangle monitor_geometry; + + meta_display_get_monitor_geometry (self->display, + self->monitor, + &monitor_geometry); - meta_background_set_layer_wrap_mode (META_BACKGROUND (priv->top_actor), priv->background->wrap_mode); - meta_background_set_layer_wrap_mode (META_BACKGROUND (priv->bottom_actor), priv->background->wrap_mode); + if (width != NULL) + *width = monitor_geometry.width; - /* this ensures the actors also get resized if the stage size changed */ - clutter_actor_queue_relayout (CLUTTER_ACTOR (priv->top_actor)); - clutter_actor_queue_relayout (CLUTTER_ACTOR (priv->bottom_actor)); + if (height != NULL) + *height = monitor_geometry.height; } static void -update_wrap_mode (MetaScreenBackground *background) +meta_background_actor_get_preferred_width (ClutterActor *actor, + gfloat for_height, + gfloat *min_width_p, + gfloat *natural_width_p) { - GSList *l; - int width, height; + gfloat width; - meta_screen_get_size (background->screen, &width, &height); + get_preferred_size (META_BACKGROUND_ACTOR (actor), &width, NULL); - /* We turn off repeating when we have a full-screen pixmap to keep from - * getting artifacts from one side of the image sneaking into the other - * side of the image via bilinear filtering. - */ - if (width == background->texture_width && height == background->texture_height) - background->wrap_mode = COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE; - else - background->wrap_mode = COGL_PIPELINE_WRAP_MODE_REPEAT; - - for (l = background->actors; l; l = l->next) - update_wrap_mode_of_actor (l->data); + if (min_width_p) + *min_width_p = width; + if (natural_width_p) + *natural_width_p = width; } static void -cancel_transitions (MetaBackgroundActor *self) +meta_background_actor_get_preferred_height (ClutterActor *actor, + gfloat for_width, + gfloat *min_height_p, + gfloat *natural_height_p) + { - MetaBackgroundActorPrivate *priv = self->priv; + gfloat height; - clutter_actor_remove_all_transitions (priv->top_actor); - clutter_actor_set_opacity (priv->top_actor, 255); - meta_background_set_layer (META_BACKGROUND (priv->bottom_actor), priv->background->texture); + get_preferred_size (META_BACKGROUND_ACTOR (actor), NULL, &height); - priv->transition_running = FALSE; + if (min_height_p) + *min_height_p = height; + if (natural_height_p) + *natural_height_p = height; } -static void -on_transition_complete (ClutterActor *actor, - gpointer user_data) +static CoglPipeline * +make_pipeline (PipelineFlags pipeline_flags) { - MetaBackgroundActor *self = (MetaBackgroundActor *)user_data; - MetaBackgroundActorPrivate *priv = self->priv; + static CoglPipeline *templates[8]; + CoglPipeline **templatep; - meta_background_set_layer (META_BACKGROUND (priv->bottom_actor), priv->background->texture); - priv->transition_running = FALSE; -} + templatep = &templates[pipeline_flags]; + if (*templatep == NULL) + { + /* Cogl automatically caches pipelines with no eviction policy, + * so we need to prevent identical pipelines from getting cached + * separately, by reusing the same shader snippets. + */ + *templatep = COGL_PIPELINE (meta_create_texture_pipeline (NULL)); -static void -set_texture_on_actors (MetaBackgroundActor *self) -{ - MetaBackgroundActorPrivate *priv = self->priv; + if ((pipeline_flags & PIPELINE_VIGNETTE) != 0) + { + static CoglSnippet *vignette_vertex_snippet; + static CoglSnippet *vignette_fragment_snippet; - meta_background_set_layer (META_BACKGROUND (priv->bottom_actor), priv->background->texture); - meta_background_set_layer (META_BACKGROUND (priv->top_actor), priv->background->texture); + if (!vignette_vertex_snippet) + vignette_vertex_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX, + VIGNETTE_VERTEX_SHADER_DECLARATIONS, + VIGNETTE_VERTEX_SHADER_CODE); - clutter_actor_queue_redraw (CLUTTER_ACTOR (self)); -} + cogl_pipeline_add_snippet (*templatep, vignette_vertex_snippet); -static void -set_texture_on_actor (MetaBackgroundActor *self) -{ - MetaBackgroundActorPrivate *priv = self->priv; - MetaBackgroundTransition background_transition; + if (!vignette_fragment_snippet) + vignette_fragment_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, + VIGNETTE_FRAGMENT_SHADER_DECLARATIONS, + VIGNETTE_FRAGMENT_SHADER_CODE); - if (priv->transition_running) - cancel_transitions (self); + cogl_pipeline_add_snippet (*templatep, vignette_fragment_snippet); + } - background_transition = meta_prefs_get_background_transition(); + if ((pipeline_flags & PIPELINE_GRADIENT) != 0) + { + static CoglSnippet *gradient_vertex_snippet; + static CoglSnippet *gradient_fragment_snippet; - if (background_transition == META_BACKGROUND_TRANSITION_NONE) - { - // NO TRANSITION - clutter_actor_set_opacity (CLUTTER_ACTOR (priv->bottom_actor), 0); - meta_background_set_layer (META_BACKGROUND (priv->top_actor), priv->background->texture); - on_transition_complete (priv->top_actor, self); - } - else - { - if (background_transition == META_BACKGROUND_TRANSITION_FADEIN) - { - // FADE_IN TRANSITION - clutter_actor_set_opacity (CLUTTER_ACTOR (priv->bottom_actor), 0); - } + if (!gradient_vertex_snippet) + gradient_vertex_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX, + GRADIENT_VERTEX_SHADER_DECLARATIONS, + GRADIENT_VERTEX_SHADER_CODE); - // BLEND TRANSITION - clutter_actor_set_opacity (CLUTTER_ACTOR (priv->top_actor), 0); - meta_background_set_layer (META_BACKGROUND (priv->top_actor), priv->background->texture); + cogl_pipeline_add_snippet (*templatep, gradient_vertex_snippet); - priv->transition_running = TRUE; + if (!gradient_fragment_snippet) + gradient_fragment_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, + GRADIENT_FRAGMENT_SHADER_DECLARATIONS, + GRADIENT_FRAGMENT_SHADER_CODE); - clutter_actor_save_easing_state (priv->top_actor); - clutter_actor_set_easing_duration (priv->top_actor, FADE_DURATION); - clutter_actor_set_opacity (priv->top_actor, 255); - clutter_actor_restore_easing_state (priv->top_actor); + cogl_pipeline_add_snippet (*templatep, gradient_fragment_snippet); + } - g_signal_connect (priv->top_actor, - "transitions-completed", - G_CALLBACK (on_transition_complete), - self); + if ((pipeline_flags & PIPELINE_BLEND) == 0) + cogl_pipeline_set_blend (*templatep, "RGBA = ADD (SRC_COLOR, 0)", NULL); + } - clutter_actor_queue_redraw (CLUTTER_ACTOR (self)); - } + return cogl_pipeline_copy (*templatep); } static void -set_texture (MetaScreenBackground *background, - CoglTexture *texture) +setup_pipeline (MetaBackgroundActor *self, + ClutterPaintContext *paint_context, + cairo_rectangle_int_t *actor_pixel_rect) { - MetaDisplay *display = meta_screen_get_display (background->screen); - GSList *l; - - /* This may trigger destruction of an old texture pixmap, which, if - * the underlying X pixmap is already gone has the tendency to trigger - * X errors inside DRI. For safety, trap errors */ - meta_error_trap_push (display); - if (background->texture != NULL) + PipelineFlags pipeline_flags = 0; + guint8 opacity; + float color_component; + CoglFramebuffer *fb; + CoglPipelineFilter min_filter, mag_filter; + + opacity = clutter_actor_get_paint_opacity (CLUTTER_ACTOR (self)); + if (opacity < 255) + pipeline_flags |= PIPELINE_BLEND; + if (self->vignette && clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL)) + pipeline_flags |= PIPELINE_VIGNETTE; + if (self->gradient && clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL)) + pipeline_flags |= PIPELINE_GRADIENT; + + if (self->pipeline && + pipeline_flags != self->pipeline_flags) { - cogl_object_unref (background->texture); - background->texture = NULL; + cogl_object_unref (self->pipeline); + self->pipeline = NULL; } - meta_error_trap_pop (display); - - if (texture != NULL) - background->texture = cogl_object_ref (texture); - background->texture_width = cogl_texture_get_width (background->texture); - background->texture_height = cogl_texture_get_height (background->texture); - - for (l = background->actors; l; l = l->next) - set_texture_on_actor (l->data); - - update_wrap_mode (background); -} + if (self->pipeline == NULL) + { + self->pipeline_flags = pipeline_flags; + self->pipeline = make_pipeline (pipeline_flags); + self->changed = CHANGED_ALL; + } -/* Sets our material to paint with a 1x1 texture of the stage's background - * color; doing this when we have no pixmap allows the application to turn - * off painting the stage. There might be a performance benefit to - * painting in this case with a solid color, but the normal solid color - * case is a 1x1 root pixmap, so we'd have to reverse-engineer that to - * actually pick up the (small?) performance win. This is just a fallback. - */ -static void -set_texture_to_stage_color (MetaScreenBackground *background) -{ - ClutterActor *stage = meta_get_stage_for_screen (background->screen); - ClutterColor color; - CoglTexture *texture; - - clutter_actor_get_background_color (stage, &color); - - /* Slicing will prevent COGL from using hardware texturing for - * the tiled 1x1 pixmap, and will cause it to draw the window - * background in millions of separate 1x1 rectangles */ - texture = meta_create_color_texture_4ub (color.red, color.green, - color.blue, 0xff, - COGL_TEXTURE_NO_SLICING); - set_texture (background, texture); - cogl_object_unref (texture); -} + if ((self->changed & CHANGED_BACKGROUND) != 0) + { + CoglPipelineWrapMode wrap_mode; + CoglTexture *texture = meta_background_get_texture (self->background, + self->monitor, + &self->texture_area, + &wrap_mode); + self->force_bilinear = texture && + (self->texture_area.width != (int)cogl_texture_get_width (texture) || + self->texture_area.height != (int)cogl_texture_get_height (texture)); + + cogl_pipeline_set_layer_texture (self->pipeline, 0, texture); + cogl_pipeline_set_layer_wrap_mode (self->pipeline, 0, wrap_mode); + + self->changed &= ~CHANGED_BACKGROUND; + } -static void -meta_background_actor_dispose (GObject *object) -{ - MetaBackgroundActor *self = META_BACKGROUND_ACTOR (object); - MetaBackgroundActorPrivate *priv = self->priv; + if ((self->changed & CHANGED_VIGNETTE_PARAMETERS) != 0) + { + cogl_pipeline_set_uniform_1f (self->pipeline, + cogl_pipeline_get_uniform_location (self->pipeline, + "vignette_sharpness"), + self->vignette_sharpness); - meta_background_actor_set_visible_region (self, NULL); + self->changed &= ~CHANGED_VIGNETTE_PARAMETERS; + } - if (priv->background != NULL) + if ((self->changed & CHANGED_GRADIENT_PARAMETERS) != 0) { - priv->background->actors = g_slist_remove (priv->background->actors, self); - priv->background = NULL; + MetaRectangle monitor_geometry; + float gradient_height_perc; + + meta_display_get_monitor_geometry (self->display, + self->monitor, &monitor_geometry); + gradient_height_perc = MAX (0.0001, self->gradient_height / (float)monitor_geometry.height); + cogl_pipeline_set_uniform_1f (self->pipeline, + cogl_pipeline_get_uniform_location (self->pipeline, + "gradient_height_perc"), + gradient_height_perc); + cogl_pipeline_set_uniform_1f (self->pipeline, + cogl_pipeline_get_uniform_location (self->pipeline, + "gradient_max_darkness"), + self->gradient_max_darkness); + + self->changed &= ~CHANGED_GRADIENT_PARAMETERS; } - if (priv->top_actor != NULL) - priv->top_actor = NULL; + if (self->vignette) + { + color_component = self->vignette_brightness * opacity / 255.; - if (priv->bottom_actor != NULL) - priv->bottom_actor = NULL; + if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL)) + { + /* Darken everything to match the average brightness that would + * be there if we were drawing the vignette, which is + * (1 - (pi/12.) * vignette_sharpness) [exercise for the reader :] + */ + color_component *= (1 - 0.74 * self->vignette_sharpness); + } + } + else + color_component = opacity / 255.; + + cogl_pipeline_set_color4f (self->pipeline, + color_component, + color_component, + color_component, + opacity / 255.); + + fb = clutter_paint_context_get_framebuffer (paint_context); + if (!self->force_bilinear && + meta_actor_painting_untransformed (fb, + actor_pixel_rect->width, + actor_pixel_rect->height, + actor_pixel_rect->width, + actor_pixel_rect->height, + NULL, NULL)) + { + min_filter = COGL_PIPELINE_FILTER_NEAREST; + mag_filter = COGL_PIPELINE_FILTER_NEAREST; + } + else + { + min_filter = COGL_PIPELINE_FILTER_LINEAR_MIPMAP_NEAREST; + mag_filter = COGL_PIPELINE_FILTER_LINEAR; + } - G_OBJECT_CLASS (meta_background_actor_parent_class)->dispose (object); + cogl_pipeline_set_layer_filters (self->pipeline, 0, min_filter, mag_filter); } static void -meta_background_actor_get_preferred_width (ClutterActor *actor, - gfloat for_height, - gfloat *min_width_p, - gfloat *natural_width_p) +set_glsl_parameters (MetaBackgroundActor *self, + cairo_rectangle_int_t *actor_pixel_rect) { - MetaBackgroundActor *self = META_BACKGROUND_ACTOR (actor); - MetaBackgroundActorPrivate *priv = self->priv; - int width, height; - - meta_screen_get_size (priv->background->screen, &width, &height); + float scale[2]; + float offset[2]; - if (min_width_p) - *min_width_p = width; - if (natural_width_p) - *natural_width_p = width; + /* Compute a scale and offset for transforming texture coordinates to the + * coordinate system from [-0.5 to 0.5] across the area of the actor + */ + scale[0] = self->texture_area.width / (float)actor_pixel_rect->width; + scale[1] = self->texture_area.height / (float)actor_pixel_rect->height; + offset[0] = self->texture_area.x / (float)actor_pixel_rect->width - 0.5; + offset[1] = self->texture_area.y / (float)actor_pixel_rect->height - 0.5; + + cogl_pipeline_set_uniform_float (self->pipeline, + cogl_pipeline_get_uniform_location (self->pipeline, + "scale"), + 2, 1, scale); + + cogl_pipeline_set_uniform_float (self->pipeline, + cogl_pipeline_get_uniform_location (self->pipeline, + "offset"), + 2, 1, offset); } static void -meta_background_actor_get_preferred_height (ClutterActor *actor, - gfloat for_width, - gfloat *min_height_p, - gfloat *natural_height_p) - +paint_clipped_rectangle (CoglFramebuffer *fb, + CoglPipeline *pipeline, + cairo_rectangle_int_t *rect, + cairo_rectangle_int_t *texture_area) { - MetaBackgroundActor *self = META_BACKGROUND_ACTOR (actor); - MetaBackgroundActorPrivate *priv = self->priv; - int width, height; - - meta_screen_get_size (priv->background->screen, &width, &height); - - if (min_height_p) - *min_height_p = height; - if (natural_height_p) - *natural_height_p = height; + float x1, y1, x2, y2; + float tx1, ty1, tx2, ty2; + + x1 = rect->x; + y1 = rect->y; + x2 = rect->x + rect->width; + y2 = rect->y + rect->height; + + tx1 = (x1 - texture_area->x) / texture_area->width; + ty1 = (y1 - texture_area->y) / texture_area->height; + tx2 = (x2 - texture_area->x) / texture_area->width; + ty2 = (y2 - texture_area->y) / texture_area->height; + + cogl_framebuffer_draw_textured_rectangle (fb, pipeline, + x1, y1, x2, y2, + tx1, ty1, tx2, ty2); } static gboolean meta_background_actor_get_paint_volume (ClutterActor *actor, ClutterPaintVolume *volume) { - MetaBackgroundActor *self = META_BACKGROUND_ACTOR (actor); - MetaBackgroundActorPrivate *priv = self->priv; - int width, height; - - meta_screen_get_size (priv->background->screen, &width, &height); - - clutter_paint_volume_set_width (volume, width); - clutter_paint_volume_set_height (volume, height); - - return TRUE; + return clutter_paint_volume_set_from_allocation (volume, actor); } static void -meta_background_actor_set_dim_factor (MetaBackgroundActor *self, - gfloat dim_factor) +meta_background_actor_paint (ClutterActor *actor, + ClutterPaintContext *paint_context) { - MetaBackgroundActorPrivate *priv = self->priv; + MetaBackgroundActor *self = META_BACKGROUND_ACTOR (actor); + ClutterActorBox actor_box; + cairo_rectangle_int_t actor_pixel_rect; + CoglFramebuffer *fb; + cairo_region_t *region; + int i, n_rects; - if (priv->dim_factor == dim_factor) + if ((self->clip_region && cairo_region_is_empty (self->clip_region))) return; - priv->dim_factor = dim_factor; + clutter_actor_get_content_box (actor, &actor_box); + actor_pixel_rect.x = actor_box.x1; + actor_pixel_rect.y = actor_box.y1; + actor_pixel_rect.width = actor_box.x2 - actor_box.x1; + actor_pixel_rect.height = actor_box.y2 - actor_box.y1; - clutter_actor_queue_redraw (CLUTTER_ACTOR (self)); + setup_pipeline (self, paint_context, &actor_pixel_rect); + set_glsl_parameters (self, &actor_pixel_rect); - g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_DIM_FACTOR]); + /* Limit to how many separate rectangles we'll draw; beyond this just + * fall back and draw the whole thing */ +#define MAX_RECTS 64 + + fb = clutter_paint_context_get_framebuffer (paint_context); + + /* Now figure out what to actually paint. + */ + if (self->clip_region) + { + region = cairo_region_copy (self->clip_region); + cairo_region_intersect_rectangle (region, &actor_pixel_rect); + } + else + { + region = cairo_region_create_rectangle (&actor_pixel_rect); + } + + if (self->unobscured_region) + cairo_region_intersect (region, self->unobscured_region); + + if (cairo_region_is_empty (region)) + { + cairo_region_destroy (region); + return; + } + + n_rects = cairo_region_num_rectangles (region); + if (n_rects <= MAX_RECTS) + { + for (i = 0; i < n_rects; i++) + { + cairo_rectangle_int_t rect; + cairo_region_get_rectangle (region, i, &rect); + paint_clipped_rectangle (fb, self->pipeline, &rect, + &self->texture_area); + } + } + else + { + cairo_rectangle_int_t rect; + cairo_region_get_extents (region, &rect); + paint_clipped_rectangle (fb, self->pipeline, &rect, + &self->texture_area); + } + + cairo_region_destroy (region); } static void -meta_background_actor_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) +meta_background_actor_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) { MetaBackgroundActor *self = META_BACKGROUND_ACTOR (object); - MetaBackgroundActorPrivate *priv = self->priv; switch (prop_id) { - case PROP_DIM_FACTOR: - g_value_set_float (value, priv->dim_factor); + case PROP_META_DISPLAY: + self->display = g_value_get_object (value); + break; + case PROP_MONITOR: + meta_background_actor_set_monitor (self, g_value_get_int (value)); + break; + case PROP_BACKGROUND: + meta_background_actor_set_background (self, g_value_get_object (value)); + break; + case PROP_GRADIENT: + meta_background_actor_set_gradient (self, + g_value_get_boolean (value), + self->gradient_height, + self->gradient_max_darkness); + break; + case PROP_GRADIENT_HEIGHT: + meta_background_actor_set_gradient (self, + self->gradient, + g_value_get_int (value), + self->gradient_max_darkness); + break; + case PROP_GRADIENT_MAX_DARKNESS: + meta_background_actor_set_gradient (self, + self->gradient, + self->gradient_height, + g_value_get_double (value)); + break; + case PROP_VIGNETTE: + meta_background_actor_set_vignette (self, + g_value_get_boolean (value), + self->vignette_brightness, + self->vignette_sharpness); + break; + case PROP_VIGNETTE_SHARPNESS: + meta_background_actor_set_vignette (self, + self->vignette, + self->vignette_brightness, + g_value_get_double (value)); + break; + case PROP_VIGNETTE_BRIGHTNESS: + meta_background_actor_set_vignette (self, + self->vignette, + g_value_get_double (value), + self->vignette_sharpness); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -426,17 +659,41 @@ meta_background_actor_get_property (GObject *object, } static void -meta_background_actor_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) +meta_background_actor_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) { MetaBackgroundActor *self = META_BACKGROUND_ACTOR (object); switch (prop_id) { - case PROP_DIM_FACTOR: - meta_background_actor_set_dim_factor (self, g_value_get_float (value)); + case PROP_META_DISPLAY: + g_value_set_object (value, self->display); + break; + case PROP_MONITOR: + g_value_set_int (value, self->monitor); + break; + case PROP_BACKGROUND: + g_value_set_object (value, self->background); + break; + case PROP_GRADIENT: + g_value_set_boolean (value, self->gradient); + break; + case PROP_GRADIENT_HEIGHT: + g_value_set_int (value, self->gradient_height); + break; + case PROP_GRADIENT_MAX_DARKNESS: + g_value_set_double (value, self->gradient_max_darkness); + break; + case PROP_VIGNETTE: + g_value_set_boolean (value, self->vignette); + break; + case PROP_VIGNETTE_BRIGHTNESS: + g_value_set_double (value, self->vignette_brightness); + break; + case PROP_VIGNETTE_SHARPNESS: + g_value_set_double (value, self->vignette_sharpness); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -449,189 +706,309 @@ meta_background_actor_class_init (MetaBackgroundActorClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); - GParamSpec *pspec; - - g_type_class_add_private (klass, sizeof (MetaBackgroundActorPrivate)); + GParamSpec *param_spec; object_class->dispose = meta_background_actor_dispose; - object_class->get_property = meta_background_actor_get_property; object_class->set_property = meta_background_actor_set_property; + object_class->get_property = meta_background_actor_get_property; actor_class->get_preferred_width = meta_background_actor_get_preferred_width; actor_class->get_preferred_height = meta_background_actor_get_preferred_height; actor_class->get_paint_volume = meta_background_actor_get_paint_volume; - - /** - * MetaBackgroundActor:dim-factor: - * - * Factor to dim the background by, between 0.0 (black) and 1.0 (original - * colors) - */ - pspec = g_param_spec_float ("dim-factor", - "Dim factor", - "Factor to dim the background by", - 0.0, 1.0, - 1.0, - G_PARAM_READWRITE); - obj_props[PROP_DIM_FACTOR] = pspec; - g_object_class_install_property (object_class, PROP_DIM_FACTOR, pspec); + actor_class->paint = meta_background_actor_paint; + + param_spec = g_param_spec_object ("meta-display", + "MetaDisplay", + "MetaDisplay", + META_TYPE_DISPLAY, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + + g_object_class_install_property (object_class, + PROP_META_DISPLAY, + param_spec); + + param_spec = g_param_spec_int ("monitor", + "monitor", + "monitor", + 0, G_MAXINT, 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + + g_object_class_install_property (object_class, + PROP_MONITOR, + param_spec); + + param_spec = g_param_spec_object ("background", + "Background", + "MetaBackground object holding background parameters", + META_TYPE_BACKGROUND, + G_PARAM_READWRITE); + + g_object_class_install_property (object_class, + PROP_BACKGROUND, + param_spec); + + param_spec = g_param_spec_boolean ("gradient", + "Gradient", + "Whether gradient effect is enabled", + FALSE, + G_PARAM_READWRITE); + + g_object_class_install_property (object_class, + PROP_GRADIENT, + param_spec); + + param_spec = g_param_spec_int ("gradient-height", + "Gradient Height", + "Height of gradient effect", + 0, G_MAXINT, 0, + G_PARAM_READWRITE); + + g_object_class_install_property (object_class, + PROP_GRADIENT_HEIGHT, + param_spec); + + param_spec = g_param_spec_double ("gradient-max-darkness", + "Gradient Max Darkness", + "How dark is the gradient initially", + 0.0, 1.0, 0.0, + G_PARAM_READWRITE); + + g_object_class_install_property (object_class, + PROP_GRADIENT_MAX_DARKNESS, + param_spec); + + param_spec = g_param_spec_boolean ("vignette", + "Vignette", + "Whether vignette effect is enabled", + FALSE, + G_PARAM_READWRITE); + + g_object_class_install_property (object_class, + PROP_VIGNETTE, + param_spec); + + param_spec = g_param_spec_double ("brightness", + "Vignette Brightness", + "Brightness of vignette effect", + 0.0, 1.0, 1.0, + G_PARAM_READWRITE); + + g_object_class_install_property (object_class, + PROP_VIGNETTE_BRIGHTNESS, + param_spec); + + param_spec = g_param_spec_double ("vignette-sharpness", + "Vignette Sharpness", + "Sharpness of vignette effect", + 0.0, G_MAXDOUBLE, 0.0, + G_PARAM_READWRITE); + + g_object_class_install_property (object_class, + PROP_VIGNETTE_SHARPNESS, + param_spec); } static void meta_background_actor_init (MetaBackgroundActor *self) { - MetaBackgroundActorPrivate *priv; + self->gradient = FALSE; + self->gradient_height = 0; + self->gradient_max_darkness = 0.0; - priv = self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, - META_TYPE_BACKGROUND_ACTOR, - MetaBackgroundActorPrivate); - priv->dim_factor = 1.0; - priv->transition_running = FALSE; + self->vignette = FALSE; + self->vignette_brightness = 1.0; + self->vignette_sharpness = 0.0; } /** - * meta_background_actor_new_for_screen: - * @screen: the #MetaScreen + * meta_background_actor_new: + * @monitor: Index of the monitor for which to draw the background * - * Creates a new actor to draw the background for the given screen. + * Creates a new actor to draw the background for the given monitor. * * Return value: the newly created background actor */ ClutterActor * -meta_background_actor_new_for_screen (MetaScreen *screen) +meta_background_actor_new (MetaDisplay *display, + int monitor) { MetaBackgroundActor *self; - MetaBackgroundActorPrivate *priv; - g_return_val_if_fail (META_IS_SCREEN (screen), NULL); + self = g_object_new (META_TYPE_BACKGROUND_ACTOR, + "meta-display", display, + "monitor", monitor, + NULL); - self = g_object_new (META_TYPE_BACKGROUND_ACTOR, NULL); - priv = self->priv; + return CLUTTER_ACTOR (self); +} - priv->background = meta_screen_background_get (screen); - priv->background->actors = g_slist_prepend (priv->background->actors, self); +static void +meta_background_actor_cull_out (MetaCullable *cullable, + cairo_region_t *unobscured_region, + cairo_region_t *clip_region) +{ + MetaBackgroundActor *self = META_BACKGROUND_ACTOR (cullable); - priv->bottom_actor = meta_background_new (screen); - clutter_actor_add_child (CLUTTER_ACTOR (self), priv->bottom_actor); - priv->top_actor = meta_background_new (screen); - clutter_actor_add_child (CLUTTER_ACTOR (self), priv->top_actor); + set_unobscured_region (self, unobscured_region); + set_clip_region (self, clip_region); +} + +static void +meta_background_actor_reset_culling (MetaCullable *cullable) +{ + MetaBackgroundActor *self = META_BACKGROUND_ACTOR (cullable); - set_texture_on_actors (self); - update_wrap_mode_of_actor (self); + set_unobscured_region (self, NULL); + set_clip_region (self, NULL); +} - return CLUTTER_ACTOR (self); +static void +cullable_iface_init (MetaCullableInterface *iface) +{ + iface->cull_out = meta_background_actor_cull_out; + iface->reset_culling = meta_background_actor_reset_culling; } /** - * meta_background_actor_update: - * @screen: a #MetaScreen + * meta_background_actor_get_clip_region: + * @self: a #MetaBackgroundActor * - * Refetches the _XROOTPMAP_ID property for the root window and updates - * the contents of the background actor based on that. There's no attempt - * to optimize out pixmap values that don't change (since a root pixmap - * could be replaced by with another pixmap with the same ID under some - * circumstances), so this should only be called when we actually receive - * a PropertyNotify event for the property. + * Return value (transfer none): a #cairo_region_t that represents the part of + * the background not obscured by other #MetaBackgroundActor or + * #MetaWindowActor objects. */ -LOCAL_SYMBOL void -meta_background_actor_update (MetaScreen *screen) +cairo_region_t * +meta_background_actor_get_clip_region (MetaBackgroundActor *self) { - MetaScreenBackground *background; - MetaDisplay *display; - MetaCompositor *compositor; - Atom type; - int format; - gulong nitems; - gulong bytes_after; - guchar *data; - Pixmap root_pixmap_id; - - background = meta_screen_background_get (screen); - display = meta_screen_get_display (screen); - compositor = meta_display_get_compositor (display); - - root_pixmap_id = None; - if (!XGetWindowProperty (meta_display_get_xdisplay (display), - meta_screen_get_xroot (screen), - compositor->atom_x_root_pixmap, - 0, LONG_MAX, - False, - AnyPropertyType, - &type, &format, &nitems, &bytes_after, &data) && - type != None) - { - /* Got a property. */ - if (type == XA_PIXMAP && format == 32 && nitems == 1) - { - /* Was what we expected. */ - root_pixmap_id = *(Pixmap *)data; - } + return self->clip_region; +} + +static void +invalidate_pipeline (MetaBackgroundActor *self, + ChangedFlags changed) +{ + self->changed |= changed; +} - XFree(data); +static void +on_background_changed (MetaBackground *background, + MetaBackgroundActor *self) +{ + invalidate_pipeline (self, CHANGED_BACKGROUND); + clutter_actor_queue_redraw (CLUTTER_ACTOR (self)); +} + +void +meta_background_actor_set_background (MetaBackgroundActor *self, + MetaBackground *background) +{ + g_return_if_fail (META_IS_BACKGROUND_ACTOR (self)); + g_return_if_fail (background == NULL || META_IS_BACKGROUND (background)); + + if (background == self->background) + return; + + if (self->background) + { + g_signal_handlers_disconnect_by_func (self->background, + (gpointer)on_background_changed, + self); + g_object_unref (self->background); + self->background = NULL; } - if (root_pixmap_id != None) + if (background) { - CoglHandle texture; - GError *error = NULL; + self->background = g_object_ref (background); + g_signal_connect (self->background, "changed", + G_CALLBACK (on_background_changed), self); + } - meta_error_trap_push (display); - texture = cogl_texture_pixmap_x11_new (compositor->context, root_pixmap_id, FALSE, &error); - meta_error_trap_pop (display); + invalidate_pipeline (self, CHANGED_BACKGROUND); + clutter_actor_queue_redraw (CLUTTER_ACTOR (self)); +} - if (texture != NULL) - { - set_texture (background, texture); - cogl_object_unref (texture); +void +meta_background_actor_set_gradient (MetaBackgroundActor *self, + gboolean enabled, + int height, + double max_darkness) +{ + gboolean changed = FALSE; - background->have_pixmap = True; - return; - } - else - { - g_warning ("Failed to create background texture from pixmap: %s", - error->message); - g_error_free (error); - } + g_return_if_fail (META_IS_BACKGROUND_ACTOR (self)); + g_return_if_fail (height >= 0); + g_return_if_fail (max_darkness >= 0. && max_darkness <= 1.); + + enabled = enabled != FALSE && height != 0; + + if (enabled != self->gradient) + { + self->gradient = enabled; + invalidate_pipeline (self, CHANGED_EFFECTS); + changed = TRUE; } - background->have_pixmap = False; - set_texture_to_stage_color (background); + if (height != self->gradient_height || max_darkness != self->gradient_max_darkness) + { + self->gradient_height = height; + self->gradient_max_darkness = max_darkness; + invalidate_pipeline (self, CHANGED_GRADIENT_PARAMETERS); + changed = TRUE; + } + + if (changed) + clutter_actor_queue_redraw (CLUTTER_ACTOR (self)); } -/** - * meta_background_actor_set_visible_region: - * @self: a #MetaBackgroundActor - * @visible_region: (allow-none): the area of the actor (in allocate-relative - * coordinates) that is visible. - * - * Sets the area of the background that is unobscured by overlapping windows. - * This is used to optimize and only paint the visible portions. - */ -LOCAL_SYMBOL void -meta_background_actor_set_visible_region (MetaBackgroundActor *self, - cairo_region_t *visible_region) +void +meta_background_actor_set_monitor (MetaBackgroundActor *self, + int monitor) { - MetaBackgroundActorPrivate *priv; + MetaRectangle old_monitor_geometry; + MetaRectangle new_monitor_geometry; + MetaDisplay *display = self->display; - g_return_if_fail (META_IS_BACKGROUND_ACTOR (self)); + if(self->monitor == monitor) + return; - priv = self->priv; + meta_display_get_monitor_geometry (display, self->monitor, &old_monitor_geometry); + meta_display_get_monitor_geometry (display, monitor, &new_monitor_geometry); + if(old_monitor_geometry.height != new_monitor_geometry.height) + invalidate_pipeline (self, CHANGED_GRADIENT_PARAMETERS); - if (priv->top_actor != NULL) - meta_background_set_visible_region (META_BACKGROUND (priv->top_actor), visible_region); + self->monitor = monitor; } -/** - * meta_background_actor_screen_size_changed: - * @screen: a #MetaScreen - * - * Called by the compositor when the size of the #MetaScreen changes - */ -LOCAL_SYMBOL void -meta_background_actor_screen_size_changed (MetaScreen *screen) +void +meta_background_actor_set_vignette (MetaBackgroundActor *self, + gboolean enabled, + double brightness, + double sharpness) { - MetaScreenBackground *background = meta_screen_background_get (screen); + gboolean changed = FALSE; + + g_return_if_fail (META_IS_BACKGROUND_ACTOR (self)); + g_return_if_fail (brightness >= 0. && brightness <= 1.); + g_return_if_fail (sharpness >= 0.); + + enabled = enabled != FALSE; - update_wrap_mode (background); + if (enabled != self->vignette) + { + self->vignette = enabled; + invalidate_pipeline (self, CHANGED_EFFECTS); + changed = TRUE; + } + + if (brightness != self->vignette_brightness || sharpness != self->vignette_sharpness) + { + self->vignette_brightness = brightness; + self->vignette_sharpness = sharpness; + invalidate_pipeline (self, CHANGED_VIGNETTE_PARAMETERS); + changed = TRUE; + } + + if (changed) + clutter_actor_queue_redraw (CLUTTER_ACTOR (self)); } diff --git a/src/compositor/meta-background-group.c b/src/compositor/meta-background-group.c new file mode 100644 index 000000000..e30b8af4c --- /dev/null +++ b/src/compositor/meta-background-group.c @@ -0,0 +1,66 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/** + * SECTION:meta-background-group + * @title: MetaBackgroundGroup + * @short_description: Container for background actors + * + * This class is a subclass of ClutterActor with special handling for + * MetaBackgroundActor/MetaBackgroundGroup when painting children. + * It makes sure to only draw the parts of the backgrounds not + * occluded by opaque windows. + * + * See #MetaWindowGroup for more information behind the motivation, + * and details on implementation. + */ + +#include "config.h" + +#include "compositor/meta-cullable.h" +#include "meta/meta-background-group.h" + +static void cullable_iface_init (MetaCullableInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (MetaBackgroundGroup, meta_background_group, CLUTTER_TYPE_ACTOR, + G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init)); + +static void +meta_background_group_class_init (MetaBackgroundGroupClass *klass) +{ +} + +static void +meta_background_group_cull_out (MetaCullable *cullable, + cairo_region_t *unobscured_region, + cairo_region_t *clip_region) +{ + meta_cullable_cull_out_children (cullable, unobscured_region, clip_region); +} + +static void +meta_background_group_reset_culling (MetaCullable *cullable) +{ + meta_cullable_reset_culling_children (cullable); +} + +static void +cullable_iface_init (MetaCullableInterface *iface) +{ + iface->cull_out = meta_background_group_cull_out; + iface->reset_culling = meta_background_group_reset_culling; +} + +static void +meta_background_group_init (MetaBackgroundGroup *self) +{ +} + +ClutterActor * +meta_background_group_new (void) +{ + MetaBackgroundGroup *background_group; + + background_group = g_object_new (META_TYPE_BACKGROUND_GROUP, NULL); + + return CLUTTER_ACTOR (background_group); +} diff --git a/src/compositor/meta-background-image.c b/src/compositor/meta-background-image.c new file mode 100644 index 000000000..a29e74380 --- /dev/null +++ b/src/compositor/meta-background-image.c @@ -0,0 +1,370 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * Copyright 2014 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +/** + * SECTION:meta-background-image + * @title: MetaBackgroundImage + * @short_description: objects holding images loaded from files, used for backgrounds + */ + +#include "config.h" + +#include "meta/meta-background-image.h" + +#include <gdk-pixbuf/gdk-pixbuf.h> +#include <gio/gio.h> + +#include "clutter/clutter.h" +#include "compositor/cogl-utils.h" + +enum +{ + LOADED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +/** + * MetaBackgroundImageCache: + * + * #MetaBackgroundImageCache caches loading of textures for backgrounds; there's actually + * nothing background specific about it, other than it is tuned to work well for + * large images as typically are used for backgrounds. + */ +struct _MetaBackgroundImageCache +{ + GObject parent_instance; + + GHashTable *images; +}; + +/** + * MetaBackgroundImage: + * + * #MetaBackgroundImage is an object that represents a loaded or loading background image. + */ +struct _MetaBackgroundImage +{ + GObject parent_instance; + GFile *file; + MetaBackgroundImageCache *cache; + gboolean in_cache; + gboolean loaded; + CoglTexture *texture; +}; + +G_DEFINE_TYPE (MetaBackgroundImageCache, meta_background_image_cache, G_TYPE_OBJECT); + +static void +meta_background_image_cache_init (MetaBackgroundImageCache *cache) +{ + cache->images = g_hash_table_new (g_file_hash, (GEqualFunc) g_file_equal); +} + +static void +meta_background_image_cache_finalize (GObject *object) +{ + MetaBackgroundImageCache *cache = META_BACKGROUND_IMAGE_CACHE (object); + GHashTableIter iter; + gpointer key, value; + + g_hash_table_iter_init (&iter, cache->images); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + MetaBackgroundImage *image = value; + image->in_cache = FALSE; + } + + g_hash_table_destroy (cache->images); + + G_OBJECT_CLASS (meta_background_image_cache_parent_class)->finalize (object); +} + +static void +meta_background_image_cache_class_init (MetaBackgroundImageCacheClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_background_image_cache_finalize; +} + +/** + * meta_background_image_cache_get_default: + * + * Return value: (transfer none): the global singleton background cache + */ +MetaBackgroundImageCache * +meta_background_image_cache_get_default (void) +{ + static MetaBackgroundImageCache *cache; + + if (cache == NULL) + cache = g_object_new (META_TYPE_BACKGROUND_IMAGE_CACHE, NULL); + + return cache; +} + +static void +load_file (GTask *task, + MetaBackgroundImage *image, + gpointer task_data, + GCancellable *cancellable) +{ + GError *error = NULL; + GdkPixbuf *pixbuf; + GFileInputStream *stream; + + stream = g_file_read (image->file, NULL, &error); + if (stream == NULL) + { + g_task_return_error (task, error); + return; + } + + pixbuf = gdk_pixbuf_new_from_stream (G_INPUT_STREAM (stream), NULL, &error); + g_object_unref (stream); + + if (pixbuf == NULL) + { + g_task_return_error (task, error); + return; + } + + g_task_return_pointer (task, pixbuf, (GDestroyNotify) g_object_unref); +} + +static void +file_loaded (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + MetaBackgroundImage *image = META_BACKGROUND_IMAGE (source_object); + GError *error = NULL; + GError *catch_error = NULL; + GTask *task; + CoglTexture *texture; + GdkPixbuf *pixbuf, *rotated; + int width, height, row_stride; + guchar *pixels; + gboolean has_alpha; + + task = G_TASK (result); + pixbuf = g_task_propagate_pointer (task, &error); + + if (pixbuf == NULL) + { + char *uri = g_file_get_uri (image->file); + g_warning ("Failed to load background '%s': %s", + uri, error->message); + g_clear_error (&error); + g_free (uri); + goto out; + } + + rotated = gdk_pixbuf_apply_embedded_orientation (pixbuf); + if (rotated != NULL) + { + g_object_unref (pixbuf); + pixbuf = rotated; + } + + width = gdk_pixbuf_get_width (pixbuf); + height = gdk_pixbuf_get_height (pixbuf); + row_stride = gdk_pixbuf_get_rowstride (pixbuf); + pixels = gdk_pixbuf_get_pixels (pixbuf); + has_alpha = gdk_pixbuf_get_has_alpha (pixbuf); + + texture = meta_create_texture (width, height, + has_alpha ? COGL_TEXTURE_COMPONENTS_RGBA : COGL_TEXTURE_COMPONENTS_RGB, + META_TEXTURE_ALLOW_SLICING); + + if (!cogl_texture_set_data (texture, + has_alpha ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888, + row_stride, + pixels, 0, + &catch_error)) + { + g_warning ("Failed to create texture for background"); + g_error_free (catch_error); + cogl_object_unref (texture); + } + + image->texture = texture; + +out: + if (pixbuf != NULL) + g_object_unref (pixbuf); + + image->loaded = TRUE; + g_signal_emit (image, signals[LOADED], 0); +} + +/** + * meta_background_image_cache_load: + * @cache: a #MetaBackgroundImageCache + * @file: #GFile to load + * + * Loads an image to use as a background, or returns a reference to an + * image that is already in the process of loading or loaded. In either + * case, what is returned is a #MetaBackgroundImage which can be derefenced + * to get a #CoglTexture. If meta_background_image_is_loaded() returns %TRUE, + * the background is loaded, otherwise the MetaBackgroundImage::loaded + * signal will be emitted exactly once. The 'loaded' state means that the + * loading process finished, whether it succeeded or failed. + * + * Return value: (transfer full): a #MetaBackgroundImage to dereference to get the loaded texture + */ +MetaBackgroundImage * +meta_background_image_cache_load (MetaBackgroundImageCache *cache, + GFile *file) +{ + MetaBackgroundImage *image; + GTask *task; + + g_return_val_if_fail (META_IS_BACKGROUND_IMAGE_CACHE (cache), NULL); + g_return_val_if_fail (file != NULL, NULL); + + image = g_hash_table_lookup (cache->images, file); + if (image != NULL) + return g_object_ref (image); + + image = g_object_new (META_TYPE_BACKGROUND_IMAGE, NULL); + image->cache = cache; + image->in_cache = TRUE; + image->file = g_object_ref (file); + g_hash_table_insert (cache->images, image->file, image); + + task = g_task_new (image, NULL, file_loaded, NULL); + + g_task_run_in_thread (task, (GTaskThreadFunc) load_file); + g_object_unref (task); + + return image; +} + +/** + * meta_background_image_cache_purge: + * @cache: a #MetaBackgroundImageCache + * @file: file to remove from the cache + * + * Remove an entry from the cache; this would be used if monitoring + * showed that the file changed. + */ +void +meta_background_image_cache_purge (MetaBackgroundImageCache *cache, + GFile *file) +{ + MetaBackgroundImage *image; + + g_return_if_fail (META_IS_BACKGROUND_IMAGE_CACHE (cache)); + g_return_if_fail (file != NULL); + + image = g_hash_table_lookup (cache->images, file); + if (image == NULL) + return; + + g_hash_table_remove (cache->images, image->file); + image->in_cache = FALSE; +} + +G_DEFINE_TYPE (MetaBackgroundImage, meta_background_image, G_TYPE_OBJECT); + +static void +meta_background_image_init (MetaBackgroundImage *image) +{ +} + +static void +meta_background_image_finalize (GObject *object) +{ + MetaBackgroundImage *image = META_BACKGROUND_IMAGE (object); + + if (image->in_cache) + g_hash_table_remove (image->cache->images, image->file); + + if (image->texture) + cogl_object_unref (image->texture); + if (image->file) + g_object_unref (image->file); + + G_OBJECT_CLASS (meta_background_image_parent_class)->finalize (object); +} + +static void +meta_background_image_class_init (MetaBackgroundImageClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_background_image_finalize; + + signals[LOADED] = + g_signal_new ("loaded", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); +} + +/** + * meta_background_image_is_loaded: + * @image: a #MetaBackgroundImage + * + * Return value: %TRUE if loading has already completed, %FALSE otherwise + */ +gboolean +meta_background_image_is_loaded (MetaBackgroundImage *image) +{ + g_return_val_if_fail (META_IS_BACKGROUND_IMAGE (image), FALSE); + + return image->loaded; +} + +/** + * meta_background_image_get_success: + * @image: a #MetaBackgroundImage + * + * This function is a convenience function for checking for success, + * without having to call meta_background_image_get_texture() and + * handle the return of a Cogl type. + * + * Return value: %TRUE if loading completed successfully, otherwise %FALSE + */ +gboolean +meta_background_image_get_success (MetaBackgroundImage *image) +{ + g_return_val_if_fail (META_IS_BACKGROUND_IMAGE (image), FALSE); + + return image->texture != NULL; +} + +/** + * meta_background_image_get_texture: + * @image: a #MetaBackgroundImage + * + * Return value: (transfer none): a #CoglTexture if loading succeeded; if + * loading failed or has not yet finished, %NULL. + */ +CoglTexture * +meta_background_image_get_texture (MetaBackgroundImage *image) +{ + g_return_val_if_fail (META_IS_BACKGROUND_IMAGE (image), NULL); + + return image->texture; +} diff --git a/src/compositor/meta-background-private.h b/src/compositor/meta-background-private.h new file mode 100644 index 000000000..871487da4 --- /dev/null +++ b/src/compositor/meta-background-private.h @@ -0,0 +1,14 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +#ifndef META_BACKGROUND_PRIVATE_H +#define META_BACKGROUND_PRIVATE_H + +#include "cogl/cogl.h" +#include "meta/meta-background.h" + +CoglTexture *meta_background_get_texture (MetaBackground *self, + int monitor_index, + cairo_rectangle_int_t *texture_area, + CoglPipelineWrapMode *wrap_mode); + +#endif /* META_BACKGROUND_PRIVATE_H */ diff --git a/src/compositor/meta-background.c b/src/compositor/meta-background.c index 33bce084d..e02d40a61 100644 --- a/src/compositor/meta-background.c +++ b/src/compositor/meta-background.c @@ -1,8 +1,7 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + /* - * meta-background.c: Actor used to create a background fade effect - * - * Copyright 2016 Linux Mint + * Copyright 2013 Red Hat, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -15,241 +14,1025 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. - * - * Portions adapted from gnome-shell/src/shell-global.c - * and meta-window-actor.c + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #include "config.h" -#include <clutter/clutter.h> -#include "cogl-utils.h" -#include <meta/errors.h> -// #include "util-private.h" -#include "meta-background-actor-private.h" +#include "compositor/meta-background-private.h" + +#include <string.h> + +#include "backends/meta-backend-private.h" +#include "compositor/cogl-utils.h" +#include "meta/display.h" +#include "meta/meta-background-image.h" +#include "meta/meta-background.h" +#include "meta/meta-monitor-manager.h" +#include "meta/util.h" -struct _MetaBackgroundPrivate +enum { - MetaScreen *screen; - CoglPipeline *pipeline; + CHANGED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +typedef struct _MetaBackgroundMonitor MetaBackgroundMonitor; - float texture_width; - float texture_height; +struct _MetaBackgroundMonitor +{ + gboolean dirty; + CoglTexture *texture; + CoglFramebuffer *fbo; +}; + +struct _MetaBackground +{ + GObject parent; + + MetaDisplay *display; + MetaBackgroundMonitor *monitors; + int n_monitors; + + CDesktopBackgroundStyle style; + CDesktopBackgroundShading shading_direction; + ClutterColor color; + ClutterColor second_color; + + GFile *file1; + MetaBackgroundImage *background_image1; + GFile *file2; + MetaBackgroundImage *background_image2; + + CoglTexture *color_texture; + CoglTexture *wallpaper_texture; + + float blend_factor; + + guint wallpaper_allocation_failed : 1; +}; - cairo_region_t *visible_region; +enum +{ + PROP_META_DISPLAY = 1, + PROP_MONITOR, }; -G_DEFINE_TYPE (MetaBackground, meta_background, CLUTTER_TYPE_ACTOR); +G_DEFINE_TYPE (MetaBackground, meta_background, G_TYPE_OBJECT) + +static gboolean texture_has_alpha (CoglTexture *texture); + +static GSList *all_backgrounds = NULL; static void -meta_background_dispose (GObject *object) +free_fbos (MetaBackground *self) { - MetaBackground *self = META_BACKGROUND (object); - MetaBackgroundPrivate *priv = self->priv; + int i; - meta_background_set_visible_region (self, NULL); + for (i = 0; i < self->n_monitors; i++) + { + MetaBackgroundMonitor *monitor = &self->monitors[i]; + if (monitor->fbo) + { + cogl_object_unref (monitor->fbo); + monitor->fbo = NULL; + } + if (monitor->texture) + { + cogl_object_unref (monitor->texture); + monitor->texture = NULL; + } + } +} - if (priv->pipeline != NULL) +static void +free_color_texture (MetaBackground *self) +{ + if (self->color_texture != NULL) { - cogl_object_unref (priv->pipeline); - priv->pipeline = NULL; + cogl_object_unref (self->color_texture); + self->color_texture = NULL; } +} - G_OBJECT_CLASS (meta_background_parent_class)->dispose (object); +static void +free_wallpaper_texture (MetaBackground *self) +{ + if (self->wallpaper_texture != NULL) + { + cogl_object_unref (self->wallpaper_texture); + self->wallpaper_texture = NULL; + } + + self->wallpaper_allocation_failed = FALSE; } static void -meta_background_get_preferred_width (ClutterActor *actor, - gfloat for_height, - gfloat *min_width_p, - gfloat *natural_width_p) +invalidate_monitor_backgrounds (MetaBackground *self) { - MetaBackground *self = META_BACKGROUND (actor); - MetaBackgroundPrivate *priv = self->priv; - int width, height; + free_fbos (self); + g_free (self->monitors); + self->monitors = NULL; + self->n_monitors = 0; + + if (self->display) + { + int i; - meta_screen_get_size (priv->screen, &width, &height); + self->n_monitors = meta_display_get_n_monitors (self->display); + self->monitors = g_new0 (MetaBackgroundMonitor, self->n_monitors); - if (min_width_p) - *min_width_p = width; - if (natural_width_p) - *natural_width_p = width; + for (i = 0; i < self->n_monitors; i++) + self->monitors[i].dirty = TRUE; + } } static void -meta_background_get_preferred_height (ClutterActor *actor, - gfloat for_width, - gfloat *min_height_p, - gfloat *natural_height_p) +on_monitors_changed (MetaBackground *self) +{ + invalidate_monitor_backgrounds (self); +} +static void +set_display (MetaBackground *self, + MetaDisplay *display) { - MetaBackground *self = META_BACKGROUND (actor); - MetaBackgroundPrivate *priv = self->priv; - int width, height; + g_set_object (&self->display, display); - meta_screen_get_size (priv->screen, &width, &height); + invalidate_monitor_backgrounds (self); +} - if (min_height_p) - *min_height_p = height; - if (natural_height_p) - *natural_height_p = height; +static void +meta_background_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) + { + case PROP_META_DISPLAY: + set_display (META_BACKGROUND (object), g_value_get_object (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void -meta_background_paint (ClutterActor *actor) +meta_background_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) { - MetaBackground *self = META_BACKGROUND (actor); - MetaBackgroundPrivate *priv = self->priv; - guint8 opacity = clutter_actor_get_paint_opacity (actor); - guint8 color_component; - int width, height; + MetaBackground *self = META_BACKGROUND (object); - meta_screen_get_size (priv->screen, &width, &height); + switch (prop_id) + { + case PROP_META_DISPLAY: + g_value_set_object (value, self->display); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} - color_component = (int)(0.5 + opacity); +static gboolean +need_prerender (MetaBackground *self) +{ + CoglTexture *texture1 = self->background_image1 ? meta_background_image_get_texture (self->background_image1) : NULL; + CoglTexture *texture2 = self->background_image2 ? meta_background_image_get_texture (self->background_image2) : NULL; + + if (texture1 == NULL && texture2 == NULL) + return FALSE; + + if (texture2 == NULL && self->style == C_DESKTOP_BACKGROUND_STYLE_WALLPAPER) + return FALSE; + + return TRUE; +} + +static void +mark_changed (MetaBackground *self) +{ + int i; + + if (!need_prerender (self)) + free_fbos (self); - cogl_pipeline_set_color4ub (priv->pipeline, - color_component, - color_component, - color_component, - opacity); + for (i = 0; i < self->n_monitors; i++) + self->monitors[i].dirty = TRUE; + + g_signal_emit (self, signals[CHANGED], 0); +} + +static void +on_background_loaded (MetaBackgroundImage *image, + MetaBackground *self) +{ + mark_changed (self); +} + +static gboolean +file_equal0 (GFile *file1, + GFile *file2) +{ + if (file1 == file2) + return TRUE; - cogl_set_source (priv->pipeline); + if ((file1 == NULL) || (file2 == NULL)) + return FALSE; - if (priv->visible_region) + return g_file_equal (file1, file2); +} + +static void +set_file (MetaBackground *self, + GFile **filep, + MetaBackgroundImage **imagep, + GFile *file, + gboolean force_reload) +{ + if (force_reload || !file_equal0 (*filep, file)) { - int n_rectangles = cairo_region_num_rectangles (priv->visible_region); - int i; + if (*imagep) + { + g_signal_handlers_disconnect_by_func (*imagep, + (gpointer)on_background_loaded, + self); + g_object_unref (*imagep); + *imagep = NULL; + } + + g_set_object (filep, file); - for (i = 0; i < n_rectangles; i++) + if (file) { - cairo_rectangle_int_t rect; - cairo_region_get_rectangle (priv->visible_region, i, &rect); + MetaBackgroundImageCache *cache = meta_background_image_cache_get_default (); - cogl_rectangle_with_texture_coords (rect.x, rect.y, - rect.x + rect.width, rect.y + rect.height, - rect.x / priv->texture_width, - rect.y / priv->texture_height, - (rect.x + rect.width) / priv->texture_width, - (rect.y + rect.height) / priv->texture_height); + *imagep = meta_background_image_cache_load (cache, file); + g_signal_connect (*imagep, "loaded", + G_CALLBACK (on_background_loaded), self); } } - else +} + +static void +on_gl_video_memory_purged (MetaBackground *self) +{ + MetaBackgroundImageCache *cache = meta_background_image_cache_get_default (); + + /* The GPU memory that just got invalidated is the texture inside + * self->background_image1,2 and/or its mipmaps. However, to save memory the + * original pixbuf isn't kept in RAM so we can't do a simple re-upload. The + * only copy of the image was the one in texture memory that got invalidated. + * So we need to do a full reload from disk. + */ + if (self->file1) { - cogl_rectangle_with_texture_coords (0.0f, 0.0f, - width, height, - 0.0f, 0.0f, - width / priv->texture_width, - height / priv->texture_height); + meta_background_image_cache_purge (cache, self->file1); + set_file (self, &self->file1, &self->background_image1, self->file1, TRUE); } + + if (self->file2) + { + meta_background_image_cache_purge (cache, self->file2); + set_file (self, &self->file2, &self->background_image2, self->file2, TRUE); + } + + mark_changed (self); } -static gboolean -meta_background_get_paint_volume (ClutterActor *actor, - ClutterPaintVolume *volume) +static void +meta_background_dispose (GObject *object) +{ + MetaBackground *self = META_BACKGROUND (object); + + free_color_texture (self); + free_wallpaper_texture (self); + + set_file (self, &self->file1, &self->background_image1, NULL, FALSE); + set_file (self, &self->file2, &self->background_image2, NULL, FALSE); + + set_display (self, NULL); + + G_OBJECT_CLASS (meta_background_parent_class)->dispose (object); +} + +static void +meta_background_finalize (GObject *object) { - return clutter_paint_volume_set_from_allocation (volume, actor); + all_backgrounds = g_slist_remove (all_backgrounds, object); + + G_OBJECT_CLASS (meta_background_parent_class)->finalize (object); } +static void +meta_background_constructed (GObject *object) +{ + MetaBackground *self = META_BACKGROUND (object); + MetaMonitorManager *monitor_manager = meta_monitor_manager_get (); + + G_OBJECT_CLASS (meta_background_parent_class)->constructed (object); + + g_signal_connect_object (self->display, "gl-video-memory-purged", + G_CALLBACK (on_gl_video_memory_purged), object, G_CONNECT_SWAPPED); + + g_signal_connect_object (monitor_manager, "monitors-changed", + G_CALLBACK (on_monitors_changed), self, + G_CONNECT_SWAPPED); +} static void meta_background_class_init (MetaBackgroundClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); - - g_type_class_add_private (klass, sizeof (MetaBackgroundPrivate)); + GParamSpec *param_spec; object_class->dispose = meta_background_dispose; + object_class->finalize = meta_background_finalize; + object_class->constructed = meta_background_constructed; + object_class->set_property = meta_background_set_property; + object_class->get_property = meta_background_get_property; + + signals[CHANGED] = + g_signal_new ("changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); + + param_spec = g_param_spec_object ("meta-display", + "MetaDisplay", + "MetaDisplay", + META_TYPE_DISPLAY, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + + g_object_class_install_property (object_class, + PROP_META_DISPLAY, + param_spec); - actor_class->get_preferred_width = meta_background_get_preferred_width; - actor_class->get_preferred_height = meta_background_get_preferred_height; - actor_class->get_paint_volume = meta_background_get_paint_volume; - actor_class->paint = meta_background_paint; } static void meta_background_init (MetaBackground *self) { - self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, - META_TYPE_BACKGROUND, - MetaBackgroundPrivate); + all_backgrounds = g_slist_prepend (all_backgrounds, self); +} + +static void +set_texture_area_from_monitor_area (cairo_rectangle_int_t *monitor_area, + cairo_rectangle_int_t *texture_area) +{ + texture_area->x = 0; + texture_area->y = 0; + texture_area->width = monitor_area->width; + texture_area->height = monitor_area->height; } -ClutterActor * -meta_background_new (MetaScreen *screen) +static void +get_texture_area (MetaBackground *self, + cairo_rectangle_int_t *monitor_rect, + float monitor_scale, + CoglTexture *texture, + cairo_rectangle_int_t *texture_area) { - MetaBackground *self; - MetaBackgroundPrivate *priv; + cairo_rectangle_int_t image_area; + int screen_width, screen_height; + float texture_width, texture_height; + float monitor_x_scale, monitor_y_scale; - self = g_object_new (META_TYPE_BACKGROUND, - NULL); - priv = self->priv; + texture_width = cogl_texture_get_width (texture); + texture_height = cogl_texture_get_height (texture); - priv->screen = screen; - priv->pipeline = meta_create_texture_pipeline (NULL); + switch (self->style) + { + case C_DESKTOP_BACKGROUND_STYLE_STRETCHED: + default: + /* paint region is whole actor, and the texture + * is scaled disproportionately to fit the actor + */ + set_texture_area_from_monitor_area (monitor_rect, texture_area); + break; + case C_DESKTOP_BACKGROUND_STYLE_WALLPAPER: + meta_display_get_size (self->display, &screen_width, &screen_height); + + /* Start off by centering a tile in the middle of the + * total screen area taking care of the monitor scaling. + */ + image_area.x = (screen_width - texture_width) / 2.0; + image_area.y = (screen_height - texture_height) / 2.0; + image_area.width = texture_width; + image_area.height = texture_height; + + /* Translate into the coordinate system of the particular monitor */ + image_area.x -= monitor_rect->x; + image_area.y -= monitor_rect->y; + + *texture_area = image_area; + break; + case C_DESKTOP_BACKGROUND_STYLE_CENTERED: + /* paint region is the original image size centered in the actor, + * and the texture is scaled to the original image size */ + image_area.width = texture_width; + image_area.height = texture_height; + image_area.x = monitor_rect->width / 2 - image_area.width / 2; + image_area.y = monitor_rect->height / 2 - image_area.height / 2; + + *texture_area = image_area; + break; + case C_DESKTOP_BACKGROUND_STYLE_SCALED: + case C_DESKTOP_BACKGROUND_STYLE_ZOOM: + /* paint region is the actor size in one dimension, and centered and + * scaled by proportional amount in the other dimension. + * + * SCALED forces the centered dimension to fit on screen. + * ZOOM forces the centered dimension to grow off screen + */ + monitor_x_scale = monitor_rect->width / texture_width; + monitor_y_scale = monitor_rect->height / texture_height; + + if ((self->style == C_DESKTOP_BACKGROUND_STYLE_SCALED && + (monitor_x_scale < monitor_y_scale)) || + (self->style == C_DESKTOP_BACKGROUND_STYLE_ZOOM && + (monitor_x_scale > monitor_y_scale))) + { + /* Fill image to exactly fit actor horizontally */ + image_area.width = monitor_rect->width; + image_area.height = texture_height * monitor_x_scale; - return CLUTTER_ACTOR (self); + /* Position image centered vertically in actor */ + image_area.x = 0; + image_area.y = monitor_rect->height / 2 - image_area.height / 2; + } + else + { + /* Scale image to exactly fit actor vertically */ + image_area.width = texture_width * monitor_y_scale; + image_area.height = monitor_rect->height; + + /* Position image centered horizontally in actor */ + image_area.x = monitor_rect->width / 2 - image_area.width / 2; + image_area.y = 0; + } + + *texture_area = image_area; + break; + + case C_DESKTOP_BACKGROUND_STYLE_SPANNED: + { + /* paint region is the union of all monitors, with the origin + * of the region set to align with monitor associated with the background. + */ + meta_display_get_size (self->display, &screen_width, &screen_height); + + /* unclipped texture area is whole screen, scaled depending on monitor */ + image_area.width = screen_width * monitor_scale; + image_area.height = screen_height * monitor_scale; + + /* But make (0,0) line up with the appropriate monitor */ + image_area.x = -monitor_rect->x; + image_area.y = -monitor_rect->y; + + *texture_area = image_area; + break; + } + } } -void -meta_background_set_layer (MetaBackground *self, - CoglTexture *texture) +static gboolean +draw_texture (MetaBackground *self, + CoglFramebuffer *framebuffer, + CoglPipeline *pipeline, + CoglTexture *texture, + cairo_rectangle_int_t *monitor_area, + float monitor_scale) { - MetaBackgroundPrivate *priv = self->priv; - MetaDisplay *display = meta_screen_get_display (priv->screen); + cairo_rectangle_int_t texture_area; + gboolean bare_region_visible; - /* This may trigger destruction of an old texture pixmap, which, if - * the underlying X pixmap is already gone has the tendency to trigger - * X errors inside DRI. For safety, trap errors */ - meta_error_trap_push (display); - cogl_pipeline_set_layer_texture (priv->pipeline, 0, texture); - meta_error_trap_pop (display); + get_texture_area (self, monitor_area, monitor_scale, texture, &texture_area); + + switch (self->style) + { + case C_DESKTOP_BACKGROUND_STYLE_STRETCHED: + case C_DESKTOP_BACKGROUND_STYLE_WALLPAPER: + case C_DESKTOP_BACKGROUND_STYLE_ZOOM: + case C_DESKTOP_BACKGROUND_STYLE_SPANNED: + /* Draw the entire monitor */ + cogl_framebuffer_draw_textured_rectangle (framebuffer, + pipeline, + 0, + 0, + monitor_area->width, + monitor_area->height, + - texture_area.x / (float)texture_area.width, + - texture_area.y / (float)texture_area.height, + (monitor_area->width - texture_area.x) / (float)texture_area.width, + (monitor_area->height - texture_area.y) / (float)texture_area.height); - priv->texture_width = cogl_texture_get_width (texture); - priv->texture_height = cogl_texture_get_height (texture); + bare_region_visible = texture_has_alpha (texture); - clutter_actor_queue_redraw (CLUTTER_ACTOR (self)); + /* Draw just the texture */ + break; + case C_DESKTOP_BACKGROUND_STYLE_CENTERED: + case C_DESKTOP_BACKGROUND_STYLE_SCALED: + cogl_framebuffer_draw_textured_rectangle (framebuffer, + pipeline, + texture_area.x, texture_area.y, + texture_area.x + texture_area.width, + texture_area.y + texture_area.height, + 0, 0, 1.0, 1.0); + bare_region_visible = texture_has_alpha (texture) || memcmp (&texture_area, monitor_area, sizeof (cairo_rectangle_int_t)) != 0; + break; + case C_DESKTOP_BACKGROUND_STYLE_NONE: + bare_region_visible = TRUE; + break; + default: + g_return_val_if_reached(FALSE); + } + + return bare_region_visible; } -void -meta_background_set_layer_wrap_mode (MetaBackground *self, - CoglPipelineWrapMode wrap_mode) +static void +ensure_color_texture (MetaBackground *self) { - MetaBackgroundPrivate *priv = self->priv; + if (self->color_texture == NULL) + { + ClutterBackend *backend = clutter_get_default_backend (); + CoglContext *ctx = clutter_backend_get_cogl_context (backend); + GError *error = NULL; + uint8_t pixels[6]; + int width, height; + + if (self->shading_direction == C_DESKTOP_BACKGROUND_SHADING_SOLID) + { + width = 1; + height = 1; + + pixels[0] = self->color.red; + pixels[1] = self->color.green; + pixels[2] = self->color.blue; + } + else + { + switch (self->shading_direction) + { + case C_DESKTOP_BACKGROUND_SHADING_VERTICAL: + width = 1; + height = 2; + break; + case C_DESKTOP_BACKGROUND_SHADING_HORIZONTAL: + width = 2; + height = 1; + break; + default: + g_return_if_reached (); + } + + pixels[0] = self->color.red; + pixels[1] = self->color.green; + pixels[2] = self->color.blue; + pixels[3] = self->second_color.red; + pixels[4] = self->second_color.green; + pixels[5] = self->second_color.blue; + } - cogl_pipeline_set_layer_wrap_mode (priv->pipeline, 0, wrap_mode); + self->color_texture = COGL_TEXTURE (cogl_texture_2d_new_from_data (ctx, width, height, + COGL_PIXEL_FORMAT_RGB_888, + width * 3, + pixels, + &error)); + + if (error != NULL) + { + meta_warning ("Failed to allocate color texture: %s\n", error->message); + g_error_free (error); + } + } } -void -meta_background_set_visible_region (MetaBackground *self, - cairo_region_t *visible_region) +typedef enum { - MetaBackgroundPrivate *priv; + PIPELINE_REPLACE, + PIPELINE_ADD, + PIPELINE_OVER_REVERSE, +} PipelineType; - g_return_if_fail (META_IS_BACKGROUND (self)); +static CoglPipeline * +create_pipeline (PipelineType type) +{ + const char * const blend_strings[3] = { + [PIPELINE_REPLACE] = "RGBA = ADD (SRC_COLOR, 0)", + [PIPELINE_ADD] = "RGBA = ADD (SRC_COLOR, DST_COLOR)", + [PIPELINE_OVER_REVERSE] = "RGBA = ADD (SRC_COLOR * (1 - DST_COLOR[A]), DST_COLOR)", + }; + static CoglPipeline *templates[3]; - priv = self->priv; + if (templates[type] == NULL) + { + templates[type] = meta_create_texture_pipeline (NULL); + cogl_pipeline_set_blend (templates[type], blend_strings[type], NULL); + } - if (priv->visible_region) + cogl_pipeline_set_layer_filters (templates[type], + 0, + COGL_PIPELINE_FILTER_LINEAR_MIPMAP_LINEAR, + COGL_PIPELINE_FILTER_LINEAR); + + return cogl_pipeline_copy (templates[type]); +} + +static gboolean +texture_has_alpha (CoglTexture *texture) +{ + if (!texture) + return FALSE; + + switch (cogl_texture_get_components (texture)) { - cairo_region_destroy (priv->visible_region); - priv->visible_region = NULL; + case COGL_TEXTURE_COMPONENTS_A: + case COGL_TEXTURE_COMPONENTS_RGBA: + return TRUE; + case COGL_TEXTURE_COMPONENTS_RG: + case COGL_TEXTURE_COMPONENTS_RGB: + case COGL_TEXTURE_COMPONENTS_DEPTH: + return FALSE; + default: + g_assert_not_reached (); + return FALSE; } +} - if (visible_region) +static gboolean +ensure_wallpaper_texture (MetaBackground *self, + CoglTexture *texture) +{ + if (self->wallpaper_texture == NULL && !self->wallpaper_allocation_failed) { - cairo_rectangle_int_t screen_rect = { 0 }; - meta_screen_get_size (priv->screen, &screen_rect.width, &screen_rect.height); + int width = cogl_texture_get_width (texture); + int height = cogl_texture_get_height (texture); + CoglOffscreen *offscreen; + CoglFramebuffer *fbo; + GError *catch_error = NULL; + CoglPipeline *pipeline; - /* Doing the intersection here is probably unnecessary - MetaWindowGroup - * should never compute a visible area that's larger than the root screen! - * but it's not that expensive and adds some extra robustness. - */ - priv->visible_region = cairo_region_create_rectangle (&screen_rect); - cairo_region_intersect (priv->visible_region, visible_region); + self->wallpaper_texture = meta_create_texture (width, height, + COGL_TEXTURE_COMPONENTS_RGBA, + META_TEXTURE_FLAGS_NONE); + offscreen = cogl_offscreen_new_with_texture (self->wallpaper_texture); + fbo = COGL_FRAMEBUFFER (offscreen); + + if (!cogl_framebuffer_allocate (fbo, &catch_error)) + { + /* This probably means that the size of the wallpapered texture is larger + * than the maximum texture size; we treat it as permanent until the + * background is changed again. + */ + g_error_free (catch_error); + + cogl_object_unref (self->wallpaper_texture); + self->wallpaper_texture = NULL; + cogl_object_unref (fbo); + + self->wallpaper_allocation_failed = TRUE; + return FALSE; + } + + cogl_framebuffer_orthographic (fbo, 0, 0, + width, height, -1., 1.); + + pipeline = create_pipeline (PIPELINE_REPLACE); + cogl_pipeline_set_layer_texture (pipeline, 0, texture); + cogl_framebuffer_draw_textured_rectangle (fbo, pipeline, 0, 0, width, height, + 0., 0., 1., 1.); + cogl_object_unref (pipeline); + + if (texture_has_alpha (texture)) + { + ensure_color_texture (self); + + pipeline = create_pipeline (PIPELINE_OVER_REVERSE); + cogl_pipeline_set_layer_texture (pipeline, 0, self->color_texture); + cogl_framebuffer_draw_rectangle (fbo, pipeline, 0, 0, width, height); + cogl_object_unref (pipeline); + } + + cogl_object_unref (fbo); + } + + return self->wallpaper_texture != NULL; +} + +static CoglPipelineWrapMode +get_wrap_mode (CDesktopBackgroundStyle style) +{ + switch (style) + { + case C_DESKTOP_BACKGROUND_STYLE_WALLPAPER: + return COGL_PIPELINE_WRAP_MODE_REPEAT; + case C_DESKTOP_BACKGROUND_STYLE_NONE: + case C_DESKTOP_BACKGROUND_STYLE_STRETCHED: + case C_DESKTOP_BACKGROUND_STYLE_CENTERED: + case C_DESKTOP_BACKGROUND_STYLE_SCALED: + case C_DESKTOP_BACKGROUND_STYLE_ZOOM: + case C_DESKTOP_BACKGROUND_STYLE_SPANNED: + default: + return COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE; + } +} + +static int +get_best_mipmap_level (CoglTexture *texture, + int visible_width, + int visible_height) +{ + int mipmap_width = cogl_texture_get_width (texture); + int mipmap_height = cogl_texture_get_height (texture); + int halves = 0; + + while (mipmap_width >= visible_width && mipmap_height >= visible_height) + { + halves++; + mipmap_width /= 2; + mipmap_height /= 2; + } + + return MAX (0, halves - 1); +} + +CoglTexture * +meta_background_get_texture (MetaBackground *self, + int monitor_index, + cairo_rectangle_int_t *texture_area, + CoglPipelineWrapMode *wrap_mode) +{ + MetaBackgroundMonitor *monitor; + MetaRectangle geometry; + cairo_rectangle_int_t monitor_area; + CoglTexture *texture1, *texture2; + float monitor_scale; + + g_return_val_if_fail (META_IS_BACKGROUND (self), NULL); + g_return_val_if_fail (monitor_index >= 0 && monitor_index < self->n_monitors, NULL); + + monitor = &self->monitors[monitor_index]; + + meta_display_get_monitor_geometry (self->display, monitor_index, &geometry); + monitor_scale = meta_display_get_monitor_scale (self->display, monitor_index); + monitor_area.x = geometry.x; + monitor_area.y = geometry.y; + monitor_area.width = geometry.width; + monitor_area.height = geometry.height; + + texture1 = self->background_image1 ? meta_background_image_get_texture (self->background_image1) : NULL; + texture2 = self->background_image2 ? meta_background_image_get_texture (self->background_image2) : NULL; + + if (texture1 == NULL && texture2 == NULL) + { + ensure_color_texture (self); + if (texture_area) + set_texture_area_from_monitor_area (&monitor_area, texture_area); + if (wrap_mode) + *wrap_mode = COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE; + return self->color_texture; + } + + if (texture2 == NULL && self->style == C_DESKTOP_BACKGROUND_STYLE_WALLPAPER && + self->shading_direction == C_DESKTOP_BACKGROUND_SHADING_SOLID && + ensure_wallpaper_texture (self, texture1)) + { + if (texture_area) + get_texture_area (self, &monitor_area, monitor_scale, + self->wallpaper_texture, texture_area); + if (wrap_mode) + *wrap_mode = COGL_PIPELINE_WRAP_MODE_REPEAT; + return self->wallpaper_texture; + } + + if (monitor->dirty) + { + GError *catch_error = NULL; + gboolean bare_region_visible = FALSE; + int texture_width, texture_height; + + if (meta_is_stage_views_scaled ()) + { + texture_width = monitor_area.width * monitor_scale; + texture_height = monitor_area.height * monitor_scale; + } + else + { + texture_width = monitor_area.width; + texture_height = monitor_area.height; + } + + if (monitor->texture == NULL) + { + CoglOffscreen *offscreen; + + monitor->texture = meta_create_texture (texture_width, + texture_height, + COGL_TEXTURE_COMPONENTS_RGBA, + META_TEXTURE_FLAGS_NONE); + offscreen = cogl_offscreen_new_with_texture (monitor->texture); + monitor->fbo = COGL_FRAMEBUFFER (offscreen); + } + + if (self->style != C_DESKTOP_BACKGROUND_STYLE_WALLPAPER) + { + monitor_area.x *= monitor_scale; + monitor_area.y *= monitor_scale; + monitor_area.width *= monitor_scale; + monitor_area.height *= monitor_scale; + } + + if (!cogl_framebuffer_allocate (monitor->fbo, &catch_error)) + { + /* Texture or framebuffer allocation failed; it's unclear why this happened; + * we'll try again the next time this is called. (MetaBackgroundActor + * caches the result, so user might be left without a background.) + */ + cogl_object_unref (monitor->texture); + monitor->texture = NULL; + cogl_object_unref (monitor->fbo); + monitor->fbo = NULL; + + g_error_free (catch_error); + return NULL; + } + + cogl_framebuffer_orthographic (monitor->fbo, 0, 0, + monitor_area.width, monitor_area.height, -1., 1.); + + if (texture2 != NULL && self->blend_factor != 0.0) + { + CoglPipeline *pipeline = create_pipeline (PIPELINE_REPLACE); + int mipmap_level; + + mipmap_level = get_best_mipmap_level (texture2, + texture_width, + texture_height); + + cogl_pipeline_set_color4f (pipeline, + self->blend_factor, self->blend_factor, self->blend_factor, self->blend_factor); + cogl_pipeline_set_layer_texture (pipeline, 0, texture2); + cogl_pipeline_set_layer_wrap_mode (pipeline, 0, get_wrap_mode (self->style)); + cogl_pipeline_set_layer_max_mipmap_level (pipeline, 0, mipmap_level); + + bare_region_visible = draw_texture (self, + monitor->fbo, pipeline, + texture2, &monitor_area, + monitor_scale); + + cogl_object_unref (pipeline); + } + else + { + cogl_framebuffer_clear4f (monitor->fbo, + COGL_BUFFER_BIT_COLOR, + 0.0, 0.0, 0.0, 0.0); + } + + if (texture1 != NULL && self->blend_factor != 1.0) + { + CoglPipeline *pipeline = create_pipeline (PIPELINE_ADD); + int mipmap_level; + + mipmap_level = get_best_mipmap_level (texture1, + texture_width, + texture_height); + + cogl_pipeline_set_color4f (pipeline, + (1 - self->blend_factor), + (1 - self->blend_factor), + (1 - self->blend_factor), + (1 - self->blend_factor));; + cogl_pipeline_set_layer_texture (pipeline, 0, texture1); + cogl_pipeline_set_layer_wrap_mode (pipeline, 0, get_wrap_mode (self->style)); + cogl_pipeline_set_layer_max_mipmap_level (pipeline, 0, mipmap_level); + + bare_region_visible = bare_region_visible || draw_texture (self, + monitor->fbo, pipeline, + texture1, &monitor_area, + monitor_scale); + + cogl_object_unref (pipeline); + } + + if (bare_region_visible) + { + CoglPipeline *pipeline = create_pipeline (PIPELINE_OVER_REVERSE); + + ensure_color_texture (self); + cogl_pipeline_set_layer_texture (pipeline, 0, self->color_texture); + cogl_framebuffer_draw_rectangle (monitor->fbo, + pipeline, + 0, 0, + monitor_area.width, monitor_area.height); + cogl_object_unref (pipeline); + } + + monitor->dirty = FALSE; } -} \ No newline at end of file + + if (texture_area) + set_texture_area_from_monitor_area (&geometry, texture_area); + + if (wrap_mode) + *wrap_mode = COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE; + return monitor->texture; +} + +MetaBackground * +meta_background_new (MetaDisplay *display) +{ + return g_object_new (META_TYPE_BACKGROUND, + "meta-display", display, + NULL); +} + +void +meta_background_set_color (MetaBackground *self, + ClutterColor *color) +{ + ClutterColor dummy = { 0 }; + + g_return_if_fail (META_IS_BACKGROUND (self)); + g_return_if_fail (color != NULL); + + meta_background_set_gradient (self, + C_DESKTOP_BACKGROUND_SHADING_SOLID, + color, &dummy); +} + +void +meta_background_set_gradient (MetaBackground *self, + CDesktopBackgroundShading shading_direction, + ClutterColor *color, + ClutterColor *second_color) +{ + g_return_if_fail (META_IS_BACKGROUND (self)); + g_return_if_fail (color != NULL); + g_return_if_fail (second_color != NULL); + + self->shading_direction = shading_direction; + self->color = *color; + self->second_color = *second_color; + + free_color_texture (self); + free_wallpaper_texture (self); + mark_changed (self); +} + +/** + * meta_background_set_file: + * @self: a #MetaBackground + * @file: (nullable): a #GFile representing the background file + * @style: the background style to apply + * + * Set the background to @file + */ +void +meta_background_set_file (MetaBackground *self, + GFile *file, + CDesktopBackgroundStyle style) +{ + g_return_if_fail (META_IS_BACKGROUND (self)); + + meta_background_set_blend (self, file, NULL, 0.0, style); +} + +void +meta_background_set_blend (MetaBackground *self, + GFile *file1, + GFile *file2, + double blend_factor, + CDesktopBackgroundStyle style) +{ + g_return_if_fail (META_IS_BACKGROUND (self)); + g_return_if_fail (blend_factor >= 0.0 && blend_factor <= 1.0); + + set_file (self, &self->file1, &self->background_image1, file1, FALSE); + set_file (self, &self->file2, &self->background_image2, file2, FALSE); + + self->blend_factor = blend_factor; + self->style = style; + + free_wallpaper_texture (self); + mark_changed (self); +} + +void +meta_background_refresh_all (void) +{ + GSList *l; + + for (l = all_backgrounds; l; l = l->next) + mark_changed (l->data); +} diff --git a/src/compositor/meta-background.h b/src/compositor/meta-background.h deleted file mode 100644 index 15566d8cf..000000000 --- a/src/compositor/meta-background.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -#ifndef META_BACKGROUND_H -#define META_BACKGROUND_H - -#include <clutter/clutter.h> - -#include <meta/screen.h> - -#define META_TYPE_BACKGROUND (meta_background_get_type ()) -#define META_BACKGROUND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_BACKGROUND, MetaBackground)) -#define META_BACKGROUND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_BACKGROUND, MetaBackgroundClass)) -#define META_IS_BACKGROUND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_BACKGROUND)) -#define META_IS_BACKGROUND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_BACKGROUND)) -#define META_BACKGROUND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_BACKGROUND, MetaBackgroundClass)) - -typedef struct _MetaBackground MetaBackground; -typedef struct _MetaBackgroundClass MetaBackgroundClass; -typedef struct _MetaBackgroundPrivate MetaBackgroundPrivate; - -struct _MetaBackgroundClass -{ - ClutterActorClass parent_class; -}; - -struct _MetaBackground -{ - ClutterActor parent; - - MetaBackgroundPrivate *priv; -}; - -GType meta_background_get_type (void); - -ClutterActor * meta_background_new (MetaScreen *screen); - -void meta_background_set_layer (MetaBackground *self, - CoglTexture *texture); -void meta_background_set_layer_wrap_mode (MetaBackground *self, - CoglPipelineWrapMode wrap_mode); -void meta_background_set_visible_region (MetaBackground *self, - cairo_region_t *visible_region); - -#endif /* META_BACKGROUND_H */ diff --git a/src/compositor/meta-compositor-server.c b/src/compositor/meta-compositor-server.c new file mode 100644 index 000000000..1e1d977d5 --- /dev/null +++ b/src/compositor/meta-compositor-server.c @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2019 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#include "config.h" + +#include "compositor/meta-compositor-server.h" + +struct _MetaCompositorServer +{ + MetaCompositor parent; +}; + +G_DEFINE_TYPE (MetaCompositorServer, meta_compositor_server, META_TYPE_COMPOSITOR) + +static void +meta_compositor_server_manage (MetaCompositor *compositor) +{ +} + +static void +meta_compositor_server_unmanage (MetaCompositor *compositor) +{ +} + +static int64_t +meta_compositor_server_monotonic_to_high_res_xserver_time (MetaCompositor *compositor, + int64_t monotonic_time_us) +{ + return meta_translate_to_high_res_xserver_time (monotonic_time_us); +} + +MetaCompositorServer * +meta_compositor_server_new (MetaDisplay *display) +{ + return g_object_new (META_TYPE_COMPOSITOR_SERVER, + "display", display, + NULL); +} + +static void +meta_compositor_server_init (MetaCompositorServer *compositor_server) +{ +} + +static void +meta_compositor_server_class_init (MetaCompositorServerClass *klass) +{ + MetaCompositorClass *compositor_class = META_COMPOSITOR_CLASS (klass); + + compositor_class->manage = meta_compositor_server_manage; + compositor_class->unmanage = meta_compositor_server_unmanage; + compositor_class->monotonic_to_high_res_xserver_time = + meta_compositor_server_monotonic_to_high_res_xserver_time; +} diff --git a/src/compositor/meta-compositor-server.h b/src/compositor/meta-compositor-server.h new file mode 100644 index 000000000..8bff05e7b --- /dev/null +++ b/src/compositor/meta-compositor-server.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2019 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#ifndef META_COMPOSITOR_SERVER_H +#define META_COMPOSITOR_SERVER_H + +#include "compositor/compositor-private.h" + +#define META_TYPE_COMPOSITOR_SERVER (meta_compositor_server_get_type ()) +G_DECLARE_FINAL_TYPE (MetaCompositorServer, meta_compositor_server, + META, COMPOSITOR_SERVER, MetaCompositor) + +MetaCompositorServer * meta_compositor_server_new (MetaDisplay *display); + +#endif /* META_COMPOSITOR_SERVER_H */ diff --git a/src/compositor/meta-compositor-x11.c b/src/compositor/meta-compositor-x11.c new file mode 100644 index 000000000..4043d8151 --- /dev/null +++ b/src/compositor/meta-compositor-x11.c @@ -0,0 +1,527 @@ +/* + * Copyright (C) 2019 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#include "config.h" + +#include "compositor/meta-compositor-x11.h" + +#include <X11/extensions/shape.h> +#include <X11/extensions/Xcomposite.h> + +#include "backends/x11/meta-backend-x11.h" +#include "backends/x11/meta-event-x11.h" +#include "clutter/x11/clutter-x11.h" +#include "compositor/meta-sync-ring.h" +#include "compositor/meta-window-actor-x11.h" +#include "core/display-private.h" +#include "core/window-private.h" +#include "x11/meta-x11-display-private.h" + +struct _MetaCompositorX11 +{ + MetaCompositor parent; + + Window output; + + gboolean frame_has_updated_xsurfaces; + gboolean have_x11_sync_object; + + MetaWindow *unredirected_window; + + gboolean xserver_uses_monotonic_clock; + int64_t xserver_time_query_time_us; + int64_t xserver_time_offset_us; + + gboolean randr_scale_disabled; +}; + +G_DEFINE_TYPE (MetaCompositorX11, meta_compositor_x11, META_TYPE_COMPOSITOR) + +static void +process_damage (MetaCompositorX11 *compositor_x11, + XDamageNotifyEvent *damage_xevent, + MetaWindow *window) +{ + MetaWindowActor *window_actor = meta_window_actor_from_window (window); + MetaWindowActorX11 *window_actor_x11 = META_WINDOW_ACTOR_X11 (window_actor); + + meta_window_actor_x11_process_damage (window_actor_x11, damage_xevent); + + compositor_x11->frame_has_updated_xsurfaces = TRUE; +} + +void +meta_compositor_x11_process_xevent (MetaCompositorX11 *compositor_x11, + XEvent *xevent, + MetaWindow *window) +{ + MetaCompositor *compositor = META_COMPOSITOR (compositor_x11); + MetaDisplay *display = meta_compositor_get_display (compositor); + MetaX11Display *x11_display = display->x11_display; + int damage_event_base; + + damage_event_base = meta_x11_display_get_damage_event_base (x11_display); + if (xevent->type == damage_event_base + XDamageNotify) + { + /* + * Core code doesn't handle damage events, so we need to extract the + * MetaWindow ourselves. + */ + if (!window) + { + Window xwindow; + + xwindow = ((XDamageNotifyEvent *) xevent)->drawable; + window = meta_x11_display_lookup_x_window (x11_display, xwindow); + } + + if (window) + process_damage (compositor_x11, (XDamageNotifyEvent *) xevent, window); + } + + if (compositor_x11->have_x11_sync_object) + meta_sync_ring_handle_event (xevent); + + /* + * Clutter needs to know about MapNotify events otherwise it will think the + * stage is invisible + */ + if (xevent->type == MapNotify) + meta_x11_handle_event (xevent); +} + +static void +determine_server_clock_source (MetaCompositorX11 *compositor_x11) +{ + MetaCompositor *compositor = META_COMPOSITOR (compositor_x11); + MetaDisplay *display = meta_compositor_get_display (compositor); + MetaX11Display *x11_display = display->x11_display; + uint32_t server_time_ms; + int64_t server_time_us; + int64_t translated_monotonic_now_us; + + server_time_ms = meta_x11_display_get_current_time_roundtrip (x11_display); + server_time_us = ms2us (server_time_ms); + translated_monotonic_now_us = + meta_translate_to_high_res_xserver_time (g_get_monotonic_time ()); + + /* If the server time offset is within a second of the monotonic time, we + * assume that they are identical. This seems like a big margin, but we want + * to be as robust as possible even if the system is under load and our + * processing of the server response is delayed. + */ + if (ABS (server_time_us - translated_monotonic_now_us) < s2us (1)) + compositor_x11->xserver_uses_monotonic_clock = TRUE; + else + compositor_x11->xserver_uses_monotonic_clock = FALSE; +} + +static void +meta_compositor_x11_manage (MetaCompositor *compositor) +{ + MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (compositor); + MetaDisplay *display = meta_compositor_get_display (compositor); + Display *xdisplay = meta_x11_display_get_xdisplay (display->x11_display); + MetaBackend *backend = meta_get_backend (); + Window xwindow; + + determine_server_clock_source (compositor_x11); + + meta_x11_display_set_cm_selection (display->x11_display); + + compositor_x11->output = display->x11_display->composite_overlay_window; + + xwindow = meta_backend_x11_get_xwindow (META_BACKEND_X11 (backend)); + + XReparentWindow (xdisplay, xwindow, compositor_x11->output, 0, 0); + + meta_x11_display_clear_stage_input_region (display->x11_display); + + /* + * Make sure there isn't any left-over output shape on the overlay window by + * setting the whole screen to be an output region. + * + * Note: there doesn't seem to be any real chance of that because the X + * server will destroy the overlay window when the last client using it + * exits. + */ + XFixesSetWindowShapeRegion (xdisplay, compositor_x11->output, + ShapeBounding, 0, 0, None); + + /* + * Map overlay window before redirecting windows offscreen so we catch their + * contents until we show the stage. + */ + XMapWindow (xdisplay, compositor_x11->output); + + compositor_x11->have_x11_sync_object = meta_sync_ring_init (xdisplay); + + meta_compositor_redirect_x11_windows (META_COMPOSITOR (compositor)); +} + +static void +meta_compositor_x11_unmanage (MetaCompositor *compositor) +{ + MetaDisplay *display = meta_compositor_get_display (compositor); + MetaX11Display *x11_display = display->x11_display; + Display *xdisplay = x11_display->xdisplay; + Window xroot = x11_display->xroot; + + /* + * This is the most important part of cleanup - we have to do this before + * giving up the window manager selection or the next window manager won't be + * able to redirect subwindows + */ + XCompositeUnredirectSubwindows (xdisplay, xroot, CompositeRedirectManual); +} + +/* + * Sets an bounding shape on the COW so that the given window + * is exposed. If window is %NULL it clears the shape again. + * + * Used so we can unredirect windows, by shaping away the part + * of the COW, letting the raw window be seen through below. + */ +static void +shape_cow_for_window (MetaCompositorX11 *compositor_x11, + MetaWindow *window) +{ + MetaCompositor *compositor = META_COMPOSITOR (compositor_x11); + MetaDisplay *display = meta_compositor_get_display (compositor); + Display *xdisplay = meta_x11_display_get_xdisplay (display->x11_display); + + if (!window) + { + XFixesSetWindowShapeRegion (xdisplay, compositor_x11->output, + ShapeBounding, 0, 0, None); + } + else + { + XserverRegion output_region; + XRectangle screen_rect, window_bounds; + int width, height; + MetaRectangle rect; + + meta_window_get_frame_rect (window, &rect); + + window_bounds.x = rect.x; + window_bounds.y = rect.y; + window_bounds.width = rect.width; + window_bounds.height = rect.height; + + meta_display_get_size (display, &width, &height); + screen_rect.x = 0; + screen_rect.y = 0; + screen_rect.width = width; + screen_rect.height = height; + + output_region = XFixesCreateRegion (xdisplay, &window_bounds, 1); + + XFixesInvertRegion (xdisplay, output_region, &screen_rect, output_region); + XFixesSetWindowShapeRegion (xdisplay, compositor_x11->output, + ShapeBounding, 0, 0, output_region); + XFixesDestroyRegion (xdisplay, output_region); + } +} + +static void +on_redirected_monitor_changed (MetaWindow *window, + int old_monitor, + MetaCompositorX11 *compositor_x11) +{ + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + + if (old_monitor >= 0 && window->monitor && + window->monitor->number != old_monitor) + { + g_signal_handlers_block_by_func (window, + on_redirected_monitor_changed, + compositor_x11); + + if (!compositor_x11->randr_scale_disabled) + { + compositor_x11->randr_scale_disabled = + meta_monitor_manager_disable_scale_for_monitor (monitor_manager, + window->monitor); + } + + g_signal_handlers_unblock_by_func (window, + on_redirected_monitor_changed, + compositor_x11); + } + else + shape_cow_for_window (META_COMPOSITOR_X11 (compositor_x11), window); +} + +static MetaWindow * +get_unredirectable_window (MetaCompositorX11 *compositor_x11) +{ + MetaCompositor *compositor = META_COMPOSITOR (compositor_x11); + MetaWindowActor *window_actor; + MetaWindowActorX11 *window_actor_x11; + + window_actor = meta_compositor_get_top_window_actor (compositor); + if (!window_actor) + return NULL; + + window_actor_x11 = META_WINDOW_ACTOR_X11 (window_actor); + if (!meta_window_actor_x11_should_unredirect (window_actor_x11)) + return NULL; + + return meta_window_actor_get_meta_window (window_actor); +} + +static void +set_unredirected_window (MetaCompositorX11 *compositor_x11, + MetaWindow *window) +{ + MetaBackend *backend; + MetaMonitorManager *monitor_manager; + MetaWindow *prev_unredirected_window = compositor_x11->unredirected_window; + + if (prev_unredirected_window == window) + { + if (!window && compositor_x11->randr_scale_disabled && + !get_unredirectable_window (compositor_x11)) + { + backend = meta_get_backend (); + monitor_manager = meta_backend_get_monitor_manager (backend); + + compositor_x11->randr_scale_disabled = + meta_monitor_manager_disable_scale_for_monitor (monitor_manager, + NULL); + } + + return; + } + + backend = meta_get_backend (); + monitor_manager = meta_backend_get_monitor_manager (backend); + + if (prev_unredirected_window) + { + MetaWindowActor *window_actor; + MetaWindowActorX11 *window_actor_x11; + + g_signal_handlers_disconnect_by_func (prev_unredirected_window, + on_redirected_monitor_changed, + compositor_x11); + + window_actor = meta_window_actor_from_window (prev_unredirected_window); + window_actor_x11 = META_WINDOW_ACTOR_X11 (window_actor); + meta_window_actor_x11_set_unredirected (window_actor_x11, FALSE); + } + + shape_cow_for_window (compositor_x11, window); + compositor_x11->unredirected_window = window; + + if (window) + { + MetaWindowActor *window_actor; + MetaWindowActorX11 *window_actor_x11; + + if (!compositor_x11->randr_scale_disabled) + { + compositor_x11->randr_scale_disabled = + meta_monitor_manager_disable_scale_for_monitor (monitor_manager, + window->monitor); + } + + g_signal_connect_object (window, "monitor-changed", + G_CALLBACK (on_redirected_monitor_changed), + compositor_x11, 0); + + window_actor = meta_window_actor_from_window (window); + window_actor_x11 = META_WINDOW_ACTOR_X11 (window_actor); + meta_window_actor_x11_set_unredirected (window_actor_x11, TRUE); + } +} + +static void +maybe_unredirect_top_window (MetaCompositorX11 *compositor_x11) +{ + MetaCompositor *compositor = META_COMPOSITOR (compositor_x11); + MetaWindow *window_to_unredirect = NULL; + + if (meta_compositor_is_unredirect_inhibited (compositor)) + goto out; + + window_to_unredirect = get_unredirectable_window (compositor_x11); + +out: + set_unredirected_window (compositor_x11, window_to_unredirect); +} + +static void +meta_compositor_x11_pre_paint (MetaCompositor *compositor) +{ + MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (compositor); + MetaCompositorClass *parent_class; + + maybe_unredirect_top_window (compositor_x11); + + parent_class = META_COMPOSITOR_CLASS (meta_compositor_x11_parent_class); + parent_class->pre_paint (compositor); + + if (compositor_x11->frame_has_updated_xsurfaces) + { + MetaDisplay *display = meta_compositor_get_display (compositor); + + /* + * We need to make sure that any X drawing that happens before the + * XDamageSubtract() for each window above is visible to subsequent GL + * rendering; the standardized way to do this is GL_EXT_X11_sync_object. + * Since this isn't implemented yet in mesa, we also have a path that + * relies on the implementation of the open source drivers. + * + * Anything else, we just hope for the best. + * + * Xorg and open source driver specifics: + * + * The X server makes sure to flush drawing to the kernel before sending + * out damage events, but since we use DamageReportBoundingBox there may + * be drawing between the last damage event and the XDamageSubtract() + * that needs to be flushed as well. + * + * Xorg always makes sure that drawing is flushed to the kernel before + * writing events or responses to the client, so any round trip request + * at this point is sufficient to flush the GLX buffers. + */ + if (compositor_x11->have_x11_sync_object) + compositor_x11->have_x11_sync_object = meta_sync_ring_insert_wait (); + else + XSync (display->x11_display->xdisplay, False); + } +} + +static void +meta_compositor_x11_post_paint (MetaCompositor *compositor) +{ + MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (compositor); + MetaCompositorClass *parent_class; + + if (compositor_x11->frame_has_updated_xsurfaces) + { + if (compositor_x11->have_x11_sync_object) + compositor_x11->have_x11_sync_object = meta_sync_ring_after_frame (); + + compositor_x11->frame_has_updated_xsurfaces = FALSE; + } + + parent_class = META_COMPOSITOR_CLASS (meta_compositor_x11_parent_class); + parent_class->post_paint (compositor); +} + +static void +meta_compositor_x11_remove_window (MetaCompositor *compositor, + MetaWindow *window) +{ + MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (compositor); + MetaCompositorClass *parent_class; + + if (compositor_x11->unredirected_window == window) + set_unredirected_window (compositor_x11, NULL); + + parent_class = META_COMPOSITOR_CLASS (meta_compositor_x11_parent_class); + parent_class->remove_window (compositor, window); +} + +static int64_t +meta_compositor_x11_monotonic_to_high_res_xserver_time (MetaCompositor *compositor, + int64_t monotonic_time_us) +{ + MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (compositor); + int64_t now_us; + + if (compositor_x11->xserver_uses_monotonic_clock) + return meta_translate_to_high_res_xserver_time (monotonic_time_us); + + now_us = g_get_monotonic_time (); + + if (compositor_x11->xserver_time_query_time_us == 0 || + now_us > (compositor_x11->xserver_time_query_time_us + s2us (10))) + { + MetaDisplay *display = meta_compositor_get_display (compositor); + MetaX11Display *x11_display = display->x11_display; + uint32_t xserver_time_ms; + int64_t xserver_time_us; + + compositor_x11->xserver_time_query_time_us = now_us; + + xserver_time_ms = + meta_x11_display_get_current_time_roundtrip (x11_display); + xserver_time_us = ms2us (xserver_time_ms); + compositor_x11->xserver_time_offset_us = xserver_time_us - now_us; + } + + return monotonic_time_us + compositor_x11->xserver_time_offset_us; +} + +Window +meta_compositor_x11_get_output_xwindow (MetaCompositorX11 *compositor_x11) +{ + return compositor_x11->output; +} + +MetaCompositorX11 * +meta_compositor_x11_new (MetaDisplay *display) +{ + return g_object_new (META_TYPE_COMPOSITOR_X11, + "display", display, + NULL); +} + +static void +meta_compositor_x11_dispose (GObject *object) +{ + MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (object); + + if (compositor_x11->have_x11_sync_object) + { + meta_sync_ring_destroy (); + compositor_x11->have_x11_sync_object = FALSE; + } + + G_OBJECT_CLASS (meta_compositor_x11_parent_class)->dispose (object); +} + +static void +meta_compositor_x11_init (MetaCompositorX11 *compositor_x11) +{ +} + +static void +meta_compositor_x11_class_init (MetaCompositorX11Class *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MetaCompositorClass *compositor_class = META_COMPOSITOR_CLASS (klass); + + object_class->dispose = meta_compositor_x11_dispose; + + compositor_class->manage = meta_compositor_x11_manage; + compositor_class->unmanage = meta_compositor_x11_unmanage; + compositor_class->pre_paint = meta_compositor_x11_pre_paint; + compositor_class->post_paint = meta_compositor_x11_post_paint; + compositor_class->remove_window = meta_compositor_x11_remove_window; + compositor_class->monotonic_to_high_res_xserver_time = + meta_compositor_x11_monotonic_to_high_res_xserver_time; +} diff --git a/src/compositor/meta-compositor-x11.h b/src/compositor/meta-compositor-x11.h new file mode 100644 index 000000000..7165493cd --- /dev/null +++ b/src/compositor/meta-compositor-x11.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2019 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#ifndef META_COMPOSITOR_X11_H +#define META_COMPOSITOR_X11_H + +#include "compositor/compositor-private.h" + +#define META_TYPE_COMPOSITOR_X11 (meta_compositor_x11_get_type ()) +G_DECLARE_FINAL_TYPE (MetaCompositorX11, meta_compositor_x11, + META, COMPOSITOR_X11, MetaCompositor) + +MetaCompositorX11 * meta_compositor_x11_new (MetaDisplay *display); + +void meta_compositor_x11_process_xevent (MetaCompositorX11 *compositor_x11, + XEvent *xevent, + MetaWindow *window); + +Window meta_compositor_x11_get_output_xwindow (MetaCompositorX11 *compositor_x11); + +#endif /* META_COMPOSITOR_X11_H */ diff --git a/src/compositor/meta-cullable.c b/src/compositor/meta-cullable.c new file mode 100644 index 000000000..6f38c5e47 --- /dev/null +++ b/src/compositor/meta-cullable.c @@ -0,0 +1,245 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * Copyright (C) 2013 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Written by: + * Owen Taylor <otaylor@redhat.com> + * Ray Strode <rstrode@redhat.com> + * Jasper St. Pierre <jstpierre@mecheye.net> + */ + +#include "config.h" + +#include "compositor/clutter-utils.h" +#include "compositor/meta-cullable.h" + +G_DEFINE_INTERFACE (MetaCullable, meta_cullable, CLUTTER_TYPE_ACTOR); + +static gboolean +has_active_effects (ClutterActor *actor) +{ + g_autoptr (GList) effects = NULL; + GList *l; + + effects = clutter_actor_get_effects (actor); + for (l = effects; l != NULL; l = l->next) + { + if (clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (l->data))) + return TRUE; + } + + return FALSE; +} + +/** + * SECTION:meta-cullable + * @title: MetaCullable + * @short_description: CPU culling operations for efficient drawing + * + * When we are painting a stack of 5-10 large actors, the standard + * bottom-to-top method of drawing every actor results in a tremendous + * amount of overdraw. If these actors are painting textures like + * windows, it can easily max out the available memory bandwidth on a + * low-end graphics chipset. It's even worse if window textures are + * being accessed over the AGP bus. + * + * #MetaCullable is our solution. The basic technique applied here is to + * do a pre-pass before painting where we walk each actor from top to bottom + * and ask each actor to "cull itself out". We pass in a region it can copy + * to clip its drawing to, and the actor can subtract its fully opaque pixels + * so that actors underneath know not to draw there as well. + */ + +/** + * meta_cullable_cull_out_children: + * @cullable: The #MetaCullable + * @unobscured_region: The unobscured region, as passed into cull_out() + * @clip_region: The clip region, as passed into cull_out() + * + * This is a helper method for actors that want to recurse over their + * child actors, and cull them out. + * + * See #MetaCullable and meta_cullable_cull_out() for more details. + */ +void +meta_cullable_cull_out_children (MetaCullable *cullable, + cairo_region_t *unobscured_region, + cairo_region_t *clip_region) +{ + ClutterActor *actor = CLUTTER_ACTOR (cullable); + ClutterActor *child; + ClutterActorIter iter; + + clutter_actor_iter_init (&iter, actor); + while (clutter_actor_iter_prev (&iter, &child)) + { + float x, y; + gboolean needs_culling; + + if (!META_IS_CULLABLE (child)) + continue; + + needs_culling = (unobscured_region != NULL && clip_region != NULL); + + if (needs_culling && !CLUTTER_ACTOR_IS_VISIBLE (child)) + needs_culling = FALSE; + + /* If an actor has effects applied, then that can change the area + * it paints and the opacity, so we no longer can figure out what + * portion of the actor is obscured and what portion of the screen + * it obscures, so we skip the actor. + * + * This has a secondary beneficial effect: if a ClutterOffscreenEffect + * is applied to an actor, then our clipped redraws interfere with the + * caching of the FBO - even if we only need to draw a small portion + * of the window right now, ClutterOffscreenEffect may use other portions + * of the FBO later. So, skipping actors with effects applied also + * prevents these bugs. + * + * Theoretically, we should check clutter_actor_get_offscreen_redirect() + * as well for the same reason, but omitted for simplicity in the + * hopes that no-one will do that. + */ + if (needs_culling && has_active_effects (child)) + needs_culling = FALSE; + + if (needs_culling && !meta_cullable_is_untransformed (META_CULLABLE (child))) + needs_culling = FALSE; + + if (needs_culling) + { + clutter_actor_get_position (child, &x, &y); + + /* Temporarily move to the coordinate system of the actor */ + cairo_region_translate (unobscured_region, - x, - y); + cairo_region_translate (clip_region, - x, - y); + + meta_cullable_cull_out (META_CULLABLE (child), unobscured_region, clip_region); + + cairo_region_translate (unobscured_region, x, y); + cairo_region_translate (clip_region, x, y); + } + else + { + meta_cullable_cull_out (META_CULLABLE (child), NULL, NULL); + } + } +} + +/** + * meta_cullable_reset_culling_children: + * @cullable: The #MetaCullable + * + * This is a helper method for actors that want to recurse over their + * child actors, and cull them out. + * + * See #MetaCullable and meta_cullable_reset_culling() for more details. + */ +void +meta_cullable_reset_culling_children (MetaCullable *cullable) +{ + ClutterActor *actor = CLUTTER_ACTOR (cullable); + ClutterActor *child; + ClutterActorIter iter; + + clutter_actor_iter_init (&iter, actor); + while (clutter_actor_iter_next (&iter, &child)) + { + if (!META_IS_CULLABLE (child)) + continue; + + meta_cullable_reset_culling (META_CULLABLE (child)); + } +} + +static gboolean +meta_cullable_default_is_untransformed (MetaCullable *cullable) +{ + float width, height; + graphene_point3d_t verts[4]; + + clutter_actor_get_size (CLUTTER_ACTOR (cullable), &width, &height); + clutter_actor_get_abs_allocation_vertices (CLUTTER_ACTOR (cullable), verts); + + return meta_actor_vertices_are_untransformed (verts, width, height, + NULL, NULL); +} + +static void +meta_cullable_default_init (MetaCullableInterface *iface) +{ + iface->is_untransformed = meta_cullable_default_is_untransformed; +} + +/** + * meta_cullable_cull_out: + * @cullable: The #MetaCullable + * @unobscured_region: The unobscured region, in @cullable's space. + * @clip_region: The clip region, in @cullable's space. + * + * When #MetaWindowGroup is painted, we walk over its direct cullable + * children from top to bottom and ask themselves to "cull out". Cullables + * can use @unobscured_region and @clip_region to clip their drawing. Actors + * interested in eliminating overdraw should copy the @clip_region and only + * paint those parts, as everything else has been obscured by actors above it. + * + * Actors that may have fully opaque parts should also subtract out a region + * that is fully opaque from @unobscured_region and @clip_region. + * + * @unobscured_region and @clip_region are extremely similar. The difference + * is that @clip_region starts off with the stage's clip, if Clutter detects + * that we're doing a clipped redraw. @unobscured_region, however, starts off + * with the full stage size, so actors that may want to record what parts of + * their window are unobscured for e.g. scheduling repaints can do so. + * + * Actors that have children can also use the meta_cullable_cull_out_children() + * helper method to do a simple cull across all their children. + */ +void +meta_cullable_cull_out (MetaCullable *cullable, + cairo_region_t *unobscured_region, + cairo_region_t *clip_region) +{ + META_CULLABLE_GET_IFACE (cullable)->cull_out (cullable, unobscured_region, clip_region); +} + +/** + * meta_cullable_is_untransformed: + * @cullable: The #MetaCullable + * + * Check if a cullable is "untransformed" - which actually means transformed by + * at most a integer-translation. + */ +gboolean +meta_cullable_is_untransformed (MetaCullable *cullable) +{ + return META_CULLABLE_GET_IFACE (cullable)->is_untransformed (cullable); +} + +/** + * meta_cullable_reset_culling: + * @cullable: The #MetaCullable + * + * Actors that copied data in their cull_out() implementation can now + * reset their data, as the paint is now over. Additional paints may be + * done by #ClutterClone or similar, and they should not be affected by + * the culling operation. + */ +void +meta_cullable_reset_culling (MetaCullable *cullable) +{ + META_CULLABLE_GET_IFACE (cullable)->reset_culling (cullable); +} diff --git a/src/compositor/meta-cullable.h b/src/compositor/meta-cullable.h new file mode 100644 index 000000000..471681da3 --- /dev/null +++ b/src/compositor/meta-cullable.h @@ -0,0 +1,61 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2013 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Written by: + * Owen Taylor <otaylor@redhat.com> + * Ray Strode <rstrode@redhat.com> + * Jasper St. Pierre <jstpierre@mecheye.net> + */ + +#ifndef __META_CULLABLE_H__ +#define __META_CULLABLE_H__ + +#include "clutter/clutter.h" + +G_BEGIN_DECLS + +#define META_TYPE_CULLABLE (meta_cullable_get_type ()) +G_DECLARE_INTERFACE (MetaCullable, meta_cullable, META, CULLABLE, ClutterActor) + +struct _MetaCullableInterface +{ + GTypeInterface g_iface; + + void (* cull_out) (MetaCullable *cullable, + cairo_region_t *unobscured_region, + cairo_region_t *clip_region); + gboolean (* is_untransformed) (MetaCullable *cullable); + void (* reset_culling) (MetaCullable *cullable); +}; + +void meta_cullable_cull_out (MetaCullable *cullable, + cairo_region_t *unobscured_region, + cairo_region_t *clip_region); +gboolean meta_cullable_is_untransformed (MetaCullable *cullable); +void meta_cullable_reset_culling (MetaCullable *cullable); + +/* Utility methods for implementations */ +void meta_cullable_cull_out_children (MetaCullable *cullable, + cairo_region_t *unobscured_region, + cairo_region_t *clip_region); +void meta_cullable_reset_culling_children (MetaCullable *cullable); + +G_END_DECLS + +#endif /* __META_CULLABLE_H__ */ + diff --git a/src/compositor/meta-dnd-actor-private.h b/src/compositor/meta-dnd-actor-private.h new file mode 100644 index 000000000..20be369eb --- /dev/null +++ b/src/compositor/meta-dnd-actor-private.h @@ -0,0 +1,48 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * meta-dnd-actor-private.h: Actor for painting the DnD surface + * + * Copyright 2014 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef META_DND_ACTOR_PRIVATE_H +#define META_DND_ACTOR_PRIVATE_H + +#include "compositor/meta-feedback-actor-private.h" + +/** + * MetaDnDActor: + * + * This class handles the rendering of the DnD surface + */ + +#define META_TYPE_DND_ACTOR (meta_dnd_actor_get_type ()) +G_DECLARE_FINAL_TYPE (MetaDnDActor, + meta_dnd_actor, + META, DND_ACTOR, + MetaFeedbackActor) + + +ClutterActor *meta_dnd_actor_new (ClutterActor *drag_origin, + int start_x, + int start_y); + +void meta_dnd_actor_drag_finish (MetaDnDActor *self, + gboolean success); + +#endif /* META_DND_ACTOR_PRIVATE_H */ diff --git a/src/compositor/meta-dnd-actor.c b/src/compositor/meta-dnd-actor.c new file mode 100644 index 000000000..80bffdeb7 --- /dev/null +++ b/src/compositor/meta-dnd-actor.c @@ -0,0 +1,242 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * Copyright 2014 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +/** + * SECTION:meta-dnd-actor + * @title: MetaDnDActor + * @short_description: Actor for painting the drag and drop surface + * + */ + +#include "config.h" + +#include "compositor/meta-dnd-actor-private.h" +#include "compositor/meta-window-actor-private.h" + +#include "clutter/clutter.h" + +#define DRAG_FAILED_DURATION 500 + +enum +{ + PROP_DRAG_ORIGIN = 1, + PROP_DRAG_START_X, + PROP_DRAG_START_Y +}; + +struct _MetaDnDActor +{ + MetaFeedbackActor parent; + + ClutterActor *drag_origin; + int drag_start_x; + int drag_start_y; +}; + +G_DEFINE_TYPE (MetaDnDActor, meta_dnd_actor, META_TYPE_FEEDBACK_ACTOR) + +static void +meta_dnd_actor_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaDnDActor *self = META_DND_ACTOR (object); + + switch (prop_id) + { + case PROP_DRAG_ORIGIN: + self->drag_origin = g_value_get_object (value); + break; + case PROP_DRAG_START_X: + self->drag_start_x = g_value_get_int (value); + break; + case PROP_DRAG_START_Y: + self->drag_start_y = g_value_get_int (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_dnd_actor_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaDnDActor *self = META_DND_ACTOR (object); + + switch (prop_id) + { + case PROP_DRAG_ORIGIN: + g_value_set_object (value, self->drag_origin); + break; + case PROP_DRAG_START_X: + g_value_set_int (value, self->drag_start_x); + break; + case PROP_DRAG_START_Y: + g_value_set_int (value, self->drag_start_y); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_dnd_actor_class_init (MetaDnDActorClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GParamSpec *pspec; + + object_class->set_property = meta_dnd_actor_set_property; + object_class->get_property = meta_dnd_actor_get_property; + + pspec = g_param_spec_object ("drag-origin", + "Drag origin", + "The origin of the DnD operation", + CLUTTER_TYPE_ACTOR, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + + g_object_class_install_property (object_class, + PROP_DRAG_ORIGIN, + pspec); + + pspec = g_param_spec_int ("drag-start-x", + "Drag start X", + "The X axis of the drag start point", + 0, G_MAXINT, 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + + g_object_class_install_property (object_class, + PROP_DRAG_START_X, + pspec); + + pspec = g_param_spec_int ("drag-start-y", + "Drag start Y", + "The Y axis of the drag start point", + 0, G_MAXINT, 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + + g_object_class_install_property (object_class, + PROP_DRAG_START_Y, + pspec); +} + +static void +meta_dnd_actor_init (MetaDnDActor *self) +{ +} + +/** + * meta_dnd_actor_new: + * + * Creates a new actor to draw the current drag and drop surface. + * + * Return value: the newly created background actor + */ +ClutterActor * +meta_dnd_actor_new (ClutterActor *drag_origin, + int drag_start_x, + int drag_start_y) +{ + MetaDnDActor *self; + + self = g_object_new (META_TYPE_DND_ACTOR, + "drag-origin", drag_origin, + "drag-start-x", drag_start_x, + "drag-start-y", drag_start_y, + NULL); + + return CLUTTER_ACTOR (self); +} + +static void +drag_failed_complete (ClutterTimeline *timeline, + gboolean is_finished, + gpointer user_data) +{ + ClutterActor *self = user_data; + + clutter_actor_remove_all_children (self); + clutter_actor_destroy (self); +} + +void +meta_dnd_actor_drag_finish (MetaDnDActor *self, + gboolean success) +{ + ClutterActor *actor; + + g_return_if_fail (META_IS_DND_ACTOR (self)); + + actor = CLUTTER_ACTOR (self); + + if (success) + { + clutter_actor_remove_all_children (CLUTTER_ACTOR (self)); + clutter_actor_destroy (CLUTTER_ACTOR (self)); + } + else + { + ClutterTransition *transition; + + clutter_actor_save_easing_state (actor); + clutter_actor_set_easing_mode (actor, CLUTTER_EASE_OUT_CUBIC); + clutter_actor_set_easing_duration (actor, DRAG_FAILED_DURATION); + clutter_actor_set_opacity (actor, 0); + + if (CLUTTER_ACTOR_IS_VISIBLE (self->drag_origin)) + { + MetaWindowActor *origin_actor; + float anchor_x, anchor_y; + graphene_point_t dest; + int origin_geometry_scale; + int feedback_geometry_scale; + + clutter_actor_get_transformed_position (self->drag_origin, + &dest.x, &dest.y); + + origin_actor = meta_window_actor_from_actor (self->drag_origin); + g_return_if_fail (origin_actor); + origin_geometry_scale = + meta_window_actor_get_geometry_scale (origin_actor); + + meta_feedback_actor_get_anchor (META_FEEDBACK_ACTOR (self), + &anchor_x, &anchor_y); + feedback_geometry_scale = + meta_feedback_actor_get_geometry_scale (META_FEEDBACK_ACTOR (self)); + + dest.x += ((self->drag_start_x * origin_geometry_scale) - + (anchor_x * feedback_geometry_scale)); + dest.y += ((self->drag_start_y * origin_geometry_scale) - + (anchor_y * feedback_geometry_scale)); + clutter_actor_set_position (actor, dest.x, dest.y); + } + + transition = clutter_actor_get_transition (actor, "opacity"); + g_signal_connect (transition, "stopped", + G_CALLBACK (drag_failed_complete), self); + + clutter_actor_restore_easing_state (actor); + } +} diff --git a/src/compositor/meta-dnd.c b/src/compositor/meta-dnd.c new file mode 100644 index 000000000..7a2f72d65 --- /dev/null +++ b/src/compositor/meta-dnd.c @@ -0,0 +1,336 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * Copyright (C) 2016 Hyungwon Hwang + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include <gdk/gdkx.h> + +#include "clutter/x11/clutter-x11.h" +#include "meta/meta-backend.h" +#include "compositor/compositor-private.h" +#include "core/display-private.h" +#include "backends/meta-dnd-private.h" +#include "backends/x11/meta-backend-x11.h" +#include "backends/x11/meta-stage-x11.h" +#include "meta/meta-dnd.h" +#include "x11/meta-x11-display-private.h" + +struct _MetaDndClass +{ + GObjectClass parent_class; +}; + +#ifdef HAVE_WAYLAND +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-wayland-data-device.h" +#endif + +typedef struct _MetaDndPrivate MetaDndPrivate; + +struct _MetaDndPrivate +{ +#ifdef HAVE_WAYLAND + gulong handler_id[3]; + + MetaCompositor *compositor; + MetaWaylandCompositor *wl_compositor; +#else + /* to avoid warnings (g_type_class_add_private: assertion `private_size > 0' failed) */ + gchar dummy; +#endif +}; + +struct _MetaDnd +{ + GObject parent; + + MetaDndPrivate *priv; +}; + +G_DEFINE_TYPE_WITH_PRIVATE (MetaDnd, meta_dnd, G_TYPE_OBJECT); + +enum +{ + ENTER, + POSITION_CHANGE, + LEAVE, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +static void +meta_dnd_class_init (MetaDndClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + signals[ENTER] = + g_signal_new ("dnd-enter", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); + + signals[POSITION_CHANGE] = + g_signal_new ("dnd-position-change", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT); + + signals[LEAVE] = + g_signal_new ("dnd-leave", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); +} + +static void +meta_dnd_init (MetaDnd *dnd) +{ +} + +void +meta_dnd_init_xdnd (MetaX11Display *x11_display) +{ + MetaBackend *backend = meta_get_backend (); + Display *xdisplay = x11_display->xdisplay; + Window xwindow, overlay_xwindow; + long xdnd_version = 5; + + overlay_xwindow = x11_display->composite_overlay_window; + xwindow = meta_backend_x11_get_xwindow (META_BACKEND_X11 (backend)); + + XChangeProperty (xdisplay, xwindow, + XInternAtom (xdisplay, "XdndAware", TRUE), XA_ATOM, + 32, PropModeReplace, + (const unsigned char *) &xdnd_version, 1); + + XChangeProperty (xdisplay, overlay_xwindow, + XInternAtom (xdisplay, "XdndProxy", TRUE), XA_WINDOW, + 32, PropModeReplace, (const unsigned char *) &xwindow, 1); + + /* + * XdndProxy is additionally set on the proxy window as verification that the + * XdndProxy property on the target window isn't a left-over + */ + XChangeProperty (xdisplay, xwindow, + XInternAtom (xdisplay, "XdndProxy", TRUE), XA_WINDOW, + 32, PropModeReplace, (const unsigned char *) &xwindow, 1); +} + +static void +meta_dnd_notify_dnd_enter (MetaDnd *dnd) +{ + g_signal_emit (dnd, signals[ENTER], 0); +} + +static void +meta_dnd_notify_dnd_position_change (MetaDnd *dnd, + int x, + int y) +{ + g_signal_emit (dnd, signals[POSITION_CHANGE], 0, x, y); +} + +static void +meta_dnd_notify_dnd_leave (MetaDnd *dnd) +{ + g_signal_emit (dnd, signals[LEAVE], 0); +} + +/* + * Process Xdnd events + * + * We pass the position and leave events to the plugin via a signal + * where the actual drag & drop handling happens. + * + * http://www.freedesktop.org/wiki/Specifications/XDND + */ +gboolean +meta_dnd_handle_xdnd_event (MetaBackend *backend, + MetaCompositorX11 *compositor_x11, + Display *xdisplay, + XEvent *xev) +{ + MetaDnd *dnd = meta_backend_get_dnd (backend); + MetaCompositor *compositor = META_COMPOSITOR (compositor_x11); + Window output_window; + ClutterStage *stage; + + if (xev->xany.type != ClientMessage) + return FALSE; + + output_window = meta_compositor_x11_get_output_xwindow (compositor_x11); + stage = meta_compositor_get_stage (compositor); + if (xev->xany.window != output_window && + xev->xany.window != meta_x11_get_stage_window (stage)) + return FALSE; + + if (xev->xclient.message_type == XInternAtom (xdisplay, "XdndPosition", TRUE)) + { + XEvent xevent; + Window src = xev->xclient.data.l[0]; + + memset (&xevent, 0, sizeof(xevent)); + xevent.xany.type = ClientMessage; + xevent.xany.display = xdisplay; + xevent.xclient.window = src; + xevent.xclient.message_type = XInternAtom (xdisplay, "XdndStatus", TRUE); + xevent.xclient.format = 32; + xevent.xclient.data.l[0] = output_window; + /* flags: bit 0: will we accept the drop? bit 1: do we want more position messages */ + xevent.xclient.data.l[1] = 2; + xevent.xclient.data.l[4] = None; + + XSendEvent (xdisplay, src, False, 0, &xevent); + + meta_dnd_notify_dnd_position_change (dnd, + (int)(xev->xclient.data.l[2] >> 16), + (int)(xev->xclient.data.l[2] & 0xFFFF)); + + return TRUE; + } + else if (xev->xclient.message_type == XInternAtom (xdisplay, "XdndLeave", TRUE)) + { + meta_dnd_notify_dnd_leave (dnd); + + return TRUE; + } + else if (xev->xclient.message_type == XInternAtom (xdisplay, "XdndEnter", TRUE)) + { + meta_dnd_notify_dnd_enter (dnd); + + return TRUE; + } + + return FALSE; +} + +#ifdef HAVE_WAYLAND +static void +meta_dnd_wayland_on_motion_event (ClutterActor *actor, + ClutterEvent *event, + MetaDnd *dnd) +{ + MetaDndPrivate *priv = meta_dnd_get_instance_private (dnd); + MetaWaylandDragGrab *current_grab; + gfloat event_x, event_y; + + g_return_if_fail (event != NULL); + + clutter_event_get_coords (event, &event_x, &event_y); + meta_dnd_notify_dnd_position_change (dnd, (int)event_x, (int)event_y); + + current_grab = meta_wayland_data_device_get_current_grab (&priv->wl_compositor->seat->data_device); + if (current_grab) + meta_wayland_drag_grab_update_feedback_actor (current_grab, event); +} + +static void +meta_dnd_wayland_end_notify (ClutterActor *actor, + ClutterEvent *event, + MetaDnd *dnd) +{ + MetaDndPrivate *priv = meta_dnd_get_instance_private (dnd); + + meta_wayland_data_device_end_drag (&priv->wl_compositor->seat->data_device); + meta_dnd_wayland_handle_end_modal (priv->compositor); +} + +static void +meta_dnd_wayland_on_button_released (ClutterActor *actor, + ClutterEvent *event, + MetaDnd *dnd) +{ + meta_dnd_wayland_end_notify (actor, event, dnd); +} + +static void +meta_dnd_wayland_on_key_pressed (ClutterActor *actor, + ClutterEvent *event, + MetaDnd *dnd) +{ + guint key = clutter_event_get_key_symbol (event); + + if (key != CLUTTER_KEY_Escape) + return; + + meta_dnd_wayland_end_notify (actor, event, dnd); +} + +void +meta_dnd_wayland_handle_begin_modal (MetaCompositor *compositor) +{ + MetaWaylandCompositor *wl_compositor = meta_wayland_compositor_get_default (); + MetaDnd *dnd = meta_backend_get_dnd (meta_get_backend ()); + MetaDndPrivate *priv = meta_dnd_get_instance_private (dnd); + + if (priv->handler_id[0] == 0 && + meta_wayland_data_device_get_current_grab (&wl_compositor->seat->data_device) != NULL) + { + ClutterStage *stage = meta_compositor_get_stage (compositor); + + priv->compositor = compositor; + priv->wl_compositor = wl_compositor; + + priv->handler_id[0] = g_signal_connect (stage, + "motion-event", + G_CALLBACK (meta_dnd_wayland_on_motion_event), + dnd); + + priv->handler_id[1] = g_signal_connect (stage, + "button-release-event", + G_CALLBACK (meta_dnd_wayland_on_button_released), + dnd); + + priv->handler_id[2] = g_signal_connect (stage, + "key-press-event", + G_CALLBACK (meta_dnd_wayland_on_key_pressed), + dnd); + + meta_dnd_notify_dnd_enter (dnd); + } +} + +void +meta_dnd_wayland_handle_end_modal (MetaCompositor *compositor) +{ + MetaDnd *dnd = meta_backend_get_dnd (meta_get_backend ()); + MetaDndPrivate *priv = meta_dnd_get_instance_private (dnd); + ClutterStage *stage = meta_compositor_get_stage (compositor); + unsigned int i; + + if (!priv->compositor) + return; + + for (i = 0; i < G_N_ELEMENTS (priv->handler_id); i++) + g_clear_signal_handler (&priv->handler_id[i], stage); + + priv->compositor = NULL; + priv->wl_compositor = NULL; + + meta_dnd_notify_dnd_leave (dnd); +} +#endif diff --git a/src/compositor/meta-feedback-actor-private.h b/src/compositor/meta-feedback-actor-private.h new file mode 100644 index 000000000..86cacb360 --- /dev/null +++ b/src/compositor/meta-feedback-actor-private.h @@ -0,0 +1,70 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * meta-feedback-actor-private.h: Actor for painting user interaction feedback + * + * Copyright 2014 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef META_FEEDBACK_ACTOR_PRIVATE_H +#define META_FEEDBACK_ACTOR_PRIVATE_H + +#include "clutter/clutter.h" + +/** + * MetaFeedbackActor: + * + * This class handles the rendering of user interaction feedback + */ + +#define META_TYPE_FEEDBACK_ACTOR (meta_feedback_actor_get_type ()) +G_DECLARE_DERIVABLE_TYPE (MetaFeedbackActor, + meta_feedback_actor, + META, FEEDBACK_ACTOR, + ClutterActor) + + +struct _MetaFeedbackActorClass +{ + /*< private >*/ + ClutterActorClass parent_class; +}; + + +ClutterActor *meta_feedback_actor_new (float anchor_x, + float anchor_y); + +void meta_feedback_actor_set_anchor (MetaFeedbackActor *actor, + float anchor_x, + float anchor_y); +void meta_feedback_actor_get_anchor (MetaFeedbackActor *actor, + float *anchor_x, + float *anchor_y); + +void meta_feedback_actor_set_position (MetaFeedbackActor *self, + float x, + float y); + +void meta_feedback_actor_update (MetaFeedbackActor *self, + const ClutterEvent *event); + +void meta_feedback_actor_set_geometry_scale (MetaFeedbackActor *self, + int geometry_scale); + +int meta_feedback_actor_get_geometry_scale (MetaFeedbackActor *self); + +#endif /* META_FEEDBACK_ACTOR_PRIVATE_H */ diff --git a/src/compositor/meta-feedback-actor.c b/src/compositor/meta-feedback-actor.c new file mode 100644 index 000000000..d3277ec3a --- /dev/null +++ b/src/compositor/meta-feedback-actor.c @@ -0,0 +1,283 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * Copyright 2014 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +/** + * SECTION:meta-feedback-actor + * @title: MetaFeedbackActor + * @short_description: Actor for painting user interaction feedback + */ + +#include "config.h" + +#include "compositor/compositor-private.h" +#include "compositor/meta-feedback-actor-private.h" +#include "core/display-private.h" + +enum +{ + PROP_ANCHOR_X = 1, + PROP_ANCHOR_Y +}; + +typedef struct _MetaFeedbackActorPrivate MetaFeedbackActorPrivate; + +struct _MetaFeedbackActorPrivate +{ + float anchor_x; + float anchor_y; + float pos_x; + float pos_y; + + int geometry_scale; +}; + +G_DEFINE_TYPE_WITH_PRIVATE (MetaFeedbackActor, meta_feedback_actor, CLUTTER_TYPE_ACTOR) + +static void +meta_feedback_actor_constructed (GObject *object) +{ + MetaDisplay *display; + ClutterActor *feedback_group; + + display = meta_get_display (); + feedback_group = meta_get_feedback_group_for_display (display); + clutter_actor_add_child (feedback_group, CLUTTER_ACTOR (object)); +} + +static void +meta_feedback_actor_update_position (MetaFeedbackActor *self) +{ + MetaFeedbackActorPrivate *priv = meta_feedback_actor_get_instance_private (self); + + clutter_actor_set_position (CLUTTER_ACTOR (self), + priv->pos_x - + (priv->anchor_x * priv->geometry_scale), + priv->pos_y - + (priv->anchor_y * priv->geometry_scale)); +} + +static void +meta_feedback_actor_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaFeedbackActor *self = META_FEEDBACK_ACTOR (object); + MetaFeedbackActorPrivate *priv = meta_feedback_actor_get_instance_private (self); + + switch (prop_id) + { + case PROP_ANCHOR_X: + priv->anchor_x = g_value_get_int (value); + meta_feedback_actor_update_position (self); + break; + case PROP_ANCHOR_Y: + priv->anchor_y = g_value_get_int (value); + meta_feedback_actor_update_position (self); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_feedback_actor_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaFeedbackActor *self = META_FEEDBACK_ACTOR (object); + MetaFeedbackActorPrivate *priv = meta_feedback_actor_get_instance_private (self); + + switch (prop_id) + { + case PROP_ANCHOR_X: + g_value_set_float (value, priv->anchor_x); + break; + case PROP_ANCHOR_Y: + g_value_set_float (value, priv->anchor_y); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_feedback_actor_class_init (MetaFeedbackActorClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GParamSpec *pspec; + + object_class->constructed = meta_feedback_actor_constructed; + object_class->set_property = meta_feedback_actor_set_property; + object_class->get_property = meta_feedback_actor_get_property; + + pspec = g_param_spec_float ("anchor-x", + "Anchor X", + "The X axis of the anchor point", + 0, G_MAXFLOAT, 0, + G_PARAM_READWRITE); + + g_object_class_install_property (object_class, + PROP_ANCHOR_X, + pspec); + + pspec = g_param_spec_float ("anchor-y", + "Anchor Y", + "The Y axis of the anchor point", + 0, G_MAXFLOAT, 0, + G_PARAM_READWRITE); + + g_object_class_install_property (object_class, + PROP_ANCHOR_Y, + pspec); +} + +static void +meta_feedback_actor_init (MetaFeedbackActor *self) +{ + clutter_actor_set_reactive (CLUTTER_ACTOR (self), FALSE); +} + +/** + * meta_feedback_actor_new: + * + * Creates a new actor to draw the current drag and drop surface. + * + * Return value: the newly created background actor + */ +ClutterActor * +meta_feedback_actor_new (float anchor_x, + float anchor_y) +{ + MetaFeedbackActor *self; + + self = g_object_new (META_TYPE_FEEDBACK_ACTOR, + "anchor-x", anchor_x, + "anchor-y", anchor_y, + NULL); + + return CLUTTER_ACTOR (self); +} + +void +meta_feedback_actor_set_anchor (MetaFeedbackActor *self, + float anchor_x, + float anchor_y) +{ + MetaFeedbackActorPrivate *priv; + + g_return_if_fail (META_IS_FEEDBACK_ACTOR (self)); + + priv = meta_feedback_actor_get_instance_private (self); + + if (priv->anchor_x == anchor_x && priv->anchor_y == anchor_y) + return; + + if (priv->anchor_x != anchor_x) + { + priv->anchor_x = anchor_x; + g_object_notify (G_OBJECT (self), "anchor-x"); + } + + if (priv->anchor_y != anchor_y) + { + priv->anchor_y = anchor_y; + g_object_notify (G_OBJECT (self), "anchor-y"); + } + + meta_feedback_actor_update_position (self); +} + +void +meta_feedback_actor_get_anchor (MetaFeedbackActor *self, + float *anchor_x, + float *anchor_y) +{ + MetaFeedbackActorPrivate *priv; + + g_return_if_fail (META_IS_FEEDBACK_ACTOR (self)); + + priv = meta_feedback_actor_get_instance_private (self); + + if (anchor_x) + *anchor_x = priv->anchor_x; + if (anchor_y) + *anchor_y = priv->anchor_y; +} + +void +meta_feedback_actor_set_position (MetaFeedbackActor *self, + float x, + float y) +{ + MetaFeedbackActorPrivate *priv; + + g_return_if_fail (META_IS_FEEDBACK_ACTOR (self)); + + priv = meta_feedback_actor_get_instance_private (self); + priv->pos_x = x; + priv->pos_y = y; + + meta_feedback_actor_update_position (self); +} + +void +meta_feedback_actor_update (MetaFeedbackActor *self, + const ClutterEvent *event) +{ + graphene_point_t point; + + g_return_if_fail (META_IS_FEEDBACK_ACTOR (self)); + g_return_if_fail (event != NULL); + + clutter_event_get_position (event, &point); + meta_feedback_actor_set_position (self, point.x, point.y); +} + +void +meta_feedback_actor_set_geometry_scale (MetaFeedbackActor *self, + int geometry_scale) +{ + MetaFeedbackActorPrivate *priv = + meta_feedback_actor_get_instance_private (self); + CoglMatrix child_transform; + + if (priv->geometry_scale == geometry_scale) + return; + + priv->geometry_scale = geometry_scale; + + cogl_matrix_init_identity (&child_transform); + cogl_matrix_scale (&child_transform, geometry_scale, geometry_scale, 1); + clutter_actor_set_child_transform (CLUTTER_ACTOR (self), + &child_transform); +} + +int +meta_feedback_actor_get_geometry_scale (MetaFeedbackActor *self) +{ + MetaFeedbackActorPrivate *priv = + meta_feedback_actor_get_instance_private (self); + + return priv->geometry_scale; +} diff --git a/src/compositor/meta-module.c b/src/compositor/meta-module.c index e643d3cc8..d5aa64846 100644 --- a/src/compositor/meta-module.c +++ b/src/compositor/meta-module.c @@ -16,20 +16,18 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ -#if HAVE_CONFIG_H -#include <config.h> -#endif +#include "config.h" -#include <meta/meta-plugin.h> -#include "meta-module.h" +#include "compositor/meta-module.h" #include <gmodule.h> +#include "meta/meta-plugin.h" +#include "meta/meta-version.h" + enum { PROP_0, @@ -43,10 +41,7 @@ struct _MetaModulePrivate GType plugin_type; }; -#define META_MODULE_GET_PRIVATE(obj) \ -(G_TYPE_INSTANCE_GET_PRIVATE ((obj), META_TYPE_MODULE, MetaModulePrivate)) - -G_DEFINE_TYPE (MetaModule, meta_module, G_TYPE_TYPE_MODULE); +G_DEFINE_TYPE_WITH_PRIVATE (MetaModule, meta_module, G_TYPE_TYPE_MODULE); static gboolean meta_module_load (GTypeModule *gmodule) @@ -74,7 +69,7 @@ meta_module_load (GTypeModule *gmodule) (gpointer *)(void *)®ister_type) && info && register_type) { - if (info->version_api != MUFFIN_PLUGIN_API_VERSION) + if (info->version_api != META_PLUGIN_API_VERSION) g_warning ("Plugin API mismatch for [%s]", priv->path); else { @@ -122,7 +117,7 @@ meta_module_finalize (GObject *object) { MetaModulePrivate *priv = META_MODULE (object)->priv; - free (priv->path); + g_free (priv->path); priv->path = NULL; G_OBJECT_CLASS (meta_module_parent_class)->finalize (object); @@ -139,7 +134,7 @@ meta_module_set_property (GObject *object, switch (prop_id) { case PROP_PATH: - free (priv->path); + g_free (priv->path); priv->path = g_value_dup_string (value); break; default: @@ -189,20 +184,15 @@ meta_module_class_init (MetaModuleClass *klass) NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - g_type_class_add_private (gobject_class, sizeof (MetaModulePrivate)); } static void meta_module_init (MetaModule *self) { - MetaModulePrivate *priv; - - self->priv = priv = META_MODULE_GET_PRIVATE (self); - + self->priv = meta_module_get_instance_private (self); } -LOCAL_SYMBOL GType +GType meta_module_get_plugin_type (MetaModule *module) { MetaModulePrivate *priv = META_MODULE (module)->priv; diff --git a/src/compositor/meta-module.h b/src/compositor/meta-module.h index b63db51c3..dd6d5a685 100644 --- a/src/compositor/meta-module.h +++ b/src/compositor/meta-module.h @@ -16,9 +16,7 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_MODULE_H_ diff --git a/src/compositor/meta-plugin-manager.c b/src/compositor/meta-plugin-manager.c index c95849663..47bf922db 100644 --- a/src/compositor/meta-plugin-manager.c +++ b/src/compositor/meta-plugin-manager.c @@ -16,49 +16,50 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #include "config.h" -#include "compositor-private.h" -#include "meta-plugin-manager.h" -#include <meta/prefs.h> -#include <meta/errors.h> -#include <meta/workspace.h> -#include "meta-module.h" -#include "window-private.h" -#include <string.h> +#include "compositor/meta-plugin-manager.h" + #include <stdlib.h> +#include <string.h> -#include <clutter/x11/clutter-x11.h> +#include "clutter/x11/clutter-x11.h" +#include "compositor/compositor-private.h" +#include "compositor/meta-module.h" +#include "core/meta-close-dialog-default-private.h" +#include "core/meta-inhibit-shortcuts-dialog-default-private.h" +#include "core/window-private.h" +#include "meta/meta-x11-errors.h" +#include "meta/prefs.h" +#include "meta/workspace.h" static GType plugin_type = G_TYPE_NONE; struct MetaPluginManager { - MetaScreen *screen; - MetaPlugin *plugin; + MetaCompositor *compositor; + MetaPlugin *plugin; }; void meta_plugin_manager_set_plugin_type (GType gtype) { - if (plugin_type != G_TYPE_NONE) - meta_fatal ("Muffin plugin already set: %s", g_type_name (plugin_type)); + if (plugin_type != G_TYPE_NONE) + meta_fatal ("Mutter plugin already set: %s", g_type_name (plugin_type)); - plugin_type = gtype; + plugin_type = gtype; } /* * Loads the given plugin. */ void -meta_plugin_manager_load (const gchar *plugin_name) +meta_plugin_manager_load (const gchar *plugin_name) { - const gchar *dpath = MUFFIN_PLUGIN_DIR "/"; + const gchar *dpath = MUTTER_PLUGIN_DIR "/"; gchar *path; MetaModule *module; @@ -82,24 +83,38 @@ meta_plugin_manager_load (const gchar *plugin_name) meta_plugin_manager_set_plugin_type (meta_module_get_plugin_type (module)); g_type_module_unuse (G_TYPE_MODULE (module)); - free (path); + g_free (path); +} + +static void +on_confirm_display_change (MetaMonitorManager *monitors, + MetaPluginManager *plugin_mgr) +{ + meta_plugin_manager_confirm_display_change (plugin_mgr); } MetaPluginManager * -meta_plugin_manager_new (MetaScreen *screen) +meta_plugin_manager_new (MetaCompositor *compositor) { MetaPluginManager *plugin_mgr; MetaPluginClass *klass; MetaPlugin *plugin; + MetaMonitorManager *monitors; plugin_mgr = g_new0 (MetaPluginManager, 1); - plugin_mgr->screen = screen; - plugin_mgr->plugin = plugin = g_object_new (plugin_type, "screen", screen, NULL); + plugin_mgr->compositor = compositor; + plugin_mgr->plugin = plugin = g_object_new (plugin_type, NULL); + + _meta_plugin_set_compositor (plugin, compositor); klass = META_PLUGIN_GET_CLASS (plugin); if (klass->start) - klass->start(plugin); + klass->start (plugin); + + monitors = meta_monitor_manager_get (); + g_signal_connect (monitors, "confirm-display-change", + G_CALLBACK (on_confirm_display_change), plugin_mgr); return plugin_mgr; } @@ -108,11 +123,21 @@ static void meta_plugin_manager_kill_window_effects (MetaPluginManager *plugin_mgr, MetaWindowActor *actor) { - MetaPlugin *plugin = plugin_mgr->plugin; - MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin); + MetaPlugin *plugin = plugin_mgr->plugin; + MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin); + + if (klass->kill_window_effects) + klass->kill_window_effects (plugin, actor); +} + +static void +meta_plugin_manager_kill_switch_workspace (MetaPluginManager *plugin_mgr) +{ + MetaPlugin *plugin = plugin_mgr->plugin; + MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin); - if (klass->kill_window_effects) - klass->kill_window_effects (plugin, actor); + if (klass->kill_switch_workspace) + klass->kill_switch_workspace (plugin); } /* @@ -124,129 +149,95 @@ meta_plugin_manager_kill_window_effects (MetaPluginManager *plugin_mgr, * manager completed() callback, and the compositor must ensure that any * appropriate post-effect cleanup is carried out. */ -LOCAL_SYMBOL gboolean +gboolean meta_plugin_manager_event_simple (MetaPluginManager *plugin_mgr, MetaWindowActor *actor, - unsigned long event) + MetaPluginEffect event) { - MetaPlugin *plugin = plugin_mgr->plugin; - MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin); - MetaDisplay *display = meta_screen_get_display (plugin_mgr->screen); - gboolean retval = FALSE; + MetaPlugin *plugin = plugin_mgr->plugin; + MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin); + MetaDisplay *display = meta_compositor_get_display (plugin_mgr->compositor); + gboolean retval = FALSE; - if (display->display_opening) - return FALSE; + if (display->display_opening) + return FALSE; - switch (event) + switch (event) { - case META_PLUGIN_MINIMIZE: - if (klass->minimize) - { - retval = TRUE; - meta_plugin_manager_kill_window_effects (plugin_mgr, actor); - - _meta_plugin_effect_started (plugin); - klass->minimize (plugin, actor); - } - break; - case META_PLUGIN_MAP: - if (klass->map) - { - retval = TRUE; - meta_plugin_manager_kill_window_effects (plugin_mgr, actor); - - _meta_plugin_effect_started (plugin); - klass->map (plugin, actor); - } - break; - case META_PLUGIN_DESTROY: - if (klass->destroy) - { - retval = TRUE; - _meta_plugin_effect_started (plugin); - klass->destroy (plugin, actor); - } - break; - default: - g_warning ("Incorrect handler called for event %lu", event); + case META_PLUGIN_MINIMIZE: + if (klass->minimize) + { + retval = TRUE; + meta_plugin_manager_kill_window_effects (plugin_mgr, + actor); + klass->minimize (plugin, actor); + } + break; + case META_PLUGIN_UNMINIMIZE: + if (klass->unminimize) + { + retval = TRUE; + meta_plugin_manager_kill_window_effects (plugin_mgr, + actor); + klass->unminimize (plugin, actor); + } + break; + case META_PLUGIN_MAP: + if (klass->map) + { + retval = TRUE; + meta_plugin_manager_kill_window_effects (plugin_mgr, + actor); + klass->map (plugin, actor); + } + break; + case META_PLUGIN_DESTROY: + if (klass->destroy) + { + retval = TRUE; + meta_plugin_manager_kill_window_effects (plugin_mgr, + actor); + klass->destroy (plugin, actor); + } + break; + default: + g_warning ("Incorrect handler called for event %d", event); } - return retval; + return retval; } -/* - * The public method that the compositor hooks into for maximize and unmaximize - * events. - * - * Returns TRUE if the plugin handled the event type (i.e., - * if the return value is FALSE, there will be no subsequent call to the - * manager completed() callback, and the compositor must ensure that any - * appropriate post-effect cleanup is carried out. - */ -LOCAL_SYMBOL gboolean -meta_plugin_manager_event_maximize (MetaPluginManager *plugin_mgr, - MetaWindowActor *actor, - unsigned long event, - gint target_x, - gint target_y, - gint target_width, - gint target_height) +void +meta_plugin_manager_event_size_changed (MetaPluginManager *plugin_mgr, + MetaWindowActor *actor) +{ + MetaPlugin *plugin = plugin_mgr->plugin; + MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin); + + if (klass->size_changed) + klass->size_changed (plugin, actor); +} + +gboolean +meta_plugin_manager_event_size_change (MetaPluginManager *plugin_mgr, + MetaWindowActor *actor, + MetaSizeChange which_change, + MetaRectangle *old_frame_rect, + MetaRectangle *old_buffer_rect) { - MetaPlugin *plugin = plugin_mgr->plugin; - MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin); - MetaDisplay *display = meta_screen_get_display (plugin_mgr->screen); - gboolean retval = FALSE; + MetaPlugin *plugin = plugin_mgr->plugin; + MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin); + MetaDisplay *display = meta_compositor_get_display (plugin_mgr->compositor); - if (display->display_opening) - return FALSE; + if (display->display_opening) + return FALSE; - switch (event) - { - case META_PLUGIN_MAXIMIZE: - if (klass->maximize) - { - retval = TRUE; - meta_plugin_manager_kill_window_effects ( - plugin_mgr, - actor); - - _meta_plugin_effect_started (plugin); - klass->maximize (plugin, actor, - target_x, target_y, - target_width, target_height); - } - break; - case META_PLUGIN_UNMAXIMIZE: - if (klass->unmaximize) - { - retval = TRUE; - meta_plugin_manager_kill_window_effects ( - plugin_mgr, - actor); - - _meta_plugin_effect_started (plugin); - klass->unmaximize (plugin, actor, - target_x, target_y, - target_width, target_height); - } - break; - case META_PLUGIN_TILE: - if (klass->tile) - { - retval = TRUE; - meta_plugin_manager_kill_window_effects (plugin_mgr, - actor); - _meta_plugin_effect_started (plugin); - klass->tile (plugin, actor, - target_x, target_y, - target_width, target_height); - } - break; - default: - g_warning ("Incorrect handler called for event %lu", event); - } + if (!klass->size_change) + return FALSE; - return retval; + meta_plugin_manager_kill_window_effects (plugin_mgr, actor); + klass->size_change (plugin, actor, which_change, old_frame_rect, old_buffer_rect); + return TRUE; } /* @@ -257,141 +248,172 @@ meta_plugin_manager_event_maximize (MetaPluginManager *plugin_mgr, * manager completed() callback, and the compositor must ensure that any * appropriate post-effect cleanup is carried out. */ -LOCAL_SYMBOL gboolean +gboolean meta_plugin_manager_switch_workspace (MetaPluginManager *plugin_mgr, gint from, gint to, MetaMotionDirection direction) { - MetaPlugin *plugin = plugin_mgr->plugin; - MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin); - MetaDisplay *display = meta_screen_get_display (plugin_mgr->screen); - gboolean retval = FALSE; + MetaPlugin *plugin = plugin_mgr->plugin; + MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin); + MetaDisplay *display = meta_compositor_get_display (plugin_mgr->compositor); + gboolean retval = FALSE; - if (display->display_opening) - return FALSE; + if (display->display_opening) + return FALSE; - if (klass->switch_workspace) + if (klass->switch_workspace) { - retval = TRUE; - - _meta_plugin_effect_started (plugin); - klass->switch_workspace (plugin, from, to, direction); + retval = TRUE; + meta_plugin_manager_kill_switch_workspace (plugin_mgr); + klass->switch_workspace (plugin, from, to, direction); } - return retval; + return retval; } -/* - * The public method that the compositor hooks into for desktop switching. - * - * Returns TRUE if the plugin handled the event type (i.e., - * if the return value is FALSE, there will be no subsequent call to the - * manager completed() callback, and the compositor must ensure that any - * appropriate post-effect cleanup is carried out. - */ -LOCAL_SYMBOL gboolean +gboolean +meta_plugin_manager_filter_keybinding (MetaPluginManager *plugin_mgr, + MetaKeyBinding *binding) +{ + MetaPlugin *plugin = plugin_mgr->plugin; + MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin); + + if (klass->keybinding_filter) + return klass->keybinding_filter (plugin, binding); + + return FALSE; +} + +gboolean meta_plugin_manager_xevent_filter (MetaPluginManager *plugin_mgr, XEvent *xev) { MetaPlugin *plugin = plugin_mgr->plugin; - MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin); - if (!plugin_mgr) - return FALSE; + return _meta_plugin_xevent_filter (plugin, xev); +} + +void +meta_plugin_manager_confirm_display_change (MetaPluginManager *plugin_mgr) +{ + MetaPlugin *plugin = plugin_mgr->plugin; + MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin); - /* We need to make sure that clutter gets certain events, like - * ConfigureNotify on the stage window. If there is a plugin that - * provides an xevent_filter function, then it's the responsibility - * of that plugin to pass events to Clutter. Otherwise, we send the - * event directly to Clutter ourselves. - */ - if (klass->xevent_filter) - return klass->xevent_filter (plugin, xev); - else - return clutter_x11_handle_event (xev) != CLUTTER_X11_FILTER_CONTINUE; + if (klass->confirm_display_change) + klass->confirm_display_change (plugin); + else + meta_plugin_complete_display_change (plugin, TRUE); } gboolean meta_plugin_manager_show_tile_preview (MetaPluginManager *plugin_mgr, MetaWindow *window, MetaRectangle *tile_rect, - int tile_monitor_number, - guint snap_queued) + int tile_monitor_number) { - MetaPlugin *plugin = plugin_mgr->plugin; - MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin); - MetaDisplay *display = meta_screen_get_display (plugin_mgr->screen); + MetaPlugin *plugin = plugin_mgr->plugin; + MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin); + MetaDisplay *display = meta_compositor_get_display (plugin_mgr->compositor); - if (display->display_opening) - return FALSE; + if (display->display_opening) + return FALSE; - if (klass->show_tile_preview) + if (klass->show_tile_preview) { - klass->show_tile_preview (plugin, window, tile_rect, tile_monitor_number, snap_queued); - return TRUE; + klass->show_tile_preview (plugin, window, tile_rect, tile_monitor_number); + return TRUE; } - return FALSE; + return FALSE; } gboolean meta_plugin_manager_hide_tile_preview (MetaPluginManager *plugin_mgr) { - MetaPlugin *plugin = plugin_mgr->plugin; - MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin); - MetaDisplay *display = meta_screen_get_display (plugin_mgr->screen); + MetaPlugin *plugin = plugin_mgr->plugin; + MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin); + MetaDisplay *display = meta_compositor_get_display (plugin_mgr->compositor); - if (display->display_opening) - return FALSE; + if (display->display_opening) + return FALSE; - if (klass->hide_tile_preview) + if (klass->hide_tile_preview) { - klass->hide_tile_preview (plugin); - return TRUE; + klass->hide_tile_preview (plugin); + return TRUE; } - return FALSE; + return FALSE; } -gboolean -meta_plugin_manager_show_hud_preview (MetaPluginManager *plugin_mgr, - guint current_proximity_zone, - MetaRectangle *work_area, - guint snap_queued) +void +meta_plugin_manager_show_window_menu (MetaPluginManager *plugin_mgr, + MetaWindow *window, + MetaWindowMenuType menu, + int x, + int y) { - MetaPlugin *plugin = plugin_mgr->plugin; - MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin); - MetaDisplay *display = meta_screen_get_display (plugin_mgr->screen); + MetaPlugin *plugin = plugin_mgr->plugin; + MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin); + MetaDisplay *display = meta_compositor_get_display (plugin_mgr->compositor); - if (display->display_opening) - return FALSE; + if (display->display_opening) + return; - if (klass->show_hud_preview) - { - klass->show_hud_preview (plugin, current_proximity_zone, - work_area, snap_queued); - return TRUE; - } + if (klass->show_window_menu) + klass->show_window_menu (plugin, window, menu, x, y); +} - return FALSE; +void +meta_plugin_manager_show_window_menu_for_rect (MetaPluginManager *plugin_mgr, + MetaWindow *window, + MetaWindowMenuType menu, + MetaRectangle *rect) +{ + MetaPlugin *plugin = plugin_mgr->plugin; + MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin); + MetaDisplay *display = meta_compositor_get_display (plugin_mgr->compositor); + + if (display->display_opening) + return; + + if (klass->show_window_menu_for_rect) + klass->show_window_menu_for_rect (plugin, window, menu, rect); } -gboolean -meta_plugin_manager_hide_hud_preview (MetaPluginManager *plugin_mgr) +MetaCloseDialog * +meta_plugin_manager_create_close_dialog (MetaPluginManager *plugin_mgr, + MetaWindow *window) { - MetaPlugin *plugin = plugin_mgr->plugin; - MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin); - MetaDisplay *display = meta_screen_get_display (plugin_mgr->screen); + MetaPlugin *plugin = plugin_mgr->plugin; + MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin); - if (display->display_opening) - return FALSE; + if (klass->create_close_dialog) + return klass->create_close_dialog (plugin, window); - if (klass->hide_hud_preview) - { - klass->hide_hud_preview (plugin); - return TRUE; - } + return meta_close_dialog_default_new (window); +} - return FALSE; +MetaInhibitShortcutsDialog * +meta_plugin_manager_create_inhibit_shortcuts_dialog (MetaPluginManager *plugin_mgr, + MetaWindow *window) +{ + MetaPlugin *plugin = plugin_mgr->plugin; + MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin); + + if (klass->create_inhibit_shortcuts_dialog) + return klass->create_inhibit_shortcuts_dialog (plugin, window); + + return meta_inhibit_shortcuts_dialog_default_new (window); +} + +void +meta_plugin_manager_locate_pointer (MetaPluginManager *plugin_mgr) +{ + MetaPlugin *plugin = plugin_mgr->plugin; + MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin); + + if (klass->locate_pointer) + klass->locate_pointer (plugin); } diff --git a/src/compositor/meta-plugin-manager.h b/src/compositor/meta-plugin-manager.h index 9a76a06d0..d1c007fa1 100644 --- a/src/compositor/meta-plugin-manager.h +++ b/src/compositor/meta-plugin-manager.h @@ -16,30 +16,26 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_PLUGIN_MANAGER_H_ #define META_PLUGIN_MANAGER_H_ -#include <meta/types.h> -#include <meta/screen.h> - -#define META_PLUGIN_FROM_MANAGER_ -#include <meta/meta-plugin.h> -#undef META_PLUGIN_FROM_MANAGER_ - -#define META_PLUGIN_MINIMIZE (1<<0) -#define META_PLUGIN_MAXIMIZE (1<<1) -#define META_PLUGIN_UNMAXIMIZE (1<<2) -#define META_PLUGIN_TILE (1<<6) -#define META_PLUGIN_MAP (1<<3) -#define META_PLUGIN_DESTROY (1<<4) -#define META_PLUGIN_SWITCH_WORKSPACE (1<<5) - -#define META_PLUGIN_ALL_EFFECTS (~0) +#include "core/util-private.h" +#include "meta/meta-plugin.h" +#include "meta/types.h" + +typedef enum +{ + META_PLUGIN_NONE, + META_PLUGIN_MINIMIZE, + META_PLUGIN_MAP, + META_PLUGIN_DESTROY, + META_PLUGIN_SWITCH_WORKSPACE, + META_PLUGIN_UNMINIMIZE, + META_PLUGIN_SIZE_CHANGE, +} MetaPluginEffect; /** * MetaPluginManager: (skip) @@ -47,47 +43,63 @@ */ typedef struct MetaPluginManager MetaPluginManager; -MetaPluginManager * meta_plugin_manager_new (MetaScreen *screen); +MetaPluginManager * meta_plugin_manager_new (MetaCompositor *compositor); +META_EXPORT_TEST void meta_plugin_manager_load (const gchar *plugin_name); gboolean meta_plugin_manager_event_simple (MetaPluginManager *mgr, MetaWindowActor *actor, - unsigned long event); + MetaPluginEffect event); -gboolean meta_plugin_manager_event_maximize (MetaPluginManager *mgr, - MetaWindowActor *actor, - unsigned long event, - gint target_x, - gint target_y, - gint target_width, - gint target_height); -void meta_plugin_manager_update_workspaces (MetaPluginManager *mgr); +void meta_plugin_manager_event_size_changed (MetaPluginManager *mgr, + MetaWindowActor *actor); -void meta_plugin_manager_update_workspace (MetaPluginManager *mgr, - MetaWorkspace *w); +gboolean meta_plugin_manager_event_size_change (MetaPluginManager *mgr, + MetaWindowActor *actor, + MetaSizeChange which_change, + MetaRectangle *old_frame_rect, + MetaRectangle *old_buffer_rect); gboolean meta_plugin_manager_switch_workspace (MetaPluginManager *mgr, gint from, gint to, MetaMotionDirection direction); +gboolean meta_plugin_manager_filter_keybinding (MetaPluginManager *mgr, + MetaKeyBinding *binding); + gboolean meta_plugin_manager_xevent_filter (MetaPluginManager *mgr, XEvent *xev); +gboolean _meta_plugin_xevent_filter (MetaPlugin *plugin, + XEvent *xev); -gboolean meta_plugin_manager_show_tile_preview (MetaPluginManager *plugin_mgr, +void meta_plugin_manager_confirm_display_change (MetaPluginManager *mgr); + +gboolean meta_plugin_manager_show_tile_preview (MetaPluginManager *mgr, MetaWindow *window, MetaRectangle *tile_rect, - int tile_monitor_number, - guint snap_queued); + int tile_monitor_number); +gboolean meta_plugin_manager_hide_tile_preview (MetaPluginManager *mgr); + +void meta_plugin_manager_show_window_menu (MetaPluginManager *mgr, + MetaWindow *window, + MetaWindowMenuType menu, + int x, + int y); + +void meta_plugin_manager_show_window_menu_for_rect (MetaPluginManager *mgr, + MetaWindow *window, + MetaWindowMenuType menu, + MetaRectangle *rect); -gboolean meta_plugin_manager_hide_tile_preview (MetaPluginManager *plugin_mgr); +MetaCloseDialog * meta_plugin_manager_create_close_dialog (MetaPluginManager *plugin_mgr, + MetaWindow *window); -gboolean meta_plugin_manager_show_hud_preview (MetaPluginManager *plugin_mgr, - guint current_proximity_zone, - MetaRectangle *work_area, - guint snap_queued); +MetaInhibitShortcutsDialog * + meta_plugin_manager_create_inhibit_shortcuts_dialog (MetaPluginManager *plugin_mgr, + MetaWindow *window); -gboolean meta_plugin_manager_hide_hud_preview (MetaPluginManager *plugin_mgr); +void meta_plugin_manager_locate_pointer (MetaPluginManager *mgr); #endif diff --git a/src/compositor/meta-plugin.c b/src/compositor/meta-plugin.c index c9ee19a46..6be512016 100644 --- a/src/compositor/meta-plugin.c +++ b/src/compositor/meta-plugin.c @@ -16,145 +16,49 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ /** * SECTION:meta-plugin * @title: MetaPlugin * @short_description: Entry point for plugins + * */ -#include <meta/meta-plugin.h> -#include "meta-plugin-manager.h" -#include <meta/screen.h> -#include <meta/display.h> +#include "config.h" + +#include "meta/meta-plugin.h" #include <string.h> #include <X11/Xlib.h> #include <X11/extensions/Xfixes.h> #include <X11/extensions/shape.h> -#include <clutter/x11/clutter-x11.h> - -#include "compositor-private.h" -#include "meta-window-actor-private.h" - -G_DEFINE_ABSTRACT_TYPE (MetaPlugin, meta_plugin, G_TYPE_OBJECT); - -#define META_PLUGIN_GET_PRIVATE(obj) \ -(G_TYPE_INSTANCE_GET_PRIVATE ((obj), META_TYPE_PLUGIN, MetaPluginPrivate)) - -enum -{ - PROP_0, - PROP_SCREEN, - PROP_DEBUG_MODE, -}; -struct _MetaPluginPrivate -{ - MetaScreen *screen; +#include "backends/meta-monitor-manager-private.h" +#include "clutter/x11/clutter-x11.h" +#include "compositor/compositor-private.h" +#include "compositor/meta-window-actor-private.h" +#include "compositor/meta-plugin-manager.h" +#include "meta/display.h" +#include "meta/util.h" - gint running; - gboolean debug : 1; -}; -static void -meta_plugin_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) +typedef struct _MetaPluginPrivate { - MetaPluginPrivate *priv = META_PLUGIN (object)->priv; - - switch (prop_id) - { - case PROP_SCREEN: - priv->screen = g_value_get_object (value); - break; - case PROP_DEBUG_MODE: - priv->debug = g_value_get_boolean (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -meta_plugin_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - MetaPluginPrivate *priv = META_PLUGIN (object)->priv; - - switch (prop_id) - { - case PROP_SCREEN: - g_value_set_object (value, priv->screen); - break; - case PROP_DEBUG_MODE: - g_value_set_boolean (value, priv->debug); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} + MetaCompositor *compositor; +} MetaPluginPrivate; +G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaPlugin, meta_plugin, G_TYPE_OBJECT); static void meta_plugin_class_init (MetaPluginClass *klass) { - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - gobject_class->set_property = meta_plugin_set_property; - gobject_class->get_property = meta_plugin_get_property; - - g_object_class_install_property (gobject_class, - PROP_SCREEN, - g_param_spec_object ("screen", - "MetaScreen", - "MetaScreen", - META_TYPE_SCREEN, - G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_class, - PROP_DEBUG_MODE, - g_param_spec_boolean ("debug-mode", - "Debug Mode", - "Debug Mode", - FALSE, - G_PARAM_READABLE)); - - g_type_class_add_private (gobject_class, sizeof (MetaPluginPrivate)); } static void meta_plugin_init (MetaPlugin *self) { - MetaPluginPrivate *priv; - - self->priv = priv = META_PLUGIN_GET_PRIVATE (self); -} - -gboolean -meta_plugin_running (MetaPlugin *plugin) -{ - MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv; - - return (priv->running > 0); -} - -gboolean -meta_plugin_debug_mode (MetaPlugin *plugin) -{ - MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv; - - return priv->debug; } const MetaPluginInfo * @@ -168,35 +72,24 @@ meta_plugin_get_info (MetaPlugin *plugin) return NULL; } -/** - * _meta_plugin_effect_started: - * @plugin: the plugin - * - * Mark that an effect has started for the plugin. This is called - * internally by MetaPluginManager. - */ -void -_meta_plugin_effect_started (MetaPlugin *plugin) +gboolean +_meta_plugin_xevent_filter (MetaPlugin *plugin, + XEvent *xev) { - MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv; + MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin); - priv->running++; + if (klass->xevent_filter) + return klass->xevent_filter (plugin, xev); + else + return FALSE; } void meta_plugin_switch_workspace_completed (MetaPlugin *plugin) { - MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv; - - MetaScreen *screen = priv->screen; + MetaPluginPrivate *priv = meta_plugin_get_instance_private (plugin); - if (priv->running-- < 0) - { - g_warning ("Error in running effect accounting, adjusting."); - priv->running = 0; - } - - meta_switch_workspace_completed (screen); + meta_switch_workspace_completed (priv->compositor); } static void @@ -204,26 +97,6 @@ meta_plugin_window_effect_completed (MetaPlugin *plugin, MetaWindowActor *actor, unsigned long event) { - MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv; - - if (priv->running-- < 0) - { - g_warning ("Error in running effect accounting, adjusting."); - priv->running = 0; - } - - if (!actor) - { - const MetaPluginInfo *info; - const gchar *name = NULL; - - if (plugin && (info = meta_plugin_get_info (plugin))) - name = info->name; - - g_warning ("Plugin [%s] passed NULL for actor!", - name ? name : "unknown"); - } - meta_window_actor_effect_completed (actor, event); } @@ -235,24 +108,17 @@ meta_plugin_minimize_completed (MetaPlugin *plugin, } void -meta_plugin_maximize_completed (MetaPlugin *plugin, - MetaWindowActor *actor) -{ - meta_plugin_window_effect_completed (plugin, actor, META_PLUGIN_MAXIMIZE); -} - -void -meta_plugin_unmaximize_completed (MetaPlugin *plugin, +meta_plugin_unminimize_completed (MetaPlugin *plugin, MetaWindowActor *actor) { - meta_plugin_window_effect_completed (plugin, actor, META_PLUGIN_UNMAXIMIZE); + meta_plugin_window_effect_completed (plugin, actor, META_PLUGIN_UNMINIMIZE); } void -meta_plugin_tile_completed (MetaPlugin *plugin, - MetaWindowActor *actor) +meta_plugin_size_change_completed (MetaPlugin *plugin, + MetaWindowActor *actor) { - meta_plugin_window_effect_completed (plugin, actor, META_PLUGIN_TILE); + meta_plugin_window_effect_completed (plugin, actor, META_PLUGIN_SIZE_CHANGE); } void @@ -272,10 +138,6 @@ meta_plugin_destroy_completed (MetaPlugin *plugin, /** * meta_plugin_begin_modal: * @plugin: a #MetaPlugin - * @grab_window: the X window to grab the keyboard and mouse on - * @cursor: the cursor to use for the pointer grab, or None, - * to use the normal cursor for the grab window and - * its descendants. * @options: flags that modify the behavior of the modal grab * @timestamp: the timestamp used for establishing grabs * @@ -296,15 +158,13 @@ meta_plugin_destroy_completed (MetaPlugin *plugin, */ gboolean meta_plugin_begin_modal (MetaPlugin *plugin, - Window grab_window, - Cursor cursor, MetaModalOptions options, guint32 timestamp) { - MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv; + MetaPluginPrivate *priv = meta_plugin_get_instance_private (plugin); - return meta_begin_modal_for_plugin (priv->screen, plugin, - grab_window, cursor, options, timestamp); + return meta_begin_modal_for_plugin (priv->compositor, plugin, + options, timestamp); } /** @@ -322,25 +182,42 @@ void meta_plugin_end_modal (MetaPlugin *plugin, guint32 timestamp) { - MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv; + MetaPluginPrivate *priv = meta_plugin_get_instance_private (plugin); - meta_end_modal_for_plugin (priv->screen, plugin, timestamp); + meta_end_modal_for_plugin (priv->compositor, plugin, timestamp); } /** - * meta_plugin_get_screen: + * meta_plugin_get_display: * @plugin: a #MetaPlugin * - * Gets the #MetaScreen corresponding to a plugin. Each plugin instance - * is associated with exactly one screen; if Metacity is managing - * multiple screens, multiple plugin instances will be created. + * Gets the #MetaDisplay corresponding to a plugin. * - * Return value: (transfer none): the #MetaScreen for the plugin + * Return value: (transfer none): the #MetaDisplay for the plugin */ -MetaScreen * -meta_plugin_get_screen (MetaPlugin *plugin) +MetaDisplay * +meta_plugin_get_display (MetaPlugin *plugin) +{ + MetaPluginPrivate *priv = meta_plugin_get_instance_private (plugin); + MetaDisplay *display = meta_compositor_get_display (priv->compositor); + + return display; +} + +void +_meta_plugin_set_compositor (MetaPlugin *plugin, MetaCompositor *compositor) +{ + MetaPluginPrivate *priv = meta_plugin_get_instance_private (plugin); + + priv->compositor = compositor; +} + +void +meta_plugin_complete_display_change (MetaPlugin *plugin, + gboolean ok) { - MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv; + MetaMonitorManager *manager; - return priv->screen; + manager = meta_monitor_manager_get (); + meta_monitor_manager_confirm_configuration (manager, ok); } diff --git a/src/compositor/meta-shadow-factory-private.h b/src/compositor/meta-shadow-factory-private.h deleted file mode 100644 index fcdf53eee..000000000 --- a/src/compositor/meta-shadow-factory-private.h +++ /dev/null @@ -1,69 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* - * MetaShadowFactory: - * - * Create and cache shadow textures for arbitrary window shapes - * - * Copyright (C) 2010 Red Hat, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. - */ - -#ifndef __META_SHADOW_FACTORY_PRIVATE_H__ -#define __META_SHADOW_FACTORY_PRIVATE_H__ - -#include <cairo.h> -#include <clutter/clutter.h> -#include "meta-window-shape.h" -#include <meta/meta-shadow-factory.h> - -/** - * MetaShadow: - * #MetaShadow holds a shadow texture along with information about how to - * apply that texture to draw a window texture. (E.g., it knows how big the - * unscaled borders are on each side of the shadow texture.) - */ -typedef struct _MetaShadow MetaShadow; - -MetaShadow *meta_shadow_ref (MetaShadow *shadow); -void meta_shadow_unref (MetaShadow *shadow); -CoglTexture*meta_shadow_get_texture (MetaShadow *shadow); -void meta_shadow_paint (MetaShadow *shadow, - CoglFramebuffer *framebuffer, - int window_x, - int window_y, - int window_width, - int window_height, - guint8 opacity, - cairo_region_t *clip, - gboolean clip_strictly); -void meta_shadow_get_bounds (MetaShadow *shadow, - int window_x, - int window_y, - int window_width, - int window_height, - cairo_rectangle_int_t *bounds); - -MetaShadowFactory *meta_shadow_factory_new (void); - -MetaShadow *meta_shadow_factory_get_shadow (MetaShadowFactory *factory, - MetaWindowShape *shape, - int width, - int height, - const char *class_name, - gboolean focused); - -#endif /* __META_SHADOW_FACTORY_PRIVATE_H__ */ diff --git a/src/compositor/meta-shadow-factory.c b/src/compositor/meta-shadow-factory.c index 31840d022..c4228fa37 100644 --- a/src/compositor/meta-shadow-factory.c +++ b/src/compositor/meta-shadow-factory.c @@ -1,9 +1,5 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ /* - * MetaShadowFactory: - * - * Create and cache shadow textures for abritrary window shapes - * * Copyright 2010 Red Hat, Inc. * * This program is free software; you can redistribute it and/or @@ -17,24 +13,24 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ /** * SECTION:meta-shadow-factory * @title: MetaShadowFactory - * @short_description: Create and cache shadow textures for arbitrary window shapes + * @short_description: Create and cache shadow textures for abritrary window shapes */ -#include <config.h> +#include "config.h" + #include <math.h> #include <string.h> -#include "cogl-utils.h" -#include "meta-shadow-factory-private.h" -#include "region-utils.h" +#include "compositor/cogl-utils.h" +#include "compositor/region-utils.h" +#include "meta/meta-shadow-factory.h" +#include "meta/util.h" /* This file implements blurring the shape of a window to produce a * shadow texture. The details are discussed below; a quick summary @@ -110,14 +106,18 @@ struct _MetaShadowFactory GHashTable *shadow_classes; }; -struct _MetaShadowFactoryClass +enum { - GObjectClass parent_class; + CHANGED, + + LAST_SIGNAL }; +static guint signals[LAST_SIGNAL] = { 0 }; + /* The first element in this array also defines the default parameters * for newly created classes */ -static MetaShadowClassInfo default_shadow_classes[] = { +MetaShadowClassInfo default_shadow_classes[] = { { "normal", { 10, -1, 0, 3, 128 }, { 8, -1, 0, 2, 64 } }, { "dialog", { 10, -1, 0, 3, 128 }, { 8, -1, 0, 2, 64 } }, { "modal_dialog", { 10, -1, 0, 3, 128 }, { 8, -1, 0, 2, 64 } }, @@ -126,8 +126,8 @@ static MetaShadowClassInfo default_shadow_classes[] = { { "menu", { 10, -1, 0, 3, 128 }, { 8, -1, 0, 2, 64 } }, { "popup-menu", { 1, -1, 0, 0, 128 }, { 1, -1, 0, 0, 128 } }, - { "dropdown-menu", { 1, -1, 0, 0, 128 }, { 1, -1, 0, 0, 128 } }, + { "attached", { 10, -1, 0, 3, 128 }, { 8, -1, 0, 2, 64 } } }; @@ -152,7 +152,7 @@ meta_shadow_cache_key_equal (gconstpointer a, meta_window_shape_equal (key_a->shape, key_b->shape)); } -LOCAL_SYMBOL MetaShadow * +MetaShadow * meta_shadow_ref (MetaShadow *shadow) { shadow->ref_count++; @@ -160,7 +160,7 @@ meta_shadow_ref (MetaShadow *shadow) return shadow; } -LOCAL_SYMBOL void +void meta_shadow_unref (MetaShadow *shadow) { shadow->ref_count--; @@ -186,7 +186,7 @@ meta_shadow_unref (MetaShadow *shadow) * @window_y: y position of the region to paint a shadow for * @window_width: actual width of the region to paint a shadow for * @window_height: actual height of the region to paint a shadow for - * @clip: (allow-none): if non-%NULL specifies the visible portion + * @clip: (nullable): if non-%NULL specifies the visible portion * of the shadow. * @clip_strictly: if %TRUE, drawing will be clipped strictly * to @clip, otherwise, it will be only used to optimize @@ -197,7 +197,7 @@ meta_shadow_unref (MetaShadow *shadow) * different sizes with the same extracted #MetaWindowShape the * size needs to be passed in here.) */ -LOCAL_SYMBOL void +void meta_shadow_paint (MetaShadow *shadow, CoglFramebuffer *framebuffer, int window_x, @@ -207,7 +207,6 @@ meta_shadow_paint (MetaShadow *shadow, guint8 opacity, cairo_region_t *clip, gboolean clip_strictly) - { float texture_width = cogl_texture_get_width (shadow->texture); float texture_height = cogl_texture_get_height (shadow->texture); @@ -217,7 +216,12 @@ meta_shadow_paint (MetaShadow *shadow, int dest_x[4]; int dest_y[4]; int n_x, n_y; - gboolean source_updated = FALSE; + + if (clip && cairo_region_is_empty (clip)) + return; + + cogl_pipeline_set_color4ub (shadow->pipeline, + opacity, opacity, opacity, opacity); if (shadow->scale_width) { @@ -296,14 +300,6 @@ meta_shadow_paint (MetaShadow *shadow, if (overlap == CAIRO_REGION_OVERLAP_OUT) continue; - if (!source_updated) - { - cogl_pipeline_set_color4ub (shadow->pipeline, - opacity, opacity, opacity, opacity); -// cogl_set_source (shadow->pipeline); do not believe needed, but still there in mutter - source_updated = TRUE; - } - /* There's quite a bit of overhead from allocating a new * region in order to find an exact intersection and * generating more geometry - we make the assumption that @@ -324,19 +320,15 @@ meta_shadow_paint (MetaShadow *shadow, { cairo_region_t *intersection; int n_rectangles, k; - float *rects; intersection = cairo_region_create_rectangle (&dest_rect); cairo_region_intersect (intersection, clip); n_rectangles = cairo_region_num_rectangles (intersection); - rects = g_alloca (sizeof (float) * 8 * n_rectangles); - for (k = 0; k < n_rectangles; k++) { cairo_rectangle_int_t rect; float src_x1, src_x2, src_y1, src_y2; - int pos; cairo_region_get_rectangle (intersection, k, &rect); @@ -353,22 +345,13 @@ meta_shadow_paint (MetaShadow *shadow, src_y2 = (src_y[j] * (dest_rect.y + dest_rect.height - (rect.y + rect.height)) + src_y[j + 1] * (rect.y + rect.height - dest_rect.y)) / dest_rect.height; - pos = k*8; - rects[pos] = rect.x; - rects[pos+1] = rect.y; - rects[pos+2] = rect.x + rect.width; - rects[pos+3] = rect.y + rect.height; - rects[pos+4] = src_x1; - rects[pos+5] = src_y1; - rects[pos+6] = src_x2; - rects[pos+7] = src_y2; + cogl_framebuffer_draw_textured_rectangle (framebuffer, + shadow->pipeline, + rect.x, rect.y, + rect.x + rect.width, rect.y + rect.height, + src_x1, src_y1, src_x2, src_y2); } - cogl_framebuffer_draw_textured_rectangles (framebuffer, - shadow->pipeline, - rects, - n_rectangles); - cairo_region_destroy (intersection); } } @@ -386,7 +369,7 @@ meta_shadow_paint (MetaShadow *shadow, * Computes the bounds of the pixels that will be affected by * meta_shadow_paint() */ -LOCAL_SYMBOL void +void meta_shadow_get_bounds (MetaShadow *shadow, int window_x, int window_y, @@ -403,7 +386,7 @@ meta_shadow_get_bounds (MetaShadow *shadow, static void meta_shadow_class_info_free (MetaShadowClassInfo *class_info) { - free ((char *)class_info->name); + g_free ((char *)class_info->name); g_slice_free (MetaShadowClassInfo, class_info); } @@ -460,9 +443,17 @@ meta_shadow_factory_class_init (MetaShadowFactoryClass *klass) GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = meta_shadow_factory_finalize; + + signals[CHANGED] = + g_signal_new ("changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); } -LOCAL_SYMBOL MetaShadowFactory * +MetaShadowFactory * meta_shadow_factory_new (void) { return g_object_new (META_TYPE_SHADOW_FACTORY, NULL); @@ -511,7 +502,12 @@ get_box_filter_size (int radius) static int get_shadow_spread (int radius) { - int d = get_box_filter_size (radius); + int d; + + if (radius == 0) + return 0; + + d = get_box_filter_size (radius); if (d % 2 == 1) return 3 * (d / 2); @@ -551,7 +547,7 @@ blur_xspan (guchar *row, * be well predicted and there are enough different possibilities * that trying to write this as a series of unconditional loops * is hard and not an obvious win. The main slow down here seems - * to be the integer division for pixel; one possible optimization + * to be the integer division per pixel; one possible optimization * would be to accumulate into two 16-bit integer buffers and * only divide down after all three passes. (SSE parallel implementation * of the divide step is possible.) @@ -559,34 +555,34 @@ blur_xspan (guchar *row, for (i = x0 - d + offset; i < x1 + offset; i++) { if (i >= 0 && i < row_width) - sum += row[i]; + sum += row[i]; if (i >= x0 + offset) - { - if (i >= d) - sum -= row[i - d]; + { + if (i >= d) + sum -= row[i - d]; - tmp_buffer[i - offset] = (sum + d / 2) / d; - } + tmp_buffer[i - offset] = (sum + d / 2) / d; + } } - memcpy(row + x0, tmp_buffer + x0, x1 - x0); + memcpy (row + x0, tmp_buffer + x0, x1 - x0); } static void blur_rows (cairo_region_t *convolve_region, int x_offset, int y_offset, - guchar *buffer, - int buffer_width, - int buffer_height, + guchar *buffer, + int buffer_width, + int buffer_height, int d) { int i, j; int n_rectangles; guchar *tmp_buffer; - tmp_buffer = malloc (buffer_width); + tmp_buffer = g_malloc (buffer_width); n_rectangles = cairo_region_num_rectangles (convolve_region); for (i = 0; i < n_rectangles; i++) @@ -596,33 +592,33 @@ blur_rows (cairo_region_t *convolve_region, cairo_region_get_rectangle (convolve_region, i, &rect); for (j = y_offset + rect.y; j < y_offset + rect.y + rect.height; j++) - { - guchar *row = buffer + j * buffer_width; - int x0 = x_offset + rect.x; - int x1 = x0 + rect.width; + { + guchar *row = buffer + j * buffer_width; + int x0 = x_offset + rect.x; + int x1 = x0 + rect.width; /* We want to produce a symmetric blur that spreads a pixel * equally far to the left and right. If d is odd that happens * naturally, but for d even, we approximate by using a blur * on either side and then a centered blur of size d + 1. - * (techique also from the SVG specification) + * (technique also from the SVG specification) */ - if (d % 2 == 1) - { - blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 0); - blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 0); - blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 0); - } - else - { - blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 1); - blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, -1); - blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d + 1, 0); - } - } + if (d % 2 == 1) + { + blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 0); + blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 0); + blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 0); + } + else + { + blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 1); + blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, -1); + blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d + 1, 0); + } + } } - free (tmp_buffer); + g_free (tmp_buffer); } static void @@ -644,7 +640,7 @@ fade_bytes (guchar *bytes, */ static guchar * flip_buffer (guchar *buffer, - int width, + int width, int height) { /* Working in blocks increases cache efficiency, compared to reading @@ -656,54 +652,54 @@ flip_buffer (guchar *buffer, int i0, j0; for (j0 = 0; j0 < height; j0 += BLOCK_SIZE) - for (i0 = 0; i0 <= j0; i0 += BLOCK_SIZE) - { - int max_j = MIN(j0 + BLOCK_SIZE, height); - int max_i = MIN(i0 + BLOCK_SIZE, width); - int i, j; - - if (i0 == j0) - { - for (j = j0; j < max_j; j++) - for (i = i0; i < j; i++) - { - guchar tmp = buffer[j * width + i]; - buffer[j * width + i] = buffer[i * width + j]; - buffer[i * width + j] = tmp; - } - } - else - { - for (j = j0; j < max_j; j++) - for (i = i0; i < max_i; i++) - { - guchar tmp = buffer[j * width + i]; - buffer[j * width + i] = buffer[i * width + j]; - buffer[i * width + j] = tmp; - } - } - } + for (i0 = 0; i0 <= j0; i0 += BLOCK_SIZE) + { + int max_j = MIN(j0 + BLOCK_SIZE, height); + int max_i = MIN(i0 + BLOCK_SIZE, width); + int i, j; + + if (i0 == j0) + { + for (j = j0; j < max_j; j++) + for (i = i0; i < j; i++) + { + guchar tmp = buffer[j * width + i]; + buffer[j * width + i] = buffer[i * width + j]; + buffer[i * width + j] = tmp; + } + } + else + { + for (j = j0; j < max_j; j++) + for (i = i0; i < max_i; i++) + { + guchar tmp = buffer[j * width + i]; + buffer[j * width + i] = buffer[i * width + j]; + buffer[i * width + j] = tmp; + } + } + } return buffer; } else { - guchar *new_buffer = malloc (height * width); + guchar *new_buffer = g_malloc (height * width); int i0, j0; for (i0 = 0; i0 < width; i0 += BLOCK_SIZE) for (j0 = 0; j0 < height; j0 += BLOCK_SIZE) - { - int max_j = MIN(j0 + BLOCK_SIZE, height); - int max_i = MIN(i0 + BLOCK_SIZE, width); - int i, j; + { + int max_j = MIN(j0 + BLOCK_SIZE, height); + int max_i = MIN(i0 + BLOCK_SIZE, width); + int i, j; for (i = i0; i < max_i; i++) for (j = j0; j < max_j; j++) - new_buffer[i * height + j] = buffer[j * width + i]; - } + new_buffer[i * height + j] = buffer[j * width + i]; + } - free (buffer); + g_free (buffer); return new_buffer; } @@ -714,6 +710,9 @@ static void make_shadow (MetaShadow *shadow, cairo_region_t *region) { + ClutterBackend *backend = clutter_get_default_backend (); + CoglContext *ctx = clutter_backend_get_cogl_context (backend); + GError *error = NULL; int d = get_box_filter_size (shadow->key.radius); int spread = get_shadow_spread (shadow->key.radius); cairo_rectangle_int_t extents; @@ -752,7 +751,7 @@ make_shadow (MetaShadow *shadow, if (buffer_width < buffer_height && buffer_width > (3 * buffer_height) / 4) buffer_width = buffer_height; - buffer = calloc (1, buffer_width * buffer_height); + buffer = g_malloc0 (buffer_width * buffer_height); /* Blurring with multiple box-blur passes is fast, but (especially for * large shadow sizes) we can improve efficiency by restricting the blur @@ -773,7 +772,7 @@ make_shadow (MetaShadow *shadow, cairo_region_get_rectangle (region, k, &rect); for (j = y_offset + rect.y; j < y_offset + rect.y + rect.height; j++) - memset (buffer + buffer_width * j + x_offset + rect.x, 255, rect.width); + memset (buffer + buffer_width * j + x_offset + rect.x, 255, rect.width); } /* Step 2: swap rows and columns */ @@ -803,19 +802,25 @@ make_shadow (MetaShadow *shadow, * in the case of top_fade >= 0. We also account for padding at the left for symmetry * though that doesn't currently occur. */ - shadow->texture = meta_cogl_texture_new_from_data_wrapper (shadow->outer_border_left + extents.width + shadow->outer_border_right, - shadow->outer_border_top + extents.height + shadow->outer_border_bottom, - COGL_TEXTURE_NONE, - COGL_PIXEL_FORMAT_A_8, - COGL_PIXEL_FORMAT_ANY, - buffer_width, - (buffer + - (y_offset - shadow->outer_border_top) * buffer_width + - (x_offset - shadow->outer_border_left))); + shadow->texture = COGL_TEXTURE (cogl_texture_2d_new_from_data (ctx, + shadow->outer_border_left + extents.width + shadow->outer_border_right, + shadow->outer_border_top + extents.height + shadow->outer_border_bottom, + COGL_PIXEL_FORMAT_A_8, + buffer_width, + (buffer + + (y_offset - shadow->outer_border_top) * buffer_width + + (x_offset - shadow->outer_border_left)), + &error)); + + if (error) + { + meta_warning ("Failed to allocate shadow texture: %s\n", error->message); + g_error_free (error); + } cairo_region_destroy (row_convolve_region); cairo_region_destroy (column_convolve_region); - free (buffer); + g_free (buffer); shadow->pipeline = meta_create_texture_pipeline (shadow->texture); } @@ -869,7 +874,7 @@ get_shadow_params (MetaShadowFactory *factory, * Return value: (transfer full): a newly referenced #MetaShadow; unref with * meta_shadow_unref() */ -LOCAL_SYMBOL MetaShadow * +MetaShadow * meta_shadow_factory_get_shadow (MetaShadowFactory *factory, MetaWindowShape *shape, int width, @@ -1025,7 +1030,7 @@ meta_shadow_factory_set_params (MetaShadowFactory *factory, *stored_params = *params; - meta_compositor_on_shadow_factory_changed (); + g_signal_emit (factory, signals[CHANGED], 0); } /** @@ -1056,3 +1061,6 @@ meta_shadow_factory_get_params (MetaShadowFactory *factory, if (params) *params = *stored_params; } + +G_DEFINE_BOXED_TYPE (MetaShadow, meta_shadow, + meta_shadow_ref, meta_shadow_unref) diff --git a/src/compositor/meta-shaped-texture-private.h b/src/compositor/meta-shaped-texture-private.h index 18d61a728..c415260c0 100644 --- a/src/compositor/meta-shaped-texture-private.h +++ b/src/compositor/meta-shaped-texture-private.h @@ -27,10 +27,46 @@ #ifndef __META_SHAPED_TEXTURE_PRIVATE_H__ #define __META_SHAPED_TEXTURE_PRIVATE_H__ -#include <meta/meta-shaped-texture.h> +#include "backends/meta-monitor-manager-private.h" +#include "meta/meta-shaped-texture.h" -ClutterActor *meta_shaped_texture_new (void); +MetaShapedTexture *meta_shaped_texture_new (void); void meta_shaped_texture_set_texture (MetaShapedTexture *stex, CoglTexture *texture); +void meta_shaped_texture_set_is_y_inverted (MetaShapedTexture *stex, + gboolean is_y_inverted); +void meta_shaped_texture_set_snippet (MetaShapedTexture *stex, + CoglSnippet *snippet); +void meta_shaped_texture_set_fallback_size (MetaShapedTexture *stex, + int fallback_width, + int fallback_height); +cairo_region_t * meta_shaped_texture_get_opaque_region (MetaShapedTexture *stex); +gboolean meta_shaped_texture_is_opaque (MetaShapedTexture *stex); +gboolean meta_shaped_texture_has_alpha (MetaShapedTexture *stex); +void meta_shaped_texture_set_transform (MetaShapedTexture *stex, + MetaMonitorTransform transform); +void meta_shaped_texture_set_viewport_src_rect (MetaShapedTexture *stex, + graphene_rect_t *src_rect); +void meta_shaped_texture_reset_viewport_src_rect (MetaShapedTexture *stex); +void meta_shaped_texture_set_viewport_dst_size (MetaShapedTexture *stex, + int dst_width, + int dst_height); +void meta_shaped_texture_reset_viewport_dst_size (MetaShapedTexture *stex); +void meta_shaped_texture_set_buffer_scale (MetaShapedTexture *stex, + int buffer_scale); +int meta_shaped_texture_get_buffer_scale (MetaShapedTexture *stex); + +gboolean meta_shaped_texture_update_area (MetaShapedTexture *stex, + int x, + int y, + int width, + int height, + cairo_rectangle_int_t *clip); + +int meta_shaped_texture_get_width (MetaShapedTexture *stex); +int meta_shaped_texture_get_height (MetaShapedTexture *stex); + +void meta_shaped_texture_set_clip_region (MetaShapedTexture *stex, + cairo_region_t *clip_region); #endif diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c index 1f0a6e299..ec1faf9fc 100644 --- a/src/compositor/meta-shaped-texture.c +++ b/src/compositor/meta-shaped-texture.c @@ -1,11 +1,9 @@ /* - * shaped texture - * - * An actor to draw a texture clipped to a list of rectangles - * * Authored By Neil Roberts <neil@linux.intel.com> + * and Jasper St. Pierre <jstpierre@mecheye.net> * * Copyright (C) 2008 Intel Corporation + * Copyright (C) 2012 Red Hat, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -18,9 +16,7 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ /** @@ -29,20 +25,21 @@ * @short_description: An actor to draw a masked texture. */ -#include <config.h> +#include "config.h" -#include <meta/meta-shaped-texture.h> -#include "clutter-utils.h" -#include "meta-texture-tower.h" -#include "meta-texture-rectangle.h" -#include "meta-shaped-texture-private.h" -#include "cogl-utils.h" +#include "backends/meta-monitor-transform.h" +#include "compositor/meta-shaped-texture-private.h" +#include "core/boxes-private.h" -#include <clutter/clutter.h> -#include <cogl/cogl.h> -#include <cogl/winsys/cogl-texture-pixmap-x11.h> -#include <gdk/gdk.h> /* for gdk_rectangle_intersect() */ -#include <string.h> +#include <gdk/gdk.h> +#include <math.h> + +#include "cogl/cogl.h" +#include "compositor/clutter-utils.h" +#include "compositor/meta-texture-tower.h" +#include "compositor/region-utils.h" +#include "core/boxes-private.h" +#include "meta/meta-shaped-texture.h" /* MAX_MIPMAPPING_FPS needs to be as small as possible for the best GPU * performance, but higher than the refresh rate of commonly slow updating @@ -60,28 +57,10 @@ static void meta_shaped_texture_dispose (GObject *object); -static void meta_shaped_texture_paint (ClutterActor *actor); - -static void meta_shaped_texture_get_preferred_width (ClutterActor *self, - gfloat for_height, - gfloat *min_width_p, - gfloat *natural_width_p); - -static void meta_shaped_texture_get_preferred_height (ClutterActor *self, - gfloat for_width, - gfloat *min_height_p, - gfloat *natural_height_p); - -static gboolean meta_shaped_texture_get_paint_volume (ClutterActor *self, ClutterPaintVolume *volume); - -G_DEFINE_TYPE (MetaShapedTexture, meta_shaped_texture, - CLUTTER_TYPE_ACTOR); - -#define META_SHAPED_TEXTURE_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((obj), META_TYPE_SHAPED_TEXTURE, \ - MetaShapedTexturePrivate)) +static void clutter_content_iface_init (ClutterContentInterface *iface); -enum { +enum +{ SIZE_CHANGED, LAST_SIGNAL, @@ -89,473 +68,561 @@ enum { static guint signals[LAST_SIGNAL]; -struct _MetaShapedTexturePrivate +struct _MetaShapedTexture { + GObject parent; + MetaTextureTower *paint_tower; - Pixmap pixmap; + CoglTexture *texture; CoglTexture *mask_texture; + CoglSnippet *snippet; - cairo_region_t *clip_region; - cairo_region_t *unobscured_region; + CoglPipeline *base_pipeline; + CoglPipeline *masked_pipeline; + CoglPipeline *unblended_pipeline; + + gboolean is_y_inverted; + + /* The region containing only fully opaque pixels */ cairo_region_t *opaque_region; - cairo_region_t *overlay_region; - cairo_path_t *overlay_path; + /* MetaCullable regions, see that documentation for more details */ + cairo_region_t *clip_region; + + gboolean size_invalid; + MetaMonitorTransform transform; + gboolean has_viewport_src_rect; + graphene_rect_t viewport_src_rect; + gboolean has_viewport_dst_size; + int viewport_dst_width; + int viewport_dst_height; - guint tex_width, tex_height; + int tex_width, tex_height; + int fallback_width, fallback_height; + int dst_width, dst_height; gint64 prev_invalidation, last_invalidation; guint fast_updates; guint remipmap_timeout_id; gint64 earliest_remipmap; + int buffer_scale; + guint create_mipmaps : 1; - guint mask_needs_update : 1; }; +G_DEFINE_TYPE_WITH_CODE (MetaShapedTexture, meta_shaped_texture, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTENT, + clutter_content_iface_init)); + static void meta_shaped_texture_class_init (MetaShapedTextureClass *klass) { GObjectClass *gobject_class = (GObjectClass *) klass; - ClutterActorClass *actor_class = (ClutterActorClass *) klass; gobject_class->dispose = meta_shaped_texture_dispose; - actor_class->get_preferred_width = meta_shaped_texture_get_preferred_width; - actor_class->get_preferred_height = meta_shaped_texture_get_preferred_height; - actor_class->paint = meta_shaped_texture_paint; - actor_class->get_paint_volume = meta_shaped_texture_get_paint_volume; - signals[SIZE_CHANGED] = g_signal_new ("size-changed", G_TYPE_FROM_CLASS (gobject_class), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); - - g_type_class_add_private (klass, sizeof (MetaShapedTexturePrivate)); } static void -meta_shaped_texture_init (MetaShapedTexture *self) +invalidate_size (MetaShapedTexture *stex) { - MetaShapedTexturePrivate *priv; - - priv = self->priv = META_SHAPED_TEXTURE_GET_PRIVATE (self); + stex->size_invalid = TRUE; +} - priv->overlay_path = NULL; - priv->overlay_region = NULL; - priv->paint_tower = meta_texture_tower_new (); - priv->texture = NULL; - priv->mask_texture = NULL; - priv->create_mipmaps = TRUE; - priv->mask_needs_update = TRUE; +static void +meta_shaped_texture_init (MetaShapedTexture *stex) +{ + stex->paint_tower = meta_texture_tower_new (); + + stex->buffer_scale = 1; + stex->texture = NULL; + stex->mask_texture = NULL; + stex->create_mipmaps = TRUE; + stex->is_y_inverted = TRUE; + stex->transform = META_MONITOR_TRANSFORM_NORMAL; } static void -meta_shaped_texture_dispose (GObject *object) +update_size (MetaShapedTexture *stex) { - MetaShapedTexture *self = (MetaShapedTexture *) object; - MetaShapedTexturePrivate *priv = self->priv; + int buffer_scale = stex->buffer_scale; + int dst_width; + int dst_height; - if (priv->remipmap_timeout_id) + if (stex->has_viewport_dst_size) { - g_source_remove (priv->remipmap_timeout_id); - priv->remipmap_timeout_id = 0; + dst_width = stex->viewport_dst_width; + dst_height = stex->viewport_dst_height; + } + else if (stex->has_viewport_src_rect) + { + dst_width = stex->viewport_src_rect.size.width; + dst_height = stex->viewport_src_rect.size.height; + } + else + { + if (meta_monitor_transform_is_rotated (stex->transform)) + { + if (stex->texture) + { + dst_width = stex->tex_height / buffer_scale; + dst_height = stex->tex_width / buffer_scale; + } + else + { + dst_width = stex->fallback_height / buffer_scale; + dst_height = stex->fallback_width / buffer_scale; + } + } + else + { + if (stex->texture) + { + dst_width = stex->tex_width / buffer_scale; + dst_height = stex->tex_height / buffer_scale; + } + else + { + dst_width = stex->fallback_width / buffer_scale; + dst_height = stex->fallback_height / buffer_scale; + } + } } - if (priv->paint_tower) - meta_texture_tower_free (priv->paint_tower); - priv->paint_tower = NULL; - - meta_shaped_texture_dirty_mask (self); - g_clear_pointer (&priv->texture, cogl_object_unref); - g_clear_pointer (&priv->opaque_region, cairo_region_destroy); - - meta_shaped_texture_set_clip_region (self, NULL); - meta_shaped_texture_set_overlay_path (self, NULL, NULL); - - G_OBJECT_CLASS (meta_shaped_texture_parent_class)->dispose (object); -} + stex->size_invalid = FALSE; -static CoglPipeline * -get_base_pipeline (CoglContext *ctx) -{ - static CoglPipeline *template = NULL; - if (G_UNLIKELY (template == NULL)) + if (stex->dst_width != dst_width || + stex->dst_height != dst_height) { - template = cogl_pipeline_new (ctx); - cogl_pipeline_set_layer_wrap_mode_s (template, 0, COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE); - cogl_pipeline_set_layer_wrap_mode_t (template, 0, COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE); - cogl_pipeline_set_layer_wrap_mode_s (template, 1, COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE); - cogl_pipeline_set_layer_wrap_mode_t (template, 1, COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE); + stex->dst_width = dst_width; + stex->dst_height = dst_height; + meta_shaped_texture_set_mask_texture (stex, NULL); + clutter_content_invalidate_size (CLUTTER_CONTENT (stex)); + g_signal_emit (stex, signals[SIZE_CHANGED], 0); } - return template; } -static CoglPipeline * -get_unmasked_pipeline (CoglContext *ctx) +static void +ensure_size_valid (MetaShapedTexture *stex) { - return get_base_pipeline (ctx); + if (stex->size_invalid) + update_size (stex); } -static CoglPipeline * -get_masked_pipeline (CoglContext *ctx) +void +meta_shaped_texture_set_clip_region (MetaShapedTexture *stex, + cairo_region_t *clip_region) { - static CoglPipeline *template = NULL; - if (G_UNLIKELY (template == NULL)) - { - template = cogl_pipeline_copy (get_base_pipeline (ctx)); - cogl_pipeline_set_layer_combine (template, 1, - "RGBA = MODULATE (PREVIOUS, TEXTURE[A])", - NULL); - } - - return template; + g_clear_pointer (&stex->clip_region, cairo_region_destroy); + if (clip_region) + stex->clip_region = cairo_region_reference (clip_region); } -static CoglPipeline * -get_unblended_pipeline (CoglContext *ctx) +static void +meta_shaped_texture_reset_pipelines (MetaShapedTexture *stex) { - static CoglPipeline *template = NULL; - if (G_UNLIKELY (template == NULL)) - { - template = cogl_pipeline_copy (get_base_pipeline (ctx)); - cogl_pipeline_set_layer_combine (template, - 0, - "RGBA = REPLACE (TEXTURE)", - NULL); - - } - - return template; + g_clear_pointer (&stex->base_pipeline, cogl_object_unref); + g_clear_pointer (&stex->masked_pipeline, cogl_object_unref); + g_clear_pointer (&stex->unblended_pipeline, cogl_object_unref); } static void -paint_clipped_rectangle (CoglFramebuffer *fb, - CoglPipeline *pipeline, - cairo_rectangle_int_t *rect, - ClutterActorBox *alloc) +meta_shaped_texture_dispose (GObject *object) { - float coords[8]; - float x1, y1, x2, y2; + MetaShapedTexture *stex = (MetaShapedTexture *) object; - x1 = rect->x; - y1 = rect->y; - x2 = rect->x + rect->width; - y2 = rect->y + rect->height; + g_clear_handle_id (&stex->remipmap_timeout_id, g_source_remove); - coords[0] = rect->x / (alloc->x2 - alloc->x1); - coords[1] = rect->y / (alloc->y2 - alloc->y1); - coords[2] = (rect->x + rect->width) / (alloc->x2 - alloc->x1); - coords[3] = (rect->y + rect->height) / (alloc->y2 - alloc->y1); + if (stex->paint_tower) + meta_texture_tower_free (stex->paint_tower); + stex->paint_tower = NULL; - coords[4] = coords[0]; - coords[5] = coords[1]; - coords[6] = coords[2]; - coords[7] = coords[3]; + g_clear_pointer (&stex->texture, cogl_object_unref); - cogl_framebuffer_draw_multitextured_rectangle (fb, pipeline, - x1, y1, x2, y2, - &coords[0], 8); + meta_shaped_texture_set_mask_texture (stex, NULL); + meta_shaped_texture_reset_pipelines (stex); -} + g_clear_pointer (&stex->opaque_region, cairo_region_destroy); + g_clear_pointer (&stex->clip_region, cairo_region_destroy); -LOCAL_SYMBOL void -meta_shaped_texture_dirty_mask (MetaShapedTexture *stex) -{ - MetaShapedTexturePrivate *priv = stex->priv; + g_clear_pointer (&stex->snippet, cogl_object_unref); - g_clear_pointer (&priv->mask_texture, cogl_object_unref); + G_OBJECT_CLASS (meta_shaped_texture_parent_class)->dispose (object); } -static void -install_overlay_path (MetaShapedTexture *stex, - guchar *mask_data, - int tex_width, - int tex_height, - int stride) +static CoglPipeline * +get_base_pipeline (MetaShapedTexture *stex, + CoglContext *ctx) { - MetaShapedTexturePrivate *priv = stex->priv; - int i, n_rects; - cairo_t *cr; - cairo_rectangle_int_t rect; - cairo_surface_t *surface; + CoglPipeline *pipeline; + CoglMatrix matrix; - if (priv->overlay_region == NULL) - return; + if (stex->base_pipeline) + return stex->base_pipeline; - surface = cairo_image_surface_create_for_data (mask_data, - CAIRO_FORMAT_A8, - tex_width, - tex_height, - stride); + pipeline = cogl_pipeline_new (ctx); + cogl_pipeline_set_layer_wrap_mode_s (pipeline, 0, + COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE); + cogl_pipeline_set_layer_wrap_mode_t (pipeline, 0, + COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE); + cogl_pipeline_set_layer_wrap_mode_s (pipeline, 1, + COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE); + cogl_pipeline_set_layer_wrap_mode_t (pipeline, 1, + COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE); - cr = cairo_create (surface); - cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); + cogl_matrix_init_identity (&matrix); + + if (!stex->is_y_inverted) + { + cogl_matrix_scale (&matrix, 1, -1, 1); + cogl_matrix_translate (&matrix, 0, -1, 0); + cogl_pipeline_set_layer_matrix (pipeline, 0, &matrix); + } - n_rects = cairo_region_num_rectangles (priv->overlay_region); - for (i = 0; i < n_rects; i++) + if (stex->transform != META_MONITOR_TRANSFORM_NORMAL) { - cairo_region_get_rectangle (priv->overlay_region, i, &rect); - cairo_rectangle (cr, rect.x, rect.y, rect.width, rect.height); + graphene_euler_t euler; + + cogl_matrix_translate (&matrix, 0.5, 0.5, 0.0); + switch (stex->transform) + { + case META_MONITOR_TRANSFORM_90: + graphene_euler_init_with_order (&euler, 0.0, 0.0, 90.0, + GRAPHENE_EULER_ORDER_SYXZ); + break; + case META_MONITOR_TRANSFORM_180: + graphene_euler_init_with_order (&euler, 0.0, 0.0, 180.0, + GRAPHENE_EULER_ORDER_SYXZ); + break; + case META_MONITOR_TRANSFORM_270: + graphene_euler_init_with_order (&euler, 0.0, 0.0, 270.0, + GRAPHENE_EULER_ORDER_SYXZ); + break; + case META_MONITOR_TRANSFORM_FLIPPED: + graphene_euler_init_with_order (&euler, 0.0, 180.0, 0.0, + GRAPHENE_EULER_ORDER_SYXZ); + break; + case META_MONITOR_TRANSFORM_FLIPPED_90: + graphene_euler_init_with_order (&euler, 180.0, 0.0, 90.0, + GRAPHENE_EULER_ORDER_SYXZ); + break; + case META_MONITOR_TRANSFORM_FLIPPED_180: + graphene_euler_init_with_order (&euler, 0.0, 180.0, 180.0, + GRAPHENE_EULER_ORDER_SYXZ); + break; + case META_MONITOR_TRANSFORM_FLIPPED_270: + graphene_euler_init_with_order (&euler, 180.0, 0.0, 270.0, + GRAPHENE_EULER_ORDER_SYXZ); + break; + case META_MONITOR_TRANSFORM_NORMAL: + g_assert_not_reached (); + } + cogl_matrix_rotate_euler (&matrix, &euler); + cogl_matrix_translate (&matrix, -0.5, -0.5, 0.0); } - cairo_fill_preserve (cr); - if (priv->overlay_path == NULL) + if (stex->has_viewport_src_rect) { - /* If we have an overlay region but not an overlay path, then we - * just need to clear the rectangles in the overlay region. */ - goto out; + float scaled_tex_width = stex->tex_width / (float) stex->buffer_scale; + float scaled_tex_height = stex->tex_height / (float) stex->buffer_scale; + + if (meta_monitor_transform_is_rotated (stex->transform)) + { + cogl_matrix_scale (&matrix, + stex->viewport_src_rect.size.width / + scaled_tex_height, + stex->viewport_src_rect.size.height / + scaled_tex_width, + 1); + } + else + { + cogl_matrix_scale (&matrix, + stex->viewport_src_rect.size.width / + scaled_tex_width, + stex->viewport_src_rect.size.height / + scaled_tex_height, + 1); + } + + cogl_matrix_translate (&matrix, + stex->viewport_src_rect.origin.x / + stex->viewport_src_rect.size.width, + stex->viewport_src_rect.origin.y / + stex->viewport_src_rect.size.height, + 0); } - cairo_clip (cr); + cogl_pipeline_set_layer_matrix (pipeline, 0, &matrix); + cogl_pipeline_set_layer_matrix (pipeline, 1, &matrix); - cairo_set_operator (cr, CAIRO_OPERATOR_OVER); - cairo_set_source_rgba (cr, 1, 1, 1, 1); + if (stex->snippet) + cogl_pipeline_add_layer_snippet (pipeline, 0, stex->snippet); - cairo_append_path (cr, priv->overlay_path); - cairo_fill (cr); + stex->base_pipeline = pipeline; - out: - cairo_destroy (cr); - cairo_surface_destroy (surface); + return stex->base_pipeline; } -LOCAL_SYMBOL void -meta_shaped_texture_ensure_mask (MetaShapedTexture *stex, - cairo_region_t *shape_region, - gboolean has_frame) +static CoglPipeline * +get_unmasked_pipeline (MetaShapedTexture *stex, + CoglContext *ctx) { - MetaShapedTexturePrivate *priv = stex->priv; - CoglTexture *paint_tex; - guint tex_width, tex_height; + return get_base_pipeline (stex, ctx); +} - paint_tex = priv->texture; +static CoglPipeline * +get_masked_pipeline (MetaShapedTexture *stex, + CoglContext *ctx) +{ + CoglPipeline *pipeline; - if (paint_tex == NULL) - return; + if (stex->masked_pipeline) + return stex->masked_pipeline; - tex_width = cogl_texture_get_width (paint_tex); - tex_height = cogl_texture_get_height (paint_tex); + pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx)); + cogl_pipeline_set_layer_combine (pipeline, 1, + "RGBA = MODULATE (PREVIOUS, TEXTURE[A])", + NULL); - /* If the mask texture we have was created for a different size then - recreate it */ - if (priv->mask_texture != NULL && priv->mask_needs_update) - { - priv->mask_needs_update = FALSE; - meta_shaped_texture_dirty_mask (stex); - } + stex->masked_pipeline = pipeline; - /* If we don't have a mask texture yet then create one */ - if (priv->mask_texture == NULL) - { - guchar *mask_data; - int i; - int n_rects; - int stride; + return pipeline; +} - /* If we have no shape region and no (or an empty) overlay region, we - * don't need to create a full mask texture, so quit early. */ - if (shape_region == NULL && - (priv->overlay_region == NULL || - cairo_region_num_rectangles (priv->overlay_region) == 0)) - { - return; - } +static CoglPipeline * +get_unblended_pipeline (MetaShapedTexture *stex, + CoglContext *ctx) +{ + CoglPipeline *pipeline; - if (shape_region == NULL) - return; + if (stex->unblended_pipeline) + return stex->unblended_pipeline; - n_rects = cairo_region_num_rectangles (shape_region); + pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx)); + cogl_pipeline_set_layer_combine (pipeline, 0, + "RGBA = REPLACE (TEXTURE)", + NULL); - if (n_rects == 0) - return; + stex->unblended_pipeline = pipeline; - stride = cairo_format_stride_for_width (CAIRO_FORMAT_A8, tex_width); + return pipeline; +} - /* Create data for an empty image */ - mask_data = g_malloc0 (stride * tex_height); +static void +paint_clipped_rectangle_node (MetaShapedTexture *stex, + ClutterPaintNode *root_node, + CoglPipeline *pipeline, + cairo_rectangle_int_t *rect, + ClutterActorBox *alloc) +{ + g_autoptr (ClutterPaintNode) node = NULL; + float ratio_h, ratio_v; + float x1, y1, x2, y2; + float coords[8]; + float alloc_width; + float alloc_height; - /* Fill in each rectangle. */ - for (i = 0; i < n_rects; i ++) - { - cairo_rectangle_int_t rect; - cairo_region_get_rectangle (shape_region, i, &rect); - - gint x1 = rect.x, x2 = x1 + rect.width; - gint y1 = rect.y, y2 = y1 + rect.height; - guchar *p; - - /* Clip the rectangle to the size of the texture */ - x1 = CLAMP (x1, 0, (gint) tex_width - 1); - x2 = CLAMP (x2, x1, (gint) tex_width); - y1 = CLAMP (y1, 0, (gint) tex_height - 1); - y2 = CLAMP (y2, y1, (gint) tex_height); - - /* Fill the rectangle */ - for (p = mask_data + y1 * stride + x1; - y1 < y2; - y1++, p += stride) - memset (p, 255, x2 - x1); - } + ratio_h = clutter_actor_box_get_width (alloc) / (float) stex->dst_width; + ratio_v = clutter_actor_box_get_height (alloc) / (float) stex->dst_height; - if (has_frame) - install_overlay_path (stex, mask_data, tex_width, tex_height, stride); + x1 = alloc->x1 + rect->x * ratio_h; + y1 = alloc->y1 + rect->y * ratio_v; + x2 = alloc->x1 + (rect->x + rect->width) * ratio_h; + y2 = alloc->y1 + (rect->y + rect->height) * ratio_v; - if (meta_texture_rectangle_check (paint_tex)) - priv->mask_texture = meta_cogl_rectangle_new (tex_width, tex_height, - COGL_PIXEL_FORMAT_A_8, - stride, mask_data); - else - priv->mask_texture = meta_cogl_texture_new_from_data_wrapper (tex_width, tex_height, - COGL_TEXTURE_NONE, - COGL_PIXEL_FORMAT_A_8, - COGL_PIXEL_FORMAT_ANY, - stride, - mask_data); - - g_free (mask_data); + alloc_width = alloc->x2 - alloc->x1; + alloc_height = alloc->y2 - alloc->y1; + + coords[0] = rect->x / alloc_width * ratio_h; + coords[1] = rect->y / alloc_height * ratio_v; + coords[2] = (rect->x + rect->width) / alloc_width * ratio_h; + coords[3] = (rect->y + rect->height) / alloc_height * ratio_v; + + coords[4] = coords[0]; + coords[5] = coords[1]; + coords[6] = coords[2]; + coords[7] = coords[3]; + + node = clutter_pipeline_node_new (pipeline); + clutter_paint_node_set_static_name (node, "MetaShapedTexture (clipped)"); + clutter_paint_node_add_child (root_node, node); + + clutter_paint_node_add_multitexture_rectangle (node, + &(ClutterActorBox) { + .x1 = x1, + .y1 = y1, + .x2 = x2, + .y2 = y2, + }, + coords, 8); +} + +static void +set_cogl_texture (MetaShapedTexture *stex, + CoglTexture *cogl_tex) +{ + int width, height; + + cogl_clear_object (&stex->texture); + + if (cogl_tex != NULL) + { + stex->texture = cogl_object_ref (cogl_tex); + width = cogl_texture_get_width (COGL_TEXTURE (cogl_tex)); + height = cogl_texture_get_height (COGL_TEXTURE (cogl_tex)); + } + else + { + width = 0; + height = 0; } + + if (stex->tex_width != width || + stex->tex_height != height) + { + stex->tex_width = width; + stex->tex_height = height; + update_size (stex); + } + + /* NB: We don't queue a redraw of the actor here because we don't + * know how much of the buffer has changed with respect to the + * previous buffer. We only queue a redraw in response to surface + * damage. */ + + if (stex->create_mipmaps) + meta_texture_tower_set_base_texture (stex->paint_tower, cogl_tex); } static gboolean texture_is_idle_and_not_mipmapped (gpointer user_data) { MetaShapedTexture *stex = META_SHAPED_TEXTURE (user_data); - MetaShapedTexturePrivate *priv = stex->priv; - if ((g_get_monotonic_time () - priv->earliest_remipmap) < 0) + if ((g_get_monotonic_time () - stex->earliest_remipmap) < 0) return G_SOURCE_CONTINUE; - clutter_actor_queue_redraw (CLUTTER_ACTOR (stex)); - priv->remipmap_timeout_id = 0; + clutter_content_invalidate (CLUTTER_CONTENT (stex)); + stex->remipmap_timeout_id = 0; return G_SOURCE_REMOVE; } +static inline void +flip_ints (int *x, + int *y) +{ + int tmp; + + tmp = *x; + *x = *y; + *y = tmp; +} + static void -meta_shaped_texture_paint (ClutterActor *actor) +do_paint_content (MetaShapedTexture *stex, + ClutterPaintNode *root_node, + ClutterPaintContext *paint_context, + CoglTexture *paint_tex, + ClutterActorBox *alloc, + uint8_t opacity) { - MetaShapedTexture *stex = (MetaShapedTexture *) actor; - MetaShapedTexturePrivate *priv = stex->priv; - guint tex_width, tex_height; - guchar opacity; + int dst_width, dst_height; + cairo_rectangle_int_t content_rect; + gboolean use_opaque_region; + cairo_region_t *blended_tex_region; CoglContext *ctx; - CoglFramebuffer *fb; - CoglTexture *paint_tex = NULL; - ClutterActorBox alloc; CoglPipelineFilter filter; - gint64 now = g_get_monotonic_time (); + CoglFramebuffer *framebuffer; + int sample_width, sample_height; - if (priv->clip_region && cairo_region_is_empty (priv->clip_region)) - return; + ensure_size_valid (stex); - if (!CLUTTER_ACTOR_IS_REALIZED (CLUTTER_ACTOR (stex))) - clutter_actor_realize (CLUTTER_ACTOR (stex)); + dst_width = stex->dst_width; + dst_height = stex->dst_height; - /* The GL EXT_texture_from_pixmap extension does allow for it to be - * used together with SGIS_generate_mipmap, however this is very - * rarely supported. Also, even when it is supported there - * are distinct performance implications from: - * - * - Updating mipmaps that we don't need - * - Having to reallocate pixmaps on the server into larger buffers - * - * So, we just unconditionally use our mipmap emulation code. If we - * wanted to use SGIS_generate_mipmap, we'd have to query COGL to - * see if it was supported (no API currently), and then if and only - * if that was the case, set the clutter texture quality to HIGH. - * Setting the texture quality to high without SGIS_generate_mipmap - * support for TFP textures will result in fallbacks to XGetImage. - */ - if (priv->create_mipmaps && priv->last_invalidation) - { - gint64 age = now - priv->last_invalidation; - - if (age >= MIN_MIPMAP_AGE_USEC || - priv->fast_updates < MIN_FAST_UPDATES_BEFORE_UNMIPMAP) - paint_tex = meta_texture_tower_get_paint_texture (priv->paint_tower); - } - - if (paint_tex == NULL) - { - paint_tex = COGL_TEXTURE (priv->texture); - - if (paint_tex == NULL) - return; - - if (priv->create_mipmaps) - { - /* Minus 1000 to ensure we don't fail the age test in timeout */ - priv->earliest_remipmap = now + MIN_MIPMAP_AGE_USEC - 1000; - - if (!priv->remipmap_timeout_id) - priv->remipmap_timeout_id = - g_timeout_add (MIN_MIPMAP_AGE_USEC / 1000, - texture_is_idle_and_not_mipmapped, - stex); - } - } - - tex_width = priv->tex_width; - tex_height = priv->tex_height; - - if (tex_width == 0 || tex_height == 0) /* no contents yet */ + if (dst_width == 0 || dst_height == 0) /* no contents yet */ return; - cairo_rectangle_int_t tex_rect = { 0, 0, tex_width, tex_height }; + content_rect = (cairo_rectangle_int_t) { + .x = 0, + .y = 0, + .width = dst_width, + .height = dst_height, + }; /* Use nearest-pixel interpolation if the texture is unscaled. This * improves performance, especially with software rendering. */ - filter = COGL_PIPELINE_FILTER_LINEAR; + framebuffer = clutter_paint_node_get_framebuffer (root_node); + if (!framebuffer) + framebuffer = clutter_paint_context_get_framebuffer (paint_context); + + if (stex->has_viewport_src_rect) + { + sample_width = stex->viewport_src_rect.size.width * stex->buffer_scale; + sample_height = stex->viewport_src_rect.size.height * stex->buffer_scale; + } + else + { + sample_width = cogl_texture_get_width (stex->texture); + sample_height = cogl_texture_get_height (stex->texture); + } + if (meta_monitor_transform_is_rotated (stex->transform)) + flip_ints (&sample_width, &sample_height); - if (meta_actor_painting_untransformed (tex_width, tex_height, NULL, NULL)) + if (meta_actor_painting_untransformed (framebuffer, + dst_width, dst_height, + sample_width, sample_height, + NULL, NULL)) filter = COGL_PIPELINE_FILTER_NEAREST; + else + filter = COGL_PIPELINE_FILTER_LINEAR; ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); - fb = cogl_get_draw_framebuffer (); - - opacity = clutter_actor_get_paint_opacity (actor); - clutter_actor_get_allocation_box (actor, &alloc); - cairo_region_t *blended_region; - gboolean use_opaque_region = (priv->opaque_region != NULL && opacity == 255); + use_opaque_region = stex->opaque_region && opacity == 255; if (use_opaque_region) { - if (priv->clip_region != NULL) - blended_region = cairo_region_copy (priv->clip_region); + if (stex->clip_region) + blended_tex_region = cairo_region_copy (stex->clip_region); else - blended_region = cairo_region_create_rectangle (&tex_rect); + blended_tex_region = cairo_region_create_rectangle (&content_rect); - cairo_region_subtract (blended_region, priv->opaque_region); + cairo_region_subtract (blended_tex_region, stex->opaque_region); } else { - if (priv->clip_region != NULL) - blended_region = cairo_region_reference (priv->clip_region); + if (stex->clip_region) + blended_tex_region = cairo_region_reference (stex->clip_region); else - blended_region = NULL; + blended_tex_region = NULL; } /* Limit to how many separate rectangles we'll draw; beyond this just * fall back and draw the whole thing */ #define MAX_RECTS 16 - if (blended_region != NULL) + if (blended_tex_region) { - int n_rects = cairo_region_num_rectangles (blended_region); + int n_rects = cairo_region_num_rectangles (blended_tex_region); if (n_rects > MAX_RECTS) { /* Fall back to taking the fully blended path. */ use_opaque_region = FALSE; - cairo_region_destroy (blended_region); - blended_region = NULL; + g_clear_pointer (&blended_tex_region, cairo_region_destroy); } } @@ -566,19 +633,21 @@ meta_shaped_texture_paint (ClutterActor *actor) int n_rects; int i; - if (priv->clip_region != NULL) + if (stex->clip_region) { - region = cairo_region_copy (priv->clip_region); - cairo_region_intersect (region, priv->opaque_region); + region = cairo_region_copy (stex->clip_region); + cairo_region_intersect (region, stex->opaque_region); } else { - region = cairo_region_reference (priv->opaque_region); + region = cairo_region_reference (stex->opaque_region); } if (!cairo_region_is_empty (region)) { - CoglPipeline *opaque_pipeline = get_unblended_pipeline (ctx); + CoglPipeline *opaque_pipeline; + + opaque_pipeline = get_unblended_pipeline (stex, ctx); cogl_pipeline_set_layer_texture (opaque_pipeline, 0, paint_tex); cogl_pipeline_set_layer_filters (opaque_pipeline, 0, filter, filter); @@ -587,7 +656,9 @@ meta_shaped_texture_paint (ClutterActor *actor) { cairo_rectangle_int_t rect; cairo_region_get_rectangle (region, i, &rect); - paint_clipped_rectangle (fb, opaque_pipeline, &rect, &alloc); + paint_clipped_rectangle_node (stex, root_node, + opaque_pipeline, + &rect, alloc); } } @@ -597,25 +668,25 @@ meta_shaped_texture_paint (ClutterActor *actor) /* Now, go ahead and paint the blended parts. */ /* We have three cases: - * 1) blended_region has rectangles - paint the rectangles. - * 2) blended_region is empty - don't paint anything - * 3) blended_region is NULL - paint fully-blended. + * 1) blended_tex_region has rectangles - paint the rectangles. + * 2) blended_tex_region is empty - don't paint anything + * 3) blended_tex_region is NULL - paint fully-blended. * * 1) and 3) are the times where we have to paint stuff. This tests * for 1) and 3). */ - if (blended_region == NULL || !cairo_region_is_empty (blended_region)) + if (!blended_tex_region || !cairo_region_is_empty (blended_tex_region)) { CoglPipeline *blended_pipeline; - if (priv->mask_texture == NULL) + if (stex->mask_texture == NULL) { - blended_pipeline = get_unmasked_pipeline (ctx); + blended_pipeline = get_unmasked_pipeline (stex, ctx); } else { - blended_pipeline = get_masked_pipeline (ctx); - cogl_pipeline_set_layer_texture (blended_pipeline, 1, priv->mask_texture); + blended_pipeline = get_masked_pipeline (stex, ctx); + cogl_pipeline_set_layer_texture (blended_pipeline, 1, stex->mask_texture); cogl_pipeline_set_layer_filters (blended_pipeline, 1, filter, filter); } @@ -626,102 +697,181 @@ meta_shaped_texture_paint (ClutterActor *actor) cogl_color_init_from_4ub (&color, opacity, opacity, opacity, opacity); cogl_pipeline_set_color (blended_pipeline, &color); - if (blended_region != NULL) + if (blended_tex_region) { - /* 1) blended_region is not empty. Paint the rectangles. */ + /* 1) blended_tex_region is not empty. Paint the rectangles. */ int i; - int n_rects = cairo_region_num_rectangles (blended_region); + int n_rects = cairo_region_num_rectangles (blended_tex_region); for (i = 0; i < n_rects; i++) { cairo_rectangle_int_t rect; - cairo_region_get_rectangle (blended_region, i, &rect); + cairo_region_get_rectangle (blended_tex_region, i, &rect); - if (!gdk_rectangle_intersect (&tex_rect, &rect, &rect)) + if (!gdk_rectangle_intersect (&content_rect, &rect, &rect)) continue; - paint_clipped_rectangle (fb, blended_pipeline, &rect, &alloc); + paint_clipped_rectangle_node (stex, root_node, + blended_pipeline, + &rect, alloc); } } else { - /* 3) blended_region is NULL. Do a full paint. */ - cogl_framebuffer_draw_rectangle (fb, blended_pipeline, - 0, 0, - alloc.x2 - alloc.x1, - alloc.y2 - alloc.y1); + g_autoptr (ClutterPaintNode) node = NULL; + + node = clutter_pipeline_node_new (blended_pipeline); + clutter_paint_node_set_static_name (node, "MetaShapedTexture (unclipped)"); + clutter_paint_node_add_child (root_node, node); + + /* 3) blended_tex_region is NULL. Do a full paint. */ + clutter_paint_node_add_rectangle (node, alloc); } } - if (blended_region != NULL) - cairo_region_destroy (blended_region); + g_clear_pointer (&blended_tex_region, cairo_region_destroy); } -static void -meta_shaped_texture_get_preferred_width (ClutterActor *self, - gfloat for_height, - gfloat *min_width_p, - gfloat *natural_width_p) +static CoglTexture * +select_texture_for_paint (MetaShapedTexture *stex, + ClutterPaintContext *paint_context) { - MetaShapedTexturePrivate *priv = META_SHAPED_TEXTURE (self)->priv; + CoglTexture *texture = NULL; + int64_t now; - if (min_width_p) - *min_width_p = priv->tex_width; + if (!stex->texture) + return NULL; + + now = g_get_monotonic_time (); + + if (stex->create_mipmaps && stex->last_invalidation) + { + int64_t age = now - stex->last_invalidation; - if (natural_width_p) - *natural_width_p = priv->tex_width; + if (age >= MIN_MIPMAP_AGE_USEC || + stex->fast_updates < MIN_FAST_UPDATES_BEFORE_UNMIPMAP) + { + texture = meta_texture_tower_get_paint_texture (stex->paint_tower, + paint_context); + } + } + + if (!texture) + { + texture = stex->texture; + + if (stex->create_mipmaps) + { + /* Minus 1000 to ensure we don't fail the age test in timeout */ + stex->earliest_remipmap = now + MIN_MIPMAP_AGE_USEC - 1000; + + if (!stex->remipmap_timeout_id) + stex->remipmap_timeout_id = + g_timeout_add (MIN_MIPMAP_AGE_USEC / 1000, + texture_is_idle_and_not_mipmapped, + stex); + } + } + + return texture; } static void -meta_shaped_texture_get_preferred_height (ClutterActor *self, - gfloat for_width, - gfloat *min_height_p, - gfloat *natural_height_p) +meta_shaped_texture_paint_content (ClutterContent *content, + ClutterActor *actor, + ClutterPaintNode *root_node, + ClutterPaintContext *paint_context) { - MetaShapedTexturePrivate *priv = META_SHAPED_TEXTURE (self)->priv; + MetaShapedTexture *stex = META_SHAPED_TEXTURE (content); + ClutterActorBox alloc; + CoglTexture *paint_tex = NULL; + uint8_t opacity; + + if (stex->clip_region && cairo_region_is_empty (stex->clip_region)) + return; + + /* The GL EXT_texture_from_pixmap extension does allow for it to be + * used together with SGIS_generate_mipmap, however this is very + * rarely supported. Also, even when it is supported there + * are distinct performance implications from: + * + * - Updating mipmaps that we don't need + * - Having to reallocate pixmaps on the server into larger buffers + * + * So, we just unconditionally use our mipmap emulation code. If we + * wanted to use SGIS_generate_mipmap, we'd have to query COGL to + * see if it was supported (no API currently), and then if and only + * if that was the case, set the clutter texture quality to HIGH. + * Setting the texture quality to high without SGIS_generate_mipmap + * support for TFP textures will result in fallbacks to XGetImage. + */ + paint_tex = select_texture_for_paint (stex, paint_context); + if (!paint_tex) + return; - if (min_height_p) - *min_height_p = priv->tex_height; + opacity = clutter_actor_get_paint_opacity (actor); + clutter_actor_get_content_box (actor, &alloc); - if (natural_height_p) - *natural_height_p = priv->tex_height; + do_paint_content (stex, root_node, paint_context, paint_tex, &alloc, opacity); } static gboolean -meta_shaped_texture_get_paint_volume (ClutterActor *self, - ClutterPaintVolume *volume) +meta_shaped_texture_get_preferred_size (ClutterContent *content, + float *width, + float *height) { - return clutter_paint_volume_set_from_allocation (volume, self); + MetaShapedTexture *stex = META_SHAPED_TEXTURE (content); + + ensure_size_valid (stex); + + if (width) + *width = stex->dst_width; + + if (height) + *height = stex->dst_height; + + return TRUE; } -ClutterActor * -meta_shaped_texture_new (void) +static void +clutter_content_iface_init (ClutterContentInterface *iface) { - ClutterActor *self = g_object_new (META_TYPE_SHAPED_TEXTURE, NULL); - - return self; + iface->paint_content = meta_shaped_texture_paint_content; + iface->get_preferred_size = meta_shaped_texture_get_preferred_size; } void meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex, gboolean create_mipmaps) { - MetaShapedTexturePrivate *priv; - g_return_if_fail (META_IS_SHAPED_TEXTURE (stex)); - priv = stex->priv; - create_mipmaps = create_mipmaps != FALSE; - if (create_mipmaps != priv->create_mipmaps) + if (create_mipmaps != stex->create_mipmaps) { CoglTexture *base_texture; - priv->create_mipmaps = create_mipmaps; - base_texture = create_mipmaps ? priv->texture : NULL; + stex->create_mipmaps = create_mipmaps; + base_texture = create_mipmaps ? stex->texture : NULL; + meta_texture_tower_set_base_texture (stex->paint_tower, base_texture); + } +} - meta_texture_tower_set_base_texture (priv->paint_tower, base_texture); +void +meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex, + CoglTexture *mask_texture) +{ + g_return_if_fail (META_IS_SHAPED_TEXTURE (stex)); + + g_clear_pointer (&stex->mask_texture, cogl_object_unref); + + if (mask_texture != NULL) + { + stex->mask_texture = mask_texture; + cogl_object_ref (stex->mask_texture); } + + clutter_content_invalidate (CLUTTER_CONTENT (stex)); } /** @@ -731,124 +881,117 @@ meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex, * @y: the y coordinate of the damaged area * @width: the width of the damaged area * @height: the height of the damaged area - * @unobscured_region: The unobscured region of the window or %NULL if - * there is no valid one (like when the actor is transformed or - * has a mapped clone) + * @clip: (out): the resulting clip region * * Repairs the damaged area indicated by @x, @y, @width and @height - * and queues a redraw for the intersection @visibible_region and - * the damage area. If @visibible_region is %NULL a redraw will always - * get queued. + * and potentially queues a redraw. * * Return value: Whether a redraw have been queued or not */ gboolean -meta_shaped_texture_update_area (MetaShapedTexture *stex, - int x, - int y, - int width, - int height, - cairo_region_t *unobscured_region) +meta_shaped_texture_update_area (MetaShapedTexture *stex, + int x, + int y, + int width, + int height, + cairo_rectangle_int_t *clip) { - MetaShapedTexturePrivate *priv; - const cairo_rectangle_int_t clip = { x, y, width, height }; + MetaMonitorTransform inverted_transform; - priv = stex->priv; - - if (priv->texture == NULL) + if (stex->texture == NULL) return FALSE; - meta_texture_tower_update_area (priv->paint_tower, x, y, width, height); - - priv->prev_invalidation = priv->last_invalidation; - priv->last_invalidation = g_get_monotonic_time (); - - if (priv->prev_invalidation) + *clip = (cairo_rectangle_int_t) { + .x = x, + .y = y, + .width = width, + .height = height + }; + + meta_rectangle_scale_double (clip, + 1.0 / stex->buffer_scale, + META_ROUNDING_STRATEGY_SHRINK, + clip); + + inverted_transform = meta_monitor_transform_invert (stex->transform); + ensure_size_valid (stex); + meta_rectangle_transform (clip, + inverted_transform, + stex->dst_width, + stex->dst_height, + clip); + + if (stex->has_viewport_src_rect || stex->has_viewport_dst_size) { - gint64 interval = priv->last_invalidation - priv->prev_invalidation; - gboolean fast_update = interval < MIN_MIPMAP_AGE_USEC; - - if (!fast_update) - priv->fast_updates = 0; - else if (priv->fast_updates < MIN_FAST_UPDATES_BEFORE_UNMIPMAP) - priv->fast_updates++; - } - - if (unobscured_region) - { - cairo_region_t *intersection; - - if (cairo_region_is_empty (unobscured_region)) - return FALSE; - - intersection = cairo_region_copy (unobscured_region); - cairo_region_intersect_rectangle (intersection, &clip); + graphene_rect_t viewport; + graphene_rect_t inverted_viewport; + float dst_width; + float dst_height; + int inverted_dst_width; + int inverted_dst_height; + + if (stex->has_viewport_src_rect) + { + viewport = stex->viewport_src_rect; + } + else + { + viewport = (graphene_rect_t) { + .origin.x = 0, + .origin.y = 0, + .size.width = stex->tex_width, + .size.height = stex->tex_height, + }; + } - if (!cairo_region_is_empty (intersection)) + if (stex->has_viewport_dst_size) + { + dst_width = (float) stex->viewport_dst_width; + dst_height = (float) stex->viewport_dst_height; + } + else { - cairo_rectangle_int_t damage_rect; - cairo_region_get_extents (intersection, &damage_rect); - clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stex), &damage_rect); - cairo_region_destroy (intersection); - return TRUE; + dst_width = (float) stex->tex_width; + dst_height = (float) stex->tex_height; } - cairo_region_destroy (intersection); - return FALSE; - } - else - { - clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stex), &clip); - return TRUE; + inverted_viewport = (graphene_rect_t) { + .origin.x = -(viewport.origin.x * (dst_width / viewport.size.width)), + .origin.y = -(viewport.origin.y * (dst_height / viewport.size.height)), + .size.width = dst_width, + .size.height = dst_height + }; + inverted_dst_width = ceilf (viewport.size.width); + inverted_dst_height = ceilf (viewport.size.height); + + meta_rectangle_crop_and_scale (clip, + &inverted_viewport, + inverted_dst_width, + inverted_dst_height, + clip); } -} - -static void -set_cogl_texture (MetaShapedTexture *stex, - CoglTexture *cogl_tex) -{ - MetaShapedTexturePrivate *priv; - guint width, height; - - g_return_if_fail (META_IS_SHAPED_TEXTURE (stex)); - priv = stex->priv; + meta_texture_tower_update_area (stex->paint_tower, + x, + y, + width, + height); - if (priv->texture != NULL) - cogl_object_unref (priv->texture); + stex->prev_invalidation = stex->last_invalidation; + stex->last_invalidation = g_get_monotonic_time (); - priv->texture = cogl_tex; - - if (cogl_tex != NULL) - { - width = cogl_texture_get_width (COGL_TEXTURE (cogl_tex)); - height = cogl_texture_get_height (COGL_TEXTURE (cogl_tex)); - } - else + if (stex->prev_invalidation) { - width = 0; - height = 0; - } - - priv->mask_needs_update = (priv->tex_width != width || - priv->tex_height != height); + gint64 interval = stex->last_invalidation - stex->prev_invalidation; + gboolean fast_update = interval < MIN_MIPMAP_AGE_USEC; - if (priv->mask_needs_update) - { - priv->tex_width = width; - priv->tex_height = height; - meta_shaped_texture_dirty_mask (stex); - clutter_actor_queue_relayout (CLUTTER_ACTOR (stex)); - g_signal_emit (stex, signals[SIZE_CHANGED], 0); + if (!fast_update) + stex->fast_updates = 0; + else if (stex->fast_updates < MIN_FAST_UPDATES_BEFORE_UNMIPMAP) + stex->fast_updates++; } - /* NB: We don't queue a redraw of the actor here because we don't - * know how much of the buffer has changed with respect to the - * previous buffer. We only queue a redraw in response to surface - * damage. */ - - if (priv->create_mipmaps) - meta_texture_tower_set_base_texture (priv->paint_tower, cogl_tex); + return TRUE; } /** @@ -862,9 +1005,44 @@ meta_shaped_texture_set_texture (MetaShapedTexture *stex, { g_return_if_fail (META_IS_SHAPED_TEXTURE (stex)); + if (stex->texture == texture) + return; + set_cogl_texture (stex, texture); } +/** + * meta_shaped_texture_set_is_y_inverted: (skip) + */ +void +meta_shaped_texture_set_is_y_inverted (MetaShapedTexture *stex, + gboolean is_y_inverted) +{ + if (stex->is_y_inverted == is_y_inverted) + return; + + meta_shaped_texture_reset_pipelines (stex); + + stex->is_y_inverted = is_y_inverted; +} + +/** + * meta_shaped_texture_set_snippet: (skip) + */ +void +meta_shaped_texture_set_snippet (MetaShapedTexture *stex, + CoglSnippet *snippet) +{ + if (stex->snippet == snippet) + return; + + meta_shaped_texture_reset_pipelines (stex); + + g_clear_pointer (&stex->snippet, cogl_object_unref); + if (snippet) + stex->snippet = cogl_object_ref (snippet); +} + /** * meta_shaped_texture_get_texture: * @stex: The #MetaShapedTexture @@ -875,116 +1053,288 @@ CoglTexture * meta_shaped_texture_get_texture (MetaShapedTexture *stex) { g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), NULL); - return stex->priv->texture; + return COGL_TEXTURE (stex->texture); } /** - * meta_shaped_texture_set_overlay_path: + * meta_shaped_texture_set_opaque_region: * @stex: a #MetaShapedTexture - * @overlay_region: A region containing the parts of the mask to overlay. - * All rectangles in this region are wiped clear to full transparency, - * and the overlay path is clipped to this region. - * @overlay_path: (transfer full): This path will be painted onto the mask - * texture with a fully opaque source. Due to the lack of refcounting - * in #cairo_path_t, ownership of the path is assumed. + * @opaque_region: (transfer full): the region of the texture that + * can have blending turned off. + * + * As most windows have a large portion that does not require blending, + * we can easily turn off blending if we know the areas that do not + * require blending. This sets the region where we will not blend for + * optimization purposes. */ void -meta_shaped_texture_set_overlay_path (MetaShapedTexture *stex, - cairo_region_t *overlay_region, - cairo_path_t *overlay_path) +meta_shaped_texture_set_opaque_region (MetaShapedTexture *stex, + cairo_region_t *opaque_region) { - MetaShapedTexturePrivate *priv; - g_return_if_fail (META_IS_SHAPED_TEXTURE (stex)); - priv = stex->priv; + if (stex->opaque_region) + cairo_region_destroy (stex->opaque_region); + + if (opaque_region) + stex->opaque_region = cairo_region_reference (opaque_region); + else + stex->opaque_region = NULL; +} + +cairo_region_t * +meta_shaped_texture_get_opaque_region (MetaShapedTexture *stex) +{ + return stex->opaque_region; +} + +gboolean +meta_shaped_texture_has_alpha (MetaShapedTexture *stex) +{ + CoglTexture *texture; + + texture = stex->texture; + if (!texture) + return TRUE; - if (priv->overlay_region != NULL) + switch (cogl_texture_get_components (texture)) { - cairo_region_destroy (priv->overlay_region); - priv->overlay_region = NULL; + case COGL_TEXTURE_COMPONENTS_A: + case COGL_TEXTURE_COMPONENTS_RGBA: + return TRUE; + case COGL_TEXTURE_COMPONENTS_RG: + case COGL_TEXTURE_COMPONENTS_RGB: + case COGL_TEXTURE_COMPONENTS_DEPTH: + return FALSE; } - if (priv->overlay_path != NULL) + g_warn_if_reached (); + return FALSE; +} + +gboolean +meta_shaped_texture_is_opaque (MetaShapedTexture *stex) +{ + CoglTexture *texture; + cairo_rectangle_int_t opaque_rect; + + texture = stex->texture; + if (!texture) + return FALSE; + + if (!meta_shaped_texture_has_alpha (stex)) + return TRUE; + + if (!stex->opaque_region) + return FALSE; + + if (cairo_region_num_rectangles (stex->opaque_region) != 1) + return FALSE; + + cairo_region_get_extents (stex->opaque_region, &opaque_rect); + + ensure_size_valid (stex); + + return meta_rectangle_equal (&opaque_rect, + &(MetaRectangle) { + .width = stex->dst_width, + .height = stex->dst_height + }); +} + +void +meta_shaped_texture_set_transform (MetaShapedTexture *stex, + MetaMonitorTransform transform) +{ + if (stex->transform == transform) + return; + + stex->transform = transform; + + meta_shaped_texture_reset_pipelines (stex); + invalidate_size (stex); +} + +void +meta_shaped_texture_set_viewport_src_rect (MetaShapedTexture *stex, + graphene_rect_t *src_rect) +{ + if (!stex->has_viewport_src_rect || + stex->viewport_src_rect.origin.x != src_rect->origin.x || + stex->viewport_src_rect.origin.y != src_rect->origin.y || + stex->viewport_src_rect.size.width != src_rect->size.width || + stex->viewport_src_rect.size.height != src_rect->size.height) { - cairo_path_destroy (priv->overlay_path); - priv->overlay_path = NULL; + stex->has_viewport_src_rect = TRUE; + stex->viewport_src_rect = *src_rect; + meta_shaped_texture_reset_pipelines (stex); + invalidate_size (stex); } +} - cairo_region_reference (overlay_region); - priv->overlay_region = overlay_region; +void +meta_shaped_texture_reset_viewport_src_rect (MetaShapedTexture *stex) +{ + if (!stex->has_viewport_src_rect) + return; - /* cairo_path_t does not have refcounting. */ - priv->overlay_path = overlay_path; + stex->has_viewport_src_rect = FALSE; + meta_shaped_texture_reset_pipelines (stex); + invalidate_size (stex); } -/** - * meta_shaped_texture_set_clip_region: - * @stex: a #MetaShapedTexture - * @clip_region: the region of the texture that is visible and - * should be painted. - * - * Provides a hint to the texture about what areas of the texture - * are not completely obscured and thus need to be painted. This - * is an optimization and is not supposed to have any effect on - * the output. - * - * Typically a parent container will set the clip region before - * painting its children, and then unset it afterwards. - */ void -meta_shaped_texture_set_clip_region (MetaShapedTexture *stex, - cairo_region_t *clip_region) +meta_shaped_texture_set_viewport_dst_size (MetaShapedTexture *stex, + int dst_width, + int dst_height) { - MetaShapedTexturePrivate *priv; + if (!stex->has_viewport_dst_size || + stex->viewport_dst_width != dst_width || + stex->viewport_dst_height != dst_height) + { + stex->has_viewport_dst_size = TRUE; + stex->viewport_dst_width = dst_width; + stex->viewport_dst_height = dst_height; + invalidate_size (stex); + } +} - g_return_if_fail (META_IS_SHAPED_TEXTURE (stex)); +void +meta_shaped_texture_reset_viewport_dst_size (MetaShapedTexture *stex) +{ + if (!stex->has_viewport_dst_size) + return; + + stex->has_viewport_dst_size = FALSE; + invalidate_size (stex); +} - priv = stex->priv; +static gboolean +should_get_via_offscreen (MetaShapedTexture *stex) +{ + if (!cogl_texture_is_get_data_supported (stex->texture)) + return TRUE; - if (priv->clip_region) - cairo_region_destroy (priv->clip_region); + if (stex->has_viewport_src_rect || stex->has_viewport_dst_size) + return TRUE; - if (clip_region) - priv->clip_region = cairo_region_copy (clip_region); - else - priv->clip_region = NULL; + switch (stex->transform) + { + case META_MONITOR_TRANSFORM_90: + case META_MONITOR_TRANSFORM_180: + case META_MONITOR_TRANSFORM_270: + case META_MONITOR_TRANSFORM_FLIPPED: + case META_MONITOR_TRANSFORM_FLIPPED_90: + case META_MONITOR_TRANSFORM_FLIPPED_180: + case META_MONITOR_TRANSFORM_FLIPPED_270: + return TRUE; + case META_MONITOR_TRANSFORM_NORMAL: + break; + } + + return FALSE; } -/** - * meta_shaped_texture_set_opaque_region: - * @stex: a #MetaShapedTexture - * @opaque_region: (transfer full): the region of the texture that - * can have blending turned off. - * - * As most windows have a large portion that does not require blending, - * we can easily turn off blending if we know the areas that do not - * require blending. This sets the region where we will not blend for - * optimization purposes. - */ -void -meta_shaped_texture_set_opaque_region (MetaShapedTexture *stex, - cairo_region_t *opaque_region) +static cairo_surface_t * +get_image_via_offscreen (MetaShapedTexture *stex, + cairo_rectangle_int_t *clip, + int image_width, + int image_height) { - MetaShapedTexturePrivate *priv; + g_autoptr (ClutterPaintNode) root_node = NULL; + ClutterBackend *clutter_backend = clutter_get_default_backend (); + CoglContext *cogl_context = + clutter_backend_get_cogl_context (clutter_backend); + CoglTexture *image_texture; + GError *error = NULL; + CoglOffscreen *offscreen; + CoglFramebuffer *fb; + CoglMatrix projection_matrix; + cairo_rectangle_int_t fallback_clip; + ClutterColor clear_color; + ClutterPaintContext *paint_context; + cairo_surface_t *surface; - g_return_if_fail (META_IS_SHAPED_TEXTURE (stex)); + if (!clip) + { + fallback_clip = (cairo_rectangle_int_t) { + .width = image_width, + .height = image_height, + }; + clip = &fallback_clip; + } - priv = stex->priv; + image_texture = + COGL_TEXTURE (cogl_texture_2d_new_with_size (cogl_context, + image_width, + image_height)); + cogl_primitive_texture_set_auto_mipmap (COGL_PRIMITIVE_TEXTURE (image_texture), + FALSE); + if (!cogl_texture_allocate (COGL_TEXTURE (image_texture), &error)) + { + g_error_free (error); + cogl_object_unref (image_texture); + return FALSE; + } + + offscreen = cogl_offscreen_new_with_texture (COGL_TEXTURE (image_texture)); + fb = COGL_FRAMEBUFFER (offscreen); + cogl_object_unref (image_texture); + if (!cogl_framebuffer_allocate (fb, &error)) + { + g_error_free (error); + cogl_object_unref (fb); + return FALSE; + } - if (priv->opaque_region) - cairo_region_destroy (priv->opaque_region); + cogl_framebuffer_push_matrix (fb); + cogl_matrix_init_identity (&projection_matrix); + cogl_matrix_scale (&projection_matrix, + 1.0 / (image_width / 2.0), + -1.0 / (image_height / 2.0), 0); + cogl_matrix_translate (&projection_matrix, + -(image_width / 2.0), + -(image_height / 2.0), 0); - if (opaque_region) - priv->opaque_region = cairo_region_reference (opaque_region); - else - priv->opaque_region = NULL; + cogl_framebuffer_set_projection_matrix (fb, &projection_matrix); + + clear_color = (ClutterColor) { 0, 0, 0, 0 }; + + root_node = clutter_root_node_new (fb, &clear_color, COGL_BUFFER_BIT_COLOR); + clutter_paint_node_set_static_name (root_node, "MetaShapedTexture.offscreen"); + + paint_context = clutter_paint_context_new_for_framebuffer (fb); + + do_paint_content (stex, root_node, paint_context, + stex->texture, + &(ClutterActorBox) { + 0, 0, + image_width, + image_height, + }, + 255); + + clutter_paint_node_paint (root_node, paint_context); + clutter_paint_context_destroy (paint_context); + + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, + clip->width, clip->height); + cogl_framebuffer_read_pixels (fb, + clip->x, clip->y, + clip->width, clip->height, + CLUTTER_CAIRO_FORMAT_ARGB32, + cairo_image_surface_get_data (surface)); + cogl_object_unref (fb); + + cairo_surface_mark_dirty (surface); + + return surface; } /** * meta_shaped_texture_get_image: * @stex: A #MetaShapedTexture - * @clip: A clipping rectangle, to help prevent extra processing. + * @clip: (nullable): A clipping rectangle, to help prevent extra processing. * In the case that the clipping rectangle is partially or fully * outside the bounds of the texture, the rectangle will be clipped. * @@ -992,41 +1342,70 @@ meta_shaped_texture_set_opaque_region (MetaShapedTexture *stex, * image by alpha blending the two images, and returns the flattened * image. * - * Returns: (transfer full): a new cairo surface to be freed with + * Returns: (nullable) (transfer full): a new cairo surface to be freed with * cairo_surface_destroy(). */ cairo_surface_t * meta_shaped_texture_get_image (MetaShapedTexture *stex, cairo_rectangle_int_t *clip) { + cairo_rectangle_int_t *image_clip = NULL; CoglTexture *texture, *mask_texture; - cairo_rectangle_int_t texture_rect = { 0, 0, 0, 0 }; cairo_surface_t *surface; g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), NULL); - texture = stex->priv->texture; + texture = COGL_TEXTURE (stex->texture); if (texture == NULL) return NULL; - texture_rect.width = cogl_texture_get_width (texture); - texture_rect.height = cogl_texture_get_height (texture); + ensure_size_valid (stex); + + if (stex->dst_width == 0 || stex->dst_height == 0) + return NULL; if (clip != NULL) { - /* GdkRectangle is just a typedef of cairo_rectangle_int_t, - * so we can use the gdk_rectangle_* APIs on these. */ - if (!gdk_rectangle_intersect (&texture_rect, clip, clip)) + cairo_rectangle_int_t dst_rect; + + image_clip = alloca (sizeof (cairo_rectangle_int_t)); + dst_rect = (cairo_rectangle_int_t) { + .width = stex->dst_width, + .height = stex->dst_height, + }; + + if (!meta_rectangle_intersect (&dst_rect, clip, + image_clip)) return NULL; + + *image_clip = (MetaRectangle) { + .x = image_clip->x * stex->buffer_scale, + .y = image_clip->y * stex->buffer_scale, + .width = image_clip->width * stex->buffer_scale, + .height = image_clip->height * stex->buffer_scale, + }; } - if (clip != NULL) + if (should_get_via_offscreen (stex)) + { + int image_width; + int image_height; + + image_width = stex->dst_width * stex->buffer_scale; + image_height = stex->dst_height * stex->buffer_scale; + return get_image_via_offscreen (stex, + image_clip, + image_width, + image_height); + } + + if (image_clip) texture = cogl_texture_new_from_sub_texture (texture, - clip->x, - clip->y, - clip->width, - clip->height); + image_clip->x, + image_clip->y, + image_clip->width, + image_clip->height); surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, cogl_texture_get_width (texture), @@ -1038,21 +1417,22 @@ meta_shaped_texture_get_image (MetaShapedTexture *stex, cairo_surface_mark_dirty (surface); - if (clip != NULL) + if (image_clip) cogl_object_unref (texture); - mask_texture = stex->priv->mask_texture; + mask_texture = stex->mask_texture; if (mask_texture != NULL) { cairo_t *cr; cairo_surface_t *mask_surface; - if (clip != NULL) - mask_texture = cogl_texture_new_from_sub_texture (mask_texture, - clip->x, - clip->y, - clip->width, - clip->height); + if (image_clip) + mask_texture = + cogl_texture_new_from_sub_texture (mask_texture, + image_clip->x, + image_clip->y, + image_clip->width, + image_clip->height); mask_surface = cairo_image_surface_create (CAIRO_FORMAT_A8, cogl_texture_get_width (mask_texture), @@ -1072,9 +1452,68 @@ meta_shaped_texture_get_image (MetaShapedTexture *stex, cairo_surface_destroy (mask_surface); - if (clip != NULL) + if (image_clip) cogl_object_unref (mask_texture); } return surface; } + +void +meta_shaped_texture_set_fallback_size (MetaShapedTexture *stex, + int fallback_width, + int fallback_height) +{ + stex->fallback_width = fallback_width; + stex->fallback_height = fallback_height; + + invalidate_size (stex); +} + +MetaShapedTexture * +meta_shaped_texture_new (void) +{ + return g_object_new (META_TYPE_SHAPED_TEXTURE, NULL); +} + +void +meta_shaped_texture_set_buffer_scale (MetaShapedTexture *stex, + int buffer_scale) +{ + g_return_if_fail (META_IS_SHAPED_TEXTURE (stex)); + + if (buffer_scale == stex->buffer_scale) + return; + + stex->buffer_scale = buffer_scale; + + invalidate_size (stex); +} + +int +meta_shaped_texture_get_buffer_scale (MetaShapedTexture *stex) +{ + g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), 1.0); + + return stex->buffer_scale; +} + +int +meta_shaped_texture_get_width (MetaShapedTexture *stex) +{ + g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), 0); + + ensure_size_valid (stex); + + return stex->dst_width; +} + +int +meta_shaped_texture_get_height (MetaShapedTexture *stex) +{ + g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), 0); + + ensure_size_valid (stex); + + return stex->dst_height; +} diff --git a/src/compositor/meta-surface-actor-wayland.c b/src/compositor/meta-surface-actor-wayland.c new file mode 100644 index 000000000..e8d946e98 --- /dev/null +++ b/src/compositor/meta-surface-actor-wayland.c @@ -0,0 +1,130 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2013 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jasper St. Pierre <jstpierre@mecheye.net> + */ + +#include "config.h" + +#include "compositor/meta-surface-actor-wayland.h" + +#include <math.h> + +#include "backends/meta-backend-private.h" +#include "backends/meta-logical-monitor.h" +#include "cogl/cogl-wayland-server.h" +#include "compositor/meta-shaped-texture-private.h" +#include "compositor/region-utils.h" +#include "wayland/meta-wayland-buffer.h" +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-window-wayland.h" + +struct _MetaSurfaceActorWayland +{ + MetaSurfaceActor parent; + + MetaWaylandSurface *surface; +}; + +G_DEFINE_TYPE (MetaSurfaceActorWayland, + meta_surface_actor_wayland, + META_TYPE_SURFACE_ACTOR) + +static void +meta_surface_actor_wayland_process_damage (MetaSurfaceActor *actor, + int x, + int y, + int width, + int height) +{ + meta_surface_actor_update_area (actor, x, y, width, height); +} + +static void +meta_surface_actor_wayland_pre_paint (MetaSurfaceActor *actor) +{ +} + +static gboolean +meta_surface_actor_wayland_is_opaque (MetaSurfaceActor *actor) +{ + MetaShapedTexture *stex = meta_surface_actor_get_texture (actor); + + return meta_shaped_texture_is_opaque (stex); +} + +static void +meta_surface_actor_wayland_dispose (GObject *object) +{ + MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (object); + MetaShapedTexture *stex; + + stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self)); + if (stex) + meta_shaped_texture_set_texture (stex, NULL); + + if (self->surface) + { + g_object_remove_weak_pointer (G_OBJECT (self->surface), + (gpointer *) &self->surface); + self->surface = NULL; + } + + G_OBJECT_CLASS (meta_surface_actor_wayland_parent_class)->dispose (object); +} + +static void +meta_surface_actor_wayland_class_init (MetaSurfaceActorWaylandClass *klass) +{ + MetaSurfaceActorClass *surface_actor_class = META_SURFACE_ACTOR_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + surface_actor_class->process_damage = meta_surface_actor_wayland_process_damage; + surface_actor_class->pre_paint = meta_surface_actor_wayland_pre_paint; + surface_actor_class->is_opaque = meta_surface_actor_wayland_is_opaque; + + object_class->dispose = meta_surface_actor_wayland_dispose; +} + +static void +meta_surface_actor_wayland_init (MetaSurfaceActorWayland *self) +{ +} + +MetaSurfaceActor * +meta_surface_actor_wayland_new (MetaWaylandSurface *surface) +{ + MetaSurfaceActorWayland *self = g_object_new (META_TYPE_SURFACE_ACTOR_WAYLAND, NULL); + + g_assert (meta_is_wayland_compositor ()); + + self->surface = surface; + g_object_add_weak_pointer (G_OBJECT (self->surface), + (gpointer *) &self->surface); + + return META_SURFACE_ACTOR (self); +} + +MetaWaylandSurface * +meta_surface_actor_wayland_get_surface (MetaSurfaceActorWayland *self) +{ + return self->surface; +} diff --git a/src/compositor/meta-surface-actor-wayland.h b/src/compositor/meta-surface-actor-wayland.h new file mode 100644 index 000000000..e1ad843f7 --- /dev/null +++ b/src/compositor/meta-surface-actor-wayland.h @@ -0,0 +1,57 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2013 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jasper St. Pierre <jstpierre@mecheye.net> + */ + +#ifndef __META_SURFACE_ACTOR_WAYLAND_H__ +#define __META_SURFACE_ACTOR_WAYLAND_H__ + +#include <glib-object.h> + +#include "backends/meta-monitor-manager-private.h" +#include "compositor/meta-surface-actor.h" +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-wayland.h" + +G_BEGIN_DECLS + +#define META_TYPE_SURFACE_ACTOR_WAYLAND (meta_surface_actor_wayland_get_type ()) +G_DECLARE_FINAL_TYPE (MetaSurfaceActorWayland, + meta_surface_actor_wayland, + META, SURFACE_ACTOR_WAYLAND, + MetaSurfaceActor) + +MetaSurfaceActor * meta_surface_actor_wayland_new (MetaWaylandSurface *surface); +MetaWaylandSurface * meta_surface_actor_wayland_get_surface (MetaSurfaceActorWayland *self); +void meta_surface_actor_wayland_surface_destroyed (MetaSurfaceActorWayland *self); + +double meta_surface_actor_wayland_get_scale (MetaSurfaceActorWayland *actor); + +void meta_surface_actor_wayland_get_subsurface_rect (MetaSurfaceActorWayland *self, + MetaRectangle *rect); + +void meta_surface_actor_wayland_add_frame_callbacks (MetaSurfaceActorWayland *self, + struct wl_list *frame_callbacks); + +G_END_DECLS + +#endif /* __META_SURFACE_ACTOR_WAYLAND_H__ */ diff --git a/src/compositor/meta-surface-actor-x11.c b/src/compositor/meta-surface-actor-x11.c new file mode 100644 index 000000000..33d393a5b --- /dev/null +++ b/src/compositor/meta-surface-actor-x11.c @@ -0,0 +1,443 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2013 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Owen Taylor <otaylor@redhat.com> + * Jasper St. Pierre <jstpierre@mecheye.net> + */ + +#include "config.h" + +#include "compositor/meta-surface-actor-x11.h" + +#include <X11/extensions/Xcomposite.h> + +#include "cogl/winsys/cogl-texture-pixmap-x11.h" +#include "compositor/meta-cullable.h" +#include "compositor/meta-shaped-texture-private.h" +#include "compositor/meta-window-actor-private.h" +#include "core/window-private.h" +#include "meta/meta-x11-errors.h" +#include "x11/meta-x11-display-private.h" +#include "x11/window-x11.h" + +struct _MetaSurfaceActorX11 +{ + MetaSurfaceActor parent; + + MetaWindow *window; + + MetaDisplay *display; + + CoglTexture *texture; + Pixmap pixmap; + Damage damage; + + int last_width; + int last_height; + + /* This is used to detect fullscreen windows that need to be unredirected */ + guint full_damage_frames_count; + guint does_full_damage : 1; + + /* Other state... */ + guint received_damage : 1; + guint size_changed : 1; + + guint unredirected : 1; +}; + +G_DEFINE_TYPE (MetaSurfaceActorX11, + meta_surface_actor_x11, + META_TYPE_SURFACE_ACTOR) + +static void +free_damage (MetaSurfaceActorX11 *self) +{ + MetaDisplay *display = self->display; + Display *xdisplay; + + if (self->damage == None) + return; + + xdisplay = meta_x11_display_get_xdisplay (display->x11_display); + + meta_x11_error_trap_push (display->x11_display); + XDamageDestroy (xdisplay, self->damage); + self->damage = None; + meta_x11_error_trap_pop (display->x11_display); +} + +static void +detach_pixmap (MetaSurfaceActorX11 *self) +{ + MetaDisplay *display = self->display; + MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self)); + Display *xdisplay; + + if (self->pixmap == None) + return; + + xdisplay = meta_x11_display_get_xdisplay (display->x11_display); + + /* Get rid of all references to the pixmap before freeing it; it's unclear whether + * you are supposed to be able to free a GLXPixmap after freeing the underlying + * pixmap, but it certainly doesn't work with current DRI/Mesa + */ + meta_shaped_texture_set_texture (stex, NULL); + cogl_flush (); + + meta_x11_error_trap_push (display->x11_display); + XFreePixmap (xdisplay, self->pixmap); + self->pixmap = None; + meta_x11_error_trap_pop (display->x11_display); + + g_clear_pointer (&self->texture, cogl_object_unref); +} + +static void +set_pixmap (MetaSurfaceActorX11 *self, + Pixmap pixmap) +{ + CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); + MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self)); + GError *error = NULL; + CoglTexture *texture; + + g_assert (self->pixmap == None); + self->pixmap = pixmap; + + texture = COGL_TEXTURE (cogl_texture_pixmap_x11_new (ctx, self->pixmap, FALSE, &error)); + + if (error != NULL) + { + g_warning ("Failed to allocate stex texture: %s", error->message); + g_error_free (error); + } + else if (G_UNLIKELY (!cogl_texture_pixmap_x11_is_using_tfp_extension (COGL_TEXTURE_PIXMAP_X11 (texture)))) + g_warning ("NOTE: Not using GLX TFP!\n"); + + self->texture = texture; + meta_shaped_texture_set_texture (stex, texture); +} + +static void +update_pixmap (MetaSurfaceActorX11 *self) +{ + MetaDisplay *display = self->display; + Display *xdisplay = meta_x11_display_get_xdisplay (display->x11_display); + + if (self->size_changed) + { + detach_pixmap (self); + self->size_changed = FALSE; + } + + if (self->pixmap == None) + { + Pixmap new_pixmap; + Window xwindow = meta_window_x11_get_toplevel_xwindow (self->window); + + meta_x11_error_trap_push (display->x11_display); + new_pixmap = XCompositeNameWindowPixmap (xdisplay, xwindow); + + if (meta_x11_error_trap_pop_with_return (display->x11_display) != Success) + { + /* Probably a BadMatch if the window isn't viewable; we could + * GrabServer/GetWindowAttributes/NameWindowPixmap/UngrabServer/Sync + * to avoid this, but there's no reason to take two round trips + * when one will do. (We need that Sync if we want to handle failures + * for any reason other than !viewable. That's unlikely, but maybe + * we'll BadAlloc or something.) + */ + new_pixmap = None; + } + + if (new_pixmap == None) + { + meta_verbose ("Unable to get named pixmap for %s\n", + meta_window_get_description (self->window)); + return; + } + + set_pixmap (self, new_pixmap); + } +} + +gboolean +meta_surface_actor_x11_is_visible (MetaSurfaceActorX11 *self) +{ + return (self->pixmap != None) && !self->unredirected; +} + +static void +meta_surface_actor_x11_process_damage (MetaSurfaceActor *actor, + int x, int y, int width, int height) +{ + MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor); + + self->received_damage = TRUE; + + if (meta_window_is_fullscreen (self->window) && !self->unredirected && !self->does_full_damage) + { + MetaRectangle window_rect; + meta_window_get_frame_rect (self->window, &window_rect); + + if (x == 0 && + y == 0 && + window_rect.width == width && + window_rect.height == height) + self->full_damage_frames_count++; + else + self->full_damage_frames_count = 0; + + if (self->full_damage_frames_count >= 100) + self->does_full_damage = TRUE; + } + + if (!meta_surface_actor_x11_is_visible (self)) + return; + + cogl_texture_pixmap_x11_update_area (COGL_TEXTURE_PIXMAP_X11 (self->texture), + x, y, width, height); + meta_surface_actor_update_area (actor, x, y, width, height); +} + +static void +meta_surface_actor_x11_pre_paint (MetaSurfaceActor *actor) +{ + MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor); + MetaDisplay *display = self->display; + Display *xdisplay = meta_x11_display_get_xdisplay (display->x11_display); + + if (self->received_damage) + { + meta_x11_error_trap_push (display->x11_display); + XDamageSubtract (xdisplay, self->damage, None, None); + meta_x11_error_trap_pop (display->x11_display); + + self->received_damage = FALSE; + } + + update_pixmap (self); +} + +static gboolean +meta_surface_actor_x11_is_opaque (MetaSurfaceActor *actor) +{ + MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor); + MetaShapedTexture *stex = meta_surface_actor_get_texture (actor); + + if (meta_surface_actor_x11_is_unredirected (self)) + return TRUE; + + return meta_shaped_texture_is_opaque (stex); +} + +gboolean +meta_surface_actor_x11_should_unredirect (MetaSurfaceActorX11 *self) +{ + MetaWindow *window = self->window; + + if (meta_window_requested_dont_bypass_compositor (window)) + return FALSE; + + if (window->opacity != 0xFF) + return FALSE; + + if (window->shape_region != NULL) + return FALSE; + + if (!meta_window_is_monitor_sized (window)) + return FALSE; + + if (meta_window_requested_bypass_compositor (window)) + return TRUE; + + if (!meta_surface_actor_x11_is_opaque (META_SURFACE_ACTOR (self))) + return FALSE; + + if (meta_window_is_override_redirect (window)) + return TRUE; + + if (self->does_full_damage) + return TRUE; + + return FALSE; +} + +static void +sync_unredirected (MetaSurfaceActorX11 *self) +{ + MetaDisplay *display = self->display; + Display *xdisplay = meta_x11_display_get_xdisplay (display->x11_display); + Window xwindow = meta_window_x11_get_toplevel_xwindow (self->window); + + meta_x11_error_trap_push (display->x11_display); + + if (self->unredirected) + { + XCompositeUnredirectWindow (xdisplay, xwindow, CompositeRedirectManual); + XSync (xdisplay, False); + detach_pixmap (self); + } + else + { + XCompositeRedirectWindow (xdisplay, xwindow, CompositeRedirectManual); + XSync (xdisplay, False); + clutter_actor_queue_redraw (CLUTTER_ACTOR (self)); + } + + meta_x11_error_trap_pop (display->x11_display); +} + +void +meta_surface_actor_x11_set_unredirected (MetaSurfaceActorX11 *self, + gboolean unredirected) +{ + if (self->unredirected == unredirected) + return; + + self->unredirected = unredirected; + sync_unredirected (self); +} + +gboolean +meta_surface_actor_x11_is_unredirected (MetaSurfaceActorX11 *self) +{ + return self->unredirected; +} + +static void +release_x11_resources (MetaSurfaceActorX11 *self) +{ + detach_pixmap (self); + free_damage (self); +} + +static void +meta_surface_actor_x11_dispose (GObject *object) +{ + MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (object); + + release_x11_resources (self); + + G_OBJECT_CLASS (meta_surface_actor_x11_parent_class)->dispose (object); +} + +static void +meta_surface_actor_x11_class_init (MetaSurfaceActorX11Class *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MetaSurfaceActorClass *surface_actor_class = META_SURFACE_ACTOR_CLASS (klass); + + object_class->dispose = meta_surface_actor_x11_dispose; + + surface_actor_class->process_damage = meta_surface_actor_x11_process_damage; + surface_actor_class->pre_paint = meta_surface_actor_x11_pre_paint; + surface_actor_class->is_opaque = meta_surface_actor_x11_is_opaque; +} + +static void +meta_surface_actor_x11_init (MetaSurfaceActorX11 *self) +{ + self->last_width = -1; + self->last_height = -1; +} + +static void +create_damage (MetaSurfaceActorX11 *self) +{ + Display *xdisplay = meta_x11_display_get_xdisplay (self->display->x11_display); + Window xwindow = meta_window_x11_get_toplevel_xwindow (self->window); + + self->damage = XDamageCreate (xdisplay, xwindow, XDamageReportBoundingBox); +} + +static void +window_decorated_notify (MetaWindow *window, + GParamSpec *pspec, + gpointer user_data) +{ + MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (user_data); + + release_x11_resources (self); + create_damage (self); +} + +static void +reset_texture (MetaSurfaceActorX11 *self) +{ + MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self)); + + if (!self->texture) + return; + + /* Setting the texture to NULL will cause all the FBO's cached by the + * shaped texture's MetaTextureTower to be discarded and recreated. + */ + meta_shaped_texture_set_texture (stex, NULL); + meta_shaped_texture_set_texture (stex, self->texture); +} + +MetaSurfaceActor * +meta_surface_actor_x11_new (MetaWindow *window) +{ + MetaSurfaceActorX11 *self = g_object_new (META_TYPE_SURFACE_ACTOR_X11, NULL); + MetaDisplay *display = meta_window_get_display (window); + + g_assert (!meta_is_wayland_compositor ()); + + self->window = window; + self->display = display; + + g_signal_connect_object (self->display, "gl-video-memory-purged", + G_CALLBACK (reset_texture), self, G_CONNECT_SWAPPED); + + create_damage (self); + g_signal_connect_object (self->window, "notify::decorated", + G_CALLBACK (window_decorated_notify), self, 0); + + g_signal_connect_object (meta_window_actor_from_window (window), "destroy", + G_CALLBACK (release_x11_resources), self, + G_CONNECT_SWAPPED); + + self->unredirected = FALSE; + sync_unredirected (self); + + clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE); + return META_SURFACE_ACTOR (self); +} + +void +meta_surface_actor_x11_set_size (MetaSurfaceActorX11 *self, + int width, int height) +{ + MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self)); + + if (self->last_width == width && + self->last_height == height) + return; + + self->size_changed = TRUE; + self->last_width = width; + self->last_height = height; + meta_shaped_texture_set_fallback_size (stex, width, height); +} diff --git a/src/compositor/meta-surface-actor-x11.h b/src/compositor/meta-surface-actor-x11.h new file mode 100644 index 000000000..9fd703bfe --- /dev/null +++ b/src/compositor/meta-surface-actor-x11.h @@ -0,0 +1,60 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2013 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Owen Taylor <otaylor@redhat.com> + * Jasper St. Pierre <jstpierre@mecheye.net> + */ + +#ifndef __META_SURFACE_ACTOR_X11_H__ +#define __META_SURFACE_ACTOR_X11_H__ + +#include <glib-object.h> + +#include <X11/extensions/Xdamage.h> + +#include "compositor/meta-surface-actor.h" +#include "meta/display.h" +#include "meta/window.h" + +G_BEGIN_DECLS + +#define META_TYPE_SURFACE_ACTOR_X11 (meta_surface_actor_x11_get_type ()) +G_DECLARE_FINAL_TYPE (MetaSurfaceActorX11, + meta_surface_actor_x11, + META, SURFACE_ACTOR_X11, + MetaSurfaceActor) + +MetaSurfaceActor * meta_surface_actor_x11_new (MetaWindow *window); + +void meta_surface_actor_x11_set_size (MetaSurfaceActorX11 *self, + int width, int height); +gboolean meta_surface_actor_x11_should_unredirect (MetaSurfaceActorX11 *self); + +void meta_surface_actor_x11_set_unredirected (MetaSurfaceActorX11 *self, + gboolean unredirected); + +gboolean meta_surface_actor_x11_is_unredirected (MetaSurfaceActorX11 *self); + +gboolean meta_surface_actor_x11_is_visible (MetaSurfaceActorX11 *self); + +G_END_DECLS + +#endif /* __META_SURFACE_ACTOR_X11_H__ */ diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c new file mode 100644 index 000000000..6cc3a6795 --- /dev/null +++ b/src/compositor/meta-surface-actor.c @@ -0,0 +1,638 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/** + * SECTION:meta-surface-actor + * @title: MetaSurfaceActor + * @short_description: An actor representing a surface in the scene graph + * + * MetaSurfaceActor is an abstract class which represents a surface in the + * Clutter scene graph. A subclass can implement the specifics of a surface + * depending on the way it is handled by a display protocol. + * + * An important feature of #MetaSurfaceActor is that it allows you to set an + * "input region": all events that occur in the surface, but outside of the + * input region are to be explicitly ignored. By default, this region is to + * %NULL, which means events on the whole surface is allowed. + */ + +#include "config.h" + +#include "compositor/meta-surface-actor.h" + +#include "clutter/clutter.h" +#include "compositor/clutter-utils.h" +#include "compositor/meta-cullable.h" +#include "compositor/meta-shaped-texture-private.h" +#include "compositor/meta-window-actor-private.h" +#include "compositor/region-utils.h" +#include "meta/meta-shaped-texture.h" + +typedef struct _MetaSurfaceActorPrivate +{ + MetaShapedTexture *texture; + + cairo_region_t *input_region; + + /* MetaCullable regions, see that documentation for more details */ + cairo_region_t *unobscured_region; + + /* Freeze/thaw accounting */ + cairo_region_t *pending_damage; + guint frozen : 1; +} MetaSurfaceActorPrivate; + +static void cullable_iface_init (MetaCullableInterface *iface); + +G_DEFINE_ABSTRACT_TYPE_WITH_CODE (MetaSurfaceActor, meta_surface_actor, CLUTTER_TYPE_ACTOR, + G_ADD_PRIVATE (MetaSurfaceActor) + G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init)); + +enum +{ + REPAINT_SCHEDULED, + SIZE_CHANGED, + + LAST_SIGNAL, +}; + +static guint signals[LAST_SIGNAL]; + +typedef enum +{ + IN_STAGE_PERSPECTIVE, + IN_ACTOR_PERSPECTIVE +} ScalePerspectiveType; + +static cairo_region_t * +effective_unobscured_region (MetaSurfaceActor *surface_actor) +{ + MetaSurfaceActorPrivate *priv = + meta_surface_actor_get_instance_private (surface_actor); + ClutterActor *actor; + + /* Fail if we have any mapped clones. */ + actor = CLUTTER_ACTOR (surface_actor); + do + { + if (clutter_actor_has_mapped_clones (actor)) + return NULL; + actor = clutter_actor_get_parent (actor); + } + while (actor != NULL); + + return priv->unobscured_region; +} + +static cairo_region_t* +get_scaled_region (MetaSurfaceActor *surface_actor, + cairo_region_t *region, + ScalePerspectiveType scale_perspective) +{ + MetaWindowActor *window_actor; + cairo_region_t *scaled_region; + int geometry_scale; + float x, y; + + window_actor = meta_window_actor_from_actor (CLUTTER_ACTOR (surface_actor)); + geometry_scale = meta_window_actor_get_geometry_scale (window_actor); + + clutter_actor_get_position (CLUTTER_ACTOR (surface_actor), &x, &y); + cairo_region_translate (region, x, y); + + switch (scale_perspective) + { + case IN_STAGE_PERSPECTIVE: + scaled_region = meta_region_scale_double (region, + geometry_scale, + META_ROUNDING_STRATEGY_GROW); + break; + case IN_ACTOR_PERSPECTIVE: + scaled_region = meta_region_scale_double (region, + 1.0 / geometry_scale, + META_ROUNDING_STRATEGY_GROW); + break; + } + + cairo_region_translate (region, -x, -y); + cairo_region_translate (scaled_region, -x, -y); + + return scaled_region; +} + +static void +set_unobscured_region (MetaSurfaceActor *surface_actor, + cairo_region_t *unobscured_region) +{ + MetaSurfaceActorPrivate *priv = + meta_surface_actor_get_instance_private (surface_actor); + + g_clear_pointer (&priv->unobscured_region, cairo_region_destroy); + if (unobscured_region) + { + if (cairo_region_is_empty (unobscured_region)) + { + priv->unobscured_region = cairo_region_reference (unobscured_region); + } + else + { + cairo_rectangle_int_t bounds = { 0, }; + float width, height; + + clutter_content_get_preferred_size (CLUTTER_CONTENT (priv->texture), + &width, + &height); + bounds = (cairo_rectangle_int_t) { + .width = width, + .height = height, + }; + + priv->unobscured_region = get_scaled_region (surface_actor, + unobscured_region, + IN_ACTOR_PERSPECTIVE); + + cairo_region_intersect_rectangle (priv->unobscured_region, &bounds); + } + } +} + +static void +set_clip_region (MetaSurfaceActor *surface_actor, + cairo_region_t *clip_region) +{ + MetaSurfaceActorPrivate *priv = + meta_surface_actor_get_instance_private (surface_actor); + MetaShapedTexture *stex = priv->texture; + + if (clip_region && !cairo_region_is_empty (clip_region)) + { + cairo_region_t *region; + + region = get_scaled_region (surface_actor, + clip_region, + IN_ACTOR_PERSPECTIVE); + meta_shaped_texture_set_clip_region (stex, region); + + cairo_region_destroy (region); + } + else + { + meta_shaped_texture_set_clip_region (stex, clip_region); + } +} + +static void +meta_surface_actor_pick (ClutterActor *actor, + ClutterPickContext *pick_context) +{ + MetaSurfaceActor *self = META_SURFACE_ACTOR (actor); + MetaSurfaceActorPrivate *priv = + meta_surface_actor_get_instance_private (self); + ClutterActorIter iter; + ClutterActor *child; + + if (!clutter_actor_should_pick_paint (actor)) + return; + + /* If there is no region then use the regular pick */ + if (priv->input_region == NULL) + { + ClutterActorClass *actor_class = + CLUTTER_ACTOR_CLASS (meta_surface_actor_parent_class); + + actor_class->pick (actor, pick_context); + } + else + { + int n_rects; + int i; + + n_rects = cairo_region_num_rectangles (priv->input_region); + + for (i = 0; i < n_rects; i++) + { + cairo_rectangle_int_t rect; + ClutterActorBox box; + + cairo_region_get_rectangle (priv->input_region, i, &rect); + + box.x1 = rect.x; + box.y1 = rect.y; + box.x2 = rect.x + rect.width; + box.y2 = rect.y + rect.height; + clutter_actor_pick_box (actor, pick_context, &box); + } + } + + clutter_actor_iter_init (&iter, actor); + + while (clutter_actor_iter_next (&iter, &child)) + clutter_actor_pick (child, pick_context); +} + +static gboolean +meta_surface_actor_get_paint_volume (ClutterActor *actor, + ClutterPaintVolume *volume) +{ + return clutter_paint_volume_set_from_allocation (volume, actor); +} + +static void +meta_surface_actor_dispose (GObject *object) +{ + MetaSurfaceActor *self = META_SURFACE_ACTOR (object); + MetaSurfaceActorPrivate *priv = + meta_surface_actor_get_instance_private (self); + + g_clear_pointer (&priv->input_region, cairo_region_destroy); + g_clear_object (&priv->texture); + + set_unobscured_region (self, NULL); + + G_OBJECT_CLASS (meta_surface_actor_parent_class)->dispose (object); +} + +static void +meta_surface_actor_class_init (MetaSurfaceActorClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); + + object_class->dispose = meta_surface_actor_dispose; + actor_class->pick = meta_surface_actor_pick; + actor_class->get_paint_volume = meta_surface_actor_get_paint_volume; + + signals[REPAINT_SCHEDULED] = g_signal_new ("repaint-scheduled", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); + + signals[SIZE_CHANGED] = g_signal_new ("size-changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); +} + +gboolean +meta_surface_actor_is_opaque (MetaSurfaceActor *self) +{ + return META_SURFACE_ACTOR_GET_CLASS (self)->is_opaque (self); +} + +static void +meta_surface_actor_cull_out (MetaCullable *cullable, + cairo_region_t *unobscured_region, + cairo_region_t *clip_region) +{ + MetaSurfaceActor *surface_actor = META_SURFACE_ACTOR (cullable); + MetaSurfaceActorPrivate *priv = + meta_surface_actor_get_instance_private (surface_actor); + uint8_t opacity = clutter_actor_get_opacity (CLUTTER_ACTOR (cullable)); + + set_unobscured_region (surface_actor, unobscured_region); + set_clip_region (surface_actor, clip_region); + + if (opacity == 0xff) + { + cairo_region_t *opaque_region; + cairo_region_t *scaled_opaque_region; + + opaque_region = meta_shaped_texture_get_opaque_region (priv->texture); + + if (!opaque_region) + return; + + scaled_opaque_region = get_scaled_region (surface_actor, + opaque_region, + IN_STAGE_PERSPECTIVE); + + if (unobscured_region) + cairo_region_subtract (unobscured_region, scaled_opaque_region); + if (clip_region) + cairo_region_subtract (clip_region, scaled_opaque_region); + + cairo_region_destroy (scaled_opaque_region); + } +} + +static gboolean +meta_surface_actor_is_untransformed (MetaCullable *cullable) +{ + ClutterActor *actor = CLUTTER_ACTOR (cullable); + MetaWindowActor *window_actor; + float width, height; + graphene_point3d_t verts[4]; + int geometry_scale; + + clutter_actor_get_size (actor, &width, &height); + clutter_actor_get_abs_allocation_vertices (actor, verts); + + window_actor = meta_window_actor_from_actor (actor); + geometry_scale = meta_window_actor_get_geometry_scale (window_actor); + + return meta_actor_vertices_are_untransformed (verts, + width * geometry_scale, + height * geometry_scale, + NULL, NULL); +} + +static void +meta_surface_actor_reset_culling (MetaCullable *cullable) +{ + MetaSurfaceActor *surface_actor = META_SURFACE_ACTOR (cullable); + + set_clip_region (surface_actor, NULL); +} + +static void +cullable_iface_init (MetaCullableInterface *iface) +{ + iface->cull_out = meta_surface_actor_cull_out; + iface->is_untransformed = meta_surface_actor_is_untransformed; + iface->reset_culling = meta_surface_actor_reset_culling; +} + +static void +texture_size_changed (MetaShapedTexture *texture, + gpointer user_data) +{ + MetaSurfaceActor *actor = META_SURFACE_ACTOR (user_data); + g_signal_emit (actor, signals[SIZE_CHANGED], 0); +} + +static void +meta_surface_actor_init (MetaSurfaceActor *self) +{ + MetaSurfaceActorPrivate *priv = + meta_surface_actor_get_instance_private (self); + + priv->texture = meta_shaped_texture_new (); + g_signal_connect_object (priv->texture, "size-changed", + G_CALLBACK (texture_size_changed), self, 0); + clutter_actor_set_content (CLUTTER_ACTOR (self), + CLUTTER_CONTENT (priv->texture)); + clutter_actor_set_request_mode (CLUTTER_ACTOR (self), + CLUTTER_REQUEST_CONTENT_SIZE); +} + +/** + * meta_surface_actor_get_image: + * @self: A #MetaSurfaceActor + * @clip: (nullable): A clipping rectangle. The clip region is in + * the same coordinate space as the contents preferred size. + * For a shaped texture of a wl_surface, this means surface + * coordinate space. If NULL, the whole content will be used. + * + * Get the image from the texture content. The resulting size of + * the returned image may be different from the preferred size of + * the shaped texture content. + * + * Returns: (nullable) (transfer full): a new cairo surface to be freed + * with cairo_surface_destroy(). + */ +cairo_surface_t * +meta_surface_actor_get_image (MetaSurfaceActor *self, + cairo_rectangle_int_t *clip) +{ + MetaSurfaceActorPrivate *priv = + meta_surface_actor_get_instance_private (self); + + return meta_shaped_texture_get_image (priv->texture, clip); +} + +MetaShapedTexture * +meta_surface_actor_get_texture (MetaSurfaceActor *self) +{ + MetaSurfaceActorPrivate *priv = + meta_surface_actor_get_instance_private (self); + + return priv->texture; +} + +void +meta_surface_actor_update_area (MetaSurfaceActor *self, + int x, + int y, + int width, + int height) +{ + MetaSurfaceActorPrivate *priv = + meta_surface_actor_get_instance_private (self); + gboolean repaint_scheduled = FALSE; + cairo_rectangle_int_t clip; + + if (meta_shaped_texture_update_area (priv->texture, x, y, width, height, &clip)) + { + cairo_region_t *unobscured_region; + + unobscured_region = effective_unobscured_region (self); + + if (unobscured_region) + { + cairo_region_t *intersection; + + if (cairo_region_is_empty (unobscured_region)) + return; + + intersection = cairo_region_copy (unobscured_region); + cairo_region_intersect_rectangle (intersection, &clip); + + if (!cairo_region_is_empty (intersection)) + { + cairo_rectangle_int_t damage_rect; + + cairo_region_get_extents (intersection, &damage_rect); + clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (self), &damage_rect); + repaint_scheduled = TRUE; + } + + cairo_region_destroy (intersection); + } + else + { + clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (self), &clip); + repaint_scheduled = TRUE; + } + } + + if (repaint_scheduled) + g_signal_emit (self, signals[REPAINT_SCHEDULED], 0); +} + +gboolean +meta_surface_actor_is_obscured (MetaSurfaceActor *self) +{ + cairo_region_t *unobscured_region; + + unobscured_region = effective_unobscured_region (self); + + if (unobscured_region) + return cairo_region_is_empty (unobscured_region); + else + return FALSE; +} + +void +meta_surface_actor_set_input_region (MetaSurfaceActor *self, + cairo_region_t *region) +{ + MetaSurfaceActorPrivate *priv = + meta_surface_actor_get_instance_private (self); + + if (priv->input_region) + cairo_region_destroy (priv->input_region); + + if (region) + priv->input_region = cairo_region_reference (region); + else + priv->input_region = NULL; +} + +void +meta_surface_actor_set_opaque_region (MetaSurfaceActor *self, + cairo_region_t *region) +{ + MetaSurfaceActorPrivate *priv = + meta_surface_actor_get_instance_private (self); + + meta_shaped_texture_set_opaque_region (priv->texture, region); +} + +cairo_region_t * +meta_surface_actor_get_opaque_region (MetaSurfaceActor *self) +{ + MetaSurfaceActorPrivate *priv = + meta_surface_actor_get_instance_private (self); + + return meta_shaped_texture_get_opaque_region (priv->texture); +} + +void +meta_surface_actor_process_damage (MetaSurfaceActor *self, + int x, int y, int width, int height) +{ + MetaSurfaceActorPrivate *priv = + meta_surface_actor_get_instance_private (self); + + if (meta_surface_actor_is_frozen (self)) + { + /* The window is frozen due to an effect in progress: we ignore damage + * here on the off chance that this will stop the corresponding + * texture_from_pixmap from being update. + * + * pending_damage tracks any damage that happened while the window was + * frozen so that when can apply it when the window becomes unfrozen. + * + * It should be noted that this is an unreliable mechanism since it's + * quite likely that drivers will aim to provide a zero-copy + * implementation of the texture_from_pixmap extension and in those cases + * any drawing done to the window is always immediately reflected in the + * texture regardless of damage event handling. + */ + cairo_rectangle_int_t rect = { .x = x, .y = y, .width = width, .height = height }; + + if (!priv->pending_damage) + priv->pending_damage = cairo_region_create_rectangle (&rect); + else + cairo_region_union_rectangle (priv->pending_damage, &rect); + return; + } + + META_SURFACE_ACTOR_GET_CLASS (self)->process_damage (self, x, y, width, height); +} + +void +meta_surface_actor_pre_paint (MetaSurfaceActor *self) +{ + META_SURFACE_ACTOR_GET_CLASS (self)->pre_paint (self); +} + +void +meta_surface_actor_set_frozen (MetaSurfaceActor *self, + gboolean frozen) +{ + MetaSurfaceActorPrivate *priv = + meta_surface_actor_get_instance_private (self); + + priv->frozen = frozen; + + if (!frozen && priv->pending_damage) + { + int i, n_rects = cairo_region_num_rectangles (priv->pending_damage); + cairo_rectangle_int_t rect; + + /* Since we ignore damage events while a window is frozen for certain effects + * we need to apply the tracked damage now. */ + + for (i = 0; i < n_rects; i++) + { + cairo_region_get_rectangle (priv->pending_damage, i, &rect); + meta_surface_actor_process_damage (self, rect.x, rect.y, + rect.width, rect.height); + } + g_clear_pointer (&priv->pending_damage, cairo_region_destroy); + } +} + +gboolean +meta_surface_actor_is_frozen (MetaSurfaceActor *self) +{ + MetaSurfaceActorPrivate *priv = + meta_surface_actor_get_instance_private (self); + + return priv->frozen; +} + +void +meta_surface_actor_set_transform (MetaSurfaceActor *self, + MetaMonitorTransform transform) +{ + MetaSurfaceActorPrivate *priv = + meta_surface_actor_get_instance_private (self); + + meta_shaped_texture_set_transform (priv->texture, transform); +} + +void +meta_surface_actor_set_viewport_src_rect (MetaSurfaceActor *self, + graphene_rect_t *src_rect) +{ + MetaSurfaceActorPrivate *priv = + meta_surface_actor_get_instance_private (self); + + meta_shaped_texture_set_viewport_src_rect (priv->texture, src_rect); +} + +void +meta_surface_actor_reset_viewport_src_rect (MetaSurfaceActor *self) +{ + MetaSurfaceActorPrivate *priv = + meta_surface_actor_get_instance_private (self); + + meta_shaped_texture_reset_viewport_src_rect (priv->texture); +} + +void +meta_surface_actor_set_viewport_dst_size (MetaSurfaceActor *self, + int dst_width, + int dst_height) +{ + MetaSurfaceActorPrivate *priv = + meta_surface_actor_get_instance_private (self); + + meta_shaped_texture_set_viewport_dst_size (priv->texture, + dst_width, + dst_height); +} + +void +meta_surface_actor_reset_viewport_dst_size (MetaSurfaceActor *self) +{ + MetaSurfaceActorPrivate *priv = + meta_surface_actor_get_instance_private (self); + + meta_shaped_texture_reset_viewport_dst_size (priv->texture); +} diff --git a/src/compositor/meta-surface-actor.h b/src/compositor/meta-surface-actor.h new file mode 100644 index 000000000..d8b7365b2 --- /dev/null +++ b/src/compositor/meta-surface-actor.h @@ -0,0 +1,70 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +#ifndef META_SURFACE_ACTOR_PRIVATE_H +#define META_SURFACE_ACTOR_PRIVATE_H + +#include "config.h" + +#include "backends/meta-backend-types.h" +#include "meta/meta-shaped-texture.h" +#include "meta/window.h" + +G_BEGIN_DECLS + +#define META_TYPE_SURFACE_ACTOR (meta_surface_actor_get_type ()) +G_DECLARE_DERIVABLE_TYPE (MetaSurfaceActor, + meta_surface_actor, + META, SURFACE_ACTOR, + ClutterActor) + +struct _MetaSurfaceActorClass +{ + /*< private >*/ + ClutterActorClass parent_class; + + void (* process_damage) (MetaSurfaceActor *actor, + int x, int y, int width, int height); + void (* pre_paint) (MetaSurfaceActor *actor); + gboolean (* is_opaque) (MetaSurfaceActor *actor); +}; + +cairo_surface_t *meta_surface_actor_get_image (MetaSurfaceActor *self, + cairo_rectangle_int_t *clip); + +MetaShapedTexture *meta_surface_actor_get_texture (MetaSurfaceActor *self); + +void meta_surface_actor_update_area (MetaSurfaceActor *self, + int x, + int y, + int width, + int height); + +gboolean meta_surface_actor_is_obscured (MetaSurfaceActor *self); + +void meta_surface_actor_set_input_region (MetaSurfaceActor *self, + cairo_region_t *region); +void meta_surface_actor_set_opaque_region (MetaSurfaceActor *self, + cairo_region_t *region); +cairo_region_t * meta_surface_actor_get_opaque_region (MetaSurfaceActor *self); + +void meta_surface_actor_process_damage (MetaSurfaceActor *actor, + int x, int y, int width, int height); +void meta_surface_actor_pre_paint (MetaSurfaceActor *actor); +gboolean meta_surface_actor_is_opaque (MetaSurfaceActor *actor); + +gboolean meta_surface_actor_is_frozen (MetaSurfaceActor *actor); +void meta_surface_actor_set_frozen (MetaSurfaceActor *actor, + gboolean frozen); + +void meta_surface_actor_set_transform (MetaSurfaceActor *self, + MetaMonitorTransform transform); +void meta_surface_actor_set_viewport_src_rect (MetaSurfaceActor *self, + graphene_rect_t *src_rect); +void meta_surface_actor_reset_viewport_src_rect (MetaSurfaceActor *self); +void meta_surface_actor_set_viewport_dst_size (MetaSurfaceActor *self, + int dst_width, + int dst_height); +void meta_surface_actor_reset_viewport_dst_size (MetaSurfaceActor *self); +G_END_DECLS + +#endif /* META_SURFACE_ACTOR_PRIVATE_H */ diff --git a/src/compositor/meta-sync-ring.c b/src/compositor/meta-sync-ring.c index d56c9a3e2..944b4a886 100644 --- a/src/compositor/meta-sync-ring.c +++ b/src/compositor/meta-sync-ring.c @@ -28,20 +28,18 @@ * Authors: James Jones <jajones@nvidia.com> */ -#include <string.h> -#include <stdlib.h> +#include "config.h" + +#include "compositor/meta-sync-ring.h" +#include <string.h> #include <GL/gl.h> #include <GL/glx.h> #include <X11/extensions/sync.h> -#include <cogl/cogl.h> -#include <clutter/clutter.h> - -#include <meta/util.h> - -#include "cogl-utils.h" -#include "meta-sync-ring.h" +#include "clutter/clutter.h" +#include "cogl/cogl.h" +#include "meta/util.h" /* Theory of operation: * @@ -159,26 +157,14 @@ check_gl_extensions (void) cogl_display = cogl_context_get_display (cogl_context); cogl_renderer = cogl_display_get_renderer (cogl_display); - meta_cogl_hardware_supports_npot_sizes (); - switch (cogl_renderer_get_driver (cogl_renderer)) { case COGL_DRIVER_GL3: { - - int major, minor; - gboolean version_ok = FALSE; int num_extensions, i; gboolean arb_sync = FALSE; gboolean x11_sync_object = FALSE; - meta_gl_get_integerv (GL_MAJOR_VERSION, &major); - meta_gl_get_integerv (GL_MINOR_VERSION, &minor); - - version_ok = (major >= 3); - - g_printerr ("openGL version %d.%d detected (GL3 Cogl Driver)\n", major, minor); - meta_gl_get_integerv (GL_NUM_EXTENSIONS, &num_extensions); for (i = 0; i < num_extensions; ++i) @@ -191,48 +177,15 @@ check_gl_extensions (void) x11_sync_object = TRUE; } - return version_ok && arb_sync && x11_sync_object; + return arb_sync && x11_sync_object; } case COGL_DRIVER_GL: { - gboolean version_ok = FALSE; - const char *extensions; - const char *version_string = meta_gl_get_string (GL_VERSION); - - /* From the spec: - - The string returned starts with "<major version>.<minor version>". - Following the minor version, there can be another '.', - then a vendor-specific build number. The string may have more content, - which is completely vendor-specific (thus not a part of the OpenGL standard). - - So, we can split this by . and care only about the first two substrings returned. - Anything else is dumped in the third substring. - */ - - gchar **split = g_strsplit (version_string, ".", 3); - - if (g_strv_length (split) >= 2) - { - g_printerr ("openGL version %s.%s detected (GL Cogl Driver)\n", split[0], split[1]); - - version_ok = (atoi (split[0]) >= 3); - } - - g_strfreev (split); - - extensions = meta_gl_get_string (GL_EXTENSIONS); - return version_ok && - (extensions != NULL && + const char *extensions = meta_gl_get_string (GL_EXTENSIONS); + return (extensions != NULL && strstr (extensions, "GL_ARB_sync") != NULL && strstr (extensions, "GL_EXT_x11_sync_object") != NULL); } - case COGL_DRIVER_ANY: - case COGL_DRIVER_NOP: - case COGL_DRIVER_GLES1: - case COGL_DRIVER_GLES2: - case COGL_DRIVER_WEBGL: - break; default: break; } @@ -262,7 +215,7 @@ load_required_symbols (void) if (!check_gl_extensions ()) { - g_printerr ("MetaSyncRing disabled: couldn't find required GL extensions, or the minimum safe openGL version was not met\n"); + meta_verbose ("MetaSyncRing: couldn't find required GL extensions\n"); goto out; } @@ -316,9 +269,6 @@ meta_sync_check_update_finished (MetaSync *self, self->gpu_fence = 0; } break; - case META_SYNC_STATE_READY: - case META_SYNC_STATE_RESET_PENDING: - break; default: break; } @@ -367,7 +317,7 @@ meta_sync_new (Display *xdisplay) MetaSync *self; XSyncAlarmAttributes attrs; - self = calloc (1, sizeof (MetaSync)); + self = g_malloc0 (sizeof (MetaSync)); self->xdisplay = xdisplay; @@ -444,7 +394,7 @@ meta_sync_free (MetaSync *self) XIfEvent (self->xdisplay, &event, alarm_event_predicate, (XPointer) self); meta_sync_handle_event (self, (XSyncAlarmNotifyEvent *) &event); } - /* fall through */ + G_GNUC_FALLTHROUGH; case META_SYNC_STATE_READY: XSyncTriggerFence (self->xdisplay, self->xfence); XFlush (self->xdisplay); @@ -458,7 +408,7 @@ meta_sync_free (MetaSync *self) XSyncDestroyCounter (self->xdisplay, self->xcounter); XSyncDestroyAlarm (self->xdisplay, self->xalarm); - free (self); + g_free (self); } gboolean diff --git a/src/compositor/meta-sync-ring.h b/src/compositor/meta-sync-ring.h index 6dca8efcd..d9739455b 100644 --- a/src/compositor/meta-sync-ring.h +++ b/src/compositor/meta-sync-ring.h @@ -2,7 +2,6 @@ #define _META_SYNC_RING_H_ #include <glib.h> - #include <X11/Xlib.h> gboolean meta_sync_ring_init (Display *dpy); diff --git a/src/compositor/meta-texture-rectangle.c b/src/compositor/meta-texture-rectangle.c deleted file mode 100644 index 2d765845b..000000000 --- a/src/compositor/meta-texture-rectangle.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * texture rectangle - * - * A small utility function to help create a rectangle texture - * - * Authored By Neil Roberts <neil@linux.intel.com> - * - * Copyright (C) 2011, 2012 Intel Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. - */ - -#include <config.h> - -#include <clutter/clutter.h> -#include "meta-texture-rectangle.h" - -static void -texture_rectangle_check_cb (CoglTexture *sub_texture, - const float *sub_texture_coords, - const float *meta_coords, - void *user_data) -{ - gboolean *result = user_data; - - if (cogl_is_texture_rectangle (sub_texture)) - *result = TRUE; -} - -/* Determines if the given texture is using a rectangle texture as its - * primitive texture type. Eventually this function could be replaced - * with cogl_texture_get_type if Cogl makes that public. - * - * http://git.gnome.org/browse/cogl/commit/?h=8012eee31 - */ -LOCAL_SYMBOL gboolean -meta_texture_rectangle_check (CoglTexture *texture) -{ - gboolean result = FALSE; - - cogl_meta_texture_foreach_in_region (COGL_META_TEXTURE (texture), - 0.0f, 0.0f, /* tx_1 / ty_1 */ - 1.0f, 1.0f, /* tx_2 / ty_2 */ - COGL_PIPELINE_WRAP_MODE_REPEAT, - COGL_PIPELINE_WRAP_MODE_REPEAT, - texture_rectangle_check_cb, - &result); - - return result; -} diff --git a/src/compositor/meta-texture-tower.c b/src/compositor/meta-texture-tower.c index 733923529..b0df9ed06 100644 --- a/src/compositor/meta-texture-tower.c +++ b/src/compositor/meta-texture-tower.c @@ -17,21 +17,15 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ -#if HAVE_CONFIG_H -#include <config.h> -#endif +#include "config.h" #include <math.h> #include <string.h> -#include "meta-texture-tower.h" -#include "meta-texture-rectangle.h" -#include "cogl-utils.h" +#include "compositor/meta-texture-tower.h" #ifndef M_LOG2E #define M_LOG2E 1.4426950408889634074 @@ -78,7 +72,7 @@ struct _MetaTextureTower * * Return value: the new texture tower. Free with meta_texture_tower_free() */ -LOCAL_SYMBOL MetaTextureTower * +MetaTextureTower * meta_texture_tower_new (void) { MetaTextureTower *tower; @@ -94,7 +88,7 @@ meta_texture_tower_new (void) * * Frees a texture tower created with meta_texture_tower_new(). */ -LOCAL_SYMBOL void +void meta_texture_tower_free (MetaTextureTower *tower) { g_return_if_fail (tower != NULL); @@ -117,9 +111,9 @@ meta_texture_tower_free (MetaTextureTower *tower) * will be used as level 0 of the tower and will be referenced until * unset or until the tower is freed. */ -LOCAL_SYMBOL void +void meta_texture_tower_set_base_texture (MetaTextureTower *tower, - CoglTexture *texture) + CoglTexture *texture) { int i; @@ -182,7 +176,7 @@ meta_texture_tower_set_base_texture (MetaTextureTower *tower, * time a scaled down version of the base texture is retrieved, * the appropriate area of the scaled down texture will be updated. */ -LOCAL_SYMBOL void +void meta_texture_tower_update_area (MetaTextureTower *tower, int x, int y, @@ -249,8 +243,11 @@ meta_texture_tower_update_area (MetaTextureTower *tower, * Meta. */ static int -get_paint_level (int width, int height) +get_paint_level (ClutterPaintContext *paint_context, + int width, + int height) { + CoglFramebuffer *framebuffer; CoglMatrix projection, modelview, pm; float v[4]; double viewport_width, viewport_height; @@ -277,12 +274,13 @@ get_paint_level (int width, int height) * (w_c) (w_o) (1) */ - cogl_get_projection_matrix (&projection); - cogl_get_modelview_matrix (&modelview); + framebuffer = clutter_paint_context_get_framebuffer (paint_context); + cogl_framebuffer_get_projection_matrix (framebuffer, &projection); + cogl_framebuffer_get_modelview_matrix (framebuffer, &modelview); cogl_matrix_multiply (&pm, &projection, &modelview); - cogl_get_viewport (v); + cogl_framebuffer_get_viewport4fv (framebuffer, v); viewport_width = v[2]; viewport_height = v[3]; @@ -351,32 +349,15 @@ get_paint_level (int width, int height) return (int)(0.5 + lambda); } -static gboolean -is_power_of_two (int x) -{ - return (x & (x - 1)) == 0; -} - static void texture_tower_create_texture (MetaTextureTower *tower, int level, int width, int height) { - if ((!is_power_of_two (width) || !is_power_of_two (height)) && - meta_texture_rectangle_check (tower->textures[level - 1])) - { - CoglTextureRectangle *texture_rectangle; - - texture_rectangle = cogl_texture_rectangle_new_with_size (meta_compositor_get_cogl_context (), width, height); - tower->textures[level] = COGL_TEXTURE (texture_rectangle); - } - else - { - tower->textures[level] = cogl_texture_new_with_size (width, height, - COGL_TEXTURE_NO_AUTO_MIPMAP, - TEXTURE_FORMAT); - } + tower->textures[level] = cogl_texture_new_with_size (width, height, + COGL_TEXTURE_NO_AUTO_MIPMAP, + TEXTURE_FORMAT); tower->invalid[level].x1 = 0; tower->invalid[level].y1 = 0; @@ -386,7 +367,7 @@ texture_tower_create_texture (MetaTextureTower *tower, static void texture_tower_revalidate (MetaTextureTower *tower, - int level) + int level) { CoglTexture *source_texture = tower->textures[level - 1]; int source_texture_width = cogl_texture_get_width (source_texture); @@ -396,7 +377,7 @@ texture_tower_revalidate (MetaTextureTower *tower, int dest_texture_height = cogl_texture_get_height (dest_texture); Box *invalid = &tower->invalid[level]; CoglFramebuffer *fb; - CoglError *catch_error = NULL; + GError *catch_error = NULL; CoglPipeline *pipeline; if (tower->fbos[level] == NULL) @@ -406,7 +387,7 @@ texture_tower_revalidate (MetaTextureTower *tower, if (!cogl_framebuffer_allocate (fb, &catch_error)) { - cogl_error_free (catch_error); + g_error_free (catch_error); return; } @@ -414,7 +395,9 @@ texture_tower_revalidate (MetaTextureTower *tower, if (!tower->pipeline_template) { - tower->pipeline_template = cogl_pipeline_new (meta_compositor_get_cogl_context ()); + CoglContext *ctx = + clutter_backend_get_cogl_context (clutter_get_default_backend ()); + tower->pipeline_template = cogl_pipeline_new (ctx); cogl_pipeline_set_blend (tower->pipeline_template, "RGBA = ADD (SRC_COLOR, 0)", NULL); } @@ -438,6 +421,7 @@ texture_tower_revalidate (MetaTextureTower *tower, /** * meta_texture_tower_get_paint_texture: * @tower: a #MetaTextureTower + * @paint_context: a #ClutterPaintContext * * Gets the texture from the tower that best matches the current * rendering scale. (On the assumption here the texture is going to @@ -448,8 +432,9 @@ texture_tower_revalidate (MetaTextureTower *tower, * Return value: the COGL texture handle to use for painting, or * %NULL if no base texture has yet been set. */ -LOCAL_SYMBOL CoglTexture * -meta_texture_tower_get_paint_texture (MetaTextureTower *tower) +CoglTexture * +meta_texture_tower_get_paint_texture (MetaTextureTower *tower, + ClutterPaintContext *paint_context) { int texture_width, texture_height; int level; @@ -462,7 +447,7 @@ meta_texture_tower_get_paint_texture (MetaTextureTower *tower) texture_width = cogl_texture_get_width (tower->textures[0]); texture_height = cogl_texture_get_height (tower->textures[0]); - level = get_paint_level(texture_width, texture_height); + level = get_paint_level (paint_context, texture_width, texture_height); if (level < 0) /* singular paint matrix, scaled to nothing */ return NULL; level = MIN (level, tower->n_levels - 1); diff --git a/src/compositor/meta-texture-tower.h b/src/compositor/meta-texture-tower.h index c7e75426f..1f5b37146 100644 --- a/src/compositor/meta-texture-tower.h +++ b/src/compositor/meta-texture-tower.h @@ -17,15 +17,13 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef __META_TEXTURE_TOWER_H__ #define __META_TEXTURE_TOWER_H__ -#include <clutter/clutter.h> +#include "clutter/clutter.h" G_BEGIN_DECLS @@ -62,8 +60,9 @@ void meta_texture_tower_update_area (MetaTextureTower *tower, int y, int width, int height); -CoglTexture *meta_texture_tower_get_paint_texture (MetaTextureTower *tower); +CoglTexture *meta_texture_tower_get_paint_texture (MetaTextureTower *tower, + ClutterPaintContext *paint_context); -G_BEGIN_DECLS +G_END_DECLS #endif /* __META_TEXTURE_TOWER_H__ */ diff --git a/src/compositor/meta-window-actor-private.h b/src/compositor/meta-window-actor-private.h index c206f860c..31cc37702 100644 --- a/src/compositor/meta-window-actor-private.h +++ b/src/compositor/meta-window-actor-private.h @@ -3,72 +3,92 @@ #ifndef META_WINDOW_ACTOR_PRIVATE_H #define META_WINDOW_ACTOR_PRIVATE_H -#include <config.h> - #include <X11/extensions/Xdamage.h> -#include <meta/compositor-muffin.h> -#include <clutter/clutter-muffin.h> -MetaWindowActor *meta_window_actor_new (MetaWindow *window); +#include "compositor/meta-plugin-manager.h" +#include "compositor/meta-surface-actor.h" +#include "meta/compositor-mutter.h" + +struct _MetaWindowActorClass +{ + ClutterActorClass parent; + + void (*frame_complete) (MetaWindowActor *actor, + ClutterFrameInfo *frame_info, + int64_t presentation_time); + + void (*assign_surface_actor) (MetaWindowActor *actor, + MetaSurfaceActor *surface_actor); + + void (*queue_frame_drawn) (MetaWindowActor *actor, + gboolean skip_sync_delay); -void meta_window_actor_destroy (MetaWindowActor *self); + void (*pre_paint) (MetaWindowActor *actor); + void (*post_paint) (MetaWindowActor *actor); + void (*queue_destroy) (MetaWindowActor *actor); + void (*set_frozen) (MetaWindowActor *actor, + gboolean frozen); + void (*update_regions) (MetaWindowActor *actor); +}; + +typedef enum +{ + META_WINDOW_ACTOR_CHANGE_SIZE = 1 << 0, + META_WINDOW_ACTOR_CHANGE_POSITION = 1 << 1 +} MetaWindowActorChanges; + +void meta_window_actor_queue_destroy (MetaWindowActor *self); void meta_window_actor_show (MetaWindowActor *self, MetaCompEffect effect); void meta_window_actor_hide (MetaWindowActor *self, MetaCompEffect effect); -void meta_window_actor_maximize (MetaWindowActor *self, - MetaRectangle *old_rect, - MetaRectangle *new_rect); -void meta_window_actor_unmaximize (MetaWindowActor *self, - MetaRectangle *old_rect, - MetaRectangle *new_rect); - -void meta_window_actor_tile (MetaWindowActor *self, - MetaRectangle *old_rect, - MetaRectangle *new_rect); - -void meta_window_actor_process_damage (MetaWindowActor *self, - XDamageNotifyEvent *event); +void meta_window_actor_size_change (MetaWindowActor *self, + MetaSizeChange which_change, + MetaRectangle *old_frame_rect, + MetaRectangle *old_buffer_rect); void meta_window_actor_pre_paint (MetaWindowActor *self); void meta_window_actor_post_paint (MetaWindowActor *self); +void meta_window_actor_frame_complete (MetaWindowActor *self, + ClutterFrameInfo *frame_info, + gint64 presentation_time); -void meta_window_actor_invalidate_shadow (MetaWindowActor *self); - -void meta_window_actor_set_redirected (MetaWindowActor *self, gboolean state); - -gboolean meta_window_actor_should_unredirect (MetaWindowActor *self); +gboolean meta_window_actor_effect_in_progress (MetaWindowActor *self); -void meta_window_actor_get_shape_bounds (MetaWindowActor *self, - cairo_rectangle_int_t *bounds); +MetaWindowActorChanges meta_window_actor_sync_actor_geometry (MetaWindowActor *self, + gboolean did_placement); -gboolean meta_window_actor_effect_in_progress (MetaWindowActor *self); -void meta_window_actor_sync_actor_geometry (MetaWindowActor *self, - gboolean did_placement); -void meta_window_actor_sync_visibility (MetaWindowActor *self); -void meta_window_actor_update_shape (MetaWindowActor *self); void meta_window_actor_update_opacity (MetaWindowActor *self); void meta_window_actor_mapped (MetaWindowActor *self); void meta_window_actor_unmapped (MetaWindowActor *self); -void meta_window_actor_set_updates_frozen (MetaWindowActor *self, - gboolean updates_frozen); +void meta_window_actor_sync_updates_frozen (MetaWindowActor *self); void meta_window_actor_queue_frame_drawn (MetaWindowActor *self, gboolean no_delay_frame); -cairo_region_t *meta_window_actor_get_obscured_region (MetaWindowActor *self); +void meta_window_actor_effect_completed (MetaWindowActor *actor, + MetaPluginEffect event); + +MetaSurfaceActor *meta_window_actor_get_surface (MetaWindowActor *self); + +void meta_window_actor_assign_surface_actor (MetaWindowActor *self, + MetaSurfaceActor *surface_actor); + +MetaWindowActor *meta_window_actor_from_window (MetaWindow *window); +MetaWindowActor *meta_window_actor_from_actor (ClutterActor *actor); + +void meta_window_actor_set_geometry_scale (MetaWindowActor *window_actor, + int geometry_scale); + +int meta_window_actor_get_geometry_scale (MetaWindowActor *window_actor); + +void meta_window_actor_notify_damaged (MetaWindowActor *window_actor); -void meta_window_actor_set_visible_region (MetaWindowActor *self, - cairo_region_t *visible_region); -void meta_window_actor_set_visible_region_beneath (MetaWindowActor *self, - cairo_region_t *beneath_region); -void meta_window_actor_reset_visible_regions (MetaWindowActor *self); +gboolean meta_window_actor_is_frozen (MetaWindowActor *self); -void meta_window_actor_set_unobscured_region (MetaWindowActor *self, - cairo_region_t *unobscured_region); +gboolean meta_window_actor_is_opaque (MetaWindowActor *self); -void meta_window_actor_effect_completed (MetaWindowActor *actor, - gulong event); +void meta_window_actor_update_regions (MetaWindowActor *self); #endif /* META_WINDOW_ACTOR_PRIVATE_H */ diff --git a/src/compositor/meta-window-actor-wayland.c b/src/compositor/meta-window-actor-wayland.c new file mode 100644 index 000000000..98f26fc6c --- /dev/null +++ b/src/compositor/meta-window-actor-wayland.c @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2018 Endless, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Georges Basile Stavracas Neto <gbsneto@gnome.org> + */ + +#include "compositor/meta-surface-actor-wayland.h" +#include "compositor/meta-window-actor-wayland.h" +#include "meta/meta-window-actor.h" +#include "wayland/meta-wayland-surface.h" + +struct _MetaWindowActorWayland +{ + MetaWindowActor parent; +}; + +G_DEFINE_TYPE (MetaWindowActorWayland, meta_window_actor_wayland, META_TYPE_WINDOW_ACTOR) + +static gboolean +remove_surface_actor_from_children (GNode *node, + gpointer data) +{ + MetaWaylandSurface *surface = node->data; + MetaSurfaceActor *surface_actor = meta_wayland_surface_get_actor (surface); + MetaWindowActor *window_actor = data; + ClutterActor *parent; + + parent = clutter_actor_get_parent (CLUTTER_ACTOR (surface_actor)); + if (!parent) + return FALSE; + + g_return_val_if_fail (parent == CLUTTER_ACTOR (window_actor), FALSE); + + clutter_actor_remove_child (CLUTTER_ACTOR (window_actor), + CLUTTER_ACTOR (surface_actor)); + + return FALSE; +} + +static gboolean +add_surface_actor_to_children (GNode *node, + gpointer data) +{ + MetaWaylandSurface *surface = node->data; + MetaSurfaceActor *surface_actor = meta_wayland_surface_get_actor (surface); + MetaWindowActor *window_actor = data; + + clutter_actor_add_child (CLUTTER_ACTOR (window_actor), + CLUTTER_ACTOR (surface_actor)); + + return FALSE; +} + +void +meta_window_actor_wayland_rebuild_surface_tree (MetaWindowActor *actor) +{ + MetaSurfaceActor *surface_actor = + meta_window_actor_get_surface (actor); + MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface ( + META_SURFACE_ACTOR_WAYLAND (surface_actor)); + GNode *root_node = surface->subsurface_branch_node; + + g_node_traverse (root_node, + G_IN_ORDER, + G_TRAVERSE_LEAVES, + -1, + remove_surface_actor_from_children, + actor); + + g_node_traverse (root_node, + G_IN_ORDER, + G_TRAVERSE_LEAVES, + -1, + add_surface_actor_to_children, + actor); +} + +static void +meta_window_actor_wayland_assign_surface_actor (MetaWindowActor *actor, + MetaSurfaceActor *surface_actor) +{ + MetaWindowActorClass *parent_class = + META_WINDOW_ACTOR_CLASS (meta_window_actor_wayland_parent_class); + + g_warn_if_fail (!meta_window_actor_get_surface (actor)); + + parent_class->assign_surface_actor (actor, surface_actor); + + meta_window_actor_wayland_rebuild_surface_tree (actor); +} + +static void +meta_window_actor_wayland_frame_complete (MetaWindowActor *actor, + ClutterFrameInfo *frame_info, + int64_t presentation_time) +{ +} + +static void +meta_window_actor_wayland_queue_frame_drawn (MetaWindowActor *actor, + gboolean skip_sync_delay) +{ +} + +static void +meta_window_actor_wayland_pre_paint (MetaWindowActor *actor) +{ +} + +static void +meta_window_actor_wayland_post_paint (MetaWindowActor *actor) +{ +} + +static void +meta_window_actor_wayland_queue_destroy (MetaWindowActor *actor) +{ +} + +static void +meta_window_actor_wayland_set_frozen (MetaWindowActor *actor, + gboolean frozen) +{ +} + +static void +meta_window_actor_wayland_update_regions (MetaWindowActor *actor) +{ +} + +static void +meta_window_actor_wayland_class_init (MetaWindowActorWaylandClass *klass) +{ + MetaWindowActorClass *window_actor_class = META_WINDOW_ACTOR_CLASS (klass); + + window_actor_class->assign_surface_actor = meta_window_actor_wayland_assign_surface_actor; + window_actor_class->frame_complete = meta_window_actor_wayland_frame_complete; + window_actor_class->queue_frame_drawn = meta_window_actor_wayland_queue_frame_drawn; + window_actor_class->pre_paint = meta_window_actor_wayland_pre_paint; + window_actor_class->post_paint = meta_window_actor_wayland_post_paint; + window_actor_class->queue_destroy = meta_window_actor_wayland_queue_destroy; + window_actor_class->set_frozen = meta_window_actor_wayland_set_frozen; + window_actor_class->update_regions = meta_window_actor_wayland_update_regions; +} + +static void +meta_window_actor_wayland_init (MetaWindowActorWayland *self) +{ +} diff --git a/src/compositor/meta-window-actor-wayland.h b/src/compositor/meta-window-actor-wayland.h new file mode 100644 index 000000000..d94de8106 --- /dev/null +++ b/src/compositor/meta-window-actor-wayland.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2018 Endless, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Georges Basile Stavracas Neto <gbsneto@gnome.org> + */ + +#ifndef META_WINDOW_ACTOR_WAYLAND_H +#define META_WINDOW_ACTOR_WAYLAND_H + +#include "compositor/meta-window-actor-private.h" +#include "wayland/meta-wayland-surface.h" + +#define META_TYPE_WINDOW_ACTOR_WAYLAND (meta_window_actor_wayland_get_type()) +G_DECLARE_FINAL_TYPE (MetaWindowActorWayland, + meta_window_actor_wayland, + META, WINDOW_ACTOR_WAYLAND, + MetaWindowActor) + +void meta_window_actor_wayland_rebuild_surface_tree (MetaWindowActor *actor); + +#endif /*META_WINDOW_ACTOR_WAYLAND_H */ diff --git a/src/compositor/meta-window-actor-x11.c b/src/compositor/meta-window-actor-x11.c new file mode 100644 index 000000000..1974f6f27 --- /dev/null +++ b/src/compositor/meta-window-actor-x11.c @@ -0,0 +1,1645 @@ +/* + * Copyright (C) 2018 Endless, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Georges Basile Stavracas Neto <gbsneto@gnome.org> + */ + +#include "config.h" + +#include "compositor/meta-window-actor-x11.h" + +#include "backends/meta-logical-monitor.h" +#include "compositor/compositor-private.h" +#include "compositor/meta-cullable.h" +#include "compositor/meta-shaped-texture-private.h" +#include "compositor/meta-surface-actor.h" +#include "compositor/meta-surface-actor-x11.h" +#include "compositor/region-utils.h" +#include "core/frame.h" +#include "core/window-private.h" +#include "meta/compositor.h" +#include "meta/meta-enum-types.h" +#include "meta/meta-shadow-factory.h" +#include "meta/meta-window-actor.h" +#include "meta/meta-x11-errors.h" +#include "meta/window.h" +#include "x11/meta-x11-display-private.h" +#include "x11/window-x11.h" + +enum +{ + PROP_SHADOW_MODE = 1, + PROP_SHADOW_CLASS +}; + +struct _MetaWindowActorX11 +{ + MetaWindowActor parent; + + /* List of FrameData for recent frames */ + GList *frames; + + guint send_frame_messages_timer; + int64_t frame_drawn_time; + + gulong repaint_scheduled_id; + gulong size_changed_id; + + /* If set, the client needs to be sent a _NET_WM_FRAME_DRAWN + * client message for one or more messages in ->frames */ + gboolean needs_frame_drawn; + gboolean repaint_scheduled; + + /* + * MetaShadowFactory only caches shadows that are actually in use; + * to avoid unnecessary recomputation we do two things: 1) we store + * both a focused and unfocused shadow for the window. If the window + * doesn't have different focused and unfocused shadow parameters, + * these will be the same. 2) when the shadow potentially changes we + * don't immediately unreference the old shadow, we just flag it as + * dirty and recompute it when we next need it (recompute_focused_shadow, + * recompute_unfocused_shadow.) Because of our extraction of + * size-invariant window shape, we'll often find that the new shadow + * is the same as the old shadow. + */ + MetaShadow *focused_shadow; + MetaShadow *unfocused_shadow; + + /* A region that matches the shape of the window, including frame bounds */ + cairo_region_t *shape_region; + /* The region we should clip to when painting the shadow */ + cairo_region_t *shadow_clip; + /* The frame region */ + cairo_region_t *frame_bounds; + + /* Extracted size-invariant shape used for shadows */ + MetaWindowShape *shadow_shape; + char *shadow_class; + + MetaShadowFactory *shadow_factory; + gulong shadow_factory_changed_handler_id; + + MetaShadowMode shadow_mode; + + gboolean needs_reshape; + gboolean recompute_focused_shadow; + gboolean recompute_unfocused_shadow; + gboolean is_frozen; +}; + +static MetaCullableInterface *cullable_parent_iface; + +static void cullable_iface_init (MetaCullableInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (MetaWindowActorX11, meta_window_actor_x11, META_TYPE_WINDOW_ACTOR, + G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init)) + +/* Each time the application updates the sync request counter to a new even value + * value, we queue a frame into the windows list of frames. Once we're painting + * an update "in response" to the window, we fill in frame_counter with the + * Cogl counter for that frame, and send _NET_WM_FRAME_DRAWN at the end of the + * frame. _NET_WM_FRAME_TIMINGS is sent when we get a frame_complete callback. + * + * As an exception, if a window is completely obscured, we try to throttle drawning + * to a slower frame rate. In this case, frame_counter stays -1 until + * send_frame_message_timeout() runs, at which point we send both the + * _NET_WM_FRAME_DRAWN and _NET_WM_FRAME_TIMINGS messages. + */ +typedef struct +{ + uint64_t sync_request_serial; + int64_t frame_counter; + int64_t frame_drawn_time; +} FrameData; + +static void +frame_data_free (FrameData *frame) +{ + g_slice_free (FrameData, frame); +} + +static void +surface_repaint_scheduled (MetaSurfaceActor *actor, + gpointer user_data) +{ + MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (user_data); + + actor_x11->repaint_scheduled = TRUE; +} + +static void +remove_frame_messages_timer (MetaWindowActorX11 *actor_x11) +{ + g_assert (actor_x11->send_frame_messages_timer != 0); + + g_clear_handle_id (&actor_x11->send_frame_messages_timer, g_source_remove); +} + +static void +do_send_frame_drawn (MetaWindowActorX11 *actor_x11, + FrameData *frame) +{ + MetaWindow *window = + meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11)); + MetaDisplay *display = meta_window_get_display (window); + Display *xdisplay = meta_x11_display_get_xdisplay (display->x11_display); + int64_t now_us; + + XClientMessageEvent ev = { 0, }; + + now_us = g_get_monotonic_time (); + frame->frame_drawn_time = + meta_compositor_monotonic_to_high_res_xserver_time (display->compositor, + now_us); + actor_x11->frame_drawn_time = frame->frame_drawn_time; + + ev.type = ClientMessage; + ev.window = meta_window_get_xwindow (window); + ev.message_type = display->x11_display->atom__NET_WM_FRAME_DRAWN; + ev.format = 32; + ev.data.l[0] = frame->sync_request_serial & G_GUINT64_CONSTANT (0xffffffff); + ev.data.l[1] = frame->sync_request_serial >> 32; + ev.data.l[2] = frame->frame_drawn_time & G_GUINT64_CONSTANT (0xffffffff); + ev.data.l[3] = frame->frame_drawn_time >> 32; + + meta_x11_error_trap_push (display->x11_display); + XSendEvent (xdisplay, ev.window, False, 0, (XEvent *) &ev); + XFlush (xdisplay); + meta_x11_error_trap_pop (display->x11_display); +} + +static void +do_send_frame_timings (MetaWindowActorX11 *actor_x11, + FrameData *frame, + int refresh_interval, + int64_t presentation_time) +{ + MetaWindow *window = + meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11)); + MetaDisplay *display = meta_window_get_display (window); + Display *xdisplay = meta_x11_display_get_xdisplay (display->x11_display); + + XClientMessageEvent ev = { 0, }; + + ev.type = ClientMessage; + ev.window = meta_window_get_xwindow (window); + ev.message_type = display->x11_display->atom__NET_WM_FRAME_TIMINGS; + ev.format = 32; + ev.data.l[0] = frame->sync_request_serial & G_GUINT64_CONSTANT (0xffffffff); + ev.data.l[1] = frame->sync_request_serial >> 32; + + if (presentation_time != 0) + { + MetaCompositor *compositor = display->compositor; + int64_t presentation_time_server; + + presentation_time_server = + meta_compositor_monotonic_to_high_res_xserver_time (compositor, + presentation_time); + int64_t presentation_time_offset = presentation_time_server - frame->frame_drawn_time; + if (presentation_time_offset == 0) + presentation_time_offset = 1; + + if ((int32_t)presentation_time_offset == presentation_time_offset) + ev.data.l[2] = presentation_time_offset; + } + + ev.data.l[3] = refresh_interval; + ev.data.l[4] = 1000 * META_SYNC_DELAY; + + meta_x11_error_trap_push (display->x11_display); + XSendEvent (xdisplay, ev.window, False, 0, (XEvent *) &ev); + XFlush (xdisplay); + meta_x11_error_trap_pop (display->x11_display); +} + +static void +send_frame_timings (MetaWindowActorX11 *actor_x11, + FrameData *frame, + ClutterFrameInfo *frame_info, + int64_t presentation_time) +{ + float refresh_rate; + int refresh_interval; + + refresh_rate = frame_info->refresh_rate; + /* 0.0 is a flag for not known, but sanity-check against other odd numbers */ + if (refresh_rate >= 1.0) + refresh_interval = (int) (0.5 + 1000000 / refresh_rate); + else + refresh_interval = 0; + + do_send_frame_timings (actor_x11, frame, refresh_interval, presentation_time); +} + +static gboolean +send_frame_messages_timeout (gpointer data) +{ + MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (data); + GList *l; + + for (l = actor_x11->frames; l;) + { + GList *l_next = l->next; + FrameData *frame = l->data; + + if (frame->frame_counter == -1) + { + do_send_frame_drawn (actor_x11, frame); + do_send_frame_timings (actor_x11, frame, 0, 0); + + actor_x11->frames = g_list_delete_link (actor_x11->frames, l); + frame_data_free (frame); + } + + l = l_next; + } + + actor_x11->needs_frame_drawn = FALSE; + actor_x11->send_frame_messages_timer = 0; + + return G_SOURCE_REMOVE; +} + +static void +queue_send_frame_messages_timeout (MetaWindowActorX11 *actor_x11) +{ + MetaWindow *window = + meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11)); + MetaDisplay *display = meta_window_get_display (window); + MetaLogicalMonitor *logical_monitor; + int64_t now_us; + int64_t current_time; + float refresh_rate; + int interval, offset; + + if (actor_x11->send_frame_messages_timer != 0) + return; + + logical_monitor = meta_window_get_main_logical_monitor (window); + if (logical_monitor) + { + GList *monitors = meta_logical_monitor_get_monitors (logical_monitor); + MetaMonitor *monitor; + MetaMonitorMode *mode; + + monitor = g_list_first (monitors)->data; + mode = meta_monitor_get_current_mode (monitor); + + refresh_rate = meta_monitor_mode_get_refresh_rate (mode); + } + else + { + refresh_rate = 60.0f; + } + + now_us = g_get_monotonic_time (); + current_time = + meta_compositor_monotonic_to_high_res_xserver_time (display->compositor, + now_us); + interval = (int) (1000000 / refresh_rate) * 6; + offset = MAX (0, actor_x11->frame_drawn_time + interval - current_time) / 1000; + + /* The clutter master clock source has already been added with META_PRIORITY_REDRAW, + * so the timer will run *after* the clutter frame handling, if a frame is ready + * to be drawn when the timer expires. + */ + actor_x11->send_frame_messages_timer = + g_timeout_add_full (META_PRIORITY_REDRAW, offset, + send_frame_messages_timeout, + actor_x11, NULL); + g_source_set_name_by_id (actor_x11->send_frame_messages_timer, + "[mutter] send_frame_messages_timeout"); +} + +static void +assign_frame_counter_to_frames (MetaWindowActorX11 *actor_x11) +{ + MetaWindow *window = + meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11)); + MetaCompositor *compositor = window->display->compositor; + ClutterStage *stage = meta_compositor_get_stage (compositor); + GList *l; + + /* If the window is obscured, then we're expecting to deal with sending + * frame messages in a timeout, rather than in this paint cycle. + */ + if (actor_x11->send_frame_messages_timer != 0) + return; + + for (l = actor_x11->frames; l; l = l->next) + { + FrameData *frame = l->data; + + if (frame->frame_counter == -1) + frame->frame_counter = clutter_stage_get_frame_counter (stage); + } +} + +static void +meta_window_actor_x11_frame_complete (MetaWindowActor *actor, + ClutterFrameInfo *frame_info, + int64_t presentation_time) +{ + MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (actor); + GList *l; + + if (meta_window_actor_is_destroyed (actor)) + return; + + for (l = actor_x11->frames; l;) + { + GList *l_next = l->next; + FrameData *frame = l->data; + int64_t frame_counter = frame_info->frame_counter; + + if (frame->frame_counter != -1 && frame->frame_counter <= frame_counter) + { + MetaWindow *window = + meta_window_actor_get_meta_window (actor); + + if (G_UNLIKELY (frame->frame_drawn_time == 0)) + g_warning ("%s: Frame has assigned frame counter but no frame drawn time", + window->desc); + if (G_UNLIKELY (frame->frame_counter < frame_counter)) + g_warning ("%s: frame_complete callback never occurred for frame %" G_GINT64_FORMAT, + window->desc, frame->frame_counter); + + actor_x11->frames = g_list_delete_link (actor_x11->frames, l); + send_frame_timings (actor_x11, frame, frame_info, presentation_time); + frame_data_free (frame); + } + + l = l_next; + } +} + +static void +surface_size_changed (MetaSurfaceActor *actor, + gpointer user_data) +{ + MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (user_data); + + meta_window_actor_x11_update_shape (actor_x11); +} + +static void +meta_window_actor_x11_assign_surface_actor (MetaWindowActor *actor, + MetaSurfaceActor *surface_actor) +{ + MetaWindowActorClass *parent_class = + META_WINDOW_ACTOR_CLASS (meta_window_actor_x11_parent_class); + MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (actor); + MetaSurfaceActor *prev_surface_actor; + + prev_surface_actor = meta_window_actor_get_surface (actor); + if (prev_surface_actor) + { + g_warn_if_fail (meta_is_wayland_compositor ()); + + g_clear_signal_handler (&actor_x11->size_changed_id, prev_surface_actor); + clutter_actor_remove_child (CLUTTER_ACTOR (actor), + CLUTTER_ACTOR (prev_surface_actor)); + } + + parent_class->assign_surface_actor (actor, surface_actor); + + clutter_actor_add_child (CLUTTER_ACTOR (actor), + CLUTTER_ACTOR (surface_actor)); + + meta_window_actor_x11_update_shape (actor_x11); + + actor_x11->size_changed_id = + g_signal_connect (surface_actor, "size-changed", + G_CALLBACK (surface_size_changed), + actor_x11); + actor_x11->repaint_scheduled_id = + g_signal_connect (surface_actor, "repaint-scheduled", + G_CALLBACK (surface_repaint_scheduled), + actor_x11); +} + +static void +meta_window_actor_x11_queue_frame_drawn (MetaWindowActor *actor, + gboolean skip_sync_delay) +{ + MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (actor); + MetaWindow *window = + meta_window_actor_get_meta_window (actor); + FrameData *frame; + + if (meta_window_actor_is_destroyed (actor)) + return; + + frame = g_slice_new0 (FrameData); + frame->frame_counter = -1; + frame->sync_request_serial = window->sync_request_serial; + + actor_x11->frames = g_list_prepend (actor_x11->frames, frame); + + actor_x11->needs_frame_drawn = TRUE; + + if (skip_sync_delay) + { + ClutterActor *stage = clutter_actor_get_stage (CLUTTER_ACTOR (actor_x11)); + clutter_stage_skip_sync_delay (CLUTTER_STAGE (stage)); + } + + if (!actor_x11->repaint_scheduled) + { + MetaSurfaceActor *surface; + gboolean is_obscured; + + surface = meta_window_actor_get_surface (META_WINDOW_ACTOR (actor_x11)); + + if (surface) + is_obscured = meta_surface_actor_is_obscured (surface); + else + is_obscured = FALSE; + + /* A frame was marked by the client without actually doing any + * damage or any unobscured, or while we had the window frozen + * (e.g. during an interactive resize.) We need to make sure that the + * pre_paint/post_paint functions get called, enabling us to + * send a _NET_WM_FRAME_DRAWN. We do a 1-pixel redraw to get + * consistent timing with non-empty frames. If the window + * is completely obscured we fire off the send_frame_messages timeout. + */ + if (is_obscured) + { + queue_send_frame_messages_timeout (actor_x11); + } + else if (surface) + { + const cairo_rectangle_int_t clip = { 0, 0, 1, 1 }; + clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (surface), &clip); + actor_x11->repaint_scheduled = TRUE; + } + } +} + +static gboolean +has_shadow (MetaWindowActorX11 *actor_x11) +{ + MetaWindow *window = + meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11)); + + if (actor_x11->shadow_mode == META_SHADOW_MODE_FORCED_OFF) + return FALSE; + if (actor_x11->shadow_mode == META_SHADOW_MODE_FORCED_ON) + return TRUE; + + /* Leaving out shadows for maximized and fullscreen windows is an effeciency + * win and also prevents the unsightly effect of the shadow of maximized + * window appearing on an adjacent window */ + if ((meta_window_get_maximized (window) == META_MAXIMIZE_BOTH) || + meta_window_is_fullscreen (window)) + return FALSE; + + /* + * If we have two snap-tiled windows, we don't want the shadow to obstruct + * the other window. + */ + if (meta_window_get_tile_match (window)) + return FALSE; + + /* + * Always put a shadow around windows with a frame - This should override + * the restriction about not putting a shadow around ARGB windows. + */ + if (meta_window_get_frame (window)) + return TRUE; + + /* + * Do not add shadows to non-opaque (ARGB32) windows, as we can't easily + * generate shadows for them. + */ + if (!meta_window_actor_is_opaque (META_WINDOW_ACTOR (actor_x11))) + return FALSE; + + /* + * If a window specifies that it has custom frame extents, that likely + * means that it is drawing a shadow itself. Don't draw our own. + */ + if (window->has_custom_frame_extents) + return FALSE; + + /* + * Generate shadows for all other windows. + */ + return TRUE; +} + +gboolean +meta_window_actor_x11_should_unredirect (MetaWindowActorX11 *actor_x11) +{ + MetaSurfaceActor *surface; + MetaSurfaceActorX11 *surface_x11; + + if (meta_window_actor_is_destroyed (META_WINDOW_ACTOR (actor_x11))) + return FALSE; + + surface = meta_window_actor_get_surface (META_WINDOW_ACTOR (actor_x11)); + if (!surface) + return FALSE; + + if (!META_IS_SURFACE_ACTOR_X11 (surface)) + return FALSE; + + surface_x11 = META_SURFACE_ACTOR_X11 (surface); + return meta_surface_actor_x11_should_unredirect (surface_x11); +} + +void +meta_window_actor_x11_set_unredirected (MetaWindowActorX11 *actor_x11, + gboolean unredirected) +{ + MetaSurfaceActor *surface; + MetaSurfaceActorX11 *surface_x11; + + surface = meta_window_actor_get_surface (META_WINDOW_ACTOR (actor_x11)); + g_assert (surface); + + g_return_if_fail (META_IS_SURFACE_ACTOR_X11 (surface)); + + surface_x11 = META_SURFACE_ACTOR_X11 (surface); + meta_surface_actor_x11_set_unredirected (surface_x11, unredirected); +} + +static const char * +get_shadow_class (MetaWindowActorX11 *actor_x11) +{ + if (actor_x11->shadow_class) + { + return actor_x11->shadow_class; + } + else + { + MetaWindow *window = + meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11)); + MetaWindowType window_type; + + window_type = meta_window_get_window_type (window); + switch (window_type) + { + case META_WINDOW_DROPDOWN_MENU: + case META_WINDOW_COMBO: + return "dropdown-menu"; + case META_WINDOW_POPUP_MENU: + return "popup-menu"; + default: + { + MetaFrameType frame_type; + + frame_type = meta_window_get_frame_type (window); + return meta_frame_type_to_string (frame_type); + } + } + } +} + +static void +get_shadow_params (MetaWindowActorX11 *actor_x11, + gboolean appears_focused, + MetaShadowParams *params) +{ + const char *shadow_class = get_shadow_class (actor_x11); + + meta_shadow_factory_get_params (actor_x11->shadow_factory, + shadow_class, appears_focused, + params); +} + +static void +get_shape_bounds (MetaWindowActorX11 *actor_x11, + cairo_rectangle_int_t *bounds) +{ + cairo_region_get_extents (actor_x11->shape_region, bounds); +} + +static void +get_shadow_bounds (MetaWindowActorX11 *actor_x11, + gboolean appears_focused, + cairo_rectangle_int_t *bounds) +{ + MetaShadow *shadow; + cairo_rectangle_int_t shape_bounds; + MetaShadowParams params; + + shadow = appears_focused ? actor_x11->focused_shadow + : actor_x11->unfocused_shadow; + + get_shape_bounds (actor_x11, &shape_bounds); + get_shadow_params (actor_x11, appears_focused, ¶ms); + + meta_shadow_get_bounds (shadow, + params.x_offset + shape_bounds.x, + params.y_offset + shape_bounds.y, + shape_bounds.width, + shape_bounds.height, + bounds); +} + +/* If we have an ARGB32 window that we decorate with a frame, it's + * probably something like a translucent terminal - something where + * the alpha channel represents transparency rather than a shape. We + * don't want to show the shadow through the translucent areas since + * the shadow is wrong for translucent windows (it should be + * translucent itself and colored), and not only that, will /look/ + * horribly wrong - a misplaced big black blob. As a hack, what we + * want to do is just draw the shadow as normal outside the frame, and + * inside the frame draw no shadow. This is also not even close to + * the right result, but looks OK. We also apply this approach to + * windows set to be partially translucent with _NET_WM_WINDOW_OPACITY. + */ +static gboolean +clip_shadow_under_window (MetaWindowActorX11 *actor_x11) +{ + MetaWindow *window = + meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11)); + + if (window->frame) + return TRUE; + + return meta_window_actor_is_opaque (META_WINDOW_ACTOR (actor_x11)); +} + +/** + * set_clip_region_beneath: + * @actor_x11: a #MetaWindowActorX11 + * @clip_region: the region of the screen that isn't completely + * obscured beneath the main window texture. + * + * Provides a hint as to what areas need to be drawn *beneath* + * the main window texture. This is the relevant clip region + * when drawing the shadow, properly accounting for areas of the + * shadow hid by the window itself. This will be set before painting + * then unset afterwards. + */ +static void +set_clip_region_beneath (MetaWindowActorX11 *actor_x11, + cairo_region_t *beneath_region) +{ + MetaWindow *window; + gboolean appears_focused; + + window = meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11)); + appears_focused = meta_window_appears_focused (window); + if (appears_focused ? actor_x11->focused_shadow : actor_x11->unfocused_shadow) + { + g_clear_pointer (&actor_x11->shadow_clip, cairo_region_destroy); + + if (beneath_region) + { + actor_x11->shadow_clip = cairo_region_copy (beneath_region); + + if (clip_shadow_under_window (actor_x11)) + { + if (actor_x11->frame_bounds) + cairo_region_subtract (actor_x11->shadow_clip, actor_x11->frame_bounds); + } + } + else + { + actor_x11->shadow_clip = NULL; + } + } +} + +static void +check_needs_shadow (MetaWindowActorX11 *actor_x11) +{ + MetaWindow *window = + meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11)); + MetaShadow *old_shadow = NULL; + MetaShadow **shadow_location; + gboolean recompute_shadow; + gboolean should_have_shadow; + gboolean appears_focused; + + /* Calling has_shadow() here at every pre-paint is cheap + * and avoids the need to explicitly handle window type changes, which + * we would do if tried to keep track of when we might be adding or removing + * a shadow more explicitly. We only keep track of changes to the *shape* of + * the shadow with actor_x11->recompute_shadow. + */ + + should_have_shadow = has_shadow (actor_x11); + appears_focused = meta_window_appears_focused (window); + + if (appears_focused) + { + recompute_shadow = actor_x11->recompute_focused_shadow; + actor_x11->recompute_focused_shadow = FALSE; + shadow_location = &actor_x11->focused_shadow; + } + else + { + recompute_shadow = actor_x11->recompute_unfocused_shadow; + actor_x11->recompute_unfocused_shadow = FALSE; + shadow_location = &actor_x11->unfocused_shadow; + } + + if (!should_have_shadow || recompute_shadow) + { + if (*shadow_location != NULL) + { + old_shadow = *shadow_location; + *shadow_location = NULL; + } + } + + if (!*shadow_location && should_have_shadow) + { + MetaShadowFactory *factory = actor_x11->shadow_factory; + const char *shadow_class = get_shadow_class (actor_x11); + cairo_rectangle_int_t shape_bounds; + + if (!actor_x11->shadow_shape) + { + actor_x11->shadow_shape = + meta_window_shape_new (actor_x11->shape_region); + } + + get_shape_bounds (actor_x11, &shape_bounds); + *shadow_location = + meta_shadow_factory_get_shadow (factory, + actor_x11->shadow_shape, + shape_bounds.width, shape_bounds.height, + shadow_class, appears_focused); + } + + if (old_shadow) + meta_shadow_unref (old_shadow); +} + +void +meta_window_actor_x11_process_damage (MetaWindowActorX11 *actor_x11, + XDamageNotifyEvent *event) +{ + MetaSurfaceActor *surface; + + surface = meta_window_actor_get_surface (META_WINDOW_ACTOR (actor_x11)); + if (surface) + meta_surface_actor_process_damage (surface, + event->area.x, + event->area.y, + event->area.width, + event->area.height); + + meta_window_actor_notify_damaged (META_WINDOW_ACTOR (actor_x11)); +} + +static cairo_region_t * +scan_visible_region (guchar *mask_data, + int stride, + cairo_region_t *scan_area) +{ + int i, n_rects = cairo_region_num_rectangles (scan_area); + MetaRegionBuilder builder; + + meta_region_builder_init (&builder); + + for (i = 0; i < n_rects; i++) + { + int x, y; + cairo_rectangle_int_t rect; + + cairo_region_get_rectangle (scan_area, i, &rect); + + for (y = rect.y; y < (rect.y + rect.height); y++) + { + for (x = rect.x; x < (rect.x + rect.width); x++) + { + int x2 = x; + while (mask_data[y * stride + x2] == 255 && x2 < (rect.x + rect.width)) + x2++; + + if (x2 > x) + { + meta_region_builder_add_rectangle (&builder, x, y, x2 - x, 1); + x = x2; + } + } + } + } + + return meta_region_builder_finish (&builder); +} + +static void +get_client_area_rect_from_texture (MetaWindowActorX11 *actor_x11, + MetaShapedTexture *shaped_texture, + cairo_rectangle_int_t *client_area) +{ + MetaWindow *window = + meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11)); + cairo_rectangle_int_t surface_rect = { 0 }; + + surface_rect.width = meta_shaped_texture_get_width (shaped_texture); + surface_rect.height = meta_shaped_texture_get_height (shaped_texture); + meta_window_x11_surface_rect_to_client_rect (window, + &surface_rect, + client_area); +} + +static void +get_client_area_rect (MetaWindowActorX11 *actor_x11, + cairo_rectangle_int_t *client_area) +{ + MetaSurfaceActor *surface = + meta_window_actor_get_surface (META_WINDOW_ACTOR (actor_x11)); + MetaWindow *window = + meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11)); + MetaShapedTexture *stex = meta_surface_actor_get_texture (surface); + + if (!meta_window_x11_always_update_shape (window) || !stex) + { + meta_window_get_client_area_rect (window, client_area); + return; + } + + get_client_area_rect_from_texture (actor_x11, stex, client_area); +} + +static void +build_and_scan_frame_mask (MetaWindowActorX11 *actor_x11, + cairo_region_t *shape_region) +{ + ClutterBackend *backend = clutter_get_default_backend (); + MetaWindow *window = + meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11)); + CoglContext *ctx = clutter_backend_get_cogl_context (backend); + MetaSurfaceActor *surface = + meta_window_actor_get_surface (META_WINDOW_ACTOR (actor_x11)); + uint8_t *mask_data; + unsigned int tex_width, tex_height; + MetaShapedTexture *stex; + CoglTexture2D *mask_texture; + int stride; + cairo_t *cr; + cairo_surface_t *image; + GError *error = NULL; + + stex = meta_surface_actor_get_texture (surface); + g_return_if_fail (stex); + + meta_shaped_texture_set_mask_texture (stex, NULL); + + tex_width = meta_shaped_texture_get_width (stex); + tex_height = meta_shaped_texture_get_height (stex); + + stride = cairo_format_stride_for_width (CAIRO_FORMAT_A8, tex_width); + + /* Create data for an empty image */ + mask_data = g_malloc0 (stride * tex_height); + + image = cairo_image_surface_create_for_data (mask_data, + CAIRO_FORMAT_A8, + tex_width, + tex_height, + stride); + cr = cairo_create (image); + + gdk_cairo_region (cr, shape_region); + cairo_fill (cr); + + if (window->frame) + { + cairo_region_t *frame_paint_region, *scanned_region; + cairo_rectangle_int_t rect = { 0, 0, tex_width, tex_height }; + cairo_rectangle_int_t client_area; + cairo_rectangle_int_t frame_rect; + + /* If we update the shape regardless of the frozen state of the actor, + * as with Xwayland to avoid the black shadow effect, we ought to base + * the frame size on the buffer size rather than the reported window's + * frame size, as the buffer may not have been committed yet at this + * point. + */ + if (meta_window_x11_always_update_shape (window)) + { + meta_window_x11_surface_rect_to_frame_rect (window, &rect, &frame_rect); + get_client_area_rect_from_texture (actor_x11, stex, &client_area); + } + else + { + meta_window_get_frame_rect (window, &frame_rect); + meta_window_get_client_area_rect (window, &client_area); + } + + /* Make sure we don't paint the frame over the client window. */ + frame_paint_region = cairo_region_create_rectangle (&rect); + cairo_region_subtract_rectangle (frame_paint_region, &client_area); + + gdk_cairo_region (cr, frame_paint_region); + cairo_clip (cr); + + meta_frame_get_mask (window->frame, &frame_rect, cr); + + cairo_surface_flush (image); + scanned_region = scan_visible_region (mask_data, stride, frame_paint_region); + cairo_region_union (shape_region, scanned_region); + cairo_region_destroy (scanned_region); + cairo_region_destroy (frame_paint_region); + } + + cairo_destroy (cr); + cairo_surface_destroy (image); + + mask_texture = cogl_texture_2d_new_from_data (ctx, tex_width, tex_height, + COGL_PIXEL_FORMAT_A_8, + stride, mask_data, &error); + + if (error) + { + g_warning ("Failed to allocate mask texture: %s", error->message); + g_error_free (error); + } + + if (mask_texture) + { + meta_shaped_texture_set_mask_texture (stex, COGL_TEXTURE (mask_texture)); + cogl_object_unref (mask_texture); + } + else + { + meta_shaped_texture_set_mask_texture (stex, NULL); + } + + g_free (mask_data); +} + +static void +invalidate_shadow (MetaWindowActorX11 *actor_x11) +{ + actor_x11->recompute_focused_shadow = TRUE; + actor_x11->recompute_unfocused_shadow = TRUE; + + if (meta_window_actor_is_frozen (META_WINDOW_ACTOR (actor_x11))) + return; + + clutter_actor_queue_redraw (CLUTTER_ACTOR (actor_x11)); +} + +static void +update_shape_region (MetaWindowActorX11 *actor_x11) +{ + MetaWindow *window = + meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11)); + cairo_region_t *region = NULL; + cairo_rectangle_int_t client_area; + + get_client_area_rect (actor_x11, &client_area); + + if (window->frame && window->shape_region) + { + region = cairo_region_copy (window->shape_region); + cairo_region_translate (region, client_area.x, client_area.y); + } + else if (window->shape_region != NULL) + { + region = cairo_region_reference (window->shape_region); + } + else + { + /* If we don't have a shape on the server, that means that + * we have an implicit shape of one rectangle covering the + * entire window. */ + region = cairo_region_create_rectangle (&client_area); + } + + if (window->shape_region || window->frame) + build_and_scan_frame_mask (actor_x11, region); + + g_clear_pointer (&actor_x11->shape_region, cairo_region_destroy); + actor_x11->shape_region = region; + + g_clear_pointer (&actor_x11->shadow_shape, meta_window_shape_unref); + + invalidate_shadow (actor_x11); +} + +static void +update_input_region (MetaWindowActorX11 *actor_x11) +{ + MetaWindow *window = + meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11)); + MetaSurfaceActor *surface = + meta_window_actor_get_surface (META_WINDOW_ACTOR (actor_x11)); + cairo_region_t *region; + + if (window->shape_region && window->input_region) + { + region = cairo_region_copy (window->shape_region); + cairo_region_intersect (region, window->input_region); + } + else if (window->shape_region) + { + region = cairo_region_reference (window->shape_region); + } + else if (window->input_region) + { + region = cairo_region_reference (window->input_region); + } + else + { + region = NULL; + } + + meta_surface_actor_set_input_region (surface, region); + cairo_region_destroy (region); +} + +static gboolean +is_actor_maybe_transparent (MetaWindowActorX11 *actor_x11) +{ + MetaSurfaceActor *surface; + MetaShapedTexture *stex; + + surface = meta_window_actor_get_surface (META_WINDOW_ACTOR (actor_x11)); + if (!surface) + return TRUE; + + if (META_IS_SURFACE_ACTOR_X11 (surface) && + meta_surface_actor_x11_is_unredirected (META_SURFACE_ACTOR_X11 (surface))) + return FALSE; + + stex = meta_surface_actor_get_texture (surface); + if (!meta_shaped_texture_has_alpha (stex)) + return FALSE; + + return TRUE; +} + +static void +update_opaque_region (MetaWindowActorX11 *actor_x11) +{ + MetaWindow *window = + meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11)); + gboolean is_maybe_transparent; + cairo_region_t *opaque_region; + MetaSurfaceActor *surface; + + is_maybe_transparent = is_actor_maybe_transparent (actor_x11); + if (is_maybe_transparent && window->opaque_region) + { + cairo_rectangle_int_t client_area; + + get_client_area_rect (actor_x11, &client_area); + + /* The opaque region is defined to be a part of the + * window which ARGB32 will always paint with opaque + * pixels. For these regions, we want to avoid painting + * windows and shadows beneath them. + * + * If the client gives bad coordinates where it does not + * fully paint, the behavior is defined by the specification + * to be undefined, and considered a client bug. In mutter's + * case, graphical glitches will occur. + */ + opaque_region = cairo_region_copy (window->opaque_region); + cairo_region_translate (opaque_region, client_area.x, client_area.y); + cairo_region_intersect (opaque_region, actor_x11->shape_region); + } + else if (is_maybe_transparent) + { + opaque_region = NULL; + } + else + { + opaque_region = cairo_region_reference (actor_x11->shape_region); + } + + surface = meta_window_actor_get_surface (META_WINDOW_ACTOR (actor_x11)); + meta_surface_actor_set_opaque_region (surface, opaque_region); + cairo_region_destroy (opaque_region); +} + +static void +update_frame_bounds (MetaWindowActorX11 *actor_x11) +{ + MetaWindow *window = + meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11)); + + g_clear_pointer (&actor_x11->frame_bounds, cairo_region_destroy); + actor_x11->frame_bounds = + cairo_region_copy (meta_window_get_frame_bounds (window)); +} + +static void +update_regions (MetaWindowActorX11 *actor_x11) +{ + if (!actor_x11->needs_reshape) + return; + + update_shape_region (actor_x11); + update_input_region (actor_x11); + update_opaque_region (actor_x11); + + actor_x11->needs_reshape = FALSE; +} + +static void +check_needs_reshape (MetaWindowActorX11 *actor_x11) +{ + MetaWindow *window = + meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11)); + + if (meta_window_x11_always_update_shape (window)) + return; + + update_regions (actor_x11); +} + +void +meta_window_actor_x11_update_shape (MetaWindowActorX11 *actor_x11) +{ + MetaSurfaceActor *surface = + meta_window_actor_get_surface (META_WINDOW_ACTOR (actor_x11)); + + actor_x11->needs_reshape = TRUE; + + if (meta_window_actor_is_frozen (META_WINDOW_ACTOR (actor_x11))) + return; + + clutter_actor_queue_redraw (CLUTTER_ACTOR (surface)); +} + +static void +handle_updates (MetaWindowActorX11 *actor_x11) +{ + MetaSurfaceActor *surface = + meta_window_actor_get_surface (META_WINDOW_ACTOR (actor_x11)); + MetaWindow *window; + + if (META_IS_SURFACE_ACTOR_X11 (surface) && + meta_surface_actor_x11_is_unredirected (META_SURFACE_ACTOR_X11 (surface))) + return; + + window = meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11)); + if (meta_window_actor_is_frozen (META_WINDOW_ACTOR (actor_x11))) + { + /* The window is frozen due to a pending animation: we'll wait until + * the animation finishes to repair the window. + * + * However, with Xwayland, we still might need to update the shape + * region as the wl_buffer will be set to plain black on resize, + * which causes the shadows to look bad. + */ + if (surface && meta_window_x11_always_update_shape (window)) + check_needs_reshape (actor_x11); + + return; + } + + meta_surface_actor_pre_paint (surface); + + if (!META_IS_SURFACE_ACTOR_X11 (surface) || + !meta_surface_actor_x11_is_visible (META_SURFACE_ACTOR_X11 (surface))) + return; + + update_frame_bounds (actor_x11); + check_needs_reshape (actor_x11); + check_needs_shadow (actor_x11); +} + +static void +meta_window_actor_x11_pre_paint (MetaWindowActor *actor) +{ + MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (actor); + + handle_updates (actor_x11); + + assign_frame_counter_to_frames (actor_x11); +} + +static void +meta_window_actor_x11_paint (ClutterActor *actor, + ClutterPaintContext *paint_context) +{ + MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (actor); + MetaWindow *window; + gboolean appears_focused; + MetaShadow *shadow; + + /* This window got damage when obscured; we set up a timer + * to send frame completion events, but since we're drawing + * the window now (for some other reason) cancel the timer + * and send the completion events normally */ + if (actor_x11->send_frame_messages_timer != 0) + { + remove_frame_messages_timer (actor_x11); + assign_frame_counter_to_frames (actor_x11); + } + + window = meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11)); + appears_focused = meta_window_appears_focused (window); + shadow = appears_focused ? actor_x11->focused_shadow + : actor_x11->unfocused_shadow; + + if (shadow) + { + MetaShadowParams params; + cairo_rectangle_int_t shape_bounds; + cairo_region_t *clip = actor_x11->shadow_clip; + CoglFramebuffer *framebuffer; + + get_shape_bounds (actor_x11, &shape_bounds); + get_shadow_params (actor_x11, appears_focused, ¶ms); + + /* The frame bounds are already subtracted from actor_x11->shadow_clip + * if that exists. + */ + if (!clip && clip_shadow_under_window (actor_x11)) + { + cairo_rectangle_int_t bounds; + + get_shadow_bounds (actor_x11, appears_focused, &bounds); + clip = cairo_region_create_rectangle (&bounds); + + if (actor_x11->frame_bounds) + cairo_region_subtract (clip, actor_x11->frame_bounds); + } + + framebuffer = clutter_paint_context_get_framebuffer (paint_context); + meta_shadow_paint (shadow, + framebuffer, + params.x_offset + shape_bounds.x, + params.y_offset + shape_bounds.y, + shape_bounds.width, + shape_bounds.height, + (clutter_actor_get_paint_opacity (actor) * + params.opacity * window->opacity) / (255 * 255), + clip, + clip_shadow_under_window (actor_x11)); + + if (clip && clip != actor_x11->shadow_clip) + cairo_region_destroy (clip); + } + + CLUTTER_ACTOR_CLASS (meta_window_actor_x11_parent_class)->paint (actor, + paint_context); +} + +static void +meta_window_actor_x11_post_paint (MetaWindowActor *actor) +{ + MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (actor); + MetaWindow *window; + + actor_x11->repaint_scheduled = FALSE; + + if (meta_window_actor_is_destroyed (actor)) + return; + + /* If the window had damage, but wasn't actually redrawn because + * it is obscured, we should wait until timer expiration before + * sending _NET_WM_FRAME_* messages. + */ + if (actor_x11->send_frame_messages_timer == 0 && + actor_x11->needs_frame_drawn) + { + GList *l; + + for (l = actor_x11->frames; l; l = l->next) + { + FrameData *frame = l->data; + + if (frame->frame_drawn_time == 0) + do_send_frame_drawn (actor_x11, frame); + } + + actor_x11->needs_frame_drawn = FALSE; + } + + /* This is for Xwayland, and a no-op on plain Xorg */ + window = meta_window_actor_get_meta_window (actor); + if (meta_window_x11_should_thaw_after_paint (window)) + { + meta_window_x11_thaw_commits (window); + meta_window_x11_set_thaw_after_paint (window, FALSE); + } +} + +static gboolean +meta_window_actor_x11_get_paint_volume (ClutterActor *actor, + ClutterPaintVolume *volume) +{ + MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (actor); + MetaWindow *window; + gboolean appears_focused; + MetaSurfaceActor *surface; + + /* The paint volume is computed before paint functions are called + * so our bounds might not be updated yet. Force an update. */ + handle_updates (actor_x11); + + window = meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11)); + appears_focused = meta_window_appears_focused (window); + if (appears_focused ? actor_x11->focused_shadow : actor_x11->unfocused_shadow) + { + cairo_rectangle_int_t shadow_bounds; + ClutterActorBox shadow_box; + + /* We could compute an full clip region as we do for the window + * texture, but the shadow is relatively cheap to draw, and + * a little more complex to clip, so we just catch the case where + * the shadow is completely obscured and doesn't need to be drawn + * at all. + */ + + get_shadow_bounds (actor_x11, appears_focused, &shadow_bounds); + shadow_box.x1 = shadow_bounds.x; + shadow_box.x2 = shadow_bounds.x + shadow_bounds.width; + shadow_box.y1 = shadow_bounds.y; + shadow_box.y2 = shadow_bounds.y + shadow_bounds.height; + + clutter_paint_volume_union_box (volume, &shadow_box); + } + + surface = meta_window_actor_get_surface (META_WINDOW_ACTOR (actor_x11)); + if (surface) + { + ClutterActor *surface_actor = CLUTTER_ACTOR (surface); + const ClutterPaintVolume *child_volume; + + child_volume = clutter_actor_get_transformed_paint_volume (surface_actor, + actor); + if (!child_volume) + return FALSE; + + clutter_paint_volume_union (volume, child_volume); + } + + return TRUE; +} + +static void +meta_window_actor_x11_queue_destroy (MetaWindowActor *actor) +{ + MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (actor); + + if (actor_x11->send_frame_messages_timer != 0) + remove_frame_messages_timer (actor_x11); +} + +static void +meta_window_actor_x11_set_frozen (MetaWindowActor *actor, + gboolean frozen) +{ + MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (actor); + MetaWindow *window = meta_window_actor_get_meta_window (actor); + + if (actor_x11->is_frozen == frozen) + return; + + actor_x11->is_frozen = frozen; + + if (frozen) + meta_window_x11_freeze_commits (window); + else + meta_window_x11_thaw_commits (window); +} + +static void +meta_window_actor_x11_update_regions (MetaWindowActor *actor) +{ + update_regions (META_WINDOW_ACTOR_X11 (actor)); +} + +static void +meta_window_actor_x11_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (object); + + switch (prop_id) + { + case PROP_SHADOW_MODE: + { + MetaShadowMode newv = g_value_get_enum (value); + + if (newv == actor_x11->shadow_mode) + return; + + actor_x11->shadow_mode = newv; + + invalidate_shadow (actor_x11); + } + break; + case PROP_SHADOW_CLASS: + { + const char *newv = g_value_get_string (value); + + if (g_strcmp0 (newv, actor_x11->shadow_class) == 0) + return; + + g_free (actor_x11->shadow_class); + actor_x11->shadow_class = g_strdup (newv); + + invalidate_shadow (actor_x11); + } + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_window_actor_x11_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (object); + + switch (prop_id) + { + case PROP_SHADOW_MODE: + g_value_set_enum (value, actor_x11->shadow_mode); + break; + case PROP_SHADOW_CLASS: + g_value_set_string (value, actor_x11->shadow_class); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_window_actor_x11_constructed (GObject *object) +{ + MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (object); + MetaWindowActor *actor = META_WINDOW_ACTOR (actor_x11); + MetaWindow *window = meta_window_actor_get_meta_window (actor); + + /* + * Start off with an empty shape region to maintain the invariant that it's + * always set. + */ + actor_x11->shape_region = cairo_region_create (); + + G_OBJECT_CLASS (meta_window_actor_x11_parent_class)->constructed (object); + + /* If a window doesn't start off with updates frozen, we should + * we should send a _NET_WM_FRAME_DRAWN immediately after the first drawn. + */ + if (window->extended_sync_request_counter && + !meta_window_updates_are_frozen (window)) + meta_window_actor_queue_frame_drawn (actor, FALSE); +} + +static void +meta_window_actor_x11_cull_out (MetaCullable *cullable, + cairo_region_t *unobscured_region, + cairo_region_t *clip_region) +{ + MetaWindowActorX11 *self = META_WINDOW_ACTOR_X11 (cullable); + + cullable_parent_iface->cull_out (cullable, unobscured_region, clip_region); + + set_clip_region_beneath (self, clip_region); +} + +static void +meta_window_actor_x11_reset_culling (MetaCullable *cullable) +{ + MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (cullable); + + g_clear_pointer (&actor_x11->shadow_clip, cairo_region_destroy); + + cullable_parent_iface->reset_culling (cullable); +} + +static void +cullable_iface_init (MetaCullableInterface *iface) +{ + cullable_parent_iface = g_type_interface_peek_parent (iface); + + iface->cull_out = meta_window_actor_x11_cull_out; + iface->reset_culling = meta_window_actor_x11_reset_culling; +} + +static void +meta_window_actor_x11_dispose (GObject *object) +{ + MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (object); + MetaSurfaceActor *surface_actor; + + g_clear_signal_handler (&actor_x11->shadow_factory_changed_handler_id, + actor_x11->shadow_factory); + + if (actor_x11->send_frame_messages_timer != 0) + remove_frame_messages_timer (actor_x11); + + surface_actor = meta_window_actor_get_surface (META_WINDOW_ACTOR (actor_x11)); + if (surface_actor) + { + g_clear_signal_handler (&actor_x11->repaint_scheduled_id, surface_actor); + g_clear_signal_handler (&actor_x11->size_changed_id, surface_actor); + } + + g_clear_pointer (&actor_x11->shape_region, cairo_region_destroy); + g_clear_pointer (&actor_x11->shadow_clip, cairo_region_destroy); + g_clear_pointer (&actor_x11->frame_bounds, cairo_region_destroy); + + g_clear_pointer (&actor_x11->shadow_class, g_free); + g_clear_pointer (&actor_x11->focused_shadow, meta_shadow_unref); + g_clear_pointer (&actor_x11->unfocused_shadow, meta_shadow_unref); + g_clear_pointer (&actor_x11->shadow_shape, meta_window_shape_unref); + + G_OBJECT_CLASS (meta_window_actor_x11_parent_class)->dispose (object); +} + +static void +meta_window_actor_x11_finalize (GObject *object) +{ + MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (object); + + g_list_free_full (actor_x11->frames, (GDestroyNotify) frame_data_free); + + G_OBJECT_CLASS (meta_window_actor_x11_parent_class)->finalize (object); +} + +static void +meta_window_actor_x11_class_init (MetaWindowActorX11Class *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); + MetaWindowActorClass *window_actor_class = META_WINDOW_ACTOR_CLASS (klass); + GParamSpec *pspec; + + window_actor_class->frame_complete = meta_window_actor_x11_frame_complete; + window_actor_class->assign_surface_actor = meta_window_actor_x11_assign_surface_actor; + window_actor_class->queue_frame_drawn = meta_window_actor_x11_queue_frame_drawn; + window_actor_class->pre_paint = meta_window_actor_x11_pre_paint; + window_actor_class->post_paint = meta_window_actor_x11_post_paint; + window_actor_class->queue_destroy = meta_window_actor_x11_queue_destroy; + window_actor_class->set_frozen = meta_window_actor_x11_set_frozen; + window_actor_class->update_regions = meta_window_actor_x11_update_regions; + + actor_class->paint = meta_window_actor_x11_paint; + actor_class->get_paint_volume = meta_window_actor_x11_get_paint_volume; + + object_class->constructed = meta_window_actor_x11_constructed; + object_class->set_property = meta_window_actor_x11_set_property; + object_class->get_property = meta_window_actor_x11_get_property; + object_class->dispose = meta_window_actor_x11_dispose; + object_class->finalize = meta_window_actor_x11_finalize; + + pspec = g_param_spec_enum ("shadow-mode", + "Shadow mode", + "Decides when to paint shadows", + META_TYPE_SHADOW_MODE, + META_SHADOW_MODE_AUTO, + G_PARAM_READWRITE); + + g_object_class_install_property (object_class, + PROP_SHADOW_MODE, + pspec); + + pspec = g_param_spec_string ("shadow-class", + "Name of the shadow class for this window.", + "NULL means to use the default shadow class for this window type", + NULL, + G_PARAM_READWRITE); + + g_object_class_install_property (object_class, + PROP_SHADOW_CLASS, + pspec); +} + +static void +meta_window_actor_x11_init (MetaWindowActorX11 *self) +{ + /* We do this now since we might be going right back into the frozen state. */ + g_signal_connect (self, "thawed", G_CALLBACK (handle_updates), NULL); + + self->shadow_factory = meta_shadow_factory_get_default (); + self->shadow_factory_changed_handler_id = + g_signal_connect_swapped (self->shadow_factory, + "changed", + G_CALLBACK (invalidate_shadow), + self); +} diff --git a/src/compositor/meta-window-actor-x11.h b/src/compositor/meta-window-actor-x11.h new file mode 100644 index 000000000..86b80034d --- /dev/null +++ b/src/compositor/meta-window-actor-x11.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2018 Endless, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Georges Basile Stavracas Neto <gbsneto@gnome.org> + */ + +#ifndef META_WINDOW_ACTOR_X11_H +#define META_WINDOW_ACTOR_X11_H + +#include "compositor/meta-window-actor-private.h" + +#define META_TYPE_WINDOW_ACTOR_X11 (meta_window_actor_x11_get_type()) +G_DECLARE_FINAL_TYPE (MetaWindowActorX11, + meta_window_actor_x11, + META, WINDOW_ACTOR_X11, + MetaWindowActor) + +void meta_window_actor_x11_process_x11_damage (MetaWindowActorX11 *actor_x11, + XDamageNotifyEvent *event); + +gboolean meta_window_actor_x11_should_unredirect (MetaWindowActorX11 *actor_x11); + +void meta_window_actor_x11_set_unredirected (MetaWindowActorX11 *actor_x11, + gboolean unredirected); + +void meta_window_actor_x11_update_shape (MetaWindowActorX11 *actor_x11); + +void meta_window_actor_x11_process_damage (MetaWindowActorX11 *actor_x11, + XDamageNotifyEvent *event); + +#endif /* META_WINDOW_ACTOR_X11_H */ diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 1e3d35bb3..31e0cb607 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -3,93 +3,59 @@ /** * SECTION:meta-window-actor * @title: MetaWindowActor - * @short_description: An actor representing a top-level window in the scene graph + * @short_description: An actor representing a top-level window in the scene + * graph + * + * #MetaWindowActor is a #ClutterActor that adds a notion of a window to the + * Clutter scene graph. It contains a #MetaWindow which provides the windowing + * API, and the #MetaCompositor that handles it. For the actual content of the + * window, it contains a #MetaSurfaceActor. + * + * #MetaWindowActor takes care of the rendering features you need for your + * window. For example, it will take the windows' requested opacity and use + * that for clutter_actor_set_opacity(). Furthermore, it will also draw a + * shadow around the window (using #MetaShadow) and deal with synchronization + * between events of the window and the actual render loop. See + * MetaWindowActor::first-frame for an example of the latter. */ -#include <config.h> +#include "config.h" +#include <gdk/gdk.h> #include <math.h> +#include <string.h> + +#include "backends/meta-screen-cast-window.h" +#include "compositor/compositor-private.h" +#include "compositor/meta-cullable.h" +#include "compositor/meta-shaped-texture-private.h" +#include "compositor/meta-surface-actor-x11.h" +#include "compositor/meta-surface-actor.h" +#include "compositor/meta-window-actor-private.h" +#include "core/boxes-private.h" +#include "core/window-private.h" +#include "meta/window.h" + +#ifdef HAVE_WAYLAND +#include "compositor/meta-surface-actor-wayland.h" +#include "wayland/meta-wayland-surface.h" +#endif -#include <X11/extensions/shape.h> -#include <X11/extensions/Xcomposite.h> -#include <X11/extensions/Xdamage.h> -#include <X11/extensions/Xrender.h> - -#include <clutter/x11/clutter-x11.h> -#include <cogl/winsys/cogl-texture-pixmap-x11.h> -#include <gdk/gdk.h> /* for gdk_rectangle_union() */ - -#include <meta/display.h> -#include <meta/errors.h> -#include "frame.h" -#include <meta/window.h> -#include <meta/meta-shaped-texture.h> -#include "xprops.h" - -#include "compositor-private.h" -#include "meta-shaped-texture-private.h" -#include "meta-shadow-factory-private.h" -#include "meta-window-actor-private.h" - -enum { - POSITION_CHANGED, - SIZE_CHANGED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = {0}; - - -struct _MetaWindowActorPrivate +typedef enum { - MetaWindow *window; - Window xwindow; - MetaScreen *screen; - - ClutterActor *actor; - - /* MetaShadowFactory only caches shadows that are actually in use; - * to avoid unnecessary recomputation we do two things: 1) we store - * both a focused and unfocused shadow for the window. If the window - * doesn't have different focused and unfocused shadow parameters, - * these will be the same. 2) when the shadow potentially changes we - * don't immediately unreference the old shadow, we just flag it as - * dirty and recompute it when we next need it (recompute_focused_shadow, - * recompute_unfocused_shadow.) Because of our extraction of - * size-invariant window shape, we'll often find that the new shadow - * is the same as the old shadow. - */ - MetaShadow *focused_shadow; - MetaShadow *unfocused_shadow; - - Pixmap back_pixmap; - - Damage damage; - - guint8 opacity; + INITIALLY_FROZEN, + DRAWING_FIRST_FRAME, + EMITTED_FIRST_FRAME +} FirstFrameState; - /* If the window is shaped, a region that matches the shape */ - cairo_region_t *shape_region; - /* The opaque region, from _NET_WM_OPAQUE_REGION, intersected with - * the shape region. */ - cairo_region_t *opaque_region; - /* The region we should clip to when painting the shadow */ - cairo_region_t *shadow_clip; - - /* The region that is visible, used to optimize out redraws */ - cairo_region_t *unobscured_region; - - /* Extracted size-invariant shape used for shadows */ - MetaWindowShape *shadow_shape; - - gint last_width; - gint last_height; - gint last_x; - gint last_y; +typedef struct _MetaWindowActorPrivate +{ + MetaWindow *window; + MetaCompositor *compositor; - gint freeze_count; + MetaSurfaceActor *surface; - char * shadow_class; + int geometry_scale; /* * These need to be counters rather than flags, since more plugins @@ -97,82 +63,40 @@ struct _MetaWindowActorPrivate * might be dubious, but we have to at least handle it correctly. */ gint minimize_in_progress; - gint maximize_in_progress; - gint unmaximize_in_progress; - gint tile_in_progress; + gint unminimize_in_progress; + gint size_change_in_progress; gint map_in_progress; gint destroy_in_progress; - /* List of FrameData for recent frames */ - GList *frames; + guint freeze_count; guint visible : 1; - guint argb32 : 1; guint disposed : 1; - guint redecorating : 1; - - guint needs_damage_all : 1; - guint received_damage : 1; - guint repaint_scheduled : 1; - - /* If set, the client needs to be sent a _NET_WM_FRAME_DRAWN - * client message using the most recent frame in ->frames */ - guint send_frame_messages_timer; - gint64 frame_drawn_time; - guint needs_frame_drawn : 1; - - guint size_changed_id; - guint opacity_changed_id; - - guint needs_pixmap : 1; - guint needs_reshape : 1; - guint recompute_focused_shadow : 1; - guint recompute_unfocused_shadow : 1; - guint size_changed : 1; - guint position_changed : 1; - guint updates_frozen : 1; guint needs_destroy : 1; - guint no_shadow : 1; - - guint unredirected : 1; - - /* This is used to detect fullscreen windows that need to be unredirected */ - guint full_damage_frames_count; - guint does_full_damage : 1; + guint updates_frozen : 1; + guint first_frame_state : 2; /* FirstFrameState */ +} MetaWindowActorPrivate; - guint has_desat_effect : 1; +enum +{ + FIRST_FRAME, + EFFECTS_COMPLETED, + DAMAGED, + THAWED, - guint reshapes; - guint should_have_shadow : 1; + LAST_SIGNAL }; -typedef struct _FrameData FrameData; - -struct _FrameData -{ - int64_t frame_counter; - guint64 sync_request_serial; - gint64 frame_drawn_time; -}; +static guint signals[LAST_SIGNAL] = { 0 }; enum { PROP_META_WINDOW = 1, - PROP_META_SCREEN, - PROP_X_WINDOW, - PROP_X_WINDOW_ATTRIBUTES, - PROP_NO_SHADOW, - PROP_SHADOW_CLASS }; -#define DEFAULT_SHADOW_RADIUS 12 -#define DEFAULT_SHADOW_X_OFFSET 0 -#define DEFAULT_SHADOW_Y_OFFSET 8 - static void meta_window_actor_dispose (GObject *object); -static void meta_window_actor_finalize (GObject *object); static void meta_window_actor_constructed (GObject *object); static void meta_window_actor_set_property (GObject *object, guint prop_id, @@ -183,453 +107,339 @@ static void meta_window_actor_get_property (GObject *object, GValue *value, GParamSpec *pspec); -static void meta_window_actor_pick (ClutterActor *actor, - const ClutterColor *color); -static void meta_window_actor_paint (ClutterActor *actor); - -static gboolean meta_window_actor_get_paint_volume (ClutterActor *actor, - ClutterPaintVolume *volume); - - -static void meta_window_actor_detach (MetaWindowActor *self); -static gboolean meta_window_actor_has_shadow (MetaWindowActor *self); +static void meta_window_actor_real_assign_surface_actor (MetaWindowActor *self, + MetaSurfaceActor *surface_actor); -static void meta_window_actor_handle_updates (MetaWindowActor *self); +static void cullable_iface_init (MetaCullableInterface *iface); -static void check_needs_reshape (MetaWindowActor *self); +static void screen_cast_window_iface_init (MetaScreenCastWindowInterface *iface); -static void do_send_frame_drawn (MetaWindowActor *self, FrameData *frame); -static void do_send_frame_timings (MetaWindowActor *self, - FrameData *frame, - gint refresh_interval, - gint64 presentation_time); - -G_DEFINE_TYPE (MetaWindowActor, meta_window_actor, CLUTTER_TYPE_ACTOR); - -static void -frame_data_free (FrameData *frame) -{ - g_slice_free (FrameData, frame); -} +G_DEFINE_ABSTRACT_TYPE_WITH_CODE (MetaWindowActor, meta_window_actor, CLUTTER_TYPE_ACTOR, + G_ADD_PRIVATE (MetaWindowActor) + G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init) + G_IMPLEMENT_INTERFACE (META_TYPE_SCREEN_CAST_WINDOW, screen_cast_window_iface_init)); static void meta_window_actor_class_init (MetaWindowActorClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); GParamSpec *pspec; - g_type_class_add_private (klass, sizeof (MetaWindowActorPrivate)); - object_class->dispose = meta_window_actor_dispose; - object_class->finalize = meta_window_actor_finalize; object_class->set_property = meta_window_actor_set_property; object_class->get_property = meta_window_actor_get_property; object_class->constructed = meta_window_actor_constructed; - actor_class->pick = meta_window_actor_pick; - actor_class->paint = meta_window_actor_paint; - actor_class->get_paint_volume = meta_window_actor_get_paint_volume; + klass->assign_surface_actor = meta_window_actor_real_assign_surface_actor; + + /** + * MetaWindowActor::first-frame: + * @actor: the #MetaWindowActor instance + * + * The ::first-frame signal will be emitted the first time a frame + * of window contents has been drawn by the application and Mutter + * has had the chance to drawn that frame to the screen. If the + * window starts off initially hidden, obscured, or on on a + * different workspace, the ::first-frame signal will be emitted + * even though the user doesn't see the contents. + * + * MetaDisplay::window-created is a good place to connect to this + * signal - at that point, the MetaWindowActor for the window + * exists, but the window has reliably not yet been drawn. + * Connecting to an existing window that has already been drawn to + * the screen is not useful. + */ + signals[FIRST_FRAME] = + g_signal_new ("first-frame", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); + + /** + * MetaWindowActor::effects-completed: + * @actor: the #MetaWindowActor instance + * + * The ::effects-completed signal will be emitted once all pending compositor + * effects are completed. + */ + signals[EFFECTS_COMPLETED] = + g_signal_new ("effects-completed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); + + /** + * MetaWindowActor::damaged: + * @actor: the #MetaWindowActor instance + * + * Notify that one or more of the surfaces of the window have been damaged. + */ + signals[DAMAGED] = + g_signal_new ("damaged", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); + + /** + * MetaWindowActor::thawed: + * @actor: the #MetaWindowActor instance + */ + signals[THAWED] = + g_signal_new ("thawed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); pspec = g_param_spec_object ("meta-window", "MetaWindow", "The displayed MetaWindow", META_TYPE_WINDOW, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (object_class, PROP_META_WINDOW, pspec); +} - pspec = g_param_spec_pointer ("meta-screen", - "MetaScreen", - "MetaScreen", - G_PARAM_READWRITE | G_PARAM_CONSTRUCT); - - g_object_class_install_property (object_class, - PROP_META_SCREEN, - pspec); - - pspec = g_param_spec_ulong ("x-window", - "Window", - "Window", - 0, - G_MAXULONG, - 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT); +static void +meta_window_actor_init (MetaWindowActor *self) +{ + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (self); - g_object_class_install_property (object_class, - PROP_X_WINDOW, - pspec); + priv->geometry_scale = 1; +} - pspec = g_param_spec_boolean ("no-shadow", - "No shadow", - "Do not add shaddow to this window", - FALSE, - G_PARAM_READWRITE); +static void +window_appears_focused_notify (MetaWindow *mw, + GParamSpec *arg1, + gpointer data) +{ + clutter_actor_queue_redraw (CLUTTER_ACTOR (data)); +} - g_object_class_install_property (object_class, - PROP_NO_SHADOW, - pspec); +gboolean +meta_window_actor_is_opaque (MetaWindowActor *self) +{ + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (self); + MetaWindow *window = priv->window; - pspec = g_param_spec_string ("shadow-class", - "Name of the shadow class for this window.", - "NULL means to use the default shadow class for this window type", - NULL, - G_PARAM_READWRITE); + if (window->opacity != 0xff) + return FALSE; - g_object_class_install_property (object_class, - PROP_SHADOW_CLASS, - pspec); + if (!priv->surface) + return FALSE; - signals[POSITION_CHANGED] = - g_signal_new ("position-changed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 0); - signals[SIZE_CHANGED] = - g_signal_new ("size-changed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 0); + return meta_surface_actor_is_opaque (priv->surface); } -static void -meta_window_actor_init (MetaWindowActor *self) +gboolean +meta_window_actor_is_frozen (MetaWindowActor *self) { - MetaWindowActorPrivate *priv; - - priv = self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, - META_TYPE_WINDOW_ACTOR, - MetaWindowActorPrivate); - priv->opacity = 0xff; - priv->shadow_class = NULL; - priv->has_desat_effect = FALSE; - priv->reshapes = 0; - priv->should_have_shadow = FALSE; + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (self); + + return priv->surface == NULL || priv->freeze_count > 0; } -static void -meta_window_actor_reset_mask_texture (MetaWindowActor *self, - cairo_region_t *shape_region, - gboolean force) +void +meta_window_actor_update_regions (MetaWindowActor *self) { - MetaShapedTexture *stex = META_SHAPED_TEXTURE (self->priv->actor); - if (force) - meta_shaped_texture_dirty_mask (stex); - meta_shaped_texture_ensure_mask (stex, shape_region, self->priv->window->frame != NULL); + META_WINDOW_ACTOR_GET_CLASS (self)->update_regions (self); } static void -maybe_desaturate_window (ClutterActor *actor) +meta_window_actor_set_frozen (MetaWindowActor *self, + gboolean frozen) { - MetaWindowActor *window = META_WINDOW_ACTOR (actor); - MetaWindowActorPrivate *priv = window->priv; + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (self); - if (!priv->should_have_shadow && !priv->has_desat_effect) + if (meta_surface_actor_is_frozen (priv->surface) == frozen) return; - guint8 opacity = clutter_actor_get_opacity (actor); + meta_surface_actor_set_frozen (priv->surface, frozen); - if (opacity < 255) - { - if (priv->has_desat_effect) - { - return; - } - else - { - ClutterEffect *effect = clutter_desaturate_effect_new (0.0); - clutter_actor_add_effect_with_name (actor, "desaturate-for-transparency", effect); - priv->has_desat_effect = TRUE; - } - } - else - { - /* This is will tend to get called fairly often - opening new windows, various - events on the window, like minimizing... but it's inexpensive - if the ClutterActor - priv->effects is NULL, it simply returns. By default cinnamon and muffin add no - other effects except the special case of dimmed windows (attached modal dialogs), which - isn't a frequent occurrence. */ - - clutter_actor_remove_effect_by_name (actor, "desaturate-for-transparency"); - priv->has_desat_effect = FALSE; - } + META_WINDOW_ACTOR_GET_CLASS (self)->set_frozen (self, frozen); } static void -window_decorated_notify (MetaWindow *mw, - GParamSpec *arg1, - gpointer data) +meta_window_actor_freeze (MetaWindowActor *self) { - MetaWindowActor *self = META_WINDOW_ACTOR (data); - MetaWindowActorPrivate *priv = self->priv; - MetaFrame *frame = meta_window_get_frame (mw); - MetaScreen *screen = priv->screen; - MetaDisplay *display = meta_screen_get_display (screen); - Display *xdisplay = meta_display_get_xdisplay (display); - Window new_xwindow; + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (self); - /* - * Basically, we have to reconstruct the the internals of this object - * from scratch, as everything has changed. - */ - priv->redecorating = TRUE; + if (priv->freeze_count == 0 && priv->surface) + meta_window_actor_set_frozen (self, TRUE); - if (frame) - new_xwindow = meta_frame_get_xwindow (frame); - else - new_xwindow = meta_window_get_xwindow (mw); + priv->freeze_count ++; +} - meta_window_actor_detach (self); +static void +meta_window_actor_sync_thawed_state (MetaWindowActor *self) +{ + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (self); - /* - * First of all, clean up any resources we are currently using and will - * be replacing. - */ - if (priv->damage != None) - { - meta_error_trap_push (display); - XDamageDestroy (xdisplay, priv->damage); - meta_error_trap_pop (display); - priv->damage = None; - } + if (priv->first_frame_state == INITIALLY_FROZEN) + priv->first_frame_state = DRAWING_FIRST_FRAME; - priv->xwindow = new_xwindow; + if (priv->surface) + meta_window_actor_set_frozen (self, FALSE); - /* - * Recreate the contents. - */ - meta_window_actor_constructed (G_OBJECT (self)); + /* We sometimes ignore moves and resizes on frozen windows */ + meta_window_actor_sync_actor_geometry (self, FALSE); } static void -window_appears_focused_notify (MetaWindow *mw, - GParamSpec *arg1, - gpointer data) +meta_window_actor_thaw (MetaWindowActor *self) { - clutter_actor_queue_redraw (CLUTTER_ACTOR (data)); + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (self); + + if (priv->freeze_count <= 0) + g_error ("Error in freeze/thaw accounting"); + + priv->freeze_count--; + if (priv->freeze_count > 0) + return; + + /* We still might be frozen due to lack of a MetaSurfaceActor */ + if (meta_window_actor_is_frozen (self)) + return; + + meta_window_actor_sync_thawed_state (self); + + g_signal_emit (self, signals[THAWED], 0); } static void -clutter_actor_opacity_notify (ClutterActor *actor, - GParamSpec *arg1m, - gpointer data) +meta_window_actor_real_assign_surface_actor (MetaWindowActor *self, + MetaSurfaceActor *surface_actor) { - maybe_desaturate_window (actor); + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (self); + + g_clear_object (&priv->surface); + priv->surface = g_object_ref_sink (surface_actor); + + if (meta_window_actor_is_frozen (self)) + meta_window_actor_set_frozen (self, TRUE); + else + meta_window_actor_sync_thawed_state (self); } -static void -texture_size_changed (MetaWindow *mw, - gpointer data) +void +meta_window_actor_assign_surface_actor (MetaWindowActor *self, + MetaSurfaceActor *surface_actor) { - MetaWindowActor *self = META_WINDOW_ACTOR (data); - - g_signal_emit (self, signals[SIZE_CHANGED], 0); // Compatibility + META_WINDOW_ACTOR_GET_CLASS (self)->assign_surface_actor (self, + surface_actor); } static void -window_position_changed (MetaWindow *mw, - gpointer data) -{ - MetaWindowActor *self = META_WINDOW_ACTOR (data); +init_surface_actor (MetaWindowActor *self) +{ + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (self); + MetaWindow *window = priv->window; + MetaSurfaceActor *surface_actor; + + if (!meta_is_wayland_compositor ()) + surface_actor = meta_surface_actor_x11_new (window); +#ifdef HAVE_WAYLAND + else if (window->surface) + surface_actor = meta_wayland_surface_get_actor (window->surface); +#endif + else + surface_actor = NULL; - g_signal_emit (self, signals[POSITION_CHANGED], 0); // Compatibility + if (surface_actor) + meta_window_actor_assign_surface_actor (self, surface_actor); } static void meta_window_actor_constructed (GObject *object) { - MetaWindowActor *self = META_WINDOW_ACTOR (object); - MetaWindowActorPrivate *priv = self->priv; - MetaScreen *screen = priv->screen; - MetaDisplay *display = meta_screen_get_display (screen); - Window xwindow = priv->xwindow; - MetaWindow *window = priv->window; - Display *xdisplay = meta_display_get_xdisplay (display); - XRenderPictFormat *format; + MetaWindowActor *self = META_WINDOW_ACTOR (object); + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (self); + MetaWindow *window = priv->window; - priv->damage = XDamageCreate (xdisplay, xwindow, - XDamageReportBoundingBox); + priv->compositor = window->display->compositor; - format = XRenderFindVisualFormat (xdisplay, window->xvisual); + /* Hang our compositor window state off the MetaWindow for fast retrieval */ + meta_window_set_compositor_private (window, object); - if (format && format->type == PictTypeDirect && format->direct.alphaMask) - priv->argb32 = TRUE; + init_surface_actor (self); - if (!priv->actor) - { - priv->actor = meta_shaped_texture_new (); + meta_window_actor_update_opacity (self); - priv->size_changed_id = g_signal_connect (priv->actor, "size-changed", - G_CALLBACK (texture_size_changed), self); - clutter_actor_add_child (CLUTTER_ACTOR (self), priv->actor); + meta_window_actor_sync_updates_frozen (self); - /* - * Since we are holding a pointer to this actor independently of the - * ClutterContainer internals, and provide a public API to access it, - * add a reference here, so that if someone is messing about with us - * via the container interface, we do not end up with a dangling pointer. - * We will release it in dispose(). - */ - g_object_ref (priv->actor); - priv->opacity_changed_id = g_signal_connect (self, "notify::opacity", - G_CALLBACK (clutter_actor_opacity_notify), NULL); - - /* Fix for the case when clients try to re-map their windows after re-decorating while - effects are enabled. For reasons currently unknown, the re-shape doesn't happen when - #meta_plugin_map_completed is called after a delay. #window_decorated_notify is not - always called on re-decoration, and when it is, its only called before the actor is - disposed in this case - we can't track after that. */ - if (meta_prefs_get_desktop_effects () && - window->frame != NULL && - window->decorated && - !window->pending_compositor_effect && - !window->unmaps_pending) - priv->needs_reshape = TRUE; - } + if (meta_window_actor_is_frozen (self)) + priv->first_frame_state = INITIALLY_FROZEN; else - { - /* - * This is the case where existing window is gaining/loosing frame. - * Just ensure the actor is top most (i.e., above shadow). - */ - g_signal_handler_disconnect (priv->actor, priv->size_changed_id); - g_signal_handler_disconnect (self, priv->opacity_changed_id); - clutter_actor_set_child_above_sibling (CLUTTER_ACTOR (self), priv->actor, NULL); - } - - meta_window_actor_update_opacity (self); - maybe_desaturate_window (CLUTTER_ACTOR (self)); + priv->first_frame_state = DRAWING_FIRST_FRAME; - priv->shape_region = cairo_region_create(); + meta_window_actor_sync_actor_geometry (self, priv->window->placed); } static void meta_window_actor_dispose (GObject *object) { - MetaWindowActor *self = META_WINDOW_ACTOR (object); - MetaWindowActorPrivate *priv = self->priv; - MetaScreen *screen; - MetaDisplay *display; - Display *xdisplay; - MetaCompositor *compositor; + MetaWindowActor *self = META_WINDOW_ACTOR (object); + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (self); + MetaCompositor *compositor = priv->compositor; if (priv->disposed) - return; - - priv->disposed = TRUE; - - if (priv->send_frame_messages_timer != 0) { - g_source_remove (priv->send_frame_messages_timer); - priv->send_frame_messages_timer = 0; + G_OBJECT_CLASS (meta_window_actor_parent_class)->dispose (object); + return; } - screen = priv->screen; - display = screen->display; - xdisplay = display->xdisplay; - compositor = display->compositor; - - meta_window_actor_detach (self); + priv->disposed = TRUE; - g_clear_pointer (&priv->unobscured_region, cairo_region_destroy); - g_clear_pointer (&priv->shape_region, cairo_region_destroy); - g_clear_pointer (&priv->opaque_region, cairo_region_destroy); - g_clear_pointer (&priv->shadow_clip, cairo_region_destroy); + meta_compositor_remove_window_actor (compositor, self); - g_clear_pointer (&priv->shadow_class, free); - g_clear_pointer (&priv->focused_shadow, meta_shadow_unref); - g_clear_pointer (&priv->unfocused_shadow, meta_shadow_unref); - g_clear_pointer (&priv->shadow_shape, meta_window_shape_unref); + g_clear_object (&priv->window); - if (priv->damage != None) + if (priv->surface) { - meta_error_trap_push (display); - XDamageDestroy (xdisplay, priv->damage); - meta_error_trap_pop (display); - - priv->damage = None; + clutter_actor_remove_child (CLUTTER_ACTOR (self), + CLUTTER_ACTOR (priv->surface)); + g_clear_object (&priv->surface); } - compositor->windows = g_list_remove (compositor->windows, (gconstpointer) self); - - g_clear_object (&priv->window); - - /* - * Release the extra reference we took on the actor. - */ - g_clear_object (&priv->actor); - G_OBJECT_CLASS (meta_window_actor_parent_class)->dispose (object); } -static void -meta_window_actor_finalize (GObject *object) -{ - MetaWindowActor *self = META_WINDOW_ACTOR (object); - MetaWindowActorPrivate *priv = self->priv; - g_list_free_full (priv->frames, (GDestroyNotify) frame_data_free); - G_OBJECT_CLASS (meta_window_actor_parent_class)->finalize (object); -} - static void meta_window_actor_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { - MetaWindowActor *self = META_WINDOW_ACTOR (object); - MetaWindowActorPrivate *priv = self->priv; + MetaWindowActor *self = META_WINDOW_ACTOR (object); + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (self); switch (prop_id) { case PROP_META_WINDOW: - { - if (priv->window) - g_object_unref (priv->window); - priv->window = g_value_dup_object (value); - - g_signal_connect_object (priv->window, "notify::decorated", - G_CALLBACK (window_decorated_notify), self, 0); - g_signal_connect_object (priv->window, "notify::appears-focused", - G_CALLBACK (window_appears_focused_notify), self, 0); - g_signal_connect_object (priv->window, "position-changed", - G_CALLBACK (window_position_changed), self, 0); - } - break; - case PROP_META_SCREEN: - priv->screen = g_value_get_pointer (value); - break; - case PROP_X_WINDOW: - priv->xwindow = g_value_get_ulong (value); - break; - case PROP_NO_SHADOW: - { - gboolean newv = g_value_get_boolean (value); - - if (newv == priv->no_shadow) - return; - - priv->no_shadow = newv; - - meta_window_actor_invalidate_shadow (self); - } - break; - case PROP_SHADOW_CLASS: - { - const char *newv = g_value_get_string (value); - - if (g_strcmp0 (newv, priv->shadow_class) == 0) - return; - - free (priv->shadow_class); - priv->shadow_class = g_strdup (newv); - - meta_window_actor_invalidate_shadow (self); - } + priv->window = g_value_dup_object (value); + g_signal_connect_object (priv->window, "notify::appears-focused", + G_CALLBACK (window_appears_focused_notify), self, 0); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -643,725 +453,121 @@ meta_window_actor_get_property (GObject *object, GValue *value, GParamSpec *pspec) { - MetaWindowActorPrivate *priv = META_WINDOW_ACTOR (object)->priv; + MetaWindowActor *self = META_WINDOW_ACTOR (object); + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (self); switch (prop_id) { case PROP_META_WINDOW: g_value_set_object (value, priv->window); break; - case PROP_META_SCREEN: - g_value_set_pointer (value, priv->screen); - break; - case PROP_X_WINDOW: - g_value_set_ulong (value, priv->xwindow); - break; - case PROP_NO_SHADOW: - g_value_set_boolean (value, priv->no_shadow); - break; - case PROP_SHADOW_CLASS: - g_value_set_string (value, priv->shadow_class); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } -static const char * -meta_window_actor_get_shadow_class (MetaWindowActor *self) -{ - MetaWindowActorPrivate *priv = self->priv; - - if (priv->shadow_class != NULL) - return priv->shadow_class; - else - { - MetaWindowType window_type = meta_window_get_window_type (priv->window); - - switch (window_type) - { - case META_WINDOW_DROPDOWN_MENU: - return "dropdown-menu"; - case META_WINDOW_POPUP_MENU: - return "popup-menu"; - default: - { - MetaFrameType frame_type = meta_window_get_frame_type (priv->window); - return meta_frame_type_to_string (frame_type); - } - } - } -} - -static void -meta_window_actor_get_shadow_params (MetaWindowActor *self, - gboolean appears_focused, - MetaShadowParams *params) +/** + * meta_window_actor_get_meta_window: + * @self: a #MetaWindowActor + * + * Gets the #MetaWindow object that the the #MetaWindowActor is displaying + * + * Return value: (transfer none): the displayed #MetaWindow + */ +MetaWindow * +meta_window_actor_get_meta_window (MetaWindowActor *self) { - const char *shadow_class = meta_window_actor_get_shadow_class (self); + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (self); - meta_shadow_factory_get_params (meta_shadow_factory_get_default (), - shadow_class, appears_focused, - params); + return priv->window; } -LOCAL_SYMBOL void -meta_window_actor_get_shape_bounds (MetaWindowActor *self, - cairo_rectangle_int_t *bounds) +/** + * meta_window_actor_get_texture: + * @self: a #MetaWindowActor + * + * Gets the ClutterActor that is used to display the contents of the window, + * or NULL if no texture is shown yet, because the window is not mapped. + * + * Return value: (transfer none): the #ClutterActor for the contents + */ +MetaShapedTexture * +meta_window_actor_get_texture (MetaWindowActor *self) { - MetaWindowActorPrivate *priv = self->priv; + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (self); - /* We need to be defensive here because there are corner cases - * where getting the shape fails on a window being destroyed - * and similar. - */ - if (priv->shape_region) - cairo_region_get_extents (priv->shape_region, bounds); + if (priv->surface) + return meta_surface_actor_get_texture (priv->surface); else - bounds->x = bounds->y = bounds->width = bounds->height = 0; + return NULL; } -static void -meta_window_actor_get_shadow_bounds (MetaWindowActor *self, - gboolean appears_focused, - cairo_rectangle_int_t *bounds) +/** + * meta_window_actor_get_surface: + * @self: a #MetaWindowActor + * + * Gets the MetaSurfaceActor that draws the content of this window, + * or NULL if there is no surface yet associated with this window. + * + * Return value: (transfer none): the #MetaSurfaceActor for the contents + */ +MetaSurfaceActor * +meta_window_actor_get_surface (MetaWindowActor *self) { - MetaWindowActorPrivate *priv = self->priv; - MetaShadow *shadow = appears_focused ? priv->focused_shadow : priv->unfocused_shadow; - cairo_rectangle_int_t shape_bounds; - MetaShadowParams params; - - meta_window_actor_get_shape_bounds (self, &shape_bounds); - meta_window_actor_get_shadow_params (self, appears_focused, ¶ms); - - meta_shadow_get_bounds (shadow, - params.x_offset + shape_bounds.x, - params.y_offset + shape_bounds.y, - shape_bounds.width, - shape_bounds.height, - bounds); + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (self); + + return priv->surface; } -/* If we have an ARGB32 window that we decorate with a frame, it's - * probably something like a translucent terminal - something where - * the alpha channel represents transparency rather than a shape. We - * don't want to show the shadow through the translucent areas since - * the shadow is wrong for translucent windows (it should be - * translucent itself and colored), and not only that, will /look/ - * horribly wrong - a misplaced big black blob. As a hack, what we - * want to do is just draw the shadow as normal outside the frame, and - * inside the frame draw no shadow. This is also not even close to - * the right result, but looks OK. We also apply this approach to - * windows set to be partially translucent with _NET_WM_WINDOW_OPACITY. +/** + * meta_window_actor_is_destroyed: + * @self: a #MetaWindowActor + * + * Gets whether the X window that the actor was displaying has been destroyed + * + * Return value: %TRUE when the window is destroyed, otherwise %FALSE */ -static gboolean -clip_shadow_under_window (MetaWindowActor *self) +gboolean +meta_window_actor_is_destroyed (MetaWindowActor *self) { - MetaWindowActorPrivate *priv = self->priv; + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (self); - return (priv->argb32 || priv->opacity != 0xff) && priv->window->frame; + return priv->disposed || priv->needs_destroy; } -static void -assign_frame_counter_to_frames (MetaWindowActor *self) +void +meta_window_actor_queue_frame_drawn (MetaWindowActor *self, + gboolean no_delay_frame) { - MetaWindowActorPrivate *priv = self->priv; - ClutterStage *stage = priv->window->display->compositor->stage; - GList *l; - - /* If the window is obscured, then we're expecting to deal with sending - * frame messages in a timeout, rather than in this paint cycle. - */ - if (priv->send_frame_messages_timer != 0) - return; + META_WINDOW_ACTOR_GET_CLASS (self)->queue_frame_drawn (self, + no_delay_frame); +} - for (l = priv->frames; l; l = l->next) - { - FrameData *frame = l->data; +gboolean +meta_window_actor_effect_in_progress (MetaWindowActor *self) +{ + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (self); - if (frame->frame_counter == -1) - frame->frame_counter = clutter_stage_get_frame_counter (stage); - } + return (priv->minimize_in_progress || + priv->size_change_in_progress || + priv->map_in_progress || + priv->destroy_in_progress); } -static void -meta_window_actor_pick (ClutterActor *actor, - const ClutterColor *color) -{ - if (!clutter_actor_should_pick_paint (actor)) - return; - - MetaWindowActor *self = (MetaWindowActor *) actor; - MetaWindowActorPrivate *priv = self->priv; - ClutterActorIter iter; - ClutterActor *child; - - /* If there is no region then use the regular pick */ - if (priv->shape_region == NULL) - CLUTTER_ACTOR_CLASS (meta_window_actor_parent_class)->pick (actor, color); - else - { - int n_rects; - float *rectangles; - int i; - CoglPipeline *pipeline; - CoglContext *ctx; - CoglFramebuffer *fb; - CoglColor cogl_color; - - n_rects = cairo_region_num_rectangles (priv->shape_region); - rectangles = g_alloca (sizeof (float) * 4 * n_rects); - - for (i = 0; i < n_rects; i++) - { - cairo_rectangle_int_t rect; - int pos = i * 4; - - cairo_region_get_rectangle (priv->shape_region, i, &rect); - - rectangles[pos + 0] = rect.x; - rectangles[pos + 1] = rect.y; - rectangles[pos + 2] = rect.x + rect.width; - rectangles[pos + 3] = rect.y + rect.height; - } - - ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); - fb = cogl_get_draw_framebuffer (); - - cogl_color_init_from_4ub (&cogl_color, color->red, color->green, color->blue, color->alpha); - - pipeline = cogl_pipeline_new (ctx); - cogl_pipeline_set_color (pipeline, &cogl_color); - cogl_framebuffer_draw_rectangles (fb, pipeline, rectangles, n_rects); - cogl_object_unref (pipeline); - } - - clutter_actor_iter_init (&iter, actor); - - while (clutter_actor_iter_next (&iter, &child)) - clutter_actor_paint (child); -} - -static void -meta_window_actor_paint (ClutterActor *actor) -{ - MetaWindowActor *self = META_WINDOW_ACTOR (actor); - MetaWindowActorPrivate *priv = self->priv; - CoglFramebuffer *framebuffer = NULL; - gboolean appears_focused = meta_window_appears_focused (priv->window); - MetaShadow *shadow = appears_focused ? priv->focused_shadow : priv->unfocused_shadow; - - if (!priv->window->display->shadows_enabled) { - shadow = NULL; - } - - /* This window got damage when obscured; we set up a timer - * to send frame completion events, but since we're drawing - * the window now (for some other reason) cancel the timer - * and send the completion events normally */ - if (priv->send_frame_messages_timer != 0) - { - g_source_remove (priv->send_frame_messages_timer); - priv->send_frame_messages_timer = 0; - - assign_frame_counter_to_frames (self); - } - - if (shadow != NULL) - { - MetaShadowParams params; - cairo_rectangle_int_t shape_bounds; - cairo_region_t *clip = priv->shadow_clip; - - meta_window_actor_get_shape_bounds (self, &shape_bounds); - meta_window_actor_get_shadow_params (self, appears_focused, ¶ms); - - /* The frame bounds are already subtracted from priv->shadow_clip - * if that exists. - */ - if (!clip && clip_shadow_under_window (self)) - { - cairo_rectangle_int_t bounds; - - meta_window_actor_get_shadow_bounds (self, appears_focused, &bounds); - clip = cairo_region_create_rectangle (&bounds); - - cairo_region_subtract (clip, meta_window_get_frame_bounds (priv->window)); - } - - framebuffer = cogl_get_draw_framebuffer (); - - meta_shadow_paint (shadow, - framebuffer, - params.x_offset + shape_bounds.x, - params.y_offset + shape_bounds.y, - shape_bounds.width, - shape_bounds.height, - (clutter_actor_get_paint_opacity (actor) * params.opacity * priv->opacity) / (255 * 255), - clip, - clip_shadow_under_window (self)); /* clip_strictly - not just as an optimization */ - - if (clip && clip != priv->shadow_clip) - cairo_region_destroy (clip); - } - - CLUTTER_ACTOR_CLASS (meta_window_actor_parent_class)->paint (actor); -} - -static gboolean -meta_window_actor_get_paint_volume (ClutterActor *actor, - ClutterPaintVolume *volume) -{ - MetaWindowActor *self = META_WINDOW_ACTOR (actor); - MetaWindowActorPrivate *priv = self->priv; - gboolean appears_focused = meta_window_appears_focused (priv->window); - - /* The paint volume is computed before paint functions are called - * so our bounds might not be updated yet. Force an update. */ - meta_window_actor_handle_updates (self); - - if (appears_focused ? priv->focused_shadow : priv->unfocused_shadow) - { - cairo_rectangle_int_t shadow_bounds; - ClutterActorBox shadow_box; - - /* We could compute an full clip region as we do for the window - * texture, but the shadow is relatively cheap to draw, and - * a little more complex to clip, so we just catch the case where - * the shadow is completely obscured and doesn't need to be drawn - * at all. - */ - - meta_window_actor_get_shadow_bounds (self, appears_focused, &shadow_bounds); - shadow_box.x1 = shadow_bounds.x; - shadow_box.x2 = shadow_bounds.x + shadow_bounds.width; - shadow_box.y1 = shadow_bounds.y; - shadow_box.y2 = shadow_bounds.y + shadow_bounds.height; - - clutter_paint_volume_union_box (volume, &shadow_box); - } - - if (priv->actor) - { - const ClutterPaintVolume *child_volume; - - child_volume = clutter_actor_get_transformed_paint_volume (CLUTTER_ACTOR (priv->actor), actor); - if (!child_volume) - return FALSE; - - clutter_paint_volume_union (volume, child_volume); - } - - return TRUE; -} - -static gboolean -meta_window_actor_has_shadow (MetaWindowActor *self) -{ - MetaWindowActorPrivate *priv = self->priv; - MetaWindowType window_type = meta_window_get_window_type (priv->window); - - if (priv->no_shadow) - return FALSE; - - /* Leaving out shadows for maximized and fullscreen windows is an effeciency - * win and also prevents the unsightly effect of the shadow of maximized - * window appearing on an adjacent window */ - if ((meta_window_get_maximized (priv->window) == (META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL)) || - meta_window_is_fullscreen (priv->window)) - return FALSE; - - /* Don't shadow tiled windows of any type */ - - if (meta_window_get_tile_type (priv->window) != META_WINDOW_TILE_TYPE_NONE) - return FALSE; - - /* - * Always put a shadow around windows with a frame - This should override - * the restriction about not putting a shadow around ARGB windows. - */ - if (priv->window) - { - if (meta_window_get_frame (priv->window)) - return TRUE; - } - - /* - * Do not add shadows to ARGB windows; eventually we should generate a - * shadow from the input shape for such windows. - */ - if (priv->argb32 || priv->opacity != 0xff) - return FALSE; - /* - * Add shadows to override redirect windows (e.g., Gtk menus). - */ - if (priv->window->override_redirect) - return TRUE; - - /* - * If a window specifies that it has custom frame extents, that likely - * means that it is drawing a shadow itself. Don't draw our own. - */ - if (priv->window->has_custom_frame_extents) - return FALSE; - - /* - * Don't put shadow around DND icon windows - */ - if (window_type == META_WINDOW_DND || - window_type == META_WINDOW_DESKTOP || - window_type == META_WINDOW_DOCK) - return FALSE; - - if (window_type == META_WINDOW_MENU -#if 0 - || window_type == META_WINDOW_DROPDOWN_MENU -#endif - ) - return TRUE; - - if (meta_window_is_client_decorated (priv->window)) - { - return FALSE; - } - -#if 0 - if (window_type == META_WINDOW_TOOLTIP) - return TRUE; -#endif - - return FALSE; -} - -/** - * meta_window_actor_get_x_window: (skip) - * - */ -Window -meta_window_actor_get_x_window (MetaWindowActor *self) -{ - if (!self) - return None; - - return self->priv->xwindow; -} - -/** - * meta_window_actor_get_meta_window: - * - * Gets the #MetaWindow object that the the #MetaWindowActor is displaying - * - * Return value: (transfer none): the displayed #MetaWindow - */ -MetaWindow * -meta_window_actor_get_meta_window (MetaWindowActor *self) -{ - return self->priv->window; -} - -/** - * meta_window_actor_get_texture: - * - * Gets the ClutterActor that is used to display the contents of the window - * - * Return value: (transfer none): the #ClutterActor for the contents - */ -ClutterActor * -meta_window_actor_get_texture (MetaWindowActor *self) -{ - return self->priv->actor; -} - -/** - * meta_window_actor_is_destroyed: - * - * Gets whether the X window that the actor was displaying has been destroyed - * - * Return value: %TRUE when the window is destroyed, otherwise %FALSE - */ -gboolean -meta_window_actor_is_destroyed (MetaWindowActor *self) -{ - return self->priv->disposed || self->priv->needs_destroy; -} - -static gboolean -send_frame_messages_timeout (gpointer data) -{ - MetaWindowActor *self = (MetaWindowActor *) data; - MetaWindowActorPrivate *priv = self->priv; - GList *l; - - for (l = priv->frames; l;) - { - GList *l_next = l->next; - FrameData *frame = l->data; - - if (frame->frame_counter == -1) - { - do_send_frame_drawn (self, frame); - do_send_frame_timings (self, frame, 0, 0); - - priv->frames = g_list_delete_link (priv->frames, l); - frame_data_free (frame); - } - - l = l_next; - } - - priv->needs_frame_drawn = FALSE; - priv->send_frame_messages_timer = 0; - - return FALSE; -} - -static void -queue_send_frame_messages_timeout (MetaWindowActor *self) -{ - MetaWindowActorPrivate *priv = self->priv; - MetaWindow *window = meta_window_actor_get_meta_window (self); - MetaDisplay *display = meta_screen_get_display (priv->screen); - int64_t current_time; - float refresh_rate; - int interval, offset; - - if (priv->send_frame_messages_timer != 0) - return; - - if (window->monitor) - { - refresh_rate = window->monitor->refresh_rate; - } - else - { - refresh_rate = 60.0f; - } - - current_time = - meta_compositor_monotonic_time_to_server_time (display, - g_get_monotonic_time ()); - interval = (int)(1000000 / refresh_rate) * 6; - offset = MAX (0, priv->frame_drawn_time + interval - current_time) / 1000; - - /* The clutter master clock source has already been added with META_PRIORITY_REDRAW, - * so the timer will run *after* the clutter frame handling, if a frame is ready - * to be drawn when the timer expires. - */ - priv->send_frame_messages_timer = g_timeout_add_full (META_PRIORITY_REDRAW, offset, send_frame_messages_timeout, self, NULL); - g_source_set_name_by_id (priv->send_frame_messages_timer, "[muffin] send_frame_messages_timeout"); -} - -gboolean -meta_window_actor_is_override_redirect (MetaWindowActor *self) -{ - return meta_window_is_override_redirect (self->priv->window); -} - -/** - * meta_window_actor_get_workspace: - * @self: #MetaWindowActor - * - * Returns the index of workspace on which this window is located; if the - * window is sticky, or is not currently located on any workspace, returns -1. - * This function is deprecated and should not be used in newly written code; - * meta_window_get_workspace() instead. - * - * Return value: index of workspace on which this window is - * located. - */ -gint -meta_window_actor_get_workspace (MetaWindowActor *self) -{ - MetaWindowActorPrivate *priv; - MetaWorkspace *workspace; - - if (!self) - return -1; - - priv = self->priv; - - if (!priv->window || meta_window_is_on_all_workspaces (priv->window)) - return -1; - - workspace = meta_window_get_workspace (priv->window); - - if (!workspace) - return -1; - - return meta_workspace_index (workspace); -} - -gboolean -meta_window_actor_showing_on_its_workspace (MetaWindowActor *self) -{ - if (!self) - return FALSE; - - /* If override redirect: */ - if (!self->priv->window) - return TRUE; - - return meta_window_showing_on_its_workspace (self->priv->window); -} - -static void -meta_window_actor_freeze (MetaWindowActor *self) -{ - self->priv->freeze_count++; -} - -static void -update_area (MetaWindowActor *self, - int x, int y, int width, int height) -{ - MetaWindowActorPrivate *priv = self->priv; - CoglTexture *texture; - - texture = meta_shaped_texture_get_texture (META_SHAPED_TEXTURE (priv->actor)); - - cogl_texture_pixmap_x11_update_area (COGL_TEXTURE_PIXMAP_X11 (texture), - x, y, width, height); -} - -static void -meta_window_actor_damage_all (MetaWindowActor *self) -{ - MetaWindowActorPrivate *priv = self->priv; - CoglTexture *texture; - - if (!priv->needs_damage_all || !priv->window->mapped || priv->needs_pixmap) - return; - - texture = meta_shaped_texture_get_texture (META_SHAPED_TEXTURE (priv->actor)); - - priv->needs_damage_all = FALSE; - - update_area (self, 0, 0, cogl_texture_get_width (texture), cogl_texture_get_height (texture)); - priv->repaint_scheduled = meta_shaped_texture_update_area (META_SHAPED_TEXTURE (priv->actor), - 0, 0, - cogl_texture_get_width (texture), - cogl_texture_get_height (texture), - clutter_actor_has_mapped_clones (priv->actor) ? NULL : priv->unobscured_region); -} - -static void -meta_window_actor_thaw (MetaWindowActor *self) -{ - self->priv->freeze_count--; - - if (G_UNLIKELY (self->priv->freeze_count < 0)) - { - g_warning ("Error in freeze/thaw accounting."); - self->priv->freeze_count = 0; - return; - } - - if (self->priv->freeze_count) - return; - - /* We sometimes ignore moves and resizes on frozen windows */ - meta_window_actor_sync_actor_geometry (self, FALSE); - - /* We do this now since we might be going right back into the - * frozen state */ - meta_window_actor_handle_updates (self); - - /* Since we ignore damage events while a window is frozen for certain effects - * we may need to issue an update_area() covering the whole pixmap if we - * don't know what real damage has happened. */ - if (self->priv->needs_damage_all) - meta_window_actor_damage_all (self); -} - -void -meta_window_actor_queue_frame_drawn (MetaWindowActor *self, - gboolean no_delay_frame) -{ - MetaWindowActorPrivate *priv = self->priv; - FrameData *frame; - - if (meta_window_actor_is_destroyed (self)) - return; - - frame = g_slice_new0 (FrameData); - frame->frame_counter = -1; - - priv->needs_frame_drawn = TRUE; - -#ifdef HAVE_XSYNC - frame->sync_request_serial = priv->window->sync_request_serial; -#else - frame->sync_request_serial = 0; -#endif - - priv->frames = g_list_prepend (priv->frames, frame); - - if (no_delay_frame) - { - ClutterActor *stage = priv->window->display->compositor->stage; - clutter_stage_skip_sync_delay (CLUTTER_STAGE (stage)); - } - - if (!priv->repaint_scheduled) - { - gboolean is_obscured = FALSE; - /* Find out whether the window is completly obscured */ - if (priv->unobscured_region) - { - cairo_region_t *unobscured_window_region; - unobscured_window_region = cairo_region_copy (priv->shape_region); - cairo_region_intersect (unobscured_window_region, priv->unobscured_region); - is_obscured = cairo_region_is_empty (unobscured_window_region); - cairo_region_destroy (unobscured_window_region); - } - - /* A frame was marked by the client without actually doing any - * damage, or while we had the window frozen (e.g. during an - * interactive resize.) We need to make sure that the - * pre_paint/post_paint functions get called, enabling us to - * send a _NET_WM_FRAME_DRAWN. We do a 1-pixel redraw to get - * consistent timing with non-empty frames. - */ - if (is_obscured) - { - queue_send_frame_messages_timeout (self); - } - else if (priv->window->mapped && !priv->needs_pixmap) - { - const cairo_rectangle_int_t clip = { 0, 0, 1, 1 }; - clutter_actor_queue_redraw_with_clip (priv->actor, &clip); - priv->repaint_scheduled = TRUE; - } - } -} - -LOCAL_SYMBOL gboolean -meta_window_actor_effect_in_progress (MetaWindowActor *self) -{ - return (self->priv->minimize_in_progress || - self->priv->maximize_in_progress || - self->priv->unmaximize_in_progress || - self->priv->map_in_progress || - self->priv->tile_in_progress || - self->priv->destroy_in_progress); -} - -static gboolean -is_frozen (MetaWindowActor *self) -{ - return self->priv->freeze_count ? TRUE : FALSE; -} - -static gboolean -is_freeze_thaw_effect (gulong event) +static gboolean +is_freeze_thaw_effect (MetaPluginEffect event) { switch (event) { case META_PLUGIN_DESTROY: - case META_PLUGIN_MAXIMIZE: - case META_PLUGIN_UNMAXIMIZE: - case META_PLUGIN_TILE: + case META_PLUGIN_SIZE_CHANGE: return TRUE; break; default: @@ -1370,32 +576,37 @@ is_freeze_thaw_effect (gulong event) } static gboolean -start_simple_effect (MetaWindowActor *self, - gulong event) -{ - MetaWindowActorPrivate *priv = self->priv; - MetaCompositor *compositor = priv->screen->display->compositor; +start_simple_effect (MetaWindowActor *self, + MetaPluginEffect event) +{ + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (self); + MetaCompositor *compositor = priv->compositor; + MetaPluginManager *plugin_mgr = + meta_compositor_get_plugin_manager (compositor); gint *counter = NULL; gboolean use_freeze_thaw = FALSE; - if (!compositor->plugin_mgr) - return FALSE; + g_assert (plugin_mgr != NULL); switch (event) { + case META_PLUGIN_NONE: + return FALSE; case META_PLUGIN_MINIMIZE: counter = &priv->minimize_in_progress; break; + case META_PLUGIN_UNMINIMIZE: + counter = &priv->unminimize_in_progress; + break; case META_PLUGIN_MAP: counter = &priv->map_in_progress; break; case META_PLUGIN_DESTROY: counter = &priv->destroy_in_progress; break; - case META_PLUGIN_UNMAXIMIZE: - case META_PLUGIN_MAXIMIZE: + case META_PLUGIN_SIZE_CHANGE: case META_PLUGIN_SWITCH_WORKSPACE: - case META_PLUGIN_TILE: g_assert_not_reached (); break; } @@ -1409,9 +620,7 @@ start_simple_effect (MetaWindowActor *self, (*counter)++; - if (!meta_plugin_manager_event_simple (compositor->plugin_mgr, - self, - event)) + if (!meta_plugin_manager_event_simple (plugin_mgr, self, event)) { (*counter)--; if (use_freeze_thaw) @@ -1425,7 +634,8 @@ start_simple_effect (MetaWindowActor *self, static void meta_window_actor_after_effects (MetaWindowActor *self) { - MetaWindowActorPrivate *priv = self->priv; + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (self); if (priv->needs_destroy) { @@ -1433,18 +643,18 @@ meta_window_actor_after_effects (MetaWindowActor *self) return; } + g_signal_emit (self, signals[EFFECTS_COMPLETED], 0); meta_window_actor_sync_visibility (self); meta_window_actor_sync_actor_geometry (self, FALSE); - - if (priv->needs_pixmap) - clutter_actor_queue_redraw (priv->actor); } -LOCAL_SYMBOL void -meta_window_actor_effect_completed (MetaWindowActor *self, - gulong event) +void +meta_window_actor_effect_completed (MetaWindowActor *self, + MetaPluginEffect event) { - MetaWindowActorPrivate *priv = self->priv; + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (self); + gboolean inconsistent = FALSE; /* NB: Keep in mind that when effects get completed it possible * that the corresponding MetaWindow may have be been destroyed. @@ -1452,14 +662,28 @@ meta_window_actor_effect_completed (MetaWindowActor *self, switch (event) { + case META_PLUGIN_NONE: + break; case META_PLUGIN_MINIMIZE: { priv->minimize_in_progress--; if (priv->minimize_in_progress < 0) - { - g_warning ("Error in minimize accounting."); - priv->minimize_in_progress = 0; - } + { + g_warning ("Error in minimize accounting."); + priv->minimize_in_progress = 0; + inconsistent = TRUE; + } + } + break; + case META_PLUGIN_UNMINIMIZE: + { + priv->unminimize_in_progress--; + if (priv->unminimize_in_progress < 0) + { + g_warning ("Error in unminimize accounting."); + priv->unminimize_in_progress = 0; + inconsistent = TRUE; + } } break; case META_PLUGIN_MAP: @@ -1468,11 +692,12 @@ meta_window_actor_effect_completed (MetaWindowActor *self, * the plugin fscked. */ priv->map_in_progress--; - priv->position_changed = TRUE; + if (priv->map_in_progress < 0) { - g_warning ("Error in map accounting."); - priv->map_in_progress = 0; + g_warning ("Error in map accounting."); + priv->map_in_progress = 0; + inconsistent = TRUE; } break; case META_PLUGIN_DESTROY: @@ -1480,32 +705,18 @@ meta_window_actor_effect_completed (MetaWindowActor *self, if (priv->destroy_in_progress < 0) { - g_warning ("Error in destroy accounting."); - priv->destroy_in_progress = 0; - } - break; - case META_PLUGIN_UNMAXIMIZE: - priv->unmaximize_in_progress--; - if (priv->unmaximize_in_progress < 0) - { - g_warning ("Error in unmaximize accounting."); - priv->unmaximize_in_progress = 0; - } - break; - case META_PLUGIN_MAXIMIZE: - priv->maximize_in_progress--; - if (priv->maximize_in_progress < 0) - { - g_warning ("Error in maximize accounting."); - priv->maximize_in_progress = 0; + g_warning ("Error in destroy accounting."); + priv->destroy_in_progress = 0; + inconsistent = TRUE; } break; - case META_PLUGIN_TILE: - priv->tile_in_progress--; - if (priv->tile_in_progress < 0) + case META_PLUGIN_SIZE_CHANGE: + priv->size_change_in_progress--; + if (priv->size_change_in_progress < 0) { - g_warning ("Error in tile accounting."); - priv->tile_in_progress = 0; + g_warning ("Error in size change accounting."); + priv->size_change_in_progress = 0; + inconsistent = TRUE; } break; case META_PLUGIN_SWITCH_WORKSPACE: @@ -1513,126 +724,24 @@ meta_window_actor_effect_completed (MetaWindowActor *self, break; } - if (is_freeze_thaw_effect (event)) + if (is_freeze_thaw_effect (event) && !inconsistent) meta_window_actor_thaw (self); if (!meta_window_actor_effect_in_progress (self)) meta_window_actor_after_effects (self); } -/* Called to drop our reference to a window backing pixmap that we - * previously obtained with XCompositeNameWindowPixmap. We do this - * when the window is unmapped or when we want to update to a new - * pixmap for a new size. - */ -static void -meta_window_actor_detach (MetaWindowActor *self) -{ - MetaWindowActorPrivate *priv = self->priv; - MetaScreen *screen = priv->screen; - MetaDisplay *display = meta_screen_get_display (screen); - Display *xdisplay = meta_display_get_xdisplay (display); - - if (!priv->back_pixmap) - return; - - /* Get rid of all references to the pixmap before freeing it; it's unclear whether - * you are supposed to be able to free a GLXPixmap after freeing the underlying - * pixmap, but it certainly doesn't work with current DRI/Mesa - */ - meta_shaped_texture_set_texture (META_SHAPED_TEXTURE (priv->actor), NULL); - - cogl_flush(); - - XFreePixmap (xdisplay, priv->back_pixmap); - priv->back_pixmap = None; - - priv->needs_pixmap = TRUE; -} - -LOCAL_SYMBOL gboolean -meta_window_actor_should_unredirect (MetaWindowActor *self) -{ - MetaWindow *metaWindow = meta_window_actor_get_meta_window (self); - MetaWindowActorPrivate *priv = self->priv; - - if (meta_window_actor_is_destroyed (self)) - return FALSE; - - if (meta_window_requested_dont_bypass_compositor (metaWindow)) - return FALSE; - - if (priv->opacity != 0xff) - return FALSE; - - if (metaWindow->has_shape) - return FALSE; - - if (priv->argb32 && !meta_window_requested_bypass_compositor (metaWindow)) - return FALSE; - - if (!meta_window_is_monitor_sized (metaWindow)) - return FALSE; - - if (meta_window_requested_bypass_compositor (metaWindow)) - return TRUE; - - if (meta_window_is_override_redirect (metaWindow)) - return TRUE; - - if (priv->does_full_damage && meta_prefs_get_unredirect_fullscreen_windows ()) - return TRUE; - - return FALSE; -} - -LOCAL_SYMBOL void -meta_window_actor_set_redirected (MetaWindowActor *self, gboolean state) -{ - MetaWindowActorPrivate *priv = self->priv; - MetaWindow *metaWindow = priv->window; - MetaDisplay *display = metaWindow->display; - - Display *xdisplay = meta_display_get_xdisplay (display); - Window xwin = meta_window_actor_get_x_window (self); - - if (priv->unredirected != state) - return; - - meta_error_trap_push (display); - - if (state) - { - XCompositeRedirectWindow (xdisplay, xwin, CompositeRedirectManual); - meta_window_actor_detach (self); - priv->unredirected = FALSE; - } - else - { - XCompositeUnredirectWindow (xdisplay, xwin, CompositeRedirectManual); - priv->repaint_scheduled = TRUE; - priv->unredirected = TRUE; - } - - meta_error_trap_pop (display); -} - -LOCAL_SYMBOL void -meta_window_actor_destroy (MetaWindowActor *self) +void +meta_window_actor_queue_destroy (MetaWindowActor *self) { - MetaWindow *window; - MetaWindowActorPrivate *priv = self->priv; - MetaWindowType window_type; + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (self); + MetaWindow *window = priv->window; + MetaWindowType window_type = meta_window_get_window_type (window); - window = priv->window; - window_type = meta_window_get_window_type (window); meta_window_set_compositor_private (window, NULL); - if (priv->send_frame_messages_timer != 0) - { - g_source_remove (priv->send_frame_messages_timer); - priv->send_frame_messages_timer = 0; - } + META_WINDOW_ACTOR_GET_CLASS (self)->queue_destroy (self); if (window_type == META_WINDOW_DROPDOWN_MENU || window_type == META_WINDOW_POPUP_MENU || @@ -1655,30 +764,23 @@ meta_window_actor_destroy (MetaWindowActor *self) clutter_actor_destroy (CLUTTER_ACTOR (self)); } -LOCAL_SYMBOL void +MetaWindowActorChanges meta_window_actor_sync_actor_geometry (MetaWindowActor *self, gboolean did_placement) { - MetaWindowActorPrivate *priv = self->priv; + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (self); MetaRectangle window_rect; + ClutterActor *actor = CLUTTER_ACTOR (self); + MetaWindowActorChanges changes = 0; - meta_window_get_input_rect (priv->window, &window_rect); - - if (priv->last_width != window_rect.width || - priv->last_height != window_rect.height) - { - priv->size_changed = TRUE; - priv->last_width = window_rect.width; - priv->last_height = window_rect.height; - } + meta_window_get_buffer_rect (priv->window, &window_rect); - if (priv->last_x != window_rect.x || - priv->last_y != window_rect.y) - { - priv->position_changed = TRUE; - priv->last_x = window_rect.x; - priv->last_y = window_rect.y; - } + /* When running as a Wayland compositor we catch size changes when new + * buffers are attached */ + if (META_IS_SURFACE_ACTOR_X11 (priv->surface)) + meta_surface_actor_x11_set_size (META_SURFACE_ACTOR_X11 (priv->surface), + window_rect.width, window_rect.height); /* Normally we want freezing a window to also freeze its position; this allows * windows to atomically move and resize together, either under app control, @@ -1687,76 +789,93 @@ meta_window_actor_sync_actor_geometry (MetaWindowActor *self, * is shown, the map effect will go into effect and prevent further geometry * updates. */ - if (is_frozen (self) && !did_placement) - return; + if (meta_window_actor_is_frozen (self) && !did_placement) + return META_WINDOW_ACTOR_CHANGE_POSITION | META_WINDOW_ACTOR_CHANGE_SIZE; if (meta_window_actor_effect_in_progress (self)) - return; + return META_WINDOW_ACTOR_CHANGE_POSITION | META_WINDOW_ACTOR_CHANGE_SIZE; - if (priv->size_changed) + if (clutter_actor_has_allocation (actor)) { - priv->needs_pixmap = TRUE; - meta_window_actor_update_shape (self); + ClutterActorBox box; + float old_x, old_y; + float old_width, old_height; - clutter_actor_set_size (CLUTTER_ACTOR (self), - window_rect.width, window_rect.height); - } + clutter_actor_get_allocation_box (actor, &box); + + old_x = box.x1; + old_y = box.y1; + old_width = box.x2 - box.x1; + old_height = box.y2 - box.y1; - if (priv->position_changed) + if (old_x != window_rect.x || old_y != window_rect.y) + changes |= META_WINDOW_ACTOR_CHANGE_POSITION; + + if (old_width != window_rect.width || old_height != window_rect.height) + changes |= META_WINDOW_ACTOR_CHANGE_SIZE; + } + else { - clutter_actor_set_position (CLUTTER_ACTOR (self), - window_rect.x, window_rect.y); + changes = META_WINDOW_ACTOR_CHANGE_POSITION | META_WINDOW_ACTOR_CHANGE_SIZE; } + + if (changes & META_WINDOW_ACTOR_CHANGE_POSITION) + clutter_actor_set_position (actor, window_rect.x, window_rect.y); + + if (changes & META_WINDOW_ACTOR_CHANGE_SIZE) + clutter_actor_set_size (actor, window_rect.width, window_rect.height); + + return changes; } void meta_window_actor_show (MetaWindowActor *self, MetaCompEffect effect) { - MetaWindowActorPrivate *priv = self->priv; - gulong event; + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (self); + MetaCompositor *compositor = priv->compositor; + MetaPluginEffect event; g_return_if_fail (!priv->visible); priv->visible = TRUE; - event = 0; switch (effect) { case META_COMP_EFFECT_CREATE: event = META_PLUGIN_MAP; break; case META_COMP_EFFECT_UNMINIMIZE: - /* FIXME: should have META_PLUGIN_UNMINIMIZE */ - event = META_PLUGIN_MAP; + event = META_PLUGIN_UNMINIMIZE; break; case META_COMP_EFFECT_NONE: + event = META_PLUGIN_NONE; break; - case META_COMP_EFFECT_DESTROY: - case META_COMP_EFFECT_MINIMIZE: + default: g_assert_not_reached(); } - if (priv->redecorating || - priv->screen->display->compositor->switch_workspace_in_progress || - event == 0 || - !meta_prefs_get_desktop_effects () || + if (event == META_PLUGIN_MAP) + meta_window_actor_sync_actor_geometry (self, TRUE); + + if (meta_compositor_is_switching_workspace (compositor) || !start_simple_effect (self, event)) { clutter_actor_show (CLUTTER_ACTOR (self)); - priv->redecorating = FALSE; } } -LOCAL_SYMBOL void +void meta_window_actor_hide (MetaWindowActor *self, MetaCompEffect effect) { - MetaWindowActorPrivate *priv = self->priv; - MetaCompositor *compositor = priv->screen->display->compositor; - gulong event; + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (self); + MetaCompositor *compositor = priv->compositor; + MetaPluginEffect event; - g_return_if_fail (priv->visible || (!priv->visible && meta_window_is_attached_dialog (priv->window))); + g_return_if_fail (priv->visible); priv->visible = FALSE; @@ -1764,10 +883,9 @@ meta_window_actor_hide (MetaWindowActor *self, * hold off on hiding the window, and do it after the workspace * switch completes */ - if (compositor->switch_workspace_in_progress) + if (meta_compositor_is_switching_workspace (compositor)) return; - event = 0; switch (effect) { case META_COMP_EFFECT_DESTROY: @@ -1777,283 +895,43 @@ meta_window_actor_hide (MetaWindowActor *self, event = META_PLUGIN_MINIMIZE; break; case META_COMP_EFFECT_NONE: + event = META_PLUGIN_NONE; break; - case META_COMP_EFFECT_UNMINIMIZE: - case META_COMP_EFFECT_CREATE: + default: g_assert_not_reached(); } - if (event == 0 || - !meta_prefs_get_desktop_effects () || - !start_simple_effect (self, event)) + if (!start_simple_effect (self, event)) clutter_actor_hide (CLUTTER_ACTOR (self)); } -LOCAL_SYMBOL void -meta_window_actor_maximize (MetaWindowActor *self, - MetaRectangle *old_rect, - MetaRectangle *new_rect) -{ - MetaCompositor *compositor = self->priv->screen->display->compositor; - /* The window has already been resized (in order to compute new_rect), - * which by side effect caused the actor to be resized. Restore it to the - * old size and position */ - clutter_actor_set_position (CLUTTER_ACTOR (self), old_rect->x, old_rect->y); - clutter_actor_set_size (CLUTTER_ACTOR (self), old_rect->width, old_rect->height); - - self->priv->maximize_in_progress++; - meta_window_actor_freeze (self); - - if (!compositor->plugin_mgr || - !meta_plugin_manager_event_maximize (compositor->plugin_mgr, - self, - META_PLUGIN_MAXIMIZE, - new_rect->x, new_rect->y, - new_rect->width, new_rect->height)) - - { - self->priv->maximize_in_progress--; - meta_window_actor_thaw (self); - } -} - -LOCAL_SYMBOL void -meta_window_actor_unmaximize (MetaWindowActor *self, - MetaRectangle *old_rect, - MetaRectangle *new_rect) -{ - MetaCompositor *compositor = self->priv->screen->display->compositor; - - /* The window has already been resized (in order to compute new_rect), - * which by side effect caused the actor to be resized. Restore it to the - * old size and position */ - clutter_actor_set_position (CLUTTER_ACTOR (self), old_rect->x, old_rect->y); - clutter_actor_set_size (CLUTTER_ACTOR (self), old_rect->width, old_rect->height); - - self->priv->unmaximize_in_progress++; - meta_window_actor_freeze (self); - - if (!compositor->plugin_mgr || - !meta_plugin_manager_event_maximize (compositor->plugin_mgr, - self, - META_PLUGIN_UNMAXIMIZE, - new_rect->x, new_rect->y, - new_rect->width, new_rect->height)) - { - self->priv->unmaximize_in_progress--; - meta_window_actor_thaw (self); - } -} - -LOCAL_SYMBOL void -meta_window_actor_tile (MetaWindowActor *self, - MetaRectangle *old_rect, - MetaRectangle *new_rect) -{ - MetaCompositor *compositor = self->priv->screen->display->compositor; - - /* The window has already been resized (in order to compute new_rect), - * which by side effect caused the actor to be resized. Restore it to the - * old size and position */ - clutter_actor_set_position (CLUTTER_ACTOR (self), old_rect->x, old_rect->y); - clutter_actor_set_size (CLUTTER_ACTOR (self), old_rect->width, old_rect->height); - - self->priv->tile_in_progress++; +void +meta_window_actor_size_change (MetaWindowActor *self, + MetaSizeChange which_change, + MetaRectangle *old_frame_rect, + MetaRectangle *old_buffer_rect) +{ + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (self); + MetaCompositor *compositor = priv->compositor; + MetaPluginManager *plugin_mgr = + meta_compositor_get_plugin_manager (compositor); + + priv->size_change_in_progress++; meta_window_actor_freeze (self); - if (!compositor->plugin_mgr || - !meta_plugin_manager_event_maximize (compositor->plugin_mgr, - self, - META_PLUGIN_TILE, - new_rect->x, new_rect->y, - new_rect->width, new_rect->height)) - + if (!meta_plugin_manager_event_size_change (plugin_mgr, self, + which_change, old_frame_rect, old_buffer_rect)) { - self->priv->tile_in_progress--; + priv->size_change_in_progress--; meta_window_actor_thaw (self); } } -static void -ensure_tooltip_visible (MetaWindow *window) -{ - const MetaMonitorInfo *wmonitor; - MetaRectangle work_area, win_rect; - gint new_x, new_y; - - /* Why this is here: - * As of gtk 3.24, tooltips for GtkStatusIcons began displaying their tool tip - * off the screen in certain situations. - * - * See: https://github.com/GNOME/gtk/commit/14d22cb3233e - * - * If the status icon is too small relative to its panel (which has been assigned - * as a strut to muffin), tooltip positioning fails both tests in gdkwindowimpl.c - * (maybe_flip_position()) skipping repositioning of the tooltip inside the workarea. - * This only occurs on bottom panels, and only begins happening when the status icon - * becomes 10px or more smaller than the panel it's *centered* on. - * - * Since the calculations are based upon the monitor's workarea and the status icon - * plug window's size, there's no way to compensate for or fool gtk into displaying it - * correctly. So here, we do our own check and adjustment if a part of the tooltip - * window falls outside the current monitor's work area. This is also useful since - * muffin knows *exactly* the work area for each monitor, whereas gtk only has - * _NET_WORKAREA to go by, which only keeps track of (primary monitor * n_workspaces), - * so an odd monitor layout would trip this up anyhow. - * - * This may cause regressions - see: https://github.com/linuxmint/muffin/commit/050038690, - * but without being able to reproduce the issue mentioned there, we'll just have to address - * it if it appears again as a result of this change. */ - - wmonitor = meta_screen_get_monitor_for_window (window->screen, window); - - meta_workspace_get_work_area_for_monitor (meta_screen_get_active_workspace (window->screen), - wmonitor->number, - &work_area); - - meta_window_get_outer_rect (window, &win_rect); - - new_x = win_rect.x; - new_y = win_rect.y; - - if (win_rect.y < work_area.y) - { - new_y = work_area.y; - } - else if (win_rect.y + win_rect.height > work_area.y + work_area.height) - { - new_y = (work_area.y + work_area.height - win_rect.height); - } - - if (win_rect.x < work_area.x) - { - new_x = work_area.x; - } - else if (win_rect.x + win_rect.width > work_area.x + work_area.width) - { - new_x = (work_area.x + work_area.width - win_rect.width); - } - - if (new_x != win_rect.x || new_y != win_rect.y) - { - meta_window_move(window, FALSE, new_x, new_y); - } -} - -LOCAL_SYMBOL MetaWindowActor * -meta_window_actor_new (MetaWindow *window) -{ - MetaScreen *screen = window->screen; - MetaCompositor *compositor = screen->display->compositor; - MetaWindowActor *self; - MetaWindowActorPrivate *priv; - MetaFrame *frame; - Window top_window; - ClutterActor *window_group; - - frame = meta_window_get_frame (window); - if (frame) - top_window = meta_frame_get_xwindow (frame); - else - top_window = meta_window_get_xwindow (window); - - meta_verbose ("add window: Meta %p, xwin 0x%x\n", window, (guint)top_window); - - self = g_object_new (META_TYPE_WINDOW_ACTOR, - "meta-window", window, - "x-window", top_window, - "meta-screen", screen, - NULL); - - priv = self->priv; - - priv->last_width = -1; - priv->last_height = -1; - priv->last_x = -1; - priv->last_y = -1; - - priv->needs_pixmap = TRUE; - - meta_window_actor_set_updates_frozen (self, - meta_window_updates_are_frozen (priv->window)); - - /* If a window doesn't start off with updates frozen, we should - * we should send a _NET_WM_FRAME_DRAWN immediately after the first drawn. - */ - if (priv->window->extended_sync_request_counter && !priv->updates_frozen) - meta_window_actor_queue_frame_drawn (self, FALSE); - - meta_window_actor_sync_actor_geometry (self, priv->window->placed); - - /* Hang our compositor window state off the MetaWindow for fast retrieval */ - meta_window_set_compositor_private (window, G_OBJECT (self)); - - if (window->type == META_WINDOW_DND) - window_group = compositor->window_group; - else if (window->layer == META_LAYER_OVERRIDE_REDIRECT) - { - if (window->type == META_WINDOW_TOOLTIP) - { - ensure_tooltip_visible (window); - } - - window_group = compositor->top_window_group; - } - else if (window->type == META_WINDOW_DESKTOP) - window_group = compositor->bottom_window_group; - else - window_group = compositor->window_group; - - clutter_actor_add_child (window_group, CLUTTER_ACTOR (self)); - - clutter_actor_hide (CLUTTER_ACTOR (self)); - - /* Initial position in the stack is arbitrary; stacking will be synced - * before we first paint. - */ - compositor->windows = g_list_append (compositor->windows, self); - - return self; -} - -static void -meta_window_actor_update_shape_region (MetaWindowActor *self, - cairo_region_t *region) -{ - MetaWindowActorPrivate *priv = self->priv; - - g_clear_pointer (&priv->shape_region, cairo_region_destroy); - - /* region must be non-null */ - priv->shape_region = region; - cairo_region_reference (region); -} - -/** - * meta_window_actor_get_obscured_region: - * @self: a #MetaWindowActor - * - * Gets the region that is completely obscured by the window. Coordinates - * are relative to the upper-left of the window. - * - * Return value: (transfer none): the area obscured by the window, - * %NULL is the same as an empty region. - */ -LOCAL_SYMBOL cairo_region_t * -meta_window_actor_get_obscured_region (MetaWindowActor *self) -{ - MetaWindowActorPrivate *priv = self->priv; - - if (priv->back_pixmap && priv->opacity == 0xff) - return priv->opaque_region; - else - return NULL; -} - #if 0 /* Print out a region; useful for debugging */ static void -dump_region (cairo_region_t *region) +print_region (cairo_region_t *region) { int n_rects; int i; @@ -2065,825 +943,579 @@ dump_region (cairo_region_t *region) cairo_rectangle_int_t rect; cairo_region_get_rectangle (region, i, &rect); g_print ("+%d+%dx%dx%d ", - rect.x, rect.y, rect.width, rect.height); - } - g_print ("]\n"); -} -#endif - -/** - * meta_window_actor_set_unobscured_region: - * @self: a #MetaWindowActor - * @unobscured_region: the region of the screen that isn't completely - * obscured. - * - * Provides a hint as to what areas of the window need to queue - * redraws when damaged. Regions not in @unobscured_region are completely obscured. - * Unlike meta_window_actor_set_clip_region(), the region here - * doesn't take into account any clipping that is in effect while drawing. - */ -void -meta_window_actor_set_unobscured_region (MetaWindowActor *self, - cairo_region_t *unobscured_region) -{ - MetaWindowActorPrivate *priv = self->priv; - - if (priv->unobscured_region) - cairo_region_destroy (priv->unobscured_region); - - if (unobscured_region) - priv->unobscured_region = cairo_region_copy (unobscured_region); - else - priv->unobscured_region = NULL; -} - -/** - * meta_window_actor_set_visible_region: - * @self: a #MetaWindowActor - * @visible_region: the region of the screen that isn't completely - * obscured. - * - * Provides a hint as to what areas of the window need to be - * drawn. Regions not in @visible_region are completely obscured. - * This will be set before painting then unset afterwards. - */ -LOCAL_SYMBOL void -meta_window_actor_set_visible_region (MetaWindowActor *self, - cairo_region_t *visible_region) -{ - MetaWindowActorPrivate *priv = self->priv; - - meta_shaped_texture_set_clip_region (META_SHAPED_TEXTURE (priv->actor), - visible_region); -} - -/** - * meta_window_actor_set_visible_region_beneath: - * @self: a #MetaWindowActor - * @visible_region: the region of the screen that isn't completely - * obscured beneath the main window texture. - * - * Provides a hint as to what areas need to be drawn *beneath* - * the main window texture. This is the relevant visible region - * when drawing the shadow, properly accounting for areas of the - * shadow hid by the window itself. This will be set before painting - * then unset afterwards. - */ -LOCAL_SYMBOL void -meta_window_actor_set_visible_region_beneath (MetaWindowActor *self, - cairo_region_t *beneath_region) -{ - MetaWindowActorPrivate *priv = self->priv; - gboolean appears_focused = meta_window_appears_focused (priv->window); - - if (appears_focused ? priv->focused_shadow : priv->unfocused_shadow) - { - g_clear_pointer (&priv->shadow_clip, cairo_region_destroy); - priv->shadow_clip = cairo_region_copy (beneath_region); - - if (clip_shadow_under_window (self)) - cairo_region_subtract (priv->shadow_clip, - meta_window_get_frame_bounds (priv->window)); + rect.x, rect.y, rect.width, rect.height); } + g_print ("]\n"); } +#endif -/** - * meta_window_actor_reset_visible_regions: - * @self: a #MetaWindowActor - * - * Unsets the regions set by meta_window_actor_reset_visible_region() and - * meta_window_actor_reset_visible_region_beneath() - */ -LOCAL_SYMBOL void -meta_window_actor_reset_visible_regions (MetaWindowActor *self) +#if 0 +/* Dump a region to a PNG file; useful for debugging */ +static void +see_region (cairo_region_t *region, + int width, + int height, + char *filename) { - MetaWindowActorPrivate *priv = self->priv; + cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height); + cairo_t *cr = cairo_create (surface); + + gdk_cairo_region (cr, region); + cairo_fill (cr); - meta_shaped_texture_set_clip_region (META_SHAPED_TEXTURE (priv->actor), - NULL); - g_clear_pointer (&priv->shadow_clip, cairo_region_destroy); + cairo_surface_write_to_png (surface, filename); + cairo_destroy (cr); + cairo_surface_destroy (surface); } +#endif + static void -check_needs_pixmap (MetaWindowActor *self) +meta_window_actor_cull_out (MetaCullable *cullable, + cairo_region_t *unobscured_region, + cairo_region_t *clip_region) { - MetaWindowActorPrivate *priv = self->priv; - MetaScreen *screen = priv->screen; - MetaDisplay *display = screen->display; - Display *xdisplay = display->xdisplay; - MetaCompositor *compositor = display->compositor; - Window xwindow = priv->xwindow; - - if ((!priv->window->mapped && !priv->window->shaded) || !priv->needs_pixmap) - return; - - if (xwindow == screen->xroot || - xwindow == clutter_x11_get_stage_window (compositor->stage)) - return; + meta_cullable_cull_out_children (cullable, unobscured_region, clip_region); +} - if (priv->size_changed) - { - meta_window_actor_detach (self); - priv->size_changed = FALSE; - } +static void +meta_window_actor_reset_culling (MetaCullable *cullable) +{ + meta_cullable_reset_culling_children (cullable); +} - if (priv->position_changed) - priv->position_changed = FALSE; +static void +cullable_iface_init (MetaCullableInterface *iface) +{ + iface->cull_out = meta_window_actor_cull_out; + iface->reset_culling = meta_window_actor_reset_culling; +} - meta_error_trap_push (display); +void +meta_window_actor_sync_visibility (MetaWindowActor *self) +{ + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (self); - if (priv->back_pixmap == None) + if (CLUTTER_ACTOR_IS_VISIBLE (self) != priv->visible) { - CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); - CoglTexture *texture; - - meta_error_trap_push (display); - - priv->back_pixmap = XCompositeNameWindowPixmap (xdisplay, xwindow); - - if (meta_error_trap_pop_with_return (display) != Success) - { - /* Probably a BadMatch if the window isn't viewable; we could - * GrabServer/GetWindowAttributes/NameWindowPixmap/UngrabServer/Sync - * to avoid this, but there's no reason to take two round trips - * when one will do. (We need that Sync if we want to handle failures - * for any reason other than !viewable. That's unlikely, but maybe - * we'll BadAlloc or something.) - */ - priv->back_pixmap = None; - } - - if (priv->back_pixmap == None) - { - meta_verbose ("Unable to get named pixmap for %p\n", self); - goto out; - } - - if (compositor->no_mipmaps) - meta_shaped_texture_set_create_mipmaps (META_SHAPED_TEXTURE (priv->actor), - FALSE); - - texture = COGL_TEXTURE (cogl_texture_pixmap_x11_new (ctx, priv->back_pixmap, FALSE, NULL)); - - /* - * This only works *after* actually setting the pixmap, so we have to - * do it here. - * See: http://bugzilla.clutter-project.org/show_bug.cgi?id=2236 - */ - if (G_UNLIKELY (!cogl_texture_pixmap_x11_is_using_tfp_extension (texture))) - g_warning ("NOTE: Not using GLX TFP!\n"); - - meta_shaped_texture_set_texture (META_SHAPED_TEXTURE (priv->actor), texture); + if (priv->visible) + clutter_actor_show (CLUTTER_ACTOR (self)); + else + clutter_actor_hide (CLUTTER_ACTOR (self)); } +} - priv->needs_pixmap = FALSE; +void +meta_window_actor_pre_paint (MetaWindowActor *self) +{ + if (meta_window_actor_is_destroyed (self)) + return; - out: - meta_error_trap_pop (display); + META_WINDOW_ACTOR_GET_CLASS (self)->pre_paint (self); } -static void -check_needs_shadow (MetaWindowActor *self) +void +meta_window_actor_post_paint (MetaWindowActor *self) { - if (!self->priv->window->display->shadows_enabled) { - return; - } + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (self); - MetaWindowActorPrivate *priv = self->priv; - MetaShadow *old_shadow = NULL; - MetaShadow **shadow_location; - gboolean recompute_shadow; - gboolean should_have_shadow; - gboolean appears_focused; + META_WINDOW_ACTOR_GET_CLASS (self)->post_paint (self); - if (!priv->window->mapped && !priv->window->shaded) + if (meta_window_actor_is_destroyed (self)) return; - /* Calling meta_window_actor_has_shadow() here at every pre-paint is cheap - * and avoids the need to explicitly handle window type changes, which - * we would do if tried to keep track of when we might be adding or removing - * a shadow more explicitly. We only keep track of changes to the *shape* of - * the shadow with priv->recompute_shadow. - */ - - should_have_shadow = meta_window_actor_has_shadow (self); - priv->should_have_shadow = should_have_shadow; - appears_focused = meta_window_appears_focused (priv->window); - - if (appears_focused) - { - recompute_shadow = priv->recompute_focused_shadow; - priv->recompute_focused_shadow = FALSE; - shadow_location = &priv->focused_shadow; - } - else - { - recompute_shadow = priv->recompute_unfocused_shadow; - priv->recompute_unfocused_shadow = FALSE; - shadow_location = &priv->unfocused_shadow; - } - - if (!should_have_shadow || recompute_shadow) + if (priv->first_frame_state == DRAWING_FIRST_FRAME) { - if (*shadow_location != NULL) - { - old_shadow = *shadow_location; - *shadow_location = NULL; - } + priv->first_frame_state = EMITTED_FIRST_FRAME; + g_signal_emit (self, signals[FIRST_FRAME], 0); } +} - if (*shadow_location == NULL && should_have_shadow) - { - if (priv->shadow_shape == NULL) - { - if (priv->shape_region) - priv->shadow_shape = meta_window_shape_new (priv->shape_region); - } +void +meta_window_actor_frame_complete (MetaWindowActor *self, + ClutterFrameInfo *frame_info, + gint64 presentation_time) +{ + META_WINDOW_ACTOR_GET_CLASS (self)->frame_complete (self, + frame_info, + presentation_time); +} - if (priv->shadow_shape != NULL) - { - MetaShadowFactory *factory = meta_shadow_factory_get_default (); - const char *shadow_class = meta_window_actor_get_shadow_class (self); - cairo_rectangle_int_t shape_bounds; - - meta_window_actor_get_shape_bounds (self, &shape_bounds); - *shadow_location = meta_shadow_factory_get_shadow (factory, - priv->shadow_shape, - shape_bounds.width, shape_bounds.height, - shadow_class, appears_focused); - } - } +void +meta_window_actor_update_opacity (MetaWindowActor *self) +{ + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (self); + MetaWindow *window = priv->window; - if (old_shadow != NULL) - meta_shadow_unref (old_shadow); + if (priv->surface) + clutter_actor_set_opacity (CLUTTER_ACTOR (priv->surface), window->opacity); } -LOCAL_SYMBOL void -meta_window_actor_process_damage (MetaWindowActor *self, - XDamageNotifyEvent *event) +static void +meta_window_actor_set_updates_frozen (MetaWindowActor *self, + gboolean updates_frozen) { - MetaWindowActorPrivate *priv = self->priv; - MetaCompositor *compositor = priv->window->display->compositor; + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (self); - priv->received_damage = TRUE; - - /* Drop damage event for unredirected windows */ - if (priv->unredirected) - return; + updates_frozen = updates_frozen != FALSE; - if (meta_window_is_fullscreen (priv->window) && g_list_last (compositor->windows)->data == self) + if (priv->updates_frozen != updates_frozen) { - MetaRectangle window_rect; - meta_window_get_outer_rect (priv->window, &window_rect); - - if (event->area.x == 0 && - event->area.y == 0 && - window_rect.width == event->area.width && - window_rect.height == event->area.height) - priv->full_damage_frames_count++; + priv->updates_frozen = updates_frozen; + if (updates_frozen) + meta_window_actor_freeze (self); else - priv->full_damage_frames_count = 0; - - if (priv->full_damage_frames_count >= 100) - priv->does_full_damage = TRUE; - } - - if (priv->freeze_count) - { - /* The window is frozen due to an effect in progress: we ignore damage - * here on the off chance that this will stop the corresponding - * texture_from_pixmap from being update. - * - * needs_damage_all tracks that some unknown damage happened while the - * window was frozen so that when the window becomes unfrozen we can - * issue a full window update to cover any lost damage. - * - * It should be noted that this is an unreliable mechanism since it's - * quite likely that drivers will aim to provide a zero-copy - * implementation of the texture_from_pixmap extension and in those cases - * any drawing done to the window is always immediately reflected in the - * texture regardless of damage event handling. - */ - priv->needs_damage_all = TRUE; - return; + meta_window_actor_thaw (self); } - - if (!priv->window->mapped || priv->needs_pixmap) - return; - - update_area (self, event->area.x, event->area.y, event->area.width, event->area.height); - priv->repaint_scheduled = meta_shaped_texture_update_area (META_SHAPED_TEXTURE (priv->actor), - event->area.x, - event->area.y, - event->area.width, - event->area.height, - clutter_actor_has_mapped_clones (priv->actor) ? NULL : priv->unobscured_region); } -LOCAL_SYMBOL void -meta_window_actor_sync_visibility (MetaWindowActor *self) +void +meta_window_actor_sync_updates_frozen (MetaWindowActor *self) { - MetaWindowActorPrivate *priv = self->priv; + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (self); + MetaWindow *window = priv->window; - if (CLUTTER_ACTOR_IS_VISIBLE (self) != priv->visible) - { - if (priv->visible) - clutter_actor_show (CLUTTER_ACTOR (self)); - else - clutter_actor_hide (CLUTTER_ACTOR (self)); - } + meta_window_actor_set_updates_frozen (self, meta_window_updates_are_frozen (window)); } -static inline void -set_integral_bounding_rect (cairo_rectangle_int_t *rect, - double x, double y, - double width, double height) +MetaWindowActor * +meta_window_actor_from_window (MetaWindow *window) { - rect->x = floor(x); - rect->y = floor(y); - rect->width = ceil(x + width) - rect->x; - rect->height = ceil(y + height) - rect->y; + return META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); } -static void -update_corners (MetaWindowActor *self) +void +meta_window_actor_set_geometry_scale (MetaWindowActor *window_actor, + int geometry_scale) { - MetaWindowActorPrivate *priv = self->priv; - MetaRectangle outer = priv->window->frame->rect; - MetaFrameBorders borders; - cairo_rectangle_int_t corner_rects[4]; - cairo_region_t *corner_region; - cairo_path_t *corner_path; - float top_left, top_right, bottom_left, bottom_right; - float x, y; - - /* need these to build a path */ - cairo_t *cr; - cairo_surface_t *surface; + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (window_actor); + CoglMatrix child_transform; - meta_frame_calc_borders (priv->window->frame, &borders); - - outer.width -= borders.invisible.left + borders.invisible.right; - outer.height -= borders.invisible.top + borders.invisible.bottom; - - meta_frame_get_corner_radiuses (priv->window->frame, - &top_left, - &top_right, - &bottom_left, - &bottom_right); - - /* Unfortunately, cairo does not allow us to create a context - * without a surface. Create a 0x0 image surface to "paint to" - * so we can get the path. */ - surface = cairo_image_surface_create (CAIRO_FORMAT_A8, - 0, 0); - - cr = cairo_create (surface); + if (priv->geometry_scale == geometry_scale) + return; - /* top left */ - x = borders.invisible.left; - y = borders.invisible.top; + priv->geometry_scale = geometry_scale; - set_integral_bounding_rect (&corner_rects[0], - x, y, top_left, top_left); + cogl_matrix_init_identity (&child_transform); + cogl_matrix_scale (&child_transform, geometry_scale, geometry_scale, 1); + clutter_actor_set_child_transform (CLUTTER_ACTOR (window_actor), + &child_transform); +} - cairo_arc (cr, - x + top_left, - y + top_left, - top_left, - 0, M_PI*2); +int +meta_window_actor_get_geometry_scale (MetaWindowActor *window_actor) +{ + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (window_actor); + return priv->geometry_scale; +} - /* top right */ - x = x + outer.width - top_right; +static void +meta_window_actor_get_buffer_bounds (MetaScreenCastWindow *screen_cast_window, + MetaRectangle *bounds) +{ + MetaWindowActor *window_actor = META_WINDOW_ACTOR (screen_cast_window); + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (window_actor); + MetaShapedTexture *stex; + int buffer_scale; - set_integral_bounding_rect (&corner_rects[1], - x, y, top_right, top_right); + stex = meta_surface_actor_get_texture (priv->surface); + buffer_scale = meta_shaped_texture_get_buffer_scale (stex); + *bounds = (MetaRectangle) { + .width = meta_shaped_texture_get_width (stex) * buffer_scale, + .height = meta_shaped_texture_get_height (stex) * buffer_scale, + }; +} - cairo_arc (cr, - x, - y + top_right, - top_right, - 0, M_PI*2); +static void +meta_window_actor_transform_relative_position (MetaScreenCastWindow *screen_cast_window, + double x, + double y, + double *x_out, + double *y_out) - /* bottom right */ - x = borders.invisible.left + outer.width - bottom_right; - y = y + outer.height - bottom_right; +{ + MetaWindowActor *window_actor = META_WINDOW_ACTOR (screen_cast_window); + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (window_actor); + MetaRectangle bounds; + graphene_point3d_t v1 = { 0.f, }, v2 = { 0.f, }; - set_integral_bounding_rect (&corner_rects[2], - x, y, bottom_right, bottom_right); + meta_window_actor_get_buffer_bounds (screen_cast_window, &bounds); - cairo_arc (cr, - x, - y, - bottom_right, - 0, M_PI*2); + v1.x = CLAMP ((float) x, + bounds.x, + bounds.x + bounds.width); + v1.y = CLAMP ((float) y, + bounds.y, + bounds.y + bounds.height); - /* bottom left */ - x = borders.invisible.left; - y = borders.invisible.top + outer.height - bottom_left; + clutter_actor_apply_transform_to_point (CLUTTER_ACTOR (priv->surface), + &v1, + &v2); - set_integral_bounding_rect (&corner_rects[3], - x, y, bottom_left, bottom_left); + *x_out = (double) v2.x; + *y_out = (double) v2.y; +} - cairo_arc (cr, - x + bottom_left, - y, - bottom_left, - 0, M_PI*2); +static gboolean +meta_window_actor_transform_cursor_position (MetaScreenCastWindow *screen_cast_window, + MetaCursorSprite *cursor_sprite, + graphene_point_t *cursor_position, + float *out_cursor_scale, + graphene_point_t *out_relative_cursor_position) +{ + MetaWindowActor *window_actor = META_WINDOW_ACTOR (screen_cast_window); + MetaWindowActorPrivate *priv = + meta_window_actor_get_instance_private (window_actor); + MetaWindow *window; - corner_path = cairo_copy_path (cr); + window = priv->window; + if (!meta_window_has_pointer (window)) + return FALSE; - cairo_surface_destroy (surface); - cairo_destroy (cr); + if (cursor_sprite && + meta_cursor_sprite_get_cogl_texture (cursor_sprite) && + out_cursor_scale) + { + MetaShapedTexture *stex; + double texture_scale; + float cursor_texture_scale; - corner_region = cairo_region_create_rectangles (corner_rects, 4); + stex = meta_surface_actor_get_texture (priv->surface); + texture_scale = meta_shaped_texture_get_buffer_scale (stex); + cursor_texture_scale = meta_cursor_sprite_get_texture_scale (cursor_sprite); - meta_shaped_texture_set_overlay_path (META_SHAPED_TEXTURE (priv->actor), - corner_region, corner_path); + *out_cursor_scale = texture_scale / cursor_texture_scale; + } + if (out_relative_cursor_position) + { + clutter_actor_transform_stage_point (CLUTTER_ACTOR (priv->surface), + cursor_position->x, + cursor_position->y, + &out_relative_cursor_position->x, + &out_relative_cursor_position->y); + } - cairo_region_destroy (corner_region); + return TRUE; } static void -check_needs_reshape (MetaWindowActor *self) -{ - MetaWindowActorPrivate *priv = self->priv; - MetaScreen *screen = priv->screen; - MetaDisplay *display = meta_screen_get_display (screen); - cairo_region_t *region = NULL; - cairo_rectangle_int_t client_area; - gboolean full_mask_reset = priv->window->fullscreen; - - if ((!priv->window->mapped && !priv->window->shaded) || !priv->needs_reshape) +meta_window_actor_capture_into (MetaScreenCastWindow *screen_cast_window, + MetaRectangle *bounds, + uint8_t *data) +{ + MetaWindowActor *window_actor = META_WINDOW_ACTOR (screen_cast_window); + cairo_surface_t *image; + uint8_t *cr_data; + int cr_stride; + int cr_width; + int cr_height; + int bpp = 4; + + if (meta_window_actor_is_destroyed (window_actor)) return; - g_clear_pointer (&priv->shape_region, cairo_region_destroy); - g_clear_pointer (&priv->shadow_shape, meta_window_shape_unref); - g_clear_pointer (&priv->opaque_region, cairo_region_destroy); - - meta_window_get_client_area_rect (priv->window, &client_area); - - if (priv->window->frame) - region = meta_window_get_frame_bounds (priv->window); + image = meta_window_actor_get_image (window_actor, bounds); + cr_data = cairo_image_surface_get_data (image); + cr_width = cairo_image_surface_get_width (image); + cr_height = cairo_image_surface_get_height (image); + cr_stride = cairo_image_surface_get_stride (image); - if (region != NULL) + if (cr_width == bounds->width && cr_height == bounds->height) { - /* This returns the window's internal frame bounds region, - * so we need to copy it because we modify it below. */ - region = cairo_region_copy (region); + memcpy (data, cr_data, cr_height * cr_stride); } else { - /* If we have no region, we have no frame. We have no frame, - * so just use the client_area instead */ - region = cairo_region_create_rectangle (&client_area); - } + int width = MIN (bounds->width, cr_width); + int height = MIN (bounds->height, cr_height); + int stride = width * bpp; + uint8_t *src, *dst; -#ifdef HAVE_SHAPE - if (priv->window->has_shape) - { - Display *xdisplay = meta_display_get_xdisplay (display); - XRectangle *rects; - int n_rects, ordering; - - /* Punch out client area. */ - cairo_region_subtract_rectangle (region, &client_area); - - meta_error_trap_push (display); - rects = XShapeGetRectangles (xdisplay, - priv->window->xwindow, - ShapeBounding, - &n_rects, - &ordering); - meta_error_trap_pop (display); - - if (rects) + src = cr_data; + dst = data; + + for (int i = 0; i < height; i++) + { + memcpy (dst, src, stride); + if (width < bounds->width) + memset (dst + stride, 0, (bounds->width * bpp) - stride); + + src += cr_stride; + dst += bounds->width * bpp; + } + + for (int i = height; i < bounds->height; i++) { - int i; - for (i = 0; i < n_rects; i ++) - { - cairo_rectangle_int_t rect = { rects[i].x + client_area.x, - rects[i].y + client_area.y, - rects[i].width, - rects[i].height }; - cairo_region_union_rectangle (region, &rect); - } - XFree (rects); + memset (dst, 0, bounds->width * bpp); + dst += bounds->width * bpp; } } -#endif - if (priv->argb32 && priv->window->opaque_region != NULL) - { - /* The opaque region is defined to be a part of the - * window which ARGB32 will always paint with opaque - * pixels. For these regions, we want to avoid painting - * windows and shadows beneath them. - * - * If the client gives bad coordinates where it does not - * fully paint, the behavior is defined by the specification - * to be undefined, and considered a client bug. In mutter's - * case, graphical glitches will occur. - */ - priv->opaque_region = cairo_region_copy (priv->window->opaque_region); - cairo_region_translate (priv->opaque_region, client_area.x, client_area.y); - cairo_region_intersect (priv->opaque_region, region); - } - else if (priv->argb32) - priv->opaque_region = NULL; - else - priv->opaque_region = cairo_region_reference (region); + cairo_surface_destroy (image); +} - if (priv->window->frame) - update_corners (self); - else if (priv->window->has_shape && priv->reshapes == 1) - full_mask_reset = TRUE; - else if (priv->reshapes < 2) - priv->reshapes++; +static gboolean +meta_window_actor_blit_to_framebuffer (MetaScreenCastWindow *screen_cast_window, + MetaRectangle *bounds, + CoglFramebuffer *framebuffer) +{ + MetaWindowActor *window_actor = META_WINDOW_ACTOR (screen_cast_window); + ClutterActor *actor = CLUTTER_ACTOR (window_actor); + ClutterPaintContext *paint_context; + MetaRectangle scaled_clip; + CoglColor clear_color; + float resource_scale; + float width, height; + float x, y; - if (priv->window->frame != NULL || priv->window->has_shape) - meta_window_actor_reset_mask_texture (self, region, full_mask_reset); + if (meta_window_actor_is_destroyed (window_actor)) + return FALSE; - meta_window_actor_update_shape_region (self, region); + clutter_actor_get_size (actor, &width, &height); - cairo_region_destroy (region); + if (width == 0 || height == 0) + return FALSE; - priv->needs_reshape = FALSE; - meta_window_actor_invalidate_shadow (self); -} + if (!clutter_actor_get_resource_scale (actor, &resource_scale)) + return FALSE; -LOCAL_SYMBOL void -meta_window_actor_update_shape (MetaWindowActor *self) -{ - MetaWindowActorPrivate *priv = self->priv; + clutter_actor_inhibit_culling (actor); - priv->needs_reshape = TRUE; + width = ceilf (width * resource_scale); + height = ceilf (height * resource_scale); - if (is_frozen (self)) - return; + clutter_actor_get_position (actor, &x, &y); - clutter_actor_queue_redraw (priv->actor); -} + cogl_color_init_from_4ub (&clear_color, 0, 0, 0, 0); + cogl_framebuffer_clear (framebuffer, COGL_BUFFER_BIT_COLOR, &clear_color); + cogl_framebuffer_orthographic (framebuffer, 0, 0, width, height, 0, 1.0); + cogl_framebuffer_set_viewport (framebuffer, 0, 0, width, height); -LOCAL_SYMBOL void -meta_window_actor_handle_updates (MetaWindowActor *self) -{ - MetaWindowActorPrivate *priv = self->priv; - MetaScreen *screen = priv->screen; - MetaDisplay *display = meta_screen_get_display (screen); - Display *xdisplay = meta_display_get_xdisplay (display); + meta_rectangle_scale_double (bounds, resource_scale, + META_ROUNDING_STRATEGY_GROW, + &scaled_clip); + meta_rectangle_intersect (&scaled_clip, + &(MetaRectangle) { + .width = width, + .height = height, + }, + &scaled_clip); - if (is_frozen (self)) - { - /* The window is frozen due to a pending animation: we'll wait until - * the animation finishes to reshape and repair the window */ - return; - } + cogl_framebuffer_push_rectangle_clip (framebuffer, + scaled_clip.x, scaled_clip.y, + scaled_clip.x + scaled_clip.width, + scaled_clip.y + scaled_clip.height); - if (priv->unredirected) - { - /* Nothing to do here until/if the window gets redirected again */ - return; - } + cogl_framebuffer_push_matrix (framebuffer); + cogl_framebuffer_scale (framebuffer, resource_scale, resource_scale, 1); + cogl_framebuffer_translate (framebuffer, -x, -y, 0); - if (!priv->visible && !priv->needs_pixmap) - return; + paint_context = clutter_paint_context_new_for_framebuffer (framebuffer); + clutter_actor_paint (actor, paint_context); + clutter_paint_context_destroy (paint_context); - if (priv->received_damage) - { - meta_error_trap_push (display); - XDamageSubtract (xdisplay, priv->damage, None, None); - meta_error_trap_pop (display); + cogl_framebuffer_pop_matrix (framebuffer); + cogl_framebuffer_pop_clip (framebuffer); - priv->received_damage = FALSE; - } + clutter_actor_uninhibit_culling (actor); - check_needs_pixmap (self); - check_needs_reshape (self); - check_needs_shadow (self); + return TRUE; } -void -meta_window_actor_pre_paint (MetaWindowActor *self) +static gboolean +meta_window_actor_has_damage (MetaScreenCastWindow *screen_cast_window) { - if (meta_window_actor_is_destroyed (self)) - return; - - meta_window_actor_handle_updates (self); - - assign_frame_counter_to_frames (self); + return clutter_actor_has_damage (CLUTTER_ACTOR (screen_cast_window)); } static void -do_send_frame_drawn (MetaWindowActor *self, FrameData *frame) +screen_cast_window_iface_init (MetaScreenCastWindowInterface *iface) { - MetaWindowActorPrivate *priv = self->priv; - MetaDisplay *display = meta_screen_get_display (priv->screen); - MetaWindow *window = meta_window_actor_get_meta_window (self); - Display *xdisplay = meta_display_get_xdisplay (display); - - XClientMessageEvent ev = { 0, }; - - frame->frame_drawn_time = meta_compositor_monotonic_time_to_server_time (display, - g_get_monotonic_time ()); - priv->frame_drawn_time = frame->frame_drawn_time; - - ev.type = ClientMessage; - ev.window = meta_window_get_xwindow (window); - ev.message_type = display->atom__NET_WM_FRAME_DRAWN; - ev.format = 32; - ev.data.l[0] = frame->sync_request_serial & G_GUINT64_CONSTANT(0xffffffff); - ev.data.l[1] = frame->sync_request_serial >> 32; - ev.data.l[2] = frame->frame_drawn_time & G_GUINT64_CONSTANT(0xffffffff); - ev.data.l[3] = frame->frame_drawn_time >> 32; - - meta_error_trap_push (display); - XSendEvent (xdisplay, ev.window, False, 0, (XEvent*) &ev); - XFlush (xdisplay); - meta_error_trap_pop (display); + iface->get_buffer_bounds = meta_window_actor_get_buffer_bounds; + iface->transform_relative_position = meta_window_actor_transform_relative_position; + iface->transform_cursor_position = meta_window_actor_transform_cursor_position; + iface->capture_into = meta_window_actor_capture_into; + iface->blit_to_framebuffer = meta_window_actor_blit_to_framebuffer; + iface->has_damage = meta_window_actor_has_damage; } +MetaWindowActor * +meta_window_actor_from_actor (ClutterActor *actor) +{ + if (!META_IS_SURFACE_ACTOR (actor)) + return NULL; + + do + { + actor = clutter_actor_get_parent (actor); + + if (META_IS_WINDOW_ACTOR (actor)) + return META_WINDOW_ACTOR (actor); + } + while (actor != NULL); + + return NULL; +} void -meta_window_actor_post_paint (MetaWindowActor *self) +meta_window_actor_notify_damaged (MetaWindowActor *window_actor) { - MetaWindowActorPrivate *priv = self->priv; + g_signal_emit (window_actor, signals[DAMAGED], 0); +} + +/** + * meta_window_actor_get_image: + * @self: A #MetaWindowActor + * @clip: (nullable): A clipping rectangle, to help prevent extra processing. + * In the case that the clipping rectangle is partially or fully + * outside the bounds of the actor, the rectangle will be clipped. + * + * Flattens the layers of @self into one ARGB32 image by alpha blending + * the images, and returns the flattened image. + * + * Returns: (nullable) (transfer full): a new cairo surface to be freed with + * cairo_surface_destroy(). + */ +cairo_surface_t * +meta_window_actor_get_image (MetaWindowActor *self, + MetaRectangle *clip) +{ + MetaWindowActorPrivate *priv = meta_window_actor_get_instance_private (self); + ClutterActor *actor = CLUTTER_ACTOR (self); + MetaBackend *backend = meta_get_backend (); + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + CoglContext *cogl_context = + clutter_backend_get_cogl_context (clutter_backend); + float resource_scale; + float width, height; + CoglTexture2D *texture; + g_autoptr (GError) error = NULL; + CoglOffscreen *offscreen; + CoglFramebuffer *framebuffer; + CoglColor clear_color; + float x, y; + MetaRectangle scaled_clip; + ClutterPaintContext *paint_context; + cairo_surface_t *surface = NULL; - priv->repaint_scheduled = FALSE; + if (!priv->surface) + return NULL; - if (meta_window_actor_is_destroyed (self)) - return; + clutter_actor_inhibit_culling (actor); - /* If the window had damage, but wasn't actually redrawn because - * it is obscured, we should wait until timer expiration before - * sending _NET_WM_FRAME_* messages. - */ - if (priv->send_frame_messages_timer == 0 && - priv->needs_frame_drawn) + if (clutter_actor_get_n_children (actor) == 1) { - GList *l; + MetaShapedTexture *stex; + MetaRectangle *surface_clip = NULL; - for (l = priv->frames; l; l = l->next) + if (clip) { - FrameData *frame = l->data; - if (frame->frame_drawn_time == 0) - do_send_frame_drawn (self, frame); - } - - priv->needs_frame_drawn = FALSE; - } -} + int geometry_scale; -static void -do_send_frame_timings (MetaWindowActor *self, - FrameData *frame, - gint refresh_interval, - gint64 presentation_time) -{ - MetaWindowActorPrivate *priv = self->priv; - MetaDisplay *display = meta_screen_get_display (priv->screen); - MetaWindow *window = meta_window_actor_get_meta_window (self); - Display *xdisplay = meta_display_get_xdisplay (display); + geometry_scale = + meta_window_actor_get_geometry_scale (self); - XClientMessageEvent ev = { 0, }; - - ev.type = ClientMessage; - ev.window = meta_window_get_xwindow (window); - ev.message_type = display->atom__NET_WM_FRAME_TIMINGS; - ev.format = 32; - ev.data.l[0] = frame->sync_request_serial & G_GUINT64_CONSTANT(0xffffffff); - ev.data.l[1] = frame->sync_request_serial >> 32; + surface_clip = g_alloca (sizeof (MetaRectangle)); + surface_clip->x = clip->x / geometry_scale, + surface_clip->y = clip->y / geometry_scale; + surface_clip->width = clip->width / geometry_scale; + surface_clip->height = clip->height / geometry_scale; + } - if (presentation_time != 0) - { - gint64 presentation_time_server = meta_compositor_monotonic_time_to_server_time (display, - presentation_time); - gint64 presentation_time_offset = presentation_time_server - frame->frame_drawn_time; - if (presentation_time_offset == 0) - presentation_time_offset = 1; - - if ((gint32)presentation_time_offset == presentation_time_offset) - ev.data.l[2] = presentation_time_offset; + stex = meta_surface_actor_get_texture (priv->surface); + surface = meta_shaped_texture_get_image (stex, surface_clip); + goto out; } - ev.data.l[3] = refresh_interval; - ev.data.l[4] = 1000 * META_SYNC_DELAY; + clutter_actor_get_size (actor, &width, &height); - meta_error_trap_push (display); - XSendEvent (xdisplay, ev.window, False, 0, (XEvent*) &ev); - XFlush (xdisplay); - meta_error_trap_pop (display); -} + if (width == 0 || height == 0) + goto out; -static void -send_frame_timings (MetaWindowActor *self, - FrameData *frame, - CoglFrameInfo *frame_info, - gint64 presentation_time) -{ - MetaWindow *window = meta_window_actor_get_meta_window (self); - float refresh_rate; - int refresh_interval; - - refresh_rate = window->monitor->refresh_rate; - /* 0.0 is a flag for not known, but sanity-check against other odd numbers */ - if (refresh_rate >= 1.0) - refresh_interval = (int) (0.5 + 1000000 / refresh_rate); - else - refresh_interval = 0; + if (!clutter_actor_get_resource_scale (actor, &resource_scale)) + goto out; - do_send_frame_timings (self, frame, refresh_interval, presentation_time); -} + width = ceilf (width * resource_scale); + height = ceilf (height * resource_scale); -void -meta_window_actor_frame_complete (MetaWindowActor *self, - ClutterFrameInfo *frame_info, - gint64 presentation_time) -{ - MetaWindowActorPrivate *priv = self->priv; - GList *l; + texture = cogl_texture_2d_new_with_size (cogl_context, width, height); + if (!texture) + goto out; - if (meta_window_actor_is_destroyed (self)) - return; + cogl_primitive_texture_set_auto_mipmap (COGL_PRIMITIVE_TEXTURE (texture), + FALSE); - for (l = priv->frames; l;) - { - GList *l_next = l->next; - FrameData *frame = l->data; - gint64 frame_counter = frame_info->frame_counter; + offscreen = cogl_offscreen_new_with_texture (COGL_TEXTURE (texture)); + framebuffer = COGL_FRAMEBUFFER (offscreen); - if (frame->frame_counter != -1 && frame->frame_counter <= frame_counter) - { - if (G_UNLIKELY (frame->frame_drawn_time == 0)) - g_warning ("%s: Frame has assigned frame counter but no frame drawn time", - priv->window->desc); - if (G_UNLIKELY (frame->frame_counter < frame_counter)) - g_warning ("%s: frame_complete callback never occurred for frame %" G_GINT64_FORMAT, - priv->window->desc, frame->frame_counter); - - priv->frames = g_list_delete_link (priv->frames, l); - send_frame_timings (self, frame, frame_info, presentation_time); - frame_data_free (frame); - } + cogl_object_unref (texture); - l = l_next; + if (!cogl_framebuffer_allocate (framebuffer, &error)) + { + g_warning ("Failed to allocate framebuffer for screenshot: %s", + error->message); + cogl_object_unref (framebuffer); + cogl_object_unref (texture); + goto out; } -} - -LOCAL_SYMBOL void -meta_window_actor_invalidate_shadow (MetaWindowActor *self) -{ - MetaWindowActorPrivate *priv = self->priv; - priv->recompute_focused_shadow = TRUE; - priv->recompute_unfocused_shadow = TRUE; + cogl_color_init_from_4ub (&clear_color, 0, 0, 0, 0); + clutter_actor_get_position (actor, &x, &y); - if (is_frozen (self)) - return; + cogl_framebuffer_clear (framebuffer, COGL_BUFFER_BIT_COLOR, &clear_color); + cogl_framebuffer_orthographic (framebuffer, 0, 0, width, height, 0, 1.0); + cogl_framebuffer_scale (framebuffer, resource_scale, resource_scale, 1); + cogl_framebuffer_translate (framebuffer, -x, -y, 0); - clutter_actor_queue_redraw (CLUTTER_ACTOR (self)); -} + paint_context = clutter_paint_context_new_for_framebuffer (framebuffer); + clutter_actor_paint (actor, paint_context); + clutter_paint_context_destroy (paint_context); -LOCAL_SYMBOL void -meta_window_actor_update_opacity (MetaWindowActor *self) -{ - MetaWindowActorPrivate *priv = self->priv; - MetaDisplay *display = meta_screen_get_display (priv->screen); - MetaCompositor *compositor = meta_display_get_compositor (display); - Window xwin = meta_window_get_xwindow (priv->window); - gulong value; - guint8 opacity; - - if (meta_prop_get_cardinal (display, xwin, - compositor->atom_net_wm_window_opacity, - &value)) + if (clip) { - opacity = (guint8)((gfloat)value * 255.0 / ((gfloat)0xffffffff)); + meta_rectangle_scale_double (clip, resource_scale, + META_ROUNDING_STRATEGY_GROW, + &scaled_clip); + meta_rectangle_intersect (&scaled_clip, + &(MetaRectangle) { + .width = width, + .height = height, + }, + &scaled_clip); } else - opacity = 255; + { + scaled_clip = (MetaRectangle) { + .width = width, + .height = height, + }; + } - self->priv->opacity = opacity; - clutter_actor_set_opacity (self->priv->actor, opacity); -} + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, + scaled_clip.width, scaled_clip.height); + cogl_framebuffer_read_pixels (framebuffer, + scaled_clip.x, scaled_clip.y, + scaled_clip.width, scaled_clip.height, + CLUTTER_CAIRO_FORMAT_ARGB32, + cairo_image_surface_get_data (surface)); -void -meta_window_actor_set_updates_frozen (MetaWindowActor *self, - gboolean updates_frozen) -{ - MetaWindowActorPrivate *priv = self->priv; + cogl_object_unref (framebuffer); - updates_frozen = updates_frozen != FALSE; + cairo_surface_mark_dirty (surface); - if (priv->updates_frozen != updates_frozen) - { - priv->updates_frozen = updates_frozen; - if (updates_frozen) - meta_window_actor_freeze (self); - else - meta_window_actor_thaw (self); - } +out: + clutter_actor_uninhibit_culling (actor); + return surface; } diff --git a/src/compositor/meta-window-group-private.h b/src/compositor/meta-window-group-private.h new file mode 100644 index 000000000..c3467066b --- /dev/null +++ b/src/compositor/meta-window-group-private.h @@ -0,0 +1,23 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +#ifndef META_WINDOW_GROUP_PRIVATE_H +#define META_WINDOW_GROUP_PRIVATE_H + +#include "meta/display.h" +#include "meta/meta-window-group.h" + +/** + * MetaWindowGroup: + * + * This class is a subclass of ClutterActor with special handling for + * #MetaCullable when painting children. It uses code similar to + * meta_cullable_cull_out_children(), but also has additional special + * cases for the undirected window, and similar. + */ + + +typedef struct _MetaWindowGroupPrivate MetaWindowGroupPrivate; + +ClutterActor *meta_window_group_new (MetaDisplay *display); + +#endif /* META_WINDOW_GROUP_PRIVATE_H */ diff --git a/src/compositor/meta-window-group.c b/src/compositor/meta-window-group.c index 2aa367e8c..d526805fe 100644 --- a/src/compositor/meta-window-group.c +++ b/src/compositor/meta-window-group.c @@ -1,19 +1,17 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -#include <config.h> +#include "config.h" -#define _ISOC99_SOURCE /* for roundf */ +#include <gdk/gdk.h> #include <math.h> -#include <gdk/gdk.h> /* for gdk_rectangle_intersect() */ - -#include <core/screen-private.h> - -#include "clutter-utils.h" -#include "compositor-private.h" -#include "meta-window-actor-private.h" -#include "meta-window-group.h" -#include "meta-background-actor-private.h" +#include "compositor/clutter-utils.h" +#include "compositor/compositor-private.h" +#include "compositor/meta-cullable.h" +#include "compositor/meta-window-actor-private.h" +#include "compositor/meta-window-group-private.h" +#include "core/display-private.h" +#include "core/window-private.h" struct _MetaWindowGroupClass { @@ -24,212 +22,59 @@ struct _MetaWindowGroup { ClutterActor parent; - MetaScreen *screen; + MetaDisplay *display; }; -G_DEFINE_TYPE (MetaWindowGroup, meta_window_group, CLUTTER_TYPE_ACTOR); +static void cullable_iface_init (MetaCullableInterface *iface); -/* Help macros to scale from OpenGL <-1,1> coordinates system to - * window coordinates ranging [0,window-size]. Borrowed from clutter-utils.c - */ -#define MTX_GL_SCALE_X(x,w,v1,v2) ((((((x) / (w)) + 1.0f) / 2.0f) * (v1)) + (v2)) -#define MTX_GL_SCALE_Y(y,w,v1,v2) ((v1) - (((((y) / (w)) + 1.0f) / 2.0f) * (v1)) + (v2)) +G_DEFINE_TYPE_WITH_CODE (MetaWindowGroup, meta_window_group, CLUTTER_TYPE_ACTOR, + G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init)); -/* Check if we're painting the MetaWindowGroup "untransformed". This can - * differ from the result of actor_is_untransformed(window_group) if we're - * inside a clone paint. The integer translation, if any, is returned. - */ -static gboolean -painting_untransformed (MetaWindowGroup *window_group, - int *x_origin, - int *y_origin) +static void +meta_window_group_cull_out (MetaCullable *cullable, + cairo_region_t *unobscured_region, + cairo_region_t *clip_region) { - CoglMatrix modelview, projection, modelview_projection; - ClutterVertex vertices[4]; - int width, height; - float viewport[4]; - int i; - - cogl_get_modelview_matrix (&modelview); - cogl_get_projection_matrix (&projection); - - cogl_matrix_multiply (&modelview_projection, - &projection, - &modelview); - - meta_screen_get_size (window_group->screen, &width, &height); - - vertices[0].x = 0; - vertices[0].y = 0; - vertices[0].z = 0; - vertices[1].x = width; - vertices[1].y = 0; - vertices[1].z = 0; - vertices[2].x = 0; - vertices[2].y = height; - vertices[2].z = 0; - vertices[3].x = width; - vertices[3].y = height; - vertices[3].z = 0; - - cogl_get_viewport (viewport); - - for (i = 0; i < 4; i++) - { - float w = 1; - cogl_matrix_transform_point (&modelview_projection, &vertices[i].x, &vertices[i].y, &vertices[i].z, &w); - vertices[i].x = MTX_GL_SCALE_X (vertices[i].x, w, - viewport[2], viewport[0]); - vertices[i].y = MTX_GL_SCALE_Y (vertices[i].y, w, - viewport[3], viewport[1]); - } - - return meta_actor_vertices_are_untransformed (vertices, width, height, x_origin, y_origin); + meta_cullable_cull_out_children (cullable, unobscured_region, clip_region); } static void -meta_window_group_cull_out (MetaWindowGroup *group, - ClutterActor *unredirected_window, - gboolean has_unredirected_window, - cairo_region_t *unobscured_region, - cairo_region_t *clip_region) +meta_window_group_reset_culling (MetaCullable *cullable) { - ClutterActor *actor = CLUTTER_ACTOR (group); - ClutterActor *child; - ClutterActorIter iter; - - /* We walk the list from top to bottom (opposite of painting order), - * and subtract the opaque area of each window out of the visible - * region that we pass to the windows below. - */ - clutter_actor_iter_init (&iter, actor); - while (clutter_actor_iter_prev (&iter, &child)) - { - if (!CLUTTER_ACTOR_IS_VISIBLE (child)) - continue; - - if (has_unredirected_window && child == unredirected_window) - continue; - - /* If an actor has effects applied, then that can change the area - * it paints and the opacity, so we no longer can figure out what - * portion of the actor is obscured and what portion of the screen - * it obscures, so we skip the actor. - * - * This has a secondary beneficial effect: if a ClutterOffscreenEffect - * is applied to an actor, then our clipped redraws interfere with the - * caching of the FBO - even if we only need to draw a small portion - * of the window right now, ClutterOffscreenEffect may use other portions - * of the FBO later. So, skipping actors with effects applied also - * prevents these bugs. - * - * Theoretically, we should check clutter_actor_get_offscreen_redirect() - * as well for the same reason, but omitted for simplicity in the - * hopes that no-one will do that. - */ - if (clutter_actor_has_effects (child)) - continue; - - if (META_IS_WINDOW_ACTOR (child)) - { - MetaWindowActor *window_actor = META_WINDOW_ACTOR (child); - int x, y; - - if (!meta_actor_is_untransformed (CLUTTER_ACTOR (window_actor), &x, &y)) - continue; - - /* Temporarily move to the coordinate system of the actor */ - cairo_region_translate (unobscured_region, - x, - y); - cairo_region_translate (clip_region, - x, - y); - - meta_window_actor_set_unobscured_region (window_actor, unobscured_region); - meta_window_actor_set_visible_region (window_actor, clip_region); - - if (clutter_actor_get_paint_opacity (CLUTTER_ACTOR (window_actor)) == 0xff) - { - cairo_region_t *obscured_region = meta_window_actor_get_obscured_region (window_actor); - if (obscured_region) - { - cairo_region_subtract (unobscured_region, obscured_region); - cairo_region_subtract (clip_region, obscured_region); - } - } - - meta_window_actor_set_visible_region_beneath (window_actor, clip_region); - - cairo_region_translate (unobscured_region, x, y); - cairo_region_translate (clip_region, x, y); - } - else if (META_IS_BACKGROUND_ACTOR (child)) - { - int x, y; - - if (!meta_actor_is_untransformed (child, &x, &y)) - continue; - - cairo_region_translate (clip_region, - x, - y); - - meta_background_actor_set_visible_region (META_BACKGROUND_ACTOR (child), clip_region); - - cairo_region_translate (clip_region, x, y); - } - } + meta_cullable_reset_culling_children (cullable); } static void -meta_window_group_reset_culling (MetaWindowGroup *group) +cullable_iface_init (MetaCullableInterface *iface) { - ClutterActor *actor = CLUTTER_ACTOR (group); - ClutterActor *child; - ClutterActorIter iter; - - /* Now that we are done painting, unset the visible regions (they will - * mess up painting clones of our actors) - */ - clutter_actor_iter_init (&iter, actor); - while (clutter_actor_iter_next (&iter, &child)) - { - if (META_IS_WINDOW_ACTOR (child)) - { - MetaWindowActor *window_actor = META_WINDOW_ACTOR (child); - meta_window_actor_reset_visible_regions (window_actor); - } - else if (META_IS_BACKGROUND_ACTOR (child)) - { - MetaBackgroundActor *background_actor = META_BACKGROUND_ACTOR (child); - meta_background_actor_set_visible_region (background_actor, NULL); - } - } + iface->cull_out = meta_window_group_cull_out; + iface->reset_culling = meta_window_group_reset_culling; } static void -meta_window_group_paint (ClutterActor *actor) +meta_window_group_paint (ClutterActor *actor, + ClutterPaintContext *paint_context) { + MetaWindowGroup *window_group = META_WINDOW_GROUP (actor); + ClutterActorClass *parent_actor_class = + CLUTTER_ACTOR_CLASS (meta_window_group_parent_class); + ClutterActor *stage = clutter_actor_get_stage (actor); + const cairo_region_t *redraw_clip; cairo_region_t *clip_region; cairo_region_t *unobscured_region; - ClutterActorIter iter; - ClutterActor *child; - cairo_rectangle_int_t visible_rect, clip_rect; - int paint_x_offset, paint_y_offset; + cairo_rectangle_int_t visible_rect; int paint_x_origin, paint_y_origin; - int actor_x_origin, actor_y_origin; - - MetaWindowGroup *window_group = META_WINDOW_GROUP (actor); - MetaCompositor *compositor = window_group->screen->display->compositor; - ClutterActor *stage = CLUTTER_STAGE (compositor->stage); + int screen_width, screen_height; - /* Start off by treating all windows as completely unobscured, so damage anywhere - * in a window queues redraws, but confine it more below. */ - clutter_actor_iter_init (&iter, actor); - while (clutter_actor_iter_next (&iter, &child)) + redraw_clip = clutter_paint_context_get_redraw_clip (paint_context); + if (!redraw_clip) { - if (META_IS_WINDOW_ACTOR (child)) - { - MetaWindowActor *window_actor = META_WINDOW_ACTOR (child); - meta_window_actor_set_unobscured_region (window_actor, NULL); - } + parent_actor_class->paint (actor, paint_context); + return; } + meta_display_get_size (window_group->display, &screen_width, &screen_height); + /* Normally we expect an actor to be drawn at it's position on the screen. * However, if we're inside the paint of a ClutterClone, that won't be the * case and we need to compensate. We look at the position of the window @@ -243,64 +88,109 @@ meta_window_group_paint (ClutterActor *actor) * painting currently, and never worry about how actors are positioned * on the stage. */ - if (!painting_untransformed (window_group, &paint_x_origin, &paint_y_origin) || - !meta_actor_is_untransformed (actor, &actor_x_origin, &actor_y_origin)) + if (clutter_actor_is_in_clone_paint (actor)) { - CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor); - return; + CoglFramebuffer *fb; + + fb = clutter_paint_context_get_framebuffer (paint_context); + if (!meta_actor_painting_untransformed (fb, + screen_width, + screen_height, + screen_width, + screen_height, + &paint_x_origin, + &paint_y_origin) || + !meta_cullable_is_untransformed (META_CULLABLE (actor))) + { + parent_actor_class->paint (actor, paint_context); + return; + } + } + else + { + paint_x_origin = 0; + paint_y_origin = 0; } - - paint_x_offset = paint_x_origin - actor_x_origin; - paint_y_offset = paint_y_origin - actor_y_origin; visible_rect.x = visible_rect.y = 0; - visible_rect.width = clutter_actor_get_width (stage); - visible_rect.height = clutter_actor_get_height (stage); + visible_rect.width = clutter_actor_get_width (CLUTTER_ACTOR (stage)); + visible_rect.height = clutter_actor_get_height (CLUTTER_ACTOR (stage)); unobscured_region = cairo_region_create_rectangle (&visible_rect); - /* Get the clipped redraw bounds from Clutter so that we can avoid - * painting shadows on windows that don't need to be painted in this - * frame. In the case of a multihead setup with mismatched monitor - * sizes, we could intersect this with an accurate union of the - * monitors to avoid painting shadows that are visible only in the - * holes. */ - clutter_stage_get_redraw_clip_bounds (stage, &clip_rect); - - clip_region = cairo_region_create_rectangle (&clip_rect); - - cairo_region_translate (clip_region, -paint_x_offset, -paint_y_offset); - - gboolean has_unredirected_window = compositor->unredirected_window != NULL; - if (has_unredirected_window) - { - cairo_rectangle_int_t unredirected_rect; - MetaWindow *window = meta_window_actor_get_meta_window (compositor->unredirected_window); + /* Get the clipped redraw bounds so that we can avoid painting shadows on + * windows that don't need to be painted in this frame. In the case of a + * multihead setup with mismatched monitor sizes, we could intersect this + * with an accurate union of the monitors to avoid painting shadows that are + * visible only in the holes. */ + clip_region = cairo_region_copy (redraw_clip); - meta_window_get_outer_rect (window, (MetaRectangle *)&unredirected_rect); - cairo_region_subtract_rectangle (unobscured_region, &unredirected_rect); - cairo_region_subtract_rectangle (clip_region, &unredirected_rect); - } + cairo_region_translate (clip_region, -paint_x_origin, -paint_y_origin); - meta_window_group_cull_out (window_group, - CLUTTER_ACTOR (compositor->unredirected_window), - has_unredirected_window, - unobscured_region, - clip_region); + meta_cullable_cull_out (META_CULLABLE (window_group), unobscured_region, clip_region); cairo_region_destroy (unobscured_region); cairo_region_destroy (clip_region); - CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor); + parent_actor_class->paint (actor, paint_context); - meta_window_group_reset_culling (window_group); + meta_cullable_reset_culling (META_CULLABLE (window_group)); } +/* Adapted from clutter_actor_update_default_paint_volume() */ static gboolean -meta_window_group_get_paint_volume (ClutterActor *actor, +meta_window_group_get_paint_volume (ClutterActor *self, ClutterPaintVolume *volume) { - return clutter_paint_volume_set_from_allocation (volume, actor); + ClutterActorIter iter; + ClutterActor *child; + + clutter_actor_iter_init (&iter, self); + while (clutter_actor_iter_next (&iter, &child)) + { + const ClutterPaintVolume *child_volume; + + if (!CLUTTER_ACTOR_IS_MAPPED (child)) + continue; + + child_volume = clutter_actor_get_transformed_paint_volume (child, self); + if (child_volume == NULL) + return FALSE; + + clutter_paint_volume_union (volume, child_volume); + } + + return TRUE; +} + +/* This is a workaround for Clutter's awful allocation tracking. + * Without this, any time the window group changed size, which is + * any time windows are dragged around, we'll do a full repaint + * of the window group, which includes the background actor, meaning + * a full-stage repaint. + * + * Since actors are allowed to paint outside their allocation, and + * since child actors are allowed to be outside their parents, this + * doesn't affect anything, but it means that we'll get much more + * sane and consistent clipped repaints from Clutter. */ +static void +meta_window_group_get_preferred_width (ClutterActor *actor, + gfloat for_height, + gfloat *min_width, + gfloat *nat_width) +{ + *min_width = 0; + *nat_width = 0; +} + +static void +meta_window_group_get_preferred_height (ClutterActor *actor, + gfloat for_width, + gfloat *min_height, + gfloat *nat_height) +{ + *min_height = 0; + *nat_height = 0; } static void @@ -310,24 +200,23 @@ meta_window_group_class_init (MetaWindowGroupClass *klass) actor_class->paint = meta_window_group_paint; actor_class->get_paint_volume = meta_window_group_get_paint_volume; + actor_class->get_preferred_width = meta_window_group_get_preferred_width; + actor_class->get_preferred_height = meta_window_group_get_preferred_height; } static void meta_window_group_init (MetaWindowGroup *window_group) { - ClutterActor *actor = CLUTTER_ACTOR (window_group); - - clutter_actor_set_flags (actor, CLUTTER_ACTOR_NO_LAYOUT); } -LOCAL_SYMBOL ClutterActor * -meta_window_group_new (MetaScreen *screen) +ClutterActor * +meta_window_group_new (MetaDisplay *display) { MetaWindowGroup *window_group; window_group = g_object_new (META_TYPE_WINDOW_GROUP, NULL); - window_group->screen = screen; + window_group->display = display; return CLUTTER_ACTOR (window_group); } diff --git a/src/compositor/meta-window-group.h b/src/compositor/meta-window-group.h deleted file mode 100644 index 0e0dc1873..000000000 --- a/src/compositor/meta-window-group.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -#ifndef META_WINDOW_GROUP_H -#define META_WINDOW_GROUP_H - -#include <clutter/clutter.h> - -#include <meta/screen.h> - -/** - * MetaWindowGroup: - * - * This class is a subclass of ClutterGroup with special handling for - * MetaWindowActor when painting the group. When we are painting a stack - * of 5-10 maximized windows, the standard bottom-to-top method of - * drawing every actor results in a tremendous amount of overdraw - * and can easily max out the available memory bandwidth on a low-end - * graphics chipset. It's even worse if window textures are being accessed - * over the AGP bus. - * - * The basic technique applied here is to do a pre-pass before painting - * where we walk window from top to bottom and compute the visible area - * at each step by subtracting out the windows above it. The visible - * area is passed to MetaWindowActor which uses it to clip the portion of - * the window which drawn and avoid redrawing the shadow if it is completely - * obscured. - * - * A caveat is that this is ineffective if applications are using ARGB - * visuals, since we have no way of knowing whether a window obscures - * the windows behind it or not. Alternate approaches using the depth - * or stencil buffer rather than client side regions might be able to - * handle alpha windows, but the combination of glAlphaFunc and stenciling - * tends not to be efficient except on newer cards. (And on newer cards - * we have lots of memory and bandwidth.) - */ - -#define META_TYPE_WINDOW_GROUP (meta_window_group_get_type ()) -#define META_WINDOW_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_WINDOW_GROUP, MetaWindowGroup)) -#define META_WINDOW_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_WINDOW_GROUP, MetaWindowGroupClass)) -#define META_IS_WINDOW_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_WINDOW_GROUP)) -#define META_IS_WINDOW_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_WINDOW_GROUP)) -#define META_WINDOW_GROUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_WINDOW_GROUP, MetaWindowGroupClass)) - -typedef struct _MetaWindowGroup MetaWindowGroup; -typedef struct _MetaWindowGroupClass MetaWindowGroupClass; -typedef struct _MetaWindowGroupPrivate MetaWindowGroupPrivate; - -GType meta_window_group_get_type (void); - -ClutterActor *meta_window_group_new (MetaScreen *screen); - -#endif /* META_WINDOW_GROUP_H */ diff --git a/src/compositor/meta-window-shape.c b/src/compositor/meta-window-shape.c index fbb129e76..1b4767567 100644 --- a/src/compositor/meta-window-shape.c +++ b/src/compositor/meta-window-shape.c @@ -1,4 +1,5 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + /* * MetaWindowShape * @@ -17,18 +18,16 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ -#if HAVE_CONFIG_H -#include <config.h> -#endif + +#include "config.h" + +#include "meta/meta-window-shape.h" #include <string.h> -#include "meta-window-shape.h" -#include "region-utils.h" +#include "compositor/region-utils.h" struct _MetaWindowShape { @@ -40,7 +39,7 @@ struct _MetaWindowShape guint hash; }; -LOCAL_SYMBOL MetaWindowShape * +MetaWindowShape * meta_window_shape_new (cairo_region_t *region) { MetaWindowShape *shape; @@ -162,7 +161,7 @@ meta_window_shape_new (cairo_region_t *region) return shape; } -LOCAL_SYMBOL MetaWindowShape * +MetaWindowShape * meta_window_shape_ref (MetaWindowShape *shape) { shape->ref_count++; @@ -170,24 +169,24 @@ meta_window_shape_ref (MetaWindowShape *shape) return shape; } -LOCAL_SYMBOL void +void meta_window_shape_unref (MetaWindowShape *shape) { shape->ref_count--; if (shape->ref_count == 0) { - free (shape->rectangles); + g_free (shape->rectangles); g_slice_free (MetaWindowShape, shape); } } -LOCAL_SYMBOL guint +guint meta_window_shape_hash (MetaWindowShape *shape) { return shape->hash; } -LOCAL_SYMBOL gboolean +gboolean meta_window_shape_equal (MetaWindowShape *shape_a, MetaWindowShape *shape_b) { @@ -198,7 +197,7 @@ meta_window_shape_equal (MetaWindowShape *shape_a, sizeof (cairo_rectangle_int_t) * shape_a->n_rectangles) == 0; } -LOCAL_SYMBOL void +void meta_window_shape_get_borders (MetaWindowShape *shape, int *border_top, int *border_right, @@ -226,7 +225,7 @@ meta_window_shape_get_borders (MetaWindowShape *shape, * * Return value: a newly created region */ -LOCAL_SYMBOL cairo_region_t * +cairo_region_t * meta_window_shape_to_region (MetaWindowShape *shape, int center_width, int center_height) @@ -256,3 +255,5 @@ meta_window_shape_to_region (MetaWindowShape *shape, return region; } +G_DEFINE_BOXED_TYPE (MetaWindowShape, meta_window_shape, + meta_window_shape_ref, meta_window_shape_unref) diff --git a/src/compositor/plugins/Makefile.am b/src/compositor/plugins/Makefile.am deleted file mode 100644 index 241b514c3..000000000 --- a/src/compositor/plugins/Makefile.am +++ /dev/null @@ -1,48 +0,0 @@ - -pkglibdir=@MUFFIN_PLUGIN_DIR@ - -AM_CPPFLAGS= \ - $(WARN_CFLAGS) \ - $(MUFFIN_CFLAGS) \ - -I$(top_builddir)/src \ - -I$(top_srcdir)/src \ - -I$(top_srcdir)/cogl \ - -I$(top_builddir)/cogl \ - -I$(top_builddir)/cogl/cogl \ - -I$(top_srcdir)/clutter \ - -I$(top_builddir)/clutter \ - -I$(top_builddir)/clutter/clutter \ - -DMUFFIN_LIBEXECDIR=\"$(libexecdir)\" \ - -DHOST_ALIAS=\"@HOST_ALIAS@\" \ - -DMUFFIN_LOCALEDIR=\"$(prefix)/@DATADIRNAME@/locale\" \ - -DMUFFIN_PKGDATADIR=\"$(pkgdatadir)\" -DMUFFIN_DATADIR=\"$(datadir)\" \ - -DG_LOG_DOMAIN=\"muffin\" \ - -DSN_API_NOT_YET_FROZEN=1 \ - -DMUFFIN_MAJOR_VERSION=$(MUFFIN_MAJOR_VERSION) \ - -DMUFFIN_MINOR_VERSION=$(MUFFIN_MINOR_VERSION) \ - -DMUFFIN_MICRO_VERSION=$(MUFFIN_MICRO_VERSION) \ - -DMUFFIN_PLUGIN_API_VERSION=$(MUFFIN_PLUGIN_API_VERSION) \ - -DMUFFIN_PLUGIN_DIR=\"@MUFFIN_PLUGIN_DIR@\" - -default_la_CFLAGS = $(WARN_CFLAGS) -fPIC -default_la_SOURCES = default.c -default_la_LDFLAGS = $(WARN_LDFLAGS) -module -avoid-version -no-undefined -default_la_LIBADD = \ - $(CLUTTER_LIBS) \ - $(top_builddir)/src/libmuffin.la \ - $(top_builddir)/clutter/clutter/libmuffin-clutter-@MUFFIN_PLUGIN_API_VERSION@.la - -pkglib_LTLIBRARIES = default.la - -# post-install hook to remove the .la and .a files we are not interested in -# (There is no way to stop libtool generating static libs locally, and we -# cannot do this globally because of libmuffin-private.so). -install-exec-hook: - -rm $(DESTDIR)$(pkglibdir)/*.a - -rm $(DESTDIR)$(pkglibdir)/*.la - -# Since we removed the .la file, 'make uninstall' doesn't work properly, -# since it counts on libtool to remove the .la files, so just kill the -# .so file manually. -uninstall-local: - -rm -f $(DESTDIR)$(pkglibdir)/default.so diff --git a/src/compositor/plugins/default.c b/src/compositor/plugins/default.c index f69563bc0..08ecf01ac 100644 --- a/src/compositor/plugins/default.c +++ b/src/compositor/plugins/default.c @@ -16,27 +16,33 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ -#include <config.h> -#include <meta/meta-plugin.h> -#include <meta/window.h> -#include <meta/util.h> +#include "config.h" + +#include "meta/display.h" + #include <glib/gi18n-lib.h> -#include <clutter/clutter.h> #include <gmodule.h> #include <string.h> -#define DESTROY_TIMEOUT 250 +#include "clutter/clutter.h" +#include "meta/meta-backend.h" +#include "meta/meta-background-actor.h" +#include "meta/meta-background-group.h" +#include "meta/meta-monitor-manager.h" +#include "meta/meta-plugin.h" +#include "meta/util.h" +#include "meta/window.h" + +#define DESTROY_TIMEOUT 100 #define MINIMIZE_TIMEOUT 250 -#define MAXIMIZE_TIMEOUT 250 #define MAP_TIMEOUT 250 #define SWITCH_TIMEOUT 500 #define ACTOR_DATA_KEY "MCCP-Default-actor-data" +#define DISPLAY_TILE_PREVIEW_DATA_KEY "MCCP-Default-display-tile-preview-data" #define META_TYPE_DEFAULT_PLUGIN (meta_default_plugin_get_type ()) #define META_DEFAULT_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_DEFAULT_PLUGIN, MetaDefaultPlugin)) @@ -45,9 +51,6 @@ #define META_IS_DEFAULT_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_DEFAULT_PLUGIN)) #define META_DEFAULT_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_DEFAULT_PLUGIN, MetaDefaultPluginClass)) -#define META_DEFAULT_PLUGIN_GET_PRIVATE(obj) \ -(G_TYPE_INSTANCE_GET_PRIVATE ((obj), META_TYPE_DEFAULT_PLUGIN, MetaDefaultPluginPrivate)) - typedef struct _MetaDefaultPlugin MetaDefaultPlugin; typedef struct _MetaDefaultPluginClass MetaDefaultPluginClass; typedef struct _MetaDefaultPluginPrivate MetaDefaultPluginPrivate; @@ -65,25 +68,15 @@ struct _MetaDefaultPluginClass }; static GQuark actor_data_quark = 0; +static GQuark display_tile_preview_data_quark = 0; +static void start (MetaPlugin *plugin); static void minimize (MetaPlugin *plugin, MetaWindowActor *actor); static void map (MetaPlugin *plugin, MetaWindowActor *actor); static void destroy (MetaPlugin *plugin, MetaWindowActor *actor); -static void maximize (MetaPlugin *plugin, - MetaWindowActor *actor, - gint x, - gint y, - gint width, - gint height); -static void unmaximize (MetaPlugin *plugin, - MetaWindowActor *actor, - gint x, - gint y, - gint width, - gint height); static void switch_workspace (MetaPlugin *plugin, gint from, @@ -92,10 +85,17 @@ static void switch_workspace (MetaPlugin *plugin, static void kill_window_effects (MetaPlugin *plugin, MetaWindowActor *actor); +static void kill_switch_workspace (MetaPlugin *plugin); -static const MetaPluginInfo * plugin_info (MetaPlugin *plugin); +static void show_tile_preview (MetaPlugin *plugin, + MetaWindow *window, + MetaRectangle *tile_rect, + int tile_monitor_number); +static void hide_tile_preview (MetaPlugin *plugin); + +static void confirm_display_change (MetaPlugin *plugin); -META_PLUGIN_DECLARE(MetaDefaultPlugin, meta_default_plugin); +static const MetaPluginInfo * plugin_info (MetaPlugin *plugin); /* * Plugin private data that we store in the .plugin_private member. @@ -108,11 +108,14 @@ struct _MetaDefaultPluginPrivate ClutterActor *desktop1; ClutterActor *desktop2; - MetaPluginInfo info; + ClutterActor *background_group; - gboolean debug_mode : 1; + MetaPluginInfo info; }; +META_PLUGIN_DECLARE_WITH_CODE (MetaDefaultPlugin, meta_default_plugin, + G_ADD_PRIVATE_DYNAMIC (MetaDefaultPlugin)); + /* * Per actor private data we attach to each actor. */ @@ -121,12 +124,8 @@ typedef struct _ActorPrivate ClutterActor *orig_parent; ClutterTimeline *tml_minimize; - ClutterTimeline *tml_maximize; ClutterTimeline *tml_destroy; ClutterTimeline *tml_map; - - gboolean is_minimized : 1; - gboolean is_maximized : 1; } ActorPrivate; /* callback data for when animations complete */ @@ -137,6 +136,15 @@ typedef struct } EffectCompleteData; +typedef struct _DisplayTilePreview +{ + ClutterActor *actor; + + GdkRGBA *preview_color; + + MetaRectangle tile_rect; +} DisplayTilePreview; + static void meta_default_plugin_dispose (GObject *object) { @@ -179,20 +187,6 @@ meta_default_plugin_get_property (GObject *object, } } -static void -start (MetaPlugin *plugin) -{ - MetaDefaultPluginPrivate *priv = META_DEFAULT_PLUGIN (plugin)->priv; - - if (meta_plugin_debug_mode (plugin)) - { - g_debug ("Plugin %s: Entering debug mode.", priv->info.name); - - priv->debug_mode = TRUE; - - } -} - static void meta_default_plugin_class_init (MetaDefaultPluginClass *klass) { @@ -207,14 +201,14 @@ meta_default_plugin_class_init (MetaDefaultPluginClass *klass) plugin_class->start = start; plugin_class->map = map; plugin_class->minimize = minimize; - plugin_class->maximize = maximize; - plugin_class->unmaximize = unmaximize; plugin_class->destroy = destroy; plugin_class->switch_workspace = switch_workspace; + plugin_class->show_tile_preview = show_tile_preview; + plugin_class->hide_tile_preview = hide_tile_preview; plugin_class->plugin_info = plugin_info; plugin_class->kill_window_effects = kill_window_effects; - - g_type_class_add_private (gobject_class, sizeof (MetaDefaultPluginPrivate)); + plugin_class->kill_switch_workspace = kill_switch_workspace; + plugin_class->confirm_display_change = confirm_display_change; } static void @@ -222,7 +216,7 @@ meta_default_plugin_init (MetaDefaultPlugin *self) { MetaDefaultPluginPrivate *priv; - self->priv = priv = META_DEFAULT_PLUGIN_GET_PRIVATE (self); + self->priv = priv = meta_default_plugin_get_instance_private (self); priv->info.name = "Default Effects"; priv->info.version = "0.1"; @@ -261,13 +255,38 @@ get_actor_private (MetaWindowActor *actor) return priv; } +static ClutterTimeline * +actor_animate (ClutterActor *actor, + ClutterAnimationMode mode, + guint duration, + const gchar *first_property, + ...) +{ + va_list args; + ClutterTransition *transition; + + clutter_actor_save_easing_state (actor); + clutter_actor_set_easing_mode (actor, mode); + clutter_actor_set_easing_duration (actor, duration); + + va_start (args, first_property); + g_object_set_valist (G_OBJECT (actor), first_property, args); + va_end (args); + + transition = clutter_actor_get_transition (actor, first_property); + + clutter_actor_restore_easing_state (actor); + + return CLUTTER_TIMELINE (transition); +} + static void on_switch_workspace_effect_complete (ClutterTimeline *timeline, gpointer data) { MetaPlugin *plugin = META_PLUGIN (data); MetaDefaultPluginPrivate *priv = META_DEFAULT_PLUGIN (plugin)->priv; - MetaScreen *screen = meta_plugin_get_screen (plugin); - GList *l = meta_get_window_actors (screen); + MetaDisplay *display = meta_plugin_get_display (plugin); + GList *l = meta_get_window_actors (display); while (l) { @@ -277,7 +296,10 @@ on_switch_workspace_effect_complete (ClutterTimeline *timeline, gpointer data) if (apriv->orig_parent) { - clutter_actor_reparent (a, apriv->orig_parent); + g_object_ref (a); + clutter_actor_remove_child (clutter_actor_get_parent (a), a); + clutter_actor_add_child (apriv->orig_parent, a); + g_object_unref (a); apriv->orig_parent = NULL; } @@ -295,45 +317,171 @@ on_switch_workspace_effect_complete (ClutterTimeline *timeline, gpointer data) meta_plugin_switch_workspace_completed (plugin); } +static void +on_monitors_changed (MetaMonitorManager *monitor_manager, + MetaPlugin *plugin) +{ + MetaDefaultPlugin *self = META_DEFAULT_PLUGIN (plugin); + MetaDisplay *display = meta_plugin_get_display (plugin); + + int i, n; + GRand *rand = g_rand_new_with_seed (123456); + + clutter_actor_destroy_all_children (self->priv->background_group); + + n = meta_display_get_n_monitors (display); + for (i = 0; i < n; i++) + { + MetaRectangle rect; + ClutterActor *background_actor; + MetaBackground *background; + ClutterColor color; + + meta_display_get_monitor_geometry (display, i, &rect); + + background_actor = meta_background_actor_new (display, i); + + clutter_actor_set_position (background_actor, rect.x, rect.y); + clutter_actor_set_size (background_actor, rect.width, rect.height); + + /* Don't use rand() here, mesa calls srand() internally when + parsing the driconf XML, but it's nice if the colors are + reproducible. + */ + clutter_color_init (&color, + g_rand_int_range (rand, 0, 255), + g_rand_int_range (rand, 0, 255), + g_rand_int_range (rand, 0, 255), + 255); + + background = meta_background_new (display); + meta_background_set_color (background, &color); + meta_background_actor_set_background (META_BACKGROUND_ACTOR (background_actor), background); + g_object_unref (background); + + meta_background_actor_set_vignette (META_BACKGROUND_ACTOR (background_actor), + TRUE, + 0.5, + 0.5); + + clutter_actor_add_child (self->priv->background_group, background_actor); + } + + g_rand_free (rand); +} + +static void +init_keymap (MetaDefaultPlugin *self) +{ + g_autoptr (GError) error = NULL; + g_autoptr (GDBusProxy) proxy = NULL; + g_autoptr (GVariant) result = NULL; + g_autoptr (GVariant) props = NULL; + g_autofree char *x11_layout = NULL; + g_autofree char *x11_options = NULL; + g_autofree char *x11_variant = NULL; + + proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "org.freedesktop.locale1", + "/org/freedesktop/locale1", + "org.freedesktop.DBus.Properties", + NULL, + &error); + if (!proxy) + { + g_message ("Failed to acquire org.freedesktop.locale1 proxy: %s, " + "probably running in CI", + error->message); + return; + } + + result = g_dbus_proxy_call_sync (proxy, + "GetAll", + g_variant_new ("(s)", + "org.freedesktop.locale1"), + G_DBUS_CALL_FLAGS_NONE, + 100, + NULL, + &error); + if (!result) + { + g_warning ("Failed to retrieve locale properties: %s", error->message); + return; + } + + props = g_variant_get_child_value (result, 0); + if (!props) + { + g_warning ("No locale properties found"); + return; + } + + if (!g_variant_lookup (props, "X11Layout", "s", &x11_layout)) + x11_layout = g_strdup ("us"); + + if (!g_variant_lookup (props, "X11Options", "s", &x11_options)) + x11_options = g_strdup (""); + + if (!g_variant_lookup (props, "X11Variant", "s", &x11_variant)) + x11_variant = g_strdup (""); + + meta_backend_set_keymap (meta_get_backend (), + x11_layout, x11_variant, x11_options); +} + +static void +start (MetaPlugin *plugin) +{ + MetaDefaultPlugin *self = META_DEFAULT_PLUGIN (plugin); + MetaDisplay *display = meta_plugin_get_display (plugin); + MetaMonitorManager *monitor_manager = meta_monitor_manager_get (); + + self->priv->background_group = meta_background_group_new (); + clutter_actor_insert_child_below (meta_get_window_group_for_display (display), + self->priv->background_group, NULL); + + g_signal_connect (monitor_manager, "monitors-changed", + G_CALLBACK (on_monitors_changed), plugin); + + on_monitors_changed (monitor_manager, plugin); + + if (meta_is_wayland_compositor ()) + init_keymap (self); + + clutter_actor_show (meta_get_stage_for_display (display)); +} + static void switch_workspace (MetaPlugin *plugin, gint from, gint to, MetaMotionDirection direction) { - MetaScreen *screen; + MetaDisplay *display; MetaDefaultPluginPrivate *priv = META_DEFAULT_PLUGIN (plugin)->priv; GList *l; - ClutterActor *workspace0 = clutter_group_new (); - ClutterActor *workspace1 = clutter_group_new (); + ClutterActor *workspace0 = clutter_actor_new (); + ClutterActor *workspace1 = clutter_actor_new (); ClutterActor *stage; int screen_width, screen_height; - ClutterAnimation *animation; - - if (priv->tml_switch_workspace1) - { - clutter_timeline_stop (priv->tml_switch_workspace1); - clutter_timeline_stop (priv->tml_switch_workspace2); - g_signal_emit_by_name (priv->tml_switch_workspace1, "completed", NULL); - } - screen = meta_plugin_get_screen (plugin); - stage = meta_get_stage_for_screen (screen); + display = meta_plugin_get_display (plugin); + stage = meta_get_stage_for_display (display); - meta_screen_get_size (screen, - &screen_width, - &screen_height); + meta_display_get_size (display, + &screen_width, + &screen_height); - clutter_actor_set_anchor_point (workspace1, - screen_width, - screen_height); + clutter_actor_set_pivot_point (workspace1, 1.0, 1.0); clutter_actor_set_position (workspace1, screen_width, screen_height); clutter_actor_set_scale (workspace1, 0.0, 0.0); - clutter_container_add_actor (CLUTTER_CONTAINER (stage), workspace1); - clutter_container_add_actor (CLUTTER_CONTAINER (stage), workspace0); + clutter_actor_add_child (stage, workspace1); + clutter_actor_add_child (stage, workspace0); if (from == to) { @@ -341,25 +489,30 @@ switch_workspace (MetaPlugin *plugin, return; } - l = g_list_last (meta_get_window_actors (screen)); + l = g_list_last (meta_get_window_actors (display)); while (l) { MetaWindowActor *window_actor = l->data; ActorPrivate *apriv = get_actor_private (window_actor); ClutterActor *actor = CLUTTER_ACTOR (window_actor); + MetaWorkspace *workspace; gint win_workspace; - win_workspace = meta_window_actor_get_workspace (window_actor); + workspace = meta_window_get_workspace (meta_window_actor_get_meta_window (window_actor)); + win_workspace = meta_workspace_index (workspace); if (win_workspace == to || win_workspace == from) { + ClutterActor *parent = win_workspace == to ? workspace1 : workspace0; apriv->orig_parent = clutter_actor_get_parent (actor); - clutter_actor_reparent (actor, - win_workspace == to ? workspace1 : workspace0); - clutter_actor_show_all (actor); - clutter_actor_raise_top (actor); + g_object_ref (actor); + clutter_actor_remove_child (clutter_actor_get_parent (actor), actor); + clutter_actor_add_child (parent, actor); + clutter_actor_show (actor); + clutter_actor_set_child_below_sibling (parent, actor, NULL); + g_object_unref (actor); } else if (win_workspace < 0) { @@ -379,23 +532,21 @@ switch_workspace (MetaPlugin *plugin, priv->desktop1 = workspace0; priv->desktop2 = workspace1; - animation = clutter_actor_animate (workspace0, CLUTTER_EASE_IN_SINE, - SWITCH_TIMEOUT, - "scale-x", 1.0, - "scale-y", 1.0, - NULL); - priv->tml_switch_workspace1 = clutter_animation_get_timeline (animation); + priv->tml_switch_workspace1 = actor_animate (workspace0, CLUTTER_EASE_IN_SINE, + SWITCH_TIMEOUT, + "scale-x", 1.0, + "scale-y", 1.0, + NULL); g_signal_connect (priv->tml_switch_workspace1, "completed", G_CALLBACK (on_switch_workspace_effect_complete), plugin); - animation = clutter_actor_animate (workspace1, CLUTTER_EASE_IN_SINE, - SWITCH_TIMEOUT, - "scale-x", 0.0, - "scale-y", 0.0, - NULL); - priv->tml_switch_workspace2 = clutter_animation_get_timeline (animation); + priv->tml_switch_workspace2 = actor_animate (workspace1, CLUTTER_EASE_IN_SINE, + SWITCH_TIMEOUT, + "scale-x", 0.0, + "scale-y", 0.0, + NULL); } @@ -422,13 +573,11 @@ on_minimize_effect_complete (ClutterTimeline *timeline, EffectCompleteData *data /* FIXME - we shouldn't assume the original scale, it should be saved * at the start of the effect */ clutter_actor_set_scale (data->actor, 1.0, 1.0); - clutter_actor_move_anchor_point_from_gravity (data->actor, - CLUTTER_GRAVITY_NORTH_WEST); /* Now notify the manager that we are done with this effect */ meta_plugin_minimize_completed (plugin, window_actor); - free (data); + g_free (data); } /* @@ -441,6 +590,7 @@ minimize (MetaPlugin *plugin, MetaWindowActor *window_actor) MetaWindowType type; MetaRectangle icon_geometry; MetaWindow *meta_window = meta_window_actor_get_meta_window (window_actor); + ClutterTimeline *timeline = NULL; ClutterActor *actor = CLUTTER_ACTOR (window_actor); @@ -454,155 +604,32 @@ minimize (MetaPlugin *plugin, MetaWindowActor *window_actor) if (type == META_WINDOW_NORMAL) { - ClutterAnimation *animation; + timeline = actor_animate (actor, + CLUTTER_EASE_IN_SINE, + MINIMIZE_TIMEOUT, + "scale-x", 0.0, + "scale-y", 0.0, + "x", (double)icon_geometry.x, + "y", (double)icon_geometry.y, + NULL); + } + + if (timeline) + { EffectCompleteData *data = g_new0 (EffectCompleteData, 1); ActorPrivate *apriv = get_actor_private (window_actor); - apriv->is_minimized = TRUE; - - clutter_actor_move_anchor_point_from_gravity (actor, - CLUTTER_GRAVITY_CENTER); - - animation = clutter_actor_animate (actor, - CLUTTER_EASE_IN_SINE, - MINIMIZE_TIMEOUT, - "scale-x", 0.0, - "scale-y", 0.0, - "x", icon_geometry.x, - "y", icon_geometry.y, - NULL); - apriv->tml_minimize = clutter_animation_get_timeline (animation); + apriv->tml_minimize = timeline; data->plugin = plugin; data->actor = actor; g_signal_connect (apriv->tml_minimize, "completed", G_CALLBACK (on_minimize_effect_complete), data); - } else meta_plugin_minimize_completed (plugin, window_actor); } -/* - * Minimize effect completion callback; this function restores actor state, and - * calls the manager callback function. - */ -static void -on_maximize_effect_complete (ClutterTimeline *timeline, EffectCompleteData *data) -{ - /* - * Must reverse the effect of the effect. - */ - MetaPlugin *plugin = data->plugin; - MetaWindowActor *window_actor = META_WINDOW_ACTOR (data->actor); - ActorPrivate *apriv = get_actor_private (window_actor); - - apriv->tml_maximize = NULL; - - /* FIXME - don't assume the original scale was 1.0 */ - clutter_actor_set_scale (data->actor, 1.0, 1.0); - clutter_actor_move_anchor_point_from_gravity (data->actor, - CLUTTER_GRAVITY_NORTH_WEST); - - /* Now notify the manager that we are done with this effect */ - meta_plugin_maximize_completed (plugin, window_actor); - - free (data); -} - -/* - * The Nature of Maximize operation is such that it is difficult to do a visual - * effect that would work well. Scaling, the obvious effect, does not work that - * well, because at the end of the effect we end up with window content bigger - * and differently laid out than in the real window; this is a proof concept. - * - * (Something like a sound would be more appropriate.) - */ -static void -maximize (MetaPlugin *plugin, - MetaWindowActor *window_actor, - gint end_x, gint end_y, gint end_width, gint end_height) -{ - MetaWindowType type; - ClutterActor *actor = CLUTTER_ACTOR (window_actor); - MetaWindow *meta_window = meta_window_actor_get_meta_window (window_actor); - - gdouble scale_x = 1.0; - gdouble scale_y = 1.0; - gfloat anchor_x = 0; - gfloat anchor_y = 0; - - type = meta_window_get_window_type (meta_window); - - if (type == META_WINDOW_NORMAL) - { - ClutterAnimation *animation; - EffectCompleteData *data = g_new0 (EffectCompleteData, 1); - ActorPrivate *apriv = get_actor_private (window_actor); - gfloat width, height; - gfloat x, y; - - apriv->is_maximized = TRUE; - - clutter_actor_get_size (actor, &width, &height); - clutter_actor_get_position (actor, &x, &y); - - /* - * Work out the scale and anchor point so that the window is expanding - * smoothly into the target size. - */ - scale_x = (gdouble)end_width / (gdouble) width; - scale_y = (gdouble)end_height / (gdouble) height; - - anchor_x = (gdouble)(x - end_x)*(gdouble)width / - ((gdouble)(end_width - width)); - anchor_y = (gdouble)(y - end_y)*(gdouble)height / - ((gdouble)(end_height - height)); - - clutter_actor_move_anchor_point (actor, anchor_x, anchor_y); - - animation = clutter_actor_animate (actor, - CLUTTER_EASE_IN_SINE, - MAXIMIZE_TIMEOUT, - "scale-x", scale_x, - "scale-y", scale_y, - NULL); - apriv->tml_maximize = clutter_animation_get_timeline (animation); - data->plugin = plugin; - data->actor = actor; - g_signal_connect (apriv->tml_maximize, "completed", - G_CALLBACK (on_maximize_effect_complete), - data); - return; - } - - meta_plugin_maximize_completed (plugin, window_actor); -} - -/* - * See comments on the maximize() function. - * - * (Just a skeleton code.) - */ -static void -unmaximize (MetaPlugin *plugin, - MetaWindowActor *window_actor, - gint end_x, gint end_y, gint end_width, gint end_height) -{ - MetaWindow *meta_window = meta_window_actor_get_meta_window (window_actor); - MetaWindowType type = meta_window_get_window_type (meta_window); - - if (type == META_WINDOW_NORMAL) - { - ActorPrivate *apriv = get_actor_private (window_actor); - - apriv->is_maximized = FALSE; - } - - /* Do this conditionally, if the effect requires completion callback. */ - meta_plugin_unmaximize_completed (plugin, window_actor); -} - static void on_map_effect_complete (ClutterTimeline *timeline, EffectCompleteData *data) { @@ -615,13 +642,10 @@ on_map_effect_complete (ClutterTimeline *timeline, EffectCompleteData *data) apriv->tml_map = NULL; - clutter_actor_move_anchor_point_from_gravity (data->actor, - CLUTTER_GRAVITY_NORTH_WEST); - /* Now notify the manager that we are done with this effect */ meta_plugin_map_completed (plugin, window_actor); - free (data); + g_free (data); } /* @@ -639,31 +663,26 @@ map (MetaPlugin *plugin, MetaWindowActor *window_actor) if (type == META_WINDOW_NORMAL) { - ClutterAnimation *animation; EffectCompleteData *data = g_new0 (EffectCompleteData, 1); ActorPrivate *apriv = get_actor_private (window_actor); - clutter_actor_move_anchor_point_from_gravity (actor, - CLUTTER_GRAVITY_CENTER); - - clutter_actor_set_scale (actor, 0.0, 0.0); + clutter_actor_set_pivot_point (actor, 0.5, 0.5); + clutter_actor_set_opacity (actor, 0); + clutter_actor_set_scale (actor, 0.5, 0.5); clutter_actor_show (actor); - animation = clutter_actor_animate (actor, - CLUTTER_EASE_IN_SINE, - MAP_TIMEOUT, - "scale-x", 1.0, - "scale-y", 1.0, - NULL); - apriv->tml_map = clutter_animation_get_timeline (animation); + apriv->tml_map = actor_animate (actor, + CLUTTER_EASE_OUT_QUAD, + MAP_TIMEOUT, + "opacity", 255, + "scale-x", 1.0, + "scale-y", 1.0, + NULL); data->actor = actor; data->plugin = plugin; g_signal_connect (apriv->tml_map, "completed", G_CALLBACK (on_map_effect_complete), data); - - apriv->is_minimized = FALSE; - } else meta_plugin_map_completed (plugin, window_actor); @@ -694,25 +713,27 @@ destroy (MetaPlugin *plugin, MetaWindowActor *window_actor) MetaWindowType type; ClutterActor *actor = CLUTTER_ACTOR (window_actor); MetaWindow *meta_window = meta_window_actor_get_meta_window (window_actor); + ClutterTimeline *timeline = NULL; type = meta_window_get_window_type (meta_window); if (type == META_WINDOW_NORMAL) { - ClutterAnimation *animation; + timeline = actor_animate (actor, + CLUTTER_EASE_OUT_QUAD, + DESTROY_TIMEOUT, + "opacity", 0, + "scale-x", 0.8, + "scale-y", 0.8, + NULL); + } + + if (timeline) + { EffectCompleteData *data = g_new0 (EffectCompleteData, 1); ActorPrivate *apriv = get_actor_private (window_actor); - clutter_actor_move_anchor_point_from_gravity (actor, - CLUTTER_GRAVITY_CENTER); - - animation = clutter_actor_animate (actor, - CLUTTER_EASE_IN_SINE, - DESTROY_TIMEOUT, - "scale-x", 0.0, - "scale-y", 1.0, - NULL); - apriv->tml_destroy = clutter_animation_get_timeline (animation); + apriv->tml_destroy = timeline; data->plugin = plugin; data->actor = actor; g_signal_connect (apriv->tml_destroy, "completed", @@ -723,37 +744,139 @@ destroy (MetaPlugin *plugin, MetaWindowActor *window_actor) meta_plugin_destroy_completed (plugin, window_actor); } +/* + * Tile preview private data accessor + */ static void -kill_window_effects (MetaPlugin *plugin, - MetaWindowActor *window_actor) +free_display_tile_preview (DisplayTilePreview *preview) { - ActorPrivate *apriv; - apriv = get_actor_private (window_actor); + if (G_LIKELY (preview != NULL)) { + clutter_actor_destroy (preview->actor); + g_slice_free (DisplayTilePreview, preview); + } +} - if (apriv->tml_minimize) +static void +on_display_closing (MetaDisplay *display, + DisplayTilePreview *preview) +{ + free_display_tile_preview (preview); +} + +static DisplayTilePreview * +get_display_tile_preview (MetaDisplay *display) +{ + DisplayTilePreview *preview; + + if (!display_tile_preview_data_quark) { - clutter_timeline_stop (apriv->tml_minimize); - g_signal_emit_by_name (apriv->tml_minimize, "completed", NULL); + display_tile_preview_data_quark = + g_quark_from_static_string (DISPLAY_TILE_PREVIEW_DATA_KEY); } - if (apriv->tml_maximize) + preview = g_object_get_qdata (G_OBJECT (display), + display_tile_preview_data_quark); + if (!preview) { - clutter_timeline_stop (apriv->tml_maximize); - g_signal_emit_by_name (apriv->tml_maximize, "completed", NULL); + preview = g_slice_new0 (DisplayTilePreview); + + preview->actor = clutter_actor_new (); + clutter_actor_set_background_color (preview->actor, CLUTTER_COLOR_Blue); + clutter_actor_set_opacity (preview->actor, 100); + + clutter_actor_add_child (meta_get_window_group_for_display (display), preview->actor); + g_signal_connect (display, + "closing", + G_CALLBACK (on_display_closing), + preview); + g_object_set_qdata (G_OBJECT (display), + display_tile_preview_data_quark, + preview); } - if (apriv->tml_map) + return preview; +} + +static void +show_tile_preview (MetaPlugin *plugin, + MetaWindow *window, + MetaRectangle *tile_rect, + int tile_monitor_number) +{ + MetaDisplay *display = meta_plugin_get_display (plugin); + DisplayTilePreview *preview = get_display_tile_preview (display); + ClutterActor *window_actor; + + if (clutter_actor_is_visible (preview->actor) + && preview->tile_rect.x == tile_rect->x + && preview->tile_rect.y == tile_rect->y + && preview->tile_rect.width == tile_rect->width + && preview->tile_rect.height == tile_rect->height) + return; /* nothing to do */ + + clutter_actor_set_position (preview->actor, tile_rect->x, tile_rect->y); + clutter_actor_set_size (preview->actor, tile_rect->width, tile_rect->height); + + clutter_actor_show (preview->actor); + + window_actor = CLUTTER_ACTOR (meta_window_get_compositor_private (window)); + clutter_actor_set_child_below_sibling (clutter_actor_get_parent (preview->actor), + preview->actor, + window_actor); + + preview->tile_rect = *tile_rect; +} + +static void +hide_tile_preview (MetaPlugin *plugin) +{ + MetaDisplay *display = meta_plugin_get_display (plugin); + DisplayTilePreview *preview = get_display_tile_preview (display); + + clutter_actor_hide (preview->actor); +} + +static void +finish_timeline (ClutterTimeline *timeline) +{ + g_object_ref (timeline); + clutter_timeline_stop (timeline); + g_signal_emit_by_name (timeline, "completed", NULL); + g_object_unref (timeline); +} + +static void +kill_switch_workspace (MetaPlugin *plugin) +{ + MetaDefaultPluginPrivate *priv = META_DEFAULT_PLUGIN (plugin)->priv; + + if (priv->tml_switch_workspace1) { - clutter_timeline_stop (apriv->tml_map); - g_signal_emit_by_name (apriv->tml_map, "completed", NULL); + g_object_ref (priv->tml_switch_workspace1); + clutter_timeline_stop (priv->tml_switch_workspace1); + clutter_timeline_stop (priv->tml_switch_workspace2); + g_signal_emit_by_name (priv->tml_switch_workspace1, "completed", NULL); + g_object_unref (priv->tml_switch_workspace1); } +} + +static void +kill_window_effects (MetaPlugin *plugin, + MetaWindowActor *window_actor) +{ + ActorPrivate *apriv; + + apriv = get_actor_private (window_actor); + + if (apriv->tml_minimize) + finish_timeline (apriv->tml_minimize); + + if (apriv->tml_map) + finish_timeline (apriv->tml_map); if (apriv->tml_destroy) - { - clutter_timeline_stop (apriv->tml_destroy); - g_signal_emit_by_name (apriv->tml_destroy, "completed", NULL); - } + finish_timeline (apriv->tml_destroy); } static const MetaPluginInfo * @@ -763,3 +886,33 @@ plugin_info (MetaPlugin *plugin) return &priv->info; } + +static void +on_dialog_closed (GPid pid, + gint status, + gpointer user_data) +{ + MetaPlugin *plugin = user_data; + gboolean ok; + + ok = g_spawn_check_exit_status (status, NULL); + meta_plugin_complete_display_change (plugin, ok); +} + +static void +confirm_display_change (MetaPlugin *plugin) +{ + GPid pid; + + pid = meta_show_dialog ("--question", + "Does the display look OK?", + "20", + NULL, + "_Keep This Configuration", + "_Restore Previous Configuration", + "preferences-desktop-display", + 0, + NULL, NULL); + + g_child_watch_add (pid, on_dialog_closed, plugin); +} diff --git a/src/compositor/plugins/meson.build b/src/compositor/plugins/meson.build new file mode 100644 index 000000000..bd7661cf1 --- /dev/null +++ b/src/compositor/plugins/meson.build @@ -0,0 +1,20 @@ +default_plugin_c_args = [ + '-fPIC', + '-DG_LOG_DOMAIN="mutter"', + '-DGETTEXT_PACKAGE="@0@"'.format(meson.project_name()), +] + +default_plugin = shared_module('default', + sources: ['default.c'], + include_directories: mutter_includes, + c_args: default_plugin_c_args, + dependencies: [ + glib_dep, + gtk3_dep, + json_glib_dep, + cinnamon_desktop_dep, + libmutter_clutter_dep, + ], + install_dir: join_paths(pkglibdir, 'plugins'), + install: true, +) diff --git a/src/compositor/region-utils.c b/src/compositor/region-utils.c index b49f9462d..7b396cce2 100644 --- a/src/compositor/region-utils.c +++ b/src/compositor/region-utils.c @@ -15,19 +15,26 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ -#if HAVE_CONFIG_H -#include <config.h> -#endif +#include "config.h" -#include "region-utils.h" +#include "backends/meta-monitor-transform.h" +#include "compositor/region-utils.h" +#include "core/boxes-private.h" #include <math.h> +#define META_REGION_MAX_STACK_RECTS 256 + +#define META_REGION_CREATE_RECTANGLE_ARRAY_SCOPED(n_rects, rects) \ + g_autofree cairo_rectangle_int_t *G_PASTE(__n, __LINE__) = NULL; \ + if (n_rects < META_REGION_MAX_STACK_RECTS) \ + rects = g_newa (cairo_rectangle_int_t, n_rects); \ + else \ + rects = G_PASTE(__n, __LINE__) = g_new (cairo_rectangle_int_t, n_rects); + /* MetaRegionBuilder */ /* Various algorithms in this file require unioning together a set of rectangles @@ -47,34 +54,17 @@ /* Optimium performance seems to be with MAX_CHUNK_RECTANGLES=4; 8 is about 10% slower. * But using 8 may be more robust to systems with slow malloc(). */ #define MAX_CHUNK_RECTANGLES 8 -#define MAX_LEVELS 16 - -typedef struct -{ - /* To merge regions in binary tree order, we need to keep track of - * the regions that we've already merged together at different - * levels of the tree. We fill in an array in the pattern: - * - * |a | - * |b |a | - * |c | |ab | - * |d |c |ab | - * |e | | |abcd| - */ - cairo_region_t *levels[MAX_LEVELS]; - int n_levels; -} MetaRegionBuilder; -static void +void meta_region_builder_init (MetaRegionBuilder *builder) { int i; - for (i = 0; i < MAX_LEVELS; i++) + for (i = 0; i < META_REGION_BUILDER_MAX_LEVELS; i++) builder->levels[i] = NULL; builder->n_levels = 1; } -static void +void meta_region_builder_add_rectangle (MetaRegionBuilder *builder, int x, int y, @@ -99,7 +89,7 @@ meta_region_builder_add_rectangle (MetaRegionBuilder *builder, { if (builder->levels[i] == NULL) { - if (i < MAX_LEVELS) + if (i < META_REGION_BUILDER_MAX_LEVELS) { builder->levels[i] = builder->levels[i - 1]; builder->levels[i - 1] = NULL; @@ -119,7 +109,7 @@ meta_region_builder_add_rectangle (MetaRegionBuilder *builder, } } -static cairo_region_t * +cairo_region_t * meta_region_builder_finish (MetaRegionBuilder *builder) { cairo_region_t *result = NULL; @@ -144,11 +134,11 @@ meta_region_builder_finish (MetaRegionBuilder *builder) return result; } - + /* MetaRegionIterator */ -LOCAL_SYMBOL void +void meta_region_iterator_init (MetaRegionIterator *iter, cairo_region_t *region) { @@ -171,13 +161,13 @@ meta_region_iterator_init (MetaRegionIterator *iter, } } -LOCAL_SYMBOL gboolean +gboolean meta_region_iterator_at_end (MetaRegionIterator *iter) { return iter->i >= iter->n_rectangles; } -LOCAL_SYMBOL void +void meta_region_iterator_next (MetaRegionIterator *iter) { iter->i++; @@ -194,7 +184,62 @@ meta_region_iterator_next (MetaRegionIterator *iter) iter->line_end = TRUE; } } - + +cairo_region_t * +meta_region_scale_double (cairo_region_t *region, + double scale, + MetaRoundingStrategy rounding_strategy) +{ + int n_rects, i; + cairo_rectangle_int_t *rects; + cairo_region_t *scaled_region; + + g_return_val_if_fail (scale > 0.0, NULL); + + if (G_APPROX_VALUE (scale, 1.f, FLT_EPSILON)) + return cairo_region_copy (region); + + n_rects = cairo_region_num_rectangles (region); + META_REGION_CREATE_RECTANGLE_ARRAY_SCOPED (n_rects, rects); + for (i = 0; i < n_rects; i++) + { + cairo_region_get_rectangle (region, i, &rects[i]); + + meta_rectangle_scale_double (&rects[i], scale, rounding_strategy, + &rects[i]); + } + + scaled_region = cairo_region_create_rectangles (rects, n_rects); + + return scaled_region; +} + +cairo_region_t * +meta_region_scale (cairo_region_t *region, int scale) +{ + int n_rects, i; + cairo_rectangle_int_t *rects; + cairo_region_t *scaled_region; + + if (scale == 1) + return cairo_region_copy (region); + + n_rects = cairo_region_num_rectangles (region); + META_REGION_CREATE_RECTANGLE_ARRAY_SCOPED (n_rects, rects); + for (i = 0; i < n_rects; i++) + { + cairo_region_get_rectangle (region, i, &rects[i]); + rects[i].x *= scale; + rects[i].y *= scale; + rects[i].width *= scale; + rects[i].height *= scale; + } + + scaled_region = cairo_region_create_rectangles (rects, n_rects); + + return scaled_region; +} + static void add_expanded_rect (MetaRegionBuilder *builder, int x, @@ -316,7 +361,7 @@ expand_region_inverse (cairo_region_t *region, * * Return value: a new region which is the border of the given region */ -LOCAL_SYMBOL cairo_region_t * +cairo_region_t * meta_make_border_region (cairo_region_t *region, int x_amount, int y_amount, @@ -332,3 +377,82 @@ meta_make_border_region (cairo_region_t *region, return border_region; } + +cairo_region_t * +meta_region_transform (cairo_region_t *region, + MetaMonitorTransform transform, + int width, + int height) +{ + int n_rects, i; + cairo_rectangle_int_t *rects; + cairo_region_t *transformed_region; + + if (transform == META_MONITOR_TRANSFORM_NORMAL) + return cairo_region_copy (region); + + n_rects = cairo_region_num_rectangles (region); + META_REGION_CREATE_RECTANGLE_ARRAY_SCOPED (n_rects, rects); + for (i = 0; i < n_rects; i++) + { + cairo_region_get_rectangle (region, i, &rects[i]); + + meta_rectangle_transform (&rects[i], + transform, + width, + height, + &rects[i]); + } + + transformed_region = cairo_region_create_rectangles (rects, n_rects); + + return transformed_region; +} + +cairo_region_t * +meta_region_crop_and_scale (cairo_region_t *region, + graphene_rect_t *src_rect, + int dst_width, + int dst_height) +{ + int n_rects, i; + cairo_rectangle_int_t *rects; + cairo_region_t *viewport_region; + + if (G_APPROX_VALUE (src_rect->size.width, dst_width, FLT_EPSILON) && + G_APPROX_VALUE (src_rect->size.height, dst_height, FLT_EPSILON) && + G_APPROX_VALUE (roundf (src_rect->origin.x), + src_rect->origin.x, FLT_EPSILON) && + G_APPROX_VALUE (roundf (src_rect->origin.y), + src_rect->origin.y, FLT_EPSILON)) + { + viewport_region = cairo_region_copy (region); + + if (G_APPROX_VALUE (src_rect->origin.x, 0, FLT_EPSILON) || + G_APPROX_VALUE (src_rect->origin.y, 0, FLT_EPSILON)) + { + cairo_region_translate (viewport_region, + (int) src_rect->origin.x, + (int) src_rect->origin.y); + } + + return viewport_region; + } + + n_rects = cairo_region_num_rectangles (region); + META_REGION_CREATE_RECTANGLE_ARRAY_SCOPED (n_rects, rects); + for (i = 0; i < n_rects; i++) + { + cairo_region_get_rectangle (region, i, &rects[i]); + + meta_rectangle_crop_and_scale (&rects[i], + src_rect, + dst_width, + dst_height, + &rects[i]); + } + + viewport_region = cairo_region_create_rectangles (rects, n_rects); + + return viewport_region; +} diff --git a/src/compositor/region-utils.h b/src/compositor/region-utils.h index 274ae4124..745021b5b 100644 --- a/src/compositor/region-utils.h +++ b/src/compositor/region-utils.h @@ -15,19 +15,19 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef __META_REGION_UTILS_H__ #define __META_REGION_UTILS_H__ -#include <clutter/clutter.h> - #include <cairo.h> #include <glib.h> +#include "backends/meta-backend-types.h" +#include "clutter/clutter.h" +#include "core/boxes-private.h" + /** * MetaRegionIterator: * @region: region being iterated @@ -63,14 +63,57 @@ struct _MetaRegionIterator { cairo_rectangle_int_t next_rectangle; }; +typedef struct _MetaRegionBuilder MetaRegionBuilder; + +#define META_REGION_BUILDER_MAX_LEVELS 16 +struct _MetaRegionBuilder { + /* To merge regions in binary tree order, we need to keep track of + * the regions that we've already merged together at different + * levels of the tree. We fill in an array in the pattern: + * + * |a | + * |b |a | + * |c | |ab | + * |d |c |ab | + * |e | | |abcd| + */ + cairo_region_t *levels[META_REGION_BUILDER_MAX_LEVELS]; + int n_levels; +}; + +void meta_region_builder_init (MetaRegionBuilder *builder); +void meta_region_builder_add_rectangle (MetaRegionBuilder *builder, + int x, + int y, + int width, + int height); +cairo_region_t * meta_region_builder_finish (MetaRegionBuilder *builder); + void meta_region_iterator_init (MetaRegionIterator *iter, cairo_region_t *region); gboolean meta_region_iterator_at_end (MetaRegionIterator *iter); void meta_region_iterator_next (MetaRegionIterator *iter); -cairo_region_t *meta_make_border_region (cairo_region_t *region, - int x_amount, - int y_amount, - gboolean flip); +cairo_region_t * meta_region_scale (cairo_region_t *region, + int scale); + +cairo_region_t * meta_region_scale_double (cairo_region_t *region, + double scale, + MetaRoundingStrategy rounding_strategy); + +cairo_region_t * meta_make_border_region (cairo_region_t *region, + int x_amount, + int y_amount, + gboolean flip); + +cairo_region_t * meta_region_transform (cairo_region_t *region, + MetaMonitorTransform transform, + int width, + int height); + +cairo_region_t * meta_region_crop_and_scale (cairo_region_t *region, + graphene_rect_t *src_rect, + int dst_width, + int dst_height); #endif /* __META_REGION_UTILS_H__ */ diff --git a/src/core/above-tab-keycode.c b/src/core/above-tab-keycode.c deleted file mode 100644 index 4232d8705..000000000 --- a/src/core/above-tab-keycode.c +++ /dev/null @@ -1,243 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Find the keycode for the key above the tab key */ -/* - * Copyright 2010 Red Hat, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. - */ - -/* The standard cycle-windows keybinding should be the key above the - * tab key. This will have a different keysym on different keyboards - - * it's the ` (grave) key on US keyboards but something else on many - * other national layouts. So we need to figure out the keycode for - * this key without reference to key symbol. - * - * The "correct" way to do this is to get the XKB geometry from the - * X server, find the Tab key, find the key above the Tab key in the - * same section and use the keycode for that key. This is what I - * implemented here, but unfortunately, fetching the geometry is rather - * slow (It could take 20ms or more.) - * - * If you looking for a way to optimize Muffin startup performance: - * On all Linux systems using evdev the key above TAB will have - * keycode 49. (KEY_GRAVE=41 + the 8 code point offset between - * evdev keysyms and X keysyms.) So a configure option - * --with-above-tab-keycode=49 could be added that bypassed this - * code. It wouldn't work right for displaying Muffin remotely - * to a non-Linux X server, but that is pretty rare. - */ - -#include <config.h> - -#include <string.h> - -#include "display-private.h" - -#include <X11/keysym.h> - -#ifdef HAVE_XKB -#include <X11/XKBlib.h> -#include <X11/extensions/XKBgeom.h> - -static guint -compute_above_tab_keycode (Display *xdisplay) -{ - XkbDescPtr keyboard; - XkbGeometryPtr geometry; - int i, j, k; - int tab_keycode; - char *tab_name; - XkbSectionPtr tab_section; - XkbBoundsRec tab_bounds; - XkbKeyPtr best_key = NULL; - guint best_keycode = (guint)-1; - int best_x_dist = G_MAXINT; - int best_y_dist = G_MAXINT; - - /* We need only the Names and the Geometry, but asking for these results - * in the Keyboard information retrieval failing for unknown reasons. - * (Testing with xorg-1.9.1.) So we ask for a part that we don't need - * as well. - */ - keyboard = XkbGetKeyboard (xdisplay, - XkbGBN_ClientSymbolsMask | XkbGBN_KeyNamesMask | XkbGBN_GeometryMask, - XkbUseCoreKbd); - if (!keyboard) - return best_keycode; - - geometry = keyboard->geom; - - /* There could potentially be multiple keys with the Tab keysym on the keyboard; - * but XKeysymToKeycode() returns us the one that the alt-Tab binding will - * use which is good enough - */ - tab_keycode = XKeysymToKeycode (xdisplay, XK_Tab); - if (tab_keycode == 0 || tab_keycode < keyboard->min_key_code || tab_keycode > keyboard->max_key_code) - goto out; - - /* The keyboard geometry is stored by key "name" rather than keycode. - * (Key names are 4-character strings like like TAB or AE01.) We use the - * 'names' part of the keyboard description to map keycode to key name. - * - * XKB has a "key aliases" feature where a single keyboard key can have - * multiple names (with separate sets of aliases in the 'names' part and - * in the 'geometry' part), but I don't really understand it or how it is used, - * so I'm ignoring it here. - */ - - tab_name = keyboard->names->keys[tab_keycode].name; /* Not NULL terminated! */ - - /* First, iterate through the keyboard geometry to find the tab key; the keyboard - * geometry has a three-level heirarchy of section > row > key - */ - for (i = 0; i < geometry->num_sections; i++) - { - XkbSectionPtr section = &geometry->sections[i]; - for (j = 0; j < section->num_rows; j++) - { - int x = 0; - int y = 0; - - XkbRowPtr row = §ion->rows[j]; - for (k = 0; k < row->num_keys; k++) - { - XkbKeyPtr key = &row->keys[k]; - XkbShapePtr shape = XkbKeyShape (geometry, key); - - if (row->vertical) - y += key->gap; - else - x += key->gap; - - if (strncmp (key->name.name, tab_name, XkbKeyNameLength) == 0) - { - tab_section = section; - tab_bounds = shape->bounds; - tab_bounds.x1 += row->left + x; - tab_bounds.x2 += row->left + x; - tab_bounds.y1 += row->top + y; - tab_bounds.y2 += row->top + y; - - goto found_tab; - } - - if (row->vertical) - y += (shape->bounds.y2 - shape->bounds.y1); - else - x += (shape->bounds.x2 - shape->bounds.x1); - } - } - } - - /* No tab key found */ - goto out; - - found_tab: - - /* Now find the key that: - * - Is in the same section as the Tab key - * - Has a horizontal center in the Tab key's horizonal bounds - * - Is above the Tab key at a distance closer than any other key - * - In case of ties, has its horizontal center as close as possible - * to the Tab key's horizontal center - */ - for (j = 0; j < tab_section->num_rows; j++) - { - int x = 0; - int y = 0; - - XkbRowPtr row = &tab_section->rows[j]; - for (k = 0; k < row->num_keys; k++) - { - XkbKeyPtr key = &row->keys[k]; - XkbShapePtr shape = XkbKeyShape(geometry, key); - XkbBoundsRec bounds = shape->bounds; - int x_center; - int x_dist, y_dist; - - if (row->vertical) - y += key->gap; - else - x += key->gap; - - bounds.x1 += row->left + x; - bounds.x2 += row->left + x; - bounds.y1 += row->top + y; - bounds.y2 += row->top + y; - - y_dist = tab_bounds.y1 - bounds.y2; - if (y_dist < 0) - continue; - - x_center = (bounds.x1 + bounds.x2) / 2; - if (x_center < tab_bounds.x1 || x_center > tab_bounds.x2) - continue; - - x_dist = ABS (x_center - (tab_bounds.x1 + tab_bounds.x2) / 2); - - if (y_dist < best_y_dist || - (y_dist == best_y_dist && x_dist < best_x_dist)) - { - best_key = key; - best_x_dist = x_dist; - best_y_dist = y_dist; - } - - if (row->vertical) - y += (shape->bounds.y2 - shape->bounds.y1); - else - x += (shape->bounds.x2 - shape->bounds.x1); - } - } - - if (best_key == NULL) - goto out; - - /* Now we need to resolve the name of the best key back to a keycode */ - for (i = keyboard->min_key_code; i < keyboard->max_key_code; i++) - { - if (strncmp (best_key->name.name, keyboard->names->keys[i].name, XkbKeyNameLength) == 0) - { - best_keycode = i; - break; - } - } - - out: - XkbFreeKeyboard (keyboard, 0, True); - - return best_keycode; -} -#else /* !HAVE_XKB */ -static guint -compute_above_tab_keycode (Display *xdisplay) -{ - return XKeysymToKeycode (xdisplay, XK_grave); -} -#endif /* HAVE_XKB */ - -LOCAL_SYMBOL guint -meta_display_get_above_tab_keycode (MetaDisplay *display) -{ - if (display->above_tab_keycode == 0) /* not yet computed */ - display->above_tab_keycode = compute_above_tab_keycode (display->xdisplay); - - if (display->above_tab_keycode == (guint)-1) /* failed to compute */ - return 0; - else - return display->above_tab_keycode; -} diff --git a/src/core/async-getprop.c b/src/core/async-getprop.c deleted file mode 100644 index 8a0aa2dd9..000000000 --- a/src/core/async-getprop.c +++ /dev/null @@ -1,683 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Asynchronous X property getting hack */ - -/* - * Copyright (C) 2002 Havoc Pennington - * Copyright (C) 1986, 1998 The Open Group - * - * Permission to use, copy, modify, distribute, and sell this software - * and its documentation for any purpose is hereby granted without - * fee, provided that the above copyright notice appear in all copies - * and that both that copyright notice and this permission notice - * appear in supporting documentation. - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Except as contained in this notice, the name of The Open Group shall not be - * used in advertising or otherwise to promote the sale, use or other dealings - * in this Software without prior written authorization from The Open Group. - */ -#if HAVE_CONFIG_H -#include <config.h> -#endif - -#include <assert.h> - -#undef DEBUG_SPEW -#ifdef DEBUG_SPEW -#include <stdio.h> -#endif - -#include "async-getprop.h" - -#define NEED_REPLIES -#include <X11/Xlibint.h> - -#ifndef NULL -#define NULL ((void*)0) -#endif - -typedef struct _ListNode ListNode; -typedef struct _AgPerDisplayData AgPerDisplayData; - -struct _ListNode -{ - ListNode *next; -}; - -struct _AgGetPropertyTask -{ - ListNode node; - - AgPerDisplayData *dd; - Window window; - Atom property; - - unsigned long request_seq; - int error; - - Atom actual_type; - int actual_format; - - unsigned long n_items; - unsigned long bytes_after; - char *data; - - Bool have_reply; -}; - -struct _AgPerDisplayData -{ - ListNode node; - _XAsyncHandler async; - - Display *display; - ListNode *pending_tasks; - ListNode *pending_tasks_tail; - ListNode *completed_tasks; - ListNode *completed_tasks_tail; - int n_tasks_pending; - int n_tasks_completed; -}; - -static ListNode *display_datas = NULL; -static ListNode *display_datas_tail = NULL; - -static void -append_to_list (ListNode **head, - ListNode **tail, - ListNode *task) -{ - task->next = NULL; - - if (*tail == NULL) - { - assert (*head == NULL); - *head = task; - *tail = task; - } - else - { - (*tail)->next = task; - *tail = task; - } -} - -static void -remove_from_list (ListNode **head, - ListNode **tail, - ListNode *task) -{ - ListNode *prev; - ListNode *node; - - prev = NULL; - node = *head; - while (node != NULL) - { - if (node == task) - { - if (prev) - prev->next = node->next; - else - *head = node->next; - - if (node == *tail) - *tail = prev; - - break; - } - - prev = node; - node = node->next; - } - - /* can't remove what's not there */ - assert (node != NULL); - - node->next = NULL; -} - -static void -move_to_completed (AgPerDisplayData *dd, - AgGetPropertyTask *task) -{ - remove_from_list (&dd->pending_tasks, - &dd->pending_tasks_tail, - &task->node); - - append_to_list (&dd->completed_tasks, - &dd->completed_tasks_tail, - &task->node); - - dd->n_tasks_pending -= 1; - dd->n_tasks_completed += 1; -} - -static AgGetPropertyTask* -find_pending_by_request_sequence (AgPerDisplayData *dd, - unsigned long request_seq) -{ - ListNode *node; - - /* if the sequence is after our last pending task, we - * aren't going to find a match - */ - { - AgGetPropertyTask *task = (AgGetPropertyTask*) dd->pending_tasks_tail; - if (task != NULL) - { - if (task->request_seq < request_seq) - return NULL; - else if (task->request_seq == request_seq) - return task; /* why not check this */ - } - } - - /* Generally we should get replies in the order we sent - * requests, so we should usually be using the task - * at the head of the list, if we use any task at all. - * I'm not sure this is 100% guaranteed, if it is, - * it would be a big speedup. - */ - - node = dd->pending_tasks; - while (node != NULL) - { - AgGetPropertyTask *task = (AgGetPropertyTask*) node; - - if (task->request_seq == request_seq) - return task; - - node = node->next; - } - - return NULL; -} - -static Bool -async_get_property_handler (Display *dpy, - xReply *rep, - char *buf, - int len, - XPointer data) -{ - xGetPropertyReply replbuf; - xGetPropertyReply *reply; - AgGetPropertyTask *task; - AgPerDisplayData *dd; - int bytes_read; - - dd = (AgPerDisplayData*) data; - -#if 0 - printf ("%s: seeing request seq %ld buflen %d\n", __FUNCTION__, - dpy->last_request_read, len); -#endif - - task = find_pending_by_request_sequence (dd, dpy->last_request_read); - - if (task == NULL) - return False; - - assert (dpy->last_request_read == task->request_seq); - - task->have_reply = True; - move_to_completed (dd, task); - - /* read bytes so far */ - bytes_read = SIZEOF (xReply); - - if (rep->generic.type == X_Error) - { - xError errbuf; - - task->error = rep->error.errorCode; - -#ifdef DEBUG_SPEW - printf ("%s: error code = %d (ignoring error, eating %d bytes, generic.length = %ld)\n", - __FUNCTION__, task->error, (SIZEOF (xError) - bytes_read), - rep->generic.length); -#endif - - /* We return True (meaning we consumed the reply) - * because otherwise it would invoke the X error handler, - * and an async API is useless if you have to synchronously - * trap X errors. Also GetProperty can always fail, pretty - * much, so trapping errors is always what you want. - * - * We have to eat all the error reply data here. - * (kind of a charade as we know sizeof(xError) == sizeof(xReply)) - * - * Passing discard = True seems to break things; I don't understand - * why, because there should be no extra data in an error reply, - * right? - */ - _XGetAsyncReply (dpy, (char *)&errbuf, rep, buf, len, - (SIZEOF (xError) - bytes_read) >> 2, /* in 32-bit words */ - False); /* really seems like it should be True */ - - return True; - } - -#ifdef DEBUG_SPEW - printf ("%s: already read %d bytes reading %d more for total of %d; generic.length = %ld\n", - __FUNCTION__, bytes_read, (SIZEOF (xGetPropertyReply) - bytes_read) >> 2, - SIZEOF (xGetPropertyReply), rep->generic.length); -#endif - - /* (kind of a silly as we know sizeof(xGetPropertyReply) == sizeof(xReply)) */ - reply = (xGetPropertyReply *) - _XGetAsyncReply (dpy, (char *)&replbuf, rep, buf, len, - (SIZEOF (xGetPropertyReply) - bytes_read) >> 2, /* in 32-bit words */ - False); /* False means expecting more data to follow, - * don't eat the rest of the reply - */ - - bytes_read = SIZEOF (xGetPropertyReply); - -#ifdef DEBUG_SPEW - printf ("%s: have reply propertyType = %ld format = %d n_items = %ld\n", - __FUNCTION__, reply->propertyType, reply->format, reply->nItems); -#endif - - assert (task->data == NULL); - - /* This is all copied from XGetWindowProperty(). Not sure we should - * LockDisplay(). Not sure I'm passing the right args to - * XGetAsyncData(). Not sure about a lot of things. - */ - - /* LockDisplay (dpy); */ - - if (reply->propertyType != None) - { - long nbytes, netbytes; - - /* this alignment macro from orbit2 */ -#define ALIGN_VALUE(this, boundary) \ - (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1))) - - switch (reply->format) - { - /* - * One extra byte is malloced than is needed to contain the property - * data, but this last byte is null terminated and convenient for - * returning string properties, so the client doesn't then have to - * recopy the string to make it null terminated. - */ - case 8: - nbytes = reply->nItems; - /* there's padding to word boundary */ - netbytes = ALIGN_VALUE (nbytes, 4); - if (nbytes + 1 > 0 && - (task->data = (char *) Xmalloc ((unsigned)nbytes + 1))) - { -#ifdef DEBUG_SPEW - printf ("%s: already read %d bytes using %ld, more eating %ld more\n", - __FUNCTION__, bytes_read, nbytes, netbytes); -#endif - /* _XReadPad (dpy, (char *) task->data, netbytes); */ - _XGetAsyncData (dpy, task->data, buf, len, - bytes_read, nbytes, - netbytes); - } - break; - - case 16: - nbytes = reply->nItems * sizeof (short); - netbytes = reply->nItems << 1; - netbytes = ALIGN_VALUE (netbytes, 4); /* align to word boundary */ - if (nbytes + 1 > 0 && - (task->data = (char *) Xmalloc ((unsigned)nbytes + 1))) - { -#ifdef DEBUG_SPEW - printf ("%s: already read %d bytes using %ld more, eating %ld more\n", - __FUNCTION__, bytes_read, nbytes, netbytes); -#endif - /* _XRead16Pad (dpy, (short *) task->data, netbytes); */ - _XGetAsyncData (dpy, task->data, buf, len, - bytes_read, nbytes, netbytes); - } - break; - - case 32: - /* NOTE buffer is in longs to match XGetWindowProperty() */ - nbytes = reply->nItems * sizeof (long); - netbytes = reply->nItems << 2; /* wire size is always 32 bits though */ - if (nbytes + 1 > 0 && - (task->data = (char *) Xmalloc ((unsigned)nbytes + 1))) - { -#ifdef DEBUG_SPEW - printf ("%s: already read %d bytes using %ld more, eating %ld more\n", - __FUNCTION__, bytes_read, nbytes, netbytes); -#endif - - /* We have to copy the XGetWindowProperty() crackrock - * and get format 32 as long even on 64-bit platforms. - */ - if (sizeof (long) == 8) - { - char *netdata; - char *lptr; - char *end_lptr; - - /* Store the 32-bit values in the end of the array */ - netdata = task->data + nbytes / 2; - - _XGetAsyncData (dpy, netdata, buf, len, - bytes_read, netbytes, - netbytes); - - /* Now move the 32-bit values to the front */ - - lptr = task->data; - end_lptr = task->data + nbytes; - while (lptr != end_lptr) - { - *(long*) lptr = *(CARD32*) netdata; - lptr += sizeof (long); - netdata += sizeof (CARD32); - } - } - else - { - /* Here the wire format matches our actual format */ - _XGetAsyncData (dpy, task->data, buf, len, - bytes_read, netbytes, - netbytes); - } - } - break; - - default: - /* - * This part of the code should never be reached. If it is, - * the server sent back a property with an invalid format. - * This is a BadImplementation error. - * - * However this async GetProperty API doesn't report errors - * via the standard X mechanism, so don't do anything about - * it, other than store it in task->error. - */ - { -#if 0 - xError error; -#endif - - task->error = BadImplementation; - -#if 0 - error.sequenceNumber = task->request_seq; - error.type = X_Error; - error.majorCode = X_GetProperty; - error.minorCode = 0; - error.errorCode = BadImplementation; - - _XError (dpy, &error); -#endif - } - - nbytes = netbytes = 0L; - break; - } - - if (task->data == NULL) - { - task->error = BadAlloc; - -#ifdef DEBUG_SPEW - printf ("%s: already read %d bytes eating %ld\n", - __FUNCTION__, bytes_read, netbytes); -#endif - /* _XEatData (dpy, (unsigned long) netbytes); */ - _XGetAsyncData (dpy, NULL, buf, len, - bytes_read, 0, netbytes); - - /* UnlockDisplay (dpy); */ - return BadAlloc; /* not Success */ - } - - (task->data)[nbytes] = '\0'; - } - -#ifdef DEBUG_SPEW - printf ("%s: have data\n", __FUNCTION__); -#endif - - task->actual_type = reply->propertyType; - task->actual_format = reply->format; - task->n_items = reply->nItems; - task->bytes_after = reply->bytesAfter; - - /* UnlockDisplay (dpy); */ - - return True; -} - -static AgPerDisplayData* -get_display_data (Display *display, - Bool create) -{ - ListNode *node; - AgPerDisplayData *dd; - - node = display_datas; - while (node != NULL) - { - dd = (AgPerDisplayData*) node; - - if (dd->display == display) - return dd; - - node = node->next; - } - - if (!create) - return NULL; - - dd = Xcalloc (1, sizeof (AgPerDisplayData)); - if (dd == NULL) - return NULL; - - dd->display = display; - dd->async.next = display->async_handlers; - dd->async.handler = async_get_property_handler; - dd->async.data = (XPointer) dd; - dd->display->async_handlers = &dd->async; - - append_to_list (&display_datas, - &display_datas_tail, - &dd->node); - - return dd; -} - -static void -maybe_free_display_data (AgPerDisplayData *dd) -{ - if (dd->pending_tasks == NULL && - dd->completed_tasks == NULL) - { - DeqAsyncHandler (dd->display, &dd->async); - remove_from_list (&display_datas, &display_datas_tail, - &dd->node); - XFree (dd); - } -} - -LOCAL_SYMBOL AgGetPropertyTask* -ag_task_create (Display *dpy, - Window window, - Atom property, - long offset, - long length, - Bool delete, - Atom req_type) -{ - AgGetPropertyTask *task; - xGetPropertyReq *req; - AgPerDisplayData *dd; - - /* Fire up our request */ - LockDisplay (dpy); - - dd = get_display_data (dpy, True); - if (dd == NULL) - { - UnlockDisplay (dpy); - return NULL; - } - - GetReq (GetProperty, req); - req->window = window; - req->property = property; - req->type = req_type; - req->delete = delete; - req->longOffset = offset; - req->longLength = length; - - /* Queue up our async task */ - task = Xcalloc (1, sizeof (AgGetPropertyTask)); - if (task == NULL) - { - UnlockDisplay (dpy); - return NULL; - } - - task->dd = dd; - task->window = window; - task->property = property; - task->request_seq = dpy->request; - - append_to_list (&dd->pending_tasks, - &dd->pending_tasks_tail, - &task->node); - dd->n_tasks_pending += 1; - - UnlockDisplay (dpy); - - SyncHandle (); - - return task; -} - -static void -free_task (AgGetPropertyTask *task) -{ - remove_from_list (&task->dd->completed_tasks, - &task->dd->completed_tasks_tail, - &task->node); - task->dd->n_tasks_completed -= 1; - maybe_free_display_data (task->dd); - XFree (task); -} - -LOCAL_SYMBOL Status -ag_task_get_reply_and_free (AgGetPropertyTask *task, - Atom *actual_type, - int *actual_format, - unsigned long *nitems, - unsigned long *bytesafter, - unsigned char **prop) -{ - Display *dpy; - - *prop = NULL; - - dpy = task->dd->display; /* Xlib macros require a variable named "dpy" */ - - if (task->error != Success) - { - Status s = task->error; - - free_task (task); - - return s; - } - - if (!task->have_reply) - { - free_task (task); - - return BadAlloc; /* not Success */ - } - - *actual_type = task->actual_type; - *actual_format = task->actual_format; - *nitems = task->n_items; - *bytesafter = task->bytes_after; - - *prop = (unsigned char*) task->data; /* pass out ownership of task->data */ - - SyncHandle (); - - free_task (task); - - return Success; -} - -LOCAL_SYMBOL Bool -ag_task_have_reply (AgGetPropertyTask *task) -{ - return task->have_reply; -} - -LOCAL_SYMBOL Atom -ag_task_get_property (AgGetPropertyTask *task) -{ - return task->property; -} - -LOCAL_SYMBOL Window -ag_task_get_window (AgGetPropertyTask *task) -{ - return task->window; -} - -LOCAL_SYMBOL Display* -ag_task_get_display (AgGetPropertyTask *task) -{ - return task->dd->display; -} - -LOCAL_SYMBOL AgGetPropertyTask* -ag_get_next_completed_task (Display *display) -{ - AgPerDisplayData *dd; - - dd = get_display_data (display, False); - - if (dd == NULL) - return NULL; - -#ifdef DEBUG_SPEW - printf ("%d pending %d completed\n", - dd->n_tasks_pending, - dd->n_tasks_completed); -#endif - - return (AgGetPropertyTask*) dd->completed_tasks; -} - -LOCAL_SYMBOL void* -ag_Xmalloc (unsigned long bytes) -{ - return (void*) Xmalloc (bytes); -} - -LOCAL_SYMBOL void* -ag_Xmalloc0 (unsigned long bytes) -{ - return (void*) Xcalloc (bytes, 1); -} diff --git a/src/core/async-getprop.h b/src/core/async-getprop.h deleted file mode 100644 index c857e9301..000000000 --- a/src/core/async-getprop.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Asynchronous X property getting hack */ - -/* - * Copyright (C) 2002 Havoc Pennington - * - * Permission to use, copy, modify, distribute, and sell this software - * and its documentation for any purpose is hereby granted without - * fee, provided that the above copyright notice appear in all copies - * and that both that copyright notice and this permission notice - * appear in supporting documentation. - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Except as contained in this notice, the name of The Open Group shall not be - * used in advertising or otherwise to promote the sale, use or other dealings - * in this Software without prior written authorization from The Open Group. - */ - -#ifndef ASYNC_GETPROP_H -#define ASYNC_GETPROP_H - -#include <X11/Xlib.h> -#include <X11/Xutil.h> - -typedef struct _AgGetPropertyTask AgGetPropertyTask; - -AgGetPropertyTask* ag_task_create (Display *display, - Window window, - Atom property, - long offset, - long length, - Bool delete, - Atom req_type); -Status ag_task_get_reply_and_free (AgGetPropertyTask *task, - Atom *actual_type, - int *actual_format, - unsigned long *nitems, - unsigned long *bytesafter, - unsigned char **prop); - -Bool ag_task_have_reply (AgGetPropertyTask *task); -Atom ag_task_get_property (AgGetPropertyTask *task); -Window ag_task_get_window (AgGetPropertyTask *task); -Display* ag_task_get_display (AgGetPropertyTask *task); - -AgGetPropertyTask* ag_get_next_completed_task (Display *display); - -/* so other headers don't have to include internal Xlib goo */ -void* ag_Xmalloc (unsigned long bytes); -void* ag_Xmalloc0 (unsigned long bytes); - -#endif - - - - diff --git a/src/core/bell.c b/src/core/bell.c index 7d02cf00d..5bbaf160b 100644 --- a/src/core/bell.c +++ b/src/core/bell.c @@ -1,11 +1,11 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* Muffin visual bell */ +/* Mutter visual bell */ -/* +/* * Copyright (C) 2002 Sun Microsystems Inc. * Copyright (C) 2005, 2006 Elijah Newren - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the @@ -15,18 +15,16 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ -/** - * SECTION:Bell +/* + * SECTION:bell * @short_description: Ring the bell or flash the screen * - * Sometimes, X programs "ring the bell", whatever that means. Muffin lets + * Sometimes, X programs "ring the bell", whatever that means. Mutter lets * the user configure the bell to be audible or visible (aka visual), and * if it's visual it can be configured to be frame-flash or fullscreen-flash. * We never get told about audible bells; X handles them just fine by itself. @@ -36,10 +34,8 @@ * function then checks what kind of visual flash you like, and calls either * bell_flash_fullscreen()-- which calls bell_flash_screen() to do * its work-- or bell_flash_frame(), which flashes the focussed window - * using bell_flash_window_frame(), unless there is no such window, in - * which case it flashes the screen instead. bell_flash_window_frame() - * flashes the frame and calls bell_unflash_frame() as a timeout to - * remove the flash. + * using bell_flash_window(), unless there is no such window, in + * which case it flashes the screen instead. * * The visual bell was the result of a discussion in Bugzilla here: * <http://bugzilla.gnome.org/show_bug.cgi?id=99886>. @@ -49,56 +45,165 @@ * things with bells; some others are entirely no-ops in that case. */ -#include <config.h> -#include "bell.h" +#include "config.h" + +#include "core/bell.h" -LOCAL_SYMBOL gboolean -meta_bell_init (MetaDisplay *display) +#include "compositor/compositor-private.h" +#include "core/util-private.h" +#include "core/window-private.h" +#include "meta/compositor.h" + +G_DEFINE_TYPE (MetaBell, meta_bell, G_TYPE_OBJECT) + +enum { -#ifdef HAVE_XKB - int xkb_base_error_type, xkb_opcode; + IS_AUDIBLE_CHANGED, + LAST_SIGNAL +}; + +static guint bell_signals [LAST_SIGNAL] = { 0 }; - if (!XkbQueryExtension (display->xdisplay, &xkb_opcode, - &display->xkb_base_event_type, - &xkb_base_error_type, - NULL, NULL)) +static void +prefs_changed_callback (MetaPreference pref, + gpointer data) +{ + MetaBell *bell = data; + + if (pref == META_PREF_AUDIBLE_BELL) { - display->xkb_base_event_type = -1; - g_message ("could not find XKB extension."); - return FALSE; + g_signal_emit (bell, bell_signals[IS_AUDIBLE_CHANGED], 0, + meta_prefs_bell_is_audible ()); } - else +} + +static void +meta_bell_finalize (GObject *object) +{ + MetaBell *bell = META_BELL (object); + + meta_prefs_remove_listener (prefs_changed_callback, bell); + + G_OBJECT_CLASS (meta_bell_parent_class)->finalize (object); +} + +static void +meta_bell_class_init (MetaBellClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_bell_finalize; + + bell_signals[IS_AUDIBLE_CHANGED] = + g_signal_new ("is-audible-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 1, + G_TYPE_BOOLEAN); +} + +static void +meta_bell_init (MetaBell *bell) +{ + meta_prefs_add_listener (prefs_changed_callback, bell); +} + +MetaBell * +meta_bell_new (MetaDisplay *display) +{ + return g_object_new (META_TYPE_BELL, NULL); +} + +/** + * bell_flash_fullscreen: + * @display: The display the event came in on + * @xkb_ev: The bell event + * + * Flashes one screen, or all screens, in response to a bell event. + * If the event is on a particular window, flash the screen that + * window is on. Otherwise, flash every screen on this display. + * + * If the configure script found we had no XKB, this does not exist. + */ +static void +bell_flash_fullscreen (MetaDisplay *display) +{ + meta_compositor_flash_display (display->compositor, display); +} + +static void +bell_flash_window (MetaWindow *window) +{ + meta_compositor_flash_window (window->display->compositor, window); +} + +/** + * bell_flash_frame: + * @display: The display the bell event came in on + * @xkb_ev: The bell event we just received + * + * Flashes the frame of the focused window. If there is no focused window, + * flashes the screen. + */ +static void +bell_flash_frame (MetaDisplay *display, + MetaWindow *window) +{ + if (window) + bell_flash_window (window); + else + bell_flash_fullscreen (display); +} + +/** + * bell_visual_notify: + * @display: The display the bell event came in on + * @xkb_ev: The bell event we just received + * + * Gives the user some kind of visual bell substitute, in response to a + * bell event. What this is depends on the "visual bell type" pref. + */ +static void +bell_visual_notify (MetaDisplay *display, + MetaWindow *window) +{ + switch (meta_prefs_get_visual_bell_type ()) { - XkbSelectEvents (display->xdisplay, - XkbUseCoreKbd, - XkbBellNotifyMask, - XkbBellNotifyMask); - return TRUE; + case C_DESKTOP_VISUAL_BELL_FULLSCREEN_FLASH: + bell_flash_fullscreen (display); + break; + case C_DESKTOP_VISUAL_BELL_FRAME_FLASH: + bell_flash_frame (display, window); + break; } -#endif - return FALSE; } -LOCAL_SYMBOL void -meta_bell_shutdown (MetaDisplay *display) +static gboolean +bell_audible_notify (MetaDisplay *display, + MetaWindow *window) { -#ifdef HAVE_XKB - /* TODO: persist initial bell state in display, reset here */ - XkbChangeEnabledControls (display->xdisplay, - XkbUseCoreKbd, - XkbAudibleBellMask, - XkbAudibleBellMask); -#endif + MetaSoundPlayer *player; + + player = meta_display_get_sound_player (display); + meta_sound_player_play_from_theme (player, + "bell-window-system", + _("Bell event"), + NULL); + return TRUE; } -LOCAL_SYMBOL void +gboolean meta_bell_notify (MetaDisplay *display, - XkbAnyEvent *xkb_ev) + MetaWindow *window) { - XkbBellNotifyEvent *xkb_bell_event = (XkbBellNotifyEvent *) xkb_ev; - MetaWindow *bell_window = NULL; - - bell_window = meta_display_lookup_x_window (display, xkb_bell_event->window); + /* flash something */ + if (meta_prefs_get_visual_bell ()) + bell_visual_notify (display, window); + + if (meta_prefs_bell_is_audible ()) + return bell_audible_notify (display, window); - g_signal_emit_by_name (display, "bell", bell_window); -} \ No newline at end of file + return TRUE; +} diff --git a/src/core/bell.h b/src/core/bell.h index c8c1b185a..f86cbb7c2 100644 --- a/src/core/bell.h +++ b/src/core/bell.h @@ -1,20 +1,8 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/** - * \file bell.h Ring the bell or flash the screen - * - * Sometimes, X programs "ring the bell", whatever that means. Muffin lets - * the user configure the bell to be audible or visible (aka visual), and - * if it's visual it can be configured to be frame-flash or fullscreen-flash. - * We never get told about audible bells; X handles them just fine by itself. - * - * The visual bell was the result of a discussion in Bugzilla here: - * <http://bugzilla.gnome.org/show_bug.cgi?id=99886>. - */ - -/* +/* * Copyright (C) 2002 Sun Microsystems Inc. - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the @@ -24,64 +12,32 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ -#include <X11/Xlib.h> -#ifdef HAVE_XKB -#include <X11/XKBlib.h> -#endif -#include "display-private.h" -#include "window-private.h" +#include "core/display-private.h" +#include "core/frame.h" -#ifdef HAVE_XKB -/** - * Gives the user some kind of visual bell; in fact, this is our response - * to any kind of bell request, but we set it up so that we only get - * notified about visual bells, and X deals with audible ones. - * - * If the configure script found we had no XKB, this does not exist. - * - * \param display The display the bell event came in on - * \param xkb_ev The bell event we just received - */ -void meta_bell_notify (MetaDisplay *display, XkbAnyEvent *xkb_ev); -#endif +struct _MetaBell +{ + GObject parent; +}; -/** - * Initialises the bell subsystem. This involves intialising - * XKB (which, despite being a keyboard extension, is the - * place to look for bell notifications), then asking it - * to send us bell notifications, and then also switching - * off the audible bell if we're using a visual one ourselves. - * - * Unlike most X extensions we use, we only initialise XKB here - * (rather than in main()). It's possible that XKB is not - * installed at all, but if that was known at build time - * we will have HAVE_XKB undefined, which will cause this - * function to be a no-op. - * - * \param display The display which is opening - * - * \bug There is a line of code that's never run that tells - * XKB to reset the bell status after we quit. Bill H said - * (<http://bugzilla.gnome.org/show_bug.cgi?id=99886#c12>) - * that XFree86's implementation is broken so we shouldn't - * call it, but that was in 2002. Is it working now? - */ -gboolean meta_bell_init (MetaDisplay *display); +#define META_TYPE_BELL (meta_bell_get_type ()) +G_DECLARE_FINAL_TYPE (MetaBell, meta_bell, META, BELL, GObject) + +MetaBell * meta_bell_new (MetaDisplay *display); /** - * Shuts down the bell subsystem. - * - * \param display The display which is closing + * meta_bell_notify: + * @display: The display the bell event came in on + * @window: The window the bell event was received on * - * \bug This is never called! If we had XkbSetAutoResetControls - * enabled in meta_bell_init(), this wouldn't be a problem, but - * we don't. + * Gives the user some kind of aural or visual feedback, such as a bell sound + * or flash. What type of feedback is invoked depends on the configuration. + * If the aural feedback could not be invoked, FALSE is returned. */ -void meta_bell_shutdown (MetaDisplay *display); +gboolean meta_bell_notify (MetaDisplay *display, + MetaWindow *window); diff --git a/src/core/boxes-private.h b/src/core/boxes-private.h index d792dc70f..1034a58ad 100644 --- a/src/core/boxes-private.h +++ b/src/core/boxes-private.h @@ -2,9 +2,9 @@ /* Simple box operations */ -/* +/* * Copyright (C) 2005, 2006 Elijah Newren - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the @@ -14,26 +14,25 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_BOXES_PRIVATE_H #define META_BOXES_PRIVATE_H #include <glib-object.h> -#include <meta/common.h> -#include <meta/boxes.h> + +#include "backends/meta-backend-types.h" +#include "core/util-private.h" +#include "meta/boxes.h" +#include "meta/common.h" #define BOX_LEFT(box) ((box).x) /* Leftmost pixel of rect */ #define BOX_RIGHT(box) ((box).x + (box).width) /* One pixel past right */ #define BOX_TOP(box) ((box).y) /* Topmost pixel of rect */ #define BOX_BOTTOM(box) ((box).y + (box).height) /* One pixel past bottom */ -#define BOX_CENTER_X(box) ((box).x + (box).width / 2) /* Center in X */ -#define BOX_CENTER_Y(box) ((box).y + (box).height / 2) /* Center in Y */ typedef enum { @@ -42,12 +41,19 @@ typedef enum FIXED_DIRECTION_Y = 1 << 1, } FixedDirections; +typedef enum _MetaRoundingStrategy +{ + META_ROUNDING_STRATEGY_SHRINK, + META_ROUNDING_STRATEGY_GROW, + META_ROUNDING_STRATEGY_ROUND, +} MetaRoundingStrategy; + /* Output functions -- note that the output buffer had better be big enough: * rect_to_string: RECT_LENGTH * region_to_string: (RECT_LENGTH+strlen(separator_string)) * * g_list_length (region) * edge_to_string: EDGE_LENGTH - * edge_list_to_...: (EDGE_LENGTH+strlen(separator_string)) * + * edge_list_to_...: (EDGE_LENGTH+strlen(separator_string)) * * g_list_length (edge_list) */ #define RECT_LENGTH 27 @@ -67,13 +73,14 @@ char* meta_rectangle_edge_list_to_string ( /* Resize old_rect to the given new_width and new_height, but store the * result in rect. NOTE THAT THIS IS RESIZE ONLY SO IT CANNOT BE USED FOR * A MOVERESIZE OPERATION (that simplies the routine a little bit as it - * means there's no difference between NorthWestGravity and StaticGravity. - * Also, I lied a little bit--technically, you could use it in a MoveResize - * operation if you muck with old_rect just right). + * means there's no difference between META_GRAVITY_NORTH_WEST and + * META_GRAVITY_STATIC. Also, I lied a little bit--technically, you could use + * it in a MoveResize operation if you muck with old_rect just right). */ +META_EXPORT_TEST void meta_rectangle_resize_with_gravity (const MetaRectangle *old_rect, MetaRectangle *rect, - int gravity, + MetaGravity gravity, int new_width, int new_height); @@ -88,6 +95,7 @@ void meta_rectangle_resize_with_gravity (const MetaRectangle *old_rect, * * See boxes.c for more details. */ +META_EXPORT_TEST GList* meta_rectangle_get_minimal_spanning_set_for_region ( const MetaRectangle *basic_rect, const GSList *all_struts); @@ -110,16 +118,11 @@ GList* meta_rectangle_expand_region_conditionally ( const int min_x, const int min_y); -void meta_rectangle_expand_to_snapped_borders (MetaRectangle *rect, - const MetaRectangle *expand_to, - const GSList *all_struts, - const GSList *snapped_windows_as_struts, - const MetaRectangle *user_rect); - /* Expand rect in direction to the size of expand_to, and then clip out any * overlapping struts oriented orthognal to the expansion direction. (Think * horizontal or vertical maximization) */ +META_EXPORT_TEST void meta_rectangle_expand_to_avoiding_struts ( MetaRectangle *rect, const MetaRectangle *expand_to, @@ -133,25 +136,36 @@ void meta_rectangle_expand_to_avoiding_struts ( * or * meta_rectangle_find_nonintersected_monitor_edges() */ +META_EXPORT_TEST void meta_rectangle_free_list_and_elements (GList *filled_list); /* could_fit_in_region determines whether one of the spanning_rects is * big enough to contain rect. contained_in_region checks whether one * actually contains it. */ +META_EXPORT_TEST gboolean meta_rectangle_could_fit_in_region ( const GList *spanning_rects, const MetaRectangle *rect); + +META_EXPORT_TEST gboolean meta_rectangle_contained_in_region ( const GList *spanning_rects, const MetaRectangle *rect); + +META_EXPORT_TEST gboolean meta_rectangle_overlaps_with_region ( const GList *spanning_rects, const MetaRectangle *rect); +gboolean meta_rectangle_has_adjacent_in_region ( + const GList *spanning_rects, + const MetaRectangle *rect); + /* Make the rectangle small enough to fit into one of the spanning_rects, * but make it no smaller than min_size. */ +META_EXPORT_TEST void meta_rectangle_clamp_to_fit_into_region ( const GList *spanning_rects, FixedDirections fixed_directions, @@ -161,6 +175,7 @@ void meta_rectangle_clamp_to_fit_into_region ( /* Clip the rectangle so that it fits into one of the spanning_rects, assuming * it overlaps with at least one of them */ +META_EXPORT_TEST void meta_rectangle_clip_to_region (const GList *spanning_rects, FixedDirections fixed_directions, MetaRectangle *rect); @@ -168,6 +183,7 @@ void meta_rectangle_clip_to_region (const GList *spanning_rects, /* Shove the rectangle into one of the spanning_rects, assuming it fits in * one of them. */ +META_EXPORT_TEST void meta_rectangle_shove_into_region( const GList *spanning_rects, FixedDirections fixed_directions, @@ -177,6 +193,7 @@ void meta_rectangle_shove_into_region( * to (px, py). Useful for finding an optimal rectangle size when given a * range between two sizes that are all candidates. */ +META_EXPORT_TEST void meta_rectangle_find_linepoint_closest_to_point (double x1, double y1, double x2, double y2, double px, double py, @@ -191,18 +208,21 @@ void meta_rectangle_find_linepoint_closest_to_point (double x1, double y1, /* Return whether an edge overlaps or is adjacent to the rectangle in the * nonzero-width dimension of the edge. */ -gboolean meta_rectangle_edge_aligns (const MetaRectangle *rect, +META_EXPORT_TEST +gboolean meta_rectangle_edge_aligns (const MetaRectangle *rect, const MetaEdge *edge); /* Compare two edges, so that sorting functions can put a list of edges in * canonical order. */ +META_EXPORT_TEST gint meta_rectangle_edge_cmp (gconstpointer a, gconstpointer b); /* Compare two edges, so that sorting functions can put a list of edges in * order. This function doesn't separate left edges first, then right edges, * etc., but rather compares only upon location. */ +META_EXPORT_TEST gint meta_rectangle_edge_cmp_ignore_type (gconstpointer a, gconstpointer b); /* Removes an parts of edges in the given list that intersect any box in the @@ -215,14 +235,58 @@ GList* meta_rectangle_remove_intersections_with_boxes_from_edges ( /* Finds all the edges of an onscreen region, returning a GList* of * MetaEdgeRect's. */ +META_EXPORT_TEST GList* meta_rectangle_find_onscreen_edges (const MetaRectangle *basic_rect, const GSList *all_struts); /* Finds edges between adjacent monitors which are not covered by the given * struts. */ +META_EXPORT_TEST GList* meta_rectangle_find_nonintersected_monitor_edges ( const GList *monitor_rects, const GSList *all_struts); +META_EXPORT_TEST +gboolean meta_rectangle_is_adjacent_to (MetaRectangle *rect, + MetaRectangle *other); + +META_EXPORT_TEST +void meta_rectangle_scale_double (const MetaRectangle *rect, + double scale, + MetaRoundingStrategy rounding_strategy, + MetaRectangle *dest); + +static inline graphene_rect_t +meta_rectangle_to_graphene_rect (MetaRectangle *rect) +{ + return (graphene_rect_t) { + .origin = { + .x = rect->x, + .y = rect->y + }, + .size = { + .width = rect->width, + .height = rect->height + } + }; +} + +META_EXPORT_TEST +void meta_rectangle_transform (const MetaRectangle *rect, + MetaMonitorTransform transform, + int width, + int height, + MetaRectangle *dest); + +void meta_rectangle_from_graphene_rect (const graphene_rect_t *rect, + MetaRoundingStrategy rounding_strategy, + MetaRectangle *dest); + +void meta_rectangle_crop_and_scale (const MetaRectangle *rect, + graphene_rect_t *src_rect, + int dst_width, + int dst_height, + MetaRectangle *dest); + #endif /* META_BOXES_PRIVATE_H */ diff --git a/src/core/boxes.c b/src/core/boxes.c index 2a9c4e7c7..93a2b6bf3 100644 --- a/src/core/boxes.c +++ b/src/core/boxes.c @@ -2,8 +2,8 @@ /** * SECTION:boxes - * @title: MetaRectangle - * @short_description: Simple box operations + * @Title: MetaRectangle + * @Short_Description: Simple box operations */ /* @@ -25,21 +25,22 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ -#if HAVE_CONFIG_H -#include <config.h> -#endif -#include "boxes-private.h" -#include <meta/util.h> -#include <X11/Xutil.h> /* Just for the definition of the various gravities */ +#include "config.h" + +#include "backends/meta-monitor-transform.h" +#include "core/boxes-private.h" + +#include <math.h> +#include <X11/Xutil.h> + +#include "meta/util.h" /* It would make sense to use GSlice here, but until we clean up the * rest of this file and the internal API to use these functions, we - * leave it using malloc()/free() for consistency. + * leave it using g_malloc()/g_free() for consistency. */ MetaRectangle * @@ -51,22 +52,13 @@ meta_rectangle_copy (const MetaRectangle *rect) void meta_rectangle_free (MetaRectangle *rect) { - free (rect); + g_free (rect); } -GType -meta_rectangle_get_type (void) -{ - static GType type_id = 0; - - if (!type_id) - type_id = g_boxed_type_register_static (g_intern_static_string ("MetaRectangle"), - (GBoxedCopyFunc) meta_rectangle_copy, - (GBoxedFreeFunc) meta_rectangle_free); - return type_id; -} +G_DEFINE_BOXED_TYPE (MetaRectangle, meta_rectangle, + meta_rectangle_copy, meta_rectangle_free); -LOCAL_SYMBOL char* +char* meta_rectangle_to_string (const MetaRectangle *rect, char *output) { @@ -80,7 +72,7 @@ meta_rectangle_to_string (const MetaRectangle *rect, return output; } -LOCAL_SYMBOL char* +char* meta_rectangle_region_to_string (GList *region, const char *separator_string, char *output) @@ -112,7 +104,7 @@ meta_rectangle_region_to_string (GList *region, return output; } -LOCAL_SYMBOL char* +char* meta_rectangle_edge_to_string (const MetaEdge *edge, char *output) { @@ -130,7 +122,7 @@ meta_rectangle_edge_to_string (const MetaEdge *edge, return output; } -LOCAL_SYMBOL char* +char* meta_rectangle_edge_list_to_string (GList *edge_list, const char *separator_string, char *output) @@ -332,10 +324,10 @@ meta_rectangle_contains_rect (const MetaRectangle *outer_rect, inner_rect->y + inner_rect->height <= outer_rect->y + outer_rect->height; } -LOCAL_SYMBOL void +void meta_rectangle_resize_with_gravity (const MetaRectangle *old_rect, MetaRectangle *rect, - int gravity, + MetaGravity gravity, int new_width, int new_height) { @@ -350,12 +342,12 @@ meta_rectangle_resize_with_gravity (const MetaRectangle *old_rect, * border_width, and old and new client area widths (instead of old total * width and new total width) and you come up with the same formulas. * - * Also, note that the reason we can treat NorthWestGravity and - * StaticGravity the same is because we're not given a location at + * Also, note that the reason we can treat META_GRAVITY_NORTH_WEST and + * META_GRAVITY_STATIC the same is because we're not given a location at * which to place the window--the window was already placed - * appropriately before. So, NorthWestGravity for this function + * appropriately before. So, META_GRAVITY_NORTH_WEST for this function * means to just leave the upper left corner of the outer window - * where it already is, and StaticGravity for this function means to + * where it already is, and META_GRAVITY_STATIC for this function means to * just leave the upper left corner of the inner window where it * already is. But leaving either of those two corners where they * already are will ensure that the other corner is fixed as well @@ -366,15 +358,15 @@ meta_rectangle_resize_with_gravity (const MetaRectangle *old_rect, /* First, the x direction */ switch (gravity) { - case NorthWestGravity: - case WestGravity: - case SouthWestGravity: + case META_GRAVITY_NORTH_WEST: + case META_GRAVITY_WEST: + case META_GRAVITY_SOUTH_WEST: rect->x = old_rect->x; break; - case NorthGravity: - case CenterGravity: - case SouthGravity: + case META_GRAVITY_NORTH: + case META_GRAVITY_CENTER: + case META_GRAVITY_SOUTH: /* FIXME: Needing to adjust new_width kind of sucks, but not doing so * would cause drift. */ @@ -382,13 +374,13 @@ meta_rectangle_resize_with_gravity (const MetaRectangle *old_rect, rect->x = old_rect->x + (old_rect->width - new_width)/2; break; - case NorthEastGravity: - case EastGravity: - case SouthEastGravity: + case META_GRAVITY_NORTH_EAST: + case META_GRAVITY_EAST: + case META_GRAVITY_SOUTH_EAST: rect->x = old_rect->x + (old_rect->width - new_width); break; - case StaticGravity: + case META_GRAVITY_STATIC: default: rect->x = old_rect->x; break; @@ -398,15 +390,15 @@ meta_rectangle_resize_with_gravity (const MetaRectangle *old_rect, /* Next, the y direction */ switch (gravity) { - case NorthWestGravity: - case NorthGravity: - case NorthEastGravity: + case META_GRAVITY_NORTH_WEST: + case META_GRAVITY_NORTH: + case META_GRAVITY_NORTH_EAST: rect->y = old_rect->y; break; - case WestGravity: - case CenterGravity: - case EastGravity: + case META_GRAVITY_WEST: + case META_GRAVITY_CENTER: + case META_GRAVITY_EAST: /* FIXME: Needing to adjust new_height kind of sucks, but not doing so * would cause drift. */ @@ -414,13 +406,13 @@ meta_rectangle_resize_with_gravity (const MetaRectangle *old_rect, rect->y = old_rect->y + (old_rect->height - new_height)/2; break; - case SouthWestGravity: - case SouthGravity: - case SouthEastGravity: + case META_GRAVITY_SOUTH_WEST: + case META_GRAVITY_SOUTH: + case META_GRAVITY_SOUTH_EAST: rect->y = old_rect->y + (old_rect->height - new_height); break; - case StaticGravity: + case META_GRAVITY_STATIC: default: rect->y = old_rect->y; break; @@ -442,8 +434,8 @@ merge_spanning_rects_in_region (GList *region) if (region == NULL) { - meta_warning ("Region to merge was empty! Either you have a some " - "pathological STRUT list or there's a bug somewhere!\n"); + g_warning ("Region to merge was empty! Either you have a some " + "pathological STRUT list or there's a bug somewhere!\n"); return NULL; } @@ -526,7 +518,7 @@ merge_spanning_rects_in_region (GList *region) } /* Okay, we can free it now */ - free (delete_me->data); + g_free (delete_me->data); region = g_list_delete_link (region, delete_me); } @@ -591,7 +583,7 @@ check_strut_align (MetaStrut *strut, const MetaRectangle *rect) * * Returns: (transfer full) (element-type Meta.Rectangle): Minimal spanning set */ -LOCAL_SYMBOL GList* +GList* meta_rectangle_get_minimal_spanning_set_for_region ( const MetaRectangle *basic_rect, const GSList *all_struts) @@ -708,7 +700,7 @@ meta_rectangle_get_minimal_spanning_set_for_region ( temp_rect->y = new_y; ret = g_list_prepend (ret, temp_rect); } - free (rect); + g_free (rect); } rect_iter = rect_iter->next; } @@ -728,7 +720,7 @@ meta_rectangle_get_minimal_spanning_set_for_region ( * meta_rectangle_expand_region: (skip) * */ -LOCAL_SYMBOL GList* +GList* meta_rectangle_expand_region (GList *region, const int left_expand, const int right_expand, @@ -748,7 +740,7 @@ meta_rectangle_expand_region (GList *region, * meta_rectangle_expand_region_conditionally: (skip) * */ -LOCAL_SYMBOL GList* +GList* meta_rectangle_expand_region_conditionally (GList *region, const int left_expand, const int right_expand, @@ -777,163 +769,7 @@ meta_rectangle_expand_region_conditionally (GList *region, return region; } -LOCAL_SYMBOL void -meta_rectangle_expand_to_snapped_borders (MetaRectangle *rect, - const MetaRectangle *expand_to, - const GSList *all_struts, - const GSList *snapped_windows_as_struts, - const MetaRectangle *user_rect) -{ - const GSList *strut_iter; - gint x_c, y_c, max_x, max_y, min_x, min_y, fallback_x, fallback_y, fallback_width, fallback_height; - gboolean ulc = FALSE, llc = FALSE, urc = FALSE, lrc = FALSE; - - x_c = BOX_CENTER_X (*user_rect); - y_c = BOX_TOP (*user_rect); - min_x = BOX_LEFT (*expand_to); - max_x = BOX_RIGHT (*expand_to); - min_y = BOX_TOP (*expand_to); - max_y = BOX_BOTTOM (*expand_to); - - /* Iterate over all struts, find a box containing the center of the current rectangle */ - for (strut_iter = all_struts; strut_iter; strut_iter = strut_iter->next) - { - MetaStrut *strut = (MetaStrut*) strut_iter->data; - - if (!meta_rectangle_overlap (&strut->rect, expand_to)) - continue; - - if (strut->side & META_SIDE_LEFT) - if (BOX_RIGHT (strut->rect) > min_x) - min_x = BOX_RIGHT (strut->rect); - if (strut->side & META_SIDE_RIGHT) - if (BOX_LEFT (strut->rect) < max_x) - max_x = BOX_LEFT (strut->rect); - if (strut->side & META_SIDE_TOP) - if (BOX_BOTTOM (strut->rect) > min_y) - min_y = BOX_BOTTOM (strut->rect); - if (strut->side & META_SIDE_BOTTOM) - if (BOX_TOP (strut->rect) < max_y) - max_y = BOX_TOP (strut->rect); - } /* end loop over struts */ - -/* store safe fallback values if we end up with an impossible situation at the end */ - fallback_x = min_x; - fallback_y = min_y; - fallback_width = max_x - min_x; - fallback_height = max_y - min_y; - - for (strut_iter = snapped_windows_as_struts; strut_iter; strut_iter = strut_iter->next) - { - - MetaStrut *strut = (MetaStrut*) strut_iter->data; - - if (strut->side == (META_SIDE_LEFT | META_SIDE_TOP) || - strut->side == (META_SIDE_LEFT | META_SIDE_BOTTOM) || - strut->side == (META_SIDE_RIGHT | META_SIDE_TOP) || - strut->side == (META_SIDE_RIGHT | META_SIDE_BOTTOM)) { - ulc = ulc || strut->side == (META_SIDE_LEFT | META_SIDE_TOP); - llc = llc || strut->side == (META_SIDE_LEFT | META_SIDE_BOTTOM); - urc = urc || strut->side == (META_SIDE_RIGHT | META_SIDE_TOP); - lrc = lrc || strut->side == (META_SIDE_RIGHT | META_SIDE_BOTTOM); - continue; - } - if (strut->side & META_SIDE_LEFT) - if (BOX_RIGHT (strut->rect) > min_x) - min_x = BOX_RIGHT (strut->rect); - if (strut->side & META_SIDE_RIGHT) - if (BOX_LEFT (strut->rect) < max_x) - max_x = BOX_LEFT (strut->rect); - if (strut->side & META_SIDE_TOP) - if (BOX_BOTTOM (strut->rect) > min_y) - min_y = BOX_BOTTOM (strut->rect); - if (strut->side & META_SIDE_BOTTOM) - if (BOX_TOP (strut->rect) < max_y) - max_y = BOX_TOP (strut->rect); - } /* end loop over struts */ - - for (strut_iter = snapped_windows_as_struts; strut_iter; strut_iter = strut_iter->next) - { - MetaStrut *strut = (MetaStrut*) strut_iter->data; - - if (strut->side == (META_SIDE_LEFT | META_SIDE_TOP)) { - if (llc) { - min_x = BOX_RIGHT (strut->rect); - } - if (urc) { - min_y = BOX_BOTTOM (strut->rect); - } - if (!llc && !urc) { - if (x_c > BOX_RIGHT (strut->rect) && - y_c < BOX_BOTTOM (strut->rect)) - min_x = BOX_RIGHT (strut->rect); - else - min_y = BOX_BOTTOM (strut->rect); - } - } else if (strut->side == (META_SIDE_LEFT | META_SIDE_BOTTOM)) { - if (ulc) { - min_x = BOX_RIGHT (strut->rect); - } - if (lrc) { - max_y = BOX_TOP (strut->rect); - } - if (!ulc && !lrc) { - if (x_c > BOX_RIGHT (strut->rect) && - y_c > BOX_TOP (strut->rect)) { - min_x = BOX_RIGHT (strut->rect); - } else { - max_y = BOX_TOP (strut->rect); - } - } - } else if (strut->side == (META_SIDE_RIGHT | META_SIDE_TOP)) { - if (lrc) { - max_x = BOX_LEFT (strut->rect); - } - if (ulc) { - min_y = BOX_BOTTOM (strut->rect); - } - if (!lrc && !ulc) { - if (x_c < BOX_LEFT (strut->rect) && - y_c < BOX_BOTTOM (strut->rect)) - max_x = BOX_LEFT (strut->rect); - else - min_y = BOX_BOTTOM (strut->rect); - } - } else if (strut->side == (META_SIDE_RIGHT | META_SIDE_BOTTOM)) { - if (urc) { - max_x = BOX_LEFT (strut->rect); - } - if (llc) { - max_y = BOX_TOP (strut->rect); - } - if (!urc && !llc) { - if (x_c < BOX_LEFT (strut->rect) && - y_c > BOX_TOP (strut->rect)) - max_x = BOX_LEFT (strut->rect); - else - max_y = BOX_TOP (strut->rect); - } - } else { - continue; - } - } /* end loop over struts */ - - rect->x = min_x; - rect->y = min_y; - rect->width = max_x - min_x; - rect->height = max_y - min_y; - - if (rect->width <= 0) { - rect->x = fallback_x; - rect->width = fallback_width; - } - if (rect->height <= 0) { - rect->y = fallback_y; - rect->height = fallback_height; - } -} - -LOCAL_SYMBOL void +void meta_rectangle_expand_to_avoiding_struts (MetaRectangle *rect, const MetaRectangle *expand_to, const MetaDirection direction, @@ -1003,16 +839,13 @@ meta_rectangle_expand_to_avoiding_struts (MetaRectangle *rect, } /* end loop over struts */ } /* end meta_rectangle_expand_to_avoiding_struts */ -LOCAL_SYMBOL void +void meta_rectangle_free_list_and_elements (GList *filled_list) { - g_list_foreach (filled_list, - (void (*)(gpointer,gpointer))&free, /* ew, for ugly */ - NULL); - g_list_free (filled_list); + g_list_free_full (filled_list, g_free); } -LOCAL_SYMBOL gboolean +gboolean meta_rectangle_could_fit_in_region (const GList *spanning_rects, const MetaRectangle *rect) { @@ -1030,7 +863,7 @@ meta_rectangle_could_fit_in_region (const GList *spanning_rects, return could_fit; } -LOCAL_SYMBOL gboolean +gboolean meta_rectangle_contained_in_region (const GList *spanning_rects, const MetaRectangle *rect) { @@ -1048,7 +881,7 @@ meta_rectangle_contained_in_region (const GList *spanning_rects, return contained; } -LOCAL_SYMBOL gboolean +gboolean meta_rectangle_overlaps_with_region (const GList *spanning_rects, const MetaRectangle *rect) { @@ -1066,8 +899,29 @@ meta_rectangle_overlaps_with_region (const GList *spanning_rects, return overlaps; } +gboolean +meta_rectangle_has_adjacent_in_region (const GList *spanning_rects, + const MetaRectangle *rect) +{ + const GList *l; + + for (l = spanning_rects; l; l = l->next) + { + MetaRectangle *other = (MetaRectangle *) l->data; -LOCAL_SYMBOL void + if (rect == other || meta_rectangle_equal (rect, other)) + continue; + + if (meta_rectangle_is_adjacent_to ((MetaRectangle *) rect, other)) + { + return TRUE; + } + } + + return FALSE; +} + +void meta_rectangle_clamp_to_fit_into_region (const GList *spanning_rects, FixedDirections fixed_directions, MetaRectangle *rect, @@ -1122,7 +976,7 @@ meta_rectangle_clamp_to_fit_into_region (const GList *spanning_rects, /* Clamp rect appropriately */ if (best_rect == NULL) { - meta_warning ("No rect whose size to clamp to found!\n"); + g_warning ("No rect whose size to clamp to found!\n"); /* If it doesn't fit, at least make it no bigger than it has to be */ if (!(fixed_directions & FIXED_DIRECTION_X)) @@ -1137,7 +991,7 @@ meta_rectangle_clamp_to_fit_into_region (const GList *spanning_rects, } } -LOCAL_SYMBOL void +void meta_rectangle_clip_to_region (const GList *spanning_rects, FixedDirections fixed_directions, MetaRectangle *rect) @@ -1185,7 +1039,9 @@ meta_rectangle_clip_to_region (const GList *spanning_rects, /* Clip rect appropriately */ if (best_rect == NULL) - meta_warning ("No rect to clip to found!\n"); + { + g_warning ("No rect to clip to found!\n"); + } else { /* Extra precaution with checking fixed direction shouldn't be needed @@ -1214,7 +1070,7 @@ meta_rectangle_clip_to_region (const GList *spanning_rects, } } -LOCAL_SYMBOL void +void meta_rectangle_shove_into_region (const GList *spanning_rects, FixedDirections fixed_directions, MetaRectangle *rect) @@ -1281,7 +1137,9 @@ meta_rectangle_shove_into_region (const GList *spanning_rects, /* Shove rect appropriately */ if (best_rect == NULL) - meta_warning ("No rect to shove into found!\n"); + { + g_warning ("No rect to shove into found!\n"); + } else { /* Extra precaution with checking fixed direction shouldn't be needed @@ -1314,7 +1172,7 @@ meta_rectangle_shove_into_region (const GList *spanning_rects, } } -LOCAL_SYMBOL void +void meta_rectangle_find_linepoint_closest_to_point (double x1, double y1, double x2, @@ -1377,7 +1235,7 @@ meta_rectangle_find_linepoint_closest_to_point (double x1, /* */ /***************************************************************************/ -LOCAL_SYMBOL gboolean +gboolean meta_rectangle_edge_aligns (const MetaRectangle *rect, const MetaEdge *edge) { /* The reason for the usage of <= below instead of < is because we are @@ -1398,6 +1256,7 @@ meta_rectangle_edge_aligns (const MetaRectangle *rect, const MetaEdge *edge) BOX_LEFT (edge->rect) <= BOX_RIGHT (*rect); default: g_assert_not_reached (); + return FALSE; } } @@ -1476,7 +1335,7 @@ replace_rect_with_list (GList *old_element, } /* Free the old_element and return the appropriate "next" point */ - free (old_element->data); + g_free (old_element->data); g_list_free_1 (old_element); return ret; } @@ -1504,7 +1363,7 @@ get_disjoint_strut_rect_list_in_region (const GSList *old_struts, if (meta_rectangle_intersect (copy, region, copy)) strut_rects = g_list_prepend (strut_rects, copy); else - free (copy); + g_free (copy); old_struts = old_struts->next; } @@ -1563,7 +1422,7 @@ get_disjoint_strut_rect_list_in_region (const GSList *old_struts, return strut_rects; } -LOCAL_SYMBOL gint +gint meta_rectangle_edge_cmp_ignore_type (gconstpointer a, gconstpointer b) { const MetaEdge *a_edge_rect = (gconstpointer) a; @@ -1607,7 +1466,7 @@ meta_rectangle_edge_cmp_ignore_type (gconstpointer a, gconstpointer b) } /* To make things easily testable, provide a nice way of sorting edges */ -LOCAL_SYMBOL gint +gint meta_rectangle_edge_cmp (gconstpointer a, gconstpointer b) { const MetaEdge *a_edge_rect = (gconstpointer) a; @@ -1872,7 +1731,7 @@ fix_up_edges (MetaRectangle *rect, MetaEdge *edge, /* Delete the old one */ tmp = tmp->next; - free (cur); + g_free (cur); *strut_edges = g_list_delete_link (*strut_edges, delete_me); } else @@ -1887,7 +1746,7 @@ fix_up_edges (MetaRectangle *rect, MetaEdge *edge, * This function removes intersections of edges with the rectangles from the * list of edges. */ -LOCAL_SYMBOL GList* +GList* meta_rectangle_remove_intersections_with_boxes_from_edges ( GList *edges, const GSList *rectangles) @@ -1935,7 +1794,7 @@ meta_rectangle_remove_intersections_with_boxes_from_edges ( edges = split_edge (edges, edge, &overlap); /* Now free the edge... */ - free (edge); + g_free (edge); edges = g_list_delete_link (edges, delete_me); } } @@ -1955,7 +1814,7 @@ meta_rectangle_remove_intersections_with_boxes_from_edges ( * * This function is trying to find all the edges of an onscreen region. */ -LOCAL_SYMBOL GList* +GList* meta_rectangle_find_onscreen_edges (const MetaRectangle *basic_rect, const GSList *all_struts) { @@ -2010,7 +1869,7 @@ meta_rectangle_find_onscreen_edges (const MetaRectangle *basic_rect, /* Delete the old edge */ GList *delete_me = edge_iter; edge_iter = edge_iter->next; - free (cur_edge); + g_free (cur_edge); ret = g_list_delete_link (ret, delete_me); /* Add the new split parts of the edge */ @@ -2041,7 +1900,7 @@ meta_rectangle_find_onscreen_edges (const MetaRectangle *basic_rect, * meta_rectangle_find_nonintersected_monitor_edges: (skip) * */ -LOCAL_SYMBOL GList* +GList* meta_rectangle_find_nonintersected_monitor_edges ( const GList *monitor_rects, const GSList *all_struts) @@ -2174,3 +2033,172 @@ meta_rectangle_find_nonintersected_monitor_edges ( return ret; } + +gboolean +meta_rectangle_is_adjacent_to (MetaRectangle *rect, + MetaRectangle *other) +{ + int rect_x1 = rect->x; + int rect_y1 = rect->y; + int rect_x2 = rect->x + rect->width; + int rect_y2 = rect->y + rect->height; + int other_x1 = other->x; + int other_y1 = other->y; + int other_x2 = other->x + other->width; + int other_y2 = other->y + other->height; + + if ((rect_x1 == other_x2 || rect_x2 == other_x1) && + !(rect_y2 <= other_y1 || rect_y1 >= other_y2)) + return TRUE; + else if ((rect_y1 == other_y2 || rect_y2 == other_y1) && + !(rect_x2 <= other_x1 || rect_x1 >= other_x2)) + return TRUE; + else + return FALSE; +} + +void +meta_rectangle_scale_double (const MetaRectangle *rect, + double scale, + MetaRoundingStrategy rounding_strategy, + MetaRectangle *dest) +{ + graphene_rect_t tmp = GRAPHENE_RECT_INIT (rect->x, rect->y, + rect->width, rect->height); + + graphene_rect_scale (&tmp, scale, scale, &tmp); + meta_rectangle_from_graphene_rect (&tmp, rounding_strategy, dest); +} + +void +meta_rectangle_transform (const MetaRectangle *rect, + MetaMonitorTransform transform, + int width, + int height, + MetaRectangle *dest) +{ + switch (transform) + { + case META_MONITOR_TRANSFORM_NORMAL: + *dest = *rect; + break; + case META_MONITOR_TRANSFORM_90: + *dest = (MetaRectangle) { + .x = width - (rect->y + rect->height), + .y = rect->x, + .width = rect->height, + .height = rect->width, + }; + break; + case META_MONITOR_TRANSFORM_180: + *dest = (MetaRectangle) { + .x = width - (rect->x + rect->width), + .y = height - (rect->y + rect->height), + .width = rect->width, + .height = rect->height, + }; + break; + case META_MONITOR_TRANSFORM_270: + *dest = (MetaRectangle) { + .x = rect->y, + .y = height - (rect->x + rect->width), + .width = rect->height, + .height = rect->width, + }; + break; + case META_MONITOR_TRANSFORM_FLIPPED: + *dest = (MetaRectangle) { + .x = width - (rect->x + rect->width), + .y = rect->y, + .width = rect->width, + .height = rect->height, + }; + break; + case META_MONITOR_TRANSFORM_FLIPPED_90: + *dest = (MetaRectangle) { + .x = width - (rect->y + rect->height), + .y = height - (rect->x + rect->width), + .width = rect->height, + .height = rect->width, + }; + break; + case META_MONITOR_TRANSFORM_FLIPPED_180: + *dest = (MetaRectangle) { + .x = rect->x, + .y = height - (rect->y + rect->height), + .width = rect->width, + .height = rect->height, + }; + break; + case META_MONITOR_TRANSFORM_FLIPPED_270: + *dest = (MetaRectangle) { + .x = rect->y, + .y = rect->x, + .width = rect->height, + .height = rect->width, + }; + break; + } +} + +void +meta_rectangle_from_graphene_rect (const graphene_rect_t *rect, + MetaRoundingStrategy rounding_strategy, + MetaRectangle *dest) +{ + switch (rounding_strategy) + { + case META_ROUNDING_STRATEGY_SHRINK: + { + *dest = (MetaRectangle) { + .x = ceilf (rect->origin.x), + .y = ceilf (rect->origin.y), + .width = floorf (rect->size.width), + .height = floorf (rect->size.height), + }; + } + break; + case META_ROUNDING_STRATEGY_GROW: + { + graphene_rect_t clamped = *rect; + + graphene_rect_round_extents (&clamped, &clamped); + + *dest = (MetaRectangle) { + .x = clamped.origin.x, + .y = clamped.origin.y, + .width = clamped.size.width, + .height = clamped.size.height, + }; + } + break; + case META_ROUNDING_STRATEGY_ROUND: + { + *dest = (MetaRectangle) { + .x = roundf (rect->origin.x), + .y = roundf (rect->origin.y), + .width = roundf (rect->size.width), + .height = roundf (rect->size.height), + }; + } + } +} + +void +meta_rectangle_crop_and_scale (const MetaRectangle *rect, + graphene_rect_t *src_rect, + int dst_width, + int dst_height, + MetaRectangle *dest) +{ + graphene_rect_t tmp = GRAPHENE_RECT_INIT (rect->x, rect->y, + rect->width, rect->height); + + graphene_rect_scale (&tmp, + src_rect->size.width / dst_width, + src_rect->size.height / dst_height, + &tmp); + graphene_rect_offset (&tmp, src_rect->origin.x, src_rect->origin.y); + + meta_rectangle_from_graphene_rect (&tmp, META_ROUNDING_STRATEGY_GROW, dest); +} diff --git a/src/core/constraints.c b/src/core/constraints.c index cb16d5d83..225ea3a85 100644 --- a/src/core/constraints.c +++ b/src/core/constraints.c @@ -1,6 +1,6 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* Muffin size/position constraints */ +/* Mutter size/position constraints */ /* * Copyright (C) 2002, 2003 Red Hat, Inc. @@ -18,21 +18,25 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ -#include <config.h> -#include "boxes-private.h" -#include "constraints.h" -#include "workspace-private.h" -#include "place.h" -#include <meta/prefs.h> -#include "xprops.h" +#include "config.h" + +#include "core/constraints.h" + #include <stdlib.h> #include <math.h> +#include "backends/meta-backend-private.h" +#include "backends/meta-logical-monitor.h" +#include "backends/meta-monitor-manager-private.h" +#include "core/boxes-private.h" +#include "core/meta-workspace-manager-private.h" +#include "core/place.h" +#include "core/workspace-private.h" +#include "meta/prefs.h" + #if 0 // This is the short and sweet version of how to hack on this file; see // doc/how-constraints-works.txt for the gory details. The basics of @@ -104,6 +108,7 @@ typedef enum PRIORITY_SIZE_HINTS_LIMITS = 3, PRIORITY_TITLEBAR_VISIBLE = 4, PRIORITY_PARTIALLY_VISIBLE_ON_WORKAREA = 4, + PRIORITY_CUSTOM_RULE = 4, PRIORITY_MAXIMUM = 4 /* Dummy value used for loop end = max(all priorities) */ } ConstraintPriority; @@ -118,8 +123,9 @@ typedef struct { MetaRectangle orig; MetaRectangle current; - MetaFrameBorders *borders; - gboolean must_free_borders; + MetaRectangle temporary; + int rel_x; + int rel_y; ActionType action_type; gboolean is_user_action; @@ -128,7 +134,7 @@ typedef struct * explanation of the differences and similarity between resize_gravity * and fixed_directions */ - int resize_gravity; + MetaGravity resize_gravity; FixedDirections fixed_directions; /* work_area_monitor - current monitor region minus struts @@ -142,12 +148,18 @@ typedef struct */ GList *usable_screen_region; GList *usable_monitor_region; + + MetaMoveResizeFlags flags; } ConstraintInfo; static gboolean do_screen_and_monitor_relative_constraints (MetaWindow *window, GList *region_spanning_rectangles, ConstraintInfo *info, gboolean check_only); +static gboolean constrain_custom_rule (MetaWindow *window, + ConstraintInfo *info, + ConstraintPriority priority, + gboolean check_only); static gboolean constrain_modal_dialog (MetaWindow *window, ConstraintInfo *info, ConstraintPriority priority, @@ -195,9 +207,8 @@ static gboolean constrain_partially_onscreen (MetaWindow *window, static void setup_constraint_info (ConstraintInfo *info, MetaWindow *window, - MetaFrameBorders *orig_borders, MetaMoveResizeFlags flags, - int resize_gravity, + MetaGravity resize_gravity, const MetaRectangle *orig, MetaRectangle *new); static void place_window_if_needed (MetaWindow *window, @@ -205,12 +216,6 @@ static void place_window_if_needed (MetaWindow *window, static void update_onscreen_requirements (MetaWindow *window, ConstraintInfo *info); -static inline void get_size_limits (const MetaWindow *window, - const MetaFrameBorders *borders, - gboolean include_frame, - MetaRectangle *min_size, - MetaRectangle *max_size); - typedef gboolean (* ConstraintFunc) (MetaWindow *window, ConstraintInfo *info, ConstraintPriority priority, @@ -222,6 +227,7 @@ typedef struct { } Constraint; static const Constraint all_constraints[] = { + {constrain_custom_rule, "constrain_custom_rule"}, {constrain_modal_dialog, "constrain_modal_dialog"}, {constrain_maximization, "constrain_maximization"}, {constrain_tiling, "constrain_tiling"}, @@ -275,23 +281,20 @@ do_all_constraints (MetaWindow *window, return TRUE; } -LOCAL_SYMBOL void +void meta_window_constrain (MetaWindow *window, - MetaFrameBorders *orig_borders, MetaMoveResizeFlags flags, - int resize_gravity, + MetaGravity resize_gravity, const MetaRectangle *orig, - MetaRectangle *new) + MetaRectangle *new, + MetaRectangle *temporary, + int *rel_x, + int *rel_y) { ConstraintInfo info; ConstraintPriority priority = PRIORITY_MINIMUM; gboolean satisfied = FALSE; - /* WARNING: orig and new specify positions and sizes of the inner window, - * not the outer. This is a common gotcha since half the constraints - * deal with inner window position/size and half deal with outer. See - * doc/how-constraints-works.txt for more information. - */ meta_topic (META_DEBUG_GEOMETRY, "Constraining %s in move from %d,%d %dx%d to %d,%d %dx%d\n", window->desc, @@ -300,7 +303,6 @@ meta_window_constrain (MetaWindow *window, setup_constraint_info (&info, window, - orig_borders, flags, resize_gravity, orig, @@ -324,59 +326,54 @@ meta_window_constrain (MetaWindow *window, /* Make sure we use the constrained position */ *new = info.current; + *temporary = info.temporary; + *rel_x = info.rel_x; + *rel_y = info.rel_y; /* We may need to update window->require_fully_onscreen, * window->require_on_single_monitor, and perhaps other quantities * if this was a user move or user move-and-resize operation. */ update_onscreen_requirements (window, &info); - - /* Ew, what an ugly way to do things. Destructors (in a real OOP language, - * not gobject-style--gobject would be more pain than it's worth) or - * smart pointers would be so much nicer here. *shrug* - */ - if (info.must_free_borders) - free (info.borders); } static void setup_constraint_info (ConstraintInfo *info, MetaWindow *window, - MetaFrameBorders *orig_borders, MetaMoveResizeFlags flags, - int resize_gravity, + MetaGravity resize_gravity, const MetaRectangle *orig, MetaRectangle *new) { - const MetaMonitorInfo *monitor_info; + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaLogicalMonitor *logical_monitor; MetaWorkspace *cur_workspace; info->orig = *orig; info->current = *new; + info->temporary = *orig; + info->rel_x = 0; + info->rel_y = 0; + info->flags = flags; - /* Create a fake frame geometry if none really exists */ - if (orig_borders && !window->fullscreen) - { - info->borders = orig_borders; - info->must_free_borders = FALSE; - } - else - { - info->borders = g_new0 (MetaFrameBorders, 1); - info->must_free_borders = TRUE; - } + if (info->current.width < 1) + info->current.width = 1; + if (info->current.height < 1) + info->current.height = 1; - if (flags & META_IS_MOVE_ACTION && flags & META_IS_RESIZE_ACTION) + if (flags & META_MOVE_RESIZE_MOVE_ACTION && flags & META_MOVE_RESIZE_RESIZE_ACTION) info->action_type = ACTION_MOVE_AND_RESIZE; - else if (flags & META_IS_RESIZE_ACTION) + else if (flags & META_MOVE_RESIZE_RESIZE_ACTION) info->action_type = ACTION_RESIZE; - else if (flags & META_IS_MOVE_ACTION) + else if (flags & META_MOVE_RESIZE_MOVE_ACTION) info->action_type = ACTION_MOVE; else g_error ("BAD, BAD developer! No treat for you! (Fix your calls to " "meta_window_move_resize_internal()).\n"); - info->is_user_action = (flags & META_IS_USER_ACTION); + info->is_user_action = (flags & META_MOVE_RESIZE_USER_ACTION); info->resize_gravity = resize_gravity; @@ -408,39 +405,38 @@ setup_constraint_info (ConstraintInfo *info, if (!info->is_user_action) info->fixed_directions = FIXED_DIRECTION_NONE; - monitor_info = - meta_screen_get_monitor_for_rect (window->screen, &info->current); - meta_window_get_work_area_for_monitor (window, - monitor_info->number, - &info->work_area_monitor); + logical_monitor = + meta_monitor_manager_get_logical_monitor_from_rect (monitor_manager, + &info->current); + meta_window_get_work_area_for_logical_monitor (window, + logical_monitor, + &info->work_area_monitor); - if (!window->fullscreen || window->fullscreen_monitors[0] == -1) + if (window->fullscreen && meta_window_has_fullscreen_monitors (window)) { - info->entire_monitor = monitor_info->rect; + info->entire_monitor = window->fullscreen_monitors.top->rect; + meta_rectangle_union (&info->entire_monitor, + &window->fullscreen_monitors.bottom->rect, + &info->entire_monitor); + meta_rectangle_union (&info->entire_monitor, + &window->fullscreen_monitors.left->rect, + &info->entire_monitor); + meta_rectangle_union (&info->entire_monitor, + &window->fullscreen_monitors.right->rect, + &info->entire_monitor); } else { - int i = 0; - long monitor; - - monitor = window->fullscreen_monitors[i]; - info->entire_monitor = - window->screen->monitor_infos[monitor].rect; - for (i = 1; i <= 3; i++) - { - monitor = window->fullscreen_monitors[i]; - meta_rectangle_union (&info->entire_monitor, - &window->screen->monitor_infos[monitor].rect, - &info->entire_monitor); - } + info->entire_monitor = logical_monitor->rect; + if (window->fullscreen) + meta_window_adjust_fullscreen_monitor_rect (window, &info->entire_monitor); } - cur_workspace = window->screen->active_workspace; + cur_workspace = window->display->workspace_manager->active_workspace; info->usable_screen_region = meta_workspace_get_onscreen_region (cur_workspace); info->usable_monitor_region = - meta_workspace_get_onmonitor_region (cur_workspace, - monitor_info->number); + meta_workspace_get_onmonitor_region (cur_workspace, logical_monitor); /* Log all this information for debugging */ meta_topic (META_DEBUG_GEOMETRY, @@ -473,6 +469,16 @@ setup_constraint_info (ConstraintInfo *info, info->entire_monitor.width, info->entire_monitor.height); } +static MetaRectangle * +get_start_rect_for_resize (MetaWindow *window, + ConstraintInfo *info) +{ + if (!info->is_user_action && info->action_type == ACTION_MOVE_AND_RESIZE) + return &info->current; + else + return &info->orig; +} + static void place_window_if_needed(MetaWindow *window, ConstraintInfo *info) @@ -492,28 +498,51 @@ place_window_if_needed(MetaWindow *window, !window->minimized && !window->fullscreen) { - MetaRectangle placed_rect = info->orig; + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaRectangle orig_rect; + MetaRectangle placed_rect; MetaWorkspace *cur_workspace; - const MetaMonitorInfo *monitor_info; + MetaLogicalMonitor *logical_monitor; + + placed_rect = (MetaRectangle) { + .x = window->rect.x, + .y = window->rect.y, + .width = info->current.width, + .height = info->current.height + }; - meta_window_place (window, info->borders, info->orig.x, info->orig.y, - &placed_rect.x, &placed_rect.y); + orig_rect = info->orig; + + if (window->placement.rule) + { + meta_window_process_placement (window, + window->placement.rule, + &info->rel_x, &info->rel_y); + placed_rect.x = window->placement.rule->parent_rect.x + info->rel_x; + placed_rect.y = window->placement.rule->parent_rect.y + info->rel_y; + } + else + { + meta_window_place (window, orig_rect.x, orig_rect.y, + &placed_rect.x, &placed_rect.y); + } did_placement = TRUE; /* placing the window may have changed the monitor. Find the * new monitor and update the ConstraintInfo */ - monitor_info = - meta_screen_get_monitor_for_rect (window->screen, &placed_rect); - info->entire_monitor = monitor_info->rect; - meta_window_get_work_area_for_monitor (window, - monitor_info->number, - &info->work_area_monitor); - cur_workspace = window->screen->active_workspace; + logical_monitor = + meta_monitor_manager_get_logical_monitor_from_rect (monitor_manager, + &placed_rect); + info->entire_monitor = logical_monitor->rect; + meta_window_get_work_area_for_logical_monitor (window, + logical_monitor, + &info->work_area_monitor); + cur_workspace = window->display->workspace_manager->active_workspace; info->usable_monitor_region = - meta_workspace_get_onmonitor_region (cur_workspace, - monitor_info->number); - + meta_workspace_get_onmonitor_region (cur_workspace, logical_monitor); info->current.x = placed_rect.x; info->current.y = placed_rect.y; @@ -529,8 +558,8 @@ place_window_if_needed(MetaWindow *window, if (window->maximize_horizontally_after_placement || window->maximize_vertically_after_placement) { - /* define a sane saved_rect so that the user can unmaximize or - * make unfullscreen to something reasonable. + /* define a sane saved_rect so that the user can unmaximize to + * something reasonable. */ if (info->current.width >= info->work_area_monitor.width) { @@ -545,10 +574,10 @@ place_window_if_needed(MetaWindow *window, .083 * info->work_area_monitor.height; } - /* idle_move_resize() uses the user_rect, - * so make sure it uses the placed coordinates. + /* idle_move_resize() uses the unconstrained_rect, so make sure it + * uses the placed coordinates (bug #556696). */ - window->user_rect = info->current; + window->unconstrained_rect = info->current; if (window->maximize_horizontally_after_placement || window->maximize_vertically_after_placement) @@ -558,10 +587,6 @@ place_window_if_needed(MetaWindow *window, (window->maximize_vertically_after_placement ? META_MAXIMIZE_VERTICAL : 0), &info->current); - /* maximization may have changed frame geometry */ - if (!window->fullscreen) - meta_frame_calc_borders (window->frame, info->borders); - window->maximize_horizontally_after_placement = FALSE; window->maximize_vertically_after_placement = FALSE; } @@ -570,41 +595,6 @@ place_window_if_needed(MetaWindow *window, meta_window_minimize (window); window->minimize_after_placement = FALSE; } - if (window->tile_after_placement) - { - window->tile_after_placement = FALSE; - - gulong *tile_info = NULL; - int nitems; - - if (meta_prop_get_cardinal_list (window->display, - window->xwindow, - window->display->atom__NET_WM_WINDOW_TILE_INFO, - &tile_info, &nitems)) - { - if (nitems == 8) - { - window->tile_mode = (MetaTileMode) tile_info[0]; - meta_window_move_resize_frame (window, - TRUE, - tile_info[2], - tile_info[3], - tile_info[4], - tile_info[5]); - window->custom_snap_size = tile_info[7] == 1; - window->tile_monitor_number = tile_info[6]; - if (tile_info[1] == META_WINDOW_TILE_TYPE_SNAPPED) - window->snap_queued = TRUE; - else - window->snap_queued = FALSE; - meta_window_real_tile (window, TRUE); - window->saved_rect = info->current; - - meta_XFree (tile_info); - } - } - - } } } @@ -644,11 +634,6 @@ update_onscreen_requirements (MetaWindow *window, * problematic case but this may need to be revisited. */ - /* The require onscreen/on-single-monitor and titlebar_visible - * stuff is relative to the outer window, not the inner - */ - meta_window_extend_by_frame (window, &info->current, info->borders); - /* Update whether we want future constraint runs to require the * window to be on fully onscreen. */ @@ -656,13 +641,12 @@ update_onscreen_requirements (MetaWindow *window, window->require_fully_onscreen = meta_rectangle_contained_in_region (info->usable_screen_region, &info->current); -#ifdef WITH_VERBOSE_MODE - if (old ^ window->require_fully_onscreen) + if (old != window->require_fully_onscreen) meta_topic (META_DEBUG_GEOMETRY, "require_fully_onscreen for %s toggled to %s\n", window->desc, window->require_fully_onscreen ? "TRUE" : "FALSE"); -#endif + /* Update whether we want future constraint runs to require the * window to be on a single monitor. */ @@ -670,74 +654,443 @@ update_onscreen_requirements (MetaWindow *window, window->require_on_single_monitor = meta_rectangle_contained_in_region (info->usable_monitor_region, &info->current); -#ifdef WITH_VERBOSE_MODE - if (old ^ window->require_on_single_monitor) + if (old != window->require_on_single_monitor) meta_topic (META_DEBUG_GEOMETRY, "require_on_single_monitor for %s toggled to %s\n", window->desc, window->require_on_single_monitor ? "TRUE" : "FALSE"); -#endif + /* Update whether we want future constraint runs to require the * titlebar to be visible. */ - - MetaRectangle titlebar_rect; - - meta_window_get_titlebar_rect (window, &titlebar_rect); - - titlebar_rect.x += info->current.x; - titlebar_rect.y += info->current.y; - - old = window->require_titlebar_visible; - window->require_titlebar_visible = - meta_rectangle_overlaps_with_region (info->usable_screen_region, - &titlebar_rect); -#ifdef WITH_VERBOSE_MODE - if (old ^ window->require_titlebar_visible) - meta_topic (META_DEBUG_GEOMETRY, - "require_titlebar_visible for %s toggled to %s\n", - window->desc, - window->require_titlebar_visible ? "TRUE" : "FALSE"); -#endif - - /* Don't forget to restore the position of the window */ - meta_window_unextend_by_frame (window, &info->current, info->borders); + if (window->frame && window->decorated) + { + MetaRectangle titlebar_rect, frame_rect; + + meta_window_get_titlebar_rect (window, &titlebar_rect); + meta_window_get_frame_rect (window, &frame_rect); + + /* translate into screen coordinates */ + titlebar_rect.x = frame_rect.x; + titlebar_rect.y = frame_rect.y; + + old = window->require_titlebar_visible; + window->require_titlebar_visible = + meta_rectangle_overlaps_with_region (info->usable_screen_region, + &titlebar_rect); + if (old != window->require_titlebar_visible) + meta_topic (META_DEBUG_GEOMETRY, + "require_titlebar_visible for %s toggled to %s\n", + window->desc, + window->require_titlebar_visible ? "TRUE" : "FALSE"); + } } static inline void -get_size_limits (const MetaWindow *window, - const MetaFrameBorders *borders, - gboolean include_frame, - MetaRectangle *min_size, - MetaRectangle *max_size) +get_size_limits (MetaWindow *window, + MetaRectangle *min_size, + MetaRectangle *max_size) { /* We pack the results into MetaRectangle structs just for convienience; we * don't actually use the position of those rects. */ + min_size->x = min_size->y = max_size->x = max_size->y = 0; min_size->width = window->size_hints.min_width; min_size->height = window->size_hints.min_height; max_size->width = window->size_hints.max_width; max_size->height = window->size_hints.max_height; - if (include_frame) + meta_window_client_rect_to_frame_rect (window, min_size, min_size); + meta_window_client_rect_to_frame_rect (window, max_size, max_size); +} + +static void +placement_rule_flip_horizontally (MetaPlacementRule *placement_rule) +{ + if (placement_rule->anchor & META_PLACEMENT_ANCHOR_LEFT) + { + placement_rule->anchor &= ~META_PLACEMENT_ANCHOR_LEFT; + placement_rule->anchor |= META_PLACEMENT_ANCHOR_RIGHT; + } + else if (placement_rule->anchor & META_PLACEMENT_ANCHOR_RIGHT) { - int fw = borders->visible.left + borders->visible.right; - int fh = borders->visible.top + borders->visible.bottom; + placement_rule->anchor &= ~META_PLACEMENT_ANCHOR_RIGHT; + placement_rule->anchor |= META_PLACEMENT_ANCHOR_LEFT; + } - min_size->width += fw; - min_size->height += fh; - /* Do check to avoid overflow (e.g. max_size->width & max_size->height - * may be set to G_MAXINT by meta_set_normal_hints()). - */ - if (max_size->width < (G_MAXINT - fw)) - max_size->width += fw; + if (placement_rule->gravity & META_PLACEMENT_GRAVITY_LEFT) + { + placement_rule->gravity &= ~META_PLACEMENT_GRAVITY_LEFT; + placement_rule->gravity |= META_PLACEMENT_GRAVITY_RIGHT; + } + else if (placement_rule->gravity & META_PLACEMENT_GRAVITY_RIGHT) + { + placement_rule->gravity &= ~META_PLACEMENT_GRAVITY_RIGHT; + placement_rule->gravity |= META_PLACEMENT_GRAVITY_LEFT; + } +} + +static void +placement_rule_flip_vertically (MetaPlacementRule *placement_rule) +{ + if (placement_rule->anchor & META_PLACEMENT_ANCHOR_TOP) + { + placement_rule->anchor &= ~META_PLACEMENT_ANCHOR_TOP; + placement_rule->anchor |= META_PLACEMENT_ANCHOR_BOTTOM; + } + else if (placement_rule->anchor & META_PLACEMENT_ANCHOR_BOTTOM) + { + placement_rule->anchor &= ~META_PLACEMENT_ANCHOR_BOTTOM; + placement_rule->anchor |= META_PLACEMENT_ANCHOR_TOP; + } + + if (placement_rule->gravity & META_PLACEMENT_GRAVITY_TOP) + { + placement_rule->gravity &= ~META_PLACEMENT_GRAVITY_TOP; + placement_rule->gravity |= META_PLACEMENT_GRAVITY_BOTTOM; + } + else if (placement_rule->gravity & META_PLACEMENT_GRAVITY_BOTTOM) + { + placement_rule->gravity &= ~META_PLACEMENT_GRAVITY_BOTTOM; + placement_rule->gravity |= META_PLACEMENT_GRAVITY_TOP; + } +} + +static void +try_flip_window_position (MetaWindow *window, + ConstraintInfo *info, + MetaPlacementRule *placement_rule, + MetaPlacementConstraintAdjustment constraint_adjustment, + int parent_x, + int parent_y, + MetaRectangle *rect, + int *rel_x, + int *rel_y, + MetaRectangle *intersection) +{ + MetaPlacementRule flipped_rule = *placement_rule;; + MetaRectangle flipped_rect; + MetaRectangle flipped_intersection; + int flipped_rel_x; + int flipped_rel_y; + + switch (constraint_adjustment) + { + case META_PLACEMENT_CONSTRAINT_ADJUSTMENT_FLIP_X: + placement_rule_flip_horizontally (&flipped_rule); + break; + case META_PLACEMENT_CONSTRAINT_ADJUSTMENT_FLIP_Y: + placement_rule_flip_vertically (&flipped_rule); + break; + + default: + g_assert_not_reached (); + } + + flipped_rect = info->current; + meta_window_process_placement (window, &flipped_rule, + &flipped_rel_x, &flipped_rel_y); + flipped_rect.x = parent_x + flipped_rel_x; + flipped_rect.y = parent_y + flipped_rel_y; + meta_rectangle_intersect (&flipped_rect, &info->work_area_monitor, + &flipped_intersection); + + if ((constraint_adjustment == META_PLACEMENT_CONSTRAINT_ADJUSTMENT_FLIP_X && + flipped_intersection.width == flipped_rect.width) || + (constraint_adjustment == META_PLACEMENT_CONSTRAINT_ADJUSTMENT_FLIP_Y && + flipped_intersection.height == flipped_rect.height)) + { + *placement_rule = flipped_rule; + *rect = flipped_rect; + *rel_x = flipped_rel_x; + *rel_y = flipped_rel_y; + *intersection = flipped_intersection; + } +} + +static gboolean +is_custom_rule_satisfied (MetaRectangle *rect, + MetaPlacementRule *placement_rule, + MetaRectangle *intersection) +{ + uint32_t x_constrain_actions, y_constrain_actions; + + x_constrain_actions = (META_PLACEMENT_CONSTRAINT_ADJUSTMENT_SLIDE_X | + META_PLACEMENT_CONSTRAINT_ADJUSTMENT_FLIP_X); + y_constrain_actions = (META_PLACEMENT_CONSTRAINT_ADJUSTMENT_SLIDE_Y | + META_PLACEMENT_CONSTRAINT_ADJUSTMENT_FLIP_Y); + if ((placement_rule->constraint_adjustment & x_constrain_actions && + rect->width != intersection->width) || + (placement_rule->constraint_adjustment & y_constrain_actions && + rect->height != intersection->height)) + return FALSE; + else + return TRUE; +} + +static gboolean +constrain_custom_rule (MetaWindow *window, + ConstraintInfo *info, + ConstraintPriority priority, + gboolean check_only) +{ + MetaPlacementRule *placement_rule; + MetaRectangle intersection; + gboolean constraint_satisfied; + MetaRectangle temporary_rect; + MetaRectangle adjusted_unconstrained; + int adjusted_rel_x; + int adjusted_rel_y; + MetaPlacementRule current_rule; + MetaWindow *parent; + int parent_x, parent_y; + + if (priority > PRIORITY_CUSTOM_RULE) + return TRUE; + + placement_rule = meta_window_get_placement_rule (window); + if (!placement_rule) + return TRUE; + + parent = meta_window_get_transient_for (window); + if (window->placement.state == META_PLACEMENT_STATE_CONSTRAINED_FINISHED) + { + placement_rule->parent_rect.x = parent->rect.x; + placement_rule->parent_rect.y = parent->rect.y; + } + parent_x = placement_rule->parent_rect.x; + parent_y = placement_rule->parent_rect.y; + + /* + * Calculate the temporary position, meaning a position that will be + * applied if the new constrained position requires asynchronous + * configuration of the window. This happens for example when the parent + * moves, causing this window to change relative position, meaning it can + * only have its newly constrained position applied when the configuration is + * acknowledged. + */ + + switch (window->placement.state) + { + case META_PLACEMENT_STATE_UNCONSTRAINED: + temporary_rect = info->current; + break; + case META_PLACEMENT_STATE_CONSTRAINED_CONFIGURED: + case META_PLACEMENT_STATE_CONSTRAINED_PENDING: + case META_PLACEMENT_STATE_CONSTRAINED_FINISHED: + case META_PLACEMENT_STATE_INVALIDATED: + temporary_rect = (MetaRectangle) { + .x = parent->rect.x + window->placement.current.rel_x, + .y = parent->rect.y + window->placement.current.rel_y, + .width = info->current.width, + .height = info->current.height, + }; + break; + } + + /* + * Calculate an adjusted current position. Depending on the rule + * configuration and placement state, this may result in window being + * reconstrained. + */ + + adjusted_unconstrained = temporary_rect; + + if (window->placement.state == META_PLACEMENT_STATE_INVALIDATED || + window->placement.state == META_PLACEMENT_STATE_UNCONSTRAINED || + (window->placement.state == META_PLACEMENT_STATE_CONSTRAINED_FINISHED && + placement_rule->is_reactive)) + { + meta_window_process_placement (window, placement_rule, + &adjusted_rel_x, + &adjusted_rel_y); + adjusted_unconstrained.x = parent_x + adjusted_rel_x; + adjusted_unconstrained.y = parent_y + adjusted_rel_y; + } + else if (window->placement.state == META_PLACEMENT_STATE_CONSTRAINED_PENDING) + { + adjusted_rel_x = window->placement.pending.rel_x; + adjusted_rel_y = window->placement.pending.rel_y; + adjusted_unconstrained.x = window->placement.pending.x; + adjusted_unconstrained.y = window->placement.pending.y; + } + else + { + adjusted_rel_x = window->placement.current.rel_x; + adjusted_rel_y = window->placement.current.rel_y; + } + + meta_rectangle_intersect (&adjusted_unconstrained, &info->work_area_monitor, + &intersection); + + constraint_satisfied = (meta_rectangle_equal (&info->current, + &adjusted_unconstrained) && + is_custom_rule_satisfied (&adjusted_unconstrained, + placement_rule, + &intersection)); + + if (check_only) + return constraint_satisfied; + + info->current = adjusted_unconstrained; + info->rel_x = adjusted_rel_x; + info->rel_y = adjusted_rel_y; + info->temporary = temporary_rect; + + switch (window->placement.state) + { + case META_PLACEMENT_STATE_CONSTRAINED_FINISHED: + if (!placement_rule->is_reactive) + return TRUE; + break; + case META_PLACEMENT_STATE_CONSTRAINED_PENDING: + case META_PLACEMENT_STATE_CONSTRAINED_CONFIGURED: + return TRUE; + case META_PLACEMENT_STATE_UNCONSTRAINED: + case META_PLACEMENT_STATE_INVALIDATED: + break; + } + + if (constraint_satisfied) + goto done; + + /* + * Process the placement rule in order either until constraints are + * satisfied, or there are no more rules to process. + */ + + current_rule = *placement_rule; + + if (info->current.width != intersection.width && + (current_rule.constraint_adjustment & + META_PLACEMENT_CONSTRAINT_ADJUSTMENT_FLIP_X)) + { + try_flip_window_position (window, info, ¤t_rule, + META_PLACEMENT_CONSTRAINT_ADJUSTMENT_FLIP_X, + parent_x, + parent_y, + &info->current, + &info->rel_x, + &info->rel_y, + &intersection); + } + if (info->current.height != intersection.height && + (current_rule.constraint_adjustment & + META_PLACEMENT_CONSTRAINT_ADJUSTMENT_FLIP_Y)) + { + try_flip_window_position (window, info, ¤t_rule, + META_PLACEMENT_CONSTRAINT_ADJUSTMENT_FLIP_Y, + parent_x, + parent_y, + &info->current, + &info->rel_x, + &info->rel_y, + &intersection); + } + + meta_rectangle_intersect (&info->current, &info->work_area_monitor, + &intersection); + constraint_satisfied = is_custom_rule_satisfied (&info->current, + placement_rule, + &intersection); + + if (constraint_satisfied) + goto done; + + if (current_rule.constraint_adjustment & + META_PLACEMENT_CONSTRAINT_ADJUSTMENT_SLIDE_X) + { + int current_x2; + int work_area_monitor_x2; + int new_x; + + current_x2 = info->current.x + info->current.width; + work_area_monitor_x2 = (info->work_area_monitor.x + + info->work_area_monitor.width); + + if (current_x2 > work_area_monitor_x2) + { + new_x = MAX (info->work_area_monitor.x, + work_area_monitor_x2 - info->current.width); + } + else if (info->current.x < info->work_area_monitor.x) + { + new_x = info->work_area_monitor.x; + } else - max_size->width = G_MAXINT; - if (max_size->height < (G_MAXINT - fh)) - max_size->height += fh; + { + new_x = info->current.x; + } + + info->rel_x += new_x - info->current.x; + info->current.x = new_x; + } + if (current_rule.constraint_adjustment & + META_PLACEMENT_CONSTRAINT_ADJUSTMENT_SLIDE_Y) + { + int current_y2; + int work_area_monitor_y2; + int new_y; + + current_y2 = info->current.y + info->current.height; + work_area_monitor_y2 = (info->work_area_monitor.y + + info->work_area_monitor.height); + + if (current_y2 > work_area_monitor_y2) + { + new_y = MAX (info->work_area_monitor.y, + work_area_monitor_y2 - info->current.height); + } + else if (info->current.y < info->work_area_monitor.y) + { + new_y = info->work_area_monitor.y; + } else - max_size->height = G_MAXINT; + { + new_y = info->current.y; + } + + info->rel_y += new_y - info->current.y; + info->current.y = new_y; + } + + meta_rectangle_intersect (&info->current, &info->work_area_monitor, + &intersection); + constraint_satisfied = is_custom_rule_satisfied (&info->current, + placement_rule, + &intersection); + + if (constraint_satisfied) + goto done; + + if (current_rule.constraint_adjustment & + META_PLACEMENT_CONSTRAINT_ADJUSTMENT_RESIZE_X) + { + int new_x; + new_x = intersection.x; + info->current.width = intersection.width; + info->rel_x += new_x - info->current.x; + info->current.x = new_x; + } + if (current_rule.constraint_adjustment & + META_PLACEMENT_CONSTRAINT_ADJUSTMENT_RESIZE_Y) + { + int new_y; + new_y = intersection.y; + info->current.height = intersection.height; + info->rel_y += new_y - info->current.y; + info->current.y = new_y; } + +done: + window->placement.state = META_PLACEMENT_STATE_CONSTRAINED_PENDING; + + window->placement.pending.rel_x = info->rel_x; + window->placement.pending.rel_y = info->rel_y; + window->placement.pending.x = info->current.x; + window->placement.pending.y = info->current.y; + + return TRUE; } static gboolean @@ -748,18 +1101,28 @@ constrain_modal_dialog (MetaWindow *window, { int x, y; MetaWindow *parent = meta_window_get_transient_for (window); + MetaRectangle child_rect, parent_rect; gboolean constraint_already_satisfied; - if (!meta_window_is_attached_dialog (window)) + if (!parent || + !meta_window_is_attached_dialog (window) || + meta_window_get_placement_rule (window)) return TRUE; - x = parent->rect.x + (parent->rect.width / 2 - info->current.width / 2); - y = parent->rect.y + (parent->rect.height / 2 - info->current.height / 2); - if (parent->frame) - { - x += parent->frame->rect.x; - y += parent->frame->rect.y; - } + /* We want to center the dialog on the parent, including the decorations + for both of them. info->current is in client X window coordinates, so we need + to convert them to frame coordinates, apply the centering and then + convert back to client. + */ + + child_rect = info->current; + + meta_window_get_frame_rect (parent, &parent_rect); + + child_rect.x = parent_rect.x + (parent_rect.width / 2 - child_rect.width / 2); + child_rect.y = parent_rect.y + (parent_rect.height / 2 - child_rect.height / 2); + x = child_rect.x; + y = child_rect.y; constraint_already_satisfied = (x == info->current.x) && (y == info->current.y); @@ -782,6 +1145,7 @@ constrain_maximization (MetaWindow *window, ConstraintPriority priority, gboolean check_only) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; MetaRectangle target_size; MetaRectangle min_size, max_size; gboolean hminbad, vminbad; @@ -793,12 +1157,15 @@ constrain_maximization (MetaWindow *window, /* Determine whether constraint applies; exit if it doesn't */ if ((!window->maximized_horizontally && !window->maximized_vertically) || - META_WINDOW_TILED_OR_SNAPPED (window)) + META_WINDOW_TILED_SIDE_BY_SIDE (window)) return TRUE; /* Calculate target_size = maximized size of (window + frame) */ - if (META_WINDOW_MAXIMIZED (window) && - (g_list_length (window->workspace->snapped_windows) == 0 || window->type == META_WINDOW_DESKTOP)) + if (META_WINDOW_TILED_MAXIMIZED (window)) + { + meta_window_get_tile_area (window, window->tile_mode, &target_size); + } + else if (META_WINDOW_MAXIMIZED (window)) { target_size = info->work_area_monitor; } @@ -818,52 +1185,19 @@ constrain_maximization (MetaWindow *window, direction = META_DIRECTION_HORIZONTAL; else direction = META_DIRECTION_VERTICAL; - active_workspace_struts = window->screen->active_workspace->all_struts; - - if (g_list_length (window->screen->active_workspace->snapped_windows) > 0) { - GList *tmp = window->screen->active_workspace->snapped_windows; - GSList *snapped_windows_as_struts = NULL; - while (tmp) { - if (tmp->data == window || META_WINDOW (tmp->data)->minimized || - meta_window_get_monitor (window) != meta_window_get_monitor (META_WINDOW (tmp->data))) { - tmp = tmp->next; - continue; - } - MetaStrut *strut = g_slice_new0 (MetaStrut); - MetaSide side; - MetaRectangle rect; - meta_window_get_outer_rect (META_WINDOW (tmp->data), &rect); - side = meta_window_get_tile_side (META_WINDOW (tmp->data)); - strut->rect = rect; - strut->side = side; - snapped_windows_as_struts = g_slist_prepend (snapped_windows_as_struts, strut); - tmp = tmp->next; - } + active_workspace_struts = workspace_manager->active_workspace->all_struts; - target_size = info->current; - meta_window_extend_by_frame (window, &target_size, info->borders); - meta_rectangle_expand_to_snapped_borders (&target_size, - &info->entire_monitor, - active_workspace_struts, - snapped_windows_as_struts, - &window->user_rect); - g_slist_free (snapped_windows_as_struts); - } else { - target_size = info->current; - meta_rectangle_expand_to_avoiding_struts (&target_size, - &info->entire_monitor, - direction, - active_workspace_struts); - } + target_size = info->current; + meta_rectangle_expand_to_avoiding_struts (&target_size, + &info->entire_monitor, + direction, + active_workspace_struts); } - /* Now make target_size = maximized size of client window */ - if (!meta_window_is_client_decorated(window)) - meta_window_unextend_by_frame (window, &target_size, info->borders); /* Check min size constraints; max size constraints are ignored for maximized * windows, as per bug 327543. */ - get_size_limits (window, info->borders, FALSE, &min_size, &max_size); + get_size_limits (window, &min_size, &max_size); hminbad = target_size.width < min_size.width && window->maximized_horizontally; vminbad = target_size.height < min_size.height && window->maximized_vertically; if (hminbad || vminbad) @@ -902,7 +1236,6 @@ constrain_tiling (MetaWindow *window, { MetaRectangle target_size; MetaRectangle min_size, max_size; - MetaRectangle actual_position; gboolean hminbad, vminbad; gboolean horiz_equal, vert_equal; gboolean constraint_already_satisfied; @@ -911,114 +1244,18 @@ constrain_tiling (MetaWindow *window, return TRUE; /* Determine whether constraint applies; exit if it doesn't */ - if (!META_WINDOW_TILED_OR_SNAPPED (window) || window->resizing_tile_type != META_WINDOW_TILE_TYPE_NONE) + if (!META_WINDOW_TILED_SIDE_BY_SIDE (window)) return TRUE; /* Calculate target_size - as the tile previews need this as well, we * use an external function for the actual calculation */ - if (window->tile_mode != META_TILE_NONE) - meta_window_get_current_tile_area (window, &target_size); - else - return TRUE; - - meta_window_get_outer_rect (window, &actual_position); - - if (window->custom_snap_size) { - switch (window->tile_mode) { - case META_TILE_LEFT: - target_size.width = BOX_RIGHT (actual_position) - target_size.x; - break; - case META_TILE_RIGHT: - target_size.width = BOX_RIGHT (target_size) - BOX_LEFT (actual_position); - target_size.x = BOX_LEFT (actual_position); - break; - case META_TILE_TOP: - target_size.height = BOX_BOTTOM (actual_position) - BOX_TOP (target_size); - break; - case META_TILE_BOTTOM: - target_size.height = BOX_BOTTOM (target_size) - BOX_TOP (actual_position); - target_size.y = BOX_TOP (actual_position); - break; - case META_TILE_ULC: - if (GRAB_OP (window) == META_GRAB_OP_RESIZING_S || - GRAB_OP (window) == META_GRAB_OP_KEYBOARD_RESIZING_S) { - target_size.width = window->snapped_rect.width; - target_size.height = BOX_BOTTOM (actual_position) - BOX_TOP (target_size); - } else if (GRAB_OP (window) == META_GRAB_OP_RESIZING_E || - GRAB_OP (window) == META_GRAB_OP_KEYBOARD_RESIZING_E) { - target_size.width = BOX_RIGHT (actual_position) - target_size.x; - target_size.height = window->snapped_rect.height; - } else { - target_size.width = BOX_RIGHT (actual_position) - target_size.x; - target_size.height = BOX_BOTTOM (actual_position) - BOX_TOP (target_size); - } - break; - case META_TILE_LLC: - if (GRAB_OP (window) == META_GRAB_OP_RESIZING_N || - GRAB_OP (window) == META_GRAB_OP_KEYBOARD_RESIZING_N) { - target_size.width = window->snapped_rect.width; - target_size.height = BOX_BOTTOM (target_size) - BOX_TOP (actual_position); - target_size.y = BOX_TOP (actual_position); - } else if (GRAB_OP (window) == META_GRAB_OP_RESIZING_E || - GRAB_OP (window) == META_GRAB_OP_KEYBOARD_RESIZING_E) { - target_size.width = BOX_RIGHT (actual_position) - target_size.x; - target_size.height = window->snapped_rect.height; - target_size.y = window->snapped_rect.y; - } else { - target_size.width = BOX_RIGHT (actual_position) - target_size.x; - target_size.height = BOX_BOTTOM (target_size) - BOX_TOP (actual_position); - target_size.y = BOX_TOP (actual_position); - } - break; - case META_TILE_URC: - if (GRAB_OP (window) == META_GRAB_OP_RESIZING_W || - GRAB_OP (window) == META_GRAB_OP_KEYBOARD_RESIZING_W) { - target_size.width = BOX_RIGHT (target_size) - BOX_LEFT (actual_position); - target_size.x = BOX_LEFT (actual_position); - target_size.height = window->snapped_rect.height; - } else if (GRAB_OP (window) == META_GRAB_OP_RESIZING_S || - GRAB_OP (window) == META_GRAB_OP_KEYBOARD_RESIZING_S) { - target_size.width = window->snapped_rect.width; - target_size.x = window->snapped_rect.x; - target_size.height = BOX_BOTTOM (actual_position) - BOX_TOP (target_size); - } else { - target_size.width = BOX_RIGHT (target_size) - BOX_LEFT (actual_position); - target_size.x = BOX_LEFT (actual_position); - target_size.height = BOX_BOTTOM (actual_position) - BOX_TOP (target_size); - } - break; - case META_TILE_LRC: - if (GRAB_OP (window) == META_GRAB_OP_RESIZING_W || - GRAB_OP (window) == META_GRAB_OP_KEYBOARD_RESIZING_W) { - target_size.width = BOX_RIGHT (target_size) - BOX_LEFT (actual_position); - target_size.x = BOX_LEFT (actual_position); - target_size.height = window->snapped_rect.height; - target_size.y = window->snapped_rect.y; - } else if (GRAB_OP (window) == META_GRAB_OP_RESIZING_N || - GRAB_OP (window) == META_GRAB_OP_KEYBOARD_RESIZING_N) { - target_size.width = window->snapped_rect.width; - target_size.x = window->snapped_rect.x; - target_size.height = BOX_BOTTOM (target_size) - BOX_TOP (actual_position); - target_size.y = BOX_TOP (actual_position); - } else { - target_size.width = BOX_RIGHT (target_size) - BOX_LEFT (actual_position); - target_size.x = BOX_LEFT (actual_position); - target_size.height = BOX_BOTTOM (target_size) - BOX_TOP (actual_position); - target_size.y = BOX_TOP (actual_position); - } - break; - default: - break; - } - } - - meta_window_unextend_by_frame (window, &target_size, info->borders); + meta_window_get_tile_area (window, window->tile_mode, &target_size); /* Check min size constraints; max size constraints are ignored as for * maximized windows. */ - get_size_limits (window, info->borders, FALSE, &min_size, &max_size); + get_size_limits (window, &min_size, &max_size); hminbad = target_size.width < min_size.width; vminbad = target_size.height < min_size.height; if (hminbad || vminbad) @@ -1061,7 +1298,7 @@ constrain_fullscreen (MetaWindow *window, monitor = info->entire_monitor; - get_size_limits (window, info->borders, FALSE, &min_size, &max_size); + get_size_limits (window, &min_size, &max_size); too_big = !meta_rectangle_could_fit_rect (&monitor, &min_size); too_small = !meta_rectangle_could_fit_rect (&max_size, &monitor); if (too_big || too_small) @@ -1088,24 +1325,26 @@ constrain_size_increments (MetaWindow *window, int new_width, new_height; gboolean constraint_already_satisfied; MetaRectangle *start_rect; + MetaRectangle client_rect; if (priority > PRIORITY_SIZE_HINTS_INCREMENTS) return TRUE; /* Determine whether constraint applies; exit if it doesn't */ if (META_WINDOW_MAXIMIZED (window) || window->fullscreen || - META_WINDOW_TILED_OR_SNAPPED (window) || - info->action_type == ACTION_MOVE || - window->resizing_tile_type != META_WINDOW_TILE_TYPE_NONE) + META_WINDOW_TILED_SIDE_BY_SIDE (window) || + info->action_type == ACTION_MOVE) return TRUE; + meta_window_frame_rect_to_client_rect (window, &info->current, &client_rect); + /* Determine whether constraint is already satisfied; exit if it is */ bh = window->size_hints.base_height; hi = window->size_hints.height_inc; bw = window->size_hints.base_width; wi = window->size_hints.width_inc; - extra_height = (info->current.height - bh) % hi; - extra_width = (info->current.width - bw) % wi; + extra_height = (client_rect.height - bh) % hi; + extra_width = (client_rect.width - bw) % wi; /* ignore size increments for maximized windows */ if (window->maximized_horizontally) extra_width *= 0; @@ -1119,8 +1358,8 @@ constrain_size_increments (MetaWindow *window, return constraint_already_satisfied; /*** Enforce constraint ***/ - new_width = info->current.width - extra_width; - new_height = info->current.height - extra_height; + new_width = client_rect.width - extra_width; + new_height = client_rect.height - extra_height; /* Adjusting down instead of up (as done in the above two lines) may * violate minimum size constraints; fix the adjustment if this @@ -1131,13 +1370,15 @@ constrain_size_increments (MetaWindow *window, if (new_height < window->size_hints.min_height) new_height += ((window->size_hints.min_height - new_height)/hi + 1)*hi; - /* Figure out what original rect to pass to meta_rectangle_resize_with_gravity - * See bug 448183 - */ - if (info->action_type == ACTION_MOVE_AND_RESIZE) - start_rect = &info->current; - else - start_rect = &info->orig; + { + client_rect.width = new_width; + client_rect.height = new_height; + meta_window_client_rect_to_frame_rect (window, &client_rect, &client_rect); + new_width = client_rect.width; + new_height = client_rect.height; + } + + start_rect = get_start_rect_for_resize (window, info); /* Resize to the new size */ meta_rectangle_resize_with_gravity (start_rect, @@ -1171,7 +1412,7 @@ constrain_size_limits (MetaWindow *window, return TRUE; /* Determine whether constraint is already satisfied; exit if it is */ - get_size_limits (window, info->borders, FALSE, &min_size, &max_size); + get_size_limits (window, &min_size, &max_size); /* We ignore max-size limits for maximized windows; see #327543 */ if (window->maximized_horizontally) max_size.width = MAX (max_size.width, info->current.width); @@ -1187,13 +1428,7 @@ constrain_size_limits (MetaWindow *window, new_width = CLAMP (info->current.width, min_size.width, max_size.width); new_height = CLAMP (info->current.height, min_size.height, max_size.height); - /* Figure out what original rect to pass to meta_rectangle_resize_with_gravity - * See bug 448183 - */ - if (info->action_type == ACTION_MOVE_AND_RESIZE) - start_rect = &info->current; - else - start_rect = &info->orig; + start_rect = get_start_rect_for_resize (window, info); meta_rectangle_resize_with_gravity (start_rect, &info->current, @@ -1215,6 +1450,7 @@ constrain_aspect_ratio (MetaWindow *window, double best_width, best_height; double alt_width, alt_height; MetaRectangle *start_rect; + MetaRectangle client_rect; if (priority > PRIORITY_ASPECT_RATIO) return TRUE; @@ -1227,7 +1463,7 @@ constrain_aspect_ratio (MetaWindow *window, constraints_are_inconsistent = minr > maxr; if (constraints_are_inconsistent || META_WINDOW_MAXIMIZED (window) || window->fullscreen || - META_WINDOW_TILED_OR_SNAPPED (window) || + META_WINDOW_TILED_SIDE_BY_SIDE (window) || info->action_type == ACTION_MOVE) return TRUE; @@ -1249,53 +1485,56 @@ constrain_aspect_ratio (MetaWindow *window, */ switch (info->resize_gravity) { - case WestGravity: - case NorthGravity: - case SouthGravity: - case EastGravity: + case META_GRAVITY_WEST: + case META_GRAVITY_NORTH: + case META_GRAVITY_SOUTH: + case META_GRAVITY_EAST: fudge = 2; break; - case NorthWestGravity: - case SouthWestGravity: - case CenterGravity: - case NorthEastGravity: - case SouthEastGravity: - case StaticGravity: + case META_GRAVITY_NORTH_WEST: + case META_GRAVITY_SOUTH_WEST: + case META_GRAVITY_CENTER: + case META_GRAVITY_NORTH_EAST: + case META_GRAVITY_SOUTH_EAST: + case META_GRAVITY_STATIC: default: fudge = 1; break; } + + meta_window_frame_rect_to_client_rect (window, &info->current, &client_rect); + constraint_already_satisfied = - info->current.width - (info->current.height * minr ) > -minr*fudge && - info->current.width - (info->current.height * maxr ) < maxr*fudge; + client_rect.width - (client_rect.height * minr ) > -minr*fudge && + client_rect.width - (client_rect.height * maxr ) < maxr*fudge; if (check_only || constraint_already_satisfied) return constraint_already_satisfied; /*** Enforce constraint ***/ - new_width = info->current.width; - new_height = info->current.height; + new_width = client_rect.width; + new_height = client_rect.height; switch (info->resize_gravity) { - case WestGravity: - case EastGravity: + case META_GRAVITY_WEST: + case META_GRAVITY_EAST: /* Yeah, I suck for doing implicit rounding -- sue me */ new_height = CLAMP (new_height, new_width / maxr, new_width / minr); break; - case NorthGravity: - case SouthGravity: + case META_GRAVITY_NORTH: + case META_GRAVITY_SOUTH: /* Yeah, I suck for doing implicit rounding -- sue me */ new_width = CLAMP (new_width, new_height * minr, new_height * maxr); break; - case NorthWestGravity: - case SouthWestGravity: - case CenterGravity: - case NorthEastGravity: - case SouthEastGravity: - case StaticGravity: + case META_GRAVITY_NORTH_WEST: + case META_GRAVITY_SOUTH_WEST: + case META_GRAVITY_CENTER: + case META_GRAVITY_NORTH_EAST: + case META_GRAVITY_SOUTH_EAST: + case META_GRAVITY_STATIC: default: /* Find what width would correspond to new_height, and what height would * correspond to new_width */ @@ -1321,13 +1560,15 @@ constrain_aspect_ratio (MetaWindow *window, break; } - /* Figure out what original rect to pass to meta_rectangle_resize_with_gravity - * See bug 448183 - */ - if (info->action_type == ACTION_MOVE_AND_RESIZE) - start_rect = &info->current; - else - start_rect = &info->orig; + { + client_rect.width = new_width; + client_rect.height = new_height; + meta_window_client_rect_to_frame_rect (window, &client_rect, &client_rect); + new_width = client_rect.width; + new_height = client_rect.height; + } + + start_rect = get_start_rect_for_resize (window, info); meta_rectangle_resize_with_gravity (start_rect, &info->current, @@ -1363,8 +1604,7 @@ do_screen_and_monitor_relative_constraints ( /* Determine whether constraint applies; exit if it doesn't */ how_far_it_can_be_smushed = info->current; - get_size_limits (window, info->borders, TRUE, &min_size, &max_size); - meta_window_extend_by_frame (window, &info->current, info->borders); + get_size_limits (window, &min_size, &max_size); if (info->action_type != ACTION_MOVE) { @@ -1383,10 +1623,7 @@ do_screen_and_monitor_relative_constraints ( meta_rectangle_contained_in_region (region_spanning_rectangles, &info->current); if (exit_early || constraint_satisfied || check_only) - { - meta_window_unextend_by_frame (window, &info->current, info->borders); - return constraint_satisfied; - } + return constraint_satisfied; /* Enforce constraint */ @@ -1403,14 +1640,11 @@ do_screen_and_monitor_relative_constraints ( info->fixed_directions, &info->current); else - { - /* For everything else, shove the rectangle into the relevant region */ - meta_rectangle_shove_into_region (region_spanning_rectangles, - info->fixed_directions, - &info->current); - } + /* For everything else, shove the rectangle into the relevant region */ + meta_rectangle_shove_into_region (region_spanning_rectangles, + info->fixed_directions, + &info->current); - meta_window_unextend_by_frame (window, &info->current, info->borders); return TRUE; } @@ -1420,6 +1654,10 @@ constrain_to_single_monitor (MetaWindow *window, ConstraintPriority priority, gboolean check_only) { + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + if (priority > PRIORITY_ENTIRELY_VISIBLE_ON_SINGLE_MONITOR) return TRUE; @@ -1428,12 +1666,13 @@ constrain_to_single_monitor (MetaWindow *window, * "onscreen" by their own strut) and we can't apply it to frameless windows * or else users will be unable to move windows such as XMMS across monitors. */ - if (window->type == META_WINDOW_DESKTOP || - window->type == META_WINDOW_DOCK || - window->screen->n_monitor_infos == 1 || - !window->require_on_single_monitor || - (!window->frame && !meta_window_is_client_decorated (window)) || - info->is_user_action) + if (window->type == META_WINDOW_DESKTOP || + window->type == META_WINDOW_DOCK || + meta_monitor_manager_get_num_logical_monitors (monitor_manager) == 1 || + !window->require_on_single_monitor || + !window->frame || + info->is_user_action || + meta_window_get_placement_rule (window)) return TRUE; /* Have a helper function handle the constraint for us */ @@ -1449,12 +1688,9 @@ constrain_fully_onscreen (MetaWindow *window, ConstraintPriority priority, gboolean check_only) { - MetaWindow *transient_for; - if (priority > PRIORITY_ENTIRELY_VISIBLE_ON_WORKAREA) return TRUE; - transient_for = meta_window_get_transient_for(window); /* Exit early if we know the constraint won't apply--note that this constraint * is only meant for normal windows (e.g. we don't want docks to be shoved * "onscreen" by their own strut). @@ -1462,9 +1698,9 @@ constrain_fully_onscreen (MetaWindow *window, if (window->type == META_WINDOW_DESKTOP || window->type == META_WINDOW_DOCK || window->fullscreen || - (transient_for && transient_for->fullscreen) || !window->require_fully_onscreen || - info->is_user_action) + info->is_user_action || + meta_window_get_placement_rule (window)) return TRUE; /* Have a helper function handle the constraint for us */ @@ -1485,7 +1721,6 @@ constrain_titlebar_visible (MetaWindow *window, int bottom_amount; int horiz_amount_offscreen, vert_amount_offscreen; int horiz_amount_onscreen, vert_amount_onscreen; - int scale = meta_prefs_get_ui_scale (); if (priority > PRIORITY_TITLEBAR_VISIBLE) return TRUE; @@ -1504,7 +1739,8 @@ constrain_titlebar_visible (MetaWindow *window, window->type == META_WINDOW_DOCK || window->fullscreen || !window->require_titlebar_visible || - unconstrained_user_action) + unconstrained_user_action || + meta_window_get_placement_rule (window)) return TRUE; /* Determine how much offscreen things are allowed. We first need to @@ -1516,8 +1752,8 @@ constrain_titlebar_visible (MetaWindow *window, */ horiz_amount_onscreen = info->current.width / 4; vert_amount_onscreen = info->current.height / 4; - horiz_amount_onscreen = CLAMP (horiz_amount_onscreen, 10 * scale, 75 * scale); - vert_amount_onscreen = CLAMP (vert_amount_onscreen, 10 * scale, 75 * scale); + horiz_amount_onscreen = CLAMP (horiz_amount_onscreen, 10, 75); + vert_amount_onscreen = CLAMP (vert_amount_onscreen, 10, 75); horiz_amount_offscreen = info->current.width - horiz_amount_onscreen; vert_amount_offscreen = info->current.height - vert_amount_onscreen; horiz_amount_offscreen = MAX (horiz_amount_offscreen, 0); @@ -1527,13 +1763,11 @@ constrain_titlebar_visible (MetaWindow *window, */ if (window->frame) { - bottom_amount = info->current.height + info->borders->visible.bottom; - vert_amount_onscreen = info->borders->visible.top; - } - else if (meta_window_is_client_decorated (window)) - { - vert_amount_onscreen = CSD_TITLEBAR_HEIGHT * scale; /* Hardcoded for now, we don't get this from Gtk */ - bottom_amount = vert_amount_offscreen = MAX ((info->current.height - (vert_amount_onscreen * 2)), 0); + MetaFrameBorders borders; + meta_frame_calc_borders (window->frame, &borders); + + bottom_amount = info->current.height - borders.visible.top; + vert_amount_onscreen = borders.visible.top; } else bottom_amount = vert_amount_offscreen; @@ -1560,6 +1794,7 @@ constrain_titlebar_visible (MetaWindow *window, -bottom_amount, horiz_amount_onscreen, vert_amount_onscreen); + return retval; } @@ -1573,7 +1808,6 @@ constrain_partially_onscreen (MetaWindow *window, int top_amount, bottom_amount; int horiz_amount_offscreen, vert_amount_offscreen; int horiz_amount_onscreen, vert_amount_onscreen; - int scale = meta_prefs_get_ui_scale (); if (priority > PRIORITY_PARTIALLY_VISIBLE_ON_WORKAREA) return TRUE; @@ -1583,7 +1817,8 @@ constrain_partially_onscreen (MetaWindow *window, * "onscreen" by their own strut). */ if (window->type == META_WINDOW_DESKTOP || - window->type == META_WINDOW_DOCK) + window->type == META_WINDOW_DOCK || + meta_window_get_placement_rule (window)) return TRUE; /* Determine how much offscreen things are allowed. We first need to @@ -1595,8 +1830,8 @@ constrain_partially_onscreen (MetaWindow *window, */ horiz_amount_onscreen = info->current.width / 4; vert_amount_onscreen = info->current.height / 4; - horiz_amount_onscreen = CLAMP (horiz_amount_onscreen, 10 * scale, 75 * scale); - vert_amount_onscreen = CLAMP (vert_amount_onscreen, 10 * scale, 75 * scale); + horiz_amount_onscreen = CLAMP (horiz_amount_onscreen, 10, 75); + vert_amount_onscreen = CLAMP (vert_amount_onscreen, 10, 75); horiz_amount_offscreen = info->current.width - horiz_amount_onscreen; vert_amount_offscreen = info->current.height - vert_amount_onscreen; horiz_amount_offscreen = MAX (horiz_amount_offscreen, 0); @@ -1607,13 +1842,14 @@ constrain_partially_onscreen (MetaWindow *window, */ if (window->frame) { - bottom_amount = info->current.height + info->borders->visible.bottom; - vert_amount_onscreen = info->borders->visible.top; + MetaFrameBorders borders; + meta_frame_calc_borders (window->frame, &borders); + + bottom_amount = info->current.height - borders.visible.top; + vert_amount_onscreen = borders.visible.top; } else - { - bottom_amount = vert_amount_offscreen; - } + bottom_amount = vert_amount_offscreen; /* Extend the region, have a helper function handle the constraint, * then return the region to its original size. diff --git a/src/core/constraints.h b/src/core/constraints.h index 158a7ab27..eaa4e4594 100644 --- a/src/core/constraints.h +++ b/src/core/constraints.h @@ -1,11 +1,11 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* Muffin size/position constraints */ +/* Mutter size/position constraints */ -/* +/* * Copyright (C) 2002 Red Hat, Inc. * Copyright (C) 2005 Elijah Newren - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the @@ -15,34 +15,25 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_CONSTRAINTS_H #define META_CONSTRAINTS_H -#include <meta/util.h> -#include "window-private.h" -#include "frame.h" - -typedef enum -{ - META_IS_CONFIGURE_REQUEST = 1 << 0, - META_DO_GRAVITY_ADJUST = 1 << 1, - META_IS_USER_ACTION = 1 << 2, - META_IS_MOVE_ACTION = 1 << 3, - META_IS_RESIZE_ACTION = 1 << 4 -} MetaMoveResizeFlags; +#include "core/frame.h" +#include "core/window-private.h" +#include "meta/util.h" void meta_window_constrain (MetaWindow *window, - MetaFrameBorders *orig_borders, MetaMoveResizeFlags flags, - int resize_gravity, + MetaGravity resize_gravity, const MetaRectangle *orig, - MetaRectangle *new); + MetaRectangle *new, + MetaRectangle *intermediate, + int *rel_x, + int *rel_y); #endif /* META_CONSTRAINTS_H */ diff --git a/src/core/core.c b/src/core/core.c deleted file mode 100644 index 2c851a75e..000000000 --- a/src/core/core.c +++ /dev/null @@ -1,813 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Muffin interface used by GTK+ UI to talk to core */ - -/* - * Copyright (C) 2001 Havoc Pennington - * Copyright (C) 2003 Rob Adams - * Copyright (C) 2004-2006 Elijah Newren - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. - */ - -#include <config.h> -#include "core.h" -#include "frame.h" -#include "workspace-private.h" -#include <meta/prefs.h> -#include <meta/errors.h> -#include "util-private.h" - -/* Looks up the MetaWindow representing the frame of the given X window. - * Used as a helper function by a bunch of the functions below. - * - * FIXME: The functions that use this function throw the result away - * after use. Many of these functions tend to be called in small groups, - * which results in get_window() getting called several times in succession - * with the same parameters. We should profile to see whether this wastes - * much time, and if it does we should look into a generalised - * meta_core_get_window_info() which takes a bunch of pointers to variables - * to put its results in, and only fills in the non-null ones. - */ -LOCAL_SYMBOL MetaWindow * -meta_core_get_window (Display *xdisplay, - Window frame_xwindow) -{ - MetaDisplay *display; - MetaWindow *window; - - display = meta_display_for_x_display (xdisplay); - window = meta_display_lookup_x_window (display, frame_xwindow); - - if (window == NULL || window->frame == NULL) - { - meta_bug ("No such frame window 0x%lx!\n", frame_xwindow); - return NULL; - } - - return window; -} - -LOCAL_SYMBOL void -meta_core_get (Display *xdisplay, - Window xwindow, - ...) -{ - va_list args; - MetaCoreGetType request; - - MetaDisplay *display = meta_display_for_x_display (xdisplay); - MetaWindow *window = meta_display_lookup_x_window (display, xwindow); - - va_start (args, xwindow); - - request = va_arg (args, MetaCoreGetType); - - /* Now, we special-case the first request slightly. Mostly, requests - * for information on windows which have no frame are errors. - * But sometimes we may want to know *whether* a window has a frame. - * In this case, pass the key META_CORE_WINDOW_HAS_FRAME - * as the *first* request, with a pointer to a boolean; if the window - * has no frame, this will be set to False and meta_core_get will - * exit immediately (so the values of any other requests will be - * undefined). Otherwise it will be set to True and meta_core_get will - * continue happily on its way. - */ - - if (request != META_CORE_WINDOW_HAS_FRAME && - (window == NULL || window->frame == NULL)) { - meta_bug ("No such frame window 0x%lx!\n", xwindow); - va_end (args); - return; - } - - while (request != META_CORE_GET_END) { - - gpointer answer = va_arg (args, gpointer); - - switch (request) { - case META_CORE_WINDOW_HAS_FRAME: - *((gboolean*)answer) = window != NULL && window->frame != NULL; - if (!*((gboolean*)answer)) return; /* see above */ - break; - case META_CORE_GET_CLIENT_WIDTH: - *((gint*)answer) = window->rect.width; - break; - case META_CORE_GET_CLIENT_HEIGHT: - *((gint*)answer) = window->rect.height; - break; - case META_CORE_GET_CLIENT_XWINDOW: - *((Window*)answer) = window->xwindow; - break; - case META_CORE_GET_FRAME_FLAGS: - *((MetaFrameFlags*)answer) = meta_frame_get_flags (window->frame); - break; - case META_CORE_GET_FRAME_TYPE: - *((MetaFrameType*)answer) = meta_window_get_frame_type (window); - break; - case META_CORE_GET_X: - meta_window_get_position (window, (int*)answer, NULL); - break; - case META_CORE_GET_Y: - meta_window_get_position (window, NULL, (int*)answer); - break; - case META_CORE_GET_FRAME_WORKSPACE: - *((gint*)answer) = meta_window_get_net_wm_desktop (window); - break; - case META_CORE_GET_FRAME_X: - *((gint*)answer) = window->frame->rect.x; - break; - case META_CORE_GET_FRAME_Y: - *((gint*)answer) = window->frame->rect.y; - break; - case META_CORE_GET_FRAME_WIDTH: - *((gint*)answer) = window->frame->rect.width; - break; - case META_CORE_GET_FRAME_HEIGHT: - *((gint*)answer) = window->frame->rect.height; - break; - case META_CORE_GET_THEME_VARIANT: - *((char**)answer) = window->gtk_theme_variant; - break; - case META_CORE_GET_SCREEN_WIDTH: - *((gint*)answer) = window->screen->rect.width; - break; - case META_CORE_GET_SCREEN_HEIGHT: - *((gint*)answer) = window->screen->rect.height; - break; - - default: - meta_warning("Unknown window information request: %d", request); - } - - request = va_arg (args, MetaCoreGetType); - } - - va_end (args); -} - -LOCAL_SYMBOL void -meta_core_queue_frame_resize (Display *xdisplay, - Window frame_xwindow) -{ - MetaWindow *window = meta_core_get_window (xdisplay, frame_xwindow); - - meta_window_queue (window, META_QUEUE_MOVE_RESIZE); - meta_window_frame_size_changed (window); -} - -LOCAL_SYMBOL void -meta_core_user_move (Display *xdisplay, - Window frame_xwindow, - int x, - int y) -{ - MetaWindow *window = meta_core_get_window (xdisplay, frame_xwindow); - - meta_window_move (window, TRUE, x, y); -} - -LOCAL_SYMBOL void -meta_core_user_resize (Display *xdisplay, - Window frame_xwindow, - int gravity, - int width, - int height) -{ - MetaWindow *window = meta_core_get_window (xdisplay, frame_xwindow); - - meta_window_resize_with_gravity (window, TRUE, width, height, gravity); -} - -LOCAL_SYMBOL void -meta_core_user_raise (Display *xdisplay, - Window frame_xwindow) -{ - MetaWindow *window = meta_core_get_window (xdisplay, frame_xwindow); - - meta_window_raise (window); -} - -static gboolean -lower_window_and_transients (MetaWindow *window, - gpointer data) -{ - meta_window_lower (window); - - meta_window_foreach_transient (window, lower_window_and_transients, NULL); - - if (meta_prefs_get_focus_mode () == C_DESKTOP_FOCUS_MODE_CLICK && - meta_prefs_get_raise_on_click ()) - { - /* Move window to the back of the focusing workspace's MRU list. - * Do extra sanity checks to avoid possible race conditions. - * (Borrowed from window.c.) - */ - if (window->screen->active_workspace && - meta_window_located_on_workspace (window, - window->screen->active_workspace)) - { - GList* link; - link = g_list_find (window->screen->active_workspace->mru_list, - window); - g_assert (link); - - window->screen->active_workspace->mru_list = - g_list_remove_link (window->screen->active_workspace->mru_list, - link); - g_list_free (link); - - window->screen->active_workspace->mru_list = - g_list_append (window->screen->active_workspace->mru_list, - window); - } - } - - return FALSE; -} - -LOCAL_SYMBOL void -meta_core_user_lower_and_unfocus (Display *xdisplay, - Window frame_xwindow, - guint32 timestamp) -{ - MetaWindow *window = meta_core_get_window (xdisplay, frame_xwindow); - - meta_screen_hide_hud_and_preview (window->screen); - - lower_window_and_transients (window, NULL); - - /* Rather than try to figure that out whether we just lowered - * the focus window, assume that's always the case. (Typically, - * this will be invoked via keyboard action or by a mouse action; - * in either case the window or a modal child will have been focused.) */ - meta_workspace_focus_default_window (window->screen->active_workspace, - NULL, - timestamp); -} - -LOCAL_SYMBOL void -meta_core_lower_beneath_grab_window (Display *xdisplay, - Window xwindow, - guint32 timestamp) -{ - XWindowChanges changes; - MetaDisplay *display; - MetaScreen *screen; - MetaWindow *grab_window; - - display = meta_display_for_x_display (xdisplay); - screen = meta_display_screen_for_xwindow (display, xwindow); - grab_window = display->grab_window; - - if (grab_window == NULL) - return; - - changes.stack_mode = Below; - changes.sibling = grab_window->frame ? grab_window->frame->xwindow - : grab_window->xwindow; - - meta_stack_tracker_record_lower_below (screen->stack_tracker, - xwindow, - changes.sibling, - XNextRequest (screen->display->xdisplay)); - - meta_error_trap_push (display); - XConfigureWindow (xdisplay, - xwindow, - CWSibling | CWStackMode, - &changes); - meta_error_trap_pop (display); -} - - -LOCAL_SYMBOL void -meta_core_lower_beneath_sibling (Display *xdisplay, - Window xwindow, - Window grab_window, - guint32 timestamp) -{ - XWindowChanges changes; - MetaDisplay *display; - MetaScreen *screen; - - display = meta_display_for_x_display (xdisplay); - screen = meta_display_screen_for_xwindow (display, xwindow); - - changes.stack_mode = Below; - changes.sibling = grab_window; - - meta_stack_tracker_record_lower_below (screen->stack_tracker, - xwindow, - changes.sibling, - XNextRequest (screen->display->xdisplay)); - - meta_error_trap_push (display); - XConfigureWindow (xdisplay, - xwindow, - CWSibling | CWStackMode, - &changes); - meta_error_trap_pop (display); -} - - -LOCAL_SYMBOL void -meta_core_user_focus (Display *xdisplay, - Window frame_xwindow, - guint32 timestamp) -{ - MetaWindow *window = meta_core_get_window (xdisplay, frame_xwindow); - - meta_window_focus (window, timestamp); -} - -LOCAL_SYMBOL void -meta_core_minimize (Display *xdisplay, - Window frame_xwindow) -{ - MetaWindow *window = meta_core_get_window (xdisplay, frame_xwindow); - - meta_screen_hide_hud_and_preview (window->screen); - - meta_window_minimize (window); -} - -LOCAL_SYMBOL void -meta_core_maximize (Display *xdisplay, - Window frame_xwindow) -{ - MetaWindow *window = meta_core_get_window (xdisplay, frame_xwindow); - - meta_screen_hide_hud_and_preview (window->screen); - - if (meta_prefs_get_raise_on_click ()) - meta_window_raise (window); - - meta_window_maximize (window, - META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL); -} - -LOCAL_SYMBOL void -meta_core_toggle_maximize_vertically (Display *xdisplay, - Window frame_xwindow) -{ - MetaWindow *window = meta_core_get_window (xdisplay, frame_xwindow); - - meta_screen_hide_hud_and_preview (window->screen); - - if (meta_prefs_get_raise_on_click ()) - meta_window_raise (window); - - if (META_WINDOW_MAXIMIZED_VERTICALLY (window)) - meta_window_unmaximize (window, - META_MAXIMIZE_VERTICAL); - else - meta_window_maximize (window, - META_MAXIMIZE_VERTICAL); -} - -LOCAL_SYMBOL void -meta_core_toggle_maximize_horizontally (Display *xdisplay, - Window frame_xwindow) -{ - MetaWindow *window = meta_core_get_window (xdisplay, frame_xwindow); - - meta_screen_hide_hud_and_preview (window->screen); - - if (meta_prefs_get_raise_on_click ()) - meta_window_raise (window); - - if (META_WINDOW_MAXIMIZED_HORIZONTALLY (window)) - meta_window_unmaximize (window, - META_MAXIMIZE_HORIZONTAL); - else - meta_window_maximize (window, - META_MAXIMIZE_HORIZONTAL); -} - -LOCAL_SYMBOL void -meta_core_toggle_maximize (Display *xdisplay, - Window frame_xwindow) -{ - MetaWindow *window = meta_core_get_window (xdisplay, frame_xwindow); - - meta_screen_hide_hud_and_preview (window->screen); - - if (meta_prefs_get_raise_on_click ()) - meta_window_raise (window); - - if (META_WINDOW_MAXIMIZED (window)) - meta_window_unmaximize (window, - META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL); - else - meta_window_maximize (window, - META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL); -} - -LOCAL_SYMBOL void -meta_core_unmaximize (Display *xdisplay, - Window frame_xwindow) -{ - MetaWindow *window = meta_core_get_window (xdisplay, frame_xwindow); - - if (meta_prefs_get_raise_on_click ()) - meta_window_raise (window); - - meta_window_unmaximize (window, - META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL); -} - -LOCAL_SYMBOL void -meta_core_delete (Display *xdisplay, - Window frame_xwindow, - guint32 timestamp) -{ - MetaWindow *window = meta_core_get_window (xdisplay, frame_xwindow); - - meta_window_delete (window, timestamp); -} - -LOCAL_SYMBOL void -meta_core_unshade (Display *xdisplay, - Window frame_xwindow, - guint32 timestamp) -{ - MetaWindow *window = meta_core_get_window (xdisplay, frame_xwindow); - - meta_screen_hide_hud_and_preview (window->screen); - - meta_window_unshade (window, timestamp); -} - -LOCAL_SYMBOL void -meta_core_shade (Display *xdisplay, - Window frame_xwindow, - guint32 timestamp) -{ - MetaWindow *window = meta_core_get_window (xdisplay, frame_xwindow); - - meta_screen_hide_hud_and_preview (window->screen); - - meta_window_shade (window, timestamp); -} - -LOCAL_SYMBOL void -meta_core_unstick (Display *xdisplay, - Window frame_xwindow) -{ - MetaWindow *window = meta_core_get_window (xdisplay, frame_xwindow); - - meta_window_unstick (window); -} - -LOCAL_SYMBOL void -meta_core_make_above (Display *xdisplay, - Window frame_xwindow) -{ - MetaWindow *window = meta_core_get_window (xdisplay, frame_xwindow); - - meta_window_make_above (window); -} - -LOCAL_SYMBOL void -meta_core_unmake_above (Display *xdisplay, - Window frame_xwindow) -{ - MetaWindow *window = meta_core_get_window (xdisplay, frame_xwindow); - - meta_window_unmake_above (window); -} - -LOCAL_SYMBOL void -meta_core_adjust_opacity (Display *xdisplay, - Window frame_xwindow, - gboolean increase) -{ - MetaWindow *window = meta_core_get_window (xdisplay, frame_xwindow); - - meta_window_adjust_opacity (window, increase); -} - -LOCAL_SYMBOL void -meta_core_stick (Display *xdisplay, - Window frame_xwindow) -{ - MetaWindow *window = meta_core_get_window (xdisplay, frame_xwindow); - - meta_window_stick (window); -} - -LOCAL_SYMBOL void -meta_core_change_workspace (Display *xdisplay, - Window frame_xwindow, - int new_workspace) -{ - MetaWindow *window = meta_core_get_window (xdisplay, frame_xwindow); - - meta_window_change_workspace (window, - meta_screen_get_workspace_by_index (window->screen, - new_workspace)); -} - -LOCAL_SYMBOL int -meta_core_get_num_workspaces (Screen *xscreen) -{ - MetaScreen *screen; - - screen = meta_screen_for_x_screen (xscreen); - - return meta_screen_get_n_workspaces (screen); -} - -LOCAL_SYMBOL int -meta_core_get_active_workspace (Screen *xscreen) -{ - MetaScreen *screen; - - screen = meta_screen_for_x_screen (xscreen); - - return meta_workspace_index (screen->active_workspace); -} - -LOCAL_SYMBOL void -meta_core_show_window_menu (Display *xdisplay, - Window frame_xwindow, - int root_x, - int root_y, - int button, - guint32 timestamp) -{ - MetaWindow *window = meta_core_get_window (xdisplay, frame_xwindow); - - meta_screen_hide_hud_and_preview (window->screen); - - if (meta_prefs_get_raise_on_click ()) - meta_window_raise (window); - meta_window_focus (window, timestamp); - - meta_window_show_menu (window, root_x, root_y, button, timestamp); -} - -LOCAL_SYMBOL void -meta_core_get_menu_accelerator (MetaMenuOp menu_op, - int workspace, - unsigned int *keysym, - MetaVirtualModifier *modifiers) -{ - const char *name; - - name = NULL; - - switch (menu_op) - { - case META_MENU_OP_NONE: - /* No keybinding for this one */ - break; - case META_MENU_OP_DELETE: - name = "close"; - break; - case META_MENU_OP_MINIMIZE: - name = "minimize"; - break; - case META_MENU_OP_UNMAXIMIZE: - name = "unmaximize"; - break; - case META_MENU_OP_MAXIMIZE: - name = "maximize"; - break; - case META_MENU_OP_UNSHADE: - case META_MENU_OP_SHADE: - name = "toggle_shaded"; - break; - case META_MENU_OP_UNSTICK: - case META_MENU_OP_STICK: - name = "toggle-on-all-workspaces"; - break; - case META_MENU_OP_ABOVE: - case META_MENU_OP_UNABOVE: - name = "toggle-above"; - break; - case META_MENU_OP_WORKSPACES: - switch (workspace) - { - case 1: - name = "move-to-workspace-1"; - break; - case 2: - name = "move-to-workspace-2"; - break; - case 3: - name = "move-to-workspace-3"; - break; - case 4: - name = "move-to-workspace-4"; - break; - case 5: - name = "move-to-workspace-5"; - break; - case 6: - name = "move-to-workspace-6"; - break; - case 7: - name = "move-to-workspace-7"; - break; - case 8: - name = "move-to-workspace-8"; - break; - case 9: - name = "move-to-workspace-9"; - break; - case 10: - name = "move-to-workspace-10"; - break; - case 11: - name = "move-to-workspace-11"; - break; - case 12: - name = "move-to-workspace-12"; - break; - } - break; - case META_MENU_OP_MOVE: - name = "begin-move"; - break; - case META_MENU_OP_RESIZE: - name = "begin-resize"; - break; - case META_MENU_OP_MOVE_LEFT: - name = "move-to-workspace-left"; - break; - case META_MENU_OP_MOVE_RIGHT: - name = "move-to-workspace-right"; - break; - case META_MENU_OP_MOVE_UP: - name = "move-to-workspace-up"; - break; - case META_MENU_OP_MOVE_DOWN: - name = "move-to-workspace-down"; - break; - case META_MENU_OP_MOVE_NEW: - name = "move-to-workspace-new"; - break; - case META_MENU_OP_RECOVER: - /* No keybinding for this one */ - break; - default: - break; - } - - if (name) - { - meta_prefs_get_window_binding (name, keysym, modifiers); - } - else - { - *keysym = 0; - *modifiers = 0; - } -} - -LOCAL_SYMBOL const char* -meta_core_get_workspace_name_with_index (Display *xdisplay, - Window xroot, - int index) -{ - MetaDisplay *display; - MetaScreen *screen; - MetaWorkspace *workspace; - - display = meta_display_for_x_display (xdisplay); - screen = meta_display_screen_for_root (display, xroot); - g_assert (screen != NULL); - workspace = meta_screen_get_workspace_by_index (screen, index); - return workspace ? meta_workspace_get_name (workspace) : NULL; -} - -LOCAL_SYMBOL gboolean -meta_core_begin_grab_op (Display *xdisplay, - Window frame_xwindow, - MetaGrabOp op, - gboolean pointer_already_grabbed, - gboolean frame_action, - int button, - gulong modmask, - guint32 timestamp, - int root_x, - int root_y) -{ - MetaWindow *window = meta_core_get_window (xdisplay, frame_xwindow); - MetaDisplay *display; - MetaScreen *screen; - - display = meta_display_for_x_display (xdisplay); - screen = meta_display_screen_for_xwindow (display, frame_xwindow); - - g_assert (screen != NULL); - - return meta_display_begin_grab_op (display, screen, window, - op, pointer_already_grabbed, - frame_action, - button, modmask, - timestamp, root_x, root_y); -} - -LOCAL_SYMBOL void -meta_core_end_grab_op (Display *xdisplay, - guint32 timestamp) -{ - MetaDisplay *display; - - display = meta_display_for_x_display (xdisplay); - - meta_display_end_grab_op (display, timestamp); -} - -LOCAL_SYMBOL MetaGrabOp -meta_core_get_grab_op (Display *xdisplay) -{ - MetaDisplay *display; - - display = meta_display_for_x_display (xdisplay); - - return display->grab_op; -} - -LOCAL_SYMBOL Window -meta_core_get_grab_frame (Display *xdisplay) -{ - MetaDisplay *display; - - display = meta_display_for_x_display (xdisplay); - - g_assert (display != NULL); - g_assert (display->grab_op == META_GRAB_OP_NONE || - display->grab_screen != NULL); - g_assert (display->grab_op == META_GRAB_OP_NONE || - display->grab_screen->display->xdisplay == xdisplay); - - if (display->grab_op != META_GRAB_OP_NONE && - display->grab_window && - display->grab_window->frame) - return display->grab_window->frame->xwindow; - else - return None; -} - -LOCAL_SYMBOL int -meta_core_get_grab_button (Display *xdisplay) -{ - MetaDisplay *display; - - display = meta_display_for_x_display (xdisplay); - - if (display->grab_op == META_GRAB_OP_NONE) - return -1; - - return display->grab_button; -} - -LOCAL_SYMBOL void -meta_core_grab_buttons (Display *xdisplay, - Window frame_xwindow) -{ - MetaDisplay *display; - - display = meta_display_for_x_display (xdisplay); - - meta_verbose ("Grabbing buttons on frame 0x%lx\n", frame_xwindow); - meta_display_grab_window_buttons (display, frame_xwindow); -} - -LOCAL_SYMBOL void -meta_core_set_screen_cursor (Display *xdisplay, - Window frame_on_screen, - MetaCursor cursor) -{ - MetaWindow *window = meta_core_get_window (xdisplay, frame_on_screen); - - meta_frame_set_screen_cursor (window->frame, cursor); -} - -LOCAL_SYMBOL void -meta_core_increment_event_serial (Display *xdisplay) -{ - MetaDisplay *display; - - display = meta_display_for_x_display (xdisplay); - - meta_display_increment_event_serial (display); -} - diff --git a/src/core/core.h b/src/core/core.h deleted file mode 100644 index e17af76de..000000000 --- a/src/core/core.h +++ /dev/null @@ -1,221 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Muffin interface used by GTK+ UI to talk to core */ - -/* - * Copyright (C) 2001 Havoc Pennington - * Copyright (C) 2005 Elijah Newren - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. - */ - -#ifndef META_CORE_H -#define META_CORE_H - -/* Don't include core headers here */ -#include <gdk/gdkx.h> -#include <meta/common.h> -#include <meta/window.h> - -typedef enum -{ - META_CORE_GET_END = 0, - META_CORE_WINDOW_HAS_FRAME, - META_CORE_GET_CLIENT_WIDTH, - META_CORE_GET_CLIENT_HEIGHT, - META_CORE_GET_CLIENT_XWINDOW, - META_CORE_GET_FRAME_FLAGS, - META_CORE_GET_FRAME_TYPE, - META_CORE_GET_X, - META_CORE_GET_Y, - META_CORE_GET_FRAME_WORKSPACE, - META_CORE_GET_FRAME_X, - META_CORE_GET_FRAME_Y, - META_CORE_GET_FRAME_WIDTH, - META_CORE_GET_FRAME_HEIGHT, - META_CORE_GET_THEME_VARIANT, - META_CORE_GET_SCREEN_WIDTH, - META_CORE_GET_SCREEN_HEIGHT, -} MetaCoreGetType; - -/* General information function about the given window. Pass in a sequence of - * pairs of MetaCoreGetTypes and pointers to variables; the variables will be - * filled with the requested values. End the list with META_CORE_GET_END. - * For example: - * - * meta_core_get (my_display, my_window, - * META_CORE_GET_X, &x, - * META_CORE_GET_Y, &y, - * META_CORE_GET_END); - * - * If the window doesn't have a frame, this will raise a meta_bug. To suppress - * this behaviour, ask META_CORE_WINDOW_HAS_FRAME as the *first* question in - * the list. If the window has no frame, the answer to this question will be - * False, and anything else you asked will be undefined. Otherwise, the answer - * will be True. The answer will necessarily be True if you ask the question - * in any other position. The positions of all other questions don't matter. - * - * The reason for this function is that some parts of the program don't know - * about MetaWindows. But they *can* see core.h. So we used to have a whole - * load of functions which took a display and an X window, looked up the - * relevant MetaWindow, and returned information about it. The trouble with - * that is that looking up the MetaWindow is a nontrivial operation, and - * consolidating the calls in this way makes (for example) frame exposes - * 33% faster, according to valgrind. - * - * This function would perhaps be slightly better if the questions were - * represented by pointers, perhaps gchar*s, because then we could take - * advantage of gcc's automatic sentinel checking. On the other hand, this - * immediately suggests string comparison, and that's slow. - * - * Another possible improvement is that core.h still has a bunch of - * functions which can't be described by the formula "give a display and - * an X window, get a single value" (meta_core_user_move, for example), but - * which could theoretically be handled by this function if we relaxed the - * requirement that all questions should have exactly one argument. - */ - -MetaWindow *meta_core_get_window (Display *xdisplay, - Window frame_xwindow); - -void meta_core_get (Display *xdisplay, - Window window, - ...); - -void meta_core_queue_frame_resize (Display *xdisplay, - Window frame_xwindow); - -/* Move as a result of user operation */ -void meta_core_user_move (Display *xdisplay, - Window frame_xwindow, - int x, - int y); -void meta_core_user_resize (Display *xdisplay, - Window frame_xwindow, - int gravity, - int width, - int height); - -void meta_core_user_raise (Display *xdisplay, - Window frame_xwindow); -void meta_core_user_lower_and_unfocus (Display *xdisplay, - Window frame_xwindow, - guint32 timestamp); - -void meta_core_user_focus (Display *xdisplay, - Window frame_xwindow, - guint32 timestamp); - -void meta_core_lower_beneath_grab_window (Display *xdisplay, - Window xwindow, - guint32 timestamp); - -void meta_core_lower_beneath_sibling (Display *xdisplay, - Window xwindow, - Window grab_window, - guint32 timestamp); - -void meta_core_minimize (Display *xdisplay, - Window frame_xwindow); -void meta_core_toggle_maximize (Display *xdisplay, - Window frame_xwindow); -void meta_core_toggle_maximize_horizontally (Display *xdisplay, - Window frame_xwindow); -void meta_core_toggle_maximize_vertically (Display *xdisplay, - Window frame_xwindow); -void meta_core_unmaximize (Display *xdisplay, - Window frame_xwindow); -void meta_core_maximize (Display *xdisplay, - Window frame_xwindow); -void meta_core_delete (Display *xdisplay, - Window frame_xwindow, - guint32 timestamp); -void meta_core_unshade (Display *xdisplay, - Window frame_xwindow, - guint32 timestamp); -void meta_core_shade (Display *xdisplay, - Window frame_xwindow, - guint32 timestamp); -void meta_core_unstick (Display *xdisplay, - Window frame_xwindow); -void meta_core_stick (Display *xdisplay, - Window frame_xwindow); -void meta_core_unmake_above (Display *xdisplay, - Window frame_xwindow); -void meta_core_make_above (Display *xdisplay, - Window frame_xwindow); -void meta_core_adjust_opacity (Display *xdisplay, - Window frame_xwindow, - gboolean increase); -void meta_core_change_workspace (Display *xdisplay, - Window frame_xwindow, - int new_workspace); - -int meta_core_get_num_workspaces (Screen *xscreen); -int meta_core_get_active_workspace (Screen *xscreen); -int meta_core_get_frame_workspace (Display *xdisplay, - Window frame_xwindow); -const char* meta_core_get_workspace_name_with_index (Display *xdisplay, - Window xroot, - int index); - -void meta_core_show_window_menu (Display *xdisplay, - Window frame_xwindow, - int root_x, - int root_y, - int button, - guint32 timestamp); - -void meta_core_get_menu_accelerator (MetaMenuOp menu_op, - int workspace, - unsigned int *keysym, - MetaVirtualModifier *modifiers); - -gboolean meta_core_begin_grab_op (Display *xdisplay, - Window frame_xwindow, - MetaGrabOp op, - gboolean pointer_already_grabbed, - gboolean frame_action, - int button, - gulong modmask, - guint32 timestamp, - int root_x, - int root_y); -void meta_core_end_grab_op (Display *xdisplay, - guint32 timestamp); -MetaGrabOp meta_core_get_grab_op (Display *xdisplay); -Window meta_core_get_grab_frame (Display *xdisplay); -int meta_core_get_grab_button (Display *xdisplay); - - -void meta_core_grab_buttons (Display *xdisplay, - Window frame_xwindow); - -void meta_core_set_screen_cursor (Display *xdisplay, - Window frame_on_screen, - MetaCursor cursor); - -/* Used because we ignore EnterNotify when a window is unmapped that - * really shouldn't cause focus changes, by comparing the event serial - * of the EnterNotify and the UnmapNotify. - */ -void meta_core_increment_event_serial (Display *display); - -#endif - - - - diff --git a/src/core/delete.c b/src/core/delete.c index 5ef767c29..28ca63d89 100644 --- a/src/core/delete.c +++ b/src/core/delete.c @@ -1,6 +1,6 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* Muffin window deletion */ +/* Mutter window deletion */ /* * Copyright (C) 2001, 2002 Havoc Pennington @@ -17,261 +17,108 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #define _XOPEN_SOURCE /* for kill() */ -#include <config.h> -#include "util-private.h" -#include "window-private.h" -#include <meta/errors.h> -#include <meta/workspace.h> +#include "config.h" -#include <sys/types.h> -#include <sys/wait.h> -#include <signal.h> -#include <unistd.h> #include <errno.h> -#include <string.h> -#include <stdlib.h> -#include <stdio.h> -static void meta_window_present_delete_dialog (MetaWindow *window, - guint32 timestamp); +#include "compositor/compositor-private.h" +#include "core/util-private.h" +#include "core/window-private.h" +#include "meta/meta-x11-errors.h" +#include "meta/workspace.h" static void -delete_ping_reply_func (MetaDisplay *display, - Window xwindow, - guint32 timestamp, - void *user_data) +close_dialog_response_cb (MetaCloseDialog *dialog, + MetaCloseDialogResponse response, + MetaWindow *window) { - meta_topic (META_DEBUG_PING, - "Got reply to delete ping for %s\n", - ((MetaWindow*)user_data)->desc); - - /* we do nothing */ + if (response == META_CLOSE_DIALOG_RESPONSE_FORCE_CLOSE) + meta_window_kill (window); } static void -dialog_exited (GPid pid, int status, gpointer user_data) +meta_window_ensure_close_dialog (MetaWindow *window) { - MetaWindow *ours = (MetaWindow*) user_data; + MetaDisplay *display; - ours->dialog_pid = -1; + if (window->close_dialog) + return; - /* exit status of 1 means the user pressed "Force Quit" */ - if (WIFEXITED (status) && WEXITSTATUS (status) == 1) - meta_window_kill (ours); + display = window->display; + window->close_dialog = meta_compositor_create_close_dialog (display->compositor, + window); + g_signal_connect (window->close_dialog, "response", + G_CALLBACK (close_dialog_response_cb), window); } -static void -delete_ping_timeout_func (MetaDisplay *display, - Window xwindow, - guint32 timestamp, - void *user_data) +void +meta_window_set_alive (MetaWindow *window, + gboolean is_alive) { - MetaWindow *window = user_data; - char *window_title; - gchar *window_content, *tmp; - GPid dialog_pid; - - meta_topic (META_DEBUG_PING, - "Got delete ping timeout for %s\n", - window->desc); - - if (window->dialog_pid >= 0) - { - meta_window_present_delete_dialog (window, timestamp); - return; - } - - /* This is to get a better string if the title isn't representable - * in the locale encoding; actual conversion to UTF-8 is done inside - * meta_show_dialog */ - - if (window->title && window->title[0]) + if (is_alive && window->close_dialog) { - tmp = g_locale_from_utf8 (window->title, -1, NULL, NULL, NULL); - if (tmp == NULL) - window_title = NULL; - else - window_title = window->title; - free (tmp); + meta_close_dialog_hide (window->close_dialog); } - else + else if (!is_alive) { - window_title = NULL; - } + meta_window_ensure_close_dialog (window); + meta_close_dialog_show (window->close_dialog); - /* Translators: %s is a window title */ - if (window_title) - { - // FIXME: Didn't want to lose translations for this.. needed to remove the - // monospace tt but it's part of the translation. Cancel them out for now. - gchar *unmarkup_title = g_markup_printf_escaped("</tt>%s<tt>", window_title); - - tmp = g_strdup_printf (_("<tt>%s</tt> is not responding."), - unmarkup_title); - - free (unmarkup_title); + if (window->display && + window->display->event_route == META_EVENT_ROUTE_NORMAL && + window == window->display->focus_window) + meta_close_dialog_focus (window->close_dialog); } - else - tmp = g_strdup (_("Application is not responding.")); - - window_content = g_strdup_printf ( - "<big><b>%s</b></big>\n\n%s", - tmp, - _("You may choose to wait a short while for it to " - "continue or force the application to quit entirely.")); - - dialog_pid = - meta_show_dialog ("--question", - window_content, NULL, - window->screen->screen_name, - _("_Wait"), _("_Force Quit"), window->xwindow, - NULL, NULL); - - free (window_content); - free (tmp); +} - window->dialog_pid = dialog_pid; - g_child_watch_add (dialog_pid, dialog_exited, window); +void +meta_window_check_alive (MetaWindow *window, + guint32 timestamp) +{ + meta_display_ping_window (window, timestamp); } void meta_window_delete (MetaWindow *window, guint32 timestamp) { - meta_error_trap_push (window->display); - if (window->delete_window) - { - meta_topic (META_DEBUG_WINDOW_OPS, - "Deleting %s with delete_window request\n", - window->desc); - meta_window_send_icccm_message (window, - window->display->atom_WM_DELETE_WINDOW, - timestamp); - } - else - { - meta_topic (META_DEBUG_WINDOW_OPS, - "Deleting %s with explicit kill\n", - window->desc); - XKillClient (window->display->xdisplay, window->xwindow); - } - meta_error_trap_pop (window->display); + META_WINDOW_GET_CLASS (window)->delete (window, timestamp); - meta_display_ping_window (window->display, - window, - timestamp, - delete_ping_reply_func, - delete_ping_timeout_func, - window); - - if (window->has_focus) - { - /* FIXME Clean this up someday - * http://bugzilla.gnome.org/show_bug.cgi?id=108706 - */ -#if 0 - /* This is unfortunately going to result in weirdness - * if the window doesn't respond to the delete event. - * I don't know how to avoid that though. - */ - meta_topic (META_DEBUG_FOCUS, - "Focusing default window because focus window %s was deleted/killed\n", - window->desc); - meta_workspace_focus_default_window (window->screen->active_workspace, - window); -#else - meta_topic (META_DEBUG_FOCUS, - "Not unfocusing %s on delete/kill\n", - window->desc); -#endif - } - else - { - meta_topic (META_DEBUG_FOCUS, - "Window %s was deleted/killed but didn't have focus\n", - window->desc); - } + meta_window_check_alive (window, timestamp); } - -LOCAL_SYMBOL void +void meta_window_kill (MetaWindow *window) { - meta_topic (META_DEBUG_WINDOW_OPS, - "Killing %s brutally\n", - window->desc); + pid_t pid = meta_window_get_client_pid (window); - if (!meta_window_is_remote (window) && - window->net_wm_pid > 0) + if (pid > 0) { meta_topic (META_DEBUG_WINDOW_OPS, "Killing %s with kill()\n", window->desc); - if (kill (window->net_wm_pid, 9) < 0) - meta_topic (META_DEBUG_WINDOW_OPS, - "Failed to signal %s: %s\n", - window->desc, strerror (errno)); + if (kill (pid, 9) == 0) + return; + + meta_topic (META_DEBUG_WINDOW_OPS, + "Failed to signal %s: %s\n", + window->desc, strerror (errno)); } - meta_topic (META_DEBUG_WINDOW_OPS, - "Disconnecting %s with XKillClient()\n", - window->desc); - meta_error_trap_push (window->display); - XKillClient (window->display->xdisplay, window->xwindow); - meta_error_trap_pop (window->display); + META_WINDOW_GET_CLASS (window)->kill (window); } -LOCAL_SYMBOL void +void meta_window_free_delete_dialog (MetaWindow *window) { - if (window->dialog_pid >= 0) - { - kill (window->dialog_pid, 9); - window->dialog_pid = -1; - } -} - -static void -meta_window_present_delete_dialog (MetaWindow *window, guint32 timestamp) -{ - meta_topic (META_DEBUG_PING, - "Presenting existing ping dialog for %s\n", - window->desc); - - if (window->dialog_pid >= 0) - { - GSList *windows; - GSList *tmp; - - /* Activate transient for window that belongs to - * muffin-dialog - */ - - windows = meta_display_list_windows (window->display, META_LIST_DEFAULT); - tmp = windows; - while (tmp != NULL) - { - MetaWindow *w = tmp->data; - - if (w->xtransient_for == window->xwindow && - w->res_class && - g_ascii_strcasecmp (w->res_class, "muffin-dialog") == 0) - { - meta_window_activate (w, timestamp); - break; - } - - tmp = tmp->next; - } - - g_slist_free (windows); - } + if (window->close_dialog && + meta_close_dialog_is_visible (window->close_dialog)) + meta_close_dialog_hide (window->close_dialog); + g_clear_object (&window->close_dialog); } diff --git a/src/core/display-private.h b/src/core/display-private.h index 6e534c75a..251e9e2a8 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -1,13 +1,13 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* Muffin X display handler */ +/* Mutter X display handler */ -/* +/* * Copyright (C) 2001 Havoc Pennington * Copyright (C) 2002 Red Hat, Inc. * Copyright (C) 2003 Rob Adams * Copyright (C) 2004-2006 Elijah Newren - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the @@ -17,50 +17,47 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_DISPLAY_PRIVATE_H #define META_DISPLAY_PRIVATE_H -#ifndef PACKAGE -#error "config.h not included" -#endif +#include "meta/display.h" #include <glib.h> +#include <X11/extensions/sync.h> #include <X11/Xlib.h> -#include "eventqueue.h" -#include <meta/common.h> -#include <meta/boxes.h> -#include <meta/display.h> -#include "keybindings-private.h" -#include <meta/prefs.h> -#include "ui.h" #ifdef HAVE_STARTUP_NOTIFICATION #include <libsn/sn.h> #endif -#ifdef HAVE_XSYNC -#include <X11/extensions/sync.h> -#endif - +#include "clutter/clutter.h" +#include "core/keybindings-private.h" +#include "core/meta-gesture-tracker-private.h" +#include "core/stack-tracker.h" +#include "core/startup-notification-private.h" +#include "meta/barrier.h" +#include "meta/boxes.h" +#include "meta/common.h" +#include "meta/meta-selection.h" +#include "meta/prefs.h" + +typedef struct _MetaBell MetaBell; typedef struct _MetaStack MetaStack; typedef struct _MetaUISlave MetaUISlave; -typedef struct _MetaGroupPropHooks MetaGroupPropHooks; -typedef struct _MetaWindowPropHooks MetaWindowPropHooks; - typedef struct MetaEdgeResistanceData MetaEdgeResistanceData; -typedef void (* MetaWindowPingFunc) (MetaDisplay *display, - Window xwindow, - guint32 timestamp, - gpointer user_data); +typedef enum +{ + META_LIST_DEFAULT = 0, /* normal windows */ + META_LIST_INCLUDE_OVERRIDE_REDIRECT = 1 << 0, /* normal and O-R */ + META_LIST_SORTED = 1 << 1, /* sort list by mru */ +} MetaListWindowsFlags; #define _NET_WM_STATE_REMOVE 0 /* remove/unset property */ #define _NET_WM_STATE_ADD 1 /* add/set property */ @@ -75,42 +72,54 @@ typedef void (* MetaWindowPingFunc) (MetaDisplay *display, */ #define N_IGNORED_CROSSING_SERIALS 10 +typedef enum +{ + META_TILE_NONE, + META_TILE_LEFT, + META_TILE_RIGHT, + META_TILE_MAXIMIZED +} MetaTileMode; + +typedef enum +{ + /* Normal interaction where you're interacting with windows. + * Events go to windows normally. */ + META_EVENT_ROUTE_NORMAL, + + /* In a window operation like moving or resizing. All events + * goes to MetaWindow, but not to the actual client window. */ + META_EVENT_ROUTE_WINDOW_OP, + + /* In a compositor grab operation. All events go to the + * compositor plugin. */ + META_EVENT_ROUTE_COMPOSITOR_GRAB, + + /* A Wayland application has a popup open. All events go to + * the Wayland application. */ + META_EVENT_ROUTE_WAYLAND_POPUP, + + /* The user is clicking on a window button. */ + META_EVENT_ROUTE_FRAME_BUTTON, +} MetaEventRoute; + +typedef void (* MetaDisplayWindowFunc) (MetaWindow *window, + gpointer user_data); + struct _MetaDisplay { GObject parent_instance; - - char *name; - Display *xdisplay; - GdkDisplay *gdk_display; - GdkDevice *gdk_device; - char *hostname; - Window leader_window; - Window timestamp_pinging_window; + MetaX11Display *x11_display; - MetaUI *ui; - - /* Pull in all the names of atoms as fields; we will intern them when the - * class is constructed. - */ -#define item(x) Atom atom_##x; -#include <meta/atomnames.h> -#undef item + int clutter_event_filter; - /* This is the actual window from focus events, - * not the one we last set + /* Our best guess as to the "currently" focused window (that is, the + * window that we expect will be focused at the point when the X + * server processes our next request), and the serial of the request + * or event that caused this. */ MetaWindow *focus_window; - /* window we are expecting a FocusIn event for or the current focus - * window if we are not expecting any FocusIn/FocusOut events; not - * perfect because applications can call XSetInputFocus directly. - * (It could also be messed up if a timestamp later than current - * time is sent to meta_display_set_input_focus_window, though that - * would be a programming error). See bug 154598 for more info. - */ - MetaWindow *expected_focus_window; - /* last timestamp passed to XSetInputFocus */ guint32 last_focus_time; @@ -131,31 +140,21 @@ struct _MetaDisplay */ guint allow_terminal_deactivation : 1; - guint static_gravity_works : 1; - /*< private-ish >*/ - guint error_trap_synced_at_last_pop : 1; - MetaEventQueue *events; - GSList *screens; - MetaScreen *active_screen; - GHashTable *window_ids; - int error_traps; - int (* error_trap_handler) (Display *display, - XErrorEvent *error); - int server_grab_count; + GHashTable *stamps; + GHashTable *wayland_windows; /* serials of leave/unmap events that may * correspond to an enter event we should * ignore */ unsigned long ignored_crossing_serials[N_IGNORED_CROSSING_SERIALS]; - Window ungrab_should_not_cause_focus_window; - + guint32 current_time; /* We maintain a sequence counter, incremented for each #MetaWindow * created. This is exposed by meta_window_get_stable_sequence() - * but is otherwise not used inside muffin. + * but is otherwise not used inside mutter. * * It can be useful to plugins which want to sort windows in a * stable fashion. @@ -165,19 +164,19 @@ struct _MetaDisplay /* Pings which we're waiting for a reply from */ GSList *pending_pings; + /* Pending focus change */ + guint focus_timeout_id; + /* Pending autoraise */ guint autoraise_timeout_id; MetaWindow* autoraise_window; - /* Alt+click button grabs */ - unsigned int window_grab_modifiers; - unsigned int mouse_zoom_modifiers; - + /* Event routing */ + MetaEventRoute event_route; + /* current window operation */ MetaGrabOp grab_op; - MetaScreen *grab_screen; MetaWindow *grab_window; - Window grab_xwindow; int grab_button; int grab_anchor_root_x; int grab_anchor_root_y; @@ -186,52 +185,20 @@ struct _MetaDisplay int grab_tile_monitor_number; int grab_latest_motion_x; int grab_latest_motion_y; - gulong grab_mask; guint grab_have_pointer : 1; guint grab_have_keyboard : 1; guint grab_frame_action : 1; - /* During a resize operation, the directions in which we've broken - * out of the initial maximization state */ - guint grab_resize_unmaximize : 2; /* MetaMaximizeFlags */ MetaRectangle grab_initial_window_pos; int grab_initial_x, grab_initial_y; /* These are only relevant for */ gboolean grab_threshold_movement_reached; /* raise_on_click == FALSE. */ - MetaResizePopup *grab_resize_popup; - GTimeVal grab_last_moveresize_time; - guint32 grab_motion_notify_time; - GList* grab_old_window_stacking; + int64_t grab_last_moveresize_time; MetaEdgeResistanceData *grab_edge_resistance_data; unsigned int grab_last_user_action_was_snap; - /* we use property updates as sentinels for certain window focus events - * to avoid some race conditions on EnterNotify events - */ - int sentinel_counter; - -#ifdef HAVE_XKB - int xkb_base_event_type; - guint32 last_bell_time; -#endif int grab_resize_timeout_id; - /* Keybindings stuff */ - MetaKeyBinding *key_bindings; - int n_key_bindings; - int min_keycode; - int max_keycode; - KeySym *keymap; - int keysyms_per_keycode; - XModifierKeymap *modmap; - unsigned int above_tab_keycode; - unsigned int ignored_modifier_mask; - unsigned int num_lock_mask; - unsigned int scroll_lock_mask; - unsigned int hyper_mask; - unsigned int super_mask; - unsigned int meta_mask; - - guint rebuild_keybinding_idle_id; - + MetaKeyBindingManager key_binding_manager; + /* Monitor cache */ unsigned int monitor_cache_invalidated : 1; @@ -241,73 +208,38 @@ struct _MetaDisplay /* Closing down the display */ int closing; - /* Managed by group.c */ - GHashTable *groups_by_leader; + /* Managed by compositor.c */ + MetaCompositor *compositor; - /* currently-active window menu if any */ - MetaWindowMenu *window_menu; - MetaWindow *window_with_menu; + MetaGestureTracker *gesture_tracker; + ClutterEventSequence *pointer_emulating_sequence; - /* Managed by window-props.c */ - MetaWindowPropHooks *prop_hooks_table; - GHashTable *prop_hooks; - int n_prop_hooks; + ClutterActor *current_pad_osd; - /* Managed by group-props.c */ - MetaGroupPropHooks *group_prop_hooks; + MetaStartupNotification *startup_notification; - /* Managed by compositor.c */ - MetaCompositor *compositor; + MetaCursor current_cursor; - unsigned int mouse_zoom_enabled : 1; + MetaStack *stack; + MetaStackTracker *stack_tracker; - int render_event_base; - int render_error_base; + guint tile_preview_timeout_id; + guint preview_tile_mode : 2; - int composite_event_base; - int composite_error_base; - int composite_major_version; - int composite_minor_version; - int damage_event_base; - int damage_error_base; - int xfixes_event_base; - int xfixes_error_base; - -#ifdef HAVE_STARTUP_NOTIFICATION - SnDisplay *sn_display; -#endif -#ifdef HAVE_XSYNC - int xsync_event_base; - int xsync_error_base; -#endif -#ifdef HAVE_SHAPE - int shape_event_base; - int shape_error_base; -#endif -#ifdef HAVE_XSYNC - unsigned int have_xsync : 1; -#define META_DISPLAY_HAS_XSYNC(display) ((display)->have_xsync) -#else -#define META_DISPLAY_HAS_XSYNC(display) FALSE -#endif -#ifdef HAVE_SHAPE - unsigned int have_shape : 1; -#define META_DISPLAY_HAS_SHAPE(display) ((display)->have_shape) -#else -#define META_DISPLAY_HAS_SHAPE(display) FALSE -#endif - unsigned int have_render : 1; -#define META_DISPLAY_HAS_RENDER(display) ((display)->have_render) - unsigned int have_composite : 1; - unsigned int have_damage : 1; - unsigned int have_xfixes : 1; -#define META_DISPLAY_HAS_COMPOSITE(display) ((display)->have_composite) -#define META_DISPLAY_HAS_DAMAGE(display) ((display)->have_damage) -#define META_DISPLAY_HAS_XFIXES(display) ((display)->have_xfixes) - MetaSyncMethod sync_method; - - guint shadows_enabled : 1; - guint debug_button_grabs : 1; + GSList *startup_sequences; + + guint work_area_later; + guint check_fullscreen_later; + + MetaBell *bell; + MetaWorkspaceManager *workspace_manager; + + MetaSoundPlayer *sound_player; + + MetaSelectionSource *selection_source; + GBytes *saved_clipboard; + gchar *saved_clipboard_mimetype; + MetaSelection *selection; }; struct _MetaDisplayClass @@ -331,59 +263,58 @@ struct _MetaDisplayClass ) gboolean meta_display_open (void); -void meta_display_close (MetaDisplay *display, - guint32 timestamp); -MetaScreen* meta_display_screen_for_x_screen (MetaDisplay *display, - Screen *screen); -MetaScreen* meta_display_screen_for_xwindow (MetaDisplay *display, - Window xindow); -void meta_display_grab (MetaDisplay *display); -void meta_display_ungrab (MetaDisplay *display); - -void meta_display_unmanage_windows_for_screen (MetaDisplay *display, - MetaScreen *screen, - guint32 timestamp); + +void meta_display_manage_all_xwindows (MetaDisplay *display); +void meta_display_unmanage_windows (MetaDisplay *display, + guint32 timestamp); /* Utility function to compare the stacking of two windows */ int meta_display_stack_cmp (const void *a, const void *b); -/* A given MetaWindow may have various X windows that "belong" - * to it, such as the frame window. +/* Each MetaWindow is uniquely identified by a 64-bit "stamp"; unlike a + * a MetaWindow *, a stamp will never be recycled */ -MetaWindow* meta_display_lookup_x_window (MetaDisplay *display, - Window xwindow); -void meta_display_register_x_window (MetaDisplay *display, - Window *xwindowp, - MetaWindow *window); -void meta_display_unregister_x_window (MetaDisplay *display, - Window xwindow); - -#ifdef HAVE_XSYNC -MetaWindow* meta_display_lookup_sync_alarm (MetaDisplay *display, - XSyncAlarm alarm); -void meta_display_register_sync_alarm (MetaDisplay *display, - XSyncAlarm *alarmp, - MetaWindow *window); -void meta_display_unregister_sync_alarm (MetaDisplay *display, - XSyncAlarm alarm); -#endif /* HAVE_XSYNC */ +MetaWindow* meta_display_lookup_stamp (MetaDisplay *display, + guint64 stamp); +void meta_display_register_stamp (MetaDisplay *display, + guint64 *stampp, + MetaWindow *window); +void meta_display_unregister_stamp (MetaDisplay *display, + guint64 stamp); + +/* A "stack id" is a XID or a stamp */ +#define META_STACK_ID_IS_X11(id) ((id) < G_GUINT64_CONSTANT(0x100000000)) + +META_EXPORT_TEST +MetaWindow* meta_display_lookup_stack_id (MetaDisplay *display, + guint64 stack_id); + +/* for debug logging only; returns a human-description of the stack + * ID - a small number of buffers are recycled, so the result must + * be used immediately or copied */ +const char *meta_display_describe_stack_id (MetaDisplay *display, + guint64 stack_id); + +void meta_display_register_wayland_window (MetaDisplay *display, + MetaWindow *window); +void meta_display_unregister_wayland_window (MetaDisplay *display, + MetaWindow *window); void meta_display_notify_window_created (MetaDisplay *display, MetaWindow *window); +META_EXPORT_TEST +GSList* meta_display_list_windows (MetaDisplay *display, + MetaListWindowsFlags flags); + MetaDisplay* meta_display_for_x_display (Display *xdisplay); -MetaDisplay* meta_get_display (void); -Cursor meta_display_create_x_cursor (MetaDisplay *display, - MetaCursor cursor); +META_EXPORT_TEST +MetaDisplay* meta_get_display (void); -void meta_display_set_grab_op_cursor (MetaDisplay *display, - MetaScreen *screen, - MetaGrabOp op, - gboolean change_pointer, - Window grab_xwindow, - guint32 timestamp); +void meta_display_reload_cursor (MetaDisplay *display); +void meta_display_update_cursor (MetaDisplay *display); void meta_display_check_threshold_reached (MetaDisplay *display, int x, @@ -401,53 +332,108 @@ void meta_display_ungrab_focus_window_button (MetaDisplay *display, /* Next function is defined in edge-resistance.c */ void meta_display_cleanup_edges (MetaDisplay *display); -/* make a request to ensure the event serial has changed */ -void meta_display_increment_event_serial (MetaDisplay *display); - -void meta_display_update_active_window_hint (MetaDisplay *display); - /* utility goo */ const char* meta_event_mode_to_string (int m); const char* meta_event_detail_to_string (int d); void meta_display_queue_retheme_all_windows (MetaDisplay *display); -void meta_display_retheme_all (void); -void meta_display_set_cursor_theme (const char *theme, - int size); +void meta_display_ping_window (MetaWindow *window, + guint32 serial); +void meta_display_pong_for_serial (MetaDisplay *display, + guint32 serial); -void meta_display_ping_window (MetaDisplay *display, - MetaWindow *window, - guint32 timestamp, - MetaWindowPingFunc ping_reply_func, - MetaWindowPingFunc ping_timeout_func, - void *user_data); -gboolean meta_display_window_has_pending_pings (MetaDisplay *display, - MetaWindow *window); - -int meta_resize_gravity_from_grab_op (MetaGrabOp op); -int meta_resize_gravity_from_tile_mode (MetaTileMode mode); +MetaGravity meta_resize_gravity_from_grab_op (MetaGrabOp op); gboolean meta_grab_op_is_moving (MetaGrabOp op); gboolean meta_grab_op_is_resizing (MetaGrabOp op); - -void meta_display_devirtualize_modifiers (MetaDisplay *display, - MetaVirtualModifier modifiers, - unsigned int *mask); - -void meta_display_increment_focus_sentinel (MetaDisplay *display); -void meta_display_decrement_focus_sentinel (MetaDisplay *display); -gboolean meta_display_focus_sentinel_clear (MetaDisplay *display); +gboolean meta_grab_op_is_mouse (MetaGrabOp op); +gboolean meta_grab_op_is_keyboard (MetaGrabOp op); void meta_display_queue_autoraise_callback (MetaDisplay *display, MetaWindow *window); void meta_display_remove_autoraise_callback (MetaDisplay *display); -/* In above-tab-keycode.c */ -guint meta_display_get_above_tab_keycode (MetaDisplay *display); +void meta_display_overlay_key_activate (MetaDisplay *display); +void meta_display_accelerator_activate (MetaDisplay *display, + guint action, + ClutterKeyEvent *event); +gboolean meta_display_modifiers_accelerator_activate (MetaDisplay *display); + +void meta_display_sync_wayland_input_focus (MetaDisplay *display); +void meta_display_update_focus_window (MetaDisplay *display, + MetaWindow *window); + +void meta_display_sanity_check_timestamps (MetaDisplay *display, + guint32 timestamp); +gboolean meta_display_timestamp_too_old (MetaDisplay *display, + guint32 *timestamp); + +void meta_display_remove_pending_pings_for_window (MetaDisplay *display, + MetaWindow *window); + +MetaGestureTracker * meta_display_get_gesture_tracker (MetaDisplay *display); + +gboolean meta_display_show_restart_message (MetaDisplay *display, + const char *message); +gboolean meta_display_request_restart (MetaDisplay *display); + +gboolean meta_display_show_resize_popup (MetaDisplay *display, + gboolean show, + MetaRectangle *rect, + int display_w, + int display_h); + +void meta_set_is_restart (gboolean whether); + +void meta_display_cancel_touch (MetaDisplay *display); + +gboolean meta_display_windows_are_interactable (MetaDisplay *display); + +void meta_display_show_tablet_mapping_notification (MetaDisplay *display, + ClutterInputDevice *pad, + const gchar *pretty_name); + +void meta_display_notify_pad_group_switch (MetaDisplay *display, + ClutterInputDevice *pad, + const gchar *pretty_name, + guint n_group, + guint n_mode, + guint n_modes); + +void meta_display_foreach_window (MetaDisplay *display, + MetaListWindowsFlags flags, + MetaDisplayWindowFunc func, + gpointer data); + +void meta_display_restacked (MetaDisplay *display); + + +void meta_display_update_tile_preview (MetaDisplay *display, + gboolean delay); +void meta_display_hide_tile_preview (MetaDisplay *display); + +gboolean meta_display_apply_startup_properties (MetaDisplay *display, + MetaWindow *window); + +void meta_display_queue_workarea_recalc (MetaDisplay *display); +void meta_display_queue_check_fullscreen (MetaDisplay *display); + +MetaWindow *meta_display_get_pointer_window (MetaDisplay *display, + MetaWindow *not_this_one); + +MetaWindow *meta_display_get_window_from_id (MetaDisplay *display, + uint64_t window_id); +uint64_t meta_display_generate_window_id (MetaDisplay *display); -void meta_display_notify_restart (MetaDisplay *display); +void meta_display_init_x11 (MetaDisplay *display, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean meta_display_init_x11_finish (MetaDisplay *display, + GAsyncResult *result, + GError **error); -void meta_display_update_sync_state (MetaSyncMethod method); +void meta_display_shutdown_x11 (MetaDisplay *display); #endif diff --git a/src/core/display.c b/src/core/display.c index ce55fddfe..0917f4693 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -1,7 +1,5 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* Muffin X display handler */ - /* * Copyright (C) 2001 Havoc Pennington * Copyright (C) 2002, 2003, 2004 Red Hat, Inc. @@ -19,78 +17,82 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ /** * SECTION:display * @title: MetaDisplay - * @short_description: Handles operations on an X display. + * @short_description: Mutter display representation * - * The display is represented as a MetaDisplay struct. + * The display is represented as a #MetaDisplay struct. */ -#define _XOPEN_SOURCE 600 /* for gethostname() */ - -#include <config.h> -#include <errno.h> -#include "display-private.h" -#include <meta/util.h> -#include <meta/main.h> -#include "screen-private.h" -#include "window-private.h" -#include "window-props.h" -#include "group-props.h" -#include "frame.h" -#include <meta/errors.h> -#include "keybindings-private.h" -#include <meta/prefs.h> -#include "resizepopup.h" -#include "xprops.h" -#include "workspace-private.h" -#include "bell.h" -#include <meta/compositor.h> -#include <X11/Xatom.h> -#include <X11/cursorfont.h> -#include "muffin-enum-types.h" +#include "config.h" -#ifdef HAVE_SOLARIS_XINERAMA -#include <X11/extensions/xinerama.h> -#endif -#ifdef HAVE_XFREE_XINERAMA -#include <X11/extensions/Xinerama.h> -#endif -#ifdef HAVE_RANDR -#include <X11/extensions/Xrandr.h> -#endif -#ifdef HAVE_SHAPE -#include <X11/extensions/shape.h> -#endif -#ifdef HAVE_XKB -#include <X11/XKBlib.h> -#endif -#ifdef HAVE_XCURSOR +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <X11/Xatom.h> #include <X11/Xcursor/Xcursor.h> -#endif -#include <X11/extensions/Xrender.h> +#include <X11/extensions/shape.h> #include <X11/extensions/Xcomposite.h> #include <X11/extensions/Xdamage.h> #include <X11/extensions/Xfixes.h> -#include <string.h> -#include <unistd.h> -#define GRAB_OP_IS_WINDOW_SWITCH(g) \ - (g == META_GRAB_OP_KEYBOARD_TABBING_NORMAL || \ - g == META_GRAB_OP_KEYBOARD_TABBING_DOCK || \ - g == META_GRAB_OP_KEYBOARD_TABBING_GROUP || \ - g == META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL || \ - g == META_GRAB_OP_KEYBOARD_ESCAPING_DOCK || \ - g == META_GRAB_OP_KEYBOARD_ESCAPING_GROUP) +#include "backends/meta-backend-private.h" +#include "backends/meta-cursor-sprite-xcursor.h" +#include "backends/meta-cursor-tracker-private.h" +#include "backends/meta-idle-monitor-dbus.h" +#include "backends/meta-input-device-private.h" +#include "backends/meta-input-settings-private.h" +#include "backends/meta-logical-monitor.h" +#include "backends/meta-stage-private.h" +#include "backends/x11/meta-backend-x11.h" +#include "backends/x11/meta-event-x11.h" +#include "backends/x11/cm/meta-backend-x11-cm.h" +#include "clutter/x11/clutter-x11.h" +#include "compositor/compositor-private.h" +#include "compositor/meta-compositor-x11.h" +#include "cogl/cogl.h" +#include "core/bell.h" +#include "core/boxes-private.h" +#include "core/display-private.h" +#include "core/events.h" +#include "core/frame.h" +#include "core/keybindings-private.h" +#include "core/main-private.h" +#include "core/meta-clipboard-manager.h" +#include "core/meta-workspace-manager-private.h" +#include "core/util-private.h" +#include "core/window-private.h" +#include "core/workspace-private.h" +#include "meta/compositor-mutter.h" +#include "meta/compositor.h" +#include "meta/main.h" +#include "meta/meta-backend.h" +#include "meta/meta-enum-types.h" +#include "meta/meta-sound-player.h" +#include "meta/meta-x11-errors.h" +#include "meta/prefs.h" +#include "x11/meta-startup-notification-x11.h" +#include "x11/meta-x11-display-private.h" +#include "x11/window-x11.h" +#include "x11/xprops.h" + +#ifdef HAVE_WAYLAND +#include "compositor/meta-compositor-server.h" +#include "wayland/meta-xwayland-private.h" +#include "wayland/meta-wayland-tablet-seat.h" +#include "wayland/meta-wayland-tablet-pad.h" +#endif + +#ifdef HAVE_NATIVE_BACKEND +#include "backends/native/meta-backend-native.h" +#endif /* - * \defgroup pings Pings + * SECTION:pings * * Sometimes we want to see whether a window is responding, * so we send it a "ping" message and see whether it sends us back a "pong" @@ -104,52 +106,64 @@ * that we're never going to do so and simplify it a bit. */ -/* +/** + * MetaPingData: + * * Describes a ping on a window. When we send a ping to a window, we build * one of these structs, and it eventually gets passed to the timeout function * or to the function which handles the response from the window. If the window * does or doesn't respond to the ping, we use this information to deal with * these facts; we have a handler function for each. - * - * \ingroup pings */ typedef struct { - MetaDisplay *display; - Window xwindow; - guint32 timestamp; - MetaWindowPingFunc ping_reply_func; - MetaWindowPingFunc ping_timeout_func; - void *user_data; - guint ping_timeout_id; + MetaWindow *window; + guint32 serial; + guint ping_timeout_id; } MetaPingData; -typedef struct -{ - MetaDisplay *display; - Window xwindow; -} MetaAutoRaiseData; - G_DEFINE_TYPE(MetaDisplay, meta_display, G_TYPE_OBJECT); /* Signals */ enum { + CURSOR_UPDATED, + X11_DISPLAY_SETUP, + X11_DISPLAY_OPENED, + X11_DISPLAY_CLOSING, + OVERLAY_KEY, + ACCELERATOR_ACTIVATED, + MODIFIERS_ACCELERATOR_ACTIVATED, FOCUS_WINDOW, WINDOW_CREATED, WINDOW_DEMANDS_ATTENTION, WINDOW_MARKED_URGENT, GRAB_OP_BEGIN, GRAB_OP_END, - ZOOM_SCROLL_IN, - ZOOM_SCROLL_OUT, - BELL, - GL_VIDEO_MEMORY_PURGED, + SHOW_RESTART_MESSAGE, RESTART, + SHOW_RESIZE_POPUP, + GL_VIDEO_MEMORY_PURGED, + SHOW_PAD_OSD, + SHOW_OSD, + PAD_MODE_SWITCH, + WINDOW_ENTERED_MONITOR, + WINDOW_LEFT_MONITOR, + WORKSPACE_ADDED, + WORKSPACE_REMOVED, + WORKSPACE_SWITCHED, + ACTIVE_WORKSPACE_CHANGED, + IN_FULLSCREEN_CHANGED, + SHOWING_DESKTOP_CHANGED, + RESTACKED, + WORKAREAS_CHANGED, + CLOSING, + INIT_XSERVER, LAST_SIGNAL }; -enum { +enum +{ PROP_0, PROP_FOCUS_WINDOW @@ -165,36 +179,14 @@ static guint display_signals [LAST_SIGNAL] = { 0 }; */ static MetaDisplay *the_display = NULL; -#ifdef WITH_VERBOSE_MODE -static void meta_spew_event (MetaDisplay *display, - XEvent *event); -#endif - -static gboolean event_callback (XEvent *event, - gpointer data); -static Window event_get_modified_window (MetaDisplay *display, - XEvent *event); -static guint32 event_get_time (MetaDisplay *display, - XEvent *event); -static void process_request_frame_extents (MetaDisplay *display, - XEvent *event); -static void process_pong_message (MetaDisplay *display, - XEvent *event); -static void process_selection_request (MetaDisplay *display, - XEvent *event); -static void process_selection_clear (MetaDisplay *display, - XEvent *event); - -static void update_window_grab_modifiers (MetaDisplay *display); -static void update_mouse_zoom_modifiers (MetaDisplay *display); +static void on_monitors_changed_internal (MetaMonitorManager *monitor_manager, + MetaDisplay *display); static void prefs_changed_callback (MetaPreference pref, void *data); -static void sanity_check_timestamps (MetaDisplay *display, - guint32 known_good_timestamp); - -static MetaGroup* get_focussed_group (MetaDisplay *display); +static int mru_cmp (gconstpointer a, + gconstpointer b); static void meta_display_get_property(GObject *object, @@ -237,6 +229,73 @@ meta_display_class_init (MetaDisplayClass *klass) object_class->get_property = meta_display_get_property; object_class->set_property = meta_display_set_property; + display_signals[CURSOR_UPDATED] = + g_signal_new ("cursor-updated", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); + + display_signals[X11_DISPLAY_SETUP] = + g_signal_new ("x11-display-setup", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); + + display_signals[X11_DISPLAY_OPENED] = + g_signal_new ("x11-display-opened", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); + + display_signals[X11_DISPLAY_CLOSING] = + g_signal_new ("x11-display-closing", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); + + display_signals[OVERLAY_KEY] = + g_signal_new ("overlay-key", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); + + display_signals[ACCELERATOR_ACTIVATED] = + g_signal_new ("accelerator-activated", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 3, G_TYPE_UINT, CLUTTER_TYPE_INPUT_DEVICE, G_TYPE_UINT); + + /** + * MetaDisplay::modifiers-accelerator-activated: + * @display: the #MetaDisplay instance + * + * The ::modifiers-accelerator-activated signal will be emitted when + * a special modifiers-only keybinding is activated. + * + * Returns: %TRUE means that the keyboard device should remain + * frozen and %FALSE for the default behavior of unfreezing the + * keyboard. + */ + display_signals[MODIFIERS_ACCELERATOR_ACTIVATED] = + g_signal_new ("modifiers-accelerator-activated", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + g_signal_accumulator_first_wins, NULL, NULL, + G_TYPE_BOOLEAN, 0); + display_signals[WINDOW_CREATED] = g_signal_new ("window-created", G_TYPE_FROM_CLASS (klass), @@ -269,7 +328,7 @@ meta_display_class_init (MetaDisplayClass *klass) 0, NULL, NULL, NULL, G_TYPE_NONE, 3, - META_TYPE_SCREEN, + META_TYPE_DISPLAY, META_TYPE_WINDOW, META_TYPE_GRAB_OP); @@ -280,33 +339,72 @@ meta_display_class_init (MetaDisplayClass *klass) 0, NULL, NULL, NULL, G_TYPE_NONE, 3, - META_TYPE_SCREEN, + META_TYPE_DISPLAY, META_TYPE_WINDOW, META_TYPE_GRAB_OP); - display_signals[ZOOM_SCROLL_IN] = - g_signal_new ("zoom-scroll-in", + /** + * MetaDisplay::show-restart-message: + * @display: the #MetaDisplay instance + * @message: (allow-none): The message to display, or %NULL + * to clear a previous restart message. + * + * The ::show-restart-message signal will be emitted to indicate + * that the compositor should show a message during restart. This is + * emitted when meta_restart() is called, either by Mutter + * internally or by the embedding compositor. The message should be + * immediately added to the Clutter stage in its final form - + * ::restart will be emitted to exit the application and leave the + * stage contents frozen as soon as the the stage is painted again. + * + * On case of failure to restart, this signal will be emitted again + * with %NULL for @message. + * + * Returns: %TRUE means the message was added to the stage; %FALSE + * indicates that the compositor did not show the message. + */ + display_signals[SHOW_RESTART_MESSAGE] = + g_signal_new ("show-restart-message", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, - NULL, NULL, NULL, - G_TYPE_NONE, 0); + g_signal_accumulator_true_handled, + NULL, NULL, + G_TYPE_BOOLEAN, 1, + G_TYPE_STRING); - display_signals[ZOOM_SCROLL_OUT] = - g_signal_new ("zoom-scroll-out", + /** + * MetaDisplay::restart: + * @display: the #MetaDisplay instance + * + * The ::restart signal is emitted to indicate that compositor + * should reexec the process. This is + * emitted when meta_restart() is called, either by Mutter + * internally or by the embedding compositor. See also + * ::show-restart-message. + * + * Returns: %FALSE to indicate that the compositor could not + * be restarted. When the compositor is restarted, the signal + * should not return. + */ + display_signals[RESTART] = + g_signal_new ("restart", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, - NULL, NULL, NULL, - G_TYPE_NONE, 0); + g_signal_accumulator_true_handled, + NULL, NULL, + G_TYPE_BOOLEAN, 0); - display_signals[BELL] = - g_signal_new ("bell", + display_signals[SHOW_RESIZE_POPUP] = + g_signal_new ("show-resize-popup", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, - NULL, NULL, NULL, - G_TYPE_NONE, 1, META_TYPE_WINDOW); + g_signal_accumulator_true_handled, + NULL, NULL, + G_TYPE_BOOLEAN, 4, + G_TYPE_BOOLEAN, META_TYPE_RECTANGLE, G_TYPE_INT, G_TYPE_INT); display_signals[GL_VIDEO_MEMORY_PURGED] = g_signal_new ("gl-video-memory-purged", @@ -317,20 +415,102 @@ meta_display_class_init (MetaDisplayClass *klass) G_TYPE_NONE, 0); /** - * MetaDisplay::restart: + * MetaDisplay::show-pad-osd: * @display: the #MetaDisplay instance + * @pad: the pad device + * @settings: the pad device settings + * @layout_path: path to the layout image + * @edition_mode: Whether the OSD should be shown in edition mode + * @monitor_idx: Monitor to show the OSD on * - * The ::restart signal is emitted to indicate that Muffin - * will restart the process. + * Requests the pad button mapping OSD to be shown. + * + * Returns: (transfer none) (nullable): The OSD actor */ - display_signals[RESTART] = - g_signal_new ("restart", + display_signals[SHOW_PAD_OSD] = + g_signal_new ("show-pad-osd", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + CLUTTER_TYPE_ACTOR, 5, CLUTTER_TYPE_INPUT_DEVICE, + G_TYPE_SETTINGS, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_INT); + + display_signals[SHOW_OSD] = + g_signal_new ("show-osd", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 3, G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING); + + display_signals[PAD_MODE_SWITCH] = + g_signal_new ("pad-mode-switch", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 3, CLUTTER_TYPE_INPUT_DEVICE, + G_TYPE_UINT, G_TYPE_UINT); + + display_signals[WINDOW_ENTERED_MONITOR] = + g_signal_new ("window-entered-monitor", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 2, + G_TYPE_INT, + META_TYPE_WINDOW); + + display_signals[WINDOW_LEFT_MONITOR] = + g_signal_new ("window-left-monitor", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 2, + G_TYPE_INT, + META_TYPE_WINDOW); + + display_signals[IN_FULLSCREEN_CHANGED] = + g_signal_new ("in-fullscreen-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 0); + + display_signals[SHOWING_DESKTOP_CHANGED] = + g_signal_new ("showing-desktop-changed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); + display_signals[RESTACKED] = + g_signal_new ("restacked", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 0); + + display_signals[WORKAREAS_CHANGED] = + g_signal_new ("workareas-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 0); + display_signals[CLOSING] = + g_signal_new ("closing", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 0); + + display_signals[INIT_XSERVER] = + g_signal_new ("init-xserver", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, g_signal_accumulator_first_wins, + NULL, NULL, + G_TYPE_BOOLEAN, 1, G_TYPE_TASK); + g_object_class_install_property (object_class, PROP_FOCUS_WINDOW, g_param_spec_object ("focus-window", @@ -338,39 +518,28 @@ meta_display_class_init (MetaDisplayClass *klass) "Currently focused window", META_TYPE_WINDOW, G_PARAM_READABLE)); + } -/* - * Destructor for MetaPingData structs. Will destroy the - * event source for the struct as well. +/** + * ping_data_free: * - * \ingroup pings + * Destructor for #MetaPingData structs. Will destroy the + * event source for the struct as well. */ static void ping_data_free (MetaPingData *ping_data) { /* Remove the timeout */ - if (ping_data->ping_timeout_id != 0) { - g_source_remove (ping_data->ping_timeout_id); - ping_data->ping_timeout_id = 0; - } + g_clear_handle_id (&ping_data->ping_timeout_id, g_source_remove); - free (ping_data); + g_free (ping_data); } -/* - * Frees every pending ping structure for the given X window on the - * given display. This means that we also destroy the timeouts. - * - * \param display The display the window appears on - * \param xwindow The X ID of the window whose pings we should remove - * - * \ingroup pings - * - */ -static void -remove_pending_pings_for_window (MetaDisplay *display, Window xwindow) +void +meta_display_remove_pending_pings_for_window (MetaDisplay *display, + MetaWindow *window) { GSList *tmp; GSList *dead; @@ -383,7 +552,7 @@ remove_pending_pings_for_window (MetaDisplay *display, Window xwindow) { MetaPingData *ping_data = tmp->data; - if (ping_data->xwindow == xwindow) + if (ping_data->window == window) dead = g_slist_prepend (dead, ping_data); } @@ -399,63 +568,48 @@ remove_pending_pings_for_window (MetaDisplay *display, Window xwindow) g_slist_free (dead); } - -#ifdef HAVE_STARTUP_NOTIFICATION -static void -sn_error_trap_push (SnDisplay *sn_display, - Display *xdisplay) -{ - MetaDisplay *display; - display = meta_display_for_x_display (xdisplay); - if (display != NULL) - meta_error_trap_push (display); -} - -static void -sn_error_trap_pop (SnDisplay *sn_display, - Display *xdisplay) +static MetaCompositor * +create_compositor (MetaDisplay *display) { - MetaDisplay *display; - display = meta_display_for_x_display (xdisplay); - if (display != NULL) - meta_error_trap_pop (display); -} +#ifdef HAVE_WAYLAND + if (meta_is_wayland_compositor ()) + return META_COMPOSITOR (meta_compositor_server_new (display)); + else #endif + return META_COMPOSITOR (meta_compositor_x11_new (display)); +} static void -enable_compositor (MetaDisplay *display, - gboolean composite_windows) +enable_compositor (MetaDisplay *display) { - GSList *list; + MetaX11Display *x11_display = display->x11_display; - if (!META_DISPLAY_HAS_COMPOSITE (display) || - !META_DISPLAY_HAS_DAMAGE (display) || - !META_DISPLAY_HAS_XFIXES (display) || - !META_DISPLAY_HAS_RENDER (display)) + if (x11_display) { - meta_warning ("Missing %s extension required for compositing", - !META_DISPLAY_HAS_COMPOSITE (display) ? "composite" : - !META_DISPLAY_HAS_DAMAGE (display) ? "damage" : - !META_DISPLAY_HAS_XFIXES (display) ? "xfixes" : "render"); - return; - } + if (!META_X11_DISPLAY_HAS_COMPOSITE (x11_display) || + !META_X11_DISPLAY_HAS_DAMAGE (x11_display)) + { + meta_fatal ("Missing %s extension required for compositing", + !META_X11_DISPLAY_HAS_COMPOSITE (x11_display) ? + "composite" : "damage"); + return; + } - if (!display->compositor) - display->compositor = meta_compositor_new (display); + int version = (x11_display->composite_major_version * 10) + + x11_display->composite_minor_version; + if (version < 3) + { + meta_fatal ("Your version of COMPOSITE (%d.%d) is too old. Version 3.0 or later required.", + x11_display->composite_major_version, + x11_display->composite_minor_version); + return; + } + } if (!display->compositor) - return; + display->compositor = create_compositor (display); - for (list = display->screens; list != NULL; list = list->next) - { - MetaScreen *screen = list->data; - - meta_compositor_manage_screen (screen->display->compositor, - screen); - - if (composite_windows) - meta_screen_composite_all_windows (screen); - } + meta_compositor_manage (display->compositor); } static void @@ -465,486 +619,358 @@ meta_display_init (MetaDisplay *disp) * but it doesn't really matter. */ } -/* - * Opens a new display, sets it up, initialises all the X extensions - * we will need, and adds it to the list of displays. - * - * \return True if the display was opened successfully, and False - * otherwise-- that is, if the display doesn't exist or it already - * has a window manager. - * - * \ingroup main - */ -LOCAL_SYMBOL gboolean -meta_display_open (void) +void +meta_display_cancel_touch (MetaDisplay *display) { - Display *xdisplay; - GSList *screens; - GSList *tmp; - int i; - guint32 timestamp; - Window old_active_xwindow = None; - char buf[257]; +#ifdef HAVE_WAYLAND + MetaWaylandCompositor *compositor; - /* A list of all atom names, so that we can intern them in one go. */ - char *atom_names[] = { -#define item(x) #x, -#include <meta/atomnames.h> -#undef item - }; - Atom atoms[G_N_ELEMENTS(atom_names)]; - - meta_verbose ("Opening display '%s'\n", XDisplayName (NULL)); + if (!meta_is_wayland_compositor ()) + return; - xdisplay = meta_ui_get_display (); + compositor = meta_wayland_compositor_get_default (); + meta_wayland_touch_cancel (compositor->seat->touch); +#endif +} - if (xdisplay == NULL) +static void +gesture_tracker_state_changed (MetaGestureTracker *tracker, + ClutterEventSequence *sequence, + MetaSequenceState state, + MetaDisplay *display) +{ + switch (state) { - meta_warning ("Failed to open X Window System display '%s'\n", - XDisplayName (NULL)); - return FALSE; - } + case META_SEQUENCE_NONE: + case META_SEQUENCE_PENDING_END: + return; + case META_SEQUENCE_ACCEPTED: + meta_display_cancel_touch (display); - if (meta_is_syncing ()) - XSynchronize (xdisplay, True); + G_GNUC_FALLTHROUGH; + case META_SEQUENCE_REJECTED: + { + MetaBackend *backend; - g_assert (the_display == NULL); - the_display = g_object_new (META_TYPE_DISPLAY, NULL); + backend = meta_get_backend (); + meta_backend_finish_touch_sequence (backend, sequence, state); + break; + } + } +} - the_display->closing = 0; +static void +on_ui_scaling_factor_changed (MetaSettings *settings, + MetaDisplay *display) +{ + meta_display_reload_cursor (display); +} - /* here we use XDisplayName which is what the user - * probably put in, vs. DisplayString(display) which is - * canonicalized by XOpenDisplay() - */ - the_display->name = g_strdup (XDisplayName (NULL)); - the_display->xdisplay = xdisplay; - the_display->gdk_display = gdk_display_get_default(); - the_display->gdk_device = gdk_seat_get_pointer (gdk_display_get_default_seat (the_display->gdk_display)); +static gboolean +meta_display_init_x11_display (MetaDisplay *display, + GError **error) +{ + MetaX11Display *x11_display; - if (gethostname (buf, sizeof(buf)-1) == 0) - { - buf[sizeof(buf)-1] = '\0'; - the_display->hostname = g_strdup (buf); - } - else - the_display->hostname = NULL; - the_display->error_trap_synced_at_last_pop = TRUE; - the_display->error_traps = 0; - the_display->error_trap_handler = NULL; - the_display->server_grab_count = 0; - the_display->display_opening = TRUE; - - the_display->pending_pings = NULL; - the_display->autoraise_timeout_id = 0; - the_display->autoraise_window = NULL; - the_display->focus_window = NULL; - the_display->expected_focus_window = NULL; - the_display->grab_old_window_stacking = NULL; - - the_display->mouse_mode = TRUE; /* Only relevant for mouse or sloppy focus */ - the_display->allow_terminal_deactivation = TRUE; /* Only relevant for when a - terminal has the focus */ + x11_display = meta_x11_display_new (display, error); + if (!x11_display) + return FALSE; - the_display->rebuild_keybinding_idle_id = 0; + display->x11_display = x11_display; + g_signal_emit (display, display_signals[X11_DISPLAY_SETUP], 0); - the_display->sync_method = meta_prefs_get_sync_method(); + meta_x11_display_create_guard_window (x11_display); - /* FIXME copy the checks from GDK probably */ - the_display->static_gravity_works = g_getenv ("MUFFIN_USE_STATIC_GRAVITY") != NULL; + if (!display->display_opening) + { + g_signal_emit (display, display_signals[X11_DISPLAY_OPENED], 0); + meta_display_manage_all_xwindows (display); + meta_compositor_redirect_x11_windows (display->compositor); + } - meta_bell_init (the_display); + return TRUE; +} - meta_display_init_keys (the_display); +#ifdef HAVE_WAYLAND +gboolean +meta_display_init_x11_finish (MetaDisplay *display, + GAsyncResult *result, + GError **error) +{ + MetaX11Display *x11_display; - update_window_grab_modifiers (the_display); - update_mouse_zoom_modifiers (the_display); - the_display->mouse_zoom_enabled = meta_prefs_get_mouse_zoom_enabled (); + g_assert (g_task_get_source_tag (G_TASK (result)) == meta_display_init_x11); - meta_prefs_add_listener (prefs_changed_callback, the_display); + if (!g_task_propagate_boolean (G_TASK (result), error)) + { + if (*error == NULL) + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unknown error"); - meta_verbose ("Creating %d atoms\n", (int) G_N_ELEMENTS (atom_names)); - XInternAtoms (the_display->xdisplay, atom_names, G_N_ELEMENTS (atom_names), - False, atoms); - { - int i = 0; -#define item(x) the_display->atom_##x = atoms[i++]; -#include <meta/atomnames.h> -#undef item - } + return FALSE; + } - the_display->prop_hooks = NULL; - meta_display_init_window_prop_hooks (the_display); - the_display->group_prop_hooks = NULL; - meta_display_init_group_prop_hooks (the_display); + if (display->x11_display) + return TRUE; - /* Offscreen unmapped window used for _NET_SUPPORTING_WM_CHECK, - * created in screen_new - */ - the_display->leader_window = None; - the_display->timestamp_pinging_window = None; + x11_display = meta_x11_display_new (display, error); + if (!x11_display) + return FALSE; - the_display->monitor_cache_invalidated = TRUE; + display->x11_display = x11_display; + g_signal_emit (display, display_signals[X11_DISPLAY_SETUP], 0); - the_display->groups_by_leader = NULL; + meta_x11_display_create_guard_window (x11_display); - the_display->window_with_menu = NULL; - the_display->window_menu = NULL; + if (!display->display_opening) + { + g_signal_emit (display, display_signals[X11_DISPLAY_OPENED], 0); + meta_x11_display_set_cm_selection (x11_display); + meta_display_manage_all_xwindows (display); + meta_compositor_redirect_x11_windows (display->compositor); + } - the_display->screens = NULL; - the_display->active_screen = NULL; + return TRUE; +} -#ifdef HAVE_STARTUP_NOTIFICATION - the_display->sn_display = sn_display_new (the_display->xdisplay, - sn_error_trap_push, - sn_error_trap_pop); -#endif +static void +on_xserver_started (MetaXWaylandManager *manager, + GAsyncResult *result, + gpointer user_data) +{ + g_autoptr (GTask) task = user_data; + MetaDisplay *display = g_task_get_source_object (task); + GError *error = NULL; + gboolean retval = FALSE; - the_display->events = NULL; + if (!meta_xwayland_start_xserver_finish (manager, result, &error)) + { + if (error) + g_task_return_error (task, error); + else + g_task_return_boolean (task, FALSE); - /* Get events */ - meta_ui_add_event_func (the_display->xdisplay, - event_callback, - the_display); + return; + } - the_display->window_ids = g_hash_table_new (meta_unsigned_long_hash, - meta_unsigned_long_equal); + g_signal_emit (display, display_signals[INIT_XSERVER], 0, task, &retval); - i = 0; - while (i < N_IGNORED_CROSSING_SERIALS) + if (!retval) { - the_display->ignored_crossing_serials[i] = 0; - ++i; + /* No handlers for this signal, proceed right away */ + g_task_return_boolean (task, TRUE); } - the_display->ungrab_should_not_cause_focus_window = None; +} - the_display->current_time = CurrentTime; - the_display->sentinel_counter = 0; +void +meta_display_init_x11 (MetaDisplay *display, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); - the_display->grab_resize_timeout_id = 0; - the_display->grab_have_keyboard = FALSE; + g_autoptr (GTask) task = NULL; -#ifdef HAVE_XKB - the_display->last_bell_time = 0; -#endif + task = g_task_new (display, cancellable, callback, user_data); + g_task_set_source_tag (task, meta_display_init_x11); - the_display->grab_op = META_GRAB_OP_NONE; - the_display->grab_window = NULL; - the_display->grab_screen = NULL; - the_display->grab_resize_popup = NULL; - the_display->grab_tile_mode = META_TILE_NONE; - the_display->grab_tile_monitor_number = -1; + meta_xwayland_start_xserver (&compositor->xwayland_manager, + cancellable, + (GAsyncReadyCallback) on_xserver_started, + g_steal_pointer (&task)); +} - the_display->grab_edge_resistance_data = NULL; +static void +on_x11_initialized (MetaDisplay *display, + GAsyncResult *result, + gpointer user_data) +{ + g_autoptr (GError) error = NULL; -#ifdef HAVE_XSYNC - { - int major, minor; + if (!meta_display_init_x11_finish (display, result, &error)) + g_critical ("Failed to init X11 display: %s", error->message); +} +#endif - the_display->have_xsync = FALSE; +void +meta_display_shutdown_x11 (MetaDisplay *display) +{ + if (!display->x11_display) + return; - the_display->xsync_error_base = 0; - the_display->xsync_event_base = 0; - - /* I don't think we really have to fill these in */ - major = SYNC_MAJOR_VERSION; - minor = SYNC_MINOR_VERSION; + g_signal_emit (display, display_signals[X11_DISPLAY_CLOSING], 0); + g_object_run_dispose (G_OBJECT (display->x11_display)); + g_clear_object (&display->x11_display); +} - if (!XSyncQueryExtension (the_display->xdisplay, - &the_display->xsync_event_base, - &the_display->xsync_error_base) || - !XSyncInitialize (the_display->xdisplay, - &major, &minor)) - { - the_display->xsync_error_base = 0; - the_display->xsync_event_base = 0; - } - else - { - the_display->have_xsync = TRUE; - XSyncSetPriority (the_display->xdisplay, None, 10); - } +/** + * meta_display_open: + * + * Opens a new display, sets it up, initialises all the X extensions + * we will need, and adds it to the list of displays. + * + * Returns: %TRUE if the display was opened successfully, and %FALSE + * otherwise-- that is, if the display doesn't exist or it already + * has a window manager. + */ +gboolean +meta_display_open (void) +{ + GError *error = NULL; + MetaDisplay *display; + int i; + guint32 timestamp; + Window old_active_xwindow = None; + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager; + MetaSettings *settings; - meta_verbose ("Attempted to init Xsync, found version %d.%d error base %d event base %d\n", - major, minor, - the_display->xsync_error_base, - the_display->xsync_event_base); - } -#else /* HAVE_XSYNC */ - meta_verbose ("Not compiled with Xsync support\n"); -#endif /* !HAVE_XSYNC */ + g_assert (the_display == NULL); + display = the_display = g_object_new (META_TYPE_DISPLAY, NULL); + display->closing = 0; + display->display_opening = TRUE; -#ifdef HAVE_SHAPE - { - the_display->have_shape = FALSE; + display->pending_pings = NULL; + display->autoraise_timeout_id = 0; + display->autoraise_window = NULL; + display->focus_window = NULL; + display->workspace_manager = NULL; + display->x11_display = NULL; - the_display->shape_error_base = 0; - the_display->shape_event_base = 0; + display->current_cursor = -1; /* invalid/unset */ + display->tile_preview_timeout_id = 0; + display->check_fullscreen_later = 0; + display->work_area_later = 0; - if (!XShapeQueryExtension (the_display->xdisplay, - &the_display->shape_event_base, - &the_display->shape_error_base)) - { - the_display->shape_error_base = 0; - the_display->shape_event_base = 0; - } - else - the_display->have_shape = TRUE; - - meta_verbose ("Attempted to init Shape, found error base %d event base %d\n", - the_display->shape_error_base, - the_display->shape_event_base); - } -#else /* HAVE_SHAPE */ - meta_verbose ("Not compiled with Shape support\n"); -#endif /* !HAVE_SHAPE */ - - { - the_display->have_render = FALSE; - - the_display->render_error_base = 0; - the_display->render_event_base = 0; - - if (!XRenderQueryExtension (the_display->xdisplay, - &the_display->render_event_base, - &the_display->render_error_base)) - { - the_display->render_error_base = 0; - the_display->render_event_base = 0; - } - else - the_display->have_render = TRUE; + display->mouse_mode = TRUE; /* Only relevant for mouse or sloppy focus */ + display->allow_terminal_deactivation = TRUE; /* Only relevant for when a + terminal has the focus */ - meta_verbose ("Attempted to init Render, found error base %d event base %d\n", - the_display->render_error_base, - the_display->render_event_base); - } + i = 0; + while (i < N_IGNORED_CROSSING_SERIALS) + { + display->ignored_crossing_serials[i] = 0; + ++i; + } - { - the_display->have_composite = FALSE; + display->current_time = META_CURRENT_TIME; - the_display->composite_error_base = 0; - the_display->composite_event_base = 0; + display->grab_resize_timeout_id = 0; + display->grab_have_keyboard = FALSE; - if (!XCompositeQueryExtension (the_display->xdisplay, - &the_display->composite_event_base, - &the_display->composite_error_base)) - { - the_display->composite_error_base = 0; - the_display->composite_event_base = 0; - } - else - { - the_display->composite_major_version = 0; - the_display->composite_minor_version = 0; - if (XCompositeQueryVersion (the_display->xdisplay, - &the_display->composite_major_version, - &the_display->composite_minor_version)) - { - the_display->have_composite = TRUE; - } - else - { - the_display->composite_major_version = 0; - the_display->composite_minor_version = 0; - } - } + display->grab_op = META_GRAB_OP_NONE; + display->grab_window = NULL; + display->grab_tile_mode = META_TILE_NONE; + display->grab_tile_monitor_number = -1; - meta_verbose ("Attempted to init Composite, found error base %d event base %d " - "extn ver %d %d\n", - the_display->composite_error_base, - the_display->composite_event_base, - the_display->composite_major_version, - the_display->composite_minor_version); + meta_display_cleanup_edges (display); - the_display->have_damage = FALSE; + meta_display_init_keys (display); - the_display->damage_error_base = 0; - the_display->damage_event_base = 0; + meta_prefs_add_listener (prefs_changed_callback, display); - if (!XDamageQueryExtension (the_display->xdisplay, - &the_display->damage_event_base, - &the_display->damage_error_base)) - { - the_display->damage_error_base = 0; - the_display->damage_event_base = 0; - } - else - the_display->have_damage = TRUE; + /* Get events */ + meta_display_init_events (display); - meta_verbose ("Attempted to init Damage, found error base %d event base %d\n", - the_display->damage_error_base, - the_display->damage_event_base); + display->stamps = g_hash_table_new (g_int64_hash, + g_int64_equal); + display->wayland_windows = g_hash_table_new (NULL, NULL); - the_display->have_xfixes = FALSE; + monitor_manager = meta_backend_get_monitor_manager (backend); + g_signal_connect (monitor_manager, "monitors-changed-internal", + G_CALLBACK (on_monitors_changed_internal), display); - the_display->xfixes_error_base = 0; - the_display->xfixes_event_base = 0; + settings = meta_backend_get_settings (backend); + g_signal_connect (settings, "ui-scaling-factor-changed", + G_CALLBACK (on_ui_scaling_factor_changed), display); - if (!XFixesQueryExtension (the_display->xdisplay, - &the_display->xfixes_event_base, - &the_display->xfixes_error_base)) - { - the_display->xfixes_error_base = 0; - the_display->xfixes_event_base = 0; - } - else - the_display->have_xfixes = TRUE; - - meta_verbose ("Attempted to init XFixes, found error base %d event base %d\n", - the_display->xfixes_error_base, - the_display->xfixes_event_base); - } - -#ifdef HAVE_XCURSOR - { - XcursorSetTheme (the_display->xdisplay, meta_prefs_get_cursor_theme ()); - XcursorSetDefaultSize (the_display->xdisplay, meta_prefs_get_cursor_size ()); - } -#else /* HAVE_XCURSOR */ - meta_verbose ("Not compiled with Xcursor support\n"); -#endif /* !HAVE_XCURSOR */ - - /* Create the leader window here. Set its properties and - * use the timestamp from one of the PropertyNotify events - * that will follow. - */ - { - gulong data[1]; - XEvent event; - - /* We only care about the PropertyChangeMask in the next 30 or so lines of - * code. Note that gdk will at some point unset the PropertyChangeMask for - * this window, so we can't rely on it still being set later. See bug - * 354213 for details. - */ - the_display->leader_window = - meta_create_offscreen_window (the_display->xdisplay, - DefaultRootWindow (the_display->xdisplay), - PropertyChangeMask); - - meta_prop_set_utf8_string_hint (the_display, - the_display->leader_window, - the_display->atom__NET_WM_NAME, - "Mutter (Muffin)"); - - /* The GNOME keybindings capplet should include both the Muffin and Metacity - * keybindings */ - meta_prop_set_utf8_string_hint (the_display, - the_display->leader_window, - the_display->atom__GNOME_WM_KEYBINDINGS, - "Muffin,Metacity"); - - meta_prop_set_utf8_string_hint (the_display, - the_display->leader_window, - the_display->atom__MUFFIN_VERSION, - VERSION); - - data[0] = the_display->leader_window; - XChangeProperty (the_display->xdisplay, - the_display->leader_window, - the_display->atom__NET_SUPPORTING_WM_CHECK, - XA_WINDOW, - 32, PropModeReplace, (guchar*) data, 1); - - XWindowEvent (the_display->xdisplay, - the_display->leader_window, - PropertyChangeMask, - &event); - - timestamp = event.xproperty.time; - - /* Make it painfully clear that we can't rely on PropertyNotify events on - * this window, as per bug 354213. - */ - XSelectInput(the_display->xdisplay, - the_display->leader_window, - NoEventMask); - } - - /* Make a little window used only for pinging the server for timestamps; note - * that meta_create_offscreen_window already selects for PropertyChangeMask. - */ - the_display->timestamp_pinging_window = - meta_create_offscreen_window (the_display->xdisplay, - DefaultRootWindow (the_display->xdisplay), - PropertyChangeMask); + meta_display_set_cursor (display, META_CURSOR_DEFAULT); - the_display->last_focus_time = timestamp; - the_display->last_user_time = timestamp; - the_display->compositor = NULL; - the_display->shadows_enabled = g_getenv ("MUFFIN_NO_SHADOWS") == NULL; - the_display->debug_button_grabs = g_getenv ("MUFFIN_DEBUG_BUTTON_GRABS") != NULL; + display->stack = meta_stack_new (display); + display->stack_tracker = meta_stack_tracker_new (display); - screens = NULL; + display->workspace_manager = meta_workspace_manager_new (display); - i = 0; - while (i < ScreenCount (xdisplay)) - { - MetaScreen *screen; + display->startup_notification = meta_startup_notification_new (display); - screen = meta_screen_new (the_display, i, timestamp); + display->bell = meta_bell_new (display); - if (screen) - screens = g_slist_prepend (screens, screen); - ++i; - } + display->selection = meta_selection_new (display); + meta_clipboard_manager_init (display); - the_display->screens = screens; +#ifdef HAVE_WAYLAND + if (meta_is_wayland_compositor ()) + { + if (meta_get_x11_display_policy () == META_DISPLAY_POLICY_MANDATORY) + { + meta_display_init_x11 (display, NULL, + (GAsyncReadyCallback) on_x11_initialized, + NULL); + } - if (screens == NULL) + timestamp = meta_display_get_current_time_roundtrip (display); + } + else +#endif { - /* This would typically happen because all the screens already - * have window managers. - */ - meta_display_close (the_display, timestamp); - return FALSE; + if (!meta_display_init_x11_display (display, &error)) + g_error ("Failed to init X11 display: %s", error->message); + + timestamp = display->x11_display->timestamp; } - meta_prop_get_window (the_display, ((MetaScreen*) the_display->screens->data)->xroot, - the_display->atom__NET_ACTIVE_WINDOW, - &old_active_xwindow); + display->last_focus_time = timestamp; + display->last_user_time = timestamp; + display->compositor = NULL; - /* We don't composite the windows here because they will be composited - faster with the call to meta_screen_manage_all_windows further down - the code */ - enable_compositor (the_display, FALSE); + if (!meta_is_wayland_compositor ()) + meta_prop_get_window (display->x11_display, + display->x11_display->xroot, + display->x11_display->atom__NET_ACTIVE_WINDOW, + &old_active_xwindow); - meta_display_grab (the_display); + enable_compositor (display); - /* Now manage all existing windows */ - tmp = the_display->screens; - while (tmp != NULL) + if (display->x11_display) { - MetaScreen *screen = tmp->data; - - meta_screen_manage_all_windows (screen); - - tmp = tmp->next; + g_signal_emit (display, display_signals[X11_DISPLAY_OPENED], 0); + meta_x11_display_restore_active_workspace (display->x11_display); + meta_x11_display_create_guard_window (display->x11_display); } - { - meta_error_trap_push (the_display); + /* Set up touch support */ + display->gesture_tracker = meta_gesture_tracker_new (); + g_signal_connect (display->gesture_tracker, "state-changed", + G_CALLBACK (gesture_tracker_state_changed), display); - if (old_active_xwindow != None) - { - MetaWindow *old_active_window = meta_display_lookup_x_window (the_display, old_active_xwindow); - if (old_active_window) - meta_display_set_input_focus_window (the_display, old_active_window, FALSE, timestamp); - else - meta_display_focus_the_no_focus_window (the_display, the_display->screens->data, timestamp); - } - else - meta_display_focus_the_no_focus_window (the_display, the_display->screens->data, timestamp); + /* We know that if mutter is running as a Wayland compositor, + * we start out with no windows. + */ + if (!meta_is_wayland_compositor ()) + meta_display_manage_all_xwindows (display); + + if (old_active_xwindow != None) + { + MetaWindow *old_active_window; + old_active_window = meta_x11_display_lookup_x_window (display->x11_display, + old_active_xwindow); + if (old_active_window) + meta_window_focus (old_active_window, timestamp); + else + meta_display_unset_input_focus (display, timestamp); + } + else + { + meta_display_unset_input_focus (display, timestamp); + } - meta_error_trap_pop (the_display); - } + meta_idle_monitor_init_dbus (); - meta_display_ungrab (the_display); + display->sound_player = g_object_new (META_TYPE_SOUND_PLAYER, NULL); /* Done opening new display */ - the_display->display_opening = FALSE; + display->display_opening = FALSE; return TRUE; } @@ -969,25 +995,44 @@ ptrcmp (gconstpointer a, gconstpointer b) * now determines whether override-redirect windows will be * included. * - * Return value: (transfer container) (element-type MetaWindow): the list of windows. + * Return value: (transfer container): the list of windows. */ GSList* meta_display_list_windows (MetaDisplay *display, MetaListWindowsFlags flags) { GSList *winlist; - GSList *tmp; GSList *prev; + GSList *tmp; GHashTableIter iter; gpointer key, value; winlist = NULL; - g_hash_table_iter_init (&iter, display->window_ids); + if (display->x11_display) + { + g_hash_table_iter_init (&iter, display->x11_display->xids); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + MetaWindow *window = value; + + if (!META_IS_WINDOW (window) || window->unmanaging) + continue; + + if (!window->override_redirect || + (flags & META_LIST_INCLUDE_OVERRIDE_REDIRECT) != 0) + winlist = g_slist_prepend (winlist, window); + } + } + + g_hash_table_iter_init (&iter, display->wayland_windows); while (g_hash_table_iter_next (&iter, &key, &value)) { MetaWindow *window = value; + if (!META_IS_WINDOW (window) || window->unmanaging) + continue; + if (!window->override_redirect || (flags & META_LIST_INCLUDE_OVERRIDE_REDIRECT) != 0) winlist = g_slist_prepend (winlist, window); @@ -1029,16 +1074,18 @@ meta_display_list_windows (MetaDisplay *display, tmp = next; } + if (flags & META_LIST_SORTED) + winlist = g_slist_sort (winlist, mru_cmp); + return winlist; } -LOCAL_SYMBOL void +void meta_display_close (MetaDisplay *display, guint32 timestamp) { - GSList *tmp; - g_assert (display != NULL); + g_assert (display == the_display); if (display->closing != 0) { @@ -1046,63 +1093,54 @@ meta_display_close (MetaDisplay *display, return; } - if (display->error_traps > 0) - meta_bug ("Display closed with error traps pending\n"); - display->closing += 1; + g_signal_emit (display, display_signals[CLOSING], 0); + + meta_compositor_unmanage (display->compositor); + + meta_display_unmanage_windows (display, timestamp); + meta_prefs_remove_listener (prefs_changed_callback, display); meta_display_remove_autoraise_callback (display); - if (display->grab_old_window_stacking) - g_list_free (display->grab_old_window_stacking); + g_clear_object (&display->gesture_tracker); + + g_clear_handle_id (&display->focus_timeout_id, g_source_remove); + g_clear_handle_id (&display->tile_preview_timeout_id, g_source_remove); + + if (display->work_area_later != 0) + meta_later_remove (display->work_area_later); + if (display->check_fullscreen_later != 0) + meta_later_remove (display->check_fullscreen_later); /* Stop caring about events */ - meta_ui_remove_event_func (display->xdisplay, - event_callback, - display); + meta_display_free_events (display); - /* Free all screens */ - tmp = display->screens; - while (tmp != NULL) - { - MetaScreen *screen = tmp->data; - meta_screen_free (screen, timestamp); - tmp = tmp->next; - } + g_clear_pointer (&display->compositor, meta_compositor_destroy); - g_slist_free (display->screens); - display->screens = NULL; + meta_display_shutdown_x11 (display); -#ifdef HAVE_STARTUP_NOTIFICATION - if (display->sn_display) - { - sn_display_unref (display->sn_display); - display->sn_display = NULL; - } -#endif + g_clear_object (&display->stack); + g_clear_pointer (&display->stack_tracker, + meta_stack_tracker_free); /* Must be after all calls to meta_window_unmanage() since they * unregister windows */ - g_hash_table_destroy (display->window_ids); - - if (display->leader_window != None) - XDestroyWindow (display->xdisplay, display->leader_window); - - XFlush (display->xdisplay); - - meta_display_free_window_prop_hooks (display); - meta_display_free_group_prop_hooks (display); - - free (display->hostname); - free (display->name); + g_hash_table_destroy (display->wayland_windows); + g_hash_table_destroy (display->stamps); meta_display_shutdown_keys (display); - if (display->compositor) - meta_compositor_destroy (display->compositor); + g_clear_object (&display->bell); + g_clear_object (&display->startup_notification); + g_clear_object (&display->workspace_manager); + g_clear_object (&display->sound_player); + + meta_clipboard_manager_shutdown (display); + g_clear_object (&display->selection); g_object_unref (display); the_display = NULL; @@ -1111,123 +1149,22 @@ meta_display_close (MetaDisplay *display, } /** - * meta_display_screen_for_root: - * @display: a #MetaDisplay + * meta_display_for_x_display: + * @xdisplay: An X display * - * Return the #MetaScreen corresponding to a specified X root window ID. - * - * Return Value: (transfer none): the screen for the specified root window ID, or %NULL - */ -MetaScreen* -meta_display_screen_for_root (MetaDisplay *display, - Window xroot) -{ - GSList *tmp; - - tmp = display->screens; - while (tmp != NULL) - { - MetaScreen *screen = tmp->data; - - if (xroot == screen->xroot) - return screen; - - tmp = tmp->next; - } - - return NULL; -} - -LOCAL_SYMBOL MetaScreen* -meta_display_screen_for_xwindow (MetaDisplay *display, - Window xwindow) -{ - XWindowAttributes attr; - int result; - - meta_error_trap_push (display); - attr.screen = NULL; - result = XGetWindowAttributes (display->xdisplay, xwindow, &attr); - meta_error_trap_pop (display); - - /* Note, XGetWindowAttributes is on all kinds of crack - * and returns 1 on success 0 on failure, rather than Success - * on success. - */ - if (result == 0 || attr.screen == NULL) - return NULL; - - return meta_display_screen_for_x_screen (display, attr.screen); -} - -LOCAL_SYMBOL MetaScreen* -meta_display_screen_for_x_screen (MetaDisplay *display, - Screen *xscreen) -{ - GSList *tmp; - - tmp = display->screens; - while (tmp != NULL) - { - MetaScreen *screen = tmp->data; - - if (xscreen == screen->xscreen) - return screen; - - tmp = tmp->next; - } - - return NULL; -} - -/* Grab/ungrab routines taken from fvwm */ -LOCAL_SYMBOL void -meta_display_grab (MetaDisplay *display) -{ - if (display->server_grab_count == 0) - { - XGrabServer (display->xdisplay); - } - display->server_grab_count += 1; - meta_verbose ("Grabbing display, grab count now %d\n", - display->server_grab_count); -} - -LOCAL_SYMBOL void -meta_display_ungrab (MetaDisplay *display) -{ - if (display->server_grab_count == 0) - meta_bug ("Ungrabbed non-grabbed server\n"); - - display->server_grab_count -= 1; - if (display->server_grab_count == 0) - { - /* FIXME we want to purge all pending "queued" stuff - * at this point, such as window hide/show - */ - XUngrabServer (display->xdisplay); - XFlush (display->xdisplay); - } - - meta_verbose ("Ungrabbing display, grab count now %d\n", - display->server_grab_count); -} - -/* - * Returns the singleton MetaDisplay if "xdisplay" matches the X display it's - * managing; otherwise gives a warning and returns NULL. When we were claiming + * Returns the singleton MetaDisplay if @xdisplay matches the X display it's + * managing; otherwise gives a warning and returns %NULL. When we were claiming * to be able to manage multiple displays, this was supposed to find the * display out of the list which matched that display. Now it's merely an * extra sanity check. * - * \param xdisplay An X display - * \return The singleton X display, or NULL if "xdisplay" isn't the one + * Returns: The singleton X display, or %NULL if @xdisplay isn't the one * we're managing. */ -LOCAL_SYMBOL MetaDisplay* +MetaDisplay* meta_display_for_x_display (Display *xdisplay) { - if (the_display->xdisplay == xdisplay) + if (the_display->x11_display->xdisplay == xdisplay) return the_display; meta_warning ("Could not find display for X display %p, probably going to crash\n", @@ -1236,143 +1173,76 @@ meta_display_for_x_display (Display *xdisplay) return NULL; } -/* +/** + * meta_get_display: + * * Accessor for the singleton MetaDisplay. * - * \return The only MetaDisplay there is. This can be NULL, but only + * Returns: The only #MetaDisplay there is. This can be %NULL, but only * during startup. */ -LOCAL_SYMBOL MetaDisplay* +MetaDisplay* meta_get_display (void) { return the_display; } -#ifdef WITH_VERBOSE_MODE -static gboolean dump_events = TRUE; -#endif +static inline gboolean +grab_op_is_window (MetaGrabOp op) +{ + return META_GRAB_OP_GET_BASE_TYPE (op) == META_GRAB_OP_WINDOW_BASE; +} -static gboolean -grab_op_is_mouse_only (MetaGrabOp op) +gboolean +meta_grab_op_is_mouse (MetaGrabOp op) { - switch (op) - { - case META_GRAB_OP_MOVING: - case META_GRAB_OP_RESIZING_SE: - case META_GRAB_OP_RESIZING_S: - case META_GRAB_OP_RESIZING_SW: - case META_GRAB_OP_RESIZING_N: - case META_GRAB_OP_RESIZING_NE: - case META_GRAB_OP_RESIZING_NW: - case META_GRAB_OP_RESIZING_W: - case META_GRAB_OP_RESIZING_E: - return TRUE; + if (!grab_op_is_window (op)) + return FALSE; - default: - return FALSE; - } + return (op & META_GRAB_OP_WINDOW_FLAG_KEYBOARD) == 0; } -static gboolean -grab_op_is_mouse (MetaGrabOp op) +gboolean +meta_grab_op_is_keyboard (MetaGrabOp op) { - switch (op) - { - case META_GRAB_OP_MOVING: - case META_GRAB_OP_RESIZING_SE: - case META_GRAB_OP_RESIZING_S: - case META_GRAB_OP_RESIZING_SW: - case META_GRAB_OP_RESIZING_N: - case META_GRAB_OP_RESIZING_NE: - case META_GRAB_OP_RESIZING_NW: - case META_GRAB_OP_RESIZING_W: - case META_GRAB_OP_RESIZING_E: - case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN: - case META_GRAB_OP_KEYBOARD_RESIZING_S: - case META_GRAB_OP_KEYBOARD_RESIZING_N: - case META_GRAB_OP_KEYBOARD_RESIZING_W: - case META_GRAB_OP_KEYBOARD_RESIZING_E: - case META_GRAB_OP_KEYBOARD_RESIZING_SE: - case META_GRAB_OP_KEYBOARD_RESIZING_NE: - case META_GRAB_OP_KEYBOARD_RESIZING_SW: - case META_GRAB_OP_KEYBOARD_RESIZING_NW: - case META_GRAB_OP_KEYBOARD_MOVING: - case META_GRAB_OP_COMPOSITOR: - return TRUE; + if (!grab_op_is_window (op)) + return FALSE; - default: - return FALSE; - } + return (op & META_GRAB_OP_WINDOW_FLAG_KEYBOARD) != 0; } -static gboolean -grab_op_is_keyboard (MetaGrabOp op) +gboolean +meta_grab_op_is_resizing (MetaGrabOp op) { - switch (op) + if (!grab_op_is_window (op)) + return FALSE; + + return (op & META_GRAB_OP_WINDOW_DIR_MASK) != 0 || op == META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN; +} + +gboolean +meta_grab_op_is_moving (MetaGrabOp op) +{ + if (!grab_op_is_window (op)) + return FALSE; + + return !meta_grab_op_is_resizing (op); +} + +/** + * meta_display_windows_are_interactable: + * @op: A #MetaGrabOp + * + * Whether windows can be interacted with. + */ +gboolean +meta_display_windows_are_interactable (MetaDisplay *display) +{ + switch (display->event_route) { - case META_GRAB_OP_KEYBOARD_MOVING: - case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN: - case META_GRAB_OP_KEYBOARD_RESIZING_S: - case META_GRAB_OP_KEYBOARD_RESIZING_N: - case META_GRAB_OP_KEYBOARD_RESIZING_W: - case META_GRAB_OP_KEYBOARD_RESIZING_E: - case META_GRAB_OP_KEYBOARD_RESIZING_SE: - case META_GRAB_OP_KEYBOARD_RESIZING_NE: - case META_GRAB_OP_KEYBOARD_RESIZING_SW: - case META_GRAB_OP_KEYBOARD_RESIZING_NW: - case META_GRAB_OP_KEYBOARD_TABBING_NORMAL: - case META_GRAB_OP_KEYBOARD_TABBING_DOCK: - case META_GRAB_OP_KEYBOARD_TABBING_GROUP: - case META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL: - case META_GRAB_OP_KEYBOARD_ESCAPING_DOCK: - case META_GRAB_OP_KEYBOARD_ESCAPING_GROUP: - case META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING: - case META_GRAB_OP_COMPOSITOR: + case META_EVENT_ROUTE_NORMAL: + case META_EVENT_ROUTE_WAYLAND_POPUP: return TRUE; - - default: - return FALSE; - } -} - -LOCAL_SYMBOL gboolean -meta_grab_op_is_resizing (MetaGrabOp op) -{ - switch (op) - { - case META_GRAB_OP_RESIZING_SE: - case META_GRAB_OP_RESIZING_S: - case META_GRAB_OP_RESIZING_SW: - case META_GRAB_OP_RESIZING_N: - case META_GRAB_OP_RESIZING_NE: - case META_GRAB_OP_RESIZING_NW: - case META_GRAB_OP_RESIZING_W: - case META_GRAB_OP_RESIZING_E: - case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN: - case META_GRAB_OP_KEYBOARD_RESIZING_S: - case META_GRAB_OP_KEYBOARD_RESIZING_N: - case META_GRAB_OP_KEYBOARD_RESIZING_W: - case META_GRAB_OP_KEYBOARD_RESIZING_E: - case META_GRAB_OP_KEYBOARD_RESIZING_SE: - case META_GRAB_OP_KEYBOARD_RESIZING_NE: - case META_GRAB_OP_KEYBOARD_RESIZING_SW: - case META_GRAB_OP_KEYBOARD_RESIZING_NW: - return TRUE; - - default: - return FALSE; - } -} - -LOCAL_SYMBOL gboolean -meta_grab_op_is_moving (MetaGrabOp op) -{ - switch (op) - { - case META_GRAB_OP_MOVING: - case META_GRAB_OP_KEYBOARD_MOVING: - return TRUE; - default: return FALSE; } @@ -1422,47 +1292,14 @@ meta_display_get_current_time (MetaDisplay *display) return display->current_time; } -/* Get a timestamp, even if it means a roundtrip */ guint32 meta_display_get_current_time_roundtrip (MetaDisplay *display) { - guint32 timestamp; - - timestamp = meta_display_get_current_time (display); - if (timestamp == CurrentTime) - { - XEvent property_event; - - /* Using the property XA_PRIMARY because it's safe; nothing - * would use it as a property. The type doesn't matter. - */ - XChangeProperty (display->xdisplay, - display->timestamp_pinging_window, - XA_PRIMARY, XA_STRING, 8, - PropModeAppend, NULL, 0); - XWindowEvent (display->xdisplay, - display->timestamp_pinging_window, - PropertyChangeMask, - &property_event); - timestamp = property_event.xproperty.time; - } - - sanity_check_timestamps (display, timestamp); - - return timestamp; -} - -/** - * meta_display_get_ignored_modifier_mask: - * @display: a #MetaDisplay - * - * Returns: a mask of modifiers that should be ignored - * when matching keybindings to events - */ -unsigned int -meta_display_get_ignored_modifier_mask (MetaDisplay *display) -{ - return display->ignored_modifier_mask; + if (meta_is_wayland_compositor ()) + /* Xwayland uses monotonic clock, so lets use it here as well */ + return (guint32) (g_get_monotonic_time () / 1000); + else + return meta_x11_display_get_current_time_roundtrip (display->x11_display); } /** @@ -1497,2403 +1334,704 @@ meta_display_add_ignored_crossing_serial (MetaDisplay *display, display->ignored_crossing_serials[i] = serial; } -static gboolean -crossing_serial_is_ignored (MetaDisplay *display, - unsigned long serial) -{ - int i; - - i = 0; - while (i < N_IGNORED_CROSSING_SERIALS) - { - if (display->ignored_crossing_serials[i] == serial) - return TRUE; - ++i; - } - return FALSE; -} - -static void -reset_ignored_crossing_serials (MetaDisplay *display) -{ - int i; - - i = 0; - while (i < N_IGNORED_CROSSING_SERIALS) - { - display->ignored_crossing_serials[i] = 0; - ++i; - } - - display->ungrab_should_not_cause_focus_window = None; -} - static gboolean window_raise_with_delay_callback (void *data) { - MetaWindow *window; - MetaAutoRaiseData *auto_raise; - - auto_raise = data; - - meta_topic (META_DEBUG_FOCUS, - "In autoraise callback for window 0x%lx\n", - auto_raise->xwindow); + MetaWindow *window = data; - auto_raise->display->autoraise_timeout_id = 0; - auto_raise->display->autoraise_window = NULL; - - window = meta_display_lookup_x_window (auto_raise->display, - auto_raise->xwindow); - - if (window == NULL) - return FALSE; + window->display->autoraise_timeout_id = 0; + window->display->autoraise_window = NULL; /* If we aren't already on top, check whether the pointer is inside * the window and raise the window if so. */ - if (meta_stack_get_top (window->screen->stack) != window) + if (meta_stack_get_top (window->display->stack) != window) { - int x, y, root_x, root_y; - Window root, child; - unsigned int mask; - gboolean same_screen; - gboolean point_in_window; - - meta_error_trap_push (window->display); - same_screen = XQueryPointer (window->display->xdisplay, - window->xwindow, - &root, &child, - &root_x, &root_y, &x, &y, &mask); - meta_error_trap_pop (window->display); - - point_in_window = - (window->frame && META_POINT_IN_RECT (root_x, root_y, window->frame->rect)) || - (window->frame == NULL && META_POINT_IN_RECT (root_x, root_y, window->rect)); - if (same_screen && point_in_window) + if (meta_window_has_pointer (window)) meta_window_raise (window); -#ifdef WITH_VERBOSE_MODE else meta_topic (META_DEBUG_FOCUS, "Pointer not inside window, not raising %s\n", window->desc); -#endif } - return FALSE; + return G_SOURCE_REMOVE; } -LOCAL_SYMBOL void +void meta_display_queue_autoraise_callback (MetaDisplay *display, MetaWindow *window) { - MetaAutoRaiseData *auto_raise_data; - meta_topic (META_DEBUG_FOCUS, "Queuing an autoraise timeout for %s with delay %d\n", window->desc, meta_prefs_get_auto_raise_delay ()); - auto_raise_data = g_new (MetaAutoRaiseData, 1); - auto_raise_data->display = window->display; - auto_raise_data->xwindow = window->xwindow; - - if (display->autoraise_timeout_id != 0) { - g_source_remove (display->autoraise_timeout_id); - display->autoraise_timeout_id = 0; - } + g_clear_handle_id (&display->autoraise_timeout_id, g_source_remove); display->autoraise_timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT, meta_prefs_get_auto_raise_delay (), window_raise_with_delay_callback, - auto_raise_data, - free); + window, NULL); + g_source_set_name_by_id (display->autoraise_timeout_id, "[mutter] window_raise_with_delay_callback"); display->autoraise_window = window; } -/* - * This is the most important function in the whole program. It is the heart, - * it is the nexus, it is the Grand Central Station of Muffin's world. - * When we create a MetaDisplay, we ask GDK to pass *all* events for *all* - * windows to this function. So every time anything happens that we might - * want to know about, this function gets called. You see why it gets a bit - * busy around here. Most of this function is a ginormous switch statement - * dealing with all the kinds of events that might turn up. - * - * \param event The event that just happened - * \param data The MetaDisplay that events are coming from, cast to a gpointer - * so that it can be sent to a callback - * - * \ingroup main - */ -static gboolean -event_callback (XEvent *event, - gpointer data) -{ - MetaWindow *window; - MetaWindow *property_for_window; - MetaDisplay *display; - Window modified; - gboolean frame_was_receiver; - gboolean bypass_compositor; - gboolean filter_out_event; - - display = data; +void +meta_display_sync_wayland_input_focus (MetaDisplay *display) +{ +#ifdef HAVE_WAYLAND + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + MetaWindow *focus_window = NULL; + MetaBackend *backend = meta_get_backend (); + MetaStage *stage = META_STAGE (meta_backend_get_stage (backend)); + gboolean is_no_focus_xwindow = FALSE; + + if (display->x11_display) + is_no_focus_xwindow = meta_x11_display_xwindow_is_a_no_focus_window (display->x11_display, + display->x11_display->focus_xwindow); + + if (!meta_display_windows_are_interactable (display)) + focus_window = NULL; + else if (is_no_focus_xwindow) + focus_window = NULL; + else if (display->focus_window && display->focus_window->surface) + focus_window = display->focus_window; + else + meta_topic (META_DEBUG_FOCUS, "Focus change has no effect, because there is no matching wayland surface"); -#ifdef WITH_VERBOSE_MODE - if (dump_events) - meta_spew_event (display, event); -#endif + meta_stage_set_active (stage, focus_window == NULL); + meta_wayland_compositor_set_input_focus (compositor, focus_window); -#ifdef HAVE_STARTUP_NOTIFICATION - sn_display_process_event (display->sn_display, event); + meta_wayland_seat_repick (compositor->seat); #endif +} - bypass_compositor = FALSE; - filter_out_event = FALSE; - display->current_time = event_get_time (display, event); - display->monitor_cache_invalidated = TRUE; - - modified = event_get_modified_window (display, event); +void +meta_display_update_focus_window (MetaDisplay *display, + MetaWindow *window) +{ + if (display->focus_window == window) + return; - if (event->type == UnmapNotify) - { - if (meta_ui_window_should_not_cause_focus (display->xdisplay, - modified)) - { - meta_display_add_ignored_crossing_serial (display, event->xany.serial); - meta_topic (META_DEBUG_FOCUS, - "Adding EnterNotify serial %lu to ignored focus serials\n", - event->xany.serial); - } - } - else if (event->type == LeaveNotify && - event->xcrossing.mode == NotifyUngrab && - modified == display->ungrab_should_not_cause_focus_window) + if (display->focus_window) { - meta_display_add_ignored_crossing_serial (display, event->xany.serial); + MetaWindow *previous; + meta_topic (META_DEBUG_FOCUS, - "Adding LeaveNotify serial %lu to ignored focus serials\n", - event->xany.serial); - } + "%s is now the previous focus window due to being focused out or unmapped\n", + display->focus_window->desc); - if (modified != None) - window = meta_display_lookup_x_window (display, modified); - else - window = NULL; + /* Make sure that signals handlers invoked by + * meta_window_set_focused_internal() don't see + * display->focus_window->has_focus == FALSE + */ + previous = display->focus_window; + display->focus_window = NULL; - /* We only want to respond to _NET_WM_USER_TIME property notify - * events on _NET_WM_USER_TIME_WINDOW windows; in particular, - * responding to UnmapNotify events is kind of bad. - */ - property_for_window = NULL; - if (window && modified == window->user_time_window) - { - property_for_window = window; - window = NULL; + meta_window_set_focused_internal (previous, FALSE); } + display->focus_window = window; - frame_was_receiver = FALSE; - if (window && - window->frame && - modified == window->frame->xwindow) + if (display->focus_window) { - /* Note that if the frame and the client both have an - * XGrabButton (as is normal with our setup), the event - * goes to the frame. - */ - frame_was_receiver = TRUE; - meta_topic (META_DEBUG_EVENTS, "Frame was receiver of event for %s\n", - window->desc); + meta_topic (META_DEBUG_FOCUS, "* Focus --> %s\n", + display->focus_window->desc); + meta_window_set_focused_internal (display->focus_window, TRUE); } + else + meta_topic (META_DEBUG_FOCUS, "* Focus --> NULL\n"); -#ifdef HAVE_XSYNC - if (META_DISPLAY_HAS_XSYNC (display) && - event->type == (display->xsync_event_base + XSyncAlarmNotify)) - { - MetaWindow *alarm_window = meta_display_lookup_sync_alarm (display, - ((XSyncAlarmNotifyEvent*)event)->alarm); - if (alarm_window != NULL) - { - XSyncValue value = ((XSyncAlarmNotifyEvent*)event)->counter_value; - gint64 new_counter_value; - new_counter_value = XSyncValueLow32 (value) + ((gint64)XSyncValueHigh32 (value) << 32); - meta_window_update_sync_request_counter (alarm_window, new_counter_value); - filter_out_event = TRUE; /* GTK doesn't want to see this really */ - } - } -#endif /* HAVE_XSYNC */ + if (meta_is_wayland_compositor ()) + meta_display_sync_wayland_input_focus (display); -#ifdef HAVE_SHAPE - if (META_DISPLAY_HAS_SHAPE (display) && - event->type == (display->shape_event_base + ShapeNotify)) - { - filter_out_event = TRUE; /* GTK doesn't want to see this really */ + g_object_notify (G_OBJECT (display), "focus-window"); +} - if (window && !frame_was_receiver) - { - XShapeEvent *sev = (XShapeEvent*) event; +gboolean +meta_display_timestamp_too_old (MetaDisplay *display, + guint32 *timestamp) +{ + /* FIXME: If Soeren's suggestion in bug 151984 is implemented, it will allow + * us to sanity check the timestamp here and ensure it doesn't correspond to + * a future time (though we would want to rename to + * timestamp_too_old_or_in_future). + */ - if (sev->kind == ShapeBounding) - { - if (sev->shaped && !window->has_shape) - { - window->has_shape = TRUE; - meta_topic (META_DEBUG_SHAPES, - "Window %s now has a shape\n", - window->desc); - } - else if (!sev->shaped && window->has_shape) - { - window->has_shape = FALSE; - meta_topic (META_DEBUG_SHAPES, - "Window %s no longer has a shape\n", - window->desc); - } -#ifdef WITH_VERBOSE_MODE - else - { - meta_topic (META_DEBUG_SHAPES, - "Window %s shape changed\n", - window->desc); - } -#endif - meta_compositor_window_shape_changed (display->compositor, - window); - } - } -#ifdef WITH_VERBOSE_MODE - else - { - meta_topic (META_DEBUG_SHAPES, - "ShapeNotify not on a client window (window %s frame_was_receiver = %d)\n", - window ? window->desc : "(none)", - frame_was_receiver); - } -#endif + if (*timestamp == META_CURRENT_TIME) + { + *timestamp = meta_display_get_current_time_roundtrip (display); + return FALSE; } -#endif /* HAVE_SHAPE */ - - if (window && !window->override_redirect && - ((event->type == KeyPress) || (event->type == ButtonPress))) + else if (XSERVER_TIME_IS_BEFORE (*timestamp, display->last_focus_time)) { - if (CurrentTime == display->current_time) - { - /* We can't use missing (i.e. invalid) timestamps to set user time, - * nor do we want to use them to sanity check other timestamps. - * See bug 313490 for more details. - */ - meta_warning ("Event has no timestamp! You may be using a broken " - "program such as xse. Please ask the authors of that " - "program to fix it.\n"); - } + if (XSERVER_TIME_IS_BEFORE (*timestamp, display->last_user_time)) + return TRUE; else { - meta_window_set_user_time (window, display->current_time); - sanity_check_timestamps (display, display->current_time); + *timestamp = display->last_focus_time; + return FALSE; } } - switch (event->type) + return FALSE; +} + +void +meta_display_set_input_focus (MetaDisplay *display, + MetaWindow *window, + gboolean focus_frame, + guint32 timestamp) +{ + if (meta_display_timestamp_too_old (display, ×tamp)) + return; + + if (display->x11_display) { - case KeyPress: - case KeyRelease: - if (display->grab_op == META_GRAB_OP_COMPOSITOR) - break; - /* For key events, it's important to enforce single-handling, or - * we can get into a confused state. So if a keybinding is - * handled (because it's one of our hot-keys, or because we are - * in a keyboard-grabbed mode like moving a window, we don't - * want to pass the key event to the compositor or GTK+ at all. - */ - if (display->grab_window == window && - grab_op_is_mouse (display->grab_op)) - meta_window_handle_keyboard_grab_op_event (window, event); + meta_x11_display_set_input_focus (display->x11_display, window, + focus_frame, timestamp); + } - if (meta_display_process_key_event (display, window, event)) - filter_out_event = bypass_compositor = TRUE; - break; - case ButtonPress: - if (display->grab_op == META_GRAB_OP_COMPOSITOR) - break; - if (display->mouse_zoom_modifiers > 0 && (event->xbutton.button == 4 || event->xbutton.button == 5)) - { - if ((event->xbutton.state & ~display->ignored_modifier_mask) == display->mouse_zoom_modifiers) - { - if (event->xbutton.button == 4) - { - g_signal_emit (display, display_signals[ZOOM_SCROLL_IN], 0); - } - - if (event->xbutton.button == 5) - { - g_signal_emit (display, display_signals[ZOOM_SCROLL_OUT], 0); - } - filter_out_event = bypass_compositor = TRUE; - } - break; - } + meta_display_update_focus_window (display, window); - if ((window && - grab_op_is_mouse (display->grab_op) && - display->grab_button != (int) event->xbutton.button && - display->grab_window == window) || - grab_op_is_keyboard (display->grab_op)) - { - meta_topic (META_DEBUG_WINDOW_OPS, - "Ending grab op %u on window %s due to button press\n", - display->grab_op, - (display->grab_window ? - display->grab_window->desc : - "none")); - if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op)) - { - MetaScreen *screen; - meta_topic (META_DEBUG_WINDOW_OPS, - "Syncing to old stack positions.\n"); - screen = - meta_display_screen_for_root (display, event->xany.window); - - if (screen!=NULL) - meta_stack_set_positions (screen->stack, - display->grab_old_window_stacking); - } + display->last_focus_time = timestamp; - if (display->grab_window->tile_mode == META_TILE_NONE) - meta_display_end_grab_op (display, - event->xbutton.time); - } - else if (window && display->grab_op == META_GRAB_OP_NONE) - { - gboolean begin_move = FALSE; - unsigned int grab_mask; - gboolean unmodified; - - grab_mask = display->window_grab_modifiers; - if (display->debug_button_grabs) - grab_mask |= ControlMask; - - /* Two possible sources of an unmodified event; one is a - * client that's letting button presses pass through to the - * frame, the other is our focus_window_grab on unmodified - * button 1. So for all such events we focus the window. - */ - unmodified = (event->xbutton.state & grab_mask) == 0; + if (window == NULL || window != display->autoraise_window) + meta_display_remove_autoraise_callback (display); +} - if (unmodified || - event->xbutton.button == 1) - { - /* don't focus if frame received, will be lowered in - * frames.c or special-cased if the click was on a - * minimize/close button. - */ - if (!frame_was_receiver) - { - if (meta_prefs_get_raise_on_click () && - !meta_ui_window_is_widget (display->active_screen->ui, modified)) - meta_window_raise (window); -#ifdef WITH_VERBOSE_MODE - else - meta_topic (META_DEBUG_FOCUS, - "Not raising window on click due to don't-raise-on-click option\n"); -#endif - /* Don't focus panels--they must explicitly request focus. - * See bug 160470 - */ - if (window->type != META_WINDOW_DOCK && - !meta_ui_window_is_widget (display->active_screen->ui, modified)) - { - meta_topic (META_DEBUG_FOCUS, - "Focusing %s due to unmodified button %u press (display.c)\n", - window->desc, event->xbutton.button); - meta_window_focus (window, event->xbutton.time); - } - else - /* However, do allow terminals to lose focus due to new - * window mappings after the user clicks on a panel. - */ - display->allow_terminal_deactivation = TRUE; - } - - /* you can move on alt-click but not on - * the click-to-focus - */ - if (!unmodified) - begin_move = TRUE; - } - else if (!unmodified && event->xbutton.button == meta_prefs_get_mouse_button_resize()) - { - if (window->has_resize_func) - { - gboolean north, south; - gboolean west, east; - int root_x, root_y; - MetaGrabOp op; - - meta_window_get_position (window, &root_x, &root_y); - - west = event->xbutton.x_root < (root_x + 1 * window->rect.width / 3); - east = event->xbutton.x_root > (root_x + 2 * window->rect.width / 3); - north = event->xbutton.y_root < (root_y + 1 * window->rect.height / 3); - south = event->xbutton.y_root > (root_y + 2 * window->rect.height / 3); - - if (north && west) - op = META_GRAB_OP_RESIZING_NW; - else if (north && east) - op = META_GRAB_OP_RESIZING_NE; - else if (south && west) - op = META_GRAB_OP_RESIZING_SW; - else if (south && east) - op = META_GRAB_OP_RESIZING_SE; - else if (north) - op = META_GRAB_OP_RESIZING_N; - else if (west) - op = META_GRAB_OP_RESIZING_W; - else if (east) - op = META_GRAB_OP_RESIZING_E; - else if (south) - op = META_GRAB_OP_RESIZING_S; - else /* Middle region is no-op to avoid user triggering wrong action */ - op = META_GRAB_OP_NONE; - - if (op != META_GRAB_OP_NONE) - meta_display_begin_grab_op (display, - window->screen, - window, - op, - TRUE, - FALSE, - event->xbutton.button, - 0, - event->xbutton.time, - event->xbutton.x_root, - event->xbutton.y_root); - } - } - else if (event->xbutton.button == meta_prefs_get_mouse_button_menu()) - { - if (meta_prefs_get_raise_on_click ()) - meta_window_raise (window); - meta_window_show_menu (window, - event->xbutton.x_root, - event->xbutton.y_root, - event->xbutton.button, - event->xbutton.time); - } +void +meta_display_unset_input_focus (MetaDisplay *display, + guint32 timestamp) +{ + meta_display_set_input_focus (display, NULL, FALSE, timestamp); +} - if (!frame_was_receiver && unmodified) - { - /* This is from our synchronous grab since - * it has no modifiers and was on the client window - */ - int mode; - - /* When clicking a different app in click-to-focus - * in application-based mode, and the different - * app is not a dock or desktop, eat the focus click. - */ - if (meta_prefs_get_focus_mode () == C_DESKTOP_FOCUS_MODE_CLICK && - meta_prefs_get_application_based () && - !window->has_focus && - window->type != META_WINDOW_DOCK && - window->type != META_WINDOW_DESKTOP && - (display->focus_window == NULL || - !meta_window_same_application (window, - display->focus_window))) - mode = AsyncPointer; /* eat focus click */ - else - mode = ReplayPointer; /* give event back */ - - meta_verbose ("Allowing events mode %s time %u\n", - mode == AsyncPointer ? "AsyncPointer" : "ReplayPointer", - (unsigned int)event->xbutton.time); - - XAllowEvents (display->xdisplay, - mode, event->xbutton.time); - } +void +meta_display_register_wayland_window (MetaDisplay *display, + MetaWindow *window) +{ + g_hash_table_add (display->wayland_windows, window); +} - if (begin_move && window->has_move_func) - { - meta_display_begin_grab_op (display, - window->screen, - window, - META_GRAB_OP_MOVING, - TRUE, - FALSE, - event->xbutton.button, - 0, - event->xbutton.time, - event->xbutton.x_root, - event->xbutton.y_root); - } - } - break; - case ButtonRelease: - if (display->grab_op == META_GRAB_OP_COMPOSITOR) - break; +void +meta_display_unregister_wayland_window (MetaDisplay *display, + MetaWindow *window) +{ + g_hash_table_remove (display->wayland_windows, window); +} - if (display->grab_window == window && - grab_op_is_mouse (display->grab_op)) - meta_window_handle_mouse_grab_op_event (window, event); - break; - case MotionNotify: - if (display->grab_op == META_GRAB_OP_COMPOSITOR) - break; +MetaWindow* +meta_display_lookup_stamp (MetaDisplay *display, + guint64 stamp) +{ + return g_hash_table_lookup (display->stamps, &stamp); +} - if (display->grab_window == window && - grab_op_is_mouse (display->grab_op)) - meta_window_handle_mouse_grab_op_event (window, event); - break; - case EnterNotify: - if (display->grab_op == META_GRAB_OP_COMPOSITOR) - break; +void +meta_display_register_stamp (MetaDisplay *display, + guint64 *stampp, + MetaWindow *window) +{ + g_return_if_fail (g_hash_table_lookup (display->stamps, stampp) == NULL); - if (display->grab_window == window && - grab_op_is_mouse (display->grab_op)) - { - meta_window_handle_mouse_grab_op_event (window, event); - break; - } + g_hash_table_insert (display->stamps, stampp, window); +} - /* If the mouse switches screens, active the default window on the new - * screen; this will make keybindings and workspace-launched items - * actually appear on the right screen. - */ - { - MetaScreen *new_screen = - meta_display_screen_for_root (display, event->xcrossing.root); +void +meta_display_unregister_stamp (MetaDisplay *display, + guint64 stamp) +{ + g_return_if_fail (g_hash_table_lookup (display->stamps, &stamp) != NULL); - if (new_screen != NULL && display->active_screen != new_screen) - meta_workspace_focus_default_window (new_screen->active_workspace, - NULL, - event->xcrossing.time); - } + g_hash_table_remove (display->stamps, &stamp); +} - /* Check if we've entered a window; do this even if window->has_focus to - * avoid races. - */ - if (window && !crossing_serial_is_ignored (display, event->xany.serial) && - event->xcrossing.mode != NotifyGrab && - event->xcrossing.mode != NotifyUngrab && - event->xcrossing.detail != NotifyInferior && - meta_display_focus_sentinel_clear (display)) - { - switch (meta_prefs_get_focus_mode ()) - { - case C_DESKTOP_FOCUS_MODE_SLOPPY: - case C_DESKTOP_FOCUS_MODE_MOUSE: - display->mouse_mode = TRUE; - if (window->type != META_WINDOW_DOCK && - window->type != META_WINDOW_DESKTOP) - { - meta_topic (META_DEBUG_FOCUS, - "Focusing %s due to enter notify with serial %lu " - "at time %lu, and setting display->mouse_mode to " - "TRUE.\n", - window->desc, - event->xany.serial, - event->xcrossing.time); - - meta_window_focus (window, event->xcrossing.time); - - /* stop ignoring stuff */ - reset_ignored_crossing_serials (display); - - if (meta_prefs_get_auto_raise ()) - { - meta_display_queue_autoraise_callback (display, window); - } -#ifdef WITH_VERBOSE_MODE - else - { - meta_topic (META_DEBUG_FOCUS, - "Auto raise is disabled\n"); - } -#endif - } - /* In mouse focus mode, we defocus when the mouse *enters* - * the DESKTOP window, instead of defocusing on LeaveNotify. - * This is because having the mouse enter override-redirect - * child windows unfortunately causes LeaveNotify events that - * we can't distinguish from the mouse actually leaving the - * toplevel window as we expect. But, since we filter out - * EnterNotify events on override-redirect windows, this - * alternative mechanism works great. - */ - if (window->type == META_WINDOW_DESKTOP && - meta_prefs_get_focus_mode() == C_DESKTOP_FOCUS_MODE_MOUSE && - display->expected_focus_window != NULL) - { - meta_topic (META_DEBUG_FOCUS, - "Unsetting focus from %s due to mouse entering " - "the DESKTOP window\n", - display->expected_focus_window->desc); - meta_display_focus_the_no_focus_window (display, - window->screen, - event->xcrossing.time); - } - break; - case C_DESKTOP_FOCUS_MODE_CLICK: - break; - } +MetaWindow* +meta_display_lookup_stack_id (MetaDisplay *display, + guint64 stack_id) +{ + if (META_STACK_ID_IS_X11 (stack_id)) + { + if (!display->x11_display) + return NULL; + return meta_x11_display_lookup_x_window (display->x11_display, + (Window)stack_id); + } + else + { + return meta_display_lookup_stamp (display, stack_id); + } +} - if (window->type == META_WINDOW_DOCK) - meta_window_raise (window); - } - break; - case LeaveNotify: - if (display->grab_op == META_GRAB_OP_COMPOSITOR) - break; +/* We return a pointer into a ring of static buffers. This is to make + * using this function for debug-logging convenient and avoid tempory + * strings that must be freed. */ +const char * +meta_display_describe_stack_id (MetaDisplay *display, + guint64 stack_id) +{ + /* 0x<64-bit: 16 characters> (<10 characters of title>)\0' */ + static char buffer[5][32]; + MetaWindow *window; + static int pos = 0; + char *result; - if (display->grab_window == window && - grab_op_is_mouse (display->grab_op)) - meta_window_handle_mouse_grab_op_event (window, event); - else if (window != NULL) - { - if (window->type == META_WINDOW_DOCK && - event->xcrossing.mode != NotifyGrab && - event->xcrossing.mode != NotifyUngrab && - !window->has_focus) - meta_window_lower (window); - } - break; - case FocusIn: - case FocusOut: - if (window) - { - meta_window_notify_focus (window, event); - } - else if (meta_display_xwindow_is_a_no_focus_window (display, - event->xany.window)) - { - meta_topic (META_DEBUG_FOCUS, - "Focus %s event received on no_focus_window 0x%lx " - "mode %s detail %s\n", - event->type == FocusIn ? "in" : - event->type == FocusOut ? "out" : - "???", - event->xany.window, - meta_event_mode_to_string (event->xfocus.mode), - meta_event_detail_to_string (event->xfocus.detail)); - } - else - { - MetaScreen *screen = - meta_display_screen_for_root(display, - event->xany.window); - if (screen == NULL) - break; - - meta_topic (META_DEBUG_FOCUS, - "Focus %s event received on root window 0x%lx " - "mode %s detail %s\n", - event->type == FocusIn ? "in" : - event->type == FocusOut ? "out" : - "???", - event->xany.window, - meta_event_mode_to_string (event->xfocus.mode), - meta_event_detail_to_string (event->xfocus.detail)); - - if (event->type == FocusIn && - event->xfocus.detail == NotifyDetailNone) - { - meta_topic (META_DEBUG_FOCUS, - "Focus got set to None, probably due to " - "brain-damage in the X protocol (see bug " - "125492). Setting the default focus window.\n"); - meta_workspace_focus_default_window (screen->active_workspace, - NULL, - meta_display_get_current_time_roundtrip (display)); - } - else if (event->type == FocusIn && - event->xfocus.mode == NotifyNormal && - event->xfocus.detail == NotifyInferior) - { - meta_topic (META_DEBUG_FOCUS, - "Focus got set to root window, probably due to " - "gnome-session logout dialog usage (see bug " - "153220). Setting the default focus window.\n"); - meta_workspace_focus_default_window (screen->active_workspace, - NULL, - meta_display_get_current_time_roundtrip (display)); - } + result = buffer[pos]; + pos = (pos + 1) % 5; - } - break; - case KeymapNotify: - break; - case Expose: - break; - case GraphicsExpose: - break; - case NoExpose: - break; - case VisibilityNotify: - break; - case CreateNotify: - { - MetaScreen *screen; - - screen = meta_display_screen_for_root (display, - event->xcreatewindow.parent); - if (screen) - meta_stack_tracker_create_event (screen->stack_tracker, - &event->xcreatewindow); - } - break; - - case DestroyNotify: - { - MetaScreen *screen; - - screen = meta_display_screen_for_root (display, - event->xdestroywindow.event); - if (screen) - meta_stack_tracker_destroy_event (screen->stack_tracker, - &event->xdestroywindow); - } - if (window) - { - /* FIXME: It sucks that DestroyNotify events don't come with - * a timestamp; could we do something better here? Maybe X - * will change one day? - */ - guint32 timestamp; - timestamp = meta_display_get_current_time_roundtrip (display); + window = meta_display_lookup_stack_id (display, stack_id); - if (display->grab_op != META_GRAB_OP_NONE && - display->grab_window == window) - meta_display_end_grab_op (display, timestamp); - - if (frame_was_receiver) - { - meta_warning ("Unexpected destruction of frame 0x%lx, not sure if this should silently fail or be considered a bug\n", - window->frame->xwindow); - meta_error_trap_push (display); - meta_window_destroy_frame (window->frame->window); - meta_error_trap_pop (display); - } - else - { - /* Unmanage destroyed window */ - meta_window_unmanage (window, timestamp); - window = NULL; - } - } - break; - case UnmapNotify: - if (window) - { - /* FIXME: It sucks that UnmapNotify events don't come with - * a timestamp; could we do something better here? Maybe X - * will change one day? - */ - guint32 timestamp; - timestamp = meta_display_get_current_time_roundtrip (display); + if (window && window->title) + snprintf (result, sizeof(buffer[0]), "%#" G_GINT64_MODIFIER "x (%.10s)", stack_id, window->title); + else + snprintf (result, sizeof(buffer[0]), "%#" G_GINT64_MODIFIER "x", stack_id); - if (display->grab_op != META_GRAB_OP_NONE && - display->grab_window == window && - window->frame == NULL) - meta_display_end_grab_op (display, timestamp); + return result; +} - if (!frame_was_receiver) - { - if (window->unmaps_pending == 0) - { - meta_topic (META_DEBUG_WINDOW_STATE, - "Window %s withdrawn\n", - window->desc); - - /* Unmanage withdrawn window */ - window->withdrawn = TRUE; - meta_window_unmanage (window, timestamp); - window = NULL; - } - else - { - window->unmaps_pending -= 1; - meta_topic (META_DEBUG_WINDOW_STATE, - "Received pending unmap, %d now pending\n", - window->unmaps_pending); - } - } +void +meta_display_notify_window_created (MetaDisplay *display, + MetaWindow *window) +{ + COGL_TRACE_BEGIN_SCOPED (MetaDisplayNotifyWindowCreated, + "Display (notify window created)"); + g_signal_emit (display, display_signals[WINDOW_CREATED], 0, window); +} - /* Unfocus on UnmapNotify, do this after the possible - * window_free above so that window_free can see if window->has_focus - * and move focus to another window - */ - if (window) - meta_window_notify_focus (window, event); - } - break; - case MapNotify: - /* NB: override redirect windows wont cause a map request so we - * watch out for map notifies against any root windows too if a - * compositor is enabled: */ - if (window == NULL && meta_display_screen_for_root (display, event->xmap.event)) - { - window = meta_window_new (display, event->xmap.window, - FALSE); - } +static MetaCursor +meta_cursor_for_grab_op (MetaGrabOp op) +{ + switch (op) + { + case META_GRAB_OP_RESIZING_SE: + case META_GRAB_OP_KEYBOARD_RESIZING_SE: + return META_CURSOR_SE_RESIZE; break; - case MapRequest: - if (window == NULL) - { - window = meta_window_new (display, event->xmaprequest.window, - FALSE); - } - /* if frame was receiver it's some malicious send event or something */ - else if (!frame_was_receiver && window) - { - meta_verbose ("MapRequest on %s mapped = %d minimized = %d\n", - window->desc, window->mapped, window->minimized); - if (window->minimized) - { - meta_window_unminimize (window); - if (window->workspace != window->screen->active_workspace) - { - meta_verbose ("Changing workspace due to MapRequest mapped = %d minimized = %d\n", - window->mapped, window->minimized); - meta_window_change_workspace (window, - window->screen->active_workspace); - } - } - } + case META_GRAB_OP_RESIZING_S: + case META_GRAB_OP_KEYBOARD_RESIZING_S: + return META_CURSOR_SOUTH_RESIZE; break; - case ReparentNotify: - { - MetaScreen *screen; - - screen = meta_display_screen_for_root (display, - event->xconfigure.event); - if (screen) - meta_stack_tracker_reparent_event (screen->stack_tracker, - &event->xreparent); - } + case META_GRAB_OP_RESIZING_SW: + case META_GRAB_OP_KEYBOARD_RESIZING_SW: + return META_CURSOR_SW_RESIZE; break; - case ConfigureNotify: - if (event->xconfigure.event != event->xconfigure.window) - { - MetaScreen *screen; - - screen = meta_display_screen_for_root (display, - event->xconfigure.event); - if (screen && - event->xconfigure.event == screen->xroot && - event->xconfigure.window != screen->composite_overlay_window) - meta_stack_tracker_configure_event (screen->stack_tracker, - &event->xconfigure); - } - if (window && window->override_redirect) - meta_window_configure_notify (window, &event->xconfigure); - else - /* Handle screen resize */ - { - MetaScreen *screen; - - screen = meta_display_screen_for_root (display, - event->xconfigure.window); - - if (screen != NULL) - { -#ifdef HAVE_RANDR - /* do the resize the official way */ - XRRUpdateConfiguration (event); -#else - /* poke around in Xlib */ - screen->xscreen->width = event->xconfigure.width; - screen->xscreen->height = event->xconfigure.height; -#endif - - meta_screen_resize (screen, - event->xconfigure.width, - event->xconfigure.height); - } - } + case META_GRAB_OP_RESIZING_N: + case META_GRAB_OP_KEYBOARD_RESIZING_N: + return META_CURSOR_NORTH_RESIZE; break; - case ConfigureRequest: - /* This comment and code is found in both twm and fvwm */ - /* - * According to the July 27, 1988 ICCCM draft, we should ignore size and - * position fields in the WM_NORMAL_HINTS property when we map a window. - * Instead, we'll read the current geometry. Therefore, we should respond - * to configuration requests for windows which have never been mapped. - */ - if (window == NULL) - { - unsigned int xwcm; - XWindowChanges xwc; - - xwcm = event->xconfigurerequest.value_mask & - (CWX | CWY | CWWidth | CWHeight | CWBorderWidth); - - xwc.x = event->xconfigurerequest.x; - xwc.y = event->xconfigurerequest.y; - xwc.width = event->xconfigurerequest.width; - xwc.height = event->xconfigurerequest.height; - xwc.border_width = event->xconfigurerequest.border_width; - - meta_verbose ("Configuring withdrawn window to %d,%d %dx%d border %d (some values may not be in mask)\n", - xwc.x, xwc.y, xwc.width, xwc.height, xwc.border_width); - meta_error_trap_push (display); - XConfigureWindow (display->xdisplay, event->xconfigurerequest.window, - xwcm, &xwc); - meta_error_trap_pop (display); - } - else - { - if (!frame_was_receiver) - meta_window_configure_request (window, event); - } + case META_GRAB_OP_RESIZING_NE: + case META_GRAB_OP_KEYBOARD_RESIZING_NE: + return META_CURSOR_NE_RESIZE; break; - case GravityNotify: + case META_GRAB_OP_RESIZING_NW: + case META_GRAB_OP_KEYBOARD_RESIZING_NW: + return META_CURSOR_NW_RESIZE; break; - case ResizeRequest: + case META_GRAB_OP_RESIZING_W: + case META_GRAB_OP_KEYBOARD_RESIZING_W: + return META_CURSOR_WEST_RESIZE; break; - case CirculateNotify: + case META_GRAB_OP_RESIZING_E: + case META_GRAB_OP_KEYBOARD_RESIZING_E: + return META_CURSOR_EAST_RESIZE; break; - case CirculateRequest: + case META_GRAB_OP_MOVING: + case META_GRAB_OP_KEYBOARD_MOVING: + case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN: + return META_CURSOR_MOVE_OR_RESIZE_WINDOW; break; - case PropertyNotify: - { - MetaGroup *group; - MetaScreen *screen; - - if (window && !frame_was_receiver) - meta_window_property_notify (window, event); - else if (property_for_window && !frame_was_receiver) - meta_window_property_notify (property_for_window, event); - - group = meta_display_lookup_group (display, - event->xproperty.window); - if (group != NULL) - meta_group_property_notify (group, event); - - screen = NULL; - if (window == NULL && - group == NULL) /* window/group != NULL means it wasn't a root window */ - screen = meta_display_screen_for_root (display, - event->xproperty.window); - - if (screen != NULL) - { - if (event->xproperty.atom == - display->atom__NET_DESKTOP_LAYOUT) - meta_screen_update_workspace_layout (screen); - else if (event->xproperty.atom == - display->atom__NET_DESKTOP_NAMES) - meta_screen_update_workspace_names (screen); -#if 0 - else if (event->xproperty.atom == - display->atom__NET_RESTACK_WINDOW) - handle_net_restack_window (display, event); -#endif - - /* we just use this property as a sentinel to avoid - * certain race conditions. See the comment for the - * sentinel_counter variable declaration in display.h - */ - if (event->xproperty.atom == - display->atom__MUFFIN_SENTINEL) - { - meta_display_decrement_focus_sentinel (display); - } - } - } + default: break; - case SelectionClear: - /* do this here instead of at end of function - * so we can return - */ + } - /* FIXME: Clearing display->current_time here makes no sense to - * me; who put this here and why? - */ - display->current_time = CurrentTime; + return META_CURSOR_DEFAULT; +} - process_selection_clear (display, event); - /* Note that processing that may have resulted in - * closing the display... so return right away. - */ - return FALSE; - case SelectionRequest: - process_selection_request (display, event); - break; - case SelectionNotify: - break; - case ColormapNotify: - if (window && !frame_was_receiver) - window->colormap = event->xcolormap.colormap; - break; - case ClientMessage: - if (window) - { - if (!frame_was_receiver) - meta_window_client_message (window, event); - } - else - { - MetaScreen *screen; +static float +find_highest_logical_monitor_scale (MetaBackend *backend, + MetaCursorSprite *cursor_sprite) +{ + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaCursorRenderer *cursor_renderer = + meta_backend_get_cursor_renderer (backend); + graphene_rect_t cursor_rect; + GList *logical_monitors; + GList *l; + float highest_scale = 0.0; - screen = meta_display_screen_for_root (display, - event->xclient.window); + cursor_rect = meta_cursor_renderer_calculate_rect (cursor_renderer, + cursor_sprite); - if (screen) - { - if (event->xclient.message_type == - display->atom__NET_CURRENT_DESKTOP) - { - int space; - MetaWorkspace *workspace; - guint32 time; - - space = event->xclient.data.l[0]; - time = event->xclient.data.l[1]; - - meta_verbose ("Request to change current workspace to %d with " - "specified timestamp of %u\n", - space, time); - - workspace = - meta_screen_get_workspace_by_index (screen, - space); - - /* Handle clients using the older version of the spec... */ - if (time == 0 && workspace) - { - meta_warning ("Received a NET_CURRENT_DESKTOP message " - "from a broken (outdated) client who sent " - "a 0 timestamp\n"); - time = meta_display_get_current_time_roundtrip (display); - } - - if (workspace) - meta_workspace_activate (workspace, time); - else - meta_verbose ("Don't know about workspace %d\n", space); - } - else if (event->xclient.message_type == - display->atom__NET_NUMBER_OF_DESKTOPS) - { - int num_spaces; - - num_spaces = event->xclient.data.l[0]; - - meta_verbose ("Request to set number of workspaces to %d\n", - num_spaces); - - meta_prefs_set_num_workspaces (num_spaces); - } - else if (event->xclient.message_type == - display->atom__NET_SHOWING_DESKTOP) - { - gboolean showing_desktop; - guint32 timestamp; - - showing_desktop = event->xclient.data.l[0] != 0; - /* FIXME: Braindead protocol doesn't have a timestamp */ - timestamp = meta_display_get_current_time_roundtrip (display); - meta_verbose ("Request to %s desktop\n", - showing_desktop ? "show" : "hide"); - - if (showing_desktop) - meta_screen_show_desktop (screen, timestamp); - else - { - meta_screen_unshow_desktop (screen); - meta_workspace_focus_default_window (screen->active_workspace, NULL, timestamp); - } - } - else if (event->xclient.message_type == - display->atom__MUFFIN_RELOAD_THEME_MESSAGE) - { - meta_verbose ("Received reload theme request\n"); - meta_ui_set_current_theme (meta_prefs_get_theme (), - TRUE); - meta_display_retheme_all (); - } - else if (event->xclient.message_type == - display->atom__MUFFIN_SET_KEYBINDINGS_MESSAGE) - { - meta_verbose ("Received set keybindings request = %d\n", - (int) event->xclient.data.l[0]); - meta_set_keybindings_disabled (!event->xclient.data.l[0]); - } - else if (event->xclient.message_type == - display->atom__MUFFIN_TOGGLE_VERBOSE) - { - meta_verbose ("Received toggle verbose message\n"); - meta_set_verbose (!meta_is_verbose ()); - } - else if (event->xclient.message_type == - display->atom_WM_PROTOCOLS) - { - meta_verbose ("Received WM_PROTOCOLS message\n"); - - if ((Atom)event->xclient.data.l[0] == display->atom__NET_WM_PING) - { - process_pong_message (display, event); - - /* We don't want ping reply events going into - * the GTK+ event loop because gtk+ will treat - * them as ping requests and send more replies. - */ - filter_out_event = TRUE; - } - } - } + logical_monitors = + meta_monitor_manager_get_logical_monitors (monitor_manager); + for (l = logical_monitors; l; l = l->next) + { + MetaLogicalMonitor *logical_monitor = l->data; + graphene_rect_t logical_monitor_rect = + meta_rectangle_to_graphene_rect (&logical_monitor->rect); - if (event->xclient.message_type == - display->atom__NET_REQUEST_FRAME_EXTENTS) - { - meta_verbose ("Received _NET_REQUEST_FRAME_EXTENTS message\n"); - process_request_frame_extents (display, event); - } - } - break; - case MappingNotify: - { - gboolean ignore_current; - - ignore_current = FALSE; - - /* Check whether the next event is an identical MappingNotify - * event. If it is, ignore the current event, we'll update - * when we get the next one. - */ - if (XPending (display->xdisplay)) - { - XEvent next_event; - - XPeekEvent (display->xdisplay, &next_event); - - if (next_event.type == MappingNotify && - next_event.xmapping.request == event->xmapping.request) - ignore_current = TRUE; - } - - if (!ignore_current) - { - /* Let XLib know that there is a new keyboard mapping. - */ - XRefreshKeyboardMapping (&event->xmapping); - meta_display_process_mapping_event (display, event); - } - } - break; - default: -#ifdef HAVE_XKB - if (event->type == display->xkb_base_event_type) - { - XkbAnyEvent *xkb_ev = (XkbAnyEvent *) event; - - switch (xkb_ev->xkb_type) - { - case XkbBellNotify: - if (XSERVER_TIME_IS_BEFORE(display->last_bell_time, - xkb_ev->time - 100)) - { - display->last_bell_time = xkb_ev->time; - meta_bell_notify (display, xkb_ev); - } - break; - case XkbNewKeyboardNotify: - case XkbMapNotify: - meta_display_process_mapping_event (display, event); - break; - } - } -#endif - break; - } + if (!graphene_rect_intersection (&cursor_rect, + &logical_monitor_rect, + NULL)) + continue; - if (!bypass_compositor) - { - if (meta_compositor_process_event (display->compositor, - event, - window)) - filter_out_event = TRUE; + highest_scale = MAX (highest_scale, logical_monitor->scale); } - display->current_time = CurrentTime; - return filter_out_event; + return highest_scale; } -/* Return the window this has to do with, if any, rather - * than the frame or root window that was selecting - * for substructure - */ -static Window -event_get_modified_window (MetaDisplay *display, - XEvent *event) +static void +root_cursor_prepare_at (MetaCursorSpriteXcursor *sprite_xcursor, + int x, + int y, + MetaDisplay *display) { - switch (event->type) + MetaCursorSprite *cursor_sprite = META_CURSOR_SPRITE (sprite_xcursor); + MetaBackend *backend = meta_get_backend (); + + if (meta_is_stage_views_scaled ()) { - case KeyPress: - case KeyRelease: - case ButtonPress: - case ButtonRelease: - case MotionNotify: - case FocusIn: - case FocusOut: - case KeymapNotify: - case Expose: - case GraphicsExpose: - case NoExpose: - case VisibilityNotify: - case ResizeRequest: - case PropertyNotify: - case SelectionClear: - case SelectionRequest: - case SelectionNotify: - case ColormapNotify: - case ClientMessage: - case EnterNotify: - case LeaveNotify: - return event->xany.window; - - case CreateNotify: - return event->xcreatewindow.window; - - case DestroyNotify: - return event->xdestroywindow.window; - - case UnmapNotify: - return event->xunmap.window; - - case MapNotify: - return event->xmap.window; - - case MapRequest: - return event->xmaprequest.window; - - case ReparentNotify: - return event->xreparent.window; - - case ConfigureNotify: - return event->xconfigure.window; - - case ConfigureRequest: - return event->xconfigurerequest.window; - - case GravityNotify: - return event->xgravity.window; - - case CirculateNotify: - return event->xcirculate.window; - - case CirculateRequest: - return event->xcirculaterequest.window; - - case MappingNotify: - return None; + float scale; - default: -#ifdef HAVE_SHAPE - if (META_DISPLAY_HAS_SHAPE (display) && - event->type == (display->shape_event_base + ShapeNotify)) + scale = find_highest_logical_monitor_scale (backend, cursor_sprite); + if (scale != 0.0) { - XShapeEvent *sev = (XShapeEvent*) event; - return sev->window; + float ceiled_scale; + + ceiled_scale = ceilf (scale); + meta_cursor_sprite_xcursor_set_theme_scale (sprite_xcursor, + (int) ceiled_scale); + meta_cursor_sprite_set_texture_scale (cursor_sprite, + 1.0 / ceiled_scale); } -#endif + } + else + { + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaLogicalMonitor *logical_monitor; + + logical_monitor = + meta_monitor_manager_get_logical_monitor_at (monitor_manager, x, y); - return None; + /* Reload the cursor texture if the scale has changed. */ + if (logical_monitor) + { + meta_cursor_sprite_xcursor_set_theme_scale (sprite_xcursor, + logical_monitor->scale); + meta_cursor_sprite_set_texture_scale (cursor_sprite, 1.0); + } } } -static guint32 -event_get_time (MetaDisplay *display, - XEvent *event) +static void +manage_root_cursor_sprite_scale (MetaDisplay *display, + MetaCursorSpriteXcursor *sprite_xcursor) { - switch (event->type) - { - case KeyPress: - case KeyRelease: - return event->xkey.time; - - case ButtonPress: - case ButtonRelease: - return event->xbutton.time; - - case MotionNotify: - return event->xmotion.time; - - case PropertyNotify: - return event->xproperty.time; - - case SelectionClear: - case SelectionRequest: - case SelectionNotify: - return event->xselection.time; - - case EnterNotify: - case LeaveNotify: - return event->xcrossing.time; - - case FocusIn: - case FocusOut: - case KeymapNotify: - case Expose: - case GraphicsExpose: - case NoExpose: - case MapNotify: - case UnmapNotify: - case VisibilityNotify: - case ResizeRequest: - case ColormapNotify: - case ClientMessage: - case CreateNotify: - case DestroyNotify: - case MapRequest: - case ReparentNotify: - case ConfigureNotify: - case ConfigureRequest: - case GravityNotify: - case CirculateNotify: - case CirculateRequest: - case MappingNotify: - default: - return CurrentTime; - } + g_signal_connect_object (sprite_xcursor, + "prepare-at", + G_CALLBACK (root_cursor_prepare_at), + display, + 0); } -#ifdef WITH_VERBOSE_MODE -LOCAL_SYMBOL const char* -meta_event_detail_to_string (int d) +void +meta_display_reload_cursor (MetaDisplay *display) { - const char *detail = "???"; - switch (d) - { - /* We are an ancestor in the A<->B focus change relationship */ - case NotifyAncestor: - detail = "NotifyAncestor"; - break; - case NotifyDetailNone: - detail = "NotifyDetailNone"; - break; - /* We are a descendant in the A<->B focus change relationship */ - case NotifyInferior: - detail = "NotifyInferior"; - break; - case NotifyNonlinear: - detail = "NotifyNonlinear"; - break; - case NotifyNonlinearVirtual: - detail = "NotifyNonlinearVirtual"; - break; - case NotifyPointer: - detail = "NotifyPointer"; - break; - case NotifyPointerRoot: - detail = "NotifyPointerRoot"; - break; - case NotifyVirtual: - detail = "NotifyVirtual"; - break; - } + MetaCursor cursor = display->current_cursor; + MetaCursorSpriteXcursor *sprite_xcursor; + MetaBackend *backend = meta_get_backend (); + MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend); - return detail; -} -#endif /* WITH_VERBOSE_MODE */ + sprite_xcursor = meta_cursor_sprite_xcursor_new (cursor); -#ifdef WITH_VERBOSE_MODE -LOCAL_SYMBOL const char* -meta_event_mode_to_string (int m) -{ - const char *mode = "???"; - switch (m) - { - case NotifyNormal: - mode = "NotifyNormal"; - break; - case NotifyGrab: - mode = "NotifyGrab"; - break; - case NotifyUngrab: - mode = "NotifyUngrab"; - break; - /* not sure any X implementations are missing this, but - * it seems to be absent from some docs. - */ -#ifdef NotifyWhileGrabbed - case NotifyWhileGrabbed: - mode = "NotifyWhileGrabbed"; - break; -#endif - } + if (meta_is_wayland_compositor ()) + manage_root_cursor_sprite_scale (display, sprite_xcursor); + + meta_cursor_tracker_set_root_cursor (cursor_tracker, + META_CURSOR_SPRITE (sprite_xcursor)); + g_object_unref (sprite_xcursor); - return mode; + g_signal_emit (display, display_signals[CURSOR_UPDATED], 0, display); } -#endif /* WITH_VERBOSE_MODE */ -#ifdef WITH_VERBOSE_MODE -static const char* -stack_mode_to_string (int mode) +void +meta_display_set_cursor (MetaDisplay *display, + MetaCursor cursor) { - switch (mode) - { - case Above: - return "Above"; - case Below: - return "Below"; - case TopIf: - return "TopIf"; - case BottomIf: - return "BottomIf"; - case Opposite: - return "Opposite"; - } + if (cursor == display->current_cursor) + return; - return "Unknown"; + display->current_cursor = cursor; + meta_display_reload_cursor (display); } -#endif /* WITH_VERBOSE_MODE */ -#ifdef WITH_VERBOSE_MODE -static char* -key_event_description (Display *xdisplay, - XEvent *event) +void +meta_display_update_cursor (MetaDisplay *display) { - KeySym keysym; - const char *str; - - keysym = XkbKeycodeToKeysym (xdisplay, event->xkey.keycode, 0, 0); - - str = XKeysymToString (keysym); - - return g_strdup_printf ("Key '%s' state 0x%x", - str ? str : "none", event->xkey.state); + meta_display_set_cursor (display, meta_cursor_for_grab_op (display->grab_op)); } -#endif /* WITH_VERBOSE_MODE */ -#ifdef HAVE_XSYNC -#ifdef WITH_VERBOSE_MODE -static gint64 -sync_value_to_64 (const XSyncValue *value) +static MetaWindow * +get_first_freefloating_window (MetaWindow *window) { - gint64 v; + while (meta_window_is_attached_dialog (window)) + window = meta_window_get_transient_for (window); - v = XSyncValueLow32 (*value); - v |= (((gint64)XSyncValueHigh32 (*value)) << 32); + /* Attached dialogs should always have a non-NULL transient-for */ + g_assert (window != NULL); - return v; + return window; } -#endif /* WITH_VERBOSE_MODE */ -#ifdef WITH_VERBOSE_MODE -static const char* -alarm_state_to_string (XSyncAlarmState state) +static MetaEventRoute +get_event_route_from_grab_op (MetaGrabOp op) { - switch (state) + switch (META_GRAB_OP_GET_BASE_TYPE (op)) { - case XSyncAlarmActive: - return "Active"; - case XSyncAlarmInactive: - return "Inactive"; - case XSyncAlarmDestroyed: - return "Destroyed"; + case META_GRAB_OP_NONE: + /* begin_grab_op shouldn't be called with META_GRAB_OP_NONE. */ + g_assert_not_reached (); + + case META_GRAB_OP_WINDOW_BASE: + return META_EVENT_ROUTE_WINDOW_OP; + + case META_GRAB_OP_COMPOSITOR: + /* begin_grab_op shouldn't be called with META_GRAB_OP_COMPOSITOR. */ + g_assert_not_reached (); + + case META_GRAB_OP_WAYLAND_POPUP: + return META_EVENT_ROUTE_WAYLAND_POPUP; + + case META_GRAB_OP_FRAME_BUTTON: + return META_EVENT_ROUTE_FRAME_BUTTON; + default: - return "(unknown)"; + g_assert_not_reached (); + return 0; } } -#endif /* WITH_VERBOSE_MODE */ -#endif /* HAVE_XSYNC */ - -#ifdef WITH_VERBOSE_MODE -static void -meta_spew_event (MetaDisplay *display, - XEvent *event) +gboolean +meta_display_begin_grab_op (MetaDisplay *display, + MetaWindow *window, + MetaGrabOp op, + gboolean pointer_already_grabbed, + gboolean frame_action, + int button, + gulong modmask, /* XXX - ignored */ + guint32 timestamp, + int root_x, + int root_y) { - const char *name = NULL; - char *extra = NULL; - char *winname; - MetaScreen *screen; + MetaBackend *backend = meta_get_backend (); + MetaWindow *grab_window = NULL; + MetaEventRoute event_route; - if (!meta_is_verbose()) - return; + g_assert (window != NULL); - /* filter overnumerous events */ - if (event->type == Expose || event->type == MotionNotify || - event->type == NoExpose) - return; + meta_topic (META_DEBUG_WINDOW_OPS, + "Doing grab op %u on window %s button %d pointer already grabbed: %d pointer pos %d,%d\n", + op, window->desc, button, pointer_already_grabbed, + root_x, root_y); - switch (event->type) + if (display->grab_op != META_GRAB_OP_NONE) { - case KeyPress: - name = "KeyPress"; - extra = key_event_description (display->xdisplay, event); - break; - case KeyRelease: - name = "KeyRelease"; - extra = key_event_description (display->xdisplay, event); - break; - case ButtonPress: - name = "ButtonPress"; - extra = g_strdup_printf ("button %u state 0x%x x %d y %d root 0x%lx same_screen %d", - event->xbutton.button, - event->xbutton.state, - event->xbutton.x, - event->xbutton.y, - event->xbutton.root, - event->xbutton.same_screen); - break; - case ButtonRelease: - name = "ButtonRelease"; - extra = g_strdup_printf ("button %u state 0x%x x %d y %d root 0x%lx same_screen %d", - event->xbutton.button, - event->xbutton.state, - event->xbutton.x, - event->xbutton.y, - event->xbutton.root, - event->xbutton.same_screen); - break; - case MotionNotify: - name = "MotionNotify"; - extra = g_strdup_printf ("win: 0x%lx x: %d y: %d", - event->xmotion.window, - event->xmotion.x, - event->xmotion.y); - break; - case EnterNotify: - name = "EnterNotify"; - extra = g_strdup_printf ("win: 0x%lx root: 0x%lx subwindow: 0x%lx mode: %s detail: %s focus: %d x: %d y: %d", - event->xcrossing.window, - event->xcrossing.root, - event->xcrossing.subwindow, - meta_event_mode_to_string (event->xcrossing.mode), - meta_event_detail_to_string (event->xcrossing.detail), - event->xcrossing.focus, - event->xcrossing.x, - event->xcrossing.y); - break; - case LeaveNotify: - name = "LeaveNotify"; - extra = g_strdup_printf ("win: 0x%lx root: 0x%lx subwindow: 0x%lx mode: %s detail: %s focus: %d x: %d y: %d", - event->xcrossing.window, - event->xcrossing.root, - event->xcrossing.subwindow, - meta_event_mode_to_string (event->xcrossing.mode), - meta_event_detail_to_string (event->xcrossing.detail), - event->xcrossing.focus, - event->xcrossing.x, - event->xcrossing.y); - break; - case FocusIn: - name = "FocusIn"; - extra = g_strdup_printf ("detail: %s mode: %s\n", - meta_event_detail_to_string (event->xfocus.detail), - meta_event_mode_to_string (event->xfocus.mode)); - break; - case FocusOut: - name = "FocusOut"; - extra = g_strdup_printf ("detail: %s mode: %s\n", - meta_event_detail_to_string (event->xfocus.detail), - meta_event_mode_to_string (event->xfocus.mode)); - break; - case KeymapNotify: - name = "KeymapNotify"; - break; - case Expose: - name = "Expose"; - break; - case GraphicsExpose: - name = "GraphicsExpose"; - break; - case NoExpose: - name = "NoExpose"; - break; - case VisibilityNotify: - name = "VisibilityNotify"; - break; - case CreateNotify: - name = "CreateNotify"; - extra = g_strdup_printf ("parent: 0x%lx window: 0x%lx", - event->xcreatewindow.parent, - event->xcreatewindow.window); - break; - case DestroyNotify: - name = "DestroyNotify"; - extra = g_strdup_printf ("event: 0x%lx window: 0x%lx", - event->xdestroywindow.event, - event->xdestroywindow.window); - break; - case UnmapNotify: - name = "UnmapNotify"; - extra = g_strdup_printf ("event: 0x%lx window: 0x%lx from_configure: %d", - event->xunmap.event, - event->xunmap.window, - event->xunmap.from_configure); - break; - case MapNotify: - name = "MapNotify"; - extra = g_strdup_printf ("event: 0x%lx window: 0x%lx override_redirect: %d", - event->xmap.event, - event->xmap.window, - event->xmap.override_redirect); - break; - case MapRequest: - name = "MapRequest"; - extra = g_strdup_printf ("window: 0x%lx parent: 0x%lx\n", - event->xmaprequest.window, - event->xmaprequest.parent); - break; - case ReparentNotify: - name = "ReparentNotify"; - extra = g_strdup_printf ("window: 0x%lx parent: 0x%lx event: 0x%lx\n", - event->xreparent.window, - event->xreparent.parent, - event->xreparent.event); - break; - case ConfigureNotify: - name = "ConfigureNotify"; - extra = g_strdup_printf ("x: %d y: %d w: %d h: %d above: 0x%lx override_redirect: %d", - event->xconfigure.x, - event->xconfigure.y, - event->xconfigure.width, - event->xconfigure.height, - event->xconfigure.above, - event->xconfigure.override_redirect); - break; - case ConfigureRequest: - name = "ConfigureRequest"; - extra = g_strdup_printf ("parent: 0x%lx window: 0x%lx x: %d %sy: %d %sw: %d %sh: %d %sborder: %d %sabove: %lx %sstackmode: %s %s", - event->xconfigurerequest.parent, - event->xconfigurerequest.window, - event->xconfigurerequest.x, - event->xconfigurerequest.value_mask & - CWX ? "" : "(unset) ", - event->xconfigurerequest.y, - event->xconfigurerequest.value_mask & - CWY ? "" : "(unset) ", - event->xconfigurerequest.width, - event->xconfigurerequest.value_mask & - CWWidth ? "" : "(unset) ", - event->xconfigurerequest.height, - event->xconfigurerequest.value_mask & - CWHeight ? "" : "(unset) ", - event->xconfigurerequest.border_width, - event->xconfigurerequest.value_mask & - CWBorderWidth ? "" : "(unset)", - event->xconfigurerequest.above, - event->xconfigurerequest.value_mask & - CWSibling ? "" : "(unset)", - stack_mode_to_string (event->xconfigurerequest.detail), - event->xconfigurerequest.value_mask & - CWStackMode ? "" : "(unset)"); - break; - case GravityNotify: - name = "GravityNotify"; - break; - case ResizeRequest: - name = "ResizeRequest"; - extra = g_strdup_printf ("width = %d height = %d", - event->xresizerequest.width, - event->xresizerequest.height); - break; - case CirculateNotify: - name = "CirculateNotify"; - break; - case CirculateRequest: - name = "CirculateRequest"; - break; - case PropertyNotify: - { - char *str; - const char *state; - - name = "PropertyNotify"; - - meta_error_trap_push (display); - str = XGetAtomName (display->xdisplay, - event->xproperty.atom); - meta_error_trap_pop (display); - - if (event->xproperty.state == PropertyNewValue) - state = "PropertyNewValue"; - else if (event->xproperty.state == PropertyDelete) - state = "PropertyDelete"; - else - state = "???"; - - extra = g_strdup_printf ("atom: %s state: %s", - str ? str : "(unknown atom)", - state); - meta_XFree (str); - } - break; - case SelectionClear: - name = "SelectionClear"; - break; - case SelectionRequest: - name = "SelectionRequest"; - break; - case SelectionNotify: - name = "SelectionNotify"; - break; - case ColormapNotify: - name = "ColormapNotify"; - break; - case ClientMessage: - { - char *str; - name = "ClientMessage"; - meta_error_trap_push (display); - str = XGetAtomName (display->xdisplay, - event->xclient.message_type); - meta_error_trap_pop (display); - extra = g_strdup_printf ("type: %s format: %d\n", - str ? str : "(unknown atom)", - event->xclient.format); - meta_XFree (str); - } - break; - case MappingNotify: - name = "MappingNotify"; - break; - default: -#ifdef HAVE_XSYNC - if (META_DISPLAY_HAS_XSYNC (display) && - event->type == (display->xsync_event_base + XSyncAlarmNotify)) - { - XSyncAlarmNotifyEvent *aevent = (XSyncAlarmNotifyEvent*) event; - - name = "XSyncAlarmNotify"; - extra = - g_strdup_printf ("alarm: 0x%lx" - " counter_value: %" G_GINT64_FORMAT - " alarm_value: %" G_GINT64_FORMAT - " time: %u alarm state: %s", - aevent->alarm, - (gint64) sync_value_to_64 (&aevent->counter_value), - (gint64) sync_value_to_64 (&aevent->alarm_value), - (unsigned int)aevent->time, - alarm_state_to_string (aevent->state)); - } + meta_warning ("Attempt to perform window operation %u on window %s when operation %u on %s already in effect\n", + op, window->desc, display->grab_op, + display->grab_window ? display->grab_window->desc : "none"); + return FALSE; + } + + event_route = get_event_route_from_grab_op (op); + + if (event_route == META_EVENT_ROUTE_WINDOW_OP) + { + if (meta_prefs_get_raise_on_click ()) + meta_window_raise (window); else -#endif /* HAVE_XSYNC */ -#ifdef HAVE_SHAPE - if (META_DISPLAY_HAS_SHAPE (display) && - event->type == (display->shape_event_base + ShapeNotify)) - { - XShapeEvent *sev = (XShapeEvent*) event; - - name = "ShapeNotify"; - - extra = - g_strdup_printf ("kind: %s " - "x: %d y: %d w: %u h: %u " - "shaped: %d", - sev->kind == ShapeBounding ? - "ShapeBounding" : - (sev->kind == ShapeClip ? - "ShapeClip" : "(unknown)"), - sev->x, sev->y, sev->width, sev->height, - sev->shaped); - } - else -#endif /* HAVE_SHAPE */ { - name = "(Unknown event)"; - extra = g_strdup_printf ("type: %d", event->xany.type); + display->grab_initial_x = root_x; + display->grab_initial_y = root_y; + display->grab_threshold_movement_reached = FALSE; } - break; } - screen = meta_display_screen_for_root (display, event->xany.window); + grab_window = window; - if (screen) - winname = g_strdup_printf ("root %d", screen->number); - else - winname = g_strdup_printf ("0x%lx", event->xany.window); - - meta_topic (META_DEBUG_EVENTS, - "%s on %s%s %s %sserial %lu\n", name, winname, - extra ? ":" : "", extra ? extra : "", - event->xany.send_event ? "SEND " : "", - event->xany.serial); + /* If we're trying to move a window, move the first + * non-attached dialog instead. + */ + if (meta_grab_op_is_moving (op)) + grab_window = get_first_freefloating_window (window); - free (winname); + g_assert (grab_window != NULL); + g_assert (op != META_GRAB_OP_NONE); - if (extra) - free (extra); -} -#endif /* WITH_VERBOSE_MODE */ + display->grab_have_pointer = FALSE; -LOCAL_SYMBOL MetaWindow* -meta_display_lookup_x_window (MetaDisplay *display, - Window xwindow) -{ - return g_hash_table_lookup (display->window_ids, &xwindow); -} + if (pointer_already_grabbed) + display->grab_have_pointer = TRUE; -LOCAL_SYMBOL void -meta_display_register_x_window (MetaDisplay *display, - Window *xwindowp, - MetaWindow *window) -{ - g_return_if_fail (g_hash_table_lookup (display->window_ids, xwindowp) == NULL); + if (META_IS_BACKEND_X11 (meta_get_backend ()) && display->x11_display) + { + /* Since grab operations often happen as a result of implicit + * pointer operations on the display X11 connection, we need + * to ungrab here to ensure that the backend's X11 can take + * the device grab. */ + XIUngrabDevice (display->x11_display->xdisplay, + META_VIRTUAL_CORE_POINTER_ID, + timestamp); + XSync (display->x11_display->xdisplay, False); + } - g_hash_table_insert (display->window_ids, xwindowp, window); -} + if (meta_backend_grab_device (backend, META_VIRTUAL_CORE_POINTER_ID, timestamp)) + display->grab_have_pointer = TRUE; -LOCAL_SYMBOL void -meta_display_unregister_x_window (MetaDisplay *display, - Window xwindow) -{ - g_return_if_fail (g_hash_table_lookup (display->window_ids, &xwindow) != NULL); - - g_hash_table_remove (display->window_ids, &xwindow); - - /* Remove any pending pings */ - remove_pending_pings_for_window (display, xwindow); -} - -LOCAL_SYMBOL void -meta_display_notify_window_created (MetaDisplay *display, - MetaWindow *window) -{ - g_signal_emit (display, display_signals[WINDOW_CREATED], 0, window); -} - -/** - * meta_display_xwindow_is_a_no_focus_window: - * @display: A #MetaDisplay - * @xwindow: An X11 window - * - * Returns %TRUE iff window is one of muffin's internal "no focus" windows - * (there is one per screen) which will have the focus when there is no - * actual client window focused. - */ -gboolean -meta_display_xwindow_is_a_no_focus_window (MetaDisplay *display, - Window xwindow) -{ - gboolean is_a_no_focus_window = FALSE; - GSList *temp = display->screens; - while (temp != NULL) { - MetaScreen *screen = temp->data; - if (screen->no_focus_window == xwindow) { - is_a_no_focus_window = TRUE; - break; - } - temp = temp->next; - } - - return is_a_no_focus_window; -} - -LOCAL_SYMBOL Cursor -meta_display_create_x_cursor (MetaDisplay *display, - MetaCursor cursor) -{ - Cursor xcursor; - guint glyph; - - switch (cursor) - { - case META_CURSOR_DEFAULT: - glyph = XC_left_ptr; - break; - case META_CURSOR_NORTH_RESIZE: - glyph = XC_top_side; - break; - case META_CURSOR_SOUTH_RESIZE: - glyph = XC_bottom_side; - break; - case META_CURSOR_WEST_RESIZE: - glyph = XC_left_side; - break; - case META_CURSOR_EAST_RESIZE: - glyph = XC_right_side; - break; - case META_CURSOR_SE_RESIZE: - glyph = XC_bottom_right_corner; - break; - case META_CURSOR_SW_RESIZE: - glyph = XC_bottom_left_corner; - break; - case META_CURSOR_NE_RESIZE: - glyph = XC_top_right_corner; - break; - case META_CURSOR_NW_RESIZE: - glyph = XC_top_left_corner; - break; - case META_CURSOR_MOVE_OR_RESIZE_WINDOW: - glyph = XC_fleur; - break; - case META_CURSOR_BUSY: - glyph = XC_watch; - break; - - default: - g_assert_not_reached (); - glyph = 0; /* silence compiler */ - break; - } - - xcursor = XCreateFontCursor (display->xdisplay, glyph); - - return xcursor; -} - -static Cursor -xcursor_for_op (MetaDisplay *display, - MetaGrabOp op) -{ - MetaCursor cursor = META_CURSOR_DEFAULT; - - switch (op) - { - case META_GRAB_OP_RESIZING_SE: - case META_GRAB_OP_KEYBOARD_RESIZING_SE: - cursor = META_CURSOR_SE_RESIZE; - break; - case META_GRAB_OP_RESIZING_S: - case META_GRAB_OP_KEYBOARD_RESIZING_S: - cursor = META_CURSOR_SOUTH_RESIZE; - break; - case META_GRAB_OP_RESIZING_SW: - case META_GRAB_OP_KEYBOARD_RESIZING_SW: - cursor = META_CURSOR_SW_RESIZE; - break; - case META_GRAB_OP_RESIZING_N: - case META_GRAB_OP_KEYBOARD_RESIZING_N: - cursor = META_CURSOR_NORTH_RESIZE; - break; - case META_GRAB_OP_RESIZING_NE: - case META_GRAB_OP_KEYBOARD_RESIZING_NE: - cursor = META_CURSOR_NE_RESIZE; - break; - case META_GRAB_OP_RESIZING_NW: - case META_GRAB_OP_KEYBOARD_RESIZING_NW: - cursor = META_CURSOR_NW_RESIZE; - break; - case META_GRAB_OP_RESIZING_W: - case META_GRAB_OP_KEYBOARD_RESIZING_W: - cursor = META_CURSOR_WEST_RESIZE; - break; - case META_GRAB_OP_RESIZING_E: - case META_GRAB_OP_KEYBOARD_RESIZING_E: - cursor = META_CURSOR_EAST_RESIZE; - break; - case META_GRAB_OP_MOVING: - case META_GRAB_OP_KEYBOARD_MOVING: - case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN: - cursor = META_CURSOR_MOVE_OR_RESIZE_WINDOW; - break; - - default: - break; - } - - if (cursor == META_CURSOR_DEFAULT) - return None; - return meta_display_create_x_cursor (display, cursor); -} - -LOCAL_SYMBOL void -meta_display_set_grab_op_cursor (MetaDisplay *display, - MetaScreen *screen, - MetaGrabOp op, - gboolean change_pointer, - Window grab_xwindow, - guint32 timestamp) -{ - Cursor cursor; - - cursor = xcursor_for_op (display, op); - -#define GRAB_MASK (PointerMotionMask | \ - ButtonPressMask | ButtonReleaseMask | \ - EnterWindowMask | LeaveWindowMask) - - if (change_pointer) - { - meta_error_trap_push_with_return (display); - XChangeActivePointerGrab (display->xdisplay, - GRAB_MASK, - cursor, - timestamp); - - meta_topic (META_DEBUG_WINDOW_OPS, - "Changed pointer with XChangeActivePointerGrab()\n"); - - if (meta_error_trap_pop_with_return (display) != Success) - { - meta_topic (META_DEBUG_WINDOW_OPS, - "Error trapped from XChangeActivePointerGrab()\n"); - if (display->grab_have_pointer) - display->grab_have_pointer = FALSE; - } - } - else - { - g_assert (screen != NULL); - - meta_error_trap_push (display); - if (XGrabPointer (display->xdisplay, - grab_xwindow, - False, - GRAB_MASK, - GrabModeAsync, GrabModeAsync, - screen->xroot, - cursor, - timestamp) == GrabSuccess) - { - display->grab_have_pointer = TRUE; - meta_topic (META_DEBUG_WINDOW_OPS, - "XGrabPointer() returned GrabSuccess time %u\n", - timestamp); - } -#ifdef WITH_VERBOSE_MODE - else - { - meta_topic (META_DEBUG_WINDOW_OPS, - "XGrabPointer() failed time %u\n", - timestamp); - } -#endif - meta_error_trap_pop (display); - } - -#undef GRAB_MASK - - if (cursor != None) - XFreeCursor (display->xdisplay, cursor); -} - -gboolean -meta_display_begin_grab_op (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - MetaGrabOp op, - gboolean pointer_already_grabbed, - gboolean frame_action, - int button, - gulong modmask, - guint32 timestamp, - int root_x, - int root_y) -{ - MetaWindow *grab_window = NULL; - Window grab_xwindow; - - meta_topic (META_DEBUG_WINDOW_OPS, - "Doing grab op %u on window %s button %d pointer already grabbed: %d pointer pos %d,%d\n", - op, window ? window->desc : "none", button, pointer_already_grabbed, - root_x, root_y); - - if (display->grab_op != META_GRAB_OP_NONE) - { - if (window) - meta_warning ("Attempt to perform window operation %u on window %s when operation %u on %s already in effect\n", - op, window->desc, display->grab_op, - display->grab_window ? display->grab_window->desc : "none"); - return FALSE; - } - - if (window && - (meta_grab_op_is_moving (op) || meta_grab_op_is_resizing (op))) - { - if (meta_prefs_get_raise_on_click ()) - meta_window_raise (window); - else - { - display->grab_initial_x = root_x; - display->grab_initial_y = root_y; - display->grab_threshold_movement_reached = FALSE; - } - } - - /* If window is a modal dialog attached to its parent, - * grab the parent instead for moving. - */ - if (window && meta_window_is_attached_dialog (window) && - meta_grab_op_is_moving (op)) - grab_window = meta_window_get_transient_for (window); - - if (grab_window == NULL) - grab_window = window; - - /* FIXME: - * If we have no MetaWindow we do our best - * and try to do the grab on the RootWindow. - * This will fail if anyone else has any - * key grab on the RootWindow. - */ - if (grab_window) - grab_xwindow = grab_window->frame ? grab_window->frame->xwindow : grab_window->xwindow; - else - grab_xwindow = screen->xroot; - - display->grab_have_pointer = FALSE; - - if (pointer_already_grabbed) - display->grab_have_pointer = TRUE; - - meta_display_set_grab_op_cursor (display, screen, op, FALSE, grab_xwindow, - timestamp); - - if (!display->grab_have_pointer && !grab_op_is_keyboard (op)) + if (!display->grab_have_pointer && !meta_grab_op_is_keyboard (op)) { - meta_topic (META_DEBUG_WINDOW_OPS, - "XGrabPointer() failed\n"); + meta_topic (META_DEBUG_WINDOW_OPS, "XIGrabDevice() failed\n"); return FALSE; } - /* Grab keys for keyboard ops and mouse move/resizes; see #126497 */ - if (grab_op_is_keyboard (op) || grab_op_is_mouse_only (op)) + /* Grab keys when beginning window ops; see #126497 */ + if (event_route == META_EVENT_ROUTE_WINDOW_OP) { - if (grab_window) - display->grab_have_keyboard = - meta_window_grab_all_keys (grab_window, timestamp); - - else - display->grab_have_keyboard = - meta_screen_grab_all_keys (screen, timestamp); + display->grab_have_keyboard = meta_window_grab_all_keys (grab_window, timestamp); if (!display->grab_have_keyboard) { - meta_topic (META_DEBUG_WINDOW_OPS, - "grabbing all keys failed, ungrabbing pointer\n"); - XUngrabPointer (display->xdisplay, timestamp); + meta_topic (META_DEBUG_WINDOW_OPS, "grabbing all keys failed, ungrabbing pointer\n"); + meta_backend_ungrab_device (backend, META_VIRTUAL_CORE_POINTER_ID, timestamp); display->grab_have_pointer = FALSE; return FALSE; } } + display->event_route = event_route; display->grab_op = op; display->grab_window = grab_window; - display->grab_screen = screen; - display->grab_xwindow = grab_xwindow; display->grab_button = button; - display->grab_mask = modmask; - if (window) - { - display->grab_tile_mode = window->tile_mode; - display->grab_tile_monitor_number = window->tile_monitor_number; - } - else - { - display->grab_tile_mode = META_TILE_NONE; - display->grab_tile_monitor_number = -1; - } + display->grab_tile_mode = grab_window->tile_mode; + display->grab_tile_monitor_number = grab_window->tile_monitor_number; display->grab_anchor_root_x = root_x; display->grab_anchor_root_y = root_y; display->grab_latest_motion_x = root_x; display->grab_latest_motion_y = root_y; - display->grab_last_moveresize_time.tv_sec = 0; - display->grab_last_moveresize_time.tv_usec = 0; - display->grab_motion_notify_time = 0; - display->grab_old_window_stacking = NULL; -#ifdef HAVE_XSYNC + display->grab_last_moveresize_time = 0; display->grab_last_user_action_was_snap = FALSE; -#endif display->grab_frame_action = frame_action; - display->grab_resize_unmaximize = 0; - - if (display->grab_resize_timeout_id) - { - g_source_remove (display->grab_resize_timeout_id); - display->grab_resize_timeout_id = 0; - } - if (display->grab_window) - { - meta_window_get_client_root_coords (display->grab_window, - &display->grab_initial_window_pos); - display->grab_anchor_window_pos = display->grab_initial_window_pos; + meta_display_update_cursor (display); -#ifdef HAVE_XSYNC - if ( meta_grab_op_is_resizing (display->grab_op) && - display->grab_window->sync_request_counter != None) - { - meta_window_create_sync_request_alarm (display->grab_window); - } -#endif - } + g_clear_handle_id (&display->grab_resize_timeout_id, g_source_remove); meta_topic (META_DEBUG_WINDOW_OPS, "Grab op %u on window %s successful\n", display->grab_op, window ? window->desc : "(null)"); - g_assert (display->grab_window != NULL || display->grab_screen != NULL); - g_assert (display->grab_op != META_GRAB_OP_NONE); - - /* Save the old stacking */ - if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op)) - { - meta_topic (META_DEBUG_WINDOW_OPS, - "Saving old stack positions; old pointer was %p.\n", - display->grab_old_window_stacking); - display->grab_old_window_stacking = - meta_stack_get_positions (screen->stack); - } + meta_window_get_frame_rect (display->grab_window, + &display->grab_initial_window_pos); + display->grab_anchor_window_pos = display->grab_initial_window_pos; - if (display->grab_window) + if (meta_is_wayland_compositor ()) { - meta_window_refresh_resize_popup (display->grab_window); + meta_display_sync_wayland_input_focus (display); + meta_display_cancel_touch (display); } - meta_compositor_grab_op_begin (display->compositor); - g_signal_emit (display, display_signals[GRAB_OP_BEGIN], 0, - screen, display->grab_window, display->grab_op); - - return TRUE; -} - -#ifdef HAVE_XSYNC -/* We store sync alarms in the window ID hash table, because they are - * just more types of XIDs in the same global space, but we have - * typesafe functions to register/unregister for readability. - */ - -MetaWindow* -meta_display_lookup_sync_alarm (MetaDisplay *display, - XSyncAlarm alarm) -{ - return g_hash_table_lookup (display->window_ids, &alarm); -} + display, display->grab_window, display->grab_op); -void -meta_display_register_sync_alarm (MetaDisplay *display, - XSyncAlarm *alarmp, - MetaWindow *window) -{ - g_return_if_fail (g_hash_table_lookup (display->window_ids, alarmp) == NULL); - - g_hash_table_insert (display->window_ids, alarmp, window); -} - -void -meta_display_unregister_sync_alarm (MetaDisplay *display, - XSyncAlarm alarm) -{ - g_return_if_fail (g_hash_table_lookup (display->window_ids, &alarm) != NULL); + if (display->event_route == META_EVENT_ROUTE_WINDOW_OP) + meta_window_grab_op_began (display->grab_window, display->grab_op); - g_hash_table_remove (display->window_ids, &alarm); + return TRUE; } -#endif /* HAVE_XSYNC */ void meta_display_end_grab_op (MetaDisplay *display, guint32 timestamp) { + MetaWindow *grab_window = display->grab_window; + MetaGrabOp grab_op = display->grab_op; + meta_topic (META_DEBUG_WINDOW_OPS, - "Ending grab op %u at time %u\n", display->grab_op, timestamp); - - if (display->grab_op == META_GRAB_OP_NONE) - return; + "Ending grab op %u at time %u\n", grab_op, timestamp); - meta_compositor_grab_op_end (display->compositor); + if (display->event_route == META_EVENT_ROUTE_NORMAL || + display->event_route == META_EVENT_ROUTE_COMPOSITOR_GRAB) + return; - g_signal_emit (display, display_signals[GRAB_OP_END], 0, - display->grab_screen, display->grab_window, display->grab_op); + g_assert (grab_window != NULL); - if (display->grab_window != NULL) - display->grab_window->shaken_loose = FALSE; + /* We need to reset this early, since the + * meta_window_grab_op_ended callback relies on this being + * up to date. */ + display->grab_op = META_GRAB_OP_NONE; - if (display->grab_window != NULL && - !meta_prefs_get_raise_on_click () && - (meta_grab_op_is_moving (display->grab_op) || - meta_grab_op_is_resizing (display->grab_op))) + if (display->event_route == META_EVENT_ROUTE_WINDOW_OP) { + /* Clear out the edge cache */ + meta_display_cleanup_edges (display); + /* Only raise the window in orthogonal raise * ('do-not-raise-on-click') mode if the user didn't try to move * or resize the given window by at least a threshold amount. * For raise on click mode, the window was raised at the * beginning of the grab_op. */ - if (!display->grab_threshold_movement_reached) + if (!meta_prefs_get_raise_on_click () && + !display->grab_threshold_movement_reached) meta_window_raise (display->grab_window); - } - - if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op) || - display->grab_op == META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING) - { - /* If the ungrab here causes an EnterNotify, ignore it for - * sloppy focus - */ - display->ungrab_should_not_cause_focus_window = display->grab_xwindow; - } - - /* If this was a move or resize clear out the edge cache */ - if (meta_grab_op_is_resizing (display->grab_op) || - meta_grab_op_is_moving (display->grab_op)) - { - meta_topic (META_DEBUG_WINDOW_OPS, - "Clearing out the edges for resistance/snapping\n"); - meta_display_cleanup_edges (display); - } - if (display->grab_old_window_stacking != NULL) - { - meta_topic (META_DEBUG_WINDOW_OPS, - "Clearing out the old stack position, which was %p.\n", - display->grab_old_window_stacking); - g_list_free (display->grab_old_window_stacking); - display->grab_old_window_stacking = NULL; + meta_window_grab_op_ended (grab_window, grab_op); } if (display->grab_have_pointer) { - meta_topic (META_DEBUG_WINDOW_OPS, - "Ungrabbing pointer with timestamp %u\n", timestamp); - XUngrabPointer (display->xdisplay, timestamp); + MetaBackend *backend = meta_get_backend (); + meta_backend_ungrab_device (backend, META_VIRTUAL_CORE_POINTER_ID, timestamp); } if (display->grab_have_keyboard) { meta_topic (META_DEBUG_WINDOW_OPS, "Ungrabbing all keys timestamp %u\n", timestamp); - if (display->grab_window) - meta_window_ungrab_all_keys (display->grab_window, timestamp); - else - meta_screen_ungrab_all_keys (display->grab_screen, timestamp); + meta_window_ungrab_all_keys (grab_window, timestamp); } - if (display->grab_window && - display->grab_window->resizing_tile_type != META_WINDOW_TILE_TYPE_NONE) { - display->grab_window->snap_queued = display->grab_window->resizing_tile_type == META_WINDOW_TILE_TYPE_SNAPPED; - display->grab_window->tile_mode = display->grab_window->resize_tile_mode; - display->grab_window->custom_snap_size = TRUE; - meta_window_real_tile (display->grab_window, TRUE); - } - - meta_screen_hide_hud_and_preview (display->grab_screen); - + display->event_route = META_EVENT_ROUTE_NORMAL; display->grab_window = NULL; - display->grab_screen = NULL; - display->grab_xwindow = None; display->grab_tile_mode = META_TILE_NONE; display->grab_tile_monitor_number = -1; - display->grab_op = META_GRAB_OP_NONE; - if (display->grab_resize_popup) - { - meta_ui_resize_popup_free (display->grab_resize_popup); - display->grab_resize_popup = NULL; - } + meta_display_update_cursor (display); - if (display->grab_resize_timeout_id) - { - g_source_remove (display->grab_resize_timeout_id); - display->grab_resize_timeout_id = 0; - } + g_clear_handle_id (&display->grab_resize_timeout_id, g_source_remove); + + if (meta_is_wayland_compositor ()) + meta_display_sync_wayland_input_focus (display); + + g_signal_emit (display, display_signals[GRAB_OP_END], 0, + display, grab_window, grab_op); } /** * meta_display_get_grab_op: + * @display: The #MetaDisplay that the window is on + * Gets the current grab operation, if any. * * Return value: the current grab operation, or %META_GRAB_OP_NONE if - * Muffin doesn't currently have a grab. %META_GRAB_OP_COMPOSITOR will + * Mutter doesn't currently have a grab. %META_GRAB_OP_COMPOSITOR will * be returned if a compositor-plugin modal operation is in effect - * (See muffin_begin_modal_for_plugin()) + * (See mutter_begin_modal_for_plugin()) */ MetaGrabOp meta_display_get_grab_op (MetaDisplay *display) @@ -3901,7 +2039,7 @@ meta_display_get_grab_op (MetaDisplay *display) return display->grab_op; } -LOCAL_SYMBOL void +void meta_display_check_threshold_reached (MetaDisplay *display, int x, int y) @@ -3916,354 +2054,29 @@ meta_display_check_threshold_reached (MetaDisplay *display, display->grab_threshold_movement_reached = TRUE; } -static void -meta_change_button_grab (MetaDisplay *display, - Window xwindow, - gboolean grab, - gboolean sync, - int button, - int modmask) +void +meta_display_queue_retheme_all_windows (MetaDisplay *display) { - unsigned int ignored_mask; - - meta_verbose ("%s 0x%lx sync = %d button = %d modmask 0x%x\n", - grab ? "Grabbing" : "Ungrabbing", - xwindow, - sync, button, modmask); - - meta_error_trap_push (display); + GSList* windows; + GSList *tmp; - ignored_mask = 0; - while (ignored_mask <= display->ignored_modifier_mask) + windows = meta_display_list_windows (display, META_LIST_DEFAULT); + tmp = windows; + while (tmp != NULL) { - if (ignored_mask & ~(display->ignored_modifier_mask)) - { - /* Not a combination of ignored modifiers - * (it contains some non-ignored modifiers) - */ - ++ignored_mask; - continue; - } - - if (meta_is_debugging ()) - meta_error_trap_push_with_return (display); - - /* GrabModeSync means freeze until XAllowEvents */ - - if (grab) - XGrabButton (display->xdisplay, button, modmask | ignored_mask, - xwindow, False, - ButtonPressMask | ButtonReleaseMask | - PointerMotionMask | PointerMotionHintMask, - sync ? GrabModeSync : GrabModeAsync, - GrabModeAsync, - False, None); - else - XUngrabButton (display->xdisplay, button, modmask | ignored_mask, - xwindow); + MetaWindow *window = tmp->data; - if (meta_is_debugging ()) + meta_window_queue (window, META_QUEUE_MOVE_RESIZE); + meta_window_frame_size_changed (window); + if (window->frame) { - int result; - - result = meta_error_trap_pop_with_return (display); - - if (result != Success) - meta_verbose ("Failed to %s button %d with mask 0x%x for window 0x%lx error code %d\n", - grab ? "grab" : "ungrab", - button, modmask | ignored_mask, xwindow, result); + meta_frame_queue_draw (window->frame); } - ++ignored_mask; + tmp = tmp->next; } - meta_error_trap_pop (display); -} - -LOCAL_SYMBOL void -meta_display_grab_window_buttons (MetaDisplay *display, - Window xwindow) -{ - /* Grab Alt + button1 for moving window. - * Grab Alt + button2 for resizing window. - * Grab Alt + button3 for popping up window menu. - * Grab Alt + Shift + button1 for snap-moving window. - * Grab Alt + button4 for scrolling in - * Grab Alt + button5 for scrolling out - */ - meta_verbose ("Grabbing window buttons for 0x%lx\n", xwindow); - - /* FIXME If we ignored errors here instead of spewing, we could - * put one big error trap around the loop and avoid a bunch of - * XSync() - */ - gboolean debug = display->debug_button_grabs; - - if (display->window_grab_modifiers != 0) - { - int i; - for (i = 1; i < 4; i++) - { - meta_change_button_grab (display, xwindow, - TRUE, - FALSE, - i, display->window_grab_modifiers); - - /* This is for debugging, since I end up moving the Xnest - * otherwise ;-) - */ - if (debug) - meta_change_button_grab (display, xwindow, - TRUE, - FALSE, - i, ControlMask); - } - - /* In addition to grabbing Alt+Button1 for moving the window, - * grab Alt+Shift+Button1 for snap-moving the window. See bug - * 112478. Unfortunately, this doesn't work with - * Shift+Alt+Button1 for some reason; so at least part of the - * order still matters, which sucks (please FIXME). - */ - meta_change_button_grab (display, xwindow, - TRUE, - FALSE, - 1, display->window_grab_modifiers | ShiftMask); - } - - if (display->mouse_zoom_enabled && display->mouse_zoom_modifiers != 0) - { - int i; - for (i = 4; i < 6; i++) - { - meta_change_button_grab (display, xwindow, - TRUE, - FALSE, - i, display->mouse_zoom_modifiers); - - /* This is for debugging, since I end up moving the Xnest - * otherwise ;-) - */ - if (debug) - meta_change_button_grab (display, xwindow, - TRUE, - FALSE, - i, ControlMask); - } - } -} - -LOCAL_SYMBOL void -meta_display_ungrab_window_buttons (MetaDisplay *display, - Window xwindow) -{ - gboolean debug; - int i; - - if (display->window_grab_modifiers == 0) - return; - - debug = display->debug_button_grabs; - i = 1; - while (i < 4) - { - meta_change_button_grab (display, xwindow, - FALSE, FALSE, i, - display->window_grab_modifiers); - - if (debug) - meta_change_button_grab (display, xwindow, - FALSE, FALSE, i, ControlMask); - - ++i; - } - - if (display->mouse_zoom_modifiers == 0) - return; - - i = 4; - while (i < 6) - { - meta_change_button_grab (display, xwindow, - FALSE, FALSE, i, - display->mouse_zoom_modifiers); - - if (debug) - meta_change_button_grab (display, xwindow, - FALSE, FALSE, i, ControlMask); - - ++i; - } -} - -/* Grab buttons we only grab while unfocused in click-to-focus mode */ -#define MAX_FOCUS_BUTTON 4 -LOCAL_SYMBOL void -meta_display_grab_focus_window_button (MetaDisplay *display, - MetaWindow *window) -{ - /* Grab button 1 for activating unfocused windows */ - meta_verbose ("Grabbing unfocused window buttons for %s\n", window->desc); - -#if 0 - /* FIXME:115072 */ - /* Don't grab at all unless in click to focus mode. In click to - * focus, we may sometimes be clever about intercepting and eating - * the focus click. But in mouse focus, we never do that since the - * focus window may not be raised, and who wants to think about - * mouse focus anyway. - */ - if (meta_prefs_get_focus_mode () != C_DESKTOP_FOCUS_MODE_CLICK) - { - meta_verbose (" (well, not grabbing since not in click to focus mode)\n"); - return; - } -#endif - - if (window->have_focus_click_grab) - { - meta_verbose (" (well, not grabbing since we already have the grab)\n"); - return; - } - - /* FIXME If we ignored errors here instead of spewing, we could - * put one big error trap around the loop and avoid a bunch of - * XSync() - */ - - { - int i = 1; - while (i < MAX_FOCUS_BUTTON) - { - meta_change_button_grab (display, - window->xwindow, - TRUE, TRUE, - i, 0); - - ++i; - } - - window->have_focus_click_grab = TRUE; - } -} - -LOCAL_SYMBOL void -meta_display_ungrab_focus_window_button (MetaDisplay *display, - MetaWindow *window) -{ - meta_verbose ("Ungrabbing unfocused window buttons for %s\n", window->desc); - - if (!window->have_focus_click_grab) - return; - - { - int i = 1; - while (i < MAX_FOCUS_BUTTON) - { - meta_change_button_grab (display, window->xwindow, - FALSE, FALSE, i, 0); - - ++i; - } - - window->have_focus_click_grab = FALSE; - } -} - -LOCAL_SYMBOL void -meta_display_increment_event_serial (MetaDisplay *display) -{ - /* We just make some random X request */ - XDeleteProperty (display->xdisplay, display->leader_window, - display->atom__MOTIF_WM_HINTS); -} - -LOCAL_SYMBOL void -meta_display_update_active_window_hint (MetaDisplay *display) -{ - GSList *tmp; - - gulong data[1]; - - if (display->closing) - return; /* Leave old value for a replacement */ - - if (display->focus_window) - data[0] = display->focus_window->xwindow; - else - data[0] = None; - - tmp = display->screens; - while (tmp != NULL) - { - MetaScreen *screen = tmp->data; - - meta_error_trap_push (display); - XChangeProperty (display->xdisplay, screen->xroot, - display->atom__NET_ACTIVE_WINDOW, - XA_WINDOW, - 32, PropModeReplace, (guchar*) data, 1); - - meta_error_trap_pop (display); - - tmp = tmp->next; - } -} - -LOCAL_SYMBOL void -meta_display_queue_retheme_all_windows (MetaDisplay *display) -{ - GSList* windows; - GSList *tmp; - - windows = meta_display_list_windows (display, META_LIST_DEFAULT); - tmp = windows; - while (tmp != NULL) - { - MetaWindow *window = tmp->data; - - meta_window_queue (window, META_QUEUE_MOVE_RESIZE); - meta_window_frame_size_changed (window); - if (window->frame) - { - meta_frame_queue_draw (window->frame); - } - - tmp = tmp->next; - } - - g_slist_free (windows); -} - -LOCAL_SYMBOL void -meta_display_retheme_all (void) -{ - meta_display_queue_retheme_all_windows (meta_get_display ()); -} - -LOCAL_SYMBOL void -meta_display_set_cursor_theme (const char *theme, - int size) -{ -#ifdef HAVE_XCURSOR - GSList *tmp; - - MetaDisplay *display = meta_get_display (); - - XcursorSetTheme (display->xdisplay, theme); - XcursorSetDefaultSize (display->xdisplay, size); - - tmp = display->screens; - while (tmp != NULL) - { - MetaScreen *screen = tmp->data; - - meta_screen_update_cursor (screen); - - tmp = tmp->next; - } - -#endif + g_slist_free (windows); } /* @@ -4271,16 +2084,18 @@ meta_display_set_cursor_theme (const char *theme, */ static gboolean is_syncing = FALSE; -/* - * Returns whether X synchronisation is currently enabled. +/** + * meta_is_syncing: * - * \return true if we must wait for events whenever we send X requests; - * false otherwise. + * Returns whether X synchronisation is currently enabled. * - * \bug This is *only* called by meta_display_open, but by that time + * FIXME: This is *only* called by meta_display_open(), but by that time * we have already turned syncing on or off on startup, and we don't - * have any way to do so while Muffin is running, so it's rather + * have any way to do so while Mutter is running, so it's rather * pointless. + * + * Returns: %TRUE if we must wait for events whenever we send X requests; + * %FALSE otherwise. */ gboolean meta_is_syncing (void) @@ -4288,11 +2103,11 @@ meta_is_syncing (void) return is_syncing; } -/* - * A handy way to turn on synchronisation on or off for every display. +/** + * meta_set_syncing: + * @setting: whether to turn syncing on or off * - * \bug Of course there is only one display ever anyway, so this can - * be rather hugely simplified. + * A handy way to turn on synchronisation on or off for every display. */ void meta_set_syncing (gboolean setting) @@ -4301,56 +2116,52 @@ meta_set_syncing (gboolean setting) { is_syncing = setting; if (meta_get_display ()) - XSynchronize (meta_get_display ()->xdisplay, is_syncing); + XSynchronize (meta_get_display ()->x11_display->xdisplay, is_syncing); } } -/* - * How long, in milliseconds, we should wait after pinging a window - * before deciding it's not going to get back to us. - */ -#define PING_TIMEOUT_DELAY 5000 - -/* +/** + * meta_display_ping_timeout: + * @data: All the information about this ping. It is a #MetaPingData + * cast to a #gpointer in order to be passable to a timeout function. + * This function will also free this parameter. + * * Does whatever it is we decided to do when a window didn't respond * to a ping. We also remove the ping from the display's list of * pending pings. This function is called by the event loop when the timeout * times out which we created at the start of the ping. * - * \param data All the information about this ping. It is a MetaPingData - * cast to a void* in order to be passable to a timeout function. - * This function will also free this parameter. - * - * \return Always returns false, because this function is called as a - * timeout and we don't want to run the timer again. - * - * \ingroup pings + * Returns: Always returns %FALSE, because this function is called as a + * timeout and we don't want to run the timer again. */ static gboolean meta_display_ping_timeout (gpointer data) { - MetaPingData *ping_data; + MetaPingData *ping_data = data; + MetaWindow *window = ping_data->window; + MetaDisplay *display = window->display; - ping_data = data; + meta_window_set_alive (window, FALSE); ping_data->ping_timeout_id = 0; meta_topic (META_DEBUG_PING, - "Ping %u on window %lx timed out\n", - ping_data->timestamp, ping_data->xwindow); - - (* ping_data->ping_timeout_func) (ping_data->display, ping_data->xwindow, - ping_data->timestamp, ping_data->user_data); + "Ping %u on window %s timed out\n", + ping_data->serial, ping_data->window->desc); - ping_data->display->pending_pings = - g_slist_remove (ping_data->display->pending_pings, - ping_data); + display->pending_pings = g_slist_remove (display->pending_pings, ping_data); ping_data_free (ping_data); return FALSE; } -/* +/** + * meta_display_ping_window: + * @display: The #MetaDisplay that the window is on + * @window: The #MetaWindow to send the ping to + * @timestamp: The timestamp of the ping. Used for uniqueness. + * Cannot be CurrentTime; use a real timestamp! + * * Sends a ping request to a window. The window must respond to * the request within a certain amount of time. If it does, we * will call one callback; if the time passes and we haven't had @@ -4359,216 +2170,112 @@ meta_display_ping_timeout (gpointer data) * we call the "got a response" callback immediately and return. * This function returns straight away after setting things up; * the callbacks will be called from the event loop. - * - * \param display The MetaDisplay that the window is on - * \param window The MetaWindow to send the ping to - * \param timestamp The timestamp of the ping. Used for uniqueness. - * Cannot be CurrentTime; use a real timestamp! - * \param ping_reply_func The callback to call if we get a response. - * \param ping_timeout_func The callback to call if we don't get a response. - * \param user_data Arbitrary data that will be passed to the callback - * function. (In practice it's often a pointer to - * the window.) - * - * \bug This should probably be a method on windows, rather than displays - * for one of their windows. - * - * \ingroup pings */ -LOCAL_SYMBOL void -meta_display_ping_window (MetaDisplay *display, - MetaWindow *window, - guint32 timestamp, - MetaWindowPingFunc ping_reply_func, - MetaWindowPingFunc ping_timeout_func, - gpointer user_data) +void +meta_display_ping_window (MetaWindow *window, + guint32 serial) { + GSList *l; + MetaDisplay *display = window->display; MetaPingData *ping_data; + unsigned int check_alive_timeout; - if (timestamp == CurrentTime) - { - meta_warning ("Tried to ping a window with CurrentTime! Not allowed.\n"); - return; - } + check_alive_timeout = meta_prefs_get_check_alive_timeout (); + if (check_alive_timeout == 0) + return; - if (!window->net_wm_ping) + if (serial == 0) { - if (ping_reply_func) - (* ping_reply_func) (display, window->xwindow, timestamp, user_data); - + meta_warning ("Tried to ping window %s with a bad serial! Not allowed.\n", + window->desc); return; } - ping_data = g_new (MetaPingData, 1); - ping_data->display = display; - ping_data->xwindow = window->xwindow; - ping_data->timestamp = timestamp; - ping_data->ping_reply_func = ping_reply_func; - ping_data->ping_timeout_func = ping_timeout_func; - ping_data->user_data = user_data; - ping_data->ping_timeout_id = g_timeout_add (PING_TIMEOUT_DELAY, - meta_display_ping_timeout, - ping_data); - - display->pending_pings = g_slist_prepend (display->pending_pings, ping_data); - - meta_topic (META_DEBUG_PING, - "Sending ping with timestamp %u to window %s\n", - timestamp, window->desc); - meta_window_send_icccm_message (window, - display->atom__NET_WM_PING, - timestamp); -} - -static void -process_request_frame_extents (MetaDisplay *display, - XEvent *event) -{ - /* The X window whose frame extents will be set. */ - Window xwindow = event->xclient.window; - unsigned long data[4] = { 0, 0, 0, 0 }; - - MotifWmHints *hints = NULL; - gboolean hints_set = FALSE; - - meta_verbose ("Setting frame extents for 0x%lx\n", xwindow); + if (!meta_window_can_ping (window)) + return; - /* See if the window is decorated. */ - hints_set = meta_prop_get_motif_hints (display, - xwindow, - display->atom__MOTIF_WM_HINTS, - &hints); - if ((hints_set && hints->decorations) || !hints_set) + for (l = display->pending_pings; l; l = l->next) { - MetaFrameBorders borders; - MetaScreen *screen; + MetaPingData *ping_data = l->data; - screen = meta_display_screen_for_xwindow (display, - event->xclient.window); - if (screen == NULL) + if (window == ping_data->window) { - meta_warning ("Received request to set _NET_FRAME_EXTENTS " - "on 0x%lx which is on a screen we are not managing\n", - event->xclient.window); - meta_XFree (hints); + meta_topic (META_DEBUG_PING, + "Window %s already is being pinged with serial %u\n", + window->desc, ping_data->serial); return; } - /* Return estimated frame extents for a normal window. */ - meta_ui_theme_get_frame_borders (screen->ui, - META_FRAME_TYPE_NORMAL, - 0, - &borders); - data[0] = borders.visible.left; - data[1] = borders.visible.right; - data[2] = borders.visible.top; - data[3] = borders.visible.bottom; + if (serial == ping_data->serial) + { + meta_warning ("Ping serial %u was reused for window %s, " + "previous use was for window %s.\n", + serial, window->desc, ping_data->window->desc); + return; + } } - meta_topic (META_DEBUG_GEOMETRY, - "Setting _NET_FRAME_EXTENTS on unmanaged window 0x%lx " - "to top = %lu, left = %lu, bottom = %lu, right = %lu\n", - xwindow, data[0], data[1], data[2], data[3]); + ping_data = g_new (MetaPingData, 1); + ping_data->window = window; + ping_data->serial = serial; + ping_data->ping_timeout_id = + g_timeout_add (check_alive_timeout, + meta_display_ping_timeout, + ping_data); + g_source_set_name_by_id (ping_data->ping_timeout_id, "[mutter] meta_display_ping_timeout"); + + display->pending_pings = g_slist_prepend (display->pending_pings, ping_data); - meta_error_trap_push (display); - XChangeProperty (display->xdisplay, xwindow, - display->atom__NET_FRAME_EXTENTS, - XA_CARDINAL, - 32, PropModeReplace, (guchar*) data, 4); - meta_error_trap_pop (display); + meta_topic (META_DEBUG_PING, + "Sending ping with serial %u to window %s\n", + serial, window->desc); - meta_XFree (hints); + META_WINDOW_GET_CLASS (window)->ping (window, serial); } -/* +/** + * meta_display_pong_for_serial: + * @display: the display we got the pong from + * @serial: the serial in the pong repsonse + * * Process the pong (the response message) from the ping we sent * to the window. This involves removing the timeout, calling the * reply handler function, and freeing memory. - * - * \param display the display we got the pong from - * \param event the XEvent which is a pong; we can tell which - * ping it corresponds to because it bears the - * same timestamp. - * - * \ingroup pings */ -static void -process_pong_message (MetaDisplay *display, - XEvent *event) +void +meta_display_pong_for_serial (MetaDisplay *display, + guint32 serial) { GSList *tmp; - guint32 timestamp = event->xclient.data.l[1]; - meta_topic (META_DEBUG_PING, "Received a pong with timestamp %u\n", - timestamp); + meta_topic (META_DEBUG_PING, "Received a pong with serial %u\n", serial); for (tmp = display->pending_pings; tmp; tmp = tmp->next) { MetaPingData *ping_data = tmp->data; - if (timestamp == ping_data->timestamp) + if (serial == ping_data->serial) { meta_topic (META_DEBUG_PING, "Matching ping found for pong %u\n", - ping_data->timestamp); + ping_data->serial); /* Remove the ping data from the list */ display->pending_pings = g_slist_remove (display->pending_pings, ping_data); /* Remove the timeout */ - if (ping_data->ping_timeout_id != 0) - { - g_source_remove (ping_data->ping_timeout_id); - ping_data->ping_timeout_id = 0; - } - - /* Call callback */ - (* ping_data->ping_reply_func) (display, - ping_data->xwindow, - ping_data->timestamp, - ping_data->user_data); + g_clear_handle_id (&ping_data->ping_timeout_id, g_source_remove); + meta_window_set_alive (ping_data->window, TRUE); ping_data_free (ping_data); - break; } } } -/* - * Finds whether a window has any pings waiting on it. - * - * \param display The MetaDisplay of the window. - * \param window The MetaWindow whose pings we want to know about. - * - * \return True if there is at least one ping which has been sent - * to the window without getting a response; false otherwise. - * - * \bug This should probably be a method on windows, rather than displays - * for one of their windows. - * - * \ingroup pings - */ -LOCAL_SYMBOL gboolean -meta_display_window_has_pending_pings (MetaDisplay *display, - MetaWindow *window) -{ - GSList *tmp; - - for (tmp = display->pending_pings; tmp; tmp = tmp->next) - { - MetaPingData *ping_data = tmp->data; - - if (ping_data->xwindow == window->xwindow) - return TRUE; - } - - return FALSE; -} - -static MetaGroup* -get_focussed_group (MetaDisplay *display) +static MetaGroup * +get_focused_group (MetaDisplay *display) { if (display->focus_window) return display->focus_window->group; @@ -4578,13 +2285,12 @@ get_focussed_group (MetaDisplay *display) #define IN_TAB_CHAIN(w,t) (((t) == META_TAB_LIST_NORMAL && META_WINDOW_IN_NORMAL_TAB_CHAIN (w)) \ || ((t) == META_TAB_LIST_DOCKS && META_WINDOW_IN_DOCK_TAB_CHAIN (w)) \ - || ((t) == META_TAB_LIST_GROUP && META_WINDOW_IN_GROUP_TAB_CHAIN (w, get_focussed_group(w->display))) \ + || ((t) == META_TAB_LIST_GROUP && META_WINDOW_IN_GROUP_TAB_CHAIN (w, get_focused_group (w->display))) \ || ((t) == META_TAB_LIST_NORMAL_ALL && META_WINDOW_IN_NORMAL_TAB_CHAIN_TYPE (w))) static MetaWindow* find_tab_forward (MetaDisplay *display, MetaTabList type, - MetaScreen *screen, MetaWorkspace *workspace, GList *start, gboolean skip_first) @@ -4602,8 +2308,7 @@ find_tab_forward (MetaDisplay *display, { MetaWindow *window = tmp->data; - if (window->screen == screen && - IN_TAB_CHAIN (window, type)) + if (IN_TAB_CHAIN (window, type)) return window; tmp = tmp->next; @@ -4626,7 +2331,6 @@ find_tab_forward (MetaDisplay *display, static MetaWindow* find_tab_backward (MetaDisplay *display, MetaTabList type, - MetaScreen *screen, MetaWorkspace *workspace, GList *start, gboolean skip_last) @@ -4643,8 +2347,7 @@ find_tab_backward (MetaDisplay *display, { MetaWindow *window = tmp->data; - if (window->screen == screen && - IN_TAB_CHAIN (window, type)) + if (IN_TAB_CHAIN (window, type)) return window; tmp = tmp->prev; @@ -4664,1063 +2367,1507 @@ find_tab_backward (MetaDisplay *display, return NULL; } +static int +mru_cmp (gconstpointer a, + gconstpointer b) +{ + guint32 time_a, time_b; + + time_a = meta_window_get_user_time ((MetaWindow *)a); + time_b = meta_window_get_user_time ((MetaWindow *)b); + + if (time_a > time_b) + return -1; + else if (time_a < time_b) + return 1; + else + return 0; +} + /** * meta_display_get_tab_list: * @display: a #MetaDisplay * @type: type of tab list - * @screen: a #MetaScreen - * @workspace: origin workspace + * @workspace: (nullable): origin workspace * * Determine the list of windows that should be displayed for Alt-TAB * functionality. The windows are returned in most recently used order. + * If @workspace is not %NULL, the list only conains windows that are on + * @workspace or have the demands-attention hint set; otherwise it contains + * all windows. * * Returns: (transfer container) (element-type Meta.Window): List of windows */ GList* meta_display_get_tab_list (MetaDisplay *display, MetaTabList type, - MetaScreen *screen, MetaWorkspace *workspace) { - GList *tab_list; + GList *tab_list = NULL; + GList *global_mru_list = NULL; + GList *mru_list, *tmp; + GSList *windows = meta_display_list_windows (display, META_LIST_DEFAULT); + GSList *w; - g_return_val_if_fail (workspace != NULL, NULL); + if (workspace == NULL) + { + /* Yay for mixing GList and GSList in the API */ + for (w = windows; w; w = w->next) + global_mru_list = g_list_prepend (global_mru_list, w->data); + global_mru_list = g_list_sort (global_mru_list, mru_cmp); + } + + mru_list = workspace ? workspace->mru_list : global_mru_list; /* Windows sellout mode - MRU order. Collect unminimized windows * then minimized so minimized windows aren't in the way so much. */ - { - GList *tmp; + for (tmp = mru_list; tmp; tmp = tmp->next) + { + MetaWindow *window = tmp->data; - tab_list = NULL; - tmp = workspace->mru_list; - while (tmp != NULL) - { - MetaWindow *window = tmp->data; + if (!window->minimized && IN_TAB_CHAIN (window, type)) + tab_list = g_list_prepend (tab_list, window); + } - if (!window->minimized && - window->screen == screen && - IN_TAB_CHAIN (window, type)) - tab_list = g_list_prepend (tab_list, window); + for (tmp = mru_list; tmp; tmp = tmp->next) + { + MetaWindow *window = tmp->data; - tmp = tmp->next; - } - } + if (window->minimized && IN_TAB_CHAIN (window, type)) + tab_list = g_list_prepend (tab_list, window); + } - { - GList *tmp; + tab_list = g_list_reverse (tab_list); - tmp = workspace->mru_list; - while (tmp != NULL) + /* If filtering by workspace, include windows from + * other workspaces that demand attention + */ + if (workspace) + for (w = windows; w; w = w->next) { - MetaWindow *window = tmp->data; - - if (window->minimized && - window->screen == screen && - IN_TAB_CHAIN (window, type)) - tab_list = g_list_prepend (tab_list, window); + MetaWindow *l_window = w->data; - tmp = tmp->next; + if (l_window->wm_state_demands_attention && + !meta_window_located_on_workspace (l_window, workspace) && + IN_TAB_CHAIN (l_window, type)) + tab_list = g_list_prepend (tab_list, l_window); } - } - tab_list = g_list_reverse (tab_list); + g_list_free (global_mru_list); + g_slist_free (windows); + + return tab_list; +} + +/** + * meta_display_get_tab_next: + * @display: a #MetaDisplay + * @type: type of tab list + * @workspace: origin workspace + * @window: (nullable): starting window + * @backward: If %TRUE, look for the previous window. + * + * Determine the next window that should be displayed for Alt-TAB + * functionality. + * + * Returns: (transfer none): Next window + * + */ +MetaWindow* +meta_display_get_tab_next (MetaDisplay *display, + MetaTabList type, + MetaWorkspace *workspace, + MetaWindow *window, + gboolean backward) +{ + gboolean skip; + GList *tab_list; + MetaWindow *ret; + tab_list = meta_display_get_tab_list (display, type, workspace); + + if (tab_list == NULL) + return NULL; + + if (window != NULL) + { + g_assert (window->display == display); + + if (backward) + ret = find_tab_backward (display, type, workspace, g_list_find (tab_list, window), TRUE); + else + ret = find_tab_forward (display, type, workspace, g_list_find (tab_list, window), TRUE); + } + else + { + skip = display->focus_window != NULL && + tab_list->data == display->focus_window; + if (backward) + ret = find_tab_backward (display, type, workspace, tab_list, skip); + else + ret = find_tab_forward (display, type, workspace, tab_list, skip); + } + + g_list_free (tab_list); + return ret; +} + +/** + * meta_display_get_tab_current: + * @display: a #MetaDisplay + * @type: type of tab list + * @workspace: origin workspace + * + * Determine the active window that should be displayed for Alt-TAB. + * + * Returns: (transfer none): Current window + * + */ +MetaWindow* +meta_display_get_tab_current (MetaDisplay *display, + MetaTabList type, + MetaWorkspace *workspace) +{ + MetaWindow *window; + + window = display->focus_window; + + if (window != NULL && + IN_TAB_CHAIN (window, type) && + (workspace == NULL || + meta_window_located_on_workspace (window, workspace))) + return window; + else + return NULL; +} + +MetaGravity +meta_resize_gravity_from_grab_op (MetaGrabOp op) +{ + MetaGravity gravity; + + gravity = -1; + switch (op) + { + case META_GRAB_OP_RESIZING_SE: + case META_GRAB_OP_KEYBOARD_RESIZING_SE: + gravity = META_GRAVITY_NORTH_WEST; + break; + case META_GRAB_OP_KEYBOARD_RESIZING_S: + case META_GRAB_OP_RESIZING_S: + gravity = META_GRAVITY_NORTH; + break; + case META_GRAB_OP_KEYBOARD_RESIZING_SW: + case META_GRAB_OP_RESIZING_SW: + gravity = META_GRAVITY_NORTH_EAST; + break; + case META_GRAB_OP_KEYBOARD_RESIZING_N: + case META_GRAB_OP_RESIZING_N: + gravity = META_GRAVITY_SOUTH; + break; + case META_GRAB_OP_KEYBOARD_RESIZING_NE: + case META_GRAB_OP_RESIZING_NE: + gravity = META_GRAVITY_SOUTH_WEST; + break; + case META_GRAB_OP_KEYBOARD_RESIZING_NW: + case META_GRAB_OP_RESIZING_NW: + gravity = META_GRAVITY_SOUTH_EAST; + break; + case META_GRAB_OP_KEYBOARD_RESIZING_E: + case META_GRAB_OP_RESIZING_E: + gravity = META_GRAVITY_WEST; + break; + case META_GRAB_OP_KEYBOARD_RESIZING_W: + case META_GRAB_OP_RESIZING_W: + gravity = META_GRAVITY_EAST; + break; + case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN: + gravity = META_GRAVITY_CENTER; + break; + default: + break; + } + + return gravity; +} + +void +meta_display_manage_all_xwindows (MetaDisplay *display) +{ + guint64 *_children; + guint64 *children; + int n_children, i; + + meta_stack_freeze (display->stack); + meta_stack_tracker_get_stack (display->stack_tracker, &_children, &n_children); + + /* Copy the stack as it will be modified as part of the loop */ + children = g_memdup (_children, sizeof (guint64) * n_children); + + for (i = 0; i < n_children; ++i) + { + if (!META_STACK_ID_IS_X11 (children[i])) + continue; + meta_window_x11_new (display, children[i], TRUE, + META_COMP_EFFECT_NONE); + } + + g_free (children); + meta_stack_thaw (display->stack); +} + +void +meta_display_unmanage_windows (MetaDisplay *display, + guint32 timestamp) +{ + GSList *tmp; + GSList *winlist; + + winlist = meta_display_list_windows (display, + META_LIST_INCLUDE_OVERRIDE_REDIRECT); + winlist = g_slist_sort (winlist, meta_display_stack_cmp); + g_slist_foreach (winlist, (GFunc)g_object_ref, NULL); + + /* Unmanage all windows */ + tmp = winlist; + while (tmp != NULL) + { + MetaWindow *window = tmp->data; + + /* Check if already unmanaged for safety - in particular, catch + * the case where unmanaging a parent window can cause attached + * dialogs to be (temporarily) unmanaged. + */ + if (!window->unmanaging) + meta_window_unmanage (window, timestamp); + g_object_unref (window); + + tmp = tmp->next; + } + g_slist_free (winlist); +} + +int +meta_display_stack_cmp (const void *a, + const void *b) +{ + MetaWindow *aw = (void*) a; + MetaWindow *bw = (void*) b; + + return meta_stack_windows_cmp (aw->display->stack, aw, bw); +} + +/** + * meta_display_sort_windows_by_stacking: + * @display: a #MetaDisplay + * @windows: (element-type MetaWindow): Set of windows + * + * Sorts a set of windows according to their current stacking order. If windows + * from multiple screens are present in the set of input windows, then all the + * windows on screen 0 are sorted below all the windows on screen 1, and so forth. + * Since the stacking order of override-redirect windows isn't controlled by + * Metacity, if override-redirect windows are in the input, the result may not + * correspond to the actual stacking order in the X server. + * + * An example of using this would be to sort the list of transient dialogs for a + * window into their current stacking order. + * + * Returns: (transfer container) (element-type MetaWindow): Input windows sorted by stacking order, from lowest to highest + */ +GSList * +meta_display_sort_windows_by_stacking (MetaDisplay *display, + GSList *windows) +{ + GSList *copy = g_slist_copy (windows); + + copy = g_slist_sort (copy, meta_display_stack_cmp); + + return copy; +} + +static void +prefs_changed_callback (MetaPreference pref, + void *data) +{ + MetaDisplay *display = data; + + if (pref == META_PREF_CURSOR_THEME || + pref == META_PREF_CURSOR_SIZE) + { + meta_display_reload_cursor (display); + } +} + +void +meta_display_sanity_check_timestamps (MetaDisplay *display, + guint32 timestamp) +{ + if (XSERVER_TIME_IS_BEFORE (timestamp, display->last_focus_time)) + { + meta_warning ("last_focus_time (%u) is greater than comparison " + "timestamp (%u). This most likely represents a buggy " + "client sending inaccurate timestamps in messages such as " + "_NET_ACTIVE_WINDOW. Trying to work around...\n", + display->last_focus_time, timestamp); + display->last_focus_time = timestamp; + } + if (XSERVER_TIME_IS_BEFORE (timestamp, display->last_user_time)) + { + GSList *windows; + GSList *tmp; + + meta_warning ("last_user_time (%u) is greater than comparison " + "timestamp (%u). This most likely represents a buggy " + "client sending inaccurate timestamps in messages such as " + "_NET_ACTIVE_WINDOW. Trying to work around...\n", + display->last_user_time, timestamp); + display->last_user_time = timestamp; + + windows = meta_display_list_windows (display, META_LIST_DEFAULT); + tmp = windows; + while (tmp != NULL) + { + MetaWindow *window = tmp->data; + + if (XSERVER_TIME_IS_BEFORE (timestamp, window->net_wm_user_time)) + { + meta_warning ("%s appears to be one of the offending windows " + "with a timestamp of %u. Working around...\n", + window->desc, window->net_wm_user_time); + meta_window_set_user_time (window, timestamp); + } + + tmp = tmp->next; + } + + g_slist_free (windows); + } +} + +void +meta_display_remove_autoraise_callback (MetaDisplay *display) +{ + g_clear_handle_id (&display->autoraise_timeout_id, g_source_remove); + display->autoraise_window = NULL; +} + +void +meta_display_overlay_key_activate (MetaDisplay *display) +{ + g_signal_emit (display, display_signals[OVERLAY_KEY], 0); +} + +void +meta_display_accelerator_activate (MetaDisplay *display, + guint action, + ClutterKeyEvent *event) +{ + g_signal_emit (display, display_signals[ACCELERATOR_ACTIVATED], 0, + action, + clutter_event_get_source_device ((ClutterEvent *) event), + event->time); +} + +gboolean +meta_display_modifiers_accelerator_activate (MetaDisplay *display) +{ + gboolean freeze; + + g_signal_emit (display, display_signals[MODIFIERS_ACCELERATOR_ACTIVATED], 0, &freeze); + + return freeze; +} + +/** + * meta_display_supports_extended_barriers: + * @display: a #MetaDisplay + * + * Returns: whether pointer barriers can be supported. + * + * When running as an X compositor the X server needs XInput 2 + * version 2.3. When running as a display server it is supported + * when running on the native backend. + * + * Clients should use this method to determine whether their + * interfaces should depend on new barrier features. + */ +gboolean +meta_display_supports_extended_barriers (MetaDisplay *display) +{ +#ifdef HAVE_NATIVE_BACKEND + if (META_IS_BACKEND_NATIVE (meta_get_backend ())) + return TRUE; +#endif + + if (META_IS_BACKEND_X11_CM (meta_get_backend ())) + { + if (meta_is_wayland_compositor()) + return FALSE; + + return META_X11_DISPLAY_HAS_XINPUT_23 (display->x11_display); + } + + return FALSE; +} + +/** + * meta_display_get_compositor: (skip) + * @display: a #MetaDisplay + * + */ +MetaCompositor * +meta_display_get_compositor (MetaDisplay *display) +{ + return display->compositor; +} + +/** + * meta_display_get_x11_display: (skip) + * @display: a #MetaDisplay + * + */ +MetaX11Display * +meta_display_get_x11_display (MetaDisplay *display) +{ + return display->x11_display; +} + +/** + * meta_display_get_size: + * @display: A #MetaDisplay + * @width: (out): The width of the screen + * @height: (out): The height of the screen + * + * Retrieve the size of the display. + */ +void +meta_display_get_size (MetaDisplay *display, + int *width, + int *height) +{ + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + int display_width, display_height; + + meta_monitor_manager_get_screen_size (monitor_manager, + &display_width, + &display_height); + + if (width != NULL) + *width = display_width; + + if (height != NULL) + *height = display_height; +} + +/** + * meta_display_get_focus_window: + * @display: a #MetaDisplay + * + * Get our best guess as to the "currently" focused window (that is, + * the window that we expect will be focused at the point when the X + * server processes our next request). + * + * Return Value: (transfer none): The current focus window + */ +MetaWindow * +meta_display_get_focus_window (MetaDisplay *display) +{ + return display->focus_window; +} + +/** + * meta_display_clear_mouse_mode: + * @display: a #MetaDisplay + * + * Sets the mouse-mode flag to %FALSE, which means that motion events are + * no longer ignored in mouse or sloppy focus. + * This is an internal function. It should be used only for reimplementing + * keybindings, and only in a manner compatible with core code. + */ +void +meta_display_clear_mouse_mode (MetaDisplay *display) +{ + display->mouse_mode = FALSE; +} - { - GSList *windows, *tmp; - MetaWindow *l_window; +MetaGestureTracker * +meta_display_get_gesture_tracker (MetaDisplay *display) +{ + return display->gesture_tracker; +} - windows = meta_display_list_windows (display, META_LIST_DEFAULT); +gboolean +meta_display_show_restart_message (MetaDisplay *display, + const char *message) +{ + gboolean result = FALSE; - /* Go through all windows */ - tmp = windows; - while (tmp != NULL) - { - l_window=tmp->data; + g_signal_emit (display, + display_signals[SHOW_RESTART_MESSAGE], 0, + message, &result); - /* Check to see if it demands attention */ - if (l_window->wm_state_demands_attention && - l_window->workspace!=workspace && - IN_TAB_CHAIN (l_window, type)) - { - /* if it does, add it to the popup */ - tab_list = g_list_prepend (tab_list, l_window); - } + return result; +} - tmp = tmp->next; - } /* End while tmp!=NULL */ +gboolean +meta_display_request_restart (MetaDisplay *display) +{ + gboolean result = FALSE; - g_slist_free (windows); - } + g_signal_emit (display, + display_signals[RESTART], 0, + &result); - return tab_list; + return result; } -/** - * meta_display_get_tab_next: - * @display: a #MetaDisplay - * @type: type of tab list - * @screen: a #MetaScreen - * @workspace: origin workspace - * @window: (allow-none): starting window - * @backward: If %TRUE, look for the previous window. - * - * Determine the next window that should be displayed for Alt-TAB - * functionality. - * - * Returns: (transfer none): Next window - * - */ -MetaWindow* -meta_display_get_tab_next (MetaDisplay *display, - MetaTabList type, - MetaScreen *screen, - MetaWorkspace *workspace, - MetaWindow *window, - gboolean backward) +gboolean +meta_display_show_resize_popup (MetaDisplay *display, + gboolean show, + MetaRectangle *rect, + int display_w, + int display_h) { - gboolean skip; - GList *tab_list; - MetaWindow *ret; - tab_list = meta_display_get_tab_list(display, - type, - screen, - workspace); - - if (tab_list == NULL) - return NULL; - - if (window != NULL) - { - g_assert (window->display == display); + gboolean result = FALSE; - if (backward) - ret = find_tab_backward (display, type, screen, workspace, - g_list_find (tab_list, - window), - TRUE); - else - ret = find_tab_forward (display, type, screen, workspace, - g_list_find (tab_list, - window), - TRUE); - } - else - { - skip = display->focus_window != NULL && - tab_list->data == display->focus_window; - if (backward) - ret = find_tab_backward (display, type, screen, workspace, - tab_list, skip); - else - ret = find_tab_forward (display, type, screen, workspace, - tab_list, skip); - } + g_signal_emit (display, + display_signals[SHOW_RESIZE_POPUP], 0, + show, rect, display_w, display_h, &result); - g_list_free (tab_list); - return ret; + return result; } /** - * meta_display_get_tab_current: - * @display: a #MetaDisplay - * @type: type of tab list - * @screen: a #MetaScreen - * @workspace: origin workspace - * - * Determine the active window that should be displayed for Alt-TAB. + * meta_display_is_pointer_emulating_sequence: + * @display: the display + * @sequence: (nullable): a #ClutterEventSequence * - * Returns: (transfer none): Current window + * Tells whether the event sequence is the used for pointer emulation + * and single-touch interaction. * - */ -MetaWindow* -meta_display_get_tab_current (MetaDisplay *display, - MetaTabList type, - MetaScreen *screen, - MetaWorkspace *workspace) + * Returns: #TRUE if the sequence emulates pointer behavior + **/ +gboolean +meta_display_is_pointer_emulating_sequence (MetaDisplay *display, + ClutterEventSequence *sequence) { - MetaWindow *window; - - window = display->focus_window; + if (!sequence) + return FALSE; - if (window != NULL && - window->screen == screen && - IN_TAB_CHAIN (window, type) && - (workspace == NULL || - meta_window_located_on_workspace (window, workspace))) - return window; - else - return NULL; + return display->pointer_emulating_sequence == sequence; } -LOCAL_SYMBOL int -meta_resize_gravity_from_grab_op (MetaGrabOp op) -{ - int gravity; +void +meta_display_request_pad_osd (MetaDisplay *display, + ClutterInputDevice *pad, + gboolean edition_mode) +{ + MetaBackend *backend = meta_get_backend (); + MetaInputSettings *input_settings; + const gchar *layout_path = NULL; + ClutterActor *osd; + MetaLogicalMonitor *logical_monitor; + GSettings *settings; +#ifdef HAVE_LIBWACOM + WacomDevice *wacom_device; +#endif - gravity = -1; - switch (op) + /* Avoid emitting the signal while there is an OSD being currently + * displayed, the first OSD will have to be dismissed before showing + * any other one. + */ + if (display->current_pad_osd) + return; + + input_settings = meta_backend_get_input_settings (meta_get_backend ()); + + if (input_settings) { - case META_GRAB_OP_RESIZING_SE: - case META_GRAB_OP_KEYBOARD_RESIZING_SE: - gravity = NorthWestGravity; - break; - case META_GRAB_OP_KEYBOARD_RESIZING_S: - case META_GRAB_OP_RESIZING_S: - gravity = NorthGravity; - break; - case META_GRAB_OP_KEYBOARD_RESIZING_SW: - case META_GRAB_OP_RESIZING_SW: - gravity = NorthEastGravity; - break; - case META_GRAB_OP_KEYBOARD_RESIZING_N: - case META_GRAB_OP_RESIZING_N: - gravity = SouthGravity; - break; - case META_GRAB_OP_KEYBOARD_RESIZING_NE: - case META_GRAB_OP_RESIZING_NE: - gravity = SouthWestGravity; - break; - case META_GRAB_OP_KEYBOARD_RESIZING_NW: - case META_GRAB_OP_RESIZING_NW: - gravity = SouthEastGravity; - break; - case META_GRAB_OP_KEYBOARD_RESIZING_E: - case META_GRAB_OP_RESIZING_E: - gravity = WestGravity; - break; - case META_GRAB_OP_KEYBOARD_RESIZING_W: - case META_GRAB_OP_RESIZING_W: - gravity = EastGravity; - break; - case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN: - gravity = CenterGravity; - break; - default: - break; + settings = meta_input_settings_get_tablet_settings (input_settings, pad); + logical_monitor = + meta_input_settings_get_tablet_logical_monitor (input_settings, pad); +#ifdef HAVE_LIBWACOM + wacom_device = meta_input_device_get_wacom_device (META_INPUT_DEVICE (pad)); + layout_path = libwacom_get_layout_filename (wacom_device); +#endif } - return gravity; -} + if (!layout_path || !settings) + return; -LOCAL_SYMBOL int -meta_resize_gravity_from_tile_mode (MetaTileMode mode) -{ - int gravity; + if (!logical_monitor) + logical_monitor = meta_backend_get_current_logical_monitor (backend); - gravity = -1; - switch (mode) + g_signal_emit (display, display_signals[SHOW_PAD_OSD], 0, + pad, settings, layout_path, + edition_mode, logical_monitor->number, &osd); + + if (osd) { - case META_TILE_LEFT: - gravity = WestGravity; - break; - case META_TILE_RIGHT: - gravity = EastGravity; - break; - case META_TILE_TOP: - gravity = NorthGravity; - break; - case META_TILE_BOTTOM: - gravity = SouthGravity; - break; - case META_TILE_ULC: - gravity = NorthWestGravity; - break; - case META_TILE_LLC: - gravity = SouthWestGravity; - break; - case META_TILE_URC: - gravity = NorthEastGravity; - break; - case META_TILE_LRC: - gravity = SouthEastGravity; - break; - case META_TILE_MAXIMIZE: - gravity = CenterGravity; - break; - default: - break; + display->current_pad_osd = osd; + g_object_add_weak_pointer (G_OBJECT (display->current_pad_osd), + (gpointer *) &display->current_pad_osd); } - return gravity; + g_object_unref (settings); } -static MetaScreen* -find_screen_for_selection (MetaDisplay *display, - Window owner, - Atom selection) +gchar * +meta_display_get_pad_action_label (MetaDisplay *display, + ClutterInputDevice *pad, + MetaPadActionType action_type, + guint action_number) { - GSList *tmp; + MetaInputSettings *settings; + gchar *label; - tmp = display->screens; - while (tmp != NULL) + /* First, lookup the action, as imposed by settings */ + settings = meta_backend_get_input_settings (meta_get_backend ()); + label = meta_input_settings_get_pad_action_label (settings, pad, action_type, action_number); + if (label) + return label; + +#ifdef HAVE_WAYLAND + /* Second, if this wayland, lookup the actions set by the clients */ + if (meta_is_wayland_compositor ()) { - MetaScreen *screen = tmp->data; + MetaWaylandCompositor *compositor; + MetaWaylandTabletSeat *tablet_seat; + MetaWaylandTabletPad *tablet_pad = NULL; - if (screen->wm_sn_selection_window == owner && - screen->wm_sn_atom == selection) - return screen; + compositor = meta_wayland_compositor_get_default (); + tablet_seat = meta_wayland_tablet_manager_ensure_seat (compositor->tablet_manager, + compositor->seat); + if (tablet_seat) + tablet_pad = meta_wayland_tablet_seat_lookup_pad (tablet_seat, pad); - tmp = tmp->next; + if (tablet_pad) + { + label = meta_wayland_tablet_pad_get_label (tablet_pad, action_type, + action_number); + } + + if (label) + return label; } +#endif return NULL; } -/* from fvwm2, Copyright Matthias Clasen, Dominik Vogt */ -static gboolean -convert_property (MetaDisplay *display, - MetaScreen *screen, - Window w, - Atom target, - Atom property) -{ -#define N_TARGETS 4 - Atom conversion_targets[N_TARGETS]; - long icccm_version[] = { 2, 0 }; - - conversion_targets[0] = display->atom_TARGETS; - conversion_targets[1] = display->atom_MULTIPLE; - conversion_targets[2] = display->atom_TIMESTAMP; - conversion_targets[3] = display->atom_VERSION; - - meta_error_trap_push_with_return (display); - if (target == display->atom_TARGETS) - XChangeProperty (display->xdisplay, w, property, - XA_ATOM, 32, PropModeReplace, - (unsigned char *)conversion_targets, N_TARGETS); - else if (target == display->atom_TIMESTAMP) - XChangeProperty (display->xdisplay, w, property, - XA_INTEGER, 32, PropModeReplace, - (unsigned char *)&screen->wm_sn_timestamp, 1); - else if (target == display->atom_VERSION) - XChangeProperty (display->xdisplay, w, property, - XA_INTEGER, 32, PropModeReplace, - (unsigned char *)icccm_version, 2); - else - { - meta_error_trap_pop_with_return (display); - return FALSE; - } +static void +meta_display_show_osd (MetaDisplay *display, + gint monitor_idx, + const gchar *icon_name, + const gchar *message) +{ + g_signal_emit (display, display_signals[SHOW_OSD], 0, + monitor_idx, icon_name, message); +} - if (meta_error_trap_pop_with_return (display) != Success) - return FALSE; +static gint +lookup_tablet_monitor (MetaDisplay *display, + ClutterInputDevice *device) +{ + MetaInputSettings *input_settings; + MetaLogicalMonitor *monitor; + gint monitor_idx = -1; - /* Be sure the PropertyNotify has arrived so we - * can send SelectionNotify - */ - /* FIXME the error trap pop synced anyway, right? */ - meta_topic (META_DEBUG_SYNC, "Syncing on %s\n", G_STRFUNC); - XSync (display->xdisplay, False); + input_settings = meta_backend_get_input_settings (meta_get_backend ()); + if (!input_settings) + return -1; - return TRUE; + monitor = meta_input_settings_get_tablet_logical_monitor (input_settings, device); + + if (monitor) + { + monitor_idx = meta_display_get_monitor_index_for_rect (display, + &monitor->rect); + } + + return monitor_idx; } -/* from fvwm2, Copyright Matthias Clasen, Dominik Vogt */ -static void -process_selection_request (MetaDisplay *display, - XEvent *event) +void +meta_display_show_tablet_mapping_notification (MetaDisplay *display, + ClutterInputDevice *pad, + const gchar *pretty_name) { - XSelectionEvent reply; - MetaScreen *screen; + if (!pretty_name) + pretty_name = clutter_input_device_get_device_name (pad); + meta_display_show_osd (display, lookup_tablet_monitor (display, pad), + "input-tablet-symbolic", pretty_name); +} - screen = find_screen_for_selection (display, - event->xselectionrequest.owner, - event->xselectionrequest.selection); +void +meta_display_notify_pad_group_switch (MetaDisplay *display, + ClutterInputDevice *pad, + const gchar *pretty_name, + guint n_group, + guint n_mode, + guint n_modes) +{ + GString *message; + guint i; - if (screen == NULL) - { - char *str; + if (!pretty_name) + pretty_name = clutter_input_device_get_device_name (pad); - meta_error_trap_push (display); - str = XGetAtomName (display->xdisplay, - event->xselectionrequest.selection); - meta_error_trap_pop (display); + message = g_string_new (pretty_name); + g_string_append_c (message, '\n'); + for (i = 0; i < n_modes; i++) + g_string_append (message, (i == n_mode) ? "⚫" : "⚪"); - meta_verbose ("Selection request with selection %s window 0x%lx not a WM_Sn selection we recognize\n", - str ? str : "(bad atom)", event->xselectionrequest.owner); + meta_display_show_osd (display, lookup_tablet_monitor (display, pad), + "input-tablet-symbolic", message->str); - meta_XFree (str); + g_signal_emit (display, display_signals[PAD_MODE_SWITCH], 0, pad, + n_group, n_mode); - return; - } + g_string_free (message, TRUE); +} - reply.type = SelectionNotify; - reply.display = display->xdisplay; - reply.requestor = event->xselectionrequest.requestor; - reply.selection = event->xselectionrequest.selection; - reply.target = event->xselectionrequest.target; - reply.property = None; - reply.time = event->xselectionrequest.time; +void +meta_display_foreach_window (MetaDisplay *display, + MetaListWindowsFlags flags, + MetaDisplayWindowFunc func, + gpointer data) +{ + GSList *windows; - if (event->xselectionrequest.target == display->atom_MULTIPLE) - { - if (event->xselectionrequest.property != None) - { - Atom type, *adata; - int i, format; - unsigned long num, rest; - unsigned char *data; - - meta_error_trap_push_with_return (display); - if (XGetWindowProperty (display->xdisplay, - event->xselectionrequest.requestor, - event->xselectionrequest.property, 0, 256, False, - display->atom_ATOM_PAIR, - &type, &format, &num, &rest, &data) != Success) - { - meta_error_trap_pop_with_return (display); - return; - } + /* If we end up doing this often, just keeping a list + * of windows might be sensible. + */ - if (meta_error_trap_pop_with_return (display) == Success) - { - /* FIXME: to be 100% correct, should deal with rest > 0, - * but since we have 4 possible targets, we will hardly ever - * meet multiple requests with a length > 8 - */ - adata = (Atom*)data; - i = 0; - while (i < (int) num) - { - if (!convert_property (display, screen, - event->xselectionrequest.requestor, - adata[i], adata[i+1])) - adata[i+1] = None; - i += 2; - } - - meta_error_trap_push (display); - XChangeProperty (display->xdisplay, - event->xselectionrequest.requestor, - event->xselectionrequest.property, - display->atom_ATOM_PAIR, - 32, PropModeReplace, data, num); - meta_error_trap_pop (display); - meta_XFree (data); - } - } - } - else - { - if (event->xselectionrequest.property == None) - event->xselectionrequest.property = event->xselectionrequest.target; - - if (convert_property (display, screen, - event->xselectionrequest.requestor, - event->xselectionrequest.target, - event->xselectionrequest.property)) - reply.property = event->xselectionrequest.property; - } + windows = meta_display_list_windows (display, flags); - XSendEvent (display->xdisplay, - event->xselectionrequest.requestor, - False, 0L, (XEvent*)&reply); + g_slist_foreach (windows, (GFunc) func, data); - meta_verbose ("Handled selection request\n"); + g_slist_free (windows); } static void -process_selection_clear (MetaDisplay *display, - XEvent *event) +meta_display_resize_func (MetaWindow *window, + gpointer user_data) { - /* We need to unmanage the screen on which we lost the selection */ - MetaScreen *screen; - - screen = find_screen_for_selection (display, - event->xselectionclear.window, - event->xselectionclear.selection); - - - if (screen != NULL) + if (window->struts) { - meta_verbose ("Got selection clear for screen %d on display %s\n", - screen->number, display->name); + meta_window_update_struts (window); + } + meta_window_queue (window, META_QUEUE_MOVE_RESIZE); - meta_display_unmanage_screen (display, - screen, - event->xselectionclear.time); + meta_window_recalc_features (window); +} - /* display and screen may both be invalid memory... */ +static void +on_monitors_changed_internal (MetaMonitorManager *monitor_manager, + MetaDisplay *display) +{ + MetaBackend *backend; + MetaCursorRenderer *cursor_renderer; - return; - } + meta_workspace_manager_reload_work_areas (display->workspace_manager); - { - char *str; + /* Fix up monitor for all windows on this display */ + meta_display_foreach_window (display, META_LIST_INCLUDE_OVERRIDE_REDIRECT, + (MetaDisplayWindowFunc) + meta_window_update_for_monitors_changed, 0); - meta_error_trap_push (display); - str = XGetAtomName (display->xdisplay, - event->xselectionclear.selection); - meta_error_trap_pop (display); + /* Queue a resize on all the windows */ + meta_display_foreach_window (display, META_LIST_DEFAULT, + meta_display_resize_func, 0); - meta_verbose ("Selection clear with selection %s window 0x%lx not a WM_Sn selection we recognize\n", - str ? str : "(bad atom)", event->xselectionclear.window); + meta_display_queue_check_fullscreen (display); - meta_XFree (str); - } + backend = meta_get_backend (); + cursor_renderer = meta_backend_get_cursor_renderer (backend); + meta_cursor_renderer_force_update (cursor_renderer); } void -meta_display_unmanage_screen (MetaDisplay *display, - MetaScreen *screen, - guint32 timestamp) +meta_display_restacked (MetaDisplay *display) { - meta_verbose ("Unmanaging screen %d on display %s\n", - screen->number, display->name); - - g_return_if_fail (g_slist_find (display->screens, screen) != NULL); - - meta_screen_free (screen, timestamp); - display->screens = g_slist_remove (display->screens, screen); - - if (display->screens == NULL) - meta_display_close (display, timestamp); + g_signal_emit (display, display_signals[RESTACKED], 0); } -LOCAL_SYMBOL void -meta_display_unmanage_windows_for_screen (MetaDisplay *display, - MetaScreen *screen, - guint32 timestamp) +static gboolean +meta_display_update_tile_preview_timeout (gpointer data) { - GSList *tmp; - GSList *winlist; + MetaDisplay *display = data; + MetaWindow *window = display->grab_window; + gboolean needs_preview = FALSE; - winlist = meta_display_list_windows (display, - META_LIST_INCLUDE_OVERRIDE_REDIRECT); - winlist = g_slist_sort (winlist, meta_display_stack_cmp); - g_slist_foreach (winlist, (GFunc)g_object_ref, NULL); + display->tile_preview_timeout_id = 0; - /* Unmanage all windows */ - tmp = winlist; - while (tmp != NULL) + if (window) { - MetaWindow *window = tmp->data; + switch (display->preview_tile_mode) + { + case META_TILE_LEFT: + case META_TILE_RIGHT: + if (!META_WINDOW_TILED_SIDE_BY_SIDE (window)) + needs_preview = TRUE; + break; - /* Check if already unmanaged for safety - in particular, catch - * the case where unmanaging a parent window can cause attached - * dialogs to be (temporarily) unmanaged. - */ - if (!window->unmanaging) - meta_window_unmanage (window, timestamp); - g_object_unref (window); + case META_TILE_MAXIMIZED: + if (!META_WINDOW_MAXIMIZED (window)) + needs_preview = TRUE; + break; - tmp = tmp->next; + default: + needs_preview = FALSE; + break; + } } - g_slist_free (winlist); -} -LOCAL_SYMBOL int -meta_display_stack_cmp (const void *a, - const void *b) -{ - MetaWindow *aw = (void*) a; - MetaWindow *bw = (void*) b; + if (needs_preview) + { + MetaRectangle tile_rect; + int monitor; - if (aw->screen == bw->screen) - return meta_stack_windows_cmp (aw->screen->stack, aw, bw); - /* Then assume screens are stacked by number */ - else if (aw->screen->number < bw->screen->number) - return -1; - else if (aw->screen->number > bw->screen->number) - return 1; + monitor = meta_window_get_current_tile_monitor_number (window); + meta_window_get_tile_area (window, display->preview_tile_mode, + &tile_rect); + meta_compositor_show_tile_preview (display->compositor, + window, &tile_rect, monitor); + } else - return 0; /* not reached in theory, if windows on same display */ -} + meta_compositor_hide_tile_preview (display->compositor); -/** - * meta_display_sort_windows_by_stacking: - * @display: a #MetaDisplay - * @windows: (element-type MetaWindow): Set of windows - * - * Sorts a set of windows according to their current stacking order. If windows - * from multiple screens are present in the set of input windows, then all the - * windows on screen 0 are sorted below all the windows on screen 1, and so forth. - * Since the stacking order of override-redirect windows isn't controlled by - * Metacity, if override-redirect windows are in the input, the result may not - * correspond to the actual stacking order in the X server. - * - * An example of using this would be to sort the list of transient dialogs for a - * window into their current stacking order. - * - * Returns: (transfer container) (element-type MetaWindow): Input windows sorted by stacking order, from lowest to highest - */ -GSList * -meta_display_sort_windows_by_stacking (MetaDisplay *display, - GSList *windows) + return FALSE; +} + +#define TILE_PREVIEW_TIMEOUT_MS 200 + +void +meta_display_update_tile_preview (MetaDisplay *display, + gboolean delay) { - GSList *copy = g_slist_copy (windows); + if (delay) + { + if (display->tile_preview_timeout_id > 0) + return; - copy = g_slist_sort (copy, meta_display_stack_cmp); + display->tile_preview_timeout_id = + g_timeout_add (TILE_PREVIEW_TIMEOUT_MS, + meta_display_update_tile_preview_timeout, + display); + g_source_set_name_by_id (display->tile_preview_timeout_id, + "[mutter] meta_display_update_tile_preview_timeout"); + } + else + { + g_clear_handle_id (&display->tile_preview_timeout_id, g_source_remove); - return copy; + meta_display_update_tile_preview_timeout ((gpointer)display); + } } -LOCAL_SYMBOL void -meta_display_devirtualize_modifiers (MetaDisplay *display, - MetaVirtualModifier modifiers, - unsigned int *mask) -{ - *mask = 0; - - if (modifiers & META_VIRTUAL_SHIFT_MASK) - *mask |= ShiftMask; - if (modifiers & META_VIRTUAL_CONTROL_MASK) - *mask |= ControlMask; - if (modifiers & META_VIRTUAL_ALT_MASK) - *mask |= Mod1Mask; - if (modifiers & META_VIRTUAL_META_MASK) - *mask |= display->meta_mask; - if (modifiers & META_VIRTUAL_HYPER_MASK) - *mask |= display->hyper_mask; - if (modifiers & META_VIRTUAL_SUPER_MASK) - *mask |= display->super_mask; - if (modifiers & META_VIRTUAL_MOD2_MASK) - *mask |= Mod2Mask; - if (modifiers & META_VIRTUAL_MOD3_MASK) - *mask |= Mod3Mask; - if (modifiers & META_VIRTUAL_MOD4_MASK) - *mask |= Mod4Mask; - if (modifiers & META_VIRTUAL_MOD5_MASK) - *mask |= Mod5Mask; -} +void +meta_display_hide_tile_preview (MetaDisplay *display) +{ + g_clear_handle_id (&display->tile_preview_timeout_id, g_source_remove); -static void -update_window_grab_modifiers (MetaDisplay *display) + display->preview_tile_mode = META_TILE_NONE; + meta_compositor_hide_tile_preview (display->compositor); +} +static MetaStartupSequence * +find_startup_sequence_by_wmclass (MetaDisplay *display, + MetaWindow *window) { - MetaVirtualModifier virtual_mods; - unsigned int mods; + GSList *startup_sequences, *l; - virtual_mods = meta_prefs_get_mouse_button_mods (); - meta_display_devirtualize_modifiers (display, virtual_mods, - &mods); + startup_sequences = + meta_startup_notification_get_sequences (display->startup_notification); - display->window_grab_modifiers = mods; -} + for (l = startup_sequences; l; l = l->next) + { + MetaStartupSequence *sequence = l->data; + const char *wmclass; -static void -update_mouse_zoom_modifiers (MetaDisplay *display) -{ - MetaVirtualModifier virtual_mods; - unsigned int mods; + wmclass = meta_startup_sequence_get_wmclass (sequence); - virtual_mods = meta_prefs_get_mouse_button_zoom_mods (); - meta_display_devirtualize_modifiers (display, virtual_mods, - &mods); + if (wmclass != NULL && + ((window->res_class && + strcmp (wmclass, window->res_class) == 0) || + (window->res_name && + strcmp (wmclass, window->res_name) == 0))) + return sequence; + } - display->mouse_zoom_modifiers = mods; + return NULL; } -static void -prefs_changed_callback (MetaPreference pref, - void *data) +/* Sets the initial_timestamp and initial_workspace properties + * of a window according to information given us by the + * startup-notification library. + * + * Returns TRUE if startup properties have been applied, and + * FALSE if they have not (for example, if they had already + * been applied.) + */ +gboolean +meta_display_apply_startup_properties (MetaDisplay *display, + MetaWindow *window) { - /* It may not be obvious why we regrab on focus mode - * change; it's because we handle focus clicks a - * bit differently for the different focus modes. - */ - if (pref == META_PREF_MOUSE_BUTTON_MODS || - pref == META_PREF_FOCUS_MODE || - pref == META_PREF_MOUSE_BUTTON_ZOOM_MODS || - pref == META_PREF_MOUSE_ZOOM_ENABLED) - { - MetaDisplay *display = data; - GSList *windows; - GSList *tmp; + const char *startup_id; + MetaStartupSequence *sequence = NULL; - windows = meta_display_list_windows (display, META_LIST_DEFAULT); + /* Does the window have a startup ID stored? */ + startup_id = meta_window_get_startup_id (window); - /* Ungrab all */ - tmp = windows; - while (tmp != NULL) + meta_topic (META_DEBUG_STARTUP, + "Applying startup props to %s id \"%s\"\n", + window->desc, + startup_id ? startup_id : "(none)"); + + if (!startup_id) + { + /* No startup ID stored for the window. Let's ask the + * startup-notification library whether there's anything + * stored for the resource name or resource class hints. + */ + sequence = find_startup_sequence_by_wmclass (display, window); + + if (sequence) { - MetaWindow *w = tmp->data; - meta_display_ungrab_window_buttons (display, w->xwindow); + g_assert (window->startup_id == NULL); + window->startup_id = g_strdup (meta_startup_sequence_get_id (sequence)); + startup_id = window->startup_id; - if (w->frame) - { - meta_display_ungrab_window_buttons (display, w->frame->xwindow); - } + meta_topic (META_DEBUG_STARTUP, + "Ending legacy sequence %s due to window %s\n", + meta_startup_sequence_get_id (sequence), + window->desc); - meta_display_ungrab_focus_window_button (display, w); - tmp = tmp->next; + meta_startup_sequence_complete (sequence); } + } + + /* Still no startup ID? Bail. */ + if (!startup_id) + return FALSE; - /* change our modifier */ - if (pref == META_PREF_MOUSE_BUTTON_MODS) - update_window_grab_modifiers (display); + /* We might get this far and not know the sequence ID (if the window + * already had a startup ID stored), so let's look for one if we don't + * already know it. + */ + if (sequence == NULL) + { + sequence = + meta_startup_notification_lookup_sequence (display->startup_notification, + startup_id); + } - if (pref == META_PREF_MOUSE_BUTTON_ZOOM_MODS) - update_mouse_zoom_modifiers (display); + if (sequence != NULL) + { + gboolean changed_something = FALSE; - display->mouse_zoom_enabled = meta_prefs_get_mouse_zoom_enabled (); + meta_topic (META_DEBUG_STARTUP, + "Found startup sequence for window %s ID \"%s\"\n", + window->desc, startup_id); - /* Grab all */ - tmp = windows; - while (tmp != NULL) + if (!window->initial_workspace_set) { - MetaWindow *w = tmp->data; - if (w->type != META_WINDOW_DOCK) + int space = meta_startup_sequence_get_workspace (sequence); + if (space >= 0) { - meta_display_grab_focus_window_button (display, w); - meta_display_grab_window_buttons (display, w->xwindow); + meta_topic (META_DEBUG_STARTUP, + "Setting initial window workspace to %d based on startup info\n", + space); - if (w->frame) - { - meta_display_grab_window_buttons (display, w->frame->xwindow); - } + window->initial_workspace_set = TRUE; + window->initial_workspace = space; + changed_something = TRUE; } - tmp = tmp->next; } - g_slist_free (windows); + if (!window->initial_timestamp_set) + { + guint32 timestamp = meta_startup_sequence_get_timestamp (sequence); + meta_topic (META_DEBUG_STARTUP, + "Setting initial window timestamp to %u based on startup info\n", + timestamp); + + window->initial_timestamp_set = TRUE; + window->initial_timestamp = timestamp; + changed_something = TRUE; + } + + return changed_something; + } + else + { + meta_topic (META_DEBUG_STARTUP, + "Did not find startup sequence for window %s ID \"%s\"\n", + window->desc, startup_id); } + + return FALSE; } -LOCAL_SYMBOL void -meta_display_increment_focus_sentinel (MetaDisplay *display) +static gboolean +set_work_area_later_func (MetaDisplay *display) { - unsigned long data[1]; + meta_topic (META_DEBUG_WORKAREA, + "Running work area hint computation function\n"); - data[0] = meta_display_get_current_time (display); + display->work_area_later = 0; - XChangeProperty (display->xdisplay, - ((MetaScreen*) display->screens->data)->xroot, - display->atom__MUFFIN_SENTINEL, - XA_CARDINAL, - 32, PropModeReplace, (guchar*) data, 1); + g_signal_emit (display, display_signals[WORKAREAS_CHANGED], 0); - display->sentinel_counter += 1; + return FALSE; } -LOCAL_SYMBOL void -meta_display_decrement_focus_sentinel (MetaDisplay *display) +void +meta_display_queue_workarea_recalc (MetaDisplay *display) { - display->sentinel_counter -= 1; - - if (display->sentinel_counter < 0) - display->sentinel_counter = 0; + /* Recompute work area later before redrawing */ + if (display->work_area_later == 0) + { + meta_topic (META_DEBUG_WORKAREA, + "Adding work area hint computation function\n"); + display->work_area_later = + meta_later_add (META_LATER_BEFORE_REDRAW, + (GSourceFunc) set_work_area_later_func, + display, + NULL); + } } -LOCAL_SYMBOL gboolean -meta_display_focus_sentinel_clear (MetaDisplay *display) +static gboolean +check_fullscreen_func (gpointer data) { - return (display->sentinel_counter == 0); -} + MetaDisplay *display = data; + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + GList *logical_monitors, *l; + MetaWindow *window; + GSList *fullscreen_monitors = NULL; + GSList *obscured_monitors = NULL; + gboolean in_fullscreen_changed = FALSE; -static void -sanity_check_timestamps (MetaDisplay *display, - guint32 timestamp) -{ - if (XSERVER_TIME_IS_BEFORE (timestamp, display->last_focus_time)) - { - meta_warning ("last_focus_time (%u) is greater than comparison " - "timestamp (%u). This most likely represents a buggy " - "client sending inaccurate timestamps in messages such as " - "_NET_ACTIVE_WINDOW. Trying to work around...\n", - display->last_focus_time, timestamp); - display->last_focus_time = timestamp; - } - if (XSERVER_TIME_IS_BEFORE (timestamp, display->last_user_time)) + display->check_fullscreen_later = 0; + + logical_monitors = + meta_monitor_manager_get_logical_monitors (monitor_manager); + + /* We consider a monitor in fullscreen if it contains a fullscreen window; + * however we make an exception for maximized windows above the fullscreen + * one, as in that case window+chrome fully obscure the fullscreen window. + */ + for (window = meta_stack_get_top (display->stack); + window; + window = meta_stack_get_below (display->stack, window, FALSE)) { - GSList *windows; - GSList *tmp; + gboolean covers_monitors = FALSE; - meta_warning ("last_user_time (%u) is greater than comparison " - "timestamp (%u). This most likely represents a buggy " - "client sending inaccurate timestamps in messages such as " - "_NET_ACTIVE_WINDOW. Trying to work around...\n", - display->last_user_time, timestamp); - display->last_user_time = timestamp; + if (window->hidden) + continue; - windows = meta_display_list_windows (display, META_LIST_DEFAULT); - tmp = windows; - while (tmp != NULL) + if (window->fullscreen) { - MetaWindow *window = tmp->data; + covers_monitors = TRUE; + } + else if (window->override_redirect) + { + /* We want to handle the case where an application is creating an + * override-redirect window the size of the screen (monitor) and treat + * it similarly to a fullscreen window, though it doesn't have fullscreen + * window management behavior. (Being O-R, it's not managed at all.) + */ + if (meta_window_is_monitor_sized (window)) + covers_monitors = TRUE; + } + else if (window->maximized_horizontally && + window->maximized_vertically) + { + MetaLogicalMonitor *logical_monitor; - if (XSERVER_TIME_IS_BEFORE (timestamp, window->net_wm_user_time)) + logical_monitor = meta_window_get_main_logical_monitor (window); + if (!g_slist_find (obscured_monitors, logical_monitor)) + obscured_monitors = g_slist_prepend (obscured_monitors, + logical_monitor); + } + + if (covers_monitors) + { + MetaRectangle window_rect; + + meta_window_get_frame_rect (window, &window_rect); + + for (l = logical_monitors; l; l = l->next) { - meta_warning ("%s appears to be one of the offending windows " - "with a timestamp of %u. Working around...\n", - window->desc, window->net_wm_user_time); - meta_window_set_user_time (window, timestamp); + MetaLogicalMonitor *logical_monitor = l->data; + + if (meta_rectangle_overlap (&window_rect, + &logical_monitor->rect) && + !g_slist_find (fullscreen_monitors, logical_monitor) && + !g_slist_find (obscured_monitors, logical_monitor)) + fullscreen_monitors = g_slist_prepend (fullscreen_monitors, + logical_monitor); } - - tmp = tmp->next; } - - g_slist_free (windows); } -} -static gboolean -timestamp_too_old (MetaDisplay *display, - MetaWindow *window, - guint32 *timestamp) -{ - /* FIXME: If Soeren's suggestion in bug 151984 is implemented, it will allow - * us to sanity check the timestamp here and ensure it doesn't correspond to - * a future time (though we would want to rename to - * timestamp_too_old_or_in_future). - */ + g_slist_free (obscured_monitors); - if (*timestamp == CurrentTime) - { - meta_warning ("Got a request to focus %s with a timestamp of 0. This " - "shouldn't happen!\n", - window ? window->desc : "the no_focus_window"); - meta_print_backtrace (); - *timestamp = meta_display_get_current_time_roundtrip (display); - return FALSE; - } - else if (XSERVER_TIME_IS_BEFORE (*timestamp, display->last_focus_time)) + for (l = logical_monitors; l; l = l->next) { - if (XSERVER_TIME_IS_BEFORE (*timestamp, display->last_user_time)) - { - meta_topic (META_DEBUG_FOCUS, - "Ignoring focus request for %s since %u " - "is less than %u and %u.\n", - window ? window->desc : "the no_focus_window", - *timestamp, - display->last_user_time, - display->last_focus_time); - return TRUE; - } - else + MetaLogicalMonitor *logical_monitor = l->data; + gboolean in_fullscreen; + + in_fullscreen = g_slist_find (fullscreen_monitors, + logical_monitor) != NULL; + if (in_fullscreen != logical_monitor->in_fullscreen) { - meta_topic (META_DEBUG_FOCUS, - "Received focus request for %s which is newer than most " - "recent user_time, but less recent than " - "last_focus_time (%u < %u < %u); adjusting " - "accordingly. (See bug 167358)\n", - window ? window->desc : "the no_focus_window", - display->last_user_time, - *timestamp, - display->last_focus_time); - *timestamp = display->last_focus_time; - return FALSE; + logical_monitor->in_fullscreen = in_fullscreen; + in_fullscreen_changed = TRUE; } } + g_slist_free (fullscreen_monitors); + + if (in_fullscreen_changed) + { + /* DOCK window stacking depends on the monitor's fullscreen + status so we need to trigger a re-layering. */ + MetaWindow *window = meta_stack_get_top (display->stack); + if (window) + meta_stack_update_layer (display->stack, window); + + g_signal_emit (display, display_signals[IN_FULLSCREEN_CHANGED], 0, NULL); + } + return FALSE; } void -meta_display_set_input_focus_window (MetaDisplay *display, - MetaWindow *window, - gboolean focus_frame, - guint32 timestamp) +meta_display_queue_check_fullscreen (MetaDisplay *display) { - if (timestamp_too_old (display, window, ×tamp)) - return; - - meta_error_trap_push (display); - XSetInputFocus (display->xdisplay, - focus_frame ? window->frame->xwindow : window->xwindow, - RevertToPointerRoot, - timestamp); - meta_error_trap_pop (display); - - display->expected_focus_window = window; - display->last_focus_time = timestamp; - display->active_screen = window->screen; - - if (window != display->autoraise_window) - meta_display_remove_autoraise_callback (window->display); + if (!display->check_fullscreen_later) + display->check_fullscreen_later = meta_later_add (META_LATER_CHECK_FULLSCREEN, + check_fullscreen_func, + display, NULL); } -void -meta_display_focus_the_no_focus_window (MetaDisplay *display, - MetaScreen *screen, - guint32 timestamp) +int +meta_display_get_monitor_index_for_rect (MetaDisplay *display, + MetaRectangle *rect) { - if (timestamp_too_old (display, NULL, ×tamp)) - return; + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaLogicalMonitor *logical_monitor; - XSetInputFocus (display->xdisplay, - screen->no_focus_window, - RevertToPointerRoot, - timestamp); - display->expected_focus_window = NULL; - display->last_focus_time = timestamp; - display->active_screen = screen; + logical_monitor = + meta_monitor_manager_get_logical_monitor_from_rect (monitor_manager, rect); + if (!logical_monitor) + return -1; - meta_display_remove_autoraise_callback (display); + return logical_monitor->number; } -LOCAL_SYMBOL void -meta_display_remove_autoraise_callback (MetaDisplay *display) +int +meta_display_get_monitor_neighbor_index (MetaDisplay *display, + int which_monitor, + MetaDisplayDirection direction) { - if (display->autoraise_timeout_id != 0) - { - g_source_remove (display->autoraise_timeout_id); - display->autoraise_timeout_id = 0; - display->autoraise_window = NULL; - } + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaLogicalMonitor *logical_monitor; + MetaLogicalMonitor *neighbor; + + logical_monitor = + meta_monitor_manager_get_logical_monitor_from_number (monitor_manager, + which_monitor); + neighbor = meta_monitor_manager_get_logical_monitor_neighbor (monitor_manager, + logical_monitor, + direction); + return neighbor ? neighbor->number : -1; } -void -meta_display_get_compositor_version (MetaDisplay *display, - int *major, - int *minor) +/** + * meta_display_get_current_monitor: + * @display: a #MetaDisplay + * + * Gets the index of the monitor that currently has the mouse pointer. + * + * Return value: a monitor index + */ +int +meta_display_get_current_monitor (MetaDisplay *display) { - *major = display->composite_major_version; - *minor = display->composite_minor_version; + MetaBackend *backend = meta_get_backend (); + MetaLogicalMonitor *logical_monitor; + + logical_monitor = meta_backend_get_current_logical_monitor (backend); + + /* Pretend its the first when there is no actual current monitor. */ + if (!logical_monitor) + return 0; + + return logical_monitor->number; } /** - * meta_display_get_xdisplay: (skip) + * meta_display_get_n_monitors: + * @display: a #MetaDisplay + * + * Gets the number of monitors that are joined together to form @display. * + * Return value: the number of monitors */ -Display * -meta_display_get_xdisplay (MetaDisplay *display) +int +meta_display_get_n_monitors (MetaDisplay *display) { - return display->xdisplay; + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + + g_return_val_if_fail (META_IS_DISPLAY (display), 0); + + return meta_monitor_manager_get_num_logical_monitors (monitor_manager); } /** - * meta_display_get_compositor: (skip) + * meta_display_get_primary_monitor: + * @display: a #MetaDisplay + * + * Gets the index of the primary monitor on this @display. * + * Return value: a monitor index */ -MetaCompositor * -meta_display_get_compositor (MetaDisplay *display) +int +meta_display_get_primary_monitor (MetaDisplay *display) { - return display->compositor; + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaLogicalMonitor *logical_monitor; + + g_return_val_if_fail (META_IS_DISPLAY (display), 0); + + logical_monitor = + meta_monitor_manager_get_primary_logical_monitor (monitor_manager); + if (logical_monitor) + return logical_monitor->number; + else + return 0; } /** - * meta_display_get_screens: + * meta_display_get_monitor_geometry: * @display: a #MetaDisplay + * @monitor: the monitor number + * @geometry: (out): location to store the monitor geometry * - * Returns: (transfer none) (element-type Meta.Screen): Screens for this display + * Stores the location and size of the indicated @monitor in @geometry. */ -GSList * -meta_display_get_screens (MetaDisplay *display) -{ - return display->screens; +void +meta_display_get_monitor_geometry (MetaDisplay *display, + int monitor, + MetaRectangle *geometry) +{ + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaLogicalMonitor *logical_monitor; +#ifndef G_DISABLE_CHECKS + int n_logical_monitors = + meta_monitor_manager_get_num_logical_monitors (monitor_manager); +#endif + + g_return_if_fail (META_IS_DISPLAY (display)); + g_return_if_fail (monitor >= 0 && monitor < n_logical_monitors); + g_return_if_fail (geometry != NULL); + + logical_monitor = + meta_monitor_manager_get_logical_monitor_from_number (monitor_manager, + monitor); + *geometry = logical_monitor->rect; } -gboolean -meta_display_has_shape (MetaDisplay *display) -{ - return META_DISPLAY_HAS_SHAPE (display); +/** + * meta_display_get_monitor_scale: + * @display: a #MetaDisplay + * @monitor: the monitor number + * + * Gets the monitor scaling value for the given @monitor. + * + * Return value: the monitor scaling value + */ +float +meta_display_get_monitor_scale (MetaDisplay *display, + int monitor) +{ + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaLogicalMonitor *logical_monitor; +#ifndef G_DISABLE_CHECKS + int n_logical_monitors = + meta_monitor_manager_get_num_logical_monitors (monitor_manager); +#endif + + g_return_val_if_fail (META_IS_DISPLAY (display), 1.0f); + g_return_val_if_fail (monitor >= 0 && monitor < n_logical_monitors, 1.0f); + + logical_monitor = + meta_monitor_manager_get_logical_monitor_from_number (monitor_manager, + monitor); + return logical_monitor->scale; } /** - * meta_display_get_focus_window: + * meta_display_get_monitor_in_fullscreen: * @display: a #MetaDisplay + * @monitor: the monitor number * - * Get the window that, according to events received from X server, - * currently has the input focus. We may have already sent a request - * to the X server to move the focus window elsewhere. (The - * expected_focus_window records where we've last set the input - * focus.) + * Determines whether there is a fullscreen window obscuring the specified + * monitor. If there is a fullscreen window, the desktop environment will + * typically hide any controls that might obscure the fullscreen window. * - * Return Value: (transfer none): The current focus window + * You can get notification when this changes by connecting to + * MetaDisplay::in-fullscreen-changed. + * + * Returns: %TRUE if there is a fullscreen window covering the specified monitor. */ -MetaWindow * -meta_display_get_focus_window (MetaDisplay *display) -{ - return display->focus_window; +gboolean +meta_display_get_monitor_in_fullscreen (MetaDisplay *display, + int monitor) +{ + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaLogicalMonitor *logical_monitor; +#ifndef G_DISABLE_CHECKS + int n_logical_monitors = + meta_monitor_manager_get_num_logical_monitors (monitor_manager); +#endif + + g_return_val_if_fail (META_IS_DISPLAY (display), FALSE); + g_return_val_if_fail (monitor >= 0 && + monitor < n_logical_monitors, FALSE); + + logical_monitor = + meta_monitor_manager_get_logical_monitor_from_number (monitor_manager, + monitor); + + /* We use -1 as a flag to mean "not known yet" for notification + purposes */ return logical_monitor->in_fullscreen == TRUE; } -int -meta_display_get_damage_event_base (MetaDisplay *display) +MetaWindow * +meta_display_get_pointer_window (MetaDisplay *display, + MetaWindow *not_this_one) { - return display->damage_event_base; + MetaWorkspaceManager *workspace_manager = display->workspace_manager; + MetaBackend *backend = meta_get_backend (); + MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend); + MetaWindow *window; + int x, y; + + if (not_this_one) + meta_topic (META_DEBUG_FOCUS, + "Focusing mouse window excluding %s\n", not_this_one->desc); + + meta_cursor_tracker_get_pointer (cursor_tracker, &x, &y, NULL); + + window = meta_stack_get_default_focus_window_at_point (display->stack, + workspace_manager->active_workspace, + not_this_one, + x, y); + + return window; } -#ifdef HAVE_SHAPE -int -meta_display_get_shape_event_base (MetaDisplay *display) +void +meta_display_focus_default_window (MetaDisplay *display, + guint32 timestamp) { - return display->shape_event_base; + MetaWorkspaceManager *workspace_manager = display->workspace_manager; + + meta_workspace_focus_default_window (workspace_manager->active_workspace, + NULL, + timestamp); } -#endif /** - * meta_display_get_leader_window: + * meta_display_get_workspace_manager: * @display: a #MetaDisplay * - * Returns the window manager's leader window (as defined by the - * _NET_SUPPORTING_WM_CHECK mechanism of EWMH). For use by plugins that wish - * to attach additional custom properties to this window. - * - * Return value: xid of the leader window. - **/ -Window -meta_display_get_leader_window (MetaDisplay *display) + * Returns: (transfer none): The workspace manager of the display + */ +MetaWorkspaceManager * +meta_display_get_workspace_manager (MetaDisplay *display) { - return display->leader_window; + return display->workspace_manager; } -static gboolean -meta_display_restart_internal (MetaDisplay *display) +MetaStartupNotification * +meta_display_get_startup_notification (MetaDisplay *display) { - GPtrArray *arr; - gsize len; + return display->startup_notification; +} - char *buf; - char *buf_p; - char *buf_end; - GError *error = NULL; +MetaWindow * +meta_display_get_window_from_id (MetaDisplay *display, + uint64_t window_id) +{ + g_autoptr (GSList) windows = NULL; + GSList *l; - if (!g_file_get_contents ("/proc/self/cmdline", &buf, &len, &error)) + windows = meta_display_list_windows (display, META_LIST_DEFAULT); + for (l = windows; l; l = l->next) { - g_warning ("Failed to get /proc/self/cmdline: %s", error->message); - return FALSE; - } + MetaWindow *window = l->data; - buf_end = buf+len; - arr = g_ptr_array_new (); - /* The cmdline file is NUL-separated */ - for (buf_p = buf; buf_p < buf_end; buf_p = buf_p + strlen (buf_p) + 1) - g_ptr_array_add (arr, buf_p); - - g_ptr_array_add (arr, NULL); - - /* Close all file descriptors other than stdin/stdout/stderr, otherwise - * they will leak and stay open after the exec. In particular, this is - * important for file descriptors that represent mapped graphics buffer - * objects. - */ - meta_pre_exec_close_fds (); - - meta_display_unmanage_screen (display, - (MetaScreen*) display->screens->data, - meta_display_get_current_time (display)); + if (window->id == window_id) + return window; + } - execvp (arr->pdata[0], (char**)arr->pdata); - g_warning ("Failed to reexec: %s", g_strerror (errno)); - g_ptr_array_free (arr, TRUE); - free (buf); - return FALSE; + return NULL; } -LOCAL_SYMBOL void -meta_display_notify_restart (MetaDisplay *display) +uint64_t +meta_display_generate_window_id (MetaDisplay *display) { - g_signal_emit (display, display_signals[RESTART], 0); + static uint64_t base_window_id; + static uint64_t last_window_id; + + if (!base_window_id) + base_window_id = g_random_int () + 1; + + /* We can overflow here, that's fine */ + return (base_window_id + last_window_id++); } /** - * meta_display_restart: + * meta_display_get_sound_player: * @display: a #MetaDisplay * - * Restart the current process. Only intended for development purposes. + * Returns: (transfer none): The sound player of the display */ -void -meta_display_restart (MetaDisplay *display) +MetaSoundPlayer * +meta_display_get_sound_player (MetaDisplay *display) { - g_idle_add_full (G_PRIORITY_LOW, - (GSourceFunc) meta_display_restart_internal, - display, NULL); + return display->sound_player; } -void -meta_display_update_sync_state (MetaSyncMethod method) +/** + * meta_display_get_selection: + * @display: a #MetaDisplay + * + * Returns: (transfer none): The selection manager of the display + */ +MetaSelection * +meta_display_get_selection (MetaDisplay *display) { - meta_compositor_update_sync_state (the_display->compositor, method); + return display->selection; } diff --git a/src/core/edge-resistance.c b/src/core/edge-resistance.c index 88e9c11ba..cf23e2604 100644 --- a/src/core/edge-resistance.c +++ b/src/core/edge-resistance.c @@ -16,23 +16,23 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ -#include <config.h> -#include "edge-resistance.h" -#include "boxes-private.h" -#include "display-private.h" -#include "workspace-private.h" +#include "config.h" + +#include "core/edge-resistance.h" + +#include "core/boxes-private.h" +#include "core/display-private.h" +#include "core/meta-workspace-manager-private.h" +#include "core/workspace-private.h" /* A simple macro for whether a given window's edges are potentially * relevant for resistance/snapping during a move/resize operation */ #define WINDOW_EDGES_RELEVANT(window, display) \ meta_window_should_be_showing (window) && \ - window->screen == display->grab_screen && \ window != display->grab_window && \ window->type != META_WINDOW_DESKTOP && \ window->type != META_WINDOW_MENU && \ @@ -196,10 +196,12 @@ find_nearest_position (const GArray *edges, int best, best_dist, i; gboolean edges_align; - /* Initialize mid in the off chance that the array only + /* Initialize mid, edge, & compare in the off change that the array only * has one element. */ mid = 0; + edge = g_array_index (edges, MetaEdge*, mid); + compare = horizontal ? edge->rect.x : edge->rect.y; /* Begin the search... */ low = 0; @@ -283,6 +285,7 @@ find_nearest_position (const GArray *edges, if (dist < best_dist) { best = compare; + best_dist = dist; } break; } @@ -305,6 +308,7 @@ movement_towards_edge (MetaSide side, int increment) return increment > 0; default: g_assert_not_reached (); + return FALSE; } } @@ -347,10 +351,6 @@ apply_edge_resistance (MetaWindow *window, const int TIMEOUT_RESISTANCE_LENGTH_MS_MONITOR = 0; const int TIMEOUT_RESISTANCE_LENGTH_MS_SCREEN = 0; - /* Edge resistance can be disabled in gettings. */ - if (!meta_prefs_get_edge_resistance_window ()) - return new_pos; - /* Quit if no movement was specified */ if (old_pos == new_pos) return new_pos; @@ -363,11 +363,7 @@ apply_edge_resistance (MetaWindow *window, resistance_data->timeout_edge_pos < new_pos))) { resistance_data->timeout_setup = FALSE; - if (resistance_data->timeout_id != 0) - { - g_source_remove (resistance_data->timeout_id); - resistance_data->timeout_id = 0; - } + g_clear_handle_id (&resistance_data->timeout_id, g_source_remove); } /* Get the range of indices in the edge array that we move past/to. */ @@ -441,6 +437,8 @@ apply_edge_resistance (MetaWindow *window, g_timeout_add (timeout_length_ms, edge_resistance_timeout, resistance_data); + g_source_set_name_by_id (resistance_data->timeout_id, + "[mutter] edge_resistance_timeout"); resistance_data->timeout_setup = TRUE; resistance_data->timeout_edge_pos = compare; resistance_data->timeout_over = FALSE; @@ -558,7 +556,7 @@ apply_edge_resistance_to_each_side (MetaDisplay *display, edge_data = display->grab_edge_resistance_data; - if (auto_snap) + if (auto_snap && !META_WINDOW_TILED_SIDE_BY_SIDE (window)) { /* Do the auto snapping instead of normal edge resistance; in all * cases, we allow snapping to opposite kinds of edges (e.g. left @@ -593,6 +591,50 @@ apply_edge_resistance_to_each_side (MetaDisplay *display, FALSE, keyboard_op); } + else if (auto_snap && META_WINDOW_TILED_SIDE_BY_SIDE (window)) + { + MetaRectangle workarea; + guint i; + + const gfloat tile_edges[] = + { + 1./4., + 1./3., + 1./2., + 2./3., + 3./4., + }; + + meta_window_get_work_area_current_monitor (window, &workarea); + + new_left = new_outer->x; + new_top = new_outer->y; + new_right = new_outer->x + new_outer->width; + new_bottom = new_outer->y + new_outer->height; + + /* When snapping tiled windows, we don't really care about the + * x and y position, only about the width and height. Also, it + * is special-cased (instead of relying on edge_data) because + * we don't really care for other windows when calculating the + * snapping points of tiled windows - we only care about the + * work area and the target position. + */ + for (i = 0; i < G_N_ELEMENTS (tile_edges); i++) + { + guint horizontal_point = workarea.x + floor (workarea.width * tile_edges[i]); + + if (ABS (horizontal_point - new_left) < 16) + { + new_left = horizontal_point; + new_right = workarea.x + workarea.width; + } + else if (ABS (horizontal_point - new_right) < 16) + { + new_left = workarea.x; + new_right = horizontal_point; + } + } + } else { /* Disable edge resistance for resizes when windows have size @@ -669,7 +711,7 @@ apply_edge_resistance_to_each_side (MetaDisplay *display, return modified; } -LOCAL_SYMBOL void +void meta_display_cleanup_edges (MetaDisplay *display) { guint i,j; @@ -681,7 +723,7 @@ meta_display_cleanup_edges (MetaDisplay *display) /* We first need to clean out any window edges */ edges_to_be_freed = g_hash_table_new_full (g_direct_hash, g_direct_equal, - free, NULL); + g_free, NULL); for (i = 0; i < 4; i++) { GArray *tmp = NULL; @@ -724,7 +766,7 @@ meta_display_cleanup_edges (MetaDisplay *display) } } - /* Now free all the window edges (the key destroy function is free) */ + /* Now free all the window edges (the key destroy function is g_free) */ g_hash_table_destroy (edges_to_be_freed); /* Now free the arrays and data */ @@ -738,24 +780,16 @@ meta_display_cleanup_edges (MetaDisplay *display) edge_data->bottom_edges = NULL; /* Cleanup the timeouts */ - if (edge_data->left_data.timeout_setup && edge_data->left_data.timeout_id != 0) { - g_source_remove (edge_data->left_data.timeout_id); - edge_data->left_data.timeout_id = 0; - } - if (edge_data->right_data.timeout_setup && edge_data->right_data.timeout_id != 0) { - g_source_remove (edge_data->right_data.timeout_id); - edge_data->right_data.timeout_id = 0; - } - if (edge_data->top_data.timeout_setup && edge_data->top_data.timeout_id != 0) { - g_source_remove (edge_data->top_data.timeout_id); - edge_data->top_data.timeout_id = 0; - } - if (edge_data->bottom_data.timeout_setup && edge_data->bottom_data.timeout_id != 0) { - g_source_remove (edge_data->bottom_data.timeout_id); - edge_data->bottom_data.timeout_id = 0; - } - - free (display->grab_edge_resistance_data); + if (edge_data->left_data.timeout_setup) + g_clear_handle_id (&edge_data->left_data.timeout_id, g_source_remove); + if (edge_data->right_data.timeout_setup) + g_clear_handle_id (&edge_data->right_data.timeout_id, g_source_remove); + if (edge_data->top_data.timeout_setup) + g_clear_handle_id (&edge_data->top_data.timeout_id, g_source_remove); + if (edge_data->bottom_data.timeout_setup) + g_clear_handle_id (&edge_data->bottom_data.timeout_id, g_source_remove); + + g_free (display->grab_edge_resistance_data); display->grab_edge_resistance_data = NULL; } @@ -961,6 +995,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display) * in the layer that we are working on */ GSList *rem_windows, *rem_win_stacking; + MetaWorkspaceManager *workspace_manager = display->workspace_manager; g_assert (display->grab_window != NULL); meta_topic (META_DEBUG_WINDOW_OPS, @@ -971,8 +1006,8 @@ compute_resistance_and_snapping_edges (MetaDisplay *display) * 1st: Get the list of relevant windows, from bottom to top */ stacked_windows = - meta_stack_list_windows (display->grab_screen->stack, - display->grab_screen->active_workspace); + meta_stack_list_windows (display->stack, + workspace_manager->active_workspace); /* * 2nd: we need to separate that stacked list into a list of windows that @@ -990,9 +1025,9 @@ compute_resistance_and_snapping_edges (MetaDisplay *display) { MetaRectangle *new_rect; new_rect = g_new (MetaRectangle, 1); - meta_window_get_outer_rect (cur_window, new_rect); + meta_window_get_frame_rect (cur_window, new_rect); obscuring_windows = g_slist_prepend (obscuring_windows, new_rect); - window_stacking = + window_stacking = g_slist_prepend (window_stacking, GINT_TO_POINTER (stack_position)); } @@ -1015,7 +1050,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display) { MetaRectangle cur_rect; MetaWindow *cur_window = cur_window_iter->data; - meta_window_get_outer_rect (cur_window, &cur_rect); + meta_window_get_frame_rect (cur_window, &cur_rect); /* Check if we want to use this window's edges for edge * resistance (note that dock edges are considered screen edges @@ -1026,14 +1061,18 @@ compute_resistance_and_snapping_edges (MetaDisplay *display) { GList *new_edges; MetaEdge *new_edge; + MetaRectangle display_rect = { 0 }; MetaRectangle reduced; + meta_display_get_size (display, + &display_rect.width, &display_rect.height); + /* We don't care about snapping to any portion of the window that * is offscreen (we also don't care about parts of edges covered * by other windows or DOCKS, but that's handled below). */ - meta_rectangle_intersect (&cur_rect, - &display->grab_screen->rect, + meta_rectangle_intersect (&cur_rect, + &display_rect, &reduced); new_edges = NULL; @@ -1058,7 +1097,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display) new_edge->side_type = META_SIDE_LEFT; new_edge->edge_type = META_EDGE_WINDOW; new_edges = g_list_prepend (new_edges, new_edge); - + /* Top side of this window is resistance for the bottom edge of * the window being moved. */ @@ -1110,13 +1149,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display) g_list_free (stacked_windows); /* Free the memory used by the obscuring windows/docks lists */ g_slist_free (window_stacking); - /* FIXME: Shouldn't there be a helper function to make this one line of code - * to free a list instead of four ugly ones? - */ - g_slist_foreach (obscuring_windows, - (void (*)(gpointer,gpointer))&free, /* ew, for ugly */ - NULL); - g_slist_free (obscuring_windows); + g_slist_free_full (obscuring_windows, g_free); /* Sort the list. FIXME: Should I bother with this sorting? I just * sort again later in cache_edges() anyway... @@ -1130,8 +1163,8 @@ compute_resistance_and_snapping_edges (MetaDisplay *display) */ cache_edges (display, edges, - display->grab_screen->active_workspace->monitor_edges, - display->grab_screen->active_workspace->screen_edges); + workspace_manager->active_workspace->monitor_edges, + workspace_manager->active_workspace->screen_edges); g_list_free (edges); /* @@ -1140,13 +1173,8 @@ compute_resistance_and_snapping_edges (MetaDisplay *display) initialize_grab_edge_resistance_data (display); } -/* Note that old_[xy] and new_[xy] are with respect to inner positions of - * the window. - */ -LOCAL_SYMBOL void +void meta_window_edge_resistance_for_move (MetaWindow *window, - int old_x, - int old_y, int *new_x, int *new_y, GSourceFunc timeout_func, @@ -1156,11 +1184,11 @@ meta_window_edge_resistance_for_move (MetaWindow *window, MetaRectangle old_outer, proposed_outer, new_outer; gboolean is_resize; - meta_window_get_outer_rect (window, &old_outer); + meta_window_get_frame_rect (window, &old_outer); proposed_outer = old_outer; - proposed_outer.x += (*new_x - old_x); - proposed_outer.y += (*new_y - old_y); + proposed_outer.x = *new_x; + proposed_outer.y = *new_y; new_outer = proposed_outer; window->display->grab_last_user_action_was_snap = snap; @@ -1211,40 +1239,33 @@ meta_window_edge_resistance_for_move (MetaWindow *window, else smaller_y_change = bottom_change; - *new_x = old_x + smaller_x_change + + *new_x = old_outer.x + smaller_x_change + (BOX_LEFT (*reference) - BOX_LEFT (old_outer)); - *new_y = old_y + smaller_y_change + + *new_y = old_outer.y + smaller_y_change + (BOX_TOP (*reference) - BOX_TOP (old_outer)); meta_topic (META_DEBUG_EDGE_RESISTANCE, "outer x & y move-to coordinate changed from %d,%d to %d,%d\n", proposed_outer.x, proposed_outer.y, - old_outer.x + (*new_x - old_x), - old_outer.y + (*new_y - old_y)); + *new_x, *new_y); } } -/* Note that old_(width|height) and new_(width|height) are with respect to - * sizes of the inner window. - */ -LOCAL_SYMBOL void +void meta_window_edge_resistance_for_resize (MetaWindow *window, - int old_width, - int old_height, int *new_width, int *new_height, - int gravity, + MetaGravity gravity, GSourceFunc timeout_func, gboolean snap, gboolean is_keyboard_op) { MetaRectangle old_outer, new_outer; int proposed_outer_width, proposed_outer_height; - gboolean is_resize; - meta_window_get_outer_rect (window, &old_outer); - proposed_outer_width = old_outer.width + (*new_width - old_width); - proposed_outer_height = old_outer.height + (*new_height - old_height); + meta_window_get_frame_rect (window, &old_outer); + proposed_outer_width = *new_width; + proposed_outer_height = *new_height; meta_rectangle_resize_with_gravity (&old_outer, &new_outer, gravity, @@ -1252,7 +1273,6 @@ meta_window_edge_resistance_for_resize (MetaWindow *window, proposed_outer_height); window->display->grab_last_user_action_was_snap = snap; - is_resize = TRUE; if (apply_edge_resistance_to_each_side (window->display, window, &old_outer, @@ -1260,10 +1280,10 @@ meta_window_edge_resistance_for_resize (MetaWindow *window, timeout_func, snap, is_keyboard_op, - is_resize)) + TRUE)) { - *new_width = old_width + (new_outer.width - old_outer.width); - *new_height = old_height + (new_outer.height - old_outer.height); + *new_width = new_outer.width; + *new_height = new_outer.height; meta_topic (META_DEBUG_EDGE_RESISTANCE, "outer width & height got changed from %d,%d to %d,%d\n", diff --git a/src/core/edge-resistance.h b/src/core/edge-resistance.h index 9e0c603a9..c980030c7 100644 --- a/src/core/edge-resistance.h +++ b/src/core/edge-resistance.h @@ -2,9 +2,9 @@ /* Edge resistance for move/resize operations */ -/* +/* * Copyright (C) 2005 Elijah Newren - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the @@ -14,32 +14,26 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_EDGE_RESISTANCE_H #define META_EDGE_RESISTANCE_H -#include "window-private.h" +#include "core/window-private.h" void meta_window_edge_resistance_for_move (MetaWindow *window, - int old_x, - int old_y, int *new_x, int *new_y, GSourceFunc timeout_func, gboolean snap, gboolean is_keyboard_op); void meta_window_edge_resistance_for_resize (MetaWindow *window, - int old_width, - int old_height, int *new_width, int *new_height, - int gravity, + MetaGravity gravity, GSourceFunc timeout_func, gboolean snap, gboolean is_keyboard_op); diff --git a/src/core/eventqueue.c b/src/core/eventqueue.c deleted file mode 100644 index ce7ec5bce..000000000 --- a/src/core/eventqueue.c +++ /dev/null @@ -1,188 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Muffin X event source for main loop */ - -/* - * Copyright (C) 2001 Havoc Pennington (based on GDK code (C) Owen - * Taylor, Red Hat Inc.) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. */ - -#if HAVE_CONFIG_H -#include <config.h> -#endif - -#include "eventqueue.h" -#include <X11/Xlib.h> - -static gboolean eq_prepare (GSource *source, - gint *timeout); -static gboolean eq_check (GSource *source); -static gboolean eq_dispatch (GSource *source, - GSourceFunc callback, - gpointer user_data); -static void eq_destroy (GSource *source); - -static GSourceFuncs eq_funcs = { - eq_prepare, - eq_check, - eq_dispatch, - eq_destroy -}; - -struct _MetaEventQueue -{ - GSource source; - - Display *display; - GPollFD poll_fd; - int connection_fd; - GQueue *events; -}; - -LOCAL_SYMBOL MetaEventQueue* -meta_event_queue_new (Display *display, MetaEventQueueFunc func, gpointer data) -{ - GSource *source; - MetaEventQueue *eq; - - source = g_source_new (&eq_funcs, sizeof (MetaEventQueue)); - eq = (MetaEventQueue*) source; - - eq->connection_fd = ConnectionNumber (display); - eq->poll_fd.fd = eq->connection_fd; - eq->poll_fd.events = G_IO_IN; - - eq->events = g_queue_new (); - - eq->display = display; - - g_source_set_priority (source, G_PRIORITY_DEFAULT); - g_source_add_poll (source, &eq->poll_fd); - g_source_set_can_recurse (source, TRUE); - - g_source_set_callback (source, (GSourceFunc) func, data, NULL); - - g_source_attach (source, NULL); - g_source_unref (source); - - return eq; -} - -LOCAL_SYMBOL void -meta_event_queue_free (MetaEventQueue *eq) -{ - GSource *source; - - source = (GSource*) eq; - - g_source_destroy (source); -} - -static gboolean -eq_events_pending (MetaEventQueue *eq) -{ - return eq->events->length > 0 || XPending (eq->display); -} - -static void -eq_queue_events (MetaEventQueue *eq) -{ - XEvent xevent; - - while (XPending (eq->display)) - { - XEvent *copy; - - XNextEvent (eq->display, &xevent); - - copy = g_new (XEvent, 1); - *copy = xevent; - - g_queue_push_tail (eq->events, copy); - } -} - -static gboolean -eq_prepare (GSource *source, gint *timeout) -{ - MetaEventQueue *eq; - - eq = (MetaEventQueue*) source; - - *timeout = -1; - - return eq_events_pending (eq); -} - -static gboolean -eq_check (GSource *source) -{ - MetaEventQueue *eq; - - eq = (MetaEventQueue*) source; - - if (eq->poll_fd.revents & G_IO_IN) - return eq_events_pending (eq); - else - return FALSE; -} - -static gboolean -eq_dispatch (GSource *source, GSourceFunc callback, gpointer user_data) -{ - MetaEventQueue *eq; - - eq = (MetaEventQueue*) source; - - eq_queue_events (eq); - - if (eq->events->length > 0) - { - XEvent *event; - MetaEventQueueFunc func; - - event = g_queue_pop_head (eq->events); - func = (MetaEventQueueFunc) callback; - - (* func) (event, user_data); - - free (event); - } - - return TRUE; -} - -static void -eq_destroy (GSource *source) -{ - MetaEventQueue *eq; - - eq = (MetaEventQueue*) source; - - while (eq->events->length > 0) - { - XEvent *event; - - event = g_queue_pop_head (eq->events); - - free (event); - } - - g_queue_free (eq->events); - - /* source itself is freed by glib */ -} diff --git a/src/core/events.c b/src/core/events.c new file mode 100644 index 000000000..e50b52d0d --- /dev/null +++ b/src/core/events.c @@ -0,0 +1,499 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001 Havoc Pennington + * Copyright (C) 2002, 2003, 2004 Red Hat, Inc. + * Copyright (C) 2003, 2004 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include "core/events.h" + +#include "backends/meta-cursor-tracker-private.h" +#include "backends/meta-idle-monitor-private.h" +#include "backends/x11/meta-backend-x11.h" +#include "compositor/meta-window-actor-private.h" +#include "core/display-private.h" +#include "core/window-private.h" +#include "meta/meta-backend.h" + +#ifdef HAVE_NATIVE_BACKEND +#include "backends/native/meta-backend-native.h" +#endif + +#ifdef HAVE_WAYLAND +#include "wayland/meta-wayland-private.h" +#endif + +#define IS_GESTURE_EVENT(e) ((e)->type == CLUTTER_TOUCHPAD_SWIPE || \ + (e)->type == CLUTTER_TOUCHPAD_PINCH || \ + (e)->type == CLUTTER_TOUCH_BEGIN || \ + (e)->type == CLUTTER_TOUCH_UPDATE || \ + (e)->type == CLUTTER_TOUCH_END || \ + (e)->type == CLUTTER_TOUCH_CANCEL) + +#define IS_KEY_EVENT(e) ((e)->type == CLUTTER_KEY_PRESS || \ + (e)->type == CLUTTER_KEY_RELEASE) + +typedef enum +{ + EVENTS_UNFREEZE_SYNC, + EVENTS_UNFREEZE_REPLAY, +} EventsUnfreezeMethod; + +static gboolean +stage_has_key_focus (void) +{ + MetaBackend *backend = meta_get_backend (); + ClutterActor *stage = meta_backend_get_stage (backend); + + return clutter_stage_get_key_focus (CLUTTER_STAGE (stage)) == stage; +} + +static MetaWindow * +get_window_for_event (MetaDisplay *display, + const ClutterEvent *event) +{ + switch (display->event_route) + { + case META_EVENT_ROUTE_NORMAL: + { + ClutterActor *source; + MetaWindowActor *window_actor; + + /* Always use the key focused window for key events. */ + if (IS_KEY_EVENT (event)) + return stage_has_key_focus () ? display->focus_window : NULL; + + source = clutter_event_get_source (event); + window_actor = meta_window_actor_from_actor (source); + if (window_actor) + return meta_window_actor_get_meta_window (window_actor); + else + return NULL; + } + case META_EVENT_ROUTE_WINDOW_OP: + case META_EVENT_ROUTE_COMPOSITOR_GRAB: + case META_EVENT_ROUTE_WAYLAND_POPUP: + case META_EVENT_ROUTE_FRAME_BUTTON: + return display->grab_window; + default: + g_assert_not_reached (); + return NULL; + } +} + +static void +handle_idletime_for_event (const ClutterEvent *event) +{ + MetaIdleMonitor *core_monitor; + + if (clutter_event_get_device (event) == NULL) + return; + + if (event->any.flags & CLUTTER_EVENT_FLAG_SYNTHETIC || + event->type == CLUTTER_ENTER || + event->type == CLUTTER_LEAVE || + event->type == CLUTTER_STAGE_STATE || + event->type == CLUTTER_DESTROY_NOTIFY || + event->type == CLUTTER_CLIENT_MESSAGE || + event->type == CLUTTER_DELETE) + return; + + core_monitor = meta_idle_monitor_get_core (); + meta_idle_monitor_reset_idletime (core_monitor); +} + +static gboolean +sequence_is_pointer_emulated (MetaDisplay *display, + const ClutterEvent *event) +{ + ClutterEventSequence *sequence; + + sequence = clutter_event_get_event_sequence (event); + + if (!sequence) + return FALSE; + + if (clutter_event_is_pointer_emulated (event)) + return TRUE; + +#ifdef HAVE_NATIVE_BACKEND + MetaBackend *backend = meta_get_backend (); + + /* When using Clutter's native input backend there is no concept of + * pointer emulating sequence, we still must make up our own to be + * able to implement single-touch (hence pointer alike) behavior. + * + * This is implemented similarly to X11, where only the first touch + * on screen gets the "pointer emulated" flag, and it won't get assigned + * to another sequence until the next first touch on an idle touchscreen. + */ + if (META_IS_BACKEND_NATIVE (backend)) + { + MetaGestureTracker *tracker; + + tracker = meta_display_get_gesture_tracker (display); + + if (event->type == CLUTTER_TOUCH_BEGIN && + meta_gesture_tracker_get_n_current_touches (tracker) == 0) + return TRUE; + } +#endif /* HAVE_NATIVE_BACKEND */ + + return FALSE; +} + +static void +maybe_unfreeze_pointer_events (MetaBackend *backend, + const ClutterEvent *event, + EventsUnfreezeMethod unfreeze_method) +{ + Display *xdisplay; + int event_mode; + int device_id; + + if (event->type != CLUTTER_BUTTON_PRESS) + return; + + if (!META_IS_BACKEND_X11 (backend)) + return; + + device_id = clutter_event_get_device_id (event); + switch (unfreeze_method) + { + case EVENTS_UNFREEZE_SYNC: + event_mode = XISyncDevice; + meta_verbose ("Syncing events time %u device %i\n", + (unsigned int) event->button.time, device_id); + break; + case EVENTS_UNFREEZE_REPLAY: + event_mode = XIReplayDevice; + meta_verbose ("Replaying events time %u device %i\n", + (unsigned int) event->button.time, device_id); + break; + default: + g_assert_not_reached (); + return; + } + + xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); + XIAllowEvents (xdisplay, device_id, event_mode, event->button.time); +} + +static gboolean +meta_display_handle_event (MetaDisplay *display, + const ClutterEvent *event) +{ + MetaBackend *backend = meta_get_backend (); + MetaWindow *window; + gboolean bypass_clutter = FALSE; + G_GNUC_UNUSED gboolean bypass_wayland = FALSE; + MetaGestureTracker *gesture_tracker; + ClutterEventSequence *sequence; + + sequence = clutter_event_get_event_sequence (event); + + /* Set the pointer emulating sequence on touch begin, if eligible */ + if (event->type == CLUTTER_TOUCH_BEGIN) + { + if (sequence_is_pointer_emulated (display, event)) + { + /* This is the new pointer emulating sequence */ + display->pointer_emulating_sequence = sequence; + } + else if (display->pointer_emulating_sequence == sequence) + { + /* This sequence was "pointer emulating" in a prior incarnation, + * but now it isn't. We unset the pointer emulating sequence at + * this point so the current sequence is not mistaken as pointer + * emulating, while we've ensured that it's been deemed + * "pointer emulating" throughout all of the event processing + * of the previous incarnation. + */ + display->pointer_emulating_sequence = NULL; + } + } + +#ifdef HAVE_WAYLAND + MetaWaylandCompositor *compositor = NULL; + if (meta_is_wayland_compositor ()) + { + compositor = meta_wayland_compositor_get_default (); + meta_wayland_compositor_update (compositor, event); + } +#endif + + if (event->type == CLUTTER_PAD_BUTTON_PRESS || + event->type == CLUTTER_PAD_BUTTON_RELEASE || + event->type == CLUTTER_PAD_RING || + event->type == CLUTTER_PAD_STRIP) + { + gboolean handle_pad_event; + gboolean is_mode_switch = FALSE; + + if (event->type == CLUTTER_PAD_BUTTON_PRESS || + event->type == CLUTTER_PAD_BUTTON_RELEASE) + { + ClutterInputDevice *pad; + uint32_t button; + + pad = clutter_event_get_source_device (event); + button = clutter_event_get_button (event); + + is_mode_switch = + clutter_input_device_get_mode_switch_button_group (pad, button) >= 0; + } + + handle_pad_event = !display->current_pad_osd || is_mode_switch; + + if (handle_pad_event && + meta_input_settings_handle_pad_event (meta_backend_get_input_settings (backend), + event)) + { + bypass_wayland = bypass_clutter = TRUE; + goto out; + } + } + + if (event->type != CLUTTER_DEVICE_ADDED && + event->type != CLUTTER_DEVICE_REMOVED) + { + ClutterInputDevice *source; + + handle_idletime_for_event (event); + source = clutter_event_get_source_device (event); + + if (source) + meta_backend_update_last_device (backend, source); + } + +#ifdef HAVE_WAYLAND + if (meta_is_wayland_compositor () && event->type == CLUTTER_MOTION) + { + MetaWaylandCompositor *compositor; + + compositor = meta_wayland_compositor_get_default (); + + if (meta_wayland_tablet_manager_consumes_event (compositor->tablet_manager, event)) + { + meta_wayland_tablet_manager_update_cursor_position (compositor->tablet_manager, event); + } + else + { + MetaCursorTracker *cursor_tracker = + meta_backend_get_cursor_tracker (backend); + + meta_cursor_tracker_update_position (cursor_tracker, + event->motion.x, + event->motion.y); + } + + display->monitor_cache_invalidated = TRUE; + } +#endif + + window = get_window_for_event (display, event); + + display->current_time = event->any.time; + + if (window && !window->override_redirect && + (event->type == CLUTTER_KEY_PRESS || + event->type == CLUTTER_BUTTON_PRESS || + event->type == CLUTTER_TOUCH_BEGIN)) + { + if (META_CURRENT_TIME == display->current_time) + { + /* We can't use missing (i.e. invalid) timestamps to set user time, + * nor do we want to use them to sanity check other timestamps. + * See bug 313490 for more details. + */ + meta_warning ("Event has no timestamp! You may be using a broken " + "program such as xse. Please ask the authors of that " + "program to fix it.\n"); + } + else + { + meta_window_set_user_time (window, display->current_time); + meta_display_sanity_check_timestamps (display, display->current_time); + } + } + + gesture_tracker = meta_display_get_gesture_tracker (display); + + if (meta_gesture_tracker_handle_event (gesture_tracker, event)) + { + bypass_wayland = bypass_clutter = TRUE; + goto out; + } + + if (display->event_route == META_EVENT_ROUTE_WINDOW_OP) + { + if (meta_window_handle_mouse_grab_op_event (window, event)) + { + bypass_clutter = TRUE; + bypass_wayland = TRUE; + goto out; + } + } + + /* For key events, it's important to enforce single-handling, or + * we can get into a confused state. So if a keybinding is + * handled (because it's one of our hot-keys, or because we are + * in a keyboard-grabbed mode like moving a window, we don't + * want to pass the key event to the compositor or Wayland at all. + */ + if (meta_keybindings_process_event (display, window, event)) + { + bypass_clutter = TRUE; + bypass_wayland = TRUE; + goto out; + } + + /* Do not pass keyboard events to Wayland if key focus is not on the + * stage in normal mode (e.g. during keynav in the panel) + */ + if (display->event_route == META_EVENT_ROUTE_NORMAL) + { + if (IS_KEY_EVENT (event) && !stage_has_key_focus ()) + { + bypass_wayland = TRUE; + goto out; + } + } + + if (display->current_pad_osd) + { + bypass_wayland = TRUE; + goto out; + } + + if (window) + { + /* Events that are likely to trigger compositor gestures should + * be known to clutter so they can propagate along the hierarchy. + * Gesture-wise, there's two groups of events we should be getting + * here: + * - CLUTTER_TOUCH_* with a touch sequence that's not yet accepted + * by the gesture tracker, these might trigger gesture actions + * into recognition. Already accepted touch sequences are handled + * directly by meta_gesture_tracker_handle_event(). + * - CLUTTER_TOUCHPAD_* events over windows. These can likewise + * trigger ::captured-event handlers along the way. + */ + bypass_clutter = !IS_GESTURE_EVENT (event); + + /* When double clicking to un-maximize an X11 window under Wayland, + * there is a race between X11 and Wayland protocols and the X11 + * XConfigureWindow may be processed by Xwayland before the button + * press event is forwarded via the Wayland protocol. + * As a result, the second click may reach another X11 window placed + * immediately underneath in the X11 stack. + * The following is to make sure we do not forward the button press + * event to Wayland if it was handled by the frame UI. + * See: https://gitlab.gnome.org/GNOME/mutter/issues/88 + */ + if (meta_window_handle_ui_frame_event (window, event)) + bypass_wayland = (event->type == CLUTTER_BUTTON_PRESS || + event->type == CLUTTER_TOUCH_BEGIN); + else + meta_window_handle_ungrabbed_event (window, event); + + /* This might start a grab op. If it does, then filter out the + * event, and if it doesn't, replay the event to release our + * own sync grab. */ + + if (display->event_route == META_EVENT_ROUTE_WINDOW_OP || + display->event_route == META_EVENT_ROUTE_FRAME_BUTTON) + { + bypass_clutter = TRUE; + bypass_wayland = TRUE; + } + else + { + /* Only replay button press events, since that's where we + * have the synchronous grab. */ + maybe_unfreeze_pointer_events (backend, event, EVENTS_UNFREEZE_REPLAY); + + /* If the focus window has an active close dialog let clutter + * events go through, so fancy clutter dialogs can get to handle + * all events. + */ + if (window->close_dialog && + meta_close_dialog_is_visible (window->close_dialog)) + { + bypass_wayland = TRUE; + bypass_clutter = FALSE; + } + } + + goto out; + } + else + { + /* We could not match the event with a window, make sure we sync + * the pointer to discard the sequence and don't keep events frozen. + */ + maybe_unfreeze_pointer_events (backend, event, EVENTS_UNFREEZE_SYNC); + } + + out: + /* If the compositor has a grab, don't pass that through to Wayland */ + if (display->event_route == META_EVENT_ROUTE_COMPOSITOR_GRAB) + bypass_wayland = TRUE; + + /* If a Wayland client has a grab, don't pass that through to Clutter */ + if (display->event_route == META_EVENT_ROUTE_WAYLAND_POPUP) + bypass_clutter = TRUE; + +#ifdef HAVE_WAYLAND + if (compositor && !bypass_wayland) + { + if (meta_wayland_compositor_handle_event (compositor, event)) + bypass_clutter = TRUE; + } +#endif + + display->current_time = META_CURRENT_TIME; + return bypass_clutter; +} + +static gboolean +event_callback (const ClutterEvent *event, + gpointer data) +{ + MetaDisplay *display = data; + + return meta_display_handle_event (display, event); +} + +void +meta_display_init_events (MetaDisplay *display) +{ + display->clutter_event_filter = clutter_event_add_filter (NULL, + event_callback, + NULL, + display); +} + +void +meta_display_free_events (MetaDisplay *display) +{ + clutter_event_remove_filter (display->clutter_event_filter); + display->clutter_event_filter = 0; +} diff --git a/src/core/events.h b/src/core/events.h new file mode 100644 index 000000000..6338119ae --- /dev/null +++ b/src/core/events.h @@ -0,0 +1,31 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001 Havoc Pennington + * Copyright (C) 2002, 2003, 2004 Red Hat, Inc. + * Copyright (C) 2003, 2004 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef META_EVENTS_H +#define META_EVENTS_H + +#include "meta/display.h" + +void meta_display_init_events (MetaDisplay *display); +void meta_display_free_events (MetaDisplay *display); + +#endif diff --git a/src/core/frame.c b/src/core/frame.c index 7a52ddd4a..b58ad1173 100644 --- a/src/core/frame.c +++ b/src/core/frame.c @@ -1,6 +1,6 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* Muffin X window decorations */ +/* Mutter X window decorations */ /* * Copyright (C) 2001 Havoc Pennington @@ -18,40 +18,35 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ -#include <config.h> -#include "frame.h" -#include <meta/errors.h> -#include "keybindings-private.h" +#include "config.h" -#include <X11/extensions/Xrender.h> +#include "core/frame.h" + +#include "backends/x11/meta-backend-x11.h" +#include "core/bell.h" +#include "core/keybindings-private.h" +#include "meta/meta-x11-errors.h" +#include "x11/meta-x11-display-private.h" #define EVENT_MASK (SubstructureRedirectMask | \ StructureNotifyMask | SubstructureNotifyMask | \ - ExposureMask | \ - ButtonPressMask | ButtonReleaseMask | \ - PointerMotionMask | PointerMotionHintMask | \ - EnterWindowMask | LeaveWindowMask | \ - FocusChangeMask | \ - ColormapChangeMask) - -LOCAL_SYMBOL void + ExposureMask | FocusChangeMask) + +void meta_window_ensure_frame (MetaWindow *window) { MetaFrame *frame; XSetWindowAttributes attrs; - Visual *visual; gulong create_serial; + MetaX11Display *x11_display; if (window->frame) return; - /* See comment below for why this is required. */ - meta_display_grab (window->display); + x11_display = window->display->x11_display; frame = g_new (MetaFrame, 1); @@ -65,65 +60,35 @@ meta_window_ensure_frame (MetaWindow *window) frame->right_width = 0; frame->current_cursor = 0; - frame->is_flashing = FALSE; frame->borders_cached = FALSE; - meta_verbose ("Framing window %s: visual %s default, depth %d default depth %d\n", - window->desc, - XVisualIDFromVisual (window->xvisual) == - XVisualIDFromVisual (window->screen->default_xvisual) ? - "is" : "is not", - window->depth, window->screen->default_depth); meta_verbose ("Frame geometry %d,%d %dx%d\n", frame->rect.x, frame->rect.y, frame->rect.width, frame->rect.height); - /* Default depth/visual handles clients with weird visuals; they can - * always be children of the root depth/visual obviously, but - * e.g. DRI games can't be children of a parent that has the same - * visual as the client. NULL means default visual. - * - * We look for an ARGB visual if we can find one, otherwise use - * the default of NULL. - */ - - /* Special case for depth 32 windows (assumed to be ARGB), - * we use the window's visual. Otherwise we just use the system visual. - */ - if (window->depth == 32) - visual = window->xvisual; - else - visual = NULL; - - frame->xwindow = meta_ui_create_frame_window (window->screen->ui, - window->display->xdisplay, - visual, - frame->rect.x, - frame->rect.y, - frame->rect.width, - frame->rect.height, - frame->window->screen->number, - &create_serial); - meta_stack_tracker_record_add (window->screen->stack_tracker, + frame->ui_frame = meta_ui_create_frame (x11_display->ui, + x11_display->xdisplay, + frame->window, + window->xvisual, + frame->rect.x, + frame->rect.y, + frame->rect.width, + frame->rect.height, + &create_serial); + frame->xwindow = frame->ui_frame->xwindow; + + meta_stack_tracker_record_add (window->display->stack_tracker, frame->xwindow, create_serial); meta_verbose ("Frame for %s is 0x%lx\n", frame->window->desc, frame->xwindow); attrs.event_mask = EVENT_MASK; - XChangeWindowAttributes (window->display->xdisplay, + XChangeWindowAttributes (x11_display->xdisplay, frame->xwindow, CWEventMask, &attrs); - meta_display_register_x_window (window->display, &frame->xwindow, window); + meta_x11_display_register_x_window (x11_display, &frame->xwindow, window); - /* Reparent the client window; it may be destroyed, - * thus the error trap. We'll get a destroy notify later - * and free everything. Comment in FVWM source code says - * we need a server grab or the child can get its MapNotify - * before we've finished reparenting and getting the decoration - * window onscreen, so ensure_frame must be called with - * a grab. - */ - meta_error_trap_push (window->display); + meta_x11_error_trap_push (x11_display); if (window->mapped) { window->mapped = FALSE; /* the reparent will unmap the window, @@ -133,20 +98,24 @@ meta_window_ensure_frame (MetaWindow *window) "Incrementing unmaps_pending on %s for reparent\n", window->desc); window->unmaps_pending += 1; } - /* window was reparented to this position */ - window->rect.x = 0; - window->rect.y = 0; - meta_stack_tracker_record_remove (window->screen->stack_tracker, + meta_stack_tracker_record_remove (window->display->stack_tracker, window->xwindow, - XNextRequest (window->display->xdisplay)); - XReparentWindow (window->display->xdisplay, + XNextRequest (x11_display->xdisplay)); + XReparentWindow (x11_display->xdisplay, window->xwindow, frame->xwindow, - window->rect.x, - window->rect.y); + frame->child_x, + frame->child_y); + window->reparents_pending += 1; /* FIXME handle this error */ - meta_error_trap_pop (window->display); + meta_x11_error_trap_pop (x11_display); + + /* Ensure focus is restored after the unmap/map events triggered + * by XReparentWindow(). + */ + if (meta_window_has_focus (window)) + window->restore_focus_on_map = TRUE; /* stick frame to the window */ window->frame = frame; @@ -154,30 +123,54 @@ meta_window_ensure_frame (MetaWindow *window) /* Now that frame->xwindow is registered with window, we can set its * style and background. */ - meta_ui_update_frame_style (window->screen->ui, frame->xwindow); + meta_frame_update_style (frame); + meta_frame_update_title (frame); - if (window->title) - meta_ui_set_frame_title (window->screen->ui, - window->frame->xwindow, - window->title); + meta_ui_map_frame (x11_display->ui, frame->xwindow); - /* Move keybindings to frame instead of window */ - meta_window_grab_keys (window); + { + MetaBackend *backend = meta_get_backend (); + if (META_IS_BACKEND_X11 (backend)) + { + Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); + + /* Since the backend selects for events on another connection, + * make sure to sync the GTK+ connection to ensure that the + * frame window has been created on the server at this point. */ + XSync (x11_display->xdisplay, False); + + unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; + XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; + + XISelectEvents (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), + frame->xwindow, &mask, 1); - meta_ui_map_frame (frame->window->screen->ui, frame->xwindow); + XISetMask (mask.mask, XI_ButtonPress); + XISetMask (mask.mask, XI_ButtonRelease); + XISetMask (mask.mask, XI_Motion); + XISetMask (mask.mask, XI_Enter); + XISetMask (mask.mask, XI_Leave); - meta_display_ungrab (window->display); + XISelectEvents (xdisplay, frame->xwindow, &mask, 1); + } + } + + /* Move keybindings to frame instead of window */ + meta_window_grab_keys (window); } -LOCAL_SYMBOL void +void meta_window_destroy_frame (MetaWindow *window) { MetaFrame *frame; MetaFrameBorders borders; + MetaX11Display *x11_display; if (window->frame == NULL) return; + x11_display = window->display->x11_display; + meta_verbose ("Unframing window %s\n", window->desc); frame = window->frame; @@ -187,7 +180,7 @@ meta_window_destroy_frame (MetaWindow *window) /* Unparent the client window; it may be destroyed, * thus the error trap. */ - meta_error_trap_push (window->display); + meta_x11_error_trap_push (x11_display); if (window->mapped) { window->mapped = FALSE; /* Keep track of unmapping it, so we @@ -198,25 +191,36 @@ meta_window_destroy_frame (MetaWindow *window) "Incrementing unmaps_pending on %s for reparent back to root\n", window->desc); window->unmaps_pending += 1; } - meta_stack_tracker_record_add (window->screen->stack_tracker, - window->xwindow, - XNextRequest (window->display->xdisplay)); - XReparentWindow (window->display->xdisplay, - window->xwindow, - window->screen->xroot, - /* Using anything other than meta_window_get_position() - * coordinates here means we'll need to ensure a configure - * notify event is sent; see bug 399552. - */ - window->frame->rect.x + borders.total.left, - window->frame->rect.y + borders.total.top); - meta_error_trap_pop (window->display); + if (!x11_display->closing) + { + meta_stack_tracker_record_add (window->display->stack_tracker, + window->xwindow, + XNextRequest (x11_display->xdisplay)); + + XReparentWindow (x11_display->xdisplay, + window->xwindow, + x11_display->xroot, + /* Using anything other than client root window coordinates + * coordinates here means we'll need to ensure a configure + * notify event is sent; see bug 399552. + */ + window->frame->rect.x + borders.invisible.left, + window->frame->rect.y + borders.invisible.top); + window->reparents_pending += 1; + } - meta_ui_destroy_frame_window (window->screen->ui, frame->xwindow); + meta_x11_error_trap_pop (x11_display); - meta_display_unregister_x_window (window->display, - frame->xwindow); + meta_ui_frame_unmanage (frame->ui_frame); + + /* Ensure focus is restored after the unmap/map events triggered + * by XReparentWindow(). + */ + if (meta_window_has_focus (window)) + window->restore_focus_on_map = TRUE; + + meta_x11_display_unregister_x_window (x11_display, frame->xwindow); window->frame = NULL; if (window->frame_bounds) @@ -228,7 +232,7 @@ meta_window_destroy_frame (MetaWindow *window) /* Move keybindings to window instead of frame */ meta_window_grab_keys (window); - free (frame); + g_free (frame); /* Put our state back where it should be */ meta_window_queue (window, META_QUEUE_CALC_SHOWING); @@ -236,7 +240,7 @@ meta_window_destroy_frame (MetaWindow *window) } -LOCAL_SYMBOL MetaFrameFlags +MetaFrameFlags meta_frame_get_flags (MetaFrame *frame) { MetaFrameFlags flags; @@ -275,18 +279,6 @@ meta_frame_get_flags (MetaFrame *frame) if (META_WINDOW_ALLOWS_VERTICAL_RESIZE (frame->window)) flags |= META_FRAME_ALLOWS_VERTICAL_RESIZE; - if (META_WINDOW_ALLOWS_TOP_RESIZE (frame->window)) - flags |= META_FRAME_ALLOWS_TOP_RESIZE; - - if (META_WINDOW_ALLOWS_BOTTOM_RESIZE (frame->window)) - flags |= META_FRAME_ALLOWS_BOTTOM_RESIZE; - - if (META_WINDOW_ALLOWS_LEFT_RESIZE (frame->window)) - flags |= META_FRAME_ALLOWS_LEFT_RESIZE; - - if (META_WINDOW_ALLOWS_RIGHT_RESIZE (frame->window)) - flags |= META_FRAME_ALLOWS_RIGHT_RESIZE; - if (meta_window_appears_focused (frame->window)) flags |= META_FRAME_HAS_FOCUS; @@ -302,27 +294,15 @@ meta_frame_get_flags (MetaFrame *frame) if (META_WINDOW_MAXIMIZED (frame->window)) flags |= META_FRAME_MAXIMIZED; - if (META_WINDOW_TILED_LEFT (frame->window) || - META_WINDOW_TILED_ULC (frame->window) || - META_WINDOW_TILED_LLC (frame->window)) + if (META_WINDOW_TILED_LEFT (frame->window)) flags |= META_FRAME_TILED_LEFT; - if (META_WINDOW_TILED_RIGHT (frame->window) || - META_WINDOW_TILED_URC (frame->window) || - META_WINDOW_TILED_LRC (frame->window)) + if (META_WINDOW_TILED_RIGHT (frame->window)) flags |= META_FRAME_TILED_RIGHT; - if (META_WINDOW_TILED_TOP (frame->window) || - META_WINDOW_TILED_BOTTOM (frame->window)) { - flags |= META_FRAME_MAXIMIZED; - } - if (frame->window->fullscreen) flags |= META_FRAME_FULLSCREEN; - if (frame->is_flashing) - flags |= META_FRAME_IS_FLASHING; - if (frame->window->wm_state_above) flags |= META_FRAME_ABOVE; @@ -338,7 +318,7 @@ meta_frame_borders_clear (MetaFrameBorders *self) self->visible.right = self->invisible.right = self->total.right = 0; } -LOCAL_SYMBOL void +void meta_frame_calc_borders (MetaFrame *frame, MetaFrameBorders *borders) { @@ -350,9 +330,7 @@ meta_frame_calc_borders (MetaFrame *frame, { if (!frame->borders_cached) { - meta_ui_get_frame_borders (frame->window->screen->ui, - frame->xwindow, - &frame->cached_borders); + meta_ui_frame_get_borders (frame->ui_frame, &frame->cached_borders); frame->borders_cached = TRUE; } @@ -366,23 +344,8 @@ meta_frame_clear_cached_borders (MetaFrame *frame) frame->borders_cached = FALSE; } -LOCAL_SYMBOL void -meta_frame_get_corner_radiuses (MetaFrame *frame, - float *top_left, - float *top_right, - float *bottom_left, - float *bottom_right) -{ - meta_ui_get_corner_radiuses (frame->window->screen->ui, - frame->xwindow, - top_left, top_right, - bottom_left, bottom_right); -} - -LOCAL_SYMBOL gboolean +gboolean meta_frame_sync_to_window (MetaFrame *frame, - int resize_gravity, - gboolean need_move, gboolean need_resize) { meta_topic (META_DEBUG_GEOMETRY, @@ -392,64 +355,73 @@ meta_frame_sync_to_window (MetaFrame *frame, frame->rect.x + frame->rect.width, frame->rect.y + frame->rect.height); - meta_ui_move_resize_frame (frame->window->screen->ui, - frame->xwindow, + meta_ui_frame_move_resize (frame->ui_frame, frame->rect.x, frame->rect.y, frame->rect.width, frame->rect.height); - if (need_resize) - { - /* If we're interactively resizing the frame, repaint - * it immediately so we don't start to lag. - */ - if (frame->window->display->grab_window == - frame->window) - meta_ui_repaint_frame (frame->window->screen->ui, - frame->xwindow); - } - return need_resize; } -LOCAL_SYMBOL cairo_region_t * +cairo_region_t * meta_frame_get_frame_bounds (MetaFrame *frame) { - return meta_ui_get_frame_bounds (frame->window->screen->ui, - frame->xwindow, - frame->rect.width, - frame->rect.height); + return meta_ui_frame_get_bounds (frame->ui_frame); } -LOCAL_SYMBOL void +void +meta_frame_get_mask (MetaFrame *frame, + cairo_rectangle_int_t *frame_rect, + cairo_t *cr) +{ + meta_ui_frame_get_mask (frame->ui_frame, frame_rect, cr); +} + +void meta_frame_queue_draw (MetaFrame *frame) { - meta_ui_queue_frame_draw (frame->window->screen->ui, - frame->xwindow); + meta_ui_frame_queue_draw (frame->ui_frame); } -LOCAL_SYMBOL void +void meta_frame_set_screen_cursor (MetaFrame *frame, MetaCursor cursor) { + MetaX11Display *x11_display; Cursor xcursor; if (cursor == frame->current_cursor) return; + frame->current_cursor = cursor; + x11_display = frame->window->display->x11_display; + if (cursor == META_CURSOR_DEFAULT) - XUndefineCursor (frame->window->display->xdisplay, frame->xwindow); + XUndefineCursor (x11_display->xdisplay, frame->xwindow); else { - xcursor = meta_display_create_x_cursor (frame->window->display, cursor); - XDefineCursor (frame->window->display->xdisplay, frame->xwindow, xcursor); - XFlush (frame->window->display->xdisplay); - XFreeCursor (frame->window->display->xdisplay, xcursor); + xcursor = meta_x11_display_create_x_cursor (x11_display, cursor); + XDefineCursor (x11_display->xdisplay, frame->xwindow, xcursor); + XFlush (x11_display->xdisplay); + XFreeCursor (x11_display->xdisplay, xcursor); } } -LOCAL_SYMBOL Window +Window meta_frame_get_xwindow (MetaFrame *frame) { return frame->xwindow; } + +void +meta_frame_update_style (MetaFrame *frame) +{ + meta_ui_frame_update_style (frame->ui_frame); +} + +void +meta_frame_update_title (MetaFrame *frame) +{ + if (frame->window->title) + meta_ui_frame_set_title (frame->ui_frame, frame->window->title); +} diff --git a/src/core/frame.h b/src/core/frame.h index 6f5c8d40a..61a5ca725 100644 --- a/src/core/frame.h +++ b/src/core/frame.h @@ -1,10 +1,10 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* Muffin X window decorations */ +/* Mutter X window decorations */ -/* +/* * Copyright (C) 2001 Havoc Pennington - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the @@ -14,18 +14,16 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_FRAME_PRIVATE_H #define META_FRAME_PRIVATE_H -#include "window-private.h" -#include "workspace-private.h" +#include "core/window-private.h" +#include "ui/frames.h" struct _MetaFrame { @@ -51,8 +49,9 @@ struct _MetaFrame int bottom_height; guint need_reapply_frame_shape : 1; - guint is_flashing : 1; /* used by the visual bell flash */ guint borders_cached : 1; + + MetaUIFrame *ui_frame; }; void meta_window_ensure_frame (MetaWindow *window); @@ -66,26 +65,21 @@ Window meta_frame_get_xwindow (MetaFrame *frame); void meta_frame_calc_borders (MetaFrame *frame, MetaFrameBorders *borders); -void meta_frame_get_corner_radiuses (MetaFrame *frame, - float *top_left, - float *top_right, - float *bottom_left, - float *bottom_right); - gboolean meta_frame_sync_to_window (MetaFrame *frame, - int gravity, - gboolean need_move, gboolean need_resize); void meta_frame_clear_cached_borders (MetaFrame *frame); cairo_region_t *meta_frame_get_frame_bounds (MetaFrame *frame); +void meta_frame_get_mask (MetaFrame *frame, + cairo_rectangle_int_t *frame_rect, + cairo_t *cr); + void meta_frame_set_screen_cursor (MetaFrame *frame, MetaCursor cursor); -#endif - - - +void meta_frame_update_style (MetaFrame *frame); +void meta_frame_update_title (MetaFrame *frame); +#endif diff --git a/src/core/iconcache.c b/src/core/iconcache.c deleted file mode 100644 index 4c2988445..000000000 --- a/src/core/iconcache.c +++ /dev/null @@ -1,773 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Muffin window icons */ - -/* - * Copyright (C) 2002 Havoc Pennington - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. - */ - -#include <config.h> -#include "iconcache.h" -#include "ui.h" -#include <meta/errors.h> - -#include <X11/Xatom.h> - -/* The icon-reading code is also in libwnck, please sync bugfixes */ - -static gboolean -find_largest_sizes (gulong *data, - gulong nitems, - int *width, - int *height) -{ - *width = 0; - *height = 0; - - while (nitems > 0) - { - int w, h; - - if (nitems < 3) - return FALSE; /* no space for w, h */ - - w = data[0]; - h = data[1]; - - if (nitems < ((gulong)(w * h) + 2)) - return FALSE; /* not enough data */ - - *width = MAX (w, *width); - *height = MAX (h, *height); - - data += (w * h) + 2; - nitems -= (w * h) + 2; - } - - return TRUE; -} - -static gboolean -find_best_size (gulong *data, - gulong nitems, - int ideal_width, - int ideal_height, - int *width, - int *height, - gulong **start) -{ - int best_w; - int best_h; - gulong *best_start; - int max_width, max_height; - - *width = 0; - *height = 0; - *start = NULL; - - if (!find_largest_sizes (data, nitems, &max_width, &max_height)) - return FALSE; - - if (ideal_width < 0) - ideal_width = max_width; - if (ideal_height < 0) - ideal_height = max_height; - - best_w = 0; - best_h = 0; - best_start = NULL; - - while (nitems > 0) - { - int w, h; - gboolean replace; - - replace = FALSE; - - if (nitems < 3) - return FALSE; /* no space for w, h */ - - w = data[0]; - h = data[1]; - - if (nitems < ((gulong)(w * h) + 2)) - break; /* not enough data */ - - if (best_start == NULL) - { - replace = TRUE; - } - else - { - /* work with averages */ - const int ideal_size = (ideal_width + ideal_height) / 2; - int best_size = (best_w + best_h) / 2; - int this_size = (w + h) / 2; - - /* larger than desired is always better than smaller */ - if (best_size < ideal_size && - this_size >= ideal_size) - replace = TRUE; - /* if we have too small, pick anything bigger */ - else if (best_size < ideal_size && - this_size > best_size) - replace = TRUE; - /* if we have too large, pick anything smaller - * but still >= the ideal - */ - else if (best_size > ideal_size && - this_size >= ideal_size && - this_size < best_size) - replace = TRUE; - } - - if (replace) - { - best_start = data + 2; - best_w = w; - best_h = h; - } - - data += (w * h) + 2; - nitems -= (w * h) + 2; - } - - if (best_start) - { - *start = best_start; - *width = best_w; - *height = best_h; - return TRUE; - } - else - return FALSE; -} - -static void -argbdata_to_pixdata (gulong *argb_data, int len, guchar **pixdata) -{ - guchar *p; - int i; - - *pixdata = g_new (guchar, len * 4); - p = *pixdata; - - /* One could speed this up a lot. */ - i = 0; - while (i < len) - { - guint argb; - guint rgba; - - argb = argb_data[i]; - rgba = (argb << 8) | (argb >> 24); - - *p = rgba >> 24; - ++p; - *p = (rgba >> 16) & 0xff; - ++p; - *p = (rgba >> 8) & 0xff; - ++p; - *p = rgba & 0xff; - ++p; - - ++i; - } -} - -static gboolean -read_rgb_icon (MetaDisplay *display, - Window xwindow, - int ideal_width, - int ideal_height, - int *width, - int *height, - guchar **pixdata) -{ - Atom type; - int format; - gulong nitems; - gulong bytes_after; - int result, err; - guchar *data; - gulong *best; - int w, h; - gulong *data_as_long; - - meta_error_trap_push_with_return (display); - type = None; - data = NULL; - result = XGetWindowProperty (display->xdisplay, - xwindow, - display->atom__NET_WM_ICON, - 0, G_MAXLONG, - False, XA_CARDINAL, &type, &format, &nitems, - &bytes_after, &data); - err = meta_error_trap_pop_with_return (display); - - if (err != Success || - result != Success) - return FALSE; - - if (type != XA_CARDINAL) - { - XFree (data); - return FALSE; - } - - data_as_long = (gulong *)data; - - if (!find_best_size (data_as_long, nitems, - ideal_width, ideal_height, - &w, &h, &best)) - { - XFree (data); - return FALSE; - } - - *width = w; - *height = h; - - argbdata_to_pixdata (best, w * h, pixdata); - - XFree (data); - - return TRUE; -} - -static void -free_pixels (guchar *pixels, gpointer data) -{ - free (pixels); -} - -static void -get_pixmap_geometry (MetaDisplay *display, - Pixmap pixmap, - int *w, - int *h, - int *d) -{ - Window root_ignored; - int x_ignored, y_ignored; - guint width, height; - guint border_width_ignored; - guint depth; - - if (w) - *w = 1; - if (h) - *h = 1; - if (d) - *d = 1; - - XGetGeometry (display->xdisplay, - pixmap, &root_ignored, &x_ignored, &y_ignored, - &width, &height, &border_width_ignored, &depth); - - if (w) - *w = width; - if (h) - *h = height; - if (d) - *d = depth; -} - -static void -apply_foreground_background (GdkPixbuf *pixbuf) -{ - int w, h; - int i, j; - guchar *pixels; - int stride; - - w = gdk_pixbuf_get_width (pixbuf); - h = gdk_pixbuf_get_height (pixbuf); - pixels = gdk_pixbuf_get_pixels (pixbuf); - stride = gdk_pixbuf_get_rowstride (pixbuf); - - i = 0; - while (i < h) - { - j = 0; - while (j < w) - { - guchar *p = pixels + i * stride + j * 4; - if (p[3] == 0) - p[0] = p[1] = p[2] = 0xff; /* white background */ - else - p[0] = p[1] = p[2] = 0x00; /* black foreground */ - - p[3] = 0xff; - - ++j; - } - - ++i; - } -} - -static GdkPixbuf* -apply_mask (GdkPixbuf *pixbuf, - GdkPixbuf *mask) -{ - int w, h; - int i, j; - GdkPixbuf *with_alpha; - guchar *src; - guchar *dest; - int src_stride; - int dest_stride; - - w = MIN (gdk_pixbuf_get_width (mask), gdk_pixbuf_get_width (pixbuf)); - h = MIN (gdk_pixbuf_get_height (mask), gdk_pixbuf_get_height (pixbuf)); - - with_alpha = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0); - - dest = gdk_pixbuf_get_pixels (with_alpha); - src = gdk_pixbuf_get_pixels (mask); - - dest_stride = gdk_pixbuf_get_rowstride (with_alpha); - src_stride = gdk_pixbuf_get_rowstride (mask); - - i = 0; - while (i < h) - { - j = 0; - while (j < w) - { - guchar *s = src + i * src_stride + j * 4; - guchar *d = dest + i * dest_stride + j * 4; - - d[3] = s[3]; - - ++j; - } - - ++i; - } - - return with_alpha; -} - -static gboolean -try_pixmap_and_mask (MetaDisplay *display, - Pixmap src_pixmap, - Pixmap src_mask, - GdkPixbuf **iconp, - int ideal_width, - int ideal_height) -{ - GdkPixbuf *unscaled = NULL; - GdkPixbuf *mask = NULL; - int w, h, d; - - if (src_pixmap == None) - return FALSE; - - meta_error_trap_push (display); - - get_pixmap_geometry (display, src_pixmap, &w, &h, &d); - - unscaled = meta_gdk_pixbuf_get_from_pixmap (src_pixmap, - 0, 0, - w, h); - - /* A depth 1 pixmap has 0 background, and 1 foreground, but - * cairo and meta_gdk_pixbuf_get_from_pixmap consider it - * to be 0 transparent, 1 opaque */ - if (d == 1) - apply_foreground_background (unscaled); - - if (unscaled && src_mask != None) - { - get_pixmap_geometry (display, src_mask, &w, &h, &d); - if (d == 1) - mask = meta_gdk_pixbuf_get_from_pixmap (src_mask, - 0, 0, - w, h); - } - - meta_error_trap_pop (display); - - if (mask) - { - GdkPixbuf *masked; - - masked = apply_mask (unscaled, mask); - g_object_unref (G_OBJECT (unscaled)); - unscaled = masked; - - g_object_unref (G_OBJECT (mask)); - mask = NULL; - } - - if (unscaled) - { - *iconp = - gdk_pixbuf_scale_simple (unscaled, - ideal_width > 0 ? ideal_width : - gdk_pixbuf_get_width (unscaled), - ideal_height > 0 ? ideal_height : - gdk_pixbuf_get_height (unscaled), - GDK_INTERP_BILINEAR); - - g_object_unref (G_OBJECT (unscaled)); - - if (*iconp) - return TRUE; - else - { - if (*iconp) - g_object_unref (G_OBJECT (*iconp)); - return FALSE; - } - } - else - return FALSE; -} - -static void -get_kwm_win_icon (MetaDisplay *display, - Window xwindow, - Pixmap *pixmap, - Pixmap *mask) -{ - Atom type; - int format; - gulong nitems; - gulong bytes_after; - guchar *data; - Pixmap *icons; - int err, result; - - *pixmap = None; - *mask = None; - - meta_error_trap_push_with_return (display); - icons = NULL; - result = XGetWindowProperty (display->xdisplay, xwindow, - display->atom__KWM_WIN_ICON, - 0, G_MAXLONG, - False, - display->atom__KWM_WIN_ICON, - &type, &format, &nitems, - &bytes_after, &data); - icons = (Pixmap *)data; - - err = meta_error_trap_pop_with_return (display); - if (err != Success || - result != Success) - return; - - if (type != display->atom__KWM_WIN_ICON) - { - XFree (icons); - return; - } - - *pixmap = icons[0]; - *mask = icons[1]; - - XFree (icons); - - return; -} - -LOCAL_SYMBOL void -meta_icon_cache_init (MetaIconCache *icon_cache) -{ - g_return_if_fail (icon_cache != NULL); - - icon_cache->origin = USING_NO_ICON; - icon_cache->prev_pixmap = None; - icon_cache->prev_mask = None; - - icon_cache->want_fallback = TRUE; - icon_cache->wm_hints_dirty = TRUE; - icon_cache->kwm_win_icon_dirty = TRUE; - icon_cache->net_wm_icon_dirty = TRUE; -} - -static void -clear_icon_cache (MetaIconCache *icon_cache, - gboolean dirty_all) -{ -#if 0 - if (icon_cache->icon) - g_object_unref (G_OBJECT (icon_cache->icon)); - icon_cache->icon = NULL; - - if (icon_cache->mini_icon) - g_object_unref (G_OBJECT (icon_cache->mini_icon)); - icon_cache->mini_icon = NULL; -#endif - - icon_cache->origin = USING_NO_ICON; - - if (dirty_all) - { - icon_cache->wm_hints_dirty = TRUE; - icon_cache->kwm_win_icon_dirty = TRUE; - icon_cache->net_wm_icon_dirty = TRUE; - } -} - -LOCAL_SYMBOL void -meta_icon_cache_free (MetaIconCache *icon_cache) -{ - clear_icon_cache (icon_cache, FALSE); -} - -LOCAL_SYMBOL void -meta_icon_cache_property_changed (MetaIconCache *icon_cache, - MetaDisplay *display, - Atom atom) -{ - if (atom == display->atom__NET_WM_ICON) - icon_cache->net_wm_icon_dirty = TRUE; - else if (atom == display->atom__KWM_WIN_ICON) - icon_cache->kwm_win_icon_dirty = TRUE; - else if (atom == XA_WM_HINTS) - icon_cache->wm_hints_dirty = TRUE; -} - -LOCAL_SYMBOL gboolean -meta_icon_cache_get_icon_invalidated (MetaIconCache *icon_cache) -{ - if (icon_cache->origin <= USING_KWM_WIN_ICON && - icon_cache->kwm_win_icon_dirty) - return TRUE; - else if (icon_cache->origin <= USING_WM_HINTS && - icon_cache->wm_hints_dirty) - return TRUE; - else if (icon_cache->origin <= USING_NET_WM_ICON && - icon_cache->net_wm_icon_dirty) - return TRUE; - else if (icon_cache->origin < USING_FALLBACK_ICON && - icon_cache->want_fallback) - return TRUE; - else if (icon_cache->origin == USING_NO_ICON) - return TRUE; - else if (icon_cache->origin == USING_FALLBACK_ICON && - !icon_cache->want_fallback) - return TRUE; - else - return FALSE; -} - -static void -replace_cache (MetaIconCache *icon_cache, - IconOrigin origin, - GdkPixbuf *new_icon) -{ - clear_icon_cache (icon_cache, FALSE); - - icon_cache->origin = origin; -} - -static GdkPixbuf* -scaled_from_pixdata (guchar *pixdata, - int w, - int h, - int new_w, - int new_h) -{ - GdkPixbuf *src; - GdkPixbuf *dest; - - src = gdk_pixbuf_new_from_data (pixdata, - GDK_COLORSPACE_RGB, - TRUE, - 8, - w, h, w * 4, - free_pixels, - NULL); - - if (src == NULL) - return NULL; - - if (w != h) - { - GdkPixbuf *tmp; - int size; - - size = MAX (w, h); - - tmp = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, size, size); - - if (tmp) - { - gdk_pixbuf_fill (tmp, 0); - gdk_pixbuf_copy_area (src, 0, 0, w, h, - tmp, - (size - w) / 2, (size - h) / 2); - - g_object_unref (src); - src = tmp; - } - } - - if (w != new_w || h != new_h) - { - dest = gdk_pixbuf_scale_simple (src, new_w, new_h, GDK_INTERP_BILINEAR); - - g_object_unref (G_OBJECT (src)); - } - else - { - dest = src; - } - - return dest; -} - -LOCAL_SYMBOL gboolean -meta_read_icons (MetaScreen *screen, - Window xwindow, - MetaIconCache *icon_cache, - Pixmap wm_hints_pixmap, - Pixmap wm_hints_mask, - GdkPixbuf **iconp, - int ideal_width, - int ideal_height) -{ - guchar *pixdata; - int w, h; - Pixmap pixmap; - Pixmap mask; - - /* Return value is whether the icon changed */ - - g_return_val_if_fail (icon_cache != NULL, FALSE); - - *iconp = NULL; - - clear_icon_cache (icon_cache, TRUE); - - pixdata = NULL; - - /* Our algorithm here assumes that we can't have for example origin - * < USING_NET_WM_ICON and icon_cache->net_wm_icon_dirty == FALSE - * unless we have tried to read NET_WM_ICON. - * - * Put another way, if an icon origin is not dirty, then we have - * tried to read it at the current size. If it is dirty, then - * we haven't done that since the last change. - */ - - if (icon_cache->origin <= USING_NET_WM_ICON && - icon_cache->net_wm_icon_dirty) - - { - icon_cache->net_wm_icon_dirty = FALSE; - - if (read_rgb_icon (screen->display, xwindow, - ideal_width, ideal_height, - &w, &h, &pixdata)) - { - *iconp = scaled_from_pixdata (pixdata, w, h, - ideal_width, ideal_height); - - if (*iconp) - { - replace_cache (icon_cache, USING_NET_WM_ICON, *iconp); - - return TRUE; - } - else - { - if (*iconp) - g_object_unref (G_OBJECT (*iconp)); - } - } - } - - if (icon_cache->origin <= USING_WM_HINTS && - icon_cache->wm_hints_dirty) - { - icon_cache->wm_hints_dirty = FALSE; - - pixmap = wm_hints_pixmap; - mask = wm_hints_mask; - - /* We won't update if pixmap is unchanged; - * avoids a get_from_drawable() on every geometry - * hints change - */ - if ((pixmap != icon_cache->prev_pixmap || - mask != icon_cache->prev_mask) && - pixmap != None) - { - if (try_pixmap_and_mask (screen->display, - pixmap, mask, - iconp, ideal_width, ideal_height)) - { - icon_cache->prev_pixmap = pixmap; - icon_cache->prev_mask = mask; - - replace_cache (icon_cache, USING_WM_HINTS, *iconp); - - return TRUE; - } - } - } - - if (icon_cache->origin <= USING_KWM_WIN_ICON && - icon_cache->kwm_win_icon_dirty) - { - icon_cache->kwm_win_icon_dirty = FALSE; - - get_kwm_win_icon (screen->display, xwindow, &pixmap, &mask); - - if ((pixmap != icon_cache->prev_pixmap || - mask != icon_cache->prev_mask) && - pixmap != None) - { - if (try_pixmap_and_mask (screen->display, pixmap, mask, - iconp, ideal_width, ideal_height)) - { - icon_cache->prev_pixmap = pixmap; - icon_cache->prev_mask = mask; - - replace_cache (icon_cache, USING_KWM_WIN_ICON, *iconp); - - return TRUE; - } - } - } - - if (icon_cache->origin < USING_FALLBACK_ICON) - { - replace_cache (icon_cache, USING_FALLBACK_ICON, *iconp); - - return TRUE; - } - - if (!icon_cache->want_fallback && - icon_cache->origin == USING_FALLBACK_ICON) - { - /* Get rid of current icon */ - clear_icon_cache (icon_cache, FALSE); - - return TRUE; - } - - /* found nothing new */ - return FALSE; -} diff --git a/src/core/keybindings-private.h b/src/core/keybindings-private.h index 32451ea66..ab1ab52fe 100644 --- a/src/core/keybindings-private.h +++ b/src/core/keybindings-private.h @@ -7,9 +7,9 @@ * the one to close a window. It also deals with incoming key events. */ -/* +/* * Copyright (C) 2001 Havoc Pennington - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the @@ -19,79 +19,144 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_KEYBINDINGS_PRIVATE_H #define META_KEYBINDINGS_PRIVATE_H -#include <meta/keybindings.h> +#include <gio/gio.h> +#include <xkbcommon/xkbcommon.h> +#include "core/meta-accel-parse.h" +#include "meta/keybindings.h" + +typedef struct _MetaKeyHandler MetaKeyHandler; struct _MetaKeyHandler { char *name; MetaKeyHandlerFunc func; MetaKeyHandlerFunc default_func; - gint data, flags, action; + gint data, flags; gpointer user_data; GDestroyNotify user_data_free_func; }; +typedef struct _MetaResolvedKeyCombo { + xkb_keycode_t *keycodes; + int len; + xkb_mod_mask_t mask; +} MetaResolvedKeyCombo; + +/** + * MetaKeyCombo: + * @keysym: keysym + * @keycode: keycode + * @modifiers: modifiers + */ +struct _MetaKeyCombo +{ + unsigned int keysym; + unsigned int keycode; + MetaVirtualModifier modifiers; +}; + struct _MetaKeyBinding { const char *name; - KeySym keysym; - KeyCode keycode; - unsigned int mask; - MetaVirtualModifier modifiers; + MetaKeyCombo combo; + MetaResolvedKeyCombo resolved_combo; + gint flags; MetaKeyHandler *handler; }; +typedef struct +{ + char *name; + GSettings *settings; + + MetaKeyBindingAction action; + + /* + * A list of MetaKeyCombos. Each of them is bound to + * this keypref. If one has keysym==modifiers==0, it is + * ignored. + */ + GSList *combos; + + /* for keybindings not added with meta_display_add_keybinding() */ + gboolean builtin:1; +} MetaKeyPref; + +typedef struct _MetaKeyBindingKeyboardLayout +{ + struct xkb_keymap *keymap; + xkb_layout_index_t index; + xkb_level_index_t n_levels; +} MetaKeyBindingKeyboardLayout; + +typedef struct +{ + MetaBackend *backend; + + GHashTable *key_bindings; + GHashTable *key_bindings_index; + xkb_mod_mask_t ignored_modifier_mask; + xkb_mod_mask_t hyper_mask; + xkb_mod_mask_t virtual_hyper_mask; + xkb_mod_mask_t super_mask; + xkb_mod_mask_t virtual_super_mask; + xkb_mod_mask_t meta_mask; + xkb_mod_mask_t virtual_meta_mask; + MetaKeyCombo overlay_key_combo; + MetaResolvedKeyCombo overlay_resolved_key_combo; + gboolean overlay_key_only_pressed; + MetaKeyCombo locate_pointer_key_combo; + MetaResolvedKeyCombo locate_pointer_resolved_key_combo; + gboolean locate_pointer_key_only_pressed; + MetaResolvedKeyCombo iso_next_group_combo[2]; + int n_iso_next_group_combos; + + /* + * A primary layout, and an optional secondary layout for when the + * primary layout does not use the latin alphabet. + */ + MetaKeyBindingKeyboardLayout active_layouts[2]; + + /* Alt+click button grabs */ + ClutterModifierType window_grab_modifiers; +} MetaKeyBindingManager; + void meta_display_init_keys (MetaDisplay *display); void meta_display_shutdown_keys (MetaDisplay *display); -void meta_screen_grab_keys (MetaScreen *screen); -void meta_screen_ungrab_keys (MetaScreen *screen); void meta_window_grab_keys (MetaWindow *window); void meta_window_ungrab_keys (MetaWindow *window); gboolean meta_window_grab_all_keys (MetaWindow *window, guint32 timestamp); void meta_window_ungrab_all_keys (MetaWindow *window, guint32 timestamp); +gboolean meta_keybindings_process_event (MetaDisplay *display, + MetaWindow *window, + const ClutterEvent *event); -gboolean meta_window_resize_or_move_allowed (MetaWindow *window, - MetaDirection dir); - -gboolean meta_display_grabbed_event_is_action (MetaDisplay *display, - XEvent *event, - MetaKeyBindingAction action); - -gboolean meta_display_process_key_event (MetaDisplay *display, - MetaWindow *window, - XEvent *event); -void meta_set_keybindings_disabled (gboolean setting); -void meta_display_process_mapping_event (MetaDisplay *display, - XEvent *event); +ClutterModifierType meta_display_get_window_grab_modifiers (MetaDisplay *display); gboolean meta_prefs_add_keybinding (const char *name, - const char *schema, + GSettings *settings, MetaKeyBindingAction action, MetaKeyBindingFlags flags); gboolean meta_prefs_remove_keybinding (const char *name); -gboolean meta_prefs_add_custom_keybinding (const char *name, - const char **binding, - MetaKeyBindingAction action, - MetaKeyBindingFlags flags); +GList *meta_prefs_get_keybindings (void); +void meta_prefs_get_overlay_binding (MetaKeyCombo *combo); +void meta_prefs_get_locate_pointer_binding (MetaKeyCombo *combo); +const char *meta_prefs_get_iso_next_group_option (void); +gboolean meta_prefs_is_locate_pointer_enabled (void); -gboolean meta_prefs_remove_custom_keybinding (const char *name); +void meta_x11_display_grab_keys (MetaX11Display *x11_display); +void meta_x11_display_ungrab_keys (MetaX11Display *x11_display); #endif - - - - diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 1cb7b4120..d2740be52 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -1,6 +1,6 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* Muffin Keybindings */ +/* Mutter Keybindings */ /* * Copyright (C) 2001 Havoc Pennington * Copyright (C) 2002 Red Hat Inc. @@ -18,112 +18,133 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ /** * SECTION:keybindings - * @title: MetaKeybinding - * @short_description: Key bindings + * @Title: MetaKeybinding + * @Short_Description: Key bindings */ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif -#define _SVID_SOURCE /* for putenv() */ - -#include <config.h> -#include "keybindings-private.h" -#include "workspace-private.h" -#include <meta/errors.h> -#include "window-private.h" -#include "edge-resistance.h" -#include "ui.h" -#include "frame.h" -#include "place.h" -#include <meta/prefs.h> -#include "util-private.h" - -#include <X11/keysym.h> -#include <string.h> -#include <stdio.h> -#include <stdlib.h> - -#ifdef HAVE_XKB -#include <X11/XKBlib.h> +#include "config.h" + +#include "backends/meta-backend-private.h" +#include "backends/meta-logical-monitor.h" +#include "backends/meta-monitor-manager-private.h" +#include "backends/x11/meta-backend-x11.h" +#include "compositor/compositor-private.h" +#include "core/edge-resistance.h" +#include "core/frame.h" +#include "core/keybindings-private.h" +#include "core/meta-accel-parse.h" +#include "core/meta-workspace-manager-private.h" +#include "core/workspace-private.h" +#include "meta/compositor.h" +#include "meta/meta-x11-errors.h" +#include "meta/prefs.h" +#include "x11/meta-x11-display-private.h" +#include "x11/window-x11.h" + +#ifdef HAVE_NATIVE_BACKEND +#include "backends/native/meta-backend-native.h" #endif -#if __GNUC__ >= 7 -#define DISABLE_GCC7_FALL_THRU_WARNING __attribute__ ((fallthrough)) -#else -#define DISABLE_GCC7_FALL_THRU_WARNING "" +#ifdef __linux__ +#include <linux/input.h> +#elif !defined KEY_GRAVE +#define KEY_GRAVE 0x29 /* assume the use of xf86-input-keyboard */ #endif -#define SCHEMA_MUFFIN_KEYBINDINGS "org.cinnamon.desktop.keybindings.wm" -#define SCHEMA_MUFFIN "org.cinnamon.muffin" +#define SCHEMA_COMMON_KEYBINDINGS "org.cinnamon.desktop.keybindings.wm" +#define SCHEMA_MUTTER_KEYBINDINGS "org.cinnamon.muffin.keybindings" +#define SCHEMA_MUTTER_WAYLAND_KEYBINDINGS "org.cinnamon.muffin.wayland.keybindings" + +#define META_KEY_BINDING_PRIMARY_LAYOUT 0 +#define META_KEY_BINDING_SECONDARY_LAYOUT 1 -static gboolean all_bindings_disabled = FALSE; -static gboolean modifier_only_is_down = FALSE; +/* Only for special modifier keys */ +#define IGNORED_MODIFIERS (CLUTTER_LOCK_MASK | \ + CLUTTER_MOD2_MASK | \ + CLUTTER_BUTTON1_MASK | \ + CLUTTER_BUTTON2_MASK | \ + CLUTTER_BUTTON3_MASK | \ + CLUTTER_BUTTON4_MASK | \ + CLUTTER_BUTTON5_MASK) + +static gboolean modifier_key_only_pressed = FALSE; static gboolean add_builtin_keybinding (MetaDisplay *display, const char *name, - const char *schema, + GSettings *settings, MetaKeyBindingFlags flags, MetaKeyBindingAction action, MetaKeyHandlerFunc handler, int handler_arg); -static void invoke_handler_by_name (MetaDisplay *display, - MetaScreen *screen, - const char *handler_name, - MetaWindow *window, - XEvent *event); - -enum { - META_MOVE_TO_XCHANGE_FLAG = 8, // 1000 - META_MOVE_TO_YCHANGE_FLAG = 4, // 0100 - META_MOVE_TO_RIGHT_FLAG = 2, // 0010 - META_MOVE_TO_BOTTOM_FLAG = 1 // 0001 -}; +static void +resolved_key_combo_reset (MetaResolvedKeyCombo *resolved_combo) +{ + g_free (resolved_combo->keycodes); + resolved_combo->len = 0; + resolved_combo->keycodes = NULL; +} -// Using flags above -enum { - META_MOVE_TO_SE = 15, // 1111 - META_MOVE_TO_NE = 14, // 1110 - META_MOVE_TO_SW = 13, // 1101 - META_MOVE_TO_NW = 12, // 1100 - META_MOVE_TO_E = 10, // 1010 - META_MOVE_TO_W = 8, // 1000 - META_MOVE_TO_S = 5, // 0101 - META_MOVE_TO_N = 4 // 0100 -}; +static void +resolved_key_combo_copy (MetaResolvedKeyCombo *from, + MetaResolvedKeyCombo *to) +{ + to->len = from->len; + to->keycodes = g_memdup (from->keycodes, + from->len * sizeof (xkb_keycode_t)); +} + +static gboolean +resolved_key_combo_has_keycode (MetaResolvedKeyCombo *resolved_combo, + int keycode) +{ + int i; + + for (i = 0; i < resolved_combo->len; i++) + if ((int) resolved_combo->keycodes[i] == keycode) + return TRUE; + + return FALSE; +} + +static gboolean +resolved_key_combo_intersect (MetaResolvedKeyCombo *a, + MetaResolvedKeyCombo *b) +{ + int i; + + for (i = 0; i < a->len; i++) + if (resolved_key_combo_has_keycode (b, a->keycodes[i])) + return TRUE; + + return FALSE; +} static void meta_key_binding_free (MetaKeyBinding *binding) { + resolved_key_combo_reset (&binding->resolved_combo); g_slice_free (MetaKeyBinding, binding); } static MetaKeyBinding * meta_key_binding_copy (MetaKeyBinding *binding) { - return g_slice_dup (MetaKeyBinding, binding); + MetaKeyBinding *clone = g_slice_dup (MetaKeyBinding, binding); + resolved_key_combo_copy (&binding->resolved_combo, + &clone->resolved_combo); + return clone; } -GType -meta_key_binding_get_type (void) -{ - static GType type_id = 0; - - if (G_UNLIKELY (type_id == 0)) - type_id = g_boxed_type_register_static (g_intern_static_string ("MetaKeyBinding"), - (GBoxedCopyFunc)meta_key_binding_copy, - (GBoxedFreeFunc)meta_key_binding_free); - - return type_id; -} +G_DEFINE_BOXED_TYPE(MetaKeyBinding, + meta_key_binding, + meta_key_binding_copy, + meta_key_binding_free) const char * meta_key_binding_get_name (MetaKeyBinding *binding) @@ -134,13 +155,25 @@ meta_key_binding_get_name (MetaKeyBinding *binding) MetaVirtualModifier meta_key_binding_get_modifiers (MetaKeyBinding *binding) { - return binding->modifiers; + return binding->combo.modifiers; +} + +gboolean +meta_key_binding_is_reversed (MetaKeyBinding *binding) +{ + return (binding->handler->flags & META_KEY_BINDING_IS_REVERSED) != 0; } guint meta_key_binding_get_mask (MetaKeyBinding *binding) { - return binding->mask; + return binding->resolved_combo.mask; +} + +gboolean +meta_key_binding_is_builtin (MetaKeyBinding *binding) +{ + return binding->handler->flags & META_KEY_BINDING_BUILTIN; } /* These can't be bound to anything, but they are used to handle @@ -148,279 +181,638 @@ meta_key_binding_get_mask (MetaKeyBinding *binding) * handler functions and have some kind of flag to say they're unbindable. */ -static gboolean process_mouse_move_resize_grab (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XEvent *event, - KeySym keysym); - -static gboolean process_keyboard_move_grab (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XEvent *event, - KeySym keysym); +static gboolean process_mouse_move_resize_grab (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event); -static gboolean process_keyboard_resize_grab (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XEvent *event, - KeySym keysym); - -static void regrab_key_bindings (MetaDisplay *display); +static gboolean process_keyboard_move_grab (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event); +static gboolean process_keyboard_resize_grab (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event); static GHashTable *key_handlers; +static GHashTable *external_grabs; #define HANDLER(name) g_hash_table_lookup (key_handlers, (name)) static void key_handler_free (MetaKeyHandler *handler) { - free (handler->name); + g_free (handler->name); if (handler->user_data_free_func && handler->user_data) handler->user_data_free_func (handler->user_data); - free (handler); + g_free (handler); } +typedef struct _MetaKeyGrab MetaKeyGrab; +struct _MetaKeyGrab { + char *name; + guint action; + MetaKeyCombo combo; + gint flags; +}; + static void -reload_keymap (MetaDisplay *display) +meta_key_grab_free (MetaKeyGrab *grab) { - if (display->keymap) - meta_XFree (display->keymap); - - /* This is expensive to compute, so we'll lazily load if and when we first - * need it */ - display->above_tab_keycode = 0; + g_free (grab->name); + g_free (grab); +} - display->keymap = XGetKeyboardMapping (display->xdisplay, - display->min_keycode, - display->max_keycode - - display->min_keycode + 1, - &display->keysyms_per_keycode); +static guint32 +key_combo_key (MetaResolvedKeyCombo *resolved_combo, + int i) +{ + /* On X, keycodes are only 8 bits while libxkbcommon supports 32 bit + keycodes, but since we're using the same XKB keymaps that X uses, + we won't find keycodes bigger than 8 bits in practice. The bits + that mutter cares about in the modifier mask are also all in the + lower 8 bits both on X and clutter key events. This means that we + can use a 32 bit integer to safely concatenate both keycode and + mask and thus making it easy to use them as an index in a + GHashTable. */ + guint32 key = resolved_combo->keycodes[i] & 0xffff; + return (key << 16) | (resolved_combo->mask & 0xffff); } static void -reload_modmap (MetaDisplay *display) +reload_modmap (MetaKeyBindingManager *keys) { - XModifierKeymap *modmap; - int map_size; - int i; + struct xkb_keymap *keymap = meta_backend_get_keymap (keys->backend); + struct xkb_state *scratch_state; + xkb_mod_mask_t scroll_lock_mask; + xkb_mod_mask_t dummy_mask; + + /* Modifiers to find. */ + struct { + const char *name; + xkb_mod_mask_t *mask_p; + xkb_mod_mask_t *virtual_mask_p; + } mods[] = { + { "ScrollLock", &scroll_lock_mask, &dummy_mask }, + { "Meta", &keys->meta_mask, &keys->virtual_meta_mask }, + { "Hyper", &keys->hyper_mask, &keys->virtual_hyper_mask }, + { "Super", &keys->super_mask, &keys->virtual_super_mask }, + }; + + scratch_state = xkb_state_new (keymap); + + gsize i; + for (i = 0; i < G_N_ELEMENTS (mods); i++) + { + xkb_mod_mask_t *mask_p = mods[i].mask_p; + xkb_mod_mask_t *virtual_mask_p = mods[i].virtual_mask_p; + xkb_mod_index_t idx = xkb_keymap_mod_get_index (keymap, mods[i].name); + + if (idx != XKB_MOD_INVALID) + { + xkb_mod_mask_t vmodmask = (1 << idx); + xkb_state_update_mask (scratch_state, vmodmask, 0, 0, 0, 0, 0); + *mask_p = xkb_state_serialize_mods (scratch_state, XKB_STATE_MODS_DEPRESSED) & ~vmodmask; + *virtual_mask_p = vmodmask; + } + else + { + *mask_p = 0; + *virtual_mask_p = 0; + } + } - if (display->modmap) - XFreeModifiermap (display->modmap); + xkb_state_unref (scratch_state); - modmap = XGetModifierMapping (display->xdisplay); - display->modmap = modmap; + keys->ignored_modifier_mask = (scroll_lock_mask | Mod2Mask | LockMask); - display->ignored_modifier_mask = 0; + meta_topic (META_DEBUG_KEYBINDINGS, + "Ignoring modmask 0x%x scroll lock 0x%x hyper 0x%x super 0x%x meta 0x%x\n", + keys->ignored_modifier_mask, + scroll_lock_mask, + keys->hyper_mask, + keys->super_mask, + keys->meta_mask); +} - /* Multiple bits may get set in each of these */ - display->num_lock_mask = 0; - display->scroll_lock_mask = 0; - display->meta_mask = 0; - display->hyper_mask = 0; - display->super_mask = 0; +static gboolean +is_keycode_for_keysym (struct xkb_keymap *keymap, + xkb_layout_index_t layout, + xkb_level_index_t level, + xkb_keycode_t keycode, + xkb_keysym_t keysym) +{ + const xkb_keysym_t *syms; + int num_syms, k; - /* there are 8 modifiers, and the first 3 are shift, shift lock, - * and control - */ - map_size = 8 * modmap->max_keypermod; - i = 3 * modmap->max_keypermod; - while (i < map_size) + num_syms = xkb_keymap_key_get_syms_by_level (keymap, keycode, layout, level, &syms); + for (k = 0; k < num_syms; k++) { - /* get the key code at this point in the map, - * see if its keysym is one we're interested in - */ - int keycode = modmap->modifiermap[i]; + if (syms[k] == keysym) + return TRUE; + } - if (keycode >= display->min_keycode && - keycode <= display->max_keycode) - { - int j = 0; - KeySym *syms = display->keymap + - (keycode - display->min_keycode) * display->keysyms_per_keycode; + return FALSE; +} - while (j < display->keysyms_per_keycode) - { - if (syms[j] != 0) - { - const char *str; +typedef struct +{ + GArray *keycodes; + xkb_keysym_t keysym; + xkb_layout_index_t layout; + xkb_level_index_t level; +} FindKeysymData; - str = XKeysymToString (syms[j]); - meta_topic (META_DEBUG_KEYBINDINGS, - "Keysym %s bound to modifier 0x%x\n", - str ? str : "none", - (1 << ( i / modmap->max_keypermod))); - } +static void +get_keycodes_for_keysym_iter (struct xkb_keymap *keymap, + xkb_keycode_t keycode, + void *data) +{ + FindKeysymData *search_data = data; + GArray *keycodes = search_data->keycodes; + xkb_keysym_t keysym = search_data->keysym; + xkb_layout_index_t layout = search_data->layout; + xkb_level_index_t level = search_data->level; - if (syms[j] == XK_Num_Lock) - { - /* Mod1Mask is 1 << 3 for example, i.e. the - * fourth modifier, i / keyspermod is the modifier - * index - */ + if (is_keycode_for_keysym (keymap, layout, level, keycode, keysym)) + { + guint i; + gboolean missing = TRUE; + + /* duplicate keycode detection */ + for (i = 0; i < keycodes->len; i++) + if (g_array_index (keycodes, xkb_keysym_t, i) == keycode) + { + missing = FALSE; + break; + } - display->num_lock_mask |= (1 << ( i / modmap->max_keypermod)); - } - else if (syms[j] == XK_Scroll_Lock) - { - display->scroll_lock_mask |= (1 << ( i / modmap->max_keypermod)); - } - else if (syms[j] == XK_Super_L || - syms[j] == XK_Super_R) - { - display->super_mask |= (1 << ( i / modmap->max_keypermod)); - } - else if (syms[j] == XK_Hyper_L || - syms[j] == XK_Hyper_R) - { - display->hyper_mask |= (1 << ( i / modmap->max_keypermod)); - } - else if (syms[j] == XK_Meta_L || - syms[j] == XK_Meta_R) - { - display->meta_mask |= (1 << ( i / modmap->max_keypermod)); - } + if (missing) + g_array_append_val (keycodes, keycode); + } +} - ++j; - } - } +static void +add_keysym_keycodes_from_layout (int keysym, + MetaKeyBindingKeyboardLayout *layout, + GArray *keycodes) +{ + xkb_level_index_t layout_level; - ++i; + for (layout_level = 0; + layout_level < layout->n_levels && keycodes->len == 0; + layout_level++) + { + FindKeysymData search_data = (FindKeysymData) { + .keycodes = keycodes, + .keysym = keysym, + .layout = layout->index, + .level = layout_level + }; + xkb_keymap_key_for_each (layout->keymap, + get_keycodes_for_keysym_iter, + &search_data); } +} - display->ignored_modifier_mask = (display->num_lock_mask | - display->scroll_lock_mask | - LockMask); +/* Original code from gdk_x11_keymap_get_entries_for_keyval() in + * gdkkeys-x11.c */ +static void +get_keycodes_for_keysym (MetaKeyBindingManager *keys, + int keysym, + MetaResolvedKeyCombo *resolved_combo) +{ + unsigned int i; + GArray *keycodes; + int keycode; - meta_topic (META_DEBUG_KEYBINDINGS, - "Ignoring modmask 0x%x num lock 0x%x scroll lock 0x%x hyper 0x%x super 0x%x meta 0x%x\n", - display->ignored_modifier_mask, - display->num_lock_mask, - display->scroll_lock_mask, - display->hyper_mask, - display->super_mask, - display->meta_mask); + keycodes = g_array_new (FALSE, FALSE, sizeof (xkb_keysym_t)); + + /* Special-case: Fake mutter keysym */ + if (keysym == META_KEY_ABOVE_TAB) + { + keycode = KEY_GRAVE + 8; + g_array_append_val (keycodes, keycode); + goto out; + } + + for (i = 0; i < G_N_ELEMENTS (keys->active_layouts); i++) + { + MetaKeyBindingKeyboardLayout *layout = &keys->active_layouts[i]; + + if (!layout->keymap) + continue; + + add_keysym_keycodes_from_layout (keysym, layout, keycodes); + } + + out: + resolved_combo->len = keycodes->len; + resolved_combo->keycodes = + (xkb_keycode_t *) g_array_free (keycodes, + keycodes->len == 0 ? TRUE : FALSE); } -static guint -keysym_to_keycode (MetaDisplay *display, - guint keysym) +typedef struct _CalculateLayoutLevelsState { - if (keysym == META_KEY_ABOVE_TAB) - return meta_display_get_above_tab_keycode (display); - else - return XKeysymToKeycode (display->xdisplay, keysym); + struct xkb_keymap *keymap; + xkb_layout_index_t layout_index; + + xkb_level_index_t out_n_levels; +} CalculateLayoutLevelState; + +static void +calculate_n_layout_levels_iter (struct xkb_keymap *keymap, + xkb_keycode_t keycode, + void *data) +{ + CalculateLayoutLevelState *state = data; + xkb_level_index_t n_levels; + + n_levels = xkb_keymap_num_levels_for_key (keymap, + keycode, + state->layout_index); + + state->out_n_levels = MAX (n_levels, state->out_n_levels); +} + +static xkb_level_index_t +calculate_n_layout_levels (struct xkb_keymap *keymap, + xkb_layout_index_t layout_index) + +{ + CalculateLayoutLevelState state = { + .keymap = keymap, + .layout_index = layout_index, + + .out_n_levels = 0 + }; + + xkb_keymap_key_for_each (keymap, calculate_n_layout_levels_iter, &state); + + return state.out_n_levels; } static void -reload_keycodes (MetaDisplay *display) +reload_iso_next_group_combos (MetaKeyBindingManager *keys) { - meta_topic (META_DEBUG_KEYBINDINGS, - "Reloading keycodes for binding tables\n"); + const char *iso_next_group_option; + int i; + + for (i = 0; i < keys->n_iso_next_group_combos; i++) + resolved_key_combo_reset (&keys->iso_next_group_combo[i]); + + keys->n_iso_next_group_combos = 0; + + iso_next_group_option = meta_prefs_get_iso_next_group_option (); + if (iso_next_group_option == NULL) + return; + + get_keycodes_for_keysym (keys, XKB_KEY_ISO_Next_Group, keys->iso_next_group_combo); - if (display->key_bindings) + if (keys->iso_next_group_combo[0].len == 0) + return; + + keys->n_iso_next_group_combos = 1; + + if (g_str_equal (iso_next_group_option, "toggle") || + g_str_equal (iso_next_group_option, "lalt_toggle") || + g_str_equal (iso_next_group_option, "lwin_toggle") || + g_str_equal (iso_next_group_option, "rwin_toggle") || + g_str_equal (iso_next_group_option, "lshift_toggle") || + g_str_equal (iso_next_group_option, "rshift_toggle") || + g_str_equal (iso_next_group_option, "lctrl_toggle") || + g_str_equal (iso_next_group_option, "rctrl_toggle") || + g_str_equal (iso_next_group_option, "sclk_toggle") || + g_str_equal (iso_next_group_option, "menu_toggle") || + g_str_equal (iso_next_group_option, "caps_toggle")) { - int i; + keys->iso_next_group_combo[0].mask = 0; + } + else if (g_str_equal (iso_next_group_option, "shift_caps_toggle") || + g_str_equal (iso_next_group_option, "shifts_toggle")) + { + keys->iso_next_group_combo[0].mask = ShiftMask; + } + else if (g_str_equal (iso_next_group_option, "alt_caps_toggle") || + g_str_equal (iso_next_group_option, "alt_space_toggle")) + { + keys->iso_next_group_combo[0].mask = Mod1Mask; + } + else if (g_str_equal (iso_next_group_option, "ctrl_shift_toggle") || + g_str_equal (iso_next_group_option, "lctrl_lshift_toggle") || + g_str_equal (iso_next_group_option, "rctrl_rshift_toggle")) + { + resolved_key_combo_copy (&keys->iso_next_group_combo[0], + &keys->iso_next_group_combo[1]); - i = 0; - while (i < display->n_key_bindings) - { - if (display->key_bindings[i].keysym != 0) - { - display->key_bindings[i].keycode = - keysym_to_keycode (display, display->key_bindings[i].keysym); - } + keys->iso_next_group_combo[0].mask = ShiftMask; + keys->iso_next_group_combo[1].mask = ControlMask; + keys->n_iso_next_group_combos = 2; + } + else if (g_str_equal (iso_next_group_option, "ctrl_alt_toggle")) + { + resolved_key_combo_copy (&keys->iso_next_group_combo[0], + &keys->iso_next_group_combo[1]); - ++i; - } + keys->iso_next_group_combo[0].mask = Mod1Mask; + keys->iso_next_group_combo[1].mask = ControlMask; + keys->n_iso_next_group_combos = 2; + } + else if (g_str_equal (iso_next_group_option, "alt_shift_toggle") || + g_str_equal (iso_next_group_option, "lalt_lshift_toggle")) + { + resolved_key_combo_copy (&keys->iso_next_group_combo[0], + &keys->iso_next_group_combo[1]); + + keys->iso_next_group_combo[0].mask = Mod1Mask; + keys->iso_next_group_combo[1].mask = ShiftMask; + keys->n_iso_next_group_combos = 2; + } + else + { + resolved_key_combo_reset (keys->iso_next_group_combo); + keys->n_iso_next_group_combos = 0; } } static void -reload_modifiers (MetaDisplay *display) +devirtualize_modifiers (MetaKeyBindingManager *keys, + MetaVirtualModifier modifiers, + unsigned int *mask) { - meta_topic (META_DEBUG_KEYBINDINGS, - "Reloading keycodes for binding tables\n"); + *mask = 0; + + if (modifiers & META_VIRTUAL_SHIFT_MASK) + *mask |= ShiftMask; + if (modifiers & META_VIRTUAL_CONTROL_MASK) + *mask |= ControlMask; + if (modifiers & META_VIRTUAL_ALT_MASK) + *mask |= Mod1Mask; + if (modifiers & META_VIRTUAL_META_MASK) + *mask |= keys->meta_mask; + if (modifiers & META_VIRTUAL_HYPER_MASK) + *mask |= keys->hyper_mask; + if (modifiers & META_VIRTUAL_SUPER_MASK) + *mask |= keys->super_mask; + if (modifiers & META_VIRTUAL_MOD2_MASK) + *mask |= Mod2Mask; + if (modifiers & META_VIRTUAL_MOD3_MASK) + *mask |= Mod3Mask; + if (modifiers & META_VIRTUAL_MOD4_MASK) + *mask |= Mod4Mask; + if (modifiers & META_VIRTUAL_MOD5_MASK) + *mask |= Mod5Mask; +} - if (display->key_bindings) +static void +index_binding (MetaKeyBindingManager *keys, + MetaKeyBinding *binding) +{ + int i; + + for (i = 0; i < binding->resolved_combo.len; i++) { - int i; + MetaKeyBinding *existing; + guint32 index_key; - i = 0; - while (i < display->n_key_bindings) + index_key = key_combo_key (&binding->resolved_combo, i); + + existing = g_hash_table_lookup (keys->key_bindings_index, + GINT_TO_POINTER (index_key)); + if (existing != NULL) { - meta_display_devirtualize_modifiers (display, - display->key_bindings[i].modifiers, - &display->key_bindings[i].mask); + /* Overwrite already indexed keycodes only for the first + * keycode, i.e. we give those primary keycodes precedence + * over non-first ones. */ + if (i > 0) + continue; + + meta_warning ("Overwriting existing binding of keysym %x" + " with keysym %x (keycode %x).\n", + binding->combo.keysym, + existing->combo.keysym, + binding->resolved_combo.keycodes[i]); + } - meta_topic (META_DEBUG_KEYBINDINGS, - " Devirtualized mods 0x%x -> 0x%x (%s)\n", - display->key_bindings[i].modifiers, - display->key_bindings[i].mask, - display->key_bindings[i].name); + g_hash_table_replace (keys->key_bindings_index, + GINT_TO_POINTER (index_key), binding); + } +} - ++i; - } +static void +resolve_key_combo (MetaKeyBindingManager *keys, + MetaKeyCombo *combo, + MetaResolvedKeyCombo *resolved_combo) +{ + + resolved_key_combo_reset (resolved_combo); + + if (combo->keysym != 0) + { + get_keycodes_for_keysym (keys, combo->keysym, resolved_combo); + } + else if (combo->keycode != 0) + { + resolved_combo->keycodes = g_new0 (xkb_keycode_t, 1); + resolved_combo->keycodes[0] = combo->keycode; + resolved_combo->len = 1; } + + devirtualize_modifiers (keys, combo->modifiers, &resolved_combo->mask); } +static void +binding_reload_combos_foreach (gpointer key, + gpointer value, + gpointer data) +{ + MetaKeyBindingManager *keys = data; + MetaKeyBinding *binding = value; -static int -count_bindings (GList *prefs) + resolve_key_combo (keys, &binding->combo, &binding->resolved_combo); + index_binding (keys, binding); +} + +typedef struct _FindLatinKeysymsState { - GList *p; - int count; + MetaKeyBindingKeyboardLayout *layout; + gboolean *required_keysyms_found; + int n_required_keysyms; +} FindLatinKeysymsState; - count = 0; - p = prefs; - while (p) +static void +find_latin_keysym (struct xkb_keymap *keymap, + xkb_keycode_t key, + void *data) +{ + FindLatinKeysymsState *state = data; + int n_keysyms, i; + const xkb_keysym_t *keysyms; + + n_keysyms = xkb_keymap_key_get_syms_by_level (state->layout->keymap, + key, + state->layout->index, + 0, + &keysyms); + for (i = 0; i < n_keysyms; i++) { - MetaKeyPref *pref = (MetaKeyPref*)p->data; - GSList *tmp = pref->bindings; + xkb_keysym_t keysym = keysyms[i]; - while (tmp) + if (keysym >= XKB_KEY_a && keysym <= XKB_KEY_z) { - MetaKeyCombo *combo = tmp->data; + unsigned int keysym_index = keysym - XKB_KEY_a; - if (combo && (combo->keysym != None || combo->keycode != 0)) + if (!state->required_keysyms_found[keysym_index]) { - count += 1; - - if (pref->add_shift && - (combo->modifiers & META_VIRTUAL_SHIFT_MASK) == 0) - count += 1; + state->required_keysyms_found[keysym_index] = TRUE; + state->n_required_keysyms--; } - - tmp = tmp->next; } + } +} - p = p->next; +static gboolean +needs_secondary_layout (MetaKeyBindingKeyboardLayout *layout) +{ + gboolean required_keysyms_found[] = { + FALSE, /* XKB_KEY_a */ + FALSE, /* XKB_KEY_b */ + FALSE, /* XKB_KEY_c */ + FALSE, /* XKB_KEY_d */ + FALSE, /* XKB_KEY_e */ + FALSE, /* XKB_KEY_f */ + FALSE, /* XKB_KEY_g */ + FALSE, /* XKB_KEY_h */ + FALSE, /* XKB_KEY_i */ + FALSE, /* XKB_KEY_j */ + FALSE, /* XKB_KEY_k */ + FALSE, /* XKB_KEY_l */ + FALSE, /* XKB_KEY_m */ + FALSE, /* XKB_KEY_n */ + FALSE, /* XKB_KEY_o */ + FALSE, /* XKB_KEY_p */ + FALSE, /* XKB_KEY_q */ + FALSE, /* XKB_KEY_r */ + FALSE, /* XKB_KEY_s */ + FALSE, /* XKB_KEY_t */ + FALSE, /* XKB_KEY_u */ + FALSE, /* XKB_KEY_v */ + FALSE, /* XKB_KEY_w */ + FALSE, /* XKB_KEY_x */ + FALSE, /* XKB_KEY_y */ + FALSE, /* XKB_KEY_z */ + }; + FindLatinKeysymsState state = { + .layout = layout, + .required_keysyms_found = required_keysyms_found, + .n_required_keysyms = G_N_ELEMENTS (required_keysyms_found), + }; + + xkb_keymap_key_for_each (layout->keymap, find_latin_keysym, &state); + + return state.n_required_keysyms != 0; +} + +static void +clear_active_keyboard_layouts (MetaKeyBindingManager *keys) +{ + unsigned int i; + + for (i = 0; i < G_N_ELEMENTS (keys->active_layouts); i++) + { + MetaKeyBindingKeyboardLayout *layout = &keys->active_layouts[i]; + + g_clear_pointer (&layout->keymap, xkb_keymap_unref); + *layout = (MetaKeyBindingKeyboardLayout) { 0 }; } +} - return count; +static MetaKeyBindingKeyboardLayout +create_us_layout (void) +{ + struct xkb_rule_names names; + struct xkb_keymap *keymap; + struct xkb_context *context; + + names.rules = DEFAULT_XKB_RULES_FILE; + names.model = DEFAULT_XKB_MODEL; + names.layout = "us"; + names.variant = ""; + names.options = ""; + + context = xkb_context_new (XKB_CONTEXT_NO_FLAGS); + keymap = xkb_keymap_new_from_names (context, &names, XKB_KEYMAP_COMPILE_NO_FLAGS); + xkb_context_unref (context); + + return (MetaKeyBindingKeyboardLayout) { + .keymap = keymap, + .n_levels = calculate_n_layout_levels (keymap, 0), + }; } static void -rebuild_binding_table (MetaDisplay *display, - MetaKeyBinding **bindings_p, - int *n_bindings_p, - GList *prefs) +reload_active_keyboard_layouts (MetaKeyBindingManager *keys) { - GList *p; - int n_bindings; - int i; + struct xkb_keymap *keymap; + xkb_layout_index_t layout_index; + MetaKeyBindingKeyboardLayout primary_layout; + + clear_active_keyboard_layouts (keys); + + keymap = meta_backend_get_keymap (keys->backend); + layout_index = meta_backend_get_keymap_layout_group (keys->backend); + primary_layout = (MetaKeyBindingKeyboardLayout) { + .keymap = xkb_keymap_ref (keymap), + .index = layout_index, + .n_levels = calculate_n_layout_levels (keymap, layout_index), + }; + + keys->active_layouts[META_KEY_BINDING_PRIMARY_LAYOUT] = primary_layout; + + if (needs_secondary_layout (&primary_layout)) + { + MetaKeyBindingKeyboardLayout us_layout; + + us_layout = create_us_layout (); + keys->active_layouts[META_KEY_BINDING_SECONDARY_LAYOUT] = us_layout; + } +} + +static void +reload_combos (MetaKeyBindingManager *keys) +{ + g_hash_table_remove_all (keys->key_bindings_index); + + reload_active_keyboard_layouts (keys); + + resolve_key_combo (keys, + &keys->overlay_key_combo, + &keys->overlay_resolved_key_combo); + + resolve_key_combo (keys, + &keys->locate_pointer_key_combo, + &keys->locate_pointer_resolved_key_combo); - n_bindings = count_bindings (prefs); - free (*bindings_p); - *bindings_p = g_new0 (MetaKeyBinding, n_bindings); + reload_iso_next_group_combos (keys); + + g_hash_table_foreach (keys->key_bindings, binding_reload_combos_foreach, keys); +} + +static void +rebuild_binding_table (MetaKeyBindingManager *keys, + GList *prefs, + GList *grabs) +{ + MetaKeyBinding *b; + GList *p, *g; + + g_hash_table_remove_all (keys->key_bindings); - i = 0; p = prefs; while (p) { MetaKeyPref *pref = (MetaKeyPref*)p->data; - GSList *tmp = pref->bindings; + GSList *tmp = pref->combos; while (tmp) { @@ -430,32 +822,13 @@ rebuild_binding_table (MetaDisplay *display, { MetaKeyHandler *handler = HANDLER (pref->name); - (*bindings_p)[i].name = pref->name; - (*bindings_p)[i].handler = handler; - (*bindings_p)[i].keysym = combo->keysym; - (*bindings_p)[i].keycode = combo->keycode; - (*bindings_p)[i].modifiers = combo->modifiers; - (*bindings_p)[i].mask = 0; - - ++i; + b = g_slice_new0 (MetaKeyBinding); + b->name = pref->name; + b->handler = handler; + b->flags = handler->flags; + b->combo = *combo; - if (pref->add_shift && - (combo->modifiers & META_VIRTUAL_SHIFT_MASK) == 0) - { - meta_topic (META_DEBUG_KEYBINDINGS, - "Binding %s also needs Shift grabbed\n", - pref->name); - - (*bindings_p)[i].name = pref->name; - (*bindings_p)[i].handler = handler; - (*bindings_p)[i].keysym = combo->keysym; - (*bindings_p)[i].keycode = combo->keycode; - (*bindings_p)[i].modifiers = combo->modifiers | - META_VIRTUAL_SHIFT_MASK; - (*bindings_p)[i].mask = 0; - - ++i; - } + g_hash_table_add (keys->key_bindings, b); } tmp = tmp->next; @@ -464,94 +837,127 @@ rebuild_binding_table (MetaDisplay *display, p = p->next; } - g_assert (i == n_bindings); + g = grabs; + while (g) + { + MetaKeyGrab *grab = (MetaKeyGrab*)g->data; + if (grab->combo.keysym != None || grab->combo.keycode != 0) + { + MetaKeyHandler *handler = HANDLER ("external-grab"); + + b = g_slice_new0 (MetaKeyBinding); + b->name = grab->name; + b->handler = handler; + b->flags = grab->flags; + b->combo = grab->combo; - *n_bindings_p = i; + g_hash_table_add (keys->key_bindings, b); + } + + g = g->next; + } meta_topic (META_DEBUG_KEYBINDINGS, " %d bindings in table\n", - *n_bindings_p); + g_hash_table_size (keys->key_bindings)); } static void -rebuild_key_binding_table (MetaDisplay *display) +rebuild_key_binding_table (MetaKeyBindingManager *keys) { - GList *prefs; + GList *prefs, *grabs; meta_topic (META_DEBUG_KEYBINDINGS, "Rebuilding key binding table from preferences\n"); prefs = meta_prefs_get_keybindings (); - rebuild_binding_table (display, - &display->key_bindings, - &display->n_key_bindings, - prefs); + grabs = g_hash_table_get_values (external_grabs); + rebuild_binding_table (keys, prefs, grabs); g_list_free (prefs); + g_list_free (grabs); } static void -regrab_key_bindings (MetaDisplay *display) +rebuild_special_bindings (MetaKeyBindingManager *keys) { - GSList *tmp; - GSList *windows; + MetaKeyCombo combo; - meta_error_trap_push (display); /* for efficiency push outer trap */ + meta_prefs_get_overlay_binding (&combo); + keys->overlay_key_combo = combo; - tmp = display->screens; - while (tmp != NULL) - { - MetaScreen *screen = tmp->data; + meta_prefs_get_locate_pointer_binding (&combo); + keys->locate_pointer_key_combo = combo; +} - meta_screen_ungrab_keys (screen); - meta_screen_grab_keys (screen); +static void +ungrab_key_bindings (MetaDisplay *display) +{ + GSList *windows, *l; - tmp = tmp->next; - } + if (display->x11_display) + meta_x11_display_ungrab_keys (display->x11_display); windows = meta_display_list_windows (display, META_LIST_DEFAULT); - tmp = windows; - while (tmp != NULL) + for (l = windows; l; l = l->next) { - MetaWindow *w = tmp->data; - + MetaWindow *w = l->data; meta_window_ungrab_keys (w); - meta_window_grab_keys (w); + } + + g_slist_free (windows); +} - tmp = tmp->next; +static void +grab_key_bindings (MetaDisplay *display) +{ + GSList *windows, *l; + + if (display->x11_display) + meta_x11_display_grab_keys (display->x11_display); + + windows = meta_display_list_windows (display, META_LIST_DEFAULT); + for (l = windows; l; l = l->next) + { + MetaWindow *w = l->data; + meta_window_grab_keys (w); } - meta_error_trap_pop (display); g_slist_free (windows); } static MetaKeyBinding * -display_get_keybinding (MetaDisplay *display, - unsigned int keysym, - unsigned int keycode, - unsigned long mask) +get_keybinding (MetaKeyBindingManager *keys, + MetaResolvedKeyCombo *resolved_combo) { + MetaKeyBinding *binding = NULL; int i; - i = display->n_key_bindings - 1; - while (i >= 0) + for (i = 0; i < resolved_combo->len; i++) { - if (display->key_bindings[i].keysym == keysym && - display->key_bindings[i].keycode == keycode && - display->key_bindings[i].mask == mask) - { - return &display->key_bindings[i]; - } + guint32 key; - --i; + key = key_combo_key (resolved_combo, i); + binding = g_hash_table_lookup (keys->key_bindings_index, + GINT_TO_POINTER (key)); + + if (binding != NULL) + break; } - return NULL; + return binding; +} + +static guint +next_dynamic_keybinding_action (void) +{ + static guint num_dynamic_bindings = 0; + return META_KEYBINDING_ACTION_LAST + (++num_dynamic_bindings); } static gboolean add_keybinding_internal (MetaDisplay *display, const char *name, - const char *schema, + GSettings *settings, MetaKeyBindingFlags flags, MetaKeyBindingAction action, MetaKeyHandlerFunc func, @@ -561,7 +967,7 @@ add_keybinding_internal (MetaDisplay *display, { MetaKeyHandler *handler; - if (!meta_prefs_add_keybinding (name, schema, action, flags)) + if (!meta_prefs_add_keybinding (name, settings, action, flags)) return FALSE; handler = g_new0 (MetaKeyHandler, 1); @@ -570,7 +976,6 @@ add_keybinding_internal (MetaDisplay *display, handler->default_func = func; handler->data = data; handler->flags = flags; - handler->action = action; handler->user_data = user_data; handler->user_data_free_func = free_data; @@ -582,13 +987,13 @@ add_keybinding_internal (MetaDisplay *display, static gboolean add_builtin_keybinding (MetaDisplay *display, const char *name, - const char *schema, + GSettings *settings, MetaKeyBindingFlags flags, MetaKeyBindingAction action, MetaKeyHandlerFunc handler, int handler_arg) { - return add_keybinding_internal (display, name, schema, + return add_keybinding_internal (display, name, settings, flags | META_KEY_BINDING_BUILTIN, action, handler, handler_arg, NULL, NULL); } @@ -597,41 +1002,41 @@ add_builtin_keybinding (MetaDisplay *display, * meta_display_add_keybinding: * @display: a #MetaDisplay * @name: the binding's name - * @schema: the #GSettings schema where @name is stored + * @settings: the #GSettings object where @name is stored * @flags: flags to specify binding details * @handler: function to run when the keybinding is invoked * @user_data: the data to pass to @handler * @free_data: function to free @user_data * - * Add a keybinding at runtime. The key @name in @schema needs to be of type - * %G_VARIANT_TYPE_STRING_ARRAY, with each string describing a keybinding in - * the form of "<Control>a" or "<Shift><Alt>F1". The parser + * Add a keybinding at runtime. The key @name in @schema needs to be of + * type %G_VARIANT_TYPE_STRING_ARRAY, with each string describing a + * keybinding in the form of "<Control>a" or "<Shift><Alt>F1". The parser * is fairly liberal and allows lower or upper case, and also abbreviations - * such as "<Ctl>" and "<Ctrl>". If the key is set to the empty - * list or a list with a single element of either "" or "disabled", the - * keybinding is disabled. If %META_KEY_BINDING_REVERSES is specified in - * @flags, the binding may be reversed by holding down the "shift" key; - * therefore, "<Shift>" - * cannot be one of the keys used. @handler is expected to check for the - * "shift" modifier in this case and reverse its action. + * such as "<Ctl>" and "<Ctrl>". If the key is set to the empty list or a + * list with a single element of either "" or "disabled", the keybinding is + * disabled. * * Use meta_display_remove_keybinding() to remove the binding. * - * Returns: %TRUE if the keybinding was added successfully, - * otherwise %FALSE + * Returns: the corresponding keybinding action if the keybinding was + * added successfully, otherwise %META_KEYBINDING_ACTION_NONE */ -gboolean +guint meta_display_add_keybinding (MetaDisplay *display, const char *name, - const char *schema, + GSettings *settings, MetaKeyBindingFlags flags, MetaKeyHandlerFunc handler, gpointer user_data, GDestroyNotify free_data) { - return add_keybinding_internal (display, name, schema, flags, - META_KEYBINDING_ACTION_NONE, - handler, 0, user_data, free_data); + guint new_action = next_dynamic_keybinding_action (); + + if (!add_keybinding_internal (display, name, settings, flags, new_action, + handler, 0, user_data, free_data)) + return META_KEYBINDING_ACTION_NONE; + + return new_action; } /** @@ -657,89 +1062,32 @@ meta_display_remove_keybinding (MetaDisplay *display, return TRUE; } -static gboolean -add_custom_keybinding_internal (MetaDisplay *display, - const char *name, - const char **bindings, - MetaKeyBindingFlags flags, - MetaKeyBindingAction action, - MetaKeyHandlerFunc func, - int data, - gpointer user_data, - GDestroyNotify free_data) +static guint +get_keybinding_action (MetaKeyBindingManager *keys, + MetaResolvedKeyCombo *resolved_combo) { - MetaKeyHandler *handler; - - if (!meta_prefs_add_custom_keybinding (name, bindings, action, flags)) - return FALSE; - - handler = g_new0 (MetaKeyHandler, 1); - handler->name = g_strdup (name); - handler->func = func; - handler->default_func = func; - handler->data = data; - handler->flags = flags; - handler->action = action; - handler->user_data = user_data; - handler->user_data_free_func = free_data; - - g_hash_table_insert (key_handlers, g_strdup (name), handler); - - return TRUE; -} - - -/** - * meta_display_add_custom_keybinding: - * @display: a #MetaDisplay - * @name: the binding's unique name - * @bindings: (allow-none) (array zero-terminated=1): array of parseable keystrokes - * @callback: function to run when the keybinding is invoked - * @user_data: the data to pass to @handler - * @free_data: function to free @user_data - * - * - * Use meta_display_remove_custom_keybinding() to remove the binding. - * - * Returns: %TRUE if the keybinding was added successfully, - * otherwise %FALSE - */ -gboolean -meta_display_add_custom_keybinding (MetaDisplay *display, - const char *name, - const char **bindings, - MetaKeyHandlerFunc callback, - gpointer user_data, - GDestroyNotify free_data) + MetaKeyBinding *binding; -{ - return add_custom_keybinding_internal (display, name, bindings, - META_KEY_BINDING_PER_WINDOW, - META_KEYBINDING_ACTION_CUSTOM, - (MetaKeyHandlerFunc)callback, 0, user_data, free_data); + binding = get_keybinding (keys, resolved_combo); + if (binding) + { + MetaKeyGrab *grab = g_hash_table_lookup (external_grabs, binding->name); + if (grab) + return grab->action; + else + return (guint) meta_prefs_get_keybinding_action (binding->name); + } + else + { + return META_KEYBINDING_ACTION_NONE; + } } -/** - * meta_display_remove_custom_keybinding: - * @display: the #MetaDisplay - * @name: name of the keybinding to remove - * - * Remove keybinding @name; the function will fail if @name is not a known - * keybinding or has not been added with meta_display_add_custom_keybinding(). - * - * Returns: %TRUE if the binding has been removed sucessfully, - * otherwise %FALSE - */ -gboolean -meta_display_remove_custom_keybinding (MetaDisplay *display, - const char *name) +static xkb_mod_mask_t +mask_from_event_params (MetaKeyBindingManager *keys, + unsigned long mask) { - if (!meta_prefs_remove_custom_keybinding (name)) - return FALSE; - - g_hash_table_remove (key_handlers, name); - - return TRUE; + return mask & 0xff & ~keys->ignored_modifier_mask; } /** @@ -748,369 +1096,468 @@ meta_display_remove_custom_keybinding (MetaDisplay *display, * @keycode: Raw keycode * @mask: Event mask * - * Get the #MetaKeyBindingAction bound to %keycode. Only builtin - * keybindings have an associated #MetaKeyBindingAction, for - * bindings added dynamically with meta_display_add_keybinding() - * the function will always return %META_KEYBINDING_ACTION_NONE. + * Get the keybinding action bound to @keycode. Builtin keybindings + * have a fixed associated #MetaKeyBindingAction, for bindings added + * dynamically the function will return the keybinding action + * meta_display_add_keybinding() returns on registration. * * Returns: The action that should be taken for the given key, or * %META_KEYBINDING_ACTION_NONE. */ -MetaKeyBindingAction +guint meta_display_get_keybinding_action (MetaDisplay *display, unsigned int keycode, unsigned long mask) { - MetaKeyBinding *binding; - KeySym keysym; - - keysym = XkbKeycodeToKeysym (display->xdisplay, keycode, 0, 0); - mask = mask & 0xff & ~display->ignored_modifier_mask; - binding = display_get_keybinding (display, keysym, keycode, mask); - - if (!binding && keycode == meta_display_get_above_tab_keycode (display)) - binding = display_get_keybinding (display, META_KEY_ABOVE_TAB, keycode, mask); + MetaKeyBindingManager *keys = &display->key_binding_manager; + xkb_keycode_t code = (xkb_keycode_t) keycode; + MetaResolvedKeyCombo resolved_combo = { &code, 1 }; - if (binding) - return meta_prefs_get_keybinding_action (binding->name); - else - return META_KEYBINDING_ACTION_NONE; + resolved_combo.mask = mask_from_event_params (keys, mask); + return get_keybinding_action (keys, &resolved_combo); } -void -meta_display_keybinding_action_invoke_by_code (MetaDisplay *display, - unsigned int keycode, - unsigned long mask) +static void +reload_keybindings (MetaDisplay *display) { - MetaKeyBinding *binding; - KeySym keysym; + MetaKeyBindingManager *keys = &display->key_binding_manager; - keysym = XkbKeycodeToKeysym (display->xdisplay, keycode, 0, 0); - mask = mask & 0xff & ~display->ignored_modifier_mask; - binding = display_get_keybinding (display, keysym, keycode, mask); + ungrab_key_bindings (display); - if (!binding && keycode == meta_display_get_above_tab_keycode (display)) - binding = display_get_keybinding (display, META_KEY_ABOVE_TAB, keycode, mask); + /* Deciphering the modmap depends on the loaded keysyms to find out + * what modifiers is Super and so forth, so we need to reload it + * even when only the keymap changes */ + reload_modmap (keys); - if (binding) - invoke_handler_by_name (display, NULL, binding->name, NULL, NULL); + reload_combos (keys); + + grab_key_bindings (display); } -LOCAL_SYMBOL void -meta_display_process_mapping_event (MetaDisplay *display, - XEvent *event) +static GArray * +calc_grab_modifiers (MetaKeyBindingManager *keys, + unsigned int modmask) { - gboolean keymap_changed = FALSE; - gboolean modmap_changed = FALSE; + unsigned int ignored_mask; + XIGrabModifiers mods; + GArray *mods_array = g_array_new (FALSE, TRUE, sizeof (XIGrabModifiers)); -#ifdef HAVE_XKB - if (event->type == display->xkb_base_event_type) + /* The X server crashes if XIAnyModifier gets passed in with any + other bits. It doesn't make sense to ask for a grab of + XIAnyModifier plus other bits anyway so we avoid that. */ + if (modmask & XIAnyModifier) { - meta_topic (META_DEBUG_KEYBINDINGS, - "XKB mapping changed, will redo keybindings\n"); + mods = (XIGrabModifiers) { XIAnyModifier, 0 }; + g_array_append_val (mods_array, mods); + return mods_array; + } + + mods = (XIGrabModifiers) { modmask, 0 }; + g_array_append_val (mods_array, mods); - keymap_changed = TRUE; - modmap_changed = TRUE; + for (ignored_mask = 1; + ignored_mask <= keys->ignored_modifier_mask; + ++ignored_mask) + { + if (ignored_mask & keys->ignored_modifier_mask) + { + mods = (XIGrabModifiers) { modmask | ignored_mask, 0 }; + g_array_append_val (mods_array, mods); + } } + + return mods_array; +} + +static void +meta_change_button_grab (MetaKeyBindingManager *keys, + Window xwindow, + gboolean grab, + gboolean sync, + int button, + int modmask) +{ + if (meta_is_wayland_compositor ()) + return; + + MetaBackendX11 *backend = META_BACKEND_X11 (keys->backend); + Display *xdisplay = meta_backend_x11_get_xdisplay (backend); + + unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; + XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; + GArray *mods; + + XISetMask (mask.mask, XI_ButtonPress); + XISetMask (mask.mask, XI_ButtonRelease); + XISetMask (mask.mask, XI_Motion); + + mods = calc_grab_modifiers (keys, modmask); + + /* GrabModeSync means freeze until XAllowEvents */ + if (grab) + XIGrabButton (xdisplay, + META_VIRTUAL_CORE_POINTER_ID, + button, xwindow, None, + sync ? XIGrabModeSync : XIGrabModeAsync, + XIGrabModeAsync, False, + &mask, mods->len, (XIGrabModifiers *)mods->data); else -#endif - if (event->xmapping.request == MappingModifier) - { - meta_topic (META_DEBUG_KEYBINDINGS, - "Received MappingModifier event, will reload modmap and redo keybindings\n"); + XIUngrabButton (xdisplay, + META_VIRTUAL_CORE_POINTER_ID, + button, xwindow, mods->len, (XIGrabModifiers *)mods->data); - modmap_changed = TRUE; - } - else if (event->xmapping.request == MappingKeyboard) - { - meta_topic (META_DEBUG_KEYBINDINGS, - "Received MappingKeyboard event, will reload keycodes and redo keybindings\n"); + g_array_free (mods, TRUE); +} - keymap_changed = TRUE; - } +ClutterModifierType +meta_display_get_window_grab_modifiers (MetaDisplay *display) +{ + MetaKeyBindingManager *keys = &display->key_binding_manager; + return keys->window_grab_modifiers; +} - /* Now to do the work itself */ +static void +meta_change_buttons_grab (MetaKeyBindingManager *keys, + Window xwindow, + gboolean grab, + gboolean sync, + int modmask) +{ +#define MAX_BUTTON 3 - if (keymap_changed || modmap_changed) - { - if (keymap_changed) - reload_keymap (display); + int i; + for (i = 1; i <= MAX_BUTTON; i++) + meta_change_button_grab (keys, xwindow, grab, sync, i, modmask); +} - /* Deciphering the modmap depends on the loaded keysyms to find out - * what modifiers is Super and so forth, so we need to reload it - * even when only the keymap changes */ - reload_modmap (display); +void +meta_display_grab_window_buttons (MetaDisplay *display, + Window xwindow) +{ + MetaKeyBindingManager *keys = &display->key_binding_manager; - if (keymap_changed) - reload_keycodes (display); + /* Grab Alt + button1 for moving window. + * Grab Alt + button2 for resizing window. + * Grab Alt + button3 for popping up window menu. + * Grab Alt + Shift + button1 for snap-moving window. + */ + meta_verbose ("Grabbing window buttons for 0x%lx\n", xwindow); - reload_modifiers (display); + /* FIXME If we ignored errors here instead of spewing, we could + * put one big error trap around the loop and avoid a bunch of + * XSync() + */ - regrab_key_bindings (display); + if (keys->window_grab_modifiers != 0) + { + meta_change_buttons_grab (keys, xwindow, TRUE, FALSE, + keys->window_grab_modifiers); + + /* In addition to grabbing Alt+Button1 for moving the window, + * grab Alt+Shift+Button1 for snap-moving the window. See bug + * 112478. Unfortunately, this doesn't work with + * Shift+Alt+Button1 for some reason; so at least part of the + * order still matters, which sucks (please FIXME). + */ + meta_change_button_grab (keys, xwindow, + TRUE, + FALSE, + 1, keys->window_grab_modifiers | ShiftMask); } } -static gboolean -rebuild_keybindings_at_idle (MetaDisplay *display) +void +meta_display_ungrab_window_buttons (MetaDisplay *display, + Window xwindow) { - display->rebuild_keybinding_idle_id = 0; + MetaKeyBindingManager *keys = &display->key_binding_manager; - rebuild_key_binding_table (display); - reload_keycodes (display); - reload_modifiers (display); - regrab_key_bindings (display); + if (keys->window_grab_modifiers == 0) + return; - return FALSE; + meta_change_buttons_grab (keys, xwindow, FALSE, FALSE, + keys->window_grab_modifiers); } static void -queue_rebuild_keybindings (MetaDisplay *display) +update_window_grab_modifiers (MetaKeyBindingManager *keys) { - if (display->rebuild_keybinding_idle_id > 0) - { - g_source_remove (display->rebuild_keybinding_idle_id); - display->rebuild_keybinding_idle_id = 0; - } + MetaVirtualModifier virtual_mods; + unsigned int mods; + + virtual_mods = meta_prefs_get_mouse_button_mods (); + devirtualize_modifiers (keys, virtual_mods, &mods); - display->rebuild_keybinding_idle_id = g_idle_add_full (G_PRIORITY_LOW, - (GSourceFunc) rebuild_keybindings_at_idle, - display, NULL); + keys->window_grab_modifiers = mods; } -static void -bindings_changed_callback (MetaPreference pref, - void *data) +void +meta_display_grab_focus_window_button (MetaDisplay *display, + MetaWindow *window) +{ + MetaKeyBindingManager *keys = &display->key_binding_manager; + + /* Grab button 1 for activating unfocused windows */ + meta_verbose ("Grabbing unfocused window buttons for %s\n", window->desc); + + if (window->have_focus_click_grab) + { + meta_verbose (" (well, not grabbing since we already have the grab)\n"); + return; + } + + /* FIXME If we ignored errors here instead of spewing, we could + * put one big error trap around the loop and avoid a bunch of + * XSync() + */ + + meta_change_buttons_grab (keys, window->xwindow, TRUE, TRUE, XIAnyModifier); + window->have_focus_click_grab = TRUE; +} + +void +meta_display_ungrab_focus_window_button (MetaDisplay *display, + MetaWindow *window) { - MetaDisplay *display; + MetaKeyBindingManager *keys = &display->key_binding_manager; + + meta_verbose ("Ungrabbing unfocused window buttons for %s\n", window->desc); - display = data; + if (!window->have_focus_click_grab) + return; + + meta_change_buttons_grab (keys, window->xwindow, FALSE, FALSE, XIAnyModifier); + window->have_focus_click_grab = FALSE; +} + +static void +prefs_changed_callback (MetaPreference pref, + void *data) +{ + MetaDisplay *display = data; + MetaKeyBindingManager *keys = &display->key_binding_manager; switch (pref) { + case META_PREF_LOCATE_POINTER: + break; case META_PREF_KEYBINDINGS: - queue_rebuild_keybindings (display); + ungrab_key_bindings (display); + rebuild_key_binding_table (keys); + rebuild_special_bindings (keys); + reload_combos (keys); + grab_key_bindings (display); break; + case META_PREF_MOUSE_BUTTON_MODS: + { + GSList *windows, *l; + windows = meta_display_list_windows (display, META_LIST_DEFAULT); + + for (l = windows; l; l = l->next) + { + MetaWindow *w = l->data; + meta_display_ungrab_window_buttons (display, w->xwindow); + } + + update_window_grab_modifiers (keys); + + for (l = windows; l; l = l->next) + { + MetaWindow *w = l->data; + if (w->type != META_WINDOW_DOCK) + meta_display_grab_window_buttons (display, w->xwindow); + } + + g_slist_free (windows); + } default: break; } } -/** - * meta_display_rebuild_keybindings: - * @display: the #MetaDisplay - * - * Rebuild all keybindings (typically done after adding, removing, or changing - * one or more keybindings) - * - */ - -void -meta_display_rebuild_keybindings (MetaDisplay *display) -{ - queue_rebuild_keybindings (display); -} -LOCAL_SYMBOL void +void meta_display_shutdown_keys (MetaDisplay *display) { - /* Note that display->xdisplay is invalid in this function */ + MetaKeyBindingManager *keys = &display->key_binding_manager; - meta_prefs_remove_listener (bindings_changed_callback, display); + meta_prefs_remove_listener (prefs_changed_callback, display); - if (display->keymap) - meta_XFree (display->keymap); + g_hash_table_destroy (keys->key_bindings_index); + g_hash_table_destroy (keys->key_bindings); - if (display->modmap) - XFreeModifiermap (display->modmap); - free (display->key_bindings); + clear_active_keyboard_layouts (keys); } -static const char* -keysym_name (int keysym) +/* Grab/ungrab, ignoring all annoying modifiers like NumLock etc. */ +static void +meta_change_keygrab (MetaKeyBindingManager *keys, + Window xwindow, + gboolean grab, + MetaResolvedKeyCombo *resolved_combo) { - const char *name; + unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; + XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; - name = XKeysymToString (keysym); - if (name == NULL) - name = "(unknown)"; + XISetMask (mask.mask, XI_KeyPress); + XISetMask (mask.mask, XI_KeyRelease); - return name; -} + if (meta_is_wayland_compositor ()) + return; -/* Grab/ungrab, ignoring all annoying modifiers like NumLock etc. */ -static void -meta_change_keygrab (MetaDisplay *display, - Window xwindow, - gboolean grab, - int keysym, - unsigned int keycode, - int modmask) -{ - unsigned int ignored_mask; + MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ()); + Display *xdisplay = meta_backend_x11_get_xdisplay (backend); + GArray *mods; + int i; /* Grab keycode/modmask, together with * all combinations of ignored modifiers. * X provides no better way to do this. */ - meta_topic (META_DEBUG_KEYBINDINGS, - "%s keybinding %s keycode %d mask 0x%x on 0x%lx\n", - grab ? "Grabbing" : "Ungrabbing", - keysym_name (keysym), keycode, - modmask, xwindow); - - /* efficiency, avoid so many XSync() */ - meta_error_trap_push (display); + mods = calc_grab_modifiers (keys, resolved_combo->mask); - ignored_mask = 0; - while (ignored_mask <= display->ignored_modifier_mask) + for (i = 0; i < resolved_combo->len; i++) { - if (ignored_mask & ~(display->ignored_modifier_mask)) - { - /* Not a combination of ignored modifiers - * (it contains some non-ignored modifiers) - */ - ++ignored_mask; - continue; - } + xkb_keycode_t keycode = resolved_combo->keycodes[i]; + + meta_topic (META_DEBUG_KEYBINDINGS, + "%s keybinding keycode %d mask 0x%x on 0x%lx\n", + grab ? "Grabbing" : "Ungrabbing", + keycode, resolved_combo->mask, xwindow); - if (meta_is_debugging ()) - meta_error_trap_push_with_return (display); if (grab) - XGrabKey (display->xdisplay, keycode, - modmask | ignored_mask, - xwindow, - True, - GrabModeAsync, GrabModeSync); + XIGrabKeycode (xdisplay, + META_VIRTUAL_CORE_KEYBOARD_ID, + keycode, xwindow, + XIGrabModeSync, XIGrabModeAsync, + False, &mask, mods->len, (XIGrabModifiers *)mods->data); else - XUngrabKey (display->xdisplay, keycode, - modmask | ignored_mask, - xwindow); - - if (meta_is_debugging ()) - { - int result; - - result = meta_error_trap_pop_with_return (display); - - if (grab && result != Success) - { - if (result == BadAccess) - meta_warning ("Some other program is already using the key %s with modifiers %x as a binding\n", keysym_name (keysym), modmask | ignored_mask); -#ifdef WITH_VERBOSE_MODE - else - meta_topic (META_DEBUG_KEYBINDINGS, - "Failed to grab key %s with modifiers %x\n", - keysym_name (keysym), modmask | ignored_mask); -#endif - } - } - - ++ignored_mask; + XIUngrabKeycode (xdisplay, + META_VIRTUAL_CORE_KEYBOARD_ID, + keycode, xwindow, + mods->len, (XIGrabModifiers *)mods->data); } - meta_error_trap_pop (display); + g_array_free (mods, TRUE); } +typedef struct +{ + MetaKeyBindingManager *keys; + Window xwindow; + gboolean only_per_window; + gboolean grab; +} ChangeKeygrabData; + static void -meta_grab_key (MetaDisplay *display, - Window xwindow, - int keysym, - unsigned int keycode, - int modmask) +change_keygrab_foreach (gpointer key, + gpointer value, + gpointer user_data) { - meta_change_keygrab (display, xwindow, TRUE, keysym, keycode, modmask); + ChangeKeygrabData *data = user_data; + MetaKeyBinding *binding = value; + gboolean binding_is_per_window = (binding->flags & META_KEY_BINDING_PER_WINDOW) != 0; + + if (data->only_per_window != binding_is_per_window) + return; + + /* Ignore the key bindings marked as META_KEY_BINDING_NO_AUTO_GRAB, + * those are handled separately + */ + if (binding->flags & META_KEY_BINDING_NO_AUTO_GRAB) + return; + + if (binding->resolved_combo.len == 0) + return; + + meta_change_keygrab (data->keys, data->xwindow, data->grab, &binding->resolved_combo); } static void -grab_keys (MetaKeyBinding *bindings, - int n_bindings, - MetaDisplay *display, - Window xwindow, - gboolean binding_per_window) +change_binding_keygrabs (MetaKeyBindingManager *keys, + Window xwindow, + gboolean only_per_window, + gboolean grab) { - int i; + ChangeKeygrabData data; - g_assert (n_bindings == 0 || bindings != NULL); + data.keys = keys; + data.xwindow = xwindow; + data.only_per_window = only_per_window; + data.grab = grab; - meta_error_trap_push (display); + g_hash_table_foreach (keys->key_bindings, change_keygrab_foreach, &data); +} - i = 0; - while (i < n_bindings) - { - if (!!binding_per_window == - !!(bindings[i].handler->flags & META_KEY_BINDING_PER_WINDOW) && - bindings[i].keycode != 0) - { - meta_grab_key (display, xwindow, - bindings[i].keysym, - bindings[i].keycode, - bindings[i].mask); - } +static void +maybe_update_locate_pointer_keygrab (MetaDisplay *display, + gboolean grab) +{ + MetaKeyBindingManager *keys = &display->key_binding_manager; - ++i; - } + if (!display->x11_display) + return; - meta_error_trap_pop (display); + if (keys->locate_pointer_resolved_key_combo.len != 0) + meta_change_keygrab (keys, display->x11_display->xroot, + (!!grab & !!meta_prefs_is_locate_pointer_enabled()), + &keys->locate_pointer_resolved_key_combo); } static void -ungrab_all_keys (MetaDisplay *display, - Window xwindow) +meta_x11_display_change_keygrabs (MetaX11Display *x11_display, + gboolean grab) { - if (meta_is_debugging ()) - meta_error_trap_push_with_return (display); - else - meta_error_trap_push (display); - - XUngrabKey (display->xdisplay, AnyKey, AnyModifier, - xwindow); + MetaKeyBindingManager *keys = &x11_display->display->key_binding_manager; + int i; - if (meta_is_debugging ()) - { - int result; + for (i = 0; i < keys->n_iso_next_group_combos; i++) + meta_change_keygrab (keys, x11_display->xroot, + grab, &keys->iso_next_group_combo[i]); - result = meta_error_trap_pop_with_return (display); -#ifdef WITH_VERBOSE_MODE - if (result != Success) - meta_topic (META_DEBUG_KEYBINDINGS, - "Ungrabbing all keys on 0x%lx failed\n", xwindow); -#endif - } - else - meta_error_trap_pop (display); + change_binding_keygrabs (keys, x11_display->xroot, + FALSE, grab); } -LOCAL_SYMBOL void -meta_screen_grab_keys (MetaScreen *screen) +void +meta_x11_display_grab_keys (MetaX11Display *x11_display) { - if (screen->all_keys_grabbed) + if (x11_display->keys_grabbed) return; - if (screen->keys_grabbed) + meta_x11_display_change_keygrabs (x11_display, TRUE); + + x11_display->keys_grabbed = TRUE; +} + +void +meta_x11_display_ungrab_keys (MetaX11Display *x11_display) +{ + if (!x11_display->keys_grabbed) return; - grab_keys (screen->display->key_bindings, - screen->display->n_key_bindings, - screen->display, screen->xroot, - FALSE); + meta_x11_display_change_keygrabs (x11_display, FALSE); - screen->keys_grabbed = TRUE; + x11_display->keys_grabbed = FALSE; } -LOCAL_SYMBOL void -meta_screen_ungrab_keys (MetaScreen *screen) +static void +change_window_keygrabs (MetaKeyBindingManager *keys, + Window xwindow, + gboolean grab) { - if (screen->keys_grabbed) - { - ungrab_all_keys (screen->display, screen->xroot); - screen->keys_grabbed = FALSE; - } + change_binding_keygrabs (keys, xwindow, TRUE, grab); } -LOCAL_SYMBOL void +void meta_window_grab_keys (MetaWindow *window) { + MetaDisplay *display = window->display; + MetaKeyBindingManager *keys = &display->key_binding_manager; + + if (meta_is_wayland_compositor ()) + return; if (window->all_keys_grabbed) return; @@ -1118,7 +1565,7 @@ meta_window_grab_keys (MetaWindow *window) || window->override_redirect) { if (window->keys_grabbed) - ungrab_all_keys (window->display, window->xwindow); + change_window_keygrabs (keys, window->xwindow, FALSE); window->keys_grabbed = FALSE; return; } @@ -1126,7 +1573,7 @@ meta_window_grab_keys (MetaWindow *window) if (window->keys_grabbed) { if (window->frame && !window->grab_on_frame) - ungrab_all_keys (window->display, window->xwindow); + change_window_keygrabs (keys, window->xwindow, FALSE); else if (window->frame == NULL && window->grab_on_frame) ; /* continue to regrab on client window */ @@ -1134,157 +1581,209 @@ meta_window_grab_keys (MetaWindow *window) return; /* already all good */ } - grab_keys (window->display->key_bindings, - window->display->n_key_bindings, - window->display, - window->frame ? window->frame->xwindow : window->xwindow, - TRUE); + change_window_keygrabs (keys, + meta_window_x11_get_toplevel_xwindow (window), + TRUE); window->keys_grabbed = TRUE; window->grab_on_frame = window->frame != NULL; } -LOCAL_SYMBOL void +void meta_window_ungrab_keys (MetaWindow *window) { - if (window->keys_grabbed) + if (!meta_is_wayland_compositor () && window->keys_grabbed) { + MetaDisplay *display = window->display; + MetaKeyBindingManager *keys = &display->key_binding_manager; + if (window->grab_on_frame && window->frame != NULL) - ungrab_all_keys (window->display, - window->frame->xwindow); + change_window_keygrabs (keys, window->frame->xwindow, FALSE); else if (!window->grab_on_frame) - ungrab_all_keys (window->display, - window->xwindow); + change_window_keygrabs (keys, window->xwindow, FALSE); window->keys_grabbed = FALSE; } } -#ifdef WITH_VERBOSE_MODE -static const char* -grab_status_to_string (int status) +static void +handle_external_grab (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer user_data) { - switch (status) - { - case AlreadyGrabbed: - return "AlreadyGrabbed"; - case GrabSuccess: - return "GrabSuccess"; - case GrabNotViewable: - return "GrabNotViewable"; - case GrabFrozen: - return "GrabFrozen"; - case GrabInvalidTime: - return "GrabInvalidTime"; - default: - return "(unknown)"; - } + MetaKeyBindingManager *keys = &display->key_binding_manager; + guint action = get_keybinding_action (keys, &binding->resolved_combo); + meta_display_accelerator_activate (display, action, event); } -#endif /* WITH_VERBOSE_MODE */ -static gboolean -grab_keyboard (MetaDisplay *display, - Window xwindow, - guint32 timestamp) + +guint +meta_display_grab_accelerator (MetaDisplay *display, + const char *accelerator, + MetaKeyBindingFlags flags) { - int result; - int grab_status; + MetaKeyBindingManager *keys = &display->key_binding_manager; + MetaKeyBinding *binding; + MetaKeyGrab *grab; + MetaKeyCombo combo = { 0 }; + MetaResolvedKeyCombo resolved_combo = { NULL, 0 }; - /* Grab the keyboard, so we get key releases and all key - * presses - */ - meta_error_trap_push_with_return (display); + if (!meta_parse_accelerator (accelerator, &combo)) + { + meta_topic (META_DEBUG_KEYBINDINGS, + "Failed to parse accelerator\n"); + meta_warning ("\"%s\" is not a valid accelerator\n", accelerator); + + return META_KEYBINDING_ACTION_NONE; + } + + resolve_key_combo (keys, &combo, &resolved_combo); - grab_status = XGrabKeyboard (display->xdisplay, - xwindow, True, - GrabModeAsync, GrabModeAsync, - timestamp); + if (resolved_combo.len == 0) + return META_KEYBINDING_ACTION_NONE; - if (grab_status != GrabSuccess) + if (get_keybinding (keys, &resolved_combo)) { - meta_error_trap_pop_with_return (display); - meta_topic (META_DEBUG_KEYBINDINGS, - "XGrabKeyboard() returned failure status %s time %u\n", - grab_status_to_string (grab_status), - timestamp); - return FALSE; + resolved_key_combo_reset (&resolved_combo); + return META_KEYBINDING_ACTION_NONE; } - else + + if (!meta_is_wayland_compositor ()) { - result = meta_error_trap_pop_with_return (display); - if (result != Success) - { - meta_topic (META_DEBUG_KEYBINDINGS, - "XGrabKeyboard() resulted in an error\n"); - return FALSE; - } + meta_change_keygrab (keys, display->x11_display->xroot, + TRUE, &resolved_combo); } - meta_topic (META_DEBUG_KEYBINDINGS, "Grabbed all keys\n"); + grab = g_new0 (MetaKeyGrab, 1); + grab->action = next_dynamic_keybinding_action (); + grab->name = meta_external_binding_name_for_action (grab->action); + grab->combo = combo; + grab->flags = flags; - return TRUE; -} + g_hash_table_insert (external_grabs, grab->name, grab); -static void -ungrab_keyboard (MetaDisplay *display, guint32 timestamp) -{ - meta_error_trap_push (display); + binding = g_slice_new0 (MetaKeyBinding); + binding->name = grab->name; + binding->handler = HANDLER ("external-grab"); + binding->combo = combo; + binding->resolved_combo = resolved_combo; + binding->flags = flags; - meta_topic (META_DEBUG_KEYBINDINGS, - "Ungrabbing keyboard with timestamp %u\n", - timestamp); - XUngrabKeyboard (display->xdisplay, timestamp); - meta_error_trap_pop (display); + g_hash_table_add (keys->key_bindings, binding); + index_binding (keys, binding); + + return grab->action; } gboolean -meta_screen_grab_all_keys (MetaScreen *screen, guint32 timestamp) +meta_display_ungrab_accelerator (MetaDisplay *display, + guint action) { - gboolean retval; + MetaKeyBindingManager *keys = &display->key_binding_manager; + MetaKeyBinding *binding; + MetaKeyGrab *grab; + g_autofree char *key = NULL; + MetaResolvedKeyCombo resolved_combo = { NULL, 0 }; - if (screen->all_keys_grabbed) - return FALSE; + g_return_val_if_fail (action != META_KEYBINDING_ACTION_NONE, FALSE); - if (screen->keys_grabbed) - meta_screen_ungrab_keys (screen); + key = meta_external_binding_name_for_action (action); + grab = g_hash_table_lookup (external_grabs, key); + if (!grab) + return FALSE; - meta_topic (META_DEBUG_KEYBINDINGS, - "Grabbing all keys on RootWindow\n"); - retval = grab_keyboard (screen->display, screen->xroot, timestamp); - if (retval) + resolve_key_combo (keys, &grab->combo, &resolved_combo); + binding = get_keybinding (keys, &resolved_combo); + if (binding) { - screen->all_keys_grabbed = TRUE; - g_object_notify (G_OBJECT (screen), "keyboard-grabbed"); + int i; + + if (!meta_is_wayland_compositor ()) + { + meta_change_keygrab (keys, display->x11_display->xroot, + FALSE, &binding->resolved_combo); + } + + for (i = 0; i < binding->resolved_combo.len; i++) + { + guint32 index_key = key_combo_key (&binding->resolved_combo, i); + g_hash_table_remove (keys->key_bindings_index, GINT_TO_POINTER (index_key)); + } + + g_hash_table_remove (keys->key_bindings, binding); } - else - meta_screen_grab_keys (screen); - return retval; + g_hash_table_remove (external_grabs, key); + resolved_key_combo_reset (&resolved_combo); + + return TRUE; } -void -meta_screen_ungrab_all_keys (MetaScreen *screen, guint32 timestamp) +static gboolean +grab_keyboard (Window xwindow, + guint32 timestamp, + int grab_mode) { - if (screen->all_keys_grabbed) - { - ungrab_keyboard (screen->display, timestamp); + int grab_status; - screen->all_keys_grabbed = FALSE; - screen->keys_grabbed = FALSE; + unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; + XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; - /* Re-establish our standard bindings */ - meta_screen_grab_keys (screen); - g_object_notify (G_OBJECT (screen), "keyboard-grabbed"); - } + XISetMask (mask.mask, XI_KeyPress); + XISetMask (mask.mask, XI_KeyRelease); + + if (meta_is_wayland_compositor ()) + return TRUE; + + /* Grab the keyboard, so we get key releases and all key + * presses + */ + + MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ()); + Display *xdisplay = meta_backend_x11_get_xdisplay (backend); + + /* Strictly, we only need to set grab_mode on the keyboard device + * while the pointer should always be XIGrabModeAsync. Unfortunately + * there is a bug in the X server, only fixed (link below) in 1.15, + * which swaps these arguments for keyboard devices. As such, we set + * both the device and the paired device mode which works around + * that bug and also works on fixed X servers. + * + * http://cgit.freedesktop.org/xorg/xserver/commit/?id=9003399708936481083424b4ff8f18a16b88b7b3 + */ + grab_status = XIGrabDevice (xdisplay, + META_VIRTUAL_CORE_KEYBOARD_ID, + xwindow, + timestamp, + None, + grab_mode, grab_mode, + False, /* owner_events */ + &mask); + + return (grab_status == Success); +} + +static void +ungrab_keyboard (guint32 timestamp) +{ + if (meta_is_wayland_compositor ()) + return; + + MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ()); + Display *xdisplay = meta_backend_x11_get_xdisplay (backend); + + XIUngrabDevice (xdisplay, META_VIRTUAL_CORE_KEYBOARD_ID, timestamp); } -LOCAL_SYMBOL gboolean +gboolean meta_window_grab_all_keys (MetaWindow *window, guint32 timestamp) { Window grabwindow; - gboolean retval; + gboolean retval = TRUE; if (window->all_keys_grabbed) return FALSE; @@ -1300,11 +1799,14 @@ meta_window_grab_all_keys (MetaWindow *window, window->desc); meta_window_focus (window, timestamp); - grabwindow = window->frame ? window->frame->xwindow : window->xwindow; + if (!meta_is_wayland_compositor ()) + { + grabwindow = meta_window_x11_get_toplevel_xwindow (window); - meta_topic (META_DEBUG_KEYBINDINGS, - "Grabbing all keys on window %s\n", window->desc); - retval = grab_keyboard (window->display, grabwindow, timestamp); + meta_topic (META_DEBUG_KEYBINDINGS, + "Grabbing all keys on window %s\n", window->desc); + retval = grab_keyboard (grabwindow, timestamp, XIGrabModeAsync); + } if (retval) { window->keys_grabbed = FALSE; @@ -1315,12 +1817,14 @@ meta_window_grab_all_keys (MetaWindow *window, return retval; } -LOCAL_SYMBOL void -meta_window_ungrab_all_keys (MetaWindow *window, guint32 timestamp) +void +meta_window_ungrab_all_keys (MetaWindow *window, + guint32 timestamp) { if (window->all_keys_grabbed) { - ungrab_keyboard (window->display, timestamp); + if (!meta_is_wayland_compositor()) + ungrab_keyboard (timestamp); window->grab_on_frame = FALSE; window->all_keys_grabbed = FALSE; @@ -1331,312 +1835,291 @@ meta_window_ungrab_all_keys (MetaWindow *window, guint32 timestamp) } } -LOCAL_SYMBOL gboolean -meta_window_resize_or_move_allowed (MetaWindow *window, - MetaDirection dir) +void +meta_display_freeze_keyboard (MetaDisplay *display, guint32 timestamp) { - if (!META_WINDOW_MAXIMIZED (window) && !META_WINDOW_TILED_OR_SNAPPED (window)) - return TRUE; + MetaBackend *backend = meta_get_backend (); - switch (dir) - { - case META_DIRECTION_LEFT: - if (window->tile_mode == META_TILE_RIGHT || - window->tile_mode == META_TILE_URC || - window->tile_mode == META_TILE_LRC) - return TRUE; - break; - case META_DIRECTION_RIGHT: - if (window->tile_mode == META_TILE_LEFT || - window->tile_mode == META_TILE_ULC || - window->tile_mode == META_TILE_LLC) - return TRUE; - break; - case META_DIRECTION_UP: - if (window->tile_mode == META_TILE_BOTTOM || - window->tile_mode == META_TILE_LLC || - window->tile_mode == META_TILE_LRC) - return TRUE; - break; - case META_DIRECTION_DOWN: - if (window->tile_mode == META_TILE_TOP || - window->tile_mode == META_TILE_ULC || - window->tile_mode == META_TILE_URC) - return TRUE; - break; - default: - return FALSE; - } + if (!META_IS_BACKEND_X11 (backend)) + return; - return FALSE; + Window window = meta_backend_x11_get_xwindow (META_BACKEND_X11 (backend)); + grab_keyboard (window, timestamp, XIGrabModeSync); } +void +meta_display_ungrab_keyboard (MetaDisplay *display, guint32 timestamp) +{ + ungrab_keyboard (timestamp); +} -static gboolean -is_modifier (MetaDisplay *display, - unsigned int keycode) +void +meta_display_unfreeze_keyboard (MetaDisplay *display, guint32 timestamp) { - int i; - int map_size; - gboolean retval = FALSE; + MetaBackend *backend = meta_get_backend (); - g_assert (display->modmap); + if (!META_IS_BACKEND_X11 (backend)) + return; - map_size = 8 * display->modmap->max_keypermod; - i = 0; - while (i < map_size) - { - if (keycode == display->modmap->modifiermap[i]) - { - retval = TRUE; - break; - } - ++i; - } + Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); - return retval; + XIAllowEvents (xdisplay, META_VIRTUAL_CORE_KEYBOARD_ID, + XIAsyncDevice, timestamp); + /* We shouldn't need to unfreeze the pointer device here, however we + * have to, due to the workaround we do in grab_keyboard(). + */ + XIAllowEvents (xdisplay, META_VIRTUAL_CORE_POINTER_ID, + XIAsyncDevice, timestamp); } -/* Indexes: - * shift = 0 - * lock = 1 - * control = 2 - * mod1 = 3 - * mod2 = 4 - * mod3 = 5 - * mod4 = 6 - * mod5 = 7 - */ +static gboolean +is_modifier (xkb_keysym_t keysym) +{ + switch (keysym) + { + case XKB_KEY_Shift_L: + case XKB_KEY_Shift_R: + case XKB_KEY_Control_L: + case XKB_KEY_Control_R: + case XKB_KEY_Caps_Lock: + case XKB_KEY_Shift_Lock: + case XKB_KEY_Meta_L: + case XKB_KEY_Meta_R: + case XKB_KEY_Alt_L: + case XKB_KEY_Alt_R: + case XKB_KEY_Super_L: + case XKB_KEY_Super_R: + case XKB_KEY_Hyper_L: + case XKB_KEY_Hyper_R: + return TRUE; + default: + return FALSE; + } +} static void -invoke_handler (MetaDisplay *display, - MetaScreen *screen, - MetaKeyHandler *handler, - MetaWindow *window, - XEvent *event, - MetaKeyBinding *binding) - +invoke_handler (MetaDisplay *display, + MetaKeyHandler *handler, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding) { if (handler->func) - (* handler->func) (display, screen, + (* handler->func) (display, handler->flags & META_KEY_BINDING_PER_WINDOW ? - window : NULL, + window : NULL, event, binding, handler->user_data); else - (* handler->default_func) (display, screen, + (* handler->default_func) (display, handler->flags & META_KEY_BINDING_PER_WINDOW ? - window: NULL, + window: NULL, event, binding, NULL); } -static void -invoke_handler_by_name (MetaDisplay *display, - MetaScreen *screen, - const char *handler_name, - MetaWindow *window, - XEvent *event) -{ - MetaKeyHandler *handler; - - handler = HANDLER (handler_name); - if (handler) - invoke_handler (display, screen, handler, window, event, NULL); -} - - static gboolean -modifier_only_keysym (KeySym keysym) +meta_key_binding_has_handler_func (MetaKeyBinding *binding) { - return keysym == XK_Super_L || - keysym == XK_Super_R || - keysym == XK_Control_L || - keysym == XK_Control_R || - keysym == XK_Alt_L || - keysym == XK_Alt_R || - keysym == XK_Shift_L || - keysym == XK_Shift_R; + return (!!binding->handler->func || !!binding->handler->default_func); } static void -strip_self_mod (KeySym keysym, unsigned long *mask) +strip_self_mod (guint keyval, + ClutterModifierType event_state, + ClutterModifierType *stripped_mod) { unsigned long mod = 0; - switch (keysym) + switch (keyval) { - case XK_Super_L: - case XK_Super_R: - mod = GDK_MOD4_MASK; + case CLUTTER_KEY_Super_L: + case CLUTTER_KEY_Super_R: + mod = CLUTTER_MOD4_MASK; break; - case XK_Control_L: - case XK_Control_R: - mod = GDK_CONTROL_MASK; + case CLUTTER_KEY_Control_L: + case CLUTTER_KEY_Control_R: + mod = CLUTTER_CONTROL_MASK; break; - case XK_Alt_L: - case XK_Alt_R: - mod = GDK_MOD1_MASK; + case CLUTTER_KEY_Alt_L: + case CLUTTER_KEY_Alt_R: + mod = CLUTTER_MOD1_MASK; break; - case XK_Shift_L: - case XK_Shift_R: - mod = GDK_SHIFT_MASK; + case CLUTTER_KEY_Shift_L: + case CLUTTER_KEY_Shift_R: + mod = CLUTTER_SHIFT_MASK; break; default: mod = 0; break; } - *mask = *mask & ~mod; -} - -static gboolean -is_modifier_only_kb (MetaDisplay *display, XEvent *event, KeySym keysym) -{ - unsigned long mask; - - mask = (event->xkey.state & 0xff & ~(display->ignored_modifier_mask)); - strip_self_mod (keysym, &mask); - - return mask == 0 && modifier_only_keysym (keysym); + *stripped_mod = event_state & ~mod; } -/* now called from only one place, may be worth merging */ static gboolean -process_event (MetaKeyBinding *bindings, - int n_bindings, - MetaDisplay *display, - MetaScreen *screen, +process_event (MetaDisplay *display, MetaWindow *window, - XEvent *event, - KeySym keysym, - gboolean on_window, - gboolean allow_release, - gboolean mouse_grab_move) + ClutterKeyEvent *event, + gboolean allow_release) { - int i; - unsigned long mask; + MetaKeyBindingManager *keys = &display->key_binding_manager; + xkb_keycode_t keycode = (xkb_keycode_t) event->hardware_keycode; + MetaResolvedKeyCombo resolved_combo = { &keycode, 1 }; + MetaKeyBinding *binding; /* we used to have release-based bindings but no longer. */ - if (event->type == KeyRelease && !allow_release) + if (event->type == CLUTTER_KEY_RELEASE && !allow_release) return FALSE; - mask = event->xkey.state & 0xff & ~(display->ignored_modifier_mask); + resolved_combo.mask = mask_from_event_params (keys, event->modifier_state); - if (allow_release) - { - strip_self_mod (keysym, &mask); - } - - /* - * TODO: This would be better done with a hash table; - * it doesn't suit to use O(n) for such a common operation. - */ - for (i=0; i<n_bindings; i++) - { - MetaKeyHandler *handler = bindings[i].handler; + strip_self_mod (event->keyval, + mask_from_event_params (keys, event->modifier_state), + &resolved_combo.mask); - /* Custom keybindings are from Cinnamon, and never need a window */ - if (!on_window && handler->flags & META_KEY_BINDING_PER_WINDOW && handler->action < META_KEYBINDING_ACTION_CUSTOM) - continue; + binding = get_keybinding (keys, &resolved_combo); - /* We allow workspace navigation in a grab state. Ordinarily we'd not make it this far, and we need to make sure - * to stop processing in this case so we return TRUE (event handled) regardless of whether we found a matching - * binding, to prevent further processing by cinnamon */ - if (mouse_grab_move && - (handler->action < META_KEYBINDING_ACTION_WORKSPACE_1 || handler->action > META_KEYBINDING_ACTION_WORKSPACE_RIGHT)) - continue; + if (!binding || + (!window && binding->flags & META_KEY_BINDING_PER_WINDOW)) + goto not_found; - if ((event->type != KeyPress && !allow_release) || - bindings[i].keycode != event->xkey.keycode || - mask != bindings[i].mask) - continue; + if (binding->handler == NULL) + meta_bug ("Binding %s has no handler\n", binding->name); - /* - * window must be non-NULL for on_window to be true, - * and so also window must be non-NULL if we get here and - * this is a META_KEY_BINDING_PER_WINDOW binding. - */ + if (!meta_key_binding_has_handler_func (binding)) + goto not_found; - meta_topic (META_DEBUG_KEYBINDINGS, - "Binding keycode 0x%x mask 0x%x matches event 0x%x state 0x%x\n", - bindings[i].keycode, bindings[i].mask, - event->xkey.keycode, event->xkey.state); + if (display->focus_window && + !(binding->handler->flags & META_KEY_BINDING_NON_MASKABLE)) + { + ClutterInputDevice *source; - if (handler == NULL) - meta_bug ("Binding %s has no handler\n", bindings[i].name); -#ifdef WITH_VERBOSE_MODE - else - meta_topic (META_DEBUG_KEYBINDINGS, - "Running handler for %s\n", - bindings[i].name); -#endif - /* Global keybindings count as a let-the-terminal-lose-focus - * due to new window mapping until the user starts - * interacting with the terminal again. - */ - display->allow_terminal_deactivation = TRUE; + source = clutter_event_get_source_device ((ClutterEvent *) event); + if (meta_window_shortcuts_inhibited (display->focus_window, source)) + goto not_found; + } - invoke_handler (display, screen, handler, window, event, &bindings[i]); + /* If the compositor filtered out the keybindings, that + * means they don't want the binding to trigger, so we do + * the same thing as if the binding didn't exist. */ + if (meta_compositor_filter_keybinding (display->compositor, binding)) + goto not_found; + if (event->flags & CLUTTER_EVENT_FLAG_REPEATED && + binding->flags & META_KEY_BINDING_IGNORE_AUTOREPEAT) + { + meta_topic (META_DEBUG_KEYBINDINGS, + "Ignore autorepeat for handler %s\n", + binding->name); return TRUE; } + meta_topic (META_DEBUG_KEYBINDINGS, + "Running handler for %s\n", + binding->name); + + /* Global keybindings count as a let-the-terminal-lose-focus + * due to new window mapping until the user starts + * interacting with the terminal again. + */ + display->allow_terminal_deactivation = TRUE; + + invoke_handler (display, binding->handler, window, event, binding); + + return TRUE; + + not_found: meta_topic (META_DEBUG_KEYBINDINGS, "No handler found for this event in this binding table\n"); + return FALSE; +} + +static gboolean +modifier_only_keyval (guint keyval) +{ + return keyval == CLUTTER_KEY_Super_L || + keyval == CLUTTER_KEY_Super_R || + keyval == CLUTTER_KEY_Control_L || + keyval == CLUTTER_KEY_Control_R || + keyval == CLUTTER_KEY_Alt_L || + keyval == CLUTTER_KEY_Alt_R || + keyval == CLUTTER_KEY_Shift_L || + keyval == CLUTTER_KEY_Shift_R; +} + +static void +get_combo (MetaKeyBindingManager *keys, + unsigned int code, + unsigned long mask, + MetaResolvedKeyCombo *combo) +{ + xkb_keycode_t keycode = (xkb_keycode_t) code; + MetaResolvedKeyCombo resolved_combo = { &keycode, 1 }; - /* If we're in the middle of a mouse grab move, we always return TRUE here, to - * prevent further processing no matter what */ - return mouse_grab_move; + resolved_combo.mask = mask_from_event_params (keys, mask); + *combo = resolved_combo; } static gboolean -process_modifier_key (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XEvent *event, - KeySym keysym, - gboolean have_window, - gboolean *allow_key_up) +process_special_modifier_key (MetaDisplay *display, + ClutterKeyEvent *event, + MetaWindow *window, + gboolean *allow_key_up, + GFunc trigger_callback) { + MetaKeyBindingManager *keys = &display->key_binding_manager; + MetaBackend *backend = keys->backend; + Display *xdisplay; + + if (META_IS_BACKEND_X11 (backend)) + xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); + else + xdisplay = NULL; - if (event->xkey.type == KeyPress) + if (event->type == CLUTTER_KEY_PRESS) { /* check if we're just Pressing a captured modifier at this time */ - if (is_modifier_only_kb (display, event, keysym)) + if (modifier_only_keyval (event->keyval)) { /* remember this state, because we'll need to know it for subsequent events */ - modifier_only_is_down = TRUE; + modifier_key_only_pressed = TRUE; /* We keep the keyboard frozen - this allows us to use ReplayKeyboard * on the next event if it's not the release of this modifier key */ - XAllowEvents (display->xdisplay, SyncKeyboard, event->xkey.time); + if (xdisplay) + XIAllowEvents (xdisplay, + clutter_input_device_get_device_id (event->device), + XISyncDevice, event->time); + return TRUE; } else { - /* If it's a press, with a mod+key combination, we try our own keybindings - * first, then pass it to the current window if we don't have anything for it. - * Also, negate modifier_only_is_down. At this point we won't want a modifier - * release to trigger a binding, since when it happens now, it will only be the - * user releasing the keys after a combination binding has been used - */ - modifier_only_is_down = FALSE; - /* Try our keybindings */ - if (process_event (display->key_bindings, - display->n_key_bindings, - display, screen, window, event, keysym, - have_window, FALSE, FALSE)) + modifier_key_only_pressed = FALSE; + + if (process_event (display, window, event, FALSE)) { - /* we had a binding, we're done */ - XAllowEvents (display->xdisplay, AsyncKeyboard, event->xkey.time); + /* As normally, after we've handled a global key + * binding, we unfreeze the keyboard but keep the grab + * (this is important for something like cycling + * windows */ + + if (xdisplay) + XIAllowEvents (xdisplay, + clutter_input_device_get_device_id (event->device), + XIAsyncDevice, event->time); return TRUE; } else { - /* if we have nothing, let focused window handle it */ - XAllowEvents (display->xdisplay, ReplayKeyboard, event->xkey.time); + /* Replay the event so it gets delivered to our + * per-window key bindings or to the application */ + if (xdisplay) + XIAllowEvents (xdisplay, + clutter_input_device_get_device_id (event->device), + XIReplayDevice, event->time); return FALSE; } } @@ -1648,242 +2131,217 @@ process_modifier_key (MetaDisplay *display, * negate modifier_only_is_down, and allow the binding handler to accept * a key release. */ - if (is_modifier_only_kb (display, event, keysym)) + if (modifier_only_keyval (event->keyval)) { - if (modifier_only_is_down) + if (modifier_key_only_pressed) *allow_key_up = TRUE; - modifier_only_is_down = FALSE; + modifier_key_only_pressed = FALSE; } } return FALSE; } -/* Handle a key event. May be called recursively: some key events cause - * grabs to be ended and then need to be processed again in their own - * right. This cannot cause infinite recursion because we never call - * ourselves when there wasn't a grab, and we always clear the grab - * first; the invariant is enforced using an assertion. See #112560. - * - * The return value is whether we handled the key event. - * - * FIXME: We need to prove there are no race conditions here. - * FIXME: Does it correctly handle alt-Tab being followed by another - * grabbing keypress without letting go of alt? - * FIXME: An iterative solution would probably be simpler to understand - * (and help us solve the other fixmes). - */ -LOCAL_SYMBOL gboolean -meta_display_process_key_event (MetaDisplay *display, - MetaWindow *window, - XEvent *event) + +static gboolean +process_modifier_only (MetaDisplay *display, + ClutterKeyEvent *event, + MetaWindow *window, + gboolean *allow_key_up) { - KeySym keysym; - gboolean keep_grab; - gboolean all_keys_grabbed; - gboolean handled; - gboolean allow_key_up = FALSE; - gboolean mouse_grab_move; - const char *str; - MetaScreen *screen; - - if (all_bindings_disabled) - { - /* In this mode, we try to pretend we don't have grabs, so we - * immediately replay events and drop the grab. (This still - * messes up global passive grabs from other clients.) The - * FALSE return here is a little suspect, but we don't really - * know if we'll see the event again or not, and it's pretty - * poorly defined how this mode is supposed to interact with - * plugins. - */ - XAllowEvents (display->xdisplay, ReplayKeyboard, event->xkey.time); - return FALSE; + MetaKeyBindingManager *keys = &display->key_binding_manager; + + if (display->focus_window && !modifier_key_only_pressed) + { + ClutterInputDevice *source; + + source = clutter_event_get_source_device ((ClutterEvent *) event); + if (meta_window_shortcuts_inhibited (display->focus_window, source)) + return FALSE; } - /* if key event was on root window, we have a shortcut */ - screen = meta_display_screen_for_root (display, event->xkey.window); + return process_special_modifier_key (display, + event, + window, + allow_key_up, + (GFunc) meta_display_overlay_key_activate); +} - /* else round-trip to server */ - if (screen == NULL) - screen = meta_display_screen_for_xwindow (display, - event->xany.window); +static void +handle_locate_pointer (MetaDisplay *display) +{ + meta_compositor_locate_pointer (display->compositor); +} - if (screen == NULL) - return FALSE; /* event window is destroyed */ +static gboolean +process_iso_next_group (MetaDisplay *display, + ClutterKeyEvent *event) +{ + MetaKeyBindingManager *keys = &display->key_binding_manager; + gboolean activate; + xkb_keycode_t keycode = (xkb_keycode_t) event->hardware_keycode; + xkb_mod_mask_t mask; + int i, j; - /* ignore key events on popup menus and such. */ - if (meta_ui_window_is_widget (screen->ui, event->xany.window)) + if (event->type == CLUTTER_KEY_RELEASE) return FALSE; - /* window may be NULL */ + activate = FALSE; + mask = mask_from_event_params (keys, event->modifier_state); - keysym = XkbKeycodeToKeysym (display->xdisplay, event->xkey.keycode, 0, 0); - - str = XKeysymToString (keysym); + for (i = 0; i < keys->n_iso_next_group_combos; ++i) + { + for (j = 0; j < keys->iso_next_group_combo[i].len; ++j) + { + if (keycode == keys->iso_next_group_combo[i].keycodes[j] && + mask == keys->iso_next_group_combo[i].mask) + { + /* If the signal handler returns TRUE the keyboard will + remain frozen. It's the signal handler's responsibility + to unfreeze it. */ + if (!meta_display_modifiers_accelerator_activate (display)) + meta_display_unfreeze_keyboard (display, event->time); + activate = TRUE; + break; + } + } + } - /* was topic */ - meta_topic (META_DEBUG_KEYBINDINGS, - "Processing key %s event, keysym: %s state: 0x%x window: %s\n", - event->type == KeyPress ? "press" : "release", - str ? str : "none", event->xkey.state, - window ? window->desc : "(no window)"); + return activate; +} - all_keys_grabbed = window ? window->all_keys_grabbed : screen->all_keys_grabbed; +static gboolean +process_key_event (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event) +{ + gboolean keep_grab; + gboolean all_keys_grabbed; + gboolean allow_key_up = FALSE; + all_keys_grabbed = window ? window->all_keys_grabbed : FALSE; if (!all_keys_grabbed) { - handled = process_modifier_key (display, screen, window, event, keysym, (!all_keys_grabbed && window), &allow_key_up); - if (handled) + if (process_modifier_only (display, event, window, &allow_key_up)) + return TRUE; + + if (process_iso_next_group (display, event)) return TRUE; } - XAllowEvents (display->xdisplay, AsyncKeyboard, event->xkey.time); + { + MetaBackend *backend = meta_get_backend (); + if (META_IS_BACKEND_X11 (backend)) + { + Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); + XIAllowEvents (xdisplay, + clutter_input_device_get_device_id (event->device), + XIAsyncDevice, event->time); + } + } - mouse_grab_move = FALSE; keep_grab = TRUE; if (all_keys_grabbed) { if (display->grab_op == META_GRAB_OP_NONE) return TRUE; + /* If we get here we have a global grab, because - * we're in some special keyboard mode such as window move - * mode. - */ - if (window ? (window == display->grab_window) : - (screen == display->grab_screen)) + * we're in some special keyboard mode such as window move + * mode. + */ + if (window == display->grab_window) { - switch (display->grab_op) + if (display->grab_op & META_GRAB_OP_WINDOW_FLAG_KEYBOARD) + { + if (display->grab_op == META_GRAB_OP_KEYBOARD_MOVING) + { + meta_topic (META_DEBUG_KEYBINDINGS, + "Processing event for keyboard move\n"); + keep_grab = process_keyboard_move_grab (display, window, event); + } + else + { + meta_topic (META_DEBUG_KEYBINDINGS, + "Processing event for keyboard resize\n"); + keep_grab = process_keyboard_resize_grab (display, window, event); + } + } + else { - case META_GRAB_OP_MOVING: - mouse_grab_move = TRUE; - /* Fall through - this is just a flag for if we make it to process_event */ - case META_GRAB_OP_RESIZING_SE: - case META_GRAB_OP_RESIZING_S: - case META_GRAB_OP_RESIZING_SW: - case META_GRAB_OP_RESIZING_N: - case META_GRAB_OP_RESIZING_NE: - case META_GRAB_OP_RESIZING_NW: - case META_GRAB_OP_RESIZING_W: - case META_GRAB_OP_RESIZING_E: meta_topic (META_DEBUG_KEYBINDINGS, "Processing event for mouse-only move/resize\n"); - g_assert (window != NULL); - keep_grab = process_mouse_move_resize_grab (display, screen, - window, event, keysym); - break; - - case META_GRAB_OP_KEYBOARD_MOVING: - meta_topic (META_DEBUG_KEYBINDINGS, - "Processing event for keyboard move\n"); - g_assert (window != NULL); - keep_grab = process_keyboard_move_grab (display, screen, - window, event, keysym); - break; - - case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN: - case META_GRAB_OP_KEYBOARD_RESIZING_S: - case META_GRAB_OP_KEYBOARD_RESIZING_N: - case META_GRAB_OP_KEYBOARD_RESIZING_W: - case META_GRAB_OP_KEYBOARD_RESIZING_E: - case META_GRAB_OP_KEYBOARD_RESIZING_SE: - case META_GRAB_OP_KEYBOARD_RESIZING_NE: - case META_GRAB_OP_KEYBOARD_RESIZING_SW: - case META_GRAB_OP_KEYBOARD_RESIZING_NW: - meta_topic (META_DEBUG_KEYBINDINGS, - "Processing event for keyboard resize\n"); - g_assert (window != NULL); - keep_grab = process_keyboard_resize_grab (display, screen, - window, event, keysym); - break; - - default: - break; + keep_grab = process_mouse_move_resize_grab (display, window, event); } } if (!keep_grab) - { - meta_topic (META_DEBUG_KEYBINDINGS, - "Ending grab op %u on key event sym %s\n", - display->grab_op, XKeysymToString (keysym)); - meta_display_end_grab_op (display, event->xkey.time); - } - - /* If this isn't specifically a mouse-based window move, we don't process keybindings - * in the middle of a grab, so we end early and prevent further processing, otherwise - * we let process_event() handle this. */ + meta_display_end_grab_op (display, event->time); - if (!mouse_grab_move) - { - return TRUE; - } + return TRUE; } /* Do the normal keybindings */ - return process_event (display->key_bindings, - display->n_key_bindings, - display, screen, window, event, keysym, - !all_keys_grabbed && window, allow_key_up, - mouse_grab_move); + return process_event (display, window, event, allow_key_up); } -static void -handle_workspace_shift (MetaWindow *window, - XEvent *event, - KeySym keysym) +/* Handle a key event. May be called recursively: some key events cause + * grabs to be ended and then need to be processed again in their own + * right. This cannot cause infinite recursion because we never call + * ourselves when there wasn't a grab, and we always clear the grab + * first; the invariant is enforced using an assertion. See #112560. + * + * The return value is whether we handled the key event. + * + * FIXME: We need to prove there are no race conditions here. + * FIXME: Does it correctly handle alt-Tab being followed by another + * grabbing keypress without letting go of alt? + * FIXME: An iterative solution would probably be simpler to understand + * (and help us solve the other fixmes). + */ +gboolean +meta_keybindings_process_event (MetaDisplay *display, + MetaWindow *window, + const ClutterEvent *event) { - MetaWorkspace *target_workspace; - guint motion = META_MOTION_LEFT; - gboolean should_handle = FALSE; + MetaKeyBindingManager *keys = &display->key_binding_manager; - if (keysym == XK_Left || keysym == XK_KP_Left) + switch (event->type) { - motion = meta_prefs_get_invert_flip_direction () ? META_MOTION_RIGHT : META_MOTION_LEFT; - should_handle = TRUE; - } - else - if (keysym == XK_Right || keysym == XK_KP_Right) - { - motion = meta_prefs_get_invert_flip_direction () ? META_MOTION_LEFT : META_MOTION_RIGHT; - should_handle = TRUE; - } - - if (!should_handle) - { - return; - } + case CLUTTER_BUTTON_PRESS: + case CLUTTER_BUTTON_RELEASE: + case CLUTTER_TOUCH_BEGIN: + case CLUTTER_TOUCH_END: + modifier_key_only_pressed = FALSE; + return FALSE; - target_workspace = meta_workspace_get_neighbor (window->screen->active_workspace, motion); + case CLUTTER_KEY_PRESS: + case CLUTTER_KEY_RELEASE: + return process_key_event (display, window, (ClutterKeyEvent *) event); - if (target_workspace) - { - meta_workspace_activate (target_workspace, event->xkey.time); + default: + return FALSE; } } static gboolean -process_mouse_move_resize_grab (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XEvent *event, - KeySym keysym) +process_mouse_move_resize_grab (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event) { - MetaWorkspace *target_workspace; - gulong mask; - gboolean numlock = FALSE; - /* don't care about releases, but eat them, don't end grab */ - if (event->type == KeyRelease) + if (event->type == CLUTTER_KEY_RELEASE) return TRUE; - if (keysym == XK_Escape) + if (event->keyval == CLUTTER_KEY_Escape) { + MetaTileMode tile_mode; + /* Hide the tiling preview if necessary */ - meta_screen_tile_preview_hide (screen); - meta_screen_tile_hud_hide (screen); + if (display->preview_tile_mode != META_TILE_NONE) + meta_display_hide_tile_preview (display); /* Restore the original tile mode */ - window->tile_mode = display->grab_tile_mode; + tile_mode = display->grab_tile_mode; window->tile_monitor_number = display->grab_tile_monitor_number; /* End move or resize and restore to original state. If the @@ -1891,150 +2349,35 @@ process_mouse_move_resize_grab (MetaDisplay *display, * need to remaximize it. In normal cases, we need to do a * moveresize now to get the position back to the original. */ - if (window->shaken_loose) - meta_window_maximize (window, - META_MAXIMIZE_HORIZONTAL | - META_MAXIMIZE_VERTICAL); - else if (window->tile_mode != META_TILE_NONE) { - window->custom_snap_size = FALSE; - meta_window_real_tile (window, FALSE); - } else - meta_window_move_resize (display->grab_window, - TRUE, - display->grab_initial_window_pos.x, - display->grab_initial_window_pos.y, - display->grab_initial_window_pos.width, - display->grab_initial_window_pos.height); + if (window->shaken_loose || tile_mode == META_TILE_MAXIMIZED) + meta_window_maximize (window, META_MAXIMIZE_BOTH); + else if (tile_mode != META_TILE_NONE) + meta_window_restore_tile (window, + tile_mode, + display->grab_initial_window_pos.width, + display->grab_initial_window_pos.height); + else + meta_window_move_resize_frame (display->grab_window, + TRUE, + display->grab_initial_window_pos.x, + display->grab_initial_window_pos.y, + display->grab_initial_window_pos.width, + display->grab_initial_window_pos.height); /* End grab */ return FALSE; } - /* Don't use ignored_modifier_mask here - we don't want to ignore numlock */ - mask = event->xkey.state & 0xff & ~(display->scroll_lock_mask | LockMask); - - /* Only proceed if no mod or only numlock */ - if (mask == display->num_lock_mask) - { - numlock = TRUE; - } - else if (mask > display->num_lock_mask) - { - return TRUE; - } - - gint index = -1; - - switch (keysym) - { - case XK_Left: - case XK_Right: - handle_workspace_shift (window, event, keysym); - return TRUE; - - case XK_KP_End: - if (!numlock) break; - DISABLE_GCC7_FALL_THRU_WARNING; - case XK_1: - index = 0; - break; - - case XK_KP_Down: - if (!numlock) break; - DISABLE_GCC7_FALL_THRU_WARNING; - case XK_2: - index = 1; - break; - - case XK_KP_Next: - if (!numlock) break; - DISABLE_GCC7_FALL_THRU_WARNING; - case XK_3: - index = 2; - break; - - case XK_KP_Left: - if (!numlock) - { - handle_workspace_shift (window, event, keysym); - return TRUE; - } - DISABLE_GCC7_FALL_THRU_WARNING; - case XK_4: - index = 3; - break; - - case XK_KP_Begin: - if (!numlock) break; - DISABLE_GCC7_FALL_THRU_WARNING; - case XK_5: - index = 4; - break; - - case XK_KP_Right: - if (!numlock) - { - handle_workspace_shift (window, event, keysym); - return TRUE; - } - DISABLE_GCC7_FALL_THRU_WARNING; - case XK_6: - index = 5; - break; - - case XK_KP_Home: - if (!numlock) break; - DISABLE_GCC7_FALL_THRU_WARNING; - case XK_7: - index = 6; - break; - - case XK_KP_Up: - if (!numlock) break; - DISABLE_GCC7_FALL_THRU_WARNING; - case XK_8: - index = 7; - break; - - case XK_KP_Prior: - if (!numlock) break; - DISABLE_GCC7_FALL_THRU_WARNING; - case XK_9: - index = 8; - break; - - case XK_KP_Insert: - if (!numlock) break; - DISABLE_GCC7_FALL_THRU_WARNING; - case XK_0: - index = 9; - break; - - default: - break; - } - - if (index >= 0) - { - target_workspace = meta_screen_get_workspace_by_index (window->screen, index); - - if (target_workspace) - { - meta_workspace_activate (target_workspace, event->xkey.time); - } - } - return TRUE; } static gboolean -process_keyboard_move_grab (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XEvent *event, - KeySym keysym) +process_keyboard_move_grab (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event) { gboolean handled; + MetaRectangle frame_rect; int x, y; int incr; gboolean smart_snap; @@ -2042,28 +2385,30 @@ process_keyboard_move_grab (MetaDisplay *display, handled = FALSE; /* don't care about releases, but eat them, don't end grab */ - if (event->type == KeyRelease) + if (event->type == CLUTTER_KEY_RELEASE) return TRUE; /* don't end grab on modifier key presses */ - if (is_modifier (display, event->xkey.keycode)) + if (is_modifier (event->keyval)) return TRUE; - meta_window_get_position (window, &x, &y); + meta_window_get_frame_rect (window, &frame_rect); + x = frame_rect.x; + y = frame_rect.y; - smart_snap = (event->xkey.state & ShiftMask) != 0; + smart_snap = (event->modifier_state & CLUTTER_SHIFT_MASK) != 0; #define SMALL_INCREMENT 1 #define NORMAL_INCREMENT 10 if (smart_snap) incr = 1; - else if (event->xkey.state & ControlMask) + else if (event->modifier_state & CLUTTER_CONTROL_MASK) incr = SMALL_INCREMENT; else incr = NORMAL_INCREMENT; - if (keysym == XK_Escape) + if (event->keyval == CLUTTER_KEY_Escape) { /* End move and restore to original state. If the window was a * maximized window that had been "shaken loose" we need to @@ -2071,25 +2416,14 @@ process_keyboard_move_grab (MetaDisplay *display, * now to get the position back to the original. */ if (window->shaken_loose) - { - meta_window_maximize (window, - META_MAXIMIZE_HORIZONTAL | - META_MAXIMIZE_VERTICAL); - } - else if (window->tile_mode != META_TILE_NONE) - { - window->custom_snap_size = FALSE; - meta_window_real_tile (window, FALSE); - } + meta_window_maximize (window, META_MAXIMIZE_BOTH); else - { - meta_window_move_resize (display->grab_window, - TRUE, - display->grab_initial_window_pos.x, - display->grab_initial_window_pos.y, - display->grab_initial_window_pos.width, - display->grab_initial_window_pos.height); - } + meta_window_move_resize_frame (display->grab_window, + TRUE, + display->grab_initial_window_pos.x, + display->grab_initial_window_pos.y, + display->grab_initial_window_pos.width, + display->grab_initial_window_pos.height); } /* When moving by increments, we still snap to edges if the move @@ -2097,37 +2431,37 @@ process_keyboard_move_grab (MetaDisplay *display, * Shift + arrow to snap is sort of a hidden feature. This way * people using just arrows shouldn't get too frustrated. */ - switch (keysym) + switch (event->keyval) { - case XK_KP_Home: - case XK_KP_Prior: - case XK_Up: - case XK_KP_Up: + case CLUTTER_KEY_KP_Home: + case CLUTTER_KEY_KP_Prior: + case CLUTTER_KEY_Up: + case CLUTTER_KEY_KP_Up: y -= incr; handled = TRUE; break; - case XK_KP_End: - case XK_KP_Next: - case XK_Down: - case XK_KP_Down: + case CLUTTER_KEY_KP_End: + case CLUTTER_KEY_KP_Next: + case CLUTTER_KEY_Down: + case CLUTTER_KEY_KP_Down: y += incr; handled = TRUE; break; } - switch (keysym) + switch (event->keyval) { - case XK_KP_Home: - case XK_KP_End: - case XK_Left: - case XK_KP_Left: + case CLUTTER_KEY_KP_Home: + case CLUTTER_KEY_KP_End: + case CLUTTER_KEY_Left: + case CLUTTER_KEY_KP_Left: x -= incr; handled = TRUE; break; - case XK_KP_Prior: - case XK_KP_Next: - case XK_Right: - case XK_KP_Right: + case CLUTTER_KEY_KP_Prior: + case CLUTTER_KEY_KP_Next: + case CLUTTER_KEY_Right: + case CLUTTER_KEY_KP_Right: x += incr; handled = TRUE; break; @@ -2135,25 +2469,18 @@ process_keyboard_move_grab (MetaDisplay *display, if (handled) { - MetaRectangle old_rect; meta_topic (META_DEBUG_KEYBINDINGS, "Computed new window location %d,%d due to keypress\n", x, y); - meta_window_tile (window, META_TILE_NONE, FALSE); - - meta_window_get_client_root_coords (window, &old_rect); - meta_window_edge_resistance_for_move (window, - old_rect.x, - old_rect.y, &x, &y, NULL, smart_snap, TRUE); - meta_window_move (window, TRUE, x, y); + meta_window_move_frame (window, TRUE, x, y); meta_window_update_keyboard_move (window); } @@ -2161,11 +2488,9 @@ process_keyboard_move_grab (MetaDisplay *display, } static gboolean -process_keyboard_resize_grab_op_change (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XEvent *event, - KeySym keysym) +process_keyboard_resize_grab_op_change (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event) { gboolean handled; @@ -2173,114 +2498,90 @@ process_keyboard_resize_grab_op_change (MetaDisplay *display, switch (display->grab_op) { case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN: - switch (keysym) + switch (event->keyval) { - case XK_Up: - case XK_KP_Up: - if (meta_window_resize_or_move_allowed (window, META_DIRECTION_UP)) { - display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_N; - } + case CLUTTER_KEY_Up: + case CLUTTER_KEY_KP_Up: + display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_N; handled = TRUE; break; - case XK_Down: - case XK_KP_Down: - if (meta_window_resize_or_move_allowed (window, META_DIRECTION_DOWN)) { - display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_S; - } + case CLUTTER_KEY_Down: + case CLUTTER_KEY_KP_Down: + display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_S; handled = TRUE; break; - case XK_Left: - case XK_KP_Left: - if (meta_window_resize_or_move_allowed (window, META_DIRECTION_LEFT)) { - display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_W; - } + case CLUTTER_KEY_Left: + case CLUTTER_KEY_KP_Left: + display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_W; handled = TRUE; break; - case XK_Right: - case XK_KP_Right: - if (meta_window_resize_or_move_allowed (window, META_DIRECTION_RIGHT)) { - display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_E; - } + case CLUTTER_KEY_Right: + case CLUTTER_KEY_KP_Right: + display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_E; handled = TRUE; break; } break; case META_GRAB_OP_KEYBOARD_RESIZING_S: - switch (keysym) + switch (event->keyval) { - case XK_Left: - case XK_KP_Left: - if (meta_window_resize_or_move_allowed (window, META_DIRECTION_LEFT)) { - display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_W; - } + case CLUTTER_KEY_Left: + case CLUTTER_KEY_KP_Left: + display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_W; handled = TRUE; break; - case XK_Right: - case XK_KP_Right: - if (meta_window_resize_or_move_allowed (window, META_DIRECTION_RIGHT)) { - display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_E; - } + case CLUTTER_KEY_Right: + case CLUTTER_KEY_KP_Right: + display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_E; handled = TRUE; break; } break; case META_GRAB_OP_KEYBOARD_RESIZING_N: - switch (keysym) + switch (event->keyval) { - case XK_Left: - case XK_KP_Left: - if (meta_window_resize_or_move_allowed (window, META_DIRECTION_LEFT)) { - display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_W; - } + case CLUTTER_KEY_Left: + case CLUTTER_KEY_KP_Left: + display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_W; handled = TRUE; break; - case XK_Right: - case XK_KP_Right: - if (meta_window_resize_or_move_allowed (window, META_DIRECTION_RIGHT)) { - display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_E; - } + case CLUTTER_KEY_Right: + case CLUTTER_KEY_KP_Right: + display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_E; handled = TRUE; break; } break; case META_GRAB_OP_KEYBOARD_RESIZING_W: - switch (keysym) + switch (event->keyval) { - case XK_Up: - case XK_KP_Up: - if (meta_window_resize_or_move_allowed (window, META_DIRECTION_UP)) { - display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_N; - } + case CLUTTER_KEY_Up: + case CLUTTER_KEY_KP_Up: + display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_N; handled = TRUE; break; - case XK_Down: - case XK_KP_Down: - if (meta_window_resize_or_move_allowed (window, META_DIRECTION_DOWN)) { - display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_S; - } + case CLUTTER_KEY_Down: + case CLUTTER_KEY_KP_Down: + display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_S; handled = TRUE; break; } break; case META_GRAB_OP_KEYBOARD_RESIZING_E: - switch (keysym) + switch (event->keyval) { - case XK_Up: - case XK_KP_Up: - if (meta_window_resize_or_move_allowed (window, META_DIRECTION_UP)) { - display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_N; - } + case CLUTTER_KEY_Up: + case CLUTTER_KEY_KP_Up: + display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_N; handled = TRUE; break; - case XK_Down: - case XK_KP_Down: - if (meta_window_resize_or_move_allowed (window, META_DIRECTION_DOWN)) { - display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_S; - } + case CLUTTER_KEY_Down: + case CLUTTER_KEY_KP_Down: + display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_S; handled = TRUE; break; } @@ -2307,55 +2608,54 @@ process_keyboard_resize_grab_op_change (MetaDisplay *display, } static gboolean -process_keyboard_resize_grab (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XEvent *event, - KeySym keysym) +process_keyboard_resize_grab (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event) { + MetaRectangle frame_rect; gboolean handled; int height_inc; int width_inc; int width, height; gboolean smart_snap; - int gravity; + MetaGravity gravity; handled = FALSE; /* don't care about releases, but eat them, don't end grab */ - if (event->type == KeyRelease) + if (event->type == CLUTTER_KEY_RELEASE) return TRUE; /* don't end grab on modifier key presses */ - if (is_modifier (display, event->xkey.keycode)) + if (is_modifier (event->keyval)) return TRUE; - if (keysym == XK_Escape) + if (event->keyval == CLUTTER_KEY_Escape) { /* End resize and restore to original state. */ - meta_window_move_resize (display->grab_window, - TRUE, - display->grab_initial_window_pos.x, - display->grab_initial_window_pos.y, - display->grab_initial_window_pos.width, - display->grab_initial_window_pos.height); + meta_window_move_resize_frame (display->grab_window, + TRUE, + display->grab_initial_window_pos.x, + display->grab_initial_window_pos.y, + display->grab_initial_window_pos.width, + display->grab_initial_window_pos.height); return FALSE; } - if (process_keyboard_resize_grab_op_change (display, screen, window, - event, keysym)) + if (process_keyboard_resize_grab_op_change (display, window, event)) return TRUE; width = window->rect.width; height = window->rect.height; - if (window->tile_mode != META_TILE_NONE) - gravity = meta_resize_gravity_from_tile_mode (window->tile_mode); - else - gravity = meta_resize_gravity_from_grab_op (display->grab_op); + meta_window_get_frame_rect (window, &frame_rect); + width = frame_rect.width; + height = frame_rect.height; - smart_snap = (event->xkey.state & ShiftMask) != 0; + gravity = meta_resize_gravity_from_grab_op (display->grab_op); + + smart_snap = (event->modifier_state & CLUTTER_SHIFT_MASK) != 0; #define SMALL_INCREMENT 1 #define NORMAL_INCREMENT 10 @@ -2365,7 +2665,7 @@ process_keyboard_resize_grab (MetaDisplay *display, height_inc = 1; width_inc = 1; } - else if (event->xkey.state & ControlMask) + else if (event->modifier_state & CLUTTER_CONTROL_MASK) { width_inc = SMALL_INCREMENT; height_inc = SMALL_INCREMENT; @@ -2384,29 +2684,31 @@ process_keyboard_resize_grab (MetaDisplay *display, if (window->size_hints.height_inc > 1) height_inc = window->size_hints.height_inc; - switch (keysym) + switch (event->keyval) { - case XK_Up: - case XK_KP_Up: + case CLUTTER_KEY_Up: + case CLUTTER_KEY_KP_Up: switch (gravity) { - case NorthGravity: - case NorthWestGravity: - case NorthEastGravity: + case META_GRAVITY_NORTH: + case META_GRAVITY_NORTH_WEST: + case META_GRAVITY_NORTH_EAST: /* Move bottom edge up */ height -= height_inc; break; - case SouthGravity: - case SouthWestGravity: - case SouthEastGravity: + case META_GRAVITY_SOUTH: + case META_GRAVITY_SOUTH_WEST: + case META_GRAVITY_SOUTH_EAST: /* Move top edge up */ height += height_inc; break; - case EastGravity: - case WestGravity: - case CenterGravity: + case META_GRAVITY_EAST: + case META_GRAVITY_WEST: + case META_GRAVITY_CENTER: + case META_GRAVITY_NONE: + case META_GRAVITY_STATIC: g_assert_not_reached (); break; } @@ -2414,27 +2716,29 @@ process_keyboard_resize_grab (MetaDisplay *display, handled = TRUE; break; - case XK_Down: - case XK_KP_Down: + case CLUTTER_KEY_Down: + case CLUTTER_KEY_KP_Down: switch (gravity) { - case NorthGravity: - case NorthWestGravity: - case NorthEastGravity: + case META_GRAVITY_NORTH: + case META_GRAVITY_NORTH_WEST: + case META_GRAVITY_NORTH_EAST: /* Move bottom edge down */ height += height_inc; break; - case SouthGravity: - case SouthWestGravity: - case SouthEastGravity: + case META_GRAVITY_SOUTH: + case META_GRAVITY_SOUTH_WEST: + case META_GRAVITY_SOUTH_EAST: /* Move top edge down */ height -= height_inc; break; - case EastGravity: - case WestGravity: - case CenterGravity: + case META_GRAVITY_EAST: + case META_GRAVITY_WEST: + case META_GRAVITY_CENTER: + case META_GRAVITY_NONE: + case META_GRAVITY_STATIC: g_assert_not_reached (); break; } @@ -2442,27 +2746,29 @@ process_keyboard_resize_grab (MetaDisplay *display, handled = TRUE; break; - case XK_Left: - case XK_KP_Left: + case CLUTTER_KEY_Left: + case CLUTTER_KEY_KP_Left: switch (gravity) { - case EastGravity: - case SouthEastGravity: - case NorthEastGravity: + case META_GRAVITY_EAST: + case META_GRAVITY_SOUTH_EAST: + case META_GRAVITY_NORTH_EAST: /* Move left edge left */ width += width_inc; break; - case WestGravity: - case SouthWestGravity: - case NorthWestGravity: + case META_GRAVITY_WEST: + case META_GRAVITY_SOUTH_WEST: + case META_GRAVITY_NORTH_WEST: /* Move right edge left */ width -= width_inc; break; - case NorthGravity: - case SouthGravity: - case CenterGravity: + case META_GRAVITY_NORTH: + case META_GRAVITY_SOUTH: + case META_GRAVITY_CENTER: + case META_GRAVITY_NONE: + case META_GRAVITY_STATIC: g_assert_not_reached (); break; } @@ -2470,27 +2776,29 @@ process_keyboard_resize_grab (MetaDisplay *display, handled = TRUE; break; - case XK_Right: - case XK_KP_Right: + case CLUTTER_KEY_Right: + case CLUTTER_KEY_KP_Right: switch (gravity) { - case EastGravity: - case SouthEastGravity: - case NorthEastGravity: + case META_GRAVITY_EAST: + case META_GRAVITY_SOUTH_EAST: + case META_GRAVITY_NORTH_EAST: /* Move left edge right */ width -= width_inc; break; - case WestGravity: - case SouthWestGravity: - case NorthWestGravity: + case META_GRAVITY_WEST: + case META_GRAVITY_SOUTH_WEST: + case META_GRAVITY_NORTH_WEST: /* Move right edge right */ width += width_inc; break; - case NorthGravity: - case SouthGravity: - case CenterGravity: + case META_GRAVITY_NORTH: + case META_GRAVITY_SOUTH: + case META_GRAVITY_CENTER: + case META_GRAVITY_NONE: + case META_GRAVITY_STATIC: g_assert_not_reached (); break; } @@ -2510,18 +2818,13 @@ process_keyboard_resize_grab (MetaDisplay *display, if (handled) { - MetaRectangle old_rect; meta_topic (META_DEBUG_KEYBINDINGS, "Computed new window size due to keypress: " "%dx%d, gravity %s\n", width, height, meta_gravity_to_string (gravity)); - old_rect = window->rect; /* Don't actually care about x,y */ - /* Do any edge resistance/snapping */ meta_window_edge_resistance_for_resize (window, - old_rect.width, - old_rect.height, &width, &height, gravity, @@ -2529,15 +2832,11 @@ process_keyboard_resize_grab (MetaDisplay *display, smart_snap, TRUE); - /* We don't need to update unless the specified width and height - * are actually different from what we had before. - */ - if (window->rect.width != width || window->rect.height != height) - meta_window_resize_with_gravity (window, - TRUE, - width, - height, - gravity); + meta_window_resize_frame_with_gravity (window, + TRUE, + width, + height, + gravity); meta_window_update_keyboard_resize (window, FALSE); } @@ -2546,29 +2845,60 @@ process_keyboard_resize_grab (MetaDisplay *display, } static void -handle_switch_to_workspace (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *event_window, - XEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_switch_to_last_workspace (MetaDisplay *display, + MetaWindow *event_window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) +{ + MetaWorkspaceManager *workspace_manager = display->workspace_manager; + gint target = meta_workspace_manager_get_n_workspaces (workspace_manager) - 1; + MetaWorkspace *workspace = meta_workspace_manager_get_workspace_by_index (workspace_manager, target); + meta_workspace_activate (workspace, event->time); +} + +static void +handle_switch_to_workspace (MetaDisplay *display, + MetaWindow *event_window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { gint which = binding->handler->data; + MetaWorkspaceManager *workspace_manager = display->workspace_manager; MetaWorkspace *workspace; - workspace = meta_screen_get_workspace_by_index (screen, which); + if (which < 0) + { + /* Negative workspace numbers are directions with respect to the + * current workspace. + */ + + workspace = meta_workspace_get_neighbor (workspace_manager->active_workspace, + which); + } + else + { + workspace = meta_workspace_manager_get_workspace_by_index (workspace_manager, which); + } if (workspace) - meta_workspace_activate (workspace, event->xkey.time); + { + meta_workspace_activate (workspace, event->time); + } + else + { + /* We could offer to create it I suppose */ + } } + static void -handle_maximize_vertically (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_maximize_vertically (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { if (window->has_resize_func) { @@ -2580,12 +2910,11 @@ handle_maximize_vertically (MetaDisplay *display, } static void -handle_maximize_horizontally (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_maximize_horizontally (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { if (window->has_resize_func) { @@ -2597,149 +2926,327 @@ handle_maximize_horizontally (MetaDisplay *display, } static void -handle_opacity (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_always_on_top (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) +{ + if (window->wm_state_above == FALSE) + meta_window_make_above (window); + else + meta_window_unmake_above (window); +} + +static void +handle_move_to_corner_backend (MetaDisplay *display, + MetaWindow *window, + MetaGravity gravity) +{ + MetaRectangle work_area; + MetaRectangle frame_rect; + int new_x, new_y; + + if (!window->monitor) + return; + + meta_window_get_work_area_current_monitor (window, &work_area); + meta_window_get_frame_rect (window, &frame_rect); + + switch (gravity) + { + case META_GRAVITY_NORTH_WEST: + case META_GRAVITY_WEST: + case META_GRAVITY_SOUTH_WEST: + new_x = work_area.x; + break; + case META_GRAVITY_NORTH: + case META_GRAVITY_SOUTH: + new_x = frame_rect.x; + break; + case META_GRAVITY_NORTH_EAST: + case META_GRAVITY_EAST: + case META_GRAVITY_SOUTH_EAST: + new_x = work_area.x + work_area.width - frame_rect.width; + break; + default: + g_assert_not_reached (); + } + + switch (gravity) + { + case META_GRAVITY_NORTH_WEST: + case META_GRAVITY_NORTH: + case META_GRAVITY_NORTH_EAST: + new_y = work_area.y; + break; + case META_GRAVITY_WEST: + case META_GRAVITY_EAST: + new_y = frame_rect.y; + break; + case META_GRAVITY_SOUTH_WEST: + case META_GRAVITY_SOUTH: + case META_GRAVITY_SOUTH_EAST: + new_y = work_area.y + work_area.height - frame_rect.height; + break; + default: + g_assert_not_reached (); + } + + meta_window_move_frame (window, + TRUE, + new_x, + new_y); +} + +static void +handle_move_to_corner_nw (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) +{ + handle_move_to_corner_backend (display, window, META_GRAVITY_NORTH_WEST); +} + +static void +handle_move_to_corner_ne (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) +{ + handle_move_to_corner_backend (display, window, META_GRAVITY_NORTH_EAST); +} + +static void +handle_move_to_corner_sw (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) +{ + handle_move_to_corner_backend (display, window, META_GRAVITY_SOUTH_WEST); +} + +static void +handle_move_to_corner_se (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) +{ + handle_move_to_corner_backend (display, window, META_GRAVITY_SOUTH_EAST); +} + +static void +handle_move_to_side_n (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) +{ + handle_move_to_corner_backend (display, window, META_GRAVITY_NORTH); +} + +static void +handle_move_to_side_s (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) +{ + handle_move_to_corner_backend (display, window, META_GRAVITY_SOUTH); +} + +static void +handle_move_to_side_e (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) +{ + handle_move_to_corner_backend (display, window, META_GRAVITY_EAST); +} + +static void +handle_move_to_side_w (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) +{ + handle_move_to_corner_backend (display, window, META_GRAVITY_WEST); +} + +static void +handle_move_to_center (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) +{ + MetaRectangle work_area; + MetaRectangle frame_rect; + + meta_window_get_work_area_all_monitors (window, &work_area); + meta_window_get_frame_rect (window, &frame_rect); + + meta_window_move_frame (window, + TRUE, + work_area.x + (work_area.width - frame_rect.width ) / 2, + work_area.y + (work_area.height - frame_rect.height) / 2); +} + +static void +handle_show_desktop (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { - MetaKeyBindingAction action = meta_prefs_get_keybinding_action (binding->name); + MetaWorkspaceManager *workspace_manager = display->workspace_manager; - meta_window_adjust_opacity (window, action == META_KEYBINDING_ACTION_INCREASE_OPACITY); + if (workspace_manager->active_workspace->showing_desktop) + { + meta_workspace_manager_unshow_desktop (workspace_manager); + meta_workspace_focus_default_window (workspace_manager->active_workspace, + NULL, + event->time); + } + else + meta_workspace_manager_show_desktop (workspace_manager, event->time); } static void -handle_move_to (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_panel (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { + MetaKeyBindingAction action = binding->handler->data; + MetaX11Display *x11_display = display->x11_display; + Atom action_atom; + XClientMessageEvent ev; - guint direction = binding->handler->data; - MetaRectangle work_area, outer; - int monitor, new_x, new_y; + action_atom = None; + switch (action) + { + /* FIXME: The numbers are wrong */ + case META_KEYBINDING_ACTION_PANEL_MAIN_MENU: + action_atom = x11_display->atom__GNOME_PANEL_ACTION_MAIN_MENU; + break; + case META_KEYBINDING_ACTION_PANEL_RUN_DIALOG: + action_atom = x11_display->atom__GNOME_PANEL_ACTION_RUN_DIALOG; + break; + default: + return; + } - monitor = meta_screen_get_current_monitor (window->screen); - meta_window_get_work_area_for_monitor (window, monitor, &work_area); - meta_window_get_outer_rect (window, &outer); + ev.type = ClientMessage; + ev.window = x11_display->xroot; + ev.message_type = x11_display->atom__GNOME_PANEL_ACTION; + ev.format = 32; + ev.data.l[0] = action_atom; + ev.data.l[1] = event->time; - if (direction & META_MOVE_TO_XCHANGE_FLAG) { - new_x = work_area.x + (direction & META_MOVE_TO_RIGHT_FLAG ? - work_area.width - outer.width : - 0); - } else { - new_x = outer.x; - } + meta_topic (META_DEBUG_KEYBINDINGS, + "Sending panel message with timestamp %u, and turning mouse_mode " + "off due to keybinding press\n", event->time); + display->mouse_mode = FALSE; - if (direction & META_MOVE_TO_YCHANGE_FLAG) { - new_y = work_area.y + (direction & META_MOVE_TO_BOTTOM_FLAG ? - work_area.height - outer.height : - 0); - } else { - new_y = outer.y; - } + meta_x11_error_trap_push (x11_display); - if (window->has_custom_frame_extents) - { - const GtkBorder *extents = &window->custom_frame_extents; - new_x -= extents->left; - new_y -= extents->top; - } + /* Release the grab for the panel before sending the event */ + XUngrabKeyboard (x11_display->xdisplay, event->time); - meta_window_move_frame (window, - TRUE, - new_x, - new_y); + XSendEvent (x11_display->xdisplay, + x11_display->xroot, + False, + StructureNotifyMask, + (XEvent*) &ev); + + meta_x11_error_trap_pop (x11_display); } static void -handle_move_to_center (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_activate_window_menu (MetaDisplay *display, + MetaWindow *event_window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { - MetaFrameBorders borders; - MetaRectangle work_area, outer_rect; - int center_x, center_y; - int x, y; - - meta_window_get_work_area_current_monitor (window, &work_area); - meta_window_get_input_rect (window, &outer_rect); - meta_frame_calc_borders (window->frame, &borders); + if (display->focus_window) + { + int x, y; + MetaRectangle frame_rect; + cairo_rectangle_int_t child_rect; - center_x = work_area.x + work_area.width / 2; - center_y = work_area.y + work_area.height / 2; + meta_window_get_frame_rect (display->focus_window, &frame_rect); + meta_window_get_client_area_rect (display->focus_window, &child_rect); - x = center_x - (window->rect.width / 2); - y = center_y - (outer_rect.height / 2) + borders.visible.top + borders.invisible.top; + x = frame_rect.x + child_rect.x; + if (meta_get_locale_direction () == META_LOCALE_DIRECTION_RTL) + x += child_rect.width; - meta_window_move_resize (window, - TRUE, - x, - y, - window->rect.width, - window->rect.height); + y = frame_rect.y + child_rect.y; + meta_window_show_menu (display->focus_window, META_WINDOW_MENU_WM, x, y); + } } static void -handle_show_desktop (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +do_choose_window (MetaDisplay *display, + MetaWindow *event_window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gboolean backward) { - meta_screen_toggle_desktop (screen, event->xkey.time); + MetaWorkspaceManager *workspace_manager = display->workspace_manager; + MetaTabList type = binding->handler->data; + MetaWindow *window; + + meta_topic (META_DEBUG_KEYBINDINGS, + "Tab list = %u\n", type); + + window = meta_display_get_tab_next (display, + type, + workspace_manager->active_workspace, + NULL, + backward); + + if (window) + meta_window_activate (window, event->time); } static void -handle_toggle_recording (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_switch (MetaDisplay *display, + MetaWindow *event_window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { - g_signal_emit_by_name (screen, "toggle-recording"); + gboolean backwards = meta_key_binding_is_reversed (binding); + do_choose_window (display, event_window, event, binding, backwards); } static void -handle_activate_window_menu (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *event_window, - XEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_cycle (MetaDisplay *display, + MetaWindow *event_window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { - if (display->focus_window) - { - int x, y; - - meta_window_get_position (display->focus_window, - &x, &y); - - if (meta_ui_get_direction() == META_UI_DIRECTION_RTL) - x += display->focus_window->rect.width; - - meta_window_show_menu (display->focus_window, - x, y, - 0, - event->xkey.time); - } + gboolean backwards = meta_key_binding_is_reversed (binding); + do_choose_window (display, event_window, event, binding, backwards); } static void -handle_toggle_fullscreen (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_toggle_fullscreen (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { if (window->fullscreen) meta_window_unmake_fullscreen (window); @@ -2748,12 +3255,11 @@ handle_toggle_fullscreen (MetaDisplay *display, } static void -handle_toggle_above (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_toggle_above (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { if (window->wm_state_above) meta_window_unmake_above (window); @@ -2761,277 +3267,150 @@ handle_toggle_above (MetaDisplay *display, meta_window_make_above (window); } -static MetaTileMode -get_new_tile_mode (MetaTileMode direction, - MetaTileMode current) -{ - MetaTileMode ret = META_TILE_NONE; - switch (current) { - case META_TILE_NONE: - ret = direction; - break; - case META_TILE_MAXIMIZE: - if (direction == META_TILE_LEFT) - ret = META_TILE_LEFT; - else if (direction == META_TILE_RIGHT) - ret = META_TILE_RIGHT; - else if (direction == META_TILE_TOP) - ret = direction; - else if (direction == META_TILE_BOTTOM) - ret = META_TILE_TOP; - else - ret = META_TILE_NONE; - break; - case META_TILE_LEFT: - if (direction == META_TILE_LEFT) - ret = META_TILE_LEFT; - else if (direction == META_TILE_RIGHT) - ret = META_TILE_NONE; - else if (direction == META_TILE_TOP) - ret = META_TILE_ULC; - else - ret = META_TILE_LLC; - break; - case META_TILE_RIGHT: - if (direction == META_TILE_LEFT) - ret = META_TILE_NONE; - else if (direction == META_TILE_RIGHT) - ret = META_TILE_RIGHT; - else if (direction == META_TILE_TOP) - ret = META_TILE_URC; - else - ret = META_TILE_LRC; - break; - case META_TILE_TOP: - if (direction == META_TILE_LEFT) - ret = META_TILE_ULC; - else if (direction == META_TILE_RIGHT) - ret = META_TILE_URC; - else if (direction == META_TILE_TOP) - ret = META_TILE_MAXIMIZE; - else - ret = META_TILE_NONE; - break; - case META_TILE_BOTTOM: - if (direction == META_TILE_LEFT) - ret = META_TILE_LLC; - else if (direction == META_TILE_RIGHT) - ret = META_TILE_LRC; - else if (direction == META_TILE_TOP) - ret = META_TILE_NONE; - else - ret = META_TILE_BOTTOM; - break; - case META_TILE_ULC: - if (direction == META_TILE_LEFT) - ret = META_TILE_ULC; - else if (direction == META_TILE_RIGHT) - ret = META_TILE_TOP; - else if (direction == META_TILE_TOP) - ret = META_TILE_ULC; - else - ret = META_TILE_LEFT; - break; - case META_TILE_LLC: - if (direction == META_TILE_LEFT) - ret = META_TILE_LLC; - else if (direction == META_TILE_RIGHT) - ret = META_TILE_BOTTOM; - else if (direction == META_TILE_TOP) - ret = META_TILE_LEFT; - else - ret = META_TILE_LLC; - break; - case META_TILE_URC: - if (direction == META_TILE_LEFT) - ret = META_TILE_TOP; - else if (direction == META_TILE_RIGHT) - ret = META_TILE_URC; - else if (direction == META_TILE_TOP) - ret = META_TILE_URC; - else - ret = META_TILE_RIGHT; - break; - case META_TILE_LRC: - if (direction == META_TILE_LEFT) - ret = META_TILE_BOTTOM; - else if (direction == META_TILE_RIGHT) - ret = META_TILE_LRC; - else if (direction == META_TILE_TOP) - ret = META_TILE_RIGHT; - else - ret = META_TILE_LRC; - break; - default: - ret = current; - break; - } - return ret; -} - static void -handle_tile_action (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_toggle_tiled (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { MetaTileMode mode = binding->handler->data; - MetaKeyBindingAction action = meta_prefs_get_keybinding_action (binding->name); - gboolean snap = action == META_KEYBINDING_ACTION_PUSH_SNAP_LEFT || - action == META_KEYBINDING_ACTION_PUSH_SNAP_RIGHT || - action == META_KEYBINDING_ACTION_PUSH_SNAP_UP || - action == META_KEYBINDING_ACTION_PUSH_SNAP_DOWN; - - MetaTileMode new_mode = get_new_tile_mode (mode, META_WINDOW_MAXIMIZED (window) ? - META_TILE_MAXIMIZE : window->tile_mode); - if (new_mode == window->tile_mode) - return; - if (new_mode == META_TILE_MAXIMIZE) + if ((META_WINDOW_TILED_LEFT (window) && mode == META_TILE_LEFT) || + (META_WINDOW_TILED_RIGHT (window) && mode == META_TILE_RIGHT)) { - meta_window_maximize (window, - META_MAXIMIZE_HORIZONTAL | - META_MAXIMIZE_VERTICAL); + window->tile_monitor_number = window->saved_maximize ? window->monitor->number + : -1; + window->tile_mode = window->saved_maximize ? META_TILE_MAXIMIZED + : META_TILE_NONE; + + if (window->saved_maximize) + meta_window_maximize (window, META_MAXIMIZE_BOTH); + else + meta_window_unmaximize (window, META_MAXIMIZE_BOTH); } - else + else if (meta_window_can_tile_side_by_side (window)) { - meta_window_tile (window, new_mode, snap); + window->tile_monitor_number = window->monitor->number; + /* Maximization constraints beat tiling constraints, so if the window + * is maximized, tiling won't have any effect unless we unmaximize it + * horizontally first; rather than calling meta_window_unmaximize(), + * we just set the flag and rely on meta_window_tile() syncing it to + * save an additional roundtrip. + */ + window->maximized_horizontally = FALSE; + meta_window_tile (window, mode); } } static void -handle_toggle_maximized (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_toggle_maximized (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { if (META_WINDOW_MAXIMIZED (window)) - meta_window_unmaximize (window, - META_MAXIMIZE_HORIZONTAL | - META_MAXIMIZE_VERTICAL); + meta_window_unmaximize (window, META_MAXIMIZE_BOTH); else if (window->has_maximize_func) - meta_window_maximize (window, - META_MAXIMIZE_HORIZONTAL | - META_MAXIMIZE_VERTICAL); + meta_window_maximize (window, META_MAXIMIZE_BOTH); } static void -handle_maximize (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_maximize (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { if (window->has_maximize_func) - meta_window_maximize (window, - META_MAXIMIZE_HORIZONTAL | - META_MAXIMIZE_VERTICAL); + meta_window_maximize (window, META_MAXIMIZE_BOTH); } static void -handle_unmaximize (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_unmaximize (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { if (window->maximized_vertically || window->maximized_horizontally) - meta_window_unmaximize (window, - META_MAXIMIZE_HORIZONTAL | - META_MAXIMIZE_VERTICAL); + meta_window_unmaximize (window, META_MAXIMIZE_BOTH); } static void -handle_toggle_shaded (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_toggle_shaded (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { if (window->shaded) - meta_window_unshade (window, event->xkey.time); + meta_window_unshade (window, event->time); else if (window->has_shade_func) - meta_window_shade (window, event->xkey.time); + meta_window_shade (window, event->time); } static void -handle_close (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_close (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { if (window->has_close_func) - meta_window_delete (window, event->xkey.time); + meta_window_delete (window, event->time); } static void -handle_minimize (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_minimize (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { if (window->has_minimize_func) meta_window_minimize (window); } static void -handle_begin_move (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_begin_move (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { if (window->has_move_func) { meta_window_begin_grab_op (window, META_GRAB_OP_KEYBOARD_MOVING, FALSE, - event->xkey.time); + event->time); } } static void -handle_begin_resize (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_begin_resize (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { if (window->has_resize_func) { - if (window->tile_mode != META_TILE_NONE) - { - window->resize_tile_mode = window->tile_mode; - window->resizing_tile_type = window->tile_type; - } - meta_window_begin_grab_op (window, META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN, FALSE, - event->xkey.time); + event->time); } } static void -handle_toggle_on_all_workspaces (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_toggle_on_all_workspaces (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { if (window->on_all_workspaces_requested) meta_window_unstick (window); @@ -3040,16 +3419,35 @@ handle_toggle_on_all_workspaces (MetaDisplay *display, } static void -handle_move_to_workspace (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_move_to_workspace_last (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) +{ + MetaWorkspaceManager *workspace_manager = display->workspace_manager; + gint which; + MetaWorkspace *workspace; + + if (window->always_sticky) + return; + + which = meta_workspace_manager_get_n_workspaces (workspace_manager) - 1; + workspace = meta_workspace_manager_get_workspace_by_index (workspace_manager, which); + meta_window_change_workspace (window, workspace); +} + + +static void +handle_move_to_workspace (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { + MetaWorkspaceManager *workspace_manager = display->workspace_manager; gint which = binding->handler->data; gboolean flip = (which < 0); - gboolean new = (which == META_MOTION_NOT_EXIST_YET); MetaWorkspace *workspace; /* If which is zero or positive, it's a workspace number, and the window @@ -3064,17 +3462,15 @@ handle_move_to_workspace (MetaDisplay *display, return; workspace = NULL; - if (!new) { - if (flip) - { - workspace = meta_workspace_get_neighbor (screen->active_workspace, - which); - } - else - { - workspace = meta_screen_get_workspace_by_index (screen, which); - } - } + if (flip) + { + workspace = meta_workspace_get_neighbor (workspace_manager->active_workspace, + which); + } + else + { + workspace = meta_workspace_manager_get_workspace_by_index (workspace_manager, which); + } if (workspace) { @@ -3085,36 +3481,34 @@ handle_move_to_workspace (MetaDisplay *display, meta_topic (META_DEBUG_FOCUS, "Resetting mouse_mode to FALSE due to " "handle_move_to_workspace() call with flip set.\n"); - workspace->screen->display->mouse_mode = FALSE; + meta_display_clear_mouse_mode (workspace->display); meta_workspace_activate_with_focus (workspace, window, - event->xkey.time); + event->time); } } - else if (new) + else { - workspace = meta_screen_append_new_workspace (window->screen, FALSE, event->xkey.time); - GSettings *cinnamon = g_settings_new ("org.cinnamon"); - g_settings_set_int (cinnamon, "number-workspaces", g_list_length (screen->workspaces)); - g_object_unref (cinnamon); - - meta_window_change_workspace (window, workspace); + /* We could offer to create it I suppose */ } } static void handle_move_to_monitor (MetaDisplay *display, - MetaScreen *screen, MetaWindow *window, - XEvent *event, + ClutterKeyEvent *event, MetaKeyBinding *binding, gpointer dummy) { + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); gint which = binding->handler->data; - const MetaMonitorInfo *current, *new; + MetaLogicalMonitor *current, *new; - current = meta_screen_get_monitor_for_window (screen, window); - new = meta_screen_get_monitor_neighbor (screen, current->number, which); + current = window->monitor; + new = meta_monitor_manager_get_logical_monitor_neighbor (monitor_manager, + current, which); if (new == NULL) return; @@ -3123,19 +3517,18 @@ handle_move_to_monitor (MetaDisplay *display, } static void -handle_raise_or_lower (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_raise_or_lower (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { /* Get window at pointer */ MetaWindow *above = NULL; /* Check if top */ - if (meta_stack_get_top (window->screen->stack) == window) + if (meta_stack_get_top (window->display->stack) == window) { meta_window_lower (window); return; @@ -3143,17 +3536,17 @@ handle_raise_or_lower (MetaDisplay *display, /* else check if windows in same layer are intersecting it */ - above = meta_stack_get_above (window->screen->stack, window, TRUE); + above = meta_stack_get_above (window->display->stack, window, TRUE); while (above) { MetaRectangle tmp, win_rect, above_rect; - - if (above->mapped && meta_window_should_be_showing(above)) + + if (above->mapped && meta_window_should_be_showing (above)) { - meta_window_get_outer_rect (window, &win_rect); - meta_window_get_outer_rect (above, &above_rect); - + meta_window_get_frame_rect (window, &win_rect); + meta_window_get_frame_rect (above, &above_rect); + /* Check if obscured */ if (meta_rectangle_intersect (&win_rect, &above_rect, &tmp)) { @@ -3162,7 +3555,7 @@ handle_raise_or_lower (MetaDisplay *display, } } - above = meta_stack_get_above (window->screen->stack, above, TRUE); + above = meta_stack_get_above (window->display->stack, above, TRUE); } /* window is not obscured */ @@ -3170,46 +3563,120 @@ handle_raise_or_lower (MetaDisplay *display, } static void -handle_raise (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_raise (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { meta_window_raise (window); } static void -handle_lower (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_lower (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { meta_window_lower (window); } static void -handle_set_spew_mark (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_set_spew_mark (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { meta_verbose ("-- MARK MARK MARK MARK --\n"); } -LOCAL_SYMBOL void -meta_set_keybindings_disabled (gboolean setting) +#ifdef HAVE_NATIVE_BACKEND +static void +handle_switch_vt (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { - all_bindings_disabled = setting; - meta_topic (META_DEBUG_KEYBINDINGS, - "Keybindings %s\n", all_bindings_disabled ? "disabled" : "enabled"); + gint vt = binding->handler->data; + GError *error = NULL; + + if (!meta_activate_vt (vt, &error)) + { + g_warning ("Failed to switch VT: %s", error->message); + g_error_free (error); + } +} +#endif /* HAVE_NATIVE_BACKEND */ + +static void +handle_switch_monitor (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) +{ + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaMonitorSwitchConfigType config_type = + meta_monitor_manager_get_switch_config (monitor_manager); + + if (!meta_monitor_manager_can_switch_config (monitor_manager)) + return; + + config_type = (config_type + 1) % (META_MONITOR_SWITCH_CONFIG_UNKNOWN); + meta_monitor_manager_switch_config (monitor_manager, config_type); +} + +static void +handle_rotate_monitor (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) +{ + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + + meta_monitor_manager_rotate_monitor (monitor_manager); +} + +static void +handle_restore_shortcuts (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) +{ + ClutterInputDevice *source; + + if (!display->focus_window) + return; + + source = clutter_event_get_source_device ((ClutterEvent *) event); + + meta_topic (META_DEBUG_KEYBINDINGS, "Restoring normal keyboard shortcuts\n"); + + meta_window_force_restore_shortcuts (display->focus_window, source); } +/** + * meta_keybindings_set_custom_handler: + * @name: The name of the keybinding to set + * @handler: (nullable): The new handler function + * @user_data: User data to pass to the callback + * @free_data: Will be called when this handler is overridden. + * + * Allows users to register a custom handler for a + * builtin key binding. + * + * Returns: %TRUE if the binding known as @name was found, + * %FALSE otherwise. + */ gboolean meta_keybindings_set_custom_handler (const gchar *name, MetaKeyHandlerFunc handler, @@ -3234,110 +3701,122 @@ meta_keybindings_set_custom_handler (const gchar *name, static void init_builtin_key_bindings (MetaDisplay *display) { -#define REVERSES_AND_REVERSED (META_KEY_BINDING_REVERSES | \ - META_KEY_BINDING_IS_REVERSED) + GSettings *common_keybindings = g_settings_new (SCHEMA_COMMON_KEYBINDINGS); + GSettings *mutter_keybindings = g_settings_new (SCHEMA_MUTTER_KEYBINDINGS); + GSettings *mutter_wayland_keybindings = g_settings_new (SCHEMA_MUTTER_WAYLAND_KEYBINDINGS); add_builtin_keybinding (display, "switch-to-workspace-1", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_NONE, + common_keybindings, + META_KEY_BINDING_NONE | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_WORKSPACE_1, handle_switch_to_workspace, 0); add_builtin_keybinding (display, "switch-to-workspace-2", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_NONE, + common_keybindings, + META_KEY_BINDING_NONE | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_WORKSPACE_2, handle_switch_to_workspace, 1); add_builtin_keybinding (display, "switch-to-workspace-3", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_NONE, + common_keybindings, + META_KEY_BINDING_NONE | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_WORKSPACE_3, handle_switch_to_workspace, 2); add_builtin_keybinding (display, "switch-to-workspace-4", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_NONE, + common_keybindings, + META_KEY_BINDING_NONE | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_WORKSPACE_4, handle_switch_to_workspace, 3); add_builtin_keybinding (display, "switch-to-workspace-5", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_NONE, + common_keybindings, + META_KEY_BINDING_NONE | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_WORKSPACE_5, handle_switch_to_workspace, 4); add_builtin_keybinding (display, "switch-to-workspace-6", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_NONE, + common_keybindings, + META_KEY_BINDING_NONE | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_WORKSPACE_6, handle_switch_to_workspace, 5); add_builtin_keybinding (display, "switch-to-workspace-7", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_NONE, + common_keybindings, + META_KEY_BINDING_NONE | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_WORKSPACE_7, handle_switch_to_workspace, 6); add_builtin_keybinding (display, "switch-to-workspace-8", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_NONE, + common_keybindings, + META_KEY_BINDING_NONE | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_WORKSPACE_8, handle_switch_to_workspace, 7); add_builtin_keybinding (display, "switch-to-workspace-9", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_NONE, + common_keybindings, + META_KEY_BINDING_NONE | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_WORKSPACE_9, handle_switch_to_workspace, 8); add_builtin_keybinding (display, "switch-to-workspace-10", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_NONE, + common_keybindings, + META_KEY_BINDING_NONE | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_WORKSPACE_10, handle_switch_to_workspace, 9); add_builtin_keybinding (display, "switch-to-workspace-11", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_NONE, + common_keybindings, + META_KEY_BINDING_NONE | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_WORKSPACE_11, handle_switch_to_workspace, 10); add_builtin_keybinding (display, "switch-to-workspace-12", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_NONE, + common_keybindings, + META_KEY_BINDING_NONE | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_WORKSPACE_12, handle_switch_to_workspace, 11); - // Handled by Cinnamon, hence handler is NULL add_builtin_keybinding (display, "switch-to-workspace-left", - SCHEMA_MUFFIN_KEYBINDINGS, + common_keybindings, META_KEY_BINDING_NONE, META_KEYBINDING_ACTION_WORKSPACE_LEFT, - NULL, META_MOTION_LEFT); + handle_switch_to_workspace, META_MOTION_LEFT); add_builtin_keybinding (display, "switch-to-workspace-right", - SCHEMA_MUFFIN_KEYBINDINGS, + common_keybindings, META_KEY_BINDING_NONE, META_KEYBINDING_ACTION_WORKSPACE_RIGHT, - NULL, META_MOTION_RIGHT); + handle_switch_to_workspace, META_MOTION_RIGHT); add_builtin_keybinding (display, "switch-to-workspace-up", - SCHEMA_MUFFIN_KEYBINDINGS, + common_keybindings, META_KEY_BINDING_NONE, META_KEYBINDING_ACTION_WORKSPACE_UP, - NULL, META_MOTION_UP); + handle_switch_to_workspace, META_MOTION_UP); add_builtin_keybinding (display, "switch-to-workspace-down", - SCHEMA_MUFFIN_KEYBINDINGS, + common_keybindings, META_KEY_BINDING_NONE, META_KEYBINDING_ACTION_WORKSPACE_DOWN, - NULL, META_MOTION_DOWN); + handle_switch_to_workspace, META_MOTION_DOWN); /* The ones which have inverses. These can't be bound to any keystroke * containing Shift because Shift will invert their "backward" state. @@ -3351,532 +3830,712 @@ init_builtin_key_bindings (MetaDisplay *display) add_builtin_keybinding (display, "switch-group", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_REVERSES, + common_keybindings, + META_KEY_BINDING_NONE, META_KEYBINDING_ACTION_SWITCH_GROUP, - NULL, META_TAB_LIST_GROUP); + handle_switch, META_TAB_LIST_GROUP); add_builtin_keybinding (display, "switch-group-backward", - SCHEMA_MUFFIN_KEYBINDINGS, - REVERSES_AND_REVERSED, + common_keybindings, + META_KEY_BINDING_IS_REVERSED, META_KEYBINDING_ACTION_SWITCH_GROUP_BACKWARD, - NULL, META_TAB_LIST_GROUP); + handle_switch, META_TAB_LIST_GROUP); + + // add_builtin_keybinding (display, + // "switch-applications", + // common_keybindings, + // META_KEY_BINDING_NONE, + // META_KEYBINDING_ACTION_SWITCH_APPLICATIONS, + // handle_switch, META_TAB_LIST_NORMAL); + + // add_builtin_keybinding (display, + // "switch-applications-backward", + // common_keybindings, + // META_KEY_BINDING_IS_REVERSED, + // META_KEYBINDING_ACTION_SWITCH_APPLICATIONS_BACKWARD, + // handle_switch, META_TAB_LIST_NORMAL); add_builtin_keybinding (display, "switch-windows", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_REVERSES, + common_keybindings, + META_KEY_BINDING_NONE, META_KEYBINDING_ACTION_SWITCH_WINDOWS, - NULL, META_TAB_LIST_NORMAL); + handle_switch, META_TAB_LIST_NORMAL); add_builtin_keybinding (display, "switch-windows-backward", - SCHEMA_MUFFIN_KEYBINDINGS, - REVERSES_AND_REVERSED, + common_keybindings, + META_KEY_BINDING_IS_REVERSED, META_KEYBINDING_ACTION_SWITCH_WINDOWS_BACKWARD, - NULL, META_TAB_LIST_NORMAL); + handle_switch, META_TAB_LIST_NORMAL); add_builtin_keybinding (display, "switch-panels", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_REVERSES, + common_keybindings, + META_KEY_BINDING_NONE, META_KEYBINDING_ACTION_SWITCH_PANELS, - NULL, META_TAB_LIST_DOCKS); + handle_switch, META_TAB_LIST_DOCKS); add_builtin_keybinding (display, "switch-panels-backward", - SCHEMA_MUFFIN_KEYBINDINGS, - REVERSES_AND_REVERSED, + common_keybindings, + META_KEY_BINDING_IS_REVERSED, META_KEYBINDING_ACTION_SWITCH_PANELS_BACKWARD, - NULL, META_TAB_LIST_DOCKS); + handle_switch, META_TAB_LIST_DOCKS); + + // add_builtin_keybinding (display, + // "cycle-group", + // common_keybindings, + // META_KEY_BINDING_NONE, + // META_KEYBINDING_ACTION_CYCLE_GROUP, + // handle_cycle, META_TAB_LIST_GROUP); + + // add_builtin_keybinding (display, + // "cycle-group-backward", + // common_keybindings, + // META_KEY_BINDING_IS_REVERSED, + // META_KEYBINDING_ACTION_CYCLE_GROUP_BACKWARD, + // handle_cycle, META_TAB_LIST_GROUP); + + // add_builtin_keybinding (display, + // "cycle-windows", + // common_keybindings, + // META_KEY_BINDING_NONE, + // META_KEYBINDING_ACTION_CYCLE_WINDOWS, + // handle_cycle, META_TAB_LIST_NORMAL); + + // add_builtin_keybinding (display, + // "cycle-windows-backward", + // common_keybindings, + // META_KEY_BINDING_IS_REVERSED, + // META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD, + // handle_cycle, META_TAB_LIST_NORMAL); + + // add_builtin_keybinding (display, + // "cycle-panels", + // common_keybindings, + // META_KEY_BINDING_NONE, + // META_KEYBINDING_ACTION_CYCLE_PANELS, + // handle_cycle, META_TAB_LIST_DOCKS); + + // add_builtin_keybinding (display, + // "cycle-panels-backward", + // common_keybindings, + // META_KEY_BINDING_IS_REVERSED, + // META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD, + // handle_cycle, META_TAB_LIST_DOCKS); + + /***********************************/ add_builtin_keybinding (display, "show-desktop", - SCHEMA_MUFFIN_KEYBINDINGS, + common_keybindings, META_KEY_BINDING_NONE, META_KEYBINDING_ACTION_SHOW_DESKTOP, handle_show_desktop, 0); + // add_builtin_keybinding (display, + // "panel-main-menu", + // common_keybindings, + // META_KEY_BINDING_NONE, + // META_KEYBINDING_ACTION_PANEL_MAIN_MENU, + // handle_panel, META_KEYBINDING_ACTION_PANEL_MAIN_MENU); + add_builtin_keybinding (display, "panel-run-dialog", - SCHEMA_MUFFIN_KEYBINDINGS, + common_keybindings, META_KEY_BINDING_NONE, META_KEYBINDING_ACTION_PANEL_RUN_DIALOG, - NULL, META_KEYBINDING_ACTION_PANEL_RUN_DIALOG); - - add_builtin_keybinding (display, - "toggle-recording", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_NONE, - META_KEYBINDING_ACTION_TOGGLE_RECORDING, - handle_toggle_recording, 0); + handle_panel, META_KEYBINDING_ACTION_PANEL_RUN_DIALOG); add_builtin_keybinding (display, "set-spew-mark", - SCHEMA_MUFFIN_KEYBINDINGS, + common_keybindings, META_KEY_BINDING_NONE, META_KEYBINDING_ACTION_SET_SPEW_MARK, handle_set_spew_mark, 0); -#undef REVERSES_AND_REVERSED + add_builtin_keybinding (display, + "toggle-recording", + common_keybindings, + META_KEY_BINDING_NONE, + META_KEYBINDING_ACTION_TOGGLE_RECORDING, + NULL, 0); + + // add_builtin_keybinding (display, + // "switch-monitor", + // mutter_keybindings, + // META_KEY_BINDING_NONE, + // META_KEYBINDING_ACTION_SWITCH_MONITOR, + // handle_switch_monitor, 0); + + // add_builtin_keybinding (display, + // "rotate-monitor", + // mutter_keybindings, + // META_KEY_BINDING_NONE, + // META_KEYBINDING_ACTION_ROTATE_MONITOR, + // handle_rotate_monitor, 0); + +#ifdef HAVE_NATIVE_BACKEND + MetaBackend *backend = meta_get_backend (); + if (META_IS_BACKEND_NATIVE (backend)) + { + add_builtin_keybinding (display, + "switch-to-session-1", + mutter_wayland_keybindings, + META_KEY_BINDING_NON_MASKABLE, + META_KEYBINDING_ACTION_NONE, + handle_switch_vt, 1); + + add_builtin_keybinding (display, + "switch-to-session-2", + mutter_wayland_keybindings, + META_KEY_BINDING_NON_MASKABLE, + META_KEYBINDING_ACTION_NONE, + handle_switch_vt, 2); + + add_builtin_keybinding (display, + "switch-to-session-3", + mutter_wayland_keybindings, + META_KEY_BINDING_NON_MASKABLE, + META_KEYBINDING_ACTION_NONE, + handle_switch_vt, 3); + + add_builtin_keybinding (display, + "switch-to-session-4", + mutter_wayland_keybindings, + META_KEY_BINDING_NON_MASKABLE, + META_KEYBINDING_ACTION_NONE, + handle_switch_vt, 4); + + add_builtin_keybinding (display, + "switch-to-session-5", + mutter_wayland_keybindings, + META_KEY_BINDING_NON_MASKABLE, + META_KEYBINDING_ACTION_NONE, + handle_switch_vt, 5); + + add_builtin_keybinding (display, + "switch-to-session-6", + mutter_wayland_keybindings, + META_KEY_BINDING_NON_MASKABLE, + META_KEYBINDING_ACTION_NONE, + handle_switch_vt, 6); + + add_builtin_keybinding (display, + "switch-to-session-7", + mutter_wayland_keybindings, + META_KEY_BINDING_NON_MASKABLE, + META_KEYBINDING_ACTION_NONE, + handle_switch_vt, 7); + + add_builtin_keybinding (display, + "switch-to-session-8", + mutter_wayland_keybindings, + META_KEY_BINDING_NON_MASKABLE, + META_KEYBINDING_ACTION_NONE, + handle_switch_vt, 8); + + add_builtin_keybinding (display, + "switch-to-session-9", + mutter_wayland_keybindings, + META_KEY_BINDING_NON_MASKABLE, + META_KEYBINDING_ACTION_NONE, + handle_switch_vt, 9); + + add_builtin_keybinding (display, + "switch-to-session-10", + mutter_wayland_keybindings, + META_KEY_BINDING_NON_MASKABLE, + META_KEYBINDING_ACTION_NONE, + handle_switch_vt, 10); + + add_builtin_keybinding (display, + "switch-to-session-11", + mutter_wayland_keybindings, + META_KEY_BINDING_NON_MASKABLE, + META_KEYBINDING_ACTION_NONE, + handle_switch_vt, 11); + + add_builtin_keybinding (display, + "switch-to-session-12", + mutter_wayland_keybindings, + META_KEY_BINDING_NON_MASKABLE, + META_KEYBINDING_ACTION_NONE, + handle_switch_vt, 12); + } +#endif /* HAVE_NATIVE_BACKEND */ + + add_builtin_keybinding (display, + "restore-shortcuts", + mutter_wayland_keybindings, + META_KEY_BINDING_NON_MASKABLE, + META_KEYBINDING_ACTION_NONE, + handle_restore_shortcuts, 0); -/************************ PER WINDOW BINDINGS ************************/ + /************************ PER WINDOW BINDINGS ************************/ -/* These take a window as an extra parameter; they have no effect - * if no window is active. - */ + /* These take a window as an extra parameter; they have no effect + * if no window is active. + */ add_builtin_keybinding (display, "activate-window-menu", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_ACTIVATE_WINDOW_MENU, handle_activate_window_menu, 0); add_builtin_keybinding (display, "toggle-fullscreen", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_TOGGLE_FULLSCREEN, handle_toggle_fullscreen, 0); add_builtin_keybinding (display, "toggle-maximized", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_TOGGLE_MAXIMIZED, handle_toggle_maximized, 0); add_builtin_keybinding (display, - "push-tile-left", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, - META_KEYBINDING_ACTION_PUSH_TILE_LEFT, - handle_tile_action, META_TILE_LEFT); - - add_builtin_keybinding (display, - "push-tile-right", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, - META_KEYBINDING_ACTION_PUSH_TILE_RIGHT, - handle_tile_action, META_TILE_RIGHT); - - add_builtin_keybinding (display, - "push-tile-up", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, - META_KEYBINDING_ACTION_PUSH_TILE_UP, - handle_tile_action, META_TILE_TOP); - - add_builtin_keybinding (display, - "push-tile-down", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, - META_KEYBINDING_ACTION_PUSH_TILE_DOWN, - handle_tile_action, META_TILE_BOTTOM); - - add_builtin_keybinding (display, - "push-snap-left", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, - META_KEYBINDING_ACTION_PUSH_SNAP_LEFT, - handle_tile_action, META_TILE_LEFT); - - add_builtin_keybinding (display, - "push-snap-right", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, - META_KEYBINDING_ACTION_PUSH_SNAP_RIGHT, - handle_tile_action, META_TILE_RIGHT); - - add_builtin_keybinding (display, - "push-snap-up", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, - META_KEYBINDING_ACTION_PUSH_SNAP_UP, - handle_tile_action, META_TILE_TOP); + "toggle-tiled-left", + mutter_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, + META_KEYBINDING_ACTION_TOGGLE_TILED_LEFT, + handle_toggle_tiled, META_TILE_LEFT); add_builtin_keybinding (display, - "push-snap-down", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, - META_KEYBINDING_ACTION_PUSH_SNAP_DOWN, - handle_tile_action, META_TILE_BOTTOM); - - + "toggle-tiled-right", + mutter_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, + META_KEYBINDING_ACTION_TOGGLE_TILED_RIGHT, + handle_toggle_tiled, META_TILE_RIGHT); add_builtin_keybinding (display, "toggle-above", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_TOGGLE_ABOVE, handle_toggle_above, 0); add_builtin_keybinding (display, "maximize", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_MAXIMIZE, handle_maximize, 0); add_builtin_keybinding (display, "unmaximize", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_UNMAXIMIZE, handle_unmaximize, 0); add_builtin_keybinding (display, "toggle-shaded", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_TOGGLE_SHADED, handle_toggle_shaded, 0); add_builtin_keybinding (display, "minimize", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_MINIMIZE, handle_minimize, 0); add_builtin_keybinding (display, "close", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_CLOSE, handle_close, 0); add_builtin_keybinding (display, "begin-move", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_BEGIN_MOVE, handle_begin_move, 0); add_builtin_keybinding (display, "begin-resize", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_BEGIN_RESIZE, handle_begin_resize, 0); add_builtin_keybinding (display, "toggle-on-all-workspaces", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_TOGGLE_ON_ALL_WORKSPACES, handle_toggle_on_all_workspaces, 0); add_builtin_keybinding (display, "move-to-workspace-1", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_1, handle_move_to_workspace, 0); add_builtin_keybinding (display, "move-to-workspace-2", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_2, handle_move_to_workspace, 1); add_builtin_keybinding (display, "move-to-workspace-3", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_3, handle_move_to_workspace, 2); add_builtin_keybinding (display, "move-to-workspace-4", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_4, handle_move_to_workspace, 3); add_builtin_keybinding (display, "move-to-workspace-5", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_5, handle_move_to_workspace, 4); add_builtin_keybinding (display, "move-to-workspace-6", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_6, handle_move_to_workspace, 5); add_builtin_keybinding (display, "move-to-workspace-7", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_7, handle_move_to_workspace, 6); add_builtin_keybinding (display, "move-to-workspace-8", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_8, handle_move_to_workspace, 7); add_builtin_keybinding (display, "move-to-workspace-9", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_9, handle_move_to_workspace, 8); add_builtin_keybinding (display, "move-to-workspace-10", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_10, handle_move_to_workspace, 9); add_builtin_keybinding (display, "move-to-workspace-11", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_11, handle_move_to_workspace, 10); add_builtin_keybinding (display, "move-to-workspace-12", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_12, handle_move_to_workspace, 11); add_builtin_keybinding (display, "move-to-workspace-left", - SCHEMA_MUFFIN_KEYBINDINGS, + common_keybindings, META_KEY_BINDING_PER_WINDOW, META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_LEFT, - NULL, META_MOTION_LEFT); + handle_move_to_workspace, META_MOTION_LEFT); add_builtin_keybinding (display, "move-to-workspace-right", - SCHEMA_MUFFIN_KEYBINDINGS, + common_keybindings, META_KEY_BINDING_PER_WINDOW, META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_RIGHT, - NULL, META_MOTION_RIGHT); + handle_move_to_workspace, META_MOTION_RIGHT); add_builtin_keybinding (display, "move-to-workspace-up", - SCHEMA_MUFFIN_KEYBINDINGS, + common_keybindings, META_KEY_BINDING_PER_WINDOW, META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_UP, handle_move_to_workspace, META_MOTION_UP); add_builtin_keybinding (display, "move-to-workspace-down", - SCHEMA_MUFFIN_KEYBINDINGS, + common_keybindings, META_KEY_BINDING_PER_WINDOW, META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_DOWN, handle_move_to_workspace, META_MOTION_DOWN); - add_builtin_keybinding (display, - "move-to-workspace-new", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, - META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_NEW, - handle_move_to_workspace, META_MOTION_NOT_EXIST_YET); - add_builtin_keybinding (display, "move-to-monitor-left", - SCHEMA_MUFFIN_KEYBINDINGS, + common_keybindings, META_KEY_BINDING_PER_WINDOW, META_KEYBINDING_ACTION_MOVE_TO_MONITOR_LEFT, - handle_move_to_monitor, META_SCREEN_LEFT); + handle_move_to_monitor, META_DISPLAY_LEFT); add_builtin_keybinding (display, "move-to-monitor-right", - SCHEMA_MUFFIN_KEYBINDINGS, + common_keybindings, META_KEY_BINDING_PER_WINDOW, META_KEYBINDING_ACTION_MOVE_TO_MONITOR_RIGHT, - handle_move_to_monitor, META_SCREEN_RIGHT); + handle_move_to_monitor, META_DISPLAY_RIGHT); add_builtin_keybinding (display, "move-to-monitor-down", - SCHEMA_MUFFIN_KEYBINDINGS, + common_keybindings, META_KEY_BINDING_PER_WINDOW, META_KEYBINDING_ACTION_MOVE_TO_MONITOR_DOWN, - handle_move_to_monitor, META_SCREEN_DOWN); + handle_move_to_monitor, META_DISPLAY_DOWN); add_builtin_keybinding (display, "move-to-monitor-up", - SCHEMA_MUFFIN_KEYBINDINGS, + common_keybindings, META_KEY_BINDING_PER_WINDOW, META_KEYBINDING_ACTION_MOVE_TO_MONITOR_UP, - handle_move_to_monitor, META_SCREEN_UP); + handle_move_to_monitor, META_DISPLAY_UP); add_builtin_keybinding (display, "raise-or-lower", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_RAISE_OR_LOWER, handle_raise_or_lower, 0); add_builtin_keybinding (display, "raise", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_RAISE, handle_raise, 0); add_builtin_keybinding (display, "lower", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_LOWER, handle_lower, 0); add_builtin_keybinding (display, "maximize-vertically", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_MAXIMIZE_VERTICALLY, handle_maximize_vertically, 0); add_builtin_keybinding (display, "maximize-horizontally", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_MAXIMIZE_HORIZONTALLY, handle_maximize_horizontally, 0); + // add_builtin_keybinding (display, + // "always-on-top", + // common_keybindings, + // META_KEY_BINDING_PER_WINDOW | + // META_KEY_BINDING_IGNORE_AUTOREPEAT, + // META_KEYBINDING_ACTION_ALWAYS_ON_TOP, + // handle_always_on_top, 0); + add_builtin_keybinding (display, "move-to-corner-nw", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_MOVE_TO_CORNER_NW, - handle_move_to, META_MOVE_TO_NW); + handle_move_to_corner_nw, 0); add_builtin_keybinding (display, "move-to-corner-ne", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_MOVE_TO_CORNER_NE, - handle_move_to, META_MOVE_TO_NE); + handle_move_to_corner_ne, 0); add_builtin_keybinding (display, "move-to-corner-sw", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_MOVE_TO_CORNER_SW, - handle_move_to, META_MOVE_TO_SW); + handle_move_to_corner_sw, 0); add_builtin_keybinding (display, "move-to-corner-se", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_MOVE_TO_CORNER_SE, - handle_move_to, META_MOVE_TO_SE); + handle_move_to_corner_se, 0); add_builtin_keybinding (display, "move-to-side-n", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_MOVE_TO_SIDE_N, - handle_move_to, META_MOVE_TO_N); + handle_move_to_side_n, 0); add_builtin_keybinding (display, "move-to-side-s", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_MOVE_TO_SIDE_S, - handle_move_to, META_MOVE_TO_S); + handle_move_to_side_s, 0); add_builtin_keybinding (display, "move-to-side-e", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_MOVE_TO_SIDE_E, - handle_move_to, META_MOVE_TO_E); + handle_move_to_side_e, 0); add_builtin_keybinding (display, "move-to-side-w", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_MOVE_TO_SIDE_W, - handle_move_to, META_MOVE_TO_W); + handle_move_to_side_w, 0); add_builtin_keybinding (display, "move-to-center", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, + common_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_MOVE_TO_CENTER, handle_move_to_center, 0); - add_builtin_keybinding (display, - "increase-opacity", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, - META_KEYBINDING_ACTION_INCREASE_OPACITY, - handle_opacity, 0); - - add_builtin_keybinding (display, - "decrease-opacity", - SCHEMA_MUFFIN_KEYBINDINGS, - META_KEY_BINDING_PER_WINDOW, - META_KEYBINDING_ACTION_DECREASE_OPACITY, - handle_opacity, 0); + g_object_unref (common_keybindings); + g_object_unref (mutter_keybindings); + g_object_unref (mutter_wayland_keybindings); } -LOCAL_SYMBOL void +void meta_display_init_keys (MetaDisplay *display) { + MetaKeyBindingManager *keys = &display->key_binding_manager; + MetaBackend *backend = meta_get_backend (); + MetaKeyHandler *handler; + + keys->backend = backend; + /* Keybindings */ - display->keymap = NULL; - display->keysyms_per_keycode = 0; - display->modmap = NULL; - display->min_keycode = 0; - display->max_keycode = 0; - display->ignored_modifier_mask = 0; - display->num_lock_mask = 0; - display->scroll_lock_mask = 0; - display->hyper_mask = 0; - display->super_mask = 0; - display->meta_mask = 0; - display->key_bindings = NULL; - display->n_key_bindings = 0; - - XDisplayKeycodes (display->xdisplay, - &display->min_keycode, - &display->max_keycode); + keys->ignored_modifier_mask = 0; + keys->hyper_mask = 0; + keys->super_mask = 0; + keys->meta_mask = 0; - meta_topic (META_DEBUG_KEYBINDINGS, - "Display has keycode range %d to %d\n", - display->min_keycode, - display->max_keycode); + keys->key_bindings = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) meta_key_binding_free); + keys->key_bindings_index = g_hash_table_new (NULL, NULL); - reload_keymap (display); - reload_modmap (display); + reload_modmap (keys); - key_handlers = g_hash_table_new_full (g_str_hash, g_str_equal, free, + key_handlers = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) key_handler_free); + + handler = g_new0 (MetaKeyHandler, 1); + handler->name = g_strdup ("overlay-key"); + handler->flags = META_KEY_BINDING_BUILTIN | META_KEY_BINDING_NO_AUTO_GRAB; + + g_hash_table_insert (key_handlers, g_strdup (handler->name), handler); + + handler = g_new0 (MetaKeyHandler, 1); + handler->name = g_strdup ("locate-pointer-key"); + handler->flags = META_KEY_BINDING_BUILTIN | META_KEY_BINDING_NO_AUTO_GRAB; + + g_hash_table_insert (key_handlers, g_strdup (handler->name), handler); + + handler = g_new0 (MetaKeyHandler, 1); + handler->name = g_strdup ("iso-next-group"); + handler->flags = META_KEY_BINDING_BUILTIN; + + g_hash_table_insert (key_handlers, g_strdup (handler->name), handler); + + handler = g_new0 (MetaKeyHandler, 1); + handler->name = g_strdup ("external-grab"); + handler->func = handle_external_grab; + handler->default_func = handle_external_grab; + + g_hash_table_insert (key_handlers, g_strdup (handler->name), handler); + + external_grabs = g_hash_table_new_full (g_str_hash, g_str_equal, + NULL, + (GDestroyNotify)meta_key_grab_free); + init_builtin_key_bindings (display); - rebuild_key_binding_table (display); + rebuild_key_binding_table (keys); + rebuild_special_bindings (keys); - reload_keycodes (display); - reload_modifiers (display); + reload_combos (keys); + + update_window_grab_modifiers (keys); /* Keys are actually grabbed in meta_screen_grab_keys() */ - meta_prefs_add_listener (bindings_changed_callback, display); + meta_prefs_add_listener (prefs_changed_callback, display); -#ifdef HAVE_XKB - /* meta_display_init_keys() should have already called XkbQueryExtension() */ - if (display->xkb_base_event_type != -1) - XkbSelectEvents (display->xdisplay, XkbUseCoreKbd, - XkbNewKeyboardNotifyMask | XkbMapNotifyMask, - XkbNewKeyboardNotifyMask | XkbMapNotifyMask); -#endif + g_signal_connect_swapped (backend, "keymap-changed", + G_CALLBACK (reload_keybindings), display); + g_signal_connect_swapped (backend, "keymap-layout-group-changed", + G_CALLBACK (reload_keybindings), display); } diff --git a/src/core/main-private.h b/src/core/main-private.h new file mode 100644 index 000000000..be6b1cef3 --- /dev/null +++ b/src/core/main-private.h @@ -0,0 +1,54 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef META_MAIN_PRIVATE_H +#define META_MAIN_PRIVATE_H + +#include "core/util-private.h" + +typedef enum _MetaCompositorType +{ +#ifdef HAVE_WAYLAND + META_COMPOSITOR_TYPE_WAYLAND, +#endif + META_COMPOSITOR_TYPE_X11, +} MetaCompositorType; + +typedef enum _MetaDisplayPolicy +{ + META_DISPLAY_POLICY_MANDATORY, + META_DISPLAY_POLICY_ON_DEMAND, + META_DISPLAY_POLICY_DISABLED, +} MetaDisplayPolicy; + +#define META_POINT_IN_RECT(xcoord, ycoord, rect) \ + ((xcoord) >= (rect).x && \ + (xcoord) < ((rect).x + (rect).width) && \ + (ycoord) >= (rect).y && \ + (ycoord) < ((rect).y + (rect).height)) + +#define META_GRAB_OP_GET_BASE_TYPE(op) (op & 0x00FF) + +META_EXPORT_TEST +void meta_override_compositor_configuration (MetaCompositorType compositor_type, + GType backend_gtype); + +MetaDisplayPolicy meta_get_x11_display_policy (void); + +#endif /* META_MAIN_PRIVATE_H */ diff --git a/src/core/main.c b/src/core/main.c index e1aaabfd1..16ab6e81f 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1,6 +1,6 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* Muffin main() */ +/* Mutter main() */ /* * Copyright (C) 2001 Havoc Pennington @@ -17,9 +17,7 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ /** @@ -28,69 +26,85 @@ * @short_description: Program startup. * * Functions which parse the command-line arguments, create the display, - * kick everything off and then close down Muffin when it's time to go. + * kick everything off and then close down Mutter when it's time to go. * * * - * Muffin - a boring window manager for the adult in you + * Mutter - a boring window manager for the adult in you * - * Many window managers are like Marshmallow Froot Loops; Muffin - * is like Cheerios. + * Many window managers are like Marshmallow Froot Loops; Mutter + * is like Frosted Flakes: it's still plain old corn, but dusted + * with some sugar. * * The best way to get a handle on how the whole system fits together * is discussed in doc/code-overview.txt; if you're looking for functions * to investigate, read main(), meta_display_open(), and event_callback(). */ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif -#define _SVID_SOURCE /* for putenv() and some signal-related functions */ - -#include <config.h> -#include <meta/main.h> -#include "util-private.h" -#include "display-private.h" -#include <meta/errors.h> -#include "ui.h" -#include "session.h" -#include <meta/prefs.h> -#include <meta/compositor.h> +#define _XOPEN_SOURCE /* for putenv() and some signal-related functions */ -#include <glib-object.h> -#include <gdk/gdkx.h> +#include "config.h" + +#include "meta/main.h" -#include <stdlib.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <stdio.h> -#include <string.h> -#include <signal.h> -#include <unistd.h> #include <errno.h> #include <fcntl.h> +#include <glib-object.h> +#include <glib-unix.h> #include <locale.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/wait.h> #include <time.h> #include <unistd.h> - -#include <clutter/clutter.h> -#include "clutter/x11/clutter-x11.h" -#include "cogl/cogl.h" -#include "cogl/cogl-xlib.h" -#include "cogl/winsys/cogl-winsys-glx-private.h" -#include <GL/gl.h> +#include <unistd.h> #ifdef HAVE_INTROSPECTION #include <girepository.h> #endif +#if defined(HAVE_NATIVE_BACKEND) && defined(HAVE_WAYLAND) +#include <systemd/sd-login.h> +#endif /* HAVE_WAYLAND && HAVE_NATIVE_BACKEND */ + +#ifdef HAVE_SYS_PRCTL +#include <sys/prctl.h> +#endif + +#include "backends/meta-backend-private.h" +#include "backends/x11/cm/meta-backend-x11-cm.h" +#include "backends/x11/meta-backend-x11.h" +#include "clutter/clutter.h" +#include "core/display-private.h" +#include "core/main-private.h" +#include "core/util-private.h" +#include "meta/compositor.h" +#include "meta/meta-backend.h" +#include "meta/meta-x11-errors.h" +#include "meta/prefs.h" +#include "ui/ui.h" +#include "x11/session.h" + +#ifdef HAVE_WAYLAND +#include "backends/x11/nested/meta-backend-x11-nested.h" +#include "wayland/meta-wayland.h" +#include "wayland/meta-xwayland.h" +#endif + +#ifdef HAVE_NATIVE_BACKEND +#include "backends/native/meta-backend-native.h" +#endif + /* * The exit code we'll return to our parent process when we eventually die. */ static MetaExitCode meta_exit_code = META_EXIT_SUCCESS; /* - * Handle on the main loop, so that we have an easy way of shutting Muffin + * Handle on the main loop, so that we have an easy way of shutting Mutter * down. */ static GMainLoop *meta_main_loop = NULL; @@ -98,92 +112,17 @@ static GMainLoop *meta_main_loop = NULL; static void prefs_changed_callback (MetaPreference pref, gpointer data); -/* - * Prints log messages. If Muffin was compiled with backtrace support, - * also prints a backtrace (see meta_print_backtrace()). +/** + * meta_print_compilation_info: * - * \param log_domain the domain the error occurred in (we ignore this) - * \param log_level the log level so that we can filter out less - * important messages - * \param message the message to log - * \param user_data arbitrary data (we ignore this) - */ -static void -log_handler (const gchar *log_domain, - GLogLevelFlags log_level, - const gchar *message, - gpointer user_data) -{ - meta_warning ("Log level %d: %s\n", log_level, message); - meta_print_backtrace (); -} - -static void -glib_debug_log_handler (const gchar *log_domain, - GLogLevelFlags log_level, - const gchar *message, - gpointer user_data) -{ - guint i; - const gchar *forbidden[] = { - "posix_spawn", - "setenv()/putenv()", - "unsetenv()" - }; - - for (i = 0; i < G_N_ELEMENTS (forbidden); i++) - { - if (g_str_has_prefix (message, forbidden[i])) - { - return; - } - } - - log_handler (log_domain, - log_level, - message, - user_data); -} - -/* * Prints a list of which configure script options were used to - * build this copy of Muffin. This is actually always called + * build this copy of Mutter. This is actually always called * on startup, but it's all no-op unless we're in verbose mode - * (see meta_set_verbose). + * (see meta_set_verbose()). */ static void meta_print_compilation_info (void) { -#ifdef HAVE_SHAPE - meta_verbose ("Compiled with shape extension\n"); -#else - meta_verbose ("Compiled without shape extension\n"); -#endif -#ifdef HAVE_XINERAMA - meta_topic (META_DEBUG_XINERAMA, "Compiled with Xinerama extension\n"); -#else - meta_topic (META_DEBUG_XINERAMA, "Compiled without Xinerama extension\n"); -#endif -#ifdef HAVE_XFREE_XINERAMA - meta_topic (META_DEBUG_XINERAMA, " (using XFree86 Xinerama)\n"); -#else - meta_topic (META_DEBUG_XINERAMA, " (not using XFree86 Xinerama)\n"); -#endif -#ifdef HAVE_SOLARIS_XINERAMA - meta_topic (META_DEBUG_XINERAMA, " (using Solaris Xinerama)\n"); -#else - meta_topic (META_DEBUG_XINERAMA, " (not using Solaris Xinerama)\n"); -#endif -#ifdef HAVE_XSYNC - meta_verbose ("Compiled with sync extension\n"); -#else - meta_verbose ("Compiled without sync extension\n"); -#endif -#ifdef HAVE_RANDR - meta_verbose ("Compiled with randr extension\n"); -#else - meta_verbose ("Compiled without randr extension\n"); -#endif #ifdef HAVE_STARTUP_NOTIFICATION meta_verbose ("Compiled with startup notification\n"); #else @@ -191,13 +130,15 @@ meta_print_compilation_info (void) #endif } -/* +/** + * meta_print_self_identity: + * * Prints the version number, the current timestamp (not the * build date), the locale, the character encoding, and a list * of configure script options that were used to build this - * copy of Muffin. This is actually always called + * copy of Mutter. This is actually always called * on startup, but it's all no-op unless we're in verbose mode - * (see meta_set_verbose). + * (see meta_set_verbose()). */ static void meta_print_self_identity (void) @@ -210,7 +151,7 @@ meta_print_self_identity (void) g_date_clear (&d, 1); g_date_set_time_t (&d, time (NULL)); g_date_strftime (buf, sizeof (buf), "%x", &d); - meta_verbose ("Muffin version %s running on %s\n", + meta_verbose ("Mutter version %s running on %s\n", VERSION, buf); /* Locale and encoding. */ @@ -223,7 +164,7 @@ meta_print_self_identity (void) } /* - * The set of possible options that can be set on Muffin's + * The set of possible options that can be set on Mutter's * command line. */ static gchar *opt_save_file; @@ -232,6 +173,15 @@ static gchar *opt_client_id; static gboolean opt_replace_wm; static gboolean opt_disable_sm; static gboolean opt_sync; +#ifdef HAVE_WAYLAND +static gboolean opt_wayland; +static gboolean opt_nested; +static gboolean opt_no_x11; +#endif +#ifdef HAVE_NATIVE_BACKEND +static gboolean opt_display_server; +#endif +static gboolean opt_x11; static GOptionEntry meta_options[] = { { @@ -241,7 +191,7 @@ static GOptionEntry meta_options[] = { NULL }, { - "replace", 0, 0, G_OPTION_ARG_NONE, + "replace", 'r', 0, G_OPTION_ARG_NONE, &opt_replace_wm, N_("Replace the running window manager"), NULL @@ -269,13 +219,45 @@ static GOptionEntry meta_options[] = { N_("Make X calls synchronous"), NULL }, +#ifdef HAVE_WAYLAND + { + "wayland", 0, 0, G_OPTION_ARG_NONE, + &opt_wayland, + N_("Run as a wayland compositor"), + NULL + }, + { + "nested", 0, 0, G_OPTION_ARG_NONE, + &opt_nested, + N_("Run as a nested compositor"), + NULL + }, + { + "no-x11", 0, 0, G_OPTION_ARG_NONE, + &opt_no_x11, + N_("Run wayland compositor without starting Xwayland"), + NULL + }, +#endif +#ifdef HAVE_NATIVE_BACKEND + { + "display-server", 0, 0, G_OPTION_ARG_NONE, + &opt_display_server, + N_("Run as a full display server, rather than nested") + }, +#endif + { + "x11", 0, 0, G_OPTION_ARG_NONE, + &opt_x11, + N_("Run with X11 backend") + }, {NULL} }; /** * meta_get_option_context: (skip) * - * Returns a #GOptionContext initialized with muffin-related options. + * Returns a #GOptionContext initialized with mutter-related options. * Parse the command-line args with this before calling meta_init(). * * Return value: the #GOptionContext @@ -287,154 +269,263 @@ meta_get_option_context (void) if (setlocale (LC_ALL, "") == NULL) meta_warning ("Locale not understood by C library, internationalization will not work\n"); - bindtextdomain (GETTEXT_PACKAGE, MUFFIN_LOCALEDIR); + bindtextdomain (GETTEXT_PACKAGE, MUTTER_LOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); ctx = g_option_context_new (NULL); g_option_context_add_main_entries (ctx, meta_options, GETTEXT_PACKAGE); - g_option_context_add_group (ctx, clutter_get_option_group_without_init ()); - g_option_context_add_group (ctx, cogl_get_option_group ()); - return ctx; } -/* Muffin is responsible for pulling events off the X queue, so Clutter - * doesn't need (and shouldn't) run its normal event source which polls - * the X fd, but we do have to deal with dispatching events that accumulate - * in the clutter queue. This happens, for example, when clutter generate - * enter/leave events on mouse motion - several events are queued in the - * clutter queue but only one dispatched. It could also happen because of - * explicit calls to clutter_event_put(). We add a very simple custom - * event loop source which is simply responsible for pulling events off - * of the queue and dispatching them before we block for new events. +/** + * meta_select_display: + * + * Selects which display Mutter should use. It first tries to use + * @display_name as the display. If @display_name is %NULL then + * try to use the environment variable MUTTER_DISPLAY. If that + * also is %NULL, use the default - :0.0 */ - -static gboolean -event_prepare (GSource *source, - gint *timeout_) +static void +meta_select_display (char *display_arg) { - *timeout_ = -1; + const char *display_name; + + if (display_arg) + display_name = (const char *) display_arg; + else + display_name = g_getenv ("MUTTER_DISPLAY"); - return clutter_events_pending (); + if (display_name) + g_setenv ("DISPLAY", display_name, TRUE); } -static gboolean -event_check (GSource *source) +static void +meta_finalize (void) { - return clutter_events_pending (); + MetaDisplay *display = meta_get_display (); + + if (display) + meta_display_close (display, + META_CURRENT_TIME); /* I doubt correct timestamps matter here */ + +#ifdef HAVE_WAYLAND + if (meta_is_wayland_compositor ()) + meta_wayland_finalize (); +#endif } static gboolean -event_dispatch (GSource *source, - GSourceFunc callback, - gpointer user_data) +on_sigterm (gpointer user_data) { - ClutterEvent *event = clutter_event_get (); - if (event) - clutter_do_event (event); + meta_quit (EXIT_SUCCESS); - return TRUE; + return G_SOURCE_REMOVE; } -static GSourceFuncs event_funcs = { - event_prepare, - event_check, - event_dispatch -}; - -static void -meta_clutter_init (void) +#if defined(HAVE_WAYLAND) && defined(HAVE_NATIVE_BACKEND) +static gboolean +session_type_is_supported (const char *session_type) { - gboolean threaded_swap = meta_prefs_get_threaded_swap (); - Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); - clutter_x11_set_display (xdisplay); - - clutter_x11_disable_event_retrieval (); + return (g_strcmp0 (session_type, "x11") == 0) || + (g_strcmp0 (session_type, "wayland") == 0); +} - if (CLUTTER_INIT_SUCCESS == clutter_init (NULL, NULL)) +static char * +find_session_type (void) +{ + char **sessions = NULL; + char *session_id; + char *session_type; + const char *session_type_env; + gboolean is_tty = FALSE; + int ret, i; + + ret = sd_pid_get_session (0, &session_id); + if (ret == 0 && session_id != NULL) { - GSource *source = g_source_new (&event_funcs, sizeof (GSource)); - g_source_attach (source, NULL); - g_source_unref (source); + ret = sd_session_get_type (session_id, &session_type); + free (session_id); - if (threaded_swap) + if (ret == 0) { - CoglRenderer *renderer = cogl_renderer_new (); - cogl_renderer_set_custom_winsys (renderer, _cogl_winsys_glx_get_vtable (), NULL); - cogl_xlib_renderer_set_foreign_display (renderer, xdisplay); - - cogl_xlib_renderer_request_reset_on_video_memory_purge (renderer, TRUE); - - /* Set up things so that if the INTEL_swap_event extension is not present, - * but the driver is known to have good thread support, we use an extra - * thread and call glXWaitVideoSync() in the thread. This allows idles - * to work properly, even when Muffin is constantly redrawing new frames; - * otherwise, without INTEL_swap_event, we'll just block in glXSwapBuffers(). - */ - cogl_xlib_renderer_set_threaded_swap_wait_enabled (renderer, TRUE); + if (session_type_is_supported (session_type)) + goto out; + else + is_tty = g_strcmp0 (session_type, "tty") == 0; + free (session_type); } } - else + else if (sd_uid_get_sessions (getuid (), 1, &sessions) > 0) + { + for (i = 0; sessions[i] != NULL; i++) + { + ret = sd_session_get_type (sessions[i], &session_type); + + if (ret < 0) + continue; + + if (session_type_is_supported (session_type)) + { + g_strfreev (sessions); + goto out; + } + + free (session_type); + } + } + g_strfreev (sessions); + + session_type_env = g_getenv ("XDG_SESSION_TYPE"); + if (session_type_is_supported (session_type_env)) + { + /* The string should be freeable */ + session_type = strdup (session_type_env); + goto out; + } + + /* Legacy support for starting through xinit */ + if (is_tty && (g_getenv ("MUTTER_DISPLAY") || g_getenv ("DISPLAY"))) { - meta_fatal ("Unable to initialize Clutter.\n"); + session_type = strdup ("x11"); + goto out; } + + meta_warning ("Unsupported session type\n"); + meta_exit (META_EXIT_ERROR); + +out: + return session_type; } -/* - * Selects which display Muffin should use. It first tries to use - * display_name as the display. If display_name is NULL then - * try to use the environment variable MUFFIN_DISPLAY. If that - * also is NULL, use the default - :0.0 - */ -static void -meta_select_display (gchar *display_name) +static gboolean +check_for_wayland_session_type (void) { - gchar *envVar = ""; - if (display_name) - envVar = g_strconcat ("DISPLAY=", display_name, NULL); - else if (g_getenv ("MUFFIN_DISPLAY")) - envVar = g_strconcat ("DISPLAY=", - g_getenv ("MUFFIN_DISPLAY"), NULL); - /* DO NOT FREE envVar, putenv() sucks */ - putenv (envVar); + char *session_type; + gboolean is_wayland; + + session_type = find_session_type (); + is_wayland = g_strcmp0 (session_type, "wayland") == 0; + free (session_type); + + return is_wayland; } +#endif +/* + * Determine the compositor configuration, i.e. whether to run as a Wayland + * compositor, as well as what backend to use. + * + * There are various different flags affecting this: + * + * --nested always forces the use of the nested X11 backend + * --display-server always forces the use of the native backend + * --wayland always forces the compositor type to be a Wayland compositor + * + * If no flag is passed that forces the compositor type, the compositor type + * is determined first from the logind session type, or if that fails, from the + * XDG_SESSION_TYPE environment variable. + * + * If no flag is passed that forces the backend type, the backend type is + * determined given the compositor type. If the compositor is a Wayland + * compositor, then the native backend is used, or the nested backend, would + * the native backend not be enabled at build time. If the compositor is not a + * Wayland compositor, then the X11 Compositing Manager backend is used. + */ static void -meta_finalize (void) +calculate_compositor_configuration (MetaCompositorType *compositor_type, + GType *backend_gtype) { - MetaDisplay *display = meta_get_display (); +#ifdef HAVE_WAYLAND + gboolean run_as_wayland_compositor = opt_wayland && !opt_x11; - if (display) - meta_display_close (display, - CurrentTime); /* I doubt correct timestamps matter here */ -} +#ifdef HAVE_NATIVE_BACKEND + if ((opt_wayland || opt_nested || opt_display_server) && opt_x11) +#else + if ((opt_wayland || opt_nested) && opt_x11) +#endif + { + meta_warning ("Can't run both as Wayland compositor and X11 compositing manager\n"); + meta_exit (META_EXIT_ERROR); + } -static int sigterm_pipe_fds[2] = { -1, -1 }; +#ifdef HAVE_NATIVE_BACKEND + if (opt_nested && opt_display_server) + { + meta_warning ("Can't run both as nested and as a display server\n"); + meta_exit (META_EXIT_ERROR); + } -static void -sigterm_handler (int signum) -{ - if (sigterm_pipe_fds[1] >= 0) + if (!run_as_wayland_compositor && !opt_x11) + run_as_wayland_compositor = check_for_wayland_session_type (); +#endif /* HAVE_NATIVE_BACKEND */ + + if (!run_as_wayland_compositor && opt_no_x11) + { + meta_warning ("Can't disable X11 support on X11 compositor\n"); + meta_exit (META_EXIT_ERROR); + } + + if (run_as_wayland_compositor) + *compositor_type = META_COMPOSITOR_TYPE_WAYLAND; + else +#endif /* HAVE_WAYLAND */ + *compositor_type = META_COMPOSITOR_TYPE_X11; + +#ifdef HAVE_WAYLAND + if (opt_nested) { - int G_GNUC_UNUSED dummy; + *backend_gtype = META_TYPE_BACKEND_X11_NESTED; + return; + } +#endif /* HAVE_WAYLAND */ + +#ifdef HAVE_NATIVE_BACKEND + if (opt_display_server) + { + *backend_gtype = META_TYPE_BACKEND_NATIVE; + return; + } + +#ifdef HAVE_WAYLAND + if (run_as_wayland_compositor) + { + *backend_gtype = META_TYPE_BACKEND_NATIVE; + return; + } +#endif /* HAVE_WAYLAND */ +#endif /* HAVE_NATIVE_BACKEND */ - dummy = write (sigterm_pipe_fds[1], "", 1); - close (sigterm_pipe_fds[1]); - sigterm_pipe_fds[1] = -1; +#ifdef HAVE_WAYLAND + if (run_as_wayland_compositor) + { + *backend_gtype = META_TYPE_BACKEND_X11_NESTED; + return; + } + else +#endif /* HAVE_WAYLAND */ + { + *backend_gtype = META_TYPE_BACKEND_X11_CM; + return; } } -static gboolean -on_sigterm (void) +static gboolean _compositor_configuration_overridden = FALSE; +static MetaCompositorType _compositor_type_override; +static GType _backend_gtype_override; + +void +meta_override_compositor_configuration (MetaCompositorType compositor_type, + GType backend_gtype) { - meta_quit (META_EXIT_SUCCESS); - return FALSE; + _compositor_configuration_overridden = TRUE; + _compositor_type_override = compositor_type; + _backend_gtype_override = backend_gtype; } /** * meta_init: (skip) * - * Initialize muffin. Call this after meta_get_option_context() and + * Initialize mutter. Call this after meta_get_option_context() and * meta_plugin_manager_set_plugin_type(), and before meta_run(). */ void @@ -442,14 +533,12 @@ meta_init (void) { struct sigaction act; sigset_t empty_mask; - GIOChannel *channel; - gboolean threaded_swap = meta_prefs_get_threaded_swap (); + MetaCompositorType compositor_type; + GType backend_gtype; - /* XInitThreads() is needed to use the "threaded swap wait" functionality - * in Cogl. We call it here to hopefully call it before any other use of XLib. - */ - if (threaded_swap) - XInitThreads(); +#ifdef HAVE_SYS_PRCTL + prctl (PR_SET_DUMPABLE, 1); +#endif sigemptyset (&empty_mask); act.sa_handler = SIG_IGN; @@ -464,26 +553,28 @@ meta_init (void) g_strerror (errno)); #endif - if (pipe (sigterm_pipe_fds) != 0) - g_printerr ("Failed to create SIGTERM pipe: %s\n", - g_strerror (errno)); - - channel = g_io_channel_unix_new (sigterm_pipe_fds[0]); - g_io_channel_set_flags (channel, G_IO_FLAG_NONBLOCK, NULL); - g_io_add_watch (channel, G_IO_IN, (GIOFunc) on_sigterm, NULL); - g_io_channel_set_close_on_unref (channel, TRUE); - g_io_channel_unref (channel); - - act.sa_handler = &sigterm_handler; - if (sigaction (SIGTERM, &act, NULL) < 0) - g_printerr ("Failed to register SIGTERM handler: %s\n", - g_strerror (errno)); + g_unix_signal_add (SIGTERM, on_sigterm, NULL); - if (g_getenv ("MUFFIN_VERBOSE")) + if (g_getenv ("MUTTER_VERBOSE")) meta_set_verbose (TRUE); - if (g_getenv ("MUFFIN_DEBUG")) + if (g_getenv ("MUTTER_DEBUG")) meta_set_debugging (TRUE); + if (_compositor_configuration_overridden) + { + compositor_type = _compositor_type_override; + backend_gtype = _backend_gtype_override; + } + else + { + calculate_compositor_configuration (&compositor_type, &backend_gtype); + } + +#ifdef HAVE_WAYLAND + if (compositor_type == META_COMPOSITOR_TYPE_WAYLAND) + meta_set_is_wayland_compositor (TRUE); +#endif + if (g_get_home_dir ()) if (chdir (g_get_home_dir ()) < 0) meta_warning ("Could not change to home directory %s.\n", @@ -492,12 +583,17 @@ meta_init (void) meta_print_self_identity (); #ifdef HAVE_INTROSPECTION - g_irepository_prepend_search_path (MUFFIN_PKGLIBDIR); + g_irepository_prepend_search_path (MUTTER_PKGLIBDIR); #endif - meta_set_syncing (opt_sync || (g_getenv ("MUFFIN_SYNC") != NULL)); + /* NB: When running as a hybrid wayland compositor we run our own headless X + * server so the user can't control the X display to connect too. */ + if (!meta_is_wayland_compositor ()) + meta_select_display (opt_display_name); - meta_select_display (opt_display_name); + meta_init_backend (backend_gtype); + + meta_set_syncing (opt_sync || (g_getenv ("MUTTER_SYNC") != NULL)); if (opt_replace_wm) meta_set_replace_current_wm (TRUE); @@ -506,88 +602,20 @@ meta_init (void) meta_fatal ("Can't specify both SM save file and SM client id\n"); meta_main_loop = g_main_loop_new (NULL, FALSE); - - meta_ui_init (); - - /* - * Disable some variables that cause rendering issues with private Clutter, - * except when software rendering is explicitly set by Cinnamon. - */ - g_unsetenv ("CLUTTER_VBLANK"); - - if (g_getenv ("CINNAMON_SOFTWARE_RENDERING") == NULL) - g_unsetenv ("CLUTTER_PAINT"); - - /* Load prefs */ - meta_prefs_init (); - _clutter_set_sync_method (meta_prefs_get_sync_method ()); - - /* - * Clutter can only be initialized after the UI. - */ - meta_clutter_init (); - - const char *renderer = (const char *) glGetString (GL_RENDERER); - if (strstr (renderer, "llvmpipe") || - strstr (renderer, "Rasterizer") || - strstr (renderer, "softpipe")) - { - /* Clutter envs not set, since they won't work after Clutter init */ - g_setenv ("CINNAMON_SOFTWARE_RENDERING", "1", FALSE); - g_setenv ("CINNAMON_SLOWDOWN_FACTOR", "0.0001", FALSE); - meta_warning ("Software rendering detected: %s\n", renderer); - } } /** - * meta_run: (skip) + * meta_register_with_session: * - * Runs muffin. Call this after completing your own initialization. + * Registers mutter with the session manager. Call this after completing your own + * initialization. * - * Return value: muffin's exit status + * This should be called when the session manager can safely continue to the + * next phase of startup and potentially display windows. */ -int -meta_run (void) +void +meta_register_with_session (void) { - const gchar *log_domains[] = { - NULL, G_LOG_DOMAIN, "Gtk", "Gdk", - "Pango", "GLib-GObject", "GThread" - }; - guint i; - - meta_prefs_add_listener (prefs_changed_callback, NULL); - - // Intercept GLib debug level - g_log_set_handler ("GLib", - G_LOG_LEVEL_DEBUG, - glib_debug_log_handler, NULL); - - // Direct all but debug to the normal handler - g_log_set_handler ("GLib", - (G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION) & ~G_LOG_LEVEL_DEBUG, - log_handler, NULL); - - for (i=0; i<G_N_ELEMENTS(log_domains); i++) - g_log_set_handler (log_domains[i], - G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, - log_handler, NULL); - - if (g_getenv ("MUFFIN_G_FATAL_WARNINGS") != NULL) - g_log_set_always_fatal (G_LOG_LEVEL_MASK); - - meta_ui_set_current_theme (meta_prefs_get_theme (), FALSE); - - if (!meta_ui_have_a_theme ()) - { - meta_ui_set_current_theme ("Default", FALSE); - meta_warning ("Could not find theme %s. Falling back to default theme.", meta_prefs_get_theme ()); - } - - - /* Connect to SM as late as possible - but before managing display, - * or we might try to manage a window before we have the session - * info - */ if (!opt_disable_sm) { if (opt_client_id == NULL) @@ -609,9 +637,25 @@ meta_run (void) /* Free memory possibly allocated by the argument parsing which are * no longer needed. */ - free (opt_save_file); - free (opt_display_name); - free (opt_client_id); + g_free (opt_save_file); + g_free (opt_display_name); + g_free (opt_client_id); +} + +/** + * meta_run: (skip) + * + * Runs mutter. Call this after completing initialization that doesn't require + * an event loop. + * + * Return value: mutter's exit status + */ +int +meta_run (void) +{ + /* Load prefs */ + meta_prefs_init (); + meta_prefs_add_listener (prefs_changed_callback, NULL); if (!meta_display_open ()) meta_exit (META_EXIT_ERROR); @@ -623,14 +667,15 @@ meta_run (void) return meta_exit_code; } -/* - * Stops Muffin. This tells the event loop to stop processing; it is +/** + * meta_quit: + * @code: The success or failure code to return to the calling process. + * + * Stops Mutter. This tells the event loop to stop processing; it is * rather dangerous to use this because this will leave the user with * no window manager. We generally do this only if, for example, the * session manager asks us to; we assume the session manager knows * what it's talking about. - * - * \param code The success or failure code to return to the calling process. */ void meta_quit (MetaExitCode code) @@ -642,14 +687,15 @@ meta_quit (MetaExitCode code) } } -/* - * Called on pref changes. (One of several functions of its kind and purpose.) +/** + * prefs_changed_callback: + * @pref: Which preference has changed + * @data: Arbitrary data (which we ignore) * - * \bug Why are these particular prefs handled in main.c and not others? - * Should they be? + * Called on pref changes. (One of several functions of its kind and purpose.) * - * \param pref Which preference has changed - * \param data Arbitrary data (which we ignore) + * FIXME: Why are these particular prefs handled in main.c and not others? + * Should they be? */ static void prefs_changed_callback (MetaPreference pref, @@ -657,28 +703,56 @@ prefs_changed_callback (MetaPreference pref, { switch (pref) { - case META_PREF_THEME: case META_PREF_DRAGGABLE_BORDER_WIDTH: - meta_ui_set_current_theme (meta_prefs_get_theme (), FALSE); - meta_display_retheme_all (); + meta_display_queue_retheme_all_windows (meta_get_display ()); break; - case META_PREF_CURSOR_THEME: - case META_PREF_CURSOR_SIZE: - meta_display_set_cursor_theme (meta_prefs_get_cursor_theme (), - meta_prefs_get_cursor_size ()); - break; - case META_PREF_SYNC_METHOD: - meta_display_update_sync_state (meta_prefs_get_sync_method ()); - break; - case META_PREF_UI_SCALE: - meta_ui_set_current_theme (meta_prefs_get_theme (), TRUE); - meta_display_retheme_all (); - meta_display_set_cursor_theme (meta_prefs_get_cursor_theme (), - meta_prefs_get_cursor_size ()); - break; default: /* handled elsewhere or otherwise */ break; } } + +MetaDisplayPolicy +meta_get_x11_display_policy (void) +{ + MetaBackend *backend = meta_get_backend (); + + if (META_IS_BACKEND_X11_CM (backend)) + return META_DISPLAY_POLICY_MANDATORY; + +#ifdef HAVE_WAYLAND + if (meta_is_wayland_compositor ()) + { + MetaSettings *settings = meta_backend_get_settings (backend); + + if (opt_no_x11) + return META_DISPLAY_POLICY_DISABLED; + + if (meta_settings_is_experimental_feature_enabled (settings, + META_EXPERIMENTAL_FEATURE_AUTOSTART_XWAYLAND)) + return META_DISPLAY_POLICY_ON_DEMAND; + } +#endif + + return META_DISPLAY_POLICY_MANDATORY; +} + +void +meta_test_init (void) +{ +#if defined(HAVE_WAYLAND) + g_autofree char *display_name = g_strdup ("mutter-test-display-XXXXXX"); + int fd = g_mkstemp (display_name); + + meta_override_compositor_configuration (META_COMPOSITOR_TYPE_WAYLAND, + META_TYPE_BACKEND_X11_NESTED); + meta_wayland_override_display_name (display_name); + meta_xwayland_override_display_number (512 + rand() % 512); + meta_init (); + + close (fd); +#else + g_warning ("Tests require wayland support"); +#endif +} diff --git a/src/core/meta-accel-parse.c b/src/core/meta-accel-parse.c new file mode 100644 index 000000000..0d34251af --- /dev/null +++ b/src/core/meta-accel-parse.c @@ -0,0 +1,358 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jasper St. Pierre <jstpierre@mecheye.net> + */ + +#include "config.h" + +#include "core/meta-accel-parse.h" + +#include <stdlib.h> +#include <string.h> +#include <xkbcommon/xkbcommon.h> + +#include "core/keybindings-private.h" + +/* This is copied from GTK+ and modified to work with mutter's + * internal structures. Originating code comes from gtk/gtkaccelgroup.c + */ + +static inline gboolean +is_alt (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 'a' || string[1] == 'A') && + (string[2] == 'l' || string[2] == 'L') && + (string[3] == 't' || string[3] == 'T') && + (string[4] == '>')); +} + +static inline gboolean +is_ctl (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 'c' || string[1] == 'C') && + (string[2] == 't' || string[2] == 'T') && + (string[3] == 'l' || string[3] == 'L') && + (string[4] == '>')); +} + +static inline gboolean +is_modx (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 'm' || string[1] == 'M') && + (string[2] == 'o' || string[2] == 'O') && + (string[3] == 'd' || string[3] == 'D') && + (string[4] >= '1' && string[4] <= '5') && + (string[5] == '>')); +} + +static inline gboolean +is_ctrl (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 'c' || string[1] == 'C') && + (string[2] == 't' || string[2] == 'T') && + (string[3] == 'r' || string[3] == 'R') && + (string[4] == 'l' || string[4] == 'L') && + (string[5] == '>')); +} + +static inline gboolean +is_shft (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 's' || string[1] == 'S') && + (string[2] == 'h' || string[2] == 'H') && + (string[3] == 'f' || string[3] == 'F') && + (string[4] == 't' || string[4] == 'T') && + (string[5] == '>')); +} + +static inline gboolean +is_shift (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 's' || string[1] == 'S') && + (string[2] == 'h' || string[2] == 'H') && + (string[3] == 'i' || string[3] == 'I') && + (string[4] == 'f' || string[4] == 'F') && + (string[5] == 't' || string[5] == 'T') && + (string[6] == '>')); +} + +static inline gboolean +is_control (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 'c' || string[1] == 'C') && + (string[2] == 'o' || string[2] == 'O') && + (string[3] == 'n' || string[3] == 'N') && + (string[4] == 't' || string[4] == 'T') && + (string[5] == 'r' || string[5] == 'R') && + (string[6] == 'o' || string[6] == 'O') && + (string[7] == 'l' || string[7] == 'L') && + (string[8] == '>')); +} + +static inline gboolean +is_meta (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 'm' || string[1] == 'M') && + (string[2] == 'e' || string[2] == 'E') && + (string[3] == 't' || string[3] == 'T') && + (string[4] == 'a' || string[4] == 'A') && + (string[5] == '>')); +} + +static inline gboolean +is_super (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 's' || string[1] == 'S') && + (string[2] == 'u' || string[2] == 'U') && + (string[3] == 'p' || string[3] == 'P') && + (string[4] == 'e' || string[4] == 'E') && + (string[5] == 'r' || string[5] == 'R') && + (string[6] == '>')); +} + +static inline gboolean +is_hyper (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 'h' || string[1] == 'H') && + (string[2] == 'y' || string[2] == 'Y') && + (string[3] == 'p' || string[3] == 'P') && + (string[4] == 'e' || string[4] == 'E') && + (string[5] == 'r' || string[5] == 'R') && + (string[6] == '>')); +} + +static inline gboolean +is_primary (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 'p' || string[1] == 'P') && + (string[2] == 'r' || string[2] == 'R') && + (string[3] == 'i' || string[3] == 'I') && + (string[4] == 'm' || string[4] == 'M') && + (string[5] == 'a' || string[5] == 'A') && + (string[6] == 'r' || string[6] == 'R') && + (string[7] == 'y' || string[7] == 'Y') && + (string[8] == '>')); +} + +static inline gboolean +is_keycode (const gchar *string) +{ + return (string[0] == '0' && + string[1] == 'x' && + g_ascii_isxdigit (string[2]) && + g_ascii_isxdigit (string[3])); +} + +static gboolean +accelerator_parse (const gchar *accelerator, + MetaKeyCombo *combo) +{ + guint keyval, keycode; + MetaVirtualModifier mods; + gint len; + + combo->keysym = 0; + combo->keycode = 0; + combo->modifiers = 0; + + if (accelerator == NULL) + return FALSE; + + keyval = 0; + keycode = 0; + mods = 0; + len = strlen (accelerator); + while (len) + { + if (*accelerator == '<') + { + if (len >= 9 && is_primary (accelerator)) + { + /* Primary is treated the same as Control */ + accelerator += 9; + len -= 9; + mods |= META_VIRTUAL_CONTROL_MASK; + } + else if (len >= 9 && is_control (accelerator)) + { + accelerator += 9; + len -= 9; + mods |= META_VIRTUAL_CONTROL_MASK; + } + else if (len >= 7 && is_shift (accelerator)) + { + accelerator += 7; + len -= 7; + mods |= META_VIRTUAL_SHIFT_MASK; + } + else if (len >= 6 && is_shft (accelerator)) + { + accelerator += 6; + len -= 6; + mods |= META_VIRTUAL_SHIFT_MASK; + } + else if (len >= 6 && is_ctrl (accelerator)) + { + accelerator += 6; + len -= 6; + mods |= META_VIRTUAL_CONTROL_MASK; + } + else if (len >= 6 && is_modx (accelerator)) + { + static const guint mod_vals[] = { + META_VIRTUAL_ALT_MASK, + META_VIRTUAL_MOD2_MASK, + META_VIRTUAL_MOD3_MASK, + META_VIRTUAL_MOD4_MASK, + META_VIRTUAL_MOD5_MASK, + }; + + len -= 6; + accelerator += 4; + mods |= mod_vals[*accelerator - '1']; + accelerator += 2; + } + else if (len >= 5 && is_ctl (accelerator)) + { + accelerator += 5; + len -= 5; + mods |= META_VIRTUAL_CONTROL_MASK; + } + else if (len >= 5 && is_alt (accelerator)) + { + accelerator += 5; + len -= 5; + mods |= META_VIRTUAL_ALT_MASK; + } + else if (len >= 6 && is_meta (accelerator)) + { + accelerator += 6; + len -= 6; + mods |= META_VIRTUAL_META_MASK; + } + else if (len >= 7 && is_hyper (accelerator)) + { + accelerator += 7; + len -= 7; + mods |= META_VIRTUAL_HYPER_MASK; + } + else if (len >= 7 && is_super (accelerator)) + { + accelerator += 7; + len -= 7; + mods |= META_VIRTUAL_SUPER_MASK; + } + else + { + gchar last_ch; + + last_ch = *accelerator; + while (last_ch && last_ch != '>') + { + last_ch = *accelerator; + accelerator += 1; + len -= 1; + } + } + } + else + { + if (len >= 4 && is_keycode (accelerator)) + { + keycode = strtoul (accelerator, NULL, 16); + goto out; + } + else if (strcmp (accelerator, "Above_Tab") == 0) + { + keyval = META_KEY_ABOVE_TAB; + goto out; + } + else + { + keyval = xkb_keysym_from_name (accelerator, XKB_KEYSYM_CASE_INSENSITIVE); + if (keyval == XKB_KEY_NoSymbol) + { + char *with_xf86 = g_strconcat ("XF86", accelerator, NULL); + keyval = xkb_keysym_from_name (with_xf86, XKB_KEYSYM_CASE_INSENSITIVE); + g_free (with_xf86); + + if (keyval == XKB_KEY_NoSymbol) + return FALSE; + } + } + + accelerator += len; + len -= len; + } + } + + out: + combo->keysym = keyval; + combo->keycode = keycode; + combo->modifiers = mods; + return TRUE; +} + +gboolean +meta_parse_accelerator (const char *accel, + MetaKeyCombo *combo) +{ + g_return_val_if_fail (combo != NULL, FALSE); + + *combo = (MetaKeyCombo) { 0 }; + + if (!accel[0] || strcmp (accel, "disabled") == 0) + return TRUE; + + return accelerator_parse (accel, combo); +} + +gboolean +meta_parse_modifier (const char *accel, + MetaVirtualModifier *mask) +{ + MetaKeyCombo combo = { 0 }; + + g_return_val_if_fail (mask != NULL, FALSE); + + *mask = 0; + + if (accel == NULL || !accel[0] || strcmp (accel, "disabled") == 0) + return TRUE; + + if (!accelerator_parse (accel, &combo)) + return FALSE; + + *mask = combo.modifiers; + return TRUE; +} diff --git a/src/core/meta-accel-parse.h b/src/core/meta-accel-parse.h new file mode 100644 index 000000000..12cf3f982 --- /dev/null +++ b/src/core/meta-accel-parse.h @@ -0,0 +1,44 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * Copyright (C) 2014 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jasper St. Pierre <jstpierre@mecheye.net> + */ + +#ifndef META_ACCEL_PARSE_H +#define META_ACCEL_PARSE_H + +#include <glib.h> + +#include "meta/common.h" + +typedef struct _MetaKeyCombo MetaKeyCombo; + +/* Not a real key symbol but means "key above the tab key"; this is + * used as the default keybinding for cycle_group. + * 0x2xxxxxxx is a range not used by GDK or X. the remaining digits are + * randomly chosen */ +#define META_KEY_ABOVE_TAB 0x2f7259c9 + +gboolean meta_parse_accelerator (const char *accel, + MetaKeyCombo *combo); +gboolean meta_parse_modifier (const char *accel, + MetaVirtualModifier *mask); + +#endif /* META_ACCEL_PARSE_H */ diff --git a/src/core/meta-border.c b/src/core/meta-border.c new file mode 100644 index 000000000..3c926c419 --- /dev/null +++ b/src/core/meta-border.c @@ -0,0 +1,154 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2015 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +#include "config.h" + +#include "core/meta-border.h" + +#include <math.h> + +static inline float +meta_vector2_cross_product (const MetaVector2 a, + const MetaVector2 b) +{ + return a.x * b.y - a.y * b.x; +} + +static inline MetaVector2 +meta_vector2_add (const MetaVector2 a, + const MetaVector2 b) +{ + return (MetaVector2) { + .x = a.x + b.x, + .y = a.y + b.y, + }; +} + +static inline MetaVector2 +meta_vector2_multiply_constant (const float c, + const MetaVector2 a) +{ + return (MetaVector2) { + .x = c * a.x, + .y = c * a.y, + }; +} + +gboolean +meta_line2_intersects_with (const MetaLine2 *line1, + const MetaLine2 *line2, + MetaVector2 *intersection) +{ + MetaVector2 p = line1->a; + MetaVector2 r = meta_vector2_subtract (line1->b, line1->a); + MetaVector2 q = line2->a; + MetaVector2 s = meta_vector2_subtract (line2->b, line2->a); + float rxs; + float sxr; + float t; + float u; + + /* + * The line (p, r) and (q, s) intersects where + * + * p + t r = q + u s + * + * Calculate t: + * + * (p + t r) × s = (q + u s) × s + * p × s + t (r × s) = q × s + u (s × s) + * p × s + t (r × s) = q × s + * t (r × s) = q × s - p × s + * t (r × s) = (q - p) × s + * t = ((q - p) × s) / (r × s) + * + * Using the same method, for u we get: + * + * u = ((p - q) × r) / (s × r) + */ + + rxs = meta_vector2_cross_product (r, s); + sxr = meta_vector2_cross_product (s, r); + + /* If r × s = 0 then the lines are either parallel or collinear. */ + if (fabsf (rxs) < FLT_MIN) + return FALSE; + + t = meta_vector2_cross_product (meta_vector2_subtract (q, p), s) / rxs; + u = meta_vector2_cross_product (meta_vector2_subtract (p, q), r) / sxr; + + /* The lines only intersect if 0 ≤ t ≤ 1 and 0 ≤ u ≤ 1. */ + if (t < 0.0 || t > 1.0 || u < 0.0 || u > 1.0) + return FALSE; + + *intersection = meta_vector2_add (p, meta_vector2_multiply_constant (t, r)); + + return TRUE; +} + +gboolean +meta_border_is_horizontal (MetaBorder *border) +{ + return border->line.a.y == border->line.b.y; +} + +gboolean +meta_border_is_blocking_directions (MetaBorder *border, + MetaBorderMotionDirection directions) +{ + if (meta_border_is_horizontal (border)) + { + if ((directions & (META_BORDER_MOTION_DIRECTION_POSITIVE_Y | + META_BORDER_MOTION_DIRECTION_NEGATIVE_Y)) == 0) + return FALSE; + } + else + { + if ((directions & (META_BORDER_MOTION_DIRECTION_POSITIVE_X | + META_BORDER_MOTION_DIRECTION_NEGATIVE_X)) == 0) + return FALSE; + } + + return (~border->blocking_directions & directions) != directions; +} + +unsigned int +meta_border_get_allows_directions (MetaBorder *border) +{ + return ~border->blocking_directions & + (META_BORDER_MOTION_DIRECTION_POSITIVE_X | + META_BORDER_MOTION_DIRECTION_POSITIVE_Y | + META_BORDER_MOTION_DIRECTION_NEGATIVE_X | + META_BORDER_MOTION_DIRECTION_NEGATIVE_Y); +} + +void +meta_border_set_allows_directions (MetaBorder *border, unsigned int directions) +{ + border->blocking_directions = + ~directions & (META_BORDER_MOTION_DIRECTION_POSITIVE_X | + META_BORDER_MOTION_DIRECTION_POSITIVE_Y | + META_BORDER_MOTION_DIRECTION_NEGATIVE_X | + META_BORDER_MOTION_DIRECTION_NEGATIVE_Y); +} diff --git a/src/core/meta-border.h b/src/core/meta-border.h new file mode 100644 index 000000000..dd76db5c9 --- /dev/null +++ b/src/core/meta-border.h @@ -0,0 +1,84 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2015 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +#ifndef META_BORDER_H +#define META_BORDER_H + +#include <glib.h> + +typedef enum +{ + META_BORDER_MOTION_DIRECTION_POSITIVE_X = 1 << 0, + META_BORDER_MOTION_DIRECTION_POSITIVE_Y = 1 << 1, + META_BORDER_MOTION_DIRECTION_NEGATIVE_X = 1 << 2, + META_BORDER_MOTION_DIRECTION_NEGATIVE_Y = 1 << 3, +} MetaBorderMotionDirection; + +typedef struct _MetaVector2 +{ + float x; + float y; +} MetaVector2; + +typedef struct _MetaLine2 +{ + MetaVector2 a; + MetaVector2 b; +} MetaLine2; + +typedef struct _MetaBorder +{ + MetaLine2 line; + MetaBorderMotionDirection blocking_directions; +} MetaBorder; + +static inline MetaVector2 +meta_vector2_subtract (const MetaVector2 a, + const MetaVector2 b) +{ + return (MetaVector2) { + .x = a.x - b.x, + .y = a.y - b.y, + }; +} + +gboolean +meta_line2_intersects_with (const MetaLine2 *line1, + const MetaLine2 *line2, + MetaVector2 *intersection); + +gboolean +meta_border_is_horizontal (MetaBorder *border); + +gboolean +meta_border_is_blocking_directions (MetaBorder *border, + MetaBorderMotionDirection directions); + +unsigned int +meta_border_get_allows_directions (MetaBorder *border); + +void +meta_border_set_allows_directions (MetaBorder *border, unsigned int directions); + +#endif /* META_BORDER_H */ diff --git a/src/core/meta-clipboard-manager.c b/src/core/meta-clipboard-manager.c new file mode 100644 index 000000000..794195f41 --- /dev/null +++ b/src/core/meta-clipboard-manager.c @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2018 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#include "config.h" + +#include "core/meta-clipboard-manager.h" +#include "meta/meta-selection-source-memory.h" + +#define MAX_TEXT_SIZE (4 * 1024 * 1024) /* 4MB */ +#define MAX_IMAGE_SIZE (200 * 1024 * 1024) /* 200MB */ + +/* Supported mimetype globs, from least to most preferred */ +static struct { + const char *mimetype_glob; + ssize_t max_transfer_size; +} supported_mimetypes[] = { + { "image/tiff", MAX_IMAGE_SIZE }, + { "image/bmp", MAX_IMAGE_SIZE }, + { "image/gif", MAX_IMAGE_SIZE }, + { "image/jpeg", MAX_IMAGE_SIZE }, + { "image/webp", MAX_IMAGE_SIZE }, + { "image/png", MAX_IMAGE_SIZE }, + { "image/svg+xml", MAX_IMAGE_SIZE }, + { "text/plain", MAX_TEXT_SIZE }, + { "text/plain;charset=utf-8", MAX_TEXT_SIZE }, +}; + +static gboolean +mimetype_match (const char *mimetype, + int *idx, + gssize *max_transfer_size) +{ + int i; + + for (i = 0; i < G_N_ELEMENTS (supported_mimetypes); i++) + { + if (g_pattern_match_simple (supported_mimetypes[i].mimetype_glob, mimetype)) + { + *max_transfer_size = supported_mimetypes[i].max_transfer_size; + *idx = i; + return TRUE; + } + } + + return FALSE; +} + +static void +transfer_cb (MetaSelection *selection, + GAsyncResult *result, + GOutputStream *output) +{ + MetaDisplay *display = meta_get_display (); + GError *error = NULL; + + if (!meta_selection_transfer_finish (selection, result, &error)) + { + g_warning ("Failed to store clipboard: %s", error->message); + g_error_free (error); + g_object_unref (output); + return; + } + + g_output_stream_close (output, NULL, NULL); + display->saved_clipboard = + g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (output)); + g_object_unref (output); +} + +static void +owner_changed_cb (MetaSelection *selection, + MetaSelectionType selection_type, + MetaSelectionSource *new_owner, + MetaDisplay *display) +{ + if (selection_type != META_SELECTION_CLIPBOARD) + return; + + if (new_owner && new_owner != display->selection_source) + { + GOutputStream *output; + GList *mimetypes, *l; + int best_idx = -1; + const char *best = NULL; + ssize_t transfer_size = -1; + + /* New selection source, find the best mimetype in order to + * keep a copy of it. + */ + g_clear_object (&display->selection_source); + g_clear_pointer (&display->saved_clipboard_mimetype, g_free); + g_clear_pointer (&display->saved_clipboard, g_bytes_unref); + + mimetypes = meta_selection_get_mimetypes (selection, selection_type); + + for (l = mimetypes; l; l = l->next) + { + gssize max_transfer_size; + int idx; + + if (!mimetype_match (l->data, &idx, &max_transfer_size)) + continue; + + if (best_idx < idx) + { + best_idx = idx; + best = l->data; + transfer_size = max_transfer_size; + } + } + + if (best_idx < 0) + { + g_list_free_full (mimetypes, g_free); + return; + } + + display->saved_clipboard_mimetype = g_strdup (best); + g_list_free_full (mimetypes, g_free); + output = g_memory_output_stream_new_resizable (); + meta_selection_transfer_async (selection, + META_SELECTION_CLIPBOARD, + display->saved_clipboard_mimetype, + transfer_size, + output, + NULL, + (GAsyncReadyCallback) transfer_cb, + output); + } + else if (!new_owner && display->saved_clipboard) + { + /* Old owner is gone, time to take over */ + new_owner = meta_selection_source_memory_new (display->saved_clipboard_mimetype, + display->saved_clipboard); + g_set_object (&display->selection_source, new_owner); + meta_selection_set_owner (selection, selection_type, new_owner); + g_object_unref (new_owner); + } +} + +void +meta_clipboard_manager_init (MetaDisplay *display) +{ + MetaSelection *selection; + + selection = meta_display_get_selection (display); + g_signal_connect_after (selection, "owner-changed", + G_CALLBACK (owner_changed_cb), display); +} + +void +meta_clipboard_manager_shutdown (MetaDisplay *display) +{ + MetaSelection *selection; + + g_clear_object (&display->selection_source); + g_clear_pointer (&display->saved_clipboard, g_bytes_unref); + g_clear_pointer (&display->saved_clipboard_mimetype, g_free); + selection = meta_display_get_selection (display); + g_signal_handlers_disconnect_by_func (selection, owner_changed_cb, display); +} diff --git a/src/core/meta-clipboard-manager.h b/src/core/meta-clipboard-manager.h new file mode 100644 index 000000000..2ba130f9b --- /dev/null +++ b/src/core/meta-clipboard-manager.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2018 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef META_CLIPBOARD_MANAGER_H +#define META_CLIPBOARD_MANAGER_H + +#include "core/display-private.h" + +void meta_clipboard_manager_init (MetaDisplay *display); +void meta_clipboard_manager_shutdown (MetaDisplay *display); + +#endif /* META_CLIPBOARD_MANAGER_H */ diff --git a/src/core/meta-close-dialog-default-private.h b/src/core/meta-close-dialog-default-private.h new file mode 100644 index 000000000..f149d3686 --- /dev/null +++ b/src/core/meta-close-dialog-default-private.h @@ -0,0 +1,37 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef META_CLOSE_DIALOG_DEFAULT_H +#define META_CLOSE_DIALOG_DEFAULT_H + +#include <glib-object.h> + +#include "meta/meta-plugin.h" + +#define META_TYPE_CLOSE_DIALOG_DEFAULT (meta_close_dialog_default_get_type ()) +G_DECLARE_FINAL_TYPE (MetaCloseDialogDefault, + meta_close_dialog_default, + META, CLOSE_DIALOG_DEFAULT, + GObject) + +MetaCloseDialog * meta_close_dialog_default_new (MetaWindow *window); + +#endif /* META_CLOSE_DIALOG_DEFAULT_H */ diff --git a/src/core/meta-close-dialog-default.c b/src/core/meta-close-dialog-default.c new file mode 100644 index 000000000..5ea32e205 --- /dev/null +++ b/src/core/meta-close-dialog-default.c @@ -0,0 +1,281 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001, 2002 Havoc Pennington + * Copyright (C) 2004 Elijah Newren + * Copyright (C) 2016 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#define _XOPEN_SOURCE /* for kill() */ + +#include "config.h" + +#include "core/meta-close-dialog-default-private.h" +#include "meta/meta-close-dialog.h" + +#include <sys/types.h> +#include <sys/wait.h> +#include <signal.h> + +#include "core/util-private.h" +#include "core/window-private.h" +#include "x11/meta-x11-display-private.h" + +typedef struct _MetaCloseDialogDefaultPrivate MetaCloseDialogDefaultPrivate; + +struct _MetaCloseDialogDefault +{ + GObject parent_instance; + MetaWindow *window; + int dialog_pid; + guint child_watch_id; +}; + +enum +{ + PROP_0, + PROP_WINDOW, + N_PROPS +}; + +GParamSpec *pspecs[N_PROPS] = { NULL }; + +static void meta_close_dialog_iface_init (MetaCloseDialogInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (MetaCloseDialogDefault, meta_close_dialog_default, + G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (META_TYPE_CLOSE_DIALOG, + meta_close_dialog_iface_init)) + +static void +dialog_exited (GPid pid, + int status, + gpointer user_data) +{ + MetaCloseDialogDefault *dialog = user_data; + + dialog->dialog_pid = -1; + + /* exit status of 0 means the user pressed "Force Quit" */ + if (WIFEXITED (status) && WEXITSTATUS (status) == 0) + g_signal_emit_by_name (dialog, "response", META_CLOSE_DIALOG_RESPONSE_FORCE_CLOSE); +} + +static void +present_existing_delete_dialog (MetaCloseDialogDefault *dialog) +{ + MetaWindow *window; + GSList *windows; + GSList *tmp; + + window = dialog->window; + + if (dialog->dialog_pid < 0) + return; + + meta_topic (META_DEBUG_PING, + "Presenting existing ping dialog for %s\n", + window->desc); + + /* Activate transient for window that belongs to + * mutter-dialog + */ + windows = meta_display_list_windows (window->display, META_LIST_DEFAULT); + tmp = windows; + + while (tmp != NULL) + { + MetaWindow *w = tmp->data; + + if (w->transient_for == window && w->res_class && + g_ascii_strcasecmp (w->res_class, "mutter-dialog") == 0) + { + meta_window_activate (w, CLUTTER_CURRENT_TIME); + break; + } + + tmp = tmp->next; + } + + g_slist_free (windows); +} + +static void +meta_close_dialog_default_show (MetaCloseDialog *dialog) +{ + MetaCloseDialogDefault *dialog_default = META_CLOSE_DIALOG_DEFAULT (dialog); + MetaWindow *window = dialog_default->window; + gchar *window_title, *window_content, *tmp; + GPid dialog_pid; + + if (dialog_default->dialog_pid >= 0) + { + present_existing_delete_dialog (dialog_default); + return; + } + + /* This is to get a better string if the title isn't representable + * in the locale encoding; actual conversion to UTF-8 is done inside + * meta_show_dialog */ + if (window->title && window->title[0]) + { + tmp = g_locale_from_utf8 (window->title, -1, NULL, NULL, NULL); + if (tmp == NULL) + window_title = NULL; + else + window_title = window->title; + g_free (tmp); + } + else + { + window_title = NULL; + } + + if (window_title) + /* Translators: %s is a window title */ + tmp = g_strdup_printf (_("“%s” is not responding."), window_title); + else + tmp = g_strdup (_("Application is not responding.")); + + window_content = g_strdup_printf ( + "<big><b>%s</b></big>\n\n%s", + tmp, + _("You may choose to wait a short while for it to " + "continue or force the application to quit entirely.")); + + dialog_pid = + meta_show_dialog ("--question", + window_content, NULL, + window->display->x11_display->screen_name, + _("_Force Quit"), _("_Wait"), + "face-sad-symbolic", window->xwindow, + NULL, NULL); + + g_free (window_content); + g_free (tmp); + + dialog_default->dialog_pid = dialog_pid; + g_child_watch_add (dialog_pid, dialog_exited, dialog); +} + +static void +meta_close_dialog_default_hide (MetaCloseDialog *dialog) +{ + MetaCloseDialogDefault *dialog_default; + + dialog_default = META_CLOSE_DIALOG_DEFAULT (dialog); + + g_clear_handle_id (&dialog_default->child_watch_id, g_source_remove); + + if (dialog_default->dialog_pid > -1) + { + kill (dialog_default->dialog_pid, SIGTERM); + dialog_default->dialog_pid = -1; + } +} + +static void +meta_close_dialog_iface_init (MetaCloseDialogInterface *iface) +{ + iface->show = meta_close_dialog_default_show; + iface->hide = meta_close_dialog_default_hide; +} + +static void +meta_close_dialog_default_finalize (GObject *object) +{ + MetaCloseDialogDefault *dialog; + + dialog = META_CLOSE_DIALOG_DEFAULT (object); + + g_clear_handle_id (&dialog->child_watch_id, g_source_remove); + + if (dialog->dialog_pid > -1) + { + kill (dialog->dialog_pid, SIGKILL); + dialog->dialog_pid = -1; + } + + G_OBJECT_CLASS (meta_close_dialog_default_parent_class)->finalize (object); +} + +static void +meta_close_dialog_default_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaCloseDialogDefault *dialog; + + dialog = META_CLOSE_DIALOG_DEFAULT (object); + + switch (prop_id) + { + case PROP_WINDOW: + dialog->window = g_value_get_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_close_dialog_default_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaCloseDialogDefault *dialog; + + dialog = META_CLOSE_DIALOG_DEFAULT (object); + + switch (prop_id) + { + case PROP_WINDOW: + g_value_set_object (value, dialog->window); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_close_dialog_default_class_init (MetaCloseDialogDefaultClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_close_dialog_default_finalize; + object_class->set_property = meta_close_dialog_default_set_property; + object_class->get_property = meta_close_dialog_default_get_property; + + g_object_class_override_property (object_class, PROP_WINDOW, "window"); +} + +static void +meta_close_dialog_default_init (MetaCloseDialogDefault *dialog) +{ + dialog->dialog_pid = -1; +} + +MetaCloseDialog * +meta_close_dialog_default_new (MetaWindow *window) +{ + return g_object_new (META_TYPE_CLOSE_DIALOG_DEFAULT, + "window", window, + NULL); +} diff --git a/src/core/meta-close-dialog.c b/src/core/meta-close-dialog.c new file mode 100644 index 000000000..6d24fa570 --- /dev/null +++ b/src/core/meta-close-dialog.c @@ -0,0 +1,144 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#include "config.h" + +#include "core/window-private.h" +#include "meta/meta-close-dialog.h" +#include "meta/meta-enum-types.h" + +enum +{ + RESPONSE, + N_SIGNALS +}; + +guint dialog_signals[N_SIGNALS] = { 0 }; + +static GQuark quark_visible = 0; + +G_DEFINE_INTERFACE (MetaCloseDialog, meta_close_dialog, G_TYPE_OBJECT) + +static void +meta_close_dialog_default_init (MetaCloseDialogInterface *iface) +{ + g_object_interface_install_property (iface, + g_param_spec_object ("window", + "Window", + "Window", + META_TYPE_WINDOW, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + dialog_signals[RESPONSE] = + g_signal_new ("response", + G_TYPE_FROM_INTERFACE (iface), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 1, META_TYPE_CLOSE_DIALOG_RESPONSE); + + quark_visible = g_quark_from_static_string ("meta-close-dialog-visible"); +} + +/** + * meta_close_dialog_show: + * @dialog: a #MetaCloseDialog + * + * Shows the close dialog. + **/ +void +meta_close_dialog_show (MetaCloseDialog *dialog) +{ + MetaCloseDialogInterface *iface; + + g_return_if_fail (META_IS_CLOSE_DIALOG (dialog)); + + iface = META_CLOSE_DIALOG_GET_IFACE (dialog); + iface->show (dialog); + g_object_set_qdata (G_OBJECT (dialog), quark_visible, GINT_TO_POINTER (TRUE)); +} + +/** + * meta_close_dialog_hide: + * @dialog: a #MetaCloseDialog + * + * Hides the close dialog. + **/ +void +meta_close_dialog_hide (MetaCloseDialog *dialog) +{ + MetaCloseDialogInterface *iface; + + g_return_if_fail (META_IS_CLOSE_DIALOG (dialog)); + + iface = META_CLOSE_DIALOG_GET_IFACE (dialog); + iface->hide (dialog); + g_object_steal_qdata (G_OBJECT (dialog), quark_visible); +} + +/** + * meta_close_dialog_response: + * @dialog: a #MetaCloseDialog + * @response: a #MetaCloseDialogResponse + * + * Responds and closes the dialog. To be called by #MetaCloseDialog + * implementations. + **/ +void +meta_close_dialog_response (MetaCloseDialog *dialog, + MetaCloseDialogResponse response) +{ + g_signal_emit (dialog, dialog_signals[RESPONSE], 0, response); + meta_close_dialog_hide (dialog); +} + +/** + * meta_close_dialog_is_visible: + * @dialog: a #MetaCloseDialog + * + * Returns whether @dialog is currently visible. + * + * Returns: #TRUE if @dialog is visible. + **/ +gboolean +meta_close_dialog_is_visible (MetaCloseDialog *dialog) +{ + return GPOINTER_TO_INT (g_object_get_qdata (G_OBJECT (dialog), quark_visible)); +} + +/** + * meta_close_dialog_focus: + * @dialog: a #MetaCloseDialog + * + * Call whenever @dialog should receive keyboard focus, + * usually when the window would. + **/ +void +meta_close_dialog_focus (MetaCloseDialog *dialog) +{ + MetaCloseDialogInterface *iface; + + g_return_if_fail (META_IS_CLOSE_DIALOG (dialog)); + + iface = META_CLOSE_DIALOG_GET_IFACE (dialog); + if (iface->focus) + iface->focus (dialog); +} diff --git a/src/core/meta-fraction.c b/src/core/meta-fraction.c new file mode 100644 index 000000000..8090aa411 --- /dev/null +++ b/src/core/meta-fraction.c @@ -0,0 +1,134 @@ +/* + * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu> + * 2000 Wim Taymans <wtay@chello.be> + * 2002 Thomas Vander Stichele <thomas@apestaart.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * Fraction utility functions in this file comes from gstutils.c in gstreamer. + */ + +#include "config.h" + +#include "core/meta-fraction.h" + +#include <glib.h> +#include <math.h> + +#define MAX_TERMS 30 +#define MIN_DIVISOR 1.0e-10 +#define MAX_ERROR 1.0e-20 + +static int +greatest_common_divisor (int a, + int b) +{ + while (b != 0) + { + int temp = a; + + a = b; + b = temp % b; + } + + return ABS (a); +} + +MetaFraction +meta_fraction_from_double (double src) +{ + double V, F; /* double being converted */ + int N, D; /* will contain the result */ + int A; /* current term in continued fraction */ + int64_t N1, D1; /* numerator, denominator of last approx */ + int64_t N2, D2; /* numerator, denominator of previous approx */ + int i; + int gcd; + gboolean negative = FALSE; + + /* initialize fraction being converted */ + F = src; + if (F < 0.0) + { + F = -F; + negative = TRUE; + } + + V = F; + /* initialize fractions with 1/0, 0/1 */ + N1 = 1; + D1 = 0; + N2 = 0; + D2 = 1; + N = 1; + D = 1; + + for (i = 0; i < MAX_TERMS; i++) + { + /* get next term */ + A = (gint) F; /* no floor() needed, F is always >= 0 */ + /* get new divisor */ + F = F - A; + + /* calculate new fraction in temp */ + N2 = N1 * A + N2; + D2 = D1 * A + D2; + + /* guard against overflow */ + if (N2 > G_MAXINT || D2 > G_MAXINT) + break; + + N = N2; + D = D2; + + /* save last two fractions */ + N2 = N1; + D2 = D1; + N1 = N; + D1 = D; + + /* quit if dividing by zero or close enough to target */ + if (F < MIN_DIVISOR || fabs (V - ((gdouble) N) / D) < MAX_ERROR) + break; + + /* Take reciprocal */ + F = 1 / F; + } + + /* fix for overflow */ + if (D == 0) + { + N = G_MAXINT; + D = 1; + } + + /* fix for negative */ + if (negative) + N = -N; + + /* simplify */ + gcd = greatest_common_divisor (N, D); + if (gcd) + { + N /= gcd; + D /= gcd; + } + + return (MetaFraction) { + .num = N, + .denom = D + }; +} diff --git a/src/core/meta-fraction.h b/src/core/meta-fraction.h new file mode 100644 index 000000000..f7ab294cd --- /dev/null +++ b/src/core/meta-fraction.h @@ -0,0 +1,31 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef META_FRACTION_H +#define META_FRACTION_H + +typedef struct _MetaFraction +{ + int num; + int denom; +} MetaFraction; + +MetaFraction meta_fraction_from_double (double src); + +#endif /* META_FRACTION_H */ diff --git a/src/core/meta-gesture-tracker-private.h b/src/core/meta-gesture-tracker-private.h new file mode 100644 index 000000000..e7bfc5472 --- /dev/null +++ b/src/core/meta-gesture-tracker-private.h @@ -0,0 +1,70 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef META_GESTURE_TRACKER_PRIVATE_H +#define META_GESTURE_TRACKER_PRIVATE_H + +#include <glib-object.h> + +#include "backends/meta-backend-private.h" +#include "clutter/clutter.h" +#include "meta/window.h" + +#define META_TYPE_GESTURE_TRACKER (meta_gesture_tracker_get_type ()) +#define META_GESTURE_TRACKER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_GESTURE_TRACKER, MetaGestureTracker)) +#define META_GESTURE_TRACKER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_GESTURE_TRACKER, MetaGestureTrackerClass)) +#define META_IS_GESTURE_TRACKER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_GESTURE_TRACKER)) +#define META_IS_GESTURE_TRACKER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_GESTURE_TRACKER)) +#define META_GESTURE_TRACKER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_GESTURE_TRACKER, MetaGestureTrackerClass)) + +typedef struct _MetaGestureTracker MetaGestureTracker; +typedef struct _MetaGestureTrackerClass MetaGestureTrackerClass; + +struct _MetaGestureTracker +{ + GObject parent_instance; +}; + +struct _MetaGestureTrackerClass +{ + GObjectClass parent_class; + + void (* state_changed) (MetaGestureTracker *tracker, + ClutterEventSequence *sequence, + MetaSequenceState state); +}; + +GType meta_gesture_tracker_get_type (void) G_GNUC_CONST; + +MetaGestureTracker * meta_gesture_tracker_new (void); + +gboolean meta_gesture_tracker_handle_event (MetaGestureTracker *tracker, + const ClutterEvent *event); +gboolean meta_gesture_tracker_set_sequence_state (MetaGestureTracker *tracker, + ClutterEventSequence *sequence, + MetaSequenceState state); +MetaSequenceState meta_gesture_tracker_get_sequence_state (MetaGestureTracker *tracker, + ClutterEventSequence *sequence); +gint meta_gesture_tracker_get_n_current_touches (MetaGestureTracker *tracker); + +#endif /* META_GESTURE_TRACKER_PRIVATE_H */ diff --git a/src/core/meta-gesture-tracker.c b/src/core/meta-gesture-tracker.c new file mode 100644 index 000000000..9bade0332 --- /dev/null +++ b/src/core/meta-gesture-tracker.c @@ -0,0 +1,581 @@ +/* + * Copyright (C) 2014 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +/** + * SECTION:gesture-tracker + * @Title: MetaGestureTracker + * @Short_Description: Manages gestures on windows/desktop + * + * Forwards touch events to clutter actors, and accepts/rejects touch sequences + * based on the outcome of those. + */ + +#include "config.h" + +#include "core/meta-gesture-tracker-private.h" + +#include "compositor/meta-surface-actor.h" + +#define DISTANCE_THRESHOLD 30 + +typedef struct _MetaGestureTrackerPrivate MetaGestureTrackerPrivate; +typedef struct _GestureActionData GestureActionData; +typedef struct _MetaSequenceInfo MetaSequenceInfo; + +struct _MetaSequenceInfo +{ + MetaGestureTracker *tracker; + ClutterEventSequence *sequence; + MetaSequenceState state; + guint autodeny_timeout_id; + gfloat start_x; + gfloat start_y; +}; + +struct _GestureActionData +{ + ClutterGestureAction *gesture; + MetaSequenceState state; + gulong gesture_begin_id; + gulong gesture_end_id; + gulong gesture_cancel_id; +}; + +struct _MetaGestureTrackerPrivate +{ + GHashTable *sequences; /* Hashtable of ClutterEventSequence->MetaSequenceInfo */ + + MetaSequenceState stage_state; + GArray *stage_gestures; /* Array of GestureActionData */ + GList *listeners; /* List of ClutterGestureAction */ + guint autodeny_timeout; +}; + +enum +{ + PROP_0, + PROP_AUTODENY_TIMEOUT, + PROP_LAST, +}; + +static GParamSpec *obj_props[PROP_LAST]; + +enum +{ + STATE_CHANGED, + N_SIGNALS +}; + +static guint signals[N_SIGNALS] = { 0 }; + +#define DEFAULT_AUTODENY_TIMEOUT 150 + +static void meta_gesture_tracker_untrack_stage (MetaGestureTracker *tracker); + +G_DEFINE_TYPE_WITH_PRIVATE (MetaGestureTracker, meta_gesture_tracker, G_TYPE_OBJECT) + +static void +meta_gesture_tracker_finalize (GObject *object) +{ + MetaGestureTrackerPrivate *priv; + + priv = meta_gesture_tracker_get_instance_private (META_GESTURE_TRACKER (object)); + + g_hash_table_destroy (priv->sequences); + g_array_free (priv->stage_gestures, TRUE); + g_list_free (priv->listeners); + + G_OBJECT_CLASS (meta_gesture_tracker_parent_class)->finalize (object); +} + +static void +meta_gesture_tracker_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaGestureTrackerPrivate *priv; + + priv = meta_gesture_tracker_get_instance_private (META_GESTURE_TRACKER (object)); + + switch (prop_id) + { + case PROP_AUTODENY_TIMEOUT: + priv->autodeny_timeout = g_value_get_uint (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_gesture_tracker_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaGestureTrackerPrivate *priv; + + priv = meta_gesture_tracker_get_instance_private (META_GESTURE_TRACKER (object)); + + switch (prop_id) + { + case PROP_AUTODENY_TIMEOUT: + g_value_set_uint (value, priv->autodeny_timeout); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_gesture_tracker_class_init (MetaGestureTrackerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_gesture_tracker_finalize; + object_class->set_property = meta_gesture_tracker_set_property; + object_class->get_property = meta_gesture_tracker_get_property; + + obj_props[PROP_AUTODENY_TIMEOUT] = g_param_spec_uint ("autodeny-timeout", + "Auto-deny timeout", + "Auto-deny timeout", + 0, G_MAXUINT, DEFAULT_AUTODENY_TIMEOUT, + G_PARAM_STATIC_STRINGS | + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY); + + g_object_class_install_properties (object_class, PROP_LAST, obj_props); + + signals[STATE_CHANGED] = + g_signal_new ("state-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (MetaGestureTrackerClass, state_changed), + NULL, NULL, NULL, + G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_UINT); +} + +static gboolean +autodeny_sequence (gpointer user_data) +{ + MetaSequenceInfo *info = user_data; + + /* Deny the sequence automatically after the given timeout */ + if (info->state == META_SEQUENCE_NONE) + meta_gesture_tracker_set_sequence_state (info->tracker, info->sequence, + META_SEQUENCE_REJECTED); + + info->autodeny_timeout_id = 0; + return G_SOURCE_REMOVE; +} + +static MetaSequenceInfo * +meta_sequence_info_new (MetaGestureTracker *tracker, + const ClutterEvent *event) +{ + MetaGestureTrackerPrivate *priv; + MetaSequenceInfo *info; + guint ms; + + priv = meta_gesture_tracker_get_instance_private (tracker); + ms = priv->autodeny_timeout; + + info = g_slice_new0 (MetaSequenceInfo); + info->tracker = tracker; + info->sequence = event->touch.sequence; + info->state = META_SEQUENCE_NONE; + info->autodeny_timeout_id = g_timeout_add (ms, autodeny_sequence, info); + + clutter_event_get_coords (event, &info->start_x, &info->start_y); + + return info; +} + +static void +meta_sequence_info_free (MetaSequenceInfo *info) +{ + g_clear_handle_id (&info->autodeny_timeout_id, g_source_remove); + + if (info->state == META_SEQUENCE_NONE) + meta_gesture_tracker_set_sequence_state (info->tracker, info->sequence, + META_SEQUENCE_REJECTED); + g_slice_free (MetaSequenceInfo, info); +} + +static gboolean +state_is_applicable (MetaSequenceState prev_state, + MetaSequenceState state) +{ + if (prev_state == META_SEQUENCE_PENDING_END) + return FALSE; + + /* Don't allow reverting to none */ + if (state == META_SEQUENCE_NONE) + return FALSE; + + /* PENDING_END state is final */ + if (prev_state == META_SEQUENCE_PENDING_END) + return FALSE; + + /* Sequences must be accepted/denied before PENDING_END */ + if (prev_state == META_SEQUENCE_NONE && + state == META_SEQUENCE_PENDING_END) + return FALSE; + + /* Make sequences stick to their accepted/denied state */ + if (state != META_SEQUENCE_PENDING_END && + prev_state != META_SEQUENCE_NONE) + return FALSE; + + return TRUE; +} + +static gboolean +meta_gesture_tracker_set_state (MetaGestureTracker *tracker, + MetaSequenceState state) +{ + MetaGestureTrackerPrivate *priv; + ClutterEventSequence *sequence; + GHashTableIter iter; + + priv = meta_gesture_tracker_get_instance_private (tracker); + + if (priv->stage_state != state && + !state_is_applicable (priv->stage_state, state)) + return FALSE; + + g_hash_table_iter_init (&iter, priv->sequences); + priv->stage_state = state; + + while (g_hash_table_iter_next (&iter, (gpointer*) &sequence, NULL)) + meta_gesture_tracker_set_sequence_state (tracker, sequence, state); + + return TRUE; +} + +static gboolean +gesture_begin_cb (ClutterGestureAction *gesture, + ClutterActor *actor, + MetaGestureTracker *tracker) +{ + MetaGestureTrackerPrivate *priv; + + priv = meta_gesture_tracker_get_instance_private (tracker); + + if (!g_list_find (priv->listeners, gesture) && + meta_gesture_tracker_set_state (tracker, META_SEQUENCE_ACCEPTED)) + priv->listeners = g_list_prepend (priv->listeners, gesture); + + return TRUE; +} + +static void +gesture_end_cb (ClutterGestureAction *gesture, + ClutterActor *actor, + MetaGestureTracker *tracker) +{ + MetaGestureTrackerPrivate *priv; + + priv = meta_gesture_tracker_get_instance_private (tracker); + priv->listeners = g_list_remove (priv->listeners, gesture); + + if (!priv->listeners) + meta_gesture_tracker_untrack_stage (tracker); +} + +static void +gesture_cancel_cb (ClutterGestureAction *gesture, + ClutterActor *actor, + MetaGestureTracker *tracker) +{ + MetaGestureTrackerPrivate *priv; + + priv = meta_gesture_tracker_get_instance_private (tracker); + + if (g_list_find (priv->listeners, gesture)) + { + priv->listeners = g_list_remove (priv->listeners, gesture); + + if (!priv->listeners) + meta_gesture_tracker_set_state (tracker, META_SEQUENCE_PENDING_END); + } +} + +static gboolean +cancel_and_unref_gesture_cb (ClutterGestureAction *action) +{ + clutter_gesture_action_cancel (action); + g_object_unref (action); + return G_SOURCE_REMOVE; +} + +static void +clear_gesture_data (GestureActionData *data) +{ + g_clear_signal_handler (&data->gesture_begin_id, data->gesture); + g_clear_signal_handler (&data->gesture_end_id, data->gesture); + g_clear_signal_handler (&data->gesture_cancel_id, data->gesture); + + /* Defer cancellation to an idle, as it may happen within event handling */ + g_idle_add ((GSourceFunc) cancel_and_unref_gesture_cb, data->gesture); +} + +static void +meta_gesture_tracker_init (MetaGestureTracker *tracker) +{ + MetaGestureTrackerPrivate *priv; + + priv = meta_gesture_tracker_get_instance_private (tracker); + priv->sequences = g_hash_table_new_full (NULL, NULL, NULL, + (GDestroyNotify) meta_sequence_info_free); + priv->stage_gestures = g_array_new (FALSE, FALSE, sizeof (GestureActionData)); + g_array_set_clear_func (priv->stage_gestures, (GDestroyNotify) clear_gesture_data); +} + +MetaGestureTracker * +meta_gesture_tracker_new (void) +{ + return g_object_new (META_TYPE_GESTURE_TRACKER, NULL); +} + +static void +meta_gesture_tracker_track_stage (MetaGestureTracker *tracker, + ClutterActor *stage) +{ + MetaGestureTrackerPrivate *priv; + GList *actions, *l; + + priv = meta_gesture_tracker_get_instance_private (tracker); + actions = clutter_actor_get_actions (stage); + + for (l = actions; l; l = l->next) + { + GestureActionData data; + + if (!CLUTTER_IS_GESTURE_ACTION (l->data)) + continue; + + data.gesture = g_object_ref (l->data); + data.state = META_SEQUENCE_NONE; + data.gesture_begin_id = + g_signal_connect (data.gesture, "gesture-begin", + G_CALLBACK (gesture_begin_cb), tracker); + data.gesture_end_id = + g_signal_connect (data.gesture, "gesture-end", + G_CALLBACK (gesture_end_cb), tracker); + data.gesture_cancel_id = + g_signal_connect (data.gesture, "gesture-cancel", + G_CALLBACK (gesture_cancel_cb), tracker); + g_array_append_val (priv->stage_gestures, data); + } + + g_list_free (actions); +} + +static void +meta_gesture_tracker_untrack_stage (MetaGestureTracker *tracker) +{ + MetaGestureTrackerPrivate *priv; + + priv = meta_gesture_tracker_get_instance_private (tracker); + priv->stage_state = META_SEQUENCE_NONE; + + g_hash_table_remove_all (priv->sequences); + + if (priv->stage_gestures->len > 0) + g_array_remove_range (priv->stage_gestures, 0, priv->stage_gestures->len); + + g_list_free (priv->listeners); + priv->listeners = NULL; +} + +gboolean +meta_gesture_tracker_handle_event (MetaGestureTracker *tracker, + const ClutterEvent *event) +{ + MetaGestureTrackerPrivate *priv; + ClutterEventSequence *sequence; + MetaSequenceState state; + MetaSequenceInfo *info; + ClutterActor *stage; + gfloat x, y; + + sequence = clutter_event_get_event_sequence (event); + + if (!sequence) + return FALSE; + + priv = meta_gesture_tracker_get_instance_private (tracker); + stage = CLUTTER_ACTOR (clutter_event_get_stage (event)); + + switch (event->type) + { + case CLUTTER_TOUCH_BEGIN: + if (g_hash_table_size (priv->sequences) == 0) + meta_gesture_tracker_track_stage (tracker, stage); + + info = meta_sequence_info_new (tracker, event); + g_hash_table_insert (priv->sequences, sequence, info); + + if (priv->stage_gestures->len == 0) + { + /* If no gestures are attached, reject the sequence right away */ + meta_gesture_tracker_set_sequence_state (tracker, sequence, + META_SEQUENCE_REJECTED); + } + else if (priv->stage_state != META_SEQUENCE_NONE) + { + /* Make the sequence state match the general state */ + meta_gesture_tracker_set_sequence_state (tracker, sequence, + priv->stage_state); + } + state = info->state; + break; + case CLUTTER_TOUCH_END: + info = g_hash_table_lookup (priv->sequences, sequence); + + if (!info) + return FALSE; + + /* If nothing was done yet about the sequence, reject it so X11 + * clients may see it + */ + if (info->state == META_SEQUENCE_NONE) + meta_gesture_tracker_set_sequence_state (tracker, sequence, + META_SEQUENCE_REJECTED); + + state = info->state; + g_hash_table_remove (priv->sequences, sequence); + + if (g_hash_table_size (priv->sequences) == 0) + meta_gesture_tracker_untrack_stage (tracker); + break; + case CLUTTER_TOUCH_UPDATE: + info = g_hash_table_lookup (priv->sequences, sequence); + + if (!info) + return FALSE; + + clutter_event_get_coords (event, &x, &y); + + if (info->state == META_SEQUENCE_NONE && + (ABS (info->start_x - x) > DISTANCE_THRESHOLD || + ABS (info->start_y - y) > DISTANCE_THRESHOLD)) + meta_gesture_tracker_set_sequence_state (tracker, sequence, + META_SEQUENCE_REJECTED); + state = info->state; + break; + default: + return FALSE; + break; + } + + /* As soon as a sequence is accepted, we replay it to + * the stage as a captured event, and make sure it's never + * propagated anywhere else. Since ClutterGestureAction does + * all its event handling from a captured-event handler on + * the stage, this effectively acts as a "sequence grab" on + * gesture actions. + * + * Sequences that aren't (yet or never) in an accepted state + * will go through, these events will get processed through + * the compositor, and eventually through clutter, still + * triggering the gestures capturing events on the stage, and + * possibly resulting in MetaSequenceState changes. + */ + if (state == META_SEQUENCE_ACCEPTED) + { + clutter_actor_event (CLUTTER_ACTOR (clutter_event_get_stage (event)), + event, TRUE); + return TRUE; + } + + return FALSE; +} + +gboolean +meta_gesture_tracker_set_sequence_state (MetaGestureTracker *tracker, + ClutterEventSequence *sequence, + MetaSequenceState state) +{ + MetaGestureTrackerPrivate *priv; + MetaSequenceInfo *info; + + g_return_val_if_fail (META_IS_GESTURE_TRACKER (tracker), FALSE); + + priv = meta_gesture_tracker_get_instance_private (tracker); + info = g_hash_table_lookup (priv->sequences, sequence); + + if (!info) + return FALSE; + else if (state == info->state) + return TRUE; + + if (!state_is_applicable (info->state, state)) + return FALSE; + + /* Unset autodeny timeout */ + g_clear_handle_id (&info->autodeny_timeout_id, g_source_remove); + + info->state = state; + g_signal_emit (tracker, signals[STATE_CHANGED], 0, sequence, info->state); + + /* If the sequence was denied, set immediately to PENDING_END after emission */ + if (state == META_SEQUENCE_REJECTED) + { + info->state = META_SEQUENCE_PENDING_END; + g_signal_emit (tracker, signals[STATE_CHANGED], 0, sequence, info->state); + } + + return TRUE; +} + +MetaSequenceState +meta_gesture_tracker_get_sequence_state (MetaGestureTracker *tracker, + ClutterEventSequence *sequence) +{ + MetaGestureTrackerPrivate *priv; + MetaSequenceInfo *info; + + g_return_val_if_fail (META_IS_GESTURE_TRACKER (tracker), META_SEQUENCE_PENDING_END); + + priv = meta_gesture_tracker_get_instance_private (tracker); + info = g_hash_table_lookup (priv->sequences, sequence); + + if (!info) + return META_SEQUENCE_PENDING_END; + + return info->state; +} + +gint +meta_gesture_tracker_get_n_current_touches (MetaGestureTracker *tracker) +{ + MetaGestureTrackerPrivate *priv; + + g_return_val_if_fail (META_IS_GESTURE_TRACKER (tracker), 0); + + priv = meta_gesture_tracker_get_instance_private (tracker); + return g_hash_table_size (priv->sequences); +} diff --git a/src/core/meta-inhibit-shortcuts-dialog-default-private.h b/src/core/meta-inhibit-shortcuts-dialog-default-private.h new file mode 100644 index 000000000..7f65494ef --- /dev/null +++ b/src/core/meta-inhibit-shortcuts-dialog-default-private.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + */ + +#ifndef META_INHIBIT_SHORTCUTS_DIALOG_DEFAULT_H +#define META_INHIBIT_SHORTCUTS_DIALOG_DEFAULT_H + +#include <glib-object.h> + +#include "meta/meta-plugin.h" + +#define META_TYPE_INHIBIT_SHORTCUTS_DIALOG_DEFAULT (meta_inhibit_shortcuts_dialog_default_get_type ()) +G_DECLARE_FINAL_TYPE (MetaInhibitShortcutsDialogDefault, + meta_inhibit_shortcuts_dialog_default, + META, INHIBIT_SHORTCUTS_DIALOG_DEFAULT, + GObject) + +MetaInhibitShortcutsDialog * meta_inhibit_shortcuts_dialog_default_new (MetaWindow *window); + +#endif /* META_INHIBIT_SHORTCUTS_DIALOG_DEFAULT_H */ diff --git a/src/core/meta-inhibit-shortcuts-dialog-default.c b/src/core/meta-inhibit-shortcuts-dialog-default.c new file mode 100644 index 000000000..d90234d6a --- /dev/null +++ b/src/core/meta-inhibit-shortcuts-dialog-default.c @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2001, 2002 Havoc Pennington + * Copyright (C) 2004 Elijah Newren + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include "core/meta-inhibit-shortcuts-dialog-default-private.h" +#include "core/util-private.h" +#include "core/window-private.h" +#include "meta/meta-inhibit-shortcuts-dialog.h" + +typedef struct _MetaInhibitShortcutsDialogDefaultPrivate MetaInhibitShortcutsDialogDefaultPrivate; + +struct _MetaInhibitShortcutsDialogDefault +{ + GObject parent_instance; + MetaWindow *window; +}; + +enum +{ + PROP_0, + PROP_WINDOW, + N_PROPS +}; + +static void meta_inhibit_shortcuts_dialog_iface_init (MetaInhibitShortcutsDialogInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (MetaInhibitShortcutsDialogDefault, meta_inhibit_shortcuts_dialog_default, + G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (META_TYPE_INHIBIT_SHORTCUTS_DIALOG, + meta_inhibit_shortcuts_dialog_iface_init)) + +static void +meta_inhibit_shortcuts_dialog_default_show (MetaInhibitShortcutsDialog *dialog) +{ + /* Default to allow shortcuts inhibitor, but complain that no dialog is implemented */ + g_warning ("No MetaInhibitShortcutDialog implementation, falling back on allowing"); + meta_inhibit_shortcuts_dialog_response (dialog, META_INHIBIT_SHORTCUTS_DIALOG_RESPONSE_ALLOW); +} + +static void +meta_inhibit_shortcuts_dialog_default_hide (MetaInhibitShortcutsDialog *dialog) +{ +} + +static void +meta_inhibit_shortcuts_dialog_iface_init (MetaInhibitShortcutsDialogInterface *iface) +{ + iface->show = meta_inhibit_shortcuts_dialog_default_show; + iface->hide = meta_inhibit_shortcuts_dialog_default_hide; +} + +static void +meta_inhibit_shortcuts_dialog_default_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaInhibitShortcutsDialogDefault *dialog; + + dialog = META_INHIBIT_SHORTCUTS_DIALOG_DEFAULT (object); + + switch (prop_id) + { + case PROP_WINDOW: + dialog->window = g_value_get_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_inhibit_shortcuts_dialog_default_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaInhibitShortcutsDialogDefault *dialog; + + dialog = META_INHIBIT_SHORTCUTS_DIALOG_DEFAULT (object); + + switch (prop_id) + { + case PROP_WINDOW: + g_value_set_object (value, dialog->window); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_inhibit_shortcuts_dialog_default_class_init (MetaInhibitShortcutsDialogDefaultClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->set_property = meta_inhibit_shortcuts_dialog_default_set_property; + object_class->get_property = meta_inhibit_shortcuts_dialog_default_get_property; + + g_object_class_override_property (object_class, PROP_WINDOW, "window"); +} + +static void +meta_inhibit_shortcuts_dialog_default_init (MetaInhibitShortcutsDialogDefault *dialog) +{ +} + +MetaInhibitShortcutsDialog * +meta_inhibit_shortcuts_dialog_default_new (MetaWindow *window) +{ + return g_object_new (META_TYPE_INHIBIT_SHORTCUTS_DIALOG_DEFAULT, + "window", window, + NULL); +} diff --git a/src/core/meta-inhibit-shortcuts-dialog.c b/src/core/meta-inhibit-shortcuts-dialog.c new file mode 100644 index 000000000..d5b4e5a05 --- /dev/null +++ b/src/core/meta-inhibit-shortcuts-dialog.c @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include "core/window-private.h" +#include "meta/meta-inhibit-shortcuts-dialog.h" +#include "meta/meta-enum-types.h" + +enum +{ + RESPONSE, + LAST_SIGNAL +}; + +static guint inhibit_dialog_signals[LAST_SIGNAL] = { 0, }; + +G_DEFINE_INTERFACE (MetaInhibitShortcutsDialog, meta_inhibit_shortcuts_dialog, G_TYPE_OBJECT) + +static void +meta_inhibit_shortcuts_dialog_default_init (MetaInhibitShortcutsDialogInterface *iface) +{ + g_object_interface_install_property (iface, + g_param_spec_object ("window", + "Window", + "Window", + META_TYPE_WINDOW, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + inhibit_dialog_signals[RESPONSE] = + g_signal_new ("response", + G_TYPE_FROM_INTERFACE (iface), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 1, META_TYPE_INHIBIT_SHORTCUTS_DIALOG_RESPONSE); +} + +/** + * meta_inhibit_shortcuts_dialog_show: + * @dialog: a #MetaInhibitShortcutsDialog + * + * Shows the inhibit shortcuts dialog. + **/ +void +meta_inhibit_shortcuts_dialog_show (MetaInhibitShortcutsDialog *dialog) +{ + MetaInhibitShortcutsDialogInterface *iface; + + g_return_if_fail (META_IS_INHIBIT_SHORTCUTS_DIALOG (dialog)); + + iface = META_INHIBIT_SHORTCUTS_DIALOG_GET_IFACE (dialog); + iface->show (dialog); +} + +/** + * meta_inhibit_shortcuts_dialog_hide: + * @dialog: a #MetaInhibitShortcutsDialog + * + * Hides the inhibit shortcuts dialog. + **/ +void +meta_inhibit_shortcuts_dialog_hide (MetaInhibitShortcutsDialog *dialog) +{ + MetaInhibitShortcutsDialogInterface *iface; + + g_return_if_fail (META_IS_INHIBIT_SHORTCUTS_DIALOG (dialog)); + + iface = META_INHIBIT_SHORTCUTS_DIALOG_GET_IFACE (dialog); + iface->hide (dialog); +} + +/** + * meta_inhibit_shortcuts_dialog_response: + * @dialog: a #MetaInhibitShortcutsDialog + * @response: a #MetaInhibitShortcutsDialogResponse + * + * Responds and closes the dialog. To be called by #MetaInhibitShortcutsDialog + * implementations. + **/ +void +meta_inhibit_shortcuts_dialog_response (MetaInhibitShortcutsDialog *dialog, + MetaInhibitShortcutsDialogResponse response) +{ + g_signal_emit (dialog, inhibit_dialog_signals[RESPONSE], 0, response); + meta_inhibit_shortcuts_dialog_hide (dialog); +} diff --git a/src/core/meta-launch-context.c b/src/core/meta-launch-context.c new file mode 100644 index 000000000..984338c1b --- /dev/null +++ b/src/core/meta-launch-context.c @@ -0,0 +1,269 @@ +/* + * Copyright (C) 2018 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#include "config.h" + +#include <gio/gdesktopappinfo.h> + +#include "core/display-private.h" +#include "meta/meta-launch-context.h" +#include "x11/meta-startup-notification-x11.h" + +typedef struct _MetaLaunchContext MetaLaunchContext; + +struct _MetaLaunchContext +{ + GAppLaunchContext parent_instance; + MetaDisplay *display; + MetaWorkspace *workspace; + uint32_t timestamp; +}; + +G_DEFINE_TYPE (MetaLaunchContext, meta_launch_context, + G_TYPE_APP_LAUNCH_CONTEXT) + +enum +{ + PROP_DISPLAY = 1, + PROP_WORKSPACE, + PROP_TIMESTAMP, + N_PROPS +}; + +static GParamSpec *props[N_PROPS] = { 0, }; + +static void +meta_launch_context_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaLaunchContext *context = META_LAUNCH_CONTEXT (object); + + switch (prop_id) + { + case PROP_DISPLAY: + context->display = g_value_get_object (value); + break; + case PROP_WORKSPACE: + meta_launch_context_set_workspace (context, + g_value_get_object (value)); + break; + case PROP_TIMESTAMP: + meta_launch_context_set_timestamp (context, + g_value_get_uint (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_launch_context_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaLaunchContext *context = META_LAUNCH_CONTEXT (object); + + switch (prop_id) + { + case PROP_DISPLAY: + g_value_set_object (value, context->display); + break; + case PROP_WORKSPACE: + g_value_set_object (value, context->workspace); + break; + case PROP_TIMESTAMP: + g_value_set_uint (value, context->timestamp); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_launch_context_finalize (GObject *object) +{ + G_OBJECT_CLASS (meta_launch_context_parent_class)->finalize (object); +} + +static void +meta_launch_context_constructed (GObject *object) +{ + MetaLaunchContext *context = META_LAUNCH_CONTEXT (object); + const char *x11_display, *wayland_display; + + G_OBJECT_CLASS (meta_launch_context_parent_class)->constructed (object); + + x11_display = getenv ("DISPLAY"); + wayland_display = getenv ("WAYLAND_DISPLAY"); + + if (x11_display) + { + g_app_launch_context_setenv (G_APP_LAUNCH_CONTEXT (context), + "DISPLAY", x11_display); + } + + if (wayland_display) + { + g_app_launch_context_setenv (G_APP_LAUNCH_CONTEXT (context), + "WAYLAND_DISPLAY", wayland_display); + } +} + +static gchar * +meta_launch_context_get_startup_notify_id (GAppLaunchContext *launch_context, + GAppInfo *info, + GList *files) +{ + MetaLaunchContext *context = META_LAUNCH_CONTEXT (launch_context); + MetaDisplay *display = context->display; + int workspace_idx = -1; + char *startup_id = NULL; + + if (context->workspace) + workspace_idx = meta_workspace_index (context->workspace); + + if (display->x11_display) + { + /* If there is a X11 display, we prefer going entirely through + * libsn, as SnMonitor expects to keep a view of the full lifetime + * of the startup sequence. We can't avoid it when launching and + * expect that a "remove" message from a X11 client will be handled. + */ + startup_id = + meta_x11_startup_notification_launch (display->x11_display, + info, + context->timestamp, + workspace_idx); + } + + if (!startup_id) + { + const char *application_id = NULL; + MetaStartupNotification *sn; + MetaStartupSequence *seq; + + startup_id = g_uuid_string_random (); + + /* Fallback through inserting our own startup sequence, this + * will be enough for wayland clients. + */ + if (G_IS_DESKTOP_APP_INFO (info)) + { + application_id = + g_desktop_app_info_get_filename (G_DESKTOP_APP_INFO (info)); + } + + sn = meta_display_get_startup_notification (context->display); + seq = g_object_new (META_TYPE_STARTUP_SEQUENCE, + "id", startup_id, + "application-id", application_id, + "name", g_app_info_get_name (info), + "workspace", workspace_idx, + "timestamp", context->timestamp, + NULL); + + meta_startup_notification_add_sequence (sn, seq); + g_object_unref (seq); + } + + return startup_id; +} + +static void +meta_launch_context_launch_failed (GAppLaunchContext *launch_context, + const gchar *startup_notify_id) +{ + MetaLaunchContext *context = META_LAUNCH_CONTEXT (launch_context); + MetaStartupNotification *sn; + MetaStartupSequence *seq; + + sn = meta_display_get_startup_notification (context->display); + seq = meta_startup_notification_lookup_sequence (sn, startup_notify_id); + + if (seq) + { + meta_startup_sequence_complete (seq); + meta_startup_notification_remove_sequence (sn, seq); + } +} + +static void +meta_launch_context_class_init (MetaLaunchContextClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GAppLaunchContextClass *ctx_class = G_APP_LAUNCH_CONTEXT_CLASS (klass); + + object_class->finalize = meta_launch_context_finalize; + object_class->constructed = meta_launch_context_constructed; + object_class->set_property = meta_launch_context_set_property; + object_class->get_property = meta_launch_context_get_property; + + ctx_class->get_startup_notify_id = meta_launch_context_get_startup_notify_id; + ctx_class->launch_failed = meta_launch_context_launch_failed; + + props[PROP_DISPLAY] = + g_param_spec_object ("display", + "display", + "Display", + META_TYPE_DISPLAY, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + props[PROP_WORKSPACE] = + g_param_spec_object ("workspace", + "workspace", + "Workspace", + META_TYPE_WORKSPACE, + G_PARAM_READWRITE); + props[PROP_TIMESTAMP] = + g_param_spec_uint ("timestamp", + "timestamp", + "Timestamp", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE); + + g_object_class_install_properties (object_class, N_PROPS, props); +} + +static void +meta_launch_context_init (MetaLaunchContext *context) +{ +} + +void +meta_launch_context_set_workspace (MetaLaunchContext *context, + MetaWorkspace *workspace) +{ + g_return_if_fail (META_IS_LAUNCH_CONTEXT (context)); + g_return_if_fail (META_IS_WORKSPACE (workspace)); + + g_set_object (&context->workspace, workspace); +} + +void +meta_launch_context_set_timestamp (MetaLaunchContext *context, + uint32_t timestamp) +{ + g_return_if_fail (META_IS_LAUNCH_CONTEXT (context)); + + context->timestamp = timestamp; +} diff --git a/src/core/meta-selection-private.h b/src/core/meta-selection-private.h new file mode 100644 index 000000000..de9caf9bf --- /dev/null +++ b/src/core/meta-selection-private.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2020 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef META_SELECTION_PRIVATE_H +#define META_SELECTION_PRIVATE_H + +#include "meta/meta-selection.h" + +MetaSelectionSource * + meta_selection_get_current_owner (MetaSelection *selection, + MetaSelectionType selection_type); + +#endif /* META_SELECTION_PRIVATE_H */ diff --git a/src/core/meta-selection-source-memory.c b/src/core/meta-selection-source-memory.c new file mode 100644 index 000000000..a52f50861 --- /dev/null +++ b/src/core/meta-selection-source-memory.c @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2018 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#include "config.h" + +#include "meta/meta-selection-source-memory.h" + +struct _MetaSelectionSourceMemory +{ + MetaSelectionSource parent_instance; + char *mimetype; + GBytes *content; +}; + +G_DEFINE_TYPE (MetaSelectionSourceMemory, + meta_selection_source_memory, + META_TYPE_SELECTION_SOURCE) + +static void +meta_selection_source_memory_read_async (MetaSelectionSource *source, + const char *mimetype, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + MetaSelectionSourceMemory *source_mem = META_SELECTION_SOURCE_MEMORY (source); + GInputStream *stream; + g_autoptr (GTask) task = NULL; + + if (g_strcmp0 (mimetype, source_mem->mimetype) != 0) + { + g_task_report_new_error (source, callback, user_data, + meta_selection_source_memory_read_async, + G_IO_ERROR, G_IO_ERROR_FAILED, + "Mimetype not in selection"); + return; + } + + task = g_task_new (source, cancellable, callback, user_data); + g_task_set_source_tag (task, meta_selection_source_memory_read_async); + + stream = g_memory_input_stream_new_from_bytes (source_mem->content); + g_task_return_pointer (task, stream, g_object_unref); +} + +static GInputStream * +meta_selection_source_memory_read_finish (MetaSelectionSource *source, + GAsyncResult *result, + GError **error) +{ + g_assert (g_task_get_source_tag (G_TASK (result)) == + meta_selection_source_memory_read_async); + return g_task_propagate_pointer (G_TASK (result), error); +} + +static GList * +meta_selection_source_memory_get_mimetypes (MetaSelectionSource *source) +{ + MetaSelectionSourceMemory *source_mem = META_SELECTION_SOURCE_MEMORY (source); + + if (!source_mem->mimetype) + return NULL; + + return g_list_prepend (NULL, g_strdup (source_mem->mimetype)); +} + +static void +meta_selection_source_memory_finalize (GObject *object) +{ + MetaSelectionSourceMemory *source_mem = META_SELECTION_SOURCE_MEMORY (object); + + g_clear_pointer (&source_mem->content, g_bytes_unref); + g_free (source_mem->mimetype); + + G_OBJECT_CLASS (meta_selection_source_memory_parent_class)->finalize (object); +} + +static void +meta_selection_source_memory_class_init (MetaSelectionSourceMemoryClass *klass) +{ + MetaSelectionSourceClass *source_class = META_SELECTION_SOURCE_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_selection_source_memory_finalize; + + source_class->read_async = meta_selection_source_memory_read_async; + source_class->read_finish = meta_selection_source_memory_read_finish; + source_class->get_mimetypes = meta_selection_source_memory_get_mimetypes; +} + +static void +meta_selection_source_memory_init (MetaSelectionSourceMemory *source) +{ +} + +MetaSelectionSource * +meta_selection_source_memory_new (const char *mimetype, + GBytes *content) +{ + MetaSelectionSourceMemory *source; + + g_return_val_if_fail (mimetype != NULL, NULL); + g_return_val_if_fail (content != NULL, NULL); + + source = g_object_new (META_TYPE_SELECTION_SOURCE_MEMORY, NULL); + source->mimetype = g_strdup (mimetype); + source->content = g_bytes_ref (content); + + return META_SELECTION_SOURCE (source); +} diff --git a/src/core/meta-selection-source.c b/src/core/meta-selection-source.c new file mode 100644 index 000000000..b076391ce --- /dev/null +++ b/src/core/meta-selection-source.c @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2018 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#include "config.h" + +#include "meta/meta-selection.h" +#include "meta/meta-selection-source.h" + +typedef struct MetaSelectionSourcePrivate MetaSelectionSourcePrivate; + +struct MetaSelectionSourcePrivate +{ + guint active : 1; +}; + +G_DEFINE_TYPE_WITH_PRIVATE (MetaSelectionSource, + meta_selection_source, + G_TYPE_OBJECT) + +enum +{ + ACTIVE, + INACTIVE, + N_SIGNALS +}; + +static guint signals[N_SIGNALS] = { 0 }; + +static void +meta_selection_source_activated (MetaSelectionSource *source) +{ + MetaSelectionSourcePrivate *priv = + meta_selection_source_get_instance_private (source); + + priv->active = TRUE; +} + +static void +meta_selection_source_deactivated (MetaSelectionSource *source) +{ + MetaSelectionSourcePrivate *priv = + meta_selection_source_get_instance_private (source); + + priv->active = FALSE; +} + +static void +meta_selection_source_class_init (MetaSelectionSourceClass *klass) +{ + klass->activated = meta_selection_source_activated; + klass->deactivated = meta_selection_source_deactivated; + + signals[ACTIVE] = + g_signal_new ("activated", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (MetaSelectionSourceClass, activated), + NULL, NULL, NULL, + G_TYPE_NONE, 0); + signals[INACTIVE] = + g_signal_new ("deactivated", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (MetaSelectionSourceClass, deactivated), + NULL, NULL, NULL, + G_TYPE_NONE, 0); +} + +static void +meta_selection_source_init (MetaSelectionSource *source) +{ +} + +void +meta_selection_source_read_async (MetaSelectionSource *source, + const gchar *mimetype, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail (META_IS_SELECTION_SOURCE (source)); + g_return_if_fail (mimetype != NULL); + g_return_if_fail (callback != NULL); + + META_SELECTION_SOURCE_GET_CLASS (source)->read_async (source, + mimetype, + cancellable, + callback, + user_data); +} + +/** + * meta_selection_source_read_finish: + * @source: The selection source + * @result: The async result + * @error: Location for returned error + * + * Finishes a read from the selection source. + * + * Returns: (transfer full): The resulting #GInputStream + */ +GInputStream * +meta_selection_source_read_finish (MetaSelectionSource *source, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (META_IS_SELECTION_SOURCE (source), NULL); + g_return_val_if_fail (g_task_is_valid (result, source), NULL); + + return META_SELECTION_SOURCE_GET_CLASS (source)->read_finish (source, + result, + error); +} + +/** + * meta_selection_source_get_mimetypes: + * @source: The selection source + * + * Returns the list of supported mimetypes. + * + * Returns: (element-type utf8) (transfer full): The supported mimetypes + */ +GList * +meta_selection_source_get_mimetypes (MetaSelectionSource *source) +{ + g_return_val_if_fail (META_IS_SELECTION_SOURCE (source), NULL); + + return META_SELECTION_SOURCE_GET_CLASS (source)->get_mimetypes (source); +} + +/** + * meta_selection_source_is_active: + * @source: the selection source + * + * Returns #TRUE if the source is active on a selection. + * + * Returns: #TRUE if the source owns a selection. + **/ +gboolean +meta_selection_source_is_active (MetaSelectionSource *source) +{ + MetaSelectionSourcePrivate *priv = + meta_selection_source_get_instance_private (source); + + g_return_val_if_fail (META_IS_SELECTION_SOURCE (source), FALSE); + + return priv->active; +} diff --git a/src/core/meta-selection.c b/src/core/meta-selection.c new file mode 100644 index 000000000..4e42e59a9 --- /dev/null +++ b/src/core/meta-selection.c @@ -0,0 +1,415 @@ +/* + * Copyright (C) 2018 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#include "config.h" + +#include "core/meta-selection-private.h" +#include "meta/meta-selection.h" + +typedef struct TransferRequest TransferRequest; + +struct _MetaSelection +{ + GObject parent_instance; + MetaDisplay *display; + MetaSelectionSource *owners[META_N_SELECTION_TYPES]; +}; + +struct TransferRequest +{ + MetaSelectionType selection_type; + GInputStream *istream; + GOutputStream *ostream; + gssize len; +}; + +enum +{ + OWNER_CHANGED, + N_SIGNALS +}; + +static guint signals[N_SIGNALS] = { 0 }; + +G_DEFINE_TYPE (MetaSelection, meta_selection, G_TYPE_OBJECT) + +static void read_selection_source_async (GTask *task, + TransferRequest *request); + +static void +meta_selection_dispose (GObject *object) +{ + MetaSelection *selection = META_SELECTION (object); + guint i; + + for (i = 0; i < META_N_SELECTION_TYPES; i++) + { + g_clear_object (&selection->owners[i]); + } + + G_OBJECT_CLASS (meta_selection_parent_class)->dispose (object); +} + +static void +meta_selection_class_init (MetaSelectionClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = meta_selection_dispose; + + signals[OWNER_CHANGED] = + g_signal_new ("owner-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 2, + G_TYPE_UINT, + META_TYPE_SELECTION_SOURCE); +} + +static void +meta_selection_init (MetaSelection *selection) +{ +} + +MetaSelection * +meta_selection_new (MetaDisplay *display) +{ + return g_object_new (META_TYPE_SELECTION, + NULL); +} + +/** + * meta_selection_set_owner: + * @selection: The selection manager + * @selection_type: Selection type + * @owner: New selection owner + * + * Sets @owner as the owner of the selection given by @selection_type, + * unsets any previous owner there was. + **/ +void +meta_selection_set_owner (MetaSelection *selection, + MetaSelectionType selection_type, + MetaSelectionSource *owner) +{ + g_return_if_fail (META_IS_SELECTION (selection)); + g_return_if_fail (selection_type < META_N_SELECTION_TYPES); + + if (selection->owners[selection_type] == owner) + return; + + if (selection->owners[selection_type]) + g_signal_emit_by_name (selection->owners[selection_type], "deactivated"); + + g_set_object (&selection->owners[selection_type], owner); + g_signal_emit_by_name (owner, "activated"); + g_signal_emit (selection, signals[OWNER_CHANGED], 0, selection_type, owner); +} + +/** + * meta_selection_unset_owner: + * @selection: The selection manager + * @selection_type: Selection type + * @owner: Owner to unset + * + * Unsets @owner as the owner the selection given by @selection_type. If + * @owner does not own the selection, nothing is done. + **/ +void +meta_selection_unset_owner (MetaSelection *selection, + MetaSelectionType selection_type, + MetaSelectionSource *owner) +{ + g_return_if_fail (META_IS_SELECTION (selection)); + g_return_if_fail (selection_type < META_N_SELECTION_TYPES); + + if (selection->owners[selection_type] == owner) + { + g_signal_emit_by_name (owner, "deactivated"); + g_clear_object (&selection->owners[selection_type]); + g_signal_emit (selection, signals[OWNER_CHANGED], 0, + selection_type, NULL); + } +} + +/** + * meta_selection_get_mimetypes: + * @selection: The selection manager + * @selection_type: Selection to query + * + * Returns the list of supported mimetypes for the given selection type. + * + * Returns: (element-type utf8) (transfer full): The supported mimetypes + */ +GList * +meta_selection_get_mimetypes (MetaSelection *selection, + MetaSelectionType selection_type) +{ + g_return_val_if_fail (META_IS_SELECTION (selection), NULL); + g_return_val_if_fail (selection_type < META_N_SELECTION_TYPES, NULL); + + if (!selection->owners[selection_type]) + return NULL; + + return meta_selection_source_get_mimetypes (selection->owners[selection_type]); +} + +static TransferRequest * +transfer_request_new (GOutputStream *ostream, + MetaSelectionType selection_type, + gssize len) +{ + TransferRequest *request; + + request = g_new0 (TransferRequest, 1); + request->ostream = g_object_ref (ostream); + request->selection_type = selection_type; + request->len = len; + return request; +} + +static void +transfer_request_free (TransferRequest *request) +{ + g_clear_object (&request->istream); + g_clear_object (&request->ostream); + g_free (request); +} + +static void +splice_cb (GOutputStream *stream, + GAsyncResult *result, + GTask *task) +{ + GError *error = NULL; + + g_output_stream_splice_finish (stream, result, &error); + if (error) + { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + g_task_return_boolean (task, TRUE); + g_object_unref (task); +} + +static void +write_cb (GOutputStream *stream, + GAsyncResult *result, + GTask *task) +{ + TransferRequest *request; + GError *error = NULL; + + g_output_stream_write_bytes_finish (stream, result, &error); + if (error) + { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + request = g_task_get_task_data (task); + + if (request->len > 0) + { + read_selection_source_async (task, request); + } + else + { + g_task_return_boolean (task, TRUE); + g_object_unref (task); + } +} + +static void +read_cb (GInputStream *stream, + GAsyncResult *result, + GTask *task) +{ + TransferRequest *request; + GError *error = NULL; + GBytes *bytes; + + bytes = g_input_stream_read_bytes_finish (stream, result, &error); + if (error) + { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + else if (g_bytes_get_size (bytes) == 0) + { + g_task_return_boolean (task, TRUE); + g_object_unref (task); + return; + } + + request = g_task_get_task_data (task); + + if (request->len < g_bytes_get_size (bytes)) + { + GBytes *copy; + + /* Trim content */ + copy = g_bytes_new_from_bytes (bytes, 0, request->len); + g_bytes_unref (bytes); + bytes = copy; + } + + request->len -= g_bytes_get_size (bytes); + g_output_stream_write_bytes_async (request->ostream, + bytes, + G_PRIORITY_DEFAULT, + g_task_get_cancellable (task), + (GAsyncReadyCallback) write_cb, + task); + g_bytes_unref (bytes); +} + +static void +read_selection_source_async (GTask *task, + TransferRequest *request) +{ + g_input_stream_read_bytes_async (request->istream, + (gsize) request->len, + G_PRIORITY_DEFAULT, + g_task_get_cancellable (task), + (GAsyncReadyCallback) read_cb, + task); +} + +static void +source_read_cb (MetaSelectionSource *source, + GAsyncResult *result, + GTask *task) +{ + TransferRequest *request; + GInputStream *stream; + GError *error = NULL; + + stream = meta_selection_source_read_finish (source, result, &error); + if (!stream) + { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + request = g_task_get_task_data (task); + request->istream = stream; + + if (request->len < 0) + { + g_output_stream_splice_async (request->ostream, + request->istream, + G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | + G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, + G_PRIORITY_DEFAULT, + g_task_get_cancellable (task), + (GAsyncReadyCallback) splice_cb, + task); + } + else + { + read_selection_source_async (task, request); + } +} + +/** + * meta_selection_transfer_async: + * @selection: The selection manager + * @selection_type: Selection type + * @mimetype: Mimetype to transfer + * @size: Maximum size to transfer, -1 for unlimited + * @output: Output stream to write contents to + * @cancellable: Cancellable + * @callback: User callback + * @user_data: User data + * + * Requests a transfer of @mimetype on the selection given by + * @selection_type. + **/ +void +meta_selection_transfer_async (MetaSelection *selection, + MetaSelectionType selection_type, + const char *mimetype, + gssize size, + GOutputStream *output, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + g_return_if_fail (META_IS_SELECTION (selection)); + g_return_if_fail (selection_type < META_N_SELECTION_TYPES); + g_return_if_fail (G_IS_OUTPUT_STREAM (output)); + g_return_if_fail (mimetype != NULL); + + task = g_task_new (selection, cancellable, callback, user_data); + g_task_set_source_tag (task, meta_selection_transfer_async); + + g_task_set_task_data (task, + transfer_request_new (output, selection_type, size), + (GDestroyNotify) transfer_request_free); + meta_selection_source_read_async (selection->owners[selection_type], + mimetype, + cancellable, + (GAsyncReadyCallback) source_read_cb, + task); +} + +/** + * meta_selection_transfer_finish: + * @selection: The selection manager + * @result: The async result + * @error: Location for returned error, or %NULL + * + * Finishes the transfer of a queried mimetype. + * + * Returns: #TRUE if the transfer was successful. + **/ +gboolean +meta_selection_transfer_finish (MetaSelection *selection, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, selection), FALSE); + g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == + meta_selection_transfer_async, FALSE); + + return g_task_propagate_boolean (G_TASK (result), error); +} + +MetaSelectionSource * +meta_selection_get_current_owner (MetaSelection *selection, + MetaSelectionType selection_type) +{ + g_return_val_if_fail (META_IS_SELECTION (selection), NULL); + g_return_val_if_fail (selection_type < META_N_SELECTION_TYPES, NULL); + + return selection->owners[selection_type]; +} diff --git a/src/core/meta-sound-player.c b/src/core/meta-sound-player.c new file mode 100644 index 000000000..930b95a99 --- /dev/null +++ b/src/core/meta-sound-player.c @@ -0,0 +1,291 @@ +/* + * Copyright (C) 2018 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#include "config.h" + +#include <canberra.h> + +#include "meta/meta-sound-player.h" + +#define EVENT_SOUNDS_KEY "event-sounds" +#define THEME_NAME_KEY "theme-name" + +typedef struct _MetaPlayRequest MetaPlayRequest; + +struct _MetaSoundPlayer +{ + GObject parent; + GThreadPool *queue; + GSettings *settings; + ca_context *context; + uint32_t id_pool; +}; + +struct _MetaPlayRequest +{ + ca_proplist *props; + uint32_t id; + gulong cancel_id; + GCancellable *cancellable; + MetaSoundPlayer *player; +}; + +const char * const cache_whitelist[] = { + "bell-window-system", + "desktop-switch-left", + "desktop-switch-right", + "desktop-switch-up", + "desktop-switch-down", + NULL +}; + +G_DEFINE_TYPE (MetaSoundPlayer, meta_sound_player, G_TYPE_OBJECT) + +static MetaPlayRequest * +meta_play_request_new (MetaSoundPlayer *player, + ca_proplist *props, + GCancellable *cancellable) +{ + MetaPlayRequest *req; + + req = g_new0 (MetaPlayRequest, 1); + req->props = props; + req->player = player; + g_set_object (&req->cancellable, cancellable); + + return req; +} + +static void +meta_play_request_free (MetaPlayRequest *req) +{ + g_clear_object (&req->cancellable); + ca_proplist_destroy (req->props); + g_free (req); +} + +static void +meta_sound_player_finalize (GObject *object) +{ + MetaSoundPlayer *player = META_SOUND_PLAYER (object); + + g_object_unref (player->settings); + g_thread_pool_free (player->queue, FALSE, TRUE); + ca_context_destroy (player->context); + + G_OBJECT_CLASS (meta_sound_player_parent_class)->finalize (object); +} + +static void +meta_sound_player_class_init (MetaSoundPlayerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_sound_player_finalize; +} + +static void +cancelled_cb (GCancellable *cancellable, + MetaPlayRequest *req) +{ + ca_context_cancel (req->player->context, req->id); +} + +static void +finish_cb (ca_context *context, + uint32_t id, + int error_code, + gpointer user_data) +{ + MetaPlayRequest *req = user_data; + + if (error_code != CA_ERROR_CANCELED) + g_cancellable_disconnect (req->cancellable, req->cancel_id); + else if (req->cancellable != NULL) + g_clear_signal_handler (&req->cancel_id, req->cancellable); + + meta_play_request_free (req); +} + +static void +play_sound (MetaPlayRequest *req, + MetaSoundPlayer *player) +{ + req->id = player->id_pool++; + + if (ca_context_play_full (player->context, req->id, req->props, + finish_cb, req) != CA_SUCCESS) + { + meta_play_request_free (req); + return; + } + + if (req->cancellable) + { + gulong cancel_id = + g_cancellable_connect (req->cancellable, + G_CALLBACK (cancelled_cb), req, NULL); + if (cancel_id) + req->cancel_id = cancel_id; + } +} + +static void +settings_changed_cb (GSettings *settings, + const char *key, + MetaSoundPlayer *player) +{ + if (strcmp (key, EVENT_SOUNDS_KEY) == 0) + { + gboolean enabled; + + enabled = g_settings_get_boolean (settings, EVENT_SOUNDS_KEY); + ca_context_change_props (player->context, CA_PROP_CANBERRA_ENABLE, + enabled ? "1" : "0", NULL); + } + else if (strcmp (key, THEME_NAME_KEY) == 0) + { + char *theme_name; + + theme_name = g_settings_get_string (settings, THEME_NAME_KEY); + ca_context_change_props (player->context, CA_PROP_CANBERRA_XDG_THEME_NAME, + theme_name, NULL); + g_free (theme_name); + } +} + +static ca_context * +create_context (MetaSoundPlayer *player) +{ + ca_context *context; + ca_proplist *props; + + if (ca_context_create (&context) != CA_SUCCESS) + return NULL; + + if (ca_proplist_create (&props) != CA_SUCCESS) + { + ca_context_destroy (context); + return NULL; + } + + ca_proplist_sets (props, CA_PROP_APPLICATION_NAME, "Muffin"); + + ca_proplist_sets (props, CA_PROP_CANBERRA_ENABLE, "1"); + settings_changed_cb (player->settings, EVENT_SOUNDS_KEY, player); + settings_changed_cb (player->settings, THEME_NAME_KEY, player); + + ca_context_change_props_full (context, props); + ca_proplist_destroy (props); + + return context; +} + +static void +meta_sound_player_init (MetaSoundPlayer *player) +{ + player->queue = g_thread_pool_new ((GFunc) play_sound, + player, 1, FALSE, NULL); + player->settings = g_settings_new ("org.cinnamon.desktop.sound"); + player->context = create_context (player); + + g_signal_connect (player->settings, "changed", + G_CALLBACK (settings_changed_cb), player); +} + +static void +build_ca_proplist (ca_proplist *props, + const char *event_property, + const char *event_id, + const char *event_description) +{ + ca_proplist_sets (props, event_property, event_id); + ca_proplist_sets (props, CA_PROP_EVENT_DESCRIPTION, event_description); +} + +/** + * meta_sound_player_play_from_theme: + * @player: a #MetaSoundPlayer + * @name: sound theme name of the event + * @description: description of the event + * @cancellable: cancellable for the request + * + * Plays a sound from the sound theme. + **/ +void +meta_sound_player_play_from_theme (MetaSoundPlayer *player, + const char *name, + const char *description, + GCancellable *cancellable) +{ + MetaPlayRequest *req; + ca_proplist *props; + + g_return_if_fail (META_IS_SOUND_PLAYER (player)); + g_return_if_fail (name != NULL); + g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable)); + + ca_proplist_create (&props); + build_ca_proplist (props, CA_PROP_EVENT_ID, name, description); + + if (g_strv_contains (cache_whitelist, name)) + ca_proplist_sets (props, CA_PROP_CANBERRA_CACHE_CONTROL, "permanent"); + else + ca_proplist_sets (props, CA_PROP_CANBERRA_CACHE_CONTROL, "volatile"); + + req = meta_play_request_new (player, props, cancellable); + g_thread_pool_push (player->queue, req, NULL); +} + +/** + * meta_sound_player_play_from_file: + * @player: a #MetaSoundPlayer + * @file: file to play + * @description: description of the played sound + * @cancellable: cancellable for the request + * + * Plays a sound from a file. + **/ +void +meta_sound_player_play_from_file (MetaSoundPlayer *player, + GFile *file, + const char *description, + GCancellable *cancellable) +{ + MetaPlayRequest *req; + ca_proplist *props; + char *path; + + g_return_if_fail (META_IS_SOUND_PLAYER (player)); + g_return_if_fail (G_IS_FILE (file)); + g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable)); + + path = g_file_get_path (file); + g_return_if_fail (path != NULL); + + ca_proplist_create (&props); + build_ca_proplist (props, CA_PROP_MEDIA_FILENAME, path, description); + ca_proplist_sets (props, CA_PROP_CANBERRA_CACHE_CONTROL, "volatile"); + g_free (path); + + req = meta_play_request_new (player, props, cancellable); + g_thread_pool_push (player->queue, req, NULL); +} diff --git a/src/core/meta-workspace-manager-private.h b/src/core/meta-workspace-manager-private.h new file mode 100644 index 000000000..261c4d47c --- /dev/null +++ b/src/core/meta-workspace-manager-private.h @@ -0,0 +1,96 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001 Havoc Pennington + * Copyright (C) 2002, 2003, 2004 Red Hat, Inc. + * Copyright (C) 2003, 2004 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef META_WORKSPACE_MANAGER_PRIVATE_H +#define META_WORKSPACE_MANAGER_PRIVATE_H + +#include <glib.h> + +#include "core/display-private.h" +#include "meta/common.h" +#include "meta/types.h" +#include "meta/meta-workspace-manager.h" + +struct _MetaWorkspaceManager +{ + GObject parent; + + MetaDisplay *display; + MetaWorkspace *active_workspace; + + GList *workspaces; + + int rows_of_workspaces; + int columns_of_workspaces; + MetaDisplayCorner starting_corner; + guint vertical_workspaces : 1; + guint workspace_layout_overridden : 1; +}; + +MetaWorkspaceManager *meta_workspace_manager_new (MetaDisplay *display); + +void meta_workspace_manager_init_workspaces (MetaWorkspaceManager *workspace_manager); +void meta_workspace_manager_update_workspace_layout (MetaWorkspaceManager *workspace_manager, + MetaDisplayCorner starting_corner, + gboolean vertical_layout, + int n_rows, + int n_columns); + +void meta_workspace_manager_reload_work_areas (MetaWorkspaceManager *workspace_manager); + +typedef struct MetaWorkspaceLayout MetaWorkspaceLayout; + +struct MetaWorkspaceLayout +{ + int rows; + int cols; + int *grid; + int grid_area; + int current_row; + int current_col; +}; + +void meta_workspace_manager_calc_workspace_layout (MetaWorkspaceManager *workspace_manager, + int num_workspaces, + int current_space, + MetaWorkspaceLayout *layout); + +void meta_workspace_manager_free_workspace_layout (MetaWorkspaceLayout *layout); + +void meta_workspace_manager_minimize_all_on_active_workspace_except (MetaWorkspaceManager *workspace_manager, + MetaWindow *keep); + +/* Show/hide the desktop (temporarily hide all windows) */ +void meta_workspace_manager_show_desktop (MetaWorkspaceManager *workspace_manager, + guint32 timestamp); +void meta_workspace_manager_unshow_desktop (MetaWorkspaceManager *workspace_manager); + +void meta_workspace_manager_workspace_switched (MetaWorkspaceManager *workspace_manager, + int from, + int to, + MetaMotionDirection direction); + +void meta_workspace_manager_update_num_workspaces (MetaWorkspaceManager *workspace_manager, + guint32 timestamp, + int new_num); + +#endif /* META_WORKSPACE_MANAGER_PRIVATE_H */ diff --git a/src/core/meta-workspace-manager.c b/src/core/meta-workspace-manager.c new file mode 100644 index 000000000..36d0b9bcd --- /dev/null +++ b/src/core/meta-workspace-manager.c @@ -0,0 +1,1061 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001 Havoc Pennington + * Copyright (C) 2002, 2003, 2004 Red Hat, Inc. + * Copyright (C) 2003, 2004 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include "core/meta-workspace-manager-private.h" + +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "core/window-private.h" +#include "core/workspace-private.h" +#include "meta/meta-enum-types.h" +#include "meta/prefs.h" +#include "meta/util.h" + +G_DEFINE_TYPE (MetaWorkspaceManager, meta_workspace_manager, G_TYPE_OBJECT) + +enum +{ + WORKSPACE_ADDED, + WORKSPACE_REMOVED, + WORKSPACE_SWITCHED, + WORKSPACES_REORDERED, + ACTIVE_WORKSPACE_CHANGED, + SHOWING_DESKTOP_CHANGED, + LAST_SIGNAL +}; + +enum +{ + PROP_0, + + PROP_LAYOUT_COLUMNS, + PROP_LAYOUT_ROWS, + + PROP_N_WORKSPACES +}; + +static guint workspace_manager_signals [LAST_SIGNAL] = { 0 }; + +static void prefs_changed_callback (MetaPreference pref, + gpointer data); + +static void +meta_workspace_manager_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaWorkspaceManager *workspace_manager = META_WORKSPACE_MANAGER (object); + + switch (prop_id) + { + case PROP_LAYOUT_COLUMNS: + g_value_set_int (value, workspace_manager->columns_of_workspaces); + break; + case PROP_LAYOUT_ROWS: + g_value_set_int (value, workspace_manager->rows_of_workspaces); + break; + case PROP_N_WORKSPACES: + g_value_set_int (value, meta_workspace_manager_get_n_workspaces (workspace_manager)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_workspace_manager_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_workspace_manager_finalize (GObject *object) +{ + MetaWorkspaceManager *workspace_manager = META_WORKSPACE_MANAGER (object); + + meta_prefs_remove_listener (prefs_changed_callback, workspace_manager); + + G_OBJECT_CLASS (meta_workspace_manager_parent_class)->finalize (object); +} + +static void +meta_workspace_manager_class_init (MetaWorkspaceManagerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = meta_workspace_manager_get_property; + object_class->set_property = meta_workspace_manager_set_property; + + object_class->finalize = meta_workspace_manager_finalize; + + workspace_manager_signals[WORKSPACE_ADDED] = + g_signal_new ("workspace-added", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, + 1, + G_TYPE_INT); + + workspace_manager_signals[WORKSPACE_REMOVED] = + g_signal_new ("workspace-removed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, + 1, + G_TYPE_INT); + + workspace_manager_signals[WORKSPACE_SWITCHED] = + g_signal_new ("workspace-switched", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, + 3, + G_TYPE_INT, + G_TYPE_INT, + META_TYPE_MOTION_DIRECTION); + + /* Emitted when calling meta_workspace_manager_reorder_workspace. + * + * This signal is emitted when a workspace has been reordered to + * a different index. Note that other workspaces can change + * their index too when reordering happens. + */ + workspace_manager_signals[WORKSPACES_REORDERED] = + g_signal_new ("workspaces-reordered", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); + + workspace_manager_signals[ACTIVE_WORKSPACE_CHANGED] = + g_signal_new ("active-workspace-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 0); + + workspace_manager_signals[SHOWING_DESKTOP_CHANGED] = + g_signal_new ("showing-desktop-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 0); + + g_object_class_install_property (object_class, + PROP_LAYOUT_COLUMNS, + g_param_spec_int ("layout-columns", + "Layout columns", + "Number of columns in layout", + -1, G_MAXINT, 1, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, + PROP_LAYOUT_ROWS, + g_param_spec_int ("layout-rows", + "Layout rows", + "Number of rows in layout", + -1, G_MAXINT, -1, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, + PROP_N_WORKSPACES, + g_param_spec_int ("n-workspaces", + "N Workspaces", + "Number of workspaces", + 1, G_MAXINT, 1, + G_PARAM_READABLE)); +} + +static void +meta_workspace_manager_init (MetaWorkspaceManager *workspace_manager) +{ +} + +void +meta_workspace_manager_reload_work_areas (MetaWorkspaceManager *workspace_manager) +{ + GList *l; + + for (l = workspace_manager->workspaces; l; l = l->next) + { + MetaWorkspace *workspace = l->data; + + meta_workspace_invalidate_work_area (workspace); + } +} + +MetaWorkspaceManager * +meta_workspace_manager_new (MetaDisplay *display) +{ + MetaWorkspaceManager *workspace_manager; + + workspace_manager = g_object_new (META_TYPE_WORKSPACE_MANAGER, NULL); + + workspace_manager->display = display; + workspace_manager->active_workspace = NULL; + workspace_manager->workspaces = NULL; + workspace_manager->rows_of_workspaces = 1; + workspace_manager->columns_of_workspaces = -1; + workspace_manager->vertical_workspaces = FALSE; + workspace_manager->starting_corner = META_DISPLAY_TOPLEFT; + + /* This is the default layout extracted from default + * variable values in update_num_workspaces () + * This can be overriden using _NET_DESKTOP_LAYOUT in + * meta_x11_display_new (), if it's specified */ + meta_workspace_manager_update_workspace_layout (workspace_manager, + META_DISPLAY_TOPLEFT, + FALSE, + -1, + 1); + + /* There must be at least one workspace at all times, + * so create that required workspace. + */ + meta_workspace_new (workspace_manager); + + meta_workspace_manager_init_workspaces (workspace_manager); + + meta_prefs_add_listener (prefs_changed_callback, workspace_manager); + + return workspace_manager; +} + +void +meta_workspace_manager_init_workspaces (MetaWorkspaceManager *workspace_manager) +{ + int num; + + g_return_if_fail (META_IS_WORKSPACE_MANAGER (workspace_manager)); + + if (meta_prefs_get_dynamic_workspaces ()) + /* This will be properly updated using _NET_NUMBER_OF_DESKTOPS + * (if set) in meta_x11_display_new () */ + num = 1; + else + num = meta_prefs_get_num_workspaces (); + + meta_workspace_manager_update_num_workspaces (workspace_manager, META_CURRENT_TIME, num); + + meta_workspace_activate (workspace_manager->workspaces->data, META_CURRENT_TIME); + + meta_workspace_manager_reload_work_areas (workspace_manager); +} + +int +meta_workspace_manager_get_n_workspaces (MetaWorkspaceManager *workspace_manager) +{ + return g_list_length (workspace_manager->workspaces); +} + +/** + * meta_workspace_manager_get_workspace_by_index: + * @workspace_manager: a #MetaWorkspaceManager + * @index: index of one of the display's workspaces + * + * Gets the workspace object for one of a workspace manager's workspaces given the workspace + * index. It's valid to call this function with an out-of-range index and it + * will robustly return %NULL. + * + * Return value: (transfer none) (nullable): the workspace object with specified + * index, or %NULL if the index is out of range. + */ +MetaWorkspace * +meta_workspace_manager_get_workspace_by_index (MetaWorkspaceManager *workspace_manager, + int idx) +{ + return g_list_nth_data (workspace_manager->workspaces, idx); +} + +void +meta_workspace_manager_remove_workspace (MetaWorkspaceManager *workspace_manager, + MetaWorkspace *workspace, + guint32 timestamp) +{ + GList *l; + GList *next; + MetaWorkspace *neighbour = NULL; + int index; + int active_index; + gboolean active_index_changed; + int new_num; + + l = g_list_find (workspace_manager->workspaces, workspace); + if (!l) + return; + + next = l->next; + + if (l->prev) + neighbour = l->prev->data; + else if (l->next) + neighbour = l->next->data; + else + { + /* Cannot remove the only workspace! */ + return; + } + + meta_workspace_relocate_windows (workspace, neighbour); + + if (workspace == workspace_manager->active_workspace) + meta_workspace_activate (neighbour, timestamp); + + /* To emit the signal after removing the workspace */ + index = meta_workspace_index (workspace); + active_index = meta_workspace_manager_get_active_workspace_index (workspace_manager); + active_index_changed = index < active_index; + + /* This also removes the workspace from the displays list */ + meta_workspace_remove (workspace); + + new_num = g_list_length (workspace_manager->workspaces); + + if (!meta_prefs_get_dynamic_workspaces ()) + meta_prefs_set_num_workspaces (new_num); + + /* If deleting a workspace before the current workspace, the active + * workspace index changes, so we need to update that hint */ + if (active_index_changed) + g_signal_emit (workspace_manager, + workspace_manager_signals[ACTIVE_WORKSPACE_CHANGED], + 0, NULL); + + for (l = next; l; l = l->next) + { + MetaWorkspace *w = l->data; + meta_workspace_index_changed (w); + } + + meta_display_queue_workarea_recalc (workspace_manager->display); + + g_signal_emit (workspace_manager, + workspace_manager_signals[WORKSPACE_REMOVED], + 0, index); + g_object_notify (G_OBJECT (workspace_manager), "n-workspaces"); +} + +/** + * meta_workspace_manager_append_new_workspace: + * @workspace_manager: a #MetaWorkspaceManager + * @activate: %TRUE if the workspace should be switched to after creation + * @timestamp: if switching to a new workspace, timestamp to be used when + * focusing a window on the new workspace. (Doesn't hurt to pass a valid + * timestamp when available even if not switching workspaces.) + * + * Append a new workspace to the workspace manager and (optionally) switch to that + * display. + * + * Return value: (transfer none): the newly appended workspace. + */ +MetaWorkspace * +meta_workspace_manager_append_new_workspace (MetaWorkspaceManager *workspace_manager, + gboolean activate, + guint32 timestamp) +{ + MetaWorkspace *w; + int new_num; + + /* This also adds the workspace to the workspace manager list */ + w = meta_workspace_new (workspace_manager); + + if (!w) + return NULL; + + if (activate) + meta_workspace_activate (w, timestamp); + + new_num = g_list_length (workspace_manager->workspaces); + + if (!meta_prefs_get_dynamic_workspaces ()) + meta_prefs_set_num_workspaces (new_num); + + meta_display_queue_workarea_recalc (workspace_manager->display); + + g_signal_emit (workspace_manager, workspace_manager_signals[WORKSPACE_ADDED], + 0, meta_workspace_index (w)); + g_object_notify (G_OBJECT (workspace_manager), "n-workspaces"); + + return w; +} + +void +meta_workspace_manager_update_num_workspaces (MetaWorkspaceManager *workspace_manager, + guint32 timestamp, + int new_num) +{ + int old_num; + GList *l; + int i = 0; + GList *extras = NULL; + MetaWorkspace *last_remaining = NULL; + gboolean need_change_space = FALSE; + + g_assert (new_num > 0); + + if (g_list_length (workspace_manager->workspaces) == (guint) new_num) + return; + + for (l = workspace_manager->workspaces; l; l = l->next) + { + MetaWorkspace *w = l->data; + + if (i >= new_num) + extras = g_list_prepend (extras, w); + else + last_remaining = w; + + ++i; + } + old_num = i; + + g_assert (last_remaining); + + /* Get rid of the extra workspaces by moving all their windows + * to last_remaining, then activating last_remaining if + * one of the removed workspaces was active. This will be a bit + * wacky if the config tool for changing number of workspaces + * is on a removed workspace ;-) + */ + for (l = extras; l; l = l->next) + { + MetaWorkspace *w = l->data; + + meta_workspace_relocate_windows (w, last_remaining); + + if (w == workspace_manager->active_workspace) + need_change_space = TRUE; + } + + if (need_change_space) + meta_workspace_activate (last_remaining, timestamp); + + /* Should now be safe to free the workspaces */ + for (l = extras; l; l = l->next) + { + MetaWorkspace *w = l->data; + + meta_workspace_remove (w); + } + + g_list_free (extras); + + for (i = old_num; i < new_num; i++) + meta_workspace_new (workspace_manager); + + meta_display_queue_workarea_recalc (workspace_manager->display); + + for (i = old_num; i < new_num; i++) + g_signal_emit (workspace_manager, + workspace_manager_signals[WORKSPACE_ADDED], + 0, i); + + g_object_notify (G_OBJECT (workspace_manager), "n-workspaces"); +} + +/** + * meta_workspace_manager_reorder_workspace: + * @workspace_manager: a #MetaWorkspaceManager + * @workspace: a #MetaWorkspace to reorder + * @new_index: the new index of the passed workspace + * + * Reorder a workspace to a new index. If the workspace is currently active + * the "active-workspace-changed" signal will be emited. + * If the workspace's index is the same as @new_index or the workspace + * will not be found in the list, this function will return. + * + * Calling this function will also emit the "workspaces-reordered" signal. + */ +void +meta_workspace_manager_reorder_workspace (MetaWorkspaceManager *workspace_manager, + MetaWorkspace *workspace, + int new_index) +{ + GList *l; + GList *from, *to; + int index; + int active_index, new_active_index; + + g_return_if_fail (META_IS_WORKSPACE_MANAGER (workspace_manager)); + g_return_if_fail (new_index >= 0 && + new_index < g_list_length (workspace_manager->workspaces)); + + l = g_list_find (workspace_manager->workspaces, workspace); + g_return_if_fail (l); + + index = meta_workspace_index (workspace); + + if (new_index == index) + return; + + active_index = + meta_workspace_manager_get_active_workspace_index (workspace_manager); + + workspace_manager->workspaces = + g_list_remove_link (workspace_manager->workspaces, l); + + workspace_manager->workspaces = + g_list_insert (workspace_manager->workspaces, l->data, new_index); + + g_list_free (l); + + new_active_index = + meta_workspace_manager_get_active_workspace_index (workspace_manager); + + if (active_index != new_active_index) + g_signal_emit (workspace_manager, + workspace_manager_signals[ACTIVE_WORKSPACE_CHANGED], + 0, NULL); + + from = g_list_nth (workspace_manager->workspaces, MIN (new_index, index)); + to = g_list_nth (workspace_manager->workspaces, MAX (new_index, index)); + for (l = from; l != to->next; l = l->next) + { + MetaWorkspace *w = l->data; + + meta_workspace_index_changed (w); + } + + meta_display_queue_workarea_recalc (workspace_manager->display); + g_signal_emit (workspace_manager, + workspace_manager_signals[WORKSPACES_REORDERED], 0, NULL); +} + +void +meta_workspace_manager_update_workspace_layout (MetaWorkspaceManager *workspace_manager, + MetaDisplayCorner starting_corner, + gboolean vertical_layout, + int n_rows, + int n_columns) +{ + g_return_if_fail (META_IS_WORKSPACE_MANAGER (workspace_manager)); + g_return_if_fail (n_rows > 0 || n_columns > 0); + g_return_if_fail (n_rows != 0 && n_columns != 0); + + if (workspace_manager->workspace_layout_overridden) + return; + + workspace_manager->vertical_workspaces = vertical_layout != FALSE; + workspace_manager->starting_corner = starting_corner; + workspace_manager->rows_of_workspaces = n_rows; + workspace_manager->columns_of_workspaces = n_columns; + + meta_verbose ("Workspace layout rows = %d cols = %d orientation = %d starting corner = %u\n", + workspace_manager->rows_of_workspaces, + workspace_manager->columns_of_workspaces, + workspace_manager->vertical_workspaces, + workspace_manager->starting_corner); + g_object_notify (G_OBJECT (workspace_manager), "layout-columns"); + g_object_notify (G_OBJECT (workspace_manager), "layout-rows"); +} + +/** + * meta_workspace_manager_override_workspace_layout: + * @workspace_manager: a #MetaWorkspaceManager + * @starting_corner: the corner at which the first workspace is found + * @vertical_layout: if %TRUE the workspaces are laid out in columns rather than rows + * @n_rows: number of rows of workspaces, or -1 to determine the number of rows from + * @n_columns and the total number of workspaces + * @n_columns: number of columns of workspaces, or -1 to determine the number of columns from + * @n_rows and the total number of workspaces + * + * Explicitly set the layout of workspaces. Once this has been called, the contents of the + * _NET_DESKTOP_LAYOUT property on the root window are completely ignored. + */ +void +meta_workspace_manager_override_workspace_layout (MetaWorkspaceManager *workspace_manager, + MetaDisplayCorner starting_corner, + gboolean vertical_layout, + int n_rows, + int n_columns) +{ + workspace_manager->workspace_layout_overridden = FALSE; + + meta_workspace_manager_update_workspace_layout (workspace_manager, + starting_corner, + vertical_layout, + n_rows, + n_columns); + + workspace_manager->workspace_layout_overridden = TRUE; +} + +#ifdef WITH_VERBOSE_MODE +static const char * +meta_workspace_manager_corner_to_string (MetaDisplayCorner corner) +{ + switch (corner) + { + case META_DISPLAY_TOPLEFT: + return "TopLeft"; + case META_DISPLAY_TOPRIGHT: + return "TopRight"; + case META_DISPLAY_BOTTOMLEFT: + return "BottomLeft"; + case META_DISPLAY_BOTTOMRIGHT: + return "BottomRight"; + } + + return "Unknown"; +} +#endif /* WITH_VERBOSE_MODE */ + +void +meta_workspace_manager_calc_workspace_layout (MetaWorkspaceManager *workspace_manager, + int num_workspaces, + int current_space, + MetaWorkspaceLayout *layout) +{ + int rows, cols; + int grid_area; + int *grid; + int i, r, c; + int current_row, current_col; + + rows = workspace_manager->rows_of_workspaces; + cols = workspace_manager->columns_of_workspaces; + if (rows <= 0 && cols <= 0) + cols = num_workspaces; + + if (rows <= 0) + rows = num_workspaces / cols + ((num_workspaces % cols) > 0 ? 1 : 0); + if (cols <= 0) + cols = num_workspaces / rows + ((num_workspaces % rows) > 0 ? 1 : 0); + + /* paranoia */ + if (rows < 1) + rows = 1; + if (cols < 1) + cols = 1; + + g_assert (rows != 0 && cols != 0); + + grid_area = rows * cols; + + meta_verbose ("Getting layout rows = %d cols = %d current = %d " + "num_spaces = %d vertical = %s corner = %s\n", + rows, cols, current_space, num_workspaces, + workspace_manager->vertical_workspaces ? "(true)" : "(false)", + meta_workspace_manager_corner_to_string (workspace_manager->starting_corner)); + + /* ok, we want to setup the distances in the workspace array to go + * in each direction. Remember, there are many ways that a workspace + * array can be setup. + * see http://www.freedesktop.org/standards/wm-spec/1.2/html/x109.html + * and look at the _NET_DESKTOP_LAYOUT section for details. + * For instance: + */ + /* starting_corner = META_DISPLAY_TOPLEFT + * vertical_workspaces = 0 vertical_workspaces=1 + * 1234 1357 + * 5678 2468 + * + * starting_corner = META_DISPLAY_TOPRIGHT + * vertical_workspaces = 0 vertical_workspaces=1 + * 4321 7531 + * 8765 8642 + * + * starting_corner = META_DISPLAY_BOTTOMLEFT + * vertical_workspaces = 0 vertical_workspaces=1 + * 5678 2468 + * 1234 1357 + * + * starting_corner = META_DISPLAY_BOTTOMRIGHT + * vertical_workspaces = 0 vertical_workspaces=1 + * 8765 8642 + * 4321 7531 + * + */ + /* keep in mind that we could have a ragged layout, e.g. the "8" + * in the above grids could be missing + */ + + + grid = g_new (int, grid_area); + + i = 0; + + switch (workspace_manager->starting_corner) + { + case META_DISPLAY_TOPLEFT: + if (workspace_manager->vertical_workspaces) + { + c = 0; + while (c < cols) + { + r = 0; + while (r < rows) + { + grid[r*cols+c] = i; + ++i; + ++r; + } + ++c; + } + } + else + { + r = 0; + while (r < rows) + { + c = 0; + while (c < cols) + { + grid[r*cols+c] = i; + ++i; + ++c; + } + ++r; + } + } + break; + case META_DISPLAY_TOPRIGHT: + if (workspace_manager->vertical_workspaces) + { + c = cols - 1; + while (c >= 0) + { + r = 0; + while (r < rows) + { + grid[r*cols+c] = i; + ++i; + ++r; + } + --c; + } + } + else + { + r = 0; + while (r < rows) + { + c = cols - 1; + while (c >= 0) + { + grid[r*cols+c] = i; + ++i; + --c; + } + ++r; + } + } + break; + case META_DISPLAY_BOTTOMLEFT: + if (workspace_manager->vertical_workspaces) + { + c = 0; + while (c < cols) + { + r = rows - 1; + while (r >= 0) + { + grid[r*cols+c] = i; + ++i; + --r; + } + ++c; + } + } + else + { + r = rows - 1; + while (r >= 0) + { + c = 0; + while (c < cols) + { + grid[r*cols+c] = i; + ++i; + ++c; + } + --r; + } + } + break; + case META_DISPLAY_BOTTOMRIGHT: + if (workspace_manager->vertical_workspaces) + { + c = cols - 1; + while (c >= 0) + { + r = rows - 1; + while (r >= 0) + { + grid[r*cols+c] = i; + ++i; + --r; + } + --c; + } + } + else + { + r = rows - 1; + while (r >= 0) + { + c = cols - 1; + while (c >= 0) + { + grid[r*cols+c] = i; + ++i; + --c; + } + --r; + } + } + break; + } + + if (i != grid_area) + meta_bug ("did not fill in the whole workspace grid in %s (%d filled)\n", + G_STRFUNC, i); + + current_row = 0; + current_col = 0; + r = 0; + while (r < rows) + { + c = 0; + while (c < cols) + { + if (grid[r*cols+c] == current_space) + { + current_row = r; + current_col = c; + } + else if (grid[r*cols+c] >= num_workspaces) + { + /* flag nonexistent spaces with -1 */ + grid[r*cols+c] = -1; + } + ++c; + } + ++r; + } + + layout->rows = rows; + layout->cols = cols; + layout->grid = grid; + layout->grid_area = grid_area; + layout->current_row = current_row; + layout->current_col = current_col; + +#ifdef WITH_VERBOSE_MODE + if (meta_is_verbose ()) + { + r = 0; + while (r < layout->rows) + { + meta_verbose (" "); + meta_push_no_msg_prefix (); + c = 0; + while (c < layout->cols) + { + if (r == layout->current_row && + c == layout->current_col) + meta_verbose ("*%2d ", layout->grid[r*layout->cols+c]); + else + meta_verbose ("%3d ", layout->grid[r*layout->cols+c]); + ++c; + } + meta_verbose ("\n"); + meta_pop_no_msg_prefix (); + ++r; + } + } +#endif /* WITH_VERBOSE_MODE */ +} + +void +meta_workspace_manager_free_workspace_layout (MetaWorkspaceLayout *layout) +{ + g_free (layout->grid); +} + +static void +queue_windows_showing (MetaWorkspaceManager *workspace_manager) +{ + GSList *windows, *l; + + /* Must operate on all windows on display instead of just on the + * active_workspace's window list, because the active_workspace's + * window list may not contain the on_all_workspace windows. + */ + windows = meta_display_list_windows (workspace_manager->display, META_LIST_DEFAULT); + + for (l = windows; l; l = l->next) + { + MetaWindow *w = l->data; + + meta_window_queue (w, META_QUEUE_CALC_SHOWING); + } + + g_slist_free (windows); +} + +void +meta_workspace_manager_minimize_all_on_active_workspace_except (MetaWorkspaceManager *workspace_manager, + MetaWindow *keep) +{ + GList *l; + + for (l = workspace_manager->active_workspace->windows; l; l = l->next) + { + MetaWindow *w = l->data; + + if (w->has_minimize_func && w != keep) + meta_window_minimize (w); + } +} + +void +meta_workspace_manager_show_desktop (MetaWorkspaceManager *workspace_manager, + guint32 timestamp) +{ + GList *l; + + if (workspace_manager->active_workspace->showing_desktop) + return; + + workspace_manager->active_workspace->showing_desktop = TRUE; + + queue_windows_showing (workspace_manager); + + /* Focus the most recently used META_WINDOW_DESKTOP window, if there is one; + * see bug 159257. + */ + for (l = workspace_manager->active_workspace->mru_list; l; l = l->next) + { + MetaWindow *w = l->data; + + if (w->type == META_WINDOW_DESKTOP) + { + meta_window_focus (w, timestamp); + break; + } + } + + g_signal_emit (workspace_manager, + workspace_manager_signals[SHOWING_DESKTOP_CHANGED], + 0, NULL); +} + +void +meta_workspace_manager_unshow_desktop (MetaWorkspaceManager *workspace_manager) +{ + if (!workspace_manager->active_workspace->showing_desktop) + return; + + workspace_manager->active_workspace->showing_desktop = FALSE; + + queue_windows_showing (workspace_manager); + + g_signal_emit (workspace_manager, + workspace_manager_signals[SHOWING_DESKTOP_CHANGED], + 0, NULL); +} + +/** + * meta_workspace_manager_get_workspaces: (skip) + * @workspace_manager: a #MetaWorkspaceManager + * + * Returns: (transfer none) (element-type Meta.Workspace): The workspaces for @display + */ +GList * +meta_workspace_manager_get_workspaces (MetaWorkspaceManager *workspace_manager) +{ + return workspace_manager->workspaces; +} + +int +meta_workspace_manager_get_active_workspace_index (MetaWorkspaceManager *workspace_manager) +{ + MetaWorkspace *active = workspace_manager->active_workspace; + + if (!active) + return -1; + + return meta_workspace_index (active); +} + +/** + * meta_workspace_manager_get_active_workspace: + * @workspace_manager: A #MetaWorkspaceManager + * + * Returns: (transfer none): The current workspace + */ +MetaWorkspace * +meta_workspace_manager_get_active_workspace (MetaWorkspaceManager *workspace_manager) +{ + return workspace_manager->active_workspace; +} + +void +meta_workspace_manager_workspace_switched (MetaWorkspaceManager *workspace_manager, + int from, + int to, + MetaMotionDirection direction) +{ + g_signal_emit (workspace_manager, + workspace_manager_signals[WORKSPACE_SWITCHED], 0, + from, to, direction); +} + +static void +prefs_changed_callback (MetaPreference pref, + gpointer data) +{ + MetaWorkspaceManager *workspace_manager = data; + + if ((pref == META_PREF_NUM_WORKSPACES || + pref == META_PREF_DYNAMIC_WORKSPACES) && + !meta_prefs_get_dynamic_workspaces ()) + { + guint32 timestamp; + int new_num; + + timestamp = + meta_display_get_current_time_roundtrip (workspace_manager->display); + new_num = meta_prefs_get_num_workspaces (); + meta_workspace_manager_update_num_workspaces (workspace_manager, + timestamp, new_num); + } +} diff --git a/src/core/muffin.c b/src/core/mutter.c similarity index 71% rename from src/core/muffin.c rename to src/core/mutter.c index 8665797a4..389d99199 100644 --- a/src/core/muffin.c +++ b/src/core/mutter.c @@ -12,23 +12,20 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #include "config.h" -#include <stdlib.h> - -#include <meta/main.h> -#include <meta/util.h> -#include "meta-plugin-manager.h" +#include <glib.h> #include <glib/gi18n-lib.h> +#include <stdlib.h> -#include <glib.h> +#include "compositor/meta-plugin-manager.h" +#include "meta/main.h" +#include "meta/util.h" static gboolean print_version (const gchar *option_name, @@ -38,17 +35,17 @@ print_version (const gchar *option_name, { const int latest_year = 2011; - g_print (_("muffin %s\n" - "Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" + g_print (_("mutter %s\n" + "Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n" "This is free software; see the source for copying conditions.\n" "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"), VERSION, latest_year); exit (0); } -static gchar *plugin = "default"; +static const char *plugin = "libdefault"; -GOptionEntry muffin_options[] = { +GOptionEntry mutter_options[] = { { "version", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, print_version, @@ -56,10 +53,10 @@ GOptionEntry muffin_options[] = { NULL }, { - "muffin-plugin", 0, 0, G_OPTION_ARG_STRING, + "mutter-plugin", 0, 0, G_OPTION_ARG_STRING, &plugin, - N_("Muffin plugin to use"), - "PLUGINS" + N_("Mutter plugin to use"), + "PLUGIN", }, { NULL } }; @@ -70,19 +67,19 @@ main (int argc, char **argv) GOptionContext *ctx; GError *error = NULL; - g_setenv ("CLUTTER_BACKEND", "x11", TRUE); - ctx = meta_get_option_context (); - g_option_context_add_main_entries (ctx, muffin_options, GETTEXT_PACKAGE); + g_option_context_add_main_entries (ctx, mutter_options, GETTEXT_PACKAGE); if (!g_option_context_parse (ctx, &argc, &argv, &error)) { - g_printerr ("muffin: %s\n", error->message); + g_printerr ("mutter: %s\n", error->message); exit (1); } + g_option_context_free (ctx); if (plugin) meta_plugin_manager_load (plugin); meta_init (); + meta_register_with_session (); return meta_run (); } diff --git a/src/core/place.c b/src/core/place.c index abbd58f85..846845376 100644 --- a/src/core/place.c +++ b/src/core/place.c @@ -1,13 +1,13 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* Muffin window placement */ +/* Mutter window placement */ -/* +/* * Copyright (C) 2001 Havoc Pennington * Copyright (C) 2002, 2003 Red Hat, Inc. * Copyright (C) 2003 Rob Adams * Copyright (C) 2005 Elijah Newren - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the @@ -17,23 +17,26 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ -#include <config.h> +#include "config.h" + +#include "core/place.h" -#include "boxes-private.h" -#include "place.h" -#include <meta/workspace.h> -#include <meta/prefs.h> #include <gdk/gdk.h> #include <math.h> #include <stdlib.h> +#include "backends/meta-backend-private.h" +#include "backends/meta-logical-monitor.h" +#include "core/boxes-private.h" +#include "meta/meta-backend.h" +#include "meta/prefs.h" +#include "meta/workspace.h" + typedef enum { META_LEFT, @@ -47,39 +50,23 @@ northwestcmp (gconstpointer a, gconstpointer b) { MetaWindow *aw = (gpointer) a; MetaWindow *bw = (gpointer) b; + MetaRectangle a_frame; + MetaRectangle b_frame; int from_origin_a; int from_origin_b; int ax, ay, bx, by; - /* we're interested in the frame position for cascading, - * not meta_window_get_position() - */ - if (aw->frame) - { - ax = aw->frame->rect.x; - ay = aw->frame->rect.y; - } - else - { - ax = aw->rect.x; - ay = aw->rect.y; - } + meta_window_get_frame_rect (aw, &a_frame); + meta_window_get_frame_rect (bw, &b_frame); + ax = a_frame.x; + ay = a_frame.y; + bx = b_frame.x; + by = b_frame.y; - if (bw->frame) - { - bx = bw->frame->rect.x; - by = bw->frame->rect.y; - } - else - { - bx = bw->rect.x; - by = bw->rect.y; - } - /* probably there's a fast good-enough-guess we could use here. */ from_origin_a = sqrt (ax * ax + ay * ay); from_origin_b = sqrt (bx * bx + by * by); - + if (from_origin_a < from_origin_b) return -1; else if (from_origin_a > from_origin_b) @@ -88,74 +75,8 @@ northwestcmp (gconstpointer a, gconstpointer b) return 0; } -static gboolean -place_by_pointer(MetaWindow *window, - MetaFrameBorders *borders, - MetaPlacementMode placement_mode, - int *new_x, - int *new_y) -{ - int window_width, window_height; - Window root_return, child_return; - int root_x_return, root_y_return; - int win_x_return, win_y_return; - unsigned int mask_return; - - XQueryPointer (window->display->xdisplay, - window->screen->xroot, - &root_return, - &child_return, - &root_x_return, - &root_y_return, - &win_x_return, - &win_y_return, - &mask_return); - - window_width = window->frame ? window->frame->rect.width : window->rect.width; - window_height = window->frame ? window->frame->rect.height : window->rect.height; - - if (borders) { - *new_x = root_x_return + borders->visible.left - window_width / 2; - *new_y = root_y_return + borders->visible.top - window_height / 2; - } - else { - *new_x = root_x_return - window_width / 2; - *new_y = root_y_return - window_height / 2; - } - - if (placement_mode == META_PLACEMENT_MODE_MANUAL) - window->move_after_placement = TRUE; - - return TRUE; -} - -static gboolean -place_in_center (MetaWindow *window, - MetaFrameBorders *borders, - MetaPlacementMode placement_mode, - int *new_x, - int *new_y) -{ - int center_x, center_y, monitor_n; - MetaRectangle work_area, outer_rect; - - monitor_n = meta_screen_get_current_monitor (window->screen); - - meta_window_get_work_area_for_monitor (window, monitor_n, &work_area); - meta_window_get_input_rect (window, &outer_rect); - - center_x = work_area.x + work_area.width / 2; - center_y = work_area.y + work_area.height / 2; - - *new_x = center_x - (window->rect.width / 2); - *new_y = center_y - (outer_rect.height / 2) + borders->visible.top + borders->invisible.top; - - return TRUE; -} - static void find_next_cascade (MetaWindow *window, - MetaFrameBorders *borders, /* visible windows on relevant workspaces */ GList *windows, int x, @@ -163,30 +84,31 @@ find_next_cascade (MetaWindow *window, int *new_x, int *new_y) { + MetaBackend *backend = meta_get_backend (); GList *tmp; GList *sorted; int cascade_x, cascade_y; MetaRectangle titlebar_rect; int x_threshold, y_threshold; + MetaRectangle frame_rect; int window_width, window_height; int cascade_stage; MetaRectangle work_area; - int current; - + MetaLogicalMonitor *current; + sorted = g_list_copy (windows); sorted = g_list_sort (sorted, northwestcmp); - /* This is a "fuzzy" cascade algorithm. + /* This is a "fuzzy" cascade algorithm. * For each window in the list, we find where we'd cascade a * new window after it. If a window is already nearly at that * position, we move on. */ - + /* arbitrary-ish threshold, honors user attempts to * manually cascade. */ #define CASCADE_FUZZ 15 - meta_window_get_titlebar_rect (window, &titlebar_rect); x_threshold = MAX (titlebar_rect.x, CASCADE_FUZZ); y_threshold = MAX (titlebar_rect.y, CASCADE_FUZZ); @@ -196,64 +118,56 @@ find_next_cascade (MetaWindow *window, * of NW corner of window frame. */ - current = meta_screen_get_current_monitor (window->screen); - meta_window_get_work_area_for_monitor (window, current, &work_area); + current = meta_backend_get_current_logical_monitor (backend); + meta_window_get_work_area_for_logical_monitor (window, current, &work_area); cascade_x = MAX (0, work_area.x); cascade_y = MAX (0, work_area.y); - + /* Find first cascade position that's not used. */ - - window_width = window->frame ? window->frame->rect.width : window->rect.width; - window_height = window->frame ? window->frame->rect.height : window->rect.height; - + + meta_window_get_frame_rect (window, &frame_rect); + window_width = frame_rect.width; + window_height = frame_rect.height; + cascade_stage = 0; tmp = sorted; while (tmp != NULL) { MetaWindow *w; + MetaRectangle w_frame_rect; int wx, wy; - + w = tmp->data; /* we want frame position, not window position */ - if (w->frame) - { - wx = w->frame->rect.x; - wy = w->frame->rect.y; - } - else - { - wx = w->rect.x; - wy = w->rect.y; - } - + meta_window_get_frame_rect (w, &w_frame_rect); + wx = w_frame_rect.x; + wy = w_frame_rect.y; + if (ABS (wx - cascade_x) < x_threshold && ABS (wy - cascade_y) < y_threshold) { - /* This window is "in the way", move to next cascade - * point. The new window frame should go at the origin - * of the client window we're stacking above. - */ meta_window_get_titlebar_rect (w, &titlebar_rect); + /* Cascade the window evenly by the titlebar height; this isn't a typo. */ cascade_x = wx + titlebar_rect.height; cascade_y = wy + titlebar_rect.height; - + /* If we go off the screen, start over with a new cascade */ - if (((cascade_x + window_width) > + if (((cascade_x + window_width) > (work_area.x + work_area.width)) || ((cascade_y + window_height) > - (work_area.y + work_area.height))) - { - cascade_x = MAX (0, work_area.x); - cascade_y = MAX (0, work_area.y); - + (work_area.y + work_area.height))) + { + cascade_x = MAX (0, work_area.x); + cascade_y = MAX (0, work_area.y); + #define CASCADE_INTERVAL 50 /* space between top-left corners of cascades */ cascade_stage += 1; - cascade_x += CASCADE_INTERVAL * cascade_stage; - - /* start over with a new cascade translated to the right, unless + cascade_x += CASCADE_INTERVAL * cascade_stage; + + /* start over with a new cascade translated to the right, unless * we are out of space */ if ((cascade_x + window_width) < @@ -268,38 +182,28 @@ find_next_cascade (MetaWindow *window, cascade_x = MAX (0, work_area.x); break; } - } + } } else { /* Keep searching for a further-down-the-diagonal window. */ } - + tmp = tmp->next; } /* cascade_x and cascade_y will match the last window in the list * that was "in the way" (in the approximate cascade diagonal) */ - + g_list_free (sorted); - /* Convert coords to position of window, not position of frame. */ - if (borders == NULL) - { - *new_x = cascade_x; - *new_y = cascade_y; - } - else - { - *new_x = cascade_x + borders->visible.left; - *new_y = cascade_y + borders->visible.top; - } + *new_x = cascade_x; + *new_y = cascade_y; } static void find_most_freespace (MetaWindow *window, - MetaFrameBorders *borders, /* visible windows on relevant workspaces */ MetaWindow *focus_window, int x, @@ -311,29 +215,25 @@ find_most_freespace (MetaWindow *window, int max_area; int max_width, max_height, left, right, top, bottom; int left_space, right_space, top_space, bottom_space; - int frame_size_left, frame_size_top; MetaRectangle work_area; MetaRectangle avoid; - MetaRectangle outer; - - frame_size_left = borders ? borders->visible.left : 0; - frame_size_top = borders ? borders->visible.top : 0; + MetaRectangle frame_rect; meta_window_get_work_area_current_monitor (focus_window, &work_area); - meta_window_get_outer_rect (focus_window, &avoid); - meta_window_get_outer_rect (window, &outer); + meta_window_get_frame_rect (focus_window, &avoid); + meta_window_get_frame_rect (window, &frame_rect); /* Find the areas of choosing the various sides of the focus window */ - max_width = MIN (avoid.width, outer.width); - max_height = MIN (avoid.height, outer.height); + max_width = MIN (avoid.width, frame_rect.width); + max_height = MIN (avoid.height, frame_rect.height); left_space = avoid.x - work_area.x; right_space = work_area.width - (avoid.x + avoid.width - work_area.x); top_space = avoid.y - work_area.y; bottom_space = work_area.height - (avoid.y + avoid.height - work_area.y); - left = MIN (left_space, outer.width); - right = MIN (right_space, outer.width); - top = MIN (top_space, outer.height); - bottom = MIN (bottom_space, outer.height); + left = MIN (left_space, frame_rect.width); + right = MIN (right_space, frame_rect.width); + top = MIN (top_space, frame_rect.height); + bottom = MIN (bottom_space, frame_rect.height); /* Find out which side of the focus_window can show the most of the window */ side = META_LEFT; @@ -365,39 +265,69 @@ find_most_freespace (MetaWindow *window, switch (side) { case META_LEFT: - *new_y = avoid.y + frame_size_top; - if (left_space > outer.width) - *new_x = avoid.x - outer.width + frame_size_left; + *new_y = avoid.y; + if (left_space > frame_rect.width) + *new_x = avoid.x - frame_rect.width; else - *new_x = work_area.x + frame_size_left; + *new_x = work_area.x; break; case META_RIGHT: - *new_y = avoid.y + frame_size_top; - if (right_space > outer.width) - *new_x = avoid.x + avoid.width + frame_size_left; + *new_y = avoid.y; + if (right_space > frame_rect.width) + *new_x = avoid.x + avoid.width; else - *new_x = work_area.x + work_area.width - outer.width + frame_size_left; + *new_x = work_area.x + work_area.width - frame_rect.width; break; case META_TOP: - *new_x = avoid.x + frame_size_left; - if (top_space > outer.height) - *new_y = avoid.y - outer.height + frame_size_top; + *new_x = avoid.x; + if (top_space > frame_rect.height) + *new_y = avoid.y - frame_rect.height; else - *new_y = work_area.y + frame_size_top; + *new_y = work_area.y; break; case META_BOTTOM: - *new_x = avoid.x + frame_size_left; - if (bottom_space > outer.height) - *new_y = avoid.y + avoid.height + frame_size_top; + *new_x = avoid.x; + if (bottom_space > frame_rect.height) + *new_y = avoid.y + avoid.height; else - *new_y = work_area.y + work_area.height - outer.height + frame_size_top; + *new_y = work_area.y + work_area.height - frame_rect.height; break; } } +static gboolean +window_overlaps_focus_window (MetaWindow *window) +{ + MetaWindow *focus_window; + MetaRectangle window_frame, focus_frame, overlap; + + focus_window = window->display->focus_window; + if (focus_window == NULL) + return FALSE; + + meta_window_get_frame_rect (window, &window_frame); + meta_window_get_frame_rect (focus_window, &focus_frame); + + return meta_rectangle_intersect (&window_frame, + &focus_frame, + &overlap); +} + +static gboolean +window_place_centered (MetaWindow *window) +{ + MetaWindowType type; + + type = window->type; + + return (type == META_WINDOW_DIALOG || + type == META_WINDOW_MODAL_DIALOG || + type == META_WINDOW_SPLASHSCREEN || + (type == META_WINDOW_NORMAL && meta_prefs_get_center_new_windows ())); +} + static void avoid_being_obscured_as_second_modal_dialog (MetaWindow *window, - MetaFrameBorders *borders, int *x, int *y) { @@ -416,18 +346,17 @@ avoid_being_obscured_as_second_modal_dialog (MetaWindow *window, */ MetaWindow *focus_window; - MetaRectangle overlap; focus_window = window->display->focus_window; + /* denied_focus_and_not_transient is only set when focus_window != NULL */ + if (window->denied_focus_and_not_transient && - window->wm_state_modal && /* FIXME: Maybe do this for all transients? */ + window->type == META_WINDOW_MODAL_DIALOG && meta_window_same_application (window, focus_window) && - meta_rectangle_intersect (&window->rect, - &focus_window->rect, - &overlap)) + window_overlaps_focus_window (window)) { - find_most_freespace (window, borders, focus_window, *x, *y, x, y); + find_most_freespace (window, focus_window, *x, *y, x, y); meta_topic (META_DEBUG_PLACEMENT, "Dialog window %s was denied focus but may be modal " "to the focus window; had to move it to avoid the " @@ -442,12 +371,12 @@ rectangle_overlaps_some_window (MetaRectangle *rect, { GList *tmp; MetaRectangle dest; - + tmp = windows; while (tmp != NULL) { MetaWindow *other = tmp->data; - MetaRectangle other_rect; + MetaRectangle other_rect; switch (other->type) { @@ -456,27 +385,27 @@ rectangle_overlaps_some_window (MetaRectangle *rect, case META_WINDOW_DESKTOP: case META_WINDOW_DIALOG: case META_WINDOW_MODAL_DIALOG: - /* override redirect window types: */ - case META_WINDOW_DROPDOWN_MENU: - case META_WINDOW_POPUP_MENU: - case META_WINDOW_TOOLTIP: - case META_WINDOW_NOTIFICATION: - case META_WINDOW_COMBO: - case META_WINDOW_DND: - case META_WINDOW_OVERRIDE_OTHER: + /* override redirect window types: */ + case META_WINDOW_DROPDOWN_MENU: + case META_WINDOW_POPUP_MENU: + case META_WINDOW_TOOLTIP: + case META_WINDOW_NOTIFICATION: + case META_WINDOW_COMBO: + case META_WINDOW_DND: + case META_WINDOW_OVERRIDE_OTHER: break; case META_WINDOW_NORMAL: case META_WINDOW_UTILITY: case META_WINDOW_TOOLBAR: case META_WINDOW_MENU: - meta_window_get_outer_rect (other, &other_rect); - + meta_window_get_frame_rect (other, &other_rect); + if (meta_rectangle_intersect (rect, &other_rect, &dest)) return TRUE; break; } - + tmp = tmp->next; } @@ -488,20 +417,14 @@ leftmost_cmp (gconstpointer a, gconstpointer b) { MetaWindow *aw = (gpointer) a; MetaWindow *bw = (gpointer) b; + MetaRectangle a_frame; + MetaRectangle b_frame; int ax, bx; - /* we're interested in the frame position for cascading, - * not meta_window_get_position() - */ - if (aw->frame) - ax = aw->frame->rect.x; - else - ax = aw->rect.x; - - if (bw->frame) - bx = bw->frame->rect.x; - else - bx = bw->rect.x; + meta_window_get_frame_rect (aw, &a_frame); + meta_window_get_frame_rect (bw, &b_frame); + ax = a_frame.x; + bx = b_frame.x; if (ax < bx) return -1; @@ -516,20 +439,14 @@ topmost_cmp (gconstpointer a, gconstpointer b) { MetaWindow *aw = (gpointer) a; MetaWindow *bw = (gpointer) b; + MetaRectangle a_frame; + MetaRectangle b_frame; int ay, by; - /* we're interested in the frame position for cascading, - * not meta_window_get_position() - */ - if (aw->frame) - ay = aw->frame->rect.y; - else - ay = aw->rect.y; - - if (bw->frame) - by = bw->frame->rect.y; - else - by = bw->rect.y; + meta_window_get_frame_rect (aw, &a_frame); + meta_window_get_frame_rect (bw, &b_frame); + ay = a_frame.y; + by = b_frame.y; if (ay < by) return -1; @@ -566,15 +483,14 @@ center_tile_rect_in_area (MetaRectangle *rect, * don't want to create a 1x1 Emacs. */ static gboolean -find_first_fit (MetaWindow *window, - MetaFrameBorders *borders, +find_first_fit (MetaWindow *window, /* visible windows on relevant workspaces */ - GList *windows, - int monitor, - int x, - int y, - int *new_x, - int *new_y) + GList *windows, + MetaLogicalMonitor *logical_monitor, + int x, + int y, + int *new_x, + int *new_y) { /* This algorithm is limited - it just brute-force tries * to fit the window in a small number of locations that are aligned @@ -582,160 +498,180 @@ find_first_fit (MetaWindow *window, * the bottom of each existing window, and then to the right * of each existing window, aligned with the left/top of the * existing window in each of those cases. - */ + */ int retval; GList *below_sorted; GList *right_sorted; GList *tmp; MetaRectangle rect; MetaRectangle work_area; - + retval = FALSE; /* Below each window */ below_sorted = g_list_copy (windows); below_sorted = g_list_sort (below_sorted, leftmost_cmp); - below_sorted = g_list_sort (below_sorted, topmost_cmp); + below_sorted = g_list_sort (below_sorted, topmost_cmp); /* To the right of each window */ right_sorted = g_list_copy (windows); right_sorted = g_list_sort (right_sorted, topmost_cmp); right_sorted = g_list_sort (right_sorted, leftmost_cmp); - - rect.width = window->rect.width; - rect.height = window->rect.height; - - if (borders) + + meta_window_get_frame_rect (window, &rect); + +#ifdef WITH_VERBOSE_MODE + { + char monitor_location_string[RECT_LENGTH]; + + meta_rectangle_to_string (&logical_monitor->rect, + monitor_location_string); + meta_topic (META_DEBUG_XINERAMA, + "Natural monitor is %s\n", + monitor_location_string); + } +#endif + + meta_window_get_work_area_for_logical_monitor (window, + logical_monitor, + &work_area); + + center_tile_rect_in_area (&rect, &work_area); + + if (meta_rectangle_contains_rect (&work_area, &rect) && + !rectangle_overlaps_some_window (&rect, windows)) { - rect.width += borders->visible.left + borders->visible.right; - rect.height += borders->visible.top + borders->visible.bottom; + *new_x = rect.x; + *new_y = rect.y; + + retval = TRUE; + + goto out; } -#ifdef WITH_VERBOSE_MODE + /* try below each window */ + tmp = below_sorted; + while (tmp != NULL) { - char monitor_location_string[RECT_LENGTH]; - meta_rectangle_to_string (&window->screen->monitor_infos[monitor].rect, - monitor_location_string); - meta_topic (META_DEBUG_XINERAMA, - "Natural monitor is %s\n", - monitor_location_string); + MetaWindow *w = tmp->data; + MetaRectangle frame_rect; + + meta_window_get_frame_rect (w, &frame_rect); + + rect.x = frame_rect.x; + rect.y = frame_rect.y + frame_rect.height; + + if (meta_rectangle_contains_rect (&work_area, &rect) && + !rectangle_overlaps_some_window (&rect, below_sorted)) + { + *new_x = rect.x; + *new_y = rect.y; + + retval = TRUE; + + goto out; + } + + tmp = tmp->next; } -#endif - meta_window_get_work_area_for_monitor (window, monitor, &work_area); + /* try to the right of each window */ + tmp = right_sorted; + while (tmp != NULL) + { + MetaWindow *w = tmp->data; + MetaRectangle frame_rect; - center_tile_rect_in_area (&rect, &work_area); + meta_window_get_frame_rect (w, &frame_rect); - if (meta_rectangle_contains_rect (&work_area, &rect) && - !rectangle_overlaps_some_window (&rect, windows)) - { - *new_x = rect.x; - *new_y = rect.y; - if (borders) - { - *new_x += borders->visible.left; - *new_y += borders->visible.top; - } - - retval = TRUE; - - goto out; - } + rect.x = frame_rect.x + frame_rect.width; + rect.y = frame_rect.y; - /* try below each window */ - tmp = below_sorted; - while (tmp != NULL) - { - MetaWindow *w = tmp->data; - MetaRectangle outer_rect; - - meta_window_get_outer_rect (w, &outer_rect); - - rect.x = outer_rect.x; - rect.y = outer_rect.y + outer_rect.height; - - if (meta_rectangle_contains_rect (&work_area, &rect) && - !rectangle_overlaps_some_window (&rect, below_sorted)) - { - *new_x = rect.x; - *new_y = rect.y; - if (borders) - { - *new_x += borders->visible.left; - *new_y += borders->visible.top; - } - - retval = TRUE; - - goto out; - } + if (meta_rectangle_contains_rect (&work_area, &rect) && + !rectangle_overlaps_some_window (&rect, right_sorted)) + { + *new_x = rect.x; + *new_y = rect.y; - tmp = tmp->next; - } + retval = TRUE; - /* try to the right of each window */ - tmp = right_sorted; - while (tmp != NULL) - { - MetaWindow *w = tmp->data; - MetaRectangle outer_rect; - - meta_window_get_outer_rect (w, &outer_rect); - - rect.x = outer_rect.x + outer_rect.width; - rect.y = outer_rect.y; - - if (meta_rectangle_contains_rect (&work_area, &rect) && - !rectangle_overlaps_some_window (&rect, right_sorted)) - { - *new_x = rect.x; - *new_y = rect.y; - if (borders) - { - *new_x += borders->visible.left; - *new_y += borders->visible.top; - } - - retval = TRUE; - - goto out; - } + goto out; + } - tmp = tmp->next; - } - - out: + tmp = tmp->next; + } + out: g_list_free (below_sorted); g_list_free (right_sorted); return retval; } -LOCAL_SYMBOL void +void +meta_window_process_placement (MetaWindow *window, + MetaPlacementRule *placement_rule, + int *rel_x, + int *rel_y) +{ + MetaRectangle anchor_rect; + int window_width, window_height; + int x, y; + + window_width = placement_rule->width; + window_height = placement_rule->height; + + anchor_rect = placement_rule->anchor_rect; + + /* Place at anchor point. */ + if (placement_rule->anchor & META_PLACEMENT_ANCHOR_LEFT) + x = anchor_rect.x; + else if (placement_rule->anchor & META_PLACEMENT_ANCHOR_RIGHT) + x = anchor_rect.x + anchor_rect.width; + else + x = anchor_rect.x + (anchor_rect.width / 2); + if (placement_rule->anchor & META_PLACEMENT_ANCHOR_TOP) + y = anchor_rect.y; + else if (placement_rule->anchor & META_PLACEMENT_ANCHOR_BOTTOM) + y = anchor_rect.y + anchor_rect.height; + else + y = anchor_rect.y + (anchor_rect.height / 2); + + /* Shift according to gravity. */ + if (placement_rule->gravity & META_PLACEMENT_GRAVITY_LEFT) + x -= window_width; + else if (placement_rule->gravity & META_PLACEMENT_GRAVITY_RIGHT) + x = x; + else + x -= window_width / 2; + if (placement_rule->gravity & META_PLACEMENT_GRAVITY_TOP) + y -= window_height; + else if (placement_rule->gravity & META_PLACEMENT_GRAVITY_BOTTOM) + y = y; + else + y -= window_height / 2; + + /* Offset according to offset. */ + x += placement_rule->offset_x; + y += placement_rule->offset_y; + + *rel_x = x; + *rel_y = y; +} + +void meta_window_place (MetaWindow *window, - MetaFrameBorders *borders, int x, int y, int *new_x, int *new_y) { - GList *windows; - const MetaMonitorInfo *xi; - MetaPlacementMode placement_mode; - MetaWindow *parent; - - /* frame member variables should NEVER be used in here, only - * MetaFrameBorders. But remember borders == NULL - * for undecorated windows. Also, this function should - * NEVER have side effects other than computing the - * placement coordinates. - */ + MetaBackend *backend = meta_get_backend (); + GList *windows = NULL; + MetaLogicalMonitor *logical_monitor; meta_topic (META_DEBUG_PLACEMENT, "Placing window %s\n", window->desc); - windows = NULL; - parent = meta_display_lookup_x_window (window->display, - window->xtransient_for); + g_return_if_fail (!window->placement.rule); switch (window->type) { @@ -745,7 +681,7 @@ meta_window_place (MetaWindow *window, case META_WINDOW_MODAL_DIALOG: case META_WINDOW_SPLASHSCREEN: break; - + /* Assume the app knows best how to place these, no placement * algorithm ever (other than "leave them as-is") */ @@ -762,11 +698,10 @@ meta_window_place (MetaWindow *window, case META_WINDOW_COMBO: case META_WINDOW_DND: case META_WINDOW_OVERRIDE_OTHER: - goto done_no_constraints; + goto done; } - - if (meta_prefs_get_disable_workarounds () || - (parent != NULL && parent->type == META_WINDOW_DESKTOP)) + + if (meta_prefs_get_disable_workarounds ()) { switch (window->type) { @@ -789,26 +724,26 @@ meta_window_place (MetaWindow *window, case META_WINDOW_MODAL_DIALOG: case META_WINDOW_SPLASHSCREEN: break; - + /* Assume the app knows best how to place these. */ case META_WINDOW_DESKTOP: case META_WINDOW_DOCK: case META_WINDOW_TOOLBAR: case META_WINDOW_MENU: case META_WINDOW_UTILITY: - /* override redirect window types: */ - case META_WINDOW_DROPDOWN_MENU: - case META_WINDOW_POPUP_MENU: - case META_WINDOW_TOOLTIP: - case META_WINDOW_NOTIFICATION: - case META_WINDOW_COMBO: - case META_WINDOW_DND: - case META_WINDOW_OVERRIDE_OTHER: + /* override redirect window types: */ + case META_WINDOW_DROPDOWN_MENU: + case META_WINDOW_POPUP_MENU: + case META_WINDOW_TOOLTIP: + case META_WINDOW_NOTIFICATION: + case META_WINDOW_COMBO: + case META_WINDOW_DND: + case META_WINDOW_OVERRIDE_OTHER: if (window->size_hints.flags & PPosition) { meta_topic (META_DEBUG_PLACEMENT, "Not placing non-normal non-dialog window with PPosition set\n"); - goto done_no_constraints; + goto done; } break; } @@ -816,84 +751,80 @@ meta_window_place (MetaWindow *window, else { /* workarounds enabled */ - + if ((window->size_hints.flags & PPosition) || (window->size_hints.flags & USPosition)) { meta_topic (META_DEBUG_PLACEMENT, "Not placing window with PPosition or USPosition set\n"); - avoid_being_obscured_as_second_modal_dialog (window, borders, &x, &y); - goto done_no_constraints; + avoid_being_obscured_as_second_modal_dialog (window, &x, &y); + goto done; } } - - if ((window->type == META_WINDOW_DIALOG || - window->type == META_WINDOW_MODAL_DIALOG) && - window->xtransient_for != None && - (parent != NULL && parent->type != META_WINDOW_DESKTOP)) + + if (window->type == META_WINDOW_DIALOG || + window->type == META_WINDOW_MODAL_DIALOG) { - /* Center horizontally, at top of parent vertically */ + MetaWindow *parent = meta_window_get_transient_for (window); if (parent) { - int w; - meta_window_get_position (parent, &x, &y); - w = parent->rect.width; + MetaRectangle frame_rect, parent_frame_rect; + + meta_window_get_frame_rect (window, &frame_rect); + meta_window_get_frame_rect (parent, &parent_frame_rect); + + y = parent_frame_rect.y; /* center of parent */ - x = x + w / 2; + x = parent_frame_rect.x + parent_frame_rect.width / 2; /* center of child over center of parent */ - x -= window->rect.width / 2; + x -= frame_rect.width / 2; /* "visually" center window over parent, leaving twice as * much space below as on top. */ - y += (parent->rect.height - window->rect.height)/3; - - /* put top of child's frame, not top of child's client */ - if (borders) - y += borders->visible.top; + y += (parent_frame_rect.height - frame_rect.height)/3; meta_topic (META_DEBUG_PLACEMENT, "Centered window %s over transient parent\n", window->desc); - - avoid_being_obscured_as_second_modal_dialog (window, borders, &x, &y); + + avoid_being_obscured_as_second_modal_dialog (window, &x, &y); goto done; } } - + /* FIXME UTILITY with transient set should be stacked up * on the sides of the parent window or something. */ - - if (window->type == META_WINDOW_DIALOG || - window->type == META_WINDOW_MODAL_DIALOG || - window->type == META_WINDOW_SPLASHSCREEN) + + if (window_place_centered (window)) { /* Center on current monitor */ int w, h; + MetaRectangle frame_rect; - /* Warning, this function is a round trip! */ - xi = meta_screen_get_current_monitor_info (window->screen); + meta_window_get_frame_rect (window, &frame_rect); - w = xi->rect.width; - h = xi->rect.height; + /* Warning, this function is a round trip! */ + logical_monitor = meta_backend_get_current_logical_monitor (backend); - x = (w - window->rect.width) / 2; - y = (h - window->rect.height) / 2; + w = logical_monitor->rect.width; + h = logical_monitor->rect.height; - x += xi->rect.x; - y += xi->rect.y; + x = (w - frame_rect.width) / 2; + y = (h - frame_rect.height) / 2; - avoid_being_obscured_as_second_modal_dialog (window, borders, &x, &y); + x += logical_monitor->rect.x; + y += logical_monitor->rect.y; - meta_topic (META_DEBUG_PLACEMENT, "Centered window %s on screen %d monitor %d\n", - window->desc, window->screen->number, xi->number); + meta_topic (META_DEBUG_PLACEMENT, "Centered window %s on monitor %d\n", + window->desc, logical_monitor->number); goto done_check_denied_focus; } - + /* Find windows that matter (not minimized, on same workspace * as placed window, may be shaded - if shaded we pretend it isn't * for placement purposes) @@ -901,7 +832,7 @@ meta_window_place (MetaWindow *window, { GSList *all_windows; GSList *tmp; - + all_windows = meta_display_list_windows (window->display, META_LIST_DEFAULT); tmp = all_windows; @@ -909,10 +840,10 @@ meta_window_place (MetaWindow *window, { MetaWindow *w = tmp->data; - if (meta_window_showing_on_its_workspace (w) && - w != window && - (window->workspace == w->workspace || - window->on_all_workspaces || w->on_all_workspaces)) + if (w != window && + meta_window_showing_on_its_workspace (w) && + (window->on_all_workspaces || + meta_window_located_on_workspace (w, window->workspace))) windows = g_list_prepend (windows, w); tmp = tmp->next; @@ -921,65 +852,45 @@ meta_window_place (MetaWindow *window, g_slist_free (all_windows); } - /* Warning, this is a round trip! */ - xi = meta_screen_get_current_monitor_info (window->screen); - - /* "Origin" placement algorithm */ - x = xi->rect.x; - y = xi->rect.y; - - - /* Placement based on pointer position */ - placement_mode = meta_prefs_get_placement_mode(); - - if (placement_mode == META_PLACEMENT_MODE_POINTER || - placement_mode == META_PLACEMENT_MODE_MANUAL) - { - if (place_by_pointer (window, borders, placement_mode, &x, &y)) - goto done_check_denied_focus; - } - - else if (placement_mode == META_PLACEMENT_MODE_CENTER) - { - if (place_in_center (window, borders, placement_mode, &x, &y)) - goto done_check_denied_focus; - } - - if (find_first_fit (window, borders, windows, - xi->number, - x, y, &x, &y)) - goto done_check_denied_focus; + /* Warning, on X11 this might be a round trip! */ + logical_monitor = meta_backend_get_current_logical_monitor (backend); /* Maximize windows if they are too big for their work area (bit of * a hack here). Assume undecorated windows probably don't intend to - * be maximized. + * be maximized. */ if (window->has_maximize_func && window->decorated && !window->fullscreen) { MetaRectangle workarea; - MetaRectangle outer; + MetaRectangle frame_rect; + + meta_window_get_work_area_for_logical_monitor (window, + logical_monitor, + &workarea); + meta_window_get_frame_rect (window, &frame_rect); - meta_window_get_work_area_for_monitor (window, - xi->number, - &workarea); - meta_window_get_outer_rect (window, &outer); - /* If the window is bigger than the screen, then automaximize. Do NOT * auto-maximize the directions independently. See #419810. */ - if (outer.width >= workarea.width && outer.height >= workarea.height) + if (frame_rect.width >= workarea.width && frame_rect.height >= workarea.height) { window->maximize_horizontally_after_placement = TRUE; window->maximize_vertically_after_placement = TRUE; } } - /* If no placement has been done, revert to cascade to avoid - * fully overlapping window (e.g. starting multiple terminals) - * */ - if (x == xi->rect.x && y == xi->rect.y) - find_next_cascade (window, borders, windows, x, y, &x, &y); + /* "Origin" placement algorithm */ + x = logical_monitor->rect.x; + y = logical_monitor->rect.y; + + if (find_first_fit (window, windows, + logical_monitor, + x, y, &x, &y)) + goto done_check_denied_focus; + + /* No good fit? Fall back to cascading... */ + find_next_cascade (window, windows, x, y, &x, &y); done_check_denied_focus: /* If the window is being denied focus and isn't a transient of the @@ -989,17 +900,14 @@ meta_window_place (MetaWindow *window, */ if (window->denied_focus_and_not_transient) { - gboolean found_fit; MetaWindow *focus_window; - MetaRectangle overlap; + gboolean found_fit; focus_window = window->display->focus_window; g_assert (focus_window != NULL); /* No need to do anything if the window doesn't overlap at all */ - found_fit = !meta_rectangle_intersect (&window->rect, - &focus_window->rect, - &overlap); + found_fit = !window_overlaps_focus_window (window); /* Try to do a first fit again, this time only taking into account the * focus window. @@ -1010,26 +918,25 @@ meta_window_place (MetaWindow *window, focus_window_list = g_list_prepend (NULL, focus_window); /* Reset x and y ("origin" placement algorithm) */ - x = xi->rect.x; - y = xi->rect.y; + x = logical_monitor->rect.x; + y = logical_monitor->rect.y; - found_fit = find_first_fit (window, borders, focus_window_list, - xi->number, + found_fit = find_first_fit (window, focus_window_list, + logical_monitor, x, y, &x, &y); g_list_free (focus_window_list); - } + } /* If that still didn't work, just place it where we can see as much * as possible. */ if (!found_fit) - find_most_freespace (window, borders, focus_window, x, y, &x, &y); + find_most_freespace (window, focus_window, x, y, &x, &y); } - + done: - g_list_free (windows); - - done_no_constraints: + if (windows) + g_list_free (windows); *new_x = x; *new_y = y; diff --git a/src/core/place.h b/src/core/place.h index 7f39ec858..2e2c81141 100644 --- a/src/core/place.h +++ b/src/core/place.h @@ -1,10 +1,10 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* Muffin window placement */ +/* Mutter window placement */ -/* +/* * Copyright (C) 2001 Havoc Pennington - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the @@ -14,21 +14,23 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_PLACE_H #define META_PLACE_H -#include "window-private.h" -#include "frame.h" +#include "core/frame.h" +#include "core/window-private.h" + +void meta_window_process_placement (MetaWindow *window, + MetaPlacementRule *placement_rule, + int *rel_x, + int *rel_y); void meta_window_place (MetaWindow *window, - MetaFrameBorders *borders, int x, int y, int *new_x, diff --git a/src/core/prefs.c b/src/core/prefs.c index 20b52b73e..1ddf89d34 100644 --- a/src/core/prefs.c +++ b/src/core/prefs.c @@ -1,7 +1,5 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* Muffin preferences */ - /* * Copyright (C) 2001 Havoc Pennington, Copyright (C) 2002 Red Hat Inc. * Copyright (C) 2006 Elijah Newren @@ -19,28 +17,28 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ /** * SECTION:prefs * @title: Preferences - * @short_description: Muffin preferences + * @short_description: Mutter preferences */ -#include <config.h> -#include <meta/prefs.h> -#include "ui.h" -#include "util-private.h" -#include "meta-plugin-manager.h" +#include "config.h" + #include <glib.h> #include <gio/gio.h> -#include <gtk/gtk.h> #include <string.h> #include <stdlib.h> -#include "keybindings-private.h" + +#include "compositor/meta-plugin-manager.h" +#include "core/keybindings-private.h" +#include "core/meta-accel-parse.h" +#include "core/util-private.h" +#include "meta/prefs.h" +#include "x11/meta-x11-display-private.h" /* If you add a key, it needs updating in init() and in the gsettings * notify listener and of course in the .schemas file. @@ -52,28 +50,25 @@ #define KEY_TITLEBAR_FONT "titlebar-font" #define KEY_NUM_WORKSPACES "num-workspaces" #define KEY_WORKSPACE_NAMES "workspace-names" -#define KEY_WORKSPACE_CYCLE "workspace-cycle" /* Keys from "foreign" schemas */ +#define KEY_GNOME_ACCESSIBILITY "toolkit-accessibility" #define KEY_GNOME_ANIMATIONS "enable-animations" #define KEY_GNOME_CURSOR_THEME "cursor-theme" #define KEY_GNOME_CURSOR_SIZE "cursor-size" +#define KEY_XKB_OPTIONS "xkb-options" -#define KEY_MIN_WINDOW_OPACITY "min-window-opacity" -#define KEY_WS_NAMES_GNOME "workspace-names" +#define KEY_OVERLAY_KEY "overlay-key" #define KEY_WORKSPACES_ONLY_ON_PRIMARY "workspaces-only-on-primary" - -#define KEY_MOUSEWHEEL_ZOOM_ENABLED "screen-magnifier-enabled" - -#define KEY_BRING_ACTIVATED_WINDOWS_TO_CURRENT_WORKSPACE "bring-windows-to-current-workspace" +#define KEY_LOCATE_POINTER "locate-pointer" /* These are the different schemas we are keeping * a GSettings instance for */ #define SCHEMA_GENERAL "org.cinnamon.desktop.wm.preferences" -#define SCHEMA_MUFFIN "org.cinnamon.muffin" +#define SCHEMA_MUTTER "org.cinnamon.muffin" #define SCHEMA_INTERFACE "org.cinnamon.desktop.interface" -#define SCHEMA_A11Y_APPLICATIONS "org.cinnamon.desktop.a11y.applications" -#define SCHEMA_CINNAMON "org.cinnamon" +#define SCHEMA_INPUT_SOURCES "org.cinnamon.desktop.input-sources" +#define SCHEMA_MOUSE "org.cinnamon.desktop.peripherals.mouse" #define SETTINGS(s) g_hash_table_lookup (settings_schemas, (s)) @@ -85,45 +80,43 @@ static GHashTable *settings_schemas; static gboolean use_system_font = FALSE; static PangoFontDescription *titlebar_font = NULL; static MetaVirtualModifier mouse_button_mods = Mod1Mask; -static MetaVirtualModifier mouse_button_zoom_mods = Mod1Mask; -static gboolean mouse_zoom_enabled = FALSE; +static MetaKeyCombo overlay_key_combo = { 0, 0, 0 }; +static MetaKeyCombo locate_pointer_key_combo = { 0, 0, 0 }; static CDesktopFocusMode focus_mode = C_DESKTOP_FOCUS_MODE_CLICK; static CDesktopFocusNewWindows focus_new_windows = C_DESKTOP_FOCUS_NEW_WINDOWS_SMART; -static gboolean bring_user_activated_windows_to_current_workspace = FALSE; static gboolean raise_on_click = TRUE; +static gboolean center_new_windows = FALSE; static gboolean attach_modal_dialogs = FALSE; -static gboolean ignore_hide_titlebar_when_maximized = FALSE; -static char* current_theme = NULL; static int num_workspaces = 4; -static gboolean workspace_cycle = FALSE; static CDesktopTitlebarAction action_double_click_titlebar = C_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE; static CDesktopTitlebarAction action_middle_click_titlebar = C_DESKTOP_TITLEBAR_ACTION_LOWER; static CDesktopTitlebarAction action_right_click_titlebar = C_DESKTOP_TITLEBAR_ACTION_MENU; -static CDesktopTitlebarScrollAction action_scroll_titlebar = C_DESKTOP_TITLEBAR_SCROLL_ACTION_NONE; static gboolean dynamic_workspaces = FALSE; -static gboolean unredirect_fullscreen_windows = FALSE; -static gboolean desktop_effects = TRUE; -static MetaSyncMethod sync_method = META_SYNC_PRESENTATION_TIME; -static gboolean threaded_swap = TRUE; -static gboolean send_frame_timings = TRUE; -static gboolean application_based = FALSE; static gboolean disable_workarounds = FALSE; static gboolean auto_raise = FALSE; static gboolean auto_raise_delay = 500; +static gboolean focus_change_on_pointer_rest = FALSE; +static gboolean bell_is_visible = FALSE; +static gboolean bell_is_audible = TRUE; +static gboolean gnome_accessibility = FALSE; static gboolean gnome_animations = TRUE; +static gboolean locate_pointer_is_enabled = FALSE; +static unsigned int check_alive_timeout = 5000; static char *cursor_theme = NULL; +/* cursor_size will, when running as an X11 compositing window manager, be the + * actual cursor size, multiplied with the global window scaling factor. On + * Wayland, it will be the actual cursor size retrieved from gsettings. + */ static int cursor_size = 24; static int draggable_border_width = 10; -static int tile_hud_threshold = 150; -static int resize_threshold = 24; -static int ui_scale = 1; -static int min_window_opacity = 0; +static int drag_threshold; static gboolean resize_with_right_button = FALSE; static gboolean edge_tiling = FALSE; -static gboolean edge_resistance_window = TRUE; static gboolean force_fullscreen = TRUE; -static unsigned int snap_modifier[2]; +static gboolean auto_maximize = TRUE; +static gboolean show_fallback_app_menu = TRUE; +static CDesktopVisualBellType visual_bell_type = C_DESKTOP_VISUAL_BELL_FULLSCREEN_FLASH; static MetaButtonLayout button_layout; /* NULL-terminated array */ @@ -131,9 +124,7 @@ static char **workspace_names = NULL; static gboolean workspaces_only_on_primary = FALSE; -static gboolean legacy_snap = FALSE; -static gboolean invert_workspace_flip = FALSE; -static gboolean tile_maximize = FALSE; +static char *iso_next_group_option = NULL; static void handle_preference_update_enum (GSettings *settings, gchar *key); @@ -141,8 +132,6 @@ static gboolean update_binding (MetaKeyPref *binding, gchar **strokes); static gboolean update_key_binding (const char *key, gchar **strokes); -static gboolean update_workspace_names (void); -static void update_min_win_opacity (void); static void settings_changed (GSettings *settings, gchar *key, @@ -156,20 +145,14 @@ static void queue_changed (MetaPreference pref); static void maybe_give_disable_workarounds_warning (void); static gboolean titlebar_handler (GVariant*, gpointer*, gpointer); -static gboolean theme_name_handler (GVariant*, gpointer*, gpointer); static gboolean mouse_button_mods_handler (GVariant*, gpointer*, gpointer); -static gboolean mouse_button_zoom_mods_handler (GVariant*, gpointer*, gpointer); -static gboolean snap_modifier_handler (GVariant*, gpointer*, gpointer); static gboolean button_layout_handler (GVariant*, gpointer*, gpointer); +static gboolean overlay_key_handler (GVariant*, gpointer*, gpointer); +static gboolean locate_pointer_key_handler (GVariant*, gpointer*, gpointer); -static void do_override (char *key, char *schema); +static gboolean iso_next_group_handler (GVariant*, gpointer*, gpointer); static void init_bindings (void); -static void init_workspace_names (void); - -static MetaPlacementMode placement_mode = META_PLACEMENT_MODE_AUTOMATIC; - -static MetaBackgroundTransition background_transition = META_BACKGROUND_TRANSITION_BLEND; typedef struct { @@ -179,8 +162,8 @@ typedef struct typedef struct { - char *key; - char *schema; + const char *key; + const char *schema; MetaPreference pref; } MetaBasePreference; @@ -196,44 +179,51 @@ typedef struct gboolean *target; } MetaBoolPreference; + +/** + * MetaStringPreference: + * @handler: (nullable): A handler. Many of the string preferences + * aren't stored as strings and need parsing; others of them have + * default values which can't be solved in the general case. If you + * include a function pointer here, it will be called instead of writing + * the string value out to the target variable. + * The function will be passed to g_settings_get_mapped() and should + * return %TRUE if the mapping was successful and %FALSE otherwise. + * In the former case the function is expected to handle the result + * of the conversion itself and call queue_changed() appropriately; + * in particular the @result (out) parameter as returned by + * g_settings_get_mapped() will be ignored in all cases. + * This may be %NULL. If it is, see "target", below. + * @target: (nullable): Where to write the incoming string. + * This must be %NULL if the handler is non-%NULL. + * If the incoming string is %NULL, no change will be made. + */ typedef struct { MetaBasePreference base; - - /* - * A handler. Many of the string preferences aren't stored as - * strings and need parsing; others of them have default values - * which can't be solved in the general case. If you include a - * function pointer here, it will be called instead of writing - * the string value out to the target variable. - * - * The function will be passed to g_settings_get_mapped() and should - * return %TRUE if the mapping was successful and %FALSE otherwise. - * In the former case the function is expected to handle the result - * of the conversion itself and call queue_changed() appropriately; - * in particular the @result (out) parameter as returned by - * g_settings_get_mapped() will be ignored in all cases. - * - * This may be NULL. If it is, see "target", below. - */ GSettingsGetMapping handler; - - /* - * Where to write the incoming string. - * - * This must be NULL if the handler is non-NULL. - * If the incoming string is NULL, no change will be made. - */ gchar **target; - } MetaStringPreference; +typedef struct +{ + MetaBasePreference base; + GSettingsGetMapping handler; + gchar ***target; +} MetaStringArrayPreference; + typedef struct { MetaBasePreference base; gint *target; } MetaIntPreference; +typedef struct +{ + MetaBasePreference base; + unsigned int *target; +} MetaUintPreference; + /* All preferences that are not keybindings must be listed here, * plus in the GSettings schemas and the MetaPreference enum. @@ -258,6 +248,13 @@ static MetaEnumPreference preferences_enum[] = }, &focus_mode, }, + { + { "visual-bell-type", + SCHEMA_GENERAL, + META_PREF_VISUAL_BELL_TYPE, + }, + &visual_bell_type, + }, { { "action-double-click-titlebar", SCHEMA_GENERAL, @@ -279,34 +276,6 @@ static MetaEnumPreference preferences_enum[] = }, &action_right_click_titlebar, }, - { - { "action-scroll-titlebar", - SCHEMA_GENERAL, - META_PREF_ACTION_SCROLL_WHEEL_TITLEBAR, - }, - &action_scroll_titlebar, - }, - { - { "placement-mode", - SCHEMA_MUFFIN, - META_PREF_PLACEMENT_MODE, - }, - &placement_mode, - }, - { - { "background-transition", - SCHEMA_MUFFIN, - META_PREF_BACKGROUND_TRANSITION, - }, - &background_transition, - }, - { - { "sync-method", - SCHEMA_MUFFIN, - META_PREF_SYNC_METHOD, - }, - &sync_method, - }, { { NULL, 0, 0 }, NULL }, }; @@ -314,17 +283,17 @@ static MetaBoolPreference preferences_bool[] = { { { "attach-modal-dialogs", - SCHEMA_MUFFIN, + SCHEMA_MUTTER, META_PREF_ATTACH_MODAL_DIALOGS, }, &attach_modal_dialogs, }, { - { "ignore-hide-titlebar-when-maximized", - SCHEMA_MUFFIN, - META_PREF_IGNORE_HIDE_TITLEBAR_WHEN_MAXIMIZED, + { "center-new-windows", + SCHEMA_MUTTER, + META_PREF_CENTER_NEW_WINDOWS, }, - &ignore_hide_titlebar_when_maximized, + ¢er_new_windows, }, { { "raise-on-click", @@ -333,13 +302,6 @@ static MetaBoolPreference preferences_bool[] = }, &raise_on_click, }, - { - { "bring-windows-to-current-workspace", - SCHEMA_CINNAMON, - META_PREF_BRING_WINDOWS_TO_CURRENT_WORKSPACE, - }, - &bring_user_activated_windows_to_current_workspace, - }, { { "titlebar-uses-system-font", SCHEMA_GENERAL, @@ -347,75 +309,54 @@ static MetaBoolPreference preferences_bool[] = }, &use_system_font, }, - { - { "workspace-cycle", - SCHEMA_MUFFIN, - META_PREF_WORKSPACE_CYCLE, - }, - &workspace_cycle, - }, { { "dynamic-workspaces", - SCHEMA_MUFFIN, + SCHEMA_MUTTER, META_PREF_DYNAMIC_WORKSPACES, }, &dynamic_workspaces, }, { - { "unredirect-fullscreen-windows", - SCHEMA_MUFFIN, - META_PREF_UNREDIRECT_FULLSCREEN_WINDOWS, - }, - &unredirect_fullscreen_windows, - }, - { - { "desktop-effects", - SCHEMA_MUFFIN, - META_PREF_DESKTOP_EFFECTS, - }, - &desktop_effects, - }, - { - { "threaded-swap", - SCHEMA_MUFFIN, - META_PREF_THREADED_SWAP, + { "disable-workarounds", + SCHEMA_GENERAL, + META_PREF_DISABLE_WORKAROUNDS, }, - &threaded_swap, + &disable_workarounds, }, { - { "send-frame-timings", - SCHEMA_MUFFIN, - META_PREF_SEND_FRAME_TIMINGS, + { "auto-raise", + SCHEMA_GENERAL, + META_PREF_AUTO_RAISE, }, - &send_frame_timings, + &auto_raise, }, { - { "application-based", - SCHEMA_GENERAL, - META_PREF_APPLICATION_BASED, + { "focus-change-on-pointer-rest", + SCHEMA_MUTTER, + META_PREF_FOCUS_CHANGE_ON_POINTER_REST, }, - NULL, /* feature is known but disabled */ + &focus_change_on_pointer_rest }, { - { "disable-workarounds", + { "visual-bell", SCHEMA_GENERAL, - META_PREF_DISABLE_WORKAROUNDS, + META_PREF_VISUAL_BELL, }, - &disable_workarounds, + &bell_is_visible, /* FIXME: change the name: it's confusing */ }, { - { "auto-raise", + { "audible-bell", SCHEMA_GENERAL, - META_PREF_AUTO_RAISE, + META_PREF_AUDIBLE_BELL, }, - &auto_raise, + &bell_is_audible, /* FIXME: change the name: it's confusing */ }, { - { KEY_MOUSEWHEEL_ZOOM_ENABLED, - SCHEMA_A11Y_APPLICATIONS, - META_PREF_MOUSE_ZOOM_ENABLED, + { KEY_GNOME_ACCESSIBILITY, + SCHEMA_INTERFACE, + META_PREF_GNOME_ACCESSIBILITY, }, - &mouse_zoom_enabled, + &gnome_accessibility, }, { { KEY_GNOME_ANIMATIONS, @@ -433,45 +374,31 @@ static MetaBoolPreference preferences_bool[] = }, { { "edge-tiling", - SCHEMA_MUFFIN, + SCHEMA_MUTTER, META_PREF_EDGE_TILING, }, &edge_tiling, }, - { - { "edge-resistance-window", - SCHEMA_MUFFIN, - META_PREF_EDGE_RESISTANCE_WINDOW, - }, - &edge_resistance_window, - }, { { "workspaces-only-on-primary", - SCHEMA_MUFFIN, + SCHEMA_MUTTER, META_PREF_WORKSPACES_ONLY_ON_PRIMARY, }, &workspaces_only_on_primary, }, { - { "legacy-snap", - SCHEMA_MUFFIN, - META_PREF_LEGACY_SNAP, - }, - &legacy_snap, - }, - { - { "invert-workspace-flip-direction", - SCHEMA_MUFFIN, - META_PREF_INVERT_WORKSPACE_FLIP_DIRECTION, + { "auto-maximize", + SCHEMA_MUTTER, + META_PREF_AUTO_MAXIMIZE, }, - &invert_workspace_flip, + &auto_maximize, }, { - { "tile-maximize", - SCHEMA_MUFFIN, - META_PREF_TILE_MAXIMIZE, + { KEY_LOCATE_POINTER, + SCHEMA_MOUSE, + META_PREF_LOCATE_POINTER, }, - &tile_maximize, + &locate_pointer_is_enabled, }, { { NULL, 0, 0 }, NULL }, }; @@ -486,22 +413,6 @@ static MetaStringPreference preferences_string[] = mouse_button_mods_handler, NULL, }, - { - { "mouse-button-zoom-modifier", - SCHEMA_GENERAL, - META_PREF_MOUSE_BUTTON_ZOOM_MODS, - }, - mouse_button_zoom_mods_handler, - NULL, - }, - { - { "theme", - SCHEMA_GENERAL, - META_PREF_THEME, - }, - theme_name_handler, - NULL, - }, { { KEY_TITLEBAR_FONT, SCHEMA_GENERAL, @@ -527,14 +438,42 @@ static MetaStringPreference preferences_string[] = &cursor_theme, }, { - { "snap-modifier", - SCHEMA_MUFFIN, - META_PREF_SNAP_MODIFIER, + { "overlay-key", + SCHEMA_MUTTER, + META_PREF_KEYBINDINGS, + }, + overlay_key_handler, + NULL, + }, + { + { "locate-pointer-key", + SCHEMA_MUTTER, + META_PREF_KEYBINDINGS, }, - snap_modifier_handler, + locate_pointer_key_handler, NULL, }, + { { NULL, 0, 0 }, NULL }, + }; +static MetaStringArrayPreference preferences_string_array[] = + { + { + { KEY_WORKSPACE_NAMES, + SCHEMA_GENERAL, + META_PREF_WORKSPACE_NAMES, + }, + NULL, + &workspace_names, + }, + { + { KEY_XKB_OPTIONS, + SCHEMA_INPUT_SOURCES, + META_PREF_KEYBINDINGS, + }, + iso_next_group_handler, + NULL, + }, { { NULL, 0, 0 }, NULL }, }; @@ -554,51 +493,41 @@ static MetaIntPreference preferences_int[] = }, &auto_raise_delay }, - { - { "cursor-size", - SCHEMA_INTERFACE, - META_PREF_CURSOR_SIZE, - }, - &cursor_size - }, { { "draggable-border-width", - SCHEMA_MUFFIN, + SCHEMA_MUTTER, META_PREF_DRAGGABLE_BORDER_WIDTH, }, &draggable_border_width }, { - { "tile-hud-threshold", - SCHEMA_MUFFIN, - META_PREF_TILE_HUD_THRESHOLD, + { "drag-threshold", + SCHEMA_MOUSE, + META_PREF_DRAG_THRESHOLD, }, - &tile_hud_threshold + &drag_threshold }, { - { "resize-threshold", - SCHEMA_MUFFIN, - META_PREF_RESIZE_THRESHOLD, + { "cursor-size", + SCHEMA_INTERFACE, + META_PREF_CURSOR_SIZE, }, - &resize_threshold + &cursor_size }, { { NULL, 0, 0 }, NULL }, }; -/* - * This is used to keep track of override schemas used to - * override preferences from the "normal" metacity/muffin - * schemas; we modify the preferences arrays directly, but - * we also need to remember what we have done to handle - * subsequent overrides correctly. - */ -typedef struct -{ - char *key; - char *new_schema; -} MetaPrefsOverriddenKey; - -static GSList *overridden_keys; +static MetaUintPreference preferences_uint[] = + { + { + { "check-alive-timeout", + SCHEMA_MUTTER, + META_PREF_CHECK_ALIVE_TIMEOUT, + }, + &check_alive_timeout, + }, + { { NULL, 0, 0 }, NULL }, + }; static void handle_preference_init_enum (void) @@ -658,7 +587,7 @@ handle_preference_init_string (void) if (!cursor->target) meta_bug ("%s must have handler or target\n", cursor->base.key); - free (*(cursor->target)); + g_free (*(cursor->target)); value = g_settings_get_string (SETTINGS (cursor->base.schema), cursor->base.key); @@ -670,6 +599,42 @@ handle_preference_init_string (void) } } +static void +handle_preference_init_string_array (void) +{ + MetaStringArrayPreference *cursor = preferences_string_array; + + while (cursor->base.key != NULL) + { + char **value; + + /* Complex keys have a mapping function to check validity */ + if (cursor->handler) + { + if (cursor->target) + meta_bug ("%s has both a target and a handler\n", cursor->base.key); + + g_settings_get_mapped (SETTINGS (cursor->base.schema), + cursor->base.key, cursor->handler, NULL); + } + else + { + if (!cursor->target) + meta_bug ("%s must have handler or target\n", cursor->base.key); + + if (*(cursor->target)) + g_strfreev (*(cursor->target)); + + value = g_settings_get_strv (SETTINGS (cursor->base.schema), + cursor->base.key); + + *(cursor->target) = value; + } + + ++cursor; + } +} + static void handle_preference_init_int (void) { @@ -686,6 +651,21 @@ handle_preference_init_int (void) } } +static void +handle_preference_init_uint (void) +{ + MetaUintPreference *cursor = preferences_uint; + + while (cursor->base.key != NULL) + { + if (cursor->target) + *cursor->target = g_settings_get_uint (SETTINGS (cursor->base.schema), + cursor->base.key); + + ++cursor; + } +} + static void handle_preference_update_enum (GSettings *settings, gchar *key) @@ -778,7 +758,7 @@ handle_preference_update_string (GSettings *settings, inform_listeners = (g_strcmp0 (value, *(cursor->target)) != 0); - free(*(cursor->target)); + g_free(*(cursor->target)); *(cursor->target) = value; } @@ -787,6 +767,56 @@ handle_preference_update_string (GSettings *settings, queue_changed (cursor->base.pref); } +static void +handle_preference_update_string_array (GSettings *settings, + gchar *key) +{ + MetaStringArrayPreference *cursor = preferences_string_array; + gboolean inform_listeners = FALSE; + + while (cursor->base.key != NULL && strcmp (key, cursor->base.key) != 0) + ++cursor; + + if (cursor->base.key==NULL) + /* Didn't recognise that key. */ + return; + + /* Complex keys have a mapping function to check validity */ + if (cursor->handler) + { + if (cursor->target) + meta_bug ("%s has both a target and a handler\n", cursor->base.key); + + g_settings_get_mapped (SETTINGS (cursor->base.schema), + cursor->base.key, cursor->handler, NULL); + } + else + { + char **values, **previous; + int n_values, n_previous, i; + + if (!cursor->target) + meta_bug ("%s must have handler or target\n", cursor->base.key); + + values = g_settings_get_strv (SETTINGS (cursor->base.schema), + cursor->base.key); + n_values = g_strv_length (values); + previous = *(cursor->target); + n_previous = previous ? g_strv_length (previous) : 0; + + inform_listeners = n_previous != n_values; + for (i = 0; i < n_values && !inform_listeners; i++) + inform_listeners = g_strcmp0 (values[i], previous[i]) != 0; + + if (*(cursor->target)) + g_strfreev (*(cursor->target)); + *(cursor->target) = values; + } + + if (inform_listeners) + queue_changed (cursor->base.pref); +} + static void handle_preference_update_int (GSettings *settings, gchar *key) @@ -811,35 +841,61 @@ handle_preference_update_int (GSettings *settings, } } - +static void +handle_preference_update_uint (GSettings *settings, + char *key) +{ + MetaUintPreference *cursor = preferences_uint; + unsigned int new_value; + + while (cursor->base.key && strcmp (key, cursor->base.key) != 0) + ++cursor; + + if (!cursor->base.key || !cursor->target) + return; + + new_value = g_settings_get_uint (SETTINGS (cursor->base.schema), key); + + if (*cursor->target != new_value) + { + *cursor->target = new_value; + queue_changed (cursor->base.pref); + } +} + + /****************************************************************************/ /* Listeners. */ /****************************************************************************/ /** * meta_prefs_add_listener: (skip) + * @func: a #MetaPrefsChangedFunc + * @user_data: data passed to the function * */ void meta_prefs_add_listener (MetaPrefsChangedFunc func, - gpointer data) + gpointer user_data) { MetaPrefsListener *l; l = g_new (MetaPrefsListener, 1); l->func = func; - l->data = data; + l->data = user_data; listeners = g_list_prepend (listeners, l); } /** * meta_prefs_remove_listener: (skip) + * @func: a #MetaPrefsChangedFunc + * @user_data: data passed to the function * */ void meta_prefs_remove_listener (MetaPrefsChangedFunc func, - gpointer data) + gpointer user_data) { GList *tmp; @@ -849,9 +905,9 @@ meta_prefs_remove_listener (MetaPrefsChangedFunc func, MetaPrefsListener *l = tmp->data; if (l->func == func && - l->data == data) + l->data == user_data) { - free (l); + g_free (l); listeners = g_list_delete_link (listeners, tmp); return; @@ -859,8 +915,6 @@ meta_prefs_remove_listener (MetaPrefsChangedFunc func, tmp = tmp->next; } - - meta_bug ("Did not find listener to remove\n"); } static void @@ -924,44 +978,19 @@ queue_changed (MetaPreference pref) if (g_list_find (changes, GINT_TO_POINTER (pref)) == NULL) changes = g_list_prepend (changes, GINT_TO_POINTER (pref)); -#ifdef WITH_VERBOSE_MODE else meta_topic (META_DEBUG_PREFS, "Change of pref %s was already pending\n", meta_preference_to_string (pref)); -#endif - if (changed_idle == 0) - changed_idle = g_idle_add_full (META_PRIORITY_PREFS_NOTIFY, - changed_idle_handler, NULL, NULL); -} - -static void -store_initial_ui_scale (void) -{ - GValue value = G_VALUE_INIT; - - g_value_init (&value, G_TYPE_INT); - - gdk_screen_get_setting (gdk_screen_get_default (), "gdk-window-scaling-factor", &value); - ui_scale = MAX (g_value_get_int (&value), 1); // Never let it be 0; -} -static void -set_ui_scale (int new_scale) -{ - if (new_scale == ui_scale) + if (changed_idle == 0) { - return; + changed_idle = g_idle_add_full (META_PRIORITY_PREFS_NOTIFY, + changed_idle_handler, NULL, NULL); + g_source_set_name_by_id (changed_idle, "[mutter] changed_idle_handler"); } - - ui_scale = new_scale; - - meta_topic (META_DEBUG_PREFS, "UI Scale changed (to %dx), triggering frames and cursor size updates.\n", - ui_scale); - - queue_changed (META_PREF_UI_SCALE); } - + /****************************************************************************/ /* Initialisation. */ /****************************************************************************/ @@ -970,57 +999,51 @@ void meta_prefs_init (void) { GSettings *settings; - GSList *tmp; settings_schemas = g_hash_table_new_full (g_str_hash, g_str_equal, - free, g_object_unref); + g_free, g_object_unref); settings = g_settings_new (SCHEMA_GENERAL); g_signal_connect (settings, "changed", G_CALLBACK (settings_changed), NULL); g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_GENERAL), settings); - settings = g_settings_new (SCHEMA_MUFFIN); + settings = g_settings_new (SCHEMA_MUTTER); g_signal_connect (settings, "changed", G_CALLBACK (settings_changed), NULL); - g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_MUFFIN), settings); + g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_MUTTER), settings); + + settings = g_settings_new (SCHEMA_MOUSE); + g_signal_connect (settings, "changed", G_CALLBACK (settings_changed), NULL); + g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_MOUSE), settings); /* Individual keys we watch outside of our schemas */ settings = g_settings_new (SCHEMA_INTERFACE); + g_signal_connect (settings, "changed::" KEY_GNOME_ACCESSIBILITY, + G_CALLBACK (settings_changed), NULL); g_signal_connect (settings, "changed::" KEY_GNOME_ANIMATIONS, G_CALLBACK (settings_changed), NULL); g_signal_connect (settings, "changed::" KEY_GNOME_CURSOR_THEME, G_CALLBACK (settings_changed), NULL); g_signal_connect (settings, "changed::" KEY_GNOME_CURSOR_SIZE, G_CALLBACK (settings_changed), NULL); - g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_INTERFACE), settings); - - settings = g_settings_new (SCHEMA_A11Y_APPLICATIONS); - g_signal_connect (settings, "changed::" KEY_MOUSEWHEEL_ZOOM_ENABLED, + g_signal_connect (settings, "changed::" KEY_LOCATE_POINTER, G_CALLBACK (settings_changed), NULL); - g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_A11Y_APPLICATIONS), settings); + g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_INTERFACE), settings); - settings = g_settings_new (SCHEMA_CINNAMON); - g_signal_connect (settings, "changed::" KEY_BRING_ACTIVATED_WINDOWS_TO_CURRENT_WORKSPACE, + settings = g_settings_new (SCHEMA_INPUT_SOURCES); + g_signal_connect (settings, "changed::" KEY_XKB_OPTIONS, G_CALLBACK (settings_changed), NULL); - g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_CINNAMON), settings); - - for (tmp = overridden_keys; tmp; tmp = tmp->next) - { - MetaPrefsOverriddenKey *override = tmp->data; - do_override (override->key, override->new_schema); - } + g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_INPUT_SOURCES), settings); /* Pick up initial values. */ handle_preference_init_enum (); handle_preference_init_bool (); handle_preference_init_string (); + handle_preference_init_string_array (); handle_preference_init_int (); - - store_initial_ui_scale (); + handle_preference_init_uint (); init_bindings (); - init_workspace_names (); - update_min_win_opacity (); } static gboolean @@ -1050,112 +1073,9 @@ find_pref (void *prefs, } -static void -do_override (char *key, - char *schema) -{ - MetaBasePreference *pref; - GSettings *settings; - char *detailed_signal; - gpointer data; - guint handler_id; - - g_return_if_fail (settings_schemas != NULL); - - if (!find_pref (preferences_enum, sizeof(MetaEnumPreference), key, &pref) && - !find_pref (preferences_bool, sizeof(MetaBoolPreference), key, &pref) && - !find_pref (preferences_string, sizeof(MetaStringPreference), key, &pref) && - !find_pref (preferences_int, sizeof(MetaIntPreference), key, &pref)) - { - meta_warning ("Can't override preference key, \"%s\" not found\n", key); - return; - } - - settings = SETTINGS (pref->schema); - data = g_object_get_data (G_OBJECT (settings), key); - if (data) - { - handler_id = GPOINTER_TO_UINT (data); - g_signal_handler_disconnect (settings, handler_id); - } - - pref->schema = schema; - settings = SETTINGS (pref->schema); - if (!settings) - { - settings = g_settings_new (pref->schema); - g_hash_table_insert (settings_schemas, g_strdup (pref->schema), settings); - } - - detailed_signal = g_strdup_printf ("changed::%s", key); - handler_id = g_signal_connect (settings, detailed_signal, - G_CALLBACK (settings_changed), NULL); - free (detailed_signal); - - g_object_set_data (G_OBJECT (settings), key, GUINT_TO_POINTER (handler_id)); - - settings_changed (settings, key, NULL); -} - - -/** - * meta_prefs_override_preference_schema: - * @key: the preference name - * @schema: new schema for preference %key - * - * Specify a schema whose keys are used to override the standard Metacity - * keys. This might be used if a plugin expected a different value for - * some preference than the Metacity default. While this function can be - * called at any point, this function should generally be called in a - * plugin's constructor, rather than in its start() method so the preference - * isn't first loaded with one value then changed to another value. - */ -void -meta_prefs_override_preference_schema (const char *key, const char *schema) -{ - MetaPrefsOverriddenKey *overridden; - GSList *tmp; - - /* Merge identical overrides, this isn't an error */ - for (tmp = overridden_keys; tmp; tmp = tmp->next) - { - MetaPrefsOverriddenKey *tmp_overridden = tmp->data; - if (strcmp (tmp_overridden->key, key) == 0 && - strcmp (tmp_overridden->new_schema, schema) == 0) - return; - } - - overridden = NULL; - - for (tmp = overridden_keys; tmp; tmp = tmp->next) - { - MetaPrefsOverriddenKey *tmp_overridden = tmp->data; - if (strcmp (tmp_overridden->key, key) == 0) - overridden = tmp_overridden; - } - - if (overridden) - { - free (overridden->new_schema); - overridden->new_schema = g_strdup (schema); - } - else - { - overridden = g_slice_new (MetaPrefsOverriddenKey); - overridden->key = g_strdup (key); - overridden->new_schema = g_strdup (schema); - - overridden_keys = g_slist_prepend (overridden_keys, overridden); - } - - if (settings_schemas != NULL) - do_override (overridden->key, overridden->new_schema); -} - - -/****************************************************************************/ -/* Updates. */ -/****************************************************************************/ +/****************************************************************************/ +/* Updates. */ +/****************************************************************************/ static void @@ -1167,24 +1087,6 @@ settings_changed (GSettings *settings, const GVariantType *type; MetaEnumPreference *cursor; gboolean found_enum; - gchar *schema; - - g_object_get(settings, "schema", &schema, NULL); - - /* String array, handled separately */ - if (strcmp (key, KEY_WORKSPACE_NAMES) == 0) - { - if (update_workspace_names ()) - queue_changed (META_PREF_WORKSPACE_NAMES); - return; - } - - if (strcmp (key, KEY_MIN_WINDOW_OPACITY) == 0) - { - update_min_win_opacity (); - queue_changed (META_PREF_MIN_WIN_OPACITY); - return; - } value = g_settings_get_value (settings, key); type = g_variant_get_type (value); @@ -1193,6 +1095,10 @@ settings_changed (GSettings *settings, handle_preference_update_bool (settings, key); else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32)) handle_preference_update_int (settings, key); + else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32)) + handle_preference_update_uint (settings, key); + else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING_ARRAY)) + handle_preference_update_string_array (settings, key); else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING)) { cursor = preferences_enum; @@ -1212,14 +1118,10 @@ settings_changed (GSettings *settings, else handle_preference_update_string (settings, key); } - else if (g_str_equal (key, KEY_WS_NAMES_GNOME)) - { - return; - } else { - /* Someone added a preference of an unhandled type */ - g_assert_not_reached (); + /* Unknown preference type. This quite likely simply isn't + * a preference we track changes to. */ } g_variant_unref (value); @@ -1239,7 +1141,9 @@ bindings_changed (GSettings *settings, g_strfreev (strokes); } -/* +/** + * maybe_give_disable_workaround_warning: + * * Special case: give a warning the first time disable_workarounds * is turned on. */ @@ -1253,7 +1157,7 @@ maybe_give_disable_workarounds_warning (void) first_disable = FALSE; meta_warning ("Workarounds for broken applications disabled. " - "Some applications may not behave properly.\n"); + "Some applications may not behave properly.\n"); } } @@ -1263,18 +1167,6 @@ meta_prefs_get_mouse_button_mods (void) return mouse_button_mods; } -MetaVirtualModifier -meta_prefs_get_mouse_button_zoom_mods (void) -{ - return mouse_button_zoom_mods; -} - -gboolean -meta_prefs_get_mouse_zoom_enabled (void) -{ - return mouse_zoom_enabled; -} - CDesktopFocusMode meta_prefs_get_focus_mode (void) { @@ -1288,39 +1180,40 @@ meta_prefs_get_focus_new_windows (void) } gboolean -meta_prefs_get_attach_modal_dialogs (void) +meta_prefs_get_center_new_windows (void) { - return attach_modal_dialogs; + return center_new_windows; } gboolean -meta_prefs_get_ignore_hide_titlebar_when_maximized (void) +meta_prefs_get_attach_modal_dialogs (void) { - return ignore_hide_titlebar_when_maximized; + return attach_modal_dialogs; } gboolean meta_prefs_get_raise_on_click (void) { - /* Force raise_on_click on for click-to-focus, as requested by Havoc - * in #326156. - */ - return raise_on_click || focus_mode == C_DESKTOP_FOCUS_MODE_CLICK; + return raise_on_click; } gboolean -meta_prefs_get_bring_windows_to_current_workspace (void) +meta_prefs_get_show_fallback_app_menu (void) { - /* Windows that the user activates (with a current timestamp) will - * be brought to the currently active workspace if necessary. Normally - * the user is brought to the window's workspace instead. */ - return bring_user_activated_windows_to_current_workspace; + return show_fallback_app_menu; } -const char* -meta_prefs_get_theme (void) +void +meta_prefs_set_show_fallback_app_menu (gboolean whether) { - return current_theme; + gboolean changed = FALSE; + + changed = (show_fallback_app_menu == !whether); + + show_fallback_app_menu = whether; + + if (changed) + queue_changed (META_PREF_BUTTON_LAYOUT); } const char* @@ -1332,10 +1225,10 @@ meta_prefs_get_cursor_theme (void) int meta_prefs_get_cursor_size (void) { - return cursor_size * ui_scale; + return cursor_size; } - + /****************************************************************************/ /* Handlers for string preferences. */ /****************************************************************************/ @@ -1355,7 +1248,7 @@ titlebar_handler (GVariant *value, if (desc == NULL) { meta_warning ("Could not parse font description " - "\"%s\" from GSettings key %s\n", + "\"%s\" from GSettings key %s\n", string_value ? string_value : "(null)", KEY_TITLEBAR_FONT); return FALSE; @@ -1379,29 +1272,6 @@ titlebar_handler (GVariant *value, return TRUE; } -static gboolean -theme_name_handler (GVariant *value, - gpointer *result, - gpointer data) -{ - const gchar *string_value; - - *result = NULL; /* ignored */ - string_value = g_variant_get_string (value, NULL); - - if (!string_value || !*string_value) - return FALSE; - - if (g_strcmp0 (current_theme, string_value) != 0) - { - free (current_theme); - current_theme = g_strdup (string_value); - queue_changed (META_PREF_THEME); - } - - return TRUE; -} - static gboolean mouse_button_mods_handler (GVariant *value, gpointer *result, @@ -1413,13 +1283,13 @@ mouse_button_mods_handler (GVariant *value, *result = NULL; /* ignored */ string_value = g_variant_get_string (value, NULL); - if (!string_value || !meta_ui_parse_modifier (string_value, &mods)) + if (!string_value || !meta_parse_modifier (string_value, &mods)) { meta_topic (META_DEBUG_KEYBINDINGS, "Failed to parse new GSettings value\n"); meta_warning ("\"%s\" found in configuration database is " - "not a valid value for mouse button modifier\n", + "not a valid value for mouse button modifier\n", string_value); return FALSE; @@ -1438,80 +1308,6 @@ mouse_button_mods_handler (GVariant *value, return TRUE; } -static gboolean -mouse_button_zoom_mods_handler (GVariant *value, - gpointer *result, - gpointer data) -{ - MetaVirtualModifier mods; - const gchar *string_value; - - *result = NULL; /* ignored */ - string_value = g_variant_get_string (value, NULL); - - if (!string_value || !meta_ui_parse_modifier (string_value, &mods)) - { - meta_topic (META_DEBUG_KEYBINDINGS, - "Failed to parse new GSettings value\n"); - - meta_warning ("\"%s\" found in configuration database is " - "not a valid value for mouse button zoom modifier\n", - string_value); - - return FALSE; - } - - meta_topic (META_DEBUG_KEYBINDINGS, - "Mouse zoom modifier has new GSettings value \"%s\"\n", - string_value); - - if (mods != mouse_button_zoom_mods) - { - mouse_button_zoom_mods = mods; - queue_changed (META_PREF_MOUSE_BUTTON_ZOOM_MODS); - } - - return TRUE; -} - -static gboolean -snap_modifier_handler (GVariant *value, - gpointer *result, - gpointer data) -{ - - const gchar *string_value; - - *result = NULL; /* ignored */ - string_value = g_variant_get_string (value, NULL); - - if (g_strcmp0 (string_value, "Super") == 0) - { - snap_modifier[0] = XStringToKeysym("Super_L"); - snap_modifier[1] = XStringToKeysym("Super_R"); - } - else if (g_strcmp0 (string_value, "Alt") == 0) - { - snap_modifier[0] = XStringToKeysym("Alt_L"); - snap_modifier[1] = XStringToKeysym("Alt_R"); - } - else if (g_strcmp0 (string_value, "Shift") == 0) - { - snap_modifier[0] = XStringToKeysym("Shift_L"); - snap_modifier[1] = XStringToKeysym("Shift_R"); - } - else if (g_strcmp0 (string_value, "Control") == 0) - { - snap_modifier[0] = XStringToKeysym("Control_L"); - snap_modifier[1] = XStringToKeysym("Control_R"); - } else - { - snap_modifier[0] = 0; - snap_modifier[1] = 0; - } - return TRUE; -} - static gboolean button_layout_equal (const MetaButtonLayout *a, const MetaButtonLayout *b) @@ -1550,42 +1346,11 @@ button_function_from_string (const char *str) return META_BUTTON_FUNCTION_MAXIMIZE; else if (strcmp (str, "close") == 0) return META_BUTTON_FUNCTION_CLOSE; - else if (strcmp (str, "shade") == 0) - return META_BUTTON_FUNCTION_SHADE; - else if (strcmp (str, "above") == 0) - return META_BUTTON_FUNCTION_ABOVE; - else if (strcmp (str, "stick") == 0) - return META_BUTTON_FUNCTION_STICK; else /* don't know; give up */ return META_BUTTON_FUNCTION_LAST; } -static MetaButtonFunction -button_opposite_function (MetaButtonFunction ofwhat) -{ - switch (ofwhat) - { - case META_BUTTON_FUNCTION_SHADE: - return META_BUTTON_FUNCTION_UNSHADE; - case META_BUTTON_FUNCTION_UNSHADE: - return META_BUTTON_FUNCTION_SHADE; - - case META_BUTTON_FUNCTION_ABOVE: - return META_BUTTON_FUNCTION_UNABOVE; - case META_BUTTON_FUNCTION_UNABOVE: - return META_BUTTON_FUNCTION_ABOVE; - - case META_BUTTON_FUNCTION_STICK: - return META_BUTTON_FUNCTION_UNSTICK; - case META_BUTTON_FUNCTION_UNSTICK: - return META_BUTTON_FUNCTION_STICK; - - default: - return META_BUTTON_FUNCTION_LAST; - } -} - static gboolean button_layout_handler (GVariant *value, gpointer *result, @@ -1629,12 +1394,6 @@ button_layout_handler (GVariant *value, if (i > 0 && strcmp("spacer", buttons[b]) == 0) { new_layout.left_buttons_has_spacer[i-1] = TRUE; - f = button_opposite_function (f); - - if (f != META_BUTTON_FUNCTION_LAST) - { - new_layout.left_buttons_has_spacer[i-2] = TRUE; - } } else { @@ -1643,19 +1402,12 @@ button_layout_handler (GVariant *value, new_layout.left_buttons[i] = f; used[f] = TRUE; ++i; - - f = button_opposite_function (f); - - if (f != META_BUTTON_FUNCTION_LAST) - new_layout.left_buttons[i++] = f; } -#ifdef WITH_VERBOSE_MODE else { meta_topic (META_DEBUG_PREFS, "Ignoring unknown or already-used button name \"%s\"\n", buttons[b]); } -#endif } ++b; @@ -1693,11 +1445,6 @@ button_layout_handler (GVariant *value, if (i > 0 && strcmp("spacer", buttons[b]) == 0) { new_layout.right_buttons_has_spacer[i-1] = TRUE; - f = button_opposite_function (f); - if (f != META_BUTTON_FUNCTION_LAST) - { - new_layout.right_buttons_has_spacer[i-2] = TRUE; - } } else { @@ -1706,20 +1453,12 @@ button_layout_handler (GVariant *value, new_layout.right_buttons[i] = f; used[f] = TRUE; ++i; - - f = button_opposite_function (f); - - if (f != META_BUTTON_FUNCTION_LAST) - new_layout.right_buttons[i++] = f; - } -#ifdef WITH_VERBOSE_MODE else { meta_topic (META_DEBUG_PREFS, "Ignoring unknown or already-used button name \"%s\"\n", buttons[b]); } -#endif } ++b; @@ -1737,37 +1476,43 @@ button_layout_handler (GVariant *value, g_strfreev (sides); /* Invert the button layout for RTL languages */ - if (meta_ui_get_direction() == META_UI_DIRECTION_RTL) - { - MetaButtonLayout rtl_layout; - int j; + if (meta_get_locale_direction() == META_LOCALE_DIRECTION_RTL) + { + MetaButtonLayout rtl_layout; + int j; - for (i = 0; new_layout.left_buttons[i] != META_BUTTON_FUNCTION_LAST; i++); - for (j = 0; j < i; j++) - { - rtl_layout.right_buttons[j] = new_layout.left_buttons[i - j - 1]; - if (j == 0) - rtl_layout.right_buttons_has_spacer[i - 1] = new_layout.left_buttons_has_spacer[i - j - 1]; - else - rtl_layout.right_buttons_has_spacer[j - 1] = new_layout.left_buttons_has_spacer[i - j - 1]; - } - rtl_layout.right_buttons[j] = META_BUTTON_FUNCTION_LAST; - rtl_layout.right_buttons_has_spacer[j] = FALSE; + for (i = 0; new_layout.left_buttons[i] != META_BUTTON_FUNCTION_LAST; i++); + for (j = 0; j < i; j++) + { + rtl_layout.right_buttons[j] = new_layout.left_buttons[i - j - 1]; + if (j == 0) + rtl_layout.right_buttons_has_spacer[i - 1] = new_layout.left_buttons_has_spacer[i - j - 1]; + else + rtl_layout.right_buttons_has_spacer[j - 1] = new_layout.left_buttons_has_spacer[i - j - 1]; + } + for (; j < MAX_BUTTONS_PER_CORNER; j++) + { + rtl_layout.right_buttons[j] = META_BUTTON_FUNCTION_LAST; + rtl_layout.right_buttons_has_spacer[j] = FALSE; + } - for (i = 0; new_layout.right_buttons[i] != META_BUTTON_FUNCTION_LAST; i++); - for (j = 0; j < i; j++) - { - rtl_layout.left_buttons[j] = new_layout.right_buttons[i - j - 1]; - if (j == 0) - rtl_layout.left_buttons_has_spacer[i - 1] = new_layout.right_buttons_has_spacer[i - j - 1]; - else - rtl_layout.left_buttons_has_spacer[j - 1] = new_layout.right_buttons_has_spacer[i - j - 1]; - } - rtl_layout.left_buttons[j] = META_BUTTON_FUNCTION_LAST; - rtl_layout.left_buttons_has_spacer[j] = FALSE; + for (i = 0; new_layout.right_buttons[i] != META_BUTTON_FUNCTION_LAST; i++); + for (j = 0; j < i; j++) + { + rtl_layout.left_buttons[j] = new_layout.right_buttons[i - j - 1]; + if (j == 0) + rtl_layout.left_buttons_has_spacer[i - 1] = new_layout.right_buttons_has_spacer[i - j - 1]; + else + rtl_layout.left_buttons_has_spacer[j - 1] = new_layout.right_buttons_has_spacer[i - j - 1]; + } + for (; j < MAX_BUTTONS_PER_CORNER; j++) + { + rtl_layout.left_buttons[j] = META_BUTTON_FUNCTION_LAST; + rtl_layout.left_buttons_has_spacer[j] = FALSE; + } - new_layout = rtl_layout; - } + new_layout = rtl_layout; + } if (!button_layout_equal (&button_layout, &new_layout)) { @@ -1778,69 +1523,120 @@ button_layout_handler (GVariant *value, return TRUE; } -const PangoFontDescription* -meta_prefs_get_titlebar_font (void) +static gboolean +overlay_key_handler (GVariant *value, + gpointer *result, + gpointer data) { - if (use_system_font) - return NULL; + MetaKeyCombo combo; + const gchar *string_value; + + *result = NULL; /* ignored */ + string_value = g_variant_get_string (value, NULL); + + if (string_value && meta_parse_accelerator (string_value, &combo)) + ; else - return titlebar_font; -} + { + meta_topic (META_DEBUG_KEYBINDINGS, + "Failed to parse value for overlay-key\n"); + return FALSE; + } -int -meta_prefs_get_num_workspaces (void) -{ - return num_workspaces; -} + combo.modifiers = 0; -gboolean -meta_prefs_get_workspace_cycle (void) -{ - return workspace_cycle; -} + if (overlay_key_combo.keysym != combo.keysym || + overlay_key_combo.keycode != combo.keycode) + { + overlay_key_combo = combo; + queue_changed (META_PREF_KEYBINDINGS); + } -gboolean -meta_prefs_get_dynamic_workspaces (void) -{ - return dynamic_workspaces; + return TRUE; } -gboolean -meta_prefs_get_unredirect_fullscreen_windows (void) +static gboolean +locate_pointer_key_handler (GVariant *value, + gpointer *result, + gpointer data) { - return unredirect_fullscreen_windows; -} + MetaKeyCombo combo; + const gchar *string_value; -gboolean -meta_prefs_get_desktop_effects (void) -{ - return desktop_effects; + *result = NULL; /* ignored */ + string_value = g_variant_get_string (value, NULL); + + if (!string_value || !meta_parse_accelerator (string_value, &combo)) + { + meta_topic (META_DEBUG_KEYBINDINGS, + "Failed to parse value for locate-pointer-key\n"); + return FALSE; + } + + combo.modifiers = 0; + + if (locate_pointer_key_combo.keysym != combo.keysym || + locate_pointer_key_combo.keycode != combo.keycode) + { + locate_pointer_key_combo = combo; + queue_changed (META_PREF_KEYBINDINGS); + } + + return TRUE; } -MetaSyncMethod -meta_prefs_get_sync_method (void) +static gboolean +iso_next_group_handler (GVariant *value, + gpointer *result, + gpointer data) { - return sync_method; + const char **xkb_options, **p; + const char *option = NULL; + gboolean changed = FALSE; + + *result = NULL; /* ignored */ + xkb_options = g_variant_get_strv (value, NULL); + + for (p = xkb_options; p && *p; ++p) + if (g_str_has_prefix (*p, "grp:")) + { + option = (*p + 4); + break; + } + + changed = (g_strcmp0 (option, iso_next_group_option) != 0); + + if (changed) + { + g_free (iso_next_group_option); + iso_next_group_option = g_strdup (option); + queue_changed (META_PREF_KEYBINDINGS); + } + + g_free (xkb_options); + + return TRUE; } -gboolean -meta_prefs_get_threaded_swap (void) +const PangoFontDescription* +meta_prefs_get_titlebar_font (void) { - return threaded_swap; + if (use_system_font) + return NULL; + else + return titlebar_font; } -gboolean -meta_prefs_get_send_frame_timings (void) +int +meta_prefs_get_num_workspaces (void) { - return send_frame_timings; + return num_workspaces; } gboolean -meta_prefs_get_application_based (void) +meta_prefs_get_dynamic_workspaces (void) { - return FALSE; /* For now, we never want this to do anything */ - - return application_based; + return dynamic_workspaces; } gboolean @@ -1859,36 +1655,27 @@ meta_preference_to_string (MetaPreference pref) case META_PREF_MOUSE_BUTTON_MODS: return "MOUSE_BUTTON_MODS"; - case META_PREF_MOUSE_BUTTON_ZOOM_MODS: - return "MOUSE_BUTTON_ZOOM_MODS"; - - case META_PREF_MOUSE_ZOOM_ENABLED: - return "MOUSE_ZOOM_ENABLED"; - case META_PREF_FOCUS_MODE: return "FOCUS_MODE"; case META_PREF_FOCUS_NEW_WINDOWS: return "FOCUS_NEW_WINDOWS"; + case META_PREF_CENTER_NEW_WINDOWS: + return "CENTER_NEW_WINDOWS"; + case META_PREF_ATTACH_MODAL_DIALOGS: return "ATTACH_MODAL_DIALOGS"; case META_PREF_RAISE_ON_CLICK: return "RAISE_ON_CLICK"; - case META_PREF_THEME: - return "THEME"; - case META_PREF_TITLEBAR_FONT: return "TITLEBAR_FONT"; case META_PREF_NUM_WORKSPACES: return "NUM_WORKSPACES"; - case META_PREF_APPLICATION_BASED: - return "APPLICATION_BASED"; - case META_PREF_KEYBINDINGS: return "KEYBINDINGS"; @@ -1904,21 +1691,33 @@ meta_preference_to_string (MetaPreference pref) case META_PREF_ACTION_RIGHT_CLICK_TITLEBAR: return "ACTION_RIGHT_CLICK_TITLEBAR"; - case META_PREF_ACTION_SCROLL_WHEEL_TITLEBAR: - return "ACTION_SCROLL_WHEEL_TITLEBAR"; - case META_PREF_AUTO_RAISE: return "AUTO_RAISE"; case META_PREF_AUTO_RAISE_DELAY: return "AUTO_RAISE_DELAY"; + case META_PREF_FOCUS_CHANGE_ON_POINTER_REST: + return "FOCUS_CHANGE_ON_POINTER_REST"; + case META_PREF_BUTTON_LAYOUT: return "BUTTON_LAYOUT"; case META_PREF_WORKSPACE_NAMES: return "WORKSPACE_NAMES"; + case META_PREF_VISUAL_BELL: + return "VISUAL_BELL"; + + case META_PREF_AUDIBLE_BELL: + return "AUDIBLE_BELL"; + + case META_PREF_VISUAL_BELL_TYPE: + return "VISUAL_BELL_TYPE"; + + case META_PREF_GNOME_ACCESSIBILITY: + return "GNOME_ACCESSIBILTY"; + case META_PREF_GNOME_ANIMATIONS: return "GNOME_ANIMATIONS"; @@ -1934,75 +1733,30 @@ meta_preference_to_string (MetaPreference pref) case META_PREF_EDGE_TILING: return "EDGE_TILING"; - case META_PREF_EDGE_RESISTANCE_WINDOW: - return "EDGE_RESISTANCE_WINDOW"; - case META_PREF_FORCE_FULLSCREEN: return "FORCE_FULLSCREEN"; case META_PREF_WORKSPACES_ONLY_ON_PRIMARY: return "WORKSPACES_ONLY_ON_PRIMARY"; - case META_PREF_WORKSPACE_CYCLE: - return "WORKSPACE_CYCLE"; - - case META_PREF_VISUAL_BELL: - return "VISUAL_BELL"; - - case META_PREF_AUDIBLE_BELL: - return "AUDIBLE_BELL"; - - case META_PREF_VISUAL_BELL_TYPE: - return "VISUAL_BELL_TYPE"; - case META_PREF_DRAGGABLE_BORDER_WIDTH: return "DRAGGABLE_BORDER_WIDTH"; - case META_PREF_TILE_HUD_THRESHOLD: - return "TILE_HUD_THRESHOLD"; - - case META_PREF_RESIZE_THRESHOLD: - return "RESIZE_THRESHOLD"; + case META_PREF_DRAG_THRESHOLD: + return "DRAG_THRESHOLD"; case META_PREF_DYNAMIC_WORKSPACES: return "DYNAMIC_WORKSPACES"; - case META_PREF_UNREDIRECT_FULLSCREEN_WINDOWS: - return "UNREDIRECT_FULLSCREEN_WINDOWS"; - - case META_PREF_SYNC_METHOD: - return "SYNC_METHOD"; - - case META_PREF_THREADED_SWAP: - return "THREADED_SWAP"; + case META_PREF_AUTO_MAXIMIZE: + return "AUTO_MAXIMIZE"; - case META_PREF_SEND_FRAME_TIMINGS: - return "SEND_FRAME_TIMINGS"; + case META_PREF_LOCATE_POINTER: + return "LOCATE_POINTER"; - case META_PREF_SNAP_MODIFIER: - return "SNAP_MODIFIER"; - - case META_PREF_LEGACY_SNAP: - return "LEGACY_SNAP"; - - case META_PREF_INVERT_WORKSPACE_FLIP_DIRECTION: - return "INVERT_WORKSPACE_FLIP_DIRECTION"; - - case META_PREF_TILE_MAXIMIZE: - return "TILE_MAXIMIZE"; - - case META_PREF_PLACEMENT_MODE: - return "PLACEMENT_MODE"; - - case META_PREF_BACKGROUND_TRANSITION: - return "BACKGROUND_TRANSITION"; - - case META_PREF_MIN_WIN_OPACITY: - return "MIN_WIN_OPACITY"; - - case META_PREF_BRING_WINDOWS_TO_CURRENT_WORKSPACE: - return "BRING_WINDOWS_TO_CURRENT_WORKSPACE"; - } + case META_PREF_CHECK_ALIVE_TIMEOUT: + return "CHECK_ALIVE_TIMEOUT"; + } return "(unknown)"; } @@ -2011,14 +1765,15 @@ meta_preference_to_string (MetaPreference pref) void meta_prefs_set_num_workspaces (int n_workspaces) { - MetaBasePreference *pref = NULL; - - find_pref (preferences_int, sizeof(MetaIntPreference), - KEY_NUM_WORKSPACES, &pref); + MetaBasePreference *pref; - g_settings_set_int (SETTINGS (pref->schema), - KEY_NUM_WORKSPACES, - n_workspaces); + if (find_pref (preferences_int, sizeof(MetaIntPreference), + KEY_NUM_WORKSPACES, &pref)) + { + g_settings_set_int (SETTINGS (pref->schema), + KEY_NUM_WORKSPACES, + n_workspaces); + } } static GHashTable *key_bindings; @@ -2028,92 +1783,107 @@ meta_key_pref_free (MetaKeyPref *pref) { update_binding (pref, NULL); - free (pref->name); - free (pref->schema); + g_free (pref->name); + g_object_unref (pref->settings); - free (pref); + g_free (pref); } + static void init_bindings (void) { - key_bindings = g_hash_table_new_full (g_str_hash, g_str_equal, free, + MetaKeyPref *pref; + + key_bindings = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)meta_key_pref_free); -} -static void -init_workspace_names (void) -{ - update_workspace_names (); + pref = g_new0 (MetaKeyPref, 1); + pref->name = g_strdup ("overlay-key"); + pref->action = META_KEYBINDING_ACTION_OVERLAY_KEY; + pref->combos = g_slist_prepend (pref->combos, &overlay_key_combo); + pref->builtin = 1; + + g_hash_table_insert (key_bindings, g_strdup (pref->name), pref); + + pref = g_new0 (MetaKeyPref, 1); + pref->name = g_strdup ("locate-pointer-key"); + pref->action = META_KEYBINDING_ACTION_LOCATE_POINTER_KEY; + pref->combos = g_slist_prepend (pref->combos, &locate_pointer_key_combo); + pref->builtin = 1; + + g_hash_table_insert (key_bindings, g_strdup (pref->name), pref); } static gboolean update_binding (MetaKeyPref *binding, gchar **strokes) { - unsigned int keysym; - unsigned int keycode; - MetaVirtualModifier mods; - MetaKeyCombo *combo; + GSList *old_combos, *a, *b; + gboolean changed; int i; meta_topic (META_DEBUG_KEYBINDINGS, "Binding \"%s\" has new GSettings value\n", binding->name); - /* Okay, so, we're about to provide a new list of key combos for this - * action. Delete any pre-existing list. - */ - g_slist_foreach (binding->bindings, (GFunc) free, NULL); - g_slist_free (binding->bindings); - binding->bindings = NULL; + old_combos = binding->combos; + binding->combos = NULL; for (i = 0; strokes && strokes[i]; i++) { - keysym = 0; - keycode = 0; - mods = 0; + MetaKeyCombo *combo; + + combo = g_malloc0 (sizeof (MetaKeyCombo)); - if (!meta_ui_parse_accelerator (strokes[i], &keysym, &keycode, &mods)) + if (!meta_parse_accelerator (strokes[i], combo)) { meta_topic (META_DEBUG_KEYBINDINGS, "Failed to parse new GSettings value\n"); meta_warning ("\"%s\" found in configuration database is not a valid value for keybinding \"%s\"\n", strokes[i], binding->name); + g_free (combo); + /* Value is kept and will thus be removed next time we save the key. * Changing the key in response to a modification could lead to cyclic calls. */ continue; } - /* Bug 329676: Bindings which can be shifted must not have no modifiers, - * nor only SHIFT as a modifier. - */ + binding->combos = g_slist_prepend (binding->combos, combo); + } - if (binding->add_shift && - 0 != keysym && - (META_VIRTUAL_SHIFT_MASK == mods || 0 == mods)) - { - meta_warning ("Cannot bind \"%s\" to %s: it needs a modifier " - "such as Ctrl or Alt.\n", - binding->name, strokes[i]); + binding->combos = g_slist_reverse (binding->combos); - /* Value is kept and will thus be removed next time we save the key. - * Changing the key in response to a modification could lead to cyclic calls. */ - continue; + a = old_combos; + b = binding->combos; + while (TRUE) + { + if ((!a && b) || (a && !b)) + { + changed = TRUE; + break; + } + else if (!a && !b) + { + changed = FALSE; + break; + } + else if (memcmp (a->data, b->data, sizeof (MetaKeyCombo)) != 0) + { + changed = TRUE; + break; } + else + { + a = a->next; + b = b->next; + } + } - combo = calloc (1, sizeof (MetaKeyCombo)); - combo->keysym = keysym; - combo->keycode = keycode; - combo->modifiers = mods; - binding->bindings = g_slist_prepend (binding->bindings, combo); + g_slist_free_full (old_combos, g_free); - meta_topic (META_DEBUG_KEYBINDINGS, - "New keybinding for \"%s\" is keysym = 0x%x keycode = 0x%x mods = 0x%x\n", - binding->name, keysym, keycode, mods); - } - return TRUE; + return changed; } static gboolean @@ -2128,53 +1898,6 @@ update_key_binding (const char *key, return FALSE; } -static gboolean -update_workspace_names (void) -{ - int i; - char **names; - int n_workspace_names, n_names; - gboolean changed = FALSE; - - names = g_settings_get_strv (SETTINGS (SCHEMA_GENERAL), KEY_WORKSPACE_NAMES); - n_names = g_strv_length (names); - n_workspace_names = workspace_names ? g_strv_length (workspace_names) : 0; - - for (i = 0; i < n_names; i++) - if (n_workspace_names < i + 1 || !workspace_names[i] || - g_strcmp0 (names[i], workspace_names[i]) != 0) - { - changed = TRUE; - break; - } - - if (n_workspace_names != n_names) - changed = TRUE; - - if (changed) - { - if (workspace_names) - g_strfreev (workspace_names); - workspace_names = names; - } - else - g_strfreev (names); - - return changed; -} - -static void -update_min_win_opacity (void) -{ - int pct; - int mapped; - - pct = g_settings_get_int (SETTINGS (SCHEMA_GENERAL), KEY_MIN_WINDOW_OPACITY); - mapped = (int)(((double)pct / 100.0) * 255.0); - - min_window_opacity = CLAMP (mapped, 0, 255); -} - const char* meta_prefs_get_workspace_name (int i) { @@ -2184,9 +1907,9 @@ meta_prefs_get_workspace_name (int i) g_strv_length (workspace_names) < (guint)i + 1 || !*workspace_names[i]) { - char *generated_name = g_strdup_printf ("Workspace %d", i + 1); + char *generated_name = g_strdup_printf (_("Workspace %d"), i + 1); name = g_intern_string (generated_name); - free (generated_name); + g_free (generated_name); } else name = workspace_names[i]; @@ -2215,14 +1938,12 @@ meta_prefs_change_workspace_name (int num, * to avoid saving it literally. */ if (g_strcmp0 (name, meta_prefs_get_workspace_name (num)) == 0) { -#ifdef WITH_VERBOSE_MODE if (!name || !*name) meta_topic (META_DEBUG_PREFS, "Workspace %d already uses default name\n", num); else meta_topic (META_DEBUG_PREFS, "Workspace %d already has name %s\n", num, name); -#endif return; } @@ -2248,26 +1969,42 @@ meta_prefs_change_workspace_name (int num, } /** - * meta_prefs_get_button_layout: - * @button_layout_p: (out): the #MetaButtonLayout - * - * Returns the titlebar button definitions. - */ + * meta_prefs_get_button_layout: + * @button_layout: (out): + */ void meta_prefs_get_button_layout (MetaButtonLayout *button_layout_p) { *button_layout_p = button_layout; } -LOCAL_SYMBOL gboolean +gboolean +meta_prefs_get_visual_bell (void) +{ + return bell_is_visible; +} + +gboolean +meta_prefs_bell_is_audible (void) +{ + return bell_is_audible; +} + +CDesktopVisualBellType +meta_prefs_get_visual_bell_type (void) +{ + return visual_bell_type; +} + +gboolean meta_prefs_add_keybinding (const char *name, - const char *schema, + GSettings *settings, MetaKeyBindingAction action, MetaKeyBindingFlags flags) { MetaKeyPref *pref; - GSettings *settings; char **strokes; + guint id; if (g_hash_table_lookup (key_bindings, name)) { @@ -2275,53 +2012,48 @@ meta_prefs_add_keybinding (const char *name, return FALSE; } - settings = SETTINGS (schema); - if (settings == NULL) - { - settings = g_settings_new (schema); - if ((flags & META_KEY_BINDING_BUILTIN) != 0) - g_signal_connect (settings, "changed", - G_CALLBACK (bindings_changed), NULL); - g_hash_table_insert (settings_schemas, g_strdup (schema), settings); - } - pref = g_new0 (MetaKeyPref, 1); pref->name = g_strdup (name); - pref->schema = g_strdup (schema); + pref->settings = g_object_ref (settings); pref->action = action; - pref->bindings = NULL; - pref->add_shift = (flags & META_KEY_BINDING_REVERSES) != 0; - pref->per_window = (flags & META_KEY_BINDING_PER_WINDOW) != 0; + pref->combos = NULL; pref->builtin = (flags & META_KEY_BINDING_BUILTIN) != 0; - strokes = g_settings_get_strv (settings, name); - update_binding (pref, strokes); - g_strfreev (strokes); - - g_hash_table_insert (key_bindings, g_strdup (name), pref); - - if (!pref->builtin) + if (pref->builtin) + { + if (g_object_get_data (G_OBJECT (settings), "changed-signal") == NULL) + { + id = g_signal_connect (settings, "changed", + G_CALLBACK (bindings_changed), NULL); + g_object_set_data (G_OBJECT (settings), "changed-signal", GUINT_TO_POINTER (id)); + } + } + else { - guint id; char *changed_signal = g_strdup_printf ("changed::%s", name); id = g_signal_connect (settings, changed_signal, G_CALLBACK (bindings_changed), NULL); - free (changed_signal); + g_free (changed_signal); g_object_set_data (G_OBJECT (settings), name, GUINT_TO_POINTER (id)); queue_changed (META_PREF_KEYBINDINGS); } + strokes = g_settings_get_strv (settings, name); + update_binding (pref, strokes); + g_strfreev (strokes); + + g_hash_table_insert (key_bindings, g_strdup (name), pref); + return TRUE; } -LOCAL_SYMBOL gboolean +gboolean meta_prefs_remove_keybinding (const char *name) { MetaKeyPref *pref; - GSettings *settings; - guint id; + gulong id; pref = g_hash_table_lookup (key_bindings, name); if (!pref) @@ -2336,9 +2068,8 @@ meta_prefs_remove_keybinding (const char *name) return FALSE; } - settings = SETTINGS (pref->schema); - id = GPOINTER_TO_UINT (g_object_steal_data (G_OBJECT (settings), name)); - g_signal_handler_disconnect (settings, id); + id = GPOINTER_TO_UINT (g_object_steal_data (G_OBJECT (pref->settings), name)); + g_clear_signal_handler (&id, pref->settings); g_hash_table_remove (key_bindings, name); @@ -2347,65 +2078,40 @@ meta_prefs_remove_keybinding (const char *name) return TRUE; } -LOCAL_SYMBOL gboolean -meta_prefs_add_custom_keybinding (const char *name, - const char **bindings, - MetaKeyBindingAction action, - MetaKeyBindingFlags flags) +GList * +meta_prefs_get_keybindings (void) { - MetaKeyPref *pref; - - - if (g_hash_table_lookup (key_bindings, name)) - { - meta_warning ("Trying to re-add custom keybinding \"%s\".\n", name); - return FALSE; - } - - pref = g_new0 (MetaKeyPref, 1); - pref->name = g_strdup (name); - pref->schema = NULL; - pref->action = action; - pref->bindings = NULL; - pref->add_shift = (flags & META_KEY_BINDING_REVERSES) != 0; - pref->per_window = (flags & META_KEY_BINDING_PER_WINDOW) != 0; - pref->builtin = (flags & META_KEY_BINDING_BUILTIN) != 0; - - update_binding (pref, (gchar **)bindings); - - g_hash_table_insert (key_bindings, g_strdup (name), pref); - - return TRUE; + return g_hash_table_get_values (key_bindings); } -LOCAL_SYMBOL gboolean -meta_prefs_remove_custom_keybinding (const char *name) +void +meta_prefs_get_overlay_binding (MetaKeyCombo *combo) { - MetaKeyPref *pref; - - pref = g_hash_table_lookup (key_bindings, name); - if (!pref) - { - meta_warning ("Trying to remove non-existent custom keybinding \"%s\".\n", name); - return FALSE; - } + *combo = overlay_key_combo; +} - g_hash_table_remove (key_bindings, name); +void +meta_prefs_get_locate_pointer_binding (MetaKeyCombo *combo) +{ + *combo = locate_pointer_key_combo; +} - queue_changed (META_PREF_KEYBINDINGS); +gboolean +meta_prefs_is_locate_pointer_enabled (void) +{ + return locate_pointer_is_enabled; +} - return TRUE; +unsigned int +meta_prefs_get_check_alive_timeout (void) +{ + return check_alive_timeout; } -/** - * meta_prefs_get_keybindings: - * - * Returns: (element-type MetaKeyPref) (transfer container): - */ -GList * -meta_prefs_get_keybindings () +const char * +meta_prefs_get_iso_next_group_option (void) { - return g_hash_table_get_values (key_bindings); + return iso_next_group_option; } CDesktopTitlebarAction @@ -2426,12 +2132,6 @@ meta_prefs_get_action_right_click_titlebar (void) return action_right_click_titlebar; } -CDesktopTitlebarScrollAction -meta_prefs_get_action_scroll_wheel_titlebar (void) -{ - return action_scroll_titlebar; -} - gboolean meta_prefs_get_auto_raise (void) { @@ -2445,21 +2145,33 @@ meta_prefs_get_auto_raise_delay (void) } gboolean -meta_prefs_get_gnome_animations () +meta_prefs_get_focus_change_on_pointer_rest (void) +{ + return focus_change_on_pointer_rest; +} + +gboolean +meta_prefs_get_gnome_accessibility (void) +{ + return gnome_accessibility; +} + +gboolean +meta_prefs_get_gnome_animations (void) { return gnome_animations; } gboolean -meta_prefs_get_edge_tiling () +meta_prefs_get_edge_tiling (void) { return edge_tiling; } gboolean -meta_prefs_get_edge_resistance_window () +meta_prefs_get_auto_maximize (void) { - return edge_resistance_window; + return auto_maximize; } MetaKeyBindingAction @@ -2471,50 +2183,13 @@ meta_prefs_get_keybinding_action (const char *name) : META_KEYBINDING_ACTION_NONE; } -/* This is used by the menu system to decide what key binding - * to display next to an option. We return the first non-disabled - * binding, if any. - */ -void -meta_prefs_get_window_binding (const char *name, - unsigned int *keysym, - MetaVirtualModifier *modifiers) -{ - MetaKeyPref *pref = g_hash_table_lookup (key_bindings, name); - - if (pref->per_window) - { - GSList *s = pref->bindings; - - while (s) - { - MetaKeyCombo *c = s->data; - - if (c->keysym != 0 || c->modifiers != 0) - { - *keysym = c->keysym; - *modifiers = c->modifiers; - return; - } - - s = s->next; - } - - /* Not found; return the disabled value */ - *keysym = *modifiers = 0; - return; - } - - g_assert_not_reached (); -} - -guint +gint meta_prefs_get_mouse_button_resize (void) { return resize_with_right_button ? 3: 2; } -guint +gint meta_prefs_get_mouse_button_menu (void) { return resize_with_right_button ? 2: 3; @@ -2532,28 +2207,16 @@ meta_prefs_get_workspaces_only_on_primary (void) return workspaces_only_on_primary; } -gboolean -meta_prefs_get_legacy_snap (void) -{ - return legacy_snap; -} - int meta_prefs_get_draggable_border_width (void) { - return draggable_border_width * ui_scale; + return draggable_border_width; } int -meta_prefs_get_tile_hud_threshold (void) +meta_prefs_get_drag_threshold (void) { - return tile_hud_threshold * ui_scale; -} - -int -meta_prefs_get_resize_threshold (void) -{ - return resize_threshold * ui_scale; + return drag_threshold; } void @@ -2561,51 +2224,3 @@ meta_prefs_set_force_fullscreen (gboolean whether) { force_fullscreen = whether; } - -unsigned int * -meta_prefs_get_snap_modifier (void) -{ - return snap_modifier; -} - -gboolean -meta_prefs_get_invert_flip_direction (void) -{ - return invert_workspace_flip; -} - -gboolean -meta_prefs_get_tile_maximize (void) -{ - return tile_maximize; -} - -MetaPlacementMode -meta_prefs_get_placement_mode (void) -{ - return placement_mode; -} - -MetaBackgroundTransition -meta_prefs_get_background_transition (void) -{ - return background_transition; -} - -gint -meta_prefs_get_min_win_opacity (void) -{ - return min_window_opacity; -} - -gint -meta_prefs_get_ui_scale (void) -{ - return ui_scale; -} - -void -meta_prefs_set_ui_scale (int new_scale) -{ - set_ui_scale (new_scale); -} \ No newline at end of file diff --git a/src/core/restart-helper.c b/src/core/restart-helper.c index b0c183b26..ccd431280 100644 --- a/src/core/restart-helper.c +++ b/src/core/restart-helper.c @@ -4,10 +4,10 @@ * SECTION:restart-helper * @short_description: helper program during a restart * - * To smoothly restart Muffin, we want to keep the composite + * To smoothly restart Mutter, we want to keep the composite * overlay window enabled during the restart. This is done by * spawning this program, which keeps a reference to the the composite - * overlay window until Muffin picks it back up. + * overlay window until Mutter picks it back up. */ /* @@ -27,6 +27,8 @@ * along with this program; if not, see <http://www.gnu.org/licenses/>. */ +#include "config.h" + #include <stdlib.h> #include <stdio.h> #include <X11/Xlib.h> @@ -60,9 +62,9 @@ main (int argc, selection_window, CurrentTime); - /* Muffin looks for an (arbitrary) line printed to stdout to know that + /* Mutter looks for an (arbitrary) line printed to stdout to know that * we have started and have a reference to the COW. XSync() so that - * everything is set on the X server before Muffin starts restarting. + * everything is set on the X server before Mutter starts restarting. */ XSync (display, False); @@ -74,7 +76,7 @@ main (int argc, XEvent xev; XNextEvent (display, &xev); - /* Muffin restarted and unset the selection to indicate that + /* Mutter restarted and unset the selection to indicate that * it has a reference on the COW again */ if (xev.xany.type == SelectionClear) return 0; diff --git a/src/core/restart.c b/src/core/restart.c index 725e117af..55bec7e02 100644 --- a/src/core/restart.c +++ b/src/core/restart.c @@ -21,7 +21,7 @@ * SECTION:restart * @short_description: Smoothly restart the compositor * - * There are some cases where we need to restart Muffin in order + * There are some cases where we need to restart Mutter in order * to deal with changes in state - the particular case inspiring * this is enabling or disabling stereo output. To make this * fairly smooth for the user, we need to do two things: @@ -34,24 +34,32 @@ * This handles both of these. */ -#include <config.h> +#include "config.h" -#include <clutter/clutter.h> #include <gio/gunixinputstream.h> -#include <meta/main.h> -#include "ui.h" -#include <meta/util.h> -#include "display-private.h" +#include "clutter/clutter.h" +#include "core/display-private.h" +#include "core/util-private.h" +#include "meta/main.h" +#include "ui/ui.h" +#include "x11/meta-x11-display-private.h" static gboolean restart_helper_started = FALSE; -static gboolean restart_stage_shown = FALSE; +static gboolean restart_message_shown = FALSE; +static gboolean is_restart = FALSE; + +void +meta_set_is_restart (gboolean whether) +{ + is_restart = whether; +} static void restart_check_ready (void) { - if (restart_helper_started && restart_stage_shown) - meta_display_restart (meta_get_display ()); + if (restart_helper_started && restart_message_shown) + meta_display_request_restart (meta_get_display ()); } static void @@ -71,7 +79,7 @@ restart_helper_read_line_callback (GObject *source_object, error ? error->message : NULL); } else - free (line); /* We don't actually care what the restart helper outputs */ + g_free (line); /* We don't actually care what the restart helper outputs */ g_object_unref (source_object); @@ -80,9 +88,9 @@ restart_helper_read_line_callback (GObject *source_object, } static gboolean -restart_stage_painted (gpointer data) +restart_message_painted (gpointer data) { - restart_stage_shown = TRUE; + restart_message_shown = TRUE; restart_check_ready (); return FALSE; @@ -90,11 +98,18 @@ restart_stage_painted (gpointer data) /** * meta_restart: + * @message: (allow-none): message to display to the user, or %NULL * - * Starts the process of restarting the compositor. + * Starts the process of restarting the compositor. Note that Mutter's + * involvement here is to make the restart visually smooth for the + * user - it cannot itself safely reexec a program that embeds libmuttter. + * So in order for this to work, the compositor must handle two + * signals - MetaDisplay::show-restart-message, to display the + * message passed here on the Clutter stage, and ::restart to actually + * reexec the compositor. */ void -meta_restart (void) +meta_restart (const char *message) { MetaDisplay *display = meta_get_display(); GInputStream *unix_stream; @@ -103,15 +118,23 @@ meta_restart (void) int helper_out_fd; static const char * const helper_argv[] = { - MUFFIN_LIBEXECDIR "/muffin-restart-helper", NULL + MUTTER_LIBEXECDIR "/muffin-restart-helper", NULL }; - meta_display_notify_restart (display); - - /* Wait until the stage was painted */ - clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_POST_PAINT, - restart_stage_painted, - NULL, NULL); + if (message && meta_display_show_restart_message (display, message)) + { + /* Wait until the stage was painted */ + clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_POST_PAINT, + restart_message_painted, + NULL, NULL); + } + else + { + /* Can't show the message, show the message as soon as the + * restart helper starts + */ + restart_message_painted (NULL); + } /* We also need to wait for the restart helper to get its * reference to the Composite Overlay Window. @@ -156,4 +179,18 @@ meta_restart (void) restart_check_ready (); return; -} \ No newline at end of file +} + +/** + * meta_is_restart: + * + * Returns %TRUE if this instance of Mutter comes from Mutter + * restarting itself (for example to enable/disable stereo.) + * See meta_restart(). If this is the case, any startup visuals + * or animations should be suppressed. + */ +gboolean +meta_is_restart (void) +{ + return is_restart; +} diff --git a/src/core/screen-private.h b/src/core/screen-private.h deleted file mode 100644 index 52dfd2548..000000000 --- a/src/core/screen-private.h +++ /dev/null @@ -1,250 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/** - * \file screen-private.h Screens which Muffin manages - * - * Managing X screens. - * This file contains methods on this class which are available to - * routines in core but not outside it. (See screen.h for the routines - * which the rest of the world is allowed to use.) - */ - -/* - * Copyright (C) 2001 Havoc Pennington - * Copyright (C) 2003 Rob Adams - * Copyright (C) 2004-2006 Elijah Newren - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. - */ - -#ifndef META_SCREEN_PRIVATE_H -#define META_SCREEN_PRIVATE_H - -#include "display-private.h" -#include <meta/screen.h> -#include <X11/Xutil.h> -#include "stack-tracker.h" -#include "ui.h" - -typedef struct _MetaMonitorInfo MetaMonitorInfo; - -struct _MetaMonitorInfo -{ - int number; - MetaRectangle rect; - gboolean is_primary; - gboolean in_fullscreen; - XID output; /* The primary or first output for this crtc, None if no xrandr */ - float refresh_rate; -}; - -typedef void (* MetaScreenWindowFunc) (MetaScreen *screen, MetaWindow *window, - gpointer user_data); - -typedef enum -{ - META_SCREEN_UP, - META_SCREEN_DOWN, - META_SCREEN_LEFT, - META_SCREEN_RIGHT -} MetaScreenDirection; - -#define META_WIREFRAME_XOR_LINE_WIDTH 2 - -struct _MetaScreen -{ - GObject parent_instance; - - MetaDisplay *display; - int number; - char *screen_name; - Screen *xscreen; - Window xroot; - int default_depth; - Visual *default_xvisual; - MetaRectangle rect; /* Size of screen; rect.x & rect.y are always 0 */ - MetaUI *ui; - - guint tile_preview_timeout_id; - guint tile_hud_timeout_id; - guint snap_osd_timeout_id; - gboolean tile_preview_visible; - gboolean tile_hud_visible; - - MetaWorkspace *active_workspace; - - /* This window holds the focus when we don't want to focus - * any actual clients - */ - Window no_focus_window; - - GList *workspaces; - - MetaStack *stack; - MetaStackTracker *stack_tracker; - - MetaCursor current_cursor; - - Window flash_window; - - Window wm_sn_selection_window; - Atom wm_sn_atom; - guint32 wm_sn_timestamp; - - MetaMonitorInfo *monitor_infos; - int primary_monitor_index; - int n_monitor_infos; - - /* Cache the current monitor */ - int last_monitor_index; - -#ifdef HAVE_STARTUP_NOTIFICATION - SnMonitorContext *sn_context; - GSList *startup_sequences; - guint startup_sequence_timeout; -#endif - - Window wm_cm_selection_window; - guint32 wm_cm_timestamp; - - guint work_area_later; - guint check_fullscreen_later; - - int rows_of_workspaces; - int columns_of_workspaces; - MetaScreenCorner starting_corner; - guint vertical_workspaces : 1; - guint workspace_layout_overridden : 1; - - guint keys_grabbed : 1; - guint all_keys_grabbed : 1; - - int closing; - - /* Instead of unmapping withdrawn windows we can leave them mapped - * and restack them below a guard window. When using a compositor - * this allows us to provide live previews of unmapped windows */ - Window guard_window; - Window composite_overlay_window; -}; - -struct _MetaScreenClass -{ - GObjectClass parent_class; - - void (*restacked) (MetaScreen *); - void (*workareas_changed) (MetaScreen *); - void (*monitors_changed) (MetaScreen *); -}; - -MetaScreen* meta_screen_new (MetaDisplay *display, - int number, - guint32 timestamp); -void meta_screen_free (MetaScreen *screen, - guint32 timestamp); -void meta_screen_manage_all_windows (MetaScreen *screen); -void meta_screen_foreach_window (MetaScreen *screen, - MetaScreenWindowFunc func, - gpointer data); -void meta_screen_queue_frame_redraws (MetaScreen *screen); -void meta_screen_queue_window_resizes (MetaScreen *screen); - -void meta_screen_set_cursor (MetaScreen *screen, - MetaCursor cursor); -void meta_screen_update_cursor (MetaScreen *screen); - -void meta_screen_tile_preview_update (MetaScreen *screen, - gboolean delay); -void meta_screen_tile_preview_hide (MetaScreen *screen); - -gboolean meta_screen_tile_preview_get_visible (MetaScreen *screen); - -void meta_screen_tile_hud_update (MetaScreen *screen, - gboolean delay, - gboolean hiding); -void meta_screen_tile_hud_hide (MetaScreen *screen); - -gboolean meta_screen_tile_hud_get_visible (MetaScreen *screen); - -void meta_screen_hide_hud_and_preview (MetaScreen *screen); - -const MetaMonitorInfo* meta_screen_get_current_monitor_info (MetaScreen *screen); -const MetaMonitorInfo* meta_screen_get_monitor_for_rect (MetaScreen *screen, - MetaRectangle *rect); -const MetaMonitorInfo* meta_screen_get_monitor_for_window (MetaScreen *screen, - MetaWindow *window); - - -const MetaMonitorInfo* meta_screen_get_monitor_neighbor (MetaScreen *screen, - int which_monitor, - MetaScreenDirection dir); -void meta_screen_get_natural_monitor_list (MetaScreen *screen, - int** monitors_list, - int* n_monitors); - -void meta_screen_update_workspace_layout (MetaScreen *screen); -void meta_screen_update_workspace_names (MetaScreen *screen); -void meta_screen_queue_workarea_recalc (MetaScreen *screen); -void meta_screen_queue_check_fullscreen (MetaScreen *screen); - -Window meta_create_offscreen_window (Display *xdisplay, - Window parent, - long valuemask); - -typedef struct MetaWorkspaceLayout MetaWorkspaceLayout; - -struct MetaWorkspaceLayout -{ - int rows; - int cols; - int *grid; - int grid_area; - int current_row; - int current_col; -}; - -void meta_screen_calc_workspace_layout (MetaScreen *screen, - int num_workspaces, - int current_space, - MetaWorkspaceLayout *layout); -void meta_screen_free_workspace_layout (MetaWorkspaceLayout *layout); - -void meta_screen_resize (MetaScreen *screen, - int width, - int height); - -void meta_screen_minimize_all_on_active_workspace_except (MetaScreen *screen, - MetaWindow *keep); - - -/* Update whether the destkop is being shown for the current active_workspace */ -void meta_screen_update_showing_desktop_hint (MetaScreen *screen); - -gboolean meta_screen_apply_startup_properties (MetaScreen *screen, - MetaWindow *window); -void meta_screen_composite_all_windows (MetaScreen *screen); - -void meta_screen_restacked (MetaScreen *screen); - -void meta_screen_workspace_switched (MetaScreen *screen, - int from, - int to, - MetaMotionDirection direction); - -void meta_screen_set_active_workspace_hint (MetaScreen *screen); - -void meta_screen_update_snapped_windows (MetaScreen *screen); -#endif diff --git a/src/core/screen.c b/src/core/screen.c deleted file mode 100644 index 5c3d1d96c..000000000 --- a/src/core/screen.c +++ /dev/null @@ -1,3910 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* - * Copyright (C) 2001, 2002 Havoc Pennington - * Copyright (C) 2002, 2003 Red Hat Inc. - * Some ICCCM manager selection code derived from fvwm2, - * Copyright (C) 2001 Dominik Vogt, Matthias Clasen, and fvwm2 team - * Copyright (C) 2003 Rob Adams - * Copyright (C) 2004-2006 Elijah Newren - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. - */ - -/** - * SECTION:screen - * @title: MetaScreen - * @short_description: Muffin X screen handler - */ - -#include <config.h> -#include "screen-private.h" -#include <meta/main.h> -#include "util-private.h" -#include <meta/errors.h> -#include "window-private.h" -#include "frame.h" -#include <meta/prefs.h> -#include "workspace-private.h" -#include "keybindings-private.h" -#include "stack.h" -#include "xprops.h" -#include <meta/compositor.h> -#include "muffin-enum-types.h" - -#ifdef HAVE_SOLARIS_XINERAMA -#include <X11/extensions/xinerama.h> -#endif -#ifdef HAVE_XFREE_XINERAMA -#include <X11/extensions/Xinerama.h> -#endif -#ifdef HAVE_RANDR -#include <X11/extensions/Xrandr.h> -#endif -#include <X11/extensions/Xcomposite.h> - -#include <X11/Xatom.h> -#include <locale.h> -#include <string.h> -#include <stdio.h> - -static char* get_screen_name (MetaDisplay *display, - int number); - -static void update_num_workspaces (MetaScreen *screen, - guint32 timestamp); -static void update_focus_mode (MetaScreen *screen); -static void set_workspace_names (MetaScreen *screen); -static void prefs_changed_callback (MetaPreference pref, - gpointer data); - -static void set_desktop_geometry_hint (MetaScreen *screen); -static void set_desktop_viewport_hint (MetaScreen *screen); - -#ifdef HAVE_STARTUP_NOTIFICATION -static void meta_screen_sn_event (SnMonitorEvent *event, - void *user_data); -#endif - -#define SNAP_OSD_TIMEOUT 1 - -#define _NET_WM_ORIENTATION_HORZ 0 -#define _NET_WM_ORIENTATION_VERT 1 - -#define _NET_WM_TOPLEFT 0 -#define _NET_WM_TOPRIGHT 1 -#define _NET_WM_BOTTOMRIGHT 2 -#define _NET_WM_BOTTOMLEFT 3 - -enum -{ - PROP_N_WORKSPACES = 1, - PROP_KEYBOARD_GRABBED, -}; - -enum -{ - RESTACKED, - TOGGLE_RECORDING, - WORKSPACE_ADDED, - WORKSPACE_REMOVED, - WORKSPACE_SWITCHED, - WINDOW_ENTERED_MONITOR, - WINDOW_LEFT_MONITOR, - STARTUP_SEQUENCE_CHANGED, - WORKAREAS_CHANGED, - MONITORS_CHANGED, - SNAP_OSD_SHOW, - SNAP_OSD_HIDE, - WORKSPACE_OSD_SHOW, - WINDOW_ADDED, - WINDOW_REMOVED, - WINDOW_MONITOR_CHANGED, - WINDOW_WORKSPACE_CHANGED, - WINDOW_SKIP_TASKBAR_CHANGED, - IN_FULLSCREEN_CHANGED, - - LAST_SIGNAL -}; - -static guint screen_signals[LAST_SIGNAL] = { 0 }; - -G_DEFINE_TYPE (MetaScreen, meta_screen, G_TYPE_OBJECT); - -static void -meta_screen_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ -#if 0 - MetaScreen *screen = META_SCREEN (object); -#endif - - switch (prop_id) - { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -meta_screen_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - MetaScreen *screen = META_SCREEN (object); - - switch (prop_id) - { - case PROP_N_WORKSPACES: - g_value_set_int (value, meta_screen_get_n_workspaces (screen)); - break; - case PROP_KEYBOARD_GRABBED: - g_value_set_boolean (value, screen->all_keys_grabbed ? TRUE : FALSE); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -meta_screen_finalize (GObject *object) -{ - /* Actual freeing done in meta_screen_free() for now */ - - G_OBJECT_CLASS (meta_screen_parent_class)->finalize (object); -} - -static void -meta_screen_class_init (MetaScreenClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - GParamSpec *pspec; - - object_class->get_property = meta_screen_get_property; - object_class->set_property = meta_screen_set_property; - object_class->finalize = meta_screen_finalize; - - screen_signals[RESTACKED] = - g_signal_new ("restacked", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (MetaScreenClass, restacked), - NULL, NULL, NULL, - G_TYPE_NONE, 0); - - pspec = g_param_spec_int ("n-workspaces", - "N Workspaces", - "Number of workspaces", - 1, G_MAXINT, 1, - G_PARAM_READABLE); - - screen_signals[WORKSPACE_ADDED] = - g_signal_new ("workspace-added", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, - 1, - G_TYPE_INT); - - screen_signals[WORKSPACE_REMOVED] = - g_signal_new ("workspace-removed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, - 1, - G_TYPE_INT); - - screen_signals[WORKSPACE_SWITCHED] = - g_signal_new ("workspace-switched", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, - 3, - G_TYPE_INT, - G_TYPE_INT, - META_TYPE_MOTION_DIRECTION); - - screen_signals[WINDOW_ENTERED_MONITOR] = - g_signal_new ("window-entered-monitor", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, 2, - G_TYPE_INT, - META_TYPE_WINDOW); - - screen_signals[WINDOW_LEFT_MONITOR] = - g_signal_new ("window-left-monitor", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, 2, - G_TYPE_INT, - META_TYPE_WINDOW); - - screen_signals[STARTUP_SEQUENCE_CHANGED] = - g_signal_new ("startup-sequence-changed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, 1, G_TYPE_POINTER); - - screen_signals[TOGGLE_RECORDING] = - g_signal_new ("toggle-recording", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, 0); - - screen_signals[WORKAREAS_CHANGED] = - g_signal_new ("workareas-changed", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (MetaScreenClass, workareas_changed), - NULL, NULL, NULL, - G_TYPE_NONE, 0); - - screen_signals[MONITORS_CHANGED] = - g_signal_new ("monitors-changed", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (MetaScreenClass, monitors_changed), - NULL, NULL, NULL, - G_TYPE_NONE, 0); - - screen_signals[SNAP_OSD_SHOW] = - g_signal_new ("show-snap-osd", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, 1, - G_TYPE_INT); - - screen_signals[SNAP_OSD_HIDE] = - g_signal_new ("hide-snap-osd", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, 0); - - screen_signals[WORKSPACE_OSD_SHOW] = - g_signal_new ("show-workspace-osd", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, 0); - - screen_signals[WINDOW_ADDED] = - g_signal_new ("window-added", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, 2, - META_TYPE_WINDOW, - G_TYPE_INT); - - screen_signals[WINDOW_REMOVED] = - g_signal_new ("window-removed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, 1, - META_TYPE_WINDOW); - - screen_signals[WINDOW_MONITOR_CHANGED] = - g_signal_new ("window-monitor-changed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, 2, - META_TYPE_WINDOW, - G_TYPE_INT); - - screen_signals[WINDOW_WORKSPACE_CHANGED] = - g_signal_new ("window-workspace-changed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, 2, - META_TYPE_WINDOW, - META_TYPE_WORKSPACE); - - screen_signals[WINDOW_SKIP_TASKBAR_CHANGED] = - g_signal_new ("window-skip-taskbar-changed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, 1, - META_TYPE_WINDOW); - - screen_signals[IN_FULLSCREEN_CHANGED] = - g_signal_new ("in-fullscreen-changed", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, 0); - - g_object_class_install_property (object_class, - PROP_N_WORKSPACES, - pspec); - - pspec = g_param_spec_boolean ("keyboard-grabbed", - "Keyboard grabbed", - "Whether the keyboard is grabbed", - FALSE, - G_PARAM_READABLE); - - g_object_class_install_property (object_class, - PROP_KEYBOARD_GRABBED, - pspec); -} - -static void -meta_screen_init (MetaScreen *screen) -{ -} - -static int -set_wm_check_hint (MetaScreen *screen) -{ - unsigned long data[1]; - - g_return_val_if_fail (screen->display->leader_window != None, 0); - - data[0] = screen->display->leader_window; - - XChangeProperty (screen->display->xdisplay, screen->xroot, - screen->display->atom__NET_SUPPORTING_WM_CHECK, - XA_WINDOW, - 32, PropModeReplace, (guchar*) data, 1); - - return Success; -} - -static void -unset_wm_check_hint (MetaScreen *screen) -{ - XDeleteProperty (screen->display->xdisplay, screen->xroot, - screen->display->atom__NET_SUPPORTING_WM_CHECK); -} - -static int -set_supported_hint (MetaScreen *screen) -{ - Atom atoms[] = { -#define EWMH_ATOMS_ONLY -#define item(x) screen->display->atom_##x, -#include <meta/atomnames.h> -#undef item -#undef EWMH_ATOMS_ONLY - - screen->display->atom__GTK_FRAME_EXTENTS, - screen->display->atom__GTK_SHOW_WINDOW_MENU, - screen->display->atom__GTK_EDGE_CONSTRAINTS, - }; - - XChangeProperty (screen->display->xdisplay, screen->xroot, - screen->display->atom__NET_SUPPORTED, - XA_ATOM, - 32, PropModeReplace, - (guchar*) atoms, G_N_ELEMENTS(atoms)); - - return Success; -} - -/* The list of monitors reported by the windowing system might include - * mirrored monitors with identical bounds. Since mirrored monitors - * shouldn't be treated as separate monitors for most purposes, we - * filter them out here. (We ignore the possibility of partially - * overlapping monitors because they are rare and it's hard to come - * up with any sensible interpretation.) - */ -static void -filter_mirrored_monitors (MetaScreen *screen) -{ - int i, j; - - /* Currently always true and simplifies things */ - g_assert (screen->primary_monitor_index == 0); - - for (i = 1; i < screen->n_monitor_infos; i++) - { - /* In case we've filtered previous monitors */ - screen->monitor_infos[i].number = i; - - for (j = 0; j < i; j++) - { - if (meta_rectangle_equal (&screen->monitor_infos[i].rect, - &screen->monitor_infos[j].rect)) - { - memmove (&screen->monitor_infos[i], - &screen->monitor_infos[i + 1], - (screen->n_monitor_infos - i - 1) * sizeof (MetaMonitorInfo)); - screen->n_monitor_infos--; - i--; - - continue; - } - } - } -} - -#ifdef HAVE_RANDR -static MetaMonitorInfo * -find_monitor_with_rect (MetaScreen *screen, int x, int y, int w, int h) -{ - MetaMonitorInfo *info; - int i; - - for (i = 0; i < screen->n_monitor_infos; i++) - { - info = &screen->monitor_infos[i]; - if (x == info->rect.x && - y == info->rect.y && - w == info->rect.width && - h == info->rect.height) - return info; - } - return NULL; -} - -/* In the case of multiple outputs of a single crtc (mirroring), we consider one of the - * outputs the "main". This is the one we consider "owning" the windows, so if - * the mirroring is changed to a dual monitor setup then the windows are moved to the - * crtc that now has that main output. If one of the outputs is the primary that is - * always the main, otherwise we just use the first. - */ -static XID -find_main_output_for_crtc (MetaScreen *screen, XRRScreenResources *resources, XRRCrtcInfo *crtc) -{ - XRROutputInfo *output; - RROutput primary_output; - int i; - XID res; - - primary_output = XRRGetOutputPrimary (screen->display->xdisplay, screen->xroot); - - res = None; - for (i = 0; i < crtc->noutput; i++) - { - output = XRRGetOutputInfo (screen->display->xdisplay, resources, crtc->outputs[i]); - if (output->connection != RR_Disconnected && - (res == None || crtc->outputs[i] == primary_output)) - res = crtc->outputs[i]; - XRRFreeOutputInfo (output); - } - - return res; -} - -#endif - -static void -reload_monitor_infos (MetaScreen *screen) -{ - MetaDisplay *display; - - { - GList *tmp; - - tmp = screen->workspaces; - while (tmp != NULL) - { - MetaWorkspace *space = tmp->data; - - meta_workspace_invalidate_work_area (space); - - tmp = tmp->next; - } - } - - display = screen->display; - - /* Any previous screen->monitor_infos is freed by the caller */ - - screen->monitor_infos = NULL; - screen->n_monitor_infos = 0; - screen->last_monitor_index = 0; - - /* Xinerama doesn't have a concept of primary monitor, however XRandR - * does. However, the XRandR xinerama compat code always sorts the - * primary output first, so we rely on that here. We could use the - * native XRandR calls instead of xinerama, but that would be - * slightly problematic for _NET_WM_FULLSCREEN_MONITORS support, as - * that is defined in terms of xinerama monitor indexes. - * So, since we don't need anything in xrandr except the primary - * we can keep using xinerama and use the first monitor as the - * primary. - */ - screen->primary_monitor_index = 0; - - screen->display->monitor_cache_invalidated = TRUE; - - if (g_getenv ("MUFFIN_DEBUG_XINERAMA")) - { - meta_topic (META_DEBUG_XINERAMA, - "Pretending a single monitor has two Xinerama screens\n"); - - screen->monitor_infos = g_new0 (MetaMonitorInfo, 2); - screen->n_monitor_infos = 2; - - screen->monitor_infos[0].number = 0; - screen->monitor_infos[0].rect = screen->rect; - screen->monitor_infos[0].rect.width = screen->rect.width / 2; - screen->monitor_infos[0].in_fullscreen = -1; - - screen->monitor_infos[1].number = 1; - screen->monitor_infos[1].rect = screen->rect; - screen->monitor_infos[1].rect.x = screen->rect.width / 2; - screen->monitor_infos[1].rect.width = screen->rect.width / 2; - screen->monitor_infos[1].in_fullscreen = -1; - } - -#ifdef HAVE_XFREE_XINERAMA - if (screen->n_monitor_infos == 0 && - XineramaIsActive (display->xdisplay)) - { - XineramaScreenInfo *infos; - int n_infos; - int i, j; - - n_infos = 0; - infos = XineramaQueryScreens (display->xdisplay, &n_infos); - - meta_topic (META_DEBUG_XINERAMA, - "Found %d Xinerama screens on display %s\n", - n_infos, display->name); - - if (n_infos > 0) - { - screen->monitor_infos = g_new0 (MetaMonitorInfo, n_infos); - screen->n_monitor_infos = n_infos; - - i = 0; - while (i < n_infos) - { - screen->monitor_infos[i].number = infos[i].screen_number; - screen->monitor_infos[i].rect.x = infos[i].x_org; - screen->monitor_infos[i].rect.y = infos[i].y_org; - screen->monitor_infos[i].rect.width = infos[i].width; - screen->monitor_infos[i].rect.height = infos[i].height; - screen->monitor_infos[i].in_fullscreen = -1; - - meta_topic (META_DEBUG_XINERAMA, - "Monitor %d is %d,%d %d x %d\n", - screen->monitor_infos[i].number, - screen->monitor_infos[i].rect.x, - screen->monitor_infos[i].rect.y, - screen->monitor_infos[i].rect.width, - screen->monitor_infos[i].rect.height); - - ++i; - } - } - - meta_XFree (infos); - -#ifdef HAVE_RANDR - { - XRRScreenResources *resources; - - resources = XRRGetScreenResourcesCurrent (display->xdisplay, screen->xroot); - if (resources) - { - for (i = 0; i < resources->ncrtc; i++) - { - XRRCrtcInfo *crtc; - MetaMonitorInfo *info; - - crtc = XRRGetCrtcInfo (display->xdisplay, resources, resources->crtcs[i]); - info = find_monitor_with_rect (screen, crtc->x, crtc->y, (int)crtc->width, (int)crtc->height); - - if (info) - { - for (j = 0; j < resources->nmode; j++) - { - if (resources->modes[j].id == crtc->mode) - info->refresh_rate = (resources->modes[j].dotClock / - ((float)resources->modes[j].hTotal * - resources->modes[j].vTotal)); - } - info->output = find_main_output_for_crtc (screen, resources, crtc); - } - - XRRFreeCrtcInfo (crtc); - } - - XRRFreeScreenResources (resources); - } - } -#endif - } - else if (screen->n_monitor_infos > 0) - { - meta_topic (META_DEBUG_XINERAMA, - "No XFree86 Xinerama extension or XFree86 Xinerama inactive on display %s\n", - display->name); - } -#else - meta_topic (META_DEBUG_XINERAMA, - "Muffin compiled without XFree86 Xinerama support\n"); -#endif /* HAVE_XFREE_XINERAMA */ - -#ifdef HAVE_SOLARIS_XINERAMA - /* This code from GDK, Copyright (C) 2002 Sun Microsystems */ - if (screen->n_monitor_infos == 0 && - XineramaGetState (screen->display->xdisplay, - screen->number)) - { - XRectangle monitors[MAXFRAMEBUFFERS]; - unsigned char hints[16]; - int result; - int n_monitors; - int i; - - n_monitors = 0; - result = XineramaGetInfo (screen->display->xdisplay, - screen->number, - monitors, hints, - &n_monitors); - /* Yes I know it should be Success but the current implementation - * returns the num of monitor - */ - if (result > 0) - { - g_assert (n_monitors > 0); - - screen->monitor_infos = g_new0 (MetaMonitorInfo, n_monitors); - screen->n_monitor_infos = n_monitors; - - i = 0; - while (i < n_monitors) - { - screen->monitor_infos[i].number = i; - screen->monitor_infos[i].rect.x = monitors[i].x; - screen->monitor_infos[i].rect.y = monitors[i].y; - screen->monitor_infos[i].rect.width = monitors[i].width; - screen->monitor_infos[i].rect.height = monitors[i].height; - - meta_topic (META_DEBUG_XINERAMA, - "Monitor %d is %d,%d %d x %d\n", - screen->monitor_infos[i].number, - screen->monitor_infos[i].rect.x, - screen->monitor_infos[i].rect.y, - screen->monitor_infos[i].rect.width, - screen->monitor_infos[i].rect.height); - - ++i; - } - } - } - else if (screen->n_monitor_infos == 0) - { - meta_topic (META_DEBUG_XINERAMA, - "No Solaris Xinerama extension or Solaris Xinerama inactive on display %s\n", - display->name); - } -#else - meta_topic (META_DEBUG_XINERAMA, - "Muffin compiled without Solaris Xinerama support\n"); -#endif /* HAVE_SOLARIS_XINERAMA */ - - - /* If no Xinerama, fill in the single screen info so - * we can use the field unconditionally - */ - if (screen->n_monitor_infos == 0) - { - meta_topic (META_DEBUG_XINERAMA, - "No Xinerama screens, using default screen info\n"); - - screen->monitor_infos = g_new0 (MetaMonitorInfo, 1); - screen->n_monitor_infos = 1; - - screen->monitor_infos[0].number = 0; - screen->monitor_infos[0].rect = screen->rect; - screen->monitor_infos[0].in_fullscreen = -1; - } - - filter_mirrored_monitors (screen); - - screen->monitor_infos[screen->primary_monitor_index].is_primary = TRUE; - - g_assert (screen->n_monitor_infos > 0); - g_assert (screen->monitor_infos != NULL); -} - -/* The guard window allows us to leave minimized windows mapped so - * that compositor code may provide live previews of them. - * Instead of being unmapped/withdrawn, they get pushed underneath - * the guard window. */ -static Window -create_guard_window (Display *xdisplay, MetaScreen *screen) -{ - XSetWindowAttributes attributes; - Window guard_window; - gulong create_serial; - - attributes.event_mask = NoEventMask; - attributes.override_redirect = True; - attributes.background_pixel = BlackPixel (xdisplay, screen->number); - - /* We have to call record_add() after we have the new window ID, - * so save the serial for the CreateWindow request until then */ - create_serial = XNextRequest(xdisplay); - guard_window = - XCreateWindow (xdisplay, - screen->xroot, - 0, /* x */ - 0, /* y */ - screen->rect.width, - screen->rect.height, - 0, /* border width */ - CopyFromParent, /* depth */ - CopyFromParent, /* class */ - CopyFromParent, /* visual */ - CWEventMask|CWOverrideRedirect|CWBackPixel, - &attributes); - meta_stack_tracker_record_add (screen->stack_tracker, - guard_window, - create_serial); - - meta_stack_tracker_record_lower (screen->stack_tracker, - guard_window, - XNextRequest (xdisplay)); - XLowerWindow (xdisplay, guard_window); - XMapWindow (xdisplay, guard_window); - return guard_window; -} - -LOCAL_SYMBOL MetaScreen* -meta_screen_new (MetaDisplay *display, - int number, - guint32 timestamp) -{ - MetaScreen *screen; - Window xroot; - Display *xdisplay; - XWindowAttributes attr; - Window new_wm_sn_owner; - Window current_wm_sn_owner; - gboolean replace_current_wm; - Atom wm_sn_atom; - char buf[128]; - guint32 manager_timestamp; - gulong current_workspace; - - replace_current_wm = meta_get_replace_current_wm (); - - /* Only display->name, display->xdisplay, and display->error_traps - * can really be used in this function, since normally screens are - * created from the MetaDisplay constructor - */ - - xdisplay = display->xdisplay; - - meta_verbose ("Trying screen %d on display '%s'\n", - number, display->name); - - xroot = RootWindow (xdisplay, number); - - /* FVWM checks for None here, I don't know if this - * ever actually happens - */ - if (xroot == None) - { - meta_warning ("Screen %d on display '%s' is invalid\n", - number, display->name); - return NULL; - } - - sprintf (buf, "WM_S%d", number); - wm_sn_atom = XInternAtom (xdisplay, buf, False); - - current_wm_sn_owner = XGetSelectionOwner (xdisplay, wm_sn_atom); - - if (current_wm_sn_owner != None) - { - XSetWindowAttributes attrs; - - if (!replace_current_wm) - { - meta_warning ("Screen %d on display \"%s\" already has a window manager; try using the --replace option to replace the current window manager.\n", - number, display->name); - - return NULL; - } - - /* We want to find out when the current selection owner dies */ - meta_error_trap_push_with_return (display); - attrs.event_mask = StructureNotifyMask; - XChangeWindowAttributes (xdisplay, - current_wm_sn_owner, CWEventMask, &attrs); - if (meta_error_trap_pop_with_return (display) != Success) - current_wm_sn_owner = None; /* don't wait for it to die later on */ - } - - /* We need SelectionClear and SelectionRequest events on the new_wm_sn_owner, - * but those cannot be masked, so we only need NoEventMask. - */ - new_wm_sn_owner = meta_create_offscreen_window (xdisplay, xroot, NoEventMask); - - manager_timestamp = timestamp; - - XSetSelectionOwner (xdisplay, wm_sn_atom, new_wm_sn_owner, - manager_timestamp); - - if (XGetSelectionOwner (xdisplay, wm_sn_atom) != new_wm_sn_owner) - { - meta_warning ("Could not acquire window manager selection on screen %d display \"%s\"\n", - number, display->name); - - XDestroyWindow (xdisplay, new_wm_sn_owner); - - return NULL; - } - - { - /* Send client message indicating that we are now the WM */ - XClientMessageEvent ev; - - ev.type = ClientMessage; - ev.window = xroot; - ev.message_type = display->atom_MANAGER; - ev.format = 32; - ev.data.l[0] = manager_timestamp; - ev.data.l[1] = wm_sn_atom; - - XSendEvent (xdisplay, xroot, False, StructureNotifyMask, (XEvent*)&ev); - } - - /* Wait for old window manager to go away */ - if (current_wm_sn_owner != None) - { - XEvent event; - - /* We sort of block infinitely here which is probably lame. */ - - meta_verbose ("Waiting for old window manager to exit\n"); - do - { - XWindowEvent (xdisplay, current_wm_sn_owner, - StructureNotifyMask, &event); - } - while (event.type != DestroyNotify); - } - - /* select our root window events */ - meta_error_trap_push_with_return (display); - - /* We need to or with the existing event mask since - * gtk+ may be interested in other events. - */ - XGetWindowAttributes (xdisplay, xroot, &attr); - XSelectInput (xdisplay, - xroot, - SubstructureRedirectMask | SubstructureNotifyMask | - ColormapChangeMask | PropertyChangeMask | - LeaveWindowMask | EnterWindowMask | - KeyPressMask | KeyReleaseMask | - FocusChangeMask | StructureNotifyMask | - ExposureMask | attr.your_event_mask); - if (meta_error_trap_pop_with_return (display) != Success) - { - meta_warning ("Screen %d on display \"%s\" already has a window manager\n", - number, display->name); - - XDestroyWindow (xdisplay, new_wm_sn_owner); - - return NULL; - } - - screen = g_object_new (META_TYPE_SCREEN, NULL); - screen->closing = 0; - - screen->display = display; - screen->number = number; - screen->screen_name = get_screen_name (display, number); - screen->xscreen = ScreenOfDisplay (xdisplay, number); - screen->xroot = xroot; - screen->rect.x = screen->rect.y = 0; - screen->rect.width = WidthOfScreen (screen->xscreen); - screen->rect.height = HeightOfScreen (screen->xscreen); - screen->current_cursor = -1; /* invalid/unset */ - screen->default_xvisual = DefaultVisualOfScreen (screen->xscreen); - screen->default_depth = DefaultDepthOfScreen (screen->xscreen); - screen->flash_window = None; - - screen->wm_sn_selection_window = new_wm_sn_owner; - screen->wm_sn_atom = wm_sn_atom; - screen->wm_sn_timestamp = manager_timestamp; - - screen->wm_cm_selection_window = meta_create_offscreen_window (xdisplay, - xroot, - NoEventMask); - screen->work_area_later = 0; - screen->check_fullscreen_later = 0; - - screen->active_workspace = NULL; - screen->workspaces = NULL; - screen->rows_of_workspaces = 1; - screen->columns_of_workspaces = -1; - screen->vertical_workspaces = FALSE; - screen->starting_corner = META_SCREEN_TOPLEFT; - screen->guard_window = None; - - screen->composite_overlay_window = XCompositeGetOverlayWindow (xdisplay, xroot); - - screen->monitor_infos = NULL; - screen->n_monitor_infos = 0; - screen->last_monitor_index = 0; - - reload_monitor_infos (screen); - - meta_screen_set_cursor (screen, META_CURSOR_DEFAULT); - - /* Handle creating a no_focus_window for this screen */ - screen->no_focus_window = - meta_create_offscreen_window (display->xdisplay, - screen->xroot, - FocusChangeMask|KeyPressMask|KeyReleaseMask); - XMapWindow (display->xdisplay, screen->no_focus_window); - /* Done with no_focus_window stuff */ - - set_supported_hint (screen); - - set_wm_check_hint (screen); - - set_desktop_viewport_hint (screen); - - set_desktop_geometry_hint (screen); - - meta_screen_update_workspace_layout (screen); - - /* Get current workspace */ - current_workspace = 0; - if (meta_prop_get_cardinal (screen->display, - screen->xroot, - screen->display->atom__NET_CURRENT_DESKTOP, - ¤t_workspace)) - meta_verbose ("Read existing _NET_CURRENT_DESKTOP = %d\n", - (int) current_workspace); - else - meta_verbose ("No _NET_CURRENT_DESKTOP present\n"); - - /* Screens must have at least one workspace at all times, - * so create that required workspace. - */ - meta_workspace_activate (meta_workspace_new (screen), timestamp); - update_num_workspaces (screen, timestamp); - - set_workspace_names (screen); - - screen->all_keys_grabbed = FALSE; - screen->keys_grabbed = FALSE; - meta_screen_grab_keys (screen); - - screen->ui = meta_ui_new (display, - screen->xscreen); - - screen->tile_preview_timeout_id = 0; - screen->tile_hud_timeout_id = 0; - - screen->snap_osd_timeout_id = 0; - - screen->tile_preview_visible = FALSE; - screen->tile_hud_visible = FALSE; - - screen->stack = meta_stack_new (screen); - screen->stack_tracker = meta_stack_tracker_new (screen); - - meta_prefs_add_listener (prefs_changed_callback, screen); - -#ifdef HAVE_STARTUP_NOTIFICATION - screen->sn_context = - sn_monitor_context_new (screen->display->sn_display, - screen->number, - meta_screen_sn_event, - screen, - NULL); - screen->startup_sequences = NULL; - screen->startup_sequence_timeout = 0; -#endif - - /* Switch to the _NET_CURRENT_DESKTOP workspace */ - { - MetaWorkspace *space; - - space = meta_screen_get_workspace_by_index (screen, - current_workspace); - - if (space != NULL) - meta_workspace_activate (space, timestamp); - } - - meta_verbose ("Added screen %d ('%s') root 0x%lx\n", - screen->number, screen->screen_name, screen->xroot); - - return screen; -} - -LOCAL_SYMBOL void -meta_screen_free (MetaScreen *screen, - guint32 timestamp) -{ - MetaDisplay *display; - - display = screen->display; - - screen->closing += 1; - - meta_display_grab (display); - - meta_compositor_unmanage_screen (screen->display->compositor, - screen); - - meta_display_unmanage_windows_for_screen (display, screen, timestamp); - - meta_prefs_remove_listener (prefs_changed_callback, screen); - - meta_screen_ungrab_keys (screen); - -#ifdef HAVE_STARTUP_NOTIFICATION - g_slist_foreach (screen->startup_sequences, - (GFunc) sn_startup_sequence_unref, NULL); - g_slist_free (screen->startup_sequences); - screen->startup_sequences = NULL; - - if (screen->startup_sequence_timeout != 0) - { - g_source_remove (screen->startup_sequence_timeout); - screen->startup_sequence_timeout = 0; - } - if (screen->sn_context) - { - sn_monitor_context_unref (screen->sn_context); - screen->sn_context = NULL; - } -#endif - - meta_ui_free (screen->ui); - - meta_stack_free (screen->stack); - meta_stack_tracker_free (screen->stack_tracker); - - meta_error_trap_push_with_return (screen->display); - XSelectInput (screen->display->xdisplay, screen->xroot, 0); - if (meta_error_trap_pop_with_return (screen->display) != Success) - meta_warning ("Could not release screen %d on display \"%s\"\n", - screen->number, screen->display->name); - - unset_wm_check_hint (screen); - - XDestroyWindow (screen->display->xdisplay, - screen->wm_sn_selection_window); - - if (screen->work_area_later != 0) { - g_source_remove (screen->work_area_later); - screen->work_area_later = 0; - } - - if (screen->check_fullscreen_later != 0) - g_source_remove (screen->check_fullscreen_later); - - free (screen->monitor_infos); - - if (screen->tile_preview_timeout_id) { - g_source_remove (screen->tile_preview_timeout_id); - screen->tile_preview_timeout_id = 0; - } - - if (screen->tile_hud_timeout_id) { - g_source_remove (screen->tile_hud_timeout_id); - screen->tile_hud_timeout_id = 0; - } - - if (screen->snap_osd_timeout_id) { - g_source_remove (screen->snap_osd_timeout_id); - screen->snap_osd_timeout_id = 0; - } - - free (screen->screen_name); - - g_object_unref (screen); - - XFlush (display->xdisplay); - meta_display_ungrab (display); -} - -typedef struct -{ - Window xwindow; - XWindowAttributes attrs; -} WindowInfo; - -static GList * -list_windows (MetaScreen *screen) -{ - Window ignored1, ignored2; - Window *children; - guint n_children, i; - GList *result; - - XQueryTree (screen->display->xdisplay, - screen->xroot, - &ignored1, &ignored2, &children, &n_children); - - result = NULL; - for (i = 0; i < n_children; ++i) - { - WindowInfo *info = g_new0 (WindowInfo, 1); - - meta_error_trap_push_with_return (screen->display); - - XGetWindowAttributes (screen->display->xdisplay, - children[i], &info->attrs); - - if (meta_error_trap_pop_with_return (screen->display)) - { - meta_verbose ("Failed to get attributes for window 0x%lx\n", - children[i]); - free (info); - } - else - { - info->xwindow = children[i]; - } - - result = g_list_prepend (result, info); - } - - if (children) - XFree (children); - - return g_list_reverse (result); -} - -LOCAL_SYMBOL void -meta_screen_manage_all_windows (MetaScreen *screen) -{ - GList *windows; - GList *list; - - meta_display_grab (screen->display); - - if (screen->guard_window == None) - screen->guard_window = create_guard_window (screen->display->xdisplay, - screen); - - windows = list_windows (screen); - - meta_stack_freeze (screen->stack); - for (list = windows; list != NULL; list = list->next) - { - WindowInfo *info = list->data; - MetaWindow *mw; - - mw = meta_window_new_with_attrs (screen->display, info->xwindow, TRUE, - META_COMP_EFFECT_NONE, - &info->attrs); - if (mw) - { - /* In this context, we're creating MetaWindows for pre-existing client windows. - * We can probably assume current positions are deliberate, and not force them - * either within the screen extents, or within a single monitor when constraints - * are run initially. */ - mw->require_fully_onscreen = FALSE; - mw->require_on_single_monitor = FALSE; - mw->require_titlebar_visible = FALSE; - } - } - meta_stack_thaw (screen->stack); - - g_list_foreach (windows, (GFunc)free, NULL); - g_list_free (windows); - - meta_display_ungrab (screen->display); -} - -LOCAL_SYMBOL void -meta_screen_composite_all_windows (MetaScreen *screen) -{ - MetaDisplay *display; - GSList *windows, *tmp; - - display = screen->display; - if (!display->compositor) - return; - - windows = meta_display_list_windows (display, - META_LIST_INCLUDE_OVERRIDE_REDIRECT); - for (tmp = windows; tmp != NULL; tmp = tmp->next) - { - MetaWindow *window = tmp->data; - - meta_compositor_add_window (display->compositor, window); - if (window->visible_to_compositor) - meta_compositor_show_window (display->compositor, window, - META_COMP_EFFECT_NONE); - } - - g_slist_free (windows); - - /* initialize the compositor's view of the stacking order */ - meta_stack_tracker_sync_stack (screen->stack_tracker); -} - -/** - * meta_screen_for_x_screen: - * @xscreen: an X screen structure. - * - * Gets the #MetaScreen corresponding to an X screen structure. - * - * Return value: (transfer none): the #MetaScreen for the X screen - * %NULL if Metacity is not managing the screen. - */ -MetaScreen* -meta_screen_for_x_screen (Screen *xscreen) -{ - MetaDisplay *display; - - display = meta_display_for_x_display (DisplayOfScreen (xscreen)); - - if (display == NULL) - return NULL; - - return meta_display_screen_for_x_screen (display, xscreen); -} - -static void -prefs_changed_callback (MetaPreference pref, - gpointer data) -{ - MetaScreen *screen = data; - - if ((pref == META_PREF_NUM_WORKSPACES || - pref == META_PREF_DYNAMIC_WORKSPACES) && - !meta_prefs_get_dynamic_workspaces ()) - { - /* GSettings doesn't provide timestamps, but luckily update_num_workspaces - * often doesn't need it... - */ - guint32 timestamp = - meta_display_get_current_time_roundtrip (screen->display); - update_num_workspaces (screen, timestamp); - } - else if (pref == META_PREF_FOCUS_MODE) - { - update_focus_mode (screen); - } - else if (pref == META_PREF_WORKSPACE_NAMES) - { - set_workspace_names (screen); - } -} - - -static char* -get_screen_name (MetaDisplay *display, - int number) -{ - char *p; - char *dname; - char *scr; - - /* DisplayString gives us a sort of canonical display, - * vs. the user-entered name from XDisplayName() - */ - dname = g_strdup (DisplayString (display->xdisplay)); - - /* Change display name to specify this screen. - */ - p = strrchr (dname, ':'); - if (p) - { - p = strchr (p, '.'); - if (p) - *p = '\0'; - } - - scr = g_strdup_printf ("%s.%d", dname, number); - - free (dname); - - return scr; -} - -static gint -ptrcmp (gconstpointer a, gconstpointer b) -{ - if (a < b) - return -1; - else if (a > b) - return 1; - else - return 0; -} - -static void -listify_func (gpointer key, gpointer value, gpointer data) -{ - GSList **listp; - - listp = data; - - *listp = g_slist_prepend (*listp, value); -} - -/** - * meta_screen_foreach_window: - * @screen: a #MetaScreen - * @func: function to call for each window - * @data: user data to pass to @func - * - * Calls the specified function for each window on the screen, - * ignoring override-redirect windows. - */ -LOCAL_SYMBOL void -meta_screen_foreach_window (MetaScreen *screen, - MetaScreenWindowFunc func, - gpointer data) -{ - GSList *winlist; - GSList *tmp; - - /* If we end up doing this often, just keeping a list - * of windows might be sensible. - */ - - winlist = NULL; - g_hash_table_foreach (screen->display->window_ids, - listify_func, - &winlist); - - winlist = g_slist_sort (winlist, ptrcmp); - - tmp = winlist; - while (tmp != NULL) - { - /* If the next node doesn't contain this window - * a second time, delete the window. - */ - if (tmp->next == NULL || - (tmp->next && tmp->next->data != tmp->data)) - { - MetaWindow *window = tmp->data; - - if (window->screen == screen && !window->override_redirect) - (* func) (screen, window, data); - } - - tmp = tmp->next; - } - g_slist_free (winlist); -} - -static void -queue_draw (MetaScreen *screen, MetaWindow *window, gpointer data) -{ - if (window->frame) - meta_frame_queue_draw (window->frame); -} - -LOCAL_SYMBOL void -meta_screen_queue_frame_redraws (MetaScreen *screen) -{ - meta_screen_foreach_window (screen, queue_draw, NULL); -} - -static void -queue_resize (MetaScreen *screen, MetaWindow *window, gpointer data) -{ - meta_window_queue (window, META_QUEUE_MOVE_RESIZE); -} - -LOCAL_SYMBOL void -meta_screen_queue_window_resizes (MetaScreen *screen) -{ - meta_screen_foreach_window (screen, queue_resize, NULL); -} - -int -meta_screen_get_n_workspaces (MetaScreen *screen) -{ - return g_list_length (screen->workspaces); -} - -/** - * meta_screen_get_workspace_by_index: - * @screen: a #MetaScreen - * @index: index of one of the screen's workspaces - * - * Gets the workspace object for one of a screen's workspaces given the workspace - * index. It's valid to call this function with an out-of-range index and it - * will robustly return %NULL. - * - * Return value: (transfer none): the workspace object with specified index, or %NULL - * if the index is out of range. - */ -MetaWorkspace* -meta_screen_get_workspace_by_index (MetaScreen *screen, - int idx) -{ - GList *tmp; - int i; - - /* should be robust, idx is maybe from an app */ - if (idx < 0) - return NULL; - - i = 0; - tmp = screen->workspaces; - while (tmp != NULL) - { - MetaWorkspace *w = tmp->data; - - if (i == idx) - return w; - - ++i; - tmp = tmp->next; - } - - return NULL; -} - -static void -update_net_desktop_layout (MetaScreen *screen, int n_columns) -{ - g_return_if_fail (META_IS_SCREEN (screen)); - - screen->columns_of_workspaces = n_columns; - - unsigned long data[4]; - - /* Orientation */ - data[0] = screen->vertical_workspaces ? _NET_WM_ORIENTATION_VERT : _NET_WM_ORIENTATION_HORZ; - /* Number of columns */ - data[1] = screen->columns_of_workspaces; - /* Number of rows */ - data[2] = screen->rows_of_workspaces; - /* Starting corner */ - data[3] = screen->starting_corner; - - meta_verbose ("Setting _NET_DESKTOP_LAYOUT on root window " - "to orientation = %lu, columns = %lu, rows = %lu, starting corner = %lu\n", - data[0], data[1], data[2], data[3]); - - meta_error_trap_push (screen->display); - - XChangeProperty (screen->display->xdisplay, screen->xroot, - screen->display->atom__NET_DESKTOP_LAYOUT, - XA_CARDINAL, 32, PropModeReplace, - (guchar*) data, 4); - - meta_error_trap_pop (screen->display); -} - -static void -set_number_of_spaces_hint (MetaScreen *screen, - int n_spaces) -{ - unsigned long data[1]; - - if (screen->closing > 0) - return; - - data[0] = n_spaces; - - meta_verbose ("Setting _NET_NUMBER_OF_DESKTOPS to %lu\n", data[0]); - - meta_error_trap_push (screen->display); - XChangeProperty (screen->display->xdisplay, screen->xroot, - screen->display->atom__NET_NUMBER_OF_DESKTOPS, - XA_CARDINAL, - 32, PropModeReplace, (guchar*) data, 1); - meta_error_trap_pop (screen->display); -} - -static void -set_desktop_geometry_hint (MetaScreen *screen) -{ - unsigned long data[2]; - - if (screen->closing > 0) - return; - - data[0] = screen->rect.width; - data[1] = screen->rect.height; - - meta_verbose ("Setting _NET_DESKTOP_GEOMETRY to %lu, %lu\n", data[0], data[1]); - - meta_error_trap_push (screen->display); - XChangeProperty (screen->display->xdisplay, screen->xroot, - screen->display->atom__NET_DESKTOP_GEOMETRY, - XA_CARDINAL, - 32, PropModeReplace, (guchar*) data, 2); - meta_error_trap_pop (screen->display); -} - -static void -set_desktop_viewport_hint (MetaScreen *screen) -{ - unsigned long data[2]; - - if (screen->closing > 0) - return; - - /* - * Muffin does not implement viewports, so this is a fixed 0,0 - */ - data[0] = 0; - data[1] = 0; - - meta_verbose ("Setting _NET_DESKTOP_VIEWPORT to 0, 0\n"); - - meta_error_trap_push (screen->display); - XChangeProperty (screen->display->xdisplay, screen->xroot, - screen->display->atom__NET_DESKTOP_VIEWPORT, - XA_CARDINAL, - 32, PropModeReplace, (guchar*) data, 2); - meta_error_trap_pop (screen->display); -} - -void -meta_screen_remove_workspace (MetaScreen *screen, MetaWorkspace *workspace, - guint32 timestamp) -{ - GList *l; - MetaWorkspace *neighbour = NULL; - GList *next = NULL; - int index; - gboolean active_index_changed; - int new_num; - - l = screen->workspaces; - while (l) - { - MetaWorkspace *w = l->data; - - if (w == workspace) - { - if (l->next) - next = l->next; - - if (l->prev) - neighbour = l->prev->data; - else if (l->next) - neighbour = l->next->data; - else - { - /* Cannot remove the only workspace! */ - return; - } - - break; - } - - l = l->next; - } - - if (!neighbour) - return; - - meta_workspace_relocate_windows (workspace, neighbour); - - if (workspace == screen->active_workspace) - meta_workspace_activate (neighbour, timestamp); - - /* To emit the signal after removing the workspace */ - index = meta_workspace_index (workspace); - active_index_changed = index < meta_screen_get_active_workspace_index (screen); - - /* This also removes the workspace from the screens list */ - meta_workspace_remove (workspace); - - new_num = g_list_length (screen->workspaces); - - set_number_of_spaces_hint (screen, new_num); - - if (!meta_prefs_get_dynamic_workspaces ()) - meta_prefs_set_num_workspaces (new_num); - - update_net_desktop_layout (screen, new_num); - - set_workspace_names (screen); - - /* If deleting a workspace before the current workspace, the active - * workspace index changes, so we need to update that hint */ - if (active_index_changed) - meta_screen_set_active_workspace_hint (screen); - - l = next; - while (l) - { - MetaWorkspace *w = l->data; - - meta_workspace_update_window_hints (w); - - l = l->next; - } - - meta_screen_queue_workarea_recalc (screen); - - g_signal_emit (screen, screen_signals[WORKSPACE_REMOVED], 0, index); - g_object_notify (G_OBJECT (screen), "n-workspaces"); -} - -/** - * meta_screen_append_new_workspace: - * @screen: a #MetaScreen - * @activate: %TRUE if the workspace should be switched to after creation - * @timestamp: if switching to a new workspace, timestamp to be used when - * focusing a window on the new workspace. (Doesn't hurt to pass a valid - * timestamp when available even if not switching workspaces.) - * - * Append a new workspace to the screen and (optionally) switch to that - * screen. - * - * Return value: (transfer none): the newly appended workspace. - */ -MetaWorkspace * -meta_screen_append_new_workspace (MetaScreen *screen, gboolean activate, - guint32 timestamp) -{ - MetaWorkspace *w; - int new_num; - - /* This also adds the workspace to the screen list */ - w = meta_workspace_new (screen); - - if (!w) - return NULL; - - if (activate) - meta_workspace_activate (w, timestamp); - - new_num = g_list_length (screen->workspaces); - - set_number_of_spaces_hint (screen, new_num); - - if (!meta_prefs_get_dynamic_workspaces ()) - meta_prefs_set_num_workspaces (new_num); - - update_net_desktop_layout (screen, new_num); - - set_workspace_names (screen); - - meta_screen_queue_workarea_recalc (screen); - - g_signal_emit (screen, screen_signals[WORKSPACE_ADDED], - 0, meta_workspace_index (w)); - g_object_notify (G_OBJECT (screen), "n-workspaces"); - - return w; -} - - -static void -update_num_workspaces (MetaScreen *screen, - guint32 timestamp) -{ - int new_num, old_num; - GList *tmp; - int i; - GList *extras; - MetaWorkspace *last_remaining; - gboolean need_change_space; - - new_num = meta_prefs_get_num_workspaces (); - - g_assert (new_num > 0); - - if (g_list_length (screen->workspaces) == (guint) new_num) - return; - - last_remaining = NULL; - extras = NULL; - i = 0; - tmp = screen->workspaces; - while (tmp != NULL) - { - MetaWorkspace *w = tmp->data; - - if (i >= new_num) - extras = g_list_prepend (extras, w); - else - last_remaining = w; - - ++i; - tmp = tmp->next; - } - old_num = i; - - g_assert (last_remaining); - - /* Get rid of the extra workspaces by moving all their windows - * to last_remaining, then activating last_remaining if - * one of the removed workspaces was active. This will be a bit - * wacky if the config tool for changing number of workspaces - * is on a removed workspace ;-) - */ - need_change_space = FALSE; - tmp = extras; - while (tmp != NULL) - { - MetaWorkspace *w = tmp->data; - - meta_workspace_relocate_windows (w, last_remaining); - - if (w == screen->active_workspace) - need_change_space = TRUE; - - tmp = tmp->next; - } - - if (need_change_space) - meta_workspace_activate (last_remaining, timestamp); - - /* Should now be safe to free the workspaces */ - tmp = extras; - while (tmp != NULL) - { - MetaWorkspace *w = tmp->data; - - g_assert (w->windows == NULL); - meta_workspace_remove (w); - - tmp = tmp->next; - } - - g_list_free (extras); - - for (i = old_num; i < new_num; i++) - meta_workspace_new (screen); - - set_number_of_spaces_hint (screen, new_num); - update_net_desktop_layout (screen, new_num); - set_workspace_names (screen); - - meta_screen_queue_workarea_recalc (screen); - - for (i = old_num; i < new_num; i++) - g_signal_emit (screen, screen_signals[WORKSPACE_ADDED], 0, i); - - g_object_notify (G_OBJECT (screen), "n-workspaces"); -} - -static void -update_focus_mode (MetaScreen *screen) -{ - /* nothing to do anymore */ ; -} - -LOCAL_SYMBOL void -meta_screen_set_cursor (MetaScreen *screen, - MetaCursor cursor) -{ - Cursor xcursor; - - if (cursor == screen->current_cursor) - return; - - screen->current_cursor = cursor; - - xcursor = meta_display_create_x_cursor (screen->display, cursor); - XDefineCursor (screen->display->xdisplay, screen->xroot, xcursor); - XFlush (screen->display->xdisplay); - XFreeCursor (screen->display->xdisplay, xcursor); -} - -LOCAL_SYMBOL void -meta_screen_update_cursor (MetaScreen *screen) -{ - Cursor xcursor; - - xcursor = meta_display_create_x_cursor (screen->display, - screen->current_cursor); - XDefineCursor (screen->display->xdisplay, screen->xroot, xcursor); - XFlush (screen->display->xdisplay); - XFreeCursor (screen->display->xdisplay, xcursor); -} - -static gboolean -snap_osd_timeout (void *data) -{ - MetaScreen *screen = data; - int monitor; - - monitor = meta_screen_get_current_monitor (screen); - - if (meta_screen_tile_preview_get_visible (screen) || - meta_screen_tile_hud_get_visible (screen)) - g_signal_emit (screen, screen_signals[SNAP_OSD_SHOW], 0, monitor); - screen->snap_osd_timeout_id = 0; - return FALSE; -} - -static gboolean -maybe_hide_snap_osd (void *data) -{ - MetaScreen *screen = data; - if (!meta_screen_tile_preview_get_visible (screen) && - !meta_screen_tile_hud_get_visible (screen)) { - if (screen->snap_osd_timeout_id > 0) { - g_source_remove (screen->snap_osd_timeout_id); - screen->snap_osd_timeout_id = 0; - } - g_signal_emit (screen, screen_signals[SNAP_OSD_HIDE], 0); - } - return FALSE; -} - -static gboolean -meta_screen_tile_preview_update_timeout (gpointer data) -{ - MetaScreen *screen = data; - MetaWindow *window = screen->display->grab_window; - gboolean needs_preview = FALSE; - - screen->tile_preview_timeout_id = 0; - - if (window && window->mouse_on_edge) - { - switch (window->tile_mode) - { - case META_TILE_LEFT: - case META_TILE_RIGHT: - if (!META_WINDOW_TILED_SIDE_BY_SIDE (window)) - needs_preview = TRUE; - break; - case META_TILE_ULC: - case META_TILE_LLC: - case META_TILE_URC: - case META_TILE_LRC: - if (!META_WINDOW_TILED_CORNER (window)) - needs_preview = TRUE; - break; - case META_TILE_TOP: - case META_TILE_BOTTOM: - if (!META_WINDOW_TILED_TOP_BOTTOM (window)) - needs_preview = TRUE; - break; - case META_TILE_MAXIMIZE: - if (!META_WINDOW_MAXIMIZED (window)) - needs_preview = TRUE; - break; - default: - needs_preview = FALSE; - break; - } - } - - if (needs_preview) - { - MetaRectangle tile_rect; - int monitor; - - monitor = meta_window_get_current_tile_monitor_number (window); - meta_window_get_current_tile_area (window, &tile_rect); - meta_compositor_show_tile_preview (screen->display->compositor, - screen, window, &tile_rect, monitor, - window->snap_queued); - screen->tile_preview_visible = TRUE; - - if (screen->snap_osd_timeout_id == 0) - screen->snap_osd_timeout_id = g_timeout_add_seconds (SNAP_OSD_TIMEOUT, - snap_osd_timeout, - screen); - } - else - { - meta_compositor_hide_tile_preview (screen->display->compositor, - screen); - screen->tile_preview_visible = FALSE; - } - - return FALSE; -} - -#define TILE_PREVIEW_TIMEOUT_MS 200 - -LOCAL_SYMBOL void -meta_screen_tile_preview_update (MetaScreen *screen, - gboolean delay) -{ - if (delay && !meta_screen_tile_preview_get_visible (screen)) - { - if (screen->tile_preview_timeout_id > 0) - return; - - screen->tile_preview_timeout_id = - g_timeout_add (TILE_PREVIEW_TIMEOUT_MS, - meta_screen_tile_preview_update_timeout, - screen); - } - else - { - if (screen->tile_preview_timeout_id > 0) { - g_source_remove (screen->tile_preview_timeout_id); - screen->tile_preview_timeout_id = 0; - } - - meta_screen_tile_preview_update_timeout ((gpointer)screen); - } -} - -LOCAL_SYMBOL void -meta_screen_tile_preview_hide (MetaScreen *screen) -{ - if (screen->tile_preview_timeout_id > 0) { - g_source_remove (screen->tile_preview_timeout_id); - screen->tile_preview_timeout_id = 0; - } - - if (!screen->tile_preview_visible) - return; - - meta_compositor_hide_tile_preview (screen->display->compositor, - screen); - screen->tile_preview_visible = FALSE; - - g_timeout_add (250, maybe_hide_snap_osd, screen); -} - -LOCAL_SYMBOL gboolean -meta_screen_tile_preview_get_visible (MetaScreen *screen) -{ - return screen->tile_preview_visible; -} - -static gboolean -meta_screen_tile_hud_update_timeout (gpointer data) -{ - MetaScreen *screen = data; - MetaWindow *window = screen->display->grab_window; - - screen->tile_hud_timeout_id = 0; - - if (!screen->tile_hud_visible && window != NULL && window->current_proximity_zone != ZONE_NONE) - { - MetaRectangle work_area; - /* This bit is liable to get more complicated when there are multiple - monitors involved - we'll have partial hud, with a bare area at the - monitor 'joint' or something... */ - int monitor; - monitor = meta_screen_get_current_monitor (screen); - meta_window_get_work_area_for_monitor (window, monitor, &work_area); - meta_compositor_show_hud_preview (screen->display->compositor, - screen, window->current_proximity_zone, - &work_area, window->snap_queued); - - screen->tile_hud_visible = TRUE; - - if (screen->snap_osd_timeout_id == 0) - screen->snap_osd_timeout_id = g_timeout_add_seconds (SNAP_OSD_TIMEOUT, - snap_osd_timeout, - screen); - } - else - { - meta_compositor_hide_hud_preview (screen->display->compositor, - screen); - screen->tile_hud_visible = FALSE; - g_timeout_add (250, maybe_hide_snap_osd, screen); - } - - return FALSE; -} - -#define TILE_HUD_TIMEOUT_MS 100 - -LOCAL_SYMBOL void -meta_screen_tile_hud_update (MetaScreen *screen, - gboolean delay, - gboolean hiding) -{ - if (screen->tile_hud_visible != hiding) - { - if (screen->tile_hud_timeout_id > 0) - { - g_source_remove (screen->tile_hud_timeout_id); - screen->tile_hud_timeout_id = 0; - } - screen->tile_hud_visible = hiding; - } - - if (delay && !meta_screen_tile_hud_get_visible (screen)) - { - if (screen->tile_hud_timeout_id > 0) - return; - - screen->tile_hud_timeout_id = g_timeout_add (TILE_HUD_TIMEOUT_MS, - meta_screen_tile_hud_update_timeout, - screen); - } - else - { - if (screen->tile_hud_timeout_id > 0) - { - g_source_remove (screen->tile_hud_timeout_id); - screen->tile_hud_timeout_id = 0; - } - - meta_screen_tile_hud_update_timeout ((gpointer)screen); - } -} - -LOCAL_SYMBOL void -meta_screen_tile_hud_hide (MetaScreen *screen) -{ - if (screen->tile_hud_timeout_id > 0) { - g_source_remove (screen->tile_hud_timeout_id); - screen->tile_hud_timeout_id = 0; - } - - if (!screen->tile_hud_visible) - return; - - meta_compositor_hide_hud_preview (screen->display->compositor, - screen); - - screen->tile_hud_visible = FALSE; - - g_timeout_add (250, maybe_hide_snap_osd, screen); -} - -LOCAL_SYMBOL gboolean -meta_screen_tile_hud_get_visible (MetaScreen *screen) -{ - return screen->tile_hud_visible; -} - -LOCAL_SYMBOL void -meta_screen_hide_hud_and_preview (MetaScreen *screen) -{ - meta_screen_tile_hud_hide (screen); - meta_screen_tile_preview_hide (screen); -} - -/** - * meta_screen_get_mouse_window: - * @screen: an X screen structure. - * @not_this_one: (allow-none): window to be excluded - * - * Gets the #MetaWindow pointed by the mouse - * - * Return value: (transfer none): the #MetaWindow pointed by the mouse - * %NULL when window not found - */ -MetaWindow* -meta_screen_get_mouse_window (MetaScreen *screen, - MetaWindow *not_this_one) -{ - MetaWindow *window; - GList *windows; - Window root_return, child_return; - int root_x_return, root_y_return; - int win_x_return, win_y_return; - unsigned int mask_return; - - window = NULL; -#ifdef WITH_VERBOSE_MODE - if (not_this_one) - meta_topic (META_DEBUG_FOCUS, - "Focusing mouse window excluding %s\n", not_this_one->desc); -#endif - meta_error_trap_push (screen->display); - XQueryPointer (screen->display->xdisplay, - screen->xroot, - &root_return, - &child_return, - &root_x_return, - &root_y_return, - &win_x_return, - &win_y_return, - &mask_return); - meta_error_trap_pop (screen->display); - - if (screen->active_workspace->showing_desktop) - { - windows = screen->active_workspace->mru_list; - while (windows != NULL) - { - MetaWindow *w = windows->data; - if (w->screen == screen && - w->type == META_WINDOW_DESKTOP) - { - window = w; - break; - } - windows = windows->next; - } - } - else - window = meta_stack_get_default_focus_window_at_point (screen->stack, - screen->active_workspace, - not_this_one, - root_x_return, - root_y_return); - - return window; -} - -LOCAL_SYMBOL const MetaMonitorInfo* -meta_screen_get_monitor_for_rect (MetaScreen *screen, - MetaRectangle *rect) -{ - int i; - int best_monitor, monitor_score, rect_area; - - if (screen->n_monitor_infos == 1) - return &screen->monitor_infos[0]; - - best_monitor = 0; - monitor_score = -1; - - rect_area = meta_rectangle_area (rect); - for (i = 0; i < screen->n_monitor_infos; i++) - { - gboolean result; - int cur; - - if (rect_area > 0) - { - MetaRectangle dest; - result = meta_rectangle_intersect (&screen->monitor_infos[i].rect, - rect, - &dest); - cur = meta_rectangle_area (&dest); - } - else - { - result = meta_rectangle_contains_rect (&screen->monitor_infos[i].rect, - rect); - cur = rect_area; - } - - if (result && cur > monitor_score) - { - monitor_score = cur; - best_monitor = i; - } - } - - return &screen->monitor_infos[best_monitor]; -} - -LOCAL_SYMBOL const MetaMonitorInfo* -meta_screen_get_monitor_for_window (MetaScreen *screen, - MetaWindow *window) -{ - MetaRectangle window_rect; - - meta_window_get_outer_rect (window, &window_rect); - - return meta_screen_get_monitor_for_rect (screen, &window_rect); -} - -int -meta_screen_get_monitor_index_for_rect (MetaScreen *screen, - MetaRectangle *rect) -{ - const MetaMonitorInfo *monitor = meta_screen_get_monitor_for_rect (screen, rect); - return monitor->number; -} - -LOCAL_SYMBOL const MetaMonitorInfo* -meta_screen_get_monitor_neighbor (MetaScreen *screen, - int which_monitor, - MetaScreenDirection direction) -{ - MetaMonitorInfo* input = screen->monitor_infos + which_monitor; - MetaMonitorInfo* current; - int i; - - for (i = 0; i < screen->n_monitor_infos; i++) - { - current = screen->monitor_infos + i; - - if ((direction == META_SCREEN_RIGHT && - current->rect.x == input->rect.x + input->rect.width && - meta_rectangle_vert_overlap(¤t->rect, &input->rect)) || - (direction == META_SCREEN_LEFT && - input->rect.x == current->rect.x + current->rect.width && - meta_rectangle_vert_overlap(¤t->rect, &input->rect)) || - (direction == META_SCREEN_UP && - input->rect.y == current->rect.y + current->rect.height && - meta_rectangle_horiz_overlap(¤t->rect, &input->rect)) || - (direction == META_SCREEN_DOWN && - current->rect.y == input->rect.y + input->rect.height && - meta_rectangle_horiz_overlap(¤t->rect, &input->rect))) - { - return current; - } - } - - return NULL; -} - -LOCAL_SYMBOL void -meta_screen_get_natural_monitor_list (MetaScreen *screen, - int** monitors_list, - int* n_monitors) -{ - const MetaMonitorInfo* current; - const MetaMonitorInfo* tmp; - GQueue* monitor_queue; - int* visited; - int cur = 0; - int i; - - *n_monitors = screen->n_monitor_infos; - *monitors_list = g_new (int, screen->n_monitor_infos); - - /* we calculate a natural ordering by which to choose monitors for - * window placement. We start at the current monitor, and perform - * a breadth-first search of the monitors starting from that - * monitor. We choose preferentially left, then right, then down, - * then up. The visitation order produced by this traversal is the - * natural monitor ordering. - */ - - visited = g_new (int, screen->n_monitor_infos); - for (i = 0; i < screen->n_monitor_infos; i++) - { - visited[i] = FALSE; - } - - current = meta_screen_get_current_monitor_info (screen); - monitor_queue = g_queue_new (); - g_queue_push_tail (monitor_queue, (gpointer) current); - visited[current->number] = TRUE; - - while (!g_queue_is_empty (monitor_queue)) - { - current = (const MetaMonitorInfo*) - g_queue_pop_head (monitor_queue); - - (*monitors_list)[cur++] = current->number; - - /* enqueue each of the directions */ - tmp = meta_screen_get_monitor_neighbor (screen, - current->number, - META_SCREEN_LEFT); - if (tmp && !visited[tmp->number]) - { - g_queue_push_tail (monitor_queue, - (MetaMonitorInfo*) tmp); - visited[tmp->number] = TRUE; - } - tmp = meta_screen_get_monitor_neighbor (screen, - current->number, - META_SCREEN_RIGHT); - if (tmp && !visited[tmp->number]) - { - g_queue_push_tail (monitor_queue, - (MetaMonitorInfo*) tmp); - visited[tmp->number] = TRUE; - } - tmp = meta_screen_get_monitor_neighbor (screen, - current->number, - META_SCREEN_UP); - if (tmp && !visited[tmp->number]) - { - g_queue_push_tail (monitor_queue, - (MetaMonitorInfo*) tmp); - visited[tmp->number] = TRUE; - } - tmp = meta_screen_get_monitor_neighbor (screen, - current->number, - META_SCREEN_DOWN); - if (tmp && !visited[tmp->number]) - { - g_queue_push_tail (monitor_queue, - (MetaMonitorInfo*) tmp); - visited[tmp->number] = TRUE; - } - } - - /* in case we somehow missed some set of monitors, go through the - * visited list and add in any monitors that were missed - */ - for (i = 0; i < screen->n_monitor_infos; i++) - { - if (visited[i] == FALSE) - { - (*monitors_list)[cur++] = i; - } - } - - free (visited); - g_queue_free (monitor_queue); -} - -const MetaMonitorInfo * -meta_screen_get_current_monitor_info (MetaScreen *screen) -{ - int monitor_index; - monitor_index = meta_screen_get_current_monitor (screen); - return &screen->monitor_infos[monitor_index]; -} - -/** - * meta_screen_get_current_monitor: - * @screen: a #MetaScreen - * - * Gets the index of the monitor that currently has the mouse pointer. - * - * Return value: a monitor index - */ -int -meta_screen_get_current_monitor (MetaScreen *screen) -{ - if (screen->n_monitor_infos == 1) - return 0; - - /* Sadly, we have to do it this way. Yuck. - */ - - if (screen->display->monitor_cache_invalidated) - { - Window root_return, child_return; - int win_x_return, win_y_return; - unsigned int mask_return; - int i; - MetaRectangle pointer_position; - - screen->display->monitor_cache_invalidated = FALSE; - - pointer_position.width = pointer_position.height = 1; - XQueryPointer (screen->display->xdisplay, - screen->xroot, - &root_return, - &child_return, - &pointer_position.x, - &pointer_position.y, - &win_x_return, - &win_y_return, - &mask_return); - - screen->last_monitor_index = 0; - for (i = 0; i < screen->n_monitor_infos; i++) - { - if (meta_rectangle_contains_rect (&screen->monitor_infos[i].rect, - &pointer_position)) - { - screen->last_monitor_index = i; - break; - } - } - - meta_topic (META_DEBUG_XINERAMA, - "Rechecked current monitor, now %d\n", - screen->last_monitor_index); - } - - return screen->last_monitor_index; -} - -/** - * meta_screen_get_n_monitors: - * @screen: a #MetaScreen - * - * Gets the number of monitors that are joined together to form @screen. - * - * Return value: the number of monitors - */ -int -meta_screen_get_n_monitors (MetaScreen *screen) -{ - g_return_val_if_fail (META_IS_SCREEN (screen), 0); - - return screen->n_monitor_infos; -} - -/** - * meta_screen_get_primary_monitor: - * @screen: a #MetaScreen - * - * Gets the index of the primary monitor on this @screen. - * - * Return value: a monitor index - */ -int -meta_screen_get_primary_monitor (MetaScreen *screen) -{ - g_return_val_if_fail (META_IS_SCREEN (screen), 0); - - return screen->primary_monitor_index; -} - -/** - * meta_screen_get_monitor_geometry: - * @screen: a #MetaScreen - * @monitor: the monitor number - * @geometry: (out): location to store the monitor geometry - * - * Stores the location and size of the indicated monitor in @geometry. - */ -void -meta_screen_get_monitor_geometry (MetaScreen *screen, - int monitor, - MetaRectangle *geometry) -{ - g_return_if_fail (META_IS_SCREEN (screen)); - g_return_if_fail (monitor >= 0 && monitor < screen->n_monitor_infos); - g_return_if_fail (geometry != NULL); - - *geometry = screen->monitor_infos[monitor].rect; -} - -LOCAL_SYMBOL void -meta_screen_update_workspace_layout (MetaScreen *screen) -{ - gulong *list; - int n_items; - - if (screen->workspace_layout_overridden) - return; - - list = NULL; - n_items = 0; - - if (meta_prop_get_cardinal_list (screen->display, - screen->xroot, - screen->display->atom__NET_DESKTOP_LAYOUT, - &list, &n_items)) - { - if (n_items == 3 || n_items == 4) - { - int cols, rows; - - switch (list[0]) - { - case _NET_WM_ORIENTATION_HORZ: - screen->vertical_workspaces = FALSE; - break; - case _NET_WM_ORIENTATION_VERT: - screen->vertical_workspaces = TRUE; - break; - default: - meta_warning ("Someone set a weird orientation in _NET_DESKTOP_LAYOUT\n"); - break; - } - - cols = list[1]; - rows = list[2]; - - if (rows <= 0 && cols <= 0) - { - meta_warning ("Columns = %d rows = %d in _NET_DESKTOP_LAYOUT makes no sense\n", rows, cols); - } - else - { - if (rows > 0) - screen->rows_of_workspaces = rows; - else - screen->rows_of_workspaces = -1; - - if (cols > 0) - screen->columns_of_workspaces = cols; - else - screen->columns_of_workspaces = -1; - } - - if (n_items == 4) - { - switch (list[3]) - { - case _NET_WM_TOPLEFT: - screen->starting_corner = META_SCREEN_TOPLEFT; - break; - case _NET_WM_TOPRIGHT: - screen->starting_corner = META_SCREEN_TOPRIGHT; - break; - case _NET_WM_BOTTOMRIGHT: - screen->starting_corner = META_SCREEN_BOTTOMRIGHT; - break; - case _NET_WM_BOTTOMLEFT: - screen->starting_corner = META_SCREEN_BOTTOMLEFT; - break; - default: - meta_warning ("Someone set a weird starting corner in _NET_DESKTOP_LAYOUT\n"); - break; - } - } - else - screen->starting_corner = META_SCREEN_TOPLEFT; - } - else - { - meta_warning ("Someone set _NET_DESKTOP_LAYOUT to %d integers instead of 4 " - "(3 is accepted for backwards compat)\n", n_items); - } - - meta_XFree (list); - } - - meta_verbose ("Workspace layout rows = %d cols = %d orientation = %d starting corner = %u\n", - screen->rows_of_workspaces, - screen->columns_of_workspaces, - screen->vertical_workspaces, - screen->starting_corner); -} - -/** - * meta_screen_override_workspace_layout: - * @screen: a #MetaScreen - * @starting_corner: the corner at which the first workspace is found - * @vertical_layout: if %TRUE the workspaces are laid out in columns rather than rows - * @n_rows: number of rows of workspaces, or -1 to determine the number of rows from - * @n_columns and the total number of workspaces - * @n_columns: number of columns of workspaces, or -1 to determine the number of columns from - * @n_rows and the total number of workspaces - * - * Explicitly set the layout of workspaces. Once this has been called, the contents of the - * _NET_DESKTOP_LAYOUT property on the root window are completely ignored. - */ -void -meta_screen_override_workspace_layout (MetaScreen *screen, - MetaScreenCorner starting_corner, - gboolean vertical_layout, - int n_rows, - int n_columns) -{ - g_return_if_fail (META_IS_SCREEN (screen)); - g_return_if_fail (n_rows > 0 || n_columns > 0); - g_return_if_fail (n_rows != 0 && n_columns != 0); - - screen->workspace_layout_overridden = TRUE; - screen->vertical_workspaces = vertical_layout != FALSE; - screen->starting_corner = starting_corner; - screen->rows_of_workspaces = n_rows; - screen->columns_of_workspaces = n_columns; -} - -static void -set_workspace_names (MetaScreen *screen) -{ - /* This updates names on root window when the pref changes, - * note we only get prefs change notify if things have - * really changed. - */ - GString *flattened; - int i; - int n_spaces; - - /* flatten to nul-separated list */ - n_spaces = meta_screen_get_n_workspaces (screen); - flattened = g_string_new (""); - i = 0; - while (i < n_spaces) - { - const char *name; - - name = meta_prefs_get_workspace_name (i); - - if (name) - g_string_append_len (flattened, name, - strlen (name) + 1); - else - g_string_append_len (flattened, "", 1); - - ++i; - } - - meta_error_trap_push (screen->display); - XChangeProperty (screen->display->xdisplay, - screen->xroot, - screen->display->atom__NET_DESKTOP_NAMES, - screen->display->atom_UTF8_STRING, - 8, PropModeReplace, - (unsigned char *)flattened->str, flattened->len); - meta_error_trap_pop (screen->display); - - g_string_free (flattened, TRUE); -} - -LOCAL_SYMBOL void -meta_screen_update_workspace_names (MetaScreen *screen) -{ - char **names; - int n_names; - int i; - - /* this updates names in prefs when the root window property changes, - * iff the new property contents don't match what's already in prefs - */ - - names = NULL; - n_names = 0; - if (!meta_prop_get_utf8_list (screen->display, - screen->xroot, - screen->display->atom__NET_DESKTOP_NAMES, - &names, &n_names)) - { - meta_verbose ("Failed to get workspace names from root window %d\n", - screen->number); - return; - } - - i = 0; - while (i < n_names) - { - meta_topic (META_DEBUG_PREFS, - "Setting workspace %d name to \"%s\" due to _NET_DESKTOP_NAMES change\n", - i, names[i] ? names[i] : "null"); - meta_prefs_change_workspace_name (i, names[i]); - - ++i; - } - - g_strfreev (names); -} - -LOCAL_SYMBOL Window -meta_create_offscreen_window (Display *xdisplay, - Window parent, - long valuemask) -{ - XSetWindowAttributes attrs; - - /* we want to be override redirect because sometimes we - * create a window on a screen we aren't managing. - * (but on a display we are managing at least one screen for) - */ - attrs.override_redirect = True; - attrs.event_mask = valuemask; - - return XCreateWindow (xdisplay, - parent, - -100, -100, 1, 1, - 0, - CopyFromParent, - CopyFromParent, - (Visual *)CopyFromParent, - CWOverrideRedirect | CWEventMask, - &attrs); -} - -static void -set_work_area_hint (MetaScreen *screen) -{ - int num_workspaces; - GList *tmp_list; - unsigned long *data, *tmp; - MetaRectangle area; - - num_workspaces = meta_screen_get_n_workspaces (screen); - data = g_new (unsigned long, num_workspaces * 4); - tmp_list = screen->workspaces; - tmp = data; - - while (tmp_list != NULL) - { - MetaWorkspace *workspace = tmp_list->data; - - if (workspace->screen == screen) - { - meta_workspace_get_work_area_all_monitors (workspace, &area); - tmp[0] = area.x; - tmp[1] = area.y; - tmp[2] = area.width; - tmp[3] = area.height; - - tmp += 4; - } - - tmp_list = tmp_list->next; - } - - meta_error_trap_push (screen->display); - XChangeProperty (screen->display->xdisplay, screen->xroot, - screen->display->atom__NET_WORKAREA, - XA_CARDINAL, 32, PropModeReplace, - (guchar*) data, num_workspaces*4); - free (data); - meta_error_trap_pop (screen->display); - - g_signal_emit (screen, screen_signals[WORKAREAS_CHANGED], 0); -} - -static gboolean -set_work_area_later_func (MetaScreen *screen) -{ - meta_topic (META_DEBUG_WORKAREA, - "Running work area hint computation function\n"); - - screen->work_area_later = 0; - - set_work_area_hint (screen); - - return FALSE; -} - -LOCAL_SYMBOL void -meta_screen_queue_workarea_recalc (MetaScreen *screen) -{ - /* Recompute work area later before redrawing */ - if (screen->work_area_later == 0) - { - meta_topic (META_DEBUG_WORKAREA, - "Adding work area hint computation function\n"); - screen->work_area_later = - meta_later_add (META_LATER_BEFORE_REDRAW, - (GSourceFunc) set_work_area_later_func, - screen, - NULL); - } -} - - -#ifdef WITH_VERBOSE_MODE -static char * -meta_screen_corner_to_string (MetaScreenCorner corner) -{ - switch (corner) - { - case META_SCREEN_TOPLEFT: - return "TopLeft"; - case META_SCREEN_TOPRIGHT: - return "TopRight"; - case META_SCREEN_BOTTOMLEFT: - return "BottomLeft"; - case META_SCREEN_BOTTOMRIGHT: - return "BottomRight"; - } - - return "Unknown"; -} -#endif /* WITH_VERBOSE_MODE */ - -LOCAL_SYMBOL void -meta_screen_calc_workspace_layout (MetaScreen *screen, - int num_workspaces, - int current_space, - MetaWorkspaceLayout *layout) -{ - int rows, cols; - int grid_area; - int *grid; - int i, r, c; - int current_row, current_col; - - rows = screen->rows_of_workspaces; - cols = screen->columns_of_workspaces; - if (rows <= 0 && cols <= 0) - cols = num_workspaces; - - if (rows <= 0) - rows = num_workspaces / cols + ((num_workspaces % cols) > 0 ? 1 : 0); - if (cols <= 0) - cols = num_workspaces / rows + ((num_workspaces % rows) > 0 ? 1 : 0); - - /* paranoia */ - if (rows < 1) - rows = 1; - if (cols < 1) - cols = 1; - - g_assert (rows != 0 && cols != 0); - - grid_area = rows * cols; - - meta_verbose ("Getting layout rows = %d cols = %d current = %d " - "num_spaces = %d vertical = %s corner = %s\n", - rows, cols, current_space, num_workspaces, - screen->vertical_workspaces ? "(true)" : "(false)", - meta_screen_corner_to_string (screen->starting_corner)); - - /* ok, we want to setup the distances in the workspace array to go - * in each direction. Remember, there are many ways that a workspace - * array can be setup. - * see http://www.freedesktop.org/standards/wm-spec/1.2/html/x109.html - * and look at the _NET_DESKTOP_LAYOUT section for details. - * For instance: - */ - /* starting_corner = META_SCREEN_TOPLEFT - * vertical_workspaces = 0 vertical_workspaces=1 - * 1234 1357 - * 5678 2468 - * - * starting_corner = META_SCREEN_TOPRIGHT - * vertical_workspaces = 0 vertical_workspaces=1 - * 4321 7531 - * 8765 8642 - * - * starting_corner = META_SCREEN_BOTTOMLEFT - * vertical_workspaces = 0 vertical_workspaces=1 - * 5678 2468 - * 1234 1357 - * - * starting_corner = META_SCREEN_BOTTOMRIGHT - * vertical_workspaces = 0 vertical_workspaces=1 - * 8765 8642 - * 4321 7531 - * - */ - /* keep in mind that we could have a ragged layout, e.g. the "8" - * in the above grids could be missing - */ - - - grid = g_new (int, grid_area); - - i = 0; - - switch (screen->starting_corner) - { - case META_SCREEN_TOPLEFT: - if (screen->vertical_workspaces) - { - c = 0; - while (c < cols) - { - r = 0; - while (r < rows) - { - grid[r*cols+c] = i; - ++i; - ++r; - } - ++c; - } - } - else - { - r = 0; - while (r < rows) - { - c = 0; - while (c < cols) - { - grid[r*cols+c] = i; - ++i; - ++c; - } - ++r; - } - } - break; - case META_SCREEN_TOPRIGHT: - if (screen->vertical_workspaces) - { - c = cols - 1; - while (c >= 0) - { - r = 0; - while (r < rows) - { - grid[r*cols+c] = i; - ++i; - ++r; - } - --c; - } - } - else - { - r = 0; - while (r < rows) - { - c = cols - 1; - while (c >= 0) - { - grid[r*cols+c] = i; - ++i; - --c; - } - ++r; - } - } - break; - case META_SCREEN_BOTTOMLEFT: - if (screen->vertical_workspaces) - { - c = 0; - while (c < cols) - { - r = rows - 1; - while (r >= 0) - { - grid[r*cols+c] = i; - ++i; - --r; - } - ++c; - } - } - else - { - r = rows - 1; - while (r >= 0) - { - c = 0; - while (c < cols) - { - grid[r*cols+c] = i; - ++i; - ++c; - } - --r; - } - } - break; - case META_SCREEN_BOTTOMRIGHT: - if (screen->vertical_workspaces) - { - c = cols - 1; - while (c >= 0) - { - r = rows - 1; - while (r >= 0) - { - grid[r*cols+c] = i; - ++i; - --r; - } - --c; - } - } - else - { - r = rows - 1; - while (r >= 0) - { - c = cols - 1; - while (c >= 0) - { - grid[r*cols+c] = i; - ++i; - --c; - } - --r; - } - } - break; - } - - if (i != grid_area) - meta_bug ("did not fill in the whole workspace grid in %s (%d filled)\n", - G_STRFUNC, i); - - current_row = 0; - current_col = 0; - r = 0; - while (r < rows) - { - c = 0; - while (c < cols) - { - if (grid[r*cols+c] == current_space) - { - current_row = r; - current_col = c; - } - else if (grid[r*cols+c] >= num_workspaces) - { - /* flag nonexistent spaces with -1 */ - grid[r*cols+c] = -1; - } - ++c; - } - ++r; - } - - layout->rows = rows; - layout->cols = cols; - layout->grid = grid; - layout->grid_area = grid_area; - layout->current_row = current_row; - layout->current_col = current_col; - -#ifdef WITH_VERBOSE_MODE - if (meta_is_verbose ()) - { - r = 0; - while (r < layout->rows) - { - meta_verbose (" "); - meta_push_no_msg_prefix (); - c = 0; - while (c < layout->cols) - { - if (r == layout->current_row && - c == layout->current_col) - meta_verbose ("*%2d ", layout->grid[r*layout->cols+c]); - else - meta_verbose ("%3d ", layout->grid[r*layout->cols+c]); - ++c; - } - meta_verbose ("\n"); - meta_pop_no_msg_prefix (); - ++r; - } - } -#endif /* WITH_VERBOSE_MODE */ -} - -LOCAL_SYMBOL void -meta_screen_free_workspace_layout (MetaWorkspaceLayout *layout) -{ - free (layout->grid); -} - -static void -meta_screen_resize_func (MetaScreen *screen, - MetaWindow *window, - void *user_data) -{ - if (window->struts) - { - meta_window_update_struts (window); - } - meta_window_queue (window, META_QUEUE_MOVE_RESIZE); - - meta_window_recalc_features (window); -} - -LOCAL_SYMBOL void -meta_screen_resize (MetaScreen *screen, - int width, - int height) -{ - GSList *windows, *tmp; - MetaMonitorInfo *old_monitor_infos; - - screen->rect.width = width; - screen->rect.height = height; - - /* Save the old monitor infos, so they stay valid during the update */ - old_monitor_infos = screen->monitor_infos; - - reload_monitor_infos (screen); - set_desktop_geometry_hint (screen); - - meta_compositor_sync_screen_size (screen->display->compositor, - screen, width, height); - - /* Queue a resize on all the windows */ - meta_screen_foreach_window (screen, meta_screen_resize_func, 0); - - /* Fix up monitor for all windows on this screen */ - windows = meta_display_list_windows (screen->display, - META_LIST_INCLUDE_OVERRIDE_REDIRECT); - for (tmp = windows; tmp != NULL; tmp = tmp->next) - { - MetaWindow *window = tmp->data; - - if (window->screen == screen) - meta_window_update_for_monitors_changed (window); - } - - free (old_monitor_infos); - g_slist_free (windows); - - meta_screen_queue_check_fullscreen (screen); - - g_signal_emit (screen, screen_signals[MONITORS_CHANGED], 0); -} - -LOCAL_SYMBOL void -meta_screen_update_showing_desktop_hint (MetaScreen *screen) -{ - unsigned long data[1]; - - data[0] = screen->active_workspace->showing_desktop ? 1 : 0; - - meta_error_trap_push (screen->display); - XChangeProperty (screen->display->xdisplay, screen->xroot, - screen->display->atom__NET_SHOWING_DESKTOP, - XA_CARDINAL, - 32, PropModeReplace, (guchar*) data, 1); - meta_error_trap_pop (screen->display); -} - -static void -queue_windows_showing (MetaScreen *screen) -{ - GSList *windows; - GSList *tmp; - - /* Must operate on all windows on display instead of just on the - * active_workspace's window list, because the active_workspace's - * window list may not contain the on_all_workspace windows. - */ - windows = meta_display_list_windows (screen->display, META_LIST_INCLUDE_OVERRIDE_REDIRECT); - - tmp = windows; - while (tmp != NULL) - { - MetaWindow *w = tmp->data; - - if (w->screen == screen) - meta_window_queue (w, META_QUEUE_CALC_SHOWING); - - tmp = tmp->next; - } - - g_slist_free (windows); -} - -LOCAL_SYMBOL void -meta_screen_minimize_all_on_active_workspace_except (MetaScreen *screen, - MetaWindow *keep) -{ - GList *windows; - GList *tmp; - - windows = screen->active_workspace->windows; - - tmp = windows; - while (tmp != NULL) - { - MetaWindow *w = tmp->data; - - if (w->screen == screen && - w->has_minimize_func && - w != keep) - meta_window_minimize (w); - - tmp = tmp->next; - } -} - -void -meta_screen_toggle_desktop (MetaScreen *screen, - guint32 timestamp) -{ - if (screen->active_workspace->showing_desktop) - { - meta_screen_unshow_desktop (screen); - meta_workspace_focus_default_window (screen->active_workspace, - NULL, - timestamp); - } - else - { - meta_screen_show_desktop (screen, timestamp); - } -} - -void -meta_screen_show_desktop (MetaScreen *screen, - guint32 timestamp) -{ - GList *windows; - - if (screen->active_workspace->showing_desktop) - return; - - screen->active_workspace->showing_desktop = TRUE; - - queue_windows_showing (screen); - - /* Focus the most recently used META_WINDOW_DESKTOP window, if there is one; - * see bug 159257. - */ - windows = screen->active_workspace->mru_list; - while (windows != NULL) - { - MetaWindow *w = windows->data; - - if (w->screen == screen && - w->type == META_WINDOW_DESKTOP) - { - meta_window_focus (w, timestamp); - break; - } - - windows = windows->next; - } - - - meta_screen_update_showing_desktop_hint (screen); -} - -void -meta_screen_unshow_desktop (MetaScreen *screen) -{ - if (!screen->active_workspace->showing_desktop) - return; - - screen->active_workspace->showing_desktop = FALSE; - - queue_windows_showing (screen); - - meta_screen_update_showing_desktop_hint (screen); -} - - -#ifdef HAVE_STARTUP_NOTIFICATION -static gboolean startup_sequence_timeout (void *data); - -static void -update_startup_feedback (MetaScreen *screen) -{ - if (screen->startup_sequences != NULL) - { - meta_topic (META_DEBUG_STARTUP, - "Setting busy cursor\n"); - meta_screen_set_cursor (screen, META_CURSOR_BUSY); - } - else - { - meta_topic (META_DEBUG_STARTUP, - "Setting default cursor\n"); - meta_screen_set_cursor (screen, META_CURSOR_DEFAULT); - } -} - -static void -add_sequence (MetaScreen *screen, - SnStartupSequence *sequence) -{ - meta_topic (META_DEBUG_STARTUP, - "Adding sequence %s\n", - sn_startup_sequence_get_id (sequence)); - sn_startup_sequence_ref (sequence); - screen->startup_sequences = g_slist_prepend (screen->startup_sequences, - sequence); - - /* our timeout just polls every second, instead of bothering - * to compute exactly when we may next time out - */ - if (screen->startup_sequence_timeout == 0) - screen->startup_sequence_timeout = g_timeout_add_seconds (1, - startup_sequence_timeout, - screen); - - update_startup_feedback (screen); -} - -static void -remove_sequence (MetaScreen *screen, - SnStartupSequence *sequence) -{ - meta_topic (META_DEBUG_STARTUP, - "Removing sequence %s\n", - sn_startup_sequence_get_id (sequence)); - - screen->startup_sequences = g_slist_remove (screen->startup_sequences, - sequence); - - if (screen->startup_sequences == NULL && - screen->startup_sequence_timeout != 0) - { - g_source_remove (screen->startup_sequence_timeout); - screen->startup_sequence_timeout = 0; - } - - update_startup_feedback (screen); - - sn_startup_sequence_unref (sequence); -} - -typedef struct -{ - GSList *list; - GTimeVal now; -} CollectTimedOutData; - -/* This should be fairly long, as it should never be required unless - * apps or .desktop files are buggy, and it's confusing if - * OpenOffice or whatever seems to stop launching - people - * might decide they need to launch it again. - */ -#define STARTUP_TIMEOUT 15000 - -static void -collect_timed_out_foreach (void *element, - void *data) -{ - CollectTimedOutData *ctod = data; - SnStartupSequence *sequence = element; - long tv_sec, tv_usec; - double elapsed; - - sn_startup_sequence_get_last_active_time (sequence, &tv_sec, &tv_usec); - - elapsed = - ((((double)ctod->now.tv_sec - tv_sec) * G_USEC_PER_SEC + - (ctod->now.tv_usec - tv_usec))) / 1000.0; - - meta_topic (META_DEBUG_STARTUP, - "Sequence used %g seconds vs. %g max: %s\n", - elapsed, (double) STARTUP_TIMEOUT, - sn_startup_sequence_get_id (sequence)); - - if (elapsed > STARTUP_TIMEOUT) - ctod->list = g_slist_prepend (ctod->list, sequence); -} - -static gboolean -startup_sequence_timeout (void *data) -{ - MetaScreen *screen = data; - CollectTimedOutData ctod; - GSList *tmp; - - ctod.list = NULL; - g_get_current_time (&ctod.now); - g_slist_foreach (screen->startup_sequences, - collect_timed_out_foreach, - &ctod); - - tmp = ctod.list; - while (tmp != NULL) - { - SnStartupSequence *sequence = tmp->data; - - meta_topic (META_DEBUG_STARTUP, - "Timed out sequence %s\n", - sn_startup_sequence_get_id (sequence)); - - sn_startup_sequence_complete (sequence); - - tmp = tmp->next; - } - - g_slist_free (ctod.list); - - if (screen->startup_sequences != NULL) - { - return TRUE; - } - else - { - /* remove */ - screen->startup_sequence_timeout = 0; - return FALSE; - } -} - -static void -meta_screen_sn_event (SnMonitorEvent *event, - void *user_data) -{ - MetaScreen *screen; - SnStartupSequence *sequence; - - screen = user_data; - - sequence = sn_monitor_event_get_startup_sequence (event); - - sn_startup_sequence_ref (sequence); - - switch (sn_monitor_event_get_type (event)) - { - case SN_MONITOR_EVENT_INITIATED: - { - const char *wmclass; - - wmclass = sn_startup_sequence_get_wmclass (sequence); - - meta_topic (META_DEBUG_STARTUP, - "Received startup initiated for %s wmclass %s\n", - sn_startup_sequence_get_id (sequence), - wmclass ? wmclass : "(unset)"); - add_sequence (screen, sequence); - } - break; - - case SN_MONITOR_EVENT_COMPLETED: - { - meta_topic (META_DEBUG_STARTUP, - "Received startup completed for %s\n", - sn_startup_sequence_get_id (sequence)); - remove_sequence (screen, - sn_monitor_event_get_startup_sequence (event)); - } - break; - - case SN_MONITOR_EVENT_CHANGED: - meta_topic (META_DEBUG_STARTUP, - "Received startup changed for %s\n", - sn_startup_sequence_get_id (sequence)); - break; - - case SN_MONITOR_EVENT_CANCELED: - meta_topic (META_DEBUG_STARTUP, - "Received startup canceled for %s\n", - sn_startup_sequence_get_id (sequence)); - break; - } - - g_signal_emit (G_OBJECT (screen), screen_signals[STARTUP_SEQUENCE_CHANGED], 0, sequence); - - sn_startup_sequence_unref (sequence); -} - -/** - * meta_screen_get_startup_sequences: (skip) - * @screen: - * - * Return value: (transfer none): Currently active #SnStartupSequence items - */ -GSList * -meta_screen_get_startup_sequences (MetaScreen *screen) -{ - return screen->startup_sequences; -} -#endif - -/* Sets the initial_timestamp and initial_workspace properties - * of a window according to information given us by the - * startup-notification library. - * - * Returns TRUE if startup properties have been applied, and - * FALSE if they have not (for example, if they had already - * been applied.) - */ -LOCAL_SYMBOL gboolean -meta_screen_apply_startup_properties (MetaScreen *screen, - MetaWindow *window) -{ -#ifdef HAVE_STARTUP_NOTIFICATION - const char *startup_id; - GSList *tmp; - SnStartupSequence *sequence; - - /* Does the window have a startup ID stored? */ - startup_id = meta_window_get_startup_id (window); - - meta_topic (META_DEBUG_STARTUP, - "Applying startup props to %s id \"%s\"\n", - window->desc, - startup_id ? startup_id : "(none)"); - - sequence = NULL; - if (startup_id == NULL) - { - /* No startup ID stored for the window. Let's ask the - * startup-notification library whether there's anything - * stored for the resource name or resource class hints. - */ - tmp = screen->startup_sequences; - while (tmp != NULL) - { - const char *wmclass; - - wmclass = sn_startup_sequence_get_wmclass (tmp->data); - - if (wmclass != NULL && - ((window->res_class && - strcmp (wmclass, window->res_class) == 0) || - (window->res_name && - strcmp (wmclass, window->res_name) == 0))) - { - sequence = tmp->data; - - g_assert (window->startup_id == NULL); - window->startup_id = g_strdup (sn_startup_sequence_get_id (sequence)); - startup_id = window->startup_id; - - meta_topic (META_DEBUG_STARTUP, - "Ending legacy sequence %s due to window %s\n", - sn_startup_sequence_get_id (sequence), - window->desc); - - sn_startup_sequence_complete (sequence); - break; - } - - tmp = tmp->next; - } - } - - /* Still no startup ID? Bail. */ - if (startup_id == NULL) - return FALSE; - - /* We might get this far and not know the sequence ID (if the window - * already had a startup ID stored), so let's look for one if we don't - * already know it. - */ - if (sequence == NULL) - { - tmp = screen->startup_sequences; - while (tmp != NULL) - { - const char *id; - - id = sn_startup_sequence_get_id (tmp->data); - - if (strcmp (id, startup_id) == 0) - { - sequence = tmp->data; - break; - } - - tmp = tmp->next; - } - } - - if (sequence != NULL) - { - gboolean changed_something = FALSE; - - meta_topic (META_DEBUG_STARTUP, - "Found startup sequence for window %s ID \"%s\"\n", - window->desc, startup_id); - - if (!window->initial_workspace_set) - { - int space = sn_startup_sequence_get_workspace (sequence); - if (space >= 0) - { - meta_topic (META_DEBUG_STARTUP, - "Setting initial window workspace to %d based on startup info\n", - space); - - window->initial_workspace_set = TRUE; - window->initial_workspace = space; - changed_something = TRUE; - } - } - - if (!window->initial_timestamp_set) - { - guint32 timestamp = sn_startup_sequence_get_timestamp (sequence); - meta_topic (META_DEBUG_STARTUP, - "Setting initial window timestamp to %u based on startup info\n", - timestamp); - - window->initial_timestamp_set = TRUE; - window->initial_timestamp = timestamp; - changed_something = TRUE; - } - - return changed_something; - } -#ifdef WITH_VERBOSE_MODE - else - { - meta_topic (META_DEBUG_STARTUP, - "Did not find startup sequence for window %s ID \"%s\"\n", - window->desc, startup_id); - } -#endif -#endif /* HAVE_STARTUP_NOTIFICATION */ - - return FALSE; -} - -int -meta_screen_get_screen_number (MetaScreen *screen) -{ - return screen->number; -} - -/** - * meta_screen_get_display: - * Retrieve the display associated with screen. - * @screen: A #MetaScreen - * - * Returns: (transfer none): Display - */ -MetaDisplay * -meta_screen_get_display (MetaScreen *screen) -{ - return screen->display; -} - -/** - * meta_screen_get_xroot: (skip) - * - */ -Window -meta_screen_get_xroot (MetaScreen *screen) -{ - return screen->xroot; -} - -/** - * meta_screen_get_size: - * @screen: A #MetaScreen - * @width: (out): The width of the screen - * @height: (out): The height of the screen - * - * Retrieve the size of the screen. - */ -void -meta_screen_get_size (MetaScreen *screen, - int *width, - int *height) -{ - *width = screen->rect.width; - *height = screen->rect.height; -} - -void -meta_screen_set_cm_selection (MetaScreen *screen) -{ - char selection[32]; - Atom a; - - screen->wm_cm_timestamp = meta_display_get_current_time_roundtrip ( - screen->display); - - g_snprintf (selection, sizeof(selection), "_NET_WM_CM_S%d", screen->number); - meta_verbose ("Setting selection: %s\n", selection); - a = XInternAtom (screen->display->xdisplay, selection, FALSE); - XSetSelectionOwner (screen->display->xdisplay, a, - screen->wm_cm_selection_window, screen->wm_cm_timestamp); -} - -void -meta_screen_unset_cm_selection (MetaScreen *screen) -{ - char selection[32]; - Atom a; - - g_snprintf (selection, sizeof(selection), "_NET_WM_CM_S%d", screen->number); - a = XInternAtom (screen->display->xdisplay, selection, FALSE); - XSetSelectionOwner (screen->display->xdisplay, a, - None, screen->wm_cm_timestamp); -} - -/** - * meta_screen_get_workspaces: (skip) - * @screen: a #MetaScreen - * - * Returns: (transfer none) (element-type Meta.Workspace): The workspaces for @screen - */ -GList * -meta_screen_get_workspaces (MetaScreen *screen) -{ - return screen->workspaces; -} - -int -meta_screen_get_active_workspace_index (MetaScreen *screen) -{ - MetaWorkspace *active = screen->active_workspace; - - if (!active) - return -1; - - return meta_workspace_index (active); -} - -/** - * meta_screen_get_active_workspace: - * - * Returns: (transfer none): The current workspace - */ -MetaWorkspace * -meta_screen_get_active_workspace (MetaScreen *screen) -{ - return screen->active_workspace; -} - -LOCAL_SYMBOL void -meta_screen_restacked (MetaScreen *screen) -{ - g_signal_emit (screen, screen_signals[RESTACKED], 0); -} - -LOCAL_SYMBOL void -meta_screen_workspace_switched (MetaScreen *screen, - int from, - int to, - MetaMotionDirection direction) -{ - meta_screen_update_snapped_windows (screen); - g_signal_emit (screen, screen_signals[WORKSPACE_SWITCHED], 0, - from, to, direction); -} - -LOCAL_SYMBOL void -meta_screen_set_active_workspace_hint (MetaScreen *screen) -{ - unsigned long data[1]; - - /* this is because we destroy the spaces in order, - * so we always end up setting a current desktop of - * 0 when closing a screen, so lose the current desktop - * on restart. By doing this we keep the current - * desktop on restart. - */ - if (screen->closing > 0) - return; - - data[0] = meta_workspace_index (screen->active_workspace); - - meta_verbose ("Setting _NET_CURRENT_DESKTOP to %lu\n", data[0]); - - meta_error_trap_push (screen->display); - XChangeProperty (screen->display->xdisplay, screen->xroot, - screen->display->atom__NET_CURRENT_DESKTOP, - XA_CARDINAL, - 32, PropModeReplace, (guchar*) data, 1); - meta_error_trap_pop (screen->display); -} - -LOCAL_SYMBOL void -meta_screen_update_snapped_windows (MetaScreen *screen) -{ - GList* tmp = screen->workspaces; - while (tmp) - { - MetaWorkspace* work = (MetaWorkspace*) tmp->data; - meta_workspace_update_snapped_windows (work); - tmp = tmp->next; - } -} - -static gboolean -check_fullscreen_func (gpointer data) -{ - MetaScreen *screen = data; - MetaWindow *window; - GSList *fullscreen_monitors = NULL; - GSList *obscured_monitors = NULL; - gboolean in_fullscreen_changed = FALSE; - int i; - - screen->check_fullscreen_later = 0; - - /* We consider a monitor in fullscreen if it contains a fullscreen window that - * is the current top-most window in that monitor. If any window (other than a - * dock/toolbar type) is above the fullscreen window, the monitor is no longer - * considered to be in fullscreen - */ - for (window = meta_stack_get_top (screen->stack); - window; - window = meta_stack_get_below (screen->stack, window, FALSE)) - { - gboolean covers_monitors = FALSE; - - if (window->screen != screen || window->hidden || window->xtransient_for) - continue; - - if (window->fullscreen) - { - covers_monitors = TRUE; - } - else if (window->override_redirect) - { - /* We want to handle the case where an application is creating an - * override-redirect window the size of the screen (monitor) and treat - * it similarly to a fullscreen window, though it doesn't have fullscreen - * window management behavior. (Being O-R, it's not managed at all.) - */ - if (meta_window_is_monitor_sized (window)) - covers_monitors = TRUE; - } - /* Any window type except dock/toolbar that comes before a fullscreen one - * will preempt fullscreen for that monitor. */ - else if (window->type != META_WINDOW_DOCK && - window->type != META_WINDOW_TOOLBAR) - { - int monitor_index = meta_window_get_monitor (window); - /* + 1 to avoid NULL */ - gpointer monitor_p = GINT_TO_POINTER(monitor_index + 1); - if (!g_slist_find (obscured_monitors, monitor_p)) - obscured_monitors = g_slist_prepend (obscured_monitors, monitor_p); - } - - if (covers_monitors) - { - int *monitors; - gsize n_monitors; - gsize j; - - monitors = meta_window_get_all_monitors (window, &n_monitors); - for (j = 0; j < n_monitors; j++) - { - /* + 1 to avoid NULL */ - gpointer monitor_p = GINT_TO_POINTER(monitors[j] + 1); - if (!g_slist_find (fullscreen_monitors, monitor_p) && - !g_slist_find (obscured_monitors, monitor_p)) - fullscreen_monitors = g_slist_prepend (fullscreen_monitors, monitor_p); - } - - free (monitors); - } - } - - g_slist_free (obscured_monitors); - - for (i = 0; i < screen->n_monitor_infos; i++) - { - MetaMonitorInfo *info = &screen->monitor_infos[i]; - gboolean in_fullscreen = g_slist_find (fullscreen_monitors, GINT_TO_POINTER (i + 1)) != NULL; - if (in_fullscreen != info->in_fullscreen) - { - info->in_fullscreen = in_fullscreen; - in_fullscreen_changed = TRUE; - } - } - - g_slist_free (fullscreen_monitors); - - if (in_fullscreen_changed) - { - /* DOCK window stacking depends on the monitor's fullscreen - status so we need to trigger a re-layering. */ - MetaWindow *top_window = meta_stack_get_top (screen->stack); - if (top_window) - meta_stack_update_layer (screen->stack, top_window); - - g_signal_emit (screen, screen_signals[IN_FULLSCREEN_CHANGED], 0, NULL); - } - - - return FALSE; -} - -void -meta_screen_queue_check_fullscreen (MetaScreen *screen) -{ - if (!screen->check_fullscreen_later) - screen->check_fullscreen_later = meta_later_add (META_LATER_CHECK_FULLSCREEN, - check_fullscreen_func, - screen, NULL); -} - -/** - * meta_screen_get_monitor_in_fullscreen: - * @screen: a #MetaScreen - * @monitor: the monitor number - * - * Determines whether there is a fullscreen window obscuring the specified - * monitor. If there is a fullscreen window, the desktop environment will - * typically hide any controls that might obscure the fullscreen window. - * - * You can get notification when this changes by connecting to - * MetaScreen::in-fullscreen-changed. - * - * Returns: %TRUE if there is a fullscreen window covering the specified monitor. - */ -gboolean -meta_screen_get_monitor_in_fullscreen (MetaScreen *screen, - int monitor) -{ - g_return_val_if_fail (META_IS_SCREEN (screen), FALSE); - g_return_val_if_fail (monitor >= 0 && monitor < screen->n_monitor_infos, FALSE); - - /* We use -1 as a flag to mean "not known yet" for notification purposes */ - return screen->monitor_infos[monitor].in_fullscreen == TRUE; -} diff --git a/src/core/stack-tracker.c b/src/core/stack-tracker.c index 2b52b64f2..a37760ec2 100644 --- a/src/core/stack-tracker.c +++ b/src/core/stack-tracker.c @@ -1,5 +1,20 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * SECTION:stack-tracker + * @short_description: Track stacking order for compositor + * + * #MetaStackTracker maintains the most accurate view we have at a + * given point of time of the ordering of the children of the root + * window (including override-redirect windows.) This is used to order + * the windows when the compositor draws them. + * + * By contrast, #MetaStack is responsible for keeping track of how we + * think that windows *should* be ordered. For windows we manage + * (non-override-redirect windows), the two stacking orders will be + * the same. + */ + /* * Copyright (C) 2009 Red Hat, Inc. * @@ -14,21 +29,21 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ -#include <config.h> +#include "config.h" -#include <string.h> +#include "core/stack-tracker.h" -#include "frame.h" -#include "screen-private.h" -#include "stack-tracker.h" -#include <meta/util.h> +#include <string.h> -#include <meta/compositor.h> +#include "core/display-private.h" +#include "core/frame.h" +#include "meta/compositor.h" +#include "meta/meta-x11-errors.h" +#include "meta/util.h" +#include "x11/meta-x11-display-private.h" /* The complexity here comes from resolving two competing factors: * @@ -66,13 +81,30 @@ typedef union _MetaStackOp MetaStackOp; -typedef enum { +typedef enum +{ STACK_OP_ADD, STACK_OP_REMOVE, STACK_OP_RAISE_ABOVE, STACK_OP_LOWER_BELOW } MetaStackOpType; +typedef enum +{ + APPLY_DEFAULT = 0, + /* Only do restacking that we can do locally without changing + * the order of X windows. After we've received any stack + * events from the X server, we apply the locally cached + * ops in this mode to handle the non-X parts */ + NO_RESTACK_X_WINDOWS = 1 << 0, + /* If the stacking operation wouldn't change the order of X + * windows, ignore it. We use this when applying events received + * from X so that a spontaneous ConfigureNotify (for a move, say) + * doesn't change the stacking of X windows with respect to + * Wayland windows. */ + IGNORE_NOOP_X_RESTACK = 1 << 1 +} ApplyFlags; + /* MetaStackOp represents a "stacking operation" - a change to * apply to a window stack. Depending on the context, it could * either reflect a request we have sent to the server, or a @@ -83,52 +115,53 @@ union _MetaStackOp struct { MetaStackOpType type; gulong serial; + guint64 window; } any; struct { MetaStackOpType type; gulong serial; - Window window; + guint64 window; } add; struct { MetaStackOpType type; gulong serial; - Window window; + guint64 window; } remove; struct { MetaStackOpType type; gulong serial; - Window window; - Window sibling; + guint64 window; + guint64 sibling; } raise_above; struct { MetaStackOpType type; gulong serial; - Window window; - Window sibling; + guint64 window; + guint64 sibling; } lower_below; }; struct _MetaStackTracker { - MetaScreen *screen; - - /* This is the last state of the stack as based on events received - * from the X server. - */ - GArray *server_stack; + MetaDisplay *display; /* This is the serial of the last request we made that was reflected - * in server_stack + * in xserver_stack */ - gulong server_serial; + gulong xserver_serial; + + /* A combined stack containing X and Wayland windows but without + * any unverified operations applied. */ + GArray *verified_stack; /* This is a queue of requests we've made to change the stacking order, * where we haven't yet gotten a reply back from the server. */ - GQueue *queued_requests; + GQueue *unverified_predictions; - /* This is how we think the stack is, based on server_stack, and - * on requests we've made subsequent to server_stack + /* This is how we think the stack is, based on verified_stack, and + * on the unverified_predictions we've made subsequent to + * verified_stack. */ GArray *predicted_stack; @@ -139,63 +172,101 @@ struct _MetaStackTracker }; static void -meta_stack_op_dump (MetaStackOp *op, - const char *prefix, - const char *suffix) +meta_stack_tracker_keep_override_redirect_on_top (MetaStackTracker *tracker); + +static inline const char * +get_window_desc (MetaStackTracker *tracker, + guint64 window) +{ + return meta_display_describe_stack_id (tracker->display, window); +} + +static void +meta_stack_op_dump (MetaStackTracker *tracker, + MetaStackOp *op, + const char *prefix, + const char *suffix) { +#ifdef WITH_VERBOSE_MODE + const char *window_desc = get_window_desc (tracker, op->any.window); +#endif + switch (op->any.type) { case STACK_OP_ADD: - meta_topic (META_DEBUG_STACK, "%sADD(%#lx; %ld)%s", - prefix, op->add.window, op->any.serial, suffix); + meta_topic (META_DEBUG_STACK, "%sADD(%s; %ld)%s", + prefix, window_desc, op->any.serial, suffix); break; case STACK_OP_REMOVE: - meta_topic (META_DEBUG_STACK, "%sREMOVE(%#lx; %ld)%s", - prefix, op->add.window, op->any.serial, suffix); + meta_topic (META_DEBUG_STACK, "%sREMOVE(%s; %ld)%s", + prefix, window_desc, op->any.serial, suffix); break; case STACK_OP_RAISE_ABOVE: - meta_topic (META_DEBUG_STACK, "%sRAISE_ABOVE(%#lx, %#lx; %ld)%s", - prefix, - op->raise_above.window, op->raise_above.sibling, - op->any.serial, - suffix); - break; + { + meta_topic (META_DEBUG_STACK, "%sRAISE_ABOVE(%s, %s; %ld)%s", + prefix, + window_desc, + get_window_desc (tracker, op->raise_above.sibling), + op->any.serial, + suffix); + break; + } case STACK_OP_LOWER_BELOW: - meta_topic (META_DEBUG_STACK, "%sLOWER_BELOW(%#lx, %#lx; %ld)%s", - prefix, - op->lower_below.window, op->lower_below.sibling, - op->any.serial, - suffix); - break; + { + meta_topic (META_DEBUG_STACK, "%sLOWER_BELOW(%s, %s; %ld)%s", + prefix, + window_desc, + get_window_desc (tracker, op->lower_below.sibling), + op->any.serial, + suffix); + break; + } } } +#ifdef WITH_VERBOSE_MODE static void -meta_stack_tracker_dump (MetaStackTracker *tracker) +stack_dump (MetaStackTracker *tracker, + GArray *stack) { guint i; - GList *l; - meta_topic (META_DEBUG_STACK, "MetaStackTracker state (screen=%d)\n", tracker->screen->number); meta_push_no_msg_prefix (); - meta_topic (META_DEBUG_STACK, " server_serial: %ld\n", tracker->server_serial); - meta_topic (META_DEBUG_STACK, " server_stack: "); - for (i = 0; i < tracker->server_stack->len; i++) - meta_topic (META_DEBUG_STACK, " %#lx", g_array_index (tracker->server_stack, Window, i)); - if (tracker->predicted_stack) + for (i = 0; i < stack->len; i++) { - meta_topic (META_DEBUG_STACK, "\n predicted_stack: "); - for (i = 0; i < tracker->predicted_stack->len; i++) - meta_topic (META_DEBUG_STACK, " %#lx", g_array_index (tracker->predicted_stack, Window, i)); + guint64 window = g_array_index (stack, guint64, i); + meta_topic (META_DEBUG_STACK, " %s", get_window_desc (tracker, window)); } - meta_topic (META_DEBUG_STACK, "\n queued_requests: ["); - for (l = tracker->queued_requests->head; l; l = l->next) + meta_topic (META_DEBUG_STACK, "\n"); + meta_pop_no_msg_prefix (); +} +#endif /* WITH_VERBOSE_MODE */ + +static void +meta_stack_tracker_dump (MetaStackTracker *tracker) +{ +#ifdef WITH_VERBOSE_MODE + GList *l; + + meta_topic (META_DEBUG_STACK, "MetaStackTracker state\n"); + meta_push_no_msg_prefix (); + meta_topic (META_DEBUG_STACK, " xserver_serial: %ld\n", tracker->xserver_serial); + meta_topic (META_DEBUG_STACK, " verified_stack: "); + stack_dump (tracker, tracker->verified_stack); + meta_topic (META_DEBUG_STACK, " unverified_predictions: ["); + for (l = tracker->unverified_predictions->head; l; l = l->next) { MetaStackOp *op = l->data; - meta_stack_op_dump (op, "", l->next ? ", " : ""); + meta_stack_op_dump (tracker, op, "", l->next ? ", " : ""); } meta_topic (META_DEBUG_STACK, "]\n"); + if (tracker->predicted_stack) + { + meta_topic (META_DEBUG_STACK, "\n predicted_stack: "); + stack_dump (tracker, tracker->predicted_stack); + } meta_pop_no_msg_prefix (); +#endif /* WITH_VERBOSE_MODE */ } static void @@ -205,44 +276,86 @@ meta_stack_op_free (MetaStackOp *op) } static int -find_window (GArray *stack, - Window window) +find_window (GArray *window_stack, + guint64 window) { guint i; - for (i = 0; i < stack->len; i++) - if (g_array_index (stack, Window, i) == window) - return i; + for (i = 0; i < window_stack->len; i++) + { + guint64 current = g_array_index (window_stack, guint64, i); + if (current == window) + return i; + } return -1; } /* Returns TRUE if stack was changed */ static gboolean -move_window_above (GArray *stack, - Window window, - int old_pos, - int above_pos) +move_window_above (GArray *stack, + guint64 window, + int old_pos, + int above_pos, + ApplyFlags apply_flags) { int i; + gboolean can_restack_this_window = + (apply_flags & NO_RESTACK_X_WINDOWS) == 0 || !META_STACK_ID_IS_X11 (window); if (old_pos < above_pos) { + if ((apply_flags & IGNORE_NOOP_X_RESTACK) != 0) + { + gboolean found_x_window = FALSE; + for (i = old_pos + 1; i <= above_pos; i++) + if (META_STACK_ID_IS_X11 (g_array_index (stack, guint64, i))) + found_x_window = TRUE; + + if (!found_x_window) + return FALSE; + } + for (i = old_pos; i < above_pos; i++) - g_array_index (stack, Window, i) = g_array_index (stack, Window, i + 1); + { + if (!can_restack_this_window && + META_STACK_ID_IS_X11 (g_array_index (stack, guint64, i + 1))) + break; - g_array_index (stack, Window, above_pos) = window; + g_array_index (stack, guint64, i) = + g_array_index (stack, guint64, i + 1); + } + + g_array_index (stack, guint64, i) = window; - return TRUE; + return i != old_pos; } else if (old_pos > above_pos + 1) { + if ((apply_flags & IGNORE_NOOP_X_RESTACK) != 0) + { + gboolean found_x_window = FALSE; + for (i = above_pos + 1; i < old_pos; i++) + if (META_STACK_ID_IS_X11 (g_array_index (stack, guint64, i))) + found_x_window = TRUE; + + if (!found_x_window) + return FALSE; + } + for (i = old_pos; i > above_pos + 1; i--) - g_array_index (stack, Window, i) = g_array_index (stack, Window, i - 1); + { + if (!can_restack_this_window && + META_STACK_ID_IS_X11 (g_array_index (stack, guint64, i - 1))) + break; + + g_array_index (stack, guint64, i) = + g_array_index (stack, guint64, i - 1); + } - g_array_index (stack, Window, above_pos + 1) = window; + g_array_index (stack, guint64, i) = window; - return TRUE; + return i != old_pos; } else return FALSE; @@ -250,18 +363,24 @@ move_window_above (GArray *stack, /* Returns TRUE if stack was changed */ static gboolean -meta_stack_op_apply (MetaStackOp *op, - GArray *stack) +meta_stack_op_apply (MetaStackTracker *tracker, + MetaStackOp *op, + GArray *stack, + ApplyFlags apply_flags) { switch (op->any.type) { case STACK_OP_ADD: { + if (META_STACK_ID_IS_X11 (op->add.window) && + (apply_flags & NO_RESTACK_X_WINDOWS) != 0) + return FALSE; + int old_pos = find_window (stack, op->add.window); if (old_pos >= 0) { - g_warning ("STACK_OP_ADD: window %#lx already in stack", - op->add.window); + g_warning ("STACK_OP_ADD: window %s already in stack", + get_window_desc (tracker, op->add.window)); return FALSE; } @@ -270,11 +389,15 @@ meta_stack_op_apply (MetaStackOp *op, } case STACK_OP_REMOVE: { + if (META_STACK_ID_IS_X11 (op->remove.window) && + (apply_flags & NO_RESTACK_X_WINDOWS) != 0) + return FALSE; + int old_pos = find_window (stack, op->remove.window); if (old_pos < 0) { - g_warning ("STACK_OP_REMOVE: window %#lx not in stack", - op->remove.window); + g_warning ("STACK_OP_REMOVE: window %s not in stack", + get_window_desc (tracker, op->remove.window)); return FALSE; } @@ -287,18 +410,18 @@ meta_stack_op_apply (MetaStackOp *op, int above_pos; if (old_pos < 0) { - g_warning ("STACK_OP_RAISE_ABOVE: window %#lx not in stack", - op->raise_above.window); + g_warning ("STACK_OP_RAISE_ABOVE: window %s not in stack", + get_window_desc (tracker, op->raise_above.window)); return FALSE; } - if (op->raise_above.sibling != None) + if (op->raise_above.sibling) { above_pos = find_window (stack, op->raise_above.sibling); if (above_pos < 0) { - g_warning ("STACK_OP_RAISE_ABOVE: sibling window %#lx not in stack", - op->raise_above.sibling); + g_warning ("STACK_OP_RAISE_ABOVE: sibling window %s not in stack", + get_window_desc (tracker, op->raise_above.sibling)); return FALSE; } } @@ -307,7 +430,8 @@ meta_stack_op_apply (MetaStackOp *op, above_pos = -1; } - return move_window_above (stack, op->raise_above.window, old_pos, above_pos); + return move_window_above (stack, op->raise_above.window, old_pos, above_pos, + apply_flags); } case STACK_OP_LOWER_BELOW: { @@ -315,18 +439,18 @@ meta_stack_op_apply (MetaStackOp *op, int above_pos; if (old_pos < 0) { - g_warning ("STACK_OP_LOWER_BELOW: window %#lx not in stack", - op->lower_below.window); + g_warning ("STACK_OP_LOWER_BELOW: window %s not in stack", + get_window_desc (tracker, op->lower_below.window)); return FALSE; } - if (op->lower_below.sibling != None) + if (op->lower_below.sibling) { int below_pos = find_window (stack, op->lower_below.sibling); if (below_pos < 0) { - g_warning ("STACK_OP_LOWER_BELOW: sibling window %#lx not in stack", - op->lower_below.sibling); + g_warning ("STACK_OP_LOWER_BELOW: sibling window %s not in stack", + get_window_desc (tracker, op->lower_below.sibling)); return FALSE; } @@ -337,7 +461,8 @@ meta_stack_op_apply (MetaStackOp *op, above_pos = stack->len - 1; } - return move_window_above (stack, op->lower_below.window, old_pos, above_pos); + return move_window_above (stack, op->lower_below.window, old_pos, above_pos, + apply_flags); } } @@ -346,161 +471,220 @@ meta_stack_op_apply (MetaStackOp *op, } static GArray * -copy_stack (Window *windows, - guint n_windows) +copy_stack (GArray *stack) { - GArray *stack = g_array_new (FALSE, FALSE, sizeof (Window)); + GArray *copy = g_array_sized_new (FALSE, FALSE, sizeof (guint64), stack->len); - g_array_set_size (stack, n_windows); - memcpy (stack->data, windows, sizeof (Window) * n_windows); + g_array_set_size (copy, stack->len); - return stack; + memcpy (copy->data, stack->data, sizeof (guint64) * stack->len); + + return copy; } -LOCAL_SYMBOL MetaStackTracker * -meta_stack_tracker_new (MetaScreen *screen) +static void +query_xserver_stack (MetaDisplay *display, + MetaStackTracker *tracker) { - MetaStackTracker *tracker; + MetaX11Display *x11_display = display->x11_display; Window ignored1, ignored2; Window *children; guint n_children; + guint i, old_len; - tracker = g_new0 (MetaStackTracker, 1); - tracker->screen = screen; - - tracker->server_serial = XNextRequest (screen->display->xdisplay); + tracker->xserver_serial = XNextRequest (x11_display->xdisplay); - XQueryTree (screen->display->xdisplay, - screen->xroot, + XQueryTree (x11_display->xdisplay, + x11_display->xroot, &ignored1, &ignored2, &children, &n_children); - tracker->server_stack = copy_stack (children, n_children); + + old_len = tracker->verified_stack->len; + + g_array_set_size (tracker->verified_stack, old_len + n_children); + + for (i = 0; i < n_children; i++) + g_array_index (tracker->verified_stack, guint64, old_len + i) = children[i]; + XFree (children); +} + +static void +drop_x11_windows (MetaDisplay *display, + MetaStackTracker *tracker) +{ + GArray *new_stack; + GList *l; + int i; + + tracker->xserver_serial = 0; + + new_stack = g_array_new (FALSE, FALSE, sizeof (guint64)); + + for (i = 0; i < tracker->verified_stack->len; i++) + { + guint64 window = g_array_index (tracker->verified_stack, guint64, i); + + if (!META_STACK_ID_IS_X11 (window)) + g_array_append_val (new_stack, window); + } + + g_array_unref (tracker->verified_stack); + tracker->verified_stack = new_stack; + l = tracker->unverified_predictions->head; + + while (l) + { + MetaStackOp *op = l->data; + GList *next = l->next; + + if (META_STACK_ID_IS_X11 (op->any.window)) + g_queue_remove (tracker->unverified_predictions, op); - tracker->queued_requests = g_queue_new (); + l = next; + } +} + +MetaStackTracker * +meta_stack_tracker_new (MetaDisplay *display) +{ + MetaStackTracker *tracker; + + tracker = g_new0 (MetaStackTracker, 1); + tracker->display = display; + + tracker->verified_stack = g_array_new (FALSE, FALSE, sizeof (guint64)); + tracker->unverified_predictions = g_queue_new (); + + g_signal_connect (display, + "x11-display-setup", + G_CALLBACK (query_xserver_stack), + tracker); + g_signal_connect (display, + "x11-display-closing", + G_CALLBACK (drop_x11_windows), + tracker); + + meta_stack_tracker_dump (tracker); return tracker; } -LOCAL_SYMBOL void +void meta_stack_tracker_free (MetaStackTracker *tracker) { if (tracker->sync_stack_later) meta_later_remove (tracker->sync_stack_later); - g_array_free (tracker->server_stack, TRUE); + g_array_free (tracker->verified_stack, TRUE); if (tracker->predicted_stack) g_array_free (tracker->predicted_stack, TRUE); - g_queue_foreach (tracker->queued_requests, (GFunc)meta_stack_op_free, NULL); - g_queue_free (tracker->queued_requests); - tracker->queued_requests = NULL; + g_queue_foreach (tracker->unverified_predictions, (GFunc)meta_stack_op_free, NULL); + g_queue_free (tracker->unverified_predictions); + tracker->unverified_predictions = NULL; + + g_signal_handlers_disconnect_by_func (tracker->display, + (gpointer)query_xserver_stack, + tracker); + g_signal_handlers_disconnect_by_func (tracker->display, + drop_x11_windows, + tracker); - free (tracker); + g_free (tracker); } static void -stack_tracker_queue_request (MetaStackTracker *tracker, - MetaStackOp *op) +stack_tracker_apply_prediction (MetaStackTracker *tracker, + MetaStackOp *op) { - meta_stack_op_dump (op, "Queueing: ", "\n"); - g_queue_push_tail (tracker->queued_requests, op); + gboolean free_at_end = FALSE; + + /* If this operation doesn't involve restacking X windows then it's + * implicitly verified. We can apply it immediately unless there + * are outstanding X restacks that haven't yet been confirmed. + */ + if (op->any.serial == 0 && + tracker->unverified_predictions->length == 0) + { + if (meta_stack_op_apply (tracker, op, tracker->verified_stack, APPLY_DEFAULT)) + meta_stack_tracker_queue_sync_stack (tracker); + + free_at_end = TRUE; + } + else + { + meta_stack_op_dump (tracker, op, "Predicting: ", "\n"); + g_queue_push_tail (tracker->unverified_predictions, op); + } + if (!tracker->predicted_stack || - meta_stack_op_apply (op, tracker->predicted_stack)) + meta_stack_op_apply (tracker, op, tracker->predicted_stack, APPLY_DEFAULT)) meta_stack_tracker_queue_sync_stack (tracker); + if (free_at_end) + meta_stack_op_free (op); + meta_stack_tracker_dump (tracker); } -LOCAL_SYMBOL void +void meta_stack_tracker_record_add (MetaStackTracker *tracker, - Window window, + guint64 window, gulong serial) { MetaStackOp *op = g_slice_new (MetaStackOp); op->any.type = STACK_OP_ADD; op->any.serial = serial; - op->add.window = window; + op->any.window = window; - stack_tracker_queue_request (tracker, op); + stack_tracker_apply_prediction (tracker, op); } -LOCAL_SYMBOL void +void meta_stack_tracker_record_remove (MetaStackTracker *tracker, - Window window, + guint64 window, gulong serial) { MetaStackOp *op = g_slice_new (MetaStackOp); op->any.type = STACK_OP_REMOVE; op->any.serial = serial; - op->remove.window = window; + op->any.window = window; - stack_tracker_queue_request (tracker, op); + stack_tracker_apply_prediction (tracker, op); } -LOCAL_SYMBOL void -meta_stack_tracker_record_restack_windows (MetaStackTracker *tracker, - Window *windows, - int n_windows, - gulong serial) -{ - int i; - - /* XRestackWindows() isn't actually a X requests - it's broken down - * by XLib into a series of XConfigureWindow(StackMode=below); we - * mirror that exactly here. - * - * Aside: Having a separate StackOp for this would be possible to - * get some extra efficiency in memory allocation and in applying - * the op, at the expense of a code complexity. Implementation hint - * for that - keep op->restack_window.n_complete, and when receiving - * events with intermediate serials, set n_complete rather than - * removing the op from the queue. - */ - for (i = 0; i < n_windows - 1; i++) - meta_stack_tracker_record_lower_below (tracker, windows[i + 1], windows[i], - serial + i); -} - -LOCAL_SYMBOL void +static void meta_stack_tracker_record_raise_above (MetaStackTracker *tracker, - Window window, - Window sibling, + guint64 window, + guint64 sibling, gulong serial) { MetaStackOp *op = g_slice_new (MetaStackOp); op->any.type = STACK_OP_RAISE_ABOVE; op->any.serial = serial; - op->raise_above.window = window; + op->any.window = window; op->raise_above.sibling = sibling; - stack_tracker_queue_request (tracker, op); + stack_tracker_apply_prediction (tracker, op); } -LOCAL_SYMBOL LOCAL_SYMBOL void +static void meta_stack_tracker_record_lower_below (MetaStackTracker *tracker, - Window window, - Window sibling, + guint64 window, + guint64 sibling, gulong serial) { MetaStackOp *op = g_slice_new (MetaStackOp); op->any.type = STACK_OP_LOWER_BELOW; op->any.serial = serial; - op->lower_below.window = window; + op->any.window = window; op->lower_below.sibling = sibling; - stack_tracker_queue_request (tracker, op); -} - -LOCAL_SYMBOL void -meta_stack_tracker_record_lower (MetaStackTracker *tracker, - Window window, - gulong serial) -{ - meta_stack_tracker_record_raise_above (tracker, window, None, serial); + stack_tracker_apply_prediction (tracker, op); } static void @@ -509,23 +693,57 @@ stack_tracker_event_received (MetaStackTracker *tracker, { gboolean need_sync = FALSE; - meta_stack_op_dump (op, "Stack op event received: ", "\n"); - - if (op->any.serial < tracker->server_serial) + /* If the event is older than our initial query, then it's + * already included in our tree. Just ignore it. */ + if (op->any.serial < tracker->xserver_serial) return; - tracker->server_serial = op->any.serial; + meta_stack_op_dump (tracker, op, "Stack op event received: ", "\n"); + + /* First we apply any operations that we have queued up that depended + * on X operations *older* than what we received .. those operations + * must have been ignored by the X server, so we just apply the + * operations we have as best as possible while not moving windows. + */ + while (tracker->unverified_predictions->head) + { + MetaStackOp *queued_op = tracker->unverified_predictions->head->data; + + if (queued_op->any.serial >= op->any.serial) + break; + + meta_stack_op_apply (tracker, queued_op, tracker->verified_stack, + NO_RESTACK_X_WINDOWS); + + g_queue_pop_head (tracker->unverified_predictions); + meta_stack_op_free (queued_op); + need_sync = TRUE; + } - if (meta_stack_op_apply (op, tracker->server_stack)) + /* Then we apply the received event. If it's a spontaneous event + * based on stacking we didn't trigger, this is the only handling. If we + * triggered it, we do the X restacking here, and then any residual + * local-only Wayland stacking below. + */ + if (meta_stack_op_apply (tracker, op, tracker->verified_stack, + IGNORE_NOOP_X_RESTACK)) need_sync = TRUE; - while (tracker->queued_requests->head) + /* What is left to process is the prediction corresponding to the event + * (if any), and then any subsequent Wayland-only events we can just + * go ahead and do now. + */ + while (tracker->unverified_predictions->head) { - MetaStackOp *queued_op = tracker->queued_requests->head->data; + MetaStackOp *queued_op = tracker->unverified_predictions->head->data; + if (queued_op->any.serial > op->any.serial) break; - g_queue_pop_head (tracker->queued_requests); + meta_stack_op_apply (tracker, queued_op, tracker->verified_stack, + NO_RESTACK_X_WINDOWS); + + g_queue_pop_head (tracker->unverified_predictions); meta_stack_op_free (queued_op); need_sync = TRUE; } @@ -544,7 +762,7 @@ stack_tracker_event_received (MetaStackTracker *tracker, meta_stack_tracker_dump (tracker); } -LOCAL_SYMBOL void +void meta_stack_tracker_create_event (MetaStackTracker *tracker, XCreateWindowEvent *event) { @@ -557,7 +775,7 @@ meta_stack_tracker_create_event (MetaStackTracker *tracker, stack_tracker_event_received (tracker, &op); } -LOCAL_SYMBOL void +void meta_stack_tracker_destroy_event (MetaStackTracker *tracker, XDestroyWindowEvent *event) { @@ -570,7 +788,7 @@ meta_stack_tracker_destroy_event (MetaStackTracker *tracker, stack_tracker_event_received (tracker, &op); } -LOCAL_SYMBOL void +void meta_stack_tracker_reparent_event (MetaStackTracker *tracker, XReparentEvent *event) { @@ -596,7 +814,7 @@ meta_stack_tracker_reparent_event (MetaStackTracker *tracker, } } -LOCAL_SYMBOL void +void meta_stack_tracker_configure_event (MetaStackTracker *tracker, XConfigureEvent *event) { @@ -610,13 +828,25 @@ meta_stack_tracker_configure_event (MetaStackTracker *tracker, stack_tracker_event_received (tracker, &op); } +static gboolean +meta_stack_tracker_is_guard_window (MetaStackTracker *tracker, + uint64_t stack_id) +{ + MetaX11Display *x11_display = tracker->display->x11_display; + + if (!x11_display) + return FALSE; + + return stack_id == x11_display->guard_window; +} + /** * meta_stack_tracker_get_stack: * @tracker: a #MetaStackTracker * @windows: location to store list of windows, or %NULL * @n_windows: location to store count of windows, or %NULL * - * Returns the most current view we have of the stacking order + * @windows will contain the most current view we have of the stacking order * of the children of the root window. The returned array contains * everything: InputOnly windows, override-redirect windows, * hidden windows, etc. Some of these will correspond to MetaWindow @@ -627,16 +857,16 @@ meta_stack_tracker_configure_event (MetaStackTracker *tracker, * returned list of windows is exactly that you'd get as the * children when calling XQueryTree() on the root window. */ -LOCAL_SYMBOL void +void meta_stack_tracker_get_stack (MetaStackTracker *tracker, - Window **windows, + guint64 **windows, int *n_windows) { GArray *stack; - if (tracker->queued_requests->length == 0) + if (tracker->unverified_predictions->length == 0) { - stack = tracker->server_stack; + stack = tracker->verified_stack; } else { @@ -644,12 +874,11 @@ meta_stack_tracker_get_stack (MetaStackTracker *tracker, { GList *l; - tracker->predicted_stack = copy_stack ((Window *)tracker->server_stack->data, - tracker->server_stack->len); - for (l = tracker->queued_requests->head; l; l = l->next) + tracker->predicted_stack = copy_stack (tracker->verified_stack); + for (l = tracker->unverified_predictions->head; l; l = l->next) { MetaStackOp *op = l->data; - meta_stack_op_apply (op, tracker->predicted_stack); + meta_stack_op_apply (tracker, op, tracker->predicted_stack, APPLY_DEFAULT); } } @@ -657,7 +886,7 @@ meta_stack_tracker_get_stack (MetaStackTracker *tracker, } if (windows) - *windows = (Window *)stack->data; + *windows = (guint64 *)stack->data; if (n_windows) *n_windows = stack->len; } @@ -669,11 +898,11 @@ meta_stack_tracker_get_stack (MetaStackTracker *tracker, * Informs the compositor of the current stacking order of windows, * based on the predicted view maintained by the #MetaStackTracker. */ -LOCAL_SYMBOL void +void meta_stack_tracker_sync_stack (MetaStackTracker *tracker) { + guint64 *windows; GList *meta_windows; - Window *windows; int n_windows; int i; @@ -683,34 +912,44 @@ meta_stack_tracker_sync_stack (MetaStackTracker *tracker) tracker->sync_stack_later = 0; } + meta_stack_tracker_keep_override_redirect_on_top (tracker); + meta_stack_tracker_get_stack (tracker, &windows, &n_windows); meta_windows = NULL; for (i = 0; i < n_windows; i++) { - MetaWindow *meta_window; - - meta_window = meta_display_lookup_x_window (tracker->screen->display, - windows[i]); - /* When mapping back from xwindow to MetaWindow we have to be a bit careful; - * children of the root could include unmapped windows created by toolkits - * for internal purposes, including ones that we have registered in our - * XID => window table. (Wine uses a toplevel for _NET_WM_USER_TIME_WINDOW; - * see window-prop.c:reload_net_wm_user_time_window() for registration.) - */ - if (meta_window && - (windows[i] == meta_window->xwindow || - (meta_window->frame && windows[i] == meta_window->frame->xwindow))) - meta_windows = g_list_prepend (meta_windows, meta_window); - } - - if (tracker->screen->display->compositor) - meta_compositor_sync_stack (tracker->screen->display->compositor, - tracker->screen, - meta_windows); + guint64 window = windows[i]; + + if (META_STACK_ID_IS_X11 (window)) + { + MetaX11Display *x11_display = tracker->display->x11_display; + MetaWindow *meta_window = NULL; + + if (x11_display) + meta_window = meta_x11_display_lookup_x_window (x11_display, (Window) window); + + /* When mapping back from xwindow to MetaWindow we have to be a bit careful; + * children of the root could include unmapped windows created by toolkits + * for internal purposes, including ones that we have registered in our + * XID => window table. (Wine uses a toplevel for _NET_WM_USER_TIME_WINDOW; + * see window-prop.c:reload_net_wm_user_time_window() for registration.) + */ + if (meta_window && + ((Window)window == meta_window->xwindow || + (meta_window->frame && (Window)window == meta_window->frame->xwindow))) + meta_windows = g_list_prepend (meta_windows, meta_window); + } + else + meta_windows = g_list_prepend (meta_windows, + meta_display_lookup_stamp (tracker->display, window)); + } + + meta_compositor_sync_stack (tracker->display->compositor, + meta_windows); g_list_free (meta_windows); - meta_screen_restacked (tracker->screen); + meta_display_restacked (tracker->display); } static gboolean @@ -734,7 +973,7 @@ stack_tracker_sync_stack_later (gpointer data) * any change to the stacking order of the X windows, if we are creating * or destroying MetaWindows. */ -LOCAL_SYMBOL void +void meta_stack_tracker_queue_sync_stack (MetaStackTracker *tracker) { if (tracker->sync_stack_later == 0) @@ -745,3 +984,279 @@ meta_stack_tracker_queue_sync_stack (MetaStackTracker *tracker) } } +/* When moving an X window we sometimes need an X based sibling. + * + * If the given sibling is X based this function returns it back + * otherwise it searches downwards looking for the nearest X window. + * + * If no X based sibling could be found return NULL. */ +static Window +find_x11_sibling_downwards (MetaStackTracker *tracker, + guint64 sibling) +{ + guint64 *windows; + int n_windows; + int i; + + if (META_STACK_ID_IS_X11 (sibling)) + return (Window)sibling; + + meta_stack_tracker_get_stack (tracker, + &windows, &n_windows); + + /* NB: Children are in order from bottom to top and we + * want to search downwards for the nearest X window. + */ + + for (i = n_windows - 1; i >= 0; i--) + if (windows[i] == sibling) + break; + + for (; i >= 0; i--) + { + if (META_STACK_ID_IS_X11 (windows[i])) + return (Window)windows[i]; + } + + return None; +} + +static Window +find_x11_sibling_upwards (MetaStackTracker *tracker, + guint64 sibling) +{ + guint64 *windows; + int n_windows; + int i; + + if (META_STACK_ID_IS_X11 (sibling)) + return (Window)sibling; + + meta_stack_tracker_get_stack (tracker, + &windows, &n_windows); + + for (i = 0; i < n_windows; i++) + if (windows[i] == sibling) + break; + + for (; i < n_windows; i++) + { + if (META_STACK_ID_IS_X11 (windows[i])) + return (Window)windows[i]; + } + + return None; +} + +static void +meta_stack_tracker_lower_below (MetaStackTracker *tracker, + guint64 window, + guint64 sibling) +{ + gulong serial = 0; + MetaX11Display *x11_display = tracker->display->x11_display; + + if (META_STACK_ID_IS_X11 (window)) + { + XWindowChanges changes; + changes.sibling = sibling ? find_x11_sibling_upwards (tracker, sibling) : None; + + if (changes.sibling != find_x11_sibling_upwards (tracker, window)) + { + serial = XNextRequest (x11_display->xdisplay); + + meta_x11_error_trap_push (x11_display); + + changes.stack_mode = changes.sibling ? Below : Above; + + XConfigureWindow (x11_display->xdisplay, + window, + (changes.sibling ? CWSibling : 0) | CWStackMode, + &changes); + + meta_x11_error_trap_pop (x11_display); + } + } + + meta_stack_tracker_record_lower_below (tracker, + window, sibling, + serial); +} + +static void +meta_stack_tracker_raise_above (MetaStackTracker *tracker, + guint64 window, + guint64 sibling) +{ + gulong serial = 0; + MetaX11Display *x11_display = tracker->display->x11_display; + + if (META_STACK_ID_IS_X11 (window)) + { + XWindowChanges changes; + changes.sibling = sibling ? find_x11_sibling_downwards (tracker, sibling) : None; + + if (changes.sibling != find_x11_sibling_downwards (tracker, window)) + { + serial = XNextRequest (x11_display->xdisplay); + + meta_x11_error_trap_push (x11_display); + + changes.stack_mode = changes.sibling ? Above : Below; + + XConfigureWindow (x11_display->xdisplay, + (Window)window, + (changes.sibling ? CWSibling : 0) | CWStackMode, + &changes); + + meta_x11_error_trap_pop (x11_display); + } + } + + meta_stack_tracker_record_raise_above (tracker, window, + sibling, serial); +} + +void +meta_stack_tracker_lower (MetaStackTracker *tracker, + guint64 window) +{ + meta_stack_tracker_raise_above (tracker, window, None); +} + +static void +meta_stack_tracker_keep_override_redirect_on_top (MetaStackTracker *tracker) +{ + guint64 *stack; + int n_windows, i; + int topmost_non_or; + + meta_stack_tracker_get_stack (tracker, &stack, &n_windows); + + for (i = n_windows - 1; i >= 0; i--) + { + MetaWindow *window; + + window = meta_display_lookup_stack_id (tracker->display, stack[i]); + if (window && window->layer != META_LAYER_OVERRIDE_REDIRECT) + break; + } + + topmost_non_or = i; + + for (i -= 1; i >= 0; i--) + { + MetaWindow *window; + + if (meta_stack_tracker_is_guard_window (tracker, stack[i])) + break; + + window = meta_display_lookup_stack_id (tracker->display, stack[i]); + if (window && window->layer == META_LAYER_OVERRIDE_REDIRECT) + { + meta_stack_tracker_raise_above (tracker, stack[i], stack[topmost_non_or]); + meta_stack_tracker_get_stack (tracker, &stack, &n_windows); + topmost_non_or -= 1; + } + } +} + +void +meta_stack_tracker_restack_managed (MetaStackTracker *tracker, + const guint64 *managed, + int n_managed) +{ + guint64 *windows; + int n_windows; + int old_pos, new_pos; + + if (n_managed == 0) + return; + + meta_stack_tracker_get_stack (tracker, &windows, &n_windows); + + /* If the top window has to be restacked, we don't want to move it to the very + * top of the stack, since apps expect override-redirect windows to stay near + * the top of the X stack; we instead move it above all managed windows (or + * above the guard window if there are no non-hidden managed windows.) + */ + old_pos = n_windows - 1; + for (old_pos = n_windows - 1; old_pos >= 0; old_pos--) + { + MetaWindow *old_window = meta_display_lookup_stack_id (tracker->display, windows[old_pos]); + if ((old_window && !old_window->override_redirect && !old_window->unmanaging) || + meta_stack_tracker_is_guard_window (tracker, windows[old_pos])) + break; + } + g_assert (old_pos >= 0); + + new_pos = n_managed - 1; + if (managed[new_pos] != windows[old_pos]) + { + /* Move the first managed window in the new stack above all managed windows */ + meta_stack_tracker_raise_above (tracker, managed[new_pos], windows[old_pos]); + meta_stack_tracker_get_stack (tracker, &windows, &n_windows); + /* Moving managed[new_pos] above windows[old_pos], moves the window at old_pos down by one */ + } + + old_pos--; + new_pos--; + + while (old_pos >= 0 && new_pos >= 0) + { + if (meta_stack_tracker_is_guard_window (tracker, windows[old_pos])) + break; + + if (windows[old_pos] == managed[new_pos]) + { + old_pos--; + new_pos--; + continue; + } + + MetaWindow *old_window = meta_display_lookup_stack_id (tracker->display, windows[old_pos]); + if (!old_window || old_window->override_redirect || old_window->unmanaging) + { + old_pos--; + continue; + } + + meta_stack_tracker_lower_below (tracker, managed[new_pos], managed[new_pos + 1]); + meta_stack_tracker_get_stack (tracker, &windows, &n_windows); + /* Moving managed[new_pos] above windows[old_pos] moves the window at old_pos down by one, + * we'll examine it again to see if it matches the next new window */ + old_pos--; + new_pos--; + } + + while (new_pos > 0) + { + meta_stack_tracker_lower_below (tracker, managed[new_pos], managed[new_pos - 1]); + new_pos--; + } +} + +void +meta_stack_tracker_restack_at_bottom (MetaStackTracker *tracker, + const guint64 *new_order, + int n_new_order) +{ + guint64 *windows; + int n_windows; + int pos; + + meta_stack_tracker_get_stack (tracker, &windows, &n_windows); + + for (pos = 0; pos < n_new_order; pos++) + { + if (pos >= n_windows || windows[pos] != new_order[pos]) + { + if (pos == 0) + meta_stack_tracker_lower (tracker, new_order[pos]); + else + meta_stack_tracker_raise_above (tracker, new_order[pos], new_order[pos - 1]); + + meta_stack_tracker_get_stack (tracker, &windows, &n_windows); + } + } +} diff --git a/src/core/stack-tracker.h b/src/core/stack-tracker.h index dc7687872..dbffb0e5e 100644 --- a/src/core/stack-tracker.h +++ b/src/core/stack-tracker.h @@ -28,46 +28,43 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_STACK_TRACKER_H #define META_STACK_TRACKER_H -#include <meta/screen.h> +#include "core/util-private.h" +#include "meta/display.h" +#include "meta/window.h" typedef struct _MetaStackTracker MetaStackTracker; -MetaStackTracker *meta_stack_tracker_new (MetaScreen *screen); +MetaStackTracker *meta_stack_tracker_new (MetaDisplay *display); void meta_stack_tracker_free (MetaStackTracker *tracker); /* These functions are called when we make an X call that changes the * stacking order; this allows MetaStackTracker to predict stacking * order before it receives events back from the X server */ void meta_stack_tracker_record_add (MetaStackTracker *tracker, - Window window, + guint64 window, gulong serial); void meta_stack_tracker_record_remove (MetaStackTracker *tracker, - Window window, - gulong serial); -void meta_stack_tracker_record_restack_windows (MetaStackTracker *tracker, - Window *windows, - int n_windows, - gulong serial); -void meta_stack_tracker_record_raise_above (MetaStackTracker *tracker, - Window window, - Window sibling, - gulong serial); -void meta_stack_tracker_record_lower_below (MetaStackTracker *tracker, - Window window, - Window sibling, - gulong serial); -void meta_stack_tracker_record_lower (MetaStackTracker *tracker, - Window window, + guint64 window, gulong serial); +/* We also have functions that also go ahead and do the work + */ +void meta_stack_tracker_lower (MetaStackTracker *tracker, + guint64 window); + +void meta_stack_tracker_restack_managed (MetaStackTracker *tracker, + const guint64 *windows, + int n_windows); +void meta_stack_tracker_restack_at_bottom (MetaStackTracker *tracker, + const guint64 *new_order, + int n_new_order); + /* These functions are used to update the stack when we get events * reflecting changes to the stacking order */ void meta_stack_tracker_create_event (MetaStackTracker *tracker, @@ -79,9 +76,10 @@ void meta_stack_tracker_reparent_event (MetaStackTracker *tracker, void meta_stack_tracker_configure_event (MetaStackTracker *tracker, XConfigureEvent *event); -void meta_stack_tracker_get_stack (MetaStackTracker *tracker, - Window **windows, - int *n_windows); +META_EXPORT_TEST +void meta_stack_tracker_get_stack (MetaStackTracker *tracker, + guint64 **windows, + int *n_entries); void meta_stack_tracker_sync_stack (MetaStackTracker *tracker); void meta_stack_tracker_queue_sync_stack (MetaStackTracker *tracker); diff --git a/src/core/stack.c b/src/core/stack.c index 49ff24b4d..f7e0f1b90 100644 --- a/src/core/stack.c +++ b/src/core/stack.c @@ -1,6 +1,6 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/** +/* * SECTION:stack * @short_description: Which windows cover which other windows */ @@ -22,98 +22,270 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ -#include <config.h> -#include "stack.h" -#include "window-private.h" -#include <meta/errors.h> -#include "frame.h" -#include <meta/group.h> -#include <meta/prefs.h> -#include <meta/workspace.h> +#include "config.h" -#include <X11/Xatom.h> +#include "core/stack.h" -#define WINDOW_HAS_TRANSIENT_TYPE(w) \ - (w->type == META_WINDOW_DIALOG || \ - w->type == META_WINDOW_MODAL_DIALOG || \ - w->type == META_WINDOW_TOOLBAR || \ - w->type == META_WINDOW_MENU || \ - w->type == META_WINDOW_UTILITY) +#include "backends/meta-logical-monitor.h" +#include "cogl/cogl.h" +#include "core/frame.h" +#include "core/main-private.h" +#include "core/meta-workspace-manager-private.h" +#include "core/window-private.h" +#include "meta/group.h" +#include "meta/prefs.h" +#include "meta/workspace.h" +#include "x11/meta-x11-display-private.h" -#define WINDOW_TRANSIENT_FOR_WHOLE_GROUP(w) \ - ((w->xtransient_for == None || \ - w->transient_parent_is_root_window) && \ - WINDOW_HAS_TRANSIENT_TYPE (w)) +#define WINDOW_TRANSIENT_FOR_WHOLE_GROUP(w) \ + (meta_window_has_transient_type (w) && w->transient_for == NULL) -#define WINDOW_IN_STACK(w) (w->stack_position >= 0) - -static void stack_sync_to_server (MetaStack *stack); static void meta_window_set_stack_position_no_sync (MetaWindow *window, int position); -static void stack_do_window_deletions (MetaStack *stack); -static void stack_do_window_additions (MetaStack *stack); -static void stack_do_relayer (MetaStack *stack); -static void stack_do_constrain (MetaStack *stack); -static void stack_do_resort (MetaStack *stack); - +static void stack_do_relayer (MetaStack *stack); +static void stack_do_constrain (MetaStack *stack); +static void stack_do_resort (MetaStack *stack); static void stack_ensure_sorted (MetaStack *stack); -LOCAL_SYMBOL MetaStack* -meta_stack_new (MetaScreen *screen) +enum { - MetaStack *stack; + PROP_DISPLAY = 1, + N_PROPS +}; - stack = g_new (MetaStack, 1); +enum +{ + CHANGED, + WINDOW_ADDED, + WINDOW_REMOVED, + N_SIGNALS +}; - stack->screen = screen; - stack->windows = g_array_new (FALSE, FALSE, sizeof (Window)); +static GParamSpec *pspecs[N_PROPS] = { 0 }; +static guint signals[N_SIGNALS] = { 0 }; - stack->sorted = NULL; - stack->added = NULL; - stack->removed = NULL; +G_DEFINE_TYPE (MetaStack, meta_stack, G_TYPE_OBJECT) - stack->freeze_count = 0; - stack->last_root_children_stacked = NULL; +static void +on_stack_changed (MetaStack *stack) +{ + MetaDisplay *display = stack->display; + GArray *all_root_children_stacked; + GList *l; + GArray *hidden_stack_ids; + GList *sorted; - stack->n_positions = 0; + meta_topic (META_DEBUG_STACK, "Syncing window stack to server\n"); - stack->need_resort = FALSE; - stack->need_relayer = FALSE; - stack->need_constrain = FALSE; + all_root_children_stacked = g_array_new (FALSE, FALSE, sizeof (uint64_t)); + hidden_stack_ids = g_array_new (FALSE, FALSE, sizeof (uint64_t)); + + meta_topic (META_DEBUG_STACK, "Bottom to top: "); + meta_push_no_msg_prefix (); + + sorted = meta_stack_list_windows (stack, NULL); + + for (l = sorted; l; l = l->next) + { + MetaWindow *w = l->data; + uint64_t top_level_window; + uint64_t stack_id; + + if (w->unmanaging) + continue; + + meta_topic (META_DEBUG_STACK, "%u:%d - %s ", + w->layer, w->stack_position, w->desc); + + if (w->frame) + top_level_window = w->frame->xwindow; + else + top_level_window = w->xwindow; + + if (w->client_type == META_WINDOW_CLIENT_TYPE_X11) + stack_id = top_level_window; + else + stack_id = w->stamp; + + /* We don't restack hidden windows along with the rest, though they are + * reflected in the _NET hints. Hidden windows all get pushed below + * the screens fullscreen guard_window. */ + if (w->hidden) + { + g_array_append_val (hidden_stack_ids, stack_id); + continue; + } + + g_array_append_val (all_root_children_stacked, stack_id); + } + + meta_topic (META_DEBUG_STACK, "\n"); + meta_pop_no_msg_prefix (); + + if (display->x11_display) + { + uint64_t guard_window_id; + + /* The screen guard window sits above all hidden windows and acts as + * a barrier to input reaching these windows. */ + guard_window_id = display->x11_display->guard_window; + g_array_append_val (hidden_stack_ids, guard_window_id); + } + + /* Sync to server */ - return stack; + meta_topic (META_DEBUG_STACK, "Restacking %u windows\n", + all_root_children_stacked->len); + + meta_stack_tracker_restack_managed (display->stack_tracker, + (uint64_t *)all_root_children_stacked->data, + all_root_children_stacked->len); + meta_stack_tracker_restack_at_bottom (display->stack_tracker, + (uint64_t *)hidden_stack_ids->data, + hidden_stack_ids->len); + + g_array_free (hidden_stack_ids, TRUE); + g_array_free (all_root_children_stacked, TRUE); + g_list_free (sorted); } -LOCAL_SYMBOL void -meta_stack_free (MetaStack *stack) +static void +meta_stack_init (MetaStack *stack) { - g_array_free (stack->windows, TRUE); + g_signal_connect (stack, "changed", + G_CALLBACK (on_stack_changed), NULL); +} + +static void +meta_stack_finalize (GObject *object) +{ + MetaStack *stack = META_STACK (object); g_list_free (stack->sorted); - g_list_free (stack->added); - g_list_free (stack->removed); - if (stack->last_root_children_stacked) - g_array_free (stack->last_root_children_stacked, TRUE); + G_OBJECT_CLASS (meta_stack_parent_class)->finalize (object); +} - free (stack); +static void +meta_stack_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaStack *stack = META_STACK (object); + + switch (prop_id) + { + case PROP_DISPLAY: + stack->display = g_value_get_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_stack_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaStack *stack = META_STACK (object); + + switch (prop_id) + { + case PROP_DISPLAY: + g_value_set_object (value, stack->display); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } } -LOCAL_SYMBOL void +static void +meta_stack_class_init (MetaStackClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->set_property = meta_stack_set_property; + object_class->get_property = meta_stack_get_property; + object_class->finalize = meta_stack_finalize; + + signals[CHANGED] = + g_signal_new ("changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 0); + signals[WINDOW_ADDED] = + g_signal_new ("window-added", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, META_TYPE_WINDOW); + signals[WINDOW_REMOVED] = + g_signal_new ("window-removed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, META_TYPE_WINDOW); + + pspecs[PROP_DISPLAY] = + g_param_spec_object ("display", + "Display", + "Display", + META_TYPE_DISPLAY, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + + g_object_class_install_properties (object_class, N_PROPS, pspecs); +} + +MetaStack * +meta_stack_new (MetaDisplay *display) +{ + return g_object_new (META_TYPE_STACK, + "display", display, + NULL); +} + +static void +meta_stack_changed (MetaStack *stack) +{ + /* Bail out if frozen */ + if (stack->freeze_count > 0) + return; + + stack_ensure_sorted (stack); + g_signal_emit (stack, signals[CHANGED], 0); +} + +void meta_stack_add (MetaStack *stack, MetaWindow *window) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; + + COGL_TRACE_BEGIN_SCOPED (MetaStackAdd, + "Stack (add window)"); + + g_return_if_fail (meta_window_is_stackable (window)); + meta_topic (META_DEBUG_STACK, "Adding window %s to the stack\n", window->desc); - if (window->stack_position >= 0) + if (meta_window_is_in_stack (window)) meta_bug ("Window %s had stack position already\n", window->desc); - stack->added = g_list_prepend (stack->added, window); + stack->sorted = g_list_prepend (stack->sorted, window); + stack->need_resort = TRUE; /* may not be needed as we add to top */ + stack->need_constrain = TRUE; + stack->need_relayer = TRUE; + + g_signal_emit (stack, signals[WINDOW_ADDED], 0, window); window->stack_position = stack->n_positions; stack->n_positions += 1; @@ -121,19 +293,20 @@ meta_stack_add (MetaStack *stack, "Window %s has stack_position initialized to %d\n", window->desc, window->stack_position); - stack_sync_to_server (stack); - meta_stack_update_window_tile_matches (stack, window->screen->active_workspace); + meta_stack_changed (stack); + meta_stack_update_window_tile_matches (stack, workspace_manager->active_workspace); } -LOCAL_SYMBOL void +void meta_stack_remove (MetaStack *stack, MetaWindow *window) { - meta_topic (META_DEBUG_STACK, "Removing window %s from the stack\n", window->desc); + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; - if (window->stack_position < 0) - meta_bug ("Window %s removed from stack but had no stack position\n", - window->desc); + COGL_TRACE_BEGIN_SCOPED (MetaStackRemove, + "Stack (remove window)"); + + meta_topic (META_DEBUG_STACK, "Removing window %s from the stack\n", window->desc); /* Set window to top position, so removing it will not leave gaps * in the set of positions @@ -143,49 +316,42 @@ meta_stack_remove (MetaStack *stack, window->stack_position = -1; stack->n_positions -= 1; - /* We don't know if it's been moved from "added" to "stack" yet */ - stack->added = g_list_remove (stack->added, window); stack->sorted = g_list_remove (stack->sorted, window); - /* Remember the window ID to remove it from the stack array. - * The macro is safe to use: Window is guaranteed to be 32 bits, and - * GUINT_TO_POINTER says it only works on 32 bits. - */ - stack->removed = g_list_prepend (stack->removed, - GUINT_TO_POINTER (window->xwindow)); - if (window->frame) - stack->removed = g_list_prepend (stack->removed, - GUINT_TO_POINTER (window->frame->xwindow)); - - stack_sync_to_server (stack); - meta_stack_update_window_tile_matches (stack, window->screen->active_workspace); + g_signal_emit (stack, signals[WINDOW_REMOVED], 0, window); + + meta_stack_changed (stack); + meta_stack_update_window_tile_matches (stack, workspace_manager->active_workspace); } -LOCAL_SYMBOL void +void meta_stack_update_layer (MetaStack *stack, MetaWindow *window) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; stack->need_relayer = TRUE; - stack_sync_to_server (stack); - meta_stack_update_window_tile_matches (stack, window->screen->active_workspace); + meta_stack_changed (stack); + meta_stack_update_window_tile_matches (stack, workspace_manager->active_workspace); } -LOCAL_SYMBOL void +void meta_stack_update_transient (MetaStack *stack, MetaWindow *window) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; stack->need_constrain = TRUE; - stack_sync_to_server (stack); - meta_stack_update_window_tile_matches (stack, window->screen->active_workspace); + meta_stack_changed (stack); + meta_stack_update_window_tile_matches (stack, workspace_manager->active_workspace); } /* raise/lower within a layer */ -LOCAL_SYMBOL void +void meta_stack_raise (MetaStack *stack, MetaWindow *window) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; GList *l; int max_stack_position = window->stack_position; MetaWorkspace *workspace; @@ -206,14 +372,15 @@ meta_stack_raise (MetaStack *stack, meta_window_set_stack_position_no_sync (window, max_stack_position); - stack_sync_to_server (stack); - meta_stack_update_window_tile_matches (stack, window->screen->active_workspace); + meta_stack_changed (stack); + meta_stack_update_window_tile_matches (stack, workspace_manager->active_workspace); } -LOCAL_SYMBOL void +void meta_stack_lower (MetaStack *stack, MetaWindow *window) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; GList *l; int min_stack_position = window->stack_position; MetaWorkspace *workspace; @@ -234,27 +401,27 @@ meta_stack_lower (MetaStack *stack, meta_window_set_stack_position_no_sync (window, min_stack_position); - stack_sync_to_server (stack); - meta_stack_update_window_tile_matches (stack, window->screen->active_workspace); + meta_stack_changed (stack); + meta_stack_update_window_tile_matches (stack, workspace_manager->active_workspace); } -LOCAL_SYMBOL void +void meta_stack_freeze (MetaStack *stack) { stack->freeze_count += 1; } -LOCAL_SYMBOL void +void meta_stack_thaw (MetaStack *stack) { g_return_if_fail (stack->freeze_count > 0); stack->freeze_count -= 1; - stack_sync_to_server (stack); + meta_stack_changed (stack); meta_stack_update_window_tile_matches (stack, NULL); } -LOCAL_SYMBOL void +void meta_stack_update_window_tile_matches (MetaStack *stack, MetaWorkspace *workspace) { @@ -274,132 +441,6 @@ meta_stack_update_window_tile_matches (MetaStack *stack, g_list_free (windows); } -/* Get layer ignoring any transient or group relationships */ -static MetaStackLayer -get_standalone_layer (MetaWindow *window) -{ - MetaStackLayer layer; - - switch (window->type) - { - case META_WINDOW_DESKTOP: - layer = META_LAYER_DESKTOP; - break; - - case META_WINDOW_DOCK: - /* still experimenting here */ - if (window->wm_state_below || (window->monitor && window->monitor->in_fullscreen)) - { - layer = META_LAYER_BOTTOM; - } - else - { - layer = META_LAYER_DOCK; - } - break; - - case META_WINDOW_DROPDOWN_MENU: - case META_WINDOW_POPUP_MENU: - case META_WINDOW_TOOLTIP: - case META_WINDOW_NOTIFICATION: - case META_WINDOW_COMBO: - case META_WINDOW_OVERRIDE_OTHER: - layer = META_LAYER_OVERRIDE_REDIRECT; - break; - default: - if (window->wm_state_below) - layer = META_LAYER_BOTTOM; - else if (window->wm_state_above) - layer = META_LAYER_TOP; - else - layer = META_LAYER_NORMAL; - break; - } - - return layer; -} - -/* Note that this function can never use window->layer only - * get_standalone_layer, or we'd have issues. - */ -static MetaStackLayer -get_maximum_layer_in_group (MetaWindow *window) -{ - GSList *members; - MetaGroup *group; - GSList *tmp; - MetaStackLayer max; - MetaStackLayer layer; - - max = META_LAYER_DESKTOP; - - group = meta_window_get_group (window); - - if (group != NULL) - members = meta_group_list_windows (group); - else - members = NULL; - - tmp = members; - while (tmp != NULL) - { - MetaWindow *w = tmp->data; - - if (!w->override_redirect) - { - layer = get_standalone_layer (w); - if (layer > max) - max = layer; - } - - tmp = tmp->next; - } - - g_slist_free (members); - - return max; -} - -static void -compute_layer (MetaWindow *window) -{ - window->layer = get_standalone_layer (window); - - /* We can only do promotion-due-to-group for dialogs and other - * transients, or weird stuff happens like the desktop window and - * nautilus windows getting in the same layer, or all gnome-terminal - * windows getting in fullscreen layer if any terminal is - * fullscreen. - */ - if (window->layer != META_LAYER_DESKTOP && - WINDOW_HAS_TRANSIENT_TYPE(window) && - (window->xtransient_for == None || - window->transient_parent_is_root_window)) - { - /* We only do the group thing if the dialog is NOT transient for - * a particular window. Imagine a group with a normal window, a dock, - * and a dialog transient for the normal window; you don't want the dialog - * above the dock if it wouldn't normally be. - */ - - MetaStackLayer group_max; - - group_max = get_maximum_layer_in_group (window); - - if (group_max > window->layer) - { - meta_topic (META_DEBUG_STACK, - "Promoting window %s from layer %u to %u due to group membership\n", - window->desc, window->layer, group_max); - window->layer = group_max; - } - } - - meta_topic (META_DEBUG_STACK, "Window %s on layer %u type = %u has_focus = %d\n", - window->desc, window->layer, - window->type, window->has_focus); -} - /* Front of the layer list is the topmost window, * so the lower stack position is later in the list */ @@ -501,8 +542,6 @@ add_constraint (Constraint **constraints, { Constraint *c; - g_assert (above->screen == below->screen); - /* check if constraint is a duplicate */ c = constraints[below->stack_position]; while (c != NULL) @@ -535,7 +574,7 @@ create_constraints (Constraint **constraints, { MetaWindow *w = tmp->data; - if (!WINDOW_IN_STACK (w)) + if (!meta_window_is_in_stack (w)) { meta_topic (META_DEBUG_STACK, "Window %s not in the stack, not constraining it\n", w->desc); @@ -562,8 +601,7 @@ create_constraints (Constraint **constraints, { MetaWindow *group_window = tmp2->data; - if (!WINDOW_IN_STACK (group_window) || - w->screen != group_window->screen || + if (!meta_window_is_in_stack (group_window) || group_window->override_redirect) { tmp2 = tmp2->next; @@ -578,7 +616,7 @@ create_constraints (Constraint **constraints, /* better way I think, so transient-for-group are constrained * only above non-transient-type windows in their group */ - if (!WINDOW_HAS_TRANSIENT_TYPE (group_window)) + if (!meta_window_has_transient_type (group_window)) #endif { meta_topic (META_DEBUG_STACK, "Constraining %s above %s as it's transient for its group\n", @@ -591,16 +629,13 @@ create_constraints (Constraint **constraints, g_slist_free (group_windows); } - else if (w->xtransient_for != None && - !w->transient_parent_is_root_window) + else if (w->transient_for != NULL) { MetaWindow *parent; - parent = - meta_display_lookup_x_window (w->display, w->xtransient_for); + parent = w->transient_for; - if (parent && WINDOW_IN_STACK (parent) && - parent->screen == w->screen) + if (parent && meta_window_is_in_stack (parent)) { meta_topic (META_DEBUG_STACK, "Constraining %s above %s due to transiency\n", w->desc, parent->desc); @@ -673,7 +708,7 @@ free_constraints (Constraint **constraints, g_slist_free (c->next_nodes); - free (c); + g_free (c); c = next; } @@ -686,8 +721,11 @@ static void ensure_above (MetaWindow *above, MetaWindow *below) { - if (WINDOW_HAS_TRANSIENT_TYPE(above) && - above->layer < below->layer) + gboolean is_transient; + + is_transient = meta_window_has_transient_type (above) || + above->transient_for == below; + if (is_transient && above->layer < below->layer) { meta_topic (META_DEBUG_STACK, "Promoting window %s from layer %u to %u due to contraint\n", @@ -767,107 +805,9 @@ apply_constraints (Constraint **constraints, g_slist_free (heads); } -/* - * Go through "deleted" and take the matching windows - * out of "windows". - */ -static void -stack_do_window_deletions (MetaStack *stack) -{ - /* Do removals before adds, with paranoid idea that we might re-add - * the same window IDs. - */ - GList *tmp; - int i; - - tmp = stack->removed; - while (tmp != NULL) - { - Window xwindow; - xwindow = GPOINTER_TO_UINT (tmp->data); - - /* We go from the end figuring removals are more - * likely to be recent. - */ - i = stack->windows->len; - while (i > 0) - { - --i; - - /* there's no guarantee we'll actually find windows to - * remove, e.g. the same xwindow could have been - * added/removed before we ever synced, and we put - * both the window->xwindow and window->frame->xwindow - * in the removal list. - */ - if (xwindow == g_array_index (stack->windows, Window, i)) - { - g_array_remove_index (stack->windows, i); - goto next; - } - } - - next: - tmp = tmp->next; - } - - g_list_free (stack->removed); - stack->removed = NULL; -} - -static void -stack_do_window_additions (MetaStack *stack) -{ - GList *tmp; - gint i, n_added; - - n_added = g_list_length (stack->added); - if (n_added > 0) - { - Window *end; - int old_size; - - meta_topic (META_DEBUG_STACK, - "Adding %d windows to sorted list\n", - n_added); - - old_size = stack->windows->len; - g_array_set_size (stack->windows, old_size + n_added); - - end = &g_array_index (stack->windows, Window, old_size); - - /* stack->added has the most recent additions at the - * front of the list, so we need to reverse it - */ - stack->added = g_list_reverse (stack->added); - - i = 0; - tmp = stack->added; - while (tmp != NULL) - { - MetaWindow *w; - - w = tmp->data; - - end[i] = w->xwindow; - - /* add to the main list */ - stack->sorted = g_list_prepend (stack->sorted, w); - - ++i; - tmp = tmp->next; - } - - stack->need_resort = TRUE; /* may not be needed as we add to top */ - stack->need_constrain = TRUE; - stack->need_relayer = TRUE; - } - - g_list_free (stack->added); - stack->added = NULL; -} - -/* +/** + * stack_do_relayer: + * * Update the layers that windows are in */ static void @@ -876,7 +816,7 @@ stack_do_relayer (MetaStack *stack) GList *tmp; if (!stack->need_relayer) - return; + return; meta_topic (META_DEBUG_STACK, "Recomputing layers\n"); @@ -891,7 +831,7 @@ stack_do_relayer (MetaStack *stack) w = tmp->data; old_layer = w->layer; - compute_layer (w); + w->layer = meta_window_calculate_layer (w); if (w->layer != old_layer) { @@ -912,7 +852,9 @@ stack_do_relayer (MetaStack *stack) stack->need_relayer = FALSE; } -/* +/** + * stack_do_constrain: + * * Update stack_position and layer to reflect transiency * constraints */ @@ -939,12 +881,14 @@ stack_do_constrain (MetaStack *stack) apply_constraints (constraints, stack->n_positions); free_constraints (constraints, stack->n_positions); - free (constraints); + g_free (constraints); stack->need_constrain = FALSE; } -/* +/** + * stack_do_resort: + * * Sort stack->sorted with layers having priority over stack_position. */ static void @@ -959,12 +903,14 @@ stack_do_resort (MetaStack *stack) stack->sorted = g_list_sort (stack->sorted, (GCompareFunc) compare_window_position); - meta_screen_queue_check_fullscreen (stack->screen); + meta_display_queue_check_fullscreen (stack->display); stack->need_resort = FALSE; } -/* +/** + * stack_ensure_sorted: + * * Puts the stack into canonical form. * * Honour the removed and added lists of the stack, and then recalculate @@ -976,370 +922,12 @@ stack_do_resort (MetaStack *stack) static void stack_ensure_sorted (MetaStack *stack) { - stack_do_window_deletions (stack); - stack_do_window_additions (stack); stack_do_relayer (stack); stack_do_constrain (stack); stack_do_resort (stack); } -/* - * This function is used to avoid raising a window above popup - * menus and other such things. - * - * The key to the operation of this function is that we are expecting - * at most one window to be added at a time. If xwindow is newly added, - * then its own stack position will be too high (the frame window - * is created at the top of the stack), but if we ignore xwindow, - * then the *next* managed window in the stack will be a window that - * we've already stacked. - * - * We could generalize this and remove the assumption that windows - * are added one at a time by keeping an explicit ->stacked flag in - * MetaWindow. - * - * An alternate approach would be to reverse the stacking algorithm to - * work by placing each window above the others, and start by lowering - * a window to the bottom (instead of the current way, which works by - * placing each window below another and starting with a raise) - */ -static void -raise_window_relative_to_managed_windows (MetaScreen *screen, - Window xwindow) -{ - - Window *children; - int n_children; - int i; - - meta_stack_tracker_get_stack (screen->stack_tracker, - &children, &n_children); - - /* Children are in order from bottom to top. We want to - * find the topmost managed child, then configure - * our window to be above it. - */ - i = n_children - 1; - while (i >= 0) - { - if (children[i] == xwindow) - { - /* Do nothing. This means we're already the topmost managed - * window, but it DOES NOT mean we are already just above - * the topmost managed window. This is important because if - * an override redirect window is up, and we map a new - * managed window, the new window is probably above the old - * popup by default, and we want to push it below that - * popup. So keep looking for a sibling managed window - * to be moved below. - */ - } - else - { - MetaWindow *other = meta_display_lookup_x_window (screen->display, - children[i]); - if (other != NULL && !other->override_redirect && !other->unmanaging) - { - XWindowChanges changes; - - /* children[i] is the topmost managed child */ - meta_topic (META_DEBUG_STACK, - "Moving 0x%lx above topmost managed child window 0x%lx\n", - xwindow, children[i]); - - changes.sibling = children[i]; - changes.stack_mode = Above; - - meta_error_trap_push (screen->display); - meta_stack_tracker_record_raise_above (screen->stack_tracker, - xwindow, - children[i], - XNextRequest (screen->display->xdisplay)); - XConfigureWindow (screen->display->xdisplay, - xwindow, - CWSibling | CWStackMode, - &changes); - meta_error_trap_pop (screen->display); - - break; - } - } - - --i; - } - - if (i < 0) - { - /* No sibling to use, just lower ourselves to the bottom - * to be sure we're below any override redirect windows. - */ - meta_error_trap_push (screen->display); - meta_stack_tracker_record_lower (screen->stack_tracker, - xwindow, - XNextRequest (screen->display->xdisplay)); - XLowerWindow (screen->display->xdisplay, - xwindow); - meta_error_trap_pop (screen->display); - } -} - -/* - * Order the windows on the X server to be the same as in our structure. - * We do this using XRestackWindows if we don't know the previous order, - * or XConfigureWindow on a few particular windows if we do and can figure - * out the minimum set of changes. After that, we set __NET_CLIENT_LIST - * and __NET_CLIENT_LIST_STACKING. - * - * FIXME: Now that we have a good view of the stacking order on the server - * with MetaStackTracker it should be possible to do a simpler and better - * job of computing the minimal set of stacking requests needed. - */ -static void -stack_sync_to_server (MetaStack *stack) -{ - GArray *stacked; - GArray *root_children_stacked; - GList *tmp; - GArray *all_hidden; - int n_override_redirect = 0; - int n_unmanaging = 0; - - /* Bail out if frozen */ - if (stack->freeze_count > 0) - return; - - meta_topic (META_DEBUG_STACK, "Syncing window stack to server\n"); - - stack_ensure_sorted (stack); - - /* Create stacked xwindow arrays. - * Painfully, "stacked" is in bottom-to-top order for the - * _NET hints, and "root_children_stacked" is in top-to-bottom - * order for XRestackWindows() - */ - stacked = g_array_new (FALSE, FALSE, sizeof (Window)); - root_children_stacked = g_array_new (FALSE, FALSE, sizeof (Window)); - all_hidden = g_array_new (FALSE, FALSE, sizeof (Window)); - - /* The screen guard window sits above all hidden windows and acts as - * a barrier to input reaching these windows. */ - g_array_append_val (all_hidden, stack->screen->guard_window); - - meta_topic (META_DEBUG_STACK, "Top to bottom: "); - meta_push_no_msg_prefix (); - - for (tmp = stack->sorted; tmp != NULL; tmp = tmp->next) - { - MetaWindow *w = tmp->data; - Window top_level_window; - - if (w->unmanaging) - { - n_unmanaging ++; - continue; - } - - meta_topic (META_DEBUG_STACK, "%u:%d - %s ", - w->layer, w->stack_position, w->desc); - - /* remember, stacked is in reverse order (bottom to top) */ - if (w->override_redirect) - n_override_redirect++; - else - g_array_prepend_val (stacked, w->xwindow); - - if (w->frame) - top_level_window = w->frame->xwindow; - else - top_level_window = w->xwindow; - - /* We don't restack hidden windows along with the rest, though they are - * reflected in the _NET hints. Hidden windows all get pushed below - * the screens fullscreen guard_window. */ - if (w->hidden) - { - g_array_append_val (all_hidden, top_level_window); - continue; - } - - /* build XRestackWindows() array from top to bottom */ - g_array_append_val (root_children_stacked, top_level_window); - } - - meta_topic (META_DEBUG_STACK, "\n"); - meta_pop_no_msg_prefix (); - - /* All windows should be in some stacking order */ - if (stacked->len != stack->windows->len - n_override_redirect - n_unmanaging) - meta_bug ("%u windows stacked, %u windows exist in stack\n", - stacked->len, stack->windows->len); - - /* Sync to server */ - - meta_topic (META_DEBUG_STACK, "Restacking %u windows\n", - root_children_stacked->len); - - meta_error_trap_push (stack->screen->display); - - if (stack->last_root_children_stacked == NULL) - { - /* Just impose our stack, we don't know the previous state. - * This involves a ton of circulate requests and may flicker. - */ - meta_topic (META_DEBUG_STACK, "Don't know last stack state, restacking everything\n"); - - if (root_children_stacked->len > 0) - { - meta_stack_tracker_record_restack_windows (stack->screen->stack_tracker, - (Window *) root_children_stacked->data, - root_children_stacked->len, - XNextRequest (stack->screen->display->xdisplay)); - XRestackWindows (stack->screen->display->xdisplay, - (Window *) root_children_stacked->data, - root_children_stacked->len); - } - } - else if (root_children_stacked->len > 0) - { - /* Try to do minimal window moves to get the stack in order */ - /* A point of note: these arrays include frames not client windows, - * so if a client window has changed frame since last_root_children_stacked - * was saved, then we may have inefficiency, but I don't think things - * break... - */ - const Window *old_stack = (Window *) stack->last_root_children_stacked->data; - const Window *new_stack = (Window *) root_children_stacked->data; - const int old_len = stack->last_root_children_stacked->len; - const int new_len = root_children_stacked->len; - const Window *oldp = old_stack; - const Window *newp = new_stack; - const Window *old_end = old_stack + old_len; - const Window *new_end = new_stack + new_len; - Window last_window = None; - - while (oldp != old_end && - newp != new_end) - { - if (*oldp == *newp) - { - /* Stacks are the same here, move on */ - ++oldp; - last_window = *newp; - ++newp; - } - else if (meta_display_lookup_x_window (stack->screen->display, - *oldp) == NULL) - { - /* *oldp is no longer known to us (probably destroyed), - * so we can just skip it - */ - ++oldp; - } - else - { - /* Move *newp below last_window */ - if (last_window == None) - { - meta_topic (META_DEBUG_STACK, "Using window 0x%lx as topmost (but leaving it in-place)\n", *newp); - - raise_window_relative_to_managed_windows (stack->screen, - *newp); - } - else - { - /* This means that if last_window is dead, but not - * *newp, then we fail to restack *newp; but on - * unmanaging last_window, we'll fix it up. - */ - - XWindowChanges changes; - - changes.sibling = last_window; - changes.stack_mode = Below; - - meta_topic (META_DEBUG_STACK, "Placing window 0x%lx below 0x%lx\n", - *newp, last_window); - - meta_stack_tracker_record_lower_below (stack->screen->stack_tracker, - *newp, last_window, - XNextRequest (stack->screen->display->xdisplay)); - XConfigureWindow (stack->screen->display->xdisplay, - *newp, - CWSibling | CWStackMode, - &changes); - } - - last_window = *newp; - ++newp; - } - } - - if (newp != new_end) - { - /* Restack remaining windows */ - meta_topic (META_DEBUG_STACK, "Restacking remaining %d windows\n", - (int) (new_end - newp)); - /* We need to include an already-stacked window - * in the restack call, so we get in the proper position - * with respect to it. - */ - if (newp != new_stack) - --newp; - meta_stack_tracker_record_restack_windows (stack->screen->stack_tracker, - (Window *) newp, new_end - newp, - XNextRequest (stack->screen->display->xdisplay)); - XRestackWindows (stack->screen->display->xdisplay, - (Window *) newp, new_end - newp); - } - } - - /* Push hidden windows to the bottom of the stack under the guard window */ - meta_stack_tracker_record_lower (stack->screen->stack_tracker, - stack->screen->guard_window, - XNextRequest (stack->screen->display->xdisplay)); - XLowerWindow (stack->screen->display->xdisplay, stack->screen->guard_window); - meta_stack_tracker_record_restack_windows (stack->screen->stack_tracker, - (Window *)all_hidden->data, - all_hidden->len, - XNextRequest (stack->screen->display->xdisplay)); - XRestackWindows (stack->screen->display->xdisplay, - (Window *)all_hidden->data, - all_hidden->len); - g_array_free (all_hidden, TRUE); - - meta_error_trap_pop (stack->screen->display); - /* on error, a window was destroyed; it should eventually - * get removed from the stacking list when we unmanage it - * and we'll fix stacking at that time. - */ - - /* Sync _NET_CLIENT_LIST and _NET_CLIENT_LIST_STACKING */ - - XChangeProperty (stack->screen->display->xdisplay, - stack->screen->xroot, - stack->screen->display->atom__NET_CLIENT_LIST, - XA_WINDOW, - 32, PropModeReplace, - (unsigned char *)stack->windows->data, - stack->windows->len); - XChangeProperty (stack->screen->display->xdisplay, - stack->screen->xroot, - stack->screen->display->atom__NET_CLIENT_LIST_STACKING, - XA_WINDOW, - 32, PropModeReplace, - (unsigned char *)stacked->data, - stacked->len); - - g_array_free (stacked, TRUE); - - if (stack->last_root_children_stacked) - g_array_free (stack->last_root_children_stacked, TRUE); - stack->last_root_children_stacked = root_children_stacked; - - /* That was scary... */ -} - -LOCAL_SYMBOL MetaWindow* +MetaWindow * meta_stack_get_top (MetaStack *stack) { stack_ensure_sorted (stack); @@ -1350,7 +938,7 @@ meta_stack_get_top (MetaStack *stack) return NULL; } -LOCAL_SYMBOL MetaWindow* +MetaWindow * meta_stack_get_bottom (MetaStack *stack) { GList *link; @@ -1364,10 +952,10 @@ meta_stack_get_bottom (MetaStack *stack) return NULL; } -LOCAL_SYMBOL MetaWindow* -meta_stack_get_above (MetaStack *stack, - MetaWindow *window, - gboolean only_within_layer) +MetaWindow * +meta_stack_get_above (MetaStack *stack, + MetaWindow *window, + gboolean only_within_layer) { GList *link; MetaWindow *above; @@ -1389,10 +977,10 @@ meta_stack_get_above (MetaStack *stack, return above; } -LOCAL_SYMBOL MetaWindow* -meta_stack_get_below (MetaStack *stack, - MetaWindow *window, - gboolean only_within_layer) +MetaWindow * +meta_stack_get_below (MetaStack *stack, + MetaWindow *window, + gboolean only_within_layer) { GList *link; MetaWindow *below; @@ -1422,12 +1010,33 @@ window_contains_point (MetaWindow *window, { MetaRectangle rect; - meta_window_get_outer_rect (window, &rect); + meta_window_get_frame_rect (window, &rect); return META_POINT_IN_RECT (root_x, root_y, rect); } -static MetaWindow* +static gboolean +window_can_get_default_focus (MetaWindow *window) +{ + if (window->unmaps_pending > 0) + return FALSE; + + if (window->unmanaging) + return FALSE; + + if (!meta_window_is_focusable (window)) + return FALSE; + + if (!meta_window_should_be_showing (window)) + return FALSE; + + if (window->type == META_WINDOW_DOCK) + return FALSE; + + return TRUE; +} + +static MetaWindow * get_default_focus_window (MetaStack *stack, MetaWorkspace *workspace, MetaWindow *not_this_one, @@ -1437,93 +1046,36 @@ get_default_focus_window (MetaStack *stack, { /* Find the topmost, focusable, mapped, window. * not_this_one is being unfocused or going away, so exclude it. - * Also, prefer to focus transient parent of not_this_one, - * or top window in same group as not_this_one. */ - MetaWindow *topmost_dock; - MetaWindow *transient_parent; - MetaWindow *topmost_in_group; - MetaWindow *topmost_overall; - MetaGroup *not_this_one_group; - GList *link; - - topmost_dock = NULL; - transient_parent = NULL; - topmost_in_group = NULL; - topmost_overall = NULL; - if (not_this_one) - not_this_one_group = meta_window_get_group (not_this_one); - else - not_this_one_group = NULL; + GList *l; stack_ensure_sorted (stack); /* top of this layer is at the front of the list */ - link = stack->sorted; - - while (link) + for (l = stack->sorted; l != NULL; l = l->next) { - MetaWindow *window = link->data; + MetaWindow *window = l->data; - if (window && - window != not_this_one && - (window->unmaps_pending == 0) && - !window->minimized && - (window->input || window->take_focus) && - (workspace == NULL || - meta_window_located_on_workspace (window, workspace))) - { - if (topmost_dock == NULL && - window->type == META_WINDOW_DOCK) - topmost_dock = window; + if (!window) + continue; - if (not_this_one != NULL) - { - if (transient_parent == NULL && - not_this_one->xtransient_for != None && - not_this_one->xtransient_for == window->xwindow && - (!must_be_at_point || - window_contains_point (window, root_x, root_y))) - transient_parent = window; - - if (topmost_in_group == NULL && - not_this_one_group != NULL && - not_this_one_group == meta_window_get_group (window) && - (!must_be_at_point || - window_contains_point (window, root_x, root_y))) - topmost_in_group = window; - } + if (window == not_this_one) + continue; - /* Note that DESKTOP windows can be topmost_overall so - * we prefer focusing desktop or other windows over - * focusing dock, even though docks are stacked higher. - */ - if (topmost_overall == NULL && - window->type != META_WINDOW_DOCK && - (!must_be_at_point || - window_contains_point (window, root_x, root_y))) - topmost_overall = window; - - /* We could try to bail out early here for efficiency in - * some cases, but it's just not worth the code. - */ - } + if (!window_can_get_default_focus (window)) + continue; - link = link->next; + if (must_be_at_point && !window_contains_point (window, root_x, root_y)) + continue; + + return window; } - if (transient_parent) - return transient_parent; - else if (topmost_in_group) - return topmost_in_group; - else if (topmost_overall) - return topmost_overall; - else - return topmost_dock; + return NULL; } -LOCAL_SYMBOL MetaWindow* +MetaWindow * meta_stack_get_default_focus_window_at_point (MetaStack *stack, MetaWorkspace *workspace, MetaWindow *not_this_one, @@ -1534,7 +1086,7 @@ meta_stack_get_default_focus_window_at_point (MetaStack *stack, TRUE, root_x, root_y); } -LOCAL_SYMBOL MetaWindow* +MetaWindow * meta_stack_get_default_focus_window (MetaStack *stack, MetaWorkspace *workspace, MetaWindow *not_this_one) @@ -1543,7 +1095,7 @@ meta_stack_get_default_focus_window (MetaStack *stack, FALSE, 0, 0); } -LOCAL_SYMBOL GList* +GList * meta_stack_list_windows (MetaStack *stack, MetaWorkspace *workspace) { @@ -1571,13 +1123,31 @@ meta_stack_list_windows (MetaStack *stack, return workspace_windows; } -LOCAL_SYMBOL int -meta_stack_windows_cmp (MetaStack *stack, - MetaWindow *window_a, - MetaWindow *window_b) +GList * +meta_stack_get_default_focus_candidates (MetaStack *stack, + MetaWorkspace *workspace) { - g_return_val_if_fail (window_a->screen == window_b->screen, 0); + GList *windows = meta_stack_list_windows (stack, workspace); + GList *l; + + for (l = windows; l;) + { + GList *next = l->next; + + if (!window_can_get_default_focus (l->data)) + windows = g_list_delete_link (windows, l); + + l = next; + } + return windows; +} + +int +meta_stack_windows_cmp (MetaStack *stack, + MetaWindow *window_a, + MetaWindow *window_b) +{ /* -1 means a below b */ stack_ensure_sorted (stack); /* update constraints, layers */ @@ -1609,7 +1179,7 @@ compare_just_window_stack_position (void *a, return 0; /* not reached */ } -LOCAL_SYMBOL GList* +GList * meta_stack_get_positions (MetaStack *stack) { GList *tmp; @@ -1660,7 +1230,7 @@ lists_contain_same_windows (GList *a, return (tmp1 == NULL); /* tmp2 is non-NULL if tmp1 is */ } -LOCAL_SYMBOL void +void meta_stack_set_positions (MetaStack *stack, GList *windows) { @@ -1695,7 +1265,7 @@ meta_stack_set_positions (MetaStack *stack, meta_topic (META_DEBUG_STACK, "Reset the stack positions of (nearly) all windows\n"); - stack_sync_to_server (stack); + meta_stack_changed (stack); meta_stack_update_window_tile_matches (stack, NULL); } @@ -1706,10 +1276,10 @@ meta_window_set_stack_position_no_sync (MetaWindow *window, int low, high, delta; GList *tmp; - g_return_if_fail (window->screen->stack != NULL); + g_return_if_fail (window->display->stack != NULL); g_return_if_fail (window->stack_position >= 0); g_return_if_fail (position >= 0); - g_return_if_fail (position < window->screen->stack->n_positions); + g_return_if_fail (position < window->display->stack->n_positions); if (position == window->stack_position) { @@ -1718,8 +1288,8 @@ meta_window_set_stack_position_no_sync (MetaWindow *window, return; } - window->screen->stack->need_resort = TRUE; - window->screen->stack->need_constrain = TRUE; + window->display->stack->need_resort = TRUE; + window->display->stack->need_constrain = TRUE; if (position < window->stack_position) { @@ -1734,7 +1304,7 @@ meta_window_set_stack_position_no_sync (MetaWindow *window, delta = -1; } - tmp = window->screen->stack->sorted; + tmp = window->display->stack->sorted; while (tmp != NULL) { MetaWindow *w = tmp->data; @@ -1753,12 +1323,14 @@ meta_window_set_stack_position_no_sync (MetaWindow *window, window->desc, window->stack_position); } -LOCAL_SYMBOL void +void meta_window_set_stack_position (MetaWindow *window, int position) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; + meta_window_set_stack_position_no_sync (window, position); - stack_sync_to_server (window->screen->stack); - meta_stack_update_window_tile_matches (window->screen->stack, - window->screen->active_workspace); + meta_stack_changed (window->display->stack); + meta_stack_update_window_tile_matches (window->display->stack, + workspace_manager->active_workspace); } diff --git a/src/core/stack.h b/src/core/stack.h index 366901457..ec5753fe7 100644 --- a/src/core/stack.h +++ b/src/core/stack.h @@ -1,27 +1,9 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/** - * \file stack.h Which windows cover which other windows - * - * There are two factors that determine window position. - * - * One is window->stack_position, which is a unique integer - * indicating how windows are ordered with respect to one - * another. The ordering here transcends layers; it isn't changed - * as the window is moved among layers. This allows us to move several - * windows from one layer to another, while preserving the relative - * order of the moved windows. Also, it allows us to restore - * the stacking order from a saved session. - * - * However when actually stacking windows on the screen, the - * layer overrides the stack_position; windows are first sorted - * by layer, then by stack_position within each layer. - */ - -/* +/* * Copyright (C) 2001 Havoc Pennington * Copyright (C) 2005 Elijah Newren - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the @@ -31,17 +13,34 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_STACK_H #define META_STACK_H -#include "screen-private.h" +/** + * SECTION:stack + * @short_description: Which windows cover which other windows + * + * There are two factors that determine window position. + * + * One is window->stack_position, which is a unique integer + * indicating how windows are ordered with respect to one + * another. The ordering here transcends layers; it isn't changed + * as the window is moved among layers. This allows us to move several + * windows from one layer to another, while preserving the relative + * order of the moved windows. Also, it allows us to restore + * the stacking order from a saved session. + * + * However when actually stacking windows on the screen, the + * layer overrides the stack_position; windows are first sorted + * by layer, then by stack_position within each layer. + */ + +#include "core/display-private.h" /** * A sorted list of windows bearing some level of resemblance to the stack of @@ -52,38 +51,14 @@ */ struct _MetaStack { - /** The MetaScreen containing this stack. */ - MetaScreen *screen; + GObject parent; - /** - * A sequence of all the Windows (X handles, not MetaWindows) of the windows - * we manage, sorted in order. Suitable to be passed into _NET_CLIENT_LIST. - */ - GArray *windows; + /** The MetaDisplay containing this stack. */ + MetaDisplay *display; /** The MetaWindows of the windows we manage, sorted in order. */ GList *sorted; - /** - * MetaWindows waiting to be added to the "sorted" and "windows" list, after - * being added by meta_stack_add() and before being assimilated by - * stack_ensure_sorted(). - * - * The order of the elements in this list is not important; what is important - * is the stack_position element of each window. - */ - GList *added; - - /** - * Windows (X handles, not MetaWindows) waiting to be removed from the - * "windows" list, after being removed by meta_stack_remove() and before - * being assimilated by stack_ensure_sorted(). (We already removed them - * from the "sorted" list.) - * - * The order of the elements in this list is not important. - */ - GList *removed; - /** * If this is zero, the local stack oughtn't to be brought up to date with * the X server's stack, because it is in the middle of being updated. @@ -98,7 +73,7 @@ struct _MetaStack * The last-known stack of all windows, bottom to top. We cache it here * so that subsequent times we'll be able to do incremental moves. */ - GArray *last_root_children_stacked; + GArray *last_all_root_children_stacked; /** * Number of stack positions; same as the length of added, but @@ -122,213 +97,253 @@ struct _MetaStack unsigned int need_constrain : 1; }; +#define META_TYPE_STACK (meta_stack_get_type ()) +G_DECLARE_FINAL_TYPE (MetaStack, meta_stack, META, STACK, GObject) + /** + * meta_stack_new: + * @display: The MetaDisplay which will be the parent of this stack. + * * Creates and initialises a MetaStack. * - * \param screen The MetaScreen which will be the parent of this stack. - * \return The new screen. + * Returns: The new stack. */ -MetaStack *meta_stack_new (MetaScreen *screen); +MetaStack * meta_stack_new (MetaDisplay *display); /** - * Destroys and frees a MetaStack. + * meta_stack_add: + * @stack: The stack to add it to + * @window: The window to add * - * \param stack The stack to destroy. - */ -void meta_stack_free (MetaStack *stack); - -/** * Adds a window to the local stack. It is a fatal error to call this * function on a window which already exists on the stack of any screen. - * - * \param window The window to add - * \param stack The stack to add it to */ -void meta_stack_add (MetaStack *stack, - MetaWindow *window); +void meta_stack_add (MetaStack *stack, + MetaWindow *window); /** + * meta_stack_remove: + * @stack: The stack to remove it from + * @window: The window to remove + * * Removes a window from the local stack. It is a fatal error to call this * function on a window which exists on the stack of any screen. - * - * \param window The window to remove - * \param stack The stack to remove it from */ -void meta_stack_remove (MetaStack *stack, - MetaWindow *window); +void meta_stack_remove (MetaStack *stack, + MetaWindow *window); /** + * meta_stack_update_layer: + * @stack: The stack to recalculate + * @window: Dummy parameter + * * Recalculates the correct layer for all windows in the stack, * and moves them about accordingly. * - * \param window Dummy parameter - * \param stack The stack to recalculate - * \bug What's with the dummy parameter? */ -void meta_stack_update_layer (MetaStack *stack, - MetaWindow *window); +void meta_stack_update_layer (MetaStack *stack, + MetaWindow *window); /** + * meta_stack_update_transient: + * @stack: The stack to recalculate + * @window: Dummy parameter + * * Recalculates the correct stacking order for all windows in the stack * according to their transience, and moves them about accordingly. * - * \param window Dummy parameter - * \param stack The stack to recalculate - * \bug What's with the dummy parameter? + * FIXME: What's with the dummy parameter? */ -void meta_stack_update_transient (MetaStack *stack, - MetaWindow *window); +void meta_stack_update_transient (MetaStack *stack, + MetaWindow *window); /** - * Move a window to the top of its layer. + * meta_stack_raise: + * @stack: The stack to modify. + * @window: The window that's making an ascension. + * (Amulet of Yendor not required.) * - * \param stack The stack to modify. - * \param window The window that's making an ascension. - * (Amulet of Yendor not required.) + * Move a window to the top of its layer. */ -void meta_stack_raise (MetaStack *stack, - MetaWindow *window); +void meta_stack_raise (MetaStack *stack, + MetaWindow *window); /** - * Move a window to the bottom of its layer. + * meta_stack_lower: + * @stack: The stack to modify. + * @window: The window that's on the way downwards. * - * \param stack The stack to modify. - * \param window The window that's on the way downwards. + * Move a window to the bottom of its layer. */ -void meta_stack_lower (MetaStack *stack, - MetaWindow *window); +void meta_stack_lower (MetaStack *stack, + MetaWindow *window); /** + * meta_stack_freeze: + * @stack: The stack to freeze. + * * Prevent syncing to server until the next call of meta_stack_thaw(), * so that we can carry out multiple operations in one go without having * everything halfway reflected on the X server. * * (Calls to meta_stack_freeze() nest, so that multiple calls to * meta_stack_freeze will require multiple calls to meta_stack_thaw().) - * - * \param stack The stack to freeze. */ -void meta_stack_freeze (MetaStack *stack); +void meta_stack_freeze (MetaStack *stack); /** + * meta_stack_thaw: + * @stack: The stack to thaw. + * * Undoes a meta_stack_freeze(), and processes anything which has become * necessary during the freeze. It is an error to call this function if * the stack has not been frozen. - * - * \param stack The stack to thaw. */ -void meta_stack_thaw (MetaStack *stack); +void meta_stack_thaw (MetaStack *stack); /** + * meta_stack_get_top: + * @stack: The stack to examine. + * * Finds the top window on the stack. * - * \param stack The stack to examine. - * \return The top window on the stack, or NULL in the vanishingly unlikely - * event that you have no windows on your screen whatsoever. + * Returns: The top window on the stack, or %NULL in the vanishingly unlikely + * event that you have no windows on your screen whatsoever. */ -MetaWindow* meta_stack_get_top (MetaStack *stack); +MetaWindow * meta_stack_get_top (MetaStack *stack); /** + * meta_stack_get_bottom: + * @stack: The stack to search + * * Finds the window at the bottom of the stack. Since that's pretty much * always the desktop, this isn't the most useful of functions, and nobody * actually calls it. We should probably get rid of it. - * - * \param stack The stack to search */ -MetaWindow* meta_stack_get_bottom (MetaStack *stack); +MetaWindow * meta_stack_get_bottom (MetaStack *stack); /** + * meta_stack_get_above: + * @stack: The stack to search. + * @window: The window to look above. + * @only_within_layer: If %TRUE, will return %NULL if @window is the + * top window in its layer. + * * Finds the window above a given window in the stack. * It is not an error to pass in a window which does not exist in - * the stack; the function will merely return NULL. - * - * \param stack The stack to search. - * \param window The window to look above. - * \param only_within_layer If true, will return NULL if "window" is the - * top window in its layer. - * \return NULL if there is no such window; - * the window above "window" otherwise. + * the stack; the function will merely return %NULL. + * + * Returns: %NULL if there is no such window; + * the window above @window otherwise. */ -MetaWindow* meta_stack_get_above (MetaStack *stack, +MetaWindow * meta_stack_get_above (MetaStack *stack, MetaWindow *window, gboolean only_within_layer); /** + * meta_stack_get_below: + * @stack: The stack to search. + * @window: The window to look below. + * @only_within_layer: If %TRUE, will return %NULL if window is the + * bottom window in its layer. + * * Finds the window below a given window in the stack. * It is not an error to pass in a window which does not exist in - * the stack; the function will merely return NULL. - * - * \param stack The stack to search. - * \param window The window to look below. - * \param only_within_layer If true, will return NULL if "window" is the - * bottom window in its layer. - * \return NULL if there is no such window; - * the window below "window" otherwise. + * the stack; the function will merely return %NULL. + * + * + * Returns: %NULL if there is no such window; + * the window below @window otherwise. */ -MetaWindow* meta_stack_get_below (MetaStack *stack, +MetaWindow * meta_stack_get_below (MetaStack *stack, MetaWindow *window, gboolean only_within_layer); /** - * Find the topmost, focusable, mapped, window in a stack. If you supply - * a window as "not_this_one", we won't return that one (presumably - * because it's going to be going away). But if you do supply "not_this_one" - * and we find its parent, we'll return that; and if "not_this_one" is in + * meta_stack_get_default_focus_window: + * @stack: The stack to search. + * @workspace: %NULL to search all workspaces; otherwise only windows + * from that workspace will be returned. + * @not_this_one: Window to ignore because it's being unfocussed or + * going away. + * + * Find the topmost, focusable, mapped, window in a stack. If you supply + * a window as @not_this_one, we won't return that one (presumably + * because it's going to be going away). But if you do supply @not_this_one + * and we find its parent, we'll return that; and if @not_this_one is in * a group, we'll return the top window of that group. * * Also, we are prejudiced against dock windows. Every kind of window, even * the desktop, will be returned in preference to a dock window. * - * \param stack The stack to search. - * \param workspace NULL to search all workspaces; otherwise only windows - * from that workspace will be returned. - * \param not_this_one Window to ignore because it's being unfocussed or - * going away. - * \return The window matching all these constraints or NULL if none does. - * - * \bug Never called! + * Returns: The window matching all these constraints or %NULL if none does. */ -MetaWindow* meta_stack_get_default_focus_window (MetaStack *stack, - MetaWorkspace *workspace, - MetaWindow *not_this_one); +MetaWindow * meta_stack_get_default_focus_window (MetaStack *stack, + MetaWorkspace *workspace, + MetaWindow *not_this_one); /** + * meta_stack_get_default_focus_window_at_point: + * @stack: The stack to search. + * @workspace: %NULL to search all workspaces; otherwise only windows + * from that workspace will be returned. + * @not_this_one: Window to ignore because it's being unfocussed or + * going away. + * @root_x: The returned window must contain this point, + * unless it's a dock. + * @root_y: See root_x. + * * Find the topmost, focusable, mapped, window in a stack. If you supply - * a window as "not_this_one", we won't return that one (presumably - * because it's going to be going away). But if you do supply "not_this_one" - * and we find its parent, we'll return that; and if "not_this_one" is in + * a window as @not_this_one, we won't return that one (presumably + * because it's going to be going away). But if you do supply @not_this_one + * and we find its parent, we'll return that; and if @not_this_one is in * a group, we'll return the top window of that group. * * Also, we are prejudiced against dock windows. Every kind of window, even * the desktop, will be returned in preference to a dock window. * - * \param stack The stack to search. - * \param workspace NULL to search all workspaces; otherwise only windows - * from that workspace will be returned. - * \param not_this_one Window to ignore because it's being unfocussed or - * going away. - * \param root_x The returned window must contain this point, - * unless it's a dock. - * \param root_y See root_x. - * \return The window matching all these constraints or NULL if none does. + * Returns: The window matching all these constraints or %NULL if none does. + */ +MetaWindow * meta_stack_get_default_focus_window_at_point (MetaStack *stack, + MetaWorkspace *workspace, + MetaWindow *not_this_one, + int root_x, + int root_y); + +/** + * meta_stack_get_default_focus_candidates: + * @stack: The stack to examine. + * @workspace: If not %NULL, only windows on this workspace will be + * returned; otherwise all windows in the stack will be + * returned. + * + * Returns all the focus candidate windows in the stack, in order. + * + * Returns: (transfer container) (element-type Meta.Window): + * A #GList of #MetaWindow, in stacking order, honouring layers. */ -MetaWindow* meta_stack_get_default_focus_window_at_point (MetaStack *stack, - MetaWorkspace *workspace, - MetaWindow *not_this_one, - int root_x, - int root_y); +GList * meta_stack_get_default_focus_candidates (MetaStack *stack, + MetaWorkspace *workspace); /** + * meta_stack_list_windows: + * @stack: The stack to examine. + * @workspace: If not %NULL, only windows on this workspace will be + * returned; otherwise all windows in the stack will be + * returned. + * * Finds all the windows in the stack, in order. * - * \param stack The stack to examine. - * \param workspace If non-NULL, only windows on this workspace will be - * returned; otherwise all windows in the stack will be - * returned. - * \return A list of windows, in stacking order, honouring layers. + * Returns: (transfer container) (element-type Meta.Window): + * A list of windows, in stacking order, honouring layers. */ -GList* meta_stack_list_windows (MetaStack *stack, - MetaWorkspace *workspace); +GList * meta_stack_list_windows (MetaStack *stack, + MetaWorkspace *workspace); /** + * meta_stack_windows_cmp: + * @stack: A stack containing both window_a and window_b + * @window_a: A window + * @window_b Another window + * * Comparison function for windows within a stack. This is not directly * suitable for use within a standard comparison routine, because it takes * an extra parameter; you will need to wrap it. @@ -339,49 +354,52 @@ GList* meta_stack_list_windows (MetaStack *stack, * * (FIXME: Apparently identical to compare_window_position(). Merge them.) * - * \param stack A stack containing both window_a and window_b - * \param window_a A window - * \param window_b Another window * \return -1 if window_a is below window_b, honouring layers; 1 if it's * above it; 0 if you passed in the same window twice! */ -int meta_stack_windows_cmp (MetaStack *stack, - MetaWindow *window_a, - MetaWindow *window_b); +int meta_stack_windows_cmp (MetaStack *stack, + MetaWindow *window_a, + MetaWindow *window_b); /** + * meta_window_set_stack_position: + * @window: The window which is moving. + * @position: Where it should move to (0 is the bottom). + * * Sets the position of a window within the stack. This will only move it * up or down within its layer. It is an error to attempt to move this * below position zero or above the last position in the stack (however, since * we don't provide a simple way to tell the number of windows in the stack, * this requirement may not be easy to fulfil). - * - * \param window The window which is moving. - * \param position Where it should move to (0 is the bottom). */ void meta_window_set_stack_position (MetaWindow *window, int position); /** + * meta_stack_get_positions: + * @stack: The stack to examine. + * * Returns the current stack state, allowing rudimentary transactions. * - * \param stack The stack to examine. - * \return An opaque GList representing the current stack sort order; - * it is the caller's responsibility to free it. - * Pass this to meta_stack_set_positions() later if you want to restore - * the state to where it was when you called this function. + * Returns: (transfer container) (element-type Meta.Window): + * An opaque #GList representing the current stack sort order; + * it is the caller's responsibility to free it. + * Pass this to meta_stack_set_positions() later if you want to restore + * the state to where it was when you called this function. */ -GList* meta_stack_get_positions (MetaStack *stack); +GList * meta_stack_get_positions (MetaStack *stack); /** + * meta_stack_set_positions: + * @stack: The stack to roll back. + * @windows: The list returned from meta_stack_get_positions(). + * * Rolls back a transaction, given the list returned from * meta_stack_get_positions(). * - * \param stack The stack to roll back. - * \param windows The list returned from meta_stack_get_positions(). */ -void meta_stack_set_positions (MetaStack *stack, - GList *windows); +void meta_stack_set_positions (MetaStack *stack, + GList *windows); void meta_stack_update_window_tile_matches (MetaStack *stack, MetaWorkspace *workspace); diff --git a/src/core/startup-notification-private.h b/src/core/startup-notification-private.h new file mode 100644 index 000000000..5bdf2ac1a --- /dev/null +++ b/src/core/startup-notification-private.h @@ -0,0 +1,52 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001, 2002 Havoc Pennington + * Copyright (C) 2002, 2003 Red Hat Inc. + * Some ICCCM manager selection code derived from fvwm2, + * Copyright (C) 2001 Dominik Vogt, Matthias Clasen, and fvwm2 team + * Copyright (C) 2003 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef META_STARTUP_NOTIFICATION_PRIVATE_H +#define META_STARTUP_NOTIFICATION_PRIVATE_H + +#include "core/display-private.h" +#include "meta/meta-startup-notification.h" + +struct _MetaStartupSequenceClass +{ + GObjectClass parent_class; + + void (* complete) (MetaStartupSequence *sequence); +}; + +MetaStartupNotification * + meta_startup_notification_new (MetaDisplay *display); + +gboolean meta_startup_notification_handle_xevent (MetaStartupNotification *sn, + XEvent *xevent); + +void meta_startup_notification_add_sequence (MetaStartupNotification *sn, + MetaStartupSequence *seq); +void meta_startup_notification_remove_sequence (MetaStartupNotification *sn, + MetaStartupSequence *seq); +MetaStartupSequence * + meta_startup_notification_lookup_sequence (MetaStartupNotification *sn, + const gchar *id); + +#endif /* META_STARTUP_NOTIFICATION_PRIVATE_H */ diff --git a/src/core/startup-notification.c b/src/core/startup-notification.c new file mode 100644 index 000000000..99c0d9d06 --- /dev/null +++ b/src/core/startup-notification.c @@ -0,0 +1,684 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001, 2002 Havoc Pennington + * Copyright (C) 2002, 2003 Red Hat Inc. + * Some ICCCM manager selection code derived from fvwm2, + * Copyright (C) 2001 Dominik Vogt, Matthias Clasen, and fvwm2 team + * Copyright (C) 2003 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <glib-object.h> + +#include "core/display-private.h" +#include "core/startup-notification-private.h" +#include "core/util-private.h" +#include "meta/meta-x11-errors.h" +#include "x11/meta-x11-display-private.h" + +/* This should be fairly long, as it should never be required unless + * apps or .desktop files are buggy, and it's confusing if + * OpenOffice or whatever seems to stop launching - people + * might decide they need to launch it again. + */ +#define STARTUP_TIMEOUT_MS 15000 + +enum +{ + PROP_0, + PROP_DISPLAY, + N_PROPS +}; + +enum +{ + PROP_SEQ_0, + PROP_SEQ_ID, + PROP_SEQ_TIMESTAMP, + PROP_SEQ_ICON_NAME, + PROP_SEQ_APPLICATION_ID, + PROP_SEQ_WMCLASS, + PROP_SEQ_WORKSPACE, + PROP_SEQ_NAME, + N_SEQ_PROPS +}; + +enum +{ + SEQ_COMPLETE, + N_SEQ_SIGNALS +}; + +enum +{ + CHANGED, + N_SIGNALS +}; + +static guint sn_signals[N_SIGNALS]; +static GParamSpec *sn_props[N_PROPS]; +static guint seq_signals[N_SEQ_SIGNALS]; +static GParamSpec *seq_props[N_SEQ_PROPS]; + +typedef struct +{ + GSList *list; + gint64 now; +} CollectTimedOutData; + +struct _MetaStartupNotification +{ + GObject parent_instance; + MetaDisplay *display; + + + GSList *startup_sequences; + guint startup_sequence_timeout; +}; + +typedef struct { + char *wmclass; + char *name; + char *application_id; + char *icon_name; + char *id; + uint64_t timestamp; + int workspace; + uint completed : 1; +} MetaStartupSequencePrivate; + +G_DEFINE_TYPE (MetaStartupNotification, + meta_startup_notification, + G_TYPE_OBJECT) +G_DEFINE_TYPE_WITH_PRIVATE (MetaStartupSequence, + meta_startup_sequence, + G_TYPE_OBJECT) + + +static void meta_startup_notification_ensure_timeout (MetaStartupNotification *sn); + +static gboolean +meta_startup_notification_has_pending_sequences (MetaStartupNotification *sn) +{ + GSList *l; + + for (l = sn->startup_sequences; l; l = l->next) + { + if (!meta_startup_sequence_get_completed (l->data)) + return TRUE; + } + + return FALSE; +} + +static void +meta_startup_notification_update_feedback (MetaStartupNotification *sn) +{ + MetaDisplay *display = sn->display; + + if (meta_startup_notification_has_pending_sequences (sn)) + { + meta_topic (META_DEBUG_STARTUP, + "Setting busy cursor\n"); + meta_display_set_cursor (display, META_CURSOR_BUSY); + } + else + { + meta_topic (META_DEBUG_STARTUP, + "Setting default cursor\n"); + meta_display_set_cursor (display, META_CURSOR_DEFAULT); + } +} + +static void +meta_startup_sequence_init (MetaStartupSequence *seq) +{ +} + +static void +meta_startup_sequence_finalize (GObject *object) +{ + MetaStartupSequence *seq; + MetaStartupSequencePrivate *priv; + + seq = META_STARTUP_SEQUENCE (object); + priv = meta_startup_sequence_get_instance_private (seq); + g_free (priv->id); + g_free (priv->wmclass); + g_free (priv->name); + g_free (priv->application_id); + g_free (priv->icon_name); + + G_OBJECT_CLASS (meta_startup_sequence_parent_class)->finalize (object); +} + +static void +meta_startup_sequence_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaStartupSequence *seq; + MetaStartupSequencePrivate *priv; + + seq = META_STARTUP_SEQUENCE (object); + priv = meta_startup_sequence_get_instance_private (seq); + + switch (prop_id) + { + case PROP_SEQ_ID: + priv->id = g_value_dup_string (value); + break; + case PROP_SEQ_TIMESTAMP: + priv->timestamp = g_value_get_uint64 (value); + break; + case PROP_SEQ_ICON_NAME: + priv->icon_name = g_value_dup_string (value); + break; + case PROP_SEQ_APPLICATION_ID: + priv->application_id = g_value_dup_string (value); + break; + case PROP_SEQ_WMCLASS: + priv->wmclass = g_value_dup_string (value); + break; + case PROP_SEQ_WORKSPACE: + priv->workspace = g_value_get_int (value); + break; + case PROP_SEQ_NAME: + priv->name = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_startup_sequence_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaStartupSequence *seq; + MetaStartupSequencePrivate *priv; + + seq = META_STARTUP_SEQUENCE (object); + priv = meta_startup_sequence_get_instance_private (seq); + + switch (prop_id) + { + case PROP_SEQ_ID: + g_value_set_string (value, priv->id); + break; + case PROP_SEQ_TIMESTAMP: + g_value_set_uint64 (value, priv->timestamp); + break; + case PROP_SEQ_ICON_NAME: + g_value_set_string (value, priv->icon_name); + break; + case PROP_SEQ_APPLICATION_ID: + g_value_set_string (value, priv->application_id); + break; + case PROP_SEQ_WMCLASS: + g_value_set_string (value, priv->wmclass); + break; + case PROP_SEQ_WORKSPACE: + g_value_set_int (value, priv->workspace); + break; + case PROP_SEQ_NAME: + g_value_set_string (value, priv->name); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_startup_sequence_class_init (MetaStartupSequenceClass *klass) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->finalize = meta_startup_sequence_finalize; + object_class->set_property = meta_startup_sequence_set_property; + object_class->get_property = meta_startup_sequence_get_property; + + seq_signals[SEQ_COMPLETE] = + g_signal_new ("complete", + META_TYPE_STARTUP_SEQUENCE, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (MetaStartupSequenceClass, complete), + NULL, NULL, NULL, + G_TYPE_NONE, 0); + + seq_props[PROP_SEQ_ID] = + g_param_spec_string ("id", + "ID", + "ID", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY); + seq_props[PROP_SEQ_TIMESTAMP] = + g_param_spec_uint64 ("timestamp", + "Timestamp", + "Timestamp", + 0, G_MAXUINT64, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY); + seq_props[PROP_SEQ_ICON_NAME] = + g_param_spec_string ("icon-name", + "Icon name", + "Icon name", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY); + seq_props[PROP_SEQ_APPLICATION_ID] = + g_param_spec_string ("application-id", + "Application ID", + "Application ID", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY); + seq_props[PROP_SEQ_WMCLASS] = + g_param_spec_string ("wmclass", + "WM class", + "WM class", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY); + seq_props[PROP_SEQ_WORKSPACE] = + g_param_spec_int ("workspace", + "Workspace", + "Workspace", + G_MININT, G_MAXINT, -1, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY); + seq_props[PROP_SEQ_NAME] = + g_param_spec_string ("name", + "Name", + "Name", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY); + + g_object_class_install_properties (object_class, N_SEQ_PROPS, seq_props); +} + +const char * +meta_startup_sequence_get_id (MetaStartupSequence *seq) +{ + MetaStartupSequencePrivate *priv; + + g_return_val_if_fail (META_IS_STARTUP_SEQUENCE (seq), NULL); + + priv = meta_startup_sequence_get_instance_private (seq); + return priv->id; +} + +uint64_t +meta_startup_sequence_get_timestamp (MetaStartupSequence *seq) +{ + MetaStartupSequencePrivate *priv; + + g_return_val_if_fail (META_IS_STARTUP_SEQUENCE (seq), 0); + + priv = meta_startup_sequence_get_instance_private (seq); + return priv->timestamp; +} + +void +meta_startup_sequence_complete (MetaStartupSequence *seq) +{ + MetaStartupSequencePrivate *priv; + + g_return_if_fail (META_IS_STARTUP_SEQUENCE (seq)); + + priv = meta_startup_sequence_get_instance_private (seq); + if (priv->completed) + return; + + priv->completed = TRUE; + g_signal_emit (seq, seq_signals[SEQ_COMPLETE], 0); +} + +gboolean +meta_startup_sequence_get_completed (MetaStartupSequence *seq) +{ + MetaStartupSequencePrivate *priv; + + g_return_val_if_fail (META_IS_STARTUP_SEQUENCE (seq), FALSE); + + priv = meta_startup_sequence_get_instance_private (seq); + return priv->completed; +} + +const char * +meta_startup_sequence_get_name (MetaStartupSequence *seq) +{ + MetaStartupSequencePrivate *priv; + + g_return_val_if_fail (META_IS_STARTUP_SEQUENCE (seq), NULL); + + priv = meta_startup_sequence_get_instance_private (seq); + return priv->name; +} + +int +meta_startup_sequence_get_workspace (MetaStartupSequence *seq) +{ + MetaStartupSequencePrivate *priv; + + g_return_val_if_fail (META_IS_STARTUP_SEQUENCE (seq), 0); + + priv = meta_startup_sequence_get_instance_private (seq); + return priv->workspace; +} + +const char * +meta_startup_sequence_get_icon_name (MetaStartupSequence *seq) +{ + MetaStartupSequencePrivate *priv; + + g_return_val_if_fail (META_IS_STARTUP_SEQUENCE (seq), NULL); + + priv = meta_startup_sequence_get_instance_private (seq); + return priv->icon_name; +} + +const char * +meta_startup_sequence_get_application_id (MetaStartupSequence *seq) +{ + MetaStartupSequencePrivate *priv; + + g_return_val_if_fail (META_IS_STARTUP_SEQUENCE (seq), NULL); + + priv = meta_startup_sequence_get_instance_private (seq); + return priv->application_id; +} + +const char * +meta_startup_sequence_get_wmclass (MetaStartupSequence *seq) +{ + MetaStartupSequencePrivate *priv; + + g_return_val_if_fail (META_IS_STARTUP_SEQUENCE (seq), NULL); + + priv = meta_startup_sequence_get_instance_private (seq); + return priv->wmclass; +} + +static void +on_sequence_completed (MetaStartupSequence *seq, + MetaStartupNotification *sn) +{ + meta_startup_notification_update_feedback (sn); + g_signal_emit (sn, sn_signals[CHANGED], 0, seq); +} + +void +meta_startup_notification_add_sequence (MetaStartupNotification *sn, + MetaStartupSequence *seq) +{ + sn->startup_sequences = g_slist_prepend (sn->startup_sequences, + g_object_ref (seq)); + g_signal_connect (seq, "complete", + G_CALLBACK (on_sequence_completed), sn); + + meta_startup_notification_ensure_timeout (sn); + meta_startup_notification_update_feedback (sn); + + g_signal_emit (sn, sn_signals[CHANGED], 0, seq); +} + +static void +collect_timed_out_foreach (void *element, + void *data) +{ + MetaStartupSequence *sequence = element; + CollectTimedOutData *ctod = data; + gint64 elapsed, timestamp; + + timestamp = meta_startup_sequence_get_timestamp (sequence); + elapsed = ctod->now - timestamp; + + meta_topic (META_DEBUG_STARTUP, + "Sequence used %" G_GINT64_FORMAT " ms vs. %d max: %s\n", + elapsed, STARTUP_TIMEOUT_MS, + meta_startup_sequence_get_id (sequence)); + + if (elapsed > STARTUP_TIMEOUT_MS) + ctod->list = g_slist_prepend (ctod->list, sequence); +} + +static gboolean +startup_sequence_timeout (void *data) +{ + MetaStartupNotification *sn = data; + CollectTimedOutData ctod; + GSList *l; + + ctod.list = NULL; + ctod.now = g_get_monotonic_time () / 1000; + g_slist_foreach (sn->startup_sequences, + collect_timed_out_foreach, + &ctod); + + for (l = ctod.list; l != NULL; l = l->next) + { + MetaStartupSequence *sequence = l->data; + + meta_topic (META_DEBUG_STARTUP, + "Timed out sequence %s\n", + meta_startup_sequence_get_id (sequence)); + + meta_startup_sequence_complete (sequence); + meta_startup_notification_remove_sequence (sn, sequence); + } + + g_slist_free (ctod.list); + + if (sn->startup_sequences != NULL) + { + return TRUE; + } + else + { + /* remove */ + sn->startup_sequence_timeout = 0; + return FALSE; + } +} + +static void +meta_startup_notification_ensure_timeout (MetaStartupNotification *sn) +{ + if (sn->startup_sequence_timeout != 0) + return; + + /* our timeout just polls every second, instead of bothering + * to compute exactly when we may next time out + */ + sn->startup_sequence_timeout = g_timeout_add_seconds (1, + startup_sequence_timeout, + sn); + g_source_set_name_by_id (sn->startup_sequence_timeout, + "[mutter] startup_sequence_timeout"); +} + +void +meta_startup_notification_remove_sequence (MetaStartupNotification *sn, + MetaStartupSequence *seq) +{ + sn->startup_sequences = g_slist_remove (sn->startup_sequences, seq); + meta_startup_notification_update_feedback (sn); + + g_signal_handlers_disconnect_by_func (seq, on_sequence_completed, sn); + + if (sn->startup_sequences == NULL) + g_clear_handle_id (&sn->startup_sequence_timeout, g_source_remove); + + g_signal_emit (sn, sn_signals[CHANGED], 0, seq); + g_object_unref (seq); +} + +MetaStartupSequence * +meta_startup_notification_lookup_sequence (MetaStartupNotification *sn, + const gchar *id) +{ + MetaStartupSequence *seq; + const gchar *seq_id; + GSList *l; + + for (l = sn->startup_sequences; l; l = l->next) + { + seq = l->data; + seq_id = meta_startup_sequence_get_id (seq); + + if (g_str_equal (seq_id, id)) + return l->data; + } + + return NULL; +} + +static void +meta_startup_notification_init (MetaStartupNotification *sn) +{ +} + +static void +meta_startup_notification_finalize (GObject *object) +{ + MetaStartupNotification *sn = META_STARTUP_NOTIFICATION (object); + + g_clear_handle_id (&sn->startup_sequence_timeout, g_source_remove); + + g_slist_free_full (sn->startup_sequences, g_object_unref); + sn->startup_sequences = NULL; + + G_OBJECT_CLASS (meta_startup_notification_parent_class)->finalize (object); +} + +static void +meta_startup_notification_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaStartupNotification *sn = META_STARTUP_NOTIFICATION (object); + + switch (prop_id) + { + case PROP_DISPLAY: + sn->display = g_value_get_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_startup_notification_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaStartupNotification *sn = META_STARTUP_NOTIFICATION (object); + + switch (prop_id) + { + case PROP_DISPLAY: + g_value_set_object (value, sn->display); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_startup_notification_constructed (GObject *object) +{ + MetaStartupNotification *sn = META_STARTUP_NOTIFICATION (object); + + g_assert (sn->display != NULL); + + sn->startup_sequences = NULL; + sn->startup_sequence_timeout = 0; +} + +static void +meta_startup_notification_class_init (MetaStartupNotificationClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->constructed = meta_startup_notification_constructed; + object_class->finalize = meta_startup_notification_finalize; + object_class->set_property = meta_startup_notification_set_property; + object_class->get_property = meta_startup_notification_get_property; + + sn_props[PROP_DISPLAY] = + g_param_spec_object ("display", + "Display", + "Display", + META_TYPE_DISPLAY, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + sn_signals[CHANGED] = + g_signal_new ("changed", + META_TYPE_STARTUP_NOTIFICATION, + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 1, G_TYPE_POINTER); + + g_object_class_install_properties (object_class, N_PROPS, sn_props); +} + +MetaStartupNotification * +meta_startup_notification_new (MetaDisplay *display) +{ + return g_object_new (META_TYPE_STARTUP_NOTIFICATION, + "display", display, + NULL); +} + +GSList * +meta_startup_notification_get_sequences (MetaStartupNotification *sn) +{ + return sn->startup_sequences; +} + +/** + * meta_startup_notification_create_launcher: + * @sn: a #MetaStartupNotification + * + * Creates an app launch context. + * + * Returns: (transfer full): a launch context. + **/ +MetaLaunchContext * +meta_startup_notification_create_launcher (MetaStartupNotification *sn) +{ + return g_object_new (META_TYPE_LAUNCH_CONTEXT, + "display", sn->display, + NULL); +} diff --git a/src/core/testasyncgetprop.c b/src/core/testasyncgetprop.c deleted file mode 100644 index a14c494d2..000000000 --- a/src/core/testasyncgetprop.c +++ /dev/null @@ -1,496 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* - * Copyright (C) 2002 Havoc Pennington - * - * Permission to use, copy, modify, distribute, and sell this software - * and its documentation for any purpose is hereby granted without - * fee, provided that the above copyright notice appear in all copies - * and that both that copyright notice and this permission notice - * appear in supporting documentation. - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Except as contained in this notice, the name of The Open Group shall not be - * used in advertising or otherwise to promote the sale, use or other dealings - * in this Software without prior written authorization from The Open Group. - */ - -#include "async-getprop.h" - -#include <time.h> -#include <sys/time.h> -#include <sys/types.h> -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> -#include <signal.h> -#include <assert.h> - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef NULL -#define NULL ((void*) 0) -#endif - -#ifdef HAVE_BACKTRACE -#include <execinfo.h> -static void -print_backtrace (void) -{ - void *bt[500]; - int bt_size; - int i; - char **syms; - - bt_size = backtrace (bt, 500); - - syms = backtrace_symbols (bt, bt_size); - - i = 0; - while (i < bt_size) - { - fprintf (stderr, " %s\n", syms[i]); - ++i; - } - - free (syms); -} -#else -static void -print_backtrace (void) -{ - fprintf (stderr, "Not compiled with backtrace support\n"); -} -#endif - -static int error_trap_depth = 0; - -static int -x_error_handler (Display *xdisplay, - XErrorEvent *error) -{ - char buf[64]; - - XGetErrorText (xdisplay, error->error_code, buf, 63); - - if (error_trap_depth == 0) - { - print_backtrace (); - - fprintf (stderr, "Unexpected X error: %s serial %ld error_code %d request_code %d minor_code %d)\n", - buf, - error->serial, - error->error_code, - error->request_code, - error->minor_code); - - exit (1); - } - - return 1; /* return value is meaningless */ -} - -static void -error_trap_push (Display *xdisplay) -{ - ++error_trap_depth; -} - -static void -error_trap_pop (Display *xdisplay) -{ - if (error_trap_depth == 0) - { - fprintf (stderr, "Error trap underflow!\n"); - exit (1); - } - - XSync (xdisplay, False); /* get all errors out of the queue */ - --error_trap_depth; -} - -static char* -my_strdup (const char *str) -{ - char *s; - - s = malloc (strlen (str) + 1); - if (s == NULL) - { - fprintf (stderr, "malloc failed\n"); - exit (1); - } - strcpy (s, str); - - return s; -} - -static char* -atom_name (Display *display, - Atom atom) -{ - if (atom == None) - { - return my_strdup ("None"); - } - else - { - char *xname; - char *ret; - - error_trap_push (display); - xname = XGetAtomName (display, atom); - error_trap_pop (display); - if (xname == NULL) - return my_strdup ("[unknown atom]"); - - ret = my_strdup (xname); - XFree (xname); - - return ret; - } -} - - -#define ELAPSED(start_time, current_time) \ - (((((double)current_time.tv_sec - start_time.tv_sec) * 1000000 + \ - (current_time.tv_usec - start_time.tv_usec))) / 1000.0) - -static struct timeval program_start_time; - -static Bool -try_get_reply (Display *xdisplay, - AgGetPropertyTask *task) -{ - if (ag_task_have_reply (task)) - { - int result; - Atom actual_type; - int actual_format; - unsigned long n_items; - unsigned long bytes_after; - unsigned char *data; - char *name; - struct timeval current_time; - - gettimeofday (¤t_time, NULL); - - printf (" %gms (we have a reply for property %ld)\n", - ELAPSED (program_start_time, current_time), - ag_task_get_property (task)); - - data = NULL; - - name = atom_name (xdisplay, - ag_task_get_property (task)); - printf (" %s on 0x%lx:\n", name, - ag_task_get_window (task)); - free (name); - - result = ag_task_get_reply_and_free (task, - &actual_type, - &actual_format, - &n_items, - &bytes_after, - &data); - task = NULL; - - if (result != Success) - { - fprintf (stderr, " error code %d getting reply\n", result); - } - else - { - name = atom_name (xdisplay, actual_type); - printf (" actual_type = %s\n", name); - free (name); - - printf (" actual_format = %d\n", actual_format); - - printf (" n_items = %lu\n", n_items); - printf (" bytes_after = %lu\n", bytes_after); - - printf (" data = \"%s\"\n", data ? (char*) data : "NULL"); - } - - return True; - } - - return False; -} - -static void run_speed_comparison (Display *xdisplay, - Window window); - -int -main (int argc, char **argv) -{ - Display *xdisplay; - int i; - int n_left; - int n_props; - Window window; - const char *window_str; - char *end; - Atom *props; - struct timeval current_time; - - if (argc < 2) - { - fprintf (stderr, "specify window ID\n"); - return 1; - } - - window_str = argv[1]; - - end = NULL; - window = strtoul (window_str, &end, 0); - if (end == NULL || *end != '\0') - { - fprintf (stderr, "\"%s\" does not parse as a window ID\n", window_str); - return 1; - } - - xdisplay = XOpenDisplay (NULL); - if (xdisplay == NULL) - { - fprintf (stderr, "Could not open display\n"); - return 1; - } - - if (getenv ("MUFFIN_SYNC") != NULL) - XSynchronize (xdisplay, True); - - XSetErrorHandler (x_error_handler); - - n_props = 0; - props = XListProperties (xdisplay, window, &n_props); - if (n_props == 0 || props == NULL) - { - fprintf (stderr, "Window has no properties\n"); - return 1; - } - - gettimeofday (&program_start_time, NULL); - - i = 0; - while (i < n_props) - { - gettimeofday (¤t_time, NULL); - printf (" %gms (sending request for property %ld)\n", - ELAPSED (program_start_time, current_time), - props[i]); - if (ag_task_create (xdisplay, - window, props[i], - 0, 0xffffffff, - False, - AnyPropertyType) == NULL) - { - fprintf (stderr, "Failed to send request\n"); - return 1; - } - - ++i; - } - - XFree (props); - props = NULL; - - n_left = n_props; - - while (TRUE) - { - XEvent xevent; - int connection; - fd_set set; - AgGetPropertyTask *task; - - /* Mop up event queue */ - while (XPending (xdisplay) > 0) - { - XNextEvent (xdisplay, &xevent); - gettimeofday (¤t_time, NULL); - printf (" %gms (processing event type %d)\n", - ELAPSED (program_start_time, current_time), - xevent.xany.type); - } - - while ((task = ag_get_next_completed_task (xdisplay))) - { - try_get_reply (xdisplay, task); - n_left -= 1; - } - - if (n_left == 0) - { - printf ("All %d replies received.\n", n_props); - break; - } - - /* Wake up if we may have a reply */ - connection = ConnectionNumber (xdisplay); - - FD_ZERO (&set); - FD_SET (connection, &set); - - gettimeofday (¤t_time, NULL); - printf (" %gms (blocking for data %d left)\n", - ELAPSED (program_start_time, current_time), n_left); - select (connection + 1, &set, NULL, NULL, NULL); - } - - run_speed_comparison (xdisplay, window); - - return 0; -} - -/* This function doesn't have all the printf's - * and other noise, it just compares async to sync - */ -static void -run_speed_comparison (Display *xdisplay, - Window window) -{ - int i; - int n_props; - struct timeval start, end; - int n_left; - - /* We just use atom values (0 to n_props) % 200, many are probably - * BadAtom, that's fine, but the %200 keeps most of them valid. The - * async case is about twice as advantageous when using valid atoms - * (or the issue may be that it's more advantageous when the - * properties are present and data is transmitted). - */ - n_props = 4000; - printf ("Timing with %d property requests\n", n_props); - - gettimeofday (&start, NULL); - - i = 0; - while (i < n_props) - { - if (ag_task_create (xdisplay, - window, (Atom) i % 200, - 0, 0xffffffff, - False, - AnyPropertyType) == NULL) - { - fprintf (stderr, "Failed to send request\n"); - exit (1); - } - - ++i; - } - - n_left = n_props; - - while (TRUE) - { - int connection; - fd_set set; - XEvent xevent; - AgGetPropertyTask *task; - - /* Mop up event queue */ - while (XPending (xdisplay) > 0) - XNextEvent (xdisplay, &xevent); - - while ((task = ag_get_next_completed_task (xdisplay))) - { - Atom actual_type; - int actual_format; - unsigned long n_items; - unsigned long bytes_after; - unsigned char *data; - - assert (ag_task_have_reply (task)); - - data = NULL; - ag_task_get_reply_and_free (task, - &actual_type, - &actual_format, - &n_items, - &bytes_after, - &data); - - if (data) - XFree (data); - - n_left -= 1; - } - - if (n_left == 0) - break; - - /* Wake up if we may have a reply */ - connection = ConnectionNumber (xdisplay); - - FD_ZERO (&set); - FD_SET (connection, &set); - - select (connection + 1, &set, NULL, NULL, NULL); - } - - gettimeofday (&end, NULL); - - printf ("Async time: %gms\n", - ELAPSED (start, end)); - - gettimeofday (&start, NULL); - - error_trap_push (xdisplay); - - i = 0; - while (i < n_props) - { - Atom actual_type; - int actual_format; - unsigned long n_items; - unsigned long bytes_after; - unsigned char *data; - - data = NULL; - if (XGetWindowProperty (xdisplay, window, - (Atom) i % 200, - 0, 0xffffffff, - False, - AnyPropertyType, - &actual_type, - &actual_format, - &n_items, - &bytes_after, - &data) == Success) - { - if (data) - XFree (data); - } - - ++i; - } - - error_trap_pop (xdisplay); - - gettimeofday (&end, NULL); - - printf ("Sync time: %gms\n", - ELAPSED (start, end)); -} diff --git a/src/core/util-private.h b/src/core/util-private.h index 8e51b42f4..0d68a7202 100644 --- a/src/core/util-private.h +++ b/src/core/util-private.h @@ -2,10 +2,10 @@ /* Mutter utilities */ -/* +/* * Copyright (C) 2001 Havoc Pennington * Copyright (C) 2005 Elijah Newren - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the @@ -15,7 +15,7 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA @@ -25,12 +25,22 @@ #ifndef META_UTIL_PRIVATE_H #define META_UTIL_PRIVATE_H -#include <meta/util.h> #include <glib/gi18n-lib.h> +#include "meta/util.h" +#include "meta/common.h" + +/* META_EXPORT_TEST should be used to export symbols that are exported only + * for testability purposes */ +#define META_EXPORT_TEST META_EXPORT + void meta_set_verbose (gboolean setting); void meta_set_debugging (gboolean setting); void meta_set_syncing (gboolean setting); void meta_set_replace_current_wm (gboolean setting); +void meta_set_is_wayland_compositor (gboolean setting); + +char * meta_generate_random_id (GRand *rand, + int length); #endif diff --git a/src/core/util.c b/src/core/util.c index 53a1fb34d..3854b3737 100644 --- a/src/core/util.c +++ b/src/core/util.c @@ -1,7 +1,5 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* Muffin utilities */ - /* * Copyright (C) 2001 Havoc Pennington * Copyright (C) 2005 Elijah Newren @@ -17,9 +15,7 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ /** @@ -28,74 +24,40 @@ * @short_description: Miscellaneous utility functions */ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif #define _POSIX_C_SOURCE 200112L /* for fdopen() */ -#include <config.h> -#include <meta/common.h> -#include "util-private.h" -#include <meta/main.h> +#include "config.h" -#include <clutter/clutter.h> /* For clutter_threads_add_repaint_func() */ +#include "core/util-private.h" #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> -#include <dirent.h> #include <string.h> -#include <fcntl.h> -#include <unistd.h> -#ifdef HAVE_SYS_RESOURCE_H -#include <sys/resource.h> -#endif #include <X11/Xlib.h> /* must explicitly be included for Solaris; #326746 */ #include <X11/Xutil.h> /* Just for the definition of the various gravities */ +#include "clutter/clutter.h" +#include "cogl/cogl.h" +#include "meta/common.h" +#include "meta/main.h" + #ifdef WITH_VERBOSE_MODE static void meta_topic_real_valist (MetaDebugTopic topic, const char *format, - va_list args); + va_list args) G_GNUC_PRINTF(2, 0); #endif -#ifdef HAVE_BACKTRACE -#include <execinfo.h> -void -meta_print_backtrace (void) -{ - void *bt[500]; - int bt_size; - int i; - char **syms; - - bt_size = backtrace (bt, 500); - - syms = backtrace_symbols (bt, bt_size); - - i = 0; - while (i < bt_size) - { - meta_verbose (" %s\n", syms[i]); - ++i; - } - - free (syms); -} -#else -void -meta_print_backtrace (void) -{ - meta_verbose ("Not compiled with backtrace support\n"); -} -#endif +static gboolean +meta_later_remove_from_list (guint later_id, GSList **laters_list); static gint verbose_topics = 0; static gboolean is_debugging = FALSE; static gboolean replace_current = FALSE; static int no_prefix = 0; +static gboolean is_wayland_compositor = FALSE; #ifdef WITH_VERBOSE_MODE static FILE* logfile = NULL; @@ -103,14 +65,14 @@ static FILE* logfile = NULL; static void ensure_logfile (void) { - if (logfile == NULL && g_getenv ("MUFFIN_USE_LOGFILE")) + if (logfile == NULL && g_getenv ("MUTTER_USE_LOGFILE")) { char *filename = NULL; char *tmpl; int fd; GError *err; - tmpl = g_strdup_printf ("muffin-%d-debug-log-XXXXXX", + tmpl = g_strdup_printf ("mutter-%d-debug-log-XXXXXX", (int) getpid ()); err = NULL; @@ -118,7 +80,7 @@ ensure_logfile (void) &filename, &err); - free (tmpl); + g_free (tmpl); if (err != NULL) { @@ -138,10 +100,10 @@ ensure_logfile (void) } else { - g_printerr ("Opened log file %s\n"), filename; + g_printerr ("Opened log file %s\n", filename); } - free (filename); + g_free (filename); } } #endif @@ -157,7 +119,7 @@ meta_set_verbose (gboolean setting) { #ifndef WITH_VERBOSE_MODE if (setting) - meta_fatal ("Muffin was compiled without support for verbose mode\n"); + meta_fatal (_("Mutter was compiled without support for verbose mode\n")); #else if (setting) ensure_logfile (); @@ -235,6 +197,18 @@ meta_set_replace_current_wm (gboolean setting) replace_current = setting; } +gboolean +meta_is_wayland_compositor (void) +{ + return is_wayland_compositor; +} + +void +meta_set_is_wayland_compositor (gboolean value) +{ + is_wayland_compositor = value; +} + char * meta_g_utf8_strndup (const gchar *src, gsize n) @@ -263,24 +237,11 @@ utf8_fputs (const char *str, else retval = fputs (l, f); - free (l); + g_free (l); return retval; } -/** - * meta_free_gslist_and_elements: (skip) - * - */ -void -meta_free_gslist_and_elements (GSList *list_to_deep_free) -{ - g_slist_foreach (list_to_deep_free, - (void (*)(gpointer,gpointer))&free, /* ew, for ugly */ - NULL); - g_slist_free (list_to_deep_free); -} - #ifdef WITH_VERBOSE_MODE void meta_debug_spew_real (const char *format, ...) @@ -301,12 +262,12 @@ meta_debug_spew_real (const char *format, ...) out = logfile ? logfile : stderr; if (no_prefix == 0) - utf8_fputs ("muffin: ", out); + utf8_fputs ("Window manager: ", out); utf8_fputs (str, out); fflush (out); - free (str); + g_free (str); } #endif /* WITH_VERBOSE_MODE */ @@ -372,10 +333,12 @@ topic_name (MetaDebugTopic topic) return "COMPOSITOR"; case META_DEBUG_EDGE_RESISTANCE: return "EDGE_RESISTANCE"; + case META_DEBUG_DBUS: + return "DBUS"; + case META_DEBUG_INPUT: + return "INPUT"; case META_DEBUG_VERBOSE: return "VERBOSE"; - default: - break; } return "WM"; @@ -415,7 +378,7 @@ meta_topic_real_valist (MetaDebugTopic topic, fflush (out); - free (str); + g_free (str); } void @@ -451,14 +414,12 @@ meta_bug (const char *format, ...) #endif if (no_prefix == 0) - utf8_fputs ("Bug in muffin: ", out); + utf8_fputs ("Bug in window manager: ", out); utf8_fputs (str, out); fflush (out); - free (str); - - meta_print_backtrace (); + g_free (str); /* stop us in a debugger */ abort (); @@ -484,12 +445,12 @@ meta_warning (const char *format, ...) #endif if (no_prefix == 0) - utf8_fputs ("Cinnamon warning: ", out); + utf8_fputs ("Window manager warning: ", out); utf8_fputs (str, out); fflush (out); - free (str); + g_free (str); } void @@ -499,7 +460,9 @@ meta_fatal (const char *format, ...) gchar *str; FILE *out; - g_return_if_fail (format != NULL); + g_warn_if_fail (format); + if (!format) + meta_exit (META_EXIT_ERROR); va_start (args, format); str = g_strdup_vprintf (format, args); @@ -512,12 +475,12 @@ meta_fatal (const char *format, ...) #endif if (no_prefix == 0) - utf8_fputs ("Cinnamon error: ", out); + utf8_fputs ("Window manager error: ", out); utf8_fputs (str, out); fflush (out); - free (str); + g_free (str); meta_exit (META_EXIT_ERROR); } @@ -564,46 +527,52 @@ meta_unsigned_long_hash (gconstpointer v) } const char* -meta_gravity_to_string (int gravity) +meta_gravity_to_string (MetaGravity gravity) { switch (gravity) { - case NorthWestGravity: - return "NorthWestGravity"; + case META_GRAVITY_NORTH_WEST: + return "META_GRAVITY_NORTH_WEST"; break; - case NorthGravity: - return "NorthGravity"; + case META_GRAVITY_NORTH: + return "META_GRAVITY_NORTH"; break; - case NorthEastGravity: - return "NorthEastGravity"; + case META_GRAVITY_NORTH_EAST: + return "META_GRAVITY_NORTH_EAST"; break; - case WestGravity: - return "WestGravity"; + case META_GRAVITY_WEST: + return "META_GRAVITY_WEST"; break; - case CenterGravity: - return "CenterGravity"; + case META_GRAVITY_CENTER: + return "META_GRAVITY_CENTER"; break; - case EastGravity: - return "EastGravity"; + case META_GRAVITY_EAST: + return "META_GRAVITY_EAST"; break; - case SouthWestGravity: - return "SouthWestGravity"; + case META_GRAVITY_SOUTH_WEST: + return "META_GRAVITY_SOUTH_WEST"; break; - case SouthGravity: - return "SouthGravity"; + case META_GRAVITY_SOUTH: + return "META_GRAVITY_SOUTH"; break; - case SouthEastGravity: - return "SouthEastGravity"; + case META_GRAVITY_SOUTH_EAST: + return "META_GRAVITY_SOUTH_EAST"; break; - case StaticGravity: - return "StaticGravity"; + case META_GRAVITY_STATIC: + return "META_GRAVITY_STATIC"; break; default: - return "NorthWestGravity"; + return "META_GRAVITY_NORTH_WEST"; break; } } +char* +meta_external_binding_name_for_action (guint keybinding_action) +{ + return g_strdup_printf ("external-grab-%u", keybinding_action); +} + /* Command line arguments are passed in the locale encoding; in almost * all cases, we'd hope that is UTF-8 and no conversion is necessary. * If it's not UTF-8, then it's possible that the message isn't @@ -625,6 +594,16 @@ append_argument (GPtrArray *args, /** * meta_show_dialog: (skip) + * @type: type of dialog + * @message: message + * @timeout: timeout + * @display: display + * @ok_text: text for Ok button + * @cancel_text: text for Cancel button + * @icon_name: icon name + * @transient_for: window XID of parent + * @columns: columns + * @entries: entries * */ GPid @@ -634,6 +613,7 @@ meta_show_dialog (const char *type, const char *display, const char *ok_text, const char *cancel_text, + const char *icon_name, const int transient_for, GSList *columns, GSList *entries) @@ -647,16 +627,19 @@ meta_show_dialog (const char *type, append_argument (args, "zenity"); append_argument (args, type); - append_argument (args, "--display"); - append_argument (args, display); + + if (display) + { + append_argument (args, "--display"); + append_argument (args, display); + } + append_argument (args, "--class"); - append_argument (args, "muffin-dialog"); + append_argument (args, "mutter-dialog"); append_argument (args, "--title"); append_argument (args, ""); append_argument (args, "--text"); append_argument (args, message); - append_argument (args, "--width"); - append_argument (args, "400"); if (timeout) { @@ -676,6 +659,12 @@ meta_show_dialog (const char *type, append_argument (args, cancel_text); } + if (icon_name) + { + append_argument (args, "--icon-name"); + append_argument (args, icon_name); + } + tmp = columns; while (tmp) { @@ -691,15 +680,17 @@ meta_show_dialog (const char *type, tmp = tmp->next; } - g_ptr_array_add (args, NULL); /* NULL-terminate */ - if (transient_for) { gchar *env = g_strdup_printf("%d", transient_for); setenv ("WINDOWID", env, 1); - free (env); + g_free (env); + + append_argument (args, "--modal"); } + g_ptr_array_add (args, NULL); /* NULL-terminate */ + g_spawn_async ( "/", (gchar**) args->pdata, @@ -742,7 +733,14 @@ typedef struct gboolean run_once; } MetaLater; -static GSList *laters = NULL; +static GSList *laters[] = { + NULL, /* META_LATER_RESIZE */ + NULL, /* META_LATER_CALC_SHOWING */ + NULL, /* META_LATER_CHECK_FULLSCREEN */ + NULL, /* META_LATER_SYNC_STACK */ + NULL, /* META_LATER_BEFORE_REDRAW */ + NULL, /* META_LATER_IDLE */ +}; /* This is a dummy timeline used to get the Clutter master clock running */ static ClutterTimeline *later_timeline; static guint later_repaint_func = 0; @@ -766,34 +764,50 @@ unref_later (MetaLater *later) static void destroy_later (MetaLater *later) { - if (later->source) - { - g_source_remove (later->source); - later->source = 0; - } + g_clear_handle_id (&later->source, g_source_remove); later->func = NULL; unref_later (later); } -/* Used to sort the list of laters with the highest priority - * functions first. - */ -static int -compare_laters (gconstpointer a, - gconstpointer b) +#ifdef COGL_HAS_TRACING +static const char * +later_type_to_string (MetaLaterType when) { - return ((const MetaLater *)a)->when - ((const MetaLater *)b)->when; + switch (when) + { + case META_LATER_RESIZE: + return "Later (resize)"; + case META_LATER_CALC_SHOWING: + return "Later (calc-showing)"; + case META_LATER_CHECK_FULLSCREEN: + return "Later (check-fullscreen)"; + case META_LATER_SYNC_STACK: + return "Later (sync-stack)"; + case META_LATER_BEFORE_REDRAW: + return "Later (before-redraw)"; + case META_LATER_IDLE: + return "Later (idle)"; + } + + return "unknown"; } +#endif static gboolean -run_repaint_laters (gpointer data) +call_later_func (MetaLater *later) +{ + COGL_TRACE_BEGIN_SCOPED (later, later_type_to_string (later->when)); + return later->func (later->data); +} + +static void +run_repaint_laters (GSList **laters_list) { GSList *laters_copy; GSList *l; - gboolean keep_timeline_running = FALSE; laters_copy = NULL; - for (l = laters; l; l = l->next) + for (l = *laters_list; l; l = l->next) { MetaLater *later = l->data; if (later->source == 0 || @@ -809,22 +823,41 @@ run_repaint_laters (gpointer data) { MetaLater *later = l->data; - if (later->func && later->func (later->data)) + if (!later->func || !call_later_func (later)) + meta_later_remove_from_list (later->id, laters_list); + unref_later (later); + } + + g_slist_free (laters_copy); +} + +static gboolean +run_all_repaint_laters (gpointer data) +{ + guint i; + GSList *l; + gboolean keep_timeline_running = FALSE; + + for (i = 0; i < G_N_ELEMENTS (laters); i++) + { + run_repaint_laters (&laters[i]); + } + + for (i = 0; i < G_N_ELEMENTS (laters); i++) + { + for (l = laters[i]; l; l = l->next) { + MetaLater *later = l->data; + if (later->source == 0) keep_timeline_running = TRUE; } - else - meta_later_remove (later->id); - unref_later (later); } if (!keep_timeline_running) clutter_timeline_stop (later_timeline); - g_slist_free (laters_copy); - - /* Just keep the repaint func around - it's cheap if the list is empty */ + /* Just keep the repaint func around - it's cheap if the lists are empty */ return TRUE; } @@ -835,7 +868,7 @@ ensure_later_repaint_func (void) later_timeline = clutter_timeline_new (G_MAXUINT); if (later_repaint_func == 0) - later_repaint_func = clutter_threads_add_repaint_func (run_repaint_laters, + later_repaint_func = clutter_threads_add_repaint_func (run_all_repaint_laters, NULL, NULL); /* Make sure the repaint function gets run */ @@ -891,7 +924,7 @@ meta_later_add (MetaLaterType when, later->data = data; later->notify = notify; - laters = g_slist_insert_sorted (laters, later, compare_laters); + laters[when] = g_slist_prepend (laters[when], later); switch (when) { @@ -905,6 +938,7 @@ meta_later_add (MetaLaterType when, * there so it will happen before GTK+ repaints. */ later->source = g_idle_add_full (META_PRIORITY_RESIZE, call_idle_later, later, NULL); + g_source_set_name_by_id (later->source, "[mutter] call_idle_later"); ensure_later_repaint_func (); break; case META_LATER_CALC_SHOWING: @@ -915,128 +949,101 @@ meta_later_add (MetaLaterType when, break; case META_LATER_IDLE: later->source = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, call_idle_later, later, NULL); - break; - default: - g_warning ("Default reached in meta_later_add"); + g_source_set_name_by_id (later->source, "[mutter] call_idle_later"); break; } return later->id; } -/** - * meta_later_remove: - * @later_id: the integer ID returned from meta_later_add() - * - * Removes a callback added with meta_later_add() - */ -void -meta_later_remove (guint later_id) +static gboolean +meta_later_remove_from_list (guint later_id, GSList **laters_list) { GSList *l; - for (l = laters; l; l = l->next) + for (l = *laters_list; l; l = l->next) { MetaLater *later = l->data; + if (later->id == later_id) { - laters = g_slist_delete_link (laters, l); + *laters_list = g_slist_delete_link (*laters_list, l); /* If this was a "repaint func" later, we just let the * repaint func run and get removed */ destroy_later (later); - return; + return TRUE; } } -} -/* eof util.c */ + return FALSE; +} -/* Code to close all file descriptors before we exec; copied from gspawn.c in GLib. - * - * Authors: Padraig O'Briain, Matthias Clasen, Lennart Poettering +/** + * meta_later_remove: + * @later_id: the integer ID returned from meta_later_add() * - * http://bugzilla.gnome.org/show_bug.cgi?id=469231 - * http://bugzilla.gnome.org/show_bug.cgi?id=357585 + * Removes a callback added with meta_later_add() */ - -static int -set_cloexec (void *data, gint fd) +void +meta_later_remove (guint later_id) { - if (fd >= GPOINTER_TO_INT (data)) - fcntl (fd, F_SETFD, FD_CLOEXEC); + guint i; - return 0; + for (i = 0; i < G_N_ELEMENTS (laters); i++) + { + if (meta_later_remove_from_list (later_id, &laters[i])) + return; + } } -#ifndef HAVE_FDWALK -static int -fdwalk (int (*cb)(void *data, int fd), void *data) +MetaLocaleDirection +meta_get_locale_direction (void) { - gint open_max; - gint fd; - gint res = 0; - -#ifdef HAVE_SYS_RESOURCE_H - struct rlimit rl; -#endif - -#ifdef __linux__ - DIR *d; - - if ((d = opendir("/proc/self/fd"))) { - struct dirent *de; - - while ((de = readdir(d))) { - glong l; - gchar *e = NULL; - - if (de->d_name[0] == '.') - continue; - - errno = 0; - l = strtol(de->d_name, &e, 10); - if (errno != 0 || !e || *e) - continue; - - fd = (gint) l; - - if ((glong) fd != l) - continue; - - if (fd == dirfd(d)) - continue; - - if ((res = cb (data, fd)) != 0) - break; - } + switch (gtk_get_locale_direction ()) + { + case GTK_TEXT_DIR_LTR: + return META_LOCALE_DIRECTION_LTR; + case GTK_TEXT_DIR_RTL: + return META_LOCALE_DIRECTION_RTL; + default: + g_assert_not_reached (); + return 0; + } +} - closedir(d); - return res; - } +char * +meta_generate_random_id (GRand *rand, + int length) +{ + char *id; + int i; - /* If /proc is not mounted or not accessible we fall back to the old - * rlimit trick */ + /* Generate a random string of printable ASCII characters. */ -#endif + id = g_new0 (char, length + 1); + for (i = 0; i < length; i++) + id[i] = (char) g_rand_int_range (rand, 32, 127); -#ifdef HAVE_SYS_RESOURCE_H - if (getrlimit(RLIMIT_NOFILE, &rl) == 0 && rl.rlim_max != RLIM_INFINITY) - open_max = rl.rlim_max; - else -#endif - open_max = sysconf (_SC_OPEN_MAX); + return id; +} - for (fd = 0; fd < open_max; fd++) - if ((res = cb (data, fd)) != 0) - break; - return res; +void +meta_add_clutter_debug_flags (ClutterDebugFlag debug_flags, + ClutterDrawDebugFlag draw_flags, + ClutterPickDebugFlag pick_flags) +{ + clutter_add_debug_flags (debug_flags, draw_flags, pick_flags); } -#endif void -meta_pre_exec_close_fds(void) +meta_remove_clutter_debug_flags (ClutterDebugFlag debug_flags, + ClutterDrawDebugFlag draw_flags, + ClutterPickDebugFlag pick_flags) { - fdwalk (set_cloexec, GINT_TO_POINTER(3)); + clutter_remove_debug_flags (debug_flags, draw_flags, pick_flags); } + +/* eof util.c */ + diff --git a/src/core/window-private.h b/src/core/window-private.h index f117491c5..273675900 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -1,7 +1,7 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ /** - * \file window-private.h Windows which Muffin manages + * \file window-private.h Windows which Mutter manages * * Managing X windows. * This file contains methods on this class which are available to @@ -9,12 +9,12 @@ * which the rest of the world is allowed to use.) */ -/* +/* * Copyright (C) 2001 Havoc Pennington * Copyright (C) 2002 Red Hat, Inc. * Copyright (C) 2003, 2004 Rob Adams * Copyright (C) 2004-2006 Elijah Newren - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the @@ -24,82 +24,139 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_WINDOW_PRIVATE_H #define META_WINDOW_PRIVATE_H -#include <config.h> -#include <meta/compositor.h> -#include <meta/window.h> -#include "screen-private.h" -#include <meta/util.h> -#include "stack.h" -#include "iconcache.h" #include <X11/Xutil.h> #include <cairo.h> #include <gdk-pixbuf/gdk-pixbuf.h> +#include "backends/meta-logical-monitor.h" +#include "clutter/clutter.h" +#include "core/stack.h" +#include "meta/compositor.h" +#include "meta/meta-close-dialog.h" +#include "meta/util.h" +#include "meta/window.h" +#include "wayland/meta-wayland-types.h" +#include "x11/group-private.h" + typedef struct _MetaWindowQueue MetaWindowQueue; -typedef enum { +typedef enum +{ META_CLIENT_TYPE_UNKNOWN = 0, META_CLIENT_TYPE_APPLICATION = 1, META_CLIENT_TYPE_PAGER = 2, META_CLIENT_TYPE_MAX_RECOGNIZED = 2 } MetaClientType; -typedef enum { +typedef enum +{ META_QUEUE_CALC_SHOWING = 1 << 0, - META_QUEUE_MOVE_RESIZE = 1 << 1 + META_QUEUE_MOVE_RESIZE = 1 << 1, + META_QUEUE_UPDATE_ICON = 1 << 2, } MetaQueueType; -/* edge zones for tiling/snapping identification - - ___________________________ - | 4 0 5 | - | | - | | - | | - | | - | 2 3 | - | | - | | - | | - | | - | 7 1 6 | - |_________________________| - -*/ - -enum { - ZONE_0 = 0, - ZONE_1, - ZONE_2, - ZONE_3, - ZONE_4, - ZONE_5, - ZONE_6, - ZONE_7, - ZONE_NONE -}; - -#define NUMBER_OF_QUEUES 2 +#define NUMBER_OF_QUEUES 3 -#define HUD_WIDTH 24 -#define CSD_TITLEBAR_HEIGHT 48 - -typedef enum { +typedef enum +{ _NET_WM_BYPASS_COMPOSITOR_HINT_AUTO = 0, _NET_WM_BYPASS_COMPOSITOR_HINT_ON = 1, _NET_WM_BYPASS_COMPOSITOR_HINT_OFF = 2, } MetaBypassCompositorHintValue; +typedef enum +{ + META_MOVE_RESIZE_CONFIGURE_REQUEST = 1 << 0, + META_MOVE_RESIZE_USER_ACTION = 1 << 1, + META_MOVE_RESIZE_MOVE_ACTION = 1 << 2, + META_MOVE_RESIZE_RESIZE_ACTION = 1 << 3, + META_MOVE_RESIZE_WAYLAND_FINISH_MOVE_RESIZE = 1 << 4, + META_MOVE_RESIZE_STATE_CHANGED = 1 << 5, + META_MOVE_RESIZE_UNMAXIMIZE = 1 << 6, + META_MOVE_RESIZE_UNFULLSCREEN = 1 << 7, + META_MOVE_RESIZE_FORCE_MOVE = 1 << 8, + META_MOVE_RESIZE_WAYLAND_STATE_CHANGED = 1 << 9, + META_MOVE_RESIZE_FORCE_UPDATE_MONITOR = 1 << 10, + META_MOVE_RESIZE_PLACEMENT_CHANGED = 1 << 11, +} MetaMoveResizeFlags; + +typedef enum +{ + META_MOVE_RESIZE_RESULT_MOVED = 1 << 0, + META_MOVE_RESIZE_RESULT_RESIZED = 1 << 1, + META_MOVE_RESIZE_RESULT_FRAME_SHAPE_CHANGED = 1 << 2, + META_MOVE_RESIZE_RESULT_STATE_CHANGED = 1 << 3, +} MetaMoveResizeResultFlags; + +typedef enum +{ + META_PLACEMENT_GRAVITY_NONE = 0, + META_PLACEMENT_GRAVITY_TOP = 1 << 0, + META_PLACEMENT_GRAVITY_BOTTOM = 1 << 1, + META_PLACEMENT_GRAVITY_LEFT = 1 << 2, + META_PLACEMENT_GRAVITY_RIGHT = 1 << 3, +} MetaPlacementGravity; + +typedef enum +{ + META_PLACEMENT_ANCHOR_NONE = 0, + META_PLACEMENT_ANCHOR_TOP = 1 << 0, + META_PLACEMENT_ANCHOR_BOTTOM = 1 << 1, + META_PLACEMENT_ANCHOR_LEFT = 1 << 2, + META_PLACEMENT_ANCHOR_RIGHT = 1 << 3, +} MetaPlacementAnchor; + +typedef enum +{ + META_PLACEMENT_CONSTRAINT_ADJUSTMENT_NONE = 0, + META_PLACEMENT_CONSTRAINT_ADJUSTMENT_SLIDE_X = 1 << 0, + META_PLACEMENT_CONSTRAINT_ADJUSTMENT_SLIDE_Y = 1 << 1, + META_PLACEMENT_CONSTRAINT_ADJUSTMENT_FLIP_X = 1 << 2, + META_PLACEMENT_CONSTRAINT_ADJUSTMENT_FLIP_Y = 1 << 3, + META_PLACEMENT_CONSTRAINT_ADJUSTMENT_RESIZE_X = 1 << 4, + META_PLACEMENT_CONSTRAINT_ADJUSTMENT_RESIZE_Y = 1 << 5, +} MetaPlacementConstraintAdjustment; + +typedef enum _MetaWindowUpdateMonitorFlags +{ + META_WINDOW_UPDATE_MONITOR_FLAGS_NONE = 0, + META_WINDOW_UPDATE_MONITOR_FLAGS_USER_OP = 1 << 0, + META_WINDOW_UPDATE_MONITOR_FLAGS_FORCE = 1 << 1, +} MetaWindowUpdateMonitorFlags; + +typedef struct _MetaPlacementRule +{ + MetaRectangle anchor_rect; + MetaPlacementGravity gravity; + MetaPlacementAnchor anchor; + MetaPlacementConstraintAdjustment constraint_adjustment; + int offset_x; + int offset_y; + int width; + int height; + + gboolean is_reactive; + + MetaRectangle parent_rect; +} MetaPlacementRule; + +typedef enum _MetaPlacementState +{ + META_PLACEMENT_STATE_UNCONSTRAINED, + META_PLACEMENT_STATE_CONSTRAINED_PENDING, + META_PLACEMENT_STATE_CONSTRAINED_CONFIGURED, + META_PLACEMENT_STATE_CONSTRAINED_FINISHED, + META_PLACEMENT_STATE_INVALIDATED, +} MetaPlacementState; + typedef enum { META_EDGE_CONSTRAINT_NONE = 0, @@ -110,38 +167,27 @@ typedef enum struct _MetaWindow { GObject parent_instance; - + MetaDisplay *display; - MetaScreen *screen; - const MetaMonitorInfo *monitor; + uint64_t id; + guint64 stamp; + MetaLogicalMonitor *monitor; MetaWorkspace *workspace; + MetaWindowClientType client_type; + MetaWaylandSurface *surface; Window xwindow; /* may be NULL! not all windows get decorated */ MetaFrame *frame; int depth; Visual *xvisual; - Colormap colormap; char *desc; /* used in debug spew */ char *title; - char *icon_name; - -/* XAppGtkWindow */ - char *theme_icon_name; - guint progress; - guint progress_pulse : 1; -/* /XappGtkWindow */ + cairo_surface_t *icon; + cairo_surface_t *mini_icon; - GdkPixbuf *icon; - MetaIconCache icon_cache; - int icon_size; - - Pixmap wm_hints_pixmap; - Pixmap wm_hints_mask; - MetaWindowType type; - Atom type_atom; - + /* NOTE these five are not in UTF-8, we just treat them as random * binary data */ @@ -152,7 +198,8 @@ struct _MetaWindow char *wm_client_machine; char *startup_id; - char *muffin_hints; + char *mutter_hints; + char *sandboxed_app_id; char *gtk_theme_variant; char *gtk_application_id; char *gtk_unique_bus_name; @@ -160,21 +207,20 @@ struct _MetaWindow char *gtk_window_object_path; char *gtk_app_menu_object_path; char *gtk_menubar_object_path; - - int hide_titlebar_when_maximized; + int net_wm_pid; - int client_pid; - + Window xtransient_for; Window xgroup_leader; Window xclient_leader; + MetaWindow *transient_for; /* Initial workspace property */ - int initial_workspace; - + int initial_workspace; + /* Initial timestamp property */ - guint32 initial_timestamp; - + guint32 initial_timestamp; + /* Whether this is an override redirect window or not */ guint override_redirect : 1; @@ -182,40 +228,29 @@ struct _MetaWindow guint maximized_horizontally : 1; guint maximized_vertically : 1; - guint32 snap_delay_timestamp; - guint snap_queued : 1; - guint zone_queued; - MetaWindowTileType tile_type; - MetaWindowTileType resizing_tile_type; - guint custom_snap_size : 1; - guint current_proximity_zone; - guint mouse_on_edge : 1; - guint maybe_retile_maximize : 1; - /* Whether we have to maximize/minimize after placement */ guint maximize_horizontally_after_placement : 1; guint maximize_vertically_after_placement : 1; guint minimize_after_placement : 1; - guint tile_after_placement : 1; - guint move_after_placement : 1; - /* The current or requested tile mode. If maximized_vertically is true, - * this is the current mode. If not, it is the mode which will be - * requested after the window grab is released */ - guint tile_mode : 4; - guint last_tile_mode : 4; - guint resize_tile_mode : 4; + /* The current tile mode */ + MetaTileMode tile_mode; /* The last "full" maximized/unmaximized state. We need to keep track of * that to toggle between normal/tiled or maximized/tiled states. */ guint saved_maximize : 1; int tile_monitor_number; - /* 0 - top - * 1 - right - * 2 - bottom - * 3 - left */ - MetaEdgeConstraint edge_constraints[4]; + struct { + MetaEdgeConstraint top; + MetaEdgeConstraint right; + MetaEdgeConstraint bottom; + MetaEdgeConstraint left; + } edge_constraints; + + double tile_hfraction; + + uint64_t preferred_output_winsys_id; /* Whether we're shaded */ guint shaded : 1; @@ -223,15 +258,20 @@ struct _MetaWindow /* Whether we're fullscreen */ guint fullscreen : 1; - /* Whether the urgent flag of WM_HINTS is set */ - guint wm_hints_urgent : 1; + /* Whether the window is marked as urgent */ + guint urgent : 1; /* Area to cover when in fullscreen mode. If _NET_WM_FULLSCREEN_MONITORS has * been overridden (via a client message), the window will cover the union of * these monitors. If not, this is the single monitor which the window's * origin is on. */ - long fullscreen_monitors[4]; - + struct { + MetaLogicalMonitor *top; + MetaLogicalMonitor *bottom; + MetaLogicalMonitor *left; + MetaLogicalMonitor *right; + } fullscreen_monitors; + /* Whether we're trying to constrain the window to be fully onscreen */ guint require_fully_onscreen : 1; @@ -260,16 +300,24 @@ struct _MetaWindow * see also unmaps_pending */ guint mapped : 1; - + /* Whether window has been hidden from view by lowering it to the bottom * of window stack. */ guint hidden : 1; - /* Whether the compositor thinks the window is visible + /* Whether the compositor thinks the window is visible. + * This should match up with calls to meta_compositor_show_window / + * meta_compositor_hide_window. */ guint visible_to_compositor : 1; + /* Whether the compositor knows about the window. + * This should match up with calls to meta_compositor_add_window / + * meta_compositor_remove_window. + */ + guint known_to_compositor : 1; + /* When we next show or hide the window, what effect we should * tell the compositor to perform. */ @@ -286,23 +334,19 @@ struct _MetaWindow /* whether an initial workspace was explicitly set */ guint initial_workspace_set : 1; - + /* whether an initial timestamp was explicitly set */ guint initial_timestamp_set : 1; - + /* whether net_wm_user_time has been set yet */ guint net_wm_user_time_set : 1; /* whether net_wm_icon_geometry has been set */ - guint icon_geometry_set: 1; - - /* These are the flags from WM_PROTOCOLS */ - guint take_focus : 1; - guint delete_window : 1; - guint net_wm_ping : 1; + guint icon_geometry_set : 1; + /* Globally active / No input */ guint input : 1; - + /* MWM hints about features of window */ guint mwm_decorated : 1; guint mwm_border_only : 1; @@ -311,7 +355,7 @@ struct _MetaWindow guint mwm_has_maximize_func : 1; guint mwm_has_move_func : 1; guint mwm_has_resize_func : 1; - + /* Computed features of window */ guint decorated : 1; guint border_only : 1; @@ -323,13 +367,6 @@ struct _MetaWindow guint has_move_func : 1; guint has_resize_func : 1; guint has_fullscreen_func : 1; - - /* Weird "_NET_WM_STATE_MODAL" flag */ - guint wm_state_modal : 1; - - /* TRUE if the client forced these on */ - guint wm_state_skip_taskbar : 1; - guint wm_state_skip_pager : 1; /* Computed whether to skip taskbar or not */ guint skip_taskbar : 1; @@ -341,16 +378,13 @@ struct _MetaWindow /* EWHH demands attention flag */ guint wm_state_demands_attention : 1; - - /* this flag tracks receipt of focus_in focus_out */ + + /* TRUE iff window == window->display->focus_window */ guint has_focus : 1; /* Have we placed this window? */ guint placed : 1; - /* Must we force_save_user_window_placement? */ - guint force_save_user_rect : 1; - /* Is this not a transient of the focus window which is being denied focus? */ guint denied_focus_and_not_transient : 1; @@ -362,15 +396,15 @@ struct _MetaWindow /* Are we in meta_window_new()? */ guint constructing : 1; - + /* Are we in the various queues? (Bitfield: see META_WINDOW_IS_IN_QUEUE) */ guint is_in_queues : NUMBER_OF_QUEUES; - + /* Used by keybindings.c */ guint keys_grabbed : 1; /* normal keybindings grabbed */ guint grab_on_frame : 1; /* grabs are on the frame */ guint all_keys_grabbed : 1; /* AnyKey grabbed */ - + /* Set if the reason for unmanaging the window is that * it was withdrawn */ @@ -381,21 +415,6 @@ struct _MetaWindow */ guint calc_placement : 1; - /* Transient parent is a root window */ - guint transient_parent_is_root_window : 1; - - /* Info on which props we got our attributes from */ - guint using_net_wm_name : 1; /* vs. plain wm_name */ - guint using_net_wm_visible_name : 1; /* tracked so we can clear it */ - guint using_net_wm_icon_name : 1; /* vs. plain wm_icon_name */ - guint using_net_wm_visible_icon_name : 1; /* tracked so we can clear it */ - - /* has a shape mask */ - guint has_shape : 1; - - /* icon props have changed */ - guint need_reread_icon : 1; - /* if TRUE, window was maximized at start of current grab op */ guint shaken_loose : 1; @@ -408,12 +427,28 @@ struct _MetaWindow /* if TRUE, window is attached to its parent */ guint attached : 1; + /* whether or not the window is from a program running on another machine */ + guint is_remote : 1; + + /* whether focus should be restored on map */ + guint restore_focus_on_map : 1; + /* if non-NULL, the bounds of the window frame */ cairo_region_t *frame_bounds; + /* if non-NULL, the bounding shape region of the window. Relative to + * the server-side client window. */ + cairo_region_t *shape_region; + /* if non-NULL, the opaque region _NET_WM_OPAQUE_REGION */ cairo_region_t *opaque_region; + /* the input shape region for picking */ + cairo_region_t *input_region; + + /* _NET_WM_WINDOW_OPACITY rescaled to 0xFF */ + guint8 opacity; + /* if TRUE, the we have the new form of sync request counter which * also handles application frames */ guint extended_sync_request_counter : 1; @@ -421,7 +456,6 @@ struct _MetaWindow /* Note: can be NULL */ GSList *struts; -#ifdef HAVE_XSYNC /* XSync update counter */ XSyncCounter sync_request_counter; gint64 sync_request_serial; @@ -429,14 +463,17 @@ struct _MetaWindow guint sync_request_timeout_id; /* alarm monitoring client's _NET_WM_SYNC_REQUEST_COUNTER */ XSyncAlarm sync_request_alarm; -#endif - + /* Number of UnmapNotify that are caused by us, if * we get UnmapNotify with none pending then the client * is withdrawing the window. */ int unmaps_pending; + /* Number of XReparentWindow requests that we have queued. + */ + int reparents_pending; + /* See docs for meta_window_get_stable_sequence() */ guint32 stable_sequence; @@ -446,55 +483,50 @@ struct _MetaWindow /* window that gets updated net_wm_user_time values */ Window user_time_window; - - /* The size we set the window to last (i.e. what we believe - * to be its actual size on the server). The x, y are - * the actual server-side x,y so are relative to the frame - * (meaning that they just hold the frame width and height) - * or the root window (meaning they specify the location - * of the top left of the inner window) as appropriate. - */ - MetaRectangle rect; gboolean has_custom_frame_extents; GtkBorder custom_frame_extents; - /* The geometry to restore when we unmaximize. The position is in - * root window coords, even if there's a frame, which contrasts with - * window->rect above. Note that this gives the position and size - * of the client window (i.e. ignoring the frame). - */ + /* The rectangles here are in "frame rect" coordinates. See the + * comment at the top of meta_window_move_resize_internal() for more + * information. */ + + /* The current window geometry of the window. */ + MetaRectangle rect; + + /* The geometry to restore when we unmaximize. */ MetaRectangle saved_rect; - /* This is the geometry the window had after the last user-initiated - * move/resize operations. We use this whenever we are moving the - * implicitly (for example, if we move to avoid a panel, we can snap - * back to this position if the panel moves again). Note that this - * gives the position and size of the client window (i.e. ignoring - * the frame). + /* This is the geometry the window will have if no constraints have + * applied. We use this whenever we are moving implicitly (for example, + * if we move to avoid a panel, we can snap back to this position if + * the panel moves again). + */ + MetaRectangle unconstrained_rect; + + /* The rectangle of the "server-side" geometry of the buffer, + * in root coordinates. * - * Position valid if user_has_moved, size valid if user_has_resized + * For X11 windows, this matches XGetGeometry of the toplevel. * - * Position always in root coords, unlike window->rect. + * For Wayland windows, the position matches the position of the + * surface associated with shell surface (wl_shell_surface, xdg_surface + * etc). The size matches the size surface size as displayed in the stage. */ - MetaRectangle user_rect; - - MetaRectangle snapped_rect; + MetaRectangle buffer_rect; /* Cached net_wm_icon_geometry */ MetaRectangle icon_geometry; - /* Requested geometry */ - int border_width; /* x/y/w/h here get filled with ConfigureRequest values */ XSizeHints size_hints; /* Managed by stack.c */ MetaStackLayer layer; int stack_position; /* see comment in stack.h */ - - /* Current dialog open for this window */ - int dialog_pid; + + /* Managed by delete.c */ + MetaCloseDialog *close_dialog; /* maintained by group.c */ MetaGroup *group; @@ -509,16 +541,82 @@ struct _MetaWindow /* Bypass compositor hints */ guint bypass_compositor; + + struct { + MetaPlacementRule *rule; + MetaPlacementState state; + + struct { + int x; + int y; + int rel_x; + int rel_y; + } pending; + + struct { + int rel_x; + int rel_y; + } current; + } placement; + + guint unmanage_idle_id; }; struct _MetaWindowClass { GObjectClass parent_class; - void (*workspace_changed) (MetaWindow *window, int old_workspace); - void (*focus) (MetaWindow *window); - void (*raised) (MetaWindow *window); - void (*unmanaged) (MetaWindow *window); + void (*manage) (MetaWindow *window); + void (*unmanage) (MetaWindow *window); + void (*ping) (MetaWindow *window, + guint32 serial); + void (*delete) (MetaWindow *window, + guint32 timestamp); + void (*kill) (MetaWindow *window); + void (*focus) (MetaWindow *window, + guint32 timestamp); + void (*grab_op_began) (MetaWindow *window, + MetaGrabOp op); + void (*grab_op_ended) (MetaWindow *window, + MetaGrabOp op); + void (*current_workspace_changed) (MetaWindow *window); + void (*move_resize_internal) (MetaWindow *window, + MetaGravity gravity, + MetaRectangle unconstrained_rect, + MetaRectangle constrained_rect, + MetaRectangle temporary_rect, + int rel_x, + int rel_y, + MetaMoveResizeFlags flags, + MetaMoveResizeResultFlags *result); + gboolean (*update_struts) (MetaWindow *window); + void (*get_default_skip_hints) (MetaWindow *window, + gboolean *skip_taskbar_out, + gboolean *skip_pager_out); + gboolean (*update_icon) (MetaWindow *window, + cairo_surface_t **icon, + cairo_surface_t **mini_icon); + uint32_t (*get_client_pid) (MetaWindow *window); + void (*update_main_monitor) (MetaWindow *window, + MetaWindowUpdateMonitorFlags flags); + void (*main_monitor_changed) (MetaWindow *window, + const MetaLogicalMonitor *old); + void (*adjust_fullscreen_monitor_rect) (MetaWindow *window, + MetaRectangle *monitor_rect); + void (*force_restore_shortcuts) (MetaWindow *window, + ClutterInputDevice *source); + gboolean (*shortcuts_inhibited) (MetaWindow *window, + ClutterInputDevice *source); + gboolean (*is_focusable) (MetaWindow *window); + gboolean (*is_stackable) (MetaWindow *window); + gboolean (*can_ping) (MetaWindow *window); + gboolean (*are_updates_frozen) (MetaWindow *window); + gboolean (*is_focus_async) (MetaWindow *window); + + MetaStackLayer (*calculate_layer) (MetaWindow *window); + + void (* map) (MetaWindow *window); + void (* unmap) (MetaWindow *window); }; /* These differ from window->has_foo_func in that they consider @@ -529,227 +627,125 @@ struct _MetaWindowClass (w)->maximized_vertically) #define META_WINDOW_MAXIMIZED_VERTICALLY(w) ((w)->maximized_vertically) #define META_WINDOW_MAXIMIZED_HORIZONTALLY(w) ((w)->maximized_horizontally) -#define META_WINDOW_TILED(w) ((w)->tile_type == META_WINDOW_TILE_TYPE_TILED) -#define META_WINDOW_SNAPPED(w) ((w)->tile_type == META_WINDOW_TILE_TYPE_SNAPPED) -#define META_WINDOW_TILED_OR_SNAPPED(w) (META_WINDOW_SNAPPED (w) || META_WINDOW_TILED (w)) -#define META_WINDOW_TILED_LEFT(w) (META_WINDOW_TILED_OR_SNAPPED (w) && (w)->tile_mode == META_TILE_LEFT) -#define META_WINDOW_TILED_RIGHT(w) (META_WINDOW_TILED_OR_SNAPPED (w) && (w)->tile_mode == META_TILE_RIGHT) -#define META_WINDOW_TILED_SIDE_BY_SIDE(w) (META_WINDOW_TILED_LEFT (w) || META_WINDOW_TILED_RIGHT (w)) -#define META_WINDOW_TILED_ULC(w) (META_WINDOW_TILED_OR_SNAPPED (w) && (w)->tile_mode == META_TILE_ULC) -#define META_WINDOW_TILED_LLC(w) (META_WINDOW_TILED_OR_SNAPPED (w) && (w)->tile_mode == META_TILE_LLC) -#define META_WINDOW_TILED_URC(w) (META_WINDOW_TILED_OR_SNAPPED (w) && (w)->tile_mode == META_TILE_URC) -#define META_WINDOW_TILED_LRC(w) (META_WINDOW_TILED_OR_SNAPPED (w) && (w)->tile_mode == META_TILE_LRC) -#define META_WINDOW_TILED_CORNER(w) (META_WINDOW_TILED_ULC (w) || \ - META_WINDOW_TILED_LLC (w) || \ - META_WINDOW_TILED_URC (w) || \ - META_WINDOW_TILED_LRC (w)) - -#define META_WINDOW_TILED_TOP(w) (META_WINDOW_TILED_OR_SNAPPED (w) && (w)->tile_mode == META_TILE_TOP) -#define META_WINDOW_TILED_BOTTOM(w) (META_WINDOW_TILED_OR_SNAPPED (w) && (w)->tile_mode == META_TILE_BOTTOM) - -#define META_WINDOW_TILED_TOP_BOTTOM(w) (META_WINDOW_TILED_TOP (w) || \ - META_WINDOW_TILED_BOTTOM (w)) - +#define META_WINDOW_TILED_SIDE_BY_SIDE(w) ((w)->maximized_vertically && \ + !(w)->maximized_horizontally && \ + (w)->tile_mode != META_TILE_NONE) +#define META_WINDOW_TILED_LEFT(w) (META_WINDOW_TILED_SIDE_BY_SIDE(w) && \ + (w)->tile_mode == META_TILE_LEFT) +#define META_WINDOW_TILED_RIGHT(w) (META_WINDOW_TILED_SIDE_BY_SIDE(w) && \ + (w)->tile_mode == META_TILE_RIGHT) +#define META_WINDOW_TILED_MAXIMIZED(w)(META_WINDOW_MAXIMIZED(w) && \ + (w)->tile_mode == META_TILE_MAXIMIZED) #define META_WINDOW_ALLOWS_MOVE(w) ((w)->has_move_func && !(w)->fullscreen) -#define META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS(w) ((w)->has_resize_func && !META_WINDOW_MAXIMIZED (w) && !(w)->fullscreen && !(w)->shaded) +#define META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS(w) ((w)->has_resize_func && !META_WINDOW_MAXIMIZED (w) && !(w)->fullscreen && !(w)->shaded) #define META_WINDOW_ALLOWS_RESIZE(w) (META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS (w) && \ (((w)->size_hints.min_width < (w)->size_hints.max_width) || \ ((w)->size_hints.min_height < (w)->size_hints.max_height))) -#define META_WINDOW_ALLOWS_HORIZONTAL_RESIZE(w) (META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS (w) && (w)->size_hints.min_width < (w)->size_hints.max_width && \ - !META_WINDOW_TILED_OR_SNAPPED (w)) -#define META_WINDOW_ALLOWS_VERTICAL_RESIZE(w) (META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS (w) && (w)->size_hints.min_height < (w)->size_hints.max_height && \ - !META_WINDOW_TILED_OR_SNAPPED (w)) -#define META_WINDOW_ALLOWS_TOP_RESIZE(w) (META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS (w) && META_WINDOW_TILED_OR_SNAPPED (w) && \ - ((w)->tile_mode == META_TILE_BOTTOM || \ - (w)->tile_mode == META_TILE_LLC || (w)->tile_mode == META_TILE_LRC)) -#define META_WINDOW_ALLOWS_BOTTOM_RESIZE(w) (META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS (w) && META_WINDOW_TILED_OR_SNAPPED (w) && \ - ((w)->tile_mode == META_TILE_TOP || \ - (w)->tile_mode == META_TILE_ULC || (w)->tile_mode == META_TILE_URC)) -#define META_WINDOW_ALLOWS_LEFT_RESIZE(w) (META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS (w) && META_WINDOW_TILED_OR_SNAPPED (w) && \ - ((w)->tile_mode == META_TILE_RIGHT || \ - (w)->tile_mode == META_TILE_URC || (w)->tile_mode == META_TILE_LRC)) -#define META_WINDOW_ALLOWS_RIGHT_RESIZE(w) (META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS (w) && META_WINDOW_TILED_OR_SNAPPED (w) && \ - ((w)->tile_mode == META_TILE_LEFT || \ - (w)->tile_mode == META_TILE_ULC || (w)->tile_mode == META_TILE_LLC)) -#define GRAB_OP(w) ((w)->display->grab_op) - -#define META_WINDOW_ - -MetaWindow* meta_window_new (MetaDisplay *display, - Window xwindow, - gboolean must_be_viewable); -MetaWindow* meta_window_new_with_attrs (MetaDisplay *display, - Window xwindow, - gboolean must_be_viewable, - MetaCompEffect effect, - XWindowAttributes *attrs); +#define META_WINDOW_ALLOWS_HORIZONTAL_RESIZE(w) (META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS (w) && (w)->size_hints.min_width < (w)->size_hints.max_width) +#define META_WINDOW_ALLOWS_VERTICAL_RESIZE(w) (META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS (w) && (w)->size_hints.min_height < (w)->size_hints.max_height) + +MetaWindow * _meta_window_shared_new (MetaDisplay *display, + MetaWindowClientType client_type, + MetaWaylandSurface *surface, + Window xwindow, + gulong existing_wm_state, + MetaCompEffect effect, + XWindowAttributes *attrs); + void meta_window_unmanage (MetaWindow *window, guint32 timestamp); +void meta_window_unmanage_on_idle (MetaWindow *window); void meta_window_queue (MetaWindow *window, guint queuebits); -void meta_window_real_tile (MetaWindow *window, - gboolean force); +META_EXPORT_TEST +void meta_window_tile (MetaWindow *window, + MetaTileMode mode); +MetaTileMode meta_window_get_tile_mode (MetaWindow *window); +void meta_window_restore_tile (MetaWindow *window, + MetaTileMode mode, + int width, + int height); void meta_window_maximize_internal (MetaWindow *window, MetaMaximizeFlags directions, MetaRectangle *saved_rect); -void meta_window_unmaximize_with_gravity (MetaWindow *window, - MetaMaximizeFlags directions, - int new_width, - int new_height, - int gravity); -void meta_window_make_above (MetaWindow *window); -void meta_window_unmake_above (MetaWindow *window); -void meta_window_shade (MetaWindow *window, - guint32 timestamp); -void meta_window_unshade (MetaWindow *window, - guint32 timestamp); -void meta_window_adjust_opacity (MetaWindow *window, - gboolean increase); void meta_window_make_fullscreen_internal (MetaWindow *window); -void meta_window_make_fullscreen (MetaWindow *window); -void meta_window_unmake_fullscreen (MetaWindow *window); -void meta_window_update_fullscreen_monitors (MetaWindow *window, - unsigned long top, - unsigned long bottom, - unsigned long left, - unsigned long right); - - -/* args to move are window pos, not frame pos */ -void meta_window_move_resize (MetaWindow *window, - gboolean user_op, - int root_x_nw, - int root_y_nw, - int w, - int h); -void meta_window_resize_with_gravity (MetaWindow *window, - gboolean user_op, - int w, - int h, - int gravity); +void meta_window_update_fullscreen_monitors (MetaWindow *window, + MetaLogicalMonitor *top, + MetaLogicalMonitor *bottom, + MetaLogicalMonitor *left, + MetaLogicalMonitor *right); +gboolean meta_window_has_fullscreen_monitors (MetaWindow *window); + +void meta_window_adjust_fullscreen_monitor_rect (MetaWindow *window, + MetaRectangle *monitor_rect); + +void meta_window_resize_frame_with_gravity (MetaWindow *window, + gboolean user_op, + int w, + int h, + MetaGravity gravity); /* Return whether the window should be currently mapped */ gboolean meta_window_should_be_showing (MetaWindow *window); -/* See warning in window.c about this function */ -gboolean __window_is_terminal (MetaWindow *window); - void meta_window_update_struts (MetaWindow *window); -/* this gets root coords */ -void meta_window_get_position (MetaWindow *window, - int *x, - int *y); - -/* Gets root coords for x, y, width & height of client window; uses - * meta_window_get_position for x & y. - */ -void meta_window_get_client_root_coords (MetaWindow *window, - MetaRectangle *rect); - /* gets position we need to set to stay in current position, * assuming position will be gravity-compensated. i.e. * this is the position a client would send in a configure * request. */ void meta_window_get_gravity_position (MetaWindow *window, - int gravity, + MetaGravity gravity, int *x, int *y); /* Get geometry for saving in the session; x/y are gravity * position, and w/h are in resize inc above the base size. */ -void meta_window_get_geometry (MetaWindow *window, +void meta_window_get_session_geometry (MetaWindow *window, int *x, int *y, int *width, int *height); -void meta_window_kill (MetaWindow *window); -void meta_window_focus (MetaWindow *window, - guint32 timestamp); - void meta_window_update_unfocused_button_grabs (MetaWindow *window); -/* Sends a client message */ -void meta_window_send_icccm_message (MetaWindow *window, - Atom atom, - guint32 timestamp); - -void meta_window_create_sync_request_alarm (MetaWindow *window); -void meta_window_destroy_sync_request_alarm (MetaWindow *window); - -void meta_window_move_resize_request(MetaWindow *window, - guint value_mask, - int gravity, - int x, - int y, - int width, - int height); -gboolean meta_window_configure_request (MetaWindow *window, - XEvent *event); -gboolean meta_window_property_notify (MetaWindow *window, - XEvent *event); -gboolean meta_window_client_message (MetaWindow *window, - XEvent *event); -gboolean meta_window_notify_focus (MetaWindow *window, - XEvent *event); - -void meta_window_set_current_workspace_hint (MetaWindow *window); - -unsigned long meta_window_get_net_wm_desktop (MetaWindow *window); - -void meta_window_show_menu (MetaWindow *window, - int root_x, - int root_y, - int button, - guint32 timestamp); - -gboolean meta_window_titlebar_is_onscreen (MetaWindow *window); -void meta_window_shove_titlebar_onscreen (MetaWindow *window); - -void meta_window_set_gravity (MetaWindow *window, - int gravity); - -#ifdef HAVE_XSYNC - void meta_window_update_sync_request_counter (MetaWindow *window, - gint64 new_counter_value); -#endif /* HAVE_XSYNC */ - -void meta_window_handle_mouse_grab_op_event (MetaWindow *window, - XEvent *event); - -void meta_window_handle_keyboard_grab_op_event (MetaWindow *window, - XEvent *event); +void meta_window_set_focused_internal (MetaWindow *window, + gboolean focused); -GList* meta_window_get_workspaces (MetaWindow *window); +gboolean meta_window_is_focusable (MetaWindow *window); -gboolean meta_window_located_on_workspace (MetaWindow *window, - MetaWorkspace *workspace); +gboolean meta_window_can_ping (MetaWindow *window); -void meta_window_get_work_area_current_monitor (MetaWindow *window, - MetaRectangle *area); -void meta_window_get_work_area_for_monitor (MetaWindow *window, - int which_monitor, - MetaRectangle *area); -void meta_window_get_work_area_all_monitors (MetaWindow *window, - MetaRectangle *area); +MetaStackLayer meta_window_calculate_layer (MetaWindow *window); -int meta_window_get_current_tile_monitor_number (MetaWindow *window); +void meta_window_current_workspace_changed (MetaWindow *window); -void meta_window_get_current_tile_area (MetaWindow *window, - MetaRectangle *tile_area); +void meta_window_show_menu (MetaWindow *window, + MetaWindowMenuType menu, + int x, + int y); -void meta_window_get_tile_threshold_area_for_mode (MetaWindow *window, - MetaRectangle work_area, - MetaTileMode mode, - MetaRectangle *tile_area, - gint zone_width); +void meta_window_show_menu_for_rect (MetaWindow *window, + MetaWindowMenuType menu, + MetaRectangle *rect); + +gboolean meta_window_handle_mouse_grab_op_event (MetaWindow *window, + const ClutterEvent *event); + +GList* meta_window_get_workspaces (MetaWindow *window); + +void meta_window_get_work_area_for_logical_monitor (MetaWindow *window, + MetaLogicalMonitor *logical_monitor, + MetaRectangle *area); + +int meta_window_get_current_tile_monitor_number (MetaWindow *window); +void meta_window_get_tile_area (MetaWindow *window, + MetaTileMode mode, + MetaRectangle *tile_area); -void meta_window_get_titlebar_rect (MetaWindow *window, - MetaRectangle *titlebar_rect); gboolean meta_window_same_application (MetaWindow *window, MetaWindow *other_window); @@ -757,34 +753,30 @@ gboolean meta_window_same_application (MetaWindow *window, #define META_WINDOW_IN_NORMAL_TAB_CHAIN_TYPE(w) \ ((w)->type != META_WINDOW_DOCK && (w)->type != META_WINDOW_DESKTOP) #define META_WINDOW_IN_NORMAL_TAB_CHAIN(w) \ - (((w)->input || (w)->take_focus ) && META_WINDOW_IN_NORMAL_TAB_CHAIN_TYPE (w) && (!(w)->skip_taskbar)) + (meta_window_is_focusable (w) && META_WINDOW_IN_NORMAL_TAB_CHAIN_TYPE (w) && (!(w)->skip_taskbar)) #define META_WINDOW_IN_DOCK_TAB_CHAIN(w) \ - (((w)->input || (w)->take_focus) && (! META_WINDOW_IN_NORMAL_TAB_CHAIN_TYPE (w) || (w)->skip_taskbar)) + (meta_window_is_focusable (w) && (! META_WINDOW_IN_NORMAL_TAB_CHAIN_TYPE (w) || (w)->skip_taskbar)) #define META_WINDOW_IN_GROUP_TAB_CHAIN(w, g) \ - (((w)->input || (w)->take_focus) && (!g || meta_window_get_group(w)==g)) - -void meta_window_refresh_resize_popup (MetaWindow *window); + (meta_window_is_focusable (w) && (!g || meta_window_get_group(w)==g)) void meta_window_free_delete_dialog (MetaWindow *window); - -void meta_window_begin_grab_op (MetaWindow *window, - MetaGrabOp op, - gboolean frame_action, - guint32 timestamp); - void meta_window_update_keyboard_resize (MetaWindow *window, gboolean update_cursor); void meta_window_update_keyboard_move (MetaWindow *window); +MetaStackLayer meta_window_get_default_layer (MetaWindow *window); void meta_window_update_layer (MetaWindow *window); void meta_window_recalc_features (MetaWindow *window); -void meta_window_recalc_window_type (MetaWindow *window); +void meta_window_set_type (MetaWindow *window, + MetaWindowType type); void meta_window_frame_size_changed (MetaWindow *window); +gboolean meta_window_is_in_stack (MetaWindow *window); + void meta_window_stack_just_below (MetaWindow *window, MetaWindow *below_this_one); @@ -794,51 +786,99 @@ void meta_window_stack_just_above (MetaWindow *window, void meta_window_set_user_time (MetaWindow *window, guint32 timestamp); -void meta_window_update_role (MetaWindow *window); -void meta_window_update_net_wm_type (MetaWindow *window); void meta_window_update_for_monitors_changed (MetaWindow *window); -void meta_window_update_on_all_workspaces (MetaWindow *window); - -void meta_window_propagate_focus_appearance (MetaWindow *window, - gboolean focused); +void meta_window_on_all_workspaces_changed (MetaWindow *window); gboolean meta_window_should_attach_to_parent (MetaWindow *window); gboolean meta_window_can_tile_side_by_side (MetaWindow *window); -gboolean meta_window_can_tile_top_bottom (MetaWindow *window); -gboolean meta_window_can_tile_corner (MetaWindow *window); -MetaSide meta_window_get_tile_side (MetaWindow *window); void meta_window_compute_tile_match (MetaWindow *window); -gboolean meta_window_mouse_on_edge (MetaWindow *window, - gint x, - gint y); +gboolean meta_window_updates_are_frozen (MetaWindow *window); -guint meta_window_get_current_zone (MetaWindow *window, - MetaRectangle monitor, - MetaRectangle work_area, - int x, - int y, - int zone_threshold); +void meta_window_set_title (MetaWindow *window, + const char *title); +void meta_window_set_wm_class (MetaWindow *window, + const char *wm_class, + const char *wm_instance); +void meta_window_set_gtk_dbus_properties (MetaWindow *window, + const char *application_id, + const char *unique_bus_name, + const char *appmenu_path, + const char *menubar_path, + const char *application_object_path, + const char *window_object_path); -void meta_window_set_tile_type (MetaWindow *window, - MetaWindowTileType type); -MetaWindowTileType meta_window_get_tile_type (MetaWindow *window); +gboolean meta_window_has_transient_type (MetaWindow *window); -gboolean meta_window_is_client_decorated (MetaWindow *window); +void meta_window_set_transient_for (MetaWindow *window, + MetaWindow *parent); +void meta_window_set_opacity (MetaWindow *window, + guint8 opacity); -gboolean meta_window_updates_are_frozen (MetaWindow *window); +void meta_window_handle_enter (MetaWindow *window, + guint32 timestamp, + guint root_x, + guint root_y); +void meta_window_handle_leave (MetaWindow *window); -void meta_window_extend_by_frame (MetaWindow *window, - MetaRectangle *rect, - const MetaFrameBorders *borders); -void meta_window_unextend_by_frame (MetaWindow *window, - MetaRectangle *rect, - const MetaFrameBorders *borders); +gboolean meta_window_handle_ui_frame_event (MetaWindow *window, + const ClutterEvent *event); + +void meta_window_handle_ungrabbed_event (MetaWindow *window, + const ClutterEvent *event); + +uint32_t meta_window_get_client_pid (MetaWindow *window); void meta_window_get_client_area_rect (const MetaWindow *window, cairo_rectangle_int_t *rect); +void meta_window_get_titlebar_rect (MetaWindow *window, + MetaRectangle *titlebar_rect); + +void meta_window_activate_full (MetaWindow *window, + guint32 timestamp, + MetaClientType source_indication, + MetaWorkspace *workspace); + +MetaLogicalMonitor * meta_window_calculate_main_logical_monitor (MetaWindow *window); + +MetaLogicalMonitor * meta_window_get_main_logical_monitor (MetaWindow *window); +void meta_window_update_monitor (MetaWindow *window, + MetaWindowUpdateMonitorFlags flags); + +void meta_window_set_urgent (MetaWindow *window, + gboolean urgent); + +void meta_window_update_resize (MetaWindow *window, + gboolean snap, + int x, int y, + gboolean force); + +void meta_window_move_resize_internal (MetaWindow *window, + MetaMoveResizeFlags flags, + MetaGravity gravity, + MetaRectangle frame_rect); + +void meta_window_grab_op_began (MetaWindow *window, MetaGrabOp op); +void meta_window_grab_op_ended (MetaWindow *window, MetaGrabOp op); + +void meta_window_set_alive (MetaWindow *window, gboolean is_alive); + +gboolean meta_window_has_pointer (MetaWindow *window); + +void meta_window_emit_size_changed (MetaWindow *window); + +MetaPlacementRule *meta_window_get_placement_rule (MetaWindow *window); + +void meta_window_force_placement (MetaWindow *window, + gboolean force_move); + +void meta_window_force_restore_shortcuts (MetaWindow *window, + ClutterInputDevice *source); -void meta_window_icon_changed (MetaWindow *window); +gboolean meta_window_shortcuts_inhibited (MetaWindow *window, + ClutterInputDevice *source); +gboolean meta_window_is_stackable (MetaWindow *window); +gboolean meta_window_is_focus_async (MetaWindow *window); #endif diff --git a/src/core/window-props.h b/src/core/window-props.h deleted file mode 100644 index cb5c7b6e6..000000000 --- a/src/core/window-props.h +++ /dev/null @@ -1,138 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/** - * \file window-props.h MetaWindow property handling - * - * A system which can inspect sets of properties of given windows - * and take appropriate action given their values. - * - * Note that all the meta_window_reload_propert* functions require a - * round trip to the server. - */ - -/* - * Copyright (C) 2001, 2002 Red Hat, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. - */ - -#ifndef META_WINDOW_PROPS_H -#define META_WINDOW_PROPS_H - -#include "window-private.h" - -/** - * Requests the current values of a single property for a given - * window from the server, and deals with it appropriately. - * Does not return it to the caller (it's been dealt with!) - * - * \param window The window. - * \param property A single X atom. - */ -void meta_window_reload_property (MetaWindow *window, - Atom property, - gboolean initial); - - -/** - * Requests the current values of a set of properties for a given - * window from the server, and deals with them appropriately. - * Does not return them to the caller (they've been dealt with!) - * - * \param window The window. - * \param properties A pointer to a list of X atoms, "n_properties" long. - * \param n_properties The length of the properties list. - */ -void meta_window_reload_properties (MetaWindow *window, - const Atom *properties, - int n_properties, - gboolean initial); - -/** - * Requests the current values of a single property for a given - * window from the server, and deals with it appropriately. - * Does not return it to the caller (it's been dealt with!) - * - * \param window A window on the same display as the one we're - * investigating (only used to find the display) - * \param xwindow The X handle for the window. - * \param property A single X atom. - */ -void meta_window_reload_property_from_xwindow - (MetaWindow *window, - Window xwindow, - Atom property, - gboolean initial); - -/** - * Requests the current values of a set of properties for a given - * window from the server, and deals with them appropriately. - * Does not return them to the caller (they've been dealt with!) - * - * \param window A window on the same display as the one we're - * investigating (only used to find the display) - * \param xwindow The X handle for the window. - * \param properties A pointer to a list of X atoms, "n_properties" long. - * \param n_properties The length of the properties list. - */ -void meta_window_reload_properties_from_xwindow - (MetaWindow *window, - Window xwindow, - const Atom *properties, - int n_properties, - gboolean initial); - -/** - * Requests the current values for standard properties for a given - * window from the server, and deals with them appropriately. - * Does not return them to the caller (they've been dealt with!) - * - * \param window The window. - */ -void meta_window_load_initial_properties (MetaWindow *window); - -/** - * Initialises the hooks used for the reload_propert* functions - * on a particular display, and stores a pointer to them in the - * display. - * - * \param display The display. - */ -void meta_display_init_window_prop_hooks (MetaDisplay *display); - -/** - * Frees the hooks used for the reload_propert* functions - * for a particular display. - * - * \param display The display. - */ -void meta_display_free_window_prop_hooks (MetaDisplay *display); - -/** - * Sets the size hints for a window. This happens when a - * WM_NORMAL_HINTS property is set on a window, but it is public - * because the size hints are set to defaults when a window is - * created. See - * http://tronche.com/gui/x/icccm/sec-4.html#WM_NORMAL_HINTS - * for the X details. - * - * \param window The window to set the size hints on. - * \param hints Either some X size hints, or NULL for default. - */ -void meta_set_normal_hints (MetaWindow *window, - XSizeHints *hints); - -#endif /* META_WINDOW_PROPS_H */ diff --git a/src/core/window.c b/src/core/window.c index 8de68fd18..f20eece4f 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -17,106 +17,122 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ /** - * SECTION:window + * SECTION:meta-window * @title: MetaWindow - * @short_description: Muffin X managed windows + * @short_description: A display-agnostic abstraction for a window. + * + * #MetaWindow is the core abstraction in Mutter of a window. It has the + * properties you'd expect, such as a title, an icon, whether it's fullscreen, + * has decorations, etc. + * + * Since a lot of different kinds of windows exist, each window also a + * #MetaWindowType which denotes which kind of window we're exactly dealing + * with. For example, one expects slightly different behaviour from a dialog + * than a "normal" window. The type of a window can be queried with + * meta_window_get_type(). + * + * Common API for windows include: + * - Minimizing: meta_window_minimize() / meta_window_unminimize() + * - Maximizing: meta_window_maximize() / meta_window_unmaximize() + * - Fullscreen: meta_window_make_fullscreen() / meta_window_unmake_fullscreen() + * / meta_window_is_fullscreen() + * + * Each #MetaWindow is part of either one or all #MetaWorkspace<!-- -->s of the + * desktop. You can activate a window on a certain workspace using + * meta_window_activate_with_workspace(), and query on which workspace it is + * located using meta_window_located_on_workspace(). The workspace it is part + * of can be obtained using meta_window_get_workspace(). + * + * Each display protocol should make a subclass to be compatible with that + * protocols' specifics, for example #MetaWindowX11 and #MetaWindowWayland. + * This is independent of the protocol that the client uses, which is modeled + * using the #MetaWindowClientType enum. + * + * To integrate within the Clutter scene graph, which deals with the actual + * rendering, each #MetaWindow will be part of a #MetaWindowActor. */ -#include <config.h> -#include "window-private.h" -#include "boxes-private.h" -#include "edge-resistance.h" -#include "util-private.h" -#include "frame.h" -#include <meta/errors.h> -#include "workspace-private.h" -#include "stack.h" -#include "keybindings-private.h" -#include "ui.h" -#include "place.h" -#include "session.h" -#include <meta/prefs.h> -#include "resizepopup.h" -#include "xprops.h" -#include <meta/group.h> -#include "window-props.h" -#include "constraints.h" -#include "muffin-enum-types.h" -#include <clutter/clutter.h> +#include "config.h" + +#include "core/window-private.h" -#include <X11/Xatom.h> -#include <X11/Xlibint.h> /* For display->resource_mask */ -#include <X11/Xlib-xcb.h> -#include <xcb/res.h> -#include <string.h> #include <math.h> +#include <stdlib.h> +#include <string.h> +#include <X11/Xatom.h> -#ifdef HAVE_SHAPE -#include <X11/extensions/shape.h> +#include "backends/meta-backend-private.h" +#include "backends/meta-logical-monitor.h" +#include "cogl/cogl.h" +#include "core/boxes-private.h" +#include "core/constraints.h" +#include "core/edge-resistance.h" +#include "core/frame.h" +#include "core/keybindings-private.h" +#include "core/meta-workspace-manager-private.h" +#include "core/place.h" +#include "core/stack.h" +#include "core/util-private.h" +#include "core/workspace-private.h" +#include "meta/compositor-mutter.h" +#include "meta/group.h" +#include "meta/meta-cursor-tracker.h" +#include "meta/meta-enum-types.h" +#include "meta/meta-x11-errors.h" +#include "meta/prefs.h" +#include "ui/ui.h" +#include "x11/meta-x11-display-private.h" +#include "x11/window-props.h" +#include "x11/window-x11.h" +#include "x11/xprops.h" + +#ifdef HAVE_WAYLAND +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-wayland-surface.h" +#include "wayland/meta-window-wayland.h" +#include "wayland/meta-window-xwayland.h" #endif -#include <X11/XKBlib.h> -#include <X11/extensions/Xcomposite.h> -#include <gdk/gdkx.h> + +/* Windows that unmaximize to a size bigger than that fraction of the workarea + * will be scaled down to that size (while maintaining aspect ratio). + * Windows that cover an area greater then this size are automaximized on map. + */ +#define MAX_UNMAXIMIZED_WINDOW_AREA .8 + +#define SNAP_SECURITY_LABEL_PREFIX "snap." static int destroying_windows_disallowed = 0; +/* Each window has a "stamp" which is a non-recycled 64-bit ID. They + * start after the end of the XID space so that, for stacking + * we can keep a guint64 that represents one or the other + */ +static guint64 next_window_stamp = G_GUINT64_CONSTANT(0x100000000); -static void update_sm_hints (MetaWindow *window); -static void update_net_frame_extents (MetaWindow *window); -static void recalc_window_type (MetaWindow *window); -static void recalc_window_features (MetaWindow *window); static void invalidate_work_areas (MetaWindow *window); -static void recalc_window_type (MetaWindow *window); -static void set_wm_state_on_xwindow (MetaDisplay *display, - Window xwindow, - int state); -static void set_wm_state (MetaWindow *window, - int state); +static void set_wm_state (MetaWindow *window); static void set_net_wm_state (MetaWindow *window); static void meta_window_set_above (MetaWindow *window, gboolean new_value); -static void send_configure_notify (MetaWindow *window); -static gboolean process_property_notify (MetaWindow *window, - XPropertyEvent *event); - -static void meta_window_force_placement (MetaWindow *window); - static void meta_window_show (MetaWindow *window); static void meta_window_hide (MetaWindow *window); -static gboolean meta_window_same_client (MetaWindow *window, - MetaWindow *other_window); - static void meta_window_save_rect (MetaWindow *window); -static void save_user_window_placement (MetaWindow *window); -static void force_save_user_window_placement (MetaWindow *window); - -static void meta_window_move_resize_internal (MetaWindow *window, - MetaMoveResizeFlags flags, - int resize_gravity, - int root_x_nw, - int root_y_nw, - int w, - int h); static void ensure_mru_position_after (MetaWindow *window, MetaWindow *after_this_one); - static void meta_window_move_resize_now (MetaWindow *window); static void meta_window_unqueue (MetaWindow *window, guint queuebits); static void update_move (MetaWindow *window, - gboolean legacy_snap, - gboolean snap_mode, + gboolean snap, int x, int y); static gboolean update_move_timeout (gpointer data); @@ -133,23 +149,26 @@ static void meta_window_flush_calc_showing (MetaWindow *window); static gboolean queue_calc_showing_func (MetaWindow *window, void *data); -static void meta_window_apply_session_info (MetaWindow *window, - const MetaWindowSessionInfo *info); static void meta_window_move_between_rects (MetaWindow *window, + MetaMoveResizeFlags move_resize_flags, const MetaRectangle *old_area, const MetaRectangle *new_area); static void unmaximize_window_before_freeing (MetaWindow *window); static void unminimize_window_and_all_transient_parents (MetaWindow *window); -static void meta_window_update_monitor (MetaWindow *window); - -static void normalize_tile_state (MetaWindow *window); +static void meta_window_propagate_focus_appearance (MetaWindow *window, + gboolean focused); +static void meta_window_update_icon_now (MetaWindow *window, + gboolean force); -static unsigned int get_mask_from_snap_keysym (MetaWindow *window); +static void set_workspace_state (MetaWindow *window, + gboolean on_all_workspaces, + MetaWorkspace *workspace); +static MetaWindow * meta_window_find_tile_match (MetaWindow *window, + MetaTileMode mode); static void update_edge_constraints (MetaWindow *window); -static void update_gtk_edge_constraints (MetaWindow *window); /* Idle handlers for the three queues (run with meta_later_add()). The * "data" parameter in each case will be a GINT_TO_POINTER of the @@ -160,26 +179,28 @@ static void update_gtk_edge_constraints (MetaWindow *window); */ static gboolean idle_calc_showing (gpointer data); static gboolean idle_move_resize (gpointer data); +static gboolean idle_update_icon (gpointer data); -G_DEFINE_TYPE (MetaWindow, meta_window, G_TYPE_OBJECT); +G_DEFINE_ABSTRACT_TYPE (MetaWindow, meta_window, G_TYPE_OBJECT); -#define SNAP_DELAY 2000 - -enum { +enum +{ PROP_0, PROP_TITLE, + PROP_ICON, + PROP_MINI_ICON, PROP_DECORATED, PROP_FULLSCREEN, PROP_MAXIMIZED_HORIZONTALLY, PROP_MAXIMIZED_VERTICALLY, - PROP_TILE_TYPE, PROP_MINIMIZED, PROP_WINDOW_TYPE, PROP_USER_TIME, PROP_DEMANDS_ATTENTION, PROP_URGENT, - PROP_MUFFIN_HINTS, + PROP_SKIP_TASKBAR, + PROP_MUTTER_HINTS, PROP_APPEARS_FOCUSED, PROP_RESIZEABLE, PROP_ABOVE, @@ -190,35 +211,28 @@ enum { PROP_GTK_WINDOW_OBJECT_PATH, PROP_GTK_APP_MENU_OBJECT_PATH, PROP_GTK_MENUBAR_OBJECT_PATH, - PROP_PROGRESS, - PROP_PROGRESS_PULSE + PROP_ON_ALL_WORKSPACES, + + PROP_LAST, }; +static GParamSpec *obj_props[PROP_LAST]; + enum { WORKSPACE_CHANGED, FOCUS, RAISED, + UNMANAGING, UNMANAGED, SIZE_CHANGED, POSITION_CHANGED, - ICON_CHANGED, + MONITOR_CHANGED, + SHOWN, LAST_SIGNAL }; -typedef enum -{ - ZONE_TOP = 1 << 0, - ZONE_RIGHT = 1 << 1, - ZONE_BOTTOM = 1 << 2, - ZONE_LEFT = 1 << 3, - ZONE_ULC = ZONE_TOP | ZONE_LEFT, - ZONE_LLC = ZONE_BOTTOM | ZONE_LEFT, - ZONE_URC = ZONE_TOP | ZONE_RIGHT, - ZONE_LRC = ZONE_BOTTOM | ZONE_RIGHT -} TileZone; - static guint window_signals[LAST_SIGNAL] = { 0 }; static void @@ -227,12 +241,66 @@ prefs_changed_callback (MetaPreference pref, { MetaWindow *window = data; - if (pref != META_PREF_WORKSPACES_ONLY_ON_PRIMARY) - return; + if (pref == META_PREF_WORKSPACES_ONLY_ON_PRIMARY) + { + meta_window_on_all_workspaces_changed (window); + } + else if (pref == META_PREF_ATTACH_MODAL_DIALOGS && + window->type == META_WINDOW_MODAL_DIALOG) + { + window->attached = meta_window_should_attach_to_parent (window); + meta_window_recalc_features (window); + meta_window_queue (window, META_QUEUE_MOVE_RESIZE); + } +} - meta_window_update_on_all_workspaces (window); +static void +meta_window_real_grab_op_began (MetaWindow *window, + MetaGrabOp op) +{ +} - meta_window_queue (window, META_QUEUE_CALC_SHOWING); +static void +meta_window_real_grab_op_ended (MetaWindow *window, + MetaGrabOp op) +{ + window->shaken_loose = FALSE; +} + +static void +meta_window_real_current_workspace_changed (MetaWindow *window) +{ +} + +static gboolean +meta_window_real_update_struts (MetaWindow *window) +{ + return FALSE; +} + +static void +meta_window_real_get_default_skip_hints (MetaWindow *window, + gboolean *skip_taskbar_out, + gboolean *skip_pager_out) +{ + *skip_taskbar_out = FALSE; + *skip_pager_out = FALSE; +} + +static gboolean +meta_window_real_update_icon (MetaWindow *window, + cairo_surface_t **icon, + cairo_surface_t **mini_icon) +{ + *icon = NULL; + *mini_icon = NULL; + return FALSE; +} + +static uint32_t +meta_window_real_get_client_pid (MetaWindow *window) +{ + return 0; } static void @@ -241,34 +309,43 @@ meta_window_finalize (GObject *object) MetaWindow *window = META_WINDOW (object); if (window->icon) - g_object_unref (G_OBJECT (window->icon)); + cairo_surface_destroy (window->icon); + + if (window->mini_icon) + cairo_surface_destroy (window->mini_icon); if (window->frame_bounds) cairo_region_destroy (window->frame_bounds); + if (window->shape_region) + cairo_region_destroy (window->shape_region); + if (window->opaque_region) cairo_region_destroy (window->opaque_region); - meta_icon_cache_free (&window->icon_cache); - - free (window->sm_client_id); - free (window->wm_client_machine); - free (window->startup_id); - free (window->muffin_hints); - free (window->role); - free (window->res_class); - free (window->res_name); - free (window->title); - free (window->icon_name); - free (window->theme_icon_name); - free (window->desc); - free (window->gtk_theme_variant); - free (window->gtk_application_id); - free (window->gtk_unique_bus_name); - free (window->gtk_application_object_path); - free (window->gtk_window_object_path); - free (window->gtk_app_menu_object_path); - free (window->gtk_menubar_object_path); + if (window->input_region) + cairo_region_destroy (window->input_region); + + if (window->transient_for) + g_object_unref (window->transient_for); + + g_free (window->sm_client_id); + g_free (window->wm_client_machine); + g_free (window->startup_id); + g_free (window->role); + g_free (window->res_class); + g_free (window->res_name); + g_free (window->title); + g_free (window->desc); + g_free (window->sandboxed_app_id); + g_free (window->gtk_theme_variant); + g_free (window->gtk_application_id); + g_free (window->gtk_unique_bus_name); + g_free (window->gtk_application_object_path); + g_free (window->gtk_window_object_path); + g_free (window->gtk_app_menu_object_path); + g_free (window->gtk_menubar_object_path); + g_free (window->placement.rule); G_OBJECT_CLASS (meta_window_parent_class)->finalize (object); } @@ -286,6 +363,12 @@ meta_window_get_property(GObject *object, case PROP_TITLE: g_value_set_string (value, win->title); break; + case PROP_ICON: + g_value_set_pointer (value, win->icon); + break; + case PROP_MINI_ICON: + g_value_set_pointer (value, win->mini_icon); + break; case PROP_DECORATED: g_value_set_boolean (value, win->decorated); break; @@ -298,9 +381,6 @@ meta_window_get_property(GObject *object, case PROP_MAXIMIZED_VERTICALLY: g_value_set_boolean (value, win->maximized_vertically); break; - case PROP_TILE_TYPE: - g_value_set_int (value, win->tile_type); - break; case PROP_MINIMIZED: g_value_set_boolean (value, win->minimized); break; @@ -314,10 +394,13 @@ meta_window_get_property(GObject *object, g_value_set_boolean (value, win->wm_state_demands_attention); break; case PROP_URGENT: - g_value_set_boolean (value, win->wm_hints_urgent); + g_value_set_boolean (value, win->urgent); + break; + case PROP_SKIP_TASKBAR: + g_value_set_boolean (value, win->skip_taskbar); break; - case PROP_MUFFIN_HINTS: - g_value_set_string (value, win->muffin_hints); + case PROP_MUTTER_HINTS: + g_value_set_string (value, win->mutter_hints); break; case PROP_APPEARS_FOCUSED: g_value_set_boolean (value, meta_window_appears_focused (win)); @@ -349,11 +432,8 @@ meta_window_get_property(GObject *object, case PROP_GTK_MENUBAR_OBJECT_PATH: g_value_set_string (value, win->gtk_menubar_object_path); break; - case PROP_PROGRESS: - g_value_set_uint (value, win->progress); - break; - case PROP_PROGRESS_PULSE: - g_value_set_boolean (value, win->progress_pulse); + case PROP_ON_ALL_WORKSPACES: + g_value_set_boolean (value, win->on_all_workspaces); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -385,218 +465,181 @@ meta_window_class_init (MetaWindowClass *klass) object_class->get_property = meta_window_get_property; object_class->set_property = meta_window_set_property; - g_object_class_install_property (object_class, - PROP_TITLE, - g_param_spec_string ("title", - "Title", - "The title of the window", - NULL, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, - PROP_DECORATED, - g_param_spec_boolean ("decorated", - "Decorated", - "Whether window is decorated", - TRUE, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, - PROP_FULLSCREEN, - g_param_spec_boolean ("fullscreen", - "Fullscreen", - "Whether window is fullscreened", - FALSE, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, - PROP_MAXIMIZED_HORIZONTALLY, - g_param_spec_boolean ("maximized-horizontally", - "Maximized horizontally", - "Whether window is maximized horizontally", - FALSE, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, - PROP_MAXIMIZED_VERTICALLY, - g_param_spec_boolean ("maximized-vertically", - "Maximizing vertically", - "Whether window is maximized vertically", - FALSE, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, - PROP_TILE_TYPE, - g_param_spec_int ("tile-type", - "Window is tiled or snapped", - "Whether window is tiled or snapped", - META_WINDOW_TILE_TYPE_NONE, - META_WINDOW_TILE_TYPE_SNAPPED, - META_WINDOW_TILE_TYPE_NONE, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, - PROP_MINIMIZED, - g_param_spec_boolean ("minimized", - "Minimizing", - "Whether window is minimized", - FALSE, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, - PROP_WINDOW_TYPE, - g_param_spec_enum ("window-type", - "Window Type", - "The type of the window", - META_TYPE_WINDOW_TYPE, - META_WINDOW_NORMAL, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, - PROP_USER_TIME, - g_param_spec_uint ("user-time", - "User time", - "Timestamp of last user interaction", - 0, - G_MAXUINT, - 0, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, - PROP_DEMANDS_ATTENTION, - g_param_spec_boolean ("demands-attention", - "Demands Attention", - "Whether the window has _NET_WM_STATE_DEMANDS_ATTENTION set", - FALSE, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, - PROP_URGENT, - g_param_spec_boolean ("urgent", - "Urgent", - "Whether the urgent flag of WM_HINTS is set", - FALSE, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, - PROP_MUFFIN_HINTS, - g_param_spec_string ("muffin-hints", - "_MUFFIN_HINTS", - "Contents of the _MUFFIN_HINTS property of this window", - NULL, - G_PARAM_READABLE)); - g_object_class_install_property (object_class, - PROP_APPEARS_FOCUSED, - g_param_spec_boolean ("appears-focused", - "Appears focused", - "Whether the window is drawn as being focused", - FALSE, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, - PROP_RESIZEABLE, - g_param_spec_boolean ("resizeable", - "Resizeable", - "Whether the window can be resized", - FALSE, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, - PROP_ABOVE, - g_param_spec_boolean ("above", - "Above", - "Whether the window is shown as always-on-top", - FALSE, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, - PROP_WM_CLASS, - g_param_spec_string ("wm-class", - "WM_CLASS", - "Contents of the WM_CLASS property of this window", - NULL, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, - PROP_GTK_APPLICATION_ID, - g_param_spec_string ("gtk-application-id", - "_GTK_APPLICATION_ID", - "Contents of the _GTK_APPLICATION_ID property of this window", - NULL, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, - PROP_GTK_UNIQUE_BUS_NAME, - g_param_spec_string ("gtk-unique-bus-name", - "_GTK_UNIQUE_BUS_NAME", - "Contents of the _GTK_UNIQUE_BUS_NAME property of this window", - NULL, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, - PROP_GTK_APPLICATION_OBJECT_PATH, - g_param_spec_string ("gtk-application-object-path", - "_GTK_APPLICATION_OBJECT_PATH", - "Contents of the _GTK_APPLICATION_OBJECT_PATH property of this window", - NULL, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, - PROP_GTK_WINDOW_OBJECT_PATH, - g_param_spec_string ("gtk-window-object-path", - "_GTK_WINDOW_OBJECT_PATH", - "Contents of the _GTK_WINDOW_OBJECT_PATH property of this window", - NULL, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, - PROP_GTK_APP_MENU_OBJECT_PATH, - g_param_spec_string ("gtk-app-menu-object-path", - "_GTK_APP_MENU_OBJECT_PATH", - "Contents of the _GTK_APP_MENU_OBJECT_PATH property of this window", - NULL, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, - PROP_GTK_MENUBAR_OBJECT_PATH, - g_param_spec_string ("gtk-menubar-object-path", - "_GTK_MENUBAR_OBJECT_PATH", - "Contents of the _GTK_MENUBAR_OBJECT_PATH property of this window", - NULL, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, - PROP_PROGRESS, - g_param_spec_uint ("progress", - "Progress", - "The progress of some long-running operation", - 0, - 100, - 0, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, - PROP_PROGRESS_PULSE, - g_param_spec_boolean ("progress-pulse", - "Pulsing progress", - "Show indeterminate or ongoing progress of an operation.", - FALSE, - G_PARAM_READABLE)); + klass->grab_op_began = meta_window_real_grab_op_began; + klass->grab_op_ended = meta_window_real_grab_op_ended; + klass->current_workspace_changed = meta_window_real_current_workspace_changed; + klass->update_struts = meta_window_real_update_struts; + klass->get_default_skip_hints = meta_window_real_get_default_skip_hints; + klass->update_icon = meta_window_real_update_icon; + klass->get_client_pid = meta_window_real_get_client_pid; + + obj_props[PROP_TITLE] = + g_param_spec_string ("title", + "Title", + "The title of the window", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_props[PROP_ICON] = + g_param_spec_pointer ("icon", + "Icon", + "Normal icon, usually 96x96 pixels", + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_props[PROP_MINI_ICON] = + g_param_spec_pointer ("mini-icon", + "Mini Icon", + "Mini icon, usually 16x16 pixels", + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_props[PROP_DECORATED] = + g_param_spec_boolean ("decorated", + "Decorated", + "Whether window is decorated", + TRUE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_props[PROP_FULLSCREEN] = + g_param_spec_boolean ("fullscreen", + "Fullscreen", + "Whether window is fullscreened", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_props[PROP_MAXIMIZED_HORIZONTALLY] = + g_param_spec_boolean ("maximized-horizontally", + "Maximized horizontally", + "Whether window is maximized horizontally", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_props[PROP_MAXIMIZED_VERTICALLY] = + g_param_spec_boolean ("maximized-vertically", + "Maximizing vertically", + "Whether window is maximized vertically", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_props[PROP_MINIMIZED] = + g_param_spec_boolean ("minimized", + "Minimizing", + "Whether window is minimized", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_props[PROP_WINDOW_TYPE] = + g_param_spec_enum ("window-type", + "Window Type", + "The type of the window", + META_TYPE_WINDOW_TYPE, + META_WINDOW_NORMAL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_props[PROP_USER_TIME] = + g_param_spec_uint ("user-time", + "User time", + "Timestamp of last user interaction", + 0, + G_MAXUINT, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_props[PROP_DEMANDS_ATTENTION] = + g_param_spec_boolean ("demands-attention", + "Demands Attention", + "Whether the window has _NET_WM_STATE_DEMANDS_ATTENTION set", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_props[PROP_URGENT] = + g_param_spec_boolean ("urgent", + "Urgent", + "Whether the urgent flag of WM_HINTS is set", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_props[PROP_SKIP_TASKBAR] = + g_param_spec_boolean ("skip-taskbar", + "Skip taskbar", + "Whether the skip-taskbar flag of WM_HINTS is set", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_props[PROP_MUTTER_HINTS] = + g_param_spec_string ("mutter-hints", + "_MUTTER_HINTS", + "Contents of the _MUTTER_HINTS property of this window", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_props[PROP_APPEARS_FOCUSED] = + g_param_spec_boolean ("appears-focused", + "Appears focused", + "Whether the window is drawn as being focused", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_props[PROP_RESIZEABLE] = + g_param_spec_boolean ("resizeable", + "Resizeable", + "Whether the window can be resized", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_props[PROP_ABOVE] = + g_param_spec_boolean ("above", + "Above", + "Whether the window is shown as always-on-top", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_props[PROP_WM_CLASS] = + g_param_spec_string ("wm-class", + "WM_CLASS", + "Contents of the WM_CLASS property of this window", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_props[PROP_GTK_APPLICATION_ID] = + g_param_spec_string ("gtk-application-id", + "_GTK_APPLICATION_ID", + "Contents of the _GTK_APPLICATION_ID property of this window", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_props[PROP_GTK_UNIQUE_BUS_NAME] = + g_param_spec_string ("gtk-unique-bus-name", + "_GTK_UNIQUE_BUS_NAME", + "Contents of the _GTK_UNIQUE_BUS_NAME property of this window", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_props[PROP_GTK_APPLICATION_OBJECT_PATH] = + g_param_spec_string ("gtk-application-object-path", + "_GTK_APPLICATION_OBJECT_PATH", + "Contents of the _GTK_APPLICATION_OBJECT_PATH property of this window", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_props[PROP_GTK_WINDOW_OBJECT_PATH] = + g_param_spec_string ("gtk-window-object-path", + "_GTK_WINDOW_OBJECT_PATH", + "Contents of the _GTK_WINDOW_OBJECT_PATH property of this window", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_props[PROP_GTK_APP_MENU_OBJECT_PATH] = + g_param_spec_string ("gtk-app-menu-object-path", + "_GTK_APP_MENU_OBJECT_PATH", + "Contents of the _GTK_APP_MENU_OBJECT_PATH property of this window", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_props[PROP_GTK_MENUBAR_OBJECT_PATH] = + g_param_spec_string ("gtk-menubar-object-path", + "_GTK_MENUBAR_OBJECT_PATH", + "Contents of the _GTK_MENUBAR_OBJECT_PATH property of this window", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_props[PROP_ON_ALL_WORKSPACES] = + g_param_spec_boolean ("on-all-workspaces", + "On all workspaces", + "Whether the window is set to appear on all workspaces", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, PROP_LAST, obj_props); window_signals[WORKSPACE_CHANGED] = g_signal_new ("workspace-changed", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (MetaWindowClass, workspace_changed), + 0, NULL, NULL, NULL, - G_TYPE_NONE, 1, - G_TYPE_INT); + G_TYPE_NONE, 0); window_signals[FOCUS] = g_signal_new ("focus", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (MetaWindowClass, focus), + 0, NULL, NULL, NULL, G_TYPE_NONE, 0); @@ -604,7 +647,15 @@ meta_window_class_init (MetaWindowClass *klass) g_signal_new ("raised", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (MetaWindowClass, raised), + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); + + window_signals[UNMANAGING] = + g_signal_new ("unmanaging", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, G_TYPE_NONE, 0); @@ -612,10 +663,19 @@ meta_window_class_init (MetaWindowClass *klass) g_signal_new ("unmanaged", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (MetaWindowClass, unmanaged), + 0, NULL, NULL, NULL, G_TYPE_NONE, 0); + /** + * MetaWindow::position-changed: + * @window: a #MetaWindow + * + * This is emitted when the position of a window might + * have changed. Specifically, this is emitted when the + * position of the toplevel window has changed, or when + * the position of the client window has changed. + */ window_signals[POSITION_CHANGED] = g_signal_new ("position-changed", G_TYPE_FROM_CLASS (object_class), @@ -624,16 +684,46 @@ meta_window_class_init (MetaWindowClass *klass) NULL, NULL, NULL, G_TYPE_NONE, 0); - window_signals[SIZE_CHANGED] = - g_signal_new ("size-changed", + /** + * MetaWindow::monitor-changed: + * @window: a #MetaWindow + * @old_monitor: the old monitor index or -1 if not known + * + * This is emitted when the window has changed monitor + */ + window_signals[MONITOR_CHANGED] = + g_signal_new ("monitor-changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 1, G_TYPE_INT); + + /** + * MetaWindow::shown: + * @window: a #MetaWindow + * + * This is emitted after a window has been shown. + */ + window_signals[SHOWN] = + g_signal_new ("shown", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); - window_signals[ICON_CHANGED] = - g_signal_new ("icon-changed", + /** + * MetaWindow::size-changed: + * @window: a #MetaWindow + * + * This is emitted when the size of a window might + * have changed. Specifically, this is emitted when the + * size of the toplevel window has changed, or when the + * size of the client window has changed. + */ + window_signals[SIZE_CHANGED] = + g_signal_new ("size-changed", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, 0, @@ -644,27 +734,10 @@ meta_window_class_init (MetaWindowClass *klass) static void meta_window_init (MetaWindow *self) { + self->stamp = next_window_stamp++; meta_prefs_add_listener (prefs_changed_callback, self); } -#ifdef WITH_VERBOSE_MODE -static const char* -wm_state_to_string (int state) -{ - switch (state) - { - case NormalState: - return "NormalState"; - case IconicState: - return "IconicState"; - case WithdrawnState: - return "WithdrawnState"; - } - - return "Unknown"; -} -#endif - static gboolean is_desktop_or_dock_foreach (MetaWindow *window, void *data) @@ -686,9 +759,10 @@ is_desktop_or_dock_foreach (MetaWindow *window, static void maybe_leave_show_desktop_mode (MetaWindow *window) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; gboolean is_desktop_or_dock; - if (!window->screen->active_workspace->showing_desktop) + if (!workspace_manager->active_workspace->showing_desktop) return; /* If the window is a transient for the dock or desktop, don't @@ -705,312 +779,229 @@ maybe_leave_show_desktop_mode (MetaWindow *window) if (!is_desktop_or_dock) { - meta_screen_minimize_all_on_active_workspace_except (window->screen, - window); - meta_screen_unshow_desktop (window->screen); + meta_workspace_manager_minimize_all_on_active_workspace_except (workspace_manager, + window); + meta_workspace_manager_unshow_desktop (workspace_manager); + } +} + +gboolean +meta_window_should_attach_to_parent (MetaWindow *window) +{ + MetaWindow *parent; + + if (!meta_prefs_get_attach_modal_dialogs () || + window->type != META_WINDOW_MODAL_DIALOG) + return FALSE; + + parent = meta_window_get_transient_for (window); + if (!parent) + return FALSE; + + switch (parent->type) + { + case META_WINDOW_NORMAL: + case META_WINDOW_DIALOG: + case META_WINDOW_MODAL_DIALOG: + return TRUE; + + default: + return FALSE; } } static gboolean client_window_should_be_mapped (MetaWindow *window) { +#ifdef HAVE_WAYLAND + if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND && + !meta_wayland_surface_get_buffer (window->surface)) + return FALSE; +#endif + return !window->shaded; } static void sync_client_window_mapped (MetaWindow *window) { - gboolean should_be_mapped; + gboolean should_be_mapped = client_window_should_be_mapped (window); g_return_if_fail (!window->override_redirect); - should_be_mapped = client_window_should_be_mapped (window); if (window->mapped == should_be_mapped) return; window->mapped = should_be_mapped; - meta_error_trap_push (window->display); - if (should_be_mapped) - { - XMapWindow (window->display->xdisplay, window->xwindow); - } + if (window->mapped) + META_WINDOW_GET_CLASS (window)->map (window); else - { - XUnmapWindow (window->display->xdisplay, window->xwindow); - window->unmaps_pending ++; - } - meta_error_trap_pop (window->display); + META_WINDOW_GET_CLASS (window)->unmap (window); } -static void -update_client_pid (MetaWindow *window) +static gboolean +meta_window_update_flatpak_id (MetaWindow *window, + uint32_t pid) { - MetaDisplay *display = window->display; - xcb_connection_t *xcb = XGetXCBConnection (display->xdisplay); - xcb_res_client_id_spec_t spec = { 0 }; - xcb_res_query_client_ids_cookie_t cookie; - xcb_res_query_client_ids_reply_t *reply = NULL; + g_autoptr(GKeyFile) key_file = NULL; + g_autofree char *info_filename = NULL; - spec.client = window->xwindow; - spec.mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID; + g_return_val_if_fail (pid != 0, FALSE); + g_return_val_if_fail (window->sandboxed_app_id == NULL, FALSE); - cookie = xcb_res_query_client_ids (xcb, 1, &spec); - reply = xcb_res_query_client_ids_reply (xcb, cookie, NULL); + key_file = g_key_file_new (); + info_filename = g_strdup_printf ("/proc/%u/root/.flatpak-info", pid); - if (reply == NULL) - { - window->client_pid = -1; - return; - } + if (!g_key_file_load_from_file (key_file, info_filename, G_KEY_FILE_NONE, NULL)) + return FALSE; - int pid = -1, *value; - xcb_res_client_id_value_iterator_t it; - for (it = xcb_res_query_client_ids_ids_iterator (reply); - it.rem; - xcb_res_client_id_value_next (&it)) - { - spec = it.data->spec; - if (spec.mask & XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID) - { - value = xcb_res_client_id_value_value (it.data); - window->client_pid = *value; - break; - } - } + window->sandboxed_app_id = g_key_file_get_string (key_file, "Application", "name", NULL); - free (reply); + return TRUE; } -LOCAL_SYMBOL MetaWindow* -meta_window_new (MetaDisplay *display, - Window xwindow, - gboolean must_be_viewable) +static gboolean +meta_window_update_snap_id (MetaWindow *window, + uint32_t pid) { - XWindowAttributes attrs; - MetaWindow *window; + g_autofree char *security_label_filename = NULL; + g_autofree char *security_label_contents = NULL; + gsize i, security_label_contents_size = 0; + char *contents_start; + char *contents_end; + char *sandboxed_app_id; - meta_display_grab (display); - meta_error_trap_push (display); /* Push a trap over all of window - * creation, to reduce XSync() calls - */ - - meta_error_trap_push_with_return (display); - - if (XGetWindowAttributes (display->xdisplay,xwindow, &attrs)) - { - if(meta_error_trap_pop_with_return (display) != Success) - { - meta_verbose ("Failed to get attributes for window 0x%lx\n", - xwindow); - meta_error_trap_pop (display); - meta_display_ungrab (display); - return NULL; - } - window = meta_window_new_with_attrs (display, xwindow, - must_be_viewable, - META_COMP_EFFECT_CREATE, - &attrs); - } - else - { - meta_error_trap_pop_with_return (display); - meta_verbose ("Failed to get attributes for window 0x%lx\n", - xwindow); - meta_error_trap_pop (display); - meta_display_ungrab (display); - return NULL; - } + g_return_val_if_fail (pid != 0, FALSE); + g_return_val_if_fail (window->sandboxed_app_id == NULL, FALSE); + security_label_filename = g_strdup_printf ("/proc/%u/attr/current", pid); - meta_error_trap_pop (display); - meta_display_ungrab (display); + if (!g_file_get_contents (security_label_filename, + &security_label_contents, + &security_label_contents_size, + NULL)) + return FALSE; - return window; -} + if (!g_str_has_prefix (security_label_contents, SNAP_SECURITY_LABEL_PREFIX)) + return FALSE; -/* The MUFFIN_WM_CLASS_FILTER environment variable is designed for - * performance and regression testing environments where we want to do - * tests with only a limited set of windows and ignore all other windows - * - * When it is set to a comma separated list of WM_CLASS class names, all - * windows not matching the list will be ignored. - * - * Returns TRUE if window has been filtered out and should be ignored. - */ -static gboolean -maybe_filter_window (MetaDisplay *display, - Window xwindow, - gboolean must_be_viewable, - XWindowAttributes *attrs) -{ - static char **filter_wm_classes = NULL; - static gboolean initialized = FALSE; - XClassHint class_hint; - gboolean filtered; - Status success; - int i; + /* We need to translate the security profile into the desktop-id. + * The profile is in the form of 'snap.name-space.binary-name (current)' + * while the desktop id will be name-space_binary-name. + */ + security_label_contents_size -= sizeof (SNAP_SECURITY_LABEL_PREFIX) - 1; + contents_start = security_label_contents + sizeof (SNAP_SECURITY_LABEL_PREFIX) - 1; + contents_end = strchr (contents_start, ' '); + + if (contents_end) + security_label_contents_size = contents_end - contents_start; - if (!initialized) + for (i = 0; i < security_label_contents_size; ++i) { - const char *filter_string = g_getenv ("MUFFIN_WM_CLASS_FILTER"); - if (filter_string) - filter_wm_classes = g_strsplit (filter_string, ",", -1); - initialized = TRUE; + if (contents_start[i] == '.') + contents_start[i] = '_'; } - if (!filter_wm_classes || !filter_wm_classes[0]) - return FALSE; - - filtered = TRUE; + sandboxed_app_id = g_malloc0 (security_label_contents_size + 1); + memcpy (sandboxed_app_id, contents_start, security_label_contents_size); - meta_error_trap_push (display); - success = XGetClassHint (display->xdisplay, xwindow, &class_hint); + window->sandboxed_app_id = sandboxed_app_id; - if (success) - { - for (i = 0; filter_wm_classes[i]; i++) - { - if (strcmp (class_hint.res_class, filter_wm_classes[i]) == 0) - { - filtered = FALSE; - break; - } - } - - XFree (class_hint.res_name); - XFree (class_hint.res_class); - } + return TRUE; +} - if (filtered) - { - /* We want to try and get the window managed by the next WM that come along, - * so we need to make sure that windows that are requested to be mapped while - * Muffin is running (!must_be_viewable), or windows already viewable at startup - * get a non-withdrawn WM_STATE property. Previously unmapped windows are left - * with whatever WM_STATE property they had. - */ - if (!must_be_viewable || attrs->map_state == IsViewable) - { - gulong old_state; +static void +meta_window_update_sandboxed_app_id (MetaWindow *window) +{ + uint32_t pid; - if (!meta_prop_get_cardinal_with_atom_type (display, xwindow, - display->atom_WM_STATE, - display->atom_WM_STATE, - &old_state)) - old_state = WithdrawnState; + g_clear_pointer (&window->sandboxed_app_id, g_free); - if (old_state == WithdrawnState) - set_wm_state_on_xwindow (display, xwindow, NormalState); - } + pid = meta_window_get_client_pid (window); - /* Make sure filtered windows are hidden from view */ - XUnmapWindow (display->xdisplay, xwindow); - } + if (pid == 0) + return; - meta_error_trap_pop (display); + if (meta_window_update_flatpak_id (window, pid)) + return; - return filtered; + if (meta_window_update_snap_id (window, pid)) + return; } -LOCAL_SYMBOL gboolean -meta_window_should_attach_to_parent (MetaWindow *window) +static void +meta_window_update_desc (MetaWindow *window) { - MetaWindow *parent; - - if (!meta_prefs_get_attach_modal_dialogs () || - window->type != META_WINDOW_MODAL_DIALOG) - return FALSE; - - parent = meta_window_get_transient_for (window); - if (!parent) - return FALSE; + g_clear_pointer (&window->desc, g_free); - switch (parent->type) + if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) + window->desc = g_strdup_printf ("0x%lx", window->xwindow); + else { - case META_WINDOW_NORMAL: - case META_WINDOW_DIALOG: - case META_WINDOW_MODAL_DIALOG: - return TRUE; + guint64 small_stamp = window->stamp - G_GUINT64_CONSTANT(0x100000000); - default: - return FALSE; + window->desc = g_strdup_printf ("W%" G_GUINT64_FORMAT , small_stamp); } } -LOCAL_SYMBOL LOCAL_SYMBOL MetaWindow* -meta_window_new_with_attrs (MetaDisplay *display, - Window xwindow, - gboolean must_be_viewable, - MetaCompEffect effect, - XWindowAttributes *attrs) +static void +meta_window_main_monitor_changed (MetaWindow *window, + const MetaLogicalMonitor *old) { - MetaWindow *window; - GSList *tmp; - MetaWorkspace *space; - gulong existing_wm_state; - gulong event_mask; - MetaMoveResizeFlags flags; - gboolean has_shape; - MetaScreen *screen; + META_WINDOW_GET_CLASS (window)->main_monitor_changed (window, old); - g_assert (attrs != NULL); + g_signal_emit (window, window_signals[MONITOR_CHANGED], 0, + old ? old->number : -1); - meta_verbose ("Attempting to manage 0x%lx\n", xwindow); + if (old) + g_signal_emit_by_name (window->display, "window-left-monitor", + old->number, window); + if (window->monitor) + g_signal_emit_by_name (window->display, "window-entered-monitor", + window->monitor->number, window); +} - if (meta_display_xwindow_is_a_no_focus_window (display, xwindow)) - { - meta_verbose ("Not managing no_focus_window 0x%lx\n", - xwindow); - return NULL; - } +MetaLogicalMonitor * +meta_window_calculate_main_logical_monitor (MetaWindow *window) +{ + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaRectangle window_rect; - screen = NULL; - for (tmp = display->screens; tmp != NULL; tmp = tmp->next) - { - MetaScreen *scr = tmp->data; + meta_window_get_frame_rect (window, &window_rect); + return meta_monitor_manager_get_logical_monitor_from_rect (monitor_manager, + &window_rect); +} - if (scr->xroot == attrs->root) - { - screen = tmp->data; - break; - } - } +static void +meta_window_manage (MetaWindow *window) +{ + COGL_TRACE_BEGIN_SCOPED (MetaWindowManage, + "Window (manage)"); - g_assert (screen); - - /* A black list of override redirect windows that we don't need to manage: */ - if (attrs->override_redirect && - (xwindow == screen->no_focus_window || - xwindow == screen->flash_window || - xwindow == screen->wm_sn_selection_window || - attrs->class == InputOnly || - /* any windows created via meta_create_offscreen_window: */ - (attrs->x == -100 && attrs->y == -100 - && attrs->width == 1 && attrs->height == 1) || - xwindow == screen->wm_cm_selection_window || - xwindow == screen->guard_window || - xwindow == screen->composite_overlay_window - ) - ) { - meta_verbose ("Not managing our own windows\n"); - return NULL; - } + META_WINDOW_GET_CLASS (window)->manage (window); +} - if (maybe_filter_window (display, xwindow, must_be_viewable, attrs)) - { - meta_verbose ("Not managing filtered window\n"); - return NULL; - } +MetaWindow * +_meta_window_shared_new (MetaDisplay *display, + MetaWindowClientType client_type, + MetaWaylandSurface *surface, + Window xwindow, + gulong existing_wm_state, + MetaCompEffect effect, + XWindowAttributes *attrs) +{ + MetaWorkspaceManager *workspace_manager = display->workspace_manager; + MetaWindow *window; - /* Grab server */ - meta_display_grab (display); - meta_error_trap_push (display); /* Push a trap over all of window - * creation, to reduce XSync() calls - */ + COGL_TRACE_BEGIN_SCOPED (MetaWindowSharedNew, + "Window (new)"); - meta_verbose ("must_be_viewable = %d attrs->map_state = %d (%s)\n", - must_be_viewable, + g_assert (attrs != NULL); + + meta_verbose ("attrs->map_state = %d (%s)\n", attrs->map_state, (attrs->map_state == IsUnmapped) ? "IsUnmapped" : @@ -1020,150 +1011,47 @@ meta_window_new_with_attrs (MetaDisplay *display, "IsUnviewable" : "(unknown)"); - existing_wm_state = WithdrawnState; - if (must_be_viewable && attrs->map_state != IsViewable) - { - /* Only manage if WM_STATE is IconicState or NormalState */ - gulong state; + if (client_type == META_WINDOW_CLIENT_TYPE_X11 && !meta_is_wayland_compositor ()) + window = g_object_new (META_TYPE_WINDOW_X11, NULL); +#ifdef HAVE_WAYLAND + else if (client_type == META_WINDOW_CLIENT_TYPE_X11) + window = g_object_new (META_TYPE_WINDOW_XWAYLAND, NULL); + else if (client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) + window = g_object_new (META_TYPE_WINDOW_WAYLAND, NULL); +#endif + else + g_assert_not_reached (); - /* WM_STATE isn't a cardinal, it's type WM_STATE, but is an int */ - if (!(meta_prop_get_cardinal_with_atom_type (display, xwindow, - display->atom_WM_STATE, - display->atom_WM_STATE, - &state) && - (state == IconicState || state == NormalState))) - { - meta_verbose ("Deciding not to manage unmapped or unviewable window 0x%lx\n", xwindow); - meta_error_trap_pop (display); - meta_display_ungrab (display); - return NULL; - } + window->constructing = TRUE; - existing_wm_state = state; - meta_verbose ("WM_STATE of %lx = %s\n", xwindow, - wm_state_to_string (existing_wm_state)); - } + window->client_type = client_type; + window->surface = surface; + window->xwindow = xwindow; - meta_error_trap_push_with_return (display); + window->display = display; + meta_display_register_stamp (window->display, &window->stamp, window); - /* - * XAddToSaveSet can only be called on windows created by a different client. - * with Muffin we want to be able to create manageable windows from within - * the process (such as a dummy desktop window), so we do not want this - * call failing to prevent the window from being managed -- wrap it in its - * own error trap (we use the _with_return() version here to ensure that - * XSync() is done on the pop, otherwise the error will not get caught). - */ - meta_error_trap_push_with_return (display); - XAddToSaveSet (display->xdisplay, xwindow); - meta_error_trap_pop_with_return (display); - - event_mask = - PropertyChangeMask | EnterWindowMask | LeaveWindowMask | - FocusChangeMask | ColormapChangeMask; - if (attrs->override_redirect) - event_mask |= StructureNotifyMask; - - /* If the window is from this client (a menu, say) we need to augment - * the event mask, not replace it. For windows from other clients, - * attrs->your_event_mask will be empty at this point. - */ - XSelectInput (display->xdisplay, xwindow, attrs->your_event_mask | event_mask); + window->workspace = NULL; - has_shape = FALSE; -#ifdef HAVE_SHAPE - if (META_DISPLAY_HAS_SHAPE (display)) - { - int x_bounding, y_bounding, x_clip, y_clip; - unsigned w_bounding, h_bounding, w_clip, h_clip; - int bounding_shaped, clip_shaped; + window->sync_request_counter = None; + window->sync_request_serial = 0; + window->sync_request_timeout_id = 0; + window->sync_request_alarm = None; - XShapeSelectInput (display->xdisplay, xwindow, ShapeNotifyMask); + meta_window_update_sandboxed_app_id (window); + meta_window_update_desc (window); - XShapeQueryExtents (display->xdisplay, xwindow, - &bounding_shaped, &x_bounding, &y_bounding, - &w_bounding, &h_bounding, - &clip_shaped, &x_clip, &y_clip, - &w_clip, &h_clip); + window->override_redirect = attrs->override_redirect; - has_shape = bounding_shaped != FALSE; - - meta_topic (META_DEBUG_SHAPES, - "Window has_shape = %d extents %d,%d %u x %u\n", - has_shape, x_bounding, y_bounding, - w_bounding, h_bounding); - } -#endif - - /* Get rid of any borders */ - if (attrs->border_width != 0) - XSetWindowBorderWidth (display->xdisplay, xwindow, 0); - - /* Get rid of weird gravities */ - if (attrs->win_gravity != NorthWestGravity) - { - XSetWindowAttributes set_attrs; - - set_attrs.win_gravity = NorthWestGravity; - - XChangeWindowAttributes (display->xdisplay, - xwindow, - CWWinGravity, - &set_attrs); - } - - if (meta_error_trap_pop_with_return (display) != Success) - { - meta_verbose ("Window 0x%lx disappeared just as we tried to manage it\n", - xwindow); - meta_error_trap_pop (display); - meta_display_ungrab (display); - return NULL; - } - - - window = g_object_new (META_TYPE_WINDOW, NULL); - - window->constructing = TRUE; - - window->dialog_pid = -1; - - window->xwindow = xwindow; - - /* this is in window->screen->display, but that's too annoying to - * type - */ - window->display = display; - window->workspace = NULL; - -#ifdef HAVE_XSYNC - window->sync_request_counter = None; - window->sync_request_serial = 0; - window->sync_request_timeout_id = 0; - window->sync_request_alarm = None; -#endif - - window->screen = screen; - - window->desc = g_strdup_printf ("0x%lx", window->xwindow); - - // -1 is used as a result in get_client_pid() if it's called with a non-window-argument - window->client_pid = -2; - - window->override_redirect = attrs->override_redirect; - - /* avoid tons of stack updates */ - meta_stack_freeze (window->screen->stack); - - window->has_shape = has_shape; + /* avoid tons of stack updates */ + meta_stack_freeze (window->display->stack); window->rect.x = attrs->x; window->rect.y = attrs->y; window->rect.width = attrs->width; window->rect.height = attrs->height; - /* And border width, size_hints are the "request" */ - window->border_width = attrs->border_width; + /* size_hints are the "request" */ window->size_hints.x = attrs->x; window->size_hints.y = attrs->y; window->size_hints.width = attrs->width; @@ -1173,62 +1061,40 @@ meta_window_new_with_attrs (MetaDisplay *display, /* And this is our unmaximized size */ window->saved_rect = window->rect; - window->user_rect = window->rect; - window->snapped_rect = window->rect; + window->unconstrained_rect = window->rect; window->depth = attrs->depth; window->xvisual = attrs->visual; - window->colormap = attrs->colormap; window->title = NULL; - window->icon_name = NULL; window->icon = NULL; - window->icon_size = -1; - meta_icon_cache_init (&window->icon_cache); - window->theme_icon_name = NULL; - window->wm_hints_pixmap = None; - window->wm_hints_mask = None; - window->wm_hints_urgent = FALSE; + window->mini_icon = NULL; window->frame = NULL; window->has_focus = FALSE; window->attached_focus_window = NULL; - window->hide_titlebar_when_maximized = FALSE; - window->maximized_horizontally = FALSE; window->maximized_vertically = FALSE; - window->tile_type = META_WINDOW_TILE_TYPE_NONE; - window->snap_queued = FALSE; - window->current_proximity_zone = 0; - window->mouse_on_edge = FALSE; - window->resizing_tile_type = META_WINDOW_TILE_TYPE_NONE; - window->custom_snap_size = FALSE; - window->zone_queued = ZONE_NONE; window->maximize_horizontally_after_placement = FALSE; window->maximize_vertically_after_placement = FALSE; window->minimize_after_placement = FALSE; - window->tile_after_placement = FALSE; - window->move_after_placement = FALSE; window->fullscreen = FALSE; - window->fullscreen_monitors[0] = -1; window->require_fully_onscreen = TRUE; window->require_on_single_monitor = TRUE; window->require_titlebar_visible = TRUE; window->on_all_workspaces = FALSE; window->on_all_workspaces_requested = FALSE; window->tile_mode = META_TILE_NONE; - window->last_tile_mode = META_TILE_NONE; - window->resize_tile_mode = META_TILE_NONE; - window->maybe_retile_maximize = FALSE; window->tile_monitor_number = -1; + window->tile_hfraction = -1.; window->shaded = FALSE; window->initially_iconic = FALSE; window->minimized = FALSE; window->tab_unminimized = FALSE; window->iconic = FALSE; window->mapped = attrs->map_state != IsUnmapped; - window->hidden = FALSE; + window->known_to_compositor = FALSE; window->visible_to_compositor = FALSE; window->pending_compositor_effect = effect; /* if already mapped, no need to worry about focus-on-first-time-showing */ @@ -1236,13 +1102,6 @@ meta_window_new_with_attrs (MetaDisplay *display, /* if already mapped we don't want to do the placement thing; * override-redirect windows are placed by the app */ window->placed = ((window->mapped && !window->hidden) || window->override_redirect); -#ifdef WITH_VERBOSE_MODE - if (window->placed) - meta_topic (META_DEBUG_PLACEMENT, - "Not placing window 0x%lx since it's already mapped\n", - xwindow); -#endif - window->force_save_user_rect = TRUE; window->denied_focus_and_not_transient = FALSE; window->unmanaging = FALSE; window->is_in_queues = 0; @@ -1254,9 +1113,6 @@ meta_window_new_with_attrs (MetaDisplay *display, window->initial_timestamp_set = FALSE; window->net_wm_user_time_set = FALSE; window->user_time_window = None; - window->take_focus = FALSE; - window->delete_window = FALSE; - window->net_wm_ping = FALSE; window->input = TRUE; window->calc_placement = FALSE; window->shaken_loose = FALSE; @@ -1264,6 +1120,7 @@ meta_window_new_with_attrs (MetaDisplay *display, window->disable_sync = FALSE; window->unmaps_pending = 0; + window->reparents_pending = 0; window->mwm_decorated = TRUE; window->mwm_border_only = FALSE; @@ -1273,7 +1130,18 @@ meta_window_new_with_attrs (MetaDisplay *display, window->mwm_has_move_func = TRUE; window->mwm_has_resize_func = TRUE; - window->decorated = TRUE; + switch (client_type) + { + case META_WINDOW_CLIENT_TYPE_X11: + window->decorated = TRUE; + window->hidden = FALSE; + break; + case META_WINDOW_CLIENT_TYPE_WAYLAND: + window->decorated = FALSE; + window->hidden = TRUE; + break; + } + window->has_close_func = TRUE; window->has_minimize_func = TRUE; window->has_maximize_func = TRUE; @@ -1286,11 +1154,8 @@ meta_window_new_with_attrs (MetaDisplay *display, window->always_sticky = FALSE; - window->wm_state_modal = FALSE; window->skip_taskbar = FALSE; window->skip_pager = FALSE; - window->wm_state_skip_taskbar = FALSE; - window->wm_state_skip_pager = FALSE; window->wm_state_above = FALSE; window->wm_state_below = FALSE; window->wm_state_demands_attention = FALSE; @@ -1300,26 +1165,18 @@ meta_window_new_with_attrs (MetaDisplay *display, window->role = NULL; window->sm_client_id = NULL; window->wm_client_machine = NULL; + window->is_remote = FALSE; window->startup_id = NULL; window->net_wm_pid = -1; window->xtransient_for = None; window->xclient_leader = None; - window->transient_parent_is_root_window = FALSE; window->type = META_WINDOW_NORMAL; - window->type_atom = None; window->struts = NULL; - window->using_net_wm_name = FALSE; - window->using_net_wm_visible_name = FALSE; - window->using_net_wm_icon_name = FALSE; - window->using_net_wm_visible_icon_name = FALSE; - - window->need_reread_icon = TRUE; - window->layer = META_LAYER_LAST; /* invalid value */ window->stack_position = -1; window->initial_workspace = 0; /* not used */ @@ -1327,10 +1184,21 @@ meta_window_new_with_attrs (MetaDisplay *display, window->compositor_private = NULL; - window->monitor = meta_screen_get_monitor_for_window (window->screen, window); + window->monitor = meta_window_calculate_main_logical_monitor (window); + if (window->monitor) + window->preferred_output_winsys_id = window->monitor->winsys_id; + else + window->preferred_output_winsys_id = UINT_MAX; window->tile_match = NULL; + /* Assign this #MetaWindow a sequence number which can be used + * for sorting. + */ + window->stable_sequence = ++display->window_sequence_counter; + + window->opacity = 0xFF; + if (window->override_redirect) { window->decorated = FALSE; @@ -1341,32 +1209,12 @@ meta_window_new_with_attrs (MetaDisplay *display, window->has_resize_func = FALSE; } - meta_display_register_x_window (display, &window->xwindow, window); - - /* Assign this #MetaWindow a sequence number which can be used - * for sorting. - */ - window->stable_sequence = ++display->window_sequence_counter; - - /* assign the window to its group, or create a new group if needed - */ - window->group = NULL; - window->xgroup_leader = None; - meta_window_compute_group (window); + window->id = meta_display_generate_window_id (display); - meta_window_load_initial_properties (window); + meta_window_manage (window); if (!window->override_redirect) - { - update_sm_hints (window); /* must come after transient_for */ - - meta_window_update_role (window); - } - - meta_window_update_net_wm_type (window); - - if (window->decorated) - meta_window_ensure_frame (window); + meta_window_update_icon_now (window, TRUE); if (window->initially_iconic) { @@ -1391,7 +1239,7 @@ meta_window_new_with_attrs (MetaDisplay *display, /* Apply any window attributes such as initial workspace * based on startup notification */ - meta_screen_apply_startup_properties (window->screen, window); + meta_display_apply_startup_properties (window->display, window); /* Try to get a "launch timestamp" for the window. If the window is * a transient, we'd like to be able to get a last-usage timestamp @@ -1400,11 +1248,6 @@ meta_window_new_with_attrs (MetaDisplay *display, * can use this time as a fallback. */ if (!window->override_redirect && !window->net_wm_user_time_set) { - MetaWindow *parent = NULL; - if (window->xtransient_for) - parent = meta_display_lookup_x_window (window->display, - window->xtransient_for); - /* First, maybe the app was launched with startup notification using an * obsolete version of the spec; use that timestamp if it exists. */ @@ -1413,8 +1256,8 @@ meta_window_new_with_attrs (MetaDisplay *display, * being recorded as a fallback for potential transients */ window->net_wm_user_time = window->initial_timestamp; - else if (parent != NULL) - meta_window_set_user_time(window, parent->net_wm_user_time); + else if (window->transient_for != NULL) + meta_window_set_user_time (window, window->transient_for->net_wm_user_time); else /* NOTE: Do NOT toggle net_wm_user_time_set to true; this is just * being recorded as a fallback for potential transients @@ -1425,14 +1268,7 @@ meta_window_new_with_attrs (MetaDisplay *display, window->attached = meta_window_should_attach_to_parent (window); if (window->attached) - recalc_window_features (window); - - meta_window_grab_keys (window); - if (window->type != META_WINDOW_DOCK && !window->override_redirect) - { - meta_display_grab_window_buttons (window->display, window->xwindow); - meta_display_grab_focus_window_button (window->display, window); - } + meta_window_recalc_features (window); if (window->type == META_WINDOW_DESKTOP || window->type == META_WINDOW_DOCK) @@ -1454,6 +1290,9 @@ meta_window_new_with_attrs (MetaDisplay *display, if (window->initial_workspace_set) { + gboolean on_all_workspaces = window->on_all_workspaces; + MetaWorkspace *workspace = NULL; + if (window->initial_workspace == (int) 0xFFFFFFFF) { meta_topic (META_DEBUG_PLACEMENT, @@ -1464,22 +1303,23 @@ meta_window_new_with_attrs (MetaDisplay *display, * added to all the MRU lists */ window->on_all_workspaces_requested = TRUE; - window->on_all_workspaces = TRUE; - meta_workspace_add_window (window->screen->active_workspace, window); + + on_all_workspaces = TRUE; } - else + else if (!on_all_workspaces) { meta_topic (META_DEBUG_PLACEMENT, "Window %s is initially on space %d\n", window->desc, window->initial_workspace); - space = - meta_screen_get_workspace_by_index (window->screen, - window->initial_workspace); - - if (space) - meta_workspace_add_window (space, window); + workspace = meta_workspace_manager_get_workspace_by_index (workspace_manager, + window->initial_workspace); } + + /* Ignore when a window requests to be placed on a non-existent workspace + */ + if (on_all_workspaces || workspace != NULL) + set_workspace_state (window, on_all_workspaces, workspace); } /* override-redirect windows are subtly different from other windows @@ -1488,54 +1328,40 @@ meta_window_new_with_attrs (MetaDisplay *display, * but appear on other workspaces. override-redirect windows are part * of no workspace. */ - if (!window->override_redirect) + if (!window->override_redirect && window->workspace == NULL) { - if (window->workspace == NULL && - window->xtransient_for != None) + if (window->transient_for != NULL) { - /* Try putting dialog on parent's workspace */ - MetaWindow *parent; - - parent = meta_display_lookup_x_window (window->display, - window->xtransient_for); - - if (parent && parent->workspace) - { - meta_topic (META_DEBUG_PLACEMENT, - "Putting window %s on same workspace as parent %s\n", - window->desc, parent->desc); - - if (parent->on_all_workspaces_requested) - { - window->on_all_workspaces_requested = TRUE; - window->on_all_workspaces = TRUE; - } + meta_topic (META_DEBUG_PLACEMENT, + "Putting window %s on same workspace as parent %s\n", + window->desc, window->transient_for->desc); - /* this will implicitly add to the appropriate MRU lists - */ - meta_workspace_add_window (parent->workspace, window); - } + g_warn_if_fail (!window->transient_for->override_redirect); + set_workspace_state (window, + window->transient_for->on_all_workspaces, + window->transient_for->workspace); } + else if (window->on_all_workspaces) + { + meta_topic (META_DEBUG_PLACEMENT, + "Putting window %s on all workspaces\n", + window->desc); - if (window->workspace == NULL) + set_workspace_state (window, TRUE, NULL); + } + else { meta_topic (META_DEBUG_PLACEMENT, "Putting window %s on active workspace\n", window->desc); - space = window->screen->active_workspace; - - meta_workspace_add_window (space, window); + set_workspace_state (window, FALSE, workspace_manager->active_workspace); } - /* for the various on_all_workspaces = TRUE possible above */ - meta_window_set_current_workspace_hint (window); - meta_window_update_struts (window); } - g_signal_emit_by_name (window->screen, "window-entered-monitor", window->monitor->number, window); - g_signal_emit_by_name (window->screen, "window-added", window, window->monitor->number); + meta_window_main_monitor_changed (window, NULL); /* Must add window to stack before doing move/resize, since the * window might have fullscreen size (i.e. should have been @@ -1544,60 +1370,33 @@ meta_window_new_with_attrs (MetaDisplay *display, * and thus constraints may try to auto-fullscreen it which also * means restacking it. */ - if (!window->override_redirect) - meta_stack_add (window->screen->stack, + if (meta_window_is_stackable (window)) + meta_stack_add (window->display->stack, window); - else + else if (window->override_redirect) window->layer = META_LAYER_OVERRIDE_REDIRECT; /* otherwise set by MetaStack */ - /* Put our state back where it should be, - * passing TRUE for is_configure_request, ICCCM says - * initial map is handled same as configure request - */ - flags = - META_IS_CONFIGURE_REQUEST | META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION; - if (!window->override_redirect) - meta_window_move_resize_internal (window, - flags, - window->size_hints.win_gravity, - window->size_hints.x, - window->size_hints.y, - window->size_hints.width, - window->size_hints.height); - - /* Now try applying saved stuff from the session */ - { - const MetaWindowSessionInfo *info; - - info = meta_window_lookup_saved_state (window); - - if (info) - { - meta_window_apply_session_info (window, info); - meta_window_release_saved_state (info); - } - } - if (!window->override_redirect) { /* FIXME we have a tendency to set this then immediately * change it again. */ - set_wm_state (window, window->iconic ? IconicState : NormalState); + set_wm_state (window); set_net_wm_state (window); } - meta_compositor_add_window (screen->display->compositor, window); + meta_compositor_add_window (window->display->compositor, window); + window->known_to_compositor = TRUE; /* Sync stack changes */ - meta_stack_thaw (window->screen->stack); + meta_stack_thaw (window->display->stack); /* Usually the we'll have queued a stack sync anyways, because we've * added a new frame window or restacked. But if an undecorated * window is mapped, already stacked in the right place, then we * might need to do this explicitly. */ - meta_stack_tracker_queue_sync_stack (window->screen->stack_tracker); + meta_stack_tracker_queue_sync_stack (window->display->stack_tracker); /* disable show desktop mode unless we're a desktop component */ maybe_leave_show_desktop_mode (window); @@ -1624,9 +1423,6 @@ meta_window_new_with_attrs (MetaDisplay *display, !window->initially_iconic) unminimize_window_and_all_transient_parents (window); - meta_error_trap_pop (display); /* pop the XSync()-reducing trap */ - meta_display_ungrab (display); - window->constructing = FALSE; meta_display_notify_window_created (display, window); @@ -1634,161 +1430,18 @@ meta_window_new_with_attrs (MetaDisplay *display, if (window->wm_state_demands_attention) g_signal_emit_by_name (window->display, "window-demands-attention", window); - if (window->wm_hints_urgent) - g_signal_emit_by_name (window->display, "window-marked-urgent", window); - return window; } -/* This function should only be called from the end of meta_window_new_with_attrs () */ -static void -meta_window_apply_session_info (MetaWindow *window, - const MetaWindowSessionInfo *info) -{ - if (info->stack_position_set) - { - meta_topic (META_DEBUG_SM, - "Restoring stack position %d for window %s\n", - info->stack_position, window->desc); - - /* FIXME well, I'm not sure how to do this. */ - } - - if (info->minimized_set) - { - meta_topic (META_DEBUG_SM, - "Restoring minimized state %d for window %s\n", - info->minimized, window->desc); - - if (window->has_minimize_func && info->minimized) - meta_window_minimize (window); - } - - if (info->maximized_set) - { - meta_topic (META_DEBUG_SM, - "Restoring maximized state %d for window %s\n", - info->maximized, window->desc); - - if (window->has_maximize_func && info->maximized) - { - meta_window_maximize (window, - META_MAXIMIZE_HORIZONTAL | - META_MAXIMIZE_VERTICAL); - - if (info->saved_rect_set) - { - meta_topic (META_DEBUG_SM, - "Restoring saved rect %d,%d %dx%d for window %s\n", - info->saved_rect.x, - info->saved_rect.y, - info->saved_rect.width, - info->saved_rect.height, - window->desc); - - window->saved_rect.x = info->saved_rect.x; - window->saved_rect.y = info->saved_rect.y; - window->saved_rect.width = info->saved_rect.width; - window->saved_rect.height = info->saved_rect.height; - } - } - } - - if (info->on_all_workspaces_set) - { - window->on_all_workspaces_requested = info->on_all_workspaces; - meta_window_update_on_all_workspaces (window); - meta_topic (META_DEBUG_SM, - "Restoring sticky state %d for window %s\n", - window->on_all_workspaces_requested, window->desc); - } - - if (info->workspace_indices) - { - GSList *tmp; - GSList *spaces; - - spaces = NULL; - - tmp = info->workspace_indices; - while (tmp != NULL) - { - MetaWorkspace *space; - - space = - meta_screen_get_workspace_by_index (window->screen, - GPOINTER_TO_INT (tmp->data)); - - if (space) - spaces = g_slist_prepend (spaces, space); - - tmp = tmp->next; - } - - if (spaces) - { - /* This briefly breaks the invariant that we are supposed - * to always be on some workspace. But we paranoically - * ensured that one of the workspaces from the session was - * indeed valid, so we know we'll go right back to one. - */ - if (window->workspace) - meta_workspace_remove_window (window->workspace, window); - - /* Only restore to the first workspace if the window - * happened to be on more than one, since we have replaces - * window->workspaces with window->workspace - */ - meta_workspace_add_window (spaces->data, window); - - meta_topic (META_DEBUG_SM, - "Restoring saved window %s to workspace %d\n", - window->desc, - meta_workspace_index (spaces->data)); - - g_slist_free (spaces); - } - } - - if (info->geometry_set) - { - int x, y, w, h; - MetaMoveResizeFlags flags; - - window->placed = TRUE; /* don't do placement algorithms later */ - - x = info->rect.x; - y = info->rect.y; - - w = window->size_hints.base_width + - info->rect.width * window->size_hints.width_inc; - h = window->size_hints.base_height + - info->rect.height * window->size_hints.height_inc; - - /* Force old gravity, ignoring anything now set */ - window->size_hints.win_gravity = info->gravity; - - meta_topic (META_DEBUG_SM, - "Restoring pos %d,%d size %d x %d for %s\n", - x, y, w, h, window->desc); - - flags = META_DO_GRAVITY_ADJUST | META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION; - meta_window_move_resize_internal (window, - flags, - window->size_hints.win_gravity, - x, y, w, h); - } -} - static gboolean detach_foreach_func (MetaWindow *window, void *data) { + GList **children = data; + MetaWindow *parent; + if (window->attached) { - GList **children = data; - MetaWindow *parent; - /* Only return the immediate children of the window being unmanaged */ parent = meta_window_get_transient_for (window); if (parent->unmanaging) @@ -1798,32 +1451,37 @@ detach_foreach_func (MetaWindow *window, return TRUE; } -LOCAL_SYMBOL void +void meta_window_unmanage (MetaWindow *window, guint32 timestamp) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; GList *tmp; - meta_verbose ("Unmanaging 0x%lx\n", window->xwindow); + meta_verbose ("Unmanaging %s\n", window->desc); + window->unmanaging = TRUE; + + g_clear_handle_id (&window->unmanage_idle_id, g_source_remove); - if (window->visible_to_compositor || meta_window_is_attached_dialog (window)) - meta_compositor_hide_window (window->display->compositor, window, - META_COMP_EFFECT_DESTROY); + g_signal_emit (window, window_signals[UNMANAGING], 0); - meta_compositor_remove_window (window->display->compositor, window); + meta_window_free_delete_dialog (window); - if (window->display->window_with_menu == window) + if (window->visible_to_compositor) { - meta_ui_window_menu_free (window->display->window_menu); - window->display->window_menu = NULL; - window->display->window_with_menu = NULL; + window->visible_to_compositor = FALSE; + meta_compositor_hide_window (window->display->compositor, window, + META_COMP_EFFECT_DESTROY); } + meta_compositor_remove_window (window->display->compositor, window); + window->known_to_compositor = FALSE; + if (destroying_windows_disallowed > 0) meta_bug ("Tried to destroy window %s while destruction was not allowed\n", window->desc); - window->unmanaging = TRUE; + meta_display_unregister_stamp (window->display, window->stamp); if (meta_prefs_get_attach_modal_dialogs ()) { @@ -1840,6 +1498,12 @@ meta_window_unmanage (MetaWindow *window, g_list_free (attached_children); } + /* Make sure to only show window on all workspaces if requested, to + * not confuse other window managers that may take over + */ + if (meta_prefs_get_workspaces_only_on_primary ()) + meta_window_on_all_workspaces_changed (window); + if (window->fullscreen) { MetaGroup *group; @@ -1848,17 +1512,18 @@ meta_window_unmanage (MetaWindow *window, * other windows in its group to a higher layer */ - meta_stack_freeze (window->screen->stack); + meta_stack_freeze (window->display->stack); group = meta_window_get_group (window); if (group) meta_group_update_layers (group); - meta_stack_thaw (window->screen->stack); + meta_stack_thaw (window->display->stack); } - meta_window_shutdown_group (window); /* safe to do this early as - * group.c won't re-add to the - * group if window->unmanaging - */ + meta_display_remove_pending_pings_for_window (window->display, window); + + /* safe to do this early as group.c won't re-add to the + * group if window->unmanaging */ + meta_window_shutdown_group (window); /* If we have the focus, focus some other window. * This is done first, so that if the unmap causes @@ -1873,17 +1538,7 @@ meta_window_unmanage (MetaWindow *window, meta_topic (META_DEBUG_FOCUS, "Focusing default window since we're unmanaging %s\n", window->desc); - meta_workspace_focus_default_window (window->screen->active_workspace, - window, - timestamp); - } - else if (window->display->expected_focus_window == window) - { - meta_topic (META_DEBUG_FOCUS, - "Focusing default window since expected focus window freed %s\n", - window->desc); - window->display->expected_focus_window = NULL; - meta_workspace_focus_default_window (window->screen->active_workspace, + meta_workspace_focus_default_window (workspace_manager->active_workspace, window, timestamp); } @@ -1894,9 +1549,11 @@ meta_window_unmanage (MetaWindow *window, window->desc); } + g_assert (window->display->focus_window != window); + if (window->struts) { - meta_free_gslist_and_elements (window->struts); + g_slist_free_full (window->struts, g_free); window->struts = NULL; meta_topic (META_DEBUG_WORKAREA, @@ -1905,40 +1562,26 @@ meta_window_unmanage (MetaWindow *window, invalidate_work_areas (window); } -#ifdef HAVE_XSYNC - if (window->sync_request_timeout_id) - { - g_source_remove (window->sync_request_timeout_id); - window->sync_request_timeout_id = 0; - } -#endif + g_clear_handle_id (&window->sync_request_timeout_id, g_source_remove); if (window->display->grab_window == window) meta_display_end_grab_op (window->display, timestamp); g_assert (window->display->grab_window != window); - if (window->display->focus_window == window) - { - window->display->focus_window = NULL; - g_object_notify (G_OBJECT (window->display), "focus-window"); - } - - if (window->maximized_horizontally || window->maximized_vertically || - window->tile_type != META_WINDOW_TILE_TYPE_NONE) + if (window->maximized_horizontally || window->maximized_vertically) unmaximize_window_before_freeing (window); meta_window_unqueue (window, META_QUEUE_CALC_SHOWING | - META_QUEUE_MOVE_RESIZE); - meta_window_free_delete_dialog (window); + META_QUEUE_MOVE_RESIZE | + META_QUEUE_UPDATE_ICON); - if (window->workspace) - meta_workspace_remove_window (window->workspace, window); + set_workspace_state (window, FALSE, NULL); g_assert (window->workspace == NULL); #ifndef G_DISABLE_CHECKS - tmp = window->screen->workspaces; + tmp = workspace_manager->workspaces; while (tmp != NULL) { MetaWorkspace *workspace = tmp->data; @@ -1952,363 +1595,69 @@ meta_window_unmanage (MetaWindow *window, if (window->monitor) { - g_signal_emit_by_name (window->screen, "window-left-monitor", - window->monitor->number, window); + const MetaLogicalMonitor *old = window->monitor; + window->monitor = NULL; + meta_window_main_monitor_changed (window, old); } - if (!window->override_redirect) - meta_stack_remove (window->screen->stack, window); - - meta_window_destroy_sync_request_alarm (window); + if (meta_window_is_in_stack (window)) + meta_stack_remove (window->display->stack, window); /* If an undecorated window is being withdrawn, that will change the * stack as presented to the compositing manager, without actually * changing the stacking order of X windows. */ - meta_stack_tracker_queue_sync_stack (window->screen->stack_tracker); - - if (window->withdrawn) - { - /* We need to clean off the window's state so it - * won't be restored if the app maps it again. - */ - meta_error_trap_push (window->display); - meta_verbose ("Cleaning state from window %s\n", window->desc); - XDeleteProperty (window->display->xdisplay, - window->xwindow, - window->display->atom__NET_WM_DESKTOP); - XDeleteProperty (window->display->xdisplay, - window->xwindow, - window->display->atom__NET_WM_STATE); - XDeleteProperty (window->display->xdisplay, - window->xwindow, - window->display->atom__NET_WM_FULLSCREEN_MONITORS); - set_wm_state (window, WithdrawnState); - meta_error_trap_pop (window->display); - } - else - { - /* We need to put WM_STATE so that others will understand it on - * restart. - */ - if (!window->minimized) - { - meta_error_trap_push (window->display); - set_wm_state (window, NormalState); - meta_error_trap_pop (window->display); - } - - /* If we're unmanaging a window that is not withdrawn, then - * either (a) muffin is exiting, in which case we need to map - * the window so the next WM will know that it's not Withdrawn, - * or (b) we want to create a new MetaWindow to replace the - * current one, which will happen automatically if we re-map - * the X Window. - */ - meta_error_trap_push (window->display); - XMapWindow (window->display->xdisplay, - window->xwindow); - meta_error_trap_pop (window->display); - } - - meta_window_ungrab_keys (window); - meta_display_ungrab_window_buttons (window->display, window->xwindow); - meta_display_ungrab_focus_window_button (window->display, window); - - meta_display_unregister_x_window (window->display, window->xwindow); - - - meta_error_trap_push (window->display); - - /* Put back anything we messed up */ - if (window->border_width != 0) - XSetWindowBorderWidth (window->display->xdisplay, - window->xwindow, - window->border_width); - - /* No save set */ - XRemoveFromSaveSet (window->display->xdisplay, - window->xwindow); - - /* Even though the window is now unmanaged, we can't unselect events. This - * window might be a window from this process, like a GdkMenu, in - * which case it will have pointer events and so forth selected - * for it by GDK. There's no way to disentangle those events from the events - * we've selected. Even for a window from a different X client, - * GDK could also have selected events for it for IPC purposes, so we - * can't unselect in that case either. - * - * Similarly, we can't unselected for events on window->user_time_window. - * It might be our own GDK focus window, or it might be a window that a - * different client is using for multiple different things: - * _NET_WM_USER_TIME_WINDOW and IPC, perhaps. - */ - - if (window->user_time_window != None) - { - meta_display_unregister_x_window (window->display, - window->user_time_window); - window->user_time_window = None; - } + meta_stack_tracker_queue_sync_stack (window->display->stack_tracker); -#ifdef HAVE_SHAPE - if (META_DISPLAY_HAS_SHAPE (window->display)) - XShapeSelectInput (window->display->xdisplay, window->xwindow, NoEventMask); -#endif + if (window->display->autoraise_window == window) + meta_display_remove_autoraise_callback (window->display); - meta_error_trap_pop (window->display); + META_WINDOW_GET_CLASS (window)->unmanage (window); meta_prefs_remove_listener (prefs_changed_callback, window); - - meta_screen_queue_check_fullscreen (window->screen); - - if (window->frame) - { - /* The XReparentWindow call in meta_window_destroy_frame() moves the - * window so we need to send a configure notify; see bug 399552. (We - * also do this just in case a window got unmaximized.) - */ - send_configure_notify (window); - - meta_window_destroy_frame (window); - } + meta_display_queue_check_fullscreen (window->display); g_signal_emit (window, window_signals[UNMANAGED], 0); - g_signal_emit_by_name (window->screen, "window-removed", window); g_object_unref (window); } -static gboolean -should_be_on_all_workspaces (MetaWindow *window) +static void +set_wm_state (MetaWindow *window) { - return - window->on_all_workspaces_requested || - window->override_redirect || - (meta_prefs_get_workspaces_only_on_primary () && - !meta_window_is_on_primary_monitor (window)); + if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) + meta_window_x11_set_wm_state (window); } -LOCAL_SYMBOL void -meta_window_update_on_all_workspaces (MetaWindow *window) +static void +set_net_wm_state (MetaWindow *window) { - gboolean old_value; + if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) + meta_window_x11_set_net_wm_state (window); +} - old_value = window->on_all_workspaces; +static void +set_allowed_actions_hint (MetaWindow *window) +{ + if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) + meta_window_x11_set_allowed_actions_hint (window); +} - window->on_all_workspaces = should_be_on_all_workspaces (window); - - if (window->on_all_workspaces != old_value && - !window->override_redirect) - { - if (window->on_all_workspaces) - { - GList* tmp = window->screen->workspaces; - - /* Add to all MRU lists */ - while (tmp) - { - MetaWorkspace* work = (MetaWorkspace*) tmp->data; - if (!g_list_find (work->mru_list, window)) - work->mru_list = g_list_prepend (work->mru_list, window); - - tmp = tmp->next; - } - } - else - { - GList* tmp = window->screen->workspaces; - - /* Remove from MRU lists except the window's workspace */ - while (tmp) - { - MetaWorkspace* work = (MetaWorkspace*) tmp->data; - if (work != window->workspace) - work->mru_list = g_list_remove (work->mru_list, window); - tmp = tmp->next; - } - } - meta_window_set_current_workspace_hint (window); - } - meta_screen_update_snapped_windows (window->screen); -} - -static void -set_wm_state_on_xwindow (MetaDisplay *display, - Window xwindow, - int state) -{ - unsigned long data[2]; - - /* Muffin doesn't use icon windows, so data[1] should be None - * according to the ICCCM 2.0 Section 4.1.3.1. - */ - data[0] = state; - data[1] = None; - - meta_error_trap_push (display); - XChangeProperty (display->xdisplay, xwindow, - display->atom_WM_STATE, - display->atom_WM_STATE, - 32, PropModeReplace, (guchar*) data, 2); - meta_error_trap_pop (display); -} - -static void -set_wm_state (MetaWindow *window, - int state) -{ - meta_verbose ("Setting wm state %s on %s\n", - wm_state_to_string (state), window->desc); - - set_wm_state_on_xwindow (window->display, window->xwindow, state); -} - -static void -set_net_wm_state (MetaWindow *window) -{ - int i; - unsigned long data[14]; - - i = 0; - if (window->shaded) - { - data[i] = window->display->atom__NET_WM_STATE_SHADED; - ++i; - } - if (window->wm_state_modal) - { - data[i] = window->display->atom__NET_WM_STATE_MODAL; - ++i; - } - if (window->skip_pager) - { - data[i] = window->display->atom__NET_WM_STATE_SKIP_PAGER; - ++i; - } - if (window->skip_taskbar) - { - data[i] = window->display->atom__NET_WM_STATE_SKIP_TASKBAR; - ++i; - } - if (window->maximized_horizontally) - { - data[i] = window->display->atom__NET_WM_STATE_MAXIMIZED_HORZ; - ++i; - } - /* As of 3.10, Gtk considers _NET_WM_STATE_MAXIMIZED_VERT to be a tiled window also */ - if (window->maximized_vertically || window->tile_type != META_WINDOW_TILE_TYPE_NONE) - { - data[i] = window->display->atom__NET_WM_STATE_MAXIMIZED_VERT; - ++i; - } - if (window->tile_type != META_WINDOW_TILE_TYPE_NONE) - { - data[i] = window->display->atom__NET_WM_STATE_TILED; - ++i; - } - if (window->fullscreen) - { - data[i] = window->display->atom__NET_WM_STATE_FULLSCREEN; - ++i; - } - if (!meta_window_showing_on_its_workspace (window) || window->shaded) - { - data[i] = window->display->atom__NET_WM_STATE_HIDDEN; - ++i; - } - if (window->wm_state_above) - { - data[i] = window->display->atom__NET_WM_STATE_ABOVE; - ++i; - } - if (window->wm_state_below) - { - data[i] = window->display->atom__NET_WM_STATE_BELOW; - ++i; - } - if (window->wm_state_demands_attention) - { - data[i] = window->display->atom__NET_WM_STATE_DEMANDS_ATTENTION; - ++i; - } - if (window->on_all_workspaces_requested) - { - data[i] = window->display->atom__NET_WM_STATE_STICKY; - ++i; - } - if (meta_window_appears_focused (window)) - { - data[i] = window->display->atom__NET_WM_STATE_FOCUSED; - ++i; - } - - meta_verbose ("Setting _NET_WM_STATE with %d atoms\n", i); - - meta_error_trap_push (window->display); - XChangeProperty (window->display->xdisplay, window->xwindow, - window->display->atom__NET_WM_STATE, - XA_ATOM, - 32, PropModeReplace, (guchar*) data, i); - meta_error_trap_pop (window->display); - - if (window->fullscreen) - { - data[0] = window->fullscreen_monitors[0]; - data[1] = window->fullscreen_monitors[1]; - data[2] = window->fullscreen_monitors[2]; - data[3] = window->fullscreen_monitors[3]; - - meta_verbose ("Setting _NET_WM_FULLSCREEN_MONITORS\n"); - meta_error_trap_push (window->display); - XChangeProperty (window->display->xdisplay, - window->xwindow, - window->display->atom__NET_WM_FULLSCREEN_MONITORS, - XA_CARDINAL, 32, PropModeReplace, - (guchar*) data, 4); - meta_error_trap_pop (window->display); - } - - if (window->tile_type != META_WINDOW_TILE_TYPE_NONE) - { - MetaRectangle rect; - meta_window_get_outer_rect (window, &rect); - data[0] = (unsigned long) window->tile_mode; - data[1] = (unsigned long) window->tile_type; - data[2] = (unsigned long) rect.x; - data[3] = (unsigned long) rect.y; - data[4] = (unsigned long) rect.width; - data[5] = (unsigned long) rect.height; - data[6] = (unsigned long) window->tile_monitor_number; - data[7] = (unsigned long) window->custom_snap_size ? 1 : 0; - - meta_error_trap_push (window->display); - XChangeProperty (window->display->xdisplay, window->xwindow, - window->display->atom__NET_WM_WINDOW_TILE_INFO, - XA_CARDINAL, - 32, PropModeReplace, (guchar*) data, 8); - meta_error_trap_pop (window->display); - } else { - meta_error_trap_push (window->display); - XDeleteProperty (window->display->xdisplay, - window->xwindow, - window->display->atom__NET_WM_WINDOW_TILE_INFO); - meta_error_trap_pop (window->display); - } - - meta_error_trap_push (window->display); - update_gtk_edge_constraints (window); - meta_error_trap_pop (window->display); -} - -LOCAL_SYMBOL gboolean -meta_window_located_on_workspace (MetaWindow *window, - MetaWorkspace *workspace) -{ - return (window->on_all_workspaces && window->screen == workspace->screen) || - (window->workspace == workspace); -} +/** + * meta_window_located_on_workspace: + * @window: a #MetaWindow + * @workspace: a #MetaWorkspace + * + * Returns: whether @window is displayed on @workspace, or whether it + * will be displayed on all workspaces. + */ +gboolean +meta_window_located_on_workspace (MetaWindow *window, + MetaWorkspace *workspace) +{ + return (window->on_all_workspaces) || (window->workspace == workspace); +} static gboolean is_minimized_foreach (MetaWindow *window, @@ -2344,12 +1693,16 @@ ancestor_is_minimized (MetaWindow *window) gboolean meta_window_showing_on_its_workspace (MetaWindow *window) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; + gboolean showing; gboolean is_desktop_or_dock; MetaWorkspace* workspace_of_window; + showing = TRUE; + /* 1. See if we're minimized */ if (window->minimized) - return FALSE; + showing = FALSE; /* 2. See if we're in "show desktop" mode */ is_desktop_or_dock = FALSE; @@ -2360,51 +1713,50 @@ meta_window_showing_on_its_workspace (MetaWindow *window) &is_desktop_or_dock); if (window->on_all_workspaces) - workspace_of_window = window->screen->active_workspace; + workspace_of_window = workspace_manager->active_workspace; else if (window->workspace) workspace_of_window = window->workspace; else /* This only seems to be needed for startup */ workspace_of_window = NULL; - if (workspace_of_window && workspace_of_window->showing_desktop && + if (showing && + workspace_of_window && workspace_of_window->showing_desktop && !is_desktop_or_dock) - return FALSE; + { + meta_verbose ("We're showing the desktop on the workspace(s) that window %s is on\n", + window->desc); + showing = FALSE; + } /* 3. See if an ancestor is minimized (note that * ancestor's "mapped" field may not be up to date * since it's being computed in this same idle queue) */ - if (ancestor_is_minimized (window)) - return FALSE; + if (showing) + { + if (ancestor_is_minimized (window)) + showing = FALSE; + } - return TRUE; + return showing; } -LOCAL_SYMBOL gboolean +gboolean meta_window_should_be_showing (MetaWindow *window) { - gboolean on_workspace; + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; - meta_verbose ("Should be showing for window %s\n", window->desc); - - /* See if we're on the workspace */ - on_workspace = meta_window_located_on_workspace (window, - window->screen->active_workspace); - - if (!on_workspace) - meta_verbose ("Window %s is not on workspace %d\n", - window->desc, - meta_workspace_index (window->screen->active_workspace)); - else - meta_verbose ("Window %s is on the active workspace %d\n", - window->desc, - meta_workspace_index (window->screen->active_workspace)); - - if (window->on_all_workspaces) - meta_verbose ("Window %s is on all workspaces\n", window->desc); +#ifdef HAVE_WAYLAND + if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND && + !meta_wayland_surface_get_buffer (window->surface)) + return FALSE; +#endif - return on_workspace && meta_window_showing_on_its_workspace (window); + /* Windows should be showing if they're located on the + * active workspace and they're showing on their own workspace. */ + return (meta_window_located_on_workspace (window, workspace_manager->active_workspace) && + meta_window_showing_on_its_workspace (window)); } static void @@ -2415,6 +1767,10 @@ implement_showing (MetaWindow *window, meta_verbose ("Implement showing = %d for window %s\n", showing, window->desc); + /* Some windows are not stackable until being showed, so add those now. */ + if (meta_window_is_stackable (window) && !meta_window_is_in_stack (window)) + meta_stack_add (window->display->stack, window); + if (!showing) { /* When we manage a new window, we normally delay placing it @@ -2422,9 +1778,11 @@ implement_showing (MetaWindow *window, * windows we might want to know where they are on the screen, * so we should place the window even if we're hiding it rather * than showing it. + * Force placing windows only when they should be already mapped, + * see #751887 */ - if (!window->placed) - meta_window_force_placement (window); + if (!window->placed && client_window_should_be_mapped (window)) + meta_window_force_placement (window, FALSE); meta_window_hide (window); } @@ -2433,8 +1791,6 @@ implement_showing (MetaWindow *window, if (!window->override_redirect) sync_client_window_mapped (window); - - window->pending_compositor_effect = META_COMP_EFFECT_NONE; } static void @@ -2452,23 +1808,20 @@ stackcmp (gconstpointer a, gconstpointer b) MetaWindow *aw = (gpointer) a; MetaWindow *bw = (gpointer) b; - if (aw->screen != bw->screen) - return 0; /* don't care how they sort with respect to each other */ - else - return meta_stack_windows_cmp (aw->screen->stack, - aw, bw); + return meta_stack_windows_cmp (aw->display->stack, + aw, bw); } static gboolean idle_calc_showing (gpointer data) { + MetaDisplay *display = meta_get_display (); GSList *tmp; GSList *copy; GSList *should_show; GSList *should_hide; GSList *unplaced; GSList *displays; - MetaWindow *first_window; guint queue_index = GPOINTER_TO_INT (data); g_return_val_if_fail (queue_pending[queue_index] != NULL, FALSE); @@ -2521,10 +1874,6 @@ idle_calc_showing (gpointer data) should_show = g_slist_sort (should_show, stackcmp); should_show = g_slist_reverse (should_show); - first_window = copy->data; - - meta_display_grab (first_window->display); - tmp = unplaced; while (tmp != NULL) { @@ -2537,6 +1886,8 @@ idle_calc_showing (gpointer data) tmp = tmp->next; } + meta_stack_freeze (display->stack); + tmp = should_show; while (tmp != NULL) { @@ -2561,6 +1912,8 @@ idle_calc_showing (gpointer data) tmp = tmp->next; } + meta_stack_thaw (display->stack); + tmp = copy; while (tmp != NULL) { @@ -2589,16 +1942,15 @@ idle_calc_showing (gpointer data) while (tmp != NULL) { MetaWindow *window = tmp->data; + MetaDisplay *display = window->display; - if (!window->display->mouse_mode) - meta_display_increment_focus_sentinel (window->display); + if (display->x11_display && !display->mouse_mode) + meta_x11_display_increment_focus_sentinel (display->x11_display); tmp = tmp->next; } } - meta_display_ungrab (first_window->display); - g_slist_free (copy); g_slist_free (unplaced); @@ -2662,14 +2014,15 @@ meta_window_flush_calc_showing (MetaWindow *window) } } -LOCAL_SYMBOL void +void meta_window_queue (MetaWindow *window, guint queuebits) { + guint queuenum; /* Easier to debug by checking here rather than in the idle */ g_return_if_fail (!window->override_redirect || (queuebits & META_QUEUE_MOVE_RESIZE) == 0); - for (guint queuenum=0; queuenum<NUMBER_OF_QUEUES; queuenum++) + for (queuenum=0; queuenum<NUMBER_OF_QUEUES; queuenum++) { if (queuebits & 1<<queuenum) { @@ -2680,14 +2033,16 @@ meta_window_queue (MetaWindow *window, guint queuebits) const MetaLaterType window_queue_later_when[NUMBER_OF_QUEUES] = { - META_LATER_CALC_SHOWING, /* CALC_SHOWING */ + META_LATER_CALC_SHOWING, /* CALC_SHOWING */ META_LATER_RESIZE, /* MOVE_RESIZE */ + META_LATER_BEFORE_REDRAW /* UPDATE_ICON */ }; const GSourceFunc window_queue_later_handler[NUMBER_OF_QUEUES] = { idle_calc_showing, - idle_move_resize + idle_move_resize, + idle_update_icon, }; /* If we're about to drop the window, there's no point in putting @@ -2750,7 +2105,6 @@ intervening_user_event_occurred (MetaWindow *window) window->net_wm_user_time, window->initial_timestamp_set, window->initial_timestamp); -#ifdef WITH_VERBOSE_MODE if (focus_window != NULL) { meta_topic (META_DEBUG_STARTUP, @@ -2762,7 +2116,7 @@ intervening_user_event_occurred (MetaWindow *window) focus_window->net_wm_user_time_set, focus_window->net_wm_user_time); } -#endif + /* We expect the most common case for not focusing a new window * to be when a hint to not focus it has been set. Since we can * deal with that case rapidly, we use special case it--this is @@ -2841,8 +2195,8 @@ intervening_user_event_occurred (MetaWindow *window) * behavior is worthwhile. The basic idea is to get more feedback about how * usage scenarios of "strict" focus users and what they expect. See #326159. */ -LOCAL_SYMBOL gboolean -__window_is_terminal (MetaWindow *window) +static gboolean +window_is_terminal (MetaWindow *window) { if (window == NULL || window->res_class == NULL) return FALSE; @@ -2901,7 +2255,7 @@ window_state_on_map (MetaWindow *window, /* don't initially focus windows that are intended to not accept * focus */ - if (!(window->input || window->take_focus)) + if (!meta_window_is_focusable (window)) { *takes_focus = FALSE; return; @@ -2918,7 +2272,7 @@ window_state_on_map (MetaWindow *window, if (*takes_focus && meta_prefs_get_focus_new_windows () == C_DESKTOP_FOCUS_NEW_WINDOWS_STRICT && !window->display->allow_terminal_deactivation && - __window_is_terminal (window->display->focus_window) && + window_is_terminal (window->display->focus_window) && !meta_window_is_ancestor_of_transient (window->display->focus_window, window)) { @@ -2965,8 +2319,8 @@ static gboolean windows_overlap (const MetaWindow *w1, const MetaWindow *w2) { MetaRectangle w1rect, w2rect; - meta_window_get_outer_rect (w1, &w1rect); - meta_window_get_outer_rect (w2, &w2rect); + meta_window_get_frame_rect (w1, &w1rect); + meta_window_get_frame_rect (w2, &w2rect); return meta_rectangle_overlap (&w1rect, &w2rect); } @@ -2984,7 +2338,7 @@ windows_overlap (const MetaWindow *w1, const MetaWindow *w2) static gboolean window_would_be_covered (const MetaWindow *newbie) { - MetaWorkspace *workspace = newbie->workspace; + MetaWorkspace *workspace = meta_window_get_workspace ((MetaWindow *)newbie); GList *tmp, *windows; windows = meta_workspace_list_windows (workspace); @@ -3011,9 +2365,12 @@ window_would_be_covered (const MetaWindow *newbie) return FALSE; /* none found */ } -static void -meta_window_force_placement (MetaWindow *window) +void +meta_window_force_placement (MetaWindow *window, + gboolean force_move) { + MetaMoveResizeFlags flags; + if (window->placed) return; @@ -3026,7 +2383,15 @@ meta_window_force_placement (MetaWindow *window) * show the window. */ window->calc_placement = TRUE; - meta_window_move_resize_now (window); + + flags = META_MOVE_RESIZE_MOVE_ACTION | META_MOVE_RESIZE_RESIZE_ACTION; + if (force_move) + flags |= META_MOVE_RESIZE_FORCE_MOVE; + + meta_window_move_resize_internal (window, + flags, + META_GRAVITY_NORTH_WEST, + window->unconstrained_rect); window->calc_placement = FALSE; /* don't ever do the initial position constraint thing again. @@ -3050,6 +2415,7 @@ meta_window_show (MetaWindow *window) gboolean needs_stacking_adjustment; MetaWindow *focus_window; gboolean notify_demands_attention = FALSE; + MetaDisplay *display = window->display; meta_topic (META_DEBUG_WINDOW_STATE, "Showing window %s, shaded: %d iconic: %d placed: %d\n", @@ -3091,7 +2457,21 @@ meta_window_show (MetaWindow *window) if (!window->placed) { - meta_window_force_placement (window); + if (window->monitor && + meta_prefs_get_auto_maximize() && + window->showing_for_first_time && + window->has_maximize_func) + { + MetaRectangle work_area; + meta_window_get_work_area_for_monitor (window, window->monitor->number, &work_area); + /* Automaximize windows that map with a size > MAX_UNMAXIMIZED_WINDOW_AREA of the work area */ + if (window->rect.width * window->rect.height > work_area.width * work_area.height * MAX_UNMAXIMIZED_WINDOW_AREA) + { + window->maximize_horizontally_after_placement = TRUE; + window->maximize_vertically_after_placement = TRUE; + } + } + meta_window_force_placement (window, FALSE); } if (needs_stacking_adjustment) @@ -3152,24 +2532,24 @@ meta_window_show (MetaWindow *window) if (window->hidden) { - meta_stack_freeze (window->screen->stack); + meta_stack_freeze (window->display->stack); window->hidden = FALSE; - meta_stack_thaw (window->screen->stack); + meta_stack_thaw (window->display->stack); did_show = TRUE; } if (window->iconic) { window->iconic = FALSE; - set_wm_state (window, NormalState); + set_wm_state (window); } if (!window->visible_to_compositor) { - window->visible_to_compositor = TRUE; - MetaCompEffect effect = META_COMP_EFFECT_NONE; + window->visible_to_compositor = TRUE; + switch (window->pending_compositor_effect) { case META_COMP_EFFECT_CREATE: @@ -3184,6 +2564,7 @@ meta_window_show (MetaWindow *window) meta_compositor_show_window (window->display->compositor, window, effect); + window->pending_compositor_effect = META_COMP_EFFECT_NONE; } /* We don't want to worry about all cases from inside @@ -3200,16 +2581,8 @@ meta_window_show (MetaWindow *window) timestamp = meta_display_get_current_time_roundtrip (window->display); meta_window_focus (window, timestamp); - - if (window->move_after_placement) - { - timestamp = meta_display_get_current_time_roundtrip (window->display); - meta_window_begin_grab_op(window, META_GRAB_OP_KEYBOARD_MOVING, - FALSE, timestamp); - window->move_after_placement = FALSE; - } } - else + else if (display->x11_display) { /* Prevent EnterNotify events in sloppy/mouse focus from * erroneously focusing the window that had been denied @@ -3217,7 +2590,7 @@ meta_window_show (MetaWindow *window) * ideas for a better way to accomplish the same thing, but * they're more involved so do it this way for now. */ - meta_display_increment_focus_sentinel (window->display); + meta_x11_display_increment_focus_sentinel (display->x11_display); } } @@ -3232,7 +2605,7 @@ meta_window_show (MetaWindow *window) } if (did_show) - meta_screen_queue_check_fullscreen (window->screen); + meta_display_queue_check_fullscreen (window->display); /* * Now that we have shown the window, we no longer want to consider the @@ -3245,15 +2618,19 @@ meta_window_show (MetaWindow *window) if (notify_demands_attention) { - g_object_notify (G_OBJECT (window), "demands-attention"); + g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_DEMANDS_ATTENTION]); g_signal_emit_by_name (window->display, "window-demands-attention", window); } + + if (did_show) + g_signal_emit (window, window_signals[SHOWN], 0); } static void meta_window_hide (MetaWindow *window) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; gboolean did_hide; meta_topic (META_DEBUG_WINDOW_STATE, @@ -3261,10 +2638,10 @@ meta_window_hide (MetaWindow *window) if (window->visible_to_compositor) { - window->visible_to_compositor = FALSE; - MetaCompEffect effect = META_COMP_EFFECT_NONE; + window->visible_to_compositor = FALSE; + switch (window->pending_compositor_effect) { case META_COMP_EFFECT_CREATE: @@ -3277,17 +2654,17 @@ meta_window_hide (MetaWindow *window) break; } - meta_compositor_hide_window (window->display->compositor, - window, effect); + meta_compositor_hide_window (window->display->compositor, window, effect); + window->pending_compositor_effect = META_COMP_EFFECT_NONE; } did_hide = FALSE; if (!window->hidden) { - meta_stack_freeze (window->screen->stack); + meta_stack_freeze (window->display->stack); window->hidden = TRUE; - meta_stack_thaw (window->screen->stack); + meta_stack_thaw (window->display->stack); did_hide = TRUE; } @@ -3295,7 +2672,7 @@ meta_window_hide (MetaWindow *window) if (!window->iconic) { window->iconic = TRUE; - set_wm_state (window, IconicState); + set_wm_state (window); } set_net_wm_state (window); @@ -3308,14 +2685,7 @@ meta_window_hide (MetaWindow *window) invalidate_work_areas (window); } - /* The check on expected_focus_window is a temporary workaround for - * https://bugzilla.gnome.org/show_bug.cgi?id=597352 - * We may have already switched away from this window but not yet - * gotten FocusIn/FocusOut events. A more complete comprehensive - * fix for these type of issues is described in the bug. - */ - if (window->has_focus && - window == window->display->expected_focus_window) + if (window->has_focus) { MetaWindow *not_this_one = NULL; MetaWorkspace *my_workspace = meta_window_get_workspace (window); @@ -3328,18 +2698,20 @@ meta_window_hide (MetaWindow *window) * active workspace; when it is not, we need to pass in NULL, so as to * focus the default window for the active workspace (this scenario * arises when we are switching workspaces). + * We also pass in NULL if we are in the process of hiding all non-desktop + * windows to avoid unexpected changes to the stacking order. */ - if (window->type == META_WINDOW_MODAL_DIALOG && - my_workspace == window->screen->active_workspace) + if (my_workspace == workspace_manager->active_workspace && + !my_workspace->showing_desktop) not_this_one = window; - meta_workspace_focus_default_window (window->screen->active_workspace, + meta_workspace_focus_default_window (workspace_manager->active_workspace, not_this_one, timestamp); } if (did_hide) - meta_screen_queue_check_fullscreen (window->screen); + meta_display_queue_check_fullscreen (window->display); } static gboolean @@ -3364,7 +2736,7 @@ meta_window_minimize (MetaWindow *window) meta_window_foreach_transient (window, queue_calc_showing_func, NULL); -#ifdef WITH_VERBOSE_MODE + if (window->has_focus) { meta_topic (META_DEBUG_FOCUS, @@ -3377,11 +2749,9 @@ meta_window_minimize (MetaWindow *window) "Minimizing window %s which doesn't have the focus\n", window->desc); } -#endif - g_object_notify (G_OBJECT (window), "minimized"); - } - meta_screen_update_snapped_windows (window->screen); + g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_MINIMIZED]); + } } void @@ -3398,10 +2768,9 @@ meta_window_unminimize (MetaWindow *window) meta_window_foreach_transient (window, queue_calc_showing_func, NULL); - g_object_notify (G_OBJECT (window), "minimized"); - } - meta_screen_update_snapped_windows (window->screen); + g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_MINIMIZED]); + } } static void @@ -3440,68 +2809,23 @@ ensure_size_hints_satisfied (MetaRectangle *rect, static void meta_window_save_rect (MetaWindow *window) { - if (!(META_WINDOW_MAXIMIZED (window) || META_WINDOW_TILED_OR_SNAPPED (window) || window->fullscreen)) + if (!(META_WINDOW_MAXIMIZED (window) || META_WINDOW_TILED_SIDE_BY_SIDE (window) || window->fullscreen)) { /* save size/pos as appropriate args for move_resize */ if (!window->maximized_horizontally) { window->saved_rect.x = window->rect.x; window->saved_rect.width = window->rect.width; - if (window->frame) - window->saved_rect.x += window->frame->rect.x; } if (!window->maximized_vertically) { window->saved_rect.y = window->rect.y; window->saved_rect.height = window->rect.height; - if (window->frame) - window->saved_rect.y += window->frame->rect.y; } } } -/* - * Save the user_rect regardless of whether the window is maximized or - * fullscreen. See save_user_window_placement() for most uses. - * - * \param window Store current position of this window for future reference - */ -static void -force_save_user_window_placement (MetaWindow *window) -{ - meta_window_get_client_root_coords (window, &window->user_rect); -} - -/* - * Save the user_rect, but only if the window is neither maximized nor - * fullscreen, otherwise the window may snap back to those dimensions - * (bug #461927). - * - * \param window Store current position of this window for future reference - */ -static void -save_user_window_placement (MetaWindow *window) -{ - if (!(META_WINDOW_MAXIMIZED (window) || META_WINDOW_TILED_OR_SNAPPED (window) || window->fullscreen)) - { - MetaRectangle user_rect; - - meta_window_get_client_root_coords (window, &user_rect); - - if (!window->maximized_horizontally) - { - window->user_rect.x = user_rect.x; - window->user_rect.width = user_rect.width; - } - if (!window->maximized_vertically) - { - window->user_rect.y = user_rect.y; - window->user_rect.height = user_rect.height; - } - } -} - -LOCAL_SYMBOL void +void meta_window_maximize_internal (MetaWindow *window, MetaMaximizeFlags directions, MetaRectangle *saved_rect) @@ -3524,34 +2848,26 @@ meta_window_maximize_internal (MetaWindow *window, else meta_window_save_rect (window); - meta_window_set_tile_type (window, META_WINDOW_TILE_TYPE_NONE); - window->tile_mode = META_TILE_NONE; - normalize_tile_state (window); + if (maximize_horizontally && maximize_vertically) + window->saved_maximize = TRUE; window->maximized_horizontally = window->maximized_horizontally || maximize_horizontally; window->maximized_vertically = window->maximized_vertically || maximize_vertically; - if (maximize_horizontally || maximize_vertically) - window->force_save_user_rect = FALSE; - - if (window->maximized_horizontally && window->maximized_vertically) - { - window->saved_maximize = TRUE; - } /* Update the edge constraints */ update_edge_constraints (window);; - recalc_window_features (window); + meta_window_recalc_features (window); set_net_wm_state (window); - if (window->monitor->in_fullscreen) - meta_screen_queue_check_fullscreen (window->screen); + if (window->monitor && window->monitor->in_fullscreen) + meta_display_queue_check_fullscreen (window->display); g_object_freeze_notify (G_OBJECT (window)); - g_object_notify (G_OBJECT (window), "maximized-horizontally"); - g_object_notify (G_OBJECT (window), "maximized-vertically"); + g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_MAXIMIZED_HORIZONTALLY]); + g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_MAXIMIZED_VERTICALLY]); g_object_thaw_notify (G_OBJECT (window)); } @@ -3598,44 +2914,39 @@ meta_window_maximize (MetaWindow *window, return; } - if ((window->tile_mode != META_TILE_NONE || - window->last_tile_mode != META_TILE_NONE) && - window->tile_mode != META_TILE_MAXIMIZE) - { - saved_rect = &window->saved_rect; + if (window->tile_mode != META_TILE_NONE) + { + saved_rect = &window->saved_rect; - window->maximized_vertically = FALSE; - } + window->maximized_vertically = FALSE; + window->tile_mode = META_TILE_NONE; + } - meta_window_maximize_internal (window, - directions, - saved_rect); + meta_window_maximize_internal (window, + directions, + saved_rect); - MetaRectangle old_rect; - MetaRectangle new_rect; - gboolean desktop_effects = meta_prefs_get_desktop_effects (); + MetaRectangle old_frame_rect, old_buffer_rect; - if (desktop_effects) - meta_window_get_outer_rect (window, &old_rect); + meta_window_get_frame_rect (window, &old_frame_rect); + meta_window_get_buffer_rect (window, &old_buffer_rect); - meta_window_move_resize_now (window); + meta_compositor_size_change_window (window->display->compositor, window, + META_SIZE_CHANGE_MAXIMIZE, + &old_frame_rect, &old_buffer_rect); - if (desktop_effects) - { - meta_window_get_outer_rect (window, &new_rect); - meta_compositor_maximize_window (window->display->compositor, - window, - &old_rect, - &new_rect); - } + meta_window_move_resize_internal (window, + (META_MOVE_RESIZE_MOVE_ACTION | + META_MOVE_RESIZE_RESIZE_ACTION | + META_MOVE_RESIZE_STATE_CHANGED), + META_GRAVITY_NORTH_WEST, + window->unconstrained_rect); } - - meta_screen_tile_preview_hide (window->screen); - normalize_tile_state (window); } /** * meta_window_get_maximized: + * @window: a #MetaWindow * * Gets the current maximization state of the window, as combination * of the %META_MAXIMIZE_HORIZONTAL and %META_MAXIMIZE_VERTICAL flags; @@ -3651,6 +2962,7 @@ meta_window_get_maximized (MetaWindow *window) /** * meta_window_is_fullscreen: + * @window: a #MetaWindow * * Return value: %TRUE if the window is currently fullscreen */ @@ -3661,63 +2973,31 @@ meta_window_is_fullscreen (MetaWindow *window) } /** - * meta_window_get_all_monitors: - * @window: The #MetaWindow - * @length: (out caller-allocates): gint holding the length, may be %NULL to - * ignore + * meta_window_is_screen_sized: + * @window: A #MetaWindow * - * Returns: (array length=length) (element-type gint) (transfer container): - * List of the monitor indices the window is on. + * Return value: %TRUE if the window is occupies the + * the whole screen (all monitors). */ -gint * -meta_window_get_all_monitors (MetaWindow *window, gsize *length) +gboolean +meta_window_is_screen_sized (MetaWindow *window) { - GArray *monitors; MetaRectangle window_rect; - int i; - - monitors = g_array_new (FALSE, FALSE, sizeof (int)); - - if (meta_window_is_client_decorated (window)) - { - window_rect = window->rect; - } - else - { - meta_window_get_outer_rect (window, &window_rect); - } - - for (i = 0; i < window->screen->n_monitor_infos; i++) - { - MetaRectangle *monitor_rect = &window->screen->monitor_infos[i].rect; - - if (window->fullscreen) - { - if (meta_rectangle_contains_rect (&window_rect, monitor_rect)) - { - g_array_append_val (monitors, i); - } - } - else - { - if (meta_rectangle_overlap (&window_rect, monitor_rect)) - { - g_array_append_val (monitors, i); - } - } - } + int screen_width, screen_height; - if (length) - *length = monitors->len; + meta_display_get_size (window->display, &screen_width, &screen_height); + meta_window_get_frame_rect (window, &window_rect); - i = -1; - g_array_append_val (monitors, i); + if (window_rect.x == 0 && window_rect.y == 0 && + window_rect.width == screen_width && window_rect.height == screen_height) + return TRUE; - return (gint*) g_array_free (monitors, FALSE); + return FALSE; } /** -* meta_window_is_monitor_sized: + * meta_window_is_monitor_sized: + * @window: a #MetaWindow * * Return value: %TRUE if the window is occupies an entire monitor or * the whole screen. @@ -3725,22 +3005,21 @@ meta_window_get_all_monitors (MetaWindow *window, gsize *length) gboolean meta_window_is_monitor_sized (MetaWindow *window) { + if (!window->monitor) + return FALSE; + if (window->fullscreen) return TRUE; + if (meta_window_is_screen_sized (window)) + return TRUE; + if (window->override_redirect) { MetaRectangle window_rect, monitor_rect; - int screen_width, screen_height; - - meta_screen_get_size (window->screen, &screen_width, &screen_height); - meta_window_get_outer_rect (window, &window_rect); - - if (window_rect.x == 0 && window_rect.y == 0 && - window_rect.width == screen_width && window_rect.height == screen_height) - return TRUE; - meta_screen_get_monitor_geometry (window->screen, window->monitor->number, &monitor_rect); + meta_window_get_frame_rect (window, &window_rect); + meta_display_get_monitor_geometry (window->display, window->monitor->number, &monitor_rect); if (meta_rectangle_equal (&window_rect, &monitor_rect)) return TRUE; @@ -3751,17 +3030,21 @@ meta_window_is_monitor_sized (MetaWindow *window) /** * meta_window_is_on_primary_monitor: + * @window: a #MetaWindow * * Return value: %TRUE if the window is on the primary monitor */ gboolean meta_window_is_on_primary_monitor (MetaWindow *window) { + g_return_val_if_fail (window->monitor, FALSE); + return window->monitor->is_primary; } /** * meta_window_requested_bypass_compositor: + * @window: a #MetaWindow * * Return value: %TRUE if the window requested to bypass the compositor */ @@ -3773,6 +3056,7 @@ meta_window_requested_bypass_compositor (MetaWindow *window) /** * meta_window_requested_dont_bypass_compositor: + * @window: a #MetaWindow * * Return value: %TRUE if the window requested to opt out of unredirecting */ @@ -3783,155 +3067,202 @@ meta_window_requested_dont_bypass_compositor (MetaWindow *window) } static void -normalize_tile_state (MetaWindow *window) +meta_window_get_tile_fraction (MetaWindow *window, + MetaTileMode tile_mode, + double *fraction) { - window->snap_queued = FALSE; - window->resize_tile_mode = META_TILE_NONE; - window->resizing_tile_type = META_WINDOW_TILE_TYPE_NONE; - meta_screen_update_snapped_windows (window->screen); -} + MetaWindow *tile_match; -LOCAL_SYMBOL void -meta_window_real_tile (MetaWindow *window, gboolean force) -{ -/* Don't do anything if no tiling is requested or we're already tiled */ - if (window->tile_mode == META_TILE_NONE || (META_WINDOW_TILED_OR_SNAPPED (window) && !force)) - return; - - if (window->last_tile_mode == META_TILE_NONE && - window->resizing_tile_type == META_WINDOW_TILE_TYPE_NONE && - !META_WINDOW_MAXIMIZED (window)) - { - meta_window_save_rect (window); - } + /* Make sure the tile match is up-to-date and matches the + * passed in mode rather than the current state + */ + tile_match = meta_window_find_tile_match (window, tile_mode); + + if (tile_mode == META_TILE_NONE) + *fraction = -1.; + else if (tile_mode == META_TILE_MAXIMIZED) + *fraction = 1.; + else if (tile_match) + *fraction = 1. - tile_match->tile_hfraction; + else if (META_WINDOW_TILED_SIDE_BY_SIDE (window)) + { + if (window->tile_mode != tile_mode) + *fraction = 1. - window->tile_hfraction; + else + *fraction = window->tile_hfraction; + } + else + *fraction = .5; +} - window->maximized_horizontally = FALSE; - window->maximized_vertically = FALSE; +static void +meta_window_update_tile_fraction (MetaWindow *window, + int new_w, + int new_h) +{ + MetaWindow *tile_match = window->tile_match; + MetaRectangle work_area; - if (window->tile_mode != META_TILE_NONE) { - if (window->snap_queued || window->resizing_tile_type == META_WINDOW_TILE_TYPE_SNAPPED) { - meta_window_set_tile_type (window, META_WINDOW_TILE_TYPE_SNAPPED); - } else { - meta_window_set_tile_type (window, META_WINDOW_TILE_TYPE_TILED); - } - } else { - meta_window_set_tile_type (window, META_WINDOW_TILE_TYPE_NONE); - } + if (!META_WINDOW_TILED_SIDE_BY_SIDE (window)) + return; - recalc_window_features (window); + meta_window_get_work_area_for_monitor (window, + window->tile_monitor_number, + &work_area); + window->tile_hfraction = (double)new_w / work_area.width; - meta_screen_tile_preview_update (window->screen, FALSE); + if (tile_match && window->display->grab_window == window) + meta_window_tile (tile_match, tile_match->tile_mode); +} - if (window->resize_tile_mode == META_TILE_NONE) +static void +update_edge_constraints (MetaWindow *window) +{ + switch (window->tile_mode) { - MetaRectangle old_rect; - MetaRectangle new_rect; - gboolean desktop_effects = meta_prefs_get_desktop_effects (); + case META_TILE_NONE: + window->edge_constraints.top = META_EDGE_CONSTRAINT_NONE; + window->edge_constraints.right = META_EDGE_CONSTRAINT_NONE; + window->edge_constraints.bottom = META_EDGE_CONSTRAINT_NONE; + window->edge_constraints.left = META_EDGE_CONSTRAINT_NONE; + break; - if (desktop_effects) - meta_window_get_input_rect (window, &old_rect); + case META_TILE_MAXIMIZED: + window->edge_constraints.top = META_EDGE_CONSTRAINT_MONITOR; + window->edge_constraints.right = META_EDGE_CONSTRAINT_MONITOR; + window->edge_constraints.bottom = META_EDGE_CONSTRAINT_MONITOR; + window->edge_constraints.left = META_EDGE_CONSTRAINT_MONITOR; + break; - meta_window_move_resize_now (window); + case META_TILE_LEFT: + window->edge_constraints.top = META_EDGE_CONSTRAINT_MONITOR; - if (desktop_effects) - { - meta_window_get_input_rect (window, &new_rect); - meta_compositor_tile_window (window->display->compositor, - window, - &old_rect, - &new_rect); - } + if (window->tile_match) + window->edge_constraints.right = META_EDGE_CONSTRAINT_WINDOW; + else + window->edge_constraints.right = META_EDGE_CONSTRAINT_NONE; - if (window->frame) - meta_ui_queue_frame_draw (window->screen->ui, - window->frame->xwindow); + window->edge_constraints.bottom = META_EDGE_CONSTRAINT_MONITOR; + window->edge_constraints.left = META_EDGE_CONSTRAINT_MONITOR; + break; + + case META_TILE_RIGHT: + window->edge_constraints.top = META_EDGE_CONSTRAINT_MONITOR; + window->edge_constraints.right = META_EDGE_CONSTRAINT_MONITOR; + window->edge_constraints.bottom = META_EDGE_CONSTRAINT_MONITOR; + + if (window->tile_match) + window->edge_constraints.left = META_EDGE_CONSTRAINT_WINDOW; + else + window->edge_constraints.left = META_EDGE_CONSTRAINT_NONE; + break; } - else + + /* h/vmaximize also modify the edge constraints */ + if (window->maximized_vertically) { - /* move_resize with new tiling constraints - */ - meta_window_queue (window, META_QUEUE_MOVE_RESIZE); + window->edge_constraints.top = META_EDGE_CONSTRAINT_MONITOR; + window->edge_constraints.bottom = META_EDGE_CONSTRAINT_MONITOR; } - normalize_tile_state (window); - - set_net_wm_state (window); - - meta_screen_tile_preview_hide (window->screen); - meta_window_get_outer_rect (window, &window->snapped_rect); + if (window->maximized_horizontally) + { + window->edge_constraints.right = META_EDGE_CONSTRAINT_MONITOR; + window->edge_constraints.left = META_EDGE_CONSTRAINT_MONITOR; + } } -static gboolean -meta_window_can_tile_maximized (MetaWindow *window) +void +meta_window_tile (MetaWindow *window, + MetaTileMode tile_mode) { - return window->has_maximize_func; -} + MetaMaximizeFlags directions; + MetaRectangle old_frame_rect, old_buffer_rect; -LOCAL_SYMBOL gboolean -meta_window_can_tile_side_by_side (MetaWindow *window) -{ - int monitor; - MetaRectangle tile_area; - MetaFrameBorders borders; + meta_window_get_tile_fraction (window, tile_mode, &window->tile_hfraction); + window->tile_mode = tile_mode; - if (!meta_window_can_tile_maximized (window)) - return FALSE; + /* Don't do anything if no tiling is requested */ + if (window->tile_mode == META_TILE_NONE) + { + window->tile_monitor_number = -1; + return; + } - monitor = meta_screen_get_current_monitor (window->screen); - meta_window_get_work_area_for_monitor (window, monitor, &tile_area); + if (window->tile_mode == META_TILE_MAXIMIZED) + directions = META_MAXIMIZE_BOTH; + else + directions = META_MAXIMIZE_VERTICAL; - tile_area.width /= 2; + meta_window_maximize_internal (window, directions, NULL); + meta_display_update_tile_preview (window->display, FALSE); - meta_frame_calc_borders (window->frame, &borders); - meta_window_unextend_by_frame (window, &tile_area, &borders); + /* Setup the edge constraints */ + update_edge_constraints (window); - return tile_area.width >= window->size_hints.min_width && - tile_area.height >= window->size_hints.min_height; -} + meta_window_get_frame_rect (window, &old_frame_rect); + meta_window_get_buffer_rect (window, &old_buffer_rect); -LOCAL_SYMBOL gboolean -meta_window_can_tile_top_bottom (MetaWindow *window) -{ - int monitor; - MetaRectangle tile_area; - MetaFrameBorders borders; + meta_compositor_size_change_window (window->display->compositor, window, + META_SIZE_CHANGE_MAXIMIZE, + &old_frame_rect, &old_buffer_rect); - if (!meta_window_can_tile_maximized (window)) - return FALSE; + meta_window_move_resize_internal (window, + (META_MOVE_RESIZE_MOVE_ACTION | + META_MOVE_RESIZE_RESIZE_ACTION | + META_MOVE_RESIZE_STATE_CHANGED), + META_GRAVITY_NORTH_WEST, + window->unconstrained_rect); - monitor = meta_screen_get_current_monitor (window->screen); - meta_window_get_work_area_for_monitor (window, monitor, &tile_area); + if (window->frame) + meta_frame_queue_draw (window->frame); +} - tile_area.height /= 2; +MetaTileMode +meta_window_get_tile_mode (MetaWindow *window) +{ + return window->tile_mode; +} - meta_frame_calc_borders (window->frame, &borders); - meta_window_unextend_by_frame (window, &tile_area, &borders); +void +meta_window_restore_tile (MetaWindow *window, + MetaTileMode mode, + int width, + int height) +{ + meta_window_update_tile_fraction (window, width, height); + meta_window_tile (window, mode); +} - return tile_area.width >= window->size_hints.min_width && - tile_area.height >= window->size_hints.min_height; +static gboolean +meta_window_can_tile_maximized (MetaWindow *window) +{ + return window->has_maximize_func; } -LOCAL_SYMBOL gboolean -meta_window_can_tile_corner (MetaWindow *window) +gboolean +meta_window_can_tile_side_by_side (MetaWindow *window) { int monitor; MetaRectangle tile_area; - MetaFrameBorders borders; + MetaRectangle client_rect; if (!meta_window_can_tile_maximized (window)) return FALSE; - monitor = meta_screen_get_current_monitor (window->screen); + monitor = meta_display_get_current_monitor (window->display); meta_window_get_work_area_for_monitor (window, monitor, &tile_area); + /* Do not allow tiling in portrait orientation */ + if (tile_area.height > tile_area.width) + return FALSE; + tile_area.width /= 2; - tile_area.height /= 2; - meta_frame_calc_borders (window->frame, &borders); - meta_window_unextend_by_frame (window, &tile_area, &borders); + meta_window_frame_rect_to_client_rect (window, &tile_area, &client_rect); - return tile_area.width >= window->size_hints.min_width && - tile_area.height >= window->size_hints.min_height; + return client_rect.width >= window->size_hints.min_width && + client_rect.height >= window->size_hints.min_height; } static void @@ -3943,18 +3274,14 @@ unmaximize_window_before_freeing (MetaWindow *window) window->maximized_horizontally = FALSE; window->maximized_vertically = FALSE; - window->custom_snap_size = FALSE; - if (window->tile_type != META_WINDOW_TILE_TYPE_NONE) { - meta_window_set_tile_type (window, META_WINDOW_TILE_TYPE_NONE); - meta_screen_update_snapped_windows (window->screen); - } if (window->withdrawn) /* See bug #137185 */ { window->rect = window->saved_rect; set_net_wm_state (window); } - else if (window->screen->closing) /* See bug #358042 */ +#ifdef HAVE_WAYLAND + else if (!meta_is_wayland_compositor ()) { /* Do NOT update net_wm_state: this screen is closing, * it likely will be managed by another window manager @@ -3962,48 +3289,58 @@ unmaximize_window_before_freeing (MetaWindow *window) * Moreover, it will need to know the unmaximized geometry, * therefore move_resize the window to saved_rect here * before closing it. */ - meta_window_move_resize (window, - FALSE, - window->saved_rect.x, - window->saved_rect.y, - window->saved_rect.width, - window->saved_rect.height); + meta_window_move_resize_frame (window, + FALSE, + window->saved_rect.x, + window->saved_rect.y, + window->saved_rect.width, + window->saved_rect.height); } +#endif } static void -meta_window_unmaximize_internal (MetaWindow *window, - MetaMaximizeFlags directions, - MetaRectangle *desired_rect, - int gravity) +meta_window_maybe_apply_size_hints (MetaWindow *window, + MetaRectangle *target_rect) +{ + meta_window_frame_rect_to_client_rect (window, target_rect, target_rect); + ensure_size_hints_satisfied (target_rect, &window->size_hints); + meta_window_client_rect_to_frame_rect (window, target_rect, target_rect); +} + +void +meta_window_unmaximize (MetaWindow *window, + MetaMaximizeFlags directions) { gboolean unmaximize_horizontally, unmaximize_vertically; + g_return_if_fail (!window->override_redirect); /* At least one of the two directions ought to be set */ unmaximize_horizontally = directions & META_MAXIMIZE_HORIZONTAL; unmaximize_vertically = directions & META_MAXIMIZE_VERTICAL; + g_assert (unmaximize_horizontally || unmaximize_vertically); if (unmaximize_horizontally && unmaximize_vertically) window->saved_maximize = FALSE; - /* Only do something if the window is tiled, or maximized in the + /* Only do something if the window isn't already maximized in the * given direction(s). */ if ((unmaximize_horizontally && window->maximized_horizontally) || - (unmaximize_vertically && window->maximized_vertically) || - window->tile_type != META_WINDOW_TILE_TYPE_NONE || - window->tile_mode != META_TILE_NONE) + (unmaximize_vertically && window->maximized_vertically)) { + MetaRectangle *desired_rect; MetaRectangle target_rect; MetaRectangle work_area; - - window->last_tile_mode = META_TILE_NONE; - window->tile_mode = META_TILE_NONE; - window->resizing_tile_type = META_WINDOW_TILE_TYPE_NONE; - meta_window_set_tile_type (window, META_WINDOW_TILE_TYPE_NONE); + MetaRectangle old_frame_rect, old_buffer_rect; meta_window_get_work_area_for_monitor (window, window->monitor->number, &work_area); + meta_window_get_frame_rect (window, &old_frame_rect); + meta_window_get_buffer_rect (window, &old_buffer_rect); + + if (unmaximize_vertically) + window->tile_mode = META_TILE_NONE; meta_topic (META_DEBUG_WINDOW_OPS, "Unmaximizing %s%s\n", @@ -4026,10 +3363,33 @@ meta_window_unmaximize_internal (MetaWindow *window, */ meta_window_frame_size_changed (window); + desired_rect = &window->saved_rect; + /* Unmaximize to the saved_rect position in the direction(s) * being unmaximized. */ - meta_window_get_client_root_coords (window, &target_rect); + target_rect = old_frame_rect; + + /* Avoid unmaximizing to "almost maximized" size when the previous size + * is greater then 80% of the work area use MAX_UNMAXIMIZED_WINDOW_AREA of the work area as upper limit + * while maintaining the aspect ratio. + */ + if (unmaximize_horizontally && unmaximize_vertically && + desired_rect->width * desired_rect->height > work_area.width * work_area.height * MAX_UNMAXIMIZED_WINDOW_AREA) + { + if (desired_rect->width > desired_rect->height) + { + float aspect = (float)desired_rect->height / (float)desired_rect->width; + desired_rect->width = MAX (work_area.width * sqrt (MAX_UNMAXIMIZED_WINDOW_AREA), window->size_hints.min_width); + desired_rect->height = MAX (desired_rect->width * aspect, window->size_hints.min_height); + } + else + { + float aspect = (float)desired_rect->width / (float)desired_rect->height; + desired_rect->height = MAX (work_area.height * sqrt (MAX_UNMAXIMIZED_WINDOW_AREA), window->size_hints.min_height); + desired_rect->width = MAX (desired_rect->height * aspect, window->size_hints.min_width); + } + } if (unmaximize_horizontally) { @@ -4045,111 +3405,44 @@ meta_window_unmaximize_internal (MetaWindow *window, /* Window's size hints may have changed while maximized, making * saved_rect invalid. #329152 */ - ensure_size_hints_satisfied (&target_rect, &window->size_hints); - - if (window->resizing_tile_type == META_WINDOW_TILE_TYPE_NONE) - { - MetaRectangle old_rect, new_rect; - gboolean desktop_effects = meta_prefs_get_desktop_effects (); - - if (desktop_effects) - meta_window_get_outer_rect (window, &old_rect); + meta_window_maybe_apply_size_hints (window, &target_rect); - meta_window_move_resize_internal (window, - META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION, - gravity, - target_rect.x, - target_rect.y, - target_rect.width, - target_rect.height); - - if (desktop_effects) - { - meta_window_get_outer_rect (window, &new_rect); - meta_compositor_unmaximize_window (window->display->compositor, - window, - &old_rect, - &new_rect); - } - } - else - { - meta_window_move_resize_internal (window, - META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION, - gravity, - target_rect.x, - target_rect.y, - target_rect.width, - target_rect.height); - } + meta_compositor_size_change_window (window->display->compositor, window, + META_SIZE_CHANGE_UNMAXIMIZE, + &old_frame_rect, &old_buffer_rect); - /* Make sure user_rect is current. - */ - force_save_user_window_placement (window); + meta_window_move_resize_internal (window, + (META_MOVE_RESIZE_MOVE_ACTION | + META_MOVE_RESIZE_RESIZE_ACTION | + META_MOVE_RESIZE_STATE_CHANGED | + META_MOVE_RESIZE_UNMAXIMIZE), + META_GRAVITY_NORTH_WEST, + target_rect); /* When we unmaximize, if we're doing a mouse move also we could * get the window suddenly jumping to the upper left corner of * the workspace, since that's where it was when the grab op - * started. So we need to update the grab state. We have to do - * it after the actual operation, as the window may have been moved - * by constraints. + * started. So we need to update the grab anchor position. */ if (meta_grab_op_is_moving (window->display->grab_op) && window->display->grab_window == window) { - window->display->grab_anchor_window_pos = window->user_rect; + window->display->grab_anchor_window_pos = target_rect; } - if (window->resizing_tile_type == META_WINDOW_TILE_TYPE_NONE) - window->custom_snap_size = FALSE; - - meta_screen_update_snapped_windows (window->screen); - - recalc_window_features (window); + meta_window_recalc_features (window); set_net_wm_state (window); if (!window->monitor->in_fullscreen) - meta_screen_queue_check_fullscreen (window->screen); + meta_display_queue_check_fullscreen (window->display); } - g_object_freeze_notify (G_OBJECT (window)); - g_object_notify (G_OBJECT (window), "maximized-horizontally"); - g_object_notify (G_OBJECT (window), "maximized-vertically"); - g_object_thaw_notify (G_OBJECT (window)); + g_object_freeze_notify (G_OBJECT (window)); + g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_MAXIMIZED_HORIZONTALLY]); + g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_MAXIMIZED_VERTICALLY]); + g_object_thaw_notify (G_OBJECT (window)); } void -meta_window_unmaximize (MetaWindow *window, - MetaMaximizeFlags directions) -{ - meta_window_unmaximize_internal (window, directions, &window->saved_rect, - NorthWestGravity); -} - -/* Like meta_window_unmaximize(), but instead of unmaximizing to the - * saved position, we give the new desired size, and the gravity that - * determines the positioning relationship between the area occupied - * maximized and the new are. The arguments are similar to - * meta_window_resize_with_gravity(). - * Unlike meta_window_unmaximize(), tiling is not restored for windows - * with a tile mode other than META_TILE_NONE. - */ -LOCAL_SYMBOL void -meta_window_unmaximize_with_gravity (MetaWindow *window, - MetaMaximizeFlags directions, - int new_width, - int new_height, - int gravity) -{ - MetaRectangle desired_rect; - - meta_window_get_position (window, &desired_rect.x, &desired_rect.y); - desired_rect.width = new_width; - desired_rect.height = new_height; - - meta_window_unmaximize_internal (window, directions, &desired_rect, gravity); -} - -LOCAL_SYMBOL void meta_window_make_above (MetaWindow *window) { g_return_if_fail (!window->override_redirect); @@ -4158,7 +3451,7 @@ meta_window_make_above (MetaWindow *window) meta_window_raise (window); } -LOCAL_SYMBOL void +void meta_window_unmake_above (MetaWindow *window) { g_return_if_fail (!window->override_redirect); @@ -4179,10 +3472,10 @@ meta_window_set_above (MetaWindow *window, meta_window_update_layer (window); set_net_wm_state (window); meta_window_frame_size_changed (window); - g_object_notify (G_OBJECT (window), "above"); + g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_ABOVE]); } -LOCAL_SYMBOL LOCAL_SYMBOL void +void meta_window_make_fullscreen_internal (MetaWindow *window) { if (!window->fullscreen) @@ -4203,46 +3496,56 @@ meta_window_make_fullscreen_internal (MetaWindow *window) meta_window_save_rect (window); window->fullscreen = TRUE; - window->force_save_user_rect = FALSE; - meta_stack_freeze (window->screen->stack); + meta_stack_freeze (window->display->stack); meta_window_raise (window); - meta_stack_thaw (window->screen->stack); + meta_stack_thaw (window->display->stack); - recalc_window_features (window); + meta_window_recalc_features (window); set_net_wm_state (window); /* For the auto-minimize feature, if we fail to get focus */ - meta_screen_queue_check_fullscreen (window->screen); + meta_display_queue_check_fullscreen (window->display); - meta_stack_tracker_queue_sync_stack (window->screen->stack_tracker); - g_object_notify (G_OBJECT (window), "fullscreen"); + g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_FULLSCREEN]); } } -LOCAL_SYMBOL void +void meta_window_make_fullscreen (MetaWindow *window) { g_return_if_fail (!window->override_redirect); if (!window->fullscreen) { + MetaRectangle old_frame_rect, old_buffer_rect; + + meta_window_get_frame_rect (window, &old_frame_rect); + meta_window_get_buffer_rect (window, &old_buffer_rect); + + meta_compositor_size_change_window (window->display->compositor, + window, META_SIZE_CHANGE_FULLSCREEN, + &old_frame_rect, &old_buffer_rect); + meta_window_make_fullscreen_internal (window); - /* move_resize with new constraints - */ - meta_window_queue(window, META_QUEUE_MOVE_RESIZE); + meta_window_move_resize_internal (window, + (META_MOVE_RESIZE_MOVE_ACTION | + META_MOVE_RESIZE_RESIZE_ACTION | + META_MOVE_RESIZE_STATE_CHANGED), + META_GRAVITY_NORTH_WEST, + window->unconstrained_rect); } } -LOCAL_SYMBOL void +void meta_window_unmake_fullscreen (MetaWindow *window) { g_return_if_fail (!window->override_redirect); if (window->fullscreen) { - MetaRectangle target_rect; + MetaRectangle old_frame_rect, old_buffer_rect, target_rect; meta_topic (META_DEBUG_WINDOW_OPS, "Unfullscreening %s\n", window->desc); @@ -4250,54 +3553,64 @@ meta_window_unmake_fullscreen (MetaWindow *window) window->fullscreen = FALSE; target_rect = window->saved_rect; + meta_window_frame_size_changed (window); + meta_window_get_frame_rect (window, &old_frame_rect); + meta_window_get_buffer_rect (window, &old_buffer_rect); + /* Window's size hints may have changed while maximized, making * saved_rect invalid. #329152 */ - ensure_size_hints_satisfied (&target_rect, &window->size_hints); + meta_window_maybe_apply_size_hints (window, &target_rect); /* Need to update window->has_resize_func before we move_resize() */ - recalc_window_features (window); + meta_window_recalc_features (window); set_net_wm_state (window); - meta_window_move_resize (window, - FALSE, - target_rect.x, - target_rect.y, - target_rect.width, - target_rect.height); + meta_compositor_size_change_window (window->display->compositor, + window, META_SIZE_CHANGE_UNFULLSCREEN, + &old_frame_rect, &old_buffer_rect); - /* Make sure user_rect is current. - */ - force_save_user_window_placement (window); + meta_window_move_resize_internal (window, + (META_MOVE_RESIZE_MOVE_ACTION | + META_MOVE_RESIZE_RESIZE_ACTION | + META_MOVE_RESIZE_STATE_CHANGED | + META_MOVE_RESIZE_UNFULLSCREEN), + META_GRAVITY_NORTH_WEST, + target_rect); - meta_screen_queue_check_fullscreen (window->screen); + meta_display_queue_check_fullscreen (window->display); - meta_stack_tracker_queue_sync_stack (window->screen->stack_tracker); - g_object_notify (G_OBJECT (window), "fullscreen"); + g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_FULLSCREEN]); } } -LOCAL_SYMBOL void -meta_window_update_fullscreen_monitors (MetaWindow *window, - unsigned long top, - unsigned long bottom, - unsigned long left, - unsigned long right) +static void +meta_window_clear_fullscreen_monitors (MetaWindow *window) +{ + window->fullscreen_monitors.top = NULL; + window->fullscreen_monitors.bottom = NULL; + window->fullscreen_monitors.left = NULL; + window->fullscreen_monitors.right = NULL; +} + +void +meta_window_update_fullscreen_monitors (MetaWindow *window, + MetaLogicalMonitor *top, + MetaLogicalMonitor *bottom, + MetaLogicalMonitor *left, + MetaLogicalMonitor *right) { - if ((int)top < window->screen->n_monitor_infos && - (int)bottom < window->screen->n_monitor_infos && - (int)left < window->screen->n_monitor_infos && - (int)right < window->screen->n_monitor_infos) + if (top && bottom && left && right) { - window->fullscreen_monitors[0] = top; - window->fullscreen_monitors[1] = bottom; - window->fullscreen_monitors[2] = left; - window->fullscreen_monitors[3] = right; + window->fullscreen_monitors.top = top; + window->fullscreen_monitors.bottom = bottom; + window->fullscreen_monitors.left = left; + window->fullscreen_monitors.right = right; } else { - window->fullscreen_monitors[0] = -1; + meta_window_clear_fullscreen_monitors (window); } if (window->fullscreen) @@ -4306,7 +3619,23 @@ meta_window_update_fullscreen_monitors (MetaWindow *window, } } -LOCAL_SYMBOL void +gboolean +meta_window_has_fullscreen_monitors (MetaWindow *window) +{ + return window->fullscreen_monitors.top != NULL; +} + +void +meta_window_adjust_fullscreen_monitor_rect (MetaWindow *window, + MetaRectangle *monitor_rect) +{ + MetaWindowClass *window_class = META_WINDOW_GET_CLASS (window); + + if (window_class->adjust_fullscreen_monitor_rect) + window_class->adjust_fullscreen_monitor_rect (window, monitor_rect); +} + +void meta_window_shade (MetaWindow *window, guint32 timestamp) { @@ -4333,7 +3662,7 @@ meta_window_shade (MetaWindow *window, } } -LOCAL_SYMBOL void +void meta_window_unshade (MetaWindow *window, guint32 timestamp) { @@ -4357,37 +3686,6 @@ meta_window_unshade (MetaWindow *window, } } -#define OPACITY_STEP 32 - -LOCAL_SYMBOL void -meta_window_adjust_opacity (MetaWindow *window, - gboolean increase) -{ - ClutterActor *actor = CLUTTER_ACTOR (meta_window_get_compositor_private (window)); - - gint current_opacity, new_opacity; - - current_opacity = clutter_actor_get_opacity (actor); - - if (increase) { - new_opacity = MIN (current_opacity + OPACITY_STEP, 255); - } else { - new_opacity = MAX (current_opacity - OPACITY_STEP, MAX (0, meta_prefs_get_min_win_opacity ())); - } - - if (new_opacity != current_opacity) { - clutter_actor_set_opacity (actor, (guint8) new_opacity); - } -} - -void -meta_window_reset_opacity (MetaWindow *window) -{ - ClutterActor *actor = CLUTTER_ACTOR (meta_window_get_compositor_private (window)); - - clutter_actor_set_opacity (actor, 255); -} - static gboolean unminimize_func (MetaWindow *window, void *data) @@ -4403,29 +3701,29 @@ unminimize_window_and_all_transient_parents (MetaWindow *window) meta_window_foreach_ancestor (window, unminimize_func, NULL); } -static void -window_activate (MetaWindow *window, - guint32 timestamp, - MetaClientType source_indication, - MetaWorkspace *workspace) +void +meta_window_activate_full (MetaWindow *window, + guint32 timestamp, + MetaClientType source_indication, + MetaWorkspace *workspace) { - gboolean can_ignore_outdated_timestamps; + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; + gboolean allow_workspace_switch; + + if (window->unmanaging) + { + g_warning ("Trying to activate unmanaged window '%s'", window->desc); + return; + } + meta_topic (META_DEBUG_FOCUS, "_NET_ACTIVE_WINDOW message sent for %s at time %u " "by client type %u.\n", window->desc, timestamp, source_indication); - /* Older EWMH spec didn't specify a timestamp; we decide to honor these only - * if the app specifies that it is a pager. - * - * Update: Unconditionally honor 0 timestamps for now; we'll fight - * that battle later. Just remove the "FALSE &&" in order to only - * honor 0 timestamps for pagers. - */ - can_ignore_outdated_timestamps = - (timestamp != 0 || (FALSE && source_indication != META_CLIENT_TYPE_PAGER)); - if (XSERVER_TIME_IS_BEFORE (timestamp, window->display->last_user_time) && - can_ignore_outdated_timestamps) + allow_workspace_switch = (timestamp != 0); + if (timestamp != 0 && + XSERVER_TIME_IS_BEFORE (timestamp, window->display->last_user_time)) { meta_topic (META_DEBUG_FOCUS, "last_user_time (%u) is more recent; ignoring " @@ -4435,14 +3733,8 @@ window_activate (MetaWindow *window, return; } - /* For those stupid pagers, get a valid timestamp and show a warning */ if (timestamp == 0) - { - meta_topic (META_DEBUG_FOCUS, - "meta_window_activate called by a pager with a 0 timestamp; " - "the pager needs to be fixed.\n"); - timestamp = meta_display_get_current_time_roundtrip (window->display); - } + timestamp = meta_display_get_current_time_roundtrip (window->display); meta_window_set_user_time (window, timestamp); @@ -4451,30 +3743,24 @@ window_activate (MetaWindow *window, /* Get window on current or given workspace */ if (workspace == NULL) - workspace = window->screen->active_workspace; + workspace = workspace_manager->active_workspace; /* For non-transient windows, we just set up a pulsing indicator, rather than move windows or workspaces. See http://bugzilla.gnome.org/show_bug.cgi?id=482354 */ - if (window->xtransient_for == None) + if (window->transient_for == NULL && + !allow_workspace_switch && + !meta_window_located_on_workspace (window, workspace)) { - if (!meta_window_located_on_workspace (window, workspace)) - { - if (meta_prefs_get_bring_windows_to_current_workspace ()) - { - meta_window_change_workspace (window, workspace); - } - else - { - meta_workspace_activate (window->workspace, timestamp); - } - } + meta_window_set_demands_attention (window); + /* We've marked it as demanding, don't need to do anything else. */ + return; } - else if (window->xtransient_for != None) + else if (window->transient_for != NULL) { /* Move transients to current workspace - preference dialogs should appear over the source window. */ - meta_window_change_workspace (window, workspace); + meta_window_change_workspace (window, workspace); } if (window->shaded) @@ -4489,11 +3775,17 @@ window_activate (MetaWindow *window, meta_topic (META_DEBUG_FOCUS, "Focusing window %s due to activation\n", window->desc); - meta_window_focus (window, timestamp); + + if (meta_window_located_on_workspace (window, workspace)) + meta_window_focus (window, timestamp); + else + meta_workspace_activate_with_focus (window->workspace, window, timestamp); + + meta_window_check_alive (window, timestamp); } /* This function exists since most of the functionality in window_activate - * is useful for Muffin, but Muffin shouldn't need to specify a client + * is useful for Mutter, but Mutter shouldn't need to specify a client * type for itself. ;-) */ void @@ -4506,7 +3798,7 @@ meta_window_activate (MetaWindow *window, * we were such. If we change the pager behavior later, we could revisit * this and just add extra flags to window_activate. */ - window_activate (window, timestamp, META_CLIENT_TYPE_PAGER, NULL); + meta_window_activate_full (window, timestamp, META_CLIENT_TYPE_PAGER, NULL); } void @@ -4516,1020 +3808,390 @@ meta_window_activate_with_workspace (MetaWindow *window, { g_return_if_fail (!window->override_redirect); - /* We're not really a pager, but the behavior we want is the same as if - * we were such. If we change the pager behavior later, we could revisit - * this and just add extra flags to window_activate. - */ - window_activate (window, timestamp, META_CLIENT_TYPE_APPLICATION, workspace); + meta_window_activate_full (window, timestamp, META_CLIENT_TYPE_APPLICATION, workspace); } -/* Manually fix all the weirdness explained in the big comment at the - * beginning of meta_window_move_resize_internal() giving positions - * expected by meta_window_constrain (i.e. positions & sizes of the - * internal or client window). +/** + * meta_window_updates_are_frozen: + * @window: a #MetaWindow + * + * Gets whether the compositor should be updating the window contents; + * window content updates may be frozen at client request by setting + * an odd value in the extended _NET_WM_SYNC_REQUEST_COUNTER counter + * by the window manager during a resize operation while waiting for + * the client to redraw. + * + * Return value: %TRUE if updates are currently frozen */ +gboolean +meta_window_updates_are_frozen (MetaWindow *window) +{ + return META_WINDOW_GET_CLASS (window)->are_updates_frozen (window); +} + static void -adjust_for_gravity (MetaWindow *window, - MetaFrameBorders *borders, - gboolean coords_assume_border, - int gravity, - MetaRectangle *rect) -{ - int ref_x, ref_y; - int bw; - int child_x, child_y; - int frame_width, frame_height; - - if (coords_assume_border) - bw = window->border_width; - else - bw = 0; +meta_window_reposition (MetaWindow *window) +{ + meta_window_move_resize_internal (window, + (META_MOVE_RESIZE_MOVE_ACTION | + META_MOVE_RESIZE_RESIZE_ACTION), + META_GRAVITY_NORTH_WEST, + window->rect); +} - if (borders) - { - child_x = borders->visible.left; - child_y = borders->visible.top; - frame_width = child_x + rect->width + borders->visible.right; - frame_height = child_y + rect->height + borders->visible.bottom; - } - else - { - child_x = 0; - child_y = 0; - frame_width = rect->width; - frame_height = rect->height; - } +static gboolean +maybe_move_attached_window (MetaWindow *window, + void *data) +{ + if (window->hidden) + return G_SOURCE_CONTINUE; - /* We're computing position to pass to window_move, which is - * the position of the client window (StaticGravity basically) - * - * (see WM spec description of gravity computation, but note that - * their formulas assume we're honoring the border width, rather - * than compensating for having turned it off) - */ - switch (gravity) - { - case NorthWestGravity: - ref_x = rect->x; - ref_y = rect->y; - break; - case NorthGravity: - ref_x = rect->x + rect->width / 2 + bw; - ref_y = rect->y; - break; - case NorthEastGravity: - ref_x = rect->x + rect->width + bw * 2; - ref_y = rect->y; - break; - case WestGravity: - ref_x = rect->x; - ref_y = rect->y + rect->height / 2 + bw; - break; - case CenterGravity: - ref_x = rect->x + rect->width / 2 + bw; - ref_y = rect->y + rect->height / 2 + bw; - break; - case EastGravity: - ref_x = rect->x + rect->width + bw * 2; - ref_y = rect->y + rect->height / 2 + bw; - break; - case SouthWestGravity: - ref_x = rect->x; - ref_y = rect->y + rect->height + bw * 2; - break; - case SouthGravity: - ref_x = rect->x + rect->width / 2 + bw; - ref_y = rect->y + rect->height + bw * 2; - break; - case SouthEastGravity: - ref_x = rect->x + rect->width + bw * 2; - ref_y = rect->y + rect->height + bw * 2; - break; - case StaticGravity: - default: - ref_x = rect->x; - ref_y = rect->y; - break; - } - - switch (gravity) - { - case NorthWestGravity: - rect->x = ref_x + child_x; - rect->y = ref_y + child_y; - break; - case NorthGravity: - rect->x = ref_x - frame_width / 2 + child_x; - rect->y = ref_y + child_y; - break; - case NorthEastGravity: - rect->x = ref_x - frame_width + child_x; - rect->y = ref_y + child_y; - break; - case WestGravity: - rect->x = ref_x + child_x; - rect->y = ref_y - frame_height / 2 + child_y; - break; - case CenterGravity: - rect->x = ref_x - frame_width / 2 + child_x; - rect->y = ref_y - frame_height / 2 + child_y; - break; - case EastGravity: - rect->x = ref_x - frame_width + child_x; - rect->y = ref_y - frame_height / 2 + child_y; - break; - case SouthWestGravity: - rect->x = ref_x + child_x; - rect->y = ref_y - frame_height + child_y; - break; - case SouthGravity: - rect->x = ref_x - frame_width / 2 + child_x; - rect->y = ref_y - frame_height + child_y; - break; - case SouthEastGravity: - rect->x = ref_x - frame_width + child_x; - rect->y = ref_y - frame_height + child_y; - break; - case StaticGravity: - default: - rect->x = ref_x; - rect->y = ref_y; - break; - } -} - -static gboolean -static_gravity_works (MetaDisplay *display) -{ - return display->static_gravity_works; -} - -void -meta_window_create_sync_request_alarm (MetaWindow *window) -{ -#ifdef HAVE_XSYNC - XSyncAlarmAttributes values; - XSyncValue init; - - if (window->sync_request_counter == None || - window->sync_request_alarm != None) - return; - - meta_error_trap_push_with_return (window->display); - - /* In the new (extended style), the counter value is initialized by - * the client before mapping the window. In the old style, we're - * responsible for setting the initial value of the counter. - */ - if (window->extended_sync_request_counter) - { - if (!XSyncQueryCounter(window->display->xdisplay, - window->sync_request_counter, - &init)) - { - meta_error_trap_pop_with_return (window->display); - window->sync_request_counter = None; - return; - } - - window->sync_request_serial = - XSyncValueLow32 (init) + ((gint64)XSyncValueHigh32 (init) << 32); - - /* if the value is odd, the window starts off with updates frozen */ - meta_compositor_set_updates_frozen (window->display->compositor, window, - meta_window_updates_are_frozen (window)); - } - else - { - XSyncIntToValue (&init, 0); - XSyncSetCounter (window->display->xdisplay, - window->sync_request_counter, init); - window->sync_request_serial = 0; - } - - values.trigger.counter = window->sync_request_counter; - values.trigger.test_type = XSyncPositiveComparison; - - /* Initialize to one greater than the current value */ - values.trigger.value_type = XSyncRelative; - XSyncIntToValue (&values.trigger.wait_value, 1); - - /* After triggering, increment test_value by this until - * until the test condition is false */ - XSyncIntToValue (&values.delta, 1); - - /* we want events (on by default anyway) */ - values.events = True; - - window->sync_request_alarm = XSyncCreateAlarm (window->display->xdisplay, - XSyncCACounter | - XSyncCAValueType | - XSyncCAValue | - XSyncCATestType | - XSyncCADelta | - XSyncCAEvents, - &values); - - if (meta_error_trap_pop_with_return (window->display) == Success) - meta_display_register_sync_alarm (window->display, &window->sync_request_alarm, window); - else - { - window->sync_request_alarm = None; - window->sync_request_counter = None; - } -#endif -} - -void -meta_window_destroy_sync_request_alarm (MetaWindow *window) -{ -#ifdef HAVE_XSYNC - if (window->sync_request_alarm != None) - { - /* Has to be unregistered _before_ clearing the structure field */ - meta_display_unregister_sync_alarm (window->display, window->sync_request_alarm); - XSyncDestroyAlarm (window->display->xdisplay, - window->sync_request_alarm); - window->sync_request_alarm = None; - } -#endif /* HAVE_XSYNC */ -} - -#ifdef HAVE_XSYNC -static gboolean -sync_request_timeout (gpointer data) -{ - MetaWindow *window = data; - - window->sync_request_timeout_id = 0; - - /* We have now waited for more than a second for the - * application to respond to the sync request - */ - window->disable_sync = TRUE; - - /* Reset the wait serial, so we don't continue freezing - * window updates - */ - window->sync_request_wait_serial = 0; - meta_compositor_set_updates_frozen (window->display->compositor, window, - meta_window_updates_are_frozen (window)); - - if (window == window->display->grab_window && - meta_grab_op_is_resizing (window->display->grab_op)) - { - update_resize (window, - window->display->grab_last_user_action_was_snap, - window->display->grab_latest_motion_x, - window->display->grab_latest_motion_y, - TRUE); - } + if (meta_window_is_attached_dialog (window) || + meta_window_get_placement_rule (window)) + meta_window_reposition (window); - return FALSE; -} - -static void -send_sync_request (MetaWindow *window) -{ - XClientMessageEvent ev; - gint64 wait_serial; - - /* For the old style of _NET_WM_SYNC_REQUEST_COUNTER, we just have to - * increase the value, but for the new "extended" style we need to - * pick an even (unfrozen) value sufficiently ahead of the last serial - * that we received from the client; the same code still works - * for the old style. The increment of 240 is specified by the EWMH - * and is (1 second) * (60fps) * (an increment of 4 per frame). - */ - wait_serial = window->sync_request_serial + 240; - - window->sync_request_wait_serial = wait_serial; - - ev.type = ClientMessage; - ev.window = window->xwindow; - ev.message_type = window->display->atom_WM_PROTOCOLS; - ev.format = 32; - ev.data.l[0] = window->display->atom__NET_WM_SYNC_REQUEST; - - ev.data.l[1] = window->display->current_time; - ev.data.l[2] = wait_serial & G_GUINT64_CONSTANT(0xffffffff); - ev.data.l[3] = wait_serial >> 32; - ev.data.l[4] = window->extended_sync_request_counter ? 1 : 0; - - /* We don't need to trap errors here as we are already - * inside an error_trap_push()/pop() pair. - */ - XSendEvent (window->display->xdisplay, - window->xwindow, False, 0, (XEvent*) &ev); - - /* We give the window 1 sec to respond to _NET_WM_SYNC_REQUEST; - * if this time expires, we consider the window unresponsive - * and resize it unsynchonized. - */ - window->sync_request_timeout_id = g_timeout_add (1000, - sync_request_timeout, - window); - - meta_compositor_set_updates_frozen (window->display->compositor, window, - meta_window_updates_are_frozen (window)); + return G_SOURCE_CONTINUE; } -#endif /** - * meta_window_updates_are_frozen: + * meta_window_get_monitor: * @window: a #MetaWindow * - * Gets whether the compositor should be updating the window contents; - * window content updates may be frozen at client request by setting - * an odd value in the extended _NET_WM_SYNC_REQUEST_COUNTER counter r - * by the window manager during a resize operation while waiting for - * the client to redraw. + * Gets index of the monitor that this window is on. * - * Return value: %TRUE if updates are currently frozen + * Return Value: The index of the monitor in the screens monitor list, or -1 + * if the window has been recently unmanaged and does not have a monitor. */ -gboolean -meta_window_updates_are_frozen (MetaWindow *window) +int +meta_window_get_monitor (MetaWindow *window) { -#ifdef HAVE_XSYNC - if (window->extended_sync_request_counter && - window->sync_request_serial % 2 == 1) - return TRUE; - - if (window->sync_request_serial < window->sync_request_wait_serial) - return TRUE; -#endif + if (!window->monitor) + return -1; - return FALSE; + return window->monitor->number; } -static gboolean -maybe_move_attached_dialog (MetaWindow *window, - void *data) +MetaLogicalMonitor * +meta_window_get_main_logical_monitor (MetaWindow *window) { - if (meta_window_is_attached_dialog (window)) - /* It ignores x,y for such a dialog */ - meta_window_move (window, FALSE, 0, 0); - - return FALSE; + return window->monitor; } -/** - * meta_window_get_monitor: - * @window: a #MetaWindow - * - * Gets index of the monitor that this window is on. - * - * Return Value: The index of the monitor in the screens monitor list - */ -int -meta_window_get_monitor (MetaWindow *window) +static MetaLogicalMonitor * +find_monitor_by_winsys_id (MetaWindow *window, + uint64_t winsys_id) { - g_return_val_if_fail (META_IS_WINDOW (window), -1); + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + GList *logical_monitors, *l; - if (window->monitor == NULL) - return -1; + logical_monitors = + meta_monitor_manager_get_logical_monitors (monitor_manager); - return window->monitor->number; + for (l = logical_monitors; l; l = l->next) + { + MetaLogicalMonitor *logical_monitor = l->data; + + if (logical_monitor->winsys_id == winsys_id) + return logical_monitor; + } + + return NULL; } /* This is called when the monitor setup has changed. The window->monitor * reference is still "valid", but refer to the previous monitor setup */ -LOCAL_SYMBOL void +void meta_window_update_for_monitors_changed (MetaWindow *window) { - const MetaMonitorInfo *old, *new; - int i; + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + const MetaLogicalMonitor *old, *new; - if (window->override_redirect) + if (meta_window_has_fullscreen_monitors (window)) + meta_window_clear_fullscreen_monitors (window); + + if (window->override_redirect || window->type == META_WINDOW_DESKTOP) { - meta_window_update_monitor (window); - return; + meta_window_update_monitor (window, + META_WINDOW_UPDATE_MONITOR_FLAGS_FORCE); + goto out; } old = window->monitor; - /* Start on primary */ - new = &window->screen->monitor_infos[window->screen->primary_monitor_index]; + /* Try the preferred output first */ + new = find_monitor_by_winsys_id (window, window->preferred_output_winsys_id); - /* But, if we can find the old output on a new monitor, use that */ - for (i = 0; i < window->screen->n_monitor_infos; i++) - { - MetaMonitorInfo *info = &window->screen->monitor_infos[i]; + /* Otherwise, try to find the old output on a new monitor */ + if (old && !new) + new = find_monitor_by_winsys_id (window, old->winsys_id); - if (info->output == old->output) - { - new = info; - break; - } - } + /* Fall back to primary if everything else failed */ + if (!new) + new = meta_monitor_manager_get_primary_logical_monitor (monitor_manager); if (window->tile_mode != META_TILE_NONE) - window->tile_monitor_number = new->number; + { + if (new) + window->tile_monitor_number = new->number; + else + window->tile_monitor_number = -1; + } + + if (new && old) + { + /* This will eventually reach meta_window_update_monitor that + * will send leave/enter-monitor events. The old != new monitor + * check will always fail (due to the new logical_monitors set) so + * we will always send the events, even if the new and old monitor + * index is the same. That is right, since the enumeration of the + * monitors changed and the same index could be refereing + * to a different monitor. */ + meta_window_move_between_rects (window, + META_MOVE_RESIZE_FORCE_UPDATE_MONITOR, + &old->rect, + &new->rect); + } + else + { + meta_window_update_monitor (window, + META_WINDOW_UPDATE_MONITOR_FLAGS_FORCE); + } - /* This will eventually reach meta_window_update_monitor that - * will send leave/enter-monitor events. The old != new monitor - * check will always fail (due to the new monitor_infos set) so - * we will always send the events, even if the new and old monitor - * index is the same. That is right, since the enumeration of the - * monitors changed and the same index could be refereing - * to a different monitor. */ - meta_window_move_between_rects (window, - &old->rect, - &new->rect); +out: + g_assert (!window->monitor || + g_list_find (meta_monitor_manager_get_logical_monitors (monitor_manager), + window->monitor)); } -static void -meta_window_update_monitor (MetaWindow *window) +void +meta_window_update_monitor (MetaWindow *window, + MetaWindowUpdateMonitorFlags flags) { - const MetaMonitorInfo *old; + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; + const MetaLogicalMonitor *old; old = window->monitor; - window->monitor = meta_screen_get_monitor_for_window (window->screen, window); + META_WINDOW_GET_CLASS (window)->update_main_monitor (window, flags); if (old != window->monitor) { - meta_window_update_on_all_workspaces (window); + meta_window_on_all_workspaces_changed (window); - /* If workspaces only on primary and we moved back to primary, ensure that the - * window is now in that workspace. We do this because while the window is on a - * non-primary monitor it is always visible, so it would be very jarring if it - * disappeared when it crossed the monitor border. + /* If workspaces only on primary and we moved back to primary due to a user action, + * ensure that the window is now in that workspace. We do this because while + * the window is on a non-primary monitor it is always visible, so it would be + * very jarring if it disappeared when it crossed the monitor border. * The one time we want it to both change to the primary monitor and a non-active * workspace is when dropping the window on some other workspace thumbnail directly. * That should be handled by explicitly moving the window before changing the - * workspace - * Don't do this if old == NULL, because thats what happens when starting up, and - * we don't want to move all windows around from a previous WM instance. Nor do - * we want it when moving from one primary monitor to another (can happen during - * screen reconfiguration. + * workspace. */ if (meta_prefs_get_workspaces_only_on_primary () && + flags & META_WINDOW_UPDATE_MONITOR_FLAGS_USER_OP && meta_window_is_on_primary_monitor (window) && - old != NULL && !old->is_primary && - window->screen->active_workspace != window->workspace) - meta_window_change_workspace (window, window->screen->active_workspace); - - if (old) { - meta_screen_queue_check_fullscreen (window->screen); - g_signal_emit_by_name (window->screen, "window-left-monitor", old->number, window); - } - g_signal_emit_by_name (window->screen, "window-entered-monitor", window->monitor->number, window); + workspace_manager->active_workspace != window->workspace) + meta_window_change_workspace (window, workspace_manager->active_workspace); - g_signal_emit_by_name (window->screen, "window-monitor-changed", window, window->monitor->number); + meta_window_main_monitor_changed (window, old); /* If we're changing monitors, we need to update the has_maximize_func flag, * as the working area has changed. */ - recalc_window_features (window); + meta_window_recalc_features (window); } } -static void +void meta_window_move_resize_internal (MetaWindow *window, MetaMoveResizeFlags flags, - int gravity, - int root_x_nw, - int root_y_nw, - int w, - int h) -{ - /* meta_window_move_resize_internal gets called with very different - * meanings for root_x_nw and root_y_nw. w & h are always the area - * of the inner or client window (i.e. excluding the frame) and - * gravity is the relevant gravity associated with the request (note - * that gravity is ignored for move-only operations unless its - * e.g. a configure request). The location is different for - * different cases because of how this function gets called; note - * that in all cases what we want to find out is the upper left - * corner of the position of the inner window: + MetaGravity gravity, + MetaRectangle frame_rect) +{ + /* The rectangle here that's passed in *always* in "frame rect" + * coordinates. That means the position of the frame's visible bounds, + * with x and y being absolute (root window) coordinates. + * + * For an X11 framed window, the client window's server rectangle is + * inset from this rectangle by the frame's visible borders, and the + * frame window's server rectangle is outset by the invisible borders. * - * Case | Called from (flags; gravity) - * -----+----------------------------------------------- - * 1 | A resize only ConfigureRequest - * 1 | meta_window_resize - * 1 | meta_window_resize_with_gravity - * 2 | New window - * 2 | Session restore - * 2 | A not-resize-only ConfigureRequest/net_moveresize_window request - * 3 | meta_window_move - * 3 | meta_window_move_resize + * For an X11 unframed window, the rectangle here directly matches + * the server's rectangle, since the visible and invisible borders + * are both 0. * - * For each of the cases, root_x_nw and root_y_nw must be treated as follows: + * For an X11 CSD window, the client window's server rectangle is + * outset from this rectagle by the client-specified frame extents. * - * (1) They should be entirely ignored; instead the previous position - * and size of the window should be resized according to the given - * gravity in order to determine the new position of the window. - * (2) Needs to be fixed up by adjust_for_gravity() as these - * coordinates are relative to some corner or side of the outer - * window (except for the case of StaticGravity) and we want to - * know the location of the upper left corner of the inner window. - * (3) These values are already the desired positon of the NW corner - * of the inner window + * For a Wayland window, this rectangle can simply be sent directly + * to the client. */ - XWindowChanges values; - unsigned int mask; - gboolean need_configure_notify; - MetaFrameBorders borders; - gboolean need_move_client = FALSE; - gboolean need_move_frame = FALSE; - gboolean need_resize_client = FALSE; - gboolean need_resize_frame = FALSE; - int frame_size_dx; - int frame_size_dy; - int size_dx; - int size_dy; - gboolean frame_shape_changed = FALSE; - gboolean is_configure_request; - gboolean do_gravity_adjust; - gboolean is_user_action; + + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; gboolean did_placement; - gboolean configure_frame_first; - gboolean use_static_gravity; - /* used for the configure request, but may not be final - * destination due to StaticGravity etc. - */ - int client_move_x; - int client_move_y; - MetaRectangle new_rect; - MetaRectangle old_rect; + MetaRectangle unconstrained_rect; + MetaRectangle constrained_rect; + MetaRectangle temporary_rect; + int rel_x = 0; + int rel_y = 0; + MetaMoveResizeResultFlags result = 0; + gboolean moved_or_resized = FALSE; + MetaWindowUpdateMonitorFlags update_monitor_flags; - if (window->type != META_WINDOW_TOOLTIP) - { - g_return_if_fail (!window->override_redirect); - } + g_return_if_fail (!window->override_redirect); - is_configure_request = (flags & META_IS_CONFIGURE_REQUEST) != 0; - do_gravity_adjust = (flags & META_DO_GRAVITY_ADJUST) != 0; - is_user_action = (flags & META_IS_USER_ACTION) != 0; + /* The action has to be a move, a resize or the wayland client + * acking our choice of size. + */ + g_assert (flags & (META_MOVE_RESIZE_MOVE_ACTION | + META_MOVE_RESIZE_RESIZE_ACTION | + META_MOVE_RESIZE_WAYLAND_FINISH_MOVE_RESIZE)); - /* The action has to be a move or a resize or both... */ - g_assert (flags & (META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION)); + did_placement = !window->placed && window->calc_placement; /* We don't need it in the idle queue anymore. */ meta_window_unqueue (window, META_QUEUE_MOVE_RESIZE); - meta_window_get_client_root_coords (window, &old_rect); - - meta_topic (META_DEBUG_GEOMETRY, - "Move/resize %s to %d,%d %dx%d%s%s from %d,%d %dx%d\n", - window->desc, root_x_nw, root_y_nw, w, h, - is_configure_request ? " (configure request)" : "", - is_user_action ? " (user move/resize)" : "", - old_rect.x, old_rect.y, old_rect.width, old_rect.height); - - meta_frame_calc_borders (window->frame, - &borders); - - new_rect.x = root_x_nw; - new_rect.y = root_y_nw; - new_rect.width = w; - new_rect.height = h; - - /* If this is a resize only, the position should be ignored and - * instead obtained by resizing the old rectangle according to the - * relevant gravity. - */ - if ((flags & (META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION)) == - META_IS_RESIZE_ACTION) + if ((flags & META_MOVE_RESIZE_RESIZE_ACTION) && (flags & META_MOVE_RESIZE_MOVE_ACTION)) + { + /* We're both moving and resizing. Just use the passed in rect. */ + unconstrained_rect = frame_rect; + } + else if ((flags & META_MOVE_RESIZE_RESIZE_ACTION)) { - meta_rectangle_resize_with_gravity (&old_rect, - &new_rect, + /* If this is only a resize, then ignore the position given in + * the parameters and instead calculate the new position from + * resizing the old rectangle with the given gravity. */ + meta_rectangle_resize_with_gravity (&window->rect, + &unconstrained_rect, gravity, - new_rect.width, - new_rect.height); - - meta_topic (META_DEBUG_GEOMETRY, - "Compensated for gravity in resize action; new pos %d,%d\n", - new_rect.x, new_rect.y); + frame_rect.width, + frame_rect.height); } - else if (is_configure_request || do_gravity_adjust) + else if ((flags & META_MOVE_RESIZE_MOVE_ACTION)) { - adjust_for_gravity (window, - window->frame ? &borders : NULL, - /* configure request coords assume - * the border width existed - */ - is_configure_request, - gravity, - &new_rect); - - meta_topic (META_DEBUG_GEOMETRY, - "Compensated for configure_request/do_gravity_adjust needing " - "weird positioning; new pos %d,%d\n", - new_rect.x, new_rect.y); + /* If this is only a move, then ignore the passed in size and + * just use the existing size of the window. */ + unconstrained_rect.x = frame_rect.x; + unconstrained_rect.y = frame_rect.y; + unconstrained_rect.width = window->rect.width; + unconstrained_rect.height = window->rect.height; } - - did_placement = !window->placed && window->calc_placement; - - meta_window_constrain (window, - window->frame ? &borders : NULL, - flags, - gravity, - &old_rect, - &new_rect); - - w = new_rect.width; - h = new_rect.height; - root_x_nw = new_rect.x; - root_y_nw = new_rect.y; - - size_dx = w - window->rect.width; - size_dy = h - window->rect.height; - - if (size_dx != 0 || size_dy != 0) - need_resize_client = TRUE; - - window->rect.width = w; - window->rect.height = h; - - if (window->frame) + else if ((flags & META_MOVE_RESIZE_WAYLAND_FINISH_MOVE_RESIZE)) { - int new_w, new_h; - - new_w = window->rect.width + borders.total.left + borders.total.right; - - if (window->shaded) - new_h = borders.total.top; - else - new_h = window->rect.height + borders.total.top + borders.total.bottom; - - if (new_w != window->frame->rect.width || - new_h != window->frame->rect.height) - { - need_resize_frame = TRUE; - window->frame->rect.width = new_w; - window->frame->rect.height = new_h; - } - - meta_topic (META_DEBUG_GEOMETRY, - "Calculated frame size %dx%d\n", - window->frame->rect.width, - window->frame->rect.height); + /* This is a Wayland buffer acking our size. The new rect is + * just the existing one we have. Ignore the passed-in rect + * completely. */ + unconstrained_rect = window->rect; } + else + g_assert_not_reached (); - - /* For nice effect, when growing the window we want to move/resize - * the frame first, when shrinking the window we want to move/resize - * the client first. If we grow one way and shrink the other, - * see which way we're moving "more" - * - * Mail from Owen subject "Suggestion: Gravity and resizing from the left" - * http://mail.gnome.org/archives/wm-spec-list/1999-November/msg00088.html - * - * An annoying fact you need to know in this code is that StaticGravity - * does nothing if you _only_ resize or _only_ move the frame; - * it must move _and_ resize, otherwise you get NorthWestGravity - * behavior. The move and resize must actually occur, it is not - * enough to set CWX | CWWidth but pass in the current size/pos. - */ - - if (window->frame) + constrained_rect = unconstrained_rect; + temporary_rect = window->rect; + if (flags & (META_MOVE_RESIZE_MOVE_ACTION | META_MOVE_RESIZE_RESIZE_ACTION) && + !(flags & META_MOVE_RESIZE_WAYLAND_FINISH_MOVE_RESIZE) && + window->monitor) { - int new_x, new_y; - int frame_pos_dx, frame_pos_dy; - - /* Compute new frame coords */ - new_x = root_x_nw - borders.total.left; - new_y = root_y_nw - borders.total.top; - - frame_pos_dx = new_x - window->frame->rect.x; - frame_pos_dy = new_y - window->frame->rect.y; - - need_move_frame = (frame_pos_dx != 0 || frame_pos_dy != 0); - - window->frame->rect.x = new_x; - window->frame->rect.y = new_y; - - /* If frame will both move and resize, then StaticGravity - * on the child window will kick in and implicitly move - * the child with respect to the frame. The implicit - * move will keep the child in the same place with - * respect to the root window. If frame only moves - * or only resizes, then the child will just move along - * with the frame. - */ - - /* window->rect.x, window->rect.y are relative to frame, - * remember they are the server coords - */ - - new_x = borders.total.left; - new_y = borders.total.top; - - if (need_resize_frame && need_move_frame && - static_gravity_works (window->display)) - { - /* static gravity kicks in because frame - * is both moved and resized - */ - /* when we move the frame by frame_pos_dx, frame_pos_dy the - * client will implicitly move relative to frame by the - * inverse delta. - * - * When moving client then frame, we move the client by the - * frame delta, to be canceled out by the implicit move by - * the inverse frame delta, resulting in a client at new_x, - * new_y. - * - * When moving frame then client, we move the client - * by the same delta as the frame, because the client - * was "left behind" by the frame - resulting in a client - * at new_x, new_y. - * - * In both cases we need to move the client window - * in all cases where we had to move the frame window. - */ - - client_move_x = new_x + frame_pos_dx; - client_move_y = new_y + frame_pos_dy; - - if (need_move_frame) - need_move_client = TRUE; - - use_static_gravity = TRUE; - } - else - { - client_move_x = new_x; - client_move_y = new_y; - - if (client_move_x != window->rect.x || - client_move_y != window->rect.y) - need_move_client = TRUE; - - use_static_gravity = FALSE; - } + MetaRectangle old_rect; + meta_window_get_frame_rect (window, &old_rect); - /* This is the final target position, but not necessarily what - * we pass to XConfigureWindow, due to StaticGravity implicit - * movement. - */ - window->rect.x = new_x; - window->rect.y = new_y; + meta_window_constrain (window, + flags, + gravity, + &old_rect, + &constrained_rect, + &temporary_rect, + &rel_x, + &rel_y); } - else + else if (window->placement.rule) { - if (root_x_nw != window->rect.x || - root_y_nw != window->rect.y) - need_move_client = TRUE; + rel_x = window->placement.pending.rel_x; + rel_y = window->placement.pending.rel_y; + } - window->rect.x = root_x_nw; - window->rect.y = root_y_nw; + /* If we did placement, then we need to save the position that the window + * was placed at to make sure that meta_window_move_resize_now places the + * window correctly. + */ + if (did_placement) + { + unconstrained_rect.x = constrained_rect.x; + unconstrained_rect.y = constrained_rect.y; + } - client_move_x = window->rect.x; - client_move_y = window->rect.y; + /* Do the protocol-specific move/resize logic */ + META_WINDOW_GET_CLASS (window)->move_resize_internal (window, + gravity, + unconstrained_rect, + constrained_rect, + temporary_rect, + rel_x, + rel_y, + flags, &result); - use_static_gravity = FALSE; + if (result & META_MOVE_RESIZE_RESULT_MOVED) + { + moved_or_resized = TRUE; + g_signal_emit (window, window_signals[POSITION_CHANGED], 0); } - /* If frame extents have changed, fill in other frame fields and - change frame's extents property. */ - if (window->frame && - (window->frame->child_x != borders.total.left || - window->frame->child_y != borders.total.top || - window->frame->right_width != borders.total.right || - window->frame->bottom_height != borders.total.bottom)) + if (result & META_MOVE_RESIZE_RESULT_RESIZED) { - window->frame->child_x = borders.total.left; - window->frame->child_y = borders.total.top; - window->frame->right_width = borders.total.right; - window->frame->bottom_height = borders.total.bottom; + moved_or_resized = TRUE; + g_signal_emit (window, window_signals[SIZE_CHANGED], 0); + } - update_net_frame_extents (window); + if (moved_or_resized || did_placement) + window->unconstrained_rect = unconstrained_rect; + + if ((moved_or_resized || + did_placement || + (result & META_MOVE_RESIZE_RESULT_STATE_CHANGED) != 0) && + window->known_to_compositor) + { + meta_compositor_sync_window_geometry (window->display->compositor, + window, + did_placement); } - /* See ICCCM 4.1.5 for when to send ConfigureNotify */ + update_monitor_flags = META_WINDOW_UPDATE_MONITOR_FLAGS_NONE; + if (flags & META_MOVE_RESIZE_USER_ACTION) + update_monitor_flags |= META_WINDOW_UPDATE_MONITOR_FLAGS_USER_OP; + if (flags & META_MOVE_RESIZE_FORCE_UPDATE_MONITOR) + update_monitor_flags |= META_WINDOW_UPDATE_MONITOR_FLAGS_FORCE; - need_configure_notify = FALSE; + if (window->monitor) + { + uint64_t old_output_winsys_id; - /* If this is a configure request and we change nothing, then we - * must send configure notify. - */ - if (is_configure_request && - !(need_move_client || need_move_frame || - need_resize_client || need_resize_frame || - window->border_width != 0)) - need_configure_notify = TRUE; - - /* We must send configure notify if we move but don't resize, since - * the client window may not get a real event - */ - if ((need_move_client || need_move_frame) && - !(need_resize_client || need_resize_frame) && - window->type != META_WINDOW_TOOLTIP) - need_configure_notify = TRUE; - - /* MapRequest events with a PPosition or UPosition hint with a frame - * are moved by muffin without resizing; send a configure notify - * in such cases. See #322840. (Note that window->constructing is - * only true iff this call is due to a MapRequest, and when - * PPosition/UPosition hints aren't set, muffin seems to send a - * ConfigureNotify anyway due to the above code.) - */ - if (window->constructing && window->frame && - ((window->size_hints.flags & PPosition) || - (window->size_hints.flags & USPosition))) - need_configure_notify = TRUE; + old_output_winsys_id = window->monitor->winsys_id; - /* The rest of this function syncs our new size/pos with X as - * efficiently as possible - */ + meta_window_update_monitor (window, update_monitor_flags); - /* Normally, we configure the frame first depending on whether - * we grow the frame more than we shrink. The idea is to avoid - * messing up the window contents by having a temporary situation - * where the frame is smaller than the window. However, if we're - * cooperating with the client to create an atomic frame upate, - * and the window is redirected, then we should always update - * the frame first, since updating the frame will force a new - * backing pixmap to be allocated, and the old backing pixmap - * will be left undisturbed for us to paint to the screen until - * the client finishes redrawing. - */ - if (window->extended_sync_request_counter) - { - configure_frame_first = TRUE; + if (old_output_winsys_id != window->monitor->winsys_id && + flags & META_MOVE_RESIZE_MOVE_ACTION && flags & META_MOVE_RESIZE_USER_ACTION) + window->preferred_output_winsys_id = window->monitor->winsys_id; } else { - size_dx = w - window->rect.width; - size_dy = h - window->rect.height; + meta_window_update_monitor (window, update_monitor_flags); + } - configure_frame_first = size_dx + size_dy >= 0; + if ((result & META_MOVE_RESIZE_RESULT_FRAME_SHAPE_CHANGED) && window->frame_bounds) + { + cairo_region_destroy (window->frame_bounds); + window->frame_bounds = NULL; } - if (use_static_gravity) - meta_window_set_gravity (window, StaticGravity); + meta_window_foreach_transient (window, maybe_move_attached_window, NULL); - if (configure_frame_first && window->frame) - frame_shape_changed = meta_frame_sync_to_window (window->frame, - gravity, - need_move_frame, need_resize_frame); + meta_stack_update_window_tile_matches (window->display->stack, + workspace_manager->active_workspace); +} - values.border_width = 0; - values.x = client_move_x; - values.y = client_move_y; - values.width = window->rect.width; - values.height = window->rect.height; - - mask = 0; - if (is_configure_request && window->border_width != 0) - mask |= CWBorderWidth; /* must force to 0 */ - if (need_move_client) - mask |= (CWX | CWY); - if (need_resize_client) - mask |= (CWWidth | CWHeight); - - if (mask != 0) - { - meta_error_trap_push (window->display); - -#ifdef HAVE_XSYNC - if (window == window->display->grab_window && - meta_grab_op_is_resizing (window->display->grab_op) && - !window->disable_sync && - window->sync_request_counter != None && - window->sync_request_alarm != None && - window->sync_request_timeout_id == 0) - { - send_sync_request (window); - } -#endif - - XConfigureWindow (window->display->xdisplay, - window->xwindow, - mask, - &values); - - meta_error_trap_pop (window->display); - } - - if (!configure_frame_first && window->frame) - frame_shape_changed = meta_frame_sync_to_window (window->frame, - gravity, - need_move_frame, need_resize_frame); - - /* Put gravity back to be nice to lesser window managers */ - if (use_static_gravity) - meta_window_set_gravity (window, NorthWestGravity); - - if (need_configure_notify) - send_configure_notify (window); - - if (!window->placed && window->force_save_user_rect && !window->fullscreen) - force_save_user_window_placement (window); - else if (is_user_action) - save_user_window_placement (window); - - if (need_move_frame || need_move_client) - g_signal_emit (window, window_signals[POSITION_CHANGED], 0); - - if (need_resize_client) - g_signal_emit (window, window_signals[SIZE_CHANGED], 0); - - if (need_move_frame || need_resize_frame || - need_move_client || need_resize_client || - did_placement) - { - int newx, newy; - meta_window_get_position (window, &newx, &newy); - meta_topic (META_DEBUG_GEOMETRY, - "New size/position %d,%d %dx%d (user %d,%d %dx%d)\n", - newx, newy, window->rect.width, window->rect.height, - window->user_rect.x, window->user_rect.y, - window->user_rect.width, window->user_rect.height); - meta_compositor_sync_window_geometry (window->display->compositor, - window, - did_placement); - } - else - { - meta_topic (META_DEBUG_GEOMETRY, "Size/position not modified\n"); - } - - meta_window_refresh_resize_popup (window); - - meta_window_update_monitor (window); - - /* Invariants leaving this function are: - * a) window->rect and frame->rect reflect the actual - * server-side size/pos of window->xwindow and frame->xwindow - * b) all constraints are obeyed by window->rect and frame->rect - */ - - if (frame_shape_changed && window->frame_bounds) - { - cairo_region_destroy (window->frame_bounds); - window->frame_bounds = NULL; - } - - meta_window_foreach_transient (window, maybe_move_attached_dialog, NULL); - - meta_stack_update_window_tile_matches (window->screen->stack, - window->screen->active_workspace); -} - -/** - * meta_window_resize: - * @window: a #MetaWindow - * @user_op: bool to indicate whether or not this is a user operation - * @w: desired width - * @h: desired height - * - * Resize the window to the desired size. - */ -void -meta_window_resize (MetaWindow *window, - gboolean user_op, - int w, - int h) -{ - int x, y; - MetaMoveResizeFlags flags; - - g_return_if_fail (!window->override_redirect); - - meta_window_get_position (window, &x, &y); - - flags = (user_op ? META_IS_USER_ACTION : 0) | META_IS_RESIZE_ACTION; - meta_window_move_resize_internal (window, - flags, - NorthWestGravity, - x, y, w, h); -} - -/** - * meta_window_move: - * @window: a #MetaWindow - * @user_op: bool to indicate whether or not this is a user operation - * @root_x_nw: desired x pos - * @root_y_nw: desired y pos - * - * Moves the window to the desired location on window's assigned workspace. - * NOTE: does NOT place according to the origin of the enclosing - * frame/window-decoration, but according to the origin of the window, - * itself. - */ -void -meta_window_move (MetaWindow *window, - gboolean user_op, - int root_x_nw, - int root_y_nw) -{ - MetaMoveResizeFlags flags; - - if (window->type != META_WINDOW_TOOLTIP) - { - g_return_if_fail (!window->override_redirect); - } - - flags = (user_op ? META_IS_USER_ACTION : 0) | META_IS_MOVE_ACTION; - - meta_window_move_resize_internal (window, - flags, - NorthWestGravity, - root_x_nw, root_y_nw, - window->rect.width, - window->rect.height); -} /** * meta_window_move_frame: * @window: a #MetaWindow @@ -5543,55 +4205,52 @@ meta_window_move (MetaWindow *window, * Otherwise, acts identically to meta_window_move(). */ void -meta_window_move_frame (MetaWindow *window, - gboolean user_op, - int root_x_nw, - int root_y_nw) +meta_window_move_frame (MetaWindow *window, + gboolean user_op, + int root_x_nw, + int root_y_nw) { - int x = root_x_nw; - int y = root_y_nw; - - if (window->frame) - { - MetaFrameBorders borders; - - meta_frame_calc_borders (window->frame, &borders); + MetaMoveResizeFlags flags; + MetaRectangle rect = { root_x_nw, root_y_nw, 0, 0 }; - /* root_x_nw and root_y_nw correspond to where the top of - * the visible frame should be. Offset by the distance between - * the origin of the window and the origin of the enclosing - * window decorations. - */ - x += window->frame->child_x - borders.invisible.left; - y += window->frame->child_y - borders.invisible.top; - } + g_return_if_fail (!window->override_redirect); - meta_window_move (window, user_op, x, y); + flags = (user_op ? META_MOVE_RESIZE_USER_ACTION : 0) | META_MOVE_RESIZE_MOVE_ACTION; + meta_window_move_resize_internal (window, flags, META_GRAVITY_NORTH_WEST, rect); } static void meta_window_move_between_rects (MetaWindow *window, + MetaMoveResizeFlags move_resize_flags, const MetaRectangle *old_area, const MetaRectangle *new_area) { int rel_x, rel_y; double scale_x, scale_y; - rel_x = window->user_rect.x - old_area->x; - rel_y = window->user_rect.y - old_area->y; - scale_x = (double)new_area->width / old_area->width; - scale_y = (double)new_area->height / old_area->height; + if (old_area) + { + rel_x = window->unconstrained_rect.x - old_area->x; + rel_y = window->unconstrained_rect.y - old_area->y; + scale_x = (double)new_area->width / old_area->width; + scale_y = (double)new_area->height / old_area->height; + } + else + { + rel_x = rel_y = scale_x = scale_y = 0; + } - window->user_rect.x = new_area->x + rel_x * scale_x; - window->user_rect.y = new_area->y + rel_y * scale_y; - window->saved_rect.x = window->user_rect.x; - window->saved_rect.y = window->user_rect.y; + window->unconstrained_rect.x = new_area->x + rel_x * scale_x; + window->unconstrained_rect.y = new_area->y + rel_y * scale_y; + window->saved_rect.x = window->unconstrained_rect.x; + window->saved_rect.y = window->unconstrained_rect.y; - meta_window_move_resize (window, FALSE, - window->user_rect.x, - window->user_rect.y, - window->user_rect.width, - window->user_rect.height); + meta_window_move_resize_internal (window, + move_resize_flags | + META_MOVE_RESIZE_MOVE_ACTION | + META_MOVE_RESIZE_RESIZE_ACTION, + META_GRAVITY_NORTH_WEST, + window->unconstrained_rect); } /** @@ -5614,18 +4273,14 @@ meta_window_move_resize_frame (MetaWindow *window, int w, int h) { - MetaFrameBorders borders; + MetaMoveResizeFlags flags; + MetaRectangle rect = { root_x_nw, root_y_nw, w, h }; - meta_frame_calc_borders (window->frame, &borders); - /* offset by the distance between the origin of the window - * and the origin of the enclosing window decorations ( + border) - */ - root_x_nw += borders.visible.left; - root_y_nw += borders.visible.top; - w -= borders.visible.left + borders.visible.right; - h -= borders.visible.top + borders.visible.bottom; + g_return_if_fail (!window->override_redirect); - meta_window_move_resize (window, user_op, root_x_nw, root_y_nw, w, h); + flags = (user_op ? META_MOVE_RESIZE_USER_ACTION : 0) | META_MOVE_RESIZE_MOVE_ACTION | META_MOVE_RESIZE_RESIZE_ACTION; + + meta_window_move_resize_internal (window, flags, META_GRAVITY_NORTH_WEST, rect); } /** @@ -5642,8 +4297,8 @@ meta_window_move_to_monitor (MetaWindow *window, { MetaRectangle old_area, new_area; - if (monitor == window->monitor->number) - return; + if (window->tile_mode != META_TILE_NONE) + window->tile_monitor_number = monitor; meta_window_get_work_area_for_monitor (window, window->monitor->number, @@ -5652,64 +4307,89 @@ meta_window_move_to_monitor (MetaWindow *window, monitor, &new_area); - if (window->tile_mode != META_TILE_NONE) - window->tile_monitor_number = monitor; + if (window->unconstrained_rect.width == 0 || + window->unconstrained_rect.height == 0 || + !meta_rectangle_overlap (&window->unconstrained_rect, &old_area)) + { + meta_window_move_between_rects (window, 0, NULL, &new_area); + } + else + { + if (monitor == window->monitor->number) + return; + + meta_window_move_between_rects (window, 0, &old_area, &new_area); + } + + window->preferred_output_winsys_id = window->monitor->winsys_id; - meta_window_move_between_rects (window, &old_area, &new_area); + if (window->fullscreen || window->override_redirect) + meta_display_queue_check_fullscreen (window->display); } -void -meta_window_move_resize (MetaWindow *window, - gboolean user_op, - int root_x_nw, - int root_y_nw, - int w, - int h) +static void +adjust_size_for_tile_match (MetaWindow *window, + int *new_w, + int *new_h) { - MetaMoveResizeFlags flags; + MetaRectangle work_area, rect; + MetaWindow *tile_match = window->tile_match; - g_return_if_fail (!window->override_redirect); + if (!META_WINDOW_TILED_SIDE_BY_SIDE (window) || !tile_match) + return; - flags = (user_op ? META_IS_USER_ACTION : 0) | - META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION; - meta_window_move_resize_internal (window, - flags, - NorthWestGravity, - root_x_nw, root_y_nw, - w, h); + meta_window_get_work_area_for_monitor (window, window->tile_monitor_number, &work_area); + + /* Make sure the resize does not break minimum sizes */ + rect = work_area; + rect.width = *new_w; + + meta_window_frame_rect_to_client_rect (window, &rect, &rect); + *new_w += MAX(0, window->size_hints.min_width - rect.width); + + /* Make sure we're not resizing the tile match below its min width */ + rect = work_area; + rect.width = work_area.width - *new_w; + + meta_window_frame_rect_to_client_rect (tile_match, &rect, &rect); + *new_w -= MAX(0, tile_match->size_hints.min_width - rect.width); } -LOCAL_SYMBOL void -meta_window_resize_with_gravity (MetaWindow *window, - gboolean user_op, - int w, - int h, - int gravity) +void +meta_window_resize_frame_with_gravity (MetaWindow *window, + gboolean user_op, + int w, + int h, + MetaGravity gravity) { - int x, y; MetaMoveResizeFlags flags; + MetaRectangle rect; - meta_window_get_position (window, &x, &y); + rect.width = w; + rect.height = h; - flags = (user_op ? META_IS_USER_ACTION : 0) | META_IS_RESIZE_ACTION; - meta_window_move_resize_internal (window, - flags, - gravity, - x, y, w, h); + if (user_op) + { + /* When resizing in-tandem with a tile match, we need to respect + * its minimum width + */ + if (window->display->grab_window == window) + adjust_size_for_tile_match (window, &w, &h); + meta_window_update_tile_fraction (window, w, h); + } + + flags = (user_op ? META_MOVE_RESIZE_USER_ACTION : 0) | META_MOVE_RESIZE_RESIZE_ACTION; + meta_window_move_resize_internal (window, flags, gravity, rect); } static void meta_window_move_resize_now (MetaWindow *window) { - /* If constraints have changed then we want to snap back to wherever - * the user had the window. We use user_rect for this reason. See - * also bug 426519 comment 3. - */ - meta_window_move_resize (window, FALSE, - window->user_rect.x, - window->user_rect.y, - window->user_rect.width, - window->user_rect.height); + meta_window_move_resize_frame (window, FALSE, + window->unconstrained_rect.x, + window->unconstrained_rect.y, + window->unconstrained_rect.width, + window->unconstrained_rect.height); } static gboolean @@ -5752,72 +4432,9 @@ idle_move_resize (gpointer data) return FALSE; } -/** - * meta_window_configure_notify: (skip) - * @window: a #MetaWindow - * @event: a #XConfigureEvent - * - * This is used to notify us of an unrequested configuration - * (only applicable to override redirect windows) - */ void -meta_window_configure_notify (MetaWindow *window, - XConfigureEvent *event) -{ - g_assert (window->override_redirect); - g_assert (window->frame == NULL); - - window->rect.x = event->x; - window->rect.y = event->y; - window->rect.width = event->width; - window->rect.height = event->height; - meta_window_update_monitor (window); - - /* Whether an override-redirect window is considered fullscreen depends - * on its geometry. - */ - if (window->override_redirect) - meta_screen_queue_check_fullscreen (window->screen); - - if (!event->override_redirect && !event->send_event) - meta_warning ("Unhandled change of windows override redirect status\n"); - - meta_compositor_sync_window_geometry (window->display->compositor, window, FALSE); -} - -LOCAL_SYMBOL void -meta_window_get_position (MetaWindow *window, - int *x, - int *y) -{ - if (window->frame) - { - if (x) - *x = window->frame->rect.x + window->frame->child_x; - if (y) - *y = window->frame->rect.y + window->frame->child_y; - } - else - { - if (x) - *x = window->rect.x; - if (y) - *y = window->rect.y; - } -} - -LOCAL_SYMBOL void -meta_window_get_client_root_coords (MetaWindow *window, - MetaRectangle *rect) -{ - meta_window_get_position (window, &rect->x, &rect->y); - rect->width = window->rect.width; - rect->height = window->rect.height; -} - -LOCAL_SYMBOL void meta_window_get_gravity_position (MetaWindow *window, - int gravity, + MetaGravity gravity, int *root_x, int *root_y) { @@ -5828,7 +4445,7 @@ meta_window_get_gravity_position (MetaWindow *window, w = window->rect.width; h = window->rect.height; - if (gravity == StaticGravity) + if (gravity == META_GRAVITY_STATIC) { frame_extents = window->rect; if (window->frame) @@ -5850,18 +4467,18 @@ meta_window_get_gravity_position (MetaWindow *window, switch (gravity) { - case NorthGravity: - case CenterGravity: - case SouthGravity: + case META_GRAVITY_NORTH: + case META_GRAVITY_CENTER: + case META_GRAVITY_SOUTH: /* Find center of frame. */ x += frame_extents.width / 2; /* Center client window on that point. */ x -= w / 2; break; - case SouthEastGravity: - case EastGravity: - case NorthEastGravity: + case META_GRAVITY_SOUTH_EAST: + case META_GRAVITY_EAST: + case META_GRAVITY_NORTH_EAST: /* Find right edge of frame */ x += frame_extents.width; /* Align left edge of client at that point. */ @@ -5873,17 +4490,17 @@ meta_window_get_gravity_position (MetaWindow *window, switch (gravity) { - case WestGravity: - case CenterGravity: - case EastGravity: + case META_GRAVITY_WEST: + case META_GRAVITY_CENTER: + case META_GRAVITY_EAST: /* Find center of frame. */ y += frame_extents.height / 2; /* Center client window there. */ y -= h / 2; break; - case SouthWestGravity: - case SouthGravity: - case SouthEastGravity: + case META_GRAVITY_SOUTH_WEST: + case META_GRAVITY_SOUTH: + case META_GRAVITY_SOUTH_EAST: /* Find south edge of frame */ y += frame_extents.height; /* Place bottom edge of client there */ @@ -5899,12 +4516,12 @@ meta_window_get_gravity_position (MetaWindow *window, *root_y = y; } -LOCAL_SYMBOL void -meta_window_get_geometry (MetaWindow *window, - int *x, - int *y, - int *width, - int *height) +void +meta_window_get_session_geometry (MetaWindow *window, + int *x, + int *y, + int *width, + int *height) { meta_window_get_gravity_position (window, window->size_hints.win_gravity, @@ -5917,136 +4534,160 @@ meta_window_get_geometry (MetaWindow *window, } /** - * meta_window_get_input_rect: + * meta_window_get_buffer_rect: * @window: a #MetaWindow * @rect: (out): pointer to an allocated #MetaRectangle * - * Gets the rectangle that bounds @window that is responsive to mouse events. - * This includes decorations - the visible portion of its border - and (if - * present) any invisible area that we make make responsive to mouse clicks in - * order to allow convenient border dragging. + * Gets the rectangle that the pixmap or buffer of @window occupies. + * + * For X11 windows, this is the server-side geometry of the toplevel + * window. + * + * For Wayland windows, this is the bounding rectangle of the attached + * buffer. */ void -meta_window_get_input_rect (const MetaWindow *window, - MetaRectangle *rect) +meta_window_get_buffer_rect (const MetaWindow *window, + MetaRectangle *rect) +{ + *rect = window->buffer_rect; +} + +/** + * meta_window_client_rect_to_frame_rect: + * @window: a #MetaWindow + * @client_rect: client rectangle in root coordinates + * @frame_rect: (out): location to store the computed corresponding frame bounds. + * + * Converts a desired bounds of the client window into the corresponding bounds + * of the window frame (excluding invisible borders and client side shadows.) + */ +void +meta_window_client_rect_to_frame_rect (MetaWindow *window, + MetaRectangle *client_rect, + MetaRectangle *frame_rect) { + if (!frame_rect) + return; + + *frame_rect = *client_rect; + + /* The support for G_MAXINT here to mean infinity is a convenience for + * constraints.c:get_size_limits() and not something that we provide + * in other locations or document. + */ if (window->frame) - *rect = window->frame->rect; + { + MetaFrameBorders borders; + meta_frame_calc_borders (window->frame, &borders); + + frame_rect->x -= borders.visible.left; + frame_rect->y -= borders.visible.top; + if (frame_rect->width != G_MAXINT) + frame_rect->width += borders.visible.left + borders.visible.right; + if (frame_rect->height != G_MAXINT) + frame_rect->height += borders.visible.top + borders.visible.bottom; + } else - *rect = window->rect; + { + const GtkBorder *extents = &window->custom_frame_extents; + frame_rect->x += extents->left; + frame_rect->y += extents->top; + if (frame_rect->width != G_MAXINT) + frame_rect->width -= extents->left + extents->right; + if (frame_rect->height != G_MAXINT) + frame_rect->height -= extents->top + extents->bottom; + } } /** - * meta_window_get_outer_rect: + * meta_window_frame_rect_to_client_rect: * @window: a #MetaWindow - * @rect: (out): pointer to an allocated #MetaRectangle + * @frame_rect: desired frame bounds for the window + * @client_rect: (out): location to store the computed corresponding client rectangle. * - * Gets the rectangle that bounds @window that is responsive to mouse events. - * This includes only what is visible; it doesn't include any extra reactive - * area we add to the edges of windows. + * Converts a desired frame bounds for a window into the bounds of the client + * window. */ void -meta_window_get_outer_rect (const MetaWindow *window, - MetaRectangle *rect) +meta_window_frame_rect_to_client_rect (MetaWindow *window, + MetaRectangle *frame_rect, + MetaRectangle *client_rect) { + if (!client_rect) + return; + + *client_rect = *frame_rect; + if (window->frame) { MetaFrameBorders borders; - *rect = window->frame->rect; meta_frame_calc_borders (window->frame, &borders); - rect->x += borders.invisible.left; - rect->y += borders.invisible.top; - rect->width -= borders.invisible.left + borders.invisible.right; - rect->height -= borders.invisible.top + borders.invisible.bottom; + client_rect->x += borders.visible.left; + client_rect->y += borders.visible.top; + client_rect->width -= borders.visible.left + borders.visible.right; + client_rect->height -= borders.visible.top + borders.visible.bottom; } else { - *rect = window->rect; - - if (window->has_custom_frame_extents) - { - const GtkBorder *extents = &window->custom_frame_extents; - rect->x += extents->left; - rect->y += extents->top; - rect->width -= extents->left + extents->right; - rect->height -= extents->top + extents->bottom; - } + const GtkBorder *extents = &window->custom_frame_extents; + client_rect->x -= extents->left; + client_rect->y -= extents->top; + client_rect->width += extents->left + extents->right; + client_rect->height += extents->top + extents->bottom; } } +/** + * meta_window_get_frame_rect: + * @window: a #MetaWindow + * @rect: (out): pointer to an allocated #MetaRectangle + * + * Gets the rectangle that bounds @window that is what the user thinks of + * as the edge of the window. This doesn't include any extra reactive + * area that we or the client adds to the window, or any area that the + * client adds to draw a client-side shadow. + */ +void +meta_window_get_frame_rect (const MetaWindow *window, + MetaRectangle *rect) +{ + *rect = window->rect; +} + /** * meta_window_get_client_area_rect: * @window: a #MetaWindow * @rect: (out): pointer to a cairo rectangle * * Gets the rectangle for the boundaries of the client area, relative - * to the frame. If the window is shaded, the height of the rectangle - * is 0. + * to the buffer rect. If the window is shaded, the height of the + * rectangle is 0. */ void meta_window_get_client_area_rect (const MetaWindow *window, cairo_rectangle_int_t *rect) { - if (window->frame) - { - rect->x = window->frame->child_x; - rect->y = window->frame->child_y; - } - else - { - rect->x = 0; - rect->y = 0; - } + MetaFrameBorders borders; + + meta_frame_calc_borders (window->frame, &borders); + + rect->x = borders.total.left; + rect->y = borders.total.top; - rect->width = window->rect.width; + rect->width = window->buffer_rect.width - borders.total.left - borders.total.right; if (window->shaded) rect->height = 0; else - rect->height = window->rect.height; -} - -MetaSide -meta_window_get_tile_side (MetaWindow *window) -{ - MetaSide side; - switch (window->tile_mode) { - case META_TILE_LEFT: - side = META_SIDE_LEFT; - break; - case META_TILE_ULC: - side = (META_SIDE_LEFT | META_SIDE_TOP); - break; - case META_TILE_LLC: - side = (META_SIDE_LEFT | META_SIDE_BOTTOM); - break; - case META_TILE_RIGHT: - side = META_SIDE_RIGHT; - break; - case META_TILE_URC: - side = (META_SIDE_RIGHT | META_SIDE_TOP); - break; - case META_TILE_LRC: - side = (META_SIDE_RIGHT | META_SIDE_BOTTOM); - break; - case META_TILE_TOP: - side = META_SIDE_TOP; - break; - case META_TILE_BOTTOM: - side = META_SIDE_BOTTOM; - break; - default: - side = META_SIDE_TOP; - break; - } - return side; + rect->height = window->buffer_rect.height - borders.total.top - borders.total.bottom; } void -meta_window_get_titlebar_rect (MetaWindow *window, +meta_window_get_titlebar_rect (MetaWindow *window, MetaRectangle *rect) { - meta_window_get_outer_rect (window, rect); + meta_window_get_frame_rect (window, rect); /* The returned rectangle is relative to the frame rect. */ rect->x = 0; @@ -6060,7 +4701,7 @@ meta_window_get_titlebar_rect (MetaWindow *window, { /* Pick an arbitrary height for a titlebar. We might want to * eventually have CSD windows expose their borders to us. */ - rect->height = CSD_TITLEBAR_HEIGHT * meta_prefs_get_ui_scale (); + rect->height = 50; } } @@ -6099,8 +4740,8 @@ get_modal_transient (MetaWindow *window) { MetaWindow *transient = tmp->data; - if (transient->xtransient_for == modal_transient->xwindow && - transient->wm_state_modal) + if (transient->transient_for == modal_transient && + transient->type == META_WINDOW_MODAL_DIALOG) { modal_transient = transient; tmp = windows; @@ -6118,21 +4759,38 @@ get_modal_transient (MetaWindow *window) return modal_transient; } +static gboolean +meta_window_transient_can_focus (MetaWindow *window) +{ +#ifdef HAVE_WAYLAND + if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) + return meta_wayland_surface_get_buffer (window->surface) != NULL; +#endif + + return TRUE; +} + /* XXX META_EFFECT_FOCUS */ -LOCAL_SYMBOL void +void meta_window_focus (MetaWindow *window, guint32 timestamp) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; MetaWindow *modal_transient; g_return_if_fail (!window->override_redirect); + /* This is a oneshot flag */ + window->restore_focus_on_map = FALSE; + meta_topic (META_DEBUG_FOCUS, - "Setting input focus to window %s, input: %d take_focus: %d\n", - window->desc, window->input, window->take_focus); + "Setting input focus to window %s, input: %d focusable: %d\n", + window->desc, window->input, meta_window_is_focusable (window)); if (window->display->grab_window && - window->display->grab_window->all_keys_grabbed) + window->display->grab_window != window && + window->display->grab_window->all_keys_grabbed && + !window->display->grab_window->unmanaging) { meta_topic (META_DEBUG_FOCUS, "Current focus window %s has global keygrab, not focusing window %s after all\n", @@ -6142,15 +4800,14 @@ meta_window_focus (MetaWindow *window, modal_transient = get_modal_transient (window); if (modal_transient != NULL && - !modal_transient->unmanaging) + !modal_transient->unmanaging && + meta_window_transient_can_focus (modal_transient)) { meta_topic (META_DEBUG_FOCUS, "%s has %s as a modal transient, so focusing it instead.\n", window->desc, modal_transient->desc); - if (!modal_transient->on_all_workspaces && - modal_transient->workspace != window->screen->active_workspace) - meta_window_change_workspace (modal_transient, - window->screen->active_workspace); + if (!meta_window_located_on_workspace (modal_transient, workspace_manager->active_workspace)) + meta_window_change_workspace (modal_transient, workspace_manager->active_workspace); window = modal_transient; } @@ -6164,82 +4821,165 @@ meta_window_focus (MetaWindow *window, return; } - /* For output-only or shaded windows, focus the frame. - * This seems to result in the client window getting key events - * though, so I don't know if it's icccm-compliant. - * - * Still, we have to do this or keynav breaks for these windows. - */ - if (window->frame && - (window->shaded || - !(window->input || window->take_focus))) + META_WINDOW_GET_CLASS (window)->focus (window, timestamp); + + if (window->display->event_route == META_EVENT_ROUTE_NORMAL) { - meta_topic (META_DEBUG_FOCUS, - "Focusing frame of %s\n", window->desc); - meta_display_set_input_focus_window (window->display, - window, - TRUE, - timestamp); + MetaBackend *backend = meta_get_backend (); + ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend)); + clutter_stage_set_key_focus (stage, NULL); } - else - { - if (window->input) - { - meta_topic (META_DEBUG_FOCUS, - "Setting input focus on %s since input = true\n", - window->desc); - meta_display_set_input_focus_window (window->display, - window, - FALSE, - timestamp); - } - if (window->take_focus) - { - meta_topic (META_DEBUG_FOCUS, - "Sending WM_TAKE_FOCUS to %s since take_focus = true\n", - window->desc); - meta_window_send_icccm_message (window, - window->display->atom_WM_TAKE_FOCUS, - timestamp); - window->display->expected_focus_window = window; - } - } + if (window->close_dialog && + meta_close_dialog_is_visible (window->close_dialog)) + meta_close_dialog_focus (window->close_dialog); if (window->wm_state_demands_attention) meta_window_unset_demands_attention(window); + +/* meta_effect_run_focus(window, NULL, NULL); */ } +/* Workspace management. Invariants: + * + * - window->workspace describes the workspace the window is on. + * + * - workspace->windows is a list of windows that is located on + * that workspace. + * + * - If the window is on_all_workspaces, then + * window->workspace == NULL, but workspace->windows contains + * the window. + */ + static void -meta_window_change_workspace_without_transients (MetaWindow *window, - MetaWorkspace *workspace) +set_workspace_state (MetaWindow *window, + gboolean on_all_workspaces, + MetaWorkspace *workspace) { - int old_workspace = -1; + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; - meta_verbose ("Changing window %s to workspace %d\n", - window->desc, meta_workspace_index (workspace)); + /* If we're on all workspaces, then our new workspace must be NULL, + * otherwise it must be set, unless we're unmanaging. */ + if (on_all_workspaces) + g_assert_null (workspace); + else + g_assert_true (window->unmanaging || workspace != NULL); - if (!window->on_all_workspaces_requested) + /* If this is an override-redirect window, ensure that the only + * times we're setting the workspace state is either during construction + * to mark as on_all_workspaces, or when unmanaging to remove all the + * workspaces. */ + if (window->override_redirect) + g_return_if_fail ((window->constructing && on_all_workspaces) || window->unmanaging); + + if (on_all_workspaces == window->on_all_workspaces && + workspace == window->workspace && + !window->constructing) + return; + + if (window->workspace) + meta_workspace_remove_window (window->workspace, window); + else if (window->on_all_workspaces) + { + GList *l; + for (l = workspace_manager->workspaces; l != NULL; l = l->next) + { + MetaWorkspace *ws = l->data; + meta_workspace_remove_window (ws, window); + } + } + + window->on_all_workspaces = on_all_workspaces; + window->workspace = workspace; + + if (window->workspace) + meta_workspace_add_window (window->workspace, window); + else if (window->on_all_workspaces) { - old_workspace = meta_workspace_index (window->workspace); + GList *l; + for (l = workspace_manager->workspaces; l != NULL; l = l->next) + { + MetaWorkspace *ws = l->data; + meta_workspace_add_window (ws, window); + } } - /* unstick if stuck. meta_window_unstick would call - * meta_window_change_workspace recursively if the window - * is not in the active workspace. + /* queue a move_resize since changing workspaces may change + * the relevant struts */ + if (!window->override_redirect) + meta_window_queue (window, META_QUEUE_MOVE_RESIZE); + meta_window_queue (window, META_QUEUE_CALC_SHOWING); + meta_window_current_workspace_changed (window); + g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_ON_ALL_WORKSPACES]); + g_signal_emit (window, window_signals[WORKSPACE_CHANGED], 0); +} + +static gboolean +should_be_on_all_workspaces (MetaWindow *window) +{ + if (window->always_sticky) + return TRUE; + if (window->on_all_workspaces_requested) - meta_window_unstick (window); + return TRUE; + + if (window->override_redirect) + return TRUE; + + if (meta_prefs_get_workspaces_only_on_primary () && + !window->unmanaging && + window->monitor && + !meta_window_is_on_primary_monitor (window)) + return TRUE; - /* See if we're already on this space. If not, make sure we are */ - if (window->workspace != workspace) + return FALSE; +} + +void +meta_window_on_all_workspaces_changed (MetaWindow *window) +{ + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; + gboolean on_all_workspaces = should_be_on_all_workspaces (window); + + if (window->on_all_workspaces == on_all_workspaces) + return; + + MetaWorkspace *workspace; + + if (on_all_workspaces) { - meta_workspace_remove_window (window->workspace, window); - meta_workspace_add_window (workspace, window); - g_signal_emit (window, window_signals[WORKSPACE_CHANGED], 0, - old_workspace); - g_signal_emit_by_name (window->screen, "window-workspace-changed", window, window->workspace); + workspace = NULL; } + else + { + /* We're coming out of the sticky state. Put the window on + * the currently active workspace. */ + workspace = workspace_manager->active_workspace; + } + + set_workspace_state (window, on_all_workspaces, workspace); +} + +static void +meta_window_change_workspace_without_transients (MetaWindow *window, + MetaWorkspace *workspace) +{ + /* Try to unstick the window if it's stuck. This doesn't + * have any guarantee that we'll actually unstick the + * window, since it could be stuck for other reasons. */ + if (window->on_all_workspaces_requested) + meta_window_unstick (window); + + /* We failed to unstick the window. */ + if (window->on_all_workspaces) + return; + + if (window->workspace == workspace) + return; + + set_workspace_state (window, FALSE, workspace); } static gboolean @@ -6250,13 +4990,6 @@ change_workspace_foreach (MetaWindow *window, return TRUE; } -/** - * meta_window_change_workspace: - * @window: a #MetaWindow - * @workspace: the #MetaWorkspace where to put the window - * - * Moves the window to the specified workspace. - */ void meta_window_change_workspace (MetaWindow *window, MetaWorkspace *workspace) @@ -6284,14 +5017,8 @@ window_stick_impl (MetaWindow *window) * to that original workspace list if on_all_workspaces is * toggled back off. */ - int old_workspace = meta_workspace_index (window->workspace); window->on_all_workspaces_requested = TRUE; - meta_window_frame_size_changed (window); - meta_window_update_on_all_workspaces (window); - - meta_window_queue(window, META_QUEUE_CALC_SHOWING); - g_signal_emit (window, window_signals[WORKSPACE_CHANGED], 0, - old_workspace); + meta_window_on_all_workspaces_changed (window); } static void @@ -6303,19 +5030,7 @@ window_unstick_impl (MetaWindow *window) /* Revert to window->workspaces */ window->on_all_workspaces_requested = FALSE; - meta_window_frame_size_changed (window); - meta_window_update_on_all_workspaces (window); - - /* We change ourselves to the active workspace, since otherwise you'd get - * a weird window-vaporization effect. Once we have UI for being - * on more than one workspace this should probably be add_workspace - * not change_workspace. - */ - if (window->screen->active_workspace != window->workspace) - meta_window_change_workspace (window, window->screen->active_workspace); - - meta_window_queue(window, META_QUEUE_CALC_SHOWING); - g_signal_emit (window, window_signals[WORKSPACE_CHANGED], 0, -1); + meta_window_on_all_workspaces_changed (window); } static gboolean @@ -6358,96 +5073,10 @@ meta_window_unstick (MetaWindow *window) &stick); } -LOCAL_SYMBOL unsigned long -meta_window_get_net_wm_desktop (MetaWindow *window) -{ - if (window->on_all_workspaces) - return 0xFFFFFFFF; - else - return meta_workspace_index (window->workspace); -} - -static void -update_net_frame_extents (MetaWindow *window) +void +meta_window_current_workspace_changed (MetaWindow *window) { - unsigned long data[4]; - MetaFrameBorders borders; - - meta_frame_calc_borders (window->frame, &borders); - /* Left */ - data[0] = borders.visible.left; - /* Right */ - data[1] = borders.visible.right; - /* Top */ - data[2] = borders.visible.top; - /* Bottom */ - data[3] = borders.visible.bottom; - - meta_topic (META_DEBUG_GEOMETRY, - "Setting _NET_FRAME_EXTENTS on managed window 0x%lx " - "to left = %lu, right = %lu, top = %lu, bottom = %lu\n", - window->xwindow, data[0], data[1], data[2], data[3]); - - meta_error_trap_push (window->display); - XChangeProperty (window->display->xdisplay, window->xwindow, - window->display->atom__NET_FRAME_EXTENTS, - XA_CARDINAL, - 32, PropModeReplace, (guchar*) data, 4); - meta_error_trap_pop (window->display); -} - -static void -update_gtk_edge_constraints (MetaWindow *window) -{ - MetaEdgeConstraint *constraints = window->edge_constraints; - unsigned long data[1]; - - /* Edge constraints */ - data[0] = (constraints[0] != META_EDGE_CONSTRAINT_NONE ? 1 : 0) << 0 | - (constraints[0] != META_EDGE_CONSTRAINT_MONITOR ? 1 : 0) << 1 | - (constraints[1] != META_EDGE_CONSTRAINT_NONE ? 1 : 0) << 2 | - (constraints[1] != META_EDGE_CONSTRAINT_MONITOR ? 1 : 0) << 3 | - (constraints[2] != META_EDGE_CONSTRAINT_NONE ? 1 : 0) << 4 | - (constraints[2] != META_EDGE_CONSTRAINT_MONITOR ? 1 : 0) << 5 | - (constraints[3] != META_EDGE_CONSTRAINT_NONE ? 1 : 0) << 6 | - (constraints[3] != META_EDGE_CONSTRAINT_MONITOR ? 1 : 0) << 7; - - meta_verbose ("Setting _GTK_EDGE_CONSTRAINTS to %lu\n", data[0]); - - meta_error_trap_push (window->display); - XChangeProperty (window->display->xdisplay, - window->xwindow, - window->display->atom__GTK_EDGE_CONSTRAINTS, - XA_CARDINAL, 32, PropModeReplace, - (guchar*) data, 1); - meta_error_trap_pop (window->display); -} - -LOCAL_SYMBOL void -meta_window_set_current_workspace_hint (MetaWindow *window) -{ - /* FIXME if on more than one workspace, we claim to be "sticky", - * the WM spec doesn't say what to do here. - */ - unsigned long data[1]; - - if (window->workspace == NULL) - { - /* this happens when unmanaging windows */ - return; - } - - data[0] = meta_window_get_net_wm_desktop (window); - - meta_verbose ("Setting _NET_WM_DESKTOP of %s to %lu\n", - window->desc, data[0]); - - meta_error_trap_push (window->display); - XChangeProperty (window->display->xdisplay, window->xwindow, - window->display->atom__NET_WM_DESKTOP, - XA_CARDINAL, - 32, PropModeReplace, (guchar*) data, 1); - meta_error_trap_pop (window->display); + META_WINDOW_GET_CLASS (window)->current_workspace_changed (window); } static gboolean @@ -6503,13 +5132,15 @@ meta_window_raise (MetaWindow *window) * constraints in stack.c then magically take care of raising all * the child windows appropriately. */ - if (window->screen->stack == ancestor->screen->stack) - meta_stack_raise (window->screen->stack, ancestor); + if (window->display->stack == ancestor->display->stack) + { + meta_stack_raise (window->display->stack, ancestor); + } else { meta_warning ( "Either stacks aren't per screen or some window has a weird " - "transient_for hint; window->screen->stack != " + "transient_for hint; window->display->stack != " "ancestor->screen->stack. window = %s, ancestor = %s.\n", window->desc, ancestor->desc); /* We could raise the window here, but don't want to do that twice and @@ -6523,7 +5154,7 @@ meta_window_raise (MetaWindow *window) * correct child. See bug 307875. */ if (window != ancestor) - meta_stack_raise (window->screen->stack, window); + meta_stack_raise (window->display->stack, window); g_signal_emit (window, window_signals[RAISED], 0); } @@ -6536,387 +5167,7 @@ meta_window_lower (MetaWindow *window) meta_topic (META_DEBUG_WINDOW_OPS, "Lowering window %s\n", window->desc); - meta_stack_lower (window->screen->stack, window); -} - -LOCAL_SYMBOL void -meta_window_send_icccm_message (MetaWindow *window, - Atom atom, - guint32 timestamp) -{ - /* This comment and code are from twm, copyright - * Open Group, Evans & Sutherland, etc. - */ - - /* - * ICCCM Client Messages - Section 4.2.8 of the ICCCM dictates that all - * client messages will have the following form: - * - * event type ClientMessage - * message type _XA_WM_PROTOCOLS - * window tmp->w - * format 32 - * data[0] message atom - * data[1] time stamp - */ - - XClientMessageEvent ev; - - ev.type = ClientMessage; - ev.window = window->xwindow; - ev.message_type = window->display->atom_WM_PROTOCOLS; - ev.format = 32; - ev.data.l[0] = atom; - ev.data.l[1] = timestamp; - - meta_error_trap_push (window->display); - XSendEvent (window->display->xdisplay, - window->xwindow, False, 0, (XEvent*) &ev); - meta_error_trap_pop (window->display); -} - -LOCAL_SYMBOL void -meta_window_move_resize_request (MetaWindow *window, - guint value_mask, - int gravity, - int new_x, - int new_y, - int new_width, - int new_height) -{ - int x, y, width, height; - gboolean allow_position_change; - gboolean in_grab_op; - MetaMoveResizeFlags flags; - - /* We ignore configure requests while the user is moving/resizing - * the window, since these represent the app sucking and fighting - * the user, most likely due to a bug in the app (e.g. pfaedit - * seemed to do this) - * - * Still have to do the ConfigureNotify and all, but pretend the - * app asked for the current size/position instead of the new one. - */ - in_grab_op = FALSE; - if (window->display->grab_op != META_GRAB_OP_NONE && - window == window->display->grab_window) - { - switch (window->display->grab_op) - { - case META_GRAB_OP_MOVING: - case META_GRAB_OP_RESIZING_SE: - case META_GRAB_OP_RESIZING_S: - case META_GRAB_OP_RESIZING_SW: - case META_GRAB_OP_RESIZING_N: - case META_GRAB_OP_RESIZING_NE: - case META_GRAB_OP_RESIZING_NW: - case META_GRAB_OP_RESIZING_W: - case META_GRAB_OP_RESIZING_E: - in_grab_op = TRUE; - break; - default: - break; - } - } - - /* it's essential to use only the explicitly-set fields, - * and otherwise use our current up-to-date position. - * - * Otherwise you get spurious position changes when the app changes - * size, for example, if window->rect is not in sync with the - * server-side position in effect when the configure request was - * generated. - */ - meta_window_get_gravity_position (window, - gravity, - &x, &y); - - allow_position_change = FALSE; - - if (meta_prefs_get_disable_workarounds ()) - { - if (window->type == META_WINDOW_DIALOG || - window->type == META_WINDOW_MODAL_DIALOG || - window->type == META_WINDOW_SPLASHSCREEN) - ; /* No position change for these */ - else if ((window->size_hints.flags & PPosition) || - /* USPosition is just stale if window is placed; - * no --geometry involved here. - */ - ((window->size_hints.flags & USPosition) && - !window->placed)) - allow_position_change = TRUE; - } - else - { - allow_position_change = TRUE; - } - - if (in_grab_op) - allow_position_change = FALSE; - - if (allow_position_change) - { - if (value_mask & CWX) - x = new_x; - if (value_mask & CWY) - y = new_y; - if (value_mask & (CWX | CWY)) - { - /* Once manually positioned, windows shouldn't be placed - * by the window manager. - */ - window->placed = TRUE; - } - } - else - { - meta_topic (META_DEBUG_GEOMETRY, - "Not allowing position change for window %s PPosition 0x%lx USPosition 0x%lx type %u\n", - window->desc, window->size_hints.flags & PPosition, - window->size_hints.flags & USPosition, - window->type); - } - - width = window->rect.width; - height = window->rect.height; - if (!in_grab_op) - { - if (value_mask & CWWidth) - width = new_width; - - if (value_mask & CWHeight) - height = new_height; - } - - /* ICCCM 4.1.5 */ - - /* We're ignoring the value_mask here, since sizes - * not in the mask will be the current window geometry. - */ - window->size_hints.x = x; - window->size_hints.y = y; - window->size_hints.width = width; - window->size_hints.height = height; - - /* NOTE: We consider ConfigureRequests to be "user" actions in one - * way, but not in another. Explanation of the two cases are in the - * next two big comments. - */ - - /* The constraints code allows user actions to move windows - * offscreen, etc., and configure request actions would often send - * windows offscreen when users don't want it if not constrained - * (e.g. hitting a dropdown triangle in a fileselector to show more - * options, which makes the window bigger). Thus we do not set - * META_IS_USER_ACTION in flags to the - * meta_window_move_resize_internal() call. - */ - flags = META_IS_CONFIGURE_REQUEST; - if (value_mask & (CWX | CWY)) - flags |= META_IS_MOVE_ACTION; - if (value_mask & (CWWidth | CWHeight)) - flags |= META_IS_RESIZE_ACTION; - - if (flags & (META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION)) - { - MetaRectangle rect, monitor_rect; - - rect.x = x; - rect.y = y; - rect.width = width; - rect.height = height; - - /* Workaround braindead legacy apps that don't know how to - * fullscreen themselves properly - don't get fooled by - * windows which hide their titlebar when maximized or which are - * client decorated; that's not the same as fullscreen, even - * if there are no struts making the workarea smaller than - * the monitor. - */ - if (window->monitor) - { - meta_screen_get_monitor_geometry (window->screen, window->monitor->number, &monitor_rect); - - if (meta_prefs_get_force_fullscreen() && - !window->hide_titlebar_when_maximized && - (window->decorated && !meta_window_is_client_decorated (window)) && - meta_rectangle_equal (&rect, &monitor_rect) && - window->has_fullscreen_func && - !window->fullscreen) - { - /* - meta_topic (META_DEBUG_GEOMETRY, - */ - meta_warning ( - "Treating resize request of legacy application %s as a " - "fullscreen request\n", - window->desc); - meta_window_make_fullscreen_internal (window); - } - } - - meta_window_move_resize_internal (window, - flags, - gravity, - x, - y, - width, - height); - } - /* window->user_rect exists to allow "snapping-back" the window if a - * new strut is set (causing the window to move) and then the strut - * is later removed without the user moving the window in the - * interim. We'd like to "snap-back" to the position specified by - * ConfigureRequest events (at least the constrained version of the - * ConfigureRequest, since that is guaranteed to be onscreen) so we - * set user_rect here. - * - * See also bug 426519. - */ - save_user_window_placement (window); -} - -static void -restack_window (MetaWindow *window, - MetaWindow *sibling, - int direction) -{ - switch (direction) - { - case Above: - if (sibling) - meta_window_stack_just_above (window, sibling); - else - meta_window_raise (window); - break; - case Below: - if (sibling) - meta_window_stack_just_below (window, sibling); - else - meta_window_lower (window); - break; - case TopIf: - case BottomIf: - case Opposite: - break; - } -} - -LOCAL_SYMBOL gboolean -meta_window_configure_request (MetaWindow *window, - XEvent *event) -{ - /* Note that x, y is the corner of the window border, - * and width, height is the size of the window inside - * its border, but that we always deny border requests - * and give windows a border of 0. But we save the - * requested border here. - */ - if (event->xconfigurerequest.value_mask & CWBorderWidth) - window->border_width = event->xconfigurerequest.border_width; - - meta_window_move_resize_request(window, - event->xconfigurerequest.value_mask, - window->size_hints.win_gravity, - event->xconfigurerequest.x, - event->xconfigurerequest.y, - event->xconfigurerequest.width, - event->xconfigurerequest.height); - - /* Handle stacking. We only handle raises/lowers, mostly because - * stack.c really can't deal with anything else. I guess we'll fix - * that if a client turns up that really requires it. Only a very - * few clients even require the raise/lower (and in fact all client - * attempts to deal with stacking order are essentially broken, - * since they have no idea what other clients are involved or how - * the stack looks). - * - * I'm pretty sure no interesting client uses TopIf, BottomIf, or - * Opposite anyway. - */ - if (event->xconfigurerequest.value_mask & CWStackMode) - { - MetaWindow *active_window; - active_window = window->display->expected_focus_window; - if (meta_prefs_get_disable_workarounds ()) - { - meta_topic (META_DEBUG_STACK, - "%s sent an xconfigure stacking request; this is " - "broken behavior and the request is being ignored.\n", - window->desc); - } - else if (active_window && - !meta_window_same_application (window, active_window) && - !meta_window_same_client (window, active_window) && - XSERVER_TIME_IS_BEFORE (window->net_wm_user_time, - active_window->net_wm_user_time)) - { - meta_topic (META_DEBUG_STACK, - "Ignoring xconfigure stacking request from %s (with " - "user_time %u); currently active application is %s (with " - "user_time %u).\n", - window->desc, - window->net_wm_user_time, - active_window->desc, - active_window->net_wm_user_time); - if (event->xconfigurerequest.detail == Above) - meta_window_set_demands_attention(window); - } - else - { - MetaWindow *sibling = NULL; - /* Handle Above/Below with a sibling set */ - if (event->xconfigurerequest.above != None) - { - MetaDisplay *display; - - display = meta_window_get_display (window); - sibling = meta_display_lookup_x_window (display, - event->xconfigurerequest.above); - if (sibling == NULL) - return TRUE; - - meta_topic (META_DEBUG_STACK, - "xconfigure stacking request from window %s sibling %s stackmode %d\n", - window->desc, sibling->desc, event->xconfigurerequest.detail); - } - restack_window (window, sibling, event->xconfigurerequest.detail); - } - } - - return TRUE; -} - -LOCAL_SYMBOL gboolean -meta_window_property_notify (MetaWindow *window, - XEvent *event) -{ - return process_property_notify (window, &event->xproperty); -} - -static void -handle_net_restack_window (MetaDisplay *display, - XEvent *event) -{ - MetaWindow *window, *sibling = NULL; - - /* Ignore if this does not come from a pager, see the WM spec - */ - if (event->xclient.data.l[0] != 2) - return; - - window = meta_display_lookup_x_window (display, - event->xclient.window); - - if (window) - { - if (event->xclient.data.l[1]) - sibling = meta_display_lookup_x_window (display, - event->xclient.data.l[1]); - - restack_window (window, sibling, event->xclient.data.l[2]); - } + meta_stack_lower (window->display->stack, window); } /* @@ -6926,11 +5177,11 @@ handle_net_restack_window (MetaDisplay *display, void meta_window_change_workspace_by_index (MetaWindow *window, gint space_index, - gboolean append, - guint32 timestamp) + gboolean append) { + MetaWorkspaceManager *workspace_manager; MetaWorkspace *workspace; - MetaScreen *screen; + MetaDisplay *display; g_return_if_fail (!window->override_redirect); @@ -6940,548 +5191,57 @@ meta_window_change_workspace_by_index (MetaWindow *window, return; } - screen = window->screen; + display = window->display; + workspace_manager = display->workspace_manager; workspace = - meta_screen_get_workspace_by_index (screen, space_index); + meta_workspace_manager_get_workspace_by_index (workspace_manager, space_index); if (!workspace && append) - { - if (timestamp == CurrentTime) - timestamp = meta_display_get_current_time_roundtrip (window->display); - workspace = meta_screen_append_new_workspace (screen, FALSE, timestamp); - } + workspace = meta_workspace_manager_append_new_workspace (workspace_manager, FALSE, META_CURRENT_TIME); if (workspace) - { - if (window->on_all_workspaces_requested) - meta_window_unstick (window); - - meta_window_change_workspace (window, workspace); - } + meta_window_change_workspace (window, workspace); } -#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0 -#define _NET_WM_MOVERESIZE_SIZE_TOP 1 -#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2 -#define _NET_WM_MOVERESIZE_SIZE_RIGHT 3 -#define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4 -#define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5 -#define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6 -#define _NET_WM_MOVERESIZE_SIZE_LEFT 7 -#define _NET_WM_MOVERESIZE_MOVE 8 -#define _NET_WM_MOVERESIZE_SIZE_KEYBOARD 9 -#define _NET_WM_MOVERESIZE_MOVE_KEYBOARD 10 -#define _NET_WM_MOVERESIZE_CANCEL 11 - -LOCAL_SYMBOL gboolean -meta_window_client_message (MetaWindow *window, - XEvent *event) +static void +meta_window_appears_focused_changed (MetaWindow *window) { - MetaDisplay *display; - - display = window->display; - - if (window->override_redirect) - { - /* Don't warn here: we could warn on any of the messages below, - * but we might also receive other client messages that are - * part of protocols we don't know anything about. So, silently - * ignoring is simplest. - */ - return FALSE; - } - - if (event->xclient.message_type == - display->atom__NET_CLOSE_WINDOW) - { - guint32 timestamp; - - if (event->xclient.data.l[0] != 0) - timestamp = event->xclient.data.l[0]; - else - { - meta_warning ("Receiving a NET_CLOSE_WINDOW message for %s without " - "a timestamp! This means some buggy (outdated) " - "application is on the loose!\n", - window->desc); - timestamp = meta_display_get_current_time (window->display); - } - - meta_window_delete (window, timestamp); - - return TRUE; - } - else if (event->xclient.message_type == - display->atom__NET_WM_DESKTOP) - { - int space; - MetaWorkspace *workspace; - - space = event->xclient.data.l[0]; - - meta_verbose ("Request to move %s to workspace %d\n", - window->desc, space); - - workspace = - meta_screen_get_workspace_by_index (window->screen, - space); - - if (workspace) - meta_window_change_workspace (window, workspace); - else if (space == (int) 0xFFFFFFFF) - meta_window_stick (window); - else - meta_verbose ("No such workspace %d for screen\n", space); - - meta_verbose ("Window %s now on_all_workspaces = %d\n", - window->desc, window->on_all_workspaces); - - return TRUE; - } - else if (event->xclient.message_type == - display->atom__NET_WM_STATE) - { - gulong action; - Atom first; - Atom second; - - action = event->xclient.data.l[0]; - first = event->xclient.data.l[1]; - second = event->xclient.data.l[2]; - - if (meta_is_verbose ()) - { - char *str1; - char *str2; - - meta_error_trap_push_with_return (display); - str1 = XGetAtomName (display->xdisplay, first); - if (meta_error_trap_pop_with_return (display) != Success) - str1 = NULL; - - meta_error_trap_push_with_return (display); - str2 = XGetAtomName (display->xdisplay, second); - if (meta_error_trap_pop_with_return (display) != Success) - str2 = NULL; - - meta_verbose ("Request to change _NET_WM_STATE action %lu atom1: %s atom2: %s\n", - action, - str1 ? str1 : "(unknown)", - str2 ? str2 : "(unknown)"); - - meta_XFree (str1); - meta_XFree (str2); - } - - if (first == display->atom__NET_WM_STATE_SHADED || - second == display->atom__NET_WM_STATE_SHADED) - { - gboolean shade; - guint32 timestamp; - - /* Stupid protocol has no timestamp; of course, shading - * sucks anyway so who really cares that we're forced to do - * a roundtrip here? - */ - timestamp = meta_display_get_current_time_roundtrip (window->display); - - shade = (action == _NET_WM_STATE_ADD || - (action == _NET_WM_STATE_TOGGLE && !window->shaded)); - if (shade && window->has_shade_func) - meta_window_shade (window, timestamp); - else - meta_window_unshade (window, timestamp); - } - - if (first == display->atom__NET_WM_STATE_FULLSCREEN || - second == display->atom__NET_WM_STATE_FULLSCREEN) - { - gboolean make_fullscreen; - - make_fullscreen = (action == _NET_WM_STATE_ADD || - (action == _NET_WM_STATE_TOGGLE && !window->fullscreen)); - if (make_fullscreen && window->has_fullscreen_func) - meta_window_make_fullscreen (window); - else - meta_window_unmake_fullscreen (window); - } - - if (first == display->atom__NET_WM_STATE_MAXIMIZED_HORZ || - second == display->atom__NET_WM_STATE_MAXIMIZED_HORZ) - { - gboolean max; - - max = (action == _NET_WM_STATE_ADD || - (action == _NET_WM_STATE_TOGGLE && - !window->maximized_horizontally)); - if (max && window->has_maximize_func) - { - if (meta_prefs_get_raise_on_click ()) - meta_window_raise (window); - meta_window_maximize (window, META_MAXIMIZE_HORIZONTAL); - } - else - { - if (meta_prefs_get_raise_on_click ()) - meta_window_raise (window); - meta_window_unmaximize (window, META_MAXIMIZE_HORIZONTAL); - } - } - - if (first == display->atom__NET_WM_STATE_MAXIMIZED_VERT || - second == display->atom__NET_WM_STATE_MAXIMIZED_VERT) - { - gboolean max; - - max = (action == _NET_WM_STATE_ADD || - (action == _NET_WM_STATE_TOGGLE && - !window->maximized_vertically)); - if (max && window->has_maximize_func) - { - if (meta_prefs_get_raise_on_click ()) - meta_window_raise (window); - meta_window_maximize (window, META_MAXIMIZE_VERTICAL); - } - else - { - if (meta_prefs_get_raise_on_click ()) - meta_window_raise (window); - meta_window_unmaximize (window, META_MAXIMIZE_VERTICAL); - } - } - - if (first == display->atom__NET_WM_STATE_MODAL || - second == display->atom__NET_WM_STATE_MODAL) - { - window->wm_state_modal = - (action == _NET_WM_STATE_ADD) || - (action == _NET_WM_STATE_TOGGLE && !window->wm_state_modal); - - recalc_window_type (window); - meta_window_queue(window, META_QUEUE_MOVE_RESIZE); - } - - if (first == display->atom__NET_WM_STATE_SKIP_PAGER || - second == display->atom__NET_WM_STATE_SKIP_PAGER) - { - window->wm_state_skip_pager = - (action == _NET_WM_STATE_ADD) || - (action == _NET_WM_STATE_TOGGLE && !window->skip_pager); - - recalc_window_features (window); - set_net_wm_state (window); - } - - if (first == display->atom__NET_WM_STATE_SKIP_TASKBAR || - second == display->atom__NET_WM_STATE_SKIP_TASKBAR) - { - window->wm_state_skip_taskbar = - (action == _NET_WM_STATE_ADD) || - (action == _NET_WM_STATE_TOGGLE && !window->skip_taskbar); - - recalc_window_features (window); - set_net_wm_state (window); - } - - if (first == display->atom__NET_WM_STATE_ABOVE || - second == display->atom__NET_WM_STATE_ABOVE) - { - meta_window_set_above(window, - (action == _NET_WM_STATE_ADD) || - (action == _NET_WM_STATE_TOGGLE && !window->wm_state_above)); - } - - if (first == display->atom__NET_WM_STATE_BELOW || - second == display->atom__NET_WM_STATE_BELOW) - { - window->wm_state_below = - (action == _NET_WM_STATE_ADD) || - (action == _NET_WM_STATE_TOGGLE && !window->wm_state_below); - - meta_window_update_layer (window); - set_net_wm_state (window); - } - - if (first == display->atom__NET_WM_STATE_DEMANDS_ATTENTION || - second == display->atom__NET_WM_STATE_DEMANDS_ATTENTION) - { - if ((action == _NET_WM_STATE_ADD) || - (action == _NET_WM_STATE_TOGGLE && !window->wm_state_demands_attention)) - meta_window_set_demands_attention (window); - else - meta_window_unset_demands_attention (window); - } - - if (first == display->atom__NET_WM_STATE_STICKY || - second == display->atom__NET_WM_STATE_STICKY) - { - if ((action == _NET_WM_STATE_ADD) || - (action == _NET_WM_STATE_TOGGLE && !window->on_all_workspaces_requested)) - meta_window_stick (window); - else - meta_window_unstick (window); - } - - return TRUE; - } - else if (event->xclient.message_type == - display->atom_WM_CHANGE_STATE) - { - meta_verbose ("WM_CHANGE_STATE client message, state: %ld\n", - event->xclient.data.l[0]); - if (event->xclient.data.l[0] == IconicState) - meta_window_minimize (window); - - return TRUE; - } - else if (event->xclient.message_type == - display->atom__NET_WM_MOVERESIZE) - { - int x_root; - int y_root; - int action; - MetaGrabOp op; - int button; - guint32 timestamp; - - /* _NET_WM_MOVERESIZE messages are almost certainly going to come from - * clients when users click on the fake "frame" that the client has, - * thus we should also treat such messages as though it were a - * "frame action". - */ - gboolean const frame_action = TRUE; - - x_root = event->xclient.data.l[0]; - y_root = event->xclient.data.l[1]; - action = event->xclient.data.l[2]; - button = event->xclient.data.l[3]; - - /* FIXME: What a braindead protocol; no timestamp?!? */ - timestamp = meta_display_get_current_time_roundtrip (display); - meta_topic (META_DEBUG_WINDOW_OPS, - "Received _NET_WM_MOVERESIZE message on %s, %d,%d action = %d, button %d\n", - window->desc, - x_root, y_root, action, button); - - op = META_GRAB_OP_NONE; - switch (action) - { - case _NET_WM_MOVERESIZE_SIZE_TOPLEFT: - op = META_GRAB_OP_RESIZING_NW; - break; - case _NET_WM_MOVERESIZE_SIZE_TOP: - op = META_GRAB_OP_RESIZING_N; - break; - case _NET_WM_MOVERESIZE_SIZE_TOPRIGHT: - op = META_GRAB_OP_RESIZING_NE; - break; - case _NET_WM_MOVERESIZE_SIZE_RIGHT: - op = META_GRAB_OP_RESIZING_E; - break; - case _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT: - op = META_GRAB_OP_RESIZING_SE; - break; - case _NET_WM_MOVERESIZE_SIZE_BOTTOM: - op = META_GRAB_OP_RESIZING_S; - break; - case _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT: - op = META_GRAB_OP_RESIZING_SW; - break; - case _NET_WM_MOVERESIZE_SIZE_LEFT: - op = META_GRAB_OP_RESIZING_W; - break; - case _NET_WM_MOVERESIZE_MOVE: - op = META_GRAB_OP_MOVING; - break; - case _NET_WM_MOVERESIZE_SIZE_KEYBOARD: - op = META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN; - break; - case _NET_WM_MOVERESIZE_MOVE_KEYBOARD: - op = META_GRAB_OP_KEYBOARD_MOVING; - break; - case _NET_WM_MOVERESIZE_CANCEL: - /* handled below */ - break; - default: - break; - } - - if (action == _NET_WM_MOVERESIZE_CANCEL) - { - meta_display_end_grab_op (window->display, timestamp); - } - else if (op != META_GRAB_OP_NONE && - ((window->has_move_func && op == META_GRAB_OP_KEYBOARD_MOVING) || - (window->has_resize_func && op == META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN))) - { - meta_window_begin_grab_op (window, op, frame_action, timestamp); - } - else if (op != META_GRAB_OP_NONE && - ((window->has_move_func && op == META_GRAB_OP_MOVING) || - (window->has_resize_func && - (op != META_GRAB_OP_MOVING && - op != META_GRAB_OP_KEYBOARD_MOVING)))) - { - /* - * the button SHOULD already be included in the message - */ - if (button == 0) - { - int x, y, query_root_x, query_root_y; - Window root, child; - guint mask; - - /* The race conditions in this _NET_WM_MOVERESIZE thing - * are mind-boggling - */ - mask = 0; - meta_error_trap_push (window->display); - XQueryPointer (window->display->xdisplay, - window->xwindow, - &root, &child, - &query_root_x, &query_root_y, - &x, &y, - &mask); - meta_error_trap_pop (window->display); - - if (mask & Button1Mask) - button = 1; - else if (mask & Button2Mask) - button = 2; - else if (mask & Button3Mask) - button = 3; - else - button = 0; - } - - if (button != 0) - { - meta_topic (META_DEBUG_WINDOW_OPS, - "Beginning move/resize with button = %d\n", button); - meta_display_begin_grab_op (window->display, - window->screen, - window, - op, - FALSE, - frame_action, - button, 0, - timestamp, - x_root, - y_root); - } - } + set_net_wm_state (window); + meta_window_frame_size_changed (window); - return TRUE; - } - else if (event->xclient.message_type == - display->atom__NET_MOVERESIZE_WINDOW) - { - int gravity; - guint value_mask; + g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_APPEARS_FOCUSED]); - gravity = (event->xclient.data.l[0] & 0xff); - value_mask = (event->xclient.data.l[0] & 0xf00) >> 8; - /* source = (event->xclient.data.l[0] & 0xf000) >> 12; */ + if (window->frame) + meta_frame_queue_draw (window->frame); +} - if (gravity == 0) - gravity = window->size_hints.win_gravity; +static gboolean +should_propagate_focus_appearance (MetaWindow *window) +{ + /* Parents of attached modal dialogs should appear focused. */ + if (meta_window_is_attached_dialog (window)) + return TRUE; - meta_window_move_resize_request(window, - value_mask, - gravity, - event->xclient.data.l[1], /* x */ - event->xclient.data.l[2], /* y */ - event->xclient.data.l[3], /* width */ - event->xclient.data.l[4]); /* height */ - } - else if (event->xclient.message_type == - display->atom__NET_ACTIVE_WINDOW) + /* Parents of these sorts of override-redirect windows should + * appear focused. */ + switch (window->type) { - MetaClientType source_indication; - guint32 timestamp; - - meta_verbose ("_NET_ACTIVE_WINDOW request for window '%s', activating\n", - window->desc); - - source_indication = event->xclient.data.l[0]; - timestamp = event->xclient.data.l[1]; - - if (source_indication > META_CLIENT_TYPE_MAX_RECOGNIZED) - source_indication = META_CLIENT_TYPE_UNKNOWN; - - if (timestamp == 0) - { - /* Client using older EWMH _NET_ACTIVE_WINDOW without a timestamp */ - meta_topic (META_DEBUG_FOCUS, - "Buggy client sent a _NET_ACTIVE_WINDOW message with a " - "timestamp of 0 for %s\n", - window->desc); - timestamp = meta_display_get_current_time (display); - } - - window_activate (window, timestamp, source_indication, NULL); + case META_WINDOW_DROPDOWN_MENU: + case META_WINDOW_POPUP_MENU: + case META_WINDOW_COMBO: + case META_WINDOW_TOOLTIP: + case META_WINDOW_NOTIFICATION: + case META_WINDOW_DND: + case META_WINDOW_OVERRIDE_OTHER: return TRUE; - } - else if (event->xclient.message_type == - display->atom__NET_WM_FULLSCREEN_MONITORS) - { - gulong top, bottom, left, right; - - meta_verbose ("_NET_WM_FULLSCREEN_MONITORS request for window '%s'\n", - window->desc); - - top = event->xclient.data.l[0]; - bottom = event->xclient.data.l[1]; - left = event->xclient.data.l[2]; - right = event->xclient.data.l[3]; - /* source_indication = event->xclient.data.l[4]; */ - - meta_window_update_fullscreen_monitors (window, top, bottom, left, right); - } - - else if (event->xclient.message_type == - display->atom__GTK_SHOW_WINDOW_MENU) - { - if (meta_window_is_client_decorated (window)) - { - int x_root, y_root; - - x_root = event->xclient.data.l[1]; - y_root = event->xclient.data.l[2]; - - meta_screen_hide_hud_and_preview (window->screen); - - if (meta_prefs_get_raise_on_click ()) - meta_window_raise (window); - meta_window_focus (window, meta_display_get_current_time_roundtrip (display)); - - meta_window_show_menu (window, x_root, - y_root, GDK_BUTTON_SECONDARY, - meta_display_get_current_time_roundtrip (display)); - } - } - else if (event->xclient.message_type == - display->atom__NET_RESTACK_WINDOW) - { - handle_net_restack_window (display, event); + default: + break; } return FALSE; } -static void -meta_window_appears_focused_changed (MetaWindow *window) -{ - set_net_wm_state (window); - meta_window_frame_size_changed (window); - - g_object_notify (G_OBJECT (window), "appears-focused"); - - if (window->frame) - meta_frame_queue_draw (window->frame); -} - /** * meta_window_propagate_focus_appearance: * @window: the window to start propagating from @@ -7495,7 +5255,7 @@ meta_window_appears_focused_changed (MetaWindow *window) * @window's ancestors will have its %attached_focus_window field * cleared if it is currently %focus_window. */ -LOCAL_SYMBOL void +static void meta_window_propagate_focus_appearance (MetaWindow *window, gboolean focused) { @@ -7505,7 +5265,7 @@ meta_window_propagate_focus_appearance (MetaWindow *window, child = window; parent = meta_window_get_transient_for (child); - while (parent && (!focused || meta_window_is_attached_dialog (child))) + while (parent && (!focused || should_propagate_focus_appearance (child))) { gboolean child_focus_state_changed; @@ -7524,8 +5284,7 @@ meta_window_propagate_focus_appearance (MetaWindow *window, parent->attached_focus_window = NULL; } - if (child_focus_state_changed && !parent->has_focus && - parent != window->display->expected_focus_window) + if (child_focus_state_changed && !parent->has_focus) { meta_window_appears_focused_changed (parent); } @@ -7535,286 +5294,96 @@ meta_window_propagate_focus_appearance (MetaWindow *window, } } -LOCAL_SYMBOL gboolean -meta_window_notify_focus (MetaWindow *window, - XEvent *event) +void +meta_window_set_focused_internal (MetaWindow *window, + gboolean focused) { - /* note the event can be on either the window or the frame, - * we focus the frame for shaded windows - */ - - /* The event can be FocusIn, FocusOut, or UnmapNotify. - * On UnmapNotify we have to pretend it's focus out, - * because we won't get a focus out if it occurs, apparently. - */ - - /* We ignore grabs, though this is questionable. - * It may be better to increase the intelligence of - * the focus window tracking. - * - * The problem is that keybindings for windows are done with - * XGrabKey, which means focus_window disappears and the front of - * the MRU list gets confused from what the user expects once a - * keybinding is used. - */ - meta_topic (META_DEBUG_FOCUS, - "Focus %s event received on %s 0x%lx (%s) " - "mode %s detail %s\n", - event->type == FocusIn ? "in" : - event->type == FocusOut ? "out" : - event->type == UnmapNotify ? "unmap" : - "???", - window->desc, event->xany.window, - event->xany.window == window->xwindow ? - "client window" : - (window->frame && event->xany.window == window->frame->xwindow) ? - "frame window" : - "unknown window", - event->type != UnmapNotify ? - meta_event_mode_to_string (event->xfocus.mode) : "n/a", - event->type != UnmapNotify ? - meta_event_detail_to_string (event->xfocus.detail) : "n/a"); - - /* FIXME our pointer tracking is broken; see how - * gtk+/gdk/x11/gdkevents-x11.c or XFree86/xc/programs/xterm/misc.c - * handle it for the correct way. In brief you need to track - * pointer focus and regular focus, and handle EnterNotify in - * PointerRoot mode with no window manager. However as noted above, - * accurate focus tracking will break things because we want to keep - * windows "focused" when using keybindings on them, and also we - * sometimes "focus" a window by focusing its frame or - * no_focus_window; so this all needs rethinking massively. - * - * My suggestion is to change it so that we clearly separate - * actual keyboard focus tracking using the xterm algorithm, - * and muffin's "pretend" focus window, and go through all - * the code and decide which one should be used in each place; - * a hard bit is deciding on a policy for that. - * - * http://bugzilla.gnome.org/show_bug.cgi?id=90382 - */ - - if ((event->type == FocusIn || - event->type == FocusOut) && - (event->xfocus.mode == NotifyGrab || - event->xfocus.mode == NotifyUngrab || - /* From WindowMaker, ignore all funky pointer root events */ - event->xfocus.detail > NotifyNonlinearVirtual)) - { - meta_topic (META_DEBUG_FOCUS, - "Ignoring focus event generated by a grab or other weirdness\n"); - return TRUE; - } + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; - if (event->type == FocusIn) + if (focused) { + window->has_focus = TRUE; if (window->override_redirect) - { - window->display->focus_window = NULL; - g_object_notify (G_OBJECT (window->display), "focus-window"); - return FALSE; - } + return; - if (window != window->display->focus_window) + /* Move to the front of the focusing workspace's MRU list. + * We should only be "removing" it from the MRU list if it's + * not already there. Note that it's possible that we might + * be processing this FocusIn after we've changed to a + * different workspace; we should therefore update the MRU + * list only if the window is actually on the active + * workspace. + */ + if (workspace_manager->active_workspace && + meta_window_located_on_workspace (window, + workspace_manager->active_workspace)) { - meta_topic (META_DEBUG_FOCUS, - "* Focus --> %s\n", window->desc); - window->display->focus_window = window; - window->has_focus = TRUE; - - /* Move to the front of the focusing workspace's MRU list. - * We should only be "removing" it from the MRU list if it's - * not already there. Note that it's possible that we might - * be processing this FocusIn after we've changed to a - * different workspace; we should therefore update the MRU - * list only if the window is actually on the active - * workspace. - */ - if (window->screen->active_workspace && - meta_window_located_on_workspace (window, - window->screen->active_workspace)) - { - GList* link; - link = g_list_find (window->screen->active_workspace->mru_list, - window); - g_assert (link); - - window->screen->active_workspace->mru_list = - g_list_remove_link (window->screen->active_workspace->mru_list, - link); - g_list_free (link); - - window->screen->active_workspace->mru_list = - g_list_prepend (window->screen->active_workspace->mru_list, - window); - } - - if (window->frame) - meta_frame_queue_draw (window->frame); - - meta_error_trap_push (window->display); - XInstallColormap (window->display->xdisplay, - window->colormap); - meta_error_trap_pop (window->display); - - - /* Ungrab click to focus button since the sync grab can interfere - * with some things you might do inside the focused window, by - * causing the client to get funky enter/leave events. - * - * The reason we usually have a passive grab on the window is - * so that we can intercept clicks and raise the window in - * response. For click-to-focus we don't need that since the - * focused window is already raised. When raise_on_click is - * FALSE we also don't need that since we don't do anything - * when the window is clicked. - * - * There is dicussion in bugs 102209, 115072, and 461577 - */ - if (meta_prefs_get_focus_mode () == C_DESKTOP_FOCUS_MODE_CLICK || - !meta_prefs_get_raise_on_click()) - meta_display_ungrab_focus_window_button (window->display, window); - - g_signal_emit (window, window_signals[FOCUS], 0); - g_object_notify (G_OBJECT (window->display), "focus-window"); + GList* link; + link = g_list_find (workspace_manager->active_workspace->mru_list, + window); + g_assert (link); - if (!window->attached_focus_window) - meta_window_appears_focused_changed (window); + workspace_manager->active_workspace->mru_list = + g_list_remove_link (workspace_manager->active_workspace->mru_list, + link); + g_list_free (link); - meta_window_propagate_focus_appearance (window, TRUE); - } - } - else if (event->type == FocusOut || - event->type == UnmapNotify) - { - if (event->type == FocusOut && - event->xfocus.detail == NotifyInferior) - { - /* This event means the client moved focus to a subwindow */ - meta_topic (META_DEBUG_FOCUS, - "Ignoring focus out on %s with NotifyInferior\n", - window->desc); - return TRUE; + workspace_manager->active_workspace->mru_list = + g_list_prepend (workspace_manager->active_workspace->mru_list, + window); } - if (window == window->display->focus_window) - { - meta_topic (META_DEBUG_FOCUS, - "%s is now the previous focus window due to being focused out or unmapped\n", - window->desc); - - meta_topic (META_DEBUG_FOCUS, - "* Focus --> NULL (was %s)\n", window->desc); - - meta_window_propagate_focus_appearance (window, FALSE); - - window->display->focus_window = NULL; - g_object_notify (G_OBJECT (window->display), "focus-window"); - window->has_focus = FALSE; - - if (!window->attached_focus_window) - meta_window_appears_focused_changed (window); - - meta_error_trap_push (window->display); - XUninstallColormap (window->display->xdisplay, - window->colormap); - meta_error_trap_pop (window->display); - - /* Re-grab for click to focus and raise-on-click, if necessary */ - if (meta_prefs_get_focus_mode () == C_DESKTOP_FOCUS_MODE_CLICK || - !meta_prefs_get_raise_on_click ()) - meta_display_grab_focus_window_button (window->display, window); - } - } - - /* Now set _NET_ACTIVE_WINDOW hint */ - meta_display_update_active_window_hint (window->display); - - return FALSE; -} - -static gboolean -process_property_notify (MetaWindow *window, - XPropertyEvent *event) -{ - Window xid = window->xwindow; - - if (meta_is_verbose ()) /* avoid looking up the name if we don't have to */ - { - char *property_name = XGetAtomName (window->display->xdisplay, - event->atom); - - meta_verbose ("Property notify on %s for %s\n", - window->desc, property_name); - XFree (property_name); - } - - if (event->atom == window->display->atom__NET_WM_USER_TIME && - window->user_time_window) - { - xid = window->user_time_window; - } - - meta_window_reload_property_from_xwindow (window, xid, event->atom, FALSE); - - return TRUE; -} - -static void -send_configure_notify (MetaWindow *window) -{ - g_return_if_fail (!window->override_redirect); - - XEvent event; - - /* from twm */ + if (window->frame) + meta_frame_queue_draw (window->frame); - event.type = ConfigureNotify; - event.xconfigure.display = window->display->xdisplay; - event.xconfigure.event = window->xwindow; - event.xconfigure.window = window->xwindow; - event.xconfigure.x = window->rect.x - window->border_width; - event.xconfigure.y = window->rect.y - window->border_width; - if (window->frame) - { - if (window->withdrawn) + /* Ungrab click to focus button since the sync grab can interfere + * with some things you might do inside the focused window, by + * causing the client to get funky enter/leave events. + * + * The reason we usually have a passive grab on the window is + * so that we can intercept clicks and raise the window in + * response. For click-to-focus we don't need that since the + * focused window is already raised. When raise_on_click is + * FALSE we also don't need that since we don't do anything + * when the window is clicked. + * + * There is dicussion in bugs 102209, 115072, and 461577 + */ + if (meta_prefs_get_focus_mode () == C_DESKTOP_FOCUS_MODE_CLICK || + !meta_prefs_get_raise_on_click()) { - MetaFrameBorders borders; - /* We reparent the client window and put it to the position - * where the visible top-left of the frame window currently is. - */ + meta_display_ungrab_focus_window_button (window->display, window); + /* Since we ungrab with XIAnyModifier above, all button + grabs go way so we need to re-grab the window buttons. */ + meta_display_grab_window_buttons (window->display, window->xwindow); + } - meta_frame_calc_borders (window->frame, &borders); + g_signal_emit (window, window_signals[FOCUS], 0); - event.xconfigure.x = window->frame->rect.x + borders.invisible.left; - event.xconfigure.y = window->frame->rect.y + borders.invisible.top; - } - else - { - /* Need to be in root window coordinates */ - event.xconfigure.x += window->frame->rect.x; - event.xconfigure.y += window->frame->rect.y; - } + if (!window->attached_focus_window) + meta_window_appears_focused_changed (window); + + meta_window_propagate_focus_appearance (window, TRUE); } - event.xconfigure.width = window->rect.width; - event.xconfigure.height = window->rect.height; - event.xconfigure.border_width = window->border_width; /* requested not actual */ - event.xconfigure.above = None; /* FIXME */ - event.xconfigure.override_redirect = False; + else + { + window->has_focus = FALSE; + if (window->override_redirect) + return; + + meta_window_propagate_focus_appearance (window, FALSE); - meta_topic (META_DEBUG_GEOMETRY, - "Sending synthetic configure notify to %s with x: %d y: %d w: %d h: %d\n", window->desc, - event.xconfigure.x, event.xconfigure.y, - event.xconfigure.width, event.xconfigure.height); + if (!window->attached_focus_window) + meta_window_appears_focused_changed (window); - meta_error_trap_push (window->display); - XSendEvent (window->display->xdisplay, - window->xwindow, - False, StructureNotifyMask, &event); - meta_error_trap_pop (window->display); + /* Re-grab for click to focus and raise-on-click, if necessary */ + if (meta_prefs_get_focus_mode () == C_DESKTOP_FOCUS_MODE_CLICK || + !meta_prefs_get_raise_on_click ()) + meta_display_grab_focus_window_button (window->display, window); + } } -/* +/** * meta_window_get_icon_geometry: * @window: a #MetaWindow * @rect: (out): rectangle into which to store the returned geometry. @@ -7845,7 +5414,7 @@ meta_window_get_icon_geometry (MetaWindow *window, /** * meta_window_set_icon_geometry: * @window: a #MetaWindow - * @rect: (allow-none): rectangle with the desired geometry or %NULL. + * @rect: (nullable): rectangle with the desired geometry or %NULL. * * Sets or unsets the location of the icon corresponding to the window. If * set, the location should correspond to a dock, task bar or other user @@ -7866,262 +5435,101 @@ meta_window_set_icon_geometry (MetaWindow *window, } } -static Window -read_client_leader (MetaDisplay *display, - Window xwindow) -{ - Window retval = None; - - meta_prop_get_window (display, xwindow, - display->atom_WM_CLIENT_LEADER, - &retval); - - return retval; -} - -typedef struct -{ - Window leader; -} ClientLeaderData; - -static gboolean -find_client_leader_func (MetaWindow *ancestor, - void *data) -{ - ClientLeaderData *d; - - d = data; - - d->leader = read_client_leader (ancestor->display, - ancestor->xwindow); - - /* keep going if no client leader found */ - return d->leader == None; -} - static void -update_sm_hints (MetaWindow *window) +redraw_icon (MetaWindow *window) { - Window leader; - - window->xclient_leader = None; - window->sm_client_id = NULL; - - /* If not on the current window, we can get the client - * leader from transient parents. If we find a client - * leader, we read the SM_CLIENT_ID from it. + /* We could probably be smart and just redraw the icon here, + * instead of the whole frame. */ - leader = read_client_leader (window->display, window->xwindow); - if (leader == None) - { - ClientLeaderData d; - d.leader = None; - meta_window_foreach_ancestor (window, find_client_leader_func, - &d); - leader = d.leader; - } - - if (leader != None) - { - char *str; - - window->xclient_leader = leader; - - if (meta_prop_get_latin1_string (window->display, leader, - window->display->atom_SM_CLIENT_ID, - &str)) - { - window->sm_client_id = g_strdup (str); - meta_XFree (str); - } - } - else - { - meta_verbose ("Didn't find a client leader for %s\n", window->desc); - - if (!meta_prefs_get_disable_workarounds ()) - { - /* Some broken apps (kdelibs fault?) set SM_CLIENT_ID on the app - * instead of the client leader - */ - char *str; - - str = NULL; - if (meta_prop_get_latin1_string (window->display, window->xwindow, - window->display->atom_SM_CLIENT_ID, - &str)) - { - if (window->sm_client_id == NULL) /* first time through */ - meta_warning ("Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER window as specified in the ICCCM.\n", - window->desc); - - window->sm_client_id = g_strdup (str); - meta_XFree (str); - } - } - } - - meta_verbose ("Window %s client leader: 0x%lx SM_CLIENT_ID: '%s'\n", - window->desc, window->xclient_leader, - window->sm_client_id ? window->sm_client_id : "none"); + if (window->frame) + meta_frame_queue_draw (window->frame); } -LOCAL_SYMBOL void -meta_window_update_role (MetaWindow *window) +static void +meta_window_update_icon_now (MetaWindow *window, + gboolean force) { - char *str; + gboolean changed; + cairo_surface_t *icon = NULL; + cairo_surface_t *mini_icon; g_return_if_fail (!window->override_redirect); - if (window->role) - free (window->role); - window->role = NULL; - - if (meta_prop_get_latin1_string (window->display, window->xwindow, - window->display->atom_WM_WINDOW_ROLE, - &str)) - { - window->role = g_strdup (str); - meta_XFree (str); - } - - meta_verbose ("Updated role of %s to '%s'\n", - window->desc, window->role ? window->role : "null"); -} - -LOCAL_SYMBOL void -meta_window_update_net_wm_type (MetaWindow *window) -{ - int n_atoms; - Atom *atoms; - int i; - - window->type_atom = None; - n_atoms = 0; - atoms = NULL; - - meta_prop_get_atom_list (window->display, window->xwindow, - window->display->atom__NET_WM_WINDOW_TYPE, - &atoms, &n_atoms); - - i = 0; - while (i < n_atoms) - { - /* We break as soon as we find one we recognize, - * supposed to prefer those near the front of the list - */ - if (atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DESKTOP || - atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DOCK || - atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_TOOLBAR || - atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_MENU || - atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_UTILITY || - atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_SPLASH || - atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DIALOG || - atoms[i] == - window->display->atom__NET_WM_WINDOW_TYPE_DROPDOWN_MENU || - atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_POPUP_MENU || - atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_TOOLTIP || - atoms[i] == - window->display->atom__NET_WM_WINDOW_TYPE_NOTIFICATION || - atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_COMBO || - atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DND || - atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_NORMAL) - { - window->type_atom = atoms[i]; - break; - } - - ++i; - } - - meta_XFree (atoms); + changed = META_WINDOW_GET_CLASS (window)->update_icon (window, &icon, &mini_icon); - if (meta_is_verbose ()) + if (changed || force) { - char *str; + if (window->icon) + cairo_surface_destroy (window->icon); + window->icon = icon; - str = NULL; - if (window->type_atom != None) - { - meta_error_trap_push (window->display); - str = XGetAtomName (window->display->xdisplay, window->type_atom); - meta_error_trap_pop (window->display); - } + if (window->mini_icon) + cairo_surface_destroy (window->mini_icon); + window->mini_icon = mini_icon; - meta_verbose ("Window %s type atom %s\n", window->desc, - str ? str : "(none)"); + g_object_freeze_notify (G_OBJECT (window)); + g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_ICON]); + g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_MINI_ICON]); + g_object_thaw_notify (G_OBJECT (window)); - if (str) - meta_XFree (str); + redraw_icon (window); } - - meta_window_recalc_window_type (window); -} - -void -meta_window_icon_changed (MetaWindow *window) -{ - g_clear_object (&window->icon); - g_signal_emit (window, window_signals[ICON_CHANGED], 0, window); } -/** - * meta_window_create_icon: - * @window: a #MetaWindow - * @size: icon width and height - * - * Creates an icon for @window. This is intended to only be used for - * window-backed apps. - * - * Return value: (transfer none): a #GdkPixbuf, or NULL. - */ -GdkPixbuf * -meta_window_create_icon (MetaWindow *window, - int size) +static gboolean +idle_update_icon (gpointer data) { - GdkPixbuf *icon; + GSList *tmp; + GSList *copy; + guint queue_index = GPOINTER_TO_INT (data); - if (window->override_redirect) - return NULL; + meta_topic (META_DEBUG_GEOMETRY, "Clearing the update_icon queue\n"); - if (window->icon) - return window->icon; + /* Work with a copy, for reentrancy. The allowed reentrancy isn't + * complete; destroying a window while we're in here would result in + * badness. But it's OK to queue/unqueue update_icons. + */ + copy = g_slist_copy (queue_pending[queue_index]); + g_slist_free (queue_pending[queue_index]); + queue_pending[queue_index] = NULL; + queue_later[queue_index] = 0; - icon = NULL; + destroying_windows_disallowed += 1; - if (meta_read_icons (window->screen, - window->xwindow, - &window->icon_cache, - window->wm_hints_pixmap, - window->wm_hints_mask, - &icon, - size, size)) + tmp = copy; + while (tmp != NULL) { - /* Cinnamon is handling the fallback icon case in CinnamonApp */ - if (icon == NULL) - return NULL; + MetaWindow *window; - if (window->icon) - g_object_unref (G_OBJECT (window->icon)); + window = tmp->data; - window->icon = icon; - window->icon_size = size; + meta_window_update_icon_now (window, FALSE); + window->is_in_queues &= ~META_QUEUE_UPDATE_ICON; - return icon; + tmp = tmp->next; } - return NULL; + g_slist_free (copy); + + destroying_windows_disallowed -= 1; + + return FALSE; } -LOCAL_SYMBOL GList* +GList* meta_window_get_workspaces (MetaWindow *window) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; + if (window->on_all_workspaces) - return window->screen->workspaces; + return workspace_manager->workspaces; else if (window->workspace != NULL) return window->workspace->list_containing_self; - else + else if (window->constructing) return NULL; + else + g_assert_not_reached (); + return NULL; } static void @@ -8141,324 +5549,52 @@ invalidate_work_areas (MetaWindow *window) void meta_window_update_struts (MetaWindow *window) { - GSList *old_struts; - GSList *new_struts; - GSList *old_iter, *new_iter; - gulong *struts = NULL; - int nitems; - gboolean changed; - - g_return_if_fail (!window->override_redirect); - - meta_verbose ("Updating struts for %s\n", window->desc); - - old_struts = window->struts; - new_struts = NULL; - - if (meta_prop_get_cardinal_list (window->display, - window->xwindow, - window->display->atom__NET_WM_STRUT_PARTIAL, - &struts, &nitems)) - { - if (nitems != 12) - meta_verbose ("_NET_WM_STRUT_PARTIAL on %s has %d values instead " - "of 12\n", - window->desc, nitems); - else - { - /* Pull out the strut info for each side in the hint */ - int i; - for (i=0; i<4; i++) - { - MetaStrut *temp; - int thickness, strut_begin, strut_end; - - thickness = struts[i]; - if (thickness == 0) - continue; - strut_begin = struts[4+(i*2)]; - strut_end = struts[4+(i*2)+1]; - - temp = g_new (MetaStrut, 1); - temp->side = 1 << i; /* See MetaSide def. Matches nicely, eh? */ - temp->rect = window->screen->rect; - switch (temp->side) - { - case META_SIDE_RIGHT: - temp->rect.x = BOX_RIGHT(temp->rect) - thickness; - /* Intentionally fall through without breaking */ - case META_SIDE_LEFT: - temp->rect.width = thickness; - temp->rect.y = strut_begin; - temp->rect.height = strut_end - strut_begin + 1; - break; - case META_SIDE_BOTTOM: - temp->rect.y = BOX_BOTTOM(temp->rect) - thickness; - /* Intentionally fall through without breaking */ - case META_SIDE_TOP: - temp->rect.height = thickness; - temp->rect.x = strut_begin; - temp->rect.width = strut_end - strut_begin + 1; - break; - default: - g_assert_not_reached (); - } - - new_struts = g_slist_prepend (new_struts, temp); - } - - meta_verbose ("_NET_WM_STRUT_PARTIAL struts %lu %lu %lu %lu for " - "window %s\n", - struts[0], struts[1], struts[2], struts[3], - window->desc); - } - meta_XFree (struts); - } - else - { - meta_verbose ("No _NET_WM_STRUT property for %s\n", - window->desc); - } - - if (!new_struts && - meta_prop_get_cardinal_list (window->display, - window->xwindow, - window->display->atom__NET_WM_STRUT, - &struts, &nitems)) - { - if (nitems != 4) - meta_verbose ("_NET_WM_STRUT on %s has %d values instead of 4\n", - window->desc, nitems); - else - { - /* Pull out the strut info for each side in the hint */ - int i; - for (i=0; i<4; i++) - { - MetaStrut *temp; - int thickness; - - thickness = struts[i]; - if (thickness == 0) - continue; - - temp = g_new (MetaStrut, 1); - temp->side = 1 << i; - temp->rect = window->screen->rect; - switch (temp->side) - { - case META_SIDE_RIGHT: - temp->rect.x = BOX_RIGHT(temp->rect) - thickness; - /* Intentionally fall through without breaking */ - case META_SIDE_LEFT: - temp->rect.width = thickness; - break; - case META_SIDE_BOTTOM: - temp->rect.y = BOX_BOTTOM(temp->rect) - thickness; - /* Intentionally fall through without breaking */ - case META_SIDE_TOP: - temp->rect.height = thickness; - break; - default: - g_assert_not_reached (); - } - - new_struts = g_slist_prepend (new_struts, temp); - } - - meta_verbose ("_NET_WM_STRUT struts %lu %lu %lu %lu for window %s\n", - struts[0], struts[1], struts[2], struts[3], - window->desc); - } - meta_XFree (struts); - } - else if (!new_struts) - { - meta_verbose ("No _NET_WM_STRUT property for %s\n", - window->desc); - } - - /* Determine whether old_struts and new_struts are the same */ - old_iter = old_struts; - new_iter = new_struts; - while (old_iter && new_iter) - { - MetaStrut *old_strut = (MetaStrut*) old_iter->data; - MetaStrut *new_strut = (MetaStrut*) new_iter->data; - - if (old_strut->side != new_strut->side || - !meta_rectangle_equal (&old_strut->rect, &new_strut->rect)) - break; - - old_iter = old_iter->next; - new_iter = new_iter->next; - } - changed = (old_iter != NULL || new_iter != NULL); - - /* Update appropriately */ - meta_free_gslist_and_elements (old_struts); - window->struts = new_struts; - if (changed) - { - meta_topic (META_DEBUG_WORKAREA, - "Invalidating work areas of window %s due to struts update\n", - window->desc); - invalidate_work_areas (window); - } - else - { - meta_topic (META_DEBUG_WORKAREA, - "Struts on %s were unchanged\n", window->desc); - } -} - -LOCAL_SYMBOL void -meta_window_recalc_window_type (MetaWindow *window) -{ - recalc_window_type (window); + if (META_WINDOW_GET_CLASS (window)->update_struts (window)) + invalidate_work_areas (window); } static void -recalc_window_type (MetaWindow *window) -{ - MetaWindowType old_type; - - old_type = window->type; - - if (window->type_atom != None) - { - if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DESKTOP) - window->type = META_WINDOW_DESKTOP; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DOCK) - window->type = META_WINDOW_DOCK; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_TOOLBAR) - window->type = META_WINDOW_TOOLBAR; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_MENU) - window->type = META_WINDOW_MENU; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_UTILITY) - window->type = META_WINDOW_UTILITY; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_SPLASH) - window->type = META_WINDOW_SPLASHSCREEN; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DIALOG) - window->type = META_WINDOW_DIALOG; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_NORMAL) - window->type = META_WINDOW_NORMAL; - /* The below are *typically* override-redirect windows, but the spec does - * not disallow using them for managed windows. - */ - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DROPDOWN_MENU) - window->type = META_WINDOW_DROPDOWN_MENU; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_POPUP_MENU) - window->type = META_WINDOW_POPUP_MENU; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_TOOLTIP) - window->type = META_WINDOW_TOOLTIP; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_NOTIFICATION) - window->type = META_WINDOW_NOTIFICATION; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_COMBO) - window->type = META_WINDOW_COMBO; - else if (window->type_atom == window->display->atom__NET_WM_WINDOW_TYPE_DND) - window->type = META_WINDOW_DND; - else - { - char *atom_name; - - /* - * Fallback on a normal type, and print warning. Don't abort. - */ - window->type = META_WINDOW_NORMAL; +meta_window_type_changed (MetaWindow *window) +{ + gboolean old_decorated = window->decorated; + GObject *object = G_OBJECT (window); - meta_error_trap_push (window->display); - atom_name = XGetAtomName (window->display->xdisplay, - window->type_atom); - meta_error_trap_pop (window->display); + window->attached = meta_window_should_attach_to_parent (window); + meta_window_recalc_features (window); - meta_warning ("Unrecognized type atom [%s] set for %s \n", - atom_name ? atom_name : "unknown", - window->desc); + if (!window->override_redirect) + set_net_wm_state (window); - if (atom_name) - XFree (atom_name); - } - } - else if (window->xtransient_for != None) - { - window->type = META_WINDOW_DIALOG; - } + /* Update frame */ + if (window->decorated) + meta_window_ensure_frame (window); else - { - window->type = META_WINDOW_NORMAL; - } - - if (window->type == META_WINDOW_DIALOG && - window->wm_state_modal) - window->type = META_WINDOW_MODAL_DIALOG; - - /* We don't want to allow override-redirect windows to have decorated-window - * types since that's just confusing. - */ - if (window->override_redirect) - { - switch (window->type) - { - /* Decorated types */ - case META_WINDOW_NORMAL: - case META_WINDOW_DIALOG: - case META_WINDOW_MODAL_DIALOG: - case META_WINDOW_MENU: - case META_WINDOW_UTILITY: - window->type = META_WINDOW_OVERRIDE_OTHER; - break; - /* Undecorated types, normally not override-redirect */ - case META_WINDOW_DESKTOP: - case META_WINDOW_DOCK: - case META_WINDOW_TOOLBAR: - case META_WINDOW_SPLASHSCREEN: - /* Undecorated types, normally override-redirect types */ - case META_WINDOW_DROPDOWN_MENU: - case META_WINDOW_POPUP_MENU: - case META_WINDOW_TOOLTIP: - case META_WINDOW_NOTIFICATION: - case META_WINDOW_COMBO: - case META_WINDOW_DND: - /* To complete enum */ - case META_WINDOW_OVERRIDE_OTHER: - break; - } - } - - meta_verbose ("Calculated type %u for %s, old type %u\n", - window->type, window->desc, old_type); + meta_window_destroy_frame (window); - if (old_type != window->type) - { - gboolean old_decorated = window->decorated; - GObject *object = G_OBJECT (window); - - recalc_window_features (window); - - if (!window->override_redirect) - set_net_wm_state (window); + /* update stacking constraints */ + meta_window_update_layer (window); - /* Update frame */ - if (window->decorated) - meta_window_ensure_frame (window); - else - meta_window_destroy_frame (window); + meta_window_grab_keys (window); - /* update stacking constraints */ - meta_window_update_layer (window); + g_object_freeze_notify (object); - meta_window_grab_keys (window); + if (old_decorated != window->decorated) + g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_DECORATED]); - g_object_freeze_notify (object); + g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_WINDOW_TYPE]); - if (old_decorated != window->decorated) - g_object_notify (object, "decorated"); + g_object_thaw_notify (object); +} - g_object_notify (object, "window-type"); +void +meta_window_set_type (MetaWindow *window, + MetaWindowType type) +{ + if (window->type == type) + return; - g_object_thaw_notify (object); - } + window->type = type; + meta_window_type_changed (window); } void @@ -8469,84 +5605,59 @@ meta_window_frame_size_changed (MetaWindow *window) } static void -set_allowed_actions_hint (MetaWindow *window) +meta_window_get_default_skip_hints (MetaWindow *window, + gboolean *skip_taskbar_out, + gboolean *skip_pager_out) { -#define MAX_N_ACTIONS 12 - unsigned long data[MAX_N_ACTIONS]; - int i; - - i = 0; - if (window->has_move_func) - { - data[i] = window->display->atom__NET_WM_ACTION_MOVE; - ++i; - } - if (window->has_resize_func) - { - data[i] = window->display->atom__NET_WM_ACTION_RESIZE; - ++i; - } - if (window->has_fullscreen_func) - { - data[i] = window->display->atom__NET_WM_ACTION_FULLSCREEN; - ++i; - } - if (window->has_minimize_func) - { - data[i] = window->display->atom__NET_WM_ACTION_MINIMIZE; - ++i; - } - if (window->has_shade_func) - { - data[i] = window->display->atom__NET_WM_ACTION_SHADE; - ++i; - } - /* sticky according to EWMH is different from muffin's sticky; - * muffin doesn't support EWMH sticky - */ - if (window->has_maximize_func) - { - data[i] = window->display->atom__NET_WM_ACTION_MAXIMIZE_HORZ; - ++i; - data[i] = window->display->atom__NET_WM_ACTION_MAXIMIZE_VERT; - ++i; - } - /* We always allow this */ - data[i] = window->display->atom__NET_WM_ACTION_CHANGE_DESKTOP; - ++i; - if (window->has_close_func) - { - data[i] = window->display->atom__NET_WM_ACTION_CLOSE; - ++i; - } - - /* I guess we always allow above/below operations */ - data[i] = window->display->atom__NET_WM_ACTION_ABOVE; - ++i; - data[i] = window->display->atom__NET_WM_ACTION_BELOW; - ++i; + META_WINDOW_GET_CLASS (window)->get_default_skip_hints (window, skip_taskbar_out, skip_pager_out); +} - g_assert (i <= MAX_N_ACTIONS); +static void +meta_window_recalc_skip_features (MetaWindow *window) +{ + switch (window->type) + { + /* Force skip taskbar/pager on these window types */ + case META_WINDOW_DESKTOP: + case META_WINDOW_DOCK: + case META_WINDOW_TOOLBAR: + case META_WINDOW_MENU: + case META_WINDOW_UTILITY: + case META_WINDOW_SPLASHSCREEN: + case META_WINDOW_DROPDOWN_MENU: + case META_WINDOW_POPUP_MENU: + case META_WINDOW_TOOLTIP: + case META_WINDOW_NOTIFICATION: + case META_WINDOW_COMBO: + case META_WINDOW_DND: + case META_WINDOW_OVERRIDE_OTHER: + window->skip_taskbar = TRUE; + window->skip_pager = TRUE; + break; - meta_verbose ("Setting _NET_WM_ALLOWED_ACTIONS with %d atoms\n", i); + case META_WINDOW_DIALOG: + case META_WINDOW_MODAL_DIALOG: + /* only skip taskbar if we have a real transient parent + (and ignore the application hints) */ + if (window->transient_for != NULL) + window->skip_taskbar = TRUE; + else + window->skip_taskbar = FALSE; + break; - meta_error_trap_push (window->display); - XChangeProperty (window->display->xdisplay, window->xwindow, - window->display->atom__NET_WM_ALLOWED_ACTIONS, - XA_ATOM, - 32, PropModeReplace, (guchar*) data, i); - meta_error_trap_pop (window->display); -#undef MAX_N_ACTIONS + case META_WINDOW_NORMAL: + { + gboolean skip_taskbar_hint, skip_pager_hint; + meta_window_get_default_skip_hints (window, &skip_taskbar_hint, &skip_pager_hint); + window->skip_taskbar = skip_taskbar_hint; + window->skip_pager = skip_pager_hint; + } + break; + } } -LOCAL_SYMBOL void +void meta_window_recalc_features (MetaWindow *window) -{ - recalc_window_features (window); -} - -static void -recalc_window_features (MetaWindow *window) { gboolean old_has_close_func; gboolean old_has_minimize_func; @@ -8565,7 +5676,10 @@ recalc_window_features (MetaWindow *window) old_skip_taskbar = window->skip_taskbar; /* Use MWM hints initially */ - window->decorated = window->mwm_decorated; + if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) + window->decorated = window->mwm_decorated; + else + window->decorated = FALSE; window->border_only = window->mwm_border_only; window->has_close_func = window->mwm_has_close_func; window->has_minimize_func = window->mwm_has_minimize_func; @@ -8605,9 +5719,6 @@ recalc_window_features (MetaWindow *window) if (window->type == META_WINDOW_TOOLBAR) window->decorated = FALSE; - if (meta_window_is_attached_dialog (window)) - window->border_only = TRUE; - if (window->type == META_WINDOW_DESKTOP || window->type == META_WINDOW_DOCK || window->override_redirect) @@ -8642,13 +5753,17 @@ recalc_window_features (MetaWindow *window) if (!window->has_resize_func) { window->has_maximize_func = FALSE; + MetaRectangle display_rect = { 0 }; + + meta_display_get_size (window->display, &display_rect.width, + &display_rect.height); /* don't allow fullscreen if we can't resize, unless the size * is entire screen size (kind of broken, because we * actually fullscreen to monitor size not screen size) */ - if (window->size_hints.min_width == window->screen->rect.width && - window->size_hints.min_height == window->screen->rect.height) + if (window->size_hints.min_width == display_rect.width && + window->size_hints.min_height == display_rect.height) ; /* leave fullscreen available */ else window->has_fullscreen_func = FALSE; @@ -8670,20 +5785,15 @@ recalc_window_features (MetaWindow *window) window->has_maximize_func = FALSE; } - if (window->has_maximize_func) + if (window->has_maximize_func && window->monitor) { - MetaRectangle work_area; - MetaFrameBorders borders; - int min_frame_width, min_frame_height; + MetaRectangle work_area, client_rect; meta_window_get_work_area_current_monitor (window, &work_area); - meta_frame_calc_borders (window->frame, &borders); + meta_window_frame_rect_to_client_rect (window, &work_area, &client_rect); - min_frame_width = window->size_hints.min_width + borders.visible.left + borders.visible.right; - min_frame_height = window->size_hints.min_height + borders.visible.top + borders.visible.bottom; - - if (min_frame_width >= work_area.width || - min_frame_height >= work_area.height) + if (window->size_hints.min_width >= client_rect.width || + window->size_hints.min_height >= client_rect.height) window->has_maximize_func = FALSE; } @@ -8701,46 +5811,12 @@ recalc_window_features (MetaWindow *window) if (!window->decorated || window->border_only) window->has_shade_func = FALSE; - window->skip_taskbar = FALSE; - window->skip_pager = FALSE; - - if (window->wm_state_skip_taskbar) - window->skip_taskbar = TRUE; - - if (window->wm_state_skip_pager) - window->skip_pager = TRUE; - - switch (window->type) - { - /* Force skip taskbar/pager on these window types */ - case META_WINDOW_DESKTOP: - case META_WINDOW_DOCK: - case META_WINDOW_TOOLBAR: - case META_WINDOW_MENU: - case META_WINDOW_UTILITY: - case META_WINDOW_SPLASHSCREEN: - case META_WINDOW_DROPDOWN_MENU: - case META_WINDOW_POPUP_MENU: - case META_WINDOW_TOOLTIP: - case META_WINDOW_NOTIFICATION: - case META_WINDOW_COMBO: - case META_WINDOW_DND: - case META_WINDOW_OVERRIDE_OTHER: - window->skip_taskbar = TRUE; - window->skip_pager = TRUE; - break; - - case META_WINDOW_DIALOG: - case META_WINDOW_MODAL_DIALOG: - /* only skip taskbar if we have a real transient parent */ - if (window->xtransient_for != None && - window->xtransient_for != window->screen->xroot) - window->skip_taskbar = TRUE; - break; + meta_window_recalc_skip_features (window); - case META_WINDOW_NORMAL: - break; - } + /* To prevent users from losing windows, let's prevent users from + * minimizing skip-taskbar windows through the window decorations. */ + if (window->skip_taskbar) + window->has_minimize_func = FALSE; meta_topic (META_DEBUG_WINDOW_OPS, "Window %s decorated = %d border_only = %d has_close = %d has_minimize = %d has_maximize = %d has_move = %d has_shade = %d skip_taskbar = %d skip_pager = %d\n", @@ -8755,11 +5831,13 @@ recalc_window_features (MetaWindow *window) window->skip_taskbar, window->skip_pager); + if (old_skip_taskbar != window->skip_taskbar) + g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_SKIP_TASKBAR]); + /* FIXME: - * Lame workaround for recalc_window_features - * being used overzealously. The fix is to - * only recalc_window_features when something - * has actually changed. + * Lame workaround for recalc_features being used overzealously. + * The fix is to only recalc_features when something has + * actually changed. */ if (window->constructing || old_has_close_func != window->has_close_func || @@ -8771,318 +5849,41 @@ recalc_window_features (MetaWindow *window) set_allowed_actions_hint (window); if (window->has_resize_func != old_has_resize_func) - g_object_notify (G_OBJECT (window), "resizeable"); + g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_RESIZEABLE]); meta_window_frame_size_changed (window); - if (old_skip_taskbar != window->skip_taskbar) - g_signal_emit_by_name (window->screen, "window-skip-taskbar-changed", window); - /* FIXME perhaps should ensure if we don't have a shade func, * we aren't shaded, etc. */ } -static void -menu_callback (MetaWindowMenu *menu, - Display *xdisplay, - Window client_xwindow, - guint32 timestamp, - MetaMenuOp op, - int workspace_index, - gpointer data) +void +meta_window_show_menu (MetaWindow *window, + MetaWindowMenuType menu, + int x, + int y) { - MetaDisplay *display; - MetaWindow *window; - MetaWorkspace *workspace; - - display = meta_display_for_x_display (xdisplay); - window = meta_display_lookup_x_window (display, client_xwindow); - workspace = NULL; - - if (window != NULL) /* window can be NULL */ - { - meta_verbose ("Menu op %u on %s\n", op, window->desc); - - switch (op) - { - case META_MENU_OP_NONE: - /* nothing */ - break; - - case META_MENU_OP_DELETE: - meta_window_delete (window, timestamp); - break; - - case META_MENU_OP_MINIMIZE: - meta_window_minimize (window); - break; - - case META_MENU_OP_UNMAXIMIZE: - meta_window_unmaximize (window, - META_MAXIMIZE_HORIZONTAL | - META_MAXIMIZE_VERTICAL); - break; - - case META_MENU_OP_MAXIMIZE: - meta_window_maximize (window, - META_MAXIMIZE_HORIZONTAL | - META_MAXIMIZE_VERTICAL); - break; - - case META_MENU_OP_UNSHADE: - meta_window_unshade (window, timestamp); - break; - - case META_MENU_OP_SHADE: - meta_window_shade (window, timestamp); - break; - - case META_MENU_OP_MOVE_LEFT: - workspace = meta_workspace_get_neighbor (window->screen->active_workspace, - META_MOTION_LEFT); - break; - - case META_MENU_OP_MOVE_RIGHT: - workspace = meta_workspace_get_neighbor (window->screen->active_workspace, - META_MOTION_RIGHT); - break; - - case META_MENU_OP_MOVE_UP: - workspace = meta_workspace_get_neighbor (window->screen->active_workspace, - META_MOTION_UP); - break; - - case META_MENU_OP_MOVE_DOWN: - workspace = meta_workspace_get_neighbor (window->screen->active_workspace, - META_MOTION_DOWN); - break; - - case META_MENU_OP_WORKSPACES: - workspace = meta_screen_get_workspace_by_index (window->screen, - workspace_index); - break; - - case META_MENU_OP_MOVE_NEW: - workspace = meta_screen_append_new_workspace (window->screen, FALSE, timestamp); - GSettings *cinnamon = g_settings_new ("org.cinnamon"); - g_settings_set_int (cinnamon, "number-workspaces", g_list_length (window->screen->workspaces)); - g_object_unref (cinnamon); - break; - - case META_MENU_OP_STICK: - meta_window_stick (window); - break; - - case META_MENU_OP_UNSTICK: - meta_window_unstick (window); - break; - - case META_MENU_OP_ABOVE: - case META_MENU_OP_UNABOVE: - if (window->wm_state_above == FALSE) - meta_window_make_above (window); - else - meta_window_unmake_above (window); - break; - - case META_MENU_OP_MOVE: - meta_window_begin_grab_op (window, - META_GRAB_OP_KEYBOARD_MOVING, - TRUE, - timestamp); - break; - - case META_MENU_OP_RESIZE: - if (window->tile_mode != META_TILE_NONE) - { - window->resize_tile_mode = window->tile_mode; - window->resizing_tile_type = window->tile_type; - } - - meta_window_begin_grab_op (window, - META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN, - TRUE, - timestamp); - break; - - case META_MENU_OP_RECOVER: - meta_window_shove_titlebar_onscreen (window); - break; - - default: - meta_warning (G_STRLOC": Unknown window op\n"); - break; - } - - if (workspace) - { - meta_window_change_workspace (window, - workspace); -#if 0 - meta_workspace_activate (workspace); - meta_window_raise (window); -#endif - } - } - else - { - meta_verbose ("Menu callback on nonexistent window\n"); - } - - if (display->window_menu == menu) - { - display->window_menu = NULL; - display->window_with_menu = NULL; - } - - meta_ui_window_menu_free (menu); + g_return_if_fail (!window->override_redirect); + meta_compositor_show_window_menu (window->display->compositor, window, menu, x, y); } -LOCAL_SYMBOL void -meta_window_show_menu (MetaWindow *window, - int root_x, - int root_y, - int button, - guint32 timestamp) +void +meta_window_show_menu_for_rect (MetaWindow *window, + MetaWindowMenuType menu, + MetaRectangle *rect) { - MetaMenuOp ops; - MetaMenuOp insensitive; - MetaWindowMenu *menu; - MetaWorkspaceLayout layout; - int n_workspaces; - // gboolean ltr; - g_return_if_fail (!window->override_redirect); - - if (window->display->window_menu) - { - meta_ui_window_menu_free (window->display->window_menu); - window->display->window_menu = NULL; - window->display->window_with_menu = NULL; - } - - ops = META_MENU_OP_NONE; - insensitive = META_MENU_OP_NONE; - - //ops |= (META_MENU_OP_DELETE | META_MENU_OP_MINIMIZE | META_MENU_OP_MOVE | META_MENU_OP_RESIZE | META_MENU_OP_MOVE_NEW); - ops |= (META_MENU_OP_DELETE | META_MENU_OP_MINIMIZE | META_MENU_OP_MOVE | META_MENU_OP_RESIZE); - - if (!meta_window_is_client_decorated (window) && - !meta_window_titlebar_is_onscreen (window) && - window->type != META_WINDOW_DOCK && - window->type != META_WINDOW_DESKTOP) - ops |= META_MENU_OP_RECOVER; - - if (!meta_prefs_get_workspaces_only_on_primary () || - meta_window_is_on_primary_monitor (window)) - { - n_workspaces = meta_screen_get_n_workspaces (window->screen); - - if (n_workspaces > 1) - ops |= META_MENU_OP_WORKSPACES; - - meta_screen_calc_workspace_layout (window->screen, - n_workspaces, - meta_workspace_index ( window->screen->active_workspace), - &layout); - - // if (!window->on_all_workspaces) - // { - // ltr = meta_ui_get_direction() == META_UI_DIRECTION_LTR; - - // if (layout.current_col > 0) - // ops |= ltr ? META_MENU_OP_MOVE_LEFT : META_MENU_OP_MOVE_RIGHT; - // if ((layout.current_col < layout.cols - 1) && - // (layout.current_row * layout.cols + (layout.current_col + 1) < n_workspaces)) - // ops |= ltr ? META_MENU_OP_MOVE_RIGHT : META_MENU_OP_MOVE_LEFT; - // if (layout.current_row > 0) - // ops |= META_MENU_OP_MOVE_UP; - // if ((layout.current_row < layout.rows - 1) && - // ((layout.current_row + 1) * layout.cols + layout.current_col < n_workspaces)) - // ops |= META_MENU_OP_MOVE_DOWN; - // } - - meta_screen_free_workspace_layout (&layout); - - ops |= META_MENU_OP_UNSTICK; - ops |= META_MENU_OP_STICK; - } - - if (META_WINDOW_MAXIMIZED (window)) - ops |= META_MENU_OP_UNMAXIMIZE; - else - ops |= META_MENU_OP_MAXIMIZE; - -#if 0 - if (window->shaded) - ops |= META_MENU_OP_UNSHADE; - else - ops |= META_MENU_OP_SHADE; -#endif - - if (window->wm_state_above) - ops |= META_MENU_OP_UNABOVE; - else - ops |= META_MENU_OP_ABOVE; - - if (!window->has_maximize_func) - insensitive |= META_MENU_OP_UNMAXIMIZE | META_MENU_OP_MAXIMIZE; - - if (!window->has_minimize_func) - insensitive |= META_MENU_OP_MINIMIZE; - - if (!window->has_close_func) - insensitive |= META_MENU_OP_DELETE; - - if (!window->has_shade_func) - insensitive |= META_MENU_OP_SHADE | META_MENU_OP_UNSHADE; - - if (!META_WINDOW_ALLOWS_MOVE (window)) - insensitive |= META_MENU_OP_MOVE; - - if (!META_WINDOW_ALLOWS_RESIZE (window)) - insensitive |= META_MENU_OP_RESIZE; - - if (window->always_sticky) - insensitive |= META_MENU_OP_STICK | META_MENU_OP_UNSTICK | META_MENU_OP_WORKSPACES; - - if ((window->type == META_WINDOW_DESKTOP) || - (window->type == META_WINDOW_DOCK) || - (window->type == META_WINDOW_SPLASHSCREEN)) - insensitive |= META_MENU_OP_ABOVE | META_MENU_OP_UNABOVE; - - /* If all operations are disabled, just quit without showing the menu. - * This is the case, for example, with META_WINDOW_DESKTOP windows. - */ - if ((ops & ~insensitive) == 0) - return; - - menu = - meta_ui_window_menu_new (window->screen->ui, - window->xwindow, - ops, - insensitive, - meta_window_get_net_wm_desktop (window), - meta_screen_get_n_workspaces (window->screen), - menu_callback, - NULL); - - window->display->window_menu = menu; - window->display->window_with_menu = window; - - meta_verbose ("Popping up window menu for %s\n", window->desc); - - meta_ui_window_menu_popup (menu, root_x, root_y, button, timestamp); + meta_compositor_show_window_menu_for_rect (window->display->compositor, window, menu, rect); } -LOCAL_SYMBOL void +void meta_window_shove_titlebar_onscreen (MetaWindow *window) { - MetaRectangle outer_rect; + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; + MetaRectangle frame_rect; GList *onscreen_region; int horiz_amount, vert_amount; - int newx, newy; g_return_if_fail (!window->override_redirect); @@ -9091,15 +5892,15 @@ meta_window_shove_titlebar_onscreen (MetaWindow *window) return; /* Get the basic info we need */ - meta_window_get_outer_rect (window, &outer_rect); - onscreen_region = window->screen->active_workspace->screen_region; + meta_window_get_frame_rect (window, &frame_rect); + onscreen_region = workspace_manager->active_workspace->screen_region; /* Extend the region (just in case the window is too big to fit on the * screen), then shove the window on screen, then return the region to * normal. */ - horiz_amount = outer_rect.width; - vert_amount = outer_rect.height; + horiz_amount = frame_rect.width; + vert_amount = frame_rect.height; meta_rectangle_expand_region (onscreen_region, horiz_amount, horiz_amount, @@ -9107,47 +5908,45 @@ meta_window_shove_titlebar_onscreen (MetaWindow *window) vert_amount); meta_rectangle_shove_into_region(onscreen_region, FIXED_DIRECTION_X, - &outer_rect); + &frame_rect); meta_rectangle_expand_region (onscreen_region, -horiz_amount, -horiz_amount, 0, -vert_amount); - newx = outer_rect.x + window->frame->child_x; - newy = outer_rect.y + window->frame->child_y; - meta_window_move_resize (window, - FALSE, - newx, - newy, - window->rect.width, - window->rect.height); + meta_window_move_frame (window, FALSE, frame_rect.x, frame_rect.y); } -LOCAL_SYMBOL gboolean +gboolean meta_window_titlebar_is_onscreen (MetaWindow *window) { - MetaRectangle titlebar_rect; + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; + MetaRectangle titlebar_rect, frame_rect; GList *onscreen_region; gboolean is_onscreen; const int min_height_needed = 8; - const int min_width_percent = 0.5; + const float min_width_percent = 0.5; const int min_width_absolute = 50; /* Titlebar can't be offscreen if there is no titlebar... */ if (!window->frame) - return FALSE; + return TRUE; /* Get the rectangle corresponding to the titlebar */ - meta_window_get_outer_rect (window, &titlebar_rect); - titlebar_rect.height = window->frame->child_y; + meta_window_get_titlebar_rect (window, &titlebar_rect); + + /* Translate into screen coordinates */ + meta_window_get_frame_rect (window, &frame_rect); + titlebar_rect.x = frame_rect.x; + titlebar_rect.y = frame_rect.y; /* Run through the spanning rectangles for the screen and see if one of * them overlaps with the titlebar sufficiently to consider it onscreen. */ is_onscreen = FALSE; - onscreen_region = window->screen->active_workspace->screen_region; + onscreen_region = workspace_manager->active_workspace->screen_region; while (onscreen_region) { MetaRectangle *spanning_rect = onscreen_region->data; @@ -9168,42 +5967,24 @@ meta_window_titlebar_is_onscreen (MetaWindow *window) return is_onscreen; } -static double -timeval_to_ms (const GTimeVal *timeval) -{ - return (timeval->tv_sec * G_USEC_PER_SEC + timeval->tv_usec) / 1000.0; -} - -static double -time_diff (const GTimeVal *first, - const GTimeVal *second) -{ - double first_ms = timeval_to_ms (first); - double second_ms = timeval_to_ms (second); - - return first_ms - second_ms; -} - static gboolean check_moveresize_frequency (MetaWindow *window, gdouble *remaining) { - GTimeVal current_time; + int64_t current_time; const double max_resizes_per_second = 25.0; const double ms_between_resizes = 1000.0 / max_resizes_per_second; double elapsed; - g_get_current_time (¤t_time); + current_time = g_get_real_time (); -#ifdef HAVE_XSYNC /* If we are throttling via _NET_WM_SYNC_REQUEST, we don't need * an artificial timeout-based throttled */ if (!window->disable_sync && window->sync_request_alarm != None) return TRUE; -#endif /* HAVE_XSYNC */ - elapsed = time_diff (¤t_time, &window->display->grab_last_moveresize_time); + elapsed = (current_time - window->display->grab_last_moveresize_time) / 1000; if (elapsed >= 0.0 && elapsed < ms_between_resizes) { @@ -9217,11 +5998,11 @@ check_moveresize_frequency (MetaWindow *window, return FALSE; } - meta_topic (META_DEBUG_RESIZING, - " Checked moveresize freq, allowing move/resize now (%g of %g seconds elapsed)\n", - elapsed / 1000.0, 1.0 / max_resizes_per_second); + meta_topic (META_DEBUG_RESIZING, + " Checked moveresize freq, allowing move/resize now (%g of %g seconds elapsed)\n", + elapsed / 1000.0, 1.0 / max_resizes_per_second); - return TRUE; + return TRUE; } static gboolean @@ -9231,142 +6012,77 @@ update_move_timeout (gpointer data) update_move (window, window->display->grab_last_user_action_was_snap, - window->snap_queued, window->display->grab_latest_motion_x, window->display->grab_latest_motion_y); return FALSE; } -guint -meta_window_get_current_zone (MetaWindow *window, - MetaRectangle monitor, - MetaRectangle work_area, - int x, - int y, - int zone_threshold) -{ - TileZone edge_zone = 0; - guint zone = ZONE_NONE; - /* First, establish edges, with top and bottom first, - so they take priority in the corners */ - if (y >= monitor.y && y <= work_area.y + zone_threshold) - edge_zone |= ZONE_TOP; - if (y >= (work_area.y + work_area.height - zone_threshold) && - y < (monitor.y + monitor.height)) - edge_zone |= ZONE_BOTTOM; - if (x >= monitor.x && x < (work_area.x + zone_threshold)) - edge_zone |= ZONE_LEFT; - if (x >= (work_area.x + work_area.width - zone_threshold) && - x < (monitor.x + monitor.width)) - edge_zone |= ZONE_RIGHT; - - /* Now for each edge zone, we can figure out the specific subzone we're in */ - - /* split the screen into a 4 x 4 grid.. the middle 2 boxes along each edge - are considered a single zone though, so effectively we'll have 3 zones per - edge */ - - switch (edge_zone) { - case ZONE_ULC: - if (meta_window_can_tile_corner (window)) - zone = ZONE_4; - break; - case ZONE_LLC: - if (meta_window_can_tile_corner (window)) - zone = ZONE_7; - break; - case ZONE_URC: - if (meta_window_can_tile_corner (window)) - zone = ZONE_5; - break; - case ZONE_LRC: - if (meta_window_can_tile_corner (window)) - zone = ZONE_6; - break; - case ZONE_TOP: - if (meta_prefs_get_tile_maximize() || window->maybe_retile_maximize) - { - if (meta_window_can_tile_maximized(window)) - zone = ZONE_0; - } - else if (meta_window_can_tile_top_bottom (window)) - zone = ZONE_0; - break; - case ZONE_BOTTOM: - if (meta_window_can_tile_top_bottom (window)) - zone = ZONE_1; - break; - case ZONE_LEFT: - if (meta_window_can_tile_side_by_side (window)) - zone = ZONE_2; - break; - case ZONE_RIGHT: - if (meta_window_can_tile_side_by_side (window)) - zone = ZONE_3; - break; - default: - zone = ZONE_NONE; - break; - } - return zone; -} +static void +update_move_maybe_tile (MetaWindow *window, + int shake_threshold, + int x, + int y) +{ + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaLogicalMonitor *logical_monitor; + MetaDisplay *display = window->display; + MetaRectangle work_area; -static unsigned int -get_mask_from_snap_keysym (MetaWindow *window) -{ - unsigned int *pref = meta_prefs_get_snap_modifier (); + /* For side-by-side tiling we are interested in the inside vertical + * edges of the work area of the monitor where the pointer is located, + * and in the outside top edge for maximized tiling. + * + * For maximized tiling we use the outside edge instead of the + * inside edge, because we don't want to force users to maximize + * windows they are placing near the top of their screens. + * + * The "current" idea of meta_window_get_work_area_current_monitor() and + * meta_screen_get_current_monitor() is slightly different: the former + * refers to the monitor which contains the largest part of the window, + * the latter to the one where the pointer is located. + */ + logical_monitor = + meta_monitor_manager_get_logical_monitor_at (monitor_manager, x, y); + if (!logical_monitor) + return; - return XkbKeysymToModifiers(window->display->xdisplay, pref[0]); -} + meta_window_get_work_area_for_monitor (window, + logical_monitor->number, + &work_area); -static inline void -get_size_limits (const MetaWindow *window, - const MetaFrameBorders *borders, - gboolean include_frame, - MetaRectangle *min_size, - MetaRectangle *max_size) -{ - /* We pack the results into MetaRectangle structs just for convienience; we - * don't actually use the position of those rects. + /* Check if the cursor is in a position which triggers tiling + * and set tile_mode accordingly. */ - min_size->width = window->size_hints.min_width; - min_size->height = window->size_hints.min_height; - max_size->width = window->size_hints.max_width; - max_size->height = window->size_hints.max_height; - - if (include_frame) - { - int fw = borders->visible.left + borders->visible.right; - int fh = borders->visible.top + borders->visible.bottom; + if (meta_window_can_tile_side_by_side (window) && + x >= logical_monitor->rect.x && x < (work_area.x + shake_threshold)) + display->preview_tile_mode = META_TILE_LEFT; + else if (meta_window_can_tile_side_by_side (window) && + x >= work_area.x + work_area.width - shake_threshold && + x < (logical_monitor->rect.x + logical_monitor->rect.width)) + display->preview_tile_mode = META_TILE_RIGHT; + else if (meta_window_can_tile_maximized (window) && + y >= logical_monitor->rect.y && y <= work_area.y) + display->preview_tile_mode = META_TILE_MAXIMIZED; + else + display->preview_tile_mode = META_TILE_NONE; - min_size->width += fw; - min_size->height += fh; - /* Do check to avoid overflow (e.g. max_size->width & max_size->height - * may be set to G_MAXINT by meta_set_normal_hints()). - */ - if (max_size->width < (G_MAXINT - fw)) - max_size->width += fw; - else - max_size->width = G_MAXINT; - if (max_size->height < (G_MAXINT - fh)) - max_size->height += fh; - else - max_size->height = G_MAXINT; - } + if (display->preview_tile_mode != META_TILE_NONE) + window->tile_monitor_number = logical_monitor->number; } static void update_move (MetaWindow *window, - gboolean legacy_snap, - gboolean snap_mode, + gboolean snap, int x, int y) { int dx, dy; int new_x, new_y; MetaRectangle old; - int breakloose_threshold; + int shake_threshold; MetaDisplay *display = window->display; display->grab_latest_motion_x = x; @@ -9386,11 +6102,6 @@ update_move (MetaWindow *window, display->grab_anchor_window_pos.y, dx, dy); - if (snap_mode) - window->snap_queued = TRUE; - else - window->snap_queued = FALSE; - /* Don't bother doing anything if no move has been specified. (This * happens often, even in keyboard moving, due to the warping of the * pointer. @@ -9402,104 +6113,31 @@ update_move (MetaWindow *window, * for the zones at the sides of the monitor where trigger tiling * because it's about the right size */ +#define DRAG_THRESHOLD_TO_SHAKE_THRESHOLD_FACTOR 6 + shake_threshold = meta_prefs_get_drag_threshold () * + DRAG_THRESHOLD_TO_SHAKE_THRESHOLD_FACTOR; - if (legacy_snap && meta_prefs_get_legacy_snap ()) + if (snap) { /* We don't want to tile while snapping. Also, clear any previous tile request. */ - window->tile_mode = META_TILE_NONE; + display->preview_tile_mode = META_TILE_NONE; window->tile_monitor_number = -1; } - else if (meta_prefs_get_edge_tiling () && !META_WINDOW_TILED_OR_SNAPPED (window)) - { - const MetaMonitorInfo *monitor; - MetaRectangle work_area; - - /* For side-by-side tiling we are interested in the inside vertical - * edges of the work area of the monitor where the pointer is located, - * and in the outside top edge for maximized tiling. - * - * For maximized tiling we use the outside edge instead of the - * inside edge, because we don't want to force users to maximize - * windows they are placing near the top of their screens. - * - * The "current" idea of meta_window_get_work_area_current_monitor() and - * meta_screen_get_current_monitor() is slightly different: the former - * refers to the monitor which contains the largest part of the window, - * the latter to the one where the pointer is located. - */ - monitor = meta_screen_get_current_monitor_info (window->screen); - meta_window_get_work_area_for_monitor (window, - monitor->number, - &work_area); - - /* Check if the cursor is in a position which triggers tiling - * and set tile_mode accordingly. - */ - - window->current_proximity_zone = meta_window_get_current_zone (window, - monitor->rect, - work_area, - x, - y, - meta_prefs_get_tile_hud_threshold ()); - - guint edge_zone = meta_window_get_current_zone (window, - monitor->rect, - work_area, - x, - y, - HUD_WIDTH * meta_prefs_get_ui_scale ()); - - switch (edge_zone) { - case ZONE_0: - window->tile_mode = window->maybe_retile_maximize ? META_TILE_MAXIMIZE : - (meta_prefs_get_tile_maximize() ? META_TILE_MAXIMIZE : META_TILE_TOP); - break; - case ZONE_1: - window->tile_mode = META_TILE_BOTTOM; - break; - case ZONE_2: - window->tile_mode = META_TILE_LEFT; - break; - case ZONE_3: - window->tile_mode = META_TILE_RIGHT; - break; - case ZONE_4: - window->tile_mode = META_TILE_ULC; - break; - case ZONE_5: - window->tile_mode = META_TILE_URC; - break; - case ZONE_6: - window->tile_mode = META_TILE_LRC; - break; - case ZONE_7: - window->tile_mode = META_TILE_LLC; - break; - default: - window->tile_mode = META_TILE_NONE; - break; - } - - if (window->tile_mode != META_TILE_NONE) - window->tile_monitor_number = monitor->number; + else if (meta_prefs_get_edge_tiling () && + !META_WINDOW_MAXIMIZED (window) && + !META_WINDOW_TILED_SIDE_BY_SIDE (window)) + { + update_move_maybe_tile (window, shake_threshold, x, y); } - update_edge_constraints (window); - /* shake loose (unmaximize) maximized or tiled window if dragged beyond * the threshold in the Y direction. Tiled windows can also be pulled * loose via X motion. */ - breakloose_threshold = meta_prefs_get_resize_threshold () * 2; - if (window->tile_type == META_WINDOW_TILE_TYPE_SNAPPED) - breakloose_threshold *= 2; - if ((META_WINDOW_MAXIMIZED (window) && ABS (dy) >= breakloose_threshold) || - (META_WINDOW_MAXIMIZED_VERTICALLY (window) && ABS (dy) >= breakloose_threshold) || - (META_WINDOW_MAXIMIZED_HORIZONTALLY (window) && ABS (dx) >= breakloose_threshold) || - (META_WINDOW_TILED_OR_SNAPPED (window) && (MAX (ABS (dx), ABS (dy)) >= breakloose_threshold))) + if ((META_WINDOW_MAXIMIZED (window) && ABS (dy) >= shake_threshold) || + (META_WINDOW_TILED_SIDE_BY_SIDE (window) && (MAX (ABS (dx), ABS (dy)) >= shake_threshold))) { double prop; @@ -9508,8 +6146,6 @@ update_move (MetaWindow *window, * is enabled, as top edge tiling can be used in that case */ window->shaken_loose = !meta_prefs_get_edge_tiling (); - if (window->saved_maximize) - window->maybe_retile_maximize = TRUE; window->tile_mode = META_TILE_NONE; /* move the unmaximized window to the cursor */ @@ -9517,23 +6153,22 @@ update_move (MetaWindow *window, ((double)(x - display->grab_initial_window_pos.x)) / ((double)display->grab_initial_window_pos.width); - display->grab_initial_window_pos.x = - x - window->saved_rect.width * prop; + display->grab_initial_window_pos.x = x - window->saved_rect.width * prop; - if (window->frame) + /* If we started dragging the window from above the top of the window, + * pretend like we started dragging from the middle of the titlebar + * instead, as the "correct" anchoring looks wrong. */ + if (display->grab_anchor_root_y < display->grab_initial_window_pos.y) { - display->grab_initial_window_pos.y = y + (window->frame->child_y / 2); - display->grab_anchor_root_x = x; - display->grab_anchor_root_y = y; + MetaRectangle titlebar_rect; + meta_window_get_titlebar_rect (window, &titlebar_rect); + display->grab_anchor_root_y = display->grab_initial_window_pos.y + titlebar_rect.height / 2; } window->saved_rect.x = display->grab_initial_window_pos.x; window->saved_rect.y = display->grab_initial_window_pos.y; - meta_window_unmaximize (window, - META_MAXIMIZE_HORIZONTAL | - META_MAXIMIZE_VERTICAL); - + meta_window_unmaximize (window, META_MAXIMIZE_BOTH); return; } @@ -9543,14 +6178,20 @@ update_move (MetaWindow *window, else if ((window->shaken_loose || META_WINDOW_MAXIMIZED (window)) && window->tile_mode != META_TILE_LEFT && window->tile_mode != META_TILE_RIGHT) { - const MetaMonitorInfo *wmonitor; + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + int n_logical_monitors; + const MetaLogicalMonitor *wmonitor; MetaRectangle work_area; int monitor; window->tile_mode = META_TILE_NONE; - wmonitor = meta_screen_get_monitor_for_window (window->screen, window); + wmonitor = window->monitor; + n_logical_monitors = + meta_monitor_manager_get_num_logical_monitors (monitor_manager); - for (monitor = 0; monitor < window->screen->n_monitor_infos; monitor++) + for (monitor = 0; monitor < n_logical_monitors; monitor++) { meta_window_get_work_area_for_monitor (window, monitor, &work_area); @@ -9558,7 +6199,7 @@ update_move (MetaWindow *window, if (x >= work_area.x && x < (work_area.x + work_area.width) && y >= work_area.y && - y < (work_area.y + breakloose_threshold)) + y < (work_area.y + shake_threshold)) { /* move the saved rect if window will become maximized on an * other monitor so user isn't surprised on a later unmaximize @@ -9574,195 +6215,48 @@ update_move (MetaWindow *window, window->saved_rect.y += window->frame->child_y; } - window->user_rect.x = window->saved_rect.x; - window->user_rect.y = window->saved_rect.y; + window->unconstrained_rect.x = window->saved_rect.x; + window->unconstrained_rect.y = window->saved_rect.y; - meta_window_unmaximize (window, - META_MAXIMIZE_HORIZONTAL | - META_MAXIMIZE_VERTICAL); - } + meta_window_unmaximize (window, META_MAXIMIZE_BOTH); - display->grab_initial_window_pos = work_area; - display->grab_anchor_root_x = x; - display->grab_anchor_root_y = y; - window->shaken_loose = FALSE; + display->grab_initial_window_pos = work_area; + display->grab_anchor_root_x = x; + display->grab_anchor_root_y = y; + window->shaken_loose = FALSE; - meta_window_maximize (window, - META_MAXIMIZE_HORIZONTAL | - META_MAXIMIZE_VERTICAL); + meta_window_maximize (window, META_MAXIMIZE_BOTH); + } return; } } } - window->mouse_on_edge = meta_window_mouse_on_edge (window, x, y); - - MetaRectangle min_size, max_size, target_size; - gboolean hminbad = FALSE; - gboolean vminbad = FALSE; - - { - if (meta_prefs_get_edge_tiling ()) - { - if (window->current_proximity_zone != ZONE_NONE && !window->mouse_on_edge) - meta_screen_tile_hud_update (window->screen, TRUE, FALSE); - else - meta_screen_tile_hud_update (window->screen, TRUE, TRUE); - } - - if (window->tile_mode == META_TILE_NONE) - { - meta_screen_tile_preview_hide (window->screen); - } - else - { - get_size_limits (window, NULL, FALSE, &min_size, &max_size); - meta_window_get_current_tile_area (window, &target_size); - MetaFrameBorders borders; - meta_frame_calc_borders (window->frame, &borders); - meta_window_unextend_by_frame (window, &target_size, &borders); - hminbad = target_size.width < min_size.width; - vminbad = target_size.height < min_size.height; - - /* Delay showing the tile preview slightly to make it more unlikely to - * trigger it unwittingly, e.g. when shaking loose the window or moving - * it to another monitor. - */ - - if (!hminbad && !vminbad) - meta_screen_tile_preview_update (window->screen, - window->tile_mode != META_TILE_NONE && - !window->screen->tile_preview_visible); - else - meta_screen_tile_preview_hide (window->screen); - } - } + /* Delay showing the tile preview slightly to make it more unlikely to + * trigger it unwittingly, e.g. when shaking loose the window or moving + * it to another monitor. + */ + meta_display_update_tile_preview (window->display, + window->tile_mode != META_TILE_NONE); - meta_window_get_client_root_coords (window, &old); + meta_window_get_frame_rect (window, &old); /* Don't allow movement in the maximized directions or while tiled */ - if (window->maximized_horizontally || META_WINDOW_TILED_OR_SNAPPED (window)) + if (window->maximized_horizontally || META_WINDOW_TILED_SIDE_BY_SIDE (window)) new_x = old.x; if (window->maximized_vertically) new_y = old.y; /* Do any edge resistance/snapping */ meta_window_edge_resistance_for_move (window, - old.x, - old.y, &new_x, &new_y, update_move_timeout, - legacy_snap && meta_prefs_get_legacy_snap (), + snap, FALSE); - meta_window_move (window, TRUE, new_x, new_y); -} - -/* When resizing a maximized window by using alt-middle-drag (resizing - * with the grips or the menu for a maximized window is not enabled), - * the user can "break" out of the maximized state. This checks for - * that possibility. During such a break-out resize the user can also - * return to the previous maximization state by resizing back to near - * the original size. - */ -static MetaMaximizeFlags -check_resize_unmaximize(MetaWindow *window, - int dx, - int dy) -{ - int threshold; - MetaMaximizeFlags new_unmaximize; - - threshold = meta_prefs_get_resize_threshold (); - new_unmaximize = 0; - - if (window->maximized_horizontally || - window->tile_mode != META_TILE_NONE || - (window->display->grab_resize_unmaximize & META_MAXIMIZE_HORIZONTAL) != 0) - { - int x_amount; - - /* We allow breaking out of maximization in either direction, to make - * the window larger than the monitor as well as smaller than the - * monitor. If we wanted to only allow resizing smaller than the - * monitor, we'd use - dx for NE/E/SE and dx for SW/W/NW. - */ - switch (window->display->grab_op) - { - case META_GRAB_OP_RESIZING_NE: - case META_GRAB_OP_KEYBOARD_RESIZING_NE: - case META_GRAB_OP_RESIZING_E: - case META_GRAB_OP_KEYBOARD_RESIZING_E: - case META_GRAB_OP_RESIZING_SE: - case META_GRAB_OP_KEYBOARD_RESIZING_SE: - case META_GRAB_OP_RESIZING_SW: - case META_GRAB_OP_KEYBOARD_RESIZING_SW: - case META_GRAB_OP_RESIZING_W: - case META_GRAB_OP_KEYBOARD_RESIZING_W: - case META_GRAB_OP_RESIZING_NW: - case META_GRAB_OP_KEYBOARD_RESIZING_NW: - x_amount = dx < 0 ? - dx : dx; - break; - default: - x_amount = 0; - break; - } - - if (x_amount > threshold) - new_unmaximize |= META_MAXIMIZE_HORIZONTAL; - } - - if (window->maximized_vertically || window->tile_mode != META_TILE_NONE || - (window->display->grab_resize_unmaximize & META_MAXIMIZE_VERTICAL) != 0) - { - int y_amount; - - switch (window->display->grab_op) - { - case META_GRAB_OP_RESIZING_N: - case META_GRAB_OP_KEYBOARD_RESIZING_N: - case META_GRAB_OP_RESIZING_NE: - case META_GRAB_OP_KEYBOARD_RESIZING_NE: - case META_GRAB_OP_RESIZING_NW: - case META_GRAB_OP_KEYBOARD_RESIZING_NW: - case META_GRAB_OP_RESIZING_SE: - case META_GRAB_OP_KEYBOARD_RESIZING_SE: - case META_GRAB_OP_RESIZING_S: - case META_GRAB_OP_KEYBOARD_RESIZING_S: - case META_GRAB_OP_RESIZING_SW: - case META_GRAB_OP_KEYBOARD_RESIZING_SW: - y_amount = dy < 0 ? - dy : dy; - break; - default: - y_amount = 0; - break; - } - - if (y_amount > threshold) - new_unmaximize |= META_MAXIMIZE_VERTICAL; - } - - /* Metacity doesn't have a full user interface for only horizontally or - * vertically maximized, so while only unmaximizing in the direction drags - * has some advantages, it will also confuse the user. So, we always - * unmaximize both ways if possible. - */ - if (new_unmaximize != 0) - { - new_unmaximize = 0; - - if (window->maximized_horizontally || - (window->display->grab_resize_unmaximize & META_MAXIMIZE_HORIZONTAL) != 0) - new_unmaximize |= META_MAXIMIZE_HORIZONTAL; - if ((window->tile_type == META_WINDOW_TILE_TYPE_NONE || - window->resizing_tile_type == META_WINDOW_TILE_TYPE_NONE) && - (window->maximized_vertically || (window->display->grab_resize_unmaximize & META_MAXIMIZE_VERTICAL) != 0)) - new_unmaximize |= META_MAXIMIZE_VERTICAL; - } - - return new_unmaximize; + meta_window_move_frame (window, TRUE, new_x, new_y); } static gboolean @@ -9785,11 +6279,10 @@ update_resize (MetaWindow *window, gboolean force) { int dx, dy; - int new_w, new_h; - int gravity; - MetaRectangle old; - double remaining; - MetaMaximizeFlags new_unmaximize; + MetaGravity gravity; + MetaRectangle new_rect; + MetaRectangle old_rect; + double remaining = 0; window->display->grab_latest_motion_x = x; window->display->grab_latest_motion_y = y; @@ -9797,13 +6290,6 @@ update_resize (MetaWindow *window, dx = x - window->display->grab_anchor_root_x; dy = y - window->display->grab_anchor_root_y; - /* Don't bother doing anything if no move has been specified. (This - * happens often, even in keyboard resizing, due to the warping of the - * pointer. - */ - if (dx == 0 && dy == 0) - return; - /* Attached modal dialogs are special in that size * changes apply to both sides, so that the dialog * remains centered to the parent. @@ -9814,149 +6300,53 @@ update_resize (MetaWindow *window, dy *= 2; } - new_w = window->display->grab_anchor_window_pos.width; - new_h = window->display->grab_anchor_window_pos.height; + new_rect.width = window->display->grab_anchor_window_pos.width; + new_rect.height = window->display->grab_anchor_window_pos.height; + + /* Don't bother doing anything if no move has been specified. (This + * happens often, even in keyboard resizing, due to the warping of the + * pointer. + */ + if (dx == 0 && dy == 0) + return; if (window->display->grab_op == META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN) { - if (window->tile_mode == META_TILE_NONE) - { - if ((dx > 0) && (dy > 0)) - { - window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_SE; - meta_window_update_keyboard_resize (window, TRUE); - } - else if ((dx < 0) && (dy > 0)) - { - window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_SW; - meta_window_update_keyboard_resize (window, TRUE); - } - else if ((dx > 0) && (dy < 0)) - { - window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_NE; - meta_window_update_keyboard_resize (window, TRUE); - } - else if ((dx < 0) && (dy < 0)) - { - window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_NW; - meta_window_update_keyboard_resize (window, TRUE); - } - else if (dx < 0) - { - window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_W; - meta_window_update_keyboard_resize (window, TRUE); - } - else if (dx > 0) - { - window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_E; - meta_window_update_keyboard_resize (window, TRUE); - } - else if (dy > 0) - { - window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_S; - meta_window_update_keyboard_resize (window, TRUE); - } - else if (dy < 0) - { - window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_N; - meta_window_update_keyboard_resize (window, TRUE); - } - } - else - { - switch (window->tile_mode) - { - case META_TILE_LEFT: - window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_E; - break; - case META_TILE_RIGHT: - window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_W; - break; - case META_TILE_TOP: - window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_S; - break; - case META_TILE_BOTTOM: - window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_N; - break; - case META_TILE_ULC: - window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_SE; - break; - case META_TILE_LLC: - window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_NE; - break; - case META_TILE_URC: - window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_SW; - break; - case META_TILE_LRC: - window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_NW; - break; - default: - break; - } - meta_window_update_keyboard_resize (window, TRUE); - } - } - - new_unmaximize = check_resize_unmaximize (window, dx, dy); + MetaGrabOp op = META_GRAB_OP_WINDOW_BASE | META_GRAB_OP_WINDOW_FLAG_KEYBOARD; - switch (window->display->grab_op) - { - case META_GRAB_OP_RESIZING_SE: - case META_GRAB_OP_RESIZING_NE: - case META_GRAB_OP_RESIZING_E: - case META_GRAB_OP_KEYBOARD_RESIZING_SE: - case META_GRAB_OP_KEYBOARD_RESIZING_NE: - case META_GRAB_OP_KEYBOARD_RESIZING_E: - if (meta_window_resize_or_move_allowed (window, META_DIRECTION_RIGHT)) - new_w += dx; - break; + if (dx > 0) + op |= META_GRAB_OP_WINDOW_DIR_EAST; + else if (dx < 0) + op |= META_GRAB_OP_WINDOW_DIR_WEST; - case META_GRAB_OP_RESIZING_NW: - case META_GRAB_OP_RESIZING_SW: - case META_GRAB_OP_RESIZING_W: - case META_GRAB_OP_KEYBOARD_RESIZING_NW: - case META_GRAB_OP_KEYBOARD_RESIZING_SW: - case META_GRAB_OP_KEYBOARD_RESIZING_W: - if (meta_window_resize_or_move_allowed (window, META_DIRECTION_LEFT)) - new_w -= dx; - break; - default: - break; - } + if (dy > 0) + op |= META_GRAB_OP_WINDOW_DIR_SOUTH; + else if (dy < 0) + op |= META_GRAB_OP_WINDOW_DIR_NORTH; - switch (window->display->grab_op) - { - case META_GRAB_OP_RESIZING_SE: - case META_GRAB_OP_RESIZING_S: - case META_GRAB_OP_RESIZING_SW: - case META_GRAB_OP_KEYBOARD_RESIZING_SE: - case META_GRAB_OP_KEYBOARD_RESIZING_S: - case META_GRAB_OP_KEYBOARD_RESIZING_SW: - if (meta_window_resize_or_move_allowed (window, META_DIRECTION_DOWN)) - new_h += dy; - break; + window->display->grab_op = op; - case META_GRAB_OP_RESIZING_N: - case META_GRAB_OP_RESIZING_NE: - case META_GRAB_OP_RESIZING_NW: - case META_GRAB_OP_KEYBOARD_RESIZING_N: - case META_GRAB_OP_KEYBOARD_RESIZING_NE: - case META_GRAB_OP_KEYBOARD_RESIZING_NW: - if (meta_window_resize_or_move_allowed (window, META_DIRECTION_UP)) - new_h -= dy; - break; - default: - break; + meta_window_update_keyboard_resize (window, TRUE); } -#ifdef HAVE_XSYNC + if (window->display->grab_op & META_GRAB_OP_WINDOW_DIR_EAST) + new_rect.width += dx; + else if (window->display->grab_op & META_GRAB_OP_WINDOW_DIR_WEST) + new_rect.width -= dx; + + if (window->display->grab_op & META_GRAB_OP_WINDOW_DIR_SOUTH) + new_rect.height += dy; + else if (window->display->grab_op & META_GRAB_OP_WINDOW_DIR_NORTH) + new_rect.height -= dy; + + meta_window_maybe_apply_size_hints (window, &new_rect); + /* If we're waiting for a request for _NET_WM_SYNC_REQUEST, we'll * resize the window when the window responds, or when we time * the response out. */ if (window->sync_request_timeout_id != 0) return; -#endif if (!check_moveresize_frequency (window, &remaining) && !force) { @@ -9969,485 +6359,217 @@ update_resize (MetaWindow *window, { window->display->grab_resize_timeout_id = g_timeout_add ((int)remaining, update_resize_timeout, window); + g_source_set_name_by_id (window->display->grab_resize_timeout_id, + "[mutter] update_resize_timeout"); } return; } /* Remove any scheduled compensation events */ - if (window->display->grab_resize_timeout_id) - { - g_source_remove (window->display->grab_resize_timeout_id); - window->display->grab_resize_timeout_id = 0; - } + g_clear_handle_id (&window->display->grab_resize_timeout_id, g_source_remove); - old = window->rect; /* Don't actually care about x,y */ + meta_window_get_frame_rect (window, &old_rect); /* One sided resizing ought to actually be one-sided, despite the fact that * aspect ratio windows don't interact nicely with the above stuff. So, * to avoid some nasty flicker, we enforce that. */ - switch (window->display->grab_op) - { - case META_GRAB_OP_RESIZING_S: - case META_GRAB_OP_RESIZING_N: - case META_GRAB_OP_KEYBOARD_RESIZING_S: - case META_GRAB_OP_KEYBOARD_RESIZING_N: - new_w = old.width; - break; - case META_GRAB_OP_RESIZING_E: - case META_GRAB_OP_RESIZING_W: - case META_GRAB_OP_KEYBOARD_RESIZING_E: - case META_GRAB_OP_KEYBOARD_RESIZING_W: - new_h = old.height; - break; + if ((window->display->grab_op & (META_GRAB_OP_WINDOW_DIR_WEST | META_GRAB_OP_WINDOW_DIR_EAST)) == 0) + new_rect.width = old_rect.width; - default: - break; - } + if ((window->display->grab_op & (META_GRAB_OP_WINDOW_DIR_NORTH | META_GRAB_OP_WINDOW_DIR_SOUTH)) == 0) + new_rect.height = old_rect.height; /* compute gravity of client during operation */ - if (window->tile_mode != META_TILE_NONE) - gravity = meta_resize_gravity_from_tile_mode (window->tile_mode); - else - gravity = meta_resize_gravity_from_grab_op (window->display->grab_op); - + gravity = meta_resize_gravity_from_grab_op (window->display->grab_op); g_assert (gravity >= 0); /* Do any edge resistance/snapping */ meta_window_edge_resistance_for_resize (window, - old.width, - old.height, - &new_w, - &new_h, + &new_rect.width, + &new_rect.height, gravity, update_resize_timeout, snap, FALSE); - if (new_unmaximize == window->display->grab_resize_unmaximize && window->tile_type == META_WINDOW_TILE_TYPE_NONE) - { - /* We don't need to update unless the specified width and height - * are actually different from what we had before. - */ - if (old.width != new_w || old.height != new_h) - { - meta_window_resize_with_gravity (window, TRUE, new_w, new_h, gravity); - } - } - else - { - if ((new_unmaximize & ~window->display->grab_resize_unmaximize) != 0) - { - meta_window_unmaximize_with_gravity (window, - (new_unmaximize & ~window->display->grab_resize_unmaximize), - new_w, new_h, gravity); - } - - if (window->tile_type != META_WINDOW_TILE_TYPE_NONE) - { - if (window->tile_mode != META_TILE_NONE) - { - window->resize_tile_mode = window->tile_mode; - window->resizing_tile_type = window->tile_type; - } - - meta_window_resize_with_gravity (window, TRUE, new_w, new_h, gravity); - } - - if (window->resizing_tile_type == META_WINDOW_TILE_TYPE_NONE && (window->display->grab_resize_unmaximize & ~new_unmaximize)) - { - MetaRectangle saved_rect = window->saved_rect; - meta_window_maximize (window, - (window->display->grab_resize_unmaximize & ~new_unmaximize)); - window->saved_rect = saved_rect; - } - } + meta_window_resize_frame_with_gravity (window, TRUE, + new_rect.width, new_rect.height, + gravity); - window->display->grab_resize_unmaximize = new_unmaximize; /* Store the latest resize time, if we actually resized. */ - - if (window->rect.width != old.width || window->rect.height != old.height) - g_get_current_time (&window->display->grab_last_moveresize_time); + if (window->rect.width != old_rect.width || + window->rect.height != old_rect.height) + window->display->grab_last_moveresize_time = g_get_real_time (); } -typedef struct +static void +maybe_maximize_tiled_window (MetaWindow *window) { - const XEvent *current_event; - int count; - guint32 last_time; -} EventScannerData; + MetaRectangle work_area; + gint shake_threshold; -static Bool -find_last_time_predicate (Display *display, - XEvent *xevent, - XPointer arg) -{ - EventScannerData *esd = (void*) arg; + if (!META_WINDOW_TILED_SIDE_BY_SIDE (window)) + return; - if (esd->current_event->type == xevent->type && - esd->current_event->xany.window == xevent->xany.window) - { - esd->count += 1; - esd->last_time = xevent->xmotion.time; - } + shake_threshold = meta_prefs_get_drag_threshold (); - return False; + meta_window_get_work_area_for_monitor (window, + window->tile_monitor_number, + &work_area); + if (window->rect.width >= work_area.width - shake_threshold) + meta_window_maximize (window, META_MAXIMIZE_BOTH); } -static gboolean -check_use_this_motion_notify (MetaWindow *window, - XEvent *event) +void +meta_window_update_resize (MetaWindow *window, + gboolean snap, + int x, int y, + gboolean force) { - EventScannerData esd; - XEvent useless; - - /* This code is copied from Owen's GDK code. */ - - if (window->display->grab_motion_notify_time != 0) - { - /* == is really the right test, but I'm all for paranoia */ - if (window->display->grab_motion_notify_time <= - event->xmotion.time) - { - meta_topic (META_DEBUG_RESIZING, - "Arrived at event with time %u (waiting for %u), using it\n", - (unsigned int)event->xmotion.time, - window->display->grab_motion_notify_time); - window->display->grab_motion_notify_time = 0; - return TRUE; - } - else - return FALSE; /* haven't reached the saved timestamp yet */ - } - - esd.current_event = event; - esd.count = 0; - esd.last_time = 0; - - /* "useless" isn't filled in because the predicate never returns True */ - XCheckIfEvent (window->display->xdisplay, - &useless, - find_last_time_predicate, - (XPointer) &esd); -#ifdef WITH_VERBOSE_MODE - if (esd.count > 0) - meta_topic (META_DEBUG_RESIZING, - "Will skip %d motion events and use the event with time %u\n", - esd.count, (unsigned int) esd.last_time); -#endif - if (esd.last_time == 0) - return TRUE; - else - { - /* Save this timestamp, and ignore all motion notify - * until we get to the one with this stamp. - */ - window->display->grab_motion_notify_time = esd.last_time; - return FALSE; - } + update_resize (window, snap, x, y, force); } static void -update_tile_mode (MetaWindow *window) -{ - switch (window->tile_mode) - { - case META_TILE_LEFT: - case META_TILE_RIGHT: - case META_TILE_ULC: - case META_TILE_LLC: - case META_TILE_URC: - case META_TILE_LRC: - case META_TILE_TOP: - case META_TILE_BOTTOM: - case META_TILE_MAXIMIZE: - if (!META_WINDOW_TILED_OR_SNAPPED (window)) - window->tile_mode = META_TILE_NONE; - break; - } -} - -#ifdef HAVE_XSYNC -void -meta_window_update_sync_request_counter (MetaWindow *window, - gint64 new_counter_value) +end_grab_op (MetaWindow *window, + const ClutterEvent *event) { - gboolean needs_frame_drawn = FALSE; - gboolean no_delay_frame = FALSE; - - if (window->extended_sync_request_counter && new_counter_value % 2 == 0) - { - needs_frame_drawn = TRUE; - no_delay_frame = new_counter_value == window->sync_request_serial + 1; - } + ClutterModifierType modifiers; + gfloat x, y; - window->sync_request_serial = new_counter_value; - meta_compositor_set_updates_frozen (window->display->compositor, window, - meta_window_updates_are_frozen (window)); + clutter_event_get_coords (event, &x, &y); + modifiers = clutter_event_get_state (event); + meta_display_check_threshold_reached (window->display, x, y); - if (window == window->display->grab_window && - meta_grab_op_is_resizing (window->display->grab_op) && - new_counter_value >= window->sync_request_wait_serial && - (!window->extended_sync_request_counter || new_counter_value % 2 == 0) && - window->sync_request_timeout_id) - { - meta_topic (META_DEBUG_RESIZING, - "Alarm event received last motion x = %d y = %d\n", - window->display->grab_latest_motion_x, - window->display->grab_latest_motion_y); - - g_source_remove (window->sync_request_timeout_id); - window->sync_request_timeout_id = 0; - - /* This means we are ready for another configure; - * no pointer round trip here, to keep in sync */ - update_resize (window, - window->display->grab_last_user_action_was_snap, - window->display->grab_latest_motion_x, - window->display->grab_latest_motion_y, - TRUE); - } - - /* If sync was previously disabled, turn it back on and hope - * the application has come to its senses (maybe it was just - * busy with a pagefault or a long computation). + /* If the user was snap moving then ignore the button + * release because they may have let go of shift before + * releasing the mouse button and they almost certainly do + * not want a non-snapped movement to occur from the button + * release. */ - window->disable_sync = FALSE; - - if (needs_frame_drawn) - meta_compositor_queue_frame_drawn (window->display->compositor, window, - no_delay_frame); -} -#endif /* HAVE_XSYNC */ - -LOCAL_SYMBOL void -meta_window_handle_mouse_grab_op_event (MetaWindow *window, - XEvent *event) -{ -#ifdef HAVE_XSYNC - if (event->type == (window->display->xsync_event_base + XSyncAlarmNotify)) - { - meta_topic (META_DEBUG_RESIZING, - "Alarm event received last motion x = %d y = %d\n", - window->display->grab_latest_motion_x, - window->display->grab_latest_motion_y); - - /* If sync was previously disabled, turn it back on and hope - * the application has come to its senses (maybe it was just - * busy with a pagefault or a long computation). - */ - window->disable_sync = FALSE; - meta_window_destroy_sync_request_alarm (window); - - /* This means we are ready for another configure. */ - switch (window->display->grab_op) - { - case META_GRAB_OP_RESIZING_E: - case META_GRAB_OP_RESIZING_W: - case META_GRAB_OP_RESIZING_S: - case META_GRAB_OP_RESIZING_N: - case META_GRAB_OP_RESIZING_SE: - case META_GRAB_OP_RESIZING_SW: - case META_GRAB_OP_RESIZING_NE: - case META_GRAB_OP_RESIZING_NW: - case META_GRAB_OP_KEYBOARD_RESIZING_S: - case META_GRAB_OP_KEYBOARD_RESIZING_N: - case META_GRAB_OP_KEYBOARD_RESIZING_W: - case META_GRAB_OP_KEYBOARD_RESIZING_E: - case META_GRAB_OP_KEYBOARD_RESIZING_SE: - case META_GRAB_OP_KEYBOARD_RESIZING_NE: - case META_GRAB_OP_KEYBOARD_RESIZING_SW: - case META_GRAB_OP_KEYBOARD_RESIZING_NW: - /* no pointer round trip here, to keep in sync */ - update_resize (window, - window->display->grab_last_user_action_was_snap, - window->display->grab_latest_motion_x, - window->display->grab_latest_motion_y, - TRUE); - break; - - default: - break; - } - } -#endif /* HAVE_XSYNC */ - - switch (event->type) + if (!window->display->grab_last_user_action_was_snap) { - case ButtonRelease: - meta_display_check_threshold_reached (window->display, - event->xbutton.x_root, - event->xbutton.y_root); - /* If the user was snap moving then ignore the button release - * because they may have let go of shift before releasing the - * mouse button and they almost certainly do not want a - * non-snapped movement to occur from the button release. - */ - if (!window->display->grab_last_user_action_was_snap) - { - if (meta_grab_op_is_moving (window->display->grab_op)) - { - if (window->tile_mode != META_TILE_NONE && - meta_window_mouse_on_edge (window, - event->xbutton.x_root, - event->xbutton.y_root)) { - window->custom_snap_size = FALSE; - if (window->tile_mode == META_TILE_MAXIMIZE) - meta_window_maximize(window, META_MAXIMIZE_VERTICAL | META_MAXIMIZE_HORIZONTAL); - else - meta_window_real_tile (window, FALSE); - } - else if (event->xbutton.root == window->screen->xroot) - update_move (window, - event->xbutton.state & ShiftMask, - event->xbutton.state & get_mask_from_snap_keysym (window), - event->xbutton.x_root, event->xbutton.y_root); - if (meta_prefs_get_edge_tiling ()) - meta_screen_tile_hud_update (window->screen, FALSE, TRUE); - } - else if (meta_grab_op_is_resizing (window->display->grab_op)) - { - if (event->xbutton.root == window->screen->xroot) - update_resize (window, - event->xbutton.state & ShiftMask, - event->xbutton.x_root, - event->xbutton.y_root, - TRUE); - } - - /* If a tiled window has been dragged free with a - * mouse resize without snapping back to the tiled - * state, it will end up with an inconsistent tile - * mode on mouse release; cleaning the mode earlier - * would break the ability to snap back to the tiled - * state, so we wait until mouse release. - */ - if (window->tile_type == META_WINDOW_TILE_TYPE_NONE) - update_tile_mode (window); - } - - window->maybe_retile_maximize = FALSE; - meta_display_end_grab_op (window->display, event->xbutton.time); - break; - - case MotionNotify: - meta_display_check_threshold_reached (window->display, - event->xmotion.x_root, - event->xmotion.y_root); if (meta_grab_op_is_moving (window->display->grab_op)) { - if (event->xmotion.root == window->screen->xroot) - { - if (check_use_this_motion_notify (window, - event)) - update_move (window, - event->xmotion.state & ShiftMask, - event->xmotion.state & get_mask_from_snap_keysym (window), - event->xmotion.x_root, - event->xmotion.y_root); - } + if (window->display->preview_tile_mode != META_TILE_NONE) + meta_window_tile (window, window->display->preview_tile_mode); + else + update_move (window, + modifiers & CLUTTER_SHIFT_MASK, + x, y); } else if (meta_grab_op_is_resizing (window->display->grab_op)) { - if (event->xmotion.root == window->screen->xroot) - { - if (check_use_this_motion_notify (window, - event)) - update_resize (window, - event->xmotion.state & ShiftMask, - event->xmotion.x_root, - event->xmotion.y_root, - FALSE); - } + update_resize (window, + modifiers & CLUTTER_SHIFT_MASK || window->tile_match != NULL, + x, y, + TRUE); + maybe_maximize_tiled_window (window); } - break; - - default: - break; } + window->display->preview_tile_mode = META_TILE_NONE; + meta_display_end_grab_op (window->display, clutter_event_get_time (event)); } -LOCAL_SYMBOL void -meta_window_handle_keyboard_grab_op_event (MetaWindow *window, - XEvent *event) +gboolean +meta_window_handle_mouse_grab_op_event (MetaWindow *window, + const ClutterEvent *event) { + ClutterEventSequence *sequence = clutter_event_get_event_sequence (event); + ClutterModifierType modifier_state; + gfloat x, y; + switch (event->type) { - case KeyPress: - case KeyRelease: - meta_display_check_threshold_reached (window->display, - event->xmotion.x_root, - event->xmotion.y_root); - if (window->display->grab_op == META_GRAB_OP_MOVING) - { - if (event->xmotion.root == window->screen->xroot) - { - if (check_use_this_motion_notify (window, - event)) { - unsigned int *mod_set = meta_prefs_get_snap_modifier (); - KeySym keysym = XkbKeycodeToKeysym (window->display->xdisplay, event->xkey.keycode, 0, 0); - if (mod_set[0] != 0) - { - gboolean snap = FALSE; - if (event->type == KeyPress && (keysym == mod_set[0] || - keysym == mod_set[1])) - snap = TRUE; - update_move (window, - event->xmotion.state & ShiftMask, - snap, - event->xmotion.x_root, - event->xmotion.y_root); - } - } - } - } - break; - default: - break; - } -} + case CLUTTER_BUTTON_PRESS: + { + ClutterModifierType grab_mods = meta_display_get_window_grab_modifiers (window->display); -LOCAL_SYMBOL void -meta_window_set_gravity (MetaWindow *window, - int gravity) -{ - XSetWindowAttributes attrs; + /* This is the keybinding or menu case where we've + * been dragging around the window without the button + * pressed. */ - meta_verbose ("Setting gravity of %s to %d\n", window->desc, gravity); + if ((meta_grab_op_is_mouse (window->display->grab_op) && + (event->button.modifier_state & grab_mods) == grab_mods && + window->display->grab_button != (int) event->button.button) || + meta_grab_op_is_keyboard (window->display->grab_op)) + { + end_grab_op (window, event); + return FALSE; + } + return TRUE; + } + + case CLUTTER_TOUCH_END: + if (meta_display_is_pointer_emulating_sequence (window->display, sequence)) + end_grab_op (window, event); + + return TRUE; + + case CLUTTER_BUTTON_RELEASE: + if (event->button.button == 1 || + event->button.button == (unsigned int) meta_prefs_get_mouse_button_resize ()) + end_grab_op (window, event); - attrs.win_gravity = gravity; + return TRUE; + + case CLUTTER_TOUCH_BEGIN: + /* This will only catch the keybinding and menu cases, just deal with this + * like a CLUTTER_TOUCH_UPDATE rather than a CLUTTER_BUTTON_PRESS, and + * wait until CLUTTER_TOUCH_END to undo the grab, just so the window + * doesn't warp below the finger and remain there. + */ + case CLUTTER_TOUCH_UPDATE: + if (!meta_display_is_pointer_emulating_sequence (window->display, sequence)) + return FALSE; - meta_error_trap_push (window->display); + /* Fall through */ + case CLUTTER_MOTION: + modifier_state = clutter_event_get_state (event); + clutter_event_get_coords (event, &x, &y); - XChangeWindowAttributes (window->display->xdisplay, - window->xwindow, - CWWinGravity, - &attrs); + meta_display_check_threshold_reached (window->display, x, y); + if (meta_grab_op_is_moving (window->display->grab_op)) + { + update_move (window, + modifier_state & CLUTTER_SHIFT_MASK, + x, y); + } + else if (meta_grab_op_is_resizing (window->display->grab_op)) + { + update_resize (window, + modifier_state & CLUTTER_SHIFT_MASK || window->tile_match != NULL, + x, y, + FALSE); + } + return TRUE; - meta_error_trap_pop (window->display); + default: + return FALSE; + } } -static void -get_work_area_monitor (MetaWindow *window, - MetaRectangle *area, - int which_monitor) +void +meta_window_get_work_area_for_logical_monitor (MetaWindow *window, + MetaLogicalMonitor *logical_monitor, + MetaRectangle *area) { GList *tmp; - g_assert (which_monitor >= 0); + g_assert (logical_monitor); /* Initialize to the whole monitor */ - *area = window->screen->monitor_infos[which_monitor].rect; + *area = logical_monitor->rect; tmp = meta_window_get_workspaces (window); while (tmp != NULL) { MetaRectangle workspace_work_area; - meta_workspace_get_work_area_for_monitor (tmp->data, - which_monitor, - &workspace_work_area); + meta_workspace_get_work_area_for_logical_monitor (tmp->data, + logical_monitor, + &workspace_work_area); meta_rectangle_intersect (area, &workspace_work_area, area); @@ -10456,43 +6578,73 @@ get_work_area_monitor (MetaWindow *window, meta_topic (META_DEBUG_WORKAREA, "Window %s monitor %d has work area %d,%d %d x %d\n", - window->desc, which_monitor, + window->desc, logical_monitor->number, area->x, area->y, area->width, area->height); } -LOCAL_SYMBOL void +/** + * meta_window_get_work_area_current_monitor: + * @window: a #MetaWindow + * @area: (out): a location to store the work area + * + * Get the work area for the monitor @window is currently on. + */ +void meta_window_get_work_area_current_monitor (MetaWindow *window, MetaRectangle *area) { - const MetaMonitorInfo *monitor = NULL; - monitor = meta_screen_get_monitor_for_window (window->screen, - window); - meta_window_get_work_area_for_monitor (window, - monitor->number, + window->monitor->number, area); } -LOCAL_SYMBOL void +/** + * meta_window_get_work_area_for_monitor: + * @window: a #MetaWindow + * @which_monitor: a moniotr to get the work area for + * @area: (out): a location to store the work area + * + * Get the work area for @window, given the monitor index + * @which_monitor. + */ +void meta_window_get_work_area_for_monitor (MetaWindow *window, int which_monitor, MetaRectangle *area) { + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = meta_backend_get_monitor_manager (backend); + MetaLogicalMonitor *logical_monitor; + g_return_if_fail (which_monitor >= 0); - get_work_area_monitor (window, - area, - which_monitor); + logical_monitor = + meta_monitor_manager_get_logical_monitor_from_number (monitor_manager, + which_monitor); + + meta_window_get_work_area_for_logical_monitor (window, logical_monitor, area); } -LOCAL_SYMBOL void +/** + * meta_window_get_work_area_all_monitors: + * @window: a #MetaWindow + * @area: (out): a location to store the work area + * + * Get the work area for all monitors for @window. + */ +void meta_window_get_work_area_all_monitors (MetaWindow *window, MetaRectangle *area) { GList *tmp; + MetaRectangle display_rect = { 0 }; - /* Initialize to the whole screen */ - *area = window->screen->rect; + meta_display_get_size (window->display, + &display_rect.width, + &display_rect.height); + + /* Initialize to the whole display */ + *area = display_rect; tmp = meta_window_get_workspaces (window); while (tmp != NULL) @@ -10511,142 +6663,44 @@ meta_window_get_work_area_all_monitors (MetaWindow *window, window->desc, area->x, area->y, area->width, area->height); } -LOCAL_SYMBOL void -meta_window_get_tile_threshold_area_for_mode (MetaWindow *window, - MetaRectangle work_area, - MetaTileMode mode, - MetaRectangle *tile_area, - gint zone_width) -{ - int tile_monitor_number; - - g_return_if_fail (mode != META_TILE_NONE); - - if (window != NULL) { - tile_monitor_number = meta_window_get_current_tile_monitor_number(window); - meta_window_get_work_area_for_monitor (window, tile_monitor_number, tile_area); - } else { - tile_area->x = work_area.x; - tile_area->y = work_area.y; - tile_area->height = work_area.height; - tile_area->width = work_area.width; - } - - switch (mode) { - case META_TILE_LEFT: - tile_area->width = zone_width; - tile_area->y = tile_area->y + zone_width; - tile_area->height = tile_area->height - (2 * zone_width); - break; - case META_TILE_RIGHT: - tile_area->x = tile_area->width - zone_width; - tile_area->width = zone_width; - tile_area->y = tile_area->y + zone_width; - tile_area->height = tile_area->height - (2 * zone_width); - break; - case META_TILE_ULC: - tile_area->width = zone_width; - tile_area->height = zone_width; - break; - case META_TILE_LLC: - tile_area->y = tile_area->height - zone_width; - tile_area->width = zone_width; - tile_area->height = zone_width; - break; - case META_TILE_URC: - tile_area->x = tile_area->width - zone_width; - tile_area->width = zone_width; - tile_area->height = zone_width; - break; - case META_TILE_LRC: - tile_area->x = tile_area->width - zone_width; - tile_area->width = zone_width; - tile_area->y = tile_area->height - zone_width; - tile_area->height = zone_width; - break; - case META_TILE_TOP: - case META_TILE_MAXIMIZE: - tile_area->height = zone_width; - tile_area->x = tile_area->x + zone_width; - tile_area->width = tile_area->width - (2 * zone_width); - break; - case META_TILE_BOTTOM: - tile_area->y = tile_area->height - zone_width; - tile_area->height = zone_width; - tile_area->x = tile_area->x + zone_width; - tile_area->width = tile_area->width - (2 * zone_width); - break; - default: - break; - } -} - int meta_window_get_current_tile_monitor_number (MetaWindow *window) { - int tile_monitor_number = window->tile_monitor_number; + int tile_monitor_number = window->tile_monitor_number; - if (tile_monitor_number < 0) + if (tile_monitor_number < 0) { - meta_warning ("%s called with an invalid monitor number, using 0 instead\n", G_STRFUNC); - tile_monitor_number = 0; + meta_warning ("%s called with an invalid monitor number; using 0 instead\n", G_STRFUNC); + tile_monitor_number = 0; } - return tile_monitor_number; + return tile_monitor_number; } -LOCAL_SYMBOL void -meta_window_get_current_tile_area (MetaWindow *window, - MetaRectangle *tile_area) +void +meta_window_get_tile_area (MetaWindow *window, + MetaTileMode tile_mode, + MetaRectangle *tile_area) { + MetaRectangle work_area; int tile_monitor_number; + double fraction; - g_return_if_fail (window->tile_mode != META_TILE_NONE); + g_return_if_fail (tile_mode != META_TILE_NONE); tile_monitor_number = meta_window_get_current_tile_monitor_number (window); - meta_window_get_work_area_for_monitor (window, tile_monitor_number, tile_area); + meta_window_get_work_area_for_monitor (window, tile_monitor_number, &work_area); + meta_window_get_tile_fraction (window, tile_mode, &fraction); - if (window->tile_mode == META_TILE_LEFT || - window->tile_mode == META_TILE_RIGHT) - tile_area->width /= 2; + *tile_area = work_area; + tile_area->width = round (tile_area->width * fraction); - if (window->tile_mode == META_TILE_RIGHT) - tile_area->x += tile_area->width; - - if (window->tile_mode == META_TILE_ULC) { - tile_area->width /= 2; - tile_area->height /= 2; - } - - if (window->tile_mode == META_TILE_LLC) { - tile_area->width /= 2; - tile_area->height /= 2; - tile_area->y += tile_area->height; - } - - if (window->tile_mode == META_TILE_URC) { - tile_area->width /= 2; - tile_area->height /= 2; - tile_area->x += tile_area->width; - } - - if (window->tile_mode == META_TILE_LRC) { - tile_area->width /= 2; - tile_area->height /= 2; - tile_area->x += tile_area->width; - tile_area->y += tile_area->height; - } - - if (window->tile_mode == META_TILE_TOP || - window->tile_mode == META_TILE_BOTTOM) - tile_area->height /= 2; - - if (window->tile_mode == META_TILE_BOTTOM) - tile_area->y += tile_area->height; + if (tile_mode == META_TILE_RIGHT) + tile_area->x += work_area.width - tile_area->width; } -LOCAL_SYMBOL gboolean +gboolean meta_window_same_application (MetaWindow *window, MetaWindow *other_window) { @@ -10659,23 +6713,6 @@ meta_window_same_application (MetaWindow *window, group==other_group; } -/* Generally meta_window_same_application() is a better idea - * of "sameness", since it handles the case where multiple apps - * want to look like the same app or the same app wants to look - * like multiple apps, but in the case of workarounds for legacy - * applications (which likely aren't setting the group properly - * anyways), it may be desirable to check this as well. - */ -static gboolean -meta_window_same_client (MetaWindow *window, - MetaWindow *other_window) -{ - int resource_mask = window->display->xdisplay->resource_mask; - - return ((window->xwindow & ~resource_mask) == - (other_window->xwindow & ~resource_mask)); -} - /** * meta_window_is_client_decorated: * @@ -10685,124 +6722,22 @@ meta_window_same_client (MetaWindow *window, gboolean meta_window_is_client_decorated (MetaWindow *window) { - /* Currently the implementation here is hackish - - * has_custom_frame_extents() is set if _GTK_FRAME_EXTENTS is set - * to any value even 0. GTK+ always sets _GTK_FRAME_EXTENTS for - * client-side-decorated window, even if the value is 0 because - * the window is maxized and has no invisible borders or shadows. - */ - return window->has_custom_frame_extents; -} - -void -meta_window_extend_by_frame (MetaWindow *window, - MetaRectangle *rect, - const MetaFrameBorders *borders) -{ - if (window->frame) - { - rect->x -= borders->visible.left; - rect->y -= borders->visible.top; - rect->width += borders->visible.left + borders->visible.right; - rect->height += borders->visible.top + borders->visible.bottom; - } - else if (meta_window_is_client_decorated (window)) - { - const GtkBorder *extents = &window->custom_frame_extents; - rect->x += extents->left; - rect->y += extents->top; - rect->width -= extents->left + extents->right; - rect->height -= extents->top + extents->bottom; - } -} - -void -meta_window_unextend_by_frame (MetaWindow *window, - MetaRectangle *rect, - const MetaFrameBorders *borders) -{ - if (window->frame) - { - rect->x += borders->visible.left; - rect->y += borders->visible.top; - rect->width -= borders->visible.left + borders->visible.right; - rect->height -= borders->visible.top + borders->visible.bottom; - } - else if (meta_window_is_client_decorated (window)) - { - const GtkBorder *extents = &window->custom_frame_extents; - rect->x -= extents->left; - rect->y -= extents->top; - rect->width += extents->left + extents->right; - rect->height += extents->top + extents->bottom; - } -} - -LOCAL_SYMBOL void -meta_window_refresh_resize_popup (MetaWindow *window) -{ - if (window->display->grab_op == META_GRAB_OP_NONE) - return; - - if (window->display->grab_window != window) - return; - - switch (window->display->grab_op) - { - case META_GRAB_OP_RESIZING_SE: - case META_GRAB_OP_RESIZING_S: - case META_GRAB_OP_RESIZING_SW: - case META_GRAB_OP_RESIZING_N: - case META_GRAB_OP_RESIZING_NE: - case META_GRAB_OP_RESIZING_NW: - case META_GRAB_OP_RESIZING_W: - case META_GRAB_OP_RESIZING_E: - case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN: - case META_GRAB_OP_KEYBOARD_RESIZING_S: - case META_GRAB_OP_KEYBOARD_RESIZING_N: - case META_GRAB_OP_KEYBOARD_RESIZING_W: - case META_GRAB_OP_KEYBOARD_RESIZING_E: - case META_GRAB_OP_KEYBOARD_RESIZING_SE: - case META_GRAB_OP_KEYBOARD_RESIZING_NE: - case META_GRAB_OP_KEYBOARD_RESIZING_SW: - case META_GRAB_OP_KEYBOARD_RESIZING_NW: - break; - - default: - /* Not resizing */ - return; - } - - if (window->display->grab_resize_popup == NULL) + if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) { - gint scale; - - scale = meta_prefs_get_ui_scale (); - - if (window->size_hints.width_inc > scale || - window->size_hints.height_inc > scale) - { - window->display->grab_resize_popup = - meta_ui_resize_popup_new (window->display->xdisplay, - window->screen->number); - } + /* Assume all Wayland clients draw decorations - not strictly + * true but good enough for current purposes. + */ + return TRUE; } - - if (window->display->grab_resize_popup != NULL) + else { - MetaRectangle rect; - - meta_window_get_client_root_coords (window, &rect); - - meta_ui_resize_popup_set (window->display->grab_resize_popup, - rect, - window->size_hints.base_width, - window->size_hints.base_height, - window->size_hints.width_inc, - window->size_hints.height_inc); - - meta_ui_resize_popup_set_showing (window->display->grab_resize_popup, - TRUE); + /* Currently the implementation here is hackish - + * has_custom_frame_extents() is set if _GTK_FRAME_EXTENTS is set + * to any value even 0. GTK+ always sets _GTK_FRAME_EXTENTS for + * client-side-decorated window, even if the value is 0 because + * the window is maxized and has no invisible borders or shadows. + */ + return window->has_custom_frame_extents; } } @@ -10864,11 +6799,10 @@ meta_window_foreach_ancestor (MetaWindow *window, w = window; do { - if (w->xtransient_for == None || - w->transient_parent_is_root_window) + if (w->transient_for == NULL) break; - w = meta_display_lookup_x_window (w->display, w->xtransient_for); + w = w->transient_for; } while (w && (* func) (w, user_data)); } @@ -10928,76 +6862,42 @@ warp_grab_pointer (MetaWindow *window, int *x, int *y) { - MetaRectangle rect; - MetaDisplay *display; + MetaRectangle rect; + MetaRectangle display_rect = { 0 }; + MetaDisplay *display; display = window->display; + meta_display_get_size (display, + &display_rect.width, + &display_rect.height); /* We may not have done begin_grab_op yet, i.e. may not be in a grab */ - meta_window_get_outer_rect (window, &rect); - - switch (grab_op) - { - case META_GRAB_OP_KEYBOARD_MOVING: - case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN: - *x = rect.width / 2; - *y = rect.height / 2; - break; - - case META_GRAB_OP_KEYBOARD_RESIZING_S: - *x = rect.width / 2; - *y = rect.height - 1; - break; - - case META_GRAB_OP_KEYBOARD_RESIZING_N: - *x = rect.width / 2; - *y = 0; - break; - - case META_GRAB_OP_KEYBOARD_RESIZING_W: - *x = 0; - *y = rect.height / 2; - break; - - case META_GRAB_OP_KEYBOARD_RESIZING_E: - *x = rect.width - 1; - *y = rect.height / 2; - break; - - case META_GRAB_OP_KEYBOARD_RESIZING_SE: - *x = rect.width - 1; - *y = rect.height - 1; - break; - - case META_GRAB_OP_KEYBOARD_RESIZING_NE: - *x = rect.width - 1; - *y = 0; - break; - - case META_GRAB_OP_KEYBOARD_RESIZING_SW: - *x = 0; - *y = rect.height - 1; - break; + meta_window_get_frame_rect (window, &rect); - case META_GRAB_OP_KEYBOARD_RESIZING_NW: - *x = 0; - *y = 0; - break; + if (grab_op & META_GRAB_OP_WINDOW_DIR_WEST) + *x = 0; + else if (grab_op & META_GRAB_OP_WINDOW_DIR_EAST) + *x = rect.width - 1; + else + *x = rect.width / 2; - default: - return FALSE; - } + if (grab_op & META_GRAB_OP_WINDOW_DIR_NORTH) + *y = 0; + else if (grab_op & META_GRAB_OP_WINDOW_DIR_SOUTH) + *y = rect.height - 1; + else + *y = rect.height / 2; *x += rect.x; *y += rect.y; /* Avoid weird bouncing at the screen edge; see bug 154706 */ - *x = CLAMP (*x, 0, window->screen->rect.width-1); - *y = CLAMP (*y, 0, window->screen->rect.height-1); + *x = CLAMP (*x, 0, display_rect.width - 1); + *y = CLAMP (*y, 0, display_rect.height - 1); - meta_error_trap_push_with_return (display); + meta_x11_error_trap_push (display->x11_display); meta_topic (META_DEBUG_WINDOW_OPS, "Warping pointer to %d,%d with window at %d,%d\n", @@ -11011,16 +6911,17 @@ warp_grab_pointer (MetaWindow *window, display->grab_anchor_root_y = *y; display->grab_latest_motion_x = *x; display->grab_latest_motion_y = *y; - meta_window_get_client_root_coords (window, - &display->grab_anchor_window_pos); + meta_window_get_frame_rect (window, + &display->grab_anchor_window_pos); + + { + ClutterSeat *seat; - XWarpPointer (display->xdisplay, - None, - window->screen->xroot, - 0, 0, 0, 0, - *x, *y); + seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); + clutter_seat_warp_pointer (seat, *x, *y); + } - if (meta_error_trap_pop_with_return (display) != Success) + if (meta_x11_error_trap_pop_with_return (display->x11_display) != Success) { meta_verbose ("Failed to warp pointer for window %s\n", window->desc); @@ -11030,7 +6931,7 @@ warp_grab_pointer (MetaWindow *window, return TRUE; } -LOCAL_SYMBOL void +void meta_window_begin_grab_op (MetaWindow *window, MetaGrabOp op, gboolean frame_action, @@ -11042,7 +6943,6 @@ meta_window_begin_grab_op (MetaWindow *window, op, &x, &y); meta_display_begin_grab_op (window->display, - window->screen, window, op, FALSE, @@ -11053,7 +6953,7 @@ meta_window_begin_grab_op (MetaWindow *window, x, y); } -LOCAL_SYMBOL void +void meta_window_update_keyboard_resize (MetaWindow *window, gboolean update_cursor) { @@ -11064,20 +6964,10 @@ meta_window_update_keyboard_resize (MetaWindow *window, &x, &y); if (update_cursor) - { - guint32 timestamp; - /* FIXME: Using CurrentTime is really bad mojo */ - timestamp = CurrentTime; - meta_display_set_grab_op_cursor (window->display, - NULL, - window->display->grab_op, - TRUE, - window->display->grab_xwindow, - timestamp); - } + meta_display_update_cursor (window->display); } -LOCAL_SYMBOL void +void meta_window_update_keyboard_move (MetaWindow *window) { int x, y; @@ -11087,18 +6977,29 @@ meta_window_update_keyboard_move (MetaWindow *window) &x, &y); } -LOCAL_SYMBOL void +MetaStackLayer +meta_window_get_default_layer (MetaWindow *window) +{ + if (window->wm_state_below) + return META_LAYER_BOTTOM; + else if (window->wm_state_above && !META_WINDOW_MAXIMIZED (window)) + return META_LAYER_TOP; + else + return META_LAYER_NORMAL; +} + +void meta_window_update_layer (MetaWindow *window) { MetaGroup *group; - meta_stack_freeze (window->screen->stack); + meta_stack_freeze (window->display->stack); group = meta_window_get_group (window); if (group) meta_group_update_layers (group); else - meta_stack_update_layer (window->screen->stack, window); - meta_stack_thaw (window->screen->stack); + meta_stack_update_layer (window->display->stack, window); + meta_stack_thaw (window->display->stack); } /* ensure_mru_position_after ensures that window appears after @@ -11116,11 +7017,13 @@ ensure_mru_position_after (MetaWindow *window, * map. */ + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; GList* active_mru_list; GList* window_position; GList* after_this_one_position; - active_mru_list = window->screen->active_workspace->mru_list; + active_mru_list = workspace_manager->active_workspace->mru_list; + window_position = g_list_find (active_mru_list, window); after_this_one_position = g_list_find (active_mru_list, after_this_one); /* after_this_one_position is NULL when we switch workspaces, but in @@ -11130,21 +7033,26 @@ ensure_mru_position_after (MetaWindow *window, if (after_this_one_position == NULL) return; - window_position = g_list_find (active_mru_list, window); if (g_list_length (window_position) > g_list_length (after_this_one_position)) { - window->screen->active_workspace->mru_list = - g_list_delete_link (window->screen->active_workspace->mru_list, + workspace_manager->active_workspace->mru_list = + g_list_delete_link (workspace_manager->active_workspace->mru_list, window_position); - window->screen->active_workspace->mru_list = - g_list_insert_before (window->screen->active_workspace->mru_list, + workspace_manager->active_workspace->mru_list = + g_list_insert_before (workspace_manager->active_workspace->mru_list, after_this_one_position->next, window); } } -LOCAL_SYMBOL void +gboolean +meta_window_is_in_stack (MetaWindow *window) +{ + return window->stack_position >= 0; +} + +void meta_window_stack_just_below (MetaWindow *window, MetaWindow *below_this_one) { @@ -11194,13 +7102,14 @@ meta_window_stack_just_above (MetaWindow *window, /** * meta_window_get_user_time: + * @window: a #MetaWindow * * The user time represents a timestamp for the last time the user * interacted with this window. Note this property is only available * for non-override-redirect windows. * - * The property is set by Muffin initially upon window creation, - * and updated thereafter on input events (key and button presses) seen by Muffin, + * The property is set by Mutter initially upon window creation, + * and updated thereafter on input events (key and button presses) seen by Mutter, * client updates to the _NET_WM_USER_TIME property (if later than the current time) * and when focusing the window. * @@ -11212,7 +7121,7 @@ meta_window_get_user_time (MetaWindow *window) return window->net_wm_user_time; } -LOCAL_SYMBOL void +void meta_window_set_user_time (MetaWindow *window, guint32 timestamp) { @@ -11245,13 +7154,12 @@ meta_window_set_user_time (MetaWindow *window, /* If this is a terminal, user interaction with it means the user likely * doesn't want to have focus transferred for now due to new windows. */ - if (meta_prefs_get_focus_new_windows () == - C_DESKTOP_FOCUS_NEW_WINDOWS_STRICT && - __window_is_terminal (window)) + if (meta_prefs_get_focus_new_windows () == C_DESKTOP_FOCUS_NEW_WINDOWS_STRICT && + window_is_terminal (window)) window->display->allow_terminal_deactivation = FALSE; - } - g_object_notify (G_OBJECT (window), "user-time"); + g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_USER_TIME]); + } } /** @@ -11280,21 +7188,18 @@ meta_window_get_stable_sequence (MetaWindow *window) void meta_window_set_demands_attention (MetaWindow *window) { - - GList *stack; + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; MetaRectangle candidate_rect, other_rect; + GList *stack = window->display->stack->sorted; MetaWindow *other_window; - gboolean obscured; - MetaWorkspace *workspace; + gboolean obscured = FALSE; + + MetaWorkspace *workspace = workspace_manager->active_workspace; if (window->wm_state_demands_attention) return; - obscured = FALSE; - stack = window->screen->stack->sorted; - workspace = window->screen->active_workspace; - - if (workspace!=window->workspace) + if (!meta_window_located_on_workspace (window, workspace)) { /* windows on other workspaces are necessarily obscured */ obscured = TRUE; @@ -11305,7 +7210,7 @@ meta_window_set_demands_attention (MetaWindow *window) } else { - meta_window_get_outer_rect (window, &candidate_rect); + meta_window_get_frame_rect (window, &candidate_rect); /* The stack is sorted with the top windows first. */ @@ -11314,11 +7219,9 @@ meta_window_set_demands_attention (MetaWindow *window) other_window = stack->data; stack = stack->next; - if (other_window->on_all_workspaces || - window->on_all_workspaces || - other_window->workspace == window->workspace) + if (meta_window_located_on_workspace (other_window, workspace)) { - meta_window_get_outer_rect (other_window, &other_rect); + meta_window_get_frame_rect (other_window, &other_rect); if (meta_rectangle_overlap (&candidate_rect, &other_rect)) { @@ -11337,11 +7240,10 @@ meta_window_set_demands_attention (MetaWindow *window) window->wm_state_demands_attention = TRUE; set_net_wm_state (window); - g_object_notify (G_OBJECT (window), "demands-attention"); + g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_DEMANDS_ATTENTION]); g_signal_emit_by_name (window->display, "window-demands-attention", window); } -#ifdef WITH_VERBOSE_MODE else { /* If the window's in full view, there's no point setting the flag. */ @@ -11351,35 +7253,6 @@ meta_window_set_demands_attention (MetaWindow *window) "it's in full view\n", window->desc); } -#endif -} - -/** - * meta_window_is_demanding_attention: - * @window: A #MetaWindow - * - * Returns true if window has the demands-attention flag set. - * - * Return value: %TRUE if wm_state_demands_attention is set. - */ -gboolean -meta_window_is_demanding_attention (MetaWindow *window) -{ - return window->wm_state_demands_attention; -} - -/** - * meta_window_is_urgent: - * @window: A #MetaWindow - * - * Returns true if window has the urgent hint set. - * - * Return value: %TRUE if wm_hints_urgent is set. - */ -gboolean -meta_window_is_urgent (MetaWindow *window) -{ - return window->wm_hints_urgent; } void @@ -11392,12 +7265,13 @@ meta_window_unset_demands_attention (MetaWindow *window) { window->wm_state_demands_attention = FALSE; set_net_wm_state (window); - g_object_notify (G_OBJECT (window), "demands-attention"); + g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_DEMANDS_ATTENTION]); } } /** * meta_window_get_frame: (skip) + * @window: a #MetaWindow * */ MetaFrame * @@ -11438,8 +7312,8 @@ meta_window_is_shaded (MetaWindow *window) * meta_window_is_override_redirect: * @window: A #MetaWindow * - * Returns if this window isn't managed by muffin; it will - * control its own positioning and muffin won't draw decorations + * Returns: %TRUE if this window isn't managed by mutter; it will + * control its own positioning and mutter won't draw decorations * among other things. In X terminology this is "override redirect". */ gboolean @@ -11464,73 +7338,6 @@ meta_window_is_skip_taskbar (MetaWindow *window) return window->skip_taskbar; } -gboolean -meta_window_is_interesting (MetaWindow *window) -{ - if (window->override_redirect - || window->skip_taskbar) - return FALSE; - - switch (window->type) - { - /* Definitely ignore these. */ - case META_WINDOW_DESKTOP: - case META_WINDOW_DOCK: - case META_WINDOW_SPLASHSCREEN: - /* Should have already been handled by override_redirect above, - * but explicitly list here so we get the "unhandled enum" - * warning if in the future anything is added.*/ - case META_WINDOW_DROPDOWN_MENU: - case META_WINDOW_POPUP_MENU: - case META_WINDOW_TOOLTIP: - case META_WINDOW_NOTIFICATION: - case META_WINDOW_COMBO: - case META_WINDOW_DND: - case META_WINDOW_OVERRIDE_OTHER: - return FALSE; - case META_WINDOW_NORMAL: - case META_WINDOW_DIALOG: - case META_WINDOW_MODAL_DIALOG: - case META_WINDOW_MENU: - case META_WINDOW_TOOLBAR: - case META_WINDOW_UTILITY: - break; - default: - g_warning ("meta_window_is_interesting: default reached"); - break; - } - - return TRUE; -} - -/** - * meta_window_get_rect: - * @window: a #MetaWindow - * - * Gets the rectangle that bounds @window, ignoring any window decorations. - * - * Return value: (transfer none): the #MetaRectangle for the window - */ -MetaRectangle * -meta_window_get_rect (MetaWindow *window) -{ - return &window->rect; -} - -/** - * meta_window_get_screen: - * @window: a #MetaWindow - * - * Gets the #MetaScreen that the window is on. - * - * Return value: (transfer none): the #MetaScreen for the window - */ -MetaScreen * -meta_window_get_screen (MetaWindow *window) -{ - return window->screen; -} - /** * meta_window_get_display: * @window: A #MetaWindow @@ -11544,15 +7351,11 @@ meta_window_get_display (MetaWindow *window) } /** - * meta_window_get_xwindow: - * @window: A #MetaWindow - * - * Returns: The Window id of the @window - * note - we return unsigned long because Window - * Can't be introspected (but Window *is* a ulong) + * meta_window_get_xwindow: (skip) + * @window: a #MetaWindow * */ -unsigned long +Window meta_window_get_xwindow (MetaWindow *window) { return window->xwindow; @@ -11564,23 +7367,6 @@ meta_window_get_window_type (MetaWindow *window) return window->type; } -/** - * meta_window_get_window_type_atom: (skip) - * @window: a #MetaWindow - * - * Gets the X atom from the _NET_WM_WINDOW_TYPE property used by the - * application to set the window type. (Note that this is constrained - * to be some value that Muffin recognizes - a completely unrecognized - * type atom will be returned as None.) - * - * Return value: the raw X atom for the window type, or None - */ -Atom -meta_window_get_window_type_atom (MetaWindow *window) -{ - return window->type_atom; -} - /** * meta_window_get_workspace: * @window: a #MetaWindow @@ -11594,10 +7380,12 @@ meta_window_get_window_type_atom (MetaWindow *window) MetaWorkspace * meta_window_get_workspace (MetaWindow *window) { - if (window->on_all_workspaces) - return window->screen->active_workspace; + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; - return window->workspace; + if (window->on_all_workspaces) + return workspace_manager->active_workspace; + else + return window->workspace; } gboolean @@ -11651,6 +7439,35 @@ meta_window_get_wm_class_instance (MetaWindow *window) return window->res_name; } +/** + * meta_window_get_sandboxed_app_id: + * @window: a #MetaWindow + * + * Gets an unique id for a sandboxed app (currently flatpaks and snaps are + * supported). + * + * Return value: (transfer none): the sandboxed application ID or %NULL + **/ +const char * +meta_window_get_sandboxed_app_id (MetaWindow *window) +{ + /* We're abusing this API here not to break the gnome shell assumptions + * or adding a new function, to be renamed to generic names in new versions */ + return window->sandboxed_app_id; +} + +/** + * meta_window_get_gtk_theme_variant: + * @window: a #MetaWindow + * + * Return value: (transfer none): the theme variant or %NULL + **/ +const char * +meta_window_get_gtk_theme_variant (MetaWindow *window) +{ + return window->gtk_theme_variant; +} + /** * meta_window_get_gtk_application_id: * @window: a #MetaWindow @@ -11760,7 +7577,7 @@ meta_window_get_role (MetaWindow *window) * meta_window_get_title: * @window: a #MetaWindow * - * Returns the current title of the window. + * Returns: the current title of the window. */ const char * meta_window_get_title (MetaWindow *window) @@ -11795,30 +7612,28 @@ meta_window_get_transient_for (MetaWindow *window) { g_return_val_if_fail (META_IS_WINDOW (window), NULL); - if (window->xtransient_for) - return meta_display_lookup_x_window (window->display, - window->xtransient_for); + if (window->transient_for) + return window->transient_for; + else if (window->xtransient_for) + return meta_x11_display_lookup_x_window (window->display->x11_display, + window->xtransient_for); else return NULL; } /** - * meta_window_get_transient_for_as_xid: + * meta_window_get_client_pid: * @window: a #MetaWindow * - * Returns the XID of the window that is pointed to by the - * WM_TRANSIENT_FOR hint on this window (see XGetTransientForHint() - * or XSetTransientForHint()). Metacity keeps transient windows above their - * parents. A typical usage of this hint is for a dialog that wants to stay - * above its associated window. + * Returns the pid of the process that created this window, if available + * to the windowing system. * - * Return value: the window this window is transient for, or - * None if the WM_TRANSIENT_FOR hint is unset. + * Return value: the pid, or 0 if not known. */ -Window -meta_window_get_transient_for_as_xid (MetaWindow *window) +uint32_t +meta_window_get_client_pid (MetaWindow *window) { - return window->xtransient_for; + return META_WINDOW_GET_CLASS (window)->get_client_pid (window); } /** @@ -11838,26 +7653,6 @@ meta_window_get_pid (MetaWindow *window) return window->net_wm_pid; } -/** - * meta_window_get_client_pid: - * @window: a #MetaWindow - * - * Returns the client pid of the process that created this window, if known (obtained from XCB). - * - * Return value: the pid, or -1 if not known. - */ -int -meta_window_get_client_pid (MetaWindow *window) -{ - g_return_val_if_fail (META_IS_WINDOW (window), -1); - - if (window->client_pid == -2) { - update_client_pid (window); - } - - return window->client_pid; -} - /** * meta_window_get_client_machine: * @window: a #MetaWindow @@ -11882,40 +7677,19 @@ meta_window_get_client_machine (MetaWindow *window) * @window: a #MetaWindow * * Returns: %TRUE if this window originates from a host - * different from the one running muffin. + * different from the one running mutter. */ gboolean meta_window_is_remote (MetaWindow *window) { - g_return_val_if_fail (META_IS_WINDOW (window), FALSE); - - if (window->wm_client_machine != NULL) - return g_strcmp0 (window->wm_client_machine, window->display->hostname) != 0; - return FALSE; -} - -/** - * meta_window_is_modal: - * @window: a #MetaWindow - * - * Queries whether the window is in a modal state as described by the - * _NET_WM_STATE protocol. - * - * Return value: TRUE if the window is in modal state. - */ -gboolean -meta_window_is_modal (MetaWindow *window) -{ - g_return_val_if_fail (META_IS_WINDOW (window), FALSE); - - return window->wm_state_modal; + return window->is_remote; } /** - * meta_window_get_muffin_hints: + * meta_window_get_mutter_hints: * @window: a #MetaWindow * - * Gets the current value of the _MUFFIN_HINTS property. + * Gets the current value of the _MUTTER_HINTS property. * * The purpose of the hints is to allow fine-tuning of the Window Manager and * Compositor behaviour on per-window basis, and is intended primarily for @@ -11923,18 +7697,18 @@ meta_window_is_modal (MetaWindow *window) * * The property is a list of colon-separated key=value pairs. The key names for * any plugin-specific hints must be suitably namespaced to allow for shared - * use; 'muffin-' key prefix is reserved for internal use, and must not be used + * use; 'mutter-' key prefix is reserved for internal use, and must not be used * by plugins. * - * Return value: (transfer none): the _MUFFIN_HINTS string, or %NULL if no hints + * Return value: (transfer none): the _MUTTER_HINTS string, or %NULL if no hints * are set. */ const char * -meta_window_get_muffin_hints (MetaWindow *window) +meta_window_get_mutter_hints (MetaWindow *window) { g_return_val_if_fail (META_IS_WINDOW (window), NULL); - return window->muffin_hints; + return window->mutter_hints; } /** @@ -11996,8 +7770,7 @@ meta_window_get_frame_type (MetaWindow *window) /* can't add border if undecorated */ return META_FRAME_TYPE_LAST; } - else if ((window->border_only && base_type != META_FRAME_TYPE_ATTACHED) || - (window->hide_titlebar_when_maximized && META_WINDOW_MAXIMIZED (window))) + else if (window->border_only) { /* override base frame type */ return META_FRAME_TYPE_BORDER; @@ -12010,10 +7783,11 @@ meta_window_get_frame_type (MetaWindow *window) /** * meta_window_get_frame_bounds: + * @window: a #MetaWindow * * Gets a region representing the outer bounds of the window's frame. * - * Return value: (transfer none) (allow-none): a #cairo_region_t + * Return value: (transfer none) (nullable): a #cairo_region_t * holding the outer bounds of the window, or %NULL if the window * doesn't have a frame. */ @@ -12025,229 +7799,700 @@ meta_window_get_frame_bounds (MetaWindow *window) if (window->frame) window->frame_bounds = meta_frame_get_frame_bounds (window->frame); } - - return window->frame_bounds; + + return window->frame_bounds; +} + +/** + * meta_window_is_attached_dialog: + * @window: a #MetaWindow + * + * Tests if @window is should be attached to its parent window. + * (If the "attach_modal_dialogs" option is not enabled, this will + * always return %FALSE.) + * + * Return value: whether @window should be attached to its parent + */ +gboolean +meta_window_is_attached_dialog (MetaWindow *window) +{ + return window->attached; +} + +/** + * meta_window_get_tile_match: + * @window: a #MetaWindow + * + * Returns the matching tiled window on the same monitor as @window. This is + * the topmost tiled window in a complementary tile mode that is: + * + * - on the same monitor; + * - on the same workspace; + * - spanning the remaining monitor width; + * - there is no 3rd window stacked between both tiled windows that's + * partially visible in the common edge. + * + * Return value: (transfer none) (nullable): the matching tiled window or + * %NULL if it doesn't exist. + */ +MetaWindow * +meta_window_get_tile_match (MetaWindow *window) +{ + return window->tile_match; +} + +void +meta_window_compute_tile_match (MetaWindow *window) +{ + window->tile_match = meta_window_find_tile_match (window, window->tile_mode); +} + +static MetaWindow * +meta_window_find_tile_match (MetaWindow *window, + MetaTileMode current_mode) +{ + MetaWindow *match; + MetaStack *stack; + MetaTileMode match_tile_mode = META_TILE_NONE; + + if (window->shaded || window->minimized) + return NULL; + + if (current_mode == META_TILE_LEFT) + match_tile_mode = META_TILE_RIGHT; + else if (current_mode == META_TILE_RIGHT) + match_tile_mode = META_TILE_LEFT; + else + return NULL; + + stack = window->display->stack; + + for (match = meta_stack_get_top (stack); + match; + match = meta_stack_get_below (stack, match, FALSE)) + { + if (!match->shaded && + !match->minimized && + match->tile_mode == match_tile_mode && + match->tile_monitor_number == window->tile_monitor_number && + meta_window_get_workspace (match) == meta_window_get_workspace (window)) + break; + } + + if (match) + { + MetaWindow *above, *bottommost, *topmost; + MetaRectangle above_rect, bottommost_rect, topmost_rect; + + if (meta_stack_windows_cmp (window->display->stack, match, window) > 0) + { + topmost = match; + bottommost = window; + } + else + { + topmost = window; + bottommost = match; + } + + meta_window_get_frame_rect (bottommost, &bottommost_rect); + meta_window_get_frame_rect (topmost, &topmost_rect); + + /* + * If we are looking for a tile match while actually being tiled, + * rather than a match for a potential tile mode, then discard + * windows with too much gap or overlap + */ + if (window->tile_mode == current_mode && + !(meta_grab_op_is_resizing (window->display->grab_op) && + window->display->grab_window == window && + window->tile_match != NULL)) + { + int threshold = meta_prefs_get_drag_threshold (); + if (ABS (topmost_rect.x - bottommost_rect.x - bottommost_rect.width) > threshold && + ABS (bottommost_rect.x - topmost_rect.x - topmost_rect.width) > threshold) + return NULL; + } + + /* + * If there's a window stacked in between which is partially visible + * behind the topmost tile we don't consider the tiles to match. + */ + for (above = meta_stack_get_above (stack, bottommost, FALSE); + above && above != topmost; + above = meta_stack_get_above (stack, above, FALSE)) + { + if (above->minimized || + above->monitor != window->monitor || + meta_window_get_workspace (above) != meta_window_get_workspace (window)) + continue; + + meta_window_get_frame_rect (above, &above_rect); + + if (meta_rectangle_overlap (&above_rect, &bottommost_rect) && + meta_rectangle_overlap (&above_rect, &topmost_rect)) + return NULL; + } + } + + return match; +} + +void +meta_window_set_title (MetaWindow *window, + const char *title) +{ + g_free (window->title); + window->title = g_strdup (title); + + if (window->frame) + meta_frame_update_title (window->frame); + + meta_window_update_desc (window); + + g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_TITLE]); +} + +void +meta_window_set_wm_class (MetaWindow *window, + const char *wm_class, + const char *wm_instance) +{ + g_free (window->res_class); + g_free (window->res_name); + + window->res_name = g_strdup (wm_instance); + window->res_class = g_strdup (wm_class); + + g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_WM_CLASS]); +} + +void +meta_window_set_gtk_dbus_properties (MetaWindow *window, + const char *application_id, + const char *unique_bus_name, + const char *appmenu_path, + const char *menubar_path, + const char *application_object_path, + const char *window_object_path) +{ + g_object_freeze_notify (G_OBJECT (window)); + + g_free (window->gtk_application_id); + window->gtk_application_id = g_strdup (application_id); + g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_GTK_APPLICATION_ID]); + + g_free (window->gtk_unique_bus_name); + window->gtk_unique_bus_name = g_strdup (unique_bus_name); + g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_GTK_UNIQUE_BUS_NAME]); + + g_free (window->gtk_app_menu_object_path); + window->gtk_app_menu_object_path = g_strdup (appmenu_path); + g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_GTK_APP_MENU_OBJECT_PATH]); + + g_free (window->gtk_menubar_object_path); + window->gtk_menubar_object_path = g_strdup (menubar_path); + g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_GTK_MENUBAR_OBJECT_PATH]); + + g_free (window->gtk_application_object_path); + window->gtk_application_object_path = g_strdup (application_object_path); + g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_GTK_APPLICATION_OBJECT_PATH]); + + g_free (window->gtk_window_object_path); + window->gtk_window_object_path = g_strdup (window_object_path); + g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_GTK_WINDOW_OBJECT_PATH]); + + g_object_thaw_notify (G_OBJECT (window)); +} + +static gboolean +check_transient_for_loop (MetaWindow *window, + MetaWindow *parent) +{ + while (parent) + { + if (parent == window) + return TRUE; + parent = parent->transient_for; + } + + return FALSE; +} + +gboolean +meta_window_has_transient_type (MetaWindow *window) +{ + return (window->type == META_WINDOW_DIALOG || + window->type == META_WINDOW_MODAL_DIALOG || + window->type == META_WINDOW_TOOLBAR || + window->type == META_WINDOW_MENU || + window->type == META_WINDOW_UTILITY); +} + +void +meta_window_set_transient_for (MetaWindow *window, + MetaWindow *parent) +{ + if (check_transient_for_loop (window, parent)) + { + meta_warning ("Setting %s transient for %s would create a loop.\n", + window->desc, parent->desc); + return; + } + + if (meta_window_appears_focused (window) && window->transient_for != NULL) + meta_window_propagate_focus_appearance (window, FALSE); + + /* may now be a dialog */ + if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) + { + meta_window_x11_recalc_window_type (window); + + if (!window->constructing) + { + /* If the window attaches, detaches, or changes attached + * parents, we need to destroy the MetaWindow and let a new one + * be created (which happens as a side effect of + * meta_window_unmanage()). The condition below is correct + * because we know window->transient_for has changed. + */ + if (window->attached || meta_window_should_attach_to_parent (window)) + { + guint32 timestamp; + + timestamp = + meta_display_get_current_time_roundtrip (window->display); + meta_window_unmanage (window, timestamp); + return; + } + } + } + else if (window->attached && parent == NULL) + { + guint32 timestamp; + + timestamp = + meta_display_get_current_time_roundtrip (window->display); + meta_window_unmanage (window, timestamp); + return; + } + /* We know this won't create a reference cycle because we check for loops */ + g_clear_object (&window->transient_for); + window->transient_for = parent ? g_object_ref (parent) : NULL; + + /* update stacking constraints */ + if (!window->override_redirect) + meta_stack_update_transient (window->display->stack, window); + + /* possibly change its group. We treat being a window's transient as + * equivalent to making it your group leader, to work around shortcomings + * in programs such as xmms-- see #328211. + */ + if (window->xtransient_for != None && + window->xgroup_leader != None && + window->xtransient_for != window->xgroup_leader) + meta_window_group_leader_changed (window); + + if (!window->constructing && !window->override_redirect) + meta_window_queue (window, META_QUEUE_MOVE_RESIZE | META_QUEUE_CALC_SHOWING); + + if (meta_window_appears_focused (window) && window->transient_for != NULL) + meta_window_propagate_focus_appearance (window, TRUE); +} + +void +meta_window_set_opacity (MetaWindow *window, + guint8 opacity) +{ + window->opacity = opacity; + + meta_compositor_window_opacity_changed (window->display->compositor, window); +} + +static void +reset_ignored_crossing_serials (MetaDisplay *display) +{ + int i; + + i = 0; + while (i < N_IGNORED_CROSSING_SERIALS) + { + display->ignored_crossing_serials[i] = 0; + ++i; + } +} + +typedef struct +{ + MetaWindow *window; + int pointer_x; + int pointer_y; +} MetaFocusData; + +static void +mouse_mode_focus (MetaWindow *window, + guint32 timestamp) +{ + MetaDisplay *display = window->display; + + if (window->override_redirect) + return; + + if (window->type != META_WINDOW_DESKTOP) + { + meta_topic (META_DEBUG_FOCUS, + "Focusing %s at time %u.\n", window->desc, timestamp); + + meta_window_focus (window, timestamp); + + if (meta_prefs_get_auto_raise ()) + meta_display_queue_autoraise_callback (display, window); + else + meta_topic (META_DEBUG_FOCUS, "Auto raise is disabled\n"); + } + else + { + /* In mouse focus mode, we defocus when the mouse *enters* + * the DESKTOP window, instead of defocusing on LeaveNotify. + * This is because having the mouse enter override-redirect + * child windows unfortunately causes LeaveNotify events that + * we can't distinguish from the mouse actually leaving the + * toplevel window as we expect. But, since we filter out + * EnterNotify events on override-redirect windows, this + * alternative mechanism works great. + */ + if (meta_prefs_get_focus_mode() == C_DESKTOP_FOCUS_MODE_MOUSE && + display->focus_window != NULL) + { + meta_topic (META_DEBUG_FOCUS, + "Unsetting focus from %s due to mouse entering " + "the DESKTOP window\n", + display->focus_window->desc); + meta_display_unset_input_focus (display, timestamp); + } + } } -/** - * meta_window_is_attached_dialog: - * @window: a #MetaWindow - * - * Tests if @window is should be attached to its parent window. - * (If the "attach_modal_dialogs" option is not enabled, this will - * always return %FALSE.) - * - * Return value: whether @window should be attached to its parent - */ -gboolean -meta_window_is_attached_dialog (MetaWindow *window) +static gboolean +window_has_pointer_wayland (MetaWindow *window) { - return window->attached; -} + ClutterSeat *seat; + ClutterInputDevice *dev; + ClutterActor *pointer_actor, *window_actor; -/** - * meta_window_get_tile_match: - * - * Returns the matching tiled window on the same monitory as @window. This is - * the topmost tiled window in a complementary tile mode that is: - * - * - on the same monitor; - * - on the same workspace; - * - spanning the remaining monitor width; - * - there is no 3rd window stacked between both tiled windows that's - * partially visible in the common edge. - * - * Return value: (transfer none) (allow-none): the matching tiled window or - * %NULL if it doesn't exist. - */ -MetaWindow * -meta_window_get_tile_match (MetaWindow *window) -{ - return window->tile_match; + seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); + dev = clutter_seat_get_pointer (seat); + pointer_actor = clutter_input_device_get_pointer_actor (dev); + window_actor = CLUTTER_ACTOR (meta_window_get_compositor_private (window)); + + return pointer_actor && clutter_actor_contains (window_actor, pointer_actor); } -LOCAL_SYMBOL void -meta_window_compute_tile_match (MetaWindow *window) +static gboolean +window_has_pointer_x11 (MetaWindow *window) { - MetaWindow *match; - MetaStack *stack; - MetaTileMode match_tile_mode; + MetaX11Display *x11_display = window->display->x11_display; + Window root, child; + double root_x, root_y, x, y; + XIButtonState buttons; + XIModifierState mods; + XIGroupState group; - window->tile_match = NULL; + meta_x11_error_trap_push (x11_display); + XIQueryPointer (x11_display->xdisplay, + META_VIRTUAL_CORE_POINTER_ID, + x11_display->xroot, + &root, &child, + &root_x, &root_y, &x, &y, + &buttons, &mods, &group); + meta_x11_error_trap_pop (x11_display); + free (buttons.mask); - if (window->shaded || window->minimized) - return; + return meta_x11_display_lookup_x_window (x11_display, child) == window; +} - match_tile_mode = META_TILE_NONE; - if (META_WINDOW_TILED_LEFT (window)) - match_tile_mode = META_TILE_RIGHT; - else if (META_WINDOW_TILED_RIGHT (window)) - match_tile_mode = META_TILE_LEFT; - else if (META_WINDOW_TILED_ULC (window)) - match_tile_mode = META_TILE_ULC; - else if (META_WINDOW_TILED_LLC (window)) - match_tile_mode = META_TILE_LLC; - else if (META_WINDOW_TILED_URC (window)) - match_tile_mode = META_TILE_URC; - else if (META_WINDOW_TILED_LRC (window)) - match_tile_mode = META_TILE_LRC; - else if (META_WINDOW_TILED_TOP (window)) - match_tile_mode = META_TILE_TOP; - else if (META_WINDOW_TILED_BOTTOM (window)) - match_tile_mode = META_TILE_BOTTOM; +gboolean +meta_window_has_pointer (MetaWindow *window) +{ + if (meta_is_wayland_compositor ()) + return window_has_pointer_wayland (window); else - return; + return window_has_pointer_x11 (window); +} + +static gboolean +window_focus_on_pointer_rest_callback (gpointer data) +{ + MetaFocusData *focus_data = data; + MetaWindow *window = focus_data->window; + MetaDisplay *display = window->display; + MetaBackend *backend = meta_get_backend (); + MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend); + int root_x, root_y; + guint32 timestamp; - stack = window->screen->stack; + if (meta_prefs_get_focus_mode () == C_DESKTOP_FOCUS_MODE_CLICK) + goto out; - for (match = meta_stack_get_top (stack); - match; - match = meta_stack_get_below (stack, match, FALSE)) + meta_cursor_tracker_get_pointer (cursor_tracker, &root_x, &root_y, NULL); + + if (root_x != focus_data->pointer_x || + root_y != focus_data->pointer_y) { - if (!match->shaded && - !match->minimized && - match->tile_mode == match_tile_mode && - match->monitor == window->monitor && - meta_window_get_workspace (match) == meta_window_get_workspace (window)) - break; + focus_data->pointer_x = root_x; + focus_data->pointer_y = root_y; + return G_SOURCE_CONTINUE; } - if (match) - { - MetaWindow *above, *bottommost, *topmost; - MetaRectangle above_rect, bottommost_rect, topmost_rect; + if (!meta_window_has_pointer (window)) + goto out; - if (meta_stack_windows_cmp (window->screen->stack, match, window) > 0) - { - topmost = match; - bottommost = window; - } - else - { - topmost = window; - bottommost = match; - } + timestamp = meta_display_get_current_time_roundtrip (display); + mouse_mode_focus (window, timestamp); - meta_window_get_outer_rect (bottommost, &bottommost_rect); - meta_window_get_outer_rect (topmost, &topmost_rect); - /* - * If there's a window stacked in between which is partially visible - * behind the topmost tile we don't consider the tiles to match. - */ - for (above = meta_stack_get_above (stack, bottommost, FALSE); - above && above != topmost; - above = meta_stack_get_above (stack, above, FALSE)) - { - if (above->minimized || - above->monitor != window->monitor || - meta_window_get_workspace (above) != meta_window_get_workspace (window)) - continue; + out: + display->focus_timeout_id = 0; + return G_SOURCE_REMOVE; +} - meta_window_get_outer_rect (above, &above_rect); +/* The interval, in milliseconds, we use in focus-follows-mouse + * mode to check whether the pointer has stopped moving after a + * crossing event. + */ +#define FOCUS_TIMEOUT_DELAY 25 - if (meta_rectangle_overlap (&above_rect, &bottommost_rect) && - meta_rectangle_overlap (&above_rect, &topmost_rect)) - return; - } +static void +queue_focus_callback (MetaDisplay *display, + MetaWindow *window, + int pointer_x, + int pointer_y) +{ + MetaFocusData *focus_data; - window->tile_match = match; - } + focus_data = g_new (MetaFocusData, 1); + focus_data->window = window; + focus_data->pointer_x = pointer_x; + focus_data->pointer_y = pointer_y; + + g_clear_handle_id (&display->focus_timeout_id, g_source_remove); + + display->focus_timeout_id = + g_timeout_add_full (G_PRIORITY_DEFAULT, + FOCUS_TIMEOUT_DELAY, + window_focus_on_pointer_rest_callback, + focus_data, + g_free); + g_source_set_name_by_id (display->focus_timeout_id, + "[mutter] window_focus_on_pointer_rest_callback"); } void -meta_window_set_tile_type (MetaWindow *window, - MetaWindowTileType type) +meta_window_handle_enter (MetaWindow *window, + guint32 timestamp, + guint root_x, + guint root_y) { - g_return_if_fail (META_IS_WINDOW (window)); + MetaDisplay *display = window->display; + + switch (meta_prefs_get_focus_mode ()) + { + case C_DESKTOP_FOCUS_MODE_SLOPPY: + case C_DESKTOP_FOCUS_MODE_MOUSE: + display->mouse_mode = TRUE; + if (window->type != META_WINDOW_DOCK) + { + if (meta_prefs_get_focus_change_on_pointer_rest()) + queue_focus_callback (display, window, root_x, root_y); + else + mouse_mode_focus (window, timestamp); - if (window->tile_type != type) { - window->tile_type = type; - g_object_freeze_notify (G_OBJECT (window)); - g_object_notify (G_OBJECT (window), "tile-type"); - g_object_thaw_notify (G_OBJECT (window)); + /* stop ignoring stuff */ + reset_ignored_crossing_serials (display); + } + break; + case C_DESKTOP_FOCUS_MODE_CLICK: + break; } + + if (window->type == META_WINDOW_DOCK) + meta_window_raise (window); } -MetaWindowTileType -meta_window_get_tile_type (MetaWindow *window) +void +meta_window_handle_leave (MetaWindow *window) { - g_return_val_if_fail (META_IS_WINDOW (window), META_WINDOW_TILE_TYPE_NONE); - - return window->tile_type; + if (window->type == META_WINDOW_DOCK && !window->has_focus) + meta_window_lower (window); } -#define ORIGIN_CONSTANT 1 -#define EXTREME_CONSTANT 2 -#define COMMON_EDGE_PADDING 10 +gboolean +meta_window_handle_ui_frame_event (MetaWindow *window, + const ClutterEvent *event) +{ + if (!window->frame) + return FALSE; -static void -get_extra_padding_for_common_monitor_edges (MetaWindow *window, - gint monitor_num, - MetaRectangle cur_rect, - gint *left_shift, - gint *right_shift, - gint *up_shift, - gint *down_shift) -{ - gint num_mons; - gint i; - MetaRectangle other_rect; - num_mons = meta_screen_get_n_monitors (window->screen); - - if (num_mons == 1) - return; + return meta_ui_frame_handle_event (window->frame->ui_frame, event); +} - for (i = 0; i < num_mons; i++) { - if (i == monitor_num) - continue; +void +meta_window_handle_ungrabbed_event (MetaWindow *window, + const ClutterEvent *event) +{ + MetaDisplay *display = window->display; + gboolean unmodified; + gboolean is_window_grab; + gboolean is_window_button_grab_allowed; + ClutterModifierType grab_mods, event_mods; + ClutterInputDevice *source; + gfloat x, y; + guint button; + + if (window->unmanaging) + return; - meta_screen_get_monitor_geometry (window->screen, i, &other_rect); + if (event->type != CLUTTER_BUTTON_PRESS && + event->type != CLUTTER_TOUCH_BEGIN) + return; - if (BOX_CENTER_X (other_rect) < BOX_LEFT (cur_rect)) { - *left_shift += COMMON_EDGE_PADDING; - continue; - } - if (BOX_CENTER_X (other_rect) > BOX_RIGHT (cur_rect)) { - *right_shift += COMMON_EDGE_PADDING; - continue; - } - if (BOX_CENTER_Y (other_rect) < BOX_TOP (cur_rect)) { - *up_shift += COMMON_EDGE_PADDING; - continue; - } - if (BOX_CENTER_Y (other_rect) > BOX_BOTTOM (cur_rect)) { - *down_shift += COMMON_EDGE_PADDING; - continue; - } + if (event->type == CLUTTER_TOUCH_BEGIN) + { + ClutterEventSequence *sequence; + + button = 1; + sequence = clutter_event_get_event_sequence (event); + if (!meta_display_is_pointer_emulating_sequence (window->display, sequence)) + return; } -} + else + button = clutter_event_get_button (event); -gboolean -meta_window_mouse_on_edge (MetaWindow *window, gint x, gint y) -{ - MetaRectangle work_area; - gboolean ret = FALSE; - int monitor; - gint left_shift, right_shift, up_shift, down_shift; - left_shift = right_shift = up_shift = down_shift = 0; + if (display->grab_op != META_GRAB_OP_NONE) + return; + + /* Some windows might not ask for input, in which case we might be here + * because we selected for ButtonPress on the root window. In that case, + * we have to take special care not to act for an override-redirect window. + */ + if (window->override_redirect) + return; - monitor = meta_screen_get_current_monitor (window->screen); - meta_window_get_work_area_for_monitor (window, monitor, &work_area); + /* Don't focus panels--they must explicitly request focus. + * See bug 160470 + */ + if (window->type != META_WINDOW_DOCK) + { + meta_topic (META_DEBUG_FOCUS, + "Focusing %s due to button %u press (display.c)\n", + window->desc, button); + meta_window_focus (window, event->any.time); + meta_window_check_alive (window, event->any.time); + } + else + /* However, do allow terminals to lose focus due to new + * window mappings after the user clicks on a panel. + */ + display->allow_terminal_deactivation = TRUE; + + /* We have three passive button grabs: + * - on any button, without modifiers => focuses and maybe raises the window + * - on resize button, with modifiers => start an interactive resizing + * (normally <Super>middle) + * - on move button, with modifiers => start an interactive move + * (normally <Super>left) + * - on menu button, with modifiers => show the window menu + * (normally <Super>right) + * + * We may get here because we actually have a button + * grab on the window, or because we're a wayland + * compositor and thus we see all the events, so we + * need to check if the event is interesting. + * We want an event that is not modified for a window. + * + * We may have other events on the window, for example + * a click on a frame button, but that's not for us to + * care about. Just let the event through. + */ - get_extra_padding_for_common_monitor_edges (window, - monitor, - work_area, - &left_shift, - &right_shift, - &up_shift, - &down_shift); + grab_mods = meta_display_get_window_grab_modifiers (display); + event_mods = clutter_event_get_state (event); + unmodified = (event_mods & grab_mods) == 0; + source = clutter_event_get_source_device (event); + is_window_button_grab_allowed = !display->focus_window || + !meta_window_shortcuts_inhibited (display->focus_window, source); + is_window_grab = (is_window_button_grab_allowed && + ((event_mods & grab_mods) == grab_mods)); - ret = x <= BOX_LEFT (work_area) + ORIGIN_CONSTANT + left_shift || - x >= BOX_RIGHT (work_area) - EXTREME_CONSTANT - right_shift || - y <= BOX_TOP (work_area) + ORIGIN_CONSTANT + up_shift || - y >= BOX_BOTTOM (work_area) - EXTREME_CONSTANT - down_shift; + clutter_event_get_coords (event, &x, &y); - return ret; + if (unmodified) + { + if (meta_prefs_get_raise_on_click ()) + meta_window_raise (window); + else + meta_topic (META_DEBUG_FOCUS, + "Not raising window on click due to don't-raise-on-click option\n"); + } + else if (is_window_grab && (int) button == meta_prefs_get_mouse_button_resize ()) + { + if (window->has_resize_func) + { + gboolean north, south; + gboolean west, east; + MetaRectangle frame_rect; + MetaGrabOp op = META_GRAB_OP_WINDOW_BASE; + + meta_window_get_frame_rect (window, &frame_rect); + + west = x < (frame_rect.x + 1 * frame_rect.width / 3); + east = x > (frame_rect.x + 2 * frame_rect.width / 3); + north = y < (frame_rect.y + 1 * frame_rect.height / 3); + south = y > (frame_rect.y + 2 * frame_rect.height / 3); + + if (west) + op |= META_GRAB_OP_WINDOW_DIR_WEST; + if (east) + op |= META_GRAB_OP_WINDOW_DIR_EAST; + if (north) + op |= META_GRAB_OP_WINDOW_DIR_NORTH; + if (south) + op |= META_GRAB_OP_WINDOW_DIR_SOUTH; + + if (op != META_GRAB_OP_WINDOW_BASE) + meta_display_begin_grab_op (display, + window, + op, + TRUE, + FALSE, + button, + 0, + event->any.time, + x, y); + } + } + else if (is_window_grab && (int) button == meta_prefs_get_mouse_button_menu ()) + { + if (meta_prefs_get_raise_on_click ()) + meta_window_raise (window); + meta_window_show_menu (window, + META_WINDOW_MENU_WM, + x, y); + } + else if (is_window_grab && (int) button == 1) + { + if (window->has_move_func) + { + meta_display_begin_grab_op (display, + window, + META_GRAB_OP_MOVING, + TRUE, + FALSE, + button, + 0, + event->any.time, + x, y); + } + } } gboolean @@ -12281,214 +8526,135 @@ meta_window_is_always_on_all_workspaces (MetaWindow *window) } gboolean -meta_window_is_always_on_top (MetaWindow *window) +meta_window_is_above (MetaWindow *window) { return window->wm_state_above; } gboolean -meta_window_can_move (MetaWindow *window) +meta_window_allows_move (MetaWindow *window) { return META_WINDOW_ALLOWS_MOVE (window); } gboolean -meta_window_can_resize (MetaWindow *window) +meta_window_allows_resize (MetaWindow *window) { return META_WINDOW_ALLOWS_RESIZE (window); } -/** - * meta_window_can_tile: - * @window: a #MetaWindow - * @mode: the #MetaTileMode to check for - * - * Tests if @window can be tiled or snapped in the supplied - * tiling zone - * - * Return value: whether @window can be tiled - */ +void +meta_window_set_urgent (MetaWindow *window, + gboolean urgent) +{ + if (window->urgent == urgent) + return; -gboolean -meta_window_can_tile (MetaWindow *window, MetaTileMode mode) + window->urgent = urgent; + g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_URGENT]); + + if (urgent) + g_signal_emit_by_name (window->display, "window-marked-urgent", window); +} + +void +meta_window_grab_op_began (MetaWindow *window, + MetaGrabOp op) { - g_return_val_if_fail (META_IS_WINDOW (window), FALSE); + META_WINDOW_GET_CLASS (window)->grab_op_began (window, op); +} - switch (mode) { - case META_TILE_LEFT: - case META_TILE_RIGHT: - return meta_window_can_tile_side_by_side (window); - case META_TILE_TOP: - case META_TILE_BOTTOM: - return meta_window_can_tile_top_bottom (window); - case META_TILE_ULC: - case META_TILE_LLC: - case META_TILE_URC: - case META_TILE_LRC: - return meta_window_can_tile_corner (window); - case META_TILE_MAXIMIZE: - case META_TILE_NONE: - return TRUE; - default: - return FALSE; - } +void +meta_window_grab_op_ended (MetaWindow *window, + MetaGrabOp op) +{ + META_WINDOW_GET_CLASS (window)->grab_op_ended (window, op); } -static void -update_edge_constraints (MetaWindow *window) +void +meta_window_emit_size_changed (MetaWindow *window) { - switch (window->tile_mode) - { - case META_TILE_NONE: - window->edge_constraints[0] = META_EDGE_CONSTRAINT_NONE; - window->edge_constraints[1] = META_EDGE_CONSTRAINT_NONE; - window->edge_constraints[2] = META_EDGE_CONSTRAINT_NONE; - window->edge_constraints[3] = META_EDGE_CONSTRAINT_NONE; - break; + g_signal_emit (window, window_signals[SIZE_CHANGED], 0); +} - case META_TILE_MAXIMIZE: - window->edge_constraints[0] = META_EDGE_CONSTRAINT_MONITOR; - window->edge_constraints[1] = META_EDGE_CONSTRAINT_MONITOR; - window->edge_constraints[2] = META_EDGE_CONSTRAINT_MONITOR; - window->edge_constraints[3] = META_EDGE_CONSTRAINT_MONITOR; - break; +MetaPlacementRule * +meta_window_get_placement_rule (MetaWindow *window) +{ + return window->placement.rule; +} - case META_TILE_LEFT: - window->edge_constraints[0] = META_EDGE_CONSTRAINT_MONITOR; - window->edge_constraints[1] = META_EDGE_CONSTRAINT_NONE; - window->edge_constraints[2] = META_EDGE_CONSTRAINT_MONITOR; - window->edge_constraints[3] = META_EDGE_CONSTRAINT_MONITOR; - break; +void +meta_window_force_restore_shortcuts (MetaWindow *window, + ClutterInputDevice *source) +{ + META_WINDOW_GET_CLASS (window)->force_restore_shortcuts (window, source); +} - case META_TILE_RIGHT: - window->edge_constraints[0] = META_EDGE_CONSTRAINT_MONITOR; - window->edge_constraints[1] = META_EDGE_CONSTRAINT_MONITOR; - window->edge_constraints[2] = META_EDGE_CONSTRAINT_MONITOR; - window->edge_constraints[3] = META_EDGE_CONSTRAINT_NONE; - break; +gboolean +meta_window_shortcuts_inhibited (MetaWindow *window, + ClutterInputDevice *source) +{ + return META_WINDOW_GET_CLASS (window)->shortcuts_inhibited (window, source); +} - case META_TILE_TOP: - window->edge_constraints[0] = META_EDGE_CONSTRAINT_MONITOR; - window->edge_constraints[1] = META_EDGE_CONSTRAINT_MONITOR; - window->edge_constraints[2] = META_EDGE_CONSTRAINT_NONE; - window->edge_constraints[3] = META_EDGE_CONSTRAINT_MONITOR; - break; +gboolean +meta_window_is_focusable (MetaWindow *window) +{ + g_return_val_if_fail (!window->unmanaging, FALSE); - case META_TILE_BOTTOM: - window->edge_constraints[0] = META_EDGE_CONSTRAINT_NONE; - window->edge_constraints[1] = META_EDGE_CONSTRAINT_MONITOR; - window->edge_constraints[2] = META_EDGE_CONSTRAINT_MONITOR; - window->edge_constraints[3] = META_EDGE_CONSTRAINT_MONITOR; - break; - case META_TILE_ULC: - window->edge_constraints[0] = META_EDGE_CONSTRAINT_MONITOR; - window->edge_constraints[1] = META_EDGE_CONSTRAINT_NONE; - window->edge_constraints[2] = META_EDGE_CONSTRAINT_NONE; - window->edge_constraints[3] = META_EDGE_CONSTRAINT_MONITOR; - break; - case META_TILE_URC: - window->edge_constraints[0] = META_EDGE_CONSTRAINT_MONITOR; - window->edge_constraints[1] = META_EDGE_CONSTRAINT_MONITOR; - window->edge_constraints[2] = META_EDGE_CONSTRAINT_NONE; - window->edge_constraints[3] = META_EDGE_CONSTRAINT_NONE; - break; - case META_TILE_LLC: - window->edge_constraints[0] = META_EDGE_CONSTRAINT_NONE; - window->edge_constraints[1] = META_EDGE_CONSTRAINT_NONE; - window->edge_constraints[2] = META_EDGE_CONSTRAINT_MONITOR; - window->edge_constraints[3] = META_EDGE_CONSTRAINT_MONITOR; - break; - case META_TILE_LRC: - window->edge_constraints[0] = META_EDGE_CONSTRAINT_NONE; - window->edge_constraints[1] = META_EDGE_CONSTRAINT_MONITOR; - window->edge_constraints[2] = META_EDGE_CONSTRAINT_MONITOR; - window->edge_constraints[3] = META_EDGE_CONSTRAINT_NONE; - break; - } + return META_WINDOW_GET_CLASS (window)->is_focusable (window); +} - /* h/vmaximize also modify the edge constraints */ - if (window->maximized_vertically) - { - window->edge_constraints[0] = META_EDGE_CONSTRAINT_MONITOR; - window->edge_constraints[2] = META_EDGE_CONSTRAINT_MONITOR; - } +gboolean +meta_window_can_ping (MetaWindow *window) +{ + g_return_val_if_fail (!window->unmanaging, FALSE); - if (window->maximized_horizontally) - { - window->edge_constraints[1] = META_EDGE_CONSTRAINT_MONITOR; - window->edge_constraints[3] = META_EDGE_CONSTRAINT_MONITOR; - } + return META_WINDOW_GET_CLASS (window)->can_ping (window); +} + +gboolean +meta_window_is_stackable (MetaWindow *window) +{ + return META_WINDOW_GET_CLASS (window)->is_stackable (window); +} + +gboolean +meta_window_is_focus_async (MetaWindow *window) +{ + return META_WINDOW_GET_CLASS (window)->is_focus_async (window); +} + +MetaStackLayer +meta_window_calculate_layer (MetaWindow *window) +{ + return META_WINDOW_GET_CLASS (window)->calculate_layer (window); } /** - * meta_window_tile: + * meta_window_get_id: * @window: a #MetaWindow - * @mode: the #MetaTileMode to use - * @snap: whether to snap the window (as opposed to simple tile) * - * Tiles or snaps the window in the requested configuration + * Returns the window id associated with window. * - * Return value: whether or not @window was successfully tiled + * Returns: The window id */ - -gboolean -meta_window_tile (MetaWindow *window, - MetaTileMode mode, - gboolean snap) +uint64_t +meta_window_get_id (MetaWindow *window) { - g_return_val_if_fail (META_IS_WINDOW (window), FALSE); - - if (!meta_window_can_tile (window, mode)) - return FALSE; - - if (mode != META_TILE_NONE) { - window->last_tile_mode = window->tile_mode; - window->snap_queued = snap; - window->tile_monitor_number = window->monitor->number; - window->tile_mode = mode; - window->custom_snap_size = FALSE; - window->saved_maximize = FALSE; - /* Maximization constraints beat tiling constraints, so if the window - * is maximized, tiling won't have any effect unless we unmaximize it - * horizontally first; rather than calling meta_window_unmaximize(), - * we just set the flag and rely on meta_window_real_tile() syncing it to - * save an additional roundtrip. - */ - meta_window_real_tile (window, TRUE); - } else { - window->last_tile_mode = window->tile_mode; - window->custom_snap_size = FALSE; - window->tile_monitor_number = window->saved_maximize ? window->monitor->number - : -1; - if (window->saved_maximize) - meta_window_maximize (window, META_MAXIMIZE_VERTICAL | - META_MAXIMIZE_HORIZONTAL); - else - meta_window_unmaximize (window, META_MAXIMIZE_VERTICAL | - META_MAXIMIZE_HORIZONTAL); - } - - return TRUE; + return window->id; } /** - * meta_window_get_icon_name: + * meta_window_get_client_type: * @window: a #MetaWindow * - * Returns the currently set icon name or icon path for the window. - * - * Note: + * Returns the #MetaWindowClientType of the window. * - * This will currently only be non-NULL for programs that use XAppGtkWindow - * in place of GtkWindow and use xapp_gtk_window_set_icon_name() or - * set_icon_from_file(). These methods will need to be used explicitly in - * C programs, but for introspection use you should not need to treat it any - * differently (except for using the correct window class.) + * Returns: The root ancestor window */ -const char * -meta_window_get_icon_name (MetaWindow *window) +MetaWindowClientType +meta_window_get_client_type (MetaWindow *window) { - g_return_val_if_fail (META_IS_WINDOW (window), NULL); - - return window->theme_icon_name; + return window->client_type; } diff --git a/src/core/workspace-private.h b/src/core/workspace-private.h index 3a1436e5b..a58b2347d 100644 --- a/src/core/workspace-private.h +++ b/src/core/workspace-private.h @@ -10,10 +10,10 @@ * are unmapped. */ -/* +/* * Copyright (C) 2001 Havoc Pennington * Copyright (C) 2004, 2005 Elijah Newren - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the @@ -23,24 +23,23 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_WORKSPACE_PRIVATE_H #define META_WORKSPACE_PRIVATE_H -#include <meta/workspace.h> -#include "window-private.h" +#include "core/window-private.h" +#include "meta/workspace.h" struct _MetaWorkspace { GObject parent_instance; - MetaScreen *screen; - + MetaDisplay *display; + MetaWorkspaceManager *manager; + GList *windows; /* The "MRU list", or "most recently used" list, is a list of @@ -56,16 +55,14 @@ struct _MetaWorkspace GList *list_containing_self; + GHashTable *logical_monitor_data; + MetaRectangle work_area_screen; - MetaRectangle *work_area_monitor; GList *screen_region; - GList **monitor_region; - gint n_monitor_regions; GList *screen_edges; GList *monitor_edges; GSList *builtin_struts; GSList *all_struts; - GList *snapped_windows; guint work_areas_invalid : 1; guint showing_desktop : 1; @@ -76,24 +73,31 @@ struct _MetaWorkspaceClass GObjectClass parent_class; }; -MetaWorkspace* meta_workspace_new (MetaScreen *screen); +MetaWorkspace* meta_workspace_new (MetaWorkspaceManager *workspace_manager); void meta_workspace_remove (MetaWorkspace *workspace); void meta_workspace_add_window (MetaWorkspace *workspace, MetaWindow *window); void meta_workspace_remove_window (MetaWorkspace *workspace, MetaWindow *window); -void meta_workspace_update_snapped_windows (MetaWorkspace *workspace); -gboolean meta_workspace_has_snapped_windows (MetaWorkspace *workspace); -void meta_workspace_recalc_for_snapped_windows (MetaWorkspace *workspace); void meta_workspace_relocate_windows (MetaWorkspace *workspace, MetaWorkspace *new_home); +void meta_workspace_get_work_area_for_logical_monitor (MetaWorkspace *workspace, + MetaLogicalMonitor *logical_monitor, + MetaRectangle *area); + void meta_workspace_invalidate_work_area (MetaWorkspace *workspace); GList* meta_workspace_get_onscreen_region (MetaWorkspace *workspace); -GList* meta_workspace_get_onmonitor_region (MetaWorkspace *workspace, - int which_monitor); +GList * meta_workspace_get_onmonitor_region (MetaWorkspace *workspace, + MetaLogicalMonitor *logical_monitor); + +void meta_workspace_focus_default_window (MetaWorkspace *workspace, + MetaWindow *not_this_one, + guint32 timestamp); const char* meta_workspace_get_name (MetaWorkspace *workspace); +void meta_workspace_index_changed (MetaWorkspace *workspace); + #endif diff --git a/src/core/workspace.c b/src/core/workspace.c index b2033e522..c437b1929 100644 --- a/src/core/workspace.c +++ b/src/core/workspace.c @@ -16,15 +16,13 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ /** * SECTION:workspace - * @title: MetaWorkspace - * @short_description: Workspaces + * @title:MetaWorkspace + * @short_description:Workspaces * * A workspace is a set of windows which all live on the same * screen. (You may also see the name "desktop" around the place, @@ -33,38 +31,43 @@ * are unmapped. */ +#include "config.h" -#include <config.h> -#include "screen-private.h" -#include <meta/workspace.h> -#include "workspace-private.h" -#include "boxes-private.h" -#include <meta/errors.h> -#include <meta/prefs.h> - -#include <meta/compositor.h> +#include "meta/workspace.h" #include <X11/Xatom.h> #include <string.h> -#ifdef HAVE_LIBCANBERRA -#include <canberra-gtk.h> -#endif - -enum { - PROP_0, - PROP_N_WINDOWS, -}; +#include "backends/meta-backend-private.h" +#include "backends/meta-logical-monitor.h" +#include "cogl/cogl.h" +#include "core/boxes-private.h" +#include "core/meta-workspace-manager-private.h" +#include "core/workspace-private.h" +#include "meta/compositor.h" +#include "meta/meta-x11-errors.h" +#include "meta/prefs.h" +#include "x11/meta-x11-display-private.h" void meta_workspace_queue_calc_showing (MetaWorkspace *workspace); static void focus_ancestor_or_top_window (MetaWorkspace *workspace, MetaWindow *not_this_one, guint32 timestamp); -static void free_this (gpointer candidate, - gpointer dummy); G_DEFINE_TYPE (MetaWorkspace, meta_workspace, G_TYPE_OBJECT); +enum +{ + PROP_0, + + PROP_N_WINDOWS, + PROP_WORKSPACE_INDEX, + + PROP_LAST, +}; + +static GParamSpec *obj_props[PROP_LAST]; + enum { WINDOW_ADDED, @@ -73,13 +76,72 @@ enum LAST_SIGNAL }; -static guint signals [LAST_SIGNAL] = { 0 }; +static guint signals[LAST_SIGNAL] = { 0 }; + +typedef struct _MetaWorkspaceLogicalMonitorData +{ + GList *logical_monitor_region; + MetaRectangle logical_monitor_work_area; +} MetaWorkspaceLogicalMonitorData; + +typedef struct _MetaWorkspaceFocusableAncestorData +{ + MetaWorkspace *workspace; + MetaWindow *out_window; +} MetaWorkspaceFocusableAncestorData; + +static MetaWorkspaceLogicalMonitorData * +meta_workspace_get_logical_monitor_data (MetaWorkspace *workspace, + MetaLogicalMonitor *logical_monitor) +{ + if (!workspace->logical_monitor_data) + return NULL; + return g_hash_table_lookup (workspace->logical_monitor_data, logical_monitor); +} + +static void +workspace_logical_monitor_data_free (MetaWorkspaceLogicalMonitorData *data) +{ + g_clear_pointer (&data->logical_monitor_region, + meta_rectangle_free_list_and_elements); + g_free (data); +} + +static MetaWorkspaceLogicalMonitorData * +meta_workspace_ensure_logical_monitor_data (MetaWorkspace *workspace, + MetaLogicalMonitor *logical_monitor) +{ + MetaWorkspaceLogicalMonitorData *data; + + data = meta_workspace_get_logical_monitor_data (workspace, logical_monitor); + if (data) + return data; + + if (!workspace->logical_monitor_data) + { + workspace->logical_monitor_data = + g_hash_table_new_full (g_direct_hash, + g_direct_equal, + NULL, + (GDestroyNotify) workspace_logical_monitor_data_free); + } + + data = g_new0 (MetaWorkspaceLogicalMonitorData, 1); + g_hash_table_insert (workspace->logical_monitor_data, logical_monitor, data); + + return data; +} + +static void +meta_workspace_clear_logical_monitor_data (MetaWorkspace *workspace) +{ + g_clear_pointer (&workspace->logical_monitor_data, g_hash_table_destroy); +} static void meta_workspace_finalize (GObject *object) { /* Actual freeing done in meta_workspace_remove() for now */ - G_OBJECT_CLASS (meta_workspace_parent_class)->finalize (object); } @@ -114,6 +176,9 @@ meta_workspace_get_property (GObject *object, */ g_value_set_uint (value, g_list_length (ws->windows)); break; + case PROP_WORKSPACE_INDEX: + g_value_set_uint (value, meta_workspace_index (ws)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -124,8 +189,6 @@ static void meta_workspace_class_init (MetaWorkspaceClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - GParamSpec *pspec; - object_class->finalize = meta_workspace_finalize; object_class->get_property = meta_workspace_get_property; object_class->set_property = meta_workspace_set_property; @@ -145,15 +208,18 @@ meta_workspace_class_init (MetaWorkspaceClass *klass) G_TYPE_NONE, 1, META_TYPE_WINDOW); - pspec = g_param_spec_uint ("n-windows", - "N Windows", - "Number of windows", - 0, G_MAXUINT, 0, - G_PARAM_READABLE); - - g_object_class_install_property (object_class, - PROP_N_WINDOWS, - pspec); + obj_props[PROP_N_WINDOWS] = g_param_spec_uint ("n-windows", + "N Windows", + "Number of windows", + 0, G_MAXUINT, 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_props[PROP_WORKSPACE_INDEX] = g_param_spec_uint ("workspace-index", + "Workspace index", + "The workspace's index", + 0, G_MAXUINT, 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, PROP_LAST, obj_props); } static void @@ -161,61 +227,54 @@ meta_workspace_init (MetaWorkspace *workspace) { } -static void -maybe_add_to_list (MetaScreen *screen, MetaWindow *window, gpointer data) -{ - GList **mru_list = data; - - if (window->on_all_workspaces) - *mru_list = g_list_prepend (*mru_list, window); -} - -LOCAL_SYMBOL MetaWorkspace* -meta_workspace_new (MetaScreen *screen) +MetaWorkspace * +meta_workspace_new (MetaWorkspaceManager *workspace_manager) { + MetaDisplay *display = workspace_manager->display; MetaWorkspace *workspace; + GSList *windows, *l; workspace = g_object_new (META_TYPE_WORKSPACE, NULL); - workspace->screen = screen; - workspace->screen->workspaces = - g_list_append (workspace->screen->workspaces, workspace); + workspace->display = display; + workspace->manager = workspace_manager; + + workspace_manager->workspaces = + g_list_append (workspace_manager->workspaces, workspace); workspace->windows = NULL; workspace->mru_list = NULL; - meta_screen_foreach_window (screen, maybe_add_to_list, &workspace->mru_list); workspace->work_areas_invalid = TRUE; - workspace->work_area_monitor = NULL; workspace->work_area_screen.x = 0; workspace->work_area_screen.y = 0; workspace->work_area_screen.width = 0; workspace->work_area_screen.height = 0; workspace->screen_region = NULL; - workspace->monitor_region = NULL; workspace->screen_edges = NULL; workspace->monitor_edges = NULL; workspace->list_containing_self = g_list_prepend (NULL, workspace); - workspace->snapped_windows = NULL; + workspace->builtin_struts = NULL; workspace->all_struts = NULL; workspace->showing_desktop = FALSE; - return workspace; -} + /* make sure sticky windows are in our mru_list */ + windows = meta_display_list_windows (display, META_LIST_SORTED); + for (l = windows; l; l = l->next) + if (meta_window_located_on_workspace (l->data, workspace)) + meta_workspace_add_window (workspace, l->data); + g_slist_free (windows); -/* Foreach function for workspace_free_struts() */ -static void -free_this (gpointer candidate, gpointer dummy) -{ - free (candidate); + return workspace; } -/* - * Frees the combined struts list of a workspace. +/** + * workspace_free_all_struts: + * @workspace: The workspace. * - * \param workspace The workspace. + * Frees the combined struts list of a workspace. */ static void workspace_free_all_struts (MetaWorkspace *workspace) @@ -223,15 +282,15 @@ workspace_free_all_struts (MetaWorkspace *workspace) if (workspace->all_struts == NULL) return; - g_slist_foreach (workspace->all_struts, free_this, NULL); - g_slist_free (workspace->all_struts); + g_slist_free_full (workspace->all_struts, g_free); workspace->all_struts = NULL; } -/* - * Frees the struts list set with meta_workspace_set_builtin_struts +/** + * workspace_free_builtin_struts: + * @workspace: The workspace. * - * \param workspace The workspace. + * Frees the struts list set with meta_workspace_set_builtin_struts */ static void workspace_free_builtin_struts (MetaWorkspace *workspace) @@ -239,46 +298,36 @@ workspace_free_builtin_struts (MetaWorkspace *workspace) if (workspace->builtin_struts == NULL) return; - g_slist_foreach (workspace->builtin_struts, free_this, NULL); - g_slist_free (workspace->builtin_struts); + g_slist_free_full (workspace->builtin_struts, g_free); workspace->builtin_struts = NULL; } -LOCAL_SYMBOL void -meta_workspace_remove (MetaWorkspace *workspace) +/* Ensure that the workspace is empty by making sure that + * all of our windows are on-all-workspaces. */ +static void +assert_workspace_empty (MetaWorkspace *workspace) { - GList *tmp; - MetaScreen *screen; - int i; - - g_return_if_fail (workspace != workspace->screen->active_workspace); - - /* Here we assume all the windows are already on another workspace - * as well, so they won't be "orphaned" - */ - - tmp = workspace->windows; - while (tmp != NULL) + GList *l; + for (l = workspace->windows; l != NULL; l = l->next) { - GList *next; - MetaWindow *window = tmp->data; - next = tmp->next; - - /* pop front of list we're iterating over */ - meta_workspace_remove_window (workspace, window); - g_assert (window->workspace != NULL); - - tmp = next; + MetaWindow *window = l->data; + g_assert (window->on_all_workspaces); } +} - g_assert (workspace->windows == NULL); +void +meta_workspace_remove (MetaWorkspace *workspace) +{ + MetaWorkspaceManager *manager = workspace->display->workspace_manager; - screen = workspace->screen; + g_return_if_fail (workspace != manager->active_workspace); - workspace->screen->workspaces = - g_list_remove (workspace->screen->workspaces, workspace); + assert_workspace_empty (workspace); - free (workspace->work_area_monitor); + manager->workspaces = + g_list_remove (manager->workspaces, workspace); + + meta_workspace_clear_logical_monitor_data (workspace); g_list_free (workspace->mru_list); g_list_free (workspace->list_containing_self); @@ -295,9 +344,6 @@ meta_workspace_remove (MetaWorkspace *workspace) if (!workspace->work_areas_invalid) { workspace_free_all_struts (workspace); - for (i = 0; i < screen->n_monitor_infos; i++) - meta_rectangle_free_list_and_elements (workspace->monitor_region[i]); - free (workspace->monitor_region); meta_rectangle_free_list_and_elements (workspace->screen_region); meta_rectangle_free_list_and_elements (workspace->screen_edges); meta_rectangle_free_list_and_elements (workspace->monitor_edges); @@ -310,42 +356,18 @@ meta_workspace_remove (MetaWorkspace *workspace) */ } -LOCAL_SYMBOL void +void meta_workspace_add_window (MetaWorkspace *workspace, MetaWindow *window) { - g_return_if_fail (window->workspace == NULL); - - /* If the window is on all workspaces, we want to add it to all mru - * lists, otherwise just add it to this workspaces mru list - */ - if (window->on_all_workspaces) - { - if (window->workspace == NULL) - { - GList* tmp = window->screen->workspaces; - while (tmp) - { - MetaWorkspace* work = (MetaWorkspace*) tmp->data; - if (!g_list_find (work->mru_list, window)) - work->mru_list = g_list_prepend (work->mru_list, window); + COGL_TRACE_BEGIN_SCOPED (MetaWorkspaceAddWindow, + "Workspace (add window)"); - tmp = tmp->next; - } - } - } - else - { - g_assert (g_list_find (workspace->mru_list, window) == NULL); - workspace->mru_list = g_list_prepend (workspace->mru_list, window); - } + g_assert (g_list_find (workspace->mru_list, window) == NULL); + workspace->mru_list = g_list_prepend (workspace->mru_list, window); workspace->windows = g_list_prepend (workspace->windows, window); - window->workspace = workspace; - - meta_window_set_current_workspace_hint (window); - if (window->struts) { meta_topic (META_DEBUG_WORKAREA, @@ -354,46 +376,21 @@ meta_workspace_add_window (MetaWorkspace *workspace, meta_workspace_invalidate_work_area (workspace); } - /* queue a move_resize since changing workspaces may change - * the relevant struts - */ - meta_window_queue (window, META_QUEUE_CALC_SHOWING|META_QUEUE_MOVE_RESIZE); - g_signal_emit (workspace, signals[WINDOW_ADDED], 0, window); - g_object_notify (G_OBJECT (workspace), "n-windows"); + g_object_notify_by_pspec (G_OBJECT (workspace), obj_props[PROP_N_WINDOWS]); } -LOCAL_SYMBOL void +void meta_workspace_remove_window (MetaWorkspace *workspace, MetaWindow *window) { - g_return_if_fail (window->workspace == workspace); + COGL_TRACE_BEGIN_SCOPED (MetaWorkspaceRemoveWindow, + "Workspace (remove window)"); workspace->windows = g_list_remove (workspace->windows, window); - window->workspace = NULL; - - /* If the window is on all workspaces, we don't want to remove it - * from the MRU list unless this causes it to be removed from all - * workspaces - */ - if (window->on_all_workspaces) - { - GList* tmp = window->screen->workspaces; - while (tmp) - { - MetaWorkspace* work = (MetaWorkspace*) tmp->data; - work->mru_list = g_list_remove (work->mru_list, window); - - tmp = tmp->next; - } - } - else - { - workspace->mru_list = g_list_remove (workspace->mru_list, window); - g_assert (g_list_find (workspace->mru_list, window) == NULL); - } - meta_window_set_current_workspace_hint (window); + workspace->mru_list = g_list_remove (workspace->mru_list, window); + g_assert (g_list_find (workspace->mru_list, window) == NULL); if (window->struts) { @@ -403,183 +400,69 @@ meta_workspace_remove_window (MetaWorkspace *workspace, meta_workspace_invalidate_work_area (workspace); } - /* queue a move_resize since changing workspaces may change - * the relevant struts - */ - meta_window_queue (window, META_QUEUE_CALC_SHOWING|META_QUEUE_MOVE_RESIZE); - g_signal_emit (workspace, signals[WINDOW_REMOVED], 0, window); g_object_notify (G_OBJECT (workspace), "n-windows"); } -LOCAL_SYMBOL void +void meta_workspace_relocate_windows (MetaWorkspace *workspace, MetaWorkspace *new_home) { - GList *tmp; - GList *copy; + GList *copy, *l; g_return_if_fail (workspace != new_home); /* can't modify list we're iterating over */ copy = g_list_copy (workspace->windows); - tmp = copy; - while (tmp != NULL) + for (l = copy; l != NULL; l = l->next) { - MetaWindow *window = tmp->data; - - meta_workspace_remove_window (workspace, window); - meta_workspace_add_window (new_home, window); + MetaWindow *window = l->data; - tmp = tmp->next; + if (!window->on_all_workspaces) + meta_window_change_workspace (window, new_home); } g_list_free (copy); - g_assert (workspace->windows == NULL); + assert_workspace_empty (workspace); } -LOCAL_SYMBOL void +void meta_workspace_queue_calc_showing (MetaWorkspace *workspace) { - GList *tmp; + GList *l; - tmp = workspace->windows; - while (tmp != NULL) - { - meta_window_queue (tmp->data, META_QUEUE_CALC_SHOWING); - - tmp = tmp->next; - } + for (l = workspace->windows; l != NULL; l = l->next) + meta_window_queue (l->data, META_QUEUE_CALC_SHOWING); } -static void -workspace_switch_sound(MetaWorkspace *from, - MetaWorkspace *to) -{ -#ifdef HAVE_LIBCANBERRA - MetaWorkspaceLayout layout; - int i, nw, x, y, fi, ti; - const char *e; - - nw = meta_screen_get_n_workspaces(from->screen); - fi = meta_workspace_index(from); - ti = meta_workspace_index(to); - - meta_screen_calc_workspace_layout(from->screen, - nw, - fi, - &layout); - - for (i = 0; i < nw; i++) - if (layout.grid[i] == ti) - break; - - if (i >= nw) - { - meta_bug("Failed to find destination workspace in layout\n"); - goto finish; - } - - y = i / layout.cols; - x = i % layout.cols; - - /* We priorize horizontal over vertical movements here. The - rationale for this is that horizontal movements are probably more - interesting for sound effects because speakers are usually - positioned on a horizontal and not a vertical axis. i.e. your - spatial "Woosh!" effects will easily be able to encode horizontal - movement but not such much vertical movement. */ - - if (x < layout.current_col) - e = "desktop-switch-left"; - else if (x > layout.current_col) - e = "desktop-switch-right"; - else if (y < layout.current_row) - e = "desktop-switch-up"; - else if (y > layout.current_row) - e = "desktop-switch-down"; - else - { - meta_bug("Uh, origin and destination workspace at same logic position!\n"); - goto finish; - } - - ca_context_play(ca_gtk_context_get(), 1, - CA_PROP_EVENT_ID, e, - CA_PROP_EVENT_DESCRIPTION, "Desktop switched", - CA_PROP_CANBERRA_CACHE_CONTROL, "permanent", - NULL); - - finish: - meta_screen_free_workspace_layout (&layout); -#endif /* HAVE_LIBCANBERRA */ -} - -static MetaMotionDirection -get_wrapped_horizontal_direction (gint from, - gint to, - MetaMotionDirection suggested_dir, - gint num_workspaces) -{ - MetaMotionDirection ret = 0; - gboolean wrap = meta_prefs_get_workspace_cycle(); - - if (suggested_dir != 0 && wrap) - { - if (meta_ui_get_direction () == META_UI_DIRECTION_RTL) - { - if (suggested_dir == META_MOTION_LEFT) - suggested_dir = META_MOTION_RIGHT; - else - if (suggested_dir == META_MOTION_RIGHT) - suggested_dir = META_MOTION_LEFT; - } - - return suggested_dir; - } - - if (meta_ui_get_direction() == META_UI_DIRECTION_RTL) - { - if (from < to) - if (wrap) - ret = (to - from) <= ((num_workspaces - to) + from) ? META_MOTION_LEFT : META_MOTION_RIGHT; - else - ret = META_MOTION_LEFT; - else if (from > to) - if (wrap) - ret = (from - to) <= ((num_workspaces - from) + to) ? META_MOTION_RIGHT : META_MOTION_LEFT; - else - ret = META_MOTION_RIGHT; - } - else - { - if (from < to) - if (wrap) - ret = (to - from) <= ((num_workspaces - to) + from) ? META_MOTION_RIGHT : META_MOTION_LEFT; - else - ret = META_MOTION_RIGHT; - else if (from > to) - if (wrap) - ret = (from - to) <= ((num_workspaces - from) + to) ? META_MOTION_LEFT : META_MOTION_RIGHT; - else - ret = META_MOTION_LEFT; - } - - return ret; -} - -static void -meta_workspace_activate_internal (MetaWorkspace *workspace, - MetaWindow *focus_this, - MetaMotionDirection suggested_dir, - guint32 timestamp) +/** + * meta_workspace_activate_with_focus: + * @workspace: a #MetaWorkspace + * @focus_this: the #MetaWindow to be focused, or %NULL + * @timestamp: timestamp for @focus_this + * + * Switches to @workspace and possibly activates the window @focus_this. + * + * The window @focus_this is activated by calling meta_window_activate() + * which will unminimize it and transient parents, raise it and give it + * the focus. + * + * If a window is currently being moved by the user, it will be + * moved to @workspace. + * + * The advantage of calling this function instead of meta_workspace_activate() + * followed by meta_window_activate() is that it happens as a unit, so + * no other window gets focused first before @focus_this. + */ +void +meta_workspace_activate_with_focus (MetaWorkspace *workspace, + MetaWindow *focus_this, + guint32 timestamp) { MetaWorkspace *old; MetaWindow *move_window; - MetaScreen *screen; - MetaDisplay *display; MetaCompositor *comp; MetaWorkspaceLayout layout1, layout2; gint num_workspaces, current_space, new_space; @@ -588,43 +471,40 @@ meta_workspace_activate_internal (MetaWorkspace *workspace, meta_verbose ("Activating workspace %d\n", meta_workspace_index (workspace)); - if (workspace->screen->active_workspace == workspace) - return; + if (workspace->manager->active_workspace == workspace) + { + if (focus_this) + meta_window_activate (focus_this, timestamp); + return; + } /* Free any cached pointers to the workspaces's edges from * a current resize or move operation */ - meta_display_cleanup_edges (workspace->screen->display); - - if (workspace->screen->active_workspace) - workspace_switch_sound (workspace->screen->active_workspace, workspace); + meta_display_cleanup_edges (workspace->display); /* Note that old can be NULL; e.g. when starting up */ - old = workspace->screen->active_workspace; + old = workspace->manager->active_workspace; - workspace->screen->active_workspace = workspace; + workspace->manager->active_workspace = workspace; - meta_screen_set_active_workspace_hint (workspace->screen); + g_signal_emit_by_name (workspace->manager, "active-workspace-changed"); + + if (old == NULL) + return; /* If the "show desktop" mode is active for either the old workspace * or the new one *but not both*, then update the * _net_showing_desktop hint */ - if (old && (old->showing_desktop ^ workspace->showing_desktop)) - meta_screen_update_showing_desktop_hint (workspace->screen); - - if (old == NULL) - return; + if (old->showing_desktop != workspace->showing_desktop) + g_signal_emit_by_name (workspace->manager, "showing-desktop-changed"); move_window = NULL; - if (workspace->screen->display->grab_op == META_GRAB_OP_MOVING || - workspace->screen->display->grab_op == META_GRAB_OP_KEYBOARD_MOVING) - move_window = workspace->screen->display->grab_window; + if (meta_grab_op_is_moving (workspace->display->grab_op)) + move_window = workspace->display->grab_window; if (move_window != NULL) { - if (move_window->on_all_workspaces) - move_window = NULL; /* don't move it after all */ - /* We put the window on the new workspace, flip spaces, * then remove from old workspace, so the window * never gets unmapped and we maintain the button grab @@ -632,39 +512,42 @@ meta_workspace_activate_internal (MetaWorkspace *workspace, * * \bug This comment appears to be the reverse of what happens */ - if (move_window && (move_window->workspace != workspace)) - { - meta_workspace_remove_window (old, move_window); - meta_workspace_add_window (workspace, move_window); - } + if (!meta_window_located_on_workspace (move_window, workspace)) + meta_window_change_workspace (move_window, workspace); } meta_workspace_queue_calc_showing (old); meta_workspace_queue_calc_showing (workspace); - /* FIXME: Why do we need this?!? Isn't it handled in the lines above? */ - if (move_window) - /* Removes window from other spaces */ - meta_window_change_workspace (move_window, workspace); - /* * Notify the compositor that the active workspace is changing. */ - screen = workspace->screen; - display = meta_screen_get_display (screen); - comp = meta_display_get_compositor (display); + comp = meta_display_get_compositor (workspace->display); direction = 0; current_space = meta_workspace_index (old); new_space = meta_workspace_index (workspace); - num_workspaces = meta_screen_get_n_workspaces (workspace->screen); - meta_screen_calc_workspace_layout (workspace->screen, num_workspaces, - current_space, &layout1); + num_workspaces = meta_workspace_manager_get_n_workspaces (workspace->manager); + meta_workspace_manager_calc_workspace_layout (workspace->manager, num_workspaces, + current_space, &layout1); - meta_screen_calc_workspace_layout (workspace->screen, num_workspaces, - new_space, &layout2); + meta_workspace_manager_calc_workspace_layout (workspace->manager, num_workspaces, + new_space, &layout2); - direction = get_wrapped_horizontal_direction (layout1.current_col, layout2.current_col, suggested_dir, num_workspaces); + if (meta_get_locale_direction () == META_LOCALE_DIRECTION_RTL) + { + if (layout1.current_col > layout2.current_col) + direction = META_MOTION_RIGHT; + else if (layout1.current_col < layout2.current_col) + direction = META_MOTION_LEFT; + } + else + { + if (layout1.current_col < layout2.current_col) + direction = META_MOTION_RIGHT; + else if (layout1.current_col > layout2.current_col) + direction = META_MOTION_LEFT; + } if (layout1.current_row < layout2.current_row) { @@ -686,13 +569,10 @@ meta_workspace_activate_internal (MetaWorkspace *workspace, direction = META_MOTION_UP_LEFT; } - meta_screen_free_workspace_layout (&layout1); - meta_screen_free_workspace_layout (&layout2); + meta_workspace_manager_free_workspace_layout (&layout1); + meta_workspace_manager_free_workspace_layout (&layout2); - if (comp != NULL) - { - meta_compositor_switch_workspace (comp, screen, old, workspace, direction); - } + meta_compositor_switch_workspace (comp, old, workspace, direction); /* This needs to be done after telling the compositor we are switching * workspaces since focusing a window will cause it to be immediately @@ -713,91 +593,41 @@ meta_workspace_activate_internal (MetaWorkspace *workspace, meta_workspace_focus_default_window (workspace, NULL, timestamp); } - /* Emit switched signal from screen.c */ - meta_screen_workspace_switched (screen, current_space, new_space, direction); -} - -/** - * meta_workspace_activate_with_focus: - * @workspace: a #MetaWorkspace - * @focus_this: the #MetaWindow to be focused, or %NULL - * @timestamp: timestamp for @focus_this - * - * Switches to @workspace and possibly activates the window @focus_this. - * - * The window @focus_this is activated by calling meta_window_activate() - * which will unminimize it and transient parents, raise it and give it - * the focus. - * - * If a window is currently being moved by the user, it will be - * moved to @workspace. - * - * The advantage of calling this function instead of meta_workspace_activate() - * followed by meta_window_activate() is that it happens as a unit, so - * no other window gets focused first before @focus_this. - */ -void -meta_workspace_activate_with_focus (MetaWorkspace *workspace, - MetaWindow *focus_this, - guint32 timestamp) -{ - g_return_if_fail (META_IS_WORKSPACE (workspace)); - - meta_workspace_activate_internal (workspace, focus_this, 0, timestamp); + meta_workspace_manager_workspace_switched (workspace->manager, current_space, + new_space, direction); } void meta_workspace_activate (MetaWorkspace *workspace, guint32 timestamp) { - g_return_if_fail (META_IS_WORKSPACE (workspace)); - - meta_workspace_activate_internal (workspace, NULL, 0, timestamp); -} - -/** - * meta_workspace_activate_with_direction_hint: - * @workspace: a #MetaWorkspace - * @direction: the suggested #MetaMotionDirection - * @timestamp: timestamp for @focus_this - * - * Switches to @workspace in the specified @direction (if possible) - */ - -void -meta_workspace_activate_with_direction_hint (MetaWorkspace *workspace, - MetaMotionDirection direction, - guint32 timestamp) -{ - g_return_if_fail (META_IS_WORKSPACE (workspace)); - - meta_workspace_activate_internal (workspace, NULL, direction, timestamp); + meta_workspace_activate_with_focus (workspace, NULL, timestamp); } int meta_workspace_index (MetaWorkspace *workspace) { - g_return_val_if_fail (META_IS_WORKSPACE (workspace), 0); + int ret; + + ret = g_list_index (workspace->manager->workspaces, workspace); + + if (ret < 0) + meta_bug ("Workspace does not exist to index!\n"); - int ret = g_list_index (workspace->screen->workspaces, workspace); - /* return value is negative if the workspace is invalid */ return ret; } void -meta_workspace_update_window_hints (MetaWorkspace *workspace) +meta_workspace_index_changed (MetaWorkspace *workspace) { - g_return_if_fail (META_IS_WORKSPACE (workspace)); - - GList *l = workspace->windows; - while (l) + GList *l; + for (l = workspace->windows; l != NULL; l = l->next) { MetaWindow *win = l->data; - - meta_window_set_current_workspace_hint (win); - - l = l->next; + meta_window_current_workspace_changed (win); } + + g_object_notify_by_pspec (G_OBJECT (workspace), obj_props[PROP_WORKSPACE_INDEX]); } /** @@ -812,26 +642,20 @@ meta_workspace_update_window_hints (MetaWorkspace *workspace) GList* meta_workspace_list_windows (MetaWorkspace *workspace) { - g_return_val_if_fail (META_IS_WORKSPACE (workspace), NULL); - - GSList *display_windows; - GSList *tmp; + GSList *display_windows, *l; GList *workspace_windows; - display_windows = meta_display_list_windows (workspace->screen->display, + display_windows = meta_display_list_windows (workspace->display, META_LIST_DEFAULT); workspace_windows = NULL; - tmp = display_windows; - while (tmp != NULL) + for (l = display_windows; l != NULL; l = l->next) { - MetaWindow *window = tmp->data; + MetaWindow *window = l->data; if (meta_window_located_on_workspace (window, workspace)) workspace_windows = g_list_prepend (workspace_windows, window); - - tmp = tmp->next; } g_slist_free (display_windows); @@ -839,12 +663,10 @@ meta_workspace_list_windows (MetaWorkspace *workspace) return workspace_windows; } -LOCAL_SYMBOL void +void meta_workspace_invalidate_work_area (MetaWorkspace *workspace) { - GList *tmp; - GList *windows; - int i; + GList *windows, *l; if (workspace->work_areas_invalid) { @@ -860,21 +682,16 @@ meta_workspace_invalidate_work_area (MetaWorkspace *workspace) /* If we are in the middle of a resize or move operation, we * might have cached pointers to the workspace's edges */ - if (workspace == workspace->screen->active_workspace) - meta_display_cleanup_edges (workspace->screen->display); + if (workspace == workspace->manager->active_workspace) + meta_display_cleanup_edges (workspace->display); - free (workspace->work_area_monitor); - workspace->work_area_monitor = NULL; + meta_workspace_clear_logical_monitor_data (workspace); workspace_free_all_struts (workspace); - for (i = 0; i < workspace->screen->n_monitor_infos; i++) - meta_rectangle_free_list_and_elements (workspace->monitor_region[i]); - free (workspace->monitor_region); meta_rectangle_free_list_and_elements (workspace->screen_region); meta_rectangle_free_list_and_elements (workspace->screen_edges); meta_rectangle_free_list_and_elements (workspace->monitor_edges); - workspace->monitor_region = NULL; workspace->screen_region = NULL; workspace->screen_edges = NULL; workspace->monitor_edges = NULL; @@ -883,19 +700,16 @@ meta_workspace_invalidate_work_area (MetaWorkspace *workspace) /* redo the size/position constraints on all windows */ windows = meta_workspace_list_windows (workspace); - tmp = windows; - while (tmp != NULL) - { - MetaWindow *w = tmp->data; + for (l = windows; l != NULL; l = l->next) + { + MetaWindow *w = l->data; meta_window_queue (w, META_QUEUE_MOVE_RESIZE); - - tmp = tmp->next; } g_list_free (windows); - meta_screen_queue_workarea_recalc (workspace->screen); + meta_display_queue_workarea_recalc (workspace->display); } static MetaStrut * @@ -909,11 +723,8 @@ copy_strut_list(GSList *original) { GSList *result = NULL; - while (original) - { - result = g_slist_prepend (result, copy_strut (original->data)); - original = original->next; - } + for (; original != NULL; original = original->next) + result = g_slist_prepend (result, copy_strut (original->data)); return g_slist_reverse (result); } @@ -921,20 +732,27 @@ copy_strut_list(GSList *original) static void ensure_work_areas_validated (MetaWorkspace *workspace) { - GList *windows; - GList *tmp; - MetaRectangle work_area; - int i; /* C89 absolutely sucks... */ + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + GList *windows; + GList *tmp; + GList *logical_monitors, *l; + MetaRectangle display_rect = { 0 }; + MetaRectangle work_area; if (!workspace->work_areas_invalid) return; g_assert (workspace->all_struts == NULL); - g_assert (workspace->monitor_region == NULL); g_assert (workspace->screen_region == NULL); g_assert (workspace->screen_edges == NULL); g_assert (workspace->monitor_edges == NULL); + meta_display_get_size (workspace->display, + &display_rect.width, + &display_rect.height); + /* STEP 1: Get the list of struts */ workspace->all_struts = copy_strut_list (workspace->builtin_struts); @@ -955,27 +773,35 @@ ensure_work_areas_validated (MetaWorkspace *workspace) /* STEP 2: Get the maximal/spanning rects for the onscreen and * on-single-monitor regions */ - g_assert (workspace->monitor_region == NULL); g_assert (workspace->screen_region == NULL); - workspace->monitor_region = g_new (GList*, - workspace->screen->n_monitor_infos); - for (i = 0; i < workspace->screen->n_monitor_infos; i++) + logical_monitors = + meta_monitor_manager_get_logical_monitors (monitor_manager); + for (l = logical_monitors; l; l = l->next) { - workspace->monitor_region[i] = + MetaLogicalMonitor *logical_monitor = l->data; + MetaWorkspaceLogicalMonitorData *data; + + g_assert (!meta_workspace_get_logical_monitor_data (workspace, + logical_monitor)); + + data = meta_workspace_ensure_logical_monitor_data (workspace, + logical_monitor); + data->logical_monitor_region = meta_rectangle_get_minimal_spanning_set_for_region ( - &workspace->screen->monitor_infos[i].rect, + &logical_monitor->rect, workspace->all_struts); } + workspace->screen_region = meta_rectangle_get_minimal_spanning_set_for_region ( - &workspace->screen->rect, + &display_rect, workspace->all_struts); /* STEP 3: Get the work areas (region-to-maximize-to) for the screen and * monitors. */ - work_area = workspace->screen->rect; /* start with the screen */ + work_area = display_rect; /* start with the screen */ if (workspace->screen_region == NULL) work_area = meta_rect (0, 0, -1, -1); else @@ -992,7 +818,7 @@ ensure_work_areas_validated (MetaWorkspace *workspace) work_area.width, MIN_SANE_AREA); if (work_area.width < 1) { - work_area.x = (workspace->screen->rect.width - MIN_SANE_AREA)/2; + work_area.x = (display_rect.width - MIN_SANE_AREA)/2; work_area.width = MIN_SANE_AREA; } else @@ -1009,7 +835,7 @@ ensure_work_areas_validated (MetaWorkspace *workspace) work_area.height, MIN_SANE_AREA); if (work_area.height < 1) { - work_area.y = (workspace->screen->rect.height - MIN_SANE_AREA)/2; + work_area.y = (display_rect.height - MIN_SANE_AREA)/2; work_area.height = MIN_SANE_AREA; } else @@ -1029,34 +855,36 @@ ensure_work_areas_validated (MetaWorkspace *workspace) workspace->work_area_screen.height); /* Now find the work areas for each monitor */ - free (workspace->work_area_monitor); - workspace->work_area_monitor = g_new (MetaRectangle, - workspace->screen->n_monitor_infos); - - for (i = 0; i < workspace->screen->n_monitor_infos; i++) + for (l = logical_monitors; l; l = l->next) { - work_area = workspace->screen->monitor_infos[i].rect; + MetaLogicalMonitor *logical_monitor = l->data; + MetaWorkspaceLogicalMonitorData *data; - if (workspace->monitor_region[i] == NULL) + data = meta_workspace_get_logical_monitor_data (workspace, + logical_monitor); + work_area = logical_monitor->rect; + + if (!data->logical_monitor_region) /* FIXME: constraints.c untested with this, but it might be nice for * a screen reader or magnifier. */ work_area = meta_rect (work_area.x, work_area.y, -1, -1); else - meta_rectangle_clip_to_region (workspace->monitor_region[i], + meta_rectangle_clip_to_region (data->logical_monitor_region, FIXED_DIRECTION_NONE, &work_area); - workspace->work_area_monitor[i] = work_area; + data->logical_monitor_work_area = work_area; + meta_topic (META_DEBUG_WORKAREA, "Computed work area for workspace %d " "monitor %d: %d,%d %d x %d\n", meta_workspace_index (workspace), - i, - workspace->work_area_monitor[i].x, - workspace->work_area_monitor[i].y, - workspace->work_area_monitor[i].width, - workspace->work_area_monitor[i].height); + logical_monitor->number, + data->logical_monitor_work_area.x, + data->logical_monitor_work_area.y, + data->logical_monitor_work_area.width, + data->logical_monitor_work_area.height); } /* STEP 4: Make sure the screen_region is nonempty (separate from step 2 @@ -1074,11 +902,15 @@ ensure_work_areas_validated (MetaWorkspace *workspace) g_assert (workspace->screen_edges == NULL); g_assert (workspace->monitor_edges == NULL); workspace->screen_edges = - meta_rectangle_find_onscreen_edges (&workspace->screen->rect, + meta_rectangle_find_onscreen_edges (&display_rect, workspace->all_struts); tmp = NULL; - for (i = 0; i < workspace->screen->n_monitor_infos; i++) - tmp = g_list_prepend (tmp, &workspace->screen->monitor_infos[i].rect); + for (l = logical_monitors; l; l = l->next) + { + MetaLogicalMonitor *logical_monitor = l->data; + + tmp = g_list_prepend (tmp, &logical_monitor->rect); + } workspace->monitor_edges = meta_rectangle_find_nonintersected_monitor_edges (tmp, workspace->all_struts); @@ -1118,41 +950,59 @@ void meta_workspace_set_builtin_struts (MetaWorkspace *workspace, GSList *struts) { - MetaScreen *screen = workspace->screen; + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaDisplay *display = workspace->display; + MetaRectangle display_rect = { 0 }; GSList *l; + meta_display_get_size (display, &display_rect.width, &display_rect.height); + for (l = struts; l; l = l->next) { MetaStrut *strut = l->data; - int idx = meta_screen_get_monitor_index_for_rect (screen, &strut->rect); + MetaLogicalMonitor *logical_monitor; + + logical_monitor = + meta_monitor_manager_get_logical_monitor_from_rect (monitor_manager, + &strut->rect); switch (strut->side) { case META_SIDE_TOP: - if (meta_screen_get_monitor_neighbor (screen, idx, META_SCREEN_UP)) + if (meta_monitor_manager_get_logical_monitor_neighbor (monitor_manager, + logical_monitor, + META_DISPLAY_UP)) continue; strut->rect.height += strut->rect.y; strut->rect.y = 0; break; case META_SIDE_BOTTOM: - if (meta_screen_get_monitor_neighbor (screen, idx, META_SCREEN_DOWN)) + if (meta_monitor_manager_get_logical_monitor_neighbor (monitor_manager, + logical_monitor, + META_DISPLAY_DOWN)) continue; - strut->rect.height = screen->rect.height - strut->rect.y; + strut->rect.height = display_rect.height - strut->rect.y; break; case META_SIDE_LEFT: - if (meta_screen_get_monitor_neighbor (screen, idx, META_SCREEN_LEFT)) + if (meta_monitor_manager_get_logical_monitor_neighbor (monitor_manager, + logical_monitor, + META_DISPLAY_LEFT)) continue; strut->rect.width += strut->rect.x; strut->rect.x = 0; break; case META_SIDE_RIGHT: - if (meta_screen_get_monitor_neighbor (screen, idx, META_SCREEN_RIGHT)) + if (meta_monitor_manager_get_logical_monitor_neighbor (monitor_manager, + logical_monitor, + META_DISPLAY_RIGHT)) continue; - strut->rect.width = screen->rect.width - strut->rect.x; + strut->rect.width = display_rect.width - strut->rect.x; break; } } @@ -1170,48 +1020,13 @@ meta_workspace_set_builtin_struts (MetaWorkspace *workspace, } void -meta_workspace_update_snapped_windows (MetaWorkspace *workspace) +meta_workspace_get_work_area_for_logical_monitor (MetaWorkspace *workspace, + MetaLogicalMonitor *logical_monitor, + MetaRectangle *area) { - GList *window_list = meta_workspace_list_windows (workspace); - GList *old = workspace->snapped_windows; - workspace->snapped_windows = NULL; - - GList *iter; - MetaWindow *window; - - for (iter = window_list; iter != NULL; iter = iter->next) - { - window = (MetaWindow *) iter->data; - if (window->tile_type == META_WINDOW_TILE_TYPE_SNAPPED) - workspace->snapped_windows = g_list_prepend (workspace->snapped_windows, window); - } - g_list_free (old); - g_list_free (window_list); - - meta_workspace_recalc_for_snapped_windows (workspace); -} - -gboolean -meta_workspace_has_snapped_windows (MetaWorkspace *workspace) -{ - return g_list_length (workspace->snapped_windows) > 0; -} - -void -meta_workspace_recalc_for_snapped_windows (MetaWorkspace *workspace) -{ - GList *window_list = meta_workspace_list_windows (workspace); - GList *iter; - MetaWindow *win; - for (iter = window_list; iter != NULL; iter = iter->next) - { - win = META_WINDOW (iter->data); - if (meta_window_get_maximized (win)) - { - meta_window_queue(win, META_QUEUE_MOVE_RESIZE); - } - } - g_list_free (window_list); + meta_workspace_get_work_area_for_monitor (workspace, + logical_monitor->number, + area); } /** @@ -1228,14 +1043,32 @@ meta_workspace_get_work_area_for_monitor (MetaWorkspace *workspace, int which_monitor, MetaRectangle *area) { - g_assert (which_monitor >= 0); + MetaBackend *backend = meta_get_backend(); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaLogicalMonitor *logical_monitor; + MetaWorkspaceLogicalMonitorData *data; + + logical_monitor = + meta_monitor_manager_get_logical_monitor_from_number (monitor_manager, + which_monitor); + g_return_if_fail (logical_monitor != NULL); ensure_work_areas_validated (workspace); - g_assert (which_monitor < workspace->screen->n_monitor_infos); + data = meta_workspace_get_logical_monitor_data (workspace, logical_monitor); + + g_return_if_fail (data != NULL); - *area = workspace->work_area_monitor[which_monitor]; + *area = data->logical_monitor_work_area; } +/** + * meta_workspace_get_work_area_all_monitors: + * @workspace: a #MetaWorkspace + * @area: (out): location to store the work area + * + * Stores the work area in @area. + */ void meta_workspace_get_work_area_all_monitors (MetaWorkspace *workspace, MetaRectangle *area) @@ -1245,7 +1078,7 @@ meta_workspace_get_work_area_all_monitors (MetaWorkspace *workspace, *area = workspace->work_area_screen; } -LOCAL_SYMBOL GList* +GList* meta_workspace_get_onscreen_region (MetaWorkspace *workspace) { ensure_work_areas_validated (workspace); @@ -1253,17 +1086,21 @@ meta_workspace_get_onscreen_region (MetaWorkspace *workspace) return workspace->screen_region; } -LOCAL_SYMBOL GList* -meta_workspace_get_onmonitor_region (MetaWorkspace *workspace, - int which_monitor) +GList * +meta_workspace_get_onmonitor_region (MetaWorkspace *workspace, + MetaLogicalMonitor *logical_monitor) { + MetaWorkspaceLogicalMonitorData *data; + ensure_work_areas_validated (workspace); - return workspace->monitor_region[which_monitor]; + data = meta_workspace_get_logical_monitor_data (workspace, logical_monitor); + + return data->logical_monitor_region; } #ifdef WITH_VERBOSE_MODE -static char * +static const char * meta_motion_direction_to_string (MetaMotionDirection direction) { switch (direction) @@ -1284,8 +1121,6 @@ meta_motion_direction_to_string (MetaMotionDirection direction) return "Up-Left"; case META_MOTION_DOWN_LEFT: return "Down-Left"; - case META_MOTION_NOT_EXIST_YET: - return "Nothing"; } return "Unknown"; @@ -1295,11 +1130,14 @@ meta_motion_direction_to_string (MetaMotionDirection direction) /** * meta_workspace_get_neighbor: * @workspace: a #MetaWorkspace - * @direction: a #MetaMotionDirection, direction in which to look for the neighbor + * @direction: a #MetaMotionDirection, relative to @workspace * - * Gets the neighbor of the #MetaWorkspace in the given direction + * Calculate and retrive the workspace that is next to @workspace, + * according to @direction and the current workspace layout, as set + * by meta_screen_override_workspace_layout(). * - * Return value: (transfer none): the neighbor #MetaWorkspace + * Returns: (transfer none): the workspace next to @workspace, or + * @workspace itself if the neighbor would be outside the layout */ MetaWorkspace* meta_workspace_get_neighbor (MetaWorkspace *workspace, @@ -1307,18 +1145,17 @@ meta_workspace_get_neighbor (MetaWorkspace *workspace, { MetaWorkspaceLayout layout; int i, current_space, num_workspaces; - gboolean ltr, cycle; + gboolean ltr; current_space = meta_workspace_index (workspace); - num_workspaces = meta_screen_get_n_workspaces (workspace->screen); - meta_screen_calc_workspace_layout (workspace->screen, num_workspaces, - current_space, &layout); - cycle = meta_prefs_get_workspace_cycle(); + num_workspaces = meta_workspace_manager_get_n_workspaces (workspace->manager); + meta_workspace_manager_calc_workspace_layout (workspace->manager, num_workspaces, + current_space, &layout); meta_verbose ("Getting neighbor of %d in direction %s\n", current_space, meta_motion_direction_to_string (direction)); - ltr = meta_ui_get_direction() == META_UI_DIRECTION_LTR; + ltr = (meta_get_locale_direction () == META_LOCALE_DIRECTION_LTR); switch (direction) { @@ -1338,9 +1175,9 @@ meta_workspace_get_neighbor (MetaWorkspace *workspace, } if (layout.current_col < 0) - layout.current_col = (cycle == 1)? layout.cols - 1 : 0; + layout.current_col = 0; if (layout.current_col >= layout.cols) - layout.current_col = (cycle == 1)? 0 : layout.cols - 1; + layout.current_col = layout.cols - 1; if (layout.current_row < 0) layout.current_row = 0; if (layout.current_row >= layout.rows) @@ -1358,12 +1195,12 @@ meta_workspace_get_neighbor (MetaWorkspace *workspace, meta_verbose ("Neighbor workspace is %d at row %d col %d\n", i, layout.current_row, layout.current_col); - meta_screen_free_workspace_layout (&layout); + meta_workspace_manager_free_workspace_layout (&layout); - return meta_screen_get_workspace_by_index (workspace->screen, i); + return meta_workspace_manager_get_workspace_by_index (workspace->manager, i); } -LOCAL_SYMBOL const char* +const char* meta_workspace_get_name (MetaWorkspace *workspace) { return meta_prefs_get_workspace_name (meta_workspace_index (workspace)); @@ -1374,29 +1211,26 @@ meta_workspace_focus_default_window (MetaWorkspace *workspace, MetaWindow *not_this_one, guint32 timestamp) { - if (timestamp == CurrentTime) - { - meta_warning ("CurrentTime used to choose focus window; " - "focus window may not be correct.\n"); - } - + if (timestamp == META_CURRENT_TIME) + meta_warning ("META_CURRENT_TIME used to choose focus window; " + "focus window may not be correct.\n"); if (meta_prefs_get_focus_mode () == C_DESKTOP_FOCUS_MODE_CLICK || - !workspace->screen->display->mouse_mode) + !workspace->display->mouse_mode) focus_ancestor_or_top_window (workspace, not_this_one, timestamp); else { MetaWindow * window; - window = meta_screen_get_mouse_window (workspace->screen, not_this_one); + window = meta_display_get_pointer_window (workspace->display, not_this_one); if (window && window->type != META_WINDOW_DOCK && window->type != META_WINDOW_DESKTOP) { - if (timestamp == CurrentTime) + if (timestamp == META_CURRENT_TIME) { /* We would like for this to never happen. However, if - * it does happen then we kludge since using CurrentTime + * it does happen then we kludge since using META_CURRENT_TIME * can mean ugly race conditions--and we can avoid these * by allowing EnterNotify events (which come with * timestamps) to handle focus. @@ -1412,11 +1246,10 @@ meta_workspace_focus_default_window (MetaWorkspace *workspace, meta_window_focus (window, timestamp); } - if (workspace->screen->display->autoraise_window != window && + if (workspace->display->autoraise_window != window && meta_prefs_get_auto_raise ()) { - meta_display_queue_autoraise_callback (workspace->screen->display, - window); + meta_display_queue_autoraise_callback (workspace->display, window); } } else if (meta_prefs_get_focus_mode () == C_DESKTOP_FOCUS_MODE_SLOPPY) @@ -1426,21 +1259,61 @@ meta_workspace_focus_default_window (MetaWorkspace *workspace, meta_topic (META_DEBUG_FOCUS, "Setting focus to no_focus_window, since no valid " "window to focus found.\n"); - meta_display_focus_the_no_focus_window (workspace->screen->display, - workspace->screen, - timestamp); + meta_display_unset_input_focus (workspace->display, timestamp); } } } static gboolean -record_ancestor (MetaWindow *window, - void *data) +find_focusable_ancestor (MetaWindow *window, + gpointer user_data) +{ + MetaWorkspaceFocusableAncestorData *data = user_data; + + if (!window->unmanaging && + window->mapped && + !window->hidden && + meta_window_is_focusable (window) && + meta_window_located_on_workspace (window, data->workspace) && + meta_window_showing_on_its_workspace (window)) + { + data->out_window = window; + return FALSE; + } + + return TRUE; +} + +static gboolean +try_to_set_focus_and_check (MetaWindow *window, + MetaWindow *not_this_one, + uint32_t timestamp) { - MetaWindow **result = data; + meta_window_focus (window, timestamp); + + /* meta_focus_window() will not change focus for clients using the + * "globally active input" model of input handling, hence defeating + * the assumption that focus should be changed for such windows. + * See https://tronche.com/gui/x/icccm/sec-4.html#s-4.1.7 + */ + if (meta_window_is_focus_async (window)) + return TRUE; + + /* meta_window_focus() does not guarantee that focus will end up + * where we expect, it can fail for various reasons, better check + * it did not actually changed or even left focus to the window we + * explicitly want to avoid. + */ + if (not_this_one && + meta_display_get_focus_window (window->display) == not_this_one) + { + meta_warning ("Failed to focus window %s while avoiding %s", + window->desc, not_this_one->desc); - *result = window; - return FALSE; /* quit with the first ancestor we find */ + return FALSE; + } + + return TRUE; } /* Focus ancestor of not_this_one if there is one */ @@ -1451,40 +1324,43 @@ focus_ancestor_or_top_window (MetaWorkspace *workspace, { MetaWindow *window = NULL; -#ifdef WITH_VERBOSE_MODE if (not_this_one) meta_topic (META_DEBUG_FOCUS, "Focusing MRU window excluding %s\n", not_this_one->desc); else meta_topic (META_DEBUG_FOCUS, "Focusing MRU window\n"); -#endif + /* First, check to see if we need to focus an ancestor of a window */ if (not_this_one) { MetaWindow *ancestor; - ancestor = NULL; - meta_window_foreach_ancestor (not_this_one, record_ancestor, &ancestor); - if (ancestor != NULL && - (ancestor->on_all_workspaces || - ancestor->workspace == workspace) && - meta_window_showing_on_its_workspace (ancestor)) + MetaWorkspaceFocusableAncestorData data; + + data = (MetaWorkspaceFocusableAncestorData) { + .workspace = workspace, + }; + meta_window_foreach_ancestor (not_this_one, find_focusable_ancestor, &data); + ancestor = data.out_window; + + if (ancestor) { meta_topic (META_DEBUG_FOCUS, "Focusing %s, ancestor of %s\n", ancestor->desc, not_this_one->desc); - meta_window_focus (ancestor, timestamp); - - /* Also raise the window if in click-to-focus */ - if (meta_prefs_get_focus_mode () == C_DESKTOP_FOCUS_MODE_CLICK) - meta_window_raise (ancestor); + if (try_to_set_focus_and_check (ancestor, not_this_one, timestamp)) + { + /* Also raise the window if in click-to-focus */ + if (meta_prefs_get_focus_mode () == C_DESKTOP_FOCUS_MODE_CLICK) + meta_window_raise (ancestor); - return; + return; + } } } - window = meta_stack_get_default_focus_window (workspace->screen->stack, + window = meta_stack_get_default_focus_window (workspace->display->stack, workspace, not_this_one); @@ -1492,18 +1368,31 @@ focus_ancestor_or_top_window (MetaWorkspace *workspace, { meta_topic (META_DEBUG_FOCUS, "Focusing workspace MRU window %s\n", window->desc); + if (try_to_set_focus_and_check (window, not_this_one, timestamp)) + { + /* Also raise the window if in click-to-focus */ + if (meta_prefs_get_focus_mode () == C_DESKTOP_FOCUS_MODE_CLICK) + meta_window_raise (window); - meta_window_focus (window, timestamp); - - /* Also raise the window if in click-to-focus */ - if (meta_prefs_get_focus_mode () == C_DESKTOP_FOCUS_MODE_CLICK) - meta_window_raise (window); - } - else - { - meta_topic (META_DEBUG_FOCUS, "No MRU window to focus found; focusing no_focus_window.\n"); - meta_display_focus_the_no_focus_window (workspace->screen->display, - workspace->screen, - timestamp); + return; + } } + + meta_topic (META_DEBUG_FOCUS, + "No MRU window to focus found; focusing no_focus_window."); + meta_display_unset_input_focus (workspace->display, timestamp); +} + +/** + * meta_workspace_get_display: + * @workspace: a #MetaWorkspace + * + * Gets the #MetaDisplay that the workspace is part of. + * + * Return value: (transfer none): the #MetaDisplay for the workspace + */ +MetaDisplay * +meta_workspace_get_display (MetaWorkspace *workspace) +{ + return workspace->display; } diff --git a/src/core/xprops.h b/src/core/xprops.h deleted file mode 100644 index 06dcf5bec..000000000 --- a/src/core/xprops.h +++ /dev/null @@ -1,233 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Muffin X property convenience routines */ - -/* - * Copyright (C) 2001 Havoc Pennington - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. - */ - -#ifndef META_XPROPS_H -#define META_XPROPS_H - -#include <config.h> - -#include <meta/display.h> -#include <X11/Xutil.h> - -#ifdef HAVE_XSYNC -#include <X11/extensions/sync.h> -#endif - -/* Copied from Lesstif by way of GTK. Rudimentary docs can be - * found in some Motif reference guides online. - */ -typedef struct { - unsigned long flags; - unsigned long functions; - unsigned long decorations; - long input_mode; - unsigned long status; -} MotifWmHints, MwmHints; - -#define MWM_HINTS_FUNCTIONS (1L << 0) -#define MWM_HINTS_DECORATIONS (1L << 1) -#define MWM_HINTS_INPUT_MODE (1L << 2) -#define MWM_HINTS_STATUS (1L << 3) - -#define MWM_FUNC_ALL (1L << 0) -#define MWM_FUNC_RESIZE (1L << 1) -#define MWM_FUNC_MOVE (1L << 2) -#define MWM_FUNC_MINIMIZE (1L << 3) -#define MWM_FUNC_MAXIMIZE (1L << 4) -#define MWM_FUNC_CLOSE (1L << 5) - -#define MWM_DECOR_ALL (1L << 0) -#define MWM_DECOR_BORDER (1L << 1) -#define MWM_DECOR_RESIZEH (1L << 2) -#define MWM_DECOR_TITLE (1L << 3) -#define MWM_DECOR_MENU (1L << 4) -#define MWM_DECOR_MINIMIZE (1L << 5) -#define MWM_DECOR_MAXIMIZE (1L << 6) - -#define MWM_INPUT_MODELESS 0 -#define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1 -#define MWM_INPUT_SYSTEM_MODAL 2 -#define MWM_INPUT_FULL_APPLICATION_MODAL 3 -#define MWM_INPUT_APPLICATION_MODAL MWM_INPUT_PRIMARY_APPLICATION_MODAL - -#define MWM_TEAROFF_WINDOW (1L<<0) - -/* These all return the memory from Xlib, so require an XFree() - * when they return TRUE. They return TRUE on success. - */ -gboolean meta_prop_get_atom_list (MetaDisplay *display, - Window xwindow, - Atom xatom, - Atom **atoms_p, - int *n_atoms_p); -gboolean meta_prop_get_motif_hints (MetaDisplay *display, - Window xwindow, - Atom xatom, - MotifWmHints **hints_p); -gboolean meta_prop_get_cardinal_list (MetaDisplay *display, - Window xwindow, - Atom xatom, - gulong **cardinals_p, - int *n_cardinals_p); -gboolean meta_prop_get_latin1_string (MetaDisplay *display, - Window xwindow, - Atom xatom, - char **str_p); -gboolean meta_prop_get_utf8_string (MetaDisplay *display, - Window xwindow, - Atom xatom, - char **str_p); -gboolean meta_prop_get_utf8_list (MetaDisplay *display, - Window xwindow, - Atom xatom, - char ***str_p, - int *n_str_p); -void meta_prop_set_utf8_string_hint - (MetaDisplay *display, - Window xwindow, - Atom atom, - const char *val); -gboolean meta_prop_get_window (MetaDisplay *display, - Window xwindow, - Atom xatom, - Window *window_p); -gboolean meta_prop_get_cardinal (MetaDisplay *display, - Window xwindow, - Atom xatom, - gulong *cardinal_p); -gboolean meta_prop_get_cardinal_with_atom_type (MetaDisplay *display, - Window xwindow, - Atom xatom, - Atom prop_type, - gulong *cardinal_p); -gboolean meta_prop_get_text_property (MetaDisplay *display, - Window xwindow, - Atom xatom, - char **utf8_str_p); - -gboolean meta_prop_get_wm_hints (MetaDisplay *display, - Window xwindow, - Atom xatom, - XWMHints **hints_p); - -gboolean meta_prop_get_class_hint (MetaDisplay *display, - Window xwindow, - Atom xatom, - XClassHint *class_hint); - -gboolean meta_prop_get_size_hints (MetaDisplay *display, - Window xwindow, - Atom xatom, - XSizeHints **hints_p, - gulong *flags_p); - -typedef enum -{ - META_PROP_VALUE_INVALID, - META_PROP_VALUE_UTF8, - META_PROP_VALUE_STRING, - META_PROP_VALUE_STRING_AS_UTF8, - META_PROP_VALUE_MOTIF_HINTS, - META_PROP_VALUE_CARDINAL, - META_PROP_VALUE_WINDOW, - META_PROP_VALUE_CARDINAL_LIST, - META_PROP_VALUE_UTF8_LIST, - META_PROP_VALUE_ATOM_LIST, - META_PROP_VALUE_TEXT_PROPERTY, /* comes back as UTF-8 string */ - META_PROP_VALUE_WM_HINTS, - META_PROP_VALUE_CLASS_HINT, - META_PROP_VALUE_SIZE_HINTS, - META_PROP_VALUE_SYNC_COUNTER, /* comes back as CARDINAL */ - META_PROP_VALUE_SYNC_COUNTER_LIST /* comes back as CARDINAL */ -} MetaPropValueType; - -/* used to request/return/store property values */ -typedef struct -{ - MetaPropValueType type; - Atom atom; - Atom required_type; /* autofilled if None */ - - union - { - char *str; - MotifWmHints *motif_hints; - Window xwindow; - gulong cardinal; - XWMHints *wm_hints; - XClassHint class_hint; -#ifdef HAVE_XSYNC - XSyncCounter xcounter; - struct - { - gulong *counters; - int n_counters; - } xcounter_list; -#endif - - struct - { - XSizeHints *hints; - unsigned long flags; - } size_hints; - - struct - { - gulong *cardinals; - int n_cardinals; - } cardinal_list; - - struct - { - char **strings; - int n_strings; - } string_list; - - struct - { - Atom *atoms; - int n_atoms; - } atom_list; - - } v; - -} MetaPropValue; - -/* Each value has type and atom initialized. If there's an error, - * or property is unset, type comes back as INVALID; - * else type comes back as it originated, and the data - * is filled in. - */ -void meta_prop_get_values (MetaDisplay *display, - Window xwindow, - MetaPropValue *values, - int n_values); - -void meta_prop_free_values (MetaPropValue *values, - int n_values); - -#endif - - - - diff --git a/src/libmuffin.pc.in b/src/libmuffin.pc.in deleted file mode 100644 index 27bbcab2b..000000000 --- a/src/libmuffin.pc.in +++ /dev/null @@ -1,19 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ -girdir=@libdir@/muffin -typelibdir=@libdir@/muffin -apiversion=@MUFFIN_PLUGIN_API_VERSION@ - -muffin_major_version=@MUFFIN_MAJOR_VERSION@ -muffin_minor_version=@MUFFIN_MINOR_VERSION@ -muffin_micro_version=@MUFFIN_MICRO_VERSION@ -muffin_plugin_api_version=@MUFFIN_PLUGIN_API_VERSION@ - -Name: libmuffin -Description: Muffin window manager library -Requires: cinnamon-desktop gtk+-3.0 muffin-clutter-@MUFFIN_PLUGIN_API_VERSION@ x11 -Version: @VERSION@ -Libs: -L${libdir} -lmuffin -Cflags: -I${includedir}/muffin -DMUFFIN_MAJOR_VERSION=${muffin_major_version} -DMUFFIN_MINOR_VERSION=${muffin_minor_version} -DMUFFIN_MICRO_VERSION=${muffin_micro_version} -DMUFFIN_PLUGIN_API_VERSION=${muffin_plugin_api_version} diff --git a/src/libmutter.pc.in b/src/libmutter.pc.in new file mode 100644 index 000000000..8ad9bdb5c --- /dev/null +++ b/src/libmutter.pc.in @@ -0,0 +1,14 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ +apiversion=@LIBMUTTER_API_VERSION@ +girdir=@libdir@/mutter-${apiversion} +typelibdir=@libdir@/mutter-${apiversion} + +Name: libmutter +Description: Mutter window manager library +Requires: gsettings-desktop-schemas gtk+-3.0 mutter-clutter-${apiversion} x11 +Version: @VERSION@ +Libs: -L${libdir} -lmutter-${apiversion} +Cflags: -I${includedir}/mutter-${apiversion} diff --git a/src/meson.build b/src/meson.build new file mode 100644 index 000000000..6e1a8e759 --- /dev/null +++ b/src/meson.build @@ -0,0 +1,1015 @@ +mutter_includesubdir = join_paths(pkgname, 'meta') +mutter_includedir = join_paths(includedir, mutter_includesubdir) + +mutter_includes = [ + include_directories('.'), + top_includepath, + clutter_includepath, + cogl_includepath, +] + +mutter_lib_deps = [ + m_dep, +] + +mutter_pkg_deps = [ + cairo_dep, + gio_unix_dep, + glib_dep, + cinnamon_desktop_dep, + gtk3_dep, + pango_dep, +] + +mutter_pkg_private_deps = [ + gmodule_no_export_dep, + cinnamon_desktop_dep, + json_glib_dep, + libcanberra_dep, + xkbcommon_dep, +] + +if have_gl + mutter_pkg_deps += [ + gl_dep, + ] +endif + +if have_gles2 + mutter_pkg_private_deps += [ + gles2_dep, + ] +endif + +if have_egl + mutter_pkg_deps += [ + egl_dep, + ] +endif + +if have_libgudev + mutter_pkg_private_deps += [ + gudev_dep, + libudev_dep, + ] +endif + +if have_startup_notification + mutter_pkg_private_deps += [ + libstartup_notification_dep, + ] +endif + +if have_libwacom + mutter_pkg_private_deps += [ + libwacom_dep, + ] +endif + +if have_remote_desktop + mutter_pkg_private_deps += [ + libpipewire_dep, + ] +endif + +if have_introspection + mutter_pkg_private_deps += [ + gobject_introspection_dep, + ] +endif + +if have_x11 + mutter_pkg_deps += [ + xfixes_dep, + xi_dep, + x11_dep, + ] + + mutter_pkg_private_deps += [ + xrandr_dep, + xinerama_dep, + xext_dep, + ice_dep, + xcomposite_dep, + xcursor_dep, + xdamage_dep, + xkbfile_dep, + xkeyboard_config_dep, + xkbcommon_x11_dep, + xrender_dep, + x11_xcb_dep, + xcb_randr_dep, + xcb_res_dep, + xau_dep, + xtst_dep, + ] + + if have_sm + mutter_pkg_private_deps += [ + sm_dep, + ] + endif +endif + +if have_wayland + mutter_pkg_deps += [ + wayland_server_dep, + ] +endif + +if have_native_backend + mutter_pkg_private_deps += [ + libdrm_dep, + libinput_dep, + gudev_dep, + libgbm_dep, + logind_provider_dep, + libudev_dep, + xkbcommon_dep, + ] +endif + +if have_wayland_eglstream + mutter_lib_deps += [ + dl_dep, + ] + mutter_pkg_private_deps += [ + wayland_eglstream_protocols_dep, + ] +endif + +mutter_deps = [ + mutter_pkg_deps, + mutter_pkg_private_deps, + mutter_lib_deps, +] + +mutter_c_args = [ + '-DCLUTTER_ENABLE_COMPOSITOR_API', + '-DCLUTTER_ENABLE_EXPERIMENTAL_API', + '-DCOGL_ENABLE_EXPERIMENTAL_API', + '-DCOGL_ENABLE_EXPERIMENTAL_2_0_API', + '-DCOGL_ENABLE_MUTTER_API', + '-DCLUTTER_DISABLE_DEPRECATION_WARNINGS', + '-DCOGL_DISABLE_DEPRECATION_WARNINGS', + '-DG_LOG_DOMAIN="mutter"', + '-DSN_API_NOT_YET_FROZEN=1', + '-DGETTEXT_PACKAGE="@0@"'.format(meson.project_name()), +] + +if get_option('verbose') + mutter_c_args += [ + '-DWITH_VERBOSE_MODE' + ] +endif + +mutter_sources = [ + 'backends/edid.h', + 'backends/edid-parse.c', + 'backends/gsm-inhibitor-flag.h', + 'backends/meta-backend.c', + 'backends/meta-backend-private.h', + 'backends/meta-barrier.c', + 'backends/meta-barrier-private.h', + 'backends/meta-crtc.c', + 'backends/meta-crtc.h', + 'backends/meta-cursor.c', + 'backends/meta-cursor.h', + 'backends/meta-cursor-renderer.c', + 'backends/meta-cursor-renderer.h', + 'backends/meta-cursor-sprite-xcursor.c', + 'backends/meta-cursor-sprite-xcursor.h', + 'backends/meta-cursor-tracker.c', + 'backends/meta-cursor-tracker-private.h', + 'backends/meta-display-config-shared.h', + 'backends/meta-dnd-private.h', + 'backends/meta-gpu.c', + 'backends/meta-gpu.h', + 'backends/meta-idle-monitor.c', + 'backends/meta-idle-monitor-dbus.c', + 'backends/meta-idle-monitor-dbus.h', + 'backends/meta-idle-monitor-private.h', + 'backends/meta-input-device.c', + 'backends/meta-input-mapper.c', + 'backends/meta-input-mapper-private.h', + 'backends/meta-input-settings.c', + 'backends/meta-input-settings-private.h', + 'backends/meta-logical-monitor.c', + 'backends/meta-logical-monitor.h', + 'backends/meta-monitor.c', + 'backends/meta-monitor-config-manager.c', + 'backends/meta-monitor-config-manager.h', + 'backends/meta-monitor-config-migration.c', + 'backends/meta-monitor-config-migration.h', + 'backends/meta-monitor-config-store.c', + 'backends/meta-monitor-config-store.h', + 'backends/meta-monitor.h', + 'backends/meta-monitor-manager.c', + 'backends/meta-monitor-manager-dummy.c', + 'backends/meta-monitor-manager-dummy.h', + 'backends/meta-monitor-manager-private.h', + 'backends/meta-monitor-transform.c', + 'backends/meta-monitor-transform.h', + 'backends/meta-orientation-manager.c', + 'backends/meta-orientation-manager.h', + 'backends/meta-output.c', + 'backends/meta-output.h', + 'backends/meta-pointer-constraint.c', + 'backends/meta-pointer-constraint.h', + 'backends/meta-remote-access-controller-private.h', + 'backends/meta-remote-access-controller.c', + 'backends/meta-renderer.c', + 'backends/meta-renderer.h', + 'backends/meta-renderer-view.c', + 'backends/meta-renderer-view.h', + 'backends/meta-screen-cast-window.c', + 'backends/meta-screen-cast-window.h', + 'backends/meta-settings.c', + 'backends/meta-settings-private.h', + 'backends/meta-stage.c', + 'backends/meta-stage-private.h', + 'backends/x11/cm/meta-backend-x11-cm.c', + 'backends/x11/cm/meta-backend-x11-cm.h', + 'backends/x11/cm/meta-cursor-sprite-xfixes.c', + 'backends/x11/cm/meta-cursor-sprite-xfixes.h', + 'backends/x11/cm/meta-renderer-x11-cm.c', + 'backends/x11/cm/meta-renderer-x11-cm.h', + 'backends/x11/meta-backend-x11.c', + 'backends/x11/meta-backend-x11.h', + 'backends/x11/meta-barrier-x11.c', + 'backends/x11/meta-barrier-x11.h', + 'backends/x11/meta-clutter-backend-x11.c', + 'backends/x11/meta-clutter-backend-x11.h', + 'backends/x11/meta-crtc-xrandr.c', + 'backends/x11/meta-crtc-xrandr.h', + 'backends/x11/meta-cursor-renderer-x11.c', + 'backends/x11/meta-cursor-renderer-x11.h', + 'backends/x11/meta-event-x11.c', + 'backends/x11/meta-event-x11.h', + 'backends/x11/meta-gpu-xrandr.c', + 'backends/x11/meta-gpu-xrandr.h', + 'backends/x11/meta-input-device-x11.c', + 'backends/x11/meta-input-device-x11.h', + 'backends/x11/meta-input-device-tool-x11.c', + 'backends/x11/meta-input-device-tool-x11.h', + 'backends/x11/meta-input-settings-x11.c', + 'backends/x11/meta-input-settings-x11.h', + 'backends/x11/meta-seat-x11.c', + 'backends/x11/meta-seat-x11.h', + 'backends/x11/meta-keymap-x11.c', + 'backends/x11/meta-keymap-x11.h', + 'backends/x11/meta-monitor-manager-xrandr.c', + 'backends/x11/meta-monitor-manager-xrandr.h', + 'backends/x11/meta-output-xrandr.c', + 'backends/x11/meta-output-xrandr.h', + 'backends/x11/meta-renderer-x11.c', + 'backends/x11/meta-renderer-x11.h', + 'backends/x11/meta-stage-x11.c', + 'backends/x11/meta-stage-x11.h', + 'backends/x11/meta-virtual-input-device-x11.c', + 'backends/x11/meta-virtual-input-device-x11.h', + 'backends/x11/meta-xkb-a11y-x11.c', + 'backends/x11/meta-xkb-a11y-x11.h', + 'backends/x11/nested/meta-backend-x11-nested.c', + 'backends/x11/nested/meta-backend-x11-nested.h', + 'backends/x11/nested/meta-cursor-renderer-x11-nested.c', + 'backends/x11/nested/meta-cursor-renderer-x11-nested.h', + 'backends/x11/nested/meta-stage-x11-nested.c', + 'backends/x11/nested/meta-stage-x11-nested.h', + 'backends/x11/nested/meta-renderer-x11-nested.c', + 'backends/x11/nested/meta-renderer-x11-nested.h', + 'compositor/clutter-utils.c', + 'compositor/clutter-utils.h', + 'compositor/cogl-utils.c', + 'compositor/cogl-utils.h', + 'compositor/compositor.c', + 'compositor/compositor-private.h', + 'compositor/meta-background-actor.c', + 'compositor/meta-background-actor-private.h', + 'compositor/meta-background.c', + 'compositor/meta-background-group.c', + 'compositor/meta-background-image.c', + 'compositor/meta-background-private.h', + 'compositor/meta-compositor-x11.c', + 'compositor/meta-compositor-x11.h', + 'compositor/meta-cullable.c', + 'compositor/meta-cullable.h', + 'compositor/meta-dnd-actor.c', + 'compositor/meta-dnd-actor-private.h', + 'compositor/meta-dnd.c', + 'compositor/meta-feedback-actor.c', + 'compositor/meta-feedback-actor-private.h', + 'compositor/meta-module.c', + 'compositor/meta-module.h', + 'compositor/meta-plugin.c', + 'compositor/meta-plugin-manager.c', + 'compositor/meta-plugin-manager.h', + 'compositor/meta-shadow-factory.c', + 'compositor/meta-shaped-texture.c', + 'compositor/meta-shaped-texture-private.h', + 'compositor/meta-surface-actor.c', + 'compositor/meta-surface-actor.h', + 'compositor/meta-surface-actor-x11.c', + 'compositor/meta-surface-actor-x11.h', + 'compositor/meta-sync-ring.c', + 'compositor/meta-sync-ring.h', + 'compositor/meta-texture-tower.c', + 'compositor/meta-texture-tower.h', + 'compositor/meta-window-actor.c', + 'compositor/meta-window-actor-private.h', + 'compositor/meta-window-actor-x11.c', + 'compositor/meta-window-actor-x11.h', + 'compositor/meta-window-group.c', + 'compositor/meta-window-group-private.h', + 'compositor/meta-window-shape.c', + 'compositor/region-utils.c', + 'compositor/region-utils.h', + 'core/bell.c', + 'core/bell.h', + 'core/boxes.c', + 'core/boxes-private.h', + 'core/constraints.c', + 'core/constraints.h', + 'core/delete.c', + 'core/display.c', + 'core/display-private.h', + 'core/edge-resistance.c', + 'core/edge-resistance.h', + 'core/events.c', + 'core/events.h', + 'core/frame.c', + 'core/frame.h', + 'core/keybindings.c', + 'core/keybindings-private.h', + 'core/main.c', + 'core/main-private.h', + 'core/meta-accel-parse.c', + 'core/meta-accel-parse.h', + 'core/meta-border.c', + 'core/meta-border.h', + 'core/meta-clipboard-manager.c', + 'core/meta-clipboard-manager.h', + 'core/meta-close-dialog.c', + 'core/meta-close-dialog-default.c', + 'core/meta-close-dialog-default-private.h', + 'core/meta-fraction.c', + 'core/meta-fraction.h', + 'core/meta-gesture-tracker.c', + 'core/meta-gesture-tracker-private.h', + 'core/meta-inhibit-shortcuts-dialog.c', + 'core/meta-inhibit-shortcuts-dialog-default.c', + 'core/meta-inhibit-shortcuts-dialog-default-private.h', + 'core/meta-launch-context.c', + 'core/meta-selection.c', + 'core/meta-selection-source.c', + 'core/meta-selection-source-memory.c', + 'core/meta-sound-player.c', + 'core/meta-workspace-manager.c', + 'core/meta-workspace-manager-private.h', + 'core/place.c', + 'core/place.h', + 'core/prefs.c', + 'core/restart.c', + 'core/stack.c', + 'core/stack.h', + 'core/stack-tracker.c', + 'core/stack-tracker.h', + 'core/startup-notification.c', + 'core/startup-notification-private.h', + 'core/util.c', + 'core/util-private.h', + 'core/window.c', + 'core/window-private.h', + 'core/workspace.c', + 'core/workspace-private.h', + 'ui/frames.c', + 'ui/frames.h', + 'ui/theme.c', + 'ui/theme-private.h', + 'ui/ui.c', + 'ui/ui.h', + 'x11/atomnames.h', + 'x11/events.c', + 'x11/events.h', + 'x11/group.c', + 'x11/group-private.h', + 'x11/group-props.c', + 'x11/group-props.h', + 'x11/iconcache.c', + 'x11/iconcache.h', + 'x11/meta-selection-source-x11.c', + 'x11/meta-selection-source-x11-private.h', + 'x11/meta-startup-notification-x11.c', + 'x11/meta-startup-notification-x11.h', + 'x11/meta-x11-display.c', + 'x11/meta-x11-display-private.h', + 'x11/meta-x11-errors.c', + 'x11/meta-x11-selection.c', + 'x11/meta-x11-selection-private.h', + 'x11/meta-x11-selection-input-stream.c', + 'x11/meta-x11-selection-input-stream-private.h', + 'x11/meta-x11-selection-output-stream.c', + 'x11/meta-x11-selection-output-stream-private.h', + 'x11/meta-x11-stack.c', + 'x11/meta-x11-stack-private.h', + 'x11/meta-x11-window-control.c', + 'x11/meta-x11-window-control.h', + 'x11/mutter-Xatomtype.h', + 'x11/session.c', + 'x11/session.h', + 'x11/window-props.c', + 'x11/window-props.h', + 'x11/window-x11.c', + 'x11/window-x11.h', + 'x11/window-x11-private.h', + 'x11/xprops.c', + 'x11/xprops.h', +] + +if have_egl + mutter_sources += [ + 'backends/meta-egl.c', + 'backends/meta-egl-ext.h', + 'backends/meta-egl.h', + ] +endif + +if have_gles2 + mutter_sources += [ + 'backends/meta-gles3.c', + 'backends/meta-gles3.h', + 'backends/meta-gles3-table.h', + ] +endif + +if have_remote_desktop + mutter_sources += [ + 'backends/meta-dbus-session-watcher.c', + 'backends/meta-dbus-session-watcher.h', + 'backends/meta-remote-desktop.c', + 'backends/meta-remote-desktop.h', + 'backends/meta-remote-desktop-session.c', + 'backends/meta-remote-desktop-session.h', + 'backends/meta-screen-cast.c', + 'backends/meta-screen-cast.h', + 'backends/meta-screen-cast-monitor-stream.c', + 'backends/meta-screen-cast-monitor-stream.h', + 'backends/meta-screen-cast-monitor-stream-src.c', + 'backends/meta-screen-cast-monitor-stream-src.h', + 'backends/meta-screen-cast-window-stream-src.c', + 'backends/meta-screen-cast-window-stream-src.h', + 'backends/meta-screen-cast-window-stream.c', + 'backends/meta-screen-cast-window-stream.h', + 'backends/meta-screen-cast-session.c', + 'backends/meta-screen-cast-session.h', + 'backends/meta-screen-cast-stream.c', + 'backends/meta-screen-cast-stream.h', + 'backends/meta-screen-cast-stream-src.c', + 'backends/meta-screen-cast-stream-src.h', + ] +endif + +if have_wayland + mutter_sources += [ + 'compositor/meta-surface-actor-wayland.c', + 'compositor/meta-surface-actor-wayland.h', + 'compositor/meta-window-actor-wayland.c', + 'compositor/meta-window-actor-wayland.h', + 'compositor/meta-compositor-server.c', + 'compositor/meta-compositor-server.h', + 'wayland/meta-cursor-sprite-wayland.c', + 'wayland/meta-cursor-sprite-wayland.h', + 'wayland/meta-pointer-confinement-wayland.c', + 'wayland/meta-pointer-confinement-wayland.h', + 'wayland/meta-pointer-lock-wayland.c', + 'wayland/meta-pointer-lock-wayland.h', + 'wayland/meta-selection-source-wayland.c', + 'wayland/meta-selection-source-wayland-private.h', + 'wayland/meta-wayland-actor-surface.c', + 'wayland/meta-wayland-actor-surface.h', + 'wayland/meta-wayland-buffer.c', + 'wayland/meta-wayland-buffer.h', + 'wayland/meta-wayland.c', + 'wayland/meta-wayland-cursor-surface.c', + 'wayland/meta-wayland-cursor-surface.h', + 'wayland/meta-wayland-data-device.c', + 'wayland/meta-wayland-data-device.h', + 'wayland/meta-wayland-data-device-primary.c', + 'wayland/meta-wayland-data-device-primary.h', + 'wayland/meta-wayland-data-device-primary-legacy.c', + 'wayland/meta-wayland-data-device-primary-legacy.h', + 'wayland/meta-wayland-data-offer.c', + 'wayland/meta-wayland-data-offer.h', + 'wayland/meta-wayland-data-offer-primary.c', + 'wayland/meta-wayland-data-offer-primary.h', + 'wayland/meta-wayland-data-offer-primary-legacy.c', + 'wayland/meta-wayland-data-offer-primary-legacy.h', + 'wayland/meta-wayland-data-source.c', + 'wayland/meta-wayland-data-source.h', + 'wayland/meta-wayland-data-source-primary.c', + 'wayland/meta-wayland-data-source-primary.h', + 'wayland/meta-wayland-data-source-primary-legacy.c', + 'wayland/meta-wayland-data-source-primary-legacy.h', + 'wayland/meta-wayland-dma-buf.c', + 'wayland/meta-wayland-dma-buf.h', + 'wayland/meta-wayland-dnd-surface.c', + 'wayland/meta-wayland-dnd-surface.h', + 'wayland/meta-wayland-gtk-shell.c', + 'wayland/meta-wayland-gtk-shell.h', + 'wayland/meta-wayland.h', + 'wayland/meta-wayland-inhibit-shortcuts.c', + 'wayland/meta-wayland-inhibit-shortcuts-dialog.c', + 'wayland/meta-wayland-inhibit-shortcuts-dialog.h', + 'wayland/meta-wayland-inhibit-shortcuts.h', + 'wayland/meta-wayland-input-device.c', + 'wayland/meta-wayland-input-device.h', + 'wayland/meta-wayland-keyboard.c', + 'wayland/meta-wayland-keyboard.h', + 'wayland/meta-wayland-legacy-xdg-shell.c', + 'wayland/meta-wayland-legacy-xdg-shell.h', + 'wayland/meta-wayland-outputs.c', + 'wayland/meta-wayland-outputs.h', + 'wayland/meta-wayland-pointer.c', + 'wayland/meta-wayland-pointer-constraints.c', + 'wayland/meta-wayland-pointer-constraints.h', + 'wayland/meta-wayland-pointer-gesture-pinch.c', + 'wayland/meta-wayland-pointer-gesture-pinch.h', + 'wayland/meta-wayland-pointer-gestures.c', + 'wayland/meta-wayland-pointer-gestures.h', + 'wayland/meta-wayland-pointer-gesture-swipe.c', + 'wayland/meta-wayland-pointer-gesture-swipe.h', + 'wayland/meta-wayland-pointer.h', + 'wayland/meta-wayland-popup.c', + 'wayland/meta-wayland-popup.h', + 'wayland/meta-wayland-private.h', + 'wayland/meta-wayland-region.c', + 'wayland/meta-wayland-region.h', + 'wayland/meta-wayland-seat.c', + 'wayland/meta-wayland-seat.h', + 'wayland/meta-wayland-shell-surface.c', + 'wayland/meta-wayland-shell-surface.h', + 'wayland/meta-wayland-subsurface.c', + 'wayland/meta-wayland-subsurface.h', + 'wayland/meta-wayland-surface.c', + 'wayland/meta-wayland-surface.h', + 'wayland/meta-wayland-tablet.c', + 'wayland/meta-wayland-tablet-cursor-surface.c', + 'wayland/meta-wayland-tablet-cursor-surface.h', + 'wayland/meta-wayland-tablet.h', + 'wayland/meta-wayland-tablet-manager.c', + 'wayland/meta-wayland-tablet-manager.h', + 'wayland/meta-wayland-tablet-pad.c', + 'wayland/meta-wayland-tablet-pad-group.c', + 'wayland/meta-wayland-tablet-pad-group.h', + 'wayland/meta-wayland-tablet-pad.h', + 'wayland/meta-wayland-tablet-pad-ring.c', + 'wayland/meta-wayland-tablet-pad-ring.h', + 'wayland/meta-wayland-tablet-pad-strip.c', + 'wayland/meta-wayland-tablet-pad-strip.h', + 'wayland/meta-wayland-tablet-seat.c', + 'wayland/meta-wayland-tablet-seat.h', + 'wayland/meta-wayland-tablet-tool.c', + 'wayland/meta-wayland-tablet-tool.h', + 'wayland/meta-wayland-text-input.c', + 'wayland/meta-wayland-text-input.h', + 'wayland/meta-wayland-text-input-legacy.c', + 'wayland/meta-wayland-text-input-legacy.h', + 'wayland/meta-wayland-touch.c', + 'wayland/meta-wayland-touch.h', + 'wayland/meta-wayland-types.h', + 'wayland/meta-wayland-versions.h', + 'wayland/meta-wayland-viewporter.c', + 'wayland/meta-wayland-viewporter.h', + 'wayland/meta-wayland-window-configuration.c', + 'wayland/meta-wayland-window-configuration.h', + 'wayland/meta-wayland-wl-shell.c', + 'wayland/meta-wayland-wl-shell.h', + 'wayland/meta-wayland-xdg-foreign.c', + 'wayland/meta-wayland-xdg-foreign.h', + 'wayland/meta-wayland-xdg-shell.c', + 'wayland/meta-wayland-xdg-shell.h', + 'wayland/meta-window-wayland.c', + 'wayland/meta-window-wayland.h', + 'wayland/meta-window-xwayland.c', + 'wayland/meta-window-xwayland.h', + 'wayland/meta-xwayland.c', + 'wayland/meta-xwayland-grab-keyboard.c', + 'wayland/meta-xwayland-grab-keyboard.h', + 'wayland/meta-xwayland.h', + 'wayland/meta-xwayland-private.h', + 'wayland/meta-xwayland-dnd.c', + 'wayland/meta-xwayland-dnd-private.h', + 'wayland/meta-xwayland-surface.c', + 'wayland/meta-xwayland-surface.h', + ] +endif + +if have_native_backend + mutter_sources += [ + 'backends/native/dbus-utils.c', + 'backends/native/dbus-utils.h', + 'backends/native/meta-backend-native.c', + 'backends/native/meta-backend-native.h', + 'backends/native/meta-backend-native-private.h', + 'backends/native/meta-backend-native-types.h', + 'backends/native/meta-barrier-native.c', + 'backends/native/meta-barrier-native.h', + 'backends/native/meta-clutter-backend-native.c', + 'backends/native/meta-clutter-backend-native.h', + 'backends/native/meta-crtc-kms.c', + 'backends/native/meta-crtc-kms.h', + 'backends/native/meta-cursor-renderer-native.c', + 'backends/native/meta-cursor-renderer-native.h', + 'backends/native/meta-drm-buffer-dumb.c', + 'backends/native/meta-drm-buffer-dumb.h', + 'backends/native/meta-drm-buffer-gbm.c', + 'backends/native/meta-drm-buffer-gbm.h', + 'backends/native/meta-drm-buffer-import.c', + 'backends/native/meta-drm-buffer-import.h', + 'backends/native/meta-drm-buffer.c', + 'backends/native/meta-drm-buffer.h', + 'backends/native/meta-event-native.c', + 'backends/native/meta-event-native.h', + 'backends/native/meta-gpu-kms.c', + 'backends/native/meta-gpu-kms.h', + 'backends/native/meta-input-device-native.c', + 'backends/native/meta-input-device-native.h', + 'backends/native/meta-input-device-tool-native.c', + 'backends/native/meta-input-device-tool-native.h', + 'backends/native/meta-input-settings-native.c', + 'backends/native/meta-input-settings-native.h', + 'backends/native/meta-keymap-native.c', + 'backends/native/meta-keymap-native.h', + 'backends/native/meta-launcher.c', + 'backends/native/meta-launcher.h', + 'backends/native/meta-monitor-manager-kms.c', + 'backends/native/meta-monitor-manager-kms.h', + 'backends/native/meta-output-kms.c', + 'backends/native/meta-output-kms.h', + 'backends/native/meta-renderer-native.c', + 'backends/native/meta-kms-connector-private.h', + 'backends/native/meta-kms-connector.c', + 'backends/native/meta-kms-connector.h', + 'backends/native/meta-kms-crtc-private.h', + 'backends/native/meta-kms-crtc.c', + 'backends/native/meta-kms-crtc.h', + 'backends/native/meta-kms-device-private.h', + 'backends/native/meta-kms-device.c', + 'backends/native/meta-kms-device.h', + 'backends/native/meta-kms-impl-device.c', + 'backends/native/meta-kms-impl-device.h', + 'backends/native/meta-kms-impl-simple.c', + 'backends/native/meta-kms-impl-simple.h', + 'backends/native/meta-kms-impl.c', + 'backends/native/meta-kms-impl.h', + 'backends/native/meta-kms-page-flip.c', + 'backends/native/meta-kms-page-flip-private.h', + 'backends/native/meta-kms-plane.c', + 'backends/native/meta-kms-plane-private.h', + 'backends/native/meta-kms-plane.h', + 'backends/native/meta-kms-private.h', + 'backends/native/meta-kms-types.h', + 'backends/native/meta-kms-update-private.h', + 'backends/native/meta-kms-update.c', + 'backends/native/meta-kms-update.h', + 'backends/native/meta-kms-utils.c', + 'backends/native/meta-kms-utils.h', + 'backends/native/meta-kms.c', + 'backends/native/meta-kms.h', + 'backends/native/meta-renderer-native-gles3.c', + 'backends/native/meta-renderer-native-gles3.h', + 'backends/native/meta-renderer-native.h', + 'backends/native/meta-seat-native.c', + 'backends/native/meta-seat-native.h', + 'backends/native/meta-stage-native.c', + 'backends/native/meta-stage-native.h', + 'backends/native/meta-udev.c', + 'backends/native/meta-udev.h', + 'backends/native/meta-virtual-input-device-native.c', + 'backends/native/meta-virtual-input-device-native.h', + 'backends/native/meta-xkb-utils.c', + 'backends/native/meta-xkb-utils.h', + ] +endif + +if have_wayland_eglstream + mutter_sources += [ + 'wayland/meta-wayland-egl-stream.c', + 'wayland/meta-wayland-egl-stream.h', + ] +endif + +mutter_built_sources = [] + +dbus_display_config_built_sources = gnome.gdbus_codegen('meta-dbus-display-config', + 'org.gnome.Mutter.DisplayConfig.xml', + interface_prefix: 'org.gnome.Mutter.', + namespace: 'MetaDBus', + ) +mutter_built_sources += dbus_display_config_built_sources + +dbus_idle_monitor_built_sources = gnome.gdbus_codegen('meta-dbus-idle-monitor', + 'org.gnome.Mutter.IdleMonitor.xml', + interface_prefix: 'org.gnome.Mutter.', + namespace: 'MetaDBus', + object_manager: true, + ) +mutter_built_sources += dbus_idle_monitor_built_sources + +mutter_marshal = gnome.genmarshal('meta-marshal', + sources: ['meta-marshal.list'], + prefix: 'meta_marshal', + internal: true, + valist_marshallers: true, + ) +mutter_built_sources += mutter_marshal + +if have_profiler + mutter_sources += [ + 'backends/meta-profiler.c', + 'backends/meta-profiler.h', + ] + + sysprof_dbus_interfaces_dir = join_paths(sysprof_dep.get_pkgconfig_variable('datadir'), 'dbus-1', 'interfaces') + sysprof3_dbus_file = join_paths(sysprof_dbus_interfaces_dir, 'org.gnome.Sysprof3.Profiler.xml') + + dbus_sysprof3_profiler_built_sources = gnome.gdbus_codegen('meta-dbus-sysprof3-profiler', + sysprof3_dbus_file, + interface_prefix: 'org.gnome.', + namespace: 'MetaDBus', + ) + mutter_built_sources += dbus_sysprof3_profiler_built_sources +endif + +if have_native_backend + cvt = find_program('cvt') + + gen_default_modes = find_program('backends/native/gen-default-modes.py') + default_modes_h = custom_target('meta-default-modes', + output: 'meta-default-modes.h', + command: [gen_default_modes, '@OUTPUT@'] + ) + mutter_built_sources += default_modes_h + + gdbus_codegen = find_program('gdbus-codegen') + dbus_login1_built_sources = custom_target('meta-dbus-login1', + input: 'org.freedesktop.login1.xml', + output: [ + 'meta-dbus-login1.c', + 'meta-dbus-login1.h', + ], + command: [ + gdbus_codegen, + '--interface-prefix', 'org.freedesktop.login1', + '--c-namespace', 'Login1', + '--generate-c-code', 'meta-dbus-login1', + '--output-directory', meson.current_build_dir(), + '--c-generate-autocleanup', 'all', + '@INPUT@', + ] + ) + mutter_built_sources += dbus_login1_built_sources +endif + +if have_remote_desktop + dbus_remote_desktop_built_sources = gnome.gdbus_codegen('meta-dbus-remote-desktop', + 'org.gnome.Mutter.RemoteDesktop.xml', + interface_prefix: 'org.gnome.Mutter.', + namespace: 'MetaDBus', + ) + mutter_built_sources += dbus_remote_desktop_built_sources + + dbus_screen_cast_built_sources = gnome.gdbus_codegen('meta-dbus-screen-cast', + 'org.gnome.Mutter.ScreenCast.xml', + interface_prefix: 'org.gnome.Mutter.', + namespace: 'MetaDBus', + ) + mutter_built_sources += dbus_screen_cast_built_sources +endif + +wayland_protocol_server_headers = [] +wayland_protocol_client_headers = [] +wayland_protocol_sources = [] + +if have_wayland + # Format: + # - protocol name + # - protocol stability ('private', 'stable' or 'unstable') + # - protocol version (if stability is 'unstable') + wayland_protocols = [ + ['gtk-primary-selection', 'private', ], + ['gtk-shell', 'private', ], + ['gtk-text-input', 'private', ], + ['keyboard-shortcuts-inhibit', 'unstable', 'v1', ], + ['linux-dmabuf', 'unstable', 'v1', ], + ['pointer-constraints', 'unstable', 'v1', ], + ['pointer-gestures', 'unstable', 'v1', ], + ['primary-selection', 'unstable', 'v1', ], + ['relative-pointer', 'unstable', 'v1', ], + ['tablet', 'unstable', 'v2', ], + ['text-input', 'unstable', 'v3', ], + ['viewporter', 'stable', ], + ['xdg-foreign', 'unstable', 'v1', ], + ['xdg-output', 'unstable', 'v1', ], + ['xdg-shell', 'unstable', 'v6', ], + ['xdg-shell', 'stable', ], + ['xwayland-keyboard-grab', 'unstable', 'v1', ], + ] + if have_wayland_eglstream + wayland_eglstream_protocols_dir = wayland_eglstream_protocols_dep.get_pkgconfig_variable('pkgdatadir') + wayland_protocols += [ + ['wayland-eglstream-controller', 'third-party', wayland_eglstream_protocols_dir], + ] + endif + + wayland_scanner = find_program('wayland-scanner') + protocols_dir = wayland_protocols_dep.get_pkgconfig_variable('pkgdatadir') + assert(protocols_dir != '', 'Could not get pkgdatadir from wayland-protocols.pc') + + foreach p: wayland_protocols + protocol_name = p.get(0) + protocol_type = p.get(1) + + if protocol_type == 'stable' + output_base = protocol_name + input = join_paths(protocols_dir, + '@0@/@1@/@2@.xml'.format(protocol_type, + protocol_name, + output_base)) + elif protocol_type == 'private' + output_base = protocol_name + input = 'wayland/protocol/@0@.xml'.format(protocol_name) + elif protocol_type == 'third-party' + output_base = protocol_name + protocol_dir = p.get(2) + input = join_paths(protocol_dir, '@0@.xml'.format(protocol_name)) + else + protocol_version = p.get(2) + output_base = '@0@-@1@-@2@'.format(protocol_name, + protocol_type, + protocol_version) + input = join_paths(protocols_dir, + '@0@/@1@/@2@.xml'.format(protocol_type, + protocol_name, + output_base)) + endif + + wayland_protocol_server_headers += custom_target('@0@ server header'.format(output_base), + input: input, + output: '@0@-server-protocol.h'.format(output_base), + command: [ + wayland_scanner, + 'server-header', + '@INPUT@', '@OUTPUT@', + ] + ) + + # used by tests + wayland_protocol_client_headers += custom_target('@0@ client header'.format(output_base), + input: input, + output: '@0@-client-protocol.h'.format(output_base), + command: [ + wayland_scanner, + 'client-header', + '@INPUT@', '@OUTPUT@', + ] + ) + + wayland_protocol_sources += custom_target('@0@ source'.format(output_base), + input: input, + output: '@0@-protocol.c'.format(output_base), + command: [ + wayland_scanner, + 'private-code', + '@INPUT@', '@OUTPUT@', + ] + ) + endforeach +endif + +mutter_built_sources += wayland_protocol_server_headers +mutter_built_sources += wayland_protocol_sources + +subdir('meta') + +mutter_built_sources += mutter_enum_types +mutter_built_sources += mutter_version + +libmutter = shared_library(libmutter_name, + sources: [ + mutter_sources, + mutter_built_sources, + ], + version: '0.0.0', + soversion: 0, + gnu_symbol_visibility: 'hidden', + include_directories: mutter_includes, + c_args: mutter_c_args, + dependencies: [ + libmutter_cogl_dep, + libmutter_clutter_dep, + mutter_deps, + ], + install_rpath: pkglibdir, + install_dir: libdir, + install: true, +) + +libmutter_dep = declare_dependency( + link_with: libmutter, + include_directories: mutter_includes, + sources: mutter_built_sources, + dependencies: [ + libmutter_cogl_dep, + libmutter_clutter_dep, + mutter_deps, + ], +) + +executable('muffin', + sources: [ + files('core/mutter.c'), + ], + include_directories: mutter_includes, + c_args: mutter_c_args, + dependencies: [libmutter_dep], + install_dir: bindir, + install: true, +) + +executable('muffin-restart-helper', + sources: [ + files('core/restart-helper.c'), + ], + include_directories: [ + top_includepath, + ], + c_args: mutter_c_args, + dependencies: [ + x11_dep, + xcomposite_dep, + ], + install_dir: libexecdir, + install: true, +) + +if have_introspection + mutter_introspected_sources = [] + foreach source : mutter_sources + if source.endswith('.c') + mutter_introspected_sources += source + endif + endforeach + + libmutter_gir = gnome.generate_gir(libmutter, + sources: [ + mutter_version, + mutter_enum_types[1], + mutter_introspected_sources, + mutter_public_header_files + ], + nsversion: libmutter_api_version, + namespace: 'Meta', + symbol_prefix: 'meta', + includes: [ + 'GObject-2.0', + 'CDesktopEnums-3.0', + 'Gdk-3.0', + 'Gtk-3.0', + 'xlib-2.0', + 'xfixes-4.0', + libmutter_cogl_gir[0], + libmutter_cogl_pango_gir[0], + libmutter_clutter_gir[0], + ], + dependencies: [ + mutter_deps, + libmutter_dep, + ], + extra_args: mutter_c_args + introspection_args, + install_dir_gir: pkglibdir, + install_dir_typelib: pkglibdir, + install: true + ) +endif + +pkg.generate(libmutter, + name: 'Meta', + filebase: 'libmuffin-' + libmutter_api_version, + description: 'Muffin compositor and window manager library', + subdirs: pkgname, + requires: [mutter_pkg_deps, libmutter_clutter_name], + version: meson.project_version(), + variables: [ + 'apiversion=' + libmutter_api_version, + 'girdir=${libdir}/muffin', + 'typelibdir=${libdir}/muffin', + ], + install_dir: pcdir, +) + +subdir('compositor/plugins') + +if have_core_tests + subdir('tests') +endif diff --git a/src/meta-marshal.list b/src/meta-marshal.list new file mode 100644 index 000000000..e26b60a8e --- /dev/null +++ b/src/meta-marshal.list @@ -0,0 +1 @@ +VOID:FLOAT,FLOAT diff --git a/src/meta/barrier.h b/src/meta/barrier.h new file mode 100644 index 000000000..72ed33cfc --- /dev/null +++ b/src/meta/barrier.h @@ -0,0 +1,124 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; c-basic-offset: 2; -*- */ + +#ifndef __META_BARRIER_H__ +#define __META_BARRIER_H__ + +#include <glib-object.h> + +#include <meta/display.h> + +G_BEGIN_DECLS + +#define META_TYPE_BARRIER (meta_barrier_get_type ()) +#define META_BARRIER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_BARRIER, MetaBarrier)) +#define META_BARRIER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_BARRIER, MetaBarrierClass)) +#define META_IS_BARRIER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_BARRIER)) +#define META_IS_BARRIER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_BARRIER)) +#define META_BARRIER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_BARRIER, MetaBarrierClass)) + +typedef struct _MetaBarrier MetaBarrier; +typedef struct _MetaBarrierClass MetaBarrierClass; +typedef struct _MetaBarrierPrivate MetaBarrierPrivate; + +typedef struct _MetaBarrierEvent MetaBarrierEvent; + +/** + * MetaBarrier: + * + * The <structname>MetaBarrier</structname> structure contains + * only private data and should be accessed using the provided API + * + **/ +struct _MetaBarrier +{ + GObject parent; + + MetaBarrierPrivate *priv; +}; + +/** + * MetaBarrierClass: + * + * The <structname>MetaBarrierClass</structname> structure contains only + * private data. + */ +struct _MetaBarrierClass +{ + /*< private >*/ + GObjectClass parent_class; +}; + +META_EXPORT +GType meta_barrier_get_type (void) G_GNUC_CONST; + +META_EXPORT +gboolean meta_barrier_is_active (MetaBarrier *barrier); + +META_EXPORT +void meta_barrier_destroy (MetaBarrier *barrier); + +META_EXPORT +void meta_barrier_release (MetaBarrier *barrier, + MetaBarrierEvent *event); + +/** + * MetaBarrierDirection: + * @META_BARRIER_DIRECTION_POSITIVE_X: Positive direction in the X axis + * @META_BARRIER_DIRECTION_POSITIVE_Y: Positive direction in the Y axis + * @META_BARRIER_DIRECTION_NEGATIVE_X: Negative direction in the X axis + * @META_BARRIER_DIRECTION_NEGATIVE_Y: Negative direction in the Y axis + */ + +/* Keep in sync with XFixes */ +typedef enum +{ + META_BARRIER_DIRECTION_POSITIVE_X = 1 << 0, + META_BARRIER_DIRECTION_POSITIVE_Y = 1 << 1, + META_BARRIER_DIRECTION_NEGATIVE_X = 1 << 2, + META_BARRIER_DIRECTION_NEGATIVE_Y = 1 << 3, +} MetaBarrierDirection; + +/** + * MetaBarrierEvent: + * @event_id: A unique integer ID identifying a + * consecutive series of motions at or along the barrier + * @time: Server time, in milliseconds + * @dt: Server time, in milliseconds, since the last event + * sent for this barrier + * @x: The cursor X position in screen coordinates + * @y: The cursor Y position in screen coordinates. + * @dx: If the cursor hadn't been constrained, the delta + * of X movement past the barrier, in screen coordinates + * @dy: If the cursor hadn't been constrained, the delta + * of X movement past the barrier, in screen coordinates + * @released: A boolean flag, %TRUE if this event generated + * by the pointer leaving the barrier as a result of a client + * calling meta_barrier_release() (will be set only for + * MetaBarrier::leave signals) + * @grabbed: A boolean flag, %TRUE if the pointer was grabbed + * at the time this event was sent + */ +struct _MetaBarrierEvent { + /* < private > */ + volatile guint ref_count; + + /* < public > */ + int event_id; + int dt; + guint32 time; + double x; + double y; + double dx; + double dy; + gboolean released; + gboolean grabbed; +}; + +#define META_TYPE_BARRIER_EVENT (meta_barrier_event_get_type ()) + +META_EXPORT +GType meta_barrier_event_get_type (void) G_GNUC_CONST; + +G_END_DECLS + +#endif /* __META_BARRIER_H__ */ diff --git a/src/meta/boxes.h b/src/meta/boxes.h index ddbbe355f..7585e1312 100644 --- a/src/meta/boxes.h +++ b/src/meta/boxes.h @@ -2,9 +2,9 @@ /* Simple box operations */ -/* +/* * Copyright (C) 2005, 2006 Elijah Newren - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the @@ -14,11 +14,9 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_BOXES_H @@ -29,7 +27,21 @@ #define META_TYPE_RECTANGLE (meta_rectangle_get_type ()) -typedef struct _MetaRectangle MetaRectangle; +/** + * MetaRectangle: + * @x: X coordinate of the top-left corner + * @y: Y coordinate of the top-left corner + * @width: Width of the rectangle + * @height: Height of the rectangle + */ +#ifdef __GI_SCANNER__ +/* The introspection scanner is currently unable to lookup how + * cairo_rectangle_int_t is actually defined. This prevents + * introspection data for the GdkRectangle type to include fields + * descriptions. To workaround this issue, we define it with the same + * content as cairo_rectangle_int_t, but only under the introspection + * define. + */ struct _MetaRectangle { int x; @@ -37,7 +49,16 @@ struct _MetaRectangle int width; int height; }; - +typedef struct _MetaRectangle MetaRectangle; +#else +typedef cairo_rectangle_int_t MetaRectangle; +#endif + +/** + * MetaStrut: + * @rect: #MetaRectangle the #MetaStrut is on + * @side: #MetaSide the #MetaStrut is on + */ typedef struct _MetaStrut MetaStrut; struct _MetaStrut { @@ -45,6 +66,12 @@ struct _MetaStrut MetaSide side; }; +/** + * MetaEdgeType: + * @META_EDGE_WINDOW: Whether the edge belongs to a window + * @META_EDGE_MONITOR: Whether the edge belongs to a monitor + * @META_EDGE_SCREEN: Whether the edge belongs to a screen + */ typedef enum { META_EDGE_WINDOW, @@ -52,6 +79,12 @@ typedef enum META_EDGE_SCREEN } MetaEdgeType; +/** + * MetaEdge: + * @rect: #MetaRectangle with the bounds of the edge + * @side_type: Side + * @edge_type: To what belongs the edge + */ typedef struct _MetaEdge MetaEdge; struct _MetaEdge { @@ -60,23 +93,34 @@ struct _MetaEdge MetaEdgeType edge_type; }; +META_EXPORT GType meta_rectangle_get_type (void); +META_EXPORT MetaRectangle *meta_rectangle_copy (const MetaRectangle *rect); + +META_EXPORT void meta_rectangle_free (MetaRectangle *rect); /* Function to make initializing a rect with a single line of code easy */ +META_EXPORT MetaRectangle meta_rect (int x, int y, int width, int height); /* Basic comparison functions */ +META_EXPORT int meta_rectangle_area (const MetaRectangle *rect); + +META_EXPORT gboolean meta_rectangle_intersect (const MetaRectangle *src1, const MetaRectangle *src2, MetaRectangle *dest); + +META_EXPORT gboolean meta_rectangle_equal (const MetaRectangle *src1, const MetaRectangle *src2); /* Find the bounding box of the union of two rectangles */ +META_EXPORT void meta_rectangle_union (const MetaRectangle *rect1, const MetaRectangle *rect2, MetaRectangle *dest); @@ -84,6 +128,7 @@ void meta_rectangle_union (const MetaRectangle *rect1, /* overlap is similar to intersect but doesn't provide location of * intersection information. */ +META_EXPORT gboolean meta_rectangle_overlap (const MetaRectangle *rect1, const MetaRectangle *rect2); @@ -92,16 +137,22 @@ gboolean meta_rectangle_overlap (const MetaRectangle *rect1, * exist a way to shift either rect horizontally so that the two rects * overlap?" horiz_overlap is similar. */ +META_EXPORT gboolean meta_rectangle_vert_overlap (const MetaRectangle *rect1, const MetaRectangle *rect2); + +META_EXPORT gboolean meta_rectangle_horiz_overlap (const MetaRectangle *rect1, const MetaRectangle *rect2); /* could_fit_rect determines whether "outer_rect" is big enough to contain * inner_rect. contains_rect checks whether it actually contains it. */ +META_EXPORT gboolean meta_rectangle_could_fit_rect (const MetaRectangle *outer_rect, const MetaRectangle *inner_rect); + +META_EXPORT gboolean meta_rectangle_contains_rect (const MetaRectangle *outer_rect, const MetaRectangle *inner_rect); diff --git a/src/meta/common.h b/src/meta/common.h index 554265892..908dc9337 100644 --- a/src/meta/common.h +++ b/src/meta/common.h @@ -1,14 +1,13 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* Muffin common types shared by core.h and ui.h - * +/* * PLEASE KEEP IN SYNC WITH GSETTINGS SCHEMAS! */ -/* +/* * Copyright (C) 2001 Havoc Pennington * Copyright (C) 2005 Elijah Newren - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the @@ -18,153 +17,197 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_COMMON_H #define META_COMMON_H -/* Don't include core headers here */ -#include <stdlib.h> #include <X11/Xlib.h> +#include <X11/extensions/XInput.h> +#include <X11/extensions/XInput2.h> #include <glib.h> #include <gtk/gtk.h> +#include "clutter/clutter.h" + /** * SECTION:common - * @title: Common - * @short_description: Muffin common types + * @Title: Common + * @Short_Description: Mutter common types */ -typedef struct _MetaResizePopup MetaResizePopup; +/* This is set in stone and also hard-coded in GDK. */ +#define META_VIRTUAL_CORE_POINTER_ID 2 +#define META_VIRTUAL_CORE_KEYBOARD_ID 3 + +/* Replacement for X11 CurrentTime */ +#define META_CURRENT_TIME 0L +#define META_EXPORT __attribute__((visibility("default"))) extern + +/** + * MetaFrameFlags: + * @META_FRAME_ALLOWS_DELETE: frame allows delete + * @META_FRAME_ALLOWS_MENU: frame allows menu + * @META_FRAME_ALLOWS_MINIMIZE: frame allows minimize + * @META_FRAME_ALLOWS_MAXIMIZE: frame allows maximize + * @META_FRAME_ALLOWS_VERTICAL_RESIZE: frame allows vertical resize + * @META_FRAME_ALLOWS_HORIZONTAL_RESIZE: frame allows horizontal resize + * @META_FRAME_HAS_FOCUS: frame has focus + * @META_FRAME_SHADED: frame is shaded + * @META_FRAME_STUCK: frame is stuck + * @META_FRAME_MAXIMIZED: frame is maximized + * @META_FRAME_ALLOWS_SHADE: frame allows shade + * @META_FRAME_ALLOWS_MOVE: frame allows move + * @META_FRAME_FULLSCREEN: frame allows fullscreen + * @META_FRAME_ABOVE: frame is above + * @META_FRAME_TILED_LEFT: frame is tiled to the left + * @META_FRAME_TILED_RIGHT: frame is tiled to the right + */ typedef enum { META_FRAME_ALLOWS_DELETE = 1 << 0, META_FRAME_ALLOWS_MENU = 1 << 1, META_FRAME_ALLOWS_MINIMIZE = 1 << 2, META_FRAME_ALLOWS_MAXIMIZE = 1 << 3, - META_FRAME_ALLOWS_LEFT_RESIZE = 1 << 4, - META_FRAME_ALLOWS_RIGHT_RESIZE = 1 << 5, - META_FRAME_ALLOWS_TOP_RESIZE = 1 << 6, - META_FRAME_ALLOWS_BOTTOM_RESIZE = 1 << 7, - META_FRAME_HAS_FOCUS = 1 << 8, - META_FRAME_SHADED = 1 << 9, - META_FRAME_STUCK = 1 << 10, - META_FRAME_MAXIMIZED = 1 << 11, - META_FRAME_ALLOWS_SHADE = 1 << 12, - META_FRAME_ALLOWS_MOVE = 1 << 13, - META_FRAME_FULLSCREEN = 1 << 14, - META_FRAME_IS_FLASHING = 1 << 15, - META_FRAME_ABOVE = 1 << 16, - META_FRAME_TILED_LEFT = 1 << 17, - META_FRAME_TILED_RIGHT = 1 << 18, - META_FRAME_ALLOWS_VERTICAL_RESIZE = (META_FRAME_ALLOWS_TOP_RESIZE | META_FRAME_ALLOWS_BOTTOM_RESIZE), - META_FRAME_ALLOWS_HORIZONTAL_RESIZE = (META_FRAME_ALLOWS_LEFT_RESIZE | META_FRAME_ALLOWS_RIGHT_RESIZE) + META_FRAME_ALLOWS_VERTICAL_RESIZE = 1 << 4, + META_FRAME_ALLOWS_HORIZONTAL_RESIZE = 1 << 5, + META_FRAME_HAS_FOCUS = 1 << 6, + META_FRAME_SHADED = 1 << 7, + META_FRAME_STUCK = 1 << 8, + META_FRAME_MAXIMIZED = 1 << 9, + META_FRAME_ALLOWS_SHADE = 1 << 10, + META_FRAME_ALLOWS_MOVE = 1 << 11, + META_FRAME_FULLSCREEN = 1 << 12, + META_FRAME_ABOVE = 1 << 13, + META_FRAME_TILED_LEFT = 1 << 14, + META_FRAME_TILED_RIGHT = 1 << 15 } MetaFrameFlags; -typedef enum -{ - META_MENU_OP_NONE = 0, - META_MENU_OP_DELETE = 1 << 0, - META_MENU_OP_MINIMIZE = 1 << 1, - META_MENU_OP_UNMAXIMIZE = 1 << 2, - META_MENU_OP_MAXIMIZE = 1 << 3, - META_MENU_OP_UNSHADE = 1 << 4, - META_MENU_OP_SHADE = 1 << 5, - META_MENU_OP_UNSTICK = 1 << 6, - META_MENU_OP_STICK = 1 << 7, - META_MENU_OP_WORKSPACES = 1 << 8, - META_MENU_OP_MOVE = 1 << 9, - META_MENU_OP_RESIZE = 1 << 10, - META_MENU_OP_ABOVE = 1 << 11, - META_MENU_OP_UNABOVE = 1 << 12, - META_MENU_OP_MOVE_LEFT = 1 << 13, - META_MENU_OP_MOVE_RIGHT = 1 << 14, - META_MENU_OP_MOVE_UP = 1 << 15, - META_MENU_OP_MOVE_DOWN = 1 << 16, - META_MENU_OP_RECOVER = 1 << 17, - META_MENU_OP_MOVE_NEW = 1 << 18 -} MetaMenuOp; - -typedef struct _MetaWindowMenu MetaWindowMenu; - -typedef void (* MetaWindowMenuFunc) (MetaWindowMenu *menu, - Display *xdisplay, - Window client_xwindow, - guint32 timestamp, - MetaMenuOp op, - int workspace, - gpointer data); - -/* when changing this enum, there are various switch statements - * you have to update +/** + * MetaGrabOp: + * @META_GRAB_OP_NONE: None + * @META_GRAB_OP_MOVING: Moving with pointer + * @META_GRAB_OP_RESIZING_SE: Resizing SE with pointer + * @META_GRAB_OP_RESIZING_S: Resizing S with pointer + * @META_GRAB_OP_RESIZING_SW: Resizing SW with pointer + * @META_GRAB_OP_RESIZING_N: Resizing N with pointer + * @META_GRAB_OP_RESIZING_NE: Resizing NE with pointer + * @META_GRAB_OP_RESIZING_NW: Resizing NW with pointer + * @META_GRAB_OP_RESIZING_W: Resizing W with pointer + * @META_GRAB_OP_RESIZING_E: Resizing E with pointer + * @META_GRAB_OP_KEYBOARD_MOVING: Moving with keyboard + * @META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN: Resizing with keyboard + * @META_GRAB_OP_KEYBOARD_RESIZING_S: Resizing S with keyboard + * @META_GRAB_OP_KEYBOARD_RESIZING_N: Resizing N with keyboard + * @META_GRAB_OP_KEYBOARD_RESIZING_W: Resizing W with keyboard + * @META_GRAB_OP_KEYBOARD_RESIZING_E: Resizing E with keyboard + * @META_GRAB_OP_KEYBOARD_RESIZING_SE: Resizing SE with keyboard + * @META_GRAB_OP_KEYBOARD_RESIZING_NE: Resizing NE with keyboard + * @META_GRAB_OP_KEYBOARD_RESIZING_SW: Resizing SW with keyboard + * @META_GRAB_OP_KEYBOARD_RESIZING_NW: Resizing NS with keyboard + * @META_GRAB_OP_COMPOSITOR: Compositor asked for grab + */ + +/* The lower 16 bits of the grab operation is its type. + * + * Window grab operations have the following layout: + * + * 0000 0000 | 0000 0011 + * NSEW flags | type + * + * Flags contains whether the operation is a keyboard operation, + * and whether the keyboard operation is "unknown". + * + * The rest of the flags tell you which direction the resize is + * going in. + * + * If the directions field is 0000, then the operation is a move, + * not a resize. */ +enum +{ + META_GRAB_OP_WINDOW_FLAG_KEYBOARD = 0x0100, + META_GRAB_OP_WINDOW_FLAG_UNKNOWN = 0x0200, + META_GRAB_OP_WINDOW_DIR_WEST = 0x1000, + META_GRAB_OP_WINDOW_DIR_EAST = 0x2000, + META_GRAB_OP_WINDOW_DIR_SOUTH = 0x4000, + META_GRAB_OP_WINDOW_DIR_NORTH = 0x8000, + META_GRAB_OP_WINDOW_DIR_MASK = 0xF000, + + /* WGO = "window grab op". shorthand for below */ + _WGO_K = META_GRAB_OP_WINDOW_FLAG_KEYBOARD, + _WGO_U = META_GRAB_OP_WINDOW_FLAG_UNKNOWN, + _WGO_W = META_GRAB_OP_WINDOW_DIR_WEST, + _WGO_E = META_GRAB_OP_WINDOW_DIR_EAST, + _WGO_S = META_GRAB_OP_WINDOW_DIR_SOUTH, + _WGO_N = META_GRAB_OP_WINDOW_DIR_NORTH, +}; + typedef enum { META_GRAB_OP_NONE, - /* Mouse ops */ - META_GRAB_OP_MOVING, - META_GRAB_OP_RESIZING_SE, - META_GRAB_OP_RESIZING_S, - META_GRAB_OP_RESIZING_SW, - META_GRAB_OP_RESIZING_N, - META_GRAB_OP_RESIZING_NE, - META_GRAB_OP_RESIZING_NW, - META_GRAB_OP_RESIZING_W, - META_GRAB_OP_RESIZING_E, - - /* Keyboard ops */ - META_GRAB_OP_KEYBOARD_MOVING, - META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN, - META_GRAB_OP_KEYBOARD_RESIZING_S, - META_GRAB_OP_KEYBOARD_RESIZING_N, - META_GRAB_OP_KEYBOARD_RESIZING_W, - META_GRAB_OP_KEYBOARD_RESIZING_E, - META_GRAB_OP_KEYBOARD_RESIZING_SE, - META_GRAB_OP_KEYBOARD_RESIZING_NE, - META_GRAB_OP_KEYBOARD_RESIZING_SW, - META_GRAB_OP_KEYBOARD_RESIZING_NW, - - /* Alt+Tab */ - META_GRAB_OP_KEYBOARD_TABBING_NORMAL, - META_GRAB_OP_KEYBOARD_TABBING_DOCK, - - /* Alt+Esc */ - META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL, - META_GRAB_OP_KEYBOARD_ESCAPING_DOCK, - - META_GRAB_OP_KEYBOARD_ESCAPING_GROUP, - - /* Alt+F6 */ - META_GRAB_OP_KEYBOARD_TABBING_GROUP, - - META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING, - - /* Frame button ops */ - META_GRAB_OP_CLICKING_MINIMIZE, - META_GRAB_OP_CLICKING_MAXIMIZE, - META_GRAB_OP_CLICKING_UNMAXIMIZE, - META_GRAB_OP_CLICKING_DELETE, - META_GRAB_OP_CLICKING_MENU, - META_GRAB_OP_CLICKING_SHADE, - META_GRAB_OP_CLICKING_UNSHADE, - META_GRAB_OP_CLICKING_ABOVE, - META_GRAB_OP_CLICKING_UNABOVE, - META_GRAB_OP_CLICKING_STICK, - META_GRAB_OP_CLICKING_UNSTICK, + /* Window grab ops. */ + META_GRAB_OP_WINDOW_BASE, /* Special grab op when the compositor asked for a grab */ - META_GRAB_OP_COMPOSITOR + META_GRAB_OP_COMPOSITOR, + + /* For when a Wayland client takes a popup grab. */ + META_GRAB_OP_WAYLAND_POPUP, + + /* For when the user clicks on a frame button. */ + META_GRAB_OP_FRAME_BUTTON, + + META_GRAB_OP_MOVING = META_GRAB_OP_WINDOW_BASE, + META_GRAB_OP_RESIZING_NW = META_GRAB_OP_WINDOW_BASE | _WGO_N | _WGO_W, + META_GRAB_OP_RESIZING_N = META_GRAB_OP_WINDOW_BASE | _WGO_N, + META_GRAB_OP_RESIZING_NE = META_GRAB_OP_WINDOW_BASE | _WGO_N | _WGO_E, + META_GRAB_OP_RESIZING_E = META_GRAB_OP_WINDOW_BASE | _WGO_E, + META_GRAB_OP_RESIZING_SW = META_GRAB_OP_WINDOW_BASE | _WGO_S | _WGO_W, + META_GRAB_OP_RESIZING_S = META_GRAB_OP_WINDOW_BASE | _WGO_S, + META_GRAB_OP_RESIZING_SE = META_GRAB_OP_WINDOW_BASE | _WGO_S | _WGO_E, + META_GRAB_OP_RESIZING_W = META_GRAB_OP_WINDOW_BASE | _WGO_W, + META_GRAB_OP_KEYBOARD_MOVING = META_GRAB_OP_WINDOW_BASE | _WGO_K, + META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN = META_GRAB_OP_WINDOW_BASE | _WGO_K | _WGO_U, + META_GRAB_OP_KEYBOARD_RESIZING_NW = META_GRAB_OP_WINDOW_BASE | _WGO_N | _WGO_W | _WGO_K, + META_GRAB_OP_KEYBOARD_RESIZING_N = META_GRAB_OP_WINDOW_BASE | _WGO_N | _WGO_K, + META_GRAB_OP_KEYBOARD_RESIZING_NE = META_GRAB_OP_WINDOW_BASE | _WGO_N | _WGO_E | _WGO_K, + META_GRAB_OP_KEYBOARD_RESIZING_E = META_GRAB_OP_WINDOW_BASE | _WGO_E | _WGO_K, + META_GRAB_OP_KEYBOARD_RESIZING_SW = META_GRAB_OP_WINDOW_BASE | _WGO_S | _WGO_W | _WGO_K, + META_GRAB_OP_KEYBOARD_RESIZING_S = META_GRAB_OP_WINDOW_BASE | _WGO_S | _WGO_K, + META_GRAB_OP_KEYBOARD_RESIZING_SE = META_GRAB_OP_WINDOW_BASE | _WGO_S | _WGO_E | _WGO_K, + META_GRAB_OP_KEYBOARD_RESIZING_W = META_GRAB_OP_WINDOW_BASE | _WGO_W | _WGO_K, } MetaGrabOp; +/** + * MetaCursor: + * @META_CURSOR_DEFAULT: Default cursor + * @META_CURSOR_NORTH_RESIZE: Resize northern edge cursor + * @META_CURSOR_SOUTH_RESIZE: Resize southern edge cursor + * @META_CURSOR_WEST_RESIZE: Resize western edge cursor + * @META_CURSOR_EAST_RESIZE: Resize eastern edge cursor + * @META_CURSOR_SE_RESIZE: Resize south-eastern corner cursor + * @META_CURSOR_SW_RESIZE: Resize south-western corner cursor + * @META_CURSOR_NE_RESIZE: Resize north-eastern corner cursor + * @META_CURSOR_NW_RESIZE: Resize north-western corner cursor + * @META_CURSOR_MOVE_OR_RESIZE_WINDOW: Move or resize cursor + * @META_CURSOR_BUSY: Busy cursor + * @META_CURSOR_DND_IN_DRAG: DND in drag cursor + * @META_CURSOR_DND_MOVE: DND move cursor + * @META_CURSOR_DND_COPY: DND copy cursor + * @META_CURSOR_DND_UNSUPPORTED_TARGET: DND unsupported target + * @META_CURSOR_POINTING_HAND: pointing hand + * @META_CURSOR_CROSSHAIR: crosshair (action forbidden) + * @META_CURSOR_IBEAM: I-beam (text input) + */ typedef enum { + META_CURSOR_NONE = 0, META_CURSOR_DEFAULT, META_CURSOR_NORTH_RESIZE, META_CURSOR_SOUTH_RESIZE, @@ -175,10 +218,28 @@ typedef enum META_CURSOR_NE_RESIZE, META_CURSOR_NW_RESIZE, META_CURSOR_MOVE_OR_RESIZE_WINDOW, - META_CURSOR_BUSY - + META_CURSOR_BUSY, + META_CURSOR_DND_IN_DRAG, + META_CURSOR_DND_MOVE, + META_CURSOR_DND_COPY, + META_CURSOR_DND_UNSUPPORTED_TARGET, + META_CURSOR_POINTING_HAND, + META_CURSOR_CROSSHAIR, + META_CURSOR_IBEAM, + META_CURSOR_LAST } MetaCursor; +/** + * MetaFrameType: + * @META_FRAME_TYPE_NORMAL: Normal frame + * @META_FRAME_TYPE_DIALOG: Dialog frame + * @META_FRAME_TYPE_MODAL_DIALOG: Modal dialog frame + * @META_FRAME_TYPE_UTILITY: Utility frame + * @META_FRAME_TYPE_MENU: Menu frame + * @META_FRAME_TYPE_BORDER: Border frame + * @META_FRAME_TYPE_ATTACHED: Attached frame + * @META_FRAME_TYPE_LAST: Marks the end of the #MetaFrameType enumeration + */ typedef enum { META_FRAME_TYPE_NORMAL, @@ -191,6 +252,19 @@ typedef enum META_FRAME_TYPE_LAST } MetaFrameType; +/** + * MetaVirtualModifier: + * @META_VIRTUAL_SHIFT_MASK: Shift mask + * @META_VIRTUAL_CONTROL_MASK: Control mask + * @META_VIRTUAL_ALT_MASK: Alt mask + * @META_VIRTUAL_META_MASK: Meta mask + * @META_VIRTUAL_SUPER_MASK: Super mask + * @META_VIRTUAL_HYPER_MASK: Hyper mask + * @META_VIRTUAL_MOD2_MASK: Mod2 mask + * @META_VIRTUAL_MOD3_MASK: Mod3 mask + * @META_VIRTUAL_MOD4_MASK: Mod4 mask + * @META_VIRTUAL_MOD5_MASK: Mod5 mask + */ typedef enum { /* Create gratuitous divergence from regular @@ -198,7 +272,7 @@ typedef enum */ META_VIRTUAL_SHIFT_MASK = 1 << 5, META_VIRTUAL_CONTROL_MASK = 1 << 6, - META_VIRTUAL_ALT_MASK = 1 << 7, + META_VIRTUAL_ALT_MASK = 1 << 7, META_VIRTUAL_META_MASK = 1 << 8, META_VIRTUAL_SUPER_MASK = 1 << 9, META_VIRTUAL_HYPER_MASK = 1 << 10, @@ -208,9 +282,21 @@ typedef enum META_VIRTUAL_MOD5_MASK = 1 << 14 } MetaVirtualModifier; +/** + * MetaDirection: + * @META_DIRECTION_LEFT: Left + * @META_DIRECTION_RIGHT: Right + * @META_DIRECTION_TOP: Top + * @META_DIRECTION_BOTTOM: Bottom + * @META_DIRECTION_UP: Up + * @META_DIRECTION_DOWN: Down + * @META_DIRECTION_HORIZONTAL: Horizontal + * @META_DIRECTION_VERTICAL: Vertical + */ + /* Relative directions or sides seem to come up all over the place... */ /* FIXME: Replace - * screen.[ch]:MetaScreenDirection, + * display.[ch]:MetaDisplayDirection, * workspace.[ch]:MetaMotionDirection, * with the use of MetaDirection. */ @@ -230,6 +316,18 @@ typedef enum META_DIRECTION_VERTICAL = META_DIRECTION_UP | META_DIRECTION_DOWN, } MetaDirection; +/** + * MetaMotionDirection: + * @META_MOTION_UP: Upwards motion + * @META_MOTION_DOWN: Downwards motion + * @META_MOTION_LEFT: Motion to the left + * @META_MOTION_RIGHT: Motion to the right + * @META_MOTION_UP_LEFT: Motion up and to the left + * @META_MOTION_UP_RIGHT: Motion up and to the right + * @META_MOTION_DOWN_LEFT: Motion down and to the left + * @META_MOTION_DOWN_RIGHT: Motion down and to the right + */ + /* Negative to avoid conflicting with real workspace * numbers */ @@ -243,10 +341,17 @@ typedef enum META_MOTION_UP_LEFT = -5, META_MOTION_UP_RIGHT = -6, META_MOTION_DOWN_LEFT = -7, - META_MOTION_DOWN_RIGHT = -8, - META_MOTION_NOT_EXIST_YET = -30 + META_MOTION_DOWN_RIGHT = -8 } MetaMotionDirection; +/** + * MetaSide: + * @META_SIDE_LEFT: Left side + * @META_SIDE_RIGHT: Right side + * @META_SIDE_TOP: Top side + * @META_SIDE_BOTTOM: Bottom side + */ + /* Sometimes we want to talk about sides instead of directions; note * that the values must be as follows or meta_window_update_struts() * won't work. Using these values also is a safety blanket since @@ -260,7 +365,15 @@ typedef enum META_SIDE_BOTTOM = META_DIRECTION_BOTTOM } MetaSide; -/* Function a window button can have. Note, you can't add stuff here +/** + * MetaButtonFunction: + * @META_BUTTON_FUNCTION_MENU: Menu + * @META_BUTTON_FUNCTION_MINIMIZE: Minimize + * @META_BUTTON_FUNCTION_MAXIMIZE: Maximize + * @META_BUTTON_FUNCTION_CLOSE: Close + * @META_BUTTON_FUNCTION_LAST: Marks the end of the #MetaButtonFunction enumeration + * + * Function a window button can have. Note, you can't add stuff here * without extending the theme format to draw a new function and * breaking all existing themes. */ @@ -270,50 +383,18 @@ typedef enum META_BUTTON_FUNCTION_MINIMIZE, META_BUTTON_FUNCTION_MAXIMIZE, META_BUTTON_FUNCTION_CLOSE, - META_BUTTON_FUNCTION_SHADE, - META_BUTTON_FUNCTION_ABOVE, - META_BUTTON_FUNCTION_STICK, - META_BUTTON_FUNCTION_UNSHADE, - META_BUTTON_FUNCTION_UNABOVE, - META_BUTTON_FUNCTION_UNSTICK, META_BUTTON_FUNCTION_LAST } MetaButtonFunction; -typedef enum { - META_TILE_NONE, - META_TILE_LEFT, - META_TILE_RIGHT, - META_TILE_ULC, - META_TILE_LLC, - META_TILE_URC, - META_TILE_LRC, - META_TILE_TOP, - META_TILE_BOTTOM, - META_TILE_MAXIMIZE -} MetaTileMode; - -typedef enum { - META_WINDOW_TILE_TYPE_NONE, - META_WINDOW_TILE_TYPE_TILED, - META_WINDOW_TILE_TYPE_SNAPPED -} MetaWindowTileType; - -typedef enum { - META_BELL_TYPE_NONE, - META_BELL_TYPE_STICKY_KEYS, - META_BELL_TYPE_SLOW_KEYS, - META_BELL_TYPE_BOUNCE_KEYS -} MetaBellType; - #define MAX_BUTTONS_PER_CORNER META_BUTTON_FUNCTION_LAST /* Keep array size in sync with MAX_BUTTONS_PER_CORNER */ /** * MetaButtonLayout: - * @left_buttons: (array fixed-size=10): - * @right_buttons: (array fixed-size=10): - * @left_buttons_has_spacer: (array fixed-size=10): - * @right_buttons_has_spacer: (array fixed-size=10): + * @left_buttons: (array fixed-size=4): + * @right_buttons: (array fixed-size=4): + * @left_buttons_has_spacer: (array fixed-size=4): + * @right_buttons_has_spacer: (array fixed-size=4): */ typedef struct _MetaButtonLayout MetaButtonLayout; struct _MetaButtonLayout @@ -327,6 +408,25 @@ struct _MetaButtonLayout gboolean right_buttons_has_spacer[MAX_BUTTONS_PER_CORNER]; }; +/** + * MetaWindowMenuType: + * @META_WINDOW_MENU_WM: the window manager menu + * @META_WINDOW_MENU_APP: the (fallback) app menu + * + * Menu the compositor should display for a given window + */ +typedef enum +{ + META_WINDOW_MENU_WM, + META_WINDOW_MENU_APP +} MetaWindowMenuType; + +/** + * MetaFrameBorders: + * @visible: inner visible portion of frame border + * @invisible: outer invisible portion of frame border + * @total: sum of the two borders above + */ typedef struct _MetaFrameBorders MetaFrameBorders; struct _MetaFrameBorders { @@ -342,8 +442,15 @@ struct _MetaFrameBorders }; /* sets all dimensions to zero */ +META_EXPORT void meta_frame_borders_clear (MetaFrameBorders *self); +/* should investigate changing these to whatever most apps use */ +#define META_ICON_WIDTH 96 +#define META_ICON_HEIGHT 96 +#define META_MINI_ICON_WIDTH 16 +#define META_MINI_ICON_HEIGHT 16 + #define META_DEFAULT_ICON_NAME "window" /* Main loop priorities determine when activity in the GLib @@ -391,20 +498,23 @@ void meta_frame_borders_clear (MetaFrameBorders *self); /* ==== Anything below here can be starved arbitrarily ==== */ /* G_PRIORITY_DEFAULT_IDLE: - * Muffin plugin unloading + * Mutter plugin unloading */ #define META_PRIORITY_PREFS_NOTIFY (G_PRIORITY_DEFAULT_IDLE + 10) /************************************************************/ -#define META_POINT_IN_RECT(xcoord, ycoord, rect) \ - ((xcoord) >= (rect).x && \ - (xcoord) < ((rect).x + (rect).width) && \ - (ycoord) >= (rect).y && \ - (ycoord) < ((rect).y + (rect).height)) - -/* +/** + * MetaStackLayer: + * @META_LAYER_DESKTOP: Desktop layer + * @META_LAYER_BOTTOM: Bottom layer + * @META_LAYER_NORMAL: Normal layer + * @META_LAYER_TOP: Top layer + * @META_LAYER_DOCK: Dock layer + * @META_LAYER_OVERRIDE_REDIRECT: Override-redirect layer + * @META_LAYER_LAST: Marks the end of the #MetaStackLayer enumeration + * * Layers a window can be in. * These MUST be in the order of stacking. */ @@ -415,40 +525,27 @@ typedef enum META_LAYER_NORMAL = 2, META_LAYER_TOP = 4, /* Same as DOCK; see EWMH and bug 330717 */ META_LAYER_DOCK = 4, - META_LAYER_FULLSCREEN = 5, - META_LAYER_FOCUSED_WINDOW = 6, META_LAYER_OVERRIDE_REDIRECT = 7, META_LAYER_LAST = 8 } MetaStackLayer; - -/* - * Placement mode - */ -typedef enum -{ - META_PLACEMENT_MODE_AUTOMATIC, - META_PLACEMENT_MODE_POINTER, - META_PLACEMENT_MODE_MANUAL, - META_PLACEMENT_MODE_CENTER -} MetaPlacementMode; - -/* - * Background transition +/* MetaGravity: (skip) + * + * Identical to the corresponding gravity value macros from libX11. */ -typedef enum -{ - META_BACKGROUND_TRANSITION_NONE, - META_BACKGROUND_TRANSITION_FADEIN, - META_BACKGROUND_TRANSITION_BLEND -} MetaBackgroundTransition; - -typedef enum +typedef enum _MetaGravity { - META_SYNC_NONE = 0, - META_SYNC_FALLBACK, - META_SYNC_SWAP_THROTTLING, - META_SYNC_PRESENTATION_TIME -} MetaSyncMethod; + META_GRAVITY_NONE = 0, + META_GRAVITY_NORTH_WEST = 1, + META_GRAVITY_NORTH = 2, + META_GRAVITY_NORTH_EAST = 3, + META_GRAVITY_WEST = 4, + META_GRAVITY_CENTER = 5, + META_GRAVITY_EAST = 6, + META_GRAVITY_SOUTH_WEST = 7, + META_GRAVITY_SOUTH = 8, + META_GRAVITY_SOUTH_EAST = 9, + META_GRAVITY_STATIC = 10, +} MetaGravity; #endif diff --git a/src/meta/compositor-muffin.h b/src/meta/compositor-muffin.h deleted file mode 100644 index 245014793..000000000 --- a/src/meta/compositor-muffin.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* - * Copyright (C) 2008 Matthew Allum - * Copyright (C) 2007 Iain Holmes - * Based on xcompmgr - (c) 2003 Keith Packard - * xfwm4 - (c) 2005-2007 Olivier Fourdan - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. - */ - -#ifndef MUFFIN_H_ -#define MUFFIN_H_ - -#include <clutter/clutter.h> -#include <X11/Xlib.h> -#include <X11/extensions/Xfixes.h> - -#include <meta/types.h> -#include <meta/compositor.h> -#include <meta/meta-window-actor.h> - -/* Public compositor API */ -ClutterActor *meta_get_stage_for_screen (MetaScreen *screen); -ClutterActor *meta_get_overlay_group_for_screen (MetaScreen *screen); -Window meta_get_overlay_window (MetaScreen *screen); -GList *meta_get_window_actors (MetaScreen *screen); -ClutterActor *meta_get_window_group_for_screen (MetaScreen *screen); -ClutterActor *meta_get_bottom_window_group_for_screen (MetaScreen *screen); -ClutterActor *meta_get_top_window_group_for_screen (MetaScreen *screen); - -void meta_disable_unredirect_for_screen (MetaScreen *screen); -void meta_enable_unredirect_for_screen (MetaScreen *screen); - -ClutterActor *meta_get_background_actor_for_screen (MetaScreen *screen); -void meta_set_stage_input_region (MetaScreen *screen, - XserverRegion region); -void meta_empty_stage_input_region (MetaScreen *screen); - -#endif diff --git a/src/meta/compositor-mutter.h b/src/meta/compositor-mutter.h new file mode 100644 index 000000000..0c420882f --- /dev/null +++ b/src/meta/compositor-mutter.h @@ -0,0 +1,60 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2008 Matthew Allum + * Copyright (C) 2007 Iain Holmes + * Based on xcompmgr - (c) 2003 Keith Packard + * xfwm4 - (c) 2005-2007 Olivier Fourdan + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef MUTTER_H_ +#define MUTTER_H_ + +#include "clutter/clutter.h" +#include "meta/compositor.h" +#include "meta/meta-window-actor.h" +#include "meta/types.h" + +/* Public compositor API */ +META_EXPORT +ClutterActor *meta_get_stage_for_display (MetaDisplay *display); + +META_EXPORT +GList *meta_get_window_actors (MetaDisplay *display); + +META_EXPORT +ClutterActor *meta_get_window_group_for_display (MetaDisplay *display); + +META_EXPORT +ClutterActor *meta_get_top_window_group_for_display (MetaDisplay *display); + +META_EXPORT +ClutterActor *meta_get_feedback_group_for_display (MetaDisplay *display); + +META_EXPORT +void meta_disable_unredirect_for_display (MetaDisplay *display); + +META_EXPORT +void meta_enable_unredirect_for_display (MetaDisplay *display); + +META_EXPORT +void meta_focus_stage_window (MetaDisplay *display, + guint32 timestamp); + +META_EXPORT +gboolean meta_stage_is_focused (MetaDisplay *display); + +#endif diff --git a/src/meta/compositor.h b/src/meta/compositor.h index 9f5e56c54..1ccae70d7 100644 --- a/src/meta/compositor.h +++ b/src/meta/compositor.h @@ -14,22 +14,24 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_COMPOSITOR_H #define META_COMPOSITOR_H #include <glib.h> -#include <X11/Xlib.h> #include <meta/types.h> #include <meta/boxes.h> #include <meta/window.h> #include <meta/workspace.h> +#define META_TYPE_COMPOSITOR (meta_compositor_get_type ()) +META_EXPORT +G_DECLARE_DERIVABLE_TYPE (MetaCompositor, meta_compositor, + META, COMPOSITOR, GObject) + /** * MetaCompEffect: * @META_COMP_EFFECT_CREATE: The window is newly created @@ -56,129 +58,108 @@ typedef enum META_COMP_EFFECT_NONE } MetaCompEffect; -MetaCompositor *meta_compositor_new (MetaDisplay *display); +typedef enum +{ + META_SIZE_CHANGE_MAXIMIZE, + META_SIZE_CHANGE_UNMAXIMIZE, + META_SIZE_CHANGE_FULLSCREEN, + META_SIZE_CHANGE_UNFULLSCREEN, +} MetaSizeChange; + +META_EXPORT void meta_compositor_destroy (MetaCompositor *compositor); -void meta_compositor_manage_screen (MetaCompositor *compositor, - MetaScreen *screen); -void meta_compositor_unmanage_screen (MetaCompositor *compositor, - MetaScreen *screen); +META_EXPORT +void meta_compositor_manage (MetaCompositor *compositor); +META_EXPORT +void meta_compositor_unmanage (MetaCompositor *compositor); + +META_EXPORT void meta_compositor_window_shape_changed (MetaCompositor *compositor, MetaWindow *window); -gboolean meta_compositor_process_event (MetaCompositor *compositor, - XEvent *event, - MetaWindow *window); +META_EXPORT +void meta_compositor_window_opacity_changed (MetaCompositor *compositor, + MetaWindow *window); -/* At a high-level, a window is not-visible or visible. When a - * window is added (with add_window()) it is not visible. - * show_window() indicates a transition from not-visible to - * visible. Some of the reasons for this: - * - * - Window newly created - * - Window is unminimized - * - Window is moved to the current desktop - * - Window was made sticky - * - * hide_window() indicates that the window has transitioned from - * visible to not-visible. Some reasons include: - * - * - Window was destroyed - * - Window is minimized - * - Window is moved to a different desktop - * - Window no longer sticky. - * - * Note that combinations are possible - a window might have first - * been minimized and then moved to a different desktop. The - * 'effect' parameter to show_window() and hide_window() is a hint - * as to the appropriate effect to show the user and should not - * be considered to be indicative of a state change. - * - * When the active workspace is changed, switch_workspace() is called - * first, then show_window() and hide_window() are called individually - * for each window affected, with an effect of META_COMP_EFFECT_NONE. - * If hiding windows will affect the switch workspace animation, the - * compositor needs to delay hiding the windows until the switch - * workspace animation completes. - * - * maximize_window() and unmaximize_window() are transitions within - * the visible state. The window is resized *before* the call, so - * it may be necessary to readjust the display based on the old_rect - * to start the animation. - */ +META_EXPORT +gboolean meta_compositor_filter_keybinding (MetaCompositor *compositor, + MetaKeyBinding *binding); + +META_EXPORT +void meta_compositor_add_window (MetaCompositor *compositor, + MetaWindow *window); -void meta_compositor_add_window (MetaCompositor *compositor, - MetaWindow *window); -void meta_compositor_remove_window (MetaCompositor *compositor, - MetaWindow *window); +META_EXPORT +void meta_compositor_remove_window (MetaCompositor *compositor, + MetaWindow *window); +META_EXPORT void meta_compositor_show_window (MetaCompositor *compositor, MetaWindow *window, MetaCompEffect effect); + +META_EXPORT void meta_compositor_hide_window (MetaCompositor *compositor, MetaWindow *window, MetaCompEffect effect); + +META_EXPORT void meta_compositor_switch_workspace (MetaCompositor *compositor, - MetaScreen *screen, MetaWorkspace *from, MetaWorkspace *to, MetaMotionDirection direction); -void meta_compositor_maximize_window (MetaCompositor *compositor, - MetaWindow *window, - MetaRectangle *old_rect, - MetaRectangle *new_rect); -void meta_compositor_unmaximize_window (MetaCompositor *compositor, - MetaWindow *window, - MetaRectangle *old_rect, - MetaRectangle *new_rect); +META_EXPORT +void meta_compositor_size_change_window (MetaCompositor *compositor, + MetaWindow *window, + MetaSizeChange which_change, + MetaRectangle *old_frame_rect, + MetaRectangle *old_buffer_rect); +META_EXPORT void meta_compositor_sync_window_geometry (MetaCompositor *compositor, MetaWindow *window, gboolean did_placement); -void meta_compositor_set_updates_frozen (MetaCompositor *compositor, - MetaWindow *window, - gboolean updates_frozen); + +META_EXPORT +void meta_compositor_sync_updates_frozen (MetaCompositor *compositor, + MetaWindow *window); + +META_EXPORT void meta_compositor_queue_frame_drawn (MetaCompositor *compositor, MetaWindow *window, gboolean no_delay_frame); +META_EXPORT void meta_compositor_sync_stack (MetaCompositor *compositor, - MetaScreen *screen, GList *stack); -void meta_compositor_sync_screen_size (MetaCompositor *compositor, - MetaScreen *screen, - guint width, - guint height); - -void meta_compositor_flash_screen (MetaCompositor *compositor, - MetaScreen *screen); - -void meta_compositor_tile_window (MetaCompositor *compositor, - MetaWindow *window, - MetaRectangle *old_rect, - MetaRectangle *new_rect); - -void meta_compositor_show_tile_preview (MetaCompositor *compositor, - MetaScreen *screen, - MetaWindow *window, - MetaRectangle *tile_rect, - int tile_monitor_number, - guint snap_queued); - -void meta_compositor_hide_tile_preview (MetaCompositor *compositor, - MetaScreen *screen); - -void meta_compositor_show_hud_preview (MetaCompositor *compositor, - MetaScreen *screen, - guint current_proximity_zone, - MetaRectangle *work_area, - guint snap_queued); - -void meta_compositor_hide_hud_preview (MetaCompositor *compositor, - MetaScreen *screen); -void meta_compositor_toggle_send_frame_timings (MetaScreen *screen); +META_EXPORT +void meta_compositor_flash_display (MetaCompositor *compositor, + MetaDisplay *display); + +META_EXPORT +void meta_compositor_show_tile_preview (MetaCompositor *compositor, + MetaWindow *window, + MetaRectangle *tile_rect, + int tile_monitor_number); + +META_EXPORT +void meta_compositor_hide_tile_preview (MetaCompositor *compositor); + +META_EXPORT +void meta_compositor_show_window_menu (MetaCompositor *compositor, + MetaWindow *window, + MetaWindowMenuType menu, + int x, + int y); + +META_EXPORT +void meta_compositor_show_window_menu_for_rect (MetaCompositor *compositor, + MetaWindow *window, + MetaWindowMenuType menu, + MetaRectangle *rect); #endif /* META_COMPOSITOR_H */ diff --git a/src/meta/display.h b/src/meta/display.h index 434296f17..5cf99cfea 100644 --- a/src/meta/display.h +++ b/src/meta/display.h @@ -14,9 +14,7 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_DISPLAY_H @@ -28,7 +26,17 @@ #include <meta/types.h> #include <meta/prefs.h> #include <meta/common.h> - +#include <meta/workspace.h> +#include <meta/meta-sound-player.h> +#include <meta/meta-startup-notification.h> + +/** + * MetaTabList: + * @META_TAB_LIST_NORMAL: Normal windows + * @META_TAB_LIST_DOCKS: Dock windows + * @META_TAB_LIST_GROUP: Groups + * @META_TAB_LIST_NORMAL_ALL: All windows + */ typedef enum { META_TAB_LIST_NORMAL, @@ -37,12 +45,24 @@ typedef enum META_TAB_LIST_NORMAL_ALL } MetaTabList; +/** + * MetaTabShowType: + * @META_TAB_SHOW_ICON: Show icon (Alt-Tab mode) + * @META_TAB_SHOW_INSTANTLY: Show instantly (Alt-Esc mode) + */ typedef enum { META_TAB_SHOW_ICON, /* Alt-Tab mode */ META_TAB_SHOW_INSTANTLY /* Alt-Esc mode */ } MetaTabShowType; +typedef enum +{ + META_PAD_ACTION_BUTTON, /* Action is a button */ + META_PAD_ACTION_RING, /* Action is a ring */ + META_PAD_ACTION_STRIP, /* Action is a strip */ +} MetaPadActionType; + typedef struct _MetaDisplayClass MetaDisplayClass; #define META_TYPE_DISPLAY (meta_display_get_type ()) @@ -52,66 +72,60 @@ typedef struct _MetaDisplayClass MetaDisplayClass; #define META_IS_DISPLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_DISPLAY)) #define META_DISPLAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_DISPLAY, MetaDisplayClass)) +META_EXPORT GType meta_display_get_type (void) G_GNUC_CONST; #define meta_XFree(p) do { if ((p)) XFree ((p)); } while (0) -typedef enum { - META_LIST_DEFAULT = 0, /* normal windows */ - META_LIST_INCLUDE_OVERRIDE_REDIRECT = 1 << 0, /* normal and O-R */ -} MetaListWindowsFlags; - -void meta_display_get_compositor_version (MetaDisplay *display, - int *major, - int *minor); -Display *meta_display_get_xdisplay (MetaDisplay *display); -MetaCompositor *meta_display_get_compositor (MetaDisplay *display); -GSList *meta_display_get_screens (MetaDisplay *display); +META_EXPORT +gboolean meta_display_supports_extended_barriers (MetaDisplay *display); -gboolean meta_display_has_shape (MetaDisplay *display); +META_EXPORT +void meta_display_close (MetaDisplay *display, + guint32 timestamp); -MetaScreen *meta_display_screen_for_root (MetaDisplay *display, - Window xroot); -MetaWindow *meta_display_get_focus_window (MetaDisplay *display); +META_EXPORT +MetaCompositor *meta_display_get_compositor (MetaDisplay *display); -GSList* meta_display_list_windows (MetaDisplay *display, - MetaListWindowsFlags flags); +META_EXPORT +MetaX11Display *meta_display_get_x11_display (MetaDisplay *display); -gboolean meta_display_xwindow_is_a_no_focus_window (MetaDisplay *display, - Window xwindow); - -int meta_display_get_damage_event_base (MetaDisplay *display); -int meta_display_get_shape_event_base (MetaDisplay *display); +META_EXPORT +MetaWindow *meta_display_get_focus_window (MetaDisplay *display); +META_EXPORT gboolean meta_display_xserver_time_is_before (MetaDisplay *display, guint32 time1, guint32 time2); +META_EXPORT guint32 meta_display_get_last_user_time (MetaDisplay *display); + +META_EXPORT guint32 meta_display_get_current_time (MetaDisplay *display); -guint32 meta_display_get_current_time_roundtrip (MetaDisplay *display); -unsigned int meta_display_get_ignored_modifier_mask (MetaDisplay *display); +META_EXPORT +guint32 meta_display_get_current_time_roundtrip (MetaDisplay *display); +META_EXPORT GList* meta_display_get_tab_list (MetaDisplay *display, MetaTabList type, - MetaScreen *screen, MetaWorkspace *workspace); +META_EXPORT MetaWindow* meta_display_get_tab_next (MetaDisplay *display, MetaTabList type, - MetaScreen *screen, MetaWorkspace *workspace, MetaWindow *window, gboolean backward); +META_EXPORT MetaWindow* meta_display_get_tab_current (MetaDisplay *display, MetaTabList type, - MetaScreen *screen, MetaWorkspace *workspace); +META_EXPORT gboolean meta_display_begin_grab_op (MetaDisplay *display, - MetaScreen *screen, MetaWindow *window, MetaGrabOp op, gboolean pointer_already_grabbed, @@ -121,75 +135,175 @@ gboolean meta_display_begin_grab_op (MetaDisplay *display, guint32 timestamp, int root_x, int root_y); + +META_EXPORT void meta_display_end_grab_op (MetaDisplay *display, guint32 timestamp); +META_EXPORT MetaGrabOp meta_display_get_grab_op (MetaDisplay *display); -gboolean meta_display_add_keybinding (MetaDisplay *display, - const char *name, - const char *schema, - MetaKeyBindingFlags flags, - MetaKeyHandlerFunc handler, - gpointer user_data, - GDestroyNotify free_data); +META_EXPORT +guint meta_display_add_keybinding (MetaDisplay *display, + const char *name, + GSettings *settings, + MetaKeyBindingFlags flags, + MetaKeyHandlerFunc handler, + gpointer user_data, + GDestroyNotify free_data); + +META_EXPORT gboolean meta_display_remove_keybinding (MetaDisplay *display, const char *name); -void meta_display_rebuild_keybindings (MetaDisplay *display); - -gboolean meta_display_add_custom_keybinding (MetaDisplay *display, - const char *name, - const char **bindings, - MetaKeyHandlerFunc callback, - gpointer user_data, - GDestroyNotify free_data); - -gboolean meta_display_remove_custom_keybinding (MetaDisplay *display, - const char *name); - -MetaKeyBindingAction meta_display_get_keybinding_action (MetaDisplay *display, - unsigned int keycode, - unsigned long mask); - -/* meta_display_set_input_focus_window is like XSetInputFocus, except - * that (a) it can't detect timestamps later than the current time, - * since Muffin isn't part of the XServer, and thus gives erroneous - * behavior in this circumstance (so don't do it), (b) it uses - * display->last_focus_time since we don't have access to the true - * Xserver one, (c) it makes use of display->user_time since checking - * whether a window should be allowed to be focused should depend - * on user_time events (see bug 167358, comment 15 in particular) - */ -void meta_display_set_input_focus_window (MetaDisplay *display, - MetaWindow *window, - gboolean focus_frame, - guint32 timestamp); - -/* meta_display_focus_the_no_focus_window is called when the - * designated no_focus_window should be focused, but is otherwise the - * same as meta_display_set_input_focus_window - */ -void meta_display_focus_the_no_focus_window (MetaDisplay *display, - MetaScreen *screen, - guint32 timestamp); +META_EXPORT +guint meta_display_grab_accelerator (MetaDisplay *display, + const char *accelerator, + MetaKeyBindingFlags flags); + +META_EXPORT +gboolean meta_display_ungrab_accelerator (MetaDisplay *display, + guint action_id); +META_EXPORT +guint meta_display_get_keybinding_action (MetaDisplay *display, + unsigned int keycode, + unsigned long mask); + +META_EXPORT GSList *meta_display_sort_windows_by_stacking (MetaDisplay *display, GSList *windows); -Window meta_display_get_leader_window (MetaDisplay *display); - +META_EXPORT void meta_display_add_ignored_crossing_serial (MetaDisplay *display, unsigned long serial); -void meta_display_unmanage_screen (MetaDisplay *display, - MetaScreen *screen, +META_EXPORT +void meta_display_clear_mouse_mode (MetaDisplay *display); + +META_EXPORT +void meta_display_freeze_keyboard (MetaDisplay *display, guint32 timestamp); -void meta_display_keybinding_action_invoke_by_code (MetaDisplay *display, - unsigned int keycode, - unsigned long mask); +META_EXPORT +void meta_display_ungrab_keyboard (MetaDisplay *display, + guint32 timestamp); -void meta_display_restart (MetaDisplay *display); +META_EXPORT +void meta_display_unfreeze_keyboard (MetaDisplay *display, + guint32 timestamp); + +META_EXPORT +gboolean meta_display_is_pointer_emulating_sequence (MetaDisplay *display, + ClutterEventSequence *sequence); + +META_EXPORT +void meta_display_request_pad_osd (MetaDisplay *display, + ClutterInputDevice *pad, + gboolean edition_mode); + +META_EXPORT +gchar * meta_display_get_pad_action_label (MetaDisplay *display, + ClutterInputDevice *pad, + MetaPadActionType action_type, + guint action_number); + +META_EXPORT +void meta_display_get_size (MetaDisplay *display, + int *width, + int *height); + +META_EXPORT +void meta_display_set_cursor (MetaDisplay *display, + MetaCursor cursor); + +/** + * MetaDisplayDirection: + * @META_DISPLAY_UP: up + * @META_DISPLAY_DOWN: down + * @META_DISPLAY_LEFT: left + * @META_DISPLAY_RIGHT: right + */ +typedef enum +{ + META_DISPLAY_UP, + META_DISPLAY_DOWN, + META_DISPLAY_LEFT, + META_DISPLAY_RIGHT +} MetaDisplayDirection; + +META_EXPORT +int meta_display_get_n_monitors (MetaDisplay *display); + +META_EXPORT +int meta_display_get_primary_monitor (MetaDisplay *display); + +META_EXPORT +int meta_display_get_current_monitor (MetaDisplay *display); + +META_EXPORT +void meta_display_get_monitor_geometry (MetaDisplay *display, + int monitor, + MetaRectangle *geometry); + +META_EXPORT +float meta_display_get_monitor_scale (MetaDisplay *display, + int monitor); + +META_EXPORT +gboolean meta_display_get_monitor_in_fullscreen (MetaDisplay *display, + int monitor); + +META_EXPORT +int meta_display_get_monitor_index_for_rect (MetaDisplay *display, + MetaRectangle *rect); + +META_EXPORT +int meta_display_get_monitor_neighbor_index (MetaDisplay *display, + int which_monitor, + MetaDisplayDirection dir); + +META_EXPORT +void meta_display_focus_default_window (MetaDisplay *display, + guint32 timestamp); + +/** + * MetaDisplayCorner: + * @META_DISPLAY_TOPLEFT: top-left corner + * @META_DISPLAY_TOPRIGHT: top-right corner + * @META_DISPLAY_BOTTOMLEFT: bottom-left corner + * @META_DISPLAY_BOTTOMRIGHT: bottom-right corner + */ +typedef enum +{ + META_DISPLAY_TOPLEFT, + META_DISPLAY_TOPRIGHT, + META_DISPLAY_BOTTOMLEFT, + META_DISPLAY_BOTTOMRIGHT +} MetaDisplayCorner; + +META_EXPORT +MetaWorkspaceManager *meta_display_get_workspace_manager (MetaDisplay *display); + +/** + * meta_display_get_startup_notification: (skip) + */ +META_EXPORT +MetaStartupNotification * meta_display_get_startup_notification (MetaDisplay *display); + +META_EXPORT +MetaSoundPlayer * meta_display_get_sound_player (MetaDisplay *display); + +META_EXPORT +MetaSelection * meta_display_get_selection (MetaDisplay *display); + +META_EXPORT +void meta_display_set_input_focus (MetaDisplay *display, + MetaWindow *window, + gboolean focus_frame, + guint32 timestamp); +META_EXPORT +void meta_display_unset_input_focus (MetaDisplay *display, + guint32 timestamp); #endif diff --git a/src/meta/gradient.h b/src/meta/gradient.h deleted file mode 100644 index 47c0536ab..000000000 --- a/src/meta/gradient.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Muffin gradient rendering */ - -/* - * Copyright (C) 2001 Havoc Pennington, 99% copied from wrlib in - * WindowMaker, Copyright (C) 1997-2000 Dan Pascu and Alfredo Kojima - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. */ - -#ifndef META_GRADIENT_H -#define META_GRADIENT_H - -#include <gdk-pixbuf/gdk-pixbuf.h> -#include <gdk/gdk.h> - -typedef enum -{ - META_GRADIENT_VERTICAL, - META_GRADIENT_HORIZONTAL, - META_GRADIENT_DIAGONAL, - META_GRADIENT_LAST -} MetaGradientType; - -GdkPixbuf* meta_gradient_create_simple (int width, - int height, - const GdkRGBA *from, - const GdkRGBA *to, - MetaGradientType style); -GdkPixbuf* meta_gradient_create_multi (int width, - int height, - const GdkRGBA *colors, - int n_colors, - MetaGradientType style); -GdkPixbuf* meta_gradient_create_interwoven (int width, - int height, - const GdkRGBA colors1[2], - int thickness1, - const GdkRGBA colors2[2], - int thickness2); - - -/* Generate an alpha gradient and multiply it with the existing alpha - * channel of the given pixbuf - */ -void meta_gradient_add_alpha (GdkPixbuf *pixbuf, - const guchar *alphas, - int n_alphas, - MetaGradientType type); - - -#endif diff --git a/src/meta/group.h b/src/meta/group.h index 666afa40a..5567cf466 100644 --- a/src/meta/group.h +++ b/src/meta/group.h @@ -1,10 +1,10 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* Muffin window groups */ +/* Mutter window groups */ -/* +/* * Copyright (C) 2002 Red Hat Inc. - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the @@ -14,11 +14,9 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_GROUP_H @@ -26,32 +24,42 @@ #include <X11/Xlib.h> #include <glib.h> + +#include <meta/common.h> #include <meta/types.h> /* note, can return NULL */ +META_EXPORT MetaGroup* meta_window_get_group (MetaWindow *window); + +META_EXPORT void meta_window_compute_group (MetaWindow* window); + +META_EXPORT void meta_window_shutdown_group (MetaWindow *window); +META_EXPORT void meta_window_group_leader_changed (MetaWindow *window); /* note, can return NULL */ -MetaGroup* meta_display_lookup_group (MetaDisplay *display, - Window group_leader); +META_EXPORT +MetaGroup *meta_x11_display_lookup_group (MetaX11Display *x11_display, + Window group_leader); +META_EXPORT GSList* meta_group_list_windows (MetaGroup *group); +META_EXPORT void meta_group_update_layers (MetaGroup *group); +META_EXPORT const char* meta_group_get_startup_id (MetaGroup *group); +META_EXPORT int meta_group_get_size (MetaGroup *group); +META_EXPORT gboolean meta_group_property_notify (MetaGroup *group, XEvent *event); #endif - - - - diff --git a/src/meta/keybindings.h b/src/meta/keybindings.h index c69506831..ac1cee5b3 100644 --- a/src/meta/keybindings.h +++ b/src/meta/keybindings.h @@ -12,9 +12,7 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_KEYBINDINGS_H @@ -25,16 +23,24 @@ #define META_TYPE_KEY_BINDING (meta_key_binding_get_type ()) +META_EXPORT const char *meta_key_binding_get_name (MetaKeyBinding *binding); + +META_EXPORT MetaVirtualModifier meta_key_binding_get_modifiers (MetaKeyBinding *binding); + +META_EXPORT guint meta_key_binding_get_mask (MetaKeyBinding *binding); +META_EXPORT +gboolean meta_key_binding_is_builtin (MetaKeyBinding *binding); + +META_EXPORT +gboolean meta_key_binding_is_reversed (MetaKeyBinding *binding); + +META_EXPORT gboolean meta_keybindings_set_custom_handler (const gchar *name, MetaKeyHandlerFunc handler, gpointer user_data, GDestroyNotify free_data); - - -void meta_screen_ungrab_all_keys (MetaScreen *screen, guint32 timestamp); -gboolean meta_screen_grab_all_keys (MetaScreen *screen, guint32 timestamp); #endif diff --git a/src/meta/main.h b/src/meta/main.h index c9294d18b..6115b7220 100644 --- a/src/meta/main.h +++ b/src/meta/main.h @@ -1,6 +1,6 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* Muffin main */ +/* Mutter main */ /* * Copyright (C) 2001 Havoc Pennington @@ -16,9 +16,7 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_MAIN_H @@ -26,15 +24,37 @@ #include <glib.h> -GOptionContext *meta_get_option_context (void); -void meta_init (void); -int meta_run (void); +#include <meta/common.h> + +META_EXPORT +GOptionContext *meta_get_option_context (void); + +META_EXPORT +void meta_init (void); + +META_EXPORT +int meta_run (void); + +META_EXPORT +void meta_register_with_session (void); + +META_EXPORT +gboolean meta_activate_session (void); /* Actually defined in meta-backend.c */ + +META_EXPORT gboolean meta_get_replace_current_wm (void); /* Actually defined in util.c */ +META_EXPORT void meta_set_wm_name (const char *wm_name); + +META_EXPORT void meta_set_gnome_wm_keybindings (const char *wm_keybindings); -void meta_restart (void); +META_EXPORT +void meta_restart (const char *message); + +META_EXPORT +gboolean meta_is_restart (void); /** * MetaExitCode: @@ -48,9 +68,15 @@ typedef enum } MetaExitCode; /* exit immediately */ -void meta_exit (MetaExitCode code); +META_EXPORT +void meta_exit (MetaExitCode code) G_GNUC_NORETURN; /* g_main_loop_quit() then fall out of main() */ +META_EXPORT void meta_quit (MetaExitCode code); +META_EXPORT +void meta_test_init (void); + + #endif diff --git a/src/meta/meson.build b/src/meta/meson.build new file mode 100644 index 000000000..14caec58d --- /dev/null +++ b/src/meta/meson.build @@ -0,0 +1,88 @@ +mutter_public_headers = [ + 'barrier.h', + 'boxes.h', + 'common.h', + 'compositor.h', + 'compositor-mutter.h', + 'display.h', + 'group.h', + 'keybindings.h', + 'main.h', + 'meta-backend.h', + 'meta-background.h', + 'meta-background-actor.h', + 'meta-background-group.h', + 'meta-background-image.h', + 'meta-close-dialog.h', + 'meta-cursor-tracker.h', + 'meta-dnd.h', + 'meta-idle-monitor.h', + 'meta-inhibit-shortcuts-dialog.h', + 'meta-launch-context.h', + 'meta-monitor-manager.h', + 'meta-plugin.h', + 'meta-remote-access-controller.h', + 'meta-selection.h', + 'meta-selection-source.h', + 'meta-selection-source-memory.h', + 'meta-settings.h', + 'meta-shadow-factory.h', + 'meta-shaped-texture.h', + 'meta-sound-player.h', + 'meta-stage.h', + 'meta-startup-notification.h', + 'meta-window-actor.h', + 'meta-window-group.h', + 'meta-window-shape.h', + 'meta-workspace-manager.h', + 'prefs.h', + 'theme.h', + 'types.h', + 'util.h', + 'window.h', + 'workspace.h', +] + +if have_x11 + mutter_public_headers += [ + 'meta-x11-display.h', + 'meta-x11-errors.h', + ] +endif + +install_headers(mutter_public_headers, + subdir: mutter_includesubdir +) + +mutter_public_header_files = files(mutter_public_headers) + +mutter_enum_types = gnome.mkenums('meta-enum-types', + sources: [mutter_public_headers], + c_template: 'meta-enum-types.c.in', + h_template: 'meta-enum-types.h.in', + install_dir: mutter_includedir, + install_header: true, +) + +mutter_version_array = meson.project_version().split('.') +mutter_version_major = mutter_version_array[0] +mutter_version_minor = mutter_version_array[1] +mutter_version_micro = mutter_version_array[2] + +mutter_version_cdata = configuration_data() +mutter_version_cdata.set('MUTTER_MAJOR_VERSION', + '@0@'.format(mutter_version_major)) +mutter_version_cdata.set('MUTTER_MINOR_VERSION', + '@0@'.format(mutter_version_minor)) +mutter_version_cdata.set('MUTTER_MICRO_VERSION', + '@0@'.format(mutter_version_micro)) +mutter_version_cdata.set('MUTTER_PLUGIN_API_VERSION', + '@0@'.format(mutter_plugin_api_version)) + +mutter_version = configure_file( + input: 'meta-version.h.in', + output: 'meta-version.h', + configuration: mutter_version_cdata, + install_dir: mutter_includedir, + install: true, +) diff --git a/src/meta/meta-backend.h b/src/meta/meta-backend.h new file mode 100644 index 000000000..8edc0bf2c --- /dev/null +++ b/src/meta/meta-backend.h @@ -0,0 +1,73 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jasper St. Pierre <jstpierre@mecheye.net> + */ + +#ifndef META_BACKEND_H +#define META_BACKEND_H + +#include <glib-object.h> + +#include "clutter/clutter.h" +#include "meta/meta-dnd.h" +#include "meta/meta-remote-access-controller.h" + +#define META_TYPE_BACKEND (meta_backend_get_type ()) +META_EXPORT +G_DECLARE_DERIVABLE_TYPE (MetaBackend, meta_backend, META, BACKEND, GObject) + +META_EXPORT +MetaBackend * meta_get_backend (void); + +META_EXPORT +void meta_backend_set_keymap (MetaBackend *backend, + const char *layouts, + const char *variants, + const char *options); + +META_EXPORT +void meta_backend_lock_layout_group (MetaBackend *backend, + guint idx); + +META_EXPORT +void meta_backend_set_numlock (MetaBackend *backend, + gboolean numlock_state); + +META_EXPORT +ClutterActor *meta_backend_get_stage (MetaBackend *backend); + +META_EXPORT +MetaDnd *meta_backend_get_dnd (MetaBackend *backend); + +META_EXPORT +MetaSettings *meta_backend_get_settings (MetaBackend *backend); + +META_EXPORT +MetaRemoteAccessController * meta_backend_get_remote_access_controller (MetaBackend *backend); + +META_EXPORT +gboolean meta_backend_is_rendering_hardware_accelerated (MetaBackend *backend); + +META_EXPORT +void meta_clutter_init (void); + +#endif /* META_BACKEND_H */ diff --git a/src/meta/meta-background-actor.h b/src/meta/meta-background-actor.h index a5f65dbaa..93a05a8de 100644 --- a/src/meta/meta-background-actor.h +++ b/src/meta/meta-background-actor.h @@ -15,17 +15,16 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_BACKGROUND_ACTOR_H #define META_BACKGROUND_ACTOR_H -#include <clutter/clutter.h> +#include <libcinnamon-desktop/cdesktop-enums.h> -#include <meta/screen.h> +#include "clutter/clutter.h" +#include "meta/meta-background.h" /** * MetaBackgroundActor: @@ -35,31 +34,37 @@ * the background that are obscured by other windows. */ -#define META_TYPE_BACKGROUND_ACTOR (meta_background_actor_get_type ()) -#define META_BACKGROUND_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_BACKGROUND_ACTOR, MetaBackgroundActor)) -#define META_BACKGROUND_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_BACKGROUND_ACTOR, MetaBackgroundActorClass)) -#define META_IS_BACKGROUND_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_BACKGROUND_ACTOR)) -#define META_IS_BACKGROUND_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_BACKGROUND_ACTOR)) -#define META_BACKGROUND_ACTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_BACKGROUND_ACTOR, MetaBackgroundActorClass)) +#define META_TYPE_BACKGROUND_ACTOR (meta_background_actor_get_type ()) -typedef struct _MetaBackgroundActor MetaBackgroundActor; -typedef struct _MetaBackgroundActorClass MetaBackgroundActorClass; -typedef struct _MetaBackgroundActorPrivate MetaBackgroundActorPrivate; +META_EXPORT +G_DECLARE_FINAL_TYPE (MetaBackgroundActor, + meta_background_actor, + META, BACKGROUND_ACTOR, + ClutterActor) -struct _MetaBackgroundActorClass -{ - ClutterActorClass parent_class; -}; -struct _MetaBackgroundActor -{ - ClutterActor parent; +META_EXPORT +ClutterActor *meta_background_actor_new (MetaDisplay *display, + int monitor); - MetaBackgroundActorPrivate *priv; -}; +META_EXPORT +void meta_background_actor_set_background (MetaBackgroundActor *self, + MetaBackground *background); -GType meta_background_actor_get_type (void); +META_EXPORT +void meta_background_actor_set_gradient (MetaBackgroundActor *self, + gboolean enabled, + int height, + double tone_start); -ClutterActor *meta_background_actor_new_for_screen (MetaScreen *screen); +META_EXPORT +void meta_background_actor_set_monitor (MetaBackgroundActor *self, + int monitor); + +META_EXPORT +void meta_background_actor_set_vignette (MetaBackgroundActor *self, + gboolean enabled, + double brightness, + double sharpness); #endif /* META_BACKGROUND_ACTOR_H */ diff --git a/src/meta/meta-background-group.h b/src/meta/meta-background-group.h new file mode 100644 index 000000000..b43fcb94a --- /dev/null +++ b/src/meta/meta-background-group.h @@ -0,0 +1,26 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +#ifndef META_BACKGROUND_GROUP_H +#define META_BACKGROUND_GROUP_H + +#include "clutter/clutter.h" + +#include <meta/common.h> + +#define META_TYPE_BACKGROUND_GROUP (meta_background_group_get_type ()) + +META_EXPORT +G_DECLARE_DERIVABLE_TYPE (MetaBackgroundGroup, + meta_background_group, + META, BACKGROUND_GROUP, + ClutterActor) + +struct _MetaBackgroundGroupClass +{ + ClutterActorClass parent_class; +}; + +META_EXPORT +ClutterActor *meta_background_group_new (void); + +#endif /* META_BACKGROUND_GROUP_H */ diff --git a/src/meta/meta-background-image.h b/src/meta/meta-background-image.h new file mode 100644 index 000000000..137a6ff8e --- /dev/null +++ b/src/meta/meta-background-image.h @@ -0,0 +1,69 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * MetaBackgroundImageCache: + * + * Simple cache for background textures loaded from files + * + * Copyright 2014 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __META_BACKGROUND_IMAGE_H__ +#define __META_BACKGROUND_IMAGE_H__ + +#include <gio/gio.h> +#include <glib-object.h> + +#include "cogl/cogl.h" +#include "meta/display.h" + +#define META_TYPE_BACKGROUND_IMAGE (meta_background_image_get_type ()) + +META_EXPORT +G_DECLARE_FINAL_TYPE (MetaBackgroundImage, + meta_background_image, + META, BACKGROUND_IMAGE, + GObject) + +META_EXPORT +gboolean meta_background_image_is_loaded (MetaBackgroundImage *image); + +META_EXPORT +gboolean meta_background_image_get_success (MetaBackgroundImage *image); + +META_EXPORT +CoglTexture *meta_background_image_get_texture (MetaBackgroundImage *image); + + +#define META_TYPE_BACKGROUND_IMAGE_CACHE (meta_background_image_cache_get_type ()) + +META_EXPORT +G_DECLARE_FINAL_TYPE (MetaBackgroundImageCache, + meta_background_image_cache, + META, BACKGROUND_IMAGE_CACHE, + GObject) + +META_EXPORT +MetaBackgroundImageCache *meta_background_image_cache_get_default (void); + +META_EXPORT +MetaBackgroundImage *meta_background_image_cache_load (MetaBackgroundImageCache *cache, + GFile *file); + +META_EXPORT +void meta_background_image_cache_purge (MetaBackgroundImageCache *cache, + GFile *file); + +#endif /* __META_BACKGROUND_IMAGE_H__ */ diff --git a/src/meta/meta-background.h b/src/meta/meta-background.h new file mode 100644 index 000000000..fcec8b20d --- /dev/null +++ b/src/meta/meta-background.h @@ -0,0 +1,74 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * meta-background-actor.h: for painting the root window background + * + * Copyright 2010 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef META_BACKGROUND_H +#define META_BACKGROUND_H + +#include <libcinnamon-desktop/cdesktop-enums.h> + +#include "clutter/clutter.h" +#include "meta/display.h" + +/** + * MetaBackground: + * + * This class handles tracking and painting the root window background. + * By integrating with #MetaWindowGroup we can avoid painting parts of + * the background that are obscured by other windows. + */ + +#define META_TYPE_BACKGROUND (meta_background_get_type ()) + +META_EXPORT +G_DECLARE_FINAL_TYPE (MetaBackground, + meta_background, + META, BACKGROUND, + GObject) + + +META_EXPORT +void meta_background_refresh_all (void); + +META_EXPORT +MetaBackground *meta_background_new (MetaDisplay *display); + +META_EXPORT +void meta_background_set_color (MetaBackground *self, + ClutterColor *color); + +META_EXPORT +void meta_background_set_gradient (MetaBackground *self, + CDesktopBackgroundShading shading_direction, + ClutterColor *color, + ClutterColor *second_color); + +META_EXPORT +void meta_background_set_file (MetaBackground *self, + GFile *file, + CDesktopBackgroundStyle style); + +META_EXPORT +void meta_background_set_blend (MetaBackground *self, + GFile *file1, + GFile *file2, + double blend_factor, + CDesktopBackgroundStyle style); + +#endif /* META_BACKGROUND_H */ diff --git a/src/meta/meta-close-dialog.h b/src/meta/meta-close-dialog.h new file mode 100644 index 000000000..281b0ee24 --- /dev/null +++ b/src/meta/meta-close-dialog.h @@ -0,0 +1,65 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef META_CLOSE_DIALOG_H +#define META_CLOSE_DIALOG_H + +#include <glib-object.h> +#include <meta/window.h> + +#define META_TYPE_CLOSE_DIALOG (meta_close_dialog_get_type ()) + +META_EXPORT +G_DECLARE_INTERFACE (MetaCloseDialog, meta_close_dialog, + META, CLOSE_DIALOG, GObject) + +typedef enum +{ + META_CLOSE_DIALOG_RESPONSE_WAIT, + META_CLOSE_DIALOG_RESPONSE_FORCE_CLOSE, +} MetaCloseDialogResponse; + +struct _MetaCloseDialogInterface +{ + GTypeInterface parent_iface; + + void (* show) (MetaCloseDialog *dialog); + void (* hide) (MetaCloseDialog *dialog); + void (* focus) (MetaCloseDialog *dialog); +}; + +META_EXPORT +void meta_close_dialog_show (MetaCloseDialog *dialog); + +META_EXPORT +void meta_close_dialog_hide (MetaCloseDialog *dialog); + +META_EXPORT +void meta_close_dialog_focus (MetaCloseDialog *dialog); + +META_EXPORT +gboolean meta_close_dialog_is_visible (MetaCloseDialog *dialog); + +META_EXPORT +void meta_close_dialog_response (MetaCloseDialog *dialog, + MetaCloseDialogResponse response); + +#endif /* META_CLOSE_DIALOG_H */ diff --git a/src/meta/meta-cursor-tracker.h b/src/meta/meta-cursor-tracker.h new file mode 100644 index 000000000..2f51115e4 --- /dev/null +++ b/src/meta/meta-cursor-tracker.h @@ -0,0 +1,65 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2013 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: Giovanni Campagna <gcampagn@redhat.com> + */ + +#ifndef META_CURSOR_TRACKER_H +#define META_CURSOR_TRACKER_H + +#include <glib-object.h> + +#include "clutter/clutter.h" +#include "cogl/cogl.h" +#include "meta/types.h" +#include "meta/workspace.h" + +#define META_TYPE_CURSOR_TRACKER (meta_cursor_tracker_get_type ()) + +META_EXPORT +G_DECLARE_FINAL_TYPE (MetaCursorTracker, + meta_cursor_tracker, + META, CURSOR_TRACKER, + GObject) + + +META_EXPORT +MetaCursorTracker *meta_cursor_tracker_get_for_display (MetaDisplay *display); + +META_EXPORT +void meta_cursor_tracker_get_hot (MetaCursorTracker *tracker, + int *x, + int *y); + +META_EXPORT +CoglTexture *meta_cursor_tracker_get_sprite (MetaCursorTracker *tracker); + +META_EXPORT +void meta_cursor_tracker_get_pointer (MetaCursorTracker *tracker, + int *x, + int *y, + ClutterModifierType *mods); + +META_EXPORT +gboolean meta_cursor_tracker_get_pointer_visible (MetaCursorTracker *tracker); + +META_EXPORT +void meta_cursor_tracker_set_pointer_visible (MetaCursorTracker *tracker, + gboolean visible); + +#endif diff --git a/src/meta/meta-dnd.h b/src/meta/meta-dnd.h new file mode 100644 index 000000000..2b2be1029 --- /dev/null +++ b/src/meta/meta-dnd.h @@ -0,0 +1,34 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Hyungwon Hwang + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef META_DND_H +#define META_DND_H + +#include <glib-object.h> +#include <string.h> + +#include <meta/common.h> +#include <meta/types.h> + +#define META_TYPE_DND (meta_dnd_get_type ()) + +META_EXPORT +G_DECLARE_FINAL_TYPE (MetaDnd, meta_dnd, META, DND, GObject) + +#endif /* META_DND_H */ diff --git a/src/muffin-enum-types.c.in b/src/meta/meta-enum-types.c.in similarity index 96% rename from src/muffin-enum-types.c.in rename to src/meta/meta-enum-types.c.in index 17e815989..0480ffdca 100644 --- a/src/muffin-enum-types.c.in +++ b/src/meta/meta-enum-types.c.in @@ -1,5 +1,5 @@ /*** BEGIN file-header ***/ -#include "muffin-enum-types.h" +#include <meta/meta-enum-types.h> /*** END file-header ***/ /*** BEGIN file-production ***/ diff --git a/src/muffin-enum-types.h.in b/src/meta/meta-enum-types.h.in similarity index 60% rename from src/muffin-enum-types.h.in rename to src/meta/meta-enum-types.h.in index 7b26c2dc9..bee0196de 100644 --- a/src/muffin-enum-types.h.in +++ b/src/meta/meta-enum-types.h.in @@ -1,25 +1,26 @@ /*** BEGIN file-header ***/ -#ifndef __MUFFIN_ENUM_TYPES_H__ -#define __MUFFIN_ENUM_TYPES_H__ +#ifndef __META_ENUM_TYPES_H__ +#define __META_ENUM_TYPES_H__ #include <glib-object.h> +#include <meta/common.h> G_BEGIN_DECLS /*** END file-header ***/ /*** BEGIN file-production ***/ -/* enumerations from "@filename@" */ +/* enumerations from "@basename@" */ /*** END file-production ***/ /*** BEGIN file-tail ***/ G_END_DECLS -#endif /* !__MUFFIN_ENUM_TYPES_H__ */ +#endif /* !__MUTTER_ENUM_TYPES_H__ */ /*** END file-tail ***/ /*** BEGIN value-header ***/ -GType @enum_name@_get_type (void) G_GNUC_CONST; +META_EXPORT GType @enum_name@_get_type (void) G_GNUC_CONST; #define META_TYPE_@ENUMSHORT@ (@enum_name@_get_type()) /*** END value-header ***/ diff --git a/src/meta/meta-idle-monitor.h b/src/meta/meta-idle-monitor.h new file mode 100644 index 000000000..caacd1f79 --- /dev/null +++ b/src/meta/meta-idle-monitor.h @@ -0,0 +1,66 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright 2013 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef META_IDLE_MONITOR_H +#define META_IDLE_MONITOR_H + +#include <glib-object.h> +#include <meta/types.h> + +#define META_TYPE_IDLE_MONITOR (meta_idle_monitor_get_type ()) +#define META_IDLE_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_IDLE_MONITOR, MetaIdleMonitor)) +#define META_IDLE_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_IDLE_MONITOR, MetaIdleMonitorClass)) +#define META_IS_IDLE_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_IDLE_MONITOR)) +#define META_IS_IDLE_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_IDLE_MONITOR)) +#define META_IDLE_MONITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_IDLE_MONITOR, MetaIdleMonitorClass)) + +typedef struct _MetaIdleMonitor MetaIdleMonitor; +typedef struct _MetaIdleMonitorClass MetaIdleMonitorClass; + +META_EXPORT +GType meta_idle_monitor_get_type (void); + +typedef void (*MetaIdleMonitorWatchFunc) (MetaIdleMonitor *monitor, + guint watch_id, + gpointer user_data); + +META_EXPORT +MetaIdleMonitor *meta_idle_monitor_get_core (void); + +META_EXPORT +guint meta_idle_monitor_add_idle_watch (MetaIdleMonitor *monitor, + guint64 interval_msec, + MetaIdleMonitorWatchFunc callback, + gpointer user_data, + GDestroyNotify notify); + +META_EXPORT +guint meta_idle_monitor_add_user_active_watch (MetaIdleMonitor *monitor, + MetaIdleMonitorWatchFunc callback, + gpointer user_data, + GDestroyNotify notify); + +META_EXPORT +void meta_idle_monitor_remove_watch (MetaIdleMonitor *monitor, + guint id); + +META_EXPORT +gint64 meta_idle_monitor_get_idletime (MetaIdleMonitor *monitor); + +#endif diff --git a/src/meta/meta-inhibit-shortcuts-dialog.h b/src/meta/meta-inhibit-shortcuts-dialog.h new file mode 100644 index 000000000..4e34f1701 --- /dev/null +++ b/src/meta/meta-inhibit-shortcuts-dialog.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + */ + +#ifndef META_INHIBIT_SHORTCUTS_DIALOG_H +#define META_INHIBIT_SHORTCUTS_DIALOG_H + +#include <glib-object.h> +#include <meta/window.h> + +#define META_TYPE_INHIBIT_SHORTCUTS_DIALOG (meta_inhibit_shortcuts_dialog_get_type ()) + +META_EXPORT +G_DECLARE_INTERFACE (MetaInhibitShortcutsDialog, meta_inhibit_shortcuts_dialog, + META, INHIBIT_SHORTCUTS_DIALOG, GObject) + +typedef enum +{ + META_INHIBIT_SHORTCUTS_DIALOG_RESPONSE_ALLOW, + META_INHIBIT_SHORTCUTS_DIALOG_RESPONSE_DENY, +} MetaInhibitShortcutsDialogResponse; + +struct _MetaInhibitShortcutsDialogInterface +{ + GTypeInterface parent_iface; + + void (* show) (MetaInhibitShortcutsDialog *dialog); + void (* hide) (MetaInhibitShortcutsDialog *dialog); +}; + +META_EXPORT +void meta_inhibit_shortcuts_dialog_show (MetaInhibitShortcutsDialog *dialog); + +META_EXPORT +void meta_inhibit_shortcuts_dialog_hide (MetaInhibitShortcutsDialog *dialog); + +META_EXPORT +void meta_inhibit_shortcuts_dialog_response (MetaInhibitShortcutsDialog *dialog, + MetaInhibitShortcutsDialogResponse response); + +#endif /* META_INHIBIT_SHORTCUTS_DIALOG_H */ diff --git a/src/meta/meta-launch-context.h b/src/meta/meta-launch-context.h new file mode 100644 index 000000000..b719f0e07 --- /dev/null +++ b/src/meta/meta-launch-context.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2018 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ +#ifndef META_LAUNCH_CONTEXT_H +#define META_LAUNCH_CONTEXT_H + +#include <meta/workspace.h> + +META_EXPORT +G_DECLARE_FINAL_TYPE (MetaLaunchContext, meta_launch_context, META, LAUNCH_CONTEXT, GAppLaunchContext) + +#define META_TYPE_LAUNCH_CONTEXT (meta_launch_context_get_type ()) + +META_EXPORT +void meta_launch_context_set_timestamp (MetaLaunchContext *context, + uint32_t timestamp); + +META_EXPORT +void meta_launch_context_set_workspace (MetaLaunchContext *context, + MetaWorkspace *workspace); + +#endif /* META_LAUNCH_CONTEXT_H */ diff --git a/src/meta/meta-monitor-manager.h b/src/meta/meta-monitor-manager.h new file mode 100644 index 000000000..033309cc8 --- /dev/null +++ b/src/meta/meta-monitor-manager.h @@ -0,0 +1,65 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2015 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_MONITOR_MANAGER_H +#define META_MONITOR_MANAGER_H + +#include <glib-object.h> + +typedef enum +{ + META_MONITOR_SWITCH_CONFIG_ALL_MIRROR, + META_MONITOR_SWITCH_CONFIG_ALL_LINEAR, + META_MONITOR_SWITCH_CONFIG_EXTERNAL, + META_MONITOR_SWITCH_CONFIG_BUILTIN, + META_MONITOR_SWITCH_CONFIG_UNKNOWN, +} MetaMonitorSwitchConfigType; + +typedef struct _MetaMonitorManagerClass MetaMonitorManagerClass; +typedef struct _MetaMonitorManager MetaMonitorManager; + +META_EXPORT +GType meta_monitor_manager_get_type (void); + +META_EXPORT +MetaMonitorManager *meta_monitor_manager_get (void); + +META_EXPORT +gint meta_monitor_manager_get_monitor_for_connector (MetaMonitorManager *manager, + const char *connector); + +META_EXPORT +gboolean meta_monitor_manager_get_is_builtin_display_on (MetaMonitorManager *manager); + +META_EXPORT +void meta_monitor_manager_switch_config (MetaMonitorManager *manager, + MetaMonitorSwitchConfigType config_type); + +META_EXPORT +gboolean meta_monitor_manager_can_switch_config (MetaMonitorManager *manager); + +META_EXPORT +MetaMonitorSwitchConfigType meta_monitor_manager_get_switch_config (MetaMonitorManager *manager); + +META_EXPORT +gint meta_monitor_manager_get_display_configuration_timeout (void); + +#endif /* META_MONITOR_MANAGER_H */ diff --git a/src/meta/meta-plugin.h b/src/meta/meta-plugin.h index 192ebecd6..b28836e88 100644 --- a/src/meta/meta-plugin.h +++ b/src/meta/meta-plugin.h @@ -16,122 +16,249 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_PLUGIN_H_ #define META_PLUGIN_H_ -#include <meta/types.h> -#include <meta/compositor.h> -#include <meta/compositor-muffin.h> - -#include <clutter/clutter.h> #include <X11/extensions/Xfixes.h> #include <gmodule.h> -#define META_TYPE_PLUGIN (meta_plugin_get_type ()) -#define META_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_PLUGIN, MetaPlugin)) -#define META_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_PLUGIN, MetaPluginClass)) -#define META_IS_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_PLUGIN)) -#define META_IS_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_PLUGIN)) -#define META_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_PLUGIN, MetaPluginClass)) +#include "clutter/clutter.h" +#include "meta/compositor-mutter.h" +#include "meta/compositor.h" +#include "meta/meta-close-dialog.h" +#include "meta/meta-inhibit-shortcuts-dialog.h" +#include "meta/meta-version.h" +#include "meta/types.h" -/** - * MetaPlugin: (skip) - * - */ -typedef struct _MetaPlugin MetaPlugin; -/** - * MetaPluginClass: (skip) - * - */ -typedef struct _MetaPluginClass MetaPluginClass; -typedef struct _MetaPluginVersion MetaPluginVersion; -typedef struct _MetaPluginInfo MetaPluginInfo; -typedef struct _MetaPluginPrivate MetaPluginPrivate; +#define META_TYPE_PLUGIN (meta_plugin_get_type ()) -struct _MetaPlugin -{ - GObject parent; +META_EXPORT +G_DECLARE_DERIVABLE_TYPE (MetaPlugin, meta_plugin, META, PLUGIN, GObject) - MetaPluginPrivate *priv; -}; +typedef struct _MetaPluginVersion MetaPluginVersion; +typedef struct _MetaPluginInfo MetaPluginInfo; +/** + * MetaPluginClass: + * @start: virtual function called when the compositor starts managing a screen + * @minimize: virtual function called when a window is minimized + * @size_change: virtual function called when a window changes size to/from constraints + * @map: virtual function called when a window is mapped + * @destroy: virtual function called when a window is destroyed + * @switch_workspace: virtual function called when the user switches to another + * workspace + * @kill_window_effects: virtual function called when the effects on a window + * need to be killed prematurely; the plugin must call the completed() callback + * as if the effect terminated naturally + * @kill_switch_workspace: virtual function called when the workspace-switching + * effect needs to be killed prematurely + * @xevent_filter: virtual function called when handling each event + * @keybinding_filter: virtual function called when handling each keybinding + * @plugin_info: virtual function that returns information about the + * #MetaPlugin + */ struct _MetaPluginClass { + /*< private >*/ GObjectClass parent_class; + /*< public >*/ + + /** + * MetaPluginClass::start: + * + * Virtual function called when the compositor starts managing a screen + */ void (*start) (MetaPlugin *plugin); + /** + * MetaPluginClass::minimize: + * @actor: a #MetaWindowActor + * + * Virtual function called when the window represented by @actor is minimized. + */ void (*minimize) (MetaPlugin *plugin, MetaWindowActor *actor); - void (*maximize) (MetaPlugin *plugin, - MetaWindowActor *actor, - gint x, - gint y, - gint width, - gint height); + /** + * MetaPluginClass::unminimize: + * @actor: a #MetaWindowActor + * + * Virtual function called when the window represented by @actor is unminimized. + */ + void (*unminimize) (MetaPlugin *plugin, + MetaWindowActor *actor); - void (*unmaximize) (MetaPlugin *plugin, - MetaWindowActor *actor, - gint x, - gint y, - gint width, - gint height); + void (*size_changed) (MetaPlugin *plugin, + MetaWindowActor *actor); - void (*tile) (MetaPlugin *plugin, + void (*size_change) (MetaPlugin *plugin, MetaWindowActor *actor, - gint x, - gint y, - gint width, - gint height); - + MetaSizeChange which_change, + MetaRectangle *old_frame_rect, + MetaRectangle *old_buffer_rect); + + /** + * MetaPluginClass::map: + * @actor: a #MetaWindowActor + * + * Virtual function called when the window represented by @actor is mapped. + */ void (*map) (MetaPlugin *plugin, MetaWindowActor *actor); + /** + * MetaPluginClass::destroy: + * @actor: a #MetaWindowActor + * + * Virtual function called when the window represented by @actor is destroyed. + */ void (*destroy) (MetaPlugin *plugin, MetaWindowActor *actor); + /** + * MetaPluginClass::switch_workspace: + * @from: origin workspace + * @to: destination workspace + * @direction: a #MetaMotionDirection + * + * Virtual function called when the window represented by @actor is destroyed. + */ void (*switch_workspace) (MetaPlugin *plugin, gint from, gint to, MetaMotionDirection direction); - void (*show_tile_preview) (MetaPlugin *plugin, - MetaWindow *window, - MetaRectangle *tile_rect, - int tile_monitor_number, - guint snap_queued); - - void (*hide_tile_preview) (MetaPlugin *plugin); - - void (*show_hud_preview) (MetaPlugin *plugin, - guint current_proximity_zone, - MetaRectangle *work_area, - guint snap_queued); + void (*show_tile_preview) (MetaPlugin *plugin, + MetaWindow *window, + MetaRectangle *tile_rect, + int tile_monitor_number); + void (*hide_tile_preview) (MetaPlugin *plugin); - void (*hide_hud_preview) (MetaPlugin *plugin); - - /* - * Called if an effects should be killed prematurely; the plugin must - * call the completed() callback as if the effect terminated naturally. + void (*show_window_menu) (MetaPlugin *plugin, + MetaWindow *window, + MetaWindowMenuType menu, + int x, + int y); + + void (*show_window_menu_for_rect) (MetaPlugin *plugin, + MetaWindow *window, + MetaWindowMenuType menu, + MetaRectangle *rect); + + /** + * MetaPluginClass::kill_window_effects: + * @actor: a #MetaWindowActor + * + * Virtual function called when the effects on @actor need to be killed + * prematurely; the plugin must call the completed() callback as if the effect + * terminated naturally. */ void (*kill_window_effects) (MetaPlugin *plugin, MetaWindowActor *actor); - /* General XEvent filter. This is fired *before* meta itself handles - * an event. Return TRUE to block any further processing. + /** + * MetaPluginClass::kill_switch_workspace: + * + * Virtual function called when the workspace-switching effect needs to be + * killed prematurely. + */ + void (*kill_switch_workspace) (MetaPlugin *plugin); + + /** + * MetaPluginClass::xevent_filter: + * @event: (type xlib.XEvent): + * + * Virtual function called when handling each event. + * + * Returns: %TRUE if the plugin handled the event type (i.e., if the return + * value is %FALSE, there will be no subsequent call to the manager + * completed() callback, and the compositor must ensure that any appropriate + * post-effect cleanup is carried out. */ gboolean (*xevent_filter) (MetaPlugin *plugin, XEvent *event); + /** + * MetaPluginClass::keybinding_filter: + * @binding: a #MetaKeyBinding + * + * Virtual function called when handling each keybinding. + * + * Returns: %TRUE if the plugin handled the keybinding. + */ + gboolean (*keybinding_filter) (MetaPlugin *plugin, + MetaKeyBinding *binding); + + /** + * MetaPluginClass::confirm_display_config: + * @plugin: a #MetaPlugin + * + * Virtual function called when the display configuration changes. + * The common way to implement this function is to show some form + * of modal dialog that should ask the user if everything was ok. + * + * When confirmed by the user, the plugin must call meta_plugin_complete_display_change() + * to make the configuration permanent. If that function is not + * called within the timeout, the previous configuration will be + * reapplied. + */ + void (*confirm_display_change) (MetaPlugin *plugin); + + /** + * MetaPluginClass::plugin_info: + * @plugin: a #MetaPlugin + * + * Virtual function that returns information about the #MetaPlugin. + * + * Returns: a #MetaPluginInfo. + */ const MetaPluginInfo * (*plugin_info) (MetaPlugin *plugin); + + /** + * MetaPluginClass::create_close_dialog: + * @plugin: a #MetaPlugin + * @window: a #MetaWindow + * + * Virtual function called to create a "force quit" dialog + * on non-responsive clients. + */ + MetaCloseDialog * (* create_close_dialog) (MetaPlugin *plugin, + MetaWindow *window); + + /** + * MetaPluginClass::create_inhibit_shortcuts_dialog: + * @plugin: a #MetaPlugin + * @window: a #MetaWindow + * + * Virtual function called to create a "inhibit shortcuts" dialog + * when a client requests compositor shortcuts to be inhibited. + */ + MetaInhibitShortcutsDialog * (* create_inhibit_shortcuts_dialog) (MetaPlugin *plugin, + MetaWindow *window); + + /** + * MetaPluginClass::locate_pointer: + * + * Virtual function called when the user triggered the "locate-pointer" + * mechanism. + * The common way to implement this function is to show some animation + * on screen to draw user attention on the pointer location. + */ + void (*locate_pointer) (MetaPlugin *plugin); }; +/** + * MetaPluginInfo: + * @name: name of the plugin + * @version: version of the plugin + * @author: author of the plugin + * @license: license of the plugin + * @description: description of the plugin + */ struct _MetaPluginInfo { const gchar *name; @@ -141,13 +268,16 @@ struct _MetaPluginInfo const gchar *description; }; -GType meta_plugin_get_type (void); - -gboolean meta_plugin_running (MetaPlugin *plugin); -gboolean meta_plugin_debug_mode (MetaPlugin *plugin); - +META_EXPORT const MetaPluginInfo * meta_plugin_get_info (MetaPlugin *plugin); +/** + * MetaPluginVersion: + * @version_major: major component of the version number of Meta with which the plugin was compiled + * @version_minor: minor component of the version number of Meta with which the plugin was compiled + * @version_micro: micro component of the version number of Meta with which the plugin was compiled + * @version_api: version of the plugin API + */ struct _MetaPluginVersion { /* @@ -170,101 +300,74 @@ struct _MetaPluginVersion /* * Convenience macro to set up the plugin type. Based on GEdit. */ -#define META_PLUGIN_DECLARE(ObjectName, object_name) \ +#define META_PLUGIN_DECLARE_WITH_CODE(ObjectName, object_name, CODE) \ G_MODULE_EXPORT MetaPluginVersion meta_plugin_version = \ { \ - MUFFIN_MAJOR_VERSION, \ - MUFFIN_MINOR_VERSION, \ - MUFFIN_MICRO_VERSION, \ - MUFFIN_PLUGIN_API_VERSION \ + META_MAJOR_VERSION, \ + META_MINOR_VERSION, \ + META_MICRO_VERSION, \ + META_PLUGIN_API_VERSION \ }; \ \ - static GType g_define_type_id = 0; \ - \ /* Prototypes */ \ - G_MODULE_EXPORT \ - GType object_name##_get_type (void); \ - \ - G_MODULE_EXPORT \ - GType object_name##_register_type (GTypeModule *type_module); \ - \ - G_MODULE_EXPORT \ - GType meta_plugin_register_type (GTypeModule *type_module); \ - \ - GType \ - object_name##_get_type () \ - { \ - return g_define_type_id; \ - } \ - \ - static void object_name##_init (ObjectName *self); \ - static void object_name##_class_init (ObjectName##Class *klass); \ - static gpointer object_name##_parent_class = NULL; \ - static void object_name##_class_intern_init (gpointer klass) \ - { \ - object_name##_parent_class = g_type_class_peek_parent (klass); \ - object_name##_class_init ((ObjectName##Class *) klass); \ - } \ + G_MODULE_EXPORT GType \ + object_name##_get_type (void); \ \ - GType \ - object_name##_register_type (GTypeModule *type_module) \ - { \ - static const GTypeInfo our_info = \ - { \ - sizeof (ObjectName##Class), \ - NULL, /* base_init */ \ - NULL, /* base_finalize */ \ - (GClassInitFunc) object_name##_class_intern_init, \ - NULL, \ - NULL, /* class_data */ \ - sizeof (ObjectName), \ - 0, /* n_preallocs */ \ - (GInstanceInitFunc) object_name##_init \ - }; \ + G_MODULE_EXPORT GType \ + meta_plugin_register_type (GTypeModule *type_module); \ \ - g_define_type_id = g_type_module_register_type (type_module, \ - META_TYPE_PLUGIN, \ - #ObjectName, \ - &our_info, \ - 0); \ \ + G_DEFINE_DYNAMIC_TYPE_EXTENDED(ObjectName, object_name, \ + META_TYPE_PLUGIN, 0, CODE) \ \ - return g_define_type_id; \ - } \ + /* Unused, but required by G_DEFINE_DYNAMIC_TYPE */ \ + static void \ + object_name##_class_finalize (ObjectName##Class *klass) {} \ \ G_MODULE_EXPORT GType \ meta_plugin_register_type (GTypeModule *type_module) \ { \ - return object_name##_register_type (type_module); \ + object_name##_register_type (type_module); \ + return object_name##_get_type (); \ } \ +#define META_PLUGIN_DECLARE(ObjectName, object_name) \ + META_PLUGIN_DECLARE_WITH_CODE(ObjectName, object_name, {}) + +META_EXPORT void meta_plugin_switch_workspace_completed (MetaPlugin *plugin); +META_EXPORT void meta_plugin_minimize_completed (MetaPlugin *plugin, MetaWindowActor *actor); +META_EXPORT void -meta_plugin_maximize_completed (MetaPlugin *plugin, - MetaWindowActor *actor); - -void -meta_plugin_unmaximize_completed (MetaPlugin *plugin, +meta_plugin_unminimize_completed (MetaPlugin *plugin, MetaWindowActor *actor); +META_EXPORT void -meta_plugin_tile_completed (MetaPlugin *plugin, - MetaWindowActor *actor); +meta_plugin_size_change_completed (MetaPlugin *plugin, + MetaWindowActor *actor); +META_EXPORT void meta_plugin_map_completed (MetaPlugin *plugin, MetaWindowActor *actor); +META_EXPORT void meta_plugin_destroy_completed (MetaPlugin *plugin, MetaWindowActor *actor); +META_EXPORT +void +meta_plugin_complete_display_change (MetaPlugin *plugin, + gboolean ok); + /** * MetaModalOptions: * @META_MODAL_POINTER_ALREADY_GRABBED: if set the pointer is already @@ -274,28 +377,30 @@ meta_plugin_destroy_completed (MetaPlugin *plugin, * * Options that can be provided when calling meta_plugin_begin_modal(). */ -typedef enum { +typedef enum +{ META_MODAL_POINTER_ALREADY_GRABBED = 1 << 0, META_MODAL_KEYBOARD_ALREADY_GRABBED = 1 << 1 } MetaModalOptions; +META_EXPORT gboolean meta_plugin_begin_modal (MetaPlugin *plugin, - Window grab_window, - Cursor cursor, MetaModalOptions options, guint32 timestamp); +META_EXPORT void meta_plugin_end_modal (MetaPlugin *plugin, guint32 timestamp); -MetaScreen *meta_plugin_get_screen (MetaPlugin *plugin); +META_EXPORT +MetaDisplay *meta_plugin_get_display (MetaPlugin *plugin); -void -_meta_plugin_effect_started (MetaPlugin *plugin); +void _meta_plugin_set_compositor (MetaPlugin *plugin, MetaCompositor *compositor); -/* Putting this here so it's in the public header */ -void meta_plugin_manager_set_plugin_type (GType gtype); +/* XXX: Putting this in here so it's in the public header. */ +META_EXPORT +void meta_plugin_manager_set_plugin_type (GType gtype); #endif /* META_PLUGIN_H_ */ diff --git a/src/meta/meta-remote-access-controller.h b/src/meta/meta-remote-access-controller.h new file mode 100644 index 000000000..939566a36 --- /dev/null +++ b/src/meta/meta-remote-access-controller.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2018 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#ifndef META_REMOTE_ACCESS_CONTROLLER_H +#define META_REMOTE_ACCESS_CONTROLLER_H + +#include <glib-object.h> + +#include <meta/common.h> + +#define META_TYPE_REMOTE_ACCESS_HANDLE meta_remote_access_handle_get_type () + +META_EXPORT +G_DECLARE_DERIVABLE_TYPE (MetaRemoteAccessHandle, + meta_remote_access_handle, + META, REMOTE_ACCESS_HANDLE, + GObject) + +struct _MetaRemoteAccessHandleClass +{ + GObjectClass parent_class; + + void (*stop) (MetaRemoteAccessHandle *handle); +}; + +META_EXPORT +void meta_remote_access_handle_stop (MetaRemoteAccessHandle *handle); + +META_EXPORT +gboolean meta_remote_access_handle_get_disable_animations (MetaRemoteAccessHandle *handle); + +#define META_TYPE_REMOTE_ACCESS_CONTROLLER meta_remote_access_controller_get_type () + +META_EXPORT +G_DECLARE_FINAL_TYPE (MetaRemoteAccessController, + meta_remote_access_controller, + META, REMOTE_ACCESS_CONTROLLER, + GObject) + +#endif /* META_REMOTE_ACCESS_CONTROLLER_H */ diff --git a/src/meta/meta-selection-source-memory.h b/src/meta/meta-selection-source-memory.h new file mode 100644 index 000000000..b72e12762 --- /dev/null +++ b/src/meta/meta-selection-source-memory.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2018 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef META_MEMORY_SELECTION_SOURCE_H +#define META_MEMORY_SELECTION_SOURCE_H + +#include "meta/meta-selection-source.h" + +#define META_TYPE_SELECTION_SOURCE_MEMORY (meta_selection_source_memory_get_type ()) + +META_EXPORT +G_DECLARE_FINAL_TYPE (MetaSelectionSourceMemory, + meta_selection_source_memory, + META, SELECTION_SOURCE_MEMORY, + MetaSelectionSource) + +META_EXPORT +MetaSelectionSource * meta_selection_source_memory_new (const char *mimetype, + GBytes *content); + +#endif /* META_SELECTION_SOURCE_MEMORY_H */ diff --git a/src/meta/meta-selection-source.h b/src/meta/meta-selection-source.h new file mode 100644 index 000000000..a341bede1 --- /dev/null +++ b/src/meta/meta-selection-source.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2018 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef META_SELECTION_SOURCE_H +#define META_SELECTION_SOURCE_H + +#include <gio/gio.h> + +#include <meta/common.h> + +typedef enum +{ + META_SELECTION_PRIMARY, + META_SELECTION_CLIPBOARD, + META_SELECTION_DND, + META_N_SELECTION_TYPES, +} MetaSelectionType; + +typedef struct _MetaSelectionSourceClass MetaSelectionSourceClass; +typedef struct _MetaSelectionSource MetaSelectionSource; + +#define META_TYPE_SELECTION_SOURCE (meta_selection_source_get_type ()) + +META_EXPORT +G_DECLARE_DERIVABLE_TYPE (MetaSelectionSource, + meta_selection_source, + META, SELECTION_SOURCE, + GObject) + +struct _MetaSelectionSourceClass +{ + GObjectClass parent_class; + + void (* activated) (MetaSelectionSource *source); + void (* deactivated) (MetaSelectionSource *source); + + GList * (* get_mimetypes) (MetaSelectionSource *source); + + void (* read_async) (MetaSelectionSource *source, + const gchar *mimetype, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + GInputStream * (* read_finish) (MetaSelectionSource *source, + GAsyncResult *result, + GError **error); +}; + +META_EXPORT +void meta_selection_source_read_async (MetaSelectionSource *source, + const gchar *mimetype, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +META_EXPORT +GInputStream * meta_selection_source_read_finish (MetaSelectionSource *source, + GAsyncResult *result, + GError **error); + +META_EXPORT +GList * meta_selection_source_get_mimetypes (MetaSelectionSource *source); + +META_EXPORT +gboolean meta_selection_source_is_active (MetaSelectionSource *source); + +#endif /* META_SELECTION_SOURCE_H */ diff --git a/src/meta/meta-selection.h b/src/meta/meta-selection.h new file mode 100644 index 000000000..ef86dce1d --- /dev/null +++ b/src/meta/meta-selection.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2018 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef META_SELECTION_H +#define META_SELECTION_H + +#include <gio/gio.h> + +#include <meta/common.h> +#include <meta/display.h> +#include <meta/meta-selection-source.h> + +#define META_TYPE_SELECTION (meta_selection_get_type ()) + +META_EXPORT +G_DECLARE_FINAL_TYPE (MetaSelection, + meta_selection, + META, SELECTION, + GObject) + +META_EXPORT +MetaSelection * + meta_selection_new (MetaDisplay *display); + +META_EXPORT +void meta_selection_set_owner (MetaSelection *selection, + MetaSelectionType selection_type, + MetaSelectionSource *owner); +META_EXPORT +void meta_selection_unset_owner (MetaSelection *selection, + MetaSelectionType selection_type, + MetaSelectionSource *owner); + +META_EXPORT +GList * meta_selection_get_mimetypes (MetaSelection *selection, + MetaSelectionType selection_type); + +META_EXPORT +void meta_selection_transfer_async (MetaSelection *selection, + MetaSelectionType selection_type, + const gchar *mimetype, + gssize size, + GOutputStream *output, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +META_EXPORT +gboolean meta_selection_transfer_finish (MetaSelection *selection, + GAsyncResult *result, + GError **error); + +#endif /* META_SELECTION_H */ diff --git a/src/meta/meta-settings.h b/src/meta/meta-settings.h new file mode 100644 index 000000000..5683d7c1d --- /dev/null +++ b/src/meta/meta-settings.h @@ -0,0 +1,34 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_SETTINGS_H +#define META_SETTINGS_H + +#include <meta/common.h> +#include <meta/types.h> + +META_EXPORT +int meta_settings_get_ui_scaling_factor (MetaSettings *settings); + +META_EXPORT +int meta_settings_get_font_dpi (MetaSettings *settings); + +#endif /* META_SETTINGS_H */ diff --git a/src/meta/meta-shadow-factory.h b/src/meta/meta-shadow-factory.h index b98aaf009..a3aa0847c 100644 --- a/src/meta/meta-shadow-factory.h +++ b/src/meta/meta-shadow-factory.h @@ -17,20 +17,23 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef __META_SHADOW_FACTORY_H__ #define __META_SHADOW_FACTORY_H__ -#include <glib-object.h> +#include <cairo.h> + +#include "clutter/clutter.h" +#include "cogl/cogl.h" +#include "meta/meta-window-shape.h" + +META_EXPORT +GType meta_shadow_get_type (void) G_GNUC_CONST; /** * MetaShadowParams: - * The #MetaShadowParams structure holds information about how to draw - * a particular style of shadow. * @radius: the radius (gaussian standard deviation) of the shadow * @top_fade: if >= 0, the shadow doesn't extend above the top * of the shape, and fades out over the given number of pixels @@ -39,6 +42,9 @@ * @y_offset: vertical offset of the shadow with respect to the * shape being shadowed, in pixels * @opacity: opacity of the shadow, from 0 to 255 + * + * The #MetaShadowParams structure holds information about how to draw + * a particular style of shadow. */ typedef struct _MetaShadowParams MetaShadowParams; @@ -52,35 +58,78 @@ struct _MetaShadowParams guint8 opacity; }; -#define META_TYPE_SHADOW_FACTORY (meta_shadow_factory_get_type ()) -#define META_SHADOW_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_SHADOW_FACTORY, MetaShadowFactory)) -#define META_SHADOW_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_SHADOW_FACTORY, MetaShadowFactoryClass)) -#define META_IS_SHADOW_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_SHADOW_FACTORY)) -#define META_IS_SHADOW_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_SHADOW_FACTORY)) -#define META_SHADOW_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_SHADOW_FACTORY, MetaShadowFactoryClass)) +#define META_TYPE_SHADOW_FACTORY (meta_shadow_factory_get_type ()) + +META_EXPORT +G_DECLARE_FINAL_TYPE (MetaShadowFactory, + meta_shadow_factory, + META, SHADOW_FACTORY, + GObject) /** * MetaShadowFactory: + * * #MetaShadowFactory is used to create window shadows. It caches shadows internally * so that multiple shadows created for the same shape with the same radius will * share the same MetaShadow. */ -typedef struct _MetaShadowFactory MetaShadowFactory; -typedef struct _MetaShadowFactoryClass MetaShadowFactoryClass; - +META_EXPORT MetaShadowFactory *meta_shadow_factory_get_default (void); -GType meta_shadow_factory_get_type (void); - +META_EXPORT void meta_shadow_factory_set_params (MetaShadowFactory *factory, const char *class_name, gboolean focused, MetaShadowParams *params); + +META_EXPORT void meta_shadow_factory_get_params (MetaShadowFactory *factory, const char *class_name, gboolean focused, MetaShadowParams *params); -void meta_compositor_on_shadow_factory_changed (void); +/** + * MetaShadow: + * #MetaShadow holds a shadow texture along with information about how to + * apply that texture to draw a window texture. (E.g., it knows how big the + * unscaled borders are on each side of the shadow texture.) + */ +typedef struct _MetaShadow MetaShadow; + +META_EXPORT +MetaShadow *meta_shadow_ref (MetaShadow *shadow); + +META_EXPORT +void meta_shadow_unref (MetaShadow *shadow); + +META_EXPORT +void meta_shadow_paint (MetaShadow *shadow, + CoglFramebuffer *framebuffer, + int window_x, + int window_y, + int window_width, + int window_height, + guint8 opacity, + cairo_region_t *clip, + gboolean clip_strictly); + +META_EXPORT +void meta_shadow_get_bounds (MetaShadow *shadow, + int window_x, + int window_y, + int window_width, + int window_height, + cairo_rectangle_int_t *bounds); + +META_EXPORT +MetaShadowFactory *meta_shadow_factory_new (void); + +META_EXPORT +MetaShadow *meta_shadow_factory_get_shadow (MetaShadowFactory *factory, + MetaWindowShape *shape, + int width, + int height, + const char *class_name, + gboolean focused); #endif /* __META_SHADOW_FACTORY_H__ */ diff --git a/src/meta/meta-shaped-texture.h b/src/meta/meta-shaped-texture.h index f85131635..e0a8207ab 100644 --- a/src/meta/meta-shaped-texture.h +++ b/src/meta/meta-shaped-texture.h @@ -18,75 +18,47 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef __META_SHAPED_TEXTURE_H__ #define __META_SHAPED_TEXTURE_H__ -#include <clutter/clutter.h> #include <X11/Xlib.h> -G_BEGIN_DECLS - -#define META_TYPE_SHAPED_TEXTURE (meta_shaped_texture_get_type()) -#define META_SHAPED_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),META_TYPE_SHAPED_TEXTURE, MetaShapedTexture)) -#define META_SHAPED_TEXTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_SHAPED_TEXTURE, MetaShapedTextureClass)) -#define META_IS_SHAPED_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_SHAPED_TEXTURE)) -#define META_IS_SHAPED_TEXTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_SHAPED_TEXTURE)) -#define META_SHAPED_TEXTURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_SHAPED_TEXTURE, MetaShapedTextureClass)) +#include "clutter/clutter.h" +#include <meta/common.h> -typedef struct _MetaShapedTexture MetaShapedTexture; -typedef struct _MetaShapedTextureClass MetaShapedTextureClass; -typedef struct _MetaShapedTexturePrivate MetaShapedTexturePrivate; - -struct _MetaShapedTextureClass -{ - ClutterActorClass parent_class; -}; +G_BEGIN_DECLS -struct _MetaShapedTexture -{ - ClutterActor parent; +#define META_TYPE_SHAPED_TEXTURE (meta_shaped_texture_get_type ()) - MetaShapedTexturePrivate *priv; -}; +META_EXPORT +G_DECLARE_FINAL_TYPE (MetaShapedTexture, + meta_shaped_texture, + META, SHAPED_TEXTURE, + GObject) -GType meta_shaped_texture_get_type (void) G_GNUC_CONST; +META_EXPORT void meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex, gboolean create_mipmaps); -gboolean meta_shaped_texture_update_area (MetaShapedTexture *stex, - int x, - int y, - int width, - int height, - cairo_region_t *unobscured_region); +META_EXPORT +CoglTexture * meta_shaped_texture_get_texture (MetaShapedTexture *stex); -CoglTexture *meta_shaped_texture_get_texture (MetaShapedTexture *stex); - -void meta_shaped_texture_set_overlay_path (MetaShapedTexture *stex, - cairo_region_t *overlay_region, - cairo_path_t *overlay_path); - -void meta_shaped_texture_set_clip_region (MetaShapedTexture *stex, - cairo_region_t *clip_region); +META_EXPORT +void meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex, + CoglTexture *mask_texture); +META_EXPORT void meta_shaped_texture_set_opaque_region (MetaShapedTexture *stex, cairo_region_t *opaque_region); +META_EXPORT cairo_surface_t * meta_shaped_texture_get_image (MetaShapedTexture *stex, cairo_rectangle_int_t *clip); -void meta_shaped_texture_ensure_mask (MetaShapedTexture *stex, - cairo_region_t *shape_region, - gboolean has_frame); - -void meta_shaped_texture_dirty_mask (MetaShapedTexture *stex); - G_END_DECLS #endif /* __META_SHAPED_TEXTURE_H__ */ diff --git a/src/meta/meta-sound-player.h b/src/meta/meta-sound-player.h new file mode 100644 index 000000000..4183689cd --- /dev/null +++ b/src/meta/meta-sound-player.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2018 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ +#ifndef META_SOUND_PLAYER_H +#define META_SOUND_PLAYER_H + +#include <gio/gio.h> + +#include <meta/common.h> + +#define META_TYPE_SOUND_PLAYER (meta_sound_player_get_type ()) + +META_EXPORT +G_DECLARE_FINAL_TYPE (MetaSoundPlayer, meta_sound_player, + META, SOUND_PLAYER, GObject) + +META_EXPORT +void meta_sound_player_play_from_theme (MetaSoundPlayer *player, + const char *name, + const char *description, + GCancellable *cancellable); + +META_EXPORT +void meta_sound_player_play_from_file (MetaSoundPlayer *player, + GFile *file, + const char *description, + GCancellable *cancellable); + +#endif /* META_SOUND_PLAYER_H */ diff --git a/src/compositor/meta-texture-rectangle.h b/src/meta/meta-stage.h similarity index 59% rename from src/compositor/meta-texture-rectangle.h rename to src/meta/meta-stage.h index 56480f2da..afab102e5 100644 --- a/src/compositor/meta-texture-rectangle.h +++ b/src/meta/meta-stage.h @@ -1,11 +1,5 @@ /* - * texture rectangle - * - * A small utility function to help create a rectangle texture - * - * Authored By Neil Roberts <neil@linux.intel.com> - * - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2012 Intel Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -19,20 +13,22 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. */ -#ifndef __META_TEXTURE_RECTANGLE_H__ -#define __META_TEXTURE_RECTANGLE_H__ +#ifndef META_STAGE_H +#define META_STAGE_H -#include <cogl/cogl.h> +#include "clutter/clutter.h" G_BEGIN_DECLS -gboolean -meta_texture_rectangle_check (CoglTexture *texture); +#define META_TYPE_STAGE (meta_stage_get_type ()) + +META_EXPORT +G_DECLARE_FINAL_TYPE (MetaStage, meta_stage, META, STAGE, ClutterStage) G_END_DECLS -#endif /* __META_TEXTURE_RECTANGLE_H__ */ +#endif /* META_STAGE_H */ diff --git a/src/meta/meta-startup-notification.h b/src/meta/meta-startup-notification.h new file mode 100644 index 000000000..11afb3e05 --- /dev/null +++ b/src/meta/meta-startup-notification.h @@ -0,0 +1,76 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * Copyright (C) 2018 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef META_STARTUP_NOTIFICATION_H +#define META_STARTUP_NOTIFICATION_H + +#include <meta/meta-launch-context.h> + +#define META_TYPE_STARTUP_SEQUENCE (meta_startup_sequence_get_type ()) +#define META_TYPE_STARTUP_NOTIFICATION (meta_startup_notification_get_type ()) + +META_EXPORT +G_DECLARE_FINAL_TYPE (MetaStartupNotification, + meta_startup_notification, + META, STARTUP_NOTIFICATION, + GObject) + +META_EXPORT +G_DECLARE_DERIVABLE_TYPE (MetaStartupSequence, + meta_startup_sequence, + META, STARTUP_SEQUENCE, + GObject) + +/** + * meta_startup_notification_get_sequences: (skip) + */ +META_EXPORT +GSList * meta_startup_notification_get_sequences (MetaStartupNotification *sn); + +META_EXPORT +MetaLaunchContext * + meta_startup_notification_create_launcher (MetaStartupNotification *sn); + +META_EXPORT +const char * meta_startup_sequence_get_id (MetaStartupSequence *sequence); + +META_EXPORT +gboolean meta_startup_sequence_get_completed (MetaStartupSequence *sequence); + +META_EXPORT +const char * meta_startup_sequence_get_name (MetaStartupSequence *sequence); + +META_EXPORT +int meta_startup_sequence_get_workspace (MetaStartupSequence *sequence); + +META_EXPORT +uint64_t meta_startup_sequence_get_timestamp (MetaStartupSequence *sequence); + +META_EXPORT +const char * meta_startup_sequence_get_icon_name (MetaStartupSequence *sequence); + +META_EXPORT +const char * meta_startup_sequence_get_application_id (MetaStartupSequence *sequence); + +META_EXPORT +const char * meta_startup_sequence_get_wmclass (MetaStartupSequence *sequence); + +META_EXPORT +void meta_startup_sequence_complete (MetaStartupSequence *sequence); + +#endif /* META_STARTUP_NOTIFICATION_H */ diff --git a/src/meta/meta-version.h.in b/src/meta/meta-version.h.in new file mode 100644 index 000000000..bf977cf41 --- /dev/null +++ b/src/meta/meta-version.h.in @@ -0,0 +1,28 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Rico Tzschichholz + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef META_VERSION_H +#define META_VERSION_H + +#define META_MAJOR_VERSION @MUTTER_MAJOR_VERSION@ +#define META_MINOR_VERSION @MUTTER_MINOR_VERSION@ +#define META_MICRO_VERSION @MUTTER_MICRO_VERSION@ +#define META_PLUGIN_API_VERSION @MUTTER_PLUGIN_API_VERSION@ + +#endif diff --git a/src/meta/meta-window-actor.h b/src/meta/meta-window-actor.h index 2969dbe57..7d3b96e59 100644 --- a/src/meta/meta-window-actor.h +++ b/src/meta/meta-window-actor.h @@ -17,53 +17,45 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_WINDOW_ACTOR_H_ #define META_WINDOW_ACTOR_H_ -#include <clutter/clutter.h> -#include <X11/Xlib.h> +#include "clutter/clutter.h" +#include "meta/compositor.h" +#include "meta/meta-shaped-texture.h" -#include <meta/compositor.h> +#define META_TYPE_WINDOW_ACTOR (meta_window_actor_get_type ()) -/* - * MetaWindowActor object (ClutterGroup sub-class) - */ -#define META_TYPE_WINDOW_ACTOR (meta_window_actor_get_type ()) -#define META_WINDOW_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_WINDOW_ACTOR, MetaWindowActor)) -#define META_WINDOW_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_WINDOW_ACTOR, MetaWindowActorClass)) -#define META_IS_WINDOW_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_WINDOW_ACTOR)) -#define META_IS_WINDOW_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_WINDOW_ACTOR)) -#define META_WINDOW_ACTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_WINDOW_ACTOR, MetaWindowActorClass)) +META_EXPORT +G_DECLARE_DERIVABLE_TYPE (MetaWindowActor, + meta_window_actor, + META, WINDOW_ACTOR, + ClutterActor) -typedef struct _MetaWindowActor MetaWindowActor; -typedef struct _MetaWindowActorClass MetaWindowActorClass; -typedef struct _MetaWindowActorPrivate MetaWindowActorPrivate; +META_EXPORT +MetaWindow * meta_window_actor_get_meta_window (MetaWindowActor *self); -struct _MetaWindowActorClass -{ - ClutterActorClass parent_class; -}; +META_EXPORT +MetaShapedTexture *meta_window_actor_get_texture (MetaWindowActor *self); -struct _MetaWindowActor -{ - ClutterActor parent; +META_EXPORT +void meta_window_actor_sync_visibility (MetaWindowActor *self); - MetaWindowActorPrivate *priv; -}; +META_EXPORT +gboolean meta_window_actor_is_destroyed (MetaWindowActor *self); -GType meta_window_actor_get_type (void); +META_EXPORT +cairo_surface_t * meta_window_actor_get_image (MetaWindowActor *self, + cairo_rectangle_int_t *clip); -Window meta_window_actor_get_x_window (MetaWindowActor *self); -gint meta_window_actor_get_workspace (MetaWindowActor *self); -MetaWindow * meta_window_actor_get_meta_window (MetaWindowActor *self); -ClutterActor * meta_window_actor_get_texture (MetaWindowActor *self); -gboolean meta_window_actor_is_override_redirect (MetaWindowActor *self); -gboolean meta_window_actor_showing_on_its_workspace (MetaWindowActor *self); -gboolean meta_window_actor_is_destroyed (MetaWindowActor *self); +typedef enum +{ + META_SHADOW_MODE_AUTO, + META_SHADOW_MODE_FORCED_OFF, + META_SHADOW_MODE_FORCED_ON, +} MetaShadowMode; #endif /* META_WINDOW_ACTOR_H */ diff --git a/src/meta/meta-window-group.h b/src/meta/meta-window-group.h new file mode 100644 index 000000000..cfc487e7c --- /dev/null +++ b/src/meta/meta-window-group.h @@ -0,0 +1,16 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +#ifndef META_WINDOW_GROUP_H +#define META_WINDOW_GROUP_H + +#include "clutter/clutter.h" + +#define META_TYPE_WINDOW_GROUP (meta_window_group_get_type()) + +META_EXPORT +G_DECLARE_FINAL_TYPE (MetaWindowGroup, + meta_window_group, + META, WINDOW_GROUP, + ClutterActor) + +#endif /* META_WINDOW_GROUP_H */ diff --git a/src/compositor/meta-window-shape.h b/src/meta/meta-window-shape.h similarity index 89% rename from src/compositor/meta-window-shape.h rename to src/meta/meta-window-shape.h index 30d99b44e..ec9fa7da1 100644 --- a/src/compositor/meta-window-shape.h +++ b/src/meta/meta-window-shape.h @@ -17,16 +17,19 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef __META_WINDOW_SHAPE_H__ #define __META_WINDOW_SHAPE_H__ #include <cairo.h> -#include <glib.h> +#include <glib-object.h> + +#include <meta/common.h> + +META_EXPORT +GType meta_window_shape_get_type (void) G_GNUC_CONST; /** * MetaWindowShape: @@ -41,17 +44,30 @@ */ typedef struct _MetaWindowShape MetaWindowShape; +META_EXPORT MetaWindowShape * meta_window_shape_new (cairo_region_t *region); + +META_EXPORT MetaWindowShape * meta_window_shape_ref (MetaWindowShape *shape); + +META_EXPORT void meta_window_shape_unref (MetaWindowShape *shape); + +META_EXPORT guint meta_window_shape_hash (MetaWindowShape *shape); + +META_EXPORT gboolean meta_window_shape_equal (MetaWindowShape *shape_a, MetaWindowShape *shape_b); + +META_EXPORT void meta_window_shape_get_borders (MetaWindowShape *shape, int *border_top, int *border_right, int *border_bottom, int *border_left); + +META_EXPORT cairo_region_t *meta_window_shape_to_region (MetaWindowShape *shape, int center_width, int center_height); diff --git a/src/meta/meta-workspace-manager.h b/src/meta/meta-workspace-manager.h new file mode 100644 index 000000000..92cd68191 --- /dev/null +++ b/src/meta/meta-workspace-manager.h @@ -0,0 +1,78 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001 Havoc Pennington + * Copyright (C) 2002, 2003, 2004 Red Hat, Inc. + * Copyright (C) 2003, 2004 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef META_WORKSPACE_MANAGER_H +#define META_WORKSPACE_MANAGER_H + +#include <glib-object.h> + +#include <meta/common.h> +#include <meta/display.h> +#include <meta/prefs.h> +#include <meta/types.h> + +#define META_TYPE_WORKSPACE_MANAGER (meta_workspace_manager_get_type ()) + +META_EXPORT +G_DECLARE_FINAL_TYPE (MetaWorkspaceManager, + meta_workspace_manager, + META, WORKSPACE_MANAGER, + GObject) + +META_EXPORT +GList *meta_workspace_manager_get_workspaces (MetaWorkspaceManager *workspace_manager); + +META_EXPORT +int meta_workspace_manager_get_n_workspaces (MetaWorkspaceManager *workspace_manager); + +META_EXPORT +MetaWorkspace* meta_workspace_manager_get_workspace_by_index (MetaWorkspaceManager *workspace_manager, + int index); + +META_EXPORT +void meta_workspace_manager_remove_workspace (MetaWorkspaceManager *workspace_manager, + MetaWorkspace *workspace, + guint32 timestamp); + +META_EXPORT +MetaWorkspace *meta_workspace_manager_append_new_workspace (MetaWorkspaceManager *workspace_manager, + gboolean activate, + guint32 timestamp); + +META_EXPORT +void meta_workspace_manager_reorder_workspace (MetaWorkspaceManager *workspace_manager, + MetaWorkspace *workspace, + int new_index); + +META_EXPORT +int meta_workspace_manager_get_active_workspace_index (MetaWorkspaceManager *workspace_manager); + +META_EXPORT +MetaWorkspace *meta_workspace_manager_get_active_workspace (MetaWorkspaceManager *workspace_manager); + +META_EXPORT +void meta_workspace_manager_override_workspace_layout (MetaWorkspaceManager *workspace_manager, + MetaDisplayCorner starting_corner, + gboolean vertical_layout, + int n_rows, + int n_columns); +#endif /* META_WORKSPACE_MANAGER_H */ diff --git a/src/meta/meta-x11-display.h b/src/meta/meta-x11-display.h new file mode 100644 index 000000000..eb84c2b20 --- /dev/null +++ b/src/meta/meta-x11-display.h @@ -0,0 +1,73 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2008 Iain Holmes + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef META_X11_DISPLAY_H +#define META_X11_DISPLAY_H + +#include <glib-object.h> +#include <X11/Xlib.h> + +#include <meta/common.h> +#include <meta/prefs.h> +#include <meta/types.h> + +#define META_TYPE_X11_DISPLAY (meta_x11_display_get_type ()) + +META_EXPORT +G_DECLARE_FINAL_TYPE (MetaX11Display, meta_x11_display, META, X11_DISPLAY, GObject) + +META_EXPORT +gboolean meta_x11_init_gdk_display (GError **error); + +META_EXPORT +int meta_x11_display_get_screen_number (MetaX11Display *x11_display); + +META_EXPORT +Display *meta_x11_display_get_xdisplay (MetaX11Display *x11_display); + +META_EXPORT +Window meta_x11_display_get_xroot (MetaX11Display *x11_display); + +META_EXPORT +int meta_x11_display_get_xinput_opcode (MetaX11Display *x11_display); + +META_EXPORT +int meta_x11_display_get_damage_event_base (MetaX11Display *x11_display); + +META_EXPORT +int meta_x11_display_get_shape_event_base (MetaX11Display *x11_display); + +META_EXPORT +gboolean meta_x11_display_has_shape (MetaX11Display *x11_display); + +META_EXPORT +void meta_x11_display_set_cm_selection (MetaX11Display *x11_display); + +META_EXPORT +gboolean meta_x11_display_xwindow_is_a_no_focus_window (MetaX11Display *x11_display, + Window xwindow); + +META_EXPORT +void meta_x11_display_set_stage_input_region (MetaX11Display *x11_display, + XserverRegion region); + +META_EXPORT +void meta_x11_display_clear_stage_input_region (MetaX11Display *x11_display); + +#endif /* META_X11_DISPLAY_H */ diff --git a/src/meta/errors.h b/src/meta/meta-x11-errors.h similarity index 64% rename from src/meta/errors.h rename to src/meta/meta-x11-errors.h index 2a37a7da8..ec9fa5c71 100644 --- a/src/meta/errors.h +++ b/src/meta/meta-x11-errors.h @@ -1,10 +1,10 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* Muffin X error handling */ +/* Mutter X error handling */ -/* +/* * Copyright (C) 2001 Havoc Pennington - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the @@ -14,11 +14,9 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_ERRORS_H @@ -27,14 +25,17 @@ #include <X11/Xlib.h> #include <meta/util.h> -#include <meta/display.h> +#include <meta/meta-x11-display.h> + +META_EXPORT +void meta_x11_error_trap_push (MetaX11Display *x11_display); -void meta_error_trap_push (MetaDisplay *display); -void meta_error_trap_pop (MetaDisplay *display); +META_EXPORT +void meta_x11_error_trap_pop (MetaX11Display *x11_display); -void meta_error_trap_push_with_return (MetaDisplay *display); /* returns X error code, or 0 for no error */ -int meta_error_trap_pop_with_return (MetaDisplay *display); +META_EXPORT +int meta_x11_error_trap_pop_with_return (MetaX11Display *x11_display); #endif diff --git a/src/meta/prefs.h b/src/meta/prefs.h index f4b28aa46..049e246a0 100644 --- a/src/meta/prefs.h +++ b/src/meta/prefs.h @@ -1,11 +1,11 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* Muffin preferences */ +/* Mutter preferences */ -/* +/* * Copyright (C) 2001 Havoc Pennington * Copyright (C) 2006 Elijah Newren - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the @@ -15,11 +15,9 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_PREFS_H @@ -30,7 +28,45 @@ #include <meta/types.h> #include <pango/pango-font.h> #include <libcinnamon-desktop/cdesktop-enums.h> -#include <X11/XKBlib.h> +#include <gio/gio.h> + +/** + * MetaPreference: + * @META_PREF_MOUSE_BUTTON_MODS: mouse button modifiers + * @META_PREF_FOCUS_MODE: focus mode + * @META_PREF_FOCUS_NEW_WINDOWS: focus new windows + * @META_PREF_ATTACH_MODAL_DIALOGS: attach modal dialogs + * @META_PREF_RAISE_ON_CLICK: raise on click + * @META_PREF_ACTION_DOUBLE_CLICK_TITLEBAR: action double click titlebar + * @META_PREF_ACTION_MIDDLE_CLICK_TITLEBAR: action middle click titlebar + * @META_PREF_ACTION_RIGHT_CLICK_TITLEBAR: action right click titlebar + * @META_PREF_AUTO_RAISE: auto-raise + * @META_PREF_AUTO_RAISE_DELAY: auto-raise delay + * @META_PREF_FOCUS_CHANGE_ON_POINTER_REST: focus change on pointer rest + * @META_PREF_TITLEBAR_FONT: title-bar font + * @META_PREF_NUM_WORKSPACES: number of workspaces + * @META_PREF_DYNAMIC_WORKSPACES: dynamic workspaces + * @META_PREF_KEYBINDINGS: keybindings + * @META_PREF_DISABLE_WORKAROUNDS: disable workarounds + * @META_PREF_BUTTON_LAYOUT: button layout + * @META_PREF_WORKSPACE_NAMES: workspace names + * @META_PREF_VISUAL_BELL: visual bell + * @META_PREF_AUDIBLE_BELL: audible bell + * @META_PREF_VISUAL_BELL_TYPE: visual bell type + * @META_PREF_GNOME_ACCESSIBILITY: GNOME accessibility + * @META_PREF_GNOME_ANIMATIONS: GNOME animations + * @META_PREF_CURSOR_THEME: cursor theme + * @META_PREF_CURSOR_SIZE: cursor size + * @META_PREF_RESIZE_WITH_RIGHT_BUTTON: resize with right button + * @META_PREF_EDGE_TILING: edge tiling + * @META_PREF_FORCE_FULLSCREEN: force fullscreen + * @META_PREF_WORKSPACES_ONLY_ON_PRIMARY: workspaces only on primary + * @META_PREF_DRAGGABLE_BORDER_WIDTH: draggable border width + * @META_PREF_AUTO_MAXIMIZE: auto-maximize + * @META_PREF_CENTER_NEW_WINDOWS: center new windows + * @META_PREF_DRAG_THRESHOLD: drag threshold + * @META_PREF_LOCATE_POINTER: show pointer location + */ /* Keep in sync with GSettings schemas! */ typedef enum @@ -39,156 +75,260 @@ typedef enum META_PREF_FOCUS_MODE, META_PREF_FOCUS_NEW_WINDOWS, META_PREF_ATTACH_MODAL_DIALOGS, - META_PREF_IGNORE_HIDE_TITLEBAR_WHEN_MAXIMIZED, META_PREF_RAISE_ON_CLICK, META_PREF_ACTION_DOUBLE_CLICK_TITLEBAR, META_PREF_ACTION_MIDDLE_CLICK_TITLEBAR, META_PREF_ACTION_RIGHT_CLICK_TITLEBAR, - META_PREF_ACTION_SCROLL_WHEEL_TITLEBAR, META_PREF_AUTO_RAISE, META_PREF_AUTO_RAISE_DELAY, - META_PREF_THEME, + META_PREF_FOCUS_CHANGE_ON_POINTER_REST, META_PREF_TITLEBAR_FONT, META_PREF_NUM_WORKSPACES, META_PREF_DYNAMIC_WORKSPACES, - META_PREF_UNREDIRECT_FULLSCREEN_WINDOWS, - META_PREF_DESKTOP_EFFECTS, - META_PREF_SYNC_METHOD, - META_PREF_THREADED_SWAP, - META_PREF_SEND_FRAME_TIMINGS, - META_PREF_APPLICATION_BASED, META_PREF_KEYBINDINGS, META_PREF_DISABLE_WORKAROUNDS, META_PREF_BUTTON_LAYOUT, META_PREF_WORKSPACE_NAMES, - META_PREF_WORKSPACE_CYCLE, META_PREF_VISUAL_BELL, META_PREF_AUDIBLE_BELL, META_PREF_VISUAL_BELL_TYPE, + META_PREF_GNOME_ACCESSIBILITY, META_PREF_GNOME_ANIMATIONS, META_PREF_CURSOR_THEME, META_PREF_CURSOR_SIZE, META_PREF_RESIZE_WITH_RIGHT_BUTTON, META_PREF_EDGE_TILING, META_PREF_FORCE_FULLSCREEN, - META_PREF_EDGE_RESISTANCE_WINDOW, META_PREF_WORKSPACES_ONLY_ON_PRIMARY, META_PREF_DRAGGABLE_BORDER_WIDTH, - META_PREF_TILE_HUD_THRESHOLD, - META_PREF_RESIZE_THRESHOLD, - META_PREF_SNAP_MODIFIER, - META_PREF_LEGACY_SNAP, - META_PREF_INVERT_WORKSPACE_FLIP_DIRECTION, - META_PREF_TILE_MAXIMIZE, - META_PREF_PLACEMENT_MODE, - META_PREF_BACKGROUND_TRANSITION, - META_PREF_MIN_WIN_OPACITY, - META_PREF_MOUSE_ZOOM_ENABLED, - META_PREF_MOUSE_BUTTON_ZOOM_MODS, - META_PREF_UI_SCALE, - META_PREF_BRING_WINDOWS_TO_CURRENT_WORKSPACE, + META_PREF_AUTO_MAXIMIZE, + META_PREF_CENTER_NEW_WINDOWS, + META_PREF_DRAG_THRESHOLD, + META_PREF_LOCATE_POINTER, + META_PREF_CHECK_ALIVE_TIMEOUT, } MetaPreference; typedef void (* MetaPrefsChangedFunc) (MetaPreference pref, - gpointer data); + gpointer user_data); +META_EXPORT void meta_prefs_add_listener (MetaPrefsChangedFunc func, - gpointer data); + gpointer user_data); + +META_EXPORT void meta_prefs_remove_listener (MetaPrefsChangedFunc func, - gpointer data); + gpointer user_data); +META_EXPORT void meta_prefs_init (void); -void meta_prefs_override_preference_schema (const char *key, - const char *schema); - +META_EXPORT const char* meta_preference_to_string (MetaPreference pref); +META_EXPORT MetaVirtualModifier meta_prefs_get_mouse_button_mods (void); -MetaVirtualModifier meta_prefs_get_mouse_button_zoom_mods (void); -gboolean meta_prefs_get_mouse_zoom_enabled (void); -guint meta_prefs_get_mouse_button_resize (void); -guint meta_prefs_get_mouse_button_menu (void); + +META_EXPORT +gint meta_prefs_get_mouse_button_resize (void); + +META_EXPORT +gint meta_prefs_get_mouse_button_menu (void); + +META_EXPORT CDesktopFocusMode meta_prefs_get_focus_mode (void); + +META_EXPORT CDesktopFocusNewWindows meta_prefs_get_focus_new_windows (void); + +META_EXPORT gboolean meta_prefs_get_attach_modal_dialogs (void); -gboolean meta_prefs_get_ignore_hide_titlebar_when_maximized (void); + +META_EXPORT gboolean meta_prefs_get_raise_on_click (void); -gboolean meta_prefs_get_bring_windows_to_current_workspace (void); -const char* meta_prefs_get_theme (void); + /* returns NULL if GTK default should be used */ +META_EXPORT const PangoFontDescription* meta_prefs_get_titlebar_font (void); + +META_EXPORT int meta_prefs_get_num_workspaces (void); -gboolean meta_prefs_get_workspace_cycle (void); + +META_EXPORT gboolean meta_prefs_get_dynamic_workspaces (void); -gboolean meta_prefs_get_unredirect_fullscreen_windows (void); -MetaSyncMethod meta_prefs_get_sync_method (void); -gboolean meta_prefs_get_threaded_swap (void); -gboolean meta_prefs_get_send_frame_timings (void); -gboolean meta_prefs_get_application_based (void); + +META_EXPORT gboolean meta_prefs_get_disable_workarounds (void); + +META_EXPORT gboolean meta_prefs_get_auto_raise (void); + +META_EXPORT int meta_prefs_get_auto_raise_delay (void); + +META_EXPORT +gboolean meta_prefs_get_focus_change_on_pointer_rest (void); + +META_EXPORT gboolean meta_prefs_get_gnome_accessibility (void); + +META_EXPORT gboolean meta_prefs_get_gnome_animations (void); + +META_EXPORT gboolean meta_prefs_get_edge_tiling (void); -gboolean meta_prefs_get_edge_resistance_window (void); -const char* meta_prefs_get_screenshot_command (void); +META_EXPORT +gboolean meta_prefs_get_auto_maximize (void); -const char* meta_prefs_get_window_screenshot_command (void); +META_EXPORT +gboolean meta_prefs_get_center_new_windows (void); -const char* meta_prefs_get_terminal_command (void); +META_EXPORT +gboolean meta_prefs_get_show_fallback_app_menu (void); -void meta_prefs_get_button_layout (MetaButtonLayout *button_layout_p); +META_EXPORT +void meta_prefs_set_show_fallback_app_menu (gboolean whether); + +META_EXPORT +void meta_prefs_get_button_layout (MetaButtonLayout *button_layout); /* Double, right, middle click can be configured to any titlebar meta-action */ +META_EXPORT CDesktopTitlebarAction meta_prefs_get_action_double_click_titlebar (void); + +META_EXPORT CDesktopTitlebarAction meta_prefs_get_action_middle_click_titlebar (void); + +META_EXPORT CDesktopTitlebarAction meta_prefs_get_action_right_click_titlebar (void); -CDesktopTitlebarScrollAction meta_prefs_get_action_scroll_wheel_titlebar (void); +META_EXPORT void meta_prefs_set_num_workspaces (int n_workspaces); +META_EXPORT const char* meta_prefs_get_workspace_name (int i); + +META_EXPORT void meta_prefs_change_workspace_name (int i, const char *name); +META_EXPORT const char* meta_prefs_get_cursor_theme (void); + +META_EXPORT int meta_prefs_get_cursor_size (void); + +META_EXPORT gboolean meta_prefs_get_compositing_manager (void); -gboolean meta_prefs_get_force_fullscreen (void); -/* - * Sets whether the compositor is turned on. - * - * \param whether TRUE to turn on, FALSE to turn off - */ -void meta_prefs_set_compositing_manager (gboolean whether); +META_EXPORT +gboolean meta_prefs_get_force_fullscreen (void); +META_EXPORT void meta_prefs_set_force_fullscreen (gboolean whether); +META_EXPORT gboolean meta_prefs_get_workspaces_only_on_primary (void); +META_EXPORT int meta_prefs_get_draggable_border_width (void); -int meta_prefs_get_tile_hud_threshold (void); -int meta_prefs_get_resize_threshold (void); - -unsigned int * meta_prefs_get_snap_modifier (void); - -gboolean meta_prefs_get_legacy_snap (void); - -gboolean meta_prefs_get_invert_flip_direction (void); - -gboolean meta_prefs_get_tile_maximize (void); - -gint meta_prefs_get_min_win_opacity (void); - -gint meta_prefs_get_ui_scale (void); - -void meta_prefs_set_ui_scale (int ui_scale); +META_EXPORT +int meta_prefs_get_drag_threshold (void); +/** + * MetaKeyBindingAction: + * @META_KEYBINDING_ACTION_NONE: FILLME + * @META_KEYBINDING_ACTION_WORKSPACE_1: FILLME + * @META_KEYBINDING_ACTION_WORKSPACE_2: FILLME + * @META_KEYBINDING_ACTION_WORKSPACE_3: FILLME + * @META_KEYBINDING_ACTION_WORKSPACE_4: FILLME + * @META_KEYBINDING_ACTION_WORKSPACE_5: FILLME + * @META_KEYBINDING_ACTION_WORKSPACE_6: FILLME + * @META_KEYBINDING_ACTION_WORKSPACE_7: FILLME + * @META_KEYBINDING_ACTION_WORKSPACE_8: FILLME + * @META_KEYBINDING_ACTION_WORKSPACE_9: FILLME + * @META_KEYBINDING_ACTION_WORKSPACE_10: FILLME + * @META_KEYBINDING_ACTION_WORKSPACE_11: FILLME + * @META_KEYBINDING_ACTION_WORKSPACE_12: FILLME + * @META_KEYBINDING_ACTION_WORKSPACE_LEFT: FILLME + * @META_KEYBINDING_ACTION_WORKSPACE_RIGHT: FILLME + * @META_KEYBINDING_ACTION_WORKSPACE_UP: FILLME + * @META_KEYBINDING_ACTION_WORKSPACE_DOWN: FILLME + * @META_KEYBINDING_ACTION_WORKSPACE_LAST: FILLME + * @META_KEYBINDING_ACTION_SWITCH_APPLICATIONS: FILLME + * @META_KEYBINDING_ACTION_SWITCH_APPLICATIONS_BACKWARD: FILLME + * @META_KEYBINDING_ACTION_SWITCH_GROUP: FILLME + * @META_KEYBINDING_ACTION_SWITCH_GROUP_BACKWARD: FILLME + * @META_KEYBINDING_ACTION_SWITCH_WINDOWS: FILLME + * @META_KEYBINDING_ACTION_SWITCH_WINDOWS_BACKWARD: FILLME + * @META_KEYBINDING_ACTION_SWITCH_PANELS: FILLME + * @META_KEYBINDING_ACTION_SWITCH_PANELS_BACKWARD: FILLME + * @META_KEYBINDING_ACTION_CYCLE_GROUP: FILLME + * @META_KEYBINDING_ACTION_CYCLE_GROUP_BACKWARD: FILLME + * @META_KEYBINDING_ACTION_CYCLE_WINDOWS: FILLME + * @META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD: FILLME + * @META_KEYBINDING_ACTION_CYCLE_PANELS: FILLME + * @META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD: FILLME + * @META_KEYBINDING_ACTION_SHOW_DESKTOP: FILLME + * @META_KEYBINDING_ACTION_PANEL_MAIN_MENU: FILLME + * @META_KEYBINDING_ACTION_PANEL_RUN_DIALOG: FILLME + * @META_KEYBINDING_ACTION_TOGGLE_RECORDING: FILLME + * @META_KEYBINDING_ACTION_SET_SPEW_MARK: FILLME + * @META_KEYBINDING_ACTION_ACTIVATE_WINDOW_MENU: FILLME + * @META_KEYBINDING_ACTION_TOGGLE_FULLSCREEN: FILLME + * @META_KEYBINDING_ACTION_TOGGLE_MAXIMIZED: FILLME + * @META_KEYBINDING_ACTION_TOGGLE_TILED_LEFT: FILLME + * @META_KEYBINDING_ACTION_TOGGLE_TILED_RIGHT: FILLME + * @META_KEYBINDING_ACTION_TOGGLE_ABOVE: FILLME + * @META_KEYBINDING_ACTION_MAXIMIZE: FILLME + * @META_KEYBINDING_ACTION_UNMAXIMIZE: FILLME + * @META_KEYBINDING_ACTION_TOGGLE_SHADED: FILLME + * @META_KEYBINDING_ACTION_MINIMIZE: FILLME + * @META_KEYBINDING_ACTION_CLOSE: FILLME + * @META_KEYBINDING_ACTION_BEGIN_MOVE: FILLME + * @META_KEYBINDING_ACTION_BEGIN_RESIZE: FILLME + * @META_KEYBINDING_ACTION_TOGGLE_ON_ALL_WORKSPACES: FILLME + * @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_1: FILLME + * @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_2: FILLME + * @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_3: FILLME + * @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_4: FILLME + * @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_5: FILLME + * @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_6: FILLME + * @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_7: FILLME + * @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_8: FILLME + * @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_9: FILLME + * @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_10: FILLME + * @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_11: FILLME + * @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_12: FILLME + * @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_LEFT: FILLME + * @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_RIGHT: FILLME + * @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_UP: FILLME + * @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_DOWN: FILLME + * @META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_LAST: FILLME + * @META_KEYBINDING_ACTION_MOVE_TO_MONITOR_LEFT: FILLME + * @META_KEYBINDING_ACTION_MOVE_TO_MONITOR_RIGHT: FILLME + * @META_KEYBINDING_ACTION_MOVE_TO_MONITOR_UP: FILLME + * @META_KEYBINDING_ACTION_MOVE_TO_MONITOR_DOWN: FILLME + * @META_KEYBINDING_ACTION_RAISE_OR_LOWER: FILLME + * @META_KEYBINDING_ACTION_RAISE: FILLME + * @META_KEYBINDING_ACTION_LOWER: FILLME + * @META_KEYBINDING_ACTION_MAXIMIZE_VERTICALLY: FILLME + * @META_KEYBINDING_ACTION_MAXIMIZE_HORIZONTALLY: FILLME + * @META_KEYBINDING_ACTION_MOVE_TO_CORNER_NW: FILLME + * @META_KEYBINDING_ACTION_MOVE_TO_CORNER_NE: FILLME + * @META_KEYBINDING_ACTION_MOVE_TO_CORNER_SW: FILLME + * @META_KEYBINDING_ACTION_MOVE_TO_CORNER_SE: FILLME + * @META_KEYBINDING_ACTION_MOVE_TO_SIDE_N: FILLME + * @META_KEYBINDING_ACTION_MOVE_TO_SIDE_S: FILLME + * @META_KEYBINDING_ACTION_MOVE_TO_SIDE_E: FILLME + * @META_KEYBINDING_ACTION_MOVE_TO_SIDE_W: FILLME + * @META_KEYBINDING_ACTION_MOVE_TO_CENTER: FILLME + * @META_KEYBINDING_ACTION_OVERLAY_KEY: FILLME + * @META_KEYBINDING_ACTION_LOCATE_POINTER_KEY: FILLME + * @META_KEYBINDING_ACTION_ALWAYS_ON_TOP: FILLME + * @META_KEYBINDING_ACTION_LAST: FILLME + */ /* XXX FIXME This should be x-macroed, but isn't yet because it would be * difficult (or perhaps impossible) to add the suffixes using the current * system. It needs some more thought, perhaps after the current system @@ -196,8 +336,7 @@ void meta_prefs_set_ui_scale (int ui_scale); */ typedef enum _MetaKeyBindingAction { - META_KEYBINDING_ACTION_NONE = -1, - /* WARNING: Watch keybindings.c 'process_event' if you change these enums */ + META_KEYBINDING_ACTION_NONE, META_KEYBINDING_ACTION_WORKSPACE_1, META_KEYBINDING_ACTION_WORKSPACE_2, META_KEYBINDING_ACTION_WORKSPACE_3, @@ -214,6 +353,9 @@ typedef enum _MetaKeyBindingAction META_KEYBINDING_ACTION_WORKSPACE_RIGHT, META_KEYBINDING_ACTION_WORKSPACE_UP, META_KEYBINDING_ACTION_WORKSPACE_DOWN, + META_KEYBINDING_ACTION_WORKSPACE_LAST, + META_KEYBINDING_ACTION_SWITCH_APPLICATIONS, + META_KEYBINDING_ACTION_SWITCH_APPLICATIONS_BACKWARD, META_KEYBINDING_ACTION_SWITCH_GROUP, META_KEYBINDING_ACTION_SWITCH_GROUP_BACKWARD, META_KEYBINDING_ACTION_SWITCH_WINDOWS, @@ -226,23 +368,16 @@ typedef enum _MetaKeyBindingAction META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD, META_KEYBINDING_ACTION_CYCLE_PANELS, META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD, - META_KEYBINDING_ACTION_TAB_POPUP_SELECT, - META_KEYBINDING_ACTION_TAB_POPUP_CANCEL, META_KEYBINDING_ACTION_SHOW_DESKTOP, + META_KEYBINDING_ACTION_PANEL_MAIN_MENU, META_KEYBINDING_ACTION_PANEL_RUN_DIALOG, META_KEYBINDING_ACTION_TOGGLE_RECORDING, META_KEYBINDING_ACTION_SET_SPEW_MARK, META_KEYBINDING_ACTION_ACTIVATE_WINDOW_MENU, META_KEYBINDING_ACTION_TOGGLE_FULLSCREEN, META_KEYBINDING_ACTION_TOGGLE_MAXIMIZED, - META_KEYBINDING_ACTION_PUSH_TILE_LEFT, - META_KEYBINDING_ACTION_PUSH_TILE_RIGHT, - META_KEYBINDING_ACTION_PUSH_TILE_UP, - META_KEYBINDING_ACTION_PUSH_TILE_DOWN, - META_KEYBINDING_ACTION_PUSH_SNAP_LEFT, - META_KEYBINDING_ACTION_PUSH_SNAP_RIGHT, - META_KEYBINDING_ACTION_PUSH_SNAP_UP, - META_KEYBINDING_ACTION_PUSH_SNAP_DOWN, + META_KEYBINDING_ACTION_TOGGLE_TILED_LEFT, + META_KEYBINDING_ACTION_TOGGLE_TILED_RIGHT, META_KEYBINDING_ACTION_TOGGLE_ABOVE, META_KEYBINDING_ACTION_MAXIMIZE, META_KEYBINDING_ACTION_UNMAXIMIZE, @@ -268,11 +403,11 @@ typedef enum _MetaKeyBindingAction META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_RIGHT, META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_UP, META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_DOWN, - META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_NEW, + META_KEYBINDING_ACTION_MOVE_TO_WORKSPACE_LAST, META_KEYBINDING_ACTION_MOVE_TO_MONITOR_LEFT, META_KEYBINDING_ACTION_MOVE_TO_MONITOR_RIGHT, - META_KEYBINDING_ACTION_MOVE_TO_MONITOR_DOWN, META_KEYBINDING_ACTION_MOVE_TO_MONITOR_UP, + META_KEYBINDING_ACTION_MOVE_TO_MONITOR_DOWN, META_KEYBINDING_ACTION_RAISE_OR_LOWER, META_KEYBINDING_ACTION_RAISE, META_KEYBINDING_ACTION_LOWER, @@ -287,83 +422,67 @@ typedef enum _MetaKeyBindingAction META_KEYBINDING_ACTION_MOVE_TO_SIDE_E, META_KEYBINDING_ACTION_MOVE_TO_SIDE_W, META_KEYBINDING_ACTION_MOVE_TO_CENTER, - META_KEYBINDING_ACTION_INCREASE_OPACITY, - META_KEYBINDING_ACTION_DECREASE_OPACITY, - META_KEYBINDING_ACTION_CUSTOM, + META_KEYBINDING_ACTION_OVERLAY_KEY, + META_KEYBINDING_ACTION_LOCATE_POINTER_KEY, + META_KEYBINDING_ACTION_ISO_NEXT_GROUP, + META_KEYBINDING_ACTION_ALWAYS_ON_TOP, + META_KEYBINDING_ACTION_SWITCH_MONITOR, + META_KEYBINDING_ACTION_ROTATE_MONITOR, META_KEYBINDING_ACTION_LAST } MetaKeyBindingAction; +/** + * MetaKeyBindingFlags: + * @META_KEY_BINDING_NONE: none + * @META_KEY_BINDING_PER_WINDOW: per-window + * @META_KEY_BINDING_BUILTIN: built-in + * @META_KEY_BINDING_IS_REVERSED: is reversed + * @META_KEY_BINDING_NON_MASKABLE: always active + * @META_KEY_BINDING_NO_AUTO_GRAB: not grabbed automatically + */ typedef enum { META_KEY_BINDING_NONE, - META_KEY_BINDING_PER_WINDOW = 1 << 0, - META_KEY_BINDING_BUILTIN = 1 << 1, - META_KEY_BINDING_REVERSES = 1 << 2, - META_KEY_BINDING_IS_REVERSED = 1 << 3 + META_KEY_BINDING_PER_WINDOW = 1 << 0, + META_KEY_BINDING_BUILTIN = 1 << 1, + META_KEY_BINDING_IS_REVERSED = 1 << 2, + META_KEY_BINDING_NON_MASKABLE = 1 << 3, + META_KEY_BINDING_IGNORE_AUTOREPEAT = 1 << 4, + META_KEY_BINDING_NO_AUTO_GRAB = 1 << 5, } MetaKeyBindingFlags; -typedef struct -{ - unsigned int keysym; - unsigned int keycode; - MetaVirtualModifier modifiers; -} MetaKeyCombo; - /** * MetaKeyHandlerFunc: - * @event: (type gpointer): + * @display: a #MetaDisplay + * @window: a #MetaWindow + * @event: (type gpointer): a #ClutterKeyEvent + * @binding: a #MetaKeyBinding + * @user_data: data passed to the function * */ -typedef void (* MetaKeyHandlerFunc) (MetaDisplay *display, - MetaScreen *screen, - MetaWindow *window, - XEvent *event, - MetaKeyBinding *binding, - gpointer user_data); - -typedef struct _MetaKeyHandler MetaKeyHandler; - -typedef struct -{ - char *name; - char *schema; - - MetaKeyBindingAction action; - - /* - * A list of MetaKeyCombos. Each of them is bound to - * this keypref. If one has keysym==modifiers==0, it is - * ignored. - */ - GSList *bindings; - - /* for keybindings that can have shift or not like Alt+Tab */ - gboolean add_shift:1; - - /* for keybindings that apply only to a window */ - gboolean per_window:1; - - /* for keybindings not added with meta_display_add_keybinding() */ - gboolean builtin:1; -} MetaKeyPref; +typedef void (* MetaKeyHandlerFunc) (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer user_data); +META_EXPORT GType meta_key_binding_get_type (void); -GList *meta_prefs_get_keybindings (void); - +META_EXPORT MetaKeyBindingAction meta_prefs_get_keybinding_action (const char *name); -void meta_prefs_get_window_binding (const char *name, - unsigned int *keysym, - MetaVirtualModifier *modifiers); - +META_EXPORT gboolean meta_prefs_get_visual_bell (void); + +META_EXPORT gboolean meta_prefs_bell_is_audible (void); -CDesktopVisualBellType meta_prefs_get_visual_bell_type (void); -MetaPlacementMode meta_prefs_get_placement_mode (void); +META_EXPORT +CDesktopVisualBellType meta_prefs_get_visual_bell_type (void); -MetaBackgroundTransition meta_prefs_get_background_transition (void); +META_EXPORT +unsigned int meta_prefs_get_check_alive_timeout (void); #endif diff --git a/src/meta/preview-widget.h b/src/meta/preview-widget.h deleted file mode 100644 index 4a0110000..000000000 --- a/src/meta/preview-widget.h +++ /dev/null @@ -1,85 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Metacity theme preview widget */ - -/* - * Copyright (C) 2002 Havoc Pennington - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. - */ - -#include <config.h> - -#include <meta/common.h> -#include <meta/theme.h> -#include <gtk/gtk.h> - -#ifndef META_PREVIEW_WIDGET_H -#define META_PREVIEW_WIDGET_H - -#define META_TYPE_PREVIEW (meta_preview_get_type ()) -#define META_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_PREVIEW, MetaPreview)) -#define META_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_PREVIEW, MetaPreviewClass)) -#define META_IS_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_PREVIEW)) -#define META_IS_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_PREVIEW)) -#define META_PREVIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_PREVIEW, MetaPreviewClass)) - -typedef struct _MetaPreview MetaPreview; -typedef struct _MetaPreviewClass MetaPreviewClass; - -struct _MetaPreview -{ - GtkBin bin; - - MetaTheme *theme; - char *title; - MetaFrameType type; - MetaFrameFlags flags; - - PangoLayout *layout; - int text_height; - - MetaFrameBorders borders; - guint borders_cached : 1; - - MetaButtonLayout button_layout; -}; - -struct _MetaPreviewClass -{ - GtkBinClass parent_class; -}; - - -GType meta_preview_get_type (void) G_GNUC_CONST; -GtkWidget* meta_preview_new (void); - -void meta_preview_set_theme (MetaPreview *preview, - MetaTheme *theme); -void meta_preview_set_title (MetaPreview *preview, - const char *title); -void meta_preview_set_frame_type (MetaPreview *preview, - MetaFrameType type); -void meta_preview_set_frame_flags (MetaPreview *preview, - MetaFrameFlags flags); -void meta_preview_set_button_layout (MetaPreview *preview, - const MetaButtonLayout *button_layout); - -cairo_region_t * meta_preview_get_clip_region (MetaPreview *preview, - gint new_window_width, - gint new_window_height); - -#endif diff --git a/src/meta/screen.h b/src/meta/screen.h deleted file mode 100644 index 727bd50c1..000000000 --- a/src/meta/screen.h +++ /dev/null @@ -1,110 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* - * Copyright (C) 2008 Iain Holmes - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. - */ - -#ifndef META_SCREEN_H -#define META_SCREEN_H - -#include <X11/Xlib.h> -#include <glib-object.h> -#include <meta/types.h> -#include <meta/workspace.h> - -#define META_TYPE_SCREEN (meta_screen_get_type ()) -#define META_SCREEN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_SCREEN, MetaScreen)) -#define META_SCREEN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_SCREEN, MetaScreenClass)) -#define META_IS_SCREEN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_SCREEN)) -#define META_IS_SCREEN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_SCREEN)) -#define META_SCREEN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_SCREEN, MetaScreenClass)) - -typedef struct _MetaScreenClass MetaScreenClass; - -GType meta_screen_get_type (void); - -int meta_screen_get_screen_number (MetaScreen *screen); -MetaDisplay *meta_screen_get_display (MetaScreen *screen); - -Window meta_screen_get_xroot (MetaScreen *screen); -void meta_screen_get_size (MetaScreen *screen, - int *width, - int *height); -MetaScreen *meta_screen_for_x_screen (Screen *xscreen); - -void meta_screen_set_cm_selection (MetaScreen *screen); -void meta_screen_unset_cm_selection (MetaScreen *screen); - -GSList *meta_screen_get_startup_sequences (MetaScreen *screen); - -GList *meta_screen_get_workspaces (MetaScreen *screen); - -int meta_screen_get_n_workspaces (MetaScreen *screen); - -MetaWorkspace* meta_screen_get_workspace_by_index (MetaScreen *screen, - int index); -void meta_screen_remove_workspace (MetaScreen *screen, - MetaWorkspace *workspace, - guint32 timestamp); - -MetaWorkspace *meta_screen_append_new_workspace (MetaScreen *screen, - gboolean activate, - guint32 timestamp); - -int meta_screen_get_active_workspace_index (MetaScreen *screen); - -MetaWorkspace * meta_screen_get_active_workspace (MetaScreen *screen); - -void meta_screen_show_desktop (MetaScreen *screen, - guint32 timestamp); - -void meta_screen_toggle_desktop (MetaScreen *screen, - guint32 timestamp); - -void meta_screen_unshow_desktop (MetaScreen *screen); - -int meta_screen_get_n_monitors (MetaScreen *screen); -int meta_screen_get_primary_monitor (MetaScreen *screen); -int meta_screen_get_current_monitor (MetaScreen *screen); -void meta_screen_get_monitor_geometry (MetaScreen *screen, - int monitor, - MetaRectangle *geometry); - -gboolean meta_screen_get_monitor_in_fullscreen (MetaScreen *screen, - int monitor); - -int meta_screen_get_monitor_index_for_rect (MetaScreen *screen, - MetaRectangle *rect); - -MetaWindow* meta_screen_get_mouse_window (MetaScreen *screen, - MetaWindow *not_this_one); - -typedef enum -{ - META_SCREEN_TOPLEFT, - META_SCREEN_TOPRIGHT, - META_SCREEN_BOTTOMLEFT, - META_SCREEN_BOTTOMRIGHT -} MetaScreenCorner; - -void meta_screen_override_workspace_layout (MetaScreen *screen, - MetaScreenCorner starting_corner, - gboolean vertical_layout, - int n_rows, - int n_columns); -#endif diff --git a/src/meta/theme.h b/src/meta/theme.h index 33a230b96..0fbd1e5af 100644 --- a/src/meta/theme.h +++ b/src/meta/theme.h @@ -2,9 +2,9 @@ /* Metacity Theme Rendering */ -/* +/* * Copyright (C) 2001 Havoc Pennington - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the @@ -14,11 +14,9 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_THEME_H @@ -32,16 +30,12 @@ */ typedef struct _MetaTheme MetaTheme; -MetaTheme* meta_theme_get_current (void); -void meta_theme_set_current (const char *name, - gboolean force_reload); +META_EXPORT +MetaTheme* meta_theme_get_default (void); +META_EXPORT MetaTheme* meta_theme_new (void); -void meta_theme_free (MetaTheme *theme); -gboolean meta_theme_validate (MetaTheme *theme, - GError **error); - -MetaTheme* meta_theme_load (const char *theme_name, - GError **err); +META_EXPORT +void meta_theme_free (MetaTheme *theme); #endif diff --git a/src/meta/types.h b/src/meta/types.h index 03c819517..49fb56816 100644 --- a/src/meta/types.h +++ b/src/meta/types.h @@ -14,9 +14,7 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_TYPES_H @@ -26,10 +24,11 @@ * MetaCompositor: (skip) * */ +typedef struct _MetaBackend MetaBackend; typedef struct _MetaCompositor MetaCompositor; typedef struct _MetaDisplay MetaDisplay; +typedef struct _MetaX11Display MetaX11Display; typedef struct _MetaFrame MetaFrame; -typedef struct _MetaScreen MetaScreen; typedef struct _MetaWindow MetaWindow; typedef struct _MetaWorkspace MetaWorkspace; /** @@ -38,5 +37,12 @@ typedef struct _MetaWorkspace MetaWorkspace; */ typedef struct _MetaGroup MetaGroup; typedef struct _MetaKeyBinding MetaKeyBinding; +typedef struct _MetaCursorTracker MetaCursorTracker; + +typedef struct _MetaDnd MetaDnd; +typedef struct _MetaSettings MetaSettings; + +typedef struct _MetaWorkspaceManager MetaWorkspaceManager; +typedef struct _MetaSelection MetaSelection; #endif diff --git a/src/meta/util.h b/src/meta/util.h index be9a33a13..86c53bb7c 100644 --- a/src/meta/util.h +++ b/src/meta/util.h @@ -1,11 +1,11 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* Muffin utilities */ +/* Mutter utilities */ -/* +/* * Copyright (C) 2001 Havoc Pennington * Copyright (C) 2005 Elijah Newren - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the @@ -15,11 +15,9 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_UTIL_H @@ -30,22 +28,64 @@ #include <meta/common.h> +META_EXPORT gboolean meta_is_verbose (void); + +META_EXPORT gboolean meta_is_debugging (void); + +META_EXPORT gboolean meta_is_syncing (void); +META_EXPORT +gboolean meta_is_wayland_compositor (void); + +META_EXPORT void meta_debug_spew_real (const char *format, ...) G_GNUC_PRINTF (1, 2); + +META_EXPORT void meta_verbose_real (const char *format, ...) G_GNUC_PRINTF (1, 2); +META_EXPORT void meta_bug (const char *format, ...) G_GNUC_PRINTF (1, 2); + +META_EXPORT void meta_warning (const char *format, ...) G_GNUC_PRINTF (1, 2); + +META_EXPORT void meta_fatal (const char *format, - ...) G_GNUC_PRINTF (1, 2); + ...) G_GNUC_PRINTF (1, 2) G_GNUC_NORETURN G_ANALYZER_NORETURN; +/** + * MetaDebugTopic: + * @META_DEBUG_VERBOSE: verbose logging + * @META_DEBUG_FOCUS: focus + * @META_DEBUG_WORKAREA: workarea + * @META_DEBUG_STACK: stack + * @META_DEBUG_THEMES: themes + * @META_DEBUG_SM: session management + * @META_DEBUG_EVENTS: events + * @META_DEBUG_WINDOW_STATE: window state + * @META_DEBUG_WINDOW_OPS: window operations + * @META_DEBUG_GEOMETRY: geometry + * @META_DEBUG_PLACEMENT: window placement + * @META_DEBUG_PING: ping + * @META_DEBUG_XINERAMA: Xinerama + * @META_DEBUG_KEYBINDINGS: keybindings + * @META_DEBUG_SYNC: sync + * @META_DEBUG_ERRORS: errors + * @META_DEBUG_STARTUP: startup + * @META_DEBUG_PREFS: preferences + * @META_DEBUG_GROUPS: groups + * @META_DEBUG_RESIZING: resizing + * @META_DEBUG_SHAPES: shapes + * @META_DEBUG_COMPOSITOR: compositor + * @META_DEBUG_EDGE_RESISTANCE: edge resistance + */ typedef enum { META_DEBUG_VERBOSE = -1, @@ -70,37 +110,54 @@ typedef enum META_DEBUG_RESIZING = 1 << 18, META_DEBUG_SHAPES = 1 << 19, META_DEBUG_COMPOSITOR = 1 << 20, - META_DEBUG_EDGE_RESISTANCE = 1 << 21 + META_DEBUG_EDGE_RESISTANCE = 1 << 21, + META_DEBUG_DBUS = 1 << 22, + META_DEBUG_INPUT = 1 << 23 } MetaDebugTopic; +META_EXPORT void meta_topic_real (MetaDebugTopic topic, const char *format, ...) G_GNUC_PRINTF (2, 3); + +META_EXPORT void meta_add_verbose_topic (MetaDebugTopic topic); + +META_EXPORT void meta_remove_verbose_topic (MetaDebugTopic topic); +META_EXPORT void meta_push_no_msg_prefix (void); + +META_EXPORT void meta_pop_no_msg_prefix (void); +META_EXPORT gint meta_unsigned_long_equal (gconstpointer v1, gconstpointer v2); -guint meta_unsigned_long_hash (gconstpointer v); -void meta_print_backtrace (void); +META_EXPORT +guint meta_unsigned_long_hash (gconstpointer v); +META_EXPORT const char* meta_frame_type_to_string (MetaFrameType type); -const char* meta_gravity_to_string (int gravity); +META_EXPORT +const char* meta_gravity_to_string (MetaGravity gravity); -char* meta_g_utf8_strndup (const gchar *src, gsize n); +META_EXPORT +char* meta_external_binding_name_for_action (guint keybinding_action); -void meta_free_gslist_and_elements (GSList *list_to_deep_free); +META_EXPORT +char* meta_g_utf8_strndup (const gchar *src, gsize n); +META_EXPORT GPid meta_show_dialog (const char *type, const char *message, const char *timeout, const char *display, const char *ok_text, const char *cancel_text, + const char *icon_name, const int transient_for, GSList *columns, GSList *entries); @@ -132,14 +189,15 @@ GPid meta_show_dialog (const char *type, * MetaLaterType: * @META_LATER_RESIZE: call in a resize processing phase that is done * before GTK+ repainting (including window borders) is done. - * @META_LATER_CALC_SHOWING: used by Muffin to compute which windows should be mapped - * @META_LATER_CHECK_FULLSCREEN: used by Muffin to see if there's a fullscreen window - * @META_LATER_SYNC_STACK: used by Muffin to send it's idea of the stacking order to the server + * @META_LATER_CALC_SHOWING: used by Mutter to compute which windows should be mapped + * @META_LATER_CHECK_FULLSCREEN: used by Mutter to see if there's a fullscreen window + * @META_LATER_SYNC_STACK: used by Mutter to send it's idea of the stacking order to the server * @META_LATER_BEFORE_REDRAW: call before the stage is redrawn * @META_LATER_IDLE: call at a very low priority (can be blocked * by running animations or redrawing applications) **/ -typedef enum { +typedef enum +{ META_LATER_RESIZE, META_LATER_CALC_SHOWING, META_LATER_CHECK_FULLSCREEN, @@ -148,13 +206,32 @@ typedef enum { META_LATER_IDLE } MetaLaterType; +META_EXPORT guint meta_later_add (MetaLaterType when, GSourceFunc func, gpointer data, GDestroyNotify notify); + +META_EXPORT void meta_later_remove (guint later_id); -void meta_pre_exec_close_fds(void); -#endif /* META_UTIL_H */ +typedef enum +{ + META_LOCALE_DIRECTION_LTR, + META_LOCALE_DIRECTION_RTL, +} MetaLocaleDirection; +META_EXPORT +MetaLocaleDirection meta_get_locale_direction (void); +META_EXPORT +void meta_add_clutter_debug_flags (ClutterDebugFlag debug_flags, + ClutterDrawDebugFlag draw_flags, + ClutterPickDebugFlag pick_flags); + +META_EXPORT +void meta_remove_clutter_debug_flags (ClutterDebugFlag debug_flags, + ClutterDrawDebugFlag draw_flags, + ClutterPickDebugFlag pick_flags); + +#endif /* META_UTIL_H */ diff --git a/src/meta/window.h b/src/meta/window.h index 05e3b5ffa..dda5acea1 100644 --- a/src/meta/window.h +++ b/src/meta/window.h @@ -14,9 +14,7 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_WINDOW_H @@ -29,6 +27,25 @@ #include <meta/boxes.h> #include <meta/types.h> +/** + * MetaWindowType: + * @META_WINDOW_NORMAL: Normal + * @META_WINDOW_DESKTOP: Desktop + * @META_WINDOW_DOCK: Dock + * @META_WINDOW_DIALOG: Dialog + * @META_WINDOW_MODAL_DIALOG: Modal dialog + * @META_WINDOW_TOOLBAR: Toolbar + * @META_WINDOW_MENU: Menu + * @META_WINDOW_UTILITY: Utility + * @META_WINDOW_SPLASHSCREEN: Splashcreen + * @META_WINDOW_DROPDOWN_MENU: Dropdown menu + * @META_WINDOW_POPUP_MENU: Popup menu + * @META_WINDOW_TOOLTIP: Tooltip + * @META_WINDOW_NOTIFICATION: Notification + * @META_WINDOW_COMBO: Combobox + * @META_WINDOW_DND: Drag and drop + * @META_WINDOW_OVERRIDE_OTHER: Other override-redirect window type + */ typedef enum { META_WINDOW_NORMAL, @@ -51,12 +68,30 @@ typedef enum META_WINDOW_OVERRIDE_OTHER } MetaWindowType; +/** + * MetaMaximizeFlags: + * @META_MAXIMIZE_HORIZONTAL: Horizontal + * @META_MAXIMIZE_VERTICAL: Vertical + * @META_MAXIMIZE_BOTH: Both + */ typedef enum { META_MAXIMIZE_HORIZONTAL = 1 << 0, - META_MAXIMIZE_VERTICAL = 1 << 1 + META_MAXIMIZE_VERTICAL = 1 << 1, + META_MAXIMIZE_BOTH = (1 << 0 | 1 << 1), } MetaMaximizeFlags; +/** + * MetaWindowClientType: + * @META_WINDOW_CLIENT_TYPE_WAYLAND: A Wayland based window + * @META_WINDOW_CLIENT_TYPE_X11: An X11 based window + */ +typedef enum +{ + META_WINDOW_CLIENT_TYPE_WAYLAND, + META_WINDOW_CLIENT_TYPE_X11 +} MetaWindowClientType; + #define META_TYPE_WINDOW (meta_window_get_type ()) #define META_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_WINDOW, MetaWindow)) #define META_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_WINDOW, MetaWindowClass)) @@ -64,140 +99,357 @@ typedef enum #define META_IS_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_WINDOW)) #define META_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_WINDOW, MetaWindowClass)) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaWindow, g_object_unref) + typedef struct _MetaWindowClass MetaWindowClass; +META_EXPORT GType meta_window_get_type (void); +META_EXPORT MetaFrame *meta_window_get_frame (MetaWindow *window); + +META_EXPORT gboolean meta_window_has_focus (MetaWindow *window); + +META_EXPORT gboolean meta_window_appears_focused (MetaWindow *window); + +META_EXPORT gboolean meta_window_is_shaded (MetaWindow *window); + +META_EXPORT gboolean meta_window_is_override_redirect (MetaWindow *window); + +META_EXPORT gboolean meta_window_is_skip_taskbar (MetaWindow *window); -gboolean meta_window_is_interesting (MetaWindow *window); -MetaRectangle *meta_window_get_rect (MetaWindow *window); -void meta_window_get_input_rect (const MetaWindow *window, MetaRectangle *rect); -void meta_window_get_outer_rect (const MetaWindow *window, MetaRectangle *rect); -MetaScreen *meta_window_get_screen (MetaWindow *window); + +META_EXPORT +void meta_window_get_buffer_rect (const MetaWindow *window, MetaRectangle *rect); + +META_EXPORT +void meta_window_get_frame_rect (const MetaWindow *window, MetaRectangle *rect); + +META_EXPORT +void meta_window_client_rect_to_frame_rect (MetaWindow *window, + MetaRectangle *client_rect, + MetaRectangle *frame_rect); + +META_EXPORT +void meta_window_frame_rect_to_client_rect (MetaWindow *window, + MetaRectangle *frame_rect, + MetaRectangle *client_rect); + +META_EXPORT MetaDisplay *meta_window_get_display (MetaWindow *window); -unsigned long meta_window_get_xwindow (MetaWindow *window); + +META_EXPORT +Window meta_window_get_xwindow (MetaWindow *window); + +META_EXPORT MetaWindowType meta_window_get_window_type (MetaWindow *window); -Atom meta_window_get_window_type_atom (MetaWindow *window); + +META_EXPORT MetaWorkspace *meta_window_get_workspace (MetaWindow *window); + +META_EXPORT int meta_window_get_monitor (MetaWindow *window); + +META_EXPORT gboolean meta_window_is_on_all_workspaces (MetaWindow *window); + +META_EXPORT +gboolean meta_window_located_on_workspace (MetaWindow *window, + MetaWorkspace *workspace); + +META_EXPORT gboolean meta_window_is_hidden (MetaWindow *window); + +META_EXPORT void meta_window_activate (MetaWindow *window,guint32 current_time); + +META_EXPORT void meta_window_activate_with_workspace (MetaWindow *window, guint32 current_time, MetaWorkspace *workspace); + +META_EXPORT const char * meta_window_get_description (MetaWindow *window); + +META_EXPORT const char * meta_window_get_wm_class (MetaWindow *window); + +META_EXPORT const char * meta_window_get_wm_class_instance (MetaWindow *window); + +META_EXPORT gboolean meta_window_showing_on_its_workspace (MetaWindow *window); +META_EXPORT +const char * meta_window_get_sandboxed_app_id (MetaWindow *window); + +META_EXPORT +const char * meta_window_get_gtk_theme_variant (MetaWindow *window); + +META_EXPORT const char * meta_window_get_gtk_application_id (MetaWindow *window); + +META_EXPORT const char * meta_window_get_gtk_unique_bus_name (MetaWindow *window); + +META_EXPORT const char * meta_window_get_gtk_application_object_path (MetaWindow *window); + +META_EXPORT const char * meta_window_get_gtk_window_object_path (MetaWindow *window); + +META_EXPORT const char * meta_window_get_gtk_app_menu_object_path (MetaWindow *window); + +META_EXPORT const char * meta_window_get_gtk_menubar_object_path (MetaWindow *window); -void meta_window_move(MetaWindow *window, gboolean user_op, int root_x_nw, int root_y_nw); +META_EXPORT void meta_window_move_frame(MetaWindow *window, gboolean user_op, int root_x_nw, int root_y_nw); + +META_EXPORT void meta_window_move_resize_frame (MetaWindow *window, gboolean user_op, int root_x_nw, int root_y_nw, int w, int h); + +META_EXPORT void meta_window_move_to_monitor (MetaWindow *window, int monitor); -void meta_window_resize(MetaWindow *window, gboolean user_op, int w, int h); +META_EXPORT void meta_window_set_demands_attention (MetaWindow *window); + +META_EXPORT void meta_window_unset_demands_attention (MetaWindow *window); +META_EXPORT const char* meta_window_get_startup_id (MetaWindow *window); + +META_EXPORT void meta_window_change_workspace_by_index (MetaWindow *window, gint space_index, - gboolean append, - guint32 timestamp); -void meta_window_change_workspace (MetaWindow *window, - MetaWorkspace *workspace); -void meta_window_stick (MetaWindow *window); -void meta_window_unstick (MetaWindow *window); + gboolean append); + +META_EXPORT +void meta_window_change_workspace (MetaWindow *window, + MetaWorkspace *workspace); + +META_EXPORT GObject *meta_window_get_compositor_private (MetaWindow *window); + +META_EXPORT void meta_window_set_compositor_private (MetaWindow *window, GObject *priv); -void meta_window_configure_notify (MetaWindow *window, XConfigureEvent *event); + +META_EXPORT const char *meta_window_get_role (MetaWindow *window); + +META_EXPORT MetaStackLayer meta_window_get_layer (MetaWindow *window); + +META_EXPORT MetaWindow* meta_window_find_root_ancestor (MetaWindow *window); + +META_EXPORT gboolean meta_window_is_ancestor_of_transient (MetaWindow *window, MetaWindow *transient); typedef gboolean (*MetaWindowForeachFunc) (MetaWindow *window, - void *data); + void *user_data); +META_EXPORT void meta_window_foreach_transient (MetaWindow *window, MetaWindowForeachFunc func, void *user_data); + +META_EXPORT void meta_window_foreach_ancestor (MetaWindow *window, MetaWindowForeachFunc func, void *user_data); +META_EXPORT MetaMaximizeFlags meta_window_get_maximized (MetaWindow *window); + +META_EXPORT gboolean meta_window_is_fullscreen (MetaWindow *window); + +META_EXPORT +gboolean meta_window_is_screen_sized (MetaWindow *window); + +META_EXPORT gboolean meta_window_is_monitor_sized (MetaWindow *window); -gboolean meta_window_is_on_primary_monitor (MetaWindow *window); -gint *meta_window_get_all_monitors (MetaWindow *window, gsize *length); -gboolean meta_window_is_demanding_attention (MetaWindow *window); -gboolean meta_window_is_urgent (MetaWindow *window); +META_EXPORT +gboolean meta_window_is_on_primary_monitor (MetaWindow *window); +META_EXPORT gboolean meta_window_requested_bypass_compositor (MetaWindow *window); + +META_EXPORT gboolean meta_window_requested_dont_bypass_compositor (MetaWindow *window); +META_EXPORT gboolean meta_window_get_icon_geometry (MetaWindow *window, MetaRectangle *rect); + +META_EXPORT void meta_window_set_icon_geometry (MetaWindow *window, MetaRectangle *rect); + +META_EXPORT void meta_window_maximize (MetaWindow *window, MetaMaximizeFlags directions); + +META_EXPORT void meta_window_unmaximize (MetaWindow *window, MetaMaximizeFlags directions); + +META_EXPORT void meta_window_minimize (MetaWindow *window); + +META_EXPORT void meta_window_unminimize (MetaWindow *window); + +META_EXPORT void meta_window_raise (MetaWindow *window); + +META_EXPORT void meta_window_lower (MetaWindow *window); -void meta_window_reset_opacity (MetaWindow *window); + +META_EXPORT const char *meta_window_get_title (MetaWindow *window); + +META_EXPORT MetaWindow *meta_window_get_transient_for (MetaWindow *window); -Window meta_window_get_transient_for_as_xid (MetaWindow *window); + +META_EXPORT void meta_window_delete (MetaWindow *window, guint32 timestamp); + +META_EXPORT guint meta_window_get_stable_sequence (MetaWindow *window); + +META_EXPORT guint32 meta_window_get_user_time (MetaWindow *window); + +META_EXPORT int meta_window_get_pid (MetaWindow *window); -int meta_window_get_client_pid (MetaWindow *window); + +META_EXPORT const char *meta_window_get_client_machine (MetaWindow *window); + +META_EXPORT gboolean meta_window_is_remote (MetaWindow *window); -gboolean meta_window_is_modal (MetaWindow *window); + +META_EXPORT gboolean meta_window_is_attached_dialog (MetaWindow *window); -const char *meta_window_get_muffin_hints (MetaWindow *window); +META_EXPORT +const char *meta_window_get_mutter_hints (MetaWindow *window); + +META_EXPORT MetaFrameType meta_window_get_frame_type (MetaWindow *window); +META_EXPORT cairo_region_t *meta_window_get_frame_bounds (MetaWindow *window); +META_EXPORT MetaWindow *meta_window_get_tile_match (MetaWindow *window); +META_EXPORT +void meta_window_make_fullscreen (MetaWindow *window); + +META_EXPORT +void meta_window_unmake_fullscreen (MetaWindow *window); + +META_EXPORT +void meta_window_make_above (MetaWindow *window); + +META_EXPORT +void meta_window_unmake_above (MetaWindow *window); + +META_EXPORT +void meta_window_shade (MetaWindow *window, + guint32 timestamp); + +META_EXPORT +void meta_window_unshade (MetaWindow *window, + guint32 timestamp); + +META_EXPORT +void meta_window_stick (MetaWindow *window); + +META_EXPORT +void meta_window_unstick (MetaWindow *window); + +META_EXPORT +void meta_window_kill (MetaWindow *window); + +META_EXPORT +void meta_window_focus (MetaWindow *window, + guint32 timestamp); + +META_EXPORT +void meta_window_check_alive (MetaWindow *window, + guint32 timestamp); + +META_EXPORT +void meta_window_get_work_area_current_monitor (MetaWindow *window, + MetaRectangle *area); + +META_EXPORT +void meta_window_get_work_area_for_monitor (MetaWindow *window, + int which_monitor, + MetaRectangle *area); + +META_EXPORT +void meta_window_get_work_area_all_monitors (MetaWindow *window, + MetaRectangle *area); + +META_EXPORT +void meta_window_begin_grab_op (MetaWindow *window, + MetaGrabOp op, + gboolean frame_action, + guint32 timestamp); + +META_EXPORT gboolean meta_window_can_maximize (MetaWindow *window); + +META_EXPORT gboolean meta_window_can_minimize (MetaWindow *window); + +META_EXPORT gboolean meta_window_can_shade (MetaWindow *window); + +META_EXPORT gboolean meta_window_can_close (MetaWindow *window); + +META_EXPORT gboolean meta_window_is_always_on_all_workspaces (MetaWindow *window); -gboolean meta_window_is_always_on_top (MetaWindow *window); -gboolean meta_window_can_move (MetaWindow *window); -gboolean meta_window_can_resize (MetaWindow *window); - -gboolean meta_window_can_tile (MetaWindow *window, MetaTileMode mode); -gboolean meta_window_tile (MetaWindow *window, MetaTileMode mode, gboolean snap); -const char *meta_window_get_icon_name (MetaWindow *window); -GdkPixbuf *meta_window_create_icon (MetaWindow *window, - int size); + +META_EXPORT +gboolean meta_window_is_above (MetaWindow *window); + +META_EXPORT +gboolean meta_window_allows_move (MetaWindow *window); + +META_EXPORT +gboolean meta_window_allows_resize (MetaWindow *window); + +META_EXPORT +gboolean meta_window_is_client_decorated (MetaWindow *window); + +META_EXPORT +gboolean meta_window_titlebar_is_onscreen (MetaWindow *window); + +META_EXPORT +void meta_window_shove_titlebar_onscreen (MetaWindow *window); + +META_EXPORT +uint64_t meta_window_get_id (MetaWindow *window); + +META_EXPORT +MetaWindowClientType meta_window_get_client_type (MetaWindow *window); + #endif diff --git a/src/meta/workspace.h b/src/meta/workspace.h index 98c943ac3..99aebee5d 100644 --- a/src/meta/workspace.h +++ b/src/meta/workspace.h @@ -15,28 +15,14 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_WORKSPACE_H #define META_WORKSPACE_H -/** - * SECTION:Workspaces - * @short_description:Workspaces - * - * A workspace is a set of windows which all live on the same - * screen. (You may also see the name "desktop" around the place, - * which is the EWMH's name for the same thing.) Only one workspace - * of a screen may be active at once; all windows on all other workspaces - * are unmapped. - */ - #include <meta/types.h> #include <meta/boxes.h> -#include <meta/screen.h> #define META_TYPE_WORKSPACE (meta_workspace_get_type ()) #define META_WORKSPACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_WORKSPACE, MetaWorkspace)) @@ -47,31 +33,41 @@ typedef struct _MetaWorkspaceClass MetaWorkspaceClass; +META_EXPORT GType meta_workspace_get_type (void); +META_EXPORT int meta_workspace_index (MetaWorkspace *workspace); + +META_EXPORT +MetaDisplay *meta_workspace_get_display (MetaWorkspace *workspace); + +META_EXPORT GList* meta_workspace_list_windows (MetaWorkspace *workspace); + +META_EXPORT void meta_workspace_get_work_area_for_monitor (MetaWorkspace *workspace, int which_monitor, MetaRectangle *area); + +META_EXPORT void meta_workspace_get_work_area_all_monitors (MetaWorkspace *workspace, MetaRectangle *area); + +META_EXPORT void meta_workspace_activate (MetaWorkspace *workspace, guint32 timestamp); + +META_EXPORT void meta_workspace_activate_with_focus (MetaWorkspace *workspace, MetaWindow *focus_this, guint32 timestamp); -void meta_workspace_activate_with_direction_hint (MetaWorkspace *workspace, - MetaMotionDirection direction, - guint32 timestamp); -void meta_workspace_update_window_hints (MetaWorkspace *workspace); +META_EXPORT void meta_workspace_set_builtin_struts (MetaWorkspace *workspace, GSList *struts); -MetaWorkspace *meta_workspace_get_neighbor (MetaWorkspace *workspace, - MetaMotionDirection direction); -void meta_workspace_focus_default_window (MetaWorkspace *workspace, - MetaWindow *not_this_one, - guint32 timestamp); +META_EXPORT +MetaWorkspace* meta_workspace_get_neighbor (MetaWorkspace *workspace, + MetaMotionDirection direction); #endif diff --git a/src/muffin-plugins.pc.in b/src/muffin-plugins.pc.in deleted file mode 100644 index e392c8446..000000000 --- a/src/muffin-plugins.pc.in +++ /dev/null @@ -1,17 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ -plugindir=@MUFFIN_PLUGIN_DIR@ -libgnome_serverdir=@libexecdir@ -muffin_major_version=@MUFFIN_MAJOR_VERSION@ -muffin_minor_version=@MUFFIN_MINOR_VERSION@ -muffin_micro_version=@MUFFIN_MICRO_VERSION@ -muffin_plugin_api_version=@MUFFIN_PLUGIN_API_VERSION@ - -Name: muffin-plugins -Description: Dev parameters for muffin plugins -Requires: muffin-clutter-@MUFFIN_PLUGIN_API_VERSION@ -Version: @VERSION@ -Libs: @CLUTTER_LIBS@ -Cflags: @CLUTTER_CFLAGS@ -DWITH_CLUTTER -I${includedir}/muffin/muffin-private -DMUFFIN_MAJOR_VERSION=${muffin_major_version} -DMUFFIN_MINOR_VERSION=${muffin_minor_version} -DMUFFIN_MICRO_VERSION=${muffin_micro_version} -DMUFFIN_PLUGIN_API_VERSION=${muffin_plugin_api_version} -DMUFFIN_PLUGIN_DIR=\"${plugindir}\" diff --git a/src/muffin.desktop.desktop b/src/muffin.desktop.desktop deleted file mode 100644 index 26b3cc4a0..000000000 --- a/src/muffin.desktop.desktop +++ /dev/null @@ -1,19 +0,0 @@ - -[Desktop Entry] -Type=Application -Name=Muffin -Exec=muffin -NoDisplay=true -# name of loadable control center module -X-GNOME-WMSettingsModule=metacity -# name we put on the WM spec check window -X-GNOME-WMName=Muffin -# back compat only -X-GnomeWMSettingsLibrary=metacity -X-GNOME-Bugzilla-Bugzilla=GNOME -X-GNOME-Bugzilla-Product=muffin -X-GNOME-Bugzilla-Component=general -X-GNOME-Autostart-Phase=WindowManager -X-GNOME-Provides=windowmanager -X-GNOME-Autostart-Notify=true -Name[en_US]=muffin.desktop diff --git a/src/org.cinnamon.muffin.gschema.xml.in b/src/org.cinnamon.muffin.gschema.xml.in deleted file mode 100644 index 32dc53aa7..000000000 --- a/src/org.cinnamon.muffin.gschema.xml.in +++ /dev/null @@ -1,584 +0,0 @@ -<schemalist> - <enum id="sync_method"> - <value value="0" nick="none"/> - <value value="1" nick="fallback"/> - <value value="2" nick="swap_throttling"/> - <value value="3" nick="presentation_time"/> - </enum> - - <enum id="placement_type"> - <value value="0" nick="automatic"/> - <value value="1" nick="pointer"/> - <value value="2" nick="manual"/> - <value value="3" nick="center"/> - </enum> - - <enum id="background_transition"> - <value value="0" nick="none"/> - <value value="1" nick="fade-in"/> - <value value="2" nick="blend"/> - </enum> - - <schema id="org.cinnamon.muffin" path="/org/cinnamon/muffin/" - gettext-domain="@GETTEXT_DOMAIN"> - - <key name="attach-modal-dialogs" type="b"> - <default>false</default> - <_summary>Attach modal dialogs</_summary> - <_description> - When true, instead of having independent titlebars, modal dialogs - appear attached to the titlebar of the parent window and are moved - together with the parent window. - </_description> - </key> - - <key name="ignore-hide-titlebar-when-maximized" type="b"> - <default>false</default> - <_summary>Ignore client requests to hide the window's titlebar when maximized.</_summary> - <_description> - If true, causes the _GTK_HIDE_TITLEBAR_WHEN_MAXIMIZED hint to be ignored by muffin. Most apps that utilize this should (one would hope) use the hint responsibly, but this will allow it to be overridden just in case. - </_description> - </key> - - <key name="edge-tiling" type="b"> - <default>true</default> - <_summary>Enable edge tiling and snapping</_summary> - <_description> - If enabled, allows you to drag windows to the screen edges - to tile or snap them in place. - </_description> - </key> - - <key name="edge-resistance-window" type="b"> - <default>true</default> - <summary>Enable window edge resistance</summary> - <description>Determine whether there is tension along other window and screen/monitor edges when dragging a window.</description> - </key> - - <key name="dynamic-workspaces" type="b"> - <default>false</default> - <_summary>Workspaces are managed dynamically</_summary> - <_description> - Determines whether workspaces are managed dynamically or - whether there's a static number of workspaces (determined - by the num-workspaces key in org.cinnamon.desktop.wm.preferences). - </_description> - </key> - - <key name="unredirect-fullscreen-windows" type="b"> - <default>false</default> - <_summary>Fullscreen windows are unredirected (i.e. they bypass compositing)</_summary> - <_description> - Determines whether fullscreen windows bypass compositing. False is better for vsync/screen-tearing, True gives games and apps i - </_description> - </key> - - <key name="sync-to-vblank" type="b"> - <default>true</default> - <_summary>Enable vertical blanking interval</_summary> - <_description> - Determines whether or not VBLANK is enabled. - </_description> - </key> - - <key name="sync-method" enum="sync_method"> - <default>'presentation_time'</default> - <_summary>Sync method</_summary> - <_description>The method used by Muffin to provide VSync.</_description> - </key> - - <key name="threaded-swap" type="b"> - <default>true</default> - <_summary>Enable threaded swap waiting</_summary> - <_description> - Determines whether or not Cogl uses a threaded implementation for waiting for swap events. - </_description> - </key> - - <key name="send-frame-timings" type="b"> - <default>true</default> - <_summary>Enable high-precision frame synchronization</_summary> - <_description> - Sends a _NET_WM_FRAME_TIMINGS message to the X server after each frame rendered to help keep frames synchronized. - </_description> - </key> - - <key name="workspace-cycle" type="b"> - <default>false</default> - <_summary>Allow cycling through workspaces</_summary> - <_description> - Allows cycling through workspaces, going to the workspace at the other end - if you are at the left-most or right-most one. - </_description> - </key> - - <key name="workspaces-only-on-primary" type="b"> - <default>false</default> - <_summary>Workspaces only on primary</_summary> - <_description> - Determines whether workspace switching should happen for windows - on all monitors or only for windows on the primary monitor. - </_description> - </key> - - <key name="draggable-border-width" type="i"> - <default>10</default> - <range min="0" max="64"/> - <_summary>Draggable border width</_summary> - <_description> - The amount of total draggable borders. If the theme's visible - borders are not enough, invisible borders will be added to meet - this value. - </_description> - </key> - - <key name="tile-hud-threshold" type="i"> - <default>25</default> - <range min="1" max="400"/> - <_summary>Window tile HUD threshold</_summary> - <_description> - The distance from the edge of the screen you must be within before - the tile/snap HUD appears - </_description> - </key> - - <key name="resize-threshold" type="i"> - <default>24</default> - <range min="1" max="400"/> - <_summary>Window resize tension threshold</_summary> - <_description> - The distance you have to move a resize grip before it's actually - registered as a resize - </_description> - </key> - - <key name="snap-modifier" type="s"> - <default>'Control'</default> - <_summary>Modifier for toggling between tile and snap mode</_summary> - <_description> - When dragging a window, holding this key will engage snap mode. - </_description> - </key> - - <key name="legacy-snap" type="b"> - <default>false</default> - <_summary>Enable legacy drag snapping</_summary> - <_description> - Enables old-style snapping by holding the shift key while dragging a window - </_description> - </key> - - <key name="button-layout" type="s"> - <default>":minimize,maximize,close"</default> - <summary>Arrangement of buttons on the titlebar</summary> - <description> - Since Cinnamon 3.8, this key is obsolete and doesn't do anything anymore. The only reason it's still here is - because its absence makes Chromium crash at launch in Debian Stretch. - </description> - </key> - - <key name="invert-workspace-flip-direction" type="b"> - <default>false</default> - <_summary>Inverts the direction the left and right arrows take you when - you switch workspaces during a window drag</_summary> - <_description> - Changes left-right arrow keys to window-centric directions rather than - workspace-centric - </_description> - </key> - - <key name="tile-maximize" type="b"> - <default>false</default> - <_summary>Sets maximize as the tile action for the top edge of the screen</_summary> - <_description> - Makes tiling to the top maximize the window - </_description> - </key> - - <key name="placement-mode" enum="placement_type"> - <default>'center'</default> - <_summary>Window placement mode</_summary> - <_description>The window placement mode indicates how new windows - are positioned. "automatic" means the system chooses a location - automatically based on the space available on the desktop, or by - a simple cascade if there is no space; "pointer" means that new - windows are placed according to the mouse pointer position; - "manual" means that the user must manually place the new window - with the mouse or keyboard; "center" means that the system places - new windows in the center of the desktop.</_description> - </key> - - <key name="background-transition" enum="background_transition"> - <default>'blend'</default> - <_summary>Background transition</_summary> - <_description>The type of animation performed when changing background. - "none" means no animation at all. - "fade-in" means the old background switches to black and the new background appears with a fade-in effect. - "blend" means the old background disappears as the new background appears with a fade-in effect. - </_description> - </key> - - <key name="desktop-effects" type="b"> - <default>true</default> - <_summary>Enable desktop effects</_summary> - <_description> - Whether to enable desktop effects and window animations. - </_description> - </key> - - <child name="keybindings" schema="org.cinnamon.muffin.keybindings"/> - </schema> - <schema id="org.cinnamon.muffin.keybindings" path="/org/cinnamon/muffin/keybindings/"> - - <key name="toggle-recording" type="as"> - <default>[]</default> - </key> - - <key name="push-tile-left" type="as"> - <default>[]</default> - </key> - - <key name="push-tile-right" type="as"> - <default>[]</default> - </key> - - <key name="push-tile-up" type="as"> - <default>[]</default> - </key> - - <key name="push-tile-down" type="as"> - <default>[]</default> - </key> - - <key name="push-snap-left" type="as"> - <default>[]</default> - </key> - - <key name="push-snap-right" type="as"> - <default>[]</default> - </key> - - <key name="push-snap-up" type="as"> - <default>[]</default> - </key> - - <key name="push-snap-down" type="as"> - <default>[]</default> - </key> - - <key name="tab-popup-select" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - - <key name="tab-popup-cancel" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - - <key name="switch-to-workspace-1" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="switch-to-workspace-2" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="switch-to-workspace-3" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="switch-to-workspace-4" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="switch-to-workspace-5" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="switch-to-workspace-6" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="switch-to-workspace-7" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="switch-to-workspace-8" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="switch-to-workspace-9" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="switch-to-workspace-10" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="switch-to-workspace-11" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="switch-to-workspace-12" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="switch-to-workspace-left" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="switch-to-workspace-right" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="switch-to-workspace-up" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="switch-to-workspace-down" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="switch-group" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="switch-group-backward" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="switch-windows" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="switch-windows-backward" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="switch-panels" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="switch-panels-backward" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="cycle-group" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="cycle-group-backward" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="cycle-windows" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="cycle-windows-backward" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="cycle-panels" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="cycle-panels-backward" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="show-desktop" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="panel-main-menu" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="panel-run-dialog" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="set-spew-mark" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="activate-window-menu" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="toggle-fullscreen" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="toggle-maximized" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="toggle-above" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="maximize" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="unmaximize" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="toggle-shaded" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="minimize" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="close" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="begin-move" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="begin-resize" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="toggle-on-all-workspaces" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="move-to-workspace-1" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="move-to-workspace-2" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="move-to-workspace-3" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="move-to-workspace-4" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="move-to-workspace-5" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="move-to-workspace-6" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="move-to-workspace-7" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="move-to-workspace-8" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="move-to-workspace-9" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="move-to-workspace-10" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="move-to-workspace-11" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="move-to-workspace-12" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="move-to-workspace-left" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="move-to-workspace-right" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="move-to-workspace-up" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="move-to-workspace-down" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="raise-or-lower" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="raise" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="lower" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="maximize-vertically" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="maximize-horizontally" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="move-to-corner-nw" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="move-to-corner-ne" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="move-to-corner-sw" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="move-to-corner-se" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="move-to-side-n" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="move-to-side-s" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="move-to-side-e" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="move-to-side-w" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="move-to-center" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="increase-opacity" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - <key name="decrease-opacity" type="as"> - <default>[]</default> - <_summary>deprecated - moved to org.cinnamon.desktop.keybindings.wm</_summary> - </key> - </schema> -</schemalist> diff --git a/src/org.freedesktop.login1.xml b/src/org.freedesktop.login1.xml new file mode 100644 index 000000000..765475132 --- /dev/null +++ b/src/org.freedesktop.login1.xml @@ -0,0 +1,46 @@ +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" +"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> +<node> + <interface name="org.freedesktop.login1.Session"> + <property name="Active" type="b" access="read" /> + + <method name="Activate"> + </method> + <method name="TakeControl"> + <arg name="force" type="b"/> + </method> + <method name="ReleaseControl"> + </method> + <method name="TakeDevice"> + <annotation name="org.gtk.GDBus.C.UnixFD" value="true"/> + <arg name="major" type="u" direction="in"/> + <arg name="minor" type="u" direction="in"/> + <arg name="fd" type="h" direction="out"/> + <arg name="paused" type="b" direction="out"/> + </method> + <method name="ReleaseDevice"> + <arg name="major" type="u"/> + <arg name="minor" type="u"/> + </method> + <method name="PauseDeviceComplete"> + <arg name="major" type="u"/> + <arg name="minor" type="u"/> + </method> + <signal name="PauseDevice"> + <arg name="major" type="u"/> + <arg name="minor" type="u"/> + <arg name="type" type="s"/> + </signal> + <signal name="ResumeDevice"> + <arg name="major" type="u"/> + <arg name="minor" type="u"/> + <arg name="fd" type="h"/> + </signal> + </interface> + + <interface name="org.freedesktop.login1.Seat"> + <method name="SwitchTo"> + <arg name="vt" type="u"/> + </method> + </interface> +</node> diff --git a/src/org.gnome.Mutter.DisplayConfig.xml b/src/org.gnome.Mutter.DisplayConfig.xml new file mode 100644 index 000000000..4ec6cd4dc --- /dev/null +++ b/src/org.gnome.Mutter.DisplayConfig.xml @@ -0,0 +1,458 @@ +<!DOCTYPE node PUBLIC +'-//freedesktop//DTD D-BUS Object Introspection 1.0//EN' +'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'> +<node> + <!-- + org.gnome.Mutter.DisplayConfig: + @short_description: display configuration interface + + This interface is used by mutter and gnome-settings-daemon + to apply multiple monitor configuration. + --> + + <interface name="org.gnome.Mutter.DisplayConfig"> + + <!-- + GetResources: + @serial: configuration serial + @crtcs: available CRTCs + @outputs: available outputs + @modes: available modes + @max_screen_width: + @max_screen_height: + + Retrieves the current layout of the hardware. + + @serial is an unique identifier representing the current state + of the screen. It must be passed back to ApplyConfiguration() + and will be increased for every configuration change (so that + mutter can detect that the new configuration is based on old + state). + + A CRTC (CRT controller) is a logical monitor, ie a portion + of the compositor coordinate space. It might correspond + to multiple monitors, when in clone mode, but not that + it is possible to implement clone mode also by setting different + CRTCs to the same coordinates. + + The number of CRTCs represent the maximum number of monitors + that can be set to expand and it is a HW constraint; if more + monitors are connected, then necessarily some will clone. This + is complementary to the concept of the encoder (not exposed in + the API), which groups outputs that necessarily will show the + same image (again a HW constraint). + + A CRTC is represented by a DBus structure with the following + layout: + * u ID: the ID in the API of this CRTC + * x winsys_id: the low-level ID of this CRTC (which might + be a XID, a KMS handle or something entirely + different) + * i x, y, width, height: the geometry of this CRTC + (might be invalid if the CRTC is not in + use) + * i current_mode: the current mode of the CRTC, or -1 if this + CRTC is not used + Note: the size of the mode will always correspond + to the width and height of the CRTC + * u current_transform: the current transform (espressed according + to the wayland protocol) + * au transforms: all possible transforms + * a{sv} properties: other high-level properties that affect this + CRTC; they are not necessarily reflected in + the hardware. + No property is specified in this version of the API. + + Note: all geometry information refers to the untransformed + display. + + An output represents a physical screen, connected somewhere to + the computer. Floating connectors are not exposed in the API. + An output is a DBus struct with the following fields: + * u ID: the ID in the API + * x winsys_id: the low-level ID of this output (XID or KMS handle) + * i current_crtc: the CRTC that is currently driving this output, + or -1 if the output is disabled + * au possible_crtcs: all CRTCs that can control this output + * s name: the name of the connector to which the output is attached + (like VGA1 or HDMI) + * au modes: valid modes for this output + * au clones: valid clones for this output, ie other outputs that + can be assigned the same CRTC as this one; if you + want to mirror two outputs that don't have each other + in the clone list, you must configure two different + CRTCs for the same geometry + * a{sv} properties: other high-level properties that affect this + output; they are not necessarily reflected in + the hardware. + Known properties: + - "vendor" (s): (readonly) the human readable name + of the manufacturer + - "product" (s): (readonly) the human readable name + of the display model + - "serial" (s): (readonly) the serial number of this + particular hardware part + - "display-name" (s): (readonly) a human readable name + of this output, to be shown in the UI + - "backlight" (i): (readonly, use the specific interface) + the backlight value as a percentage + (-1 if not supported) + - "primary" (b): whether this output is primary + or not + - "presentation" (b): whether this output is + for presentation only + Note: properties might be ignored if not consistenly + applied to all outputs in the same clone group. In + general, it's expected that presentation or primary + outputs will not be cloned. + + A mode represents a set of parameters that are applied to + each output, such as resolution and refresh rate. It is a separate + object so that it can be referenced by CRTCs and outputs. + Multiple outputs in the same CRTCs must all have the same mode. + A mode is exposed as: + * u ID: the ID in the API + * x winsys_id: the low-level ID of this mode + * u width, height: the resolution + * d frequency: refresh rate + * u flags: mode flags as defined in xf86drmMode.h and randr.h + + Output and modes are read-only objects (except for output properties), + they can change only in accordance to HW changes (such as hotplugging + a monitor), while CRTCs can be changed with ApplyConfiguration(). + + XXX: actually, if you insist enough, you can add new modes + through xrandr command line or the KMS API, overriding what the + kernel driver and the EDID say. + Usually, it only matters with old cards with broken drivers, or + old monitors with broken EDIDs, but it happens more often with + projectors (if for example the kernel driver doesn't add the + 640x480 - 800x600 - 1024x768 default modes). Probably something + that we need to handle in mutter anyway. + --> + <method name="GetResources"> + <arg name="serial" direction="out" type="u" /> + <arg name="crtcs" direction="out" type="a(uxiiiiiuaua{sv})" /> + <arg name="outputs" direction="out" type="a(uxiausauaua{sv})" /> + <arg name="modes" direction="out" type="a(uxuudu)" /> + <arg name="max_screen_width" direction="out" type="i" /> + <arg name="max_screen_height" direction="out" type="i" /> + </method> + + <!-- + ApplyConfiguration: + @serial: configuration serial + @persistent: whether this configuration should be saved on disk + @crtcs: new data for CRTCs + @outputs: new data for outputs + + Applies the requested configuration changes. + + @serial must match the serial from the last GetResources() call, + or org.freedesktop.DBus.AccessDenied will be generated. + + If @persistent is true, mutter will attempt to replicate this + configuration the next time this HW layout appears. + + @crtcs represents the new logical configuration, as a list + of structures containing: + - u ID: the API ID from the corresponding GetResources() call + - i new_mode: the API ID of the new mode to configure the CRTC + with, or -1 if the CRTC should be disabled + - i x, y: the new coordinates of the top left corner + the geometry will be completed with the size information + from @new_mode + - u transform: the desired transform + - au outputs: the API ID of outputs that should be assigned to + this CRTC + - a{sv} properties: properties whose value should be changed + + Note: CRTCs not referenced in the array will be disabled. + + @outputs represent the output property changes as: + - u ID: the API ID of the output to change + - a{sv} properties: properties whose value should be changed + + Note: both for CRTCs and outputs, properties not included in + the dictionary will not be changed. + + Note: unrecognized properties will have no effect, but if the + configuration change succeeds the property will be reported + by the next GetResources() call, and if @persistent is true, + it will also be saved to disk. + + If the configuration is invalid according to the previous + GetResources() call, for example because a CRTC references + an output it cannot drive, or not all outputs support the + chosen mode, the error org.freedesktop.DBus.InvalidArgs will + be generated. + + If the configuration cannot be applied for any other reason + (eg. the screen size would exceed texture limits), the error + org.freedesktop.DBus.Error.LimitsExceeded will be generated. + --> + <method name="ApplyConfiguration"> + <arg name="serial" direction="in" type="u" /> + <arg name="persistent" direction="in" type="b" /> + <arg name="crtcs" direction="in" type="a(uiiiuaua{sv})" /> + <arg name="outputs" direction="in" type="a(ua{sv})" /> + </method> + + <!-- + ChangeBacklight: + @serial: configuration serial + @output: the API id of the output + @value: the new backlight value + + Changes the backlight of @output to @value, which is + expressed as a percentage and rounded to the HW limits. + + Returns the new value after rounding. + --> + <method name="ChangeBacklight"> + <arg name="serial" direction="in" type="u" /> + <arg name="output" direction="in" type="u" /> + <arg name="value" direction="in" type="i" /> + <arg name="new_value" direction="out" type="i" /> + </method> + + <!-- + GetCrtcGamma: + @serial: configuration serial + @crtc: API id of the crtc + @red: red gamma ramp + @green: green gamma ramp + @blue: blue gamma ramp + + Requests the current gamma ramps of @crtc. + --> + <method name="GetCrtcGamma"> + <arg name="serial" direction="in" type="u" /> + <arg name="crtc" direction="in" type="u" /> + <arg name="red" direction="out" type="aq" /> + <arg name="green" direction="out" type="aq" /> + <arg name="blue" direction="out" type="aq" /> + </method> + + <!-- + SetCrtcGamma: + @serial: configuration serial + @crtc: API id of the crtc + @red: red gamma ramp + @green: green gamma ramp + @blue: blue gamma ramp + + Changes the gamma ramps of @crtc. + --> + <method name="SetCrtcGamma"> + <arg name="serial" direction="in" type="u" /> + <arg name="crtc" direction="in" type="u" /> + <arg name="red" direction="in" type="aq" /> + <arg name="green" direction="in" type="aq" /> + <arg name="blue" direction="in" type="aq" /> + </method> + + <!-- + PowerSaveMode: + + Contains the current power saving mode for the screen, and + allows changing it. + + Possible values: + - 0: on + - 1: standby + - 2: suspend + - 3: off + - -1: unknown (unsupported) + + A client should not attempt to change the powersave mode + from -1 (unknown) to any other value, and viceversa. + Note that the actual effects of the different values + depend on the hardware and the kernel driver in use, and + it's perfectly possible that all values different than on + have the same effect. + Also, setting the PowerSaveMode to 3 (off) may or may + not have the same effect as disabling all outputs by + setting no CRTC on them with ApplyConfiguration(), and + may or may not cause a configuration change. + + Also note that this property might become out of date + if changed through different means (for example using the + XRandR interface directly). + --> + <property name="PowerSaveMode" type="i" access="readwrite" /> + + <!-- + MonitorsChanged: + + The signal is emitted every time the screen configuration + changes. + The client should then call GetResources() to read the new layout. + --> + <signal name="MonitorsChanged" /> + + <!-- + GetCurrentState: + @serial: configuration serial + @monitors: available monitors + @logical_monitors: current logical monitor configuration + @properties: display configuration properties + + @monitors represent connected physical monitors + + * s connector: connector name (e.g. HDMI-1, DP-1, etc) + * s vendor: vendor name + * s product: product name + * s serial: product serial + * a(siiddada{sv}) modes: available modes + * s id: mode ID + * i width: width in physical pixels + * i height: height in physical pixels + * d refresh rate: refresh rate + * d preferred scale: scale preferred as per calculations + * ad supported scales: scales supported by this mode + * a{sv} properties: optional properties, including: + - "is-current" (b): the mode is currently active mode + - "is-preferred" (b): the mode is the preferred mode + - "is-interlaced" (b): the mode is an interlaced mode + * a{sv} properties: optional properties, including: + - "width-mm" (i): physical width of monitor in millimeters + - "height-mm" (i): physical height of monitor in millimeters + - "is-underscanning" (b): whether underscanning is enabled + (absence of this means underscanning + not being supported) + - "max-screen-size" (ii): the maximum size a screen may have + (absence of this means unlimited screen + size) + - "is-builtin" (b): whether the monitor is built in, e.g. a + laptop panel (absence of this means it is + not built in) + - "display-name" (s): a human readable display name of the monitor + + Possible mode flags: + 1 : preferred mode + 2 : current mode + + + @logical_monitors represent current logical monitor configuration + + * i x: x position + * i y: y position + * d scale: scale + * u transform: transform (see below) + * b primary: true if this is the primary logical monitor + * a(sss) monitors: monitors displaying this logical monitor + * connector: name of the connector (e.g. DP-1, eDP-1 etc) + * vendor: vendor name + * product: product name + * serial: product serial + * a{sv} properties: possibly other properties + + Posisble transform values: + 0: normal + 1: 90° + 2: 180° + 3: 270° + 4: flipped + 5: 90° flipped + 6: 180° flipped + 7: 270° flipped + + + @layout_mode current layout mode represents the way logical monitors + are layed out on the screen. Possible modes include: + + 1 : physical + 2 : logical + + With physical layout mode, each logical monitor has the same dimensions + as the monitor modes of the associated monitors assigned to it, no + matter what scale is in use. + + With logical mode, the dimension of a logical monitor is the dimension + of the monitor mode, divided by the logical monitor scale. + + + Possible @properties are: + + * "supports-mirroring" (b): FALSE if mirroring not supported; TRUE or not + present if mirroring is supported. + * "layout-mode" (u): Represents in what way logical monitors are laid + out on the screen. The layout mode can be either + of the ones listed below. Absence of this property + means the layout mode cannot be changed, and that + "logical" mode is assumed to be used. + * 1 : logical - the dimension of a logical monitor is derived from + the monitor modes associated with it, then scaled + using the logical monitor scale. + * 2 : physical - the dimension of a logical monitor is derived from + the monitor modes associated with it. + * 3 : logical with ui scaling - the dimension of a logical monitor + is derived from the monitor modes associated with it, + then scaled using the logical monitor scale that is also + scaled by the global UI scaling (computed using the maximum + ceiled scaling value across the displays). + * "supports-changing-layout-mode" (b): True if the layout mode can be + changed. Absence of this means the + layout mode cannot be changed. + * "global-scale-required" (b): True if all the logical monitors must + always use the same scale. Absence of + this means logical monitor scales can + differ. + * "legacy-ui-scaling-factor" (i): The legacy scaling factor traditionally + used to scale X11 clients (commonly + communicated via the + Gdk/WindowScalingFactor XSetting entry). + --> + <method name="GetCurrentState"> + <arg name="serial" direction="out" type="u" /> + <arg name="monitors" direction="out" type="a((ssss)a(siiddada{sv})a{sv})" /> + <arg name="logical_monitors" direction="out" type="a(iiduba(ssss)a{sv})" /> + <arg name="properties" direction="out" type="a{sv}" /> + </method> + + <!-- + ApplyMonitorsConfig: + @serial: configuration serial + @method: configuration method + @logical_monitors: monitors configuration + @properties: properties + + @method represents the way the configuration should be handled. + + Possible methods: + 0: verify + 1: temporary + 2: persistent + + @logical_monitors consists of a list of logical monitor configurations. + Each logical monitor configuration consists of: + + * i: layout x position + * i: layout y position + * d: scale + * u: transform (see GetCurrentState) + * b primary: true if this is the primary logical monitor + * a(ssa{sv}): a list of monitors, each consisting of: + * s: connector + * s: monitor mode ID + * a{sv}: monitor properties, including: + - "enable_underscanning" (b): enable monitor underscanning; + may only be set when underscanning + is supported (see GetCurrentState). + + @properties may effect the global monitor configuration state. Possible + properties are: + + * "layout-mode" (u): layout mode the passed configuration is in; may + only be set when changing the layout mode is + supported (see GetCurrentState). + --> + <method name="ApplyMonitorsConfig"> + <arg name="serial" direction="in" type="u" /> + <arg name="method" direction="in" type="u" /> + <arg name="logical_monitors" direction="in" type="a(iiduba(ssa{sv}))" /> + <arg name="properties" direction="in" type="a{sv}" /> + </method> + </interface> +</node> diff --git a/src/org.gnome.Mutter.IdleMonitor.xml b/src/org.gnome.Mutter.IdleMonitor.xml new file mode 100644 index 000000000..374af4dc4 --- /dev/null +++ b/src/org.gnome.Mutter.IdleMonitor.xml @@ -0,0 +1,37 @@ +<!DOCTYPE node PUBLIC +'-//freedesktop//DTD D-BUS Object Introspection 1.0//EN' +'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'> +<node> + <!-- + org.gnome.Mutter.IdleMonitor: + @short_description: idle monitor interface + + This interface is used by gnome-desktop to implement + user activity monitoring. + --> + + <interface name="org.gnome.Mutter.IdleMonitor"> + <method name="GetIdletime"> + <arg name="idletime" direction="out" type="t"/> + </method> + + <method name="AddIdleWatch"> + <arg name="interval" direction="in" type="t" /> + <arg name="id" direction="out" type="u" /> + </method> + + <method name="AddUserActiveWatch"> + <arg name="id" direction="out" type="u" /> + </method> + + <method name="RemoveWatch"> + <arg name="id" direction="in" type="u" /> + </method> + + <method name="ResetIdletime"/> + + <signal name="WatchFired"> + <arg name="id" direction="out" type="u" /> + </signal> + </interface> +</node> diff --git a/src/org.gnome.Mutter.RemoteDesktop.xml b/src/org.gnome.Mutter.RemoteDesktop.xml new file mode 100644 index 000000000..a07aefe27 --- /dev/null +++ b/src/org.gnome.Mutter.RemoteDesktop.xml @@ -0,0 +1,191 @@ +<!DOCTYPE node PUBLIC +'-//freedesktop//DTD D-BUS Object Introspection 1.0//EN' +'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'> +<node> + + <!-- + org.gnome.Mutter.RemoteDesktop: + @short_description: Remote desktop interface + + This API is private and not intended to be used outside of the integrated + system that uses libmutter. No compatibility between versions are + promised. + --> + <interface name="org.gnome.Mutter.RemoteDesktop"> + + <!-- + CreateSession: + @session_path: Path to the new session object + --> + <method name="CreateSession"> + <arg name="session_path" type="o" direction="out" /> + </method> + + <!-- + SupportedDeviceTypes: + @short_description: Bit mask of supported device types + + Device types: + 1: keyboard + 2: pointer + 4: touchscreen + --> + <property name="SupportedDeviceTypes" type="u" access="read" /> + + <!-- + Version: + @short_description: API version + --> + <property name="Version" type="i" access="read" /> + + </interface> + + <!-- + org.gnome.Mutter.RemoteDesktop.Session: + @short_description: Remote desktop session + --> + <interface name="org.gnome.Mutter.RemoteDesktop.Session"> + + <!-- + SessionId: + + An identification string used for identifying a remote desktop session. + It can be used to associate screen cast sessions with a remote desktop session. + --> + <property name="SessionId" type="s" access="read" /> + + <!-- + Start: + + Start the remote desktop session + --> + <method name="Start" /> + + <!-- + Stop: + + Stop the remote desktop session + --> + <method name="Stop" /> + + <!-- + Closed: + + The session has closed. + + A session doesn't have to have been started before it may be closed. + After it being closed, it can no longer be used. + --> + <signal name="Closed" /> + + <!-- + NotifyKeyboardKeycode: + + A key identified by a keysym was pressed or released + --> + <method name="NotifyKeyboardKeycode"> + <arg name="keycode" type="u" direction="in" /> + <arg name="state" type="b" direction="in" /> + </method> + + <!-- + NotifyKeyboardKeysym: + + A key identified by a keysym was pressed or released + --> + <method name="NotifyKeyboardKeysym"> + <arg name="keysym" type="u" direction="in" /> + <arg name="state" type="b" direction="in" /> + </method> + + <!-- + NotifyPointerButton: + + A pointer button was pressed or released + --> + <method name="NotifyPointerButton"> + <arg name="button" type="i" direction="in" /> + <arg name="state" type="b" direction="in" /> + </method> + + <!-- + NotifyPointerAxis: + + A smooth pointer axis event notification + + Possible @flags: + 1: finish - scroll motion was finished (e.g. fingers lifted) + --> + <method name="NotifyPointerAxis"> + <arg name="dx" type="d" direction="in" /> + <arg name="dy" type="d" direction="in" /> + <arg name="flags" type="u" direction="in" /> + </method> + + <!-- + NotifyPointerAxisDiscrete: + + A discrete pointer axis event notification + --> + <method name="NotifyPointerAxisDiscrete"> + <arg name="axis" type="u" direction="in" /> + <arg name="steps" type="i" direction="in" /> + </method> + + <!-- + NotifyPointerMotionRelative: + + A relative pointer motion event notification + --> + <method name="NotifyPointerMotionRelative"> + <arg name="dx" type="d" direction="in" /> + <arg name="dy" type="d" direction="in" /> + </method> + + <!-- + NotifyPointerMotionAbsolute: + + A absolute pointer motion event notification + --> + <method name="NotifyPointerMotionAbsolute"> + <arg name="stream" type="s" direction="in" /> + <arg name="x" type="d" direction="in" /> + <arg name="y" type="d" direction="in" /> + </method> + + <!-- + NotifyTouchDown: + + A absolute pointer motion event notification + --> + <method name="NotifyTouchDown"> + <arg name="stream" type="s" direction="in" /> + <arg name="slot" type="u" direction="in" /> + <arg name="x" type="d" direction="in" /> + <arg name="y" type="d" direction="in" /> + </method> + + <!-- + NotifyTouchMotion: + + A absolute pointer motion event notification + --> + <method name="NotifyTouchMotion"> + <arg name="stream" type="s" direction="in" /> + <arg name="slot" type="u" direction="in" /> + <arg name="x" type="d" direction="in" /> + <arg name="y" type="d" direction="in" /> + </method> + + <!-- + NotifyTouchUp: + + A absolute pointer motion event notification + --> + <method name="NotifyTouchUp"> + <arg name="slot" type="u" direction="in" /> + </method> + + </interface> + +</node> diff --git a/src/org.gnome.Mutter.ScreenCast.xml b/src/org.gnome.Mutter.ScreenCast.xml new file mode 100644 index 000000000..1d9fa598e --- /dev/null +++ b/src/org.gnome.Mutter.ScreenCast.xml @@ -0,0 +1,149 @@ +<!DOCTYPE node PUBLIC +'-//freedesktop//DTD D-BUS Object Introspection 1.0//EN' +'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'> +<node> + + <!-- + org.gnome.Mutter.ScreenCast: + @short_description: Screen cast interface + + This API is private and not intended to be used outside of the integrated + system that uses libmutter. No compatibility between versions are + promised. + --> + <interface name="org.gnome.Mutter.ScreenCast"> + + <!-- + CreateSession: + @properties: Properties + @session_path: Path to the new session object + + * "remote-desktop-session-id" (s): The ID of a remote desktop session. + Remote desktop driven screen casts + are started and stopped by the remote + desktop session. + * "disable-animations" (b): Set to "true" if the screen cast application + would prefer animations to be globally + disabled, while the session is running. Default + is "false". Available since version 3. + --> + <method name="CreateSession"> + <arg name="properties" type="a{sv}" direction="in" /> + <arg name="session_path" type="o" direction="out" /> + </method> + + <!-- + Version: + @short_description: API version + --> + <property name="Version" type="i" access="read" /> + + </interface> + + <!-- + org.gnome.Mutter.ScreenCast.Session: + @short_description: Screen cast session + --> + <interface name="org.gnome.Mutter.ScreenCast.Session"> + + <!-- + Start: + + Start the screen cast session + --> + <method name="Start" /> + + <!-- + Stop: + + Stop the screen cast session + --> + <method name="Stop" /> + + <!-- + Closed: + + The session has closed. + --> + <signal name="Closed" /> + + <!-- + RecordMonitor: + @connector: Connector of the monitor to record + @properties: Properties + @stream_path: Path to the new stream object + + Record a single monitor. + + Available @properties include: + + * "cursor-mode" (u): Cursor mode. Default: 'hidden' (see below) + Available since API version 2. + + Available cursor mode values: + + 0: hidden - cursor is not included in the stream + 1: embedded - cursor is included in the framebuffer + 2: metadata - cursor is included as metadata in the PipeWire stream + --> + <method name="RecordMonitor"> + <arg name="connector" type="s" direction="in" /> + <arg name="properties" type="a{sv}" direction="in" /> + <arg name="stream_path" type="o" direction="out" /> + </method> + + <!-- + RecordWindow: + @properties: Properties used determining what window to select + @stream_path: Path to the new stream object + + Supported since API version 2. + + Record a single window. The cursor will not be included. + + Available @properties include: + + * "window-id" (t): Id of the window to record. + * "cursor-mode" (u): Cursor mode. Default: 'hidden' (see RecordMonitor). + + --> + <method name="RecordWindow"> + <arg name="properties" type="a{sv}" direction="in" /> + <arg name="stream_path" type="o" direction="out" /> + </method> + </interface> + + <!-- + org.gnome.Mutter.ScreenCast.Stream: + @short_description: Screen cast stream + --> + <interface name="org.gnome.Mutter.ScreenCast.Stream"> + + <!-- + PipeWireStreamAdded: + @short_description: Pipewire stream added + + A signal emitted when PipeWire stream for the screen cast stream has + been created. The @node_id corresponds to the PipeWire stream node. + --> + <signal name="PipeWireStreamAdded"> + <annotation name="org.gtk.GDBus.C.Name" value="pipewire-stream-added"/> + <arg name="node_id" type="u" direction="out" /> + </signal> + + <!-- + Parameters: + @short_description: Optional stream parameters + + Available parameters include: + + * "position" (ii): Position of the source of the stream in the + compositor coordinate space. + * "size" (ii): Size of the source of the stream in the compositor + coordinate space. + --> + <property name="Parameters" type="a{sv}" access="read" /> + + </interface> + +</node> diff --git a/src/stock_delete.png b/src/stock_delete.png deleted file mode 100644 index 429401cb7ba316e6286cafd58ac0de20c8e0c603..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 220 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmPmhmeSlXs-b4I-rnjiEBiObAE1aYF-J0b5UwyNotBh zd1gt5LP$ocg1e`0!21-{JfK1cPZ!4!i_^&o5@iqUMTB+Fx40`BCh_#Jh!{N*Je<kE zESGN}^q488Eg|%@OXiBpN4P~;AJqpvo#F98O8M{y7KUI;e$GpBv%Uk(V(@hJb6Mw< G&;$UgH9qSA diff --git a/src/stock_maximize.png b/src/stock_maximize.png deleted file mode 100644 index 6f1084058e214f21884b4e307f0b7b0e52bb6ce3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 166 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G^tAk28_ZrvZCAbW|YuPgf{R(U=)*_<lN44{y)r;B4q#hl~>iBAoJz5nNj)cQ=> z)sVy-ae-CNc31m5T@eNK<t>lSHhw>3V9@ZW#e|1}LHItKXd7FSE>Jszr>mdKI;Vst E0OCI|fdBvi diff --git a/src/stock_minimize.png b/src/stock_minimize.png deleted file mode 100644 index a22e3c45b0fa870ce093aff2726a7ab9f97360b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G^tAk28_ZrvZCAbW|YuPgf{R(U=)?iuTPEP+CDo-U3d6?2jkBv=<G7%;e*{HqW8 iY8d#6sf$+vXh8!%Bb)fM`Nx4O89ZJ6T-G@yGywppq9t(v diff --git a/src/tests/README b/src/tests/README new file mode 100644 index 000000000..9c620c328 --- /dev/null +++ b/src/tests/README @@ -0,0 +1,93 @@ +This directory implements a framework for automated tests of Mutter. The basic +idea is that mutter-test-runner acts as the window manager and compositor, and +forks off instances of mutter-test-client to act as clients. + +There's a simple scripting language for tests. A very small test would look like: + +--- +# Start up a new X11 client with the client id 1 (doesn't have to be an integer) +# Windows for this client will be referred to as 1/<window-id> +new_client 1 x11 + +# Create and show two windows - again the IDs don't have to be integers +create 1/1 +show 1/1 +create 1/2 +show 1/2 + +# Wait for the commands we've executed in the clients to reach Mutter +wait + +# Check that the windows are in the order we expect +assert_stacking 1/1 1/2 +--- + +Running +======= + +The tests are installed according to: + +https://wiki.gnome.org/Initiatives/GnomeGoals/InstalledTests + +if -Dtests=true is passed to `meson configure`. You can run them uninstalled with: + + ninja test + +Command reference +================= + +The following commands are supported. Quoting and comments follow shell rules. + +new_client <client-id> [wayland|x11] + Starts a client, connecting by either Wayland or X11. The client + will subsequently be known with the given client-id (an arbitrary + string) + +quit_client <client-id> + Destroys all windows for the client, waits for that to be processed, + then instructs the client to exit. + +create <client-id>/<window-id> [override|csd] + Creates a new window. For the X11 backend, the keyword 'override' + can be given to create an override-redirect and the keyword 'csd' + can be given to create a client-side decorated window. + +show <client-id>/<window-id> +hide <client-id>/<window-id> + Ask the client to show (map) or hide (unmap) the given window + +activate <client-id>/<window-id> + Ask the client to raise and focus the given window. This is currently a no-op + for Wayland, where this capability is not supported in the protocol. + +local_activate <client-id>-<window-id> + The same as 'activate', but the operation is done directly inside Mutter + and works for both backends + +raise <client-id>/<window-id> +lower <client-id>/<window-id> + Ask the client to raise or lower the given window ID. This is a no-op + for Wayland clients. (It's also considered discouraged, but supported, for + non-override-redirect X11 clients.) + +minimize <client-id>/<window-id> +unminimize <client-id>/<window-id> + Ask the client to minimize or unminimize the given window ID. This older + term for this operation is "iconify". + +destroy <client-id>/<window-id> + Destroy the given window + +wait + Wait until all requests sent by Mutter to clients have been received by Mutter, + and then wait until all requests by Mutter have been processed by the X server. + +assert_stacking <client-id>/<window-id> <client-id>/<window-id> ... + Assert that the list of client windows known to Mutter is as given and in + the given order, bottom to top. The character '|' can be present in the + list of windows to indicate the guard window that separates hidden and + visible windows. If '|' isn't present, the guard window is asserted to + be below all client windows. + + This function also queries the X server stack and verifies that Mutter's + expectation of the X server stack matches reality. diff --git a/src/core/testboxes.c b/src/tests/boxes-tests.c similarity index 93% rename from src/core/testboxes.c rename to src/tests/boxes-tests.c index dbbdada85..0c27ea77e 100644 --- a/src/core/testboxes.c +++ b/src/tests/boxes-tests.c @@ -1,6 +1,6 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* Muffin box operation testing program */ +/* Mutter box operation testing program */ /* * Copyright (C) 2005 Elijah Newren @@ -16,24 +16,28 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ -#include "boxes-private.h" +#include "config.h" + +#include "tests/boxes-tests.h" + #include <glib.h> #include <stdlib.h> #include <stdio.h> -#include <X11/Xutil.h> /* Just for the definition of the various gravities */ -#include <time.h> /* To initialize random seed */ +#include <X11/Xutil.h> +#include <time.h> +#include <math.h> + +#include "core/boxes-private.h" #define NUM_RANDOM_RUNS 10000 static void -init_random_ness () +init_random_ness (void) { - srand(time(NULL)); + srand (time (NULL)); } static void @@ -100,7 +104,7 @@ new_monitor_edge (int x, int y, int width, int height, int side_type) } static void -test_area () +test_area (void) { MetaRectangle temp; int i; @@ -112,12 +116,10 @@ test_area () temp = meta_rect (0, 0, 5, 7); g_assert (meta_rectangle_area (&temp) == 35); - - printf ("%s passed.\n", G_STRFUNC); } static void -test_intersect () +test_intersect (void) { MetaRectangle a = {100, 200, 50, 40}; MetaRectangle b = { 0, 50, 110, 152}; @@ -140,12 +142,10 @@ test_intersect () meta_rectangle_intersect (&b, &d, &b); g_assert (meta_rectangle_equal (&b, &b_intersect_d)); - - printf ("%s passed.\n", G_STRFUNC); } static void -test_equal () +test_equal (void) { MetaRectangle a = {10, 12, 4, 18}; MetaRectangle b = a; @@ -159,12 +159,10 @@ test_equal () g_assert (!meta_rectangle_equal (&a, &d)); g_assert (!meta_rectangle_equal (&a, &e)); g_assert (!meta_rectangle_equal (&a, &f)); - - printf ("%s passed.\n", G_STRFUNC); } static void -test_overlap_funcs () +test_overlap_funcs (void) { MetaRectangle temp1, temp2; int i; @@ -182,12 +180,10 @@ test_overlap_funcs () g_assert (!meta_rectangle_overlap (&temp1, &temp2)); g_assert (!meta_rectangle_horiz_overlap (&temp1, &temp2)); g_assert ( meta_rectangle_vert_overlap (&temp1, &temp2)); - - printf ("%s passed.\n", G_STRFUNC); } static void -test_basic_fitting () +test_basic_fitting (void) { MetaRectangle temp1, temp2, temp3; int i; @@ -220,20 +216,12 @@ test_basic_fitting () g_assert (!meta_rectangle_contains_rect (&temp1, &temp3)); g_assert ( meta_rectangle_could_fit_rect (&temp1, &temp3)); g_assert (!meta_rectangle_could_fit_rect (&temp3, &temp2)); - - printf ("%s passed.\n", G_STRFUNC); } static void free_strut_list (GSList *struts) { - GSList *tmp = struts; - while (tmp) - { - free (tmp->data); - tmp = tmp->next; - } - g_slist_free (struts); + g_slist_free_full (struts, g_free); } static GSList* @@ -358,7 +346,7 @@ get_monitor_edges (int which_monitor_set, int which_strut_set) #if 0 static void -test_merge_regions () +test_merge_regions (void) { /* logarithmically distributed random number of struts (range?) * logarithmically distributed random size of struts (up to screen size???) @@ -496,7 +484,7 @@ test_merge_regions () } /* Okay, we can free it now */ - free (delete_me->data); + g_free (delete_me->data); region = g_list_delete_link (region, delete_me); } @@ -580,7 +568,7 @@ verify_lists_are_equal (GList *code, GList *answer) } static void -test_regions_okay () +test_regions_okay (void) { GList* region; GList* tmp; @@ -653,20 +641,20 @@ test_regions_okay () /*************************************************************/ /* Make sure test region 5 has the right spanning rectangles */ /*************************************************************/ - printf ("The next test intentionally causes a warning, " - "but it can be ignored.\n"); + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, + "Region to merge was empty!*"); region = get_screen_region (5); + g_test_assert_expected_messages (); + verify_lists_are_equal (region, NULL); /* FIXME: Still to do: * - Create random struts and check the regions somehow */ - - printf ("%s passed.\n", G_STRFUNC); } static void -test_region_fitting () +test_region_fitting (void) { GList* region; MetaRectangle rect; @@ -705,12 +693,10 @@ test_region_fitting () g_assert (!meta_rectangle_contained_in_region (region, &rect)); meta_rectangle_free_list_and_elements (region); - - printf ("%s passed.\n", G_STRFUNC); } static void -test_clamping_to_region () +test_clamping_to_region (void) { GList* region; MetaRectangle rect; @@ -761,14 +747,17 @@ test_clamping_to_region () &min_size); g_assert (rect.width == 400 && rect.height == 1180); - printf ("The next test intentionally causes a warning, " - "but it can be ignored.\n"); rect = meta_rect (50, 50, 10000, 10000); min_size.width = 600; min_size.height = 1170; + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, + "No rect whose size to clamp to found*"); meta_rectangle_clamp_to_fit_into_region (region, fixed_directions, &rect, &min_size); + g_test_assert_expected_messages (); + g_assert (rect.width == 600 && rect.height == 1170); rect = meta_rect (350, 50, 100, 1100); @@ -789,20 +778,21 @@ test_clamping_to_region () &min_size); g_assert (rect.width == 400 && rect.height == 1100); - printf ("The next test intentionally causes a warning, " - "but it can be ignored.\n"); rect = meta_rect (300, 70, 999999, 999999); min_size.width = 100; min_size.height = 200; fixed_directions = FIXED_DIRECTION_Y; + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, + "No rect whose size to clamp to found*"); meta_rectangle_clamp_to_fit_into_region (region, fixed_directions, &rect, &min_size); + g_test_assert_expected_messages (); + g_assert (rect.width == 100 && rect.height == 999999); meta_rectangle_free_list_and_elements (region); - - printf ("%s passed.\n", G_STRFUNC); } static gboolean @@ -827,7 +817,7 @@ rect_overlaps_region (const GList *spanning_rects, gboolean time_to_print = FALSE; static void -test_clipping_to_region () +test_clipping_to_region (void) { GList* region; MetaRectangle rect, temp; @@ -884,12 +874,10 @@ test_clipping_to_region () g_assert (meta_rectangle_equal (&rect, &temp)); meta_rectangle_free_list_and_elements (region); - - printf ("%s passed.\n", G_STRFUNC); } static void -test_shoving_into_region () +test_shoving_into_region (void) { GList* region; MetaRectangle rect, temp; @@ -954,8 +942,6 @@ test_shoving_into_region () g_assert (meta_rectangle_equal (&rect, &temp)); meta_rectangle_free_list_and_elements (region); - - printf ("%s passed.\n", G_STRFUNC); } static void @@ -1006,7 +992,7 @@ verify_edge_lists_are_equal (GList *code, GList *answer) } static void -test_find_onscreen_edges () +test_find_onscreen_edges (void) { GList* edges; GList* tmp; @@ -1134,12 +1120,10 @@ test_find_onscreen_edges () verify_edge_lists_are_equal (edges, tmp); meta_rectangle_free_list_and_elements (tmp); meta_rectangle_free_list_and_elements (edges); - - printf ("%s passed.\n", G_STRFUNC); } static void -test_find_nonintersected_monitor_edges () +test_find_nonintersected_monitor_edges (void) { GList* edges; GList* tmp; @@ -1223,12 +1207,10 @@ test_find_nonintersected_monitor_edges () verify_edge_lists_are_equal (edges, tmp); meta_rectangle_free_list_and_elements (tmp); meta_rectangle_free_list_and_elements (edges); - - printf ("%s passed.\n", G_STRFUNC); } static void -test_gravity_resize () +test_gravity_resize (void) { MetaRectangle oldrect, rect, temp; @@ -1239,7 +1221,7 @@ test_gravity_resize () temp = meta_rect ( 50, 300, 20, 5); meta_rectangle_resize_with_gravity (&oldrect, &rect, - NorthWestGravity, + META_GRAVITY_NORTH_WEST, 20, 5); g_assert (meta_rectangle_equal (&rect, &temp)); @@ -1248,7 +1230,7 @@ test_gravity_resize () temp = meta_rect (165, 300, 20, 5); meta_rectangle_resize_with_gravity (&rect, &rect, - NorthGravity, + META_GRAVITY_NORTH, 20, 5); g_assert (meta_rectangle_equal (&rect, &temp)); @@ -1257,7 +1239,7 @@ test_gravity_resize () temp = meta_rect (280, 300, 20, 5); meta_rectangle_resize_with_gravity (&rect, &rect, - NorthEastGravity, + META_GRAVITY_NORTH_EAST, 20, 5); g_assert (meta_rectangle_equal (&rect, &temp)); @@ -1266,7 +1248,7 @@ test_gravity_resize () temp = meta_rect ( 50, 695, 50, 5); meta_rectangle_resize_with_gravity (&rect, &rect, - SouthWestGravity, + META_GRAVITY_SOUTH_WEST, 50, 5); g_assert (meta_rectangle_equal (&rect, &temp)); @@ -1275,7 +1257,7 @@ test_gravity_resize () temp = meta_rect (150, 695, 50, 5); meta_rectangle_resize_with_gravity (&rect, &rect, - SouthGravity, + META_GRAVITY_SOUTH, 50, 5); g_assert (meta_rectangle_equal (&rect, &temp)); @@ -1284,7 +1266,7 @@ test_gravity_resize () temp = meta_rect (250, 695, 50, 5); meta_rectangle_resize_with_gravity (&rect, &rect, - SouthEastGravity, + META_GRAVITY_SOUTH_EAST, 50, 5); g_assert (meta_rectangle_equal (&rect, &temp)); @@ -1293,7 +1275,7 @@ test_gravity_resize () temp = meta_rect (167, 1113, 832, 93); meta_rectangle_resize_with_gravity (&rect, &rect, - WestGravity, + META_GRAVITY_WEST, 832, 93); g_assert (meta_rectangle_equal (&rect, &temp)); @@ -1302,7 +1284,7 @@ test_gravity_resize () temp = meta_rect (-131, 1113, 833, 93); meta_rectangle_resize_with_gravity (&rect, &rect, - CenterGravity, + META_GRAVITY_CENTER, 832, 93); g_assert (meta_rectangle_equal (&rect, &temp)); @@ -1311,7 +1293,7 @@ test_gravity_resize () temp = meta_rect (270, 994, 430, 212); meta_rectangle_resize_with_gravity (&rect, &rect, - EastGravity, + META_GRAVITY_EAST, 430, 211); g_assert (meta_rectangle_equal (&rect, &temp)); @@ -1320,16 +1302,15 @@ test_gravity_resize () temp = meta_rect (300, 1000, 430, 211); meta_rectangle_resize_with_gravity (&rect, &rect, - StaticGravity, + META_GRAVITY_STATIC, 430, 211); g_assert (meta_rectangle_equal (&rect, &temp)); - - printf ("%s passed.\n", G_STRFUNC); } +#define EPSILON 0.000000001 static void -test_find_closest_point_to_line () +test_find_closest_point_to_line (void) { double x1, y1, x2, y2, px, py, rx, ry; double answer_x, answer_y; @@ -1342,7 +1323,7 @@ test_find_closest_point_to_line () x2, y2, px, py, &rx, &ry); - g_assert (rx == answer_x && ry == answer_y); + g_assert (fabs (rx - answer_x) < EPSILON && fabs (ry - answer_y) < EPSILON); /* Special test for x1 == x2, so that slop of line is infinite */ x1 = 3.0; y1 = 49.0; @@ -1353,7 +1334,7 @@ test_find_closest_point_to_line () x2, y2, px, py, &rx, &ry); - g_assert (rx == answer_x && ry == answer_y); + g_assert (fabs (rx - answer_x) < EPSILON && fabs (ry - answer_y) < EPSILON); /* Special test for y1 == y2, so perp line has slope of infinity */ x1 = 3.14; y1 = 7.0; @@ -1364,7 +1345,7 @@ test_find_closest_point_to_line () x2, y2, px, py, &rx, &ry); - g_assert (rx == answer_x && ry == answer_y); + g_assert (fabs (rx - answer_x) < EPSILON && fabs (ry - answer_y) < EPSILON); /* Test when we the point we want to be closest to is actually on the line */ x1 = 3.0; y1 = 49.0; @@ -1375,36 +1356,34 @@ test_find_closest_point_to_line () x2, y2, px, py, &rx, &ry); - g_assert (rx == answer_x && ry == answer_y); - - printf ("%s passed.\n", G_STRFUNC); + g_assert (fabs (rx - answer_x) < EPSILON && fabs (ry - answer_y) < EPSILON); } -int -main() +void +init_boxes_tests (void) { init_random_ness (); - test_area (); - test_intersect (); - test_equal (); - test_overlap_funcs (); - test_basic_fitting (); - test_regions_okay (); - test_region_fitting (); + g_test_add_func ("/util/boxes/area", test_area); + g_test_add_func ("/util/boxes/intersect", test_intersect); + g_test_add_func ("/util/boxes/equal", test_equal); + g_test_add_func ("/util/boxes/overlap", test_overlap_funcs); + g_test_add_func ("/util/boxes/basic-fitting", test_basic_fitting); - test_clamping_to_region (); - test_clipping_to_region (); - test_shoving_into_region (); + g_test_add_func ("/util/boxes/regions-ok", test_regions_okay); + g_test_add_func ("/util/boxes/regions-fitting", test_region_fitting); + + g_test_add_func ("/util/boxes/clamp-to-region", test_clamping_to_region); + g_test_add_func ("/util/boxes/clip-to-region", test_clipping_to_region); + g_test_add_func ("/util/boxes/shove-into-region", test_shoving_into_region); /* And now the functions dealing with edges more than boxes */ - test_find_onscreen_edges (); - test_find_nonintersected_monitor_edges (); + g_test_add_func ("/util/boxes/onscreen-edges", test_find_onscreen_edges); + g_test_add_func ("/util/boxes/nonintersected-monitor-edges", + test_find_nonintersected_monitor_edges); /* And now the misfit functions that don't quite fit in anywhere else... */ - test_gravity_resize (); - test_find_closest_point_to_line (); - - printf ("All tests passed.\n"); - return 0; + g_test_add_func ("/util/boxes/gravity-resize", test_gravity_resize); + g_test_add_func ("/util/boxes/closest-point-to-line", + test_find_closest_point_to_line); } diff --git a/src/tests/boxes-tests.h b/src/tests/boxes-tests.h new file mode 100644 index 000000000..9f3b778b7 --- /dev/null +++ b/src/tests/boxes-tests.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2018 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef BOXES_TESTS_H +#define BOXES_TESTS_H + +void init_boxes_tests (void); + +#endif /* BOXES_TESTS_H */ diff --git a/clutter/clutter/clutter-test-utils.c b/src/tests/clutter-test-utils.c similarity index 89% rename from clutter/clutter/clutter-test-utils.c rename to src/tests/clutter-test-utils.c index 11d13846c..59db1021a 100644 --- a/clutter/clutter/clutter-test-utils.c +++ b/src/tests/clutter-test-utils.c @@ -1,17 +1,8 @@ -#include "clutter-build-config.h" - #include "clutter-test-utils.h" #include <stdlib.h> #include <glib-object.h> - -#include "clutter-actor.h" -#include "clutter-color.h" -#include "clutter-event.h" -#include "clutter-keysyms.h" -#include "clutter-main.h" -#include "clutter-private.h" -#include "clutter-stage.h" +#include <clutter/clutter.h> typedef struct { ClutterActor *stage; @@ -21,6 +12,22 @@ typedef struct { static ClutterTestEnvironment *test_environ = NULL; +#define DBUS_NAME_WARNING "Lost or failed to acquire name" + +static gboolean +log_func (const gchar *log_domain, + GLogLevelFlags log_level, + const gchar *message, + gpointer user_data) +{ + if ((log_level & G_LOG_LEVEL_WARNING) && + g_strcmp0 (log_domain, "mutter") == 0 && + g_str_has_prefix (message, DBUS_NAME_WARNING)) + return FALSE; + + return TRUE; +} + /* * clutter_test_init: * @argc: (inout): number of arguments in @argv @@ -116,6 +123,8 @@ clutter_test_func_wrapper (gconstpointer data_) { const ClutterTestData *data = data_; + g_test_log_set_fatal_handler (log_func, NULL); + /* ensure that the previous test state has been cleaned up */ g_assert_null (test_environ->stage); @@ -220,7 +229,7 @@ clutter_test_add_data_full (const char *test_path, g_test_add_data_func_full (test_path, data, clutter_test_func_wrapper, - free); + g_free); } /** @@ -262,10 +271,10 @@ clutter_test_run (void) int res; g_assert (test_environ != NULL); - + res = g_test_run (); - free (test_environ); + g_free (test_environ); return res; } @@ -273,7 +282,7 @@ clutter_test_run (void) typedef struct { ClutterActor *stage; - ClutterPoint point; + graphene_point_t point; gpointer result; @@ -348,13 +357,13 @@ on_key_press_event (ClutterActor *stage, * Since: 1.18 */ gboolean -clutter_test_check_actor_at_point (ClutterActor *stage, - const ClutterPoint *point, - ClutterActor *actor, - ClutterActor **result) +clutter_test_check_actor_at_point (ClutterActor *stage, + const graphene_point_t *point, + ClutterActor *actor, + ClutterActor **result) { ValidateData *data; - guint press_id = 0; + gulong press_id = 0; g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE); g_return_val_if_fail (point != NULL, FALSE); @@ -386,10 +395,9 @@ clutter_test_check_actor_at_point (ClutterActor *stage, *result = data->result; - if (press_id != 0) - g_signal_handler_disconnect (stage, press_id); + g_clear_signal_handler (&press_id, stage); - free (data); + g_free (data); return *result == actor; } @@ -410,15 +418,15 @@ clutter_test_check_actor_at_point (ClutterActor *stage, * Since: 1.18 */ gboolean -clutter_test_check_color_at_point (ClutterActor *stage, - const ClutterPoint *point, - const ClutterColor *color, - ClutterColor *result) +clutter_test_check_color_at_point (ClutterActor *stage, + const graphene_point_t *point, + const ClutterColor *color, + ClutterColor *result) { ValidateData *data; gboolean retval; guint8 *buffer; - guint press_id = 0; + gulong press_id = 0; g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE); g_return_val_if_fail (point != NULL, FALSE); @@ -448,8 +456,7 @@ clutter_test_check_color_at_point (ClutterActor *stage, while (!data->was_painted) g_main_context_iteration (NULL, TRUE); - if (press_id != 0) - g_signal_handler_disconnect (stage, press_id); + g_clear_signal_handler (&press_id, stage); buffer = data->result; @@ -460,8 +467,8 @@ clutter_test_check_color_at_point (ClutterActor *stage, buffer[1] == color->green && buffer[2] == color->blue; - free (data->result); - free (data); + g_free (data->result); + g_free (data); return retval; } diff --git a/clutter/clutter/clutter-test-utils.h b/src/tests/clutter-test-utils.h similarity index 82% rename from clutter/clutter/clutter-test-utils.h rename to src/tests/clutter-test-utils.h index 37bf8b2f6..62e8e9fdc 100644 --- a/clutter/clutter/clutter-test-utils.h +++ b/src/tests/clutter-test-utils.h @@ -19,16 +19,23 @@ * License along with this library. If not, see <http://www.gnu.org/licenses/>. */ +#include "config.h" + #ifndef __CLUTTER_TEST_UTILS_H__ #define __CLUTTER_TEST_UTILS_H__ -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only <clutter/clutter.h> can be included directly." -#endif +#define __CLUTTER_H_INSIDE__ -#include <clutter/clutter-types.h> -#include <clutter/clutter-actor.h> -#include <clutter/clutter-color.h> +#include "clutter/clutter-types.h" +#include "clutter/clutter-actor.h" +#include "clutter/clutter-color.h" +#include "clutter/clutter-private.h" +#include "core/main-private.h" +#include "meta/common.h" +#include "meta/main.h" +#include "backends/x11/nested/meta-backend-x11-nested.h" +#include "wayland/meta-wayland.h" +#include "wayland/meta-xwayland.h" G_BEGIN_DECLS @@ -79,6 +86,8 @@ G_BEGIN_DECLS int \ main (int argc, char *argv[]) \ { \ + meta_test_init ();\ +\ clutter_test_init (&argc, &argv); \ \ { \ @@ -88,31 +97,31 @@ main (int argc, char *argv[]) \ return clutter_test_run (); \ } -CLUTTER_AVAILABLE_IN_1_18 +CLUTTER_EXPORT void clutter_test_init (int *argc, char ***argv); -CLUTTER_AVAILABLE_IN_1_18 +CLUTTER_EXPORT int clutter_test_run (void); -CLUTTER_AVAILABLE_IN_1_18 +CLUTTER_EXPORT void clutter_test_add (const char *test_path, GTestFunc test_func); -CLUTTER_AVAILABLE_IN_1_18 +CLUTTER_EXPORT void clutter_test_add_data (const char *test_path, GTestDataFunc test_func, gpointer test_data); -CLUTTER_AVAILABLE_IN_1_18 +CLUTTER_EXPORT void clutter_test_add_data_full (const char *test_path, GTestDataFunc test_func, gpointer test_data, GDestroyNotify test_notify); -CLUTTER_AVAILABLE_IN_1_18 +CLUTTER_EXPORT ClutterActor * clutter_test_get_stage (void); #define clutter_test_assert_actor_at_point(stage,point,actor) \ G_STMT_START { \ - const ClutterPoint *__p = (point); \ + const graphene_point_t *__p = (point); \ ClutterActor *__actor = (actor); \ ClutterActor *__stage = (stage); \ ClutterActor *__res; \ @@ -126,13 +135,13 @@ G_STMT_START { \ char *__msg = g_strdup_printf ("assertion failed (actor %s at %.2f,%.2f): found actor %s", \ __str1, __p->x, __p->y, __str2); \ g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, __msg); \ - free (__msg); \ + g_free (__msg); \ } \ } G_STMT_END #define clutter_test_assert_color_at_point(stage,point,color) \ G_STMT_START { \ - const ClutterPoint *__p = (point); \ + const graphene_point_t *__p = (point); \ const ClutterColor *__c = (color); \ ClutterActor *__stage = (stage); \ ClutterColor __res; \ @@ -142,22 +151,22 @@ G_STMT_START { \ char *__msg = g_strdup_printf ("assertion failed (color %s at %.2f,%.2f): found color %s", \ __str1, __p->x, __p->y, __str2); \ g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, __msg); \ - free (__msg); \ - free (__str1); \ - free (__str2); \ + g_free (__msg); \ + g_free (__str1); \ + g_free (__str2); \ } \ } G_STMT_END -CLUTTER_AVAILABLE_IN_1_18 -gboolean clutter_test_check_actor_at_point (ClutterActor *stage, - const ClutterPoint *point, - ClutterActor *actor, - ClutterActor **result); -CLUTTER_AVAILABLE_IN_1_18 -gboolean clutter_test_check_color_at_point (ClutterActor *stage, - const ClutterPoint *point, - const ClutterColor *color, - ClutterColor *result); +CLUTTER_EXPORT +gboolean clutter_test_check_actor_at_point (ClutterActor *stage, + const graphene_point_t *point, + ClutterActor *actor, + ClutterActor **result); +CLUTTER_EXPORT +gboolean clutter_test_check_color_at_point (ClutterActor *stage, + const graphene_point_t *point, + const ClutterColor *color, + ClutterColor *result); G_END_DECLS diff --git a/src/tests/clutter/README b/src/tests/clutter/README new file mode 100644 index 000000000..b5665e6ab --- /dev/null +++ b/src/tests/clutter/README @@ -0,0 +1,38 @@ +Outline of test categories: + +The conform/ tests should be non-interactive unit-tests that verify a single +feature is behaving as documented. Use the GLib and Clutter test API and macros +to write the test units. The conformance test suites are meant to be used with +continuous integration builds. + +The performance/ tests are performance tests, both focused tests testing single +metrics and larger tests. These tests are used to report one or more +performance markers for the build of Clutter. Each performance marker is picked +up from the standard output of running the tests from strings having the form +"\n@ marker-name: 42.23" where 'marker-name' and '42.23' are the key/value pairs +of a single metric. Each test can provide multiple key/value pairs. Note that +if framerate is the feedback metric the test should forcibly enable FPS +debugging itself. The file test-common.h contains utility function helping to +do fps reporting. + +The interactive/ tests are any tests whose status can not be determined without +a user looking at some visual output, or providing some manual input etc. This +covers most of the original Clutter tests. Ideally some of these tests will be +migrated into the conform/ directory. + +The accessibility/ tests are tests created to test the accessibility support of +clutter, testing some of the atk interfaces. + +Other notes: + +• All tests should ideally include a detailed description in the source +explaining exactly what the test is for, how the test was designed to work, +and possibly a rationale for the approach taken for testing. Tests for specific +bugs should reference the bug report URL or number. + +• When running tests under Valgrind, you should follow the instructions +available here: + + https://wiki.gnome.org/Valgrind + +and also use the suppression file available in the Git repository. diff --git a/clutter/tests/accessibility/cally-atkcomponent-example.c b/src/tests/clutter/accessibility/cally-atkcomponent-example.c similarity index 100% rename from clutter/tests/accessibility/cally-atkcomponent-example.c rename to src/tests/clutter/accessibility/cally-atkcomponent-example.c diff --git a/clutter/tests/accessibility/cally-atkeditabletext-example.c b/src/tests/clutter/accessibility/cally-atkeditabletext-example.c similarity index 100% rename from clutter/tests/accessibility/cally-atkeditabletext-example.c rename to src/tests/clutter/accessibility/cally-atkeditabletext-example.c diff --git a/clutter/tests/accessibility/cally-atkevents-example.c b/src/tests/clutter/accessibility/cally-atkevents-example.c similarity index 100% rename from clutter/tests/accessibility/cally-atkevents-example.c rename to src/tests/clutter/accessibility/cally-atkevents-example.c diff --git a/clutter/tests/accessibility/cally-atktext-example.c b/src/tests/clutter/accessibility/cally-atktext-example.c similarity index 84% rename from clutter/tests/accessibility/cally-atktext-example.c rename to src/tests/clutter/accessibility/cally-atktext-example.c index aaee04c1e..fce36f1a4 100644 --- a/clutter/tests/accessibility/cally-atktext-example.c +++ b/src/tests/clutter/accessibility/cally-atktext-example.c @@ -40,7 +40,7 @@ test_atk_text (ClutterActor *actor) gchar *text = NULL; AtkObject *object = NULL; AtkText *cally_text = NULL; - gboolean bool = FALSE; + gboolean boolean = FALSE; gunichar unichar; gint count = -1; gint start = -1; @@ -63,29 +63,16 @@ test_atk_text (ClutterActor *actor) unichar = atk_text_get_character_at_offset (cally_text, 5); buf = g_ucs4_to_utf8 (&unichar, 1, NULL, NULL, NULL); g_print ("atk_text_get_character_at_offset(5): '%s' vs '%c'\n", buf, text[5]); - free (text); text = NULL; - free (buf); buf = NULL; + g_free (text); text = NULL; + g_free (buf); buf = NULL; - text = atk_text_get_text_before_offset (cally_text, - 5, ATK_TEXT_BOUNDARY_WORD_END, - &start, &end); - g_print ("atk_text_get_text_before_offset: %s, %i, %i\n", - text, start, end); - free (text); text = NULL; - - text = atk_text_get_text_at_offset (cally_text, - 5, ATK_TEXT_BOUNDARY_WORD_END, - &start, &end); - g_print ("atk_text_get_text_at_offset: %s, %i, %i\n", - text, start, end); - free (text); text = NULL; - - text = atk_text_get_text_after_offset (cally_text, - 5, ATK_TEXT_BOUNDARY_WORD_END, - &start, &end); - g_print ("atk_text_get_text_after_offset: %s, %i, %i\n", + text = atk_text_get_string_at_offset (cally_text, + 5, + ATK_TEXT_GRANULARITY_WORD, + &start, &end); + g_print ("atk_text_get_string_at_offset: %s, %i, %i\n", text, start, end); - free (text); text = NULL; + g_free (text); text = NULL; pos = atk_text_get_caret_offset (cally_text); g_print ("atk_text_get_caret_offset: %i\n", pos); @@ -100,19 +87,19 @@ test_atk_text (ClutterActor *actor) text = atk_text_get_selection (cally_text, 0, &start, &end); g_print ("atk_text_get_selection: %s, %i, %i\n", text, start, end); - free(text); text = NULL; + g_free(text); text = NULL; - bool = atk_text_remove_selection (cally_text, 0); - g_print ("atk_text_remove_selection (0): %i\n", bool); + boolean = atk_text_remove_selection (cally_text, 0); + g_print ("atk_text_remove_selection (0): %i\n", boolean); - bool = atk_text_remove_selection (cally_text, 1); - g_print ("atk_text_remove_selection (1): %i\n", bool); + boolean = atk_text_remove_selection (cally_text, 1); + g_print ("atk_text_remove_selection (1): %i\n", boolean); - bool = atk_text_add_selection (cally_text, 5, 10); - g_print ("atk_text_add_selection: %i\n", bool); + boolean = atk_text_add_selection (cally_text, 5, 10); + g_print ("atk_text_add_selection: %i\n", boolean); - bool = atk_text_set_selection (cally_text, 0, 6, 10); - g_print ("atk_text_set_selection: %i\n", bool); + boolean = atk_text_set_selection (cally_text, 0, 6, 10); + g_print ("atk_text_set_selection: %i\n", boolean); at_set = atk_text_get_run_attributes (cally_text, 0, &start, &end); diff --git a/clutter/tests/accessibility/cally-clone-example.c b/src/tests/clutter/accessibility/cally-clone-example.c similarity index 100% rename from clutter/tests/accessibility/cally-clone-example.c rename to src/tests/clutter/accessibility/cally-clone-example.c diff --git a/clutter/tests/accessibility/cally-examples-util.c b/src/tests/clutter/accessibility/cally-examples-util.c similarity index 98% rename from clutter/tests/accessibility/cally-examples-util.c rename to src/tests/clutter/accessibility/cally-examples-util.c index 830b43208..ea3e31aa7 100644 --- a/clutter/tests/accessibility/cally-examples-util.c +++ b/src/tests/clutter/accessibility/cally-examples-util.c @@ -139,8 +139,8 @@ cally_util_a11y_init (int *argc, char ***argv) result = _a11y_invoke_module (bridge_path, TRUE); - free (bridge_dir); - free (bridge_path); + g_free (bridge_dir); + g_free (bridge_path); return result; } diff --git a/clutter/tests/accessibility/cally-examples-util.h b/src/tests/clutter/accessibility/cally-examples-util.h similarity index 100% rename from clutter/tests/accessibility/cally-examples-util.h rename to src/tests/clutter/accessibility/cally-examples-util.h diff --git a/src/tests/clutter/accessibility/meson.build b/src/tests/clutter/accessibility/meson.build new file mode 100644 index 000000000..fe9732efc --- /dev/null +++ b/src/tests/clutter/accessibility/meson.build @@ -0,0 +1,38 @@ +clutter_test_accessibility_common_sources = [ + 'cally-examples-util.c', + 'cally-examples-util.h', +] + +clutter_test_accessibility_c_args = [ + '-DPREFIXDIR="@0@"'.format(libdir), + '-DCLUTTER_DISABLE_DEPRECATION_WARNINGS', + '-DGLIB_DISABLE_DEPRECATION_WARNINGS', +] + +clutter_test_accessibility_c_args += clutter_debug_c_args + +clutter_accessibility_tests_dependencies = [ + clutter_deps, + libmutter_clutter_dep, +] + +clutter_accessibility_tests = [ + 'cally-atkcomponent-example', + 'cally-atktext-example', + 'cally-atkevents-example', + 'cally-atkeditabletext-example', + 'cally-clone-example', +] + +foreach test : clutter_accessibility_tests + executable(test, + sources: [ + clutter_test_accessibility_common_sources, + test + '.c', + ], + include_directories: clutter_includes, + c_args: clutter_test_accessibility_c_args, + dependencies: [clutter_accessibility_tests_dependencies], + install: false, + ) +endforeach diff --git a/clutter/tests/clutter-1.0.suppressions b/src/tests/clutter/clutter-1.0.suppressions similarity index 95% rename from clutter/tests/clutter-1.0.suppressions rename to src/tests/clutter/clutter-1.0.suppressions index f47498d16..b7f82ab30 100644 --- a/clutter/tests/clutter-1.0.suppressions +++ b/src/tests/clutter/clutter-1.0.suppressions @@ -66,14 +66,6 @@ fun:g_get_charset } -{ - cogl_features - Memcheck:Leak - fun:*alloc - ... - fun:cogl_get_features -} - { glx_query_version Memcheck:Leak diff --git a/clutter/tests/conform/actor-anchors.c b/src/tests/clutter/conform/actor-anchors.c similarity index 98% rename from clutter/tests/conform/actor-anchors.c rename to src/tests/clutter/conform/actor-anchors.c index ee3b6a5e6..3cf3191f3 100644 --- a/clutter/tests/conform/actor-anchors.c +++ b/src/tests/clutter/conform/actor-anchors.c @@ -4,6 +4,8 @@ #define CLUTTER_DISABLE_DEPRECATION_WARNINGS #include <clutter/clutter.h> +#include "tests/clutter-test-utils.h" + #define NOTIFY_ANCHOR_X (1 << 0) #define NOTIFY_ANCHOR_Y (1 << 1) #define NOTIFY_ANCHOR_GRAVITY (1 << 2) @@ -99,7 +101,7 @@ notify_cb (GObject *object, GParamSpec *pspec, TestState *state) macro so that the assertion failure will report the right line number */ #define assert_coords(state, x_1, y_1, x_2, y_2) G_STMT_START { \ - ClutterVertex verts[4]; \ + graphene_point3d_t verts[4]; \ clutter_actor_get_abs_allocation_vertices ((state)->rect, verts); \ check_coords ((state), (x_1), (y_1), (x_2), (y_2), verts); \ g_assert (approx_equal ((x_1), verts[0].x)); \ @@ -114,7 +116,7 @@ notify_cb (GObject *object, GParamSpec *pspec, TestState *state) g_assert (approx_equal (v->x, xc) && \ approx_equal (v->y, yc) && \ approx_equal (v->z, zc)); \ - g_boxed_free (CLUTTER_TYPE_VERTEX, v); } G_STMT_END + g_boxed_free (GRAPHENE_TYPE_POINT3D, v); } G_STMT_END static inline gboolean approx_equal (int a, int b) @@ -128,7 +130,7 @@ check_coords (TestState *state, gint y_1, gint x_2, gint y_2, - const ClutterVertex *verts) + const graphene_point3d_t *verts) { if (g_test_verbose ()) g_print ("checking that (%i,%i,%i,%i) \xe2\x89\x88 (%i,%i,%i,%i): %s\n", @@ -407,8 +409,7 @@ test_scale_center (TestState *state) g_assert (scale_x == 4.0); g_assert (scale_y == 2.0); g_assert (gravity == CLUTTER_GRAVITY_NONE); - assert_notifications (NOTIFY_SCALE_X | NOTIFY_SCALE_Y - | NOTIFY_SCALE_CENTER_X | NOTIFY_SCALE_CENTER_Y + assert_notifications (NOTIFY_SCALE_CENTER_X | NOTIFY_SCALE_CENTER_Y | NOTIFY_SCALE_GRAVITY); assert_coords (state, 100 + 10 - 10 * 4, 200 + 20 - 20 * 2, 100 + 10 + (RECT_WIDTH - 10) * 4, @@ -425,7 +426,7 @@ test_rotate_center (TestState *state) { ClutterActor *rect = state->rect; gdouble angle_x, angle_y, angle_z; - ClutterVertex *center_x, *center_y, *center_z; + graphene_point3d_t *center_x, *center_y, *center_z; ClutterGravity z_center_gravity; gfloat stage_width, stage_height; gfloat rect_x, rect_y; diff --git a/src/tests/clutter/conform/actor-clone.c b/src/tests/clutter/conform/actor-clone.c new file mode 100644 index 000000000..e78bf9baf --- /dev/null +++ b/src/tests/clutter/conform/actor-clone.c @@ -0,0 +1,68 @@ +#include <stdlib.h> +#include <string.h> + +#include <clutter/clutter.h> + +#include "tests/clutter-test-utils.h" + +static void +on_presented (ClutterStage *stage, + CoglFrameEvent *frame_event, + ClutterFrameInfo *frame_info, + gboolean *was_presented) +{ + *was_presented = TRUE; +} + +static void +actor_clone_unmapped (void) +{ + ClutterActor *container; + ClutterActor *actor; + ClutterActor *clone; + ClutterActor *stage; + gboolean was_presented; + + stage = clutter_test_get_stage (); + + container = clutter_actor_new (); + g_object_ref_sink (container); + g_object_add_weak_pointer (G_OBJECT (container), (gpointer *) &container); + + actor = clutter_actor_new (); + g_object_ref_sink (actor); + g_object_add_weak_pointer (G_OBJECT (actor), (gpointer *) &actor); + + clone = clutter_clone_new (actor); + g_object_ref_sink (clone); + g_object_add_weak_pointer (G_OBJECT (clone), (gpointer *) &clone); + + clutter_actor_hide (container); + clutter_actor_hide (actor); + + clutter_actor_add_child (stage, container); + clutter_actor_add_child (container, actor); + clutter_actor_add_child (stage, clone); + + clutter_actor_set_offscreen_redirect (actor, CLUTTER_OFFSCREEN_REDIRECT_ALWAYS); + + g_signal_connect (stage, "presented", G_CALLBACK (on_presented), + &was_presented); + + clutter_actor_show (stage); + + was_presented = FALSE; + while (!was_presented) + g_main_context_iteration (NULL, FALSE); + + clutter_actor_destroy (clone); + clutter_actor_destroy (actor); + clutter_actor_destroy (container); + g_assert_null (clone); + g_assert_null (actor); + g_assert_null (container); +} + +CLUTTER_TEST_SUITE ( + CLUTTER_TEST_UNIT ("/actor/clone/unmapped", actor_clone_unmapped) +) diff --git a/clutter/tests/conform/actor-destroy.c b/src/tests/clutter/conform/actor-destroy.c similarity index 77% rename from clutter/tests/conform/actor-destroy.c rename to src/tests/clutter/conform/actor-destroy.c index 03092a010..09a931d79 100644 --- a/clutter/tests/conform/actor-destroy.c +++ b/src/tests/clutter/conform/actor-destroy.c @@ -1,6 +1,8 @@ #define CLUTTER_DISABLE_DEPRECATION_WARNINGS #include <clutter/clutter.h> +#include "tests/clutter-test-utils.h" + #define TEST_TYPE_DESTROY (test_destroy_get_type ()) #define TEST_DESTROY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_DESTROY, TestDestroy)) #define TEST_IS_DESTROY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_DESTROY)) @@ -14,7 +16,6 @@ struct _TestDestroy ClutterActor *bg; ClutterActor *label; - ClutterActor *tex; GList *children; }; @@ -58,13 +59,8 @@ test_destroy_remove (ClutterContainer *container, clutter_actor_get_name (actor), G_OBJECT_TYPE_NAME (actor)); - g_assert (actor != self->bg); - g_assert (actor != self->label); - - if (!g_list_find (self->children, actor)) - g_assert (actor == self->tex); - else - self->children = g_list_remove (self->children, actor); + g_assert_true (g_list_find (self->children, actor)); + self->children = g_list_remove (self->children, actor); clutter_actor_unparent (actor); } @@ -81,6 +77,8 @@ test_destroy_destroy (ClutterActor *self) { TestDestroy *test = TEST_DESTROY (self); + g_assert_cmpuint (g_list_length (test->children), ==, 3); + if (test->bg != NULL) { if (g_test_verbose ()) @@ -103,23 +101,12 @@ test_destroy_destroy (ClutterActor *self) test->label = NULL; } - if (test->tex != NULL) - { - if (g_test_verbose ()) - g_print ("Destroying '%s' (type:%s)\n", - clutter_actor_get_name (test->tex), - G_OBJECT_TYPE_NAME (test->tex)); - - clutter_actor_destroy (test->tex); - test->tex = NULL; - } - - g_list_foreach (test->children, (GFunc) clutter_actor_destroy, NULL); - g_list_free (test->children); - test->children = NULL; + g_assert_cmpuint (g_list_length (test->children), ==, 1); if (CLUTTER_ACTOR_CLASS (test_destroy_parent_class)->destroy) CLUTTER_ACTOR_CLASS (test_destroy_parent_class)->destroy (self); + + g_assert_null (test->children); } static void @@ -133,24 +120,13 @@ test_destroy_class_init (TestDestroyClass *klass) static void test_destroy_init (TestDestroy *self) { - clutter_actor_push_internal (CLUTTER_ACTOR (self)); - - if (g_test_verbose ()) - g_print ("Adding internal children...\n"); - self->bg = clutter_rectangle_new (); - clutter_actor_set_parent (self->bg, CLUTTER_ACTOR (self)); + clutter_container_add_actor (CLUTTER_CONTAINER (self), self->bg); clutter_actor_set_name (self->bg, "Background"); self->label = clutter_text_new (); - clutter_actor_set_parent (self->label, CLUTTER_ACTOR (self)); + clutter_container_add_actor (CLUTTER_CONTAINER (self), self->label); clutter_actor_set_name (self->label, "Label"); - - clutter_actor_pop_internal (CLUTTER_ACTOR (self)); - - self->tex = clutter_texture_new (); - clutter_actor_set_parent (self->tex, CLUTTER_ACTOR (self)); - clutter_actor_set_name (self->tex, "Texture"); } static void @@ -159,15 +135,39 @@ on_destroy (ClutterActor *actor, { gboolean *destroy_called = data; + g_assert_true (CLUTTER_IS_ACTOR (clutter_actor_get_parent (actor))); + *destroy_called = TRUE; } +static void +on_parent_set (ClutterActor *actor, + ClutterActor *old_parent, + gpointer data) +{ + gboolean *parent_set_called = data; + + *parent_set_called = TRUE; +} + +static void +on_notify (ClutterActor *actor, + ClutterActor *old_parent, + gpointer data) +{ + gboolean *property_changed = data; + + *property_changed = TRUE; +} + static void actor_destruction (void) { ClutterActor *test = g_object_new (TEST_TYPE_DESTROY, NULL); ClutterActor *child = clutter_rectangle_new (); gboolean destroy_called = FALSE; + gboolean parent_set_called = FALSE; + gboolean property_changed = FALSE; g_object_ref_sink (test); @@ -179,6 +179,9 @@ actor_destruction (void) clutter_actor_set_name (child, "Child"); clutter_container_add_actor (CLUTTER_CONTAINER (test), child); + g_signal_connect (child, "parent-set", G_CALLBACK (on_parent_set), + &parent_set_called); + g_signal_connect (child, "notify", G_CALLBACK (on_notify), &property_changed); g_signal_connect (child, "destroy", G_CALLBACK (on_destroy), &destroy_called); if (g_test_verbose ()) @@ -186,6 +189,8 @@ actor_destruction (void) clutter_actor_destroy (test); g_assert (destroy_called); + g_assert_false (parent_set_called); + g_assert_false (property_changed); g_assert_null (child); g_assert_null (test); } diff --git a/clutter/tests/conform/actor-graph.c b/src/tests/clutter/conform/actor-graph.c similarity index 99% rename from clutter/tests/conform/actor-graph.c rename to src/tests/clutter/conform/actor-graph.c index 8fbf4bcb7..b388fe127 100644 --- a/clutter/tests/conform/actor-graph.c +++ b/src/tests/clutter/conform/actor-graph.c @@ -1,5 +1,7 @@ #include <clutter/clutter.h> +#include "tests/clutter-test-utils.h" + static void actor_add_child (void) { diff --git a/clutter/tests/conform/actor-invariants.c b/src/tests/clutter/conform/actor-invariants.c similarity index 99% rename from clutter/tests/conform/actor-invariants.c rename to src/tests/clutter/conform/actor-invariants.c index 87df90bc1..42dad3a04 100644 --- a/clutter/tests/conform/actor-invariants.c +++ b/src/tests/clutter/conform/actor-invariants.c @@ -4,6 +4,8 @@ #define CLUTTER_DISABLE_DEPRECATION_WARNINGS #include <clutter/clutter.h> +#include "tests/clutter-test-utils.h" + static void actor_initial_state (void) { diff --git a/clutter/tests/conform/actor-iter.c b/src/tests/clutter/conform/actor-iter.c similarity index 98% rename from clutter/tests/conform/actor-iter.c rename to src/tests/clutter/conform/actor-iter.c index 65f59ed21..3e963c56a 100644 --- a/clutter/tests/conform/actor-iter.c +++ b/src/tests/clutter/conform/actor-iter.c @@ -1,6 +1,8 @@ #include <glib.h> #include <clutter/clutter.h> +#include "tests/clutter-test-utils.h" + static void actor_iter_traverse_children (void) { @@ -24,7 +26,7 @@ actor_iter_traverse_children (void) clutter_actor_add_child (actor, child); - free (name); + g_free (name); } g_assert_cmpint (clutter_actor_get_n_children (actor), ==, n_actors); @@ -99,7 +101,7 @@ actor_iter_traverse_remove (void) clutter_actor_add_child (actor, child); - free (name); + g_free (name); } g_assert_cmpint (clutter_actor_get_n_children (actor), ==, n_actors); @@ -155,7 +157,7 @@ actor_iter_assignment (void) clutter_actor_add_child (actor, child); - free (name); + g_free (name); } g_assert_cmpint (clutter_actor_get_n_children (actor), ==, n_actors); diff --git a/clutter/tests/conform/actor-layout.c b/src/tests/clutter/conform/actor-layout.c similarity index 90% rename from clutter/tests/conform/actor-layout.c rename to src/tests/clutter/conform/actor-layout.c index 2cc89400c..9a9814b08 100644 --- a/clutter/tests/conform/actor-layout.c +++ b/src/tests/clutter/conform/actor-layout.c @@ -1,12 +1,14 @@ #include <clutter/clutter.h> +#include "tests/clutter-test-utils.h" + static void actor_basic_layout (void) { ClutterActor *stage = clutter_test_get_stage (); ClutterActor *vase; ClutterActor *flower[3]; - ClutterPoint p; + graphene_point_t p; vase = clutter_actor_new (); clutter_actor_set_name (vase, "Vase"); @@ -31,13 +33,13 @@ actor_basic_layout (void) clutter_actor_set_name (flower[2], "Green Flower"); clutter_actor_add_child (vase, flower[2]); - clutter_point_init (&p, 50, 50); + graphene_point_init (&p, 50, 50); clutter_test_assert_actor_at_point (stage, &p, flower[0]); - clutter_point_init (&p, 150, 50); + graphene_point_init (&p, 150, 50); clutter_test_assert_actor_at_point (stage, &p, flower[1]); - clutter_point_init (&p, 250, 50); + graphene_point_init (&p, 250, 50); clutter_test_assert_actor_at_point (stage, &p, flower[2]); } @@ -47,7 +49,7 @@ actor_margin_layout (void) ClutterActor *stage = clutter_test_get_stage (); ClutterActor *vase; ClutterActor *flower[3]; - ClutterPoint p; + graphene_point_t p; vase = clutter_actor_new (); clutter_actor_set_name (vase, "Vase"); @@ -76,13 +78,13 @@ actor_margin_layout (void) clutter_actor_set_margin_bottom (flower[2], 6); clutter_actor_add_child (vase, flower[2]); - clutter_point_init (&p, 0, 7); + graphene_point_init (&p, 0, 7); clutter_test_assert_actor_at_point (stage, &p, flower[0]); - clutter_point_init (&p, 106, 50); + graphene_point_init (&p, 106, 50); clutter_test_assert_actor_at_point (stage, &p, flower[1]); - clutter_point_init (&p, 212, 7); + graphene_point_init (&p, 212, 7); clutter_test_assert_actor_at_point (stage, &p, flower[2]); } diff --git a/clutter/tests/conform/actor-meta.c b/src/tests/clutter/conform/actor-meta.c similarity index 96% rename from clutter/tests/conform/actor-meta.c rename to src/tests/clutter/conform/actor-meta.c index 52a313d22..0211f99ae 100644 --- a/clutter/tests/conform/actor-meta.c +++ b/src/tests/clutter/conform/actor-meta.c @@ -3,6 +3,8 @@ #include <clutter/clutter.h> +#include "tests/clutter-test-utils.h" + static void actor_meta_clear (void) { diff --git a/clutter/tests/conform/actor-offscreen-redirect.c b/src/tests/clutter/conform/actor-offscreen-redirect.c similarity index 69% rename from clutter/tests/conform/actor-offscreen-redirect.c rename to src/tests/clutter/conform/actor-offscreen-redirect.c index 3c8f14ad6..a3faaabfc 100644 --- a/clutter/tests/conform/actor-offscreen-redirect.c +++ b/src/tests/clutter/conform/actor-offscreen-redirect.c @@ -1,6 +1,8 @@ #define CLUTTER_DISABLE_DEPRECATION_WARNINGS #include <clutter/clutter.h> +#include "tests/clutter-test-utils.h" + typedef struct _FooActor FooActor; typedef struct _FooActorClass FooActorClass; @@ -35,10 +37,15 @@ G_DEFINE_TYPE (FooActor, foo_actor, CLUTTER_TYPE_ACTOR); static gboolean group_has_overlaps; static void -foo_actor_paint (ClutterActor *actor) +foo_actor_paint (ClutterActor *actor, + ClutterPaintContext *paint_context) { + CoglContext *ctx = + clutter_backend_get_cogl_context (clutter_get_default_backend ()); FooActor *foo_actor = (FooActor *) actor; ClutterActorBox allocation; + CoglPipeline *pipeline; + CoglFramebuffer *framebuffer; foo_actor->last_paint_opacity = clutter_actor_get_paint_opacity (actor); foo_actor->paint_count++; @@ -46,14 +53,19 @@ foo_actor_paint (ClutterActor *actor) clutter_actor_get_allocation_box (actor, &allocation); /* Paint a red rectangle with the right opacity */ - cogl_set_source_color4ub (255, - 0, - 0, - foo_actor->last_paint_opacity); - cogl_rectangle (allocation.x1, - allocation.y1, - allocation.x2, - allocation.y2); + pipeline = cogl_pipeline_new (ctx); + cogl_pipeline_set_color4ub (pipeline, + 255, 0, 0, + foo_actor->last_paint_opacity); + + framebuffer = clutter_paint_context_get_framebuffer (paint_context); + cogl_framebuffer_draw_rectangle (framebuffer, + pipeline, + allocation.x1, + allocation.y1, + allocation.x2, + allocation.y2); + cogl_object_unref (pipeline); } static gboolean @@ -147,14 +159,14 @@ verify_results (Data *data, g_assert_cmpint (ABS ((int) expected_color_green - (int) pixel[1]), <=, 2); g_assert_cmpint (ABS ((int) expected_color_blue - (int) pixel[2]), <=, 2); - free (pixel); + g_free (pixel); } static void verify_redraw (Data *data, int expected_paint_count) { GMainLoop *main_loop = g_main_loop_new (NULL, TRUE); - guint paint_handler; + gulong paint_handler; paint_handler = g_signal_connect_data (data->stage, "paint", @@ -171,7 +183,7 @@ verify_redraw (Data *data, int expected_paint_count) /* Wait for it to paint */ g_main_loop_run (main_loop); - g_signal_handler_disconnect (data->stage, paint_handler); + g_clear_signal_handler (&paint_handler, data->stage); g_assert_cmpint (data->foo_actor->paint_count, ==, expected_paint_count); } @@ -181,6 +193,9 @@ verify_redraws (gpointer user_data) { Data *data = user_data; + clutter_actor_set_offscreen_redirect (data->container, + CLUTTER_OFFSCREEN_REDIRECT_ALWAYS); + /* Queueing a redraw on the actor should cause a redraw */ clutter_actor_queue_redraw (data->container); verify_redraw (data, 1); @@ -189,10 +204,11 @@ verify_redraws (gpointer user_data) clutter_actor_queue_redraw (data->child); verify_redraw (data, 1); - /* Modifying the transformation on the parent should cause a - redraw */ + /* Modifying the transformation on the parent should not cause a redraw, + since the FBO stores pre-transformed rendering that can be reused with + any transformation. */ clutter_actor_set_anchor_point (data->parent_container, 0, 1); - verify_redraw (data, 1); + verify_redraw (data, 0); /* Redrawing an unrelated actor shouldn't cause a redraw */ clutter_actor_set_position (data->unrelated_actor, 0, 1); @@ -207,6 +223,7 @@ static gboolean run_verify (gpointer user_data) { Data *data = user_data; + int i; group_has_overlaps = FALSE; @@ -300,6 +317,90 @@ run_verify (gpointer user_data) 0, 255); + /* ON_IDLE: Defer redirection through the FBO until it is deemed to be the + * best performing option, which means when the actor's contents have + * stopped changing. + */ + clutter_actor_set_offscreen_redirect (data->container, + CLUTTER_OFFSCREEN_REDIRECT_ON_IDLE); + + /* Changing modes should not incur a redraw */ + verify_results (data, + 255, 0, 0, + 0, + 255); + + /* These will incur a redraw because the actor is dirty: */ + for (i = 0; i < 10; i++) + { + clutter_actor_queue_redraw (data->container); + verify_results (data, + 255, 0, 0, + 1, + 255); + } + + /* The actor is not dirty, but also not yet cached so a redraw is expected */ + verify_results (data, + 255, 0, 0, + 1, + 255); + + /* These will NOT incur a redraw because the actor is unchanged: */ + for (i = 0; i < 10; i++) + { + verify_results (data, + 255, 0, 0, + 0, + 255); + } + + /* The first opacity change should require no redaw */ + clutter_actor_set_opacity (data->container, 64); + verify_results (data, + 255, 191, 191, + 0, + 255); + + /* The second opacity change should require no redaw */ + clutter_actor_set_opacity (data->container, 127); + verify_results (data, + 255, 127, 127, + 0, + 255); + + /* The third opacity change should require no redaw */ + clutter_actor_set_opacity (data->container, 255); + verify_results (data, + 255, 0, 0, + 0, + 255); + + /* Now several frames without the actor changing AND the FBO is populated. + * Expect no internal repaints. + */ + for (i = 0; i < 10; i++) + { + verify_results (data, + 255, 0, 0, + 0, + 255); + } + + /* Another opacity change, no redraw expected */ + clutter_actor_set_opacity (data->container, 127); + verify_results (data, + 255, 127, 127, + 0, + 255); + + /* Finally the actor's content changes so a redraw is expected */ + clutter_actor_queue_redraw (data->container); + verify_results (data, + 255, 127, 127, + 1, + 127); + /* Check redraws */ g_idle_add (verify_redraws, data); @@ -311,11 +412,11 @@ actor_offscreen_redirect (void) { Data data = { 0 }; - if (!cogl_features_available (COGL_FEATURE_OFFSCREEN)) - return; - data.stage = clutter_test_get_stage (); data.parent_container = clutter_actor_new (); + clutter_actor_set_background_color (data.parent_container, + &(ClutterColor) { 255, 255, 255, 255 }); + data.container = g_object_new (foo_group_get_type (), NULL); data.foo_actor = g_object_new (foo_actor_get_type (), NULL); clutter_actor_set_size (CLUTTER_ACTOR (data.foo_actor), 100, 100); diff --git a/clutter/tests/conform/actor-paint-opacity.c b/src/tests/clutter/conform/actor-paint-opacity.c similarity index 99% rename from clutter/tests/conform/actor-paint-opacity.c rename to src/tests/clutter/conform/actor-paint-opacity.c index 6df240872..8e0447de9 100644 --- a/clutter/tests/conform/actor-paint-opacity.c +++ b/src/tests/clutter/conform/actor-paint-opacity.c @@ -1,6 +1,8 @@ #include <clutter/clutter.h> #include <stdlib.h> +#include "tests/clutter-test-utils.h" + static void opacity_label (void) { diff --git a/clutter/tests/conform/actor-pick.c b/src/tests/clutter/conform/actor-pick.c similarity index 67% rename from clutter/tests/conform/actor-pick.c rename to src/tests/clutter/conform/actor-pick.c index 969b4920a..dcee96424 100644 --- a/clutter/tests/conform/actor-pick.c +++ b/src/tests/clutter/conform/actor-pick.c @@ -1,11 +1,12 @@ #define CLUTTER_DISABLE_DEPRECATION_WARNINGS #include <clutter/clutter.h> +#include "tests/clutter-test-utils.h" + #define STAGE_WIDTH 640 #define STAGE_HEIGHT 480 #define ACTORS_X 12 #define ACTORS_Y 16 -#define SHIFT_STEP STAGE_WIDTH / ACTORS_X typedef struct _State State; @@ -20,84 +21,11 @@ struct _State gboolean pass; }; -struct _ShiftEffect -{ - ClutterShaderEffect parent_instance; -}; - -struct _ShiftEffectClass -{ - ClutterShaderEffectClass parent_class; -}; - -typedef struct _ShiftEffect ShiftEffect; -typedef struct _ShiftEffectClass ShiftEffectClass; - -#define TYPE_SHIFT_EFFECT (shift_effect_get_type ()) - -GType shift_effect_get_type (void); - -G_DEFINE_TYPE (ShiftEffect, - shift_effect, - CLUTTER_TYPE_SHADER_EFFECT); - -static void -shader_paint (ClutterEffect *effect, - ClutterEffectPaintFlags flags) -{ - ClutterShaderEffect *shader = CLUTTER_SHADER_EFFECT (effect); - float tex_width; - ClutterActor *actor = - clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect)); - - if (g_test_verbose ()) - g_debug ("shader_paint"); - - clutter_shader_effect_set_shader_source (shader, - "uniform sampler2D tex;\n" - "uniform float step;\n" - "void main (void)\n" - "{\n" - " cogl_color_out = texture2D(tex, vec2 (cogl_tex_coord_in[0].s + step,\n" - " cogl_tex_coord_in[0].t));\n" - "}\n"); - - tex_width = clutter_actor_get_width (actor); - - clutter_shader_effect_set_uniform (shader, "tex", G_TYPE_INT, 1, 0); - clutter_shader_effect_set_uniform (shader, "step", G_TYPE_FLOAT, 1, - SHIFT_STEP / tex_width); - - CLUTTER_EFFECT_CLASS (shift_effect_parent_class)->paint (effect, flags); -} - -static void -shader_pick (ClutterEffect *effect, - ClutterEffectPaintFlags flags) -{ - shader_paint (effect, flags); -} - -static void -shift_effect_class_init (ShiftEffectClass *klass) -{ - ClutterEffectClass *shader_class = CLUTTER_EFFECT_CLASS (klass); - - shader_class->paint = shader_paint; - shader_class->pick = shader_pick; -} - -static void -shift_effect_init (ShiftEffect *self) -{ -} - static const char *test_passes[] = { "No covering actor", "Invisible covering actor", "Clipped covering actor", "Blur effect", - "Shift effect", }; static gboolean @@ -139,6 +67,9 @@ on_timeout (gpointer data) } else if (test_num == 2) { + ClutterActorBox over_actor_box = + CLUTTER_ACTOR_BOX_INIT (0, 0, STAGE_WIDTH, STAGE_HEIGHT); + /* Make the actor visible but set a clip so that only some of the actors are accessible */ clutter_actor_show (over_actor); @@ -148,6 +79,11 @@ on_timeout (gpointer data) state->actor_width * (ACTORS_X - 4), state->actor_height * (ACTORS_Y - 4)); + /* Only allocated actors can be picked, so force an allocation + * of the overlay actor here. + */ + clutter_actor_allocate (over_actor, &over_actor_box, 0); + if (g_test_verbose ()) g_print ("Clipped covering actor:\n"); } @@ -165,30 +101,10 @@ on_timeout (gpointer data) if (g_test_verbose ()) g_print ("With blur effect:\n"); } - else if (test_num == 4) - { - if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL)) - continue; - - clutter_actor_hide (over_actor); - clutter_actor_remove_effect_by_name (CLUTTER_ACTOR (state->stage), - "blur"); - - clutter_actor_add_effect_with_name (CLUTTER_ACTOR (state->stage), - "shift", - g_object_new (TYPE_SHIFT_EFFECT, - NULL)); - - if (g_test_verbose ()) - g_print ("With shift effect:\n"); - } for (y = 0; y < ACTORS_Y; y++) { - if (test_num == 4) - x = 1; - else - x = 0; + x = 0; for (; x < ACTORS_X; x++) { @@ -198,9 +114,6 @@ on_timeout (gpointer data) pick_x = x * state->actor_width + state->actor_width / 2; - if (test_num == 4) - pick_x -= SHIFT_STEP; - actor = clutter_stage_get_actor_at_pos (CLUTTER_STAGE (state->stage), CLUTTER_PICK_ALL, @@ -270,10 +183,10 @@ actor_pick (void) for (y = 0; y < ACTORS_Y; y++) for (x = 0; x < ACTORS_X; x++) { - ClutterColor color = { x * 255 / (ACTORS_X - 1), - y * 255 / (ACTORS_Y - 1), - 128, 255 }; - ClutterActor *rect = clutter_rectangle_new_with_color (&color); + ClutterColor color = { x * 255 / (ACTORS_X - 1), + y * 255 / (ACTORS_Y - 1), + 128, 255 }; + ClutterActor *rect = clutter_rectangle_new_with_color (&color); clutter_actor_set_position (rect, x * state.actor_width, @@ -282,9 +195,9 @@ actor_pick (void) state.actor_width, state.actor_height); - clutter_actor_add_child (state.stage, rect); + clutter_actor_add_child (state.stage, rect); - state.actors[y * ACTORS_X + x] = rect; + state.actors[y * ACTORS_X + x] = rect; } clutter_actor_show (state.stage); diff --git a/clutter/tests/conform/actor-shader-effect.c b/src/tests/clutter/conform/actor-shader-effect.c similarity index 85% rename from clutter/tests/conform/actor-shader-effect.c rename to src/tests/clutter/conform/actor-shader-effect.c index d3ddd384f..a2cea6d46 100644 --- a/clutter/tests/conform/actor-shader-effect.c +++ b/src/tests/clutter/conform/actor-shader-effect.c @@ -2,6 +2,8 @@ #define CLUTTER_DISABLE_DEPRECATION_WARNINGS #include <clutter/clutter.h> +#include "tests/clutter-test-utils.h" + /**************************************************************** Old style shader effect This uses clutter_shader_effect_set_source @@ -34,7 +36,8 @@ G_DEFINE_TYPE (FooOldShaderEffect, CLUTTER_TYPE_SHADER_EFFECT); static void -foo_old_shader_effect_paint_target (ClutterOffscreenEffect *effect) +foo_old_shader_effect_paint_target (ClutterOffscreenEffect *effect, + ClutterPaintContext *paint_context) { clutter_shader_effect_set_shader_source (CLUTTER_SHADER_EFFECT (effect), old_shader_effect_source); @@ -44,7 +47,7 @@ foo_old_shader_effect_paint_target (ClutterOffscreenEffect *effect) 1.0f, 0.0f, 0.0f); CLUTTER_OFFSCREEN_EFFECT_CLASS (foo_old_shader_effect_parent_class)-> - paint_target (effect); + paint_target (effect, paint_context); } static void @@ -108,7 +111,8 @@ foo_new_shader_effect_get_static_source (ClutterShaderEffect *effect) } static void -foo_new_shader_effect_paint_target (ClutterOffscreenEffect *effect) +foo_new_shader_effect_paint_target (ClutterOffscreenEffect *effect, + ClutterPaintContext *paint_context) { clutter_shader_effect_set_uniform (CLUTTER_SHADER_EFFECT (effect), "override_color", @@ -116,7 +120,7 @@ foo_new_shader_effect_paint_target (ClutterOffscreenEffect *effect) 0.0f, 1.0f, 0.0f); CLUTTER_OFFSCREEN_EFFECT_CLASS (foo_new_shader_effect_parent_class)-> - paint_target (effect); + paint_target (effect, paint_context); } static void @@ -209,14 +213,16 @@ make_actor (GType shader_type) } static guint32 -get_pixel (int x, int y) +get_pixel (CoglFramebuffer *fb, + int x, + int y) { guint8 data[4]; - cogl_read_pixels (x, y, 1, 1, - COGL_READ_PIXELS_COLOR_BUFFER, - COGL_PIXEL_FORMAT_RGBA_8888_PRE, - data); + cogl_framebuffer_read_pixels (fb, + x, y, 1, 1, + COGL_PIXEL_FORMAT_RGBA_8888_PRE, + data); return (((guint32) data[0] << 16) | ((guint32) data[1] << 8) | @@ -224,19 +230,22 @@ get_pixel (int x, int y) } static void -paint_cb (ClutterStage *stage, - gpointer data) +view_painted_cb (ClutterStage *stage, + ClutterStageView *view, + cairo_region_t *redraw_clip, + gpointer data) { + CoglFramebuffer *fb = clutter_stage_view_get_framebuffer (view); gboolean *was_painted = data; /* old shader effect */ - g_assert_cmpint (get_pixel (50, 50), ==, 0xff0000); + g_assert_cmpint (get_pixel (fb, 0, 25), ==, 0xff0000); /* new shader effect */ - g_assert_cmpint (get_pixel (150, 50), ==, 0x00ffff); + g_assert_cmpint (get_pixel (fb, 100, 25), ==, 0x00ffff); /* another new shader effect */ - g_assert_cmpint (get_pixel (250, 50), ==, 0xff00ff); + g_assert_cmpint (get_pixel (fb, 200, 25), ==, 0xff00ff); /* new shader effect */ - g_assert_cmpint (get_pixel (350, 50), ==, 0x00ffff); + g_assert_cmpint (get_pixel (fb, 300, 25), ==, 0x00ffff); *was_painted = TRUE; } @@ -271,9 +280,9 @@ actor_shader_effect (void) clutter_actor_show (stage); was_painted = FALSE; - g_signal_connect (stage, "after-paint", - G_CALLBACK (paint_cb), - &was_painted); + g_signal_connect_after (stage, "paint-view", + G_CALLBACK (view_painted_cb), + &was_painted); while (!was_painted) g_main_context_iteration (NULL, FALSE); diff --git a/clutter/tests/conform/actor-size.c b/src/tests/clutter/conform/actor-size.c similarity index 99% rename from clutter/tests/conform/actor-size.c rename to src/tests/clutter/conform/actor-size.c index 7245f157d..0d909f028 100644 --- a/clutter/tests/conform/actor-size.c +++ b/src/tests/clutter/conform/actor-size.c @@ -3,6 +3,8 @@ #include <clutter/clutter.h> +#include "tests/clutter-test-utils.h" + #define TEST_TYPE_ACTOR (test_actor_get_type ()) typedef struct _TestActor TestActor; diff --git a/clutter/tests/conform/binding-pool.c b/src/tests/clutter/conform/binding-pool.c similarity index 92% rename from clutter/tests/conform/binding-pool.c rename to src/tests/clutter/conform/binding-pool.c index 4e4752b6b..a14ea573e 100644 --- a/clutter/tests/conform/binding-pool.c +++ b/src/tests/clutter/conform/binding-pool.c @@ -2,6 +2,8 @@ #include <clutter/clutter.h> +#include "tests/clutter-test-utils.h" + #define TYPE_KEY_GROUP (key_group_get_type ()) #define KEY_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_KEY_GROUP, KeyGroup)) #define IS_KEY_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_KEY_GROUP)) @@ -130,13 +132,23 @@ key_group_key_press (ClutterActor *actor, } static void -key_group_paint (ClutterActor *actor) +key_group_paint (ClutterActor *actor, + ClutterPaintContext *paint_context) { KeyGroup *self = KEY_GROUP (actor); + CoglContext *ctx = + clutter_backend_get_cogl_context (clutter_get_default_backend ()); ClutterActorIter iter; ClutterActor *child; + CoglPipeline *pipeline; + CoglFramebuffer *framebuffer; gint i = 0; + pipeline = cogl_pipeline_new (ctx); + cogl_pipeline_set_color4ub (pipeline, 255, 255, 0, 224); + + framebuffer = clutter_paint_context_get_framebuffer (paint_context); + clutter_actor_iter_init (&iter, actor); while (clutter_actor_iter_next (&iter, &child)) { @@ -152,12 +164,14 @@ key_group_paint (ClutterActor *actor) box.x2 += 2; box.y2 += 2; - cogl_set_source_color4ub (255, 255, 0, 224); - cogl_rectangle (box.x1, box.y1, box.x2, box.y2); + cogl_framebuffer_draw_rectangle (framebuffer, pipeline, + box.x1, box.y1, box.x2, box.y2); } - clutter_actor_paint (child); + clutter_actor_paint (child, paint_context); } + + cogl_object_unref (pipeline); } static void diff --git a/clutter/tests/conform/cally-text.c b/src/tests/clutter/conform/cally-text.c similarity index 99% rename from clutter/tests/conform/cally-text.c rename to src/tests/clutter/conform/cally-text.c index b6e4f70bf..32d7afb70 100644 --- a/clutter/tests/conform/cally-text.c +++ b/src/tests/clutter/conform/cally-text.c @@ -189,7 +189,7 @@ check_result (CallbackData *data) dump_attribute_set (attrs); } - free (text); + g_free (text); text = NULL; if (fail) @@ -235,7 +235,7 @@ build_attribute_set (const gchar* first_attribute, ...) { if ((i> 0) && (i % 2 != 0)) { - AtkAttribute *at = malloc (sizeof (AtkAttribute)); + AtkAttribute *at = g_malloc (sizeof (AtkAttribute)); at->name = g_strdup (name); at->value = g_strdup (value); return_set = g_slist_prepend (return_set, at); diff --git a/clutter/tests/conform/color.c b/src/tests/clutter/conform/color.c similarity index 99% rename from clutter/tests/conform/color.c rename to src/tests/clutter/conform/color.c index 220d9b7de..f8a860b32 100644 --- a/clutter/tests/conform/color.c +++ b/src/tests/clutter/conform/color.c @@ -1,5 +1,7 @@ #include <clutter/clutter.h> +#include "tests/clutter-test-utils.h" + static void color_hls_roundtrip (void) { @@ -251,7 +253,7 @@ color_to_string (void) str = clutter_color_to_string (&color); g_assert_cmpstr (str, ==, "#cccccc22"); - free (str); + g_free (str); } static void diff --git a/clutter/tests/conform/group.c b/src/tests/clutter/conform/group.c similarity index 97% rename from clutter/tests/conform/group.c rename to src/tests/clutter/conform/group.c index 3f7b1fb4b..a1eaf7eb7 100644 --- a/clutter/tests/conform/group.c +++ b/src/tests/clutter/conform/group.c @@ -1,6 +1,8 @@ #define CLUTTER_DISABLE_DEPRECATION_WARNINGS #include <clutter/clutter.h> +#include "tests/clutter-test-utils.h" + static void group_depth_sorting (void) { diff --git a/clutter/tests/conform/interval.c b/src/tests/clutter/conform/interval.c similarity index 98% rename from clutter/tests/conform/interval.c rename to src/tests/clutter/conform/interval.c index ac93ad891..468f21312 100644 --- a/clutter/tests/conform/interval.c +++ b/src/tests/clutter/conform/interval.c @@ -1,5 +1,7 @@ #include <clutter/clutter.h> +#include "tests/clutter-test-utils.h" + static void interval_initial_state (void) { @@ -107,7 +109,7 @@ interval_from_script (void) g_assert (G_VALUE_HOLDS (final, CLUTTER_TYPE_COLOR)); g_object_unref (script); - free (test_file); + g_free (test_file); } CLUTTER_TEST_SUITE ( diff --git a/src/tests/clutter/conform/meson.build b/src/tests/clutter/conform/meson.build new file mode 100644 index 000000000..320b00cf4 --- /dev/null +++ b/src/tests/clutter/conform/meson.build @@ -0,0 +1,79 @@ +clutter_tests_conform_c_args = [ + '-DG_LOG_DOMAIN="Clutter-Conform"', + '-DCOGL_DISABLE_DEPRECATION_WARNINGS', +] +clutter_tests_conform_c_args += clutter_debug_c_args + +clutter_tests_conform_link_args = [ + '-Wl,--export-dynamic', +] + +clutter_conform_tests_actor_tests = [ + 'actor-anchors', + 'actor-clone', + 'actor-destroy', + 'actor-graph', + 'actor-invariants', + 'actor-iter', + 'actor-layout', + 'actor-meta', + 'actor-offscreen-redirect', + 'actor-paint-opacity', + 'actor-pick', + 'actor-shader-effect', + 'actor-size', +] + +clutter_conform_tests_classes_tests = [ + 'text', +] + +clutter_conform_tests_general_tests = [ + 'binding-pool', + 'color', + 'interval', + 'script-parser', + 'units', +] + +clutter_conform_tests_deprecated_tests = [ + 'group', + 'rectangle', +] + +clutter_conform_tests = [] +clutter_conform_tests += clutter_conform_tests_actor_tests +clutter_conform_tests += clutter_conform_tests_classes_tests +clutter_conform_tests += clutter_conform_tests_general_tests +clutter_conform_tests += clutter_conform_tests_deprecated_tests + +test_env = environment() +test_env.set('G_TEST_SRCDIR', meson.current_source_dir()) +test_env.set('G_TEST_BUILDDIR', meson.current_build_dir()) +test_env.set('G_ENABLE_DIAGNOSTIC', '0') +test_env.set('CLUTTER_ENABLE_DIAGNOSTIC', '0') +test_env.set('CLUTTER_SCALE', '1') + +foreach test : clutter_conform_tests + test_executable = executable('@0@'.format(test), + sources: [ + '@0@.c'.format(test), + clutter_test_utils, + ], + include_directories: clutter_includes, + c_args: clutter_tests_conform_c_args, + link_args: clutter_tests_conform_link_args, + dependencies: [ + clutter_deps, + libmutter_clutter_dep, + libmutter_cogl_path_dep, + libmutter_dep + ], + install: false, + ) + + test(test, test_executable, + suite: ['clutter', 'clutter/conform'], + env: test_env + ) +endforeach diff --git a/clutter/tests/conform/path.c b/src/tests/clutter/conform/path.c similarity index 99% rename from clutter/tests/conform/path.c rename to src/tests/clutter/conform/path.c index 6f1d3a4ed..b292ac9da 100644 --- a/clutter/tests/conform/path.c +++ b/src/tests/clutter/conform/path.c @@ -389,8 +389,8 @@ path_test_get_description (CallbackData *data) if (strcmp (desc1, desc2)) ret = FALSE; - free (desc1); - free (desc2); + g_free (desc1); + g_free (desc2); return ret; } diff --git a/clutter/tests/conform/rectangle.c b/src/tests/clutter/conform/rectangle.c similarity index 97% rename from clutter/tests/conform/rectangle.c rename to src/tests/clutter/conform/rectangle.c index 1c09f00b7..588c73a10 100644 --- a/clutter/tests/conform/rectangle.c +++ b/src/tests/clutter/conform/rectangle.c @@ -1,6 +1,8 @@ #define CLUTTER_DISABLE_DEPRECATION_WARNINGS #include <clutter/clutter.h> +#include "tests/clutter-test-utils.h" + static void rectangle_set_size (void) { diff --git a/clutter/tests/conform/script-parser.c b/src/tests/clutter/conform/script-parser.c similarity index 90% rename from clutter/tests/conform/script-parser.c rename to src/tests/clutter/conform/script-parser.c index b14b87086..b51db38d6 100644 --- a/clutter/tests/conform/script-parser.c +++ b/src/tests/clutter/conform/script-parser.c @@ -4,6 +4,8 @@ #define CLUTTER_DISABLE_DEPRECATION_WARNINGS #include <clutter/clutter.h> +#include "tests/clutter-test-utils.h" + #define TEST_TYPE_GROUP (test_group_get_type ()) #define TEST_TYPE_GROUP_META (test_group_meta_get_type ()) @@ -160,7 +162,7 @@ script_child (void) g_assert (!focus_ret); g_object_unref (script); - free (test_file); + g_free (test_file); } static void @@ -193,45 +195,7 @@ script_single (void) g_assert_cmpint (color.alpha, ==, 0xff); g_object_unref (script); - free (test_file); -} - -static void -script_implicit_alpha (void) -{ - ClutterScript *script = clutter_script_new (); - ClutterTimeline *timeline; - GObject *behaviour = NULL; - GError *error = NULL; - ClutterAlpha *alpha; - gchar *test_file; - - test_file = g_test_build_filename (G_TEST_DIST, "scripts", "test-script-implicit-alpha.json", NULL); - clutter_script_load_from_file (script, test_file, &error); - if (g_test_verbose () && error) - g_print ("Error: %s", error->message); - -#if GLIB_CHECK_VERSION (2, 20, 0) - g_assert_no_error (error); -#else - g_assert (error == NULL); -#endif - - behaviour = clutter_script_get_object (script, "test"); - g_assert (CLUTTER_IS_BEHAVIOUR (behaviour)); - - alpha = clutter_behaviour_get_alpha (CLUTTER_BEHAVIOUR (behaviour)); - g_assert (CLUTTER_IS_ALPHA (alpha)); - - g_assert_cmpint (clutter_alpha_get_mode (alpha), ==, CLUTTER_EASE_OUT_CIRC); - - timeline = clutter_alpha_get_timeline (alpha); - g_assert (CLUTTER_IS_TIMELINE (timeline)); - - g_assert_cmpint (clutter_timeline_get_duration (timeline), ==, 500); - - g_object_unref (script); - free (test_file); + g_free (test_file); } static void @@ -257,7 +221,7 @@ script_object_property (void) g_assert (CLUTTER_IS_BIN_LAYOUT (manager)); g_object_unref (script); - free (test_file); + g_free (test_file); } static void @@ -284,7 +248,7 @@ script_named_object (void) g_assert (clutter_box_layout_get_vertical (CLUTTER_BOX_LAYOUT (manager))); g_object_unref (script); - free (test_file); + g_free (test_file); } static void @@ -306,7 +270,7 @@ script_animation (void) g_assert (CLUTTER_IS_ANIMATION (animation)); g_object_unref (script); - free (test_file); + g_free (test_file); } static void @@ -412,7 +376,7 @@ script_margin (void) g_assert_cmpfloat (clutter_actor_get_margin_left (actor), ==, 40.0f); g_object_unref (script); - free (test_file); + g_free (test_file); } CLUTTER_TEST_SUITE ( @@ -420,7 +384,6 @@ CLUTTER_TEST_SUITE ( CLUTTER_TEST_UNIT ("/script/container-child", script_child) CLUTTER_TEST_UNIT ("/script/named-object", script_named_object) CLUTTER_TEST_UNIT ("/script/animation", script_animation) - CLUTTER_TEST_UNIT ("/script/implicit-alpha", script_implicit_alpha) CLUTTER_TEST_UNIT ("/script/object-property", script_object_property) CLUTTER_TEST_UNIT ("/script/layout-property", script_layout_property) CLUTTER_TEST_UNIT ("/script/actor-margin", script_margin) diff --git a/clutter/tests/conform/scripts/test-animator-1.json b/src/tests/clutter/conform/scripts/test-animator-1.json similarity index 100% rename from clutter/tests/conform/scripts/test-animator-1.json rename to src/tests/clutter/conform/scripts/test-animator-1.json diff --git a/clutter/tests/conform/scripts/test-animator-2.json b/src/tests/clutter/conform/scripts/test-animator-2.json similarity index 100% rename from clutter/tests/conform/scripts/test-animator-2.json rename to src/tests/clutter/conform/scripts/test-animator-2.json diff --git a/clutter/tests/conform/scripts/test-animator-3.json b/src/tests/clutter/conform/scripts/test-animator-3.json similarity index 100% rename from clutter/tests/conform/scripts/test-animator-3.json rename to src/tests/clutter/conform/scripts/test-animator-3.json diff --git a/clutter/tests/conform/scripts/test-script-animation.json b/src/tests/clutter/conform/scripts/test-script-animation.json similarity index 100% rename from clutter/tests/conform/scripts/test-script-animation.json rename to src/tests/clutter/conform/scripts/test-script-animation.json diff --git a/clutter/tests/conform/scripts/test-script-child.json b/src/tests/clutter/conform/scripts/test-script-child.json similarity index 100% rename from clutter/tests/conform/scripts/test-script-child.json rename to src/tests/clutter/conform/scripts/test-script-child.json diff --git a/clutter/tests/conform/scripts/test-script-interval.json b/src/tests/clutter/conform/scripts/test-script-interval.json similarity index 100% rename from clutter/tests/conform/scripts/test-script-interval.json rename to src/tests/clutter/conform/scripts/test-script-interval.json diff --git a/clutter/tests/conform/scripts/test-script-layout-property.json b/src/tests/clutter/conform/scripts/test-script-layout-property.json similarity index 100% rename from clutter/tests/conform/scripts/test-script-layout-property.json rename to src/tests/clutter/conform/scripts/test-script-layout-property.json diff --git a/clutter/tests/conform/scripts/test-script-margin.json b/src/tests/clutter/conform/scripts/test-script-margin.json similarity index 100% rename from clutter/tests/conform/scripts/test-script-margin.json rename to src/tests/clutter/conform/scripts/test-script-margin.json diff --git a/clutter/tests/conform/scripts/test-script-model.json b/src/tests/clutter/conform/scripts/test-script-model.json similarity index 100% rename from clutter/tests/conform/scripts/test-script-model.json rename to src/tests/clutter/conform/scripts/test-script-model.json diff --git a/clutter/tests/conform/scripts/test-script-named-object.json b/src/tests/clutter/conform/scripts/test-script-named-object.json similarity index 100% rename from clutter/tests/conform/scripts/test-script-named-object.json rename to src/tests/clutter/conform/scripts/test-script-named-object.json diff --git a/clutter/tests/conform/scripts/test-script-object-property.json b/src/tests/clutter/conform/scripts/test-script-object-property.json similarity index 100% rename from clutter/tests/conform/scripts/test-script-object-property.json rename to src/tests/clutter/conform/scripts/test-script-object-property.json diff --git a/clutter/tests/conform/scripts/test-script-single.json b/src/tests/clutter/conform/scripts/test-script-single.json similarity index 100% rename from clutter/tests/conform/scripts/test-script-single.json rename to src/tests/clutter/conform/scripts/test-script-single.json diff --git a/clutter/tests/conform/scripts/test-script-timeline-markers.json b/src/tests/clutter/conform/scripts/test-script-timeline-markers.json similarity index 100% rename from clutter/tests/conform/scripts/test-script-timeline-markers.json rename to src/tests/clutter/conform/scripts/test-script-timeline-markers.json diff --git a/clutter/tests/conform/scripts/test-state-1.json b/src/tests/clutter/conform/scripts/test-state-1.json similarity index 100% rename from clutter/tests/conform/scripts/test-state-1.json rename to src/tests/clutter/conform/scripts/test-state-1.json diff --git a/clutter/tests/conform/state.c b/src/tests/clutter/conform/state.c similarity index 99% rename from clutter/tests/conform/state.c rename to src/tests/clutter/conform/state.c index 55fa7c1fc..7e4720dc5 100644 --- a/clutter/tests/conform/state.c +++ b/src/tests/clutter/conform/state.c @@ -19,7 +19,7 @@ state_base (TestConformSimpleFixture *fixture G_GNUC_UNUSED, if (g_test_verbose () && error) g_print ("Error: %s\n", error->message); - free (test_file); + g_free (test_file); #if GLIB_CHECK_VERSION (2, 20, 0) g_assert_no_error (error); @@ -45,7 +45,7 @@ state_base (TestConformSimpleFixture *fixture G_GNUC_UNUSED, keys = clutter_state_get_keys (CLUTTER_STATE (state), "base", "clicked", clutter_script_get_object (script, "rect"), "opacity"); - + g_assert (keys != NULL); g_assert_cmpint (g_list_length (keys), ==, 1); @@ -65,7 +65,7 @@ state_base (TestConformSimpleFixture *fixture G_GNUC_UNUSED, keys = clutter_state_get_keys (CLUTTER_STATE (state), "base", "clicked", NULL, NULL); - + g_assert (keys != NULL); g_assert_cmpint (g_list_length (keys), ==, 2); g_list_free (keys); diff --git a/clutter/tests/conform/text-cache.c b/src/tests/clutter/conform/text-cache.c similarity index 98% rename from clutter/tests/conform/text-cache.c rename to src/tests/clutter/conform/text-cache.c index 6b4bddf78..748101eab 100644 --- a/clutter/tests/conform/text-cache.c +++ b/src/tests/clutter/conform/text-cache.c @@ -28,7 +28,9 @@ struct _CallbackData }; static void -on_paint (ClutterActor *stage, CallbackData *data) +on_paint (ClutterActor *stage, + ClutterPaintContext *paint_context, + CallbackData *data) { PangoLayout *new_layout; diff --git a/clutter/tests/conform/text.c b/src/tests/clutter/conform/text.c similarity index 96% rename from clutter/tests/conform/text.c rename to src/tests/clutter/conform/text.c index ee5b49d1d..ebe4b7bb1 100644 --- a/clutter/tests/conform/text.c +++ b/src/tests/clutter/conform/text.c @@ -2,6 +2,8 @@ #include <clutter/clutter.h> #include <string.h> +#include "tests/clutter-test-utils.h" + typedef struct { gunichar unichar; const char bytes[6]; @@ -256,19 +258,19 @@ text_get_chars (void) chars = clutter_text_get_chars (text, 2, -1); g_assert_cmpstr (chars, ==, "abcdef11"); - free (chars); + g_free (chars); chars = clutter_text_get_chars (text, 0, 8); g_assert_cmpstr (chars, ==, "00abcdef"); - free (chars); + g_free (chars); chars = clutter_text_get_chars (text, 2, 8); g_assert_cmpstr (chars, ==, "abcdef"); - free (chars); + g_free (chars); chars = clutter_text_get_chars (text, 8, 12); g_assert_cmpstr (chars, ==, "11"); - free (chars); + g_free (chars); clutter_actor_destroy (CLUTTER_ACTOR (text)); } @@ -468,6 +470,19 @@ validate_markup_attributes (ClutterText *text, a = attributes->data; + if (a->klass->type == PANGO_ATTR_SCALE) + { + PangoAttrFloat *scale = (PangoAttrFloat*) a; + float resource_scale; + + if (!clutter_actor_get_resource_scale (CLUTTER_ACTOR (text), &resource_scale)) + resource_scale = 1.0; + + g_assert_cmpfloat (scale->value, ==, resource_scale); + g_slist_free_full (attributes, (GDestroyNotify) pango_attribute_destroy); + continue; + } + g_assert (a->klass->type == attr_type); g_assert_cmpint (a->start_index, ==, start_index); g_assert_cmpint (a->end_index, ==, end_index); diff --git a/clutter/tests/conform/texture-fbo.c b/src/tests/clutter/conform/texture-fbo.c similarity index 97% rename from clutter/tests/conform/texture-fbo.c rename to src/tests/clutter/conform/texture-fbo.c index 21a6f530a..ac70ebc67 100644 --- a/clutter/tests/conform/texture-fbo.c +++ b/src/tests/clutter/conform/texture-fbo.c @@ -107,7 +107,7 @@ validate_part (TestState *state, g_assert_cmpint (pixels[1], ==, correct_color->green); g_assert_cmpint (pixels[2], ==, correct_color->blue); - free (pixels); + g_free (pixels); } } @@ -165,14 +165,6 @@ texture_fbo (TestConformSimpleFixture *fixture, ClutterActor *actor; int ypos = 0; - if (!cogl_features_available (COGL_FEATURE_OFFSCREEN)) - { - if (g_test_verbose ()) - g_print ("Offscreen buffers are not available, skipping.\n"); - - return; - } - state.frame = 0; state.stage = clutter_stage_new (); diff --git a/clutter/tests/conform/timeline-interpolate.c b/src/tests/clutter/conform/timeline-interpolate.c similarity index 93% rename from clutter/tests/conform/timeline-interpolate.c rename to src/tests/clutter/conform/timeline-interpolate.c index 5eab888b3..3988c038d 100644 --- a/clutter/tests/conform/timeline-interpolate.c +++ b/src/tests/clutter/conform/timeline-interpolate.c @@ -18,7 +18,7 @@ typedef struct _TestState { ClutterTimeline *timeline; - GTimeVal start_time; + int64_t start_time; guint new_frame_counter; gint expected_frame; gint completion_count; @@ -31,18 +31,17 @@ new_frame_cb (ClutterTimeline *timeline, gint frame_num, TestState *state) { - GTimeVal current_time; + int64_t current_time; gint current_frame; glong msec_diff; gint loop_overflow = 0; static gint step = 1; - g_get_current_time (¤t_time); + current_time = g_get_real_time (); current_frame = clutter_timeline_get_elapsed_time (state->timeline); - msec_diff = (current_time.tv_sec - state->start_time.tv_sec) * 1000; - msec_diff += (current_time.tv_usec - state->start_time.tv_usec)/1000; + msec_diff = (current_time - state->start_time) / G_TIME_SPAN_MILLISECOND; /* If we expect to have interpolated past the end of the timeline * we keep track of the overflow so we can determine when @@ -153,7 +152,7 @@ timeline_interpolation (void) state.passed = TRUE; state.expected_frame = 0; - g_get_current_time (&state.start_time); + state.start_time = g_get_real_time (); clutter_timeline_start (state.timeline); clutter_main(); diff --git a/clutter/tests/conform/timeline-progress.c b/src/tests/clutter/conform/timeline-progress.c similarity index 100% rename from clutter/tests/conform/timeline-progress.c rename to src/tests/clutter/conform/timeline-progress.c diff --git a/clutter/tests/conform/timeline-rewind.c b/src/tests/clutter/conform/timeline-rewind.c similarity index 100% rename from clutter/tests/conform/timeline-rewind.c rename to src/tests/clutter/conform/timeline-rewind.c diff --git a/clutter/tests/conform/timeline.c b/src/tests/clutter/conform/timeline.c similarity index 98% rename from clutter/tests/conform/timeline.c rename to src/tests/clutter/conform/timeline.c index e07549e96..283db7001 100644 --- a/clutter/tests/conform/timeline.c +++ b/src/tests/clutter/conform/timeline.c @@ -38,8 +38,7 @@ timeline_data_init (TimelineData *data, int timeline_num) static void timeline_data_destroy (TimelineData *data) { - g_slist_foreach (data->markers_hit, (GFunc) free, NULL); - g_slist_free (data->markers_hit); + g_slist_free_full (data->markers_hit, g_free); } static void @@ -159,7 +158,7 @@ check_timeline (ClutterTimeline *timeline, } g_strfreev (markers); - free (marker_reached_count); + g_free (marker_reached_count); return succeeded; } @@ -314,7 +313,7 @@ timeline_base (TestConformSimpleFixture *fixture, timeline_data_destroy (&data_2); timeline_data_destroy (&data_3); - g_source_remove (delay_tag); + g_clear_handle_id (&delay_tag, g_source_remove); clutter_actor_destroy (stage); } @@ -358,5 +357,5 @@ timeline_markers_from_script (TestConformSimpleFixture *fixture, g_object_unref (script); - free (test_file); + g_free (test_file); } diff --git a/clutter/tests/conform/units.c b/src/tests/clutter/conform/units.c similarity index 98% rename from clutter/tests/conform/units.c rename to src/tests/clutter/conform/units.c index c37a0f081..bcfb5890d 100644 --- a/clutter/tests/conform/units.c +++ b/src/tests/clutter/conform/units.c @@ -1,5 +1,7 @@ #include <clutter/clutter.h> +#include "tests/clutter-test-utils.h" + static void units_cache (void) { @@ -107,7 +109,7 @@ units_string (void) clutter_units_from_pt (&units, 24.0); string = clutter_units_to_string (&units); g_assert_cmpstr (string, ==, "24.0 pt"); - free (string); + g_free (string); clutter_units_from_em (&units, 3.0); string = clutter_units_to_string (&units); @@ -121,7 +123,7 @@ units_string (void) g_assert (clutter_units_get_unit_type (&units) == CLUTTER_UNIT_EM); g_assert_cmpint ((int) clutter_units_get_unit_value (&units), ==, 3); - free (string); + g_free (string); } CLUTTER_TEST_SUITE ( diff --git a/src/tests/clutter/interactive/meson.build b/src/tests/clutter/interactive/meson.build new file mode 100644 index 000000000..12274768e --- /dev/null +++ b/src/tests/clutter/interactive/meson.build @@ -0,0 +1,84 @@ +clutter_tests_interactive_srcdir = meson.current_source_dir() +clutter_tests_interactive_includepath = include_directories('.') + +clutter_tests_interactive_c_args = [ + '-DTESTS_DATADIR="@0@"'.format(clutter_tests_interactive_srcdir), + '-DG_DISABLE_SINGLE_INCLUDES', + '-DGLIB_DISABLE_DEPRECATION_WARNINGS', + '-DCOGL_DISABLE_DEPRECATION_WARNINGS', + '-DCLUTTER_DISABLE_DEPRECATION_WARNINGS', +] +clutter_tests_interactive_c_args += clutter_debug_c_args + +clutter_tests_interactive_link_args = [ + '-Wl,--export-dynamic', +] + +clutter_tests_interactive_test_sources = [ + 'test-events.c', + 'test-actors.c', + 'test-shader-effects.c', + 'test-script.c', + 'test-grab.c', + 'test-cogl-shader-glsl.c', + 'test-state.c', + 'test-cogl-tex-tile.c', + 'test-cogl-tex-convert.c', + 'test-cogl-offscreen.c', + 'test-cogl-tex-polygon.c', + 'test-cogl-multitexture.c', + 'test-paint-wrapper.c', + 'test-layout.c', + 'test-animation.c', + 'test-easing.c', + 'test-binding-pool.c', + 'test-text.c', + 'test-text-field.c', + 'test-cairo-clock.c', + 'test-cairo-flowers.c', + 'test-stage-sizing.c', + 'test-scrolling.c', + 'test-swipe-action.c', + 'test-cogl-point-sprites.c', + 'test-path-constraint.c', + 'test-state-script.c', + 'test-devices.c', + 'test-content.c', + 'test-keyframe-transition.c', + 'test-bind-constraint.c', + 'test-touch-events.c', + 'test-rotate-zoom.c', + 'test-image.c', +] + +gen_test_unit_names = find_program('meson/gen-test-unit-names.sh') +clutter_interactive_test_unit_names_h = custom_target('gen-test-unit-names', + output: 'test-unit-names.h', + input: clutter_tests_interactive_test_sources, + command: [gen_test_unit_names, '@OUTPUT@', '@INPUT@'], + install: false, +) + +clutter_tests_interactive_sources = [ + 'test-main.c', + clutter_interactive_test_unit_names_h, + clutter_tests_interactive_test_sources +] + +executable('test-interactive', + sources: clutter_tests_interactive_sources, + include_directories: [ + clutter_includes, + clutter_tests_includepath, + clutter_tests_interactive_includepath, + ], + c_args: clutter_tests_interactive_c_args, + link_args: clutter_tests_interactive_link_args, + dependencies: [ + clutter_deps, + libmutter_clutter_dep, + libmutter_dep, + gdk_pixbuf_dep, + ], + install: false, +) diff --git a/src/tests/clutter/interactive/meson/gen-test-unit-names.sh b/src/tests/clutter/interactive/meson/gen-test-unit-names.sh new file mode 100755 index 000000000..72c5bf362 --- /dev/null +++ b/src/tests/clutter/interactive/meson/gen-test-unit-names.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +outputfile=$1 +shift + +echo '/* ** This file is autogenerated. Do not edit. ** */' > "$outputfile" +echo '' >> "$outputfile" +echo 'const char *test_unit_names[] = {' >> "$outputfile" + +for test_source_file in "$@"; do + echo " \"$(echo "$test_source_file" | sed 's/.*\(test-[a-z0-9\-]\+\)\.c/\1/')\"," >> "$outputfile" +done + +echo '};' >> "$outputfile" diff --git a/clutter/examples/redhand.png b/src/tests/clutter/interactive/redhand.png similarity index 100% rename from clutter/examples/redhand.png rename to src/tests/clutter/interactive/redhand.png diff --git a/clutter/tests/interactive/test-actors.c b/src/tests/clutter/interactive/test-actors.c similarity index 87% rename from clutter/tests/interactive/test-actors.c rename to src/tests/clutter/interactive/test-actors.c index e70537f9f..20edc8517 100644 --- a/clutter/tests/interactive/test-actors.c +++ b/src/tests/clutter/interactive/test-actors.c @@ -6,6 +6,8 @@ #include <glib.h> #include <gmodule.h> +#include "test-utils.h" + #define NHANDS 6 typedef struct SuperOH @@ -20,13 +22,14 @@ typedef struct SuperOH gint stage_height; gfloat radius; - ClutterBehaviour *scaler_1; - ClutterBehaviour *scaler_2; ClutterTimeline *timeline; } SuperOH; static gint n_hands = NHANDS; +int +test_actors_main (int argc, char *argv[]); + static GOptionEntry super_oh_entries[] = { { "num-hands", 'n', @@ -152,20 +155,9 @@ stop_and_quit (ClutterActor *stage, clutter_main_quit (); } -static gdouble -my_sine_wave (ClutterAlpha *alpha, - gpointer dummy G_GNUC_UNUSED) -{ - ClutterTimeline *timeline = clutter_alpha_get_timeline (alpha); - gdouble progress = clutter_timeline_get_progress (timeline); - - return sin (progress * G_PI); -} - G_MODULE_EXPORT int test_actors_main (int argc, char *argv[]) { - ClutterAlpha *alpha; SuperOH *oh; gint i; GError *error; @@ -196,7 +188,6 @@ test_actors_main (int argc, char *argv[]) g_signal_connect (oh->stage, "destroy", G_CALLBACK (stop_and_quit), oh); clutter_stage_set_title (CLUTTER_STAGE (oh->stage), "Actors"); - clutter_stage_set_user_resizable (CLUTTER_STAGE (oh->stage), TRUE); /* Create a timeline to manage animation */ oh->timeline = clutter_timeline_new (6000); @@ -205,18 +196,12 @@ test_actors_main (int argc, char *argv[]) /* fire a callback for frame change */ g_signal_connect (oh->timeline, "new-frame", G_CALLBACK (frame_cb), oh); - /* Set up some behaviours to handle scaling */ - alpha = clutter_alpha_new_with_func (oh->timeline, my_sine_wave, NULL, NULL); - - oh->scaler_1 = clutter_behaviour_scale_new (alpha, 0.5, 0.5, 1.0, 1.0); - oh->scaler_2 = clutter_behaviour_scale_new (alpha, 1.0, 1.0, 0.5, 0.5); - file = g_build_filename (TESTS_DATADIR, "redhand.png", NULL); - real_hand = clutter_texture_new_from_file (file, &error); + real_hand = clutter_test_utils_create_texture_from_file (file, &error); if (real_hand == NULL) g_error ("image load failed: %s", error->message); - free (file); + g_free (file); /* create a new actor to hold other actors */ oh->group = clutter_actor_new (); @@ -281,11 +266,6 @@ test_actors_main (int argc, char *argv[]) g_signal_connect (oh->hand[i], "destroy", G_CALLBACK (on_hand_destroy), oh); - - if (i % 2) - clutter_behaviour_apply (oh->scaler_1, oh->hand[i]); - else - clutter_behaviour_apply (oh->scaler_2, oh->hand[i]); } /* Add the group to the stage */ @@ -306,11 +286,9 @@ test_actors_main (int argc, char *argv[]) clutter_timeline_stop (oh->timeline); /* clean up */ - g_object_unref (oh->scaler_1); - g_object_unref (oh->scaler_2); g_object_unref (oh->timeline); - free (oh->hand); - free (oh); + g_free (oh->hand); + g_free (oh); return EXIT_SUCCESS; } diff --git a/clutter/tests/interactive/test-animation.c b/src/tests/clutter/interactive/test-animation.c similarity index 97% rename from clutter/tests/interactive/test-animation.c rename to src/tests/clutter/interactive/test-animation.c index 5d4aa4e6e..dbd5e5876 100644 --- a/clutter/tests/interactive/test-animation.c +++ b/src/tests/clutter/interactive/test-animation.c @@ -4,6 +4,12 @@ static gboolean is_expanded = FALSE; +int +test_animation_main (int argc, char *argv[]); + +const char * +test_animation_describe (void); + static void on_rect_transitions_completed (ClutterActor *actor) { @@ -19,7 +25,6 @@ on_clicked (ClutterClickAction *action, ClutterActor *actor, gpointer dummy G_GNUC_UNUSED) { - ClutterAnimation *animation; gfloat old_x, old_y, new_x, new_y; gfloat old_width, old_height, new_width, new_height; gdouble new_angle; @@ -82,7 +87,6 @@ G_MODULE_EXPORT int test_animation_main (int argc, char *argv[]) { ClutterActor *stage, *rect; - ClutterColor rect_color = { 0x44, 0xdd, 0x44, 0xff }; ClutterAction *action; if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) diff --git a/clutter/tests/interactive/test-bind-constraint.c b/src/tests/clutter/interactive/test-bind-constraint.c similarity index 98% rename from clutter/tests/interactive/test-bind-constraint.c rename to src/tests/clutter/interactive/test-bind-constraint.c index 6cceebad7..f8df31b02 100644 --- a/clutter/tests/interactive/test-bind-constraint.c +++ b/src/tests/clutter/interactive/test-bind-constraint.c @@ -47,6 +47,12 @@ static const gchar *desaturare_glsl_shader = static gboolean is_expanded = FALSE; +const char * +test_bind_constraint_describe (void); + +int +test_bind_constraint_main (int argc, char *argv[]); + static gboolean on_button_release (ClutterActor *actor, ClutterEvent *event, @@ -175,7 +181,6 @@ test_bind_constraint_main (int argc, char *argv[]) stage = clutter_stage_new (); g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); clutter_stage_set_title (CLUTTER_STAGE (stage), "Constraints"); - clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE); clutter_actor_set_size (stage, 800, 600); /* main rectangle */ diff --git a/clutter/tests/interactive/test-binding-pool.c b/src/tests/clutter/interactive/test-binding-pool.c similarity index 92% rename from clutter/tests/interactive/test-binding-pool.c rename to src/tests/clutter/interactive/test-binding-pool.c index 59b42c198..c9ddfe57a 100644 --- a/clutter/tests/interactive/test-binding-pool.c +++ b/src/tests/clutter/interactive/test-binding-pool.c @@ -31,6 +31,14 @@ struct _KeyGroupClass ClutterActor *child); }; +GType key_group_get_type (void); + +int +test_binding_pool_main (int argc, char *argv[]); + +const char * +test_binding_pool_describe (void); + G_DEFINE_TYPE (KeyGroup, key_group, CLUTTER_TYPE_ACTOR) enum @@ -142,12 +150,19 @@ key_group_key_press (ClutterActor *actor, } static void -key_group_paint (ClutterActor *actor) +key_group_paint (ClutterActor *actor, + ClutterPaintContext *paint_context) { KeyGroup *self = KEY_GROUP (actor); ClutterActorIter iter; ClutterActor *child; gint i = 0; + CoglFramebuffer *framebuffer = + clutter_paint_context_get_framebuffer (paint_context); + CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); + CoglPipeline *pipeline; + + pipeline = cogl_pipeline_new (ctx); clutter_actor_iter_init (&iter, actor); while (clutter_actor_iter_next (&iter, &child)) @@ -164,11 +179,13 @@ key_group_paint (ClutterActor *actor) box.x2 += 2; box.y2 += 2; - cogl_set_source_color4ub (255, 255, 0, 224); - cogl_rectangle (box.x1, box.y1, box.x2, box.y2); + cogl_pipeline_set_color4ub (pipeline, 255, 255, 0, 224); + + cogl_framebuffer_draw_rectangle (framebuffer, pipeline, + box.x1, box.y1, box.x2, box.y2); } - clutter_actor_paint (child); + clutter_actor_paint (child, paint_context); i += 1; } diff --git a/clutter/tests/interactive/test-cairo-clock.c b/src/tests/clutter/interactive/test-cairo-clock.c similarity index 97% rename from clutter/tests/interactive/test-cairo-clock.c rename to src/tests/clutter/interactive/test-cairo-clock.c index fa5166e02..931282b02 100644 --- a/clutter/tests/interactive/test-cairo-clock.c +++ b/src/tests/clutter/interactive/test-cairo-clock.c @@ -3,6 +3,12 @@ #include <cairo.h> #include <clutter/clutter.h> +int +test_cairo_clock_main (int argc, char *argv[]); + +const char * +test_cairo_clock_describe (void); + static gboolean draw_clock (ClutterCanvas *canvas, cairo_t *cr, @@ -85,7 +91,6 @@ test_cairo_clock_main (int argc, char *argv[]) /* create a resizable stage */ stage = clutter_stage_new (); clutter_stage_set_title (CLUTTER_STAGE (stage), "2D Clock"); - clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE); clutter_actor_set_background_color (stage, CLUTTER_COLOR_LightSkyBlue); clutter_actor_set_size (stage, 300, 300); clutter_actor_show (stage); diff --git a/clutter/tests/interactive/test-cairo-flowers.c b/src/tests/clutter/interactive/test-cairo-flowers.c similarity index 98% rename from clutter/tests/interactive/test-cairo-flowers.c rename to src/tests/clutter/interactive/test-cairo-flowers.c index 2594d686b..6f60784bb 100644 --- a/clutter/tests/interactive/test-cairo-flowers.c +++ b/src/tests/clutter/interactive/test-cairo-flowers.c @@ -25,6 +25,12 @@ Flower; static ClutterActor *stage = NULL; +int +test_cairo_flowers_main (int argc, char **argv); + +const char * +test_cairo_flowers_describe (void); + static gboolean draw_flower (ClutterCanvas *canvas, cairo_t *cr, diff --git a/clutter/tests/interactive/test-cogl-multitexture.c b/src/tests/clutter/interactive/test-cogl-multitexture.c similarity index 80% rename from clutter/tests/interactive/test-cogl-multitexture.c rename to src/tests/clutter/interactive/test-cogl-multitexture.c index d503190e0..5d33e40e3 100644 --- a/clutter/tests/interactive/test-cogl-multitexture.c +++ b/src/tests/clutter/interactive/test-cogl-multitexture.c @@ -30,6 +30,11 @@ typedef struct _TestMultiLayerMaterialState } TestMultiLayerMaterialState; +int +test_cogl_multitexture_main (int argc, char *argv[]); + +const char * +test_cogl_multitexture_describe (void); static void frame_cb (ClutterTimeline *timeline, @@ -50,25 +55,31 @@ frame_cb (ClutterTimeline *timeline, } static void -material_rectangle_paint (ClutterActor *actor, gpointer data) +material_rectangle_paint (ClutterActor *actor, + ClutterPaintContext *paint_context, + gpointer data) { TestMultiLayerMaterialState *state = data; - - cogl_push_matrix (); - - cogl_translate (150, 15, 0); - - cogl_set_source (state->material0); - cogl_rectangle_with_multitexture_coords (0, 0, 200, 213, - state->tex_coords, - 12); - cogl_translate (-300, -30, 0); - cogl_set_source (state->material1); - cogl_rectangle_with_multitexture_coords (0, 0, 200, 213, - state->tex_coords, - 12); - - cogl_pop_matrix (); + CoglFramebuffer *framebuffer = + clutter_paint_context_get_framebuffer (paint_context); + + cogl_framebuffer_push_matrix (framebuffer); + + cogl_framebuffer_translate (framebuffer, 150, 15, 0); + + cogl_framebuffer_draw_multitextured_rectangle (framebuffer, + COGL_FRAMEBUFFER (state->material0), + 0, 0, 200, 213, + state->tex_coords, + 12); + cogl_framebuffer_translate (framebuffer, -300, -30, 0); + cogl_framebuffer_draw_multitextured_rectangle (framebuffer, + COGL_FRAMEBUFFER (state->material1), + 0, 0, 200, 213, + state->tex_coords, + 12); + + cogl_framebuffer_pop_matrix (framebuffer); } static void @@ -101,7 +112,7 @@ test_cogl_multitexture_main (int argc, char *argv[]) GError *error = NULL; ClutterActor *stage; ClutterColor stage_color = { 0x61, 0x56, 0x56, 0xff }; - TestMultiLayerMaterialState *state = g_new0 (TestMultiLayerMaterialState, 1); + g_autofree TestMultiLayerMaterialState *state = g_new0 (TestMultiLayerMaterialState, 1); gfloat stage_w, stage_h; gchar **files; gfloat tex_coords[] = @@ -220,13 +231,13 @@ test_cogl_multitexture_main (int argc, char *argv[]) clutter_main(); - cogl_handle_unref (state->material1); - cogl_handle_unref (state->material0); - cogl_handle_unref (state->alpha_tex); - cogl_handle_unref (state->redhand_tex); - cogl_handle_unref (state->light_tex0); - cogl_handle_unref (state->light_tex1); - free (state); + cogl_object_unref (state->material1); + cogl_object_unref (state->material0); + cogl_object_unref (state->alpha_tex); + cogl_object_unref (state->redhand_tex); + cogl_object_unref (state->light_tex0); + cogl_object_unref (state->light_tex1); + g_free (state); return 0; } diff --git a/clutter/tests/interactive/test-cogl-offscreen.c b/src/tests/clutter/interactive/test-cogl-offscreen.c similarity index 70% rename from clutter/tests/interactive/test-cogl-offscreen.c rename to src/tests/clutter/interactive/test-cogl-offscreen.c index b50352c65..bade842d4 100644 --- a/clutter/tests/interactive/test-cogl-offscreen.c +++ b/src/tests/clutter/interactive/test-cogl-offscreen.c @@ -13,7 +13,7 @@ G_BEGIN_DECLS #define TEST_COGLBOX(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ - TEST_TYPE_COGLBOX, TestCoglboxClass)) + TEST_TYPE_COGLBOX, TestCoglbox)) #define TEST_COGLBOX_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), \ @@ -56,16 +56,17 @@ struct _TestCoglboxClass static GType test_coglbox_get_type (void) G_GNUC_CONST; +int +test_cogl_offscreen_main (int argc, char *argv[]); + +const char * +test_cogl_offscreen_describe (void); + G_END_DECLS /* Coglbox private declaration *--------------------------------------------------*/ -G_DEFINE_TYPE (TestCoglbox, test_coglbox, CLUTTER_TYPE_ACTOR); - -#define TEST_COGLBOX_GET_PRIVATE(obj) \ -(G_TYPE_INSTANCE_GET_PRIVATE ((obj), TEST_TYPE_COGLBOX, TestCoglboxPrivate)) - struct _TestCoglboxPrivate { CoglHandle texhand_id; @@ -73,45 +74,60 @@ struct _TestCoglboxPrivate CoglHandle offscreen_id; }; +G_DEFINE_TYPE_WITH_PRIVATE (TestCoglbox, test_coglbox, CLUTTER_TYPE_ACTOR); + +#define TEST_COGLBOX_GET_PRIVATE(obj) \ +(test_coglbox_get_instance_private (TEST_COGLBOX ((obj)))) + /* Coglbox implementation *--------------------------------------------------*/ static void -test_coglbox_paint (ClutterActor *self) +test_coglbox_paint (ClutterActor *self, + ClutterPaintContext *paint_context) { TestCoglboxPrivate *priv = TEST_COGLBOX_GET_PRIVATE (self); + CoglFramebuffer *framebuffer = + clutter_paint_context_get_framebuffer (paint_context); + CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); gfloat texcoords[4] = { 0, 0, 1, 1 }; - CoglHandle material; - - cogl_set_source_color4ub (0x66, 0x66, 0xdd, 0xff); - cogl_rectangle (0, 0, 400, 400); - - cogl_set_source_texture (priv->texhand_id); - cogl_rectangle_with_texture_coords (0, 0, - 400, 400, - 0, 0, - 6, 6); - - cogl_push_framebuffer (priv->offscreen_id); - - cogl_set_source_color4ub (0xff, 0, 0, 0xff); - cogl_rectangle (20, 20, 20 + 100, 20 + 100); - - cogl_set_source_color4ub (0, 0xff, 0, 0xff); - cogl_rectangle (80, 80, 80 + 100, 80 + 100); - - cogl_pop_framebuffer (); - - material = cogl_material_new (); - cogl_material_set_color4ub (material, 0x88, 0x88, 0x88, 0x88); - cogl_material_set_layer (material, 0, priv->texture_id); - cogl_set_source (material); - cogl_rectangle_with_texture_coords (100, 100, - 300, 300, - texcoords[0], - texcoords[1], - texcoords[2], - texcoords[3]); + CoglPipeline *pipeline; + + pipeline = cogl_pipeline_new (ctx); + cogl_pipeline_set_color4ub (pipeline, 0x66, 0x66, 0xdd, 0xff); + cogl_framebuffer_draw_rectangle (framebuffer, pipeline, 0, 0, 400, 400); + cogl_object_unref (pipeline); + + pipeline = cogl_pipeline_new (ctx); + cogl_pipeline_set_layer_texture (pipeline, 0, priv->texhand_id); + cogl_framebuffer_draw_textured_rectangle (framebuffer, pipeline, + 0, 0, + 400, 400, + 0, 0, + 6, 6); + cogl_object_unref (pipeline); + + pipeline = cogl_pipeline_new (ctx); + cogl_pipeline_set_color4ub (pipeline, 0xff, 0, 0, 0xff); + cogl_framebuffer_draw_rectangle (priv->offscreen_id, pipeline, + 20, 20, 20 + 100, 20 + 100); + + cogl_pipeline_set_color4ub (pipeline, 0, 0xff, 0, 0xff); + cogl_framebuffer_draw_rectangle (priv->offscreen_id, pipeline, + 80, 80, 80 + 100, 80 + 100); + cogl_object_unref (pipeline); + + pipeline = cogl_pipeline_new (ctx); + cogl_pipeline_set_color4ub (pipeline, 0x88, 0x88, 0x88, 0x88); + cogl_pipeline_set_layer_texture (pipeline, 0, priv->texture_id); + cogl_framebuffer_draw_textured_rectangle (framebuffer, pipeline, + 100, 100, + 300, 300, + texcoords[0], + texcoords[1], + texcoords[2], + texcoords[3]); + cogl_object_unref (pipeline); } static void @@ -127,8 +143,8 @@ test_coglbox_dispose (GObject *object) priv = TEST_COGLBOX_GET_PRIVATE (object); - cogl_handle_unref (priv->texture_id); - cogl_handle_unref (priv->offscreen_id); + cogl_object_unref (priv->texture_id); + cogl_object_unref (priv->offscreen_id); G_OBJECT_CLASS (test_coglbox_parent_class)->dispose (object); } @@ -153,25 +169,26 @@ test_coglbox_dispose (GObject *object) * This sets up a Clutter like coordinate system for a Cogl * framebuffer */ -void -setup_viewport (unsigned int width, - unsigned int height, - float fovy, - float aspect, - float z_near, - float z_far) +static void +setup_viewport (CoglFramebuffer *framebuffer, + unsigned int width, + unsigned int height, + float fovy, + float aspect, + float z_near, + float z_far) { float z_camera; CoglMatrix projection_matrix; CoglMatrix mv_matrix; - cogl_set_viewport (0, 0, width, height); + cogl_framebuffer_set_viewport (framebuffer, 0, 0, width, height); /* For Ortho projection. * _cogl_matrix_stack_ortho (projection_stack, 0, width, 0, height, -1, 1); */ - cogl_perspective (fovy, aspect, z_near, z_far); + cogl_framebuffer_perspective (framebuffer, fovy, aspect, z_near, z_far); /* * In theory, we can compute the camera distance from screen as: @@ -212,14 +229,14 @@ setup_viewport (unsigned int width, * doesn't make sense. */ - cogl_get_projection_matrix (&projection_matrix); + cogl_framebuffer_get_projection_matrix (framebuffer, &projection_matrix); z_camera = 0.5 * projection_matrix.xx; cogl_matrix_init_identity (&mv_matrix); cogl_matrix_translate (&mv_matrix, -0.5f, -0.5f, -z_camera); cogl_matrix_scale (&mv_matrix, 1.0f / width, -1.0f / height, 1.0f / width); cogl_matrix_translate (&mv_matrix, 0.0f, -1.0 * height, 0.0f); - cogl_set_modelview_matrix (&mv_matrix); + cogl_framebuffer_set_modelview_matrix (framebuffer, &mv_matrix); } static void @@ -240,17 +257,14 @@ test_coglbox_map (ClutterActor *actor) clutter_stage_get_perspective (CLUTTER_STAGE (stage), &perspective); clutter_actor_get_size (stage, &stage_width, &stage_height); - cogl_push_framebuffer (priv->offscreen_id); - - setup_viewport (stage_width, stage_height, + setup_viewport (priv->offscreen_id, + stage_width, stage_height, perspective.fovy, perspective.aspect, perspective.z_near, perspective.z_far); - cogl_pop_framebuffer (); - - if (priv->offscreen_id == COGL_INVALID_HANDLE) + if (priv->offscreen_id == NULL) printf ("Failed creating offscreen to texture!\n"); } @@ -268,14 +282,14 @@ test_coglbox_init (TestCoglbox *self) COGL_TEXTURE_NONE, COGL_PIXEL_FORMAT_ANY, NULL); - free (file); + g_free (file); printf ("Creating texture with size\n"); priv->texture_id = cogl_texture_new_with_size (200, 200, COGL_TEXTURE_NONE, COGL_PIXEL_FORMAT_RGB_888); - if (priv->texture_id == COGL_INVALID_HANDLE) + if (priv->texture_id == NULL) printf ("Failed creating texture with size!\n"); } @@ -290,8 +304,6 @@ test_coglbox_class_init (TestCoglboxClass *klass) actor_class->map = test_coglbox_map; actor_class->paint = test_coglbox_paint; - - g_type_class_add_private (gobject_class, sizeof (TestCoglboxPrivate)); } static ClutterActor* diff --git a/clutter/tests/interactive/test-cogl-point-sprites.c b/src/tests/clutter/interactive/test-cogl-point-sprites.c similarity index 87% rename from clutter/tests/interactive/test-cogl-point-sprites.c rename to src/tests/clutter/interactive/test-cogl-point-sprites.c index de52b3250..e89367083 100644 --- a/clutter/tests/interactive/test-cogl-point-sprites.c +++ b/src/tests/clutter/interactive/test-cogl-point-sprites.c @@ -51,6 +51,12 @@ struct _Data CoglMaterial *material; }; +int +test_cogl_point_sprites_main (int argc, char *argv[]); + +const char * +test_cogl_point_sprites_describe (void); + static CoglHandle generate_round_texture (void) { @@ -58,7 +64,7 @@ generate_round_texture (void) int x, y; CoglHandle tex; - p = data = malloc (TEXTURE_SIZE * TEXTURE_SIZE * 4); + p = data = g_malloc (TEXTURE_SIZE * TEXTURE_SIZE * 4); /* Generate a yellow circle which gets transparent towards the edges */ for (y = 0; y < TEXTURE_SIZE; y++) @@ -83,26 +89,29 @@ generate_round_texture (void) TEXTURE_SIZE * 4, data); - free (data); + g_free (data); return tex; } static void -paint_cb (ClutterActor *stage, Data *data) +paint_cb (ClutterActor *stage, + ClutterPaintContext *paint_context, + Data *data) { + CoglFramebuffer *framebuffer = + clutter_paint_context_get_framebuffer (paint_context); CoglMatrix old_matrix, new_matrix; int i; float diff_time; - CoglHandle vbo; - cogl_get_projection_matrix (&old_matrix); + cogl_framebuffer_get_projection_matrix (framebuffer, &old_matrix); /* Use an orthogonal projection from -1 -> 1 in both axes */ cogl_matrix_init_identity (&new_matrix); - cogl_set_projection_matrix (&new_matrix); + cogl_framebuffer_set_projection_matrix (framebuffer, &new_matrix); - cogl_push_matrix (); - cogl_set_modelview_matrix (&new_matrix); + cogl_framebuffer_push_matrix (framebuffer); + cogl_framebuffer_set_modelview_matrix (framebuffer, &new_matrix); /* Update all of the firework's positions */ for (i = 0; i < N_FIREWORKS; i++) @@ -189,24 +198,8 @@ paint_cb (ClutterActor *stage, Data *data) g_timer_reset (data->last_spark_time); } - vbo = cogl_vertex_buffer_new (N_SPARKS); - cogl_vertex_buffer_add (vbo, "gl_Vertex", 2, - COGL_ATTRIBUTE_TYPE_FLOAT, FALSE, - sizeof (Spark), - &data->sparks[0].x); - cogl_vertex_buffer_add (vbo, "gl_Color", 4, - COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE, TRUE, - sizeof (Spark), - &data->sparks[0].color.red); - cogl_vertex_buffer_submit (vbo); - - cogl_set_source (data->material); - cogl_vertex_buffer_draw (vbo, COGL_VERTICES_MODE_POINTS, 0, N_SPARKS); - - cogl_handle_unref (vbo); - - cogl_set_projection_matrix (&old_matrix); - cogl_pop_matrix (); + cogl_framebuffer_set_projection_matrix (framebuffer, &old_matrix); + cogl_framebuffer_pop_matrix (framebuffer); } static gboolean @@ -236,7 +229,7 @@ test_cogl_point_sprites_main (int argc, char *argv[]) tex = generate_round_texture (); cogl_material_set_layer (data.material, 0, tex); - cogl_handle_unref (tex); + cogl_object_unref (tex); if (!cogl_material_set_layer_point_sprite_coords_enabled (data.material, 0, TRUE, diff --git a/clutter/tests/interactive/test-cogl-shader-glsl.c b/src/tests/clutter/interactive/test-cogl-shader-glsl.c similarity index 90% rename from clutter/tests/interactive/test-cogl-shader-glsl.c rename to src/tests/clutter/interactive/test-cogl-shader-glsl.c index 406d970ce..84461d34d 100644 --- a/clutter/tests/interactive/test-cogl-shader-glsl.c +++ b/src/tests/clutter/interactive/test-cogl-shader-glsl.c @@ -7,10 +7,13 @@ typedef struct { - char *name; - char *source; + const char *name; + const char *source; } ShaderSource; +int +test_cogl_shader_glsl_main (int argc, char *argv[]); + /* a couple of boilerplate defines that are common amongst all the * sample shaders */ @@ -51,22 +54,6 @@ static ShaderSource shaders[]= {"box-blur", FRAGMENT_SHADER_VARS -#if GPU_SUPPORTS_DYNAMIC_BRANCHING - "uniform float radius;" - FRAGMENT_SHADER_BEGIN - "float u, v;" - "int count = 1;" - "for (u=-radius;u<radius;u++)" - " for (v=-radius;v<radius;v++)" - " {" - " color += texture2D(tex, " - " vec2(cogl_tex_coord_in[0].s + u * 2.0 * x_step, " - " cogl_tex_coord_in[0].t + v * 2.0 * y_step));" - " count ++;" - " }" - "color = color / float(count);" - FRAGMENT_SHADER_END -#else "vec4 get_rgba_rel(sampler2D tex, float dx, float dy)" "{" " return texture2D (tex, cogl_tex_coord_in[0].st " @@ -86,7 +73,6 @@ static ShaderSource shaders[]= " color += get_rgba_rel (tex, x_step, y_step); count++;" " color = color / count;" FRAGMENT_SHADER_END -#endif }, {"invert", @@ -178,18 +164,21 @@ static unsigned int timeout_id = 0; static int shader_no = 0; static void -paint_cb (ClutterActor *actor) +paint_cb (ClutterActor *actor, + ClutterPaintContext *paint_context) { + CoglFramebuffer *framebuffer = + clutter_paint_context_get_framebuffer (paint_context); float stage_width = clutter_actor_get_width (actor); float stage_height = clutter_actor_get_height (actor); float image_width = cogl_texture_get_width (redhand); float image_height = cogl_texture_get_height (redhand); - cogl_set_source (material); - cogl_rectangle (stage_width/2.0f - image_width/2.0f, - stage_height/2.0f - image_height/2.0f, - stage_width/2.0f + image_width/2.0f, - stage_height/2.0f + image_height/2.0f); + cogl_framebuffer_draw_rectangle (framebuffer, COGL_PIPELINE (material), + stage_width / 2.0f - image_width / 2.0f, + stage_height / 2.0f - image_height / 2.0f, + stage_width / 2.0f + image_width / 2.0f, + stage_height / 2.0f + image_height / 2.0f); } static void @@ -207,11 +196,10 @@ set_shader_num (int new_no) shader = cogl_create_shader (COGL_SHADER_TYPE_FRAGMENT); cogl_shader_source (shader, shaders[new_no].source); - cogl_shader_compile (shader); program = cogl_create_program (); cogl_program_attach_shader (program, shader); - cogl_handle_unref (shader); + cogl_object_unref (shader); cogl_program_link (program); uniform_no = cogl_program_get_uniform_location (program, "tex"); @@ -229,7 +217,7 @@ set_shader_num (int new_no) cogl_program_set_uniform_1f (program, uniform_no, 1.0f / image_height); cogl_material_set_user_program (material, program); - cogl_handle_unref (program); + cogl_object_unref (program); shader_no = new_no; } @@ -243,11 +231,7 @@ button_release_cb (ClutterActor *actor, /* Stop the automatic cycling if the user want to manually control * which shader to display */ - if (timeout_id) - { - g_source_remove (timeout_id); - timeout_id = 0; - } + g_clear_handle_id (&timeout_id, g_source_remove); if (event->button.button == 1) { @@ -334,7 +318,7 @@ test_cogl_shader_glsl_main (int argc, char *argv[]) COGL_TEXTURE_NO_ATLAS, COGL_PIXEL_FORMAT_ANY, &error); - if (redhand == COGL_INVALID_HANDLE) + if (redhand == NULL) g_error ("image load failed: %s", error->message); material = cogl_material_new (); diff --git a/clutter/tests/interactive/test-cogl-tex-convert.c b/src/tests/clutter/interactive/test-cogl-tex-convert.c similarity index 58% rename from clutter/tests/interactive/test-cogl-tex-convert.c rename to src/tests/clutter/interactive/test-cogl-tex-convert.c index 303b0a683..5f4257d7c 100644 --- a/clutter/tests/interactive/test-cogl-tex-convert.c +++ b/src/tests/clutter/interactive/test-cogl-tex-convert.c @@ -8,12 +8,12 @@ *--------------------------------------------------*/ G_BEGIN_DECLS - + #define TEST_TYPE_COGLBOX test_coglbox_get_type() #define TEST_COGLBOX(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ - TEST_TYPE_COGLBOX, TestCoglboxClass)) + TEST_TYPE_COGLBOX, TestCoglbox)) #define TEST_COGLBOX_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), \ @@ -43,7 +43,7 @@ struct _TestCoglbox TestCoglboxPrivate *priv; }; -struct _TestCoglboxClass +struct _TestCoglboxClass { ClutterActorClass parent_class; @@ -56,67 +56,88 @@ struct _TestCoglboxClass static GType test_coglbox_get_type (void) G_GNUC_CONST; +int +test_cogl_tex_convert_main (int argc, char *argv[]); + +const char * +test_cogl_tex_convert_describe (void); + G_END_DECLS /* Coglbox private declaration *--------------------------------------------------*/ -G_DEFINE_TYPE (TestCoglbox, test_coglbox, CLUTTER_TYPE_ACTOR); - -#define TEST_COGLBOX_GET_PRIVATE(obj) \ -(G_TYPE_INSTANCE_GET_PRIVATE ((obj), TEST_TYPE_COGLBOX, TestCoglboxPrivate)) - struct _TestCoglboxPrivate { CoglHandle cogl_tex_id[4]; gint frame; }; +G_DEFINE_TYPE_WITH_PRIVATE (TestCoglbox, test_coglbox, CLUTTER_TYPE_ACTOR); + +#define TEST_COGLBOX_GET_PRIVATE(obj) \ +(test_coglbox_get_instance_private (TEST_COGLBOX ((obj)))) + /* Coglbox implementation *--------------------------------------------------*/ static void -test_coglbox_paint(ClutterActor *self) +test_coglbox_paint (ClutterActor *self, + ClutterPaintContext *paint_context) { TestCoglboxPrivate *priv = TEST_COGLBOX_GET_PRIVATE (self); + CoglPipeline *pipeline; + CoglFramebuffer *framebuffer = + clutter_paint_context_get_framebuffer (paint_context); + CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); gfloat texcoords[4] = { 0.0, 0.0, 1.0, 1.0 }; priv = TEST_COGLBOX_GET_PRIVATE (self); - cogl_set_source_color4ub (0x66, 0x66, 0xdd, 0xff); - cogl_rectangle (0, 0, 400, 400); - - cogl_push_matrix (); - cogl_set_source_texture (priv->cogl_tex_id[0]); - cogl_rectangle_with_texture_coords (0, 0, 200, 213, - texcoords[0], texcoords[1], - texcoords[2], texcoords[3]); - - cogl_pop_matrix (); - cogl_push_matrix (); - cogl_translate (200, 0, 0); - cogl_set_source_texture (priv->cogl_tex_id[1]); - cogl_rectangle_with_texture_coords (0, 0, 200, 213, - texcoords[0], texcoords[1], - texcoords[2], texcoords[3]); - - cogl_pop_matrix (); - cogl_push_matrix (); - cogl_translate (0, 200, 0); - cogl_set_source_texture (priv->cogl_tex_id[2]); - cogl_rectangle_with_texture_coords (0, 0, 200, 213, - texcoords[0], texcoords[1], - texcoords[2], texcoords[3]); - - cogl_pop_matrix (); - cogl_push_matrix (); - cogl_translate (200, 200, 0); - cogl_set_source_texture (priv->cogl_tex_id[3]); - cogl_rectangle_with_texture_coords (0, 0, 200, 213, - texcoords[0], texcoords[1], - texcoords[2], texcoords[3]); - - cogl_pop_matrix(); + pipeline = cogl_pipeline_new (ctx); + cogl_pipeline_set_color4ub (pipeline, 0x66, 0x66, 0xdd, 0xff); + cogl_framebuffer_draw_rectangle (framebuffer, pipeline, 0, 0, 400, 400); + cogl_object_unref (pipeline); + + pipeline = cogl_pipeline_new (ctx); + + cogl_framebuffer_push_matrix (framebuffer); + cogl_pipeline_set_layer_texture (pipeline, 0, priv->cogl_tex_id[0]); + cogl_framebuffer_draw_textured_rectangle (framebuffer, pipeline, + 0, 0, 200, 213, + texcoords[0], texcoords[1], + texcoords[2], texcoords[3]); + + cogl_framebuffer_pop_matrix (framebuffer); + cogl_framebuffer_push_matrix (framebuffer); + cogl_framebuffer_translate (framebuffer, 200, 0, 0); + cogl_pipeline_set_layer_texture (pipeline, 0, priv->cogl_tex_id[1]); + cogl_framebuffer_draw_textured_rectangle (framebuffer, pipeline, + 0, 0, 200, 213, + texcoords[0], texcoords[1], + texcoords[2], texcoords[3]); + + cogl_framebuffer_pop_matrix (framebuffer); + cogl_framebuffer_push_matrix (framebuffer); + cogl_framebuffer_translate (framebuffer, 0, 200, 0); + cogl_pipeline_set_layer_texture (pipeline, 0, priv->cogl_tex_id[2]); + cogl_framebuffer_draw_textured_rectangle (framebuffer, pipeline, + 0, 0, 200, 213, + texcoords[0], texcoords[1], + texcoords[2], texcoords[3]); + + cogl_framebuffer_pop_matrix (framebuffer); + cogl_framebuffer_push_matrix (framebuffer); + cogl_framebuffer_translate (framebuffer, 200, 200, 0); + cogl_pipeline_set_layer_texture (pipeline, 0, priv->cogl_tex_id[3]); + cogl_framebuffer_draw_textured_rectangle (framebuffer, pipeline, + 0, 0, 200, 213, + texcoords[0], texcoords[1], + texcoords[2], texcoords[3]); + cogl_framebuffer_pop_matrix (framebuffer); + + cogl_object_unref (pipeline); + } static void @@ -129,10 +150,10 @@ static void test_coglbox_dispose (GObject *object) { TestCoglboxPrivate *priv; - + priv = TEST_COGLBOX_GET_PRIVATE (object); - cogl_handle_unref (priv->cogl_tex_id); - + cogl_object_unref (priv->cogl_tex_id); + G_OBJECT_CLASS (test_coglbox_parent_class)->dispose (object); } @@ -151,26 +172,26 @@ test_coglbox_init (TestCoglbox *self) COGL_TEXTURE_NONE, COGL_PIXEL_FORMAT_ANY, NULL); - + priv->cogl_tex_id[1] = cogl_texture_new_from_file (file, COGL_TEXTURE_NONE, COGL_PIXEL_FORMAT_BGRA_8888, NULL); - + priv->cogl_tex_id[2] = cogl_texture_new_from_file (file, COGL_TEXTURE_NONE, COGL_PIXEL_FORMAT_ARGB_8888, NULL); - + priv->cogl_tex_id[3] = cogl_texture_new_from_file (file, COGL_TEXTURE_NONE, COGL_PIXEL_FORMAT_G_8, NULL); - free (file); + g_free (file); } static void @@ -180,10 +201,8 @@ test_coglbox_class_init (TestCoglboxClass *klass) ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); gobject_class->finalize = test_coglbox_finalize; - gobject_class->dispose = test_coglbox_dispose; + gobject_class->dispose = test_coglbox_dispose; actor_class->paint = test_coglbox_paint; - - g_type_class_add_private (gobject_class, sizeof (TestCoglboxPrivate)); } static ClutterActor* @@ -197,10 +216,10 @@ test_cogl_tex_convert_main (int argc, char *argv[]) { ClutterActor *stage; ClutterActor *coglbox; - + if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) return 1; - + /* Stage */ stage = clutter_stage_new (); clutter_actor_set_size (stage, 400, 400); @@ -210,11 +229,11 @@ test_cogl_tex_convert_main (int argc, char *argv[]) /* Cogl Box */ coglbox = test_coglbox_new (); clutter_container_add_actor (CLUTTER_CONTAINER (stage), coglbox); - + clutter_actor_show_all (stage); - + clutter_main (); - + return 0; } diff --git a/clutter/tests/interactive/test-cogl-tex-polygon.c b/src/tests/clutter/interactive/test-cogl-tex-polygon.c similarity index 67% rename from clutter/tests/interactive/test-cogl-tex-polygon.c rename to src/tests/clutter/interactive/test-cogl-tex-polygon.c index 9bdb2a1b9..654401b4d 100644 --- a/clutter/tests/interactive/test-cogl-tex-polygon.c +++ b/src/tests/clutter/interactive/test-cogl-tex-polygon.c @@ -13,7 +13,7 @@ G_BEGIN_DECLS #define TEST_COGLBOX(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ - TEST_TYPE_COGLBOX, TestCoglboxClass)) + TEST_TYPE_COGLBOX, TestCoglbox)) #define TEST_COGLBOX_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), \ @@ -56,16 +56,17 @@ struct _TestCoglboxClass static GType test_coglbox_get_type (void) G_GNUC_CONST; +int +test_cogl_tex_polygon_main (int argc, char *argv[]); + +const char * +test_cogl_tex_polygon_describe (void); + G_END_DECLS /* Coglbox private declaration *--------------------------------------------------*/ -G_DEFINE_TYPE (TestCoglbox, test_coglbox, CLUTTER_TYPE_ACTOR); - -#define TEST_COGLBOX_GET_PRIVATE(obj) \ -(G_TYPE_INSTANCE_GET_PRIVATE ((obj), TEST_TYPE_COGLBOX, TestCoglboxPrivate)) - struct _TestCoglboxPrivate { CoglHandle sliced_tex, not_sliced_tex; @@ -74,99 +75,130 @@ struct _TestCoglboxPrivate gboolean use_linear_filtering; }; +G_DEFINE_TYPE_WITH_PRIVATE (TestCoglbox, test_coglbox, CLUTTER_TYPE_ACTOR); + +#define TEST_COGLBOX_GET_PRIVATE(obj) \ +((TestCoglboxPrivate *)test_coglbox_get_instance_private (TEST_COGLBOX ((obj)))) + /* Coglbox implementation *--------------------------------------------------*/ static void -test_coglbox_fade_texture (gfloat x1, - gfloat y1, - gfloat x2, - gfloat y2, - gfloat tx1, - gfloat ty1, - gfloat tx2, - gfloat ty2) +test_coglbox_fade_texture (CoglFramebuffer *framebuffer, + CoglPipeline *pipeline, + float x1, + float y1, + float x2, + float y2, + float tx1, + float ty1, + float tx2, + float ty2) { - CoglTextureVertex vertices[4]; + CoglVertexP3T2C4 vertices[4]; + CoglPrimitive *primitive; int i; vertices[0].x = x1; vertices[0].y = y1; vertices[0].z = 0; - vertices[0].tx = tx1; - vertices[0].ty = ty1; + vertices[0].s = tx1; + vertices[0].t = ty1; vertices[1].x = x1; vertices[1].y = y2; vertices[1].z = 0; - vertices[1].tx = tx1; - vertices[1].ty = ty2; + vertices[1].s = tx1; + vertices[1].t = ty2; vertices[2].x = x2; vertices[2].y = y2; vertices[2].z = 0; - vertices[2].tx = tx2; - vertices[2].ty = ty2; + vertices[2].s = tx2; + vertices[2].t = ty2; vertices[3].x = x2; vertices[3].y = y1; vertices[3].z = 0; - vertices[3].tx = tx2; - vertices[3].ty = ty1; + vertices[3].s = tx2; + vertices[3].t = ty1; for (i = 0; i < 4; i++) { - cogl_color_init_from_4ub (&(vertices[i].color), + CoglColor cogl_color; + + cogl_color_init_from_4ub (&cogl_color, 255, 255, 255, ((i ^ (i >> 1)) & 1) ? 0 : 128); - cogl_color_premultiply (&(vertices[i].color)); + cogl_color_premultiply (&cogl_color); + vertices[i].r = cogl_color_get_red_byte (&cogl_color); + vertices[i].g = cogl_color_get_green_byte (&cogl_color); + vertices[i].b = cogl_color_get_blue_byte (&cogl_color); + vertices[i].a = cogl_color_get_alpha_byte (&cogl_color); } - cogl_polygon (vertices, 4, TRUE); + primitive = + cogl_primitive_new_p3t2c4 (cogl_framebuffer_get_context (framebuffer), + COGL_VERTICES_MODE_TRIANGLE_FAN, + 4, + vertices); + cogl_primitive_draw (primitive, framebuffer, pipeline); + cogl_object_unref (primitive); } static void -test_coglbox_triangle_texture (int tex_width, - int tex_height, - gfloat x, - gfloat y, - gfloat tx1, - gfloat ty1, - gfloat tx2, - gfloat ty2, - gfloat tx3, - gfloat ty3) +test_coglbox_triangle_texture (CoglFramebuffer *framebuffer, + CoglHandle material, + int tex_width, + int tex_height, + float x, + float y, + float tx1, + float ty1, + float tx2, + float ty2, + float tx3, + float ty3) { - CoglTextureVertex vertices[3]; + CoglVertexP3T2 vertices[3]; + CoglPrimitive *primitive; vertices[0].x = x + tx1 * tex_width; vertices[0].y = y + ty1 * tex_height; vertices[0].z = 0; - vertices[0].tx = tx1; - vertices[0].ty = ty1; + vertices[0].s = tx1; + vertices[0].t = ty1; vertices[1].x = x + tx2 * tex_width; vertices[1].y = y + ty2 * tex_height; vertices[1].z = 0; - vertices[1].tx = tx2; - vertices[1].ty = ty2; + vertices[1].s = tx2; + vertices[1].t = ty2; vertices[2].x = x + tx3 * tex_width; vertices[2].y = y + ty3 * tex_height; vertices[2].z = 0; - vertices[2].tx = tx3; - vertices[2].ty = ty3; - - cogl_polygon (vertices, 3, FALSE); + vertices[2].s = tx3; + vertices[2].t = ty3; + + primitive = cogl_primitive_new_p3t2 (cogl_framebuffer_get_context (framebuffer), + COGL_VERTICES_MODE_TRIANGLE_FAN, + 3, + vertices); + cogl_primitive_draw (primitive, framebuffer, material); + cogl_object_unref (primitive); } static void -test_coglbox_paint (ClutterActor *self) +test_coglbox_paint (ClutterActor *self, + ClutterPaintContext *paint_context) { TestCoglboxPrivate *priv = TEST_COGLBOX_GET_PRIVATE (self); CoglHandle tex_handle = priv->use_sliced ? priv->sliced_tex : priv->not_sliced_tex; int tex_width = cogl_texture_get_width (tex_handle); int tex_height = cogl_texture_get_height (tex_handle); + CoglFramebuffer *framebuffer = + clutter_paint_context_get_framebuffer (paint_context); CoglHandle material = cogl_material_new (); cogl_material_set_layer (material, 0, tex_handle); @@ -179,42 +211,45 @@ test_coglbox_paint (ClutterActor *self) ? COGL_MATERIAL_FILTER_LINEAR : COGL_MATERIAL_FILTER_NEAREST); - cogl_push_matrix (); - cogl_translate (tex_width / 2, 0, 0); - cogl_rotate (priv->frame, 0, 1, 0); - cogl_translate (-tex_width / 2, 0, 0); + cogl_framebuffer_push_matrix (framebuffer); + cogl_framebuffer_translate (framebuffer, tex_width / 2, 0, 0); + cogl_framebuffer_rotate (framebuffer, priv->frame, 0, 1, 0); + cogl_framebuffer_translate (framebuffer, -tex_width / 2, 0, 0); /* Draw a hand and refect it */ - cogl_set_source (material); - cogl_rectangle_with_texture_coords (0, 0, tex_width, tex_height, - 0, 0, 1, 1); - test_coglbox_fade_texture (0, tex_height, + cogl_framebuffer_draw_textured_rectangle (framebuffer, material, + 0, 0, tex_width, tex_height, + 0, 0, 1, 1); + test_coglbox_fade_texture (framebuffer, material, + 0, tex_height, tex_width, (tex_height * 3 / 2), 0.0, 1.0, 1.0, 0.5); - cogl_pop_matrix (); + cogl_framebuffer_pop_matrix (framebuffer); - cogl_push_matrix (); - cogl_translate (tex_width * 3 / 2 + 60, 0, 0); - cogl_rotate (priv->frame, 0, 1, 0); - cogl_translate (-tex_width / 2 - 10, 0, 0); + cogl_framebuffer_push_matrix (framebuffer); + cogl_framebuffer_translate (framebuffer, tex_width * 3 / 2 + 60, 0, 0); + cogl_framebuffer_rotate (framebuffer, priv->frame, 0, 1, 0); + cogl_framebuffer_translate (framebuffer, -tex_width / 2 - 10, 0, 0); /* Draw the texture split into two triangles */ - test_coglbox_triangle_texture (tex_width, tex_height, + test_coglbox_triangle_texture (framebuffer, material, + tex_width, tex_height, 0, 0, 0, 0, 0, 1, 1, 1); - test_coglbox_triangle_texture (tex_width, tex_height, + test_coglbox_triangle_texture (framebuffer, material, + tex_width, tex_height, 20, 0, 0, 0, 1, 0, 1, 1); - cogl_pop_matrix (); + cogl_framebuffer_pop_matrix (framebuffer); - cogl_handle_unref (material); + cogl_object_unref (material); } static void @@ -229,8 +264,8 @@ test_coglbox_dispose (GObject *object) TestCoglboxPrivate *priv; priv = TEST_COGLBOX_GET_PRIVATE (object); - cogl_handle_unref (priv->not_sliced_tex); - cogl_handle_unref (priv->sliced_tex); + cogl_object_unref (priv->not_sliced_tex); + cogl_object_unref (priv->sliced_tex); G_OBJECT_CLASS (test_coglbox_parent_class)->dispose (object); } @@ -253,7 +288,7 @@ test_coglbox_init (TestCoglbox *self) COGL_TEXTURE_NONE, COGL_PIXEL_FORMAT_ANY, &error); - if (priv->sliced_tex == COGL_INVALID_HANDLE) + if (priv->sliced_tex == NULL) { if (error) { @@ -270,7 +305,7 @@ test_coglbox_init (TestCoglbox *self) COGL_TEXTURE_NO_SLICING, COGL_PIXEL_FORMAT_ANY, &error); - if (priv->not_sliced_tex == COGL_INVALID_HANDLE) + if (priv->not_sliced_tex == NULL) { if (error) { @@ -281,7 +316,7 @@ test_coglbox_init (TestCoglbox *self) g_warning ("Texture loading failed: <unknown>"); } - free (file); + g_free (file); } static void @@ -293,8 +328,6 @@ test_coglbox_class_init (TestCoglboxClass *klass) gobject_class->finalize = test_coglbox_finalize; gobject_class->dispose = test_coglbox_dispose; actor_class->paint = test_coglbox_paint; - - g_type_class_add_private (gobject_class, sizeof (TestCoglboxPrivate)); } static ClutterActor* diff --git a/clutter/tests/interactive/test-cogl-tex-tile.c b/src/tests/clutter/interactive/test-cogl-tex-tile.c similarity index 77% rename from clutter/tests/interactive/test-cogl-tex-tile.c rename to src/tests/clutter/interactive/test-cogl-tex-tile.c index c7cd4f031..9948696a4 100644 --- a/clutter/tests/interactive/test-cogl-tex-tile.c +++ b/src/tests/clutter/interactive/test-cogl-tex-tile.c @@ -14,7 +14,7 @@ G_BEGIN_DECLS #define TEST_COGLBOX(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ - TEST_TYPE_COGLBOX, TestCoglboxClass)) + TEST_TYPE_COGLBOX, TestCoglbox)) #define TEST_COGLBOX_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), \ @@ -57,29 +57,40 @@ struct _TestCoglboxClass static GType test_coglbox_get_type (void) G_GNUC_CONST; +int +test_cogl_tex_tile_main (int argc, char *argv[]); + +const char * +test_cogl_tex_tile_describe (void); + G_END_DECLS /* Coglbox private declaration *--------------------------------------------------*/ -G_DEFINE_TYPE (TestCoglbox, test_coglbox, CLUTTER_TYPE_ACTOR); - -#define TEST_COGLBOX_GET_PRIVATE(obj) \ -(G_TYPE_INSTANCE_GET_PRIVATE ((obj), TEST_TYPE_COGLBOX, TestCoglboxPrivate)) - struct _TestCoglboxPrivate { CoglHandle cogl_tex_id; gdouble animation_progress; }; +G_DEFINE_TYPE_WITH_PRIVATE (TestCoglbox, test_coglbox, CLUTTER_TYPE_ACTOR); + +#define TEST_COGLBOX_GET_PRIVATE(obj) \ +(test_coglbox_get_instance_private (TEST_COGLBOX ((obj)))) + /* Coglbox implementation *--------------------------------------------------*/ static void -test_coglbox_paint (ClutterActor *self) +test_coglbox_paint (ClutterActor *self, + ClutterPaintContext *paint_context) { TestCoglboxPrivate *priv = TEST_COGLBOX_GET_PRIVATE (self); + CoglFramebuffer *framebuffer = + clutter_paint_context_get_framebuffer (paint_context); + CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); + CoglPipeline *pipeline; gfloat texcoords[4] = { 0.0f, 0.0f, 1.0f, 1.0f }; gfloat angle; gfloat frac; @@ -102,18 +113,24 @@ test_coglbox_paint (ClutterActor *self) priv = TEST_COGLBOX_GET_PRIVATE (self); - cogl_push_matrix (); + cogl_framebuffer_push_matrix (framebuffer); - cogl_set_source_color4ub (0x66, 0x66, 0xdd, 0xff); - cogl_rectangle (0, 0, 400, 400); + pipeline = cogl_pipeline_new (ctx); + cogl_pipeline_set_color4ub (pipeline, 0x66, 0x66, 0xdd, 0xff); + cogl_framebuffer_draw_rectangle (framebuffer, pipeline, 0, 0, 400, 400); + cogl_object_unref (pipeline); - cogl_translate (100, 100, 0); - cogl_set_source_texture (priv->cogl_tex_id); - cogl_rectangle_with_texture_coords (0, 0, 200, 213, - texcoords[0], texcoords[1], - texcoords[2], texcoords[3]); + cogl_framebuffer_translate (framebuffer, 100, 100, 0); - cogl_pop_matrix(); + pipeline = cogl_pipeline_new (ctx); + cogl_pipeline_set_layer_texture (pipeline, 0, priv->cogl_tex_id); + cogl_framebuffer_draw_textured_rectangle (framebuffer, pipeline, + 0, 0, 200, 213, + texcoords[0], texcoords[1], + texcoords[2], texcoords[3]); + cogl_object_unref (pipeline); + + cogl_framebuffer_pop_matrix (framebuffer); } static void @@ -128,7 +145,7 @@ test_coglbox_dispose (GObject *object) TestCoglboxPrivate *priv; priv = TEST_COGLBOX_GET_PRIVATE (object); - cogl_handle_unref (priv->cogl_tex_id); + cogl_object_unref (priv->cogl_tex_id); G_OBJECT_CLASS (test_coglbox_parent_class)->dispose (object); } @@ -146,7 +163,7 @@ test_coglbox_init (TestCoglbox *self) COGL_TEXTURE_NONE, COGL_PIXEL_FORMAT_ANY, NULL); - free (file); + g_free (file); } static void @@ -158,8 +175,6 @@ test_coglbox_class_init (TestCoglboxClass *klass) gobject_class->finalize = test_coglbox_finalize; gobject_class->dispose = test_coglbox_dispose; actor_class->paint = test_coglbox_paint; - - g_type_class_add_private (gobject_class, sizeof (TestCoglboxPrivate)); } static ClutterActor* diff --git a/clutter/tests/interactive/test-content.c b/src/tests/clutter/interactive/test-content.c similarity index 92% rename from clutter/tests/interactive/test-content.c rename to src/tests/clutter/interactive/test-content.c index e34ac089b..ede6db591 100644 --- a/clutter/tests/interactive/test-content.c +++ b/src/tests/clutter/interactive/test-content.c @@ -17,16 +17,25 @@ typedef struct _ColorContentClass { GObjectClass parent_class; } ColorContentClass; -static void clutter_content_iface_init (ClutterContentIface *iface); +static void clutter_content_iface_init (ClutterContentInterface *iface); + +GType color_content_get_type (void); + +int +test_content_main (int argc, char *argv[]); + +const char * +test_content_describe (void); G_DEFINE_TYPE_WITH_CODE (ColorContent, color_content, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTENT, clutter_content_iface_init)) static void -color_content_paint_content (ClutterContent *content, - ClutterActor *actor, - ClutterPaintNode *root) +color_content_paint_content (ClutterContent *content, + ClutterActor *actor, + ClutterPaintNode *root, + ClutterPaintContext *paint_context) { ColorContent *self = (ColorContent *) content; ClutterActorBox box, content_box; @@ -127,7 +136,7 @@ color_content_paint_content (ClutterContent *content, } static void -clutter_content_iface_init (ClutterContentIface *iface) +clutter_content_iface_init (ClutterContentInterface *iface) { iface->paint_content = color_content_paint_content; } @@ -173,7 +182,6 @@ test_content_main (int argc, char *argv[]) stage = clutter_stage_new (); clutter_actor_set_name (stage, "Stage"); clutter_stage_set_title (CLUTTER_STAGE (stage), "Content"); - clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE); g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); clutter_actor_show (stage); @@ -209,8 +217,8 @@ test_content_main (int argc, char *argv[]) name = g_strconcat ("Box <", color, ">", NULL); clutter_actor_set_name (box, name); - free (name); - free (color); + g_free (name); + g_free (color); clutter_actor_set_background_color (box, &bg_color); clutter_actor_set_content (box, content); diff --git a/clutter/tests/interactive/test-devices.c b/src/tests/clutter/interactive/test-devices.c similarity index 83% rename from clutter/tests/interactive/test-devices.c rename to src/tests/clutter/interactive/test-devices.c index f0dd9fa55..072c2e730 100644 --- a/clutter/tests/interactive/test-devices.c +++ b/src/tests/clutter/interactive/test-devices.c @@ -6,12 +6,17 @@ #include <clutter/x11/clutter-x11.h> #endif +#include "test-utils.h" + typedef struct { ClutterActor *stage; GHashTable *devices; } TestDevicesApp; +int +test_devices_main (int argc, char **argv); + static const gchar * device_type_name (ClutterInputDevice *device) { @@ -147,9 +152,9 @@ stage_motion_event_cb (ClutterActor *actor, } static void -manager_device_added_cb (ClutterDeviceManager *manager, - ClutterInputDevice *device, - TestDevicesApp *app) +seat_device_added_cb (ClutterSeat *seat, + ClutterInputDevice *device, + TestDevicesApp *app) { ClutterInputDeviceType device_type; ClutterActor *hand = NULL; @@ -169,10 +174,10 @@ manager_device_added_cb (ClutterDeviceManager *manager, clutter_input_device_set_enabled (device, TRUE); - hand = clutter_texture_new_from_file (TESTS_DATADIR - G_DIR_SEPARATOR_S - "redhand.png", - NULL); + hand = clutter_test_utils_create_texture_from_file (TESTS_DATADIR + G_DIR_SEPARATOR_S + "redhand.png", + NULL); g_hash_table_insert (app->devices, device, hand); clutter_container_add_actor (CLUTTER_CONTAINER (app->stage), hand); @@ -180,9 +185,9 @@ manager_device_added_cb (ClutterDeviceManager *manager, } static void -manager_device_removed_cb (ClutterDeviceManager *manager, - ClutterInputDevice *device, - TestDevicesApp *app) +seat_device_removed_cb (ClutterSeat *seat, + ClutterInputDevice *device, + TestDevicesApp *app) { ClutterInputDeviceType device_type; ClutterActor *hand = NULL; @@ -210,8 +215,8 @@ test_devices_main (int argc, char **argv) { ClutterActor *stage; TestDevicesApp *app; - ClutterDeviceManager *manager; - const GSList *stage_devices, *l; + ClutterSeat *seat; + GList *stage_devices, *l; if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) return 1; @@ -236,15 +241,15 @@ test_devices_main (int argc, char **argv) clutter_actor_show_all (stage); - manager = clutter_device_manager_get_default (); - g_signal_connect (manager, - "device-added", G_CALLBACK (manager_device_added_cb), + seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); + g_signal_connect (seat, + "device-added", G_CALLBACK (seat_device_added_cb), app); - g_signal_connect (manager, - "device-removed", G_CALLBACK (manager_device_removed_cb), + g_signal_connect (seat, + "device-removed", G_CALLBACK (seat_device_removed_cb), app); - stage_devices = clutter_device_manager_peek_devices (manager); + stage_devices = clutter_seat_list_devices (seat); if (stage_devices == NULL) g_error ("No input devices found."); @@ -270,16 +275,18 @@ test_devices_main (int argc, char **argv) clutter_input_device_set_enabled (device, TRUE); - hand = clutter_texture_new_from_file (TESTS_DATADIR - G_DIR_SEPARATOR_S - "redhand.png", - NULL); + hand = clutter_test_utils_create_texture_from_file (TESTS_DATADIR + G_DIR_SEPARATOR_S + "redhand.png", + NULL); g_hash_table_insert (app->devices, device, hand); clutter_container_add_actor (CLUTTER_CONTAINER (stage), hand); } } + g_list_free (stage_devices); + clutter_main (); return EXIT_SUCCESS; diff --git a/clutter/tests/interactive/test-easing.c b/src/tests/clutter/interactive/test-easing.c similarity index 91% rename from clutter/tests/interactive/test-easing.c rename to src/tests/clutter/interactive/test-easing.c index 6c9726d91..c0d175a21 100644 --- a/clutter/tests/interactive/test-easing.c +++ b/src/tests/clutter/interactive/test-easing.c @@ -55,6 +55,12 @@ static ClutterActor *easing_mode_label = NULL; static ClutterAnimation *last_animation = NULL; +int +test_easing_main (int argc, char *argv[]); + +const char * +test_easing_describe (void); + /* recenter_bouncer: * * repositions (through an animation) the bouncer at the center of the stage @@ -98,7 +104,7 @@ on_button_press (ClutterActor *actor, n_easing_modes); clutter_text_set_text (CLUTTER_TEXT (easing_mode_label), text); - free (text); + g_free (text); } else if (event->button == CLUTTER_BUTTON_PRIMARY) { @@ -130,19 +136,21 @@ on_button_press (ClutterActor *actor, } static gboolean -draw_bouncer (ClutterCairoTexture *texture, - cairo_t *cr) +draw_bouncer (ClutterCanvas *canvas, + cairo_t *cr, + int width, + int height) { const ClutterColor *bouncer_color; cairo_pattern_t *pattern; - guint width, height; float radius; - clutter_cairo_texture_get_surface_size (texture, &width, &height); - radius = MAX (width, height); - clutter_cairo_texture_clear (texture); + cairo_save (cr); + cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); + cairo_paint (cr); + cairo_restore (cr); cairo_arc (cr, radius / 2, radius / 2, radius / 2, 0.0, 2.0 * G_PI); @@ -175,18 +183,22 @@ static ClutterActor * make_bouncer (gfloat width, gfloat height) { + ClutterContent *canvas; ClutterActor *retval; - retval = clutter_cairo_texture_new (width, height); - g_signal_connect (retval, "draw", G_CALLBACK (draw_bouncer), NULL); + canvas = clutter_canvas_new (); + clutter_canvas_set_size (CLUTTER_CANVAS (canvas), width, height); + g_signal_connect (canvas, "draw", G_CALLBACK (draw_bouncer), NULL); + retval = g_object_new (CLUTTER_TYPE_ACTOR, + "content", canvas, + NULL); clutter_actor_set_name (retval, "bouncer"); clutter_actor_set_size (retval, width, height); clutter_actor_set_anchor_point (retval, width / 2, height / 2); clutter_actor_set_reactive (retval, TRUE); - /* make sure we draw the bouncer immediately */ - clutter_cairo_texture_invalidate (CLUTTER_CAIRO_TEXTURE (retval)); + clutter_content_invalidate (canvas); return retval; } @@ -250,7 +262,7 @@ test_easing_main (int argc, char *argv[]) clutter_actor_add_constraint (label, clutter_align_constraint_new (stage, CLUTTER_ALIGN_Y_AXIS, 0.95)); easing_mode_label = label; - free (text); + g_free (text); g_signal_connect (stage, "button-press-event", G_CALLBACK (on_button_press), diff --git a/clutter/tests/interactive/test-events.c b/src/tests/clutter/interactive/test-events.c similarity index 87% rename from clutter/tests/interactive/test-events.c rename to src/tests/clutter/interactive/test-events.c index 8c2cee6fb..f31c7d228 100644 --- a/clutter/tests/interactive/test-events.c +++ b/src/tests/clutter/interactive/test-events.c @@ -2,7 +2,13 @@ #include <clutter/clutter.h> #include <string.h> -gboolean IsFullScreen = FALSE, IsMotion = TRUE; +gboolean IsMotion = TRUE; + +int +test_events_main (int argc, char *argv[]); + +const char * +test_events_describe (void); static const gchar * get_event_type_name (const ClutterEvent *event) @@ -53,7 +59,7 @@ get_event_type_name (const ClutterEvent *event) static gchar * get_event_state_string (const ClutterEvent *event) { - gchar *mods[18]; + const char *mods[18]; int i = 0; ClutterModifierType state = clutter_event_get_state (event); @@ -96,7 +102,7 @@ get_event_state_string (const ClutterEvent *event) mods[i++] = "-"; mods[i] = NULL; - return g_strjoinv (",", mods); + return g_strjoinv (",", (char **) mods); } static void @@ -108,28 +114,6 @@ stage_state_cb (ClutterStage *stage, printf("[stage signal] %s\n", detail); } -static gboolean -blue_button_cb (ClutterActor *actor, - ClutterEvent *event, - gpointer data) -{ - ClutterActor *stage; - - stage = clutter_actor_get_stage (actor); - - if (IsFullScreen) - IsFullScreen = FALSE; - else - IsFullScreen = TRUE; - - clutter_stage_set_fullscreen (CLUTTER_STAGE (stage), IsFullScreen); - - g_print ("*** Fullscreen %s ***\n", - IsFullScreen ? "enabled" : "disabled"); - - return FALSE; -} - static gboolean red_button_cb (ClutterActor *actor, ClutterEvent *event, @@ -168,7 +152,7 @@ static void key_focus_in_cb (ClutterActor *actor, gpointer data) { - ClutterActor *focus_box = CLUTTER_ACTOR (data); + ClutterActor *focus_box = CLUTTER_ACTOR (data); if (CLUTTER_IS_STAGE (actor)) clutter_actor_hide (focus_box); @@ -232,9 +216,9 @@ input_cb (ClutterActor *actor, ClutterEvent *event, gpointer data) { - ClutterActor *stage = clutter_actor_get_stage (actor); + ClutterActor *stage = clutter_actor_get_stage (actor); ClutterActor *source_actor = clutter_event_get_source (event); - ClutterPoint position; + graphene_point_t position; gchar *state; gchar keybuf[128]; gint device_id; @@ -371,15 +355,40 @@ input_cb (ClutterActor *actor, case CLUTTER_DELETE: g_print ("[%s] DELETE", clutter_actor_get_name (source_actor)); break; + case CLUTTER_TOUCHPAD_PINCH: + g_print ("[%s] TOUCHPAD PINCH", clutter_actor_get_name (source_actor)); + break; + case CLUTTER_TOUCHPAD_SWIPE: + g_print ("[%s] TOUCHPAD SWIPE", clutter_actor_get_name (source_actor)); + break; + case CLUTTER_PROXIMITY_IN: + g_print ("[%s] PROXIMITY IN", clutter_actor_get_name (source_actor)); + break; + case CLUTTER_PROXIMITY_OUT: + g_print ("[%s] PROXIMITY OUT", clutter_actor_get_name (source_actor)); + break; + case CLUTTER_PAD_BUTTON_PRESS: + g_print ("[%s] PAD BUTTON PRESS", clutter_actor_get_name (source_actor)); + break; + case CLUTTER_PAD_BUTTON_RELEASE: + g_print ("[%s] PAD BUTTON RELEASE", clutter_actor_get_name (source_actor)); + break; + case CLUTTER_PAD_STRIP: + g_print ("[%s] PAD STRIP", clutter_actor_get_name (source_actor)); + break; + case CLUTTER_PAD_RING: + g_print ("[%s] PAD RING", clutter_actor_get_name (source_actor)); + break; case CLUTTER_NOTHING: + default: return FALSE; } - free (state); + g_free (state); if (source_actor == actor) g_print (" *source*"); - + g_print ("\n"); return FALSE; @@ -397,15 +406,11 @@ test_events_main (int argc, char *argv[]) clutter_stage_set_title (CLUTTER_STAGE (stage), "Events"); clutter_actor_set_name (stage, "Stage"); g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); - g_signal_connect (stage, "event", G_CALLBACK (input_cb), "stage"); - g_signal_connect (stage, "fullscreen", - G_CALLBACK (stage_state_cb), "fullscreen"); - g_signal_connect (stage, "unfullscreen", - G_CALLBACK (stage_state_cb), "unfullscreen"); - g_signal_connect (stage, "activate", - G_CALLBACK (stage_state_cb), "activate"); - g_signal_connect (stage, "deactivate", - G_CALLBACK (stage_state_cb), "deactivate"); + g_signal_connect (stage, "event", G_CALLBACK (input_cb), (char *) "stage"); + g_signal_connect (stage, "activate", + G_CALLBACK (stage_state_cb), (char *) "activate"); + g_signal_connect (stage, "deactivate", + G_CALLBACK (stage_state_cb), (char *) "deactivate"); focus_box = clutter_rectangle_new_with_color (CLUTTER_COLOR_Black); clutter_actor_set_name (focus_box, "Focus Box"); @@ -417,7 +422,7 @@ test_events_main (int argc, char *argv[]) clutter_actor_set_position (actor, 100, 100); clutter_actor_set_reactive (actor, TRUE); clutter_container_add (CLUTTER_CONTAINER (stage), actor, NULL); - g_signal_connect (actor, "event", G_CALLBACK (input_cb), "red box"); + g_signal_connect (actor, "event", G_CALLBACK (input_cb), (char *) "red box"); g_signal_connect (actor, "key-focus-in", G_CALLBACK (key_focus_in_cb), focus_box); /* Toggle motion - enter/leave capture */ @@ -432,31 +437,18 @@ test_events_main (int argc, char *argv[]) clutter_actor_set_position (actor, 250, 100); clutter_actor_set_reactive (actor, TRUE); clutter_container_add (CLUTTER_CONTAINER (stage), actor, NULL); - g_signal_connect (actor, "event", G_CALLBACK (input_cb), "green box"); + g_signal_connect (actor, "event", G_CALLBACK (input_cb), (char *) "green box"); g_signal_connect (actor, "key-focus-in", G_CALLBACK (key_focus_in_cb), focus_box); g_signal_connect (actor, "captured-event", G_CALLBACK (capture_cb), NULL); - actor = clutter_rectangle_new_with_color (CLUTTER_COLOR_Blue); - clutter_actor_set_name (actor, "Blue Box"); - clutter_actor_set_size (actor, 100, 100); - clutter_actor_set_position (actor, 400, 100); - clutter_actor_set_reactive (actor, TRUE); - clutter_container_add (CLUTTER_CONTAINER(stage), actor, NULL); - g_signal_connect (actor, "event", G_CALLBACK (input_cb), "blue box"); - g_signal_connect (actor, "key-focus-in", G_CALLBACK (key_focus_in_cb), - focus_box); - /* Fullscreen */ - g_signal_connect (actor, "button-press-event", - G_CALLBACK (blue_button_cb), NULL); - /* non reactive */ actor = clutter_rectangle_new_with_color (CLUTTER_COLOR_Black); clutter_actor_set_name (actor, "Black Box"); clutter_actor_set_size (actor, 400, 50); clutter_actor_set_position (actor, 100, 250); clutter_container_add (CLUTTER_CONTAINER(stage), actor, NULL); - g_signal_connect (actor, "event", G_CALLBACK (input_cb), "blue box"); + g_signal_connect (actor, "event", G_CALLBACK (input_cb), (char *) "blue box"); g_signal_connect (actor, "key-focus-in", G_CALLBACK (key_focus_in_cb), focus_box); g_signal_connect (stage, "key-focus-in", G_CALLBACK (key_focus_in_cb), @@ -468,7 +460,7 @@ test_events_main (int argc, char *argv[]) clutter_actor_set_size (actor, 100, 100); clutter_actor_set_reactive (actor, TRUE); - g_signal_connect (actor, "event", G_CALLBACK (input_cb), "yellow box"); + g_signal_connect (actor, "event", G_CALLBACK (input_cb), (char *) "yellow box"); /* note group not reactive */ group = clutter_group_new (); diff --git a/clutter/tests/interactive/test-grab.c b/src/tests/clutter/interactive/test-grab.c similarity index 74% rename from clutter/tests/interactive/test-grab.c rename to src/tests/clutter/interactive/test-grab.c index 931d0c464..eabec8778 100644 --- a/clutter/tests/interactive/test-grab.c +++ b/src/tests/clutter/interactive/test-grab.c @@ -1,6 +1,12 @@ #include <gmodule.h> #include <clutter/clutter.h> +int +test_grab_main (int argc, char *argv[]); + +const char * +test_grab_describe (void); + static void stage_state_cb (ClutterStage *stage, gpointer data) @@ -63,7 +69,44 @@ debug_event_cb (ClutterActor *actor, case CLUTTER_DELETE: printf("[%s] DELETE", source); break; + case CLUTTER_TOUCH_BEGIN: + g_print ("[%s] TOUCH BEGIN", source); + break; + case CLUTTER_TOUCH_UPDATE: + g_print ("[%s] TOUCH UPDATE", source); + break; + case CLUTTER_TOUCH_END: + g_print ("[%s] TOUCH END", source); + break; + case CLUTTER_TOUCH_CANCEL: + g_print ("[%s] TOUCH CANCEL", source); + break; + case CLUTTER_TOUCHPAD_PINCH: + g_print ("[%s] TOUCHPAD PINCH", source); + break; + case CLUTTER_TOUCHPAD_SWIPE: + g_print ("[%s] TOUCHPAD SWIPE", source); + break; + case CLUTTER_PROXIMITY_IN: + g_print ("[%s] PROXIMITY IN", source); + break; + case CLUTTER_PROXIMITY_OUT: + g_print ("[%s] PROXIMITY OUT", source); + break; + case CLUTTER_PAD_BUTTON_PRESS: + g_print ("[%s] PAD BUTTON PRESS", source); + break; + case CLUTTER_PAD_BUTTON_RELEASE: + g_print ("[%s] PAD BUTTON RELEASE", source); + break; + case CLUTTER_PAD_STRIP: + g_print ("[%s] PAD STRIP", source); + break; + case CLUTTER_PAD_RING: + g_print ("[%s] PAD RING", source); + break; case CLUTTER_NOTHING: + default: return FALSE; } @@ -80,7 +123,9 @@ grab_pointer_cb (ClutterActor *actor, ClutterEvent *event, gpointer data) { - clutter_grab_pointer (actor); + ClutterInputDevice *device = clutter_event_get_device (event); + + clutter_input_device_grab (device, actor); return FALSE; } @@ -89,7 +134,9 @@ red_release_cb (ClutterActor *actor, ClutterEvent *event, gpointer data) { - clutter_ungrab_pointer (); + ClutterInputDevice *device = clutter_event_get_device (event); + + clutter_input_device_ungrab (device); return FALSE; } @@ -126,14 +173,17 @@ toggle_grab_pointer_cb (ClutterActor *actor, ClutterEvent *event, gpointer data) { + ClutterInputDevice *device = clutter_event_get_device (event); + /* we only deal with the event if the source is ourself */ if (event->button.source == actor) { - if (clutter_get_pointer_grab () != NULL) - clutter_ungrab_pointer (); + if (clutter_input_device_get_grabbed_actor (device) != NULL) + clutter_input_device_ungrab (device); else - clutter_grab_pointer (actor); + clutter_input_device_grab (device, actor); } + return FALSE; } @@ -142,10 +192,15 @@ cyan_press_cb (ClutterActor *actor, ClutterEvent *event, gpointer data) { - if (clutter_get_keyboard_grab () != NULL) - clutter_ungrab_keyboard (); + ClutterBackend *backend = clutter_get_default_backend (); + ClutterSeat *seat = clutter_backend_get_default_seat (backend); + ClutterInputDevice *device = clutter_seat_get_pointer (seat); + + if (clutter_input_device_get_grabbed_actor (device) != NULL) + clutter_input_device_ungrab (device); else - clutter_grab_keyboard (actor); + clutter_input_device_grab (device, actor); + return FALSE; } @@ -174,22 +229,18 @@ test_grab_main (int argc, char *argv[]) clutter_stage_set_title (CLUTTER_STAGE (stage), "Grabs"); g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); g_signal_connect (stage, "event", - G_CALLBACK (debug_event_cb), "stage"); - g_signal_connect (stage, "fullscreen", - G_CALLBACK (stage_state_cb), "fullscreen"); - g_signal_connect (stage, "unfullscreen", - G_CALLBACK (stage_state_cb), "unfullscreen"); + G_CALLBACK (debug_event_cb), (char *) "stage"); g_signal_connect (stage, "activate", - G_CALLBACK (stage_state_cb), "activate"); + G_CALLBACK (stage_state_cb), (char *) "activate"); g_signal_connect (stage, "deactivate", - G_CALLBACK (stage_state_cb), "deactivate"); + G_CALLBACK (stage_state_cb), (char *) "deactivate"); actor = clutter_rectangle_new_with_color (&rcol); clutter_actor_set_size (actor, 100, 100); clutter_actor_set_position (actor, 100, 100); clutter_actor_set_reactive (actor, TRUE); clutter_container_add (CLUTTER_CONTAINER (stage), actor, NULL); - g_signal_connect (actor, "event", G_CALLBACK (debug_event_cb), "red box"); + g_signal_connect (actor, "event", G_CALLBACK (debug_event_cb), (char *) "red box"); g_signal_connect (actor, "button-press-event", G_CALLBACK (grab_pointer_cb), NULL); g_signal_connect (actor, "button-release-event", @@ -200,7 +251,7 @@ test_grab_main (int argc, char *argv[]) clutter_actor_set_position (actor, 100, 300); clutter_actor_set_reactive (actor, TRUE); clutter_container_add (CLUTTER_CONTAINER (stage), actor, NULL); - g_signal_connect (actor, "event", G_CALLBACK (debug_event_cb), "yellow box"); + g_signal_connect (actor, "event", G_CALLBACK (debug_event_cb), (char *) "yellow box"); g_signal_connect (actor, "button-press-event", G_CALLBACK (toggle_grab_pointer_cb), NULL); @@ -210,7 +261,7 @@ test_grab_main (int argc, char *argv[]) clutter_actor_set_reactive (actor, TRUE); clutter_container_add (CLUTTER_CONTAINER (stage), actor, NULL); g_signal_connect (actor, "event", - G_CALLBACK (debug_event_cb), "blue box"); + G_CALLBACK (debug_event_cb), (char *) "blue box"); g_signal_connect (actor, "button-press-event", G_CALLBACK (grab_pointer_cb), NULL); g_signal_connect (actor, "button-release-event", @@ -222,7 +273,7 @@ test_grab_main (int argc, char *argv[]) clutter_actor_set_reactive (actor, TRUE); clutter_container_add (CLUTTER_CONTAINER (stage), actor, NULL); g_signal_connect (actor, "event", - G_CALLBACK (debug_event_cb), "green box"); + G_CALLBACK (debug_event_cb), (char *) "green box"); g_signal_connect (actor, "button-press-event", G_CALLBACK (green_press_cb), NULL); @@ -233,7 +284,7 @@ test_grab_main (int argc, char *argv[]) clutter_actor_set_reactive (actor, TRUE); clutter_container_add (CLUTTER_CONTAINER (stage), actor, NULL); g_signal_connect (actor, "event", - G_CALLBACK (debug_event_cb), "cyan box"); + G_CALLBACK (debug_event_cb), (char *) "cyan box"); g_signal_connect (actor, "button-press-event", G_CALLBACK (cyan_press_cb), NULL); diff --git a/clutter/tests/interactive/test-image.c b/src/tests/clutter/interactive/test-image.c similarity index 92% rename from clutter/tests/interactive/test-image.c rename to src/tests/clutter/interactive/test-image.c index 3ee83f1c4..81fd3c36d 100644 --- a/clutter/tests/interactive/test-image.c +++ b/src/tests/clutter/interactive/test-image.c @@ -18,16 +18,25 @@ typedef struct _SolidContentClass { GObjectClass parent_class; } SolidContentClass; -static void clutter_content_iface_init (ClutterContentIface *iface); +static void clutter_content_iface_init (ClutterContentInterface *iface); + +GType solid_content_get_type (void); + +const char * +test_image_describe (void); + +int +test_image_main (int argc, char *argv[]); G_DEFINE_TYPE_WITH_CODE (SolidContent, solid_content, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTENT, clutter_content_iface_init)) static void -solid_content_paint_content (ClutterContent *content, - ClutterActor *actor, - ClutterPaintNode *root) +solid_content_paint_content (ClutterContent *content, + ClutterActor *actor, + ClutterPaintNode *root, + ClutterPaintContext *paint_context) { SolidContent *self = (SolidContent *) content; ClutterActorBox box, content_box; @@ -128,7 +137,7 @@ solid_content_paint_content (ClutterContent *content, } static void -clutter_content_iface_init (ClutterContentIface *iface) +clutter_content_iface_init (ClutterContentInterface *iface) { iface->paint_content = solid_content_paint_content; } @@ -181,7 +190,6 @@ test_image_main (int argc, char *argv[]) stage = clutter_stage_new (); clutter_actor_set_name (stage, "Stage"); clutter_stage_set_title (CLUTTER_STAGE (stage), "Content"); - clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE); g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); clutter_actor_show (stage); @@ -230,8 +238,8 @@ test_image_main (int argc, char *argv[]) name = g_strconcat ("Box <", color, ">", NULL); clutter_actor_set_name (box, name); - free (name); - free (str); + g_free (name); + g_free (str); if ((i % 2) == 0) clutter_actor_set_content (box, color); diff --git a/clutter/tests/interactive/test-keyframe-transition.c b/src/tests/clutter/interactive/test-keyframe-transition.c similarity index 96% rename from clutter/tests/interactive/test-keyframe-transition.c rename to src/tests/clutter/interactive/test-keyframe-transition.c index 8c8c9b8d6..ec5d0c5b5 100644 --- a/clutter/tests/interactive/test-keyframe-transition.c +++ b/src/tests/clutter/interactive/test-keyframe-transition.c @@ -11,6 +11,12 @@ static const ClutterColor colors[] = { #define PADDING (64.0f) #define SIZE (64.0f) +const char * +test_keyframe_transition_describe (void); + +int +test_keyframe_transition_main (int argc, char *argv[]); + static void on_transition_stopped (ClutterActor *actor, const gchar *transition_name, @@ -97,7 +103,7 @@ test_keyframe_transition_main (int argc, char *argv[]) NULL); g_object_unref (group); - free (name); + g_free (name); } clutter_actor_show (stage); diff --git a/clutter/tests/interactive/test-layout.c b/src/tests/clutter/interactive/test-layout.c similarity index 97% rename from clutter/tests/interactive/test-layout.c rename to src/tests/clutter/interactive/test-layout.c index ec3ebada0..9666f15df 100644 --- a/clutter/tests/interactive/test-layout.c +++ b/src/tests/clutter/interactive/test-layout.c @@ -5,6 +5,7 @@ #include <cogl/cogl.h> #include <clutter/clutter.h> +#include "test-utils.h" /* layout actor, by Lucas Rocha */ @@ -40,11 +41,6 @@ enum PROP_USE_TRANSFORMED_BOX }; -G_DEFINE_TYPE (MyThing, my_thing, CLUTTER_TYPE_ACTOR) - -#define MY_THING_GET_PRIVATE(obj) \ -(G_TYPE_INSTANCE_GET_PRIVATE ((obj), MY_TYPE_THING, MyThingPrivate)) - struct _MyThingPrivate { gfloat spacing; @@ -53,6 +49,19 @@ struct _MyThingPrivate guint use_transformed_box : 1; }; +GType my_thing_get_type (void); + +int +test_layout_main (int argc, char *argv[]); + +const char * +test_layout_describe (void); + +G_DEFINE_TYPE_WITH_PRIVATE (MyThing, my_thing, CLUTTER_TYPE_ACTOR) + +#define MY_THING_GET_PRIVATE(obj) \ +(G_TYPE_INSTANCE_GET_PRIVATE ((obj), MY_TYPE_THING, MyThingPrivate)) + static void my_thing_set_property (GObject *gobject, guint prop_id, @@ -326,7 +335,7 @@ my_thing_allocate (ClutterActor *self, if (clutter_actor_is_scaled (child) || clutter_actor_is_rotated (child)) { - ClutterVertex v1 = { 0, }, v2 = { 0, }; + graphene_point3d_t v1 = { 0, }, v2 = { 0, }; ClutterActorBox transformed_box = { 0, }; /* origin */ @@ -409,8 +418,6 @@ my_thing_class_init (MyThingClass *klass) "Use transformed box when allocating", FALSE, G_PARAM_READWRITE)); - - g_type_class_add_private (klass, sizeof (MyThingPrivate)); } static void @@ -419,7 +426,7 @@ my_thing_init (MyThing *thing) thing->priv = MY_THING_GET_PRIVATE (thing); } -ClutterActor * +static ClutterActor * my_thing_new (gfloat padding, gfloat spacing) { @@ -623,10 +630,10 @@ test_layout_main (int argc, char *argv[]) clutter_actor_set_position (box, 20, 20); clutter_actor_set_size (box, 350, -1); - icon = clutter_texture_new_from_file (TESTS_DATADIR - G_DIR_SEPARATOR_S - "redhand.png", - &error); + icon = clutter_test_utils_create_texture_from_file (TESTS_DATADIR + G_DIR_SEPARATOR_S + "redhand.png", + &error); if (error) g_error ("Unable to load 'redhand.png': %s", error->message); diff --git a/clutter/tests/interactive/test-main.c b/src/tests/clutter/interactive/test-main.c similarity index 88% rename from clutter/tests/interactive/test-main.c rename to src/tests/clutter/interactive/test-main.c index 8fcc205f8..95b45bb4c 100644 --- a/clutter/tests/interactive/test-main.c +++ b/src/tests/clutter/interactive/test-main.c @@ -1,8 +1,15 @@ +#include "config.h" + #include <stdlib.h> #include <string.h> #include <glib.h> #include <gmodule.h> +#include "backends/x11/nested/meta-backend-x11-nested.h" +#include "core/main-private.h" +#include "meta/main.h" +#include "wayland/meta-wayland.h" +#include "wayland/meta-xwayland.h" #include "test-unit-names.h" #define MAX_DESC_SIZE 72 @@ -21,7 +28,7 @@ get_symbol_with_suffix (const char *unit_name, g_module_symbol (module, main_symbol_name, &func); - free (main_symbol_name); + g_free (main_symbol_name); return func; } @@ -119,6 +126,12 @@ main (int argc, char **argv) g_option_context_free (context); + meta_wayland_override_display_name ("mutter-test-display"); + meta_xwayland_override_display_number (512); + meta_override_compositor_configuration (META_COMPOSITOR_TYPE_WAYLAND, + META_TYPE_BACKEND_X11_NESTED); + meta_init (); + module = g_module_open (NULL, 0); if (!module) g_error ("*** Failed to open self for symbol lookup"); @@ -142,7 +155,7 @@ main (int argc, char **argv) (int) (len - strlen (str)), " ", str); - free (str); + g_free (str); } ret = EXIT_SUCCESS; @@ -188,7 +201,7 @@ main (int argc, char **argv) g_print ("* %s:\n%s\n\n", unit_test, str); - free (str); + g_free (str); ret = EXIT_SUCCESS; } @@ -205,12 +218,12 @@ main (int argc, char **argv) ret = unit_test_main (n_unit_names, unit_names); - free (unit_test); + g_free (unit_test); break; } - free (unit_test); + g_free (unit_test); } out: diff --git a/clutter/tests/interactive/test-paint-wrapper.c b/src/tests/clutter/interactive/test-paint-wrapper.c similarity index 80% rename from clutter/tests/interactive/test-paint-wrapper.c rename to src/tests/clutter/interactive/test-paint-wrapper.c index 352adce5f..6e8c293db 100644 --- a/clutter/tests/interactive/test-paint-wrapper.c +++ b/src/tests/clutter/interactive/test-paint-wrapper.c @@ -15,6 +15,8 @@ #include "clutter/x11/clutter-x11.h" #endif +#include "test-utils.h" + #define NHANDS 6 typedef struct SuperOH @@ -28,11 +30,9 @@ typedef struct SuperOH gint stage_height; gfloat radius; - ClutterBehaviour *scaler_1; - ClutterBehaviour *scaler_2; ClutterTimeline *timeline; - guint frame_id; + gulong frame_id; gboolean *paint_guards; } SuperOH; @@ -56,6 +56,12 @@ static GOptionEntry super_oh_entries[] = { { NULL } }; +int +test_paint_wrapper_main (int argc, char *argv[]); + +const char * +test_paint_wrapper_describe (void); + static gboolean on_button_press_event (ClutterActor *actor, ClutterEvent *event, @@ -137,20 +143,15 @@ frame_cb (ClutterTimeline *timeline, } } -static gdouble -my_sine_wave (ClutterAlpha *alpha, - gpointer dummy G_GNUC_UNUSED) -{ - ClutterTimeline *timeline = clutter_alpha_get_timeline (alpha); - gdouble progress = clutter_timeline_get_progress (timeline); - - return sin (progress * G_PI); -} - static void -hand_pre_paint (ClutterActor *actor, - gpointer user_data) +hand_pre_paint (ClutterActor *actor, + ClutterPaintContext *paint_context, + gpointer user_data) { + CoglFramebuffer *framebuffer = + clutter_paint_context_get_framebuffer (paint_context); + CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); + CoglPipeline *pipeline; SuperOH *oh = user_data; gfloat w, h; int actor_num; @@ -162,16 +163,24 @@ hand_pre_paint (ClutterActor *actor, clutter_actor_get_size (actor, &w, &h); - cogl_set_source_color4ub (255, 0, 0, 128); - cogl_rectangle (0, 0, w / 2, h / 2); + pipeline = cogl_pipeline_new (ctx); + cogl_pipeline_set_color4ub (pipeline, 255, 0, 0, 128); + cogl_framebuffer_draw_rectangle (framebuffer, pipeline, + 0, 0, w / 2, h / 2); + cogl_object_unref (pipeline); oh->paint_guards[actor_num] = TRUE; } static void -hand_post_paint (ClutterActor *actor, - gpointer user_data) +hand_post_paint (ClutterActor *actor, + ClutterPaintContext *paint_context, + gpointer user_data) { + CoglFramebuffer *framebuffer = + clutter_paint_context_get_framebuffer (paint_context); + CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); + CoglPipeline *pipeline; SuperOH *oh = user_data; gfloat w, h; int actor_num; @@ -183,8 +192,11 @@ hand_post_paint (ClutterActor *actor, clutter_actor_get_size (actor, &w, &h); - cogl_set_source_color4ub (0, 255, 0, 128); - cogl_rectangle (w / 2, h / 2, w, h); + pipeline = cogl_pipeline_new (ctx); + cogl_pipeline_set_color4ub (pipeline, 0, 255, 0, 128); + cogl_framebuffer_draw_rectangle (framebuffer, pipeline, + w / 2, h / 2, w, h); + cogl_object_unref (pipeline); oh->paint_guards[actor_num] = FALSE; } @@ -193,7 +205,7 @@ static void stop_and_quit (ClutterActor *actor, SuperOH *oh) { - g_signal_handler_disconnect (oh->timeline, oh->frame_id); + g_clear_signal_handler (&oh->frame_id, oh->timeline); clutter_timeline_stop (oh->timeline); clutter_main_quit (); @@ -202,7 +214,6 @@ stop_and_quit (ClutterActor *actor, G_MODULE_EXPORT int test_paint_wrapper_main (int argc, char *argv[]) { - ClutterAlpha *alpha; ClutterActor *stage; ClutterColor stage_color = { 0x61, 0x64, 0x8c, 0xff }; SuperOH *oh; @@ -254,16 +265,10 @@ test_paint_wrapper_main (int argc, char *argv[]) oh->frame_id = g_signal_connect (oh->timeline, "new-frame", G_CALLBACK (frame_cb), oh); - /* Set up some behaviours to handle scaling */ - alpha = clutter_alpha_new_with_func (oh->timeline, my_sine_wave, NULL, NULL); - - oh->scaler_1 = clutter_behaviour_scale_new (alpha, 0.5, 0.5, 1.0, 1.0); - oh->scaler_2 = clutter_behaviour_scale_new (alpha, 1.0, 1.0, 0.5, 0.5); - - real_hand = clutter_texture_new_from_file (TESTS_DATADIR - G_DIR_SEPARATOR_S - "redhand.png", - &error); + real_hand = clutter_test_utils_create_texture_from_file (TESTS_DATADIR + G_DIR_SEPARATOR_S + "redhand.png", + &error); if (real_hand == NULL) { g_error ("image load failed: %s", error->message); @@ -328,14 +333,9 @@ test_paint_wrapper_main (int argc, char *argv[]) /* Add to our group group */ clutter_container_add_actor (CLUTTER_CONTAINER (oh->group), oh->hand[i]); - - if (i % 2) - clutter_behaviour_apply (oh->scaler_1, oh->hand[i]); - else - clutter_behaviour_apply (oh->scaler_2, oh->hand[i]); } - oh->paint_guards = calloc (1, sizeof (gboolean) * n_hands); + oh->paint_guards = g_malloc0 (sizeof (gboolean) * n_hands); /* Add the group to the stage */ clutter_container_add_actor (CLUTTER_CONTAINER (stage), @@ -353,12 +353,10 @@ test_paint_wrapper_main (int argc, char *argv[]) clutter_main (); - g_object_unref (oh->scaler_1); - g_object_unref (oh->scaler_2); g_object_unref (oh->timeline); - free (oh->paint_guards); - free (oh->hand); - free (oh); + g_free (oh->paint_guards); + g_free (oh->hand); + g_free (oh); return 0; } diff --git a/clutter/tests/interactive/test-path-constraint.c b/src/tests/clutter/interactive/test-path-constraint.c similarity index 97% rename from clutter/tests/interactive/test-path-constraint.c rename to src/tests/clutter/interactive/test-path-constraint.c index 9d2dd1c48..f802ed481 100644 --- a/clutter/tests/interactive/test-path-constraint.c +++ b/src/tests/clutter/interactive/test-path-constraint.c @@ -11,6 +11,10 @@ static gboolean toggled = FALSE; +int +test_path_constraint_main (int argc, + char *argv[]); + static gboolean on_button_press (ClutterActor *actor, const ClutterEvent *event, @@ -91,7 +95,7 @@ on_node_reached (ClutterPathConstraint *constraint, str = node_to_string (&node); g_print ("Node %d reached: %s\n", index_, str); - free (str); + g_free (str); } G_MODULE_EXPORT int diff --git a/clutter/tests/interactive/test-rotate-zoom.c b/src/tests/clutter/interactive/test-rotate-zoom.c similarity index 96% rename from clutter/tests/interactive/test-rotate-zoom.c rename to src/tests/clutter/interactive/test-rotate-zoom.c index 2c25d7f7f..071e454b3 100644 --- a/clutter/tests/interactive/test-rotate-zoom.c +++ b/src/tests/clutter/interactive/test-rotate-zoom.c @@ -26,6 +26,12 @@ #define STAGE_WIDTH 800 #define STAGE_HEIGHT 550 +int +test_rotate_zoom_main (int argc, char *argv[]); + +const char * +test_rotate_zoom_describe (void); + static ClutterActor * create_hand (void) { @@ -67,7 +73,6 @@ test_rotate_zoom_main (int argc, char *argv[]) stage = clutter_stage_new (); g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); clutter_stage_set_title (CLUTTER_STAGE (stage), "Rotate and Zoom actions"); - clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE); clutter_actor_set_size (stage, STAGE_WIDTH, STAGE_HEIGHT); clutter_actor_set_reactive (stage, FALSE); clutter_actor_show (stage); diff --git a/clutter/tests/interactive/test-script-signals.json b/src/tests/clutter/interactive/test-script-signals.json similarity index 100% rename from clutter/tests/interactive/test-script-signals.json rename to src/tests/clutter/interactive/test-script-signals.json diff --git a/clutter/tests/interactive/test-script.c b/src/tests/clutter/interactive/test-script.c similarity index 72% rename from clutter/tests/interactive/test-script.c rename to src/tests/clutter/interactive/test-script.c index f0b508a2f..999e5191b 100644 --- a/clutter/tests/interactive/test-script.c +++ b/src/tests/clutter/interactive/test-script.c @@ -10,6 +10,9 @@ static ClutterScript *script = NULL; static guint merge_id = 0; +int +test_script_main (int argc, char *argv[]); + static const gchar *test_unmerge = "[" " {" @@ -44,59 +47,8 @@ static const gchar *test_behaviour = " \"function\" : \"sine_alpha\"," " \"timeline\" : \"main-timeline\"" " }," -" {" -" \"id\" : \"path-behaviour\"," -" \"type\" : \"ClutterBehaviourPath\"," -" \"path\" : \"M 50 50 L 100 100\"," -" \"alpha\" : {" -" \"timeline\" : \"main-timeline\"," -" \"function\" : \"double_ramp_alpha\"" -" }" -" }," -" {" -" \"id\" : \"rotate-behaviour\"," -" \"type\" : \"ClutterBehaviourRotate\"," -" \"angle-start\" : 0.0," -" \"angle-end\" : 360.0," -" \"axis\" : \"y-axis\"," -" \"alpha\" : \"sine-alpha\"" -" }," -" {" -" \"id\" : \"fade-behaviour\"," -" \"type\" : \"ClutterBehaviourOpacity\"," -" \"opacity-start\" : 255," -" \"opacity-end\" : 0," -" \"alpha\" : {" -" \"id\" : \"fade-alpha\"," -" \"type\" : \"ClutterAlpha\"," -" \"timeline\" : \"main-timeline\"," -" \"mode\" : \"linear\"" -" }" -" }" "]"; -gdouble -sine_alpha (ClutterAlpha *alpha, - gpointer dummy G_GNUC_UNUSED) -{ - ClutterTimeline *timeline = clutter_alpha_get_timeline (alpha); - - return sin (clutter_timeline_get_progress (timeline) * G_PI); -} - -gdouble -double_ramp_alpha (ClutterAlpha *alpha, - gpointer dummy G_GNUC_UNUSED) -{ - ClutterTimeline *timeline = clutter_alpha_get_timeline (alpha); - gdouble progress = clutter_timeline_get_progress (timeline); - - if (progress >= 0.5) - return 1.0 - progress; - - return progress; -} - static gboolean blue_button_press (ClutterActor *actor, ClutterButtonEvent *event, @@ -162,11 +114,11 @@ test_script_main (int argc, char *argv[]) "*** %s\n", error->message); g_error_free (error); g_object_unref (script); - free (file); + g_free (file); return EXIT_FAILURE; } - free (file); + g_free (file); merge_id = clutter_script_load_from_data (script, test_unmerge, -1, &error); if (error) diff --git a/clutter/tests/interactive/test-script.json b/src/tests/clutter/interactive/test-script.json similarity index 71% rename from clutter/tests/interactive/test-script.json rename to src/tests/clutter/interactive/test-script.json index 54d4fb457..ce135cb3a 100644 --- a/clutter/tests/interactive/test-script.json +++ b/src/tests/clutter/interactive/test-script.json @@ -17,8 +17,7 @@ "reactive" : true, "rotation" : [ { "z-axis" : [ 45.0, [ 75, 75 ] ] } - ], - "behaviours" : [ "fade-behaviour", "path-behaviour" ] + ] }, { "id" : "green-button", @@ -34,25 +33,6 @@ { "name" : "button-press-event", "handler" : "clutter_main_quit" } ] }, - { - "id" : "red-hand", - "type" : "ClutterTexture", - "filename" : "redhand.png", - "position" : { "x" : 100.0, "y" : 100.0 }, - "width" : "20 mm", - "keep-aspect-ratio" : true, - "anchor-x" : "5 em", - "anchor-y" : "5 pt", - "opacity" : 100, - "behaviours" : [ "rotate-behaviour", "fade-behaviour" ] - }, - { - "id" : "red-hand-clone", - "type" : "ClutterClone", - "source" : "red-hand", - "position" : [ 250.0, 150.0 ], - "opacity" : 100 - }, { "id" : "label", "type" : "ClutterText", diff --git a/clutter/tests/interactive/test-scrolling.c b/src/tests/clutter/interactive/test-scrolling.c similarity index 98% rename from clutter/tests/interactive/test-scrolling.c rename to src/tests/clutter/interactive/test-scrolling.c index 173325fda..d4137bf14 100644 --- a/clutter/tests/interactive/test-scrolling.c +++ b/src/tests/clutter/interactive/test-scrolling.c @@ -20,6 +20,9 @@ static const gchar *rect_color[N_RECTS] = { static ClutterActor *rectangle[N_RECTS]; static ClutterActor *viewport = NULL; +int +test_scrolling_main (int argc, char *argv[]); + static void on_drag_end (ClutterDragAction *action, ClutterActor *actor, diff --git a/clutter/tests/interactive/test-shader-effects.c b/src/tests/clutter/interactive/test-shader-effects.c similarity index 94% rename from clutter/tests/interactive/test-shader-effects.c rename to src/tests/clutter/interactive/test-shader-effects.c index b516a8113..1fb7cefda 100644 --- a/clutter/tests/interactive/test-shader-effects.c +++ b/src/tests/clutter/interactive/test-shader-effects.c @@ -6,6 +6,10 @@ #include <gmodule.h> #include <clutter/clutter.h> +#include "test-utils.h" + +int +test_shader_effects_main (int argc, char *argv[]); G_MODULE_EXPORT int test_shader_effects_main (int argc, char *argv[]) @@ -28,11 +32,11 @@ test_shader_effects_main (int argc, char *argv[]) /* Make a hand */ file = g_build_filename (TESTS_DATADIR, "redhand.png", NULL); - hand = clutter_texture_new_from_file (file, NULL); + hand = clutter_test_utils_create_texture_from_file (file, NULL); if (!hand) g_error("Unable to load '%s'", file); - free (file); + g_free (file); clutter_actor_set_position (hand, 326, 265); clutter_actor_add_effect_with_name (hand, "desaturate", clutter_desaturate_effect_new (0.75)); @@ -69,7 +73,7 @@ test_shader_effects_main (int argc, char *argv[]) NULL); clutter_container_add (CLUTTER_CONTAINER (stage), rect, hand, label, NULL); - + /* start the timeline and thus the animations */ clutter_timeline_start (timeline); diff --git a/clutter/tests/interactive/test-stage-sizing.c b/src/tests/clutter/interactive/test-stage-sizing.c similarity index 56% rename from clutter/tests/interactive/test-stage-sizing.c rename to src/tests/clutter/interactive/test-stage-sizing.c index 45223011b..c4fedb956 100644 --- a/clutter/tests/interactive/test-stage-sizing.c +++ b/src/tests/clutter/interactive/test-stage-sizing.c @@ -2,20 +2,11 @@ #include <gmodule.h> #include <clutter/clutter.h> -static gboolean -fullscreen_clicked_cb (ClutterStage *stage) -{ - clutter_stage_set_fullscreen (stage, !clutter_stage_get_fullscreen (stage)); - return CLUTTER_EVENT_STOP; -} +int +test_stage_sizing_main (int argc, char *argv[]); -static gboolean -resize_clicked_cb (ClutterStage *stage) -{ - clutter_stage_set_user_resizable (stage, - !clutter_stage_get_user_resizable (stage)); - return CLUTTER_EVENT_STOP; -} +const char * +test_stage_sizing_describe (void); static gboolean shrink_clicked_cb (ClutterActor *stage) @@ -35,22 +26,6 @@ expand_clicked_cb (ClutterActor *stage) return CLUTTER_EVENT_STOP; } -static void -on_fullscreen (ClutterStage *stage) -{ - float width, height; - gboolean is_fullscreen; - - is_fullscreen = clutter_stage_get_fullscreen (stage); - - clutter_actor_get_size (CLUTTER_ACTOR (stage), &width, &height); - - g_print ("Stage size [%s]: %d x %d\n", - is_fullscreen ? "fullscreen" : "not fullscreen", - (int) width, - (int) height); -} - G_MODULE_EXPORT int test_stage_sizing_main (int argc, char *argv[]) { @@ -63,40 +38,12 @@ test_stage_sizing_main (int argc, char *argv[]) stage = clutter_stage_new (); clutter_stage_set_title (CLUTTER_STAGE (stage), "Stage Sizing"); g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); - g_signal_connect_after (stage, "notify::fullscreen-set", G_CALLBACK (on_fullscreen), NULL); box = clutter_actor_new (); clutter_actor_set_layout_manager (box, clutter_box_layout_new ()); clutter_actor_add_constraint (box, clutter_align_constraint_new (stage, CLUTTER_ALIGN_BOTH, 0.5)); clutter_actor_add_child (stage, box); - rect = clutter_actor_new (); - clutter_actor_set_layout_manager (rect, - clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_CENTER, - CLUTTER_BIN_ALIGNMENT_CENTER)); - clutter_actor_set_background_color (rect, CLUTTER_COLOR_LightScarletRed); - clutter_actor_set_reactive (rect, TRUE); - g_signal_connect_swapped (rect, "button-press-event", - G_CALLBACK (fullscreen_clicked_cb), - stage); - label = clutter_text_new_with_text ("Sans 16", "Toggle fullscreen"); - clutter_actor_set_margin (label, &margin); - clutter_actor_add_child (rect, label); - clutter_actor_add_child (box, rect); - - rect = clutter_actor_new (); - clutter_actor_set_layout_manager (rect, - clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_CENTER, - CLUTTER_BIN_ALIGNMENT_CENTER)); - clutter_actor_set_background_color (rect, CLUTTER_COLOR_Chameleon); - clutter_actor_set_reactive (rect, TRUE); - g_signal_connect_swapped (rect, "button-press-event", - G_CALLBACK (resize_clicked_cb), stage); - label = clutter_text_new_with_text ("Sans 16", "Toggle resizable"); - clutter_actor_set_margin (label, &margin); - clutter_actor_add_child (rect, label); - clutter_actor_add_child (box, rect); - rect = clutter_actor_new (); clutter_actor_set_layout_manager (rect, clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_CENTER, diff --git a/clutter/tests/interactive/test-state-script.c b/src/tests/clutter/interactive/test-state-script.c similarity index 82% rename from clutter/tests/interactive/test-state-script.c rename to src/tests/clutter/interactive/test-state-script.c index 34b1b8789..66b54b092 100644 --- a/clutter/tests/interactive/test-state-script.c +++ b/src/tests/clutter/interactive/test-state-script.c @@ -6,15 +6,8 @@ #define TEST_STATE_SCRIPT_FILE "test-script-signals.json" -gboolean -on_button_press (ClutterActor *actor, - ClutterEvent *event, - gpointer dummy G_GNUC_UNUSED) -{ - g_print ("Button pressed!\n"); - - return FALSE; -} +int +test_state_script_main (int argc, char *argv[]); G_MODULE_EXPORT int test_state_script_main (int argc, char *argv[]) @@ -35,7 +28,6 @@ test_state_script_main (int argc, char *argv[]) stage = clutter_stage_new (); clutter_stage_set_title (CLUTTER_STAGE (stage), "State Script"); - clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE); g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); clutter_actor_show (stage); diff --git a/clutter/tests/interactive/test-state.c b/src/tests/clutter/interactive/test-state.c similarity index 96% rename from clutter/tests/interactive/test-state.c rename to src/tests/clutter/interactive/test-state.c index 30a4d41ff..799ec980d 100644 --- a/clutter/tests/interactive/test-state.c +++ b/src/tests/clutter/interactive/test-state.c @@ -2,6 +2,7 @@ #include <math.h> #include <gmodule.h> #include <clutter/clutter.h> +#include "test-utils.h" #define STAGE_WIDTH 1024 #define STAGE_HEIGHT 768 @@ -13,6 +14,12 @@ #define ROWS (STAGE_HEIGHT/ACTOR_HEIGHT) #define TOTAL (ROWS*COLS) +gint +test_state_main (gint argc, + gchar **argv); + +const char * +test_state_describe (void); static gboolean press_event (ClutterActor *actor, ClutterEvent *event, @@ -76,10 +83,10 @@ static ClutterActor *new_rect (gint r, gchar *file = g_build_filename (TESTS_DATADIR, "redhand.png", NULL); - hand = clutter_texture_new_from_file (file, &error); + hand = clutter_test_utils_create_texture_from_file (file, &error); if (rectangle == NULL) g_error ("image load failed: %s", error->message); - free (file); + g_free (file); clutter_actor_set_size (hand, ACTOR_WIDTH,ACTOR_HEIGHT); clutter_actor_set_background_color (rectangle, color); @@ -134,7 +141,7 @@ test_state_main (gint argc, clutter_state_set (layout_state, NULL, "active", actor, "delayed::x", CLUTTER_LINEAR, - ACTOR_WIDTH * 1.0 * ((TOTAL-1-i) % COLS), + ACTOR_WIDTH * 1.0 * ((TOTAL-1-i) % COLS), ((row*1.0/ROWS))/2, (1.0-(row*1.0/ROWS))/2, actor, "delayed::y", CLUTTER_LINEAR, ACTOR_HEIGHT * 1.0 * ((TOTAL-1-i) / COLS), diff --git a/clutter/tests/interactive/test-swipe-action.c b/src/tests/clutter/interactive/test-swipe-action.c similarity index 96% rename from clutter/tests/interactive/test-swipe-action.c rename to src/tests/clutter/interactive/test-swipe-action.c index 84b4ca6aa..3d0877401 100644 --- a/clutter/tests/interactive/test-swipe-action.c +++ b/src/tests/clutter/interactive/test-swipe-action.c @@ -1,12 +1,19 @@ #include <stdlib.h> #include <clutter/clutter.h> -enum { +enum +{ VERTICAL = 0, HORIZONTAL = 1, BOTH = 2 }; +int +test_swipe_action_main (int argc, char *argv[]); + +const char * +test_swipe_action_describe (void); + static void swept_cb (ClutterSwipeAction *action, ClutterActor *actor, @@ -39,7 +46,7 @@ swept_cb (ClutterSwipeAction *action, char *old_str = direction_str; direction_str = g_strconcat (direction_str, " up", NULL); - free (old_str); + g_free (old_str); } if (direction & CLUTTER_SWIPE_DIRECTION_DOWN) @@ -47,7 +54,7 @@ swept_cb (ClutterSwipeAction *action, char *old_str = direction_str; direction_str = g_strconcat (direction_str, " down", NULL); - free (old_str); + g_free (old_str); } if (direction & CLUTTER_SWIPE_DIRECTION_LEFT) @@ -55,7 +62,7 @@ swept_cb (ClutterSwipeAction *action, char *old_str = direction_str; direction_str = g_strconcat (direction_str, " left", NULL); - free (old_str); + g_free (old_str); } if (direction & CLUTTER_SWIPE_DIRECTION_RIGHT) @@ -63,12 +70,12 @@ swept_cb (ClutterSwipeAction *action, char *old_str = direction_str; direction_str = g_strconcat (direction_str, " right", NULL); - free (old_str); + g_free (old_str); } g_print ("swept: '%s': %s\n", clutter_actor_get_name (actor), direction_str); - free (direction_str); + g_free (direction_str); } static void diff --git a/clutter/tests/interactive/test-text-field.c b/src/tests/clutter/interactive/test-text-field.c similarity index 93% rename from clutter/tests/interactive/test-text-field.c rename to src/tests/clutter/interactive/test-text-field.c index 18cdfcb71..34d9f00c1 100644 --- a/clutter/tests/interactive/test-text-field.c +++ b/src/tests/clutter/interactive/test-text-field.c @@ -2,6 +2,13 @@ #include <gmodule.h> #include <clutter/clutter.h> +gint +test_text_field_main (gint argc, + gchar **argv); + +const char * +test_text_field_describe (void); + static void on_entry_activate (ClutterText *text, gpointer data) @@ -247,7 +254,7 @@ test_text_field_main (gint argc, { ClutterActor *stage; ClutterActor *box, *label, *entry; - ClutterLayoutManager *table; + ClutterLayoutManager *grid; PangoAttrList *entry_attrs; if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) @@ -258,12 +265,12 @@ test_text_field_main (gint argc, clutter_actor_set_background_color (stage, CLUTTER_COLOR_Black); g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); - table = clutter_table_layout_new (); - clutter_table_layout_set_column_spacing (CLUTTER_TABLE_LAYOUT (table), 6); - clutter_table_layout_set_row_spacing (CLUTTER_TABLE_LAYOUT (table), 6); + grid = clutter_grid_layout_new (); + clutter_grid_layout_set_column_spacing (CLUTTER_GRID_LAYOUT (grid), 6); + clutter_grid_layout_set_row_spacing (CLUTTER_GRID_LAYOUT (grid), 6); box = clutter_actor_new (); - clutter_actor_set_layout_manager (box, table); + clutter_actor_set_layout_manager (box, grid); clutter_actor_add_constraint (box, clutter_bind_constraint_new (stage, CLUTTER_BIND_WIDTH, -24.0)); clutter_actor_add_constraint (box, clutter_bind_constraint_new (stage, CLUTTER_BIND_HEIGHT, -24.0)); clutter_actor_set_position (box, 12, 12); @@ -272,7 +279,7 @@ test_text_field_main (gint argc, label = create_label (CLUTTER_COLOR_White, "<b>Input field:</b>"); g_object_set (label, "min-width", 150.0, NULL); clutter_actor_add_child (box, label); - clutter_layout_manager_child_set (table, CLUTTER_CONTAINER (box), label, + clutter_layout_manager_child_set (grid, CLUTTER_CONTAINER (box), label, "row", 0, "column", 0, "x-expand", FALSE, @@ -284,7 +291,7 @@ test_text_field_main (gint argc, pango_attr_list_insert (entry_attrs, pango_attr_underline_color_new (65535, 0, 0)); entry = create_entry (CLUTTER_COLOR_Black, "somme misspeeled textt", entry_attrs, 0, 0); clutter_actor_add_child (box, entry); - clutter_layout_manager_child_set (table, CLUTTER_CONTAINER (box), entry, + clutter_layout_manager_child_set (grid, CLUTTER_CONTAINER (box), entry, "row", 0, "column", 1, "x-expand", TRUE, @@ -295,7 +302,7 @@ test_text_field_main (gint argc, label = create_label (CLUTTER_COLOR_White, "<b>A very long password field:</b>"); clutter_actor_add_child (box, label); - clutter_layout_manager_child_set (table, CLUTTER_CONTAINER (box), label, + clutter_layout_manager_child_set (grid, CLUTTER_CONTAINER (box), label, "row", 1, "column", 0, "x-expand", FALSE, @@ -304,7 +311,7 @@ test_text_field_main (gint argc, entry = create_entry (CLUTTER_COLOR_Black, "password", NULL, '*', 8); clutter_actor_add_child (box, entry); - clutter_layout_manager_child_set (table, CLUTTER_CONTAINER (box), entry, + clutter_layout_manager_child_set (grid, CLUTTER_CONTAINER (box), entry, "row", 1, "column", 1, "x-expand", TRUE, diff --git a/clutter/tests/interactive/test-text.c b/src/tests/clutter/interactive/test-text.c similarity index 96% rename from clutter/tests/interactive/test-text.c rename to src/tests/clutter/interactive/test-text.c index 37e45a798..bbe2a1b4e 100644 --- a/clutter/tests/interactive/test-text.c +++ b/src/tests/clutter/interactive/test-text.c @@ -10,6 +10,13 @@ static const gchar *runes = "ᛋᚳᛖᚪᛚ᛫ᚦᛖᚪᚻ᛫ᛗᚪᚾᚾᚪ᛫ᚷᛖᚻᚹᛦᛚᚳ᛫ᛗᛁᚳᛚᚢᚾ᛫ᚻᛦᛏ᛫ᛞᚫᛚᚪᚾ\n" "ᚷᛁᚠ᛫ᚻᛖ᛫ᚹᛁᛚᛖ᛫ᚠᚩᚱ᛫ᛞᚱᛁᚻᛏᚾᛖ᛫ᛞᚩᛗᛖᛋ᛫ᚻᛚᛇᛏᚪᚾ᛬\n"; +gint +test_text_main (gint argc, + gchar **argv); + +const char * +test_text_describe (void); + G_MODULE_EXPORT gint test_text_main (gint argc, gchar **argv) diff --git a/clutter/tests/interactive/test-touch-events.c b/src/tests/clutter/interactive/test-touch-events.c similarity index 81% rename from clutter/tests/interactive/test-touch-events.c rename to src/tests/clutter/interactive/test-touch-events.c index 184924a2a..14ad6d314 100644 --- a/clutter/tests/interactive/test-touch-events.c +++ b/src/tests/clutter/interactive/test-touch-events.c @@ -31,7 +31,7 @@ static GQueue events = G_QUEUE_INIT; static GQueue all_events = G_QUEUE_INIT; static gboolean new_surface = TRUE; -static const ClutterColor const static_colors[] = { +static const ClutterColor static_colors[] = { { 0xff, 0x00, 0x00, 0xff }, /* red */ { 0x80, 0x00, 0x00, 0xff }, /* dark red */ { 0x00, 0xff, 0x00, 0xff }, /* green */ @@ -45,11 +45,11 @@ static const ClutterColor const static_colors[] = { }; static GHashTable *sequence_to_color = NULL; -static void -canvas_paint (ClutterCairoTexture *canvas) -{ - clutter_cairo_texture_invalidate (canvas); -} +int +test_touch_events_main (int argc, char *argv[]); + +const char * +test_touch_events_describe (void); static void draw_touch (ClutterEvent *event, @@ -74,8 +74,10 @@ draw_touch (ClutterEvent *event, } static gboolean -draw_touches (ClutterCairoTexture *canvas, - cairo_t *cr) +draw_touches (ClutterCanvas *canvas, + cairo_t *cr, + int width, + int height) { g_queue_foreach (new_surface ? &all_events : &events, (GFunc) draw_touch, cr); g_queue_clear (&events); @@ -85,17 +87,6 @@ draw_touches (ClutterCairoTexture *canvas, return TRUE; } -static cairo_surface_t * -create_surface (ClutterCairoTexture *texture, - guint width, - guint height, - gpointer user_data) -{ - new_surface = TRUE; - - return NULL; -} - static gboolean event_cb (ClutterActor *actor, ClutterEvent *event, ClutterActor *canvas) { @@ -129,7 +120,8 @@ rect_event_cb (ClutterActor *actor, ClutterEvent *event, gpointer data) G_MODULE_EXPORT int test_touch_events_main (int argc, char *argv[]) { - ClutterActor *stage, *canvas; + ClutterActor *stage, *canvas_actor; + ClutterContent *canvas; int i; /* initialize Clutter */ @@ -140,24 +132,21 @@ test_touch_events_main (int argc, char *argv[]) stage = clutter_stage_new (); g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); clutter_stage_set_title (CLUTTER_STAGE (stage), "Touch events"); - clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE); clutter_actor_set_size (stage, STAGE_WIDTH, STAGE_HEIGHT); clutter_actor_set_reactive (stage, TRUE); clutter_actor_show (stage); /* our 2D canvas, courtesy of Cairo */ - canvas = clutter_cairo_texture_new (1, 1); - g_signal_connect (canvas, "paint", G_CALLBACK (canvas_paint), NULL); + canvas = clutter_canvas_new (); + clutter_canvas_set_size (CLUTTER_CANVAS (canvas), STAGE_WIDTH, STAGE_HEIGHT); g_signal_connect (canvas, "draw", G_CALLBACK (draw_touches), NULL); - g_signal_connect (canvas, "create-surface", G_CALLBACK (create_surface), NULL); - clutter_cairo_texture_set_auto_resize (CLUTTER_CAIRO_TEXTURE (canvas), TRUE); - clutter_actor_add_constraint (canvas, - clutter_bind_constraint_new (stage, - CLUTTER_BIND_SIZE, - 0)); - clutter_container_add_actor (CLUTTER_CONTAINER (stage), canvas); - - g_signal_connect (stage, "event", G_CALLBACK (event_cb), canvas); + + canvas_actor = g_object_new (CLUTTER_TYPE_ACTOR, + "content", canvas, + NULL); + clutter_container_add_actor (CLUTTER_CONTAINER (stage), canvas_actor); + + g_signal_connect (stage, "event", G_CALLBACK (event_cb), canvas_actor); for (i = 0; i < NUM_ACTORS; i++) { diff --git a/clutter/tests/interactive/wrapper.sh.in b/src/tests/clutter/interactive/wrapper.sh.in similarity index 100% rename from clutter/tests/interactive/wrapper.sh.in rename to src/tests/clutter/interactive/wrapper.sh.in diff --git a/src/tests/clutter/meson.build b/src/tests/clutter/meson.build new file mode 100644 index 000000000..e09b7f94e --- /dev/null +++ b/src/tests/clutter/meson.build @@ -0,0 +1,7 @@ +clutter_tests_includepath = include_directories('.') + +subdir('accessibility') +subdir('conform') +subdir('interactive') +subdir('micro-bench') +subdir('performance') diff --git a/src/tests/clutter/micro-bench/meson.build b/src/tests/clutter/micro-bench/meson.build new file mode 100644 index 000000000..b8fe1e794 --- /dev/null +++ b/src/tests/clutter/micro-bench/meson.build @@ -0,0 +1,28 @@ +clutter_tests_micro_bench_c_args = [ + '-DG_DISABLE_SINGLE_INCLUDES', + '-DGLIB_DISABLE_DEPRECATION_WARNINGS', + '-DCOGL_DISABLE_DEPRECATION_WARNINGS', + '-DCLUTTER_DISABLE_DEPRECATION_WARNINGS', +] +clutter_tests_micro_bench_c_args += clutter_debug_c_args + +clutter_tests_micro_bench_tests = [ + 'test-text', + 'test-picking', + 'test-text-perf', + 'test-random-text', + 'test-cogl-perf', +] + +foreach test : clutter_tests_micro_bench_tests + executable(test, + sources: '@0@.c'.format(test), + include_directories: clutter_includes, + c_args: clutter_tests_micro_bench_c_args, + dependencies: [ + clutter_deps, + libmutter_clutter_dep, + ], + install: false, + ) +endforeach diff --git a/clutter/tests/micro-bench/test-cogl-perf.c b/src/tests/clutter/micro-bench/test-cogl-perf.c similarity index 62% rename from clutter/tests/micro-bench/test-cogl-perf.c rename to src/tests/clutter/micro-bench/test-cogl-perf.c index 0b92219c5..9bf8a4721 100644 --- a/clutter/tests/micro-bench/test-cogl-perf.c +++ b/src/tests/clutter/micro-bench/test-cogl-perf.c @@ -27,15 +27,21 @@ typedef struct _TestState int current_test; } TestState; -typedef void (*TestCallback) (TestState *state); +typedef void (*TestCallback) (TestState *state, + ClutterPaintContext *paint_context); static void -test_rectangles (TestState *state) +test_rectangles (TestState *state, + ClutterPaintContext *paint_context) { #define RECT_WIDTH 5 #define RECT_HEIGHT 5 + CoglFramebuffer *framebuffer = + clutter_paint_context_get_framebuffer (paint_context); + CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); int x; int y; + CoglPipeline *pipeline; /* Should the rectangles be randomly positioned/colored/rotated? * @@ -59,19 +65,23 @@ test_rectangles (TestState *state) * */ + pipeline = cogl_pipeline_new (ctx); + for (y = 0; y < STAGE_HEIGHT; y += RECT_HEIGHT) { for (x = 0; x < STAGE_WIDTH; x += RECT_WIDTH) { - cogl_push_matrix (); - cogl_translate (x, y, 0); - cogl_rotate (45, 0, 0, 1); - cogl_set_source_color4f (1, - (1.0f/STAGE_WIDTH)*y, - (1.0f/STAGE_HEIGHT)*x, - 1); - cogl_rectangle (0, 0, RECT_WIDTH, RECT_HEIGHT); - cogl_pop_matrix (); + cogl_framebuffer_push_matrix (framebuffer); + cogl_framebuffer_translate (framebuffer, x, y, 0); + cogl_framebuffer_rotate (framebuffer, 45, 0, 0, 1); + cogl_pipeline_set_color4f (pipeline, + 1, + (1.0f / STAGE_WIDTH) * y, + (1.0f / STAGE_HEIGHT) * x, + 1); + cogl_framebuffer_draw_rectangle (framebuffer, pipeline, + 0, 0, RECT_WIDTH, RECT_HEIGHT); + cogl_framebuffer_pop_matrix (framebuffer); } } @@ -79,15 +89,17 @@ test_rectangles (TestState *state) { for (x = 0; x < STAGE_WIDTH; x += RECT_WIDTH) { - cogl_push_matrix (); - cogl_translate (x, y, 0); - cogl_rotate (0, 0, 0, 1); - cogl_set_source_color4f (1, - (1.0f/STAGE_WIDTH)*x, - (1.0f/STAGE_HEIGHT)*y, - (1.0f/STAGE_WIDTH)*x); - cogl_rectangle (0, 0, RECT_WIDTH, RECT_HEIGHT); - cogl_pop_matrix (); + cogl_framebuffer_push_matrix (framebuffer); + cogl_framebuffer_translate (framebuffer, x, y, 0); + cogl_framebuffer_rotate (framebuffer, 0, 0, 0, 1); + cogl_pipeline_set_color4f (pipeline, + 1, + (1.0f / STAGE_WIDTH) * x, + (1.0f / STAGE_HEIGHT) * y, + (1.0f / STAGE_WIDTH) * x); + cogl_framebuffer_draw_rectangle (framebuffer, pipeline, + 0, 0, RECT_WIDTH, RECT_HEIGHT); + cogl_framebuffer_pop_matrix (framebuffer); } } } @@ -98,9 +110,11 @@ TestCallback tests[] = }; static void -on_paint (ClutterActor *actor, TestState *state) +on_paint (ClutterActor *actor, + ClutterPaintContext *paint_context, + TestState *state) { - tests[state->current_test] (state); + tests[state->current_test] (state, paint_context); } static gboolean diff --git a/clutter/tests/micro-bench/test-picking.c b/src/tests/clutter/micro-bench/test-picking.c similarity index 96% rename from clutter/tests/micro-bench/test-picking.c rename to src/tests/clutter/micro-bench/test-picking.c index 845e600d9..942e161f7 100644 --- a/clutter/tests/micro-bench/test-picking.c +++ b/src/tests/clutter/micro-bench/test-picking.c @@ -54,7 +54,9 @@ do_events (ClutterActor *stage) } static void -on_paint (ClutterActor *stage, gconstpointer *data) +on_paint (ClutterActor *stage, + ClutterPaintContext *paint_context, + gconstpointer *data) { do_events (stage); } diff --git a/clutter/tests/micro-bench/test-random-text.c b/src/tests/clutter/micro-bench/test-random-text.c similarity index 100% rename from clutter/tests/micro-bench/test-random-text.c rename to src/tests/clutter/micro-bench/test-random-text.c diff --git a/clutter/tests/micro-bench/test-text-perf.c b/src/tests/clutter/micro-bench/test-text-perf.c similarity index 96% rename from clutter/tests/micro-bench/test-text-perf.c rename to src/tests/clutter/micro-bench/test-text-perf.c index c7f689f24..76084c4ff 100644 --- a/clutter/tests/micro-bench/test-text-perf.c +++ b/src/tests/clutter/micro-bench/test-text-perf.c @@ -11,7 +11,9 @@ static int n_chars; static int rows, cols; static void -on_paint (ClutterActor *actor, gconstpointer *data) +on_paint (ClutterActor *actor, + ClutterPaintContext *paint_context, + gconstpointer *data) { static GTimer *timer = NULL; static int fps = 0; @@ -95,7 +97,7 @@ create_label (void) label = clutter_text_new_with_text (font_name, str->str); clutter_text_set_color (CLUTTER_TEXT (label), &label_color); - free (font_name); + g_free (font_name); g_string_free (str, TRUE); return label; diff --git a/clutter/tests/micro-bench/test-text.c b/src/tests/clutter/micro-bench/test-text.c similarity index 96% rename from clutter/tests/micro-bench/test-text.c rename to src/tests/clutter/micro-bench/test-text.c index d79bfd65a..18bd841eb 100644 --- a/clutter/tests/micro-bench/test-text.c +++ b/src/tests/clutter/micro-bench/test-text.c @@ -10,7 +10,9 @@ #define ROWS 20 static void -on_paint (ClutterActor *actor, gconstpointer *data) +on_paint (ClutterActor *actor, + ClutterPaintContext *paint_context, + gconstpointer *data) { static GTimer *timer = NULL; static int fps = 0; diff --git a/clutter/tests/performance/create-report.rb b/src/tests/clutter/performance/create-report.rb similarity index 100% rename from clutter/tests/performance/create-report.rb rename to src/tests/clutter/performance/create-report.rb diff --git a/clutter/tests/performance/joblist b/src/tests/clutter/performance/joblist similarity index 100% rename from clutter/tests/performance/joblist rename to src/tests/clutter/performance/joblist diff --git a/clutter/tests/performance/makejobs.rb b/src/tests/clutter/performance/makejobs.rb similarity index 100% rename from clutter/tests/performance/makejobs.rb rename to src/tests/clutter/performance/makejobs.rb diff --git a/src/tests/clutter/performance/meson.build b/src/tests/clutter/performance/meson.build new file mode 100644 index 000000000..ee092bb04 --- /dev/null +++ b/src/tests/clutter/performance/meson.build @@ -0,0 +1,38 @@ +clutter_tests_performance_c_args = [ + '-DTESTS_DATA_DIR="@0@"'.format(clutter_tests_interactive_srcdir), + '-DG_DISABLE_SINGLE_INCLUDES', + '-DGLIB_DISABLE_DEPRECATION_WARNINGS', + '-DCOGL_DISABLE_DEPRECATION_WARNINGS', + '-DCLUTTER_DISABLE_DEPRECATION_WARNINGS', +] + +clutter_tests_performance_c_args += clutter_debug_c_args + +clutter_tests_performance_tests = [ + 'test-picking', + 'test-text-perf', + 'test-state', + 'test-state-interactive', + 'test-state-hidden', + 'test-state-mini', + 'test-state-pick', +] + +foreach test : clutter_tests_performance_tests + executable(test, + sources: [ + '@0@.c'.format(test), + 'test-common.h', + ], + include_directories: [ + clutter_includes, + clutter_tests_includepath, + ], + c_args: clutter_tests_performance_c_args, + dependencies: [ + clutter_deps, + libmutter_clutter_dep, + ], + install: false, + ) +endforeach diff --git a/clutter/tests/performance/test-common.h b/src/tests/clutter/performance/test-common.h similarity index 77% rename from clutter/tests/performance/test-common.h rename to src/tests/clutter/performance/test-common.h index b0bed1082..693d9188a 100644 --- a/clutter/tests/performance/test-common.h +++ b/src/tests/clutter/performance/test-common.h @@ -7,7 +7,8 @@ static gint testframes = 0; static float testmaxtime = 1.0; /* initialize environment to be suitable for fps testing */ -void clutter_perf_fps_init (void) +static inline void +clutter_perf_fps_init (void) { /* Force not syncing to vblank, we want free-running maximum FPS */ g_setenv ("vblank_mode", "0", FALSE); @@ -24,26 +25,34 @@ void clutter_perf_fps_init (void) g_random_set_seed (12345678); } -static void perf_stage_paint_cb (ClutterStage *stage, gpointer *data); +static void perf_stage_paint_cb (ClutterStage *stage, + ClutterPaintContext *paint_context, + gpointer *data); static gboolean perf_fake_mouse_cb (gpointer stage); -void clutter_perf_fps_start (ClutterStage *stage) +static inline void +clutter_perf_fps_start (ClutterStage *stage) { g_signal_connect (stage, "paint", G_CALLBACK (perf_stage_paint_cb), NULL); } -void clutter_perf_fake_mouse (ClutterStage *stage) +static inline void +clutter_perf_fake_mouse (ClutterStage *stage) { clutter_threads_add_timeout (1000/60, perf_fake_mouse_cb, stage); } -void clutter_perf_fps_report (const gchar *id) +static inline void +clutter_perf_fps_report (const gchar *id) { g_print ("\n@ %s: %.2f fps \n", id, testframes / g_timer_elapsed (testtimer, NULL)); } -static void perf_stage_paint_cb (ClutterStage *stage, gpointer *data) +static void +perf_stage_paint_cb (ClutterStage *stage, + ClutterPaintContext *paint_context, + gpointer *data) { if (!testtimer) testtimer = g_timer_new (); @@ -86,15 +95,18 @@ static gboolean perf_fake_mouse_cb (gpointer stage) */ { ClutterEvent *event2 = clutter_event_new (CLUTTER_ENTER); - device = clutter_device_manager_get_core_device (clutter_device_manager_get_default (), CLUTTER_POINTER_DEVICE); + ClutterBackend *backend = clutter_get_default_backend (); + ClutterSeat *seat = clutter_backend_get_default_seat (backend); + + device = clutter_seat_get_pointer (seat); event2->crossing.stage = stage; event2->crossing.source = stage; event2->crossing.x = 10; event2->crossing.y = 10; - event2->crossing.device = device; event2->crossing.related = NULL; + clutter_event_set_device (event2, device); clutter_input_device_update_from_event (device, event2, TRUE); clutter_event_put (event2); @@ -104,7 +116,7 @@ static gboolean perf_fake_mouse_cb (gpointer stage) clutter_actor_get_size (stage, &w, &h); event->motion.stage = stage; - event->motion.device = device; + clutter_event_set_device (event, device); /* called about every 60fps, and do 10 picks per stage */ for (i = 0; i < 10; i++) diff --git a/clutter/tests/performance/test-picking.c b/src/tests/clutter/performance/test-picking.c similarity index 100% rename from clutter/tests/performance/test-picking.c rename to src/tests/clutter/performance/test-picking.c diff --git a/clutter/tests/performance/test-state-hidden.c b/src/tests/clutter/performance/test-state-hidden.c similarity index 99% rename from clutter/tests/performance/test-state-hidden.c rename to src/tests/clutter/performance/test-state-hidden.c index ceeed1a53..64911b4eb 100644 --- a/clutter/tests/performance/test-state-hidden.c +++ b/src/tests/clutter/performance/test-state-hidden.c @@ -42,7 +42,7 @@ static ClutterActor *new_rect (gint r, gchar *file = g_build_filename (TESTS_DATA_DIR, "redhand.png", NULL); - free (file); + g_free (file); clutter_actor_set_size (rectangle, ACTOR_WIDTH,ACTOR_HEIGHT); clutter_color_free (color); clutter_container_add (CLUTTER_CONTAINER (group), rectangle, NULL); @@ -87,7 +87,7 @@ main (gint argc, clutter_state_set (layout_state, NULL, "active", actor, "delayed::x", CLUTTER_LINEAR, - ACTOR_WIDTH * 1.0 * ((TOTAL-1-i) % COLS), + ACTOR_WIDTH * 1.0 * ((TOTAL-1-i) % COLS), ((row*1.0/ROWS))/2, (1.0-(row*1.0/ROWS))/2, actor, "delayed::y", CLUTTER_LINEAR, ACTOR_HEIGHT * 1.0 * ((TOTAL-1-i) / COLS), diff --git a/clutter/tests/performance/test-state-interactive.c b/src/tests/clutter/performance/test-state-interactive.c similarity index 98% rename from clutter/tests/performance/test-state-interactive.c rename to src/tests/clutter/performance/test-state-interactive.c index 4abb68435..e0cfe0671 100644 --- a/clutter/tests/performance/test-state-interactive.c +++ b/src/tests/clutter/performance/test-state-interactive.c @@ -3,6 +3,7 @@ #include <gmodule.h> #include <clutter/clutter.h> #include "test-common.h" +#include "test-utils.h" #define STAGE_WIDTH 800 #define STAGE_HEIGHT 600 @@ -77,10 +78,10 @@ static ClutterActor *new_rect (gint r, gchar *file = g_build_filename (TESTS_DATA_DIR, "redhand.png", NULL); - hand = clutter_texture_new_from_file (file, &error); + hand = clutter_test_utils_create_texture_from_file (file, &error); if (rectangle == NULL) g_error ("image load failed: %s", error->message); - free (file); + g_free (file); clutter_actor_set_size (hand, ACTOR_WIDTH,ACTOR_HEIGHT); clutter_actor_set_size (rectangle, ACTOR_WIDTH,ACTOR_HEIGHT); @@ -128,7 +129,7 @@ main (gint argc, clutter_state_set (layout_state, NULL, "active", actor, "delayed::x", CLUTTER_LINEAR, - ACTOR_WIDTH * 1.0 * ((TOTAL-1-i) % COLS), + ACTOR_WIDTH * 1.0 * ((TOTAL-1-i) % COLS), ((row*1.0/ROWS))/2, (1.0-(row*1.0/ROWS))/2, actor, "delayed::y", CLUTTER_LINEAR, ACTOR_HEIGHT * 1.0 * ((TOTAL-1-i) / COLS), diff --git a/clutter/tests/performance/test-state-mini.c b/src/tests/clutter/performance/test-state-mini.c similarity index 97% rename from clutter/tests/performance/test-state-mini.c rename to src/tests/clutter/performance/test-state-mini.c index 5bcbf7cfa..5bd8fb282 100644 --- a/clutter/tests/performance/test-state-mini.c +++ b/src/tests/clutter/performance/test-state-mini.c @@ -3,6 +3,7 @@ #include <gmodule.h> #include <clutter/clutter.h> #include "test-common.h" +#include "test-utils.h" #define STAGE_WIDTH 160 #define STAGE_HEIGHT 120 @@ -44,10 +45,10 @@ static ClutterActor *new_rect (gint r, gchar *file = g_build_filename (TESTS_DATA_DIR, "redhand.png", NULL); - hand = clutter_texture_new_from_file (file, &error); + hand = clutter_test_utils_create_texture_from_file (file, &error); if (rectangle == NULL) g_error ("image load failed: %s", error->message); - free (file); + g_free (file); clutter_actor_set_size (hand, ACTOR_WIDTH,ACTOR_HEIGHT); clutter_actor_set_size (rectangle, ACTOR_WIDTH,ACTOR_HEIGHT); @@ -92,7 +93,7 @@ main (gint argc, clutter_state_set (layout_state, NULL, "active", actor, "delayed::x", CLUTTER_LINEAR, - ACTOR_WIDTH * 1.0 * ((TOTAL-1-i) % COLS), + ACTOR_WIDTH * 1.0 * ((TOTAL-1-i) % COLS), ((row*1.0/ROWS))/2, (1.0-(row*1.0/ROWS))/2, actor, "delayed::y", CLUTTER_LINEAR, ACTOR_HEIGHT * 1.0 * ((TOTAL-1-i) / COLS), diff --git a/clutter/tests/performance/test-state-pick.c b/src/tests/clutter/performance/test-state-pick.c similarity index 97% rename from clutter/tests/performance/test-state-pick.c rename to src/tests/clutter/performance/test-state-pick.c index 86fd7386b..bf0d68c2b 100644 --- a/clutter/tests/performance/test-state-pick.c +++ b/src/tests/clutter/performance/test-state-pick.c @@ -3,6 +3,7 @@ #include <gmodule.h> #include <clutter/clutter.h> #include "test-common.h" +#include "test-utils.h" static gint times = 16; @@ -49,10 +50,10 @@ static ClutterActor *new_rect (gint r, gchar *file = g_build_filename (TESTS_DATA_DIR, "redhand.png", NULL); - hand = clutter_texture_new_from_file (file, &error); + hand = clutter_test_utils_create_texture_from_file (file, &error); if (rectangle == NULL) g_error ("image load failed: %s", error->message); - free (file); + g_free (file); clutter_actor_set_size (hand, ACTOR_WIDTH,ACTOR_HEIGHT); clutter_actor_set_size (rectangle, ACTOR_WIDTH,ACTOR_HEIGHT); @@ -97,7 +98,7 @@ main (gint argc, clutter_state_set (layout_state, NULL, "active", actor, "delayed::x", CLUTTER_LINEAR, - ACTOR_WIDTH * 1.0 * ((TOTAL-1-i) % COLS), + ACTOR_WIDTH * 1.0 * ((TOTAL-1-i) % COLS), ((row*1.0/ROWS))/2, (1.0-(row*1.0/ROWS))/2, actor, "delayed::y", CLUTTER_LINEAR, ACTOR_HEIGHT * 1.0 * ((TOTAL-1-i) / COLS), diff --git a/clutter/tests/performance/test-state.c b/src/tests/clutter/performance/test-state.c similarity index 97% rename from clutter/tests/performance/test-state.c rename to src/tests/clutter/performance/test-state.c index ec0727ba0..7a6303b58 100644 --- a/clutter/tests/performance/test-state.c +++ b/src/tests/clutter/performance/test-state.c @@ -3,6 +3,7 @@ #include <gmodule.h> #include <clutter/clutter.h> #include "test-common.h" +#include "test-utils.h" static gint times = 16; @@ -49,10 +50,10 @@ static ClutterActor *new_rect (gint r, gchar *file = g_build_filename (TESTS_DATA_DIR, "redhand.png", NULL); - hand = clutter_texture_new_from_file (file, &error); + hand = clutter_test_utils_create_texture_from_file (file, &error); if (rectangle == NULL) g_error ("image load failed: %s", error->message); - free (file); + g_free (file); clutter_actor_set_size (hand, ACTOR_WIDTH,ACTOR_HEIGHT); clutter_actor_set_size (rectangle, ACTOR_WIDTH,ACTOR_HEIGHT); @@ -97,7 +98,7 @@ main (gint argc, clutter_state_set (layout_state, NULL, "active", actor, "delayed::x", CLUTTER_LINEAR, - ACTOR_WIDTH * 1.0 * ((TOTAL-1-i) % COLS), + ACTOR_WIDTH * 1.0 * ((TOTAL-1-i) % COLS), ((row*1.0/ROWS))/2, (1.0-(row*1.0/ROWS))/2, actor, "delayed::y", CLUTTER_LINEAR, ACTOR_HEIGHT * 1.0 * ((TOTAL-1-i) / COLS), diff --git a/clutter/tests/performance/test-text-perf.c b/src/tests/clutter/performance/test-text-perf.c similarity index 99% rename from clutter/tests/performance/test-text-perf.c rename to src/tests/clutter/performance/test-text-perf.c index f2823ddc5..bf08a4810 100644 --- a/clutter/tests/performance/test-text-perf.c +++ b/src/tests/clutter/performance/test-text-perf.c @@ -71,7 +71,7 @@ create_label (void) label = clutter_text_new_with_text (font_name, str->str); clutter_text_set_color (CLUTTER_TEXT (label), &label_color); - free (font_name); + g_free (font_name); g_string_free (str, TRUE); return label; diff --git a/src/tests/clutter/test-utils.h b/src/tests/clutter/test-utils.h new file mode 100644 index 000000000..6ed1a938b --- /dev/null +++ b/src/tests/clutter/test-utils.h @@ -0,0 +1,30 @@ +#include <clutter/clutter.h> +#include <gdk-pixbuf/gdk-pixbuf.h> + +static inline ClutterActor * +clutter_test_utils_create_texture_from_file (const char *filename, + GError **error) +{ + g_autoptr (ClutterContent) image = NULL; + g_autoptr (GdkPixbuf) pixbuf = NULL; + + pixbuf = gdk_pixbuf_new_from_file (filename, error); + if (!pixbuf) + return NULL; + + image = clutter_image_new (); + if (!clutter_image_set_data (CLUTTER_IMAGE (image), + gdk_pixbuf_get_pixels (pixbuf), + gdk_pixbuf_get_has_alpha (pixbuf) + ? COGL_PIXEL_FORMAT_RGBA_8888 + : COGL_PIXEL_FORMAT_RGB_888, + gdk_pixbuf_get_width (pixbuf), + gdk_pixbuf_get_height (pixbuf), + gdk_pixbuf_get_rowstride (pixbuf), + error)) + return NULL; + + return g_object_new (CLUTTER_TYPE_ACTOR, + "content", image, + NULL); +} diff --git a/src/tests/headless-start-test.c b/src/tests/headless-start-test.c new file mode 100644 index 000000000..95ba3fa53 --- /dev/null +++ b/src/tests/headless-start-test.c @@ -0,0 +1,218 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include "backends/meta-monitor-manager-private.h" +#include "backends/meta-crtc.h" +#include "backends/meta-output.h" +#include "compositor/meta-plugin-manager.h" +#include "core/display-private.h" +#include "core/main-private.h" +#include "meta/main.h" +#include "tests/meta-backend-test.h" +#include "tests/meta-monitor-manager-test.h" +#include "tests/test-utils.h" +#include "wayland/meta-wayland.h" + +#define ALL_TRANSFORMS ((1 << (META_MONITOR_TRANSFORM_FLIPPED_270 + 1)) - 1) +#define FRAME_WARNING "Frame has assigned frame counter but no frame drawn time" + +static gboolean +run_tests (gpointer data) +{ + MetaBackend *backend = meta_get_backend (); + MetaSettings *settings = meta_backend_get_settings (backend); + gboolean ret; + + g_test_log_set_fatal_handler (NULL, NULL); + + meta_settings_override_experimental_features (settings); + + meta_settings_enable_experimental_feature ( + settings, + META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER); + + ret = g_test_run (); + + meta_quit (ret != 0); + + return FALSE; +} + +static gboolean +ignore_frame_counter_warning (const gchar *log_domain, + GLogLevelFlags log_level, + const gchar *message, + gpointer user_data) +{ + if ((log_level & G_LOG_LEVEL_WARNING) && + g_strcmp0 (log_domain, "mutter") == 0 && + g_str_has_suffix (message, FRAME_WARNING)) + return FALSE; + + return TRUE; +} + +static void +meta_test_headless_start (void) +{ + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + GList *gpus; + MetaGpu *gpu; + + gpus = meta_backend_get_gpus (backend); + g_assert_cmpint ((int) g_list_length (gpus), ==, 1); + + gpu = gpus->data; + g_assert_null (meta_gpu_get_modes (gpu)); + g_assert_null (meta_gpu_get_outputs (gpu)); + g_assert_null (meta_gpu_get_crtcs (gpu)); + g_assert_null (monitor_manager->monitors); + g_assert_null (monitor_manager->logical_monitors); + + g_assert_cmpint (monitor_manager->screen_width, + ==, + META_MONITOR_MANAGER_MIN_SCREEN_WIDTH); + g_assert_cmpint (monitor_manager->screen_height, + ==, + META_MONITOR_MANAGER_MIN_SCREEN_HEIGHT); +} + +static void +meta_test_headless_monitor_getters (void) +{ + MetaDisplay *display; + int index; + + display = meta_get_display (); + + index = meta_display_get_monitor_index_for_rect (display, + &(MetaRectangle) { 0 }); + g_assert_cmpint (index, ==, -1); +} + +static void +meta_test_headless_monitor_connect (void) +{ + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaMonitorManagerTest *monitor_manager_test = + META_MONITOR_MANAGER_TEST (monitor_manager); + MetaMonitorTestSetup *test_setup; + MetaCrtcMode **modes; + MetaCrtcMode *crtc_mode; + MetaCrtc *crtc; + MetaCrtc **possible_crtcs; + MetaOutput *output; + GList *logical_monitors; + ClutterActor *stage; + + test_setup = g_new0 (MetaMonitorTestSetup, 1); + + crtc_mode = g_object_new (META_TYPE_CRTC_MODE, NULL); + crtc_mode->mode_id = 1; + crtc_mode->width = 1024; + crtc_mode->height = 768; + crtc_mode->refresh_rate = 60.0; + test_setup->modes = g_list_append (NULL, crtc_mode); + + crtc = g_object_new (META_TYPE_CRTC, NULL); + crtc->crtc_id = 1; + crtc->all_transforms = ALL_TRANSFORMS; + test_setup->crtcs = g_list_append (NULL, crtc); + + modes = g_new0 (MetaCrtcMode *, 1); + modes[0] = crtc_mode; + + possible_crtcs = g_new0 (MetaCrtc *, 1); + possible_crtcs[0] = g_list_first (test_setup->crtcs)->data; + + output = g_object_new (META_TYPE_OUTPUT, NULL); + output->winsys_id = 1; + output->name = g_strdup ("DP-1"); + output->vendor = g_strdup ("MetaProduct's Inc."); + output->product = g_strdup ("MetaMonitor"); + output->serial = g_strdup ("0x987654"); + output->preferred_mode = modes[0]; + output->n_modes = 1; + output->modes = modes; + output->n_possible_crtcs = 1; + output->possible_crtcs = possible_crtcs; + output->connector_type = META_CONNECTOR_TYPE_DisplayPort; + test_setup->outputs = g_list_append (NULL, output); + + meta_monitor_manager_test_emulate_hotplug (monitor_manager_test, test_setup); + + logical_monitors = + meta_monitor_manager_get_logical_monitors (monitor_manager); + g_assert_cmpint (g_list_length (logical_monitors), ==, 1); + + g_assert_cmpint (monitor_manager->screen_width, ==, 1024); + g_assert_cmpint (monitor_manager->screen_height, ==, 768); + + stage = meta_backend_get_stage (backend); + g_assert_cmpint (clutter_actor_get_width (stage), ==, 1024); + g_assert_cmpint (clutter_actor_get_height (stage), ==, 768); +} + +static MetaMonitorTestSetup * +create_headless_test_setup (void) +{ + return g_new0 (MetaMonitorTestSetup, 1); +} + +static void +init_tests (int argc, char **argv) +{ + MetaMonitorTestSetup *initial_test_setup; + + initial_test_setup = create_headless_test_setup (); + meta_monitor_manager_test_init_test_setup (initial_test_setup); + + g_test_add_func ("/headless-start/start", meta_test_headless_start); + g_test_add_func ("/headless-start/monitor-getters", + meta_test_headless_monitor_getters); + g_test_add_func ("/headless-start/connect", + meta_test_headless_monitor_connect); +} + +int +main (int argc, char *argv[]) +{ + test_init (&argc, &argv); + init_tests (argc, argv); + + meta_plugin_manager_load (test_get_plugin_name ()); + + meta_override_compositor_configuration (META_COMPOSITOR_TYPE_WAYLAND, + META_TYPE_BACKEND_TEST); + + meta_init (); + meta_register_with_session (); + + g_test_log_set_fatal_handler (ignore_frame_counter_warning, NULL); + + g_idle_add (run_tests, NULL); + + return meta_run (); +} diff --git a/src/tests/meson.build b/src/tests/meson.build new file mode 100644 index 000000000..89bd00f6f --- /dev/null +++ b/src/tests/meson.build @@ -0,0 +1,174 @@ +clutter_test_utils = files ( + 'clutter-test-utils.c', + 'clutter-test-utils.h', +) + +if have_clutter_tests + subdir('clutter') +endif + +tests_includepath = mutter_includes +tests_c_args = mutter_c_args + +tests_deps = [ + mutter_deps, + libmutter_dep, + libmutter_cogl_dep, + libmutter_clutter_dep, +] + +subdir('wayland-test-clients') + +if have_installed_tests + stacking_files_datadir = join_paths(pkgdatadir, 'tests') + + installed_tests_cdata = configuration_data() + installed_tests_cdata.set('libexecdir', libexecdir) + installed_tests_cdata.set('apiversion', libmutter_api_version) + + configure_file( + input: 'mutter-all.test.in', + output: 'mutter-all.test', + configuration: installed_tests_cdata, + install: true, + install_dir: mutter_installed_tests_datadir, + ) + + install_subdir('stacking', install_dir: stacking_files_datadir) +endif + +test_env = environment() +test_env.set('G_TEST_SRCDIR', join_paths(meson.source_root(), 'src')) +test_env.set('G_TEST_BUILDDIR', meson.build_root()) +test_env.set('MUTTER_TEST_PLUGIN_PATH', '@0@'.format(default_plugin.full_path())) + +test_client = executable('mutter-test-client', + sources: ['test-client.c'], + include_directories: tests_includepath, + c_args: tests_c_args, + dependencies: [ + gtk3_dep, + gio_unix_dep, + x11_dep, + xext_dep, + ], + install: have_installed_tests, + install_dir: mutter_installed_tests_libexecdir, +) + +test_runner = executable('mutter-test-runner', + sources: [ + 'test-utils.c', + 'test-utils.h', + 'test-runner.c', + ], + include_directories: tests_includepath, + c_args: tests_c_args, + dependencies: [tests_deps], + install: have_installed_tests, + install_dir: mutter_installed_tests_libexecdir, +) + +unit_tests = executable('mutter-test-unit-tests', + sources: [ + 'test-utils.c', + 'test-utils.h', + 'unit-tests.c', + 'boxes-tests.c', + 'boxes-tests.h', + 'meta-backend-test.c', + 'meta-backend-test.h', + 'meta-gpu-test.c', + 'meta-gpu-test.h', + 'meta-monitor-manager-test.c', + 'meta-monitor-manager-test.h', + 'monitor-config-migration-unit-tests.c', + 'monitor-config-migration-unit-tests.h', + 'monitor-store-unit-tests.c', + 'monitor-store-unit-tests.h', + 'monitor-test-utils.c', + 'monitor-test-utils.h', + 'monitor-transform-tests.c', + 'monitor-transform-tests.h', + 'monitor-unit-tests.c', + 'monitor-unit-tests.h', + 'wayland-unit-tests.c', + 'wayland-unit-tests.h', + test_driver_server_header, + test_driver_protocol_code, + ], + include_directories: tests_includepath, + c_args: tests_c_args, + dependencies: [tests_deps], + install: have_installed_tests, + install_dir: mutter_installed_tests_libexecdir, +) + +headless_start_test = executable('mutter-headless-start-test', + sources: [ + 'headless-start-test.c', + 'meta-backend-test.c', + 'meta-backend-test.h', + 'meta-gpu-test.c', + 'meta-gpu-test.h', + 'meta-monitor-manager-test.c', + 'meta-monitor-manager-test.h', + 'test-utils.c', + 'test-utils.h', + ], + include_directories: tests_includepath, + c_args: tests_c_args, + dependencies: [tests_deps], + install: have_installed_tests, + install_dir: mutter_installed_tests_libexecdir, +) + +stacking_tests = [ + 'basic-x11', + 'basic-wayland', + 'client-side-decorated', + 'closed-transient', + 'closed-transient-no-input-no-take-focus-parent', + 'closed-transient-no-input-no-take-focus-parents', + 'closed-transient-no-input-parent', + 'closed-transient-no-input-parent-delayed-focus-default-cancelled', + 'closed-transient-no-input-parents', + 'closed-transient-no-input-parents-queued-default-focus-destroyed', + 'closed-transient-only-take-focus-parents', + 'minimized', + 'mixed-windows', + 'set-parent', + 'override-redirect', + 'set-override-redirect-parent', + 'set-parent-exported', +] + +foreach stacking_test: stacking_tests + suites = ['core', 'mutter/stacking'] + if stacking_test.startswith('closed-transient-no-input') + suites += ['flaky'] + endif + test(stacking_test, test_runner, + suite: suites, + env: test_env, + args: [ + files(join_paths('stacking', stacking_test + '.metatest')), + ], + is_parallel: false, + timeout: 60, + ) +endforeach + +test('normal', unit_tests, + suite: ['core', 'mutter/unit'], + env: test_env, + is_parallel: false, + timeout: 60, +) + +test('headless-start', headless_start_test, + suite: ['core', 'mutter/unit'], + env: test_env, + is_parallel: false, + timeout: 60, +) diff --git a/src/tests/meta-backend-test.c b/src/tests/meta-backend-test.c new file mode 100644 index 000000000..0bc30d04d --- /dev/null +++ b/src/tests/meta-backend-test.c @@ -0,0 +1,95 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include "tests/meta-backend-test.h" + +#include "tests/meta-gpu-test.h" +#include "tests/meta-monitor-manager-test.h" + +struct _MetaBackendTest +{ + MetaBackendX11Nested parent; + + MetaGpu *gpu; + + gboolean is_lid_closed; +}; + +G_DEFINE_TYPE (MetaBackendTest, meta_backend_test, META_TYPE_BACKEND_X11_NESTED) + +void +meta_backend_test_set_is_lid_closed (MetaBackendTest *backend_test, + gboolean is_lid_closed) +{ + backend_test->is_lid_closed = is_lid_closed; +} + +MetaGpu * +meta_backend_test_get_gpu (MetaBackendTest *backend_test) +{ + return backend_test->gpu; +} + +static gboolean +meta_backend_test_is_lid_closed (MetaBackend *backend) +{ + MetaBackendTest *backend_test = META_BACKEND_TEST (backend); + + return backend_test->is_lid_closed; +} + +static void +meta_backend_test_init_gpus (MetaBackendX11Nested *backend_x11_nested) +{ + MetaBackendTest *backend_test = META_BACKEND_TEST (backend_x11_nested); + + backend_test->gpu = g_object_new (META_TYPE_GPU_TEST, + "backend", backend_test, + NULL); + meta_backend_add_gpu (META_BACKEND (backend_test), backend_test->gpu); +} + +static void +meta_backend_test_init (MetaBackendTest *backend_test) +{ +} + +static MetaMonitorManager * +meta_backend_test_create_monitor_manager (MetaBackend *backend, + GError **error) +{ + return g_object_new (META_TYPE_MONITOR_MANAGER_TEST, + "backend", backend, + NULL); +} + +static void +meta_backend_test_class_init (MetaBackendTestClass *klass) +{ + MetaBackendClass *backend_class = META_BACKEND_CLASS (klass); + MetaBackendX11NestedClass *backend_x11_nested_class = + META_BACKEND_X11_NESTED_CLASS (klass); + + backend_class->create_monitor_manager = meta_backend_test_create_monitor_manager; + backend_class->is_lid_closed = meta_backend_test_is_lid_closed; + + backend_x11_nested_class->init_gpus = meta_backend_test_init_gpus; +} diff --git a/src/tests/meta-backend-test.h b/src/tests/meta-backend-test.h new file mode 100644 index 000000000..d1cf81f1c --- /dev/null +++ b/src/tests/meta-backend-test.h @@ -0,0 +1,34 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef META_BACKEND_TEST_H +#define META_BACKEND_TEST_H + +#include "backends/x11/nested/meta-backend-x11-nested.h" + +#define META_TYPE_BACKEND_TEST (meta_backend_test_get_type ()) +G_DECLARE_FINAL_TYPE (MetaBackendTest, meta_backend_test, + META, BACKEND_TEST, MetaBackendX11Nested) + +void meta_backend_test_set_is_lid_closed (MetaBackendTest *backend_test, + gboolean is_lid_closed); + +MetaGpu * meta_backend_test_get_gpu (MetaBackendTest *backend_test); + +#endif /* META_BACKEND_TEST_H */ diff --git a/src/tests/meta-gpu-test.c b/src/tests/meta-gpu-test.c new file mode 100644 index 000000000..d483fd211 --- /dev/null +++ b/src/tests/meta-gpu-test.c @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2016-2018 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include "tests/meta-gpu-test.h" + +#include "backends/meta-backend-private.h" +#include "tests/meta-monitor-manager-test.h" + +struct _MetaGpuTest +{ + MetaGpu parent; +}; + +G_DEFINE_TYPE (MetaGpuTest, meta_gpu_test, META_TYPE_GPU) + +static gboolean +meta_gpu_test_read_current (MetaGpu *gpu, + GError **error) +{ + MetaBackend *backend = meta_gpu_get_backend (gpu); + MetaMonitorManager *manager = meta_backend_get_monitor_manager (backend); + + meta_monitor_manager_test_read_current (manager); + + return TRUE; +} + +static void +meta_gpu_test_init (MetaGpuTest *gpu_test) +{ +} + +static void +meta_gpu_test_class_init (MetaGpuTestClass *klass) +{ + MetaGpuClass *gpu_class = META_GPU_CLASS (klass); + + gpu_class->read_current = meta_gpu_test_read_current; +} diff --git a/src/tests/meta-gpu-test.h b/src/tests/meta-gpu-test.h new file mode 100644 index 000000000..46bbc80e2 --- /dev/null +++ b/src/tests/meta-gpu-test.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2016-2018 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef META_GPU_TEST_H +#define META_GPU_TEST_H + +#include "backends/meta-gpu.h" + +#define META_TYPE_GPU_TEST (meta_gpu_test_get_type ()) +G_DECLARE_FINAL_TYPE (MetaGpuTest, meta_gpu_test, META, GPU_TEST, MetaGpu) + +#endif /* META_GPU_TEST_H */ diff --git a/src/tests/meta-monitor-manager-test.c b/src/tests/meta-monitor-manager-test.c new file mode 100644 index 000000000..3cc96fcd2 --- /dev/null +++ b/src/tests/meta-monitor-manager-test.c @@ -0,0 +1,445 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include "tests/meta-monitor-manager-test.h" + +#include "backends/meta-backend-private.h" +#include "backends/meta-crtc.h" +#include "backends/meta-gpu.h" +#include "backends/meta-monitor-config-manager.h" +#include "backends/meta-output.h" +#include "tests/meta-backend-test.h" + +struct _MetaMonitorManagerTest +{ + MetaMonitorManager parent; + + gboolean handles_transforms; + + int tiled_monitor_count; + + MetaMonitorTestSetup *test_setup; +}; + +G_DEFINE_TYPE (MetaMonitorManagerTest, meta_monitor_manager_test, + META_TYPE_MONITOR_MANAGER) + +static MetaMonitorTestSetup *_initial_test_setup = NULL; + +void +meta_monitor_manager_test_init_test_setup (MetaMonitorTestSetup *test_setup) +{ + _initial_test_setup = test_setup; +} + +void +meta_monitor_manager_test_emulate_hotplug (MetaMonitorManagerTest *manager_test, + MetaMonitorTestSetup *test_setup) +{ + MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_test); + MetaMonitorTestSetup *old_test_setup; + + old_test_setup = manager_test->test_setup; + manager_test->test_setup = test_setup; + + meta_monitor_manager_read_current_state (manager); + meta_monitor_manager_on_hotplug (manager); + + g_free (old_test_setup); +} + +void +meta_monitor_manager_test_set_handles_transforms (MetaMonitorManagerTest *manager_test, + gboolean handles_transforms) +{ + g_assert (handles_transforms || meta_is_stage_views_enabled()); + + manager_test->handles_transforms = handles_transforms; +} + +int +meta_monitor_manager_test_get_tiled_monitor_count (MetaMonitorManagerTest *manager_test) +{ + return manager_test->tiled_monitor_count; +} + +void +meta_monitor_manager_test_read_current (MetaMonitorManager *manager) +{ + MetaMonitorManagerTest *manager_test = META_MONITOR_MANAGER_TEST (manager); + MetaBackend *backend = meta_monitor_manager_get_backend (manager); + MetaBackendTest *backend_test = META_BACKEND_TEST (backend); + MetaGpu *gpu = meta_backend_test_get_gpu (backend_test); + GList *l; + + g_assert (manager_test->test_setup); + + for (l = manager_test->test_setup->outputs; l; l = l->next) + META_OUTPUT (l->data)->gpu = gpu; + for (l = manager_test->test_setup->crtcs; l; l = l->next) + META_CRTC (l->data)->gpu = gpu; + + meta_gpu_take_modes (gpu, manager_test->test_setup->modes); + meta_gpu_take_crtcs (gpu, manager_test->test_setup->crtcs); + meta_gpu_take_outputs (gpu, manager_test->test_setup->outputs); +} + +static void +meta_monitor_manager_test_ensure_initial_config (MetaMonitorManager *manager) +{ + MetaMonitorsConfig *config; + + config = meta_monitor_manager_ensure_configured (manager); + + if (meta_is_stage_views_enabled ()) + { + meta_monitor_manager_update_logical_state (manager, config); + } + else + { + meta_monitor_manager_update_logical_state_derived (manager, NULL); + } +} + +static void +apply_crtc_assignments (MetaMonitorManager *manager, + MetaCrtcInfo **crtcs, + unsigned int n_crtcs, + MetaOutputInfo **outputs, + unsigned int n_outputs) +{ + MetaBackend *backend = meta_monitor_manager_get_backend (manager); + MetaBackendTest *backend_test = META_BACKEND_TEST (backend); + MetaGpu *gpu = meta_backend_test_get_gpu (backend_test); + GList *l; + unsigned int i; + + for (i = 0; i < n_crtcs; i++) + { + MetaCrtcInfo *crtc_info = crtcs[i]; + MetaCrtc *crtc = crtc_info->crtc; + crtc->is_dirty = TRUE; + + if (crtc_info->mode == NULL) + { + meta_crtc_unset_config (crtc); + } + else + { + MetaOutput *output; + unsigned int j; + + meta_crtc_set_config (crtc, + &crtc_info->layout, + crtc_info->mode, + crtc_info->transform); + + for (j = 0; j < crtc_info->outputs->len; j++) + { + output = ((MetaOutput**)crtc_info->outputs->pdata)[j]; + + output->is_dirty = TRUE; + meta_output_assign_crtc (output, crtc); + } + } + } + + for (i = 0; i < n_outputs; i++) + { + MetaOutputInfo *output_info = outputs[i]; + MetaOutput *output = output_info->output; + + output->is_primary = output_info->is_primary; + output->is_presentation = output_info->is_presentation; + output->is_underscanning = output_info->is_underscanning; + } + + /* Disable CRTCs not mentioned in the list */ + for (l = meta_gpu_get_crtcs (gpu); l; l = l->next) + { + MetaCrtc *crtc = l->data; + + if (crtc->is_dirty) + { + crtc->is_dirty = FALSE; + continue; + } + + meta_crtc_unset_config (crtc); + } + + /* Disable outputs not mentioned in the list */ + for (l = meta_gpu_get_outputs (gpu); l; l = l->next) + { + MetaOutput *output = l->data; + + if (output->is_dirty) + { + output->is_dirty = FALSE; + continue; + } + + meta_output_unassign_crtc (output); + output->is_primary = FALSE; + } +} + +static void +update_screen_size (MetaMonitorManager *manager, + MetaMonitorsConfig *config) +{ + GList *l; + int screen_width = 0; + int screen_height = 0; + + for (l = config->logical_monitor_configs; l; l = l->next) + { + MetaLogicalMonitorConfig *logical_monitor_config = l->data; + int right_edge; + int bottom_edge; + + right_edge = (logical_monitor_config->layout.width + + logical_monitor_config->layout.x); + if (right_edge > screen_width) + screen_width = right_edge; + + bottom_edge = (logical_monitor_config->layout.height + + logical_monitor_config->layout.y); + if (bottom_edge > screen_height) + screen_height = bottom_edge; + } + + manager->screen_width = screen_width; + manager->screen_height = screen_height; +} + +static gboolean +meta_monitor_manager_test_apply_monitors_config (MetaMonitorManager *manager, + MetaMonitorsConfig *config, + MetaMonitorsConfigMethod method, + GError **error) +{ + GPtrArray *crtc_infos; + GPtrArray *output_infos; + + if (!config) + { + manager->screen_width = META_MONITOR_MANAGER_MIN_SCREEN_WIDTH; + manager->screen_height = META_MONITOR_MANAGER_MIN_SCREEN_HEIGHT; + + if (meta_is_stage_views_enabled ()) + meta_monitor_manager_rebuild (manager, NULL); + else + meta_monitor_manager_rebuild_derived (manager, config); + + return TRUE; + } + + if (!meta_monitor_config_manager_assign (manager, config, + &crtc_infos, + &output_infos, + error)) + return FALSE; + + if (method == META_MONITORS_CONFIG_METHOD_VERIFY) + { + g_ptr_array_free (crtc_infos, TRUE); + g_ptr_array_free (output_infos, TRUE); + return TRUE; + } + + apply_crtc_assignments (manager, + (MetaCrtcInfo **) crtc_infos->pdata, + crtc_infos->len, + (MetaOutputInfo **) output_infos->pdata, + output_infos->len); + + g_ptr_array_free (crtc_infos, TRUE); + g_ptr_array_free (output_infos, TRUE); + + update_screen_size (manager, config); + + if (meta_is_stage_views_enabled ()) + meta_monitor_manager_rebuild (manager, config); + else + meta_monitor_manager_rebuild_derived (manager, config); + + return TRUE; +} + +static void +meta_monitor_manager_test_tiled_monitor_added (MetaMonitorManager *manager, + MetaMonitor *monitor) +{ + MetaMonitorManagerTest *manager_test = META_MONITOR_MANAGER_TEST (manager); + + manager_test->tiled_monitor_count++; +} + +static void +meta_monitor_manager_test_tiled_monitor_removed (MetaMonitorManager *manager, + MetaMonitor *monitor) +{ + MetaMonitorManagerTest *manager_test = META_MONITOR_MANAGER_TEST (manager); + + manager_test->tiled_monitor_count--; +} + +static gboolean +meta_monitor_manager_test_is_transform_handled (MetaMonitorManager *manager, + MetaCrtc *crtc, + MetaMonitorTransform transform) +{ + MetaMonitorManagerTest *manager_test = META_MONITOR_MANAGER_TEST (manager); + + return manager_test->handles_transforms; +} + +static float +meta_monitor_manager_test_calculate_monitor_mode_scale (MetaMonitorManager *manager, + MetaLogicalMonitorLayoutMode layout_mode, + MetaMonitor *monitor, + MetaMonitorMode *monitor_mode) +{ + MetaOutput *output; + MetaOutputTest *output_test; + + output = meta_monitor_get_main_output (monitor); + output_test = output->driver_private; + + if (output_test) + return output_test->scale; + else + return 1; +} + +static float * +meta_monitor_manager_test_calculate_supported_scales (MetaMonitorManager *manager, + MetaLogicalMonitorLayoutMode layout_mode, + MetaMonitor *monitor, + MetaMonitorMode *monitor_mode, + int *n_supported_scales) +{ + MetaMonitorScalesConstraint constraints = + META_MONITOR_SCALES_CONSTRAINT_NONE; + + switch (layout_mode) + { + case META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL: + case META_LOGICAL_MONITOR_LAYOUT_MODE_GLOBAL_UI_LOGICAL: + break; + case META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL: + constraints |= META_MONITOR_SCALES_CONSTRAINT_NO_FRAC; + break; + } + + return meta_monitor_calculate_supported_scales (monitor, monitor_mode, + constraints, + n_supported_scales); +} + +static gboolean +is_monitor_framebuffer_scaled (void) +{ + MetaBackend *backend = meta_get_backend (); + MetaSettings *settings = meta_backend_get_settings (backend); + + return meta_settings_is_experimental_feature_enabled ( + settings, + META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER); +} + +static MetaMonitorManagerCapability +meta_monitor_manager_test_get_capabilities (MetaMonitorManager *manager) +{ + MetaMonitorManagerCapability capabilities; + + capabilities = META_MONITOR_MANAGER_CAPABILITY_TILING; + + if (is_monitor_framebuffer_scaled ()) + capabilities |= META_MONITOR_MANAGER_CAPABILITY_LAYOUT_MODE; + + return capabilities; +} + +static gboolean +meta_monitor_manager_test_get_max_screen_size (MetaMonitorManager *manager, + int *max_width, + int *max_height) +{ + if (meta_is_stage_views_enabled ()) + return FALSE; + + *max_width = 65535; + *max_height = 65535; + + return TRUE; +} + +static MetaLogicalMonitorLayoutMode +meta_monitor_manager_test_get_default_layout_mode (MetaMonitorManager *manager) +{ + if (!meta_is_stage_views_enabled ()) + return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL; + + if (is_monitor_framebuffer_scaled ()) + return META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL; + else + return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL; +} + +static void +meta_monitor_manager_test_dispose (GObject *object) +{ + MetaMonitorManagerTest *manager_test = META_MONITOR_MANAGER_TEST (object); + + g_clear_pointer (&manager_test->test_setup, g_free); +} + +static void +meta_monitor_manager_test_init (MetaMonitorManagerTest *manager_test) +{ + g_assert (_initial_test_setup); + + manager_test->handles_transforms = TRUE; + + manager_test->test_setup = _initial_test_setup; +} + +static void +meta_monitor_manager_test_class_init (MetaMonitorManagerTestClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MetaMonitorManagerClass *manager_class = META_MONITOR_MANAGER_CLASS (klass); + + object_class->dispose = meta_monitor_manager_test_dispose; + + manager_class->ensure_initial_config = meta_monitor_manager_test_ensure_initial_config; + manager_class->apply_monitors_config = meta_monitor_manager_test_apply_monitors_config; + manager_class->tiled_monitor_added = meta_monitor_manager_test_tiled_monitor_added; + manager_class->tiled_monitor_removed = meta_monitor_manager_test_tiled_monitor_removed; + manager_class->is_transform_handled = meta_monitor_manager_test_is_transform_handled; + manager_class->calculate_monitor_mode_scale = meta_monitor_manager_test_calculate_monitor_mode_scale; + manager_class->calculate_supported_scales = meta_monitor_manager_test_calculate_supported_scales; + manager_class->get_capabilities = meta_monitor_manager_test_get_capabilities; + manager_class->get_max_screen_size = meta_monitor_manager_test_get_max_screen_size; + manager_class->get_default_layout_mode = meta_monitor_manager_test_get_default_layout_mode; +} diff --git a/src/tests/meta-monitor-manager-test.h b/src/tests/meta-monitor-manager-test.h new file mode 100644 index 000000000..0512a7fcb --- /dev/null +++ b/src/tests/meta-monitor-manager-test.h @@ -0,0 +1,53 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef META_MONITOR_MANAGER_TEST_H +#define META_MONITOR_MANAGER_TEST_H + +#include "backends/meta-monitor-manager-private.h" + +typedef struct _MetaMonitorTestSetup +{ + GList *modes; + GList *outputs; + GList *crtcs; +} MetaMonitorTestSetup; + +typedef struct _MetaOutputTest +{ + float scale; +} MetaOutputTest; + +#define META_TYPE_MONITOR_MANAGER_TEST (meta_monitor_manager_test_get_type ()) +G_DECLARE_FINAL_TYPE (MetaMonitorManagerTest, meta_monitor_manager_test, + META, MONITOR_MANAGER_TEST, MetaMonitorManager) + +void meta_monitor_manager_test_init_test_setup (MetaMonitorTestSetup *test_setup); + +void meta_monitor_manager_test_read_current (MetaMonitorManager *manager); + +void meta_monitor_manager_test_emulate_hotplug (MetaMonitorManagerTest *manager_test, + MetaMonitorTestSetup *test_setup); + +void meta_monitor_manager_test_set_handles_transforms (MetaMonitorManagerTest *manager_test, + gboolean handles_transforms); + +int meta_monitor_manager_test_get_tiled_monitor_count (MetaMonitorManagerTest *manager_test); + +#endif /* META_MONITOR_MANAGER_TEST_H */ diff --git a/src/tests/migration/basic-new.xml b/src/tests/migration/basic-new.xml new file mode 100644 index 000000000..569d1e7cd --- /dev/null +++ b/src/tests/migration/basic-new.xml @@ -0,0 +1,78 @@ +<monitors version="2"> + <configuration> + <migrated/> + <logicalmonitor> + <x>0</x> + <y>0</y> + <monitor> + <monitorspec> + <connector>HDMI-1</connector> + <vendor>DEL</vendor> + <product>DELL P2415Q</product> + <serial>GTTPW67P0WFB</serial> + </monitorspec> + <mode> + <width>3840</width> + <height>2160</height> + <rate>29.981103897094727</rate> + </mode> + </monitor> + </logicalmonitor> + <logicalmonitor> + <x>3840</x> + <y>0</y> + <primary>yes</primary> + <monitor> + <monitorspec> + <connector>eDP-1</connector> + <vendor>AUO</vendor> + <product>0x123d</product> + <serial>0x00000000</serial> + </monitorspec> + <mode> + <width>1920</width> + <height>1080</height> + <rate>60.049972534179688</rate> + </mode> + </monitor> + </logicalmonitor> + </configuration> + <configuration> + <migrated/> + <logicalmonitor> + <x>1920</x> + <y>0</y> + <monitor> + <monitorspec> + <connector>DP-2</connector> + <vendor>ACI</vendor> + <product>VX239</product> + <serial>ECLMRS004144</serial> + </monitorspec> + <mode> + <width>1920</width> + <height>1080</height> + <rate>60</rate> + </mode> + </monitor> + </logicalmonitor> + <logicalmonitor> + <x>0</x> + <y>0</y> + <primary>yes</primary> + <monitor> + <monitorspec> + <connector>eDP-1</connector> + <vendor>AUO</vendor> + <product>0x123d</product> + <serial>0x00000000</serial> + </monitorspec> + <mode> + <width>1920</width> + <height>1080</height> + <rate>60.049468994140625</rate> + </mode> + </monitor> + </logicalmonitor> + </configuration> +</monitors> diff --git a/src/tests/migration/basic-old.xml b/src/tests/migration/basic-old.xml new file mode 100644 index 000000000..c47dc55c1 --- /dev/null +++ b/src/tests/migration/basic-old.xml @@ -0,0 +1,72 @@ +<monitors version="1"> + <configuration> + <clone>no</clone> + <output name="HDMI-1"> + <vendor>DEL</vendor> + <product>DELL P2415Q</product> + <serial>GTTPW67P0WFB</serial> + <width>3840</width> + <height>2160</height> + <rate>29.981103897094727</rate> + <x>0</x> + <y>0</y> + <rotation>normal</rotation> + <reflect_x>no</reflect_x> + <reflect_y>no</reflect_y> + <primary>no</primary> + <presentation>no</presentation> + <underscanning>no</underscanning> + </output> + <output name="eDP-1"> + <vendor>AUO</vendor> + <product>0x123d</product> + <serial>0x00000000</serial> + <width>1920</width> + <height>1080</height> + <rate>60.049972534179688</rate> + <x>3840</x> + <y>0</y> + <rotation>normal</rotation> + <reflect_x>no</reflect_x> + <reflect_y>no</reflect_y> + <primary>yes</primary> + <presentation>no</presentation> + <underscanning>no</underscanning> + </output> + </configuration> + <configuration> + <clone>no</clone> + <output name="DP-2"> + <vendor>ACI</vendor> + <product>VX239</product> + <serial>ECLMRS004144</serial> + <width>1920</width> + <height>1080</height> + <rate>60</rate> + <x>1920</x> + <y>0</y> + <rotation>normal</rotation> + <reflect_x>no</reflect_x> + <reflect_y>no</reflect_y> + <primary>no</primary> + <presentation>no</presentation> + <underscanning>no</underscanning> + </output> + <output name="eDP-1"> + <vendor>AUO</vendor> + <product>0x123d</product> + <serial>0x00000000</serial> + <width>1920</width> + <height>1080</height> + <rate>60.049468994140625</rate> + <x>0</x> + <y>0</y> + <rotation>normal</rotation> + <reflect_x>no</reflect_x> + <reflect_y>no</reflect_y> + <primary>yes</primary> + <presentation>no</presentation> + <underscanning>no</underscanning> + </output> + </configuration> +</monitors> diff --git a/src/tests/migration/first-rotated-new.xml b/src/tests/migration/first-rotated-new.xml new file mode 100644 index 000000000..9f875c21f --- /dev/null +++ b/src/tests/migration/first-rotated-new.xml @@ -0,0 +1,44 @@ +<monitors version="2"> + <configuration> + <migrated/> + <logicalmonitor> + <x>0</x> + <y>0</y> + <transform> + <rotation>left</rotation> + <flipped>no</flipped> + </transform> + <monitor> + <monitorspec> + <connector>HDMI-1</connector> + <vendor>DEL</vendor> + <product>DELL P2415Q</product> + <serial>GTTPW67P0WFB</serial> + </monitorspec> + <mode> + <width>3840</width> + <height>2160</height> + <rate>29.981103897094727</rate> + </mode> + </monitor> + </logicalmonitor> + <logicalmonitor> + <x>2160</x> + <y>0</y> + <primary>yes</primary> + <monitor> + <monitorspec> + <connector>eDP-1</connector> + <vendor>AUO</vendor> + <product>0x123d</product> + <serial>0x00000000</serial> + </monitorspec> + <mode> + <width>1920</width> + <height>1080</height> + <rate>60.049972534179688</rate> + </mode> + </monitor> + </logicalmonitor> + </configuration> +</monitors> diff --git a/src/tests/migration/first-rotated-old.xml b/src/tests/migration/first-rotated-old.xml new file mode 100644 index 000000000..b00a35963 --- /dev/null +++ b/src/tests/migration/first-rotated-old.xml @@ -0,0 +1,37 @@ +<monitors version="1"> + <configuration> + <clone>no</clone> + <output name="HDMI-1"> + <vendor>DEL</vendor> + <product>DELL P2415Q</product> + <serial>GTTPW67P0WFB</serial> + <width>2160</width> + <height>3840</height> + <rate>29.981103897094727</rate> + <x>0</x> + <y>0</y> + <rotation>left</rotation> + <reflect_x>no</reflect_x> + <reflect_y>no</reflect_y> + <primary>no</primary> + <presentation>no</presentation> + <underscanning>no</underscanning> + </output> + <output name="eDP-1"> + <vendor>AUO</vendor> + <product>0x123d</product> + <serial>0x00000000</serial> + <width>1920</width> + <height>1080</height> + <rate>60.049972534179688</rate> + <x>2160</x> + <y>0</y> + <rotation>normal</rotation> + <reflect_x>no</reflect_x> + <reflect_y>no</reflect_y> + <primary>yes</primary> + <presentation>no</presentation> + <underscanning>no</underscanning> + </output> + </configuration> +</monitors> diff --git a/src/tests/migration/oneoff-new-finished.xml b/src/tests/migration/oneoff-new-finished.xml new file mode 100644 index 000000000..d3ee95c36 --- /dev/null +++ b/src/tests/migration/oneoff-new-finished.xml @@ -0,0 +1,31 @@ +<monitors version="2"> + <configuration> + <logicalmonitor> + <x>0</x> + <y>0</y> + <scale>1</scale> + <primary>yes</primary> + <monitor> + <monitorspec> + <connector>DP-1</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + </monitorspec> + <mode> + <width>800</width> + <height>600</height> + <rate>60</rate> + </mode> + </monitor> + </logicalmonitor> + <disabled> + <monitorspec> + <connector>DP-2</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x654321</serial> + </monitorspec> + </disabled> + </configuration> +</monitors> diff --git a/src/tests/migration/oneoff-new.xml b/src/tests/migration/oneoff-new.xml new file mode 100644 index 000000000..1475c07e2 --- /dev/null +++ b/src/tests/migration/oneoff-new.xml @@ -0,0 +1,31 @@ +<monitors version="2"> + <configuration> + <migrated/> + <logicalmonitor> + <x>0</x> + <y>0</y> + <primary>yes</primary> + <monitor> + <monitorspec> + <connector>DP-1</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + </monitorspec> + <mode> + <width>800</width> + <height>600</height> + <rate>60</rate> + </mode> + </monitor> + </logicalmonitor> + <disabled> + <monitorspec> + <connector>DP-2</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x654321</serial> + </monitorspec> + </disabled> + </configuration> +</monitors> diff --git a/src/tests/migration/oneoff-old.xml b/src/tests/migration/oneoff-old.xml new file mode 100644 index 000000000..185ecd666 --- /dev/null +++ b/src/tests/migration/oneoff-old.xml @@ -0,0 +1,26 @@ +<monitors version="1"> + <configuration> + <clone>no</clone> + <output name="DP-1"> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + <width>800</width> + <height>600</height> + <rate>60</rate> + <x>0</x> + <y>0</y> + <rotation>normal</rotation> + <reflect_x>no</reflect_x> + <reflect_y>no</reflect_y> + <primary>yes</primary> + <presentation>no</presentation> + <underscanning>no</underscanning> + </output> + <output name="DP-2"> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x654321</serial> + </output> + </configuration> +</monitors> diff --git a/src/tests/migration/rotated-new-finished.xml b/src/tests/migration/rotated-new-finished.xml new file mode 100644 index 000000000..ad8d614eb --- /dev/null +++ b/src/tests/migration/rotated-new-finished.xml @@ -0,0 +1,27 @@ +<monitors version="2"> + <configuration> + <logicalmonitor> + <x>0</x> + <y>0</y> + <scale>1</scale> + <primary>yes</primary> + <transform> + <rotation>right</rotation> + <flipped>no</flipped> + </transform> + <monitor> + <monitorspec> + <connector>DP-1</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + </monitorspec> + <mode> + <width>800</width> + <height>600</height> + <rate>60</rate> + </mode> + </monitor> + </logicalmonitor> + </configuration> +</monitors> diff --git a/src/tests/migration/rotated-new.xml b/src/tests/migration/rotated-new.xml new file mode 100644 index 000000000..f8de70beb --- /dev/null +++ b/src/tests/migration/rotated-new.xml @@ -0,0 +1,27 @@ +<monitors version="2"> + <configuration> + <migrated/> + <logicalmonitor> + <x>0</x> + <y>0</y> + <primary>yes</primary> + <transform> + <rotation>right</rotation> + <flipped>no</flipped> + </transform> + <monitor> + <monitorspec> + <connector>DP-1</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + </monitorspec> + <mode> + <width>800</width> + <height>600</height> + <rate>60</rate> + </mode> + </monitor> + </logicalmonitor> + </configuration> +</monitors> diff --git a/src/tests/migration/rotated-old.xml b/src/tests/migration/rotated-old.xml new file mode 100644 index 000000000..cf48ef7b9 --- /dev/null +++ b/src/tests/migration/rotated-old.xml @@ -0,0 +1,21 @@ +<monitors version="1"> + <configuration> + <clone>no</clone> + <output name="DP-1"> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + <width>600</width> + <height>800</height> + <rate>60</rate> + <x>0</x> + <y>0</y> + <rotation>right</rotation> + <reflect_x>no</reflect_x> + <reflect_y>no</reflect_y> + <primary>yes</primary> + <presentation>no</presentation> + <underscanning>no</underscanning> + </output> + </configuration> +</monitors> diff --git a/src/tests/migration/tiled-new.xml b/src/tests/migration/tiled-new.xml new file mode 100644 index 000000000..9fe285ac8 --- /dev/null +++ b/src/tests/migration/tiled-new.xml @@ -0,0 +1,23 @@ +<monitors version="2"> + <configuration> + <migrated/> + <logicalmonitor> + <x>0</x> + <y>0</y> + <primary>yes</primary> + <monitor> + <monitorspec> + <connector>DP-1</connector> + <vendor>DEL</vendor> + <product>DELL P2415Q</product> + <serial>GTTPW67P0WFB</serial> + </monitorspec> + <mode> + <width>3840</width> + <height>2160</height> + <rate>60</rate> + </mode> + </monitor> + </logicalmonitor> + </configuration> +</monitors> diff --git a/src/tests/migration/tiled-old.xml b/src/tests/migration/tiled-old.xml new file mode 100644 index 000000000..8235b31e3 --- /dev/null +++ b/src/tests/migration/tiled-old.xml @@ -0,0 +1,37 @@ +<monitors version="1"> + <configuration> + <clone>no</clone> + <output name="DP-1"> + <vendor>DEL</vendor> + <product>DELL P2415Q</product> + <serial>GTTPW67P0WFB</serial> + <width>1920</width> + <height>2160</height> + <rate>60</rate> + <x>0</x> + <y>0</y> + <rotation>normal</rotation> + <reflect_x>no</reflect_x> + <reflect_y>no</reflect_y> + <primary>yes</primary> + <presentation>no</presentation> + <underscanning>no</underscanning> + </output> + <output name="DP-2"> + <vendor>DEL</vendor> + <product>DELL P2415Q</product> + <serial>GTTPW67P0WFB</serial> + <width>1920</width> + <height>2160</height> + <rate>60</rate> + <x>1920</x> + <y>0</y> + <rotation>normal</rotation> + <reflect_x>no</reflect_x> + <reflect_y>no</reflect_y> + <primary>yes</primary> + <presentation>no</presentation> + <underscanning>no</underscanning> + </output> + </configuration> +</monitors> diff --git a/src/tests/migration/wiggle-new-discarded.xml b/src/tests/migration/wiggle-new-discarded.xml new file mode 100644 index 000000000..fa4090a11 --- /dev/null +++ b/src/tests/migration/wiggle-new-discarded.xml @@ -0,0 +1,2 @@ +<monitors version="2"> +</monitors> diff --git a/src/tests/migration/wiggle-new-finished.xml b/src/tests/migration/wiggle-new-finished.xml new file mode 100644 index 000000000..4d7e9dca1 --- /dev/null +++ b/src/tests/migration/wiggle-new-finished.xml @@ -0,0 +1,27 @@ +<monitors version="2"> + <configuration> + <logicalmonitor> + <x>0</x> + <y>0</y> + <scale>1</scale> + <primary>yes</primary> + <transform> + <rotation>left</rotation> + <flipped>no</flipped> + </transform> + <monitor> + <monitorspec> + <connector>DP-1</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + </monitorspec> + <mode> + <width>800</width> + <height>600</height> + <rate>60.000801086425781</rate> + </mode> + </monitor> + </logicalmonitor> + </configuration> +</monitors> diff --git a/src/tests/migration/wiggle-new.xml b/src/tests/migration/wiggle-new.xml new file mode 100644 index 000000000..9afc90496 --- /dev/null +++ b/src/tests/migration/wiggle-new.xml @@ -0,0 +1,27 @@ +<monitors version="2"> + <configuration> + <migrated/> + <logicalmonitor> + <x>0</x> + <y>0</y> + <primary>yes</primary> + <transform> + <rotation>left</rotation> + <flipped>no</flipped> + </transform> + <monitor> + <monitorspec> + <connector>DP-1</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + </monitorspec> + <mode> + <width>800</width> + <height>600</height> + <rate>60.000801086425781</rate> + </mode> + </monitor> + </logicalmonitor> + </configuration> +</monitors> diff --git a/src/tests/migration/wiggle-old.xml b/src/tests/migration/wiggle-old.xml new file mode 100644 index 000000000..be57011de --- /dev/null +++ b/src/tests/migration/wiggle-old.xml @@ -0,0 +1,21 @@ +<monitors version="1"> + <configuration> + <clone>no</clone> + <output name="DP-1"> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + <width>600</width> + <height>800</height> + <rate>60.000801086425781</rate> + <x>0</x> + <y>0</y> + <rotation>left</rotation> + <reflect_x>no</reflect_x> + <reflect_y>no</reflect_y> + <primary>yes</primary> + <presentation>no</presentation> + <underscanning>no</underscanning> + </output> + </configuration> +</monitors> diff --git a/src/tests/monitor-config-migration-unit-tests.c b/src/tests/monitor-config-migration-unit-tests.c new file mode 100644 index 000000000..461035d63 --- /dev/null +++ b/src/tests/monitor-config-migration-unit-tests.c @@ -0,0 +1,136 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include "tests/monitor-config-migration-unit-tests.h" + +#include <glib.h> +#include <gio/gio.h> + +#include "backends/meta-backend-private.h" +#include "backends/meta-monitor-config-manager.h" +#include "backends/meta-monitor-config-store.h" +#include "backends/meta-monitor-manager-private.h" +#include "backends/meta-monitor-config-migration.h" +#include "tests/monitor-test-utils.h" + +static void +test_migration (const char *old_config, + const char *new_config) +{ + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaMonitorConfigManager *config_manager = monitor_manager->config_manager; + MetaMonitorConfigStore *config_store = + meta_monitor_config_manager_get_store (config_manager); + GError *error = NULL; + const char *old_config_path; + g_autoptr (GFile) old_config_file = NULL; + g_autofree char *migrated_path = NULL; + const char *expected_path; + g_autofree char *migrated_data = NULL; + g_autofree char *expected_data = NULL; + g_autoptr (GFile) migrated_file = NULL; + + migrated_path = g_build_filename (g_get_tmp_dir (), + "test-migrated-monitors.xml", + NULL); + if (!meta_monitor_config_store_set_custom (config_store, "/dev/null", + migrated_path, + &error)) + g_error ("Failed to set custom config store: %s", error->message); + + old_config_path = g_test_get_filename (G_TEST_DIST, "tests", "migration", + old_config, NULL); + old_config_file = g_file_new_for_path (old_config_path); + if (!meta_migrate_old_monitors_config (config_store, + old_config_file, + &error)) + g_error ("Failed to migrate config: %s", error->message); + + expected_path = g_test_get_filename (G_TEST_DIST, "tests", "migration", + new_config, NULL); + + expected_data = read_file (expected_path); + migrated_data = read_file (migrated_path); + + g_assert_nonnull (expected_data); + g_assert_nonnull (migrated_data); + + g_assert (strcmp (expected_data, migrated_data) == 0); + + migrated_file = g_file_new_for_path (migrated_path); + if (!g_file_delete (migrated_file, NULL, &error)) + g_error ("Failed to remove test data output file: %s", error->message); +} + +static void +meta_test_monitor_config_migration_basic (void) +{ + test_migration ("basic-old.xml", "basic-new.xml"); +} + +static void +meta_test_monitor_config_migration_rotated (void) +{ + test_migration ("rotated-old.xml", "rotated-new.xml"); +} + +static void +meta_test_monitor_config_migration_tiled (void) +{ + test_migration ("tiled-old.xml", "tiled-new.xml"); +} + +static void +meta_test_monitor_config_migration_first_rotated (void) +{ + test_migration ("first-rotated-old.xml", "first-rotated-new.xml"); +} + +static void +meta_test_monitor_config_migration_oneoff (void) +{ + test_migration ("oneoff-old.xml", "oneoff-new.xml"); +} + +static void +meta_test_monitor_config_migration_wiggle (void) +{ + test_migration ("wiggle-old.xml", "wiggle-new.xml"); +} + +void +init_monitor_config_migration_tests (void) +{ + g_test_add_func ("/backends/monitor-config-migration/basic", + meta_test_monitor_config_migration_basic); + g_test_add_func ("/backends/monitor-config-migration/rotated", + meta_test_monitor_config_migration_rotated); + g_test_add_func ("/backends/monitor-config-migration/tiled", + meta_test_monitor_config_migration_tiled); + g_test_add_func ("/backends/monitor-config-migration/first-rotated", + meta_test_monitor_config_migration_first_rotated); + g_test_add_func ("/backends/monitor-config-migration/oneoff", + meta_test_monitor_config_migration_oneoff); + g_test_add_func ("/backends/monitor-config-migration/wiggle", + meta_test_monitor_config_migration_wiggle); +} diff --git a/src/tests/monitor-config-migration-unit-tests.h b/src/tests/monitor-config-migration-unit-tests.h new file mode 100644 index 000000000..a8d18de9a --- /dev/null +++ b/src/tests/monitor-config-migration-unit-tests.h @@ -0,0 +1,25 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef MONITOR_CONFIG_MIGRATION_UNIT_TESTS_H +#define MONITOR_CONFIG_MIGRATION_UNIT_TESTS_H + +void init_monitor_config_migration_tests (void); + +#endif /* MONITOR_CONFIG_MIGRATION_UNIT_TESTS_H */ diff --git a/src/tests/monitor-configs/first-rotated.xml b/src/tests/monitor-configs/first-rotated.xml new file mode 100644 index 000000000..f24797554 --- /dev/null +++ b/src/tests/monitor-configs/first-rotated.xml @@ -0,0 +1,47 @@ +<monitors version="2"> + <configuration> + <logicalmonitor> + <x>0</x> + <y>0</y> + <primary>yes</primary> + <transform> + <rotation>right</rotation> + <flipped>no</flipped> + </transform> + <monitor> + <monitorspec> + <connector>DP-1</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + </monitorspec> + <mode> + <width>1024</width> + <height>768</height> + <rate>60.000495910644531</rate> + </mode> + </monitor> + </logicalmonitor> + <logicalmonitor> + <x>768</x> + <y>0</y> + <transform> + <rotation>normal</rotation> + <flipped>no</flipped> + </transform> + <monitor> + <monitorspec> + <connector>DP-2</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + </monitorspec> + <mode> + <width>1024</width> + <height>768</height> + <rate>60.000495910644531</rate> + </mode> + </monitor> + </logicalmonitor> + </configuration> +</monitors> diff --git a/src/tests/monitor-configs/fractional-scale.xml b/src/tests/monitor-configs/fractional-scale.xml new file mode 100644 index 000000000..eeb49b6bc --- /dev/null +++ b/src/tests/monitor-configs/fractional-scale.xml @@ -0,0 +1,23 @@ +<monitors version="2"> + <configuration> + <logicalmonitor> + <x>0</x> + <y>0</y> + <primary>yes</primary> + <scale>1.5</scale> + <monitor> + <monitorspec> + <connector>DP-1</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + </monitorspec> + <mode> + <width>1200</width> + <height>900</height> + <rate>60.000495910644531</rate> + </mode> + </monitor> + </logicalmonitor> + </configuration> +</monitors> diff --git a/src/tests/monitor-configs/high-precision-fractional-scale.xml b/src/tests/monitor-configs/high-precision-fractional-scale.xml new file mode 100644 index 000000000..8fe66477d --- /dev/null +++ b/src/tests/monitor-configs/high-precision-fractional-scale.xml @@ -0,0 +1,23 @@ +<monitors version="2"> + <configuration> + <logicalmonitor> + <x>0</x> + <y>0</y> + <primary>yes</primary> + <scale>1.3763440847396851</scale> + <monitor> + <monitorspec> + <connector>DP-1</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + </monitorspec> + <mode> + <width>1024</width> + <height>768</height> + <rate>60.000495910644531</rate> + </mode> + </monitor> + </logicalmonitor> + </configuration> +</monitors> diff --git a/src/tests/monitor-configs/interlaced.xml b/src/tests/monitor-configs/interlaced.xml new file mode 100644 index 000000000..e7e22feb4 --- /dev/null +++ b/src/tests/monitor-configs/interlaced.xml @@ -0,0 +1,23 @@ +<monitors version="2"> + <configuration> + <logicalmonitor> + <x>0</x> + <y>0</y> + <primary>yes</primary> + <monitor> + <monitorspec> + <connector>DP-1</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + </monitorspec> + <mode> + <width>1024</width> + <height>768</height> + <rate>60.000495910644531</rate> + <flag>interlace</flag> + </mode> + </monitor> + </logicalmonitor> + </configuration> +</monitors> diff --git a/src/tests/monitor-configs/lid-scale.xml b/src/tests/monitor-configs/lid-scale.xml new file mode 100644 index 000000000..9b40f0f9a --- /dev/null +++ b/src/tests/monitor-configs/lid-scale.xml @@ -0,0 +1,23 @@ +<monitors version="2"> + <configuration> + <logicalmonitor> + <x>0</x> + <y>0</y> + <primary>yes</primary> + <scale>2</scale> + <monitor> + <monitorspec> + <connector>eDP-1</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + </monitorspec> + <mode> + <width>1920</width> + <height>1080</height> + <rate>60.000495910644531</rate> + </mode> + </monitor> + </logicalmonitor> + </configuration> +</monitors> diff --git a/src/tests/monitor-configs/lid-switch.xml b/src/tests/monitor-configs/lid-switch.xml new file mode 100644 index 000000000..fe5144660 --- /dev/null +++ b/src/tests/monitor-configs/lid-switch.xml @@ -0,0 +1,91 @@ +<monitors version="2"> + <configuration> + <logicalmonitor> + <x>0</x> + <y>0</y> + <primary>yes</primary> + <monitor> + <monitorspec> + <connector>eDP-1</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + </monitorspec> + <mode> + <width>1024</width> + <height>768</height> + <rate>60.000495910644531</rate> + </mode> + </monitor> + </logicalmonitor> + <logicalmonitor> + <x>1024</x> + <y>0</y> + <transform> + <rotation>right</rotation> + <flipped>no</flipped> + </transform> + <monitor> + <monitorspec> + <connector>DP-1</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + </monitorspec> + <mode> + <width>1024</width> + <height>768</height> + <rate>60.000495910644531</rate> + </mode> + </monitor> + </logicalmonitor> + </configuration> + <configuration> + <logicalmonitor> + <x>0</x> + <y>0</y> + <primary>yes</primary> + <transform> + <rotation>left</rotation> + <flipped>no</flipped> + </transform> + <monitor> + <monitorspec> + <connector>DP-1</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + </monitorspec> + <mode> + <width>1024</width> + <height>768</height> + <rate>60.000495910644531</rate> + </mode> + </monitor> + </logicalmonitor> + </configuration> + <configuration> + <logicalmonitor> + <x>0</x> + <y>0</y> + <primary>yes</primary> + <transform> + <rotation>right</rotation> + <flipped>no</flipped> + </transform> + <monitor> + <monitorspec> + <connector>eDP-1</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + </monitorspec> + <mode> + <width>1024</width> + <height>768</height> + <rate>60.000495910644531</rate> + </mode> + </monitor> + </logicalmonitor> + </configuration> +</monitors> diff --git a/src/tests/monitor-configs/mirrored.xml b/src/tests/monitor-configs/mirrored.xml new file mode 100644 index 000000000..0db260f8c --- /dev/null +++ b/src/tests/monitor-configs/mirrored.xml @@ -0,0 +1,35 @@ +<monitors version="2"> + <configuration> + <logicalmonitor> + <x>0</x> + <y>0</y> + <primary>yes</primary> + <monitor> + <monitorspec> + <connector>DP-1</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + </monitorspec> + <mode> + <width>800</width> + <height>600</height> + <rate>60.000495910644531</rate> + </mode> + </monitor> + <monitor> + <monitorspec> + <connector>DP-2</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + </monitorspec> + <mode> + <width>800</width> + <height>600</height> + <rate>60.000495910644531</rate> + </mode> + </monitor> + </logicalmonitor> + </configuration> +</monitors> diff --git a/src/tests/monitor-configs/non-preferred-tiled-custom-resolution.xml b/src/tests/monitor-configs/non-preferred-tiled-custom-resolution.xml new file mode 100644 index 000000000..8ee2abf09 --- /dev/null +++ b/src/tests/monitor-configs/non-preferred-tiled-custom-resolution.xml @@ -0,0 +1,22 @@ +<monitors version="2"> + <configuration> + <logicalmonitor> + <x>0</x> + <y>0</y> + <primary>yes</primary> + <monitor> + <monitorspec> + <connector>DP-2</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + </monitorspec> + <mode> + <width>800</width> + <height>600</height> + <rate>60</rate> + </mode> + </monitor> + </logicalmonitor> + </configuration> +</monitors> diff --git a/src/tests/monitor-configs/oneoff.xml b/src/tests/monitor-configs/oneoff.xml new file mode 100644 index 000000000..4e5c6b7a5 --- /dev/null +++ b/src/tests/monitor-configs/oneoff.xml @@ -0,0 +1,31 @@ +<monitors version="2"> + <configuration> + <logicalmonitor> + <x>0</x> + <y>0</y> + <scale>1</scale> + <primary>yes</primary> + <monitor> + <monitorspec> + <connector>DP-1</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + </monitorspec> + <mode> + <width>800</width> + <height>600</height> + <rate>60</rate> + </mode> + </monitor> + </logicalmonitor> + <disabled> + <monitorspec> + <connector>DP-2</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x654321</serial> + </monitorspec> + </disabled> + </configuration> +</monitors> diff --git a/src/tests/monitor-configs/primary.xml b/src/tests/monitor-configs/primary.xml new file mode 100644 index 000000000..7238b4fd8 --- /dev/null +++ b/src/tests/monitor-configs/primary.xml @@ -0,0 +1,40 @@ +<monitors version="2"> + <configuration> + <logicalmonitor> + <x>0</x> + <y>0</y> + <primary>no</primary> + <monitor> + <monitorspec> + <connector>DP-1</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + </monitorspec> + <mode> + <width>1024</width> + <height>768</height> + <rate>60.000495910644531</rate> + </mode> + </monitor> + </logicalmonitor> + <logicalmonitor> + <x>1024</x> + <y>0</y> + <primary>yes</primary> + <monitor> + <monitorspec> + <connector>DP-2</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + </monitorspec> + <mode> + <width>800</width> + <height>600</height> + <rate>60.000495910644531</rate> + </mode> + </monitor> + </logicalmonitor> + </configuration> +</monitors> diff --git a/src/tests/monitor-configs/scale.xml b/src/tests/monitor-configs/scale.xml new file mode 100644 index 000000000..d6c66b70b --- /dev/null +++ b/src/tests/monitor-configs/scale.xml @@ -0,0 +1,23 @@ +<monitors version="2"> + <configuration> + <logicalmonitor> + <x>0</x> + <y>0</y> + <primary>yes</primary> + <scale>2</scale> + <monitor> + <monitorspec> + <connector>DP-1</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + </monitorspec> + <mode> + <width>1920</width> + <height>1080</height> + <rate>60.000495910644531</rate> + </mode> + </monitor> + </logicalmonitor> + </configuration> +</monitors> diff --git a/src/tests/monitor-configs/second-rotated-tiled.xml b/src/tests/monitor-configs/second-rotated-tiled.xml new file mode 100644 index 000000000..a8593d503 --- /dev/null +++ b/src/tests/monitor-configs/second-rotated-tiled.xml @@ -0,0 +1,43 @@ +<monitors version="2"> + <configuration> + <logicalmonitor> + <x>0</x> + <y>256</y> + <primary>yes</primary> + <monitor> + <monitorspec> + <connector>DP-1</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + </monitorspec> + <mode> + <width>1024</width> + <height>768</height> + <rate>60.000495910644531</rate> + </mode> + </monitor> + </logicalmonitor> + <logicalmonitor> + <x>1024</x> + <y>0</y> + <transform> + <rotation>left</rotation> + <flipped>no</flipped> + </transform> + <monitor> + <monitorspec> + <connector>DP-2</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + </monitorspec> + <mode> + <width>800</width> + <height>600</height> + <rate>60.000495910644531</rate> + </mode> + </monitor> + </logicalmonitor> + </configuration> +</monitors> diff --git a/src/tests/monitor-configs/second-rotated.xml b/src/tests/monitor-configs/second-rotated.xml new file mode 100644 index 000000000..ee70c5e9b --- /dev/null +++ b/src/tests/monitor-configs/second-rotated.xml @@ -0,0 +1,43 @@ +<monitors version="2"> + <configuration> + <logicalmonitor> + <x>0</x> + <y>256</y> + <primary>yes</primary> + <monitor> + <monitorspec> + <connector>DP-1</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + </monitorspec> + <mode> + <width>1024</width> + <height>768</height> + <rate>60.000495910644531</rate> + </mode> + </monitor> + </logicalmonitor> + <logicalmonitor> + <x>1024</x> + <y>0</y> + <transform> + <rotation>left</rotation> + <flipped>no</flipped> + </transform> + <monitor> + <monitorspec> + <connector>DP-2</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + </monitorspec> + <mode> + <width>1024</width> + <height>768</height> + <rate>60.000495910644531</rate> + </mode> + </monitor> + </logicalmonitor> + </configuration> +</monitors> diff --git a/src/tests/monitor-configs/single.xml b/src/tests/monitor-configs/single.xml new file mode 100644 index 000000000..771957a4a --- /dev/null +++ b/src/tests/monitor-configs/single.xml @@ -0,0 +1,22 @@ +<monitors version="2"> + <configuration> + <logicalmonitor> + <x>0</x> + <y>0</y> + <primary>yes</primary> + <monitor> + <monitorspec> + <connector>DP-1</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + </monitorspec> + <mode> + <width>1920</width> + <height>1080</height> + <rate>60.000495910644531</rate> + </mode> + </monitor> + </logicalmonitor> + </configuration> +</monitors> diff --git a/src/tests/monitor-configs/tiled-custom-resolution.xml b/src/tests/monitor-configs/tiled-custom-resolution.xml new file mode 100644 index 000000000..b51c3b6f6 --- /dev/null +++ b/src/tests/monitor-configs/tiled-custom-resolution.xml @@ -0,0 +1,23 @@ +<monitors version="2"> + <configuration> + <logicalmonitor> + <x>0</x> + <y>0</y> + <primary>yes</primary> + <scale>2</scale> + <monitor> + <monitorspec> + <connector>DP-1</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + </monitorspec> + <mode> + <width>640</width> + <height>480</height> + <rate>60.000495910644531</rate> + </mode> + </monitor> + </logicalmonitor> + </configuration> +</monitors> diff --git a/src/tests/monitor-configs/tiled.xml b/src/tests/monitor-configs/tiled.xml new file mode 100644 index 000000000..806a5853b --- /dev/null +++ b/src/tests/monitor-configs/tiled.xml @@ -0,0 +1,23 @@ +<monitors version="2"> + <configuration> + <logicalmonitor> + <x>0</x> + <y>0</y> + <primary>yes</primary> + <scale>2</scale> + <monitor> + <monitorspec> + <connector>DP-1</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + </monitorspec> + <mode> + <width>800</width> + <height>600</height> + <rate>60.000495910644531</rate> + </mode> + </monitor> + </logicalmonitor> + </configuration> +</monitors> diff --git a/src/tests/monitor-configs/underscanning.xml b/src/tests/monitor-configs/underscanning.xml new file mode 100644 index 000000000..7bcd6e75a --- /dev/null +++ b/src/tests/monitor-configs/underscanning.xml @@ -0,0 +1,23 @@ +<monitors version="2"> + <configuration> + <logicalmonitor> + <x>0</x> + <y>0</y> + <primary>yes</primary> + <monitor> + <monitorspec> + <connector>DP-1</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + </monitorspec> + <mode> + <width>1024</width> + <height>768</height> + <rate>60.000495910644531</rate> + </mode> + <underscanning>yes</underscanning> + </monitor> + </logicalmonitor> + </configuration> +</monitors> diff --git a/src/tests/monitor-configs/vertical.xml b/src/tests/monitor-configs/vertical.xml new file mode 100644 index 000000000..76f11297b --- /dev/null +++ b/src/tests/monitor-configs/vertical.xml @@ -0,0 +1,39 @@ +<monitors version="2"> + <configuration> + <logicalmonitor> + <x>0</x> + <y>0</y> + <primary>yes</primary> + <monitor> + <monitorspec> + <connector>DP-1</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + </monitorspec> + <mode> + <width>1024</width> + <height>768</height> + <rate>60.000495910644531</rate> + </mode> + </monitor> + </logicalmonitor> + <logicalmonitor> + <x>0</x> + <y>768</y> + <monitor> + <monitorspec> + <connector>DP-2</connector> + <vendor>MetaProduct's Inc.</vendor> + <product>MetaMonitor</product> + <serial>0x123456</serial> + </monitorspec> + <mode> + <width>800</width> + <height>600</height> + <rate>60.000495910644531</rate> + </mode> + </monitor> + </logicalmonitor> + </configuration> +</monitors> diff --git a/src/tests/monitor-store-unit-tests.c b/src/tests/monitor-store-unit-tests.c new file mode 100644 index 000000000..4a73d89db --- /dev/null +++ b/src/tests/monitor-store-unit-tests.c @@ -0,0 +1,864 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include "tests/monitor-store-unit-tests.h" + +#include "backends/meta-backend-private.h" +#include "backends/meta-monitor-config-store.h" +#include "backends/meta-monitor-config-manager.h" +#include "backends/meta-monitor-manager-private.h" +#include "tests/monitor-test-utils.h" + +#define MAX_N_MONITORS 10 +#define MAX_N_LOGICAL_MONITORS 10 +#define MAX_N_CONFIGURATIONS 10 + +typedef struct _MonitorTestCaseMonitorMode +{ + int width; + int height; + float refresh_rate; + MetaCrtcModeFlag flags; +} MonitorTestCaseMonitorMode; + +typedef struct _MonitorTestCaseMonitor +{ + const char *connector; + const char *vendor; + const char *product; + const char *serial; + MonitorTestCaseMonitorMode mode; + gboolean is_underscanning; +} MonitorTestCaseMonitor; + +typedef struct _MonitorTestCaseLogicalMonitor +{ + MetaRectangle layout; + float scale; + MetaMonitorTransform transform; + gboolean is_primary; + gboolean is_presentation; + MonitorTestCaseMonitor monitors[MAX_N_MONITORS]; + int n_monitors; +} MonitorTestCaseLogicalMonitor; + +typedef struct _MonitorStoreTestConfiguration +{ + MonitorTestCaseLogicalMonitor logical_monitors[MAX_N_LOGICAL_MONITORS]; + int n_logical_monitors; +} MonitorStoreTestConfiguration; + +typedef struct _MonitorStoreTestExpect +{ + MonitorStoreTestConfiguration configurations[MAX_N_CONFIGURATIONS]; + int n_configurations; +} MonitorStoreTestExpect; + +static MetaMonitorsConfigKey * +create_config_key_from_expect (MonitorStoreTestConfiguration *expect_config) +{ + MetaMonitorsConfigKey *config_key; + GList *monitor_specs; + int i; + + monitor_specs = NULL; + for (i = 0; i < expect_config->n_logical_monitors; i++) + { + int j; + + for (j = 0; j < expect_config->logical_monitors[i].n_monitors; j++) + { + MetaMonitorSpec *monitor_spec; + MonitorTestCaseMonitor *test_monitor = + &expect_config->logical_monitors[i].monitors[j]; + + monitor_spec = g_new0 (MetaMonitorSpec, 1); + + monitor_spec->connector = g_strdup (test_monitor->connector); + monitor_spec->vendor = g_strdup (test_monitor->vendor); + monitor_spec->product = g_strdup (test_monitor->product); + monitor_spec->serial = g_strdup (test_monitor->serial); + + monitor_specs = g_list_prepend (monitor_specs, monitor_spec); + } + } + + g_assert_nonnull (monitor_specs); + + monitor_specs = g_list_sort (monitor_specs, + (GCompareFunc) meta_monitor_spec_compare); + + config_key = g_new0 (MetaMonitorsConfigKey, 1); + *config_key = (MetaMonitorsConfigKey) { + .monitor_specs = monitor_specs + }; + + return config_key; +} + +static void +check_monitor_configuration (MetaMonitorConfigStore *config_store, + MonitorStoreTestConfiguration *config_expect) +{ + MetaMonitorsConfigKey *config_key; + MetaMonitorsConfig *config; + GList *l; + int i; + + config_key = create_config_key_from_expect (config_expect); + config = meta_monitor_config_store_lookup (config_store, config_key); + g_assert_nonnull (config); + + g_assert (meta_monitors_config_key_equal (config->key, config_key)); + meta_monitors_config_key_free (config_key); + + g_assert_cmpuint (g_list_length (config->logical_monitor_configs), + ==, + config_expect->n_logical_monitors); + + for (l = config->logical_monitor_configs, i = 0; l; l = l->next, i++) + { + MetaLogicalMonitorConfig *logical_monitor_config = l->data; + GList *k; + int j; + + g_assert (meta_rectangle_equal (&logical_monitor_config->layout, + &config_expect->logical_monitors[i].layout)); + g_assert_cmpfloat (logical_monitor_config->scale, + ==, + config_expect->logical_monitors[i].scale); + g_assert_cmpint (logical_monitor_config->transform, + ==, + config_expect->logical_monitors[i].transform); + g_assert_cmpint (logical_monitor_config->is_primary, + ==, + config_expect->logical_monitors[i].is_primary); + g_assert_cmpint (logical_monitor_config->is_presentation, + ==, + config_expect->logical_monitors[i].is_presentation); + + g_assert_cmpint ((int) g_list_length (logical_monitor_config->monitor_configs), + ==, + config_expect->logical_monitors[i].n_monitors); + + for (k = logical_monitor_config->monitor_configs, j = 0; + k; + k = k->next, j++) + { + MetaMonitorConfig *monitor_config = k->data; + MonitorTestCaseMonitor *test_monitor = + &config_expect->logical_monitors[i].monitors[j]; + + g_assert_cmpstr (monitor_config->monitor_spec->connector, + ==, + test_monitor->connector); + g_assert_cmpstr (monitor_config->monitor_spec->vendor, + ==, + test_monitor->vendor); + g_assert_cmpstr (monitor_config->monitor_spec->product, + ==, + test_monitor->product); + g_assert_cmpstr (monitor_config->monitor_spec->serial, + ==, + test_monitor->serial); + + g_assert_cmpint (monitor_config->mode_spec->width, + ==, + test_monitor->mode.width); + g_assert_cmpint (monitor_config->mode_spec->height, + ==, + test_monitor->mode.height); + g_assert_cmpfloat (monitor_config->mode_spec->refresh_rate, + ==, + test_monitor->mode.refresh_rate); + g_assert_cmpint (monitor_config->mode_spec->flags, + ==, + test_monitor->mode.flags); + g_assert_cmpint (monitor_config->enable_underscanning, + ==, + test_monitor->is_underscanning); + } + } +} + +static void +check_monitor_configurations (MonitorStoreTestExpect *expect) +{ + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaMonitorConfigManager *config_manager = monitor_manager->config_manager; + MetaMonitorConfigStore *config_store = + meta_monitor_config_manager_get_store (config_manager); + int i; + + g_assert_cmpint (meta_monitor_config_store_get_config_count (config_store), + ==, + expect->n_configurations); + + for (i = 0; i < expect->n_configurations; i++) + check_monitor_configuration (config_store, &expect->configurations[i]); +} + +static void +meta_test_monitor_store_single (void) +{ + MonitorStoreTestExpect expect = { + .configurations = { + { + .logical_monitors = { + { + .layout = { + .x = 0, + .y = 0, + .width = 1920, + .height = 1080 + }, + .scale = 1, + .is_primary = TRUE, + .is_presentation = FALSE, + .monitors = { + { + .connector = "DP-1", + .vendor = "MetaProduct's Inc.", + .product = "MetaMonitor", + .serial = "0x123456", + .mode = { + .width = 1920, + .height = 1080, + .refresh_rate = 60.000495910644531 + } + } + }, + .n_monitors = 1, + } + }, + .n_logical_monitors = 1 + } + }, + .n_configurations = 1 + }; + + set_custom_monitor_config ("single.xml"); + + check_monitor_configurations (&expect); +} + +static void +meta_test_monitor_store_vertical (void) +{ + MonitorStoreTestExpect expect = { + .configurations = { + { + .logical_monitors = { + { + .layout = { + .x = 0, + .y = 0, + .width = 1024, + .height = 768 + }, + .scale = 1, + .is_primary = TRUE, + .is_presentation = FALSE, + .monitors = { + { + .connector = "DP-1", + .vendor = "MetaProduct's Inc.", + .product = "MetaMonitor", + .serial = "0x123456", + .mode = { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531 + } + } + }, + .n_monitors = 1, + }, + { + .layout = { + .x = 0, + .y = 768, + .width = 800, + .height = 600 + }, + .scale = 1, + .is_primary = FALSE, + .is_presentation = FALSE, + .monitors = { + { + .connector = "DP-2", + .vendor = "MetaProduct's Inc.", + .product = "MetaMonitor", + .serial = "0x123456", + .mode = { + .width = 800, + .height = 600, + .refresh_rate = 60.000495910644531 + } + } + }, + .n_monitors = 1, + } + }, + .n_logical_monitors = 2 + } + }, + .n_configurations = 1 + }; + + set_custom_monitor_config ("vertical.xml"); + + check_monitor_configurations (&expect); +} + +static void +meta_test_monitor_store_primary (void) +{ + MonitorStoreTestExpect expect = { + .configurations = { + { + .logical_monitors = { + { + .layout = { + .x = 0, + .y = 0, + .width = 1024, + .height = 768 + }, + .scale = 1, + .is_primary = FALSE, + .is_presentation = FALSE, + .monitors = { + { + .connector = "DP-1", + .vendor = "MetaProduct's Inc.", + .product = "MetaMonitor", + .serial = "0x123456", + .mode = { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531 + } + } + }, + .n_monitors = 1, + }, + { + .layout = { + .x = 1024, + .y = 0, + .width = 800, + .height = 600 + }, + .scale = 1, + .is_primary = TRUE, + .is_presentation = FALSE, + .monitors = { + { + .connector = "DP-2", + .vendor = "MetaProduct's Inc.", + .product = "MetaMonitor", + .serial = "0x123456", + .mode = { + .width = 800, + .height = 600, + .refresh_rate = 60.000495910644531 + } + } + }, + .n_monitors = 1, + } + }, + .n_logical_monitors = 2 + } + }, + .n_configurations = 1 + }; + + set_custom_monitor_config ("primary.xml"); + + check_monitor_configurations (&expect); +} + +static void +meta_test_monitor_store_underscanning (void) +{ + MonitorStoreTestExpect expect = { + .configurations = { + { + .logical_monitors = { + { + .layout = { + .x = 0, + .y = 0, + .width = 1024, + .height = 768 + }, + .scale = 1, + .is_primary = TRUE, + .is_presentation = FALSE, + .monitors = { + { + .connector = "DP-1", + .vendor = "MetaProduct's Inc.", + .product = "MetaMonitor", + .serial = "0x123456", + .is_underscanning = TRUE, + .mode = { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531 + } + } + }, + .n_monitors = 1, + }, + }, + .n_logical_monitors = 1 + } + }, + .n_configurations = 1 + }; + + set_custom_monitor_config ("underscanning.xml"); + + check_monitor_configurations (&expect); +} + +static void +meta_test_monitor_store_scale (void) +{ + MonitorStoreTestExpect expect = { + .configurations = { + { + .logical_monitors = { + { + .layout = { + .x = 0, + .y = 0, + .width = 960, + .height = 540 + }, + .scale = 2, + .is_primary = TRUE, + .is_presentation = FALSE, + .monitors = { + { + .connector = "DP-1", + .vendor = "MetaProduct's Inc.", + .product = "MetaMonitor", + .serial = "0x123456", + .mode = { + .width = 1920, + .height = 1080, + .refresh_rate = 60.000495910644531 + } + } + }, + .n_monitors = 1, + } + }, + .n_logical_monitors = 1 + } + }, + .n_configurations = 1 + }; + + if (!meta_is_stage_views_enabled ()) + { + g_test_skip ("Not using stage views"); + return; + } + + set_custom_monitor_config ("scale.xml"); + + check_monitor_configurations (&expect); +} + +static void +meta_test_monitor_store_fractional_scale (void) +{ + MonitorStoreTestExpect expect = { + .configurations = { + { + .logical_monitors = { + { + .layout = { + .x = 0, + .y = 0, + .width = 800, + .height = 600 + }, + .scale = 1.5, + .is_primary = TRUE, + .is_presentation = FALSE, + .monitors = { + { + .connector = "DP-1", + .vendor = "MetaProduct's Inc.", + .product = "MetaMonitor", + .serial = "0x123456", + .mode = { + .width = 1200, + .height = 900, + .refresh_rate = 60.000495910644531 + } + } + }, + .n_monitors = 1, + } + }, + .n_logical_monitors = 1 + } + }, + .n_configurations = 1 + }; + + if (!meta_is_stage_views_enabled ()) + { + g_test_skip ("Not using stage views"); + return; + } + + set_custom_monitor_config ("fractional-scale.xml"); + + check_monitor_configurations (&expect); +} + +static void +meta_test_monitor_store_high_precision_fractional_scale (void) +{ + MonitorStoreTestExpect expect = { + .configurations = { + { + .logical_monitors = { + { + .layout = { + .x = 0, + .y = 0, + .width = 744, + .height = 558 + }, + .scale = 1.3763440847396851, + .is_primary = TRUE, + .is_presentation = FALSE, + .monitors = { + { + .connector = "DP-1", + .vendor = "MetaProduct's Inc.", + .product = "MetaMonitor", + .serial = "0x123456", + .mode = { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531 + } + } + }, + .n_monitors = 1, + } + }, + .n_logical_monitors = 1 + } + }, + .n_configurations = 1 + }; + + if (!meta_is_stage_views_enabled ()) + { + g_test_skip ("Not using stage views"); + return; + } + + set_custom_monitor_config ("high-precision-fractional-scale.xml"); + + check_monitor_configurations (&expect); +} + +static void +meta_test_monitor_store_mirrored (void) +{ + MonitorStoreTestExpect expect = { + .configurations = { + { + .logical_monitors = { + { + .layout = { + .x = 0, + .y = 0, + .width = 800, + .height = 600 + }, + .scale = 1, + .is_primary = TRUE, + .monitors = { + { + .connector = "DP-1", + .vendor = "MetaProduct's Inc.", + .product = "MetaMonitor", + .serial = "0x123456", + .mode = { + .width = 800, + .height = 600, + .refresh_rate = 60.000495910644531 + } + }, + { + .connector = "DP-2", + .vendor = "MetaProduct's Inc.", + .product = "MetaMonitor", + .serial = "0x123456", + .mode = { + .width = 800, + .height = 600, + .refresh_rate = 60.000495910644531 + } + } + }, + .n_monitors = 2, + } + }, + .n_logical_monitors = 1 + } + }, + .n_configurations = 1 + }; + + set_custom_monitor_config ("mirrored.xml"); + + check_monitor_configurations (&expect); +} + +static void +meta_test_monitor_store_first_rotated (void) +{ + MonitorStoreTestExpect expect = { + .configurations = { + { + .logical_monitors = { + { + .layout = { + .x = 0, + .y = 0, + .width = 768, + .height = 1024 + }, + .scale = 1, + .transform = META_MONITOR_TRANSFORM_270, + .is_primary = TRUE, + .is_presentation = FALSE, + .monitors = { + { + .connector = "DP-1", + .vendor = "MetaProduct's Inc.", + .product = "MetaMonitor", + .serial = "0x123456", + .mode = { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531 + } + } + }, + .n_monitors = 1, + }, + { + .layout = { + .x = 768, + .y = 0, + .width = 1024, + .height = 768 + }, + .scale = 1, + .transform = META_MONITOR_TRANSFORM_NORMAL, + .is_primary = FALSE, + .is_presentation = FALSE, + .monitors = { + { + .connector = "DP-2", + .vendor = "MetaProduct's Inc.", + .product = "MetaMonitor", + .serial = "0x123456", + .mode = { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531 + } + } + }, + .n_monitors = 1, + } + }, + .n_logical_monitors = 2 + } + }, + .n_configurations = 1 + }; + + set_custom_monitor_config ("first-rotated.xml"); + + check_monitor_configurations (&expect); +} + +static void +meta_test_monitor_store_second_rotated (void) +{ + MonitorStoreTestExpect expect = { + .configurations = { + { + .logical_monitors = { + { + .layout = { + .x = 0, + .y = 256, + .width = 1024, + .height = 768 + }, + .scale = 1, + .transform = META_MONITOR_TRANSFORM_NORMAL, + .is_primary = TRUE, + .is_presentation = FALSE, + .monitors = { + { + .connector = "DP-1", + .vendor = "MetaProduct's Inc.", + .product = "MetaMonitor", + .serial = "0x123456", + .mode = { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531 + } + } + }, + .n_monitors = 1, + }, + { + .layout = { + .x = 1024, + .y = 0, + .width = 768, + .height = 1024 + }, + .scale = 1, + .transform = META_MONITOR_TRANSFORM_90, + .is_primary = FALSE, + .is_presentation = FALSE, + .monitors = { + { + .connector = "DP-2", + .vendor = "MetaProduct's Inc.", + .product = "MetaMonitor", + .serial = "0x123456", + .mode = { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531 + } + } + }, + .n_monitors = 1, + } + }, + .n_logical_monitors = 2 + } + }, + .n_configurations = 1 + }; + + set_custom_monitor_config ("second-rotated.xml"); + + check_monitor_configurations (&expect); +} + +static void +meta_test_monitor_store_interlaced (void) +{ + MonitorStoreTestExpect expect = { + .configurations = { + { + .logical_monitors = { + { + .layout = { + .x = 0, + .y = 0, + .width = 1024, + .height = 768 + }, + .scale = 1, + .is_primary = TRUE, + .is_presentation = FALSE, + .monitors = { + { + .connector = "DP-1", + .vendor = "MetaProduct's Inc.", + .product = "MetaMonitor", + .serial = "0x123456", + .mode = { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531, + .flags = META_CRTC_MODE_FLAG_INTERLACE, + } + } + }, + .n_monitors = 1, + }, + }, + .n_logical_monitors = 1 + } + }, + .n_configurations = 1 + }; + + set_custom_monitor_config ("interlaced.xml"); + + check_monitor_configurations (&expect); +} + +void +init_monitor_store_tests (void) +{ + g_test_add_func ("/backends/monitor-store/single", + meta_test_monitor_store_single); + g_test_add_func ("/backends/monitor-store/vertical", + meta_test_monitor_store_vertical); + g_test_add_func ("/backends/monitor-store/primary", + meta_test_monitor_store_primary); + g_test_add_func ("/backends/monitor-store/underscanning", + meta_test_monitor_store_underscanning); + g_test_add_func ("/backends/monitor-store/scale", + meta_test_monitor_store_scale); + g_test_add_func ("/backends/monitor-store/fractional-scale", + meta_test_monitor_store_fractional_scale); + g_test_add_func ("/backends/monitor-store/high-precision-fractional-scale", + meta_test_monitor_store_high_precision_fractional_scale); + g_test_add_func ("/backends/monitor-store/mirrored", + meta_test_monitor_store_mirrored); + g_test_add_func ("/backends/monitor-store/first-rotated", + meta_test_monitor_store_first_rotated); + g_test_add_func ("/backends/monitor-store/second-rotated", + meta_test_monitor_store_second_rotated); + g_test_add_func ("/backends/monitor-store/interlaced", + meta_test_monitor_store_interlaced); +} diff --git a/src/tests/monitor-store-unit-tests.h b/src/tests/monitor-store-unit-tests.h new file mode 100644 index 000000000..2e9496d32 --- /dev/null +++ b/src/tests/monitor-store-unit-tests.h @@ -0,0 +1,25 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef MONITOR_STORE_UNIT_TESTS_H +#define MONITOR_STORE_UNIT_TESTS_H + +void init_monitor_store_tests (void); + +#endif /* MONITOR_STORE_UNIT_TESTS_H */ diff --git a/src/tests/monitor-test-utils.c b/src/tests/monitor-test-utils.c new file mode 100644 index 000000000..548815691 --- /dev/null +++ b/src/tests/monitor-test-utils.c @@ -0,0 +1,81 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include "tests/monitor-test-utils.h" + +#include "backends/meta-backend-private.h" +#include "backends/meta-monitor-config-manager.h" +#include "backends/meta-monitor-config-store.h" + +void +set_custom_monitor_config (const char *filename) +{ + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaMonitorConfigManager *config_manager = monitor_manager->config_manager; + MetaMonitorConfigStore *config_store; + GError *error = NULL; + const char *path; + + g_assert_nonnull (config_manager); + + config_store = meta_monitor_config_manager_get_store (config_manager); + + path = g_test_get_filename (G_TEST_DIST, "tests", "monitor-configs", + filename, NULL); + if (!meta_monitor_config_store_set_custom (config_store, path, NULL, + &error)) + g_error ("Failed to set custom config: %s", error->message); +} + +char * +read_file (const char *file_path) +{ + g_autoptr (GFile) file = NULL; + g_autoptr (GFileInputStream) input_stream = NULL; + g_autoptr (GFileInfo) file_info = NULL; + goffset file_size; + gsize bytes_read; + g_autofree char *buffer = NULL; + GError *error = NULL; + + file = g_file_new_for_path (file_path); + input_stream = g_file_read (file, NULL, &error); + if (!input_stream) + g_error ("Failed to read migrated config file: %s", error->message); + + file_info = g_file_input_stream_query_info (input_stream, + G_FILE_ATTRIBUTE_STANDARD_SIZE, + NULL, &error); + if (!file_info) + g_error ("Failed to read file info: %s", error->message); + + file_size = g_file_info_get_size (file_info); + buffer = g_malloc0 (file_size + 1); + + if (!g_input_stream_read_all (G_INPUT_STREAM (input_stream), + buffer, file_size, &bytes_read, NULL, &error)) + g_error ("Failed to read file content: %s", error->message); + g_assert_cmpint ((goffset) bytes_read, ==, file_size); + + return g_steal_pointer (&buffer); +} diff --git a/src/tests/monitor-test-utils.h b/src/tests/monitor-test-utils.h new file mode 100644 index 000000000..4b9b3f0c7 --- /dev/null +++ b/src/tests/monitor-test-utils.h @@ -0,0 +1,31 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef MONITOR_TEST_UTILS_H +#define MONITOR_TEST_UTILS_H + +#include <glib.h> + +gboolean is_using_monitor_config_manager (void); + +void set_custom_monitor_config (const char *filename); + +char * read_file (const char *file_path); + +#endif /* MONITOR_TEST_UTILS_H */ diff --git a/src/tests/monitor-transform-tests.c b/src/tests/monitor-transform-tests.c new file mode 100644 index 000000000..91ce985be --- /dev/null +++ b/src/tests/monitor-transform-tests.c @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2020 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include "tests/monitor-transform-tests.h" + +#include "backends/meta-monitor-transform.h" + +static void +test_transform (void) +{ + const struct + { + MetaMonitorTransform transform; + MetaMonitorTransform other; + MetaMonitorTransform expect; + } tests[] = { + { + .transform = META_MONITOR_TRANSFORM_NORMAL, + .other = META_MONITOR_TRANSFORM_90, + .expect = META_MONITOR_TRANSFORM_90, + }, + { + .transform = META_MONITOR_TRANSFORM_NORMAL, + .other = META_MONITOR_TRANSFORM_FLIPPED_90, + .expect = META_MONITOR_TRANSFORM_FLIPPED_90, + }, + { + .transform = META_MONITOR_TRANSFORM_90, + .other = META_MONITOR_TRANSFORM_90, + .expect = META_MONITOR_TRANSFORM_180, + }, + { + .transform = META_MONITOR_TRANSFORM_FLIPPED_90, + .other = META_MONITOR_TRANSFORM_90, + .expect = META_MONITOR_TRANSFORM_FLIPPED_180, + }, + { + .transform = META_MONITOR_TRANSFORM_FLIPPED_90, + .other = META_MONITOR_TRANSFORM_180, + .expect = META_MONITOR_TRANSFORM_FLIPPED_270, + }, + { + .transform = META_MONITOR_TRANSFORM_FLIPPED_180, + .other = META_MONITOR_TRANSFORM_FLIPPED_180, + .expect = META_MONITOR_TRANSFORM_NORMAL, + }, + { + .transform = META_MONITOR_TRANSFORM_NORMAL, + .other = -META_MONITOR_TRANSFORM_90, + .expect = META_MONITOR_TRANSFORM_270, + }, + { + .transform = META_MONITOR_TRANSFORM_FLIPPED, + .other = -META_MONITOR_TRANSFORM_90, + .expect = META_MONITOR_TRANSFORM_FLIPPED_270, + }, + { + .transform = META_MONITOR_TRANSFORM_FLIPPED_180, + .other = -META_MONITOR_TRANSFORM_270, + .expect = META_MONITOR_TRANSFORM_FLIPPED_270, + }, + { + .transform = META_MONITOR_TRANSFORM_FLIPPED_180, + .other = -META_MONITOR_TRANSFORM_FLIPPED_180, + .expect = META_MONITOR_TRANSFORM_NORMAL, + }, + }; + int i; + + for (i = 0; i < G_N_ELEMENTS (tests); i++) + { + MetaMonitorTransform result; + + result = meta_monitor_transform_transform (tests[i].transform, + tests[i].other); + g_assert_cmpint (result, ==, tests[i].expect); + } +} + +void +init_monitor_transform_tests (void) +{ + g_test_add_func ("/util/monitor-transform/transform", test_transform); +} diff --git a/src/tests/monitor-transform-tests.h b/src/tests/monitor-transform-tests.h new file mode 100644 index 000000000..f6d019132 --- /dev/null +++ b/src/tests/monitor-transform-tests.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2018 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef MONITOR_TRANSFORM_UNIT_TESTS_H +#define MONITOR_TRANSFORM_UNIT_TESTS_H + +void init_monitor_transform_tests (void); + +#endif /* MONITOR_TRANSFORM_TESTS_H */ diff --git a/src/tests/monitor-unit-tests.c b/src/tests/monitor-unit-tests.c new file mode 100644 index 000000000..8e4166243 --- /dev/null +++ b/src/tests/monitor-unit-tests.c @@ -0,0 +1,6433 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include "tests/monitor-unit-tests.h" + +#include "backends/meta-backend-private.h" +#include "backends/meta-crtc.h" +#include "backends/meta-logical-monitor.h" +#include "backends/meta-monitor.h" +#include "backends/meta-monitor-config-migration.h" +#include "backends/meta-monitor-config-store.h" +#include "backends/meta-output.h" +#include "core/window-private.h" +#include "meta-backend-test.h" +#include "tests/meta-monitor-manager-test.h" +#include "tests/monitor-test-utils.h" +#include "tests/test-utils.h" +#include "x11/meta-x11-display-private.h" + +#define ALL_TRANSFORMS ((1 << (META_MONITOR_TRANSFORM_FLIPPED_270 + 1)) - 1) + +#define MAX_N_MODES 10 +#define MAX_N_OUTPUTS 10 +#define MAX_N_CRTCS 10 +#define MAX_N_MONITORS 10 +#define MAX_N_LOGICAL_MONITORS 10 + +/* + * The following structures are used to define test cases. + * + * Each test case consists of a test case setup and a test case expectaction. + * and a expected result, consisting + * of an array of monitors, logical monitors and a screen size. + * + * TEST CASE SETUP: + * + * A test case setup consists of an array of modes, an array of outputs and an + * array of CRTCs. + * + * A mode has a width and height in pixels, and a refresh rate in updates per + * second. + * + * An output has an array of available modes, and a preferred mode. Modes are + * defined as indices into the modes array of the test case setup. + * + * It also has CRTc and an array of possible CRTCs. Crtcs are defined as indices + * into the CRTC array. The CRTC value -1 means no CRTC. + * + * It also has various meta data, such as physical dimension, tile info and + * scale. + * + * A CRTC only has a current mode. A mode is defined as an index into the modes + * array. + * + * + * TEST CASE EXPECTS: + * + * A test case expects consists of an array of monitors, an array of logical + * monitors, a output and crtc count, and a screen width. + * + * A monitor represents a physical monitor (such as an external monitor, or a + * laptop panel etc). A monitor consists of an array of outputs, defined by + * indices into the setup output array, an array of monitor modes, and the + * current mode, defined by an index into the monitor modes array, and the + * physical dimensions. + * + * A logical monitor represents a region of the total screen area. It contains + * the expected layout and a scale. + */ + +typedef enum _MonitorTestFlag +{ + MONITOR_TEST_FLAG_NONE, + MONITOR_TEST_FLAG_NO_STORED +} MonitorTestFlag; + +typedef struct _MonitorTestCaseMode +{ + int width; + int height; + float refresh_rate; + MetaCrtcModeFlag flags; +} MonitorTestCaseMode; + +typedef struct _MonitorTestCaseOutput +{ + int crtc; + int modes[MAX_N_MODES]; + int n_modes; + int preferred_mode; + int possible_crtcs[MAX_N_CRTCS]; + int n_possible_crtcs; + int width_mm; + int height_mm; + MetaTileInfo tile_info; + float scale; + gboolean is_laptop_panel; + gboolean is_underscanning; + const char *serial; + MetaMonitorTransform panel_orientation_transform; +} MonitorTestCaseOutput; + +typedef struct _MonitorTestCaseCrtc +{ + int current_mode; +} MonitorTestCaseCrtc; + +typedef struct _MonitorTestCaseSetup +{ + MonitorTestCaseMode modes[MAX_N_MODES]; + int n_modes; + + MonitorTestCaseOutput outputs[MAX_N_OUTPUTS]; + int n_outputs; + + MonitorTestCaseCrtc crtcs[MAX_N_CRTCS]; + int n_crtcs; +} MonitorTestCaseSetup; + +typedef struct _MonitorTestCaseMonitorCrtcMode +{ + uint64_t output; + int crtc_mode; +} MetaTestCaseMonitorCrtcMode; + +typedef struct _MonitorTestCaseMonitorMode +{ + int width; + int height; + float refresh_rate; + MetaCrtcModeFlag flags; + MetaTestCaseMonitorCrtcMode crtc_modes[MAX_N_CRTCS]; +} MetaMonitorTestCaseMonitorMode; + +typedef struct _MonitorTestCaseMonitor +{ + uint64_t outputs[MAX_N_OUTPUTS]; + int n_outputs; + MetaMonitorTestCaseMonitorMode modes[MAX_N_MODES]; + int n_modes; + int current_mode; + int width_mm; + int height_mm; + gboolean is_underscanning; +} MonitorTestCaseMonitor; + +typedef struct _MonitorTestCaseLogicalMonitor +{ + MetaRectangle layout; + float scale; + int monitors[MAX_N_MONITORS]; + int n_monitors; + MetaMonitorTransform transform; +} MonitorTestCaseLogicalMonitor; + +typedef struct _MonitorTestCaseCrtcExpect +{ + MetaMonitorTransform transform; + int current_mode; + float x; + float y; +} MonitorTestCaseCrtcExpect; + +typedef struct _MonitorTestCaseExpect +{ + MonitorTestCaseMonitor monitors[MAX_N_MONITORS]; + int n_monitors; + MonitorTestCaseLogicalMonitor logical_monitors[MAX_N_LOGICAL_MONITORS]; + int n_logical_monitors; + int primary_logical_monitor; + int n_outputs; + MonitorTestCaseCrtcExpect crtcs[MAX_N_CRTCS]; + int n_crtcs; + int n_tiled_monitors; + int screen_width; + int screen_height; +} MonitorTestCaseExpect; + +typedef struct _MonitorTestCase +{ + MonitorTestCaseSetup setup; + MonitorTestCaseExpect expect; +} MonitorTestCase; + +static MonitorTestCase initial_test_case = { + .setup = { + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0 + } + }, + .n_modes = 1, + .outputs = { + { + .crtc = 0, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125 + }, + { + .crtc = 1, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 1 }, + .n_possible_crtcs = 1, + .width_mm = 220, + .height_mm = 124 + } + }, + .n_outputs = 2, + .crtcs = { + { + .current_mode = 0 + }, + { + .current_mode = 0 + } + }, + .n_crtcs = 2 + }, + + .expect = { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125 + }, + { + .outputs = { 1 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0, + .crtc_modes = { + { + .output = 1, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 220, + .height_mm = 124 + } + }, + .n_monitors = 2, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 1024, .height = 768 }, + .scale = 1 + }, + { + .monitors = { 1 }, + .n_monitors = 1, + .layout = { .x = 1024, .y = 0, .width = 1024, .height = 768 }, + .scale = 1 + } + }, + .n_logical_monitors = 2, + .primary_logical_monitor = 0, + .n_outputs = 2, + .crtcs = { + { + .current_mode = 0, + }, + { + .current_mode = 0, + .x = 1024, + } + }, + .n_crtcs = 2, + .screen_width = 1024 * 2, + .screen_height = 768 + } +}; + +static TestClient *wayland_monitor_test_client = NULL; +static TestClient *x11_monitor_test_client = NULL; + +#define WAYLAND_TEST_CLIENT_NAME "wayland_monitor_test_client" +#define WAYLAND_TEST_CLIENT_WINDOW "window1" +#define X11_TEST_CLIENT_NAME "x11_monitor_test_client" +#define X11_TEST_CLIENT_WINDOW "window1" + +static gboolean +monitor_tests_alarm_filter (MetaX11Display *x11_display, + XSyncAlarmNotifyEvent *event, + gpointer data) +{ + return test_client_alarm_filter (x11_display, event, x11_monitor_test_client); +} + +static void +create_monitor_test_clients (void) +{ + GError *error = NULL; + + test_wait_for_x11_display (); + + meta_x11_display_set_alarm_filter (meta_get_display ()->x11_display, + monitor_tests_alarm_filter, NULL); + + wayland_monitor_test_client = test_client_new (WAYLAND_TEST_CLIENT_NAME, + META_WINDOW_CLIENT_TYPE_WAYLAND, + &error); + if (!wayland_monitor_test_client) + g_error ("Failed to launch Wayland test client: %s", error->message); + + x11_monitor_test_client = test_client_new (X11_TEST_CLIENT_NAME, + META_WINDOW_CLIENT_TYPE_X11, + &error); + if (!x11_monitor_test_client) + g_error ("Failed to launch X11 test client: %s", error->message); + + if (!test_client_do (wayland_monitor_test_client, &error, + "create", WAYLAND_TEST_CLIENT_WINDOW, + NULL)) + g_error ("Failed to create Wayland window: %s", error->message); + + if (!test_client_do (x11_monitor_test_client, &error, + "create", X11_TEST_CLIENT_WINDOW, + NULL)) + g_error ("Failed to create X11 window: %s", error->message); + + if (!test_client_do (wayland_monitor_test_client, &error, + "show", WAYLAND_TEST_CLIENT_WINDOW, + NULL)) + g_error ("Failed to show the window: %s", error->message); + + if (!test_client_do (x11_monitor_test_client, &error, + "show", X11_TEST_CLIENT_WINDOW, + NULL)) + g_error ("Failed to show the window: %s", error->message); +} + +static void +check_test_client_state (TestClient *test_client) +{ + GError *error = NULL; + + if (!test_client_wait (test_client, &error)) + { + g_error ("Failed to sync test client '%s': %s", + test_client_get_id (test_client), error->message); + } +} + +static void +check_monitor_test_clients_state (void) +{ + check_test_client_state (wayland_monitor_test_client); + check_test_client_state (x11_monitor_test_client); +} + +static void +destroy_monitor_test_clients (void) +{ + GError *error = NULL; + + if (!test_client_quit (wayland_monitor_test_client, &error)) + g_error ("Failed to quit Wayland test client: %s", error->message); + + if (!test_client_quit (x11_monitor_test_client, &error)) + g_error ("Failed to quit X11 test client: %s", error->message); + + test_client_destroy (wayland_monitor_test_client); + test_client_destroy (x11_monitor_test_client); + + meta_x11_display_set_alarm_filter (meta_get_display ()->x11_display, + NULL, NULL); +} + +static MetaOutput * +output_from_winsys_id (MetaBackend *backend, + uint64_t winsys_id) +{ + MetaGpu *gpu = meta_backend_test_get_gpu (META_BACKEND_TEST (backend)); + GList *l; + + for (l = meta_gpu_get_outputs (gpu); l; l = l->next) + { + MetaOutput *output = l->data; + + if (output->winsys_id == winsys_id) + return output; + } + + return NULL; +} + +typedef struct _CheckMonitorModeData +{ + MetaBackend *backend; + MetaTestCaseMonitorCrtcMode *expect_crtc_mode_iter; +} CheckMonitorModeData; + +static gboolean +check_monitor_mode (MetaMonitor *monitor, + MetaMonitorMode *mode, + MetaMonitorCrtcMode *monitor_crtc_mode, + gpointer user_data, + GError **error) +{ + CheckMonitorModeData *data = user_data; + MetaBackend *backend = data->backend; + MetaOutput *output; + MetaCrtcMode *crtc_mode; + int expect_crtc_mode_index; + + output = output_from_winsys_id (backend, + data->expect_crtc_mode_iter->output); + g_assert (monitor_crtc_mode->output == output); + + expect_crtc_mode_index = data->expect_crtc_mode_iter->crtc_mode; + if (expect_crtc_mode_index == -1) + { + crtc_mode = NULL; + } + else + { + MetaGpu *gpu = meta_output_get_gpu (output); + + crtc_mode = g_list_nth_data (meta_gpu_get_modes (gpu), + expect_crtc_mode_index); + } + g_assert (monitor_crtc_mode->crtc_mode == crtc_mode); + + if (crtc_mode) + { + float refresh_rate; + MetaCrtcModeFlag flags; + + refresh_rate = meta_monitor_mode_get_refresh_rate (mode); + flags = meta_monitor_mode_get_flags (mode); + + g_assert_cmpfloat (refresh_rate, ==, crtc_mode->refresh_rate); + g_assert_cmpint (flags, ==, (crtc_mode->flags & HANDLED_CRTC_MODE_FLAGS)); + } + + data->expect_crtc_mode_iter++; + + return TRUE; +} + +static gboolean +check_current_monitor_mode (MetaMonitor *monitor, + MetaMonitorMode *mode, + MetaMonitorCrtcMode *monitor_crtc_mode, + gpointer user_data, + GError **error) +{ + CheckMonitorModeData *data = user_data; + MetaBackend *backend = data->backend; + MetaOutput *output; + MetaCrtc *crtc; + + output = output_from_winsys_id (backend, + data->expect_crtc_mode_iter->output); + crtc = meta_output_get_assigned_crtc (output); + + if (data->expect_crtc_mode_iter->crtc_mode == -1) + { + g_assert_null (crtc); + } + else + { + MetaCrtcConfig *crtc_config; + MetaLogicalMonitor *logical_monitor; + + g_assert_nonnull (crtc); + + crtc_config = crtc->config; + g_assert_nonnull (crtc_config); + + g_assert (monitor_crtc_mode->crtc_mode == crtc_config->mode); + + logical_monitor = meta_monitor_get_logical_monitor (monitor); + g_assert_nonnull (logical_monitor); + } + + + data->expect_crtc_mode_iter++; + + return TRUE; +} + +static MetaLogicalMonitor * +logical_monitor_from_layout (MetaMonitorManager *monitor_manager, + MetaRectangle *layout) +{ + GList *l; + + for (l = monitor_manager->logical_monitors; l; l = l->next) + { + MetaLogicalMonitor *logical_monitor = l->data; + + if (meta_rectangle_equal (layout, &logical_monitor->rect)) + return logical_monitor; + } + + return NULL; +} + +static void +check_logical_monitor (MonitorTestCase *test_case, + MetaMonitorManager *monitor_manager, + MonitorTestCaseLogicalMonitor *test_logical_monitor) +{ + MetaLogicalMonitor *logical_monitor; + MetaOutput *primary_output; + GList *monitors; + GList *l; + int i; + + logical_monitor = logical_monitor_from_layout (monitor_manager, + &test_logical_monitor->layout); + g_assert_nonnull (logical_monitor); + + g_assert_cmpint (logical_monitor->rect.x, + ==, + test_logical_monitor->layout.x); + g_assert_cmpint (logical_monitor->rect.y, + ==, + test_logical_monitor->layout.y); + g_assert_cmpint (logical_monitor->rect.width, + ==, + test_logical_monitor->layout.width); + g_assert_cmpint (logical_monitor->rect.height, + ==, + test_logical_monitor->layout.height); + g_assert_cmpfloat (logical_monitor->scale, + ==, + test_logical_monitor->scale); + g_assert_cmpuint (logical_monitor->transform, + ==, + test_logical_monitor->transform); + + if (logical_monitor == monitor_manager->primary_logical_monitor) + g_assert (meta_logical_monitor_is_primary (logical_monitor)); + + primary_output = NULL; + monitors = meta_logical_monitor_get_monitors (logical_monitor); + g_assert_cmpint ((int) g_list_length (monitors), + ==, + test_logical_monitor->n_monitors); + + for (i = 0; i < test_logical_monitor->n_monitors; i++) + { + MetaMonitor *monitor = + g_list_nth (monitor_manager->monitors, + test_logical_monitor->monitors[i])->data; + + g_assert_nonnull (g_list_find (monitors, monitor)); + } + + for (l = monitors; l; l = l->next) + { + MetaMonitor *monitor = l->data; + GList *outputs; + GList *l_output; + + outputs = meta_monitor_get_outputs (monitor); + for (l_output = outputs; l_output; l_output = l_output->next) + { + MetaOutput *output = l_output->data; + MetaCrtc *crtc; + + if (output->is_primary) + { + g_assert_null (primary_output); + primary_output = output; + } + + crtc = meta_output_get_assigned_crtc (output); + g_assert (!crtc || + meta_monitor_get_logical_monitor (monitor) == logical_monitor); + g_assert_cmpint (logical_monitor->is_presentation, + ==, + output->is_presentation); + } + } + + if (logical_monitor == monitor_manager->primary_logical_monitor) + g_assert_nonnull (primary_output); +} + +static void +check_monitor_configuration (MonitorTestCase *test_case) +{ + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaMonitorManagerTest *monitor_manager_test = + META_MONITOR_MANAGER_TEST (monitor_manager); + MetaGpu *gpu = meta_backend_test_get_gpu (META_BACKEND_TEST (backend)); + int tiled_monitor_count; + GList *monitors; + GList *crtcs; + int n_logical_monitors; + GList *l; + int i; + + g_assert_cmpint (monitor_manager->screen_width, + ==, + test_case->expect.screen_width); + g_assert_cmpint (monitor_manager->screen_height, + ==, + test_case->expect.screen_height); + g_assert_cmpint ((int) g_list_length (meta_gpu_get_outputs (gpu)), + ==, + test_case->expect.n_outputs); + g_assert_cmpint ((int) g_list_length (meta_gpu_get_crtcs (gpu)), + ==, + test_case->expect.n_crtcs); + + tiled_monitor_count = + meta_monitor_manager_test_get_tiled_monitor_count (monitor_manager_test); + g_assert_cmpint (tiled_monitor_count, + ==, + test_case->expect.n_tiled_monitors); + + monitors = meta_monitor_manager_get_monitors (monitor_manager); + g_assert_cmpint ((int) g_list_length (monitors), + ==, + test_case->expect.n_monitors); + for (l = monitors, i = 0; l; l = l->next, i++) + { + MetaMonitor *monitor = l->data; + GList *outputs; + GList *l_output; + int j; + int width_mm, height_mm; + GList *modes; + GList *l_mode; + MetaMonitorMode *current_mode; + int expected_current_mode_index; + MetaMonitorMode *expected_current_mode; + + outputs = meta_monitor_get_outputs (monitor); + + g_assert_cmpint ((int) g_list_length (outputs), + ==, + test_case->expect.monitors[i].n_outputs); + + for (l_output = outputs, j = 0; l_output; l_output = l_output->next, j++) + { + MetaOutput *output = l_output->data; + uint64_t winsys_id = test_case->expect.monitors[i].outputs[j]; + + g_assert (output == output_from_winsys_id (backend, winsys_id)); + g_assert_cmpint (test_case->expect.monitors[i].is_underscanning, + ==, + output->is_underscanning); + } + + meta_monitor_get_physical_dimensions (monitor, &width_mm, &height_mm); + g_assert_cmpint (width_mm, + ==, + test_case->expect.monitors[i].width_mm); + g_assert_cmpint (height_mm, + ==, + test_case->expect.monitors[i].height_mm); + + modes = meta_monitor_get_modes (monitor); + g_assert_cmpint (g_list_length (modes), + ==, + test_case->expect.monitors[i].n_modes); + + for (l_mode = modes, j = 0; l_mode; l_mode = l_mode->next, j++) + { + MetaMonitorMode *mode = l_mode->data; + int width; + int height; + float refresh_rate; + MetaCrtcModeFlag flags; + CheckMonitorModeData data; + + meta_monitor_mode_get_resolution (mode, &width, &height); + refresh_rate = meta_monitor_mode_get_refresh_rate (mode); + flags = meta_monitor_mode_get_flags (mode); + + g_assert_cmpint (width, + ==, + test_case->expect.monitors[i].modes[j].width); + g_assert_cmpint (height, + ==, + test_case->expect.monitors[i].modes[j].height); + g_assert_cmpfloat (refresh_rate, + ==, + test_case->expect.monitors[i].modes[j].refresh_rate); + g_assert_cmpint (flags, + ==, + test_case->expect.monitors[i].modes[j].flags); + + data = (CheckMonitorModeData) { + .backend = backend, + .expect_crtc_mode_iter = + test_case->expect.monitors[i].modes[j].crtc_modes + }; + meta_monitor_mode_foreach_output (monitor, mode, + check_monitor_mode, + &data, + NULL); + } + + current_mode = meta_monitor_get_current_mode (monitor); + expected_current_mode_index = test_case->expect.monitors[i].current_mode; + if (expected_current_mode_index == -1) + expected_current_mode = NULL; + else + expected_current_mode = g_list_nth (modes, + expected_current_mode_index)->data; + + g_assert (current_mode == expected_current_mode); + if (current_mode) + g_assert (meta_monitor_is_active (monitor)); + else + g_assert (!meta_monitor_is_active (monitor)); + + if (current_mode) + { + CheckMonitorModeData data; + + data = (CheckMonitorModeData) { + .backend = backend, + .expect_crtc_mode_iter = + test_case->expect.monitors[i].modes[expected_current_mode_index].crtc_modes + }; + meta_monitor_mode_foreach_output (monitor, expected_current_mode, + check_current_monitor_mode, + &data, + NULL); + } + + meta_monitor_derive_current_mode (monitor); + g_assert (current_mode == meta_monitor_get_current_mode (monitor)); + } + + n_logical_monitors = + meta_monitor_manager_get_num_logical_monitors (monitor_manager); + g_assert_cmpint (n_logical_monitors, + ==, + test_case->expect.n_logical_monitors); + + /* + * Check that we have a primary logical monitor (except for headless), + * and that the main output of the first monitor is the only output + * that is marked as primary (further below). Note: outputs being primary or + * not only matters on X11. + */ + if (test_case->expect.primary_logical_monitor == -1) + { + g_assert_null (monitor_manager->primary_logical_monitor); + g_assert_null (monitor_manager->logical_monitors); + } + else + { + MonitorTestCaseLogicalMonitor *test_logical_monitor = + &test_case->expect.logical_monitors[test_case->expect.primary_logical_monitor]; + MetaLogicalMonitor *logical_monitor; + + logical_monitor = + logical_monitor_from_layout (monitor_manager, + &test_logical_monitor->layout); + g_assert (logical_monitor == monitor_manager->primary_logical_monitor); + } + + for (i = 0; i < test_case->expect.n_logical_monitors; i++) + { + MonitorTestCaseLogicalMonitor *test_logical_monitor = + &test_case->expect.logical_monitors[i]; + + check_logical_monitor (test_case, monitor_manager, test_logical_monitor); + } + g_assert_cmpint (n_logical_monitors, ==, i); + + crtcs = meta_gpu_get_crtcs (gpu); + for (l = crtcs, i = 0; l; l = l->next, i++) + { + MetaCrtc *crtc = l->data; + MetaCrtcConfig *crtc_config = crtc->config; + + if (test_case->expect.crtcs[i].current_mode == -1) + { + g_assert_null (crtc_config); + } + else + { + MetaCrtcMode *expected_current_mode; + + g_assert_nonnull (crtc_config); + + expected_current_mode = + g_list_nth_data (meta_gpu_get_modes (gpu), + test_case->expect.crtcs[i].current_mode); + g_assert (crtc_config->mode == expected_current_mode); + + g_assert_cmpuint (crtc_config->transform, + ==, + test_case->expect.crtcs[i].transform); + + g_assert_cmpfloat_with_epsilon (crtc_config->layout.origin.x, + test_case->expect.crtcs[i].x, + FLT_EPSILON); + g_assert_cmpfloat_with_epsilon (crtc_config->layout.origin.y, + test_case->expect.crtcs[i].y, + FLT_EPSILON); + } + } + + check_monitor_test_clients_state (); +} + +static void +meta_output_test_destroy_notify (MetaOutput *output) +{ + g_clear_pointer (&output->driver_private, g_free); +} + +static MetaMonitorTestSetup * +create_monitor_test_setup (MonitorTestCase *test_case, + MonitorTestFlag flags) +{ + MetaMonitorTestSetup *test_setup; + int i; + int n_laptop_panels = 0; + int n_normal_panels = 0; + gboolean hotplug_mode_update; + + if (flags & MONITOR_TEST_FLAG_NO_STORED) + hotplug_mode_update = TRUE; + else + hotplug_mode_update = FALSE; + + test_setup = g_new0 (MetaMonitorTestSetup, 1); + + test_setup->modes = NULL; + for (i = 0; i < test_case->setup.n_modes; i++) + { + MetaCrtcMode *mode; + + mode = g_object_new (META_TYPE_CRTC_MODE, NULL); + mode->mode_id = i; + mode->width = test_case->setup.modes[i].width; + mode->height = test_case->setup.modes[i].height; + mode->refresh_rate = test_case->setup.modes[i].refresh_rate; + mode->flags = test_case->setup.modes[i].flags; + + test_setup->modes = g_list_append (test_setup->modes, mode); + } + + test_setup->crtcs = NULL; + for (i = 0; i < test_case->setup.n_crtcs; i++) + { + MetaCrtc *crtc; + + crtc = g_object_new (META_TYPE_CRTC, NULL); + crtc->crtc_id = i + 1; + crtc->all_transforms = ALL_TRANSFORMS; + + test_setup->crtcs = g_list_append (test_setup->crtcs, crtc); + } + + test_setup->outputs = NULL; + for (i = 0; i < test_case->setup.n_outputs; i++) + { + MetaOutput *output; + MetaOutputTest *output_test; + int crtc_index; + MetaCrtc *crtc; + int preferred_mode_index; + MetaCrtcMode *preferred_mode; + MetaCrtcMode **modes; + int n_modes; + int j; + MetaCrtc **possible_crtcs; + int n_possible_crtcs; + int scale; + gboolean is_laptop_panel; + const char *serial; + + crtc_index = test_case->setup.outputs[i].crtc; + if (crtc_index == -1) + crtc = NULL; + else + crtc = g_list_nth_data (test_setup->crtcs, crtc_index); + + preferred_mode_index = test_case->setup.outputs[i].preferred_mode; + if (preferred_mode_index == -1) + preferred_mode = NULL; + else + preferred_mode = g_list_nth_data (test_setup->modes, + preferred_mode_index); + + n_modes = test_case->setup.outputs[i].n_modes; + modes = g_new0 (MetaCrtcMode *, n_modes); + for (j = 0; j < n_modes; j++) + { + int mode_index; + + mode_index = test_case->setup.outputs[i].modes[j]; + modes[j] = g_list_nth_data (test_setup->modes, mode_index); + } + + n_possible_crtcs = test_case->setup.outputs[i].n_possible_crtcs; + possible_crtcs = g_new0 (MetaCrtc *, n_possible_crtcs); + for (j = 0; j < n_possible_crtcs; j++) + { + int possible_crtc_index; + + possible_crtc_index = test_case->setup.outputs[i].possible_crtcs[j]; + possible_crtcs[j] = g_list_nth_data (test_setup->crtcs, + possible_crtc_index); + } + + output_test = g_new0 (MetaOutputTest, 1); + + scale = test_case->setup.outputs[i].scale; + if (scale < 1) + scale = 1; + + *output_test = (MetaOutputTest) { + .scale = scale + }; + + is_laptop_panel = test_case->setup.outputs[i].is_laptop_panel; + + serial = test_case->setup.outputs[i].serial; + if (!serial) + serial = "0x123456"; + + output = g_object_new (META_TYPE_OUTPUT, NULL); + + if (crtc) + meta_output_assign_crtc (output, crtc); + output->winsys_id = i; + output->name = (is_laptop_panel ? g_strdup_printf ("eDP-%d", + ++n_laptop_panels) + : g_strdup_printf ("DP-%d", + ++n_normal_panels)); + output->vendor = g_strdup ("MetaProduct's Inc."); + output->product = g_strdup ("MetaMonitor"); + output->serial = g_strdup (serial); + output->suggested_x = -1; + output->suggested_y = -1; + output->hotplug_mode_update = hotplug_mode_update; + output->width_mm = test_case->setup.outputs[i].width_mm; + output->height_mm = test_case->setup.outputs[i].height_mm; + output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN; + output->preferred_mode = preferred_mode; + output->n_modes = n_modes; + output->modes = modes; + output->n_possible_crtcs = n_possible_crtcs; + output->possible_crtcs = possible_crtcs; + output->n_possible_clones = 0; + output->possible_clones = NULL; + output->backlight = -1; + output->connector_type = (is_laptop_panel ? META_CONNECTOR_TYPE_eDP + : META_CONNECTOR_TYPE_DisplayPort); + output->tile_info = test_case->setup.outputs[i].tile_info; + output->is_underscanning = test_case->setup.outputs[i].is_underscanning; + output->panel_orientation_transform = + test_case->setup.outputs[i].panel_orientation_transform; + output->driver_private = output_test; + output->driver_notify = (GDestroyNotify) meta_output_test_destroy_notify; + + test_setup->outputs = g_list_append (test_setup->outputs, output); + } + + return test_setup; +} + +static void +meta_test_monitor_initial_linear_config (void) +{ + check_monitor_configuration (&initial_test_case); +} + +static void +emulate_hotplug (MetaMonitorTestSetup *test_setup) +{ + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaMonitorManagerTest *monitor_manager_test = + META_MONITOR_MANAGER_TEST (monitor_manager); + + meta_monitor_manager_test_emulate_hotplug (monitor_manager_test, test_setup); + g_usleep (G_USEC_PER_SEC / 100); +} + +static void +meta_test_monitor_one_disconnected_linear_config (void) +{ + MonitorTestCase test_case = initial_test_case; + MetaMonitorTestSetup *test_setup; + + test_case.setup.n_outputs = 1; + + test_case.expect = (MonitorTestCaseExpect) { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125 + } + }, + .n_monitors = 1, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 1024, .height = 768 }, + .scale = 1 + }, + }, + .n_logical_monitors = 1, + .primary_logical_monitor = 0, + .n_outputs = 1, + .crtcs = { + { + .current_mode = 0, + }, + { + .current_mode = -1, + } + }, + .n_crtcs = 2, + .screen_width = 1024, + .screen_height = 768 + }; + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NO_STORED); + emulate_hotplug (test_setup); + check_monitor_configuration (&test_case); +} + +static void +meta_test_monitor_one_off_linear_config (void) +{ + MonitorTestCase test_case; + MetaMonitorTestSetup *test_setup; + MonitorTestCaseOutput outputs[] = { + { + .crtc = 0, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125 + }, + { + .crtc = -1, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 1 }, + .n_possible_crtcs = 1, + .width_mm = 224, + .height_mm = 126 + } + }; + + test_case = initial_test_case; + + memcpy (&test_case.setup.outputs, &outputs, sizeof (outputs)); + test_case.setup.n_outputs = G_N_ELEMENTS (outputs); + + test_case.setup.crtcs[1].current_mode = -1; + + test_case.expect = (MonitorTestCaseExpect) { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125 + }, + { + .outputs = { 1 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0, + .crtc_modes = { + { + .output = 1, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 224, + .height_mm = 126 + } + }, + .n_monitors = 2, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 1024, .height = 768 }, + .scale = 1 + }, + { + .monitors = { 1 }, + .n_monitors = 1, + .layout = { .x = 1024, .y = 0, .width = 1024, .height = 768 }, + .scale = 1 + }, + }, + .n_logical_monitors = 2, + .primary_logical_monitor = 0, + .n_outputs = 2, + .crtcs = { + { + .current_mode = 0, + }, + { + .current_mode = 0, + .x = 1024, + } + }, + .n_crtcs = 2, + .screen_width = 1024 * 2, + .screen_height = 768 + }; + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NO_STORED); + emulate_hotplug (test_setup); + check_monitor_configuration (&test_case); +} + +static void +meta_test_monitor_preferred_linear_config (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 800, + .height = 600, + .refresh_rate = 60.0 + }, + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0 + }, + { + .width = 1280, + .height = 720, + .refresh_rate = 60.0 + } + }, + .n_modes = 3, + .outputs = { + { + .crtc = -1, + .modes = { 0, 1, 2 }, + .n_modes = 3, + .preferred_mode = 1, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125 + } + }, + .n_outputs = 1, + .crtcs = { + { + .current_mode = -1 + } + }, + .n_crtcs = 1 + }, + + .expect = { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 800, + .height = 600, + .refresh_rate = 60.0, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0 + } + } + }, + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 1 + } + } + }, + { + .width = 1280, + .height = 720, + .refresh_rate = 60.0, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 2 + } + } + } + }, + .n_modes = 3, + .current_mode = 1, + .width_mm = 222, + .height_mm = 125 + } + }, + .n_monitors = 1, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 1024, .height = 768 }, + .scale = 1 + }, + }, + .n_logical_monitors = 1, + .primary_logical_monitor = 0, + .n_outputs = 1, + .crtcs = { + { + .current_mode = 1, + } + }, + .n_crtcs = 1, + .screen_width = 1024, + .screen_height = 768, + } + }; + MetaMonitorTestSetup *test_setup; + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NO_STORED); + emulate_hotplug (test_setup); + check_monitor_configuration (&test_case); +} + +static void +meta_test_monitor_tiled_linear_config (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 400, + .height = 600, + .refresh_rate = 60.0 + }, + }, + .n_modes = 1, + .outputs = { + { + .crtc = -1, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125, + .tile_info = { + .group_id = 1, + .max_h_tiles = 2, + .max_v_tiles = 1, + .loc_h_tile = 0, + .loc_v_tile = 0, + .tile_w = 400, + .tile_h = 600 + } + }, + { + .crtc = -1, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 1 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125, + .tile_info = { + .group_id = 1, + .max_h_tiles = 2, + .max_v_tiles = 1, + .loc_h_tile = 1, + .loc_v_tile = 0, + .tile_w = 400, + .tile_h = 600 + } + } + }, + .n_outputs = 2, + .crtcs = { + { + .current_mode = -1 + }, + { + .current_mode = -1 + } + }, + .n_crtcs = 2 + }, + + .expect = { + .monitors = { + { + .outputs = { 0, 1 }, + .n_outputs = 2, + .modes = { + { + .width = 800, + .height = 600, + .refresh_rate = 60.0, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0 + }, + { + .output = 1, + .crtc_mode = 0, + } + } + }, + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125, + } + }, + .n_monitors = 1, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 800, .height = 600 }, + .scale = 1 + }, + }, + .n_logical_monitors = 1, + .primary_logical_monitor = 0, + .n_outputs = 2, + .crtcs = { + { + .current_mode = 0, + }, + { + .current_mode = 0, + .x = 400, + .y = 0 + } + }, + .n_crtcs = 2, + .n_tiled_monitors = 1, + .screen_width = 800, + .screen_height = 600, + } + }; + MetaMonitorTestSetup *test_setup; + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NO_STORED); + emulate_hotplug (test_setup); + check_monitor_configuration (&test_case); +} + +static void +meta_test_monitor_tiled_non_preferred_linear_config (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 640, + .height = 480, + .refresh_rate = 60.0 + }, + { + .width = 800, + .height = 600, + .refresh_rate = 60.0 + }, + { + .width = 512, + .height = 768, + .refresh_rate = 120.0 + }, + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0 + }, + }, + .n_modes = 4, + .outputs = { + { + .crtc = -1, + .modes = { 0, 2 }, + .n_modes = 2, + .preferred_mode = 1, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125, + .tile_info = { + .group_id = 1, + .max_h_tiles = 2, + .max_v_tiles = 1, + .loc_h_tile = 0, + .loc_v_tile = 0, + .tile_w = 512, + .tile_h = 768 + } + }, + { + .crtc = -1, + .modes = { 1, 2, 3 }, + .n_modes = 3, + .preferred_mode = 0, + .possible_crtcs = { 1 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125, + .tile_info = { + .group_id = 1, + .max_h_tiles = 2, + .max_v_tiles = 1, + .loc_h_tile = 1, + .loc_v_tile = 0, + .tile_w = 512, + .tile_h = 768 + } + } + }, + .n_outputs = 2, + .crtcs = { + { + .current_mode = -1 + }, + { + .current_mode = -1 + } + }, + .n_crtcs = 2 + }, + + .expect = { + .monitors = { + { + .outputs = { 0, 1 }, + .n_outputs = 2, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 120.0, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 2 + }, + { + .output = 1, + .crtc_mode = 2, + } + } + }, + { + .width = 800, + .height = 600, + .refresh_rate = 60.0, + .crtc_modes = { + { + .output = 0, + .crtc_mode = -1 + }, + { + .output = 1, + .crtc_mode = 1, + } + } + }, + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0, + .crtc_modes = { + { + .output = 0, + .crtc_mode = -1 + }, + { + .output = 1, + .crtc_mode = 3, + } + } + }, + }, + .n_modes = 3, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125, + } + }, + .n_monitors = 1, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 1024, .height = 768 }, + .scale = 1 + }, + }, + .n_logical_monitors = 1, + .primary_logical_monitor = 0, + .n_outputs = 2, + .crtcs = { + { + .current_mode = 2, + }, + { + .current_mode = 2, + .x = 512 + } + }, + .n_crtcs = 2, + .n_tiled_monitors = 1, + .screen_width = 1024, + .screen_height = 768, + } + }; + MetaMonitorTestSetup *test_setup; + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NO_STORED); + emulate_hotplug (test_setup); + check_monitor_configuration (&test_case); +} + +static void +meta_test_monitor_tiled_non_main_origin_linear_config (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 400, + .height = 600, + .refresh_rate = 60.0 + }, + { + .width = 800, + .height = 600, + .refresh_rate = 30.0 + }, + }, + .n_modes = 2, + .outputs = { + { + .crtc = -1, + .modes = { 0, 1 }, + .n_modes = 2, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125, + .tile_info = { + .group_id = 1, + .max_h_tiles = 2, + .max_v_tiles = 1, + .loc_h_tile = 1, + .loc_v_tile = 0, + .tile_w = 400, + .tile_h = 600 + } + }, + { + .crtc = -1, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 1 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125, + .tile_info = { + .group_id = 1, + .max_h_tiles = 2, + .max_v_tiles = 1, + .loc_h_tile = 0, + .loc_v_tile = 0, + .tile_w = 400, + .tile_h = 600 + } + } + }, + .n_outputs = 2, + .crtcs = { + { + .current_mode = -1 + }, + { + .current_mode = -1 + } + }, + .n_crtcs = 2 + }, + + .expect = { + .monitors = { + { + .outputs = { 0, 1 }, + .n_outputs = 2, + .modes = { + { + .width = 800, + .height = 600, + .refresh_rate = 60.0, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0, + }, + { + .output = 1, + .crtc_mode = 0, + } + } + }, + { + .width = 800, + .height = 600, + .refresh_rate = 30.0, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 1 + }, + { + .output = 1, + .crtc_mode = -1, + } + } + }, + }, + .n_modes = 2, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125, + } + }, + .n_monitors = 1, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 800, .height = 600 }, + .scale = 1 + }, + }, + .n_logical_monitors = 1, + .primary_logical_monitor = 0, + .n_outputs = 2, + .crtcs = { + { + .current_mode = 0, + .x = 400, + .y = 0 + }, + { + .current_mode = 0, + } + }, + .n_crtcs = 2, + .n_tiled_monitors = 1, + .screen_width = 800, + .screen_height = 600, + } + }; + MetaMonitorTestSetup *test_setup; + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NO_STORED); + emulate_hotplug (test_setup); + check_monitor_configuration (&test_case); +} + +static void +meta_test_monitor_hidpi_linear_config (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 1280, + .height = 720, + .refresh_rate = 60.0 + }, + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0 + } + }, + .n_modes = 2, + .outputs = { + { + .crtc = 0, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + /* These will result in DPI of about 216" */ + .width_mm = 150, + .height_mm = 85, + .scale = 2, + }, + { + .crtc = 1, + .modes = { 1 }, + .n_modes = 1, + .preferred_mode = 1, + .possible_crtcs = { 1 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125, + .scale = 1, + } + }, + .n_outputs = 2, + .crtcs = { + { + .current_mode = -1 + }, + { + .current_mode = -1 + } + }, + .n_crtcs = 2 + }, + + .expect = { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 1280, + .height = 720, + .refresh_rate = 60.0, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0 + } + } + }, + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 150, + .height_mm = 85 + }, + { + .outputs = { 1 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0, + .crtc_modes = { + { + .output = 1, + .crtc_mode = 1 + } + } + }, + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125 + } + }, + .n_monitors = 2, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 640, .height = 360 }, + .scale = 2 + }, + { + .monitors = { 1 }, + .n_monitors = 1, + .layout = { .x = 640, .y = 0, .width = 1024, .height = 768 }, + .scale = 1 + } + }, + .n_logical_monitors = 2, + .primary_logical_monitor = 0, + .n_outputs = 2, + .crtcs = { + { + .current_mode = 0, + }, + { + .current_mode = 1, + .x = 640, + } + }, + .n_crtcs = 2, + .screen_width = 640 + 1024, + .screen_height = 768 + } + }; + MetaMonitorTestSetup *test_setup; + + if (!meta_is_stage_views_enabled ()) + { + g_test_skip ("Not using stage views"); + return; + } + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NO_STORED); + emulate_hotplug (test_setup); + check_monitor_configuration (&test_case); +} + +static void +set_suggested_output_position (MetaOutput *output, + int x, + int y) +{ + output->suggested_x = x; + output->suggested_y = y; +} + +static void +meta_test_monitor_suggested_config (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 800, + .height = 600, + .refresh_rate = 60.0 + }, + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0 + } + }, + .n_modes = 2, + .outputs = { + { + .crtc = 0, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125 + }, + { + .crtc = 1, + .modes = { 1 }, + .n_modes = 1, + .preferred_mode = 1, + .possible_crtcs = { 1 }, + .n_possible_crtcs = 1, + .width_mm = 220, + .height_mm = 124 + } + }, + .n_outputs = 2, + .crtcs = { + { + .current_mode = -1 + }, + { + .current_mode = -1 + } + }, + .n_crtcs = 2 + }, + + .expect = { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 800, + .height = 600, + .refresh_rate = 60.0, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125 + }, + { + .outputs = { 1 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0, + .crtc_modes = { + { + .output = 1, + .crtc_mode = 1 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 220, + .height_mm = 124 + } + }, + .n_monitors = 2, + /* + * Logical monitors expectations altered to correspond to the + * "suggested_x/y" changed further below. + */ + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 1024, .y = 758, .width = 800, .height = 600 }, + .scale = 1 + }, + { + .monitors = { 1 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 1024, .height = 768 }, + .scale = 1 + } + }, + .n_logical_monitors = 2, + .primary_logical_monitor = 1, + .n_outputs = 2, + .crtcs = { + { + .current_mode = 0, + .x = 1024, + .y = 758, + }, + { + .current_mode = 1, + } + }, + .n_crtcs = 2, + .n_tiled_monitors = 0, + .screen_width = 1024 + 800, + .screen_height = 1358 + } + }; + MetaMonitorTestSetup *test_setup; + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NO_STORED); + + set_suggested_output_position (g_list_nth_data (test_setup->outputs, 0), + 1024, 758); + set_suggested_output_position (g_list_nth_data (test_setup->outputs, 1), + 0, 0); + + emulate_hotplug (test_setup); + check_monitor_configuration (&test_case); +} + +static void +meta_test_monitor_limited_crtcs (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0 + } + }, + .n_modes = 1, + .outputs = { + { + .crtc = -1, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125 + }, + { + .crtc = -1, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 220, + .height_mm = 124 + } + }, + .n_outputs = 2, + .crtcs = { + { + .current_mode = 0 + } + }, + .n_crtcs = 1 + }, + + .expect = { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125 + }, + { + .outputs = { 1 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0, + .crtc_modes = { + { + .output = 1, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = -1, + .width_mm = 220, + .height_mm = 124 + } + }, + .n_monitors = 2, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 1024, .height = 768 }, + .scale = 1 + }, + }, + .n_logical_monitors = 1, + .primary_logical_monitor = 0, + .n_outputs = 2, + .crtcs = { + { + .current_mode = 0, + } + }, + .n_crtcs = 1, + .n_tiled_monitors = 0, + .screen_width = 1024, + .screen_height = 768 + } + }; + MetaMonitorTestSetup *test_setup; + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NO_STORED); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, + "Failed to use linear *"); + + emulate_hotplug (test_setup); + g_test_assert_expected_messages (); + + check_monitor_configuration (&test_case); +} + +static void +meta_test_monitor_lid_switch_config (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0 + } + }, + .n_modes = 1, + .outputs = { + { + .crtc = 0, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125, + .is_laptop_panel = TRUE + }, + { + .crtc = 1, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 1 }, + .n_possible_crtcs = 1, + .width_mm = 220, + .height_mm = 124 + } + }, + .n_outputs = 2, + .crtcs = { + { + .current_mode = 0 + }, + { + .current_mode = 0 + } + }, + .n_crtcs = 2 + }, + + .expect = { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125 + }, + { + .outputs = { 1 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0, + .crtc_modes = { + { + .output = 1, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 220, + .height_mm = 124 + } + }, + .n_monitors = 2, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 1024, .height = 768 }, + .scale = 1 + }, + { + .monitors = { 1 }, + .n_monitors = 1, + .layout = { .x = 1024, .y = 0, .width = 1024, .height = 768 }, + .scale = 1 + } + }, + .n_logical_monitors = 2, + .primary_logical_monitor = 0, + .n_outputs = 2, + .crtcs = { + { + .current_mode = 0, + }, + { + .current_mode = 0, + .x = 1024, + } + }, + .n_crtcs = 2, + .n_tiled_monitors = 0, + .screen_width = 1024 * 2, + .screen_height = 768 + } + }; + MetaMonitorTestSetup *test_setup; + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NO_STORED); + emulate_hotplug (test_setup); + check_monitor_configuration (&test_case); + + meta_backend_test_set_is_lid_closed (META_BACKEND_TEST (backend), TRUE); + meta_monitor_manager_lid_is_closed_changed (monitor_manager); + + test_case.expect.logical_monitors[0] = (MonitorTestCaseLogicalMonitor) { + .monitors = { 1 }, + .n_monitors = 1, + .layout = {.x = 0, .y = 0, .width = 1024, .height = 768 }, + .scale = 1 + }; + test_case.expect.n_logical_monitors = 1; + test_case.expect.screen_width = 1024; + test_case.expect.monitors[0].current_mode = -1; + test_case.expect.crtcs[0].current_mode = -1; + test_case.expect.crtcs[1].x = 0; + + check_monitor_configuration (&test_case); + + meta_backend_test_set_is_lid_closed (META_BACKEND_TEST (backend), FALSE); + meta_monitor_manager_lid_is_closed_changed (monitor_manager); + + test_case.expect.logical_monitors[0] = (MonitorTestCaseLogicalMonitor) { + .monitors = { 0 }, + .n_monitors = 1, + .layout = {.x = 0, .y = 0, .width = 1024, .height = 768 }, + .scale = 1 + }; + test_case.expect.n_logical_monitors = 2; + test_case.expect.screen_width = 1024 * 2; + test_case.expect.monitors[0].current_mode = 0; + test_case.expect.primary_logical_monitor = 0; + + test_case.expect.crtcs[0].current_mode = 0; + test_case.expect.crtcs[1].current_mode = 0; + test_case.expect.crtcs[1].x = 1024; + + check_monitor_configuration (&test_case); +} + +static void +meta_test_monitor_lid_opened_config (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0 + } + }, + .n_modes = 1, + .outputs = { + { + .crtc = 0, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125, + .is_laptop_panel = TRUE + }, + { + .crtc = 1, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 1 }, + .n_possible_crtcs = 1, + .width_mm = 220, + .height_mm = 124 + } + }, + .n_outputs = 2, + .crtcs = { + { + .current_mode = 0 + }, + { + .current_mode = 0 + } + }, + .n_crtcs = 2 + }, + + .expect = { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = -1, + .width_mm = 222, + .height_mm = 125 + }, + { + .outputs = { 1 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0, + .crtc_modes = { + { + .output = 1, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 220, + .height_mm = 124 + } + }, + .n_monitors = 2, + .logical_monitors = { + { + .monitors = { 1 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 1024, .height = 768 }, + .scale = 1 + }, + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 1024, .y = 0, .width = 1024, .height = 768 }, + .scale = 1 + } + }, + .n_logical_monitors = 1, /* Second one checked after lid opened. */ + .primary_logical_monitor = 0, + .n_outputs = 2, + .crtcs = { + { + .current_mode = -1, + }, + { + .current_mode = 0, + } + }, + .n_crtcs = 2, + .n_tiled_monitors = 0, + .screen_width = 1024, + .screen_height = 768 + } + }; + MetaMonitorTestSetup *test_setup; + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NO_STORED); + meta_backend_test_set_is_lid_closed (META_BACKEND_TEST (backend), TRUE); + + emulate_hotplug (test_setup); + check_monitor_configuration (&test_case); + + meta_backend_test_set_is_lid_closed (META_BACKEND_TEST (backend), FALSE); + meta_monitor_manager_lid_is_closed_changed (monitor_manager); + + test_case.expect.n_logical_monitors = 2; + test_case.expect.screen_width = 1024 * 2; + test_case.expect.monitors[0].current_mode = 0; + test_case.expect.crtcs[0].current_mode = 0; + test_case.expect.crtcs[0].x = 1024; + test_case.expect.crtcs[1].current_mode = 0; + test_case.expect.crtcs[1].x = 0; + + check_monitor_configuration (&test_case); +} + +static void +meta_test_monitor_lid_closed_no_external (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0 + } + }, + .n_modes = 1, + .outputs = { + { + .crtc = 0, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125, + .is_laptop_panel = TRUE + } + }, + .n_outputs = 1, + .crtcs = { + { + .current_mode = 0 + } + }, + .n_crtcs = 1 + }, + + .expect = { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125 + } + }, + .n_monitors = 1, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 1024, .height = 768 }, + .scale = 1 + } + }, + .n_logical_monitors = 1, + .primary_logical_monitor = 0, + .n_outputs = 1, + .crtcs = { + { + .current_mode = 0, + }, + }, + .n_crtcs = 1, + .n_tiled_monitors = 0, + .screen_width = 1024, + .screen_height = 768 + } + }; + MetaMonitorTestSetup *test_setup; + MetaBackend *backend = meta_get_backend (); + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NO_STORED); + meta_backend_test_set_is_lid_closed (META_BACKEND_TEST (backend), TRUE); + + emulate_hotplug (test_setup); + check_monitor_configuration (&test_case); +} + +static void +meta_test_monitor_lid_closed_with_hotplugged_external (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0 + } + }, + .n_modes = 1, + .outputs = { + { + .crtc = -1, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125, + .is_laptop_panel = TRUE + }, + { + .crtc = -1, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 1 }, + .n_possible_crtcs = 1, + .width_mm = 220, + .height_mm = 124 + } + }, + .n_outputs = 1, /* Second is hotplugged later */ + .crtcs = { + { + .current_mode = -1 + }, + { + .current_mode = -1 + } + }, + .n_crtcs = 2 + }, + + .expect = { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125 + }, + { + .outputs = { 1 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0, + .crtc_modes = { + { + .output = 1, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 220, + .height_mm = 124 + } + }, + .n_monitors = 1, /* Second is hotplugged later */ + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 1024, .height = 768 }, + .scale = 1 + }, + { + .monitors = { 1 }, + .n_monitors = 1, + .layout = { .x = 1024, .y = 0, .width = 1024, .height = 768 }, + .scale = 1 + } + }, + .n_logical_monitors = 1, /* Second is hotplugged later */ + .primary_logical_monitor = 0, + .n_outputs = 1, + .crtcs = { + { + .current_mode = 0, + }, + { + .current_mode = -1, + } + }, + .n_crtcs = 2, + .n_tiled_monitors = 0, + .screen_width = 1024, + .screen_height = 768 + } + }; + MetaMonitorTestSetup *test_setup; + MetaBackend *backend = meta_get_backend (); + + /* + * The first part of this test emulate the following: + * 1) Start with the lid open + * 2) Connect external monitor + * 3) Close lid + */ + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NO_STORED); + meta_backend_test_set_is_lid_closed (META_BACKEND_TEST (backend), FALSE); + + emulate_hotplug (test_setup); + check_monitor_configuration (&test_case); + + /* External monitor connected */ + + test_case.setup.n_outputs = 2; + test_case.expect.n_outputs = 2; + test_case.expect.n_monitors = 2; + test_case.expect.n_logical_monitors = 2; + test_case.expect.crtcs[1].current_mode = 0; + test_case.expect.crtcs[1].x = 1024; + test_case.expect.screen_width = 1024 * 2; + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NO_STORED); + emulate_hotplug (test_setup); + check_monitor_configuration (&test_case); + + /* Lid closed */ + + test_case.expect.monitors[0].current_mode = -1; + test_case.expect.logical_monitors[0].monitors[0] = 1, + test_case.expect.n_logical_monitors = 1; + test_case.expect.crtcs[0].current_mode = -1; + test_case.expect.crtcs[1].x = 0; + test_case.expect.screen_width = 1024; + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NO_STORED); + meta_backend_test_set_is_lid_closed (META_BACKEND_TEST (backend), TRUE); + emulate_hotplug (test_setup); + check_monitor_configuration (&test_case); + + /* + * The second part of this test emulate the following: + * 1) Open lid + * 2) Disconnect external monitor + * 3) Close lid + * 4) Open lid + */ + + /* Lid opened */ + + test_case.expect.monitors[0].current_mode = 0; + test_case.expect.logical_monitors[0].monitors[0] = 0, + test_case.expect.logical_monitors[1].monitors[0] = 1, + test_case.expect.n_logical_monitors = 2; + test_case.expect.crtcs[0].current_mode = 0; + test_case.expect.crtcs[1].x = 1024; + test_case.expect.screen_width = 1024 * 2; + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NO_STORED); + meta_backend_test_set_is_lid_closed (META_BACKEND_TEST (backend), FALSE); + emulate_hotplug (test_setup); + check_monitor_configuration (&test_case); + + /* External monitor disconnected */ + + test_case.setup.n_outputs = 1; + test_case.expect.n_outputs = 1; + test_case.expect.n_monitors = 1; + test_case.expect.n_logical_monitors = 1; + test_case.expect.crtcs[1].current_mode = -1; + test_case.expect.screen_width = 1024; + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NO_STORED); + emulate_hotplug (test_setup); + check_monitor_configuration (&test_case); + + /* Lid closed */ + + test_case.expect.logical_monitors[0].monitors[0] = 0, + test_case.expect.n_logical_monitors = 1; + test_case.expect.screen_width = 1024; + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NO_STORED); + meta_backend_test_set_is_lid_closed (META_BACKEND_TEST (backend), TRUE); + emulate_hotplug (test_setup); + check_monitor_configuration (&test_case); + + /* Lid opened */ + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NO_STORED); + meta_backend_test_set_is_lid_closed (META_BACKEND_TEST (backend), FALSE); + emulate_hotplug (test_setup); + check_monitor_configuration (&test_case); +} + +static void +meta_test_monitor_lid_scaled_closed_opened (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 1920, + .height = 1080, + .refresh_rate = 60.000495910644531 + } + }, + .n_modes = 1, + .outputs = { + { + .crtc = 0, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125, + .is_laptop_panel = TRUE + }, + }, + .n_outputs = 1, + .crtcs = { + { + .current_mode = 0 + }, + }, + .n_crtcs = 1 + }, + + .expect = { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 1920, + .height = 1080, + .refresh_rate = 60.000495910644531, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125, + } + }, + .n_monitors = 1, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 960, .height = 540 }, + .scale = 2 + } + }, + .n_logical_monitors = 1, + .primary_logical_monitor = 0, + .n_outputs = 1, + .crtcs = { + { + .current_mode = 0, + } + }, + .n_crtcs = 1, + .n_tiled_monitors = 0, + .screen_width = 960, + .screen_height = 540 + } + }; + MetaMonitorTestSetup *test_setup; + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + + if (!meta_is_stage_views_enabled ()) + { + g_test_skip ("Not using stage views"); + return; + } + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NONE); + set_custom_monitor_config ("lid-scale.xml"); + emulate_hotplug (test_setup); + check_monitor_configuration (&test_case); + + meta_backend_test_set_is_lid_closed (META_BACKEND_TEST (backend), TRUE); + meta_monitor_manager_lid_is_closed_changed (monitor_manager); + + check_monitor_configuration (&test_case); + + meta_backend_test_set_is_lid_closed (META_BACKEND_TEST (backend), FALSE); + meta_monitor_manager_lid_is_closed_changed (monitor_manager); + + check_monitor_configuration (&test_case); +} + +static void +meta_test_monitor_no_outputs (void) +{ + MonitorTestCase test_case = { + .setup = { + .n_modes = 0, + .n_outputs = 0, + .n_crtcs = 0 + }, + + .expect = { + .n_monitors = 0, + .n_logical_monitors = 0, + .primary_logical_monitor = -1, + .n_outputs = 0, + .n_crtcs = 0, + .n_tiled_monitors = 0, + .screen_width = META_MONITOR_MANAGER_MIN_SCREEN_WIDTH, + .screen_height = META_MONITOR_MANAGER_MIN_SCREEN_HEIGHT + } + }; + MetaMonitorTestSetup *test_setup; + GError *error = NULL; + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NO_STORED); + + emulate_hotplug (test_setup); + check_monitor_configuration (&test_case); + + if (!test_client_do (x11_monitor_test_client, &error, + "resize", X11_TEST_CLIENT_WINDOW, + "123", "210", + NULL)) + g_error ("Failed to resize X11 window: %s", error->message); + + if (!test_client_do (wayland_monitor_test_client, &error, + "resize", WAYLAND_TEST_CLIENT_WINDOW, + "123", "210", + NULL)) + g_error ("Failed to resize Wayland window: %s", error->message); + + check_monitor_test_clients_state (); + + /* Also check that we handle going headless -> headless */ + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NO_STORED); + + emulate_hotplug (test_setup); + check_monitor_configuration (&test_case); +} + +static void +meta_test_monitor_underscanning_config (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0 + } + }, + .n_modes = 1, + .outputs = { + { + .crtc = 0, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125, + .is_underscanning = TRUE, + } + }, + .n_outputs = 1, + .crtcs = { + { + .current_mode = 0 + } + }, + .n_crtcs = 1 + }, + + .expect = { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125, + .is_underscanning = TRUE, + } + }, + .n_monitors = 1, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 1024, .height = 768 }, + .scale = 1 + } + }, + .n_logical_monitors = 1, + .primary_logical_monitor = 0, + .n_outputs = 1, + .crtcs = { + { + .current_mode = 0, + } + }, + .n_crtcs = 1, + .screen_width = 1024, + .screen_height = 768 + } + }; + MetaMonitorTestSetup *test_setup; + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NO_STORED); + emulate_hotplug (test_setup); + check_monitor_configuration (&test_case); +} + +static void +meta_test_monitor_preferred_non_first_mode (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 800, + .height = 600, + .refresh_rate = 60.0, + .flags = META_CRTC_MODE_FLAG_NHSYNC, + }, + { + .width = 800, + .height = 600, + .refresh_rate = 60.0, + .flags = META_CRTC_MODE_FLAG_PHSYNC, + }, + }, + .n_modes = 2, + .outputs = { + { + .crtc = -1, + .modes = { 0, 1 }, + .n_modes = 2, + .preferred_mode = 1, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125 + } + }, + .n_outputs = 1, + .crtcs = { + { + .current_mode = -1 + } + }, + .n_crtcs = 1 + }, + + .expect = { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 800, + .height = 600, + .refresh_rate = 60.0, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 1 + } + } + }, + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125 + } + }, + .n_monitors = 1, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 800, .height = 600 }, + .scale = 1 + }, + }, + .n_logical_monitors = 1, + .primary_logical_monitor = 0, + .n_outputs = 1, + .crtcs = { + { + .current_mode = 1, + } + }, + .n_crtcs = 1, + .screen_width = 800, + .screen_height = 600, + } + }; + MetaMonitorTestSetup *test_setup; + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NO_STORED); + emulate_hotplug (test_setup); + check_monitor_configuration (&test_case); +} + +static void +meta_test_monitor_non_upright_panel (void) +{ + MonitorTestCase test_case = initial_test_case; + MetaMonitorTestSetup *test_setup; + + test_case.setup.modes[1] = (MonitorTestCaseMode) { + .width = 768, + .height = 1024, + .refresh_rate = 60.0, + }; + test_case.setup.n_modes = 2; + test_case.setup.outputs[0].modes[0] = 1; + test_case.setup.outputs[0].preferred_mode = 1; + test_case.setup.outputs[0].panel_orientation_transform = + META_MONITOR_TRANSFORM_90; + /* + * Note we do not swap outputs[0].width_mm and height_mm, because these get + * swapped for rotated panels inside the xrandr / kms code and we directly + * create a dummy output here, skipping this code. + */ + test_case.setup.crtcs[0].current_mode = 1; + + test_case.expect.monitors[0].modes[0].crtc_modes[0].crtc_mode = 1; + test_case.expect.crtcs[0].current_mode = 1; + test_case.expect.crtcs[0].transform = META_MONITOR_TRANSFORM_90; + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NO_STORED); + emulate_hotplug (test_setup); + check_monitor_configuration (&test_case); +} + +static void +meta_test_monitor_custom_vertical_config (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531 + }, + { + .width = 800, + .height = 600, + .refresh_rate = 60.000495910644531 + } + }, + .n_modes = 2, + .outputs = { + { + .crtc = 0, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125 + }, + { + .crtc = 1, + .modes = { 1 }, + .n_modes = 1, + .preferred_mode = 1, + .possible_crtcs = { 1 }, + .n_possible_crtcs = 1, + .width_mm = 220, + .height_mm = 124 + } + }, + .n_outputs = 2, + .crtcs = { + { + .current_mode = 0 + }, + { + .current_mode = 0 + } + }, + .n_crtcs = 2 + }, + + .expect = { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125 + }, + { + .outputs = { 1 }, + .n_outputs = 1, + .modes = { + { + .width = 800, + .height = 600, + .refresh_rate = 60.000495910644531, + .crtc_modes = { + { + .output = 1, + .crtc_mode = 1 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 220, + .height_mm = 124 + } + }, + .n_monitors = 2, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 1024, .height = 768 }, + .scale = 1 + }, + { + .monitors = { 1 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 768, .width = 800, .height = 600 }, + .scale = 1 + } + }, + .n_logical_monitors = 2, + .primary_logical_monitor = 0, + .n_outputs = 2, + .crtcs = { + { + .current_mode = 0, + }, + { + .current_mode = 1, + .y = 768, + } + }, + .n_crtcs = 2, + .n_tiled_monitors = 0, + .screen_width = 1024, + .screen_height = 768 + 600 + } + }; + MetaMonitorTestSetup *test_setup; + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NONE); + set_custom_monitor_config ("vertical.xml"); + emulate_hotplug (test_setup); + + check_monitor_configuration (&test_case); +} + +static void +meta_test_monitor_custom_primary_config (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531 + }, + { + .width = 800, + .height = 600, + .refresh_rate = 60.000495910644531 + } + }, + .n_modes = 2, + .outputs = { + { + .crtc = 0, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125 + }, + { + .crtc = 1, + .modes = { 1 }, + .n_modes = 1, + .preferred_mode = 1, + .possible_crtcs = { 1 }, + .n_possible_crtcs = 1, + .width_mm = 220, + .height_mm = 124 + } + }, + .n_outputs = 2, + .crtcs = { + { + .current_mode = 0 + }, + { + .current_mode = 0 + } + }, + .n_crtcs = 2 + }, + + .expect = { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125 + }, + { + .outputs = { 1 }, + .n_outputs = 1, + .modes = { + { + .width = 800, + .height = 600, + .refresh_rate = 60.000495910644531, + .crtc_modes = { + { + .output = 1, + .crtc_mode = 1 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 220, + .height_mm = 124 + } + }, + .n_monitors = 2, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 1024, .height = 768 }, + .scale = 1 + }, + { + .monitors = { 1 }, + .n_monitors = 1, + .layout = { .x = 1024, .y = 0, .width = 800, .height = 600 }, + .scale = 1 + } + }, + .n_logical_monitors = 2, + .primary_logical_monitor = 1, + .n_outputs = 2, + .crtcs = { + { + .current_mode = 0, + }, + { + .current_mode = 1, + .x = 1024, + } + }, + .n_crtcs = 2, + .n_tiled_monitors = 0, + .screen_width = 1024 + 800, + .screen_height = 768 + } + }; + MetaMonitorTestSetup *test_setup; + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NONE); + set_custom_monitor_config ("primary.xml"); + emulate_hotplug (test_setup); + + check_monitor_configuration (&test_case); +} + +static void +meta_test_monitor_custom_underscanning_config (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531 + } + }, + .n_modes = 1, + .outputs = { + { + .crtc = 0, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125 + }, + }, + .n_outputs = 1, + .crtcs = { + { + .current_mode = 0 + }, + }, + .n_crtcs = 1 + }, + + .expect = { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125, + .is_underscanning = TRUE, + } + }, + .n_monitors = 1, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 1024, .height = 768 }, + .scale = 1 + } + }, + .n_logical_monitors = 1, + .primary_logical_monitor = 0, + .n_outputs = 1, + .crtcs = { + { + .current_mode = 0, + } + }, + .n_crtcs = 1, + .n_tiled_monitors = 0, + .screen_width = 1024, + .screen_height = 768 + } + }; + MetaMonitorTestSetup *test_setup; + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NONE); + set_custom_monitor_config ("underscanning.xml"); + emulate_hotplug (test_setup); + + check_monitor_configuration (&test_case); +} + +static void +meta_test_monitor_custom_scale_config (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 1920, + .height = 1080, + .refresh_rate = 60.000495910644531 + } + }, + .n_modes = 1, + .outputs = { + { + .crtc = 0, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125 + }, + }, + .n_outputs = 1, + .crtcs = { + { + .current_mode = 0 + }, + }, + .n_crtcs = 1 + }, + + .expect = { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 1920, + .height = 1080, + .refresh_rate = 60.000495910644531, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125, + } + }, + .n_monitors = 1, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 960, .height = 540 }, + .scale = 2 + } + }, + .n_logical_monitors = 1, + .primary_logical_monitor = 0, + .n_outputs = 1, + .crtcs = { + { + .current_mode = 0, + } + }, + .n_crtcs = 1, + .n_tiled_monitors = 0, + .screen_width = 960, + .screen_height = 540 + } + }; + MetaMonitorTestSetup *test_setup; + + if (!meta_is_stage_views_enabled ()) + { + g_test_skip ("Not using stage views"); + return; + } + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NONE); + set_custom_monitor_config ("scale.xml"); + emulate_hotplug (test_setup); + + check_monitor_configuration (&test_case); +} + +static void +meta_test_monitor_custom_fractional_scale_config (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 1200, + .height = 900, + .refresh_rate = 60.000495910644531 + } + }, + .n_modes = 1, + .outputs = { + { + .crtc = 0, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125 + }, + }, + .n_outputs = 1, + .crtcs = { + { + .current_mode = 0 + }, + }, + .n_crtcs = 1 + }, + + .expect = { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 1200, + .height = 900, + .refresh_rate = 60.000495910644531, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125, + } + }, + .n_monitors = 1, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 800, .height = 600 }, + .scale = 1.5 + } + }, + .n_logical_monitors = 1, + .primary_logical_monitor = 0, + .n_outputs = 1, + .crtcs = { + { + .current_mode = 0, + } + }, + .n_crtcs = 1, + .n_tiled_monitors = 0, + .screen_width = 800, + .screen_height = 600 + } + }; + MetaMonitorTestSetup *test_setup; + + if (!meta_is_stage_views_enabled ()) + { + g_test_skip ("Not using stage views"); + return; + } + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NONE); + set_custom_monitor_config ("fractional-scale.xml"); + emulate_hotplug (test_setup); + + check_monitor_configuration (&test_case); +} + +static void +meta_test_monitor_custom_high_precision_fractional_scale_config (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531 + } + }, + .n_modes = 1, + .outputs = { + { + .crtc = 0, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125 + }, + }, + .n_outputs = 1, + .crtcs = { + { + .current_mode = 0 + }, + }, + .n_crtcs = 1 + }, + + .expect = { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125, + } + }, + .n_monitors = 1, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 744, .height = 558 }, + .scale = 1024.0/744.0 /* 1.3763440847396851 */ + } + }, + .n_logical_monitors = 1, + .primary_logical_monitor = 0, + .n_outputs = 1, + .crtcs = { + { + .current_mode = 0, + } + }, + .n_crtcs = 1, + .n_tiled_monitors = 0, + .screen_width = 744, + .screen_height = 558 + } + }; + MetaMonitorTestSetup *test_setup; + + if (!meta_is_stage_views_enabled ()) + { + g_test_skip ("Not using stage views"); + return; + } + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NONE); + set_custom_monitor_config ("high-precision-fractional-scale.xml"); + emulate_hotplug (test_setup); + + check_monitor_configuration (&test_case); +} + +static void +meta_test_monitor_custom_tiled_config (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 400, + .height = 600, + .refresh_rate = 60.000495910644531 + } + }, + .n_modes = 1, + .outputs = { + { + .crtc = -1, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0, 1 }, + .n_possible_crtcs = 2, + .width_mm = 222, + .height_mm = 125, + .tile_info = { + .group_id = 1, + .max_h_tiles = 2, + .max_v_tiles = 1, + .loc_h_tile = 0, + .loc_v_tile = 0, + .tile_w = 400, + .tile_h = 600 + } + }, + { + .crtc = -1, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0, 1 }, + .n_possible_crtcs = 2, + .width_mm = 222, + .height_mm = 125, + .tile_info = { + .group_id = 1, + .max_h_tiles = 2, + .max_v_tiles = 1, + .loc_h_tile = 1, + .loc_v_tile = 0, + .tile_w = 400, + .tile_h = 600 + } + } + }, + .n_outputs = 2, + .crtcs = { + { + .current_mode = 0 + }, + { + .current_mode = -1 + } + }, + .n_crtcs = 2 + }, + + .expect = { + .monitors = { + { + .outputs = { 0, 1 }, + .n_outputs = 2, + .modes = { + { + .width = 800, + .height = 600, + .refresh_rate = 60.000495910644531, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0, + }, + { + .output = 1, + .crtc_mode = 0, + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125, + } + }, + .n_monitors = 1, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 400, .height = 300 }, + .scale = 2 + } + }, + .n_logical_monitors = 1, + .primary_logical_monitor = 0, + .n_outputs = 2, + .crtcs = { + { + .current_mode = 0, + }, + { + .current_mode = 0, + .x = 200, + .y = 0 + } + }, + .n_crtcs = 2, + .n_tiled_monitors = 1, + .screen_width = 400, + .screen_height = 300 + } + }; + MetaMonitorTestSetup *test_setup; + + if (!meta_is_stage_views_enabled ()) + { + g_test_skip ("Not using stage views"); + return; + } + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NONE); + set_custom_monitor_config ("tiled.xml"); + emulate_hotplug (test_setup); + + check_monitor_configuration (&test_case); +} + +static void +meta_test_monitor_custom_tiled_custom_resolution_config (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 400, + .height = 600, + .refresh_rate = 60.000495910644531 + }, + { + .width = 640, + .height = 480, + .refresh_rate = 60.000495910644531 + } + }, + .n_modes = 2, + .outputs = { + { + .crtc = -1, + .modes = { 0, 1 }, + .n_modes = 2, + .preferred_mode = 0, + .possible_crtcs = { 0, 1 }, + .n_possible_crtcs = 2, + .width_mm = 222, + .height_mm = 125, + .tile_info = { + .group_id = 1, + .max_h_tiles = 2, + .max_v_tiles = 1, + .loc_h_tile = 0, + .loc_v_tile = 0, + .tile_w = 400, + .tile_h = 600 + } + }, + { + .crtc = -1, + .modes = { 0, 1 }, + .n_modes = 2, + .preferred_mode = 0, + .possible_crtcs = { 0, 1 }, + .n_possible_crtcs = 2, + .width_mm = 222, + .height_mm = 125, + .tile_info = { + .group_id = 1, + .max_h_tiles = 2, + .max_v_tiles = 1, + .loc_h_tile = 1, + .loc_v_tile = 0, + .tile_w = 400, + .tile_h = 600 + } + } + }, + .n_outputs = 2, + .crtcs = { + { + .current_mode = -1 + }, + { + .current_mode = -1 + } + }, + .n_crtcs = 2 + }, + + .expect = { + .monitors = { + { + .outputs = { 0, 1 }, + .n_outputs = 2, + .modes = { + { + .width = 800, + .height = 600, + .refresh_rate = 60.000495910644531, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0, + }, + { + .output = 1, + .crtc_mode = 0, + } + } + }, + { + .width = 640, + .height = 480, + .refresh_rate = 60.000495910644531, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 1, + }, + { + .output = 1, + .crtc_mode = -1, + } + } + } + }, + .n_modes = 2, + .current_mode = 1, + .width_mm = 222, + .height_mm = 125, + } + }, + .n_monitors = 1, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 320, .height = 240 }, + .scale = 2 + } + }, + .n_logical_monitors = 1, + .primary_logical_monitor = 0, + .n_outputs = 2, + .crtcs = { + { + .current_mode = 1, + }, + { + .current_mode = -1, + .x = 400, + .y = 0, + } + }, + .n_crtcs = 2, + .n_tiled_monitors = 1, + .screen_width = 320, + .screen_height = 240 + } + }; + MetaMonitorTestSetup *test_setup; + + if (!meta_is_stage_views_enabled ()) + { + g_test_skip ("Not using stage views"); + return; + } + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NONE); + set_custom_monitor_config ("tiled-custom-resolution.xml"); + emulate_hotplug (test_setup); + + check_monitor_configuration (&test_case); +} + +static void +meta_test_monitor_custom_tiled_non_preferred_config (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 640, + .height = 480, + .refresh_rate = 60.0 + }, + { + .width = 800, + .height = 600, + .refresh_rate = 60.0 + }, + { + .width = 512, + .height = 768, + .refresh_rate = 120.0 + }, + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0 + }, + }, + .n_modes = 4, + .outputs = { + { + .crtc = -1, + .modes = { 0, 2 }, + .n_modes = 2, + .preferred_mode = 1, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125, + .tile_info = { + .group_id = 1, + .max_h_tiles = 2, + .max_v_tiles = 1, + .loc_h_tile = 0, + .loc_v_tile = 0, + .tile_w = 512, + .tile_h = 768 + } + }, + { + .crtc = -1, + .modes = { 1, 2, 3 }, + .n_modes = 3, + .preferred_mode = 0, + .possible_crtcs = { 1 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125, + .tile_info = { + .group_id = 1, + .max_h_tiles = 2, + .max_v_tiles = 1, + .loc_h_tile = 1, + .loc_v_tile = 0, + .tile_w = 512, + .tile_h = 768 + } + } + }, + .n_outputs = 2, + .crtcs = { + { + .current_mode = -1 + }, + { + .current_mode = -1 + } + }, + .n_crtcs = 2 + }, + + .expect = { + .monitors = { + { + .outputs = { 0, 1 }, + .n_outputs = 2, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 120.0, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 2 + }, + { + .output = 1, + .crtc_mode = 2, + } + } + }, + { + .width = 800, + .height = 600, + .refresh_rate = 60.0, + .crtc_modes = { + { + .output = 0, + .crtc_mode = -1 + }, + { + .output = 1, + .crtc_mode = 1, + } + } + }, + { + .width = 1024, + .height = 768, + .refresh_rate = 60.0, + .crtc_modes = { + { + .output = 0, + .crtc_mode = -1 + }, + { + .output = 1, + .crtc_mode = 3, + } + } + }, + }, + .n_modes = 3, + .current_mode = 1, + .width_mm = 222, + .height_mm = 125, + } + }, + .n_monitors = 1, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 800, .height = 600 }, + .scale = 1 + }, + }, + .n_logical_monitors = 1, + .primary_logical_monitor = 0, + .n_outputs = 2, + .crtcs = { + { + .current_mode = -1, + }, + { + .current_mode = 1, + } + }, + .n_crtcs = 2, + .n_tiled_monitors = 1, + .screen_width = 800, + .screen_height = 600, + } + }; + MetaMonitorTestSetup *test_setup; + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NONE); + set_custom_monitor_config ("non-preferred-tiled-custom-resolution.xml"); + emulate_hotplug (test_setup); + + check_monitor_configuration (&test_case); +} + +static void +meta_test_monitor_custom_mirrored_config (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 800, + .height = 600, + .refresh_rate = 60.000495910644531 + } + }, + .n_modes = 1, + .outputs = { + { + .crtc = 0, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125 + }, + { + .crtc = 1, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 1 }, + .n_possible_crtcs = 1, + .width_mm = 220, + .height_mm = 124 + } + }, + .n_outputs = 2, + .crtcs = { + { + .current_mode = 0 + }, + { + .current_mode = 0 + } + }, + .n_crtcs = 2 + }, + + .expect = { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 800, + .height = 600, + .refresh_rate = 60.000495910644531, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125 + }, + { + .outputs = { 1 }, + .n_outputs = 1, + .modes = { + { + .width = 800, + .height = 600, + .refresh_rate = 60.000495910644531, + .crtc_modes = { + { + .output = 1, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 220, + .height_mm = 124 + } + }, + .n_monitors = 2, + .logical_monitors = { + { + .monitors = { 0, 1 }, + .n_monitors = 2, + .layout = { .x = 0, .y = 0, .width = 800, .height = 600 }, + .scale = 1 + } + }, + .n_logical_monitors = 1, + .primary_logical_monitor = 0, + .n_outputs = 2, + .crtcs = { + { + .current_mode = 0, + }, + { + .current_mode = 0, + } + }, + .n_crtcs = 2, + .n_tiled_monitors = 0, + .screen_width = 800, + .screen_height = 600 + } + }; + MetaMonitorTestSetup *test_setup; + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NONE); + set_custom_monitor_config ("mirrored.xml"); + emulate_hotplug (test_setup); + + check_monitor_configuration (&test_case); +} + +static void +meta_test_monitor_custom_first_rotated_config (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531 + } + }, + .n_modes = 1, + .outputs = { + { + .crtc = 0, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125, + }, + { + .crtc = 1, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 1 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125, + } + }, + .n_outputs = 2, + .crtcs = { + { + .current_mode = 0, + }, + { + .current_mode = 0 + } + }, + .n_crtcs = 2 + }, + + .expect = { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125, + }, + { + .outputs = { 1 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531, + .crtc_modes = { + { + .output = 1, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125, + } + }, + .n_monitors = 2, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 768, .height = 1024 }, + .scale = 1, + .transform = META_MONITOR_TRANSFORM_270 + }, + { + .monitors = { 1 }, + .n_monitors = 1, + .layout = { .x = 768, .y = 0, .width = 1024, .height = 768 }, + .scale = 1 + } + }, + .n_logical_monitors = 2, + .primary_logical_monitor = 0, + .n_outputs = 2, + .crtcs = { + { + .current_mode = 0, + .transform = META_MONITOR_TRANSFORM_270 + }, + { + .current_mode = 0, + .x = 768, + } + }, + .n_crtcs = 2, + .screen_width = 768 + 1024, + .screen_height = 1024 + } + }; + MetaMonitorTestSetup *test_setup; + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NONE); + set_custom_monitor_config ("first-rotated.xml"); + emulate_hotplug (test_setup); + check_monitor_configuration (&test_case); +} + +static void +meta_test_monitor_custom_second_rotated_config (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531 + } + }, + .n_modes = 1, + .outputs = { + { + .crtc = 0, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125, + }, + { + .crtc = 1, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 1 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125, + } + }, + .n_outputs = 2, + .crtcs = { + { + .current_mode = 0 + }, + { + .current_mode = 0 + } + }, + .n_crtcs = 2 + }, + + .expect = { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125, + }, + { + .outputs = { 1 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531, + .crtc_modes = { + { + .output = 1, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125, + } + }, + .n_monitors = 2, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 256, .width = 1024, .height = 768 }, + .scale = 1 + }, + { + .monitors = { 1 }, + .n_monitors = 1, + .layout = { .x = 1024, .y = 0, .width = 768, .height = 1024 }, + .scale = 1, + .transform = META_MONITOR_TRANSFORM_90 + } + }, + .n_logical_monitors = 2, + .primary_logical_monitor = 0, + .n_outputs = 2, + .crtcs = { + { + .current_mode = 0, + .y = 256, + }, + { + .current_mode = 0, + .transform = META_MONITOR_TRANSFORM_90, + .x = 1024, + } + }, + .n_crtcs = 2, + .screen_width = 768 + 1024, + .screen_height = 1024 + } + }; + MetaMonitorTestSetup *test_setup; + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NONE); + set_custom_monitor_config ("second-rotated.xml"); + emulate_hotplug (test_setup); + check_monitor_configuration (&test_case); +} + +static void +meta_test_monitor_custom_second_rotated_tiled_config (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531 + }, + { + .width = 400, + .height = 600, + .refresh_rate = 60.000495910644531 + } + }, + .n_modes = 2, + .outputs = { + { + .crtc = 0, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125, + }, + { + .crtc = -1, + .modes = { 1 }, + .n_modes = 1, + .preferred_mode = 1, + .possible_crtcs = { 1, 2 }, + .n_possible_crtcs = 2, + .width_mm = 222, + .height_mm = 125, + .tile_info = { + .group_id = 1, + .max_h_tiles = 2, + .max_v_tiles = 1, + .loc_h_tile = 0, + .loc_v_tile = 0, + .tile_w = 400, + .tile_h = 600 + } + }, + { + .crtc = -1, + .modes = { 1 }, + .n_modes = 1, + .preferred_mode = 1, + .possible_crtcs = { 1, 2 }, + .n_possible_crtcs = 2, + .width_mm = 222, + .height_mm = 125, + .tile_info = { + .group_id = 1, + .max_h_tiles = 2, + .max_v_tiles = 1, + .loc_h_tile = 1, + .loc_v_tile = 0, + .tile_w = 400, + .tile_h = 600 + } + } + }, + .n_outputs = 3, + .crtcs = { + { + .current_mode = -1 + }, + { + .current_mode = -1 + }, + { + .current_mode = -1 + } + }, + .n_crtcs = 3 + }, + + .expect = { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125, + }, + { + .outputs = { 1, 2 }, + .n_outputs = 2, + .modes = { + { + .width = 800, + .height = 600, + .refresh_rate = 60.000495910644531, + .crtc_modes = { + { + .output = 1, + .crtc_mode = 1, + }, + { + .output = 2, + .crtc_mode = 1, + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125, + } + }, + .n_monitors = 2, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 256, .width = 1024, .height = 768 }, + .scale = 1 + }, + { + .monitors = { 1 }, + .n_monitors = 1, + .layout = { .x = 1024, .y = 0, .width = 600, .height = 800 }, + .scale = 1, + .transform = META_MONITOR_TRANSFORM_90 + } + }, + .n_logical_monitors = 2, + .primary_logical_monitor = 0, + .n_outputs = 3, + .crtcs = { + { + .current_mode = 0, + .y = 256, + }, + { + .current_mode = 1, + .transform = META_MONITOR_TRANSFORM_90, + .x = 1024, + .y = 0, + }, + { + .current_mode = 1, + .transform = META_MONITOR_TRANSFORM_90, + .x = 1024, + .y = 400, + } + }, + .n_crtcs = 3, + .n_tiled_monitors = 1, + .screen_width = 1024 + 600, + .screen_height = 1024 + } + }; + MetaMonitorTestSetup *test_setup; + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaMonitorManagerTest *monitor_manager_test = + META_MONITOR_MANAGER_TEST (monitor_manager); + + meta_monitor_manager_test_set_handles_transforms (monitor_manager_test, + TRUE); + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NONE); + set_custom_monitor_config ("second-rotated-tiled.xml"); + emulate_hotplug (test_setup); + check_monitor_configuration (&test_case); +} + +static void +meta_test_monitor_custom_second_rotated_nonnative_tiled_config (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531 + }, + { + .width = 400, + .height = 600, + .refresh_rate = 60.000495910644531 + } + }, + .n_modes = 2, + .outputs = { + { + .crtc = 0, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125, + }, + { + .crtc = -1, + .modes = { 1 }, + .n_modes = 1, + .preferred_mode = 1, + .possible_crtcs = { 1, 2 }, + .n_possible_crtcs = 2, + .width_mm = 222, + .height_mm = 125, + .tile_info = { + .group_id = 1, + .max_h_tiles = 2, + .max_v_tiles = 1, + .loc_h_tile = 0, + .loc_v_tile = 0, + .tile_w = 400, + .tile_h = 600 + } + }, + { + .crtc = -1, + .modes = { 1 }, + .n_modes = 1, + .preferred_mode = 1, + .possible_crtcs = { 1, 2 }, + .n_possible_crtcs = 2, + .width_mm = 222, + .height_mm = 125, + .tile_info = { + .group_id = 1, + .max_h_tiles = 2, + .max_v_tiles = 1, + .loc_h_tile = 1, + .loc_v_tile = 0, + .tile_w = 400, + .tile_h = 600 + } + } + }, + .n_outputs = 3, + .crtcs = { + { + .current_mode = -1 + }, + { + .current_mode = -1 + }, + { + .current_mode = -1 + } + }, + .n_crtcs = 3 + }, + + .expect = { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125, + }, + { + .outputs = { 1, 2 }, + .n_outputs = 2, + .modes = { + { + .width = 800, + .height = 600, + .refresh_rate = 60.000495910644531, + .crtc_modes = { + { + .output = 1, + .crtc_mode = 1, + }, + { + .output = 2, + .crtc_mode = 1, + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125, + } + }, + .n_monitors = 2, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 256, .width = 1024, .height = 768 }, + .scale = 1 + }, + { + .monitors = { 1 }, + .n_monitors = 1, + .layout = { .x = 1024, .y = 0, .width = 600, .height = 800 }, + .scale = 1, + .transform = META_MONITOR_TRANSFORM_90 + } + }, + .n_logical_monitors = 2, + .primary_logical_monitor = 0, + .n_outputs = 3, + .crtcs = { + { + .current_mode = 0, + .y = 256, + }, + { + .current_mode = 1, + .transform = META_MONITOR_TRANSFORM_NORMAL, + .x = 1024, + .y = 0, + }, + { + .current_mode = 1, + .transform = META_MONITOR_TRANSFORM_NORMAL, + .x = 1024, + .y = 400, + } + }, + .n_crtcs = 3, + .n_tiled_monitors = 1, + .screen_width = 1024 + 600, + .screen_height = 1024 + } + }; + MetaMonitorTestSetup *test_setup; + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaMonitorManagerTest *monitor_manager_test = + META_MONITOR_MANAGER_TEST (monitor_manager); + + meta_monitor_manager_test_set_handles_transforms (monitor_manager_test, + FALSE); + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NONE); + set_custom_monitor_config ("second-rotated-tiled.xml"); + emulate_hotplug (test_setup); + check_monitor_configuration (&test_case); +} + +static void +meta_test_monitor_custom_second_rotated_nonnative_config (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531 + } + }, + .n_modes = 1, + .outputs = { + { + .crtc = 0, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125, + }, + { + .crtc = 1, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 1 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125, + } + }, + .n_outputs = 2, + .crtcs = { + { + .current_mode = 0 + }, + { + .current_mode = 0 + } + }, + .n_crtcs = 2 + }, + + .expect = { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125, + }, + { + .outputs = { 1 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531, + .crtc_modes = { + { + .output = 1, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125, + } + }, + .n_monitors = 2, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 256, .width = 1024, .height = 768 }, + .scale = 1 + }, + { + .monitors = { 1 }, + .n_monitors = 1, + .layout = { .x = 1024, .y = 0, .width = 768, .height = 1024 }, + .scale = 1, + .transform = META_MONITOR_TRANSFORM_90 + } + }, + .n_logical_monitors = 2, + .primary_logical_monitor = 0, + .n_outputs = 2, + .crtcs = { + { + .current_mode = 0, + .y = 256, + }, + { + .current_mode = 0, + .transform = META_MONITOR_TRANSFORM_NORMAL, + .x = 1024, + } + }, + .n_crtcs = 2, + .screen_width = 768 + 1024, + .screen_height = 1024 + } + }; + MetaMonitorTestSetup *test_setup; + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaMonitorManagerTest *monitor_manager_test = + META_MONITOR_MANAGER_TEST (monitor_manager); + + if (!meta_is_stage_views_enabled ()) + { + g_test_skip ("Not using stage views"); + return; + } + + meta_monitor_manager_test_set_handles_transforms (monitor_manager_test, + FALSE); + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NONE); + set_custom_monitor_config ("second-rotated.xml"); + emulate_hotplug (test_setup); + check_monitor_configuration (&test_case); +} + +static void +meta_test_monitor_custom_interlaced_config (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531 + }, + { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531, + .flags = META_CRTC_MODE_FLAG_INTERLACE, + } + }, + .n_modes = 2, + .outputs = { + { + .crtc = 0, + .modes = { 0, 1 }, + .n_modes = 2, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125 + }, + }, + .n_outputs = 1, + .crtcs = { + { + .current_mode = 0 + }, + }, + .n_crtcs = 1 + }, + + .expect = { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531, + .flags = META_CRTC_MODE_FLAG_NONE, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0, + }, + } + }, + { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531, + .flags = META_CRTC_MODE_FLAG_INTERLACE, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 1, + } + } + } + }, + .n_modes = 2, + .current_mode = 1, + .width_mm = 222, + .height_mm = 125, + } + }, + .n_monitors = 1, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 1024, .height = 768 }, + .scale = 1 + } + }, + .n_logical_monitors = 1, + .primary_logical_monitor = 0, + .n_outputs = 1, + .crtcs = { + { + .current_mode = 1, + } + }, + .n_crtcs = 1, + .n_tiled_monitors = 0, + .screen_width = 1024, + .screen_height = 768 + } + }; + MetaMonitorTestSetup *test_setup; + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NONE); + set_custom_monitor_config ("interlaced.xml"); + emulate_hotplug (test_setup); + + check_monitor_configuration (&test_case); +} + +static void +meta_test_monitor_custom_oneoff (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 800, + .height = 600, + .refresh_rate = 60.0 + } + }, + .n_modes = 1, + .outputs = { + { + .crtc = -1, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0, 1 }, + .n_possible_crtcs = 2, + .width_mm = 222, + .height_mm = 125 + }, + { + .crtc = -1, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0, 1 }, + .n_possible_crtcs = 2, + .width_mm = 222, + .height_mm = 125, + .serial = "0x654321" + } + }, + .n_outputs = 2, + .crtcs = { + { + .current_mode = -1 + }, + { + .current_mode = -1 + } + }, + .n_crtcs = 2 + }, + + .expect = { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 800, + .height = 600, + .refresh_rate = 60.0, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125 + }, + { + .outputs = { 1 }, + .n_outputs = 1, + .modes = { + { + .width = 800, + .height = 600, + .refresh_rate = 60.0, + .crtc_modes = { + { + .output = 1, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = -1, + .width_mm = 222, + .height_mm = 125 + } + }, + .n_monitors = 2, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 800, .height = 600 }, + .scale = 1, + .transform = META_MONITOR_TRANSFORM_NORMAL + }, + }, + .n_logical_monitors = 1, + .primary_logical_monitor = 0, + .n_outputs = 2, + .crtcs = { + { + .current_mode = 0, + }, + { + .current_mode = -1, + } + }, + .n_crtcs = 2, + .screen_width = 800, + .screen_height = 600, + } + }; + MetaMonitorTestSetup *test_setup; + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NONE); + set_custom_monitor_config ("oneoff.xml"); + emulate_hotplug (test_setup); + + check_monitor_configuration (&test_case); +} + +static void +meta_test_monitor_custom_lid_switch_config (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531 + } + }, + .n_modes = 1, + .outputs = { + { + .crtc = -1, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125, + .is_laptop_panel = TRUE + }, + { + .crtc = -1, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 1 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125, + } + }, + .n_outputs = 1, /* Second one hot plugged later */ + .crtcs = { + { + .current_mode = 0, + }, + { + .current_mode = 0 + } + }, + .n_crtcs = 2 + }, + + .expect = { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125, + }, + { + .outputs = { 1 }, + .n_outputs = 1, + .modes = { + { + .width = 1024, + .height = 768, + .refresh_rate = 60.000495910644531, + .crtc_modes = { + { + .output = 1, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125, + } + }, + .n_monitors = 1, /* Second one hot plugged later */ + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 768, .height = 1024 }, + .scale = 1, + .transform = META_MONITOR_TRANSFORM_270 + }, + { + .monitors = { 1 }, + .n_monitors = 1, + .layout = { .x = 1024, .y = 0, .width = 768, .height = 1024 }, + .scale = 1 + } + }, + .n_logical_monitors = 1, /* Second one hot plugged later */ + .primary_logical_monitor = 0, + .n_outputs = 1, + .crtcs = { + { + .current_mode = 0, + .transform = META_MONITOR_TRANSFORM_270 + }, + { + .current_mode = -1, + } + }, + .n_crtcs = 2, + .screen_width = 768, + .screen_height = 1024 + } + }; + MetaMonitorTestSetup *test_setup; + MetaBackend *backend = meta_get_backend (); + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NONE); + set_custom_monitor_config ("lid-switch.xml"); + emulate_hotplug (test_setup); + check_monitor_configuration (&test_case); + + /* External monitor connected */ + + test_case.setup.n_outputs = 2; + test_case.expect.n_monitors = 2; + test_case.expect.n_outputs = 2; + test_case.expect.crtcs[0].transform = META_MONITOR_TRANSFORM_NORMAL; + test_case.expect.crtcs[1].current_mode = 0; + test_case.expect.crtcs[1].x = 1024; + test_case.expect.crtcs[1].transform = META_MONITOR_TRANSFORM_270; + test_case.expect.logical_monitors[0].layout = + (MetaRectangle) { .width = 1024, .height = 768 }; + test_case.expect.logical_monitors[0].transform = META_MONITOR_TRANSFORM_NORMAL; + test_case.expect.logical_monitors[1].transform = META_MONITOR_TRANSFORM_270; + test_case.expect.n_logical_monitors = 2; + test_case.expect.screen_width = 1024 + 768; + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NONE); + emulate_hotplug (test_setup); + check_monitor_configuration (&test_case); + + /* Lid was closed */ + + test_case.expect.crtcs[0].current_mode = -1; + test_case.expect.crtcs[1].transform = META_MONITOR_TRANSFORM_90; + test_case.expect.crtcs[1].x = 0; + test_case.expect.monitors[0].current_mode = -1; + test_case.expect.logical_monitors[0].layout = + (MetaRectangle) { .width = 768, .height = 1024 }; + test_case.expect.logical_monitors[0].monitors[0] = 1; + test_case.expect.logical_monitors[0].transform = META_MONITOR_TRANSFORM_90; + test_case.expect.n_logical_monitors = 1; + test_case.expect.screen_width = 768; + meta_backend_test_set_is_lid_closed (META_BACKEND_TEST (backend), TRUE); + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NONE); + emulate_hotplug (test_setup); + check_monitor_configuration (&test_case); + + /* Lid was opened */ + + test_case.expect.crtcs[0].current_mode = 0; + test_case.expect.crtcs[0].transform = META_MONITOR_TRANSFORM_NORMAL; + test_case.expect.crtcs[1].current_mode = 0; + test_case.expect.crtcs[1].transform = META_MONITOR_TRANSFORM_270; + test_case.expect.crtcs[1].x = 1024; + test_case.expect.monitors[0].current_mode = 0; + test_case.expect.logical_monitors[0].layout = + (MetaRectangle) { .width = 1024, .height = 768 }; + test_case.expect.logical_monitors[0].monitors[0] = 0; + test_case.expect.logical_monitors[0].transform = META_MONITOR_TRANSFORM_NORMAL; + test_case.expect.logical_monitors[1].transform = META_MONITOR_TRANSFORM_270; + test_case.expect.n_logical_monitors = 2; + test_case.expect.screen_width = 1024 + 768; + meta_backend_test_set_is_lid_closed (META_BACKEND_TEST (backend), FALSE); + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NONE); + emulate_hotplug (test_setup); + check_monitor_configuration (&test_case); +} + +static void +meta_test_monitor_migrated_rotated (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 800, + .height = 600, + .refresh_rate = 60.0 + } + }, + .n_modes = 1, + .outputs = { + { + .crtc = -1, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125 + } + }, + .n_outputs = 1, + .crtcs = { + { + .current_mode = -1 + } + }, + .n_crtcs = 1 + }, + + .expect = { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 800, + .height = 600, + .refresh_rate = 60.0, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125 + } + }, + .n_monitors = 1, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 600, .height = 800 }, + .scale = 1, + .transform = META_MONITOR_TRANSFORM_270 + }, + }, + .n_logical_monitors = 1, + .primary_logical_monitor = 0, + .n_outputs = 1, + .crtcs = { + { + .current_mode = 0, + .transform = META_MONITOR_TRANSFORM_270 + } + }, + .n_crtcs = 1, + .screen_width = 600, + .screen_height = 800, + } + }; + MetaMonitorTestSetup *test_setup; + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaMonitorConfigManager *config_manager = monitor_manager->config_manager; + MetaMonitorConfigStore *config_store = + meta_monitor_config_manager_get_store (config_manager); + g_autofree char *migrated_path = NULL; + const char *old_config_path; + g_autoptr (GFile) old_config_file = NULL; + GError *error = NULL; + const char *expected_path; + g_autofree char *migrated_data = NULL; + g_autofree char *expected_data = NULL; + g_autoptr (GFile) migrated_file = NULL; + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NONE); + + migrated_path = g_build_filename (g_get_tmp_dir (), + "test-finished-migrated-monitors.xml", + NULL); + if (!meta_monitor_config_store_set_custom (config_store, + "/dev/null", + migrated_path, + &error)) + g_error ("Failed to set custom config store files: %s", error->message); + + old_config_path = g_test_get_filename (G_TEST_DIST, + "tests", "migration", + "rotated-old.xml", + NULL); + old_config_file = g_file_new_for_path (old_config_path); + if (!meta_migrate_old_monitors_config (config_store, + old_config_file, + &error)) + g_error ("Failed to migrate config: %s", error->message); + + emulate_hotplug (test_setup); + + check_monitor_configuration (&test_case); + + expected_path = g_test_get_filename (G_TEST_DIST, + "tests", "migration", + "rotated-new-finished.xml", + NULL); + expected_data = read_file (expected_path); + migrated_data = read_file (migrated_path); + + g_assert_nonnull (expected_data); + g_assert_nonnull (migrated_data); + + g_assert (strcmp (expected_data, migrated_data) == 0); + + migrated_file = g_file_new_for_path (migrated_path); + if (!g_file_delete (migrated_file, NULL, &error)) + g_error ("Failed to remove test data output file: %s", error->message); +} + +static void +meta_test_monitor_migrated_wiggle_discard (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 800, + .height = 600, + .refresh_rate = 59.0 + } + }, + .n_modes = 1, + .outputs = { + { + .crtc = -1, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125 + } + }, + .n_outputs = 1, + .crtcs = { + { + .current_mode = -1 + } + }, + .n_crtcs = 1 + }, + + .expect = { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 800, + .height = 600, + .refresh_rate = 59.0, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125 + } + }, + .n_monitors = 1, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 800, .height = 600 }, + .scale = 1, + .transform = META_MONITOR_TRANSFORM_NORMAL + }, + }, + .n_logical_monitors = 1, + .primary_logical_monitor = 0, + .n_outputs = 1, + .crtcs = { + { + .current_mode = 0, + } + }, + .n_crtcs = 1, + .screen_width = 800, + .screen_height = 600, + } + }; + MetaMonitorTestSetup *test_setup; + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaMonitorConfigManager *config_manager = monitor_manager->config_manager; + MetaMonitorConfigStore *config_store = + meta_monitor_config_manager_get_store (config_manager); + g_autofree char *migrated_path = NULL; + const char *old_config_path; + g_autoptr (GFile) old_config_file = NULL; + GError *error = NULL; + const char *expected_path; + g_autofree char *migrated_data = NULL; + g_autofree char *expected_data = NULL; + g_autoptr (GFile) migrated_file = NULL; + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NONE); + + migrated_path = g_build_filename (g_get_tmp_dir (), + "test-finished-migrated-monitors.xml", + NULL); + if (!meta_monitor_config_store_set_custom (config_store, + "/dev/null", + migrated_path, + &error)) + g_error ("Failed to set custom config store files: %s", error->message); + + old_config_path = g_test_get_filename (G_TEST_DIST, + "tests", "migration", + "wiggle-old.xml", + NULL); + old_config_file = g_file_new_for_path (old_config_path); + if (!meta_migrate_old_monitors_config (config_store, + old_config_file, + &error)) + g_error ("Failed to migrate config: %s", error->message); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, + "Failed to finish monitors config migration: " + "Mode not available on monitor"); + emulate_hotplug (test_setup); + g_test_assert_expected_messages (); + + check_monitor_configuration (&test_case); + + expected_path = g_test_get_filename (G_TEST_DIST, + "tests", "migration", + "wiggle-new-discarded.xml", + NULL); + expected_data = read_file (expected_path); + migrated_data = read_file (migrated_path); + + g_assert_nonnull (expected_data); + g_assert_nonnull (migrated_data); + + g_assert (strcmp (expected_data, migrated_data) == 0); + + migrated_file = g_file_new_for_path (migrated_path); + if (!g_file_delete (migrated_file, NULL, &error)) + g_error ("Failed to remove test data output file: %s", error->message); +} + +static gboolean +quit_main_loop (gpointer data) +{ + GMainLoop *loop = data; + + g_main_loop_quit (loop); + + return G_SOURCE_REMOVE; +} + +static void +dispatch (void) +{ + GMainLoop *loop; + + loop = g_main_loop_new (NULL, FALSE); + meta_later_add (META_LATER_BEFORE_REDRAW, + quit_main_loop, + loop, + NULL); + g_main_loop_run (loop); +} + +static TestClient * +create_test_window (const char *window_name) +{ + TestClient *test_client; + static int client_count = 0; + g_autofree char *client_name = NULL; + g_autoptr (GError) error = NULL; + + client_name = g_strdup_printf ("test_client_%d", client_count++); + test_client = test_client_new (client_name, META_WINDOW_CLIENT_TYPE_WAYLAND, + &error); + if (!test_client) + g_error ("Failed to launch test client: %s", error->message); + + if (!test_client_do (test_client, &error, + "create", window_name, + NULL)) + g_error ("Failed to create window: %s", error->message); + + return test_client; +} + +static void +meta_test_monitor_wm_tiling (void) +{ + MonitorTestCase test_case = initial_test_case; + MetaMonitorTestSetup *test_setup; + g_autoptr (GError) error = NULL; + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NO_STORED); + emulate_hotplug (test_setup); + + /* + * 1) Start with two monitors connected. + * 2) Tile it on the second monitor. + * 3) Unplug both monitors. + * 4) Replug in first monitor. + */ + + const char *test_window_name= "window1"; + TestClient *test_client = create_test_window (test_window_name); + + if (!test_client_do (test_client, &error, + "show", test_window_name, + NULL)) + g_error ("Failed to show the window: %s", error->message); + + MetaWindow *test_window = + test_client_find_window (test_client, + test_window_name, + &error); + if (!test_window) + g_error ("Failed to find the window: %s", error->message); + test_client_wait_for_window_shown (test_client, test_window); + + meta_window_tile (test_window, META_TILE_MAXIMIZED); + meta_window_move_to_monitor (test_window, 1); + check_test_client_state (test_client); + + fprintf(stderr, ":::: %s:%d %s() - UNPLUGGING\n", __FILE__, __LINE__, __func__); + + test_case.setup.n_outputs = 0; + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NO_STORED); + emulate_hotplug (test_setup); + test_case.setup.n_outputs = 1; + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NO_STORED); + emulate_hotplug (test_setup); + + dispatch (); + + /* + * 1) Start with two monitors connected. + * 2) Tile a window on the second monitor. + * 3) Untile window. + * 4) Unplug monitor. + * 5) Tile window again. + */ + + test_case.setup.n_outputs = 2; + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NO_STORED); + emulate_hotplug (test_setup); + + meta_window_move_to_monitor (test_window, 1); + meta_window_tile (test_window, META_TILE_NONE); + + test_case.setup.n_outputs = 1; + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NO_STORED); + emulate_hotplug (test_setup); + + meta_window_tile (test_window, META_TILE_MAXIMIZED); + + test_client_destroy (test_client); +} + +static void +meta_test_monitor_migrated_wiggle (void) +{ + MonitorTestCase test_case = { + .setup = { + .modes = { + { + .width = 800, + .height = 600, + .refresh_rate = 60.0 + } + }, + .n_modes = 1, + .outputs = { + { + .crtc = -1, + .modes = { 0 }, + .n_modes = 1, + .preferred_mode = 0, + .possible_crtcs = { 0 }, + .n_possible_crtcs = 1, + .width_mm = 222, + .height_mm = 125 + } + }, + .n_outputs = 1, + .crtcs = { + { + .current_mode = -1 + } + }, + .n_crtcs = 1 + }, + + .expect = { + .monitors = { + { + .outputs = { 0 }, + .n_outputs = 1, + .modes = { + { + .width = 800, + .height = 600, + .refresh_rate = 60.0, + .crtc_modes = { + { + .output = 0, + .crtc_mode = 0 + } + } + } + }, + .n_modes = 1, + .current_mode = 0, + .width_mm = 222, + .height_mm = 125 + } + }, + .n_monitors = 1, + .logical_monitors = { + { + .monitors = { 0 }, + .n_monitors = 1, + .layout = { .x = 0, .y = 0, .width = 600, .height = 800 }, + .scale = 1, + .transform = META_MONITOR_TRANSFORM_90 + }, + }, + .n_logical_monitors = 1, + .primary_logical_monitor = 0, + .n_outputs = 1, + .crtcs = { + { + .current_mode = 0, + .transform = META_MONITOR_TRANSFORM_90 + } + }, + .n_crtcs = 1, + .screen_width = 600, + .screen_height = 800, + } + }; + MetaMonitorTestSetup *test_setup; + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaMonitorConfigManager *config_manager = monitor_manager->config_manager; + MetaMonitorConfigStore *config_store = + meta_monitor_config_manager_get_store (config_manager); + g_autofree char *migrated_path = NULL; + const char *old_config_path; + g_autoptr (GFile) old_config_file = NULL; + GError *error = NULL; + const char *expected_path; + g_autofree char *migrated_data = NULL; + g_autofree char *expected_data = NULL; + g_autoptr (GFile) migrated_file = NULL; + + test_setup = create_monitor_test_setup (&test_case, + MONITOR_TEST_FLAG_NONE); + + migrated_path = g_build_filename (g_get_tmp_dir (), + "test-finished-migrated-monitors.xml", + NULL); + if (!meta_monitor_config_store_set_custom (config_store, + "/dev/null", + migrated_path, + &error)) + g_error ("Failed to set custom config store files: %s", error->message); + + old_config_path = g_test_get_filename (G_TEST_DIST, + "tests", "migration", + "wiggle-old.xml", + NULL); + old_config_file = g_file_new_for_path (old_config_path); + if (!meta_migrate_old_monitors_config (config_store, + old_config_file, + &error)) + g_error ("Failed to migrate config: %s", error->message); + + emulate_hotplug (test_setup); + + check_monitor_configuration (&test_case); + + expected_path = g_test_get_filename (G_TEST_DIST, + "tests", "migration", + "wiggle-new-finished.xml", + NULL); + expected_data = read_file (expected_path); + migrated_data = read_file (migrated_path); + + g_assert_nonnull (expected_data); + g_assert_nonnull (migrated_data); + + g_assert (strcmp (expected_data, migrated_data) == 0); + + migrated_file = g_file_new_for_path (migrated_path); + if (!g_file_delete (migrated_file, NULL, &error)) + g_error ("Failed to remove test data output file: %s", error->message); +} + +static void +test_case_setup (void **fixture, + const void *data) +{ + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaMonitorManagerTest *monitor_manager_test = + META_MONITOR_MANAGER_TEST (monitor_manager); + MetaMonitorConfigManager *config_manager = monitor_manager->config_manager; + + meta_monitor_manager_test_set_handles_transforms (monitor_manager_test, + TRUE); + meta_monitor_config_manager_set_current (config_manager, NULL); + meta_monitor_config_manager_clear_history (config_manager); +} + +static void +add_monitor_test (const char *test_path, + GTestFunc test_func) +{ + g_test_add (test_path, gpointer, NULL, + test_case_setup, + (void (* ) (void **, const void *)) test_func, + NULL); +} + +void +init_monitor_tests (void) +{ + MetaMonitorTestSetup *initial_test_setup; + + initial_test_setup = create_monitor_test_setup (&initial_test_case, + MONITOR_TEST_FLAG_NO_STORED); + meta_monitor_manager_test_init_test_setup (initial_test_setup); + + add_monitor_test ("/backends/monitor/initial-linear-config", + meta_test_monitor_initial_linear_config); + add_monitor_test ("/backends/monitor/one-disconnected-linear-config", + meta_test_monitor_one_disconnected_linear_config); + add_monitor_test ("/backends/monitor/one-off-linear-config", + meta_test_monitor_one_off_linear_config); + add_monitor_test ("/backends/monitor/preferred-linear-config", + meta_test_monitor_preferred_linear_config); + add_monitor_test ("/backends/monitor/tiled-linear-config", + meta_test_monitor_tiled_linear_config); + add_monitor_test ("/backends/monitor/tiled-non-preferred-linear-config", + meta_test_monitor_tiled_non_preferred_linear_config); + add_monitor_test ("/backends/monitor/tiled-non-main-origin-linear-config", + meta_test_monitor_tiled_non_main_origin_linear_config); + add_monitor_test ("/backends/monitor/hidpi-linear-config", + meta_test_monitor_hidpi_linear_config); + add_monitor_test ("/backends/monitor/suggested-config", + meta_test_monitor_suggested_config); + add_monitor_test ("/backends/monitor/limited-crtcs", + meta_test_monitor_limited_crtcs); + add_monitor_test ("/backends/monitor/lid-switch-config", + meta_test_monitor_lid_switch_config); + add_monitor_test ("/backends/monitor/lid-opened-config", + meta_test_monitor_lid_opened_config); + add_monitor_test ("/backends/monitor/lid-closed-no-external", + meta_test_monitor_lid_closed_no_external); + add_monitor_test ("/backends/monitor/lid-closed-with-hotplugged-external", + meta_test_monitor_lid_closed_with_hotplugged_external); + add_monitor_test ("/backends/monitor/lid-scaled-closed-opened", + meta_test_monitor_lid_scaled_closed_opened); + add_monitor_test ("/backends/monitor/no-outputs", + meta_test_monitor_no_outputs); + add_monitor_test ("/backends/monitor/underscanning-config", + meta_test_monitor_underscanning_config); + add_monitor_test ("/backends/monitor/preferred-non-first-mode", + meta_test_monitor_preferred_non_first_mode); + add_monitor_test ("/backends/monitor/non-upright-panel", + meta_test_monitor_non_upright_panel); + + add_monitor_test ("/backends/monitor/custom/vertical-config", + meta_test_monitor_custom_vertical_config); + add_monitor_test ("/backends/monitor/custom/primary-config", + meta_test_monitor_custom_primary_config); + add_monitor_test ("/backends/monitor/custom/underscanning-config", + meta_test_monitor_custom_underscanning_config); + add_monitor_test ("/backends/monitor/custom/scale-config", + meta_test_monitor_custom_scale_config); + add_monitor_test ("/backends/monitor/custom/fractional-scale-config", + meta_test_monitor_custom_fractional_scale_config); + add_monitor_test ("/backends/monitor/custom/high-precision-fractional-scale-config", + meta_test_monitor_custom_high_precision_fractional_scale_config); + add_monitor_test ("/backends/monitor/custom/tiled-config", + meta_test_monitor_custom_tiled_config); + add_monitor_test ("/backends/monitor/custom/tiled-custom-resolution-config", + meta_test_monitor_custom_tiled_custom_resolution_config); + add_monitor_test ("/backends/monitor/custom/tiled-non-preferred-config", + meta_test_monitor_custom_tiled_non_preferred_config); + add_monitor_test ("/backends/monitor/custom/mirrored-config", + meta_test_monitor_custom_mirrored_config); + add_monitor_test ("/backends/monitor/custom/first-rotated-config", + meta_test_monitor_custom_first_rotated_config); + add_monitor_test ("/backends/monitor/custom/second-rotated-config", + meta_test_monitor_custom_second_rotated_config); + add_monitor_test ("/backends/monitor/custom/second-rotated-tiled-config", + meta_test_monitor_custom_second_rotated_tiled_config); + add_monitor_test ("/backends/monitor/custom/second-rotated-nonnative-tiled-config", + meta_test_monitor_custom_second_rotated_nonnative_tiled_config); + add_monitor_test ("/backends/monitor/custom/second-rotated-nonnative-config", + meta_test_monitor_custom_second_rotated_nonnative_config); + add_monitor_test ("/backends/monitor/custom/interlaced-config", + meta_test_monitor_custom_interlaced_config); + add_monitor_test ("/backends/monitor/custom/oneoff-config", + meta_test_monitor_custom_oneoff); + add_monitor_test ("/backends/monitor/custom/lid-switch-config", + meta_test_monitor_custom_lid_switch_config); + + add_monitor_test ("/backends/monitor/migrated/rotated", + meta_test_monitor_migrated_rotated); + add_monitor_test ("/backends/monitor/migrated/wiggle", + meta_test_monitor_migrated_wiggle); + add_monitor_test ("/backends/monitor/migrated/wiggle-discard", + meta_test_monitor_migrated_wiggle_discard); + + add_monitor_test ("/backends/monitor/wm/tiling", + meta_test_monitor_wm_tiling); +} + +void +pre_run_monitor_tests (void) +{ + create_monitor_test_clients (); +} + +void +finish_monitor_tests (void) +{ + destroy_monitor_test_clients (); +} diff --git a/src/tests/monitor-unit-tests.h b/src/tests/monitor-unit-tests.h new file mode 100644 index 000000000..b215e31d1 --- /dev/null +++ b/src/tests/monitor-unit-tests.h @@ -0,0 +1,29 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef MONITOR_UNIT_TESTS_H +#define MONITOR_UNIT_TESTS_H + +void init_monitor_tests (void); + +void pre_run_monitor_tests (void); + +void finish_monitor_tests (void); + +#endif /* MONITOR_UNIT_TESTS_H */ diff --git a/src/tests/mutter-all.test.in b/src/tests/mutter-all.test.in new file mode 100644 index 000000000..3078ff67e --- /dev/null +++ b/src/tests/mutter-all.test.in @@ -0,0 +1,5 @@ +[Test] +Description=All Mutter tests +Exec=@libexecdir@/installed-tests/mutter-@apiversion@/mutter-test-runner --all +Type=session +Output=TAP diff --git a/src/tests/stacking/basic-wayland.metatest b/src/tests/stacking/basic-wayland.metatest new file mode 100644 index 000000000..63ce6082b --- /dev/null +++ b/src/tests/stacking/basic-wayland.metatest @@ -0,0 +1,22 @@ +new_client 1 wayland +create 1/1 +show 1/1 +create 1/2 +show 1/2 +wait +assert_stacking 1/1 1/2 + +# Currently Wayland clients have no wait to bring themselves to the user's +# attention; gtk_window_present() is a no-op with the X11 backend of GTK+ + +# activate 1/1 +# wait +# assert_stacking 1/2 1/1 +# activate 1/2 +# wait +# assert_stacking 1/1 1/2 + +local_activate 1/1 +assert_stacking 1/2 1/1 +local_activate 1/2 +assert_stacking 1/1 1/2 diff --git a/src/tests/stacking/basic-x11.metatest b/src/tests/stacking/basic-x11.metatest new file mode 100644 index 000000000..ee261ece0 --- /dev/null +++ b/src/tests/stacking/basic-x11.metatest @@ -0,0 +1,19 @@ +new_client 1 x11 +create 1/1 +show 1/1 +create 1/2 +show 1/2 +wait +assert_stacking 1/1 1/2 + +activate 1/1 +wait +assert_stacking 1/2 1/1 +activate 1/2 +wait +assert_stacking 1/1 1/2 + +local_activate 1/1 +assert_stacking 1/2 1/1 +local_activate 1/2 +assert_stacking 1/1 1/2 diff --git a/src/tests/stacking/client-side-decorated.metatest b/src/tests/stacking/client-side-decorated.metatest new file mode 100644 index 000000000..1d5dfc646 --- /dev/null +++ b/src/tests/stacking/client-side-decorated.metatest @@ -0,0 +1,22 @@ +new_client 1 x11 +create 1/1 +show 1/1 +create 1/2 csd +show 1/2 +wait +assert_stacking 1/1 1/2 + +destroy 1/2 +wait +assert_stacking 1/1 + +create 1/2 csd +show 1/2 +create 1/3 csd +show 1/3 +wait +assert_stacking 1/1 1/2 1/3 + +destroy 1/2 +wait +assert_stacking 1/1 1/3 diff --git a/src/tests/stacking/closed-transient-no-input-no-take-focus-parent.metatest b/src/tests/stacking/closed-transient-no-input-no-take-focus-parent.metatest new file mode 100644 index 000000000..0c0649c07 --- /dev/null +++ b/src/tests/stacking/closed-transient-no-input-no-take-focus-parent.metatest @@ -0,0 +1,23 @@ +new_client 1 x11 +create 1/1 +show 1/1 + +create 1/2 csd +set_parent 1/2 1 +can_take_focus 1/2 false +accept_focus 1/2 false +show 1/2 + +create 1/3 csd +set_parent 1/3 2 +show 1/3 + +wait +assert_focused 1/3 +assert_stacking 1/1 1/2 1/3 + +destroy 1/3 + +wait +assert_focused 1/1 +assert_stacking 1/1 1/2 diff --git a/src/tests/stacking/closed-transient-no-input-no-take-focus-parents.metatest b/src/tests/stacking/closed-transient-no-input-no-take-focus-parents.metatest new file mode 100644 index 000000000..6556803e1 --- /dev/null +++ b/src/tests/stacking/closed-transient-no-input-no-take-focus-parents.metatest @@ -0,0 +1,30 @@ +new_client 2 x11 +create 2/1 +show 2/1 +wait + +new_client 1 x11 +create 1/1 +accept_focus 1/1 false +can_take_focus 1/1 false +show 1/1 + +create 1/2 csd +set_parent 1/2 1 +can_take_focus 1/2 false +accept_focus 1/2 false +show 1/2 + +create 1/3 csd +set_parent 1/3 2 +show 1/3 + +wait +assert_focused 1/3 +assert_stacking 2/1 1/1 1/2 1/3 + +destroy 1/3 + +wait +assert_stacking 1/1 1/2 2/1 +assert_focused 2/1 diff --git a/src/tests/stacking/closed-transient-no-input-parent-delayed-focus-default-cancelled.metatest b/src/tests/stacking/closed-transient-no-input-parent-delayed-focus-default-cancelled.metatest new file mode 100644 index 000000000..0c7261fa7 --- /dev/null +++ b/src/tests/stacking/closed-transient-no-input-parent-delayed-focus-default-cancelled.metatest @@ -0,0 +1,36 @@ +new_client 2 x11 +create 2/1 +show 2/1 + +new_client 1 x11 +create 1/1 +show 1/1 + +create 1/2 csd +set_parent 1/2 1 +accept_focus 1/2 false +show 1/2 + +create 1/3 csd +set_parent 1/3 2 +show 1/3 + +wait +assert_focused 1/3 +assert_stacking 2/1 1/1 1/2 1/3 + +destroy 1/3 +dispatch + +assert_focused none +assert_stacking 2/1 1/1 1/2 + +activate 2/1 +wait + +assert_focused 2/1 +assert_stacking 1/1 1/2 2/1 + +sleep 250 +assert_focused 2/1 +assert_stacking 1/1 1/2 2/1 diff --git a/src/tests/stacking/closed-transient-no-input-parent.metatest b/src/tests/stacking/closed-transient-no-input-parent.metatest new file mode 100644 index 000000000..d0f3228d5 --- /dev/null +++ b/src/tests/stacking/closed-transient-no-input-parent.metatest @@ -0,0 +1,30 @@ +new_client 2 x11 +create 2/1 +show 2/1 + +new_client 1 x11 +create 1/1 +show 1/1 + +create 1/2 csd +set_parent 1/2 1 +accept_focus 1/2 false +show 1/2 + +create 1/3 csd +set_parent 1/3 2 +show 1/3 + +wait +assert_focused 1/3 +assert_stacking 2/1 1/1 1/2 1/3 + +destroy 1/3 +dispatch + +assert_focused none +assert_stacking 2/1 1/1 1/2 + +sleep 150 +assert_focused 1/1 +assert_stacking 2/1 1/1 1/2 diff --git a/src/tests/stacking/closed-transient-no-input-parents-queued-default-focus-destroyed.metatest b/src/tests/stacking/closed-transient-no-input-parents-queued-default-focus-destroyed.metatest new file mode 100644 index 000000000..49ecc510f --- /dev/null +++ b/src/tests/stacking/closed-transient-no-input-parents-queued-default-focus-destroyed.metatest @@ -0,0 +1,43 @@ +new_client 0 x11 +create 0/1 +show 0/1 + +new_client 1 x11 +create 1/1 +show 1/1 + +create 1/2 csd +set_parent 1/2 1 +accept_focus 1/2 false +show 1/2 + +create 1/3 csd +set_parent 1/3 2 +accept_focus 1/3 false +show 1/3 + +create 1/4 csd +set_parent 1/4 3 +accept_focus 1/4 false +show 1/4 + +create 1/5 csd +set_parent 1/5 3 +show 1/5 + +wait +assert_focused 1/5 +assert_stacking 0/1 1/1 1/2 1/3 1/4 1/5 + +destroy 1/5 +dispatch + +assert_focused none +assert_stacking 0/1 1/1 1/2 1/3 1/4 + +destroy 1/2 +dispatch + +sleep 450 +assert_focused 1/1 +assert_stacking 0/1 1/1 1/3 1/4 diff --git a/src/tests/stacking/closed-transient-no-input-parents.metatest b/src/tests/stacking/closed-transient-no-input-parents.metatest new file mode 100644 index 000000000..ee9984192 --- /dev/null +++ b/src/tests/stacking/closed-transient-no-input-parents.metatest @@ -0,0 +1,46 @@ +new_client 0 x11 +create 0/1 +show 0/1 + +new_client 1 x11 +create 1/1 +show 1/1 + +create 1/2 csd +set_parent 1/2 1 +accept_focus 1/2 false +show 1/2 + +create 1/3 csd +set_parent 1/3 2 +accept_focus 1/3 false +show 1/3 + +create 1/4 csd +set_parent 1/4 3 +accept_focus 1/4 false +show 1/4 + +create 1/5 csd +set_parent 1/5 3 +show 1/5 + +wait +assert_focused 1/5 +assert_stacking 0/1 1/1 1/2 1/3 1/4 1/5 + +destroy 1/5 +dispatch + +assert_focused none +assert_stacking 0/1 1/1 1/2 1/3 1/4 + +sleep 600 +assert_focused 1/1 +assert_stacking 0/1 1/1 1/2 1/3 1/4 + +destroy 1/3 +wait + +assert_focused 1/1 +assert_stacking 0/1 1/1 1/2 1/4 diff --git a/src/tests/stacking/closed-transient-only-take-focus-parents.metatest b/src/tests/stacking/closed-transient-only-take-focus-parents.metatest new file mode 100644 index 000000000..8aa86700f --- /dev/null +++ b/src/tests/stacking/closed-transient-only-take-focus-parents.metatest @@ -0,0 +1,34 @@ +new_client 0 x11 +create 0/1 +show 0/1 + +new_client 1 x11 +create 1/1 +accept_focus 1/1 false +can_take_focus 1/1 true +accept_take_focus 1/1 true +show 1/1 + +create 1/2 csd +set_parent 1/2 1 +accept_focus 1/2 false +can_take_focus 1/2 true +accept_take_focus 1/2 true +show 1/2 + +create 1/3 +set_parent 1/3 2 +show 1/3 + +assert_focused 1/3 +assert_stacking 0/1 1/1 1/2 1/3 + +destroy 1/3 +wait + +assert_focused 1/2 +assert_stacking 0/1 1/1 1/2 + +sleep 150 +assert_focused 1/2 +assert_stacking 0/1 1/1 1/2 diff --git a/src/tests/stacking/closed-transient.metatest b/src/tests/stacking/closed-transient.metatest new file mode 100644 index 000000000..5ca95ba0f --- /dev/null +++ b/src/tests/stacking/closed-transient.metatest @@ -0,0 +1,19 @@ +new_client 1 wayland +create 1/1 +show 1/1 + +new_client 2 wayland +create 2/1 +show 2/1 + +create 1/2 +show 1/2 +set_parent 1/2 1 + +wait +assert_stacking 1/1 2/1 1/2 + +destroy 1/2 + +wait +assert_stacking 2/1 1/1 diff --git a/src/tests/stacking/minimized.metatest b/src/tests/stacking/minimized.metatest new file mode 100644 index 000000000..3da236d19 --- /dev/null +++ b/src/tests/stacking/minimized.metatest @@ -0,0 +1,18 @@ +new_client 1 x11 +create 1/1 +show 1/1 +create 1/2 +show 1/2 +wait +assert_stacking 1/1 1/2 + +minimize 1/2 +wait +assert_stacking 1/2 | 1/1 + +# unminimize doesn't work for GTK+ currently, because GTK+ expects +# to be able to de-iconify with MapWindow, but the window is already +# mapped. +activate 1/2 +wait +assert_stacking 1/1 1/2 diff --git a/src/tests/stacking/mixed-windows.metatest b/src/tests/stacking/mixed-windows.metatest new file mode 100644 index 000000000..38058b582 --- /dev/null +++ b/src/tests/stacking/mixed-windows.metatest @@ -0,0 +1,26 @@ +new_client w wayland +new_client x x11 + +create w/1 +show w/1 +create w/2 +show w/2 +wait + +create x/1 +show x/1 +create x/2 +show x/2 +wait + +assert_stacking w/1 w/2 x/1 x/2 + +local_activate w/1 +assert_stacking w/2 x/1 x/2 w/1 + +local_activate x/1 +assert_stacking w/2 x/2 w/1 x/1 + +lower x/1 +wait +assert_stacking x/1 w/2 x/2 w/1 diff --git a/src/tests/stacking/override-redirect.metatest b/src/tests/stacking/override-redirect.metatest new file mode 100644 index 000000000..b313d240b --- /dev/null +++ b/src/tests/stacking/override-redirect.metatest @@ -0,0 +1,19 @@ +new_client 1 x11 +create 1/1 +show 1/1 +create 1/2 override +show 1/2 +wait +assert_stacking 1/1 1/2 + +activate 1/1 +wait +assert_stacking 1/1 1/2 + +lower 1/2 +wait +assert_stacking 1/2 | 1/1 + +raise 1/2 +wait +assert_stacking 1/1 1/2 diff --git a/src/tests/stacking/set-override-redirect-parent.metatest b/src/tests/stacking/set-override-redirect-parent.metatest new file mode 100644 index 000000000..4c98bee22 --- /dev/null +++ b/src/tests/stacking/set-override-redirect-parent.metatest @@ -0,0 +1,37 @@ +new_client 1 x11 +create 1/1 override +show 1/1 + +create 1/2 +set_parent 1/2 1 +show 1/2 + +create 1/3 +set_parent 1/3 2 +show 1/3 + + +new_client 2 x11 +create 2/1 +show 2/1 + +create 2/2 override +set_parent 2/2 1 +show 2/2 + +create 2/3 +set_parent 2/3 2 +show 2/3 + + +new_client 3 x11 +create 3/1 override +show 3/1 + +create 3/2 override +set_parent 3/2 1 +show 3/2 + +create 3/3 override +set_parent 3/3 2 +show 3/3 diff --git a/src/tests/stacking/set-parent-exported.metatest b/src/tests/stacking/set-parent-exported.metatest new file mode 100644 index 000000000..8dbb9c932 --- /dev/null +++ b/src/tests/stacking/set-parent-exported.metatest @@ -0,0 +1,15 @@ +new_client 1 wayland +create 1/1 +show 1/1 +create 1/2 +show 1/2 +wait + +set_parent_exported 1/1 2 +wait +assert_stacking 1/2 1/1 + +local_activate 1/2 +assert_stacking 1/2 1/1 + +destroy 1/2 diff --git a/src/tests/stacking/set-parent.metatest b/src/tests/stacking/set-parent.metatest new file mode 100644 index 000000000..e95eaca29 --- /dev/null +++ b/src/tests/stacking/set-parent.metatest @@ -0,0 +1,14 @@ +new_client 1 wayland +create 1/1 +show 1/1 +create 1/2 +show 1/2 +wait +assert_stacking 1/1 1/2 + +set_parent 1/1 2 +wait +assert_stacking 1/2 1/1 + +local_activate 1/2 +assert_stacking 1/2 1/1 diff --git a/src/tests/test-client.c b/src/tests/test-client.c new file mode 100644 index 000000000..83a5ce485 --- /dev/null +++ b/src/tests/test-client.c @@ -0,0 +1,787 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <gio/gunixinputstream.h> +#include <gtk/gtk.h> +#include <gdk/gdkx.h> +#include <gdk/gdkwayland.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <X11/extensions/sync.h> + +const char *client_id = "0"; +static gboolean wayland; +GHashTable *windows; +GQuark event_source_quark; +GQuark event_handlers_quark; +GQuark can_take_focus_quark; + +typedef void (*XEventHandler) (GtkWidget *window, XEvent *event); + +static void read_next_line (GDataInputStream *in); + +static void +window_export_handle_cb (GdkWindow *window, + const char *handle_str, + gpointer user_data) +{ + GdkWindow *gdk_window = gtk_widget_get_window (GTK_WIDGET (user_data)); + + if (!gdk_wayland_window_set_transient_for_exported (gdk_window, + (gchar *) handle_str)) + g_print ("Fail to set transient_for exported window handle %s", handle_str); + gdk_window_set_modal_hint (gdk_window, TRUE); +} + +static GtkWidget * +lookup_window (const char *window_id) +{ + GtkWidget *window = g_hash_table_lookup (windows, window_id); + if (!window) + g_print ("Window %s doesn't exist", window_id); + + return window; +} + +typedef struct { + GSource base; + GSource **self_ref; + GPollFD event_poll_fd; + Display *xdisplay; +} XClientEventSource; + +static gboolean +x_event_source_prepare (GSource *source, + int *timeout) +{ + XClientEventSource *x_source = (XClientEventSource *) source; + + *timeout = -1; + + return XPending (x_source->xdisplay); +} + +static gboolean +x_event_source_check (GSource *source) +{ + XClientEventSource *x_source = (XClientEventSource *) source; + + return XPending (x_source->xdisplay); +} + +static gboolean +x_event_source_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + XClientEventSource *x_source = (XClientEventSource *) source; + + while (XPending (x_source->xdisplay)) + { + GHashTableIter iter; + XEvent event; + gpointer value; + + XNextEvent (x_source->xdisplay, &event); + + g_hash_table_iter_init (&iter, windows); + while (g_hash_table_iter_next (&iter, NULL, &value)) + { + GList *l; + GtkWidget *window = value; + GList *handlers = + g_object_get_qdata (G_OBJECT (window), event_handlers_quark); + + for (l = handlers; l; l = l->next) + { + XEventHandler handler = l->data; + handler (window, &event); + } + } + } + + return TRUE; +} + +static void +x_event_source_finalize (GSource *source) +{ + XClientEventSource *x_source = (XClientEventSource *) source; + + *x_source->self_ref = NULL; +} + +static GSourceFuncs x_event_funcs = { + x_event_source_prepare, + x_event_source_check, + x_event_source_dispatch, + x_event_source_finalize, +}; + +static GSource* +ensure_xsource_handler (GdkDisplay *gdkdisplay) +{ + static GSource *source = NULL; + Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdkdisplay); + XClientEventSource *x_source; + + if (source) + return g_source_ref (source); + + source = g_source_new (&x_event_funcs, sizeof (XClientEventSource)); + x_source = (XClientEventSource *) source; + x_source->self_ref = &source; + x_source->xdisplay = xdisplay; + x_source->event_poll_fd.fd = ConnectionNumber (xdisplay); + x_source->event_poll_fd.events = G_IO_IN; + g_source_add_poll (source, &x_source->event_poll_fd); + + g_source_set_priority (source, GDK_PRIORITY_EVENTS - 1); + g_source_set_can_recurse (source, TRUE); + g_source_attach (source, NULL); + + return source; +} + +static gboolean +window_has_x11_event_handler (GtkWidget *window, + XEventHandler handler) +{ + GList *handlers = + g_object_get_qdata (G_OBJECT (window), event_handlers_quark); + + g_return_val_if_fail (handler, FALSE); + g_return_val_if_fail (!wayland, FALSE); + + return g_list_find (handlers, handler) != NULL; +} + +static void +unref_and_maybe_destroy_gsource (GSource *source) +{ + g_source_unref (source); + + if (source->ref_count == 1) + g_source_destroy (source); +} + +static void +window_add_x11_event_handler (GtkWidget *window, + XEventHandler handler) +{ + GSource *source; + GList *handlers = + g_object_get_qdata (G_OBJECT (window), event_handlers_quark); + + g_return_if_fail (!window_has_x11_event_handler (window, handler)); + + source = ensure_xsource_handler (gtk_widget_get_display (window)); + g_object_set_qdata_full (G_OBJECT (window), event_source_quark, source, + (GDestroyNotify) unref_and_maybe_destroy_gsource); + + handlers = g_list_append (handlers, handler); + g_object_set_qdata (G_OBJECT (window), event_handlers_quark, handlers); +} + +static void +window_remove_x11_event_handler (GtkWidget *window, + XEventHandler handler) +{ + GList *handlers = + g_object_get_qdata (G_OBJECT (window), event_handlers_quark); + + g_return_if_fail (window_has_x11_event_handler (window, handler)); + + g_object_set_qdata (G_OBJECT (window), event_source_quark, NULL); + + handlers = g_list_remove (handlers, handler); + g_object_set_qdata (G_OBJECT (window), event_handlers_quark, handlers); +} + +static void +handle_take_focus (GtkWidget *window, + XEvent *xevent) +{ + GdkWindow *gdkwindow = gtk_widget_get_window (window); + GdkDisplay *display = gtk_widget_get_display (window); + Atom wm_protocols = + gdk_x11_get_xatom_by_name_for_display (display, "WM_PROTOCOLS"); + Atom wm_take_focus = + gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS"); + + if (xevent->xany.type != ClientMessage || + xevent->xany.window != GDK_WINDOW_XID (gdkwindow)) + return; + + if (xevent->xclient.message_type == wm_protocols && + xevent->xclient.data.l[0] == wm_take_focus) + { + XSetInputFocus (xevent->xany.display, + GDK_WINDOW_XID (gdkwindow), + RevertToParent, + xevent->xclient.data.l[1]); + } +} + +static void +process_line (const char *line) +{ + GError *error = NULL; + int argc; + char **argv; + + if (!g_shell_parse_argv (line, &argc, &argv, &error)) + { + g_print ("error parsing command: %s", error->message); + g_error_free (error); + return; + } + + if (argc < 1) + { + g_print ("Empty command"); + goto out; + } + + if (strcmp (argv[0], "create") == 0) + { + int i; + + if (argc < 2) + { + g_print ("usage: create <id> [override|csd]"); + goto out; + } + + if (g_hash_table_lookup (windows, argv[1])) + { + g_print ("window %s already exists", argv[1]); + goto out; + } + + gboolean override = FALSE; + gboolean csd = FALSE; + for (i = 2; i < argc; i++) + { + if (strcmp (argv[i], "override") == 0) + override = TRUE; + if (strcmp (argv[i], "csd") == 0) + csd = TRUE; + } + + if (override && csd) + { + g_print ("override and csd keywords are exclusie"); + goto out; + } + + GtkWidget *window = gtk_window_new (override ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL); + g_hash_table_insert (windows, g_strdup (argv[1]), window); + + if (csd) + { + GtkWidget *headerbar = gtk_header_bar_new (); + gtk_window_set_titlebar (GTK_WINDOW (window), headerbar); + gtk_widget_show (headerbar); + } + + gtk_window_set_default_size (GTK_WINDOW (window), 100, 100); + + gchar *title = g_strdup_printf ("test/%s/%s", client_id, argv[1]); + gtk_window_set_title (GTK_WINDOW (window), title); + g_free (title); + + g_object_set_qdata (G_OBJECT (window), can_take_focus_quark, + GUINT_TO_POINTER (TRUE)); + + gtk_widget_realize (window); + + if (!wayland) + { + /* The cairo xlib backend creates a window when initialized, which + * confuses our testing if it happens asynchronously the first + * time a window is painted. By creating an Xlib surface and + * destroying it, we force initialization at a more predictable time. + */ + GdkWindow *window_gdk = gtk_widget_get_window (window); + cairo_surface_t *surface = gdk_window_create_similar_surface (window_gdk, + CAIRO_CONTENT_COLOR, + 1, 1); + cairo_surface_destroy (surface); + } + + } + else if (strcmp (argv[0], "set_parent") == 0) + { + if (argc != 3) + { + g_print ("usage: set_parent <window-id> <parent-id>"); + goto out; + } + + GtkWidget *window = lookup_window (argv[1]); + if (!window) + { + g_print ("unknown window %s", argv[1]); + goto out; + } + + GtkWidget *parent_window = lookup_window (argv[2]); + if (!parent_window) + { + g_print ("unknown parent window %s", argv[2]); + goto out; + } + + gtk_window_set_transient_for (GTK_WINDOW (window), + GTK_WINDOW (parent_window)); + } + else if (strcmp (argv[0], "set_parent_exported") == 0) + { + if (argc != 3) + { + g_print ("usage: set_parent_exported <window-id> <parent-id>"); + goto out; + } + + GtkWidget *window = lookup_window (argv[1]); + if (!window) + { + g_print ("unknown window %s", argv[1]); + goto out; + } + + GtkWidget *parent_window = lookup_window (argv[2]); + if (!parent_window) + { + g_print ("unknown parent window %s", argv[2]); + goto out; + } + + GdkWindow *parent_gdk_window = gtk_widget_get_window (parent_window); + if (!gdk_wayland_window_export_handle (parent_gdk_window, + window_export_handle_cb, + window, + NULL)) + g_print ("Fail to export handle for window id %s", argv[2]); + } + else if (strcmp (argv[0], "accept_focus") == 0) + { + if (argc != 3) + { + g_print ("usage: %s <window-id> [true|false]", argv[0]); + goto out; + } + + GtkWidget *window = lookup_window (argv[1]); + if (!window) + { + g_print ("unknown window %s", argv[1]); + goto out; + } + + if (!wayland && + window_has_x11_event_handler (window, handle_take_focus)) + { + g_print ("Impossible to use %s for windows accepting take focus", + argv[1]); + goto out; + } + + gboolean enabled = g_ascii_strcasecmp (argv[2], "true") == 0; + gtk_window_set_accept_focus (GTK_WINDOW (window), enabled); + } + else if (strcmp (argv[0], "can_take_focus") == 0) + { + if (argc != 3) + { + g_print ("usage: %s <window-id> [true|false]", argv[0]); + goto out; + } + + GtkWidget *window = lookup_window (argv[1]); + if (!window) + { + g_print ("unknown window %s", argv[1]); + goto out; + } + + if (wayland) + { + g_print ("%s not supported under wayland", argv[0]); + goto out; + } + + if (window_has_x11_event_handler (window, handle_take_focus)) + { + g_print ("Impossible to change %s for windows accepting take focus", + argv[1]); + goto out; + } + + GdkDisplay *display = gdk_display_get_default (); + GdkWindow *gdkwindow = gtk_widget_get_window (window); + Display *xdisplay = gdk_x11_display_get_xdisplay (display); + Window xwindow = GDK_WINDOW_XID (gdkwindow); + Atom wm_take_focus = gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS"); + gboolean add = g_ascii_strcasecmp(argv[2], "true") == 0; + Atom *protocols = NULL; + Atom *new_protocols; + int n_protocols = 0; + int i, n = 0; + + gdk_display_sync (display); + XGetWMProtocols (xdisplay, xwindow, &protocols, &n_protocols); + new_protocols = g_new0 (Atom, n_protocols + (add ? 1 : 0)); + + for (i = 0; i < n_protocols; ++i) + { + if (protocols[i] != wm_take_focus) + new_protocols[n++] = protocols[i]; + } + + if (add) + new_protocols[n++] = wm_take_focus; + + XSetWMProtocols (xdisplay, xwindow, new_protocols, n); + g_object_set_qdata (G_OBJECT (window), can_take_focus_quark, + GUINT_TO_POINTER (add)); + + XFree (new_protocols); + XFree (protocols); + } + else if (strcmp (argv[0], "accept_take_focus") == 0) + { + if (argc != 3) + { + g_print ("usage: %s <window-id> [true|false]", argv[0]); + goto out; + } + + GtkWidget *window = lookup_window (argv[1]); + if (!window) + { + g_print ("unknown window %s", argv[1]); + goto out; + } + + if (wayland) + { + g_print ("%s not supported under wayland", argv[0]); + goto out; + } + + if (gtk_window_get_accept_focus (GTK_WINDOW (window))) + { + g_print ("%s not supported for input windows", argv[0]); + goto out; + } + + if (!g_object_get_qdata (G_OBJECT (window), can_take_focus_quark)) + { + g_print ("%s not supported for windows with no WM_TAKE_FOCUS set", + argv[0]); + goto out; + } + + if (g_ascii_strcasecmp (argv[2], "true") == 0) + window_add_x11_event_handler (window, handle_take_focus); + else + window_remove_x11_event_handler (window, handle_take_focus); + } + else if (strcmp (argv[0], "show") == 0) + { + if (argc != 2) + { + g_print ("usage: show <id>"); + goto out; + } + + GtkWidget *window = lookup_window (argv[1]); + if (!window) + goto out; + + gtk_widget_show (window); + gdk_display_sync (gdk_display_get_default ()); + } + else if (strcmp (argv[0], "hide") == 0) + { + if (argc != 2) + { + g_print ("usage: hide <id>"); + goto out; + } + + GtkWidget *window = lookup_window (argv[1]); + if (!window) + goto out; + + gtk_widget_hide (window); + } + else if (strcmp (argv[0], "activate") == 0) + { + if (argc != 2) + { + g_print ("usage: activate <id>"); + goto out; + } + + GtkWidget *window = lookup_window (argv[1]); + if (!window) + goto out; + + gtk_window_present (GTK_WINDOW (window)); + } + else if (strcmp (argv[0], "resize") == 0) + { + if (argc != 4) + { + g_print ("usage: resize <id> <width> <height>"); + goto out; + } + + GtkWidget *window = lookup_window (argv[1]); + if (!window) + goto out; + + int width = atoi (argv[2]); + int height = atoi (argv[3]); + gtk_window_resize (GTK_WINDOW (window), width, height); + } + else if (strcmp (argv[0], "raise") == 0) + { + if (argc != 2) + { + g_print ("usage: raise <id>"); + goto out; + } + + GtkWidget *window = lookup_window (argv[1]); + if (!window) + goto out; + + gdk_window_raise (gtk_widget_get_window (window)); + } + else if (strcmp (argv[0], "lower") == 0) + { + if (argc != 2) + { + g_print ("usage: lower <id>"); + goto out; + } + + GtkWidget *window = lookup_window (argv[1]); + if (!window) + goto out; + + gdk_window_lower (gtk_widget_get_window (window)); + } + else if (strcmp (argv[0], "destroy") == 0) + { + if (argc != 2) + { + g_print ("usage: destroy <id>"); + goto out; + } + + GtkWidget *window = lookup_window (argv[1]); + if (!window) + goto out; + + g_hash_table_remove (windows, argv[1]); + gtk_widget_destroy (window); + } + else if (strcmp (argv[0], "destroy_all") == 0) + { + if (argc != 1) + { + g_print ("usage: destroy_all"); + goto out; + } + + GHashTableIter iter; + gpointer key, value; + + g_hash_table_iter_init (&iter, windows); + while (g_hash_table_iter_next (&iter, &key, &value)) + gtk_widget_destroy (value); + + g_hash_table_remove_all (windows); + } + else if (strcmp (argv[0], "sync") == 0) + { + if (argc != 1) + { + g_print ("usage: sync"); + goto out; + } + + gdk_display_sync (gdk_display_get_default ()); + } + else if (strcmp (argv[0], "set_counter") == 0) + { + XSyncCounter counter; + int value; + + if (argc != 3) + { + g_print ("usage: set_counter <counter> <value>"); + goto out; + } + + if (wayland) + { + g_print ("usage: set_counter can only be used for X11"); + goto out; + } + + counter = strtoul(argv[1], NULL, 10); + value = atoi(argv[2]); + XSyncValue sync_value; + XSyncIntToValue (&sync_value, value); + + XSyncSetCounter (gdk_x11_display_get_xdisplay (gdk_display_get_default ()), + counter, sync_value); + } + else if (strcmp (argv[0], "minimize") == 0) + { + if (argc != 2) + { + g_print ("usage: minimize <id>"); + goto out; + } + + GtkWidget *window = lookup_window (argv[1]); + if (!window) + goto out; + + gtk_window_iconify (GTK_WINDOW (window)); + } + else if (strcmp (argv[0], "unminimize") == 0) + { + if (argc != 2) + { + g_print ("usage: unminimize <id>"); + goto out; + } + + GtkWidget *window = lookup_window (argv[1]); + if (!window) + goto out; + + gtk_window_deiconify (GTK_WINDOW (window)); + } + else + { + g_print ("Unknown command %s", argv[0]); + goto out; + } + + g_print ("OK\n"); + + out: + g_strfreev (argv); +} + +static void +on_line_received (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GDataInputStream *in = G_DATA_INPUT_STREAM (source); + GError *error = NULL; + gsize length; + char *line = g_data_input_stream_read_line_finish_utf8 (in, result, &length, &error); + + if (line == NULL) + { + if (error != NULL) + g_printerr ("Error reading from stdin: %s\n", error->message); + gtk_main_quit (); + return; + } + + process_line (line); + g_free (line); + read_next_line (in); +} + +static void +read_next_line (GDataInputStream *in) +{ + g_data_input_stream_read_line_async (in, G_PRIORITY_DEFAULT, NULL, + on_line_received, NULL); +} + +const GOptionEntry options[] = { + { + "wayland", 0, 0, G_OPTION_ARG_NONE, + &wayland, + "Create a wayland client, not an X11 one", + NULL + }, + { + "client-id", 0, 0, G_OPTION_ARG_STRING, + &client_id, + "Identifier used in Window titles for this client", + "CLIENT_ID", + }, + { NULL } +}; + +int +main(int argc, char **argv) +{ + GOptionContext *context = g_option_context_new (NULL); + GError *error = NULL; + + g_option_context_add_main_entries (context, options, NULL); + + if (!g_option_context_parse (context, + &argc, &argv, &error)) + { + g_printerr ("%s", error->message); + return 1; + } + + if (wayland) + gdk_set_allowed_backends ("wayland"); + else + gdk_set_allowed_backends ("x11"); + + gtk_init (NULL, NULL); + + windows = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, NULL); + event_source_quark = g_quark_from_static_string ("event-source"); + event_handlers_quark = g_quark_from_static_string ("event-handlers"); + can_take_focus_quark = g_quark_from_static_string ("can-take-focus"); + + GInputStream *raw_in = g_unix_input_stream_new (0, FALSE); + GDataInputStream *in = g_data_input_stream_new (raw_in); + + read_next_line (in); + + gtk_main (); + + return 0; +} diff --git a/src/tests/test-runner.c b/src/tests/test-runner.c new file mode 100644 index 000000000..950556233 --- /dev/null +++ b/src/tests/test-runner.c @@ -0,0 +1,908 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <gio/gio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> + +#include "compositor/meta-plugin-manager.h" +#include "core/window-private.h" +#include "meta/main.h" +#include "meta/util.h" +#include "meta/window.h" +#include "tests/test-utils.h" +#include "ui/ui.h" +#include "wayland/meta-wayland.h" +#include "x11/meta-x11-display-private.h" + +typedef struct { + GHashTable *clients; + AsyncWaiter *waiter; + GString *warning_messages; + GMainLoop *loop; +} TestCase; + +static gboolean +test_case_alarm_filter (MetaX11Display *x11_display, + XSyncAlarmNotifyEvent *event, + gpointer data) +{ + TestCase *test = data; + GHashTableIter iter; + gpointer key, value; + + if (async_waiter_alarm_filter (x11_display, event, test->waiter)) + return TRUE; + + g_hash_table_iter_init (&iter, test->clients); + while (g_hash_table_iter_next (&iter, &key, &value)) + if (test_client_alarm_filter (x11_display, event, value)) + return TRUE; + + return FALSE; +} + +static TestCase * +test_case_new (void) +{ + TestCase *test = g_new0 (TestCase, 1); + + test_wait_for_x11_display (); + + meta_x11_display_set_alarm_filter (meta_get_display ()->x11_display, + test_case_alarm_filter, test); + + test->clients = g_hash_table_new (g_str_hash, g_str_equal); + test->waiter = async_waiter_new (); + test->loop = g_main_loop_new (NULL, FALSE); + + return test; +} + +static gboolean +test_case_loop_quit (gpointer data) +{ + TestCase *test = data; + + g_main_loop_quit (test->loop); + + return FALSE; +} + +static gboolean +test_case_dispatch (TestCase *test, + GError **error) +{ + /* Wait until we've done any outstanding queued up work. + * Though we add this as BEFORE_REDRAW, the iteration that runs the + * BEFORE_REDRAW idles will proceed on and do the redraw, so we're + * waiting until after *all* frame processing. + */ + meta_later_add (META_LATER_BEFORE_REDRAW, + test_case_loop_quit, + test, + NULL); + g_main_loop_run (test->loop); + + return TRUE; +} + +static gboolean +test_case_wait (TestCase *test, + GError **error) +{ + GHashTableIter iter; + gpointer key, value; + + /* First have each client set a XSync counter, and wait until + * we receive the resulting event - so we know we've received + * everything that the client have sent us. + */ + g_hash_table_iter_init (&iter, test->clients); + while (g_hash_table_iter_next (&iter, &key, &value)) + if (!test_client_wait (value, error)) + return FALSE; + + /* Then wait until we've done any outstanding queued up work. */ + test_case_dispatch (test, error); + + /* Then set an XSync counter ourselves and and wait until + * we receive the resulting event - this makes sure that we've + * received back any X events we generated. + */ + async_waiter_set_and_wait (test->waiter); + return TRUE; +} + +static gboolean +test_case_sleep (TestCase *test, + guint32 interval, + GError **error) +{ + g_timeout_add_full (G_PRIORITY_LOW, interval, test_case_loop_quit, test, NULL); + g_main_loop_run (test->loop); + + return TRUE; +} + +#define BAD_COMMAND(...) \ + G_STMT_START { \ + g_set_error (error, \ + TEST_RUNNER_ERROR, TEST_RUNNER_ERROR_BAD_COMMAND, \ + __VA_ARGS__); \ + return FALSE; \ + } G_STMT_END + +static TestClient * +test_case_lookup_client (TestCase *test, + char *client_id, + GError **error) +{ + TestClient *client = g_hash_table_lookup (test->clients, client_id); + if (!client) + g_set_error (error, TEST_RUNNER_ERROR, TEST_RUNNER_ERROR_BAD_COMMAND, + "No such client %s", client_id); + + return client; +} + +static gboolean +test_case_parse_window_id (TestCase *test, + const char *client_and_window_id, + TestClient **client, + const char **window_id, + GError **error) +{ + const char *slash = strchr (client_and_window_id, '/'); + char *tmp; + if (slash == NULL) + BAD_COMMAND ("client/window ID %s doesnt' contain a /", client_and_window_id); + + *window_id = slash + 1; + + tmp = g_strndup (client_and_window_id, slash - client_and_window_id); + *client = test_case_lookup_client (test, tmp, error); + g_free (tmp); + + return client != NULL; +} + +static gboolean +test_case_assert_stacking (TestCase *test, + char **expected_windows, + int n_expected_windows, + GError **error) +{ + MetaDisplay *display = meta_get_display (); + guint64 *windows; + int n_windows; + GString *stack_string = g_string_new (NULL); + GString *expected_string = g_string_new (NULL); + int i; + + meta_stack_tracker_get_stack (display->stack_tracker, &windows, &n_windows); + for (i = 0; i < n_windows; i++) + { + MetaWindow *window = meta_display_lookup_stack_id (display, windows[i]); + if (window != NULL && window->title) + { + /* See comment in meta_ui_new() about why the dummy window for GTK+ theming + * is managed as a MetaWindow. + */ + if (META_STACK_ID_IS_X11 (windows[i]) && + meta_ui_window_is_dummy (display->x11_display->ui, windows[i])) + continue; + + if (stack_string->len > 0) + g_string_append_c (stack_string, ' '); + + if (g_str_has_prefix (window->title, "test/")) + g_string_append (stack_string, window->title + 5); + else + g_string_append_printf (stack_string, "(%s)", window->title); + } + else if (windows[i] == display->x11_display->guard_window) + { + if (stack_string->len > 0) + g_string_append_c (stack_string, ' '); + + g_string_append_c (stack_string, '|'); + } + } + + for (i = 0; i < n_expected_windows; i++) + { + if (expected_string->len > 0) + g_string_append_c (expected_string, ' '); + + g_string_append (expected_string, expected_windows[i]); + } + + /* Don't require '| ' as a prefix if there are no hidden windows - we + * remove the prefix from the actual string instead of adding it to the + * expected string for clarity of the error message + */ + if (index (expected_string->str, '|') == NULL && stack_string->str[0] == '|') + { + g_string_erase (stack_string, + 0, stack_string->str[1] == ' ' ? 2 : 1); + } + + if (strcmp (expected_string->str, stack_string->str) != 0) + { + g_set_error (error, TEST_RUNNER_ERROR, TEST_RUNNER_ERROR_ASSERTION_FAILED, + "stacking: expected='%s', actual='%s'", + expected_string->str, stack_string->str); + } + + g_string_free (stack_string, TRUE); + g_string_free (expected_string, TRUE); + + return *error == NULL; +} + +static gboolean +test_case_assert_focused (TestCase *test, + const char *expected_window, + GError **error) +{ + MetaDisplay *display = meta_get_display (); + + if (!display->focus_window) + { + if (g_strcmp0 (expected_window, "none") != 0) + { + g_set_error (error, TEST_RUNNER_ERROR, TEST_RUNNER_ERROR_ASSERTION_FAILED, + "focus: expected='%s', actual='none'", expected_window); + } + } + else + { + const char *focused = display->focus_window->title; + + if (g_str_has_prefix (focused, "test/")) + focused += 5; + + if (g_strcmp0 (focused, expected_window) != 0) + g_set_error (error, TEST_RUNNER_ERROR, TEST_RUNNER_ERROR_ASSERTION_FAILED, + "focus: expected='%s', actual='%s'", + expected_window, focused); + } + + return *error == NULL; +} + +static gboolean +test_case_check_xserver_stacking (TestCase *test, + GError **error) +{ + MetaDisplay *display = meta_get_display (); + GString *local_string = g_string_new (NULL); + GString *x11_string = g_string_new (NULL); + int i; + + guint64 *windows; + int n_windows; + meta_stack_tracker_get_stack (display->stack_tracker, &windows, &n_windows); + + for (i = 0; i < n_windows; i++) + { + if (META_STACK_ID_IS_X11 (windows[i])) + { + if (local_string->len > 0) + g_string_append_c (local_string, ' '); + + g_string_append_printf (local_string, "%#lx", (Window)windows[i]); + } + } + + Window root; + Window parent; + Window *children; + unsigned int n_children; + XQueryTree (display->x11_display->xdisplay, + display->x11_display->xroot, + &root, &parent, &children, &n_children); + + for (i = 0; i < (int)n_children; i++) + { + if (x11_string->len > 0) + g_string_append_c (x11_string, ' '); + + g_string_append_printf (x11_string, "%#lx", (Window)children[i]); + } + + if (strcmp (x11_string->str, local_string->str) != 0) + g_set_error (error, TEST_RUNNER_ERROR, TEST_RUNNER_ERROR_ASSERTION_FAILED, + "xserver stacking: x11='%s', local='%s'", + x11_string->str, local_string->str); + + XFree (children); + + g_string_free (local_string, TRUE); + g_string_free (x11_string, TRUE); + + return *error == NULL; +} + +static gboolean +test_case_do (TestCase *test, + int argc, + char **argv, + GError **error) +{ + if (strcmp (argv[0], "new_client") == 0) + { + MetaWindowClientType type; + TestClient *client; + + if (argc != 3) + BAD_COMMAND("usage: new_client <client-id> [wayland|x11]"); + + if (strcmp (argv[2], "x11") == 0) + type = META_WINDOW_CLIENT_TYPE_X11; + else if (strcmp (argv[2], "wayland") == 0) + type = META_WINDOW_CLIENT_TYPE_WAYLAND; + else + BAD_COMMAND("usage: new_client <client-id> [wayland|x11]"); + + if (g_hash_table_lookup (test->clients, argv[1])) + BAD_COMMAND("client %s already exists", argv[1]); + + client = test_client_new (argv[1], type, error); + if (!client) + return FALSE; + + g_hash_table_insert (test->clients, test_client_get_id (client), client); + } + else if (strcmp (argv[0], "quit_client") == 0) + { + if (argc != 2) + BAD_COMMAND("usage: quit_client <client-id>"); + + TestClient *client = test_case_lookup_client (test, argv[1], error); + if (!client) + return FALSE; + + if (!test_client_quit (client, error)) + return FALSE; + + g_hash_table_remove (test->clients, test_client_get_id (client)); + test_client_destroy (client); + } + else if (strcmp (argv[0], "create") == 0) + { + if (!(argc == 2 || + (argc == 3 && strcmp (argv[2], "override") == 0) || + (argc == 3 && strcmp (argv[2], "csd") == 0))) + BAD_COMMAND("usage: %s <client-id>/<window-id > [override|csd]", argv[0]); + + TestClient *client; + const char *window_id; + if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error)) + return FALSE; + + if (!test_client_do (client, error, + "create", window_id, + argc == 3 ? argv[2] : NULL, + NULL)) + return FALSE; + + if (!test_client_wait (client, error)) + return FALSE; + } + else if (strcmp (argv[0], "set_parent") == 0 || + strcmp (argv[0], "set_parent_exported") == 0) + { + if (argc != 3) + BAD_COMMAND("usage: %s <client-id>/<window-id> <parent-window-id>", + argv[0]); + + TestClient *client; + const char *window_id; + if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error)) + return FALSE; + + if (!test_client_do (client, error, + argv[0], window_id, + argv[2], + NULL)) + return FALSE; + } + else if (strcmp (argv[0], "accept_focus") == 0) + { + if (argc != 3 || + (g_ascii_strcasecmp (argv[2], "true") != 0 && + g_ascii_strcasecmp (argv[2], "false") != 0)) + BAD_COMMAND("usage: %s <client-id>/<window-id> [true|false]", + argv[0]); + + TestClient *client; + const char *window_id; + if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error)) + return FALSE; + + if (!test_client_do (client, error, + argv[0], window_id, + argv[2], + NULL)) + return FALSE; + } + else if (strcmp (argv[0], "can_take_focus") == 0) + { + if (argc != 3 || + (g_ascii_strcasecmp (argv[2], "true") != 0 && + g_ascii_strcasecmp (argv[2], "false") != 0)) + BAD_COMMAND("usage: %s <client-id>/<window-id> [true|false]", + argv[0]); + + TestClient *client; + const char *window_id; + if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error)) + return FALSE; + + if (!test_client_do (client, error, + argv[0], window_id, + argv[2], + NULL)) + return FALSE; + } + else if (strcmp (argv[0], "accept_take_focus") == 0) + { + if (argc != 3 || + (g_ascii_strcasecmp (argv[2], "true") != 0 && + g_ascii_strcasecmp (argv[2], "false") != 0)) + BAD_COMMAND("usage: %s <client-id>/<window-id> [true|false]", + argv[0]); + + TestClient *client; + const char *window_id; + if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error)) + return FALSE; + + if (!test_client_do (client, error, + argv[0], window_id, + argv[2], + NULL)) + return FALSE; + } + else if (strcmp (argv[0], "show") == 0) + { + if (argc != 2) + BAD_COMMAND("usage: %s <client-id>/<window-id>", argv[0]); + + TestClient *client; + const char *window_id; + if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error)) + return FALSE; + + if (!test_client_do (client, error, argv[0], window_id, NULL)) + return FALSE; + + MetaWindow *window = test_client_find_window (client, window_id, error); + if (!window) + return FALSE; + + test_client_wait_for_window_shown (client, window); + } + else if (strcmp (argv[0], "hide") == 0 || + strcmp (argv[0], "activate") == 0 || + strcmp (argv[0], "raise") == 0 || + strcmp (argv[0], "lower") == 0 || + strcmp (argv[0], "minimize") == 0 || + strcmp (argv[0], "unminimize") == 0 || + strcmp (argv[0], "destroy") == 0) + { + if (argc != 2) + BAD_COMMAND("usage: %s <client-id>/<window-id>", argv[0]); + + TestClient *client; + const char *window_id; + if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error)) + return FALSE; + + if (!test_client_do (client, error, argv[0], window_id, NULL)) + return FALSE; + } + else if (strcmp (argv[0], "local_activate") == 0) + { + if (argc != 2) + BAD_COMMAND("usage: %s <client-id>/<window-id>", argv[0]); + + TestClient *client; + const char *window_id; + if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error)) + return FALSE; + + MetaWindow *window = test_client_find_window (client, window_id, error); + if (!window) + return FALSE; + + meta_window_activate (window, 0); + } + else if (strcmp (argv[0], "wait") == 0) + { + if (argc != 1) + BAD_COMMAND("usage: %s", argv[0]); + + if (!test_case_wait (test, error)) + return FALSE; + } + else if (strcmp (argv[0], "dispatch") == 0) + { + if (argc != 1) + BAD_COMMAND("usage: %s", argv[0]); + + if (!test_case_dispatch (test, error)) + return FALSE; + } + else if (strcmp (argv[0], "sleep") == 0) + { + guint64 interval; + + if (argc != 2) + BAD_COMMAND("usage: %s <milliseconds>", argv[0]); + + if (!g_ascii_string_to_unsigned (argv[1], 10, 0, G_MAXUINT32, + &interval, error)) + return FALSE; + + if (!test_case_sleep (test, (guint32) interval, error)) + return FALSE; + } + else if (strcmp (argv[0], "assert_stacking") == 0) + { + if (!test_case_assert_stacking (test, argv + 1, argc - 1, error)) + return FALSE; + + if (!test_case_check_xserver_stacking (test, error)) + return FALSE; + } + else if (strcmp (argv[0], "assert_focused") == 0) + { + if (!test_case_assert_focused (test, argv[1], error)) + return FALSE; + } + else + { + BAD_COMMAND("Unknown command %s", argv[0]); + } + + return TRUE; +} + +static gboolean +test_case_destroy (TestCase *test, + GError **error) +{ + /* Failures when cleaning up the test case aren't recoverable, since we'll + * pollute the subsequent test cases, so we just return the error, and + * skip the rest of the cleanup. + */ + GHashTableIter iter; + gpointer key, value; + + g_hash_table_iter_init (&iter, test->clients); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + if (!test_client_do (value, error, "destroy_all", NULL)) + return FALSE; + + } + + if (!test_case_wait (test, error)) + return FALSE; + + if (!test_case_assert_stacking (test, NULL, 0, error)) + return FALSE; + + g_hash_table_iter_init (&iter, test->clients); + while (g_hash_table_iter_next (&iter, &key, &value)) + test_client_destroy (value); + + async_waiter_destroy (test->waiter); + + meta_x11_display_set_alarm_filter (meta_get_display ()->x11_display, + NULL, NULL); + + g_hash_table_destroy (test->clients); + g_free (test); + + return TRUE; +} + +/**********************************************************************/ + +static gboolean +run_test (const char *filename, + int index) +{ + TestCase *test = test_case_new (); + GError *error = NULL; + + GFile *file = g_file_new_for_path (filename); + + GDataInputStream *in = NULL; + + GFileInputStream *in_raw = g_file_read (file, NULL, &error); + g_object_unref (file); + if (in_raw == NULL) + goto out; + + in = g_data_input_stream_new (G_INPUT_STREAM (in_raw)); + g_object_unref (in_raw); + + int line_no = 0; + while (error == NULL) + { + char *line = g_data_input_stream_read_line_utf8 (in, NULL, NULL, &error); + if (line == NULL) + break; + + line_no++; + + int argc; + char **argv = NULL; + if (!g_shell_parse_argv (line, &argc, &argv, &error)) + { + if (g_error_matches (error, G_SHELL_ERROR, G_SHELL_ERROR_EMPTY_STRING)) + { + g_clear_error (&error); + goto next; + } + + goto next; + } + + test_case_do (test, argc, argv, &error); + + next: + if (error) + g_prefix_error (&error, "%d: ", line_no); + + g_free (line); + g_strfreev (argv); + } + + { + GError *tmp_error = NULL; + if (!g_input_stream_close (G_INPUT_STREAM (in), NULL, &tmp_error)) + { + if (error != NULL) + g_clear_error (&tmp_error); + else + g_propagate_error (&error, tmp_error); + } + } + + out: + if (in != NULL) + g_object_unref (in); + + GError *cleanup_error = NULL; + test_case_destroy (test, &cleanup_error); + + const char *testspos = strstr (filename, "tests/"); + char *pretty_name; + if (testspos) + pretty_name = g_strdup (testspos + strlen("tests/")); + else + pretty_name = g_strdup (filename); + + if (error || cleanup_error) + { + g_print ("not ok %d %s\n", index, pretty_name); + + if (error) + g_print (" %s\n", error->message); + + if (cleanup_error) + { + g_print (" Fatal Error During Cleanup\n"); + g_print (" %s\n", cleanup_error->message); + exit (1); + } + } + else + { + g_print ("ok %d %s\n", index, pretty_name); + } + + g_free (pretty_name); + + gboolean success = error == NULL; + + g_clear_error (&error); + g_clear_error (&cleanup_error); + + return success; +} + +typedef struct { + int n_tests; + char **tests; +} RunTestsInfo; + +static gboolean +run_tests (gpointer data) +{ + RunTestsInfo *info = data; + int i; + gboolean success = TRUE; + + g_print ("1..%d\n", info->n_tests); + + for (i = 0; i < info->n_tests; i++) + if (!run_test (info->tests[i], i + 1)) + success = FALSE; + + meta_quit (success ? 0 : 1); + + return FALSE; +} + +/**********************************************************************/ + +static gboolean +find_metatests_in_directory (GFile *directory, + GPtrArray *results, + GError **error) +{ + GFileEnumerator *enumerator = g_file_enumerate_children (directory, + "standard::name,standard::type", + G_FILE_QUERY_INFO_NONE, + NULL, error); + if (!enumerator) + return FALSE; + + while (*error == NULL) + { + GFileInfo *info = g_file_enumerator_next_file (enumerator, NULL, error); + if (info == NULL) + break; + + GFile *child = g_file_enumerator_get_child (enumerator, info); + switch (g_file_info_get_file_type (info)) + { + case G_FILE_TYPE_REGULAR: + { + const char *name = g_file_info_get_name (info); + if (g_str_has_suffix (name, ".metatest")) + g_ptr_array_add (results, g_file_get_path (child)); + break; + } + case G_FILE_TYPE_DIRECTORY: + find_metatests_in_directory (child, results, error); + break; + default: + break; + } + + g_object_unref (child); + g_object_unref (info); + } + + { + GError *tmp_error = NULL; + if (!g_file_enumerator_close (enumerator, NULL, &tmp_error)) + { + if (*error != NULL) + g_clear_error (&tmp_error); + else + g_propagate_error (error, tmp_error); + } + } + + g_object_unref (enumerator); + return *error == NULL; +} + +static gboolean all_tests = FALSE; + +const GOptionEntry options[] = { + { + "all", 0, 0, G_OPTION_ARG_NONE, + &all_tests, + "Run all installed tests", + NULL + }, + { NULL } +}; + +int +main (int argc, char **argv) +{ + GOptionContext *ctx; + GError *error = NULL; + + /* First parse the arguments that are passed to us */ + + ctx = g_option_context_new (NULL); + g_option_context_add_main_entries (ctx, options, NULL); + + if (!g_option_context_parse (ctx, + &argc, &argv, &error)) + { + g_printerr ("%s", error->message); + return 1; + } + + g_option_context_free (ctx); + + test_init (&argc, &argv); + + GPtrArray *tests = g_ptr_array_new (); + + if (all_tests) + { + GFile *test_dir = g_file_new_for_path (MUTTER_PKGDATADIR "/tests"); + + if (!find_metatests_in_directory (test_dir, tests, &error)) + { + g_printerr ("Error enumerating tests: %s\n", error->message); + return 1; + } + } + else + { + int i; + char *curdir = g_get_current_dir (); + + for (i = 1; i < argc; i++) + { + if (g_path_is_absolute (argv[i])) + g_ptr_array_add (tests, g_strdup (argv[i])); + else + g_ptr_array_add (tests, g_build_filename (curdir, argv[i], NULL)); + } + + g_free (curdir); + } + + /* Then initalize mutter with a different set of arguments */ + + char *fake_args[] = { NULL, (char *)"--wayland", (char *)"--nested" }; + fake_args[0] = argv[0]; + char **fake_argv = fake_args; + int fake_argc = G_N_ELEMENTS (fake_args); + + ctx = meta_get_option_context (); + if (!g_option_context_parse (ctx, &fake_argc, &fake_argv, &error)) + { + g_printerr ("mutter: %s\n", error->message); + exit (1); + } + g_option_context_free (ctx); + + meta_plugin_manager_load (test_get_plugin_name ()); + + meta_init (); + meta_register_with_session (); + + RunTestsInfo info; + info.tests = (char **)tests->pdata; + info.n_tests = tests->len; + + g_idle_add (run_tests, &info); + + return meta_run (); +} diff --git a/src/tests/test-utils.c b/src/tests/test-utils.c new file mode 100644 index 000000000..28cf97164 --- /dev/null +++ b/src/tests/test-utils.c @@ -0,0 +1,550 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014-2017 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include "tests/test-utils.h" + +#include <gio/gio.h> +#include <string.h> + +#include "core/display-private.h" +#include "core/window-private.h" +#include "wayland/meta-wayland.h" +#include "wayland/meta-xwayland.h" +#include "x11/meta-x11-display-private.h" + +struct _TestClient { + char *id; + MetaWindowClientType type; + GSubprocess *subprocess; + GCancellable *cancellable; + GMainLoop *loop; + GDataOutputStream *in; + GDataInputStream *out; + + char *line; + GError **error; + + AsyncWaiter *waiter; +}; + +struct _AsyncWaiter { + XSyncCounter counter; + int counter_value; + XSyncAlarm alarm; + + GMainLoop *loop; + int counter_wait_value; +}; + +G_DEFINE_QUARK (test-runner-error-quark, test_runner_error) + +static char *test_client_path; + +static void +ensure_test_client_path (int argc, + char **argv) +{ + test_client_path = g_test_build_filename (G_TEST_BUILT, + "src", + "tests", + "mutter-test-client", + NULL); + if (!g_file_test (test_client_path, + G_FILE_TEST_EXISTS | G_FILE_TEST_IS_EXECUTABLE)) + { + g_autofree char *basename = NULL; + g_autofree char *dirname = NULL; + + basename = g_path_get_basename (argv[0]); + + dirname = g_path_get_dirname (argv[0]); + test_client_path = g_build_filename (dirname, + "mutter-test-client", NULL); + } + + if (!g_file_test (test_client_path, + G_FILE_TEST_EXISTS | G_FILE_TEST_IS_EXECUTABLE)) + g_error ("mutter-test-client executable not found"); +} + +void +test_init (int *argc, + char ***argv) +{ + g_test_init (argc, argv, NULL); + g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id="); + + ensure_test_client_path (*argc, *argv); + + meta_wayland_override_display_name ("mutter-test-display"); + meta_xwayland_override_display_number (512); +} + +AsyncWaiter * +async_waiter_new (void) +{ + AsyncWaiter *waiter = g_new0 (AsyncWaiter, 1); + + MetaDisplay *display = meta_get_display (); + Display *xdisplay = display->x11_display->xdisplay; + XSyncValue value; + XSyncAlarmAttributes attr; + + waiter->counter_value = 0; + XSyncIntToValue (&value, waiter->counter_value); + + waiter->counter = XSyncCreateCounter (xdisplay, value); + + attr.trigger.counter = waiter->counter; + attr.trigger.test_type = XSyncPositiveComparison; + + /* Initialize to one greater than the current value */ + attr.trigger.value_type = XSyncRelative; + XSyncIntToValue (&attr.trigger.wait_value, 1); + + /* After triggering, increment test_value by this until + * until the test condition is false */ + XSyncIntToValue (&attr.delta, 1); + + /* we want events (on by default anyway) */ + attr.events = True; + + waiter->alarm = XSyncCreateAlarm (xdisplay, + XSyncCACounter | + XSyncCAValueType | + XSyncCAValue | + XSyncCATestType | + XSyncCADelta | + XSyncCAEvents, + &attr); + + waiter->loop = g_main_loop_new (NULL, FALSE); + + return waiter; +} + +void +async_waiter_destroy (AsyncWaiter *waiter) +{ + MetaDisplay *display = meta_get_display (); + Display *xdisplay = display->x11_display->xdisplay; + + XSyncDestroyAlarm (xdisplay, waiter->alarm); + XSyncDestroyCounter (xdisplay, waiter->counter); + g_main_loop_unref (waiter->loop); +} + +static int +async_waiter_next_value (AsyncWaiter *waiter) +{ + return waiter->counter_value + 1; +} + +static void +async_waiter_wait (AsyncWaiter *waiter, + int wait_value) +{ + if (waiter->counter_value < wait_value) + { + waiter->counter_wait_value = wait_value; + g_main_loop_run (waiter->loop); + waiter->counter_wait_value = 0; + } +} + +void +async_waiter_set_and_wait (AsyncWaiter *waiter) +{ + MetaDisplay *display = meta_get_display (); + Display *xdisplay = display->x11_display->xdisplay; + int wait_value = async_waiter_next_value (waiter); + + XSyncValue sync_value; + XSyncIntToValue (&sync_value, wait_value); + + XSyncSetCounter (xdisplay, waiter->counter, sync_value); + async_waiter_wait (waiter, wait_value); +} + +gboolean +async_waiter_alarm_filter (MetaX11Display *x11_display, + XSyncAlarmNotifyEvent *event, + gpointer data) +{ + AsyncWaiter *waiter = data; + + if (event->alarm != waiter->alarm) + return FALSE; + + waiter->counter_value = XSyncValueLow32 (event->counter_value); + + if (waiter->counter_wait_value != 0 && + waiter->counter_value >= waiter->counter_wait_value) + g_main_loop_quit (waiter->loop); + + return TRUE; +} + +char * +test_client_get_id (TestClient *client) +{ + return client->id; +} + +static void +test_client_line_read (GObject *source, + GAsyncResult *result, + gpointer data) +{ + TestClient *client = data; + + client->line = g_data_input_stream_read_line_finish_utf8 (client->out, + result, + NULL, + client->error); + g_main_loop_quit (client->loop); +} + +gboolean +test_client_do (TestClient *client, + GError **error, + ...) +{ + GString *command = g_string_new (NULL); + char *line = NULL; + va_list vap; + + va_start (vap, error); + + while (TRUE) + { + char *word = va_arg (vap, char *); + char *quoted; + + if (word == NULL) + break; + + if (command->len > 0) + g_string_append_c (command, ' '); + + quoted = g_shell_quote (word); + g_string_append (command, quoted); + g_free (quoted); + } + + va_end (vap); + + g_string_append_c (command, '\n'); + + if (!g_data_output_stream_put_string (client->in, command->str, + client->cancellable, error)) + goto out; + + g_data_input_stream_read_line_async (client->out, + G_PRIORITY_DEFAULT, + client->cancellable, + test_client_line_read, + client); + + client->error = error; + g_main_loop_run (client->loop); + line = client->line; + client->line = NULL; + client->error = NULL; + + if (!line) + { + if (*error == NULL) + g_set_error (error, TEST_RUNNER_ERROR, TEST_RUNNER_ERROR_RUNTIME_ERROR, + "test client exited"); + goto out; + } + + if (strcmp (line, "OK") != 0) + { + g_set_error (error, TEST_RUNNER_ERROR, TEST_RUNNER_ERROR_RUNTIME_ERROR, + "%s", line); + goto out; + } + + out: + g_string_free (command, TRUE); + g_free (line); + + return *error == NULL; +} + +gboolean +test_client_wait (TestClient *client, + GError **error) +{ + if (client->type == META_WINDOW_CLIENT_TYPE_WAYLAND) + { + return test_client_do (client, error, "sync", NULL); + } + else + { + int wait_value = async_waiter_next_value (client->waiter); + char *counter_str = g_strdup_printf ("%lu", client->waiter->counter); + char *wait_value_str = g_strdup_printf ("%d", wait_value); + gboolean success; + + success = test_client_do (client, error, + "set_counter", counter_str, wait_value_str, + NULL); + g_free (counter_str); + g_free (wait_value_str); + if (!success) + return FALSE; + + async_waiter_wait (client->waiter, wait_value); + return TRUE; + } +} + +MetaWindow * +test_client_find_window (TestClient *client, + const char *window_id, + GError **error) +{ + MetaDisplay *display = meta_get_display (); + GSList *windows; + GSList *l; + MetaWindow *result; + char *expected_title; + + windows = + meta_display_list_windows (display, + META_LIST_INCLUDE_OVERRIDE_REDIRECT); + + expected_title = g_strdup_printf ("test/%s/%s", client->id, window_id); + + result = NULL; + for (l = windows; l; l = l->next) + { + MetaWindow *window = l->data; + + if (g_strcmp0 (window->title, expected_title) == 0) + { + result = window; + break; + } + } + + g_slist_free (windows); + g_free (expected_title); + + if (result == NULL) + g_set_error (error, TEST_RUNNER_ERROR, TEST_RUNNER_ERROR_RUNTIME_ERROR, + "window %s/%s isn't known to Mutter", client->id, window_id); + + return result; +} + +typedef struct _WaitForShownData +{ + GMainLoop *loop; + MetaWindow *window; + gulong shown_handler_id; +} WaitForShownData; + +static void +on_window_shown (MetaWindow *window, + WaitForShownData *data) +{ + g_main_loop_quit (data->loop); +} + +static gboolean +wait_for_showing_before_redraw (gpointer user_data) +{ + WaitForShownData *data = user_data; + + if (meta_window_is_hidden (data->window)) + { + data->shown_handler_id = g_signal_connect (data->window, "shown", + G_CALLBACK (on_window_shown), + data); + } + else + { + g_main_loop_quit (data->loop); + } + + return FALSE; +} + +void +test_client_wait_for_window_shown (TestClient *client, + MetaWindow *window) +{ + WaitForShownData data = { + .loop = g_main_loop_new (NULL, FALSE), + .window = window, + }; + meta_later_add (META_LATER_BEFORE_REDRAW, + wait_for_showing_before_redraw, + &data, + NULL); + g_main_loop_run (data.loop); + g_clear_signal_handler (&data.shown_handler_id, window); + g_main_loop_unref (data.loop); +} + +gboolean +test_client_alarm_filter (MetaX11Display *x11_display, + XSyncAlarmNotifyEvent *event, + gpointer data) +{ + TestClient *client = data; + + if (client->waiter) + return async_waiter_alarm_filter (x11_display, event, client->waiter); + else + return FALSE; +} + +TestClient * +test_client_new (const char *id, + MetaWindowClientType type, + GError **error) +{ + TestClient *client; + GSubprocessLauncher *launcher; + GSubprocess *subprocess; + MetaWaylandCompositor *compositor; + const char *wayland_display_name; + const char *x11_display_name; + + launcher = g_subprocess_launcher_new ((G_SUBPROCESS_FLAGS_STDIN_PIPE | + G_SUBPROCESS_FLAGS_STDOUT_PIPE)); + + g_assert (meta_is_wayland_compositor ()); + compositor = meta_wayland_compositor_get_default (); + wayland_display_name = meta_wayland_get_wayland_display_name (compositor); + x11_display_name = meta_wayland_get_xwayland_display_name (compositor); + + g_subprocess_launcher_setenv (launcher, + "WAYLAND_DISPLAY", wayland_display_name, + TRUE); + g_subprocess_launcher_setenv (launcher, + "DISPLAY", x11_display_name, + TRUE); + + subprocess = g_subprocess_launcher_spawn (launcher, + error, + test_client_path, + "--client-id", + id, + (type == META_WINDOW_CLIENT_TYPE_WAYLAND ? + "--wayland" : NULL), + NULL); + g_object_unref (launcher); + + if (!subprocess) + return NULL; + + client = g_new0 (TestClient, 1); + client->type = type; + client->id = g_strdup (id); + client->cancellable = g_cancellable_new (); + client->subprocess = subprocess; + client->in = + g_data_output_stream_new (g_subprocess_get_stdin_pipe (subprocess)); + client->out = + g_data_input_stream_new (g_subprocess_get_stdout_pipe (subprocess)); + client->loop = g_main_loop_new (NULL, FALSE); + + if (client->type == META_WINDOW_CLIENT_TYPE_X11) + client->waiter = async_waiter_new (); + + return client; +} + +gboolean +test_client_quit (TestClient *client, + GError **error) +{ + if (!test_client_do (client, error, "destroy_all", NULL)) + return FALSE; + + if (!test_client_wait (client, error)) + return FALSE; + + return TRUE; +} + +void +test_client_destroy (TestClient *client) +{ + GError *error = NULL; + + if (client->waiter) + async_waiter_destroy (client->waiter); + + g_output_stream_close (G_OUTPUT_STREAM (client->in), NULL, &error); + if (error) + { + g_warning ("Error closing client stdin: %s", error->message); + g_clear_error (&error); + } + g_object_unref (client->in); + + g_input_stream_close (G_INPUT_STREAM (client->out), NULL, &error); + if (error) + { + g_warning ("Error closing client stdout: %s", error->message); + g_clear_error (&error); + } + g_object_unref (client->out); + + g_object_unref (client->cancellable); + g_object_unref (client->subprocess); + g_main_loop_unref (client->loop); + g_free (client->id); + g_free (client); +} + +const char * +test_get_plugin_name (void) +{ + const char *name; + + name = g_getenv ("MUTTER_TEST_PLUGIN_PATH"); + if (name) + return name; + else + return "libdefault"; +} + +void +test_wait_for_x11_display (void) +{ + MetaDisplay *display; + + display = meta_get_display (); + g_assert_nonnull (display); + + while (!display->x11_display) + g_main_context_iteration (NULL, TRUE); + + g_assert_nonnull (display->x11_display); +} diff --git a/src/tests/test-utils.h b/src/tests/test-utils.h new file mode 100644 index 000000000..1710b98e0 --- /dev/null +++ b/src/tests/test-utils.h @@ -0,0 +1,89 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef TEST_UTILS_H +#define TEST_UTILS_H + +#include <glib.h> +#include <X11/Xlib.h> +#include <X11/extensions/sync.h> + +#include "meta/window.h" + +#define TEST_RUNNER_ERROR test_runner_error_quark () + +typedef enum +{ + TEST_RUNNER_ERROR_BAD_COMMAND, + TEST_RUNNER_ERROR_RUNTIME_ERROR, + TEST_RUNNER_ERROR_ASSERTION_FAILED +} TestRunnerError; + +GQuark test_runner_error_quark (void); + +typedef struct _AsyncWaiter AsyncWaiter; +typedef struct _TestClient TestClient; + +void test_init (int *argc, + char ***argv); + +gboolean async_waiter_alarm_filter (MetaX11Display *display, + XSyncAlarmNotifyEvent *event, + gpointer data); + +void async_waiter_set_and_wait (AsyncWaiter *waiter); + +AsyncWaiter * async_waiter_new (void); + +void async_waiter_destroy (AsyncWaiter *waiter); + +char * test_client_get_id (TestClient *client); + +gboolean test_client_alarm_filter (MetaX11Display *x11_display, + XSyncAlarmNotifyEvent *event, + gpointer data); + +gboolean test_client_wait (TestClient *client, + GError **error); + +gboolean test_client_do (TestClient *client, + GError **error, + ...) G_GNUC_NULL_TERMINATED; + +MetaWindow * test_client_find_window (TestClient *client, + const char *window_id, + GError **error); + +void test_client_wait_for_window_shown (TestClient *client, + MetaWindow *window); + +gboolean test_client_quit (TestClient *client, + GError **error); + +TestClient * test_client_new (const char *id, + MetaWindowClientType type, + GError **error); + +void test_client_destroy (TestClient *client); + +const char * test_get_plugin_name (void); + +void test_wait_for_x11_display (void); + +#endif /* TEST_UTILS_H */ diff --git a/src/tests/unit-tests.c b/src/tests/unit-tests.c new file mode 100644 index 000000000..464fd769b --- /dev/null +++ b/src/tests/unit-tests.c @@ -0,0 +1,278 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2015 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <glib.h> +#include <stdlib.h> + +#include <meta/main.h> +#include <meta/util.h> + +#include "compositor/meta-plugin-manager.h" +#include "core/boxes-private.h" +#include "core/main-private.h" +#include "tests/boxes-tests.h" +#include "tests/meta-backend-test.h" +#include "tests/monitor-config-migration-unit-tests.h" +#include "tests/monitor-unit-tests.h" +#include "tests/monitor-store-unit-tests.h" +#include "tests/monitor-transform-tests.h" +#include "tests/test-utils.h" +#include "tests/wayland-unit-tests.h" +#include "wayland/meta-wayland.h" + +typedef struct _MetaTestLaterOrderCallbackData +{ + GMainLoop *loop; /* Loop to terminate when done. */ + int callback_num; /* Callback number integer. */ + int *expected_callback_num; /* Pointer to the expected callback number. */ +} MetaTestLaterOrderCallbackData; + +static gboolean +test_later_order_callback (gpointer user_data) +{ + MetaTestLaterOrderCallbackData *data = user_data; + + g_assert_cmpint (data->callback_num, ==, *data->expected_callback_num); + + if (*data->expected_callback_num == 0) + g_main_loop_quit (data->loop); + else + (*data->expected_callback_num)--; + + return FALSE; +} + +static void +meta_test_util_later_order (void) +{ + GMainLoop *loop; + int expected_callback_num; + int i; + const int num_callbacks = 3; + MetaTestLaterOrderCallbackData callback_data[num_callbacks]; + + loop = g_main_loop_new (NULL, FALSE); + + /* Schedule three BEFORE_DRAW callbacks each with its own number associated + * with it. + */ + for (i = 0; i < num_callbacks; i++) + { + callback_data[i] = (MetaTestLaterOrderCallbackData) { + .loop = loop, + .callback_num = i, + .expected_callback_num = &expected_callback_num, + }; + meta_later_add (META_LATER_BEFORE_REDRAW, + test_later_order_callback, + &callback_data[i], + NULL); + } + + /* Check that the callbacks are invoked in the opposite order that they were + * scheduled. Each callback will decrease the number by 1 after it checks the + * validity. + */ + expected_callback_num = num_callbacks - 1; + g_main_loop_run (loop); + g_assert_cmpint (expected_callback_num, ==, 0); + g_main_loop_unref (loop); +} + +typedef enum _MetaTestLaterScheduleFromLaterState +{ + META_TEST_LATER_EXPECT_CALC_SHOWING, + META_TEST_LATER_EXPECT_SYNC_STACK, + META_TEST_LATER_EXPECT_BEFORE_REDRAW, + META_TEST_LATER_FINISHED, +} MetaTestLaterScheduleFromLaterState; + +typedef struct _MetaTestLaterScheduleFromLaterData +{ + GMainLoop *loop; + MetaTestLaterScheduleFromLaterState state; +} MetaTestLaterScheduleFromLaterData; + +static gboolean +test_later_schedule_from_later_sync_stack_callback (gpointer user_data); + +static gboolean +test_later_schedule_from_later_calc_showing_callback (gpointer user_data) +{ + MetaTestLaterScheduleFromLaterData *data = user_data; + + g_assert_cmpint (data->state, ==, META_TEST_LATER_EXPECT_CALC_SHOWING); + + meta_later_add (META_LATER_SYNC_STACK, + test_later_schedule_from_later_sync_stack_callback, + data, + NULL); + + data->state = META_TEST_LATER_EXPECT_SYNC_STACK; + + return FALSE; +} + +static gboolean +test_later_schedule_from_later_sync_stack_callback (gpointer user_data) +{ + MetaTestLaterScheduleFromLaterData *data = user_data; + + g_assert_cmpint (data->state, ==, META_TEST_LATER_EXPECT_SYNC_STACK); + + data->state = META_TEST_LATER_EXPECT_BEFORE_REDRAW; + + return FALSE; +} + +static gboolean +test_later_schedule_from_later_before_redraw_callback (gpointer user_data) +{ + MetaTestLaterScheduleFromLaterData *data = user_data; + + g_assert_cmpint (data->state, ==, META_TEST_LATER_EXPECT_BEFORE_REDRAW); + data->state = META_TEST_LATER_FINISHED; + g_main_loop_quit (data->loop); + + return FALSE; +} + +static void +meta_test_util_later_schedule_from_later (void) +{ + MetaTestLaterScheduleFromLaterData data; + + data.loop = g_main_loop_new (NULL, FALSE); + + /* Test that scheduling a MetaLater with 'when' being later than the one being + * invoked causes it to be invoked before any callback with a later 'when' + * value being invoked. + * + * The first and last callback is queued here. The one to be invoked in + * between is invoked in test_later_schedule_from_later_calc_showing_callback. + */ + meta_later_add (META_LATER_CALC_SHOWING, + test_later_schedule_from_later_calc_showing_callback, + &data, + NULL); + meta_later_add (META_LATER_BEFORE_REDRAW, + test_later_schedule_from_later_before_redraw_callback, + &data, + NULL); + + data.state = META_TEST_LATER_EXPECT_CALC_SHOWING; + + g_main_loop_run (data.loop); + g_main_loop_unref (data.loop); + + g_assert_cmpint (data.state, ==, META_TEST_LATER_FINISHED); +} + +static void +meta_test_adjacent_to (void) +{ + MetaRectangle base = { .x = 10, .y = 10, .width = 10, .height = 10 }; + MetaRectangle adjacent[] = { + { .x = 20, .y = 10, .width = 10, .height = 10 }, + { .x = 0, .y = 10, .width = 10, .height = 10 }, + { .x = 0, .y = 1, .width = 10, .height = 10 }, + { .x = 20, .y = 19, .width = 10, .height = 10 }, + { .x = 10, .y = 20, .width = 10, .height = 10 }, + { .x = 10, .y = 0, .width = 10, .height = 10 }, + }; + MetaRectangle not_adjacent[] = { + { .x = 0, .y = 0, .width = 10, .height = 10 }, + { .x = 20, .y = 20, .width = 10, .height = 10 }, + { .x = 21, .y = 10, .width = 10, .height = 10 }, + { .x = 10, .y = 21, .width = 10, .height = 10 }, + { .x = 10, .y = 5, .width = 10, .height = 10 }, + { .x = 11, .y = 10, .width = 10, .height = 10 }, + { .x = 19, .y = 10, .width = 10, .height = 10 }, + }; + unsigned int i; + + for (i = 0; i < G_N_ELEMENTS (adjacent); i++) + g_assert (meta_rectangle_is_adjacent_to (&base, &adjacent[i])); + + for (i = 0; i < G_N_ELEMENTS (not_adjacent); i++) + g_assert (!meta_rectangle_is_adjacent_to (&base, ¬_adjacent[i])); +} + +static gboolean +run_tests (gpointer data) +{ + MetaBackend *backend = meta_get_backend (); + MetaSettings *settings = meta_backend_get_settings (backend); + gboolean ret; + + meta_settings_override_experimental_features (settings); + + meta_settings_enable_experimental_feature ( + settings, + META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER); + + pre_run_monitor_tests (); + pre_run_wayland_tests (); + + ret = g_test_run (); + + finish_monitor_tests (); + + meta_quit (ret != 0); + + return FALSE; +} + +static void +init_tests (int argc, char **argv) +{ + g_test_add_func ("/util/meta-later/order", meta_test_util_later_order); + g_test_add_func ("/util/meta-later/schedule-from-later", + meta_test_util_later_schedule_from_later); + + g_test_add_func ("/core/boxes/adjacent-to", meta_test_adjacent_to); + + init_monitor_store_tests (); + init_monitor_config_migration_tests (); + init_monitor_tests (); + init_boxes_tests (); + init_wayland_tests (); + init_monitor_transform_tests (); +} + +int +main (int argc, char *argv[]) +{ + test_init (&argc, &argv); + init_tests (argc, argv); + + meta_plugin_manager_load (test_get_plugin_name ()); + + meta_override_compositor_configuration (META_COMPOSITOR_TYPE_WAYLAND, + META_TYPE_BACKEND_TEST); + + meta_init (); + meta_register_with_session (); + + g_idle_add (run_tests, NULL); + + return meta_run (); +} diff --git a/src/tests/wayland-test-clients/meson.build b/src/tests/wayland-test-clients/meson.build new file mode 100644 index 000000000..3d795dd0e --- /dev/null +++ b/src/tests/wayland-test-clients/meson.build @@ -0,0 +1,61 @@ +wayland_test_client_installed_tests_libexecdir = join_paths( + mutter_installed_tests_libexecdir, + 'wayland-test-clients', +) + +test_driver_server_header = custom_target( + 'test-driver server header', + input: 'test-driver.xml', + output: 'test-driver-server-protocol.h', + command: [ + wayland_scanner, + 'server-header', + '@INPUT@', '@OUTPUT@', + ] +) + +test_driver_client_header = custom_target( + 'test-driver client header', + input: 'test-driver.xml', + output: 'test-driver-client-protocol.h', + command: [ + wayland_scanner, + 'client-header', + '@INPUT@', '@OUTPUT@', + ] +) + +test_driver_protocol_code = custom_target( + 'test-driver source', + input: 'test-driver.xml', + output: 'test-driver-protocol.c', + command: [ + wayland_scanner, + 'private-code', + '@INPUT@', '@OUTPUT@', + ] +) + +common_sources = [ + 'wayland-test-client-utils.c', + 'wayland-test-client-utils.h', + wayland_protocol_client_headers, + wayland_protocol_sources, + test_driver_client_header, + test_driver_protocol_code, +] + +executable('subsurface-remap-toplevel', + sources: [ + 'subsurface-remap-toplevel.c', + common_sources, + ], + include_directories: tests_includepath, + c_args: tests_c_args, + dependencies: [ + glib_dep, + wayland_client_dep, + ], + install: have_installed_tests, + install_dir: wayland_test_client_installed_tests_libexecdir, +) diff --git a/src/tests/wayland-test-clients/subsurface-remap-toplevel.c b/src/tests/wayland-test-clients/subsurface-remap-toplevel.c new file mode 100644 index 000000000..25ff3a2d1 --- /dev/null +++ b/src/tests/wayland-test-clients/subsurface-remap-toplevel.c @@ -0,0 +1,397 @@ +/* + * Copyright (C) 2019 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <glib.h> +#include <sys/mman.h> +#include <unistd.h> +#include <wayland-client.h> + +#include "wayland-test-client-utils.h" + +#include "test-driver-client-protocol.h" +#include "xdg-shell-client-protocol.h" + +typedef enum _State +{ + STATE_INIT = 0, + STATE_WAIT_FOR_CONFIGURE_1, + STATE_WAIT_FOR_FRAME_1, + STATE_WAIT_FOR_ACTOR_DESTROYED, + STATE_WAIT_FOR_CONFIGURE_2, + STATE_WAIT_FOR_FRAME_2 +} State; + +static struct wl_display *display; +static struct wl_registry *registry; +static struct wl_compositor *compositor; +static struct wl_subcompositor *subcompositor; +static struct xdg_wm_base *xdg_wm_base; +static struct wl_shm *shm; +static struct test_driver *test_driver; + +static struct wl_surface *surface; +static struct xdg_surface *xdg_surface; +static struct xdg_toplevel *xdg_toplevel; + +static struct wl_surface *subsurface_surface; +static struct wl_subsurface *subsurface; + +static struct wl_callback *frame_callback; + +static gboolean running; + +static State state; + +static void +init_surface (void) +{ + xdg_toplevel_set_title (xdg_toplevel, "gradient-test"); + wl_surface_commit (surface); +} + +static void +actor_destroyed (void *data, + struct wl_callback *callback, + uint32_t serial) +{ + g_assert_cmpint (state, ==, STATE_WAIT_FOR_ACTOR_DESTROYED); + + init_surface (); + state = STATE_WAIT_FOR_CONFIGURE_2; + + wl_callback_destroy (callback); +} + +static const struct wl_callback_listener actor_destroy_listener = { + actor_destroyed, +}; + +static void +reset_surface (void) +{ + struct wl_callback *callback; + + callback = test_driver_sync_actor_destroyed (test_driver, surface); + wl_callback_add_listener (callback, &actor_destroy_listener, NULL); + + wl_surface_attach (surface, NULL, 0, 0); + wl_surface_commit (surface); + + state = STATE_WAIT_FOR_ACTOR_DESTROYED; +} + +static void +handle_buffer_release (void *data, + struct wl_buffer *buffer) +{ + wl_buffer_destroy (buffer); +} + +static const struct wl_buffer_listener buffer_listener = { + handle_buffer_release +}; + +static gboolean +create_shm_buffer (int width, + int height, + struct wl_buffer **out_buffer, + void **out_data, + int *out_size) +{ + struct wl_shm_pool *pool; + static struct wl_buffer *buffer; + int fd, size, stride; + int bytes_per_pixel; + void *data; + + bytes_per_pixel = 4; + stride = width * bytes_per_pixel; + size = stride * height; + + fd = create_anonymous_file (size); + if (fd < 0) + { + fprintf (stderr, "Creating a buffer file for %d B failed: %m\n", + size); + return FALSE; + } + + data = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (data == MAP_FAILED) + { + fprintf (stderr, "mmap failed: %m\n"); + close (fd); + return FALSE; + } + + pool = wl_shm_create_pool (shm, fd, size); + buffer = wl_shm_pool_create_buffer (pool, 0, + width, height, + stride, + WL_SHM_FORMAT_ARGB8888); + wl_buffer_add_listener (buffer, &buffer_listener, buffer); + wl_shm_pool_destroy (pool); + close (fd); + + *out_buffer = buffer; + *out_data = data; + *out_size = size; + + return TRUE; +} + +static void +fill (void *buffer_data, + int width, + int height, + uint32_t color) +{ + uint32_t *pixels = buffer_data; + int x, y; + + for (y = 0; y < height; y++) + { + for (x = 0; x < width; x++) + pixels[y * width + x] = color; + } +} + +static void +draw (struct wl_surface *surface, + int width, + int height, + uint32_t color) +{ + struct wl_buffer *buffer; + void *buffer_data; + int size; + + if (!create_shm_buffer (width, height, + &buffer, &buffer_data, &size)) + g_error ("Failed to create shm buffer"); + + fill (buffer_data, width, height, color); + + wl_surface_attach (surface, buffer, 0, 0); +} + +static void +draw_main (void) +{ + draw (surface, 700, 500, 0xff00ff00); +} + +static void +draw_subsurface (void) +{ + draw (subsurface_surface, 500, 300, 0xff007f00); +} + +static void +handle_xdg_toplevel_configure (void *data, + struct xdg_toplevel *xdg_toplevel, + int32_t width, + int32_t height, + struct wl_array *state) +{ +} + +static void +handle_xdg_toplevel_close(void *data, + struct xdg_toplevel *xdg_toplevel) +{ + g_assert_not_reached (); +} + +static const struct xdg_toplevel_listener xdg_toplevel_listener = { + handle_xdg_toplevel_configure, + handle_xdg_toplevel_close, +}; + +static void +handle_frame_callback (void *data, + struct wl_callback *callback, + uint32_t time) +{ + switch (state) + { + case STATE_WAIT_FOR_FRAME_1: + reset_surface (); + break; + case STATE_WAIT_FOR_FRAME_2: + exit (EXIT_SUCCESS); + case STATE_INIT: + g_assert_not_reached (); + case STATE_WAIT_FOR_CONFIGURE_1: + g_assert_not_reached (); + case STATE_WAIT_FOR_ACTOR_DESTROYED: + g_assert_not_reached (); + case STATE_WAIT_FOR_CONFIGURE_2: + g_assert_not_reached (); + } +} + +static const struct wl_callback_listener frame_listener = { + handle_frame_callback, +}; + +static void +handle_xdg_surface_configure (void *data, + struct xdg_surface *xdg_surface, + uint32_t serial) +{ + switch (state) + { + case STATE_INIT: + g_assert_not_reached (); + case STATE_WAIT_FOR_CONFIGURE_1: + draw_main (); + state = STATE_WAIT_FOR_FRAME_1; + break; + case STATE_WAIT_FOR_CONFIGURE_2: + draw_main (); + state = STATE_WAIT_FOR_FRAME_2; + break; + case STATE_WAIT_FOR_ACTOR_DESTROYED: + g_assert_not_reached (); + case STATE_WAIT_FOR_FRAME_1: + case STATE_WAIT_FOR_FRAME_2: + /* ignore */ + return; + } + + xdg_surface_ack_configure (xdg_surface, serial); + frame_callback = wl_surface_frame (surface); + wl_callback_add_listener (frame_callback, &frame_listener, NULL); + wl_surface_commit (surface); + wl_display_flush (display); +} + +static const struct xdg_surface_listener xdg_surface_listener = { + handle_xdg_surface_configure, +}; + +static void +handle_xdg_wm_base_ping (void *data, + struct xdg_wm_base *xdg_wm_base, + uint32_t serial) +{ + xdg_wm_base_pong (xdg_wm_base, serial); +} + +static const struct xdg_wm_base_listener xdg_wm_base_listener = { + handle_xdg_wm_base_ping, +}; + +static void +handle_registry_global (void *data, + struct wl_registry *registry, + uint32_t id, + const char *interface, + uint32_t version) +{ + if (strcmp (interface, "wl_compositor") == 0) + { + compositor = wl_registry_bind (registry, id, &wl_compositor_interface, 1); + } + else if (strcmp (interface, "wl_subcompositor") == 0) + { + subcompositor = wl_registry_bind (registry, + id, &wl_subcompositor_interface, 1); + } + else if (strcmp (interface, "xdg_wm_base") == 0) + { + xdg_wm_base = wl_registry_bind (registry, id, + &xdg_wm_base_interface, 1); + xdg_wm_base_add_listener (xdg_wm_base, &xdg_wm_base_listener, NULL); + } + else if (strcmp (interface, "wl_shm") == 0) + { + shm = wl_registry_bind (registry, + id, &wl_shm_interface, 1); + } + else if (strcmp (interface, "test_driver") == 0) + { + test_driver = wl_registry_bind (registry, id, &test_driver_interface, 1); + } +} + +static void +handle_registry_global_remove (void *data, + struct wl_registry *registry, + uint32_t name) +{ +} + +static const struct wl_registry_listener registry_listener = { + handle_registry_global, + handle_registry_global_remove +}; + +int +main (int argc, + char **argv) +{ + display = wl_display_connect (NULL); + registry = wl_display_get_registry (display); + wl_registry_add_listener (registry, ®istry_listener, NULL); + wl_display_roundtrip (display); + + if (!shm) + { + fprintf (stderr, "No wl_shm global\n"); + return EXIT_FAILURE; + } + + if (!xdg_wm_base) + { + fprintf (stderr, "No xdg_wm_base global\n"); + return EXIT_FAILURE; + } + + wl_display_roundtrip (display); + + g_assert_nonnull (test_driver); + + surface = wl_compositor_create_surface (compositor); + xdg_surface = xdg_wm_base_get_xdg_surface (xdg_wm_base, surface); + xdg_surface_add_listener (xdg_surface, &xdg_surface_listener, NULL); + xdg_toplevel = xdg_surface_get_toplevel (xdg_surface); + xdg_toplevel_add_listener (xdg_toplevel, &xdg_toplevel_listener, NULL); + + subsurface_surface = wl_compositor_create_surface (compositor); + subsurface = wl_subcompositor_get_subsurface (subcompositor, + subsurface_surface, + surface); + wl_subsurface_set_position (subsurface, 100, 100); + draw_subsurface (); + wl_surface_commit (subsurface_surface); + + init_surface (); + state = STATE_WAIT_FOR_CONFIGURE_1; + + running = TRUE; + while (running) + { + if (wl_display_dispatch (display) == -1) + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/src/tests/wayland-test-clients/test-driver.xml b/src/tests/wayland-test-clients/test-driver.xml new file mode 100644 index 000000000..dd5f52145 --- /dev/null +++ b/src/tests/wayland-test-clients/test-driver.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<protocol name="test_driver"> + <interface name="test_driver" version="1"> + <request name="sync_actor_destroyed"> + <arg name="callback" type="new_id" interface="wl_callback"/> + <arg name="surface" type="object" interface="wl_surface"/> + </request> + </interface> +</protocol> diff --git a/src/tests/wayland-test-clients/wayland-test-client-utils.c b/src/tests/wayland-test-clients/wayland-test-client-utils.c new file mode 100644 index 000000000..9deb122cb --- /dev/null +++ b/src/tests/wayland-test-clients/wayland-test-client-utils.c @@ -0,0 +1,88 @@ +/* + * Copyright © 2012 Collabora, Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "wayland-test-client-utils.h" + +#include <errno.h> +#include <fcntl.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +static int +create_tmpfile_cloexec (char *tmpname) +{ + int fd; + + fd = mkostemp (tmpname, O_CLOEXEC); + if (fd >= 0) + unlink (tmpname); + + return fd; +} + +int +create_anonymous_file (off_t size) +{ + static const char template[] = "/wayland-test-client-shared-XXXXXX"; + const char *path; + char *name; + int fd; + int ret; + + path = getenv ("XDG_RUNTIME_DIR"); + if (!path) + { + errno = ENOENT; + return -1; + } + + name = malloc (strlen (path) + sizeof (template)); + if (!name) + return -1; + + strcpy (name, path); + strcat (name, template); + + fd = create_tmpfile_cloexec (name); + + free (name); + + if (fd < 0) + return -1; + + do + ret = posix_fallocate (fd, 0, size); + while (ret == EINTR); + + if (ret != 0) + { + close (fd); + errno = ret; + return -1; + } + + return fd; +} diff --git a/src/tests/wayland-test-clients/wayland-test-client-utils.h b/src/tests/wayland-test-clients/wayland-test-client-utils.h new file mode 100644 index 000000000..a8dcb5321 --- /dev/null +++ b/src/tests/wayland-test-clients/wayland-test-client-utils.h @@ -0,0 +1,8 @@ +#ifndef WAYLAND_TEST_CLIENT_UTILS_H +#define WAYLAND_TEST_CLIENT_UTILS_H + +#include <stdio.h> + +int create_anonymous_file (off_t size); + +#endif /* WAYLAND_TEST_CLIENT_UTILS_H */ diff --git a/src/tests/wayland-unit-tests.c b/src/tests/wayland-unit-tests.c new file mode 100644 index 000000000..30c7c7c24 --- /dev/null +++ b/src/tests/wayland-unit-tests.c @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2019 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include "tests/wayland-unit-tests.h" + +#include <gio/gio.h> +#include <wayland-server.h> + +#include "wayland/meta-wayland.h" +#include "wayland/meta-wayland-actor-surface.h" +#include "wayland/meta-wayland-surface.h" +#include "wayland/meta-wayland-private.h" + +#include "test-driver-server-protocol.h" + +typedef struct _WaylandTestClient +{ + GSubprocess *subprocess; + char *path; + GMainLoop *main_loop; +} WaylandTestClient; + +static char * +get_test_client_path (const char *test_client_name) +{ + return g_test_build_filename (G_TEST_BUILT, + "src", + "tests", + "wayland-test-clients", + test_client_name, + NULL); +} + +static WaylandTestClient * +wayland_test_client_new (const char *test_client_name) +{ + MetaWaylandCompositor *compositor; + const char *wayland_display_name; + g_autofree char *test_client_path = NULL; + g_autoptr (GSubprocessLauncher) launcher = NULL; + GSubprocess *subprocess; + GError *error = NULL; + WaylandTestClient *wayland_test_client; + + compositor = meta_wayland_compositor_get_default (); + wayland_display_name = meta_wayland_get_wayland_display_name (compositor); + test_client_path = get_test_client_path (test_client_name); + + launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_NONE); + g_subprocess_launcher_setenv (launcher, + "WAYLAND_DISPLAY", wayland_display_name, + TRUE); + + subprocess = g_subprocess_launcher_spawn (launcher, + &error, + test_client_path, + NULL); + if (!subprocess) + { + g_error ("Failed to launch Wayland test client '%s': %s", + test_client_path, error->message); + } + + wayland_test_client = g_new0 (WaylandTestClient, 1); + wayland_test_client->subprocess = subprocess; + wayland_test_client->path = g_strdup (test_client_name); + wayland_test_client->main_loop = g_main_loop_new (NULL, FALSE); + + return wayland_test_client; +} + +static void +wayland_test_client_finished (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + WaylandTestClient *wayland_test_client = user_data; + GError *error = NULL; + + if (!g_subprocess_wait_finish (wayland_test_client->subprocess, + res, + &error)) + { + g_error ("Failed to wait for Wayland test client '%s': %s", + wayland_test_client->path, error->message); + } + + g_main_loop_quit (wayland_test_client->main_loop); +} + +static void +wayland_test_client_finish (WaylandTestClient *wayland_test_client) +{ + g_subprocess_wait_async (wayland_test_client->subprocess, NULL, + wayland_test_client_finished, wayland_test_client); + + g_main_loop_run (wayland_test_client->main_loop); + + g_assert_true (g_subprocess_get_successful (wayland_test_client->subprocess)); + + g_main_loop_unref (wayland_test_client->main_loop); + g_free (wayland_test_client->path); + g_object_unref (wayland_test_client->subprocess); + g_free (wayland_test_client); +} + +static void +subsurface_remap_toplevel (void) +{ + WaylandTestClient *wayland_test_client; + + wayland_test_client = wayland_test_client_new ("subsurface-remap-toplevel"); + wayland_test_client_finish (wayland_test_client); +} + +static void +on_actor_destroyed (ClutterActor *actor, + struct wl_resource *callback) +{ + wl_callback_send_done (callback, 0); + wl_resource_destroy (callback); +} + +static void +sync_actor_destroy (struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *surface_resource) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + MetaWaylandActorSurface *actor_surface; + MetaSurfaceActor *actor; + struct wl_resource *callback; + + g_assert_nonnull (surface); + + actor_surface = (MetaWaylandActorSurface *) surface->role; + g_assert_nonnull (actor_surface); + + actor = meta_wayland_actor_surface_get_actor (actor_surface); + g_assert_nonnull (actor); + + callback = wl_resource_create (client, &wl_callback_interface, 1, id); + + g_signal_connect (actor, "destroy", G_CALLBACK (on_actor_destroyed), + callback); +} + +static const struct test_driver_interface meta_test_driver_interface = { + sync_actor_destroy, +}; + +static void +bind_test_driver (struct wl_client *client, + void *data, + uint32_t version, + uint32_t id) +{ + struct wl_resource *resource; + + resource = wl_resource_create (client, &test_driver_interface, + version, id); + wl_resource_set_implementation (resource, &meta_test_driver_interface, + NULL, NULL); +} + +void +pre_run_wayland_tests (void) +{ + MetaWaylandCompositor *compositor; + + compositor = meta_wayland_compositor_get_default (); + g_assert_nonnull (compositor); + + if (wl_global_create (compositor->wayland_display, + &test_driver_interface, + 1, + NULL, bind_test_driver) == NULL) + g_error ("Failed to register a global wl-subcompositor object"); +} + +void +init_wayland_tests (void) +{ + g_test_add_func ("/wayland/subsurface/remap-toplevel", + subsurface_remap_toplevel); +} diff --git a/src/tests/wayland-unit-tests.h b/src/tests/wayland-unit-tests.h new file mode 100644 index 000000000..b7d8d4204 --- /dev/null +++ b/src/tests/wayland-unit-tests.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2019 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef WAYLAND_UNIT_TESTS_H +#define WAYLAND_UNIT_TESTS_H + +void init_wayland_tests (void); + +void pre_run_wayland_tests (void); + +#endif /* WAYLAND_UNIT_TESTS_H */ diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am deleted file mode 100644 index d20971c88..000000000 --- a/src/tools/Makefile.am +++ /dev/null @@ -1,34 +0,0 @@ -@INTLTOOL_DESKTOP_RULE@ - -icondir=$(pkgdatadir)/icons -icon_DATA=muffin-window-demo.png - -AM_CPPFLAGS=$(WARN_CFLAGS) @MUFFIN_WINDOW_DEMO_CFLAGS@ @MUFFIN_MESSAGE_CFLAGS@ \ - -I$(top_srcdir)/src \ - -DMUFFIN_ICON_DIR=\"$(pkgdatadir)/icons\" \ - -DMUFFIN_LOCALEDIR=\"$(prefix)/@DATADIRNAME@/locale\" - -muffin_message_SOURCES= \ - muffin-message.c - -muffin_window_demo_SOURCES= \ - muffin-window-demo.c - -muffin_mag_SOURCES= \ - muffin-mag.c - -muffin_grayscale_SOURCES= \ - muffin-grayscale.c - -bin_PROGRAMS=muffin-message muffin-window-demo - -## cheesy hacks I use, don't really have any business existing. ;-) -noinst_PROGRAMS=muffin-mag muffin-grayscale - -muffin_message_LDADD= @MUFFIN_MESSAGE_LIBS@ -muffin_window_demo_LDADD= @MUFFIN_WINDOW_DEMO_LIBS@ -muffin_mag_LDADD= @MUFFIN_WINDOW_DEMO_LIBS@ -muffin_grayscale_LDADD = @MUFFIN_WINDOW_DEMO_LIBS@ - -EXTRA_DIST=$(icon_DATA) - diff --git a/src/tools/muffin-grayscale.c b/src/tools/muffin-grayscale.c deleted file mode 100644 index 0695235ac..000000000 --- a/src/tools/muffin-grayscale.c +++ /dev/null @@ -1,107 +0,0 @@ -/* Hack for grayscaling an image */ - -/* - * Copyright (C) 2002 Red Hat Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. - */ - -#include <gdk-pixbuf/gdk-pixbuf.h> -#include <unistd.h> -#include <stdlib.h> -#include <math.h> - -#define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11) - -static GdkPixbuf* -grayscale_pixbuf (GdkPixbuf *pixbuf) -{ - GdkPixbuf *gray; - guchar *pixels; - int rowstride; - int pixstride; - int row; - int n_rows; - int width; - - gray = gdk_pixbuf_copy (pixbuf); - rowstride = gdk_pixbuf_get_rowstride (gray); - pixstride = gdk_pixbuf_get_has_alpha (gray) ? 4 : 3; - - pixels = gdk_pixbuf_get_pixels (gray); - n_rows = gdk_pixbuf_get_height (gray); - width = gdk_pixbuf_get_width (gray); - - row = 0; - while (row < n_rows) - { - guchar *p = pixels + row * rowstride; - guchar *end = p + (pixstride * width); - - while (p != end) - { - double v = INTENSITY (p[0], p[1], p[2]); - - p[0] = (guchar) v; - p[1] = (guchar) v; - p[2] = (guchar) v; - - p += pixstride; - } - - ++row; - } - - return gray; -} - -int -main (int argc, char **argv) -{ - GdkPixbuf *pixbuf; - GdkPixbuf *gray; - GError *err; - - if (argc != 2) - { - g_printerr ("specify a single image on the command line\n"); - return 1; - } - - err = NULL; - pixbuf = gdk_pixbuf_new_from_file (argv[1], &err); - if (err != NULL) - { - g_printerr ("failed to load image: %s\n", err->message); - g_error_free (err); - return 1; - } - - gray = grayscale_pixbuf (pixbuf); - - err = NULL; - gdk_pixbuf_save (gray, "grayscale.png", "png", &err, NULL); - if (err != NULL) - { - g_printerr ("failed to save image: %s\n", err->message); - g_error_free (err); - return 1; - } - - g_print ("wrote grayscale.png\n"); - - return 0; -} diff --git a/src/tools/muffin-mag.c b/src/tools/muffin-mag.c deleted file mode 100644 index 7b10ec27d..000000000 --- a/src/tools/muffin-mag.c +++ /dev/null @@ -1,301 +0,0 @@ -/* Hack for use instead of xmag */ - -/* - * Copyright (C) 2002 Red Hat Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. - */ - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif -#define _XOPEN_SOURCE 600 /* C99 -- for rint() */ - -#include <gtk/gtk.h> -#include <gdk/gdkx.h> -#include <gdk/gdkkeysyms.h> -#include <unistd.h> -#include <stdlib.h> -#include <math.h> - -static GtkWidget *grab_widget = NULL; -static GtkWidget *display_window = NULL; -static int last_grab_x = 0; -static int last_grab_y = 0; -static int last_grab_width = 150; -static int last_grab_height = 150; -static GtkAllocation last_grab_allocation; -static double width_factor = 4.0; -static double height_factor = 4.0; -static GdkInterpType interp_mode = GDK_INTERP_NEAREST; -static guint regrab_idle_id = 0; - -static GdkPixbuf* -get_pixbuf (void) -{ - GdkPixbuf *screenshot; - GdkPixbuf *magnified; - -#if 0 - g_print ("Size %d x %d\n", - last_grab_width, last_grab_height); -#endif - - screenshot = gdk_pixbuf_get_from_window (gdk_get_default_root_window (), - last_grab_x, last_grab_y, - last_grab_width, last_grab_height); - - if (screenshot == NULL) - { - g_printerr ("Screenshot failed\n"); - exit (1); - } - - magnified = gdk_pixbuf_scale_simple (screenshot, last_grab_width * width_factor, - last_grab_height * height_factor, - interp_mode); - - - g_object_unref (G_OBJECT (screenshot)); - - return magnified; -} - -static gboolean -regrab_idle (GtkWidget *image) -{ - GtkAllocation allocation; - GdkPixbuf *magnified; - - gtk_widget_get_allocation (image, &allocation); - - if (allocation.width != last_grab_allocation.width || - allocation.height != last_grab_allocation.height) - { - last_grab_width = rint (allocation.width / width_factor); - last_grab_height = rint (allocation.height / height_factor); - last_grab_allocation = allocation; - - magnified = get_pixbuf (); - - gtk_image_set_from_pixbuf (GTK_IMAGE (image), magnified); - - g_object_unref (G_OBJECT (magnified)); - } - - regrab_idle_id = 0; - - return FALSE; -} - -static void -image_resized (GtkWidget *image) -{ - if (regrab_idle_id == 0) - regrab_idle_id = g_idle_add_full (G_PRIORITY_LOW + 100, (GSourceFunc) regrab_idle, - image, NULL); -} - -static void -grab_area_at_mouse (GtkWidget *invisible, - int x_root, - int y_root) -{ - GdkPixbuf *magnified; - int width, height; - GtkWidget *widget; - - width = last_grab_width; - height = last_grab_height; - - last_grab_x = x_root; - last_grab_y = y_root; - last_grab_width = width; - last_grab_height = height; - - magnified = get_pixbuf (); - - display_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_window_set_default_size (GTK_WINDOW (display_window), - last_grab_width, last_grab_height); - widget = gtk_image_new_from_pixbuf (magnified); - gtk_widget_set_size_request (widget, 40, 40); - gtk_container_add (GTK_CONTAINER (display_window), widget); - g_object_unref (G_OBJECT (magnified)); - - g_object_add_weak_pointer (G_OBJECT (display_window), - (gpointer) &display_window); - - g_signal_connect (G_OBJECT (display_window), "destroy", - G_CALLBACK (gtk_main_quit), NULL); - - g_signal_connect_after (G_OBJECT (widget), "size_allocate", G_CALLBACK (image_resized), NULL); - - gtk_widget_show_all (display_window); -} - -static void -shutdown_grab (void) -{ - GdkDeviceManager *manager; - GdkDevice *device; - - manager = gdk_display_get_device_manager (gdk_display_get_default ()); - device = gdk_device_manager_get_client_pointer (manager); - - gdk_device_ungrab (device, gtk_get_current_event_time ()); - gdk_device_ungrab (gdk_device_get_associated_device (device), - gtk_get_current_event_time ()); - gtk_grab_remove (grab_widget); -} - -static void -mouse_motion (GtkWidget *invisible, - GdkEventMotion *event, - gpointer data) -{ - -} - -static gboolean -mouse_release (GtkWidget *invisible, - GdkEventButton *event, - gpointer data) -{ - if (event->button != 1) - return FALSE; - - grab_area_at_mouse (invisible, event->x_root, event->y_root); - - shutdown_grab (); - - g_signal_handlers_disconnect_by_func (invisible, mouse_motion, NULL); - g_signal_handlers_disconnect_by_func (invisible, mouse_release, NULL); - - return TRUE; -} - -/* Helper Functions */ - -static gboolean mouse_press (GtkWidget *invisible, - GdkEventButton *event, - gpointer data); - -static gboolean -key_press (GtkWidget *invisible, - GdkEventKey *event, - gpointer data) -{ - if (event->keyval == GDK_KEY_Escape) - { - shutdown_grab (); - - g_signal_handlers_disconnect_by_func (invisible, mouse_press, NULL); - g_signal_handlers_disconnect_by_func (invisible, key_press, NULL); - - gtk_main_quit (); - - return TRUE; - } - - return FALSE; -} - -static gboolean -mouse_press (GtkWidget *invisible, - GdkEventButton *event, - gpointer data) -{ - if (event->type == GDK_BUTTON_PRESS && - event->button == 1) - { - g_signal_connect (invisible, "motion_notify_event", - G_CALLBACK (mouse_motion), NULL); - g_signal_connect (invisible, "button_release_event", - G_CALLBACK (mouse_release), NULL); - g_signal_handlers_disconnect_by_func (invisible, mouse_press, NULL); - g_signal_handlers_disconnect_by_func (invisible, key_press, NULL); - return TRUE; - } - - return FALSE; -} - -static void -begin_area_grab (void) -{ - GdkWindow *window; - GdkDeviceManager *manager; - GdkDevice *device; - - if (grab_widget == NULL) - { - grab_widget = gtk_invisible_new (); - - gtk_widget_add_events (grab_widget, - GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK); - - gtk_widget_show (grab_widget); - } - - window = gtk_widget_get_window (grab_widget); - manager = gdk_display_get_device_manager (gdk_display_get_default ()); - device = gdk_device_manager_get_client_pointer (manager); - - if (gdk_device_grab (device, - window, - GDK_OWNERSHIP_NONE, - FALSE, - GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK, - NULL, - gtk_get_current_event_time ()) != GDK_GRAB_SUCCESS) - { - g_warning ("Failed to grab pointer to do eyedropper"); - return; - } - - if (gdk_device_grab (gdk_device_get_associated_device (device), - window, - GDK_OWNERSHIP_NONE, - FALSE, - GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK, - NULL, - gtk_get_current_event_time ()) != GDK_GRAB_SUCCESS) - { - gdk_device_ungrab (device, gtk_get_current_event_time ()); - g_warning ("Failed to grab keyboard to do eyedropper"); - return; - } - - gtk_grab_add (grab_widget); - - g_signal_connect (grab_widget, "button_press_event", - G_CALLBACK (mouse_press), NULL); - g_signal_connect (grab_widget, "key_press_event", - G_CALLBACK (key_press), NULL); -} - -int -main (int argc, char **argv) -{ - gtk_init (&argc, &argv); - - begin_area_grab (); - - gtk_main (); - - return 0; -} diff --git a/src/tools/muffin-message.c b/src/tools/muffin-message.c deleted file mode 100644 index 9cb4a442c..000000000 --- a/src/tools/muffin-message.c +++ /dev/null @@ -1,158 +0,0 @@ -/* Muffin send-magic-messages app */ - -/* - * Copyright (C) 2002 Havoc Pennington - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. - */ - -#include <config.h> -#include <gtk/gtk.h> -#include <gdk/gdkx.h> -#include <stdlib.h> -#include <string.h> - -#include <glib/gi18n.h> - -static Display *display; - -static void -send_reload_theme (void) -{ - XEvent xev; - - xev.xclient.type = ClientMessage; - xev.xclient.serial = 0; - xev.xclient.send_event = True; - xev.xclient.display = display; - xev.xclient.window = gdk_x11_get_default_root_xwindow (); - xev.xclient.message_type = XInternAtom (display, - "_MUFFIN_RELOAD_THEME_MESSAGE", - False); - xev.xclient.format = 32; - xev.xclient.data.l[0] = 0; - xev.xclient.data.l[1] = 0; - xev.xclient.data.l[2] = 0; - - XSendEvent (display, - gdk_x11_get_default_root_xwindow (), - False, - SubstructureRedirectMask | SubstructureNotifyMask, - &xev); - - XFlush (display); - XSync (display, False); -} - -static void -send_set_keybindings (gboolean enabled) -{ - XEvent xev; - - xev.xclient.type = ClientMessage; - xev.xclient.serial = 0; - xev.xclient.send_event = True; - xev.xclient.display = display; - xev.xclient.window = gdk_x11_get_default_root_xwindow (); - xev.xclient.message_type = XInternAtom (display, - "_MUFFIN_SET_KEYBINDINGS_MESSAGE", - False); - xev.xclient.format = 32; - xev.xclient.data.l[0] = enabled; - xev.xclient.data.l[1] = 0; - xev.xclient.data.l[2] = 0; - - XSendEvent (display, - gdk_x11_get_default_root_xwindow (), - False, - SubstructureRedirectMask | SubstructureNotifyMask, - &xev); - - XFlush (display); - XSync (display, False); -} - -#ifdef WITH_VERBOSE_MODE -static void -send_toggle_verbose (void) -{ - XEvent xev; - - xev.xclient.type = ClientMessage; - xev.xclient.serial = 0; - xev.xclient.send_event = True; - xev.xclient.display = display; - xev.xclient.window = gdk_x11_get_default_root_xwindow (); - xev.xclient.message_type = XInternAtom (display, - "_MUFFIN_TOGGLE_VERBOSE", - False); - xev.xclient.format = 32; - xev.xclient.data.l[0] = 0; - xev.xclient.data.l[1] = 0; - xev.xclient.data.l[2] = 0; - - XSendEvent (display, - gdk_x11_get_default_root_xwindow (), - False, - SubstructureRedirectMask | SubstructureNotifyMask, - &xev); - - XFlush (display); - XSync (display, False); -} -#endif - -static void -usage (void) -{ - g_printerr (_("Usage: %s\n"), - "muffin-message (reload-theme|enable-keybindings|disable-keybindings|toggle-verbose)"); - exit (1); -} - -int -main (int argc, char **argv) -{ - bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); - - gtk_init (&argc, &argv); - - if (argc < 2) - usage (); - - display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); - - if (strcmp (argv[1], "reload-theme") == 0) - send_reload_theme (); - else if (strcmp (argv[1], "enable-keybindings") == 0) - send_set_keybindings (TRUE); - else if (strcmp (argv[1], "disable-keybindings") == 0) - send_set_keybindings (FALSE); - else if (strcmp (argv[1], "toggle-verbose") == 0) - { -#ifndef WITH_VERBOSE_MODE - g_printerr (_("Muffin was compiled without support for verbose mode\n")); - return 1; -#else - send_toggle_verbose (); -#endif - } - else - usage (); - - return 0; -} - diff --git a/src/tools/muffin-window-demo.c b/src/tools/muffin-window-demo.c deleted file mode 100644 index 1fbf33ee8..000000000 --- a/src/tools/muffin-window-demo.c +++ /dev/null @@ -1,1049 +0,0 @@ -/* Muffin window types/properties demo app */ - -/* - * Copyright (C) 2002 Havoc Pennington - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. - */ - -#include <gtk/gtk.h> -#include <gdk/gdkx.h> -#include <X11/Xatom.h> -#include <unistd.h> - -static GtkWidget* do_appwindow (void); - -static gboolean aspect_on; - -static void -set_gdk_window_struts (GdkWindow *window, - int left, - int right, - int top, - int bottom) -{ - long vals[12]; - - vals[0] = left; - vals[1] = right; - vals[2] = top; - vals[3] = bottom; - vals[4] = 000; - vals[5] = 400; - vals[6] = 200; - vals[7] = 600; - vals[8] = 76; - vals[9] = 676; - vals[10] = 200; - vals[11] = 800; - - XChangeProperty (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XID (window), - XInternAtom (GDK_WINDOW_XDISPLAY (window), - "_NET_WM_STRUT_PARTIAL", False), - XA_CARDINAL, 32, PropModeReplace, - (guchar *)vals, 12); -} - -static void -on_realize_set_struts (GtkWindow *window, - gpointer data) -{ - GtkWidget *widget; - int left; - int right; - int top; - int bottom; - - widget = GTK_WIDGET (window); - - g_return_if_fail (gtk_widget_get_realized (widget)); - - left = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "meta-strut-left")); - right = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "meta-strut-right")); - top = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "meta-strut-top")); - bottom = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "meta-strut-bottom")); - - set_gdk_window_struts (gtk_widget_get_window (widget), - left, right, top, bottom); -} - -static void -set_gtk_window_struts (GtkWidget *window, - int left, - int right, - int top, - int bottom) -{ - GtkWidget *widget; - - widget = GTK_WIDGET (window); - - g_object_set_data (G_OBJECT (window), "meta-strut-left", - GINT_TO_POINTER (left)); - g_object_set_data (G_OBJECT (window), "meta-strut-right", - GINT_TO_POINTER (right)); - g_object_set_data (G_OBJECT (window), "meta-strut-top", - GINT_TO_POINTER (top)); - g_object_set_data (G_OBJECT (window), "meta-strut-bottom", - GINT_TO_POINTER (bottom)); - - g_signal_handlers_disconnect_by_func (G_OBJECT (window), - on_realize_set_struts, - NULL); - - g_signal_connect_after (G_OBJECT (window), - "realize", - G_CALLBACK (on_realize_set_struts), - NULL); - - if (gtk_widget_get_realized (widget)) - set_gdk_window_struts (gtk_widget_get_window (widget), - left, right, top, bottom); -} - -static void -set_gdk_window_type (GdkWindow *window, - const char *type) -{ - Atom atoms[2] = { None, None }; - - atoms[0] = XInternAtom (GDK_WINDOW_XDISPLAY (window), - type, False); - - XChangeProperty (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XID (window), - XInternAtom (GDK_WINDOW_XDISPLAY (window), "_NET_WM_WINDOW_TYPE", False), - XA_ATOM, 32, PropModeReplace, - (guchar *)atoms, - 1); -} - -static void -on_realize_set_type (GtkWindow *window, - gpointer data) -{ - GtkWidget *widget; - const char *type; - - widget = GTK_WIDGET (window); - - g_return_if_fail (gtk_widget_get_realized (widget)); - - type = g_object_get_data (G_OBJECT (window), "meta-window-type"); - - g_return_if_fail (type != NULL); - - set_gdk_window_type (gtk_widget_get_window (widget), - type); -} - -static void -set_gtk_window_type (GtkWindow *window, - const char *type) -{ - GtkWidget *widget; - - widget = GTK_WIDGET (window); - - g_object_set_data (G_OBJECT (window), "meta-window-type", (char*) type); - - g_signal_handlers_disconnect_by_func (G_OBJECT (window), - on_realize_set_type, - NULL); - - g_signal_connect_after (G_OBJECT (window), - "realize", - G_CALLBACK (on_realize_set_type), - NULL); - - if (gtk_widget_get_realized (widget)) - set_gdk_window_type (gtk_widget_get_window (widget), - type); -} - -static void -set_gdk_window_border_only (GdkWindow *window) -{ - gdk_window_set_decorations (window, GDK_DECOR_BORDER); -} - -static void -on_realize_set_border_only (GtkWindow *window, - gpointer data) -{ - GtkWidget *widget; - - widget = GTK_WIDGET (window); - - g_return_if_fail (gtk_widget_get_realized (widget)); - - set_gdk_window_border_only (gtk_widget_get_window (widget)); -} - -static void -set_gtk_window_border_only (GtkWindow *window) -{ - GtkWidget *widget; - - widget = GTK_WIDGET (window); - - g_signal_handlers_disconnect_by_func (G_OBJECT (window), - on_realize_set_border_only, - NULL); - - g_signal_connect_after (G_OBJECT (window), - "realize", - G_CALLBACK (on_realize_set_border_only), - NULL); - - if (gtk_widget_get_realized (widget)) - set_gdk_window_border_only (gtk_widget_get_window (widget)); -} - -int -main (int argc, char **argv) -{ - GList *list; - GdkPixbuf *pixbuf; - GError *err; - - gtk_init (&argc, &argv); - - err = NULL; - pixbuf = gdk_pixbuf_new_from_file (MUFFIN_ICON_DIR"/muffin-window-demo.png", - &err); - if (pixbuf) - { - list = g_list_prepend (NULL, pixbuf); - - gtk_window_set_default_icon_list (list); - g_list_free (list); - g_object_unref (G_OBJECT (pixbuf)); - } - else - { - g_printerr ("Could not load icon: %s\n", err->message); - g_error_free (err); - } - - do_appwindow (); - - gtk_main (); - - return 0; -} - -static void -response_cb (GtkDialog *dialog, - int response_id, - void *data); - -static void -make_dialog (GtkWidget *parent, - int depth) -{ - GtkWidget *dialog; - char *str; - - dialog = gtk_message_dialog_new (parent ? GTK_WINDOW (parent) : NULL, - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_INFO, - GTK_BUTTONS_CLOSE, - parent ? "Here is a dialog %d" : - "Here is a dialog %d with no transient parent", - depth); - - str = g_strdup_printf ("%d dialog", depth); - gtk_window_set_title (GTK_WINDOW (dialog), str); - free (str); - - gtk_dialog_add_button (GTK_DIALOG (dialog), - "Open child dialog", - GTK_RESPONSE_ACCEPT); - - /* Close dialog on user response */ - g_signal_connect (G_OBJECT (dialog), - "response", - G_CALLBACK (response_cb), - NULL); - - g_object_set_data (G_OBJECT (dialog), "depth", - GINT_TO_POINTER (depth)); - - gtk_widget_show (dialog); -} - -static void -response_cb (GtkDialog *dialog, - int response_id, - void *data) -{ - switch (response_id) - { - case GTK_RESPONSE_ACCEPT: - make_dialog (GTK_WIDGET (dialog), - GPOINTER_TO_INT (g_object_get_data (G_OBJECT (dialog), - "depth")) + 1); - break; - - default: - gtk_widget_destroy (GTK_WIDGET (dialog)); - break; - } -} - -static void -dialog_cb (GtkAction *action, - gpointer callback_data) -{ - make_dialog (GTK_WIDGET (callback_data), 1); -} - -static void -modal_dialog_cb (GtkAction *action, - gpointer callback_data) -{ - GtkWidget *dialog; - - dialog = gtk_message_dialog_new (GTK_WINDOW (callback_data), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_INFO, - GTK_BUTTONS_CLOSE, - "Here is a MODAL dialog"); - - set_gtk_window_type (GTK_WINDOW (dialog), "_NET_WM_WINDOW_TYPE_MODAL_DIALOG"); - - gtk_dialog_run (GTK_DIALOG (dialog)); - - gtk_widget_destroy (dialog); -} - -static void -no_parent_dialog_cb (GtkAction *action, - gpointer callback_data) -{ - make_dialog (NULL, 1); -} - -static void -utility_cb (GtkAction *action, - gpointer callback_data) -{ - GtkWidget *window; - GtkWidget *vbox; - GtkWidget *button; - - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - set_gtk_window_type (GTK_WINDOW (window), "_NET_WM_WINDOW_TYPE_UTILITY"); - gtk_window_set_title (GTK_WINDOW (window), "Utility"); - - gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (callback_data)); - - vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); - - gtk_container_add (GTK_CONTAINER (window), vbox); - - button = gtk_button_new_with_mnemonic ("_A button"); - gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); - - button = gtk_button_new_with_mnemonic ("_B button"); - gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); - - button = gtk_button_new_with_mnemonic ("_C button"); - gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); - - button = gtk_button_new_with_mnemonic ("_D button"); - gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); - - gtk_widget_show_all (window); -} - -static void -toolbar_cb (GtkAction *action, - gpointer callback_data) -{ - GtkWidget *window; - GtkWidget *vbox; - GtkWidget *label; - - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - set_gtk_window_type (GTK_WINDOW (window), "_NET_WM_WINDOW_TYPE_TOOLBAR"); - gtk_window_set_title (GTK_WINDOW (window), "Toolbar"); - - gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (callback_data)); - - vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); - - gtk_container_add (GTK_CONTAINER (window), vbox); - - label = gtk_label_new ("FIXME this needs a resize grip, etc."); - gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); - - gtk_widget_show_all (window); -} - -static void -menu_cb (GtkAction *action, - gpointer callback_data) -{ - GtkWidget *window; - GtkWidget *vbox; - GtkWidget *label; - - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - set_gtk_window_type (GTK_WINDOW (window), "_NET_WM_WINDOW_TYPE_MENU"); - gtk_window_set_title (GTK_WINDOW (window), "Menu"); - - gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (callback_data)); - - vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); - - gtk_container_add (GTK_CONTAINER (window), vbox); - - label = gtk_label_new ("FIXME this isn't a menu."); - gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); - - gtk_widget_show_all (window); -} - -static void -override_redirect_cb (GtkAction *action, - gpointer callback_data) -{ - GtkWidget *window; - GtkWidget *vbox; - GtkWidget *label; - - window = gtk_window_new (GTK_WINDOW_POPUP); - gtk_window_set_title (GTK_WINDOW (window), "Override Redirect"); - - vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); - - gtk_container_add (GTK_CONTAINER (window), vbox); - - label = gtk_label_new ("This is an override\nredirect window\nand should not be managed"); - gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); - - gtk_widget_show_all (window); -} - -static void -border_only_cb (GtkAction *action, - gpointer callback_data) -{ - GtkWidget *window; - GtkWidget *vbox; - GtkWidget *label; - - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - set_gtk_window_border_only (GTK_WINDOW (window)); - gtk_window_set_title (GTK_WINDOW (window), "Border only"); - - gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (callback_data)); - - vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); - - gtk_container_add (GTK_CONTAINER (window), vbox); - - label = gtk_label_new ("This window is supposed to have a border but no titlebar."); - gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); - - gtk_widget_show_all (window); -} - -#if 0 -static void -changing_icon_cb (GtkAction *action, - gpointer callback_data) -{ - GtkWidget *window; - GtkWidget *vbox; - GtkWidget *label; - - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_window_set_title (GTK_WINDOW (window), "Changing Icon"); - - vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); - - gtk_container_add (GTK_CONTAINER (window), vbox); - - label = gtk_label_new ("This window has an icon that changes over time"); - gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); - - gtk_widget_show_all (window); -} -#endif - -static gboolean -focus_in_event_cb (GtkWidget *window, - GdkEvent *event, - gpointer data) -{ - GtkWidget *widget; - - widget = GTK_WIDGET (data); - - gtk_label_set_text (GTK_LABEL (widget), "Has focus"); - - return TRUE; -} - - -static gboolean -focus_out_event_cb (GtkWidget *window, - GdkEvent *event, - gpointer data) -{ - GtkWidget *widget; - - widget = GTK_WIDGET (data); - - gtk_label_set_text (GTK_LABEL (widget), "Not focused"); - - return TRUE; -} - -static GtkWidget* -focus_label (GtkWidget *window) -{ - GtkWidget *label; - - label = gtk_label_new ("Not focused"); - - g_signal_connect (G_OBJECT (window), "focus_in_event", - G_CALLBACK (focus_in_event_cb), label); - - g_signal_connect (G_OBJECT (window), "focus_out_event", - G_CALLBACK (focus_out_event_cb), label); - - return label; -} - -static void -splashscreen_cb (GtkAction *action, - gpointer callback_data) -{ - GtkWidget *window; - GtkWidget *image; - GtkWidget *vbox; - - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - set_gtk_window_type (GTK_WINDOW (window), "_NET_WM_WINDOW_TYPE_SPLASHSCREEN"); - gtk_window_set_title (GTK_WINDOW (window), "Splashscreen"); - - vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); - - image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG); - gtk_box_pack_start (GTK_BOX (vbox), image, FALSE, FALSE, 0); - - gtk_box_pack_start (GTK_BOX (vbox), focus_label (window), FALSE, FALSE, 0); - - gtk_container_add (GTK_CONTAINER (window), vbox); - - gtk_widget_show_all (window); -} - -enum -{ - DOCK_TOP = 1, - DOCK_BOTTOM = 2, - DOCK_LEFT = 3, - DOCK_RIGHT = 4, - DOCK_ALL = 5 -}; - -static void -make_dock (int type) -{ - GtkWidget *window; - GtkWidget *image; - GtkWidget *box; - GtkWidget *button; - - g_return_if_fail (type != DOCK_ALL); - - box = NULL; - switch (type) - { - case DOCK_LEFT: - case DOCK_RIGHT: - box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); - break; - case DOCK_TOP: - case DOCK_BOTTOM: - box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); - break; - case DOCK_ALL: - break; - } - - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - set_gtk_window_type (GTK_WINDOW (window), "_NET_WM_WINDOW_TYPE_DOCK"); - - image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG); - gtk_box_pack_start (GTK_BOX (box), image, FALSE, FALSE, 0); - - gtk_box_pack_start (GTK_BOX (box), focus_label (window), FALSE, FALSE, 0); - - button = gtk_button_new_with_label ("Close"); - gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0); - - g_signal_connect_swapped (G_OBJECT (button), "clicked", - G_CALLBACK (gtk_widget_destroy), window); - - gtk_container_add (GTK_CONTAINER (window), box); - -#define DOCK_SIZE 48 - switch (type) - { - case DOCK_LEFT: - gtk_widget_set_size_request (window, DOCK_SIZE, 400); - gtk_window_move (GTK_WINDOW (window), 0, 000); - set_gtk_window_struts (window, DOCK_SIZE, 0, 0, 0); - gtk_window_set_title (GTK_WINDOW (window), "LeftDock"); - break; - case DOCK_RIGHT: - gtk_widget_set_size_request (window, DOCK_SIZE, 400); - gtk_window_move (GTK_WINDOW (window), gdk_screen_width () - DOCK_SIZE, 200); - set_gtk_window_struts (window, 0, DOCK_SIZE, 0, 0); - gtk_window_set_title (GTK_WINDOW (window), "RightDock"); - break; - case DOCK_TOP: - gtk_widget_set_size_request (window, 600, DOCK_SIZE); - gtk_window_move (GTK_WINDOW (window), 76, 0); - set_gtk_window_struts (window, 0, 0, DOCK_SIZE, 0); - gtk_window_set_title (GTK_WINDOW (window), "TopDock"); - break; - case DOCK_BOTTOM: - gtk_widget_set_size_request (window, 600, DOCK_SIZE); - gtk_window_move (GTK_WINDOW (window), 200, gdk_screen_height () - DOCK_SIZE); - set_gtk_window_struts (window, 0, 0, 0, DOCK_SIZE); - gtk_window_set_title (GTK_WINDOW (window), "BottomDock"); - break; - case DOCK_ALL: - break; - } - - gtk_widget_show_all (window); -} - -static void -dock_cb (GtkAction *action, - gpointer callback_data) -{ - guint callback_action; - const gchar *name; - - name = gtk_action_get_name (action); - - if (!g_strcmp0 (name, "Top dock")) - callback_action = DOCK_TOP; - else if (!g_strcmp0 (name, "Bottom dock")) - callback_action = DOCK_BOTTOM; - else if (!g_strcmp0 (name, "Left dock")) - callback_action = DOCK_LEFT; - else if (!g_strcmp0 (name, "Right dock")) - callback_action = DOCK_RIGHT; - else if (!g_strcmp0 (name, "All docks")) - callback_action = DOCK_ALL; - else - return; - - if (callback_action == DOCK_ALL) - { - make_dock (DOCK_TOP); - make_dock (DOCK_BOTTOM); - make_dock (DOCK_LEFT); - make_dock (DOCK_RIGHT); - } - else - { - make_dock (callback_action); - } -} - -static void -desktop_cb (GtkAction *action, - gpointer callback_data) -{ - GtkWidget *window; - GtkWidget *label; - GdkRGBA desktop_color; - - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - set_gtk_window_type (GTK_WINDOW (window), "_NET_WM_WINDOW_TYPE_DESKTOP"); - gtk_window_set_title (GTK_WINDOW (window), "Desktop"); - gtk_widget_set_size_request (window, - gdk_screen_width (), gdk_screen_height ()); - gtk_window_move (GTK_WINDOW (window), 0, 0); - - desktop_color.red = 0.32; - desktop_color.green = 0.46; - desktop_color.blue = 0.65; - desktop_color.alpha = 1.0; - - gtk_widget_override_background_color (window, 0, &desktop_color); - - label = focus_label (window); - - gtk_container_add (GTK_CONTAINER (window), label); - - gtk_widget_show_all (window); -} - -static void -sleep_cb (GtkAction *action, - gpointer data) -{ - sleep (1000); -} - -static void -toggle_aspect_ratio (GtkAction *action, - gpointer data) -{ - GtkWidget *window; - GdkGeometry geom; - GtkWidget *widget = GTK_WIDGET (data); - - if (aspect_on) - { - geom.min_aspect = 0; - geom.max_aspect = 65535; - } - else - { - geom.min_aspect = 1.777778; - geom.max_aspect = 1.777778; - } - - aspect_on = !aspect_on; - - window = gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW); - if (window) - gtk_window_set_geometry_hints (GTK_WINDOW (window), - widget, - &geom, - GDK_HINT_ASPECT); - -} - -static void -toggle_decorated_cb (GtkWidget *button, - gpointer data) -{ - GtkWidget *window; - window = gtk_widget_get_ancestor (data, GTK_TYPE_WINDOW); - if (window) - gtk_window_set_decorated (GTK_WINDOW (window), - !gtk_window_get_decorated (GTK_WINDOW (window))); -} - -static void -clicked_toolbar_cb (GtkWidget *button, - gpointer data) -{ - GtkWidget *dialog; - - dialog = gtk_message_dialog_new (GTK_WINDOW (data), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_INFO, - GTK_BUTTONS_CLOSE, - "Clicking the toolbar buttons doesn't do anything"); - - /* Close dialog on user response */ - g_signal_connect (G_OBJECT (dialog), - "response", - G_CALLBACK (gtk_widget_destroy), - NULL); - - gtk_widget_show (dialog); -} - -static void -update_statusbar (GtkTextBuffer *buffer, - GtkStatusbar *statusbar) -{ - gchar *msg; - gint row, col; - gint count; - GtkTextIter iter; - - gtk_statusbar_pop (statusbar, 0); /* clear any previous message, underflow is allowed */ - - count = gtk_text_buffer_get_char_count (buffer); - - gtk_text_buffer_get_iter_at_mark (buffer, - &iter, - gtk_text_buffer_get_insert (buffer)); - - row = gtk_text_iter_get_line (&iter); - col = gtk_text_iter_get_line_offset (&iter); - - msg = g_strdup_printf ("Cursor at row %d column %d - %d chars in document", - row, col, count); - - gtk_statusbar_push (statusbar, 0, msg); - - free (msg); -} - -static void -mark_set_callback (GtkTextBuffer *buffer, - const GtkTextIter *new_location, - GtkTextMark *mark, - gpointer data) -{ - update_statusbar (buffer, GTK_STATUSBAR (data)); -} - -static int window_count = 0; - -static void -destroy_cb (GtkWidget *w, gpointer data) -{ - --window_count; - if (window_count == 0) - gtk_main_quit (); -} - -static const gchar *menu_item_string = - "<ui>\n" - "<menubar>\n" - "<menu name='Windows' action='Windows'>\n" - "<menuitem name='Dialog' action='Dialog'/>\n" - "<menuitem name='Modal dialog' action='Modal dialog'/>\n" - "<menuitem name='Parentless dialog' action='Parentless dialog'/>\n" - "<menuitem name='Utility' action='Utility'/>\n" - "<menuitem name='Splashscreen' action='Splashscreen'/>\n" - "<menuitem name='Top dock' action='Top dock'/>\n" - "<menuitem name='Bottom dock' action='Bottom dock'/>\n" - "<menuitem name='Left dock' action='Left dock'/>\n" - "<menuitem name='Right dock' action='Right dock'/>\n" - "<menuitem name='All docks' action='All docks'/>\n" - "<menuitem name='Desktop' action='Desktop'/>\n" - "<menuitem name='Menu' action='Menu'/>\n" - "<menuitem name='Toolbar' action='Toolbar'/>\n" - "<menuitem name='Override Redirect' action='Override Redirect'/>\n" - "<menuitem name='Border Only' action='Border Only'/>\n" - "</menu>\n" - "</menubar>\n" - "<toolbar>\n" - "<toolitem name='New' action='New'/>\n" - "<toolitem name='Lock' action='Lock'/>\n" - "<toolitem name='Decorations' action='Decorations'/>\n" - "<toolitem name='Ratio' action='Ratio'/>\n" - "<toolitem name='Quit' action='Quit'/>\n" - "</toolbar>\n" - "</ui>\n"; - -static const GtkActionEntry menu_items[] = -{ - { "Windows", NULL, "_Windows", NULL, - NULL, NULL }, - { "Dialog", NULL, "_Dialog", "<control>d", - NULL, G_CALLBACK (dialog_cb) }, - { "Modal dialog", NULL, "_Modal dialog", NULL, - NULL, G_CALLBACK (modal_dialog_cb) }, - { "Parentless dialog", NULL, "_Parentless dialog", NULL, - NULL, G_CALLBACK (no_parent_dialog_cb) }, - { "Utility", NULL, "_Utility", "<control>u", - NULL, G_CALLBACK (utility_cb) }, - { "Splashscreen", NULL, "_Splashscreen", "<control>s", - NULL, G_CALLBACK (splashscreen_cb) }, - { "Top dock", NULL, "_Top dock", NULL, - NULL, G_CALLBACK (dock_cb) }, - { "Bottom dock", NULL, "_Bottom dock", NULL, - NULL, G_CALLBACK (dock_cb) }, - { "Left dock", NULL, "_Left dock", NULL, - NULL, G_CALLBACK (dock_cb) }, - { "Right dock", NULL, "_Right dock", NULL, - NULL, G_CALLBACK (dock_cb) }, - { "All docks", NULL, "_All docks", NULL, - NULL, G_CALLBACK (dock_cb) }, - { "Desktop", NULL, "Des_ktop", NULL, - NULL, G_CALLBACK (desktop_cb) }, - { "Menu", NULL, "Me_nu", NULL, - NULL, G_CALLBACK (menu_cb) }, - { "Toolbar", NULL, "Tool_bar", NULL, - NULL, G_CALLBACK (toolbar_cb) }, - { "Override Redirect", NULL, "Override Redirect", NULL, - NULL, G_CALLBACK (override_redirect_cb) }, - { "Border Only", NULL, "Border Only", NULL, - NULL, G_CALLBACK (border_only_cb) } -}; - -static const GtkActionEntry tool_items[] = -{ - { "New", GTK_STOCK_NEW, NULL, NULL, - "Open another one of these windows", G_CALLBACK (do_appwindow) }, - { "Lock", GTK_STOCK_OPEN, NULL, NULL, - "This is a demo button that" - " locks up the demo", G_CALLBACK (sleep_cb) }, - { "Decorations", GTK_STOCK_OPEN, NULL, NULL, - "This is a demo button that " - "toggles window decorations", G_CALLBACK (toggle_decorated_cb) }, - { "Quit", GTK_STOCK_QUIT, NULL, NULL, - "This is a demo button with " - " a 'quit' icon", G_CALLBACK (clicked_toolbar_cb) }, - { "Ratio", GTK_STOCK_OPEN, NULL, NULL, - "This is a demo button that locks the aspect ratio " - "using a hint", G_CALLBACK (toggle_aspect_ratio) } -}; - -static GtkWidget * -do_appwindow (void) -{ - GtkWidget *window; - GtkWidget *grid; - GtkWidget *statusbar; - GtkWidget *contents; - GtkWidget *sw; - GtkTextBuffer *buffer; - GtkActionGroup *action_group; - GtkUIManager *ui_manager; - - /* Create the toplevel window - */ - - ++window_count; - - aspect_on = FALSE; - - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_window_set_title (GTK_WINDOW (window), "Application Window"); - - g_signal_connect (G_OBJECT (window), "destroy", - G_CALLBACK (destroy_cb), NULL); - - grid = gtk_grid_new (); - - gtk_widget_set_vexpand (grid, TRUE); - gtk_widget_set_hexpand (grid, TRUE); - - gtk_container_add (GTK_CONTAINER (window), grid); - - /* Create the menubar - */ - - contents = gtk_text_view_new (); - - action_group = gtk_action_group_new ("mainmenu"); - gtk_action_group_add_actions (action_group, - menu_items, - G_N_ELEMENTS (menu_items), - window); - gtk_action_group_add_actions (action_group, - tool_items, - G_N_ELEMENTS (tool_items), - window); - - ui_manager = gtk_ui_manager_new (); - - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - - /* create menu items */ - - gtk_ui_manager_add_ui_from_string (ui_manager, menu_item_string, -1, NULL); - - gtk_grid_attach (GTK_GRID (grid), - gtk_ui_manager_get_widget (ui_manager, "/ui/menubar"), - 0, 0, 1, 1); - - gtk_widget_set_hexpand (gtk_ui_manager_get_widget (ui_manager, "/ui/menubar"), - TRUE); - - /* Create document - */ - - sw = gtk_scrolled_window_new (NULL, NULL); - - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), - GTK_SHADOW_IN); - - gtk_grid_attach (GTK_GRID (grid), - sw, - 0, 2, 1, 1); - - gtk_widget_set_hexpand (sw, TRUE); - gtk_widget_set_vexpand (sw, TRUE); - - gtk_window_set_default_size (GTK_WINDOW (window), - 200, 200); - - gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (contents), - PANGO_WRAP_WORD); - - gtk_container_add (GTK_CONTAINER (sw), - contents); - - /* Create the toolbar - */ - - gtk_grid_attach (GTK_GRID (grid), - gtk_ui_manager_get_widget (ui_manager, "/ui/toolbar"), - 0, 1, 1, 1); - - gtk_widget_set_hexpand (gtk_ui_manager_get_widget (ui_manager, "/ui/toolbar"), - TRUE); - - /* Create statusbar */ - - statusbar = gtk_statusbar_new (); - gtk_grid_attach (GTK_GRID (grid), - statusbar, - 0, 3, 1, 1); - - gtk_widget_set_hexpand (statusbar, - TRUE); - - /* Show text widget info in the statusbar */ - buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (contents)); - - gtk_text_buffer_set_text (buffer, - "This demo demonstrates various kinds of windows that " - "window managers and window manager themes should handle. " - "Be sure to tear off the menu and toolbar, those are also " - "a special kind of window.", - -1); - - g_signal_connect_object (buffer, - "changed", - G_CALLBACK (update_statusbar), - statusbar, - 0); - - g_signal_connect_object (buffer, - "mark_set", /* cursor moved */ - G_CALLBACK (mark_set_callback), - statusbar, - 0); - - update_statusbar (buffer, GTK_STATUSBAR (statusbar)); - - gtk_widget_show_all (window); - - g_object_unref (ui_manager); - - return window; -} - - diff --git a/src/tools/muffin-window-demo.png b/src/tools/muffin-window-demo.png deleted file mode 100644 index d87f8296e7666871e3d2662c18601aaf23017049..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3453 zcmV-@4TAECP)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm00004XF*Lt006O% z3;baP000d%Nkl<Zc%1E-Yph+xb;o~e_CAk$eXp+{IL0IfV;oGBM@_Lr8by$%A!$R1 zP+MpMB+yn>XmBbur3#T!8a1d@t3>Jt8jxC5RM1DDMW|}2TOLYC112%GNic~+!pp%9 z5BomPIeX8{TB{%SHg+68xFmdIq^)z#J~Mm%|5<DO*P7YzdV9US-d=CVYHv7cY6H-H zE$5I|(&^)${K&;1pArdYf-iCBYaxW+z2(N+4jgODWxsyjpHx-+#GQ9<djz-)82r3I zAKt==I$X8ovTKV@dB?Klz4Oj``^uGT&zPF*^^1$#ea}@}uDI@4<3!{`4{rb7!PPH+ zZitU)#qs{UYReU?L}csOSXr!EGZClv4|fC0PF=UWJF&D=PQO&W`|NXnq1yS)Z$EVS zxXXXz{Ih0e7p~dyou>dk1AOnbB5(o=_><!kB`a2qRnspG!*Gz-59f3F)DNcf{ue7* zep0^={^wU-bNOeE7<kPC+jjMUCxH83BkaI&2wb)0@(0RNmYlYJxepdnSF?|nPW8HH zY+R8}J$-8awDnV?H=eq5_OvsWc?j|sAOGY>wjLZiJ+pAu{6aMX{_J>@@7#KW?A&_8 zD~iKowWAKcYReVpOW?k>>n43>y3P}m-R`m#{n>qc7A8VrG1j>^KO0d6ksu-jK+N(Z zx88L7=3m;p@qvf7?_LhP{ope%{J^I3C&#;Q&N-<e^5cCo&;0ep@BM0b^Ew9{VAHRD z&KFDIsKHefa`V)R9&<BwKIsi(oge>b;NugWys%KkdX%$Bh!A#*_>CciZK`R7yZvbh z<p)3Z`<H%W$5$Vo1GWKN_lF<4V)^pPzbryHB}K=?h$(T_nTdaS@kh+w{=|;?`RZE_ zJ@kXW+PU?HCl^cNr!4T>e{k6)-EQZfC#SlWv(B$vwPfkuJ#&Nk+2PkiD91#?10wRp zTW-8<c;whCuD;~cAY1OZ<*qyHDn9q68!kU@Y)SXxA_R~E4Ae8#Fp@PhiWNB<!;~2e zE9T}$kL-GE?`I#~`OH19n!qQn{rK$CscvuC%Km{D_6^IK>5;mzAR^mE!sl<f@wVMp zU-{nmtXq51wY{Rau+s~uJEo4q_Db_US6j1k<<#bGucXuI5JCVEFi3Smb0Wn|RVON| zs58vX51Aj0SXfAm>bUi>NB4Z{iSPgT2a6)G<+E3PzU&mAE=m^mzc89KvjNEeiiGR` z;cx!&@%Nqg*3&Qil}-QF?{?1ajdkdhfubys5KxRDp}7iy5Gcxk0HG+!$;dIGn#nOD z7<C;P#6*>pDkbIy6?5}L2E#})eg43U3s>HM@8kb{JOV!v1HFFv(V6Mt{uHfn=lY^3 z|LK++Z+jl#o#&jf?!)ij^o@SMzh=o;k50c!rwH^Xrs$M?2E!T3P#}c?0TF@Vm;)k| zrBR6?$q+hNj&yom`UYl@)G0!s-|G-#A`Wcz@|BZYKX~!kpS=679XFkjz?IircG2{K zp`@r^xb>#5{QZ#~FS+R42PY>d){IXqVcD`(tX#F0Ri|vE8qVOZ9C+~=7UrKv1VRX? zIiYCeC99DwA*CP=qTmRHIGs*OUyM3N%241ID9RE<sZ*rW315Ei1#i3m{(BzVeOv-& z8Z2_%tv7w;&Lca0;d7VXylna8n(>J-)^FIv>a}lWY-}l2HH(Bm9L<x{Jl%c|TyQr+ z>8Kmv1aI6bSb<8wi;R>3&5o1-kAbob^gA8uULxi|(GAD|M1)l*FTE3Z>(L0jTuOX< z`>x&J-oER*M|SwVkNxubXKq+?<HSUt)oa#q@|)g9w>t*njD|A|M*A7eJ&yz3&NwDU z2!e<ZihyC58R|y%gqx!-APx?yin{?qc0)}`mPtuT*>N$7BCOi9dEM-Hc0Rl9NPH(O z=H9aLlrQ$WUB>$3tT<^MWv4^dioyH~6lI5MZ~#KV(q(HPGy&~6gaA11;5hCX_Xdz- z7@&<XK@i-bFbD$Uy*{08pb#)qsyZ_q#H){n@3;hh=VR|VZ){0tbEj8O_IpfBtpc2? zo~J0gy!7G^0i)j=Cs`zE)qs|O1L}giVy>7OW{$fYii>QxJF1GB;sumN7j;3TL_#2& zW0q0#jf*C*Vg2eq3ZbAVOHNvKIt0NiBc{yE?4>_G2?#M|QoVp9@bZdVGqF0V8OJd* zn!3STYdGpoGEfsdIaw7EqZA<&P9cG$nVj=cF&?*0@AWz#?)17y5s*%gx*AXhp{f?> zlpW^gUH}5_2{pr|)x?9V?iqJ&R@@8`!Q4OsCZO3lR5v&(;Ns-$SOC+2iQp-a3tJq4 z3qP>w^r9OG0wEN1%RV`c7*=x-3bbyLQlpCjQv)}0t32k0Y8#ZA+SPCFrI>IB5hp67 zthhB~%)v#l91(GF!*Jvn71A*YocWeh&J)1gaWhh?$=QiHzU<d-3Q{1RQIFt?ngfl= zbE`gPG!}A4%`iU*8q6Xlkb;v;QO{r*RZtvUkRXj^7ek;E3S2;fAVnbM3II35P&AEj z2c!fPwT$MBnj!*fjqf*r4FpUL%|^Cn#j`8XX{6S{Tu~G1tkhK^rHrcKY7|AWeNhBV zoSc<phPp66n5NfTLJ%XT*s4kfNdys6R&vfrP@q|9Cu82qra9RRm!`aMjFhcar9jL| zMyO*ZRtXD$Dk|QnSMWy`MPN9r_qYg}m6Rf*(SS}_lFZQ@8}MX68r{cnNtm{P-7t5u z<~E460hx@P70pe2Xm+wDL?EVSe9XeA$|QHJc053EzxQZ3k13;HzUiL(Q&Q>}sZ*kk z0~Ut!Bps48GKy6LNE50`${AI~X#8HS$*_))^&nUyr6!<bHq09GYEGRZF*~EWCaYqA zDVP{;%-nbPcm8!z767PY`meGReyyq^AtXd9iWCsZ<dm^sgrcOW${Y2;9mktQrABC7 zF(xIcVh);>Y>Au=RVAxXRhbmqz}G~s8fg|2ie7p9u`nJtkv+F}`b%}KWXp`|A%oF8 z!)nN2RFN%`t+7DLhc0y^YZJ_lQ^iEgjWrqzWwI(cgR7BJW>k-;>zY(21`9P+N~jv< zf(vvya`USq@OOWE-+f8*^Hm+G>qu1%sp}y*kErWNOwIk2YqC1#N=%8Ajg*xb6K0B8 zCTVV6MNvR4Q$=mE_%M^QGfWwyAghs*;%fBAy8pTL&Ye4sh4F+ZW^;3+%euYtzD8LB zT~$IMltsV@jZPOr5foQPBs6lUt#4O~xsh@vre;HL*+|K#>PQ@AqGn=L%tGT{QC=<r z%TlgC9=_wA%mHkB=!vJ^_3pFIHM2Ln8E&l%dLwUHn;NA~4M?+0OiCS<l$5MW%8{y0 zq?E|Xs7H-B<dmtiHi<GrOqnW1Vyux6D9X;)?)mqfcK~Cwd!zRAl@kD1zhU*my?*af zL?&WBR9UJU>P}r}%(M+wr;eGNjhHiaQbxmws*z*eth6fGjBHL$N}ars**cL^#tpLD z@Q2^sd*}RYH3hr@m;!n&0jE`sS43dvj;9Ztx$)$?y4~<wgfL-d)G4<LVz?`HG-6JS z>KfJDSfoy**u+H~MPh17g~1@>rf7nsO*xfvq^^uuXIzZEdk&P({_v%9fp-F@04srI zz&MTUIgnow0f3$V_w@8TesSHSL5lZh)d|l=Rwvh)QOx9&$m(b^szD}>Dylj%8pbxe z8dZ+uq-a*EXoL`Ohe{K%b}UEKl-b#e$9L|L)<Y(M4Zu0T89*P1Ev&TYbIITQ=(!tL zuU__bDZ(oE(B|Q$&<Zp~TVok-Dr?uq-7uUIL2)mdjBQ}%)G<+~M2?C1xtec2aMb-f zz_7jk2lx+Q*DJO_+rs0IJvT7*2d1X_7leYTY)*<wN{x~vO{BUB(v%ZPjjXBJ|0W~Q z?AFY{tjPl@X3UJieB|M;9rq+&XaadabMpPtq6q-w`}R)vAKme6iO9QFtXR@$c~+7u zvC1S>TtM9r31}9Ib|$rElkXz9*~{5@-`;5+dGLe>aSnV7*a<uZJhNCA3N&i49(V`v z#}kwNx4h$=b-d}+6-`}}oc#yp+41m`%*~7dm|8Z@`i&>EV&xLX#(Q+Sf+LJ7W%`9# zcJJE9?DPrWKrI0G(yaXVf$svl7fV2Bg6K`aS-@uCf|ksZQ`W9Tfamt?U*uzt*__5* z9&7=>2t3(d&j2sInwJX&FbSMYqY9@1Zv@V!A+nN2uV3wp3#VD_r-9wTv%m|$b1mrS zf&IV?&B@HGYJny@PPTwgrb#w$JnVBVu#|?#!FeWV$dxpD9%xi$&;on51$O{Q?Y(`6 zeI980znqbOrq??yfTAU{v;}xDbFMfHY-|A?oKFtBS97R57`6YU_L`<y>6y0QPo1s& ztOSmHR;Rs6npo+zzf()}U<N%1QfW#8<<O=g(=1GEzsL6eF(-X3o3vo$u<r-Kv^$`m fD9#rBj_m&dggXI2l2`g900000NkvXXu0mjfkvpnL diff --git a/src/ui/draw-workspace.c b/src/ui/draw-workspace.c deleted file mode 100644 index 9a6650584..000000000 --- a/src/ui/draw-workspace.c +++ /dev/null @@ -1,184 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Draw a workspace */ - -/* This file should not be modified to depend on other files in - * libwnck or muffin, since it's used in both of them - */ - -/* - * Copyright (C) 2002 Red Hat Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. - */ - -#if HAVE_CONFIG_H -#include <config.h> -#endif - -#include "draw-workspace.h" -#include "theme-private.h" - - -static void -get_window_rect (const WnckWindowDisplayInfo *win, - int screen_width, - int screen_height, - const GdkRectangle *workspace_rect, - GdkRectangle *rect) -{ - double width_ratio, height_ratio; - int x, y, width, height; - - width_ratio = (double) workspace_rect->width / (double) screen_width; - height_ratio = (double) workspace_rect->height / (double) screen_height; - - x = win->x; - y = win->y; - width = win->width; - height = win->height; - - x *= width_ratio; - y *= height_ratio; - width *= width_ratio; - height *= height_ratio; - - x += workspace_rect->x; - y += workspace_rect->y; - - if (width < 3) - width = 3; - if (height < 3) - height = 3; - - rect->x = x; - rect->y = y; - rect->width = width; - rect->height = height; -} - -static void -draw_window (GtkWidget *widget, - cairo_t *cr, - const WnckWindowDisplayInfo *win, - const GdkRectangle *winrect, - GtkStateFlags state) -{ - gboolean is_active; - GdkRGBA color; - GtkStyleContext *style; - - is_active = win->is_active; - - cairo_save (cr); - - cairo_rectangle (cr, winrect->x, winrect->y, winrect->width, winrect->height); - cairo_clip (cr); - - style = gtk_widget_get_style_context (widget); - if (is_active) - meta_gtk_style_get_light_color (style, state, &color); - else - gtk_style_context_get_background_color (style, state, &color); - gdk_cairo_set_source_rgba (cr, &color); - - cairo_rectangle (cr, - winrect->x + 1, winrect->y + 1, - MAX (0, winrect->width - 2), MAX (0, winrect->height - 2)); - cairo_fill (cr); - - gtk_style_context_get_color (style, state, &color); - gdk_cairo_set_source_rgba (cr, &color); - cairo_set_line_width (cr, 1.0); - cairo_rectangle (cr, - winrect->x + 0.5, winrect->y + 0.5, - MAX (0, winrect->width - 1), MAX (0, winrect->height - 1)); - cairo_stroke (cr); - - cairo_restore (cr); -} - -LOCAL_SYMBOL void -wnck_draw_workspace (GtkWidget *widget, - cairo_t *cr, - int x, - int y, - int width, - int height, - int screen_width, - int screen_height, - GdkPixbuf *workspace_background, - gboolean is_active, - const WnckWindowDisplayInfo *windows, - int n_windows) -{ - int i; - GdkRectangle workspace_rect; - GtkStateFlags state; - GtkStyleContext *style; - - workspace_rect.x = x; - workspace_rect.y = y; - workspace_rect.width = width; - workspace_rect.height = height; - - if (is_active) - state = GTK_STATE_FLAG_SELECTED; - else if (workspace_background) - state = GTK_STATE_FLAG_PRELIGHT; - else - state = GTK_STATE_FLAG_NORMAL; - - style = gtk_widget_get_style_context (widget); - - cairo_save (cr); - - if (workspace_background) - { - gdk_cairo_set_source_pixbuf (cr, workspace_background, x, y); - cairo_paint (cr); - } - else - { - GdkRGBA color; - - meta_gtk_style_get_dark_color (style,state, &color); - gdk_cairo_set_source_rgba (cr, &color); - cairo_rectangle (cr, x, y, width, height); - cairo_fill (cr); - } - - i = 0; - while (i < n_windows) - { - const WnckWindowDisplayInfo *win = &windows[i]; - GdkRectangle winrect; - - get_window_rect (win, screen_width, - screen_height, &workspace_rect, &winrect); - - draw_window (widget, - cr, - win, - &winrect, - state); - - ++i; - } - - cairo_restore (cr); - -} diff --git a/src/ui/draw-workspace.h b/src/ui/draw-workspace.h deleted file mode 100644 index 028d6e8d8..000000000 --- a/src/ui/draw-workspace.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Draw a workspace */ - -/* This file should not be modified to depend on other files in - * libwnck or metacity, since it's used in both of them - */ - -/* - * Copyright (C) 2002 Red Hat Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. - */ - -#ifndef WNCK_DRAW_WORKSPACE_H -#define WNCK_DRAW_WORKSPACE_H - -#include <gdk/gdk.h> -#include <gdk-pixbuf/gdk-pixbuf.h> -#include <gtk/gtk.h> - -typedef struct -{ - int x; - int y; - int width; - int height; - - guint is_active : 1; - -} WnckWindowDisplayInfo; - -void wnck_draw_workspace (GtkWidget *widget, - cairo_t *cr, - int x, - int y, - int width, - int height, - int screen_width, - int screen_height, - GdkPixbuf *workspace_background, - gboolean is_active, - const WnckWindowDisplayInfo *windows, - int n_windows); - -#endif diff --git a/src/ui/frames.c b/src/ui/frames.c index be0751348..0486dad91 100644 --- a/src/ui/frames.c +++ b/src/ui/frames.c @@ -18,29 +18,26 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ -#include <config.h> -#include <math.h> -#include <string.h> -#include <meta/boxes.h> -#include "frames.h" -#include <meta/util.h> -#include "core.h" -#include "menu.h" -#include "window-private.h" -#include <meta/theme.h> -#include <meta/prefs.h> -#include "ui.h" +#include "config.h" #include <cairo-xlib.h> +#include <math.h> +#include <string.h> -#ifdef HAVE_SHAPE -#include <X11/extensions/shape.h> -#endif +#include "core/frame.h" +#include "core/window-private.h" +#include "meta/boxes.h" +#include "meta/prefs.h" +#include "meta/theme.h" +#include "meta/util.h" +#include "ui/ui.h" +#include "ui/frames.h" +#include "x11/meta-x11-window-control.h" +#include "x11/window-x11-private.h" +#include "x11/window-x11.h" #define DEFAULT_INNER_BUTTON_BORDER 3 @@ -48,40 +45,19 @@ static void meta_frames_destroy (GtkWidget *object); static void meta_frames_finalize (GObject *object); static void meta_frames_style_updated (GtkWidget *widget); -static void meta_frames_update_prelit_control (MetaFrames *frames, - MetaUIFrame *frame, - MetaFrameControl control); -static gboolean meta_frames_button_press_event (GtkWidget *widget, - GdkEventButton *event); -static gboolean meta_frames_button_release_event (GtkWidget *widget, - GdkEventButton *event); -static gboolean meta_frames_motion_notify_event (GtkWidget *widget, - GdkEventMotion *event); -static gboolean meta_frames_destroy_event (GtkWidget *widget, - GdkEventAny *event); static gboolean meta_frames_draw (GtkWidget *widget, cairo_t *cr); -static gboolean meta_frames_enter_notify_event (GtkWidget *widget, - GdkEventCrossing *event); -static gboolean meta_frames_leave_notify_event (GtkWidget *widget, - GdkEventCrossing *event); - -static void meta_frames_attach_style (MetaFrames *frames, - MetaUIFrame *frame); -static void meta_frames_paint (MetaFrames *frames, - MetaUIFrame *frame, - cairo_t *cr); +static void meta_ui_frame_attach_style (MetaUIFrame *frame); -static void meta_frames_calc_geometry (MetaFrames *frames, - MetaUIFrame *frame, - MetaFrameGeometry *fgeom); +static void meta_ui_frame_paint (MetaUIFrame *frame, + cairo_t *cr); -static void meta_frames_ensure_layout (MetaFrames *frames, - MetaUIFrame *frame); +static void meta_ui_frame_calc_geometry (MetaUIFrame *frame, + MetaFrameGeometry *fgeom); -static MetaUIFrame* meta_frames_lookup_window (MetaFrames *frames, - Window xwindow); +static void meta_ui_frame_update_prelit_control (MetaUIFrame *frame, + MetaFrameControl control); static void meta_frames_font_changed (MetaFrames *frames); static void meta_frames_button_layout_changed (MetaFrames *frames); @@ -89,16 +65,21 @@ static void meta_frames_button_layout_changed (MetaFrames *frames); static GdkRectangle* control_rect (MetaFrameControl control, MetaFrameGeometry *fgeom); -static MetaFrameControl get_control (MetaFrames *frames, - MetaUIFrame *frame, +static MetaFrameControl get_control (MetaUIFrame *frame, int x, int y); -static void invalidate_all_caches (MetaFrames *frames); -static void invalidate_whole_window (MetaFrames *frames, - MetaUIFrame *frame); G_DEFINE_TYPE (MetaFrames, meta_frames, GTK_TYPE_WINDOW); +enum +{ + META_ACTION_CLICK, + META_ACTION_RIGHT_CLICK, + META_ACTION_MIDDLE_CLICK, + META_ACTION_DOUBLE_CLICK, + META_ACTION_IGNORE +}; + static GObject * meta_frames_constructor (GType gtype, guint n_properties, @@ -134,12 +115,6 @@ meta_frames_class_init (MetaFramesClass *class) widget_class->style_updated = meta_frames_style_updated; widget_class->draw = meta_frames_draw; - widget_class->destroy_event = meta_frames_destroy_event; - widget_class->button_press_event = meta_frames_button_press_event; - widget_class->button_release_event = meta_frames_button_release_event; - widget_class->motion_notify_event = meta_frames_motion_notify_event; - widget_class->enter_notify_event = meta_frames_enter_notify_event; - widget_class->leave_notify_event = meta_frames_leave_notify_event; } static gint @@ -179,72 +154,54 @@ prefs_changed_callback (MetaPreference pref, } } -static GtkStyleContext * -create_style_context (MetaFrames *frames, - const gchar *variant) +static void +invalidate_whole_window (MetaUIFrame *frame) { - GtkStyleContext *style; - GdkScreen *screen; - char *theme_name; - - screen = gtk_widget_get_screen (GTK_WIDGET (frames)); - g_object_get (gtk_settings_get_for_screen (screen), - "gtk-theme-name", &theme_name, - NULL); - - style = gtk_style_context_new (); - gtk_style_context_set_path (style, - gtk_widget_get_path (GTK_WIDGET (frames))); - - if (theme_name && *theme_name) + if (!frame->is_frozen) { - GtkCssProvider *provider; - - provider = gtk_css_provider_get_named (theme_name, variant); - gtk_style_context_add_provider (style, - GTK_STYLE_PROVIDER (provider), - GTK_STYLE_PROVIDER_PRIORITY_SETTINGS); + meta_window_x11_freeze_commits (frame->meta_window); + frame->is_frozen = TRUE; } - - free (theme_name); - - return style; + gdk_window_invalidate_rect (frame->window, NULL, FALSE); } -static GtkStyleContext * +static MetaStyleInfo * meta_frames_get_theme_variant (MetaFrames *frames, const gchar *variant) { - GtkStyleContext *style; + MetaStyleInfo *style_info; - style = g_hash_table_lookup (frames->style_variants, variant); - if (style == NULL) + style_info = g_hash_table_lookup (frames->style_variants, variant); + if (style_info == NULL) { - style = create_style_context (frames, variant); - g_hash_table_insert (frames->style_variants, g_strdup (variant), style); + style_info = meta_theme_create_style_info (gtk_widget_get_screen (GTK_WIDGET (frames)), variant); + g_hash_table_insert (frames->style_variants, g_strdup (variant), style_info); } - return style; + return style_info; } static void update_style_contexts (MetaFrames *frames) { - GtkStyleContext *style; - GList *variant_list, *variant; + MetaStyleInfo *style_info; + GList *variants, *variant; + GdkScreen *screen; + + screen = gtk_widget_get_screen (GTK_WIDGET (frames)); if (frames->normal_style) - g_object_unref (frames->normal_style); - frames->normal_style = create_style_context (frames, NULL); + meta_style_info_unref (frames->normal_style); + frames->normal_style = meta_theme_create_style_info (screen, NULL); - variant_list = g_hash_table_get_keys (frames->style_variants); - for (variant = variant_list; variant; variant = variant->next) + variants = g_hash_table_get_keys (frames->style_variants); + for (variant = variants; variant; variant = variant->next) { - style = create_style_context (frames, (char *)variant->data); + style_info = meta_theme_create_style_info (screen, (char *)variant->data); g_hash_table_insert (frames->style_variants, - g_strdup (variant->data), style); + g_strdup (variant->data), style_info); } - g_list_free (variant_list); + g_list_free (variants); } static void @@ -254,17 +211,11 @@ meta_frames_init (MetaFrames *frames) frames->frames = g_hash_table_new (unsigned_long_hash, unsigned_long_equal); - frames->invalidate_cache_timeout_id = 0; - frames->invalidate_frames = NULL; - frames->cache = g_hash_table_new (g_direct_hash, g_direct_equal); - frames->style_variants = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, (GDestroyNotify)meta_style_info_unref); - free, g_object_unref); update_style_contexts (frames); - gtk_widget_set_double_buffered (GTK_WIDGET (frames), FALSE); - meta_prefs_add_listener (prefs_changed_callback, frames); } @@ -292,17 +243,14 @@ meta_frames_destroy (GtkWidget *object) /* Unmanage all frames */ for (tmp = winlist; tmp != NULL; tmp = tmp->next) { - MetaUIFrame *frame; - - frame = tmp->data; - - meta_frames_unmanage_window (frames, frame->xwindow); + MetaUIFrame *frame = tmp->data; + meta_ui_frame_unmanage (frame); } g_slist_free (winlist); if (frames->normal_style) { - g_object_unref (frames->normal_style); + meta_style_info_unref (frames->normal_style); frames->normal_style = NULL; } @@ -326,113 +274,25 @@ meta_frames_finalize (GObject *object) g_hash_table_destroy (frames->text_heights); - invalidate_all_caches (frames); - if (frames->invalidate_cache_timeout_id) { - g_source_remove (frames->invalidate_cache_timeout_id); - frames->invalidate_cache_timeout_id = 0; - } - g_assert (g_hash_table_size (frames->frames) == 0); g_hash_table_destroy (frames->frames); - g_hash_table_destroy (frames->cache); G_OBJECT_CLASS (meta_frames_parent_class)->finalize (object); } -typedef struct -{ - cairo_rectangle_int_t rect; - cairo_surface_t *pixmap; -} CachedFramePiece; - -typedef struct -{ - /* Caches of the four rendered sides in a MetaFrame. - * Order: top (titlebar), left, right, bottom. - */ - CachedFramePiece piece[4]; -} CachedPixels; - -static CachedPixels * -get_cache (MetaFrames *frames, - MetaUIFrame *frame) -{ - CachedPixels *pixels; - - pixels = g_hash_table_lookup (frames->cache, frame); - - if (!pixels) - { - pixels = g_new0 (CachedPixels, 1); - g_hash_table_insert (frames->cache, frame, pixels); - } - - return pixels; -} - -static void -invalidate_cache (MetaFrames *frames, - MetaUIFrame *frame) -{ - CachedPixels *pixels = get_cache (frames, frame); - int i; - - for (i = 0; i < 4; i++) - if (pixels->piece[i].pixmap) - cairo_surface_destroy (pixels->piece[i].pixmap); - - free (pixels); - g_hash_table_remove (frames->cache, frame); -} - -static void -invalidate_all_caches (MetaFrames *frames) -{ - GList *l; - - for (l = frames->invalidate_frames; l; l = l->next) - { - MetaUIFrame *frame = l->data; - - invalidate_cache (frames, frame); - } - - g_list_free (frames->invalidate_frames); - frames->invalidate_frames = NULL; -} - -static gboolean -invalidate_cache_timeout (gpointer data) -{ - MetaFrames *frames = data; - - invalidate_all_caches (frames); - frames->invalidate_cache_timeout_id = 0; - return FALSE; -} - static void -queue_recalc_func (gpointer key, gpointer value, gpointer data) +queue_recalc_func (gpointer key, + gpointer value, + gpointer user_data) { - MetaUIFrame *frame; - MetaFrames *frames; - - frames = META_FRAMES (data); - frame = value; - - invalidate_whole_window (frames, frame); - meta_core_queue_frame_resize (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), - frame->xwindow); - if (frame->layout) - { - /* save title to recreate layout */ - free (frame->title); + MetaUIFrame *frame = value; + MetaFrames *frames = user_data; - frame->title = g_strdup (pango_layout_get_text (frame->layout)); + invalidate_whole_window (frame); + meta_x11_wm_queue_frame_resize (frames->x11_display, + frame->xwindow); - g_object_unref (G_OBJECT (frame->layout)); - frame->layout = NULL; - } + g_clear_object (&frame->text_layout); } static void @@ -453,13 +313,8 @@ meta_frames_font_changed (MetaFrames *frames) static void queue_draw_func (gpointer key, gpointer value, gpointer data) { - MetaUIFrame *frame; - MetaFrames *frames; - - frames = META_FRAMES (data); - frame = value; - - invalidate_whole_window (frames, frame); + MetaUIFrame *frame = value; + invalidate_whole_window (frame); } static void @@ -472,13 +327,8 @@ meta_frames_button_layout_changed (MetaFrames *frames) static void reattach_style_func (gpointer key, gpointer value, gpointer data) { - MetaUIFrame *frame; - MetaFrames *frames; - - frames = META_FRAMES (data); - frame = value; - - meta_frames_attach_style (frames, frame); + MetaUIFrame *frame = value; + meta_ui_frame_attach_style (frame); } static void @@ -492,67 +342,46 @@ meta_frames_style_updated (GtkWidget *widget) update_style_contexts (frames); - g_hash_table_foreach (frames->frames, - reattach_style_func, frames); + g_hash_table_foreach (frames->frames, reattach_style_func, NULL); + + meta_display_queue_retheme_all_windows (meta_get_display ()); GTK_WIDGET_CLASS (meta_frames_parent_class)->style_updated (widget); } static void -meta_frames_ensure_layout (MetaFrames *frames, - MetaUIFrame *frame) +meta_ui_frame_ensure_layout (MetaUIFrame *frame, + MetaFrameType type) { + MetaFrames *frames = frame->frames; GtkWidget *widget; - MetaFrameFlags flags; - MetaFrameType type; - MetaFrameStyle *style; + MetaFrameLayout *layout; widget = GTK_WIDGET (frames); g_return_if_fail (gtk_widget_get_realized (widget)); - - meta_core_get (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), frame->xwindow, - META_CORE_GET_FRAME_FLAGS, &flags, - META_CORE_GET_FRAME_TYPE, &type, - META_CORE_GET_END); - - style = meta_theme_get_frame_style (meta_theme_get_current (), - type, flags); - if (style != frame->cache_style) - { - if (frame->layout) - { - /* save title to recreate layout */ - free (frame->title); + layout = meta_theme_get_frame_layout (meta_theme_get_default (), type); - frame->title = g_strdup (pango_layout_get_text (frame->layout)); - - g_object_unref (G_OBJECT (frame->layout)); - frame->layout = NULL; - } - } + if (layout != frame->cache_layout) + g_clear_object (&frame->text_layout); - frame->cache_style = style; + frame->cache_layout = layout; - if (frame->layout == NULL) + if (frame->text_layout == NULL) { gpointer key, value; PangoFontDescription *font_desc; - double scale; int size; - scale = meta_theme_get_title_scale (meta_theme_get_current (), - type, - flags); - - frame->layout = gtk_widget_create_pango_layout (widget, frame->title); + frame->text_layout = gtk_widget_create_pango_layout (widget, frame->title); - pango_layout_set_ellipsize (frame->layout, PANGO_ELLIPSIZE_END); - pango_layout_set_auto_dir (frame->layout, FALSE); + pango_layout_set_ellipsize (frame->text_layout, PANGO_ELLIPSIZE_END); + pango_layout_set_auto_dir (frame->text_layout, FALSE); + pango_layout_set_single_paragraph_mode (frame->text_layout, TRUE); - font_desc = meta_gtk_widget_get_font_desc (widget, scale, - meta_prefs_get_titlebar_font ()); + font_desc = meta_style_info_create_font_desc (frame->style_info); + meta_frame_layout_apply_scale (layout, font_desc); size = pango_font_description_get_size (font_desc); @@ -573,60 +402,50 @@ meta_frames_ensure_layout (MetaFrames *frames, GINT_TO_POINTER (frame->text_height)); } - pango_layout_set_font_description (frame->layout, + pango_layout_set_font_description (frame->text_layout, font_desc); pango_font_description_free (font_desc); - - /* Save some RAM */ - free (frame->title); - frame->title = NULL; } } static void -meta_frames_calc_geometry (MetaFrames *frames, - MetaUIFrame *frame, - MetaFrameGeometry *fgeom) +meta_ui_frame_calc_geometry (MetaUIFrame *frame, + MetaFrameGeometry *fgeom) { - int width, height; MetaFrameFlags flags; MetaFrameType type; MetaButtonLayout button_layout; - - meta_core_get (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), frame->xwindow, - META_CORE_GET_CLIENT_WIDTH, &width, - META_CORE_GET_CLIENT_HEIGHT, &height, - META_CORE_GET_FRAME_FLAGS, &flags, - META_CORE_GET_FRAME_TYPE, &type, - META_CORE_GET_END); + MetaWindowX11 *window_x11 = META_WINDOW_X11 (frame->meta_window); + MetaWindowX11Private *priv = window_x11->priv; + + flags = meta_frame_get_flags (frame->meta_window->frame); + type = meta_window_get_frame_type (frame->meta_window); - meta_frames_ensure_layout (frames, frame); + meta_ui_frame_ensure_layout (frame, type); meta_prefs_get_button_layout (&button_layout); - meta_theme_calc_geometry (meta_theme_get_current (), + meta_theme_calc_geometry (meta_theme_get_default (), + frame->style_info, type, frame->text_height, flags, - width, height, + priv->client_rect.width, + priv->client_rect.height, &button_layout, fgeom); } -LOCAL_SYMBOL MetaFrames* -meta_frames_new (int screen_number) +MetaFrames* +meta_frames_new (MetaX11Display *x11_display) { - GdkScreen *screen; MetaFrames *frames; - screen = gdk_display_get_screen (gdk_display_get_default (), - screen_number); - frames = g_object_new (META_TYPE_FRAMES, - "screen", screen, "type", GTK_WINDOW_POPUP, NULL); + frames->x11_display = x11_display; /* Put the window at an arbitrary offscreen location; the one place * it can't be is at -100x-100, since the meta_window_new() will @@ -640,6 +459,23 @@ meta_frames_new (int screen_number) return frames; } +static const char * +get_global_theme_variant (MetaFrames *frames) +{ + GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (frames)); + GtkSettings *settings = gtk_settings_get_for_screen (screen); + gboolean dark_theme_requested; + + g_object_get (settings, + "gtk-application-prefer-dark-theme", &dark_theme_requested, + NULL); + + if (dark_theme_requested) + return "dark"; + + return NULL; +} + /* In order to use a style with a window it has to be attached to that * window. Actually, the colormaps just have to match, but since GTK+ * already takes care of making sure that its cheap to attach a style @@ -647,30 +483,28 @@ meta_frames_new (int screen_number) * and attach separately for each window. */ static void -meta_frames_attach_style (MetaFrames *frames, - MetaUIFrame *frame) +meta_ui_frame_attach_style (MetaUIFrame *frame) { - gboolean has_frame; - char *variant = NULL; + MetaFrames *frames = frame->frames; + const char *variant; - if (frame->style != NULL) - g_object_unref (frame->style); + if (frame->style_info != NULL) + meta_style_info_unref (frame->style_info); - meta_core_get (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), - frame->xwindow, - META_CORE_WINDOW_HAS_FRAME, &has_frame, - META_CORE_GET_THEME_VARIANT, &variant, - META_CORE_GET_END); + variant = frame->meta_window->gtk_theme_variant; + if (variant == NULL) + variant = get_global_theme_variant (frame->frames);; - if (variant == NULL || strcmp(variant, "normal") == 0) - frame->style = g_object_ref (frames->normal_style); + if (variant == NULL || *variant == '\0') + frame->style_info = meta_style_info_ref (frames->normal_style); else - frame->style = g_object_ref (meta_frames_get_theme_variant (frames, - variant)); + frame->style_info = meta_style_info_ref (meta_frames_get_theme_variant (frames, + variant)); } -LOCAL_SYMBOL void +MetaUIFrame * meta_frames_manage_window (MetaFrames *frames, + MetaWindow *meta_window, Window xwindow, GdkWindow *window) { @@ -680,186 +514,105 @@ meta_frames_manage_window (MetaFrames *frames, frame = g_new (MetaUIFrame, 1); + frame->frames = frames; frame->window = window; gdk_window_set_user_data (frame->window, frames); - frame->style = NULL; + frame->style_info = NULL; /* Don't set event mask here, it's in frame.c */ frame->xwindow = xwindow; - frame->cache_style = NULL; - frame->layout = NULL; + frame->meta_window = meta_window; + frame->cache_layout = NULL; + frame->text_layout = NULL; frame->text_height = -1; frame->title = NULL; - frame->shape_applied = FALSE; frame->prelit_control = META_FRAME_CONTROL_NONE; + frame->button_state = META_BUTTON_STATE_NORMAL; + frame->is_frozen = FALSE; + + meta_x11_wm_grab_buttons (frames->x11_display, frame->xwindow); - meta_core_grab_buttons (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), frame->xwindow); - g_hash_table_replace (frames->frames, &frame->xwindow, frame); + + return frame; } -LOCAL_SYMBOL void -meta_frames_unmanage_window (MetaFrames *frames, - Window xwindow) +void +meta_ui_frame_unmanage (MetaUIFrame *frame) { - MetaUIFrame *frame; - - frame = g_hash_table_lookup (frames->frames, &xwindow); - - if (frame) - { - /* invalidating all caches ensures the frame - * is not actually referenced anymore - */ - invalidate_all_caches (frames); - - /* restore the cursor */ - meta_core_set_screen_cursor (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), - frame->xwindow, - META_CURSOR_DEFAULT); - - gdk_window_set_user_data (frame->window, NULL); + MetaFrames *frames = frame->frames; - if (frames->last_motion_frame == frame) - frames->last_motion_frame = NULL; - - g_hash_table_remove (frames->frames, &frame->xwindow); + /* restore the cursor */ + meta_x11_wm_set_screen_cursor (frames->x11_display, + frame->xwindow, + META_CURSOR_DEFAULT); - g_object_unref (frame->style); + gdk_window_set_user_data (frame->window, NULL); - gdk_window_destroy (frame->window); + g_hash_table_remove (frames->frames, &frame->xwindow); - if (frame->layout) - g_object_unref (G_OBJECT (frame->layout)); + meta_style_info_unref (frame->style_info); - free (frame->title); + gdk_window_destroy (frame->window); - free (frame); - } - else - meta_warning ("Frame 0x%lx not managed, can't unmanage\n", xwindow); -} + if (frame->text_layout) + g_object_unref (G_OBJECT (frame->text_layout)); -static MetaUIFrame* -meta_frames_lookup_window (MetaFrames *frames, - Window xwindow) -{ - MetaUIFrame *frame; + if (frame->is_frozen) + meta_window_x11_thaw_commits (frame->meta_window); - frame = g_hash_table_lookup (frames->frames, &xwindow); + g_free (frame->title); - return frame; + g_free (frame); } -LOCAL_SYMBOL void -meta_frames_get_borders (MetaFrames *frames, - Window xwindow, - MetaFrameBorders *borders) +void +meta_ui_frame_get_borders (MetaUIFrame *frame, + MetaFrameBorders *borders) { MetaFrameFlags flags; - MetaUIFrame *frame; MetaFrameType type; - frame = meta_frames_lookup_window (frames, xwindow); - - if (frame == NULL) - meta_bug ("No such frame 0x%lx\n", xwindow); - - meta_core_get (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), frame->xwindow, - META_CORE_GET_FRAME_FLAGS, &flags, - META_CORE_GET_FRAME_TYPE, &type, - META_CORE_GET_END); + flags = meta_frame_get_flags (frame->meta_window->frame); + type = meta_window_get_frame_type (frame->meta_window); g_return_if_fail (type < META_FRAME_TYPE_LAST); - meta_frames_ensure_layout (frames, frame); + meta_ui_frame_ensure_layout (frame, type); /* We can't get the full geometry, because that depends on * the client window size and probably we're being called * by the core move/resize code to decide on the client * window size */ - meta_theme_get_frame_borders (meta_theme_get_current (), + meta_theme_get_frame_borders (meta_theme_get_default (), + frame->style_info, type, frame->text_height, flags, borders); } -LOCAL_SYMBOL void -meta_frames_get_corner_radiuses (MetaFrames *frames, - Window xwindow, - float *top_left, - float *top_right, - float *bottom_left, - float *bottom_right) -{ - MetaUIFrame *frame; - MetaFrameGeometry fgeom; - - frame = meta_frames_lookup_window (frames, xwindow); - - meta_frames_calc_geometry (frames, frame, &fgeom); - - /* For compatibility with the code in get_visible_rect(), there's - * a mysterious sqrt() added to the corner radiuses: - * - * const float radius = sqrt(corner) + corner; - * - * It's unclear why the radius is calculated like this, but we - * need to be consistent with it. - */ - - if (top_left) - *top_left = fgeom.top_left_corner_rounded_radius + sqrt(fgeom.top_left_corner_rounded_radius); - if (top_right) - *top_right = fgeom.top_right_corner_rounded_radius + sqrt(fgeom.top_right_corner_rounded_radius); - if (bottom_left) - *bottom_left = fgeom.bottom_left_corner_rounded_radius + sqrt(fgeom.bottom_left_corner_rounded_radius); - if (bottom_right) - *bottom_right = fgeom.bottom_right_corner_rounded_radius + sqrt(fgeom.bottom_right_corner_rounded_radius); -} - -/* The client rectangle surrounds client window; it subtracts both - * the visible and invisible borders from the frame window's size. - */ -static void -get_client_rect (MetaFrameGeometry *fgeom, - int window_width, - int window_height, - cairo_rectangle_int_t *rect) -{ - rect->x = fgeom->borders.total.left; - rect->y = fgeom->borders.total.top; - rect->width = window_width - fgeom->borders.total.right - rect->x; - rect->height = window_height - fgeom->borders.total.bottom - rect->y; -} - /* The visible frame rectangle surrounds the visible portion of the * frame window; it subtracts only the invisible borders from the frame * window's size. */ static void get_visible_frame_rect (MetaFrameGeometry *fgeom, - int window_width, - int window_height, cairo_rectangle_int_t *rect) { rect->x = fgeom->borders.invisible.left; rect->y = fgeom->borders.invisible.top; - rect->width = window_width - fgeom->borders.invisible.right - rect->x; - rect->height = window_height - fgeom->borders.invisible.bottom - rect->y; + rect->width = fgeom->width - fgeom->borders.invisible.right - rect->x; + rect->height = fgeom->height - fgeom->borders.invisible.bottom - rect->y; } static cairo_region_t * -get_visible_region (MetaFrames *frames, - MetaUIFrame *frame, - MetaFrameGeometry *fgeom, - int window_width, - int window_height) +get_visible_region (MetaUIFrame *frame, + MetaFrameGeometry *fgeom) { cairo_region_t *corners_region; cairo_region_t *visible_region; @@ -867,12 +620,12 @@ get_visible_region (MetaFrames *frames, cairo_rectangle_int_t frame_rect; corners_region = cairo_region_create (); - get_visible_frame_rect (fgeom, window_width, window_height, &frame_rect); + get_visible_frame_rect (fgeom, &frame_rect); if (fgeom->top_left_corner_rounded_radius != 0) { const int corner = fgeom->top_left_corner_rounded_radius; - const float radius = sqrt(corner) + corner; + const float radius = corner; int i; for (i=0; i<corner; i++) @@ -890,7 +643,7 @@ get_visible_region (MetaFrames *frames, if (fgeom->top_right_corner_rounded_radius != 0) { const int corner = fgeom->top_right_corner_rounded_radius; - const float radius = sqrt(corner) + corner; + const float radius = corner; int i; for (i=0; i<corner; i++) @@ -908,7 +661,7 @@ get_visible_region (MetaFrames *frames, if (fgeom->bottom_left_corner_rounded_radius != 0) { const int corner = fgeom->bottom_left_corner_rounded_radius; - const float radius = sqrt(corner) + corner; + const float radius = corner; int i; for (i=0; i<corner; i++) @@ -926,7 +679,7 @@ get_visible_region (MetaFrames *frames, if (fgeom->bottom_right_corner_rounded_radius != 0) { const int corner = fgeom->bottom_right_corner_rounded_radius; - const float radius = sqrt(corner) + corner; + const float radius = corner; int i; for (i=0; i<corner; i++) @@ -948,34 +701,18 @@ get_visible_region (MetaFrames *frames, return visible_region; } -LOCAL_SYMBOL cairo_region_t * -meta_frames_get_frame_bounds (MetaFrames *frames, - Window xwindow, - int window_width, - int window_height) +cairo_region_t * +meta_ui_frame_get_bounds (MetaUIFrame *frame) { - MetaUIFrame *frame; MetaFrameGeometry fgeom; - - frame = meta_frames_lookup_window (frames, xwindow); - g_return_val_if_fail (frame != NULL, NULL); - - meta_frames_calc_geometry (frames, frame, &fgeom); - - return get_visible_region (frames, frame, - &fgeom, - window_width, window_height); + meta_ui_frame_calc_geometry (frame, &fgeom); + return get_visible_region (frame, &fgeom); } -LOCAL_SYMBOL void -meta_frames_move_resize_frame (MetaFrames *frames, - Window xwindow, - int x, - int y, - int width, - int height) +void +meta_ui_frame_move_resize (MetaUIFrame *frame, + int x, int y, int width, int height) { - MetaUIFrame *frame = meta_frames_lookup_window (frames, xwindow); int old_width, old_height; old_width = gdk_window_get_width (frame->window); @@ -984,206 +721,114 @@ meta_frames_move_resize_frame (MetaFrames *frames, gdk_window_move_resize (frame->window, x, y, width, height); if (old_width != width || old_height != height) - invalidate_whole_window (frames, frame); + invalidate_whole_window (frame); } -LOCAL_SYMBOL void -meta_frames_queue_draw (MetaFrames *frames, - Window xwindow) +void +meta_ui_frame_queue_draw (MetaUIFrame *frame) { - MetaUIFrame *frame; - - frame = meta_frames_lookup_window (frames, xwindow); - - invalidate_whole_window (frames, frame); + invalidate_whole_window (frame); } -LOCAL_SYMBOL void -meta_frames_set_title (MetaFrames *frames, - Window xwindow, - const char *title) +void +meta_ui_frame_set_title (MetaUIFrame *frame, + const char *title) { - MetaUIFrame *frame; - - frame = meta_frames_lookup_window (frames, xwindow); - - g_assert (frame); - - free (frame->title); + g_free (frame->title); frame->title = g_strdup (title); - if (frame->layout) - { - g_object_unref (frame->layout); - frame->layout = NULL; - } - - invalidate_whole_window (frames, frame); -} - -LOCAL_SYMBOL void -meta_frames_update_frame_style (MetaFrames *frames, - Window xwindow) -{ - MetaUIFrame *frame; - - frame = meta_frames_lookup_window (frames, xwindow); + g_clear_object (&frame->text_layout); - g_assert (frame); - - meta_frames_attach_style (frames, frame); - invalidate_whole_window (frames, frame); + invalidate_whole_window (frame); } -LOCAL_SYMBOL void -meta_frames_repaint_frame (MetaFrames *frames, - Window xwindow) +void +meta_ui_frame_update_style (MetaUIFrame *frame) { - MetaUIFrame *frame; - - frame = meta_frames_lookup_window (frames, xwindow); - - g_assert (frame); - - /* repaint everything, so the other frame don't - * lag behind if they are exposed - */ - gdk_window_process_all_updates (); + meta_ui_frame_attach_style (frame); + invalidate_whole_window (frame); } static void -redraw_control (MetaFrames *frames, - MetaUIFrame *frame, +redraw_control (MetaUIFrame *frame, MetaFrameControl control) { MetaFrameGeometry fgeom; GdkRectangle *rect; - - meta_frames_calc_geometry (frames, frame, &fgeom); + + meta_ui_frame_calc_geometry (frame, &fgeom); rect = control_rect (control, &fgeom); gdk_window_invalidate_rect (frame->window, rect, FALSE); - invalidate_cache (frames, frame); } -enum -{ - MOUSEWHEEL_UP = 4, - MOUSEWHEEL_DOWN = 5 -}; - static gboolean -meta_frame_titlebar_event (MetaUIFrame *frame, - GdkEventButton *event, - int action) +meta_frame_titlebar_event (MetaUIFrame *frame, + const ClutterEvent *event, + int action) { MetaFrameFlags flags; - Display *display; + MetaX11Display *x11_display; + uint32_t evtime; + float x, y; + + g_assert (event->type == CLUTTER_BUTTON_PRESS || + event->type == CLUTTER_TOUCH_BEGIN); + + x11_display = frame->frames->x11_display; + + flags = meta_frame_get_flags (frame->meta_window->frame); + + evtime = clutter_event_get_time (event); + clutter_event_get_coords (event, &x, &y); - display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); - switch (action) { case C_DESKTOP_TITLEBAR_ACTION_TOGGLE_SHADE: { - meta_core_get (display, frame->xwindow, - META_CORE_GET_FRAME_FLAGS, &flags, - META_CORE_GET_END); - if (flags & META_FRAME_ALLOWS_SHADE) { if (flags & META_FRAME_SHADED) - meta_core_unshade (display, - frame->xwindow, - event->time); + meta_window_unshade (frame->meta_window, evtime); else - meta_core_shade (display, - frame->xwindow, - event->time); + meta_window_shade (frame->meta_window, evtime); } } break; case C_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE: { - meta_core_get (display, frame->xwindow, - META_CORE_GET_FRAME_FLAGS, &flags, - META_CORE_GET_END); - if (flags & META_FRAME_ALLOWS_MAXIMIZE) { - meta_core_toggle_maximize (display, frame->xwindow); + meta_x11_wm_toggle_maximize (x11_display, frame->xwindow); } } break; case C_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE_HORIZONTALLY: { - meta_core_get (display, frame->xwindow, - META_CORE_GET_FRAME_FLAGS, &flags, - META_CORE_GET_END); - if (flags & META_FRAME_ALLOWS_MAXIMIZE) { - meta_core_toggle_maximize_horizontally (display, frame->xwindow); + meta_x11_wm_toggle_maximize_horizontally (x11_display, + frame->xwindow); } } break; case C_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE_VERTICALLY: { - meta_core_get (display, frame->xwindow, - META_CORE_GET_FRAME_FLAGS, &flags, - META_CORE_GET_END); - if (flags & META_FRAME_ALLOWS_MAXIMIZE) { - meta_core_toggle_maximize_vertically (display, frame->xwindow); + meta_x11_wm_toggle_maximize_vertically (x11_display, frame->xwindow); } } break; - case C_DESKTOP_TITLEBAR_ACTION_TOGGLE_STUCK: - { - meta_core_get (display, frame->xwindow, - META_CORE_GET_FRAME_FLAGS, &flags, - META_CORE_GET_END); - - if (flags & META_FRAME_STUCK) - meta_core_unstick (display, - frame->xwindow); - else - meta_core_stick (display, - frame->xwindow); - } - break; - - case C_DESKTOP_TITLEBAR_ACTION_TOGGLE_ABOVE: - { - meta_core_get (display, frame->xwindow, - META_CORE_GET_FRAME_FLAGS, &flags, - META_CORE_GET_END); - - if (flags & META_FRAME_ABOVE) - meta_core_unmake_above (display, - frame->xwindow); - else - meta_core_make_above (display, - frame->xwindow); - } - break; - case C_DESKTOP_TITLEBAR_ACTION_MINIMIZE: { - meta_core_get (display, frame->xwindow, - META_CORE_GET_FRAME_FLAGS, &flags, - META_CORE_GET_END); - if (flags & META_FRAME_ALLOWS_MINIMIZE) - { - meta_core_minimize (display, frame->xwindow); - } + meta_window_minimize (frame->meta_window); } break; @@ -1192,60 +837,16 @@ meta_frame_titlebar_event (MetaUIFrame *frame, break; case C_DESKTOP_TITLEBAR_ACTION_LOWER: - meta_core_user_lower_and_unfocus (display, - frame->xwindow, - event->time); + meta_x11_wm_user_lower_and_unfocus (x11_display, + frame->xwindow, + evtime); break; case C_DESKTOP_TITLEBAR_ACTION_MENU: - meta_core_show_window_menu (display, - frame->xwindow, - event->x_root, - event->y_root, - event->button, - event->time); - break; - - /* These last 3 are CDesktopTitlebarScrollAction but - since we're working with ints, it doesn't matter */ - - case C_DESKTOP_TITLEBAR_SCROLL_ACTION_SHADE: - { - meta_core_get (display, frame->xwindow, - META_CORE_GET_FRAME_FLAGS, &flags, - META_CORE_GET_END); - - if (flags & META_FRAME_ALLOWS_SHADE) - { - if (event->button == MOUSEWHEEL_DOWN && - flags & META_FRAME_SHADED) - meta_core_unshade (display, - frame->xwindow, - event->time); - else if (event->button == MOUSEWHEEL_UP && - flags & ~META_FRAME_SHADED) - meta_core_shade (display, - frame->xwindow, - event->time); - } - } - break; - - case C_DESKTOP_TITLEBAR_SCROLL_ACTION_OPACITY: - { - if (event->button == MOUSEWHEEL_UP) { - meta_core_adjust_opacity (display, - frame->xwindow, - TRUE); /* TRUE = increase */ - } else { - meta_core_adjust_opacity (display, - frame->xwindow, - FALSE); /* decrease */ - } - } - break; - - case C_DESKTOP_TITLEBAR_SCROLL_ACTION_NONE: + meta_x11_wm_show_window_menu (x11_display, + frame->xwindow, + META_WINDOW_MENU_WM, + x, y, evtime); break; } @@ -1253,8 +854,8 @@ meta_frame_titlebar_event (MetaUIFrame *frame, } static gboolean -meta_frame_double_click_event (MetaUIFrame *frame, - GdkEventButton *event) +meta_frame_double_click_event (MetaUIFrame *frame, + const ClutterEvent *event) { int action = meta_prefs_get_action_double_click_titlebar (); @@ -1262,450 +863,364 @@ meta_frame_double_click_event (MetaUIFrame *frame, } static gboolean -meta_frame_middle_click_event (MetaUIFrame *frame, - GdkEventButton *event) +meta_frame_middle_click_event (MetaUIFrame *frame, + ClutterButtonEvent *event) { int action = meta_prefs_get_action_middle_click_titlebar(); - return meta_frame_titlebar_event (frame, event, action); + return meta_frame_titlebar_event (frame, (const ClutterEvent *) event, + action); } static gboolean -meta_frame_right_click_event(MetaUIFrame *frame, - GdkEventButton *event) +meta_frame_right_click_event (MetaUIFrame *frame, + ClutterButtonEvent *event) { int action = meta_prefs_get_action_right_click_titlebar(); - return meta_frame_titlebar_event (frame, event, action); + return meta_frame_titlebar_event (frame, (const ClutterEvent *) event, + action); } static gboolean -meta_frame_scroll_wheel_event (MetaUIFrame *frame, - GdkEventButton *event) +meta_frames_try_grab_op (MetaUIFrame *frame, + MetaGrabOp op, + gdouble grab_x, + gdouble grab_y, + guint32 time) { - int action = meta_prefs_get_action_scroll_wheel_titlebar(); + MetaFrames *frames = frame->frames; + gboolean ret; - return meta_frame_titlebar_event (frame, event, action); -} + ret = meta_x11_wm_begin_grab_op (frames->x11_display, + frame->xwindow, + op, + FALSE, + TRUE, + frame->grab_button, + 0, + time, + grab_x, grab_y); + if (!ret) + { + frames->current_grab_op = op; + frames->grab_frame = frame; + frames->grab_x = grab_x; + frames->grab_y = grab_y; + } + else + frames->grab_touch = NULL; -static gboolean -meta_frame_double_click_edge_event (MetaUIFrame *frame, - GdkEventButton *event, - MetaFrameControl control) -{ - switch (control) { - case META_FRAME_CONTROL_RESIZE_N: - case META_FRAME_CONTROL_RESIZE_S: - return meta_frame_titlebar_event (frame, - event, - C_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE_VERTICALLY); - case META_FRAME_CONTROL_RESIZE_E: - case META_FRAME_CONTROL_RESIZE_W: - return meta_frame_titlebar_event (frame, - event, - C_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE_HORIZONTALLY); - default: - return FALSE; - } + return ret; } static gboolean -meta_frames_button_press_event (GtkWidget *widget, - GdkEventButton *event) +meta_frames_retry_grab_op (MetaFrames *frames, + guint time) { - MetaUIFrame *frame; - MetaFrames *frames; - MetaFrameControl control; - Display *display; + MetaGrabOp op; + gboolean ret; - frames = META_FRAMES (widget); - display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); + if (frames->current_grab_op == META_GRAB_OP_NONE) + return TRUE; - /* Remember that the display may have already done something with this event. - * If so there's probably a GrabOp in effect. - */ + op = frames->current_grab_op; + frames->current_grab_op = META_GRAB_OP_NONE; - frame = meta_frames_lookup_window (frames, GDK_WINDOW_XID (event->window)); - if (frame == NULL) - return FALSE; + ret = meta_x11_wm_begin_grab_op (frames->x11_display, + frames->grab_frame->xwindow, + op, + FALSE, + TRUE, + frames->grab_frame->grab_button, + 0, + time, + frames->grab_x, + frames->grab_y); + if (ret) + frames->grab_touch = NULL; - control = get_control (frames, frame, event->x, event->y); + return ret; +} - /* focus on click, even if click was on client area */ - if (event->button == 1 && - !(control == META_FRAME_CONTROL_MINIMIZE || - control == META_FRAME_CONTROL_DELETE || - control == META_FRAME_CONTROL_MAXIMIZE)) +static MetaGrabOp +grab_op_from_resize_control (MetaFrameControl control) +{ + switch (control) { - meta_topic (META_DEBUG_FOCUS, - "Focusing window with frame 0x%lx due to button 1 press\n", - frame->xwindow); - meta_core_user_focus (display, - frame->xwindow, - event->time); + case META_FRAME_CONTROL_RESIZE_SE: + return META_GRAB_OP_RESIZING_SE; + case META_FRAME_CONTROL_RESIZE_S: + return META_GRAB_OP_RESIZING_S; + case META_FRAME_CONTROL_RESIZE_SW: + return META_GRAB_OP_RESIZING_SW; + case META_FRAME_CONTROL_RESIZE_NE: + return META_GRAB_OP_RESIZING_NE; + case META_FRAME_CONTROL_RESIZE_N: + return META_GRAB_OP_RESIZING_N; + case META_FRAME_CONTROL_RESIZE_NW: + return META_GRAB_OP_RESIZING_NW; + case META_FRAME_CONTROL_RESIZE_E: + return META_GRAB_OP_RESIZING_E; + case META_FRAME_CONTROL_RESIZE_W: + return META_GRAB_OP_RESIZING_W; + default: + g_assert_not_reached (); + return META_GRAB_OP_NONE; } +} - /* don't do the rest of this if on client area */ - if (control == META_FRAME_CONTROL_CLIENT_AREA) - return FALSE; /* not on the frame, just passed through from client */ - - /* We want to shade even if we have a GrabOp, since we'll have a move grab - * if we double click the titlebar. - */ - if (control == META_FRAME_CONTROL_TITLE && - event->button == 1 && - event->type == GDK_2BUTTON_PRESS) +static guint +get_action (const ClutterEvent *event) +{ + if (event->type == CLUTTER_BUTTON_PRESS || + event->type == CLUTTER_BUTTON_RELEASE) { - meta_core_end_grab_op (display, event->time); - return meta_frame_double_click_event (frame, event); - } - - if (event->button == 1 && - event->type == GDK_2BUTTON_PRESS && - (control == META_FRAME_CONTROL_RESIZE_N || - control == META_FRAME_CONTROL_RESIZE_S || - control == META_FRAME_CONTROL_RESIZE_E || - control == META_FRAME_CONTROL_RESIZE_W)) + switch (event->button.button) + { + case CLUTTER_BUTTON_PRIMARY: + if (clutter_event_get_click_count (event) == 2) + return META_ACTION_DOUBLE_CLICK; + else + return META_ACTION_CLICK; + case CLUTTER_BUTTON_SECONDARY: + return META_ACTION_RIGHT_CLICK; + case CLUTTER_BUTTON_MIDDLE: + return META_ACTION_MIDDLE_CLICK; + default: + meta_verbose ("No action triggered for button %u %s\n", + event->button.button, + (event->type == CLUTTER_BUTTON_PRESS) ? "press" : "release"); + } + } + else if (event->type == CLUTTER_TOUCH_BEGIN || + event->type == CLUTTER_TOUCH_UPDATE || + event->type == CLUTTER_TOUCH_END) { - meta_core_end_grab_op (display, event->time); - return meta_frame_double_click_edge_event (frame, event, control); + return META_ACTION_CLICK; } - if (meta_core_get_grab_op (display) != - META_GRAB_OP_NONE) - return FALSE; /* already up to something */ - - if (event->button == 1 && - (control == META_FRAME_CONTROL_MAXIMIZE || - control == META_FRAME_CONTROL_UNMAXIMIZE || - control == META_FRAME_CONTROL_MINIMIZE || - control == META_FRAME_CONTROL_DELETE || - control == META_FRAME_CONTROL_SHADE || - control == META_FRAME_CONTROL_UNSHADE || - control == META_FRAME_CONTROL_ABOVE || - control == META_FRAME_CONTROL_UNABOVE || - control == META_FRAME_CONTROL_STICK || - control == META_FRAME_CONTROL_UNSTICK || - control == META_FRAME_CONTROL_MENU)) - { - MetaGrabOp op = META_GRAB_OP_NONE; + return META_ACTION_IGNORE; +} - switch (control) - { - case META_FRAME_CONTROL_MINIMIZE: - op = META_GRAB_OP_CLICKING_MINIMIZE; - break; - case META_FRAME_CONTROL_MAXIMIZE: - op = META_GRAB_OP_CLICKING_MAXIMIZE; - break; - case META_FRAME_CONTROL_UNMAXIMIZE: - op = META_GRAB_OP_CLICKING_UNMAXIMIZE; - break; - case META_FRAME_CONTROL_DELETE: - op = META_GRAB_OP_CLICKING_DELETE; - break; - case META_FRAME_CONTROL_MENU: - op = META_GRAB_OP_CLICKING_MENU; - break; - case META_FRAME_CONTROL_SHADE: - op = META_GRAB_OP_CLICKING_SHADE; - break; - case META_FRAME_CONTROL_UNSHADE: - op = META_GRAB_OP_CLICKING_UNSHADE; - break; - case META_FRAME_CONTROL_ABOVE: - op = META_GRAB_OP_CLICKING_ABOVE; - break; - case META_FRAME_CONTROL_UNABOVE: - op = META_GRAB_OP_CLICKING_UNABOVE; - break; - case META_FRAME_CONTROL_STICK: - op = META_GRAB_OP_CLICKING_STICK; - break; - case META_FRAME_CONTROL_UNSTICK: - op = META_GRAB_OP_CLICKING_UNSTICK; - break; - default: - g_assert_not_reached (); - break; - } +static uint32_t +get_button_number (const ClutterEvent *event) +{ + if (event->type == CLUTTER_TOUCH_BEGIN || + event->type == CLUTTER_TOUCH_UPDATE || + event->type == CLUTTER_TOUCH_END) + return -1; + else if (event->type == CLUTTER_BUTTON_PRESS || + event->type == CLUTTER_BUTTON_RELEASE) + return clutter_event_get_button (event); - meta_core_begin_grab_op (display, - frame->xwindow, - op, - TRUE, - TRUE, - event->button, - 0, - event->time, - event->x_root, - event->y_root); - + g_assert_not_reached (); + return -1; +} + +static gboolean +meta_frame_left_click_event (MetaUIFrame *frame, + const ClutterEvent *event) +{ + MetaX11Display *x11_display = frame->frames->x11_display; + MetaFrameControl control; + guint32 evtime; + gfloat x, y; + + evtime = clutter_event_get_time (event); + clutter_event_get_coords (event, &x, &y); + control = get_control (frame, x, y); + + switch (control) + { + case META_FRAME_CONTROL_MAXIMIZE: + case META_FRAME_CONTROL_UNMAXIMIZE: + case META_FRAME_CONTROL_MINIMIZE: + case META_FRAME_CONTROL_DELETE: + case META_FRAME_CONTROL_MENU: + frame->grab_button = get_button_number (event); + frame->button_state = META_BUTTON_STATE_PRESSED; frame->prelit_control = control; - redraw_control (frames, frame, control); + redraw_control (frame, control); - if (op == META_GRAB_OP_CLICKING_MENU) + if (control == META_FRAME_CONTROL_MENU) { MetaFrameGeometry fgeom; GdkRectangle *rect; - int dx, dy; - - meta_frames_calc_geometry (frames, frame, &fgeom); - - rect = control_rect (META_FRAME_CONTROL_MENU, &fgeom); - - /* get delta to convert to root coords */ - dx = event->x_root - event->x; - dy = event->y_root - event->y; - - /* Align to the right end of the menu rectangle if RTL */ - if (meta_ui_get_direction() == META_UI_DIRECTION_RTL) - dx += rect->width; - - meta_core_show_window_menu (display, - frame->xwindow, - rect->x + dx, - rect->y + rect->height + dy, - event->button, - event->time); + MetaRectangle root_rect; + int win_x, win_y; + + meta_ui_frame_calc_geometry (frame, &fgeom); + + rect = control_rect (control, &fgeom); + + gdk_window_get_position (frame->window, &win_x, &win_y); + + root_rect.x = win_x + rect->x; + root_rect.y = win_y + rect->y; + root_rect.width = rect->width; + root_rect.height = rect->height; + + /* if the compositor takes a grab for showing the menu, we will + * get a LeaveNotify event we want to ignore, to keep the pressed + * button state while the menu is open + */ + frame->maybe_ignore_leave_notify = TRUE; + meta_x11_wm_show_window_menu_for_rect (x11_display, + frame->xwindow, + META_WINDOW_MENU_WM, + &root_rect, + evtime); } - } - else if (event->button == 1 && - (control == META_FRAME_CONTROL_RESIZE_SE || - control == META_FRAME_CONTROL_RESIZE_S || - control == META_FRAME_CONTROL_RESIZE_SW || - control == META_FRAME_CONTROL_RESIZE_NE || - control == META_FRAME_CONTROL_RESIZE_N || - control == META_FRAME_CONTROL_RESIZE_NW || - control == META_FRAME_CONTROL_RESIZE_E || - control == META_FRAME_CONTROL_RESIZE_W)) - { - MetaGrabOp op; - - op = META_GRAB_OP_NONE; - - switch (control) + else { - case META_FRAME_CONTROL_RESIZE_SE: - op = META_GRAB_OP_RESIZING_SE; - break; - case META_FRAME_CONTROL_RESIZE_S: - op = META_GRAB_OP_RESIZING_S; - break; - case META_FRAME_CONTROL_RESIZE_SW: - op = META_GRAB_OP_RESIZING_SW; - break; - case META_FRAME_CONTROL_RESIZE_NE: - op = META_GRAB_OP_RESIZING_NE; - break; - case META_FRAME_CONTROL_RESIZE_N: - op = META_GRAB_OP_RESIZING_N; - break; - case META_FRAME_CONTROL_RESIZE_NW: - op = META_GRAB_OP_RESIZING_NW; - break; - case META_FRAME_CONTROL_RESIZE_E: - op = META_GRAB_OP_RESIZING_E; - break; - case META_FRAME_CONTROL_RESIZE_W: - op = META_GRAB_OP_RESIZING_W; - break; - default: - g_assert_not_reached (); - break; + meta_frames_try_grab_op (frame, META_GRAB_OP_FRAME_BUTTON, + x, y, evtime); } - meta_core_begin_grab_op (display, - frame->xwindow, - op, - TRUE, - TRUE, - event->button, - 0, - event->time, - event->x_root, - event->y_root); - } - else if (control == META_FRAME_CONTROL_TITLE && - event->button == 1) - { - MetaFrameFlags flags; + return TRUE; + case META_FRAME_CONTROL_RESIZE_SE: + case META_FRAME_CONTROL_RESIZE_S: + case META_FRAME_CONTROL_RESIZE_SW: + case META_FRAME_CONTROL_RESIZE_NE: + case META_FRAME_CONTROL_RESIZE_N: + case META_FRAME_CONTROL_RESIZE_NW: + case META_FRAME_CONTROL_RESIZE_E: + case META_FRAME_CONTROL_RESIZE_W: + meta_frames_try_grab_op (frame, + grab_op_from_resize_control (control), + x, y, evtime); + + return TRUE; + case META_FRAME_CONTROL_TITLE: + { + MetaFrameFlags flags = meta_frame_get_flags (frame->meta_window->frame); - meta_core_get (display, frame->xwindow, - META_CORE_GET_FRAME_FLAGS, &flags, - META_CORE_GET_END); + if (flags & META_FRAME_ALLOWS_MOVE) + { + meta_frames_try_grab_op (frame, + META_GRAB_OP_MOVING, + x, y, evtime); + } + } - if (flags & META_FRAME_ALLOWS_MOVE) - { - meta_core_begin_grab_op (display, - frame->xwindow, - META_GRAB_OP_MOVING, - TRUE, - TRUE, - event->button, - 0, - event->time, - event->x_root, - event->y_root); - } - } - else if (control == META_FRAME_CONTROL_TITLE && - (event->button == 4 || event->button == 5)) - { - return meta_frame_scroll_wheel_event (frame, event); - } - else if (event->button == 2) - { - return meta_frame_middle_click_event (frame, event); - } - else if (event->button == 3) - { - return meta_frame_right_click_event (frame, event); + return TRUE; + case META_FRAME_CONTROL_NONE: + /* We can get this for example when trying to resize window + * that cannot be resized (e. g. it is maximized and the theme + * currently used has borders for maximized windows), see #751884 */ + return FALSE; + default: + g_assert_not_reached (); + return FALSE; } - - return TRUE; } -LOCAL_SYMBOL void -meta_frames_notify_menu_hide (MetaFrames *frames) +static gboolean +handle_press_event (MetaUIFrame *frame, + const ClutterEvent *event) { - Display *display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); - if (meta_core_get_grab_op (display) == - META_GRAB_OP_CLICKING_MENU) + MetaFrameControl control; + uint32_t evtime, action; + float x, y; + + g_assert (event->type == CLUTTER_BUTTON_PRESS || + event->type == CLUTTER_TOUCH_BEGIN); + + action = get_action (event); + if (action == META_ACTION_IGNORE) + return FALSE; + + evtime = clutter_event_get_time (event); + clutter_event_get_coords (event, &x, &y); + control = get_control (frame, x, y); + /* don't do the rest of this if on client area */ + if (control == META_FRAME_CONTROL_CLIENT_AREA) + return FALSE; /* not on the frame, just passed through from client */ + + if (action == META_ACTION_CLICK && + !(control == META_FRAME_CONTROL_MINIMIZE || + control == META_FRAME_CONTROL_DELETE || + control == META_FRAME_CONTROL_MAXIMIZE)) { - Window grab_frame; + meta_topic (META_DEBUG_FOCUS, + "Focusing window with frame 0x%lx due to button 1 press\n", + frame->xwindow); + meta_window_focus (frame->meta_window, evtime); + } - grab_frame = meta_core_get_grab_frame (display); + /* We want to shade even if we have a GrabOp, since we'll have a move grab + * if we double click the titlebar. + */ + if (control == META_FRAME_CONTROL_TITLE && + action == META_ACTION_DOUBLE_CLICK) + { + meta_x11_wm_end_grab_op (frame->frames->x11_display, evtime); + return meta_frame_double_click_event (frame, event); + } - if (grab_frame != None) - { - MetaUIFrame *frame; + if (meta_x11_wm_get_grab_op (frame->frames->x11_display) != META_GRAB_OP_NONE) + return FALSE; /* already up to something */ - frame = meta_frames_lookup_window (frames, grab_frame); + frame->grab_button = get_button_number (event); - if (frame) - { - redraw_control (frames, frame, - META_FRAME_CONTROL_MENU); - meta_core_end_grab_op (display, CurrentTime); - } - } + switch (action) + { + case META_ACTION_CLICK: + return meta_frame_left_click_event (frame, event); + case META_ACTION_MIDDLE_CLICK: + return meta_frame_middle_click_event (frame, (ClutterButtonEvent *) event); + case META_ACTION_RIGHT_CLICK: + return meta_frame_right_click_event (frame, (ClutterButtonEvent *) event); + default: + return FALSE; } } static gboolean -meta_frames_button_release_event (GtkWidget *widget, - GdkEventButton *event) +handle_release_event (MetaUIFrame *frame, + const ClutterEvent *event) { - MetaUIFrame *frame; - MetaFrames *frames; - MetaGrabOp op; - Display *display; + guint32 evtime, button; + gfloat x, y; - frames = META_FRAMES (widget); - display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); - - frame = meta_frames_lookup_window (frames, GDK_WINDOW_XID (event->window)); - if (frame == NULL) - return FALSE; + g_assert (event->type == CLUTTER_BUTTON_RELEASE || + event->type == CLUTTER_TOUCH_END); - op = meta_core_get_grab_op (display); + evtime = clutter_event_get_time (event); + clutter_event_get_coords (event, &x, &y); + button = get_button_number (event); - if (op == META_GRAB_OP_NONE) - return FALSE; + frame->frames->current_grab_op = META_GRAB_OP_NONE; + meta_x11_wm_end_grab_op (frame->frames->x11_display, evtime); /* We only handle the releases we handled the presses for (things * involving frame controls). Window ops that don't require a * frame are handled in the Xlib part of the code, display.c/window.c */ - if (frame->xwindow == meta_core_get_grab_frame (display) && - ((int) event->button) == meta_core_get_grab_button (display)) + if (((int) button) == frame->grab_button && + frame->button_state == META_BUTTON_STATE_PRESSED) { - MetaFrameControl control; - - control = get_control (frames, frame, event->x, event->y); - - switch (op) + switch (frame->prelit_control) { - case META_GRAB_OP_CLICKING_MINIMIZE: - if (control == META_FRAME_CONTROL_MINIMIZE) - meta_core_minimize (display, frame->xwindow); - - meta_core_end_grab_op (display, event->time); - break; - - case META_GRAB_OP_CLICKING_MAXIMIZE: - if (control == META_FRAME_CONTROL_MAXIMIZE) - { - /* Focus the window on the maximize */ - meta_core_user_focus (display, - frame->xwindow, - event->time); - meta_core_maximize (display, frame->xwindow); - } - meta_core_end_grab_op (display, event->time); - break; - - case META_GRAB_OP_CLICKING_UNMAXIMIZE: - if (control == META_FRAME_CONTROL_UNMAXIMIZE) - meta_core_unmaximize (display, frame->xwindow); - - meta_core_end_grab_op (display, event->time); - break; - - case META_GRAB_OP_CLICKING_DELETE: - if (control == META_FRAME_CONTROL_DELETE) - meta_core_delete (display, frame->xwindow, event->time); - - meta_core_end_grab_op (display, event->time); - break; - - case META_GRAB_OP_CLICKING_MENU: - meta_core_end_grab_op (display, event->time); - break; - - case META_GRAB_OP_CLICKING_SHADE: - if (control == META_FRAME_CONTROL_SHADE) - meta_core_shade (display, frame->xwindow, event->time); - - meta_core_end_grab_op (display, event->time); - break; - - case META_GRAB_OP_CLICKING_UNSHADE: - if (control == META_FRAME_CONTROL_UNSHADE) - meta_core_unshade (display, frame->xwindow, event->time); - - meta_core_end_grab_op (display, event->time); - break; - - case META_GRAB_OP_CLICKING_ABOVE: - if (control == META_FRAME_CONTROL_ABOVE) - meta_core_make_above (display, frame->xwindow); - - meta_core_end_grab_op (display, event->time); + case META_FRAME_CONTROL_MINIMIZE: + meta_window_minimize (frame->meta_window); break; - - case META_GRAB_OP_CLICKING_UNABOVE: - if (control == META_FRAME_CONTROL_UNABOVE) - meta_core_unmake_above (display, frame->xwindow); - - meta_core_end_grab_op (display, event->time); + case META_FRAME_CONTROL_MAXIMIZE: + /* Focus the window on the maximize */ + meta_window_focus (frame->meta_window, evtime); + if (meta_prefs_get_raise_on_click ()) + meta_window_raise (frame->meta_window); + meta_window_maximize (frame->meta_window, META_MAXIMIZE_BOTH); break; - - case META_GRAB_OP_CLICKING_STICK: - if (control == META_FRAME_CONTROL_STICK) - meta_core_stick (display, frame->xwindow); - - meta_core_end_grab_op (display, event->time); + case META_FRAME_CONTROL_UNMAXIMIZE: + if (meta_prefs_get_raise_on_click ()) + meta_window_raise (frame->meta_window); + meta_window_unmaximize (frame->meta_window, META_MAXIMIZE_BOTH); break; - - case META_GRAB_OP_CLICKING_UNSTICK: - if (control == META_FRAME_CONTROL_UNSTICK) - meta_core_unstick (display, frame->xwindow); - - meta_core_end_grab_op (display, event->time); + case META_FRAME_CONTROL_DELETE: + meta_window_delete (frame->meta_window, evtime); break; - default: break; } @@ -1715,21 +1230,20 @@ meta_frames_button_release_event (GtkWidget *widget, * prelit so to let the user know that it can now be pressed. * :) */ - meta_frames_update_prelit_control (frames, frame, control); + MetaFrameControl control = get_control (frame, x, y); + meta_ui_frame_update_prelit_control (frame, control); } return TRUE; } static void -meta_frames_update_prelit_control (MetaFrames *frames, - MetaUIFrame *frame, - MetaFrameControl control) +meta_ui_frame_update_prelit_control (MetaUIFrame *frame, + MetaFrameControl control) { MetaFrameControl old_control; MetaCursor cursor; - meta_verbose ("Updating prelit control from %u to %u\n", frame->prelit_control, control); @@ -1753,18 +1267,6 @@ meta_frames_update_prelit_control (MetaFrames *frames, break; case META_FRAME_CONTROL_UNMAXIMIZE: break; - case META_FRAME_CONTROL_SHADE: - break; - case META_FRAME_CONTROL_UNSHADE: - break; - case META_FRAME_CONTROL_ABOVE: - break; - case META_FRAME_CONTROL_UNABOVE: - break; - case META_FRAME_CONTROL_STICK: - break; - case META_FRAME_CONTROL_UNSTICK: - break; case META_FRAME_CONTROL_RESIZE_SE: cursor = META_CURSOR_SE_RESIZE; break; @@ -1792,9 +1294,9 @@ meta_frames_update_prelit_control (MetaFrames *frames, } /* set/unset the prelight cursor */ - meta_core_set_screen_cursor (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), - frame->xwindow, - cursor); + meta_x11_wm_set_screen_cursor (frame->frames->x11_display, + frame->xwindow, + cursor); switch (control) { @@ -1802,12 +1304,6 @@ meta_frames_update_prelit_control (MetaFrames *frames, case META_FRAME_CONTROL_MINIMIZE: case META_FRAME_CONTROL_MAXIMIZE: case META_FRAME_CONTROL_DELETE: - case META_FRAME_CONTROL_SHADE: - case META_FRAME_CONTROL_UNSHADE: - case META_FRAME_CONTROL_ABOVE: - case META_FRAME_CONTROL_UNABOVE: - case META_FRAME_CONTROL_STICK: - case META_FRAME_CONTROL_UNSTICK: case META_FRAME_CONTROL_UNMAXIMIZE: /* leave control set */ break; @@ -1817,370 +1313,168 @@ meta_frames_update_prelit_control (MetaFrames *frames, break; } - if (control == frame->prelit_control) + if (control == frame->prelit_control && + frame->button_state == META_BUTTON_STATE_PRELIGHT) return; /* Save the old control so we can unprelight it */ old_control = frame->prelit_control; + frame->button_state = META_BUTTON_STATE_PRELIGHT; frame->prelit_control = control; - redraw_control (frames, frame, old_control); - redraw_control (frames, frame, control); -} - -static gboolean -meta_frames_motion_notify_event (GtkWidget *widget, - GdkEventMotion *event) -{ - MetaUIFrame *frame; - MetaFrames *frames; - MetaGrabOp grab_op; - Display *display; - - frames = META_FRAMES (widget); - display = GDK_DISPLAY_XDISPLAY (gdk_window_get_display (event->window)); - - frame = meta_frames_lookup_window (frames, GDK_WINDOW_XID (event->window)); - if (frame == NULL) - return FALSE; - - frames->last_motion_frame = frame; - - grab_op = meta_core_get_grab_op (display); - - switch (grab_op) - { - case META_GRAB_OP_CLICKING_MENU: - case META_GRAB_OP_CLICKING_DELETE: - case META_GRAB_OP_CLICKING_MINIMIZE: - case META_GRAB_OP_CLICKING_MAXIMIZE: - case META_GRAB_OP_CLICKING_UNMAXIMIZE: - case META_GRAB_OP_CLICKING_SHADE: - case META_GRAB_OP_CLICKING_UNSHADE: - case META_GRAB_OP_CLICKING_ABOVE: - case META_GRAB_OP_CLICKING_UNABOVE: - case META_GRAB_OP_CLICKING_STICK: - case META_GRAB_OP_CLICKING_UNSTICK: - { - MetaFrameControl control; - int x, y; - - gdk_window_get_device_position (frame->window, event->device, - &x, &y, NULL); - - /* Control is set to none unless it matches - * the current grab - */ - control = get_control (frames, frame, x, y); - if (! ((control == META_FRAME_CONTROL_MENU && - grab_op == META_GRAB_OP_CLICKING_MENU) || - (control == META_FRAME_CONTROL_DELETE && - grab_op == META_GRAB_OP_CLICKING_DELETE) || - (control == META_FRAME_CONTROL_MINIMIZE && - grab_op == META_GRAB_OP_CLICKING_MINIMIZE) || - ((control == META_FRAME_CONTROL_MAXIMIZE || - control == META_FRAME_CONTROL_UNMAXIMIZE) && - (grab_op == META_GRAB_OP_CLICKING_MAXIMIZE || - grab_op == META_GRAB_OP_CLICKING_UNMAXIMIZE)) || - (control == META_FRAME_CONTROL_SHADE && - grab_op == META_GRAB_OP_CLICKING_SHADE) || - (control == META_FRAME_CONTROL_UNSHADE && - grab_op == META_GRAB_OP_CLICKING_UNSHADE) || - (control == META_FRAME_CONTROL_ABOVE && - grab_op == META_GRAB_OP_CLICKING_ABOVE) || - (control == META_FRAME_CONTROL_UNABOVE && - grab_op == META_GRAB_OP_CLICKING_UNABOVE) || - (control == META_FRAME_CONTROL_STICK && - grab_op == META_GRAB_OP_CLICKING_STICK) || - (control == META_FRAME_CONTROL_UNSTICK && - grab_op == META_GRAB_OP_CLICKING_UNSTICK))) - control = META_FRAME_CONTROL_NONE; - - /* Update prelit control and cursor */ - meta_frames_update_prelit_control (frames, frame, control); - - } - break; - case META_GRAB_OP_NONE: - { - MetaFrameControl control; - int x, y; - - gdk_window_get_device_position (frame->window, event->device, - &x, &y, NULL); - - control = get_control (frames, frame, x, y); - - /* Update prelit control and cursor */ - meta_frames_update_prelit_control (frames, frame, control); - } - break; - - default: - break; - } - - return TRUE; + redraw_control (frame, old_control); + redraw_control (frame, control); } static gboolean -meta_frames_destroy_event (GtkWidget *widget, - GdkEventAny *event) +handle_motion_event (MetaUIFrame *frame, + const ClutterEvent *event) { - MetaUIFrame *frame; - MetaFrames *frames; - - frames = META_FRAMES (widget); - - frame = meta_frames_lookup_window (frames, GDK_WINDOW_XID (event->window)); - if (frame == NULL) - return FALSE; - - return TRUE; -} + MetaFrames *frames = frame->frames; + MetaFrameControl control; + ClutterModifierType modifiers; + guint32 evtime; + gfloat x, y; + g_assert (event->type == CLUTTER_MOTION || + event->type == CLUTTER_TOUCH_UPDATE); -static void -setup_bg_cr (cairo_t *cr, GdkWindow *window, int x_offset, int y_offset) -{ - GdkWindow *parent = gdk_window_get_parent (window); - cairo_pattern_t *bg_pattern; + modifiers = clutter_event_get_state (event); + evtime = clutter_event_get_time (event); + clutter_event_get_coords (event, &x, &y); + control = get_control (frame, x, y); - bg_pattern = gdk_window_get_background_pattern (window); - if (bg_pattern == NULL && parent) + if (frame->button_state == META_BUTTON_STATE_PRESSED) { - gint window_x, window_y; - - gdk_window_get_position (window, &window_x, &window_y); - setup_bg_cr (cr, parent, x_offset + window_x, y_offset + window_y); + /* If the user leaves the frame button, set the state + * back to normal and redraw. */ + if (frame->prelit_control != control) + { + frame->button_state = META_BUTTON_STATE_NORMAL; + redraw_control (frame, frame->prelit_control); + } } - else if (bg_pattern) + else { - cairo_translate (cr, - x_offset, - y_offset); - cairo_set_source (cr, bg_pattern); - cairo_translate (cr, x_offset, y_offset); + /* Update prelit control and cursor */ + meta_ui_frame_update_prelit_control (frame, control); } -} -/* Returns a pixmap with a piece of the windows frame painted on it. -*/ - -static cairo_surface_t * -generate_pixmap (MetaFrames *frames, - MetaUIFrame *frame, - cairo_rectangle_int_t *rect) -{ - cairo_surface_t *result; - cairo_t *cr; + if (frames->current_grab_op != META_GRAB_OP_NONE && + (event->type == CLUTTER_TOUCH_UPDATE || + (event->type == CLUTTER_MOTION && + (modifiers & CLUTTER_BUTTON1_MASK)))) + meta_frames_retry_grab_op (frames, evtime); - /* do not create a pixmap for nonexisting areas */ - if (rect->width <= 0 || rect->height <= 0) - return NULL; - - result = gdk_window_create_similar_surface (frame->window, - CAIRO_CONTENT_COLOR, - rect->width, rect->height); - - cr = cairo_create (result); - cairo_translate (cr, -rect->x, -rect->y); - - setup_bg_cr (cr, frame->window, 0, 0); - cairo_paint (cr); - - meta_frames_paint (frames, frame, cr); - - cairo_destroy (cr); - - return result; + return TRUE; } - -static void -populate_cache (MetaFrames *frames, - MetaUIFrame *frame) +static cairo_region_t * +get_visible_frame_border_region (MetaUIFrame *frame) { + cairo_rectangle_int_t area; + cairo_region_t *frame_border; + MetaFrameFlags flags; + MetaFrameType type; MetaFrameBorders borders; - int width, height; - int frame_width, frame_height, screen_width, screen_height; - CachedPixels *pixels; - MetaFrameType frame_type; - MetaFrameFlags frame_flags; - int i; + MetaRectangle buffer_rect = frame->meta_window->buffer_rect; - meta_core_get (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), - frame->xwindow, - META_CORE_GET_FRAME_WIDTH, &frame_width, - META_CORE_GET_FRAME_HEIGHT, &frame_height, - META_CORE_GET_SCREEN_WIDTH, &screen_width, - META_CORE_GET_SCREEN_HEIGHT, &screen_height, - META_CORE_GET_CLIENT_WIDTH, &width, - META_CORE_GET_CLIENT_HEIGHT, &height, - META_CORE_GET_FRAME_TYPE, &frame_type, - META_CORE_GET_FRAME_FLAGS, &frame_flags, - META_CORE_GET_END); - - /* don't cache extremely large windows */ - if (frame_width > 2 * screen_width || - frame_height > 2 * screen_height) - { - return; - } + flags = meta_frame_get_flags (frame->meta_window->frame); + type = meta_window_get_frame_type (frame->meta_window); - meta_theme_get_frame_borders (meta_theme_get_current (), - frame_type, - frame->text_height, - frame_flags, + meta_theme_get_frame_borders (meta_theme_get_default (), frame->style_info, + type, frame->text_height, flags, &borders); - pixels = get_cache (frames, frame); + /* Frame rect */ + area.x = 0; + area.y = 0; + area.width = buffer_rect.width; + area.height = buffer_rect.height; - /* Setup the rectangles for the four visible frame borders. First top, then - * left, right and bottom. Top and bottom extend to the invisible borders - * while left and right snugly fit in between: - * ----- - * | | - * ----- - */ + frame_border = cairo_region_create_rectangle (&area); - /* width and height refer to the client window's - * size without any border added. */ - - /* top */ - pixels->piece[0].rect.x = borders.invisible.left; - pixels->piece[0].rect.y = borders.invisible.top; - pixels->piece[0].rect.width = width + borders.visible.left + borders.visible.right; - pixels->piece[0].rect.height = borders.visible.top; - - /* left */ - pixels->piece[1].rect.x = borders.invisible.left; - pixels->piece[1].rect.y = borders.total.top; - pixels->piece[1].rect.height = height; - pixels->piece[1].rect.width = borders.visible.left; - - /* right */ - pixels->piece[2].rect.x = borders.total.left + width; - pixels->piece[2].rect.y = borders.total.top; - pixels->piece[2].rect.width = borders.visible.right; - pixels->piece[2].rect.height = height; - - /* bottom */ - pixels->piece[3].rect.x = borders.invisible.left; - pixels->piece[3].rect.y = borders.total.top + height; - pixels->piece[3].rect.width = width + borders.visible.left + borders.visible.right; - pixels->piece[3].rect.height = borders.visible.bottom; - - for (i = 0; i < 4; i++) - { - CachedFramePiece *piece = &pixels->piece[i]; - /* generate_pixmap() returns NULL for 0 width/height pieces, but - * does so cheaply so we don't need to cache the NULL return */ - if (!piece->pixmap) - piece->pixmap = generate_pixmap (frames, frame, &piece->rect); - } + /* Client rect */ + area.x += borders.total.left; + area.y += borders.total.top; + area.width -= borders.total.left + borders.total.right; + area.height -= borders.total.top + borders.total.bottom; - if (frames->invalidate_cache_timeout_id) { - g_source_remove (frames->invalidate_cache_timeout_id); - frames->invalidate_cache_timeout_id = 0; - } - - frames->invalidate_cache_timeout_id = g_timeout_add (1000, invalidate_cache_timeout, frames); - - if (!g_list_find (frames->invalidate_frames, frame)) - frames->invalidate_frames = - g_list_prepend (frames->invalidate_frames, frame); + /* Visible frame border */ + cairo_region_subtract_rectangle (frame_border, &area); + return frame_border; } -static void -clip_to_screen (cairo_region_t *region, - MetaUIFrame *frame) +/* + * Draw the opaque and semi-opaque pixels of this frame into a mask. + * + * (0,0) in Cairo coordinates is assumed to be the top left corner of the + * invisible border. + * + * The parts of @cr's surface in the clip region are assumed to be + * initialized to fully-transparent, and the clip region is assumed to + * contain the invisible border and the visible parts of the frame, but + * not the client area. + * + * This function uses @cr to draw pixels of arbitrary color (it will + * typically be drawing in a %CAIRO_FORMAT_A8 surface, so the color is + * discarded anyway) with appropriate alpha values to reproduce this + * frame's alpha channel, as a mask to be applied to an opaque pixmap. + * + * @frame: This frame + * @frame_rect: The frame rect + * @cr: Used to draw the resulting mask + */ +void +meta_ui_frame_get_mask (MetaUIFrame *frame, + cairo_rectangle_int_t *frame_rect, + cairo_t *cr) { - cairo_rectangle_int_t frame_area; - cairo_rectangle_int_t screen_area = { 0, 0, 0, 0 }; - cairo_region_t *tmp_region; + MetaFrameBorders borders; + MetaFrameFlags flags; + cairo_surface_t *surface; + double xscale, yscale; + int scale; - /* Chop off stuff outside the screen; this optimization - * is crucial to handle huge client windows, - * like "xterm -geometry 1000x1000" - */ - meta_core_get (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), - frame->xwindow, - META_CORE_GET_FRAME_X, &frame_area.x, - META_CORE_GET_FRAME_Y, &frame_area.y, - META_CORE_GET_FRAME_WIDTH, &frame_area.width, - META_CORE_GET_FRAME_HEIGHT, &frame_area.height, - META_CORE_GET_SCREEN_WIDTH, &screen_area.width, - META_CORE_GET_SCREEN_HEIGHT, &screen_area.height, - META_CORE_GET_END); - - cairo_region_translate (region, frame_area.x, frame_area.y); - - tmp_region = cairo_region_create_rectangle (&frame_area); - cairo_region_intersect (region, tmp_region); - cairo_region_destroy (tmp_region); - - tmp_region = cairo_region_create_rectangle (&screen_area); - cairo_region_intersect (region, tmp_region); - cairo_region_destroy (tmp_region); - - cairo_region_translate (region, - frame_area.x, - frame_area.y); -} + flags = meta_frame_get_flags (frame->meta_window->frame); -static void -subtract_client_area (cairo_region_t *region, - MetaUIFrame *frame) -{ - cairo_rectangle_int_t area; - MetaFrameFlags flags; - MetaFrameType type; - MetaFrameBorders borders; - cairo_region_t *tmp_region; - Display *display; - - display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); - - meta_core_get (display, frame->xwindow, - META_CORE_GET_FRAME_FLAGS, &flags, - META_CORE_GET_FRAME_TYPE, &type, - META_CORE_GET_CLIENT_WIDTH, &area.width, - META_CORE_GET_CLIENT_HEIGHT, &area.height, - META_CORE_GET_END); - meta_theme_get_frame_borders (meta_theme_get_current (), - type, frame->text_height, flags, - &borders); + meta_style_info_set_flags (frame->style_info, flags); + meta_ui_frame_get_borders (frame, &borders); + + /* See comment in meta_frame_layout_draw_with_style() for details on HiDPI handling */ + scale = meta_theme_get_window_scaling_factor (); + surface = cairo_get_target (cr); + cairo_surface_get_device_scale (surface, &xscale, &yscale); + cairo_surface_set_device_scale (surface, scale, scale); - area.x = borders.total.left; - area.y = borders.total.top; + gtk_render_background (frame->style_info->styles[META_STYLE_ELEMENT_FRAME], cr, + borders.invisible.left / scale, + borders.invisible.top / scale, + frame_rect->width / scale, frame_rect->height / scale); + gtk_render_background (frame->style_info->styles[META_STYLE_ELEMENT_TITLEBAR], cr, + borders.invisible.left / scale, + borders.invisible.top / scale, + frame_rect->width / scale, borders.total.top / scale); - tmp_region = cairo_region_create_rectangle (&area); - cairo_region_subtract (region, tmp_region); - cairo_region_destroy (tmp_region); + cairo_surface_set_device_scale (surface, xscale, yscale); } -static void -cached_pixels_draw (CachedPixels *pixels, - cairo_t *cr, - cairo_region_t *region) +/* XXX -- this is disgusting. Find a better approach here. + * Use multiple widgets? */ +static MetaUIFrame * +find_frame_to_draw (MetaFrames *frames, + cairo_t *cr) { - cairo_region_t *region_piece; - int i; - - for (i = 0; i < 4; i++) - { - CachedFramePiece *piece; - piece = &pixels->piece[i]; + GHashTableIter iter; + MetaUIFrame *frame; - if (piece->pixmap) - { - cairo_set_source_surface (cr, piece->pixmap, - piece->rect.x, piece->rect.y); - cairo_paint (cr); + g_hash_table_iter_init (&iter, frames->frames); + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &frame)) + if (gtk_cairo_should_draw_window (cr, frame->window)) + return frame; - region_piece = cairo_region_create_rectangle (&piece->rect); - cairo_region_subtract (region, region_piece); - cairo_region_destroy (region_piece); - } - } + return NULL; } static gboolean @@ -2189,222 +1483,195 @@ meta_frames_draw (GtkWidget *widget, { MetaUIFrame *frame; MetaFrames *frames; - CachedPixels *pixels; cairo_region_t *region; - cairo_rectangle_int_t clip; - int i, n_areas; - cairo_surface_t *target; frames = META_FRAMES (widget); - target = cairo_get_target (cr); - gdk_cairo_get_clip_rectangle (cr, &clip); - g_assert (cairo_surface_get_type (target) == CAIRO_SURFACE_TYPE_XLIB); - frame = meta_frames_lookup_window (frames, cairo_xlib_surface_get_drawable (target)); + frame = find_frame_to_draw (frames, cr); if (frame == NULL) return FALSE; - populate_cache (frames, frame); - - region = cairo_region_create_rectangle (&clip); - - pixels = get_cache (frames, frame); - - cached_pixels_draw (pixels, cr, region); + region = get_visible_frame_border_region (frame); + gdk_cairo_region (cr, region); + cairo_clip (cr); - clip_to_screen (region, frame); - subtract_client_area (region, frame); - - n_areas = cairo_region_num_rectangles (region); - - for (i = 0; i < n_areas; i++) - { - cairo_rectangle_int_t area; - - cairo_region_get_rectangle (region, i, &area); - - cairo_save (cr); - - cairo_rectangle (cr, area.x, area.y, area.width, area.height); - cairo_clip (cr); - - cairo_push_group (cr); - - meta_frames_paint (frames, frame, cr); - - cairo_pop_group_to_source (cr); - cairo_paint (cr); - - cairo_restore (cr); - } + /* The target may be cleared to black or transparent, depending + * on the frame's visual; we don't want decorations to appear + * differently when the theme's decorations aren't fully opaque, + * so clear to black first + */ + cairo_paint (cr); + meta_ui_frame_paint (frame, cr); cairo_region_destroy (region); return TRUE; } static void -meta_frames_paint (MetaFrames *frames, - MetaUIFrame *frame, - cairo_t *cr) +meta_ui_frame_paint (MetaUIFrame *frame, + cairo_t *cr) { - GtkWidget *widget; MetaFrameFlags flags; MetaFrameType type; - int w, h; + cairo_surface_t *mini_icon; MetaButtonState button_states[META_BUTTON_TYPE_LAST]; - Window grab_frame; int i; + int button_type = -1; MetaButtonLayout button_layout; - MetaGrabOp grab_op; - Display *display; - - widget = GTK_WIDGET (frames); - display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); + MetaWindowX11 *window_x11 = META_WINDOW_X11 (frame->meta_window); + MetaWindowX11Private *priv = window_x11->priv; for (i = 0; i < META_BUTTON_TYPE_LAST; i++) button_states[i] = META_BUTTON_STATE_NORMAL; - grab_frame = meta_core_get_grab_frame (display); - grab_op = meta_core_get_grab_op (display); - if (grab_frame != frame->xwindow) - grab_op = META_GRAB_OP_NONE; - /* Set prelight state */ switch (frame->prelit_control) { case META_FRAME_CONTROL_MENU: - if (grab_op == META_GRAB_OP_CLICKING_MENU) - button_states[META_BUTTON_TYPE_MENU] = META_BUTTON_STATE_PRESSED; - else - button_states[META_BUTTON_TYPE_MENU] = META_BUTTON_STATE_PRELIGHT; + button_type = META_BUTTON_TYPE_MENU; break; case META_FRAME_CONTROL_MINIMIZE: - if (grab_op == META_GRAB_OP_CLICKING_MINIMIZE) - button_states[META_BUTTON_TYPE_MINIMIZE] = META_BUTTON_STATE_PRESSED; - else - button_states[META_BUTTON_TYPE_MINIMIZE] = META_BUTTON_STATE_PRELIGHT; + button_type = META_BUTTON_TYPE_MINIMIZE; break; case META_FRAME_CONTROL_MAXIMIZE: - if (grab_op == META_GRAB_OP_CLICKING_MAXIMIZE) - button_states[META_BUTTON_TYPE_MAXIMIZE] = META_BUTTON_STATE_PRESSED; - else - button_states[META_BUTTON_TYPE_MAXIMIZE] = META_BUTTON_STATE_PRELIGHT; + button_type = META_BUTTON_TYPE_MAXIMIZE; break; case META_FRAME_CONTROL_UNMAXIMIZE: - if (grab_op == META_GRAB_OP_CLICKING_UNMAXIMIZE) - button_states[META_BUTTON_TYPE_MAXIMIZE] = META_BUTTON_STATE_PRESSED; - else - button_states[META_BUTTON_TYPE_MAXIMIZE] = META_BUTTON_STATE_PRELIGHT; - break; - case META_FRAME_CONTROL_SHADE: - if (grab_op == META_GRAB_OP_CLICKING_SHADE) - button_states[META_BUTTON_TYPE_SHADE] = META_BUTTON_STATE_PRESSED; - else - button_states[META_BUTTON_TYPE_SHADE] = META_BUTTON_STATE_PRELIGHT; - break; - case META_FRAME_CONTROL_UNSHADE: - if (grab_op == META_GRAB_OP_CLICKING_UNSHADE) - button_states[META_BUTTON_TYPE_UNSHADE] = META_BUTTON_STATE_PRESSED; - else - button_states[META_BUTTON_TYPE_UNSHADE] = META_BUTTON_STATE_PRELIGHT; - break; - case META_FRAME_CONTROL_ABOVE: - if (grab_op == META_GRAB_OP_CLICKING_ABOVE) - button_states[META_BUTTON_TYPE_ABOVE] = META_BUTTON_STATE_PRESSED; - else - button_states[META_BUTTON_TYPE_ABOVE] = META_BUTTON_STATE_PRELIGHT; - break; - case META_FRAME_CONTROL_UNABOVE: - if (grab_op == META_GRAB_OP_CLICKING_UNABOVE) - button_states[META_BUTTON_TYPE_UNABOVE] = META_BUTTON_STATE_PRESSED; - else - button_states[META_BUTTON_TYPE_UNABOVE] = META_BUTTON_STATE_PRELIGHT; - break; - case META_FRAME_CONTROL_STICK: - if (grab_op == META_GRAB_OP_CLICKING_STICK) - button_states[META_BUTTON_TYPE_STICK] = META_BUTTON_STATE_PRESSED; - else - button_states[META_BUTTON_TYPE_STICK] = META_BUTTON_STATE_PRELIGHT; - break; - case META_FRAME_CONTROL_UNSTICK: - if (grab_op == META_GRAB_OP_CLICKING_UNSTICK) - button_states[META_BUTTON_TYPE_UNSTICK] = META_BUTTON_STATE_PRESSED; - else - button_states[META_BUTTON_TYPE_UNSTICK] = META_BUTTON_STATE_PRELIGHT; + button_type = META_BUTTON_TYPE_MAXIMIZE; break; case META_FRAME_CONTROL_DELETE: - if (grab_op == META_GRAB_OP_CLICKING_DELETE) - button_states[META_BUTTON_TYPE_CLOSE] = META_BUTTON_STATE_PRESSED; - else - button_states[META_BUTTON_TYPE_CLOSE] = META_BUTTON_STATE_PRELIGHT; + button_type = META_BUTTON_TYPE_CLOSE; break; default: break; } - - meta_core_get (display, frame->xwindow, - META_CORE_GET_FRAME_FLAGS, &flags, - META_CORE_GET_FRAME_TYPE, &type, - META_CORE_GET_CLIENT_WIDTH, &w, - META_CORE_GET_CLIENT_HEIGHT, &h, - META_CORE_GET_END); - meta_frames_ensure_layout (frames, frame); + if (button_type > -1) + button_states[button_type] = frame->button_state; + + mini_icon = frame->meta_window->mini_icon; + flags = meta_frame_get_flags (frame->meta_window->frame); + type = meta_window_get_frame_type (frame->meta_window); + + meta_ui_frame_ensure_layout (frame, type); meta_prefs_get_button_layout (&button_layout); - meta_theme_draw_frame_with_style (meta_theme_get_current (), - frame->style, - widget, - cr, - type, - flags, - w, h, - frame->layout, - frame->text_height, - &button_layout, - button_states); + meta_theme_draw_frame (meta_theme_get_default (), + frame->style_info, + cr, + type, + flags, + priv->client_rect.width, + priv->client_rect.height, + frame->text_layout, + frame->text_height, + &button_layout, + button_states, + mini_icon); + + if (frame->is_frozen) + { + meta_window_x11_thaw_commits (frame->meta_window); + frame->is_frozen = FALSE; + } } static gboolean -meta_frames_enter_notify_event (GtkWidget *widget, - GdkEventCrossing *event) +handle_enter_notify_event (MetaUIFrame *frame, + ClutterCrossingEvent *event) { - MetaUIFrame *frame; - MetaFrames *frames; MetaFrameControl control; - frames = META_FRAMES (widget); - - frame = meta_frames_lookup_window (frames, GDK_WINDOW_XID (event->window)); - if (frame == NULL) - return FALSE; + frame->maybe_ignore_leave_notify = FALSE; - control = get_control (frames, frame, event->x, event->y); - meta_frames_update_prelit_control (frames, frame, control); + control = get_control (frame, event->x, event->y); + meta_ui_frame_update_prelit_control (frame, control); return TRUE; } static gboolean -meta_frames_leave_notify_event (GtkWidget *widget, - GdkEventCrossing *event) +handle_leave_notify_event (MetaUIFrame *frame, + ClutterCrossingEvent *event) { - MetaUIFrame *frame; - MetaFrames *frames; + MetaGrabOp grab_op; - frames = META_FRAMES (widget); + grab_op = meta_x11_wm_get_grab_op (frame->frames->x11_display); - frame = meta_frames_lookup_window (frames, GDK_WINDOW_XID (event->window)); - if (frame == NULL) + /* ignore the first LeaveNotify event after opening a window menu + * if it is the result of a compositor grab + */ + frame->maybe_ignore_leave_notify = frame->maybe_ignore_leave_notify && + grab_op == META_GRAB_OP_COMPOSITOR; + + if (frame->maybe_ignore_leave_notify) return FALSE; - meta_frames_update_prelit_control (frames, frame, META_FRAME_CONTROL_NONE); + meta_ui_frame_update_prelit_control (frame, META_FRAME_CONTROL_NONE); return TRUE; } +gboolean +meta_ui_frame_handle_event (MetaUIFrame *frame, + const ClutterEvent *event) +{ + if (event->type == CLUTTER_TOUCH_BEGIN || + event->type == CLUTTER_TOUCH_UPDATE || + event->type == CLUTTER_TOUCH_END) + { + ClutterEventSequence *sequence; + MetaFrames *frames = frame->frames; + + /* In X11, mutter sets up passive touch grabs which basically + * means we handle those events twice (once through the passive + * grab, and then through XISelectEvents). + * + * Receiving touch events here means we are going through the + * former, but passive grabs are exclusively for gesture + * recognition purposes. + * + * We do actually want this to happen though the regular event + * selection paths to avoid breaking internal state, which means + * we will get pointer events, because we don't select for XI_Touch*. + */ + if (!meta_is_wayland_compositor ()) + return FALSE; + + sequence = clutter_event_get_event_sequence (event); + + /* Lock onto a single touch */ + if (frames->grab_touch && frames->grab_touch != sequence) + return FALSE; + + if (event->type == CLUTTER_TOUCH_BEGIN) + frames->grab_touch = sequence; + else if (event->type == CLUTTER_TOUCH_END) + frames->grab_touch = NULL; + } + + switch (event->any.type) + { + case CLUTTER_BUTTON_PRESS: + case CLUTTER_TOUCH_BEGIN: + return handle_press_event (frame, event); + case CLUTTER_BUTTON_RELEASE: + case CLUTTER_TOUCH_END: + return handle_release_event (frame, event); + case CLUTTER_MOTION: + case CLUTTER_TOUCH_UPDATE: + return handle_motion_event (frame, event); + case CLUTTER_ENTER: + return handle_enter_notify_event (frame, (ClutterCrossingEvent *) event); + case CLUTTER_LEAVE: + return handle_leave_notify_event (frame, (ClutterCrossingEvent *) event); + default: + return FALSE; + } +} + static GdkRectangle* control_rect (MetaFrameControl control, MetaFrameGeometry *fgeom) @@ -2430,24 +1697,6 @@ control_rect (MetaFrameControl control, case META_FRAME_CONTROL_UNMAXIMIZE: rect = &fgeom->max_rect.visible; break; - case META_FRAME_CONTROL_SHADE: - rect = &fgeom->shade_rect.visible; - break; - case META_FRAME_CONTROL_UNSHADE: - rect = &fgeom->unshade_rect.visible; - break; - case META_FRAME_CONTROL_ABOVE: - rect = &fgeom->above_rect.visible; - break; - case META_FRAME_CONTROL_UNABOVE: - rect = &fgeom->unabove_rect.visible; - break; - case META_FRAME_CONTROL_STICK: - rect = &fgeom->stick_rect.visible; - break; - case META_FRAME_CONTROL_UNSTICK: - rect = &fgeom->unstick_rect.visible; - break; case META_FRAME_CONTROL_RESIZE_SE: break; case META_FRAME_CONTROL_RESIZE_S: @@ -2475,29 +1724,28 @@ control_rect (MetaFrameControl control, #define TOP_RESIZE_HEIGHT 4 #define CORNER_SIZE_MULT 2 - static MetaFrameControl -get_control (MetaFrames *frames, - MetaUIFrame *frame, - int x, int y) +get_control (MetaUIFrame *frame, int root_x, int root_y) { MetaFrameGeometry fgeom; MetaFrameFlags flags; MetaFrameType type; - MetaWindow *window; - gboolean has_vert, has_horiz, has_left, has_right, has_bottom, has_top; + gboolean has_vert, has_horiz; gboolean has_north_resize; cairo_rectangle_int_t client; + int x, y; + int win_x, win_y; - window = meta_core_get_window (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), - frame->xwindow); - - meta_frames_calc_geometry (frames, frame, &fgeom); - get_client_rect (&fgeom, fgeom.width, fgeom.height, &client); + gdk_window_get_position (frame->window, &win_x, &win_y); + x = root_x - win_x; + y = root_y - win_y; + meta_window_get_client_area_rect (frame->meta_window, &client); if (META_POINT_IN_RECT (x, y, client)) return META_FRAME_CONTROL_CLIENT_AREA; - + + meta_ui_frame_calc_geometry (frame, &fgeom); + if (META_POINT_IN_RECT (x, y, fgeom.close_rect.clickable)) return META_FRAME_CONTROL_DELETE; @@ -2507,19 +1755,15 @@ get_control (MetaFrames *frames, if (META_POINT_IN_RECT (x, y, fgeom.menu_rect.clickable)) return META_FRAME_CONTROL_MENU; - meta_core_get (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), - frame->xwindow, - META_CORE_GET_FRAME_FLAGS, &flags, - META_CORE_GET_FRAME_TYPE, &type, - META_CORE_GET_END); + flags = meta_frame_get_flags (frame->meta_window->frame); + type = meta_window_get_frame_type (frame->meta_window); has_north_resize = (type != META_FRAME_TYPE_ATTACHED); has_vert = (flags & META_FRAME_ALLOWS_VERTICAL_RESIZE) != 0; has_horiz = (flags & META_FRAME_ALLOWS_HORIZONTAL_RESIZE) != 0; - has_top = (flags & META_FRAME_ALLOWS_TOP_RESIZE) != 0; - has_left = (flags & META_FRAME_ALLOWS_LEFT_RESIZE) != 0; - has_right = (flags & META_FRAME_ALLOWS_RIGHT_RESIZE) != 0; - has_bottom = (flags & META_FRAME_ALLOWS_BOTTOM_RESIZE) != 0; + + if (flags & META_FRAME_TILED_LEFT || flags & META_FRAME_TILED_RIGHT) + has_vert = has_horiz = FALSE; if (META_POINT_IN_RECT (x, y, fgeom.title_rect)) { @@ -2531,46 +1775,11 @@ get_control (MetaFrames *frames, if (META_POINT_IN_RECT (x, y, fgeom.max_rect.clickable)) { - if (flags & META_FRAME_MAXIMIZED && - (META_WINDOW_TILED_TOP (window) || - META_WINDOW_TILED_BOTTOM (window))) - return META_FRAME_CONTROL_MAXIMIZE; - if (flags & META_FRAME_MAXIMIZED) return META_FRAME_CONTROL_UNMAXIMIZE; else return META_FRAME_CONTROL_MAXIMIZE; } - - if (META_POINT_IN_RECT (x, y, fgeom.shade_rect.clickable)) - { - return META_FRAME_CONTROL_SHADE; - } - - if (META_POINT_IN_RECT (x, y, fgeom.unshade_rect.clickable)) - { - return META_FRAME_CONTROL_UNSHADE; - } - - if (META_POINT_IN_RECT (x, y, fgeom.above_rect.clickable)) - { - return META_FRAME_CONTROL_ABOVE; - } - - if (META_POINT_IN_RECT (x, y, fgeom.unabove_rect.clickable)) - { - return META_FRAME_CONTROL_UNABOVE; - } - - if (META_POINT_IN_RECT (x, y, fgeom.stick_rect.clickable)) - { - return META_FRAME_CONTROL_STICK; - } - - if (META_POINT_IN_RECT (x, y, fgeom.unstick_rect.clickable)) - { - return META_FRAME_CONTROL_UNSTICK; - } /* South resize always has priority over north resize, * in case of overlap. @@ -2579,61 +1788,61 @@ get_control (MetaFrames *frames, if (y >= (fgeom.height - fgeom.borders.total.bottom * CORNER_SIZE_MULT) && x >= (fgeom.width - fgeom.borders.total.right * CORNER_SIZE_MULT)) { - if ((has_vert && has_horiz) || (has_bottom && has_right)) + if (has_vert && has_horiz) return META_FRAME_CONTROL_RESIZE_SE; - else if (has_bottom) + else if (has_vert) return META_FRAME_CONTROL_RESIZE_S; - else if (has_right) + else if (has_horiz) return META_FRAME_CONTROL_RESIZE_E; } else if (y >= (fgeom.height - fgeom.borders.total.bottom * CORNER_SIZE_MULT) && x <= fgeom.borders.total.left * CORNER_SIZE_MULT) { - if ((has_vert && has_horiz) || (has_bottom && has_left)) + if (has_vert && has_horiz) return META_FRAME_CONTROL_RESIZE_SW; - else if (has_bottom) + else if (has_vert) return META_FRAME_CONTROL_RESIZE_S; - else if (has_left) + else if (has_horiz) return META_FRAME_CONTROL_RESIZE_W; } else if (y < (fgeom.borders.invisible.top * CORNER_SIZE_MULT) && - (x <= fgeom.borders.total.left * CORNER_SIZE_MULT) && has_north_resize) + x <= (fgeom.borders.total.left * CORNER_SIZE_MULT) && has_north_resize) { - if ((has_vert && has_horiz) || (has_top && has_left)) + if (has_vert && has_horiz) return META_FRAME_CONTROL_RESIZE_NW; - else if (has_top) + else if (has_vert) return META_FRAME_CONTROL_RESIZE_N; - else if (has_left) + else if (has_horiz) return META_FRAME_CONTROL_RESIZE_W; } else if (y < (fgeom.borders.invisible.top * CORNER_SIZE_MULT) && - x >= (fgeom.width - fgeom.borders.total.right * CORNER_SIZE_MULT) && has_north_resize) + x >= (fgeom.width - fgeom.borders.total.right * CORNER_SIZE_MULT) && has_north_resize) { - if ((has_vert && has_horiz) || (has_top && has_right)) + if (has_vert && has_horiz) return META_FRAME_CONTROL_RESIZE_NE; - else if (has_top) + else if (has_vert) return META_FRAME_CONTROL_RESIZE_N; - else if (has_right) + else if (has_horiz) return META_FRAME_CONTROL_RESIZE_E; } else if (y < (fgeom.borders.invisible.top + TOP_RESIZE_HEIGHT)) { - if (has_top && has_north_resize) + if (has_vert && has_north_resize) return META_FRAME_CONTROL_RESIZE_N; } else if (y >= (fgeom.height - fgeom.borders.total.bottom)) { - if (has_bottom) + if (has_vert) return META_FRAME_CONTROL_RESIZE_S; } else if (x <= fgeom.borders.total.left) { - if (has_left) + if (has_horiz || flags & META_FRAME_TILED_RIGHT) return META_FRAME_CONTROL_RESIZE_W; } else if (x >= (fgeom.width - fgeom.borders.total.right)) { - if (has_right) + if (has_horiz || flags & META_FRAME_TILED_LEFT) return META_FRAME_CONTROL_RESIZE_E; } @@ -2642,11 +1851,3 @@ get_control (MetaFrames *frames, else return META_FRAME_CONTROL_TITLE; } - -static void -invalidate_whole_window (MetaFrames *frames, - MetaUIFrame *frame) -{ - gdk_window_invalidate_rect (frame->window, NULL, FALSE); - invalidate_cache (frames, frame); -} diff --git a/src/ui/frames.h b/src/ui/frames.h index 97ed62227..73dee1737 100644 --- a/src/ui/frames.h +++ b/src/ui/frames.h @@ -2,9 +2,9 @@ /* Metacity window frame manager widget */ -/* +/* * Copyright (C) 2001 Havoc Pennington - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the @@ -14,11 +14,9 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_FRAMES_H @@ -26,8 +24,12 @@ #include <gtk/gtk.h> #include <gdk/gdkx.h> -#include <meta/common.h> -#include "theme-private.h" + +#include "core/main-private.h" +#include "meta/common.h" +#include "meta/types.h" +#include "ui/theme-private.h" +#include "ui/ui.h" typedef enum { @@ -38,12 +40,6 @@ typedef enum META_FRAME_CONTROL_MINIMIZE, META_FRAME_CONTROL_MAXIMIZE, META_FRAME_CONTROL_UNMAXIMIZE, - META_FRAME_CONTROL_SHADE, - META_FRAME_CONTROL_UNSHADE, - META_FRAME_CONTROL_ABOVE, - META_FRAME_CONTROL_UNABOVE, - META_FRAME_CONTROL_STICK, - META_FRAME_CONTROL_UNSTICK, META_FRAME_CONTROL_RESIZE_SE, META_FRAME_CONTROL_RESIZE_S, META_FRAME_CONTROL_RESIZE_SW, @@ -69,39 +65,47 @@ typedef enum typedef struct _MetaFrames MetaFrames; typedef struct _MetaFramesClass MetaFramesClass; -typedef struct _MetaUIFrame MetaUIFrame; - struct _MetaUIFrame { + MetaFrames *frames; + MetaWindow *meta_window; Window xwindow; GdkWindow *window; - GtkStyleContext *style; - MetaFrameStyle *cache_style; - PangoLayout *layout; + MetaStyleInfo *style_info; + MetaFrameLayout *cache_layout; + PangoLayout *text_layout; int text_height; char *title; /* NULL once we have a layout */ - guint shape_applied : 1; - + guint maybe_ignore_leave_notify : 1; + /* FIXME get rid of this, it can just be in the MetaFrames struct */ MetaFrameControl prelit_control; + MetaButtonState button_state; + int grab_button; + + gboolean is_frozen; }; struct _MetaFrames { GtkWindow parent_instance; - + + MetaX11Display *x11_display; + GHashTable *text_heights; GHashTable *frames; - MetaUIFrame *last_motion_frame; - - GtkStyleContext *normal_style; + MetaStyleInfo *normal_style; GHashTable *style_variants; - int invalidate_cache_timeout_id; - GList *invalidate_frames; - GHashTable *cache; + MetaGrabOp current_grab_op; + MetaUIFrame *grab_frame; + guint grab_button; + gdouble grab_x; + gdouble grab_y; + + ClutterEventSequence *grab_touch; }; struct _MetaFramesClass @@ -112,50 +116,34 @@ struct _MetaFramesClass GType meta_frames_get_type (void) G_GNUC_CONST; -MetaFrames *meta_frames_new (int screen_number); - -void meta_frames_manage_window (MetaFrames *frames, - Window xwindow, - GdkWindow *window); -void meta_frames_unmanage_window (MetaFrames *frames, - Window xwindow); -void meta_frames_set_title (MetaFrames *frames, - Window xwindow, - const char *title); - -void meta_frames_update_frame_style (MetaFrames *frames, - Window xwindow); - -void meta_frames_repaint_frame (MetaFrames *frames, - Window xwindow); - -void meta_frames_get_borders (MetaFrames *frames, - Window xwindow, - MetaFrameBorders *borders); - -cairo_region_t *meta_frames_get_frame_bounds (MetaFrames *frames, - Window xwindow, - int window_width, - int window_height); - -void meta_frames_get_corner_radiuses (MetaFrames *frames, - Window xwindow, - float *top_left, - float *top_right, - float *bottom_left, - float *bottom_right); - -void meta_frames_move_resize_frame (MetaFrames *frames, - Window xwindow, - int x, - int y, - int width, - int height); -void meta_frames_queue_draw (MetaFrames *frames, - Window xwindow); - -void meta_frames_notify_menu_hide (MetaFrames *frames); - -Window meta_frames_get_moving_frame (MetaFrames *frames); +MetaFrames * meta_frames_new (MetaX11Display *x11_display); + +MetaUIFrame * meta_frames_manage_window (MetaFrames *frames, + MetaWindow *meta_window, + Window xwindow, + GdkWindow *window); + +void meta_ui_frame_unmanage (MetaUIFrame *frame); + +void meta_ui_frame_set_title (MetaUIFrame *frame, + const char *title); + +void meta_ui_frame_update_style (MetaUIFrame *frame); + +void meta_ui_frame_get_borders (MetaUIFrame *frame, + MetaFrameBorders *borders); + +cairo_region_t * meta_ui_frame_get_bounds (MetaUIFrame *frame); + +void meta_ui_frame_get_mask (MetaUIFrame *frame, + cairo_rectangle_int_t *frame_rect, + cairo_t *cr); + +void meta_ui_frame_move_resize (MetaUIFrame *frame, + int x, int y, int width, int height); + +void meta_ui_frame_queue_draw (MetaUIFrame *frame); + +gboolean meta_ui_frame_handle_event (MetaUIFrame *frame, const ClutterEvent *event); #endif diff --git a/src/ui/gradient.c b/src/ui/gradient.c deleted file mode 100644 index 0d115c82c..000000000 --- a/src/ui/gradient.c +++ /dev/null @@ -1,871 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Metacity gradient rendering */ - -/* - * Copyright (C) 2001 Havoc Pennington, 99% copied from wrlib in - * WindowMaker, Copyright (C) 1997-2000 Dan Pascu and Alfredo Kojima - * Copyright (C) 2005 Elijah Newren - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. */ - -#include <meta/gradient.h> -#include <meta/util.h> -#include <string.h> - -/* This is all Alfredo's and Dan's usual very nice WindowMaker code, - * slightly GTK-ized - */ -static GdkPixbuf* meta_gradient_create_horizontal (int width, - int height, - const GdkRGBA *from, - const GdkRGBA *to); -static GdkPixbuf* meta_gradient_create_vertical (int width, - int height, - const GdkRGBA *from, - const GdkRGBA *to); -static GdkPixbuf* meta_gradient_create_diagonal (int width, - int height, - const GdkRGBA *from, - const GdkRGBA *to); -static GdkPixbuf* meta_gradient_create_multi_horizontal (int width, - int height, - const GdkRGBA *colors, - int count); -static GdkPixbuf* meta_gradient_create_multi_vertical (int width, - int height, - const GdkRGBA *colors, - int count); -static GdkPixbuf* meta_gradient_create_multi_diagonal (int width, - int height, - const GdkRGBA *colors, - int count); - - -/* Used as the destroy notification function for gdk_pixbuf_new() */ -static void -free_buffer (guchar *pixels, gpointer data) -{ - free (pixels); -} - -static GdkPixbuf* -blank_pixbuf (int width, int height, gboolean no_padding) -{ - guchar *buf; - int rowstride; - - g_return_val_if_fail (width > 0, NULL); - g_return_val_if_fail (height > 0, NULL); - - if (no_padding) - rowstride = width * 3; - else - /* Always align rows to 32-bit boundaries */ - rowstride = 4 * ((3 * width + 3) / 4); - - buf = g_try_malloc (height * rowstride); - if (!buf) - return NULL; - - return gdk_pixbuf_new_from_data (buf, GDK_COLORSPACE_RGB, - FALSE, 8, - width, height, rowstride, - free_buffer, NULL); -} - -/** - * meta_gradient_create_simple: - * @width: Width in pixels - * @height: Height in pixels - * @from: Starting color - * @to: Ending color - * @style: Gradient style - * - * Returns: (transfer full): A new linear gradient - */ -GdkPixbuf* -meta_gradient_create_simple (int width, - int height, - const GdkRGBA *from, - const GdkRGBA *to, - MetaGradientType style) -{ - switch (style) - { - case META_GRADIENT_HORIZONTAL: - return meta_gradient_create_horizontal (width, height, - from, to); - case META_GRADIENT_VERTICAL: - return meta_gradient_create_vertical (width, height, - from, to); - - case META_GRADIENT_DIAGONAL: - return meta_gradient_create_diagonal (width, height, - from, to); - case META_GRADIENT_LAST: - break; - default: - break; - } - g_assert_not_reached (); - return NULL; -} - -/** - * meta_gradient_create_multi: - * @width: Width in pixels - * @height: Height in pixels - * @colors: (array length=n_colors): Array of colors - * @n_colors: Number of colors - * @style: Gradient style - * - * Returns: (transfer full): A new multi-step linear gradient - */ -GdkPixbuf* -meta_gradient_create_multi (int width, - int height, - const GdkRGBA *colors, - int n_colors, - MetaGradientType style) -{ - - if (n_colors > 2) - { - switch (style) - { - case META_GRADIENT_HORIZONTAL: - return meta_gradient_create_multi_horizontal (width, height, colors, n_colors); - case META_GRADIENT_VERTICAL: - return meta_gradient_create_multi_vertical (width, height, colors, n_colors); - case META_GRADIENT_DIAGONAL: - return meta_gradient_create_multi_diagonal (width, height, colors, n_colors); - case META_GRADIENT_LAST: - g_assert_not_reached (); - break; - default: - break; - } - } - else if (n_colors > 1) - { - return meta_gradient_create_simple (width, height, &colors[0], &colors[1], - style); - } - else if (n_colors > 0) - { - return meta_gradient_create_simple (width, height, &colors[0], &colors[0], - style); - } - g_assert_not_reached (); - return NULL; -} - -/** - * meta_gradient_create_interwoven: (skip) - * - * Interwoven essentially means we have two vertical gradients, - * cut into horizontal strips of the given thickness, and then the strips - * are alternated. I'm not sure what it's good for, just copied since - * WindowMaker had it. - */ -GdkPixbuf* -meta_gradient_create_interwoven (int width, - int height, - const GdkRGBA colors1[2], - int thickness1, - const GdkRGBA colors2[2], - int thickness2) -{ - - int i, j, k, l, ll; - long r1, g1, b1, dr1, dg1, db1; - long r2, g2, b2, dr2, dg2, db2; - GdkPixbuf *pixbuf; - unsigned char *ptr; - unsigned char *pixels; - int rowstride; - - pixbuf = blank_pixbuf (width, height, FALSE); - if (pixbuf == NULL) - return NULL; - - pixels = gdk_pixbuf_get_pixels (pixbuf); - rowstride = gdk_pixbuf_get_rowstride (pixbuf); - - r1 = (long)(colors1[0].red*0xffffff); - g1 = (long)(colors1[0].green*0xffffff); - b1 = (long)(colors1[0].blue*0xffffff); - - r2 = (long)(colors2[0].red*0xffffff); - g2 = (long)(colors2[0].green*0xffffff); - b2 = (long)(colors2[0].blue*0xffffff); - - dr1 = ((colors1[1].red-colors1[0].red)*0xffffff)/(int)height; - dg1 = ((colors1[1].green-colors1[0].green)*0xffffff)/(int)height; - db1 = ((colors1[1].blue-colors1[0].blue)*0xffffff)/(int)height; - - dr2 = ((colors2[1].red-colors2[0].red)*0xffffff)/(int)height; - dg2 = ((colors2[1].green-colors2[0].green)*0xffffff)/(int)height; - db2 = ((colors2[1].blue-colors2[0].blue)*0xffffff)/(int)height; - - for (i=0,k=0,l=0,ll=thickness1; i<height; i++) - { - ptr = pixels + i * rowstride; - - if (k == 0) - { - ptr[0] = (unsigned char) (r1>>16); - ptr[1] = (unsigned char) (g1>>16); - ptr[2] = (unsigned char) (b1>>16); - } - else - { - ptr[0] = (unsigned char) (r2>>16); - ptr[1] = (unsigned char) (g2>>16); - ptr[2] = (unsigned char) (b2>>16); - } - - for (j=1; j <= width/2; j *= 2) - memcpy (&(ptr[j*3]), ptr, j*3); - memcpy (&(ptr[j*3]), ptr, (width - j)*3); - - if (++l == ll) - { - if (k == 0) - { - k = 1; - ll = thickness2; - } - else - { - k = 0; - ll = thickness1; - } - l = 0; - } - r1+=dr1; - g1+=dg1; - b1+=db1; - - r2+=dr2; - g2+=dg2; - b2+=db2; - } - - return pixbuf; -} - -/* - *---------------------------------------------------------------------- - * meta_gradient_create_horizontal-- - * Renders a horizontal linear gradient of the specified size in the - * GdkPixbuf format with a border of the specified type. - * - * Returns: - * A 24bit GdkPixbuf with the gradient (no alpha channel). - * - * Side effects: - * None - *---------------------------------------------------------------------- - */ -static GdkPixbuf* -meta_gradient_create_horizontal (int width, int height, - const GdkRGBA *from, - const GdkRGBA *to) -{ - int i; - long r, g, b, dr, dg, db; - GdkPixbuf *pixbuf; - unsigned char *ptr; - unsigned char *pixels; - int r0, g0, b0; - int rf, gf, bf; - int rowstride; - - pixbuf = blank_pixbuf (width, height, FALSE); - if (pixbuf == NULL) - return NULL; - - pixels = gdk_pixbuf_get_pixels (pixbuf); - ptr = pixels; - rowstride = gdk_pixbuf_get_rowstride (pixbuf); - - r0 = (guchar) (from->red * 0xff); - g0 = (guchar) (from->green * 0xff); - b0 = (guchar) (from->blue * 0xff); - rf = (guchar) (to->red * 0xff); - gf = (guchar) (to->green * 0xff); - bf = (guchar) (to->blue * 0xff); - - r = r0 << 16; - g = g0 << 16; - b = b0 << 16; - - dr = ((rf-r0)<<16)/(int)width; - dg = ((gf-g0)<<16)/(int)width; - db = ((bf-b0)<<16)/(int)width; - /* render the first line */ - for (i=0; i<width; i++) - { - *(ptr++) = (unsigned char)(r>>16); - *(ptr++) = (unsigned char)(g>>16); - *(ptr++) = (unsigned char)(b>>16); - r += dr; - g += dg; - b += db; - } - - /* copy the first line to the other lines */ - for (i=1; i<height; i++) - { - memcpy (&(pixels[i*rowstride]), pixels, rowstride); - } - return pixbuf; -} - -/* - *---------------------------------------------------------------------- - * meta_gradient_create_vertical-- - * Renders a vertical linear gradient of the specified size in the - * GdkPixbuf format with a border of the specified type. - * - * Returns: - * A 24bit GdkPixbuf with the gradient (no alpha channel). - * - * Side effects: - * None - *---------------------------------------------------------------------- - */ -static GdkPixbuf* -meta_gradient_create_vertical (int width, int height, - const GdkRGBA *from, - const GdkRGBA *to) -{ - int i, j; - long r, g, b, dr, dg, db; - GdkPixbuf *pixbuf; - unsigned char *ptr; - int r0, g0, b0; - int rf, gf, bf; - int rowstride; - unsigned char *pixels; - - pixbuf = blank_pixbuf (width, height, FALSE); - if (pixbuf == NULL) - return NULL; - - pixels = gdk_pixbuf_get_pixels (pixbuf); - rowstride = gdk_pixbuf_get_rowstride (pixbuf); - - r0 = (guchar) (from->red * 0xff); - g0 = (guchar) (from->green * 0xff); - b0 = (guchar) (from->blue * 0xff); - rf = (guchar) (to->red * 0xff); - gf = (guchar) (to->green * 0xff); - bf = (guchar) (to->blue * 0xff); - - r = r0<<16; - g = g0<<16; - b = b0<<16; - - dr = ((rf-r0)<<16)/(int)height; - dg = ((gf-g0)<<16)/(int)height; - db = ((bf-b0)<<16)/(int)height; - - for (i=0; i<height; i++) - { - ptr = pixels + i * rowstride; - - ptr[0] = (unsigned char)(r>>16); - ptr[1] = (unsigned char)(g>>16); - ptr[2] = (unsigned char)(b>>16); - - for (j=1; j <= width/2; j *= 2) - memcpy (&(ptr[j*3]), ptr, j*3); - memcpy (&(ptr[j*3]), ptr, (width - j)*3); - - r+=dr; - g+=dg; - b+=db; - } - return pixbuf; -} - - -/* - *---------------------------------------------------------------------- - * meta_gradient_create_diagonal-- - * Renders a diagonal linear gradient of the specified size in the - * GdkPixbuf format with a border of the specified type. - * - * Returns: - * A 24bit GdkPixbuf with the gradient (no alpha channel). - * - * Side effects: - * None - *---------------------------------------------------------------------- - */ - - -static GdkPixbuf* -meta_gradient_create_diagonal (int width, int height, - const GdkRGBA *from, - const GdkRGBA *to) -{ - GdkPixbuf *pixbuf, *tmp; - int j; - float a, offset; - unsigned char *ptr; - unsigned char *pixels; - int rowstride; - - if (width == 1) - return meta_gradient_create_vertical (width, height, from, to); - else if (height == 1) - return meta_gradient_create_horizontal (width, height, from, to); - - pixbuf = blank_pixbuf (width, height, FALSE); - if (pixbuf == NULL) - return NULL; - - pixels = gdk_pixbuf_get_pixels (pixbuf); - rowstride = gdk_pixbuf_get_rowstride (pixbuf); - - tmp = meta_gradient_create_horizontal (2*width-1, 1, from, to); - if (!tmp) - { - g_object_unref (G_OBJECT (pixbuf)); - return NULL; - } - - ptr = gdk_pixbuf_get_pixels (tmp); - - a = ((float)(width - 1))/((float)(height - 1)); - width = width * 3; - - /* copy the first line to the other lines with corresponding offset */ - for (j=0, offset=0.0; j<rowstride*height; j += rowstride) - { - memcpy (&(pixels[j]), &ptr[3*(int)offset], width); - offset += a; - } - - g_object_unref (G_OBJECT (tmp)); - return pixbuf; -} - - -static GdkPixbuf* -meta_gradient_create_multi_horizontal (int width, int height, - const GdkRGBA *colors, - int count) -{ - int i, j, k; - long r, g, b, dr, dg, db; - GdkPixbuf *pixbuf; - unsigned char *ptr; - unsigned char *pixels; - int width2; - int rowstride; - - g_return_val_if_fail (count > 2, NULL); - - pixbuf = blank_pixbuf (width, height, FALSE); - if (pixbuf == NULL) - return NULL; - - pixels = gdk_pixbuf_get_pixels (pixbuf); - rowstride = gdk_pixbuf_get_rowstride (pixbuf); - ptr = pixels; - - if (count > width) - count = width; - - if (count > 1) - width2 = width/(count-1); - else - width2 = width; - - k = 0; - - r = (long)(colors[0].red * 0xffffff); - g = (long)(colors[0].green * 0xffffff); - b = (long)(colors[0].blue * 0xffffff); - - /* render the first line */ - for (i=1; i<count; i++) - { - dr = (int)((colors[i].red - colors[i-1].red) *0xffffff)/(int)width2; - dg = (int)((colors[i].green - colors[i-1].green)*0xffffff)/(int)width2; - db = (int)((colors[i].blue - colors[i-1].blue) *0xffffff)/(int)width2; - for (j=0; j<width2; j++) - { - *ptr++ = (unsigned char)(r>>16); - *ptr++ = (unsigned char)(g>>16); - *ptr++ = (unsigned char)(b>>16); - r += dr; - g += dg; - b += db; - k++; - } - r = (long)(colors[i].red * 0xffffff); - g = (long)(colors[i].green * 0xffffff); - b = (long)(colors[i].blue * 0xffffff); - } - for (j=k; j<width; j++) - { - *ptr++ = (unsigned char)(r>>16); - *ptr++ = (unsigned char)(g>>16); - *ptr++ = (unsigned char)(b>>16); - } - - /* copy the first line to the other lines */ - for (i=1; i<height; i++) - { - memcpy (&(pixels[i*rowstride]), pixels, rowstride); - } - return pixbuf; -} - -static GdkPixbuf* -meta_gradient_create_multi_vertical (int width, int height, - const GdkRGBA *colors, - int count) -{ - int i, j, k; - long r, g, b, dr, dg, db; - GdkPixbuf *pixbuf; - unsigned char *ptr, *tmp, *pixels; - int height2; - int x; - int rowstride; - - g_return_val_if_fail (count > 2, NULL); - - pixbuf = blank_pixbuf (width, height, FALSE); - if (pixbuf == NULL) - return NULL; - - pixels = gdk_pixbuf_get_pixels (pixbuf); - rowstride = gdk_pixbuf_get_rowstride (pixbuf); - ptr = pixels; - - if (count > height) - count = height; - - if (count > 1) - height2 = height/(count-1); - else - height2 = height; - - k = 0; - - r = (long)(colors[0].red * 0xffffff); - g = (long)(colors[0].green * 0xffffff); - b = (long)(colors[0].blue * 0xffffff); - - for (i=1; i<count; i++) - { - dr = (int)((colors[i].red - colors[i-1].red) *0xffffff)/(int)height2; - dg = (int)((colors[i].green - colors[i-1].green)*0xffffff)/(int)height2; - db = (int)((colors[i].blue - colors[i-1].blue) *0xffffff)/(int)height2; - - for (j=0; j<height2; j++) - { - ptr[0] = (unsigned char)(r>>16); - ptr[1] = (unsigned char)(g>>16); - ptr[2] = (unsigned char)(b>>16); - - for (x=1; x <= width/2; x *= 2) - memcpy (&(ptr[x*3]), ptr, x*3); - memcpy (&(ptr[x*3]), ptr, (width - x)*3); - - ptr += rowstride; - - r += dr; - g += dg; - b += db; - k++; - } - r = (long)(colors[i].red * 0xffffff); - g = (long)(colors[i].green * 0xffffff); - b = (long)(colors[i].blue * 0xffffff); - } - - if (k<height) - { - tmp = ptr; - - ptr[0] = (unsigned char) (r>>16); - ptr[1] = (unsigned char) (g>>16); - ptr[2] = (unsigned char) (b>>16); - - for (x=1; x <= width/2; x *= 2) - memcpy (&(ptr[x*3]), ptr, x*3); - memcpy (&(ptr[x*3]), ptr, (width - x)*3); - - ptr += rowstride; - - for (j=k+1; j<height; j++) - { - memcpy (ptr, tmp, rowstride); - ptr += rowstride; - } - } - - return pixbuf; -} - - -static GdkPixbuf* -meta_gradient_create_multi_diagonal (int width, int height, - const GdkRGBA *colors, - int count) -{ - GdkPixbuf *pixbuf, *tmp; - float a, offset; - int j; - unsigned char *ptr; - unsigned char *pixels; - int rowstride; - - g_return_val_if_fail (count > 2, NULL); - - if (width == 1) - return meta_gradient_create_multi_vertical (width, height, colors, count); - else if (height == 1) - return meta_gradient_create_multi_horizontal (width, height, colors, count); - - pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, - width, height); - if (pixbuf == NULL) - return NULL; - - pixels = gdk_pixbuf_get_pixels (pixbuf); - rowstride = gdk_pixbuf_get_rowstride (pixbuf); - - if (count > width) - count = width; - if (count > height) - count = height; - - if (count > 2) - tmp = meta_gradient_create_multi_horizontal (2*width-1, 1, colors, count); - else - /* wrlib multiplies these colors by 256 before passing them in, but - * I think it's a bug in wrlib, so changed here. I could be wrong - * though, if we notice two-color multi diagonals not working. - */ - tmp = meta_gradient_create_horizontal (2*width-1, 1, - &colors[0], &colors[1]); - - if (!tmp) - { - g_object_unref (G_OBJECT (pixbuf)); - return NULL; - } - ptr = gdk_pixbuf_get_pixels (tmp); - - a = ((float)(width - 1))/((float)(height - 1)); - width = width * 3; - - /* copy the first line to the other lines with corresponding offset */ - for (j=0, offset=0; j<rowstride*height; j += rowstride) - { - memcpy (&(pixels[j]), &ptr[3*(int)offset], width); - offset += a; - } - - g_object_unref (G_OBJECT (tmp)); - return pixbuf; -} - -static void -simple_multiply_alpha (GdkPixbuf *pixbuf, - guchar alpha) -{ - guchar *pixels; - int rowstride; - int height; - int row; - - g_return_if_fail (GDK_IS_PIXBUF (pixbuf)); - - if (alpha == 255) - return; - - g_assert (gdk_pixbuf_get_has_alpha (pixbuf)); - - pixels = gdk_pixbuf_get_pixels (pixbuf); - rowstride = gdk_pixbuf_get_rowstride (pixbuf); - height = gdk_pixbuf_get_height (pixbuf); - - row = 0; - while (row < height) - { - guchar *p; - guchar *end; - - p = pixels + row * rowstride; - end = p + rowstride; - - while (p != end) - { - p += 3; /* skip RGB */ - - /* multiply the two alpha channels. not sure this is right. - * but some end cases are that if the pixbuf contains 255, - * then it should be modified to contain "alpha"; if the - * pixbuf contains 0, it should remain 0. - */ - /* ((*p / 255.0) * (alpha / 255.0)) * 255; */ - *p = (guchar) (((int) *p * (int) alpha) / (int) 255); - - ++p; /* skip A */ - } - - ++row; - } -} - -static void -meta_gradient_add_alpha_horizontal (GdkPixbuf *pixbuf, - const unsigned char *alphas, - int n_alphas) -{ - int i, j; - long a, da; - unsigned char *p; - unsigned char *pixels; - int width2; - int rowstride; - int width, height; - unsigned char *gradient; - unsigned char *gradient_p; - unsigned char *gradient_end; - - g_return_if_fail (n_alphas > 0); - - if (n_alphas == 1) - { - /* Optimize this */ - simple_multiply_alpha (pixbuf, alphas[0]); - return; - } - - width = gdk_pixbuf_get_width (pixbuf); - height = gdk_pixbuf_get_height (pixbuf); - - gradient = g_new (unsigned char, width); - gradient_end = gradient + width; - - if (n_alphas > width) - n_alphas = width; - - if (n_alphas > 1) - width2 = width / (n_alphas - 1); - else - width2 = width; - - a = alphas[0] << 8; - gradient_p = gradient; - - /* render the gradient into an array */ - for (i = 1; i < n_alphas; i++) - { - da = (((int)(alphas[i] - (int) alphas[i-1])) << 8) / (int) width2; - - for (j = 0; j < width2; j++) - { - *gradient_p++ = (a >> 8); - - a += da; - } - - a = alphas[i] << 8; - } - - /* get leftover pixels */ - while (gradient_p != gradient_end) - { - *gradient_p++ = a >> 8; - } - - /* Now for each line of the pixbuf, fill in with the gradient */ - pixels = gdk_pixbuf_get_pixels (pixbuf); - rowstride = gdk_pixbuf_get_rowstride (pixbuf); - - p = pixels; - i = 0; - while (i < height) - { - unsigned char *row_end = p + rowstride; - gradient_p = gradient; - - p += 3; - while (gradient_p != gradient_end) - { - /* multiply the two alpha channels. not sure this is right. - * but some end cases are that if the pixbuf contains 255, - * then it should be modified to contain "alpha"; if the - * pixbuf contains 0, it should remain 0. - */ - /* ((*p / 255.0) * (alpha / 255.0)) * 255; */ - *p = (guchar) (((int) *p * (int) *gradient_p) / (int) 255); - - p += 4; - ++gradient_p; - } - - p = row_end; - ++i; - } - - free (gradient); -} - -void -meta_gradient_add_alpha (GdkPixbuf *pixbuf, - const guchar *alphas, - int n_alphas, - MetaGradientType type) -{ - g_return_if_fail (GDK_IS_PIXBUF (pixbuf)); - g_return_if_fail (gdk_pixbuf_get_has_alpha (pixbuf)); - g_return_if_fail (n_alphas > 0); - - switch (type) - { - case META_GRADIENT_HORIZONTAL: - meta_gradient_add_alpha_horizontal (pixbuf, alphas, n_alphas); - break; - - case META_GRADIENT_VERTICAL: - g_printerr ("metacity: vertical alpha channel gradient not implemented yet\n"); - break; - - case META_GRADIENT_DIAGONAL: - g_printerr ("metacity: diagonal alpha channel gradient not implemented yet\n"); - break; - - case META_GRADIENT_LAST: - g_assert_not_reached (); - break; - default: - break; - } -} diff --git a/src/ui/menu.c b/src/ui/menu.c deleted file mode 100644 index 5d1155e7c..000000000 --- a/src/ui/menu.c +++ /dev/null @@ -1,551 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Muffin window menu */ - -/* - * Copyright (C) 2001 Havoc Pennington - * Copyright (C) 2004 Rob Adams - * Copyright (C) 2005 Elijah Newren - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. - */ - -#include <config.h> -#include <stdio.h> -#include <string.h> -#include "menu.h" -#include <meta/main.h> -#include "util-private.h" -#include "core.h" -#include "metaaccellabel.h" -#include "ui.h" - -typedef struct _MenuItem MenuItem; -typedef struct _MenuData MenuData; - -typedef enum -{ - MENU_ITEM_SEPARATOR = 0, - MENU_ITEM_NORMAL, - MENU_ITEM_IMAGE, - MENU_ITEM_CHECKBOX, - MENU_ITEM_RADIOBUTTON, - MENU_ITEM_WORKSPACE_LIST, -} MetaMenuItemType; - -struct _MenuItem -{ - MetaMenuOp op; - MetaMenuItemType type; - const char *stock_id; - const gboolean checked; - const char *label; -}; - - -struct _MenuData -{ - MetaWindowMenu *menu; - MetaMenuOp op; -}; - -static void activate_cb (GtkWidget *menuitem, gpointer data); - -static MenuItem menuitems[] = { - /* Translators: Translate this string the same way as you do in libwnck! */ - { META_MENU_OP_MINIMIZE, MENU_ITEM_IMAGE, METACITY_STOCK_MINIMIZE, FALSE, N_("Mi_nimize") }, - /* Translators: Translate this string the same way as you do in libwnck! */ - { META_MENU_OP_MAXIMIZE, MENU_ITEM_IMAGE, METACITY_STOCK_MAXIMIZE, FALSE, N_("Ma_ximize") }, - /* Translators: Translate this string the same way as you do in libwnck! */ - { META_MENU_OP_UNMAXIMIZE, MENU_ITEM_NORMAL, NULL, FALSE, N_("Unma_ximize") }, - /* Translators: Translate this string the same way as you do in libwnck! */ - { META_MENU_OP_SHADE, MENU_ITEM_NORMAL, NULL, FALSE, N_("Roll _Up") }, - /* Translators: Translate this string the same way as you do in libwnck! */ - { META_MENU_OP_UNSHADE, MENU_ITEM_NORMAL, NULL, FALSE, N_("_Unroll") }, - /* Translators: Translate this string the same way as you do in libwnck! */ - { META_MENU_OP_MOVE, MENU_ITEM_NORMAL, NULL, FALSE, N_("_Move") }, - /* Translators: Translate this string the same way as you do in libwnck! */ - { META_MENU_OP_RESIZE, MENU_ITEM_NORMAL, NULL, FALSE, N_("_Resize") }, - /* Translators: Translate this string the same way as you do in libwnck! */ - { META_MENU_OP_RECOVER, MENU_ITEM_NORMAL, NULL, FALSE, N_("Move Titlebar On_screen") }, - { META_MENU_OP_WORKSPACES, MENU_ITEM_SEPARATOR, NULL, FALSE, NULL }, /* separator */ - /* Translators: Translate this string the same way as you do in libwnck! */ - { META_MENU_OP_ABOVE, MENU_ITEM_CHECKBOX, NULL, FALSE, N_("Always on _Top") }, - /* Translators: Translate this string the same way as you do in libwnck! */ - { META_MENU_OP_UNABOVE, MENU_ITEM_CHECKBOX, NULL, TRUE, N_("Always on _Top") }, - /* Translators: Translate this string the same way as you do in libwnck! */ - { META_MENU_OP_STICK, MENU_ITEM_RADIOBUTTON, NULL, FALSE, N_("_Always on Visible Workspace") }, - /* Translators: Translate this string the same way as you do in libwnck! */ - { META_MENU_OP_UNSTICK, MENU_ITEM_RADIOBUTTON, NULL, FALSE, N_("_Only on This Workspace") }, - /* Translators: Translate this string the same way as you do in libwnck! */ - { META_MENU_OP_MOVE_LEFT, MENU_ITEM_NORMAL, NULL, FALSE, N_("Move to Workspace _Left") }, - /* Translators: Translate this string the same way as you do in libwnck! */ - { META_MENU_OP_MOVE_RIGHT, MENU_ITEM_NORMAL, NULL, FALSE, N_("Move to Workspace R_ight") }, - /* Translators: This will create a new workspace, and move this window to that new workspace */ - { META_MENU_OP_MOVE_NEW, MENU_ITEM_NORMAL, NULL, FALSE, N_("Move to a New W_orkspace") }, - /* Translators: Translate this string the same way as you do in libwnck! */ - { META_MENU_OP_MOVE_UP, MENU_ITEM_NORMAL, NULL, FALSE, N_("Move to Workspace _Up") }, - /* Translators: Translate this string the same way as you do in libwnck! */ - { META_MENU_OP_MOVE_DOWN, MENU_ITEM_NORMAL, NULL, FALSE, N_("Move to Workspace _Down") }, - { 0, MENU_ITEM_WORKSPACE_LIST, NULL, FALSE, NULL }, - { 0, MENU_ITEM_SEPARATOR, NULL, FALSE, NULL }, /* separator */ - /* Translators: Translate this string the same way as you do in libwnck! */ - { META_MENU_OP_DELETE, MENU_ITEM_IMAGE, METACITY_STOCK_DELETE, FALSE, N_("_Close") } -}; - -static void -popup_position_func (GtkMenu *menu, - gint *x, - gint *y, - gboolean *push_in, - gpointer user_data) -{ - GtkRequisition req; - GdkPoint *pos; - - pos = user_data; - - gtk_widget_get_preferred_size (GTK_WIDGET (menu), &req, NULL); - - *x = pos->x; - *y = pos->y; - - if (meta_ui_get_direction() == META_UI_DIRECTION_RTL) - *x = MAX (0, *x - req.width); - - /* Ensure onscreen */ - *x = CLAMP (*x, 0, MAX (0, gdk_screen_width () - req.width)); - *y = CLAMP (*y, 0, MAX (0, gdk_screen_height () - req.height)); -} - -static void -menu_closed (GtkMenu *widget, - gpointer data) -{ - MetaWindowMenu *menu; - - menu = data; - - meta_frames_notify_menu_hide (menu->frames); - (* menu->func) (menu, - GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), - menu->client_xwindow, - gtk_get_current_event_time (), - 0, 0, - menu->data); - - /* menu may now be freed */ -} - -static void -activate_cb (GtkWidget *menuitem, gpointer data) -{ - MenuData *md; - - g_return_if_fail (GTK_IS_WIDGET (menuitem)); - - md = data; - - meta_frames_notify_menu_hide (md->menu->frames); - (* md->menu->func) (md->menu, - GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), - md->menu->client_xwindow, - gtk_get_current_event_time (), - md->op, - GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menuitem), - "workspace")), - md->menu->data); - - /* menu may now be freed */ -} - -/* - * Given a Display and an index, get the workspace name and add any - * accelerators. At the moment this means adding a _ if the name is of - * the form "Workspace n" where n is less than 10, and escaping any - * other '_'s so they do not create inadvertant accelerators. - * - * The calling code owns the string, and is reponsible to free the - * memory after use. - * - * See also http://mail.gnome.org/archives/gnome-i18n/2008-March/msg00380.html - * which discusses possible i18n concerns. - */ -static char* -get_workspace_name_with_accel (Display *display, - Window xroot, - int index) -{ - const char *name; - int number; - int charcount=0; - - name = meta_core_get_workspace_name_with_index (display, xroot, index); - - g_assert (name != NULL); - - /* - * If the name is of the form "Workspace x" where x is an unsigned - * integer, insert a '_' before the number if it is less than 10 and - * return it - */ - number = 0; - if (sscanf (name, _("Workspace %d%n"), &number, &charcount) != 0 && - *(name + charcount)=='\0') - { - char *new_name; - - /* - * Above name is a pointer into the Workspace struct. Here we make - * a copy copy so we can have our wicked way with it. - */ - if (number == 10) - new_name = g_strdup_printf (_("Workspace 1_0")); - else - new_name = g_strdup_printf (_("Workspace %s%d"), - number < 10 ? "_" : "", - number); - return new_name; - } - else - { - /* - * Otherwise this is just a normal name. Escape any _ characters so that - * the user's workspace names do not get mangled. If the number is less - * than 10 we provide an accelerator. - */ - char *new_name; - const char *source; - char *dest; - - /* - * Assume the worst case, that every character is a _. We also - * provide memory for " (_#)" - */ - new_name = calloc (1, strlen (name) * 2 + 6 + 1); - - /* - * Now iterate down the strings, adding '_' to escape as we go - */ - dest = new_name; - source = name; - while (*source != '\0') - { - if (*source == '_') - *dest++ = '_'; - *dest++ = *source++; - } - - /* People don't start at workspace 0, but workspace 1 */ - if (index < 9) - { - g_snprintf (dest, 6, " (_%d)", index + 1); - } - else if (index == 9) - { - g_snprintf (dest, 6, " (_0)"); - } - - return new_name; - } -} - -static GtkWidget * -menu_item_new (MenuItem *menuitem, int workspace_id) -{ - unsigned int key; - MetaVirtualModifier mods; - const char *i18n_label; - GtkWidget *mi; - GtkWidget *accel_label; - - if (menuitem->type == MENU_ITEM_NORMAL) - { - mi = gtk_menu_item_new (); - } - else if (menuitem->type == MENU_ITEM_IMAGE) - { - GtkWidget *image; - - image = gtk_image_new_from_stock (menuitem->stock_id, GTK_ICON_SIZE_MENU); - mi = gtk_image_menu_item_new (); - - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), image); - gtk_widget_show (image); - } - else if (menuitem->type == MENU_ITEM_CHECKBOX) - { - mi = gtk_check_menu_item_new (); - - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mi), - menuitem->checked); - } - else if (menuitem->type == MENU_ITEM_RADIOBUTTON) - { - mi = gtk_check_menu_item_new (); - - gtk_check_menu_item_set_draw_as_radio (GTK_CHECK_MENU_ITEM (mi), - TRUE); - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mi), - menuitem->checked); - } - else if (menuitem->type == MENU_ITEM_WORKSPACE_LIST) - return NULL; - else - return gtk_separator_menu_item_new (); - - i18n_label = _(menuitem->label); - meta_core_get_menu_accelerator (menuitem->op, workspace_id, &key, &mods); - - accel_label = meta_accel_label_new_with_mnemonic (i18n_label); - gtk_misc_set_alignment (GTK_MISC (accel_label), 0.0, 0.5); - - gtk_container_add (GTK_CONTAINER (mi), accel_label); - gtk_widget_show (accel_label); - - meta_accel_label_set_accelerator (META_ACCEL_LABEL (accel_label), - key, mods); - - return mi; -} - -LOCAL_SYMBOL MetaWindowMenu* -meta_window_menu_new (MetaFrames *frames, - MetaMenuOp ops, - MetaMenuOp insensitive, - Window client_xwindow, - unsigned long active_workspace, - int n_workspaces, - MetaWindowMenuFunc func, - gpointer data) -{ - int i; - MetaWindowMenu *menu; - - /* FIXME: Modifications to 'ops' should happen in meta_window_show_menu */ - if (n_workspaces < 2) - ops &= ~(META_MENU_OP_STICK | META_MENU_OP_UNSTICK | META_MENU_OP_WORKSPACES); - - menu = g_new (MetaWindowMenu, 1); - menu->frames = frames; - menu->client_xwindow = client_xwindow; - menu->func = func; - menu->data = data; - menu->ops = ops; - menu->insensitive = insensitive; - - menu->menu = gtk_menu_new (); - - gtk_menu_set_screen (GTK_MENU (menu->menu), - gtk_widget_get_screen (GTK_WIDGET (frames))); - - for (i = 0; i < (int) G_N_ELEMENTS (menuitems); i++) - { - MenuItem menuitem = menuitems[i]; - if (ops & menuitem.op || menuitem.op == 0) - { - GtkWidget *mi; - MenuData *md; - unsigned int key; - MetaVirtualModifier mods; - - mi = menu_item_new (&menuitem, -1); - - /* Set the activeness of radiobuttons. */ - switch (menuitem.op) - { - case META_MENU_OP_STICK: - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mi), - active_workspace == 0xFFFFFFFF); - break; - case META_MENU_OP_UNSTICK: - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mi), - active_workspace != 0xFFFFFFFF); - break; - case META_MENU_OP_NONE: - case META_MENU_OP_DELETE: - case META_MENU_OP_MINIMIZE: - case META_MENU_OP_UNMAXIMIZE: - case META_MENU_OP_MAXIMIZE: - case META_MENU_OP_UNSHADE: - case META_MENU_OP_SHADE: - case META_MENU_OP_WORKSPACES: - case META_MENU_OP_MOVE: - case META_MENU_OP_RESIZE: - case META_MENU_OP_ABOVE: - case META_MENU_OP_UNABOVE: - case META_MENU_OP_MOVE_LEFT: - case META_MENU_OP_MOVE_RIGHT: - case META_MENU_OP_MOVE_UP: - case META_MENU_OP_MOVE_DOWN: - case META_MENU_OP_RECOVER: - case META_MENU_OP_MOVE_NEW: - break; - default: - break; - } - - if (menuitem.type == MENU_ITEM_WORKSPACE_LIST) - { - if (ops & META_MENU_OP_WORKSPACES) - { - Display *display; - Window xroot; - GdkScreen *screen; - GdkWindow *window; - GtkWidget *submenu; - int j; - - MenuItem to_another_workspace = { - 0, MENU_ITEM_NORMAL, - NULL, FALSE, - N_("Move to Another _Workspace") - }; - - meta_verbose ("Creating %d-workspace menu current space %lu\n", - n_workspaces, active_workspace); - - window = gtk_widget_get_window (GTK_WIDGET (frames)); - display = GDK_WINDOW_XDISPLAY (window); - - screen = gdk_window_get_screen (window); - xroot = GDK_WINDOW_XID (gdk_screen_get_root_window (screen)); - - submenu = gtk_menu_new (); - - g_assert (mi==NULL); - mi = menu_item_new (&to_another_workspace, -1); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (mi), submenu); - - for (j = 0; j < n_workspaces; j++) - { - char *label; - MenuData *md1; - unsigned int key1; - MetaVirtualModifier mods1; - MenuItem moveitem; - GtkWidget *submi; - - meta_core_get_menu_accelerator (META_MENU_OP_WORKSPACES, - j + 1, - &key1, &mods1); - - label = get_workspace_name_with_accel (display, xroot, j); - - moveitem.type = MENU_ITEM_NORMAL; - moveitem.op = META_MENU_OP_WORKSPACES; - moveitem.label = label; - submi = menu_item_new (&moveitem, j + 1); - - free (label); - - if ((active_workspace == (unsigned)j) && (ops & META_MENU_OP_UNSTICK)) - gtk_widget_set_sensitive (submi, FALSE); - - md1 = g_new (MenuData, 1); - - md1->menu = menu; - md1->op = META_MENU_OP_WORKSPACES; - - g_object_set_data (G_OBJECT (submi), - "workspace", - GINT_TO_POINTER (j)); - - g_signal_connect_data (G_OBJECT (submi), - "activate", - G_CALLBACK (activate_cb), - md1, - (GClosureNotify) free, 0); - - gtk_menu_shell_append (GTK_MENU_SHELL (submenu), submi); - - gtk_widget_show (submi); - } - } - else - meta_verbose ("not creating workspace menu\n"); - } - else if (menuitem.type != MENU_ITEM_SEPARATOR) - { - meta_core_get_menu_accelerator (menuitems[i].op, -1, - &key, &mods); - - if (insensitive & menuitem.op) - gtk_widget_set_sensitive (mi, FALSE); - - md = g_new (MenuData, 1); - - md->menu = menu; - md->op = menuitem.op; - - g_signal_connect_data (G_OBJECT (mi), - "activate", - G_CALLBACK (activate_cb), - md, - (GClosureNotify) free, 0); - } - - if (mi) - { - gtk_menu_shell_append (GTK_MENU_SHELL (menu->menu), mi); - - gtk_widget_show (mi); - } - } - } - - - g_signal_connect (menu->menu, "selection_done", - G_CALLBACK (menu_closed), menu); - - return menu; -} - -LOCAL_SYMBOL void -meta_window_menu_popup (MetaWindowMenu *menu, - int root_x, - int root_y, - int button, - guint32 timestamp) -{ - GdkPoint *pt; - - pt = g_new (GdkPoint, 1); - - g_object_set_data_full (G_OBJECT (menu->menu), - "destroy-point", - pt, - free); - - pt->x = root_x; - pt->y = root_y; - - gtk_menu_popup (GTK_MENU (menu->menu), - NULL, NULL, - popup_position_func, pt, - button, - timestamp); - - if (!gtk_widget_get_visible (menu->menu)) - meta_warning ("GtkMenu failed to grab the pointer\n"); -} - -LOCAL_SYMBOL void -meta_window_menu_free (MetaWindowMenu *menu) -{ - gtk_widget_destroy (menu->menu); - free (menu); -} diff --git a/src/ui/menu.h b/src/ui/menu.h deleted file mode 100644 index 06c73417e..000000000 --- a/src/ui/menu.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Muffin window menu */ - -/* - * Copyright (C) 2001 Havoc Pennington - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. - */ - -#ifndef META_MENU_H -#define META_MENU_H - -#include <gtk/gtk.h> -#include "frames.h" - -/* Stock icons */ -#define METACITY_STOCK_DELETE "metacity-delete" -#define METACITY_STOCK_MINIMIZE "metacity-minimize" -#define METACITY_STOCK_MAXIMIZE "metacity-maximize" - -struct _MetaWindowMenu -{ - MetaFrames *frames; - Window client_xwindow; - GtkWidget *menu; - MetaWindowMenuFunc func; - gpointer data; - MetaMenuOp ops; - MetaMenuOp insensitive; -}; - -MetaWindowMenu* meta_window_menu_new (MetaFrames *frames, - MetaMenuOp ops, - MetaMenuOp insensitive, - Window client_xwindow, - unsigned long active_workspace, - int n_workspaces, - MetaWindowMenuFunc func, - gpointer data); -void meta_window_menu_popup (MetaWindowMenu *menu, - int root_x, - int root_y, - int button, - guint32 timestamp); -void meta_window_menu_free (MetaWindowMenu *menu); - - -#endif diff --git a/src/ui/metaaccellabel.c b/src/ui/metaaccellabel.c deleted file mode 100644 index 097b45b47..000000000 --- a/src/ui/metaaccellabel.c +++ /dev/null @@ -1,453 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Metacity hacked-up GtkAccelLabel */ -/* Copyright (C) 2002 Red Hat, Inc. */ -/* GTK - The GIMP Toolkit - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * MetaAccelLabel: GtkLabel with accelerator monitoring facilities. - * Copyright (C) 1998 Tim Janik - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street - Suite 500, - * Boston, MA 02110-1335, USA. - */ - -/* - * Modified by the GTK+ Team and others 1997-2001. See the AUTHORS - * file for a list of people on the GTK+ Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. - */ - -#include <config.h> -#include "metaaccellabel.h" -#include <gtk/gtk.h> -#include <string.h> -#include "util-private.h" - -static void meta_accel_label_destroy (GtkWidget *object); -static void meta_accel_label_finalize (GObject *object); -static void meta_accel_label_get_preferred_width (GtkWidget *widget, - gint *minimum, - gint *natural); -static void meta_accel_label_get_preferred_height (GtkWidget *widget, - gint *minimum, - gint *natural); -static gboolean meta_accel_label_draw (GtkWidget *widget, - cairo_t *cr); - -static void meta_accel_label_update (MetaAccelLabel *accel_label); -static int meta_accel_label_get_accel_width (MetaAccelLabel *accel_label); - -G_DEFINE_TYPE (MetaAccelLabel, meta_accel_label, GTK_TYPE_LABEL); - -static void -meta_accel_label_class_init (MetaAccelLabelClass *class) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (class); - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class); - - gobject_class->finalize = meta_accel_label_finalize; - - widget_class->destroy = meta_accel_label_destroy; - - widget_class->get_preferred_width = meta_accel_label_get_preferred_width; - widget_class->get_preferred_height = meta_accel_label_get_preferred_height; - widget_class->draw = meta_accel_label_draw; - - class->signal_quote1 = g_strdup ("<:"); - class->signal_quote2 = g_strdup (":>"); - /* This is the text that should appear next to menu accelerators - * that use the shift key. If the text on this key isn't typically - * translated on keyboards used for your language, don't translate - * this. - */ - class->mod_name_shift = g_strdup (_("Shift")); - /* This is the text that should appear next to menu accelerators - * that use the control key. If the text on this key isn't typically - * translated on keyboards used for your language, don't translate - * this. - */ - class->mod_name_control = g_strdup (_("Ctrl")); - /* This is the text that should appear next to menu accelerators - * that use the alt key. If the text on this key isn't typically - * translated on keyboards used for your language, don't translate - * this. - */ - class->mod_name_alt = g_strdup (_("Alt")); - /* This is the text that should appear next to menu accelerators - * that use the meta key. If the text on this key isn't typically - * translated on keyboards used for your language, don't translate - * this. - */ - class->mod_name_meta = g_strdup (_("Meta")); - /* This is the text that should appear next to menu accelerators - * that use the super key. If the text on this key isn't typically - * translated on keyboards used for your language, don't translate - * this. - */ - class->mod_name_super = g_strdup (_("Super")); - /* This is the text that should appear next to menu accelerators - * that use the hyper key. If the text on this key isn't typically - * translated on keyboards used for your language, don't translate - * this. - */ - class->mod_name_hyper = g_strdup (_("Hyper")); - /* This is the text that should appear next to menu accelerators - * that use the mod2 key. If the text on this key isn't typically - * translated on keyboards used for your language, don't translate - * this. - */ - class->mod_name_mod2 = g_strdup (_("Mod2")); - /* This is the text that should appear next to menu accelerators - * that use the mod3 key. If the text on this key isn't typically - * translated on keyboards used for your language, don't translate - * this. - */ - class->mod_name_mod3 = g_strdup (_("Mod3")); - /* This is the text that should appear next to menu accelerators - * that use the mod4 key. If the text on this key isn't typically - * translated on keyboards used for your language, don't translate - * this. - */ - class->mod_name_mod4 = g_strdup (_("Mod4")); - /* This is the text that should appear next to menu accelerators - * that use the mod5 key. If the text on this key isn't typically - * translated on keyboards used for your language, don't translate - * this. - */ - class->mod_name_mod5 = g_strdup (_("Mod5")); - - class->mod_separator = g_strdup ("+"); - class->accel_seperator = g_strdup (" / "); - class->latin1_to_char = TRUE; -} - -static void -meta_accel_label_init (MetaAccelLabel *accel_label) -{ - accel_label->accel_padding = 3; - accel_label->accel_string = NULL; - - meta_accel_label_update (accel_label); -} - -LOCAL_SYMBOL GtkWidget* -meta_accel_label_new_with_mnemonic (const gchar *string) -{ - MetaAccelLabel *accel_label; - - g_return_val_if_fail (string != NULL, NULL); - - accel_label = g_object_new (META_TYPE_ACCEL_LABEL, NULL); - - gtk_label_set_text_with_mnemonic (GTK_LABEL (accel_label), string); - - return GTK_WIDGET (accel_label); -} - -static void -meta_accel_label_destroy (GtkWidget *object) -{ - MetaAccelLabel *accel_label = META_ACCEL_LABEL (object); - - - free (accel_label->accel_string); - accel_label->accel_string = NULL; - - accel_label->accel_mods = 0; - accel_label->accel_key = 0; - - GTK_WIDGET_CLASS (meta_accel_label_parent_class)->destroy (object); -} - -static void -meta_accel_label_finalize (GObject *object) -{ - MetaAccelLabel *accel_label = META_ACCEL_LABEL (object); - - free (accel_label->accel_string); - - G_OBJECT_CLASS (meta_accel_label_parent_class)->finalize (object); -} - -LOCAL_SYMBOL void -meta_accel_label_set_accelerator (MetaAccelLabel *accel_label, - guint accelerator_key, - MetaVirtualModifier accelerator_mods) -{ - g_return_if_fail (META_IS_ACCEL_LABEL (accel_label)); - - if (accelerator_key != accel_label->accel_key || - accelerator_mods != accel_label->accel_mods) - { - accel_label->accel_mods = accelerator_mods; - accel_label->accel_key = accelerator_key; - - meta_accel_label_update (accel_label); - } -} - -static int -meta_accel_label_get_accel_width (MetaAccelLabel *accel_label) -{ - g_return_val_if_fail (META_IS_ACCEL_LABEL (accel_label), 0); - - return (accel_label->accel_string_width + - (accel_label->accel_string_width ? accel_label->accel_padding : 0)); -} - -static void -meta_accel_label_get_preferred_width (GtkWidget *widget, - gint *minimum, - gint *natural) -{ - MetaAccelLabel *accel_label = META_ACCEL_LABEL (widget); - PangoLayout *layout; - gint width; - - GTK_WIDGET_CLASS (meta_accel_label_parent_class)->get_preferred_width (widget, minimum, natural); - - layout = gtk_widget_create_pango_layout (widget, accel_label->accel_string); - pango_layout_get_pixel_size (layout, &width, NULL); - accel_label->accel_string_width = width; - - g_object_unref (G_OBJECT (layout)); -} - -static void -meta_accel_label_get_preferred_height (GtkWidget *widget, - gint *minimum, - gint *natural) -{ - GTK_WIDGET_CLASS (meta_accel_label_parent_class)->get_preferred_height (widget, minimum, natural); -} - -/* Mostly taken from GTK3. */ -static gboolean -meta_accel_label_draw (GtkWidget *widget, - cairo_t *cr) -{ - MetaAccelLabel *accel_label = META_ACCEL_LABEL (widget); - GtkMisc *misc = GTK_MISC (accel_label); - GtkTextDirection direction; - int ac_width; - GtkAllocation allocation; - GtkRequisition requisition; - - direction = gtk_widget_get_direction (widget); - ac_width = meta_accel_label_get_accel_width (accel_label); - gtk_widget_get_allocation (widget, &allocation); - gtk_widget_get_preferred_size (widget, - &requisition, NULL); - - if (allocation.width >= requisition.width + ac_width) - { - GtkStyleContext *style; - PangoLayout *label_layout; - PangoLayout *accel_layout; - GtkLabel *label = GTK_LABEL (widget); - gint x, y, xpad, ypad; - gfloat xalign, yalign; - - label_layout = gtk_label_get_layout (GTK_LABEL (accel_label)); - gtk_misc_get_alignment (misc, &xalign, &yalign); - - cairo_save (cr); - - /* XXX: Mad hack: We modify the label's width so it renders - * properly in its draw function that we chain to. */ - if (direction == GTK_TEXT_DIR_RTL) - cairo_translate (cr, ac_width, 0); - if (gtk_label_get_ellipsize (label)) - pango_layout_set_width (label_layout, - pango_layout_get_width (label_layout) - - ac_width * PANGO_SCALE); - - allocation.width -= ac_width; - gtk_widget_set_allocation (widget, &allocation); - if (GTK_WIDGET_CLASS (meta_accel_label_parent_class)->draw) - GTK_WIDGET_CLASS (meta_accel_label_parent_class)->draw (widget, - cr); - allocation.width += ac_width; - gtk_widget_set_allocation (widget, &allocation); - if (gtk_label_get_ellipsize (label)) - pango_layout_set_width (label_layout, - pango_layout_get_width (label_layout) - + ac_width * PANGO_SCALE); - - cairo_restore (cr); - - gtk_misc_get_padding (misc, &xpad, &ypad); - - if (direction == GTK_TEXT_DIR_RTL) - x = xpad; - else - x = gtk_widget_get_allocated_width (widget) - xpad - ac_width; - - gtk_label_get_layout_offsets (GTK_LABEL (accel_label), NULL, &y); - - accel_layout = gtk_widget_create_pango_layout (widget, accel_label->accel_string); - - y = (allocation.height - (requisition.height - ypad * 2)) * yalign + 1.5; - - style = gtk_widget_get_style_context (widget); - gtk_style_context_save (style); - gtk_style_context_set_state (style, - gtk_widget_get_state_flags (widget)); - gtk_render_layout (gtk_widget_get_style_context (widget), - cr, - x, y, - accel_layout); - gtk_style_context_restore (style); - - g_object_unref (accel_layout); - } - else - { - if (GTK_WIDGET_CLASS (meta_accel_label_parent_class)->draw) - GTK_WIDGET_CLASS (meta_accel_label_parent_class)->draw (widget, cr); - } - - return FALSE; -} - -static void -meta_accel_label_update (MetaAccelLabel *accel_label) -{ - MetaAccelLabelClass *class; - GString *gstring; - gboolean seen_mod = FALSE; - gunichar ch; - - g_return_if_fail (META_IS_ACCEL_LABEL (accel_label)); - - class = META_ACCEL_LABEL_GET_CLASS (accel_label); - - free (accel_label->accel_string); - accel_label->accel_string = NULL; - - gstring = g_string_new (accel_label->accel_string); - g_string_append (gstring, gstring->len ? class->accel_seperator : " "); - - if (accel_label->accel_mods & META_VIRTUAL_SHIFT_MASK) - { - g_string_append (gstring, class->mod_name_shift); - seen_mod = TRUE; - } - if (accel_label->accel_mods & META_VIRTUAL_CONTROL_MASK) - { - if (seen_mod) - g_string_append (gstring, class->mod_separator); - g_string_append (gstring, class->mod_name_control); - seen_mod = TRUE; - } - if (accel_label->accel_mods & META_VIRTUAL_ALT_MASK) - { - if (seen_mod) - g_string_append (gstring, class->mod_separator); - g_string_append (gstring, class->mod_name_alt); - seen_mod = TRUE; - } - if (accel_label->accel_mods & META_VIRTUAL_META_MASK) - { - if (seen_mod) - g_string_append (gstring, class->mod_separator); - g_string_append (gstring, class->mod_name_meta); - seen_mod = TRUE; - } - if (accel_label->accel_mods & META_VIRTUAL_SUPER_MASK) - { - if (seen_mod) - g_string_append (gstring, class->mod_separator); - g_string_append (gstring, class->mod_name_super); - seen_mod = TRUE; - } - if (accel_label->accel_mods & META_VIRTUAL_HYPER_MASK) - { - if (seen_mod) - g_string_append (gstring, class->mod_separator); - g_string_append (gstring, class->mod_name_hyper); - seen_mod = TRUE; - } - if (accel_label->accel_mods & META_VIRTUAL_MOD2_MASK) - { - if (seen_mod) - g_string_append (gstring, class->mod_separator); - g_string_append (gstring, class->mod_name_mod2); - seen_mod = TRUE; - } - if (accel_label->accel_mods & META_VIRTUAL_MOD3_MASK) - { - if (seen_mod) - g_string_append (gstring, class->mod_separator); - g_string_append (gstring, class->mod_name_mod3); - seen_mod = TRUE; - } - if (accel_label->accel_mods & META_VIRTUAL_MOD4_MASK) - { - if (seen_mod) - g_string_append (gstring, class->mod_separator); - g_string_append (gstring, class->mod_name_mod4); - seen_mod = TRUE; - } - if (accel_label->accel_mods & META_VIRTUAL_MOD5_MASK) - { - if (seen_mod) - g_string_append (gstring, class->mod_separator); - g_string_append (gstring, class->mod_name_mod5); - seen_mod = TRUE; - } - - if (seen_mod) - g_string_append (gstring, class->mod_separator); - - ch = gdk_keyval_to_unicode (accel_label->accel_key); - if (ch && (g_unichar_isgraph (ch) || ch == ' ') && - (ch < 0x80 || class->latin1_to_char)) - { - switch (ch) - { - case ' ': - g_string_append (gstring, "Space"); - break; - case '\\': - g_string_append (gstring, "Backslash"); - break; - default: - g_string_append_unichar (gstring, g_unichar_toupper (ch)); - break; - } - } - else - { - gchar *tmp; - - tmp = gtk_accelerator_name (accel_label->accel_key, 0); - if (tmp[0] != 0 && tmp[1] == 0) - tmp[0] = g_ascii_toupper (tmp[0]); - g_string_append (gstring, tmp); - free (tmp); - } - - free (accel_label->accel_string); - accel_label->accel_string = gstring->str; - g_string_free (gstring, FALSE); - - g_assert (accel_label->accel_string); - /* accel_label->accel_string = g_strdup ("-/-"); */ - - gtk_widget_queue_resize (GTK_WIDGET (accel_label)); -} diff --git a/src/ui/metaaccellabel.h b/src/ui/metaaccellabel.h deleted file mode 100644 index 9e3e8f928..000000000 --- a/src/ui/metaaccellabel.h +++ /dev/null @@ -1,106 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Metacity hacked-up GtkAccelLabel */ -/* Copyright (C) 2002 Red Hat, Inc. */ -/* GTK - The GIMP Toolkit - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * MetaAccelLabel: GtkLabel with accelerator monitoring facilities. - * Copyright (C) 1998 Tim Janik - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street - Suite 500, - * Boston, MA 02110-1335, USA. - */ - -/* - * Modified by the GTK+ Team and others 1997-2001. See the AUTHORS - * file for a list of people on the GTK+ Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. - */ - -#ifndef __META_ACCEL_LABEL_H__ -#define __META_ACCEL_LABEL_H__ - -#include <gtk/gtk.h> -#include <meta/common.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -#define META_TYPE_ACCEL_LABEL (meta_accel_label_get_type ()) -#define META_ACCEL_LABEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_ACCEL_LABEL, MetaAccelLabel)) -#define META_ACCEL_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_ACCEL_LABEL, MetaAccelLabelClass)) -#define META_IS_ACCEL_LABEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_ACCEL_LABEL)) -#define META_IS_ACCEL_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_ACCEL_LABEL)) -#define META_ACCEL_LABEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_ACCEL_LABEL, MetaAccelLabelClass)) - - -typedef struct _MetaAccelLabel MetaAccelLabel; -typedef struct _MetaAccelLabelClass MetaAccelLabelClass; - -struct _MetaAccelLabel -{ - GtkLabel label; - - MetaVirtualModifier accel_mods; - guint accel_key; - guint accel_padding; - gchar *accel_string; - guint16 accel_string_width; -}; - -struct _MetaAccelLabelClass -{ - GtkLabelClass parent_class; - - gchar *signal_quote1; - gchar *signal_quote2; - gchar *mod_name_shift; - gchar *mod_name_control; - gchar *mod_name_alt; - gchar *mod_name_meta; - gchar *mod_name_super; - gchar *mod_name_hyper; - gchar *mod_name_mod2; - gchar *mod_name_mod3; - gchar *mod_name_mod4; - gchar *mod_name_mod5; - gchar *mod_separator; - gchar *accel_seperator; - guint latin1_to_char : 1; - - /* Padding for future expansion */ - void (*_gtk_reserved1) (void); - void (*_gtk_reserved2) (void); - void (*_gtk_reserved3) (void); - void (*_gtk_reserved4) (void); -}; - -GType meta_accel_label_get_type (void) G_GNUC_CONST; -GtkWidget* meta_accel_label_new_with_mnemonic (const gchar *string); -void meta_accel_label_set_accelerator (MetaAccelLabel *accel_label, - guint accelerator_key, - MetaVirtualModifier accelerator_mods); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - - -#endif /* __META_ACCEL_LABEL_H__ */ diff --git a/src/ui/preview-widget.c b/src/ui/preview-widget.c deleted file mode 100644 index 8f5789072..000000000 --- a/src/ui/preview-widget.c +++ /dev/null @@ -1,515 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Metacity theme preview widget */ - -/* - * Copyright (C) 2002 Havoc Pennington - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. - */ - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif -#define _XOPEN_SOURCE 600 /* for the maths routines over floats */ - -#include <math.h> -#include <gtk/gtk.h> -#include <meta/preview-widget.h> -#include "theme-private.h" - -static void meta_preview_get_preferred_width (GtkWidget *widget, - gint *minimum, - gint *natural); -static void meta_preview_get_preferred_height (GtkWidget *widget, - gint *minimum, - gint *natural); -static void meta_preview_size_allocate (GtkWidget *widget, - GtkAllocation *allocation); -static gboolean meta_preview_draw (GtkWidget *widget, - cairo_t *cr); -static void meta_preview_finalize (GObject *object); - -G_DEFINE_TYPE (MetaPreview, meta_preview, GTK_TYPE_BIN); - -static void -meta_preview_class_init (MetaPreviewClass *class) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (class); - GtkWidgetClass *widget_class; - - widget_class = (GtkWidgetClass*) class; - - gobject_class->finalize = meta_preview_finalize; - - widget_class->draw = meta_preview_draw; - widget_class->get_preferred_width = meta_preview_get_preferred_width; - widget_class->get_preferred_height = meta_preview_get_preferred_height; - widget_class->size_allocate = meta_preview_size_allocate; - - gtk_container_class_handle_border_width (GTK_CONTAINER_CLASS (class)); -} - -static void -meta_preview_init (MetaPreview *preview) -{ - int i; - - gtk_widget_set_has_window (GTK_WIDGET (preview), FALSE); - - i = 0; - while (i < MAX_BUTTONS_PER_CORNER) - { - preview->button_layout.left_buttons[i] = META_BUTTON_FUNCTION_LAST; - preview->button_layout.right_buttons[i] = META_BUTTON_FUNCTION_LAST; - ++i; - } - - preview->button_layout.left_buttons[0] = META_BUTTON_FUNCTION_MENU; - - preview->button_layout.right_buttons[0] = META_BUTTON_FUNCTION_MINIMIZE; - preview->button_layout.right_buttons[1] = META_BUTTON_FUNCTION_MAXIMIZE; - preview->button_layout.right_buttons[2] = META_BUTTON_FUNCTION_CLOSE; - - preview->type = META_FRAME_TYPE_NORMAL; - preview->flags = - META_FRAME_ALLOWS_DELETE | - META_FRAME_ALLOWS_MENU | - META_FRAME_ALLOWS_MINIMIZE | - META_FRAME_ALLOWS_MAXIMIZE | - META_FRAME_ALLOWS_VERTICAL_RESIZE | - META_FRAME_ALLOWS_HORIZONTAL_RESIZE | - META_FRAME_HAS_FOCUS | - META_FRAME_ALLOWS_SHADE | - META_FRAME_ALLOWS_MOVE; - - preview->borders_cached = FALSE; -} - -GtkWidget* -meta_preview_new (void) -{ - MetaPreview *preview; - - preview = g_object_new (META_TYPE_PREVIEW, NULL); - - return GTK_WIDGET (preview); -} - -static void -meta_preview_finalize (GObject *object) -{ - MetaPreview *preview; - - preview = META_PREVIEW (object); - - free (preview->title); - preview->title = NULL; - - G_OBJECT_CLASS (meta_preview_parent_class)->finalize (object); -} - -static void -ensure_info (MetaPreview *preview) -{ - GtkWidget *widget; - - widget = GTK_WIDGET (preview); - - if (preview->layout == NULL) - { - PangoFontDescription *font_desc; - double scale; - PangoAttrList *attrs; - PangoAttribute *attr; - - if (preview->theme) - scale = meta_theme_get_title_scale (preview->theme, - preview->type, - preview->flags); - else - scale = 1.0; - - preview->layout = gtk_widget_create_pango_layout (widget, - preview->title); - - font_desc = meta_gtk_widget_get_font_desc (widget, scale, NULL); - - preview->text_height = - meta_pango_font_desc_get_text_height (font_desc, - gtk_widget_get_pango_context (widget)); - - attrs = pango_attr_list_new (); - - attr = pango_attr_size_new (pango_font_description_get_size (font_desc)); - attr->start_index = 0; - attr->end_index = G_MAXINT; - - pango_attr_list_insert (attrs, attr); - - pango_layout_set_attributes (preview->layout, attrs); - - pango_attr_list_unref (attrs); - - pango_font_description_free (font_desc); - } - - if (!preview->borders_cached) - { - if (preview->theme) - meta_theme_get_frame_borders (preview->theme, - preview->type, - preview->text_height, - preview->flags, - &preview->borders); - else - meta_frame_borders_clear (&preview->borders); - preview->borders_cached = TRUE; - } -} - -static gboolean -meta_preview_draw (GtkWidget *widget, - cairo_t *cr) -{ - MetaPreview *preview = META_PREVIEW (widget); - GtkAllocation allocation; - - gtk_widget_get_allocation (widget, &allocation); - - if (preview->theme) - { - int client_width; - int client_height; - MetaButtonState button_states[META_BUTTON_TYPE_LAST] = - { - META_BUTTON_STATE_NORMAL, - META_BUTTON_STATE_NORMAL, - META_BUTTON_STATE_NORMAL, - META_BUTTON_STATE_NORMAL - }; - - ensure_info (preview); - cairo_save (cr); - - client_width = allocation.width - preview->borders.total.left - preview->borders.total.right; - client_height = allocation.height - preview->borders.total.top - preview->borders.total.bottom; - - if (client_width < 0) - client_width = 1; - if (client_height < 0) - client_height = 1; - - meta_theme_draw_frame (preview->theme, - widget, - cr, - preview->type, - preview->flags, - client_width, client_height, - preview->layout, - preview->text_height, - &preview->button_layout, - button_states); - - cairo_restore (cr); - } - - /* draw child */ - return GTK_WIDGET_CLASS (meta_preview_parent_class)->draw (widget, cr); -} - -#define NO_CHILD_WIDTH 80 -#define NO_CHILD_HEIGHT 20 - -static void -meta_preview_get_preferred_width (GtkWidget *widget, - gint *minimum, - gint *natural) -{ - MetaPreview *preview; - GtkWidget *child; - - preview = META_PREVIEW (widget); - - ensure_info (preview); - - *minimum = *natural = preview->borders.total.left + preview->borders.total.right; - - child = gtk_bin_get_child (GTK_BIN (preview)); - if (child && gtk_widget_get_visible (child)) - { - gint child_min, child_nat; - - gtk_widget_get_preferred_width (child, &child_min, &child_nat); - - *minimum += child_min; - *natural += child_nat; - } - else - { - *minimum += NO_CHILD_WIDTH; - *natural += NO_CHILD_WIDTH; - } -} - -static void -meta_preview_get_preferred_height (GtkWidget *widget, - gint *minimum, - gint *natural) -{ - MetaPreview *preview; - GtkWidget *child; - - preview = META_PREVIEW (widget); - - ensure_info (preview); - - *minimum = *natural = preview->borders.total.top + preview->borders.total.bottom; - - child = gtk_bin_get_child (GTK_BIN (preview)); - if (child && gtk_widget_get_visible (child)) - { - gint child_min, child_nat; - - gtk_widget_get_preferred_height (child, &child_min, &child_nat); - - *minimum += child_min; - *natural += child_nat; - } - else - { - *minimum += NO_CHILD_HEIGHT; - *natural += NO_CHILD_HEIGHT; - } -} - -static void -meta_preview_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) -{ - MetaPreview *preview; - GtkAllocation widget_allocation, child_allocation; - GtkWidget *child; - - preview = META_PREVIEW (widget); - - ensure_info (preview); - - gtk_widget_set_allocation (widget, allocation); - - child = gtk_bin_get_child (GTK_BIN (widget)); - if (child && gtk_widget_get_visible (child)) - { - gtk_widget_get_allocation (widget, &widget_allocation); - child_allocation.x = widget_allocation.x + preview->borders.total.left; - child_allocation.y = widget_allocation.y + preview->borders.total.top; - - child_allocation.width = MAX (1, widget_allocation.width - preview->borders.total.left - preview->borders.total.right); - child_allocation.height = MAX (1, widget_allocation.height - preview->borders.total.top - preview->borders.total.bottom); - - gtk_widget_size_allocate (child, &child_allocation); - } -} - -static void -clear_cache (MetaPreview *preview) -{ - if (preview->layout) - { - g_object_unref (G_OBJECT (preview->layout)); - preview->layout = NULL; - } - - preview->borders_cached = FALSE; -} - -void -meta_preview_set_theme (MetaPreview *preview, - MetaTheme *theme) -{ - g_return_if_fail (META_IS_PREVIEW (preview)); - - preview->theme = theme; - - clear_cache (preview); - - gtk_widget_queue_resize (GTK_WIDGET (preview)); -} - -void -meta_preview_set_title (MetaPreview *preview, - const char *title) -{ - g_return_if_fail (META_IS_PREVIEW (preview)); - - free (preview->title); - preview->title = g_strdup (title); - - clear_cache (preview); - - gtk_widget_queue_resize (GTK_WIDGET (preview)); -} - -void -meta_preview_set_frame_type (MetaPreview *preview, - MetaFrameType type) -{ - g_return_if_fail (META_IS_PREVIEW (preview)); - - preview->type = type; - - clear_cache (preview); - - gtk_widget_queue_resize (GTK_WIDGET (preview)); -} - -void -meta_preview_set_frame_flags (MetaPreview *preview, - MetaFrameFlags flags) -{ - g_return_if_fail (META_IS_PREVIEW (preview)); - - preview->flags = flags; - - clear_cache (preview); - - gtk_widget_queue_resize (GTK_WIDGET (preview)); -} - -void -meta_preview_set_button_layout (MetaPreview *preview, - const MetaButtonLayout *button_layout) -{ - g_return_if_fail (META_IS_PREVIEW (preview)); - - preview->button_layout = *button_layout; - - gtk_widget_queue_draw (GTK_WIDGET (preview)); -} - -cairo_region_t * -meta_preview_get_clip_region (MetaPreview *preview, gint new_window_width, gint new_window_height) -{ - cairo_rectangle_int_t xrect; - cairo_region_t *corners_xregion, *window_xregion; - gint flags; - MetaFrameLayout *fgeom; - MetaFrameStyle *frame_style; - - g_return_val_if_fail (META_IS_PREVIEW (preview), NULL); - - flags = (META_PREVIEW (preview)->flags); - - window_xregion = cairo_region_create (); - - xrect.x = 0; - xrect.y = 0; - xrect.width = new_window_width; - xrect.height = new_window_height; - - cairo_region_union_rectangle (window_xregion, &xrect); - - if (preview->theme == NULL) - return window_xregion; - - /* Otherwise, we do have a theme, so calculate the corners */ - frame_style = meta_theme_get_frame_style (preview->theme, - META_FRAME_TYPE_NORMAL, flags); - - fgeom = frame_style->layout; - - corners_xregion = cairo_region_create (); - - if (fgeom->top_left_corner_rounded_radius != 0) - { - const int corner = fgeom->top_left_corner_rounded_radius; - const float radius = sqrt(corner) + corner; - int i; - - for (i=0; i<corner; i++) - { - - const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5)))); - xrect.x = 0; - xrect.y = i; - xrect.width = width; - xrect.height = 1; - - cairo_region_union_rectangle (corners_xregion, &xrect); - } - } - - if (fgeom->top_right_corner_rounded_radius != 0) - { - const int corner = fgeom->top_right_corner_rounded_radius; - const float radius = sqrt(corner) + corner; - int i; - - for (i=0; i<corner; i++) - { - const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5)))); - xrect.x = new_window_width - width; - xrect.y = i; - xrect.width = width; - xrect.height = 1; - - cairo_region_union_rectangle (corners_xregion, &xrect); - } - } - - if (fgeom->bottom_left_corner_rounded_radius != 0) - { - const int corner = fgeom->bottom_left_corner_rounded_radius; - const float radius = sqrt(corner) + corner; - int i; - - for (i=0; i<corner; i++) - { - const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5)))); - xrect.x = 0; - xrect.y = new_window_height - i - 1; - xrect.width = width; - xrect.height = 1; - - cairo_region_union_rectangle (corners_xregion, &xrect); - } - } - - if (fgeom->bottom_right_corner_rounded_radius != 0) - { - const int corner = fgeom->bottom_right_corner_rounded_radius; - const float radius = sqrt(corner) + corner; - int i; - - for (i=0; i<corner; i++) - { - const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5)))); - xrect.x = new_window_width - width; - xrect.y = new_window_height - i - 1; - xrect.width = width; - xrect.height = 1; - - cairo_region_union_rectangle (corners_xregion, &xrect); - } - } - - cairo_region_subtract (window_xregion, corners_xregion); - cairo_region_destroy (corners_xregion); - - return window_xregion; -} - - diff --git a/src/ui/resizepopup.c b/src/ui/resizepopup.c deleted file mode 100644 index 56742fd72..000000000 --- a/src/ui/resizepopup.c +++ /dev/null @@ -1,217 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Metacity resizing-terminal-window feedback */ - -/* - * Copyright (C) 2001 Havoc Pennington - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. - */ - -#include <config.h> -#include "resizepopup.h" -#include "util-private.h" -#include <gtk/gtk.h> -#include <gdk/gdkx.h> - -struct _MetaResizePopup -{ - GtkWidget *size_window; - GtkWidget *size_label; - Display *display; - int screen_number; - - int vertical_size; - int horizontal_size; - - gboolean showing; - - MetaRectangle rect; -}; - -LOCAL_SYMBOL MetaResizePopup* -meta_ui_resize_popup_new (Display *display, - int screen_number) -{ - MetaResizePopup *popup; - - popup = g_new0 (MetaResizePopup, 1); - - popup->display = display; - popup->screen_number = screen_number; - - return popup; -} - -LOCAL_SYMBOL void -meta_ui_resize_popup_free (MetaResizePopup *popup) -{ - g_return_if_fail (popup != NULL); - - if (popup->size_window) - gtk_widget_destroy (popup->size_window); - - free (popup); -} - -static void -ensure_size_window (MetaResizePopup *popup) -{ - GtkWidget *frame; - - if (popup->size_window) - return; - - popup->size_window = gtk_window_new (GTK_WINDOW_POPUP); - - gtk_window_set_screen (GTK_WINDOW (popup->size_window), - gdk_display_get_screen (gdk_x11_lookup_xdisplay (popup->display), - popup->screen_number)); - - /* never shrink the size window */ - gtk_window_set_resizable (GTK_WINDOW (popup->size_window), - TRUE); - - frame = gtk_frame_new (NULL); - gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT); - - gtk_container_add (GTK_CONTAINER (popup->size_window), frame); - - popup->size_label = gtk_label_new (""); - gtk_misc_set_padding (GTK_MISC (popup->size_label), 3, 3); - - gtk_container_add (GTK_CONTAINER (frame), popup->size_label); - - gtk_widget_show_all (frame); -} - -static void -update_size_window (MetaResizePopup *popup) -{ - char *str; - int x, y; - int width, height; - - g_return_if_fail (popup->size_window != NULL); - - /* Translators: This represents the size of a window. The first number is - * the width of the window and the second is the height. - */ - str = g_strdup_printf (_("%d x %d"), - popup->horizontal_size, - popup->vertical_size); - - gtk_label_set_text (GTK_LABEL (popup->size_label), str); - - free (str); - - gtk_window_get_size (GTK_WINDOW (popup->size_window), &width, &height); - - x = popup->rect.x + (popup->rect.width - width) / 2; - y = popup->rect.y + (popup->rect.height - height) / 2; - - if (gtk_widget_get_realized (popup->size_window)) - { - /* using move_resize to avoid jumpiness */ - gdk_window_move_resize (gtk_widget_get_window (popup->size_window), - x, y, - width, height); - } - else - { - gtk_window_move (GTK_WINDOW (popup->size_window), - x, y); - } -} - -static void -sync_showing (MetaResizePopup *popup) -{ - if (popup->showing) - { - if (popup->size_window) - gtk_widget_show (popup->size_window); - - if (popup->size_window && gtk_widget_get_realized (popup->size_window)) - gdk_window_raise (gtk_widget_get_window (popup->size_window)); - } - else - { - if (popup->size_window) - gtk_widget_hide (popup->size_window); - } -} - -LOCAL_SYMBOL void -meta_ui_resize_popup_set (MetaResizePopup *popup, - MetaRectangle rect, - int base_width, - int base_height, - int width_inc, - int height_inc) -{ - gboolean need_update_size; - int display_w, display_h; - - g_return_if_fail (popup != NULL); - - need_update_size = FALSE; - - display_w = rect.width - base_width; - if (width_inc > 0) - display_w /= width_inc; - - display_h = rect.height - base_height; - if (height_inc > 0) - display_h /= height_inc; - - if (!meta_rectangle_equal(&popup->rect, &rect) || - display_w != popup->horizontal_size || - display_h != popup->vertical_size) - need_update_size = TRUE; - - popup->rect = rect; - popup->vertical_size = display_h; - popup->horizontal_size = display_w; - - if (need_update_size) - { - ensure_size_window (popup); - update_size_window (popup); - } - - sync_showing (popup); -} - -LOCAL_SYMBOL void -meta_ui_resize_popup_set_showing (MetaResizePopup *popup, - gboolean showing) -{ - g_return_if_fail (popup != NULL); - - if (showing == popup->showing) - return; - - popup->showing = !!showing; - - if (popup->showing) - { - ensure_size_window (popup); - update_size_window (popup); - } - - sync_showing (popup); -} diff --git a/src/ui/resizepopup.h b/src/ui/resizepopup.h deleted file mode 100644 index 084731d32..000000000 --- a/src/ui/resizepopup.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Muffin resizing-terminal-window feedback */ - -/* - * Copyright (C) 2001 Havoc Pennington - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. - */ - -#ifndef META_RESIZEPOPUP_H -#define META_RESIZEPOPUP_H - -/* Don't include gtk.h or gdk.h here */ -#include <meta/boxes.h> -#include <meta/common.h> -#include <X11/Xlib.h> -#include <glib.h> -#include <gdk-pixbuf/gdk-pixbuf.h> - -MetaResizePopup* meta_ui_resize_popup_new (Display *display, - int screen_number); -void meta_ui_resize_popup_free (MetaResizePopup *popup); -void meta_ui_resize_popup_set (MetaResizePopup *popup, - MetaRectangle rect, - int base_width, - int base_height, - int width_inc, - int height_inc); -void meta_ui_resize_popup_set_showing (MetaResizePopup *popup, - gboolean showing); - -#endif - diff --git a/src/ui/testgradient.c b/src/ui/testgradient.c deleted file mode 100644 index 146d29334..000000000 --- a/src/ui/testgradient.c +++ /dev/null @@ -1,317 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Muffin gradient test program */ - -/* - * Copyright (C) 2002 Havoc Pennington - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. */ - -#include <meta/gradient.h> -#include <gtk/gtk.h> - -typedef void (* RenderGradientFunc) (cairo_t *cr, - int width, - int height); - -static void -draw_checkerboard (cairo_t *cr, - int width, - int height) -{ - gint i, j, xcount, ycount; - GdkRGBA color1, color2; - -#define CHECK_SIZE 10 -#define SPACING 2 - - color1.red = 30000. / 65535.; - color1.green = 30000. / 65535.; - color1.blue = 30000. / 65535.; - color1.alpha = 1.0; - - color2.red = 50000. / 65535.; - color2.green = 50000. / 65535.; - color2.blue = 50000. / 65535.; - color2.alpha = 1.0; - - xcount = 0; - i = SPACING; - while (i < width) - { - j = SPACING; - ycount = xcount % 2; /* start with even/odd depending on row */ - while (j < height) - { - if (ycount % 2) - gdk_cairo_set_source_rgba (cr, &color1); - else - gdk_cairo_set_source_rgba (cr, &color2); - - /* If we're outside event->area, this will do nothing. - * It might be mildly more efficient if we handled - * the clipping ourselves, but again we're feeling lazy. - */ - cairo_rectangle (cr, i, j, CHECK_SIZE, CHECK_SIZE); - cairo_fill (cr); - - j += CHECK_SIZE + SPACING; - ++ycount; - } - - i += CHECK_SIZE + SPACING; - ++xcount; - } -} - -static void -render_simple (cairo_t *cr, - int width, int height, - MetaGradientType type, - gboolean with_alpha) -{ - GdkPixbuf *pixbuf; - GdkRGBA from, to; - - gdk_rgba_parse (&from, "blue"); - gdk_rgba_parse (&to, "green"); - - pixbuf = meta_gradient_create_simple (width, height, - &from, &to, - type); - - if (with_alpha) - { - const unsigned char alphas[] = { 0xff, 0xaa, 0x2f, 0x0, 0xcc, 0xff, 0xff }; - - if (!gdk_pixbuf_get_has_alpha (pixbuf)) - { - GdkPixbuf *new_pixbuf; - - new_pixbuf = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0); - g_object_unref (G_OBJECT (pixbuf)); - pixbuf = new_pixbuf; - } - - meta_gradient_add_alpha (pixbuf, - alphas, G_N_ELEMENTS (alphas), - META_GRADIENT_HORIZONTAL); - - draw_checkerboard (cr , width, height); - } - - gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0); - cairo_rectangle (cr, 0, 0, width, height); - cairo_fill (cr); - - g_object_unref (G_OBJECT (pixbuf)); -} - -static void -render_vertical_func (cairo_t *cr, - int width, int height) -{ - render_simple (cr, width, height, META_GRADIENT_VERTICAL, FALSE); -} - -static void -render_horizontal_func (cairo_t *cr, - int width, int height) -{ - render_simple (cr, width, height, META_GRADIENT_HORIZONTAL, FALSE); -} - -static void -render_diagonal_func (cairo_t *cr, - int width, int height) -{ - render_simple (cr, width, height, META_GRADIENT_DIAGONAL, FALSE); -} - -static void -render_diagonal_alpha_func (cairo_t *cr, - int width, int height) -{ - render_simple (cr, width, height, META_GRADIENT_DIAGONAL, TRUE); -} - -static void -render_multi (cairo_t *cr, - int width, int height, - MetaGradientType type) -{ - GdkPixbuf *pixbuf; -#define N_COLORS 5 - GdkRGBA colors[N_COLORS]; - - gdk_rgba_parse (&colors[0], "red"); - gdk_rgba_parse (&colors[1], "blue"); - gdk_rgba_parse (&colors[2], "orange"); - gdk_rgba_parse (&colors[3], "pink"); - gdk_rgba_parse (&colors[4], "green"); - - pixbuf = meta_gradient_create_multi (width, height, - colors, N_COLORS, - type); - - gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0); - cairo_rectangle (cr, 0, 0, width, height); - cairo_fill (cr); - - g_object_unref (G_OBJECT (pixbuf)); -#undef N_COLORS -} - -static void -render_vertical_multi_func (cairo_t *cr, - int width, int height) -{ - render_multi (cr, width, height, META_GRADIENT_VERTICAL); -} - -static void -render_horizontal_multi_func (cairo_t *cr, - int width, int height) -{ - render_multi (cr, width, height, META_GRADIENT_HORIZONTAL); -} - -static void -render_diagonal_multi_func (cairo_t *cr, - int width, int height) -{ - render_multi (cr, width, height, META_GRADIENT_DIAGONAL); -} - -static void -render_interwoven_func (cairo_t *cr, - int width, int height) -{ - GdkPixbuf *pixbuf; -#define N_COLORS 4 - GdkRGBA colors[N_COLORS]; - - gdk_rgba_parse (&colors[0], "red"); - gdk_rgba_parse (&colors[1], "blue"); - gdk_rgba_parse (&colors[2], "pink"); - gdk_rgba_parse (&colors[3], "green"); - - pixbuf = meta_gradient_create_interwoven (width, height, - colors, height / 10, - colors + 2, height / 14); - - gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0); - cairo_rectangle (cr, 0, 0, width, height); - cairo_fill (cr); - - g_object_unref (G_OBJECT (pixbuf)); -} - -static gboolean -draw_callback (GtkWidget *widget, - cairo_t *cr, - gpointer data) -{ - RenderGradientFunc func = data; - GtkStyleContext *style; - GdkRGBA color; - - style = gtk_widget_get_style_context (widget); - - gtk_style_context_save (style); - gtk_style_context_set_state (style, gtk_widget_get_state_flags (widget)); - gtk_style_context_lookup_color (style, "foreground-color", &color); - gtk_style_context_restore (style); - - gdk_cairo_set_source_rgba (cr, &color); - - (* func) (cr, - gtk_widget_get_allocated_width (widget), - gtk_widget_get_allocated_height (widget)); - - return FALSE; -} - -static GtkWidget* -create_gradient_window (const char *title, - RenderGradientFunc func) -{ - GtkWidget *window; - GtkWidget *drawing_area; - - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - - gtk_window_set_title (GTK_WINDOW (window), title); - - drawing_area = gtk_drawing_area_new (); - - gtk_widget_set_size_request (drawing_area, 1, 1); - - gtk_window_set_default_size (GTK_WINDOW (window), 175, 175); - - g_signal_connect (G_OBJECT (drawing_area), - "draw", - G_CALLBACK (draw_callback), - func); - - gtk_container_add (GTK_CONTAINER (window), drawing_area); - - gtk_widget_show_all (window); - - return window; -} - -static void -meta_gradient_test (void) -{ - create_gradient_window ("Simple vertical", - render_vertical_func); - - create_gradient_window ("Simple horizontal", - render_horizontal_func); - - create_gradient_window ("Simple diagonal", - render_diagonal_func); - - create_gradient_window ("Multi vertical", - render_vertical_multi_func); - - create_gradient_window ("Multi horizontal", - render_horizontal_multi_func); - - create_gradient_window ("Multi diagonal", - render_diagonal_multi_func); - - create_gradient_window ("Interwoven", - render_interwoven_func); - - create_gradient_window ("Simple diagonal with horizontal multi alpha", - render_diagonal_alpha_func); - -} - -int -main (int argc, char **argv) -{ - gtk_init (&argc, &argv); - - meta_gradient_test (); - - gtk_main (); - - return 0; -} - diff --git a/src/ui/theme-parser.c b/src/ui/theme-parser.c deleted file mode 100644 index 628bf73e9..000000000 --- a/src/ui/theme-parser.c +++ /dev/null @@ -1,4419 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Metacity theme parsing */ - -/* - * Copyright (C) 2001 Havoc Pennington - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. - */ - -#include <config.h> -#include "theme-private.h" -#include "util-private.h" -#include <meta/prefs.h> -#include <string.h> -#include <stdlib.h> -#include <clutter/clutter.h> - -/* We were intending to put the version number - * in the subdirectory name, but we ended up - * using the filename instead. The "-1" survives - * as a fossil. - */ -#define THEME_SUBDIR "metacity-1" - -/* Highest version of the theme format to - * look out for. - */ -#define THEME_MAJOR_VERSION 3 -#define THEME_MINOR_VERSION 4 -#define THEME_VERSION (1000 * THEME_MAJOR_VERSION + THEME_MINOR_VERSION) - -#define METACITY_THEME_FILENAME_FORMAT "metacity-theme-%d.xml" - -typedef enum -{ - STATE_START, - STATE_THEME, - /* info section */ - STATE_INFO, - STATE_NAME, - STATE_AUTHOR, - STATE_COPYRIGHT, - STATE_DATE, - STATE_DESCRIPTION, - /* constants */ - STATE_CONSTANT, - /* geometry */ - STATE_FRAME_GEOMETRY, - STATE_DISTANCE, - STATE_BORDER, - STATE_ASPECT_RATIO, - /* draw ops */ - STATE_DRAW_OPS, - STATE_LINE, - STATE_RECTANGLE, - STATE_ARC, - STATE_CLIP, - STATE_TINT, - STATE_GRADIENT, - STATE_IMAGE, - STATE_GTK_ARROW, - STATE_GTK_BOX, - STATE_GTK_VLINE, - STATE_ICON, - STATE_TITLE, - STATE_INCLUDE, /* include another draw op list */ - STATE_TILE, /* tile another draw op list */ - /* sub-parts of gradient */ - STATE_COLOR, - /* frame style */ - STATE_FRAME_STYLE, - STATE_PIECE, - STATE_BUTTON, - /* style set */ - STATE_FRAME_STYLE_SET, - STATE_FRAME, - /* assigning style sets to windows */ - STATE_WINDOW, - /* things we don't use any more but we can still parse: */ - STATE_MENU_ICON, - STATE_FALLBACK, - /* an ubuntu specific ignore-this-element state */ - UBUNTU_STATE_IGNORE -} ParseState; - -typedef struct -{ - /* This two lists contain stacks of state and required version - * (cast to pointers.) There is one list item for each currently - * open element. */ - GSList *states; - GSList *required_versions; - - const char *theme_name; /* name of theme (directory it's in) */ - const char *theme_file; /* theme filename */ - const char *theme_dir; /* dir the theme is inside */ - MetaTheme *theme; /* theme being parsed */ - guint format_version; /* version of format of theme file */ - char *name; /* name of named thing being parsed */ - MetaFrameLayout *layout; /* layout being parsed if any */ - MetaDrawOpList *op_list; /* op list being parsed if any */ - MetaDrawOp *op; /* op being parsed if any */ - MetaFrameStyle *style; /* frame style being parsed if any */ - MetaFrameStyleSet *style_set; /* frame style set being parsed if any */ - MetaFramePiece piece; /* position of piece being parsed */ - MetaButtonType button_type; /* type of button/menuitem being parsed */ - MetaButtonState button_state; /* state of button being parsed */ - int skip_level; /* depth of elements that we're ignoring */ -} ParseInfo; - -typedef enum { - THEME_PARSE_ERROR_TOO_OLD, - THEME_PARSE_ERROR_TOO_FAILED -} ThemeParseError; - -static GQuark -theme_parse_error_quark (void) -{ - return g_quark_from_static_string ("theme-parse-error-quark"); -} - -#define THEME_PARSE_ERROR (theme_parse_error_quark ()) - -static void set_error (GError **err, - GMarkupParseContext *context, - int error_domain, - int error_code, - const char *format, - ...) G_GNUC_PRINTF (5, 6); - -static void add_context_to_error (GError **err, - GMarkupParseContext *context); - -static void parse_info_init (ParseInfo *info); -static void parse_info_free (ParseInfo *info); - -static void push_state (ParseInfo *info, - ParseState state); -static void pop_state (ParseInfo *info); -static ParseState peek_state (ParseInfo *info); - - -static void parse_toplevel_element (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - ParseInfo *info, - GError **error); -static void parse_info_element (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - ParseInfo *info, - GError **error); -static void parse_geometry_element (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - ParseInfo *info, - GError **error); -static void parse_draw_op_element (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - ParseInfo *info, - GError **error); -static void parse_gradient_element (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - ParseInfo *info, - GError **error); -static void parse_style_element (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - ParseInfo *info, - GError **error); -static void parse_style_set_element (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - ParseInfo *info, - GError **error); - -static void parse_piece_element (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - ParseInfo *info, - GError **error); - -static void parse_button_element (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - ParseInfo *info, - GError **error); - -static void parse_menu_icon_element (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - ParseInfo *info, - GError **error); - -static void start_element_handler (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - gpointer user_data, - GError **error); -static void end_element_handler (GMarkupParseContext *context, - const gchar *element_name, - gpointer user_data, - GError **error); -static void text_handler (GMarkupParseContext *context, - const gchar *text, - gsize text_len, - gpointer user_data, - GError **error); - -/* Translators: This means that an attribute which should have been found - * on an XML element was not in fact found. - */ -#define ATTRIBUTE_NOT_FOUND _("No \"%s\" attribute on element <%s>") - -static GMarkupParser metacity_theme_parser = { - start_element_handler, - end_element_handler, - text_handler, - NULL, - NULL -}; - -static void -set_error (GError **err, - GMarkupParseContext *context, - int error_domain, - int error_code, - const char *format, - ...) -{ - int line, ch; - va_list args; - char *str; - - g_markup_parse_context_get_position (context, &line, &ch); - - va_start (args, format); - str = g_strdup_vprintf (format, args); - va_end (args); - - g_set_error (err, error_domain, error_code, - _("Line %d character %d: %s"), - line, ch, str); - - free (str); -} - -static void -add_context_to_error (GError **err, - GMarkupParseContext *context) -{ - int line, ch; - char *str; - - if (err == NULL || *err == NULL) - return; - - g_markup_parse_context_get_position (context, &line, &ch); - - str = g_strdup_printf (_("Line %d character %d: %s"), - line, ch, (*err)->message); - free ((*err)->message); - (*err)->message = str; -} - -static void -parse_info_init (ParseInfo *info) -{ - info->theme_file = NULL; - info->states = g_slist_prepend (NULL, GINT_TO_POINTER (STATE_START)); - info->required_versions = NULL; - info->theme = NULL; - info->name = NULL; - info->layout = NULL; - info->op_list = NULL; - info->op = NULL; - info->style = NULL; - info->style_set = NULL; - info->piece = META_FRAME_PIECE_LAST; - info->button_type = META_BUTTON_TYPE_LAST; - info->button_state = META_BUTTON_STATE_LAST; - info->skip_level = 0; -} - -static void -parse_info_free (ParseInfo *info) -{ - g_slist_free (info->states); - g_slist_free (info->required_versions); - - if (info->theme) - meta_theme_free (info->theme); - - if (info->layout) - meta_frame_layout_unref (info->layout); - - if (info->op_list) - meta_draw_op_list_unref (info->op_list); - - if (info->op) - meta_draw_op_free (info->op); - - if (info->style) - meta_frame_style_unref (info->style); - - if (info->style_set) - meta_frame_style_set_unref (info->style_set); -} - -static void -push_state (ParseInfo *info, - ParseState state) -{ - info->states = g_slist_prepend (info->states, GINT_TO_POINTER (state)); -} - -static void -pop_state (ParseInfo *info) -{ - g_return_if_fail (info->states != NULL); - - info->states = g_slist_remove (info->states, info->states->data); -} - -static ParseState -peek_state (ParseInfo *info) -{ - g_return_val_if_fail (info->states != NULL, STATE_START); - - return GPOINTER_TO_INT (info->states->data); -} - -static void -push_required_version (ParseInfo *info, - int version) -{ - info->required_versions = g_slist_prepend (info->required_versions, - GINT_TO_POINTER (version)); -} - -static void -pop_required_version (ParseInfo *info) -{ - g_return_if_fail (info->required_versions != NULL); - - info->required_versions = g_slist_delete_link (info->required_versions, info->required_versions); -} - -static int -peek_required_version (ParseInfo *info) -{ - if (info->required_versions) - return GPOINTER_TO_INT (info->required_versions->data); - else - return info->format_version; -} - -#define ELEMENT_IS(name) (strcmp (element_name, (name)) == 0) - -typedef struct -{ - const char *name; - const char **retloc; - gboolean required; -} LocateAttr; - -/* Attribute names can have a leading '!' to indicate that they are - * required. - */ -static gboolean -locate_attributes (GMarkupParseContext *context, - const char *element_name, - const char **attribute_names, - const char **attribute_values, - GError **error, - const char *first_attribute_name, - const char **first_attribute_retloc, - ...) -{ - va_list args; - const char *name; - const char **retloc; - int n_attrs; -#define MAX_ATTRS 24 - LocateAttr attrs[MAX_ATTRS]; - gboolean retval; - int i; - - g_return_val_if_fail (first_attribute_name != NULL, FALSE); - g_return_val_if_fail (first_attribute_retloc != NULL, FALSE); - - retval = TRUE; - - /* FIXME: duplicated code; refactor loop */ - n_attrs = 1; - attrs[0].name = first_attribute_name; - attrs[0].retloc = first_attribute_retloc; - attrs[0].required = attrs[0].name[0]=='!'; - if (attrs[0].required) - attrs[0].name++; /* skip past it */ - *first_attribute_retloc = NULL; - - va_start (args, first_attribute_retloc); - - name = va_arg (args, const char*); - retloc = va_arg (args, const char**); - - while (name != NULL) - { - g_return_val_if_fail (retloc != NULL, FALSE); - - g_assert (n_attrs < MAX_ATTRS); - - attrs[n_attrs].name = name; - attrs[n_attrs].retloc = retloc; - attrs[n_attrs].required = attrs[n_attrs].name[0]=='!'; - if (attrs[n_attrs].required) - attrs[n_attrs].name++; /* skip past it */ - - n_attrs += 1; - *retloc = NULL; - - name = va_arg (args, const char*); - retloc = va_arg (args, const char**); - } - - va_end (args); - - i = 0; - while (attribute_names[i]) - { - int j; - gboolean found; - - /* Can be present anywhere */ - if (strcmp (attribute_names[i], "version") == 0) - { - ++i; - continue; - } - - found = FALSE; - j = 0; - while (j < n_attrs) - { - if (strcmp (attrs[j].name, attribute_names[i]) == 0) - { - retloc = attrs[j].retloc; - - if (*retloc != NULL) - { - - set_error (error, context, - G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("Attribute \"%s\" repeated twice on the same <%s> element"), - attrs[j].name, element_name); - retval = FALSE; - goto out; - } - - *retloc = attribute_values[i]; - found = TRUE; - } - - ++j; - } - - if (!found) - { - j = 0; - while (j < n_attrs) - { - g_warning ("It could have been %s.\n", attrs[j++].name); - } - - set_error (error, context, - G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("Attribute \"%s\" is invalid on <%s> element in this context"), - attribute_names[i], element_name); - retval = FALSE; - goto out; - } - - ++i; - } - - /* Did we catch them all? */ - i = 0; - while (i < n_attrs) - { - if (attrs[i].required && *(attrs[i].retloc)==NULL) - { - set_error (error, context, - G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - ATTRIBUTE_NOT_FOUND, - attrs[i].name, element_name); - retval = FALSE; - goto out; - } - - ++i; - } - - out: - return retval; -} - -static gboolean -check_no_attributes (GMarkupParseContext *context, - const char *element_name, - const char **attribute_names, - const char **attribute_values, - GError **error) -{ - int i = 0; - - /* Can be present anywhere */ - if (attribute_names[0] && strcmp (attribute_names[i], "version") == 0) - i++; - - if (attribute_names[i] != NULL) - { - set_error (error, context, - G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("Attribute \"%s\" is invalid on <%s> element in this context"), - attribute_names[0], element_name); - return FALSE; - } - - return TRUE; -} - -#define MAX_REASONABLE 4096 -static gboolean -parse_positive_integer (const char *str, - int *val, - GMarkupParseContext *context, - MetaTheme *theme, - GError **error) -{ - char *end; - long l; - int j; - - *val = 0; - - end = NULL; - - /* Is str a constant? */ - - if (META_THEME_ALLOWS (theme, META_THEME_UBIQUITOUS_CONSTANTS) && - meta_theme_lookup_int_constant (theme, str, &j)) - { - /* Yes. */ - l = j; - } - else - { - /* No. Let's try parsing it instead. */ - - l = strtol (str, &end, 10); - - if (end == NULL || end == str) - { - set_error (error, context, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("Could not parse \"%s\" as an integer"), - str); - return FALSE; - } - - if (*end != '\0') - { - set_error (error, context, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("Did not understand trailing characters \"%s\" in string \"%s\""), - end, str); - return FALSE; - } - } - - if (l < 0) - { - set_error (error, context, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("Integer %ld must be positive"), l); - return FALSE; - } - - if (l > MAX_REASONABLE) - { - set_error (error, context, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("Integer %ld is too large, current max is %d"), - l, MAX_REASONABLE); - return FALSE; - } - - *val = (int) l * theme->scale; - - return TRUE; -} - -static gboolean -parse_double (const char *str, - double *val, - GMarkupParseContext *context, - GError **error) -{ - char *end; - - *val = 0; - - end = NULL; - - *val = g_ascii_strtod (str, &end); - - if (end == NULL || end == str) - { - set_error (error, context, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("Could not parse \"%s\" as a floating point number"), - str); - return FALSE; - } - - if (*end != '\0') - { - set_error (error, context, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("Did not understand trailing characters \"%s\" in string \"%s\""), - end, str); - return FALSE; - } - - return TRUE; -} - -static gboolean -parse_boolean (const char *str, - gboolean *val, - GMarkupParseContext *context, - GError **error) -{ - if (strcmp ("true", str) == 0) - *val = TRUE; - else if (strcmp ("false", str) == 0) - *val = FALSE; - else - { - set_error (error, context, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("Boolean values must be \"true\" or \"false\" not \"%s\""), - str); - return FALSE; - } - - return TRUE; -} - -static gboolean -parse_rounding (const char *str, - guint *val, - GMarkupParseContext *context, - MetaTheme *theme, - GError **error) -{ - if (strcmp ("true", str) == 0) - *val = 5; /* historical "true" value */ - else if (strcmp ("false", str) == 0) - *val = 0; - else - { - int tmp; - gboolean result; - if (!META_THEME_ALLOWS (theme, META_THEME_VARIED_ROUND_CORNERS)) - { - /* Not known in this version, so bail. */ - set_error (error, context, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("Boolean values must be \"true\" or \"false\" not \"%s\""), - str); - return FALSE; - } - - result = parse_positive_integer (str, &tmp, context, theme, error); - - *val = tmp; - - return result; - } - - return TRUE; -} - -static gboolean -parse_angle (const char *str, - double *val, - GMarkupParseContext *context, - GError **error) -{ - if (!parse_double (str, val, context, error)) - return FALSE; - - if (*val < (0.0 - 1e6) || *val > (360.0 + 1e6)) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Angle must be between 0.0 and 360.0, was %g\n"), - *val); - return FALSE; - } - - return TRUE; -} - -static gboolean -parse_alpha (const char *str, - MetaAlphaGradientSpec **spec_ret, - GMarkupParseContext *context, - GError **error) -{ - char **split; - int i; - int n_alphas; - MetaAlphaGradientSpec *spec; - - *spec_ret = NULL; - - split = g_strsplit (str, ":", -1); - - i = 0; - while (split[i]) - ++i; - - if (i == 0) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Could not parse \"%s\" as a floating point number"), - str); - - g_strfreev (split); - - return FALSE; - } - - n_alphas = i; - - /* FIXME allow specifying horizontal/vertical/diagonal in theme format, - * once we implement vertical/diagonal in gradient.c - */ - spec = meta_alpha_gradient_spec_new (META_GRADIENT_HORIZONTAL, - n_alphas); - - i = 0; - while (i < n_alphas) - { - double v; - - if (!parse_double (split[i], &v, context, error)) - { - /* clear up, but don't set error: it was set by parse_double */ - g_strfreev (split); - meta_alpha_gradient_spec_free (spec); - - return FALSE; - } - - if (v < (0.0 - 1e-6) || v > (1.0 + 1e-6)) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n"), - v); - - g_strfreev (split); - meta_alpha_gradient_spec_free (spec); - - return FALSE; - } - - spec->alphas[i] = (unsigned char) (v * 255); - - ++i; - } - - g_strfreev (split); - - *spec_ret = spec; - - return TRUE; -} - -static MetaColorSpec* -parse_color (MetaTheme *theme, - const char *str, - GError **err) -{ - char* referent; - - if (META_THEME_ALLOWS (theme, META_THEME_COLOR_CONSTANTS) && - meta_theme_lookup_color_constant (theme, str, &referent)) - { - if (referent) - return meta_color_spec_new_from_string (referent, err); - - /* no need to free referent: it's a pointer into the actual hash table */ - } - - return meta_color_spec_new_from_string (str, err); -} - -static gboolean -parse_title_scale (const char *str, - double *val, - GMarkupParseContext *context, - GError **error) -{ - double factor; - - if (strcmp (str, "xx-small") == 0) - factor = PANGO_SCALE_XX_SMALL; - else if (strcmp (str, "x-small") == 0) - factor = PANGO_SCALE_X_SMALL; - else if (strcmp (str, "small") == 0) - factor = PANGO_SCALE_SMALL; - else if (strcmp (str, "medium") == 0) - factor = PANGO_SCALE_MEDIUM; - else if (strcmp (str, "large") == 0) - factor = PANGO_SCALE_LARGE; - else if (strcmp (str, "x-large") == 0) - factor = PANGO_SCALE_X_LARGE; - else if (strcmp (str, "xx-large") == 0) - factor = PANGO_SCALE_XX_LARGE; - else - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium,large,x-large,xx-large)\n"), - str); - return FALSE; - } - - *val = factor; - - return TRUE; -} - -static void -parse_toplevel_element (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - ParseInfo *info, - GError **error) -{ - g_return_if_fail (peek_state (info) == STATE_THEME); - - if (ELEMENT_IS ("info")) - { - if (!check_no_attributes (context, element_name, - attribute_names, attribute_values, - error)) - return; - - push_state (info, STATE_INFO); - } - else if (ELEMENT_IS ("constant")) - { - const char *name; - const char *value; - int ival = 0; - double dval = 0.0; - - if (!locate_attributes (context, element_name, attribute_names, attribute_values, - error, - "!name", &name, "!value", &value, - NULL)) - return; - - /* We don't know how a a constant is going to be used, so we have guess its - * type from its contents: - * - * - Starts like a number and contains a '.': float constant - * - Starts like a number and doesn't contain a '.': int constant - * - Starts with anything else: a color constant. - * (colors always start with # or a letter) - */ - if (value[0] == '.' || value[0] == '+' || value[0] == '-' || (value[0] >= '0' && value[0] <= '9')) - { - if (strchr (value, '.')) - { - if (!parse_double (value, &dval, context, error)) - return; - - if (!meta_theme_define_float_constant (info->theme, - name, - dval, - error)) - { - add_context_to_error (error, context); - return; - } - } - else - { - if (!parse_positive_integer (value, &ival, context, info->theme, error)) - return; - - if (!meta_theme_define_int_constant (info->theme, - name, - ival, - error)) - { - add_context_to_error (error, context); - return; - } - } - } - else - { - if (!meta_theme_define_color_constant (info->theme, - name, - value, - error)) - { - add_context_to_error (error, context); - return; - } - } - - push_state (info, STATE_CONSTANT); - } - else if (ELEMENT_IS ("frame_geometry")) - { - const char *name = NULL; - const char *parent = NULL; - const char *has_title = NULL; - const char *title_scale = NULL; - const char *rounded_top_left = NULL; - const char *rounded_top_right = NULL; - const char *rounded_bottom_left = NULL; - const char *rounded_bottom_right = NULL; - const char *hide_buttons = NULL; - gboolean has_title_val; - guint rounded_top_left_val; - guint rounded_top_right_val; - guint rounded_bottom_left_val; - guint rounded_bottom_right_val; - gboolean hide_buttons_val; - double title_scale_val; - MetaFrameLayout *parent_layout; - - if (!locate_attributes (context, element_name, attribute_names, attribute_values, - error, - "!name", &name, "parent", &parent, - "has_title", &has_title, "title_scale", &title_scale, - "rounded_top_left", &rounded_top_left, - "rounded_top_right", &rounded_top_right, - "rounded_bottom_left", &rounded_bottom_left, - "rounded_bottom_right", &rounded_bottom_right, - "hide_buttons", &hide_buttons, - NULL)) - return; - - has_title_val = TRUE; - if (has_title && !parse_boolean (has_title, &has_title_val, context, error)) - return; - - hide_buttons_val = FALSE; - if (hide_buttons && !parse_boolean (hide_buttons, &hide_buttons_val, context, error)) - return; - - rounded_top_left_val = 0; - rounded_top_right_val = 0; - rounded_bottom_left_val = 0; - rounded_bottom_right_val = 0; - - if (rounded_top_left && !parse_rounding (rounded_top_left, &rounded_top_left_val, context, info->theme, error)) - return; - if (rounded_top_right && !parse_rounding (rounded_top_right, &rounded_top_right_val, context, info->theme, error)) - return; - if (rounded_bottom_left && !parse_rounding (rounded_bottom_left, &rounded_bottom_left_val, context, info->theme, error)) - return; - if (rounded_bottom_right && !parse_rounding (rounded_bottom_right, &rounded_bottom_right_val, context, info->theme, error)) - return; - - title_scale_val = 1.0; - if (title_scale && !parse_title_scale (title_scale, &title_scale_val, context, error)) - return; - - if (meta_theme_lookup_layout (info->theme, name)) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("<%s> name \"%s\" used a second time"), - element_name, name); - return; - } - - parent_layout = NULL; - if (parent) - { - parent_layout = meta_theme_lookup_layout (info->theme, parent); - if (parent_layout == NULL) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("<%s> parent \"%s\" has not been defined"), - element_name, parent); - return; - } - } - - g_assert (info->layout == NULL); - - if (parent_layout) - info->layout = meta_frame_layout_copy (parent_layout); - else - info->layout = meta_frame_layout_new (); - - if (has_title) /* only if explicit, otherwise inherit */ - info->layout->has_title = has_title_val; - - if (META_THEME_ALLOWS (info->theme, META_THEME_HIDDEN_BUTTONS) && hide_buttons_val) - info->layout->hide_buttons = hide_buttons_val; - - if (title_scale) - info->layout->title_scale = title_scale_val; - - if (rounded_top_left) - info->layout->top_left_corner_rounded_radius = rounded_top_left_val; - - if (rounded_top_right) - info->layout->top_right_corner_rounded_radius = rounded_top_right_val; - - if (rounded_bottom_left) - info->layout->bottom_left_corner_rounded_radius = rounded_bottom_left_val; - - if (rounded_bottom_right) - info->layout->bottom_right_corner_rounded_radius = rounded_bottom_right_val; - - meta_theme_insert_layout (info->theme, name, info->layout); - - push_state (info, STATE_FRAME_GEOMETRY); - } - else if (ELEMENT_IS ("draw_ops")) - { - const char *name = NULL; - - if (!locate_attributes (context, element_name, attribute_names, attribute_values, - error, - "!name", &name, - NULL)) - return; - - if (meta_theme_lookup_draw_op_list (info->theme, name)) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("<%s> name \"%s\" used a second time"), - element_name, name); - return; - } - - g_assert (info->op_list == NULL); - info->op_list = meta_draw_op_list_new (2); - - meta_theme_insert_draw_op_list (info->theme, name, info->op_list); - - push_state (info, STATE_DRAW_OPS); - } - else if (ELEMENT_IS ("frame_style")) - { - const char *name = NULL; - const char *parent = NULL; - const char *geometry = NULL; - const char *background = NULL; - const char *alpha = NULL; - MetaFrameStyle *parent_style; - MetaFrameLayout *layout; - - if (!locate_attributes (context, element_name, attribute_names, attribute_values, - error, - "!name", &name, "parent", &parent, - "geometry", &geometry, - "background", &background, - "alpha", &alpha, - NULL)) - return; - - if (meta_theme_lookup_style (info->theme, name)) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("<%s> name \"%s\" used a second time"), - element_name, name); - return; - } - - parent_style = NULL; - if (parent) - { - parent_style = meta_theme_lookup_style (info->theme, parent); - if (parent_style == NULL) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("<%s> parent \"%s\" has not been defined"), - element_name, parent); - return; - } - } - - layout = NULL; - if (geometry) - { - layout = meta_theme_lookup_layout (info->theme, geometry); - if (layout == NULL) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("<%s> geometry \"%s\" has not been defined"), - element_name, geometry); - return; - } - } - else if (parent_style) - { - layout = parent_style->layout; - } - - if (layout == NULL) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("<%s> must specify either a geometry or a parent that has a geometry"), - element_name); - return; - } - - g_assert (info->style == NULL); - - info->style = meta_frame_style_new (parent_style); - g_assert (info->style->layout == NULL); - meta_frame_layout_ref (layout); - info->style->layout = layout; - - if (background != NULL && META_THEME_ALLOWS (info->theme, META_THEME_FRAME_BACKGROUNDS)) - { - info->style->window_background_color = meta_color_spec_new_from_string (background, error); - if (!info->style->window_background_color) - return; - - if (alpha != NULL) - { - - gboolean success; - MetaAlphaGradientSpec *alpha_vector; - - g_clear_error (error); - /* fortunately, we already have a routine to parse alpha values, - * though it produces a vector of them, which is a superset of - * what we want. - */ - success = parse_alpha (alpha, &alpha_vector, context, error); - if (!success) - return; - - /* alpha_vector->alphas must contain at least one element */ - info->style->window_background_alpha = alpha_vector->alphas[0]; - - meta_alpha_gradient_spec_free (alpha_vector); - } - } - else if (alpha != NULL) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("You must specify a background for an alpha value to be meaningful")); - return; - } - - meta_theme_insert_style (info->theme, name, info->style); - - push_state (info, STATE_FRAME_STYLE); - } - else if (ELEMENT_IS ("frame_style_set")) - { - const char *name = NULL; - const char *parent = NULL; - MetaFrameStyleSet *parent_set; - - if (!locate_attributes (context, element_name, attribute_names, attribute_values, - error, - "!name", &name, "parent", &parent, - NULL)) - return; - - if (meta_theme_lookup_style_set (info->theme, name)) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("<%s> name \"%s\" used a second time"), - element_name, name); - return; - } - - parent_set = NULL; - if (parent) - { - parent_set = meta_theme_lookup_style_set (info->theme, parent); - if (parent_set == NULL) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("<%s> parent \"%s\" has not been defined"), - element_name, parent); - return; - } - } - - g_assert (info->style_set == NULL); - - info->style_set = meta_frame_style_set_new (parent_set); - - meta_theme_insert_style_set (info->theme, name, info->style_set); - - push_state (info, STATE_FRAME_STYLE_SET); - } - else if (ELEMENT_IS ("window")) - { - const char *type_name = NULL; - const char *style_set_name = NULL; - MetaFrameStyleSet *style_set; - MetaFrameType type; - - if (!locate_attributes (context, element_name, attribute_names, attribute_values, - error, - "!type", &type_name, "!style_set", &style_set_name, - NULL)) - return; - - type = meta_frame_type_from_string (type_name); - - if (type == META_FRAME_TYPE_LAST || - (type == META_FRAME_TYPE_ATTACHED && peek_required_version (info) < 3002)) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Unknown type \"%s\" on <%s> element"), - type_name, element_name); - return; - } - - style_set = meta_theme_lookup_style_set (info->theme, - style_set_name); - - if (style_set == NULL) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Unknown style_set \"%s\" on <%s> element"), - style_set_name, element_name); - return; - } - - if (info->theme->style_sets_by_type[type] != NULL) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Window type \"%s\" has already been assigned a style set"), - type_name); - return; - } - - meta_frame_style_set_ref (style_set); - info->theme->style_sets_by_type[type] = style_set; - - push_state (info, STATE_WINDOW); - } - else if (ELEMENT_IS ("menu_icon")) - { - /* Not supported any more, but we have to parse it if they include it, - * for backwards compatibility. - */ - g_assert (info->op_list == NULL); - - push_state (info, STATE_MENU_ICON); - } - else if (ELEMENT_IS ("fallback")) - { - /* Not supported any more, but we have to parse it if they include it, - * for backwards compatibility. - */ - push_state (info, STATE_FALLBACK); - } - else if (ELEMENT_IS ("shadow")) - { - /* ubuntu specific, workaround for light-themes: silently ignore shadow tag. - */ - push_state (info, UBUNTU_STATE_IGNORE); - } - else if (ELEMENT_IS ("padding")) - { - /* ubuntu specific, workaround for light-themes: silently ignore padding tag. - */ - push_state (info, UBUNTU_STATE_IGNORE); - } - else - { - set_error (error, context, - G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Element <%s> is not allowed below <%s>"), - element_name, "metacity_theme"); - } -} - -static void -parse_info_element (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - ParseInfo *info, - GError **error) -{ - g_return_if_fail (peek_state (info) == STATE_INFO); - - if (ELEMENT_IS ("name")) - { - if (!check_no_attributes (context, element_name, - attribute_names, attribute_values, - error)) - return; - - push_state (info, STATE_NAME); - } - else if (ELEMENT_IS ("author")) - { - if (!check_no_attributes (context, element_name, - attribute_names, attribute_values, - error)) - return; - - push_state (info, STATE_AUTHOR); - } - else if (ELEMENT_IS ("copyright")) - { - if (!check_no_attributes (context, element_name, - attribute_names, attribute_values, - error)) - return; - - push_state (info, STATE_COPYRIGHT); - } - else if (ELEMENT_IS ("description")) - { - if (!check_no_attributes (context, element_name, - attribute_names, attribute_values, - error)) - return; - - push_state (info, STATE_DESCRIPTION); - } - else if (ELEMENT_IS ("date")) - { - if (!check_no_attributes (context, element_name, - attribute_names, attribute_values, - error)) - return; - - push_state (info, STATE_DATE); - } - else - { - set_error (error, context, - G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Element <%s> is not allowed below <%s>"), - element_name, "info"); - } -} - -static void -parse_distance (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - ParseInfo *info, - GError **error) -{ - const char *name; - const char *value; - int val; - - if (!locate_attributes (context, element_name, attribute_names, attribute_values, - error, - "!name", &name, "!value", &value, - NULL)) - return; - - val = 0; - if (!parse_positive_integer (value, &val, context, info->theme, error)) - return; - - g_assert (val >= 0); /* yeah, "non-negative" not "positive" get over it */ - g_assert (info->layout); - - if (strcmp (name, "left_width") == 0) - info->layout->left_width = val; - else if (strcmp (name, "right_width") == 0) - info->layout->right_width = val; - else if (strcmp (name, "bottom_height") == 0) - info->layout->bottom_height = val; - else if (strcmp (name, "title_vertical_pad") == 0) - info->layout->title_vertical_pad = val; - else if (strcmp (name, "right_titlebar_edge") == 0) - info->layout->right_titlebar_edge = val; - else if (strcmp (name, "left_titlebar_edge") == 0) - info->layout->left_titlebar_edge = val; - else if (strcmp (name, "button_width") == 0) - { - info->layout->button_width = val; - - if (!(info->layout->button_sizing == META_BUTTON_SIZING_LAST || - info->layout->button_sizing == META_BUTTON_SIZING_FIXED)) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" for buttons")); - return; - } - - info->layout->button_sizing = META_BUTTON_SIZING_FIXED; - } - else if (strcmp (name, "button_height") == 0) - { - info->layout->button_height = val; - - if (!(info->layout->button_sizing == META_BUTTON_SIZING_LAST || - info->layout->button_sizing == META_BUTTON_SIZING_FIXED)) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" for buttons")); - return; - } - - info->layout->button_sizing = META_BUTTON_SIZING_FIXED; - } - else - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Distance \"%s\" is unknown"), name); - return; - } -} - -static void -parse_aspect_ratio (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - ParseInfo *info, - GError **error) -{ - const char *name; - const char *value; - double val; - - if (!locate_attributes (context, element_name, attribute_names, attribute_values, - error, - "!name", &name, "!value", &value, - NULL)) - return; - - val = 0; - if (!parse_double (value, &val, context, error)) - return; - - g_assert (info->layout); - - if (strcmp (name, "button") == 0) - { - info->layout->button_aspect = val; - - if (info->layout->button_sizing != META_BUTTON_SIZING_LAST) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" for buttons")); - return; - } - - info->layout->button_sizing = META_BUTTON_SIZING_ASPECT; - } - else - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Aspect ratio \"%s\" is unknown"), name); - return; - } -} - -static void -parse_border (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - ParseInfo *info, - GError **error) -{ - const char *name; - const char *top; - const char *bottom; - const char *left; - const char *right; - int top_val; - int bottom_val; - int left_val; - int right_val; - GtkBorder *border; - - if (!locate_attributes (context, element_name, attribute_names, attribute_values, - error, - "!name", &name, - "!top", &top, - "!bottom", &bottom, - "!left", &left, - "!right", &right, - NULL)) - return; - - top_val = 0; - if (!parse_positive_integer (top, &top_val, context, info->theme, error)) - return; - - bottom_val = 0; - if (!parse_positive_integer (bottom, &bottom_val, context, info->theme, error)) - return; - - left_val = 0; - if (!parse_positive_integer (left, &left_val, context, info->theme, error)) - return; - - right_val = 0; - if (!parse_positive_integer (right, &right_val, context, info->theme, error)) - return; - - g_assert (info->layout); - - border = NULL; - - if (strcmp (name, "title_border") == 0) - border = &info->layout->title_border; - else if (strcmp (name, "button_border") == 0) - border = &info->layout->button_border; - - if (border == NULL) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Border \"%s\" is unknown"), name); - return; - } - - border->top = top_val; - border->bottom = bottom_val; - border->left = left_val; - border->right = right_val; -} - -static void -parse_geometry_element (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - ParseInfo *info, - GError **error) -{ - g_return_if_fail (peek_state (info) == STATE_FRAME_GEOMETRY); - - if (ELEMENT_IS ("distance")) - { - parse_distance (context, element_name, - attribute_names, attribute_values, - info, error); - push_state (info, STATE_DISTANCE); - } - else if (ELEMENT_IS ("border")) - { - parse_border (context, element_name, - attribute_names, attribute_values, - info, error); - push_state (info, STATE_BORDER); - } - else if (ELEMENT_IS ("aspect_ratio")) - { - parse_aspect_ratio (context, element_name, - attribute_names, attribute_values, - info, error); - - push_state (info, STATE_ASPECT_RATIO); - } - else - { - set_error (error, context, - G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Element <%s> is not allowed below <%s>"), - element_name, "frame_geometry"); - } -} - -#if 0 -static gboolean -check_expression (PosToken *tokens, - int n_tokens, - gboolean has_object, - MetaTheme *theme, - GMarkupParseContext *context, - GError **error) -{ - MetaPositionExprEnv env; - int x, y; - - /* We set it all to 0 to try and catch divide-by-zero screwups. - * it's possible we should instead guarantee that widths and heights - * are at least 1. - */ - - env.rect = meta_rect (0, 0, 0, 0); - if (has_object) - { - env.object_width = 0; - env.object_height = 0; - } - else - { - env.object_width = -1; - env.object_height = -1; - } - - env.left_width = 0; - env.right_width = 0; - env.top_height = 0; - env.bottom_height = 0; - env.title_width = 0; - env.title_height = 0; - - env.icon_width = 0; - env.icon_height = 0; - env.mini_icon_width = 0; - env.mini_icon_height = 0; - - env.theme = theme; - - if (!meta_parse_position_expression (tokens, n_tokens, - &env, - &x, &y, - error)) - { - add_context_to_error (error, context); - return FALSE; - } - - return TRUE; -} -#endif - -static void -parse_draw_op_element (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - ParseInfo *info, - GError **error) -{ - g_return_if_fail (peek_state (info) == STATE_DRAW_OPS); - - if (ELEMENT_IS ("line")) - { - MetaDrawOp *op; - const char *color; - const char *x1; - const char *y1; - const char *x2; - const char *y2; - const char *dash_on_length; - const char *dash_off_length; - const char *width; - MetaColorSpec *color_spec; - int dash_on_val; - int dash_off_val; - int width_val; - - if (!locate_attributes (context, element_name, attribute_names, attribute_values, - error, - "!color", &color, - "!x1", &x1, "!y1", &y1, - "!x2", &x2, "!y2", &y2, - "dash_on_length", &dash_on_length, - "dash_off_length", &dash_off_length, - "width", &width, - NULL)) - return; - -#if 0 - if (!check_expression (x1, FALSE, info->theme, context, error)) - return; - - if (!check_expression (y1, FALSE, info->theme, context, error)) - return; - - if (!check_expression (x2, FALSE, info->theme, context, error)) - return; - - if (!check_expression (y2, FALSE, info->theme, context, error)) - return; -#endif - - dash_on_val = 0; - if (dash_on_length && - !parse_positive_integer (dash_on_length, &dash_on_val, context, info->theme, error)) - return; - - dash_off_val = 0; - if (dash_off_length && - !parse_positive_integer (dash_off_length, &dash_off_val, context, info->theme, error)) - return; - - width_val = 0; - if (width && - !parse_positive_integer (width, &width_val, context, info->theme, error)) - return; - - /* Check last so we don't have to free it when other - * stuff fails - */ - color_spec = parse_color (info->theme, color, error); - if (color_spec == NULL) - { - add_context_to_error (error, context); - return; - } - - op = meta_draw_op_new (META_DRAW_LINE); - - op->data.line.color_spec = color_spec; - - op->data.line.x1 = meta_draw_spec_new (info->theme, x1, NULL); - op->data.line.y1 = meta_draw_spec_new (info->theme, y1, NULL); - - if (strcmp(x1, x2)==0) - op->data.line.x2 = NULL; - else - op->data.line.x2 = meta_draw_spec_new (info->theme, x2, NULL); - - if (strcmp(y1, y2)==0) - op->data.line.y2 = NULL; - else - op->data.line.y2 = meta_draw_spec_new (info->theme, y2, NULL); - - op->data.line.width = width_val; - op->data.line.dash_on_length = dash_on_val; - op->data.line.dash_off_length = dash_off_val; - - g_assert (info->op_list); - - meta_draw_op_list_append (info->op_list, op); - - push_state (info, STATE_LINE); - } - else if (ELEMENT_IS ("rectangle")) - { - MetaDrawOp *op; - const char *color; - const char *x; - const char *y; - const char *width; - const char *height; - const char *filled; - gboolean filled_val; - MetaColorSpec *color_spec; - - if (!locate_attributes (context, element_name, attribute_names, attribute_values, - error, - "!color", &color, - "!x", &x, "!y", &y, - "!width", &width, "!height", &height, - "filled", &filled, - NULL)) - return; - -#if 0 - if (!check_expression (x, FALSE, info->theme, context, error)) - return; - - if (!check_expression (y, FALSE, info->theme, context, error)) - return; - - if (!check_expression (width, FALSE, info->theme, context, error)) - return; - - if (!check_expression (height, FALSE, info->theme, context, error)) - return; -#endif - - filled_val = FALSE; - if (filled && !parse_boolean (filled, &filled_val, context, error)) - return; - - /* Check last so we don't have to free it when other - * stuff fails - */ - color_spec = parse_color (info->theme, color, error); - if (color_spec == NULL) - { - add_context_to_error (error, context); - return; - } - - op = meta_draw_op_new (META_DRAW_RECTANGLE); - - op->data.rectangle.color_spec = color_spec; - op->data.rectangle.x = meta_draw_spec_new (info->theme, x, NULL); - op->data.rectangle.y = meta_draw_spec_new (info->theme, y, NULL); - op->data.rectangle.width = meta_draw_spec_new (info->theme, width, NULL); - op->data.rectangle.height = meta_draw_spec_new (info->theme, - height, NULL); - - op->data.rectangle.filled = filled_val; - - g_assert (info->op_list); - - meta_draw_op_list_append (info->op_list, op); - - push_state (info, STATE_RECTANGLE); - } - else if (ELEMENT_IS ("arc")) - { - MetaDrawOp *op; - const char *color; - const char *x; - const char *y; - const char *width; - const char *height; - const char *filled; - const char *start_angle; - const char *extent_angle; - const char *from; - const char *to; - gboolean filled_val; - double start_angle_val; - double extent_angle_val; - MetaColorSpec *color_spec; - - if (!locate_attributes (context, element_name, attribute_names, attribute_values, - error, - "!color", &color, - "!x", &x, "!y", &y, - "!width", &width, "!height", &height, - "filled", &filled, - "start_angle", &start_angle, - "extent_angle", &extent_angle, - "from", &from, - "to", &to, - NULL)) - return; - - if (META_THEME_ALLOWS (info->theme, META_THEME_DEGREES_IN_ARCS) ) - { - if (start_angle == NULL && from == NULL) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("No \"start_angle\" or \"from\" attribute on element <%s>"), element_name); - return; - } - - if (extent_angle == NULL && to == NULL) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("No \"extent_angle\" or \"to\" attribute on element <%s>"), element_name); - return; - } - } - else - { - if (start_angle == NULL) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - ATTRIBUTE_NOT_FOUND, "start_angle", element_name); - return; - } - - if (extent_angle == NULL) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - ATTRIBUTE_NOT_FOUND, "extent_angle", element_name); - return; - } - } - -#if 0 - if (!check_expression (x, FALSE, info->theme, context, error)) - return; - - if (!check_expression (y, FALSE, info->theme, context, error)) - return; - - if (!check_expression (width, FALSE, info->theme, context, error)) - return; - - if (!check_expression (height, FALSE, info->theme, context, error)) - return; -#endif - - if (start_angle == NULL) - { - if (!parse_angle (from, &start_angle_val, context, error)) - return; - - start_angle_val = (180-start_angle_val)/360.0; - } - else - { - if (!parse_angle (start_angle, &start_angle_val, context, error)) - return; - } - - if (extent_angle == NULL) - { - if (!parse_angle (to, &extent_angle_val, context, error)) - return; - - extent_angle_val = ((180-extent_angle_val)/360.0) - start_angle_val; - } - else - { - if (!parse_angle (extent_angle, &extent_angle_val, context, error)) - return; - } - - filled_val = FALSE; - if (filled && !parse_boolean (filled, &filled_val, context, error)) - return; - - /* Check last so we don't have to free it when other - * stuff fails - */ - color_spec = parse_color (info->theme, color, error); - if (color_spec == NULL) - { - add_context_to_error (error, context); - return; - } - - op = meta_draw_op_new (META_DRAW_ARC); - - op->data.arc.color_spec = color_spec; - - op->data.arc.x = meta_draw_spec_new (info->theme, x, NULL); - op->data.arc.y = meta_draw_spec_new (info->theme, y, NULL); - op->data.arc.width = meta_draw_spec_new (info->theme, width, NULL); - op->data.arc.height = meta_draw_spec_new (info->theme, height, NULL); - - op->data.arc.filled = filled_val; - op->data.arc.start_angle = start_angle_val; - op->data.arc.extent_angle = extent_angle_val; - - g_assert (info->op_list); - - meta_draw_op_list_append (info->op_list, op); - - push_state (info, STATE_ARC); - } - else if (ELEMENT_IS ("clip")) - { - MetaDrawOp *op; - const char *x; - const char *y; - const char *width; - const char *height; - - if (!locate_attributes (context, element_name, attribute_names, attribute_values, - error, - "!x", &x, "!y", &y, - "!width", &width, "!height", &height, - NULL)) - return; - -#if 0 - if (!check_expression (x, FALSE, info->theme, context, error)) - return; - - if (!check_expression (y, FALSE, info->theme, context, error)) - return; - - if (!check_expression (width, FALSE, info->theme, context, error)) - return; - - if (!check_expression (height, FALSE, info->theme, context, error)) - return; -#endif - op = meta_draw_op_new (META_DRAW_CLIP); - - op->data.clip.x = meta_draw_spec_new (info->theme, x, NULL); - op->data.clip.y = meta_draw_spec_new (info->theme, y, NULL); - op->data.clip.width = meta_draw_spec_new (info->theme, width, NULL); - op->data.clip.height = meta_draw_spec_new (info->theme, height, NULL); - - g_assert (info->op_list); - - meta_draw_op_list_append (info->op_list, op); - - push_state (info, STATE_CLIP); - } - else if (ELEMENT_IS ("tint")) - { - MetaDrawOp *op; - const char *color; - const char *x; - const char *y; - const char *width; - const char *height; - const char *alpha; - MetaAlphaGradientSpec *alpha_spec; - MetaColorSpec *color_spec; - - if (!locate_attributes (context, element_name, attribute_names, attribute_values, - error, - "!color", &color, - "!x", &x, "!y", &y, - "!width", &width, "!height", &height, - "!alpha", &alpha, - NULL)) - return; - -#if 0 - if (!check_expression (x, FALSE, info->theme, context, error)) - return; - - if (!check_expression (y, FALSE, info->theme, context, error)) - return; - - if (!check_expression (width, FALSE, info->theme, context, error)) - return; - - if (!check_expression (height, FALSE, info->theme, context, error)) - return; -#endif - alpha_spec = NULL; - if (!parse_alpha (alpha, &alpha_spec, context, error)) - return; - - /* Check last so we don't have to free it when other - * stuff fails - */ - color_spec = parse_color (info->theme, color, error); - if (color_spec == NULL) - { - if (alpha_spec) - meta_alpha_gradient_spec_free (alpha_spec); - - add_context_to_error (error, context); - return; - } - - op = meta_draw_op_new (META_DRAW_TINT); - - op->data.tint.color_spec = color_spec; - op->data.tint.alpha_spec = alpha_spec; - - op->data.tint.x = meta_draw_spec_new (info->theme, x, NULL); - op->data.tint.y = meta_draw_spec_new (info->theme, y, NULL); - op->data.tint.width = meta_draw_spec_new (info->theme, width, NULL); - op->data.tint.height = meta_draw_spec_new (info->theme, height, NULL); - - g_assert (info->op_list); - - meta_draw_op_list_append (info->op_list, op); - - push_state (info, STATE_TINT); - } - else if (ELEMENT_IS ("gradient")) - { - const char *x; - const char *y; - const char *width; - const char *height; - const char *type; - const char *alpha; - MetaAlphaGradientSpec *alpha_spec; - MetaGradientType type_val; - - if (!locate_attributes (context, element_name, attribute_names, attribute_values, - error, - "!type", &type, - "!x", &x, "!y", &y, - "!width", &width, "!height", &height, - "alpha", &alpha, - NULL)) - return; - -#if 0 - if (!check_expression (x, FALSE, info->theme, context, error)) - return; - - if (!check_expression (y, FALSE, info->theme, context, error)) - return; - - if (!check_expression (width, FALSE, info->theme, context, error)) - return; - - if (!check_expression (height, FALSE, info->theme, context, error)) - return; -#endif - - type_val = meta_gradient_type_from_string (type); - if (type_val == META_GRADIENT_LAST) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Did not understand value \"%s\" for type of gradient"), - type); - return; - } - - alpha_spec = NULL; - if (alpha && !parse_alpha (alpha, &alpha_spec, context, error)) - return; - - g_assert (info->op == NULL); - info->op = meta_draw_op_new (META_DRAW_GRADIENT); - - info->op->data.gradient.x = meta_draw_spec_new (info->theme, x, NULL); - info->op->data.gradient.y = meta_draw_spec_new (info->theme, y, NULL); - info->op->data.gradient.width = meta_draw_spec_new (info->theme, - width, NULL); - info->op->data.gradient.height = meta_draw_spec_new (info->theme, - height, NULL); - - info->op->data.gradient.gradient_spec = meta_gradient_spec_new (type_val); - - info->op->data.gradient.alpha_spec = alpha_spec; - - push_state (info, STATE_GRADIENT); - - /* op gets appended on close tag */ - } - else if (ELEMENT_IS ("image")) - { - MetaDrawOp *op; - const char *filename; - const char *x; - const char *y; - const char *width; - const char *height; - const char *alpha; - const char *colorize; - const char *fill_type; - MetaAlphaGradientSpec *alpha_spec; - GdkPixbuf *pixbuf; - MetaColorSpec *colorize_spec = NULL; - MetaImageFillType fill_type_val; - int h, w, c; - int pixbuf_width, pixbuf_height, pixbuf_n_channels, pixbuf_rowstride; - guchar *pixbuf_pixels; - - if (!locate_attributes (context, element_name, attribute_names, attribute_values, - error, - "!x", &x, "!y", &y, - "!width", &width, "!height", &height, - "alpha", &alpha, "!filename", &filename, - "colorize", &colorize, - "fill_type", &fill_type, - NULL)) - return; - -#if 0 - if (!check_expression (x, TRUE, info->theme, context, error)) - return; - - if (!check_expression (y, TRUE, info->theme, context, error)) - return; - - if (!check_expression (width, TRUE, info->theme, context, error)) - return; - - if (!check_expression (height, TRUE, info->theme, context, error)) - return; -#endif - fill_type_val = META_IMAGE_FILL_SCALE; - if (fill_type) - { - fill_type_val = meta_image_fill_type_from_string (fill_type); - - if (((int) fill_type_val) == -1) - { - set_error (error, context, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("Did not understand fill type \"%s\" for <%s> element"), - fill_type, element_name); - } - } - - /* Check last so we don't have to free it when other - * stuff fails. - * - */ - pixbuf = meta_theme_load_image (info->theme, filename, info->theme->scale, error); - - if (pixbuf == NULL) - { - add_context_to_error (error, context); - return; - } - - if (colorize) - { - colorize_spec = parse_color (info->theme, colorize, error); - - if (colorize_spec == NULL) - { - add_context_to_error (error, context); - g_object_unref (G_OBJECT (pixbuf)); - return; - } - } - - alpha_spec = NULL; - if (alpha && !parse_alpha (alpha, &alpha_spec, context, error)) - { - g_object_unref (G_OBJECT (pixbuf)); - return; - } - - op = meta_draw_op_new (META_DRAW_IMAGE); - - op->data.image.pixbuf = pixbuf; - op->data.image.colorize_spec = colorize_spec; - - op->data.image.x = meta_draw_spec_new (info->theme, x, NULL); - op->data.image.y = meta_draw_spec_new (info->theme, y, NULL); - op->data.image.width = meta_draw_spec_new (info->theme, width, NULL); - op->data.image.height = meta_draw_spec_new (info->theme, height, NULL); - - op->data.image.alpha_spec = alpha_spec; - op->data.image.fill_type = fill_type_val; - - /* Check for vertical & horizontal stripes */ - pixbuf_n_channels = gdk_pixbuf_get_n_channels(pixbuf); - pixbuf_width = gdk_pixbuf_get_width(pixbuf); - pixbuf_height = gdk_pixbuf_get_height(pixbuf); - pixbuf_rowstride = gdk_pixbuf_get_rowstride(pixbuf); - pixbuf_pixels = gdk_pixbuf_get_pixels(pixbuf); - - /* Check for horizontal stripes */ - for (h = 0; h < pixbuf_height; h++) - { - for (w = 1; w < pixbuf_width; w++) - { - for (c = 0; c < pixbuf_n_channels; c++) - { - if (pixbuf_pixels[(h * pixbuf_rowstride) + c] != - pixbuf_pixels[(h * pixbuf_rowstride) + w + c]) - break; - } - if (c < pixbuf_n_channels) - break; - } - if (w < pixbuf_width) - break; - } - - if (h >= pixbuf_height) - { - op->data.image.horizontal_stripes = TRUE; - } - else - { - op->data.image.horizontal_stripes = FALSE; - } - - /* Check for vertical stripes */ - for (w = 0; w < pixbuf_width; w++) - { - for (h = 1; h < pixbuf_height; h++) - { - for (c = 0; c < pixbuf_n_channels; c++) - { - if (pixbuf_pixels[w + c] != - pixbuf_pixels[(h * pixbuf_rowstride) + w + c]) - break; - } - if (c < pixbuf_n_channels) - break; - } - if (h < pixbuf_height) - break; - } - - if (w >= pixbuf_width) - { - op->data.image.vertical_stripes = TRUE; - } - else - { - op->data.image.vertical_stripes = FALSE; - } - - g_assert (info->op_list); - - meta_draw_op_list_append (info->op_list, op); - - push_state (info, STATE_IMAGE); - } - else if (ELEMENT_IS ("gtk_arrow")) - { - MetaDrawOp *op; - const char *state; - const char *shadow; - const char *arrow; - const char *x; - const char *y; - const char *width; - const char *height; - const char *filled; - gboolean filled_val; - GtkStateFlags state_val; - GtkShadowType shadow_val; - GtkArrowType arrow_val; - - if (!locate_attributes (context, element_name, attribute_names, attribute_values, - error, - "!state", &state, - "!shadow", &shadow, - "!arrow", &arrow, - "!x", &x, "!y", &y, - "!width", &width, "!height", &height, - "filled", &filled, - NULL)) - return; - -#if 0 - if (!check_expression (x, FALSE, info->theme, context, error)) - return; - - if (!check_expression (y, FALSE, info->theme, context, error)) - return; - - if (!check_expression (width, FALSE, info->theme, context, error)) - return; - - if (!check_expression (height, FALSE, info->theme, context, error)) - return; -#endif - filled_val = TRUE; - if (filled && !parse_boolean (filled, &filled_val, context, error)) - return; - - state_val = meta_gtk_state_from_string (state); - if (((int) state_val) == -1) - { - set_error (error, context, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("Did not understand state \"%s\" for <%s> element"), - state, element_name); - return; - } - - shadow_val = meta_gtk_shadow_from_string (shadow); - if (((int) shadow_val) == -1) - { - set_error (error, context, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("Did not understand shadow \"%s\" for <%s> element"), - shadow, element_name); - return; - } - - arrow_val = meta_gtk_arrow_from_string (arrow); - if (((int) arrow_val) == -1) - { - set_error (error, context, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("Did not understand arrow \"%s\" for <%s> element"), - arrow, element_name); - return; - } - - op = meta_draw_op_new (META_DRAW_GTK_ARROW); - - op->data.gtk_arrow.x = meta_draw_spec_new (info->theme, x, NULL); - op->data.gtk_arrow.y = meta_draw_spec_new (info->theme, y, NULL); - op->data.gtk_arrow.width = meta_draw_spec_new (info->theme, width, NULL); - op->data.gtk_arrow.height = meta_draw_spec_new (info->theme, - height, NULL); - - op->data.gtk_arrow.filled = filled_val; - op->data.gtk_arrow.state = state_val; - op->data.gtk_arrow.shadow = shadow_val; - op->data.gtk_arrow.arrow = arrow_val; - - g_assert (info->op_list); - - meta_draw_op_list_append (info->op_list, op); - - push_state (info, STATE_GTK_ARROW); - } - else if (ELEMENT_IS ("gtk_box")) - { - MetaDrawOp *op; - const char *state; - const char *shadow; - const char *x; - const char *y; - const char *width; - const char *height; - GtkStateFlags state_val; - GtkShadowType shadow_val; - - if (!locate_attributes (context, element_name, attribute_names, attribute_values, - error, - "!state", &state, - "!shadow", &shadow, - "!x", &x, "!y", &y, - "!width", &width, "!height", &height, - NULL)) - return; - -#if 0 - if (!check_expression (x, FALSE, info->theme, context, error)) - return; - - if (!check_expression (y, FALSE, info->theme, context, error)) - return; - - if (!check_expression (width, FALSE, info->theme, context, error)) - return; - - if (!check_expression (height, FALSE, info->theme, context, error)) - return; -#endif - state_val = meta_gtk_state_from_string (state); - if (((int) state_val) == -1) - { - set_error (error, context, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("Did not understand state \"%s\" for <%s> element"), - state, element_name); - return; - } - - shadow_val = meta_gtk_shadow_from_string (shadow); - if (((int) shadow_val) == -1) - { - set_error (error, context, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("Did not understand shadow \"%s\" for <%s> element"), - shadow, element_name); - return; - } - - op = meta_draw_op_new (META_DRAW_GTK_BOX); - - op->data.gtk_box.x = meta_draw_spec_new (info->theme, x, NULL); - op->data.gtk_box.y = meta_draw_spec_new (info->theme, y, NULL); - op->data.gtk_box.width = meta_draw_spec_new (info->theme, width, NULL); - op->data.gtk_box.height = meta_draw_spec_new (info->theme, height, NULL); - - op->data.gtk_box.state = state_val; - op->data.gtk_box.shadow = shadow_val; - - g_assert (info->op_list); - - meta_draw_op_list_append (info->op_list, op); - - push_state (info, STATE_GTK_BOX); - } - else if (ELEMENT_IS ("gtk_vline")) - { - MetaDrawOp *op; - const char *state; - const char *x; - const char *y1; - const char *y2; - GtkStateFlags state_val; - - if (!locate_attributes (context, element_name, attribute_names, attribute_values, - error, - "!state", &state, - "!x", &x, "!y1", &y1, "!y2", &y2, - NULL)) - return; - -#if 0 - if (!check_expression (x, FALSE, info->theme, context, error)) - return; - - if (!check_expression (y1, FALSE, info->theme, context, error)) - return; - - if (!check_expression (y2, FALSE, info->theme, context, error)) - return; -#endif - - state_val = meta_gtk_state_from_string (state); - if (((int) state_val) == -1) - { - set_error (error, context, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("Did not understand state \"%s\" for <%s> element"), - state, element_name); - return; - } - - op = meta_draw_op_new (META_DRAW_GTK_VLINE); - - op->data.gtk_vline.x = meta_draw_spec_new (info->theme, x, NULL); - op->data.gtk_vline.y1 = meta_draw_spec_new (info->theme, y1, NULL); - op->data.gtk_vline.y2 = meta_draw_spec_new (info->theme, y2, NULL); - - op->data.gtk_vline.state = state_val; - - g_assert (info->op_list); - - meta_draw_op_list_append (info->op_list, op); - - push_state (info, STATE_GTK_VLINE); - } - else if (ELEMENT_IS ("icon")) - { - MetaDrawOp *op; - const char *x; - const char *y; - const char *width; - const char *height; - const char *alpha; - const char *fill_type; - MetaAlphaGradientSpec *alpha_spec; - MetaImageFillType fill_type_val; - - if (!locate_attributes (context, element_name, attribute_names, attribute_values, - error, - "!x", &x, "!y", &y, - "!width", &width, "!height", &height, - "alpha", &alpha, - "fill_type", &fill_type, - NULL)) - return; - -#if 0 - if (!check_expression (x, FALSE, info->theme, context, error)) - return; - - if (!check_expression (y, FALSE, info->theme, context, error)) - return; - - if (!check_expression (width, FALSE, info->theme, context, error)) - return; - - if (!check_expression (height, FALSE, info->theme, context, error)) - return; -#endif - fill_type_val = META_IMAGE_FILL_SCALE; - if (fill_type) - { - fill_type_val = meta_image_fill_type_from_string (fill_type); - - if (((int) fill_type_val) == -1) - { - set_error (error, context, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("Did not understand fill type \"%s\" for <%s> element"), - fill_type, element_name); - } - } - - alpha_spec = NULL; - if (alpha && !parse_alpha (alpha, &alpha_spec, context, error)) - return; - - op = meta_draw_op_new (META_DRAW_ICON); - - op->data.icon.x = meta_draw_spec_new (info->theme, x, NULL); - op->data.icon.y = meta_draw_spec_new (info->theme, y, NULL); - op->data.icon.width = meta_draw_spec_new (info->theme, width, NULL); - op->data.icon.height = meta_draw_spec_new (info->theme, height, NULL); - - op->data.icon.alpha_spec = alpha_spec; - op->data.icon.fill_type = fill_type_val; - - g_assert (info->op_list); - - meta_draw_op_list_append (info->op_list, op); - - push_state (info, STATE_ICON); - } - else if (ELEMENT_IS ("title")) - { - MetaDrawOp *op; - const char *color; - const char *x; - const char *y; - const char *ellipsize_width; - MetaColorSpec *color_spec; - - if (!locate_attributes (context, element_name, attribute_names, attribute_values, - error, - "!color", &color, - "!x", &x, "!y", &y, - "ellipsize_width", &ellipsize_width, - NULL)) - return; - -#if 0 - if (!check_expression (x, FALSE, info->theme, context, error)) - return; - - if (!check_expression (y, FALSE, info->theme, context, error)) - return; - - if (!check_expression (ellipsize_width, FALSE, info->theme, context, error)) - return; -#endif - - if (ellipsize_width && peek_required_version (info) < 3001) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - ATTRIBUTE_NOT_FOUND, "ellipsize_width", element_name); - return; - } - - /* Check last so we don't have to free it when other - * stuff fails - */ - color_spec = parse_color (info->theme, color, error); - if (color_spec == NULL) - { - add_context_to_error (error, context); - return; - } - - op = meta_draw_op_new (META_DRAW_TITLE); - - op->data.title.color_spec = color_spec; - - op->data.title.x = meta_draw_spec_new (info->theme, x, NULL); - op->data.title.y = meta_draw_spec_new (info->theme, y, NULL); - if (ellipsize_width) - op->data.title.ellipsize_width = meta_draw_spec_new (info->theme, ellipsize_width, NULL); - - g_assert (info->op_list); - - meta_draw_op_list_append (info->op_list, op); - - push_state (info, STATE_TITLE); - } - else if (ELEMENT_IS ("include")) - { - MetaDrawOp *op; - const char *name; - const char *x; - const char *y; - const char *width; - const char *height; - MetaDrawOpList *op_list; - - if (!locate_attributes (context, element_name, attribute_names, attribute_values, - error, - "x", &x, "y", &y, - "width", &width, "height", &height, - "!name", &name, - NULL)) - return; - - /* x/y/width/height default to 0,0,width,height - should - * probably do this for all the draw ops - */ -#if 0 - if (x && !check_expression (x, FALSE, info->theme, context, error)) - return; - - if (y && !check_expression (y, FALSE, info->theme, context, error)) - return; - - if (width && !check_expression (width, FALSE, info->theme, context, error)) - return; - - if (height && !check_expression (height, FALSE, info->theme, context, error)) - return; -#endif - - op_list = meta_theme_lookup_draw_op_list (info->theme, - name); - if (op_list == NULL) - { - set_error (error, context, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("No <draw_ops> called \"%s\" has been defined"), - name); - return; - } - - g_assert (info->op_list); - - if (op_list == info->op_list || - meta_draw_op_list_contains (op_list, info->op_list)) - { - set_error (error, context, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("Including draw_ops \"%s\" here would create a circular reference"), - name); - return; - } - - op = meta_draw_op_new (META_DRAW_OP_LIST); - - meta_draw_op_list_ref (op_list); - op->data.op_list.op_list = op_list; - - op->data.op_list.x = meta_draw_spec_new (info->theme, x ? x : "0", NULL); - op->data.op_list.y = meta_draw_spec_new (info->theme, y ? y : "0", NULL); - op->data.op_list.width = meta_draw_spec_new (info->theme, - width ? width : "width", - NULL); - op->data.op_list.height = meta_draw_spec_new (info->theme, - height ? height : "height", - NULL); - - meta_draw_op_list_append (info->op_list, op); - - push_state (info, STATE_INCLUDE); - } - else if (ELEMENT_IS ("tile")) - { - MetaDrawOp *op; - const char *name; - const char *x; - const char *y; - const char *width; - const char *height; - const char *tile_xoffset; - const char *tile_yoffset; - const char *tile_width; - const char *tile_height; - MetaDrawOpList *op_list; - - if (!locate_attributes (context, element_name, attribute_names, attribute_values, - error, - "x", &x, "y", &y, - "width", &width, "height", &height, - "!name", &name, - "tile_xoffset", &tile_xoffset, - "tile_yoffset", &tile_yoffset, - "!tile_width", &tile_width, - "!tile_height", &tile_height, - NULL)) - return; - - /* These default to 0 */ -#if 0 - if (tile_xoffset && !check_expression (tile_xoffset, FALSE, info->theme, context, error)) - return; - - if (tile_yoffset && !check_expression (tile_yoffset, FALSE, info->theme, context, error)) - return; - - /* x/y/width/height default to 0,0,width,height - should - * probably do this for all the draw ops - */ - if (x && !check_expression (x, FALSE, info->theme, context, error)) - return; - - if (y && !check_expression (y, FALSE, info->theme, context, error)) - return; - - if (width && !check_expression (width, FALSE, info->theme, context, error)) - return; - - if (height && !check_expression (height, FALSE, info->theme, context, error)) - return; - - if (!check_expression (tile_width, FALSE, info->theme, context, error)) - return; - - if (!check_expression (tile_height, FALSE, info->theme, context, error)) - return; -#endif - op_list = meta_theme_lookup_draw_op_list (info->theme, - name); - if (op_list == NULL) - { - set_error (error, context, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("No <draw_ops> called \"%s\" has been defined"), - name); - return; - } - - g_assert (info->op_list); - - if (op_list == info->op_list || - meta_draw_op_list_contains (op_list, info->op_list)) - { - set_error (error, context, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("Including draw_ops \"%s\" here would create a circular reference"), - name); - return; - } - - op = meta_draw_op_new (META_DRAW_TILE); - - meta_draw_op_list_ref (op_list); - - op->data.tile.x = meta_draw_spec_new (info->theme, x ? x : "0", NULL); - op->data.tile.y = meta_draw_spec_new (info->theme, y ? y : "0", NULL); - op->data.tile.width = meta_draw_spec_new (info->theme, - width ? width : "width", - NULL); - op->data.tile.height = meta_draw_spec_new (info->theme, - height ? height : "height", - NULL); - op->data.tile.tile_xoffset = meta_draw_spec_new (info->theme, - tile_xoffset ? tile_xoffset : "0", - NULL); - op->data.tile.tile_yoffset = meta_draw_spec_new (info->theme, - tile_yoffset ? tile_yoffset : "0", - NULL); - op->data.tile.tile_width = meta_draw_spec_new (info->theme, tile_width, NULL); - op->data.tile.tile_height = meta_draw_spec_new (info->theme, tile_height, NULL); - - op->data.tile.op_list = op_list; - - meta_draw_op_list_append (info->op_list, op); - - push_state (info, STATE_TILE); - } - else - { - set_error (error, context, - G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Element <%s> is not allowed below <%s>"), - element_name, "draw_ops"); - } -} - -static void -parse_gradient_element (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - ParseInfo *info, - GError **error) -{ - g_return_if_fail (peek_state (info) == STATE_GRADIENT); - - if (ELEMENT_IS ("color")) - { - const char *value = NULL; - MetaColorSpec *color_spec; - - if (!locate_attributes (context, element_name, attribute_names, attribute_values, - error, - "!value", &value, - NULL)) - return; - - color_spec = parse_color (info->theme, value, error); - if (color_spec == NULL) - { - add_context_to_error (error, context); - return; - } - - g_assert (info->op); - g_assert (info->op->type == META_DRAW_GRADIENT); - g_assert (info->op->data.gradient.gradient_spec != NULL); - info->op->data.gradient.gradient_spec->color_specs = - g_slist_append (info->op->data.gradient.gradient_spec->color_specs, - color_spec); - - push_state (info, STATE_COLOR); - } - else - { - set_error (error, context, - G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Element <%s> is not allowed below <%s>"), - element_name, "gradient"); - } -} - -static void -parse_style_element (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - ParseInfo *info, - GError **error) -{ - g_return_if_fail (peek_state (info) == STATE_FRAME_STYLE); - - g_assert (info->style); - - if (ELEMENT_IS ("piece")) - { - const char *position = NULL; - const char *draw_ops = NULL; - - if (!locate_attributes (context, element_name, attribute_names, attribute_values, - error, - "!position", &position, - "draw_ops", &draw_ops, - NULL)) - return; - - info->piece = meta_frame_piece_from_string (position); - if (info->piece == META_FRAME_PIECE_LAST) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Unknown position \"%s\" for frame piece"), - position); - return; - } - - if (info->style->pieces[info->piece] != NULL) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Frame style already has a piece at position %s"), - position); - return; - } - - g_assert (info->op_list == NULL); - - if (draw_ops) - { - MetaDrawOpList *op_list; - - op_list = meta_theme_lookup_draw_op_list (info->theme, - draw_ops); - - if (op_list == NULL) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("No <draw_ops> with the name \"%s\" has been defined"), - draw_ops); - return; - } - - meta_draw_op_list_ref (op_list); - info->op_list = op_list; - } - - push_state (info, STATE_PIECE); - } - else if (ELEMENT_IS ("button")) - { - const char *function = NULL; - const char *state = NULL; - const char *draw_ops = NULL; - gint required_version; - - if (!locate_attributes (context, element_name, attribute_names, attribute_values, - error, - "!function", &function, - "!state", &state, - "draw_ops", &draw_ops, - NULL)) - return; - - info->button_type = meta_button_type_from_string (function, info->theme); - if (info->button_type == META_BUTTON_TYPE_LAST) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Unknown function \"%s\" for button"), - function); - return; - } - - required_version = peek_required_version (info); - if (meta_theme_earliest_version_with_button (info->button_type) > - (guint)required_version) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Button function \"%s\" does not exist in this version (%d, need %d)"), - function, - required_version, - meta_theme_earliest_version_with_button (info->button_type) - ); - return; - } - - info->button_state = meta_button_state_from_string (state); - if (info->button_state == META_BUTTON_STATE_LAST) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Unknown state \"%s\" for button"), - state); - return; - } - - if (info->style->buttons[info->button_type][info->button_state] != NULL) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Frame style already has a button for function %s state %s"), - function, state); - return; - } - - g_assert (info->op_list == NULL); - - if (draw_ops) - { - MetaDrawOpList *op_list; - - op_list = meta_theme_lookup_draw_op_list (info->theme, - draw_ops); - - if (op_list == NULL) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("No <draw_ops> with the name \"%s\" has been defined"), - draw_ops); - return; - } - - meta_draw_op_list_ref (op_list); - info->op_list = op_list; - } - - push_state (info, STATE_BUTTON); - } - else if (ELEMENT_IS ("shadow")) - { - /* ubuntu specific, workaround for light-themes: silently ignore shadow tag. - */ - push_state (info, UBUNTU_STATE_IGNORE); - } - else if (ELEMENT_IS ("padding")) - { - /* ubuntu specific, workaround for light-themes: silently ignore padding tag. - */ - push_state (info, UBUNTU_STATE_IGNORE); - } - else - { - set_error (error, context, - G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Element <%s> is not allowed below <%s>"), - element_name, "frame_style"); - } -} - -static void -parse_style_set_element (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - ParseInfo *info, - GError **error) -{ - g_return_if_fail (peek_state (info) == STATE_FRAME_STYLE_SET); - - if (ELEMENT_IS ("frame")) - { - const char *focus = NULL; - const char *state = NULL; - const char *resize = NULL; - const char *style = NULL; - MetaFrameFocus frame_focus; - MetaFrameState frame_state; - MetaFrameResize frame_resize; - MetaFrameStyle *frame_style; - - if (!locate_attributes (context, element_name, attribute_names, attribute_values, - error, - "!focus", &focus, - "!state", &state, - "resize", &resize, - "!style", &style, - NULL)) - return; - - frame_focus = meta_frame_focus_from_string (focus); - if (frame_focus == META_FRAME_FOCUS_LAST) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("\"%s\" is not a valid value for focus attribute"), - focus); - return; - } - - frame_state = meta_frame_state_from_string (state); - if (frame_state == META_FRAME_STATE_LAST) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("\"%s\" is not a valid value for state attribute"), - focus); - return; - } - - frame_style = meta_theme_lookup_style (info->theme, style); - - if (frame_style == NULL) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("A style called \"%s\" has not been defined"), - style); - return; - } - - switch (frame_state) - { - case META_FRAME_STATE_NORMAL: - if (resize == NULL) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - ATTRIBUTE_NOT_FOUND, - "resize", element_name); - return; - } - - - frame_resize = meta_frame_resize_from_string (resize); - if (frame_resize == META_FRAME_RESIZE_LAST) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("\"%s\" is not a valid value for resize attribute"), - focus); - return; - } - - break; - - case META_FRAME_STATE_SHADED: - if (META_THEME_ALLOWS (info->theme, META_THEME_UNRESIZABLE_SHADED_STYLES)) - { - if (resize == NULL) - /* In state="normal" we would complain here. But instead we accept - * not having a resize attribute and default to resize="both", since - * that most closely mimics what we did in v1, and thus people can - * upgrade a theme to v2 without as much hassle. - */ - frame_resize = META_FRAME_RESIZE_BOTH; - else - { - frame_resize = meta_frame_resize_from_string (resize); - if (frame_resize == META_FRAME_RESIZE_LAST) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("\"%s\" is not a valid value for resize attribute"), - focus); - return; - } - } - } - else /* v1 theme */ - { - if (resize != NULL) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Should not have \"resize\" attribute on <%s> element for maximized/shaded states"), - element_name); - return; - } - - /* resize="both" is equivalent to the old behaviour */ - frame_resize = META_FRAME_RESIZE_BOTH; - } - break; - - default: - if (resize != NULL) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Should not have \"resize\" attribute on <%s> element for maximized states"), - element_name); - return; - } - - frame_resize = META_FRAME_RESIZE_LAST; - } - - switch (frame_state) - { - case META_FRAME_STATE_NORMAL: - if (info->style_set->normal_styles[frame_resize][frame_focus]) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Style has already been specified for state %s resize %s focus %s"), - state, resize, focus); - return; - } - meta_frame_style_ref (frame_style); - info->style_set->normal_styles[frame_resize][frame_focus] = frame_style; - break; - case META_FRAME_STATE_MAXIMIZED: - if (info->style_set->maximized_styles[frame_focus]) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Style has already been specified for state %s focus %s"), - state, focus); - return; - } - meta_frame_style_ref (frame_style); - info->style_set->maximized_styles[frame_focus] = frame_style; - break; - case META_FRAME_STATE_TILED_LEFT: - if (info->style_set->tiled_left_styles[frame_focus]) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Style has already been specified for state %s focus %s"), - state, focus); - return; - } - meta_frame_style_ref (frame_style); - info->style_set->tiled_left_styles[frame_focus] = frame_style; - break; - case META_FRAME_STATE_TILED_RIGHT: - if (info->style_set->tiled_right_styles[frame_focus]) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Style has already been specified for state %s focus %s"), - state, focus); - return; - } - meta_frame_style_ref (frame_style); - info->style_set->tiled_right_styles[frame_focus] = frame_style; - break; - meta_frame_style_ref (frame_style); - info->style_set->tiled_right_styles[frame_focus] = frame_style; - break; - case META_FRAME_STATE_SHADED: - if (info->style_set->shaded_styles[frame_resize][frame_focus]) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Style has already been specified for state %s resize %s focus %s"), - state, resize, focus); - return; - } - meta_frame_style_ref (frame_style); - info->style_set->shaded_styles[frame_resize][frame_focus] = frame_style; - break; - case META_FRAME_STATE_MAXIMIZED_AND_SHADED: - if (info->style_set->maximized_and_shaded_styles[frame_focus]) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Style has already been specified for state %s focus %s"), - state, focus); - return; - } - meta_frame_style_ref (frame_style); - info->style_set->maximized_and_shaded_styles[frame_focus] = frame_style; - break; - case META_FRAME_STATE_TILED_LEFT_AND_SHADED: - if (info->style_set->tiled_left_and_shaded_styles[frame_focus]) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Style has already been specified for state %s focus %s"), - state, focus); - return; - } - meta_frame_style_ref (frame_style); - info->style_set->tiled_left_and_shaded_styles[frame_focus] = frame_style; - break; - case META_FRAME_STATE_TILED_RIGHT_AND_SHADED: - if (info->style_set->tiled_right_and_shaded_styles[frame_focus]) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Style has already been specified for state %s focus %s"), - state, focus); - return; - } - meta_frame_style_ref (frame_style); - info->style_set->tiled_right_and_shaded_styles[frame_focus] = frame_style; - break; - case META_FRAME_STATE_LAST: - g_assert_not_reached (); - break; - } - - push_state (info, STATE_FRAME); - } - else - { - set_error (error, context, - G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Element <%s> is not allowed below <%s>"), - element_name, "frame_style_set"); - } -} - -static void -parse_piece_element (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - ParseInfo *info, - GError **error) -{ - g_return_if_fail (peek_state (info) == STATE_PIECE); - - if (ELEMENT_IS ("draw_ops")) - { - if (info->op_list) - { - set_error (error, context, - G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Can't have a two draw_ops for a <piece> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)")); - return; - } - - if (!check_no_attributes (context, element_name, attribute_names, attribute_values, - error)) - return; - - g_assert (info->op_list == NULL); - info->op_list = meta_draw_op_list_new (2); - - push_state (info, STATE_DRAW_OPS); - } - else - { - set_error (error, context, - G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Element <%s> is not allowed below <%s>"), - element_name, "piece"); - } -} - -static void -parse_button_element (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - ParseInfo *info, - GError **error) -{ - g_return_if_fail (peek_state (info) == STATE_BUTTON); - - if (ELEMENT_IS ("draw_ops")) - { - if (info->op_list) - { - set_error (error, context, - G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Can't have a two draw_ops for a <button> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)")); - return; - } - - if (!check_no_attributes (context, element_name, attribute_names, attribute_values, - error)) - return; - - g_assert (info->op_list == NULL); - info->op_list = meta_draw_op_list_new (2); - - push_state (info, STATE_DRAW_OPS); - } - else - { - set_error (error, context, - G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Element <%s> is not allowed below <%s>"), - element_name, "button"); - } -} - -static void -parse_menu_icon_element (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - ParseInfo *info, - GError **error) -{ - g_return_if_fail (peek_state (info) == STATE_MENU_ICON); - - if (ELEMENT_IS ("draw_ops")) - { - if (info->op_list) - { - set_error (error, context, - G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Can't have a two draw_ops for a <menu_icon> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)")); - return; - } - - if (!check_no_attributes (context, element_name, attribute_names, attribute_values, - error)) - return; - - g_assert (info->op_list == NULL); - info->op_list = meta_draw_op_list_new (2); - - push_state (info, STATE_DRAW_OPS); - } - else - { - set_error (error, context, - G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Element <%s> is not allowed below <%s>"), - element_name, "menu_icon"); - } -} - -static const char * -find_version (const char **attribute_names, - const char **attribute_values) -{ - int i; - - for (i = 0; attribute_names[i]; i++) - { - if (strcmp (attribute_names[i], "version") == 0) - return attribute_values[i]; - } - - return NULL; -} - -/* Returns whether the version element was successfully parsed. - * If successfully parsed, then two additional items are returned: - * - * satisfied: whether this version of Muffin meets the version check - * minimum_required: minimum version of theme format required by version check - */ -static gboolean -check_version (GMarkupParseContext *context, - const char *version_str, - gboolean *satisfied, - guint *minimum_required, - GError **error) -{ - static GRegex *version_regex; - GMatchInfo *info; - char *comparison_str, *major_str, *minor_str; - guint version; - - *minimum_required = 0; - - if (!version_regex) - version_regex = g_regex_new ("^\\s*([<>]=?)\\s*(\\d+)(\\.\\d+)?\\s*$", 0, 0, NULL); - - if (!g_regex_match (version_regex, version_str, 0, &info)) - { - g_match_info_free (info); - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Bad version specification '%s'"), version_str); - return FALSE; - } - - comparison_str = g_match_info_fetch (info, 1); - major_str = g_match_info_fetch (info, 2); - minor_str = g_match_info_fetch (info, 3); - - version = 1000 * atoi (major_str); - /* might get NULL, see: https://bugzilla.gnome.org/review?bug=588217 */ - if (minor_str && minor_str[0]) - version += atoi (minor_str + 1); - - if (comparison_str[0] == '<') - { - if (comparison_str[1] == '=') - *satisfied = THEME_VERSION <= version; - else - { - *satisfied = THEME_VERSION < version; - } - } - else - { - if (comparison_str[1] == '=') - { - *satisfied = THEME_VERSION >= version; - *minimum_required = version; - } - else - { - *satisfied = THEME_VERSION > version; - *minimum_required = version + 1; - } - } - - free (comparison_str); - free (major_str); - free (minor_str); - g_match_info_free (info); - - return TRUE; -} - -static void -start_element_handler (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - gpointer user_data, - GError **error) -{ - ParseInfo *info = user_data; - const char *version; - guint required_version = 0; - - if (info->skip_level > 0) - { - info->skip_level++; - return; - } - - required_version = peek_required_version (info); - - version = find_version (attribute_names, attribute_values); - if (version != NULL) - { - gboolean satisfied; - guint element_required; - - if (required_version < 3000) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-theme-2.xml")); - return; - } - - if (!check_version (context, version, &satisfied, &element_required, error)) - return; - - /* Two different ways of handling an unsatisfied version check: - * for the toplevel element of a file, we throw an error back so - * that the controlling code can go ahead and look for an - * alternate metacity-theme-1.xml or metacity-theme-2.xml; for - * other elements we just silently skip the element and children. - */ - if (peek_state (info) == STATE_START) - { - if (satisfied) - { - if (element_required > info->format_version) - info->format_version = element_required; - } - else - { - set_error (error, context, THEME_PARSE_ERROR, THEME_PARSE_ERROR_TOO_OLD, - _("Theme requires version %s but latest supported theme version is %d.%d"), - version, THEME_VERSION, THEME_MINOR_VERSION); - return; - } - } - else if (!satisfied) - { - info->skip_level = 1; - return; - } - - if (element_required > required_version) - required_version = element_required; - } - - push_required_version (info, required_version); - - switch (peek_state (info)) - { - case STATE_START: - if (strcmp (element_name, "metacity_theme") == 0) - { - info->theme = meta_theme_new (); - info->theme->name = g_strdup (info->theme_name); - info->theme->filename = g_strdup (info->theme_file); - info->theme->dirname = g_strdup (info->theme_dir); - info->theme->format_version = info->format_version; - info->theme->scale = meta_prefs_get_ui_scale (); - - push_state (info, STATE_THEME); - } - else - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Outermost element in theme must be <metacity_theme> not <%s>"), - element_name); - break; - - case STATE_THEME: - parse_toplevel_element (context, element_name, - attribute_names, attribute_values, - info, error); - break; - case STATE_INFO: - parse_info_element (context, element_name, - attribute_names, attribute_values, - info, error); - break; - case STATE_NAME: - case STATE_AUTHOR: - case STATE_COPYRIGHT: - case STATE_DATE: - case STATE_DESCRIPTION: - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Element <%s> is not allowed inside a name/author/date/description element"), - element_name); - break; - case STATE_CONSTANT: - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Element <%s> is not allowed inside a <constant> element"), - element_name); - break; - case STATE_FRAME_GEOMETRY: - parse_geometry_element (context, element_name, - attribute_names, attribute_values, - info, error); - break; - case STATE_DISTANCE: - case STATE_BORDER: - case STATE_ASPECT_RATIO: - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Element <%s> is not allowed inside a distance/border/aspect_ratio element"), - element_name); - break; - case STATE_DRAW_OPS: - parse_draw_op_element (context, element_name, - attribute_names, attribute_values, - info, error); - break; - case STATE_LINE: - case STATE_RECTANGLE: - case STATE_ARC: - case STATE_CLIP: - case STATE_TINT: - case STATE_IMAGE: - case STATE_GTK_ARROW: - case STATE_GTK_BOX: - case STATE_GTK_VLINE: - case STATE_ICON: - case STATE_TITLE: - case STATE_INCLUDE: - case STATE_TILE: - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Element <%s> is not allowed inside a draw operation element"), - element_name); - break; - case STATE_GRADIENT: - parse_gradient_element (context, element_name, - attribute_names, attribute_values, - info, error); - break; - case STATE_COLOR: - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Element <%s> is not allowed inside a <%s> element"), - element_name, "color"); - break; - case STATE_FRAME_STYLE: - parse_style_element (context, element_name, - attribute_names, attribute_values, - info, error); - break; - case STATE_PIECE: - parse_piece_element (context, element_name, - attribute_names, attribute_values, - info, error); - break; - case STATE_BUTTON: - parse_button_element (context, element_name, - attribute_names, attribute_values, - info, error); - break; - case STATE_MENU_ICON: - parse_menu_icon_element (context, element_name, - attribute_names, attribute_values, - info, error); - break; - case STATE_FRAME_STYLE_SET: - parse_style_set_element (context, element_name, - attribute_names, attribute_values, - info, error); - break; - case STATE_FRAME: - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Element <%s> is not allowed inside a <%s> element"), - element_name, "frame"); - break; - case STATE_WINDOW: - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Element <%s> is not allowed inside a <%s> element"), - element_name, "window"); - break; - case STATE_FALLBACK: - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("Element <%s> is not allowed inside a <%s> element"), - element_name, "fallback"); - break; - case UBUNTU_STATE_IGNORE: - break; - } -} - -static void -end_element_handler (GMarkupParseContext *context, - const gchar *element_name, - gpointer user_data, - GError **error) -{ - ParseInfo *info = user_data; - - if (info->skip_level > 0) - { - info->skip_level--; - return; - } - - switch (peek_state (info)) - { - case STATE_START: - break; - case STATE_THEME: - g_assert (info->theme); - - if (!meta_theme_validate (info->theme, error)) - { - add_context_to_error (error, context); - meta_theme_free (info->theme); - info->theme = NULL; - } - - pop_state (info); - g_assert (peek_state (info) == STATE_START); - break; - case STATE_INFO: - pop_state (info); - g_assert (peek_state (info) == STATE_THEME); - break; - case STATE_NAME: - pop_state (info); - g_assert (peek_state (info) == STATE_INFO); - break; - case STATE_AUTHOR: - pop_state (info); - g_assert (peek_state (info) == STATE_INFO); - break; - case STATE_COPYRIGHT: - pop_state (info); - g_assert (peek_state (info) == STATE_INFO); - break; - case STATE_DATE: - pop_state (info); - g_assert (peek_state (info) == STATE_INFO); - break; - case STATE_DESCRIPTION: - pop_state (info); - g_assert (peek_state (info) == STATE_INFO); - break; - case STATE_CONSTANT: - pop_state (info); - g_assert (peek_state (info) == STATE_THEME); - break; - case STATE_FRAME_GEOMETRY: - g_assert (info->layout); - - if (!meta_frame_layout_validate (info->layout, - error)) - { - add_context_to_error (error, context); - } - - /* layout will already be stored in the theme under - * its name - */ - meta_frame_layout_unref (info->layout); - info->layout = NULL; - pop_state (info); - g_assert (peek_state (info) == STATE_THEME); - break; - case STATE_DISTANCE: - pop_state (info); - g_assert (peek_state (info) == STATE_FRAME_GEOMETRY); - break; - case STATE_BORDER: - pop_state (info); - g_assert (peek_state (info) == STATE_FRAME_GEOMETRY); - break; - case STATE_ASPECT_RATIO: - pop_state (info); - g_assert (peek_state (info) == STATE_FRAME_GEOMETRY); - break; - case STATE_DRAW_OPS: - { - g_assert (info->op_list); - - if (!meta_draw_op_list_validate (info->op_list, - error)) - { - add_context_to_error (error, context); - meta_draw_op_list_unref (info->op_list); - info->op_list = NULL; - } - - pop_state (info); - - switch (peek_state (info)) - { - case STATE_BUTTON: - case STATE_PIECE: - case STATE_MENU_ICON: - /* Leave info->op_list to be picked up - * when these elements are closed - */ - g_assert (info->op_list); - break; - case STATE_THEME: - g_assert (info->op_list); - meta_draw_op_list_unref (info->op_list); - info->op_list = NULL; - break; - default: - /* Op list can't occur in other contexts */ - g_assert_not_reached (); - break; - } - } - break; - case STATE_LINE: - pop_state (info); - g_assert (peek_state (info) == STATE_DRAW_OPS); - break; - case STATE_RECTANGLE: - pop_state (info); - g_assert (peek_state (info) == STATE_DRAW_OPS); - break; - case STATE_ARC: - pop_state (info); - g_assert (peek_state (info) == STATE_DRAW_OPS); - break; - case STATE_CLIP: - pop_state (info); - g_assert (peek_state (info) == STATE_DRAW_OPS); - break; - case STATE_TINT: - pop_state (info); - g_assert (peek_state (info) == STATE_DRAW_OPS); - break; - case STATE_GRADIENT: - g_assert (info->op); - g_assert (info->op->type == META_DRAW_GRADIENT); - if (!meta_gradient_spec_validate (info->op->data.gradient.gradient_spec, - error)) - { - add_context_to_error (error, context); - meta_draw_op_free (info->op); - info->op = NULL; - } - else - { - g_assert (info->op_list); - meta_draw_op_list_append (info->op_list, info->op); - info->op = NULL; - } - pop_state (info); - g_assert (peek_state (info) == STATE_DRAW_OPS); - break; - case STATE_IMAGE: - pop_state (info); - g_assert (peek_state (info) == STATE_DRAW_OPS); - break; - case STATE_GTK_ARROW: - pop_state (info); - g_assert (peek_state (info) == STATE_DRAW_OPS); - break; - case STATE_GTK_BOX: - pop_state (info); - g_assert (peek_state (info) == STATE_DRAW_OPS); - break; - case STATE_GTK_VLINE: - pop_state (info); - g_assert (peek_state (info) == STATE_DRAW_OPS); - break; - case STATE_ICON: - pop_state (info); - g_assert (peek_state (info) == STATE_DRAW_OPS); - break; - case STATE_TITLE: - pop_state (info); - g_assert (peek_state (info) == STATE_DRAW_OPS); - break; - case STATE_INCLUDE: - pop_state (info); - g_assert (peek_state (info) == STATE_DRAW_OPS); - break; - case STATE_TILE: - pop_state (info); - g_assert (peek_state (info) == STATE_DRAW_OPS); - break; - case STATE_COLOR: - pop_state (info); - g_assert (peek_state (info) == STATE_GRADIENT); - break; - case STATE_FRAME_STYLE: - g_assert (info->style); - - if (!meta_frame_style_validate (info->style, - peek_required_version (info), - error)) - { - add_context_to_error (error, context); - } - - /* Frame style is in the theme hash table and a ref - * is held there - */ - meta_frame_style_unref (info->style); - info->style = NULL; - pop_state (info); - g_assert (peek_state (info) == STATE_THEME); - break; - case STATE_PIECE: - g_assert (info->style); - if (info->op_list == NULL) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("No draw_ops provided for frame piece")); - } - else - { - info->style->pieces[info->piece] = info->op_list; - info->op_list = NULL; - } - pop_state (info); - g_assert (peek_state (info) == STATE_FRAME_STYLE); - break; - case STATE_BUTTON: - g_assert (info->style); - if (info->op_list == NULL) - { - set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - _("No draw_ops provided for button")); - } - else - { - info->style->buttons[info->button_type][info->button_state] = - info->op_list; - info->op_list = NULL; - } - pop_state (info); - break; - case STATE_MENU_ICON: - g_assert (info->theme); - if (info->op_list != NULL) - { - meta_draw_op_list_unref (info->op_list); - info->op_list = NULL; - } - pop_state (info); - g_assert (peek_state (info) == STATE_THEME); - break; - case STATE_FRAME_STYLE_SET: - g_assert (info->style_set); - - if (!meta_frame_style_set_validate (info->style_set, - error)) - { - add_context_to_error (error, context); - } - - /* Style set is in the theme hash table and a reference - * is held there. - */ - meta_frame_style_set_unref (info->style_set); - info->style_set = NULL; - pop_state (info); - g_assert (peek_state (info) == STATE_THEME); - break; - case STATE_FRAME: - pop_state (info); - g_assert (peek_state (info) == STATE_FRAME_STYLE_SET); - break; - case STATE_WINDOW: - pop_state (info); - g_assert (peek_state (info) == STATE_THEME); - break; - case STATE_FALLBACK: - pop_state (info); - g_assert (peek_state (info) == STATE_THEME); - break; - case UBUNTU_STATE_IGNORE: - pop_state (info); - break; - } - - pop_required_version (info); -} - -#define NO_TEXT(element_name) set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, _("No text is allowed inside element <%s>"), element_name) - -static gboolean -all_whitespace (const char *text, - int text_len) -{ - const char *p; - const char *end; - - p = text; - end = text + text_len; - - while (p != end) - { - if (!g_ascii_isspace (*p)) - return FALSE; - - p = g_utf8_next_char (p); - } - - return TRUE; -} - -static void -text_handler (GMarkupParseContext *context, - const gchar *text, - gsize text_len, - gpointer user_data, - GError **error) -{ - ParseInfo *info = user_data; - - if (info->skip_level > 0) - return; - - if (all_whitespace (text, text_len)) - return; - - /* FIXME http://bugzilla.gnome.org/show_bug.cgi?id=70448 would - * allow a nice cleanup here. - */ - - switch (peek_state (info)) - { - case STATE_START: - g_assert_not_reached (); /* gmarkup shouldn't do this */ - break; - case STATE_THEME: - NO_TEXT ("metacity_theme"); - break; - case STATE_INFO: - NO_TEXT ("info"); - break; - case STATE_NAME: - if (info->theme->readable_name != NULL) - { - set_error (error, context, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("<%s> specified twice for this theme"), - "name"); - return; - } - - info->theme->readable_name = g_strndup (text, text_len); - break; - case STATE_AUTHOR: - if (info->theme->author != NULL) - { - set_error (error, context, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("<%s> specified twice for this theme"), - "author"); - return; - } - - info->theme->author = g_strndup (text, text_len); - break; - case STATE_COPYRIGHT: - if (info->theme->copyright != NULL) - { - set_error (error, context, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("<%s> specified twice for this theme"), - "copyright"); - return; - } - - info->theme->copyright = g_strndup (text, text_len); - break; - case STATE_DATE: - if (info->theme->date != NULL) - { - set_error (error, context, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("<%s> specified twice for this theme"), - "date"); - return; - } - - info->theme->date = g_strndup (text, text_len); - break; - case STATE_DESCRIPTION: - if (info->theme->description != NULL) - { - set_error (error, context, G_MARKUP_ERROR, - G_MARKUP_ERROR_PARSE, - _("<%s> specified twice for this theme"), - "description"); - return; - } - - info->theme->description = g_strndup (text, text_len); - break; - case STATE_CONSTANT: - NO_TEXT ("constant"); - break; - case STATE_FRAME_GEOMETRY: - NO_TEXT ("frame_geometry"); - break; - case STATE_DISTANCE: - NO_TEXT ("distance"); - break; - case STATE_BORDER: - NO_TEXT ("border"); - break; - case STATE_ASPECT_RATIO: - NO_TEXT ("aspect_ratio"); - break; - case STATE_DRAW_OPS: - NO_TEXT ("draw_ops"); - break; - case STATE_LINE: - NO_TEXT ("line"); - break; - case STATE_RECTANGLE: - NO_TEXT ("rectangle"); - break; - case STATE_ARC: - NO_TEXT ("arc"); - break; - case STATE_CLIP: - NO_TEXT ("clip"); - break; - case STATE_TINT: - NO_TEXT ("tint"); - break; - case STATE_GRADIENT: - NO_TEXT ("gradient"); - break; - case STATE_IMAGE: - NO_TEXT ("image"); - break; - case STATE_GTK_ARROW: - NO_TEXT ("gtk_arrow"); - break; - case STATE_GTK_BOX: - NO_TEXT ("gtk_box"); - break; - case STATE_GTK_VLINE: - NO_TEXT ("gtk_vline"); - break; - case STATE_ICON: - NO_TEXT ("icon"); - break; - case STATE_TITLE: - NO_TEXT ("title"); - break; - case STATE_INCLUDE: - NO_TEXT ("include"); - break; - case STATE_TILE: - NO_TEXT ("tile"); - break; - case STATE_COLOR: - NO_TEXT ("color"); - break; - case STATE_FRAME_STYLE: - NO_TEXT ("frame_style"); - break; - case STATE_PIECE: - NO_TEXT ("piece"); - break; - case STATE_BUTTON: - NO_TEXT ("button"); - break; - case STATE_MENU_ICON: - NO_TEXT ("menu_icon"); - break; - case STATE_FRAME_STYLE_SET: - NO_TEXT ("frame_style_set"); - break; - case STATE_FRAME: - NO_TEXT ("frame"); - break; - case STATE_WINDOW: - NO_TEXT ("window"); - break; - case STATE_FALLBACK: - NO_TEXT ("fallback"); - break; - case UBUNTU_STATE_IGNORE: - NO_TEXT ("ignored_element"); - break; - } -} - -/* If the theme is not-corrupt, keep looking for alternate versions - * in other locations we might be compatible with - */ -static gboolean -theme_error_is_fatal (GError *error) -{ - return !(error->domain == G_FILE_ERROR || - (error->domain == THEME_PARSE_ERROR && - error->code == THEME_PARSE_ERROR_TOO_OLD)); -} - -static MetaTheme * -load_theme (const char *theme_dir, - const char *theme_name, - guint major_version, - GError **error) -{ - GMarkupParseContext *context; - ParseInfo info; - char *text; - gsize length; - char *theme_filename; - char *theme_file; - MetaTheme *retval; - - g_return_val_if_fail (error && *error == NULL, NULL); - - text = NULL; - retval = NULL; - context = NULL; - - theme_filename = g_strdup_printf (METACITY_THEME_FILENAME_FORMAT, major_version); - theme_file = g_build_filename (theme_dir, theme_filename, NULL); - - if (!g_file_get_contents (theme_file, - &text, - &length, - error)) - goto out; - - meta_topic (META_DEBUG_THEMES, "Parsing theme file %s\n", theme_file); - - parse_info_init (&info); - - info.theme_name = theme_name; - info.theme_file = theme_file; - info.theme_dir = theme_dir; - - info.format_version = 1000 * major_version; - - context = g_markup_parse_context_new (&metacity_theme_parser, - 0, &info, NULL); - - if (!g_markup_parse_context_parse (context, - text, - length, - error)) - goto out; - - if (!g_markup_parse_context_end_parse (context, error)) - goto out; - - retval = info.theme; - info.theme = NULL; - - out: -#ifdef WITH_VERBOSE_MODE - if (*error && !theme_error_is_fatal (*error)) - { - meta_topic (META_DEBUG_THEMES, "Failed to read theme from file %s: %s\n", - theme_file, (*error)->message); - } -#endif - free (theme_filename); - free (theme_file); - free (text); - - if (context) - { - g_markup_parse_context_free (context); - parse_info_free (&info); - } - - return retval; -} - -static gboolean -keep_trying (GError **error) -{ - if (*error && !theme_error_is_fatal (*error)) - { - g_clear_error (error); - return TRUE; - } - - return FALSE; -} - -/** - * meta_theme_load: (skip) - * - */ -MetaTheme* -meta_theme_load (const char *theme_name, - GError **err) -{ - GError *error = NULL; - char *theme_dir; - MetaTheme *retval; - const gchar* const* xdg_data_dirs; - int major_version; - int i; - - retval = NULL; - - if (meta_is_debugging ()) - { - /* Try in themes in our source tree */ - /* We try all supported major versions from current to oldest */ - for (major_version = THEME_MAJOR_VERSION; (major_version > 0); major_version--) - { - theme_dir = g_build_filename ("./themes", theme_name, NULL); - retval = load_theme (theme_dir, theme_name, major_version, &error); - free (theme_dir); - if (!keep_trying (&error)) - goto out; - } - } - - if (strcmp(theme_name, "Default") == 0) - { - theme_dir = g_build_filename (MUFFIN_DATADIR, - "muffin", - "theme", - NULL); - - retval = load_theme (theme_dir, "Default", 3, &error); - free (theme_dir); - if (!keep_trying (&error)) - goto out; - } - - /* We try all supported major versions from current to oldest */ - for (major_version = THEME_MAJOR_VERSION; (major_version > 0); major_version--) - { - /* We try first in XDG_DATA_HOME, home dir, XDG_DATA_DIRS, then system dir for themes */ - - /* user data dir */ - theme_dir = g_build_filename (g_get_user_data_dir (), - "themes", - theme_name, - THEME_SUBDIR, - NULL); - - retval = load_theme (theme_dir, theme_name, major_version, &error); - free (theme_dir); - if (!keep_trying (&error)) - goto out; - - /* Try home dir for themes */ - theme_dir = g_build_filename (g_get_home_dir (), - ".themes", - theme_name, - THEME_SUBDIR, - NULL); - - retval = load_theme (theme_dir, theme_name, major_version, &error); - free (theme_dir); - if (!keep_trying (&error)) - goto out; - - /* Try each XDG_DATA_DIRS for theme */ - xdg_data_dirs = g_get_system_data_dirs(); - for(i = 0; xdg_data_dirs[i] != NULL; i++) - { - theme_dir = g_build_filename (xdg_data_dirs[i], - "themes", - theme_name, - THEME_SUBDIR, - NULL); - - retval = load_theme (theme_dir, theme_name, major_version, &error); - free (theme_dir); - if (!keep_trying (&error)) - goto out; - } - - /* Look for themes in MUFFIN_DATADIR */ - theme_dir = g_build_filename (MUFFIN_DATADIR, - "themes", - theme_name, - THEME_SUBDIR, - NULL); - - retval = load_theme (theme_dir, theme_name, major_version, &error); - free (theme_dir); - if (!keep_trying (&error)) - goto out; - } - - out: - if (!error && !retval) - g_set_error (&error, META_THEME_ERROR, META_THEME_ERROR_FAILED, - _("Failed to find a valid file for theme %s\n"), - theme_name); - - if (error) - { - g_propagate_error (err, error); - } - - return retval; -} diff --git a/src/ui/theme-private.h b/src/ui/theme-private.h index a19178665..269dbe867 100644 --- a/src/ui/theme-private.h +++ b/src/ui/theme-private.h @@ -2,9 +2,9 @@ /* Metacity Theme Rendering */ -/* +/* * Copyright (C) 2001 Havoc Pennington - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the @@ -14,57 +14,25 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_THEME_PRIVATE_H #define META_THEME_PRIVATE_H -#include <meta/boxes.h> -#include <meta/gradient.h> -#include <meta/theme.h> -#include <meta/common.h> #include <gtk/gtk.h> +#include "meta/boxes.h" +#include "meta/common.h" +#include "meta/theme.h" + /** - * MetaFrameStyle: (skip) - * - */ -typedef struct _MetaFrameStyle MetaFrameStyle; -/** - * MetaFrameStyleSet: (skip) - * - */ -typedef struct _MetaFrameStyleSet MetaFrameStyleSet; -/** - * MetaDrawOp: (skip) - * - */ -typedef struct _MetaDrawOp MetaDrawOp; -/** - * MetaDrawOpList: (skip) - * - */ -typedef struct _MetaDrawOpList MetaDrawOpList; -/** - * MetaGradientSpec: (skip) - * - */ -typedef struct _MetaGradientSpec MetaGradientSpec; -/** - * MetaAlphaGradientSpec: (skip) - * - */ -typedef struct _MetaAlphaGradientSpec MetaAlphaGradientSpec; -/** - * MetaColorSpec: (skip) + * MetaStyleInfo: (skip) * */ -typedef struct _MetaColorSpec MetaColorSpec; +typedef struct _MetaStyleInfo MetaStyleInfo; /** * MetaFrameLayout: (skip) * @@ -81,107 +49,39 @@ typedef struct _MetaButtonSpace MetaButtonSpace; */ typedef struct _MetaFrameGeometry MetaFrameGeometry; -/** - * MetaPositionExprEnv: (skip) - * - */ -typedef struct _MetaPositionExprEnv MetaPositionExprEnv; -/** - * MetaDrawInfo: (skip) - * - */ -typedef struct _MetaDrawInfo MetaDrawInfo; - -#define META_THEME_ERROR (g_quark_from_static_string ("meta-theme-error")) - -typedef enum -{ - META_THEME_ERROR_FRAME_GEOMETRY, - META_THEME_ERROR_BAD_CHARACTER, - META_THEME_ERROR_BAD_PARENS, - META_THEME_ERROR_UNKNOWN_VARIABLE, - META_THEME_ERROR_DIVIDE_BY_ZERO, - META_THEME_ERROR_MOD_ON_FLOAT, - META_THEME_ERROR_FAILED -} MetaThemeError; - -/** - * Whether a button's size is calculated from the area around it (aspect - * sizing) or is given as a fixed height and width in pixels (fixed sizing). - * - * \bug This could be done away with; see the comment at the top of - * MetaFrameLayout. - */ -typedef enum -{ - META_BUTTON_SIZING_ASPECT, - META_BUTTON_SIZING_FIXED, - META_BUTTON_SIZING_LAST -} MetaButtonSizing; - /** * Various parameters used to calculate the geometry of a frame. - * They are used inside a MetaFrameStyle. - * This corresponds closely to the <frame_geometry> tag in a theme file. - * - * \bug button_sizing isn't really necessary, because we could easily say - * that if button_aspect is zero, the height and width are fixed values. - * This would also mean that MetaButtonSizing didn't need to exist, and - * save code. **/ struct _MetaFrameLayout { - /** Reference count. */ - int refcount; - - /** Size of left side */ - int left_width; - /** Size of right side */ - int right_width; - /** Size of bottom side */ - int bottom_height; - - /** Border of blue title region - * \bug (blue?!) - **/ - GtkBorder title_border; + /** Invisible border required by the theme */ + GtkBorder invisible_border; + /** Border/padding of the entire frame */ + GtkBorder frame_border; + /** Border/padding of the titlebar region */ + GtkBorder titlebar_border; + /** Border/padding of titlebar buttons */ + GtkBorder button_border; - /** Extra height for inside of title region, above the font height */ - int title_vertical_pad; - - /** Right indent of buttons from edges of frame */ - int right_titlebar_edge; - /** Left indent of buttons from edges of frame */ - int left_titlebar_edge; - - /** - * Sizing rule of buttons, either META_BUTTON_SIZING_ASPECT - * (in which case button_aspect will be honoured, and - * button_width and button_height set from it), or - * META_BUTTON_SIZING_FIXED (in which case we read the width - * and height directly). - */ - MetaButtonSizing button_sizing; + /** Margin of title */ + GtkBorder title_margin; + /** Margin of titlebar buttons */ + GtkBorder button_margin; - /** - * Ratio of height/width. Honoured only if - * button_sizing==META_BUTTON_SIZING_ASPECT. - * Otherwise we figure out the height from the button_border. - */ - double button_aspect; - - /** Width of a button; set even when we are using aspect sizing */ - int button_width; + /** Min size of titlebar region */ + GtkRequisition titlebar_min_size; + /** Min size of titlebar buttons */ + GtkRequisition button_min_size; - /** Height of a button; set even when we are using aspect sizing */ - int button_height; + /** Size of images in buttons */ + guint icon_size; - /** Space around buttons */ - GtkBorder button_border; + /** Space between titlebar elements */ + guint titlebar_spacing; /** scale factor for title text */ double title_scale; - + /** Whether title text will be displayed */ guint has_title : 1; @@ -220,47 +120,28 @@ struct _MetaFrameGeometry MetaFrameBorders borders; int width; - int height; + int height; GdkRectangle title_rect; - int left_titlebar_edge; - int right_titlebar_edge; - int top_titlebar_edge; - int bottom_titlebar_edge; + GtkBorder content_border; /* used for a memset hack */ #define ADDRESS_OF_BUTTON_RECTS(fgeom) (((char*)(fgeom)) + G_STRUCT_OFFSET (MetaFrameGeometry, close_rect)) -#define LENGTH_OF_BUTTON_RECTS (G_STRUCT_OFFSET (MetaFrameGeometry, right_single_background) + sizeof (GdkRectangle) - G_STRUCT_OFFSET (MetaFrameGeometry, close_rect)) - +#define LENGTH_OF_BUTTON_RECTS (G_STRUCT_OFFSET (MetaFrameGeometry, menu_rect) + sizeof (MetaButtonSpace) - G_STRUCT_OFFSET (MetaFrameGeometry, close_rect)) + /* The button rects (if changed adjust memset hack) */ MetaButtonSpace close_rect; MetaButtonSpace max_rect; MetaButtonSpace min_rect; MetaButtonSpace menu_rect; - MetaButtonSpace shade_rect; - MetaButtonSpace above_rect; - MetaButtonSpace stick_rect; - MetaButtonSpace unshade_rect; - MetaButtonSpace unabove_rect; - MetaButtonSpace unstick_rect; - -#define MAX_MIDDLE_BACKGROUNDS (MAX_BUTTONS_PER_CORNER - 2) - GdkRectangle left_left_background; - GdkRectangle left_middle_backgrounds[MAX_MIDDLE_BACKGROUNDS]; - GdkRectangle left_right_background; - GdkRectangle left_single_background; - GdkRectangle right_left_background; - GdkRectangle right_middle_backgrounds[MAX_MIDDLE_BACKGROUNDS]; - GdkRectangle right_right_background; - GdkRectangle right_single_background; /* End of button rects (if changed adjust memset hack) */ /* Saved button layout */ MetaButtonLayout button_layout; int n_left_buttons; int n_right_buttons; - + /* Round corners */ guint top_left_corner_rounded_radius; guint top_right_corner_rounded_radius; @@ -268,373 +149,6 @@ struct _MetaFrameGeometry guint bottom_right_corner_rounded_radius; }; -typedef enum -{ - META_IMAGE_FILL_SCALE, /* default, needs to be all-bits-zero for g_new0 */ - META_IMAGE_FILL_TILE -} MetaImageFillType; - -typedef enum -{ - META_COLOR_SPEC_BASIC, - META_COLOR_SPEC_GTK, - META_COLOR_SPEC_GTK_CUSTOM, - META_COLOR_SPEC_BLEND, - META_COLOR_SPEC_SHADE -} MetaColorSpecType; - -typedef enum -{ - META_GTK_COLOR_FG, - META_GTK_COLOR_BG, - META_GTK_COLOR_LIGHT, - META_GTK_COLOR_DARK, - META_GTK_COLOR_MID, - META_GTK_COLOR_TEXT, - META_GTK_COLOR_BASE, - META_GTK_COLOR_TEXT_AA, - META_GTK_COLOR_LAST -} MetaGtkColorComponent; - -struct _MetaColorSpec -{ - MetaColorSpecType type; - union - { - struct { - GdkRGBA color; - } basic; - struct { - MetaGtkColorComponent component; - GtkStateFlags state; - } gtk; - struct { - char *color_name; - MetaColorSpec *fallback; - } gtkcustom; - struct { - MetaColorSpec *foreground; - MetaColorSpec *background; - double alpha; - - GdkRGBA color; - } blend; - struct { - MetaColorSpec *base; - double factor; - - GdkRGBA color; - } shade; - } data; -}; - -struct _MetaGradientSpec -{ - MetaGradientType type; - GSList *color_specs; -}; - -struct _MetaAlphaGradientSpec -{ - MetaGradientType type; - unsigned char *alphas; - int n_alphas; -}; - -struct _MetaDrawInfo -{ - PangoLayout *title_layout; - int title_layout_width; - int title_layout_height; - const MetaFrameGeometry *fgeom; -}; - -/** - * A drawing operation in our simple vector drawing language. - */ -typedef enum -{ - /** Basic drawing-- line */ - META_DRAW_LINE, - /** Basic drawing-- rectangle */ - META_DRAW_RECTANGLE, - /** Basic drawing-- arc */ - META_DRAW_ARC, - - /** Clip to a rectangle */ - META_DRAW_CLIP, - - /* Texture thingies */ - - /** Just a filled rectangle with alpha */ - META_DRAW_TINT, - META_DRAW_GRADIENT, - META_DRAW_IMAGE, - - /** GTK theme engine stuff */ - META_DRAW_GTK_ARROW, - META_DRAW_GTK_BOX, - META_DRAW_GTK_VLINE, - - /** App's window icon */ - META_DRAW_ICON, - /** App's window title */ - META_DRAW_TITLE, - /** a draw op list */ - META_DRAW_OP_LIST, - /** tiled draw op list */ - META_DRAW_TILE -} MetaDrawType; - -typedef enum -{ - POS_TOKEN_INT, - POS_TOKEN_DOUBLE, - POS_TOKEN_OPERATOR, - POS_TOKEN_VARIABLE, - POS_TOKEN_OPEN_PAREN, - POS_TOKEN_CLOSE_PAREN -} PosTokenType; - -typedef enum -{ - POS_OP_NONE, - POS_OP_ADD, - POS_OP_SUBTRACT, - POS_OP_MULTIPLY, - POS_OP_DIVIDE, - POS_OP_MOD, - POS_OP_MAX, - POS_OP_MIN -} PosOperatorType; - -/** - * A token, as output by the tokeniser. - * - * \ingroup tokenizer - */ -typedef struct -{ - PosTokenType type; - - union - { - struct { - int val; - } i; - - struct { - double val; - } d; - - struct { - PosOperatorType op; - } o; - - struct { - char *name; - GQuark name_quark; - } v; - - } d; -} PosToken; - -/** - * MetaDrawSpec: (skip) - * - * A computed expression in our simple vector drawing language. - * While it appears to take the form of a tree, this is actually - * merely a list; concerns such as precedence of operators are - * currently recomputed on every recalculation. - * - * Created by meta_draw_spec_new(), destroyed by meta_draw_spec_free(). - * pos_eval() fills this with ...FIXME. Are tokens a tree or a list? - * \ingroup parser - */ -typedef struct _MetaDrawSpec MetaDrawSpec; -struct _MetaDrawSpec -{ - /** - * If this spec is constant, this is the value of the constant; - * otherwise it is zero. - */ - int value; - - /** A list of tokens in the expression. */ - PosToken *tokens; - - /** How many tokens are in the tokens list. */ - int n_tokens; - - /** Does the expression contain any variables? */ - gboolean constant : 1; -}; - -/** - * A single drawing operation in our simple vector drawing language. - */ -struct _MetaDrawOp -{ - MetaDrawType type; - - /* Positions are strings because they can be expressions */ - union - { - struct { - MetaColorSpec *color_spec; - int dash_on_length; - int dash_off_length; - int width; - MetaDrawSpec *x1; - MetaDrawSpec *y1; - MetaDrawSpec *x2; - MetaDrawSpec *y2; - } line; - - struct { - MetaColorSpec *color_spec; - gboolean filled; - MetaDrawSpec *x; - MetaDrawSpec *y; - MetaDrawSpec *width; - MetaDrawSpec *height; - } rectangle; - - struct { - MetaColorSpec *color_spec; - gboolean filled; - MetaDrawSpec *x; - MetaDrawSpec *y; - MetaDrawSpec *width; - MetaDrawSpec *height; - double start_angle; - double extent_angle; - } arc; - - struct { - MetaDrawSpec *x; - MetaDrawSpec *y; - MetaDrawSpec *width; - MetaDrawSpec *height; - } clip; - - struct { - MetaColorSpec *color_spec; - MetaAlphaGradientSpec *alpha_spec; - MetaDrawSpec *x; - MetaDrawSpec *y; - MetaDrawSpec *width; - MetaDrawSpec *height; - } tint; - - struct { - MetaGradientSpec *gradient_spec; - MetaAlphaGradientSpec *alpha_spec; - MetaDrawSpec *x; - MetaDrawSpec *y; - MetaDrawSpec *width; - MetaDrawSpec *height; - } gradient; - - struct { - MetaColorSpec *colorize_spec; - MetaAlphaGradientSpec *alpha_spec; - GdkPixbuf *pixbuf; - MetaDrawSpec *x; - MetaDrawSpec *y; - MetaDrawSpec *width; - MetaDrawSpec *height; - - guint32 colorize_cache_pixel; - GdkPixbuf *colorize_cache_pixbuf; - MetaImageFillType fill_type; - unsigned int vertical_stripes : 1; - unsigned int horizontal_stripes : 1; - } image; - - struct { - GtkStateFlags state; - GtkShadowType shadow; - GtkArrowType arrow; - gboolean filled; - - MetaDrawSpec *x; - MetaDrawSpec *y; - MetaDrawSpec *width; - MetaDrawSpec *height; - } gtk_arrow; - - struct { - GtkStateFlags state; - GtkShadowType shadow; - MetaDrawSpec *x; - MetaDrawSpec *y; - MetaDrawSpec *width; - MetaDrawSpec *height; - } gtk_box; - - struct { - GtkStateFlags state; - MetaDrawSpec *x; - MetaDrawSpec *y1; - MetaDrawSpec *y2; - } gtk_vline; - - struct { - MetaAlphaGradientSpec *alpha_spec; - MetaDrawSpec *x; - MetaDrawSpec *y; - MetaDrawSpec *width; - MetaDrawSpec *height; - MetaImageFillType fill_type; - } icon; - - struct { - MetaColorSpec *color_spec; - MetaDrawSpec *x; - MetaDrawSpec *y; - MetaDrawSpec *ellipsize_width; - } title; - - struct { - MetaDrawOpList *op_list; - MetaDrawSpec *x; - MetaDrawSpec *y; - MetaDrawSpec *width; - MetaDrawSpec *height; - } op_list; - - struct { - MetaDrawOpList *op_list; - MetaDrawSpec *x; - MetaDrawSpec *y; - MetaDrawSpec *width; - MetaDrawSpec *height; - MetaDrawSpec *tile_xoffset; - MetaDrawSpec *tile_yoffset; - MetaDrawSpec *tile_width; - MetaDrawSpec *tile_height; - } tile; - - } data; -}; - -/** - * A list of MetaDrawOp objects. Maintains a reference count. - * Grows as necessary and allows the allocation of unused spaces - * to keep reallocations to a minimum. - * - * \bug Do we really win anything from not using the equivalent - * GLib structures? - */ -struct _MetaDrawOpList -{ - int refcount; - MetaDrawOp **ops; - int n_ops; - int n_allocated; -}; - typedef enum { META_BUTTON_STATE_NORMAL, @@ -645,130 +159,43 @@ typedef enum typedef enum { - /* Ordered so that background is drawn first */ - META_BUTTON_TYPE_LEFT_LEFT_BACKGROUND, - META_BUTTON_TYPE_LEFT_MIDDLE_BACKGROUND, - META_BUTTON_TYPE_LEFT_RIGHT_BACKGROUND, - META_BUTTON_TYPE_LEFT_SINGLE_BACKGROUND, - META_BUTTON_TYPE_RIGHT_LEFT_BACKGROUND, - META_BUTTON_TYPE_RIGHT_MIDDLE_BACKGROUND, - META_BUTTON_TYPE_RIGHT_RIGHT_BACKGROUND, - META_BUTTON_TYPE_RIGHT_SINGLE_BACKGROUND, META_BUTTON_TYPE_CLOSE, META_BUTTON_TYPE_MAXIMIZE, META_BUTTON_TYPE_MINIMIZE, META_BUTTON_TYPE_MENU, - META_BUTTON_TYPE_SHADE, - META_BUTTON_TYPE_ABOVE, - META_BUTTON_TYPE_STICK, - META_BUTTON_TYPE_UNSHADE, - META_BUTTON_TYPE_UNABOVE, - META_BUTTON_TYPE_UNSTICK, META_BUTTON_TYPE_LAST } MetaButtonType; typedef enum { - META_MENU_ICON_TYPE_CLOSE, - META_MENU_ICON_TYPE_MAXIMIZE, - META_MENU_ICON_TYPE_UNMAXIMIZE, - META_MENU_ICON_TYPE_MINIMIZE, - META_MENU_ICON_TYPE_LAST -} MetaMenuIconType; - -typedef enum + META_STYLE_ELEMENT_WINDOW, + META_STYLE_ELEMENT_FRAME, + META_STYLE_ELEMENT_TITLEBAR, + META_STYLE_ELEMENT_TITLE, + META_STYLE_ELEMENT_BUTTON, + META_STYLE_ELEMENT_IMAGE, + META_STYLE_ELEMENT_LAST +} MetaStyleElement; + +struct _MetaStyleInfo { - /* Listed in the order in which the textures are drawn. - * (though this only matters for overlaps of course.) - * Buttons are drawn after the frame textures. - * - * On the corners, horizontal pieces are arbitrarily given the - * corner area: - * - * ===== |==== - * | | - * | rather than | - * - */ - - /* entire frame */ - META_FRAME_PIECE_ENTIRE_BACKGROUND, - /* entire titlebar background */ - META_FRAME_PIECE_TITLEBAR, - /* portion of the titlebar background inside the titlebar - * background edges - */ - META_FRAME_PIECE_TITLEBAR_MIDDLE, - /* left end of titlebar */ - META_FRAME_PIECE_LEFT_TITLEBAR_EDGE, - /* right end of titlebar */ - META_FRAME_PIECE_RIGHT_TITLEBAR_EDGE, - /* top edge of titlebar */ - META_FRAME_PIECE_TOP_TITLEBAR_EDGE, - /* bottom edge of titlebar */ - META_FRAME_PIECE_BOTTOM_TITLEBAR_EDGE, - /* render over title background (text area) */ - META_FRAME_PIECE_TITLE, - /* left edge of the frame */ - META_FRAME_PIECE_LEFT_EDGE, - /* right edge of the frame */ - META_FRAME_PIECE_RIGHT_EDGE, - /* bottom edge of the frame */ - META_FRAME_PIECE_BOTTOM_EDGE, - /* place over entire frame, after drawing everything else */ - META_FRAME_PIECE_OVERLAY, - /* Used to get size of the enum */ - META_FRAME_PIECE_LAST -} MetaFramePiece; - -/** - * How to draw a frame in a particular state (say, a focussed, non-maximised, - * resizable frame). This corresponds closely to the <frame_style> tag - * in a theme file. - */ -struct _MetaFrameStyle -{ - /** Reference count. */ int refcount; - /** - * Parent style. - * Settings which are unspecified here will be taken from there. - */ - MetaFrameStyle *parent; - /** Operations for drawing each kind of button in each state. */ - MetaDrawOpList *buttons[META_BUTTON_TYPE_LAST][META_BUTTON_STATE_LAST]; - /** Operations for drawing each piece of the frame. */ - MetaDrawOpList *pieces[META_FRAME_PIECE_LAST]; - /** - * Details such as the height and width of each edge, the corner rounding, - * and the aspect ratio of the buttons. - */ - MetaFrameLayout *layout; - /** - * Background colour of the window. Only present in theme formats - * 2 and above. Can be NULL to use the standard GTK theme engine. - */ - MetaColorSpec *window_background_color; - /** - * Transparency of the window background. 0=transparent; 255=opaque. - */ - guint8 window_background_alpha; + + GtkStyleContext *styles[META_STYLE_ELEMENT_LAST]; }; /* Kinds of frame... - * - * normal -> noresize / vert only / horz only / both - * focused / unfocused + * + * normal -> focused / unfocused * max -> focused / unfocused * shaded -> focused / unfocused * max/shaded -> focused / unfocused * - * so 4 states with 8 sub-states in one, 2 sub-states in the other 3, - * meaning 14 total + * so 4 states with 2 sub-states each, meaning 8 total * - * 14 window states times 7 or 8 window types. Except some + * 8 window states times 7 or 8 window types. Except some * window types never get a frame so that narrows it down a bit. - * + * */ typedef enum { @@ -783,15 +210,6 @@ typedef enum META_FRAME_STATE_LAST } MetaFrameState; -typedef enum -{ - META_FRAME_RESIZE_NONE, - META_FRAME_RESIZE_VERTICAL, - META_FRAME_RESIZE_HORIZONTAL, - META_FRAME_RESIZE_BOTH, - META_FRAME_RESIZE_LAST -} MetaFrameResize; - typedef enum { META_FRAME_FOCUS_NO, @@ -799,284 +217,33 @@ typedef enum META_FRAME_FOCUS_LAST } MetaFrameFocus; -/** - * How to draw frames at different times: when it's maximised or not, shaded - * or not, when it's focussed or not, and (for non-maximised windows), when - * it can be horizontally or vertically resized, both, or neither. - * Not all window types actually get a frame. - * - * A theme contains one of these objects for each type of window (each - * MetaFrameType), that is, normal, dialogue (modal and non-modal), etc. - * - * This corresponds closely to the <frame_style_set> tag in a theme file. - */ -struct _MetaFrameStyleSet -{ - int refcount; - MetaFrameStyleSet *parent; - MetaFrameStyle *normal_styles[META_FRAME_RESIZE_LAST][META_FRAME_FOCUS_LAST]; - MetaFrameStyle *maximized_styles[META_FRAME_FOCUS_LAST]; - MetaFrameStyle *tiled_left_styles[META_FRAME_FOCUS_LAST]; - MetaFrameStyle *tiled_right_styles[META_FRAME_FOCUS_LAST]; - MetaFrameStyle *tiled_ulc_styles[META_FRAME_FOCUS_LAST]; - MetaFrameStyle *tiled_llc_styles[META_FRAME_FOCUS_LAST]; - MetaFrameStyle *tiled_urc_styles[META_FRAME_FOCUS_LAST]; - MetaFrameStyle *tiled_lrc_styles[META_FRAME_FOCUS_LAST]; - MetaFrameStyle *shaded_styles[META_FRAME_RESIZE_LAST][META_FRAME_FOCUS_LAST]; - MetaFrameStyle *maximized_and_shaded_styles[META_FRAME_FOCUS_LAST]; - MetaFrameStyle *tiled_left_and_shaded_styles[META_FRAME_FOCUS_LAST]; - MetaFrameStyle *tiled_right_and_shaded_styles[META_FRAME_FOCUS_LAST]; - MetaFrameStyle *tiled_ulc_and_shaded_styles[META_FRAME_FOCUS_LAST]; - MetaFrameStyle *tiled_llc_and_shaded_styles[META_FRAME_FOCUS_LAST]; - MetaFrameStyle *tiled_urc_and_shaded_styles[META_FRAME_FOCUS_LAST]; - MetaFrameStyle *tiled_lrc_and_shaded_styles[META_FRAME_FOCUS_LAST]; -}; - /** * A theme. This is a singleton class which groups all settings from a theme - * on disk together. - * - * \bug It is rather useless to keep the metadata fields in core, I think. + * together. */ struct _MetaTheme { - /** Name of the theme (on disk), e.g. "Crux" */ - char *name; - /** Path to the files associated with the theme */ - char *dirname; - /** - * Filename of the XML theme file. - * \bug Kept lying around for no discernable reason. - */ - char *filename; - /** Metadata: Human-readable name of the theme. */ - char *readable_name; - /** Metadata: Author of the theme. */ - char *author; - /** Metadata: Copyright holder. */ - char *copyright; - /** Metadata: Date of the theme. */ - char *date; - /** Metadata: Description of the theme. */ - char *description; - /** Version of the theme format. Older versions cannot use the features - * of newer versions even if they think they can (this is to allow forward - * and backward compatibility. - */ - guint format_version; - - guint scale; - - /** Symbol table of integer constants. */ - GHashTable *integer_constants; - /** Symbol table of float constants. */ - GHashTable *float_constants; - /** - * Symbol table of colour constants (hex triples, and triples - * plus alpha). - * */ - GHashTable *color_constants; - GHashTable *images_by_filename; - GHashTable *layouts_by_name; - GHashTable *draw_op_lists_by_name; - GHashTable *styles_by_name; - GHashTable *style_sets_by_name; - MetaFrameStyleSet *style_sets_by_type[META_FRAME_TYPE_LAST]; - - GQuark quark_width; - GQuark quark_height; - GQuark quark_object_width; - GQuark quark_object_height; - GQuark quark_left_width; - GQuark quark_right_width; - GQuark quark_top_height; - GQuark quark_bottom_height; - GQuark quark_mini_icon_width; - GQuark quark_mini_icon_height; - GQuark quark_icon_width; - GQuark quark_icon_height; - GQuark quark_title_width; - GQuark quark_title_height; - GQuark quark_frame_x_center; - GQuark quark_frame_y_center; -}; - -struct _MetaPositionExprEnv -{ - MetaRectangle rect; - /* size of an object being drawn, if it has a natural size */ - int object_width; - int object_height; - /* global object sizes, always available */ - int left_width; - int right_width; - int top_height; - int bottom_height; - int title_width; - int title_height; - int frame_x_center; - int frame_y_center; - int mini_icon_width; - int mini_icon_height; - int icon_width; - int icon_height; - /* Theme so we can look up constants */ - MetaTheme *theme; + MetaFrameLayout *layouts[META_FRAME_TYPE_LAST]; }; -MetaFrameLayout* meta_frame_layout_new (void); -MetaFrameLayout* meta_frame_layout_copy (const MetaFrameLayout *src); -void meta_frame_layout_ref (MetaFrameLayout *layout); -void meta_frame_layout_unref (MetaFrameLayout *layout); -void meta_frame_layout_get_borders (const MetaFrameLayout *layout, - int text_height, - MetaFrameFlags flags, - MetaFrameType type, - MetaFrameBorders *borders); -void meta_frame_layout_calc_geometry (const MetaFrameLayout *layout, - int text_height, - MetaFrameFlags flags, - int client_width, - int client_height, - const MetaButtonLayout *button_layout, - MetaFrameType type, - MetaFrameGeometry *fgeom, - MetaTheme *theme); - -gboolean meta_frame_layout_validate (const MetaFrameLayout *layout, - GError **error); - -gboolean meta_parse_position_expression (MetaDrawSpec *spec, - const MetaPositionExprEnv *env, - int *x_return, - int *y_return, - GError **err); -gboolean meta_parse_size_expression (MetaDrawSpec *spec, - const MetaPositionExprEnv *env, - int *val_return, - GError **err); - -MetaDrawSpec* meta_draw_spec_new (MetaTheme *theme, - const char *expr, - GError **error); -void meta_draw_spec_free (MetaDrawSpec *spec); - -MetaColorSpec* meta_color_spec_new (MetaColorSpecType type); -MetaColorSpec* meta_color_spec_new_from_string (const char *str, - GError **err); -MetaColorSpec* meta_color_spec_new_gtk (MetaGtkColorComponent component, - GtkStateFlags state); -void meta_color_spec_free (MetaColorSpec *spec); -void meta_color_spec_render (MetaColorSpec *spec, - GtkStyleContext *style_gtk, - GdkRGBA *color); - - -MetaDrawOp* meta_draw_op_new (MetaDrawType type); -void meta_draw_op_free (MetaDrawOp *op); -void meta_draw_op_draw (const MetaDrawOp *op, - GtkWidget *widget, - cairo_t *cr, - const MetaDrawInfo *info, - /* logical region being drawn */ - MetaRectangle logical_region); +void meta_frame_layout_apply_scale (const MetaFrameLayout *layout, + PangoFontDescription *font_desc); -void meta_draw_op_draw_with_style (const MetaDrawOp *op, - GtkStyleContext *style_gtk, - GtkWidget *widget, - cairo_t *cr, - const MetaDrawInfo *info, - /* logical region being drawn */ - MetaRectangle logical_region); +MetaFrameLayout* meta_theme_get_frame_layout (MetaTheme *theme, + MetaFrameType type); -MetaDrawOpList* meta_draw_op_list_new (int n_preallocs); -void meta_draw_op_list_ref (MetaDrawOpList *op_list); -void meta_draw_op_list_unref (MetaDrawOpList *op_list); -void meta_draw_op_list_draw (const MetaDrawOpList *op_list, - GtkWidget *widget, - cairo_t *cr, - const MetaDrawInfo *info, - MetaRectangle rect); -void meta_draw_op_list_draw_with_style (const MetaDrawOpList *op_list, - GtkStyleContext *style_gtk, - GtkWidget *widget, - cairo_t *cr, - const MetaDrawInfo *info, - MetaRectangle rect); -void meta_draw_op_list_append (MetaDrawOpList *op_list, - MetaDrawOp *op); -gboolean meta_draw_op_list_validate (MetaDrawOpList *op_list, - GError **error); -gboolean meta_draw_op_list_contains (MetaDrawOpList *op_list, - MetaDrawOpList *child); +MetaStyleInfo * meta_theme_create_style_info (GdkScreen *screen, + const gchar *variant); +MetaStyleInfo * meta_style_info_ref (MetaStyleInfo *style); +void meta_style_info_unref (MetaStyleInfo *style_info); -MetaGradientSpec* meta_gradient_spec_new (MetaGradientType type); -void meta_gradient_spec_free (MetaGradientSpec *desc); -GdkPixbuf* meta_gradient_spec_render (const MetaGradientSpec *desc, - GtkStyleContext *gtk_style, - int width, - int height); -gboolean meta_gradient_spec_validate (MetaGradientSpec *spec, - GError **error); +void meta_style_info_set_flags (MetaStyleInfo *style_info, + MetaFrameFlags flags); -MetaAlphaGradientSpec* meta_alpha_gradient_spec_new (MetaGradientType type, - int n_alphas); -void meta_alpha_gradient_spec_free (MetaAlphaGradientSpec *spec); - - -MetaFrameStyle* meta_frame_style_new (MetaFrameStyle *parent); -void meta_frame_style_ref (MetaFrameStyle *style); -void meta_frame_style_unref (MetaFrameStyle *style); - -void meta_frame_style_draw (MetaFrameStyle *style, - GtkWidget *widget, - cairo_t *cr, - const MetaFrameGeometry *fgeom, - int client_width, - int client_height, - PangoLayout *title_layout, - int text_height, - MetaButtonState button_states[META_BUTTON_TYPE_LAST]); - - -void meta_frame_style_draw_with_style (MetaFrameStyle *style, - GtkStyleContext *style_gtk, - GtkWidget *widget, - cairo_t *cr, - const MetaFrameGeometry *fgeom, - int client_width, - int client_height, - PangoLayout *title_layout, - int text_height, - MetaButtonState button_states[META_BUTTON_TYPE_LAST]); - - -gboolean meta_frame_style_validate (MetaFrameStyle *style, - guint current_theme_version, - GError **error); - -MetaFrameStyleSet* meta_frame_style_set_new (MetaFrameStyleSet *parent); -void meta_frame_style_set_ref (MetaFrameStyleSet *style_set); -void meta_frame_style_set_unref (MetaFrameStyleSet *style_set); - -gboolean meta_frame_style_set_validate (MetaFrameStyleSet *style_set, - GError **error); - -GdkPixbuf* meta_theme_load_image (MetaTheme *theme, - const char *filename, - guint size_of_theme_icons, - GError **error); - -MetaFrameStyle* meta_theme_get_frame_style (MetaTheme *theme, - MetaFrameType type, - MetaFrameFlags flags); - -double meta_theme_get_title_scale (MetaTheme *theme, - MetaFrameType type, - MetaFrameFlags flags); +PangoFontDescription * meta_style_info_create_font_desc (MetaStyleInfo *style_info); void meta_theme_draw_frame (MetaTheme *theme, - GtkWidget *widget, + MetaStyleInfo *style_info, cairo_t *cr, MetaFrameType type, MetaFrameFlags flags, @@ -1085,28 +252,18 @@ void meta_theme_draw_frame (MetaTheme *theme, PangoLayout *title_layout, int text_height, const MetaButtonLayout *button_layout, - MetaButtonState button_states[META_BUTTON_TYPE_LAST]); - -void meta_theme_draw_frame_with_style (MetaTheme *theme, - GtkStyleContext *style_gtk, - GtkWidget *widget, - cairo_t *cr, - MetaFrameType type, - MetaFrameFlags flags, - int client_width, - int client_height, - PangoLayout *title_layout, - int text_height, - const MetaButtonLayout *button_layout, - MetaButtonState button_states[META_BUTTON_TYPE_LAST]); + MetaButtonState button_states[META_BUTTON_TYPE_LAST], + cairo_surface_t *mini_icon); void meta_theme_get_frame_borders (MetaTheme *theme, + MetaStyleInfo *style_info, MetaFrameType type, int text_height, MetaFrameFlags flags, MetaFrameBorders *borders); void meta_theme_calc_geometry (MetaTheme *theme, + MetaStyleInfo *style_info, MetaFrameType type, int text_height, MetaFrameFlags flags, @@ -1115,112 +272,10 @@ void meta_theme_calc_geometry (MetaTheme *theme, const MetaButtonLayout *button_layout, MetaFrameGeometry *fgeom); -MetaFrameLayout* meta_theme_lookup_layout (MetaTheme *theme, - const char *name); -void meta_theme_insert_layout (MetaTheme *theme, - const char *name, - MetaFrameLayout *layout); -MetaDrawOpList* meta_theme_lookup_draw_op_list (MetaTheme *theme, - const char *name); -void meta_theme_insert_draw_op_list (MetaTheme *theme, - const char *name, - MetaDrawOpList *op_list); -MetaFrameStyle* meta_theme_lookup_style (MetaTheme *theme, - const char *name); -void meta_theme_insert_style (MetaTheme *theme, - const char *name, - MetaFrameStyle *style); -MetaFrameStyleSet* meta_theme_lookup_style_set (MetaTheme *theme, - const char *name); -void meta_theme_insert_style_set (MetaTheme *theme, - const char *name, - MetaFrameStyleSet *style_set); -gboolean meta_theme_define_int_constant (MetaTheme *theme, - const char *name, - int value, - GError **error); -gboolean meta_theme_lookup_int_constant (MetaTheme *theme, - const char *name, - int *value); -gboolean meta_theme_define_float_constant (MetaTheme *theme, - const char *name, - double value, - GError **error); -gboolean meta_theme_lookup_float_constant (MetaTheme *theme, - const char *name, - double *value); - -gboolean meta_theme_define_color_constant (MetaTheme *theme, - const char *name, - const char *value, - GError **error); -gboolean meta_theme_lookup_color_constant (MetaTheme *theme, - const char *name, - char **value); - -gboolean meta_theme_replace_constants (MetaTheme *theme, - PosToken *tokens, - int n_tokens, - GError **err); - /* random stuff */ -PangoFontDescription* meta_gtk_widget_get_font_desc (GtkWidget *widget, - double scale, - const PangoFontDescription *override); int meta_pango_font_desc_get_text_height (const PangoFontDescription *font_desc, PangoContext *context); - - -/* Enum converters */ -MetaGtkColorComponent meta_color_component_from_string (const char *str); -const char* meta_color_component_to_string (MetaGtkColorComponent component); -MetaButtonState meta_button_state_from_string (const char *str); -const char* meta_button_state_to_string (MetaButtonState state); -MetaButtonType meta_button_type_from_string (const char *str, - MetaTheme *theme); -const char* meta_button_type_to_string (MetaButtonType type); -MetaFramePiece meta_frame_piece_from_string (const char *str); -const char* meta_frame_piece_to_string (MetaFramePiece piece); -MetaFrameState meta_frame_state_from_string (const char *str); -const char* meta_frame_state_to_string (MetaFrameState state); -MetaFrameResize meta_frame_resize_from_string (const char *str); -const char* meta_frame_resize_to_string (MetaFrameResize resize); -MetaFrameFocus meta_frame_focus_from_string (const char *str); -const char* meta_frame_focus_to_string (MetaFrameFocus focus); -MetaFrameType meta_frame_type_from_string (const char *str); -MetaGradientType meta_gradient_type_from_string (const char *str); -const char* meta_gradient_type_to_string (MetaGradientType type); -GtkStateFlags meta_gtk_state_from_string (const char *str); -const char* meta_gtk_state_to_string (GtkStateFlags state); -GtkShadowType meta_gtk_shadow_from_string (const char *str); -const char* meta_gtk_shadow_to_string (GtkShadowType shadow); -GtkArrowType meta_gtk_arrow_from_string (const char *str); -const char* meta_gtk_arrow_to_string (GtkArrowType arrow); -MetaImageFillType meta_image_fill_type_from_string (const char *str); -const char* meta_image_fill_type_to_string (MetaImageFillType fill_type); - -void meta_gtk_style_get_light_color (GtkStyleContext *style, - GtkStateFlags state, - GdkRGBA *color); -void meta_gtk_style_get_dark_color (GtkStyleContext *style, - GtkStateFlags state, - GdkRGBA *color); - -guint meta_theme_earliest_version_with_button (MetaButtonType type); - - -#define META_THEME_ALLOWS(theme, feature) (theme->format_version >= feature) - -/* What version of the theme file format were various features introduced in? */ -#define META_THEME_SHADE_STICK_ABOVE_BUTTONS 2 -#define META_THEME_UBIQUITOUS_CONSTANTS 2 -#define META_THEME_VARIED_ROUND_CORNERS 2 -#define META_THEME_IMAGES_FROM_ICON_THEMES 2 -#define META_THEME_UNRESIZABLE_SHADED_STYLES 2 -#define META_THEME_DEGREES_IN_ARCS 2 -#define META_THEME_HIDDEN_BUTTONS 2 -#define META_THEME_COLOR_CONSTANTS 2 -#define META_THEME_FRAME_BACKGROUNDS 2 +int meta_theme_get_window_scaling_factor (void); #endif /* META_THEME_PRIVATE_H */ diff --git a/src/ui/theme-viewer.c b/src/ui/theme-viewer.c deleted file mode 100644 index d39e4bf99..000000000 --- a/src/ui/theme-viewer.c +++ /dev/null @@ -1,1360 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Metacity theme viewer and test app main() */ - -/* - * Copyright (C) 2002 Havoc Pennington - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. - */ - -#include <config.h> -#include <meta/util.h> -#include <meta/theme.h> -#include "theme-private.h" -#include <meta/preview-widget.h> -#include <gtk/gtk.h> -#include <time.h> -#include <stdlib.h> -#include <string.h> -#include <glib/gi18n.h> - -/* We need to compute all different button arrangements - * in terms of button location. We don't care about - * different arrangements in terms of button function. - * - * So if dups are allowed, from 0-4 buttons on the left, from 0-4 on - * the right, 5x5=25 combinations. - * - * If no dups, 0-4 on left determines the number on the right plus - * we have a special case for the "no buttons on either side" case. - */ -#ifndef ALLOW_DUPLICATE_BUTTONS -#define BUTTON_LAYOUT_COMBINATIONS (MAX_BUTTONS_PER_CORNER + 1 + 1) -#else -#define BUTTON_LAYOUT_COMBINATIONS ((MAX_BUTTONS_PER_CORNER+1)*(MAX_BUTTONS_PER_CORNER+1)) -#endif - -enum -{ - FONT_SIZE_SMALL, - FONT_SIZE_NORMAL, - FONT_SIZE_LARGE, - FONT_SIZE_LAST -}; - -static MetaTheme *global_theme = NULL; -static GtkWidget *previews[META_FRAME_TYPE_LAST*FONT_SIZE_LAST + BUTTON_LAYOUT_COMBINATIONS] = { NULL, }; -static double milliseconds_to_draw_frame = 0.0; - -static void run_position_expression_tests (void); -#if 0 -static void run_position_expression_timings (void); -#endif -static void run_theme_benchmark (void); - - -static const gchar *menu_item_string = - "<ui>\n" - "<menubar>\n" - "<menu name='Windows' action='Windows'>\n" - "<menuitem name='Dialog' action='Dialog'/>\n" - "<menuitem name='Modal dialog' action='Modal dialog'/>\n" - "<menuitem name='Utility' action='Utility'/>\n" - "<menuitem name='Splashscreen' action='Splashscreen'/>\n" - "<menuitem name='Top dock' action='Top dock'/>\n" - "<menuitem name='Bottom dock' action='Bottom dock'/>\n" - "<menuitem name='Left dock' action='Left dock'/>\n" - "<menuitem name='Right dock' action='Right dock'/>\n" - "<menuitem name='Desktop' action='Desktop'/>\n" - "</menu>\n" - "</menubar>\n" - "<toolbar>\n" - "<separator/>\n" - "<toolitem name='New' action='New'/>\n" - "<toolitem name='Open' action='Open'/>\n" - "<toolitem name='Quit' action='Quit'/>\n" - "<separator/>\n" - "</toolbar>\n" - "</ui>\n"; - -static GtkActionEntry menu_items[] = -{ - { "Windows", NULL, N_("_Windows"), NULL, NULL, NULL }, - { "Dialog", NULL, N_("_Dialog"), "<control>d", NULL, NULL }, - { "Modal dialog", NULL, N_("_Modal dialog"), NULL, NULL, NULL }, - { "Utility", NULL, N_("_Utility"), "<control>u", NULL, NULL }, - { "Splashscreen", NULL, N_("_Splashscreen"), "<control>s", NULL, NULL }, - { "Top dock", NULL, N_("_Top dock"), NULL, NULL, NULL }, - { "Bottom dock", NULL, N_("_Bottom dock"), NULL, NULL, NULL }, - { "Left dock", NULL, N_("_Left dock"), NULL, NULL, NULL }, - { "Right dock", NULL, N_("_Right dock"), NULL, NULL, NULL }, - { "All docks", NULL, N_("_All docks"), NULL, NULL, NULL }, - { "Desktop", NULL, N_("Des_ktop"), NULL, NULL, NULL } -}; - -static GtkActionEntry tool_items[] = -{ - { "New", GTK_STOCK_NEW, NULL, NULL, - N_("Open another one of these windows"), NULL }, - { "Open", GTK_STOCK_OPEN, NULL, NULL, - N_("This is a demo button with an 'open' icon"), NULL }, - { "Quit", GTK_STOCK_QUIT, NULL, NULL, - N_("This is a demo button with a 'quit' icon"), NULL } -}; - -static GtkWidget * -normal_contents (void) -{ - GtkWidget *grid; - GtkWidget *statusbar; - GtkWidget *contents; - GtkWidget *sw; - GtkActionGroup *action_group; - GtkUIManager *ui_manager; - - grid = gtk_grid_new (); - - /* Create the menubar - */ - - action_group = gtk_action_group_new ("mainmenu"); - gtk_action_group_add_actions (action_group, - menu_items, - G_N_ELEMENTS (menu_items), - NULL); - gtk_action_group_add_actions (action_group, - tool_items, - G_N_ELEMENTS (tool_items), - NULL); - - ui_manager = gtk_ui_manager_new (); - - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - - /* create menu items */ - gtk_ui_manager_add_ui_from_string (ui_manager, menu_item_string, -1, NULL); - - gtk_grid_attach (GTK_GRID (grid), - gtk_ui_manager_get_widget (ui_manager, "/ui/menubar"), - 0, 0, 1, 1); - - gtk_widget_set_hexpand (gtk_ui_manager_get_widget (ui_manager, "/ui/menubar"), - TRUE); - - /* Create the toolbar - */ - gtk_grid_attach (GTK_GRID (grid), - gtk_ui_manager_get_widget (ui_manager, "/ui/toolbar"), - 0, 1, 1, 1); - - gtk_widget_set_hexpand (gtk_ui_manager_get_widget (ui_manager, "/ui/toolbar"), - TRUE); - - /* Create document - */ - - sw = gtk_scrolled_window_new (NULL, NULL); - - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), - GTK_SHADOW_IN); - - gtk_grid_attach (GTK_GRID (grid), - sw, - 0, 2, 1, 1); - - gtk_widget_set_hexpand (sw, TRUE); - gtk_widget_set_vexpand (sw, TRUE); - - contents = gtk_text_view_new (); - gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (contents), - PANGO_WRAP_WORD); - - gtk_container_add (GTK_CONTAINER (sw), - contents); - - /* Create statusbar */ - - statusbar = gtk_statusbar_new (); - gtk_grid_attach (GTK_GRID (grid), - statusbar, - 0, 3, 1, 1); - - gtk_widget_set_hexpand (statusbar, TRUE); - - gtk_widget_show_all (grid); - - g_object_unref (ui_manager); - - return grid; -} - -static void -update_spacings (GtkWidget *vbox, - GtkWidget *action_area) -{ - gtk_container_set_border_width (GTK_CONTAINER (vbox), 2); - gtk_box_set_spacing (GTK_BOX (action_area), 10); - gtk_container_set_border_width (GTK_CONTAINER (action_area), 5); -} - -static GtkWidget* -dialog_contents (void) -{ - GtkWidget *vbox; - GtkWidget *hbox; - GtkWidget *action_area; - GtkWidget *label; - GtkWidget *image; - GtkWidget *button; - - vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); - - action_area = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL); - - gtk_button_box_set_layout (GTK_BUTTON_BOX (action_area), - GTK_BUTTONBOX_END); - - button = gtk_button_new_from_stock (GTK_STOCK_OK); - gtk_box_pack_end (GTK_BOX (action_area), - button, - FALSE, TRUE, 0); - - gtk_box_pack_end (GTK_BOX (vbox), action_area, - FALSE, TRUE, 0); - - update_spacings (vbox, action_area); - - label = gtk_label_new (_("This is a sample message in a sample dialog")); - image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_INFO, - GTK_ICON_SIZE_DIALOG); - gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0); - - gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); - gtk_label_set_selectable (GTK_LABEL (label), TRUE); - - hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); - - gtk_box_pack_start (GTK_BOX (hbox), image, - FALSE, FALSE, 0); - - gtk_box_pack_start (GTK_BOX (hbox), label, - TRUE, TRUE, 0); - - gtk_box_pack_start (GTK_BOX (vbox), - hbox, - FALSE, FALSE, 0); - - gtk_widget_show_all (vbox); - - return vbox; -} - -static GtkWidget* -utility_contents (void) -{ - GtkWidget *grid; - GtkWidget *button; - int i, j; - - grid = gtk_grid_new (); - - i = 0; - while (i < 3) - { - j = 0; - while (j < 4) - { - char *str; - - str = g_strdup_printf ("_%c", (char) ('A' + 4*i + j)); - - button = gtk_button_new_with_mnemonic (str); - - free (str); - - gtk_grid_attach (GTK_GRID (grid), - button, - i, j, 1, 1); - - ++j; - } - - ++i; - } - - gtk_widget_show_all (grid); - - return grid; -} - -static GtkWidget* -menu_contents (void) -{ - GtkWidget *vbox; - GtkWidget *mi; - int i; - GtkWidget *frame; - - frame = gtk_frame_new (NULL); - gtk_frame_set_shadow_type (GTK_FRAME (frame), - GTK_SHADOW_OUT); - - vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); - - i = 0; - while (i < 10) - { - char *str = g_strdup_printf (_("Fake menu item %d\n"), i + 1); - mi = gtk_label_new (str); - gtk_misc_set_alignment (GTK_MISC (mi), 0.0, 0.5); - free (str); - gtk_box_pack_start (GTK_BOX (vbox), mi, FALSE, FALSE, 0); - - ++i; - } - - gtk_container_add (GTK_CONTAINER (frame), vbox); - - gtk_widget_show_all (frame); - - return frame; -} - -static GtkWidget* -border_only_contents (void) -{ - GtkWidget *event_box; - GtkWidget *vbox; - GtkWidget *w; - GdkRGBA color; - - event_box = gtk_event_box_new (); - - color.red = 0.6; - color.green = 0; - color.blue = 0.6; - color.alpha = 1.0; - gtk_widget_override_background_color (event_box, 0, &color); - - vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); - gtk_container_set_border_width (GTK_CONTAINER (vbox), 3); - - w = gtk_label_new (_("Border-only window")); - gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 0); - w = gtk_button_new_with_label (_("Bar")); - gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 0); - - gtk_container_add (GTK_CONTAINER (event_box), vbox); - - gtk_widget_show_all (event_box); - - return event_box; -} - -static GtkWidget* -get_window_contents (MetaFrameType type, - const char **title) -{ - switch (type) - { - case META_FRAME_TYPE_NORMAL: - *title = _("Normal Application Window"); - return normal_contents (); - - case META_FRAME_TYPE_DIALOG: - *title = _("Dialog Box"); - return dialog_contents (); - - case META_FRAME_TYPE_MODAL_DIALOG: - *title = _("Modal Dialog Box"); - return dialog_contents (); - - case META_FRAME_TYPE_UTILITY: - *title = _("Utility Palette"); - return utility_contents (); - - case META_FRAME_TYPE_MENU: - *title = _("Torn-off Menu"); - return menu_contents (); - - case META_FRAME_TYPE_BORDER: - *title = _("Border"); - return border_only_contents (); - - case META_FRAME_TYPE_ATTACHED: - *title = _("Attached Modal Dialog"); - return dialog_contents (); - - case META_FRAME_TYPE_LAST: - g_assert_not_reached (); - break; - } - - return NULL; -} - -static MetaFrameFlags -get_window_flags (MetaFrameType type) -{ - MetaFrameFlags flags; - - flags = META_FRAME_ALLOWS_DELETE | - META_FRAME_ALLOWS_MENU | - META_FRAME_ALLOWS_MINIMIZE | - META_FRAME_ALLOWS_MAXIMIZE | - META_FRAME_ALLOWS_VERTICAL_RESIZE | - META_FRAME_ALLOWS_HORIZONTAL_RESIZE | - META_FRAME_HAS_FOCUS | - META_FRAME_ALLOWS_SHADE | - META_FRAME_ALLOWS_MOVE; - - switch (type) - { - case META_FRAME_TYPE_NORMAL: - break; - - case META_FRAME_TYPE_DIALOG: - case META_FRAME_TYPE_MODAL_DIALOG: - flags &= ~(META_FRAME_ALLOWS_MINIMIZE | - META_FRAME_ALLOWS_MAXIMIZE); - break; - - case META_FRAME_TYPE_UTILITY: - flags &= ~(META_FRAME_ALLOWS_MINIMIZE | - META_FRAME_ALLOWS_MAXIMIZE); - break; - - case META_FRAME_TYPE_MENU: - flags &= ~(META_FRAME_ALLOWS_MINIMIZE | - META_FRAME_ALLOWS_MAXIMIZE); - break; - - case META_FRAME_TYPE_BORDER: - break; - - case META_FRAME_TYPE_ATTACHED: - break; - - case META_FRAME_TYPE_LAST: - g_assert_not_reached (); - break; - } - - return flags; -} - -static GtkWidget* -preview_collection (int font_size, - const PangoFontDescription *base_desc) -{ - GtkWidget *box; - GtkWidget *sw; - GdkRGBA desktop_color; - int i; - GtkWidget *eventbox; - - sw = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - - box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); - gtk_box_set_spacing (GTK_BOX (box), 20); - gtk_container_set_border_width (GTK_CONTAINER (box), 20); - - eventbox = gtk_event_box_new (); - gtk_container_add (GTK_CONTAINER (eventbox), box); - gtk_container_add (GTK_CONTAINER (sw), eventbox); - - desktop_color.red = 0.32; - desktop_color.green = 0.46; - desktop_color.blue = 0.65; - desktop_color.alpha = 1.0; - - gtk_widget_override_background_color (eventbox, 0, &desktop_color); - - i = 0; - while (i < META_FRAME_TYPE_LAST) - { - const char *title = NULL; - GtkWidget *contents; - GtkWidget *align; - double xalign, yalign; - GtkWidget *eventbox2; - GtkWidget *preview; - PangoFontDescription *font_desc; - double scale; - - eventbox2 = gtk_event_box_new (); - - preview = meta_preview_new (); - - gtk_container_add (GTK_CONTAINER (eventbox2), preview); - - meta_preview_set_frame_type (META_PREVIEW (preview), i); - meta_preview_set_frame_flags (META_PREVIEW (preview), - get_window_flags (i)); - - meta_preview_set_theme (META_PREVIEW (preview), global_theme); - - contents = get_window_contents (i, &title); - - meta_preview_set_title (META_PREVIEW (preview), title); - - gtk_container_add (GTK_CONTAINER (preview), contents); - - if (i == META_FRAME_TYPE_MENU) - { - xalign = 0.0; - yalign = 0.0; - } - else - { - xalign = 0.5; - yalign = 0.5; - } - - align = gtk_alignment_new (0.0, 0.0, xalign, yalign); - gtk_container_add (GTK_CONTAINER (align), eventbox2); - - gtk_box_pack_start (GTK_BOX (box), align, TRUE, TRUE, 0); - - switch (font_size) - { - case FONT_SIZE_SMALL: - scale = PANGO_SCALE_XX_SMALL; - break; - case FONT_SIZE_LARGE: - scale = PANGO_SCALE_XX_LARGE; - break; - default: - scale = 1.0; - break; - } - - if (scale != 1.0) - { - font_desc = pango_font_description_new (); - - pango_font_description_set_size (font_desc, - MAX (pango_font_description_get_size (base_desc) * scale, 1)); - - gtk_widget_override_font (preview, font_desc); - - pango_font_description_free (font_desc); - } - - previews[font_size*META_FRAME_TYPE_LAST + i] = preview; - - ++i; - } - - return sw; -} - -static MetaButtonLayout different_layouts[BUTTON_LAYOUT_COMBINATIONS]; - -static void -init_layouts (void) -{ - int i; - - /* Blank out all the layouts */ - i = 0; - while (i < (int) G_N_ELEMENTS (different_layouts)) - { - int j; - - j = 0; - while (j < MAX_BUTTONS_PER_CORNER) - { - different_layouts[i].left_buttons[j] = META_BUTTON_FUNCTION_LAST; - different_layouts[i].right_buttons[j] = META_BUTTON_FUNCTION_LAST; - ++j; - } - ++i; - } - -#ifndef ALLOW_DUPLICATE_BUTTONS - i = 0; - while (i <= MAX_BUTTONS_PER_CORNER) - { - int j; - - j = 0; - while (j < i) - { - different_layouts[i].right_buttons[j] = (MetaButtonFunction) j; - ++j; - } - while (j < MAX_BUTTONS_PER_CORNER) - { - different_layouts[i].left_buttons[j-i] = (MetaButtonFunction) j; - ++j; - } - - ++i; - } - - /* Special extra case for no buttons on either side */ - different_layouts[i].left_buttons[0] = META_BUTTON_FUNCTION_LAST; - different_layouts[i].right_buttons[0] = META_BUTTON_FUNCTION_LAST; - -#else - /* FIXME this code is if we allow duplicate buttons, - * which we currently do not - */ - int left; - int i; - - left = 0; - i = 0; - - while (left < MAX_BUTTONS_PER_CORNER) - { - int right; - - right = 0; - - while (right < MAX_BUTTONS_PER_CORNER) - { - int j; - - static MetaButtonFunction left_functions[MAX_BUTTONS_PER_CORNER] = { - META_BUTTON_FUNCTION_MENU, - META_BUTTON_FUNCTION_MINIMIZE, - META_BUTTON_FUNCTION_MAXIMIZE, - META_BUTTON_FUNCTION_CLOSE - }; - static MetaButtonFunction right_functions[MAX_BUTTONS_PER_CORNER] = { - META_BUTTON_FUNCTION_MINIMIZE, - META_BUTTON_FUNCTION_MAXIMIZE, - META_BUTTON_FUNCTION_CLOSE, - META_BUTTON_FUNCTION_MENU - }; - - g_assert (i < BUTTON_LAYOUT_COMBINATIONS); - - j = 0; - while (j <= left) - { - different_layouts[i].left_buttons[j] = left_functions[j]; - ++j; - } - - j = 0; - while (j <= right) - { - different_layouts[i].right_buttons[j] = right_functions[j]; - ++j; - } - - ++i; - - ++right; - } - - ++left; - } -#endif -} - - -static GtkWidget* -previews_of_button_layouts (void) -{ - static gboolean initted = FALSE; - GtkWidget *box; - GtkWidget *sw; - GdkRGBA desktop_color; - int i; - GtkWidget *eventbox; - - if (!initted) - { - init_layouts (); - initted = TRUE; - } - - sw = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - - box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); - gtk_box_set_spacing (GTK_BOX (box), 20); - gtk_container_set_border_width (GTK_CONTAINER (box), 20); - - eventbox = gtk_event_box_new (); - gtk_container_add (GTK_CONTAINER (eventbox), box); - gtk_container_add (GTK_CONTAINER (sw), eventbox); - - desktop_color.red = 0.32; - desktop_color.green = 0.46; - desktop_color.blue = 0.65; - desktop_color.alpha = 1.0; - - gtk_widget_override_background_color (eventbox, 0, &desktop_color); - - i = 0; - while (i < BUTTON_LAYOUT_COMBINATIONS) - { - GtkWidget *align; - double xalign, yalign; - GtkWidget *eventbox2; - GtkWidget *preview; - char *title; - - eventbox2 = gtk_event_box_new (); - - preview = meta_preview_new (); - - gtk_container_add (GTK_CONTAINER (eventbox2), preview); - - meta_preview_set_theme (META_PREVIEW (preview), global_theme); - - title = g_strdup_printf (_("Button layout test %d"), i+1); - meta_preview_set_title (META_PREVIEW (preview), title); - free (title); - - meta_preview_set_button_layout (META_PREVIEW (preview), - &different_layouts[i]); - - xalign = 0.5; - yalign = 0.5; - - align = gtk_alignment_new (0.0, 0.0, xalign, yalign); - gtk_container_add (GTK_CONTAINER (align), eventbox2); - - gtk_box_pack_start (GTK_BOX (box), align, TRUE, TRUE, 0); - - previews[META_FRAME_TYPE_LAST*FONT_SIZE_LAST + i] = preview; - - ++i; - } - - return sw; -} - -static GtkWidget* -benchmark_summary (void) -{ - char *msg; - GtkWidget *label; - - msg = g_strdup_printf (_("%g milliseconds to draw one window frame"), - milliseconds_to_draw_frame); - label = gtk_label_new (msg); - free (msg); - - return label; -} - -int -main (int argc, char **argv) -{ - GtkStyleContext *style; - PangoFontDescription *font_desc; - GtkWidget *window; - GtkWidget *collection; - GError *err; - clock_t start, end; - GtkWidget *notebook; - int i; - - bindtextdomain (GETTEXT_PACKAGE, MUFFIN_LOCALEDIR); - textdomain(GETTEXT_PACKAGE); - bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); - - run_position_expression_tests (); -#if 0 - run_position_expression_timings (); -#endif - - gtk_init (&argc, &argv); - - if (g_getenv ("MUFFIN_DEBUG") != NULL) - { - meta_set_debugging (TRUE); - meta_set_verbose (TRUE); - } - - start = clock (); - err = NULL; - if (argc == 1) - global_theme = meta_theme_load ("Atlanta", &err); - else if (argc == 2) - global_theme = meta_theme_load (argv[1], &err); - else - { - g_printerr (_("Usage: metacity-theme-viewer [THEMENAME]\n")); - exit (1); - } - end = clock (); - - if (global_theme == NULL) - { - g_printerr (_("Error loading theme: %s\n"), - err->message); - g_error_free (err); - exit (1); - } - - g_print (_("Loaded theme \"%s\" in %g seconds\n"), - global_theme->name, - (end - start) / (double) CLOCKS_PER_SEC); - - run_theme_benchmark (); - - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_window_set_default_size (GTK_WINDOW (window), 350, 350); - - if (strcmp (global_theme->name, global_theme->readable_name)==0) - gtk_window_set_title (GTK_WINDOW (window), - global_theme->readable_name); - else - { - /* The theme directory name is different from the name the theme - * gives itself within its file. Display both, directory name first. - */ - gchar *title = g_strconcat (global_theme->name, " - ", - global_theme->readable_name, - NULL); - - gtk_window_set_title (GTK_WINDOW (window), - title); - - free (title); - } - - g_signal_connect (G_OBJECT (window), "destroy", - G_CALLBACK (gtk_main_quit), NULL); - - gtk_widget_realize (window); - style = gtk_widget_get_style_context (window); - gtk_style_context_get (style, GTK_STATE_FLAG_NORMAL, - GTK_STYLE_PROPERTY_FONT, &font_desc, - NULL); - - g_assert (style); - g_assert (font_desc); - - notebook = gtk_notebook_new (); - gtk_container_add (GTK_CONTAINER (window), notebook); - - collection = preview_collection (FONT_SIZE_NORMAL, - font_desc); - gtk_notebook_append_page (GTK_NOTEBOOK (notebook), - collection, - gtk_label_new (_("Normal Title Font"))); - - collection = preview_collection (FONT_SIZE_SMALL, - font_desc); - gtk_notebook_append_page (GTK_NOTEBOOK (notebook), - collection, - gtk_label_new (_("Small Title Font"))); - - collection = preview_collection (FONT_SIZE_LARGE, - font_desc); - gtk_notebook_append_page (GTK_NOTEBOOK (notebook), - collection, - gtk_label_new (_("Large Title Font"))); - - collection = previews_of_button_layouts (); - gtk_notebook_append_page (GTK_NOTEBOOK (notebook), - collection, - gtk_label_new (_("Button Layouts"))); - - collection = benchmark_summary (); - gtk_notebook_append_page (GTK_NOTEBOOK (notebook), - collection, - gtk_label_new (_("Benchmark"))); - - pango_font_description_free (font_desc); - - i = 0; - while (i < (int) G_N_ELEMENTS (previews)) - { - /* preview widget likes to be realized before its size request. - * it's lame that way. - */ - gtk_widget_realize (previews[i]); - - ++i; - } - - gtk_widget_show_all (window); - - gtk_main (); - - return 0; -} - - -static MetaFrameFlags -get_flags (GtkWidget *widget) -{ - return META_FRAME_ALLOWS_DELETE | - META_FRAME_ALLOWS_MENU | - META_FRAME_ALLOWS_MINIMIZE | - META_FRAME_ALLOWS_MAXIMIZE | - META_FRAME_ALLOWS_VERTICAL_RESIZE | - META_FRAME_ALLOWS_HORIZONTAL_RESIZE | - META_FRAME_HAS_FOCUS | - META_FRAME_ALLOWS_SHADE | - META_FRAME_ALLOWS_MOVE; -} - -static int -get_text_height (GtkWidget *widget) -{ - GtkStyleContext *style; - PangoFontDescription *font_desc; - int text_height; - - style = gtk_widget_get_style_context (widget); - gtk_style_context_get (style, GTK_STATE_FLAG_NORMAL, - GTK_STYLE_PROPERTY_FONT, &font_desc, - NULL); - - text_height = meta_pango_font_desc_get_text_height (font_desc, - gtk_widget_get_pango_context (widget)); - pango_font_description_free (font_desc); - return text_height; -} - -static PangoLayout* -create_title_layout (GtkWidget *widget) -{ - PangoLayout *layout; - - layout = gtk_widget_create_pango_layout (widget, _("Window Title Goes Here")); - - return layout; -} - -static void -run_theme_benchmark (void) -{ - GtkWidget* widget; - cairo_surface_t *pixmap; - MetaFrameBorders borders; - MetaButtonState button_states[META_BUTTON_TYPE_LAST] = - { - META_BUTTON_STATE_NORMAL, - META_BUTTON_STATE_NORMAL, - META_BUTTON_STATE_NORMAL, - META_BUTTON_STATE_NORMAL - }; - PangoLayout *layout; - clock_t start; - clock_t end; - GTimer *timer; - int i; - MetaButtonLayout button_layout; -#define ITERATIONS 100 - int client_width; - int client_height; - cairo_t *cr; - int inc; - - widget = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_widget_realize (widget); - - meta_theme_get_frame_borders (global_theme, - META_FRAME_TYPE_NORMAL, - get_text_height (widget), - get_flags (widget), - &borders); - - layout = create_title_layout (widget); - - i = 0; - while (i < MAX_BUTTONS_PER_CORNER) - { - button_layout.left_buttons[i] = META_BUTTON_FUNCTION_LAST; - button_layout.right_buttons[i] = META_BUTTON_FUNCTION_LAST; - ++i; - } - - button_layout.left_buttons[0] = META_BUTTON_FUNCTION_MENU; - - button_layout.right_buttons[0] = META_BUTTON_FUNCTION_MINIMIZE; - button_layout.right_buttons[1] = META_BUTTON_FUNCTION_MAXIMIZE; - button_layout.right_buttons[2] = META_BUTTON_FUNCTION_CLOSE; - - timer = g_timer_new (); - start = clock (); - - client_width = 50; - client_height = 50; - inc = 1000 / ITERATIONS; /* Increment to grow width/height, - * eliminates caching effects. - */ - - i = 0; - while (i < ITERATIONS) - { - /* Creating the pixmap in the loop is right, since - * GDK does the same with its double buffering. - */ - pixmap = gdk_window_create_similar_surface (gtk_widget_get_window (widget), - CAIRO_CONTENT_COLOR, - client_width + borders.total.left + borders.total.right, - client_height + borders.total.top + borders.total.bottom); - - cr = cairo_create (pixmap); - - meta_theme_draw_frame (global_theme, - widget, - cr, - META_FRAME_TYPE_NORMAL, - get_flags (widget), - client_width, client_height, - layout, - get_text_height (widget), - &button_layout, - button_states); - cairo_destroy (cr); - cairo_surface_destroy (pixmap); - - ++i; - client_width += inc; - client_height += inc; - } - - end = clock (); - g_timer_stop (timer); - - milliseconds_to_draw_frame = (g_timer_elapsed (timer, NULL) / (double) ITERATIONS) * 1000; - - g_print (_("Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g seconds wall clock time including X server resources (%g milliseconds per frame)\n"), - ITERATIONS, - ((double)end - (double)start) / CLOCKS_PER_SEC, - (((double)end - (double)start) / CLOCKS_PER_SEC / (double) ITERATIONS) * 1000, - g_timer_elapsed (timer, NULL), - milliseconds_to_draw_frame); - - g_timer_destroy (timer); - g_object_unref (G_OBJECT (layout)); - gtk_widget_destroy (widget); - -#undef ITERATIONS -} - -typedef struct -{ - GdkRectangle rect; - const char *expr; - int expected_x; - int expected_y; - MetaThemeError expected_error; -} PositionExpressionTest; - -#define NO_ERROR -1 - -static const PositionExpressionTest position_expression_tests[] = { - /* Just numbers */ - { { 10, 20, 40, 50 }, - "10", 20, 30, NO_ERROR }, - { { 10, 20, 40, 50 }, - "14.37", 24, 34, NO_ERROR }, - /* Binary expressions with 2 ints */ - { { 10, 20, 40, 50 }, - "14 * 10", 150, 160, NO_ERROR }, - { { 10, 20, 40, 50 }, - "14 + 10", 34, 44, NO_ERROR }, - { { 10, 20, 40, 50 }, - "14 - 10", 14, 24, NO_ERROR }, - { { 10, 20, 40, 50 }, - "8 / 2", 14, 24, NO_ERROR }, - { { 10, 20, 40, 50 }, - "8 % 3", 12, 22, NO_ERROR }, - /* Binary expressions with floats and mixed float/ints */ - { { 10, 20, 40, 50 }, - "7.0 / 3.5", 12, 22, NO_ERROR }, - { { 10, 20, 40, 50 }, - "12.1 / 3", 14, 24, NO_ERROR }, - { { 10, 20, 40, 50 }, - "12 / 2.95", 14, 24, NO_ERROR }, - /* Binary expressions without whitespace after first number */ - { { 10, 20, 40, 50 }, - "14* 10", 150, 160, NO_ERROR }, - { { 10, 20, 40, 50 }, - "14+ 10", 34, 44, NO_ERROR }, - { { 10, 20, 40, 50 }, - "14- 10", 14, 24, NO_ERROR }, - { { 10, 20, 40, 50 }, - "8/ 2", 14, 24, NO_ERROR }, - { { 10, 20, 40, 50 }, - "7.0/ 3.5", 12, 22, NO_ERROR }, - { { 10, 20, 40, 50 }, - "12.1/ 3", 14, 24, NO_ERROR }, - { { 10, 20, 40, 50 }, - "12/ 2.95", 14, 24, NO_ERROR }, - /* Binary expressions without whitespace before second number */ - { { 10, 20, 40, 50 }, - "14 *10", 150, 160, NO_ERROR }, - { { 10, 20, 40, 50 }, - "14 +10", 34, 44, NO_ERROR }, - { { 10, 20, 40, 50 }, - "14 -10", 14, 24, NO_ERROR }, - { { 10, 20, 40, 50 }, - "8 /2", 14, 24, NO_ERROR }, - { { 10, 20, 40, 50 }, - "7.0 /3.5", 12, 22, NO_ERROR }, - { { 10, 20, 40, 50 }, - "12.1 /3", 14, 24, NO_ERROR }, - { { 10, 20, 40, 50 }, - "12 /2.95", 14, 24, NO_ERROR }, - /* Binary expressions without any whitespace */ - { { 10, 20, 40, 50 }, - "14*10", 150, 160, NO_ERROR }, - { { 10, 20, 40, 50 }, - "14+10", 34, 44, NO_ERROR }, - { { 10, 20, 40, 50 }, - "14-10", 14, 24, NO_ERROR }, - { { 10, 20, 40, 50 }, - "8/2", 14, 24, NO_ERROR }, - { { 10, 20, 40, 50 }, - "7.0/3.5", 12, 22, NO_ERROR }, - { { 10, 20, 40, 50 }, - "12.1/3", 14, 24, NO_ERROR }, - { { 10, 20, 40, 50 }, - "12/2.95", 14, 24, NO_ERROR }, - /* Binary expressions with parentheses */ - { { 10, 20, 40, 50 }, - "(14) * (10)", 150, 160, NO_ERROR }, - { { 10, 20, 40, 50 }, - "(14) + (10)", 34, 44, NO_ERROR }, - { { 10, 20, 40, 50 }, - "(14) - (10)", 14, 24, NO_ERROR }, - { { 10, 20, 40, 50 }, - "(8) / (2)", 14, 24, NO_ERROR }, - { { 10, 20, 40, 50 }, - "(7.0) / (3.5)", 12, 22, NO_ERROR }, - { { 10, 20, 40, 50 }, - "(12.1) / (3)", 14, 24, NO_ERROR }, - { { 10, 20, 40, 50 }, - "(12) / (2.95)", 14, 24, NO_ERROR }, - /* Lots of extra parentheses */ - { { 10, 20, 40, 50 }, - "(((14)) * ((10)))", 150, 160, NO_ERROR }, - { { 10, 20, 40, 50 }, - "((((14)))) + ((((((((10))))))))", 34, 44, NO_ERROR }, - { { 10, 20, 40, 50 }, - "((((((((((14 - 10))))))))))", 14, 24, NO_ERROR }, - /* Binary expressions with variables */ - { { 10, 20, 40, 50 }, - "2 * width", 90, 100, NO_ERROR }, - { { 10, 20, 40, 50 }, - "2 * height", 110, 120, NO_ERROR }, - { { 10, 20, 40, 50 }, - "width - 10", 40, 50, NO_ERROR }, - { { 10, 20, 40, 50 }, - "height / 2", 35, 45, NO_ERROR }, - /* More than two operands */ - { { 10, 20, 40, 50 }, - "8 / 2 + 5", 19, 29, NO_ERROR }, - { { 10, 20, 40, 50 }, - "8 * 2 + 5", 31, 41, NO_ERROR }, - { { 10, 20, 40, 50 }, - "8 + 2 * 5", 28, 38, NO_ERROR }, - { { 10, 20, 40, 50 }, - "8 + 8 / 2", 22, 32, NO_ERROR }, - { { 10, 20, 40, 50 }, - "14 / (2 + 5)", 12, 22, NO_ERROR }, - { { 10, 20, 40, 50 }, - "8 * (2 + 5)", 66, 76, NO_ERROR }, - { { 10, 20, 40, 50 }, - "(8 + 2) * 5", 60, 70, NO_ERROR }, - { { 10, 20, 40, 50 }, - "(8 + 8) / 2", 18, 28, NO_ERROR }, - /* Errors */ - { { 10, 20, 40, 50 }, - "2 * foo", 0, 0, META_THEME_ERROR_UNKNOWN_VARIABLE }, - { { 10, 20, 40, 50 }, - "2 *", 0, 0, META_THEME_ERROR_FAILED }, - { { 10, 20, 40, 50 }, - "- width", 0, 0, META_THEME_ERROR_FAILED }, - { { 10, 20, 40, 50 }, - "5 % 1.0", 0, 0, META_THEME_ERROR_MOD_ON_FLOAT }, - { { 10, 20, 40, 50 }, - "1.0 % 5", 0, 0, META_THEME_ERROR_MOD_ON_FLOAT }, - { { 10, 20, 40, 50 }, - "! * 2", 0, 0, META_THEME_ERROR_BAD_CHARACTER }, - { { 10, 20, 40, 50 }, - " ", 0, 0, META_THEME_ERROR_FAILED }, - { { 10, 20, 40, 50 }, - "() () (( ) ()) ((()))", 0, 0, META_THEME_ERROR_FAILED }, - { { 10, 20, 40, 50 }, - "(*) () ((/) ()) ((()))", 0, 0, META_THEME_ERROR_FAILED }, - { { 10, 20, 40, 50 }, - "2 * 5 /", 0, 0, META_THEME_ERROR_FAILED }, - { { 10, 20, 40, 50 }, - "+ 2 * 5", 0, 0, META_THEME_ERROR_FAILED }, - { { 10, 20, 40, 50 }, - "+ 2 * 5", 0, 0, META_THEME_ERROR_FAILED } -}; - -static void -run_position_expression_tests (void) -{ -#if 0 - int i; - MetaPositionExprEnv env; - - i = 0; - while (i < (int) G_N_ELEMENTS (position_expression_tests)) - { - GError *err; - gboolean retval; - const PositionExpressionTest *test; - PosToken *tokens; - int n_tokens; - int x, y; - - test = &position_expression_tests[i]; - - if (g_getenv ("META_PRINT_TESTS") != NULL) - g_print ("Test expression: \"%s\" expecting x = %d y = %d", - test->expr, test->expected_x, test->expected_y); - - err = NULL; - - env.rect = meta_rect (test->rect.x, test->rect.y, - test->rect.width, test->rect.height); - env.object_width = -1; - env.object_height = -1; - env.left_width = 0; - env.right_width = 0; - env.top_height = 0; - env.bottom_height = 0; - env.title_width = 5; - env.title_height = 5; - env.icon_width = 32; - env.icon_height = 32; - env.mini_icon_width = 16; - env.mini_icon_height = 16; - env.theme = NULL; - - if (err == NULL) - { - retval = meta_parse_position_expression (tokens, n_tokens, - &env, - &x, &y, - &err); - } - - if (retval && err) - g_error (_("position expression test returned TRUE but set error")); - if (!retval && err == NULL) - g_error (_("position expression test returned FALSE but didn't set error")); - if (((int) test->expected_error) != NO_ERROR) - { - if (err == NULL) - g_error (_("Error was expected but none given")); - if (err->code != (int) test->expected_error) - g_error (_("Error %d was expected but %d given"), - test->expected_error, err->code); - } - else - { - if (err) - g_error (_("Error not expected but one was returned: %s"), - err->message); - - if (x != test->expected_x) - g_error (_("x value was %d, %d was expected"), x, test->expected_x); - - if (y != test->expected_y) - g_error (_("y value was %d, %d was expected"), y, test->expected_y); - } - - if (err) - g_error_free (err); - - meta_pos_tokens_free (tokens, n_tokens); - ++i; - } -#endif -} - -#if 0 -static void -run_position_expression_timings (void) -{ - int i; - int iters; - clock_t start; - clock_t end; - MetaPositionExprEnv env; - -#define ITERATIONS 100000 - - start = clock (); - - iters = 0; - i = 0; - while (iters < ITERATIONS) - { - const PositionExpressionTest *test; - int x, y; - - test = &position_expression_tests[i]; - - env.x = test->rect.x; - env.y = test->rect.y; - env.width = test->rect.width; - env.height = test->rect.height; - env.object_width = -1; - env.object_height = -1; - env.left_width = 0; - env.right_width = 0; - env.top_height = 0; - env.bottom_height = 0; - env.title_width = 5; - env.title_height = 5; - env.icon_width = 32; - env.icon_height = 32; - env.mini_icon_width = 16; - env.mini_icon_height = 16; - env.theme = NULL; - - meta_parse_position_expression (test->expr, - &env, - &x, &y, NULL); - - ++iters; - ++i; - if (i == G_N_ELEMENTS (position_expression_tests)) - i = 0; - } - - end = clock (); - - g_print (_("%d coordinate expressions parsed in %g seconds (%g seconds average)\n"), - ITERATIONS, - ((double)end - (double)start) / CLOCKS_PER_SEC, - ((double)end - (double)start) / CLOCKS_PER_SEC / (double) ITERATIONS); - -} -#endif diff --git a/src/ui/theme.c b/src/ui/theme.c index 99ea519cc..3f8d728e8 100644 --- a/src/ui/theme.c +++ b/src/ui/theme.c @@ -1,7 +1,5 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* Metacity Theme Rendering */ - /* * Copyright (C) 2001 Havoc Pennington * @@ -16,396 +14,60 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. - */ - -/** - * SECTION:theme - * @short_description: Making Metacity look pretty - * - * The window decorations drawn by Metacity are described by files on disk - * known internally as "themes" (externally as "window border themes" on - * http://art.gnome.org/themes/metacity/ or "Metacity themes"). This file - * contains most of the code necessary to support themes; it does not - * contain the XML parser, which is in theme-parser.c. - * - * \bug This is a big file with lots of different subsystems, which might - * be better split out into separate files. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ -/* - * \defgroup tokenizer The theme expression tokenizer - * - * Themes can use a simple expression language to represent the values of - * things. This is the tokeniser used for that language. - * - * \bug We could remove almost all this code by using GScanner instead, - * but we would also have to find every expression in every existing theme - * we could and make sure the parse trees were the same. - */ +#include "config.h" -/* - * \defgroup parser The theme expression parser - * - * Themes can use a simple expression language to represent the values of - * things. This is the parser used for that language. - */ +#include "ui/theme-private.h" -#include <config.h> -#include "theme-private.h" -#include "util-private.h" -#include <meta/gradient.h> -#include <meta/prefs.h> #include <gtk/gtk.h> -#include <string.h> -#include <stdlib.h> #include <math.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> -#define GDK_COLOR_RGBA(color) \ - ((guint32) (0xff | \ - ((int)((color).red * 255) << 24) | \ - ((int)((color).green * 255) << 16) | \ - ((int)((color).blue * 255) << 8))) - -#define GDK_COLOR_RGB(color) \ - ((guint32) (((int)((color).red * 255) << 16) | \ - ((int)((color).green * 255) << 8) | \ - ((int)((color).blue * 255)))) - -#define ALPHA_TO_UCHAR(d) ((unsigned char) ((d) * 255)) - -#define DEBUG_FILL_STRUCT(s) memset ((s), 0xef, sizeof (*(s))) -#define CLAMP_UCHAR(v) ((guchar) (CLAMP (((int)v), (int)0, (int)255))) -#define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11) - -static void gtk_style_shade (GdkRGBA *a, - GdkRGBA *b, - gdouble k); -static void rgb_to_hls (gdouble *r, - gdouble *g, - gdouble *b); -static void hls_to_rgb (gdouble *h, - gdouble *l, - gdouble *s); - -/* - * The current theme. (Themes are singleton.) - */ -static MetaTheme *meta_current_theme = NULL; - -static GdkPixbuf * -colorize_pixbuf (GdkPixbuf *orig, - GdkRGBA *new_color) -{ - GdkPixbuf *pixbuf; - double intensity; - int x, y; - const guchar *src; - guchar *dest; - int orig_rowstride; - int dest_rowstride; - int width, height; - gboolean has_alpha; - const guchar *src_pixels; - guchar *dest_pixels; - - pixbuf = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (orig), gdk_pixbuf_get_has_alpha (orig), - gdk_pixbuf_get_bits_per_sample (orig), - gdk_pixbuf_get_width (orig), gdk_pixbuf_get_height (orig)); - - if (pixbuf == NULL) - return NULL; - - orig_rowstride = gdk_pixbuf_get_rowstride (orig); - dest_rowstride = gdk_pixbuf_get_rowstride (pixbuf); - width = gdk_pixbuf_get_width (pixbuf); - height = gdk_pixbuf_get_height (pixbuf); - has_alpha = gdk_pixbuf_get_has_alpha (orig); - src_pixels = gdk_pixbuf_get_pixels (orig); - dest_pixels = gdk_pixbuf_get_pixels (pixbuf); - - for (y = 0; y < height; y++) - { - src = src_pixels + y * orig_rowstride; - dest = dest_pixels + y * dest_rowstride; - - for (x = 0; x < width; x++) - { - double dr, dg, db; - - intensity = INTENSITY (src[0], src[1], src[2]) / 255.0; - - if (intensity <= 0.5) - { - /* Go from black at intensity = 0.0 to new_color at intensity = 0.5 */ - dr = new_color->red * intensity * 2.0; - dg = new_color->green * intensity * 2.0; - db = new_color->blue * intensity * 2.0; - } - else - { - /* Go from new_color at intensity = 0.5 to white at intensity = 1.0 */ - dr = new_color->red + (1.0 - new_color->red) * (intensity - 0.5) * 2.0; - dg = new_color->green + (1.0 - new_color->green) * (intensity - 0.5) * 2.0; - db = new_color->blue + (1.0 - new_color->blue) * (intensity - 0.5) * 2.0; - } - - dest[0] = CLAMP_UCHAR (255 * dr); - dest[1] = CLAMP_UCHAR (255 * dg); - dest[2] = CLAMP_UCHAR (255 * db); - - if (has_alpha) - { - dest[3] = src[3]; - src += 4; - dest += 4; - } - else - { - src += 3; - dest += 3; - } - } - } - - return pixbuf; -} - -static void -color_composite (const GdkRGBA *bg, - const GdkRGBA *fg, - double alpha, - GdkRGBA *color) -{ - *color = *bg; - color->red = color->red + (fg->red - color->red) * alpha; - color->green = color->green + (fg->green - color->green) * alpha; - color->blue = color->blue + (fg->blue - color->blue) * alpha; -} +#include "core/util-private.h" +#include "meta/prefs.h" +#include "ui/frames.h" -/* - * Sets all the fields of a border to dummy values. - * - * \param border The border whose fields should be reset. - */ -static void -init_border (GtkBorder *border) -{ - border->top = -1; - border->bottom = -1; - border->left = -1; - border->right = -1; -} +static void scale_border (GtkBorder *border, double factor); -/** - * meta_frame_layout_new: (skip) - * - * Creates a new, empty MetaFrameLayout. The fields will be set to dummy - * values. - * - * Returns: The newly created MetaFrameLayout. - */ -LOCAL_SYMBOL MetaFrameLayout* +static MetaFrameLayout * meta_frame_layout_new (void) { MetaFrameLayout *layout; layout = g_new0 (MetaFrameLayout, 1); - layout->refcount = 1; - - /* Fill with -1 values to detect invalid themes */ - layout->left_width = -1; - layout->right_width = -1; - layout->bottom_height = -1; - - init_border (&layout->title_border); - - layout->title_vertical_pad = -1; - - layout->right_titlebar_edge = -1; - layout->left_titlebar_edge = -1; - - layout->button_sizing = META_BUTTON_SIZING_LAST; - layout->button_aspect = 1.0; - layout->button_width = -1; - layout->button_height = -1; - + /* Spacing as hardcoded in GTK+: + * https://git.gnome.org/browse/gtk+/tree/gtk/gtkheaderbar.c?h=gtk-3-14#n53 + */ + layout->titlebar_spacing = 6; layout->has_title = TRUE; - layout->title_scale = 1.0; - - init_border (&layout->button_border); - - return layout; -} - -/* - * - */ -static gboolean -validate_border (const GtkBorder *border, - const char **bad) -{ - *bad = NULL; - - if (border->top < 0) - *bad = _("top"); - else if (border->bottom < 0) - *bad = _("bottom"); - else if (border->left < 0) - *bad = _("left"); - else if (border->right < 0) - *bad = _("right"); - - return *bad == NULL; -} - -/* - * Ensures that the theme supplied a particular dimension. When a - * MetaFrameLayout is created, all its integer fields are set to -1 - * by meta_frame_layout_new(). After an instance of this type - * should have been initialised, this function checks that - * a given field is not still at -1. It is never called directly, but - * rather via the CHECK_GEOMETRY_VALUE and CHECK_GEOMETRY_BORDER - * macros. - * - * \param val The value to check - * \param name The name to use in the error message - * \param[out] error Set to an error if val was not initialised - */ -static gboolean -validate_geometry_value (int val, - const char *name, - GError **error) -{ - if (val < 0) - { - g_set_error (error, META_THEME_ERROR, - META_THEME_ERROR_FRAME_GEOMETRY, - _("frame geometry does not specify \"%s\" dimension"), - name); - return FALSE; - } - else - return TRUE; -} - -static gboolean -validate_geometry_border (const GtkBorder *border, - const char *name, - GError **error) -{ - const char *bad; - - if (!validate_border (border, &bad)) - { - g_set_error (error, META_THEME_ERROR, - META_THEME_ERROR_FRAME_GEOMETRY, - _("frame geometry does not specify dimension \"%s\" for border \"%s\""), - bad, name); - return FALSE; - } - else - return TRUE; -} - -LOCAL_SYMBOL gboolean -meta_frame_layout_validate (const MetaFrameLayout *layout, - GError **error) -{ - g_return_val_if_fail (layout != NULL, FALSE); - -#define CHECK_GEOMETRY_VALUE(vname) if (!validate_geometry_value (layout->vname, #vname, error)) return FALSE - -#define CHECK_GEOMETRY_BORDER(bname) if (!validate_geometry_border (&layout->bname, #bname, error)) return FALSE - - CHECK_GEOMETRY_VALUE (left_width); - CHECK_GEOMETRY_VALUE (right_width); - CHECK_GEOMETRY_VALUE (bottom_height); - - CHECK_GEOMETRY_BORDER (title_border); - - CHECK_GEOMETRY_VALUE (title_vertical_pad); - - CHECK_GEOMETRY_VALUE (right_titlebar_edge); - CHECK_GEOMETRY_VALUE (left_titlebar_edge); - - switch (layout->button_sizing) - { - case META_BUTTON_SIZING_ASPECT: - if (layout->button_aspect < (0.1) || - layout->button_aspect > (15.0)) - { - g_set_error (error, META_THEME_ERROR, - META_THEME_ERROR_FRAME_GEOMETRY, - _("Button aspect ratio %g is not reasonable"), - layout->button_aspect); - return FALSE; - } - break; - case META_BUTTON_SIZING_FIXED: - CHECK_GEOMETRY_VALUE (button_width); - CHECK_GEOMETRY_VALUE (button_height); - break; - case META_BUTTON_SIZING_LAST: - g_set_error (error, META_THEME_ERROR, - META_THEME_ERROR_FRAME_GEOMETRY, - _("Frame geometry does not specify size of buttons")); - return FALSE; - } - - CHECK_GEOMETRY_BORDER (button_border); - - return TRUE; -} - -LOCAL_SYMBOL MetaFrameLayout* -meta_frame_layout_copy (const MetaFrameLayout *src) -{ - MetaFrameLayout *layout; - - layout = g_new0 (MetaFrameLayout, 1); - - *layout = *src; - - layout->refcount = 1; + layout->title_scale = PANGO_SCALE_MEDIUM; + layout->icon_size = META_MINI_ICON_WIDTH; return layout; } -LOCAL_SYMBOL void -meta_frame_layout_ref (MetaFrameLayout *layout) -{ - g_return_if_fail (layout != NULL); - - layout->refcount += 1; -} - -LOCAL_SYMBOL void -meta_frame_layout_unref (MetaFrameLayout *layout) +static void +meta_frame_layout_free (MetaFrameLayout *layout) { g_return_if_fail (layout != NULL); - g_return_if_fail (layout->refcount > 0); - - layout->refcount -= 1; - if (layout->refcount == 0) - { - DEBUG_FILL_STRUCT (layout); - free (layout); - } + g_free (layout); } -LOCAL_SYMBOL void +static void meta_frame_layout_get_borders (const MetaFrameLayout *layout, int text_height, MetaFrameFlags flags, MetaFrameType type, MetaFrameBorders *borders) { - int buttons_height, title_height, draggable_borders; + int buttons_height, content_height, draggable_borders; + int scale = meta_theme_get_window_scaling_factor (); meta_frame_borders_clear (borders); @@ -417,77 +79,78 @@ meta_frame_layout_get_borders (const MetaFrameLayout *layout, if (!layout->has_title) text_height = 0; + else + text_height = layout->title_margin.top + text_height + layout->title_margin.bottom; - buttons_height = layout->button_height + - layout->button_border.top + layout->button_border.bottom; - title_height = text_height + - layout->title_vertical_pad + - layout->title_border.top + layout->title_border.bottom; + buttons_height = MAX ((int)layout->icon_size, layout->button_min_size.height) + + layout->button_margin.top + layout->button_border.top + + layout->button_margin.bottom + layout->button_border.bottom; + content_height = MAX (buttons_height, text_height); + content_height = MAX (content_height, layout->titlebar_min_size.height) + + layout->titlebar_border.top + layout->titlebar_border.bottom; - borders->visible.top = MAX (buttons_height, title_height); - borders->visible.left = layout->left_width; - borders->visible.right = layout->right_width; - borders->visible.bottom = layout->bottom_height; + borders->visible.top = layout->frame_border.top + content_height; + borders->visible.left = layout->frame_border.left; + borders->visible.right = layout->frame_border.right; + borders->visible.bottom = layout->frame_border.bottom; - draggable_borders = meta_prefs_get_draggable_border_width (); + borders->invisible = layout->invisible_border; - if (flags & META_FRAME_ALLOWS_TOP_RESIZE) - { - if (type != META_FRAME_TYPE_ATTACHED) - borders->invisible.top = MAX (0, draggable_borders - 2); - } + draggable_borders = meta_prefs_get_draggable_border_width (); - if (flags & META_FRAME_ALLOWS_BOTTOM_RESIZE) + if (flags & META_FRAME_ALLOWS_HORIZONTAL_RESIZE) { - borders->invisible.bottom = MAX (0, draggable_borders - borders->visible.bottom); + borders->invisible.left = MAX (borders->invisible.left, + draggable_borders - borders->visible.left); + borders->invisible.right = MAX (borders->invisible.right, + draggable_borders - borders->visible.right); } - if (flags & META_FRAME_ALLOWS_LEFT_RESIZE) + if (flags & META_FRAME_ALLOWS_VERTICAL_RESIZE) { - borders->invisible.left = MAX (0, draggable_borders - borders->visible.left); - } + borders->invisible.bottom = MAX (borders->invisible.bottom, + draggable_borders - borders->visible.bottom); - if (flags & META_FRAME_ALLOWS_RIGHT_RESIZE) - { - borders->invisible.right = MAX (0, draggable_borders - borders->visible.right); + /* borders.visible.top is the height of the *title bar*. We can't do the same + * algorithm here, titlebars are expectedly much bigger. Just subtract a couple + * pixels to get a proper feel. */ + if (type != META_FRAME_TYPE_ATTACHED) + borders->invisible.top = MAX (borders->invisible.top, draggable_borders - 2); } borders->total.left = borders->invisible.left + borders->visible.left; borders->total.right = borders->invisible.right + borders->visible.right; borders->total.bottom = borders->invisible.bottom + borders->visible.bottom; borders->total.top = borders->invisible.top + borders->visible.top; + + /* Scale geometry for HiDPI, see comment in meta_frame_layout_draw_with_style() */ + scale_border (&borders->visible, scale); + scale_border (&borders->invisible, scale); + scale_border (&borders->total, scale); } -static MetaButtonType -map_button_function_to_type (MetaButtonFunction function) +int +meta_theme_get_window_scaling_factor (void) { - switch (function) - { - case META_BUTTON_FUNCTION_SHADE: - return META_BUTTON_TYPE_SHADE; - case META_BUTTON_FUNCTION_ABOVE: - return META_BUTTON_TYPE_ABOVE; - case META_BUTTON_FUNCTION_STICK: - return META_BUTTON_TYPE_STICK; - case META_BUTTON_FUNCTION_UNSHADE: - return META_BUTTON_TYPE_UNSHADE; - case META_BUTTON_FUNCTION_UNABOVE: - return META_BUTTON_TYPE_UNABOVE; - case META_BUTTON_FUNCTION_UNSTICK: - return META_BUTTON_TYPE_UNSTICK; - case META_BUTTON_FUNCTION_MENU: - return META_BUTTON_TYPE_MENU; - case META_BUTTON_FUNCTION_MINIMIZE: - return META_BUTTON_TYPE_MINIMIZE; - case META_BUTTON_FUNCTION_MAXIMIZE: - return META_BUTTON_TYPE_MAXIMIZE; - case META_BUTTON_FUNCTION_CLOSE: - return META_BUTTON_TYPE_CLOSE; - case META_BUTTON_FUNCTION_LAST: - return META_BUTTON_TYPE_LAST; - } + GdkScreen *screen; + GValue value = G_VALUE_INIT; + + g_value_init (&value, G_TYPE_INT); + + screen = gdk_screen_get_default (); + if (gdk_screen_get_setting (screen, "gdk-window-scaling-factor", &value)) + return g_value_get_int (&value); + else + return 1; +} - return META_BUTTON_TYPE_LAST; +void +meta_frame_layout_apply_scale (const MetaFrameLayout *layout, + PangoFontDescription *font_desc) +{ + int size = pango_font_description_get_size (font_desc); + double scale = layout->title_scale / meta_theme_get_window_scaling_factor (); + pango_font_description_set_size (font_desc, MAX (size * scale, 1)); } static MetaButtonSpace* @@ -496,48 +159,6 @@ rect_for_function (MetaFrameGeometry *fgeom, MetaButtonFunction function, MetaTheme *theme) { - - /* Firstly, check version-specific things. */ - - if (META_THEME_ALLOWS(theme, META_THEME_SHADE_STICK_ABOVE_BUTTONS)) - { - switch (function) - { - case META_BUTTON_FUNCTION_SHADE: - if ((flags & META_FRAME_ALLOWS_SHADE) && !(flags & META_FRAME_SHADED)) - return &fgeom->shade_rect; - else - return NULL; - case META_BUTTON_FUNCTION_ABOVE: - if (!(flags & META_FRAME_ABOVE)) - return &fgeom->above_rect; - else - return NULL; - case META_BUTTON_FUNCTION_STICK: - if (!(flags & META_FRAME_STUCK)) - return &fgeom->stick_rect; - else - return NULL; - case META_BUTTON_FUNCTION_UNSHADE: - if ((flags & META_FRAME_ALLOWS_SHADE) && (flags & META_FRAME_SHADED)) - return &fgeom->unshade_rect; - else - return NULL; - case META_BUTTON_FUNCTION_UNABOVE: - if (flags & META_FRAME_ABOVE) - return &fgeom->unabove_rect; - else - return NULL; - case META_BUTTON_FUNCTION_UNSTICK: - if (flags & META_FRAME_STUCK) - return &fgeom->unstick_rect; - default: - /* just go on to the next switch block */; - } - } - - /* now consider the buttons which exist in all versions */ - switch (function) { case META_BUTTON_FUNCTION_MENU: @@ -560,18 +181,6 @@ rect_for_function (MetaFrameGeometry *fgeom, return &fgeom->close_rect; else return NULL; - case META_BUTTON_FUNCTION_STICK: - case META_BUTTON_FUNCTION_SHADE: - case META_BUTTON_FUNCTION_ABOVE: - case META_BUTTON_FUNCTION_UNSTICK: - case META_BUTTON_FUNCTION_UNSHADE: - case META_BUTTON_FUNCTION_UNABOVE: - /* we are being asked for a >v1 button which hasn't been handled yet, - * so obviously we're not in a theme which supports that version. - * therefore, we don't show the button. return NULL and all will - * be well. - */ - return NULL; case META_BUTTON_FUNCTION_LAST: return NULL; @@ -582,7 +191,6 @@ rect_for_function (MetaFrameGeometry *fgeom, static gboolean strip_button (MetaButtonSpace *func_rects[MAX_BUTTONS_PER_CORNER], - GdkRectangle *bg_rects[MAX_BUTTONS_PER_CORNER], int *n_rects, MetaButtonSpace *to_strip) { @@ -599,13 +207,11 @@ strip_button (MetaButtonSpace *func_rects[MAX_BUTTONS_PER_CORNER], while (i < *n_rects) { func_rects[i] = func_rects[i+1]; - bg_rects[i] = bg_rects[i+1]; ++i; } func_rects[i] = NULL; - bg_rects[i] = NULL; return TRUE; } @@ -616,8 +222,130 @@ strip_button (MetaButtonSpace *func_rects[MAX_BUTTONS_PER_CORNER], return FALSE; /* did not strip anything */ } -LOCAL_SYMBOL void -meta_frame_layout_calc_geometry (const MetaFrameLayout *layout, +static void +get_padding_and_border (GtkStyleContext *style, + GtkBorder *border) +{ + GtkBorder tmp; + GtkStateFlags state = gtk_style_context_get_state (style); + + gtk_style_context_get_border (style, state, border); + gtk_style_context_get_padding (style, state, &tmp); + + border->left += tmp.left; + border->top += tmp.top; + border->right += tmp.right; + border->bottom += tmp.bottom; +} + +static void +get_min_size (GtkStyleContext *style, + GtkRequisition *requisition) +{ + gtk_style_context_get (style, gtk_style_context_get_state (style), + "min-width", &requisition->width, + "min-height", &requisition->height, + NULL); +} + +static void +scale_border (GtkBorder *border, + double factor) +{ + border->left *= factor; + border->right *= factor; + border->top *= factor; + border->bottom *= factor; +} + +static void +meta_frame_layout_sync_with_style (MetaFrameLayout *layout, + MetaStyleInfo *style_info, + MetaFrameFlags flags) +{ + GtkStyleContext *style; + GtkBorder border; + GtkRequisition requisition; + GdkRectangle clip_rect; + int border_radius, max_radius; + + meta_style_info_set_flags (style_info, flags); + + style = style_info->styles[META_STYLE_ELEMENT_FRAME]; + get_padding_and_border (style, &layout->frame_border); + scale_border (&layout->frame_border, layout->title_scale); + + gtk_render_background_get_clip (style, 0, 0, 0, 0, &clip_rect); + layout->invisible_border.left = -clip_rect.x; + layout->invisible_border.right = clip_rect.width + clip_rect.x; + layout->invisible_border.top = -clip_rect.y; + layout->invisible_border.bottom = clip_rect.height + clip_rect.y; + + if (layout->hide_buttons) + layout->icon_size = 0; + + if (!layout->has_title && layout->hide_buttons) + return; /* border-only - be done */ + + style = style_info->styles[META_STYLE_ELEMENT_TITLEBAR]; + gtk_style_context_get (style, gtk_style_context_get_state (style), + "border-radius", &border_radius, + NULL); + /* GTK+ currently does not allow us to look up radii of individual + * corners; however we don't clip the client area, so with the + * current trend of using small/no visible frame borders, most + * themes should work fine with this. + */ + layout->top_left_corner_rounded_radius = border_radius; + layout->top_right_corner_rounded_radius = border_radius; + max_radius = MIN (layout->frame_border.bottom, layout->frame_border.left); + layout->bottom_left_corner_rounded_radius = MAX (border_radius, max_radius); + max_radius = MIN (layout->frame_border.bottom, layout->frame_border.right); + layout->bottom_right_corner_rounded_radius = MAX (border_radius, max_radius); + + get_min_size (style, &layout->titlebar_min_size); + get_padding_and_border (style, &layout->titlebar_border); + scale_border (&layout->titlebar_border, layout->title_scale); + + style = style_info->styles[META_STYLE_ELEMENT_TITLE]; + gtk_style_context_get_margin (style, gtk_style_context_get_state (style), + &layout->title_margin); + scale_border (&layout->title_margin, layout->title_scale); + + style = style_info->styles[META_STYLE_ELEMENT_BUTTON]; + get_min_size (style, &layout->button_min_size); + get_padding_and_border (style, &layout->button_border); + scale_border (&layout->button_border, layout->title_scale); + gtk_style_context_get_margin (style, gtk_style_context_get_state (style), + &layout->button_margin); + scale_border (&layout->button_margin, layout->title_scale); + + style = style_info->styles[META_STYLE_ELEMENT_IMAGE]; + get_min_size (style, &requisition); + get_padding_and_border (style, &border); + scale_border (&border, layout->title_scale); + + layout->button_border.left += border.left; + layout->button_border.right += border.right; + layout->button_border.top += border.top; + layout->button_border.bottom += border.bottom; + + gtk_style_context_get_margin (style, gtk_style_context_get_state (style), + &border); + layout->button_border.left += border.left; + layout->button_border.right += border.right; + layout->button_border.top += border.top; + layout->button_border.bottom += border.bottom; + + layout->button_min_size.width = MAX(layout->button_min_size.width, + requisition.width); + layout->button_min_size.height = MAX(layout->button_min_size.height, + requisition.height); +} + +static void +meta_frame_layout_calc_geometry (MetaFrameLayout *layout, + MetaStyleInfo *style_info, int text_height, MetaFrameFlags flags, int client_width, @@ -632,58 +360,56 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout *layout, int button_y; int title_right_edge; int width, height; + int content_width, content_height; int button_width, button_height; int min_size_for_rounding; + int scale = meta_theme_get_window_scaling_factor (); /* the left/right rects in order; the max # of rects * is the number of button functions */ MetaButtonSpace *left_func_rects[MAX_BUTTONS_PER_CORNER]; MetaButtonSpace *right_func_rects[MAX_BUTTONS_PER_CORNER]; - GdkRectangle *left_bg_rects[MAX_BUTTONS_PER_CORNER]; gboolean left_buttons_has_spacer[MAX_BUTTONS_PER_CORNER]; - GdkRectangle *right_bg_rects[MAX_BUTTONS_PER_CORNER]; gboolean right_buttons_has_spacer[MAX_BUTTONS_PER_CORNER]; MetaFrameBorders borders; + meta_frame_layout_sync_with_style (layout, style_info, flags); + meta_frame_layout_get_borders (layout, text_height, flags, type, &borders); fgeom->borders = borders; + /* Scale geometry for HiDPI, see comment in meta_frame_layout_draw_with_style() */ + fgeom->content_border = layout->frame_border; + fgeom->content_border.left += layout->titlebar_border.left * scale; + fgeom->content_border.right += layout->titlebar_border.right * scale; + fgeom->content_border.top += layout->titlebar_border.top * scale; + fgeom->content_border.bottom += layout->titlebar_border.bottom * scale; + width = client_width + borders.total.left + borders.total.right; - height = ((flags & META_FRAME_SHADED) ? 0: client_height) + - borders.total.top + borders.total.bottom; + height = borders.total.top + borders.total.bottom; + if (!(flags & META_FRAME_SHADED)) + height += client_height; fgeom->width = width; fgeom->height = height; - fgeom->top_titlebar_edge = layout->title_border.top; - fgeom->bottom_titlebar_edge = layout->title_border.bottom; - fgeom->left_titlebar_edge = layout->left_titlebar_edge; - fgeom->right_titlebar_edge = layout->right_titlebar_edge; - - /* gcc warnings */ - button_width = -1; - button_height = -1; + content_width = width - + (fgeom->content_border.left + borders.invisible.left) - + (fgeom->content_border.right + borders.invisible.right); + content_height = borders.visible.top - fgeom->content_border.top - fgeom->content_border.bottom; - switch (layout->button_sizing) - { - case META_BUTTON_SIZING_ASPECT: - button_height = borders.visible.top - layout->button_border.top - layout->button_border.bottom; - button_width = button_height / layout->button_aspect; - break; - case META_BUTTON_SIZING_FIXED: - button_width = layout->button_width; - button_height = layout->button_height; - break; - case META_BUTTON_SIZING_LAST: - g_assert_not_reached (); - break; - } + button_width = MAX ((int)layout->icon_size, layout->button_min_size.width) + + layout->button_border.left + layout->button_border.right; + button_height = MAX ((int)layout->icon_size, layout->button_min_size.height) + + layout->button_border.top + layout->button_border.bottom; + button_width *= scale; + button_height *= scale; /* FIXME all this code sort of pretends that duplicate buttons * with the same function are allowed, but that breaks the @@ -734,57 +460,26 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout *layout, } } - for (i = 0; i < MAX_BUTTONS_PER_CORNER; i++) - { - left_bg_rects[i] = NULL; - right_bg_rects[i] = NULL; - } - - for (i = 0; i < n_left; i++) - { - if (n_left == 1) - left_bg_rects[i] = &fgeom->left_single_background; - else if (i == 0) - left_bg_rects[i] = &fgeom->left_left_background; - else if (i == (n_left - 1)) - left_bg_rects[i] = &fgeom->left_right_background; - else - left_bg_rects[i] = &fgeom->left_middle_backgrounds[i - 1]; - } - - for (i = 0; i < n_right; i++) - { - if (n_right == 1) - right_bg_rects[i] = &fgeom->right_single_background; - else if (i == (n_right - 1)) - right_bg_rects[i] = &fgeom->right_right_background; - else if (i == 0) - right_bg_rects[i] = &fgeom->right_left_background; - else - right_bg_rects[i] = &fgeom->right_middle_backgrounds[i - 1]; - } - /* Be sure buttons fit */ while (n_left > 0 || n_right > 0) { int space_used_by_buttons; - int space_available; - - space_available = fgeom->width - layout->left_titlebar_edge - layout->right_titlebar_edge; space_used_by_buttons = 0; + space_used_by_buttons += layout->button_margin.left * scale * n_left; space_used_by_buttons += button_width * n_left; + space_used_by_buttons += layout->button_margin.right * scale * n_left; space_used_by_buttons += (button_width * 0.75) * n_left_spacers; - space_used_by_buttons += layout->button_border.left * n_left; - space_used_by_buttons += layout->button_border.right * n_left; + space_used_by_buttons += layout->titlebar_spacing * scale * MAX (n_left - 1, 0); + space_used_by_buttons += layout->button_margin.left * scale * n_right; space_used_by_buttons += button_width * n_right; + space_used_by_buttons += layout->button_margin.right * scale * n_right; space_used_by_buttons += (button_width * 0.75) * n_right_spacers; - space_used_by_buttons += layout->button_border.left * n_right; - space_used_by_buttons += layout->button_border.right * n_right; + space_used_by_buttons += layout->titlebar_spacing * scale * MAX (n_right - 1, 0); - if (space_used_by_buttons <= space_available) + if (space_used_by_buttons <= content_width) break; /* Everything fits, bail out */ /* First try to remove separators */ @@ -800,50 +495,24 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout *layout, } /* Otherwise we need to shave out a button. Shave - * above, stick, shade, min, max, close, then menu (menu is most useful); + * min, max, close, then menu (menu is most useful); * prefer the default button locations. */ - if (strip_button (left_func_rects, left_bg_rects, - &n_left, &fgeom->above_rect)) - continue; - else if (strip_button (right_func_rects, right_bg_rects, - &n_right, &fgeom->above_rect)) + if (strip_button (left_func_rects, &n_left, &fgeom->min_rect)) continue; - else if (strip_button (left_func_rects, left_bg_rects, - &n_left, &fgeom->stick_rect)) + else if (strip_button (right_func_rects, &n_right, &fgeom->min_rect)) continue; - else if (strip_button (right_func_rects, right_bg_rects, - &n_right, &fgeom->stick_rect)) + else if (strip_button (left_func_rects, &n_left, &fgeom->max_rect)) continue; - else if (strip_button (left_func_rects, left_bg_rects, - &n_left, &fgeom->shade_rect)) + else if (strip_button (right_func_rects, &n_right, &fgeom->max_rect)) continue; - else if (strip_button (right_func_rects, right_bg_rects, - &n_right, &fgeom->shade_rect)) + else if (strip_button (left_func_rects, &n_left, &fgeom->close_rect)) continue; - else if (strip_button (left_func_rects, left_bg_rects, - &n_left, &fgeom->min_rect)) + else if (strip_button (right_func_rects, &n_right, &fgeom->close_rect)) continue; - else if (strip_button (right_func_rects, right_bg_rects, - &n_right, &fgeom->min_rect)) + else if (strip_button (right_func_rects, &n_right, &fgeom->menu_rect)) continue; - else if (strip_button (left_func_rects, left_bg_rects, - &n_left, &fgeom->max_rect)) - continue; - else if (strip_button (right_func_rects, right_bg_rects, - &n_right, &fgeom->max_rect)) - continue; - else if (strip_button (left_func_rects, left_bg_rects, - &n_left, &fgeom->close_rect)) - continue; - else if (strip_button (right_func_rects, right_bg_rects, - &n_right, &fgeom->close_rect)) - continue; - else if (strip_button (right_func_rects, right_bg_rects, - &n_right, &fgeom->menu_rect)) - continue; - else if (strip_button (left_func_rects, left_bg_rects, - &n_left, &fgeom->menu_rect)) + else if (strip_button (left_func_rects, &n_left, &fgeom->menu_rect)) continue; else { @@ -858,11 +527,11 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout *layout, fgeom->n_right_buttons = n_right; /* center buttons vertically */ - button_y = (borders.visible.top - - (button_height + layout->button_border.top + layout->button_border.bottom)) / 2 + layout->button_border.top + borders.invisible.top; + button_y = fgeom->content_border.top + borders.invisible.top + + (content_height - button_height) / 2; /* right edge of farthest-right button */ - x = width - layout->right_titlebar_edge - borders.invisible.right; + x = width - fgeom->content_border.right - borders.invisible.right; i = n_right - 1; while (i >= 0) @@ -872,8 +541,10 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout *layout, if (x < 0) /* if we go negative, leave the buttons we don't get to as 0-width */ break; + x -= layout->button_margin.right * scale; + rect = right_func_rects[i]; - rect->visible.x = x - layout->button_border.right - button_width; + rect->visible.x = x - button_width; if (right_buttons_has_spacer[i]) rect->visible.x -= (button_width * 0.75); @@ -891,33 +562,36 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout *layout, rect->clickable.height = button_height + button_y; if (i == n_right - 1) - rect->clickable.width += layout->right_titlebar_edge + layout->right_width + layout->button_border.right; + rect->clickable.width += fgeom->content_border.right; } else - g_memmove (&(rect->clickable), &(rect->visible), sizeof(rect->clickable)); + memmove (&(rect->clickable), &(rect->visible), sizeof (rect->clickable)); - *(right_bg_rects[i]) = rect->visible; + x = rect->visible.x - layout->button_margin.left * scale; - x = rect->visible.x - layout->button_border.left; + if (i > 0) + x -= layout->titlebar_spacing * scale; --i; } /* save right edge of titlebar for later use */ - title_right_edge = x - layout->title_border.right; + title_right_edge = x; /* Now x changes to be position from the left and we go through * the left-side buttons */ - x = layout->left_titlebar_edge + borders.invisible.left; + x = fgeom->content_border.left + borders.invisible.left; for (i = 0; i < n_left; i++) { MetaButtonSpace *rect; + x += layout->button_margin.left * scale; + rect = left_func_rects[i]; - rect->visible.x = x + layout->button_border.left; + rect->visible.x = x; rect->visible.y = button_y; rect->visible.width = button_width; rect->visible.height = button_height; @@ -935,27 +609,25 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout *layout, rect->clickable.width = button_width; } - rect->clickable.y = 0; - rect->clickable.height = button_height + button_y; - } - else - g_memmove (&(rect->clickable), &(rect->visible), sizeof(rect->clickable)); - + rect->clickable.y = 0; + rect->clickable.height = button_height + button_y; + } + else + memmove (&(rect->clickable), &(rect->visible), sizeof (rect->clickable)); - x = rect->visible.x + rect->visible.width + layout->button_border.right; + x = rect->visible.x + rect->visible.width + layout->button_margin.right * scale; + if (i < n_left - 1) + x += layout->titlebar_spacing * scale; if (left_buttons_has_spacer[i]) x += (button_width * 0.75); - - *(left_bg_rects[i]) = rect->visible; } - /* We always fill as much vertical space as possible with title rect, - * rather than centering it like the buttons - */ - fgeom->title_rect.x = x + layout->title_border.left; - fgeom->title_rect.y = layout->title_border.top + borders.invisible.top; + /* Center vertically in the available content area */ + fgeom->title_rect.x = x; + fgeom->title_rect.y = fgeom->content_border.top + borders.invisible.top + + (content_height - text_height) / 2; fgeom->title_rect.width = title_right_edge - fgeom->title_rect.x; - fgeom->title_rect.height = borders.visible.top - layout->title_border.top - layout->title_border.bottom; + fgeom->title_rect.height = text_height; /* Nuke title if it won't fit */ if (fgeom->title_rect.width < 0 || @@ -968,7 +640,7 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout *layout, if (flags & META_FRAME_SHADED) min_size_for_rounding = 0; else - min_size_for_rounding = 5; + min_size_for_rounding = 5 * scale; fgeom->top_left_corner_rounded_radius = 0; fgeom->top_right_corner_rounded_radius = 0; @@ -976,4617 +648,595 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout *layout, fgeom->bottom_right_corner_rounded_radius = 0; if (borders.visible.top + borders.visible.left >= min_size_for_rounding) - fgeom->top_left_corner_rounded_radius = layout->top_left_corner_rounded_radius; + fgeom->top_left_corner_rounded_radius = layout->top_left_corner_rounded_radius * scale; if (borders.visible.top + borders.visible.right >= min_size_for_rounding) - fgeom->top_right_corner_rounded_radius = layout->top_right_corner_rounded_radius; + fgeom->top_right_corner_rounded_radius = layout->top_right_corner_rounded_radius * scale; if (borders.visible.bottom + borders.visible.left >= min_size_for_rounding) - fgeom->bottom_left_corner_rounded_radius = layout->bottom_left_corner_rounded_radius; + fgeom->bottom_left_corner_rounded_radius = layout->bottom_left_corner_rounded_radius * scale; if (borders.visible.bottom + borders.visible.right >= min_size_for_rounding) - fgeom->bottom_right_corner_rounded_radius = layout->bottom_right_corner_rounded_radius; + fgeom->bottom_right_corner_rounded_radius = layout->bottom_right_corner_rounded_radius * scale; } -/** - * meta_gradient_spec_new: (skip) - * - */ -LOCAL_SYMBOL MetaGradientSpec* -meta_gradient_spec_new (MetaGradientType type) +static void +get_button_rect (MetaButtonType type, + const MetaFrameGeometry *fgeom, + GdkRectangle *rect) { - MetaGradientSpec *spec; - - spec = g_new (MetaGradientSpec, 1); + switch (type) + { + case META_BUTTON_TYPE_CLOSE: + *rect = fgeom->close_rect.visible; + break; - spec->type = type; - spec->color_specs = NULL; + case META_BUTTON_TYPE_MAXIMIZE: + *rect = fgeom->max_rect.visible; + break; - return spec; -} + case META_BUTTON_TYPE_MINIMIZE: + *rect = fgeom->min_rect.visible; + break; -static void -free_color_spec (gpointer spec, gpointer user_data) -{ - meta_color_spec_free (spec); -} - -LOCAL_SYMBOL void -meta_gradient_spec_free (MetaGradientSpec *spec) -{ - g_return_if_fail (spec != NULL); - - g_slist_foreach (spec->color_specs, free_color_spec, NULL); - g_slist_free (spec->color_specs); - - DEBUG_FILL_STRUCT (spec); - free (spec); -} - -LOCAL_SYMBOL GdkPixbuf* -meta_gradient_spec_render (const MetaGradientSpec *spec, - GtkStyleContext *style, - int width, - int height) -{ - int n_colors; - GdkRGBA *colors; - GSList *tmp; - int i; - GdkPixbuf *pixbuf; - - n_colors = g_slist_length (spec->color_specs); - - if (n_colors == 0) - return NULL; - - colors = g_new (GdkRGBA, n_colors); - - i = 0; - tmp = spec->color_specs; - while (tmp != NULL) - { - meta_color_spec_render (tmp->data, style, &colors[i]); + case META_BUTTON_TYPE_MENU: + *rect = fgeom->menu_rect.visible; + break; - tmp = tmp->next; - ++i; + default: + case META_BUTTON_TYPE_LAST: + g_assert_not_reached (); + break; } - - pixbuf = meta_gradient_create_multi (width, height, - colors, n_colors, - spec->type); - - free (colors); - - return pixbuf; } -LOCAL_SYMBOL gboolean -meta_gradient_spec_validate (MetaGradientSpec *spec, - GError **error) +static const char * +get_class_from_button_type (MetaButtonType type) { - g_return_val_if_fail (spec != NULL, FALSE); - - if (g_slist_length (spec->color_specs) < 2) + switch (type) { - g_set_error (error, META_THEME_ERROR, - META_THEME_ERROR_FAILED, - _("Gradients should have at least two colors")); - return FALSE; + case META_BUTTON_TYPE_CLOSE: + return "close"; + case META_BUTTON_TYPE_MAXIMIZE: + return "maximize"; + case META_BUTTON_TYPE_MINIMIZE: + return "minimize"; + default: + return NULL; } - - return TRUE; } -/** - * meta_alpha_gradient_spec_new: (skip) - * - */ -LOCAL_SYMBOL LOCAL_SYMBOL MetaAlphaGradientSpec* -meta_alpha_gradient_spec_new (MetaGradientType type, - int n_alphas) +static void +meta_frame_layout_draw_with_style (MetaFrameLayout *layout, + MetaStyleInfo *style_info, + cairo_t *cr, + const MetaFrameGeometry *fgeom, + PangoLayout *title_layout, + MetaFrameFlags flags, + MetaButtonState button_states[META_BUTTON_TYPE_LAST], + cairo_surface_t *mini_icon) { - MetaAlphaGradientSpec *spec; - - g_return_val_if_fail (n_alphas > 0, NULL); - - spec = g_new0 (MetaAlphaGradientSpec, 1); + GtkStyleContext *style; + GtkStateFlags state; + MetaButtonType button_type; + GdkRectangle visible_rect; + GdkRectangle titlebar_rect; + GdkRectangle button_rect; + const MetaFrameBorders *borders; + cairo_surface_t *frame_surface; + double xscale, yscale; + int scale; + + /* We opt out of GTK+/Clutter's HiDPI handling, so we have to do the scaling + * ourselves; the nitty-gritty is a bit confusing, so here is an overview: + * - the values in MetaFrameLayout are always as they appear in the theme, + * i.e. unscaled + * - calculated values (borders, MetaFrameGeometry) include the scale - as + * the geometry is comprised of scaled decorations and the client size + * which we must not scale, we don't have another option + * - for drawing, we scale the canvas to have GTK+ render elements (borders, + * radii, ...) at the correct scale - as a result, we have to "unscale" + * the geometry again to not apply the scaling twice + * - As per commit e36b629c GTK expects the device scale to be set and match + * the final scaling or the surface caching won't take this in account + * breaking -gtk-scaled items. + */ + scale = meta_theme_get_window_scaling_factor (); + frame_surface = cairo_get_target (cr); + cairo_surface_get_device_scale (frame_surface, &xscale, &yscale); + cairo_surface_set_device_scale (frame_surface, scale, scale); - spec->type = type; - spec->alphas = g_new0 (unsigned char, n_alphas); - spec->n_alphas = n_alphas; + borders = &fgeom->borders; - return spec; -} + visible_rect.x = borders->invisible.left / scale; + visible_rect.y = borders->invisible.top / scale; + visible_rect.width = (fgeom->width - borders->invisible.left - borders->invisible.right) / scale; + visible_rect.height = (fgeom->height - borders->invisible.top - borders->invisible.bottom) / scale; -LOCAL_SYMBOL void -meta_alpha_gradient_spec_free (MetaAlphaGradientSpec *spec) -{ - g_return_if_fail (spec != NULL); + meta_style_info_set_flags (style_info, flags); - free (spec->alphas); - free (spec); -} + style = style_info->styles[META_STYLE_ELEMENT_FRAME]; + gtk_render_background (style, cr, + visible_rect.x, visible_rect.y, + visible_rect.width, visible_rect.height); + gtk_render_frame (style, cr, + visible_rect.x, visible_rect.y, + visible_rect.width, visible_rect.height); -/** - * meta_color_spec_new: (skip) - * - */ -LOCAL_SYMBOL MetaColorSpec* -meta_color_spec_new (MetaColorSpecType type) -{ - MetaColorSpec *spec; - MetaColorSpec dummy; - int size; + titlebar_rect.x = visible_rect.x; + titlebar_rect.y = visible_rect.y; + titlebar_rect.width = visible_rect.width; + titlebar_rect.height = borders->visible.top / scale; - size = G_STRUCT_OFFSET (MetaColorSpec, data); + style = style_info->styles[META_STYLE_ELEMENT_TITLEBAR]; + gtk_render_background (style, cr, + titlebar_rect.x, titlebar_rect.y, + titlebar_rect.width, titlebar_rect.height); + gtk_render_frame (style, cr, + titlebar_rect.x, titlebar_rect.y, + titlebar_rect.width, titlebar_rect.height); - switch (type) + if (layout->has_title && title_layout) { - case META_COLOR_SPEC_BASIC: - size += sizeof (dummy.data.basic); - break; - - case META_COLOR_SPEC_GTK: - size += sizeof (dummy.data.gtk); - break; + PangoRectangle logical; + int text_width, x, y; - case META_COLOR_SPEC_GTK_CUSTOM: - size += sizeof (dummy.data.gtkcustom); - break; - - case META_COLOR_SPEC_BLEND: - size += sizeof (dummy.data.blend); - break; - - case META_COLOR_SPEC_SHADE: - size += sizeof (dummy.data.shade); - break; - } - - spec = calloc (1, size); - - spec->type = type; + pango_layout_set_width (title_layout, -1); + pango_layout_get_pixel_extents (title_layout, NULL, &logical); - return spec; -} - -LOCAL_SYMBOL void -meta_color_spec_free (MetaColorSpec *spec) -{ - g_return_if_fail (spec != NULL); - - switch (spec->type) - { - case META_COLOR_SPEC_BASIC: - DEBUG_FILL_STRUCT (&spec->data.basic); - break; + text_width = MIN(fgeom->title_rect.width / scale, logical.width); - case META_COLOR_SPEC_GTK: - DEBUG_FILL_STRUCT (&spec->data.gtk); - break; + if (text_width < logical.width) + pango_layout_set_width (title_layout, PANGO_SCALE * text_width); - case META_COLOR_SPEC_GTK_CUSTOM: - free (spec->data.gtkcustom.color_name); - if (spec->data.gtkcustom.fallback) - meta_color_spec_free (spec->data.gtkcustom.fallback); - DEBUG_FILL_STRUCT (&spec->data.gtkcustom); - break; + /* Center within the frame if possible */ + x = titlebar_rect.x + (titlebar_rect.width - text_width) / 2; + y = titlebar_rect.y + (titlebar_rect.height - logical.height) / 2; - case META_COLOR_SPEC_BLEND: - if (spec->data.blend.foreground) - meta_color_spec_free (spec->data.blend.foreground); - if (spec->data.blend.background) - meta_color_spec_free (spec->data.blend.background); - DEBUG_FILL_STRUCT (&spec->data.blend); - break; + if (x < fgeom->title_rect.x / scale) + x = fgeom->title_rect.x / scale; + else if (x + text_width > (fgeom->title_rect.x + fgeom->title_rect.width) / scale) + x = (fgeom->title_rect.x + fgeom->title_rect.width) / scale - text_width; - case META_COLOR_SPEC_SHADE: - if (spec->data.shade.base) - meta_color_spec_free (spec->data.shade.base); - DEBUG_FILL_STRUCT (&spec->data.shade); - break; + style = style_info->styles[META_STYLE_ELEMENT_TITLE]; + gtk_render_layout (style, cr, x, y, title_layout); } - free (spec); -} + style = style_info->styles[META_STYLE_ELEMENT_BUTTON]; + state = gtk_style_context_get_state (style); + for (button_type = META_BUTTON_TYPE_CLOSE; button_type < META_BUTTON_TYPE_LAST; button_type++) + { + const char *button_class = get_class_from_button_type (button_type); + if (button_class) + gtk_style_context_add_class (style, button_class); -/** - * meta_color_spec_new_from_string: (skip) - * - */ -LOCAL_SYMBOL MetaColorSpec* -meta_color_spec_new_from_string (const char *str, - GError **err) -{ - MetaColorSpec *spec; + get_button_rect (button_type, fgeom, &button_rect); - spec = NULL; + button_rect.x /= scale; + button_rect.y /= scale; + button_rect.width /= scale; + button_rect.height /= scale; - if (str[0] == 'g' && str[1] == 't' && str[2] == 'k' && str[3] == ':' && - str[4] == 'c' && str[5] == 'u' && str[6] == 's' && str[7] == 't' && - str[8] == 'o' && str[9] == 'm') - { - const char *color_name_start, *fallback_str_start, *end; - char *color_name; - MetaColorSpec *fallback = NULL; - static gboolean debug, debug_set = FALSE; + if (button_states[button_type] == META_BUTTON_STATE_PRELIGHT) + gtk_style_context_set_state (style, state | GTK_STATE_PRELIGHT); + else if (button_states[button_type] == META_BUTTON_STATE_PRESSED) + gtk_style_context_set_state (style, state | GTK_STATE_ACTIVE); + else + gtk_style_context_set_state (style, state); - if (!debug_set) - { - debug = g_getenv ("MUFFIN_DISABLE_FALLBACK_COLOR") != NULL; - debug_set = TRUE; - } + cairo_save (cr); - if (str[10] != '(') + if (button_rect.width > 0 && button_rect.height > 0) { - g_set_error (err, META_THEME_ERROR, - META_THEME_ERROR_FAILED, - _("GTK custom color specification must have color name and fallback in parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\""), - str); - return NULL; - } + cairo_surface_t *surface = NULL; + const char *icon_name = NULL; - color_name_start = str + 11; + gtk_render_background (style, cr, + button_rect.x, button_rect.y, + button_rect.width, button_rect.height); + gtk_render_frame (style, cr, + button_rect.x, button_rect.y, + button_rect.width, button_rect.height); - fallback_str_start = color_name_start; - while (*fallback_str_start && *fallback_str_start != ',') - { - if (!(g_ascii_isalnum (*fallback_str_start) - || *fallback_str_start == '-' - || *fallback_str_start == '_')) + switch (button_type) { - g_set_error (err, META_THEME_ERROR, - META_THEME_ERROR_FAILED, - _("Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-_ are valid"), - *fallback_str_start); - return NULL; + case META_BUTTON_TYPE_CLOSE: + icon_name = "window-close-symbolic"; + break; + case META_BUTTON_TYPE_MAXIMIZE: + if (flags & META_FRAME_MAXIMIZED) + icon_name = "window-restore-symbolic"; + else + icon_name = "window-maximize-symbolic"; + break; + case META_BUTTON_TYPE_MINIMIZE: + icon_name = "window-minimize-symbolic"; + break; + case META_BUTTON_TYPE_MENU: + icon_name = "open-menu-symbolic"; + break; + default: + icon_name = NULL; + break; } - fallback_str_start++; - } - fallback_str_start++; - end = strrchr (str, ')'); - - if (color_name_start == NULL || fallback_str_start == NULL || end == NULL) - { - g_set_error (err, META_THEME_ERROR, - META_THEME_ERROR_FAILED, - _("Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not fit the format"), - str); - return NULL; - } - - if (!debug) - { - char *fallback_str; - fallback_str = g_strndup (fallback_str_start, - end - fallback_str_start); - fallback = meta_color_spec_new_from_string (fallback_str, err); - free (fallback_str); - } - else - { - fallback = meta_color_spec_new_from_string ("pink", err); - } + if (icon_name) + { + g_autoptr (GIcon) icon = NULL; + g_autoptr (GtkIconInfo) info = NULL; + g_autoptr (GdkPixbuf) pixbuf = NULL; + GtkIconTheme *theme; + int flags; + + theme = gtk_icon_theme_get_default (); + + /* This can't be exactly like Gtk does as some -gtk-* css + * properties that are used for setting the loading flags + * are not accessible from here */ + flags = GTK_ICON_LOOKUP_USE_BUILTIN; + flags |= (meta_get_locale_direction () == META_LOCALE_DIRECTION_LTR) ? + GTK_ICON_LOOKUP_DIR_LTR : GTK_ICON_LOOKUP_DIR_RTL; + + icon = g_themed_icon_new_with_default_fallbacks (icon_name); + info = gtk_icon_theme_lookup_by_gicon_for_scale (theme, icon, + layout->icon_size, + scale, flags); + if (gtk_icon_info_is_symbolic (info)) + pixbuf = gtk_icon_info_load_symbolic_for_context (info, style, + NULL, NULL); + else + pixbuf = gtk_icon_info_load_icon (info, NULL); - if (fallback == NULL) - return NULL; + if (pixbuf) + surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale, + NULL); + } - color_name = g_strndup (color_name_start, - fallback_str_start - color_name_start - 1); + if (surface) + { + double x, y; + x = button_rect.x + (button_rect.width - layout->icon_size) / 2.0; + y = button_rect.y + (button_rect.height - layout->icon_size) / 2.0; - spec = meta_color_spec_new (META_COLOR_SPEC_GTK_CUSTOM); - spec->data.gtkcustom.color_name = color_name; - spec->data.gtkcustom.fallback = fallback; - } - else if (str[0] == 'g' && str[1] == 't' && str[2] == 'k' && str[3] == ':') - { - /* GTK color */ - const char *bracket; - const char *end_bracket; - char *tmp; - GtkStateFlags state; - MetaGtkColorComponent component; - - bracket = str; - while (*bracket && *bracket != '[') - ++bracket; - - if (*bracket == '\0') - { - g_set_error (err, META_THEME_ERROR, - META_THEME_ERROR_FAILED, - _("GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\""), - str); - return NULL; + gtk_render_icon_surface (style, cr, surface, x, y); + cairo_surface_destroy (surface); + } } + cairo_restore (cr); + if (button_class) + gtk_style_context_remove_class (style, button_class); + gtk_style_context_set_state (style, state); + } - end_bracket = bracket; - ++end_bracket; - while (*end_bracket && *end_bracket != ']') - ++end_bracket; + cairo_surface_set_device_scale (frame_surface, xscale, yscale); +} - if (*end_bracket == '\0') - { - g_set_error (err, META_THEME_ERROR, - META_THEME_ERROR_FAILED, - _("GTK color specification must have a close bracket after the state, e.g. gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\""), - str); - return NULL; - } +/** + * meta_theme_get_default: (skip) + * + */ +MetaTheme* +meta_theme_get_default (void) +{ + static MetaTheme *theme = NULL; + int frame_type; - tmp = g_strndup (bracket + 1, end_bracket - bracket - 1); - state = meta_gtk_state_from_string (tmp); - if (((int) state) == -1) - { - g_set_error (err, META_THEME_ERROR, - META_THEME_ERROR_FAILED, - _("Did not understand state \"%s\" in color specification"), - tmp); - free (tmp); - return NULL; - } - free (tmp); + if (theme) + return theme; - tmp = g_strndup (str + 4, bracket - str - 4); - component = meta_color_component_from_string (tmp); - if (component == META_GTK_COLOR_LAST) - { - g_set_error (err, META_THEME_ERROR, - META_THEME_ERROR_FAILED, - _("Did not understand color component \"%s\" in color specification"), - tmp); - free (tmp); - return NULL; - } - free (tmp); + theme = meta_theme_new (); - spec = meta_color_spec_new (META_COLOR_SPEC_GTK); - spec->data.gtk.state = state; - spec->data.gtk.component = component; - g_assert (spec->data.gtk.component < META_GTK_COLOR_LAST); - } - else if (str[0] == 'b' && str[1] == 'l' && str[2] == 'e' && str[3] == 'n' && - str[4] == 'd' && str[5] == '/') + for (frame_type = 0; frame_type < META_FRAME_TYPE_LAST; frame_type++) { - /* blend */ - char **split; - double alpha; - char *end; - MetaColorSpec *fg; - MetaColorSpec *bg; - - split = g_strsplit (str, "/", 4); + MetaFrameLayout *layout = meta_frame_layout_new (); - if (split[0] == NULL || split[1] == NULL || - split[2] == NULL || split[3] == NULL) + switch (frame_type) { - g_set_error (err, META_THEME_ERROR, - META_THEME_ERROR_FAILED, - _("Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the format"), - str); - g_strfreev (split); - return NULL; + case META_FRAME_TYPE_NORMAL: + case META_FRAME_TYPE_DIALOG: + case META_FRAME_TYPE_MODAL_DIALOG: + case META_FRAME_TYPE_ATTACHED: + break; + case META_FRAME_TYPE_MENU: + case META_FRAME_TYPE_UTILITY: + layout->title_scale = PANGO_SCALE_SMALL; + break; + case META_FRAME_TYPE_BORDER: + layout->has_title = FALSE; + layout->hide_buttons = TRUE; + break; + default: + g_assert_not_reached (); } - alpha = g_ascii_strtod (split[3], &end); - if (end == split[3]) - { - g_set_error (err, META_THEME_ERROR, - META_THEME_ERROR_FAILED, - _("Could not parse alpha value \"%s\" in blended color"), - split[3]); - g_strfreev (split); - return NULL; - } + theme->layouts[frame_type] = layout; + } + return theme; +} - if (alpha < (0.0 - 1e6) || alpha > (1.0 + 1e6)) - { - g_set_error (err, META_THEME_ERROR, - META_THEME_ERROR_FAILED, - _("Alpha value \"%s\" in blended color is not between 0.0 and 1.0"), - split[3]); - g_strfreev (split); - return NULL; - } +/** + * meta_theme_new: (skip) + * + */ +MetaTheme* +meta_theme_new (void) +{ + return g_new0 (MetaTheme, 1); +} - fg = NULL; - bg = NULL; - bg = meta_color_spec_new_from_string (split[1], err); - if (bg == NULL) - { - g_strfreev (split); - return NULL; - } +void +meta_theme_free (MetaTheme *theme) +{ + int i; - fg = meta_color_spec_new_from_string (split[2], err); - if (fg == NULL) - { - meta_color_spec_free (bg); - g_strfreev (split); - return NULL; - } + g_return_if_fail (theme != NULL); - g_strfreev (split); + for (i = 0; i < META_FRAME_TYPE_LAST; i++) + if (theme->layouts[i]) + meta_frame_layout_free (theme->layouts[i]); - spec = meta_color_spec_new (META_COLOR_SPEC_BLEND); - spec->data.blend.alpha = alpha; - spec->data.blend.background = bg; - spec->data.blend.foreground = fg; - } - else if (str[0] == 's' && str[1] == 'h' && str[2] == 'a' && str[3] == 'd' && - str[4] == 'e' && str[5] == '/') - { - /* shade */ - char **split; - double factor; - char *end; - MetaColorSpec *base; + g_free (theme); +} - split = g_strsplit (str, "/", 3); +MetaFrameLayout* +meta_theme_get_frame_layout (MetaTheme *theme, + MetaFrameType type) +{ + g_return_val_if_fail (type < META_FRAME_TYPE_LAST, NULL); - if (split[0] == NULL || split[1] == NULL || - split[2] == NULL) - { - g_set_error (err, META_THEME_ERROR, - META_THEME_ERROR_FAILED, - _("Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format"), - str); - g_strfreev (split); - return NULL; - } + return theme->layouts[type]; +} - factor = g_ascii_strtod (split[2], &end); - if (end == split[2]) - { - g_set_error (err, META_THEME_ERROR, - META_THEME_ERROR_FAILED, - _("Could not parse shade factor \"%s\" in shaded color"), - split[2]); - g_strfreev (split); - return NULL; - } +static GtkStyleContext * +create_style_context (GType widget_type, + GtkStyleContext *parent_style, + GtkCssProvider *provider, + const char *object_name, + const char *first_class, + ...) +{ + GtkStyleContext *style; + GtkStateFlags state; + GtkWidgetPath *path; + const char *name; + va_list ap; - if (factor < (0.0 - 1e6)) - { - g_set_error (err, META_THEME_ERROR, - META_THEME_ERROR_FAILED, - _("Shade factor \"%s\" in shaded color is negative"), - split[2]); - g_strfreev (split); - return NULL; - } + style = gtk_style_context_new (); + gtk_style_context_set_scale (style, meta_theme_get_window_scaling_factor ()); + gtk_style_context_set_parent (style, parent_style); - base = NULL; + if (parent_style) + path = gtk_widget_path_copy (gtk_style_context_get_path (parent_style)); + else + path = gtk_widget_path_new (); - base = meta_color_spec_new_from_string (split[1], err); - if (base == NULL) - { - g_strfreev (split); - return NULL; - } + gtk_widget_path_append_type (path, widget_type); - g_strfreev (split); + if (object_name) + gtk_widget_path_iter_set_object_name (path, -1, object_name); - spec = meta_color_spec_new (META_COLOR_SPEC_SHADE); - spec->data.shade.factor = factor; - spec->data.shade.base = base; + state = gtk_style_context_get_state (style); + if (meta_get_locale_direction() == META_LOCALE_DIRECTION_RTL) + { + state |= GTK_STATE_FLAG_DIR_RTL; + state &= ~GTK_STATE_FLAG_DIR_LTR; } else { - spec = meta_color_spec_new (META_COLOR_SPEC_BASIC); - - if (!gdk_rgba_parse (&spec->data.basic.color, str)) - { - g_set_error (err, META_THEME_ERROR, - META_THEME_ERROR_FAILED, - _("Could not parse color \"%s\""), - str); - meta_color_spec_free (spec); - return NULL; - } + state |= GTK_STATE_FLAG_DIR_LTR; + state &= ~GTK_STATE_FLAG_DIR_RTL; } + gtk_style_context_set_state (style, state); - g_assert (spec); - - return spec; -} + va_start (ap, first_class); + for (name = first_class; name; name = va_arg (ap, const char *)) + gtk_widget_path_iter_add_class (path, -1, name); + va_end (ap); -/** - * meta_color_spec_new_gtk: (skip) - * - */ -LOCAL_SYMBOL LOCAL_SYMBOL MetaColorSpec* -meta_color_spec_new_gtk (MetaGtkColorComponent component, - GtkStateFlags state) -{ - MetaColorSpec *spec; + gtk_style_context_set_path (style, path); + gtk_widget_path_unref (path); - spec = meta_color_spec_new (META_COLOR_SPEC_GTK); + gtk_style_context_add_provider (style, GTK_STYLE_PROVIDER (provider), + GTK_STYLE_PROVIDER_PRIORITY_SETTINGS); - spec->data.gtk.component = component; - spec->data.gtk.state = state; + return style; +} - return spec; +static inline GtkCssProvider * +get_css_provider_for_theme_name (const gchar *theme_name, + const gchar *variant) +{ + static GtkCssProvider *default_provider = NULL; + + if (!theme_name || *theme_name == '\0') + { + if (G_UNLIKELY (default_provider == NULL)) + default_provider = gtk_css_provider_new (); + + return default_provider; + } + + return gtk_css_provider_get_named (theme_name, variant); +} + +MetaStyleInfo * +meta_theme_create_style_info (GdkScreen *screen, + const gchar *variant) +{ + MetaStyleInfo *style_info; + GtkCssProvider *provider; + char *theme_name; + + g_object_get (gtk_settings_get_for_screen (screen), + "gtk-theme-name", &theme_name, + NULL); + + provider = get_css_provider_for_theme_name (theme_name, variant); + g_free (theme_name); + + style_info = g_new0 (MetaStyleInfo, 1); + style_info->refcount = 1; + + style_info->styles[META_STYLE_ELEMENT_WINDOW] = + create_style_context (META_TYPE_FRAMES, + NULL, + provider, + "window", + GTK_STYLE_CLASS_BACKGROUND, + "ssd", + NULL); + style_info->styles[META_STYLE_ELEMENT_FRAME] = + create_style_context (META_TYPE_FRAMES, + style_info->styles[META_STYLE_ELEMENT_WINDOW], + provider, + "decoration", + NULL); + style_info->styles[META_STYLE_ELEMENT_TITLEBAR] = + create_style_context (GTK_TYPE_HEADER_BAR, + style_info->styles[META_STYLE_ELEMENT_FRAME], + provider, + "headerbar", + GTK_STYLE_CLASS_TITLEBAR, + GTK_STYLE_CLASS_HORIZONTAL, + "default-decoration", + NULL); + style_info->styles[META_STYLE_ELEMENT_TITLE] = + create_style_context (GTK_TYPE_LABEL, + style_info->styles[META_STYLE_ELEMENT_TITLEBAR], + provider, + "label", + GTK_STYLE_CLASS_TITLE, + NULL); + style_info->styles[META_STYLE_ELEMENT_BUTTON] = + create_style_context (GTK_TYPE_BUTTON, + style_info->styles[META_STYLE_ELEMENT_TITLEBAR], + provider, + "button", + "titlebutton", + NULL); + style_info->styles[META_STYLE_ELEMENT_IMAGE] = + create_style_context (GTK_TYPE_IMAGE, + style_info->styles[META_STYLE_ELEMENT_BUTTON], + provider, + "image", + NULL); + return style_info; +} + +MetaStyleInfo * +meta_style_info_ref (MetaStyleInfo *style_info) +{ + g_return_val_if_fail (style_info != NULL, NULL); + g_return_val_if_fail (style_info->refcount > 0, NULL); + + g_atomic_int_inc ((volatile int *)&style_info->refcount); + return style_info; } -static void -get_background_color (GtkStyleContext *context, - GtkStateFlags state, - GdkRGBA *color) +void +meta_style_info_unref (MetaStyleInfo *style_info) { - gtk_style_context_get_background_color (context, state, color); - - GdkRGBA empty = {0.0, 0.0, 0.0, 0.0}; + g_return_if_fail (style_info != NULL); + g_return_if_fail (style_info->refcount > 0); - // Sometimes the widget has no background color, so append the background - // class and ask again. - if (gdk_rgba_equal(color, &empty)) + if (g_atomic_int_dec_and_test ((volatile int *)&style_info->refcount)) { - gtk_style_context_add_class (context, GTK_STYLE_CLASS_BACKGROUND); - gtk_style_context_get_background_color (context, state, color); + int i; + for (i = 0; i < META_STYLE_ELEMENT_LAST; i++) + g_object_unref (style_info->styles[i]); + g_free (style_info); } } -/* Based on set_color() in gtkstyle.c */ -#define LIGHTNESS_MULT 1.3 -#define DARKNESS_MULT 0.7 -LOCAL_SYMBOL void -meta_gtk_style_get_light_color (GtkStyleContext *style, - GtkStateFlags state, - GdkRGBA *color) -{ - get_background_color (style, state, color); - gtk_style_shade (color, color, LIGHTNESS_MULT); -} - -LOCAL_SYMBOL void -meta_gtk_style_get_dark_color (GtkStyleContext *style, - GtkStateFlags state, - GdkRGBA *color) -{ - get_background_color (style, state, color); - gtk_style_shade (color, color, DARKNESS_MULT); -} - static void -meta_set_color_from_style (GdkRGBA *color, - GtkStyleContext *context, - GtkStateFlags state, - MetaGtkColorComponent component) +add_toplevel_class (GtkStyleContext *style, + const char *class_name) { - GdkRGBA other; - - switch (component) + if (gtk_style_context_get_parent (style)) { - case META_GTK_COLOR_BG: - case META_GTK_COLOR_BASE: - get_background_color (context, state, color); - break; - case META_GTK_COLOR_FG: - case META_GTK_COLOR_TEXT: - gtk_style_context_get_color (context, state, color); - break; - case META_GTK_COLOR_TEXT_AA: - gtk_style_context_get_color (context, state, color); - meta_set_color_from_style (&other, context, state, META_GTK_COLOR_BASE); - - color->red = (color->red + other.red) / 2; - color->green = (color->green + other.green) / 2; - color->blue = (color->blue + other.blue) / 2; - break; - case META_GTK_COLOR_MID: - meta_gtk_style_get_light_color (context, state, color); - meta_gtk_style_get_dark_color (context, state, &other); + GtkWidgetPath *path; - color->red = (color->red + other.red) / 2; - color->green = (color->green + other.green) / 2; - color->blue = (color->blue + other.blue) / 2; - break; - case META_GTK_COLOR_LIGHT: - meta_gtk_style_get_light_color (context, state, color); - break; - case META_GTK_COLOR_DARK: - meta_gtk_style_get_dark_color (context, state, color); - break; - case META_GTK_COLOR_LAST: - g_assert_not_reached (); - break; + path = gtk_widget_path_copy (gtk_style_context_get_path (style)); + gtk_widget_path_iter_add_class (path, 0, class_name); + gtk_style_context_set_path (style, path); + gtk_widget_path_unref (path); } + else + gtk_style_context_add_class (style, class_name); } static void -meta_set_custom_color_from_style (GdkRGBA *color, - GtkStyleContext *context, - char *color_name, - MetaColorSpec *fallback) -{ - if (!gtk_style_context_lookup_color (context, color_name, color)) - meta_color_spec_render (fallback, context, color); -} - -LOCAL_SYMBOL void -meta_color_spec_render (MetaColorSpec *spec, - GtkStyleContext *context, - GdkRGBA *color) +remove_toplevel_class (GtkStyleContext *style, + const char *class_name) { - g_return_if_fail (spec != NULL); - g_return_if_fail (GTK_IS_STYLE_CONTEXT (context)); - - switch (spec->type) + if (gtk_style_context_get_parent (style)) { - case META_COLOR_SPEC_BASIC: - *color = spec->data.basic.color; - break; - - case META_COLOR_SPEC_GTK: - meta_set_color_from_style (color, - context, - spec->data.gtk.state, - spec->data.gtk.component); - break; + GtkWidgetPath *path; - case META_COLOR_SPEC_GTK_CUSTOM: - meta_set_custom_color_from_style (color, - context, - spec->data.gtkcustom.color_name, - spec->data.gtkcustom.fallback); - break; + path = gtk_widget_path_copy (gtk_style_context_get_path (style)); + gtk_widget_path_iter_remove_class (path, 0, class_name); + gtk_style_context_set_path (style, path); + gtk_widget_path_unref (path); + } + else + gtk_style_context_remove_class (style, class_name); +} - case META_COLOR_SPEC_BLEND: - { - GdkRGBA bg, fg; +void +meta_style_info_set_flags (MetaStyleInfo *style_info, + MetaFrameFlags flags) +{ + GtkStyleContext *style; + const char *class_name = NULL; + gboolean backdrop; + GtkStateFlags state; + int i; - meta_color_spec_render (spec->data.blend.background, context, &bg); - meta_color_spec_render (spec->data.blend.foreground, context, &fg); + backdrop = !(flags & META_FRAME_HAS_FOCUS); - color_composite (&bg, &fg, spec->data.blend.alpha, - &spec->data.blend.color); + if (flags & META_FRAME_MAXIMIZED) + class_name = "maximized"; + else if (flags & META_FRAME_TILED_LEFT || + flags & META_FRAME_TILED_RIGHT) + class_name = "tiled"; - *color = spec->data.blend.color; - } - break; + for (i = 0; i < META_STYLE_ELEMENT_LAST; i++) + { + style = style_info->styles[i]; - case META_COLOR_SPEC_SHADE: - { - meta_color_spec_render (spec->data.shade.base, context, - &spec->data.shade.color); + state = gtk_style_context_get_state (style); + if (backdrop) + gtk_style_context_set_state (style, state | GTK_STATE_FLAG_BACKDROP); + else + gtk_style_context_set_state (style, state & ~GTK_STATE_FLAG_BACKDROP); - gtk_style_shade (&spec->data.shade.color, - &spec->data.shade.color, spec->data.shade.factor); + remove_toplevel_class (style, "maximized"); + remove_toplevel_class (style, "tiled"); - *color = spec->data.shade.color; - } - break; + if (class_name) + add_toplevel_class (style, class_name); } } -/* - * Represents an operation as a string. - * - * \param type an operation, such as addition - * \return a string, such as "+" - */ -static const char* -op_name (PosOperatorType type) +PangoFontDescription* +meta_style_info_create_font_desc (MetaStyleInfo *style_info) { - switch (type) - { - case POS_OP_ADD: - return "+"; - case POS_OP_SUBTRACT: - return "-"; - case POS_OP_MULTIPLY: - return "*"; - case POS_OP_DIVIDE: - return "/"; - case POS_OP_MOD: - return "%"; - case POS_OP_MAX: - return "`max`"; - case POS_OP_MIN: - return "`min`"; - case POS_OP_NONE: - break; - } - - return "<unknown>"; -} + PangoFontDescription *font_desc; + const PangoFontDescription *override = meta_prefs_get_titlebar_font (); + GtkStyleContext *context = style_info->styles[META_STYLE_ELEMENT_TITLE]; -/* - * Parses a string and returns an operation. - * - * \param p a pointer into a string representing an operation; part of an - * expression somewhere, so not null-terminated - * \param len set to the length of the string found. Set to 0 if none is. - * \return the operation found. If none was, returns POS_OP_NONE. - */ -static PosOperatorType -op_from_string (const char *p, - int *len) -{ - *len = 0; + gtk_style_context_get (context, + gtk_style_context_get_state (context), + "font", &font_desc, NULL); - switch (*p) - { - case '+': - *len = 1; - return POS_OP_ADD; - case '-': - *len = 1; - return POS_OP_SUBTRACT; - case '*': - *len = 1; - return POS_OP_MULTIPLY; - case '/': - *len = 1; - return POS_OP_DIVIDE; - case '%': - *len = 1; - return POS_OP_MOD; - - case '`': - if (p[0] == '`' && - p[1] == 'm' && - p[2] == 'a' && - p[3] == 'x' && - p[4] == '`') - { - *len = 5; - return POS_OP_MAX; - } - else if (p[0] == '`' && - p[1] == 'm' && - p[2] == 'i' && - p[3] == 'n' && - p[4] == '`') - { - *len = 5; - return POS_OP_MIN; - } - } + if (override) + pango_font_description_merge (font_desc, override, TRUE); - return POS_OP_NONE; -} - -/* - * Frees an array of tokens. All the tokens and their associated memory - * will be freed. - * - * \param tokens an array of tokens to be freed - * \param n_tokens how many tokens are in the array. - */ -static void -free_tokens (PosToken *tokens, - int n_tokens) -{ - int i; - - /* n_tokens can be 0 since tokens may have been allocated more than - * it was initialized - */ - - for (i = 0; i < n_tokens; i++) - if (tokens[i].type == POS_TOKEN_VARIABLE) - free (tokens[i].d.v.name); - - free (tokens); -} - -/* - * Tokenises a number in an expression. - * - * \param p a pointer into a string representing an operation; part of an - * expression somewhere, so not null-terminated - * \param end_return set to a pointer to the end of the number found; but - * not updated if no number was found at all - * \param next set to either an integer or a float token - * \param[out] err set to the problem if there was a problem - * \return TRUE if a valid number was found, FALSE otherwise (and "err" will - * have been set) - * - * \bug The "while (*start)..." part: what's wrong with strchr-ish things? - * \bug The name is wrong: it doesn't parse anything. - * \ingroup tokenizer - */ -static gboolean -parse_number (const char *p, - const char **end_return, - PosToken *next, - GError **err) -{ - const char *start = p; - char *end; - gboolean is_float; - char *num_str; - - while (*p && (*p == '.' || g_ascii_isdigit (*p))) - ++p; - - if (p == start) - { - char buf[7] = { '\0' }; - buf[g_unichar_to_utf8 (g_utf8_get_char (p), buf)] = '\0'; - g_set_error (err, META_THEME_ERROR, - META_THEME_ERROR_BAD_CHARACTER, - _("Coordinate expression contains character '%s' which is not allowed"), - buf); - return FALSE; - } - - *end_return = p; - - /* we need this to exclude floats like "1e6" */ - num_str = g_strndup (start, p - start); - start = num_str; - is_float = FALSE; - while (*start) - { - if (*start == '.') - is_float = TRUE; - ++start; - } - - if (is_float) - { - next->type = POS_TOKEN_DOUBLE; - next->d.d.val = g_ascii_strtod (num_str, &end); - - if (end == num_str) - { - g_set_error (err, META_THEME_ERROR, - META_THEME_ERROR_FAILED, - _("Coordinate expression contains floating point number '%s' which could not be parsed"), - num_str); - free (num_str); - return FALSE; - } - } - else - { - next->type = POS_TOKEN_INT; - next->d.i.val = strtol (num_str, &end, 10); - if (end == num_str) - { - g_set_error (err, META_THEME_ERROR, - META_THEME_ERROR_FAILED, - _("Coordinate expression contains integer '%s' which could not be parsed"), - num_str); - free (num_str); - return FALSE; - } - } - - free (num_str); - - g_assert (next->type == POS_TOKEN_INT || next->type == POS_TOKEN_DOUBLE); - - return TRUE; -} - -/* - * Whether a variable can validly appear as part of the name of a variable. - */ -#define IS_VARIABLE_CHAR(c) (g_ascii_isalpha ((c)) || (c) == '_') - -#if 0 -static void -debug_print_tokens (PosToken *tokens, - int n_tokens) -{ - int i; - - for (i = 0; i < n_tokens; i++) - { - PosToken *t = &tokens[i]; - - g_print (" "); - - switch (t->type) - { - case POS_TOKEN_INT: - g_print ("\"%d\"", t->d.i.val); - break; - case POS_TOKEN_DOUBLE: - g_print ("\"%g\"", t->d.d.val); - break; - case POS_TOKEN_OPEN_PAREN: - g_print ("\"(\""); - break; - case POS_TOKEN_CLOSE_PAREN: - g_print ("\")\""); - break; - case POS_TOKEN_VARIABLE: - g_print ("\"%s\"", t->d.v.name); - break; - case POS_TOKEN_OPERATOR: - g_print ("\"%s\"", op_name (t->d.o.op)); - break; - } - } - - g_print ("\n"); -} -#endif - -/* - * Tokenises an expression. - * - * \param expr The expression - * \param[out] tokens_p The resulting tokens - * \param[out] n_tokens_p The number of resulting tokens - * \param[out] err set to the problem if there was a problem - * - * \return True if the expression was successfully tokenised; false otherwise. - * - * \ingroup tokenizer - */ -static gboolean -pos_tokenize (const char *expr, - PosToken **tokens_p, - int *n_tokens_p, - GError **err) -{ - PosToken *tokens; - int n_tokens; - int allocated; - const char *p; - - *tokens_p = NULL; - *n_tokens_p = 0; - - allocated = 3; - n_tokens = 0; - tokens = g_new (PosToken, allocated); - - p = expr; - while (*p) - { - PosToken *next; - int len; - - if (n_tokens == allocated) - { - allocated *= 2; - tokens = g_renew (PosToken, tokens, allocated); - } - - next = &tokens[n_tokens]; - - switch (*p) - { - case '*': - case '/': - case '+': - case '-': /* negative numbers aren't allowed so this is easy */ - case '%': - case '`': - next->type = POS_TOKEN_OPERATOR; - next->d.o.op = op_from_string (p, &len); - if (next->d.o.op != POS_OP_NONE) - { - ++n_tokens; - p = p + (len - 1); /* -1 since we ++p later */ - } - else - { - g_set_error (err, META_THEME_ERROR, - META_THEME_ERROR_FAILED, - _("Coordinate expression contained unknown operator at the start of this text: \"%s\""), - p); - - goto error; - } - break; - - case '(': - next->type = POS_TOKEN_OPEN_PAREN; - ++n_tokens; - break; - - case ')': - next->type = POS_TOKEN_CLOSE_PAREN; - ++n_tokens; - break; - - case ' ': - case '\t': - case '\n': - break; - - default: - if (IS_VARIABLE_CHAR (*p)) - { - /* Assume variable */ - const char *start = p; - while (*p && IS_VARIABLE_CHAR (*p)) - ++p; - g_assert (p != start); - next->type = POS_TOKEN_VARIABLE; - next->d.v.name = g_strndup (start, p - start); - ++n_tokens; - --p; /* since we ++p again at the end of while loop */ - } - else - { - /* Assume number */ - const char *end; - - if (!parse_number (p, &end, next, err)) - goto error; - - ++n_tokens; - p = end - 1; /* -1 since we ++p again at the end of while loop */ - } - - break; - } - - ++p; - } - - if (n_tokens == 0) - { - g_set_error (err, META_THEME_ERROR, - META_THEME_ERROR_FAILED, - _("Coordinate expression was empty or not understood")); - - goto error; - } - - *tokens_p = tokens; - *n_tokens_p = n_tokens; - - return TRUE; - - error: - g_assert (err == NULL || *err != NULL); - - free_tokens (tokens, n_tokens); - return FALSE; -} - -/* - * The type of a PosExpr: either integer, double, or an operation. - * \ingroup parser - */ -typedef enum -{ - POS_EXPR_INT, - POS_EXPR_DOUBLE, - POS_EXPR_OPERATOR -} PosExprType; - -/* - * Type and value of an expression in a parsed sequence. We don't - * keep expressions in a tree; if this is of type POS_EXPR_OPERATOR, - * the arguments of the operator will be in the array positions - * immediately preceding and following this operator; they cannot - * themselves be operators. - * - * \bug operator is char; it should really be of PosOperatorType. - * \ingroup parser - */ -typedef struct -{ - PosExprType type; - union - { - double double_val; - int int_val; - char operator; - } d; -} PosExpr; - -#if 0 -static void -debug_print_exprs (PosExpr *exprs, - int n_exprs) -{ - int i; - - for (i = 0; i < n_exprs; i++) - { - switch (exprs[i].type) - { - case POS_EXPR_INT: - g_print (" %d", exprs[i].d.int_val); - break; - case POS_EXPR_DOUBLE: - g_print (" %g", exprs[i].d.double_val); - break; - case POS_EXPR_OPERATOR: - g_print (" %s", op_name (exprs[i].d.operator)); - break; - } - } - g_print ("\n"); -} -#endif - -static gboolean -do_operation (PosExpr *a, - PosExpr *b, - PosOperatorType op, - GError **err) -{ - /* Promote types to double if required */ - if (a->type == POS_EXPR_DOUBLE || - b->type == POS_EXPR_DOUBLE) - { - if (a->type != POS_EXPR_DOUBLE) - { - a->type = POS_EXPR_DOUBLE; - a->d.double_val = a->d.int_val; - } - if (b->type != POS_EXPR_DOUBLE) - { - b->type = POS_EXPR_DOUBLE; - b->d.double_val = b->d.int_val; - } - } - - g_assert (a->type == b->type); - - if (a->type == POS_EXPR_INT) - { - switch (op) - { - case POS_OP_MULTIPLY: - a->d.int_val = a->d.int_val * b->d.int_val; - break; - case POS_OP_DIVIDE: - if (b->d.int_val == 0) - { - g_set_error (err, META_THEME_ERROR, - META_THEME_ERROR_DIVIDE_BY_ZERO, - _("Coordinate expression results in division by zero")); - return FALSE; - } - a->d.int_val = a->d.int_val / b->d.int_val; - break; - case POS_OP_MOD: - if (b->d.int_val == 0) - { - g_set_error (err, META_THEME_ERROR, - META_THEME_ERROR_DIVIDE_BY_ZERO, - _("Coordinate expression results in division by zero")); - return FALSE; - } - a->d.int_val = a->d.int_val % b->d.int_val; - break; - case POS_OP_ADD: - a->d.int_val = a->d.int_val + b->d.int_val; - break; - case POS_OP_SUBTRACT: - a->d.int_val = a->d.int_val - b->d.int_val; - break; - case POS_OP_MAX: - a->d.int_val = MAX (a->d.int_val, b->d.int_val); - break; - case POS_OP_MIN: - a->d.int_val = MIN (a->d.int_val, b->d.int_val); - break; - case POS_OP_NONE: - g_assert_not_reached (); - break; - } - } - else if (a->type == POS_EXPR_DOUBLE) - { - switch (op) - { - case POS_OP_MULTIPLY: - a->d.double_val = a->d.double_val * b->d.double_val; - break; - case POS_OP_DIVIDE: - if (b->d.double_val == 0.0) - { - g_set_error (err, META_THEME_ERROR, - META_THEME_ERROR_DIVIDE_BY_ZERO, - _("Coordinate expression results in division by zero")); - return FALSE; - } - a->d.double_val = a->d.double_val / b->d.double_val; - break; - case POS_OP_MOD: - g_set_error (err, META_THEME_ERROR, - META_THEME_ERROR_MOD_ON_FLOAT, - _("Coordinate expression tries to use mod operator on a floating-point number")); - return FALSE; - case POS_OP_ADD: - a->d.double_val = a->d.double_val + b->d.double_val; - break; - case POS_OP_SUBTRACT: - a->d.double_val = a->d.double_val - b->d.double_val; - break; - case POS_OP_MAX: - a->d.double_val = MAX (a->d.double_val, b->d.double_val); - break; - case POS_OP_MIN: - a->d.double_val = MIN (a->d.double_val, b->d.double_val); - break; - case POS_OP_NONE: - g_assert_not_reached (); - break; - } - } - else - g_assert_not_reached (); - - return TRUE; -} - -static gboolean -do_operations (PosExpr *exprs, - int *n_exprs, - int precedence, - GError **err) -{ - int i; - -#if 0 - g_print ("Doing prec %d ops on %d exprs\n", precedence, *n_exprs); - debug_print_exprs (exprs, *n_exprs); -#endif - - i = 1; - while (i < *n_exprs) - { - gboolean compress; - - /* exprs[i-1] first operand - * exprs[i] operator - * exprs[i+1] second operand - * - * we replace first operand with result of mul/div/mod, - * or skip over operator and second operand if we have - * an add/subtract - */ - - if (exprs[i-1].type == POS_EXPR_OPERATOR) - { - g_set_error (err, META_THEME_ERROR, - META_THEME_ERROR_FAILED, - _("Coordinate expression has an operator \"%s\" where an operand was expected"), - op_name (exprs[i-1].d.operator)); - return FALSE; - } - - if (exprs[i].type != POS_EXPR_OPERATOR) - { - g_set_error (err, META_THEME_ERROR, - META_THEME_ERROR_FAILED, - _("Coordinate expression had an operand where an operator was expected")); - return FALSE; - } - - if (i == (*n_exprs - 1)) - { - g_set_error (err, META_THEME_ERROR, - META_THEME_ERROR_FAILED, - _("Coordinate expression ended with an operator instead of an operand")); - return FALSE; - } - - g_assert ((i+1) < *n_exprs); - - if (exprs[i+1].type == POS_EXPR_OPERATOR) - { - g_set_error (err, META_THEME_ERROR, - META_THEME_ERROR_FAILED, - _("Coordinate expression has operator \"%c\" following operator \"%c\" with no operand in between"), - exprs[i+1].d.operator, - exprs[i].d.operator); - return FALSE; - } - - compress = FALSE; - - switch (precedence) - { - case 2: - switch (exprs[i].d.operator) - { - case POS_OP_DIVIDE: - case POS_OP_MOD: - case POS_OP_MULTIPLY: - compress = TRUE; - if (!do_operation (&exprs[i-1], &exprs[i+1], - exprs[i].d.operator, - err)) - return FALSE; - break; - } - break; - case 1: - switch (exprs[i].d.operator) - { - case POS_OP_ADD: - case POS_OP_SUBTRACT: - compress = TRUE; - if (!do_operation (&exprs[i-1], &exprs[i+1], - exprs[i].d.operator, - err)) - return FALSE; - break; - } - break; - /* I have no rationale at all for making these low-precedence */ - case 0: - switch (exprs[i].d.operator) - { - case POS_OP_MAX: - case POS_OP_MIN: - compress = TRUE; - if (!do_operation (&exprs[i-1], &exprs[i+1], - exprs[i].d.operator, - err)) - return FALSE; - break; - } - break; - } - - if (compress) - { - /* exprs[i-1] first operand (now result) - * exprs[i] operator - * exprs[i+1] second operand - * exprs[i+2] new operator - * - * we move new operator just after first operand - */ - if ((i+2) < *n_exprs) - { - g_memmove (&exprs[i], &exprs[i+2], - sizeof (PosExpr) * (*n_exprs - i - 2)); - } - - *n_exprs -= 2; - } - else - { - /* Skip operator and next operand */ - i += 2; - } - } - - return TRUE; -} - -/* - * There is a predefined set of variables which can appear in an expression. - * Here we take a token representing a variable, and return the current value - * of that variable in a particular environment. - * (The value is always an integer.) - * - * There are supposedly some circumstances in which this function can be - * called from outside Metacity, in which case env->theme will be NULL, and - * therefore we can't use it to find out quark values, so we do the comparison - * using strcmp, which is slower. - * - * \param t The token representing a variable - * \param[out] result The value of that variable; not set if the token did - * not represent a known variable - * \param env The environment within which t should be evaluated - * \param[out] err set to the problem if there was a problem - * - * \return true if we found the variable asked for, false if we didn't - * - * \bug shouldn't t be const? - * \bug we should perhaps consider some sort of lookup arrangement into an - * array; also, the duplication of code is unlovely; perhaps using glib - * string hashes instead of quarks would fix both problems? - * \ingroup parser - */ -static gboolean -pos_eval_get_variable (PosToken *t, - int *result, - const MetaPositionExprEnv *env, - GError **err) -{ - if (env->theme) - { - if (t->d.v.name_quark == env->theme->quark_width) - *result = env->rect.width; - else if (t->d.v.name_quark == env->theme->quark_height) - *result = env->rect.height; - else if (env->object_width >= 0 && - t->d.v.name_quark == env->theme->quark_object_width) - *result = env->object_width; - else if (env->object_height >= 0 && - t->d.v.name_quark == env->theme->quark_object_height) - *result = env->object_height; - else if (t->d.v.name_quark == env->theme->quark_left_width) - *result = env->left_width; - else if (t->d.v.name_quark == env->theme->quark_right_width) - *result = env->right_width; - else if (t->d.v.name_quark == env->theme->quark_top_height) - *result = env->top_height; - else if (t->d.v.name_quark == env->theme->quark_bottom_height) - *result = env->bottom_height; - else if (t->d.v.name_quark == env->theme->quark_mini_icon_width) - *result = env->mini_icon_width; - else if (t->d.v.name_quark == env->theme->quark_mini_icon_height) - *result = env->mini_icon_height; - else if (t->d.v.name_quark == env->theme->quark_icon_width) - *result = env->icon_width; - else if (t->d.v.name_quark == env->theme->quark_icon_height) - *result = env->icon_height; - else if (t->d.v.name_quark == env->theme->quark_title_width) - *result = env->title_width; - else if (t->d.v.name_quark == env->theme->quark_title_height) - *result = env->title_height; - else if (t->d.v.name_quark == env->theme->quark_frame_x_center) - *result = env->frame_x_center; - else if (t->d.v.name_quark == env->theme->quark_frame_y_center) - *result = env->frame_y_center; - else - { - g_set_error (err, META_THEME_ERROR, - META_THEME_ERROR_UNKNOWN_VARIABLE, - _("Coordinate expression had unknown variable or constant \"%s\""), - t->d.v.name); - return FALSE; - } - } - else - { - if (strcmp (t->d.v.name, "width") == 0) - *result = env->rect.width; - else if (strcmp (t->d.v.name, "height") == 0) - *result = env->rect.height; - else if (env->object_width >= 0 && - strcmp (t->d.v.name, "object_width") == 0) - *result = env->object_width; - else if (env->object_height >= 0 && - strcmp (t->d.v.name, "object_height") == 0) - *result = env->object_height; - else if (strcmp (t->d.v.name, "left_width") == 0) - *result = env->left_width; - else if (strcmp (t->d.v.name, "right_width") == 0) - *result = env->right_width; - else if (strcmp (t->d.v.name, "top_height") == 0) - *result = env->top_height; - else if (strcmp (t->d.v.name, "bottom_height") == 0) - *result = env->bottom_height; - else if (strcmp (t->d.v.name, "mini_icon_width") == 0) - *result = env->mini_icon_width; - else if (strcmp (t->d.v.name, "mini_icon_height") == 0) - *result = env->mini_icon_height; - else if (strcmp (t->d.v.name, "icon_width") == 0) - *result = env->icon_width; - else if (strcmp (t->d.v.name, "icon_height") == 0) - *result = env->icon_height; - else if (strcmp (t->d.v.name, "title_width") == 0) - *result = env->title_width; - else if (strcmp (t->d.v.name, "title_height") == 0) - *result = env->title_height; - else if (strcmp (t->d.v.name, "frame_x_center") == 0) - *result = env->frame_x_center; - else if (strcmp (t->d.v.name, "frame_y_center") == 0) - *result = env->frame_y_center; - else - { - g_set_error (err, META_THEME_ERROR, - META_THEME_ERROR_UNKNOWN_VARIABLE, - _("Coordinate expression had unknown variable or constant \"%s\""), - t->d.v.name); - return FALSE; - } - } - - return TRUE; -} - -/* - * Evaluates a sequence of tokens within a particular environment context, - * and returns the current value. May recur if parantheses are found. - * - * \param tokens A list of tokens to evaluate. - * \param n_tokens How many tokens are in the list. - * \param env The environment context in which to evaluate the expression. - * \param[out] result The current value of the expression - * - * \bug Yes, we really do reparse the expression every time it's evaluated. - * We should keep the parse tree around all the time and just - * run the new values through it. - * \ingroup parser - */ -static gboolean -pos_eval_helper (PosToken *tokens, - int n_tokens, - const MetaPositionExprEnv *env, - PosExpr *result, - GError **err) -{ - /* Lazy-ass hardcoded limit on number of terms in expression */ -#define MAX_EXPRS 32 - int paren_level; - int first_paren; - int i; - PosExpr exprs[MAX_EXPRS]; - int n_exprs; - int precedence; - - /* Our first goal is to get a list of PosExpr, essentially - * substituting variables and handling parentheses. - */ - - first_paren = 0; - paren_level = 0; - n_exprs = 0; - for (i = 0; i < n_tokens; i++) - { - PosToken *t = &tokens[i]; - - if (n_exprs >= MAX_EXPRS) - { - g_set_error (err, META_THEME_ERROR, - META_THEME_ERROR_FAILED, - _("Coordinate expression parser overflowed its buffer.")); - return FALSE; - } - - if (paren_level == 0) - { - switch (t->type) - { - case POS_TOKEN_INT: - exprs[n_exprs].type = POS_EXPR_INT; - exprs[n_exprs].d.int_val = t->d.i.val; - ++n_exprs; - break; - - case POS_TOKEN_DOUBLE: - exprs[n_exprs].type = POS_EXPR_DOUBLE; - exprs[n_exprs].d.double_val = t->d.d.val; - ++n_exprs; - break; - - case POS_TOKEN_OPEN_PAREN: - ++paren_level; - if (paren_level == 1) - first_paren = i; - break; - - case POS_TOKEN_CLOSE_PAREN: - g_set_error (err, META_THEME_ERROR, - META_THEME_ERROR_BAD_PARENS, - _("Coordinate expression had a close parenthesis with no open parenthesis")); - return FALSE; - - case POS_TOKEN_VARIABLE: - exprs[n_exprs].type = POS_EXPR_INT; - - /* FIXME we should just dump all this crap - * in a hash, maybe keep width/height out - * for optimization purposes - */ - if (!pos_eval_get_variable (t, &exprs[n_exprs].d.int_val, env, err)) - return FALSE; - - ++n_exprs; - break; - - case POS_TOKEN_OPERATOR: - exprs[n_exprs].type = POS_EXPR_OPERATOR; - exprs[n_exprs].d.operator = t->d.o.op; - ++n_exprs; - break; - } - } - else - { - g_assert (paren_level > 0); - - switch (t->type) - { - case POS_TOKEN_INT: - case POS_TOKEN_DOUBLE: - case POS_TOKEN_VARIABLE: - case POS_TOKEN_OPERATOR: - break; - - case POS_TOKEN_OPEN_PAREN: - ++paren_level; - break; - - case POS_TOKEN_CLOSE_PAREN: - if (paren_level == 1) - { - /* We closed a toplevel paren group, so recurse */ - if (!pos_eval_helper (&tokens[first_paren+1], - i - first_paren - 1, - env, - &exprs[n_exprs], - err)) - return FALSE; - - ++n_exprs; - } - - --paren_level; - break; - - } - } - } - - if (paren_level > 0) - { - g_set_error (err, META_THEME_ERROR, - META_THEME_ERROR_BAD_PARENS, - _("Coordinate expression had an open parenthesis with no close parenthesis")); - return FALSE; - } - - /* Now we have no parens and no vars; so we just do all the multiplies - * and divides, then all the add and subtract. - */ - if (n_exprs == 0) - { - g_set_error (err, META_THEME_ERROR, - META_THEME_ERROR_FAILED, - _("Coordinate expression doesn't seem to have any operators or operands")); - return FALSE; - } - - /* precedence 1 ops */ - precedence = 2; - while (precedence >= 0) - { - if (!do_operations (exprs, &n_exprs, precedence, err)) - return FALSE; - --precedence; - } - - g_assert (n_exprs == 1); - - *result = *exprs; - - return TRUE; -} - -/* - * expr = int | double | expr * expr | expr / expr | - * expr + expr | expr - expr | (expr) - * - * so very not worth fooling with bison, yet so very painful by hand. - */ -/* - * Evaluates an expression. - * - * \param spec The expression to evaluate. - * \param env The environment context to evaluate the expression in. - * \param[out] val_p The integer value of the expression; if the expression - * is of type float, this will be rounded. If we return - * FALSE because the expression is invalid, this will be - * zero. - * \param[out] err The error, if anything went wrong. - * - * \return True if we evaluated the expression successfully; false otherwise. - * - * \bug Shouldn't spec be const? - * \ingroup parser - */ -static gboolean -pos_eval (MetaDrawSpec *spec, - const MetaPositionExprEnv *env, - int *val_p, - GError **err) -{ - PosExpr expr; - - *val_p = 0; - - if (pos_eval_helper (spec->tokens, spec->n_tokens, env, &expr, err)) - { - switch (expr.type) - { - case POS_EXPR_INT: - *val_p = expr.d.int_val; - break; - case POS_EXPR_DOUBLE: - *val_p = expr.d.double_val; - break; - case POS_EXPR_OPERATOR: - g_assert_not_reached (); - break; - } - return TRUE; - } - else - { - return FALSE; - } -} - -/* We always return both X and Y, but only one will be meaningful in - * most contexts. - */ - -/** - * meta_parse_position_expression: (skip) - * - */ -LOCAL_SYMBOL gboolean -meta_parse_position_expression (MetaDrawSpec *spec, - const MetaPositionExprEnv *env, - int *x_return, - int *y_return, - GError **err) -{ - /* All positions are in a coordinate system with x, y at the origin. - * The expression can have -, +, *, / as operators, floating point - * or integer constants, and the variables "width" and "height" and - * optionally "object_width" and object_height". Negative numbers - * aren't allowed. - */ - int val; - - if (spec->constant) - val = spec->value; - else - { - if (pos_eval (spec, env, &spec->value, err) == FALSE) - { - g_assert (err == NULL || *err != NULL); - return FALSE; - } - - val = spec->value; - } - - if (x_return) - *x_return = env->rect.x + val; - if (y_return) - *y_return = env->rect.y + val; - - return TRUE; -} - - -/** - * meta_parse_size_expression: (skip) - * - */ -LOCAL_SYMBOL gboolean -meta_parse_size_expression (MetaDrawSpec *spec, - const MetaPositionExprEnv *env, - int *val_return, - GError **err) -{ - int val; - - if (spec->constant) - val = spec->value; - else - { - if (pos_eval (spec, env, &spec->value, err) == FALSE) - { - g_assert (err == NULL || *err != NULL); - return FALSE; - } - - val = spec->value; - } - - if (val_return) - *val_return = MAX (val, 1); /* require that sizes be at least 1x1 */ - - return TRUE; -} - -/* To do this we tokenize, replace variable tokens - * that are constants, then reassemble. The purpose - * here is to optimize expressions so we don't do hash - * lookups to eval them. Obviously it's a tradeoff that - * slows down theme load times. - */ -LOCAL_SYMBOL gboolean -meta_theme_replace_constants (MetaTheme *theme, - PosToken *tokens, - int n_tokens, - GError **err) -{ - int i; - double dval; - int ival; - gboolean is_constant = TRUE; - - /* Loop through tokenized string looking for variables to replace */ - for (i = 0; i < n_tokens; i++) - { - PosToken *t = &tokens[i]; - - if (t->type == POS_TOKEN_VARIABLE) - { - if (meta_theme_lookup_int_constant (theme, t->d.v.name, &ival)) - { - free (t->d.v.name); - t->type = POS_TOKEN_INT; - t->d.i.val = ival; - } - else if (meta_theme_lookup_float_constant (theme, t->d.v.name, &dval)) - { - free (t->d.v.name); - t->type = POS_TOKEN_DOUBLE; - t->d.d.val = dval; - } - else - { - /* If we've found a variable that cannot be replaced then the - expression is not a constant expression and we want to - replace it with a GQuark */ - - t->d.v.name_quark = g_quark_from_string (t->d.v.name); - is_constant = FALSE; - } - } - } - - return is_constant; -} - -static int -parse_x_position_unchecked (MetaDrawSpec *spec, - const MetaPositionExprEnv *env) -{ - int retval; - GError *error; - - retval = 0; - error = NULL; - if (!meta_parse_position_expression (spec, env, &retval, NULL, &error)) - { - meta_warning (_("Theme contained an expression that resulted in an error: %s\n"), - error->message); - - g_error_free (error); - } - - return retval; -} - -static int -parse_y_position_unchecked (MetaDrawSpec *spec, - const MetaPositionExprEnv *env) -{ - int retval; - GError *error; - - retval = 0; - error = NULL; - if (!meta_parse_position_expression (spec, env, NULL, &retval, &error)) - { - meta_warning (_("Theme contained an expression that resulted in an error: %s\n"), - error->message); - - g_error_free (error); - } - - return retval; -} - -static int -parse_size_unchecked (MetaDrawSpec *spec, - MetaPositionExprEnv *env) -{ - int retval; - GError *error; - - retval = 0; - error = NULL; - if (!meta_parse_size_expression (spec, env, &retval, &error)) - { - meta_warning (_("Theme contained an expression that resulted in an error: %s\n"), - error->message); - - g_error_free (error); - } - - return retval; -} - -LOCAL_SYMBOL void -meta_draw_spec_free (MetaDrawSpec *spec) -{ - if (!spec) return; - free_tokens (spec->tokens, spec->n_tokens); - g_slice_free (MetaDrawSpec, spec); -} - -/** - * meta_draw_spec_new: (skip) - * - */ -LOCAL_SYMBOL MetaDrawSpec * -meta_draw_spec_new (MetaTheme *theme, - const char *expr, - GError **error) -{ - MetaDrawSpec *spec; - - spec = g_slice_new0 (MetaDrawSpec); - - pos_tokenize (expr, &spec->tokens, &spec->n_tokens, NULL); - - spec->constant = meta_theme_replace_constants (theme, spec->tokens, - spec->n_tokens, NULL); - if (spec->constant) - { - gboolean result; - - result = pos_eval (spec, NULL, &spec->value, error); - if (result == FALSE) - { - meta_draw_spec_free (spec); - return NULL; - } - } - - return spec; -} - -/** - * meta_draw_op_new: (skip) - * - */ -LOCAL_SYMBOL MetaDrawOp* -meta_draw_op_new (MetaDrawType type) -{ - MetaDrawOp *op; - MetaDrawOp dummy; - int size; - - size = G_STRUCT_OFFSET (MetaDrawOp, data); - - switch (type) - { - case META_DRAW_LINE: - size += sizeof (dummy.data.line); - break; - - case META_DRAW_RECTANGLE: - size += sizeof (dummy.data.rectangle); - break; - - case META_DRAW_ARC: - size += sizeof (dummy.data.arc); - break; - - case META_DRAW_CLIP: - size += sizeof (dummy.data.clip); - break; - - case META_DRAW_TINT: - size += sizeof (dummy.data.tint); - break; - - case META_DRAW_GRADIENT: - size += sizeof (dummy.data.gradient); - break; - - case META_DRAW_IMAGE: - size += sizeof (dummy.data.image); - break; - - case META_DRAW_GTK_ARROW: - size += sizeof (dummy.data.gtk_arrow); - break; - - case META_DRAW_GTK_BOX: - size += sizeof (dummy.data.gtk_box); - break; - - case META_DRAW_GTK_VLINE: - size += sizeof (dummy.data.gtk_vline); - break; - - case META_DRAW_ICON: - size += sizeof (dummy.data.icon); - break; - - case META_DRAW_TITLE: - size += sizeof (dummy.data.title); - break; - case META_DRAW_OP_LIST: - size += sizeof (dummy.data.op_list); - break; - case META_DRAW_TILE: - size += sizeof (dummy.data.tile); - break; - } - - op = calloc (1, size); - - op->type = type; - - return op; -} - -LOCAL_SYMBOL void -meta_draw_op_free (MetaDrawOp *op) -{ - g_return_if_fail (op != NULL); - - switch (op->type) - { - case META_DRAW_LINE: - if (op->data.line.color_spec) - meta_color_spec_free (op->data.line.color_spec); - - meta_draw_spec_free (op->data.line.x1); - meta_draw_spec_free (op->data.line.y1); - meta_draw_spec_free (op->data.line.x2); - meta_draw_spec_free (op->data.line.y2); - break; - - case META_DRAW_RECTANGLE: - free (op->data.rectangle.color_spec); - meta_draw_spec_free (op->data.rectangle.x); - meta_draw_spec_free (op->data.rectangle.y); - meta_draw_spec_free (op->data.rectangle.width); - meta_draw_spec_free (op->data.rectangle.height); - break; - - case META_DRAW_ARC: - free (op->data.arc.color_spec); - meta_draw_spec_free (op->data.arc.x); - meta_draw_spec_free (op->data.arc.y); - meta_draw_spec_free (op->data.arc.width); - meta_draw_spec_free (op->data.arc.height); - break; - - case META_DRAW_CLIP: - meta_draw_spec_free (op->data.clip.x); - meta_draw_spec_free (op->data.clip.y); - meta_draw_spec_free (op->data.clip.width); - meta_draw_spec_free (op->data.clip.height); - break; - - case META_DRAW_TINT: - if (op->data.tint.color_spec) - meta_color_spec_free (op->data.tint.color_spec); - - if (op->data.tint.alpha_spec) - meta_alpha_gradient_spec_free (op->data.tint.alpha_spec); - - meta_draw_spec_free (op->data.tint.x); - meta_draw_spec_free (op->data.tint.y); - meta_draw_spec_free (op->data.tint.width); - meta_draw_spec_free (op->data.tint.height); - break; - - case META_DRAW_GRADIENT: - if (op->data.gradient.gradient_spec) - meta_gradient_spec_free (op->data.gradient.gradient_spec); - - if (op->data.gradient.alpha_spec) - meta_alpha_gradient_spec_free (op->data.gradient.alpha_spec); - - meta_draw_spec_free (op->data.gradient.x); - meta_draw_spec_free (op->data.gradient.y); - meta_draw_spec_free (op->data.gradient.width); - meta_draw_spec_free (op->data.gradient.height); - break; - - case META_DRAW_IMAGE: - if (op->data.image.alpha_spec) - meta_alpha_gradient_spec_free (op->data.image.alpha_spec); - - if (op->data.image.pixbuf) - g_object_unref (G_OBJECT (op->data.image.pixbuf)); - - if (op->data.image.colorize_spec) - meta_color_spec_free (op->data.image.colorize_spec); - - if (op->data.image.colorize_cache_pixbuf) - g_object_unref (G_OBJECT (op->data.image.colorize_cache_pixbuf)); - - meta_draw_spec_free (op->data.image.x); - meta_draw_spec_free (op->data.image.y); - meta_draw_spec_free (op->data.image.width); - meta_draw_spec_free (op->data.image.height); - break; - - case META_DRAW_GTK_ARROW: - meta_draw_spec_free (op->data.gtk_arrow.x); - meta_draw_spec_free (op->data.gtk_arrow.y); - meta_draw_spec_free (op->data.gtk_arrow.width); - meta_draw_spec_free (op->data.gtk_arrow.height); - break; - - case META_DRAW_GTK_BOX: - meta_draw_spec_free (op->data.gtk_box.x); - meta_draw_spec_free (op->data.gtk_box.y); - meta_draw_spec_free (op->data.gtk_box.width); - meta_draw_spec_free (op->data.gtk_box.height); - break; - - case META_DRAW_GTK_VLINE: - meta_draw_spec_free (op->data.gtk_vline.x); - meta_draw_spec_free (op->data.gtk_vline.y1); - meta_draw_spec_free (op->data.gtk_vline.y2); - break; - - case META_DRAW_ICON: - if (op->data.icon.alpha_spec) - meta_alpha_gradient_spec_free (op->data.icon.alpha_spec); - - meta_draw_spec_free (op->data.icon.x); - meta_draw_spec_free (op->data.icon.y); - meta_draw_spec_free (op->data.icon.width); - meta_draw_spec_free (op->data.icon.height); - break; - - case META_DRAW_TITLE: - if (op->data.title.color_spec) - meta_color_spec_free (op->data.title.color_spec); - - meta_draw_spec_free (op->data.title.x); - meta_draw_spec_free (op->data.title.y); - if (op->data.title.ellipsize_width) - meta_draw_spec_free (op->data.title.ellipsize_width); - break; - - case META_DRAW_OP_LIST: - if (op->data.op_list.op_list) - meta_draw_op_list_unref (op->data.op_list.op_list); - - meta_draw_spec_free (op->data.op_list.x); - meta_draw_spec_free (op->data.op_list.y); - meta_draw_spec_free (op->data.op_list.width); - meta_draw_spec_free (op->data.op_list.height); - break; - - case META_DRAW_TILE: - if (op->data.tile.op_list) - meta_draw_op_list_unref (op->data.tile.op_list); - - meta_draw_spec_free (op->data.tile.x); - meta_draw_spec_free (op->data.tile.y); - meta_draw_spec_free (op->data.tile.width); - meta_draw_spec_free (op->data.tile.height); - meta_draw_spec_free (op->data.tile.tile_xoffset); - meta_draw_spec_free (op->data.tile.tile_yoffset); - meta_draw_spec_free (op->data.tile.tile_width); - meta_draw_spec_free (op->data.tile.tile_height); - break; - } - - free (op); -} - -static GdkPixbuf* -apply_alpha (GdkPixbuf *pixbuf, - MetaAlphaGradientSpec *spec, - gboolean force_copy) -{ - GdkPixbuf *new_pixbuf; - gboolean needs_alpha; - - g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL); - - needs_alpha = spec && (spec->n_alphas > 1 || - spec->alphas[0] != 0xff); - - if (!needs_alpha) - return pixbuf; - - if (!gdk_pixbuf_get_has_alpha (pixbuf)) - { - new_pixbuf = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0); - g_object_unref (G_OBJECT (pixbuf)); - pixbuf = new_pixbuf; - } - else if (force_copy) - { - new_pixbuf = gdk_pixbuf_copy (pixbuf); - g_object_unref (G_OBJECT (pixbuf)); - pixbuf = new_pixbuf; - } - - g_assert (gdk_pixbuf_get_has_alpha (pixbuf)); - - meta_gradient_add_alpha (pixbuf, spec->alphas, spec->n_alphas, spec->type); - - return pixbuf; -} - -static GdkPixbuf* -pixbuf_tile (GdkPixbuf *tile, - int width, - int height) -{ - GdkPixbuf *pixbuf; - int tile_width; - int tile_height; - int i, j; - - tile_width = gdk_pixbuf_get_width (tile); - tile_height = gdk_pixbuf_get_height (tile); - - pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, - gdk_pixbuf_get_has_alpha (tile), - 8, width, height); - - i = 0; - while (i < width) - { - j = 0; - while (j < height) - { - int w, h; - - w = MIN (tile_width, width - i); - h = MIN (tile_height, height - j); - - gdk_pixbuf_copy_area (tile, - 0, 0, - w, h, - pixbuf, - i, j); - - j += tile_height; - } - - i += tile_width; - } - - return pixbuf; -} - -static GdkPixbuf * -replicate_rows (GdkPixbuf *src, - int src_x, - int src_y, - int width, - int height) -{ - unsigned int n_channels = gdk_pixbuf_get_n_channels (src); - unsigned int src_rowstride = gdk_pixbuf_get_rowstride (src); - unsigned char *pixels = (gdk_pixbuf_get_pixels (src) + src_y * src_rowstride + src_x - * n_channels); - unsigned char *dest_pixels; - GdkPixbuf *result; - unsigned int dest_rowstride; - int i; - - result = gdk_pixbuf_new (GDK_COLORSPACE_RGB, n_channels == 4, 8, - width, height); - dest_rowstride = gdk_pixbuf_get_rowstride (result); - dest_pixels = gdk_pixbuf_get_pixels (result); - - for (i = 0; i < height; i++) - memcpy (dest_pixels + dest_rowstride * i, pixels, n_channels * width); - - return result; -} - -static GdkPixbuf * -replicate_cols (GdkPixbuf *src, - int src_x, - int src_y, - int width, - int height) -{ - unsigned int n_channels = gdk_pixbuf_get_n_channels (src); - unsigned int src_rowstride = gdk_pixbuf_get_rowstride (src); - unsigned char *pixels = (gdk_pixbuf_get_pixels (src) + src_y * src_rowstride + src_x - * n_channels); - unsigned char *dest_pixels; - GdkPixbuf *result; - unsigned int dest_rowstride; - int i, j; - - result = gdk_pixbuf_new (GDK_COLORSPACE_RGB, n_channels == 4, 8, - width, height); - dest_rowstride = gdk_pixbuf_get_rowstride (result); - dest_pixels = gdk_pixbuf_get_pixels (result); - - for (i = 0; i < height; i++) - { - unsigned char *p = dest_pixels + dest_rowstride * i; - unsigned char *q = pixels + src_rowstride * i; - - unsigned char r = *(q++); - unsigned char g = *(q++); - unsigned char b = *(q++); - - if (n_channels == 4) - { - unsigned char a; - - a = *(q++); - - for (j = 0; j < width; j++) - { - *(p++) = r; - *(p++) = g; - *(p++) = b; - *(p++) = a; - } - } - else - { - for (j = 0; j < width; j++) - { - *(p++) = r; - *(p++) = g; - *(p++) = b; - } - } - } - - return result; -} - -/* gdk_pixbuf_scale_simple doesn't do too well with - scaling a pixel or two up or down, you end up with - a blurry icon. Avoid scaling the icon if the scaled - size difference is within our arbitrary tolerance. This - isn't perfect.. if you use a crazy-sized window title font, - your icons still may end up less than ideal, but for most users, - this will solve things. - - It would be more effective to avoid scaling at all, - and load the image from a file directly here (especially - with SVG images,) but images are used in some themes to - construct frames and I don't want to affect that. There - are also unknown performance implications to loading here - every time a window is added) -*/ - -#define PIXBUF_SIZE_TOLERANCE 2 - -static gboolean -in_tolerance_to (gint size, gint scale_size) -{ - return scale_size <= size + PIXBUF_SIZE_TOLERANCE && - scale_size >= size - PIXBUF_SIZE_TOLERANCE; -} - -static GdkPixbuf* -scale_and_alpha_pixbuf (GdkPixbuf *src, - MetaAlphaGradientSpec *alpha_spec, - MetaImageFillType fill_type, - int width, - int height, - gboolean vertical_stripes, - gboolean horizontal_stripes) -{ - GdkPixbuf *pixbuf; - GdkPixbuf *temp_pixbuf; - - pixbuf = NULL; - - pixbuf = src; - - if (gdk_pixbuf_get_width (pixbuf) == width && - gdk_pixbuf_get_height (pixbuf) == height) - { - g_object_ref (G_OBJECT (pixbuf)); - } - else - { - if (fill_type == META_IMAGE_FILL_TILE) - { - pixbuf = pixbuf_tile (pixbuf, width, height); - } - else - { - int src_h, src_w, dest_h, dest_w; - src_h = gdk_pixbuf_get_height (src); - src_w = gdk_pixbuf_get_width (src); - - /* prefer to replicate_cols if possible, as that - * is faster (no memory reads) - */ - if (horizontal_stripes) - { - dest_w = gdk_pixbuf_get_width (src); - dest_h = height; - } - else if (vertical_stripes) - { - dest_w = width; - dest_h = gdk_pixbuf_get_height (src); - } - - else - { - dest_w = width; - dest_h = height; - } - - if (in_tolerance_to (src_w, dest_w) && in_tolerance_to (src_h, dest_h)) - { - temp_pixbuf = src; - g_object_ref (G_OBJECT (temp_pixbuf)); - } - else - { - temp_pixbuf = gdk_pixbuf_scale_simple (src, - dest_w, dest_h, - GDK_INTERP_BILINEAR); - } - - /* prefer to replicate_cols if possible, as that - * is faster (no memory reads) - */ - if (horizontal_stripes) - { - pixbuf = replicate_cols (temp_pixbuf, 0, 0, width, height); - g_object_unref (G_OBJECT (temp_pixbuf)); - } - else if (vertical_stripes) - { - pixbuf = replicate_rows (temp_pixbuf, 0, 0, width, height); - g_object_unref (G_OBJECT (temp_pixbuf)); - } - else - { - pixbuf = temp_pixbuf; - } - } - } - - if (pixbuf) - pixbuf = apply_alpha (pixbuf, alpha_spec, pixbuf == src); - - return pixbuf; -} - -static GdkPixbuf* -draw_op_as_pixbuf (const MetaDrawOp *op, - GtkStyleContext *context, - const MetaDrawInfo *info, - int width, - int height) -{ - /* Try to get the op as a pixbuf, assuming w/h in the op - * matches the width/height passed in. return NULL - * if the op can't be converted to an equivalent pixbuf. - */ - GdkPixbuf *pixbuf; - - pixbuf = NULL; - - switch (op->type) - { - case META_DRAW_LINE: - break; - - case META_DRAW_RECTANGLE: - if (op->data.rectangle.filled) - { - GdkRGBA color; - - meta_color_spec_render (op->data.rectangle.color_spec, - context, - &color); - - pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, - FALSE, - 8, width, height); - - gdk_pixbuf_fill (pixbuf, GDK_COLOR_RGBA (color)); - } - break; - - case META_DRAW_ARC: - break; - - case META_DRAW_CLIP: - break; - - case META_DRAW_TINT: - { - GdkRGBA color; - guint32 rgba; - gboolean has_alpha; - - meta_color_spec_render (op->data.rectangle.color_spec, - context, - &color); - - has_alpha = - op->data.tint.alpha_spec && - (op->data.tint.alpha_spec->n_alphas > 1 || - op->data.tint.alpha_spec->alphas[0] != 0xff); - - pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, - has_alpha, - 8, width, height); - - if (!has_alpha) - { - rgba = GDK_COLOR_RGBA (color); - - gdk_pixbuf_fill (pixbuf, rgba); - } - else if (op->data.tint.alpha_spec->n_alphas == 1) - { - rgba = GDK_COLOR_RGBA (color); - rgba &= ~0xff; - rgba |= op->data.tint.alpha_spec->alphas[0]; - - gdk_pixbuf_fill (pixbuf, rgba); - } - else - { - rgba = GDK_COLOR_RGBA (color); - - gdk_pixbuf_fill (pixbuf, rgba); - - meta_gradient_add_alpha (pixbuf, - op->data.tint.alpha_spec->alphas, - op->data.tint.alpha_spec->n_alphas, - op->data.tint.alpha_spec->type); - } - } - break; - - case META_DRAW_GRADIENT: - { - pixbuf = meta_gradient_spec_render (op->data.gradient.gradient_spec, - context, width, height); - - pixbuf = apply_alpha (pixbuf, - op->data.gradient.alpha_spec, - FALSE); - } - break; - - - case META_DRAW_IMAGE: - { - if (op->data.image.colorize_spec) - { - GdkRGBA color; - - meta_color_spec_render (op->data.image.colorize_spec, - context, &color); - - if (op->data.image.colorize_cache_pixbuf == NULL || - op->data.image.colorize_cache_pixel != GDK_COLOR_RGB (color)) - { - if (op->data.image.colorize_cache_pixbuf) - g_object_unref (G_OBJECT (op->data.image.colorize_cache_pixbuf)); - - /* const cast here */ - ((MetaDrawOp*)op)->data.image.colorize_cache_pixbuf = - colorize_pixbuf (op->data.image.pixbuf, - &color); - ((MetaDrawOp*)op)->data.image.colorize_cache_pixel = - GDK_COLOR_RGB (color); - } - - if (op->data.image.colorize_cache_pixbuf) - { - pixbuf = scale_and_alpha_pixbuf (op->data.image.colorize_cache_pixbuf, - op->data.image.alpha_spec, - op->data.image.fill_type, - width, height, - op->data.image.vertical_stripes, - op->data.image.horizontal_stripes); - } - } - else - { - pixbuf = scale_and_alpha_pixbuf (op->data.image.pixbuf, - op->data.image.alpha_spec, - op->data.image.fill_type, - width, height, - op->data.image.vertical_stripes, - op->data.image.horizontal_stripes); - } - break; - } - - case META_DRAW_GTK_ARROW: - case META_DRAW_GTK_BOX: - case META_DRAW_GTK_VLINE: - break; - case META_DRAW_ICON: - break; - case META_DRAW_TITLE: - break; - - case META_DRAW_OP_LIST: - break; - - case META_DRAW_TILE: - break; - } - - return pixbuf; -} - -static void -fill_env (MetaPositionExprEnv *env, - const MetaDrawInfo *info, - MetaRectangle logical_region) -{ - /* FIXME this stuff could be raised into draw_op_list_draw() probably - */ - env->rect = logical_region; - env->object_width = -1; - env->object_height = -1; - if (info->fgeom) - { - env->left_width = info->fgeom->borders.visible.left; - env->right_width = info->fgeom->borders.visible.right; - env->top_height = info->fgeom->borders.visible.top; - env->bottom_height = info->fgeom->borders.visible.bottom; - env->frame_x_center = info->fgeom->width / 2 - logical_region.x; - env->frame_y_center = info->fgeom->height / 2 - logical_region.y; - } - else - { - env->left_width = 0; - env->right_width = 0; - env->top_height = 0; - env->bottom_height = 0; - env->frame_x_center = 0; - env->frame_y_center = 0; - } - -#define META_ICON_WIDTH 32 -#define META_ICON_HEIGHT 32 -#define META_MINI_ICON_WIDTH 16 -#define META_MINI_ICON_HEIGHT 16 - - env->mini_icon_width = META_MINI_ICON_WIDTH; - env->mini_icon_height = META_MINI_ICON_HEIGHT; - env->icon_width = META_ICON_WIDTH; - env->icon_height = META_ICON_HEIGHT; - - env->title_width = info->title_layout_width; - env->title_height = info->title_layout_height; - env->theme = meta_current_theme; -} - - -/* This code was originally rendering anti-aliased using X primitives, and - * now has been switched to draw anti-aliased using cairo. In general, the - * closest correspondence between X rendering and cairo rendering is given - * by offsetting the geometry by 0.5 pixels in both directions before rendering - * with cairo. This is because X samples at the upper left corner of the - * pixel while cairo averages over the entire pixel. However, in the cases - * where the X rendering was an exact rectangle with no "jaggies" - * we need to be a bit careful about applying the offset. We want to produce - * the exact same pixel-aligned rectangle, rather than a rectangle with - * fuzz around the edges. - */ -static void -meta_draw_op_draw_with_env (const MetaDrawOp *op, - GtkStyleContext *style_gtk, - GtkWidget *widget, - cairo_t *cr, - const MetaDrawInfo *info, - MetaRectangle rect, - MetaPositionExprEnv *env) -{ - GdkRGBA color; - - cairo_save (cr); - gtk_style_context_save (style_gtk); - - cairo_set_line_width (cr, 1.0); - - switch (op->type) - { - case META_DRAW_LINE: - { - int x1, x2, y1, y2; - - meta_color_spec_render (op->data.line.color_spec, style_gtk, &color); - gdk_cairo_set_source_rgba (cr, &color); - - if (op->data.line.width > 0) - cairo_set_line_width (cr, op->data.line.width); - - if (op->data.line.dash_on_length > 0 && - op->data.line.dash_off_length > 0) - { - double dash_list[2]; - dash_list[0] = op->data.line.dash_on_length; - dash_list[1] = op->data.line.dash_off_length; - cairo_set_dash (cr, dash_list, 2, 0); - } - - x1 = parse_x_position_unchecked (op->data.line.x1, env); - y1 = parse_y_position_unchecked (op->data.line.y1, env); - - if (!op->data.line.x2 && - !op->data.line.y2 && - op->data.line.width==0) - { - cairo_rectangle (cr, x1, y1, 1, 1); - cairo_fill (cr); - } - else - { - if (op->data.line.x2) - x2 = parse_x_position_unchecked (op->data.line.x2, env); - else - x2 = x1; - - if (op->data.line.y2) - y2 = parse_y_position_unchecked (op->data.line.y2, env); - else - y2 = y1; - - /* This is one of the cases where we are matching the exact - * pixel aligned rectangle produced by X; for zero-width lines - * the generic algorithm produces the right result so we don't - * need to handle them here. - */ - if ((y1 == y2 || x1 == x2) && op->data.line.width != 0) - { - double offset = op->data.line.width % 2 ? .5 : 0; - - if (y1 == y2) - { - cairo_move_to (cr, x1, y1 + offset); - cairo_line_to (cr, x2, y2 + offset); - } - else - { - cairo_move_to (cr, x1 + offset, y1); - cairo_line_to (cr, x2 + offset, y2); - } - } - else - { - /* zero-width lines include both end-points in X, unlike wide lines */ - if (op->data.line.width == 0) - cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE); - - cairo_move_to (cr, x1 + .5, y1 + .5); - cairo_line_to (cr, x2 + .5, y2 + .5); - } - cairo_stroke (cr); - } - } - break; - - case META_DRAW_RECTANGLE: - { - int rx, ry, rwidth, rheight; - - meta_color_spec_render (op->data.rectangle.color_spec, - style_gtk, &color); - gdk_cairo_set_source_rgba (cr, &color); - - rx = parse_x_position_unchecked (op->data.rectangle.x, env); - ry = parse_y_position_unchecked (op->data.rectangle.y, env); - rwidth = parse_size_unchecked (op->data.rectangle.width, env); - rheight = parse_size_unchecked (op->data.rectangle.height, env); - - /* Filled and stroked rectangles are the other cases - * we pixel-align to X rasterization - */ - if (op->data.rectangle.filled) - { - cairo_rectangle (cr, rx, ry, rwidth, rheight); - cairo_fill (cr); - } - else - { - cairo_rectangle (cr, rx + .5, ry + .5, rwidth, rheight); - cairo_stroke (cr); - } - } - break; - - case META_DRAW_ARC: - { - int rx, ry, rwidth, rheight; - double start_angle, end_angle; - double center_x, center_y; - - meta_color_spec_render (op->data.arc.color_spec, style_gtk, &color); - gdk_cairo_set_source_rgba (cr, &color); - - rx = parse_x_position_unchecked (op->data.arc.x, env); - ry = parse_y_position_unchecked (op->data.arc.y, env); - rwidth = parse_size_unchecked (op->data.arc.width, env); - rheight = parse_size_unchecked (op->data.arc.height, env); - - start_angle = op->data.arc.start_angle * (M_PI / 180.) - - (.5 * M_PI); /* start at 12 instead of 3 oclock */ - end_angle = start_angle + op->data.arc.extent_angle * (M_PI / 180.); - center_x = rx + (double)rwidth / 2. + .5; - center_y = ry + (double)rheight / 2. + .5; - - cairo_save (cr); - - cairo_translate (cr, center_x, center_y); - cairo_scale (cr, (double)rwidth / 2., (double)rheight / 2.); - - if (op->data.arc.extent_angle >= 0) - cairo_arc (cr, 0, 0, 1, start_angle, end_angle); - else - cairo_arc_negative (cr, 0, 0, 1, start_angle, end_angle); - - cairo_restore (cr); - - if (op->data.arc.filled) - { - cairo_line_to (cr, center_x, center_y); - cairo_fill (cr); - } - else - cairo_stroke (cr); - } - break; - - case META_DRAW_CLIP: - break; - - case META_DRAW_TINT: - { - int rx, ry, rwidth, rheight; - gboolean needs_alpha; - - needs_alpha = op->data.tint.alpha_spec && - (op->data.tint.alpha_spec->n_alphas > 1 || - op->data.tint.alpha_spec->alphas[0] != 0xff); - - rx = parse_x_position_unchecked (op->data.tint.x, env); - ry = parse_y_position_unchecked (op->data.tint.y, env); - rwidth = parse_size_unchecked (op->data.tint.width, env); - rheight = parse_size_unchecked (op->data.tint.height, env); - - if (!needs_alpha) - { - meta_color_spec_render (op->data.tint.color_spec, - style_gtk, &color); - gdk_cairo_set_source_rgba (cr, &color); - - cairo_rectangle (cr, rx, ry, rwidth, rheight); - cairo_fill (cr); - } - else - { - GdkPixbuf *pixbuf; - - pixbuf = draw_op_as_pixbuf (op, style_gtk, info, - rwidth, rheight); - - if (pixbuf) - { - gdk_cairo_set_source_pixbuf (cr, pixbuf, rx, ry); - cairo_paint (cr); - - g_object_unref (G_OBJECT (pixbuf)); - } - } - } - break; - - case META_DRAW_GRADIENT: - { - int rx, ry, rwidth, rheight; - GdkPixbuf *pixbuf; - - rx = parse_x_position_unchecked (op->data.gradient.x, env); - ry = parse_y_position_unchecked (op->data.gradient.y, env); - rwidth = parse_size_unchecked (op->data.gradient.width, env); - rheight = parse_size_unchecked (op->data.gradient.height, env); - - pixbuf = draw_op_as_pixbuf (op, style_gtk, info, - rwidth, rheight); - - if (pixbuf) - { - gdk_cairo_set_source_pixbuf (cr, pixbuf, rx, ry); - cairo_paint (cr); - - g_object_unref (G_OBJECT (pixbuf)); - } - } - break; - - case META_DRAW_IMAGE: - { - int rx, ry, rwidth, rheight; - GdkPixbuf *pixbuf; - - if (op->data.image.pixbuf) - { - env->object_width = gdk_pixbuf_get_width (op->data.image.pixbuf); - env->object_height = gdk_pixbuf_get_height (op->data.image.pixbuf); - } - - rwidth = parse_size_unchecked (op->data.image.width, env); - rheight = parse_size_unchecked (op->data.image.height, env); - - pixbuf = draw_op_as_pixbuf (op, style_gtk, info, - rwidth, rheight); - - if (pixbuf) - { - rx = parse_x_position_unchecked (op->data.image.x, env); - ry = parse_y_position_unchecked (op->data.image.y, env); - - gdk_cairo_set_source_pixbuf (cr, pixbuf, rx, ry); - cairo_paint (cr); - - g_object_unref (G_OBJECT (pixbuf)); - } - } - break; - - case META_DRAW_GTK_ARROW: - { - int rx, ry, rwidth, rheight; - double angle = 0, size; - - rx = parse_x_position_unchecked (op->data.gtk_arrow.x, env); - ry = parse_y_position_unchecked (op->data.gtk_arrow.y, env); - rwidth = parse_size_unchecked (op->data.gtk_arrow.width, env); - rheight = parse_size_unchecked (op->data.gtk_arrow.height, env); - - size = MAX(rwidth, rheight); - - switch (op->data.gtk_arrow.arrow) - { - case GTK_ARROW_UP: - angle = 0; - break; - case GTK_ARROW_RIGHT: - angle = M_PI / 2; - break; - case GTK_ARROW_DOWN: - angle = M_PI; - break; - case GTK_ARROW_LEFT: - angle = 3 * M_PI / 2; - break; - case GTK_ARROW_NONE: - return; - } - - gtk_style_context_set_state (style_gtk, op->data.gtk_arrow.state); - gtk_render_arrow (style_gtk, cr, angle, rx, ry, size); - } - break; - - case META_DRAW_GTK_BOX: - { - int rx, ry, rwidth, rheight; - - rx = parse_x_position_unchecked (op->data.gtk_box.x, env); - ry = parse_y_position_unchecked (op->data.gtk_box.y, env); - rwidth = parse_size_unchecked (op->data.gtk_box.width, env); - rheight = parse_size_unchecked (op->data.gtk_box.height, env); - - gtk_style_context_set_state (style_gtk, op->data.gtk_box.state); - gtk_render_background (style_gtk, cr, rx, ry, rwidth, rheight); - gtk_render_frame (style_gtk, cr, rx, ry, rwidth, rheight); - } - break; - - case META_DRAW_GTK_VLINE: - { - int rx, ry1, ry2; - - rx = parse_x_position_unchecked (op->data.gtk_vline.x, env); - ry1 = parse_y_position_unchecked (op->data.gtk_vline.y1, env); - ry2 = parse_y_position_unchecked (op->data.gtk_vline.y2, env); - - gtk_style_context_set_state (style_gtk, op->data.gtk_vline.state); - gtk_render_line (style_gtk, cr, rx, ry1, rx, ry2); - } - break; - - case META_DRAW_ICON: - { - int rx, ry, rwidth, rheight; - GdkPixbuf *pixbuf; - - rwidth = parse_size_unchecked (op->data.icon.width, env); - rheight = parse_size_unchecked (op->data.icon.height, env); - - pixbuf = draw_op_as_pixbuf (op, style_gtk, info, - rwidth, rheight); - - if (pixbuf) - { - rx = parse_x_position_unchecked (op->data.icon.x, env); - ry = parse_y_position_unchecked (op->data.icon.y, env); - - gdk_cairo_set_source_pixbuf (cr, pixbuf, rx, ry); - cairo_paint (cr); - - g_object_unref (G_OBJECT (pixbuf)); - } - } - break; - - case META_DRAW_TITLE: - if (info->title_layout) - { - int rx, ry; - PangoRectangle ink_rect, logical_rect; - - meta_color_spec_render (op->data.title.color_spec, - style_gtk, &color); - gdk_cairo_set_source_rgba (cr, &color); - - rx = parse_x_position_unchecked (op->data.title.x, env); - ry = parse_y_position_unchecked (op->data.title.y, env); - - if (op->data.title.ellipsize_width) - { - int ellipsize_width; - int right_bearing; - - ellipsize_width = parse_x_position_unchecked (op->data.title.ellipsize_width, env); - /* HACK: parse_x_position_unchecked adds in env->rect.x, subtract out again */ - ellipsize_width -= env->rect.x; - - pango_layout_set_width (info->title_layout, -1); - pango_layout_get_pixel_extents (info->title_layout, - &ink_rect, &logical_rect); - - /* Pango's idea of ellipsization is with respect to the logical rect. - * correct for this, by reducing the ellipsization width by the overflow - * of the un-ellipsized text on the right... it's always the visual - * right we want regardless of bidi, since since the X we pass in to - * cairo_move_to() is always the left edge of the line. - */ - right_bearing = (ink_rect.x + ink_rect.width) - (logical_rect.x + logical_rect.width); - right_bearing = MAX (right_bearing, 0); - - ellipsize_width -= right_bearing; - ellipsize_width = MAX (ellipsize_width, 0); - - /* Only ellipsizing when necessary is a performance optimization - - * pango_layout_set_width() will force a relayout if it isn't the - * same as the current width of -1. - */ - if (ellipsize_width < logical_rect.width) - pango_layout_set_width (info->title_layout, PANGO_SCALE * ellipsize_width); - } - - cairo_move_to (cr, rx, ry); - pango_cairo_show_layout (cr, info->title_layout); - - /* Remove any ellipsization we might have set; will short-circuit - * if the width is already -1 */ - pango_layout_set_width (info->title_layout, -1); - } - break; - - case META_DRAW_OP_LIST: - { - MetaRectangle d_rect; - - d_rect.x = parse_x_position_unchecked (op->data.op_list.x, env); - d_rect.y = parse_y_position_unchecked (op->data.op_list.y, env); - d_rect.width = parse_size_unchecked (op->data.op_list.width, env); - d_rect.height = parse_size_unchecked (op->data.op_list.height, env); - - meta_draw_op_list_draw_with_style (op->data.op_list.op_list, - style_gtk, widget, cr, info, - d_rect); - } - break; - - case META_DRAW_TILE: - { - int rx, ry, rwidth, rheight; - int tile_xoffset, tile_yoffset; - MetaRectangle tile; - - rx = parse_x_position_unchecked (op->data.tile.x, env); - ry = parse_y_position_unchecked (op->data.tile.y, env); - rwidth = parse_size_unchecked (op->data.tile.width, env); - rheight = parse_size_unchecked (op->data.tile.height, env); - - cairo_save (cr); - - cairo_rectangle (cr, rx, ry, rwidth, rheight); - cairo_clip (cr); - - tile_xoffset = parse_x_position_unchecked (op->data.tile.tile_xoffset, env); - tile_yoffset = parse_y_position_unchecked (op->data.tile.tile_yoffset, env); - /* tile offset should not include x/y */ - tile_xoffset -= rect.x; - tile_yoffset -= rect.y; - - tile.width = parse_size_unchecked (op->data.tile.tile_width, env); - tile.height = parse_size_unchecked (op->data.tile.tile_height, env); - - tile.x = rx - tile_xoffset; - - while (tile.x < (rx + rwidth)) - { - tile.y = ry - tile_yoffset; - while (tile.y < (ry + rheight)) - { - meta_draw_op_list_draw_with_style (op->data.tile.op_list, - style_gtk, widget, cr, info, - tile); - - tile.y += tile.height; - } - - tile.x += tile.width; - } - cairo_restore (cr); - - } - break; - } - - cairo_restore (cr); - gtk_style_context_restore (style_gtk); -} - -LOCAL_SYMBOL void -meta_draw_op_draw_with_style (const MetaDrawOp *op, - GtkStyleContext *style_gtk, - GtkWidget *widget, - cairo_t *cr, - const MetaDrawInfo *info, - MetaRectangle logical_region) -{ - MetaPositionExprEnv env; - - fill_env (&env, info, logical_region); - - meta_draw_op_draw_with_env (op, style_gtk, widget, cr, - info, logical_region, - &env); - -} - -LOCAL_SYMBOL void -meta_draw_op_draw (const MetaDrawOp *op, - GtkWidget *widget, - cairo_t *cr, - const MetaDrawInfo *info, - MetaRectangle logical_region) -{ - meta_draw_op_draw_with_style (op, gtk_widget_get_style_context (widget), - widget, cr, info, logical_region); -} - -/** - * meta_draw_op_list_new: (skip) - * - */ -LOCAL_SYMBOL MetaDrawOpList* -meta_draw_op_list_new (int n_preallocs) -{ - MetaDrawOpList *op_list; - - g_return_val_if_fail (n_preallocs >= 0, NULL); - - op_list = g_new (MetaDrawOpList, 1); - - op_list->refcount = 1; - op_list->n_allocated = n_preallocs; - op_list->ops = g_new (MetaDrawOp*, op_list->n_allocated); - op_list->n_ops = 0; - - return op_list; -} - -LOCAL_SYMBOL void -meta_draw_op_list_ref (MetaDrawOpList *op_list) -{ - g_return_if_fail (op_list != NULL); - - op_list->refcount += 1; -} - -LOCAL_SYMBOL void -meta_draw_op_list_unref (MetaDrawOpList *op_list) -{ - g_return_if_fail (op_list != NULL); - g_return_if_fail (op_list->refcount > 0); - - op_list->refcount -= 1; - - if (op_list->refcount == 0) - { - int i; - - for (i = 0; i < op_list->n_ops; i++) - meta_draw_op_free (op_list->ops[i]); - - free (op_list->ops); - - DEBUG_FILL_STRUCT (op_list); - free (op_list); - } -} - -LOCAL_SYMBOL void -meta_draw_op_list_draw_with_style (const MetaDrawOpList *op_list, - GtkStyleContext *style_gtk, - GtkWidget *widget, - cairo_t *cr, - const MetaDrawInfo *info, - MetaRectangle rect) -{ - int i; - MetaPositionExprEnv env; - - if (op_list->n_ops == 0) - return; - - fill_env (&env, info, rect); - - /* FIXME this can be optimized, potentially a lot, by - * compressing multiple ops when possible. For example, - * anything convertible to a pixbuf can be composited - * client-side, and putting a color tint over a pixbuf - * can be done without creating the solid-color pixbuf. - * - * To implement this my plan is to have the idea of a - * compiled draw op (with the string expressions already - * evaluated), we make an array of those, and then fold - * adjacent items when possible. - */ - - cairo_save (cr); - - for (i = 0; i < op_list->n_ops; i++) - { - MetaDrawOp *op = op_list->ops[i]; - - if (op->type == META_DRAW_CLIP) - { - cairo_restore (cr); - - cairo_rectangle (cr, - parse_x_position_unchecked (op->data.clip.x, &env), - parse_y_position_unchecked (op->data.clip.y, &env), - parse_size_unchecked (op->data.clip.width, &env), - parse_size_unchecked (op->data.clip.height, &env)); - cairo_clip (cr); - - cairo_save (cr); - } - else if (gdk_cairo_get_clip_rectangle (cr, NULL)) - { - meta_draw_op_draw_with_env (op, - style_gtk, widget, cr, info, - rect, - &env); - } - } - - cairo_restore (cr); -} - -LOCAL_SYMBOL void -meta_draw_op_list_draw (const MetaDrawOpList *op_list, - GtkWidget *widget, - cairo_t *cr, - const MetaDrawInfo *info, - MetaRectangle rect) - -{ - meta_draw_op_list_draw_with_style (op_list, gtk_widget_get_style_context (widget), widget, - cr, info, rect); -} - -LOCAL_SYMBOL void -meta_draw_op_list_append (MetaDrawOpList *op_list, - MetaDrawOp *op) -{ - if (op_list->n_ops == op_list->n_allocated) - { - op_list->n_allocated *= 2; - op_list->ops = g_renew (MetaDrawOp*, op_list->ops, op_list->n_allocated); - } - - op_list->ops[op_list->n_ops] = op; - op_list->n_ops += 1; -} - -LOCAL_SYMBOL gboolean -meta_draw_op_list_validate (MetaDrawOpList *op_list, - GError **error) -{ - g_return_val_if_fail (op_list != NULL, FALSE); - - /* empty lists are OK, nothing else to check really */ - - return TRUE; -} - -/* This is not done in validate, since we wouldn't know the name - * of the list to report the error. It might be nice to - * store names inside the list sometime. - */ -LOCAL_SYMBOL gboolean -meta_draw_op_list_contains (MetaDrawOpList *op_list, - MetaDrawOpList *child) -{ - int i; - - /* mmm, huge tree recursion */ - - for (i = 0; i < op_list->n_ops; i++) - { - if (op_list->ops[i]->type == META_DRAW_OP_LIST) - { - if (op_list->ops[i]->data.op_list.op_list == child) - return TRUE; - - if (meta_draw_op_list_contains (op_list->ops[i]->data.op_list.op_list, - child)) - return TRUE; - } - else if (op_list->ops[i]->type == META_DRAW_TILE) - { - if (op_list->ops[i]->data.tile.op_list == child) - return TRUE; - - if (meta_draw_op_list_contains (op_list->ops[i]->data.tile.op_list, - child)) - return TRUE; - } - } - - return FALSE; -} - -/* - * Constructor for a MetaFrameStyle. - * - * \param parent The parent style. Data not filled in here will be - * looked for in the parent style, and in its parent - * style, and so on. - * - * \return The newly-constructed style. - */ -LOCAL_SYMBOL MetaFrameStyle* -meta_frame_style_new (MetaFrameStyle *parent) -{ - MetaFrameStyle *style; - - style = g_new0 (MetaFrameStyle, 1); - - style->refcount = 1; - - /* Default alpha is fully opaque */ - style->window_background_alpha = 255; - - style->parent = parent; - if (parent) - meta_frame_style_ref (parent); - - return style; -} - -/* - * Increases the reference count of a frame style. - * If the style is NULL, this is a no-op. - * - * \param style The style. - */ -LOCAL_SYMBOL void -meta_frame_style_ref (MetaFrameStyle *style) -{ - g_return_if_fail (style != NULL); - - style->refcount += 1; -} - -static void -free_button_ops (MetaDrawOpList *op_lists[META_BUTTON_TYPE_LAST][META_BUTTON_STATE_LAST]) -{ - int i, j; - - for (i = 0; i < META_BUTTON_TYPE_LAST; i++) - for (j = 0; j < META_BUTTON_STATE_LAST; j++) - if (op_lists[i][j]) - meta_draw_op_list_unref (op_lists[i][j]); -} - -LOCAL_SYMBOL void -meta_frame_style_unref (MetaFrameStyle *style) -{ - g_return_if_fail (style != NULL); - g_return_if_fail (style->refcount > 0); - - style->refcount -= 1; - - if (style->refcount == 0) - { - int i; - - free_button_ops (style->buttons); - - for (i = 0; i < META_FRAME_PIECE_LAST; i++) - if (style->pieces[i]) - meta_draw_op_list_unref (style->pieces[i]); - - if (style->layout) - meta_frame_layout_unref (style->layout); - - if (style->window_background_color) - meta_color_spec_free (style->window_background_color); - - /* we hold a reference to any parent style */ - if (style->parent) - meta_frame_style_unref (style->parent); - - DEBUG_FILL_STRUCT (style); - free (style); - } -} - -static MetaButtonState -map_button_state (MetaButtonType button_type, - const MetaFrameGeometry *fgeom, - int middle_bg_offset, - MetaButtonState button_states[META_BUTTON_TYPE_LAST]) -{ - MetaButtonFunction function = META_BUTTON_FUNCTION_LAST; - - switch (button_type) - { - /* First hande functions, which map directly */ - case META_BUTTON_TYPE_SHADE: - case META_BUTTON_TYPE_ABOVE: - case META_BUTTON_TYPE_STICK: - case META_BUTTON_TYPE_UNSHADE: - case META_BUTTON_TYPE_UNABOVE: - case META_BUTTON_TYPE_UNSTICK: - case META_BUTTON_TYPE_MENU: - case META_BUTTON_TYPE_MINIMIZE: - case META_BUTTON_TYPE_MAXIMIZE: - case META_BUTTON_TYPE_CLOSE: - return button_states[button_type]; - - /* Map position buttons to the corresponding function */ - case META_BUTTON_TYPE_RIGHT_LEFT_BACKGROUND: - case META_BUTTON_TYPE_RIGHT_SINGLE_BACKGROUND: - if (fgeom->n_right_buttons > 0) - function = fgeom->button_layout.right_buttons[0]; - break; - case META_BUTTON_TYPE_RIGHT_RIGHT_BACKGROUND: - if (fgeom->n_right_buttons > 0) - function = fgeom->button_layout.right_buttons[fgeom->n_right_buttons - 1]; - break; - case META_BUTTON_TYPE_RIGHT_MIDDLE_BACKGROUND: - if (middle_bg_offset + 1 < fgeom->n_right_buttons) - function = fgeom->button_layout.right_buttons[middle_bg_offset + 1]; - break; - case META_BUTTON_TYPE_LEFT_LEFT_BACKGROUND: - case META_BUTTON_TYPE_LEFT_SINGLE_BACKGROUND: - if (fgeom->n_left_buttons > 0) - function = fgeom->button_layout.left_buttons[0]; - break; - case META_BUTTON_TYPE_LEFT_RIGHT_BACKGROUND: - if (fgeom->n_left_buttons > 0) - function = fgeom->button_layout.left_buttons[fgeom->n_left_buttons - 1]; - break; - case META_BUTTON_TYPE_LEFT_MIDDLE_BACKGROUND: - if (middle_bg_offset + 1 < fgeom->n_left_buttons) - function = fgeom->button_layout.left_buttons[middle_bg_offset + 1]; - break; - case META_BUTTON_TYPE_LAST: - break; - } - - if (function != META_BUTTON_FUNCTION_LAST) - return button_states[map_button_function_to_type (function)]; - - return META_BUTTON_STATE_LAST; -} - -static MetaDrawOpList* -get_button (MetaFrameStyle *style, - MetaButtonType type, - MetaButtonState state) -{ - MetaDrawOpList *op_list; - MetaFrameStyle *parent; - - parent = style; - op_list = NULL; - while (parent && op_list == NULL) - { - op_list = parent->buttons[type][state]; - parent = parent->parent; - } - - /* We fall back to the side buttons if we don't have - * single button backgrounds, and to middle button - * backgrounds if we don't have the ones on the sides - */ - - if (op_list == NULL && - type == META_BUTTON_TYPE_LEFT_SINGLE_BACKGROUND) - return get_button (style, META_BUTTON_TYPE_LEFT_LEFT_BACKGROUND, state); - - if (op_list == NULL && - type == META_BUTTON_TYPE_RIGHT_SINGLE_BACKGROUND) - return get_button (style, META_BUTTON_TYPE_RIGHT_RIGHT_BACKGROUND, state); - - if (op_list == NULL && - (type == META_BUTTON_TYPE_LEFT_LEFT_BACKGROUND || - type == META_BUTTON_TYPE_LEFT_RIGHT_BACKGROUND)) - return get_button (style, META_BUTTON_TYPE_LEFT_MIDDLE_BACKGROUND, - state); - - if (op_list == NULL && - (type == META_BUTTON_TYPE_RIGHT_LEFT_BACKGROUND || - type == META_BUTTON_TYPE_RIGHT_RIGHT_BACKGROUND)) - return get_button (style, META_BUTTON_TYPE_RIGHT_MIDDLE_BACKGROUND, - state); - - /* We fall back to normal if no prelight */ - if (op_list == NULL && - state == META_BUTTON_STATE_PRELIGHT) - return get_button (style, type, META_BUTTON_STATE_NORMAL); - - return op_list; -} - -LOCAL_SYMBOL gboolean -meta_frame_style_validate (MetaFrameStyle *style, - guint current_theme_version, - GError **error) -{ - int i, j; - - g_return_val_if_fail (style != NULL, FALSE); - g_return_val_if_fail (style->layout != NULL, FALSE); - - for (i = 0; i < META_BUTTON_TYPE_LAST; i++) - { - /* for now the "positional" buttons are optional */ - if (i >= META_BUTTON_TYPE_CLOSE) - { - for (j = 0; j < META_BUTTON_STATE_LAST; j++) - { - if (get_button (style, i, j) == NULL && - meta_theme_earliest_version_with_button (i) <= current_theme_version - ) - { - g_set_error (error, META_THEME_ERROR, - META_THEME_ERROR_FAILED, - _("<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be specified for this frame style"), - meta_button_type_to_string (i), - meta_button_state_to_string (j)); - return FALSE; - } - } - } - } - - return TRUE; -} - -static void -button_rect (MetaButtonType type, - const MetaFrameGeometry *fgeom, - int middle_background_offset, - GdkRectangle *rect) -{ - switch (type) - { - case META_BUTTON_TYPE_LEFT_LEFT_BACKGROUND: - *rect = fgeom->left_left_background; - break; - - case META_BUTTON_TYPE_LEFT_MIDDLE_BACKGROUND: - *rect = fgeom->left_middle_backgrounds[middle_background_offset]; - break; - - case META_BUTTON_TYPE_LEFT_RIGHT_BACKGROUND: - *rect = fgeom->left_right_background; - break; - - case META_BUTTON_TYPE_LEFT_SINGLE_BACKGROUND: - *rect = fgeom->left_single_background; - break; - - case META_BUTTON_TYPE_RIGHT_LEFT_BACKGROUND: - *rect = fgeom->right_left_background; - break; - - case META_BUTTON_TYPE_RIGHT_MIDDLE_BACKGROUND: - *rect = fgeom->right_middle_backgrounds[middle_background_offset]; - break; - - case META_BUTTON_TYPE_RIGHT_RIGHT_BACKGROUND: - *rect = fgeom->right_right_background; - break; - - case META_BUTTON_TYPE_RIGHT_SINGLE_BACKGROUND: - *rect = fgeom->right_single_background; - break; - - case META_BUTTON_TYPE_CLOSE: - *rect = fgeom->close_rect.visible; - break; - - case META_BUTTON_TYPE_SHADE: - *rect = fgeom->shade_rect.visible; - break; - - case META_BUTTON_TYPE_UNSHADE: - *rect = fgeom->unshade_rect.visible; - break; - - case META_BUTTON_TYPE_ABOVE: - *rect = fgeom->above_rect.visible; - break; - - case META_BUTTON_TYPE_UNABOVE: - *rect = fgeom->unabove_rect.visible; - break; - - case META_BUTTON_TYPE_STICK: - *rect = fgeom->stick_rect.visible; - break; - - case META_BUTTON_TYPE_UNSTICK: - *rect = fgeom->unstick_rect.visible; - break; - - case META_BUTTON_TYPE_MAXIMIZE: - *rect = fgeom->max_rect.visible; - break; - - case META_BUTTON_TYPE_MINIMIZE: - *rect = fgeom->min_rect.visible; - break; - - case META_BUTTON_TYPE_MENU: - *rect = fgeom->menu_rect.visible; - break; - - case META_BUTTON_TYPE_LAST: - g_assert_not_reached (); - break; - } -} - -LOCAL_SYMBOL LOCAL_SYMBOL void -meta_frame_style_draw_with_style (MetaFrameStyle *style, - GtkStyleContext *style_gtk, - GtkWidget *widget, - cairo_t *cr, - const MetaFrameGeometry *fgeom, - int client_width, - int client_height, - PangoLayout *title_layout, - int text_height, - MetaButtonState button_states[META_BUTTON_TYPE_LAST]) -{ - int i, j; - GdkRectangle visible_rect; - GdkRectangle titlebar_rect; - GdkRectangle left_titlebar_edge; - GdkRectangle right_titlebar_edge; - GdkRectangle bottom_titlebar_edge; - GdkRectangle top_titlebar_edge; - GdkRectangle left_edge, right_edge, bottom_edge; - PangoRectangle logical_rect; - MetaDrawInfo draw_info; - const MetaFrameBorders *borders; - - borders = &fgeom->borders; - - visible_rect.x = borders->invisible.left; - visible_rect.y = borders->invisible.top; - visible_rect.width = fgeom->width - borders->invisible.left - borders->invisible.right; - visible_rect.height = fgeom->height - borders->invisible.top - borders->invisible.bottom; - - titlebar_rect.x = visible_rect.x; - titlebar_rect.y = visible_rect.y; - titlebar_rect.width = visible_rect.width; - titlebar_rect.height = borders->visible.top; - - left_titlebar_edge.x = titlebar_rect.x; - left_titlebar_edge.y = titlebar_rect.y + fgeom->top_titlebar_edge; - left_titlebar_edge.width = fgeom->left_titlebar_edge; - left_titlebar_edge.height = titlebar_rect.height - fgeom->top_titlebar_edge - fgeom->bottom_titlebar_edge; - - right_titlebar_edge.y = left_titlebar_edge.y; - right_titlebar_edge.height = left_titlebar_edge.height; - right_titlebar_edge.width = fgeom->right_titlebar_edge; - right_titlebar_edge.x = titlebar_rect.x + titlebar_rect.width - right_titlebar_edge.width; - - top_titlebar_edge.x = titlebar_rect.x; - top_titlebar_edge.y = titlebar_rect.y; - top_titlebar_edge.width = titlebar_rect.width; - top_titlebar_edge.height = fgeom->top_titlebar_edge; - - bottom_titlebar_edge.x = titlebar_rect.x; - bottom_titlebar_edge.width = titlebar_rect.width; - bottom_titlebar_edge.height = fgeom->bottom_titlebar_edge; - bottom_titlebar_edge.y = titlebar_rect.y + titlebar_rect.height - bottom_titlebar_edge.height; - - left_edge.x = visible_rect.x; - left_edge.y = visible_rect.y + borders->visible.top; - left_edge.width = borders->visible.left; - left_edge.height = visible_rect.height - borders->visible.top - borders->visible.bottom; - - right_edge.x = visible_rect.x + visible_rect.width - borders->visible.right; - right_edge.y = visible_rect.y + borders->visible.top; - right_edge.width = borders->visible.right; - right_edge.height = visible_rect.height - borders->visible.top - borders->visible.bottom; - - bottom_edge.x = visible_rect.x; - bottom_edge.y = visible_rect.y + visible_rect.height - borders->visible.bottom; - bottom_edge.width = visible_rect.width; - bottom_edge.height = borders->visible.bottom; - - if (title_layout) - pango_layout_get_pixel_extents (title_layout, - NULL, &logical_rect); - - draw_info.title_layout = title_layout; - draw_info.title_layout_width = title_layout ? logical_rect.width : 0; - draw_info.title_layout_height = title_layout ? logical_rect.height : 0; - draw_info.fgeom = fgeom; - - /* The enum is in the order the pieces should be rendered. */ - i = 0; - while (i < META_FRAME_PIECE_LAST) - { - GdkRectangle rect; - - switch ((MetaFramePiece) i) - { - case META_FRAME_PIECE_ENTIRE_BACKGROUND: - rect = visible_rect; - break; - - case META_FRAME_PIECE_TITLEBAR: - rect = titlebar_rect; - break; - - case META_FRAME_PIECE_LEFT_TITLEBAR_EDGE: - rect = left_titlebar_edge; - break; - - case META_FRAME_PIECE_RIGHT_TITLEBAR_EDGE: - rect = right_titlebar_edge; - break; - - case META_FRAME_PIECE_TOP_TITLEBAR_EDGE: - rect = top_titlebar_edge; - break; - - case META_FRAME_PIECE_BOTTOM_TITLEBAR_EDGE: - rect = bottom_titlebar_edge; - break; - - case META_FRAME_PIECE_TITLEBAR_MIDDLE: - rect.x = left_titlebar_edge.x + left_titlebar_edge.width; - rect.y = top_titlebar_edge.y + top_titlebar_edge.height; - rect.width = titlebar_rect.width - left_titlebar_edge.width - - right_titlebar_edge.width; - rect.height = titlebar_rect.height - top_titlebar_edge.height - bottom_titlebar_edge.height; - break; - - case META_FRAME_PIECE_TITLE: - rect = fgeom->title_rect; - break; - - case META_FRAME_PIECE_LEFT_EDGE: - rect = left_edge; - break; - - case META_FRAME_PIECE_RIGHT_EDGE: - rect = right_edge; - break; - - case META_FRAME_PIECE_BOTTOM_EDGE: - rect = bottom_edge; - break; - - case META_FRAME_PIECE_OVERLAY: - rect = visible_rect; - break; - - case META_FRAME_PIECE_LAST: - g_assert_not_reached (); - break; - } - - cairo_save (cr); - - gdk_cairo_rectangle (cr, &rect); - cairo_clip (cr); - - if (gdk_cairo_get_clip_rectangle (cr, NULL)) - { - MetaDrawOpList *op_list; - MetaFrameStyle *parent; - - parent = style; - op_list = NULL; - while (parent && op_list == NULL) - { - op_list = parent->pieces[i]; - parent = parent->parent; - } - - if (op_list) - { - MetaRectangle m_rect; - m_rect = meta_rect (rect.x, rect.y, rect.width, rect.height); - meta_draw_op_list_draw_with_style (op_list, - style_gtk, - widget, - cr, - &draw_info, - m_rect); - } - } - - cairo_restore (cr); - - /* Draw buttons just before overlay */ - if ((i + 1) == META_FRAME_PIECE_OVERLAY) - { - MetaDrawOpList *op_list; - int middle_bg_offset; - - middle_bg_offset = 0; - j = 0; - while (j < META_BUTTON_TYPE_LAST) - { - MetaButtonState button_state; - - button_rect (j, fgeom, middle_bg_offset, &rect); - - button_state = map_button_state (j, fgeom, middle_bg_offset, button_states); - - op_list = get_button (style, j, button_state); - - if (op_list) - { - cairo_save (cr); - gdk_cairo_rectangle (cr, &rect); - cairo_clip (cr); - - if (gdk_cairo_get_clip_rectangle (cr, NULL)) - { - MetaRectangle m_rect; - - m_rect = meta_rect (rect.x, rect.y, - rect.width, rect.height); - - meta_draw_op_list_draw_with_style (op_list, - style_gtk, - widget, - cr, - &draw_info, - m_rect); - } - - cairo_restore (cr); - } - - /* MIDDLE_BACKGROUND type may get drawn more than once */ - if ((j == META_BUTTON_TYPE_RIGHT_MIDDLE_BACKGROUND || - j == META_BUTTON_TYPE_LEFT_MIDDLE_BACKGROUND) && - middle_bg_offset < MAX_MIDDLE_BACKGROUNDS) - { - ++middle_bg_offset; - } - else - { - middle_bg_offset = 0; - ++j; - } - } - } - - ++i; - } -} - -LOCAL_SYMBOL void -meta_frame_style_draw (MetaFrameStyle *style, - GtkWidget *widget, - cairo_t *cr, - const MetaFrameGeometry *fgeom, - int client_width, - int client_height, - PangoLayout *title_layout, - int text_height, - MetaButtonState button_states[META_BUTTON_TYPE_LAST]) -{ - meta_frame_style_draw_with_style (style, gtk_widget_get_style_context (widget), widget, - cr, fgeom, client_width, client_height, - title_layout, text_height, - button_states); -} - -LOCAL_SYMBOL MetaFrameStyleSet* -meta_frame_style_set_new (MetaFrameStyleSet *parent) -{ - MetaFrameStyleSet *style_set; - - style_set = g_new0 (MetaFrameStyleSet, 1); - - style_set->parent = parent; - if (parent) - meta_frame_style_set_ref (parent); - - style_set->refcount = 1; - - return style_set; -} - -static void -free_focus_styles (MetaFrameStyle *focus_styles[META_FRAME_FOCUS_LAST]) -{ - int i; - - for (i = 0; i < META_FRAME_FOCUS_LAST; i++) - if (focus_styles[i]) - meta_frame_style_unref (focus_styles[i]); -} - -LOCAL_SYMBOL void -meta_frame_style_set_ref (MetaFrameStyleSet *style_set) -{ - g_return_if_fail (style_set != NULL); - - style_set->refcount += 1; -} - -LOCAL_SYMBOL void -meta_frame_style_set_unref (MetaFrameStyleSet *style_set) -{ - g_return_if_fail (style_set != NULL); - g_return_if_fail (style_set->refcount > 0); - - style_set->refcount -= 1; - - if (style_set->refcount == 0) - { - int i; - - for (i = 0; i < META_FRAME_RESIZE_LAST; i++) - { - free_focus_styles (style_set->normal_styles[i]); - free_focus_styles (style_set->shaded_styles[i]); - } - - free_focus_styles (style_set->maximized_styles); - free_focus_styles (style_set->tiled_left_styles); - free_focus_styles (style_set->tiled_right_styles); - free_focus_styles (style_set->maximized_and_shaded_styles); - free_focus_styles (style_set->tiled_left_and_shaded_styles); - free_focus_styles (style_set->tiled_right_and_shaded_styles); - - if (style_set->parent) - meta_frame_style_set_unref (style_set->parent); - - DEBUG_FILL_STRUCT (style_set); - free (style_set); - } -} - - -static MetaFrameStyle* -get_style (MetaFrameStyleSet *style_set, - MetaFrameState state, - MetaFrameResize resize, - MetaFrameFocus focus) -{ - MetaFrameStyle *style; - - style = NULL; - - switch (state) - { - case META_FRAME_STATE_NORMAL: - case META_FRAME_STATE_SHADED: - { - if (state == META_FRAME_STATE_SHADED) - style = style_set->shaded_styles[resize][focus]; - else - style = style_set->normal_styles[resize][focus]; - - /* Try parent if we failed here */ - if (style == NULL && style_set->parent) - style = get_style (style_set->parent, state, resize, focus); - - /* Allow people to omit the vert/horz/none resize modes */ - if (style == NULL && - resize != META_FRAME_RESIZE_BOTH) - style = get_style (style_set, state, META_FRAME_RESIZE_BOTH, focus); - } - break; - default: - { - MetaFrameStyle **styles; - - styles = NULL; - - switch (state) - { - case META_FRAME_STATE_MAXIMIZED: - styles = style_set->maximized_styles; - break; - case META_FRAME_STATE_TILED_LEFT: - styles = style_set->tiled_left_styles; - break; - case META_FRAME_STATE_TILED_RIGHT: - styles = style_set->tiled_right_styles; - break; - case META_FRAME_STATE_MAXIMIZED_AND_SHADED: - styles = style_set->maximized_and_shaded_styles; - break; - case META_FRAME_STATE_TILED_LEFT_AND_SHADED: - styles = style_set->tiled_left_and_shaded_styles; - break; - case META_FRAME_STATE_TILED_RIGHT_AND_SHADED: - styles = style_set->tiled_right_and_shaded_styles; - break; - case META_FRAME_STATE_NORMAL: - case META_FRAME_STATE_SHADED: - case META_FRAME_STATE_LAST: - break; - } - - style = styles[focus]; - - /* Tiled states are optional, try falling back to non-tiled states */ - if (style == NULL) - { - if (state == META_FRAME_STATE_TILED_LEFT || - state == META_FRAME_STATE_TILED_RIGHT) - style = get_style (style_set, META_FRAME_STATE_NORMAL, - resize, focus); - else if (state == META_FRAME_STATE_TILED_LEFT_AND_SHADED || - state == META_FRAME_STATE_TILED_RIGHT_AND_SHADED) - style = get_style (style_set, META_FRAME_STATE_SHADED, - resize, focus); - } - - /* Try parent if we failed here */ - if (style == NULL && style_set->parent) - style = get_style (style_set->parent, state, resize, focus); - } - } - - return style; -} - -static gboolean -check_state (MetaFrameStyleSet *style_set, - MetaFrameState state, - GError **error) -{ - int i; - - for (i = 0; i < META_FRAME_FOCUS_LAST; i++) - { - if (get_style (style_set, state, - META_FRAME_RESIZE_NONE, i) == NULL) - { - /* Translators: This error occurs when a <frame> tag is missing - * in theme XML. The "<frame ...>" is intended as a noun phrase, - * and the "missing" qualifies it. You should translate "whatever". - */ - g_set_error (error, META_THEME_ERROR, - META_THEME_ERROR_FAILED, - _("Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>"), - meta_frame_state_to_string (state), - meta_frame_resize_to_string (META_FRAME_RESIZE_NONE), - meta_frame_focus_to_string (i)); - return FALSE; - } - } - - return TRUE; -} - -LOCAL_SYMBOL gboolean -meta_frame_style_set_validate (MetaFrameStyleSet *style_set, - GError **error) -{ - int i, j; - - g_return_val_if_fail (style_set != NULL, FALSE); - - for (i = 0; i < META_FRAME_RESIZE_LAST; i++) - for (j = 0; j < META_FRAME_FOCUS_LAST; j++) - if (get_style (style_set, META_FRAME_STATE_NORMAL, i, j) == NULL) - { - g_set_error (error, META_THEME_ERROR, - META_THEME_ERROR_FAILED, - _("Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>"), - meta_frame_state_to_string (META_FRAME_STATE_NORMAL), - meta_frame_resize_to_string (i), - meta_frame_focus_to_string (j)); - return FALSE; - } - - if (!check_state (style_set, META_FRAME_STATE_SHADED, error)) - return FALSE; - - if (!check_state (style_set, META_FRAME_STATE_MAXIMIZED, error)) - return FALSE; - - if (!check_state (style_set, META_FRAME_STATE_MAXIMIZED_AND_SHADED, error)) - return FALSE; - - return TRUE; -} - -/** - * meta_theme_get_current: (skip) - * - */ -MetaTheme* -meta_theme_get_current (void) -{ - return meta_current_theme; -} - -void -meta_theme_set_current (const char *name, - gboolean force_reload) -{ - MetaTheme *new_theme; - GError *err; - - meta_topic (META_DEBUG_THEMES, "Setting current theme to \"%s\"\n", name); - - if (!force_reload && - meta_current_theme && - strcmp (name, meta_current_theme->name) == 0) - return; - - err = NULL; - new_theme = meta_theme_load (name, &err); - - if (new_theme == NULL) - { - meta_warning (_("Failed to load theme \"%s\": %s\n"), - name, err->message); - g_error_free (err); - } - else - { - if (meta_current_theme) - meta_theme_free (meta_current_theme); - - meta_current_theme = new_theme; - - meta_topic (META_DEBUG_THEMES, "New theme is \"%s\"\n", meta_current_theme->name); - } -} - -/** - * meta_theme_new: (skip) - * - */ -MetaTheme* -meta_theme_new (void) -{ - MetaTheme *theme; - - theme = g_new0 (MetaTheme, 1); - - theme->images_by_filename = - g_hash_table_new_full (g_str_hash, - g_str_equal, - free, - (GDestroyNotify) g_object_unref); - - theme->layouts_by_name = - g_hash_table_new_full (g_str_hash, - g_str_equal, - free, - (GDestroyNotify) meta_frame_layout_unref); - - theme->draw_op_lists_by_name = - g_hash_table_new_full (g_str_hash, - g_str_equal, - free, - (GDestroyNotify) meta_draw_op_list_unref); - - theme->styles_by_name = - g_hash_table_new_full (g_str_hash, - g_str_equal, - free, - (GDestroyNotify) meta_frame_style_unref); - - theme->style_sets_by_name = - g_hash_table_new_full (g_str_hash, - g_str_equal, - free, - (GDestroyNotify) meta_frame_style_set_unref); - - /* Create our variable quarks so we can look up variables without - having to strcmp for the names */ - theme->quark_width = g_quark_from_static_string ("width"); - theme->quark_height = g_quark_from_static_string ("height"); - theme->quark_object_width = g_quark_from_static_string ("object_width"); - theme->quark_object_height = g_quark_from_static_string ("object_height"); - theme->quark_left_width = g_quark_from_static_string ("left_width"); - theme->quark_right_width = g_quark_from_static_string ("right_width"); - theme->quark_top_height = g_quark_from_static_string ("top_height"); - theme->quark_bottom_height = g_quark_from_static_string ("bottom_height"); - theme->quark_mini_icon_width = g_quark_from_static_string ("mini_icon_width"); - theme->quark_mini_icon_height = g_quark_from_static_string ("mini_icon_height"); - theme->quark_icon_width = g_quark_from_static_string ("icon_width"); - theme->quark_icon_height = g_quark_from_static_string ("icon_height"); - theme->quark_title_width = g_quark_from_static_string ("title_width"); - theme->quark_title_height = g_quark_from_static_string ("title_height"); - theme->quark_frame_x_center = g_quark_from_static_string ("frame_x_center"); - theme->quark_frame_y_center = g_quark_from_static_string ("frame_y_center"); - return theme; -} - - -void -meta_theme_free (MetaTheme *theme) -{ - int i; - - g_return_if_fail (theme != NULL); - - free (theme->name); - free (theme->dirname); - free (theme->filename); - free (theme->readable_name); - free (theme->date); - free (theme->description); - free (theme->author); - free (theme->copyright); - - /* be more careful when destroying the theme hash tables, - since they are only constructed as needed, and may be NULL. */ - if (theme->integer_constants) - g_hash_table_destroy (theme->integer_constants); - if (theme->images_by_filename) - g_hash_table_destroy (theme->images_by_filename); - if (theme->layouts_by_name) - g_hash_table_destroy (theme->layouts_by_name); - if (theme->draw_op_lists_by_name) - g_hash_table_destroy (theme->draw_op_lists_by_name); - if (theme->styles_by_name) - g_hash_table_destroy (theme->styles_by_name); - if (theme->style_sets_by_name) - g_hash_table_destroy (theme->style_sets_by_name); - - for (i = 0; i < META_FRAME_TYPE_LAST; i++) - if (theme->style_sets_by_type[i]) - meta_frame_style_set_unref (theme->style_sets_by_type[i]); - - DEBUG_FILL_STRUCT (theme); - free (theme); -} - -gboolean -meta_theme_validate (MetaTheme *theme, - GError **error) -{ - int i; - - g_return_val_if_fail (theme != NULL, FALSE); - - /* FIXME what else should be checked? */ - - g_assert (theme->name); - - if (theme->readable_name == NULL) - { - /* Translators: This error means that a necessary XML tag (whose name - * is given in angle brackets) was not found in a given theme (whose - * name is given second, in quotation marks). - */ - g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED, - _("No <%s> set for theme \"%s\""), "name", theme->name); - return FALSE; - } - - if (theme->author == NULL) - { - g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED, - _("No <%s> set for theme \"%s\""), "author", theme->name); - return FALSE; - } - - if (theme->date == NULL) - { - g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED, - _("No <%s> set for theme \"%s\""), "date", theme->name); - return FALSE; - } - - if (theme->description == NULL) - { - g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED, - _("No <%s> set for theme \"%s\""), "description", theme->name); - return FALSE; - } - - if (theme->copyright == NULL) - { - g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED, - _("No <%s> set for theme \"%s\""), "copyright", theme->name); - return FALSE; - } - - for (i = 0; i < (int)META_FRAME_TYPE_LAST; i++) - if (i != (int)META_FRAME_TYPE_ATTACHED && theme->style_sets_by_type[i] == NULL) - { - g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED, - _("No frame style set for window type \"%s\" in theme \"%s\", add a <window type=\"%s\" style_set=\"whatever\"/> element"), - meta_frame_type_to_string (i), - theme->name, - meta_frame_type_to_string (i)); - - return FALSE; - } - - return TRUE; -} - -/** - * meta_theme_load_image: (skip) - * - */ -LOCAL_SYMBOL GdkPixbuf* -meta_theme_load_image (MetaTheme *theme, - const char *filename, - guint scale, - GError **error) -{ - GdkPixbuf *pixbuf; - - pixbuf = g_hash_table_lookup (theme->images_by_filename, - filename); - - if (pixbuf == NULL) - { - - if (g_str_has_prefix (filename, "theme:") && - META_THEME_ALLOWS (theme, META_THEME_IMAGES_FROM_ICON_THEMES)) - { - pixbuf = gtk_icon_theme_load_icon_for_scale (gtk_icon_theme_get_default (), - filename+6, - 20, - scale, - 0, - error); - if (pixbuf == NULL) return NULL; - } - else - { - char *full_path; - gint width, height; - - full_path = g_build_filename (theme->dirname, filename, NULL); - - if (gdk_pixbuf_get_file_info (full_path, &width, &height) == NULL) - { - g_free (full_path); - return NULL; - } - - width *= scale; - height *= scale; - - pixbuf = gdk_pixbuf_new_from_file_at_size (full_path, width, height, error); - - if (pixbuf == NULL) - { - g_free (full_path); - return NULL; - } - - g_free (full_path); - } - g_hash_table_replace (theme->images_by_filename, - g_strdup (filename), - pixbuf); - } - - g_assert (pixbuf); - - g_object_ref (G_OBJECT (pixbuf)); - - return pixbuf; -} - -static MetaFrameStyle* -theme_get_style (MetaTheme *theme, - MetaFrameType type, - MetaFrameFlags flags) -{ - MetaFrameState state; - MetaFrameResize resize; - MetaFrameFocus focus; - MetaFrameStyle *style; - MetaFrameStyleSet *style_set; - - style_set = theme->style_sets_by_type[type]; - - if (style_set == NULL && type == META_FRAME_TYPE_ATTACHED) - style_set = theme->style_sets_by_type[META_FRAME_TYPE_BORDER]; - - /* Right now the parser forces a style set for all other types, - * but this fallback code is here in case I take that out. - */ - if (style_set == NULL) - style_set = theme->style_sets_by_type[META_FRAME_TYPE_NORMAL]; - if (style_set == NULL) - return NULL; - - switch (flags & (META_FRAME_MAXIMIZED | META_FRAME_SHADED | - META_FRAME_TILED_LEFT | META_FRAME_TILED_RIGHT)) - { - case 0: - state = META_FRAME_STATE_NORMAL; - break; - case META_FRAME_MAXIMIZED: - state = META_FRAME_STATE_MAXIMIZED; - break; - case META_FRAME_TILED_LEFT: - state = META_FRAME_STATE_TILED_LEFT; - break; - case META_FRAME_TILED_RIGHT: - state = META_FRAME_STATE_TILED_RIGHT; - break; - case META_FRAME_SHADED: - state = META_FRAME_STATE_SHADED; - break; - case (META_FRAME_MAXIMIZED | META_FRAME_SHADED): - state = META_FRAME_STATE_MAXIMIZED_AND_SHADED; - break; - case (META_FRAME_TILED_LEFT | META_FRAME_SHADED): - state = META_FRAME_STATE_TILED_LEFT_AND_SHADED; - break; - case (META_FRAME_TILED_RIGHT | META_FRAME_SHADED): - state = META_FRAME_STATE_TILED_RIGHT_AND_SHADED; - break; - default: - state = META_FRAME_STATE_LAST; /* compiler */ - break; - } - - switch (flags & (META_FRAME_ALLOWS_VERTICAL_RESIZE | META_FRAME_ALLOWS_HORIZONTAL_RESIZE)) - { - case 0: - resize = META_FRAME_RESIZE_NONE; - break; - case META_FRAME_ALLOWS_VERTICAL_RESIZE: - case META_FRAME_ALLOWS_BOTTOM_RESIZE: - case META_FRAME_ALLOWS_TOP_RESIZE: - resize = META_FRAME_RESIZE_VERTICAL; - break; - case META_FRAME_ALLOWS_HORIZONTAL_RESIZE: - case META_FRAME_ALLOWS_LEFT_RESIZE: - case META_FRAME_ALLOWS_RIGHT_RESIZE: - resize = META_FRAME_RESIZE_HORIZONTAL; - break; - case (META_FRAME_ALLOWS_VERTICAL_RESIZE | META_FRAME_ALLOWS_HORIZONTAL_RESIZE): - case (META_FRAME_ALLOWS_LEFT_RESIZE | META_FRAME_ALLOWS_BOTTOM_RESIZE): - case (META_FRAME_ALLOWS_RIGHT_RESIZE | META_FRAME_ALLOWS_BOTTOM_RESIZE): - case (META_FRAME_ALLOWS_LEFT_RESIZE | META_FRAME_ALLOWS_TOP_RESIZE): - case (META_FRAME_ALLOWS_RIGHT_RESIZE | META_FRAME_ALLOWS_TOP_RESIZE): - resize = META_FRAME_RESIZE_BOTH; - break; - default: - g_assert_not_reached (); - resize = META_FRAME_RESIZE_LAST; /* compiler */ - break; - } - - /* re invert the styles used for focus/unfocussed while flashing a frame */ - if (((flags & META_FRAME_HAS_FOCUS) && !(flags & META_FRAME_IS_FLASHING)) - || (!(flags & META_FRAME_HAS_FOCUS) && (flags & META_FRAME_IS_FLASHING))) - focus = META_FRAME_FOCUS_YES; - else - focus = META_FRAME_FOCUS_NO; - - style = get_style (style_set, state, resize, focus); - - return style; -} - -LOCAL_SYMBOL MetaFrameStyle* -meta_theme_get_frame_style (MetaTheme *theme, - MetaFrameType type, - MetaFrameFlags flags) -{ - MetaFrameStyle *style; - - g_return_val_if_fail (type < META_FRAME_TYPE_LAST, NULL); - - style = theme_get_style (theme, type, flags); - - return style; -} - -LOCAL_SYMBOL double -meta_theme_get_title_scale (MetaTheme *theme, - MetaFrameType type, - MetaFrameFlags flags) -{ - MetaFrameStyle *style; - - g_return_val_if_fail (type < META_FRAME_TYPE_LAST, 1.0); - - style = theme_get_style (theme, type, flags); - - /* Parser is not supposed to allow this currently */ - if (style == NULL) - return 1.0; - - return style->layout->title_scale; -} - -LOCAL_SYMBOL void -meta_theme_draw_frame_with_style (MetaTheme *theme, - GtkStyleContext *style_gtk, - GtkWidget *widget, - cairo_t *cr, - MetaFrameType type, - MetaFrameFlags flags, - int client_width, - int client_height, - PangoLayout *title_layout, - int text_height, - const MetaButtonLayout *button_layout, - MetaButtonState button_states[META_BUTTON_TYPE_LAST]) -{ - MetaFrameGeometry fgeom; - MetaFrameStyle *style; - - g_return_if_fail (type < META_FRAME_TYPE_LAST); - - style = theme_get_style (theme, type, flags); - - /* Parser is not supposed to allow this currently */ - if (style == NULL) - return; - - meta_frame_layout_calc_geometry (style->layout, - text_height, - flags, - client_width, client_height, - button_layout, - type, - &fgeom, - theme); - - meta_frame_style_draw_with_style (style, - style_gtk, - widget, - cr, - &fgeom, - client_width, client_height, - title_layout, - text_height, - button_states); + return font_desc; } void meta_theme_draw_frame (MetaTheme *theme, - GtkWidget *widget, + MetaStyleInfo *style_info, cairo_t *cr, MetaFrameType type, MetaFrameFlags flags, @@ -5595,770 +1245,131 @@ meta_theme_draw_frame (MetaTheme *theme, PangoLayout *title_layout, int text_height, const MetaButtonLayout *button_layout, - MetaButtonState button_states[META_BUTTON_TYPE_LAST]) -{ - meta_theme_draw_frame_with_style (theme, gtk_widget_get_style_context (widget), widget, - cr, type,flags, - client_width, client_height, - title_layout, text_height, - button_layout, button_states); -} - -void -meta_theme_get_frame_borders (MetaTheme *theme, - MetaFrameType type, - int text_height, - MetaFrameFlags flags, - MetaFrameBorders *borders) -{ - MetaFrameStyle *style; - - g_return_if_fail (type < META_FRAME_TYPE_LAST); - - style = theme_get_style (theme, type, flags); - - meta_frame_borders_clear (borders); - - /* Parser is not supposed to allow this currently */ - if (style == NULL) - return; - - meta_frame_layout_get_borders (style->layout, - text_height, - flags, type, - borders); -} - -LOCAL_SYMBOL void -meta_theme_calc_geometry (MetaTheme *theme, - MetaFrameType type, - int text_height, - MetaFrameFlags flags, - int client_width, - int client_height, - const MetaButtonLayout *button_layout, - MetaFrameGeometry *fgeom) + MetaButtonState button_states[META_BUTTON_TYPE_LAST], + cairo_surface_t *mini_icon) { - MetaFrameStyle *style; + MetaFrameGeometry fgeom; + MetaFrameLayout *layout; g_return_if_fail (type < META_FRAME_TYPE_LAST); - style = theme_get_style (theme, type, flags); + layout = theme->layouts[type]; /* Parser is not supposed to allow this currently */ - if (style == NULL) + if (layout == NULL) return; - meta_frame_layout_calc_geometry (style->layout, + meta_frame_layout_calc_geometry (layout, + style_info, text_height, flags, client_width, client_height, button_layout, type, - fgeom, + &fgeom, theme); -} - -LOCAL_SYMBOL MetaFrameLayout* -meta_theme_lookup_layout (MetaTheme *theme, - const char *name) -{ - return g_hash_table_lookup (theme->layouts_by_name, name); -} - -LOCAL_SYMBOL void -meta_theme_insert_layout (MetaTheme *theme, - const char *name, - MetaFrameLayout *layout) -{ - meta_frame_layout_ref (layout); - g_hash_table_replace (theme->layouts_by_name, g_strdup (name), layout); -} - -LOCAL_SYMBOL MetaDrawOpList* -meta_theme_lookup_draw_op_list (MetaTheme *theme, - const char *name) -{ - return g_hash_table_lookup (theme->draw_op_lists_by_name, name); -} - -LOCAL_SYMBOL void -meta_theme_insert_draw_op_list (MetaTheme *theme, - const char *name, - MetaDrawOpList *op_list) -{ - meta_draw_op_list_ref (op_list); - g_hash_table_replace (theme->draw_op_lists_by_name, g_strdup (name), op_list); -} - -LOCAL_SYMBOL MetaFrameStyle* -meta_theme_lookup_style (MetaTheme *theme, - const char *name) -{ - return g_hash_table_lookup (theme->styles_by_name, name); -} - -LOCAL_SYMBOL void -meta_theme_insert_style (MetaTheme *theme, - const char *name, - MetaFrameStyle *style) -{ - meta_frame_style_ref (style); - g_hash_table_replace (theme->styles_by_name, g_strdup (name), style); -} - -LOCAL_SYMBOL MetaFrameStyleSet* -meta_theme_lookup_style_set (MetaTheme *theme, - const char *name) -{ - return g_hash_table_lookup (theme->style_sets_by_name, name); -} - -LOCAL_SYMBOL LOCAL_SYMBOL void -meta_theme_insert_style_set (MetaTheme *theme, - const char *name, - MetaFrameStyleSet *style_set) -{ - meta_frame_style_set_ref (style_set); - g_hash_table_replace (theme->style_sets_by_name, g_strdup (name), style_set); -} - -static gboolean -first_uppercase (const char *str) -{ - return g_ascii_isupper (*str); -} - -LOCAL_SYMBOL gboolean -meta_theme_define_int_constant (MetaTheme *theme, - const char *name, - int value, - GError **error) -{ - if (theme->integer_constants == NULL) - theme->integer_constants = g_hash_table_new_full (g_str_hash, - g_str_equal, - free, - NULL); - - if (!first_uppercase (name)) - { - g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED, - _("User-defined constants must begin with a capital letter; \"%s\" does not"), - name); - return FALSE; - } - - if (g_hash_table_lookup_extended (theme->integer_constants, name, NULL, NULL)) - { - g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED, - _("Constant \"%s\" has already been defined"), - name); - - return FALSE; - } - - g_hash_table_insert (theme->integer_constants, - g_strdup (name), - GINT_TO_POINTER (value)); - - return TRUE; -} - -LOCAL_SYMBOL gboolean -meta_theme_lookup_int_constant (MetaTheme *theme, - const char *name, - int *value) -{ - gpointer old_value; - - *value = 0; - - if (theme->integer_constants == NULL) - return FALSE; - - if (g_hash_table_lookup_extended (theme->integer_constants, - name, NULL, &old_value)) - { - *value = GPOINTER_TO_INT (old_value); - return TRUE; - } - else - { - return FALSE; - } -} - -LOCAL_SYMBOL gboolean -meta_theme_define_float_constant (MetaTheme *theme, - const char *name, - double value, - GError **error) -{ - double *d; - - if (theme->float_constants == NULL) - theme->float_constants = g_hash_table_new_full (g_str_hash, - g_str_equal, - free, - free); - - if (!first_uppercase (name)) - { - g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED, - _("User-defined constants must begin with a capital letter; \"%s\" does not"), - name); - return FALSE; - } - - if (g_hash_table_lookup_extended (theme->float_constants, name, NULL, NULL)) - { - g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED, - _("Constant \"%s\" has already been defined"), - name); - - return FALSE; - } - - d = g_new (double, 1); - *d = value; - g_hash_table_insert (theme->float_constants, - g_strdup (name), d); - - return TRUE; -} - -LOCAL_SYMBOL gboolean -meta_theme_lookup_float_constant (MetaTheme *theme, - const char *name, - double *value) -{ - double *d; - - *value = 0.0; - - if (theme->float_constants == NULL) - return FALSE; - - d = g_hash_table_lookup (theme->float_constants, name); - - if (d) - { - *value = *d; - return TRUE; - } - else - { - return FALSE; - } -} - -LOCAL_SYMBOL gboolean -meta_theme_define_color_constant (MetaTheme *theme, - const char *name, - const char *value, - GError **error) -{ - if (theme->color_constants == NULL) - theme->color_constants = g_hash_table_new_full (g_str_hash, - g_str_equal, - free, - NULL); - - if (!first_uppercase (name)) - { - g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED, - _("User-defined constants must begin with a capital letter; \"%s\" does not"), - name); - return FALSE; - } - - if (g_hash_table_lookup_extended (theme->color_constants, name, NULL, NULL)) - { - g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED, - _("Constant \"%s\" has already been defined"), - name); - - return FALSE; - } - - g_hash_table_insert (theme->color_constants, - g_strdup (name), - g_strdup (value)); - - return TRUE; -} - -/* - * Looks up a colour constant. - * - * \param theme the theme containing the constant - * \param name the name of the constant - * \param value [out] the string representation of the colour, or NULL if it - * doesn't exist - * \return TRUE if it exists, FALSE otherwise - */ -LOCAL_SYMBOL gboolean -meta_theme_lookup_color_constant (MetaTheme *theme, - const char *name, - char **value) -{ - char *result; - - *value = NULL; - - if (theme->color_constants == NULL) - return FALSE; - - result = g_hash_table_lookup (theme->color_constants, name); - - if (result) - { - *value = result; - return TRUE; - } - else - { - return FALSE; - } -} - - -LOCAL_SYMBOL PangoFontDescription* -meta_gtk_widget_get_font_desc (GtkWidget *widget, - double scale, - const PangoFontDescription *override) -{ - GtkStyleContext *style; - PangoFontDescription *font_desc; - - g_return_val_if_fail (gtk_widget_get_realized (widget), NULL); - - style = gtk_widget_get_style_context (widget); - gtk_style_context_get (style, gtk_style_context_get_state (style), - GTK_STYLE_PROPERTY_FONT, &font_desc, - NULL); - - if (override) - pango_font_description_merge (font_desc, override, TRUE); - - pango_font_description_set_size (font_desc, - MAX (pango_font_description_get_size (font_desc) * scale, 1)); - - return font_desc; -} - -/* - * Returns the height of the letters in a particular font. - * - * \param font_desc the font - * \param context the context of the font - * \return the height of the letters - */ -int -meta_pango_font_desc_get_text_height (const PangoFontDescription *font_desc, - PangoContext *context) -{ - PangoFontMetrics *metrics; - PangoLanguage *lang; - int retval; - - lang = pango_context_get_language (context); - metrics = pango_context_get_metrics (context, font_desc, lang); - - retval = PANGO_PIXELS (pango_font_metrics_get_ascent (metrics) + - pango_font_metrics_get_descent (metrics)); - - pango_font_metrics_unref (metrics); - - return retval; -} - -LOCAL_SYMBOL MetaGtkColorComponent -meta_color_component_from_string (const char *str) -{ - if (strcmp ("fg", str) == 0) - return META_GTK_COLOR_FG; - else if (strcmp ("bg", str) == 0) - return META_GTK_COLOR_BG; - else if (strcmp ("light", str) == 0) - return META_GTK_COLOR_LIGHT; - else if (strcmp ("dark", str) == 0) - return META_GTK_COLOR_DARK; - else if (strcmp ("mid", str) == 0) - return META_GTK_COLOR_MID; - else if (strcmp ("text", str) == 0) - return META_GTK_COLOR_TEXT; - else if (strcmp ("base", str) == 0) - return META_GTK_COLOR_BASE; - else if (strcmp ("text_aa", str) == 0) - return META_GTK_COLOR_TEXT_AA; - else - return META_GTK_COLOR_LAST; -} - -LOCAL_SYMBOL const char* -meta_color_component_to_string (MetaGtkColorComponent component) -{ - switch (component) - { - case META_GTK_COLOR_FG: - return "fg"; - case META_GTK_COLOR_BG: - return "bg"; - case META_GTK_COLOR_LIGHT: - return "light"; - case META_GTK_COLOR_DARK: - return "dark"; - case META_GTK_COLOR_MID: - return "mid"; - case META_GTK_COLOR_TEXT: - return "text"; - case META_GTK_COLOR_BASE: - return "base"; - case META_GTK_COLOR_TEXT_AA: - return "text_aa"; - case META_GTK_COLOR_LAST: - break; - } - - return "<unknown>"; -} - -LOCAL_SYMBOL MetaButtonState -meta_button_state_from_string (const char *str) -{ - if (strcmp ("normal", str) == 0) - return META_BUTTON_STATE_NORMAL; - else if (strcmp ("pressed", str) == 0) - return META_BUTTON_STATE_PRESSED; - else if (strcmp ("prelight", str) == 0) - return META_BUTTON_STATE_PRELIGHT; - else - return META_BUTTON_STATE_LAST; -} - -LOCAL_SYMBOL const char* -meta_button_state_to_string (MetaButtonState state) -{ - switch (state) - { - case META_BUTTON_STATE_NORMAL: - return "normal"; - case META_BUTTON_STATE_PRESSED: - return "pressed"; - case META_BUTTON_STATE_PRELIGHT: - return "prelight"; - case META_BUTTON_STATE_LAST: - break; - } - - return "<unknown>"; + meta_frame_layout_draw_with_style (layout, + style_info, + cr, + &fgeom, + title_layout, + flags, + button_states, + mini_icon); } -LOCAL_SYMBOL MetaButtonType -meta_button_type_from_string (const char *str, MetaTheme *theme) -{ - if (META_THEME_ALLOWS(theme, META_THEME_SHADE_STICK_ABOVE_BUTTONS)) - { - if (strcmp ("shade", str) == 0) - return META_BUTTON_TYPE_SHADE; - else if (strcmp ("above", str) == 0) - return META_BUTTON_TYPE_ABOVE; - else if (strcmp ("stick", str) == 0) - return META_BUTTON_TYPE_STICK; - else if (strcmp ("unshade", str) == 0) - return META_BUTTON_TYPE_UNSHADE; - else if (strcmp ("unabove", str) == 0) - return META_BUTTON_TYPE_UNABOVE; - else if (strcmp ("unstick", str) == 0) - return META_BUTTON_TYPE_UNSTICK; - } - - if (strcmp ("close", str) == 0) - return META_BUTTON_TYPE_CLOSE; - else if (strcmp ("maximize", str) == 0) - return META_BUTTON_TYPE_MAXIMIZE; - else if (strcmp ("minimize", str) == 0) - return META_BUTTON_TYPE_MINIMIZE; - else if (strcmp ("menu", str) == 0) - return META_BUTTON_TYPE_MENU; - else if (strcmp ("left_left_background", str) == 0) - return META_BUTTON_TYPE_LEFT_LEFT_BACKGROUND; - else if (strcmp ("left_middle_background", str) == 0) - return META_BUTTON_TYPE_LEFT_MIDDLE_BACKGROUND; - else if (strcmp ("left_right_background", str) == 0) - return META_BUTTON_TYPE_LEFT_RIGHT_BACKGROUND; - else if (strcmp ("left_single_background", str) == 0) - return META_BUTTON_TYPE_LEFT_SINGLE_BACKGROUND; - else if (strcmp ("right_left_background", str) == 0) - return META_BUTTON_TYPE_RIGHT_LEFT_BACKGROUND; - else if (strcmp ("right_middle_background", str) == 0) - return META_BUTTON_TYPE_RIGHT_MIDDLE_BACKGROUND; - else if (strcmp ("right_right_background", str) == 0) - return META_BUTTON_TYPE_RIGHT_RIGHT_BACKGROUND; - else if (strcmp ("right_single_background", str) == 0) - return META_BUTTON_TYPE_RIGHT_SINGLE_BACKGROUND; - else - return META_BUTTON_TYPE_LAST; -} - -LOCAL_SYMBOL const char* -meta_button_type_to_string (MetaButtonType type) +void +meta_theme_get_frame_borders (MetaTheme *theme, + MetaStyleInfo *style_info, + MetaFrameType type, + int text_height, + MetaFrameFlags flags, + MetaFrameBorders *borders) { - switch (type) - { - case META_BUTTON_TYPE_CLOSE: - return "close"; - case META_BUTTON_TYPE_MAXIMIZE: - return "maximize"; - case META_BUTTON_TYPE_MINIMIZE: - return "minimize"; - case META_BUTTON_TYPE_SHADE: - return "shade"; - case META_BUTTON_TYPE_ABOVE: - return "above"; - case META_BUTTON_TYPE_STICK: - return "stick"; - case META_BUTTON_TYPE_UNSHADE: - return "unshade"; - case META_BUTTON_TYPE_UNABOVE: - return "unabove"; - case META_BUTTON_TYPE_UNSTICK: - return "unstick"; - case META_BUTTON_TYPE_MENU: - return "menu"; - case META_BUTTON_TYPE_LEFT_LEFT_BACKGROUND: - return "left_left_background"; - case META_BUTTON_TYPE_LEFT_MIDDLE_BACKGROUND: - return "left_middle_background"; - case META_BUTTON_TYPE_LEFT_RIGHT_BACKGROUND: - return "left_right_background"; - case META_BUTTON_TYPE_LEFT_SINGLE_BACKGROUND: - return "left_single_background"; - case META_BUTTON_TYPE_RIGHT_LEFT_BACKGROUND: - return "right_left_background"; - case META_BUTTON_TYPE_RIGHT_MIDDLE_BACKGROUND: - return "right_middle_background"; - case META_BUTTON_TYPE_RIGHT_RIGHT_BACKGROUND: - return "right_right_background"; - case META_BUTTON_TYPE_RIGHT_SINGLE_BACKGROUND: - return "right_single_background"; - case META_BUTTON_TYPE_LAST: - break; - } + MetaFrameLayout *layout; - return "<unknown>"; -} + g_return_if_fail (type < META_FRAME_TYPE_LAST); -LOCAL_SYMBOL MetaFramePiece -meta_frame_piece_from_string (const char *str) -{ - if (strcmp ("entire_background", str) == 0) - return META_FRAME_PIECE_ENTIRE_BACKGROUND; - else if (strcmp ("titlebar", str) == 0) - return META_FRAME_PIECE_TITLEBAR; - else if (strcmp ("titlebar_middle", str) == 0) - return META_FRAME_PIECE_TITLEBAR_MIDDLE; - else if (strcmp ("left_titlebar_edge", str) == 0) - return META_FRAME_PIECE_LEFT_TITLEBAR_EDGE; - else if (strcmp ("right_titlebar_edge", str) == 0) - return META_FRAME_PIECE_RIGHT_TITLEBAR_EDGE; - else if (strcmp ("top_titlebar_edge", str) == 0) - return META_FRAME_PIECE_TOP_TITLEBAR_EDGE; - else if (strcmp ("bottom_titlebar_edge", str) == 0) - return META_FRAME_PIECE_BOTTOM_TITLEBAR_EDGE; - else if (strcmp ("title", str) == 0) - return META_FRAME_PIECE_TITLE; - else if (strcmp ("left_edge", str) == 0) - return META_FRAME_PIECE_LEFT_EDGE; - else if (strcmp ("right_edge", str) == 0) - return META_FRAME_PIECE_RIGHT_EDGE; - else if (strcmp ("bottom_edge", str) == 0) - return META_FRAME_PIECE_BOTTOM_EDGE; - else if (strcmp ("overlay", str) == 0) - return META_FRAME_PIECE_OVERLAY; - else - return META_FRAME_PIECE_LAST; -} + layout = theme->layouts[type]; -LOCAL_SYMBOL const char* -meta_frame_piece_to_string (MetaFramePiece piece) -{ - switch (piece) - { - case META_FRAME_PIECE_ENTIRE_BACKGROUND: - return "entire_background"; - case META_FRAME_PIECE_TITLEBAR: - return "titlebar"; - case META_FRAME_PIECE_TITLEBAR_MIDDLE: - return "titlebar_middle"; - case META_FRAME_PIECE_LEFT_TITLEBAR_EDGE: - return "left_titlebar_edge"; - case META_FRAME_PIECE_RIGHT_TITLEBAR_EDGE: - return "right_titlebar_edge"; - case META_FRAME_PIECE_TOP_TITLEBAR_EDGE: - return "top_titlebar_edge"; - case META_FRAME_PIECE_BOTTOM_TITLEBAR_EDGE: - return "bottom_titlebar_edge"; - case META_FRAME_PIECE_TITLE: - return "title"; - case META_FRAME_PIECE_LEFT_EDGE: - return "left_edge"; - case META_FRAME_PIECE_RIGHT_EDGE: - return "right_edge"; - case META_FRAME_PIECE_BOTTOM_EDGE: - return "bottom_edge"; - case META_FRAME_PIECE_OVERLAY: - return "overlay"; - case META_FRAME_PIECE_LAST: - break; - } + meta_frame_borders_clear (borders); - return "<unknown>"; -} + /* Parser is not supposed to allow this currently */ + if (layout == NULL) + return; -LOCAL_SYMBOL MetaFrameState -meta_frame_state_from_string (const char *str) -{ - if (strcmp ("normal", str) == 0) - return META_FRAME_STATE_NORMAL; - else if (strcmp ("maximized", str) == 0) - return META_FRAME_STATE_MAXIMIZED; - else if (strcmp ("tiled_left", str) == 0) - return META_FRAME_STATE_TILED_LEFT; - else if (strcmp ("tiled_right", str) == 0) - return META_FRAME_STATE_TILED_RIGHT; - else if (strcmp ("shaded", str) == 0) - return META_FRAME_STATE_SHADED; - else if (strcmp ("maximized_and_shaded", str) == 0) - return META_FRAME_STATE_MAXIMIZED_AND_SHADED; - else if (strcmp ("tiled_left_and_shaded", str) == 0) - return META_FRAME_STATE_TILED_LEFT_AND_SHADED; - else if (strcmp ("tiled_right_and_shaded", str) == 0) - return META_FRAME_STATE_TILED_RIGHT_AND_SHADED; - else - return META_FRAME_STATE_LAST; + meta_frame_layout_sync_with_style (layout, style_info, flags); + + meta_frame_layout_get_borders (layout, + text_height, + flags, type, + borders); } -LOCAL_SYMBOL const char* -meta_frame_state_to_string (MetaFrameState state) +void +meta_theme_calc_geometry (MetaTheme *theme, + MetaStyleInfo *style_info, + MetaFrameType type, + int text_height, + MetaFrameFlags flags, + int client_width, + int client_height, + const MetaButtonLayout *button_layout, + MetaFrameGeometry *fgeom) { - switch (state) - { - case META_FRAME_STATE_NORMAL: - return "normal"; - case META_FRAME_STATE_MAXIMIZED: - return "maximized"; - case META_FRAME_STATE_TILED_LEFT: - return "tiled_left"; - case META_FRAME_STATE_TILED_RIGHT: - return "tiled_right"; - case META_FRAME_STATE_SHADED: - return "shaded"; - case META_FRAME_STATE_MAXIMIZED_AND_SHADED: - return "maximized_and_shaded"; - case META_FRAME_STATE_TILED_LEFT_AND_SHADED: - return "tiled_left_and_shaded"; - case META_FRAME_STATE_TILED_RIGHT_AND_SHADED: - return "tiled_right_and_shaded"; - case META_FRAME_STATE_LAST: - break; - } + MetaFrameLayout *layout; - return "<unknown>"; -} + g_return_if_fail (type < META_FRAME_TYPE_LAST); -LOCAL_SYMBOL MetaFrameResize -meta_frame_resize_from_string (const char *str) -{ - if (strcmp ("none", str) == 0) - return META_FRAME_RESIZE_NONE; - else if (strcmp ("vertical", str) == 0) - return META_FRAME_RESIZE_VERTICAL; - else if (strcmp ("horizontal", str) == 0) - return META_FRAME_RESIZE_HORIZONTAL; - else if (strcmp ("both", str) == 0) - return META_FRAME_RESIZE_BOTH; - else - return META_FRAME_RESIZE_LAST; -} + layout = theme->layouts[type]; -LOCAL_SYMBOL const char* -meta_frame_resize_to_string (MetaFrameResize resize) -{ - switch (resize) - { - case META_FRAME_RESIZE_NONE: - return "none"; - case META_FRAME_RESIZE_VERTICAL: - return "vertical"; - case META_FRAME_RESIZE_HORIZONTAL: - return "horizontal"; - case META_FRAME_RESIZE_BOTH: - return "both"; - case META_FRAME_RESIZE_LAST: - break; - } + /* Parser is not supposed to allow this currently */ + if (layout == NULL) + return; - return "<unknown>"; + meta_frame_layout_calc_geometry (layout, + style_info, + text_height, + flags, + client_width, client_height, + button_layout, + type, + fgeom, + theme); } -LOCAL_SYMBOL MetaFrameFocus -meta_frame_focus_from_string (const char *str) +/** + * meta_pango_font_desc_get_text_height: + * @font_desc: the font + * @context: the context of the font + * + * Returns the height of the letters in a particular font. + * + * Returns: the height of the letters + */ +int +meta_pango_font_desc_get_text_height (const PangoFontDescription *font_desc, + PangoContext *context) { - if (strcmp ("no", str) == 0) - return META_FRAME_FOCUS_NO; - else if (strcmp ("yes", str) == 0) - return META_FRAME_FOCUS_YES; - else - return META_FRAME_FOCUS_LAST; -} + PangoFontMetrics *metrics; + PangoLanguage *lang; + int retval; -LOCAL_SYMBOL const char* -meta_frame_focus_to_string (MetaFrameFocus focus) -{ - switch (focus) - { - case META_FRAME_FOCUS_NO: - return "no"; - case META_FRAME_FOCUS_YES: - return "yes"; - case META_FRAME_FOCUS_LAST: - break; - } + lang = pango_context_get_language (context); + metrics = pango_context_get_metrics (context, font_desc, lang); - return "<unknown>"; -} + retval = PANGO_PIXELS (pango_font_metrics_get_ascent (metrics) + + pango_font_metrics_get_descent (metrics)); -LOCAL_SYMBOL MetaFrameType -meta_frame_type_from_string (const char *str) -{ - if (strcmp ("normal", str) == 0) - return META_FRAME_TYPE_NORMAL; - else if (strcmp ("dialog", str) == 0) - return META_FRAME_TYPE_DIALOG; - else if (strcmp ("modal_dialog", str) == 0) - return META_FRAME_TYPE_MODAL_DIALOG; - else if (strcmp ("utility", str) == 0) - return META_FRAME_TYPE_UTILITY; - else if (strcmp ("menu", str) == 0) - return META_FRAME_TYPE_MENU; - else if (strcmp ("border", str) == 0) - return META_FRAME_TYPE_BORDER; - else if (strcmp ("attached", str) == 0) - return META_FRAME_TYPE_ATTACHED; -#if 0 - else if (strcmp ("toolbar", str) == 0) - return META_FRAME_TYPE_TOOLBAR; -#endif - else - return META_FRAME_TYPE_LAST; + pango_font_metrics_unref (metrics); + + return retval; } /** * meta_frame_type_to_string: + * @type: a #MetaFrameType * * Converts a frame type enum value to the name string that would * appear in the theme definition file. @@ -6394,672 +1405,3 @@ meta_frame_type_to_string (MetaFrameType type) return "<unknown>"; } - -LOCAL_SYMBOL MetaGradientType -meta_gradient_type_from_string (const char *str) -{ - if (strcmp ("vertical", str) == 0) - return META_GRADIENT_VERTICAL; - else if (strcmp ("horizontal", str) == 0) - return META_GRADIENT_HORIZONTAL; - else if (strcmp ("diagonal", str) == 0) - return META_GRADIENT_DIAGONAL; - else - return META_GRADIENT_LAST; -} - -LOCAL_SYMBOL const char* -meta_gradient_type_to_string (MetaGradientType type) -{ - switch (type) - { - case META_GRADIENT_VERTICAL: - return "vertical"; - case META_GRADIENT_HORIZONTAL: - return "horizontal"; - case META_GRADIENT_DIAGONAL: - return "diagonal"; - case META_GRADIENT_LAST: - break; - } - - return "<unknown>"; -} - -LOCAL_SYMBOL GtkStateFlags -meta_gtk_state_from_string (const char *str) -{ - if (g_ascii_strcasecmp ("normal", str) == 0) - return GTK_STATE_FLAG_NORMAL; - else if (g_ascii_strcasecmp ("prelight", str) == 0) - return GTK_STATE_FLAG_PRELIGHT; - else if (g_ascii_strcasecmp ("active", str) == 0) - return GTK_STATE_FLAG_ACTIVE; - else if (g_ascii_strcasecmp ("selected", str) == 0) - return GTK_STATE_FLAG_SELECTED; - else if (g_ascii_strcasecmp ("insensitive", str) == 0) - return GTK_STATE_FLAG_INSENSITIVE; - else if (g_ascii_strcasecmp ("inconsistent", str) == 0) - return GTK_STATE_FLAG_INCONSISTENT; - else if (g_ascii_strcasecmp ("focused", str) == 0) - return GTK_STATE_FLAG_FOCUSED; - else if (g_ascii_strcasecmp ("backdrop", str) == 0) - return GTK_STATE_FLAG_BACKDROP; - else - return -1; /* hack */ -} - -LOCAL_SYMBOL const char* -meta_gtk_state_to_string (GtkStateFlags state) -{ - switch (state) - { - case GTK_STATE_FLAG_NORMAL: - return "NORMAL"; - case GTK_STATE_FLAG_PRELIGHT: - return "PRELIGHT"; - case GTK_STATE_FLAG_ACTIVE: - return "ACTIVE"; - case GTK_STATE_FLAG_SELECTED: - return "SELECTED"; - case GTK_STATE_FLAG_INSENSITIVE: - return "INSENSITIVE"; - case GTK_STATE_FLAG_INCONSISTENT: - return "INCONSISTENT"; - case GTK_STATE_FLAG_FOCUSED: - return "FOCUSED"; - case GTK_STATE_FLAG_BACKDROP: - return "BACKDROP"; -#if GTK_MAJOR_VERSION > 3 || (GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION >= 7) - case GTK_STATE_FLAG_DIR_LTR: - return "DIR_LTR"; - case GTK_STATE_FLAG_DIR_RTL: - return "DIR_RTL"; -#endif -#if GTK_MAJOR_VERSION > 3 || (GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION >= 12) - case GTK_STATE_FLAG_LINK: - return "LINK"; - case GTK_STATE_FLAG_VISITED: - return "VISITED"; -#endif -#if GTK_MAJOR_VERSION > 3 || (GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION >= 14) - case GTK_STATE_FLAG_CHECKED: - return "CHECKED"; -#endif - } - - return "<unknown>"; -} - -LOCAL_SYMBOL GtkShadowType -meta_gtk_shadow_from_string (const char *str) -{ - if (strcmp ("none", str) == 0) - return GTK_SHADOW_NONE; - else if (strcmp ("in", str) == 0) - return GTK_SHADOW_IN; - else if (strcmp ("out", str) == 0) - return GTK_SHADOW_OUT; - else if (strcmp ("etched_in", str) == 0) - return GTK_SHADOW_ETCHED_IN; - else if (strcmp ("etched_out", str) == 0) - return GTK_SHADOW_ETCHED_OUT; - else - return -1; -} - -LOCAL_SYMBOL const char* -meta_gtk_shadow_to_string (GtkShadowType shadow) -{ - switch (shadow) - { - case GTK_SHADOW_NONE: - return "none"; - case GTK_SHADOW_IN: - return "in"; - case GTK_SHADOW_OUT: - return "out"; - case GTK_SHADOW_ETCHED_IN: - return "etched_in"; - case GTK_SHADOW_ETCHED_OUT: - return "etched_out"; - } - - return "<unknown>"; -} - -LOCAL_SYMBOL GtkArrowType -meta_gtk_arrow_from_string (const char *str) -{ - if (strcmp ("up", str) == 0) - return GTK_ARROW_UP; - else if (strcmp ("down", str) == 0) - return GTK_ARROW_DOWN; - else if (strcmp ("left", str) == 0) - return GTK_ARROW_LEFT; - else if (strcmp ("right", str) == 0) - return GTK_ARROW_RIGHT; - else if (strcmp ("none", str) == 0) - return GTK_ARROW_NONE; - else - return -1; -} - -LOCAL_SYMBOL const char* -meta_gtk_arrow_to_string (GtkArrowType arrow) -{ - switch (arrow) - { - case GTK_ARROW_UP: - return "up"; - case GTK_ARROW_DOWN: - return "down"; - case GTK_ARROW_LEFT: - return "left"; - case GTK_ARROW_RIGHT: - return "right"; - case GTK_ARROW_NONE: - return "none"; - } - - return "<unknown>"; -} - -/* - * Returns a fill_type from a string. The inverse of - * meta_image_fill_type_to_string(). - * - * \param str a string representing a fill_type - * \result the fill_type, or -1 if it represents no fill_type. - */ -LOCAL_SYMBOL MetaImageFillType -meta_image_fill_type_from_string (const char *str) -{ - if (strcmp ("tile", str) == 0) - return META_IMAGE_FILL_TILE; - else if (strcmp ("scale", str) == 0) - return META_IMAGE_FILL_SCALE; - else - return -1; -} - -/* - * Returns a string representation of a fill_type. The inverse of - * meta_image_fill_type_from_string(). - * - * \param fill_type the fill type - * \result a string representing that type - */ -LOCAL_SYMBOL const char* -meta_image_fill_type_to_string (MetaImageFillType fill_type) -{ - switch (fill_type) - { - case META_IMAGE_FILL_TILE: - return "tile"; - case META_IMAGE_FILL_SCALE: - return "scale"; - } - - return "<unknown>"; -} - -/* - * Takes a colour "a", scales the lightness and saturation by a certain amount, - * and sets "b" to the resulting colour. - * gtkstyle.c cut-and-pastage. - * - * \param a the starting colour - * \param b [out] the resulting colour - * \param k amount to scale lightness and saturation by - */ -static void -gtk_style_shade (GdkRGBA *a, - GdkRGBA *b, - gdouble k) -{ - gdouble red; - gdouble green; - gdouble blue; - - red = a->red; - green = a->green; - blue = a->blue; - - rgb_to_hls (&red, &green, &blue); - - green *= k; - if (green > 1.0) - green = 1.0; - else if (green < 0.0) - green = 0.0; - - blue *= k; - if (blue > 1.0) - blue = 1.0; - else if (blue < 0.0) - blue = 0.0; - - hls_to_rgb (&red, &green, &blue); - - b->red = red; - b->green = green; - b->blue = blue; -} - -/* - * Converts a red/green/blue triplet to a hue/lightness/saturation triplet. - * - * \param r on input, red; on output, hue - * \param g on input, green; on output, lightness - * \param b on input, blue; on output, saturation - */ -static void -rgb_to_hls (gdouble *r, - gdouble *g, - gdouble *b) -{ - gdouble min; - gdouble max; - gdouble red; - gdouble green; - gdouble blue; - gdouble h, l, s; - gdouble delta; - - red = *r; - green = *g; - blue = *b; - - if (red > green) - { - if (red > blue) - max = red; - else - max = blue; - - if (green < blue) - min = green; - else - min = blue; - } - else - { - if (green > blue) - max = green; - else - max = blue; - - if (red < blue) - min = red; - else - min = blue; - } - - l = (max + min) / 2; - s = 0; - h = 0; - - if (max != min) - { - if (l <= 0.5) - s = (max - min) / (max + min); - else - s = (max - min) / (2 - max - min); - - delta = max -min; - if (red == max) - h = (green - blue) / delta; - else if (green == max) - h = 2 + (blue - red) / delta; - else if (blue == max) - h = 4 + (red - green) / delta; - - h *= 60; - if (h < 0.0) - h += 360; - } - - *r = h; - *g = l; - *b = s; -} - -/* - * Converts a hue/lightness/saturation triplet to a red/green/blue triplet. - * - * \param h on input, hue; on output, red - * \param l on input, lightness; on output, green - * \param s on input, saturation; on output, blue - */ -static void -hls_to_rgb (gdouble *h, - gdouble *l, - gdouble *s) -{ - gdouble hue; - gdouble lightness; - gdouble saturation; - gdouble m1, m2; - gdouble r, g, b; - - lightness = *l; - saturation = *s; - - if (lightness <= 0.5) - m2 = lightness * (1 + saturation); - else - m2 = lightness + saturation - lightness * saturation; - m1 = 2 * lightness - m2; - - if (saturation == 0) - { - *h = lightness; - *l = lightness; - *s = lightness; - } - else - { - hue = *h + 120; - while (hue > 360) - hue -= 360; - while (hue < 0) - hue += 360; - - if (hue < 60) - r = m1 + (m2 - m1) * hue / 60; - else if (hue < 180) - r = m2; - else if (hue < 240) - r = m1 + (m2 - m1) * (240 - hue) / 60; - else - r = m1; - - hue = *h; - while (hue > 360) - hue -= 360; - while (hue < 0) - hue += 360; - - if (hue < 60) - g = m1 + (m2 - m1) * hue / 60; - else if (hue < 180) - g = m2; - else if (hue < 240) - g = m1 + (m2 - m1) * (240 - hue) / 60; - else - g = m1; - - hue = *h - 120; - while (hue > 360) - hue -= 360; - while (hue < 0) - hue += 360; - - if (hue < 60) - b = m1 + (m2 - m1) * hue / 60; - else if (hue < 180) - b = m2; - else if (hue < 240) - b = m1 + (m2 - m1) * (240 - hue) / 60; - else - b = m1; - - *h = r; - *l = g; - *s = b; - } -} - -#if 0 -/* These are some functions I'm saving to use in optimizing - * MetaDrawOpList, namely to pre-composite pixbufs on client side - * prior to rendering to the server - */ -static void -draw_bg_solid_composite (const MetaTextureSpec *bg, - const MetaTextureSpec *fg, - double alpha, - GtkWidget *widget, - GdkDrawable *drawable, - const GdkRectangle *clip, - MetaTextureDrawMode mode, - double xalign, - double yalign, - int x, - int y, - int width, - int height) -{ - GdkRGBA bg_color; - - g_assert (bg->type == META_TEXTURE_SOLID); - g_assert (fg->type != META_TEXTURE_COMPOSITE); - g_assert (fg->type != META_TEXTURE_SHAPE_LIST); - - meta_color_spec_render (bg->data.solid.color_spec, - widget, - &bg_color); - - switch (fg->type) - { - case META_TEXTURE_SOLID: - { - GdkRGBA fg_color; - - meta_color_spec_render (fg->data.solid.color_spec, - widget, - &fg_color); - - color_composite (&bg_color, &fg_color, - alpha, &fg_color); - - draw_color_rectangle (widget, drawable, &fg_color, clip, - x, y, width, height); - } - break; - - case META_TEXTURE_GRADIENT: - /* FIXME I think we could just composite all the colors in - * the gradient prior to generating the gradient? - */ - /* FALL THRU */ - case META_TEXTURE_IMAGE: - { - GdkPixbuf *pixbuf; - GdkPixbuf *composited; - - pixbuf = meta_texture_spec_render (fg, widget, mode, 255, - width, height); - - if (pixbuf == NULL) - return; - - composited = gdk_pixbuf_new (GDK_COLORSPACE_RGB, - gdk_pixbuf_get_has_alpha (pixbuf), 8, - gdk_pixbuf_get_width (pixbuf), - gdk_pixbuf_get_height (pixbuf)); - - if (composited == NULL) - { - g_object_unref (G_OBJECT (pixbuf)); - return; - } - - gdk_pixbuf_composite_color (pixbuf, - composited, - 0, 0, - gdk_pixbuf_get_width (pixbuf), - gdk_pixbuf_get_height (pixbuf), - 0.0, 0.0, /* offsets */ - 1.0, 1.0, /* scale */ - GDK_INTERP_BILINEAR, - 255 * alpha, - 0, 0, /* check offsets */ - 0, /* check size */ - GDK_COLOR_RGB (bg_color), - GDK_COLOR_RGB (bg_color)); - - /* Need to draw background since pixbuf is not - * necessarily covering the whole thing - */ - draw_color_rectangle (widget, drawable, &bg_color, clip, - x, y, width, height); - - render_pixbuf_aligned (drawable, clip, composited, - xalign, yalign, - x, y, width, height); - - g_object_unref (G_OBJECT (pixbuf)); - g_object_unref (G_OBJECT (composited)); - } - break; - - case META_TEXTURE_BLANK: - case META_TEXTURE_COMPOSITE: - case META_TEXTURE_SHAPE_LIST: - g_assert_not_reached (); - break; - } -} - -static void -draw_bg_gradient_composite (const MetaTextureSpec *bg, - const MetaTextureSpec *fg, - double alpha, - GtkWidget *widget, - GdkDrawable *drawable, - const GdkRectangle *clip, - MetaTextureDrawMode mode, - double xalign, - double yalign, - int x, - int y, - int width, - int height) -{ - g_assert (bg->type == META_TEXTURE_GRADIENT); - g_assert (fg->type != META_TEXTURE_COMPOSITE); - g_assert (fg->type != META_TEXTURE_SHAPE_LIST); - - switch (fg->type) - { - case META_TEXTURE_SOLID: - case META_TEXTURE_GRADIENT: - case META_TEXTURE_IMAGE: - { - GdkPixbuf *bg_pixbuf; - GdkPixbuf *fg_pixbuf; - GdkPixbuf *composited; - int fg_width, fg_height; - - bg_pixbuf = meta_texture_spec_render (bg, widget, mode, 255, - width, height); - - if (bg_pixbuf == NULL) - return; - - fg_pixbuf = meta_texture_spec_render (fg, widget, mode, 255, - width, height); - - if (fg_pixbuf == NULL) - { - g_object_unref (G_OBJECT (bg_pixbuf)); - return; - } - - /* gradients always fill the entire target area */ - g_assert (gdk_pixbuf_get_width (bg_pixbuf) == width); - g_assert (gdk_pixbuf_get_height (bg_pixbuf) == height); - - composited = gdk_pixbuf_new (GDK_COLORSPACE_RGB, - gdk_pixbuf_get_has_alpha (bg_pixbuf), 8, - gdk_pixbuf_get_width (bg_pixbuf), - gdk_pixbuf_get_height (bg_pixbuf)); - - if (composited == NULL) - { - g_object_unref (G_OBJECT (bg_pixbuf)); - g_object_unref (G_OBJECT (fg_pixbuf)); - return; - } - - fg_width = gdk_pixbuf_get_width (fg_pixbuf); - fg_height = gdk_pixbuf_get_height (fg_pixbuf); - - /* If we wanted to be all cool we could deal with the - * offsets and try to composite only in the clip rectangle, - * but I just don't care enough to figure it out. - */ - - gdk_pixbuf_composite (fg_pixbuf, - composited, - x + (width - fg_width) * xalign, - y + (height - fg_height) * yalign, - gdk_pixbuf_get_width (fg_pixbuf), - gdk_pixbuf_get_height (fg_pixbuf), - 0.0, 0.0, /* offsets */ - 1.0, 1.0, /* scale */ - GDK_INTERP_BILINEAR, - 255 * alpha); - - gdk_cairo_set_source_pixbuf (cr, composited, x, y); - cairo_paint (cr); - - g_object_unref (G_OBJECT (bg_pixbuf)); - g_object_unref (G_OBJECT (fg_pixbuf)); - g_object_unref (G_OBJECT (composited)); - } - break; - - case META_TEXTURE_BLANK: - case META_TEXTURE_SHAPE_LIST: - case META_TEXTURE_COMPOSITE: - g_assert_not_reached (); - break; - } -} -#endif - -/* - * Returns the earliest version of the theme format which required support - * for a particular button. (For example, "shade" first appeared in v2, and - * "close" in v1.) - * - * \param type the button type - * \return the number of the theme format - */ -LOCAL_SYMBOL guint -meta_theme_earliest_version_with_button (MetaButtonType type) -{ - switch (type) - { - case META_BUTTON_TYPE_CLOSE: - case META_BUTTON_TYPE_MAXIMIZE: - case META_BUTTON_TYPE_MINIMIZE: - case META_BUTTON_TYPE_MENU: - case META_BUTTON_TYPE_LEFT_LEFT_BACKGROUND: - case META_BUTTON_TYPE_LEFT_MIDDLE_BACKGROUND: - case META_BUTTON_TYPE_LEFT_RIGHT_BACKGROUND: - case META_BUTTON_TYPE_RIGHT_LEFT_BACKGROUND: - case META_BUTTON_TYPE_RIGHT_MIDDLE_BACKGROUND: - case META_BUTTON_TYPE_RIGHT_RIGHT_BACKGROUND: - return 1000; - - case META_BUTTON_TYPE_SHADE: - case META_BUTTON_TYPE_ABOVE: - case META_BUTTON_TYPE_STICK: - case META_BUTTON_TYPE_UNSHADE: - case META_BUTTON_TYPE_UNABOVE: - case META_BUTTON_TYPE_UNSTICK: - return 2000; - - case META_BUTTON_TYPE_LEFT_SINGLE_BACKGROUND: - case META_BUTTON_TYPE_RIGHT_SINGLE_BACKGROUND: - return 3003; - - default: - meta_warning("Unknown button %d\n", type); - return 1000; - } -} diff --git a/src/ui/ui.c b/src/ui/ui.c index f83854746..64afb0134 100644 --- a/src/ui/ui.c +++ b/src/ui/ui.c @@ -1,11 +1,10 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* Muffin interface for talking to GTK+ UI module */ +/* Mutter interface for talking to GTK+ UI module */ -/* +/* * Copyright (C) 2002 Havoc Pennington - * stock icon code Copyright (C) 2002 Jorn Baayen <jorn@nl.linux.org> - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the @@ -15,281 +14,52 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ -#include <config.h> -#include <meta/prefs.h> -#include "ui.h" -#include "frames.h" -#include <meta/util.h> -#include "menu.h" -#include "core.h" -#include "theme-private.h" -#include "display-private.h" -#include "inlinepixbufs.h" +#include "config.h" -#include <string.h> -#include <stdlib.h> #include <cairo-xlib.h> +#include <stdlib.h> +#include <string.h> -static void meta_stock_icons_init (void); -static void meta_ui_accelerator_parse (const char *accel, - guint *keysym, - guint *keycode, - GdkModifierType *keymask); +#include "meta/prefs.h" +#include "meta/util.h" +#include "ui/frames.h" +#include "ui/theme-private.h" +#include "ui/ui.h" +#include "x11/meta-x11-display-private.h" +#include "x11/meta-x11-window-control.h" struct _MetaUI { Display *xdisplay; - Screen *xscreen; MetaFrames *frames; /* For double-click tracking */ - guint button_click_number; + gint button_click_number; Window button_click_window; int button_click_x; int button_click_y; guint32 button_click_time; }; -LOCAL_SYMBOL void -meta_ui_init (void) -{ - /* As of 2.91.7, Gdk uses XI2 by default, which conflicts with the - * direct X calls we use - in particular, events caused by calls to - * XGrabPointer/XGrabKeyboard are no longer understood by GDK, while - * GDK will no longer generate the core XEvents we process. - * So at least for now, enforce the previous behavior. - */ - gdk_disable_multidevice (); - - if (!gtk_init_check (NULL, NULL)) - meta_fatal ("Unable to open X display %s\n", XDisplayName (NULL)); - -/* We need to be able to fully trust that the window and monitor sizes -+ that Gdk reports corresponds to the X ones, so we disable the automatic -+ scale handling */ - gdk_x11_display_set_window_scale (gdk_display_get_default (), 1); - - meta_stock_icons_init (); -} - -LOCAL_SYMBOL Display* -meta_ui_get_display (void) -{ - return GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); -} - -/* We do some of our event handling in frames.c, which expects - * GDK events delivered by GTK+. However, since the transition to - * client side windows, we can't let GDK see button events, since the - * client-side tracking of implicit and explicit grabs it does will - * get confused by our direct use of X grabs in the core code. - * - * So we do a very minimal GDK => GTK event conversion here and send on the - * events we care about, and then filter them out so they don't go - * through the normal GDK event handling. - * - * To reduce the amount of code, the only events fields filled out - * below are the ones that frames.c uses. If frames.c is modified to - * use more fields, more fields need to be filled out below. - */ - -static gboolean -maybe_redirect_mouse_event (MetaDisplay *display, - XEvent *xevent) +MetaUI * +meta_ui_new (MetaX11Display *x11_display) { - GdkDisplay *gdisplay; - GdkDevice *gdevice; MetaUI *ui; - GdkEvent *gevent; - GdkWindow *gdk_window; - Window window; - - switch (xevent->type) - { - case ButtonPress: - case ButtonRelease: - window = xevent->xbutton.window; - break; - case MotionNotify: - window = xevent->xmotion.window; - break; - case EnterNotify: - case LeaveNotify: - window = xevent->xcrossing.window; - break; - default: - return FALSE; - } - - gdisplay = display->gdk_display; - ui = display->ui; - - if (!ui) - return FALSE; - - gdk_window = gdk_x11_window_lookup_for_display (gdisplay, window); - if (gdk_window == NULL) - return FALSE; - - gdevice = display->gdk_device; - - /* If GDK already thinks it has a grab, we better let it see events; this - * is the menu-navigation case and events need to get sent to the appropriate - * (client-side) subwindow for individual menu items. - */ - if (gdk_display_device_is_grabbed (gdisplay, gdevice)) - return FALSE; - - switch (xevent->type) - { - case ButtonPress: - case ButtonRelease: - if (xevent->type == ButtonPress) - { - GtkSettings *settings = gtk_settings_get_default (); - int double_click_time; - int double_click_distance; - - g_object_get (settings, - "gtk-double-click-time", &double_click_time, - "gtk-double-click-distance", &double_click_distance, - NULL); - - if (xevent->xbutton.button == ui->button_click_number && - xevent->xbutton.window == ui->button_click_window && - xevent->xbutton.time < ui->button_click_time + double_click_time && - ABS (xevent->xbutton.x - ui->button_click_x) <= double_click_distance && - ABS (xevent->xbutton.y - ui->button_click_y) <= double_click_distance) - { - gevent = gdk_event_new (GDK_2BUTTON_PRESS); - - ui->button_click_number = 0; - } - else - { - gevent = gdk_event_new (GDK_BUTTON_PRESS); - ui->button_click_number = xevent->xbutton.button; - ui->button_click_window = xevent->xbutton.window; - ui->button_click_time = xevent->xbutton.time; - ui->button_click_x = xevent->xbutton.x; - ui->button_click_y = xevent->xbutton.y; - } - } - else - { - gevent = gdk_event_new (GDK_BUTTON_RELEASE); - } - - gevent->button.window = g_object_ref (gdk_window); - gevent->button.button = xevent->xbutton.button; - gevent->button.time = xevent->xbutton.time; - gevent->button.x = xevent->xbutton.x; - gevent->button.y = xevent->xbutton.y; - gevent->button.x_root = xevent->xbutton.x_root; - gevent->button.y_root = xevent->xbutton.y_root; - - break; - case MotionNotify: - gevent = gdk_event_new (GDK_MOTION_NOTIFY); - gevent->motion.type = GDK_MOTION_NOTIFY; - gevent->motion.window = g_object_ref (gdk_window); - break; - case EnterNotify: - case LeaveNotify: - gevent = gdk_event_new (xevent->type == EnterNotify ? GDK_ENTER_NOTIFY : GDK_LEAVE_NOTIFY); - gevent->crossing.window = g_object_ref (gdk_window); - gevent->crossing.x = xevent->xcrossing.x; - gevent->crossing.y = xevent->xcrossing.y; - break; - default: - g_assert_not_reached (); - break; - } - - /* If we've gotten here, we've created the gdk_event and should send it on */ - gdk_event_set_device (gevent, gdevice); - gtk_main_do_event (gevent); - gdk_event_free (gevent); - - return TRUE; -} - -typedef struct _EventFunc EventFunc; - -struct _EventFunc -{ - MetaEventFunc func; - gpointer data; -}; - -static EventFunc *ef = NULL; - -static GdkFilterReturn -filter_func (GdkXEvent *xevent, - GdkEvent *event, - gpointer data) -{ - MetaDisplay *display = (MetaDisplay*) ef->data; - - g_return_val_if_fail (ef != NULL && ef->data != NULL && display != NULL && !display->closing, GDK_FILTER_CONTINUE); - if ((* ef->func) (xevent, ef->data) || - maybe_redirect_mouse_event (display, xevent)) - return GDK_FILTER_REMOVE; - else - return GDK_FILTER_CONTINUE; -} - -LOCAL_SYMBOL void -meta_ui_add_event_func (Display *xdisplay, - MetaEventFunc func, - gpointer data) -{ - g_return_if_fail (ef == NULL); - - ef = g_new (EventFunc, 1); - ef->func = func; - ef->data = data; - - gdk_window_add_filter (NULL, filter_func, ef); -} - -/* removal is by data due to proxy function */ -LOCAL_SYMBOL void -meta_ui_remove_event_func (Display *xdisplay, - MetaEventFunc func, - gpointer data) -{ - g_return_if_fail (ef != NULL); - - gdk_window_remove_filter (NULL, filter_func, ef); - - free (ef); - ef = NULL; -} - -LOCAL_SYMBOL MetaUI* -meta_ui_new (MetaDisplay *display, - Screen *screen) -{ - GdkDisplay *gdisplay; - MetaUI *ui; + if (!gtk_init_check (NULL, NULL)) + meta_fatal ("Unable to initialize GTK"); - ui = display->ui = g_new0 (MetaUI, 1); - ui->xdisplay = display->xdisplay; - ui->xscreen = screen; + g_assert (x11_display->gdk_display == gdk_display_get_default ()); - gdisplay = display->gdk_display; - g_assert (gdisplay == gdk_display_get_default ()); + ui = g_new0 (MetaUI, 1); + ui->xdisplay = x11_display->xdisplay; - ui->frames = meta_frames_new (XScreenNumberOfScreen (screen)); + ui->frames = meta_frames_new (x11_display); /* GTK+ needs the frame-sync protocol to work in order to properly * handle style changes. This means that the dummy widget we create * to get the style for title bars actually needs to be mapped @@ -298,47 +68,25 @@ meta_ui_new (MetaDisplay *display, */ gtk_widget_show (GTK_WIDGET (ui->frames)); - g_object_set_data (G_OBJECT (gdisplay), "meta-ui", ui); + g_object_set_data (G_OBJECT (x11_display->gdk_display), "meta-ui", ui); return ui; } -LOCAL_SYMBOL void +void meta_ui_free (MetaUI *ui) { - GdkDisplay *gdisplay; + GdkDisplay *gdk_display; gtk_widget_destroy (GTK_WIDGET (ui->frames)); - gdisplay = gdk_x11_lookup_xdisplay (ui->xdisplay); - g_object_set_data (G_OBJECT (gdisplay), "meta-ui", NULL); - - free (ui); -} - -LOCAL_SYMBOL void -meta_ui_get_frame_borders (MetaUI *ui, - Window frame_xwindow, - MetaFrameBorders *borders) -{ - meta_frames_get_borders (ui->frames, frame_xwindow, - borders); -} + gdk_display = gdk_x11_lookup_xdisplay (ui->xdisplay); + g_object_set_data (G_OBJECT (gdk_display), "meta-ui", NULL); -LOCAL_SYMBOL void -meta_ui_get_corner_radiuses (MetaUI *ui, - Window xwindow, - float *top_left, - float *top_right, - float *bottom_left, - float *bottom_right) -{ - meta_frames_get_corner_radiuses (ui->frames, xwindow, - top_left, top_right, - bottom_left, bottom_right); + g_free (ui); } -LOCAL_SYMBOL void +static void set_background_none (Display *xdisplay, Window xwindow) { @@ -349,24 +97,26 @@ set_background_none (Display *xdisplay, CWBackPixmap, &attrs); } -LOCAL_SYMBOL Window -meta_ui_create_frame_window (MetaUI *ui, - Display *xdisplay, - Visual *xvisual, - gint x, - gint y, - gint width, - gint height, - gint screen_no, - gulong *create_serial) +MetaUIFrame * +meta_ui_create_frame (MetaUI *ui, + Display *xdisplay, + MetaWindow *meta_window, + Visual *xvisual, + gint x, + gint y, + gint width, + gint height, + gulong *create_serial) { GdkDisplay *display = gdk_x11_lookup_xdisplay (xdisplay); - GdkScreen *screen = gdk_display_get_screen (display, screen_no); + GdkScreen *screen; GdkWindowAttr attrs; gint attributes_mask; GdkWindow *window; GdkVisual *visual; - + + screen = gdk_display_get_default_screen (display); + /* Default depth/visual handles clients with weird visuals; they can * always be children of the root depth/visual obviously, but * e.g. DRI games can't be children of a parent that has the same @@ -382,13 +132,7 @@ meta_ui_create_frame_window (MetaUI *ui, attrs.title = NULL; - /* frame.c is going to replace the event mask immediately, but - * we still have to set it here to let GDK know what it is. - */ - attrs.event_mask = - GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | - GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_FOCUS_CHANGE_MASK; + attrs.event_mask = GDK_EXPOSURE_MASK; attrs.x = x; attrs.y = y; attrs.wclass = GDK_INPUT_OUTPUT; @@ -416,31 +160,11 @@ meta_ui_create_frame_window (MetaUI *ui, gdk_window_resize (window, width, height); set_background_none (xdisplay, GDK_WINDOW_XID (window)); - - meta_frames_manage_window (ui->frames, GDK_WINDOW_XID (window), window); - - return GDK_WINDOW_XID (window); -} - -LOCAL_SYMBOL void -meta_ui_destroy_frame_window (MetaUI *ui, - Window xwindow) -{ - meta_frames_unmanage_window (ui->frames, xwindow); -} -LOCAL_SYMBOL void -meta_ui_move_resize_frame (MetaUI *ui, - Window frame, - int x, - int y, - int width, - int height) -{ - meta_frames_move_resize_frame (ui->frames, frame, x, y, width, height); + return meta_frames_manage_window (ui->frames, meta_window, GDK_WINDOW_XID (window), window); } -LOCAL_SYMBOL void +void meta_ui_map_frame (MetaUI *ui, Window xwindow) { @@ -454,7 +178,7 @@ meta_ui_map_frame (MetaUI *ui, gdk_window_show_unraised (window); } -LOCAL_SYMBOL void +void meta_ui_unmap_frame (MetaUI *ui, Window xwindow) { @@ -468,130 +192,7 @@ meta_ui_unmap_frame (MetaUI *ui, gdk_window_hide (window); } -LOCAL_SYMBOL void -meta_ui_update_frame_style (MetaUI *ui, - Window xwindow) -{ - meta_frames_update_frame_style (ui->frames, xwindow); -} - -LOCAL_SYMBOL void -meta_ui_repaint_frame (MetaUI *ui, - Window xwindow) -{ - meta_frames_repaint_frame (ui->frames, xwindow); -} - -LOCAL_SYMBOL cairo_region_t * -meta_ui_get_frame_bounds (MetaUI *ui, - Window xwindow, - int window_width, - int window_height) -{ - return meta_frames_get_frame_bounds (ui->frames, xwindow, - window_width, window_height); -} - -LOCAL_SYMBOL void -meta_ui_queue_frame_draw (MetaUI *ui, - Window xwindow) -{ - meta_frames_queue_draw (ui->frames, xwindow); -} - -LOCAL_SYMBOL void -meta_ui_set_frame_title (MetaUI *ui, - Window xwindow, - const char *title) -{ - meta_frames_set_title (ui->frames, xwindow, title); -} - -LOCAL_SYMBOL MetaWindowMenu* -meta_ui_window_menu_new (MetaUI *ui, - Window client_xwindow, - MetaMenuOp ops, - MetaMenuOp insensitive, - unsigned long active_workspace, - int n_workspaces, - MetaWindowMenuFunc func, - gpointer data) -{ - return meta_window_menu_new (ui->frames, - ops, insensitive, - client_xwindow, - active_workspace, - n_workspaces, - func, data); -} - -LOCAL_SYMBOL void -meta_ui_window_menu_popup (MetaWindowMenu *menu, - int root_x, - int root_y, - int button, - guint32 timestamp) -{ - meta_window_menu_popup (menu, root_x, root_y, button, timestamp); -} - -LOCAL_SYMBOL void -meta_ui_window_menu_free (MetaWindowMenu *menu) -{ - meta_window_menu_free (menu); -} - -LOCAL_SYMBOL GdkPixbuf* -meta_gdk_pixbuf_get_from_pixmap (Pixmap xpixmap, - int src_x, - int src_y, - int width, - int height) -{ - cairo_surface_t *surface; - Display *display; - Window root_return; - int x_ret, y_ret; - unsigned int w_ret, h_ret, bw_ret, depth_ret; - XWindowAttributes attrs; - GdkPixbuf *retval; - - display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); - - if (!XGetGeometry (display, xpixmap, &root_return, - &x_ret, &y_ret, &w_ret, &h_ret, &bw_ret, &depth_ret)) - return NULL; - - if (depth_ret == 1) - { - surface = cairo_xlib_surface_create_for_bitmap (display, - xpixmap, - GDK_SCREEN_XSCREEN (gdk_screen_get_default ()), - w_ret, - h_ret); - } - else - { - if (!XGetWindowAttributes (display, root_return, &attrs)) - return NULL; - - surface = cairo_xlib_surface_create (display, - xpixmap, - attrs.visual, - w_ret, h_ret); - } - - retval = gdk_pixbuf_get_from_surface (surface, - src_x, - src_y, - width, - height); - cairo_surface_destroy (surface); - - return retval; -} - -LOCAL_SYMBOL gboolean +gboolean meta_ui_window_should_not_cause_focus (Display *xdisplay, Window xwindow) { @@ -610,286 +211,48 @@ meta_ui_window_should_not_cause_focus (Display *xdisplay, return FALSE; } -LOCAL_SYMBOL char* -meta_text_property_to_utf8 (Display *xdisplay, - const XTextProperty *prop) -{ - GdkDisplay *display; - char **list; - int count; - char *retval; - - list = NULL; - - display = gdk_x11_lookup_xdisplay (xdisplay); - count = gdk_text_property_to_utf8_list_for_display (display, - gdk_x11_xatom_to_atom_for_display (display, prop->encoding), - prop->format, - prop->value, - prop->nitems, - &list); - - if (count == 0) - retval = NULL; - else - { - retval = list[0]; - list[0] = g_strdup (""); /* something to free */ - } - - g_strfreev (list); - - return retval; -} - -LOCAL_SYMBOL void +void meta_ui_theme_get_frame_borders (MetaUI *ui, MetaFrameType type, MetaFrameFlags flags, MetaFrameBorders *borders) { + GdkDisplay *display; + GdkScreen *screen; int text_height; - GtkStyleContext *style = NULL; + MetaStyleInfo *style_info = NULL; PangoContext *context; const PangoFontDescription *font_desc; PangoFontDescription *free_font_desc = NULL; - if (meta_ui_have_a_theme ()) - { - context = gtk_widget_get_pango_context (GTK_WIDGET (ui->frames)); - font_desc = meta_prefs_get_titlebar_font (); - - if (!font_desc) - { - style = gtk_style_context_new (); - gtk_style_context_get (style, GTK_STATE_FLAG_NORMAL, - GTK_STYLE_PROPERTY_FONT, &free_font_desc, - NULL); - font_desc = (const PangoFontDescription *) free_font_desc; - } - - text_height = meta_pango_font_desc_get_text_height (font_desc, context); - - meta_theme_get_frame_borders (meta_theme_get_current (), - type, text_height, flags, - borders); - - if (free_font_desc) - pango_font_description_free (free_font_desc); - } - else - { - meta_frame_borders_clear (borders); - } - - if (style != NULL) - g_object_unref (style); -} - -LOCAL_SYMBOL void -meta_ui_set_current_theme (const char *name, - gboolean force_reload) -{ - meta_theme_set_current (name, force_reload); -} - -LOCAL_SYMBOL gboolean -meta_ui_have_a_theme (void) -{ - return meta_theme_get_current () != NULL; -} - -static void -meta_ui_accelerator_parse (const char *accel, - guint *keysym, - guint *keycode, - GdkModifierType *keymask) -{ - const char *above_tab; - - if (accel[0] == '0' && accel[1] == 'x') - { - *keysym = 0; - *keycode = (guint) strtoul (accel, NULL, 16); - *keymask = 0; - - return; - } - - /* The key name 'Above_Tab' is special - it's not an actual keysym name, - * but rather refers to the key above the tab key. In order to use - * the GDK parsing for modifiers in combination with it, we substitute - * it with 'Tab' temporarily before calling gtk_accelerator_parse(). - */ -#define is_word_character(c) (g_ascii_isalnum(c) || ((c) == '_')) -#define ABOVE_TAB "Above_Tab" -#define ABOVE_TAB_LEN 9 - - above_tab = strstr (accel, ABOVE_TAB); - if (above_tab && - (above_tab == accel || !is_word_character (above_tab[-1])) && - !is_word_character (above_tab[ABOVE_TAB_LEN])) - { - char *before = g_strndup (accel, above_tab - accel); - char *after = g_strdup (above_tab + ABOVE_TAB_LEN); - char *replaced = g_strconcat (before, "Tab", after, NULL); - - gtk_accelerator_parse (replaced, NULL, keymask); - - free (before); - free (after); - free (replaced); - - *keysym = META_KEY_ABOVE_TAB; - return; - } - -#undef is_word_character -#undef ABOVE_TAB -#undef ABOVE_TAB_LEN + display = gdk_x11_lookup_xdisplay (ui->xdisplay); + screen = gdk_display_get_default_screen (display); - gtk_accelerator_parse (accel, keysym, keymask); -} + style_info = meta_theme_create_style_info (screen, NULL); -LOCAL_SYMBOL gboolean -meta_ui_parse_accelerator (const char *accel, - unsigned int *keysym, - unsigned int *keycode, - MetaVirtualModifier *mask) -{ - GdkModifierType gdk_mask = 0; - guint gdk_sym = 0; - guint gdk_code = 0; - - *keysym = 0; - *keycode = 0; - *mask = 0; - - if (!accel[0] || strcmp (accel, "disabled") == 0) - return TRUE; - - meta_ui_accelerator_parse (accel, &gdk_sym, &gdk_code, &gdk_mask); - if (gdk_mask == 0 && gdk_sym == 0 && gdk_code == 0) - return FALSE; - - if (gdk_sym == None && gdk_code == 0) - return FALSE; - - if (gdk_mask & GDK_RELEASE_MASK) /* we don't allow this */ - return FALSE; - - *keysym = gdk_sym; - *keycode = gdk_code; - - if (gdk_mask & GDK_SHIFT_MASK) - *mask |= META_VIRTUAL_SHIFT_MASK; - if (gdk_mask & GDK_CONTROL_MASK) - *mask |= META_VIRTUAL_CONTROL_MASK; - if (gdk_mask & GDK_MOD1_MASK) - *mask |= META_VIRTUAL_ALT_MASK; - if (gdk_mask & GDK_MOD2_MASK) - *mask |= META_VIRTUAL_MOD2_MASK; - if (gdk_mask & GDK_MOD3_MASK) - *mask |= META_VIRTUAL_MOD3_MASK; - if (gdk_mask & GDK_MOD4_MASK) - *mask |= META_VIRTUAL_MOD4_MASK; - if (gdk_mask & GDK_MOD5_MASK) - *mask |= META_VIRTUAL_MOD5_MASK; - if (gdk_mask & GDK_SUPER_MASK) - *mask |= META_VIRTUAL_SUPER_MASK; - if (gdk_mask & GDK_HYPER_MASK) - *mask |= META_VIRTUAL_HYPER_MASK; - if (gdk_mask & GDK_META_MASK) - *mask |= META_VIRTUAL_META_MASK; - - return TRUE; -} + context = gtk_widget_get_pango_context (GTK_WIDGET (ui->frames)); + font_desc = meta_prefs_get_titlebar_font (); -/* Caller responsible for freeing return string of meta_ui_accelerator_name! */ -LOCAL_SYMBOL gchar* -meta_ui_accelerator_name (unsigned int keysym, - MetaVirtualModifier mask) -{ - GdkModifierType mods = 0; - - if (keysym == 0 && mask == 0) + if (!font_desc) { - return g_strdup ("disabled"); + free_font_desc = meta_style_info_create_font_desc (style_info); + font_desc = (const PangoFontDescription *) free_font_desc; } - if (mask & META_VIRTUAL_SHIFT_MASK) - mods |= GDK_SHIFT_MASK; - if (mask & META_VIRTUAL_CONTROL_MASK) - mods |= GDK_CONTROL_MASK; - if (mask & META_VIRTUAL_ALT_MASK) - mods |= GDK_MOD1_MASK; - if (mask & META_VIRTUAL_MOD2_MASK) - mods |= GDK_MOD2_MASK; - if (mask & META_VIRTUAL_MOD3_MASK) - mods |= GDK_MOD3_MASK; - if (mask & META_VIRTUAL_MOD4_MASK) - mods |= GDK_MOD4_MASK; - if (mask & META_VIRTUAL_MOD5_MASK) - mods |= GDK_MOD5_MASK; - if (mask & META_VIRTUAL_SUPER_MASK) - mods |= GDK_SUPER_MASK; - if (mask & META_VIRTUAL_HYPER_MASK) - mods |= GDK_HYPER_MASK; - if (mask & META_VIRTUAL_META_MASK) - mods |= GDK_META_MASK; - - return gtk_accelerator_name (keysym, mods); - -} - -LOCAL_SYMBOL gboolean -meta_ui_parse_modifier (const char *accel, - MetaVirtualModifier *mask) -{ - GdkModifierType gdk_mask = 0; - guint gdk_sym = 0; - guint gdk_code = 0; - - *mask = 0; + text_height = meta_pango_font_desc_get_text_height (font_desc, context); - if (accel == NULL || !accel[0] || strcmp (accel, "disabled") == 0) - return TRUE; - - meta_ui_accelerator_parse (accel, &gdk_sym, &gdk_code, &gdk_mask); - if (gdk_mask == 0 && gdk_sym == 0 && gdk_code == 0) - return FALSE; + meta_theme_get_frame_borders (meta_theme_get_default (), + style_info, type, text_height, flags, + borders); - if (gdk_sym != None || gdk_code != 0) - return FALSE; - - if (gdk_mask & GDK_RELEASE_MASK) /* we don't allow this */ - return FALSE; + if (free_font_desc) + pango_font_description_free (free_font_desc); - if (gdk_mask & GDK_SHIFT_MASK) - *mask |= META_VIRTUAL_SHIFT_MASK; - if (gdk_mask & GDK_CONTROL_MASK) - *mask |= META_VIRTUAL_CONTROL_MASK; - if (gdk_mask & GDK_MOD1_MASK) - *mask |= META_VIRTUAL_ALT_MASK; - if (gdk_mask & GDK_MOD2_MASK) - *mask |= META_VIRTUAL_MOD2_MASK; - if (gdk_mask & GDK_MOD3_MASK) - *mask |= META_VIRTUAL_MOD3_MASK; - if (gdk_mask & GDK_MOD4_MASK) - *mask |= META_VIRTUAL_MOD4_MASK; - if (gdk_mask & GDK_MOD5_MASK) - *mask |= META_VIRTUAL_MOD5_MASK; - if (gdk_mask & GDK_SUPER_MASK) - *mask |= META_VIRTUAL_SUPER_MASK; - if (gdk_mask & GDK_HYPER_MASK) - *mask |= META_VIRTUAL_HYPER_MASK; - if (gdk_mask & GDK_META_MASK) - *mask |= META_VIRTUAL_META_MASK; - - return TRUE; + if (style_info != NULL) + meta_style_info_unref (style_info); } -LOCAL_SYMBOL gboolean +gboolean meta_ui_window_is_widget (MetaUI *ui, Window xwindow) { @@ -909,54 +272,10 @@ meta_ui_window_is_widget (MetaUI *ui, return FALSE; } -/* stock icon code Copyright (C) 2002 Jorn Baayen <jorn@nl.linux.org> */ -typedef struct -{ - char *stock_id; - const guint8 *icon_data; -} MetaStockIcon; - -static void -meta_stock_icons_init (void) +gboolean +meta_ui_window_is_dummy (MetaUI *ui, + Window xwindow) { - GtkIconFactory *factory; - int i; - - MetaStockIcon items[] = - { - { METACITY_STOCK_DELETE, stock_delete_data }, - { METACITY_STOCK_MINIMIZE, stock_minimize_data }, - { METACITY_STOCK_MAXIMIZE, stock_maximize_data } - }; - - factory = gtk_icon_factory_new (); - gtk_icon_factory_add_default (factory); - - for (i = 0; i < (gint) G_N_ELEMENTS (items); i++) - { - GtkIconSet *icon_set; - GdkPixbuf *pixbuf; - - pixbuf = gdk_pixbuf_new_from_inline (-1, items[i].icon_data, - FALSE, - NULL); - - icon_set = gtk_icon_set_new_from_pixbuf (pixbuf); - gtk_icon_factory_add (factory, items[i].stock_id, icon_set); - gtk_icon_set_unref (icon_set); - - g_object_unref (G_OBJECT (pixbuf)); - } - - g_object_unref (G_OBJECT (factory)); + GdkWindow *frames_window = gtk_widget_get_window (GTK_WIDGET (ui->frames)); + return xwindow == gdk_x11_window_get_xid (frames_window); } - -LOCAL_SYMBOL MetaUIDirection -meta_ui_get_direction (void) -{ - if (gtk_widget_get_default_direction() == GTK_TEXT_DIR_RTL) - return META_UI_DIRECTION_RTL; - - return META_UI_DIRECTION_LTR; -} - diff --git a/src/ui/ui.h b/src/ui/ui.h index c89f0f28a..e7a00e4e6 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -1,10 +1,10 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* Muffin interface for talking to GTK+ UI module */ +/* Mutter interface for talking to GTK+ UI module */ -/* +/* * Copyright (C) 2001 Havoc Pennington - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the @@ -14,68 +14,45 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_UI_H #define META_UI_H -/* Don't include gtk.h or gdk.h here */ -#include <meta/common.h> -#include <meta/display.h> #include <X11/Xlib.h> #include <X11/Xutil.h> #include <cairo.h> -#include <glib.h> #include <gdk-pixbuf/gdk-pixbuf.h> +#include <glib.h> + +#include "core/util-private.h" +#include "meta/types.h" typedef struct _MetaUI MetaUI; +typedef struct _MetaUIFrame MetaUIFrame; typedef gboolean (* MetaEventFunc) (XEvent *xevent, gpointer data); -typedef enum -{ - META_UI_DIRECTION_LTR, - META_UI_DIRECTION_RTL -} MetaUIDirection; - -void meta_ui_init (void); - -Display* meta_ui_get_display (void); - -void meta_ui_add_event_func (Display *xdisplay, - MetaEventFunc func, - gpointer data); -void meta_ui_remove_event_func (Display *xdisplay, - MetaEventFunc func, - gpointer data); - -MetaUI* meta_ui_new (MetaDisplay *display, - Screen *screen); +MetaUI *meta_ui_new (MetaX11Display *x11_display); void meta_ui_free (MetaUI *ui); void meta_ui_theme_get_frame_borders (MetaUI *ui, MetaFrameType type, MetaFrameFlags flags, MetaFrameBorders *borders); -void meta_ui_get_frame_borders (MetaUI *ui, - Window frame_xwindow, - MetaFrameBorders *borders); -Window meta_ui_create_frame_window (MetaUI *ui, + +MetaUIFrame * meta_ui_create_frame (MetaUI *ui, Display *xdisplay, + MetaWindow *meta_window, Visual *xvisual, - gint x, - gint y, - gint width, - gint height, - gint screen_no, + gint x, + gint y, + gint width, + gint height, gulong *create_serial); -void meta_ui_destroy_frame_window (MetaUI *ui, - Window xwindow); void meta_ui_move_resize_frame (MetaUI *ui, Window frame, int x, @@ -89,83 +66,14 @@ void meta_ui_map_frame (MetaUI *ui, void meta_ui_unmap_frame (MetaUI *ui, Window xwindow); -cairo_region_t *meta_ui_get_frame_bounds (MetaUI *ui, - Window xwindow, - int window_width, - int window_height); - -void meta_ui_get_corner_radiuses (MetaUI *ui, - Window xwindow, - float *top_left, - float *top_right, - float *bottom_left, - float *bottom_right); - -void meta_ui_queue_frame_draw (MetaUI *ui, - Window xwindow); - -void meta_ui_set_frame_title (MetaUI *ui, - Window xwindow, - const char *title); - -void meta_ui_update_frame_style (MetaUI *ui, - Window window); - -void meta_ui_repaint_frame (MetaUI *ui, - Window xwindow); - -MetaWindowMenu* meta_ui_window_menu_new (MetaUI *ui, - Window client_xwindow, - MetaMenuOp ops, - MetaMenuOp insensitive, - unsigned long active_workspace, - int n_workspaces, - MetaWindowMenuFunc func, - gpointer data); -void meta_ui_window_menu_popup (MetaWindowMenu *menu, - int root_x, - int root_y, - int button, - guint32 timestamp); -void meta_ui_window_menu_free (MetaWindowMenu *menu); - - -/* FIXME these lack a display arg */ -GdkPixbuf* meta_gdk_pixbuf_get_from_pixmap (Pixmap xpixmap, - int src_x, - int src_y, - int width, - int height); - gboolean meta_ui_window_should_not_cause_focus (Display *xdisplay, Window xwindow); -char* meta_text_property_to_utf8 (Display *xdisplay, - const XTextProperty *prop); - -void meta_ui_set_current_theme (const char *name, - gboolean force_reload); -gboolean meta_ui_have_a_theme (void); - -/* Not a real key symbol but means "key above the tab key"; this is - * used as the default keybinding for cycle_group. - * 0x2xxxxxxx is a range not used by GDK or X. the remaining digits are - * randomly chosen */ -#define META_KEY_ABOVE_TAB 0x2f7259c9 - -gboolean meta_ui_parse_accelerator (const char *accel, - unsigned int *keysym, - unsigned int *keycode, - MetaVirtualModifier *mask); -gboolean meta_ui_parse_modifier (const char *accel, - MetaVirtualModifier *mask); - -/* Caller responsible for freeing return string of meta_ui_accelerator_name! */ -gchar* meta_ui_accelerator_name (unsigned int keysym, - MetaVirtualModifier mask); gboolean meta_ui_window_is_widget (MetaUI *ui, Window xwindow); -MetaUIDirection meta_ui_get_direction (void); +META_EXPORT_TEST +gboolean meta_ui_window_is_dummy (MetaUI *ui, + Window xwindow); #endif diff --git a/src/wayland/meta-cursor-sprite-wayland.c b/src/wayland/meta-cursor-sprite-wayland.c new file mode 100644 index 000000000..7c14960ff --- /dev/null +++ b/src/wayland/meta-cursor-sprite-wayland.c @@ -0,0 +1,75 @@ +/* + * Copyright 2015, 2018 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include "wayland/meta-cursor-sprite-wayland.h" + +struct _MetaCursorSpriteWayland +{ + MetaCursorSprite parent; + + MetaWaylandSurface *surface; +}; + +G_DEFINE_TYPE (MetaCursorSpriteWayland, + meta_cursor_sprite_wayland, + META_TYPE_CURSOR_SPRITE) + +static void +meta_cursor_sprite_wayland_realize_texture (MetaCursorSprite *sprite) +{ +} + +static gboolean +meta_cursor_sprite_wayland_is_animated (MetaCursorSprite *sprite) +{ + return FALSE; +} + +MetaCursorSpriteWayland * +meta_cursor_sprite_wayland_new (MetaWaylandSurface *surface) +{ + MetaCursorSpriteWayland *sprite_wayland; + + sprite_wayland = g_object_new (META_TYPE_CURSOR_SPRITE_WAYLAND, NULL); + sprite_wayland->surface = surface; + + return sprite_wayland; +} + +MetaWaylandBuffer * +meta_cursor_sprite_wayland_get_buffer (MetaCursorSpriteWayland *sprite_wayland) +{ + return meta_wayland_surface_get_buffer (sprite_wayland->surface); +} + +static void +meta_cursor_sprite_wayland_init (MetaCursorSpriteWayland *sprite_wayland) +{ +} + +static void +meta_cursor_sprite_wayland_class_init (MetaCursorSpriteWaylandClass *klass) +{ + MetaCursorSpriteClass *cursor_sprite_class = META_CURSOR_SPRITE_CLASS (klass); + + cursor_sprite_class->realize_texture = + meta_cursor_sprite_wayland_realize_texture; + cursor_sprite_class->is_animated = meta_cursor_sprite_wayland_is_animated; +} diff --git a/src/wayland/meta-cursor-sprite-wayland.h b/src/wayland/meta-cursor-sprite-wayland.h new file mode 100644 index 000000000..107698f3f --- /dev/null +++ b/src/wayland/meta-cursor-sprite-wayland.h @@ -0,0 +1,35 @@ +/* + * Copyright 2013, 2018 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + */ + +#ifndef META_CURSOR_SPRITE_WAYLAND_H +#define META_CURSOR_SPRITE_WAYLAND_H + +#include <glib-object.h> + +#include "backends/meta-cursor.h" +#include "wayland/meta-wayland-surface.h" + +#define META_TYPE_CURSOR_SPRITE_WAYLAND meta_cursor_sprite_wayland_get_type () +G_DECLARE_FINAL_TYPE (MetaCursorSpriteWayland, meta_cursor_sprite_wayland, + META, CURSOR_SPRITE_WAYLAND, MetaCursorSprite) + +MetaCursorSpriteWayland * meta_cursor_sprite_wayland_new (MetaWaylandSurface *surface); + +MetaWaylandBuffer * meta_cursor_sprite_wayland_get_buffer (MetaCursorSpriteWayland *sprite_wayland); + +#endif /* META_CURSOR_SPRITE_WAYLAND_H */ diff --git a/src/wayland/meta-pointer-confinement-wayland.c b/src/wayland/meta-pointer-confinement-wayland.c new file mode 100644 index 000000000..7f980054c --- /dev/null +++ b/src/wayland/meta-pointer-confinement-wayland.c @@ -0,0 +1,738 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2015 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +/** + * SECTION:meta-pointer-confinement-wayland + * @title: MetaPointerConfinementWayland + * @short_description: A #MetaPointerConstraint implementing pointer confinement + * + * A MetaPointerConfinementConstraint implements the client pointer constraint + * "pointer confinement": the cursor should not be able to "break out" of a + * certain area defined by the client requesting it. + */ + +#include "config.h" + +#include "wayland/meta-pointer-confinement-wayland.h" + +#include <glib-object.h> +#include <cairo.h> + +#include "backends/meta-backend-private.h" +#include "backends/meta-pointer-constraint.h" +#include "compositor/meta-surface-actor-wayland.h" +#include "core/meta-border.h" +#include "wayland/meta-wayland-pointer-constraints.h" +#include "wayland/meta-wayland-pointer.h" +#include "wayland/meta-wayland-seat.h" +#include "wayland/meta-wayland-surface.h" + +struct _MetaPointerConfinementWayland +{ + MetaPointerConstraint parent; + + MetaWaylandPointerConstraint *constraint; +}; + +typedef struct _MetaBox +{ + int x1; + int y1; + int x2; + int y2; +} MetaBox; + +G_DEFINE_TYPE (MetaPointerConfinementWayland, meta_pointer_confinement_wayland, + META_TYPE_POINTER_CONSTRAINT); + +static MetaBorder * +add_border (GArray *borders, + float x1, float y1, + float x2, float y2, + MetaBorderMotionDirection blocking_directions) +{ + MetaBorder border; + + border = (MetaBorder) { + .line = (MetaLine2) { + .a = (MetaVector2) { + .x = x1, + .y = y1, + }, + .b = (MetaVector2) { + .x = x2, + .y = y2, + }, + }, + .blocking_directions = blocking_directions, + }; + + g_array_append_val (borders, border); + + return &g_array_index (borders, MetaBorder, borders->len - 1); +} + +static gint +compare_lines_x (gconstpointer a, gconstpointer b) +{ + const MetaBorder *border_a = a; + const MetaBorder *border_b = b; + + if (border_a->line.a.x == border_b->line.a.x) + return border_a->line.b.x < border_b->line.b.x; + else + return border_a->line.a.x > border_b->line.a.x; +} + +static void +add_non_overlapping_edges (MetaBox *boxes, + unsigned int band_above_start, + unsigned int band_below_start, + unsigned int band_below_end, + GArray *borders) +{ + unsigned int i; + GArray *band_merge; + MetaBorder *border; + MetaBorder *prev_border; + MetaBorder *new_border; + + band_merge = g_array_new (FALSE, FALSE, sizeof *border); + + /* Add bottom band of previous row, and top band of current row, and + * sort them so lower left x coordinate comes first. If there are two + * borders with the same left x coordinate, the wider one comes first. + */ + for (i = band_above_start; i < band_below_start; i++) + { + MetaBox *box = &boxes[i]; + add_border (band_merge, box->x1, box->y2, box->x2, box->y2, + META_BORDER_MOTION_DIRECTION_POSITIVE_Y); + } + for (i = band_below_start; i < band_below_end; i++) + { + MetaBox *box= &boxes[i]; + add_border (band_merge, box->x1, box->y1, box->x2, box->y1, + META_BORDER_MOTION_DIRECTION_NEGATIVE_Y); + } + g_array_sort (band_merge, compare_lines_x); + + /* Combine the two combined bands so that any overlapping border is + * eliminated. */ + prev_border = NULL; + for (i = 0; i < band_merge->len; i++) + { + border = &g_array_index (band_merge, MetaBorder, i); + + g_assert (border->line.a.y == border->line.b.y); + g_assert (!prev_border || + prev_border->line.a.y == border->line.a.y); + g_assert (!prev_border || + (prev_border->line.a.x != border->line.a.x || + prev_border->line.b.x != border->line.b.x)); + g_assert (!prev_border || + prev_border->line.a.x <= border->line.a.x); + + if (prev_border && + prev_border->line.a.x == border->line.a.x) + { + /* + * ------------ + + * ------- = + * [ ]----- + */ + prev_border->line.a.x = border->line.b.x; + } + else if (prev_border && + prev_border->line.b.x == border->line.b.x) + { + /* + * ------------ + + * ------ = + * ------[ ] + */ + prev_border->line.b.x = border->line.a.x; + } + else if (prev_border && + prev_border->line.b.x == border->line.a.x) + { + /* + * -------- + + * ------ = + * -------------- + */ + prev_border->line.b.x = border->line.b.x; + } + else if (prev_border && + prev_border->line.b.x >= border->line.a.x) + { + /* + * --------------- + + * ------ = + * -----[ ]---- + */ + new_border = add_border (borders, + border->line.b.x, + border->line.b.y, + prev_border->line.b.x, + prev_border->line.b.y, + prev_border->blocking_directions); + prev_border->line.b.x = border->line.a.x; + prev_border = new_border; + } + else + { + g_assert (!prev_border || + prev_border->line.b.x < border->line.a.x); + /* + * First border or non-overlapping. + * + * ----- + + * ----- = + * ----- ----- + */ + g_array_append_val (borders, *border); + prev_border = &g_array_index (borders, MetaBorder, borders->len - 1); + } + } + + g_array_free (band_merge, FALSE); +} + +static void +add_band_bottom_edges (MetaBox *boxes, + int band_start, + int band_end, + GArray *borders) +{ + int i; + + for (i = band_start; i < band_end; i++) + { + add_border (borders, + boxes[i].x1, boxes[i].y2, + boxes[i].x2, boxes[i].y2, + META_BORDER_MOTION_DIRECTION_POSITIVE_Y); + } +} + +static void +region_to_outline (cairo_region_t *region, + GArray *borders) +{ + MetaBox *boxes; + int num_boxes; + int i; + int top_most, bottom_most; + int current_roof; + int prev_top; + int band_start, prev_band_start; + + /* + * Remove any overlapping lines from the set of rectangles. Note that + * pixman regions are grouped as rows of rectangles, where rectangles + * in one row never touch or overlap and are all of the same height. + * + * -------- --- -------- --- + * | | | | | | | | + * ----------====---- --- ----------- ----- --- + * | | => | | + * ----==========--------- ----- ---------- + * | | | | + * ------------------- ------------------- + * + */ + + num_boxes = cairo_region_num_rectangles (region); + boxes = g_new (MetaBox, num_boxes); + for (i = 0; i < num_boxes; i++) + { + cairo_rectangle_int_t rect; + cairo_region_get_rectangle (region, i, &rect); + boxes[i] = (MetaBox) { + .x1 = rect.x, + .y1 = rect.y, + .x2 = rect.x + rect.width, + .y2 = rect.y + rect.height, + }; + } + prev_top = 0; + top_most = boxes[0].y1; + current_roof = top_most; + bottom_most = boxes[num_boxes - 1].y2; + band_start = 0; + prev_band_start = 0; + for (i = 0; i < num_boxes; i++) + { + /* Detect if there is a vertical empty space, and add the lower + * level of the previous band if so was the case. */ + if (i > 0 && + boxes[i].y1 != prev_top && + boxes[i].y1 != boxes[i - 1].y2) + { + current_roof = boxes[i].y1; + add_band_bottom_edges (boxes, + band_start, + i, + borders); + } + + /* Special case adding the last band, since it won't be handled + * by the band change detection below. */ + if (boxes[i].y1 != current_roof && i == num_boxes - 1) + { + if (boxes[i].y1 != prev_top) + { + /* The last band is a single box, so we don't + * have a prev_band_start to tell us when the + * previous band started. */ + add_non_overlapping_edges (boxes, + band_start, + i, + i + 1, + borders); + } + else + { + add_non_overlapping_edges (boxes, + prev_band_start, + band_start, + i + 1, + borders); + } + } + + /* Detect when passing a band and combine the top border of the + * just passed band with the bottom band of the previous band. + */ + if (boxes[i].y1 != top_most && boxes[i].y1 != prev_top) + { + /* Combine the two passed bands. */ + if (prev_top != current_roof) + { + add_non_overlapping_edges (boxes, + prev_band_start, + band_start, + i, + borders); + } + + prev_band_start = band_start; + band_start = i; + } + + /* Add the top border if the box is part of the current roof. */ + if (boxes[i].y1 == current_roof) + { + add_border (borders, + boxes[i].x1, boxes[i].y1, + boxes[i].x2, boxes[i].y1, + META_BORDER_MOTION_DIRECTION_NEGATIVE_Y); + } + + /* Add the bottom border of the last band. */ + if (boxes[i].y2 == bottom_most) + { + add_border (borders, + boxes[i].x1, boxes[i].y2, + boxes[i].x2, boxes[i].y2, + META_BORDER_MOTION_DIRECTION_POSITIVE_Y); + } + + /* Always add the left border. */ + add_border (borders, + boxes[i].x1, boxes[i].y1, + boxes[i].x1, boxes[i].y2, + META_BORDER_MOTION_DIRECTION_NEGATIVE_X); + + /* Always add the right border. */ + add_border (borders, + boxes[i].x2, boxes[i].y1, + boxes[i].x2, boxes[i].y2, + META_BORDER_MOTION_DIRECTION_POSITIVE_X); + + prev_top = boxes[i].y1; + } + + g_free (boxes); +} + +static MetaBorder * +get_closest_border (GArray *borders, + MetaLine2 *motion, + uint32_t directions) +{ + MetaBorder *border; + MetaVector2 intersection; + MetaVector2 delta; + float distance_2; + MetaBorder *closest_border = NULL; + float closest_distance_2 = DBL_MAX; + unsigned int i; + + for (i = 0; i < borders->len; i++) + { + border = &g_array_index (borders, MetaBorder, i); + + if (!meta_border_is_blocking_directions (border, directions)) + continue; + + if (!meta_line2_intersects_with (&border->line, motion, &intersection)) + continue; + + delta = meta_vector2_subtract (intersection, motion->a); + distance_2 = delta.x*delta.x + delta.y*delta.y; + if (distance_2 < closest_distance_2) + { + closest_border = border; + closest_distance_2 = distance_2; + } + } + + return closest_border; +} + +static void +clamp_to_border (MetaBorder *border, + MetaLine2 *motion, + uint32_t *motion_dir) +{ + /* + * When clamping either rightward or downward motions, the motion needs to be + * clamped so that the destination coordinate does not end up on the border + * (see weston_pointer_clamp_event_to_region). Do this by clamping such + * motions to the border minus the smallest possible wl_fixed_t value. + * + * When clamping in either leftward or upward motion, the resulting coordinate + * needs to be clamped so that it is enough on the inside to avoid the + * inaccuracies of clutter's stage to actor transformation algorithm (the one + * used in clutter_actor_transform_stage_point) to make it end up outside the + * next motion. It also needs to be clamped so that to the wl_fixed_t + * coordinate may still be right on the border (i.e. at .0). Testing shows + * that the smallest wl_fixed_t value divided by 10 is small enough to make + * the wl_fixed_t coordinate .0 and large enough to avoid the inaccuracies of + * clutters transform algorithm. + */ + if (meta_border_is_horizontal (border)) + { + if (*motion_dir & META_BORDER_MOTION_DIRECTION_POSITIVE_Y) + motion->b.y = border->line.a.y - wl_fixed_to_double (1); + else + motion->b.y = border->line.a.y + wl_fixed_to_double (1) / 10; + *motion_dir &= ~(META_BORDER_MOTION_DIRECTION_POSITIVE_Y | + META_BORDER_MOTION_DIRECTION_NEGATIVE_Y); + } + else + { + if (*motion_dir & META_BORDER_MOTION_DIRECTION_POSITIVE_X) + motion->b.x = border->line.a.x - wl_fixed_to_double (1); + else + motion->b.x = border->line.a.x + wl_fixed_to_double (1) / 10; + *motion_dir &= ~(META_BORDER_MOTION_DIRECTION_POSITIVE_X | + META_BORDER_MOTION_DIRECTION_NEGATIVE_X); + } +} + +static uint32_t +get_motion_directions (MetaLine2 *motion) +{ + uint32_t directions = 0; + + if (motion->a.x < motion->b.x) + directions |= META_BORDER_MOTION_DIRECTION_POSITIVE_X; + else if (motion->a.x > motion->b.x) + directions |= META_BORDER_MOTION_DIRECTION_NEGATIVE_X; + if (motion->a.y < motion->b.y) + directions |= META_BORDER_MOTION_DIRECTION_POSITIVE_Y; + else if (motion->a.y > motion->b.y) + directions |= META_BORDER_MOTION_DIRECTION_NEGATIVE_Y; + + return directions; +} + +static void +meta_pointer_confinement_wayland_constrain (MetaPointerConstraint *constraint, + ClutterInputDevice *device, + guint32 time, + float prev_x, + float prev_y, + float *x, + float *y) +{ + MetaPointerConfinementWayland *self = + META_POINTER_CONFINEMENT_WAYLAND (constraint); + MetaWaylandSurface *surface; + cairo_region_t *region; + float sx, sy; + float prev_sx, prev_sy; + GArray *borders; + MetaLine2 motion; + MetaBorder *closest_border; + uint32_t directions; + + surface = meta_wayland_pointer_constraint_get_surface (self->constraint); + + meta_wayland_surface_get_relative_coordinates (surface, *x, *y, &sx, &sy); + meta_wayland_surface_get_relative_coordinates (surface, prev_x, prev_y, + &prev_sx, &prev_sy); + + /* For motions in a positive direction on any axis, append the smallest + * possible value representable in a Wayland absolute coordinate. This is + * in order to avoid not clamping motion that as a floating point number + * won't be clamped, but will be rounded up to be outside of the range + * of wl_fixed_t. */ + if (sx > prev_sx) + sx += (float)wl_fixed_to_double(1); + if (sy > prev_sy) + sy += (float)wl_fixed_to_double(1); + + borders = g_array_new (FALSE, FALSE, sizeof (MetaBorder)); + + /* + * Generate borders given the confine region we are to use. The borders + * are defined to be the outer region of the allowed area. This means + * top/left borders are "within" the allowed area, while bottom/right + * borders are outside. This needs to be considered when clamping + * confined motion vectors. + */ + region = + meta_wayland_pointer_constraint_calculate_effective_region (self->constraint); + region_to_outline (region, borders); + cairo_region_destroy (region); + + motion = (MetaLine2) { + .a = (MetaVector2) { + .x = prev_sx, + .y = prev_sy, + }, + .b = (MetaVector2) { + .x = sx, + .y = sy, + }, + }; + directions = get_motion_directions (&motion); + + while (directions) + { + closest_border = get_closest_border (borders, + &motion, + directions); + if (closest_border) + clamp_to_border (closest_border, &motion, &directions); + else + break; + } + + meta_wayland_surface_get_absolute_coordinates (surface, + motion.b.x, motion.b.y, + x, y); + + g_array_free (borders, FALSE); +} + +static float +point_to_border_distance_2 (MetaBorder *border, + float x, + float y) +{ + float orig_x, orig_y; + float dx, dy; + + if (meta_border_is_horizontal (border)) + { + if (x < border->line.a.x) + orig_x = border->line.a.x; + else if (x > border->line.b.x) + orig_x = border->line.b.x; + else + orig_x = x; + orig_y = border->line.a.y; + } + else + { + if (y < border->line.a.y) + orig_y = border->line.a.y; + else if (y > border->line.b.y) + orig_y = border->line.b.y; + else + orig_y = y; + orig_x = border->line.a.x; + } + + dx = fabsf (orig_x - x); + dy = fabsf (orig_y - y); + return dx*dx + dy*dy; +} + +static void +warp_to_behind_border (MetaBorder *border, + float *sx, + float *sy) +{ + switch (border->blocking_directions) + { + case META_BORDER_MOTION_DIRECTION_POSITIVE_X: + case META_BORDER_MOTION_DIRECTION_NEGATIVE_X: + if (border->blocking_directions == META_BORDER_MOTION_DIRECTION_POSITIVE_X) + *sx = border->line.a.x - wl_fixed_to_double (1); + else + *sx = border->line.a.x + wl_fixed_to_double (1); + if (*sy < border->line.a.y) + *sy = border->line.a.y + wl_fixed_to_double (1); + else if (*sy > border->line.b.y) + *sy = border->line.b.y - wl_fixed_to_double (1); + break; + case META_BORDER_MOTION_DIRECTION_POSITIVE_Y: + case META_BORDER_MOTION_DIRECTION_NEGATIVE_Y: + if (border->blocking_directions == META_BORDER_MOTION_DIRECTION_POSITIVE_Y) + *sy = border->line.a.y - wl_fixed_to_double (1); + else + *sy = border->line.a.y + wl_fixed_to_double (1); + if (*sx < border->line.a.x) + *sx = border->line.a.x + wl_fixed_to_double (1); + else if (*sx > (border->line.b.x)) + *sx = border->line.b.x - wl_fixed_to_double (1); + break; + } +} + +static void +meta_pointer_confinement_wayland_maybe_warp (MetaPointerConfinementWayland *self) +{ + MetaWaylandSeat *seat; + MetaWaylandSurface *surface; + graphene_point_t point; + float sx; + float sy; + cairo_region_t *region; + + seat = meta_wayland_pointer_constraint_get_seat (self->constraint); + surface = meta_wayland_pointer_constraint_get_surface (self->constraint); + + clutter_input_device_get_coords (seat->pointer->device, NULL, &point); + meta_wayland_surface_get_relative_coordinates (surface, + point.x, point.y, + &sx, &sy); + + region = + meta_wayland_pointer_constraint_calculate_effective_region (self->constraint); + + if (!cairo_region_contains_point (region, (int)sx, (int)sy)) + { + GArray *borders; + float closest_distance_2 = FLT_MAX; + MetaBorder *closest_border = NULL; + ClutterSeat *seat; + unsigned int i; + float x; + float y; + + borders = g_array_new (FALSE, FALSE, sizeof (MetaBorder)); + + region_to_outline (region, borders); + + for (i = 0; i < borders->len; i++) + { + MetaBorder *border = &g_array_index (borders, MetaBorder, i); + float distance_2; + + distance_2 = point_to_border_distance_2 (border, sx, sy); + if (distance_2 < closest_distance_2) + { + closest_border = border; + closest_distance_2 = distance_2; + } + } + + warp_to_behind_border (closest_border, &sx, &sy); + + meta_wayland_surface_get_absolute_coordinates (surface, sx, sy, &x, &y); + + seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); + clutter_seat_warp_pointer (seat, (int)x, (int)y); + } + + cairo_region_destroy (region); +} + +static void +surface_geometry_changed (MetaWaylandSurface *surface, + MetaPointerConfinementWayland *self) +{ + meta_pointer_confinement_wayland_maybe_warp (self); +} + +static void +window_position_changed (MetaWindow *window, + MetaPointerConfinementWayland *self) +{ + meta_pointer_confinement_wayland_maybe_warp (self); +} + +MetaPointerConstraint * +meta_pointer_confinement_wayland_new (MetaWaylandPointerConstraint *constraint) +{ + GObject *object; + MetaPointerConfinementWayland *confinement; + MetaWaylandSurface *surface; + MetaWindow *window; + + object = g_object_new (META_TYPE_POINTER_CONFINEMENT_WAYLAND, NULL); + confinement = META_POINTER_CONFINEMENT_WAYLAND (object); + + confinement->constraint = constraint; + + surface = meta_wayland_pointer_constraint_get_surface (constraint); + g_signal_connect_object (surface, + "geometry-changed", + G_CALLBACK (surface_geometry_changed), + confinement, + 0); + + window = meta_wayland_surface_get_window (surface); + if (window) + { + g_signal_connect_object (window, + "position-changed", + G_CALLBACK (window_position_changed), + confinement, + 0); + } + + return META_POINTER_CONSTRAINT (confinement); +} + +static void +meta_pointer_confinement_wayland_init (MetaPointerConfinementWayland *confinement_wayland) +{ +} + +static void +meta_pointer_confinement_wayland_class_init (MetaPointerConfinementWaylandClass *klass) +{ + MetaPointerConstraintClass *pointer_constraint_class = + META_POINTER_CONSTRAINT_CLASS (klass); + + pointer_constraint_class->constrain = meta_pointer_confinement_wayland_constrain; +} diff --git a/src/wayland/meta-pointer-confinement-wayland.h b/src/wayland/meta-pointer-confinement-wayland.h new file mode 100644 index 000000000..482a25a9a --- /dev/null +++ b/src/wayland/meta-pointer-confinement-wayland.h @@ -0,0 +1,45 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2015 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +#ifndef META_POINTER_CONFINEMENT_WAYLAND_H +#define META_POINTER_CONFINEMENT_WAYLAND_H + +#include <glib-object.h> + +#include "backends/meta-pointer-constraint.h" +#include "wayland/meta-wayland-pointer-constraints.h" + +G_BEGIN_DECLS + +#define META_TYPE_POINTER_CONFINEMENT_WAYLAND (meta_pointer_confinement_wayland_get_type ()) +G_DECLARE_FINAL_TYPE (MetaPointerConfinementWayland, + meta_pointer_confinement_wayland, + META, POINTER_CONFINEMENT_WAYLAND, + MetaPointerConstraint); + +MetaPointerConstraint *meta_pointer_confinement_wayland_new (MetaWaylandPointerConstraint *constraint); + +G_END_DECLS + +#endif /* META_CONFINEMENT_WAYLAND_H */ diff --git a/src/wayland/meta-pointer-lock-wayland.c b/src/wayland/meta-pointer-lock-wayland.c new file mode 100644 index 000000000..08c2789bc --- /dev/null +++ b/src/wayland/meta-pointer-lock-wayland.c @@ -0,0 +1,81 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2015 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +/** + * SECTION:meta-pointer-lock-wayland + * @title: MetaPointerLockWayland + * @short_description: A #MetaPointerConstraint implementing pointer lock. + * + * A MetaPointerLockConstraint implements the client pointer constraint "pointer + * lock": the cursor should not make any movement. + */ + +#include "config.h" + +#include "wayland/meta-pointer-lock-wayland.h" + +#include <glib-object.h> + +#include "backends/meta-pointer-constraint.h" + +struct _MetaPointerLockWayland +{ + MetaPointerConstraint parent; +}; + +G_DEFINE_TYPE (MetaPointerLockWayland, meta_pointer_lock_wayland, + META_TYPE_POINTER_CONSTRAINT); + +static void +meta_pointer_lock_wayland_constrain (MetaPointerConstraint *constraint, + ClutterInputDevice *device, + guint32 time, + float prev_x, + float prev_y, + float *x, + float *y) +{ + *x = prev_x; + *y = prev_y; +} + +MetaPointerConstraint * +meta_pointer_lock_wayland_new (void) +{ + return g_object_new (META_TYPE_POINTER_LOCK_WAYLAND, NULL); +} + +static void +meta_pointer_lock_wayland_init (MetaPointerLockWayland *lock_wayland) +{ +} + +static void +meta_pointer_lock_wayland_class_init (MetaPointerLockWaylandClass *klass) +{ + MetaPointerConstraintClass *pointer_constraint_class = + META_POINTER_CONSTRAINT_CLASS (klass); + + pointer_constraint_class->constrain = meta_pointer_lock_wayland_constrain; +} diff --git a/src/wayland/meta-pointer-lock-wayland.h b/src/wayland/meta-pointer-lock-wayland.h new file mode 100644 index 000000000..787b43269 --- /dev/null +++ b/src/wayland/meta-pointer-lock-wayland.h @@ -0,0 +1,42 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2015 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +#ifndef META_POINTER_LOCK_WAYLAND_H +#define META_POINTER_LOCK_WAYLAND_H + +#include <glib-object.h> + +#include "backends/meta-pointer-constraint.h" + +G_BEGIN_DECLS + +#define META_TYPE_POINTER_LOCK_WAYLAND (meta_pointer_lock_wayland_get_type ()) +G_DECLARE_FINAL_TYPE (MetaPointerLockWayland, meta_pointer_lock_wayland, + META, POINTER_LOCK_WAYLAND, MetaPointerConstraint); + +MetaPointerConstraint *meta_pointer_lock_wayland_new (void); + +G_END_DECLS + +#endif /* META_LOCK_WAYLAND_H */ diff --git a/src/wayland/meta-selection-source-wayland-private.h b/src/wayland/meta-selection-source-wayland-private.h new file mode 100644 index 000000000..38489530a --- /dev/null +++ b/src/wayland/meta-selection-source-wayland-private.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2018 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef META_SELECTION_SOURCE_WAYLAND_H +#define META_SELECTION_SOURCE_WAYLAND_H + +#include <wayland-server.h> + +#include "meta/meta-selection-source.h" +#include "wayland/meta-wayland-data-device.h" + +#define META_TYPE_SELECTION_SOURCE_WAYLAND (meta_selection_source_wayland_get_type ()) + +G_DECLARE_FINAL_TYPE (MetaSelectionSourceWayland, + meta_selection_source_wayland, + META, SELECTION_SOURCE_WAYLAND, + MetaSelectionSource) + +MetaSelectionSource * meta_selection_source_wayland_new (MetaWaylandDataSource *source); + +#endif /* META_SELECTION_SOURCE_WAYLAND_H */ diff --git a/src/wayland/meta-selection-source-wayland.c b/src/wayland/meta-selection-source-wayland.c new file mode 100644 index 000000000..4f6f0c33c --- /dev/null +++ b/src/wayland/meta-selection-source-wayland.c @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2018 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#include "config.h" + +#include <glib-unix.h> +#include <gio/gunixinputstream.h> + +#include "wayland/meta-selection-source-wayland-private.h" + +struct _MetaSelectionSourceWayland +{ + MetaSelectionSource parent_instance; + MetaWaylandDataSource *data_source; + GList *mimetypes; +}; + +G_DEFINE_TYPE (MetaSelectionSourceWayland, meta_selection_source_wayland, + META_TYPE_SELECTION_SOURCE) + +static void +meta_selection_source_wayland_finalize (GObject *object) +{ + MetaSelectionSourceWayland *source_wayland = META_SELECTION_SOURCE_WAYLAND (object); + + g_list_free_full (source_wayland->mimetypes, g_free); + + G_OBJECT_CLASS (meta_selection_source_wayland_parent_class)->finalize (object); +} + +static void +meta_selection_source_wayland_read_async (MetaSelectionSource *source, + const gchar *mimetype, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + MetaSelectionSourceWayland *source_wayland = META_SELECTION_SOURCE_WAYLAND (source); + GInputStream *stream; + GTask *task; + int pipe_fds[2]; + + if (!g_unix_open_pipe (pipe_fds, FD_CLOEXEC, NULL)) + { + g_task_report_new_error (source, callback, user_data, + meta_selection_source_wayland_read_async, + G_IO_ERROR, G_IO_ERROR_FAILED, + "Could not open pipe to read wayland selection"); + return; + } + + if (!g_unix_set_fd_nonblocking (pipe_fds[0], TRUE, NULL) || + !g_unix_set_fd_nonblocking (pipe_fds[1], TRUE, NULL)) + { + g_task_report_new_error (source, callback, user_data, + meta_selection_source_wayland_read_async, + G_IO_ERROR, G_IO_ERROR_FAILED, + "Could not make pipe nonblocking"); + close (pipe_fds[0]); + close (pipe_fds[1]); + return; + } + + task = g_task_new (source, cancellable, callback, user_data); + g_task_set_source_tag (task, meta_selection_source_wayland_read_async); + + stream = g_unix_input_stream_new (pipe_fds[0], TRUE); + meta_wayland_data_source_send (source_wayland->data_source, + mimetype, pipe_fds[1]); + close (pipe_fds[1]); + + g_task_return_pointer (task, stream, g_object_unref); + g_object_unref (task); +} + +static GInputStream * +meta_selection_source_wayland_read_finish (MetaSelectionSource *source, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, source), FALSE); + g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == + meta_selection_source_wayland_read_async, FALSE); + + return g_task_propagate_pointer (G_TASK (result), error); +} + +static GList * +meta_selection_source_wayland_get_mimetypes (MetaSelectionSource *source) +{ + MetaSelectionSourceWayland *source_wayland = META_SELECTION_SOURCE_WAYLAND (source); + + return g_list_copy_deep (source_wayland->mimetypes, + (GCopyFunc) g_strdup, NULL); +} + +static void +meta_selection_source_wayland_deactivated (MetaSelectionSource *source) +{ + MetaSelectionSourceWayland *source_wayland = + META_SELECTION_SOURCE_WAYLAND (source); + + meta_wayland_data_source_cancel (source_wayland->data_source); + META_SELECTION_SOURCE_CLASS (meta_selection_source_wayland_parent_class)->deactivated (source); +} + +static void +meta_selection_source_wayland_class_init (MetaSelectionSourceWaylandClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MetaSelectionSourceClass *source_class = META_SELECTION_SOURCE_CLASS (klass); + + object_class->finalize = meta_selection_source_wayland_finalize; + + source_class->deactivated = meta_selection_source_wayland_deactivated; + + source_class->read_async = meta_selection_source_wayland_read_async; + source_class->read_finish = meta_selection_source_wayland_read_finish; + source_class->get_mimetypes = meta_selection_source_wayland_get_mimetypes; +} + +static void +meta_selection_source_wayland_init (MetaSelectionSourceWayland *source) +{ +} + +static GList * +copy_string_array_to_list (struct wl_array *array) +{ + GList *l = NULL; + char **p; + + wl_array_for_each (p, array) + l = g_list_prepend (l, g_strdup (*p)); + + return l; +} + +MetaSelectionSource * +meta_selection_source_wayland_new (MetaWaylandDataSource *data_source) +{ + MetaSelectionSourceWayland *source_wayland; + struct wl_array *mimetypes; + + source_wayland = g_object_new (META_TYPE_SELECTION_SOURCE_WAYLAND, NULL); + source_wayland->data_source = data_source; + + mimetypes = meta_wayland_data_source_get_mime_types (data_source); + source_wayland->mimetypes = copy_string_array_to_list (mimetypes); + + return META_SELECTION_SOURCE (source_wayland); +} diff --git a/src/wayland/meta-wayland-actor-surface.c b/src/wayland/meta-wayland-actor-surface.c new file mode 100644 index 000000000..f4b958673 --- /dev/null +++ b/src/wayland/meta-wayland-actor-surface.c @@ -0,0 +1,455 @@ +/* + * Copyright (C) 2012,2013 Intel Corporation + * Copyright (C) 2013-2017 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#include "config.h" + +#include "wayland/meta-wayland-actor-surface.h" + +#include "backends/meta-backend-private.h" +#include "backends/meta-logical-monitor.h" +#include "compositor/meta-surface-actor-wayland.h" +#include "compositor/meta-window-actor-wayland.h" +#include "compositor/region-utils.h" +#include "wayland/meta-wayland-buffer.h" +#include "wayland/meta-wayland-surface.h" +#include "wayland/meta-window-wayland.h" +#include "wayland/meta-xwayland-surface.h" + +typedef struct _MetaWaylandActorSurfacePrivate MetaWaylandActorSurfacePrivate; + +struct _MetaWaylandActorSurfacePrivate +{ + MetaSurfaceActor *actor; + + gulong actor_destroyed_handler_id; + + struct wl_list frame_callback_list; +}; + +G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaWaylandActorSurface, + meta_wayland_actor_surface, + META_TYPE_WAYLAND_SURFACE_ROLE) + +static void +meta_wayland_actor_surface_constructed (GObject *object) +{ + G_OBJECT_CLASS (meta_wayland_actor_surface_parent_class)->constructed (object); + + meta_wayland_actor_surface_reset_actor (META_WAYLAND_ACTOR_SURFACE (object)); +} + +static void +clear_surface_actor (MetaWaylandActorSurface *actor_surface) +{ + MetaWaylandActorSurfacePrivate *priv = + meta_wayland_actor_surface_get_instance_private (actor_surface); + MetaWaylandSurfaceRole *surface_role = + META_WAYLAND_SURFACE_ROLE (actor_surface); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + + if (!priv->actor) + return; + + g_clear_signal_handler (&priv->actor_destroyed_handler_id, priv->actor); + g_signal_handlers_disconnect_by_func (priv->actor, + meta_wayland_surface_notify_geometry_changed, + surface); + g_clear_object (&priv->actor); +} + +static void +meta_wayland_actor_surface_dispose (GObject *object) +{ + MetaWaylandActorSurface *actor_surface = META_WAYLAND_ACTOR_SURFACE (object); + MetaWaylandActorSurfacePrivate *priv = + meta_wayland_actor_surface_get_instance_private (actor_surface); + MetaWaylandFrameCallback *cb, *next; + + if (priv->actor) + { + clutter_actor_set_reactive (CLUTTER_ACTOR (priv->actor), FALSE); + clear_surface_actor (actor_surface); + } + + wl_list_for_each_safe (cb, next, &priv->frame_callback_list, link) + wl_resource_destroy (cb->resource); + + G_OBJECT_CLASS (meta_wayland_actor_surface_parent_class)->dispose (object); +} + +static void +meta_wayland_actor_surface_assigned (MetaWaylandSurfaceRole *surface_role) +{ + MetaWaylandActorSurfacePrivate *priv = + meta_wayland_actor_surface_get_instance_private (META_WAYLAND_ACTOR_SURFACE (surface_role)); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + + if (wl_list_empty (&surface->unassigned.pending_frame_callback_list)) + return; + + wl_list_insert_list (priv->frame_callback_list.prev, + &surface->unassigned.pending_frame_callback_list); + wl_list_init (&surface->unassigned.pending_frame_callback_list); + + meta_wayland_compositor_add_frame_callback_surface (surface->compositor, + surface); +} + +void +meta_wayland_actor_surface_queue_frame_callbacks (MetaWaylandActorSurface *actor_surface, + MetaWaylandSurfaceState *pending) +{ + MetaWaylandActorSurfacePrivate *priv = + meta_wayland_actor_surface_get_instance_private (actor_surface); + MetaWaylandSurfaceRole *surface_role = + META_WAYLAND_SURFACE_ROLE (actor_surface); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + + if (wl_list_empty (&pending->frame_callback_list)) + return; + + wl_list_insert_list (priv->frame_callback_list.prev, + &pending->frame_callback_list); + wl_list_init (&pending->frame_callback_list); + + meta_wayland_compositor_add_frame_callback_surface (surface->compositor, + surface); +} + +void +meta_wayland_actor_surface_emit_frame_callbacks (MetaWaylandActorSurface *actor_surface, + uint32_t timestamp_ms) +{ + MetaWaylandActorSurfacePrivate *priv = + meta_wayland_actor_surface_get_instance_private (actor_surface); + + while (!wl_list_empty (&priv->frame_callback_list)) + { + MetaWaylandFrameCallback *callback = + wl_container_of (priv->frame_callback_list.next, callback, link); + + wl_callback_send_done (callback->resource, timestamp_ms); + wl_resource_destroy (callback->resource); + } +} + +double +meta_wayland_actor_surface_get_geometry_scale (MetaWaylandActorSurface *actor_surface) +{ + MetaWaylandActorSurfaceClass *actor_surface_class = + META_WAYLAND_ACTOR_SURFACE_GET_CLASS (actor_surface); + + return actor_surface_class->get_geometry_scale (actor_surface); +} + +static void +meta_wayland_actor_surface_real_sync_actor_state (MetaWaylandActorSurface *actor_surface) +{ + MetaWaylandActorSurfacePrivate *priv = + meta_wayland_actor_surface_get_instance_private (actor_surface); + MetaWaylandSurfaceRole *surface_role = + META_WAYLAND_SURFACE_ROLE (actor_surface); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaSurfaceActor *surface_actor; + MetaShapedTexture *stex; + MetaWaylandBuffer *buffer; + cairo_rectangle_int_t surface_rect; + MetaWaylandSurface *subsurface_surface; + + surface_actor = priv->actor; + stex = meta_surface_actor_get_texture (surface_actor); + + buffer = surface->buffer_ref.buffer; + if (buffer) + { + CoglSnippet *snippet; + gboolean is_y_inverted; + + snippet = meta_wayland_buffer_create_snippet (buffer); + is_y_inverted = meta_wayland_buffer_is_y_inverted (buffer); + + meta_shaped_texture_set_texture (stex, surface->texture); + meta_shaped_texture_set_snippet (stex, snippet); + meta_shaped_texture_set_is_y_inverted (stex, is_y_inverted); + meta_shaped_texture_set_buffer_scale (stex, surface->scale); + cogl_clear_object (&snippet); + } + else + { + meta_shaped_texture_set_texture (stex, NULL); + } + + surface_rect = (cairo_rectangle_int_t) { + .width = meta_wayland_surface_get_width (surface), + .height = meta_wayland_surface_get_height (surface), + }; + + if (surface->input_region) + { + cairo_region_t *input_region; + + input_region = cairo_region_copy (surface->input_region); + cairo_region_intersect_rectangle (input_region, &surface_rect); + meta_surface_actor_set_input_region (surface_actor, input_region); + cairo_region_destroy (input_region); + } + else + { + meta_surface_actor_set_input_region (surface_actor, NULL); + } + + if (!META_IS_XWAYLAND_SURFACE (surface_role)) + { + if (!meta_shaped_texture_has_alpha (stex)) + { + cairo_region_t *opaque_region; + + opaque_region = cairo_region_create_rectangle (&surface_rect); + meta_surface_actor_set_opaque_region (surface_actor, opaque_region); + cairo_region_destroy (opaque_region); + } + else if (surface->opaque_region) + { + cairo_region_t *opaque_region; + + opaque_region = cairo_region_copy (surface->opaque_region); + cairo_region_intersect_rectangle (opaque_region, &surface_rect); + meta_surface_actor_set_opaque_region (surface_actor, opaque_region); + cairo_region_destroy (opaque_region); + } + else + { + meta_surface_actor_set_opaque_region (surface_actor, NULL); + } + } + + meta_surface_actor_set_transform (surface_actor, surface->buffer_transform); + + if (surface->viewport.has_src_rect) + { + meta_surface_actor_set_viewport_src_rect (surface_actor, + &surface->viewport.src_rect); + } + else + { + meta_surface_actor_reset_viewport_src_rect (surface_actor); + } + + if (surface->viewport.has_dst_size) + { + meta_surface_actor_set_viewport_dst_size (surface_actor, + surface->viewport.dst_width, + surface->viewport.dst_height); + } + else + { + meta_surface_actor_reset_viewport_dst_size (surface_actor); + } + + META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (surface, subsurface_surface) + { + MetaWaylandActorSurface *actor_surface; + + actor_surface = META_WAYLAND_ACTOR_SURFACE (subsurface_surface->role); + meta_wayland_actor_surface_sync_actor_state (actor_surface); + } +} + +void +meta_wayland_actor_surface_sync_actor_state (MetaWaylandActorSurface *actor_surface) +{ + MetaWaylandActorSurfaceClass *actor_surface_class = + META_WAYLAND_ACTOR_SURFACE_GET_CLASS (actor_surface); + + actor_surface_class->sync_actor_state (actor_surface); +} + +static void +meta_wayland_actor_surface_apply_state (MetaWaylandSurfaceRole *surface_role, + MetaWaylandSurfaceState *pending) +{ + MetaWaylandActorSurface *actor_surface = + META_WAYLAND_ACTOR_SURFACE (surface_role); + MetaWaylandActorSurfacePrivate *priv = + meta_wayland_actor_surface_get_instance_private (actor_surface); + + if (!wl_list_empty (&pending->frame_callback_list) && + priv->actor && + !meta_surface_actor_is_obscured (priv->actor)) + { + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaBackend *backend = surface->compositor->backend; + ClutterActor *stage = meta_backend_get_stage (backend); + + clutter_stage_schedule_update (CLUTTER_STAGE (stage)); + } + + meta_wayland_actor_surface_queue_frame_callbacks (actor_surface, pending); + + meta_wayland_actor_surface_sync_actor_state (actor_surface); +} + +static gboolean +meta_wayland_actor_surface_is_on_logical_monitor (MetaWaylandSurfaceRole *surface_role, + MetaLogicalMonitor *logical_monitor) +{ + MetaWaylandActorSurfacePrivate *priv = + meta_wayland_actor_surface_get_instance_private (META_WAYLAND_ACTOR_SURFACE (surface_role)); + ClutterActor *actor = CLUTTER_ACTOR (priv->actor); + float x, y, width, height; + cairo_rectangle_int_t actor_rect; + cairo_region_t *region; + MetaRectangle logical_monitor_layout; + gboolean is_on_monitor; + + if (!clutter_actor_is_mapped (actor)) + return FALSE; + + clutter_actor_get_transformed_position (actor, &x, &y); + clutter_actor_get_transformed_size (actor, &width, &height); + + actor_rect.x = (int) roundf (x); + actor_rect.y = (int) roundf (y); + actor_rect.width = (int) roundf (x + width) - actor_rect.x; + actor_rect.height = (int) roundf (y + height) - actor_rect.y; + + /* Calculate the scaled surface actor region. */ + region = cairo_region_create_rectangle (&actor_rect); + + logical_monitor_layout = meta_logical_monitor_get_layout (logical_monitor); + + cairo_region_intersect_rectangle (region, + &((cairo_rectangle_int_t) { + .x = logical_monitor_layout.x, + .y = logical_monitor_layout.y, + .width = logical_monitor_layout.width, + .height = logical_monitor_layout.height, + })); + + is_on_monitor = !cairo_region_is_empty (region); + cairo_region_destroy (region); + + return is_on_monitor; +} + +static void +meta_wayland_actor_surface_get_relative_coordinates (MetaWaylandSurfaceRole *surface_role, + float abs_x, + float abs_y, + float *out_sx, + float *out_sy) +{ + MetaWaylandActorSurface *actor_surface = + META_WAYLAND_ACTOR_SURFACE (surface_role); + MetaWaylandActorSurfacePrivate *priv = + meta_wayland_actor_surface_get_instance_private (actor_surface); + + clutter_actor_transform_stage_point (CLUTTER_ACTOR (priv->actor), + abs_x, abs_y, + out_sx, out_sy); +} + +static void +meta_wayland_actor_surface_init (MetaWaylandActorSurface *actor_surface) +{ + MetaWaylandActorSurfacePrivate *priv = + meta_wayland_actor_surface_get_instance_private (actor_surface); + + wl_list_init (&priv->frame_callback_list); +} + +static void +meta_wayland_actor_surface_class_init (MetaWaylandActorSurfaceClass *klass) +{ + MetaWaylandSurfaceRoleClass *surface_role_class = + META_WAYLAND_SURFACE_ROLE_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->constructed = meta_wayland_actor_surface_constructed; + object_class->dispose = meta_wayland_actor_surface_dispose; + + surface_role_class->assigned = meta_wayland_actor_surface_assigned; + surface_role_class->apply_state = meta_wayland_actor_surface_apply_state; + surface_role_class->is_on_logical_monitor = + meta_wayland_actor_surface_is_on_logical_monitor; + surface_role_class->get_relative_coordinates = + meta_wayland_actor_surface_get_relative_coordinates; + + klass->sync_actor_state = meta_wayland_actor_surface_real_sync_actor_state; +} + +MetaSurfaceActor * +meta_wayland_actor_surface_get_actor (MetaWaylandActorSurface *actor_surface) +{ + MetaWaylandActorSurfacePrivate *priv = + meta_wayland_actor_surface_get_instance_private (actor_surface); + + return priv->actor; +} + +static void +on_actor_destroyed (ClutterActor *actor, + MetaWaylandActorSurface *actor_surface) +{ + clear_surface_actor (actor_surface); +} + +void +meta_wayland_actor_surface_reset_actor (MetaWaylandActorSurface *actor_surface) +{ + MetaWaylandActorSurfacePrivate *priv = + meta_wayland_actor_surface_get_instance_private (actor_surface); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (META_WAYLAND_SURFACE_ROLE (actor_surface)); + MetaWaylandSurface *subsurface_surface; + + META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (surface, subsurface_surface) + { + MetaWaylandActorSurface *actor_surface; + + actor_surface = META_WAYLAND_ACTOR_SURFACE (subsurface_surface->role); + meta_wayland_actor_surface_reset_actor (actor_surface); + meta_wayland_actor_surface_sync_actor_state (actor_surface); + } + + clear_surface_actor (actor_surface); + + priv->actor = g_object_ref_sink (meta_surface_actor_wayland_new (surface)); + priv->actor_destroyed_handler_id = + g_signal_connect (priv->actor, "destroy", + G_CALLBACK (on_actor_destroyed), + actor_surface); + + g_signal_connect_swapped (priv->actor, "notify::allocation", + G_CALLBACK (meta_wayland_surface_notify_geometry_changed), + surface); + g_signal_connect_swapped (priv->actor, "notify::position", + G_CALLBACK (meta_wayland_surface_notify_geometry_changed), + surface); + g_signal_connect_swapped (priv->actor, "notify::mapped", + G_CALLBACK (meta_wayland_surface_notify_geometry_changed), + surface); +} diff --git a/src/wayland/meta-wayland-actor-surface.h b/src/wayland/meta-wayland-actor-surface.h new file mode 100644 index 000000000..bd0cca275 --- /dev/null +++ b/src/wayland/meta-wayland-actor-surface.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2012,2013 Intel Corporation + * Copyright (C) 2013-2017 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_WAYLAND_ACTOR_SURFACE_H +#define META_WAYLAND_ACTOR_SURFACE_H + +#include "wayland/meta-wayland-surface.h" + +#define META_TYPE_WAYLAND_ACTOR_SURFACE (meta_wayland_actor_surface_get_type ()) +G_DECLARE_DERIVABLE_TYPE (MetaWaylandActorSurface, + meta_wayland_actor_surface, + META, WAYLAND_ACTOR_SURFACE, + MetaWaylandSurfaceRole) + +struct _MetaWaylandActorSurfaceClass +{ + MetaWaylandSurfaceRoleClass parent_class; + + double (* get_geometry_scale) (MetaWaylandActorSurface *actor_surface); + void (* sync_actor_state) (MetaWaylandActorSurface *actor_surface); +}; + +void meta_wayland_actor_surface_sync_actor_state (MetaWaylandActorSurface *actor_surface); +double meta_wayland_actor_surface_get_geometry_scale (MetaWaylandActorSurface *actor_surface); + +META_EXPORT_TEST +MetaSurfaceActor * meta_wayland_actor_surface_get_actor (MetaWaylandActorSurface *actor_surface); + +void meta_wayland_actor_surface_reset_actor (MetaWaylandActorSurface *actor_surface); + +void meta_wayland_actor_surface_queue_frame_callbacks (MetaWaylandActorSurface *actor_surface, + MetaWaylandSurfaceState *pending); + +void meta_wayland_actor_surface_emit_frame_callbacks (MetaWaylandActorSurface *actor_surface, + uint32_t timestamp_ms); + +#endif /* META_WAYLAND_ACTOR_SURFACE_H */ diff --git a/src/wayland/meta-wayland-buffer.c b/src/wayland/meta-wayland-buffer.c new file mode 100644 index 000000000..6236579e7 --- /dev/null +++ b/src/wayland/meta-wayland-buffer.c @@ -0,0 +1,619 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Endless Mobile + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jasper St. Pierre <jstpierre@mecheye.net> + */ + +/** + * SECTION:meta-wayland-buffer + * @title: MetaWaylandBuffer + * @short_description: A wrapper for wayland buffers + * + * #MetaWaylandBuffer is a general wrapper around wl_buffer, the basic way of + * passing rendered data from Wayland clients to the compositor. Note that a + * buffer can be backed by several types of memory, as specified by + * #MetaWaylandBufferType. + */ + +/** + * MetaWaylandBufferType: + * @META_WAYLAND_BUFFER_TYPE_UNKNOWN: Unknown type. + * @META_WAYLAND_BUFFER_TYPE_SHM: wl_buffer backed by shared memory + * @META_WAYLAND_BUFFER_TYPE_EGL_IMAGE: wl_buffer backed by an EGLImage + * @META_WAYLAND_BUFFER_TYPE_EGL_STREAM: wl_buffer backed by an EGLStream (NVIDIA-specific) + * @META_WAYLAND_BUFFER_TYPE_DMA_BUF: wl_buffer backed by a Linux DMA-BUF + * + * Specifies the backing memory for a #MetaWaylandBuffer. Depending on the type + * of buffer, this will lead to different handling for the compositor. For + * example, a shared-memory buffer will still need to be uploaded to the GPU. + */ + +#include "config.h" + +#include "wayland/meta-wayland-buffer.h" + +#include <drm_fourcc.h> + +#include "backends/meta-backend-private.h" +#include "clutter/clutter.h" +#include "cogl/cogl-egl.h" +#include "meta/util.h" +#include "wayland/meta-wayland-dma-buf.h" + +#ifndef DRM_FORMAT_MOD_INVALID +#define DRM_FORMAT_MOD_INVALID ((1ULL << 56) - 1) +#endif + +enum +{ + RESOURCE_DESTROYED, + + LAST_SIGNAL +}; + +guint signals[LAST_SIGNAL]; + +G_DEFINE_TYPE (MetaWaylandBuffer, meta_wayland_buffer, G_TYPE_OBJECT); + +static void +meta_wayland_buffer_destroy_handler (struct wl_listener *listener, + void *data) +{ + MetaWaylandBuffer *buffer = + wl_container_of (listener, buffer, destroy_listener); + + buffer->resource = NULL; + g_signal_emit (buffer, signals[RESOURCE_DESTROYED], 0); + g_object_unref (buffer); +} + +MetaWaylandBuffer * +meta_wayland_buffer_from_resource (struct wl_resource *resource) +{ + MetaWaylandBuffer *buffer; + struct wl_listener *listener; + + listener = + wl_resource_get_destroy_listener (resource, + meta_wayland_buffer_destroy_handler); + + if (listener) + { + buffer = wl_container_of (listener, buffer, destroy_listener); + } + else + { + buffer = g_object_new (META_TYPE_WAYLAND_BUFFER, NULL); + + buffer->resource = resource; + buffer->destroy_listener.notify = meta_wayland_buffer_destroy_handler; + wl_resource_add_destroy_listener (resource, &buffer->destroy_listener); + } + + return buffer; +} + +struct wl_resource * +meta_wayland_buffer_get_resource (MetaWaylandBuffer *buffer) +{ + return buffer->resource; +} + +gboolean +meta_wayland_buffer_is_realized (MetaWaylandBuffer *buffer) +{ + return buffer->type != META_WAYLAND_BUFFER_TYPE_UNKNOWN; +} + +gboolean +meta_wayland_buffer_realize (MetaWaylandBuffer *buffer) +{ + EGLint format; + MetaBackend *backend = meta_get_backend (); + MetaEgl *egl = meta_backend_get_egl (backend); + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend); + EGLDisplay egl_display = cogl_egl_context_get_egl_display (cogl_context); +#ifdef HAVE_WAYLAND_EGLSTREAM + MetaWaylandEglStream *stream; +#endif + MetaWaylandDmaBufBuffer *dma_buf; + + if (wl_shm_buffer_get (buffer->resource) != NULL) + { + buffer->type = META_WAYLAND_BUFFER_TYPE_SHM; + return TRUE; + } + +#ifdef HAVE_WAYLAND_EGLSTREAM + stream = meta_wayland_egl_stream_new (buffer, NULL); + if (stream) + { + CoglTexture2D *texture; + + texture = meta_wayland_egl_stream_create_texture (stream, NULL); + if (!texture) + return FALSE; + + buffer->egl_stream.stream = stream; + buffer->type = META_WAYLAND_BUFFER_TYPE_EGL_STREAM; + buffer->egl_stream.texture = COGL_TEXTURE (texture); + buffer->is_y_inverted = meta_wayland_egl_stream_is_y_inverted (stream); + + return TRUE; + } +#endif /* HAVE_WAYLAND_EGLSTREAM */ + + if (meta_egl_query_wayland_buffer (egl, egl_display, buffer->resource, + EGL_TEXTURE_FORMAT, &format, + NULL)) + { + buffer->type = META_WAYLAND_BUFFER_TYPE_EGL_IMAGE; + return TRUE; + } + + dma_buf = meta_wayland_dma_buf_from_buffer (buffer); + if (dma_buf) + { + buffer->dma_buf.dma_buf = dma_buf; + buffer->type = META_WAYLAND_BUFFER_TYPE_DMA_BUF; + return TRUE; + } + + return FALSE; +} + +static void +shm_buffer_get_cogl_pixel_format (struct wl_shm_buffer *shm_buffer, + CoglPixelFormat *format_out, + CoglTextureComponents *components_out) +{ + CoglPixelFormat format; + CoglTextureComponents components = COGL_TEXTURE_COMPONENTS_RGBA; + + switch (wl_shm_buffer_get_format (shm_buffer)) + { +#if G_BYTE_ORDER == G_BIG_ENDIAN + case WL_SHM_FORMAT_ARGB8888: + format = COGL_PIXEL_FORMAT_ARGB_8888_PRE; + break; + case WL_SHM_FORMAT_XRGB8888: + format = COGL_PIXEL_FORMAT_ARGB_8888; + components = COGL_TEXTURE_COMPONENTS_RGB; + break; +#elif G_BYTE_ORDER == G_LITTLE_ENDIAN + case WL_SHM_FORMAT_ARGB8888: + format = COGL_PIXEL_FORMAT_BGRA_8888_PRE; + break; + case WL_SHM_FORMAT_XRGB8888: + format = COGL_PIXEL_FORMAT_BGRA_8888; + components = COGL_TEXTURE_COMPONENTS_RGB; + break; +#endif + default: + g_warn_if_reached (); + format = COGL_PIXEL_FORMAT_ARGB_8888; + } + + if (format_out) + *format_out = format; + if (components_out) + *components_out = components; +} + +static gboolean +shm_buffer_attach (MetaWaylandBuffer *buffer, + CoglTexture **texture, + GError **error) +{ + MetaBackend *backend = meta_get_backend (); + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend); + struct wl_shm_buffer *shm_buffer; + int stride, width, height; + CoglPixelFormat format; + CoglTextureComponents components; + CoglBitmap *bitmap; + CoglTexture *new_texture; + + shm_buffer = wl_shm_buffer_get (buffer->resource); + stride = wl_shm_buffer_get_stride (shm_buffer); + width = wl_shm_buffer_get_width (shm_buffer); + height = wl_shm_buffer_get_height (shm_buffer); + shm_buffer_get_cogl_pixel_format (shm_buffer, &format, &components); + + if (*texture && + cogl_texture_get_width (*texture) == width && + cogl_texture_get_height (*texture) == height && + cogl_texture_get_components (*texture) == components && + _cogl_texture_get_format (*texture) == format) + { + buffer->is_y_inverted = TRUE; + return TRUE; + } + + cogl_clear_object (texture); + + wl_shm_buffer_begin_access (shm_buffer); + + bitmap = cogl_bitmap_new_for_data (cogl_context, + width, height, + format, + stride, + wl_shm_buffer_get_data (shm_buffer)); + + new_texture = COGL_TEXTURE (cogl_texture_2d_new_from_bitmap (bitmap)); + cogl_texture_set_components (new_texture, components); + + if (!cogl_texture_allocate (new_texture, error)) + { + g_clear_pointer (&new_texture, cogl_object_unref); + if (g_error_matches (*error, COGL_TEXTURE_ERROR, COGL_TEXTURE_ERROR_SIZE)) + { + CoglTexture2DSliced *texture_sliced; + + g_clear_error (error); + + texture_sliced = + cogl_texture_2d_sliced_new_from_bitmap (bitmap, + COGL_TEXTURE_MAX_WASTE); + new_texture = COGL_TEXTURE (texture_sliced); + cogl_texture_set_components (new_texture, components); + + if (!cogl_texture_allocate (new_texture, error)) + g_clear_pointer (&new_texture, cogl_object_unref); + } + } + + cogl_object_unref (bitmap); + + wl_shm_buffer_end_access (shm_buffer); + + if (!new_texture) + return FALSE; + + *texture = new_texture; + buffer->is_y_inverted = TRUE; + + return TRUE; +} + +static gboolean +egl_image_buffer_attach (MetaWaylandBuffer *buffer, + CoglTexture **texture, + GError **error) +{ + MetaBackend *backend = meta_get_backend (); + MetaEgl *egl = meta_backend_get_egl (backend); + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend); + EGLDisplay egl_display = cogl_egl_context_get_egl_display (cogl_context); + int format, width, height, y_inverted; + CoglPixelFormat cogl_format; + EGLImageKHR egl_image; + CoglEglImageFlags flags; + CoglTexture2D *texture_2d; + + if (buffer->egl_image.texture) + { + cogl_clear_object (texture); + *texture = cogl_object_ref (buffer->egl_image.texture); + return TRUE; + } + + if (!meta_egl_query_wayland_buffer (egl, egl_display, buffer->resource, + EGL_TEXTURE_FORMAT, &format, + error)) + return FALSE; + + if (!meta_egl_query_wayland_buffer (egl, egl_display, buffer->resource, + EGL_WIDTH, &width, + error)) + return FALSE; + + if (!meta_egl_query_wayland_buffer (egl, egl_display, buffer->resource, + EGL_HEIGHT, &height, + error)) + return FALSE; + + if (!meta_egl_query_wayland_buffer (egl, egl_display, buffer->resource, + EGL_WAYLAND_Y_INVERTED_WL, &y_inverted, + NULL)) + y_inverted = EGL_TRUE; + + switch (format) + { + case EGL_TEXTURE_RGB: + cogl_format = COGL_PIXEL_FORMAT_RGB_888; + break; + case EGL_TEXTURE_RGBA: + cogl_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE; + break; + default: + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_FAILED, + "Unsupported buffer format %d", format); + return FALSE; + } + + /* The WL_bind_wayland_display spec states that EGL_NO_CONTEXT is to be used + * in conjunction with the EGL_WAYLAND_BUFFER_WL target. */ + egl_image = meta_egl_create_image (egl, egl_display, EGL_NO_CONTEXT, + EGL_WAYLAND_BUFFER_WL, buffer->resource, + NULL, + error); + if (egl_image == EGL_NO_IMAGE_KHR) + return FALSE; + + flags = COGL_EGL_IMAGE_FLAG_NONE; + texture_2d = cogl_egl_texture_2d_new_from_image (cogl_context, + width, height, + cogl_format, + egl_image, + flags, + error); + + meta_egl_destroy_image (egl, egl_display, egl_image, NULL); + + if (!texture_2d) + return FALSE; + + buffer->egl_image.texture = COGL_TEXTURE (texture_2d); + buffer->is_y_inverted = !!y_inverted; + + cogl_clear_object (texture); + *texture = cogl_object_ref (buffer->egl_image.texture); + + return TRUE; +} + +#ifdef HAVE_WAYLAND_EGLSTREAM +static gboolean +egl_stream_buffer_attach (MetaWaylandBuffer *buffer, + CoglTexture **texture, + GError **error) +{ + MetaWaylandEglStream *stream = buffer->egl_stream.stream; + + g_assert (stream); + + if (!meta_wayland_egl_stream_attach (stream, error)) + return FALSE; + + cogl_clear_object (texture); + *texture = cogl_object_ref (buffer->egl_stream.texture); + + return TRUE; +} +#endif /* HAVE_WAYLAND_EGLSTREAM */ + +/** + * meta_wayland_buffer_attach: + * @buffer: a pointer to a #MetaWaylandBuffer + * @texture: (inout) (transfer full): a #CoglTexture representing the surface + * content + * @error: return location for error or %NULL + * + * This function should be passed a pointer to the texture used to draw the + * surface content. The texture will either be replaced by a new texture, or + * stay the same, in which case, it may later be updated with new content when + * processing damage. The new texture might be newly created, or it may be a + * reference to an already existing one. + * + * If replaced, the old texture will have its reference count decreased by one, + * potentially freeing it. When a new texture is set, the caller (i.e. the + * surface) will be the owner of one reference count. It must free it, either + * using g_object_unref() or have it updated again using + * meta_wayland_buffer_attach(), which also might free it, as described above. + */ +gboolean +meta_wayland_buffer_attach (MetaWaylandBuffer *buffer, + CoglTexture **texture, + GError **error) +{ + g_return_val_if_fail (buffer->resource, FALSE); + + if (!meta_wayland_buffer_is_realized (buffer)) + { + /* The buffer should have been realized at surface commit time */ + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_FAILED, + "Unknown buffer type"); + return FALSE; + } + + switch (buffer->type) + { + case META_WAYLAND_BUFFER_TYPE_SHM: + return shm_buffer_attach (buffer, texture, error); + case META_WAYLAND_BUFFER_TYPE_EGL_IMAGE: + return egl_image_buffer_attach (buffer, texture, error); +#ifdef HAVE_WAYLAND_EGLSTREAM + case META_WAYLAND_BUFFER_TYPE_EGL_STREAM: + return egl_stream_buffer_attach (buffer, texture, error); +#endif + case META_WAYLAND_BUFFER_TYPE_DMA_BUF: + return meta_wayland_dma_buf_buffer_attach (buffer, + texture, + error); + case META_WAYLAND_BUFFER_TYPE_UNKNOWN: + g_assert_not_reached (); + return FALSE; + } + + g_assert_not_reached (); + return FALSE; +} + +/** + * meta_wayland_buffer_create_snippet: + * @buffer: A #MetaWaylandBuffer object + * + * If needed, this method creates a #CoglSnippet to make sure the buffer can be + * dealt with appropriately in a #CoglPipeline that renders it. + * + * Returns: (transfer full) (nullable): A new #CoglSnippet, or %NULL. + */ +CoglSnippet * +meta_wayland_buffer_create_snippet (MetaWaylandBuffer *buffer) +{ +#ifdef HAVE_WAYLAND_EGLSTREAM + if (!buffer->egl_stream.stream) + return NULL; + + return meta_wayland_egl_stream_create_snippet (buffer->egl_stream.stream); +#else + return NULL; +#endif /* HAVE_WAYLAND_EGLSTREAM */ +} + +gboolean +meta_wayland_buffer_is_y_inverted (MetaWaylandBuffer *buffer) +{ + return buffer->is_y_inverted; +} + +static gboolean +process_shm_buffer_damage (MetaWaylandBuffer *buffer, + CoglTexture *texture, + cairo_region_t *region, + GError **error) +{ + struct wl_shm_buffer *shm_buffer; + int i, n_rectangles; + gboolean set_texture_failed = FALSE; + CoglPixelFormat format; + + n_rectangles = cairo_region_num_rectangles (region); + + shm_buffer = wl_shm_buffer_get (buffer->resource); + + shm_buffer_get_cogl_pixel_format (shm_buffer, &format, NULL); + g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, FALSE); + + wl_shm_buffer_begin_access (shm_buffer); + + for (i = 0; i < n_rectangles; i++) + { + const uint8_t *data = wl_shm_buffer_get_data (shm_buffer); + int32_t stride = wl_shm_buffer_get_stride (shm_buffer); + cairo_rectangle_int_t rect; + int bpp; + + bpp = cogl_pixel_format_get_bytes_per_pixel (format, 0); + cairo_region_get_rectangle (region, i, &rect); + + if (!_cogl_texture_set_region (texture, + rect.width, rect.height, + format, + stride, + data + rect.x * bpp + rect.y * stride, + rect.x, rect.y, + 0, + error)) + { + set_texture_failed = TRUE; + break; + } + } + + wl_shm_buffer_end_access (shm_buffer); + + return !set_texture_failed; +} + +void +meta_wayland_buffer_process_damage (MetaWaylandBuffer *buffer, + CoglTexture *texture, + cairo_region_t *region) +{ + gboolean res = FALSE; + GError *error = NULL; + + g_return_if_fail (buffer->resource); + + switch (buffer->type) + { + case META_WAYLAND_BUFFER_TYPE_SHM: + res = process_shm_buffer_damage (buffer, texture, region, &error); + break; + case META_WAYLAND_BUFFER_TYPE_EGL_IMAGE: +#ifdef HAVE_WAYLAND_EGLSTREAM + case META_WAYLAND_BUFFER_TYPE_EGL_STREAM: +#endif + case META_WAYLAND_BUFFER_TYPE_DMA_BUF: + res = TRUE; + break; + case META_WAYLAND_BUFFER_TYPE_UNKNOWN: + g_set_error (&error, G_IO_ERROR, + G_IO_ERROR_FAILED, + "Unknown buffer type"); + res = FALSE; + break; + } + + if (!res) + { + g_warning ("Failed to process Wayland buffer damage: %s", error->message); + g_error_free (error); + } +} + +static void +meta_wayland_buffer_finalize (GObject *object) +{ + MetaWaylandBuffer *buffer = META_WAYLAND_BUFFER (object); + + g_clear_pointer (&buffer->egl_image.texture, cogl_object_unref); +#ifdef HAVE_WAYLAND_EGLSTREAM + g_clear_pointer (&buffer->egl_stream.texture, cogl_object_unref); + g_clear_object (&buffer->egl_stream.stream); +#endif + g_clear_pointer (&buffer->dma_buf.texture, cogl_object_unref); + g_clear_object (&buffer->dma_buf.dma_buf); + + G_OBJECT_CLASS (meta_wayland_buffer_parent_class)->finalize (object); +} + +static void +meta_wayland_buffer_init (MetaWaylandBuffer *buffer) +{ +} + +static void +meta_wayland_buffer_class_init (MetaWaylandBufferClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_wayland_buffer_finalize; + + /** + * MetaWaylandBuffer::resource-destroyed: + * + * Called when the underlying wl_resource was destroyed. + */ + signals[RESOURCE_DESTROYED] = g_signal_new ("resource-destroyed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); +} diff --git a/src/wayland/meta-wayland-buffer.h b/src/wayland/meta-wayland-buffer.h new file mode 100644 index 000000000..4a503b183 --- /dev/null +++ b/src/wayland/meta-wayland-buffer.h @@ -0,0 +1,92 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Endless Mobile + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jasper St. Pierre <jstpierre@mecheye.net> + */ + +#ifndef META_WAYLAND_BUFFER_H +#define META_WAYLAND_BUFFER_H + +#include <cairo.h> +#include <wayland-server.h> + +#include "cogl/cogl.h" +#include "wayland/meta-wayland-types.h" +#include "wayland/meta-wayland-egl-stream.h" +#include "wayland/meta-wayland-dma-buf.h" + +typedef enum _MetaWaylandBufferType +{ + META_WAYLAND_BUFFER_TYPE_UNKNOWN, + META_WAYLAND_BUFFER_TYPE_SHM, + META_WAYLAND_BUFFER_TYPE_EGL_IMAGE, +#ifdef HAVE_WAYLAND_EGLSTREAM + META_WAYLAND_BUFFER_TYPE_EGL_STREAM, +#endif + META_WAYLAND_BUFFER_TYPE_DMA_BUF, +} MetaWaylandBufferType; + +struct _MetaWaylandBuffer +{ + GObject parent; + + struct wl_resource *resource; + struct wl_listener destroy_listener; + + gboolean is_y_inverted; + + MetaWaylandBufferType type; + + struct { + CoglTexture *texture; + } egl_image; + +#ifdef HAVE_WAYLAND_EGLSTREAM + struct { + MetaWaylandEglStream *stream; + CoglTexture *texture; + } egl_stream; +#endif + + struct { + MetaWaylandDmaBufBuffer *dma_buf; + CoglTexture *texture; + } dma_buf; +}; + +#define META_TYPE_WAYLAND_BUFFER (meta_wayland_buffer_get_type ()) +G_DECLARE_FINAL_TYPE (MetaWaylandBuffer, meta_wayland_buffer, + META, WAYLAND_BUFFER, GObject); + +MetaWaylandBuffer * meta_wayland_buffer_from_resource (struct wl_resource *resource); +struct wl_resource * meta_wayland_buffer_get_resource (MetaWaylandBuffer *buffer); +gboolean meta_wayland_buffer_is_realized (MetaWaylandBuffer *buffer); +gboolean meta_wayland_buffer_realize (MetaWaylandBuffer *buffer); +gboolean meta_wayland_buffer_attach (MetaWaylandBuffer *buffer, + CoglTexture **texture, + GError **error); +CoglSnippet * meta_wayland_buffer_create_snippet (MetaWaylandBuffer *buffer); +gboolean meta_wayland_buffer_is_y_inverted (MetaWaylandBuffer *buffer); +void meta_wayland_buffer_process_damage (MetaWaylandBuffer *buffer, + CoglTexture *texture, + cairo_region_t *region); + +#endif /* META_WAYLAND_BUFFER_H */ diff --git a/src/wayland/meta-wayland-cursor-surface.c b/src/wayland/meta-wayland-cursor-surface.c new file mode 100644 index 000000000..95f8186df --- /dev/null +++ b/src/wayland/meta-wayland-cursor-surface.c @@ -0,0 +1,387 @@ +/* + * Wayland Support + * + * Copyright (C) 2015 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "wayland/meta-wayland-cursor-surface.h" + +#include "backends/meta-backend-private.h" +#include "backends/meta-logical-monitor.h" +#include "cogl/cogl-wayland-server.h" +#include "cogl/cogl.h" +#include "core/boxes-private.h" +#include "wayland/meta-cursor-sprite-wayland.h" +#include "wayland/meta-wayland-buffer.h" +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-xwayland.h" + +typedef struct _MetaWaylandCursorSurfacePrivate MetaWaylandCursorSurfacePrivate; + +struct _MetaWaylandCursorSurfacePrivate +{ + int hot_x; + int hot_y; + MetaCursorSpriteWayland *cursor_sprite; + MetaCursorRenderer *cursor_renderer; + MetaWaylandBuffer *buffer; + struct wl_list frame_callbacks; + gulong cursor_painted_handler_id; +}; + +G_DEFINE_TYPE_WITH_PRIVATE (MetaWaylandCursorSurface, + meta_wayland_cursor_surface, + META_TYPE_WAYLAND_SURFACE_ROLE) + +static void +update_cursor_sprite_texture (MetaWaylandCursorSurface *cursor_surface) +{ + MetaWaylandCursorSurfacePrivate *priv = + meta_wayland_cursor_surface_get_instance_private (cursor_surface); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (META_WAYLAND_SURFACE_ROLE (cursor_surface)); + MetaCursorSprite *cursor_sprite = META_CURSOR_SPRITE (priv->cursor_sprite); + CoglTexture *texture; + + if (!priv->cursor_renderer) + return; + + texture = meta_wayland_surface_get_texture (surface); + if (texture) + { + meta_cursor_sprite_set_texture (cursor_sprite, + texture, + priv->hot_x * surface->scale, + priv->hot_y * surface->scale); + } + else + { + meta_cursor_sprite_set_texture (cursor_sprite, NULL, 0, 0); + } + + meta_cursor_renderer_force_update (priv->cursor_renderer); +} + +static void +cursor_sprite_prepare_at (MetaCursorSprite *cursor_sprite, + int x, + int y, + MetaWaylandCursorSurface *cursor_surface) +{ + MetaWaylandSurfaceRole *role = META_WAYLAND_SURFACE_ROLE (cursor_surface); + MetaWaylandSurface *surface = meta_wayland_surface_role_get_surface (role); + + if (!meta_xwayland_is_xwayland_surface (surface)) + { + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaLogicalMonitor *logical_monitor; + + logical_monitor = + meta_monitor_manager_get_logical_monitor_at (monitor_manager, x, y); + if (logical_monitor) + { + float texture_scale; + + if (meta_is_stage_views_scaled ()) + texture_scale = 1.0 / surface->scale; + else + texture_scale = (meta_logical_monitor_get_scale (logical_monitor) / + surface->scale); + + meta_cursor_sprite_set_texture_scale (cursor_sprite, texture_scale); + } + } + meta_wayland_surface_update_outputs (surface); +} + +static void +meta_wayland_cursor_surface_assigned (MetaWaylandSurfaceRole *surface_role) +{ + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWaylandCursorSurface *cursor_surface = + META_WAYLAND_CURSOR_SURFACE (surface_role); + MetaWaylandCursorSurfacePrivate *priv = + meta_wayland_cursor_surface_get_instance_private (cursor_surface); + + wl_list_insert_list (&priv->frame_callbacks, + &surface->unassigned.pending_frame_callback_list); + wl_list_init (&surface->unassigned.pending_frame_callback_list); +} + +static void +meta_wayland_cursor_surface_pre_apply_state (MetaWaylandSurfaceRole *surface_role, + MetaWaylandSurfaceState *pending) +{ + MetaWaylandCursorSurface *cursor_surface = + META_WAYLAND_CURSOR_SURFACE (surface_role); + MetaWaylandCursorSurfacePrivate *priv = + meta_wayland_cursor_surface_get_instance_private (cursor_surface); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + + if (pending->newly_attached && priv->buffer) + { + meta_wayland_surface_unref_buffer_use_count (surface); + g_clear_object (&priv->buffer); + } +} + +static void +meta_wayland_cursor_surface_apply_state (MetaWaylandSurfaceRole *surface_role, + MetaWaylandSurfaceState *pending) +{ + MetaWaylandCursorSurface *cursor_surface = + META_WAYLAND_CURSOR_SURFACE (surface_role); + MetaWaylandCursorSurfacePrivate *priv = + meta_wayland_cursor_surface_get_instance_private (cursor_surface); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface); + + if (pending->newly_attached) + { + g_set_object (&priv->buffer, buffer); + if (priv->buffer) + meta_wayland_surface_ref_buffer_use_count (surface); + } + + wl_list_insert_list (&priv->frame_callbacks, + &pending->frame_callback_list); + wl_list_init (&pending->frame_callback_list); + + if (pending->newly_attached && + ((!cairo_region_is_empty (pending->surface_damage) || + !cairo_region_is_empty (pending->buffer_damage)) || + !priv->buffer)) + update_cursor_sprite_texture (META_WAYLAND_CURSOR_SURFACE (surface_role)); +} + +static gboolean +meta_wayland_cursor_surface_is_on_logical_monitor (MetaWaylandSurfaceRole *role, + MetaLogicalMonitor *logical_monitor) +{ + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (role); + MetaWaylandCursorSurface *cursor_surface = + META_WAYLAND_CURSOR_SURFACE (surface->role); + MetaWaylandCursorSurfacePrivate *priv = + meta_wayland_cursor_surface_get_instance_private (cursor_surface); + graphene_point_t point; + graphene_rect_t logical_monitor_rect; + + if (!priv->cursor_renderer) + return FALSE; + + logical_monitor_rect = + meta_rectangle_to_graphene_rect (&logical_monitor->rect); + + point = meta_cursor_renderer_get_position (priv->cursor_renderer); + + return graphene_rect_contains_point (&logical_monitor_rect, &point); +} + +static void +meta_wayland_cursor_surface_dispose (GObject *object) +{ + MetaWaylandCursorSurface *cursor_surface = + META_WAYLAND_CURSOR_SURFACE (object); + MetaWaylandCursorSurfacePrivate *priv = + meta_wayland_cursor_surface_get_instance_private (cursor_surface); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (META_WAYLAND_SURFACE_ROLE (object)); + MetaWaylandFrameCallback *cb, *next; + + wl_list_for_each_safe (cb, next, &priv->frame_callbacks, link) + wl_resource_destroy (cb->resource); + + g_signal_handlers_disconnect_by_func (priv->cursor_sprite, + cursor_sprite_prepare_at, cursor_surface); + + g_clear_object (&priv->cursor_renderer); + g_clear_object (&priv->cursor_sprite); + + if (priv->buffer) + { + meta_wayland_surface_unref_buffer_use_count (surface); + g_clear_object (&priv->buffer); + } + + G_OBJECT_CLASS (meta_wayland_cursor_surface_parent_class)->dispose (object); +} + +static void +meta_wayland_cursor_surface_constructed (GObject *object) +{ + MetaWaylandCursorSurface *cursor_surface = + META_WAYLAND_CURSOR_SURFACE (object); + MetaWaylandCursorSurfacePrivate *priv = + meta_wayland_cursor_surface_get_instance_private (cursor_surface); + MetaWaylandSurfaceRole *surface_role = + META_WAYLAND_SURFACE_ROLE (cursor_surface); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWaylandBuffer *buffer; + + buffer = meta_wayland_surface_get_buffer (surface); + + g_warn_if_fail (!buffer || buffer->resource); + + if (buffer && buffer->resource) + { + g_set_object (&priv->buffer, buffer); + meta_wayland_surface_ref_buffer_use_count (surface); + } + + priv->cursor_sprite = meta_cursor_sprite_wayland_new (surface); + g_signal_connect_object (priv->cursor_sprite, + "prepare-at", + G_CALLBACK (cursor_sprite_prepare_at), + cursor_surface, + 0); +} + +static void +meta_wayland_cursor_surface_init (MetaWaylandCursorSurface *role) +{ + MetaWaylandCursorSurfacePrivate *priv = + meta_wayland_cursor_surface_get_instance_private (role); + + wl_list_init (&priv->frame_callbacks); +} + +static void +meta_wayland_cursor_surface_class_init (MetaWaylandCursorSurfaceClass *klass) +{ + MetaWaylandSurfaceRoleClass *surface_role_class = + META_WAYLAND_SURFACE_ROLE_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + surface_role_class->assigned = meta_wayland_cursor_surface_assigned; + surface_role_class->pre_apply_state = + meta_wayland_cursor_surface_pre_apply_state; + surface_role_class->apply_state = meta_wayland_cursor_surface_apply_state; + surface_role_class->is_on_logical_monitor = + meta_wayland_cursor_surface_is_on_logical_monitor; + + object_class->constructed = meta_wayland_cursor_surface_constructed; + object_class->dispose = meta_wayland_cursor_surface_dispose; +} + +MetaCursorSprite * +meta_wayland_cursor_surface_get_sprite (MetaWaylandCursorSurface *cursor_surface) +{ + MetaWaylandCursorSurfacePrivate *priv = + meta_wayland_cursor_surface_get_instance_private (cursor_surface); + + return META_CURSOR_SPRITE (priv->cursor_sprite); +} + +void +meta_wayland_cursor_surface_set_hotspot (MetaWaylandCursorSurface *cursor_surface, + int hotspot_x, + int hotspot_y) +{ + MetaWaylandCursorSurfacePrivate *priv = + meta_wayland_cursor_surface_get_instance_private (cursor_surface); + + if (priv->hot_x == hotspot_x && + priv->hot_y == hotspot_y) + return; + + priv->hot_x = hotspot_x; + priv->hot_y = hotspot_y; + update_cursor_sprite_texture (cursor_surface); +} + +void +meta_wayland_cursor_surface_get_hotspot (MetaWaylandCursorSurface *cursor_surface, + int *hotspot_x, + int *hotspot_y) +{ + MetaWaylandCursorSurfacePrivate *priv = + meta_wayland_cursor_surface_get_instance_private (cursor_surface); + + if (hotspot_x) + *hotspot_x = priv->hot_x; + if (hotspot_y) + *hotspot_y = priv->hot_y; +} + +static void +on_cursor_painted (MetaCursorRenderer *renderer, + MetaCursorSprite *displayed_sprite, + MetaWaylandCursorSurface *cursor_surface) +{ + MetaWaylandCursorSurfacePrivate *priv = + meta_wayland_cursor_surface_get_instance_private (cursor_surface); + guint32 time = (guint32) (g_get_monotonic_time () / 1000); + + if (displayed_sprite != META_CURSOR_SPRITE (priv->cursor_sprite)) + return; + + while (!wl_list_empty (&priv->frame_callbacks)) + { + MetaWaylandFrameCallback *callback = + wl_container_of (priv->frame_callbacks.next, callback, link); + + wl_callback_send_done (callback->resource, time); + wl_resource_destroy (callback->resource); + } +} + +void +meta_wayland_cursor_surface_set_renderer (MetaWaylandCursorSurface *cursor_surface, + MetaCursorRenderer *renderer) +{ + MetaWaylandCursorSurfacePrivate *priv = + meta_wayland_cursor_surface_get_instance_private (cursor_surface); + + if (priv->cursor_renderer == renderer) + return; + + if (priv->cursor_renderer) + { + g_clear_signal_handler (&priv->cursor_painted_handler_id, + priv->cursor_renderer); + g_object_unref (priv->cursor_renderer); + } + if (renderer) + { + priv->cursor_painted_handler_id = + g_signal_connect_object (renderer, "cursor-painted", + G_CALLBACK (on_cursor_painted), cursor_surface, 0); + g_object_ref (renderer); + } + + priv->cursor_renderer = renderer; + update_cursor_sprite_texture (cursor_surface); +} + +MetaCursorRenderer * +meta_wayland_cursor_surface_get_renderer (MetaWaylandCursorSurface *cursor_surface) +{ + MetaWaylandCursorSurfacePrivate *priv = + meta_wayland_cursor_surface_get_instance_private (cursor_surface); + + return priv->cursor_renderer; +} diff --git a/src/wayland/meta-wayland-cursor-surface.h b/src/wayland/meta-wayland-cursor-surface.h new file mode 100644 index 000000000..05b344f04 --- /dev/null +++ b/src/wayland/meta-wayland-cursor-surface.h @@ -0,0 +1,52 @@ +/* + * Wayland Support + * + * Copyright (C) 2015 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_WAYLAND_CURSOR_SURFACE_H +#define META_WAYLAND_CURSOR_SURFACE_H + +#include "backends/meta-cursor-renderer.h" +#include "wayland/meta-wayland-surface.h" + +struct _MetaWaylandCursorSurfaceClass +{ + MetaWaylandSurfaceRoleClass parent_class; +}; + +#define META_TYPE_WAYLAND_CURSOR_SURFACE (meta_wayland_cursor_surface_get_type ()) +G_DECLARE_DERIVABLE_TYPE (MetaWaylandCursorSurface, + meta_wayland_cursor_surface, + META, WAYLAND_CURSOR_SURFACE, + MetaWaylandSurfaceRole); + +MetaCursorSprite * meta_wayland_cursor_surface_get_sprite (MetaWaylandCursorSurface *cursor_surface); + +void meta_wayland_cursor_surface_set_hotspot (MetaWaylandCursorSurface *cursor_surface, + int hotspot_x, + int hotspot_y); +void meta_wayland_cursor_surface_get_hotspot (MetaWaylandCursorSurface *cursor_surface, + int *hotspot_x, + int *hotspot_y); +void meta_wayland_cursor_surface_set_renderer (MetaWaylandCursorSurface *cursor_surface, + MetaCursorRenderer *renderer); +MetaCursorRenderer * meta_wayland_cursor_surface_get_renderer (MetaWaylandCursorSurface *cursor_surface); + + +#endif /* META_WAYLAND_CURSOR_SURFACE_H */ diff --git a/src/wayland/meta-wayland-data-device-primary-legacy.c b/src/wayland/meta-wayland-data-device-primary-legacy.c new file mode 100644 index 000000000..2c5304c5f --- /dev/null +++ b/src/wayland/meta-wayland-data-device-primary-legacy.c @@ -0,0 +1,354 @@ +/* + * Copyright © 2011 Kristian Høgsberg + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* The file is based on src/data-device.c from Weston */ + +#include "config.h" + +#include "wayland/meta-wayland-data-device-primary-legacy.h" + +#include "compositor/meta-dnd-actor-private.h" +#include "meta/meta-selection-source-memory.h" +#include "wayland/meta-selection-source-wayland-private.h" +#include "wayland/meta-wayland-data-offer-primary-legacy.h" +#include "wayland/meta-wayland-data-source-primary-legacy.h" +#include "wayland/meta-wayland-dnd-surface.h" +#include "wayland/meta-wayland-pointer.h" +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-wayland-seat.h" + +#include "gtk-primary-selection-server-protocol.h" + +static struct wl_resource * create_and_send_primary_offer (MetaWaylandDataDevicePrimaryLegacy *data_device, + struct wl_resource *target); + +static void +move_resources (struct wl_list *destination, + struct wl_list *source) +{ + wl_list_insert_list (destination, source); + wl_list_init (source); +} + +static void +move_resources_for_client (struct wl_list *destination, + struct wl_list *source, + struct wl_client *client) +{ + struct wl_resource *resource, *tmp; + wl_resource_for_each_safe (resource, tmp, source) + { + if (wl_resource_get_client (resource) == client) + { + wl_list_remove (wl_resource_get_link (resource)); + wl_list_insert (destination, wl_resource_get_link (resource)); + } + } +} + +static void +unbind_resource (struct wl_resource *resource) +{ + wl_list_remove (wl_resource_get_link (resource)); +} + +static void +default_destructor (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +set_selection_source (MetaWaylandDataDevicePrimaryLegacy *data_device, + MetaSelectionSource *selection_source) + +{ + MetaDisplay *display = meta_get_display (); + + meta_selection_set_owner (meta_display_get_selection (display), + META_SELECTION_PRIMARY, + selection_source); + g_set_object (&data_device->owner, selection_source); +} + +static void +unset_selection_source (MetaWaylandDataDevicePrimaryLegacy *data_device) +{ + MetaDisplay *display = meta_get_display (); + + if (!data_device->owner) + return; + + meta_selection_unset_owner (meta_display_get_selection (display), + META_SELECTION_PRIMARY, + data_device->owner); + g_clear_object (&data_device->owner); +} + +static void +primary_source_destroyed (gpointer data, + GObject *object_was_here) +{ + MetaWaylandDataDevicePrimaryLegacy *data_device = data; + + data_device->data_source = NULL; + unset_selection_source (data_device); +} + +static void +meta_wayland_data_device_primary_legacy_set_selection (MetaWaylandDataDevicePrimaryLegacy *data_device, + MetaWaylandDataSource *source, + uint32_t serial) +{ + MetaWaylandSeat *seat = wl_container_of (data_device, seat, primary_legacy_data_device); + MetaSelectionSource *selection_source; + + g_assert (!source || META_IS_WAYLAND_DATA_SOURCE_PRIMARY_LEGACY (source)); + + if (data_device->data_source && + data_device->serial - serial < UINT32_MAX / 2) + return; + + if (data_device->data_source) + { + g_object_weak_unref (G_OBJECT (data_device->data_source), + primary_source_destroyed, + data_device); + } + + data_device->data_source = source; + data_device->serial = serial; + + if (source) + { + meta_wayland_data_source_set_seat (source, seat); + g_object_weak_ref (G_OBJECT (source), + primary_source_destroyed, + data_device); + + selection_source = meta_selection_source_wayland_new (source); + } + else + { + selection_source = g_object_new (META_TYPE_SELECTION_SOURCE_MEMORY, NULL); + } + + set_selection_source (data_device, selection_source); + g_object_unref (selection_source); +} + +static void +primary_device_set_selection (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *source_resource, + uint32_t serial) +{ + MetaWaylandDataDevicePrimaryLegacy *data_device = wl_resource_get_user_data (resource); + MetaWaylandSeat *seat = wl_container_of (data_device, seat, primary_legacy_data_device); + MetaWaylandDataSource *source = NULL; + + if (source_resource) + source = wl_resource_get_user_data (source_resource); + + if (wl_resource_get_client (resource) != + meta_wayland_keyboard_get_focus_client (seat->keyboard)) + return; + + meta_wayland_data_device_primary_legacy_set_selection (data_device, source, serial); +} + +static const struct gtk_primary_selection_device_interface primary_device_interface = { + primary_device_set_selection, + default_destructor, +}; + +static void +owner_changed_cb (MetaSelection *selection, + MetaSelectionType selection_type, + MetaSelectionSource *new_owner, + MetaWaylandDataDevicePrimaryLegacy *data_device) +{ + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + MetaWaylandSeat *seat = compositor->seat; + struct wl_resource *data_device_resource; + struct wl_client *focus_client; + + focus_client = meta_wayland_keyboard_get_focus_client (seat->keyboard); + if (!focus_client) + return; + + if (selection_type == META_SELECTION_PRIMARY) + { + wl_resource_for_each (data_device_resource, &data_device->focus_resource_list) + { + struct wl_resource *offer = NULL; + + if (new_owner) + { + offer = create_and_send_primary_offer (data_device, + data_device_resource); + } + + gtk_primary_selection_device_send_selection (data_device_resource, + offer); + } + } +} + +static void +ensure_owners_changed_handler_connected (MetaWaylandDataDevicePrimaryLegacy *data_device) +{ + if (data_device->selection_owner_signal_id != 0) + return; + + data_device->selection_owner_signal_id = + g_signal_connect (meta_display_get_selection (meta_get_display ()), + "owner-changed", + G_CALLBACK (owner_changed_cb), data_device); +} + +static void +primary_device_manager_create_source (struct wl_client *client, + struct wl_resource *manager_resource, + guint32 id) +{ + struct wl_resource *source_resource; + + source_resource = + wl_resource_create (client, >k_primary_selection_source_interface, + wl_resource_get_version (manager_resource), + id); + meta_wayland_data_source_primary_legacy_new (source_resource); +} + +static void +primary_device_manager_get_device (struct wl_client *client, + struct wl_resource *manager_resource, + guint32 id, + struct wl_resource *seat_resource) +{ + MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); + struct wl_resource *cr; + + cr = wl_resource_create (client, >k_primary_selection_device_interface, + wl_resource_get_version (manager_resource), id); + wl_resource_set_implementation (cr, &primary_device_interface, + &seat->primary_legacy_data_device, unbind_resource); + wl_list_insert (&seat->primary_legacy_data_device.resource_list, + wl_resource_get_link (cr)); + + ensure_owners_changed_handler_connected (&seat->primary_legacy_data_device); +} + +static const struct gtk_primary_selection_device_manager_interface primary_manager_interface = { + primary_device_manager_create_source, + primary_device_manager_get_device, + default_destructor, +}; + +static void +bind_primary_manager (struct wl_client *client, + void *data, + uint32_t version, + uint32_t id) +{ + struct wl_resource *resource; + + resource = wl_resource_create (client, >k_primary_selection_device_manager_interface, + version, id); + wl_resource_set_implementation (resource, &primary_manager_interface, NULL, NULL); +} + +void +meta_wayland_data_device_primary_legacy_manager_init (MetaWaylandCompositor *compositor) +{ + if (wl_global_create (compositor->wayland_display, + >k_primary_selection_device_manager_interface, + 1, NULL, bind_primary_manager) == NULL) + g_error ("Could not create data_device"); +} + +void +meta_wayland_data_device_primary_legacy_init (MetaWaylandDataDevicePrimaryLegacy *data_device) +{ + wl_list_init (&data_device->resource_list); + wl_list_init (&data_device->focus_resource_list); +} + +static struct wl_resource * +create_and_send_primary_offer (MetaWaylandDataDevicePrimaryLegacy *data_device, + struct wl_resource *target) +{ + MetaWaylandDataOffer *offer; + MetaDisplay *display = meta_get_display (); + struct wl_resource *resource; + GList *mimetypes, *l; + + mimetypes = meta_selection_get_mimetypes (meta_display_get_selection (display), + META_SELECTION_PRIMARY); + if (!mimetypes) + return NULL; + + offer = meta_wayland_data_offer_primary_legacy_new (target); + resource = meta_wayland_data_offer_get_resource (offer); + + gtk_primary_selection_device_send_data_offer (target, resource); + + for (l = mimetypes; l; l = l->next) + gtk_primary_selection_offer_send_offer (resource, l->data); + + g_list_free_full (mimetypes, g_free); + + return resource; +} + +void +meta_wayland_data_device_primary_legacy_set_keyboard_focus (MetaWaylandDataDevicePrimaryLegacy *data_device) +{ + MetaWaylandSeat *seat = wl_container_of (data_device, seat, primary_legacy_data_device); + struct wl_client *focus_client; + struct wl_resource *data_device_resource; + + focus_client = meta_wayland_keyboard_get_focus_client (seat->keyboard); + + if (focus_client == data_device->focus_client) + return; + + data_device->focus_client = focus_client; + move_resources (&data_device->resource_list, + &data_device->focus_resource_list); + + if (!focus_client) + return; + + move_resources_for_client (&data_device->focus_resource_list, + &data_device->resource_list, + focus_client); + + wl_resource_for_each (data_device_resource, &data_device->focus_resource_list) + { + struct wl_resource *offer; + offer = create_and_send_primary_offer (data_device, data_device_resource); + gtk_primary_selection_device_send_selection (data_device_resource, offer); + } +} diff --git a/src/wayland/meta-wayland-data-device-primary-legacy.h b/src/wayland/meta-wayland-data-device-primary-legacy.h new file mode 100644 index 000000000..c1b4d6e99 --- /dev/null +++ b/src/wayland/meta-wayland-data-device-primary-legacy.h @@ -0,0 +1,55 @@ +/* + * Copyright © 2008 Kristian Høgsberg + * 2020 Red Hat Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef META_WAYLAND_DATA_DEVICE_PRIMARY_LEGACY_H +#define META_WAYLAND_DATA_DEVICE_PRIMARY_LEGACY_H + +#include <glib-object.h> +#include <wayland-server.h> + +#include "clutter/clutter.h" +#include "meta/meta-selection-source.h" +#include "wayland/meta-wayland-data-offer.h" +#include "wayland/meta-wayland-data-source.h" +#include "wayland/meta-wayland-types.h" + +struct _MetaWaylandDataDevicePrimaryLegacy +{ + uint32_t serial; + MetaWaylandDataSource *data_source; + struct wl_list resource_list; + struct wl_list focus_resource_list; + struct wl_client *focus_client; + + guint selection_owner_signal_id; + + MetaSelectionSource *owner; +}; + +void meta_wayland_data_device_primary_legacy_manager_init (MetaWaylandCompositor *compositor); + +void meta_wayland_data_device_primary_legacy_init (MetaWaylandDataDevicePrimaryLegacy *data_device); + +void meta_wayland_data_device_primary_legacy_set_keyboard_focus (MetaWaylandDataDevicePrimaryLegacy *data_device); + +#endif /* META_WAYLAND_DATA_DEVICE_PRIMARY_LEGACY_H */ diff --git a/src/wayland/meta-wayland-data-device-primary.c b/src/wayland/meta-wayland-data-device-primary.c new file mode 100644 index 000000000..fb6417cfe --- /dev/null +++ b/src/wayland/meta-wayland-data-device-primary.c @@ -0,0 +1,353 @@ +/* + * Copyright © 2011 Kristian Høgsberg + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* The file is based on src/data-device.c from Weston */ + +#include "config.h" + +#include "wayland/meta-wayland-data-device-primary.h" + +#include "compositor/meta-dnd-actor-private.h" +#include "meta/meta-selection-source-memory.h" +#include "wayland/meta-selection-source-wayland-private.h" +#include "wayland/meta-wayland-data-offer-primary.h" +#include "wayland/meta-wayland-data-source-primary.h" +#include "wayland/meta-wayland-dnd-surface.h" +#include "wayland/meta-wayland-pointer.h" +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-wayland-seat.h" + +#include "primary-selection-unstable-v1-server-protocol.h" + +static struct wl_resource * create_and_send_primary_offer (MetaWaylandDataDevicePrimary *data_device, + struct wl_resource *target); + +static void +move_resources (struct wl_list *destination, + struct wl_list *source) +{ + wl_list_insert_list (destination, source); + wl_list_init (source); +} + +static void +move_resources_for_client (struct wl_list *destination, + struct wl_list *source, + struct wl_client *client) +{ + struct wl_resource *resource, *tmp; + wl_resource_for_each_safe (resource, tmp, source) + { + if (wl_resource_get_client (resource) == client) + { + wl_list_remove (wl_resource_get_link (resource)); + wl_list_insert (destination, wl_resource_get_link (resource)); + } + } +} + +static void +unbind_resource (struct wl_resource *resource) +{ + wl_list_remove (wl_resource_get_link (resource)); +} + +static void +default_destructor (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +set_selection_source (MetaWaylandDataDevicePrimary *data_device, + MetaSelectionSource *selection_source) + +{ + MetaDisplay *display = meta_get_display (); + + meta_selection_set_owner (meta_display_get_selection (display), + META_SELECTION_PRIMARY, + selection_source); + g_set_object (&data_device->owner, selection_source); +} + +static void +unset_selection_source (MetaWaylandDataDevicePrimary *data_device) +{ + MetaDisplay *display = meta_get_display (); + + if (!data_device->owner) + return; + + meta_selection_unset_owner (meta_display_get_selection (display), + META_SELECTION_PRIMARY, + data_device->owner); + g_clear_object (&data_device->owner); +} + +static void +primary_source_destroyed (gpointer data, + GObject *object_was_here) +{ + MetaWaylandDataDevicePrimary *data_device = data; + + data_device->data_source = NULL; + unset_selection_source (data_device); +} + +static void +meta_wayland_data_device_primary_set_selection (MetaWaylandDataDevicePrimary *data_device, + MetaWaylandDataSource *source, + uint32_t serial) +{ + MetaWaylandSeat *seat = wl_container_of (data_device, seat, primary_data_device); + MetaSelectionSource *selection_source; + + g_assert (!source || META_IS_WAYLAND_DATA_SOURCE_PRIMARY (source)); + + if (data_device->data_source && + data_device->serial - serial < UINT32_MAX / 2) + return; + + if (data_device->data_source) + { + g_object_weak_unref (G_OBJECT (data_device->data_source), + primary_source_destroyed, + data_device); + } + + data_device->data_source = source; + data_device->serial = serial; + + if (source) + { + meta_wayland_data_source_set_seat (source, seat); + g_object_weak_ref (G_OBJECT (source), + primary_source_destroyed, + data_device); + + selection_source = meta_selection_source_wayland_new (source); + } + else + { + selection_source = g_object_new (META_TYPE_SELECTION_SOURCE_MEMORY, NULL); + } + + set_selection_source (data_device, selection_source); + g_object_unref (selection_source); +} + +static void +primary_device_set_selection (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *source_resource, + uint32_t serial) +{ + MetaWaylandDataDevicePrimary *data_device = wl_resource_get_user_data (resource); + MetaWaylandSeat *seat = wl_container_of (data_device, seat, primary_data_device); + MetaWaylandDataSource *source = NULL; + + if (source_resource) + source = wl_resource_get_user_data (source_resource); + + if (wl_resource_get_client (resource) != + meta_wayland_keyboard_get_focus_client (seat->keyboard)) + return; + + meta_wayland_data_device_primary_set_selection (data_device, source, serial); +} + +static const struct zwp_primary_selection_device_v1_interface primary_device_interface = { + primary_device_set_selection, + default_destructor, +}; + +static void +owner_changed_cb (MetaSelection *selection, + MetaSelectionType selection_type, + MetaSelectionSource *new_owner, + MetaWaylandDataDevicePrimary *data_device) +{ + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + MetaWaylandSeat *seat = compositor->seat; + struct wl_resource *data_device_resource; + struct wl_client *focus_client; + + focus_client = meta_wayland_keyboard_get_focus_client (seat->keyboard); + if (!focus_client) + return; + + if (selection_type == META_SELECTION_PRIMARY) + { + wl_resource_for_each (data_device_resource, &data_device->focus_resource_list) + { + struct wl_resource *offer = NULL; + + if (new_owner) + { + offer = create_and_send_primary_offer (data_device, + data_device_resource); + } + + zwp_primary_selection_device_v1_send_selection (data_device_resource, + offer); + } + } +} + +static void +ensure_owners_changed_handler_connected (MetaWaylandDataDevicePrimary *data_device) +{ + if (data_device->selection_owner_signal_id != 0) + return; + + data_device->selection_owner_signal_id = + g_signal_connect (meta_display_get_selection (meta_get_display ()), + "owner-changed", + G_CALLBACK (owner_changed_cb), data_device); +} + +static void +primary_device_manager_create_source (struct wl_client *client, + struct wl_resource *manager_resource, + guint32 id) +{ + struct wl_resource *source_resource; + + source_resource = + wl_resource_create (client, &zwp_primary_selection_source_v1_interface, + wl_resource_get_version (manager_resource), + id); + meta_wayland_data_source_primary_new (source_resource); +} + +static void +primary_device_manager_get_device (struct wl_client *client, + struct wl_resource *manager_resource, + guint32 id, + struct wl_resource *seat_resource) +{ + MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); + struct wl_resource *cr; + + cr = wl_resource_create (client, &zwp_primary_selection_device_v1_interface, + wl_resource_get_version (manager_resource), id); + wl_resource_set_implementation (cr, &primary_device_interface, + &seat->primary_data_device, unbind_resource); + wl_list_insert (&seat->primary_data_device.resource_list, wl_resource_get_link (cr)); + + ensure_owners_changed_handler_connected (&seat->primary_data_device); +} + +static const struct zwp_primary_selection_device_manager_v1_interface primary_manager_interface = { + primary_device_manager_create_source, + primary_device_manager_get_device, + default_destructor, +}; + +static void +bind_primary_manager (struct wl_client *client, + void *data, + uint32_t version, + uint32_t id) +{ + struct wl_resource *resource; + + resource = wl_resource_create (client, &zwp_primary_selection_device_manager_v1_interface, + version, id); + wl_resource_set_implementation (resource, &primary_manager_interface, NULL, NULL); +} + +void +meta_wayland_data_device_primary_manager_init (MetaWaylandCompositor *compositor) +{ + if (wl_global_create (compositor->wayland_display, + &zwp_primary_selection_device_manager_v1_interface, + 1, NULL, bind_primary_manager) == NULL) + g_error ("Could not create data_device"); +} + +void +meta_wayland_data_device_primary_init (MetaWaylandDataDevicePrimary *data_device) +{ + wl_list_init (&data_device->resource_list); + wl_list_init (&data_device->focus_resource_list); +} + +static struct wl_resource * +create_and_send_primary_offer (MetaWaylandDataDevicePrimary *data_device, + struct wl_resource *target) +{ + MetaWaylandDataOffer *offer; + MetaDisplay *display = meta_get_display (); + struct wl_resource *resource; + GList *mimetypes, *l; + + mimetypes = meta_selection_get_mimetypes (meta_display_get_selection (display), + META_SELECTION_PRIMARY); + if (!mimetypes) + return NULL; + + offer = meta_wayland_data_offer_primary_new (target); + resource = meta_wayland_data_offer_get_resource (offer); + + zwp_primary_selection_device_v1_send_data_offer (target, resource); + + for (l = mimetypes; l; l = l->next) + zwp_primary_selection_offer_v1_send_offer (resource, l->data); + + g_list_free_full (mimetypes, g_free); + + return resource; +} + +void +meta_wayland_data_device_primary_set_keyboard_focus (MetaWaylandDataDevicePrimary *data_device) +{ + MetaWaylandSeat *seat = wl_container_of (data_device, seat, primary_data_device); + struct wl_client *focus_client; + struct wl_resource *data_device_resource; + + focus_client = meta_wayland_keyboard_get_focus_client (seat->keyboard); + + if (focus_client == data_device->focus_client) + return; + + data_device->focus_client = focus_client; + move_resources (&data_device->resource_list, + &data_device->focus_resource_list); + + if (!focus_client) + return; + + move_resources_for_client (&data_device->focus_resource_list, + &data_device->resource_list, + focus_client); + + wl_resource_for_each (data_device_resource, &data_device->focus_resource_list) + { + struct wl_resource *offer; + offer = create_and_send_primary_offer (data_device, data_device_resource); + zwp_primary_selection_device_v1_send_selection (data_device_resource, offer); + } +} diff --git a/src/wayland/meta-wayland-data-device-primary.h b/src/wayland/meta-wayland-data-device-primary.h new file mode 100644 index 000000000..77fcbf97e --- /dev/null +++ b/src/wayland/meta-wayland-data-device-primary.h @@ -0,0 +1,55 @@ +/* + * Copyright © 2008 Kristian Høgsberg + * 2020 Red Hat Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef META_WAYLAND_DATA_DEVICE_PRIMARY_H +#define META_WAYLAND_DATA_DEVICE_PRIMARY_H + +#include <glib-object.h> +#include <wayland-server.h> + +#include "clutter/clutter.h" +#include "meta/meta-selection-source.h" +#include "wayland/meta-wayland-data-offer.h" +#include "wayland/meta-wayland-data-source.h" +#include "wayland/meta-wayland-types.h" + +struct _MetaWaylandDataDevicePrimary +{ + uint32_t serial; + MetaWaylandDataSource *data_source; + struct wl_list resource_list; + struct wl_list focus_resource_list; + struct wl_client *focus_client; + + guint selection_owner_signal_id; + + MetaSelectionSource *owner; +}; + +void meta_wayland_data_device_primary_manager_init (MetaWaylandCompositor *compositor); + +void meta_wayland_data_device_primary_init (MetaWaylandDataDevicePrimary *data_device); + +void meta_wayland_data_device_primary_set_keyboard_focus (MetaWaylandDataDevicePrimary *data_device); + +#endif /* META_WAYLAND_DATA_DEVICE_PRIMARY_H */ diff --git a/src/wayland/meta-wayland-data-device.c b/src/wayland/meta-wayland-data-device.c new file mode 100644 index 000000000..e40a58c29 --- /dev/null +++ b/src/wayland/meta-wayland-data-device.c @@ -0,0 +1,1129 @@ +/* + * Copyright © 2011 Kristian Høgsberg + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* The file is based on src/data-device.c from Weston */ + +#include "config.h" + +#include "wayland/meta-wayland-data-device.h" + +#include <gio/gunixoutputstream.h> +#include <glib-unix.h> +#include <glib.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "compositor/meta-dnd-actor-private.h" +#include "meta/meta-selection-source-memory.h" +#include "wayland/meta-selection-source-wayland-private.h" +#include "wayland/meta-wayland-dnd-surface.h" +#include "wayland/meta-wayland-pointer.h" +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-wayland-seat.h" + +#define ROOTWINDOW_DROP_MIME "application/x-rootwindow-drop" + +static void unset_selection_source (MetaWaylandDataDevice *data_device, + MetaSelectionType selection_type); + +static void +drag_grab_data_source_destroyed (gpointer data, GObject *where_the_object_was); + +static struct wl_resource * create_and_send_clipboard_offer (MetaWaylandDataDevice *data_device, + struct wl_resource *target); + +static void +move_resources (struct wl_list *destination, + struct wl_list *source) +{ + wl_list_insert_list (destination, source); + wl_list_init (source); +} + +static void +move_resources_for_client (struct wl_list *destination, + struct wl_list *source, + struct wl_client *client) +{ + struct wl_resource *resource, *tmp; + wl_resource_for_each_safe (resource, tmp, source) + { + if (wl_resource_get_client (resource) == client) + { + wl_list_remove (wl_resource_get_link (resource)); + wl_list_insert (destination, wl_resource_get_link (resource)); + } + } +} + +static void +unbind_resource (struct wl_resource *resource) +{ + wl_list_remove (wl_resource_get_link (resource)); +} + +static void +default_destructor (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static struct wl_resource * +create_and_send_dnd_offer (MetaWaylandDataSource *source, + struct wl_resource *target) +{ + MetaWaylandDataOffer *offer; + struct wl_array *mime_types; + struct wl_resource *resource; + char **p; + + offer = meta_wayland_data_offer_new (META_SELECTION_DND, source, target); + resource = meta_wayland_data_offer_get_resource (offer); + + wl_data_device_send_data_offer (target, resource); + + mime_types = meta_wayland_data_source_get_mime_types (source); + + wl_array_for_each (p, mime_types) + wl_data_offer_send_offer (resource, *p); + + meta_wayland_data_offer_update_action (offer); + meta_wayland_data_source_set_current_offer (source, offer); + + return resource; +} + +struct _MetaWaylandDragGrab { + MetaWaylandPointerGrab generic; + + MetaWaylandKeyboardGrab keyboard_grab; + + MetaWaylandSeat *seat; + struct wl_client *drag_client; + + MetaWaylandSurface *drag_focus; + gulong drag_focus_destroy_handler_id; + struct wl_resource *drag_focus_data_device; + struct wl_listener drag_focus_listener; + + MetaWaylandSurface *drag_surface; + struct wl_listener drag_icon_listener; + + MetaWaylandDataSource *drag_data_source; + + ClutterActor *feedback_actor; + + MetaWaylandSurface *drag_origin; + struct wl_listener drag_origin_listener; + + int drag_start_x, drag_start_y; + ClutterModifierType buttons; + + guint need_initial_focus : 1; +}; + +static void +set_selection_source (MetaWaylandDataDevice *data_device, + MetaSelectionType selection_type, + MetaSelectionSource *selection_source) + +{ + MetaDisplay *display = meta_get_display (); + + meta_selection_set_owner (meta_display_get_selection (display), + selection_type, selection_source); + g_set_object (&data_device->owners[selection_type], selection_source); +} + +static void +unset_selection_source (MetaWaylandDataDevice *data_device, + MetaSelectionType selection_type) +{ + MetaDisplay *display = meta_get_display (); + + if (!data_device->owners[selection_type]) + return; + + meta_selection_unset_owner (meta_display_get_selection (display), + selection_type, + data_device->owners[selection_type]); + g_clear_object (&data_device->owners[selection_type]); +} + +static void +destroy_drag_focus (struct wl_listener *listener, void *data) +{ + MetaWaylandDragGrab *grab = wl_container_of (listener, grab, drag_focus_listener); + + grab->drag_focus_data_device = NULL; + + g_clear_signal_handler (&grab->drag_focus_destroy_handler_id, + grab->drag_focus); + grab->drag_focus = NULL; +} + +static void +on_drag_focus_destroyed (MetaWaylandSurface *surface, + MetaWaylandDragGrab *grab) +{ + meta_wayland_surface_drag_dest_focus_out (grab->drag_focus); + grab->drag_focus = NULL; +} + +static void +meta_wayland_drag_grab_set_source (MetaWaylandDragGrab *drag_grab, + MetaWaylandDataSource *source) +{ + if (drag_grab->drag_data_source) + g_object_weak_unref (G_OBJECT (drag_grab->drag_data_source), + drag_grab_data_source_destroyed, + drag_grab); + + drag_grab->drag_data_source = source; + + if (source) + g_object_weak_ref (G_OBJECT (source), + drag_grab_data_source_destroyed, + drag_grab); +} + +static void +meta_wayland_drag_source_fake_acceptance (MetaWaylandDataSource *source, + const gchar *mimetype) +{ + uint32_t actions, user_action, action = 0; + + meta_wayland_data_source_get_actions (source, &actions); + user_action = meta_wayland_data_source_get_user_action (source); + + /* Pick a suitable action */ + if ((user_action & actions) != 0) + action = user_action; + else if (actions != 0) + action = 1 << (ffs (actions) - 1); + + /* Bail out if there is none, source didn't cooperate */ + if (action == 0) + return; + + meta_wayland_data_source_target (source, mimetype); + meta_wayland_data_source_set_current_action (source, action); + meta_wayland_data_source_set_has_target (source, TRUE); +} + +void +meta_wayland_drag_grab_set_focus (MetaWaylandDragGrab *drag_grab, + MetaWaylandSurface *surface) +{ + MetaWaylandSeat *seat = drag_grab->seat; + MetaWaylandDataSource *source = drag_grab->drag_data_source; + struct wl_client *client; + struct wl_resource *data_device_resource, *offer = NULL; + + if (!drag_grab->need_initial_focus && + drag_grab->drag_focus == surface) + return; + + drag_grab->need_initial_focus = FALSE; + + if (drag_grab->drag_focus) + { + meta_wayland_surface_drag_dest_focus_out (drag_grab->drag_focus); + g_clear_signal_handler (&drag_grab->drag_focus_destroy_handler_id, + drag_grab->drag_focus); + drag_grab->drag_focus = NULL; + } + + if (source) + meta_wayland_data_source_set_current_offer (source, NULL); + + if (!surface && source && + meta_wayland_data_source_has_mime_type (source, ROOTWINDOW_DROP_MIME)) + meta_wayland_drag_source_fake_acceptance (source, ROOTWINDOW_DROP_MIME); + else if (source) + meta_wayland_data_source_target (source, NULL); + + if (!surface) + return; + + if (!source && + wl_resource_get_client (surface->resource) != drag_grab->drag_client) + return; + + client = wl_resource_get_client (surface->resource); + + data_device_resource = wl_resource_find_for_client (&seat->data_device.resource_list, client); + if (!data_device_resource) + { + data_device_resource = + wl_resource_find_for_client (&seat->data_device.focus_resource_list, + client); + } + + if (source && data_device_resource) + offer = create_and_send_dnd_offer (source, data_device_resource); + + drag_grab->drag_focus = surface; + drag_grab->drag_focus_destroy_handler_id = + g_signal_connect (surface, "destroy", + G_CALLBACK (on_drag_focus_destroyed), + drag_grab); + drag_grab->drag_focus_data_device = data_device_resource; + + meta_wayland_surface_drag_dest_focus_in (drag_grab->drag_focus, + offer ? wl_resource_get_user_data (offer) : NULL); +} + +MetaWaylandSurface * +meta_wayland_drag_grab_get_focus (MetaWaylandDragGrab *drag_grab) +{ + return drag_grab->drag_focus; +} + +void +meta_wayland_drag_grab_update_feedback_actor (MetaWaylandDragGrab *drag_grab, + ClutterEvent *event) +{ + meta_feedback_actor_update (META_FEEDBACK_ACTOR (drag_grab->feedback_actor), + event); +} + +static void +drag_grab_focus (MetaWaylandPointerGrab *grab, + MetaWaylandSurface *surface) +{ + MetaWaylandDragGrab *drag_grab = (MetaWaylandDragGrab*) grab; + + meta_wayland_drag_grab_set_focus (drag_grab, surface); +} + +static void +data_source_update_user_dnd_action (MetaWaylandDataSource *source, + ClutterModifierType modifiers) +{ + enum wl_data_device_manager_dnd_action user_dnd_action = 0; + + if (modifiers & CLUTTER_SHIFT_MASK) + user_dnd_action = WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE; + else if (modifiers & CLUTTER_CONTROL_MASK) + user_dnd_action = WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY; + else if (modifiers & (CLUTTER_MOD1_MASK | CLUTTER_BUTTON2_MASK)) + user_dnd_action = WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK; + + meta_wayland_data_source_set_user_action (source, user_dnd_action); +} + +static void +drag_grab_motion (MetaWaylandPointerGrab *grab, + const ClutterEvent *event) +{ + MetaWaylandDragGrab *drag_grab = (MetaWaylandDragGrab*) grab; + + if (drag_grab->drag_focus) + meta_wayland_surface_drag_dest_motion (drag_grab->drag_focus, event); + + if (drag_grab->drag_surface) + meta_feedback_actor_update (META_FEEDBACK_ACTOR (drag_grab->feedback_actor), + event); +} + +static void +data_device_end_drag_grab (MetaWaylandDragGrab *drag_grab) +{ + meta_wayland_drag_grab_set_source (drag_grab, NULL); + meta_wayland_drag_grab_set_focus (drag_grab, NULL); + + if (drag_grab->drag_origin) + { + drag_grab->drag_origin = NULL; + wl_list_remove (&drag_grab->drag_origin_listener.link); + } + + if (drag_grab->drag_surface) + { + drag_grab->drag_surface = NULL; + wl_list_remove (&drag_grab->drag_icon_listener.link); + } + + if (drag_grab->feedback_actor) + { + clutter_actor_remove_all_children (drag_grab->feedback_actor); + clutter_actor_destroy (drag_grab->feedback_actor); + } + + drag_grab->seat->data_device.current_grab = NULL; + + /* There might be other grabs created in result to DnD actions like popups + * on "ask" actions, we must not reset those, only our own. + */ + if (drag_grab->generic.pointer->grab == (MetaWaylandPointerGrab *) drag_grab) + { + meta_wayland_pointer_end_grab (drag_grab->generic.pointer); + meta_wayland_keyboard_end_grab (drag_grab->keyboard_grab.keyboard); + meta_display_sync_wayland_input_focus (meta_get_display ()); + } + + g_slice_free (MetaWaylandDragGrab, drag_grab); +} + +static gboolean +on_fake_read_hup (GIOChannel *channel, + GIOCondition condition, + gpointer data) +{ + MetaWaylandDataSource *source = data; + + meta_wayland_data_source_notify_finish (source); + g_io_channel_shutdown (channel, FALSE, NULL); + g_io_channel_unref (channel); + + return G_SOURCE_REMOVE; +} + +static void +meta_wayland_data_source_fake_read (MetaWaylandDataSource *source, + const gchar *mimetype) +{ + GIOChannel *channel; + int p[2]; + + if (!g_unix_open_pipe (p, FD_CLOEXEC, NULL)) + { + meta_wayland_data_source_notify_finish (source); + return; + } + + if (!g_unix_set_fd_nonblocking (p[0], TRUE, NULL) || + !g_unix_set_fd_nonblocking (p[1], TRUE, NULL)) + { + meta_wayland_data_source_notify_finish (source); + close (p[0]); + close (p[1]); + return; + } + + meta_wayland_data_source_send (source, mimetype, p[1]); + channel = g_io_channel_unix_new (p[0]); + g_io_add_watch (channel, G_IO_HUP, on_fake_read_hup, source); +} + +static void +drag_grab_button (MetaWaylandPointerGrab *grab, + const ClutterEvent *event) +{ + MetaWaylandDragGrab *drag_grab = (MetaWaylandDragGrab*) grab; + MetaWaylandSeat *seat = drag_grab->seat; + ClutterEventType event_type = clutter_event_type (event); + + if (drag_grab->generic.pointer->grab_button == clutter_event_get_button (event) && + event_type == CLUTTER_BUTTON_RELEASE) + { + MetaWaylandDataSource *source = drag_grab->drag_data_source; + gboolean success; + + if (drag_grab->drag_focus && source && + meta_wayland_data_source_has_target (source) && + meta_wayland_data_source_get_current_action (source)) + { + meta_wayland_surface_drag_dest_drop (drag_grab->drag_focus); + meta_wayland_data_source_notify_drop_performed (source); + + meta_wayland_data_source_update_in_ask (source); + success = TRUE; + } + else if (!drag_grab->drag_focus && source && + meta_wayland_data_source_has_target (source) && + meta_wayland_data_source_get_current_action (source) && + meta_wayland_data_source_has_mime_type (source, ROOTWINDOW_DROP_MIME)) + { + /* Perform a fake read, that will lead to notify_finish() being called */ + meta_wayland_data_source_fake_read (source, ROOTWINDOW_DROP_MIME); + success = TRUE; + } + else + { + if (source) + meta_wayland_data_source_set_current_offer (source, NULL); + meta_wayland_data_device_set_dnd_source (&seat->data_device, NULL); + unset_selection_source (&seat->data_device, META_SELECTION_DND); + success = FALSE; + } + + /* Finish drag and let actor self-destruct */ + meta_dnd_actor_drag_finish (META_DND_ACTOR (drag_grab->feedback_actor), success); + drag_grab->feedback_actor = NULL; + } + + if (seat->pointer->button_count == 0 && + event_type == CLUTTER_BUTTON_RELEASE) + data_device_end_drag_grab (drag_grab); +} + +static const MetaWaylandPointerGrabInterface drag_grab_interface = { + drag_grab_focus, + drag_grab_motion, + drag_grab_button, +}; + +static gboolean +keyboard_drag_grab_key (MetaWaylandKeyboardGrab *grab, + const ClutterEvent *event) +{ + if (event->key.keyval == CLUTTER_KEY_Escape) + { + MetaWaylandDragGrab *drag_grab; + + drag_grab = wl_container_of (grab, drag_grab, keyboard_grab); + meta_wayland_data_source_cancel (drag_grab->drag_data_source); + meta_wayland_data_source_set_current_offer (drag_grab->drag_data_source, NULL); + meta_dnd_actor_drag_finish (META_DND_ACTOR (drag_grab->feedback_actor), FALSE); + drag_grab->feedback_actor = NULL; + data_device_end_drag_grab (drag_grab); + + return TRUE; + } + + return FALSE; +} + +static void +keyboard_drag_grab_modifiers (MetaWaylandKeyboardGrab *grab, + ClutterModifierType modifiers) +{ + MetaWaylandDragGrab *drag_grab; + + drag_grab = wl_container_of (grab, drag_grab, keyboard_grab); + + /* The modifiers here just contain keyboard modifiers, mix it with the + * mouse button modifiers we got when starting the drag operation. + */ + modifiers |= drag_grab->buttons; + + if (drag_grab->drag_data_source) + { + data_source_update_user_dnd_action (drag_grab->drag_data_source, modifiers); + + if (drag_grab->drag_focus) + meta_wayland_surface_drag_dest_update (drag_grab->drag_focus); + } +} + +static const MetaWaylandKeyboardGrabInterface keyboard_drag_grab_interface = { + keyboard_drag_grab_key, + keyboard_drag_grab_modifiers +}; + +static void +destroy_data_device_origin (struct wl_listener *listener, void *data) +{ + MetaWaylandDragGrab *drag_grab = + wl_container_of (listener, drag_grab, drag_origin_listener); + + drag_grab->drag_origin = NULL; + meta_wayland_data_device_set_dnd_source (&drag_grab->seat->data_device, NULL); + unset_selection_source (&drag_grab->seat->data_device, META_SELECTION_DND); + meta_wayland_data_source_set_current_offer (drag_grab->drag_data_source, NULL); + data_device_end_drag_grab (drag_grab); +} + +static void +drag_grab_data_source_destroyed (gpointer data, GObject *where_the_object_was) +{ + MetaWaylandDragGrab *drag_grab = data; + + drag_grab->drag_data_source = NULL; + data_device_end_drag_grab (drag_grab); +} + +static void +destroy_data_device_icon (struct wl_listener *listener, void *data) +{ + MetaWaylandDragGrab *drag_grab = + wl_container_of (listener, drag_grab, drag_icon_listener); + + drag_grab->drag_surface = NULL; + + if (drag_grab->feedback_actor) + clutter_actor_remove_all_children (drag_grab->feedback_actor); +} + +void +meta_wayland_data_device_start_drag (MetaWaylandDataDevice *data_device, + struct wl_client *client, + const MetaWaylandPointerGrabInterface *funcs, + MetaWaylandSurface *surface, + MetaWaylandDataSource *source, + MetaWaylandSurface *icon_surface) +{ + MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device); + MetaWaylandDragGrab *drag_grab; + graphene_point_t pos, surface_pos; + ClutterModifierType modifiers; + MetaSurfaceActor *surface_actor; + + data_device->current_grab = drag_grab = g_slice_new0 (MetaWaylandDragGrab); + + drag_grab->generic.interface = funcs; + drag_grab->generic.pointer = seat->pointer; + + drag_grab->keyboard_grab.interface = &keyboard_drag_grab_interface; + drag_grab->keyboard_grab.keyboard = seat->keyboard; + + drag_grab->drag_client = client; + drag_grab->seat = seat; + + drag_grab->drag_origin = surface; + drag_grab->drag_origin_listener.notify = destroy_data_device_origin; + wl_resource_add_destroy_listener (surface->resource, + &drag_grab->drag_origin_listener); + + surface_actor = meta_wayland_surface_get_actor (surface); + + clutter_actor_transform_stage_point (CLUTTER_ACTOR (surface_actor), + seat->pointer->grab_x, + seat->pointer->grab_y, + &surface_pos.x, &surface_pos.y); + drag_grab->drag_start_x = surface_pos.x; + drag_grab->drag_start_y = surface_pos.y; + + drag_grab->need_initial_focus = TRUE; + + modifiers = clutter_input_device_get_modifier_state (seat->pointer->device); + drag_grab->buttons = modifiers & + (CLUTTER_BUTTON1_MASK | CLUTTER_BUTTON2_MASK | CLUTTER_BUTTON3_MASK | + CLUTTER_BUTTON4_MASK | CLUTTER_BUTTON5_MASK); + + meta_wayland_drag_grab_set_source (drag_grab, source); + meta_wayland_data_device_set_dnd_source (data_device, + drag_grab->drag_data_source); + data_source_update_user_dnd_action (source, modifiers); + + if (icon_surface) + { + ClutterActor *drag_surface_actor; + + drag_grab->drag_surface = icon_surface; + + drag_grab->drag_icon_listener.notify = destroy_data_device_icon; + wl_resource_add_destroy_listener (icon_surface->resource, + &drag_grab->drag_icon_listener); + + drag_surface_actor = CLUTTER_ACTOR (meta_wayland_surface_get_actor (drag_grab->drag_surface)); + + drag_grab->feedback_actor = meta_dnd_actor_new (CLUTTER_ACTOR (surface_actor), + drag_grab->drag_start_x, + drag_grab->drag_start_y); + meta_feedback_actor_set_anchor (META_FEEDBACK_ACTOR (drag_grab->feedback_actor), + 0, 0); + clutter_actor_add_child (drag_grab->feedback_actor, drag_surface_actor); + + clutter_input_device_get_coords (seat->pointer->device, NULL, &pos); + meta_feedback_actor_set_position (META_FEEDBACK_ACTOR (drag_grab->feedback_actor), + pos.x, pos.y); + } + + meta_wayland_pointer_start_grab (seat->pointer, + (MetaWaylandPointerGrab*) drag_grab); + meta_wayland_data_source_set_seat (source, seat); +} + +void +meta_wayland_data_device_end_drag (MetaWaylandDataDevice *data_device) +{ + if (data_device->current_grab) + data_device_end_drag_grab (data_device->current_grab); +} + +static void +data_device_start_drag (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *source_resource, + struct wl_resource *origin_resource, + struct wl_resource *icon_resource, guint32 serial) +{ + MetaWaylandDataDevice *data_device = wl_resource_get_user_data (resource); + MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device); + MetaWaylandSurface *surface = NULL, *icon_surface = NULL; + MetaWaylandDataSource *drag_source = NULL; + MetaSelectionSource *selection_source; + + if (origin_resource) + surface = wl_resource_get_user_data (origin_resource); + + if (!surface) + return; + + if (seat->pointer->button_count == 0 || + seat->pointer->grab_serial != serial || + !seat->pointer->focus_surface || + seat->pointer->focus_surface != surface) + return; + + /* FIXME: Check that the data source type array isn't empty. */ + + if (data_device->current_grab || + seat->pointer->grab != &seat->pointer->default_grab) + return; + + if (icon_resource) + icon_surface = wl_resource_get_user_data (icon_resource); + if (source_resource) + drag_source = wl_resource_get_user_data (source_resource); + + if (icon_resource && + !meta_wayland_surface_assign_role (icon_surface, + META_TYPE_WAYLAND_SURFACE_ROLE_DND, + NULL)) + { + wl_resource_post_error (resource, WL_DATA_DEVICE_ERROR_ROLE, + "wl_surface@%d already has a different role", + wl_resource_get_id (icon_resource)); + return; + } + + selection_source = meta_selection_source_wayland_new (drag_source); + set_selection_source (data_device, META_SELECTION_DND, + selection_source); + g_object_unref (selection_source); + + meta_wayland_pointer_set_focus (seat->pointer, NULL); + meta_wayland_data_device_start_drag (data_device, client, + &drag_grab_interface, + surface, drag_source, icon_surface); + + if (meta_wayland_seat_has_keyboard (seat)) + meta_wayland_keyboard_start_grab (seat->keyboard, + &seat->data_device.current_grab->keyboard_grab); +} + +static void +selection_data_source_destroyed (gpointer data, GObject *object_was_here) +{ + MetaWaylandDataDevice *data_device = data; + + data_device->selection_data_source = NULL; + unset_selection_source (data_device, META_SELECTION_CLIPBOARD); +} + +static void +meta_wayland_drag_dest_focus_in (MetaWaylandDataDevice *data_device, + MetaWaylandSurface *surface, + MetaWaylandDataOffer *offer) +{ + MetaWaylandDragGrab *grab = data_device->current_grab; + MetaWaylandDataSource *source; + struct wl_display *display; + struct wl_client *client; + struct wl_resource *resource; + uint32_t source_actions; + wl_fixed_t sx, sy; + + if (!grab->drag_focus_data_device) + return; + + client = wl_resource_get_client (surface->resource); + display = wl_client_get_display (client); + + grab->drag_focus_listener.notify = destroy_drag_focus; + wl_resource_add_destroy_listener (grab->drag_focus_data_device, + &grab->drag_focus_listener); + + resource = meta_wayland_data_offer_get_resource (offer); + + if (wl_resource_get_version (resource) >= + WL_DATA_OFFER_SOURCE_ACTIONS_SINCE_VERSION) + { + source = meta_wayland_data_offer_get_source (offer); + meta_wayland_data_source_get_actions (source, &source_actions); + wl_data_offer_send_source_actions (resource, source_actions); + } + + meta_wayland_pointer_get_relative_coordinates (grab->generic.pointer, + surface, &sx, &sy); + wl_data_device_send_enter (grab->drag_focus_data_device, + wl_display_next_serial (display), + surface->resource, sx, sy, resource); +} + +static void +meta_wayland_drag_dest_focus_out (MetaWaylandDataDevice *data_device, + MetaWaylandSurface *surface) +{ + MetaWaylandDragGrab *grab = data_device->current_grab; + + if (!grab->drag_focus_data_device) + return; + + wl_data_device_send_leave (grab->drag_focus_data_device); + wl_list_remove (&grab->drag_focus_listener.link); + grab->drag_focus_data_device = NULL; +} + +static void +meta_wayland_drag_dest_motion (MetaWaylandDataDevice *data_device, + MetaWaylandSurface *surface, + const ClutterEvent *event) +{ + MetaWaylandDragGrab *grab = data_device->current_grab; + wl_fixed_t sx, sy; + + if (!grab->drag_focus_data_device) + return; + + meta_wayland_pointer_get_relative_coordinates (grab->generic.pointer, + grab->drag_focus, + &sx, &sy); + wl_data_device_send_motion (grab->drag_focus_data_device, + clutter_event_get_time (event), + sx, sy); +} + +static void +meta_wayland_drag_dest_drop (MetaWaylandDataDevice *data_device, + MetaWaylandSurface *surface) +{ + MetaWaylandDragGrab *grab = data_device->current_grab; + + if (!grab->drag_focus_data_device) + return; + + wl_data_device_send_drop (grab->drag_focus_data_device); +} + +static void +meta_wayland_drag_dest_update (MetaWaylandDataDevice *data_device, + MetaWaylandSurface *surface) +{ +} + +static const MetaWaylandDragDestFuncs meta_wayland_drag_dest_funcs = { + meta_wayland_drag_dest_focus_in, + meta_wayland_drag_dest_focus_out, + meta_wayland_drag_dest_motion, + meta_wayland_drag_dest_drop, + meta_wayland_drag_dest_update +}; + +const MetaWaylandDragDestFuncs * +meta_wayland_data_device_get_drag_dest_funcs (void) +{ + return &meta_wayland_drag_dest_funcs; +} + +static void +dnd_data_source_destroyed (gpointer data, + GObject *object_was_here) +{ + MetaWaylandDataDevice *data_device = data; + + data_device->dnd_data_source = NULL; + unset_selection_source (data_device, META_SELECTION_DND); +} + +void +meta_wayland_data_device_set_dnd_source (MetaWaylandDataDevice *data_device, + MetaWaylandDataSource *source) +{ + if (data_device->dnd_data_source == source) + return; + + if (data_device->dnd_data_source) + { + g_object_weak_unref (G_OBJECT (data_device->dnd_data_source), + dnd_data_source_destroyed, + data_device); + } + + data_device->dnd_data_source = source; + + if (source) + { + g_object_weak_ref (G_OBJECT (source), + dnd_data_source_destroyed, + data_device); + } +} + +void +meta_wayland_data_device_set_selection (MetaWaylandDataDevice *data_device, + MetaWaylandDataSource *source, + guint32 serial) +{ + MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device); + MetaSelectionSource *selection_source; + + if (data_device->selection_data_source && + data_device->selection_serial - serial < UINT32_MAX / 2) + return; + + if (data_device->selection_data_source) + { + g_object_weak_unref (G_OBJECT (data_device->selection_data_source), + selection_data_source_destroyed, + data_device); + data_device->selection_data_source = NULL; + } + + data_device->selection_data_source = source; + data_device->selection_serial = serial; + + if (source) + { + meta_wayland_data_source_set_seat (source, seat); + g_object_weak_ref (G_OBJECT (source), + selection_data_source_destroyed, + data_device); + + selection_source = meta_selection_source_wayland_new (source); + } + else + { + selection_source = g_object_new (META_TYPE_SELECTION_SOURCE_MEMORY, NULL); + } + + set_selection_source (data_device, META_SELECTION_CLIPBOARD, + selection_source); + g_object_unref (selection_source); +} + +static void +data_device_set_selection (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *source_resource, + guint32 serial) +{ + MetaWaylandDataDevice *data_device = wl_resource_get_user_data (resource); + MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device); + MetaWaylandDataSource *source; + + if (source_resource) + source = wl_resource_get_user_data (source_resource); + else + source = NULL; + + if (source) + { + if (meta_wayland_data_source_get_actions (source, NULL)) + { + wl_resource_post_error(source_resource, + WL_DATA_SOURCE_ERROR_INVALID_SOURCE, + "cannot set drag-and-drop source as selection"); + return; + } + } + + if (wl_resource_get_client (resource) != + meta_wayland_keyboard_get_focus_client (seat->keyboard)) + return; + + /* FIXME: Store serial and check against incoming serial here. */ + meta_wayland_data_device_set_selection (data_device, source, serial); +} + +static const struct wl_data_device_interface data_device_interface = { + data_device_start_drag, + data_device_set_selection, + default_destructor, +}; + +static void +create_data_source (struct wl_client *client, + struct wl_resource *resource, guint32 id) +{ + struct wl_resource *source_resource; + + source_resource = wl_resource_create (client, &wl_data_source_interface, + wl_resource_get_version (resource), id); + meta_wayland_data_source_new (source_resource); +} + +static void +owner_changed_cb (MetaSelection *selection, + MetaSelectionType selection_type, + MetaSelectionSource *new_owner, + MetaWaylandDataDevice *data_device) +{ + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + MetaWaylandSeat *seat = compositor->seat; + struct wl_resource *data_device_resource; + struct wl_client *focus_client; + + focus_client = meta_wayland_keyboard_get_focus_client (seat->keyboard); + if (!focus_client) + return; + + if (selection_type == META_SELECTION_CLIPBOARD) + { + wl_resource_for_each (data_device_resource, &data_device->focus_resource_list) + { + struct wl_resource *offer = NULL; + + if (new_owner) + { + offer = create_and_send_clipboard_offer (data_device, + data_device_resource); + } + + wl_data_device_send_selection (data_device_resource, offer); + } + } +} + +static void +ensure_owners_changed_handler_connected (MetaWaylandDataDevice *data_device) +{ + if (data_device->selection_owner_signal_id != 0) + return; + + data_device->selection_owner_signal_id = + g_signal_connect (meta_display_get_selection (meta_get_display ()), + "owner-changed", + G_CALLBACK (owner_changed_cb), data_device); +} + +static void +get_data_device (struct wl_client *client, + struct wl_resource *manager_resource, + guint32 id, struct wl_resource *seat_resource) +{ + MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); + struct wl_resource *cr; + + cr = wl_resource_create (client, &wl_data_device_interface, wl_resource_get_version (manager_resource), id); + wl_resource_set_implementation (cr, &data_device_interface, &seat->data_device, unbind_resource); + wl_list_insert (&seat->data_device.resource_list, wl_resource_get_link (cr)); + + ensure_owners_changed_handler_connected (&seat->data_device); +} + +static const struct wl_data_device_manager_interface manager_interface = { + create_data_source, + get_data_device +}; + +static void +bind_manager (struct wl_client *client, + void *data, guint32 version, guint32 id) +{ + struct wl_resource *resource; + resource = wl_resource_create (client, &wl_data_device_manager_interface, version, id); + wl_resource_set_implementation (resource, &manager_interface, NULL, NULL); +} + +void +meta_wayland_data_device_manager_init (MetaWaylandCompositor *compositor) +{ + if (wl_global_create (compositor->wayland_display, + &wl_data_device_manager_interface, + META_WL_DATA_DEVICE_MANAGER_VERSION, + NULL, bind_manager) == NULL) + g_error ("Could not create data_device"); +} + +void +meta_wayland_data_device_init (MetaWaylandDataDevice *data_device) +{ + wl_list_init (&data_device->resource_list); + wl_list_init (&data_device->focus_resource_list); +} + +static struct wl_resource * +create_and_send_clipboard_offer (MetaWaylandDataDevice *data_device, + struct wl_resource *target) +{ + MetaWaylandDataOffer *offer; + MetaDisplay *display = meta_get_display (); + struct wl_resource *resource; + GList *mimetypes, *l; + + mimetypes = meta_selection_get_mimetypes (meta_display_get_selection (display), + META_SELECTION_CLIPBOARD); + if (!mimetypes) + return NULL; + + offer = meta_wayland_data_offer_new (META_SELECTION_CLIPBOARD, NULL, target); + resource = meta_wayland_data_offer_get_resource (offer); + + wl_data_device_send_data_offer (target, resource); + + for (l = mimetypes; l; l = l->next) + wl_data_offer_send_offer (resource, l->data); + + g_list_free_full (mimetypes, g_free); + + return resource; +} + +void +meta_wayland_data_device_set_keyboard_focus (MetaWaylandDataDevice *data_device) +{ + MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device); + struct wl_client *focus_client; + struct wl_resource *data_device_resource; + + focus_client = meta_wayland_keyboard_get_focus_client (seat->keyboard); + + if (focus_client == data_device->focus_client) + return; + + data_device->focus_client = focus_client; + move_resources (&data_device->resource_list, + &data_device->focus_resource_list); + + if (!focus_client) + return; + + move_resources_for_client (&data_device->focus_resource_list, + &data_device->resource_list, + focus_client); + + wl_resource_for_each (data_device_resource, &data_device->focus_resource_list) + { + struct wl_resource *offer; + + offer = create_and_send_clipboard_offer (data_device, data_device_resource); + wl_data_device_send_selection (data_device_resource, offer); + } +} + +gboolean +meta_wayland_data_device_is_dnd_surface (MetaWaylandDataDevice *data_device, + MetaWaylandSurface *surface) +{ + return data_device->current_grab && + data_device->current_grab->drag_surface == surface; +} + +MetaWaylandDragGrab * +meta_wayland_data_device_get_current_grab (MetaWaylandDataDevice *data_device) +{ + return data_device->current_grab; +} + +void +meta_wayland_data_device_unset_dnd_selection (MetaWaylandDataDevice *data_device) +{ + unset_selection_source (data_device, META_SELECTION_DND); +} diff --git a/src/wayland/meta-wayland-data-device.h b/src/wayland/meta-wayland-data-device.h new file mode 100644 index 000000000..840893389 --- /dev/null +++ b/src/wayland/meta-wayland-data-device.h @@ -0,0 +1,91 @@ +/* + * Copyright © 2008 Kristian Høgsberg + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef META_WAYLAND_DATA_DEVICE_H +#define META_WAYLAND_DATA_DEVICE_H + +#include <glib-object.h> +#include <wayland-server.h> + +#include "clutter/clutter.h" +#include "meta/meta-selection-source.h" +#include "wayland/meta-wayland-data-offer.h" +#include "wayland/meta-wayland-data-source.h" +#include "wayland/meta-wayland-types.h" + +typedef struct _MetaWaylandDragGrab MetaWaylandDragGrab; +typedef struct _MetaWaylandDataSourceFuncs MetaWaylandDataSourceFuncs; + +struct _MetaWaylandDataDevice +{ + uint32_t selection_serial; + MetaWaylandDataSource *selection_data_source; + MetaWaylandDataSource *dnd_data_source; + struct wl_list resource_list; + struct wl_list focus_resource_list; + MetaWaylandDragGrab *current_grab; + struct wl_client *focus_client; + + guint selection_owner_signal_id; + + MetaSelectionSource *owners[META_N_SELECTION_TYPES]; +}; + +void meta_wayland_data_device_manager_init (MetaWaylandCompositor *compositor); + +void meta_wayland_data_device_init (MetaWaylandDataDevice *data_device); + +void meta_wayland_data_device_set_keyboard_focus (MetaWaylandDataDevice *data_device); + +gboolean meta_wayland_data_device_is_dnd_surface (MetaWaylandDataDevice *data_device, + MetaWaylandSurface *surface); + +MetaWaylandDragGrab * + meta_wayland_data_device_get_current_grab (MetaWaylandDataDevice *data_device); + +void meta_wayland_data_device_set_dnd_source (MetaWaylandDataDevice *data_device, + MetaWaylandDataSource *source); +void meta_wayland_data_device_set_selection (MetaWaylandDataDevice *data_device, + MetaWaylandDataSource *source, + guint32 serial); +void meta_wayland_data_device_unset_dnd_selection (MetaWaylandDataDevice *data_device); + +const MetaWaylandDragDestFuncs * + meta_wayland_data_device_get_drag_dest_funcs (void); + +void meta_wayland_data_device_start_drag (MetaWaylandDataDevice *data_device, + struct wl_client *client, + const MetaWaylandPointerGrabInterface *funcs, + MetaWaylandSurface *surface, + MetaWaylandDataSource *source, + MetaWaylandSurface *icon_surface); + +void meta_wayland_data_device_end_drag (MetaWaylandDataDevice *data_device); + +void meta_wayland_drag_grab_set_focus (MetaWaylandDragGrab *drag_grab, + MetaWaylandSurface *surface); +MetaWaylandSurface * + meta_wayland_drag_grab_get_focus (MetaWaylandDragGrab *drag_grab); +void meta_wayland_drag_grab_update_feedback_actor (MetaWaylandDragGrab *drag_grab, + ClutterEvent *event); + +#endif /* META_WAYLAND_DATA_DEVICE_H */ diff --git a/src/wayland/meta-wayland-data-offer-primary-legacy.c b/src/wayland/meta-wayland-data-offer-primary-legacy.c new file mode 100644 index 000000000..5fe9523d3 --- /dev/null +++ b/src/wayland/meta-wayland-data-offer-primary-legacy.c @@ -0,0 +1,139 @@ +/* + * Copyright © 2011 Kristian Høgsberg + * 2020 Red Hat Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "config.h" + +#include "meta-wayland-data-offer-primary-legacy.h" + +#include <gio/gunixoutputstream.h> +#include <glib-unix.h> +#include <glib.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "core/display-private.h" +#include "gtk-primary-selection-server-protocol.h" +#include "wayland/meta-wayland-data-offer.h" + +static void +transfer_cb (MetaSelection *selection, + GAsyncResult *res, + GOutputStream *stream) +{ + GError *error = NULL; + + if (!meta_selection_transfer_finish (selection, res, &error)) + { + g_warning ("Could not fetch selection data: %s", error->message); + g_error_free (error); + } + + g_output_stream_close (stream, NULL, NULL); + g_object_unref (stream); +} + +static void +primary_offer_receive (struct wl_client *client, + struct wl_resource *resource, + const char *mime_type, + int32_t fd) +{ + MetaDisplay *display = meta_get_display (); + GOutputStream *stream; + GList *mime_types; + gboolean found; + + mime_types = meta_selection_get_mimetypes (meta_display_get_selection (display), + META_SELECTION_PRIMARY); + found = g_list_find_custom (mime_types, mime_type, (GCompareFunc) g_strcmp0) != NULL; + g_list_free_full (mime_types, g_free); + + if (!found) + { + close (fd); + return; + } + + stream = g_unix_output_stream_new (fd, TRUE); + meta_selection_transfer_async (meta_display_get_selection (display), + META_SELECTION_PRIMARY, + mime_type, + -1, + stream, + NULL, + (GAsyncReadyCallback) transfer_cb, + stream); +} + +static void +primary_offer_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static const struct gtk_primary_selection_offer_interface primary_offer_interface = { + primary_offer_receive, + primary_offer_destroy, +}; + +static void +destroy_primary_offer (struct wl_resource *resource) +{ + MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource); + + if (offer->source) + { + if (offer == meta_wayland_data_source_get_current_offer (offer->source)) + { + meta_wayland_data_source_cancel (offer->source); + meta_wayland_data_source_set_current_offer (offer->source, NULL); + } + + g_object_remove_weak_pointer (G_OBJECT (offer->source), + (gpointer *)&offer->source); + offer->source = NULL; + } + + meta_display_sync_wayland_input_focus (meta_get_display ()); + g_slice_free (MetaWaylandDataOffer, offer); +} + +MetaWaylandDataOffer * +meta_wayland_data_offer_primary_legacy_new (struct wl_resource *target) +{ + MetaWaylandDataOffer *offer; + + offer = g_slice_new0 (MetaWaylandDataOffer); + offer->selection_type = META_SELECTION_PRIMARY; + offer->resource = wl_resource_create (wl_resource_get_client (target), + >k_primary_selection_offer_interface, + wl_resource_get_version (target), 0); + wl_resource_set_implementation (offer->resource, + &primary_offer_interface, + offer, + destroy_primary_offer); + return offer; +} diff --git a/src/wayland/meta-wayland-data-offer-primary-legacy.h b/src/wayland/meta-wayland-data-offer-primary-legacy.h new file mode 100644 index 000000000..96a32c34e --- /dev/null +++ b/src/wayland/meta-wayland-data-offer-primary-legacy.h @@ -0,0 +1,31 @@ +/* + * Copyright © 2011 Kristian Høgsberg + * 2020 Red Hat Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef META_WAYLAND_DATA_OFFER_PRIMARY_LEGACY_H +#define META_WAYLAND_DATA_OFFER_PRIMARY_LEGACY_H + +#include "meta-wayland-data-offer.h" + +MetaWaylandDataOffer * meta_wayland_data_offer_primary_legacy_new (struct wl_resource *target); + +#endif /* META_WAYLAND_DATA_OFFER_PRIMARY_LEGACY_H */ diff --git a/src/wayland/meta-wayland-data-offer-primary.c b/src/wayland/meta-wayland-data-offer-primary.c new file mode 100644 index 000000000..a2a4dfe80 --- /dev/null +++ b/src/wayland/meta-wayland-data-offer-primary.c @@ -0,0 +1,139 @@ +/* + * Copyright © 2011 Kristian Høgsberg + * 2020 Red Hat Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "config.h" + +#include "meta-wayland-data-offer-primary.h" + +#include <gio/gunixoutputstream.h> +#include <glib-unix.h> +#include <glib.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "core/display-private.h" +#include "primary-selection-unstable-v1-server-protocol.h" +#include "wayland/meta-wayland-data-offer.h" + +static void +transfer_cb (MetaSelection *selection, + GAsyncResult *res, + GOutputStream *stream) +{ + GError *error = NULL; + + if (!meta_selection_transfer_finish (selection, res, &error)) + { + g_warning ("Could not fetch selection data: %s", error->message); + g_error_free (error); + } + + g_output_stream_close (stream, NULL, NULL); + g_object_unref (stream); +} + +static void +primary_offer_receive (struct wl_client *client, + struct wl_resource *resource, + const char *mime_type, + int32_t fd) +{ + MetaDisplay *display = meta_get_display (); + GOutputStream *stream; + GList *mime_types; + gboolean found; + + mime_types = meta_selection_get_mimetypes (meta_display_get_selection (display), + META_SELECTION_PRIMARY); + found = g_list_find_custom (mime_types, mime_type, (GCompareFunc) g_strcmp0) != NULL; + g_list_free_full (mime_types, g_free); + + if (!found) + { + close (fd); + return; + } + + stream = g_unix_output_stream_new (fd, TRUE); + meta_selection_transfer_async (meta_display_get_selection (display), + META_SELECTION_PRIMARY, + mime_type, + -1, + stream, + NULL, + (GAsyncReadyCallback) transfer_cb, + stream); +} + +static void +primary_offer_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static const struct zwp_primary_selection_offer_v1_interface primary_offer_interface = { + primary_offer_receive, + primary_offer_destroy, +}; + +static void +destroy_primary_offer (struct wl_resource *resource) +{ + MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource); + + if (offer->source) + { + if (offer == meta_wayland_data_source_get_current_offer (offer->source)) + { + meta_wayland_data_source_cancel (offer->source); + meta_wayland_data_source_set_current_offer (offer->source, NULL); + } + + g_object_remove_weak_pointer (G_OBJECT (offer->source), + (gpointer *)&offer->source); + offer->source = NULL; + } + + meta_display_sync_wayland_input_focus (meta_get_display ()); + g_slice_free (MetaWaylandDataOffer, offer); +} + +MetaWaylandDataOffer * +meta_wayland_data_offer_primary_new (struct wl_resource *target) +{ + MetaWaylandDataOffer *offer; + + offer = g_slice_new0 (MetaWaylandDataOffer); + offer->selection_type = META_SELECTION_PRIMARY; + offer->resource = wl_resource_create (wl_resource_get_client (target), + &zwp_primary_selection_offer_v1_interface, + wl_resource_get_version (target), 0); + wl_resource_set_implementation (offer->resource, + &primary_offer_interface, + offer, + destroy_primary_offer); + return offer; +} diff --git a/src/wayland/meta-wayland-data-offer-primary.h b/src/wayland/meta-wayland-data-offer-primary.h new file mode 100644 index 000000000..cf59fb5c7 --- /dev/null +++ b/src/wayland/meta-wayland-data-offer-primary.h @@ -0,0 +1,31 @@ +/* + * Copyright © 2011 Kristian Høgsberg + * 2020 Red Hat Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef META_WAYLAND_DATA_OFFER_PRIMARY_H +#define META_WAYLAND_DATA_OFFER_PRIMARY_H + +#include "meta-wayland-data-offer.h" + +MetaWaylandDataOffer * meta_wayland_data_offer_primary_new (struct wl_resource *target); + +#endif /* META_WAYLAND_DATA_OFFER_PRIMARY_H */ diff --git a/src/wayland/meta-wayland-data-offer.c b/src/wayland/meta-wayland-data-offer.c new file mode 100644 index 000000000..fa14fae1a --- /dev/null +++ b/src/wayland/meta-wayland-data-offer.c @@ -0,0 +1,327 @@ +/* + * Copyright © 2011 Kristian Høgsberg + * 2020 Red Hat Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "config.h" + +#include <gio/gunixoutputstream.h> +#include <glib-unix.h> +#include <glib.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "meta/meta-selection.h" +#include "wayland/meta-wayland-data-device.h" +#include "wayland/meta-wayland-private.h" + +#include "meta-wayland-data-offer.h" + +#define ALL_ACTIONS (WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY | \ + WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE | \ + WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK) + +static void +data_offer_accept (struct wl_client *client, + struct wl_resource *resource, + guint32 serial, + const char *mime_type) +{ + MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource); + + /* FIXME: Check that client is currently focused by the input + * device that is currently dragging this data source. Should + * this be a wl_data_device request? */ + + if (offer->source) + { + meta_wayland_data_source_target (offer->source, mime_type); + meta_wayland_data_source_set_has_target (offer->source, + mime_type != NULL); + } + + offer->accepted = mime_type != NULL; +} + +static void +transfer_cb (MetaSelection *selection, + GAsyncResult *res, + GOutputStream *stream) +{ + GError *error = NULL; + + if (!meta_selection_transfer_finish (selection, res, &error)) + { + g_warning ("Could not fetch selection data: %s", error->message); + g_error_free (error); + } + + g_output_stream_close (stream, NULL, NULL); + g_object_unref (stream); +} + +static void +data_offer_receive (struct wl_client *client, struct wl_resource *resource, + const char *mime_type, int32_t fd) +{ + MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource); + MetaDisplay *display = meta_get_display (); + MetaSelectionType selection_type; + GList *mime_types; + gboolean found; + + selection_type = offer->selection_type; + mime_types = meta_selection_get_mimetypes (meta_display_get_selection (display), + selection_type); + found = g_list_find_custom (mime_types, mime_type, (GCompareFunc) g_strcmp0) != NULL; + g_list_free_full (mime_types, g_free); + + if (found) + { + GOutputStream *stream; + + stream = g_unix_output_stream_new (fd, TRUE); + meta_selection_transfer_async (meta_display_get_selection (display), + selection_type, + mime_type, + -1, + stream, + NULL, + (GAsyncReadyCallback) transfer_cb, + stream); + } + else + { + close (fd); + } +} + +static void +data_offer_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +data_offer_finish (struct wl_client *client, + struct wl_resource *resource) +{ + MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource); + enum wl_data_device_manager_dnd_action current_action; + + if (!offer->source || + offer != meta_wayland_data_source_get_current_offer (offer->source)) + return; + + if (!offer->accepted || !offer->action_sent) + { + wl_resource_post_error (offer->resource, + WL_DATA_OFFER_ERROR_INVALID_FINISH, + "premature finish request"); + return; + } + + current_action = meta_wayland_data_source_get_current_action (offer->source); + + if (current_action == WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE || + current_action == WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK) + { + wl_resource_post_error (offer->resource, + WL_DATA_OFFER_ERROR_INVALID_OFFER, + "offer finished with an invalid action"); + return; + } + + meta_wayland_data_source_notify_finish (offer->source); +} + +static void +data_offer_set_actions (struct wl_client *client, + struct wl_resource *resource, + uint32_t dnd_actions, + uint32_t preferred_action) +{ + MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource); + + if (dnd_actions & ~(ALL_ACTIONS)) + { + wl_resource_post_error (offer->resource, + WL_DATA_OFFER_ERROR_INVALID_ACTION_MASK, + "invalid actions mask %x", dnd_actions); + return; + } + + if (preferred_action && + (!(preferred_action & dnd_actions) || + __builtin_popcount (preferred_action) > 1)) + { + wl_resource_post_error (offer->resource, + WL_DATA_OFFER_ERROR_INVALID_ACTION, + "invalid action %x", preferred_action); + return; + } + + offer->dnd_actions = dnd_actions; + offer->preferred_dnd_action = preferred_action; + + meta_wayland_data_offer_update_action (offer); +} + +static const struct wl_data_offer_interface data_offer_interface = { + data_offer_accept, + data_offer_receive, + data_offer_destroy, + data_offer_finish, + data_offer_set_actions, +}; + +static void +destroy_data_offer (struct wl_resource *resource) +{ + MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource); + MetaWaylandSeat *seat; + + if (offer->source) + { + seat = meta_wayland_data_source_get_seat (offer->source); + + if (offer == meta_wayland_data_source_get_current_offer (offer->source)) + { + if (seat->data_device.dnd_data_source == offer->source) + { + if (wl_resource_get_version (offer->resource) < + WL_DATA_OFFER_ACTION_SINCE_VERSION) + meta_wayland_data_source_notify_finish (offer->source); + else if (meta_wayland_data_source_get_drop_performed (offer->source)) + meta_wayland_data_source_cancel (offer->source); + } + else + { + meta_wayland_data_source_set_current_offer (offer->source, NULL); + meta_wayland_data_source_set_has_target (offer->source, FALSE); + } + } + + g_object_remove_weak_pointer (G_OBJECT (offer->source), + (gpointer *)&offer->source); + offer->source = NULL; + } + + meta_display_sync_wayland_input_focus (meta_get_display ()); + g_slice_free (MetaWaylandDataOffer, offer); +} + +MetaWaylandDataOffer * +meta_wayland_data_offer_new (MetaSelectionType selection_type, + MetaWaylandDataSource *source, + struct wl_resource *target) +{ + MetaWaylandDataOffer *offer; + + offer = g_slice_new0 (MetaWaylandDataOffer); + offer->selection_type = selection_type; + offer->resource = wl_resource_create (wl_resource_get_client (target), + &wl_data_offer_interface, + wl_resource_get_version (target), 0); + wl_resource_set_implementation (offer->resource, + &data_offer_interface, + offer, + destroy_data_offer); + if (source) + { + offer->source = source; + g_object_add_weak_pointer (G_OBJECT (source), (gpointer *)&offer->source); + } + + return offer; +} + +static enum wl_data_device_manager_dnd_action +data_offer_choose_action (MetaWaylandDataOffer *offer) +{ + MetaWaylandDataSource *source = offer->source; + uint32_t actions, user_action, available_actions; + + if (wl_resource_get_version (offer->resource) < + WL_DATA_OFFER_ACTION_SINCE_VERSION) + return WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY; + + meta_wayland_data_source_get_actions (source, &actions); + user_action = meta_wayland_data_source_get_user_action (source); + + available_actions = actions & offer->dnd_actions; + + if (!available_actions) + return WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE; + + /* If the user is forcing an action, go for it */ + if ((user_action & available_actions) != 0) + return user_action; + + /* If the dest side has a preferred DnD action, use it */ + if ((offer->preferred_dnd_action & available_actions) != 0) + return offer->preferred_dnd_action; + + /* Use the first found action, in bit order */ + return 1 << (ffs (available_actions) - 1); +} + +void +meta_wayland_data_offer_update_action (MetaWaylandDataOffer *offer) +{ + enum wl_data_device_manager_dnd_action current_action, action; + MetaWaylandDataSource *source; + + if (!offer->source) + return; + + source = offer->source; + current_action = meta_wayland_data_source_get_current_action (source); + action = data_offer_choose_action (offer); + + if (current_action == action) + return; + + meta_wayland_data_source_set_current_action (source, action); + + if (!meta_wayland_data_source_get_in_ask (source) && + wl_resource_get_version (offer->resource) >= + WL_DATA_OFFER_ACTION_SINCE_VERSION) + { + wl_data_offer_send_action (offer->resource, action); + offer->action_sent = TRUE; + } +} + +struct wl_resource * +meta_wayland_data_offer_get_resource (MetaWaylandDataOffer *offer) +{ + return offer->resource; +} + +MetaWaylandDataSource * +meta_wayland_data_offer_get_source (MetaWaylandDataOffer *offer) +{ + return offer->source; +} diff --git a/src/wayland/meta-wayland-data-offer.h b/src/wayland/meta-wayland-data-offer.h new file mode 100644 index 000000000..811aa0935 --- /dev/null +++ b/src/wayland/meta-wayland-data-offer.h @@ -0,0 +1,51 @@ +/* + * Copyright © 2011 Kristian Høgsberg + * 2020 Red Hat Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef META_WAYLAND_DATA_OFFER_H +#define META_WAYLAND_DATA_OFFER_H + +#include "meta/meta-selection.h" +#include "wayland/meta-wayland-data-source.h" + +struct _MetaWaylandDataOffer +{ + struct wl_resource *resource; + MetaWaylandDataSource *source; + struct wl_listener source_destroy_listener; + gboolean accepted; + gboolean action_sent; + uint32_t dnd_actions; + enum wl_data_device_manager_dnd_action preferred_dnd_action; + MetaSelectionType selection_type; +}; + +MetaWaylandDataOffer * meta_wayland_data_offer_new (MetaSelectionType selection_type, + MetaWaylandDataSource *source, + struct wl_resource *resource); + +void meta_wayland_data_offer_update_action (MetaWaylandDataOffer *offer); + +struct wl_resource * meta_wayland_data_offer_get_resource (MetaWaylandDataOffer *offer); +MetaWaylandDataSource * meta_wayland_data_offer_get_source (MetaWaylandDataOffer *offer); + +#endif /* META_WAYLAND_DATA_OFFER_H */ diff --git a/src/wayland/meta-wayland-data-source-primary-legacy.c b/src/wayland/meta-wayland-data-source-primary-legacy.c new file mode 100644 index 000000000..a7a1788ae --- /dev/null +++ b/src/wayland/meta-wayland-data-source-primary-legacy.c @@ -0,0 +1,117 @@ +/* + * Copyright © 2011 Kristian Høgsberg + * 2020 Red Hat Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "config.h" + +#include <unistd.h> + +#include "gtk-primary-selection-server-protocol.h" +#include "wayland/meta-wayland-data-source-primary-legacy.h" + +typedef struct _MetaWaylandDataSourcePrimaryLegacy +{ + MetaWaylandDataSource parent; +} MetaWaylandDataSourcePrimaryLegacy; + +G_DEFINE_TYPE (MetaWaylandDataSourcePrimaryLegacy, meta_wayland_data_source_primary_legacy, + META_TYPE_WAYLAND_DATA_SOURCE); + +static void +primary_source_offer (struct wl_client *client, + struct wl_resource *resource, + const char *type) +{ + MetaWaylandDataSource *source = wl_resource_get_user_data (resource); + + if (!meta_wayland_data_source_add_mime_type (source, type)) + wl_resource_post_no_memory (resource); +} + +static void +primary_source_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static struct gtk_primary_selection_source_interface primary_source_interface = { + primary_source_offer, + primary_source_destroy, +}; + +static void +destroy_primary_source (struct wl_resource *resource) +{ + MetaWaylandDataSource *source = wl_resource_get_user_data (resource); + + meta_wayland_data_source_set_resource (source, NULL); + g_object_unref (source); +} + +static void +meta_wayland_data_source_primary_legacy_send (MetaWaylandDataSource *source, + const gchar *mime_type, + gint fd) +{ + struct wl_resource *resource = meta_wayland_data_source_get_resource (source); + + gtk_primary_selection_source_send_send (resource, mime_type, fd); + close (fd); +} + +static void +meta_wayland_data_source_primary_legacy_cancel (MetaWaylandDataSource *source) +{ + struct wl_resource *resource = meta_wayland_data_source_get_resource (source); + + if (resource) + gtk_primary_selection_source_send_cancelled (resource); +} + +static void +meta_wayland_data_source_primary_legacy_init (MetaWaylandDataSourcePrimaryLegacy *source_primary) +{ +} + +static void +meta_wayland_data_source_primary_legacy_class_init (MetaWaylandDataSourcePrimaryLegacyClass *klass) +{ + MetaWaylandDataSourceClass *data_source_class = + META_WAYLAND_DATA_SOURCE_CLASS (klass); + + data_source_class->send = meta_wayland_data_source_primary_legacy_send; + data_source_class->cancel = meta_wayland_data_source_primary_legacy_cancel; +} + +MetaWaylandDataSource * +meta_wayland_data_source_primary_legacy_new (struct wl_resource *resource) +{ + MetaWaylandDataSource *source_primary = + g_object_new (META_TYPE_WAYLAND_DATA_SOURCE_PRIMARY_LEGACY, NULL); + + meta_wayland_data_source_set_resource (source_primary, resource); + wl_resource_set_implementation (resource, &primary_source_interface, + source_primary, destroy_primary_source); + + return source_primary; +} diff --git a/src/wayland/meta-wayland-data-source-primary-legacy.h b/src/wayland/meta-wayland-data-source-primary-legacy.h new file mode 100644 index 000000000..2904807c8 --- /dev/null +++ b/src/wayland/meta-wayland-data-source-primary-legacy.h @@ -0,0 +1,37 @@ +/* + * Copyright © 2011 Kristian Høgsberg + * 2020 Red Hat Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef META_WAYLAND_DATA_SOURCE_PRIMARY_LEGACY_H +#define META_WAYLAND_DATA_SOURCE_PRIMARY_LEGACY_H + +#include "meta-wayland-data-source.h" + +#define META_TYPE_WAYLAND_DATA_SOURCE_PRIMARY_LEGACY (meta_wayland_data_source_primary_legacy_get_type ()) +G_DECLARE_FINAL_TYPE (MetaWaylandDataSourcePrimaryLegacy, + meta_wayland_data_source_primary_legacy, + META, WAYLAND_DATA_SOURCE_PRIMARY_LEGACY, + MetaWaylandDataSource); + +MetaWaylandDataSource * meta_wayland_data_source_primary_legacy_new (struct wl_resource *resource); + +#endif /* META_WAYLAND_DATA_SOURCE_PRIMARY_LEGACY_H */ diff --git a/src/wayland/meta-wayland-data-source-primary.c b/src/wayland/meta-wayland-data-source-primary.c new file mode 100644 index 000000000..0229c840a --- /dev/null +++ b/src/wayland/meta-wayland-data-source-primary.c @@ -0,0 +1,117 @@ +/* + * Copyright © 2011 Kristian Høgsberg + * 2020 Red Hat Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "config.h" + +#include <unistd.h> + +#include "primary-selection-unstable-v1-server-protocol.h" +#include "wayland/meta-wayland-data-source-primary.h" + +typedef struct _MetaWaylandDataSourcePrimary +{ + MetaWaylandDataSource parent; +} MetaWaylandDataSourcePrimary; + +G_DEFINE_TYPE (MetaWaylandDataSourcePrimary, meta_wayland_data_source_primary, + META_TYPE_WAYLAND_DATA_SOURCE); + +static void +primary_source_offer (struct wl_client *client, + struct wl_resource *resource, + const char *type) +{ + MetaWaylandDataSource *source = wl_resource_get_user_data (resource); + + if (!meta_wayland_data_source_add_mime_type (source, type)) + wl_resource_post_no_memory (resource); +} + +static void +primary_source_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static struct zwp_primary_selection_source_v1_interface primary_source_interface = { + primary_source_offer, + primary_source_destroy, +}; + +static void +destroy_primary_source (struct wl_resource *resource) +{ + MetaWaylandDataSource *source = wl_resource_get_user_data (resource); + + meta_wayland_data_source_set_resource (source, NULL); + g_object_unref (source); +} + +static void +meta_wayland_data_source_primary_send (MetaWaylandDataSource *source, + const gchar *mime_type, + gint fd) +{ + struct wl_resource *resource = meta_wayland_data_source_get_resource (source); + + zwp_primary_selection_source_v1_send_send (resource, mime_type, fd); + close (fd); +} + +static void +meta_wayland_data_source_primary_cancel (MetaWaylandDataSource *source) +{ + struct wl_resource *resource = meta_wayland_data_source_get_resource (source); + + if (resource) + zwp_primary_selection_source_v1_send_cancelled (resource); +} + +static void +meta_wayland_data_source_primary_init (MetaWaylandDataSourcePrimary *source_primary) +{ +} + +static void +meta_wayland_data_source_primary_class_init (MetaWaylandDataSourcePrimaryClass *klass) +{ + MetaWaylandDataSourceClass *data_source_class = + META_WAYLAND_DATA_SOURCE_CLASS (klass); + + data_source_class->send = meta_wayland_data_source_primary_send; + data_source_class->cancel = meta_wayland_data_source_primary_cancel; +} + +MetaWaylandDataSource * +meta_wayland_data_source_primary_new (struct wl_resource *resource) +{ + MetaWaylandDataSource *source_primary = + g_object_new (META_TYPE_WAYLAND_DATA_SOURCE_PRIMARY, NULL); + + meta_wayland_data_source_set_resource (source_primary, resource); + wl_resource_set_implementation (resource, &primary_source_interface, + source_primary, destroy_primary_source); + + return source_primary; +} diff --git a/src/wayland/meta-wayland-data-source-primary.h b/src/wayland/meta-wayland-data-source-primary.h new file mode 100644 index 000000000..78ab55c19 --- /dev/null +++ b/src/wayland/meta-wayland-data-source-primary.h @@ -0,0 +1,37 @@ +/* + * Copyright © 2011 Kristian Høgsberg + * 2020 Red Hat Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef META_WAYLAND_DATA_SOURCE_PRIMARY_H +#define META_WAYLAND_DATA_SOURCE_PRIMARY_H + +#include "meta-wayland-data-source.h" + +#define META_TYPE_WAYLAND_DATA_SOURCE_PRIMARY (meta_wayland_data_source_primary_get_type ()) +G_DECLARE_FINAL_TYPE (MetaWaylandDataSourcePrimary, + meta_wayland_data_source_primary, + META, WAYLAND_DATA_SOURCE_PRIMARY, + MetaWaylandDataSource); + +MetaWaylandDataSource * meta_wayland_data_source_primary_new (struct wl_resource *resource); + +#endif /* META_WAYLAND_DATA_SOURCE_PRIMARY_H */ diff --git a/src/wayland/meta-wayland-data-source.c b/src/wayland/meta-wayland-data-source.c new file mode 100644 index 000000000..93aa3fdc8 --- /dev/null +++ b/src/wayland/meta-wayland-data-source.c @@ -0,0 +1,523 @@ +/* + * Copyright © 2011 Kristian Høgsberg + * 2020 Red Hat Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "config.h" + +#include <unistd.h> + +#include "wayland/meta-wayland-data-source.h" +#include "wayland/meta-wayland-private.h" + +#define ALL_ACTIONS (WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY | \ + WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE | \ + WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK) + +typedef struct _MetaWaylandDataSourcePrivate +{ + struct wl_resource *resource; + MetaWaylandDataOffer *offer; + struct wl_array mime_types; + gboolean has_target; + uint32_t dnd_actions; + enum wl_data_device_manager_dnd_action user_dnd_action; + enum wl_data_device_manager_dnd_action current_dnd_action; + MetaWaylandSeat *seat; + guint actions_set : 1; + guint in_ask : 1; + guint drop_performed : 1; +} MetaWaylandDataSourcePrivate; + +G_DEFINE_TYPE_WITH_PRIVATE (MetaWaylandDataSource, meta_wayland_data_source, + G_TYPE_OBJECT); + +static void +meta_wayland_data_source_real_send (MetaWaylandDataSource *source, + const gchar *mime_type, + gint fd) +{ + MetaWaylandDataSourcePrivate *priv = + meta_wayland_data_source_get_instance_private (source); + + wl_data_source_send_send (priv->resource, mime_type, fd); + close (fd); +} + +static void +meta_wayland_data_source_real_target (MetaWaylandDataSource *source, + const gchar *mime_type) +{ + MetaWaylandDataSourcePrivate *priv = + meta_wayland_data_source_get_instance_private (source); + + wl_data_source_send_target (priv->resource, mime_type); +} + +static void +meta_wayland_data_source_real_cancel (MetaWaylandDataSource *source) +{ + MetaWaylandDataSourcePrivate *priv = + meta_wayland_data_source_get_instance_private (source); + + if (!priv->resource) + return; + + wl_data_source_send_cancelled (priv->resource); +} + +static void +meta_wayland_data_source_real_action (MetaWaylandDataSource *source, + enum wl_data_device_manager_dnd_action action) +{ + MetaWaylandDataSourcePrivate *priv = + meta_wayland_data_source_get_instance_private (source); + + if (wl_resource_get_version (priv->resource) >= + WL_DATA_SOURCE_ACTION_SINCE_VERSION) + wl_data_source_send_action (priv->resource, action); +} + +static void +meta_wayland_data_source_real_drop_performed (MetaWaylandDataSource *source) +{ + MetaWaylandDataSourcePrivate *priv = + meta_wayland_data_source_get_instance_private (source); + + if (wl_resource_get_version (priv->resource) >= + WL_DATA_SOURCE_DND_DROP_PERFORMED_SINCE_VERSION) + { + priv->drop_performed = TRUE; + wl_data_source_send_dnd_drop_performed (priv->resource); + } +} + +static void +meta_wayland_data_source_real_drag_finished (MetaWaylandDataSource *source) +{ + MetaWaylandDataSourcePrivate *priv = + meta_wayland_data_source_get_instance_private (source); + enum wl_data_device_manager_dnd_action action; + + if (meta_wayland_data_source_get_in_ask (source)) + { + action = meta_wayland_data_source_get_current_action (source); + meta_wayland_data_source_real_action (source, action); + } + + if (wl_resource_get_version (priv->resource) >= + WL_DATA_SOURCE_DND_FINISHED_SINCE_VERSION) + wl_data_source_send_dnd_finished (priv->resource); +} + +static void +meta_wayland_data_source_finalize (GObject *object) +{ + MetaWaylandDataSource *source = META_WAYLAND_DATA_SOURCE (object); + MetaWaylandDataSourcePrivate *priv = + meta_wayland_data_source_get_instance_private (source); + char **pos; + + wl_array_for_each (pos, &priv->mime_types) + g_free (*pos); + wl_array_release (&priv->mime_types); + + G_OBJECT_CLASS (meta_wayland_data_source_parent_class)->finalize (object); +} + +static void +meta_wayland_data_source_init (MetaWaylandDataSource *source) +{ + MetaWaylandDataSourcePrivate *priv = + meta_wayland_data_source_get_instance_private (source); + + wl_array_init (&priv->mime_types); + priv->current_dnd_action = -1; + priv->drop_performed = FALSE; +} + +static void +meta_wayland_data_source_class_init (MetaWaylandDataSourceClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_wayland_data_source_finalize; + + klass->send = meta_wayland_data_source_real_send; + klass->target = meta_wayland_data_source_real_target; + klass->cancel = meta_wayland_data_source_real_cancel; + klass->action = meta_wayland_data_source_real_action; + klass->drop_performed = meta_wayland_data_source_real_drop_performed; + klass->drag_finished = meta_wayland_data_source_real_drag_finished; +} + + +static void +data_source_offer (struct wl_client *client, + struct wl_resource *resource, const char *type) +{ + MetaWaylandDataSource *source = wl_resource_get_user_data (resource); + + if (!meta_wayland_data_source_add_mime_type (source, type)) + wl_resource_post_no_memory (resource); +} + +static void +data_source_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +data_source_set_actions (struct wl_client *client, + struct wl_resource *resource, + uint32_t dnd_actions) +{ + MetaWaylandDataSource *source = wl_resource_get_user_data (resource); + MetaWaylandDataSourcePrivate *priv = + meta_wayland_data_source_get_instance_private (source); + + if (priv->actions_set) + { + wl_resource_post_error (priv->resource, + WL_DATA_SOURCE_ERROR_INVALID_ACTION_MASK, + "cannot set actions more than once"); + return; + } + + if (dnd_actions & ~(ALL_ACTIONS)) + { + wl_resource_post_error (priv->resource, + WL_DATA_SOURCE_ERROR_INVALID_ACTION_MASK, + "invalid actions mask %x", dnd_actions); + return; + } + + if (meta_wayland_data_source_get_seat (source)) + { + wl_resource_post_error (priv->resource, + WL_DATA_SOURCE_ERROR_INVALID_ACTION_MASK, + "invalid action change after " + "wl_data_device.start_drag"); + return; + } + + meta_wayland_data_source_set_actions (source, dnd_actions); +} + +static struct wl_data_source_interface data_source_interface = { + data_source_offer, + data_source_destroy, + data_source_set_actions +}; + +static void +destroy_data_source (struct wl_resource *resource) +{ + MetaWaylandDataSource *source = wl_resource_get_user_data (resource); + + meta_wayland_data_source_set_resource (source, NULL); + g_object_unref (source); +} + +MetaWaylandDataSource * +meta_wayland_data_source_new (struct wl_resource *resource) +{ + MetaWaylandDataSource *source = + g_object_new (META_TYPE_WAYLAND_DATA_SOURCE, NULL); + MetaWaylandDataSourcePrivate *priv = + meta_wayland_data_source_get_instance_private (source); + + meta_wayland_data_source_set_resource (source, resource); + wl_resource_set_implementation (resource, &data_source_interface, + source, destroy_data_source); + + if (wl_resource_get_version (resource) < WL_DATA_SOURCE_ACTION_SINCE_VERSION) + { + priv->dnd_actions = priv->user_dnd_action = + WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY; + } + + return source; +} + +struct wl_resource * +meta_wayland_data_source_get_resource (MetaWaylandDataSource *source) +{ + MetaWaylandDataSourcePrivate *priv = + meta_wayland_data_source_get_instance_private (source); + + return priv->resource; +} + +void +meta_wayland_data_source_set_resource (MetaWaylandDataSource *source, + struct wl_resource *resource) +{ + MetaWaylandDataSourcePrivate *priv = + meta_wayland_data_source_get_instance_private (source); + + priv->resource = resource; +} + +gboolean +meta_wayland_data_source_get_in_ask (MetaWaylandDataSource *source) +{ + MetaWaylandDataSourcePrivate *priv = + meta_wayland_data_source_get_instance_private (source); + + return priv->in_ask; +} + +void +meta_wayland_data_source_update_in_ask (MetaWaylandDataSource *source) +{ + MetaWaylandDataSourcePrivate *priv = + meta_wayland_data_source_get_instance_private (source); + + priv->in_ask = + priv->current_dnd_action == WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK; +} + +void +meta_wayland_data_source_target (MetaWaylandDataSource *source, + const char *mime_type) +{ + if (META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->target) + META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->target (source, mime_type); +} + +void +meta_wayland_data_source_send (MetaWaylandDataSource *source, + const char *mime_type, + int fd) +{ + META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->send (source, mime_type, fd); +} + +gboolean +meta_wayland_data_source_has_target (MetaWaylandDataSource *source) +{ + MetaWaylandDataSourcePrivate *priv = + meta_wayland_data_source_get_instance_private (source); + + return priv->has_target; +} + +void +meta_wayland_data_source_set_seat (MetaWaylandDataSource *source, + MetaWaylandSeat *seat) +{ + MetaWaylandDataSourcePrivate *priv = + meta_wayland_data_source_get_instance_private (source); + + priv->seat = seat; +} + +MetaWaylandSeat * +meta_wayland_data_source_get_seat (MetaWaylandDataSource *source) +{ + MetaWaylandDataSourcePrivate *priv = + meta_wayland_data_source_get_instance_private (source); + + return priv->seat; +} + +void +meta_wayland_data_source_set_has_target (MetaWaylandDataSource *source, + gboolean has_target) +{ + MetaWaylandDataSourcePrivate *priv = + meta_wayland_data_source_get_instance_private (source); + + priv->has_target = has_target; +} + +struct wl_array * +meta_wayland_data_source_get_mime_types (MetaWaylandDataSource *source) +{ + MetaWaylandDataSourcePrivate *priv = + meta_wayland_data_source_get_instance_private ((MetaWaylandDataSource *)source); + + return &priv->mime_types; +} + +void +meta_wayland_data_source_cancel (MetaWaylandDataSource *source) +{ + META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->cancel (source); +} + +gboolean +meta_wayland_data_source_get_actions (MetaWaylandDataSource *source, + uint32_t *dnd_actions) +{ + MetaWaylandDataSourcePrivate *priv = + meta_wayland_data_source_get_instance_private (source); + + if (dnd_actions) + *dnd_actions = priv->dnd_actions; + + return priv->actions_set; +} + +enum wl_data_device_manager_dnd_action +meta_wayland_data_source_get_user_action (MetaWaylandDataSource *source) +{ + MetaWaylandDataSourcePrivate *priv = + meta_wayland_data_source_get_instance_private (source); + + if (!priv->seat) + return WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE; + + return priv->user_dnd_action; +} + +enum wl_data_device_manager_dnd_action +meta_wayland_data_source_get_current_action (MetaWaylandDataSource *source) +{ + MetaWaylandDataSourcePrivate *priv = + meta_wayland_data_source_get_instance_private (source); + + return priv->current_dnd_action; +} + +void +meta_wayland_data_source_set_current_offer (MetaWaylandDataSource *source, + MetaWaylandDataOffer *offer) +{ + MetaWaylandDataSourcePrivate *priv = + meta_wayland_data_source_get_instance_private (source); + + priv->offer = offer; +} + +MetaWaylandDataOffer * +meta_wayland_data_source_get_current_offer (MetaWaylandDataSource *source) +{ + MetaWaylandDataSourcePrivate *priv = + meta_wayland_data_source_get_instance_private (source); + + return priv->offer; +} + +void +meta_wayland_data_source_set_current_action (MetaWaylandDataSource *source, + enum wl_data_device_manager_dnd_action action) +{ + MetaWaylandDataSourcePrivate *priv = + meta_wayland_data_source_get_instance_private (source); + + if (priv->current_dnd_action == action) + return; + + priv->current_dnd_action = action; + + if (!meta_wayland_data_source_get_in_ask (source)) + META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->action (source, action); +} + +void +meta_wayland_data_source_set_actions (MetaWaylandDataSource *source, + uint32_t dnd_actions) +{ + MetaWaylandDataSourcePrivate *priv = + meta_wayland_data_source_get_instance_private (source); + + priv->dnd_actions = dnd_actions; + priv->actions_set = TRUE; +} + +void +meta_wayland_data_source_set_user_action (MetaWaylandDataSource *source, + uint32_t action) +{ + MetaWaylandDataSourcePrivate *priv = + meta_wayland_data_source_get_instance_private (source); + MetaWaylandDataOffer *offer; + + if (priv->user_dnd_action == action) + return; + + priv->user_dnd_action = action; + offer = meta_wayland_data_source_get_current_offer (source); + + if (offer) + meta_wayland_data_offer_update_action (offer); +} + +gboolean +meta_wayland_data_source_get_drop_performed (MetaWaylandDataSource *source) +{ + MetaWaylandDataSourcePrivate *priv = + meta_wayland_data_source_get_instance_private (source); + + return priv->drop_performed; +} + +void +meta_wayland_data_source_notify_drop_performed (MetaWaylandDataSource *source) +{ + META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->drop_performed (source); +} + +void +meta_wayland_data_source_notify_finish (MetaWaylandDataSource *source) +{ + META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->drag_finished (source); +} + +gboolean +meta_wayland_data_source_add_mime_type (MetaWaylandDataSource *source, + const char *mime_type) +{ + MetaWaylandDataSourcePrivate *priv = + meta_wayland_data_source_get_instance_private (source); + char **pos; + + pos = wl_array_add (&priv->mime_types, sizeof (*pos)); + + if (pos) + { + *pos = g_strdup (mime_type); + return *pos != NULL; + } + + return FALSE; +} + +gboolean +meta_wayland_data_source_has_mime_type (MetaWaylandDataSource *source, + const char *mime_type) +{ + MetaWaylandDataSourcePrivate *priv = + meta_wayland_data_source_get_instance_private (source); + char **p; + + wl_array_for_each (p, &priv->mime_types) + { + if (g_strcmp0 (mime_type, *p) == 0) + return TRUE; + } + + return FALSE; +} diff --git a/src/wayland/meta-wayland-data-source.h b/src/wayland/meta-wayland-data-source.h new file mode 100644 index 000000000..900329b10 --- /dev/null +++ b/src/wayland/meta-wayland-data-source.h @@ -0,0 +1,112 @@ +/* + * Copyright © 2011 Kristian Høgsberg + * 2020 Red Hat Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef META_WAYLAND_DATA_SOURCE_H +#define META_WAYLAND_DATA_SOURCE_H + +#include <glib-object.h> +#include <wayland-server.h> + +#include "wayland/meta-wayland-types.h" + +#define META_TYPE_WAYLAND_DATA_SOURCE (meta_wayland_data_source_get_type ()) +G_DECLARE_DERIVABLE_TYPE (MetaWaylandDataSource, + meta_wayland_data_source, + META, WAYLAND_DATA_SOURCE, + GObject) + +typedef struct _MetaWaylandDataSourceClass MetaWaylandDataSourceClass; + +struct _MetaWaylandDataSourceClass +{ + GObjectClass parent_class; + + void (* send) (MetaWaylandDataSource *source, + const gchar *mime_type, + gint fd); + void (* target) (MetaWaylandDataSource *source, + const gchar *mime_type); + void (* cancel) (MetaWaylandDataSource *source); + + void (* action) (MetaWaylandDataSource *source, + uint32_t action); + void (* drop_performed) (MetaWaylandDataSource *source); + void (* drag_finished) (MetaWaylandDataSource *source); +}; + +MetaWaylandDataSource * meta_wayland_data_source_new (struct wl_resource *resource); + +struct wl_resource * meta_wayland_data_source_get_resource (MetaWaylandDataSource *source); +void meta_wayland_data_source_set_resource (MetaWaylandDataSource *source, + struct wl_resource *resource); + +gboolean meta_wayland_data_source_get_in_ask (MetaWaylandDataSource *source); +void meta_wayland_data_source_update_in_ask (MetaWaylandDataSource *source); + +void meta_wayland_data_source_target (MetaWaylandDataSource *source, + const char *mime_type); +void meta_wayland_data_source_send (MetaWaylandDataSource *source, + const char *mime_type, + int fd); +void meta_wayland_data_source_cancel (MetaWaylandDataSource *source); + +gboolean meta_wayland_data_source_has_target (MetaWaylandDataSource *source); + +void meta_wayland_data_source_set_seat (MetaWaylandDataSource *source, + MetaWaylandSeat *seat); +MetaWaylandSeat * meta_wayland_data_source_get_seat (MetaWaylandDataSource *source); + +void meta_wayland_data_source_set_has_target (MetaWaylandDataSource *source, + gboolean has_target); +struct wl_array * meta_wayland_data_source_get_mime_types (MetaWaylandDataSource *source); +gboolean meta_wayland_data_source_add_mime_type (MetaWaylandDataSource *source, + const gchar *mime_type); +gboolean meta_wayland_data_source_has_mime_type (MetaWaylandDataSource *source, + const char *mime_type); + +gboolean meta_wayland_data_source_get_actions (MetaWaylandDataSource *source, + uint32_t *dnd_actions); +void meta_wayland_data_source_set_actions (MetaWaylandDataSource *source, + uint32_t dnd_actions); + +enum wl_data_device_manager_dnd_action + meta_wayland_data_source_get_current_action (MetaWaylandDataSource *source); +void meta_wayland_data_source_set_current_action (MetaWaylandDataSource *source, + enum wl_data_device_manager_dnd_action action); + +enum wl_data_device_manager_dnd_action + meta_wayland_data_source_get_user_action (MetaWaylandDataSource *source); +void meta_wayland_data_source_set_user_action (MetaWaylandDataSource *source, + uint32_t action); + +MetaWaylandDataOffer * + meta_wayland_data_source_get_current_offer (MetaWaylandDataSource *source); +void meta_wayland_data_source_set_current_offer (MetaWaylandDataSource *source, + MetaWaylandDataOffer *offer); + +gboolean meta_wayland_data_source_get_drop_performed (MetaWaylandDataSource *source); + +void meta_wayland_data_source_notify_drop_performed (MetaWaylandDataSource *source); +void meta_wayland_data_source_notify_finish (MetaWaylandDataSource *source); + +#endif /* META_WAYLAND_DATA_SOURCE_H */ diff --git a/src/wayland/meta-wayland-dma-buf.c b/src/wayland/meta-wayland-dma-buf.c new file mode 100644 index 000000000..ac412d214 --- /dev/null +++ b/src/wayland/meta-wayland-dma-buf.c @@ -0,0 +1,602 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat Inc. + * Copyright (C) 2017 Intel Corporation + * Copyright (C) 2018,2019 DisplayLink (UK) Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + * Daniel Stone <daniels@collabora.com> + */ + +/** + * SECTION:meta-wayland-dma-buf + * @title: MetaWaylandDmaBuf + * @short_description: Handles passing DMA-BUFs in Wayland + * + * The MetaWaylandDmaBuf namespace contains several objects and functions to + * handle DMA-BUF buffers that are passed through from clients in Wayland (e.g. + * using the linux_dmabuf_unstable_v1 protocol). + */ + +#include "config.h" + +#include "wayland/meta-wayland-dma-buf.h" + +#include <drm_fourcc.h> + +#include "backends/meta-backend-private.h" +#include "backends/meta-egl-ext.h" +#include "backends/meta-egl.h" +#include "cogl/cogl-egl.h" +#include "cogl/cogl.h" +#include "meta/meta-backend.h" +#include "wayland/meta-wayland-buffer.h" +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-wayland-versions.h" + +#include "linux-dmabuf-unstable-v1-server-protocol.h" + +#ifndef DRM_FORMAT_MOD_INVALID +#define DRM_FORMAT_MOD_INVALID ((1ULL << 56) - 1) +#endif + +#define META_WAYLAND_DMA_BUF_MAX_FDS 4 + +struct _MetaWaylandDmaBufBuffer +{ + GObject parent; + + int width; + int height; + uint32_t drm_format; + uint64_t drm_modifier; + bool is_y_inverted; + int fds[META_WAYLAND_DMA_BUF_MAX_FDS]; + uint32_t offsets[META_WAYLAND_DMA_BUF_MAX_FDS]; + uint32_t strides[META_WAYLAND_DMA_BUF_MAX_FDS]; +}; + +G_DEFINE_TYPE (MetaWaylandDmaBufBuffer, meta_wayland_dma_buf_buffer, G_TYPE_OBJECT); + +static gboolean +meta_wayland_dma_buf_realize_texture (MetaWaylandBuffer *buffer, + GError **error) +{ + MetaBackend *backend = meta_get_backend (); + MetaEgl *egl = meta_backend_get_egl (backend); + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend); + EGLDisplay egl_display = cogl_egl_context_get_egl_display (cogl_context); + MetaWaylandDmaBufBuffer *dma_buf = buffer->dma_buf.dma_buf; + uint32_t n_planes; + uint64_t modifiers[META_WAYLAND_DMA_BUF_MAX_FDS]; + CoglPixelFormat cogl_format; + EGLImageKHR egl_image; + CoglEglImageFlags flags; + CoglTexture2D *texture; + + if (buffer->dma_buf.texture) + return TRUE; + + switch (dma_buf->drm_format) + { + /* + * NOTE: The cogl_format here is only used for texture color channel + * swizzling as compared to COGL_PIXEL_FORMAT_ARGB. It is *not* used + * for accessing the buffer memory. EGL will access the buffer + * memory according to the DRM fourcc code. Cogl will not mmap + * and access the buffer memory at all. + */ + case DRM_FORMAT_XRGB8888: + cogl_format = COGL_PIXEL_FORMAT_RGB_888; + break; + case DRM_FORMAT_ARGB8888: + cogl_format = COGL_PIXEL_FORMAT_ARGB_8888_PRE; + break; + case DRM_FORMAT_ARGB2101010: + cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010_PRE; + break; + case DRM_FORMAT_RGB565: + cogl_format = COGL_PIXEL_FORMAT_RGB_565; + break; + default: + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_FAILED, + "Unsupported buffer format %d", dma_buf->drm_format); + return FALSE; + } + + for (n_planes = 0; n_planes < META_WAYLAND_DMA_BUF_MAX_FDS; n_planes++) + { + if (dma_buf->fds[n_planes] < 0) + break; + + modifiers[n_planes] = dma_buf->drm_modifier; + } + + egl_image = meta_egl_create_dmabuf_image (egl, + egl_display, + dma_buf->width, + dma_buf->height, + dma_buf->drm_format, + n_planes, + dma_buf->fds, + dma_buf->strides, + dma_buf->offsets, + modifiers, + error); + if (egl_image == EGL_NO_IMAGE_KHR) + return FALSE; + + flags = COGL_EGL_IMAGE_FLAG_NO_GET_DATA; + texture = cogl_egl_texture_2d_new_from_image (cogl_context, + dma_buf->width, + dma_buf->height, + cogl_format, + egl_image, + flags, + error); + + meta_egl_destroy_image (egl, egl_display, egl_image, NULL); + + if (!texture) + return FALSE; + + buffer->dma_buf.texture = COGL_TEXTURE (texture); + buffer->is_y_inverted = dma_buf->is_y_inverted; + + return TRUE; +} + +gboolean +meta_wayland_dma_buf_buffer_attach (MetaWaylandBuffer *buffer, + CoglTexture **texture, + GError **error) +{ + if (!meta_wayland_dma_buf_realize_texture (buffer, error)) + return FALSE; + + cogl_clear_object (texture); + *texture = cogl_object_ref (buffer->dma_buf.texture); + return TRUE; +} + +static void +buffer_params_add (struct wl_client *client, + struct wl_resource *resource, + int32_t fd, + uint32_t plane_idx, + uint32_t offset, + uint32_t stride, + uint32_t drm_modifier_hi, + uint32_t drm_modifier_lo) +{ + MetaWaylandDmaBufBuffer *dma_buf; + uint64_t drm_modifier; + + drm_modifier = ((uint64_t) drm_modifier_hi) << 32; + drm_modifier |= ((uint64_t) drm_modifier_lo) & 0xffffffff; + + dma_buf = wl_resource_get_user_data (resource); + if (!dma_buf) + { + wl_resource_post_error (resource, + ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_ALREADY_USED, + "params already used"); + return; + } + + if (plane_idx >= META_WAYLAND_DMA_BUF_MAX_FDS) + { + wl_resource_post_error (resource, + ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_PLANE_IDX, + "out-of-bounds plane index %d", + plane_idx); + return; + } + + if (dma_buf->fds[plane_idx] != -1) + { + wl_resource_post_error (resource, + ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_PLANE_SET, + "plane index %d already set", + plane_idx); + return; + } + + if (dma_buf->drm_modifier != DRM_FORMAT_MOD_INVALID && + dma_buf->drm_modifier != drm_modifier) + { + wl_resource_post_error (resource, + ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INVALID_WL_BUFFER, + "mismatching modifier between planes"); + return; + } + + dma_buf->drm_modifier = drm_modifier; + dma_buf->fds[plane_idx] = fd; + dma_buf->offsets[plane_idx] = offset; + dma_buf->strides[plane_idx] = stride; +} + +static void +buffer_params_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +buffer_params_destructor (struct wl_resource *resource) +{ + MetaWaylandDmaBufBuffer *dma_buf; + + /* The user-data for our MetaWaylandBuffer is only valid in between adding + * FDs and creating the buffer; once it is created, we free it out into + * the wild, where the ref is considered transferred to the wl_buffer. */ + dma_buf = wl_resource_get_user_data (resource); + if (dma_buf) + g_object_unref (dma_buf); +} + +static void +buffer_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static const struct wl_buffer_interface dma_buf_buffer_impl = +{ + buffer_destroy, +}; + +/** + * meta_wayland_dma_buf_from_buffer: + * @buffer: A #MetaWaylandBuffer object + * + * Fetches the associated #MetaWaylandDmaBufBuffer from the wayland buffer. + * This does not *create* a new object, as this happens in the create_params + * request of linux_dmabuf_unstable_v1. + * + * Returns: (transfer none): The corresponding #MetaWaylandDmaBufBuffer (or + * %NULL if it wasn't a dma_buf-based wayland buffer) + */ +MetaWaylandDmaBufBuffer * +meta_wayland_dma_buf_from_buffer (MetaWaylandBuffer *buffer) +{ + if (wl_resource_instance_of (buffer->resource, &wl_buffer_interface, + &dma_buf_buffer_impl)) + return wl_resource_get_user_data (buffer->resource); + + return NULL; +} + +static void +buffer_params_create_common (struct wl_client *client, + struct wl_resource *params_resource, + uint32_t buffer_id, + int32_t width, + int32_t height, + uint32_t drm_format, + uint32_t flags) +{ + MetaWaylandDmaBufBuffer *dma_buf; + MetaWaylandBuffer *buffer; + struct wl_resource *buffer_resource; + GError *error = NULL; + + dma_buf = wl_resource_get_user_data (params_resource); + if (!dma_buf) + { + wl_resource_post_error (params_resource, + ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_ALREADY_USED, + "params already used"); + return; + } + + /* Calling the 'create' method is the point of no return: after that point, + * the params object cannot be used. This method must either transfer the + * ownership of the MetaWaylandDmaBufBuffer to a MetaWaylandBuffer, or + * destroy it. */ + wl_resource_set_user_data (params_resource, NULL); + + if (dma_buf->fds[0] == -1) + { + wl_resource_post_error (params_resource, + ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INCOMPLETE, + "no planes added to params"); + g_object_unref (dma_buf); + return; + } + + if ((dma_buf->fds[3] >= 0 || dma_buf->fds[2] >= 0) && + (dma_buf->fds[2] == -1 || dma_buf->fds[1] == -1)) + { + wl_resource_post_error (params_resource, + ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INCOMPLETE, + "gap in planes added to params"); + g_object_unref (dma_buf); + return; + } + + dma_buf->width = width; + dma_buf->height = height; + dma_buf->drm_format = drm_format; + dma_buf->is_y_inverted = !(flags & ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_Y_INVERT); + + if (flags & ~ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_Y_INVERT) + { + wl_resource_post_error (params_resource, + ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INVALID_WL_BUFFER, + "unknown flags 0x%x supplied", flags); + g_object_unref (dma_buf); + return; + } + + /* Create a new MetaWaylandBuffer wrapping our dmabuf, and immediately try + * to realize it, so we can give the client success/fail feedback for the + * import. */ + buffer_resource = + wl_resource_create (client, &wl_buffer_interface, 1, buffer_id); + wl_resource_set_implementation (buffer_resource, &dma_buf_buffer_impl, + dma_buf, NULL); + buffer = meta_wayland_buffer_from_resource (buffer_resource); + + meta_wayland_buffer_realize (buffer); + if (!meta_wayland_dma_buf_realize_texture (buffer, &error)) + { + if (buffer_id == 0) + { + zwp_linux_buffer_params_v1_send_failed (params_resource); + } + else + { + wl_resource_post_error (params_resource, + ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INVALID_WL_BUFFER, + "failed to import supplied dmabufs: %s", + error ? error->message : "unknown error"); + } + + /* will unref the MetaWaylandBuffer */ + wl_resource_destroy (buffer->resource); + return; + } + + /* If buffer_id is 0, we are using the non-immediate interface, so + * need to send a success event with our buffer. */ + if (buffer_id == 0) + zwp_linux_buffer_params_v1_send_created (params_resource, + buffer->resource); +} + +static void +buffer_params_create (struct wl_client *client, + struct wl_resource *params_resource, + int32_t width, + int32_t height, + uint32_t format, + uint32_t flags) +{ + buffer_params_create_common (client, params_resource, 0, width, height, + format, flags); +} + +static void +buffer_params_create_immed (struct wl_client *client, + struct wl_resource *params_resource, + uint32_t buffer_id, + int32_t width, + int32_t height, + uint32_t format, + uint32_t flags) +{ + buffer_params_create_common (client, params_resource, buffer_id, width, + height, format, flags); +} + +static const struct zwp_linux_buffer_params_v1_interface buffer_params_implementation = +{ + buffer_params_destroy, + buffer_params_add, + buffer_params_create, + buffer_params_create_immed, +}; + +static void +dma_buf_handle_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +dma_buf_handle_create_buffer_params (struct wl_client *client, + struct wl_resource *dma_buf_resource, + uint32_t params_id) +{ + struct wl_resource *params_resource; + MetaWaylandDmaBufBuffer *dma_buf; + + dma_buf = g_object_new (META_TYPE_WAYLAND_DMA_BUF_BUFFER, NULL); + + params_resource = + wl_resource_create (client, + &zwp_linux_buffer_params_v1_interface, + wl_resource_get_version (dma_buf_resource), + params_id); + wl_resource_set_implementation (params_resource, + &buffer_params_implementation, + dma_buf, + buffer_params_destructor); +} + +static const struct zwp_linux_dmabuf_v1_interface dma_buf_implementation = +{ + dma_buf_handle_destroy, + dma_buf_handle_create_buffer_params, +}; + +static void +send_modifiers (struct wl_resource *resource, + uint32_t format) +{ + MetaBackend *backend = meta_get_backend (); + MetaEgl *egl = meta_backend_get_egl (backend); + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend); + EGLDisplay egl_display = cogl_egl_context_get_egl_display (cogl_context); + EGLint num_modifiers; + EGLuint64KHR *modifiers; + GError *error = NULL; + gboolean ret; + int i; + + zwp_linux_dmabuf_v1_send_format (resource, format); + + /* The modifier event was only added in v3; v1 and v2 only have the format + * event. */ + if (wl_resource_get_version (resource) < ZWP_LINUX_DMABUF_V1_MODIFIER_SINCE_VERSION) + return; + + /* First query the number of available modifiers, then allocate an array, + * then fill the array. */ + ret = meta_egl_query_dma_buf_modifiers (egl, egl_display, format, 0, NULL, + NULL, &num_modifiers, NULL); + if (!ret) + return; + + if (num_modifiers == 0) + { + zwp_linux_dmabuf_v1_send_modifier (resource, format, + DRM_FORMAT_MOD_INVALID >> 32, + DRM_FORMAT_MOD_INVALID & 0xffffffff); + return; + } + + modifiers = g_new0 (uint64_t, num_modifiers); + ret = meta_egl_query_dma_buf_modifiers (egl, egl_display, format, + num_modifiers, modifiers, NULL, + &num_modifiers, &error); + if (!ret) + { + g_warning ("Failed to query modifiers for format 0x%" PRIu32 ": %s", + format, error ? error->message : "unknown error"); + g_free (modifiers); + return; + } + + for (i = 0; i < num_modifiers; i++) + { + zwp_linux_dmabuf_v1_send_modifier (resource, format, + modifiers[i] >> 32, + modifiers[i] & 0xffffffff); + } + + g_free (modifiers); +} + +static void +dma_buf_bind (struct wl_client *client, + void *data, + uint32_t version, + uint32_t id) +{ + MetaWaylandCompositor *compositor = data; + struct wl_resource *resource; + + resource = wl_resource_create (client, &zwp_linux_dmabuf_v1_interface, + version, id); + wl_resource_set_implementation (resource, &dma_buf_implementation, + compositor, NULL); + send_modifiers (resource, DRM_FORMAT_ARGB8888); + send_modifiers (resource, DRM_FORMAT_XRGB8888); + send_modifiers (resource, DRM_FORMAT_ARGB2101010); + send_modifiers (resource, DRM_FORMAT_RGB565); +} + +/** + * meta_wayland_dma_buf_init: + * @compositor: The #MetaWaylandCompositor + * + * Creates the global Wayland object that exposes the linux-dmabuf protocol. + * + * Returns: Whether the initialization was succesfull. If this is %FALSE, + * clients won't be able to use the linux-dmabuf protocol to pass buffers. + */ +gboolean +meta_wayland_dma_buf_init (MetaWaylandCompositor *compositor) +{ + MetaBackend *backend = meta_get_backend (); + MetaEgl *egl = meta_backend_get_egl (backend); + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend); + EGLDisplay egl_display = cogl_egl_context_get_egl_display (cogl_context); + + g_assert (backend && egl && clutter_backend && cogl_context && egl_display); + + if (!meta_egl_has_extensions (egl, egl_display, NULL, + "EGL_EXT_image_dma_buf_import_modifiers", + NULL)) + return FALSE; + + if (!wl_global_create (compositor->wayland_display, + &zwp_linux_dmabuf_v1_interface, + META_ZWP_LINUX_DMABUF_V1_VERSION, + compositor, + dma_buf_bind)) + return FALSE; + + return TRUE; +} + +static void +meta_wayland_dma_buf_buffer_finalize (GObject *object) +{ + MetaWaylandDmaBufBuffer *dma_buf = META_WAYLAND_DMA_BUF_BUFFER (object); + int i; + + for (i = 0; i < META_WAYLAND_DMA_BUF_MAX_FDS; i++) + { + if (dma_buf->fds[i] != -1) + close (dma_buf->fds[i]); + } + + G_OBJECT_CLASS (meta_wayland_dma_buf_buffer_parent_class)->finalize (object); +} + +static void +meta_wayland_dma_buf_buffer_init (MetaWaylandDmaBufBuffer *dma_buf) +{ + int i; + + dma_buf->drm_modifier = DRM_FORMAT_MOD_INVALID; + + for (i = 0; i < META_WAYLAND_DMA_BUF_MAX_FDS; i++) + dma_buf->fds[i] = -1; +} + +static void +meta_wayland_dma_buf_buffer_class_init (MetaWaylandDmaBufBufferClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_wayland_dma_buf_buffer_finalize; +} diff --git a/src/wayland/meta-wayland-dma-buf.h b/src/wayland/meta-wayland-dma-buf.h new file mode 100644 index 000000000..b7f712d8d --- /dev/null +++ b/src/wayland/meta-wayland-dma-buf.h @@ -0,0 +1,52 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat Inc. + * Copyright (C) 2017 Intel Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + * Daniel Stone <daniels@collabora.com> + */ + +#ifndef META_WAYLAND_DMA_BUF_H +#define META_WAYLAND_DMA_BUF_H + +#include <glib.h> +#include <glib-object.h> + +#include "cogl/cogl.h" +#include "wayland/meta-wayland-types.h" + +#define META_TYPE_WAYLAND_DMA_BUF_BUFFER (meta_wayland_dma_buf_buffer_get_type ()) +G_DECLARE_FINAL_TYPE (MetaWaylandDmaBufBuffer, meta_wayland_dma_buf_buffer, + META, WAYLAND_DMA_BUF_BUFFER, GObject); + +typedef struct _MetaWaylandDmaBufBuffer MetaWaylandDmaBufBuffer; + +gboolean meta_wayland_dma_buf_init (MetaWaylandCompositor *compositor); + +gboolean +meta_wayland_dma_buf_buffer_attach (MetaWaylandBuffer *buffer, + CoglTexture **texture, + GError **error); + +MetaWaylandDmaBufBuffer * +meta_wayland_dma_buf_from_buffer (MetaWaylandBuffer *buffer); + +#endif /* META_WAYLAND_DMA_BUF_H */ diff --git a/src/wayland/meta-wayland-dnd-surface.c b/src/wayland/meta-wayland-dnd-surface.c new file mode 100644 index 000000000..0786b99d9 --- /dev/null +++ b/src/wayland/meta-wayland-dnd-surface.c @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2015-2019 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "wayland/meta-wayland-dnd-surface.h" + +#include "backends/meta-logical-monitor.h" +#include "compositor/meta-feedback-actor-private.h" +#include "wayland/meta-wayland.h" + +struct _MetaWaylandSurfaceRoleDND +{ + MetaWaylandActorSurface parent; + int32_t pending_offset_x; + int32_t pending_offset_y; +}; + +G_DEFINE_TYPE (MetaWaylandSurfaceRoleDND, + meta_wayland_surface_role_dnd, + META_TYPE_WAYLAND_ACTOR_SURFACE) + +static void +dnd_surface_assigned (MetaWaylandSurfaceRole *surface_role) +{ + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + + if (wl_list_empty (&surface->unassigned.pending_frame_callback_list)) + return; + + meta_wayland_compositor_add_frame_callback_surface (surface->compositor, + surface); +} + +static void +dnd_surface_apply_state (MetaWaylandSurfaceRole *surface_role, + MetaWaylandSurfaceState *pending) +{ + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWaylandSurfaceRoleDND *surface_role_dnd = + META_WAYLAND_SURFACE_ROLE_DND (surface_role); + MetaWaylandSurfaceRoleClass *surface_role_class = + META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_surface_role_dnd_parent_class); + + meta_wayland_compositor_add_frame_callback_surface (surface->compositor, + surface); + + surface_role_dnd->pending_offset_x = pending->dx; + surface_role_dnd->pending_offset_y = pending->dy; + + surface_role_class->apply_state (surface_role, pending); +} + +static MetaLogicalMonitor * +dnd_surface_find_logical_monitor (MetaWaylandActorSurface *actor_surface) +{ + MetaBackend *backend = meta_get_backend (); + MetaCursorRenderer *cursor_renderer = + meta_backend_get_cursor_renderer (backend); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + graphene_point_t pointer_pos; + + pointer_pos = meta_cursor_renderer_get_position (cursor_renderer); + return meta_monitor_manager_get_logical_monitor_at (monitor_manager, + pointer_pos.x, + pointer_pos.y); +} + +static double +dnd_subsurface_get_geometry_scale (MetaWaylandActorSurface *actor_surface) +{ + if (meta_is_stage_views_scaled ()) + { + return 1; + } + else + { + MetaLogicalMonitor *logical_monitor; + + logical_monitor = dnd_surface_find_logical_monitor (actor_surface); + return meta_logical_monitor_get_scale (logical_monitor); + } +} + +static void +dnd_subsurface_sync_actor_state (MetaWaylandActorSurface *actor_surface) +{ + MetaSurfaceActor *surface_actor = + meta_wayland_actor_surface_get_actor (actor_surface); + MetaFeedbackActor *feedback_actor = + META_FEEDBACK_ACTOR (clutter_actor_get_parent (CLUTTER_ACTOR (surface_actor))); + MetaWaylandSurfaceRole *surface_role = + META_WAYLAND_SURFACE_ROLE (actor_surface); + MetaWaylandSurfaceRoleDND *surface_role_dnd = + META_WAYLAND_SURFACE_ROLE_DND (surface_role); + MetaWaylandActorSurfaceClass *actor_surface_class = + META_WAYLAND_ACTOR_SURFACE_CLASS (meta_wayland_surface_role_dnd_parent_class); + int geometry_scale; + float anchor_x; + float anchor_y; + + g_return_if_fail (META_IS_FEEDBACK_ACTOR (feedback_actor)); + + geometry_scale = + meta_wayland_actor_surface_get_geometry_scale (actor_surface); + meta_feedback_actor_set_geometry_scale (feedback_actor, geometry_scale); + + meta_feedback_actor_get_anchor (feedback_actor, &anchor_x, &anchor_y); + anchor_x -= surface_role_dnd->pending_offset_x; + anchor_y -= surface_role_dnd->pending_offset_y; + meta_feedback_actor_set_anchor (feedback_actor, anchor_x, anchor_y); + + actor_surface_class->sync_actor_state (actor_surface); +} + +static void +meta_wayland_surface_role_dnd_init (MetaWaylandSurfaceRoleDND *role) +{ +} + +static void +meta_wayland_surface_role_dnd_class_init (MetaWaylandSurfaceRoleDNDClass *klass) +{ + MetaWaylandSurfaceRoleClass *surface_role_class = + META_WAYLAND_SURFACE_ROLE_CLASS (klass); + MetaWaylandActorSurfaceClass *actor_surface_class = + META_WAYLAND_ACTOR_SURFACE_CLASS (klass); + + surface_role_class->assigned = dnd_surface_assigned; + surface_role_class->apply_state = dnd_surface_apply_state; + + actor_surface_class->get_geometry_scale = dnd_subsurface_get_geometry_scale; + actor_surface_class->sync_actor_state = dnd_subsurface_sync_actor_state; +} diff --git a/src/wayland/meta-wayland-dnd-surface.h b/src/wayland/meta-wayland-dnd-surface.h new file mode 100644 index 000000000..45cf689ee --- /dev/null +++ b/src/wayland/meta-wayland-dnd-surface.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2015-2019 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_WAYLAND_DND_SURFACE_H +#define META_WAYLAND_DND_SURFACE_H + +#include "wayland/meta-wayland-actor-surface.h" + +#define META_TYPE_WAYLAND_SURFACE_ROLE_DND (meta_wayland_surface_role_dnd_get_type ()) +G_DECLARE_FINAL_TYPE (MetaWaylandSurfaceRoleDND, + meta_wayland_surface_role_dnd, + META, WAYLAND_SURFACE_ROLE_DND, + MetaWaylandActorSurface) + +#endif /* META_WAYLAND_DND_SURFACE_H */ diff --git a/src/wayland/meta-wayland-egl-stream.c b/src/wayland/meta-wayland-egl-stream.c new file mode 100644 index 000000000..3a2e1e56a --- /dev/null +++ b/src/wayland/meta-wayland-egl-stream.c @@ -0,0 +1,367 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +#include "config.h" + +#include "wayland/meta-wayland-egl-stream.h" + +#include <dlfcn.h> + +#include "backends/meta-backend-private.h" +#include "backends/meta-egl-ext.h" +#include "backends/meta-egl.h" +#include "cogl/cogl-egl.h" +#include "meta/meta-backend.h" +#include "wayland/meta-wayland-buffer.h" +#include "wayland/meta-wayland-private.h" + +#include "wayland-eglstream-controller-server-protocol.h" + +static struct wl_interface *wl_eglstream_controller_interface_ptr = NULL; + +static void +attach_eglstream_consumer (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *wl_surface, + struct wl_resource *wl_eglstream) +{ + MetaWaylandBuffer *buffer = meta_wayland_buffer_from_resource (wl_eglstream); + + if (!meta_wayland_buffer_is_realized (buffer)) + meta_wayland_buffer_realize (buffer); +} + +static const struct wl_eglstream_controller_interface +meta_eglstream_controller_interface = { + attach_eglstream_consumer +}; + +static void +bind_eglstream_controller (struct wl_client *client, + void *data, + uint32_t version, + uint32_t id) +{ + struct wl_resource *resource; + + g_assert (wl_eglstream_controller_interface_ptr != NULL); + + resource = wl_resource_create (client, + wl_eglstream_controller_interface_ptr, + version, + id); + + if (resource == NULL) + { + wl_client_post_no_memory(client); + return; + } + + wl_resource_set_implementation (resource, + &meta_eglstream_controller_interface, + data, + NULL); +} + +gboolean +meta_wayland_eglstream_controller_init (MetaWaylandCompositor *compositor) +{ + /* + * wl_eglstream_controller_interface is provided by + * libnvidia-egl-wayland.so.1 + * + * Since it might not be available on the + * system, dynamically load it at runtime and resolve the needed + * symbols. If available, it should be found under any of the search + * directories of dlopen() + * + * Failure to initialize wl_eglstream_controller is non-fatal + */ + + void *lib = dlopen ("libnvidia-egl-wayland.so.1", RTLD_NOW | RTLD_LAZY); + if (!lib) + goto fail; + + wl_eglstream_controller_interface_ptr = + dlsym (lib, "wl_eglstream_controller_interface"); + + if (!wl_eglstream_controller_interface_ptr) + goto fail; + + if (wl_global_create (compositor->wayland_display, + wl_eglstream_controller_interface_ptr, 1, + NULL, + bind_eglstream_controller) == NULL) + goto fail; + + g_debug ("WL: loaded libnvidia-egl-wayland.so.1:wl_eglstream_controller."); + + return TRUE; + +fail: + if (lib) + dlclose(lib); + + g_debug ("WL: Unable to initialize wl_eglstream_controller."); + + return FALSE; +} + +struct _MetaWaylandEglStream +{ + GObject parent; + + EGLStreamKHR egl_stream; + MetaWaylandBuffer *buffer; + CoglTexture2D *texture; + gboolean is_y_inverted; + CoglSnippet *snippet; +}; + +G_DEFINE_TYPE (MetaWaylandEglStream, meta_wayland_egl_stream, + G_TYPE_OBJECT) + +MetaWaylandEglStream * +meta_wayland_egl_stream_new (MetaWaylandBuffer *buffer, + GError **error) +{ + MetaBackend *backend = meta_get_backend (); + MetaEgl *egl = meta_backend_get_egl (backend); + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend); + EGLDisplay egl_display = cogl_egl_context_get_egl_display (cogl_context); + EGLAttrib stream_attribs[] = { + EGL_WAYLAND_EGLSTREAM_WL, (EGLAttrib) buffer->resource, + EGL_NONE + }; + EGLStreamKHR egl_stream; + MetaWaylandEglStream *stream; + + egl_stream = meta_egl_create_stream_attrib (egl, egl_display, stream_attribs, + error); + if (egl_stream == EGL_NO_STREAM_KHR) + { + g_set_error (error, G_IO_ERROR, + G_IO_ERROR_FAILED, + "Failed to create stream from wl_buffer resource"); + return NULL; + } + + stream = g_object_new (META_TYPE_WAYLAND_EGL_STREAM, NULL); + stream->egl_stream = egl_stream; + stream->buffer = buffer; + + return stream; +} + +static void +stream_texture_destroyed (gpointer data) +{ + MetaWaylandEglStream *stream = data; + + stream->texture = NULL; + + g_object_unref (stream); +} + +static gboolean +alloc_egl_stream_texture (CoglTexture2D *texture, + gpointer user_data, + GError **error) +{ + MetaBackend *backend = meta_get_backend (); + MetaEgl *egl = meta_backend_get_egl (backend); + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend); + EGLDisplay egl_display = cogl_egl_context_get_egl_display (cogl_context); + MetaWaylandEglStream *stream = user_data; + + return meta_egl_stream_consumer_gl_texture_external (egl, egl_display, + stream->egl_stream, + error); +} + +CoglTexture2D * +meta_wayland_egl_stream_create_texture (MetaWaylandEglStream *stream, + GError **error) +{ + MetaBackend *backend = meta_get_backend (); + MetaEgl *egl = meta_backend_get_egl (backend); + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend); + EGLDisplay egl_display = cogl_egl_context_get_egl_display (cogl_context); + CoglTexture2D *texture; + int width, height; + int y_inverted; + + if (!meta_egl_query_wayland_buffer (egl, egl_display, + stream->buffer->resource, + EGL_WIDTH, &width, + error)) + return NULL; + + if (!meta_egl_query_wayland_buffer (egl, egl_display, + stream->buffer->resource, + EGL_HEIGHT, &height, + error)) + return NULL; + + if (!meta_egl_query_wayland_buffer (egl, egl_display, + stream->buffer->resource, + EGL_WAYLAND_Y_INVERTED_WL, &y_inverted, + NULL)) + y_inverted = EGL_TRUE; + + texture = + cogl_texture_2d_new_from_egl_image_external (cogl_context, + width, height, + alloc_egl_stream_texture, + g_object_ref (stream), + stream_texture_destroyed, + error); + if (!texture) + { + g_object_unref (stream); + return NULL; + } + + if (!cogl_texture_allocate (COGL_TEXTURE (texture), error)) + { + cogl_object_unref (texture); + return NULL; + } + + stream->texture = texture; + stream->is_y_inverted = !!y_inverted; + + return texture; +} + +gboolean +meta_wayland_egl_stream_attach (MetaWaylandEglStream *stream, + GError **error) +{ + MetaBackend *backend = meta_get_backend (); + MetaEgl *egl = meta_backend_get_egl (backend); + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend); + EGLDisplay egl_display = cogl_egl_context_get_egl_display (cogl_context); + EGLint stream_state; + + if (!meta_egl_query_stream (egl, egl_display, stream->egl_stream, + EGL_STREAM_STATE_KHR, &stream_state, + error)) + return FALSE; + + if (stream_state == EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR) + { + if (!meta_egl_stream_consumer_acquire (egl, egl_display, + stream->egl_stream, + error)) + return FALSE; + } + + return TRUE; +} + +gboolean +meta_wayland_egl_stream_is_y_inverted (MetaWaylandEglStream *stream) +{ + return stream->is_y_inverted; +} + +CoglSnippet * +meta_wayland_egl_stream_create_snippet (MetaWaylandEglStream *stream) +{ + if (!stream->snippet) + { + CoglSnippet *snippet; + + snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_LOOKUP, + "uniform samplerExternalOES tex_external;", + NULL); + cogl_snippet_set_replace (snippet, + "cogl_texel = texture2D (tex_external,\n" + " cogl_tex_coord.xy);"); + stream->snippet = snippet; + } + + return cogl_object_ref (stream->snippet); +} + +gboolean +meta_wayland_is_egl_stream_buffer (MetaWaylandBuffer *buffer) +{ + MetaBackend *backend = meta_get_backend (); + MetaEgl *egl = meta_backend_get_egl (backend); + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend); + EGLDisplay egl_display = cogl_egl_context_get_egl_display (cogl_context); + int stream_fd; + + if (!meta_egl_has_extensions (egl, egl_display, NULL, + "EGL_KHR_stream_consumer_gltexture", + "EGL_KHR_stream_cross_process_fd", + NULL)) + return FALSE; + + if (!meta_egl_query_wayland_buffer (egl, egl_display, buffer->resource, + EGL_WAYLAND_BUFFER_WL, &stream_fd, + NULL)) + return FALSE; + + return TRUE; +} + +static void +meta_wayland_egl_stream_finalize (GObject *object) +{ + MetaWaylandEglStream *stream = META_WAYLAND_EGL_STREAM (object); + MetaBackend *backend = meta_get_backend (); + MetaEgl *egl = meta_backend_get_egl (backend); + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend); + EGLDisplay egl_display = cogl_egl_context_get_egl_display (cogl_context); + + g_assert (!stream->texture); + + meta_egl_destroy_stream (egl, egl_display, stream->egl_stream, NULL); + + cogl_clear_object (&stream->snippet); + + G_OBJECT_CLASS (meta_wayland_egl_stream_parent_class)->finalize (object); +} + +static void +meta_wayland_egl_stream_init (MetaWaylandEglStream *stream) +{ +} + +static void +meta_wayland_egl_stream_class_init (MetaWaylandEglStreamClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_wayland_egl_stream_finalize; +} diff --git a/src/wayland/meta-wayland-egl-stream.h b/src/wayland/meta-wayland-egl-stream.h new file mode 100644 index 000000000..b8a6b1968 --- /dev/null +++ b/src/wayland/meta-wayland-egl-stream.h @@ -0,0 +1,54 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +#ifndef META_WAYLAND_EGL_STREAM_H +#define META_WAYLAND_EGL_STREAM_H + +#include <glib.h> +#include <glib-object.h> + +#include "cogl/cogl.h" +#include "wayland/meta-wayland-types.h" + +gboolean meta_wayland_eglstream_controller_init (MetaWaylandCompositor *compositor); + +#define META_TYPE_WAYLAND_EGL_STREAM (meta_wayland_egl_stream_get_type ()) +G_DECLARE_FINAL_TYPE (MetaWaylandEglStream, meta_wayland_egl_stream, + META, WAYLAND_EGL_STREAM, GObject); + +gboolean meta_wayland_is_egl_stream_buffer (MetaWaylandBuffer *buffer); + +MetaWaylandEglStream * meta_wayland_egl_stream_new (MetaWaylandBuffer *buffer, + GError **error); + +gboolean meta_wayland_egl_stream_attach (MetaWaylandEglStream *stream, + GError **error); + +CoglTexture2D * meta_wayland_egl_stream_create_texture (MetaWaylandEglStream *stream, + GError **error); +CoglSnippet * meta_wayland_egl_stream_create_snippet (MetaWaylandEglStream *stream); + +gboolean meta_wayland_egl_stream_is_y_inverted (MetaWaylandEglStream *stream); + +#endif /* META_WAYLAND_EGL_STREAM_H */ diff --git a/src/wayland/meta-wayland-gtk-shell.c b/src/wayland/meta-wayland-gtk-shell.c new file mode 100644 index 000000000..9c5357b91 --- /dev/null +++ b/src/wayland/meta-wayland-gtk-shell.c @@ -0,0 +1,544 @@ +/* + * Wayland Support + * + * Copyright (C) 2012,2013 Intel Corporation + * 2013-2016 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "wayland/meta-wayland-gtk-shell.h" + +#include "core/bell.h" +#include "core/window-private.h" +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-wayland-surface.h" +#include "wayland/meta-wayland-versions.h" +#include "wayland/meta-window-wayland.h" + +#include "gtk-shell-server-protocol.h" + +static GQuark quark_gtk_surface_data = 0; + +typedef struct _MetaWaylandGtkSurface +{ + struct wl_resource *resource; + MetaWaylandSurface *surface; + gboolean is_modal; + gulong configure_handler_id; +} MetaWaylandGtkSurface; + +struct _MetaWaylandGtkShell +{ + GObject parent; + + GList *shell_resources; + uint32_t capabilities; +}; + +G_DEFINE_TYPE (MetaWaylandGtkShell, meta_wayland_gtk_shell, G_TYPE_OBJECT) + +static void +gtk_surface_destructor (struct wl_resource *resource) +{ + MetaWaylandGtkSurface *gtk_surface = wl_resource_get_user_data (resource); + + if (gtk_surface->surface) + { + g_object_steal_qdata (G_OBJECT (gtk_surface->surface), + quark_gtk_surface_data); + g_clear_signal_handler (>k_surface->configure_handler_id, + gtk_surface->surface); + } + + g_free (gtk_surface); +} + +static void +gtk_surface_set_dbus_properties (struct wl_client *client, + struct wl_resource *resource, + const char *application_id, + const char *app_menu_path, + const char *menubar_path, + const char *window_object_path, + const char *application_object_path, + const char *unique_bus_name) +{ + MetaWaylandGtkSurface *gtk_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = gtk_surface->surface; + MetaWindow *window; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + meta_window_set_gtk_dbus_properties (window, + application_id, + unique_bus_name, + app_menu_path, + menubar_path, + application_object_path, + window_object_path); +} + +static void +gtk_surface_set_modal (struct wl_client *client, + struct wl_resource *resource) +{ + MetaWaylandGtkSurface *gtk_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = gtk_surface->surface; + MetaWindow *window; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + if (gtk_surface->is_modal) + return; + + gtk_surface->is_modal = TRUE; + meta_window_set_type (window, META_WINDOW_MODAL_DIALOG); +} + +static void +gtk_surface_unset_modal (struct wl_client *client, + struct wl_resource *resource) +{ + MetaWaylandGtkSurface *gtk_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = gtk_surface->surface; + MetaWindow *window; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + if (!gtk_surface->is_modal) + return; + + gtk_surface->is_modal = FALSE; + meta_window_set_type (window, META_WINDOW_NORMAL); +} + +static void +gtk_surface_present (struct wl_client *client, + struct wl_resource *resource, + uint32_t timestamp) +{ + MetaWaylandGtkSurface *gtk_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = gtk_surface->surface; + MetaWindow *window; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + meta_window_activate_full (window, timestamp, + META_CLIENT_TYPE_APPLICATION, NULL); +} + +static void +gtk_surface_request_focus (struct wl_client *client, + struct wl_resource *resource, + const char *startup_id) +{ + MetaWaylandGtkSurface *gtk_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = gtk_surface->surface; + MetaDisplay *display = meta_get_display (); + MetaStartupSequence *sequence = NULL; + MetaWindow *window; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + if (startup_id) + sequence = meta_startup_notification_lookup_sequence (display->startup_notification, + startup_id); + + if (sequence) + { + uint32_t timestamp; + int32_t workspace_idx; + + workspace_idx = meta_startup_sequence_get_workspace (sequence); + timestamp = meta_startup_sequence_get_timestamp (sequence); + + meta_startup_sequence_complete (sequence); + meta_startup_notification_remove_sequence (display->startup_notification, + sequence); + if (workspace_idx >= 0) + meta_window_change_workspace_by_index (window, workspace_idx, TRUE); + + meta_window_activate_full (window, timestamp, + META_CLIENT_TYPE_APPLICATION, NULL); + } + else + { + meta_window_set_demands_attention (window); + } +} + +static const struct gtk_surface1_interface meta_wayland_gtk_surface_interface = { + gtk_surface_set_dbus_properties, + gtk_surface_set_modal, + gtk_surface_unset_modal, + gtk_surface_present, + gtk_surface_request_focus, +}; + +static void +gtk_surface_surface_destroyed (MetaWaylandGtkSurface *gtk_surface) +{ + wl_resource_set_implementation (gtk_surface->resource, + NULL, NULL, NULL); + gtk_surface->surface = NULL; +} + +static void +fill_edge_states (struct wl_array *states, + MetaWindow *window) +{ + uint32_t *s; + + if (window->edge_constraints.top != META_EDGE_CONSTRAINT_MONITOR) + { + s = wl_array_add (states, sizeof *s); + *s = GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_TOP; + } + + if (window->edge_constraints.right != META_EDGE_CONSTRAINT_MONITOR) + { + s = wl_array_add (states, sizeof *s); + *s = GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_RIGHT; + } + + if (window->edge_constraints.bottom != META_EDGE_CONSTRAINT_MONITOR) + { + s = wl_array_add (states, sizeof *s); + *s = GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_BOTTOM; + } + + if (window->edge_constraints.left != META_EDGE_CONSTRAINT_MONITOR) + { + s = wl_array_add (states, sizeof *s); + *s = GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_LEFT; + } +} + +static void +send_configure_edges (MetaWaylandGtkSurface *gtk_surface, + MetaWindow *window) +{ + struct wl_array edge_states; + + wl_array_init (&edge_states); + fill_edge_states (&edge_states, window); + + gtk_surface1_send_configure_edges (gtk_surface->resource, &edge_states); + + wl_array_release (&edge_states); +} + +static void +add_state_value (struct wl_array *states, + enum gtk_surface1_state state) +{ + uint32_t *s; + + s = wl_array_add (states, sizeof *s); + *s = state; +} + +static void +fill_states (struct wl_array *states, + MetaWindow *window, + struct wl_resource *resource) +{ + int version; + + version = wl_resource_get_version (resource); + + if (version < GTK_SURFACE1_CONFIGURE_EDGES_SINCE_VERSION && + (window->tile_mode == META_TILE_LEFT || + window->tile_mode == META_TILE_RIGHT)) + add_state_value (states, GTK_SURFACE1_STATE_TILED); + + if (version >= GTK_SURFACE1_STATE_TILED_TOP_SINCE_VERSION && + window->edge_constraints.top != META_EDGE_CONSTRAINT_NONE) + add_state_value (states, GTK_SURFACE1_STATE_TILED_TOP); + + if (version >= GTK_SURFACE1_STATE_TILED_RIGHT_SINCE_VERSION && + window->edge_constraints.right != META_EDGE_CONSTRAINT_NONE) + add_state_value (states, GTK_SURFACE1_STATE_TILED_RIGHT); + + if (version >= GTK_SURFACE1_STATE_TILED_BOTTOM_SINCE_VERSION && + window->edge_constraints.bottom != META_EDGE_CONSTRAINT_NONE) + add_state_value (states, GTK_SURFACE1_STATE_TILED_BOTTOM); + + if (version >= GTK_SURFACE1_STATE_TILED_LEFT_SINCE_VERSION && + window->edge_constraints.left != META_EDGE_CONSTRAINT_NONE) + add_state_value (states, GTK_SURFACE1_STATE_TILED_LEFT); +} + +static void +send_configure (MetaWaylandGtkSurface *gtk_surface, + MetaWindow *window) +{ + struct wl_array states; + + wl_array_init (&states); + fill_states (&states, window, gtk_surface->resource); + + gtk_surface1_send_configure (gtk_surface->resource, &states); + + wl_array_release (&states); +} + +static void +on_configure (MetaWaylandSurface *surface, + MetaWaylandGtkSurface *gtk_surface) +{ + MetaWindow *window; + + window = meta_wayland_surface_get_window (surface); + send_configure (gtk_surface, window); + + if (wl_resource_get_version (gtk_surface->resource) >= + GTK_SURFACE1_CONFIGURE_EDGES_SINCE_VERSION) + send_configure_edges (gtk_surface, window); +} + +static void +gtk_shell_get_gtk_surface (struct wl_client *client, + struct wl_resource *resource, + guint32 id, + struct wl_resource *surface_resource) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + MetaWaylandGtkSurface *gtk_surface; + + gtk_surface = g_object_get_qdata (G_OBJECT (surface), quark_gtk_surface_data); + if (gtk_surface) + { + wl_resource_post_error (surface_resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "gtk_shell::get_gtk_surface already requested"); + return; + } + + gtk_surface = g_new0 (MetaWaylandGtkSurface, 1); + gtk_surface->surface = surface; + gtk_surface->resource = wl_resource_create (client, + >k_surface1_interface, + wl_resource_get_version (resource), + id); + wl_resource_set_implementation (gtk_surface->resource, + &meta_wayland_gtk_surface_interface, + gtk_surface, gtk_surface_destructor); + + gtk_surface->configure_handler_id = g_signal_connect (surface, + "configure", + G_CALLBACK (on_configure), + gtk_surface); + + g_object_set_qdata_full (G_OBJECT (surface), + quark_gtk_surface_data, + gtk_surface, + (GDestroyNotify) gtk_surface_surface_destroyed); +} + +static void +gtk_shell_set_startup_id (struct wl_client *client, + struct wl_resource *resource, + const char *startup_id) +{ + MetaStartupSequence *sequence; + MetaDisplay *display; + + display = meta_get_display (); + + sequence = meta_startup_notification_lookup_sequence (display->startup_notification, + startup_id); + if (sequence) + meta_startup_sequence_complete (sequence); +} + +static void +gtk_shell_system_bell (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *gtk_surface_resource) +{ + MetaDisplay *display = meta_get_display (); + + if (gtk_surface_resource) + { + MetaWaylandGtkSurface *gtk_surface = + wl_resource_get_user_data (gtk_surface_resource); + MetaWaylandSurface *surface = gtk_surface->surface; + MetaWindow *window; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + meta_bell_notify (display, window); + } + else + { + meta_bell_notify (display, NULL); + } +} + +static void +gtk_shell_notify_launch (struct wl_client *client, + struct wl_resource *resource, + const char *startup_id) +{ + MetaDisplay *display = meta_get_display (); + MetaStartupSequence *sequence; + uint32_t timestamp; + + sequence = meta_startup_notification_lookup_sequence (display->startup_notification, + startup_id); + if (sequence) + { + g_warning ("Naughty client notified launch with duplicate startup_id '%s'", + startup_id); + return; + } + + timestamp = meta_display_get_current_time_roundtrip (display); + sequence = g_object_new (META_TYPE_STARTUP_SEQUENCE, + "id", startup_id, + "timestamp", timestamp, + NULL); + + meta_startup_notification_add_sequence (display->startup_notification, + sequence); + g_object_unref (sequence); +} + +static const struct gtk_shell1_interface meta_wayland_gtk_shell_interface = { + gtk_shell_get_gtk_surface, + gtk_shell_set_startup_id, + gtk_shell_system_bell, + gtk_shell_notify_launch, +}; + +static void +gtk_shell_destructor (struct wl_resource *resource) +{ + MetaWaylandGtkShell *gtk_shell = wl_resource_get_user_data (resource); + + gtk_shell->shell_resources = g_list_remove (gtk_shell->shell_resources, + resource); +} + +static void +bind_gtk_shell (struct wl_client *client, + void *data, + guint32 version, + guint32 id) +{ + MetaWaylandGtkShell *gtk_shell = data; + struct wl_resource *resource; + + resource = wl_resource_create (client, >k_shell1_interface, version, id); + wl_resource_set_implementation (resource, &meta_wayland_gtk_shell_interface, + data, gtk_shell_destructor); + + gtk_shell->shell_resources = g_list_prepend (gtk_shell->shell_resources, + resource); + + gtk_shell1_send_capabilities (resource, gtk_shell->capabilities); +} + +static void +meta_wayland_gtk_shell_init (MetaWaylandGtkShell *gtk_shell) +{ +} + +static void +meta_wayland_gtk_shell_class_init (MetaWaylandGtkShellClass *klass) +{ + quark_gtk_surface_data = + g_quark_from_static_string ("-meta-wayland-gtk-shell-surface-data"); +} + +static uint32_t +calculate_capabilities (void) +{ + uint32_t capabilities = 0; + + if (!meta_prefs_get_show_fallback_app_menu ()) + capabilities = GTK_SHELL1_CAPABILITY_GLOBAL_APP_MENU; + + return capabilities; +} + +static void +prefs_changed (MetaPreference pref, + gpointer user_data) +{ + MetaWaylandGtkShell *gtk_shell = user_data; + uint32_t new_capabilities; + GList *l; + + if (pref != META_PREF_BUTTON_LAYOUT) + return; + + new_capabilities = calculate_capabilities (); + if (gtk_shell->capabilities == new_capabilities) + return; + gtk_shell->capabilities = new_capabilities; + + for (l = gtk_shell->shell_resources; l; l = l->next) + { + struct wl_resource *resource = l->data; + + gtk_shell1_send_capabilities (resource, gtk_shell->capabilities); + } +} + +static MetaWaylandGtkShell * +meta_wayland_gtk_shell_new (MetaWaylandCompositor *compositor) +{ + MetaWaylandGtkShell *gtk_shell; + + gtk_shell = g_object_new (META_TYPE_WAYLAND_GTK_SHELL, NULL); + + if (wl_global_create (compositor->wayland_display, + >k_shell1_interface, + META_GTK_SHELL1_VERSION, + gtk_shell, bind_gtk_shell) == NULL) + g_error ("Failed to register a global gtk-shell object"); + + gtk_shell->capabilities = calculate_capabilities (); + + meta_prefs_add_listener (prefs_changed, gtk_shell); + + return gtk_shell; +} + +void +meta_wayland_init_gtk_shell (MetaWaylandCompositor *compositor) +{ + g_object_set_data_full (G_OBJECT (compositor), "-meta-wayland-gtk-shell", + meta_wayland_gtk_shell_new (compositor), + g_object_unref); +} diff --git a/src/wayland/meta-wayland-gtk-shell.h b/src/wayland/meta-wayland-gtk-shell.h new file mode 100644 index 000000000..347c1f398 --- /dev/null +++ b/src/wayland/meta-wayland-gtk-shell.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2016 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_WAYLAND_GTK_SHELL_H +#define META_WAYLAND_GTK_SHELL_H + +#include "wayland/meta-wayland.h" + +#define META_TYPE_WAYLAND_GTK_SHELL (meta_wayland_gtk_shell_get_type ()) +G_DECLARE_FINAL_TYPE (MetaWaylandGtkShell, meta_wayland_gtk_shell, + META, WAYLAND_GTK_SHELL, GObject) + +void meta_wayland_init_gtk_shell (MetaWaylandCompositor *compositor); + +#endif /* META_WAYLAND_GTK_SHELL_H */ diff --git a/src/wayland/meta-wayland-inhibit-shortcuts-dialog.c b/src/wayland/meta-wayland-inhibit-shortcuts-dialog.c new file mode 100644 index 000000000..818098460 --- /dev/null +++ b/src/wayland/meta-wayland-inhibit-shortcuts-dialog.c @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include "compositor/compositor-private.h" +#include "core/window-private.h" +#include "wayland/meta-wayland-inhibit-shortcuts-dialog.h" +#include "wayland/meta-wayland.h" +#include "wayland/meta-window-wayland.h" + +static GQuark quark_surface_inhibit_shortcuts_data = 0; + +typedef struct _InhibitShortcutsData +{ + MetaWaylandSurface *surface; + MetaWaylandSeat *seat; + MetaInhibitShortcutsDialog *dialog; + gulong response_handler_id; + gboolean has_last_response; + gboolean request_canceled; + MetaInhibitShortcutsDialogResponse last_response; +} InhibitShortcutsData; + +static InhibitShortcutsData * +surface_inhibit_shortcuts_data_get (MetaWaylandSurface *surface) +{ + return g_object_get_qdata (G_OBJECT (surface), + quark_surface_inhibit_shortcuts_data); +} + +static void +surface_inhibit_shortcuts_data_set (MetaWaylandSurface *surface, + InhibitShortcutsData *data) +{ + g_object_set_qdata (G_OBJECT (surface), + quark_surface_inhibit_shortcuts_data, + data); +} + +static void +surface_inhibit_shortcuts_data_destroy_dialog (InhibitShortcutsData *data) +{ + g_clear_signal_handler (&data->response_handler_id, data->dialog); + meta_inhibit_shortcuts_dialog_hide (data->dialog); + g_clear_object (&data->dialog); +} + +static void +surface_inhibit_shortcuts_data_free (InhibitShortcutsData *data) +{ + if (data->dialog) + surface_inhibit_shortcuts_data_destroy_dialog (data); + g_free (data); +} + +static void +on_surface_destroyed (MetaWaylandSurface *surface, + InhibitShortcutsData *data) +{ + surface_inhibit_shortcuts_data_free (data); + g_object_set_qdata (G_OBJECT (surface), + quark_surface_inhibit_shortcuts_data, + NULL); +} + +static void +inhibit_shortcuts_dialog_response_apply (InhibitShortcutsData *data) +{ + if (data->last_response == META_INHIBIT_SHORTCUTS_DIALOG_RESPONSE_ALLOW) + meta_wayland_surface_inhibit_shortcuts (data->surface, data->seat); + else if (meta_wayland_surface_is_shortcuts_inhibited (data->surface, data->seat)) + meta_wayland_surface_restore_shortcuts (data->surface, data->seat); +} + +static void +inhibit_shortcuts_dialog_response_cb (MetaInhibitShortcutsDialog *dialog, + MetaInhibitShortcutsDialogResponse response, + InhibitShortcutsData *data) +{ + data->last_response = response; + data->has_last_response = TRUE; + + /* If the request was canceled, we don't need to apply the choice made */ + if (!data->request_canceled) + inhibit_shortcuts_dialog_response_apply (data); + + meta_inhibit_shortcuts_dialog_hide (data->dialog); + surface_inhibit_shortcuts_data_destroy_dialog (data); +} + +static InhibitShortcutsData * +meta_wayland_surface_ensure_inhibit_shortcuts_dialog (MetaWaylandSurface *surface, + MetaWaylandSeat *seat) +{ + InhibitShortcutsData *data; + MetaWindow *window; + MetaDisplay *display; + MetaInhibitShortcutsDialog *dialog; + + data = surface_inhibit_shortcuts_data_get (surface); + if (data) + return data; + + data = g_new0 (InhibitShortcutsData, 1); + surface_inhibit_shortcuts_data_set (surface, data); + g_signal_connect (surface, "destroy", + G_CALLBACK (on_surface_destroyed), + data); + + window = meta_wayland_surface_get_toplevel_window (surface); + display = window->display; + dialog = + meta_compositor_create_inhibit_shortcuts_dialog (display->compositor, + window); + + data->surface = surface; + data->seat = seat; + data->dialog = dialog; + data->response_handler_id = + g_signal_connect (dialog, "response", + G_CALLBACK (inhibit_shortcuts_dialog_response_cb), + data); + + return data; +} + +void +meta_wayland_surface_show_inhibit_shortcuts_dialog (MetaWaylandSurface *surface, + MetaWaylandSeat *seat) +{ + InhibitShortcutsData *data; + + g_return_if_fail (META_IS_WAYLAND_SURFACE (surface)); + + data = surface_inhibit_shortcuts_data_get (surface); + if (data && data->has_last_response) + { + /* The dialog was shown before for this surface but is not showing + * anymore, reuse the last user response. + */ + inhibit_shortcuts_dialog_response_apply (data); + return; + } + + data = meta_wayland_surface_ensure_inhibit_shortcuts_dialog (surface, seat); + /* This is a new request */ + data->request_canceled = FALSE; + + meta_inhibit_shortcuts_dialog_show (data->dialog); +} + +void +meta_wayland_surface_cancel_inhibit_shortcuts_dialog (MetaWaylandSurface *surface) +{ + InhibitShortcutsData *data; + + g_return_if_fail (META_IS_WAYLAND_SURFACE (surface)); + + /* The closure notify will take care of actually hiding the dialog */ + data = surface_inhibit_shortcuts_data_get (surface); + g_return_if_fail (data); + + /* Keep the dialog on screen, but mark the request as canceled */ + data->request_canceled = TRUE; +} + +void +meta_wayland_surface_inhibit_shortcuts_dialog_init (void) +{ + quark_surface_inhibit_shortcuts_data = + g_quark_from_static_string ("-meta-wayland-surface-inhibit-shortcuts-data"); +} diff --git a/src/wayland/meta-wayland-inhibit-shortcuts-dialog.h b/src/wayland/meta-wayland-inhibit-shortcuts-dialog.h new file mode 100644 index 000000000..7f3501565 --- /dev/null +++ b/src/wayland/meta-wayland-inhibit-shortcuts-dialog.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + */ + +#ifndef META_WAYLAND_INHIBIT_SHORTCUTS_DIALOG_H +#define META_WAYLAND_INHIBIT_SHORTCUTS_DIALOG_H + +#include "wayland/meta-wayland-private.h" + +void meta_wayland_surface_show_inhibit_shortcuts_dialog (MetaWaylandSurface *surface, + MetaWaylandSeat *seat); + +void meta_wayland_surface_cancel_inhibit_shortcuts_dialog (MetaWaylandSurface *surface); + +void meta_wayland_surface_inhibit_shortcuts_dialog_init (void); + +#endif /* META_WAYLAND_INHIBIT_SHORTCUTS_DIALOG_H */ diff --git a/src/wayland/meta-wayland-inhibit-shortcuts.c b/src/wayland/meta-wayland-inhibit-shortcuts.c new file mode 100644 index 000000000..68e90eec2 --- /dev/null +++ b/src/wayland/meta-wayland-inhibit-shortcuts.c @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Olivier Fourdan <ofourdan@redhat.com> + */ + +#include "config.h" + +#include <wayland-server.h> + +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-wayland-versions.h" +#include "wayland/meta-wayland-inhibit-shortcuts.h" +#include "wayland/meta-wayland-inhibit-shortcuts-dialog.h" + +#include "keyboard-shortcuts-inhibit-unstable-v1-server-protocol.h" + +struct _MetaWaylandKeyboardShotscutsInhibit +{ + MetaWaylandSurface *surface; + MetaWaylandSeat *seat; + gulong inhibit_shortcut_handler; + gulong restore_shortcut_handler; + gulong surface_destroyed_handler; + struct wl_resource *resource; +}; + +static void +zwp_keyboard_shortcuts_inhibit_destructor (struct wl_resource *resource) +{ + MetaWaylandKeyboardShotscutsInhibit *shortcut_inhibit; + + shortcut_inhibit = wl_resource_get_user_data (resource); + if (shortcut_inhibit->surface) + { + meta_wayland_surface_cancel_inhibit_shortcuts_dialog (shortcut_inhibit->surface); + + g_clear_signal_handler (&shortcut_inhibit->surface_destroyed_handler, + shortcut_inhibit->surface); + + g_clear_signal_handler (&shortcut_inhibit->inhibit_shortcut_handler, + shortcut_inhibit->surface); + + g_clear_signal_handler (&shortcut_inhibit->restore_shortcut_handler, + shortcut_inhibit->surface); + + meta_wayland_surface_restore_shortcuts (shortcut_inhibit->surface, + shortcut_inhibit->seat); + } + g_free (shortcut_inhibit); +} + +static void +zwp_keyboard_shortcuts_inhibit_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static const struct zwp_keyboard_shortcuts_inhibit_manager_v1_interface + meta_keyboard_shortcuts_inhibit_interface = { + zwp_keyboard_shortcuts_inhibit_destroy, + }; + +static void +surface_destroyed_cb (MetaWaylandSurface *surface, + MetaWaylandKeyboardShotscutsInhibit *shortcut_inhibit) +{ + shortcut_inhibit->surface = NULL; + shortcut_inhibit->seat = NULL; +} + +static void +shortcuts_inhibited_cb (MetaWaylandSurface *surface, + MetaWaylandKeyboardShotscutsInhibit *shortcut_inhibit) +{ + zwp_keyboard_shortcuts_inhibitor_v1_send_active (shortcut_inhibit->resource); +} + +static void +shortcuts_restored_cb (MetaWaylandSurface *surface, + MetaWaylandKeyboardShotscutsInhibit *shortcut_inhibit) +{ + zwp_keyboard_shortcuts_inhibitor_v1_send_inactive (shortcut_inhibit->resource); +} + +static void +zwp_keyboard_shortcuts_inhibit_manager_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +zwp_keyboard_shortcuts_inhibit_manager_inhibit_shortcuts (struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *surface_resource, + struct wl_resource *seat_resource) +{ + MetaWaylandKeyboardShotscutsInhibit *shortcut_inhibit; + MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); + struct wl_resource *keyboard_shortcuts_inhibit_resource; + + keyboard_shortcuts_inhibit_resource = + wl_resource_create (client, + &zwp_keyboard_shortcuts_inhibitor_v1_interface, + META_ZWP_KEYBOARD_SHORTCUTS_INHIBIT_V1_VERSION, + id); + + shortcut_inhibit = g_new0 (MetaWaylandKeyboardShotscutsInhibit, 1); + shortcut_inhibit->surface = surface; + shortcut_inhibit->seat = seat; + shortcut_inhibit->resource = keyboard_shortcuts_inhibit_resource; + + shortcut_inhibit->inhibit_shortcut_handler = + g_signal_connect (surface, "shortcuts-inhibited", + G_CALLBACK (shortcuts_inhibited_cb), + shortcut_inhibit); + shortcut_inhibit->restore_shortcut_handler = + g_signal_connect (surface, "shortcuts-restored", + G_CALLBACK (shortcuts_restored_cb), + shortcut_inhibit); + shortcut_inhibit->surface_destroyed_handler = + g_signal_connect (surface, "destroy", + G_CALLBACK (surface_destroyed_cb), + shortcut_inhibit); + + /* Cannot grant shortcuts to a surface without any window */ + if (meta_wayland_surface_get_toplevel_window (surface)) + meta_wayland_surface_show_inhibit_shortcuts_dialog (surface, seat); + + wl_resource_set_implementation (keyboard_shortcuts_inhibit_resource, + &meta_keyboard_shortcuts_inhibit_interface, + shortcut_inhibit, + zwp_keyboard_shortcuts_inhibit_destructor); +} + +static const struct zwp_keyboard_shortcuts_inhibit_manager_v1_interface + meta_keyboard_shortcuts_inhibit_manager_interface = { + zwp_keyboard_shortcuts_inhibit_manager_destroy, + zwp_keyboard_shortcuts_inhibit_manager_inhibit_shortcuts, + }; + +static void +bind_keyboard_shortcuts_inhibit (struct wl_client *client, + void *data, + uint32_t version, + uint32_t id) +{ + struct wl_resource *resource; + + resource = wl_resource_create (client, + &zwp_keyboard_shortcuts_inhibit_manager_v1_interface, + META_ZWP_KEYBOARD_SHORTCUTS_INHIBIT_V1_VERSION, + id); + + wl_resource_set_implementation (resource, + &meta_keyboard_shortcuts_inhibit_manager_interface, + NULL, NULL); +} + +gboolean +meta_wayland_keyboard_shortcuts_inhibit_init (MetaWaylandCompositor *compositor) +{ + return (wl_global_create (compositor->wayland_display, + &zwp_keyboard_shortcuts_inhibit_manager_v1_interface, + META_ZWP_KEYBOARD_SHORTCUTS_INHIBIT_V1_VERSION, + NULL, + bind_keyboard_shortcuts_inhibit) != NULL); +} diff --git a/src/wayland/meta-wayland-inhibit-shortcuts.h b/src/wayland/meta-wayland-inhibit-shortcuts.h new file mode 100644 index 000000000..52b2240c4 --- /dev/null +++ b/src/wayland/meta-wayland-inhibit-shortcuts.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Olivier Fourdan <ofourdan@redhat.com> + */ + +#ifndef META_WAYLAND_INHIBIT_SHORTCUTS_H +#define META_WAYLAND_INHIBIT_SHORTCUTS_H + +#include <wayland-server.h> + +#include "meta/window.h" +#include "wayland/meta-wayland-types.h" + +#define META_TYPE_WAYLAND_KEYBOARD_SHORTCUTS_INHIBIT (meta_wayland_keyboard_shortcuts_inhibit_resource_get_type ()) +G_DECLARE_FINAL_TYPE (MetaWaylandKeyboardShotscutsInhibit, + meta_wayland_keyboard_shortcuts_inhibit_resource, + META, WAYLAND_KEYBOARD_SHORTCUTS_INHIBIT, + GObject); + +gboolean meta_wayland_keyboard_shortcuts_inhibit_init (MetaWaylandCompositor *compositor); + +#endif /* META_WAYLAND_INHIBIT_SHORTCUTS_H */ diff --git a/src/wayland/meta-wayland-input-device.c b/src/wayland/meta-wayland-input-device.c new file mode 100644 index 000000000..b82f204cf --- /dev/null +++ b/src/wayland/meta-wayland-input-device.c @@ -0,0 +1,129 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +#include "config.h" + +#include "wayland/meta-wayland-input-device.h" + +#include <wayland-server.h> + +#include "wayland/meta-wayland-seat.h" + +enum +{ + PROP_0, + + PROP_SEAT +}; + +typedef struct _MetaWaylandInputDevicePrivate +{ + MetaWaylandSeat *seat; +} MetaWaylandInputDevicePrivate; + +G_DEFINE_TYPE_WITH_PRIVATE (MetaWaylandInputDevice, + meta_wayland_input_device, + G_TYPE_OBJECT) + +MetaWaylandSeat * +meta_wayland_input_device_get_seat (MetaWaylandInputDevice *input_device) +{ + MetaWaylandInputDevicePrivate *priv = + meta_wayland_input_device_get_instance_private (input_device); + + return priv->seat; +} + +uint32_t +meta_wayland_input_device_next_serial (MetaWaylandInputDevice *input_device) +{ + MetaWaylandSeat *seat = meta_wayland_input_device_get_seat (input_device); + + return wl_display_next_serial (seat->wl_display); +} + +static void +meta_wayland_input_device_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaWaylandInputDevice *input_device = META_WAYLAND_INPUT_DEVICE (object); + MetaWaylandInputDevicePrivate *priv = + meta_wayland_input_device_get_instance_private (input_device); + + switch (prop_id) + { + case PROP_SEAT: + priv->seat = g_value_get_pointer (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_wayland_input_device_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaWaylandInputDevice *input_device = META_WAYLAND_INPUT_DEVICE (object); + MetaWaylandInputDevicePrivate *priv = + meta_wayland_input_device_get_instance_private (input_device); + + switch (prop_id) + { + case PROP_SEAT: + g_value_set_pointer (value, priv->seat); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_wayland_input_device_init (MetaWaylandInputDevice *input_device) +{ +} + +static void +meta_wayland_input_device_class_init (MetaWaylandInputDeviceClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GParamSpec *pspec; + + object_class->set_property = meta_wayland_input_device_set_property; + object_class->get_property = meta_wayland_input_device_get_property; + + pspec = g_param_spec_pointer ("seat", + "MetaWaylandSeat", + "The seat", + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS | + G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (object_class, PROP_SEAT, pspec); +} diff --git a/src/wayland/meta-wayland-input-device.h b/src/wayland/meta-wayland-input-device.h new file mode 100644 index 000000000..c6a6c3d38 --- /dev/null +++ b/src/wayland/meta-wayland-input-device.h @@ -0,0 +1,48 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +#ifndef META_WAYLAND_INPUT_DEVICE_H +#define META_WAYLAND_INPUT_DEVICE_H + +#include <glib-object.h> +#include <stdint.h> + +#include "wayland/meta-wayland-types.h" + +#define META_TYPE_WAYLAND_INPUT_DEVICE (meta_wayland_input_device_get_type ()) +G_DECLARE_DERIVABLE_TYPE (MetaWaylandInputDevice, + meta_wayland_input_device, + META, WAYLAND_INPUT_DEVICE, + GObject) + +struct _MetaWaylandInputDeviceClass +{ + GObjectClass parent_class; +}; + +MetaWaylandSeat * meta_wayland_input_device_get_seat (MetaWaylandInputDevice *input_device); + +uint32_t meta_wayland_input_device_next_serial (MetaWaylandInputDevice *input_device); + +#endif /* META_WAYLAND_INPUT_DEVICE_H */ diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c new file mode 100644 index 000000000..6b6c1f778 --- /dev/null +++ b/src/wayland/meta-wayland-keyboard.c @@ -0,0 +1,933 @@ +/* + * Wayland Support + * + * Copyright (C) 2013 Intel Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +/* + * Copyright © 2010-2011 Intel Corporation + * Copyright © 2008-2011 Kristian Høgsberg + * Copyright © 2012 Collabora, Ltd. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holders not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. The copyright holders make + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* The file is based on src/input.c from Weston */ + +#include "config.h" + +#include <errno.h> +#include <fcntl.h> +#include <glib.h> +#include <stdlib.h> +#include <string.h> +#include <sys/mman.h> +#include <unistd.h> + +#include "backends/meta-backend-private.h" +#include "core/display-private.h" +#include "wayland/meta-wayland-private.h" + +#ifdef HAVE_NATIVE_BACKEND +#include "backends/native/meta-backend-native.h" +#include "backends/native/meta-event-native.h" +#endif + +#define GSD_KEYBOARD_SCHEMA "org.gnome.settings-daemon.peripherals.keyboard" + +G_DEFINE_TYPE (MetaWaylandKeyboard, meta_wayland_keyboard, + META_TYPE_WAYLAND_INPUT_DEVICE) + +static void meta_wayland_keyboard_update_xkb_state (MetaWaylandKeyboard *keyboard); +static void notify_modifiers (MetaWaylandKeyboard *keyboard); +static guint evdev_code (const ClutterKeyEvent *event); + +static void +unbind_resource (struct wl_resource *resource) +{ + wl_list_remove (wl_resource_get_link (resource)); +} + +static int +create_anonymous_file (off_t size, + GError **error) +{ + static const char template[] = "mutter-shared-XXXXXX"; + char *path; + int fd, flags; + + fd = g_file_open_tmp (template, &path, error); + + if (fd == -1) + return -1; + + unlink (path); + g_free (path); + + flags = fcntl (fd, F_GETFD); + if (flags == -1) + goto err; + + if (fcntl (fd, F_SETFD, flags | FD_CLOEXEC) == -1) + goto err; + + if (ftruncate (fd, size) < 0) + goto err; + + return fd; + + err: + g_set_error_literal (error, + G_FILE_ERROR, + g_file_error_from_errno (errno), + strerror (errno)); + close (fd); + + return -1; +} + +static void +send_keymap (MetaWaylandKeyboard *keyboard, + struct wl_resource *resource) +{ + MetaWaylandXkbInfo *xkb_info = &keyboard->xkb_info; + GError *error = NULL; + int fd; + char *keymap_area; + + if (!xkb_info->keymap_string) + return; + + fd = create_anonymous_file (xkb_info->keymap_size, &error); + if (fd < 0) + { + g_warning ("Creating a keymap file for %lu bytes failed: %s", + (unsigned long) xkb_info->keymap_size, + error->message); + g_clear_error (&error); + return; + } + + + keymap_area = mmap (NULL, xkb_info->keymap_size, + PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (keymap_area == MAP_FAILED) + { + g_warning ("Failed to mmap() %lu bytes\n", + (unsigned long) xkb_info->keymap_size); + close (fd); + return; + } + + strcpy (keymap_area, xkb_info->keymap_string); + + munmap (keymap_area, xkb_info->keymap_size); + + wl_keyboard_send_keymap (resource, + WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, + fd, + keyboard->xkb_info.keymap_size); + close (fd); +} + +static void +inform_clients_of_new_keymap (MetaWaylandKeyboard *keyboard) +{ + struct wl_resource *keyboard_resource; + + wl_resource_for_each (keyboard_resource, &keyboard->resource_list) + send_keymap (keyboard, keyboard_resource); + wl_resource_for_each (keyboard_resource, &keyboard->focus_resource_list) + send_keymap (keyboard, keyboard_resource); +} + +static void +meta_wayland_keyboard_take_keymap (MetaWaylandKeyboard *keyboard, + struct xkb_keymap *keymap) +{ + MetaWaylandXkbInfo *xkb_info = &keyboard->xkb_info; + + if (keymap == NULL) + { + g_warning ("Attempting to set null keymap (compilation probably failed)"); + return; + } + + g_clear_pointer (&xkb_info->keymap_string, g_free); + xkb_keymap_unref (xkb_info->keymap); + xkb_info->keymap = xkb_keymap_ref (keymap); + + meta_wayland_keyboard_update_xkb_state (keyboard); + + xkb_info->keymap_string = + xkb_keymap_get_as_string (xkb_info->keymap, XKB_KEYMAP_FORMAT_TEXT_V1); + if (!xkb_info->keymap_string) + { + g_warning ("Failed to get string version of keymap"); + return; + } + xkb_info->keymap_size = strlen (xkb_info->keymap_string) + 1; + + inform_clients_of_new_keymap (keyboard); + + notify_modifiers (keyboard); +} + +static xkb_mod_mask_t +kbd_a11y_apply_mask (MetaWaylandKeyboard *keyboard) +{ + xkb_mod_mask_t latched, locked, depressed, group; + xkb_mod_mask_t update_mask = 0; + + depressed = xkb_state_serialize_mods(keyboard->xkb_info.state, XKB_STATE_DEPRESSED); + latched = xkb_state_serialize_mods (keyboard->xkb_info.state, XKB_STATE_MODS_LATCHED); + locked = xkb_state_serialize_mods (keyboard->xkb_info.state, XKB_STATE_MODS_LOCKED); + group = xkb_state_serialize_layout (keyboard->xkb_info.state, XKB_STATE_LAYOUT_EFFECTIVE); + + if ((latched & keyboard->kbd_a11y_latched_mods) != keyboard->kbd_a11y_latched_mods) + update_mask |= XKB_STATE_MODS_LATCHED; + + if ((locked & keyboard->kbd_a11y_locked_mods) != keyboard->kbd_a11y_locked_mods) + update_mask |= XKB_STATE_MODS_LOCKED; + + if (update_mask) + { + latched |= keyboard->kbd_a11y_latched_mods; + locked |= keyboard->kbd_a11y_locked_mods; + xkb_state_update_mask (keyboard->xkb_info.state, depressed, latched, locked, 0, 0, group); + } + + return update_mask; +} + +static void +on_keymap_changed (MetaBackend *backend, + gpointer data) +{ + MetaWaylandKeyboard *keyboard = data; + + meta_wayland_keyboard_take_keymap (keyboard, meta_backend_get_keymap (backend)); +} + +static void +on_keymap_layout_group_changed (MetaBackend *backend, + guint idx, + gpointer data) +{ + MetaWaylandKeyboard *keyboard = data; + xkb_mod_mask_t depressed_mods; + xkb_mod_mask_t latched_mods; + xkb_mod_mask_t locked_mods; + struct xkb_state *state; + + state = keyboard->xkb_info.state; + + depressed_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_DEPRESSED); + latched_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_LATCHED); + locked_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED); + + xkb_state_update_mask (state, depressed_mods, latched_mods, locked_mods, 0, 0, idx); + kbd_a11y_apply_mask (keyboard); + + notify_modifiers (keyboard); +} + +static void +keyboard_handle_focus_surface_destroy (struct wl_listener *listener, void *data) +{ + MetaWaylandKeyboard *keyboard = wl_container_of (listener, keyboard, + focus_surface_listener); + + meta_wayland_keyboard_set_focus (keyboard, NULL); +} + +static gboolean +meta_wayland_keyboard_broadcast_key (MetaWaylandKeyboard *keyboard, + uint32_t time, + uint32_t key, + uint32_t state) +{ + struct wl_resource *resource; + + if (!wl_list_empty (&keyboard->focus_resource_list)) + { + MetaWaylandInputDevice *input_device = + META_WAYLAND_INPUT_DEVICE (keyboard); + uint32_t serial; + + serial = meta_wayland_input_device_next_serial (input_device); + + if (state) + { + keyboard->key_down_serial = serial; + keyboard->key_down_keycode = key; + } + else + { + keyboard->key_up_serial = serial; + keyboard->key_up_keycode = key; + } + + wl_resource_for_each (resource, &keyboard->focus_resource_list) + wl_keyboard_send_key (resource, serial, time, key, state); + } + + /* Eat the key events if we have a focused surface. */ + return (keyboard->focus_surface != NULL); +} + +static gboolean +notify_key (MetaWaylandKeyboard *keyboard, + const ClutterEvent *event) +{ + return keyboard->grab->interface->key (keyboard->grab, event); +} + +static xkb_mod_mask_t +add_vmod (xkb_mod_mask_t mask, + xkb_mod_mask_t mod, + xkb_mod_mask_t vmod, + xkb_mod_mask_t *added) +{ + if ((mask & mod) && !(mod & *added)) + { + mask |= vmod; + *added |= mod; + } + return mask; +} + +static xkb_mod_mask_t +add_virtual_mods (xkb_mod_mask_t mask) +{ + MetaKeyBindingManager *keys = &(meta_get_display ()->key_binding_manager); + xkb_mod_mask_t added; + guint i; + /* Order is important here: if multiple vmods share the same real + modifier we only want to add the first. */ + struct { + xkb_mod_mask_t mod; + xkb_mod_mask_t vmod; + } mods[] = { + { keys->super_mask, keys->virtual_super_mask }, + { keys->hyper_mask, keys->virtual_hyper_mask }, + { keys->meta_mask, keys->virtual_meta_mask }, + }; + + added = 0; + for (i = 0; i < G_N_ELEMENTS (mods); ++i) + mask = add_vmod (mask, mods[i].mod, mods[i].vmod, &added); + + return mask; +} + +static void +keyboard_send_modifiers (MetaWaylandKeyboard *keyboard, + struct wl_resource *resource, + uint32_t serial) +{ + struct xkb_state *state = keyboard->xkb_info.state; + xkb_mod_mask_t depressed, latched, locked; + + depressed = add_virtual_mods (xkb_state_serialize_mods (state, XKB_STATE_MODS_DEPRESSED)); + latched = add_virtual_mods (xkb_state_serialize_mods (state, XKB_STATE_MODS_LATCHED)); + locked = add_virtual_mods (xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED)); + + wl_keyboard_send_modifiers (resource, serial, depressed, latched, locked, + xkb_state_serialize_layout (state, XKB_STATE_LAYOUT_EFFECTIVE)); +} + +static void +meta_wayland_keyboard_broadcast_modifiers (MetaWaylandKeyboard *keyboard) +{ + struct wl_resource *resource; + + if (!wl_list_empty (&keyboard->focus_resource_list)) + { + MetaWaylandInputDevice *input_device = + META_WAYLAND_INPUT_DEVICE (keyboard); + uint32_t serial; + + serial = meta_wayland_input_device_next_serial (input_device); + + wl_resource_for_each (resource, &keyboard->focus_resource_list) + keyboard_send_modifiers (keyboard, resource, serial); + } +} + +static void +notify_modifiers (MetaWaylandKeyboard *keyboard) +{ + struct xkb_state *state; + + state = keyboard->xkb_info.state; + keyboard->grab->interface->modifiers (keyboard->grab, + xkb_state_serialize_mods (state, XKB_STATE_MODS_EFFECTIVE)); +} + +static void +meta_wayland_keyboard_update_xkb_state (MetaWaylandKeyboard *keyboard) +{ + MetaWaylandXkbInfo *xkb_info = &keyboard->xkb_info; + xkb_mod_mask_t latched, locked, numlock; + MetaBackend *backend = meta_get_backend (); + xkb_layout_index_t layout_idx; + ClutterKeymap *keymap; + ClutterSeat *seat; + + /* Preserve latched/locked modifiers state */ + if (xkb_info->state) + { + latched = xkb_state_serialize_mods (xkb_info->state, XKB_STATE_MODS_LATCHED); + locked = xkb_state_serialize_mods (xkb_info->state, XKB_STATE_MODS_LOCKED); + xkb_state_unref (xkb_info->state); + } + else + { + latched = locked = 0; + } + + seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); + keymap = clutter_seat_get_keymap (seat); + numlock = (1 << xkb_keymap_mod_get_index (xkb_info->keymap, "Mod2")); + + if (clutter_keymap_get_num_lock_state (keymap)) + locked |= numlock; + else + locked &= ~numlock; + + xkb_info->state = xkb_state_new (xkb_info->keymap); + + layout_idx = meta_backend_get_keymap_layout_group (backend); + xkb_state_update_mask (xkb_info->state, 0, latched, locked, 0, 0, layout_idx); + + kbd_a11y_apply_mask (keyboard); +} + +static void +on_kbd_a11y_mask_changed (ClutterSeat *seat, + xkb_mod_mask_t new_latched_mods, + xkb_mod_mask_t new_locked_mods, + MetaWaylandKeyboard *keyboard) +{ + xkb_mod_mask_t latched, locked, depressed, group; + + if (keyboard->xkb_info.state == NULL) + return; + + depressed = xkb_state_serialize_mods(keyboard->xkb_info.state, XKB_STATE_DEPRESSED); + latched = xkb_state_serialize_mods (keyboard->xkb_info.state, XKB_STATE_MODS_LATCHED); + locked = xkb_state_serialize_mods (keyboard->xkb_info.state, XKB_STATE_MODS_LOCKED); + group = xkb_state_serialize_layout (keyboard->xkb_info.state, XKB_STATE_LAYOUT_EFFECTIVE); + + /* Clear previous masks */ + latched &= ~keyboard->kbd_a11y_latched_mods; + locked &= ~keyboard->kbd_a11y_locked_mods; + xkb_state_update_mask (keyboard->xkb_info.state, depressed, latched, locked, 0, 0, group); + + /* Apply new masks */ + keyboard->kbd_a11y_latched_mods = new_latched_mods; + keyboard->kbd_a11y_locked_mods = new_locked_mods; + kbd_a11y_apply_mask (keyboard); + + notify_modifiers (keyboard); +} + +static void +notify_key_repeat_for_resource (MetaWaylandKeyboard *keyboard, + struct wl_resource *keyboard_resource) +{ + if (wl_resource_get_version (keyboard_resource) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) + { + gboolean repeat; + unsigned int delay, rate; + + repeat = g_settings_get_boolean (keyboard->settings, "repeat"); + + if (repeat) + { + unsigned int interval; + interval = g_settings_get_uint (keyboard->settings, "repeat-interval"); + /* Our setting is in the milliseconds between keys. "rate" is the number + * of keys per second. */ + if (interval > 0) + rate = (1000 / interval); + else + rate = 0; + + delay = g_settings_get_uint (keyboard->settings, "delay"); + } + else + { + rate = 0; + delay = 0; + } + + wl_keyboard_send_repeat_info (keyboard_resource, rate, delay); + } +} + +static void +notify_key_repeat (MetaWaylandKeyboard *keyboard) +{ + struct wl_resource *keyboard_resource; + + wl_resource_for_each (keyboard_resource, &keyboard->resource_list) + { + notify_key_repeat_for_resource (keyboard, keyboard_resource); + } + + wl_resource_for_each (keyboard_resource, &keyboard->focus_resource_list) + { + notify_key_repeat_for_resource (keyboard, keyboard_resource); + } +} + +static void +settings_changed (GSettings *settings, + const char *key, + gpointer data) +{ + MetaWaylandKeyboard *keyboard = data; + + notify_key_repeat (keyboard); +} + +static gboolean +default_grab_key (MetaWaylandKeyboardGrab *grab, + const ClutterEvent *event) +{ + MetaWaylandKeyboard *keyboard = grab->keyboard; + gboolean is_press = event->type == CLUTTER_KEY_PRESS; + guint32 code = 0; +#ifdef HAVE_NATIVE_BACKEND + MetaBackend *backend = meta_get_backend (); +#endif + + /* Ignore autorepeat events, as autorepeat in Wayland is done on the client + * side. */ + if (event->key.flags & CLUTTER_EVENT_FLAG_REPEATED) + return FALSE; + +#ifdef HAVE_NATIVE_BACKEND + if (META_IS_BACKEND_NATIVE (backend)) + code = meta_event_native_get_event_code (event); + if (code == 0) +#endif + code = evdev_code (&event->key); + + return meta_wayland_keyboard_broadcast_key (keyboard, event->key.time, + code, is_press); +} + +static void +default_grab_modifiers (MetaWaylandKeyboardGrab *grab, + ClutterModifierType modifiers) +{ + meta_wayland_keyboard_broadcast_modifiers (grab->keyboard); +} + +static const MetaWaylandKeyboardGrabInterface default_keyboard_grab_interface = { + default_grab_key, + default_grab_modifiers +}; + +void +meta_wayland_keyboard_enable (MetaWaylandKeyboard *keyboard) +{ + MetaBackend *backend = meta_get_backend (); + ClutterBackend *clutter_backend = clutter_get_default_backend (); + + keyboard->settings = g_settings_new ("org.gnome.desktop.peripherals.keyboard"); + g_signal_connect (keyboard->settings, "changed", + G_CALLBACK (settings_changed), keyboard); + + g_signal_connect (backend, "keymap-changed", + G_CALLBACK (on_keymap_changed), keyboard); + g_signal_connect (backend, "keymap-layout-group-changed", + G_CALLBACK (on_keymap_layout_group_changed), keyboard); + + g_signal_connect (clutter_backend_get_default_seat (clutter_backend), + "kbd-a11y-mods-state-changed", + G_CALLBACK (on_kbd_a11y_mask_changed), keyboard); + + meta_wayland_keyboard_take_keymap (keyboard, meta_backend_get_keymap (backend)); +} + +static void +meta_wayland_xkb_info_destroy (MetaWaylandXkbInfo *xkb_info) +{ + g_clear_pointer (&xkb_info->keymap, xkb_keymap_unref); + g_clear_pointer (&xkb_info->state, xkb_state_unref); + g_clear_pointer (&xkb_info->keymap_string, g_free); +} + +void +meta_wayland_keyboard_disable (MetaWaylandKeyboard *keyboard) +{ + MetaBackend *backend = meta_get_backend (); + + g_signal_handlers_disconnect_by_func (backend, on_keymap_changed, keyboard); + g_signal_handlers_disconnect_by_func (backend, on_keymap_layout_group_changed, keyboard); + + meta_wayland_keyboard_end_grab (keyboard); + meta_wayland_keyboard_set_focus (keyboard, NULL); + + wl_list_remove (&keyboard->resource_list); + wl_list_init (&keyboard->resource_list); + wl_list_remove (&keyboard->focus_resource_list); + wl_list_init (&keyboard->focus_resource_list); + + g_clear_object (&keyboard->settings); +} + +static guint +evdev_code (const ClutterKeyEvent *event) +{ + /* clutter-xkb-utils.c adds a fixed offset of 8 to go into XKB's + * range, so we do the reverse here. */ + return event->hardware_keycode - 8; +} + +void +meta_wayland_keyboard_update (MetaWaylandKeyboard *keyboard, + const ClutterKeyEvent *event) +{ + gboolean is_press = event->type == CLUTTER_KEY_PRESS; + + /* Only handle real, non-synthetic, events here. The IM is free to reemit + * key events (incl. modifiers), handling those additionally will result + * in doubly-pressed keys. + */ + if ((event->flags & + (CLUTTER_EVENT_FLAG_SYNTHETIC | CLUTTER_EVENT_FLAG_INPUT_METHOD)) != 0) + return; + + /* If we get a key event but still have pending modifier state + * changes from a previous event that didn't get cleared, we need to + * send that state right away so that the new key event can be + * interpreted by clients correctly modified. */ + if (keyboard->mods_changed) + notify_modifiers (keyboard); + + keyboard->mods_changed = xkb_state_update_key (keyboard->xkb_info.state, + event->hardware_keycode, + is_press ? XKB_KEY_DOWN : XKB_KEY_UP); + keyboard->mods_changed |= kbd_a11y_apply_mask (keyboard); +} + +gboolean +meta_wayland_keyboard_handle_event (MetaWaylandKeyboard *keyboard, + const ClutterKeyEvent *event) +{ +#ifdef WITH_VERBOSE_MODE + gboolean is_press = event->type == CLUTTER_KEY_PRESS; +#endif + gboolean handled; + + /* Synthetic key events are for autorepeat. Ignore those, as + * autorepeat in Wayland is done on the client side. */ + if ((event->flags & CLUTTER_EVENT_FLAG_SYNTHETIC) && + !(event->flags & CLUTTER_EVENT_FLAG_INPUT_METHOD)) + return FALSE; + + meta_verbose ("Handling key %s event code %d\n", + is_press ? "press" : "release", + event->hardware_keycode); + + handled = notify_key (keyboard, (const ClutterEvent *) event); + + if (handled) + meta_verbose ("Sent event to wayland client\n"); + else + meta_verbose ("No wayland surface is focused, continuing normal operation\n"); + + if (keyboard->mods_changed != 0) + { + notify_modifiers (keyboard); + keyboard->mods_changed = 0; + } + + return handled; +} + +void +meta_wayland_keyboard_update_key_state (MetaWaylandKeyboard *keyboard, + char *key_vector, + int key_vector_len, + int offset) +{ + gboolean mods_changed = FALSE; + + int i; + for (i = offset; i < key_vector_len * 8; i++) + { + gboolean set = (key_vector[i/8] & (1 << (i % 8))) != 0; + + /* The 'offset' parameter allows the caller to have the indices + * into key_vector to either be X-style (base 8) or evdev (base 0), or + * something else (unlikely). We subtract 'offset' to convert to evdev + * style, then add 8 to convert the "evdev" style keycode back to + * the X-style that xkbcommon expects. + */ + mods_changed |= xkb_state_update_key (keyboard->xkb_info.state, + i - offset + 8, + set ? XKB_KEY_DOWN : XKB_KEY_UP); + } + + mods_changed |= kbd_a11y_apply_mask (keyboard); + if (mods_changed) + notify_modifiers (keyboard); +} + +static void +move_resources (struct wl_list *destination, struct wl_list *source) +{ + wl_list_insert_list (destination, source); + wl_list_init (source); +} + +static void +move_resources_for_client (struct wl_list *destination, + struct wl_list *source, + struct wl_client *client) +{ + struct wl_resource *resource, *tmp; + wl_resource_for_each_safe (resource, tmp, source) + { + if (wl_resource_get_client (resource) == client) + { + wl_list_remove (wl_resource_get_link (resource)); + wl_list_insert (destination, wl_resource_get_link (resource)); + } + } +} + +static void +broadcast_focus (MetaWaylandKeyboard *keyboard, + struct wl_resource *resource) +{ + struct wl_array fake_keys; + + /* We never want to send pressed keys to wayland clients on + * enter. The protocol says that we should send them, presumably so + * that clients can trigger their own key repeat routine in case + * they are given focus and a key is physically pressed. + * + * Unfortunately this causes some clients, in particular Xwayland, + * to register key events that they really shouldn't handle, + * e.g. on an Alt+Tab keybinding, where Alt is released before Tab, + * clients would see Tab being pressed on enter followed by a key + * release event for Tab, meaning that Tab would be processed by + * the client when it really shouldn't. + * + * Since the use case for the pressed keys array on enter seems weak + * to us, we'll just fake that there are no pressed keys instead + * which should be spec compliant even if it might not be true. + */ + wl_array_init (&fake_keys); + + keyboard_send_modifiers (keyboard, resource, keyboard->focus_serial); + wl_keyboard_send_enter (resource, keyboard->focus_serial, + keyboard->focus_surface->resource, + &fake_keys); +} + +void +meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard, + MetaWaylandSurface *surface) +{ + MetaWaylandInputDevice *input_device = META_WAYLAND_INPUT_DEVICE (keyboard); + + if (keyboard->focus_surface == surface) + return; + + if (keyboard->focus_surface != NULL) + { + if (!wl_list_empty (&keyboard->focus_resource_list)) + { + struct wl_resource *resource; + uint32_t serial; + + serial = meta_wayland_input_device_next_serial (input_device); + + wl_resource_for_each (resource, &keyboard->focus_resource_list) + { + wl_keyboard_send_leave (resource, serial, + keyboard->focus_surface->resource); + } + + move_resources (&keyboard->resource_list, + &keyboard->focus_resource_list); + } + + wl_list_remove (&keyboard->focus_surface_listener.link); + keyboard->focus_surface = NULL; + } + + if (surface != NULL) + { + struct wl_resource *focus_surface_resource; + + keyboard->focus_surface = surface; + focus_surface_resource = keyboard->focus_surface->resource; + wl_resource_add_destroy_listener (focus_surface_resource, + &keyboard->focus_surface_listener); + + move_resources_for_client (&keyboard->focus_resource_list, + &keyboard->resource_list, + wl_resource_get_client (focus_surface_resource)); + + /* Make sure a11y masks are applied before braodcasting modifiers */ + kbd_a11y_apply_mask (keyboard); + + if (!wl_list_empty (&keyboard->focus_resource_list)) + { + struct wl_resource *resource; + + keyboard->focus_serial = + meta_wayland_input_device_next_serial (input_device); + + wl_resource_for_each (resource, &keyboard->focus_resource_list) + { + broadcast_focus (keyboard, resource); + } + } + } +} + +struct wl_client * +meta_wayland_keyboard_get_focus_client (MetaWaylandKeyboard *keyboard) +{ + if (keyboard->focus_surface) + return wl_resource_get_client (keyboard->focus_surface->resource); + else + return NULL; +} + +static void +keyboard_release (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static const struct wl_keyboard_interface keyboard_interface = { + keyboard_release, +}; + +void +meta_wayland_keyboard_create_new_resource (MetaWaylandKeyboard *keyboard, + struct wl_client *client, + struct wl_resource *seat_resource, + uint32_t id) +{ + struct wl_resource *resource; + + resource = wl_resource_create (client, &wl_keyboard_interface, + wl_resource_get_version (seat_resource), id); + wl_resource_set_implementation (resource, &keyboard_interface, + keyboard, unbind_resource); + + send_keymap (keyboard, resource); + + notify_key_repeat_for_resource (keyboard, resource); + + if (keyboard->focus_surface && + wl_resource_get_client (keyboard->focus_surface->resource) == client) + { + wl_list_insert (&keyboard->focus_resource_list, + wl_resource_get_link (resource)); + broadcast_focus (keyboard, resource); + } + else + { + wl_list_insert (&keyboard->resource_list, + wl_resource_get_link (resource)); + } +} + +gboolean +meta_wayland_keyboard_can_popup (MetaWaylandKeyboard *keyboard, + uint32_t serial) +{ + return (keyboard->key_down_serial == serial || + ((keyboard->key_down_keycode == keyboard->key_up_keycode) && + keyboard->key_up_serial == serial)); +} + +void +meta_wayland_keyboard_start_grab (MetaWaylandKeyboard *keyboard, + MetaWaylandKeyboardGrab *grab) +{ + meta_wayland_keyboard_set_focus (keyboard, NULL); + keyboard->grab = grab; + grab->keyboard = keyboard; +} + +void +meta_wayland_keyboard_end_grab (MetaWaylandKeyboard *keyboard) +{ + keyboard->grab = &keyboard->default_grab; +} + +static void +meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard) +{ + wl_list_init (&keyboard->resource_list); + wl_list_init (&keyboard->focus_resource_list); + + keyboard->default_grab.interface = &default_keyboard_grab_interface; + keyboard->default_grab.keyboard = keyboard; + keyboard->grab = &keyboard->default_grab; + + keyboard->focus_surface_listener.notify = + keyboard_handle_focus_surface_destroy; +} + +static void +meta_wayland_keyboard_finalize (GObject *object) +{ + MetaWaylandKeyboard *keyboard = META_WAYLAND_KEYBOARD (object); + + meta_wayland_xkb_info_destroy (&keyboard->xkb_info); +} + +static void +meta_wayland_keyboard_class_init (MetaWaylandKeyboardClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_wayland_keyboard_finalize; +} diff --git a/src/wayland/meta-wayland-keyboard.h b/src/wayland/meta-wayland-keyboard.h new file mode 100644 index 000000000..1dd3b12ba --- /dev/null +++ b/src/wayland/meta-wayland-keyboard.h @@ -0,0 +1,140 @@ +/* + * Wayland Support + * + * Copyright (C) 2013 Intel Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +/* + * Copyright © 2008-2011 Kristian Høgsberg + * Copyright © 2012 Collabora, Ltd. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holders not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. The copyright holders make + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef META_WAYLAND_KEYBOARD_H +#define META_WAYLAND_KEYBOARD_H + +#include <wayland-server.h> +#include <xkbcommon/xkbcommon.h> + +#include "clutter/clutter.h" +#include "wayland/meta-wayland-types.h" + +#define META_TYPE_WAYLAND_KEYBOARD (meta_wayland_keyboard_get_type ()) +G_DECLARE_FINAL_TYPE (MetaWaylandKeyboard, meta_wayland_keyboard, + META, WAYLAND_KEYBOARD, + MetaWaylandInputDevice) + +struct _MetaWaylandKeyboardGrabInterface +{ + gboolean (*key) (MetaWaylandKeyboardGrab *grab, + const ClutterEvent *event); + void (*modifiers) (MetaWaylandKeyboardGrab *grab, + ClutterModifierType modifiers); +}; + +struct _MetaWaylandKeyboardGrab +{ + const MetaWaylandKeyboardGrabInterface *interface; + MetaWaylandKeyboard *keyboard; +}; + +typedef struct +{ + struct xkb_keymap *keymap; + struct xkb_state *state; + size_t keymap_size; + char *keymap_string; +} MetaWaylandXkbInfo; + +struct _MetaWaylandKeyboard +{ + MetaWaylandInputDevice parent; + + struct wl_list resource_list; + struct wl_list focus_resource_list; + + MetaWaylandSurface *focus_surface; + struct wl_listener focus_surface_listener; + uint32_t focus_serial; + + uint32_t key_down_keycode; + uint32_t key_down_serial; + + uint32_t key_up_keycode; + uint32_t key_up_serial; + + MetaWaylandXkbInfo xkb_info; + enum xkb_state_component mods_changed; + xkb_mod_mask_t kbd_a11y_latched_mods; + xkb_mod_mask_t kbd_a11y_locked_mods; + + MetaWaylandKeyboardGrab *grab; + MetaWaylandKeyboardGrab default_grab; + + GSettings *settings; +}; + +void meta_wayland_keyboard_enable (MetaWaylandKeyboard *keyboard); + +void meta_wayland_keyboard_disable (MetaWaylandKeyboard *keyboard); + +void meta_wayland_keyboard_update (MetaWaylandKeyboard *keyboard, + const ClutterKeyEvent *event); + +gboolean meta_wayland_keyboard_handle_event (MetaWaylandKeyboard *keyboard, + const ClutterKeyEvent *event); +void meta_wayland_keyboard_update_key_state (MetaWaylandKeyboard *compositor, + char *key_vector, + int key_vector_len, + int offset); + +void meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard, + MetaWaylandSurface *surface); + +struct wl_client * meta_wayland_keyboard_get_focus_client (MetaWaylandKeyboard *keyboard); + +void meta_wayland_keyboard_create_new_resource (MetaWaylandKeyboard *keyboard, + struct wl_client *client, + struct wl_resource *seat_resource, + uint32_t id); + +gboolean meta_wayland_keyboard_can_popup (MetaWaylandKeyboard *keyboard, + uint32_t serial); + +void meta_wayland_keyboard_start_grab (MetaWaylandKeyboard *keyboard, + MetaWaylandKeyboardGrab *grab); +void meta_wayland_keyboard_end_grab (MetaWaylandKeyboard *keyboard); + +#endif /* META_WAYLAND_KEYBOARD_H */ diff --git a/src/wayland/meta-wayland-legacy-xdg-shell.c b/src/wayland/meta-wayland-legacy-xdg-shell.c new file mode 100644 index 000000000..90eacab36 --- /dev/null +++ b/src/wayland/meta-wayland-legacy-xdg-shell.c @@ -0,0 +1,2102 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2012-2013 Intel Corporation + * Copyright (C) 2013-2015 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#include "config.h" + +#include "wayland/meta-wayland-legacy-xdg-shell.h" + +#include "backends/meta-logical-monitor.h" +#include "core/window-private.h" +#include "wayland/meta-wayland-outputs.h" +#include "wayland/meta-wayland-popup.h" +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-wayland-seat.h" +#include "wayland/meta-wayland-shell-surface.h" +#include "wayland/meta-wayland-surface.h" +#include "wayland/meta-wayland-versions.h" +#include "wayland/meta-wayland-window-configuration.h" +#include "wayland/meta-wayland.h" +#include "wayland/meta-window-wayland.h" + +#include "xdg-shell-unstable-v6-server-protocol.h" + +enum +{ + ZXDG_SURFACE_V6_PROP_0, + + ZXDG_SURFACE_V6_PROP_SHELL_CLIENT, + ZXDG_SURFACE_V6_PROP_RESOURCE, +}; + +typedef struct _MetaWaylandZxdgShellV6Client +{ + struct wl_resource *resource; + GList *surfaces; + GList *surface_constructors; +} MetaWaylandZxdgShellV6Client; + +typedef struct _MetaWaylandZxdgPositionerV6 +{ + MetaRectangle anchor_rect; + int32_t width; + int32_t height; + uint32_t gravity; + uint32_t anchor; + uint32_t constraint_adjustment; + int32_t offset_x; + int32_t offset_y; +} MetaWaylandZxdgPositionerV6; + +typedef struct _MetaWaylandZxdgSurfaceV6Constructor +{ + MetaWaylandSurface *surface; + struct wl_resource *resource; + MetaWaylandZxdgShellV6Client *shell_client; +} MetaWaylandZxdgSurfaceV6Constructor; + +typedef struct _MetaWaylandZxdgSurfaceV6Private +{ + struct wl_resource *resource; + MetaWaylandZxdgShellV6Client *shell_client; + MetaRectangle geometry; + + guint configure_sent : 1; + guint first_buffer_attached : 1; + guint has_set_geometry : 1; +} MetaWaylandZxdgSurfaceV6Private; + +G_DEFINE_TYPE_WITH_PRIVATE (MetaWaylandZxdgSurfaceV6, + meta_wayland_zxdg_surface_v6, + META_TYPE_WAYLAND_SHELL_SURFACE); + +struct _MetaWaylandZxdgToplevelV6 +{ + MetaWaylandZxdgSurfaceV6 parent; + + struct wl_resource *resource; +}; + +G_DEFINE_TYPE (MetaWaylandZxdgToplevelV6, + meta_wayland_zxdg_toplevel_v6, + META_TYPE_WAYLAND_ZXDG_SURFACE_V6); + +struct _MetaWaylandZxdgPopupV6 +{ + MetaWaylandZxdgSurfaceV6 parent; + + struct wl_resource *resource; + + MetaWaylandSurface *parent_surface; + struct wl_listener parent_destroy_listener; + + MetaWaylandPopup *popup; + + struct { + MetaWaylandSurface *parent_surface; + + /* + * The coordinates/dimensions in the placement rule are in logical pixel + * coordinate space, i.e. not scaled given what monitor the popup is on. + */ + MetaPlacementRule placement_rule; + + MetaWaylandSeat *grab_seat; + uint32_t grab_serial; + } setup; +}; + +static void +popup_surface_iface_init (MetaWaylandPopupSurfaceInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (MetaWaylandZxdgPopupV6, + meta_wayland_zxdg_popup_v6, + META_TYPE_WAYLAND_ZXDG_SURFACE_V6, + G_IMPLEMENT_INTERFACE (META_TYPE_WAYLAND_POPUP_SURFACE, + popup_surface_iface_init)); + +static MetaPlacementRule +meta_wayland_zxdg_positioner_v6_to_placement (MetaWaylandZxdgPositionerV6 *xdg_positioner); + +static struct wl_resource * +meta_wayland_zxdg_surface_v6_get_shell_resource (MetaWaylandZxdgSurfaceV6 *xdg_surface); + +static MetaRectangle +meta_wayland_zxdg_surface_v6_get_window_geometry (MetaWaylandZxdgSurfaceV6 *xdg_surface); + +static void +meta_wayland_zxdg_surface_v6_send_configure (MetaWaylandZxdgSurfaceV6 *xdg_surface, + MetaWaylandWindowConfiguration *configuration); + +static MetaWaylandSurface * +surface_from_xdg_surface_resource (struct wl_resource *resource) +{ + MetaWaylandSurfaceRole *surface_role = wl_resource_get_user_data (resource); + + return meta_wayland_surface_role_get_surface (surface_role); +} + +static MetaWaylandSurface * +surface_from_xdg_toplevel_resource (struct wl_resource *resource) +{ + return surface_from_xdg_surface_resource (resource); +} + +static void +zxdg_toplevel_v6_destructor (struct wl_resource *resource) +{ + MetaWaylandZxdgToplevelV6 *xdg_toplevel = + wl_resource_get_user_data (resource); + MetaWaylandShellSurface *shell_surface = + META_WAYLAND_SHELL_SURFACE (xdg_toplevel); + + meta_wayland_shell_surface_destroy_window (shell_surface); + xdg_toplevel->resource = NULL; +} + +static void +zxdg_toplevel_v6_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +zxdg_toplevel_v6_set_parent (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *parent_resource) +{ + MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource); + MetaWindow *transient_for = NULL; + MetaWindow *window; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + if (parent_resource) + { + MetaWaylandSurface *parent_surface = + surface_from_xdg_surface_resource (parent_resource); + + transient_for = meta_wayland_surface_get_window (parent_surface); + } + + meta_window_set_transient_for (window, transient_for); +} + +static void +zxdg_toplevel_v6_set_title (struct wl_client *client, + struct wl_resource *resource, + const char *title) +{ + MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource); + MetaWindow *window; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + if (!g_utf8_validate (title, -1, NULL)) + title = ""; + + meta_window_set_title (window, title); +} + +static void +zxdg_toplevel_v6_set_app_id (struct wl_client *client, + struct wl_resource *resource, + const char *app_id) +{ + MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource); + MetaWindow *window; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + if (!g_utf8_validate (app_id, -1, NULL)) + app_id = ""; + + meta_window_set_wm_class (window, app_id, app_id); +} + +static void +zxdg_toplevel_v6_show_window_menu (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *seat_resource, + uint32_t serial, + int32_t x, + int32_t y) +{ + MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); + MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource); + MetaWindow *window; + int monitor_scale; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + if (!meta_wayland_seat_get_grab_info (seat, surface, serial, FALSE, NULL, NULL)) + return; + + monitor_scale = meta_window_wayland_get_geometry_scale (window); + meta_window_show_menu (window, META_WINDOW_MENU_WM, + window->buffer_rect.x + (x * monitor_scale), + window->buffer_rect.y + (y * monitor_scale)); +} + +static void +zxdg_toplevel_v6_move (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *seat_resource, + uint32_t serial) +{ + MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); + MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource); + MetaWindow *window; + gfloat x, y; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + if (!meta_wayland_seat_get_grab_info (seat, surface, serial, TRUE, &x, &y)) + return; + + meta_wayland_surface_begin_grab_op (surface, seat, META_GRAB_OP_MOVING, x, y); +} + +static MetaGrabOp +grab_op_for_xdg_toplevel_resize_edge (int edge) +{ + MetaGrabOp op = META_GRAB_OP_WINDOW_BASE; + + if (edge & ZXDG_TOPLEVEL_V6_RESIZE_EDGE_TOP) + op |= META_GRAB_OP_WINDOW_DIR_NORTH; + if (edge & ZXDG_TOPLEVEL_V6_RESIZE_EDGE_BOTTOM) + op |= META_GRAB_OP_WINDOW_DIR_SOUTH; + if (edge & ZXDG_TOPLEVEL_V6_RESIZE_EDGE_LEFT) + op |= META_GRAB_OP_WINDOW_DIR_WEST; + if (edge & ZXDG_TOPLEVEL_V6_RESIZE_EDGE_RIGHT) + op |= META_GRAB_OP_WINDOW_DIR_EAST; + + if (op == META_GRAB_OP_WINDOW_BASE) + { + g_warning ("invalid edge: %d", edge); + return META_GRAB_OP_NONE; + } + + return op; +} + +static void +zxdg_toplevel_v6_resize (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *seat_resource, + uint32_t serial, + uint32_t edges) +{ + MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); + MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource); + MetaWindow *window; + gfloat x, y; + MetaGrabOp grab_op; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + if (!meta_wayland_seat_get_grab_info (seat, surface, serial, TRUE, &x, &y)) + return; + + grab_op = grab_op_for_xdg_toplevel_resize_edge (edges); + meta_wayland_surface_begin_grab_op (surface, seat, grab_op, x, y); +} + +static void +zxdg_toplevel_v6_set_max_size (struct wl_client *client, + struct wl_resource *resource, + int32_t width, + int32_t height) +{ + MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource); + MetaWaylandSurfaceState *pending; + MetaWindow *window; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + if (width < 0 || height < 0) + { + wl_resource_post_error (resource, + ZXDG_SHELL_V6_ERROR_INVALID_SURFACE_STATE, + "invalid negative max size requested %i x %i", + width, height); + return; + } + + pending = meta_wayland_surface_get_pending_state (surface); + pending->has_new_max_size = TRUE; + pending->new_max_width = width; + pending->new_max_height = height; +} + +static void +zxdg_toplevel_v6_set_min_size (struct wl_client *client, + struct wl_resource *resource, + int32_t width, + int32_t height) +{ + MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource); + MetaWaylandSurfaceState *pending; + MetaWindow *window; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + if (width < 0 || height < 0) + { + wl_resource_post_error (resource, + ZXDG_SHELL_V6_ERROR_INVALID_SURFACE_STATE, + "invalid negative min size requested %i x %i", + width, height); + return; + } + + pending = meta_wayland_surface_get_pending_state (surface); + pending->has_new_min_size = TRUE; + pending->new_min_width = width; + pending->new_min_height = height; +} + +static void +zxdg_toplevel_v6_set_maximized (struct wl_client *client, + struct wl_resource *resource) +{ + MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource); + MetaWindow *window; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + if (!window->has_maximize_func) + return; + + meta_window_force_placement (window, TRUE); + meta_window_maximize (window, META_MAXIMIZE_BOTH); +} + +static void +zxdg_toplevel_v6_unset_maximized (struct wl_client *client, + struct wl_resource *resource) +{ + MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource); + MetaWindow *window; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + meta_window_unmaximize (window, META_MAXIMIZE_BOTH); +} + +static void +zxdg_toplevel_v6_set_fullscreen (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *output_resource) +{ + MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource); + MetaWindow *window; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + if (output_resource) + { + MetaWaylandOutput *output = wl_resource_get_user_data (output_resource); + if (output && output->logical_monitor) + meta_window_move_to_monitor (window, output->logical_monitor->number); + } + + meta_window_make_fullscreen (window); +} + +static void +zxdg_toplevel_v6_unset_fullscreen (struct wl_client *client, + struct wl_resource *resource) +{ + MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource); + MetaWindow *window; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + meta_window_unmake_fullscreen (window); +} + +static void +zxdg_toplevel_v6_set_minimized (struct wl_client *client, + struct wl_resource *resource) +{ + MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource); + MetaWindow *window; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + meta_window_minimize (window); +} + +static const struct zxdg_toplevel_v6_interface meta_wayland_zxdg_toplevel_v6_interface = { + zxdg_toplevel_v6_destroy, + zxdg_toplevel_v6_set_parent, + zxdg_toplevel_v6_set_title, + zxdg_toplevel_v6_set_app_id, + zxdg_toplevel_v6_show_window_menu, + zxdg_toplevel_v6_move, + zxdg_toplevel_v6_resize, + zxdg_toplevel_v6_set_max_size, + zxdg_toplevel_v6_set_min_size, + zxdg_toplevel_v6_set_maximized, + zxdg_toplevel_v6_unset_maximized, + zxdg_toplevel_v6_set_fullscreen, + zxdg_toplevel_v6_unset_fullscreen, + zxdg_toplevel_v6_set_minimized, +}; + +static void +zxdg_popup_v6_destructor (struct wl_resource *resource) +{ + MetaWaylandZxdgPopupV6 *xdg_popup = + META_WAYLAND_ZXDG_POPUP_V6 (wl_resource_get_user_data (resource)); + + if (xdg_popup->parent_surface) + { + wl_list_remove (&xdg_popup->parent_destroy_listener.link); + xdg_popup->parent_surface = NULL; + } + + if (xdg_popup->popup) + meta_wayland_popup_dismiss (xdg_popup->popup); + + xdg_popup->resource = NULL; +} + +static void +zxdg_popup_v6_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +zxdg_popup_v6_grab (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *seat_resource, + uint32_t serial) +{ + MetaWaylandZxdgPopupV6 *xdg_popup = + META_WAYLAND_ZXDG_POPUP_V6 (wl_resource_get_user_data (resource)); + MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); + MetaWaylandSurface *parent_surface; + + parent_surface = xdg_popup->setup.parent_surface; + if (!parent_surface) + { + wl_resource_post_error (resource, + ZXDG_POPUP_V6_ERROR_INVALID_GRAB, + "tried to grab after popup was mapped"); + return; + } + + xdg_popup->setup.grab_seat = seat; + xdg_popup->setup.grab_serial = serial; +} + +static const struct zxdg_popup_v6_interface meta_wayland_zxdg_popup_v6_interface = { + zxdg_popup_v6_destroy, + zxdg_popup_v6_grab, +}; + +static void +handle_popup_parent_destroyed (struct wl_listener *listener, + void *data) +{ + MetaWaylandZxdgPopupV6 *xdg_popup = + wl_container_of (listener, xdg_popup, parent_destroy_listener); + MetaWaylandZxdgSurfaceV6 *xdg_surface = + META_WAYLAND_ZXDG_SURFACE_V6 (xdg_popup); + struct wl_resource *xdg_shell_resource = + meta_wayland_zxdg_surface_v6_get_shell_resource (xdg_surface); + MetaWaylandShellSurface *shell_surface = + META_WAYLAND_SHELL_SURFACE (xdg_popup); + + wl_resource_post_error (xdg_shell_resource, + ZXDG_SHELL_V6_ERROR_NOT_THE_TOPMOST_POPUP, + "destroyed popup not top most popup"); + xdg_popup->parent_surface = NULL; + + meta_wayland_shell_surface_destroy_window (shell_surface); +} + +static void +add_state_value (struct wl_array *states, + enum zxdg_toplevel_v6_state state) +{ + uint32_t *s; + + s = wl_array_add (states, sizeof *s); + *s = state; +} + +static void +fill_states (struct wl_array *states, + MetaWindow *window) +{ + if (META_WINDOW_MAXIMIZED (window)) + add_state_value (states, ZXDG_TOPLEVEL_V6_STATE_MAXIMIZED); + if (meta_window_is_fullscreen (window)) + add_state_value (states, ZXDG_TOPLEVEL_V6_STATE_FULLSCREEN); + if (meta_grab_op_is_resizing (window->display->grab_op)) + add_state_value (states, ZXDG_TOPLEVEL_V6_STATE_RESIZING); + if (meta_window_appears_focused (window)) + add_state_value (states, ZXDG_TOPLEVEL_V6_STATE_ACTIVATED); +} + +static void +meta_wayland_zxdg_toplevel_v6_send_configure (MetaWaylandZxdgToplevelV6 *xdg_toplevel, + MetaWaylandWindowConfiguration *configuration) +{ + MetaWaylandZxdgSurfaceV6 *xdg_surface = + META_WAYLAND_ZXDG_SURFACE_V6 (xdg_toplevel); + MetaWaylandSurfaceRole *surface_role = + META_WAYLAND_SURFACE_ROLE (xdg_toplevel); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWindow *window; + struct wl_array states; + + window = meta_wayland_surface_get_window (surface); + + wl_array_init (&states); + fill_states (&states, window); + + zxdg_toplevel_v6_send_configure (xdg_toplevel->resource, + configuration->width / configuration->scale, + configuration->height / configuration->scale, + &states); + wl_array_release (&states); + + meta_wayland_zxdg_surface_v6_send_configure (xdg_surface, configuration); +} + +static gboolean +is_new_size_hints_valid (MetaWindow *window, + MetaWaylandSurfaceState *pending) +{ + int new_min_width, new_min_height; + int new_max_width, new_max_height; + + if (pending->has_new_min_size) + { + new_min_width = pending->new_min_width; + new_min_height = pending->new_min_height; + } + else + { + meta_window_wayland_get_min_size (window, &new_min_width, &new_min_height); + } + + if (pending->has_new_max_size) + { + new_max_width = pending->new_max_width; + new_max_height = pending->new_max_height; + } + else + { + meta_window_wayland_get_max_size (window, &new_max_width, &new_max_height); + } + /* Zero means unlimited */ + return ((new_max_width == 0 || new_min_width <= new_max_width) && + (new_max_height == 0 || new_min_height <= new_max_height)); +} + +static void +meta_wayland_zxdg_toplevel_v6_apply_state (MetaWaylandSurfaceRole *surface_role, + MetaWaylandSurfaceState *pending) +{ + MetaWaylandZxdgToplevelV6 *xdg_toplevel = + META_WAYLAND_ZXDG_TOPLEVEL_V6 (surface_role); + MetaWaylandZxdgSurfaceV6 *xdg_surface = + META_WAYLAND_ZXDG_SURFACE_V6 (xdg_toplevel); + MetaWaylandZxdgSurfaceV6Private *xdg_surface_priv = + meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface); + MetaWaylandActorSurface *actor_surface = + META_WAYLAND_ACTOR_SURFACE (xdg_surface); + MetaWaylandSurfaceRoleClass *surface_role_class; + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWindow *window; + + window = meta_wayland_surface_get_window (surface); + if (!window) + { + meta_wayland_actor_surface_queue_frame_callbacks (actor_surface, pending); + return; + } + + surface_role_class = + META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_zxdg_toplevel_v6_parent_class); + surface_role_class->apply_state (surface_role, pending); + + if (!xdg_surface_priv->configure_sent) + { + MetaWaylandWindowConfiguration *configuration; + + configuration = meta_wayland_window_configuration_new_empty (); + meta_wayland_zxdg_toplevel_v6_send_configure (xdg_toplevel, + configuration); + meta_wayland_window_configuration_free (configuration); + return; + } +} + +static void +meta_wayland_zxdg_toplevel_v6_post_apply_state (MetaWaylandSurfaceRole *surface_role, + MetaWaylandSurfaceState *pending) +{ + MetaWaylandZxdgToplevelV6 *xdg_toplevel = + META_WAYLAND_ZXDG_TOPLEVEL_V6 (surface_role); + MetaWaylandZxdgSurfaceV6 *xdg_surface = + META_WAYLAND_ZXDG_SURFACE_V6 (xdg_toplevel); + MetaWaylandZxdgSurfaceV6Private *xdg_surface_priv = + meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface); + MetaWaylandSurfaceRoleClass *surface_role_class; + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWindow *window; + MetaRectangle old_geometry; + gboolean geometry_changed; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + if (!pending->newly_attached) + return; + + old_geometry = xdg_surface_priv->geometry; + + surface_role_class = + META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_zxdg_toplevel_v6_parent_class); + surface_role_class->post_apply_state (surface_role, pending); + + geometry_changed = !meta_rectangle_equal (&old_geometry, &xdg_surface_priv->geometry); + + if (geometry_changed || pending->has_acked_configure_serial) + { + MetaRectangle window_geometry; + + window_geometry = + meta_wayland_zxdg_surface_v6_get_window_geometry (xdg_surface); + meta_window_wayland_finish_move_resize (window, window_geometry, pending); + } + else if (pending->dx != 0 || pending->dy != 0) + { + g_warning ("XXX: Attach-initiated move without a new geometry. " + "This is unimplemented right now."); + } + + /* When we get to this point, we ought to have valid size hints */ + if (pending->has_new_min_size || pending->has_new_max_size) + { + if (is_new_size_hints_valid (window, pending)) + { + if (pending->has_new_min_size) + meta_window_wayland_set_min_size (window, + pending->new_min_width, + pending->new_min_height); + + if (pending->has_new_max_size) + meta_window_wayland_set_max_size (window, + pending->new_max_width, + pending->new_max_height); + + meta_window_recalc_features (window); + } + else + { + wl_resource_post_error (surface->resource, + ZXDG_SHELL_V6_ERROR_INVALID_SURFACE_STATE, + "Invalid min/max size"); + } + } +} + +static MetaWaylandSurface * +meta_wayland_zxdg_toplevel_v6_get_toplevel (MetaWaylandSurfaceRole *surface_role) +{ + return meta_wayland_surface_role_get_surface (surface_role); +} + +static void +meta_wayland_zxdg_toplevel_v6_configure (MetaWaylandShellSurface *shell_surface, + MetaWaylandWindowConfiguration *configuration) +{ + MetaWaylandZxdgToplevelV6 *xdg_toplevel = + META_WAYLAND_ZXDG_TOPLEVEL_V6 (shell_surface); + MetaWaylandZxdgSurfaceV6 *xdg_surface = + META_WAYLAND_ZXDG_SURFACE_V6 (xdg_toplevel); + MetaWaylandZxdgSurfaceV6Private *xdg_surface_priv = + meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface); + + if (!xdg_surface_priv->resource) + return; + + if (!xdg_toplevel->resource) + return; + + meta_wayland_zxdg_toplevel_v6_send_configure (xdg_toplevel, configuration); +} + +static void +meta_wayland_zxdg_toplevel_v6_managed (MetaWaylandShellSurface *shell_surface, + MetaWindow *window) +{ +} + +static void +meta_wayland_zxdg_toplevel_v6_close (MetaWaylandShellSurface *shell_surface) +{ + MetaWaylandZxdgToplevelV6 *xdg_toplevel = + META_WAYLAND_ZXDG_TOPLEVEL_V6 (shell_surface); + + zxdg_toplevel_v6_send_close (xdg_toplevel->resource); +} + +static void +meta_wayland_zxdg_toplevel_v6_shell_client_destroyed (MetaWaylandZxdgSurfaceV6 *xdg_surface) +{ + MetaWaylandZxdgToplevelV6 *xdg_toplevel = + META_WAYLAND_ZXDG_TOPLEVEL_V6 (xdg_surface); + struct wl_resource *xdg_shell_resource = + meta_wayland_zxdg_surface_v6_get_shell_resource (xdg_surface); + MetaWaylandZxdgSurfaceV6Class *xdg_surface_class = + META_WAYLAND_ZXDG_SURFACE_V6_CLASS (meta_wayland_zxdg_toplevel_v6_parent_class); + + xdg_surface_class->shell_client_destroyed (xdg_surface); + + if (xdg_toplevel->resource) + { + wl_resource_post_error (xdg_shell_resource, + ZXDG_SHELL_V6_ERROR_DEFUNCT_SURFACES, + "xdg_shell of xdg_toplevel@%d was destroyed", + wl_resource_get_id (xdg_toplevel->resource)); + + wl_resource_destroy (xdg_toplevel->resource); + } +} + +static void +meta_wayland_zxdg_toplevel_v6_finalize (GObject *object) +{ + MetaWaylandZxdgToplevelV6 *xdg_toplevel = + META_WAYLAND_ZXDG_TOPLEVEL_V6 (object); + + g_clear_pointer (&xdg_toplevel->resource, wl_resource_destroy); + + G_OBJECT_CLASS (meta_wayland_zxdg_toplevel_v6_parent_class)->finalize (object); +} + +static void +meta_wayland_zxdg_toplevel_v6_init (MetaWaylandZxdgToplevelV6 *role) +{ +} + +static void +meta_wayland_zxdg_toplevel_v6_class_init (MetaWaylandZxdgToplevelV6Class *klass) +{ + GObjectClass *object_class; + MetaWaylandSurfaceRoleClass *surface_role_class; + MetaWaylandShellSurfaceClass *shell_surface_class; + MetaWaylandZxdgSurfaceV6Class *xdg_surface_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->finalize = meta_wayland_zxdg_toplevel_v6_finalize; + + surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass); + surface_role_class->apply_state = meta_wayland_zxdg_toplevel_v6_apply_state; + surface_role_class->post_apply_state = + meta_wayland_zxdg_toplevel_v6_post_apply_state; + surface_role_class->get_toplevel = meta_wayland_zxdg_toplevel_v6_get_toplevel; + + shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass); + shell_surface_class->configure = meta_wayland_zxdg_toplevel_v6_configure; + shell_surface_class->managed = meta_wayland_zxdg_toplevel_v6_managed; + shell_surface_class->close = meta_wayland_zxdg_toplevel_v6_close; + + xdg_surface_class = META_WAYLAND_ZXDG_SURFACE_V6_CLASS (klass); + xdg_surface_class->shell_client_destroyed = + meta_wayland_zxdg_toplevel_v6_shell_client_destroyed; +} + +static void +scale_placement_rule (MetaPlacementRule *placement_rule, + MetaWaylandSurface *surface) +{ + MetaWindow *window; + int geometry_scale; + + window = meta_wayland_surface_get_window (surface); + geometry_scale = meta_window_wayland_get_geometry_scale (window); + + placement_rule->anchor_rect.x *= geometry_scale; + placement_rule->anchor_rect.y *= geometry_scale; + placement_rule->anchor_rect.width *= geometry_scale; + placement_rule->anchor_rect.height *= geometry_scale; + placement_rule->offset_x *= geometry_scale; + placement_rule->offset_y *= geometry_scale; + placement_rule->width *= geometry_scale; + placement_rule->height *= geometry_scale; +} + +static void +finish_popup_setup (MetaWaylandZxdgPopupV6 *xdg_popup) +{ + MetaWaylandZxdgSurfaceV6 *xdg_surface = + META_WAYLAND_ZXDG_SURFACE_V6 (xdg_popup); + MetaWaylandShellSurface *shell_surface = + META_WAYLAND_SHELL_SURFACE (xdg_popup); + MetaWaylandSurfaceRole *surface_role = META_WAYLAND_SURFACE_ROLE (xdg_popup); + struct wl_resource *xdg_shell_resource = + meta_wayland_zxdg_surface_v6_get_shell_resource (xdg_surface); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWaylandSurface *parent_surface; + MetaPlacementRule scaled_placement_rule; + MetaWaylandSeat *seat; + uint32_t serial; + MetaDisplay *display = meta_get_display (); + MetaWindow *window; + + parent_surface = xdg_popup->setup.parent_surface; + seat = xdg_popup->setup.grab_seat; + serial = xdg_popup->setup.grab_serial; + + xdg_popup->setup.parent_surface = NULL; + xdg_popup->setup.grab_seat = NULL; + + if (!meta_wayland_surface_get_window (parent_surface)) + { + zxdg_popup_v6_send_popup_done (xdg_popup->resource); + return; + } + + if (seat) + { + MetaWaylandSurface *top_popup; + + if (!meta_wayland_seat_can_popup (seat, serial)) + { + zxdg_popup_v6_send_popup_done (xdg_popup->resource); + return; + } + + top_popup = meta_wayland_pointer_get_top_popup (seat->pointer); + if (top_popup && parent_surface != top_popup) + { + wl_resource_post_error (xdg_shell_resource, + ZXDG_SHELL_V6_ERROR_NOT_THE_TOPMOST_POPUP, + "parent not top most surface"); + return; + } + } + + xdg_popup->parent_surface = parent_surface; + xdg_popup->parent_destroy_listener.notify = handle_popup_parent_destroyed; + wl_resource_add_destroy_listener (parent_surface->resource, + &xdg_popup->parent_destroy_listener); + + window = meta_window_wayland_new (display, surface); + meta_wayland_shell_surface_set_window (shell_surface, window); + + scaled_placement_rule = xdg_popup->setup.placement_rule; + scale_placement_rule (&scaled_placement_rule, surface); + meta_window_place_with_placement_rule (window, &scaled_placement_rule); + + if (seat) + { + MetaWaylandPopupSurface *popup_surface; + MetaWaylandPopup *popup; + + meta_window_focus (window, meta_display_get_current_time (display)); + popup_surface = META_WAYLAND_POPUP_SURFACE (surface->role); + popup = meta_wayland_pointer_start_popup_grab (seat->pointer, + popup_surface); + if (popup == NULL) + { + zxdg_popup_v6_send_popup_done (xdg_popup->resource); + meta_wayland_shell_surface_destroy_window (shell_surface); + return; + } + + xdg_popup->popup = popup; + } + else + { + /* The keyboard focus semantics for non-grabbing zxdg_shell_v6 popups + * is pretty undefined. Same applies for subsurfaces, but in practice, + * subsurfaces never receive keyboard focus, so it makes sense to + * do the same for non-grabbing popups. + * + * See https://bugzilla.gnome.org/show_bug.cgi?id=771694#c24 + */ + window->input = FALSE; + } +} + +static void +meta_wayland_zxdg_popup_v6_apply_state (MetaWaylandSurfaceRole *surface_role, + MetaWaylandSurfaceState *pending) +{ + MetaWaylandZxdgPopupV6 *xdg_popup = META_WAYLAND_ZXDG_POPUP_V6 (surface_role); + MetaWaylandSurfaceRoleClass *surface_role_class; + + if (xdg_popup->setup.parent_surface) + finish_popup_setup (xdg_popup); + + surface_role_class = + META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_zxdg_popup_v6_parent_class); + surface_role_class->apply_state (surface_role, pending); +} + +static void +meta_wayland_zxdg_popup_v6_post_apply_state (MetaWaylandSurfaceRole *surface_role, + MetaWaylandSurfaceState *pending) +{ + MetaWaylandZxdgSurfaceV6 *xdg_surface = + META_WAYLAND_ZXDG_SURFACE_V6 (surface_role); + MetaWaylandSurfaceRoleClass *surface_role_class; + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWindow *window; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + surface_role_class = + META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_zxdg_popup_v6_parent_class); + surface_role_class->post_apply_state (surface_role, pending); + + if (!pending->newly_attached) + return; + + if (!surface->buffer_ref.buffer) + return; + + if (pending->has_acked_configure_serial) + { + MetaRectangle window_geometry; + + window_geometry = + meta_wayland_zxdg_surface_v6_get_window_geometry (xdg_surface); + meta_window_wayland_finish_move_resize (window, + window_geometry, + pending); + } +} + +static MetaWaylandSurface * +meta_wayland_zxdg_popup_v6_get_toplevel (MetaWaylandSurfaceRole *surface_role) +{ + MetaWaylandZxdgPopupV6 *xdg_popup = META_WAYLAND_ZXDG_POPUP_V6 (surface_role); + + if (xdg_popup->parent_surface) + return meta_wayland_surface_get_toplevel (xdg_popup->parent_surface); + else + return NULL; +} + +static void +meta_wayland_zxdg_popup_v6_configure (MetaWaylandShellSurface *shell_surface, + MetaWaylandWindowConfiguration *configuration) +{ + MetaWaylandZxdgPopupV6 *xdg_popup = + META_WAYLAND_ZXDG_POPUP_V6 (shell_surface); + MetaWaylandZxdgSurfaceV6 *xdg_surface = + META_WAYLAND_ZXDG_SURFACE_V6 (xdg_popup); + MetaWindow *parent_window = + meta_wayland_surface_get_window (xdg_popup->parent_surface); + int geometry_scale; + int x, y; + + /* If the parent surface was destroyed, its window will be destroyed + * before the popup receives the parent-destroy signal. This means that + * the popup may potentially get temporary focus until itself is destroyed. + * If this happen, don't try to configure the xdg_popup surface. + * + * FIXME: Could maybe add a signal that is emitted before the window is + * created so that we can avoid incorrect intermediate foci. + */ + if (!parent_window) + return; + + geometry_scale = meta_window_wayland_get_geometry_scale (parent_window); + x = configuration->rel_x / geometry_scale; + y = configuration->rel_y / geometry_scale; + + zxdg_popup_v6_send_configure (xdg_popup->resource, + x, y, + configuration->width / configuration->scale, + configuration->height / configuration->scale); + meta_wayland_zxdg_surface_v6_send_configure (xdg_surface, configuration); +} + +static void +meta_wayland_zxdg_popup_v6_managed (MetaWaylandShellSurface *shell_surface, + MetaWindow *window) +{ + MetaWaylandZxdgPopupV6 *xdg_popup = + META_WAYLAND_ZXDG_POPUP_V6 (shell_surface); + MetaWaylandSurface *parent = xdg_popup->parent_surface; + + g_assert (parent); + + meta_window_set_transient_for (window, + meta_wayland_surface_get_window (parent)); + meta_window_set_type (window, META_WINDOW_DROPDOWN_MENU); +} + +static void +meta_wayland_zxdg_popup_v6_shell_client_destroyed (MetaWaylandZxdgSurfaceV6 *xdg_surface) +{ + MetaWaylandZxdgPopupV6 *xdg_popup = META_WAYLAND_ZXDG_POPUP_V6 (xdg_surface); + struct wl_resource *xdg_shell_resource = + meta_wayland_zxdg_surface_v6_get_shell_resource (xdg_surface); + MetaWaylandZxdgSurfaceV6Class *xdg_surface_class = + META_WAYLAND_ZXDG_SURFACE_V6_CLASS (meta_wayland_zxdg_popup_v6_parent_class); + + xdg_surface_class->shell_client_destroyed (xdg_surface); + + if (xdg_popup->resource) + { + wl_resource_post_error (xdg_shell_resource, + ZXDG_SHELL_V6_ERROR_DEFUNCT_SURFACES, + "xdg_shell of xdg_popup@%d was destroyed", + wl_resource_get_id (xdg_popup->resource)); + + wl_resource_destroy (xdg_popup->resource); + } +} + +static void +meta_wayland_zxdg_popup_v6_done (MetaWaylandPopupSurface *popup_surface) +{ + MetaWaylandZxdgPopupV6 *xdg_popup = META_WAYLAND_ZXDG_POPUP_V6 (popup_surface); + + zxdg_popup_v6_send_popup_done (xdg_popup->resource); +} + +static void +meta_wayland_zxdg_popup_v6_dismiss (MetaWaylandPopupSurface *popup_surface) +{ + MetaWaylandZxdgPopupV6 *xdg_popup = + META_WAYLAND_ZXDG_POPUP_V6 (popup_surface); + MetaWaylandZxdgSurfaceV6 *xdg_surface = + META_WAYLAND_ZXDG_SURFACE_V6 (xdg_popup); + struct wl_resource *xdg_shell_resource = + meta_wayland_zxdg_surface_v6_get_shell_resource (xdg_surface); + MetaWaylandShellSurface *shell_surface = + META_WAYLAND_SHELL_SURFACE (xdg_popup); + MetaWaylandSurfaceRole *surface_role = META_WAYLAND_SURFACE_ROLE (xdg_popup); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWaylandSurface *top_popup; + + top_popup = meta_wayland_popup_get_top_popup (xdg_popup->popup); + if (surface != top_popup) + { + wl_resource_post_error (xdg_shell_resource, + ZXDG_SHELL_V6_ERROR_NOT_THE_TOPMOST_POPUP, + "destroyed popup not top most popup"); + } + + xdg_popup->popup = NULL; + + meta_wayland_shell_surface_destroy_window (shell_surface); +} + +static MetaWaylandSurface * +meta_wayland_zxdg_popup_v6_get_surface (MetaWaylandPopupSurface *popup_surface) +{ + MetaWaylandSurfaceRole *surface_role = + META_WAYLAND_SURFACE_ROLE (popup_surface); + + return meta_wayland_surface_role_get_surface (surface_role); +} + +static void +popup_surface_iface_init (MetaWaylandPopupSurfaceInterface *iface) +{ + iface->done = meta_wayland_zxdg_popup_v6_done; + iface->dismiss = meta_wayland_zxdg_popup_v6_dismiss; + iface->get_surface = meta_wayland_zxdg_popup_v6_get_surface; +} + +static void +meta_wayland_zxdg_popup_v6_role_finalize (GObject *object) +{ + MetaWaylandZxdgPopupV6 *xdg_popup = META_WAYLAND_ZXDG_POPUP_V6 (object); + + g_clear_pointer (&xdg_popup->resource, wl_resource_destroy); + + G_OBJECT_CLASS (meta_wayland_zxdg_popup_v6_parent_class)->finalize (object); +} + +static void +meta_wayland_zxdg_popup_v6_init (MetaWaylandZxdgPopupV6 *role) +{ +} + +static void +meta_wayland_zxdg_popup_v6_class_init (MetaWaylandZxdgPopupV6Class *klass) +{ + GObjectClass *object_class; + MetaWaylandSurfaceRoleClass *surface_role_class; + MetaWaylandShellSurfaceClass *shell_surface_class; + MetaWaylandZxdgSurfaceV6Class *xdg_surface_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->finalize = meta_wayland_zxdg_popup_v6_role_finalize; + + surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass); + surface_role_class->apply_state = meta_wayland_zxdg_popup_v6_apply_state; + surface_role_class->post_apply_state = + meta_wayland_zxdg_popup_v6_post_apply_state; + surface_role_class->get_toplevel = meta_wayland_zxdg_popup_v6_get_toplevel; + + shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass); + shell_surface_class->configure = meta_wayland_zxdg_popup_v6_configure; + shell_surface_class->managed = meta_wayland_zxdg_popup_v6_managed; + + xdg_surface_class = META_WAYLAND_ZXDG_SURFACE_V6_CLASS (klass); + xdg_surface_class->shell_client_destroyed = + meta_wayland_zxdg_popup_v6_shell_client_destroyed; +} + +static struct wl_resource * +meta_wayland_zxdg_surface_v6_get_shell_resource (MetaWaylandZxdgSurfaceV6 *xdg_surface) +{ + MetaWaylandZxdgSurfaceV6Private *priv = + meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface); + + return priv->shell_client->resource; +} + +static MetaRectangle +meta_wayland_zxdg_surface_v6_get_window_geometry (MetaWaylandZxdgSurfaceV6 *xdg_surface) +{ + MetaWaylandZxdgSurfaceV6Private *priv = + meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface); + + return priv->geometry; +} + +static gboolean +meta_wayland_zxdg_surface_v6_is_assigned (MetaWaylandZxdgSurfaceV6 *xdg_surface) +{ + MetaWaylandZxdgSurfaceV6Private *priv = + meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface); + + return priv->resource != NULL; +} + +static void +meta_wayland_zxdg_surface_v6_send_configure (MetaWaylandZxdgSurfaceV6 *xdg_surface, + MetaWaylandWindowConfiguration *configuration) +{ + MetaWaylandZxdgSurfaceV6Private *priv = + meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface); + + zxdg_surface_v6_send_configure (priv->resource, configuration->serial); + + priv->configure_sent = TRUE; +} + +static void +zxdg_surface_v6_destructor (struct wl_resource *resource) +{ + MetaWaylandZxdgSurfaceV6 *xdg_surface = wl_resource_get_user_data (resource); + MetaWaylandZxdgSurfaceV6Private *priv = + meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface); + + priv->shell_client->surfaces = g_list_remove (priv->shell_client->surfaces, + xdg_surface); + + priv->resource = NULL; + priv->first_buffer_attached = FALSE; +} + +static void +zxdg_surface_v6_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +zxdg_surface_v6_get_toplevel (struct wl_client *client, + struct wl_resource *resource, + uint32_t id) +{ + MetaWaylandZxdgSurfaceV6 *xdg_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = surface_from_xdg_surface_resource (resource); + struct wl_resource *xdg_shell_resource = + meta_wayland_zxdg_surface_v6_get_shell_resource (xdg_surface); + + wl_resource_post_error (xdg_shell_resource, ZXDG_SHELL_V6_ERROR_ROLE, + "wl_surface@%d already has a role assigned", + wl_resource_get_id (surface->resource)); +} + +static void +zxdg_surface_v6_get_popup (struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *parent_resource, + struct wl_resource *positioner_resource) +{ + MetaWaylandZxdgSurfaceV6 *xdg_surface = wl_resource_get_user_data (resource); + MetaWaylandZxdgSurfaceV6Private *priv = + meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface); + MetaWaylandSurface *surface = surface_from_xdg_surface_resource (resource); + + wl_resource_post_error (priv->shell_client->resource, + ZXDG_SHELL_V6_ERROR_ROLE, + "wl_surface@%d already has a role assigned", + wl_resource_get_id (surface->resource)); +} + +static void +zxdg_surface_v6_set_window_geometry (struct wl_client *client, + struct wl_resource *resource, + int32_t x, + int32_t y, + int32_t width, + int32_t height) +{ + MetaWaylandSurface *surface = surface_from_xdg_surface_resource (resource); + MetaWaylandSurfaceState *pending; + + pending = meta_wayland_surface_get_pending_state (surface); + pending->has_new_geometry = TRUE; + pending->new_geometry.x = x; + pending->new_geometry.y = y; + pending->new_geometry.width = width; + pending->new_geometry.height = height; +} + +static void +zxdg_surface_v6_ack_configure (struct wl_client *client, + struct wl_resource *resource, + uint32_t serial) +{ + MetaWaylandSurface *surface = surface_from_xdg_surface_resource (resource); + MetaWaylandSurfaceState *pending; + + pending = meta_wayland_surface_get_pending_state (surface); + pending->has_acked_configure_serial = TRUE; + pending->acked_configure_serial = serial; +} + +static const struct zxdg_surface_v6_interface meta_wayland_zxdg_surface_v6_interface = { + zxdg_surface_v6_destroy, + zxdg_surface_v6_get_toplevel, + zxdg_surface_v6_get_popup, + zxdg_surface_v6_set_window_geometry, + zxdg_surface_v6_ack_configure, +}; + +static void +meta_wayland_zxdg_surface_v6_finalize (GObject *object) +{ + MetaWaylandZxdgSurfaceV6 *xdg_surface = META_WAYLAND_ZXDG_SURFACE_V6 (object); + MetaWaylandZxdgSurfaceV6Private *priv = + meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface); + + g_clear_pointer (&priv->resource, wl_resource_destroy); + + G_OBJECT_CLASS (meta_wayland_zxdg_surface_v6_parent_class)->finalize (object); +} + +static void +meta_wayland_zxdg_surface_v6_apply_state (MetaWaylandSurfaceRole *surface_role, + MetaWaylandSurfaceState *pending) +{ + MetaWaylandZxdgSurfaceV6 *xdg_surface = + META_WAYLAND_ZXDG_SURFACE_V6 (surface_role); + MetaWaylandZxdgSurfaceV6Private *priv = + meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWindow *window = meta_wayland_surface_get_window (surface); + MetaWaylandSurfaceRoleClass *surface_role_class; + + surface_role_class = + META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_zxdg_surface_v6_parent_class); + surface_role_class->apply_state (surface_role, pending); + + /* Ignore commits when unassigned. */ + if (!priv->resource) + return; + + if (surface->buffer_ref.buffer == NULL && priv->first_buffer_attached) + { + /* XDG surfaces can't commit NULL buffers */ + wl_resource_post_error (surface->resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "Cannot commit a NULL buffer to an xdg_surface"); + return; + } + + if (surface->buffer_ref.buffer && !priv->configure_sent) + { + wl_resource_post_error (surface->resource, + ZXDG_SURFACE_V6_ERROR_UNCONFIGURED_BUFFER, + "buffer committed to unconfigured xdg_surface"); + return; + } + + if (!window) + return; + + if (surface->buffer_ref.buffer) + priv->first_buffer_attached = TRUE; +} + +static void +meta_wayland_zxdg_surface_v6_post_apply_state (MetaWaylandSurfaceRole *surface_role, + MetaWaylandSurfaceState *pending) +{ + MetaWaylandZxdgSurfaceV6 *xdg_surface = + META_WAYLAND_ZXDG_SURFACE_V6 (surface_role); + MetaWaylandZxdgSurfaceV6Private *priv = + meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface); + MetaWaylandShellSurface *shell_surface = + META_WAYLAND_SHELL_SURFACE (xdg_surface); + + if (pending->has_new_geometry) + { + meta_wayland_shell_surface_determine_geometry (shell_surface, + &pending->new_geometry, + &priv->geometry); + priv->has_set_geometry = TRUE; + } + else if (!priv->has_set_geometry) + { + MetaRectangle new_geometry = { 0 }; + + /* If the surface has never set any geometry, calculate + * a default one unioning the surface and all subsurfaces together. */ + + meta_wayland_shell_surface_calculate_geometry (shell_surface, + &new_geometry); + if (!meta_rectangle_equal (&new_geometry, &priv->geometry)) + { + pending->has_new_geometry = TRUE; + priv->geometry = new_geometry; + } + } +} + +static void +meta_wayland_zxdg_surface_v6_assigned (MetaWaylandSurfaceRole *surface_role) +{ + MetaWaylandZxdgSurfaceV6 *xdg_surface = + META_WAYLAND_ZXDG_SURFACE_V6 (surface_role); + MetaWaylandZxdgSurfaceV6Private *priv = + meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + struct wl_resource *xdg_shell_resource = + meta_wayland_zxdg_surface_v6_get_shell_resource (xdg_surface); + MetaWaylandSurfaceRoleClass *surface_role_class; + + priv->configure_sent = FALSE; + priv->first_buffer_attached = FALSE; + + if (surface->buffer_ref.buffer) + { + wl_resource_post_error (xdg_shell_resource, + ZXDG_SHELL_V6_ERROR_INVALID_SURFACE_STATE, + "wl_surface@%d already has a buffer committed", + wl_resource_get_id (surface->resource)); + return; + } + + surface_role_class = + META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_zxdg_surface_v6_parent_class); + surface_role_class->assigned (surface_role); +} + +static void +meta_wayland_zxdg_surface_v6_ping (MetaWaylandShellSurface *shell_surface, + uint32_t serial) +{ + MetaWaylandZxdgSurfaceV6 *xdg_surface = + META_WAYLAND_ZXDG_SURFACE_V6 (shell_surface); + MetaWaylandZxdgSurfaceV6Private *priv = + meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface); + + zxdg_shell_v6_send_ping (priv->shell_client->resource, serial); +} + +static void +meta_wayland_zxdg_surface_v6_real_shell_client_destroyed (MetaWaylandZxdgSurfaceV6 *xdg_surface) +{ + MetaWaylandZxdgSurfaceV6Private *priv = + meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface); + + if (priv->resource) + { + wl_resource_post_error (priv->shell_client->resource, + ZXDG_SHELL_V6_ERROR_DEFUNCT_SURFACES, + "xdg_shell of xdg_surface@%d was destroyed", + wl_resource_get_id (priv->resource)); + + wl_resource_destroy (priv->resource); + } +} + +static void +meta_wayland_zxdg_surface_v6_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaWaylandZxdgSurfaceV6 *xdg_surface = META_WAYLAND_ZXDG_SURFACE_V6 (object); + MetaWaylandZxdgSurfaceV6Private *priv = + meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface); + + switch (prop_id) + { + case ZXDG_SURFACE_V6_PROP_SHELL_CLIENT: + priv->shell_client = g_value_get_pointer (value); + break; + + case ZXDG_SURFACE_V6_PROP_RESOURCE: + priv->resource = g_value_get_pointer (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_wayland_zxdg_surface_v6_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaWaylandZxdgSurfaceV6 *xdg_surface = META_WAYLAND_ZXDG_SURFACE_V6 (object); + MetaWaylandZxdgSurfaceV6Private *priv = + meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface); + + switch (prop_id) + { + case ZXDG_SURFACE_V6_PROP_SHELL_CLIENT: + g_value_set_pointer (value, priv->shell_client); + break; + + case ZXDG_SURFACE_V6_PROP_RESOURCE: + g_value_set_pointer (value, priv->resource); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_wayland_zxdg_surface_v6_init (MetaWaylandZxdgSurfaceV6 *xdg_surface) +{ +} + +static void +meta_wayland_zxdg_surface_v6_class_init (MetaWaylandZxdgSurfaceV6Class *klass) +{ + GObjectClass *object_class; + MetaWaylandSurfaceRoleClass *surface_role_class; + MetaWaylandShellSurfaceClass *shell_surface_class; + GParamSpec *pspec; + + object_class = G_OBJECT_CLASS (klass); + object_class->finalize = meta_wayland_zxdg_surface_v6_finalize; + object_class->set_property = meta_wayland_zxdg_surface_v6_set_property; + object_class->get_property = meta_wayland_zxdg_surface_v6_get_property; + + surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass); + surface_role_class->apply_state = meta_wayland_zxdg_surface_v6_apply_state; + surface_role_class->post_apply_state = + meta_wayland_zxdg_surface_v6_post_apply_state; + surface_role_class->assigned = meta_wayland_zxdg_surface_v6_assigned; + + shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass); + shell_surface_class->ping = meta_wayland_zxdg_surface_v6_ping; + + klass->shell_client_destroyed = + meta_wayland_zxdg_surface_v6_real_shell_client_destroyed; + + pspec = g_param_spec_pointer ("shell-client", + "MetaWaylandZxdgShellV6Client", + "The shell client instance", + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, + ZXDG_SURFACE_V6_PROP_SHELL_CLIENT, + pspec); + pspec = g_param_spec_pointer ("xdg-surface-resource", + "xdg_surface wl_resource", + "The xdg_surface wl_resource instance", + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, + ZXDG_SURFACE_V6_PROP_RESOURCE, + pspec); +} + +static void +meta_wayland_zxdg_surface_v6_shell_client_destroyed (MetaWaylandZxdgSurfaceV6 *xdg_surface) +{ + MetaWaylandZxdgSurfaceV6Class *xdg_surface_class = + META_WAYLAND_ZXDG_SURFACE_V6_GET_CLASS (xdg_surface); + + xdg_surface_class->shell_client_destroyed (xdg_surface); +} + +static void +meta_wayland_zxdg_surface_v6_constructor_finalize (MetaWaylandZxdgSurfaceV6Constructor *constructor, + MetaWaylandZxdgSurfaceV6 *xdg_surface) +{ + MetaWaylandZxdgShellV6Client *shell_client = constructor->shell_client; + + shell_client->surface_constructors = + g_list_remove (shell_client->surface_constructors, constructor); + shell_client->surfaces = g_list_append (shell_client->surfaces, xdg_surface); + + wl_resource_set_implementation (constructor->resource, + &meta_wayland_zxdg_surface_v6_interface, + xdg_surface, + zxdg_surface_v6_destructor); + + g_free (constructor); +} + +static void +zxdg_surface_v6_constructor_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_post_error (resource, + ZXDG_SURFACE_V6_ERROR_NOT_CONSTRUCTED, + "xdg_surface destroyed before constructed"); + wl_resource_destroy (resource); +} + +static void +zxdg_surface_v6_constructor_get_toplevel (struct wl_client *client, + struct wl_resource *resource, + uint32_t id) +{ + MetaWaylandZxdgSurfaceV6Constructor *constructor = + wl_resource_get_user_data (resource); + MetaWaylandZxdgShellV6Client *shell_client = constructor->shell_client; + struct wl_resource *xdg_surface_resource = constructor->resource; + MetaWaylandSurface *surface = constructor->surface; + MetaWaylandZxdgToplevelV6 *xdg_toplevel; + MetaWaylandZxdgSurfaceV6 *xdg_surface; + MetaWaylandShellSurface *shell_surface; + MetaWindow *window; + + if (!meta_wayland_surface_assign_role (surface, + META_TYPE_WAYLAND_ZXDG_TOPLEVEL_V6, + "shell-client", shell_client, + "xdg-surface-resource", xdg_surface_resource, + NULL)) + { + wl_resource_post_error (resource, ZXDG_SHELL_V6_ERROR_ROLE, + "wl_surface@%d already has a different role", + wl_resource_get_id (surface->resource)); + return; + } + + xdg_toplevel = META_WAYLAND_ZXDG_TOPLEVEL_V6 (surface->role); + xdg_toplevel->resource = wl_resource_create (client, + &zxdg_toplevel_v6_interface, + wl_resource_get_version (resource), + id); + wl_resource_set_implementation (xdg_toplevel->resource, + &meta_wayland_zxdg_toplevel_v6_interface, + xdg_toplevel, + zxdg_toplevel_v6_destructor); + + xdg_surface = META_WAYLAND_ZXDG_SURFACE_V6 (xdg_toplevel); + meta_wayland_zxdg_surface_v6_constructor_finalize (constructor, xdg_surface); + + window = meta_window_wayland_new (meta_get_display (), surface); + shell_surface = META_WAYLAND_SHELL_SURFACE (xdg_surface); + meta_wayland_shell_surface_set_window (shell_surface, window); +} + +static void +zxdg_surface_v6_constructor_get_popup (struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *parent_resource, + struct wl_resource *positioner_resource) +{ + MetaWaylandZxdgSurfaceV6Constructor *constructor = + wl_resource_get_user_data (resource); + MetaWaylandZxdgShellV6Client *shell_client = constructor->shell_client; + MetaWaylandSurface *surface = constructor->surface; + struct wl_resource *xdg_shell_resource = constructor->shell_client->resource; + struct wl_resource *xdg_surface_resource = constructor->resource; + MetaWaylandSurface *parent_surface = + surface_from_xdg_surface_resource (parent_resource); + MetaWaylandZxdgPositionerV6 *xdg_positioner; + MetaWaylandZxdgPopupV6 *xdg_popup; + MetaWaylandZxdgSurfaceV6 *xdg_surface; + + if (!meta_wayland_surface_assign_role (surface, + META_TYPE_WAYLAND_ZXDG_POPUP_V6, + "shell-client", shell_client, + "xdg-surface-resource", xdg_surface_resource, + NULL)) + { + wl_resource_post_error (xdg_shell_resource, ZXDG_SHELL_V6_ERROR_ROLE, + "wl_surface@%d already has a different role", + wl_resource_get_id (surface->resource)); + return; + } + + if (!META_IS_WAYLAND_ZXDG_SURFACE_V6 (parent_surface->role)) + { + wl_resource_post_error (xdg_shell_resource, + ZXDG_SHELL_V6_ERROR_INVALID_POPUP_PARENT, + "Invalid popup parent role"); + return; + } + + xdg_popup = META_WAYLAND_ZXDG_POPUP_V6 (surface->role); + + xdg_popup->resource = wl_resource_create (client, + &zxdg_popup_v6_interface, + wl_resource_get_version (resource), + id); + wl_resource_set_implementation (xdg_popup->resource, + &meta_wayland_zxdg_popup_v6_interface, + xdg_popup, + zxdg_popup_v6_destructor); + + xdg_surface = META_WAYLAND_ZXDG_SURFACE_V6 (xdg_popup); + meta_wayland_zxdg_surface_v6_constructor_finalize (constructor, xdg_surface); + + xdg_positioner = wl_resource_get_user_data (positioner_resource); + xdg_popup->setup.placement_rule = + meta_wayland_zxdg_positioner_v6_to_placement (xdg_positioner); + xdg_popup->setup.parent_surface = parent_surface; +} + +static void +zxdg_surface_v6_constructor_set_window_geometry (struct wl_client *client, + struct wl_resource *resource, + int32_t x, + int32_t y, + int32_t width, + int32_t height) +{ + wl_resource_post_error (resource, + ZXDG_SURFACE_V6_ERROR_NOT_CONSTRUCTED, + "xdg_surface::set_window_geometry called before constructed"); +} + +static void +zxdg_surface_v6_constructor_ack_configure (struct wl_client *client, + struct wl_resource *resource, + uint32_t serial) +{ + wl_resource_post_error (resource, + ZXDG_SURFACE_V6_ERROR_NOT_CONSTRUCTED, + "xdg_surface::ack_configure called before constructed"); +} + +static const struct zxdg_surface_v6_interface meta_wayland_zxdg_surface_v6_constructor_interface = { + zxdg_surface_v6_constructor_destroy, + zxdg_surface_v6_constructor_get_toplevel, + zxdg_surface_v6_constructor_get_popup, + zxdg_surface_v6_constructor_set_window_geometry, + zxdg_surface_v6_constructor_ack_configure, +}; + +static void +zxdg_surface_v6_constructor_destructor (struct wl_resource *resource) +{ + MetaWaylandZxdgSurfaceV6Constructor *constructor = + wl_resource_get_user_data (resource); + + constructor->shell_client->surface_constructors = + g_list_remove (constructor->shell_client->surface_constructors, + constructor); + + g_free (constructor); +} + +static MetaPlacementRule +meta_wayland_zxdg_positioner_v6_to_placement (MetaWaylandZxdgPositionerV6 *xdg_positioner) +{ + return (MetaPlacementRule) { + .anchor_rect = xdg_positioner->anchor_rect, + .gravity = xdg_positioner->gravity, + .anchor = xdg_positioner->anchor, + .constraint_adjustment = xdg_positioner->constraint_adjustment, + .offset_x = xdg_positioner->offset_x, + .offset_y = xdg_positioner->offset_y, + .width = xdg_positioner->width, + .height = xdg_positioner->height, + }; +} + +static void +zxdg_positioner_v6_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +zxdg_positioner_v6_set_size (struct wl_client *client, + struct wl_resource *resource, + int32_t width, + int32_t height) +{ + MetaWaylandZxdgPositionerV6 *positioner = wl_resource_get_user_data (resource); + + if (width <= 0 || height <= 0) + { + wl_resource_post_error (resource, ZXDG_POSITIONER_V6_ERROR_INVALID_INPUT, + "Invalid size"); + return; + } + + positioner->width = width; + positioner->height = height; +} + +static void +zxdg_positioner_v6_set_anchor_rect (struct wl_client *client, + struct wl_resource *resource, + int32_t x, + int32_t y, + int32_t width, + int32_t height) +{ + MetaWaylandZxdgPositionerV6 *positioner = wl_resource_get_user_data (resource); + + if (width <= 0 || height <= 0) + { + wl_resource_post_error (resource, ZXDG_POSITIONER_V6_ERROR_INVALID_INPUT, + "Invalid anchor rectangle size"); + return; + } + + positioner->anchor_rect = (MetaRectangle) { + .x = x, + .y = y, + .width = width, + .height = height, + }; +} + +static void +zxdg_positioner_v6_set_anchor (struct wl_client *client, + struct wl_resource *resource, + uint32_t anchor) +{ + MetaWaylandZxdgPositionerV6 *positioner = wl_resource_get_user_data (resource); + + if ((anchor & ZXDG_POSITIONER_V6_ANCHOR_LEFT && + anchor & ZXDG_POSITIONER_V6_ANCHOR_RIGHT) || + (anchor & ZXDG_POSITIONER_V6_ANCHOR_TOP && + anchor & ZXDG_POSITIONER_V6_ANCHOR_BOTTOM)) + { + wl_resource_post_error (resource, ZXDG_POSITIONER_V6_ERROR_INVALID_INPUT, + "Invalid anchor"); + return; + } + + positioner->anchor = anchor; +} + +static void +zxdg_positioner_v6_set_gravity (struct wl_client *client, + struct wl_resource *resource, + uint32_t gravity) +{ + MetaWaylandZxdgPositionerV6 *positioner = wl_resource_get_user_data (resource); + + if ((gravity & ZXDG_POSITIONER_V6_GRAVITY_LEFT && + gravity & ZXDG_POSITIONER_V6_GRAVITY_RIGHT) || + (gravity & ZXDG_POSITIONER_V6_GRAVITY_TOP && + gravity & ZXDG_POSITIONER_V6_GRAVITY_BOTTOM)) + { + wl_resource_post_error (resource, ZXDG_POSITIONER_V6_ERROR_INVALID_INPUT, + "Invalid gravity"); + return; + } + + positioner->gravity = gravity; +} + +static void +zxdg_positioner_v6_set_constraint_adjustment (struct wl_client *client, + struct wl_resource *resource, + uint32_t constraint_adjustment) +{ + MetaWaylandZxdgPositionerV6 *positioner = wl_resource_get_user_data (resource); + uint32_t all_adjustments = (ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_SLIDE_X | + ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_FLIP_X | + ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_SLIDE_Y | + ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_FLIP_Y | + ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_RESIZE_X | + ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_RESIZE_Y); + + if ((constraint_adjustment & ~all_adjustments) != 0) + { + wl_resource_post_error (resource, ZXDG_POSITIONER_V6_ERROR_INVALID_INPUT, + "Invalid constraint action"); + return; + } + + positioner->constraint_adjustment = constraint_adjustment; +} + +static void +zxdg_positioner_v6_set_offset (struct wl_client *client, + struct wl_resource *resource, + int32_t x, + int32_t y) +{ + MetaWaylandZxdgPositionerV6 *positioner = wl_resource_get_user_data (resource); + + positioner->offset_x = x; + positioner->offset_y = y; +} + +static const struct zxdg_positioner_v6_interface meta_wayland_zxdg_positioner_v6_interface = { + zxdg_positioner_v6_destroy, + zxdg_positioner_v6_set_size, + zxdg_positioner_v6_set_anchor_rect, + zxdg_positioner_v6_set_anchor, + zxdg_positioner_v6_set_gravity, + zxdg_positioner_v6_set_constraint_adjustment, + zxdg_positioner_v6_set_offset, +}; + +static void +zxdg_positioner_v6_destructor (struct wl_resource *resource) +{ + MetaWaylandZxdgPositionerV6 *positioner = wl_resource_get_user_data (resource); + + g_free (positioner); +} + +static void +zxdg_shell_v6_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + MetaWaylandZxdgShellV6Client *shell_client = wl_resource_get_user_data (resource); + + if (shell_client->surfaces || shell_client->surface_constructors) + wl_resource_post_error (resource, ZXDG_SHELL_V6_ERROR_DEFUNCT_SURFACES, + "xdg_shell destroyed before its surfaces"); + + wl_resource_destroy (resource); +} + +static void +zxdg_shell_v6_create_positioner (struct wl_client *client, + struct wl_resource *resource, + uint32_t id) +{ + MetaWaylandZxdgPositionerV6 *positioner; + struct wl_resource *positioner_resource; + + positioner = g_new0 (MetaWaylandZxdgPositionerV6, 1); + positioner_resource = wl_resource_create (client, + &zxdg_positioner_v6_interface, + wl_resource_get_version (resource), + id); + wl_resource_set_implementation (positioner_resource, + &meta_wayland_zxdg_positioner_v6_interface, + positioner, + zxdg_positioner_v6_destructor); +} + +static void +zxdg_shell_v6_get_xdg_surface (struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *surface_resource) +{ + MetaWaylandZxdgShellV6Client *shell_client = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + MetaWaylandZxdgSurfaceV6 *xdg_surface = NULL; + MetaWaylandZxdgSurfaceV6Constructor *constructor; + + if (surface->role && !META_IS_WAYLAND_ZXDG_SURFACE_V6 (surface->role)) + { + wl_resource_post_error (resource, ZXDG_SHELL_V6_ERROR_ROLE, + "wl_surface@%d already has a different role", + wl_resource_get_id (surface->resource)); + return; + } + + if (surface->role) + xdg_surface = META_WAYLAND_ZXDG_SURFACE_V6 (surface->role); + if (xdg_surface && meta_wayland_zxdg_surface_v6_is_assigned (xdg_surface)) + { + wl_resource_post_error (surface_resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "zxdg_shell_v6::get_xdg_surface already requested"); + return; + } + + if (surface->buffer_ref.buffer) + { + wl_resource_post_error (resource, + ZXDG_SHELL_V6_ERROR_INVALID_SURFACE_STATE, + "wl_surface@%d already has a buffer committed", + wl_resource_get_id (surface->resource)); + return; + } + + constructor = g_new0 (MetaWaylandZxdgSurfaceV6Constructor, 1); + constructor->surface = surface; + constructor->shell_client = shell_client; + constructor->resource = wl_resource_create (client, + &zxdg_surface_v6_interface, + wl_resource_get_version (resource), + id); + wl_resource_set_implementation (constructor->resource, + &meta_wayland_zxdg_surface_v6_constructor_interface, + constructor, + zxdg_surface_v6_constructor_destructor); + + shell_client->surface_constructors = + g_list_append (shell_client->surface_constructors, constructor); +} + +static void +zxdg_shell_v6_pong (struct wl_client *client, + struct wl_resource *resource, + uint32_t serial) +{ + MetaDisplay *display = meta_get_display (); + + meta_display_pong_for_serial (display, serial); +} + +static const struct zxdg_shell_v6_interface meta_wayland_zxdg_shell_v6_interface = { + zxdg_shell_v6_destroy, + zxdg_shell_v6_create_positioner, + zxdg_shell_v6_get_xdg_surface, + zxdg_shell_v6_pong, +}; + +static void +meta_wayland_zxdg_shell_v6_client_destroy (MetaWaylandZxdgShellV6Client *shell_client) +{ + while (shell_client->surface_constructors) + { + MetaWaylandZxdgSurfaceV6Constructor *constructor = + g_list_first (shell_client->surface_constructors)->data; + + wl_resource_destroy (constructor->resource); + } + g_list_free (shell_client->surface_constructors); + + while (shell_client->surfaces) + { + MetaWaylandZxdgSurfaceV6 *xdg_surface = + g_list_first (shell_client->surfaces)->data; + + meta_wayland_zxdg_surface_v6_shell_client_destroyed (xdg_surface); + } + g_list_free (shell_client->surfaces); + + g_free (shell_client); +} + +static void +zxdg_shell_v6_destructor (struct wl_resource *resource) +{ + MetaWaylandZxdgShellV6Client *shell_client = wl_resource_get_user_data (resource); + + meta_wayland_zxdg_shell_v6_client_destroy (shell_client); +} + +static void +bind_zxdg_shell_v6 (struct wl_client *client, + void *data, + guint32 version, + guint32 id) +{ + MetaWaylandZxdgShellV6Client *shell_client; + + shell_client = g_new0 (MetaWaylandZxdgShellV6Client, 1); + + shell_client->resource = wl_resource_create (client, + &zxdg_shell_v6_interface, + version, id); + wl_resource_set_implementation (shell_client->resource, + &meta_wayland_zxdg_shell_v6_interface, + shell_client, zxdg_shell_v6_destructor); +} + +void +meta_wayland_legacy_xdg_shell_init (MetaWaylandCompositor *compositor) +{ + if (wl_global_create (compositor->wayland_display, + &zxdg_shell_v6_interface, + META_ZXDG_SHELL_V6_VERSION, + compositor, bind_zxdg_shell_v6) == NULL) + g_error ("Failed to register a global xdg-shell object"); +} diff --git a/src/wayland/meta-wayland-legacy-xdg-shell.h b/src/wayland/meta-wayland-legacy-xdg-shell.h new file mode 100644 index 000000000..8a07dfb29 --- /dev/null +++ b/src/wayland/meta-wayland-legacy-xdg-shell.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2013-2015 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_WAYLAND_LEGACY_XDG_SHELL_H +#define META_WAYLAND_LEGACY_XDG_SHELL_H + +#include "wayland/meta-wayland-shell-surface.h" +#include "wayland/meta-wayland-surface.h" + +#define META_TYPE_WAYLAND_ZXDG_SURFACE_V6 (meta_wayland_zxdg_surface_v6_get_type ()) +G_DECLARE_DERIVABLE_TYPE (MetaWaylandZxdgSurfaceV6, + meta_wayland_zxdg_surface_v6, + META, WAYLAND_ZXDG_SURFACE_V6, + MetaWaylandShellSurface) + +struct _MetaWaylandZxdgSurfaceV6Class +{ + MetaWaylandShellSurfaceClass parent_class; + + void (*shell_client_destroyed) (MetaWaylandZxdgSurfaceV6 *xdg_surface); +}; + +#define META_TYPE_WAYLAND_ZXDG_TOPLEVEL_V6 (meta_wayland_zxdg_toplevel_v6_get_type ()) +G_DECLARE_FINAL_TYPE (MetaWaylandZxdgToplevelV6, + meta_wayland_zxdg_toplevel_v6, + META, WAYLAND_ZXDG_TOPLEVEL_V6, + MetaWaylandZxdgSurfaceV6); + +#define META_TYPE_WAYLAND_ZXDG_POPUP_V6 (meta_wayland_zxdg_popup_v6_get_type ()) +G_DECLARE_FINAL_TYPE (MetaWaylandZxdgPopupV6, + meta_wayland_zxdg_popup_v6, + META, WAYLAND_ZXDG_POPUP_V6, + MetaWaylandZxdgSurfaceV6); + +void meta_wayland_legacy_xdg_shell_init (MetaWaylandCompositor *compositor); + +#endif /* META_WAYLAND_LEGACY_XDG_SHELL_H */ diff --git a/src/wayland/meta-wayland-outputs.c b/src/wayland/meta-wayland-outputs.c new file mode 100644 index 000000000..64de5abc3 --- /dev/null +++ b/src/wayland/meta-wayland-outputs.c @@ -0,0 +1,748 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jasper St. Pierre <jstpierre@mecheye.net> + */ + +#include "config.h" + +#include "wayland/meta-wayland-outputs.h" + +#include <string.h> + +#include "backends/meta-logical-monitor.h" +#include "backends/meta-monitor.h" +#include "backends/meta-monitor-manager-private.h" +#include "wayland/meta-wayland-private.h" + +#include "xdg-output-unstable-v1-server-protocol.h" + +/* Wayland protocol headers list new additions, not deprecations */ +#define NO_XDG_OUTPUT_DONE_SINCE_VERSION 3 + +enum +{ + OUTPUT_DESTROYED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL]; + +G_DEFINE_TYPE (MetaWaylandOutput, meta_wayland_output, G_TYPE_OBJECT) + +static void +send_xdg_output_events (struct wl_resource *resource, + MetaWaylandOutput *wayland_output, + MetaLogicalMonitor *logical_monitor, + gboolean need_all_events, + gboolean *pending_done_event); + +static void +output_resource_destroy (struct wl_resource *res) +{ + MetaWaylandOutput *wayland_output; + + wayland_output = wl_resource_get_user_data (res); + if (!wayland_output) + return; + + wayland_output->resources = g_list_remove (wayland_output->resources, res); +} + +static MetaMonitor * +pick_main_monitor (MetaLogicalMonitor *logical_monitor) +{ + GList *monitors; + + monitors = meta_logical_monitor_get_monitors (logical_monitor); + return g_list_first (monitors)->data; +} + +static enum wl_output_subpixel +cogl_subpixel_order_to_wl_output_subpixel (CoglSubpixelOrder subpixel_order) +{ + switch (subpixel_order) + { + case COGL_SUBPIXEL_ORDER_UNKNOWN: + return WL_OUTPUT_SUBPIXEL_UNKNOWN; + case COGL_SUBPIXEL_ORDER_NONE: + return WL_OUTPUT_SUBPIXEL_NONE; + case COGL_SUBPIXEL_ORDER_HORIZONTAL_RGB: + return WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB; + case COGL_SUBPIXEL_ORDER_HORIZONTAL_BGR: + return WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR; + case COGL_SUBPIXEL_ORDER_VERTICAL_RGB: + return WL_OUTPUT_SUBPIXEL_VERTICAL_RGB; + case COGL_SUBPIXEL_ORDER_VERTICAL_BGR: + return WL_OUTPUT_SUBPIXEL_VERTICAL_BGR; + } + + g_assert_not_reached (); + return WL_OUTPUT_SUBPIXEL_UNKNOWN; +} + +static enum wl_output_subpixel +calculate_suitable_subpixel_order (MetaLogicalMonitor *logical_monitor) +{ + GList *monitors; + GList *l; + MetaMonitor *first_monitor; + CoglSubpixelOrder subpixel_order; + + monitors = meta_logical_monitor_get_monitors (logical_monitor); + first_monitor = monitors->data; + subpixel_order = meta_monitor_get_subpixel_order (first_monitor); + + for (l = monitors->next; l; l = l->next) + { + MetaMonitor *monitor = l->data; + + if (meta_monitor_get_subpixel_order (monitor) != subpixel_order) + { + subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN; + break; + } + } + + return cogl_subpixel_order_to_wl_output_subpixel (subpixel_order); +} + +static int +calculate_wayland_output_scale (MetaLogicalMonitor *logical_monitor) +{ + float scale; + + scale = meta_logical_monitor_get_scale (logical_monitor); + return ceilf (scale); +} + +static void +get_rotated_physical_dimensions (MetaMonitor *monitor, + int *width_mm, + int *height_mm) +{ + int monitor_width_mm, monitor_height_mm; + MetaLogicalMonitor *logical_monitor; + + meta_monitor_get_physical_dimensions (monitor, + &monitor_width_mm, + &monitor_height_mm); + logical_monitor = meta_monitor_get_logical_monitor (monitor); + + if (meta_monitor_transform_is_rotated (logical_monitor->transform)) + { + *width_mm = monitor_height_mm; + *height_mm = monitor_width_mm; + } + else + { + *width_mm = monitor_width_mm; + *height_mm = monitor_height_mm; + } +} + +static gboolean +is_different_rotation (MetaLogicalMonitor *a, + MetaLogicalMonitor *b) +{ + return (meta_monitor_transform_is_rotated (a->transform) != + meta_monitor_transform_is_rotated (b->transform)); +} + +static void +get_native_output_mode_resolution (MetaLogicalMonitor *logical_monitor, + MetaMonitorMode *mode, + int *mode_width, + int *mode_height) +{ + MetaMonitorTransform transform; + + transform = meta_logical_monitor_get_transform (logical_monitor); + if (meta_monitor_transform_is_rotated (transform)) + meta_monitor_mode_get_resolution (mode, mode_height, mode_width); + else + meta_monitor_mode_get_resolution (mode, mode_width, mode_height); +} + +static void +send_output_events (struct wl_resource *resource, + MetaWaylandOutput *wayland_output, + MetaLogicalMonitor *logical_monitor, + gboolean need_all_events, + gboolean *pending_done_event) +{ + int version = wl_resource_get_version (resource); + MetaMonitor *monitor; + MetaMonitorMode *current_mode; + MetaMonitorMode *preferred_mode; + guint mode_flags = WL_OUTPUT_MODE_CURRENT; + MetaLogicalMonitor *old_logical_monitor; + guint old_mode_flags; + gint old_scale; + float old_refresh_rate; + float refresh_rate; + int new_width, new_height; + + old_logical_monitor = wayland_output->logical_monitor; + old_mode_flags = wayland_output->mode_flags; + old_scale = wayland_output->scale; + old_refresh_rate = wayland_output->refresh_rate; + + monitor = pick_main_monitor (logical_monitor); + + current_mode = meta_monitor_get_current_mode (monitor); + refresh_rate = meta_monitor_mode_get_refresh_rate (current_mode); + + gboolean need_done = FALSE; + + if (need_all_events || + old_logical_monitor->rect.x != logical_monitor->rect.x || + old_logical_monitor->rect.y != logical_monitor->rect.y || + is_different_rotation (old_logical_monitor, logical_monitor)) + { + int width_mm, height_mm; + const char *vendor; + const char *product; + uint32_t transform; + enum wl_output_subpixel subpixel_order; + + /* + * While the wl_output carries information specific to a single monitor, + * it is actually referring to a region of the compositor's screen region + * (logical monitor), which may consist of multiple monitors (clones). + * Arbitrarily use whatever monitor is the first in the logical monitor + * and use that for these details. + */ + get_rotated_physical_dimensions (monitor, &width_mm, &height_mm); + vendor = meta_monitor_get_vendor (monitor); + product = meta_monitor_get_product (monitor); + + subpixel_order = calculate_suitable_subpixel_order (logical_monitor); + + /* + * TODO: When we support wl_surface.set_buffer_transform, pass along + * the correct transform here instead of always pretending its 'normal'. + * The reason for this is to try stopping clients from setting any buffer + * transform other than 'normal'. + */ + transform = WL_OUTPUT_TRANSFORM_NORMAL; + + wl_output_send_geometry (resource, + logical_monitor->rect.x, + logical_monitor->rect.y, + width_mm, + height_mm, + subpixel_order, + vendor, + product, + transform); + need_done = TRUE; + } + + preferred_mode = meta_monitor_get_preferred_mode (monitor); + if (current_mode == preferred_mode) + mode_flags |= WL_OUTPUT_MODE_PREFERRED; + + get_native_output_mode_resolution (logical_monitor, + current_mode, + &new_width, + &new_height); + if (need_all_events || + wayland_output->mode_width != new_width || + wayland_output->mode_height != new_height || + old_refresh_rate != refresh_rate || + old_mode_flags != mode_flags) + { + wl_output_send_mode (resource, + mode_flags, + new_width, + new_height, + (int32_t) (refresh_rate * 1000)); + need_done = TRUE; + } + + if (version >= WL_OUTPUT_SCALE_SINCE_VERSION) + { + int scale; + + scale = calculate_wayland_output_scale (logical_monitor); + if (need_all_events || + old_scale != scale) + { + wl_output_send_scale (resource, scale); + need_done = TRUE; + } + } + + if (need_all_events && version >= WL_OUTPUT_DONE_SINCE_VERSION) + { + wl_output_send_done (resource); + need_done = FALSE; + } + + if (pending_done_event && need_done) + *pending_done_event = TRUE; +} + +static void +bind_output (struct wl_client *client, + void *data, + guint32 version, + guint32 id) +{ + MetaWaylandOutput *wayland_output = data; + MetaLogicalMonitor *logical_monitor = wayland_output->logical_monitor; + struct wl_resource *resource; +#ifdef WITH_VERBOSE_MODE + MetaMonitor *monitor; +#endif + + resource = wl_resource_create (client, &wl_output_interface, version, id); + wayland_output->resources = g_list_prepend (wayland_output->resources, resource); + + wl_resource_set_user_data (resource, wayland_output); + wl_resource_set_destructor (resource, output_resource_destroy); + + if (!logical_monitor) + return; + +#ifdef WITH_VERBOSE_MODE + monitor = pick_main_monitor (logical_monitor); + + meta_verbose ("Binding monitor %p/%s (%u, %u, %u, %u) x %f\n", + logical_monitor, + meta_monitor_get_product (monitor), + logical_monitor->rect.x, logical_monitor->rect.y, + wayland_output->mode_width, + wayland_output->mode_height, + wayland_output->refresh_rate); +#endif + + send_output_events (resource, wayland_output, logical_monitor, TRUE, NULL); +} + +static void +wayland_output_destroy_notify (gpointer data) +{ + MetaWaylandOutput *wayland_output = data; + + g_signal_emit (wayland_output, signals[OUTPUT_DESTROYED], 0); + g_object_unref (wayland_output); +} + +static void +meta_wayland_output_set_logical_monitor (MetaWaylandOutput *wayland_output, + MetaLogicalMonitor *logical_monitor) +{ + MetaMonitor *monitor; + MetaMonitorMode *current_mode; + MetaMonitorMode *preferred_mode; + + wayland_output->logical_monitor = logical_monitor; + wayland_output->mode_flags = WL_OUTPUT_MODE_CURRENT; + + monitor = pick_main_monitor (logical_monitor); + current_mode = meta_monitor_get_current_mode (monitor); + preferred_mode = meta_monitor_get_preferred_mode (monitor); + + if (current_mode == preferred_mode) + wayland_output->mode_flags |= WL_OUTPUT_MODE_PREFERRED; + wayland_output->scale = calculate_wayland_output_scale (logical_monitor); + wayland_output->refresh_rate = meta_monitor_mode_get_refresh_rate (current_mode); + + wayland_output->winsys_id = logical_monitor->winsys_id; + get_native_output_mode_resolution (logical_monitor, + current_mode, + &wayland_output->mode_width, + &wayland_output->mode_height); +} + +static void +wayland_output_update_for_output (MetaWaylandOutput *wayland_output, + MetaLogicalMonitor *logical_monitor) +{ + GList *iter; + gboolean pending_done_event; + + pending_done_event = FALSE; + for (iter = wayland_output->resources; iter; iter = iter->next) + { + struct wl_resource *resource = iter->data; + send_output_events (resource, wayland_output, logical_monitor, FALSE, &pending_done_event); + } + + for (iter = wayland_output->xdg_output_resources; iter; iter = iter->next) + { + struct wl_resource *xdg_output = iter->data; + send_xdg_output_events (xdg_output, wayland_output, logical_monitor, FALSE, &pending_done_event); + } + + /* Send the "done" events if needed */ + if (pending_done_event) + { + for (iter = wayland_output->resources; iter; iter = iter->next) + { + struct wl_resource *resource = iter->data; + if (wl_resource_get_version (resource) >= WL_OUTPUT_DONE_SINCE_VERSION) + wl_output_send_done (resource); + } + + for (iter = wayland_output->xdg_output_resources; iter; iter = iter->next) + { + struct wl_resource *xdg_output = iter->data; + if (wl_resource_get_version (xdg_output) < NO_XDG_OUTPUT_DONE_SINCE_VERSION) + zxdg_output_v1_send_done (xdg_output); + } + } + /* It's very important that we change the output pointer here, as + the old structure is about to be freed by MetaMonitorManager */ + meta_wayland_output_set_logical_monitor (wayland_output, logical_monitor); +} + +static MetaWaylandOutput * +meta_wayland_output_new (MetaWaylandCompositor *compositor, + MetaLogicalMonitor *logical_monitor) +{ + MetaWaylandCompositor *wayland_compositor = + meta_wayland_compositor_get_default (); + MetaWaylandOutput *wayland_output; + + wayland_output = g_object_new (META_TYPE_WAYLAND_OUTPUT, NULL); + wayland_output->global = wl_global_create (compositor->wayland_display, + &wl_output_interface, + META_WL_OUTPUT_VERSION, + wayland_output, bind_output); + meta_wayland_compositor_flush_clients (wayland_compositor); + meta_wayland_output_set_logical_monitor (wayland_output, logical_monitor); + + return wayland_output; +} + +static void +make_output_resources_inert (MetaWaylandOutput *wayland_output) +{ + GList *l; + + for (l = wayland_output->resources; l; l = l->next) + { + struct wl_resource *output_resource = l->data; + + wl_resource_set_user_data (output_resource, NULL); + } + g_list_free (wayland_output->resources); + wayland_output->resources = NULL; + + for (l = wayland_output->xdg_output_resources; l; l = l->next) + { + struct wl_resource *xdg_output_resource = l->data; + + wl_resource_set_user_data (xdg_output_resource, NULL); + } + g_list_free (wayland_output->xdg_output_resources); + wayland_output->xdg_output_resources = NULL; +} + +static void +make_output_inert (gpointer key, + gpointer value, + gpointer data) +{ + MetaWaylandOutput *wayland_output = value; + + wayland_output->logical_monitor = NULL; + make_output_resources_inert (wayland_output); +} + +static gboolean +delayed_destroy_outputs (gpointer data) +{ + g_hash_table_destroy (data); + return G_SOURCE_REMOVE; +} + +static GHashTable * +meta_wayland_compositor_update_outputs (MetaWaylandCompositor *compositor, + MetaMonitorManager *monitor_manager) +{ + GHashTable *new_table; + GList *logical_monitors, *l; + + logical_monitors = + meta_monitor_manager_get_logical_monitors (monitor_manager); + new_table = g_hash_table_new_full (g_int64_hash, g_int64_equal, NULL, + wayland_output_destroy_notify); + + for (l = logical_monitors; l; l = l->next) + { + MetaLogicalMonitor *logical_monitor = l->data; + MetaWaylandOutput *wayland_output = NULL; + + if (logical_monitor->winsys_id == 0) + continue; + + wayland_output = g_hash_table_lookup (compositor->outputs, + &logical_monitor->winsys_id); + + if (wayland_output) + { + g_hash_table_steal (compositor->outputs, + &logical_monitor->winsys_id); + } + else + { + wayland_output = meta_wayland_output_new (compositor, logical_monitor); + } + + wayland_output_update_for_output (wayland_output, logical_monitor); + g_hash_table_insert (new_table, + &wayland_output->winsys_id, + wayland_output); + } + + g_hash_table_foreach (compositor->outputs, make_output_inert, NULL); + g_timeout_add_seconds (10, delayed_destroy_outputs, compositor->outputs); + + return new_table; +} + +static void +on_monitors_changed (MetaMonitorManager *monitors, + MetaWaylandCompositor *compositor) +{ + compositor->outputs = meta_wayland_compositor_update_outputs (compositor, monitors); +} + +static void +meta_wayland_output_init (MetaWaylandOutput *wayland_output) +{ +} + +static void +meta_wayland_output_finalize (GObject *object) +{ + MetaWaylandOutput *wayland_output = META_WAYLAND_OUTPUT (object); + + wl_global_destroy (wayland_output->global); + + /* Make sure the wl_output destructor doesn't try to access MetaWaylandOutput + * after we have freed it. + */ + make_output_resources_inert (wayland_output); + + G_OBJECT_CLASS (meta_wayland_output_parent_class)->finalize (object); +} + +static void +meta_wayland_output_class_init (MetaWaylandOutputClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_wayland_output_finalize; + + signals[OUTPUT_DESTROYED] = g_signal_new ("output-destroyed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); +} + +static void +meta_xdg_output_destructor (struct wl_resource *resource) +{ + MetaWaylandOutput *wayland_output; + + wayland_output = wl_resource_get_user_data (resource); + if (!wayland_output) + return; + + wayland_output->xdg_output_resources = + g_list_remove (wayland_output->xdg_output_resources, resource); +} + +static void +meta_xdg_output_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static const struct zxdg_output_v1_interface + meta_xdg_output_interface = { + meta_xdg_output_destroy, + }; + +static void +send_xdg_output_events (struct wl_resource *resource, + MetaWaylandOutput *wayland_output, + MetaLogicalMonitor *logical_monitor, + gboolean need_all_events, + gboolean *pending_done_event) +{ + MetaRectangle new_layout; + MetaRectangle old_layout; + MetaLogicalMonitor *old_logical_monitor; + MetaMonitor *monitor; + gboolean need_done; + int version; + + need_done = FALSE; + old_logical_monitor = wayland_output->logical_monitor; + old_layout = meta_logical_monitor_get_layout (old_logical_monitor); + new_layout = meta_logical_monitor_get_layout (logical_monitor); + + if (need_all_events || + old_layout.x != new_layout.x || + old_layout.y != new_layout.y) + { + zxdg_output_v1_send_logical_position (resource, + new_layout.x, + new_layout.y); + need_done = TRUE; + } + + if (need_all_events || + old_layout.width != new_layout.width || + old_layout.height != new_layout.height) + { + zxdg_output_v1_send_logical_size (resource, + new_layout.width, + new_layout.height); + need_done = TRUE; + } + + version = wl_resource_get_version (resource); + monitor = pick_main_monitor (logical_monitor); + + if (need_all_events && version >= ZXDG_OUTPUT_V1_NAME_SINCE_VERSION) + { + const char *name; + + name = meta_monitor_get_connector (monitor); + zxdg_output_v1_send_name (resource, name); + } + + if (need_all_events && version >= ZXDG_OUTPUT_V1_DESCRIPTION_SINCE_VERSION) + { + const char *description; + + description = meta_monitor_get_display_name (monitor); + zxdg_output_v1_send_description (resource, description); + } + + if (pending_done_event && need_done) + *pending_done_event = TRUE; +} + +static void +meta_xdg_output_manager_get_xdg_output (struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *output) +{ + struct wl_resource *xdg_output_resource; + MetaWaylandOutput *wayland_output; + int xdg_output_version; + int wl_output_version; + + xdg_output_resource = wl_resource_create (client, + &zxdg_output_v1_interface, + wl_resource_get_version (resource), + id); + + wayland_output = wl_resource_get_user_data (output); + if (!wayland_output) + return; + + wl_resource_set_implementation (xdg_output_resource, + &meta_xdg_output_interface, + wayland_output, meta_xdg_output_destructor); + + wayland_output->xdg_output_resources = + g_list_prepend (wayland_output->xdg_output_resources, xdg_output_resource); + + if (!wayland_output->logical_monitor) + return; + + send_xdg_output_events (xdg_output_resource, + wayland_output, + wayland_output->logical_monitor, + TRUE, NULL); + + xdg_output_version = wl_resource_get_version (xdg_output_resource); + wl_output_version = wl_resource_get_version (output); + + if (xdg_output_version < NO_XDG_OUTPUT_DONE_SINCE_VERSION) + zxdg_output_v1_send_done (xdg_output_resource); + else if (wl_output_version >= WL_OUTPUT_DONE_SINCE_VERSION) + wl_output_send_done (output); +} + +static void +meta_xdg_output_manager_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static const struct zxdg_output_manager_v1_interface + meta_xdg_output_manager_interface = { + meta_xdg_output_manager_destroy, + meta_xdg_output_manager_get_xdg_output, + }; + +static void +bind_xdg_output_manager (struct wl_client *client, + void *data, + uint32_t version, + uint32_t id) +{ + struct wl_resource *resource; + + resource = wl_resource_create (client, + &zxdg_output_manager_v1_interface, + version, id); + + wl_resource_set_implementation (resource, + &meta_xdg_output_manager_interface, + NULL, NULL); +} + +void +meta_wayland_outputs_init (MetaWaylandCompositor *compositor) +{ + MetaMonitorManager *monitors; + + monitors = meta_monitor_manager_get (); + g_signal_connect (monitors, "monitors-changed-internal", + G_CALLBACK (on_monitors_changed), compositor); + + compositor->outputs = g_hash_table_new_full (g_int64_hash, g_int64_equal, NULL, + wayland_output_destroy_notify); + compositor->outputs = meta_wayland_compositor_update_outputs (compositor, monitors); + + wl_global_create (compositor->wayland_display, + &zxdg_output_manager_v1_interface, + META_ZXDG_OUTPUT_V1_VERSION, + NULL, + bind_xdg_output_manager); +} diff --git a/src/wayland/meta-wayland-outputs.h b/src/wayland/meta-wayland-outputs.h new file mode 100644 index 000000000..381febcdb --- /dev/null +++ b/src/wayland/meta-wayland-outputs.h @@ -0,0 +1,55 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jasper St. Pierre <jstpierre@mecheye.net> + */ + +#ifndef META_WAYLAND_OUTPUTS_H +#define META_WAYLAND_OUTPUTS_H + +#include "backends/meta-monitor-manager-private.h" +#include "wayland/meta-wayland-private.h" + +#define META_TYPE_WAYLAND_OUTPUT (meta_wayland_output_get_type ()) +G_DECLARE_FINAL_TYPE (MetaWaylandOutput, meta_wayland_output, + META, WAYLAND_OUTPUT, GObject) + +struct _MetaWaylandOutput +{ + GObject parent; + + struct wl_global *global; + MetaLogicalMonitor *logical_monitor; + guint mode_flags; + float refresh_rate; + gint scale; + int mode_width; + int mode_height; + + GList *resources; + GList *xdg_output_resources; + + uint64_t winsys_id; +}; + +void meta_wayland_outputs_init (MetaWaylandCompositor *compositor); + +#endif /* META_WAYLAND_OUTPUTS_H */ diff --git a/src/wayland/meta-wayland-pointer-constraints.c b/src/wayland/meta-wayland-pointer-constraints.c new file mode 100644 index 000000000..c36f4654c --- /dev/null +++ b/src/wayland/meta-wayland-pointer-constraints.c @@ -0,0 +1,1202 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2015 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +#include "config.h" + +#include "wayland/meta-wayland-pointer-constraints.h" + +#include <glib.h> + +#include "backends/meta-backend-private.h" +#include "backends/meta-pointer-constraint.h" +#include "core/frame.h" +#include "core/window-private.h" +#include "meta/meta-backend.h" +#include "wayland/meta-pointer-confinement-wayland.h" +#include "wayland/meta-pointer-lock-wayland.h" +#include "wayland/meta-wayland-pointer.h" +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-wayland-region.h" +#include "wayland/meta-wayland-seat.h" +#include "wayland/meta-wayland-surface.h" +#include "wayland/meta-xwayland.h" + +#include "pointer-constraints-unstable-v1-server-protocol.h" + +#ifdef HAVE_NATIVE_BACKEND +#include "backends/native/meta-backend-native.h" +#endif + +static GQuark quark_pending_constraint_state = 0; +static GQuark quark_surface_pointer_constraints_data = 0; + +struct _MetaWaylandPointerConstraint +{ + GObject parent; + + MetaWaylandSurface *surface; + gboolean is_enabled; + cairo_region_t *region; + struct wl_resource *resource; + MetaWaylandPointerGrab grab; + MetaWaylandSeat *seat; + enum zwp_pointer_constraints_v1_lifetime lifetime; + gulong pointer_focus_surface_handler_id; + + gboolean hint_set; + wl_fixed_t x_hint; + wl_fixed_t y_hint; + + MetaPointerConstraint *constraint; +}; + +typedef struct _MetaWaylandSurfacePointerConstraintsData +{ + MetaWaylandSurface *surface; + + GList *pointer_constraints; + + MetaWindow *window; + gulong window_associated_handler_id; + + gulong appears_changed_handler_id; + gulong raised_handler_id; +} MetaWaylandSurfacePointerConstraintsData; + +typedef struct +{ + MetaWaylandPointerConstraint *constraint; + cairo_region_t *region; + gulong applied_handler_id; +} MetaWaylandPendingConstraintState; + +typedef struct +{ + GList *pending_constraint_states; +} MetaWaylandPendingConstraintStateContainer; + +G_DEFINE_TYPE (MetaWaylandPointerConstraint, meta_wayland_pointer_constraint, + G_TYPE_OBJECT); + +static const struct zwp_locked_pointer_v1_interface locked_pointer_interface; +static const struct zwp_confined_pointer_v1_interface confined_pointer_interface; +static const MetaWaylandPointerGrabInterface locked_pointer_grab_interface; +static const MetaWaylandPointerGrabInterface confined_pointer_grab_interface; + +static void +meta_wayland_pointer_constraint_destroy (MetaWaylandPointerConstraint *constraint); + +static void +meta_wayland_pointer_constraint_maybe_enable (MetaWaylandPointerConstraint *constraint); + +static void +meta_wayland_pointer_constraint_maybe_enable_for_window (MetaWindow *window); + +static void +meta_wayland_pointer_constraint_maybe_remove_for_seat (MetaWaylandSeat *seat, + MetaWindow *window); + +static MetaWaylandSurfacePointerConstraintsData * +get_surface_constraints_data (MetaWaylandSurface *surface) +{ + return g_object_get_qdata (G_OBJECT (surface), + quark_surface_pointer_constraints_data); +} + +static void +appears_focused_changed (MetaWindow *window, + GParamSpec *pspec, + gpointer user_data) +{ + MetaWaylandCompositor *wayland_compositor; + + wayland_compositor = meta_wayland_compositor_get_default (); + meta_wayland_pointer_constraint_maybe_remove_for_seat (wayland_compositor->seat, + window); + + meta_wayland_pointer_constraint_maybe_enable_for_window (window); +} + +static void +window_raised (MetaWindow *window) +{ + meta_wayland_pointer_constraint_maybe_enable_for_window (window); +} + +static void +connect_window (MetaWaylandSurfacePointerConstraintsData *data, + MetaWindow *window) +{ + data->window = window; + g_object_add_weak_pointer (G_OBJECT (data->window), + (gpointer *) &data->window); + data->appears_changed_handler_id = + g_signal_connect (data->window, "notify::appears-focused", + G_CALLBACK (appears_focused_changed), NULL); + data->raised_handler_id = + g_signal_connect (data->window, "raised", + G_CALLBACK (window_raised), NULL); +} + +static void +window_associated (MetaWaylandSurfaceRole *surface_role, + MetaWaylandSurfacePointerConstraintsData *data) +{ + MetaWaylandSurface *surface = data->surface; + MetaWindow *window; + + window = meta_wayland_surface_get_window (surface); + connect_window (data, window); + g_clear_signal_handler (&data->window_associated_handler_id, surface); + + meta_wayland_pointer_constraint_maybe_enable_for_window (window); +} + +static MetaWaylandSurfacePointerConstraintsData * +surface_constraint_data_new (MetaWaylandSurface *surface) +{ + MetaWaylandSurfacePointerConstraintsData *data; + MetaWindow *window; + + data = g_new0 (MetaWaylandSurfacePointerConstraintsData, 1); + + data->surface = surface; + + window = meta_wayland_surface_get_window (surface); + if (window) + { + connect_window (data, window); + } + else if (meta_xwayland_is_xwayland_surface (surface)) + { + data->window_associated_handler_id = + g_signal_connect (surface->role, "window-associated", + G_CALLBACK (window_associated), + data); + } + else + { + /* TODO: Support constraints on non-toplevel windows, such as subsurfaces. + */ + g_warn_if_reached (); + } + + return data; +} +static void +surface_constraint_data_free (MetaWaylandSurfacePointerConstraintsData *data) +{ + if (data->window) + { + g_clear_signal_handler (&data->appears_changed_handler_id, data->window); + g_clear_signal_handler (&data->raised_handler_id, data->window); + g_object_remove_weak_pointer (G_OBJECT (data->window), + (gpointer *) &data->window); + } + else + { + g_clear_signal_handler (&data->window_associated_handler_id, + data->surface->role); + } + + g_list_free_full (data->pointer_constraints, + (GDestroyNotify) meta_wayland_pointer_constraint_destroy); + g_free (data); +} + +static void +constrained_surface_destroyed (MetaWaylandSurface *surface, + MetaWaylandSurfacePointerConstraintsData *data) +{ + surface_constraint_data_free (data); +} + +static MetaWaylandSurfacePointerConstraintsData * +ensure_surface_constraints_data (MetaWaylandSurface *surface) +{ + MetaWaylandSurfacePointerConstraintsData *data; + + data = get_surface_constraints_data (surface); + if (!data) + { + data = surface_constraint_data_new (surface); + g_object_set_qdata (G_OBJECT (surface), + quark_surface_pointer_constraints_data, + data); + g_signal_connect (surface, "destroy", + G_CALLBACK (constrained_surface_destroyed), data); + } + + return data; +} + +static void +surface_add_pointer_constraint (MetaWaylandSurface *surface, + MetaWaylandPointerConstraint *constraint) +{ + MetaWaylandSurfacePointerConstraintsData *data; + + data = ensure_surface_constraints_data (surface); + data->pointer_constraints = g_list_append (data->pointer_constraints, + constraint); +} + +static void +surface_remove_pointer_constraints (MetaWaylandSurface *surface, + MetaWaylandPointerConstraint *constraint) +{ + MetaWaylandSurfacePointerConstraintsData *data; + + data = get_surface_constraints_data (surface); + data->pointer_constraints = + g_list_remove (data->pointer_constraints, constraint); + + if (!data->pointer_constraints) + { + g_object_set_qdata (G_OBJECT (surface), + quark_surface_pointer_constraints_data, + NULL); + } +} + +static void +pointer_focus_surface_changed (MetaWaylandPointer *pointer, + MetaWaylandPointerConstraint *constraint) +{ + MetaWindow *window; + + window = meta_wayland_surface_get_window (constraint->surface); + if (window) + { + MetaWaylandSeat *seat = meta_wayland_pointer_get_seat (pointer); + + meta_wayland_pointer_constraint_maybe_remove_for_seat (seat, window); + } + + meta_wayland_pointer_constraint_maybe_enable (constraint); +} + +static MetaWaylandPointerConstraint * +meta_wayland_pointer_constraint_new (MetaWaylandSurface *surface, + MetaWaylandSeat *seat, + MetaWaylandRegion *region, + enum zwp_pointer_constraints_v1_lifetime lifetime, + struct wl_resource *resource, + const MetaWaylandPointerGrabInterface *grab_interface) +{ + MetaWaylandPointerConstraint *constraint; + + constraint = g_object_new (META_TYPE_WAYLAND_POINTER_CONSTRAINT, NULL); + if (!constraint) + return NULL; + + constraint->surface = surface; + constraint->seat = seat; + constraint->lifetime = lifetime; + constraint->resource = resource; + constraint->grab.interface = grab_interface; + + if (region) + { + constraint->region = + cairo_region_copy (meta_wayland_region_peek_cairo_region (region)); + } + else + { + constraint->region = NULL; + } + + constraint->pointer_focus_surface_handler_id = + g_signal_connect (seat->pointer, "focus-surface-changed", + G_CALLBACK (pointer_focus_surface_changed), + constraint); + + return constraint; +} + +static gboolean +meta_wayland_pointer_constraint_is_enabled (MetaWaylandPointerConstraint *constraint) +{ + return constraint->is_enabled; +} + +static void +meta_wayland_pointer_constraint_notify_activated (MetaWaylandPointerConstraint *constraint) +{ + struct wl_resource *resource = constraint->resource; + + if (wl_resource_instance_of (resource, + &zwp_locked_pointer_v1_interface, + &locked_pointer_interface)) + { + zwp_locked_pointer_v1_send_locked (resource); + } + else if (wl_resource_instance_of (resource, + &zwp_confined_pointer_v1_interface, + &confined_pointer_interface)) + { + zwp_confined_pointer_v1_send_confined (resource); + } +} + +static void +meta_wayland_pointer_constraint_notify_deactivated (MetaWaylandPointerConstraint *constraint) +{ + struct wl_resource *resource = constraint->resource; + + if (wl_resource_instance_of (resource, + &zwp_locked_pointer_v1_interface, + &locked_pointer_interface)) + zwp_locked_pointer_v1_send_unlocked (resource); + else if (wl_resource_instance_of (resource, + &zwp_confined_pointer_v1_interface, + &confined_pointer_interface)) + zwp_confined_pointer_v1_send_unconfined (resource); +} + +static MetaPointerConstraint * +meta_wayland_pointer_constraint_create_pointer_constraint (MetaWaylandPointerConstraint *constraint) +{ + struct wl_resource *resource = constraint->resource; + + if (wl_resource_instance_of (resource, + &zwp_locked_pointer_v1_interface, + &locked_pointer_interface)) + { + return meta_pointer_lock_wayland_new (); + } + else if (wl_resource_instance_of (resource, + &zwp_confined_pointer_v1_interface, + &confined_pointer_interface)) + { + return meta_pointer_confinement_wayland_new (constraint); + } + g_assert_not_reached (); + return NULL; +} + +static void +meta_wayland_pointer_constraint_enable (MetaWaylandPointerConstraint *constraint) +{ + MetaBackend *backend = meta_get_backend (); + + g_assert (!constraint->is_enabled); + + constraint->is_enabled = TRUE; + meta_wayland_pointer_constraint_notify_activated (constraint); + meta_wayland_pointer_start_grab (constraint->seat->pointer, + &constraint->grab); + + constraint->constraint = + meta_wayland_pointer_constraint_create_pointer_constraint (constraint); + meta_backend_set_client_pointer_constraint (backend, constraint->constraint); + g_object_add_weak_pointer (G_OBJECT (constraint->constraint), + (gpointer *) &constraint->constraint); + g_object_unref (constraint->constraint); +} + +static void +meta_wayland_pointer_constraint_disable (MetaWaylandPointerConstraint *constraint) +{ + constraint->is_enabled = FALSE; + meta_wayland_pointer_constraint_notify_deactivated (constraint); + meta_backend_set_client_pointer_constraint (meta_get_backend (), NULL); + meta_wayland_pointer_end_grab (constraint->grab.pointer); +} + +void +meta_wayland_pointer_constraint_destroy (MetaWaylandPointerConstraint *constraint) +{ + if (meta_wayland_pointer_constraint_is_enabled (constraint)) + meta_wayland_pointer_constraint_disable (constraint); + + wl_resource_set_user_data (constraint->resource, NULL); + g_clear_pointer (&constraint->region, cairo_region_destroy); + g_object_unref (constraint); +} + +static gboolean +is_within_constraint_region (MetaWaylandPointerConstraint *constraint, + wl_fixed_t sx, + wl_fixed_t sy) +{ + cairo_region_t *region; + gboolean is_within; + + region = meta_wayland_pointer_constraint_calculate_effective_region (constraint); + is_within = cairo_region_contains_point (region, + wl_fixed_to_int (sx), + wl_fixed_to_int (sy)); + cairo_region_destroy (region); + + return is_within; +} + +static gboolean +should_constraint_be_enabled (MetaWaylandPointerConstraint *constraint) +{ + MetaWindow *window; + + window = meta_wayland_surface_get_window (constraint->surface); + if (!window) + { + /* + * Locks from Xwayland may come before we have had the opportunity to + * associate the X11 Window with the wl_surface. + */ + g_warn_if_fail (meta_xwayland_is_xwayland_surface (constraint->surface)); + return FALSE; + } + + if (window->unmanaging) + return FALSE; + + if (constraint->seat->pointer->focus_surface != constraint->surface) + return FALSE; + + if (meta_xwayland_is_xwayland_surface (constraint->surface)) + { + MetaDisplay *display = meta_get_display (); + + /* + * We need to handle Xwayland surfaces differently in order to allow + * Xwayland to be able to lock the pointer. For example, we cannot require + * the locked window to "appear focused" because the surface Xwayland + * locks might not be able to appear focused (for example it may be a + * override redirect window). + * + * Since we don't have any way to know what focused window an override + * redirect is associated with, nor have a way to know if the override + * redirect window even shares the same connection as a focused window, + * we simply can only really restrict it to enable the lock if any + * Xwayland window appears focused. + */ + + if (display->focus_window && + display->focus_window->client_type != META_WINDOW_CLIENT_TYPE_X11) + return FALSE; + } + else + { + if (!meta_window_appears_focused (window)) + return FALSE; + } + + return TRUE; +} + +static void +meta_wayland_pointer_constraint_maybe_enable (MetaWaylandPointerConstraint *constraint) +{ + wl_fixed_t sx, sy; + + if (constraint->is_enabled) + return; + + if (!should_constraint_be_enabled (constraint)) + return; + + meta_wayland_pointer_get_relative_coordinates (constraint->seat->pointer, + constraint->surface, + &sx, &sy); + if (!is_within_constraint_region (constraint, sx, sy)) + return; + + meta_wayland_pointer_constraint_enable (constraint); +} + +static void +meta_wayland_pointer_constraint_remove (MetaWaylandPointerConstraint *constraint) +{ + MetaWaylandSurface *surface = constraint->surface; + + surface_remove_pointer_constraints (surface, constraint); + meta_wayland_pointer_constraint_destroy (constraint); +} + +static void +meta_wayland_pointer_constraint_deactivate (MetaWaylandPointerConstraint *constraint) +{ + switch (constraint->lifetime) + { + case ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ONESHOT: + meta_wayland_pointer_constraint_remove (constraint); + break; + + case ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT: + meta_wayland_pointer_constraint_disable (constraint); + break; + + default: + g_assert_not_reached (); + } +} + +void +meta_wayland_pointer_constraint_maybe_remove_for_seat (MetaWaylandSeat *seat, + MetaWindow *window) +{ + MetaWaylandPointer *pointer = seat->pointer; + MetaWaylandPointerConstraint *constraint; + + if ((pointer->grab->interface != &confined_pointer_grab_interface && + pointer->grab->interface != &locked_pointer_grab_interface)) + return; + + constraint = wl_container_of (pointer->grab, constraint, grab); + + if (should_constraint_be_enabled (constraint)) + return; + + meta_wayland_pointer_constraint_deactivate (constraint); +} + +static void +meta_wayland_pointer_constraint_maybe_enable_for_window (MetaWindow *window) +{ + MetaWaylandSurface *surface = window->surface; + MetaWaylandSurfacePointerConstraintsData *surface_data; + GList *l; + + if (!surface) + { + g_warn_if_fail (window->client_type == META_WINDOW_CLIENT_TYPE_X11); + return; + } + + surface_data = get_surface_constraints_data (surface); + if (!surface_data) + return; + + for (l = surface_data->pointer_constraints; l; l = l->next) + { + MetaWaylandPointerConstraint *constraint = l->data; + + meta_wayland_pointer_constraint_maybe_enable (constraint); + } +} + +MetaWaylandSeat * +meta_wayland_pointer_constraint_get_seat (MetaWaylandPointerConstraint *constraint) +{ + return constraint->seat; +} + +cairo_region_t * +meta_wayland_pointer_constraint_calculate_effective_region (MetaWaylandPointerConstraint *constraint) +{ + cairo_region_t *region; + MetaWindow *window; + + region = meta_wayland_surface_calculate_input_region (constraint->surface); + if (constraint->region) + cairo_region_intersect (region, constraint->region); + + window = meta_wayland_surface_get_window (constraint->surface); + if (window && window->frame) + { + MetaFrame *frame = window->frame; + int actual_width, actual_height; + + g_assert (meta_xwayland_is_xwayland_surface (constraint->surface)); + + actual_width = window->buffer_rect.width - (frame->child_x + + frame->right_width); + actual_height = window->buffer_rect.height - (frame->child_y + + frame->bottom_height); + if (actual_width > 0 && actual_height > 0) + { + cairo_region_intersect_rectangle (region, &(cairo_rectangle_int_t) { + .x = frame->child_x, + .y = frame->child_y, + .width = actual_width, + .height = actual_height + }); + } + } + + return region; +} + +MetaWaylandSurface * +meta_wayland_pointer_constraint_get_surface (MetaWaylandPointerConstraint *constraint) +{ + return constraint->surface; +} + +static void +pointer_constraint_resource_destroyed (struct wl_resource *resource) +{ + MetaWaylandPointerConstraint *constraint = + wl_resource_get_user_data (resource); + + if (!constraint) + return; + + meta_wayland_pointer_constraint_remove (constraint); +} + +static void +pending_constraint_state_free (MetaWaylandPendingConstraintState *constraint_pending) +{ + g_clear_pointer (&constraint_pending->region, cairo_region_destroy); + if (constraint_pending->constraint) + g_object_remove_weak_pointer (G_OBJECT (constraint_pending->constraint), + (gpointer *) &constraint_pending->constraint); +} + +static MetaWaylandPendingConstraintStateContainer * +get_pending_constraint_state_container (MetaWaylandSurfaceState *pending) +{ + return g_object_get_qdata (G_OBJECT (pending), + quark_pending_constraint_state); +} + +static MetaWaylandPendingConstraintState * +get_pending_constraint_state (MetaWaylandPointerConstraint *constraint) +{ + MetaWaylandSurfaceState *pending; + MetaWaylandPendingConstraintStateContainer *container; + GList *l; + + pending = meta_wayland_surface_get_pending_state (constraint->surface); + container = get_pending_constraint_state_container (pending); + for (l = container->pending_constraint_states; l; l = l->next) + { + MetaWaylandPendingConstraintState *constraint_pending = l->data; + + if (constraint_pending->constraint == constraint) + return constraint_pending; + } + + return NULL; +} + +static void +pending_constraint_state_container_free (MetaWaylandPendingConstraintStateContainer *container) +{ + g_list_free_full (container->pending_constraint_states, + (GDestroyNotify) pending_constraint_state_free); + g_free (container); +} + +static MetaWaylandPendingConstraintStateContainer * +ensure_pending_constraint_state_container (MetaWaylandSurfaceState *pending) +{ + MetaWaylandPendingConstraintStateContainer *container; + + container = get_pending_constraint_state_container (pending); + if (!container) + { + container = g_new0 (MetaWaylandPendingConstraintStateContainer, 1); + g_object_set_qdata_full (G_OBJECT (pending), + quark_pending_constraint_state, + container, + (GDestroyNotify) pending_constraint_state_container_free); + + } + + return container; +} + +static void +remove_pending_constraint_state (MetaWaylandPointerConstraint *constraint, + MetaWaylandSurfaceState *pending) +{ + MetaWaylandPendingConstraintStateContainer *container; + GList *l; + + container = get_pending_constraint_state_container (pending); + for (l = container->pending_constraint_states; l; l = l->next) + { + MetaWaylandPendingConstraintState *constraint_pending = l->data; + if (constraint_pending->constraint != constraint) + continue; + + pending_constraint_state_free (l->data); + container->pending_constraint_states = + g_list_remove_link (container->pending_constraint_states, l); + break; + } +} + +static void +pending_constraint_state_applied (MetaWaylandSurfaceState *pending, + MetaWaylandPendingConstraintState *constraint_pending) +{ + MetaWaylandPointerConstraint *constraint = constraint_pending->constraint; + + if (!constraint) + return; + + g_clear_pointer (&constraint->region, cairo_region_destroy); + if (constraint_pending->region) + { + constraint->region = constraint_pending->region; + constraint_pending->region = NULL; + } + else + { + constraint->region = NULL; + } + + g_clear_signal_handler (&constraint_pending->applied_handler_id, pending); + remove_pending_constraint_state (constraint, pending); + + /* The pointer is potentially warped by the actor paint signal callback if + * the new region proved it necessary. + */ +} + +static MetaWaylandPendingConstraintState * +ensure_pending_constraint_state (MetaWaylandPointerConstraint *constraint) +{ + MetaWaylandSurfaceState *pending; + MetaWaylandPendingConstraintStateContainer *container; + MetaWaylandPendingConstraintState *constraint_pending; + + pending = meta_wayland_surface_get_pending_state (constraint->surface); + container = ensure_pending_constraint_state_container (pending); + constraint_pending = get_pending_constraint_state (constraint); + if (!constraint_pending) + { + constraint_pending = g_new0 (MetaWaylandPendingConstraintState, 1); + constraint_pending->constraint = constraint; + constraint_pending->applied_handler_id = + g_signal_connect (pending, "applied", + G_CALLBACK (pending_constraint_state_applied), + constraint_pending); + g_object_add_weak_pointer (G_OBJECT (constraint), + (gpointer *) &constraint_pending->constraint); + + container->pending_constraint_states = + g_list_append (container->pending_constraint_states, + constraint_pending); + } + + return constraint_pending; +} + +static void +meta_wayland_pointer_constraint_set_pending_region (MetaWaylandPointerConstraint *constraint, + MetaWaylandRegion *region) +{ + MetaWaylandPendingConstraintState *constraint_pending; + + constraint_pending = ensure_pending_constraint_state (constraint); + + g_clear_pointer (&constraint_pending->region, cairo_region_destroy); + if (region) + { + constraint_pending->region = + cairo_region_copy (meta_wayland_region_peek_cairo_region (region)); + } +} + +static MetaWaylandPointerConstraint * +get_pointer_constraint_for_seat (MetaWaylandSurface *surface, + MetaWaylandSeat *seat) +{ + MetaWaylandSurfacePointerConstraintsData *surface_data; + GList *l; + + surface_data = get_surface_constraints_data (surface); + if (!surface_data) + return NULL; + + for (l = surface_data->pointer_constraints; l; l = l->next) + { + MetaWaylandPointerConstraint *constraint = l->data; + + if (seat == constraint->seat) + return constraint; + } + + return NULL; +} + +static void +init_pointer_constraint (struct wl_resource *resource, + uint32_t id, + MetaWaylandSurface *surface, + MetaWaylandSeat *seat, + MetaWaylandRegion *region, + enum zwp_pointer_constraints_v1_lifetime lifetime, + const struct wl_interface *interface, + const void *implementation, + const MetaWaylandPointerGrabInterface *grab_interface) +{ + struct wl_client *client = wl_resource_get_client (resource); + struct wl_resource *cr; + MetaWaylandPointerConstraint *constraint; + + if (get_pointer_constraint_for_seat (surface, seat)) + { + wl_resource_post_error (resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "the pointer was already requested to be " + "locked or confined on that surface"); + return; + } + + cr = wl_resource_create (client, interface, + wl_resource_get_version (resource), + id); + if (cr == NULL) + { + wl_client_post_no_memory (client); + return; + } + + switch (lifetime) + { + case ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ONESHOT: + case ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT: + break; + + default: + wl_resource_post_error (resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "Invalid constraint lifetime"); + return; + } + + constraint = meta_wayland_pointer_constraint_new (surface, seat, + region, + lifetime, + cr, grab_interface); + if (constraint == NULL) + { + wl_client_post_no_memory (client); + return; + } + + surface_add_pointer_constraint (surface, constraint); + + wl_resource_set_implementation (cr, implementation, constraint, + pointer_constraint_resource_destroyed); + + meta_wayland_pointer_constraint_maybe_enable (constraint); +} + +static void +locked_pointer_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + MetaWaylandPointerConstraint *constraint = + wl_resource_get_user_data (resource); + gboolean warp_pointer = FALSE; + int warp_x, warp_y; + + if (constraint && constraint->is_enabled && constraint->hint_set && + is_within_constraint_region (constraint, + constraint->x_hint, + constraint->y_hint)) + { + float sx, sy; + float x, y; + + sx = (float)wl_fixed_to_double (constraint->x_hint); + sy = (float)wl_fixed_to_double (constraint->y_hint); + meta_wayland_surface_get_absolute_coordinates (constraint->surface, + sx, sy, + &x, &y); + warp_pointer = TRUE; + warp_x = (int) x; + warp_y = (int) y; + } + wl_resource_destroy (resource); + + if (warp_pointer) + { + ClutterSeat *seat; + + seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); + clutter_seat_warp_pointer (seat, warp_x, warp_y); + } +} + +static void +locked_pointer_set_cursor_position_hint (struct wl_client *client, + struct wl_resource *resource, + wl_fixed_t surface_x, + wl_fixed_t surface_y) +{ + MetaWaylandPointerConstraint *constraint = + wl_resource_get_user_data (resource); + + /* Ignore a set cursor hint that was already sent after the constraint + * was cancelled. */ + if (!constraint || !constraint->resource || constraint->resource != resource) + return; + + constraint->hint_set = TRUE; + constraint->x_hint = surface_x; + constraint->y_hint = surface_y; +} + +static void +locked_pointer_set_region (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *region_resource) +{ + MetaWaylandPointerConstraint *constraint = + wl_resource_get_user_data (resource); + MetaWaylandRegion *region = + region_resource ? wl_resource_get_user_data (region_resource) : NULL; + + if (!constraint) + return; + + meta_wayland_pointer_constraint_set_pending_region (constraint, region); +} + +static const struct zwp_locked_pointer_v1_interface locked_pointer_interface = { + locked_pointer_destroy, + locked_pointer_set_cursor_position_hint, + locked_pointer_set_region, +}; + +static void +locked_pointer_grab_pointer_focus (MetaWaylandPointerGrab *grab, + MetaWaylandSurface *surface) +{ +} + +static void +locked_pointer_grab_pointer_motion (MetaWaylandPointerGrab *grab, + const ClutterEvent *event) +{ + meta_wayland_pointer_send_relative_motion (grab->pointer, event); + meta_wayland_pointer_broadcast_frame (grab->pointer); +} + +static void +locked_pointer_grab_pointer_button (MetaWaylandPointerGrab *grab, + const ClutterEvent *event) +{ + meta_wayland_pointer_send_button (grab->pointer, event); +} + +static void +locked_pointer_grab_pointer_cancel (MetaWaylandPointerGrab *grab) +{ + MetaWaylandPointerConstraint *constraint = + wl_container_of (grab, constraint, grab); + + meta_wayland_pointer_constraint_deactivate (constraint); +} + +static const MetaWaylandPointerGrabInterface locked_pointer_grab_interface = { + locked_pointer_grab_pointer_focus, + locked_pointer_grab_pointer_motion, + locked_pointer_grab_pointer_button, + locked_pointer_grab_pointer_cancel, +}; + +static void +pointer_constraints_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +pointer_constraints_lock_pointer (struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *surface_resource, + struct wl_resource *pointer_resource, + struct wl_resource *region_resource, + uint32_t lifetime) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + MetaWaylandPointer *pointer = wl_resource_get_user_data (pointer_resource); + MetaWaylandSeat *seat = meta_wayland_pointer_get_seat (pointer); + MetaWaylandRegion *region = + region_resource ? wl_resource_get_user_data (region_resource) : NULL; + + init_pointer_constraint (resource, id, surface, seat, region, lifetime, + &zwp_locked_pointer_v1_interface, + &locked_pointer_interface, + &locked_pointer_grab_interface); +} + +static void +confined_pointer_grab_pointer_focus (MetaWaylandPointerGrab *grab, + MetaWaylandSurface *surface) +{ +} + +static void +confined_pointer_grab_pointer_motion (MetaWaylandPointerGrab *grab, + const ClutterEvent *event) +{ + MetaWaylandPointerConstraint *constraint = + wl_container_of (grab, constraint, grab); + MetaWaylandPointer *pointer = grab->pointer; + + g_assert (pointer->focus_surface); + g_assert (pointer->focus_surface == constraint->surface); + + meta_wayland_pointer_send_motion (pointer, event); +} + +static void +confined_pointer_grab_pointer_button (MetaWaylandPointerGrab *grab, + const ClutterEvent *event) +{ + meta_wayland_pointer_send_button (grab->pointer, event); +} + +static void +confined_pointer_grab_pointer_cancel (MetaWaylandPointerGrab *grab) +{ + MetaWaylandPointerConstraint *constraint = + wl_container_of (grab, constraint, grab); + + meta_wayland_pointer_constraint_deactivate (constraint); +} + +static const MetaWaylandPointerGrabInterface confined_pointer_grab_interface = { + confined_pointer_grab_pointer_focus, + confined_pointer_grab_pointer_motion, + confined_pointer_grab_pointer_button, + confined_pointer_grab_pointer_cancel, +}; + +static void +confined_pointer_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +confined_pointer_set_region (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *region_resource) +{ + MetaWaylandPointerConstraint *constraint = + wl_resource_get_user_data (resource); + MetaWaylandRegion *region = + region_resource ? wl_resource_get_user_data (region_resource) : NULL; + + if (!constraint) + return; + + meta_wayland_pointer_constraint_set_pending_region (constraint, region); +} + +static const struct zwp_confined_pointer_v1_interface confined_pointer_interface = { + confined_pointer_destroy, + confined_pointer_set_region, +}; + +static void +pointer_constraints_confine_pointer (struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *surface_resource, + struct wl_resource *pointer_resource, + struct wl_resource *region_resource, + uint32_t lifetime) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + MetaWaylandPointer *pointer = wl_resource_get_user_data (pointer_resource); + MetaWaylandSeat *seat = meta_wayland_pointer_get_seat (pointer); + MetaWaylandRegion *region = + region_resource ? wl_resource_get_user_data (region_resource) : NULL; + + init_pointer_constraint (resource, id, surface, seat, region, lifetime, + &zwp_confined_pointer_v1_interface, + &confined_pointer_interface, + &confined_pointer_grab_interface); + +} + +static const struct zwp_pointer_constraints_v1_interface pointer_constraints = { + pointer_constraints_destroy, + pointer_constraints_lock_pointer, + pointer_constraints_confine_pointer, +}; + +static void +bind_pointer_constraints (struct wl_client *client, + void *data, + uint32_t version, + uint32_t id) +{ + MetaWaylandCompositor *compositor = data; + struct wl_resource *resource; + + resource = wl_resource_create (client, + &zwp_pointer_constraints_v1_interface, + 1, id); + + wl_resource_set_implementation (resource, + &pointer_constraints, + compositor, + NULL); +} + +static void +meta_wayland_pointer_constraint_finalize (GObject *object) +{ + MetaWaylandPointerConstraint *constraint = + META_WAYLAND_POINTER_CONSTRAINT (object); + + g_clear_signal_handler (&constraint->pointer_focus_surface_handler_id, + constraint->seat->pointer); + + G_OBJECT_CLASS (meta_wayland_pointer_constraint_parent_class)->finalize (object); +} + +void +meta_wayland_pointer_constraints_init (MetaWaylandCompositor *compositor) +{ + if (!wl_global_create (compositor->wayland_display, + &zwp_pointer_constraints_v1_interface, 1, + compositor, bind_pointer_constraints)) + g_error ("Could not create wp_pointer_constraints global"); +} + +static void +meta_wayland_pointer_constraint_init (MetaWaylandPointerConstraint *constraint) +{ +} + +static void +meta_wayland_pointer_constraint_class_init (MetaWaylandPointerConstraintClass *klass) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->finalize = meta_wayland_pointer_constraint_finalize; + + quark_pending_constraint_state = + g_quark_from_static_string ("-meta-wayland-pointer-constraint-pending_state"); + quark_surface_pointer_constraints_data = + g_quark_from_static_string ("-meta-wayland-surface-constraints-data"); +} diff --git a/src/wayland/meta-wayland-pointer-constraints.h b/src/wayland/meta-wayland-pointer-constraints.h new file mode 100644 index 000000000..dee7568de --- /dev/null +++ b/src/wayland/meta-wayland-pointer-constraints.h @@ -0,0 +1,47 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2015 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +#ifndef META_WAYLAND_POINTER_CONSTRAINTS_H +#define META_WAYLAND_POINTER_CONSTRAINTS_H + +#include <wayland-server.h> + +#include "meta/window.h" +#include "wayland/meta-wayland-types.h" + +#define META_TYPE_WAYLAND_POINTER_CONSTRAINT (meta_wayland_pointer_constraint_get_type ()) +G_DECLARE_FINAL_TYPE (MetaWaylandPointerConstraint, + meta_wayland_pointer_constraint, + META, WAYLAND_POINTER_CONSTRAINT, + GObject); + +void meta_wayland_pointer_constraints_init (MetaWaylandCompositor *compositor); + +MetaWaylandSeat * meta_wayland_pointer_constraint_get_seat (MetaWaylandPointerConstraint *constraint); + +cairo_region_t * meta_wayland_pointer_constraint_calculate_effective_region (MetaWaylandPointerConstraint *constraint); + +MetaWaylandSurface * meta_wayland_pointer_constraint_get_surface (MetaWaylandPointerConstraint *constraint); + +#endif /* META_WAYLAND_POINTER_CONSTRAINTS_H */ diff --git a/src/wayland/meta-wayland-pointer-gesture-pinch.c b/src/wayland/meta-wayland-pointer-gesture-pinch.c new file mode 100644 index 000000000..f7b37ff27 --- /dev/null +++ b/src/wayland/meta-wayland-pointer-gesture-pinch.c @@ -0,0 +1,166 @@ +/* + * Wayland Support + * + * Copyright (C) 2015 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#include "config.h" + +#include "wayland/meta-wayland-pointer-gesture-pinch.h" + +#include <glib.h> + +#include "wayland/meta-wayland-pointer.h" +#include "wayland/meta-wayland-seat.h" +#include "wayland/meta-wayland-surface.h" + +#include "pointer-gestures-unstable-v1-server-protocol.h" + +static void +handle_pinch_begin (MetaWaylandPointer *pointer, + const ClutterEvent *event) +{ + MetaWaylandPointerClient *pointer_client; + MetaWaylandSeat *seat; + struct wl_resource *resource; + uint32_t serial, fingers; + + pointer_client = pointer->focus_client; + seat = meta_wayland_pointer_get_seat (pointer); + serial = wl_display_next_serial (seat->wl_display); + fingers = clutter_event_get_touchpad_gesture_finger_count (event); + + wl_resource_for_each (resource, &pointer_client->pinch_gesture_resources) + { + zwp_pointer_gesture_pinch_v1_send_begin (resource, serial, + clutter_event_get_time (event), + pointer->focus_surface->resource, + fingers); + } +} + +static void +handle_pinch_update (MetaWaylandPointer *pointer, + const ClutterEvent *event) +{ + MetaWaylandPointerClient *pointer_client; + struct wl_resource *resource; + gdouble dx, dy, scale, rotation; + + pointer_client = pointer->focus_client; + clutter_event_get_gesture_motion_delta (event, &dx, &dy); + rotation = clutter_event_get_gesture_pinch_angle_delta (event); + scale = clutter_event_get_gesture_pinch_scale (event); + + wl_resource_for_each (resource, &pointer_client->pinch_gesture_resources) + { + zwp_pointer_gesture_pinch_v1_send_update (resource, + clutter_event_get_time (event), + wl_fixed_from_double (dx), + wl_fixed_from_double (dy), + wl_fixed_from_double (scale), + wl_fixed_from_double (rotation)); + } +} + +static void +handle_pinch_end (MetaWaylandPointer *pointer, + const ClutterEvent *event) +{ + MetaWaylandPointerClient *pointer_client; + MetaWaylandSeat *seat; + struct wl_resource *resource; + gboolean cancelled = FALSE; + uint32_t serial; + + pointer_client = pointer->focus_client; + seat = meta_wayland_pointer_get_seat (pointer); + serial = wl_display_next_serial (seat->wl_display); + + if (event->touchpad_pinch.phase == CLUTTER_TOUCHPAD_GESTURE_PHASE_CANCEL) + cancelled = TRUE; + + wl_resource_for_each (resource, &pointer_client->pinch_gesture_resources) + { + zwp_pointer_gesture_pinch_v1_send_end (resource, serial, + clutter_event_get_time (event), + cancelled); + } +} + +gboolean +meta_wayland_pointer_gesture_pinch_handle_event (MetaWaylandPointer *pointer, + const ClutterEvent *event) +{ + if (event->type != CLUTTER_TOUCHPAD_PINCH) + return FALSE; + + if (!pointer->focus_client) + return FALSE; + + switch (event->touchpad_pinch.phase) + { + case CLUTTER_TOUCHPAD_GESTURE_PHASE_BEGIN: + handle_pinch_begin (pointer, event); + break; + case CLUTTER_TOUCHPAD_GESTURE_PHASE_UPDATE: + handle_pinch_update (pointer, event); + break; + case CLUTTER_TOUCHPAD_GESTURE_PHASE_END: + case CLUTTER_TOUCHPAD_GESTURE_PHASE_CANCEL: + handle_pinch_end (pointer, event); + break; + default: + return FALSE; + } + + return TRUE; +} + +static void +pointer_gesture_pinch_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static const struct zwp_pointer_gesture_pinch_v1_interface pointer_gesture_pinch_interface = { + pointer_gesture_pinch_destroy +}; + +void +meta_wayland_pointer_gesture_pinch_create_new_resource (MetaWaylandPointer *pointer, + struct wl_client *client, + struct wl_resource *gestures_resource, + uint32_t id) +{ + MetaWaylandPointerClient *pointer_client; + struct wl_resource *res; + + pointer_client = meta_wayland_pointer_get_pointer_client (pointer, client); + g_return_if_fail (pointer_client != NULL); + + res = wl_resource_create (client, &zwp_pointer_gesture_pinch_v1_interface, + wl_resource_get_version (gestures_resource), id); + wl_resource_set_implementation (res, &pointer_gesture_pinch_interface, pointer, + meta_wayland_pointer_unbind_pointer_client_resource); + wl_list_insert (&pointer_client->pinch_gesture_resources, + wl_resource_get_link (res)); +} diff --git a/src/wayland/meta-wayland-pointer-gesture-pinch.h b/src/wayland/meta-wayland-pointer-gesture-pinch.h new file mode 100644 index 000000000..9ea3733f7 --- /dev/null +++ b/src/wayland/meta-wayland-pointer-gesture-pinch.h @@ -0,0 +1,39 @@ +/* + * Wayland Support + * + * Copyright (C) 2015 Red Hat + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef META_WAYLAND_POINTER_GESTURE_PINCH_H +#define META_WAYLAND_POINTER_GESTURE_PINCH_H + +#include <glib.h> +#include <wayland-server.h> + +#include "clutter/clutter.h" +#include "wayland/meta-wayland-types.h" + +gboolean meta_wayland_pointer_gesture_pinch_handle_event (MetaWaylandPointer *pointer, + const ClutterEvent *event); + +void meta_wayland_pointer_gesture_pinch_create_new_resource (MetaWaylandPointer *pointer, + struct wl_client *client, + struct wl_resource *gestures_resource, + uint32_t id); + +#endif /* META_WAYLAND_POINTER_GESTURE_PINCH_H */ diff --git a/src/wayland/meta-wayland-pointer-gesture-swipe.c b/src/wayland/meta-wayland-pointer-gesture-swipe.c new file mode 100644 index 000000000..043e3eb23 --- /dev/null +++ b/src/wayland/meta-wayland-pointer-gesture-swipe.c @@ -0,0 +1,161 @@ +/* + * Wayland Support + * + * Copyright (C) 2015 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#include "config.h" + +#include "wayland/meta-wayland-pointer-gesture-swipe.h" + +#include <glib.h> + +#include "wayland/meta-wayland-pointer.h" +#include "wayland/meta-wayland-seat.h" +#include "wayland/meta-wayland-surface.h" + +#include "pointer-gestures-unstable-v1-server-protocol.h" + +static void +handle_swipe_begin (MetaWaylandPointer *pointer, + const ClutterEvent *event) +{ + MetaWaylandPointerClient *pointer_client; + MetaWaylandSeat *seat; + struct wl_resource *resource; + uint32_t serial, fingers; + + pointer_client = pointer->focus_client; + seat = meta_wayland_pointer_get_seat (pointer); + serial = wl_display_next_serial (seat->wl_display); + fingers = clutter_event_get_touchpad_gesture_finger_count (event); + + wl_resource_for_each (resource, &pointer_client->swipe_gesture_resources) + { + zwp_pointer_gesture_swipe_v1_send_begin (resource, serial, + clutter_event_get_time (event), + pointer->focus_surface->resource, + fingers); + } +} + +static void +handle_swipe_update (MetaWaylandPointer *pointer, + const ClutterEvent *event) +{ + MetaWaylandPointerClient *pointer_client; + struct wl_resource *resource; + gdouble dx, dy; + + pointer_client = pointer->focus_client; + clutter_event_get_gesture_motion_delta (event, &dx, &dy); + + wl_resource_for_each (resource, &pointer_client->swipe_gesture_resources) + { + zwp_pointer_gesture_swipe_v1_send_update (resource, + clutter_event_get_time (event), + wl_fixed_from_double (dx), + wl_fixed_from_double (dy)); + } +} + +static void +handle_swipe_end (MetaWaylandPointer *pointer, + const ClutterEvent *event) +{ + MetaWaylandPointerClient *pointer_client; + MetaWaylandSeat *seat; + struct wl_resource *resource; + gboolean cancelled = FALSE; + uint32_t serial; + + pointer_client = pointer->focus_client; + seat = meta_wayland_pointer_get_seat (pointer); + serial = wl_display_next_serial (seat->wl_display); + + if (event->touchpad_swipe.phase == CLUTTER_TOUCHPAD_GESTURE_PHASE_CANCEL) + cancelled = TRUE; + + wl_resource_for_each (resource, &pointer_client->swipe_gesture_resources) + { + zwp_pointer_gesture_swipe_v1_send_end (resource, serial, + clutter_event_get_time (event), + cancelled); + } +} + +gboolean +meta_wayland_pointer_gesture_swipe_handle_event (MetaWaylandPointer *pointer, + const ClutterEvent *event) +{ + if (event->type != CLUTTER_TOUCHPAD_SWIPE) + return FALSE; + + if (!pointer->focus_client) + return FALSE; + + switch (event->touchpad_swipe.phase) + { + case CLUTTER_TOUCHPAD_GESTURE_PHASE_BEGIN: + handle_swipe_begin (pointer, event); + break; + case CLUTTER_TOUCHPAD_GESTURE_PHASE_UPDATE: + handle_swipe_update (pointer, event); + break; + case CLUTTER_TOUCHPAD_GESTURE_PHASE_END: + handle_swipe_end (pointer, event); + break; + default: + return FALSE; + } + + return TRUE; +} + +static void +pointer_gesture_swipe_release (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static const struct zwp_pointer_gesture_swipe_v1_interface pointer_gesture_swipe_interface = { + pointer_gesture_swipe_release +}; + +void +meta_wayland_pointer_gesture_swipe_create_new_resource (MetaWaylandPointer *pointer, + struct wl_client *client, + struct wl_resource *pointer_resource, + uint32_t id) +{ + MetaWaylandPointerClient *pointer_client; + struct wl_resource *res; + + pointer_client = meta_wayland_pointer_get_pointer_client (pointer, client); + g_return_if_fail (pointer_client != NULL); + + res = wl_resource_create (client, &zwp_pointer_gesture_swipe_v1_interface, + wl_resource_get_version (pointer_resource), id); + wl_resource_set_implementation (res, &pointer_gesture_swipe_interface, pointer, + meta_wayland_pointer_unbind_pointer_client_resource); + wl_list_insert (&pointer_client->swipe_gesture_resources, + wl_resource_get_link (res)); +} diff --git a/src/wayland/meta-wayland-pointer-gesture-swipe.h b/src/wayland/meta-wayland-pointer-gesture-swipe.h new file mode 100644 index 000000000..ed53fc4b2 --- /dev/null +++ b/src/wayland/meta-wayland-pointer-gesture-swipe.h @@ -0,0 +1,39 @@ +/* + * Wayland Support + * + * Copyright (C) 2015 Red Hat + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef META_WAYLAND_POINTER_GESTURE_SWIPE_H +#define META_WAYLAND_POINTER_GESTURE_SWIPE_H + +#include <glib.h> +#include <wayland-server.h> + +#include "clutter/clutter.h" +#include "wayland/meta-wayland-types.h" + +gboolean meta_wayland_pointer_gesture_swipe_handle_event (MetaWaylandPointer *pointer, + const ClutterEvent *event); + +void meta_wayland_pointer_gesture_swipe_create_new_resource (MetaWaylandPointer *pointer, + struct wl_client *client, + struct wl_resource *pointer_resource, + uint32_t id); + +#endif /* META_WAYLAND_POINTER_GESTURE_SWIPE_H */ diff --git a/src/wayland/meta-wayland-pointer-gestures.c b/src/wayland/meta-wayland-pointer-gestures.c new file mode 100644 index 000000000..7222a8a8c --- /dev/null +++ b/src/wayland/meta-wayland-pointer-gestures.c @@ -0,0 +1,83 @@ +/* + * Wayland Support + * + * Copyright (C) 2015 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#include "config.h" + +#include "wayland/meta-wayland-pointer-gestures.h" + +#include <glib.h> + +#include "wayland/meta-wayland-versions.h" +#include "wayland/meta-wayland-private.h" + +#include "pointer-gestures-unstable-v1-server-protocol.h" + +static void +gestures_get_swipe (struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *pointer_resource) +{ + MetaWaylandPointer *pointer = wl_resource_get_user_data (pointer_resource); + + meta_wayland_pointer_gesture_swipe_create_new_resource (pointer, client, resource, id); +} + +static void +gestures_get_pinch (struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *pointer_resource) +{ + MetaWaylandPointer *pointer = wl_resource_get_user_data (pointer_resource); + + meta_wayland_pointer_gesture_pinch_create_new_resource (pointer, client, resource, id); +} + +static const struct zwp_pointer_gestures_v1_interface pointer_gestures_interface = { + gestures_get_swipe, + gestures_get_pinch +}; + +static void +bind_pointer_gestures (struct wl_client *client, + void *data, + guint32 version, + guint32 id) +{ + struct wl_resource *resource; + + resource = wl_resource_create (client, &zwp_pointer_gestures_v1_interface, + version, id); + wl_resource_set_implementation (resource, &pointer_gestures_interface, + NULL, NULL); +} + +void +meta_wayland_pointer_gestures_init (MetaWaylandCompositor *compositor) +{ + wl_global_create (compositor->wayland_display, + &zwp_pointer_gestures_v1_interface, + META_ZWP_POINTER_GESTURES_V1_VERSION, + NULL, bind_pointer_gestures); +} diff --git a/src/wayland/meta-wayland-pointer-gestures.h b/src/wayland/meta-wayland-pointer-gestures.h new file mode 100644 index 000000000..48792da12 --- /dev/null +++ b/src/wayland/meta-wayland-pointer-gestures.h @@ -0,0 +1,32 @@ +/* + * Wayland Support + * + * Copyright (C) 2015 Red Hat + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef META_WAYLAND_POINTER_GESTURES_H +#define META_WAYLAND_POINTER_GESTURES_H + +#include <glib.h> +#include <wayland-server.h> + +#include "wayland/meta-wayland-types.h" + +void meta_wayland_pointer_gestures_init (MetaWaylandCompositor *compositor); + +#endif /* META_WAYLAND_POINTER_GESTURES_H */ diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c new file mode 100644 index 000000000..d30085202 --- /dev/null +++ b/src/wayland/meta-wayland-pointer.c @@ -0,0 +1,1387 @@ +/* + * Wayland Support + * + * Copyright (C) 2013 Intel Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * Copyright © 2008 Kristian Høgsberg + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* The file is based on src/input.c from Weston */ + +#include "config.h" + +#include <linux/input.h> +#include <string.h> + +#include "backends/meta-backend-private.h" +#include "backends/meta-cursor-renderer.h" +#include "backends/meta-cursor-tracker-private.h" +#include "backends/meta-cursor.h" +#include "clutter/clutter.h" +#include "cogl/cogl-wayland-server.h" +#include "cogl/cogl.h" +#include "compositor/meta-surface-actor-wayland.h" +#include "meta/meta-cursor-tracker.h" +#include "wayland/meta-wayland-buffer.h" +#include "wayland/meta-wayland-cursor-surface.h" +#include "wayland/meta-wayland-pointer.h" +#include "wayland/meta-wayland-popup.h" +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-wayland-seat.h" +#include "wayland/meta-wayland-surface.h" +#include "wayland/meta-xwayland.h" + +#ifdef HAVE_NATIVE_BACKEND +#include "backends/native/meta-backend-native.h" +#include "backends/native/meta-event-native.h" +#endif + +#include "relative-pointer-unstable-v1-server-protocol.h" + +#define DEFAULT_AXIS_STEP_DISTANCE wl_fixed_from_int (10) + +enum +{ + FOCUS_SURFACE_CHANGED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL]; + +G_DEFINE_TYPE (MetaWaylandPointer, meta_wayland_pointer, + META_TYPE_WAYLAND_INPUT_DEVICE) + +static void +meta_wayland_pointer_set_current (MetaWaylandPointer *pointer, + MetaWaylandSurface *surface); + +static void +meta_wayland_pointer_reset_grab (MetaWaylandPointer *pointer); + +static void +meta_wayland_pointer_cancel_grab (MetaWaylandPointer *pointer); + +static MetaWaylandPointerClient * +meta_wayland_pointer_client_new (void) +{ + MetaWaylandPointerClient *pointer_client; + + pointer_client = g_slice_new0 (MetaWaylandPointerClient); + wl_list_init (&pointer_client->pointer_resources); + wl_list_init (&pointer_client->swipe_gesture_resources); + wl_list_init (&pointer_client->pinch_gesture_resources); + wl_list_init (&pointer_client->relative_pointer_resources); + + return pointer_client; +} + +static void +meta_wayland_pointer_client_free (MetaWaylandPointerClient *pointer_client) +{ + struct wl_resource *resource, *next; + + /* Since we make every wl_pointer resource defunct when we stop advertising + * the pointer capability on the wl_seat, we need to make sure all the + * resources in the pointer client instance gets removed. + */ + wl_resource_for_each_safe (resource, next, &pointer_client->pointer_resources) + { + wl_list_remove (wl_resource_get_link (resource)); + wl_list_init (wl_resource_get_link (resource)); + } + wl_resource_for_each_safe (resource, next, &pointer_client->swipe_gesture_resources) + { + wl_list_remove (wl_resource_get_link (resource)); + wl_list_init (wl_resource_get_link (resource)); + } + wl_resource_for_each_safe (resource, next, &pointer_client->pinch_gesture_resources) + { + wl_list_remove (wl_resource_get_link (resource)); + wl_list_init (wl_resource_get_link (resource)); + } + wl_resource_for_each_safe (resource, next, &pointer_client->relative_pointer_resources) + { + wl_list_remove (wl_resource_get_link (resource)); + wl_list_init (wl_resource_get_link (resource)); + } + + g_slice_free (MetaWaylandPointerClient, pointer_client); +} + +static gboolean +meta_wayland_pointer_client_is_empty (MetaWaylandPointerClient *pointer_client) +{ + return (wl_list_empty (&pointer_client->pointer_resources) && + wl_list_empty (&pointer_client->swipe_gesture_resources) && + wl_list_empty (&pointer_client->pinch_gesture_resources) && + wl_list_empty (&pointer_client->relative_pointer_resources)); +} + +MetaWaylandPointerClient * +meta_wayland_pointer_get_pointer_client (MetaWaylandPointer *pointer, + struct wl_client *client) +{ + if (!pointer->pointer_clients) + return NULL; + return g_hash_table_lookup (pointer->pointer_clients, client); +} + +static MetaWaylandPointerClient * +meta_wayland_pointer_ensure_pointer_client (MetaWaylandPointer *pointer, + struct wl_client *client) +{ + MetaWaylandPointerClient *pointer_client; + + pointer_client = meta_wayland_pointer_get_pointer_client (pointer, client); + if (pointer_client) + return pointer_client; + + pointer_client = meta_wayland_pointer_client_new (); + g_hash_table_insert (pointer->pointer_clients, client, pointer_client); + + if (!pointer->focus_client && + pointer->focus_surface && + wl_resource_get_client (pointer->focus_surface->resource) == client) + pointer->focus_client = pointer_client; + + return pointer_client; +} + +static void +meta_wayland_pointer_cleanup_pointer_client (MetaWaylandPointer *pointer, + MetaWaylandPointerClient *pointer_client, + struct wl_client *client) +{ + if (meta_wayland_pointer_client_is_empty (pointer_client)) + { + if (pointer->focus_client == pointer_client) + pointer->focus_client = NULL; + g_hash_table_remove (pointer->pointer_clients, client); + } +} + +void +meta_wayland_pointer_unbind_pointer_client_resource (struct wl_resource *resource) +{ + MetaWaylandPointer *pointer = wl_resource_get_user_data (resource); + MetaWaylandPointerClient *pointer_client; + struct wl_client *client = wl_resource_get_client (resource); + + wl_list_remove (wl_resource_get_link (resource)); + + pointer_client = meta_wayland_pointer_get_pointer_client (pointer, client); + if (!pointer_client) + { + /* This happens if all pointer devices were unplugged and no new resources + * were created by the client. + * + * If this is a resource that was previously made defunct, pointer_client + * be non-NULL but it is harmless since the below cleanup call will be + * prevented from removing the pointer client because of valid resources. + */ + return; + } + + meta_wayland_pointer_cleanup_pointer_client (pointer, + pointer_client, + client); +} + +static void +sync_focus_surface (MetaWaylandPointer *pointer) +{ + MetaDisplay *display = meta_get_display (); + MetaBackend *backend = meta_get_backend (); + MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend); + ClutterBackend *clutter_backend = clutter_get_default_backend (); + ClutterSeat *clutter_seat = clutter_backend_get_default_seat (clutter_backend); + + if (!meta_cursor_tracker_get_pointer_visible (cursor_tracker) && + !clutter_seat_is_unfocus_inhibited (clutter_seat)) + { + meta_wayland_pointer_set_focus (pointer, NULL); + return; + } + + switch (display->event_route) + { + case META_EVENT_ROUTE_WINDOW_OP: + case META_EVENT_ROUTE_COMPOSITOR_GRAB: + case META_EVENT_ROUTE_FRAME_BUTTON: + /* The compositor has a grab, so remove our focus... */ + meta_wayland_pointer_set_focus (pointer, NULL); + break; + + case META_EVENT_ROUTE_NORMAL: + case META_EVENT_ROUTE_WAYLAND_POPUP: + { + const MetaWaylandPointerGrabInterface *interface = pointer->grab->interface; + interface->focus (pointer->grab, pointer->current); + } + break; + + default: + g_assert_not_reached (); + } + +} + +static void +meta_wayland_pointer_send_frame (MetaWaylandPointer *pointer, + struct wl_resource *resource) +{ + if (wl_resource_get_version (resource) >= WL_POINTER_AXIS_SOURCE_SINCE_VERSION) + wl_pointer_send_frame (resource); +} + +void +meta_wayland_pointer_broadcast_frame (MetaWaylandPointer *pointer) +{ + struct wl_resource *resource; + + if (!pointer->focus_client) + return; + + wl_resource_for_each (resource, &pointer->focus_client->pointer_resources) + { + meta_wayland_pointer_send_frame (pointer, resource); + } +} + +void +meta_wayland_pointer_send_relative_motion (MetaWaylandPointer *pointer, + const ClutterEvent *event) +{ +#ifdef HAVE_NATIVE_BACKEND + struct wl_resource *resource; + double dx, dy; + double dx_unaccel, dy_unaccel; + uint64_t time_us; + uint32_t time_us_hi; + uint32_t time_us_lo; + wl_fixed_t dxf, dyf; + wl_fixed_t dx_unaccelf, dy_unaccelf; + MetaBackend *backend = meta_get_backend (); + + if (!pointer->focus_client) + return; + + if (!META_IS_BACKEND_NATIVE (backend) || + !meta_event_native_get_relative_motion (event, + &dx, &dy, + &dx_unaccel, &dy_unaccel)) + return; + + time_us = meta_event_native_get_time_usec (event); + if (time_us == 0) + time_us = clutter_event_get_time (event) * 1000ULL; + time_us_hi = (uint32_t) (time_us >> 32); + time_us_lo = (uint32_t) time_us; + dxf = wl_fixed_from_double (dx); + dyf = wl_fixed_from_double (dy); + dx_unaccelf = wl_fixed_from_double (dx_unaccel); + dy_unaccelf = wl_fixed_from_double (dy_unaccel); + + wl_resource_for_each (resource, + &pointer->focus_client->relative_pointer_resources) + { + zwp_relative_pointer_v1_send_relative_motion (resource, + time_us_hi, + time_us_lo, + dxf, + dyf, + dx_unaccelf, + dy_unaccelf); + } +#endif +} + +void +meta_wayland_pointer_send_motion (MetaWaylandPointer *pointer, + const ClutterEvent *event) +{ + struct wl_resource *resource; + uint32_t time; + float sx, sy; + + if (!pointer->focus_client) + return; + + time = clutter_event_get_time (event); + meta_wayland_surface_get_relative_coordinates (pointer->focus_surface, + event->motion.x, + event->motion.y, + &sx, &sy); + + wl_resource_for_each (resource, &pointer->focus_client->pointer_resources) + { + wl_pointer_send_motion (resource, time, + wl_fixed_from_double (sx), + wl_fixed_from_double (sy)); + } + + meta_wayland_pointer_send_relative_motion (pointer, event); + + meta_wayland_pointer_broadcast_frame (pointer); +} + +void +meta_wayland_pointer_send_button (MetaWaylandPointer *pointer, + const ClutterEvent *event) +{ + struct wl_resource *resource; + ClutterEventType event_type; + + event_type = clutter_event_type (event); + + if (pointer->focus_client && + !wl_list_empty (&pointer->focus_client->pointer_resources)) + { + MetaWaylandInputDevice *input_device = + META_WAYLAND_INPUT_DEVICE (pointer); + uint32_t time; + uint32_t button; + uint32_t serial; + +#ifdef HAVE_NATIVE_BACKEND + MetaBackend *backend = meta_get_backend (); + if (META_IS_BACKEND_NATIVE (backend)) + button = meta_event_native_get_event_code (event); + else +#endif + { + button = clutter_event_get_button (event); + switch (button) + { + case 1: + button = BTN_LEFT; + break; + + /* The evdev input right and middle button numbers are swapped + relative to how Clutter numbers them */ + case 2: + button = BTN_MIDDLE; + break; + + case 3: + button = BTN_RIGHT; + break; + + default: + button = button + (BTN_LEFT - 1) + 4; + break; + } + } + + time = clutter_event_get_time (event); + serial = meta_wayland_input_device_next_serial (input_device); + + wl_resource_for_each (resource, &pointer->focus_client->pointer_resources) + { + wl_pointer_send_button (resource, serial, + time, button, + event_type == CLUTTER_BUTTON_PRESS ? 1 : 0); + } + + meta_wayland_pointer_broadcast_frame (pointer); + } + + if (pointer->button_count == 0 && event_type == CLUTTER_BUTTON_RELEASE) + sync_focus_surface (pointer); +} + +static void +default_grab_focus (MetaWaylandPointerGrab *grab, + MetaWaylandSurface *surface) +{ + MetaWaylandPointer *pointer = grab->pointer; + MetaWaylandSeat *seat = meta_wayland_pointer_get_seat (pointer); + MetaDisplay *display = meta_get_display (); + MetaBackend *backend = meta_get_backend (); + MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend); + ClutterBackend *clutter_backend = clutter_get_default_backend (); + ClutterSeat *clutter_seat = clutter_backend_get_default_seat (clutter_backend); + + if (!meta_wayland_seat_has_pointer (seat)) + return; + + if (!meta_cursor_tracker_get_pointer_visible (cursor_tracker) && + !clutter_seat_is_unfocus_inhibited (clutter_seat)) + return; + + if (pointer->button_count > 0) + return; + + switch (display->event_route) + { + case META_EVENT_ROUTE_WINDOW_OP: + case META_EVENT_ROUTE_COMPOSITOR_GRAB: + case META_EVENT_ROUTE_FRAME_BUTTON: + return; + break; + + case META_EVENT_ROUTE_NORMAL: + case META_EVENT_ROUTE_WAYLAND_POPUP: + break; + } + + meta_wayland_pointer_set_focus (pointer, surface); +} + +static void +default_grab_motion (MetaWaylandPointerGrab *grab, + const ClutterEvent *event) +{ + MetaWaylandPointer *pointer = grab->pointer; + + meta_wayland_pointer_send_motion (pointer, event); +} + +static void +default_grab_button (MetaWaylandPointerGrab *grab, + const ClutterEvent *event) +{ + MetaWaylandPointer *pointer = grab->pointer; + + meta_wayland_pointer_send_button (pointer, event); +} + +static const MetaWaylandPointerGrabInterface default_pointer_grab_interface = { + default_grab_focus, + default_grab_motion, + default_grab_button +}; + +static void +meta_wayland_pointer_on_cursor_changed (MetaCursorTracker *cursor_tracker, + MetaWaylandPointer *pointer) +{ + if (pointer->cursor_surface) + meta_wayland_surface_update_outputs (pointer->cursor_surface); +} + +void +meta_wayland_pointer_enable (MetaWaylandPointer *pointer) +{ + MetaBackend *backend = meta_get_backend (); + MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend); + ClutterSeat *clutter_seat; + + pointer->pointer_clients = + g_hash_table_new_full (NULL, NULL, NULL, + (GDestroyNotify) meta_wayland_pointer_client_free); + + pointer->cursor_surface = NULL; + + clutter_seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); + pointer->device = clutter_seat_get_pointer (clutter_seat); + + g_signal_connect (cursor_tracker, + "cursor-changed", + G_CALLBACK (meta_wayland_pointer_on_cursor_changed), + pointer); + + g_signal_connect_swapped (cursor_tracker, + "visibility-changed", + G_CALLBACK (sync_focus_surface), + pointer); + + g_signal_connect_swapped (clutter_seat, + "is-unfocus-inhibited-changed", + G_CALLBACK (sync_focus_surface), + pointer); +} + +void +meta_wayland_pointer_disable (MetaWaylandPointer *pointer) +{ + MetaBackend *backend = meta_get_backend (); + MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend); + ClutterBackend *clutter_backend = clutter_get_default_backend (); + ClutterSeat *clutter_seat = clutter_backend_get_default_seat (clutter_backend); + + g_signal_handlers_disconnect_by_func (cursor_tracker, + (gpointer) meta_wayland_pointer_on_cursor_changed, + pointer); + + g_signal_handlers_disconnect_by_func (cursor_tracker, + sync_focus_surface, + pointer); + + g_signal_handlers_disconnect_by_func (clutter_seat, + sync_focus_surface, + pointer); + + if (pointer->cursor_surface) + { + g_clear_signal_handler (&pointer->cursor_surface_destroy_id, + pointer->cursor_surface); + } + + meta_wayland_pointer_cancel_grab (pointer); + meta_wayland_pointer_reset_grab (pointer); + meta_wayland_pointer_set_focus (pointer, NULL); + meta_wayland_pointer_set_current (pointer, NULL); + + g_clear_pointer (&pointer->pointer_clients, g_hash_table_unref); + pointer->cursor_surface = NULL; +} + +static int +count_buttons (const ClutterEvent *event) +{ + static gint maskmap[5] = + { + CLUTTER_BUTTON1_MASK, CLUTTER_BUTTON2_MASK, CLUTTER_BUTTON3_MASK, + CLUTTER_BUTTON4_MASK, CLUTTER_BUTTON5_MASK + }; + ClutterModifierType mod_mask; + int i, count; + + mod_mask = clutter_event_get_state (event); + count = 0; + for (i = 0; i < 5; i++) + { + if (mod_mask & maskmap[i]) + count++; + } + + return count; +} + +static void +current_surface_destroyed (MetaWaylandSurface *surface, + MetaWaylandPointer *pointer) +{ + meta_wayland_pointer_set_current (pointer, NULL); +} + +static void +meta_wayland_pointer_set_current (MetaWaylandPointer *pointer, + MetaWaylandSurface *surface) +{ + if (pointer->current) + { + g_clear_signal_handler (&pointer->current_surface_destroyed_handler_id, + pointer->current); + pointer->current = NULL; + } + + if (surface) + { + pointer->current = surface; + pointer->current_surface_destroyed_handler_id = + g_signal_connect (surface, "destroy", + G_CALLBACK (current_surface_destroyed), + pointer); + } +} + +static void +repick_for_event (MetaWaylandPointer *pointer, + const ClutterEvent *for_event) +{ + ClutterActor *actor; + MetaWaylandSurface *surface; + + if (for_event) + actor = clutter_event_get_source (for_event); + else + actor = clutter_input_device_get_pointer_actor (pointer->device); + + if (META_IS_SURFACE_ACTOR_WAYLAND (actor)) + { + MetaSurfaceActorWayland *actor_wayland = + META_SURFACE_ACTOR_WAYLAND (actor); + + surface = meta_surface_actor_wayland_get_surface (actor_wayland); + } + else + { + surface = NULL; + } + + meta_wayland_pointer_set_current (pointer, surface); + + sync_focus_surface (pointer); + meta_wayland_pointer_update_cursor_surface (pointer); +} + +void +meta_wayland_pointer_update (MetaWaylandPointer *pointer, + const ClutterEvent *event) +{ + repick_for_event (pointer, event); + + if (event->type == CLUTTER_MOTION || + event->type == CLUTTER_BUTTON_PRESS || + event->type == CLUTTER_BUTTON_RELEASE) + { + pointer->button_count = count_buttons (event); + } +} + +static void +notify_motion (MetaWaylandPointer *pointer, + const ClutterEvent *event) +{ + pointer->grab->interface->motion (pointer->grab, event); +} + +static void +handle_motion_event (MetaWaylandPointer *pointer, + const ClutterEvent *event) +{ + notify_motion (pointer, event); +} + +static void +handle_button_event (MetaWaylandPointer *pointer, + const ClutterEvent *event) +{ + gboolean implicit_grab; + + implicit_grab = (event->type == CLUTTER_BUTTON_PRESS) && (pointer->button_count == 1); + if (implicit_grab) + { + pointer->grab_button = clutter_event_get_button (event); + pointer->grab_time = clutter_event_get_time (event); + clutter_event_get_coords (event, &pointer->grab_x, &pointer->grab_y); + } + + pointer->grab->interface->button (pointer->grab, event); + + if (implicit_grab) + { + MetaWaylandSeat *seat = meta_wayland_pointer_get_seat (pointer); + + pointer->grab_serial = wl_display_get_serial (seat->wl_display); + } +} + +static void +handle_scroll_event (MetaWaylandPointer *pointer, + const ClutterEvent *event) +{ + struct wl_resource *resource; + wl_fixed_t x_value = 0, y_value = 0; + int x_discrete = 0, y_discrete = 0; + enum wl_pointer_axis_source source = -1; + + if (clutter_event_is_pointer_emulated (event)) + return; + + switch (event->scroll.scroll_source) + { + case CLUTTER_SCROLL_SOURCE_WHEEL: + source = WL_POINTER_AXIS_SOURCE_WHEEL; + break; + case CLUTTER_SCROLL_SOURCE_FINGER: + source = WL_POINTER_AXIS_SOURCE_FINGER; + break; + case CLUTTER_SCROLL_SOURCE_CONTINUOUS: + source = WL_POINTER_AXIS_SOURCE_CONTINUOUS; + break; + default: + source = WL_POINTER_AXIS_SOURCE_WHEEL; + break; + } + + switch (clutter_event_get_scroll_direction (event)) + { + case CLUTTER_SCROLL_UP: + y_value = -DEFAULT_AXIS_STEP_DISTANCE; + y_discrete = -1; + break; + + case CLUTTER_SCROLL_DOWN: + y_value = DEFAULT_AXIS_STEP_DISTANCE; + y_discrete = 1; + break; + + case CLUTTER_SCROLL_LEFT: + x_value = -DEFAULT_AXIS_STEP_DISTANCE; + x_discrete = -1; + break; + + case CLUTTER_SCROLL_RIGHT: + x_value = DEFAULT_AXIS_STEP_DISTANCE; + x_discrete = 1; + break; + + case CLUTTER_SCROLL_SMOOTH: + { + double dx, dy; + /* Clutter smooth scroll events are in discrete steps (1 step = 1.0 long + * vector along one axis). To convert to smooth scroll events that are + * in pointer motion event space, multiply the vector with the 10. */ + const double factor = 10.0; + clutter_event_get_scroll_delta (event, &dx, &dy); + x_value = wl_fixed_from_double (dx) * factor; + y_value = wl_fixed_from_double (dy) * factor; + } + break; + + default: + return; + } + + if (pointer->focus_client) + { + wl_resource_for_each (resource, &pointer->focus_client->pointer_resources) + { + if (wl_resource_get_version (resource) >= WL_POINTER_AXIS_SOURCE_SINCE_VERSION) + wl_pointer_send_axis_source (resource, source); + + /* X axis */ + if (x_discrete != 0 && + wl_resource_get_version (resource) >= WL_POINTER_AXIS_DISCRETE_SINCE_VERSION) + wl_pointer_send_axis_discrete (resource, + WL_POINTER_AXIS_HORIZONTAL_SCROLL, + x_discrete); + + if (x_value) + wl_pointer_send_axis (resource, clutter_event_get_time (event), + WL_POINTER_AXIS_HORIZONTAL_SCROLL, x_value); + + if ((event->scroll.finish_flags & CLUTTER_SCROLL_FINISHED_HORIZONTAL) && + wl_resource_get_version (resource) >= WL_POINTER_AXIS_STOP_SINCE_VERSION) + wl_pointer_send_axis_stop (resource, + clutter_event_get_time (event), + WL_POINTER_AXIS_HORIZONTAL_SCROLL); + /* Y axis */ + if (y_discrete != 0 && + wl_resource_get_version (resource) >= WL_POINTER_AXIS_DISCRETE_SINCE_VERSION) + wl_pointer_send_axis_discrete (resource, + WL_POINTER_AXIS_VERTICAL_SCROLL, + y_discrete); + + if (y_value) + wl_pointer_send_axis (resource, clutter_event_get_time (event), + WL_POINTER_AXIS_VERTICAL_SCROLL, y_value); + + if ((event->scroll.finish_flags & CLUTTER_SCROLL_FINISHED_VERTICAL) && + wl_resource_get_version (resource) >= WL_POINTER_AXIS_STOP_SINCE_VERSION) + wl_pointer_send_axis_stop (resource, + clutter_event_get_time (event), + WL_POINTER_AXIS_VERTICAL_SCROLL); + } + + meta_wayland_pointer_broadcast_frame (pointer); + } +} + +gboolean +meta_wayland_pointer_handle_event (MetaWaylandPointer *pointer, + const ClutterEvent *event) +{ + switch (event->type) + { + case CLUTTER_MOTION: + handle_motion_event (pointer, event); + break; + + case CLUTTER_BUTTON_PRESS: + case CLUTTER_BUTTON_RELEASE: + handle_button_event (pointer, event); + break; + + case CLUTTER_SCROLL: + handle_scroll_event (pointer, event); + break; + + case CLUTTER_TOUCHPAD_SWIPE: + meta_wayland_pointer_gesture_swipe_handle_event (pointer, event); + break; + + case CLUTTER_TOUCHPAD_PINCH: + meta_wayland_pointer_gesture_pinch_handle_event (pointer, event); + break; + + default: + break; + } + + return FALSE; +} + +static void +meta_wayland_pointer_send_enter (MetaWaylandPointer *pointer, + struct wl_resource *pointer_resource, + uint32_t serial, + MetaWaylandSurface *surface) +{ + wl_fixed_t sx, sy; + + meta_wayland_pointer_get_relative_coordinates (pointer, surface, &sx, &sy); + wl_pointer_send_enter (pointer_resource, + serial, + surface->resource, + sx, sy); +} + +static void +meta_wayland_pointer_send_leave (MetaWaylandPointer *pointer, + struct wl_resource *pointer_resource, + uint32_t serial, + MetaWaylandSurface *surface) +{ + wl_pointer_send_leave (pointer_resource, serial, surface->resource); +} + +static void +meta_wayland_pointer_broadcast_enter (MetaWaylandPointer *pointer, + uint32_t serial, + MetaWaylandSurface *surface) +{ + struct wl_resource *pointer_resource; + + wl_resource_for_each (pointer_resource, + &pointer->focus_client->pointer_resources) + meta_wayland_pointer_send_enter (pointer, pointer_resource, + serial, surface); + + meta_wayland_pointer_broadcast_frame (pointer); +} + +static void +meta_wayland_pointer_broadcast_leave (MetaWaylandPointer *pointer, + uint32_t serial, + MetaWaylandSurface *surface) +{ + struct wl_resource *pointer_resource; + + wl_resource_for_each (pointer_resource, + &pointer->focus_client->pointer_resources) + meta_wayland_pointer_send_leave (pointer, pointer_resource, + serial, surface); + + meta_wayland_pointer_broadcast_frame (pointer); +} + +static void +focus_surface_destroyed (MetaWaylandSurface *surface, + MetaWaylandPointer *pointer) +{ + meta_wayland_pointer_set_focus (pointer, NULL); +} + +void +meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, + MetaWaylandSurface *surface) +{ + MetaWaylandInputDevice *input_device = META_WAYLAND_INPUT_DEVICE (pointer); + MetaBackend *backend = meta_get_backend (); + MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend); + ClutterBackend *clutter_backend = clutter_get_default_backend (); + ClutterSeat *clutter_seat = clutter_backend_get_default_seat (clutter_backend); + + g_return_if_fail (meta_cursor_tracker_get_pointer_visible (cursor_tracker) || + clutter_seat_is_unfocus_inhibited (clutter_seat) || + surface == NULL); + + if (pointer->focus_surface == surface) + return; + + if (pointer->focus_surface != NULL) + { + uint32_t serial; + + serial = meta_wayland_input_device_next_serial (input_device); + + if (pointer->focus_client) + { + meta_wayland_pointer_broadcast_leave (pointer, + serial, + pointer->focus_surface); + pointer->focus_client = NULL; + } + + g_clear_signal_handler (&pointer->focus_surface_destroyed_handler_id, + pointer->focus_surface); + pointer->focus_surface = NULL; + } + + if (surface != NULL) + { + struct wl_client *client = wl_resource_get_client (surface->resource); + graphene_point_t pos; + MetaWindow *focus_window; + + pointer->focus_surface = surface; + + pointer->focus_surface_destroyed_handler_id = + g_signal_connect_after (pointer->focus_surface, "destroy", + G_CALLBACK (focus_surface_destroyed), + pointer); + + clutter_input_device_get_coords (pointer->device, NULL, &pos); + + focus_window = meta_wayland_surface_get_window (pointer->focus_surface); + if (focus_window) + meta_window_handle_enter (focus_window, + /* XXX -- can we reliably get a timestamp for setting focus? */ + clutter_get_current_event_time (), + pos.x, pos.y); + + pointer->focus_client = + meta_wayland_pointer_get_pointer_client (pointer, client); + if (pointer->focus_client) + { + pointer->focus_serial = + meta_wayland_input_device_next_serial (input_device); + meta_wayland_pointer_broadcast_enter (pointer, + pointer->focus_serial, + pointer->focus_surface); + } + } + + meta_wayland_pointer_update_cursor_surface (pointer); + + g_signal_emit (pointer, signals[FOCUS_SURFACE_CHANGED], 0); +} + +void +meta_wayland_pointer_start_grab (MetaWaylandPointer *pointer, + MetaWaylandPointerGrab *grab) +{ + const MetaWaylandPointerGrabInterface *interface; + + meta_wayland_pointer_cancel_grab (pointer); + + pointer->grab = grab; + interface = pointer->grab->interface; + grab->pointer = pointer; + + interface->focus (pointer->grab, pointer->current); +} + +static void +meta_wayland_pointer_reset_grab (MetaWaylandPointer *pointer) +{ + pointer->grab = &pointer->default_grab; +} + +void +meta_wayland_pointer_end_grab (MetaWaylandPointer *pointer) +{ + const MetaWaylandPointerGrabInterface *interface; + + pointer->grab = &pointer->default_grab; + interface = pointer->grab->interface; + interface->focus (pointer->grab, pointer->current); + + meta_wayland_pointer_update_cursor_surface (pointer); +} + +static void +meta_wayland_pointer_cancel_grab (MetaWaylandPointer *pointer) +{ + if (pointer->grab->interface->cancel) + pointer->grab->interface->cancel (pointer->grab); +} + +void +meta_wayland_pointer_end_popup_grab (MetaWaylandPointer *pointer) +{ + MetaWaylandPopupGrab *popup_grab = (MetaWaylandPopupGrab*)pointer->grab; + + meta_wayland_popup_grab_destroy (popup_grab); +} + +MetaWaylandPopup * +meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer, + MetaWaylandPopupSurface *popup_surface) +{ + MetaWaylandPopupGrab *grab; + + if (pointer->grab != &pointer->default_grab && + !meta_wayland_pointer_grab_is_popup_grab (pointer->grab)) + return NULL; + + if (pointer->grab == &pointer->default_grab) + grab = meta_wayland_popup_grab_create (pointer, popup_surface); + else + grab = (MetaWaylandPopupGrab*)pointer->grab; + + return meta_wayland_popup_create (popup_surface, grab); +} + +void +meta_wayland_pointer_repick (MetaWaylandPointer *pointer) +{ + clutter_input_device_update (pointer->device, NULL, FALSE); + repick_for_event (pointer, NULL); +} + +void +meta_wayland_pointer_get_relative_coordinates (MetaWaylandPointer *pointer, + MetaWaylandSurface *surface, + wl_fixed_t *sx, + wl_fixed_t *sy) +{ + float xf = 0.0f, yf = 0.0f; + graphene_point_t pos; + + clutter_input_device_get_coords (pointer->device, NULL, &pos); + meta_wayland_surface_get_relative_coordinates (surface, pos.x, pos.y, &xf, &yf); + + *sx = wl_fixed_from_double (xf); + *sy = wl_fixed_from_double (yf); +} + +void +meta_wayland_pointer_update_cursor_surface (MetaWaylandPointer *pointer) +{ + MetaBackend *backend = meta_get_backend (); + MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend); + + if (pointer->current) + { + MetaCursorSprite *cursor_sprite = NULL; + + if (pointer->cursor_surface) + { + MetaWaylandCursorSurface *cursor_surface = + META_WAYLAND_CURSOR_SURFACE (pointer->cursor_surface->role); + + cursor_sprite = meta_wayland_cursor_surface_get_sprite (cursor_surface); + } + + meta_cursor_tracker_set_window_cursor (cursor_tracker, cursor_sprite); + } + else + { + meta_cursor_tracker_unset_window_cursor (cursor_tracker); + } +} + +static void +ensure_update_cursor_surface (MetaWaylandPointer *pointer, + MetaWaylandSurface *surface) +{ + if (pointer->cursor_surface != surface) + return; + + pointer->cursor_surface = NULL; + meta_wayland_pointer_update_cursor_surface (pointer); +} + +static void +meta_wayland_pointer_set_cursor_surface (MetaWaylandPointer *pointer, + MetaWaylandSurface *cursor_surface) +{ + MetaWaylandSurface *prev_cursor_surface; + + prev_cursor_surface = pointer->cursor_surface; + + if (prev_cursor_surface == cursor_surface) + return; + + pointer->cursor_surface = cursor_surface; + + if (prev_cursor_surface) + { + meta_wayland_surface_update_outputs (prev_cursor_surface); + g_clear_signal_handler (&pointer->cursor_surface_destroy_id, + prev_cursor_surface); + } + + if (cursor_surface) + { + pointer->cursor_surface_destroy_id = + g_signal_connect_swapped (cursor_surface, "destroy", + G_CALLBACK (ensure_update_cursor_surface), + pointer); + } + + meta_wayland_pointer_update_cursor_surface (pointer); +} + +static void +pointer_set_cursor (struct wl_client *client, + struct wl_resource *resource, + uint32_t serial, + struct wl_resource *surface_resource, + int32_t hot_x, int32_t hot_y) +{ + MetaWaylandPointer *pointer = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface; + + surface = (surface_resource ? wl_resource_get_user_data (surface_resource) : NULL); + + if (pointer->focus_surface == NULL) + return; + if (wl_resource_get_client (pointer->focus_surface->resource) != client) + return; + if (pointer->focus_serial - serial > G_MAXUINT32 / 2) + return; + + if (surface && + !meta_wayland_surface_assign_role (surface, + META_TYPE_WAYLAND_CURSOR_SURFACE, + NULL)) + { + wl_resource_post_error (resource, WL_POINTER_ERROR_ROLE, + "wl_surface@%d already has a different role", + wl_resource_get_id (surface_resource)); + return; + } + + if (surface) + { + MetaCursorRenderer *cursor_renderer = + meta_backend_get_cursor_renderer (meta_get_backend ()); + MetaWaylandCursorSurface *cursor_surface; + + cursor_surface = META_WAYLAND_CURSOR_SURFACE (surface->role); + meta_wayland_cursor_surface_set_renderer (cursor_surface, + cursor_renderer); + meta_wayland_cursor_surface_set_hotspot (cursor_surface, + hot_x, hot_y); + } + + meta_wayland_pointer_set_cursor_surface (pointer, surface); +} + +static void +pointer_release (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static const struct wl_pointer_interface pointer_interface = { + pointer_set_cursor, + pointer_release, +}; + +void +meta_wayland_pointer_create_new_resource (MetaWaylandPointer *pointer, + struct wl_client *client, + struct wl_resource *seat_resource, + uint32_t id) +{ + struct wl_resource *resource; + MetaWaylandPointerClient *pointer_client; + + resource = wl_resource_create (client, &wl_pointer_interface, + wl_resource_get_version (seat_resource), id); + wl_resource_set_implementation (resource, &pointer_interface, pointer, + meta_wayland_pointer_unbind_pointer_client_resource); + + pointer_client = meta_wayland_pointer_ensure_pointer_client (pointer, client); + + wl_list_insert (&pointer_client->pointer_resources, + wl_resource_get_link (resource)); + + if (pointer->focus_client == pointer_client) + { + meta_wayland_pointer_send_enter (pointer, resource, + pointer->focus_serial, + pointer->focus_surface); + meta_wayland_pointer_send_frame (pointer, resource); + } +} + +static gboolean +pointer_can_grab_surface (MetaWaylandPointer *pointer, + MetaWaylandSurface *surface) +{ + MetaWaylandSurface *subsurface; + + if (pointer->focus_surface == surface) + return TRUE; + + META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (surface, subsurface) + { + if (pointer_can_grab_surface (pointer, subsurface)) + return TRUE; + } + + return FALSE; +} + +gboolean +meta_wayland_pointer_can_grab_surface (MetaWaylandPointer *pointer, + MetaWaylandSurface *surface, + uint32_t serial) +{ + return (pointer->grab_serial == serial && + pointer_can_grab_surface (pointer, surface)); +} + +gboolean +meta_wayland_pointer_can_popup (MetaWaylandPointer *pointer, uint32_t serial) +{ + return pointer->grab_serial == serial; +} + +MetaWaylandSurface * +meta_wayland_pointer_get_top_popup (MetaWaylandPointer *pointer) +{ + MetaWaylandPopupGrab *grab; + + if (!meta_wayland_pointer_grab_is_popup_grab (pointer->grab)) + return NULL; + + grab = (MetaWaylandPopupGrab*)pointer->grab; + return meta_wayland_popup_grab_get_top_popup(grab); +} + +static void +relative_pointer_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static const struct zwp_relative_pointer_v1_interface relative_pointer_interface = { + relative_pointer_destroy +}; + +static void +relative_pointer_manager_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +relative_pointer_manager_get_relative_pointer (struct wl_client *client, + struct wl_resource *manager_resource, + uint32_t id, + struct wl_resource *pointer_resource) +{ + MetaWaylandPointer *pointer = wl_resource_get_user_data (pointer_resource); + struct wl_resource *resource; + MetaWaylandPointerClient *pointer_client; + + resource = wl_resource_create (client, &zwp_relative_pointer_v1_interface, + wl_resource_get_version (manager_resource), + id); + if (!resource) + { + wl_client_post_no_memory (client); + return; + } + + wl_resource_set_implementation (resource, &relative_pointer_interface, + pointer, + meta_wayland_pointer_unbind_pointer_client_resource); + + pointer_client = meta_wayland_pointer_ensure_pointer_client (pointer, client); + + wl_list_insert (&pointer_client->relative_pointer_resources, + wl_resource_get_link (resource)); +} + +static const struct zwp_relative_pointer_manager_v1_interface relative_pointer_manager = { + relative_pointer_manager_destroy, + relative_pointer_manager_get_relative_pointer, +}; + +static void +bind_relative_pointer_manager (struct wl_client *client, + void *data, + uint32_t version, + uint32_t id) +{ + MetaWaylandCompositor *compositor = data; + struct wl_resource *resource; + + resource = wl_resource_create (client, + &zwp_relative_pointer_manager_v1_interface, + 1, id); + + if (version != 1) + wl_resource_post_error (resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "bound invalid version %u of " + "wp_relative_pointer_manager", + version); + + wl_resource_set_implementation (resource, &relative_pointer_manager, + compositor, + NULL); +} + +void +meta_wayland_relative_pointer_init (MetaWaylandCompositor *compositor) +{ + /* Relative pointer events are currently only supported by the native backend + * so lets just advertise the extension when the native backend is used. + */ +#ifdef HAVE_NATIVE_BACKEND + if (!META_IS_BACKEND_NATIVE (meta_get_backend ())) + return; +#else + return; +#endif + + if (!wl_global_create (compositor->wayland_display, + &zwp_relative_pointer_manager_v1_interface, 1, + compositor, bind_relative_pointer_manager)) + g_error ("Could not create relative pointer manager global"); +} + +MetaWaylandSeat * +meta_wayland_pointer_get_seat (MetaWaylandPointer *pointer) +{ + MetaWaylandInputDevice *input_device = META_WAYLAND_INPUT_DEVICE (pointer); + + return meta_wayland_input_device_get_seat (input_device); +} + +static void +meta_wayland_pointer_init (MetaWaylandPointer *pointer) +{ + pointer->default_grab.interface = &default_pointer_grab_interface; + pointer->default_grab.pointer = pointer; + pointer->grab = &pointer->default_grab; +} + +static void +meta_wayland_pointer_class_init (MetaWaylandPointerClass *klass) +{ + signals[FOCUS_SURFACE_CHANGED] = g_signal_new ("focus-surface-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); +} diff --git a/src/wayland/meta-wayland-pointer.h b/src/wayland/meta-wayland-pointer.h new file mode 100644 index 000000000..529177b8c --- /dev/null +++ b/src/wayland/meta-wayland-pointer.h @@ -0,0 +1,160 @@ +/* + * Wayland Support + * + * Copyright (C) 2013 Intel Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef META_WAYLAND_POINTER_H +#define META_WAYLAND_POINTER_H + +#include <glib.h> +#include <wayland-server.h> + +#include "meta/meta-cursor-tracker.h" +#include "wayland/meta-wayland-pointer-constraints.h" +#include "wayland/meta-wayland-pointer-gesture-pinch.h" +#include "wayland/meta-wayland-pointer-gesture-swipe.h" +#include "wayland/meta-wayland-seat.h" +#include "wayland/meta-wayland-surface.h" +#include "wayland/meta-wayland-types.h" + +#define META_TYPE_WAYLAND_POINTER (meta_wayland_pointer_get_type ()) +G_DECLARE_FINAL_TYPE (MetaWaylandPointer, meta_wayland_pointer, + META, WAYLAND_POINTER, + MetaWaylandInputDevice) + +struct _MetaWaylandPointerGrabInterface +{ + void (*focus) (MetaWaylandPointerGrab *grab, + MetaWaylandSurface *surface); + void (*motion) (MetaWaylandPointerGrab *grab, + const ClutterEvent *event); + void (*button) (MetaWaylandPointerGrab *grab, + const ClutterEvent *event); + void (*cancel) (MetaWaylandPointerGrab *grab); +}; + +struct _MetaWaylandPointerGrab +{ + const MetaWaylandPointerGrabInterface *interface; + MetaWaylandPointer *pointer; +}; + +struct _MetaWaylandPointerClient +{ + struct wl_list pointer_resources; + struct wl_list swipe_gesture_resources; + struct wl_list pinch_gesture_resources; + struct wl_list relative_pointer_resources; +}; + +struct _MetaWaylandPointer +{ + MetaWaylandInputDevice parent; + + MetaWaylandPointerClient *focus_client; + GHashTable *pointer_clients; + + MetaWaylandSurface *focus_surface; + gulong focus_surface_destroyed_handler_id; + guint32 focus_serial; + guint32 click_serial; + + MetaWaylandSurface *cursor_surface; + gulong cursor_surface_destroy_id; + + MetaWaylandPointerGrab *grab; + MetaWaylandPointerGrab default_grab; + guint32 grab_button; + guint32 grab_serial; + guint32 grab_time; + float grab_x, grab_y; + + ClutterInputDevice *device; + MetaWaylandSurface *current; + gulong current_surface_destroyed_handler_id; + + guint32 button_count; +}; + +void meta_wayland_pointer_enable (MetaWaylandPointer *pointer); + +void meta_wayland_pointer_disable (MetaWaylandPointer *pointer); + +void meta_wayland_pointer_update (MetaWaylandPointer *pointer, + const ClutterEvent *event); + +gboolean meta_wayland_pointer_handle_event (MetaWaylandPointer *pointer, + const ClutterEvent *event); + +void meta_wayland_pointer_send_motion (MetaWaylandPointer *pointer, + const ClutterEvent *event); + +void meta_wayland_pointer_send_relative_motion (MetaWaylandPointer *pointer, + const ClutterEvent *event); + +void meta_wayland_pointer_send_button (MetaWaylandPointer *pointer, + const ClutterEvent *event); + +void meta_wayland_pointer_broadcast_frame (MetaWaylandPointer *pointer); + +void meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, + MetaWaylandSurface *surface); + +void meta_wayland_pointer_start_grab (MetaWaylandPointer *pointer, + MetaWaylandPointerGrab *grab); + +void meta_wayland_pointer_end_grab (MetaWaylandPointer *pointer); + +MetaWaylandPopup *meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer, + MetaWaylandPopupSurface *popup_surface); + +void meta_wayland_pointer_end_popup_grab (MetaWaylandPointer *pointer); + +void meta_wayland_pointer_repick (MetaWaylandPointer *pointer); + +void meta_wayland_pointer_get_relative_coordinates (MetaWaylandPointer *pointer, + MetaWaylandSurface *surface, + wl_fixed_t *x, + wl_fixed_t *y); + +void meta_wayland_pointer_create_new_resource (MetaWaylandPointer *pointer, + struct wl_client *client, + struct wl_resource *seat_resource, + uint32_t id); + +gboolean meta_wayland_pointer_can_grab_surface (MetaWaylandPointer *pointer, + MetaWaylandSurface *surface, + uint32_t serial); + +gboolean meta_wayland_pointer_can_popup (MetaWaylandPointer *pointer, + uint32_t serial); + +MetaWaylandSurface *meta_wayland_pointer_get_top_popup (MetaWaylandPointer *pointer); + +MetaWaylandPointerClient * meta_wayland_pointer_get_pointer_client (MetaWaylandPointer *pointer, + struct wl_client *client); +void meta_wayland_pointer_unbind_pointer_client_resource (struct wl_resource *resource); + +void meta_wayland_relative_pointer_init (MetaWaylandCompositor *compositor); + +MetaWaylandSeat *meta_wayland_pointer_get_seat (MetaWaylandPointer *pointer); + +void meta_wayland_surface_cursor_update (MetaWaylandSurface *cursor_surface); + +void meta_wayland_pointer_update_cursor_surface (MetaWaylandPointer *pointer); + +#endif /* META_WAYLAND_POINTER_H */ diff --git a/src/wayland/meta-wayland-popup.c b/src/wayland/meta-wayland-popup.c new file mode 100644 index 000000000..f628ef04c --- /dev/null +++ b/src/wayland/meta-wayland-popup.c @@ -0,0 +1,307 @@ +/* + * Wayland Support + * + * Copyright (C) 2013 Intel Corporation + * Copyright (C) 2015 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * Copyright © 2008 Kristian Høgsberg + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "config.h" + +#include "wayland/meta-wayland-popup.h" + +#include "wayland/meta-wayland-pointer.h" +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-wayland-surface.h" + +G_DEFINE_INTERFACE (MetaWaylandPopupSurface, meta_wayland_popup_surface, + G_TYPE_OBJECT); + +struct _MetaWaylandPopupGrab +{ + MetaWaylandPointerGrab generic; + + struct wl_client *grab_client; + struct wl_list all_popups; +}; + +struct _MetaWaylandPopup +{ + MetaWaylandPopupGrab *grab; + MetaWaylandPopupSurface *popup_surface; + struct wl_list link; +}; + +static void +meta_wayland_popup_grab_begin (MetaWaylandPopupGrab *grab, + MetaWaylandSurface *surface); + +static void +meta_wayland_popup_grab_end (MetaWaylandPopupGrab *grab); + +static void +meta_wayland_popup_surface_default_init (MetaWaylandPopupSurfaceInterface *iface) +{ +} + +static void +meta_wayland_popup_surface_done (MetaWaylandPopupSurface *popup_surface) +{ + META_WAYLAND_POPUP_SURFACE_GET_IFACE (popup_surface)->done (popup_surface); +} + +static void +meta_wayland_popup_surface_dismiss (MetaWaylandPopupSurface *popup_surface) +{ + META_WAYLAND_POPUP_SURFACE_GET_IFACE (popup_surface)->dismiss (popup_surface); +} + +static MetaWaylandSurface * +meta_wayland_popup_surface_get_surface (MetaWaylandPopupSurface *popup_surface) +{ + return META_WAYLAND_POPUP_SURFACE_GET_IFACE (popup_surface)->get_surface (popup_surface); +} + +static void +popup_grab_focus (MetaWaylandPointerGrab *grab, + MetaWaylandSurface *surface) +{ + MetaWaylandPopupGrab *popup_grab = (MetaWaylandPopupGrab*)grab; + MetaWaylandSeat *seat = meta_wayland_pointer_get_seat (grab->pointer); + + /* + * We rely on having a pointer grab even when the seat doesn't have + * the pointer capability. In this case, we shouldn't update any pointer focus + * since there is no such thing when the seat doesn't have the pointer + * capability. + */ + if (!meta_wayland_seat_has_pointer (seat)) + return; + + /* Popup grabs are in owner-events mode (ie, events for the same client + are reported as normal) */ + if (surface && + wl_resource_get_client (surface->resource) == popup_grab->grab_client) + meta_wayland_pointer_set_focus (grab->pointer, surface); + else + meta_wayland_pointer_set_focus (grab->pointer, NULL); +} + +static void +popup_grab_motion (MetaWaylandPointerGrab *grab, + const ClutterEvent *event) +{ + meta_wayland_pointer_send_motion (grab->pointer, event); +} + +static void +popup_grab_button (MetaWaylandPointerGrab *grab, + const ClutterEvent *event) +{ + MetaWaylandPointer *pointer = grab->pointer; + + if (pointer->focus_surface) + meta_wayland_pointer_send_button (grab->pointer, event); + else if (clutter_event_type (event) == CLUTTER_BUTTON_RELEASE && + pointer->button_count == 0) + meta_wayland_pointer_end_popup_grab (grab->pointer); +} + +static void +popup_grab_cancel (MetaWaylandPointerGrab *grab) +{ + meta_wayland_pointer_end_popup_grab (grab->pointer); +} + +static MetaWaylandPointerGrabInterface popup_grab_interface = { + popup_grab_focus, + popup_grab_motion, + popup_grab_button, + popup_grab_cancel +}; + +MetaWaylandPopupGrab * +meta_wayland_popup_grab_create (MetaWaylandPointer *pointer, + MetaWaylandPopupSurface *popup_surface) +{ + MetaWaylandSurface *surface = + meta_wayland_popup_surface_get_surface (popup_surface); + struct wl_client *client = wl_resource_get_client (surface->resource); + MetaWaylandPopupGrab *grab; + + grab = g_slice_new0 (MetaWaylandPopupGrab); + grab->generic.interface = &popup_grab_interface; + grab->generic.pointer = pointer; + grab->grab_client = client; + wl_list_init (&grab->all_popups); + + meta_wayland_popup_grab_begin (grab, surface); + + return grab; +} + +void +meta_wayland_popup_grab_destroy (MetaWaylandPopupGrab *grab) +{ + meta_wayland_popup_grab_end (grab); + g_slice_free (MetaWaylandPopupGrab, grab); +} + +static void +meta_wayland_popup_grab_begin (MetaWaylandPopupGrab *grab, + MetaWaylandSurface *surface) +{ + MetaWaylandPointer *pointer = grab->generic.pointer; + MetaWindow *window = meta_wayland_surface_get_window (surface); + + meta_wayland_pointer_start_grab (pointer, (MetaWaylandPointerGrab*)grab); + meta_display_begin_grab_op (window->display, + window, + META_GRAB_OP_WAYLAND_POPUP, + FALSE, /* pointer_already_grabbed */ + FALSE, /* frame_action */ + 1, /* button. XXX? */ + 0, /* modmask */ + meta_display_get_current_time_roundtrip ( + window->display), + pointer->grab_x, + pointer->grab_y); +} + +void +meta_wayland_popup_grab_end (MetaWaylandPopupGrab *grab) +{ + MetaWaylandPopup *popup, *tmp; + + g_assert (grab->generic.interface == &popup_grab_interface); + + wl_list_for_each_safe (popup, tmp, &grab->all_popups, link) + { + meta_wayland_popup_surface_done (popup->popup_surface); + meta_wayland_popup_destroy (popup); + } + + { + MetaDisplay *display = meta_get_display (); + meta_display_end_grab_op (display, + meta_display_get_current_time_roundtrip (display)); + } + + meta_wayland_pointer_end_grab (grab->generic.pointer); +} + +MetaWaylandSurface * +meta_wayland_popup_grab_get_top_popup (MetaWaylandPopupGrab *grab) +{ + MetaWaylandPopup *popup; + + g_assert (!wl_list_empty (&grab->all_popups)); + popup = wl_container_of (grab->all_popups.next, popup, link); + + return meta_wayland_popup_surface_get_surface (popup->popup_surface); +} + +gboolean +meta_wayland_pointer_grab_is_popup_grab (MetaWaylandPointerGrab *grab) +{ + return grab->interface == &popup_grab_interface; +} + +void +meta_wayland_popup_destroy (MetaWaylandPopup *popup) +{ + meta_wayland_popup_surface_dismiss (popup->popup_surface); + + wl_list_remove (&popup->link); + g_slice_free (MetaWaylandPopup, popup); +} + +void +meta_wayland_popup_dismiss (MetaWaylandPopup *popup) +{ + MetaWaylandPopupGrab *popup_grab = popup->grab; + + meta_wayland_popup_destroy (popup); + + if (wl_list_empty (&popup_grab->all_popups)) + { + meta_wayland_pointer_end_popup_grab (popup_grab->generic.pointer); + } + else + { + MetaWaylandSurface *top_popup_surface; + MetaWaylandSeat *seat; + + top_popup_surface = meta_wayland_popup_grab_get_top_popup (popup_grab); + seat = meta_wayland_pointer_get_seat (popup_grab->generic.pointer); + + if (meta_wayland_seat_has_keyboard (seat)) + meta_wayland_keyboard_set_focus (seat->keyboard, top_popup_surface); + } +} + +MetaWaylandSurface * +meta_wayland_popup_get_top_popup (MetaWaylandPopup *popup) +{ + return meta_wayland_popup_grab_get_top_popup (popup->grab); +} + +MetaWaylandPopup * +meta_wayland_popup_create (MetaWaylandPopupSurface *popup_surface, + MetaWaylandPopupGrab *grab) +{ + MetaWaylandSurface *surface = + meta_wayland_popup_surface_get_surface (popup_surface); + MetaWaylandPopup *popup; + MetaWaylandSeat *seat; + + /* Don't allow creating popups if the grab has a different client. */ + if (grab->grab_client != wl_resource_get_client (surface->resource)) + return NULL; + + popup = g_slice_new0 (MetaWaylandPopup); + popup->grab = grab; + popup->popup_surface = popup_surface; + + wl_list_insert (&grab->all_popups, &popup->link); + + seat = meta_wayland_pointer_get_seat (grab->generic.pointer); + if (meta_wayland_seat_has_keyboard (seat)) + meta_wayland_keyboard_set_focus (seat->keyboard, surface); + + return popup; +} diff --git a/src/wayland/meta-wayland-popup.h b/src/wayland/meta-wayland-popup.h new file mode 100644 index 000000000..3cc90e22a --- /dev/null +++ b/src/wayland/meta-wayland-popup.h @@ -0,0 +1,62 @@ +/* + * Wayland Support + * + * Copyright (C) 2013 Intel Corporation + * Copyright (C) 2015 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef META_WAYLAND_POPUP_H +#define META_WAYLAND_POPUP_H + +#include <glib.h> +#include <wayland-server.h> + +#include "wayland/meta-wayland-types.h" +#include "wayland/meta-wayland-pointer.h" + +#define META_TYPE_WAYLAND_POPUP_SURFACE (meta_wayland_popup_surface_get_type ()) +G_DECLARE_INTERFACE (MetaWaylandPopupSurface, meta_wayland_popup_surface, + META, WAYLAND_POPUP_SURFACE, + GObject); + +struct _MetaWaylandPopupSurfaceInterface +{ + GTypeInterface parent_iface; + + void (*done) (MetaWaylandPopupSurface *popup_surface); + void (*dismiss) (MetaWaylandPopupSurface *popup_surface); + MetaWaylandSurface *(*get_surface) (MetaWaylandPopupSurface *popup_surface); +}; + +MetaWaylandPopupGrab *meta_wayland_popup_grab_create (MetaWaylandPointer *pointer, + MetaWaylandPopupSurface *popup_surface); + +void meta_wayland_popup_grab_destroy (MetaWaylandPopupGrab *grab); + +MetaWaylandSurface *meta_wayland_popup_grab_get_top_popup (MetaWaylandPopupGrab *grab); + +gboolean meta_wayland_pointer_grab_is_popup_grab (MetaWaylandPointerGrab *grab); + +MetaWaylandPopup *meta_wayland_popup_create (MetaWaylandPopupSurface *surface, + MetaWaylandPopupGrab *grab); + +void meta_wayland_popup_destroy (MetaWaylandPopup *popup); + +void meta_wayland_popup_dismiss (MetaWaylandPopup *popup); + +MetaWaylandSurface *meta_wayland_popup_get_top_popup (MetaWaylandPopup *popup); + +#endif /* META_WAYLAND_POPUP_H */ diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h new file mode 100644 index 000000000..727009b07 --- /dev/null +++ b/src/wayland/meta-wayland-private.h @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2012 Intel Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_WAYLAND_PRIVATE_H +#define META_WAYLAND_PRIVATE_H + +#include <glib.h> +#include <wayland-server.h> + +#include "clutter/clutter.h" +#include "core/window-private.h" +#include "meta/meta-cursor-tracker.h" +#include "wayland/meta-wayland-pointer-gestures.h" +#include "wayland/meta-wayland-seat.h" +#include "wayland/meta-wayland-surface.h" +#include "wayland/meta-wayland-tablet-manager.h" +#include "wayland/meta-wayland-versions.h" +#include "wayland/meta-wayland.h" + +typedef struct _MetaXWaylandDnd MetaXWaylandDnd; + +typedef struct +{ + struct wl_list link; + struct wl_resource *resource; + MetaWaylandSurface *surface; +} MetaWaylandFrameCallback; + +typedef struct +{ + int display_index; + char *lock_file; + int abstract_fd; + int unix_fd; + char *name; +} MetaXWaylandConnection; + +typedef struct +{ + MetaXWaylandConnection private_connection; + MetaXWaylandConnection public_connection; + + guint xserver_grace_period_id; + struct wl_display *wayland_display; + struct wl_client *client; + struct wl_resource *xserver_resource; + char *auth_file; + + GCancellable *xserver_died_cancellable; + GSubprocess *proc; + + GList *x11_windows; + + MetaXWaylandDnd *dnd; +} MetaXWaylandManager; + +struct _MetaWaylandCompositor +{ + GObject parent; + + MetaBackend *backend; + + struct wl_display *wayland_display; + char *display_name; + GHashTable *outputs; + GList *frame_callback_surfaces; + + MetaXWaylandManager xwayland_manager; + + MetaWaylandSeat *seat; + MetaWaylandTabletManager *tablet_manager; + + GHashTable *scheduled_surface_associations; +}; + +#define META_TYPE_WAYLAND_COMPOSITOR (meta_wayland_compositor_get_type ()) +G_DECLARE_FINAL_TYPE (MetaWaylandCompositor, meta_wayland_compositor, + META, WAYLAND_COMPOSITOR, GObject) + +#endif /* META_WAYLAND_PRIVATE_H */ diff --git a/src/wayland/meta-wayland-region.c b/src/wayland/meta-wayland-region.c new file mode 100644 index 000000000..761b97c13 --- /dev/null +++ b/src/wayland/meta-wayland-region.c @@ -0,0 +1,105 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Endless Mobile + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jasper St. Pierre <jstpierre@mecheye.net> + */ + +#include "config.h" + +#include "wayland/meta-wayland-region.h" + +struct _MetaWaylandRegion +{ + struct wl_resource *resource; + cairo_region_t *region; +}; + +static void +wl_region_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +wl_region_add (struct wl_client *client, + struct wl_resource *resource, + gint32 x, + gint32 y, + gint32 width, + gint32 height) +{ + MetaWaylandRegion *region = wl_resource_get_user_data (resource); + cairo_rectangle_int_t rectangle = { x, y, width, height }; + + cairo_region_union_rectangle (region->region, &rectangle); +} + +static void +wl_region_subtract (struct wl_client *client, + struct wl_resource *resource, + gint32 x, + gint32 y, + gint32 width, + gint32 height) +{ + MetaWaylandRegion *region = wl_resource_get_user_data (resource); + cairo_rectangle_int_t rectangle = { x, y, width, height }; + + cairo_region_subtract_rectangle (region->region, &rectangle); +} + +static const struct wl_region_interface meta_wayland_wl_region_interface = { + wl_region_destroy, + wl_region_add, + wl_region_subtract +}; + +static void +wl_region_destructor (struct wl_resource *resource) +{ + MetaWaylandRegion *region = wl_resource_get_user_data (resource); + + cairo_region_destroy (region->region); + g_slice_free (MetaWaylandRegion, region); +} + +MetaWaylandRegion * +meta_wayland_region_create (MetaWaylandCompositor *compositor, + struct wl_client *client, + struct wl_resource *compositor_resource, + guint32 id) +{ + MetaWaylandRegion *region = g_slice_new0 (MetaWaylandRegion); + + region->resource = wl_resource_create (client, &wl_region_interface, wl_resource_get_version (compositor_resource), id); + wl_resource_set_implementation (region->resource, &meta_wayland_wl_region_interface, region, wl_region_destructor); + + region->region = cairo_region_create (); + + return region; +} + +cairo_region_t * +meta_wayland_region_peek_cairo_region (MetaWaylandRegion *region) +{ + return region->region; +} diff --git a/src/wayland/meta-wayland-region.h b/src/wayland/meta-wayland-region.h new file mode 100644 index 000000000..201580a67 --- /dev/null +++ b/src/wayland/meta-wayland-region.h @@ -0,0 +1,41 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Endless Mobile + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jasper St. Pierre <jstpierre@mecheye.net> + */ + +#ifndef META_WAYLAND_REGION_H +#define META_WAYLAND_REGION_H + +#include <cairo.h> +#include <glib.h> +#include <wayland-server.h> + +#include "wayland/meta-wayland-types.h" + +MetaWaylandRegion * meta_wayland_region_create (MetaWaylandCompositor *compositor, + struct wl_client *client, + struct wl_resource *compositor_resource, + guint32 id); + +cairo_region_t * meta_wayland_region_peek_cairo_region (MetaWaylandRegion *region); + +#endif /* META_WAYLAND_REGION_H */ diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c new file mode 100644 index 000000000..10dbc4e97 --- /dev/null +++ b/src/wayland/meta-wayland-seat.c @@ -0,0 +1,561 @@ +/* + * Wayland Support + * + * Copyright (C) 2013 Intel Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "wayland/meta-wayland-seat.h" + +#include "wayland/meta-wayland-data-device.h" +#include "wayland/meta-wayland-data-device-primary-legacy.h" +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-wayland-tablet-seat.h" +#include "wayland/meta-wayland-versions.h" + +#define CAPABILITY_ENABLED(prev, cur, capability) ((cur & (capability)) && !(prev & (capability))) +#define CAPABILITY_DISABLED(prev, cur, capability) ((prev & (capability)) && !(cur & (capability))) + +static void +unbind_resource (struct wl_resource *resource) +{ + wl_list_remove (wl_resource_get_link (resource)); +} + +static void +seat_get_pointer (struct wl_client *client, + struct wl_resource *resource, + uint32_t id) +{ + MetaWaylandSeat *seat = wl_resource_get_user_data (resource); + MetaWaylandPointer *pointer = seat->pointer; + + if (meta_wayland_seat_has_pointer (seat)) + meta_wayland_pointer_create_new_resource (pointer, client, resource, id); +} + +static void +seat_get_keyboard (struct wl_client *client, + struct wl_resource *resource, + uint32_t id) +{ + MetaWaylandSeat *seat = wl_resource_get_user_data (resource); + MetaWaylandKeyboard *keyboard = seat->keyboard; + + if (meta_wayland_seat_has_keyboard (seat)) + meta_wayland_keyboard_create_new_resource (keyboard, client, resource, id); +} + +static void +seat_get_touch (struct wl_client *client, + struct wl_resource *resource, + uint32_t id) +{ + MetaWaylandSeat *seat = wl_resource_get_user_data (resource); + MetaWaylandTouch *touch = seat->touch; + + if (meta_wayland_seat_has_touch (seat)) + meta_wayland_touch_create_new_resource (touch, client, resource, id); +} + +static void +seat_release (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static const struct wl_seat_interface seat_interface = { + seat_get_pointer, + seat_get_keyboard, + seat_get_touch, + seat_release +}; + +static void +bind_seat (struct wl_client *client, + void *data, + guint32 version, + guint32 id) +{ + MetaWaylandSeat *seat = data; + struct wl_resource *resource; + + resource = wl_resource_create (client, &wl_seat_interface, version, id); + wl_resource_set_implementation (resource, &seat_interface, seat, unbind_resource); + wl_list_insert (&seat->base_resource_list, wl_resource_get_link (resource)); + + wl_seat_send_capabilities (resource, seat->capabilities); + + if (version >= WL_SEAT_NAME_SINCE_VERSION) + wl_seat_send_name (resource, "seat0"); +} + +static uint32_t +lookup_device_capabilities (ClutterSeat *seat) +{ + GList *devices, *l; + uint32_t capabilities = 0; + + devices = clutter_seat_list_devices (seat); + + for (l = devices; l; l = l->next) + { + ClutterInputDeviceType device_type; + + /* Only look for physical devices, master devices have rather generic + * keyboard/pointer device types, which is not truly representative of + * the slave devices connected to them. + */ + if (clutter_input_device_get_device_mode (l->data) == CLUTTER_INPUT_MODE_MASTER) + continue; + + device_type = clutter_input_device_get_device_type (l->data); + + switch (device_type) + { + case CLUTTER_TOUCHPAD_DEVICE: + case CLUTTER_POINTER_DEVICE: + capabilities |= WL_SEAT_CAPABILITY_POINTER; + break; + case CLUTTER_KEYBOARD_DEVICE: + capabilities |= WL_SEAT_CAPABILITY_KEYBOARD; + break; + case CLUTTER_TOUCHSCREEN_DEVICE: + capabilities |= WL_SEAT_CAPABILITY_TOUCH; + break; + default: + g_debug ("Ignoring device '%s' with unhandled type %d", + clutter_input_device_get_device_name (l->data), + device_type); + break; + } + } + + g_list_free (devices); + + return capabilities; +} + +static void +meta_wayland_seat_set_capabilities (MetaWaylandSeat *seat, + uint32_t flags) +{ + struct wl_resource *resource; + uint32_t prev_flags; + + prev_flags = seat->capabilities; + + if (prev_flags == flags) + return; + + seat->capabilities = flags; + + if (CAPABILITY_ENABLED (prev_flags, flags, WL_SEAT_CAPABILITY_POINTER)) + meta_wayland_pointer_enable (seat->pointer); + else if (CAPABILITY_DISABLED (prev_flags, flags, WL_SEAT_CAPABILITY_POINTER)) + meta_wayland_pointer_disable (seat->pointer); + + if (CAPABILITY_ENABLED (prev_flags, flags, WL_SEAT_CAPABILITY_KEYBOARD)) + { + MetaDisplay *display; + + meta_wayland_keyboard_enable (seat->keyboard); + display = meta_get_display (); + + /* Post-initialization, ensure the input focus is in sync */ + if (display) + meta_display_sync_wayland_input_focus (display); + } + else if (CAPABILITY_DISABLED (prev_flags, flags, WL_SEAT_CAPABILITY_KEYBOARD)) + meta_wayland_keyboard_disable (seat->keyboard); + + if (CAPABILITY_ENABLED (prev_flags, flags, WL_SEAT_CAPABILITY_TOUCH)) + meta_wayland_touch_enable (seat->touch); + else if (CAPABILITY_DISABLED (prev_flags, flags, WL_SEAT_CAPABILITY_TOUCH)) + meta_wayland_touch_disable (seat->touch); + + /* Broadcast capability changes */ + wl_resource_for_each (resource, &seat->base_resource_list) + { + wl_seat_send_capabilities (resource, flags); + } +} + +static void +meta_wayland_seat_update_capabilities (MetaWaylandSeat *seat, + ClutterSeat *clutter_seat) +{ + uint32_t capabilities; + + capabilities = lookup_device_capabilities (clutter_seat); + meta_wayland_seat_set_capabilities (seat, capabilities); +} + +static void +meta_wayland_seat_devices_updated (ClutterSeat *clutter_seat, + ClutterInputDevice *input_device, + MetaWaylandSeat *seat) +{ + meta_wayland_seat_update_capabilities (seat, clutter_seat); +} + +static MetaWaylandSeat * +meta_wayland_seat_new (MetaWaylandCompositor *compositor, + struct wl_display *display) +{ + MetaWaylandSeat *seat = g_new0 (MetaWaylandSeat, 1); + ClutterSeat *clutter_seat; + + wl_list_init (&seat->base_resource_list); + seat->wl_display = display; + + seat->pointer = g_object_new (META_TYPE_WAYLAND_POINTER, + "seat", seat, + NULL); + seat->keyboard = g_object_new (META_TYPE_WAYLAND_KEYBOARD, + "seat", seat, + NULL); + seat->touch = g_object_new (META_TYPE_WAYLAND_TOUCH, + "seat", seat, + NULL); + + seat->text_input = meta_wayland_text_input_new (seat); + seat->gtk_text_input = meta_wayland_gtk_text_input_new (seat); + + meta_wayland_data_device_init (&seat->data_device); + meta_wayland_data_device_primary_init (&seat->primary_data_device); + meta_wayland_data_device_primary_legacy_init (&seat->primary_legacy_data_device); + + clutter_seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); + meta_wayland_seat_update_capabilities (seat, clutter_seat); + g_signal_connect (clutter_seat, "device-added", + G_CALLBACK (meta_wayland_seat_devices_updated), seat); + g_signal_connect (clutter_seat, "device-removed", + G_CALLBACK (meta_wayland_seat_devices_updated), seat); + + wl_global_create (display, &wl_seat_interface, META_WL_SEAT_VERSION, seat, bind_seat); + + meta_wayland_tablet_manager_ensure_seat (compositor->tablet_manager, seat); + + return seat; +} + +void +meta_wayland_seat_init (MetaWaylandCompositor *compositor) +{ + compositor->seat = meta_wayland_seat_new (compositor, + compositor->wayland_display); +} + +void +meta_wayland_seat_free (MetaWaylandSeat *seat) +{ + ClutterSeat *clutter_seat; + + clutter_seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); + g_signal_handlers_disconnect_by_data (clutter_seat, seat); + meta_wayland_seat_set_capabilities (seat, 0); + + g_object_unref (seat->pointer); + g_object_unref (seat->keyboard); + g_object_unref (seat->touch); + meta_wayland_gtk_text_input_destroy (seat->gtk_text_input); + meta_wayland_text_input_destroy (seat->text_input); + + g_free (seat); +} + +static gboolean +event_is_synthesized_crossing (const ClutterEvent *event) +{ + ClutterInputDevice *device; + + if (event->type != CLUTTER_ENTER && event->type != CLUTTER_LEAVE) + return FALSE; + + device = clutter_event_get_source_device (event); + return clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER; +} + +static gboolean +event_from_supported_hardware_device (MetaWaylandSeat *seat, + const ClutterEvent *event) +{ + ClutterInputDevice *input_device; + ClutterInputMode input_mode; + ClutterInputDeviceType device_type; + gboolean hardware_device = FALSE; + gboolean supported_device = FALSE; + + input_device = clutter_event_get_source_device (event); + + if (input_device == NULL) + goto out; + + input_mode = clutter_input_device_get_device_mode (input_device); + + if (input_mode != CLUTTER_INPUT_MODE_SLAVE) + goto out; + + hardware_device = TRUE; + + device_type = clutter_input_device_get_device_type (input_device); + + switch (device_type) + { + case CLUTTER_TOUCHPAD_DEVICE: + case CLUTTER_POINTER_DEVICE: + case CLUTTER_KEYBOARD_DEVICE: + case CLUTTER_TOUCHSCREEN_DEVICE: + supported_device = TRUE; + break; + + default: + supported_device = FALSE; + break; + } + +out: + return hardware_device && supported_device; +} + +void +meta_wayland_seat_update (MetaWaylandSeat *seat, + const ClutterEvent *event) +{ + if (!(clutter_event_get_flags (event) & CLUTTER_EVENT_FLAG_INPUT_METHOD) && + !event_from_supported_hardware_device (seat, event) && + !event_is_synthesized_crossing (event)) + return; + + switch (event->type) + { + case CLUTTER_MOTION: + case CLUTTER_BUTTON_PRESS: + case CLUTTER_BUTTON_RELEASE: + case CLUTTER_SCROLL: + case CLUTTER_ENTER: + case CLUTTER_LEAVE: + if (meta_wayland_seat_has_pointer (seat)) + meta_wayland_pointer_update (seat->pointer, event); + break; + + case CLUTTER_KEY_PRESS: + case CLUTTER_KEY_RELEASE: + if (meta_wayland_seat_has_keyboard (seat)) + meta_wayland_keyboard_update (seat->keyboard, (const ClutterKeyEvent *) event); + break; + + case CLUTTER_TOUCH_BEGIN: + case CLUTTER_TOUCH_UPDATE: + case CLUTTER_TOUCH_END: + if (meta_wayland_seat_has_touch (seat)) + meta_wayland_touch_update (seat->touch, event); + break; + + default: + break; + } +} + +gboolean +meta_wayland_seat_handle_event (MetaWaylandSeat *seat, + const ClutterEvent *event) +{ + if (!(clutter_event_get_flags (event) & CLUTTER_EVENT_FLAG_INPUT_METHOD) && + !event_from_supported_hardware_device (seat, event)) + return FALSE; + + switch (event->type) + { + case CLUTTER_MOTION: + case CLUTTER_BUTTON_PRESS: + case CLUTTER_BUTTON_RELEASE: + case CLUTTER_SCROLL: + case CLUTTER_TOUCHPAD_SWIPE: + case CLUTTER_TOUCHPAD_PINCH: + if (meta_wayland_seat_has_pointer (seat)) + return meta_wayland_pointer_handle_event (seat->pointer, event); + + break; + case CLUTTER_KEY_PRESS: + case CLUTTER_KEY_RELEASE: + if (meta_wayland_text_input_handle_event (seat->text_input, event)) + return TRUE; + + if (meta_wayland_gtk_text_input_handle_event (seat->gtk_text_input, + event)) + return TRUE; + + if (meta_wayland_seat_has_keyboard (seat)) + return meta_wayland_keyboard_handle_event (seat->keyboard, + (const ClutterKeyEvent *) event); + break; + case CLUTTER_TOUCH_BEGIN: + case CLUTTER_TOUCH_UPDATE: + case CLUTTER_TOUCH_END: + if (meta_wayland_seat_has_touch (seat)) + return meta_wayland_touch_handle_event (seat->touch, event); + + break; + case CLUTTER_IM_COMMIT: + case CLUTTER_IM_DELETE: + case CLUTTER_IM_PREEDIT: + if (meta_wayland_text_input_handle_event (seat->text_input, event)) + return TRUE; + if (meta_wayland_gtk_text_input_handle_event (seat->gtk_text_input, + event)) + return TRUE; + + break; + default: + break; + } + + return FALSE; +} + +void +meta_wayland_seat_repick (MetaWaylandSeat *seat) +{ + if (!meta_wayland_seat_has_pointer (seat)) + return; + + meta_wayland_pointer_repick (seat->pointer); +} + +void +meta_wayland_seat_set_input_focus (MetaWaylandSeat *seat, + MetaWaylandSurface *surface) +{ + MetaWaylandTabletSeat *tablet_seat; + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + + if (meta_wayland_seat_has_keyboard (seat)) + { + meta_wayland_keyboard_set_focus (seat->keyboard, surface); + meta_wayland_data_device_set_keyboard_focus (&seat->data_device); + meta_wayland_data_device_primary_set_keyboard_focus (&seat->primary_data_device); + meta_wayland_data_device_primary_legacy_set_keyboard_focus (&seat->primary_legacy_data_device); + } + + tablet_seat = meta_wayland_tablet_manager_ensure_seat (compositor->tablet_manager, seat); + meta_wayland_tablet_seat_set_pad_focus (tablet_seat, surface); + + meta_wayland_text_input_set_focus (seat->text_input, surface); + meta_wayland_gtk_text_input_set_focus (seat->gtk_text_input, surface); +} + +gboolean +meta_wayland_seat_get_grab_info (MetaWaylandSeat *seat, + MetaWaylandSurface *surface, + uint32_t serial, + gboolean require_pressed, + gfloat *x, + gfloat *y) +{ + MetaWaylandCompositor *compositor; + MetaWaylandTabletSeat *tablet_seat; + GList *tools, *l; + + compositor = meta_wayland_compositor_get_default (); + tablet_seat = meta_wayland_tablet_manager_ensure_seat (compositor->tablet_manager, seat); + tools = g_hash_table_get_values (tablet_seat->tools); + + if (meta_wayland_seat_has_touch (seat)) + { + ClutterEventSequence *sequence; + sequence = meta_wayland_touch_find_grab_sequence (seat->touch, + surface, + serial); + if (sequence) + { + meta_wayland_touch_get_press_coords (seat->touch, sequence, x, y); + return TRUE; + } + } + + if (meta_wayland_seat_has_pointer (seat)) + { + if ((!require_pressed || seat->pointer->button_count > 0) && + meta_wayland_pointer_can_grab_surface (seat->pointer, surface, serial)) + { + if (x) + *x = seat->pointer->grab_x; + if (y) + *y = seat->pointer->grab_y; + + return TRUE; + } + } + + for (l = tools; l; l = l->next) + { + MetaWaylandTabletTool *tool = l->data; + + if ((!require_pressed || tool->button_count > 0) && + meta_wayland_tablet_tool_can_grab_surface (tool, surface, serial)) + { + if (x) + *x = tool->grab_x; + if (y) + *y = tool->grab_y; + + return TRUE; + } + } + + return FALSE; +} + +gboolean +meta_wayland_seat_can_popup (MetaWaylandSeat *seat, + uint32_t serial) +{ + MetaWaylandCompositor *compositor; + MetaWaylandTabletSeat *tablet_seat; + + compositor = meta_wayland_compositor_get_default (); + tablet_seat = + meta_wayland_tablet_manager_ensure_seat (compositor->tablet_manager, seat); + + return (meta_wayland_pointer_can_popup (seat->pointer, serial) || + meta_wayland_keyboard_can_popup (seat->keyboard, serial) || + meta_wayland_touch_can_popup (seat->touch, serial) || + meta_wayland_tablet_seat_can_popup (tablet_seat, serial)); +} + +gboolean +meta_wayland_seat_has_keyboard (MetaWaylandSeat *seat) +{ + return (seat->capabilities & WL_SEAT_CAPABILITY_KEYBOARD) != 0; +} + +gboolean +meta_wayland_seat_has_pointer (MetaWaylandSeat *seat) +{ + return (seat->capabilities & WL_SEAT_CAPABILITY_POINTER) != 0; +} + +gboolean +meta_wayland_seat_has_touch (MetaWaylandSeat *seat) +{ + return (seat->capabilities & WL_SEAT_CAPABILITY_TOUCH) != 0; +} diff --git a/src/wayland/meta-wayland-seat.h b/src/wayland/meta-wayland-seat.h new file mode 100644 index 000000000..f41c44207 --- /dev/null +++ b/src/wayland/meta-wayland-seat.h @@ -0,0 +1,89 @@ +/* + * Wayland Support + * + * Copyright (C) 2012 Intel Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_WAYLAND_SEAT_H +#define META_WAYLAND_SEAT_H + +#include <wayland-server.h> + +#include "clutter/clutter.h" +#include "wayland/meta-wayland-data-device.h" +#include "wayland/meta-wayland-data-device-primary.h" +#include "wayland/meta-wayland-data-device-primary-legacy.h" +#include "wayland/meta-wayland-input-device.h" +#include "wayland/meta-wayland-keyboard.h" +#include "wayland/meta-wayland-pointer.h" +#include "wayland/meta-wayland-tablet-tool.h" +#include "wayland/meta-wayland-text-input.h" +#include "wayland/meta-wayland-text-input-legacy.h" +#include "wayland/meta-wayland-touch.h" +#include "wayland/meta-wayland-types.h" + +struct _MetaWaylandSeat +{ + struct wl_list base_resource_list; + struct wl_display *wl_display; + + MetaWaylandPointer *pointer; + MetaWaylandKeyboard *keyboard; + MetaWaylandTouch *touch; + + MetaWaylandDataDevice data_device; + MetaWaylandDataDevicePrimary primary_data_device; + MetaWaylandDataDevicePrimaryLegacy primary_legacy_data_device; + + MetaWaylandGtkTextInput *gtk_text_input; + MetaWaylandTextInput *text_input; + + guint capabilities; +}; + +void meta_wayland_seat_init (MetaWaylandCompositor *compositor); + +void meta_wayland_seat_free (MetaWaylandSeat *seat); + +void meta_wayland_seat_update (MetaWaylandSeat *seat, + const ClutterEvent *event); + +gboolean meta_wayland_seat_handle_event (MetaWaylandSeat *seat, + const ClutterEvent *event); + +void meta_wayland_seat_set_input_focus (MetaWaylandSeat *seat, + MetaWaylandSurface *surface); + +void meta_wayland_seat_repick (MetaWaylandSeat *seat); + +gboolean meta_wayland_seat_get_grab_info (MetaWaylandSeat *seat, + MetaWaylandSurface *surface, + uint32_t serial, + gboolean require_pressed, + gfloat *x, + gfloat *y); +gboolean meta_wayland_seat_can_popup (MetaWaylandSeat *seat, + uint32_t serial); + +gboolean meta_wayland_seat_has_keyboard (MetaWaylandSeat *seat); + +gboolean meta_wayland_seat_has_pointer (MetaWaylandSeat *seat); + +gboolean meta_wayland_seat_has_touch (MetaWaylandSeat *seat); + +#endif /* META_WAYLAND_SEAT_H */ diff --git a/src/wayland/meta-wayland-shell-surface.c b/src/wayland/meta-wayland-shell-surface.c new file mode 100644 index 000000000..a1f5f36af --- /dev/null +++ b/src/wayland/meta-wayland-shell-surface.c @@ -0,0 +1,411 @@ +/* + * Copyright (C) 2012,2013 Intel Corporation + * Copyright (C) 2013-2017 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#include "config.h" + +#include "wayland/meta-wayland-shell-surface.h" + +#include "compositor/meta-surface-actor-wayland.h" +#include "compositor/meta-window-actor-private.h" +#include "compositor/meta-window-actor-wayland.h" +#include "wayland/meta-wayland-actor-surface.h" +#include "wayland/meta-wayland-buffer.h" +#include "wayland/meta-wayland-subsurface.h" +#include "wayland/meta-wayland-surface.h" +#include "wayland/meta-window-wayland.h" + +typedef struct _MetaWaylandShellSurfacePrivate +{ + MetaWindow *window; + + gulong unmanaging_handler_id; + gulong position_changed_handler_id; + gulong effects_completed_handler_id; +} MetaWaylandShellSurfacePrivate; + +G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaWaylandShellSurface, + meta_wayland_shell_surface, + META_TYPE_WAYLAND_ACTOR_SURFACE) + +void +meta_wayland_shell_surface_calculate_geometry (MetaWaylandShellSurface *shell_surface, + MetaRectangle *out_geometry) +{ + MetaWaylandSurfaceRole *surface_role = + META_WAYLAND_SURFACE_ROLE (shell_surface); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaRectangle geometry; + MetaWaylandSurface *subsurface_surface; + + geometry = (MetaRectangle) { + .width = meta_wayland_surface_get_width (surface), + .height = meta_wayland_surface_get_height (surface), + }; + + META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (surface, subsurface_surface) + { + MetaWaylandSubsurface *subsurface; + + subsurface = META_WAYLAND_SUBSURFACE (subsurface_surface->role); + meta_wayland_subsurface_union_geometry (subsurface, + 0, 0, + &geometry); + } + + *out_geometry = geometry; +} + +void +meta_wayland_shell_surface_determine_geometry (MetaWaylandShellSurface *shell_surface, + MetaRectangle *set_geometry, + MetaRectangle *out_geometry) +{ + MetaRectangle bounding_geometry = { 0 }; + MetaRectangle intersected_geometry = { 0 }; + + meta_wayland_shell_surface_calculate_geometry (shell_surface, + &bounding_geometry); + + meta_rectangle_intersect (set_geometry, &bounding_geometry, + &intersected_geometry); + + *out_geometry = intersected_geometry; +} + +static void +clear_window (MetaWaylandShellSurface *shell_surface) +{ + MetaWaylandShellSurfacePrivate *priv = + meta_wayland_shell_surface_get_instance_private (shell_surface); + MetaWaylandSurfaceRole *surface_role = + META_WAYLAND_SURFACE_ROLE (shell_surface); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaSurfaceActor *surface_actor; + + if (!priv->window) + return; + + g_clear_signal_handler (&priv->unmanaging_handler_id, + priv->window); + g_clear_signal_handler (&priv->position_changed_handler_id, + priv->window); + g_clear_signal_handler (&priv->effects_completed_handler_id, + meta_window_actor_from_window (priv->window)); + priv->window = NULL; + + surface_actor = meta_wayland_surface_get_actor (surface); + if (surface_actor) + clutter_actor_set_reactive (CLUTTER_ACTOR (surface_actor), FALSE); + + meta_wayland_surface_notify_unmapped (surface); +} + +static void +window_unmanaging (MetaWindow *window, + MetaWaylandShellSurface *shell_surface) +{ + clear_window (shell_surface); +} + +static void +window_position_changed (MetaWindow *window, + MetaWaylandSurface *surface) +{ + meta_wayland_surface_update_outputs_recursively (surface); +} + +static void +window_actor_effects_completed (MetaWindowActor *window_actor, + MetaWaylandSurface *surface) +{ + meta_wayland_surface_update_outputs_recursively (surface); + meta_wayland_compositor_repick (surface->compositor); +} + +void +meta_wayland_shell_surface_set_window (MetaWaylandShellSurface *shell_surface, + MetaWindow *window) +{ + MetaWaylandShellSurfacePrivate *priv = + meta_wayland_shell_surface_get_instance_private (shell_surface); + MetaWaylandSurfaceRole *surface_role = + META_WAYLAND_SURFACE_ROLE (shell_surface); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaSurfaceActor *surface_actor; + + g_assert (!priv->window); + + priv->window = window; + + surface_actor = meta_wayland_surface_get_actor (surface); + if (surface_actor) + clutter_actor_set_reactive (CLUTTER_ACTOR (surface_actor), TRUE); + + priv->unmanaging_handler_id = + g_signal_connect (window, + "unmanaging", + G_CALLBACK (window_unmanaging), + shell_surface); + priv->position_changed_handler_id = + g_signal_connect (window, + "position-changed", + G_CALLBACK (window_position_changed), + surface); + priv->effects_completed_handler_id = + g_signal_connect (meta_window_actor_from_window (window), + "effects-completed", + G_CALLBACK (window_actor_effects_completed), + surface); + + meta_window_update_monitor (window, META_WINDOW_UPDATE_MONITOR_FLAGS_NONE); +} + +void +meta_wayland_shell_surface_configure (MetaWaylandShellSurface *shell_surface, + MetaWaylandWindowConfiguration *configuration) +{ + MetaWaylandShellSurfaceClass *shell_surface_class = + META_WAYLAND_SHELL_SURFACE_GET_CLASS (shell_surface); + + shell_surface_class->configure (shell_surface, configuration); +} + +void +meta_wayland_shell_surface_ping (MetaWaylandShellSurface *shell_surface, + uint32_t serial) +{ + MetaWaylandShellSurfaceClass *shell_surface_class = + META_WAYLAND_SHELL_SURFACE_GET_CLASS (shell_surface); + + shell_surface_class->ping (shell_surface, serial); +} + +void +meta_wayland_shell_surface_close (MetaWaylandShellSurface *shell_surface) +{ + MetaWaylandShellSurfaceClass *shell_surface_class = + META_WAYLAND_SHELL_SURFACE_GET_CLASS (shell_surface); + + shell_surface_class->close (shell_surface); +} + +void +meta_wayland_shell_surface_managed (MetaWaylandShellSurface *shell_surface, + MetaWindow *window) +{ + MetaWaylandShellSurfaceClass *shell_surface_class = + META_WAYLAND_SHELL_SURFACE_GET_CLASS (shell_surface); + + shell_surface_class->managed (shell_surface, window); +} + +static void +meta_wayland_shell_surface_assigned (MetaWaylandSurfaceRole *surface_role) +{ + MetaWaylandSurfaceRoleClass *surface_role_class = + META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_shell_surface_parent_class); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + + surface->dnd.funcs = meta_wayland_data_device_get_drag_dest_funcs (); + + surface_role_class->assigned (surface_role); +} + +static void +meta_wayland_shell_surface_surface_pre_apply_state (MetaWaylandSurfaceRole *surface_role, + MetaWaylandSurfaceState *pending) +{ + MetaWaylandShellSurface *shell_surface = + META_WAYLAND_SHELL_SURFACE (surface_role); + MetaWaylandShellSurfacePrivate *priv = + meta_wayland_shell_surface_get_instance_private (shell_surface); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + + if (pending->newly_attached && + !surface->buffer_ref.buffer && + priv->window) + meta_window_queue (priv->window, META_QUEUE_CALC_SHOWING); +} + +static void +meta_wayland_shell_surface_surface_apply_state (MetaWaylandSurfaceRole *surface_role, + MetaWaylandSurfaceState *pending) +{ + MetaWaylandShellSurface *shell_surface = + META_WAYLAND_SHELL_SURFACE (surface_role); + MetaWaylandShellSurfacePrivate *priv = + meta_wayland_shell_surface_get_instance_private (shell_surface); + MetaWaylandActorSurface *actor_surface = + META_WAYLAND_ACTOR_SURFACE (surface_role); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWaylandSurfaceRoleClass *surface_role_class; + MetaWindow *window; + MetaWaylandBuffer *buffer; + double geometry_scale; + + surface_role_class = + META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_shell_surface_parent_class); + surface_role_class->apply_state (surface_role, pending); + + buffer = surface->buffer_ref.buffer; + if (!buffer) + return; + + window = priv->window; + if (!window) + return; + + geometry_scale = meta_wayland_actor_surface_get_geometry_scale (actor_surface); + + window->buffer_rect.width = + meta_wayland_surface_get_width (surface) * geometry_scale; + window->buffer_rect.height = + meta_wayland_surface_get_height (surface) * geometry_scale; +} + +static MetaWindow * +meta_wayland_shell_surface_get_window (MetaWaylandSurfaceRole *surface_role) +{ + MetaWaylandShellSurface *shell_surface = + META_WAYLAND_SHELL_SURFACE (surface_role); + MetaWaylandShellSurfacePrivate *priv = + meta_wayland_shell_surface_get_instance_private (shell_surface); + + return priv->window; +} + +static void +meta_wayland_shell_surface_notify_subsurface_state_changed (MetaWaylandSurfaceRole *surface_role) +{ + MetaWaylandShellSurface *shell_surface = + META_WAYLAND_SHELL_SURFACE (surface_role); + MetaWaylandShellSurfacePrivate *priv = + meta_wayland_shell_surface_get_instance_private (shell_surface); + MetaWindow *window; + MetaWindowActor *window_actor; + + window = priv->window; + if (!window) + return; + + window_actor = meta_window_actor_from_window (window); + meta_window_actor_wayland_rebuild_surface_tree (window_actor); +} + +static double +meta_wayland_shell_surface_get_geometry_scale (MetaWaylandActorSurface *actor_surface) +{ + MetaWaylandSurfaceRole *surface_role = + META_WAYLAND_SURFACE_ROLE (actor_surface); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWindow *toplevel_window; + + toplevel_window = meta_wayland_surface_get_toplevel_window (surface); + if (meta_is_stage_views_scaled () || !toplevel_window) + return 1; + else + return meta_window_wayland_get_geometry_scale (toplevel_window); +} + +static void +meta_wayland_shell_surface_sync_actor_state (MetaWaylandActorSurface *actor_surface) +{ + MetaWaylandSurfaceRole *surface_role = + META_WAYLAND_SURFACE_ROLE (actor_surface); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWaylandActorSurfaceClass *actor_surface_class = + META_WAYLAND_ACTOR_SURFACE_CLASS (meta_wayland_shell_surface_parent_class); + MetaWindow *toplevel_window; + + toplevel_window = meta_wayland_surface_get_toplevel_window (surface); + if (!toplevel_window) + return; + + actor_surface_class->sync_actor_state (actor_surface); +} + +void +meta_wayland_shell_surface_destroy_window (MetaWaylandShellSurface *shell_surface) +{ + MetaWaylandShellSurfacePrivate *priv = + meta_wayland_shell_surface_get_instance_private (shell_surface); + MetaWindow *window; + MetaDisplay *display; + uint32_t timestamp; + + window = priv->window; + if (!window) + return; + + display = meta_window_get_display (window); + timestamp = meta_display_get_current_time_roundtrip (display); + meta_window_unmanage (window, timestamp); + g_assert (!priv->window); +} + +static void +meta_wayland_shell_surface_finalize (GObject *object) +{ + MetaWaylandShellSurface *shell_surface = META_WAYLAND_SHELL_SURFACE (object); + + meta_wayland_shell_surface_destroy_window (shell_surface); + + G_OBJECT_CLASS (meta_wayland_shell_surface_parent_class)->finalize (object); +} + +static void +meta_wayland_shell_surface_init (MetaWaylandShellSurface *role) +{ +} + +static void +meta_wayland_shell_surface_class_init (MetaWaylandShellSurfaceClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MetaWaylandSurfaceRoleClass *surface_role_class = + META_WAYLAND_SURFACE_ROLE_CLASS (klass); + MetaWaylandActorSurfaceClass *actor_surface_class = + META_WAYLAND_ACTOR_SURFACE_CLASS (klass); + + object_class->finalize = meta_wayland_shell_surface_finalize; + + surface_role_class->assigned = meta_wayland_shell_surface_assigned; + surface_role_class->pre_apply_state = + meta_wayland_shell_surface_surface_pre_apply_state; + surface_role_class->apply_state = + meta_wayland_shell_surface_surface_apply_state; + surface_role_class->notify_subsurface_state_changed = + meta_wayland_shell_surface_notify_subsurface_state_changed; + surface_role_class->get_window = meta_wayland_shell_surface_get_window; + + actor_surface_class->get_geometry_scale = + meta_wayland_shell_surface_get_geometry_scale; + actor_surface_class->sync_actor_state = + meta_wayland_shell_surface_sync_actor_state; +} diff --git a/src/wayland/meta-wayland-shell-surface.h b/src/wayland/meta-wayland-shell-surface.h new file mode 100644 index 000000000..d1bbeef65 --- /dev/null +++ b/src/wayland/meta-wayland-shell-surface.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2012,2013 Intel Corporation + * Copyright (C) 2013-2017 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_WAYLAND_SHELL_SURFACE_H +#define META_WAYLAND_SHELL_SURFACE_H + +#include "wayland/meta-wayland-actor-surface.h" + +#define META_TYPE_WAYLAND_SHELL_SURFACE (meta_wayland_shell_surface_get_type ()) +G_DECLARE_DERIVABLE_TYPE (MetaWaylandShellSurface, + meta_wayland_shell_surface, + META, WAYLAND_SHELL_SURFACE, + MetaWaylandActorSurface) + +struct _MetaWaylandShellSurfaceClass +{ + MetaWaylandActorSurfaceClass parent_class; + + void (*configure) (MetaWaylandShellSurface *shell_surface, + MetaWaylandWindowConfiguration *configuration); + void (*managed) (MetaWaylandShellSurface *shell_surface, + MetaWindow *window); + void (*ping) (MetaWaylandShellSurface *shell_surface, + uint32_t serial); + void (*close) (MetaWaylandShellSurface *shell_surface); +}; + +void meta_wayland_shell_surface_configure (MetaWaylandShellSurface *shell_surface, + MetaWaylandWindowConfiguration *configuration); + +void meta_wayland_shell_surface_ping (MetaWaylandShellSurface *shell_surface, + uint32_t serial); + +void meta_wayland_shell_surface_close (MetaWaylandShellSurface *shell_surface); + +void meta_wayland_shell_surface_managed (MetaWaylandShellSurface *shell_surface, + MetaWindow *window); + +void meta_wayland_shell_surface_calculate_geometry (MetaWaylandShellSurface *shell_surface, + MetaRectangle *out_geometry); + +void meta_wayland_shell_surface_determine_geometry (MetaWaylandShellSurface *shell_surface, + MetaRectangle *set_geometry, + MetaRectangle *out_geometry); + +void meta_wayland_shell_surface_set_window (MetaWaylandShellSurface *shell_surface, + MetaWindow *window); + +void meta_wayland_shell_surface_destroy_window (MetaWaylandShellSurface *shell_surface); + +#endif /* META_WAYLAND_SHELL_SURFACE_H */ diff --git a/src/wayland/meta-wayland-subsurface.c b/src/wayland/meta-wayland-subsurface.c new file mode 100644 index 000000000..0027bb210 --- /dev/null +++ b/src/wayland/meta-wayland-subsurface.c @@ -0,0 +1,600 @@ +/* + * Copyright (C) 2012,2013 Intel Corporation + * Copyright (C) 2013-2017 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "wayland/meta-wayland-subsurface.h" + +#include "compositor/meta-surface-actor-wayland.h" +#include "compositor/meta-window-actor-wayland.h" +#include "wayland/meta-wayland.h" +#include "wayland/meta-wayland-actor-surface.h" +#include "wayland/meta-wayland-buffer.h" +#include "wayland/meta-wayland-surface.h" +#include "wayland/meta-window-wayland.h" + +struct _MetaWaylandSubsurface +{ + MetaWaylandActorSurface parent; +}; + +G_DEFINE_TYPE (MetaWaylandSubsurface, + meta_wayland_subsurface, + META_TYPE_WAYLAND_ACTOR_SURFACE) + +static void +transform_subsurface_position (MetaWaylandSurface *surface, + int *x, + int *y) +{ + do + { + *x += surface->sub.x; + *y += surface->sub.y; + + surface = surface->sub.parent; + } + while (surface); +} + +static void +sync_actor_subsurface_state (MetaWaylandSurface *surface) +{ + ClutterActor *actor = CLUTTER_ACTOR (meta_wayland_surface_get_actor (surface)); + MetaWindow *toplevel_window; + int x, y; + + toplevel_window = meta_wayland_surface_get_toplevel_window (surface); + if (!toplevel_window) + return; + + if (toplevel_window->client_type == META_WINDOW_CLIENT_TYPE_X11) + return; + + x = y = 0; + transform_subsurface_position (surface, &x, &y); + + clutter_actor_set_position (actor, x, y); + clutter_actor_set_reactive (actor, TRUE); + + if (surface->buffer_ref.buffer) + clutter_actor_show (actor); + else + clutter_actor_hide (actor); +} + +static gboolean +is_child (MetaWaylandSurface *surface, + MetaWaylandSurface *sibling) +{ + if (surface->sub.parent == sibling) + return TRUE; + else + return FALSE; +} + +static gboolean +is_sibling (MetaWaylandSurface *surface, + MetaWaylandSurface *sibling) +{ + if (surface->sub.parent == sibling->sub.parent) + return TRUE; + else + return FALSE; +} + +static gboolean +is_surface_effectively_synchronized (MetaWaylandSurface *surface) +{ + return meta_wayland_surface_should_cache_state (surface); +} + +void +meta_wayland_subsurface_parent_state_applied (MetaWaylandSubsurface *subsurface) +{ + MetaWaylandSurfaceRole *surface_role = META_WAYLAND_SURFACE_ROLE (subsurface); + MetaWaylandActorSurface *actor_surface = + META_WAYLAND_ACTOR_SURFACE (subsurface); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + + if (surface->sub.pending_pos) + { + surface->sub.x = surface->sub.pending_x; + surface->sub.y = surface->sub.pending_y; + surface->sub.pending_pos = FALSE; + } + + if (is_surface_effectively_synchronized (surface)) + meta_wayland_surface_apply_cached_state (surface); + + meta_wayland_actor_surface_sync_actor_state (actor_surface); +} + +void +meta_wayland_subsurface_union_geometry (MetaWaylandSubsurface *subsurface, + int parent_x, + int parent_y, + MetaRectangle *out_geometry) +{ + MetaWaylandSurfaceRole *surface_role = META_WAYLAND_SURFACE_ROLE (subsurface); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaRectangle geometry; + MetaWaylandSurface *subsurface_surface; + + geometry = (MetaRectangle) { + .x = surface->offset_x + surface->sub.x, + .y = surface->offset_y + surface->sub.y, + .width = meta_wayland_surface_get_width (surface), + .height = meta_wayland_surface_get_height (surface), + }; + + meta_rectangle_union (out_geometry, &geometry, out_geometry); + + META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (surface, subsurface_surface) + { + MetaWaylandSubsurface *subsurface; + + subsurface = META_WAYLAND_SUBSURFACE (subsurface_surface->role); + meta_wayland_subsurface_union_geometry (subsurface, + parent_x + geometry.x, + parent_y + geometry.y, + out_geometry); + } +} + +static void +meta_wayland_subsurface_assigned (MetaWaylandSurfaceRole *surface_role) +{ + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWaylandSurfaceRoleClass *surface_role_class = + META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_subsurface_parent_class); + + surface->dnd.funcs = meta_wayland_data_device_get_drag_dest_funcs (); + + surface_role_class->assigned (surface_role); +} + +static MetaWaylandSurface * +meta_wayland_subsurface_get_toplevel (MetaWaylandSurfaceRole *surface_role) +{ + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWaylandSurface *parent = surface->sub.parent; + + if (parent) + return meta_wayland_surface_get_toplevel (parent); + else + return NULL; +} + +static gboolean +meta_wayland_subsurface_should_cache_state (MetaWaylandSurfaceRole *surface_role) +{ + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWaylandSurface *parent; + + if (surface->sub.synchronous) + return TRUE; + + parent = surface->sub.parent; + if (parent) + return meta_wayland_surface_should_cache_state (parent); + + return TRUE; +} + +static void +meta_wayland_subsurface_notify_subsurface_state_changed (MetaWaylandSurfaceRole *surface_role) +{ + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWaylandSurface *parent = surface->sub.parent; + + if (parent) + return meta_wayland_surface_notify_subsurface_state_changed (parent); +} + +static double +meta_wayland_subsurface_get_geometry_scale (MetaWaylandActorSurface *actor_surface) +{ + MetaWaylandSurfaceRole *surface_role = + META_WAYLAND_SURFACE_ROLE (actor_surface); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWaylandSurface *parent = surface->sub.parent; + + if (parent) + { + MetaWaylandActorSurface *parent_actor; + + parent_actor = META_WAYLAND_ACTOR_SURFACE (surface->sub.parent->role); + return meta_wayland_actor_surface_get_geometry_scale (parent_actor); + } + else + { + return 1; + } +} + +static void +meta_wayland_subsurface_sync_actor_state (MetaWaylandActorSurface *actor_surface) +{ + MetaWaylandSurfaceRole *surface_role = + META_WAYLAND_SURFACE_ROLE (actor_surface); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWaylandActorSurfaceClass *actor_surface_class = + META_WAYLAND_ACTOR_SURFACE_CLASS (meta_wayland_subsurface_parent_class); + MetaWaylandSurface *toplevel_surface; + + toplevel_surface = meta_wayland_surface_get_toplevel (surface); + if (toplevel_surface && meta_wayland_surface_get_window (toplevel_surface)) + actor_surface_class->sync_actor_state (actor_surface); + + sync_actor_subsurface_state (surface); +} + +static void +meta_wayland_subsurface_init (MetaWaylandSubsurface *role) +{ +} + +static void +meta_wayland_subsurface_class_init (MetaWaylandSubsurfaceClass *klass) +{ + MetaWaylandSurfaceRoleClass *surface_role_class = + META_WAYLAND_SURFACE_ROLE_CLASS (klass); + MetaWaylandActorSurfaceClass *actor_surface_class = + META_WAYLAND_ACTOR_SURFACE_CLASS (klass); + + surface_role_class->assigned = meta_wayland_subsurface_assigned; + surface_role_class->get_toplevel = meta_wayland_subsurface_get_toplevel; + surface_role_class->should_cache_state = meta_wayland_subsurface_should_cache_state; + surface_role_class->notify_subsurface_state_changed = + meta_wayland_subsurface_notify_subsurface_state_changed; + + actor_surface_class->get_geometry_scale = + meta_wayland_subsurface_get_geometry_scale; + actor_surface_class->sync_actor_state = + meta_wayland_subsurface_sync_actor_state; +} + +static void +unparent_actor (MetaWaylandSurface *surface) +{ + ClutterActor *actor; + ClutterActor *parent_actor; + + actor = CLUTTER_ACTOR (meta_wayland_surface_get_actor (surface)); + if (!actor) + return; + + parent_actor = clutter_actor_get_parent (actor); + clutter_actor_remove_child (parent_actor, actor); +} + +static void +wl_subsurface_destructor (struct wl_resource *resource) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); + + g_node_unlink (surface->subsurface_branch_node); + unparent_actor (surface); + + if (surface->sub.parent) + { + wl_list_remove (&surface->sub.parent_destroy_listener.link); + surface->sub.parent = NULL; + } + + surface->wl_subsurface = NULL; +} + +static void +wl_subsurface_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +wl_subsurface_set_position (struct wl_client *client, + struct wl_resource *resource, + int32_t x, + int32_t y) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); + + surface->sub.pending_x = x; + surface->sub.pending_y = y; + surface->sub.pending_pos = TRUE; +} + +static gboolean +is_valid_sibling (MetaWaylandSurface *surface, + MetaWaylandSurface *sibling) +{ + if (is_child (surface, sibling)) + return TRUE; + if (is_sibling (surface, sibling)) + return TRUE; + return FALSE; +} + +static void +subsurface_handle_pending_surface_destroyed (struct wl_listener *listener, + void *data) +{ + MetaWaylandSubsurfacePlacementOp *op = + wl_container_of (listener, op, surface_destroy_listener); + + op->surface = NULL; +} + +static void +subsurface_handle_pending_sibling_destroyed (struct wl_listener *listener, + void *data) +{ + MetaWaylandSubsurfacePlacementOp *op = + wl_container_of (listener, op, sibling_destroy_listener); + + op->sibling = NULL; +} + +void +meta_wayland_subsurface_placement_op_free (MetaWaylandSubsurfacePlacementOp *op) +{ + if (op->surface) + wl_list_remove (&op->surface_destroy_listener.link); + if (op->sibling) + wl_list_remove (&op->sibling_destroy_listener.link); + g_free (op); +} + +static void +queue_subsurface_placement (MetaWaylandSurface *surface, + MetaWaylandSurface *sibling, + MetaWaylandSubsurfacePlacement placement) +{ + MetaWaylandSurface *parent = surface->sub.parent; + MetaWaylandSubsurfacePlacementOp *op = + g_new0 (MetaWaylandSubsurfacePlacementOp, 1); + + op->placement = placement; + op->surface = surface; + op->sibling = sibling; + op->surface_destroy_listener.notify = + subsurface_handle_pending_surface_destroyed; + op->sibling_destroy_listener.notify = + subsurface_handle_pending_sibling_destroyed; + wl_resource_add_destroy_listener (surface->resource, + &op->surface_destroy_listener); + wl_resource_add_destroy_listener (sibling->resource, + &op->sibling_destroy_listener); + + parent->pending_state->subsurface_placement_ops = + g_slist_append (parent->pending_state->subsurface_placement_ops, op); +} + +static void +wl_subsurface_place_above (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *sibling_resource) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *sibling = wl_resource_get_user_data (sibling_resource); + + if (!is_valid_sibling (surface, sibling)) + { + wl_resource_post_error (resource, WL_SUBSURFACE_ERROR_BAD_SURFACE, + "wl_subsurface::place_above: wl_surface@%d is " + "not a valid parent or sibling", + wl_resource_get_id (sibling->resource)); + return; + } + + queue_subsurface_placement (surface, + sibling, + META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE); +} + +static void +wl_subsurface_place_below (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *sibling_resource) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *sibling = wl_resource_get_user_data (sibling_resource); + + if (!is_valid_sibling (surface, sibling)) + { + wl_resource_post_error (resource, WL_SUBSURFACE_ERROR_BAD_SURFACE, + "wl_subsurface::place_below: wl_surface@%d is " + "not a valid parent or sibling", + wl_resource_get_id (sibling->resource)); + return; + } + + queue_subsurface_placement (surface, + sibling, + META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW); +} + +static void +wl_subsurface_set_sync (struct wl_client *client, + struct wl_resource *resource) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); + + surface->sub.synchronous = TRUE; +} + +static void +wl_subsurface_set_desync (struct wl_client *client, + struct wl_resource *resource) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); + gboolean was_effectively_synchronized; + + was_effectively_synchronized = is_surface_effectively_synchronized (surface); + surface->sub.synchronous = FALSE; + + if (was_effectively_synchronized && + !is_surface_effectively_synchronized (surface)) + meta_wayland_surface_apply_cached_state (surface); +} + +static const struct wl_subsurface_interface meta_wayland_wl_subsurface_interface = { + wl_subsurface_destroy, + wl_subsurface_set_position, + wl_subsurface_place_above, + wl_subsurface_place_below, + wl_subsurface_set_sync, + wl_subsurface_set_desync, +}; + +static void +wl_subcompositor_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +surface_handle_parent_surface_destroyed (struct wl_listener *listener, + void *data) +{ + MetaWaylandSurface *surface = wl_container_of (listener, + surface, + sub.parent_destroy_listener); + + surface->sub.parent = NULL; +} + +static gboolean +is_same_or_ancestor (MetaWaylandSurface *surface, + MetaWaylandSurface *other_surface) +{ + if (surface == other_surface) + return TRUE; + if (other_surface->sub.parent) + return is_same_or_ancestor (surface, other_surface->sub.parent); + return FALSE; +} + +static void +wl_subcompositor_get_subsurface (struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *surface_resource, + struct wl_resource *parent_resource) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + MetaWaylandSurface *parent = wl_resource_get_user_data (parent_resource); + MetaWindow *toplevel_window; + + if (surface->wl_subsurface) + { + wl_resource_post_error (surface_resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "wl_subcompositor::get_subsurface already requested"); + return; + } + + if (is_same_or_ancestor (surface, parent)) + { + wl_resource_post_error (resource, WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE, + "Circular relationship between wl_surface@%d " + "and parent surface wl_surface@%d", + wl_resource_get_id (surface->resource), + wl_resource_get_id (parent->resource)); + return; + } + + if (!meta_wayland_surface_assign_role (surface, + META_TYPE_WAYLAND_SUBSURFACE, + NULL)) + { + wl_resource_post_error (resource, WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE, + "wl_surface@%d already has a different role", + wl_resource_get_id (surface->resource)); + return; + } + + toplevel_window = meta_wayland_surface_get_toplevel_window (parent); + if (toplevel_window && + toplevel_window->client_type == META_WINDOW_CLIENT_TYPE_X11) + g_warning ("XWayland subsurfaces not currently supported"); + + surface->wl_subsurface = + wl_resource_create (client, + &wl_subsurface_interface, + wl_resource_get_version (resource), + id); + wl_resource_set_implementation (surface->wl_subsurface, + &meta_wayland_wl_subsurface_interface, + surface, + wl_subsurface_destructor); + + surface->sub.synchronous = TRUE; + surface->sub.parent = parent; + surface->sub.parent_destroy_listener.notify = + surface_handle_parent_surface_destroyed; + wl_resource_add_destroy_listener (parent->resource, + &surface->sub.parent_destroy_listener); + + g_node_append (parent->subsurface_branch_node, + surface->subsurface_branch_node); + + meta_wayland_surface_notify_subsurface_state_changed (parent); +} + +static const struct wl_subcompositor_interface meta_wayland_subcompositor_interface = { + wl_subcompositor_destroy, + wl_subcompositor_get_subsurface, +}; + +static void +bind_subcompositor (struct wl_client *client, + void *data, + uint32_t version, + uint32_t id) +{ + struct wl_resource *resource; + + resource = wl_resource_create (client, &wl_subcompositor_interface, + version, id); + wl_resource_set_implementation (resource, &meta_wayland_subcompositor_interface, + data, NULL); +} + +void +meta_wayland_subsurfaces_init (MetaWaylandCompositor *compositor) +{ + if (wl_global_create (compositor->wayland_display, + &wl_subcompositor_interface, + META_WL_SUBCOMPOSITOR_VERSION, + compositor, bind_subcompositor) == NULL) + g_error ("Failed to register a global wl-subcompositor object"); +} diff --git a/src/wayland/meta-wayland-subsurface.h b/src/wayland/meta-wayland-subsurface.h new file mode 100644 index 000000000..7ea6bc5ae --- /dev/null +++ b/src/wayland/meta-wayland-subsurface.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2012,2013 Intel Corporation + * Copyright (C) 2013-2017 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_WAYLAND_SUBSURFACE_H +#define META_WAYLAND_SUBSURFACE_H + +#include "wayland/meta-wayland-actor-surface.h" + +#define META_TYPE_WAYLAND_SUBSURFACE (meta_wayland_subsurface_get_type ()) +G_DECLARE_FINAL_TYPE (MetaWaylandSubsurface, + meta_wayland_subsurface, + META, WAYLAND_SUBSURFACE, + MetaWaylandActorSurface) + +typedef enum +{ + META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE, + META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW +} MetaWaylandSubsurfacePlacement; + +typedef struct +{ + MetaWaylandSubsurfacePlacement placement; + MetaWaylandSurface *surface; + MetaWaylandSurface *sibling; + struct wl_listener surface_destroy_listener; + struct wl_listener sibling_destroy_listener; +} MetaWaylandSubsurfacePlacementOp; + +void meta_wayland_subsurface_parent_state_applied (MetaWaylandSubsurface *subsurface); + +void meta_wayland_subsurface_union_geometry (MetaWaylandSubsurface *subsurface, + int parent_x, + int parent_y, + MetaRectangle *out_geometry); + +void meta_wayland_subsurface_placement_op_free (MetaWaylandSubsurfacePlacementOp *op); + +void meta_wayland_subsurfaces_init (MetaWaylandCompositor *compositor); + +#endif /* META_WAYLAND_SUBSURFACE_H */ diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c new file mode 100644 index 000000000..aecaac4ce --- /dev/null +++ b/src/wayland/meta-wayland-surface.c @@ -0,0 +1,1982 @@ +/* + * Wayland Support + * + * Copyright (C) 2012,2013 Intel Corporation + * Copyright (C) 2013-2017 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "wayland/meta-wayland-surface.h" + +#include <gobject/gvaluecollector.h> +#include <wayland-server.h> + +#include "backends/meta-cursor-tracker-private.h" +#include "clutter/clutter.h" +#include "clutter/wayland/clutter-wayland-compositor.h" +#include "cogl/cogl-wayland-server.h" +#include "cogl/cogl.h" +#include "compositor/meta-surface-actor-wayland.h" +#include "compositor/meta-surface-actor.h" +#include "compositor/meta-window-actor-private.h" +#include "compositor/region-utils.h" +#include "core/display-private.h" +#include "core/window-private.h" +#include "wayland/meta-wayland-actor-surface.h" +#include "wayland/meta-wayland-buffer.h" +#include "wayland/meta-wayland-data-device.h" +#include "wayland/meta-wayland-gtk-shell.h" +#include "wayland/meta-wayland-keyboard.h" +#include "wayland/meta-wayland-legacy-xdg-shell.h" +#include "wayland/meta-wayland-outputs.h" +#include "wayland/meta-wayland-pointer.h" +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-wayland-region.h" +#include "wayland/meta-wayland-seat.h" +#include "wayland/meta-wayland-subsurface.h" +#include "wayland/meta-wayland-viewporter.h" +#include "wayland/meta-wayland-wl-shell.h" +#include "wayland/meta-wayland-xdg-shell.h" +#include "wayland/meta-window-wayland.h" +#include "wayland/meta-xwayland-private.h" +#include "wayland/meta-xwayland-private.h" + +enum +{ + SURFACE_STATE_SIGNAL_APPLIED, + + SURFACE_STATE_SIGNAL_N_SIGNALS +}; + +enum +{ + SURFACE_ROLE_PROP_0, + + SURFACE_ROLE_PROP_SURFACE, +}; + +static guint surface_state_signals[SURFACE_STATE_SIGNAL_N_SIGNALS]; + +typedef struct _MetaWaylandSurfaceRolePrivate +{ + MetaWaylandSurface *surface; +} MetaWaylandSurfaceRolePrivate; + +G_DEFINE_TYPE (MetaWaylandSurface, meta_wayland_surface, G_TYPE_OBJECT); + +G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaWaylandSurfaceRole, + meta_wayland_surface_role, + G_TYPE_OBJECT) + +G_DEFINE_TYPE (MetaWaylandSurfaceState, + meta_wayland_surface_state, + G_TYPE_OBJECT) + +enum +{ + SURFACE_DESTROY, + SURFACE_UNMAPPED, + SURFACE_CONFIGURE, + SURFACE_SHORTCUTS_INHIBITED, + SURFACE_SHORTCUTS_RESTORED, + SURFACE_GEOMETRY_CHANGED, + SURFACE_PRE_STATE_APPLIED, + N_SURFACE_SIGNALS +}; + +guint surface_signals[N_SURFACE_SIGNALS] = { 0 }; + +static void +meta_wayland_surface_role_assigned (MetaWaylandSurfaceRole *surface_role); + +static void +meta_wayland_surface_role_pre_apply_state (MetaWaylandSurfaceRole *surface_role, + MetaWaylandSurfaceState *pending); + +static void +meta_wayland_surface_role_apply_state (MetaWaylandSurfaceRole *surface_role, + MetaWaylandSurfaceState *pending); + +static void +meta_wayland_surface_role_post_apply_state (MetaWaylandSurfaceRole *surface_role, + MetaWaylandSurfaceState *pending); + +static gboolean +meta_wayland_surface_role_is_on_logical_monitor (MetaWaylandSurfaceRole *surface_role, + MetaLogicalMonitor *logical_monitor); + +static MetaWaylandSurface * +meta_wayland_surface_role_get_toplevel (MetaWaylandSurfaceRole *surface_role); + +static void +role_assignment_valist_to_properties (GType role_type, + const char *first_property_name, + va_list var_args, + GArray *names, + GArray *values) +{ + GObjectClass *object_class; + const char *property_name = first_property_name; + + object_class = g_type_class_ref (role_type); + + while (property_name) + { + GValue value = G_VALUE_INIT; + GParamSpec *pspec; + GType ptype; + gchar *error = NULL; + + pspec = g_object_class_find_property (object_class, + property_name); + g_assert (pspec); + + ptype = G_PARAM_SPEC_VALUE_TYPE (pspec); + G_VALUE_COLLECT_INIT (&value, ptype, var_args, 0, &error); + g_assert (!error); + + g_array_append_val (names, property_name); + g_array_append_val (values, value); + + property_name = va_arg (var_args, const char *); + } + + g_type_class_unref (object_class); +} + +gboolean +meta_wayland_surface_assign_role (MetaWaylandSurface *surface, + GType role_type, + const char *first_property_name, + ...) +{ + va_list var_args; + + if (!surface->role) + { + if (first_property_name) + { + GArray *names; + GArray *values; + const char *surface_prop_name; + GValue surface_value = G_VALUE_INIT; + GObject *role_object; + + names = g_array_new (FALSE, FALSE, sizeof (const char *)); + values = g_array_new (FALSE, FALSE, sizeof (GValue)); + g_array_set_clear_func (values, (GDestroyNotify) g_value_unset); + + va_start (var_args, first_property_name); + role_assignment_valist_to_properties (role_type, + first_property_name, + var_args, + names, + values); + va_end (var_args); + + surface_prop_name = "surface"; + g_value_init (&surface_value, META_TYPE_WAYLAND_SURFACE); + g_value_set_object (&surface_value, surface); + g_array_append_val (names, surface_prop_name); + g_array_append_val (values, surface_value); + + role_object = + g_object_new_with_properties (role_type, + values->len, + (const char **) names->data, + (const GValue *) values->data); + surface->role = META_WAYLAND_SURFACE_ROLE (role_object); + + g_array_free (names, TRUE); + g_array_free (values, TRUE); + } + else + { + surface->role = g_object_new (role_type, "surface", surface, NULL); + } + + meta_wayland_surface_role_assigned (surface->role); + + /* Release the use count held on behalf of the just assigned role. */ + if (surface->unassigned.buffer) + { + meta_wayland_surface_unref_buffer_use_count (surface); + g_clear_object (&surface->unassigned.buffer); + } + + return TRUE; + } + else if (G_OBJECT_TYPE (surface->role) != role_type) + { + return FALSE; + } + else + { + va_start (var_args, first_property_name); + g_object_set_valist (G_OBJECT (surface->role), + first_property_name, var_args); + va_end (var_args); + + meta_wayland_surface_role_assigned (surface->role); + + return TRUE; + } +} + +static int +get_buffer_width (MetaWaylandSurface *surface) +{ + MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface); + + if (buffer) + return cogl_texture_get_width (surface->texture); + else + return 0; +} + +static int +get_buffer_height (MetaWaylandSurface *surface) +{ + MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface); + + if (buffer) + return cogl_texture_get_height (surface->texture); + else + return 0; +} + +static void +surface_process_damage (MetaWaylandSurface *surface, + cairo_region_t *surface_region, + cairo_region_t *buffer_region) +{ + MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface); + cairo_rectangle_int_t surface_rect; + cairo_rectangle_int_t buffer_rect; + cairo_region_t *scaled_region; + cairo_region_t *transformed_region; + cairo_region_t *viewport_region; + graphene_rect_t src_rect; + MetaSurfaceActor *actor; + + /* If the client destroyed the buffer it attached before committing, but + * still posted damage, or posted damage without any buffer, don't try to + * process it on the non-existing buffer. + */ + if (!buffer) + return; + + buffer_rect = (cairo_rectangle_int_t) { + .width = get_buffer_width (surface), + .height = get_buffer_height (surface), + }; + + /* Intersect the damage region with the surface region before scaling in + * order to avoid integer overflow when scaling a damage region is too large + * (for example INT32_MAX which mesa passes). */ + surface_rect = (cairo_rectangle_int_t) { + .width = meta_wayland_surface_get_width (surface), + .height = meta_wayland_surface_get_height (surface), + }; + cairo_region_intersect_rectangle (surface_region, &surface_rect); + + /* The damage region must be in the same coordinate space as the buffer, + * i.e. scaled with surface->scale. */ + scaled_region = meta_region_scale (surface_region, surface->scale); + if (surface->viewport.has_src_rect) + { + src_rect = (graphene_rect_t) { + .origin.x = surface->viewport.src_rect.origin.x * surface->scale, + .origin.y = surface->viewport.src_rect.origin.y * surface->scale, + .size.width = surface->viewport.src_rect.size.width * surface->scale, + .size.height = surface->viewport.src_rect.size.height * surface->scale + }; + } + else + { + src_rect = (graphene_rect_t) { + .size.width = surface_rect.width * surface->scale, + .size.height = surface_rect.height * surface->scale, + }; + } + viewport_region = meta_region_crop_and_scale (scaled_region, + &src_rect, + surface_rect.width * + surface->scale, + surface_rect.height * + surface->scale); + transformed_region = meta_region_transform (viewport_region, + surface->buffer_transform, + buffer_rect.width, + buffer_rect.height); + + /* Now add the scaled, cropped and transformed damage region to the + * buffer damage. Buffer damage is already in the correct coordinate space. */ + cairo_region_union (buffer_region, transformed_region); + + cairo_region_intersect_rectangle (buffer_region, &buffer_rect); + + meta_wayland_buffer_process_damage (buffer, surface->texture, buffer_region); + + actor = meta_wayland_surface_get_actor (surface); + if (actor) + { + int i, n_rectangles; + + n_rectangles = cairo_region_num_rectangles (buffer_region); + for (i = 0; i < n_rectangles; i++) + { + cairo_rectangle_int_t rect; + cairo_region_get_rectangle (buffer_region, i, &rect); + + meta_surface_actor_process_damage (actor, + rect.x, rect.y, + rect.width, rect.height); + } + } + + cairo_region_destroy (viewport_region); + cairo_region_destroy (scaled_region); + cairo_region_destroy (transformed_region); +} + +MetaWaylandBuffer * +meta_wayland_surface_get_buffer (MetaWaylandSurface *surface) +{ + return surface->buffer_ref.buffer; +} + +void +meta_wayland_surface_ref_buffer_use_count (MetaWaylandSurface *surface) +{ + g_return_if_fail (surface->buffer_ref.buffer); + g_warn_if_fail (surface->buffer_ref.buffer->resource); + + surface->buffer_ref.use_count++; +} + +void +meta_wayland_surface_unref_buffer_use_count (MetaWaylandSurface *surface) +{ + MetaWaylandBuffer *buffer = surface->buffer_ref.buffer; + + g_return_if_fail (surface->buffer_ref.use_count != 0); + + surface->buffer_ref.use_count--; + + g_return_if_fail (buffer); + + if (surface->buffer_ref.use_count == 0 && buffer->resource) + wl_buffer_send_release (buffer->resource); +} + +static void +pending_buffer_resource_destroyed (MetaWaylandBuffer *buffer, + MetaWaylandSurfaceState *pending) +{ + g_clear_signal_handler (&pending->buffer_destroy_handler_id, buffer); + pending->buffer = NULL; +} + +static void +meta_wayland_surface_state_set_default (MetaWaylandSurfaceState *state) +{ + state->newly_attached = FALSE; + state->buffer = NULL; + state->buffer_destroy_handler_id = 0; + state->dx = 0; + state->dy = 0; + state->scale = 0; + + state->input_region = NULL; + state->input_region_set = FALSE; + state->opaque_region = NULL; + state->opaque_region_set = FALSE; + + state->surface_damage = cairo_region_create (); + state->buffer_damage = cairo_region_create (); + wl_list_init (&state->frame_callback_list); + + state->has_new_geometry = FALSE; + state->has_acked_configure_serial = FALSE; + state->has_new_min_size = FALSE; + state->has_new_max_size = FALSE; + + state->has_new_buffer_transform = FALSE; + state->has_new_viewport_src_rect = FALSE; + state->has_new_viewport_dst_size = FALSE; + + state->subsurface_placement_ops = NULL; +} + +static void +meta_wayland_surface_state_clear (MetaWaylandSurfaceState *state) +{ + MetaWaylandFrameCallback *cb, *next; + + g_clear_pointer (&state->surface_damage, cairo_region_destroy); + g_clear_pointer (&state->buffer_damage, cairo_region_destroy); + g_clear_pointer (&state->input_region, cairo_region_destroy); + g_clear_pointer (&state->opaque_region, cairo_region_destroy); + + if (state->buffer) + g_clear_signal_handler (&state->buffer_destroy_handler_id, state->buffer); + + wl_list_for_each_safe (cb, next, &state->frame_callback_list, link) + wl_resource_destroy (cb->resource); + + if (state->subsurface_placement_ops) + { + g_slist_free_full ( + state->subsurface_placement_ops, + (GDestroyNotify) meta_wayland_subsurface_placement_op_free); + } +} + +static void +meta_wayland_surface_state_reset (MetaWaylandSurfaceState *state) +{ + meta_wayland_surface_state_clear (state); + meta_wayland_surface_state_set_default (state); +} + +static void +meta_wayland_surface_state_merge_into (MetaWaylandSurfaceState *from, + MetaWaylandSurfaceState *to) +{ + if (from->newly_attached) + { + if (to->buffer) + g_clear_signal_handler (&to->buffer_destroy_handler_id, to->buffer); + + if (from->buffer) + g_clear_signal_handler (&from->buffer_destroy_handler_id, from->buffer); + + to->newly_attached = TRUE; + to->buffer = from->buffer; + to->dx = from->dx; + to->dy = from->dy; + } + + wl_list_insert_list (&to->frame_callback_list, &from->frame_callback_list); + + cairo_region_union (to->surface_damage, from->surface_damage); + cairo_region_union (to->buffer_damage, from->buffer_damage); + cairo_region_destroy (from->surface_damage); + cairo_region_destroy (from->buffer_damage); + + if (from->input_region_set) + { + if (to->input_region) + cairo_region_union (to->input_region, from->input_region); + else + to->input_region = cairo_region_reference (from->input_region); + + to->input_region_set = TRUE; + cairo_region_destroy (from->input_region); + } + + if (from->opaque_region_set) + { + if (to->opaque_region) + cairo_region_union (to->opaque_region, from->opaque_region); + else + to->opaque_region = cairo_region_reference (from->opaque_region); + + to->opaque_region_set = TRUE; + cairo_region_destroy (from->opaque_region); + } + + if (from->has_new_geometry) + { + to->new_geometry = from->new_geometry; + to->has_new_geometry = TRUE; + } + + if (from->has_acked_configure_serial) + { + to->acked_configure_serial = from->acked_configure_serial; + to->has_acked_configure_serial = TRUE; + } + + if (from->has_new_min_size) + { + to->new_min_width = from->new_min_width; + to->new_min_height = from->new_min_height; + to->has_new_min_size = TRUE; + } + + if (from->has_new_max_size) + { + to->new_max_width = from->new_max_width; + to->new_max_height = from->new_max_height; + to->has_new_max_size = TRUE; + } + + if (from->scale > 0) + to->scale = from->scale; + + if (from->has_new_buffer_transform) + { + to->buffer_transform = from->buffer_transform; + to->has_new_buffer_transform = TRUE; + } + + if (from->has_new_viewport_src_rect) + { + to->viewport_src_rect.origin.x = from->viewport_src_rect.origin.x; + to->viewport_src_rect.origin.y = from->viewport_src_rect.origin.y; + to->viewport_src_rect.size.width = from->viewport_src_rect.size.width; + to->viewport_src_rect.size.height = from->viewport_src_rect.size.height; + to->has_new_viewport_src_rect = TRUE; + } + + if (from->has_new_viewport_dst_size) + { + to->viewport_dst_width = from->viewport_dst_width; + to->viewport_dst_height = from->viewport_dst_height; + to->has_new_viewport_dst_size = TRUE; + } + + if (to->buffer && to->buffer_destroy_handler_id == 0) + { + to->buffer_destroy_handler_id = + g_signal_connect (to->buffer, "resource-destroyed", + G_CALLBACK (pending_buffer_resource_destroyed), + to); + } + + if (from->subsurface_placement_ops != NULL) + { + if (to->subsurface_placement_ops != NULL) + { + to->subsurface_placement_ops = + g_slist_concat (to->subsurface_placement_ops, + from->subsurface_placement_ops); + } + else + { + to->subsurface_placement_ops = from->subsurface_placement_ops; + } + + from->subsurface_placement_ops = NULL; + } + + meta_wayland_surface_state_set_default (from); +} + +static void +meta_wayland_surface_state_finalize (GObject *object) +{ + MetaWaylandSurfaceState *state = META_WAYLAND_SURFACE_STATE (object); + + meta_wayland_surface_state_clear (state); + + G_OBJECT_CLASS (meta_wayland_surface_state_parent_class)->finalize (object); +} + +static void +meta_wayland_surface_state_init (MetaWaylandSurfaceState *state) +{ + meta_wayland_surface_state_set_default (state); +} + +static void +meta_wayland_surface_state_class_init (MetaWaylandSurfaceStateClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_wayland_surface_state_finalize; + + surface_state_signals[SURFACE_STATE_SIGNAL_APPLIED] = + g_signal_new ("applied", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); +} + +static void +meta_wayland_surface_apply_state (MetaWaylandSurface *surface, + MetaWaylandSurfaceState *state) +{ + MetaWaylandSurface *subsurface_surface; + gboolean had_damage = FALSE; + + g_signal_emit (surface, surface_signals[SURFACE_PRE_STATE_APPLIED], 0); + + if (surface->role) + { + meta_wayland_surface_role_pre_apply_state (surface->role, state); + } + else + { + if (state->newly_attached && surface->unassigned.buffer) + { + meta_wayland_surface_unref_buffer_use_count (surface); + g_clear_object (&surface->unassigned.buffer); + } + } + + if (state->newly_attached) + { + /* Always release any previously held buffer. If the buffer held is same + * as the newly attached buffer, we still need to release it here, because + * wl_surface.attach+commit and wl_buffer.release on the attached buffer + * is symmetric. + */ + if (surface->buffer_held) + meta_wayland_surface_unref_buffer_use_count (surface); + + g_set_object (&surface->buffer_ref.buffer, state->buffer); + + if (state->buffer) + meta_wayland_surface_ref_buffer_use_count (surface); + + if (state->buffer) + { + GError *error = NULL; + + if (!meta_wayland_buffer_attach (state->buffer, + &surface->texture, + &error)) + { + g_warning ("Could not import pending buffer: %s", error->message); + wl_resource_post_error (surface->resource, WL_DISPLAY_ERROR_NO_MEMORY, + "Failed to attach buffer to surface %i: %s", + wl_resource_get_id (surface->resource), + error->message); + g_error_free (error); + goto cleanup; + } + } + else + { + cogl_clear_object (&surface->texture); + } + + /* If the newly attached buffer is going to be accessed directly without + * making a copy, such as an EGL buffer, mark it as in-use don't release + * it until is replaced by a subsequent wl_surface.commit or when the + * wl_surface is destroyed. + */ + surface->buffer_held = (state->buffer && + !wl_shm_buffer_get (state->buffer->resource)); + } + + if (state->scale > 0) + surface->scale = state->scale; + + if (state->has_new_buffer_transform) + surface->buffer_transform = state->buffer_transform; + + if (state->has_new_viewport_src_rect) + { + surface->viewport.src_rect.origin.x = state->viewport_src_rect.origin.x; + surface->viewport.src_rect.origin.y = state->viewport_src_rect.origin.y; + surface->viewport.src_rect.size.width = state->viewport_src_rect.size.width; + surface->viewport.src_rect.size.height = state->viewport_src_rect.size.height; + surface->viewport.has_src_rect = surface->viewport.src_rect.size.width > 0; + } + + if (state->has_new_viewport_dst_size) + { + surface->viewport.dst_width = state->viewport_dst_width; + surface->viewport.dst_height = state->viewport_dst_height; + surface->viewport.has_dst_size = surface->viewport.dst_width > 0; + } + + if (!cairo_region_is_empty (state->surface_damage) || + !cairo_region_is_empty (state->buffer_damage)) + { + surface_process_damage (surface, + state->surface_damage, + state->buffer_damage); + had_damage = TRUE; + } + + surface->offset_x += state->dx; + surface->offset_y += state->dy; + + if (state->opaque_region_set) + { + if (surface->opaque_region) + cairo_region_destroy (surface->opaque_region); + if (state->opaque_region) + surface->opaque_region = cairo_region_reference (state->opaque_region); + else + surface->opaque_region = NULL; + } + + if (state->input_region_set) + { + if (surface->input_region) + cairo_region_destroy (surface->input_region); + if (state->input_region) + surface->input_region = cairo_region_reference (state->input_region); + else + surface->input_region = NULL; + } + + if (surface->role) + { + meta_wayland_surface_role_apply_state (surface->role, state); + g_assert (wl_list_empty (&state->frame_callback_list)); + } + else + { + wl_list_insert_list (surface->unassigned.pending_frame_callback_list.prev, + &state->frame_callback_list); + wl_list_init (&state->frame_callback_list); + + if (state->newly_attached) + { + /* The need to keep the wl_buffer from being released depends on what + * role the surface is given. That means we need to also keep a use + * count for wl_buffer's that are used by unassigned wl_surface's. + */ + g_set_object (&surface->unassigned.buffer, surface->buffer_ref.buffer); + if (surface->unassigned.buffer) + meta_wayland_surface_ref_buffer_use_count (surface); + } + } + + if (state->subsurface_placement_ops) + { + GSList *l; + + for (l = state->subsurface_placement_ops; l; l = l->next) + { + MetaWaylandSubsurfacePlacementOp *op = l->data; + GNode *sibling_node; + + if (!op->surface || !op->sibling) + continue; + + if (op->sibling == surface) + sibling_node = surface->subsurface_leaf_node; + else + sibling_node = op->sibling->subsurface_branch_node; + + g_node_unlink (op->surface->subsurface_branch_node); + + switch (op->placement) + { + case META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE: + g_node_insert_after (surface->subsurface_branch_node, + sibling_node, + op->surface->subsurface_branch_node); + break; + case META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW: + g_node_insert_before (surface->subsurface_branch_node, + sibling_node, + op->surface->subsurface_branch_node); + break; + } + } + + meta_wayland_surface_notify_subsurface_state_changed (surface); + } + +cleanup: + /* If we have a buffer that we are not using, decrease the use count so it may + * be released if no-one else has a use-reference to it. + */ + if (state->newly_attached && + !surface->buffer_held && surface->buffer_ref.buffer) + meta_wayland_surface_unref_buffer_use_count (surface); + + g_signal_emit (state, + surface_state_signals[SURFACE_STATE_SIGNAL_APPLIED], + 0); + + META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (surface, subsurface_surface) + { + MetaWaylandSubsurface *subsurface; + + subsurface = META_WAYLAND_SUBSURFACE (subsurface_surface->role); + meta_wayland_subsurface_parent_state_applied (subsurface); + } + + if (had_damage) + { + MetaWindow *toplevel_window; + + toplevel_window = meta_wayland_surface_get_toplevel_window (surface); + if (toplevel_window) + { + MetaWindowActor *toplevel_window_actor; + + toplevel_window_actor = + meta_window_actor_from_window (toplevel_window); + if (toplevel_window_actor) + meta_window_actor_notify_damaged (toplevel_window_actor); + } + } + + if (surface->role) + meta_wayland_surface_role_post_apply_state (surface->role, state); + + meta_wayland_surface_state_reset (state); +} + +void +meta_wayland_surface_apply_cached_state (MetaWaylandSurface *surface) +{ + if (!surface->cached_state) + return; + + meta_wayland_surface_apply_state (surface, surface->cached_state); +} + +MetaWaylandSurfaceState * +meta_wayland_surface_get_pending_state (MetaWaylandSurface *surface) +{ + return surface->pending_state; +} + +MetaWaylandSurfaceState * +meta_wayland_surface_ensure_cached_state (MetaWaylandSurface *surface) +{ + if (!surface->cached_state) + surface->cached_state = g_object_new (META_TYPE_WAYLAND_SURFACE_STATE, + NULL); + return surface->cached_state; +} + +static void +meta_wayland_surface_commit (MetaWaylandSurface *surface) +{ + MetaWaylandSurfaceState *pending = surface->pending_state; + + COGL_TRACE_BEGIN_SCOPED (MetaWaylandSurfaceCommit, + "WaylandSurface (commit)"); + + if (pending->buffer && + !meta_wayland_buffer_is_realized (pending->buffer)) + meta_wayland_buffer_realize (pending->buffer); + + /* + * If this is a sub-surface and it is in effective synchronous mode, only + * cache the pending surface state until either one of the following two + * scenarios happens: + * 1) Its parent surface gets its state applied. + * 2) Its mode changes from synchronized to desynchronized and its parent + * surface is in effective desynchronized mode. + */ + if (meta_wayland_surface_should_cache_state (surface)) + { + MetaWaylandSurfaceState *cached_state; + + cached_state = meta_wayland_surface_ensure_cached_state (surface); + meta_wayland_surface_state_merge_into (pending, cached_state); + } + else + { + meta_wayland_surface_apply_state (surface, surface->pending_state); + } +} + +static void +wl_surface_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +wl_surface_attach (struct wl_client *client, + struct wl_resource *surface_resource, + struct wl_resource *buffer_resource, + gint32 dx, gint32 dy) +{ + MetaWaylandSurface *surface = + wl_resource_get_user_data (surface_resource); + MetaWaylandSurfaceState *pending = surface->pending_state; + MetaWaylandBuffer *buffer; + + /* X11 unmanaged window */ + if (!surface) + return; + + if (buffer_resource) + buffer = meta_wayland_buffer_from_resource (buffer_resource); + else + buffer = NULL; + + if (surface->pending_state->buffer) + { + g_clear_signal_handler (&pending->buffer_destroy_handler_id, + pending->buffer); + } + + pending->newly_attached = TRUE; + pending->buffer = buffer; + pending->dx = dx; + pending->dy = dy; + + if (buffer) + { + pending->buffer_destroy_handler_id = + g_signal_connect (buffer, "resource-destroyed", + G_CALLBACK (pending_buffer_resource_destroyed), + pending); + } +} + +static void +wl_surface_damage (struct wl_client *client, + struct wl_resource *surface_resource, + int32_t x, + int32_t y, + int32_t width, + int32_t height) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + MetaWaylandSurfaceState *pending = surface->pending_state; + cairo_rectangle_int_t rectangle; + + /* X11 unmanaged window */ + if (!surface) + return; + + rectangle = (cairo_rectangle_int_t) { + .x = x, + .y = y, + .width = width, + .height = height + }; + cairo_region_union_rectangle (pending->surface_damage, &rectangle); +} + +static void +destroy_frame_callback (struct wl_resource *callback_resource) +{ + MetaWaylandFrameCallback *callback = + wl_resource_get_user_data (callback_resource); + + wl_list_remove (&callback->link); + g_slice_free (MetaWaylandFrameCallback, callback); +} + +static void +wl_surface_frame (struct wl_client *client, + struct wl_resource *surface_resource, + guint32 callback_id) +{ + MetaWaylandFrameCallback *callback; + MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + MetaWaylandSurfaceState *pending = surface->pending_state; + + /* X11 unmanaged window */ + if (!surface) + return; + + callback = g_slice_new0 (MetaWaylandFrameCallback); + callback->surface = surface; + callback->resource = wl_resource_create (client, + &wl_callback_interface, + META_WL_CALLBACK_VERSION, + callback_id); + wl_resource_set_implementation (callback->resource, NULL, callback, + destroy_frame_callback); + + wl_list_insert (pending->frame_callback_list.prev, &callback->link); +} + +static void +wl_surface_set_opaque_region (struct wl_client *client, + struct wl_resource *surface_resource, + struct wl_resource *region_resource) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + MetaWaylandSurfaceState *pending = surface->pending_state; + + /* X11 unmanaged window */ + if (!surface) + return; + + g_clear_pointer (&pending->opaque_region, cairo_region_destroy); + if (region_resource) + { + MetaWaylandRegion *region = wl_resource_get_user_data (region_resource); + cairo_region_t *cr_region = meta_wayland_region_peek_cairo_region (region); + pending->opaque_region = cairo_region_copy (cr_region); + } + pending->opaque_region_set = TRUE; +} + +static void +wl_surface_set_input_region (struct wl_client *client, + struct wl_resource *surface_resource, + struct wl_resource *region_resource) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + MetaWaylandSurfaceState *pending = surface->pending_state; + + /* X11 unmanaged window */ + if (!surface) + return; + + g_clear_pointer (&pending->input_region, cairo_region_destroy); + if (region_resource) + { + MetaWaylandRegion *region = wl_resource_get_user_data (region_resource); + cairo_region_t *cr_region = meta_wayland_region_peek_cairo_region (region); + pending->input_region = cairo_region_copy (cr_region); + } + pending->input_region_set = TRUE; +} + +static void +wl_surface_commit (struct wl_client *client, + struct wl_resource *resource) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); + + /* X11 unmanaged window */ + if (!surface) + return; + + meta_wayland_surface_commit (surface); +} + +static MetaMonitorTransform +transform_from_wl_output_transform (int32_t transform_value) +{ + enum wl_output_transform transform = transform_value; + + switch (transform) + { + case WL_OUTPUT_TRANSFORM_NORMAL: + return META_MONITOR_TRANSFORM_NORMAL; + case WL_OUTPUT_TRANSFORM_90: + return META_MONITOR_TRANSFORM_90; + case WL_OUTPUT_TRANSFORM_180: + return META_MONITOR_TRANSFORM_180; + case WL_OUTPUT_TRANSFORM_270: + return META_MONITOR_TRANSFORM_270; + case WL_OUTPUT_TRANSFORM_FLIPPED: + return META_MONITOR_TRANSFORM_FLIPPED; + case WL_OUTPUT_TRANSFORM_FLIPPED_90: + return META_MONITOR_TRANSFORM_FLIPPED_90; + case WL_OUTPUT_TRANSFORM_FLIPPED_180: + return META_MONITOR_TRANSFORM_FLIPPED_180; + case WL_OUTPUT_TRANSFORM_FLIPPED_270: + return META_MONITOR_TRANSFORM_FLIPPED_270; + default: + return -1; + } +} + +static void +wl_surface_set_buffer_transform (struct wl_client *client, + struct wl_resource *resource, + int32_t transform) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); + MetaWaylandSurfaceState *pending = surface->pending_state; + MetaMonitorTransform buffer_transform; + + buffer_transform = transform_from_wl_output_transform (transform); + + if (buffer_transform == -1) + { + wl_resource_post_error (resource, + WL_SURFACE_ERROR_INVALID_TRANSFORM, + "Trying to set invalid buffer_transform of %d\n", + transform); + return; + } + + pending->buffer_transform = buffer_transform; + pending->has_new_buffer_transform = TRUE; +} + +static void +wl_surface_set_buffer_scale (struct wl_client *client, + struct wl_resource *resource, + int scale) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); + MetaWaylandSurfaceState *pending = surface->pending_state; + + if (scale <= 0) + { + wl_resource_post_error (resource, + WL_SURFACE_ERROR_INVALID_SCALE, + "Trying to set invalid buffer_scale of %d\n", + scale); + return; + } + + pending->scale = scale; +} + +static void +wl_surface_damage_buffer (struct wl_client *client, + struct wl_resource *surface_resource, + int32_t x, + int32_t y, + int32_t width, + int32_t height) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + MetaWaylandSurfaceState *pending = surface->pending_state; + cairo_rectangle_int_t rectangle; + + /* X11 unmanaged window */ + if (!surface) + return; + + rectangle = (cairo_rectangle_int_t) { + .x = x, + .y = y, + .width = width, + .height = height + }; + cairo_region_union_rectangle (pending->buffer_damage, &rectangle); +} + +static const struct wl_surface_interface meta_wayland_wl_surface_interface = { + wl_surface_destroy, + wl_surface_attach, + wl_surface_damage, + wl_surface_frame, + wl_surface_set_opaque_region, + wl_surface_set_input_region, + wl_surface_commit, + wl_surface_set_buffer_transform, + wl_surface_set_buffer_scale, + wl_surface_damage_buffer, +}; + +static void +surface_entered_output (MetaWaylandSurface *surface, + MetaWaylandOutput *wayland_output) +{ + GList *iter; + struct wl_resource *resource; + + for (iter = wayland_output->resources; iter != NULL; iter = iter->next) + { + resource = iter->data; + + if (wl_resource_get_client (resource) != + wl_resource_get_client (surface->resource)) + continue; + + wl_surface_send_enter (surface->resource, resource); + } +} + +static void +surface_left_output (MetaWaylandSurface *surface, + MetaWaylandOutput *wayland_output) +{ + GList *iter; + struct wl_resource *resource; + + for (iter = wayland_output->resources; iter != NULL; iter = iter->next) + { + resource = iter->data; + + if (wl_resource_get_client (resource) != + wl_resource_get_client (surface->resource)) + continue; + + wl_surface_send_leave (surface->resource, resource); + } +} + +static void +set_surface_is_on_output (MetaWaylandSurface *surface, + MetaWaylandOutput *wayland_output, + gboolean is_on_output); + +static void +surface_handle_output_destroy (MetaWaylandOutput *wayland_output, + MetaWaylandSurface *surface) +{ + set_surface_is_on_output (surface, wayland_output, FALSE); +} + +static void +set_surface_is_on_output (MetaWaylandSurface *surface, + MetaWaylandOutput *wayland_output, + gboolean is_on_output) +{ + gpointer orig_id; + gboolean was_on_output = g_hash_table_lookup_extended (surface->outputs_to_destroy_notify_id, + wayland_output, + NULL, &orig_id); + + if (!was_on_output && is_on_output) + { + gulong id; + + id = g_signal_connect (wayland_output, "output-destroyed", + G_CALLBACK (surface_handle_output_destroy), + surface); + g_hash_table_insert (surface->outputs_to_destroy_notify_id, wayland_output, + GSIZE_TO_POINTER ((gsize)id)); + surface_entered_output (surface, wayland_output); + } + else if (was_on_output && !is_on_output) + { + g_hash_table_remove (surface->outputs_to_destroy_notify_id, wayland_output); + g_signal_handler_disconnect (wayland_output, (gulong) GPOINTER_TO_SIZE (orig_id)); + surface_left_output (surface, wayland_output); + } +} + +static void +update_surface_output_state (gpointer key, gpointer value, gpointer user_data) +{ + MetaWaylandOutput *wayland_output = value; + MetaWaylandSurface *surface = user_data; + MetaLogicalMonitor *logical_monitor; + gboolean is_on_logical_monitor; + + g_assert (surface->role); + + logical_monitor = wayland_output->logical_monitor; + if (!logical_monitor) + { + set_surface_is_on_output (surface, wayland_output, FALSE); + return; + } + + is_on_logical_monitor = + meta_wayland_surface_role_is_on_logical_monitor (surface->role, + logical_monitor); + set_surface_is_on_output (surface, wayland_output, is_on_logical_monitor); +} + +static void +surface_output_disconnect_signal (gpointer key, gpointer value, gpointer user_data) +{ + g_signal_handler_disconnect (key, (gulong) GPOINTER_TO_SIZE (value)); +} + +void +meta_wayland_surface_update_outputs (MetaWaylandSurface *surface) +{ + if (!surface->compositor) + return; + + g_hash_table_foreach (surface->compositor->outputs, + update_surface_output_state, + surface); +} + +void +meta_wayland_surface_update_outputs_recursively (MetaWaylandSurface *surface) +{ + MetaWaylandSurface *subsurface_surface; + + meta_wayland_surface_update_outputs (surface); + + META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (surface, subsurface_surface) + meta_wayland_surface_update_outputs_recursively (subsurface_surface); +} + +void +meta_wayland_surface_notify_unmapped (MetaWaylandSurface *surface) +{ + g_signal_emit (surface, surface_signals[SURFACE_UNMAPPED], 0); +} + +static void +unlink_note (GNode *node, + gpointer data) +{ + g_node_unlink (node); +} + +static void +wl_surface_destructor (struct wl_resource *resource) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); + MetaWaylandCompositor *compositor = surface->compositor; + MetaWaylandFrameCallback *cb, *next; + + g_signal_emit (surface, surface_signals[SURFACE_DESTROY], 0); + + g_clear_object (&surface->role); + + if (surface->unassigned.buffer) + { + meta_wayland_surface_unref_buffer_use_count (surface); + g_clear_object (&surface->unassigned.buffer); + } + + if (surface->buffer_held) + meta_wayland_surface_unref_buffer_use_count (surface); + g_clear_pointer (&surface->texture, cogl_object_unref); + g_clear_object (&surface->buffer_ref.buffer); + + g_clear_object (&surface->cached_state); + g_clear_object (&surface->pending_state); + + if (surface->opaque_region) + cairo_region_destroy (surface->opaque_region); + if (surface->input_region) + cairo_region_destroy (surface->input_region); + + meta_wayland_compositor_remove_frame_callback_surface (compositor, surface); + + g_hash_table_foreach (surface->outputs_to_destroy_notify_id, + surface_output_disconnect_signal, + surface); + g_hash_table_unref (surface->outputs_to_destroy_notify_id); + + wl_list_for_each_safe (cb, next, + &surface->unassigned.pending_frame_callback_list, + link) + wl_resource_destroy (cb->resource); + + if (surface->resource) + wl_resource_set_user_data (surface->resource, NULL); + + if (surface->wl_subsurface) + wl_resource_destroy (surface->wl_subsurface); + + if (surface->subsurface_branch_node) + { + g_node_children_foreach (surface->subsurface_branch_node, + G_TRAVERSE_NON_LEAVES, + unlink_note, + NULL); + g_clear_pointer (&surface->subsurface_branch_node, g_node_destroy); + } + + g_hash_table_destroy (surface->shortcut_inhibited_seats); + + g_object_unref (surface); + + meta_wayland_compositor_repick (compositor); +} + +MetaWaylandSurface * +meta_wayland_surface_create (MetaWaylandCompositor *compositor, + struct wl_client *client, + struct wl_resource *compositor_resource, + guint32 id) +{ + MetaWaylandSurface *surface = g_object_new (META_TYPE_WAYLAND_SURFACE, NULL); + int surface_version; + + surface->compositor = compositor; + surface->scale = 1; + + surface_version = wl_resource_get_version (compositor_resource); + surface->resource = wl_resource_create (client, + &wl_surface_interface, + surface_version, + id); + wl_resource_set_implementation (surface->resource, + &meta_wayland_wl_surface_interface, + surface, + wl_surface_destructor); + + wl_list_init (&surface->unassigned.pending_frame_callback_list); + + surface->outputs_to_destroy_notify_id = g_hash_table_new (NULL, NULL); + surface->shortcut_inhibited_seats = g_hash_table_new (NULL, NULL); + + meta_wayland_compositor_notify_surface_id (compositor, id, surface); + + return surface; +} + +gboolean +meta_wayland_surface_begin_grab_op (MetaWaylandSurface *surface, + MetaWaylandSeat *seat, + MetaGrabOp grab_op, + gfloat x, + gfloat y) +{ + MetaWindow *window = meta_wayland_surface_get_window (surface); + + if (grab_op == META_GRAB_OP_NONE) + return FALSE; + + /* This is an input driven operation so we set frame_action to + constrain it in the same way as it would be if the window was + being moved/resized via a SSD event. */ + return meta_display_begin_grab_op (window->display, + window, + grab_op, + TRUE, /* pointer_already_grabbed */ + TRUE, /* frame_action */ + 1, /* button. XXX? */ + 0, /* modmask */ + meta_display_get_current_time_roundtrip (window->display), + x, y); +} + +/** + * meta_wayland_shell_init: + * @compositor: The #MetaWaylandCompositor object + * + * Initializes the Wayland interfaces providing features that deal with + * desktop-specific conundrums, like XDG shell, wl_shell (deprecated), etc. + */ +void +meta_wayland_shell_init (MetaWaylandCompositor *compositor) +{ + meta_wayland_xdg_shell_init (compositor); + meta_wayland_legacy_xdg_shell_init (compositor); + meta_wayland_wl_shell_init (compositor); + meta_wayland_init_gtk_shell (compositor); + meta_wayland_init_viewporter (compositor); +} + +void +meta_wayland_surface_configure_notify (MetaWaylandSurface *surface, + MetaWaylandWindowConfiguration *configuration) +{ + MetaWaylandShellSurface *shell_surface = + META_WAYLAND_SHELL_SURFACE (surface->role); + + g_signal_emit (surface, surface_signals[SURFACE_CONFIGURE], 0); + + meta_wayland_shell_surface_configure (shell_surface, configuration); +} + +void +meta_wayland_surface_ping (MetaWaylandSurface *surface, + guint32 serial) +{ + MetaWaylandShellSurface *shell_surface = + META_WAYLAND_SHELL_SURFACE (surface->role); + + meta_wayland_shell_surface_ping (shell_surface, serial); +} + +void +meta_wayland_surface_delete (MetaWaylandSurface *surface) +{ + MetaWaylandShellSurface *shell_surface = + META_WAYLAND_SHELL_SURFACE (surface->role); + + meta_wayland_shell_surface_close (shell_surface); +} + +void +meta_wayland_surface_window_managed (MetaWaylandSurface *surface, + MetaWindow *window) +{ + MetaWaylandShellSurface *shell_surface = + META_WAYLAND_SHELL_SURFACE (surface->role); + + meta_wayland_shell_surface_managed (shell_surface, window); +} + +void +meta_wayland_surface_drag_dest_focus_in (MetaWaylandSurface *surface, + MetaWaylandDataOffer *offer) +{ + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + MetaWaylandDataDevice *data_device = &compositor->seat->data_device; + + surface->dnd.funcs->focus_in (data_device, surface, offer); +} + +void +meta_wayland_surface_drag_dest_motion (MetaWaylandSurface *surface, + const ClutterEvent *event) +{ + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + MetaWaylandDataDevice *data_device = &compositor->seat->data_device; + + surface->dnd.funcs->motion (data_device, surface, event); +} + +void +meta_wayland_surface_drag_dest_focus_out (MetaWaylandSurface *surface) +{ + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + MetaWaylandDataDevice *data_device = &compositor->seat->data_device; + + surface->dnd.funcs->focus_out (data_device, surface); +} + +void +meta_wayland_surface_drag_dest_drop (MetaWaylandSurface *surface) +{ + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + MetaWaylandDataDevice *data_device = &compositor->seat->data_device; + + surface->dnd.funcs->drop (data_device, surface); +} + +void +meta_wayland_surface_drag_dest_update (MetaWaylandSurface *surface) +{ + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + MetaWaylandDataDevice *data_device = &compositor->seat->data_device; + + surface->dnd.funcs->update (data_device, surface); +} + +MetaWaylandSurface * +meta_wayland_surface_get_toplevel (MetaWaylandSurface *surface) +{ + if (surface->role) + return meta_wayland_surface_role_get_toplevel (surface->role); + else + return NULL; +} + +MetaWindow * +meta_wayland_surface_get_toplevel_window (MetaWaylandSurface *surface) +{ + MetaWaylandSurface *toplevel; + + toplevel = meta_wayland_surface_get_toplevel (surface); + if (toplevel) + return meta_wayland_surface_get_window (toplevel); + else + return NULL; +} + +void +meta_wayland_surface_get_relative_coordinates (MetaWaylandSurface *surface, + float abs_x, + float abs_y, + float *sx, + float *sy) +{ + MetaWaylandSurfaceRoleClass *surface_role_class = + META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface->role); + + surface_role_class->get_relative_coordinates (surface->role, + abs_x, abs_y, + sx, sy); +} + +void +meta_wayland_surface_get_absolute_coordinates (MetaWaylandSurface *surface, + float sx, + float sy, + float *x, + float *y) +{ + ClutterActor *actor = + CLUTTER_ACTOR (meta_wayland_surface_get_actor (surface)); + graphene_point3d_t sv = { + .x = sx, + .y = sy, + }; + graphene_point3d_t v = { 0 }; + + clutter_actor_apply_relative_transform_to_point (actor, NULL, &sv, &v); + + *x = v.x; + *y = v.y; +} + +static void +meta_wayland_surface_init (MetaWaylandSurface *surface) +{ + surface->pending_state = g_object_new (META_TYPE_WAYLAND_SURFACE_STATE, NULL); + surface->subsurface_branch_node = g_node_new (surface); + surface->subsurface_leaf_node = + g_node_prepend_data (surface->subsurface_branch_node, surface); + + g_signal_connect (surface, "geometry-changed", + G_CALLBACK (meta_wayland_surface_update_outputs_recursively), + NULL); +} + +static void +meta_wayland_surface_class_init (MetaWaylandSurfaceClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + surface_signals[SURFACE_DESTROY] = + g_signal_new ("destroy", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + surface_signals[SURFACE_UNMAPPED] = + g_signal_new ("unmapped", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + surface_signals[SURFACE_CONFIGURE] = + g_signal_new ("configure", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + surface_signals[SURFACE_SHORTCUTS_INHIBITED] = + g_signal_new ("shortcuts-inhibited", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + surface_signals[SURFACE_SHORTCUTS_RESTORED] = + g_signal_new ("shortcuts-restored", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + surface_signals[SURFACE_GEOMETRY_CHANGED] = + g_signal_new ("geometry-changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + surface_signals[SURFACE_PRE_STATE_APPLIED] = + g_signal_new ("pre-state-applied", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +static void +meta_wayland_surface_role_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaWaylandSurfaceRole *surface_role = META_WAYLAND_SURFACE_ROLE (object); + MetaWaylandSurfaceRolePrivate *priv = + meta_wayland_surface_role_get_instance_private (surface_role); + + switch (prop_id) + { + case SURFACE_ROLE_PROP_SURFACE: + priv->surface = g_value_get_object (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_wayland_surface_role_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaWaylandSurfaceRole *surface_role = META_WAYLAND_SURFACE_ROLE (object); + MetaWaylandSurfaceRolePrivate *priv = + meta_wayland_surface_role_get_instance_private (surface_role); + + switch (prop_id) + { + case SURFACE_ROLE_PROP_SURFACE: + g_value_set_object (value, priv->surface); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_wayland_surface_role_init (MetaWaylandSurfaceRole *role) +{ +} + +static void +meta_wayland_surface_role_class_init (MetaWaylandSurfaceRoleClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->set_property = meta_wayland_surface_role_set_property; + object_class->get_property = meta_wayland_surface_role_get_property; + + g_object_class_install_property (object_class, + SURFACE_ROLE_PROP_SURFACE, + g_param_spec_object ("surface", + "MetaWaylandSurface", + "The MetaWaylandSurface instance", + META_TYPE_WAYLAND_SURFACE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); +} + +static void +meta_wayland_surface_role_assigned (MetaWaylandSurfaceRole *surface_role) +{ + META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface_role)->assigned (surface_role); +} + +static void +meta_wayland_surface_role_pre_apply_state (MetaWaylandSurfaceRole *surface_role, + MetaWaylandSurfaceState *pending) +{ + MetaWaylandSurfaceRoleClass *klass; + + klass = META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface_role); + if (klass->pre_apply_state) + klass->pre_apply_state (surface_role, pending); +} + +static void +meta_wayland_surface_role_post_apply_state (MetaWaylandSurfaceRole *surface_role, + MetaWaylandSurfaceState *pending) +{ + MetaWaylandSurfaceRoleClass *klass; + + klass = META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface_role); + if (klass->post_apply_state) + klass->post_apply_state (surface_role, pending); +} + +static void +meta_wayland_surface_role_apply_state (MetaWaylandSurfaceRole *surface_role, + MetaWaylandSurfaceState *pending) +{ + META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface_role)->apply_state (surface_role, + pending); +} + +static gboolean +meta_wayland_surface_role_is_on_logical_monitor (MetaWaylandSurfaceRole *surface_role, + MetaLogicalMonitor *logical_monitor) +{ + MetaWaylandSurfaceRoleClass *klass; + + klass = META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface_role); + if (klass->is_on_logical_monitor) + return klass->is_on_logical_monitor (surface_role, logical_monitor); + else + return FALSE; +} + +static MetaWaylandSurface * +meta_wayland_surface_role_get_toplevel (MetaWaylandSurfaceRole *surface_role) +{ + MetaWaylandSurfaceRoleClass *klass; + + klass = META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface_role); + if (klass->get_toplevel) + return klass->get_toplevel (surface_role); + else + return NULL; +} + +static MetaWindow * +meta_wayland_surface_role_get_window (MetaWaylandSurfaceRole *surface_role) +{ + MetaWaylandSurfaceRoleClass *klass; + + klass = META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface_role); + + if (klass->get_window) + return klass->get_window (surface_role); + else + return NULL; +} + +MetaWindow * +meta_wayland_surface_get_window (MetaWaylandSurface *surface) +{ + if (!surface->role) + return NULL; + + return meta_wayland_surface_role_get_window (surface->role); +} + +static gboolean +meta_wayland_surface_role_should_cache_state (MetaWaylandSurfaceRole *surface_role) +{ + MetaWaylandSurfaceRoleClass *klass; + + klass = META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface_role); + if (klass->should_cache_state) + return klass->should_cache_state (surface_role); + else + return FALSE; +} + +gboolean +meta_wayland_surface_should_cache_state (MetaWaylandSurface *surface) +{ + if (!surface->role) + return FALSE; + + return meta_wayland_surface_role_should_cache_state (surface->role); +} + +static void +meta_wayland_surface_role_notify_subsurface_state_changed (MetaWaylandSurfaceRole *surface_role) +{ + MetaWaylandSurfaceRoleClass *klass; + + klass = META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface_role); + g_return_if_fail (klass->notify_subsurface_state_changed); + + klass->notify_subsurface_state_changed (surface_role); +} + +void +meta_wayland_surface_notify_subsurface_state_changed (MetaWaylandSurface *surface) +{ + if (surface->role) + meta_wayland_surface_role_notify_subsurface_state_changed (surface->role); +} + +MetaWaylandSurface * +meta_wayland_surface_role_get_surface (MetaWaylandSurfaceRole *role) +{ + MetaWaylandSurfaceRolePrivate *priv = + meta_wayland_surface_role_get_instance_private (role); + + return priv->surface; +} + +cairo_region_t * +meta_wayland_surface_calculate_input_region (MetaWaylandSurface *surface) +{ + cairo_region_t *region; + cairo_rectangle_int_t buffer_rect; + + if (!surface->buffer_ref.buffer) + return NULL; + + buffer_rect = (cairo_rectangle_int_t) { + .width = meta_wayland_surface_get_width (surface), + .height = meta_wayland_surface_get_height (surface), + }; + region = cairo_region_create_rectangle (&buffer_rect); + + if (surface->input_region) + cairo_region_intersect (region, surface->input_region); + + return region; +} + +void +meta_wayland_surface_inhibit_shortcuts (MetaWaylandSurface *surface, + MetaWaylandSeat *seat) +{ + g_hash_table_add (surface->shortcut_inhibited_seats, seat); + g_signal_emit (surface, surface_signals[SURFACE_SHORTCUTS_INHIBITED], 0); +} + +void +meta_wayland_surface_restore_shortcuts (MetaWaylandSurface *surface, + MetaWaylandSeat *seat) +{ + g_signal_emit (surface, surface_signals[SURFACE_SHORTCUTS_RESTORED], 0); + g_hash_table_remove (surface->shortcut_inhibited_seats, seat); +} + +gboolean +meta_wayland_surface_is_shortcuts_inhibited (MetaWaylandSurface *surface, + MetaWaylandSeat *seat) +{ + if (surface->shortcut_inhibited_seats == NULL) + return FALSE; + + return g_hash_table_contains (surface->shortcut_inhibited_seats, seat); +} + +CoglTexture * +meta_wayland_surface_get_texture (MetaWaylandSurface *surface) +{ + return surface->texture; +} + +MetaSurfaceActor * +meta_wayland_surface_get_actor (MetaWaylandSurface *surface) +{ + if (!surface->role || !META_IS_WAYLAND_ACTOR_SURFACE (surface->role)) + return NULL; + + return meta_wayland_actor_surface_get_actor (META_WAYLAND_ACTOR_SURFACE (surface->role)); +} + +void +meta_wayland_surface_notify_geometry_changed (MetaWaylandSurface *surface) +{ + g_signal_emit (surface, surface_signals[SURFACE_GEOMETRY_CHANGED], 0); +} + +int +meta_wayland_surface_get_width (MetaWaylandSurface *surface) +{ + if (surface->viewport.has_dst_size) + { + return surface->viewport.dst_width; + } + else if (surface->viewport.has_src_rect) + { + return ceilf (surface->viewport.src_rect.size.width); + } + else + { + int width; + + if (meta_monitor_transform_is_rotated (surface->buffer_transform)) + width = get_buffer_height (surface); + else + width = get_buffer_width (surface); + + return width / surface->scale; + } +} + +int +meta_wayland_surface_get_height (MetaWaylandSurface *surface) +{ + if (surface->viewport.has_dst_size) + { + return surface->viewport.dst_height; + } + else if (surface->viewport.has_src_rect) + { + return ceilf (surface->viewport.src_rect.size.height); + } + else + { + int height; + + if (meta_monitor_transform_is_rotated (surface->buffer_transform)) + height = get_buffer_width (surface); + else + height = get_buffer_height (surface); + + return height / surface->scale; + } +} diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h new file mode 100644 index 000000000..7e8814c23 --- /dev/null +++ b/src/wayland/meta-wayland-surface.h @@ -0,0 +1,375 @@ +/* + * Copyright (C) 2013 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_WAYLAND_SURFACE_H +#define META_WAYLAND_SURFACE_H + +#include <cairo.h> +#include <glib.h> +#include <wayland-server.h> +#include <xkbcommon/xkbcommon.h> + +#include "backends/meta-monitor-manager-private.h" +#include "clutter/clutter.h" +#include "compositor/meta-shaped-texture-private.h" +#include "compositor/meta-surface-actor.h" +#include "meta/meta-cursor-tracker.h" +#include "wayland/meta-wayland-pointer-constraints.h" +#include "wayland/meta-wayland-types.h" + +#define META_TYPE_WAYLAND_SURFACE (meta_wayland_surface_get_type ()) +G_DECLARE_FINAL_TYPE (MetaWaylandSurface, + meta_wayland_surface, + META, WAYLAND_SURFACE, + GObject); + +#define META_TYPE_WAYLAND_SURFACE_ROLE (meta_wayland_surface_role_get_type ()) +G_DECLARE_DERIVABLE_TYPE (MetaWaylandSurfaceRole, meta_wayland_surface_role, + META, WAYLAND_SURFACE_ROLE, GObject); + +#define META_TYPE_WAYLAND_SURFACE_STATE (meta_wayland_surface_state_get_type ()) +G_DECLARE_FINAL_TYPE (MetaWaylandSurfaceState, + meta_wayland_surface_state, + META, WAYLAND_SURFACE_STATE, + GObject) + +struct _MetaWaylandSurfaceRoleClass +{ + GObjectClass parent_class; + + void (*assigned) (MetaWaylandSurfaceRole *surface_role); + void (*pre_apply_state) (MetaWaylandSurfaceRole *surface_role, + MetaWaylandSurfaceState *pending); + void (*apply_state) (MetaWaylandSurfaceRole *surface_role, + MetaWaylandSurfaceState *pending); + void (*post_apply_state) (MetaWaylandSurfaceRole *surface_role, + MetaWaylandSurfaceState *pending); + gboolean (*is_on_logical_monitor) (MetaWaylandSurfaceRole *surface_role, + MetaLogicalMonitor *logical_monitor); + MetaWaylandSurface * (*get_toplevel) (MetaWaylandSurfaceRole *surface_role); + gboolean (*should_cache_state) (MetaWaylandSurfaceRole *surface_role); + void (*notify_subsurface_state_changed) (MetaWaylandSurfaceRole *surface_role); + void (*get_relative_coordinates) (MetaWaylandSurfaceRole *surface_role, + float abs_x, + float abs_y, + float *out_sx, + float *out_sy); + MetaWindow * (*get_window) (MetaWaylandSurfaceRole *surface_role); +}; + +struct _MetaWaylandSurfaceState +{ + GObject parent; + + /* wl_surface.attach */ + gboolean newly_attached; + MetaWaylandBuffer *buffer; + gulong buffer_destroy_handler_id; + int32_t dx; + int32_t dy; + + int scale; + + /* wl_surface.damage */ + cairo_region_t *surface_damage; + /* wl_surface.damage_buffer */ + cairo_region_t *buffer_damage; + + cairo_region_t *input_region; + gboolean input_region_set; + cairo_region_t *opaque_region; + gboolean opaque_region_set; + + /* wl_surface.frame */ + struct wl_list frame_callback_list; + + MetaRectangle new_geometry; + gboolean has_new_geometry; + + gboolean has_acked_configure_serial; + uint32_t acked_configure_serial; + + /* pending min/max size in window geometry coordinates */ + gboolean has_new_min_size; + int new_min_width; + int new_min_height; + gboolean has_new_max_size; + int new_max_width; + int new_max_height; + + gboolean has_new_buffer_transform; + MetaMonitorTransform buffer_transform; + gboolean has_new_viewport_src_rect; + graphene_rect_t viewport_src_rect; + gboolean has_new_viewport_dst_size; + int viewport_dst_width; + int viewport_dst_height; + + GSList *subsurface_placement_ops; +}; + +struct _MetaWaylandDragDestFuncs +{ + void (* focus_in) (MetaWaylandDataDevice *data_device, + MetaWaylandSurface *surface, + MetaWaylandDataOffer *offer); + void (* focus_out) (MetaWaylandDataDevice *data_device, + MetaWaylandSurface *surface); + void (* motion) (MetaWaylandDataDevice *data_device, + MetaWaylandSurface *surface, + const ClutterEvent *event); + void (* drop) (MetaWaylandDataDevice *data_device, + MetaWaylandSurface *surface); + void (* update) (MetaWaylandDataDevice *data_device, + MetaWaylandSurface *surface); +}; + +struct _MetaWaylandSurface +{ + GObject parent; + + /* Generic stuff */ + struct wl_resource *resource; + MetaWaylandCompositor *compositor; + MetaWaylandSurfaceRole *role; + cairo_region_t *input_region; + cairo_region_t *opaque_region; + int scale; + int32_t offset_x, offset_y; + GNode *subsurface_branch_node; + GNode *subsurface_leaf_node; + GHashTable *outputs_to_destroy_notify_id; + MetaMonitorTransform buffer_transform; + + CoglTexture *texture; + + /* Buffer reference state. */ + struct { + MetaWaylandBuffer *buffer; + unsigned int use_count; + } buffer_ref; + + /* Buffer renderer state. */ + gboolean buffer_held; + + /* Intermediate state for when no role has been assigned. */ + struct { + struct wl_list pending_frame_callback_list; + MetaWaylandBuffer *buffer; + } unassigned; + + struct { + const MetaWaylandDragDestFuncs *funcs; + } dnd; + + /* All the pending state that wl_surface.commit will apply. */ + MetaWaylandSurfaceState *pending_state; + /* State cached due to inter-surface synchronization such. */ + MetaWaylandSurfaceState *cached_state; + + /* Extension resources. */ + struct wl_resource *wl_subsurface; + + /* wl_subsurface stuff. */ + struct { + MetaWaylandSurface *parent; + struct wl_listener parent_destroy_listener; + + int x; + int y; + + /* When the surface is synchronous, its state will be applied + * when the parent is committed. This is done by moving the + * "real" pending state below to here when this surface is + * committed and in synchronous mode. + * + * When the parent surface is committed, we apply the pending + * state here. + */ + gboolean synchronous; + + int32_t pending_x; + int32_t pending_y; + gboolean pending_pos; + } sub; + + /* wp_viewport */ + struct { + struct wl_resource *resource; + gulong destroy_handler_id; + + gboolean has_src_rect; + graphene_rect_t src_rect; + + gboolean has_dst_size; + int dst_width; + int dst_height; + } viewport; + + /* table of seats for which shortcuts are inhibited */ + GHashTable *shortcut_inhibited_seats; +}; + +void meta_wayland_shell_init (MetaWaylandCompositor *compositor); + +MetaWaylandSurface *meta_wayland_surface_create (MetaWaylandCompositor *compositor, + struct wl_client *client, + struct wl_resource *compositor_resource, + guint32 id); + +MetaWaylandSurfaceState * + meta_wayland_surface_get_pending_state (MetaWaylandSurface *surface); + +MetaWaylandSurfaceState * + meta_wayland_surface_ensure_cached_state (MetaWaylandSurface *surface); + +void meta_wayland_surface_apply_cached_state (MetaWaylandSurface *surface); + +gboolean meta_wayland_surface_is_effectively_synchronized (MetaWaylandSurface *surface); + +gboolean meta_wayland_surface_assign_role (MetaWaylandSurface *surface, + GType role_type, + const char *first_property_name, + ...); + +MetaWaylandBuffer *meta_wayland_surface_get_buffer (MetaWaylandSurface *surface); + +void meta_wayland_surface_ref_buffer_use_count (MetaWaylandSurface *surface); + +void meta_wayland_surface_unref_buffer_use_count (MetaWaylandSurface *surface); + +void meta_wayland_surface_set_window (MetaWaylandSurface *surface, + MetaWindow *window); + +void meta_wayland_surface_configure_notify (MetaWaylandSurface *surface, + MetaWaylandWindowConfiguration *configuration); + +void meta_wayland_surface_ping (MetaWaylandSurface *surface, + guint32 serial); +void meta_wayland_surface_delete (MetaWaylandSurface *surface); + +/* Drag dest functions */ +void meta_wayland_surface_drag_dest_focus_in (MetaWaylandSurface *surface, + MetaWaylandDataOffer *offer); +void meta_wayland_surface_drag_dest_motion (MetaWaylandSurface *surface, + const ClutterEvent *event); +void meta_wayland_surface_drag_dest_focus_out (MetaWaylandSurface *surface); +void meta_wayland_surface_drag_dest_drop (MetaWaylandSurface *surface); +void meta_wayland_surface_drag_dest_update (MetaWaylandSurface *surface); + +void meta_wayland_surface_update_outputs (MetaWaylandSurface *surface); + +MetaWaylandSurface *meta_wayland_surface_get_toplevel (MetaWaylandSurface *surface); + +MetaWindow * meta_wayland_surface_get_window (MetaWaylandSurface *surface); + +gboolean meta_wayland_surface_should_cache_state (MetaWaylandSurface *surface); + +MetaWindow * meta_wayland_surface_get_toplevel_window (MetaWaylandSurface *surface); + +void meta_wayland_surface_queue_pending_frame_callbacks (MetaWaylandSurface *surface); + +void meta_wayland_surface_queue_pending_state_frame_callbacks (MetaWaylandSurface *surface, + MetaWaylandSurfaceState *pending); + +void meta_wayland_surface_get_relative_coordinates (MetaWaylandSurface *surface, + float abs_x, + float abs_y, + float *sx, + float *sy); + +void meta_wayland_surface_get_absolute_coordinates (MetaWaylandSurface *surface, + float sx, + float sy, + float *x, + float *y); + +MetaWaylandSurface * meta_wayland_surface_role_get_surface (MetaWaylandSurfaceRole *role); + +cairo_region_t * meta_wayland_surface_calculate_input_region (MetaWaylandSurface *surface); + + +gboolean meta_wayland_surface_begin_grab_op (MetaWaylandSurface *surface, + MetaWaylandSeat *seat, + MetaGrabOp grab_op, + gfloat x, + gfloat y); + +void meta_wayland_surface_window_managed (MetaWaylandSurface *surface, + MetaWindow *window); + +void meta_wayland_surface_inhibit_shortcuts (MetaWaylandSurface *surface, + MetaWaylandSeat *seat); + +void meta_wayland_surface_restore_shortcuts (MetaWaylandSurface *surface, + MetaWaylandSeat *seat); + +gboolean meta_wayland_surface_is_shortcuts_inhibited (MetaWaylandSurface *surface, + MetaWaylandSeat *seat); + +CoglTexture * meta_wayland_surface_get_texture (MetaWaylandSurface *surface); + +MetaSurfaceActor * meta_wayland_surface_get_actor (MetaWaylandSurface *surface); + +void meta_wayland_surface_notify_geometry_changed (MetaWaylandSurface *surface); + +void meta_wayland_surface_notify_subsurface_state_changed (MetaWaylandSurface *surface); + +void meta_wayland_surface_notify_unmapped (MetaWaylandSurface *surface); + +void meta_wayland_surface_update_outputs_recursively (MetaWaylandSurface *surface); + +int meta_wayland_surface_get_width (MetaWaylandSurface *surface); +int meta_wayland_surface_get_height (MetaWaylandSurface *surface); + +static inline GNode * +meta_get_next_subsurface_sibling (GNode *n) +{ + GNode *next; + + if (!n) + return NULL; + + next = g_node_next_sibling (n); + if (!next) + return NULL; + if (!G_NODE_IS_LEAF (next)) + return next; + else + return meta_get_next_subsurface_sibling (next); +} + +static inline GNode * +meta_get_first_subsurface_node (MetaWaylandSurface *surface) +{ + GNode *n; + + n = g_node_first_child (surface->subsurface_branch_node); + if (!G_NODE_IS_LEAF (n)) + return n; + else + return meta_get_next_subsurface_sibling (n); +} + +#define META_WAYLAND_SURFACE_FOREACH_SUBSURFACE(surface, subsurface) \ + for (GNode *G_PASTE(__n, __LINE__) = meta_get_first_subsurface_node ((surface)); \ + (subsurface = (G_PASTE (__n, __LINE__) ? G_PASTE (__n, __LINE__)->data : NULL)); \ + G_PASTE (__n, __LINE__) = meta_get_next_subsurface_sibling (G_PASTE (__n, __LINE__))) + +#endif diff --git a/src/wayland/meta-wayland-tablet-cursor-surface.c b/src/wayland/meta-wayland-tablet-cursor-surface.c new file mode 100644 index 000000000..421b7c20a --- /dev/null +++ b/src/wayland/meta-wayland-tablet-cursor-surface.c @@ -0,0 +1,43 @@ +/* + * Wayland Support + * + * Copyright (C) 2016 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "wayland/meta-wayland-tablet-cursor-surface.h" + +struct _MetaWaylandTabletCursorSurface +{ + MetaWaylandCursorSurface parent; +}; + +G_DEFINE_TYPE (MetaWaylandTabletCursorSurface, + meta_wayland_tablet_cursor_surface, + META_TYPE_WAYLAND_CURSOR_SURFACE) + +static void +meta_wayland_tablet_cursor_surface_init (MetaWaylandTabletCursorSurface *role) +{ +} + +static void +meta_wayland_tablet_cursor_surface_class_init (MetaWaylandTabletCursorSurfaceClass *klass) +{ +} diff --git a/src/wayland/meta-wayland-tablet-cursor-surface.h b/src/wayland/meta-wayland-tablet-cursor-surface.h new file mode 100644 index 000000000..df41e832e --- /dev/null +++ b/src/wayland/meta-wayland-tablet-cursor-surface.h @@ -0,0 +1,33 @@ +/* + * Wayland Support + * + * Copyright (C) 2016 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_WAYLAND_TABLET_CURSOR_SURFACE_H +#define META_WAYLAND_TABLET_CURSOR_SURFACE_H + +#include "wayland/meta-wayland-cursor-surface.h" + +#define META_TYPE_WAYLAND_TABLET_CURSOR_SURFACE (meta_wayland_tablet_cursor_surface_get_type ()) +G_DECLARE_FINAL_TYPE (MetaWaylandTabletCursorSurface, + meta_wayland_tablet_cursor_surface, + META, WAYLAND_TABLET_CURSOR_SURFACE, + MetaWaylandCursorSurface) + +#endif /* META_WAYLAND_TABLET_CURSOR_SURFACE_H */ diff --git a/src/wayland/meta-wayland-tablet-manager.c b/src/wayland/meta-wayland-tablet-manager.c new file mode 100644 index 000000000..7810f7b59 --- /dev/null +++ b/src/wayland/meta-wayland-tablet-manager.c @@ -0,0 +1,271 @@ +/* + * Wayland Support + * + * Copyright (C) 2015 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#include "config.h" + +#include <glib.h> + +#include <wayland-server.h> + +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-wayland-tablet-manager.h" +#include "wayland/meta-wayland-tablet-seat.h" +#include "wayland/meta-wayland-tablet-tool.h" + +#include "tablet-unstable-v2-server-protocol.h" + +static void +unbind_resource (struct wl_resource *resource) +{ + wl_list_remove (wl_resource_get_link (resource)); +} + +static gboolean +is_tablet_device (ClutterInputDevice *device) +{ + ClutterInputDeviceType device_type; + + if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER) + return FALSE; + + device_type = clutter_input_device_get_device_type (device); + + return (device_type == CLUTTER_TABLET_DEVICE || + device_type == CLUTTER_PEN_DEVICE || + device_type == CLUTTER_ERASER_DEVICE || + device_type == CLUTTER_CURSOR_DEVICE || + device_type == CLUTTER_PAD_DEVICE); +} + +static void +tablet_manager_get_tablet_seat (struct wl_client *client, + struct wl_resource *resource, + guint32 id, + struct wl_resource *seat_resource) +{ + MetaWaylandTabletManager *tablet_manager = wl_resource_get_user_data (resource); + MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); + MetaWaylandTabletSeat *tablet_seat; + + tablet_seat = meta_wayland_tablet_manager_ensure_seat (tablet_manager, seat); + meta_wayland_tablet_seat_create_new_resource (tablet_seat, client, + resource, id); +} + +static void +tablet_manager_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static const struct zwp_tablet_manager_v2_interface tablet_manager_interface = { + tablet_manager_get_tablet_seat, + tablet_manager_destroy +}; + +static void +bind_tablet_manager (struct wl_client *client, + void *data, + uint32_t version, + uint32_t id) +{ + MetaWaylandCompositor *compositor = data; + MetaWaylandTabletManager *tablet_manager = compositor->tablet_manager; + struct wl_resource *resource; + + resource = wl_resource_create (client, &zwp_tablet_manager_v2_interface, + MIN (version, 1), id); + wl_resource_set_implementation (resource, &tablet_manager_interface, + tablet_manager, unbind_resource); + wl_resource_set_user_data (resource, tablet_manager); + wl_list_insert (&tablet_manager->resource_list, + wl_resource_get_link (resource)); +} + +static MetaWaylandTabletManager * +meta_wayland_tablet_manager_new (MetaWaylandCompositor *compositor) +{ + MetaWaylandTabletManager *tablet_manager; + + tablet_manager = g_slice_new0 (MetaWaylandTabletManager); + tablet_manager->compositor = compositor; + tablet_manager->wl_display = compositor->wayland_display; + tablet_manager->seats = g_hash_table_new_full (NULL, NULL, NULL, + (GDestroyNotify) meta_wayland_tablet_seat_free); + wl_list_init (&tablet_manager->resource_list); + + wl_global_create (tablet_manager->wl_display, + &zwp_tablet_manager_v2_interface, 1, + compositor, bind_tablet_manager); + + return tablet_manager; +} + +void +meta_wayland_tablet_manager_init (MetaWaylandCompositor *compositor) +{ + compositor->tablet_manager = meta_wayland_tablet_manager_new (compositor); +} + +void +meta_wayland_tablet_manager_free (MetaWaylandTabletManager *tablet_manager) +{ + g_hash_table_destroy (tablet_manager->seats); + g_slice_free (MetaWaylandTabletManager, tablet_manager); +} + +static MetaWaylandTabletSeat * +meta_wayland_tablet_manager_lookup_seat (MetaWaylandTabletManager *manager, + ClutterInputDevice *device) +{ + MetaWaylandTabletSeat *tablet_seat; + MetaWaylandSeat *seat; + GHashTableIter iter; + + if (!device || !is_tablet_device (device)) + return NULL; + + g_hash_table_iter_init (&iter, manager->seats); + + while (g_hash_table_iter_next (&iter, (gpointer*) &seat, (gpointer*) &tablet_seat)) + { + if (meta_wayland_tablet_seat_lookup_tablet (tablet_seat, device) || + meta_wayland_tablet_seat_lookup_pad (tablet_seat, device)) + return tablet_seat; + } + + return NULL; +} + +gboolean +meta_wayland_tablet_manager_consumes_event (MetaWaylandTabletManager *manager, + const ClutterEvent *event) +{ + ClutterInputDevice *device = clutter_event_get_source_device (event); + + return meta_wayland_tablet_manager_lookup_seat (manager, device) != NULL; +} + +void +meta_wayland_tablet_manager_update (MetaWaylandTabletManager *manager, + const ClutterEvent *event) +{ + ClutterInputDevice *device = clutter_event_get_source_device (event); + MetaWaylandTabletSeat *tablet_seat; + + tablet_seat = meta_wayland_tablet_manager_lookup_seat (manager, device); + + if (!tablet_seat) + return; + + switch (event->type) + { + case CLUTTER_PROXIMITY_IN: + case CLUTTER_PROXIMITY_OUT: + case CLUTTER_BUTTON_PRESS: + case CLUTTER_BUTTON_RELEASE: + case CLUTTER_MOTION: + case CLUTTER_PAD_BUTTON_PRESS: + case CLUTTER_PAD_BUTTON_RELEASE: + case CLUTTER_PAD_RING: + case CLUTTER_PAD_STRIP: + meta_wayland_tablet_seat_update (tablet_seat, event); + break; + default: + break; + } +} + +gboolean +meta_wayland_tablet_manager_handle_event (MetaWaylandTabletManager *manager, + const ClutterEvent *event) +{ + ClutterInputDevice *device = clutter_event_get_source_device (event); + MetaWaylandTabletSeat *tablet_seat; + + tablet_seat = meta_wayland_tablet_manager_lookup_seat (manager, device); + + if (!tablet_seat) + return CLUTTER_EVENT_PROPAGATE; + + switch (event->type) + { + case CLUTTER_PROXIMITY_IN: + case CLUTTER_PROXIMITY_OUT: + case CLUTTER_BUTTON_PRESS: + case CLUTTER_BUTTON_RELEASE: + case CLUTTER_MOTION: + case CLUTTER_PAD_BUTTON_PRESS: + case CLUTTER_PAD_BUTTON_RELEASE: + case CLUTTER_PAD_RING: + case CLUTTER_PAD_STRIP: + return meta_wayland_tablet_seat_handle_event (tablet_seat, event); + default: + return CLUTTER_EVENT_PROPAGATE; + } +} + +MetaWaylandTabletSeat * +meta_wayland_tablet_manager_ensure_seat (MetaWaylandTabletManager *manager, + MetaWaylandSeat *seat) +{ + MetaWaylandTabletSeat *tablet_seat; + + tablet_seat = g_hash_table_lookup (manager->seats, seat); + + if (!tablet_seat) + { + tablet_seat = meta_wayland_tablet_seat_new (manager, seat); + g_hash_table_insert (manager->seats, seat, tablet_seat); + } + + return tablet_seat; +} + +void +meta_wayland_tablet_manager_update_cursor_position (MetaWaylandTabletManager *manager, + const ClutterEvent *event) +{ + MetaWaylandTabletSeat *tablet_seat = NULL; + MetaWaylandTabletTool *tool = NULL; + ClutterInputDeviceTool *device_tool; + ClutterInputDevice *device; + + device = clutter_event_get_source_device (event); + device_tool = clutter_event_get_device_tool (event); + + if (device) + tablet_seat = meta_wayland_tablet_manager_lookup_seat (manager, device); + + if (tablet_seat && device_tool) + tool = meta_wayland_tablet_seat_lookup_tool (tablet_seat, device_tool); + + if (tool) + { + gfloat new_x, new_y; + + clutter_event_get_coords (event, &new_x, &new_y); + meta_wayland_tablet_tool_set_cursor_position (tool, new_x, new_y); + } +} diff --git a/src/wayland/meta-wayland-tablet-manager.h b/src/wayland/meta-wayland-tablet-manager.h new file mode 100644 index 000000000..5d4b28c2d --- /dev/null +++ b/src/wayland/meta-wayland-tablet-manager.h @@ -0,0 +1,56 @@ +/* + * Wayland Support + * + * Copyright (C) 2015 Red Hat + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef META_WAYLAND_TABLET_MANAGER_H +#define META_WAYLAND_TABLET_MANAGER_H + +#include <glib.h> +#include <wayland-server.h> + +#include "wayland/meta-wayland-types.h" + +struct _MetaWaylandTabletManager +{ + MetaWaylandCompositor *compositor; + struct wl_display *wl_display; + struct wl_list resource_list; + + GHashTable *seats; +}; + +void meta_wayland_tablet_manager_init (MetaWaylandCompositor *compositor); +void meta_wayland_tablet_manager_free (MetaWaylandTabletManager *tablet_manager); + +gboolean meta_wayland_tablet_manager_consumes_event (MetaWaylandTabletManager *manager, + const ClutterEvent *event); +void meta_wayland_tablet_manager_update (MetaWaylandTabletManager *manager, + const ClutterEvent *event); +gboolean meta_wayland_tablet_manager_handle_event (MetaWaylandTabletManager *manager, + const ClutterEvent *event); + +MetaWaylandTabletSeat * + meta_wayland_tablet_manager_ensure_seat (MetaWaylandTabletManager *manager, + MetaWaylandSeat *seat); + +void meta_wayland_tablet_manager_update_cursor_position (MetaWaylandTabletManager *manager, + const ClutterEvent *event); + +#endif /* META_WAYLAND_TABLET_MANAGER_H */ diff --git a/src/wayland/meta-wayland-tablet-pad-group.c b/src/wayland/meta-wayland-tablet-pad-group.c new file mode 100644 index 000000000..4229f834a --- /dev/null +++ b/src/wayland/meta-wayland-tablet-pad-group.c @@ -0,0 +1,403 @@ +/* + * Wayland Support + * + * Copyright (C) 2016 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#include "config.h" + +#include <wayland-server.h> + +#include "compositor/meta-surface-actor-wayland.h" +#include "wayland/meta-wayland-tablet-pad-group.h" +#include "wayland/meta-wayland-tablet-pad-ring.h" +#include "wayland/meta-wayland-tablet-pad-strip.h" +#include "wayland/meta-wayland-tablet-pad.h" +#include "wayland/meta-wayland-tablet-seat.h" + +#ifdef HAVE_NATIVE_BACKEND +#include "backends/native/meta-backend-native.h" +#include "backends/native/meta-event-native.h" +#include "backends/native/meta-input-device-native.h" +#endif + +#include "tablet-unstable-v2-server-protocol.h" + +static void +unbind_resource (struct wl_resource *resource) +{ + wl_list_remove (wl_resource_get_link (resource)); +} + +MetaWaylandTabletPadGroup * +meta_wayland_tablet_pad_group_new (MetaWaylandTabletPad *pad) +{ + MetaWaylandTabletPadGroup *group; + + group = g_slice_new0 (MetaWaylandTabletPadGroup); + wl_list_init (&group->resource_list); + wl_list_init (&group->focus_resource_list); + group->pad = pad; + + return group; +} + +void +meta_wayland_tablet_pad_group_free (MetaWaylandTabletPadGroup *group) +{ + struct wl_resource *resource, *next; + + wl_resource_for_each_safe (resource, next, &group->resource_list) + { + wl_list_remove (wl_resource_get_link (resource)); + wl_list_init (wl_resource_get_link (resource)); + } + + g_list_free (group->rings); + g_list_free (group->strips); + + g_slice_free (MetaWaylandTabletPadGroup, group); +} + +static void +tablet_pad_group_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static const struct zwp_tablet_pad_group_v2_interface group_interface = { + tablet_pad_group_destroy +}; + +struct wl_resource * +meta_wayland_tablet_pad_group_create_new_resource (MetaWaylandTabletPadGroup *group, + struct wl_client *client, + struct wl_resource *pad_resource, + uint32_t id) +{ + struct wl_resource *resource; + + resource = wl_resource_create (client, &zwp_tablet_pad_group_v2_interface, + wl_resource_get_version (pad_resource), id); + wl_resource_set_implementation (resource, &group_interface, + group, unbind_resource); + wl_resource_set_user_data (resource, group); + wl_list_insert (&group->resource_list, wl_resource_get_link (resource)); + + return resource; +} + +struct wl_resource * +meta_wayland_tablet_pad_group_lookup_resource (MetaWaylandTabletPadGroup *group, + struct wl_client *client) +{ + struct wl_resource *resource; + + resource = wl_resource_find_for_client (&group->resource_list, client); + + if (!resource) + resource = wl_resource_find_for_client (&group->focus_resource_list, client); + + return resource; +} + +gboolean +meta_wayland_tablet_pad_group_has_button (MetaWaylandTabletPadGroup *group, + guint button) +{ +#ifdef HAVE_NATIVE_BACKEND + MetaBackend *backend = meta_get_backend (); + + if (META_IS_BACKEND_NATIVE (backend)) + { + struct libinput_device *libinput_device; + struct libinput_tablet_pad_mode_group *mode_group; + guint n_group; + + libinput_device = meta_input_device_native_get_libinput_device (group->pad->device); + n_group = g_list_index (group->pad->groups, group); + mode_group = libinput_device_tablet_pad_get_mode_group (libinput_device, n_group); + + return libinput_tablet_pad_mode_group_has_button (mode_group, button); + } + else +#endif + { + return g_list_length (group->pad->groups) == 1; + } +} + +static void +meta_wayland_tablet_pad_group_send_buttons (MetaWaylandTabletPadGroup *group, + struct wl_resource *resource) +{ + struct wl_array buttons; + guint i; + + wl_array_init (&buttons); + + for (i = 0; i < group->pad->n_buttons; i++) + { + uint32_t *pos; + + if (!meta_wayland_tablet_pad_group_has_button (group, i)) + continue; + + pos = wl_array_add (&buttons, sizeof (*pos)); + *pos = i; + } + + zwp_tablet_pad_group_v2_send_buttons (resource, &buttons); + wl_array_release (&buttons); +} + +void +meta_wayland_tablet_pad_group_notify (MetaWaylandTabletPadGroup *group, + struct wl_resource *resource) +{ + struct wl_client *client = wl_resource_get_client (resource); + struct wl_array buttons; + guint n_group, n_modes; + GList *l; + + wl_array_init (&buttons); + + /* Buttons */ + meta_wayland_tablet_pad_group_send_buttons (group, resource); + + /* Rings */ + for (l = group->rings; l; l = l->next) + { + MetaWaylandTabletPadRing *ring = l->data; + struct wl_resource *ring_resource; + + ring_resource = meta_wayland_tablet_pad_ring_create_new_resource (ring, + client, + resource, + 0); + zwp_tablet_pad_group_v2_send_ring (resource, ring_resource); + } + + /* Strips */ + for (l = group->strips; l; l = l->next) + { + MetaWaylandTabletPadStrip *strip = l->data; + struct wl_resource *strip_resource; + + strip_resource = meta_wayland_tablet_pad_strip_create_new_resource (strip, + client, + resource, + 0); + zwp_tablet_pad_group_v2_send_strip (resource, strip_resource); + } + + n_group = g_list_index (group->pad->groups, group); + n_modes = clutter_input_device_get_group_n_modes (group->pad->device, + n_group); + + zwp_tablet_pad_group_v2_send_modes (resource, n_modes); + zwp_tablet_pad_group_v2_send_done (resource); +} + +void +meta_wayland_tablet_pad_group_update (MetaWaylandTabletPadGroup *group, + const ClutterEvent *event) +{ + switch (event->type) + { + case CLUTTER_PAD_BUTTON_PRESS: + case CLUTTER_PAD_BUTTON_RELEASE: + if (meta_wayland_tablet_pad_group_is_mode_switch_button (group, event->pad_button.button)) + group->current_mode = event->pad_button.mode; + break; + default: + break; + } +} + +static gboolean +handle_pad_ring_event (MetaWaylandTabletPadGroup *group, + const ClutterEvent *event) +{ + MetaWaylandTabletPadRing *ring; + + if (event->type != CLUTTER_PAD_RING) + return FALSE; + + ring = g_list_nth_data (group->rings, event->pad_ring.ring_number); + + if (!ring) + return FALSE; + + return meta_wayland_tablet_pad_ring_handle_event (ring, event); +} + +static gboolean +handle_pad_strip_event (MetaWaylandTabletPadGroup *group, + const ClutterEvent *event) +{ + MetaWaylandTabletPadStrip *strip; + + if (event->type != CLUTTER_PAD_STRIP) + return FALSE; + + strip = g_list_nth_data (group->strips, event->pad_strip.strip_number); + + if (!strip) + return FALSE; + + return meta_wayland_tablet_pad_strip_handle_event (strip, event); +} + +static void +broadcast_group_mode (MetaWaylandTabletPadGroup *group, + uint32_t time) +{ + struct wl_display *display = group->pad->tablet_seat->seat->wl_display; + struct wl_resource *resource; + + group->mode_switch_serial = wl_display_next_serial (display); + + wl_resource_for_each (resource, &group->focus_resource_list) + { + zwp_tablet_pad_group_v2_send_mode_switch (resource, time, + group->mode_switch_serial, + group->current_mode); + } +} + +static void +broadcast_group_buttons (MetaWaylandTabletPadGroup *group) +{ + struct wl_resource *resource; + + wl_resource_for_each (resource, &group->focus_resource_list) + { + meta_wayland_tablet_pad_group_send_buttons (group, resource); + } +} + +gboolean +meta_wayland_tablet_pad_group_handle_event (MetaWaylandTabletPadGroup *group, + const ClutterEvent *event) +{ + switch (clutter_event_type (event)) + { + case CLUTTER_PAD_BUTTON_PRESS: + case CLUTTER_PAD_BUTTON_RELEASE: + if (meta_wayland_tablet_pad_group_is_mode_switch_button (group, event->pad_button.button)) + { + if (event->type == CLUTTER_PAD_BUTTON_PRESS) + broadcast_group_mode (group, clutter_event_get_time (event)); + return TRUE; + } + else + { + return FALSE; + } + break; + case CLUTTER_PAD_RING: + return handle_pad_ring_event (group, event); + case CLUTTER_PAD_STRIP: + return handle_pad_strip_event (group, event); + default: + return FALSE; + } +} + +static void +meta_wayland_tablet_pad_group_update_rings_focus (MetaWaylandTabletPadGroup *group) +{ + GList *l; + + for (l = group->rings; l; l = l->next) + meta_wayland_tablet_pad_ring_sync_focus (l->data); +} + +static void +meta_wayland_tablet_pad_group_update_strips_focus (MetaWaylandTabletPadGroup *group) +{ + GList *l; + + for (l = group->strips; l; l = l->next) + meta_wayland_tablet_pad_strip_sync_focus (l->data); +} + +static void +move_resources (struct wl_list *destination, struct wl_list *source) +{ + wl_list_insert_list (destination, source); + wl_list_init (source); +} + +static void +move_resources_for_client (struct wl_list *destination, + struct wl_list *source, + struct wl_client *client) +{ + struct wl_resource *resource, *tmp; + + wl_resource_for_each_safe (resource, tmp, source) + { + if (wl_resource_get_client (resource) == client) + { + wl_list_remove (wl_resource_get_link (resource)); + wl_list_insert (destination, wl_resource_get_link (resource)); + } + } +} + +void +meta_wayland_tablet_pad_group_sync_focus (MetaWaylandTabletPadGroup *group) +{ + if (!wl_list_empty (&group->focus_resource_list)) + { + move_resources (&group->resource_list, &group->focus_resource_list); + } + + if (group->pad->focus_surface != NULL) + { + move_resources_for_client (&group->focus_resource_list, + &group->resource_list, + wl_resource_get_client (group->pad->focus_surface->resource)); + } + + meta_wayland_tablet_pad_group_update_rings_focus (group); + meta_wayland_tablet_pad_group_update_strips_focus (group); + + if (!wl_list_empty (&group->focus_resource_list)) + { + broadcast_group_mode (group, clutter_get_current_event_time ()); + broadcast_group_buttons (group); + } +} + +gboolean +meta_wayland_tablet_pad_group_is_mode_switch_button (MetaWaylandTabletPadGroup *group, + guint button) +{ + gint n_group = g_list_index (group->pad->groups, group); + + g_assert (n_group >= 0); + + return clutter_input_device_is_mode_switch_button (group->pad->device, + n_group, button); +} diff --git a/src/wayland/meta-wayland-tablet-pad-group.h b/src/wayland/meta-wayland-tablet-pad-group.h new file mode 100644 index 000000000..0df3cc1f8 --- /dev/null +++ b/src/wayland/meta-wayland-tablet-pad-group.h @@ -0,0 +1,73 @@ +/* + * Wayland Support + * + * Copyright (C) 2016 Red Hat + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef META_WAYLAND_TABLET_PAD_GROUP_H +#define META_WAYLAND_TABLET_PAD_GROUP_H + +#include <glib.h> +#include <wayland-server.h> + +#include "clutter/clutter.h" +#include "wayland/meta-wayland-types.h" + +struct _MetaWaylandTabletPadGroup +{ + MetaWaylandTabletPad *pad; + GArray *buttons; + uint32_t n_modes; + uint32_t current_mode; + + struct wl_list resource_list; + struct wl_list focus_resource_list; + uint32_t mode_switch_serial; + + GList *strips; + GList *rings; +}; + +MetaWaylandTabletPadGroup * meta_wayland_tablet_pad_group_new (MetaWaylandTabletPad *pad); +void meta_wayland_tablet_pad_group_free (MetaWaylandTabletPadGroup *group); + +struct wl_resource * + meta_wayland_tablet_pad_group_create_new_resource (MetaWaylandTabletPadGroup *group, + struct wl_client *client, + struct wl_resource *pad_resource, + uint32_t id); +struct wl_resource * + meta_wayland_tablet_pad_group_lookup_resource (MetaWaylandTabletPadGroup *group, + struct wl_client *client); + +void meta_wayland_tablet_pad_group_notify (MetaWaylandTabletPadGroup *group, + struct wl_resource *resource); + +void meta_wayland_tablet_pad_group_update (MetaWaylandTabletPadGroup *group, + const ClutterEvent *event); +gboolean meta_wayland_tablet_pad_group_handle_event (MetaWaylandTabletPadGroup *group, + const ClutterEvent *event); + +void meta_wayland_tablet_pad_group_sync_focus (MetaWaylandTabletPadGroup *group); + +gboolean meta_wayland_tablet_pad_group_has_button (MetaWaylandTabletPadGroup *group, + guint button); +gboolean meta_wayland_tablet_pad_group_is_mode_switch_button (MetaWaylandTabletPadGroup *group, + guint button); + +#endif /* META_WAYLAND_TABLET_PAD_GROUP_H */ diff --git a/src/wayland/meta-wayland-tablet-pad-ring.c b/src/wayland/meta-wayland-tablet-pad-ring.c new file mode 100644 index 000000000..a89f5dd94 --- /dev/null +++ b/src/wayland/meta-wayland-tablet-pad-ring.c @@ -0,0 +1,206 @@ +/* + * Wayland Support + * + * Copyright (C) 2016 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#include "config.h" + +#include "wayland/meta-wayland-tablet-pad-ring.h" + +#include <glib.h> +#include <wayland-server.h> + +#include "compositor/meta-surface-actor-wayland.h" +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-wayland-tablet-pad.h" +#include "wayland/meta-wayland-tablet-pad-group.h" + +#include "tablet-unstable-v2-server-protocol.h" + +static void +unbind_resource (struct wl_resource *resource) +{ + wl_list_remove (wl_resource_get_link (resource)); +} + +MetaWaylandTabletPadRing * +meta_wayland_tablet_pad_ring_new (MetaWaylandTabletPad *pad) +{ + MetaWaylandTabletPadRing *ring; + + ring = g_slice_new0 (MetaWaylandTabletPadRing); + wl_list_init (&ring->resource_list); + wl_list_init (&ring->focus_resource_list); + ring->pad = pad; + + return ring; +} + +void +meta_wayland_tablet_pad_ring_free (MetaWaylandTabletPadRing *ring) +{ + struct wl_resource *resource, *next; + + wl_resource_for_each_safe (resource, next, &ring->resource_list) + { + wl_list_remove (wl_resource_get_link (resource)); + wl_list_init (wl_resource_get_link (resource)); + } + + g_free (ring->feedback); + g_slice_free (MetaWaylandTabletPadRing, ring); +} + +static void +tablet_pad_ring_set_feedback (struct wl_client *client, + struct wl_resource *resource, + const char *str, + uint32_t serial) +{ + MetaWaylandTabletPadRing *ring = wl_resource_get_user_data (resource); + + if (ring->group->mode_switch_serial != serial) + return; + + ring->feedback = g_strdup (str); +} + +static void +tablet_pad_ring_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static const struct zwp_tablet_pad_ring_v2_interface ring_interface = { + tablet_pad_ring_set_feedback, + tablet_pad_ring_destroy, +}; + +struct wl_resource * +meta_wayland_tablet_pad_ring_create_new_resource (MetaWaylandTabletPadRing *ring, + struct wl_client *client, + struct wl_resource *group_resource, + uint32_t id) +{ + struct wl_resource *resource; + + resource = wl_resource_create (client, &zwp_tablet_pad_ring_v2_interface, + wl_resource_get_version (group_resource), id); + wl_resource_set_implementation (resource, &ring_interface, + ring, unbind_resource); + wl_resource_set_user_data (resource, ring); + wl_list_insert (&ring->resource_list, wl_resource_get_link (resource)); + + return resource; +} + +gboolean +meta_wayland_tablet_pad_ring_handle_event (MetaWaylandTabletPadRing *ring, + const ClutterEvent *event) +{ + struct wl_list *focus_resources = &ring->focus_resource_list; + enum zwp_tablet_pad_ring_v2_source source; + gboolean source_known = FALSE; + struct wl_resource *resource; + + if (wl_list_empty (focus_resources)) + return FALSE; + if (event->type != CLUTTER_PAD_RING) + return FALSE; + + if (event->pad_ring.ring_source == CLUTTER_INPUT_DEVICE_PAD_SOURCE_FINGER) + { + source = ZWP_TABLET_PAD_RING_V2_SOURCE_FINGER; + source_known = TRUE; + } + + wl_resource_for_each (resource, focus_resources) + { + gdouble angle = event->pad_ring.angle; + + if (source_known) + zwp_tablet_pad_ring_v2_send_source (resource, source); + + if (angle >= 0) + zwp_tablet_pad_ring_v2_send_angle (resource, + wl_fixed_from_double (angle)); + else + zwp_tablet_pad_ring_v2_send_stop (resource); + + zwp_tablet_pad_ring_v2_send_frame (resource, + clutter_event_get_time (event)); + } + + return TRUE; +} + +static void +move_resources (struct wl_list *destination, struct wl_list *source) +{ + wl_list_insert_list (destination, source); + wl_list_init (source); +} + +static void +move_resources_for_client (struct wl_list *destination, + struct wl_list *source, + struct wl_client *client) +{ + struct wl_resource *resource, *tmp; + wl_resource_for_each_safe (resource, tmp, source) + { + if (wl_resource_get_client (resource) == client) + { + wl_list_remove (wl_resource_get_link (resource)); + wl_list_insert (destination, wl_resource_get_link (resource)); + } + } +} + +void +meta_wayland_tablet_pad_ring_sync_focus (MetaWaylandTabletPadRing *ring) +{ + g_clear_pointer (&ring->feedback, g_free); + + if (!wl_list_empty (&ring->focus_resource_list)) + { + move_resources (&ring->resource_list, &ring->focus_resource_list); + } + + if (ring->pad->focus_surface != NULL) + { + move_resources_for_client (&ring->focus_resource_list, + &ring->resource_list, + wl_resource_get_client (ring->pad->focus_surface->resource)); + } +} + +void +meta_wayland_tablet_pad_ring_set_group (MetaWaylandTabletPadRing *ring, + MetaWaylandTabletPadGroup *group) +{ + /* Group is static, can only be set once */ + g_assert (ring->group == NULL); + + ring->group = group; + group->rings = g_list_append (group->rings, ring); +} diff --git a/src/wayland/meta-wayland-tablet-pad-ring.h b/src/wayland/meta-wayland-tablet-pad-ring.h new file mode 100644 index 000000000..744ba2e84 --- /dev/null +++ b/src/wayland/meta-wayland-tablet-pad-ring.h @@ -0,0 +1,59 @@ +/* + * Wayland Support + * + * Copyright (C) 2016 Red Hat + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef META_WAYLAND_TABLET_PAD_RING_H +#define META_WAYLAND_TABLET_PAD_RING_H + +#include <glib.h> +#include <wayland-server.h> + +#include "backends/meta-cursor-renderer.h" +#include "wayland/meta-wayland-types.h" + +struct _MetaWaylandTabletPadRing +{ + MetaWaylandTabletPad *pad; + MetaWaylandTabletPadGroup *group; + + struct wl_list resource_list; + struct wl_list focus_resource_list; + + gchar *feedback; +}; + +MetaWaylandTabletPadRing * meta_wayland_tablet_pad_ring_new (MetaWaylandTabletPad *pad); +void meta_wayland_tablet_pad_ring_free (MetaWaylandTabletPadRing *ring); + +void meta_wayland_tablet_pad_ring_set_group (MetaWaylandTabletPadRing *ring, + MetaWaylandTabletPadGroup *group); +struct wl_resource * + meta_wayland_tablet_pad_ring_create_new_resource (MetaWaylandTabletPadRing *ring, + struct wl_client *client, + struct wl_resource *group_resource, + uint32_t id); + +gboolean meta_wayland_tablet_pad_ring_handle_event (MetaWaylandTabletPadRing *ring, + const ClutterEvent *event); + +void meta_wayland_tablet_pad_ring_sync_focus (MetaWaylandTabletPadRing *ring); + +#endif /* META_WAYLAND_TABLET_PAD_RING_H */ + diff --git a/src/wayland/meta-wayland-tablet-pad-strip.c b/src/wayland/meta-wayland-tablet-pad-strip.c new file mode 100644 index 000000000..6f6c20d8d --- /dev/null +++ b/src/wayland/meta-wayland-tablet-pad-strip.c @@ -0,0 +1,205 @@ +/* + * Wayland Support + * + * Copyright (C) 2016 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#include "config.h" + +#include "wayland/meta-wayland-tablet-pad-strip.h" + +#include <glib.h> +#include <wayland-server.h> + +#include "compositor/meta-surface-actor-wayland.h" +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-wayland-tablet-pad.h" +#include "wayland/meta-wayland-tablet-pad-group.h" + +#include "tablet-unstable-v2-server-protocol.h" + +static void +unbind_resource (struct wl_resource *resource) +{ + wl_list_remove (wl_resource_get_link (resource)); +} + +MetaWaylandTabletPadStrip * +meta_wayland_tablet_pad_strip_new (MetaWaylandTabletPad *pad) +{ + MetaWaylandTabletPadStrip *strip; + + strip = g_slice_new0 (MetaWaylandTabletPadStrip); + wl_list_init (&strip->resource_list); + wl_list_init (&strip->focus_resource_list); + strip->pad = pad; + + return strip; +} + +void +meta_wayland_tablet_pad_strip_free (MetaWaylandTabletPadStrip *strip) +{ + struct wl_resource *resource, *next; + + wl_resource_for_each_safe (resource, next, &strip->resource_list) + { + wl_list_remove (wl_resource_get_link (resource)); + wl_list_init (wl_resource_get_link (resource)); + } + + g_free (strip->feedback); + g_slice_free (MetaWaylandTabletPadStrip, strip); +} + +static void +tablet_pad_strip_set_feedback (struct wl_client *client, + struct wl_resource *resource, + const char *str, + uint32_t serial) +{ + MetaWaylandTabletPadStrip *strip = wl_resource_get_user_data (resource); + + if (strip->group->mode_switch_serial != serial) + return; + + strip->feedback = g_strdup (str); +} + +static void +tablet_pad_strip_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static const struct zwp_tablet_pad_strip_v2_interface strip_interface = { + tablet_pad_strip_set_feedback, + tablet_pad_strip_destroy, +}; + +struct wl_resource * +meta_wayland_tablet_pad_strip_create_new_resource (MetaWaylandTabletPadStrip *strip, + struct wl_client *client, + struct wl_resource *group_resource, + uint32_t id) +{ + struct wl_resource *resource; + + resource = wl_resource_create (client, &zwp_tablet_pad_strip_v2_interface, + wl_resource_get_version (group_resource), id); + wl_resource_set_implementation (resource, &strip_interface, + strip, unbind_resource); + wl_resource_set_user_data (resource, strip); + wl_list_insert (&strip->resource_list, wl_resource_get_link (resource)); + + return resource; +} + +gboolean +meta_wayland_tablet_pad_strip_handle_event (MetaWaylandTabletPadStrip *strip, + const ClutterEvent *event) +{ + struct wl_list *focus_resources = &strip->focus_resource_list; + enum zwp_tablet_pad_strip_v2_source source; + gboolean source_known = FALSE; + struct wl_resource *resource; + + if (wl_list_empty (focus_resources)) + return FALSE; + if (event->type != CLUTTER_PAD_STRIP) + return FALSE; + + if (event->pad_strip.strip_source == CLUTTER_INPUT_DEVICE_PAD_SOURCE_FINGER) + { + source = ZWP_TABLET_PAD_STRIP_V2_SOURCE_FINGER; + source_known = TRUE; + } + + wl_resource_for_each (resource, focus_resources) + { + gdouble value = event->pad_strip.value; + + if (source_known) + zwp_tablet_pad_strip_v2_send_source (resource, source); + + if (value >= 0) + zwp_tablet_pad_strip_v2_send_position (resource, (uint32_t) (value * 65535)); + else + zwp_tablet_pad_strip_v2_send_stop (resource); + + zwp_tablet_pad_strip_v2_send_frame (resource, + clutter_event_get_time (event)); + } + + return TRUE; +} + +static void +move_resources (struct wl_list *destination, struct wl_list *source) +{ + wl_list_insert_list (destination, source); + wl_list_init (source); +} + +static void +move_resources_for_client (struct wl_list *destination, + struct wl_list *source, + struct wl_client *client) +{ + struct wl_resource *resource, *tmp; + wl_resource_for_each_safe (resource, tmp, source) + { + if (wl_resource_get_client (resource) == client) + { + wl_list_remove (wl_resource_get_link (resource)); + wl_list_insert (destination, wl_resource_get_link (resource)); + } + } +} + +void +meta_wayland_tablet_pad_strip_sync_focus (MetaWaylandTabletPadStrip *strip) +{ + g_clear_pointer (&strip->feedback, g_free); + + if (!wl_list_empty (&strip->focus_resource_list)) + { + move_resources (&strip->resource_list, &strip->focus_resource_list); + } + + if (strip->pad->focus_surface != NULL) + { + move_resources_for_client (&strip->focus_resource_list, + &strip->resource_list, + wl_resource_get_client (strip->pad->focus_surface->resource)); + } +} + +void +meta_wayland_tablet_pad_strip_set_group (MetaWaylandTabletPadStrip *strip, + MetaWaylandTabletPadGroup *group) +{ + /* Group is static, can only be set once */ + g_assert (strip->group == NULL); + + strip->group = group; + group->strips = g_list_append (group->strips, strip); +} diff --git a/src/wayland/meta-wayland-tablet-pad-strip.h b/src/wayland/meta-wayland-tablet-pad-strip.h new file mode 100644 index 000000000..9d69de4eb --- /dev/null +++ b/src/wayland/meta-wayland-tablet-pad-strip.h @@ -0,0 +1,59 @@ +/* + * Wayland Support + * + * Copyright (C) 2016 Red Hat + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef META_WAYLAND_TABLET_PAD_STRIP_H +#define META_WAYLAND_TABLET_PAD_STRIP_H + +#include <glib.h> +#include <wayland-server.h> + +#include "backends/meta-cursor-renderer.h" +#include "wayland/meta-wayland-types.h" + +struct _MetaWaylandTabletPadStrip +{ + MetaWaylandTabletPad *pad; + MetaWaylandTabletPadGroup *group; + + struct wl_list resource_list; + struct wl_list focus_resource_list; + + gchar *feedback; +}; + +MetaWaylandTabletPadStrip * meta_wayland_tablet_pad_strip_new (MetaWaylandTabletPad *pad); +void meta_wayland_tablet_pad_strip_free (MetaWaylandTabletPadStrip *strip); + +void meta_wayland_tablet_pad_strip_set_group (MetaWaylandTabletPadStrip *strip, + MetaWaylandTabletPadGroup *group); + +struct wl_resource * + meta_wayland_tablet_pad_strip_create_new_resource (MetaWaylandTabletPadStrip *strip, + struct wl_client *client, + struct wl_resource *group_resource, + uint32_t id); + +gboolean meta_wayland_tablet_pad_strip_handle_event (MetaWaylandTabletPadStrip *strip, + const ClutterEvent *event); + +void meta_wayland_tablet_pad_strip_sync_focus (MetaWaylandTabletPadStrip *strip); + +#endif /* META_WAYLAND_TABLET_PAD_STRIP_H */ diff --git a/src/wayland/meta-wayland-tablet-pad.c b/src/wayland/meta-wayland-tablet-pad.c new file mode 100644 index 000000000..167d45948 --- /dev/null +++ b/src/wayland/meta-wayland-tablet-pad.c @@ -0,0 +1,612 @@ +/* + * Wayland Support + * + * Copyright (C) 2016 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#include "config.h" + +#include <glib.h> +#include <glib/gi18n-lib.h> +#include <wayland-server.h> + +#include "backends/meta-input-settings-private.h" +#include "compositor/meta-surface-actor-wayland.h" +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-wayland-tablet-pad-group.h" +#include "wayland/meta-wayland-tablet-pad-ring.h" +#include "wayland/meta-wayland-tablet-pad-strip.h" +#include "wayland/meta-wayland-tablet-pad.h" +#include "wayland/meta-wayland-tablet-seat.h" +#include "wayland/meta-wayland-tablet.h" + +#ifdef HAVE_NATIVE_BACKEND +#include <libinput.h> +#include "backends/native/meta-backend-native.h" +#include "backends/native/meta-input-device-native.h" +#endif + +#include "tablet-unstable-v2-server-protocol.h" + +static void +unbind_resource (struct wl_resource *resource) +{ + wl_list_remove (wl_resource_get_link (resource)); +} + +static void +pad_handle_focus_surface_destroy (struct wl_listener *listener, + void *data) +{ + MetaWaylandTabletPad *pad = wl_container_of (listener, pad, focus_surface_listener); + + meta_wayland_tablet_pad_set_focus (pad, NULL); +} + +static void +group_rings_strips (MetaWaylandTabletPad *pad) +{ + gint n_group, n_elem; + GList *g, *l; +#ifdef HAVE_NATIVE_BACKEND + MetaBackend *backend = meta_get_backend (); + struct libinput_device *libinput_device = NULL; + + if (META_IS_BACKEND_NATIVE (backend)) + libinput_device = meta_input_device_native_get_libinput_device (pad->device); +#endif + + for (n_group = 0, g = pad->groups; g; g = g->next) + { + MetaWaylandTabletPadGroup *group = g->data; +#ifdef HAVE_NATIVE_BACKEND + struct libinput_tablet_pad_mode_group *mode_group = NULL; + + if (libinput_device) + mode_group = libinput_device_tablet_pad_get_mode_group (libinput_device, n_group); +#endif + + for (n_elem = 0, l = pad->rings; l; l = l->next) + { + MetaWaylandTabletPadRing *ring = l->data; + +#ifdef HAVE_NATIVE_BACKEND + if (mode_group) + { + if (libinput_tablet_pad_mode_group_has_ring (mode_group, n_elem)) + meta_wayland_tablet_pad_ring_set_group (ring, group); + } + else +#endif + { + /* Assign everything to the first group */ + if (n_group == 0) + meta_wayland_tablet_pad_ring_set_group (ring, group); + } + n_elem++; + } + + for (n_elem = 0, l = pad->strips; l; l = l->next) + { + MetaWaylandTabletPadStrip *strip = l->data; + +#ifdef HAVE_NATIVE_BACKEND + if (mode_group) + { + if (libinput_tablet_pad_mode_group_has_strip (mode_group, n_elem)) + meta_wayland_tablet_pad_strip_set_group (strip, group); + } + else +#endif + { + /* Assign everything to the first group */ + if (n_group == 0) + meta_wayland_tablet_pad_strip_set_group (strip, group); + } + + n_elem++; + } + + n_group++; + } +} + +MetaWaylandTabletPad * +meta_wayland_tablet_pad_new (ClutterInputDevice *device, + MetaWaylandTabletSeat *tablet_seat) +{ +#ifdef HAVE_NATIVE_BACKEND + MetaBackend *backend = meta_get_backend (); +#endif + MetaWaylandTabletPad *pad; + guint n_elems, i; + + pad = g_slice_new0 (MetaWaylandTabletPad); + wl_list_init (&pad->resource_list); + wl_list_init (&pad->focus_resource_list); + pad->focus_surface_listener.notify = pad_handle_focus_surface_destroy; + pad->device = device; + pad->tablet_seat = tablet_seat; + + pad->feedback = g_hash_table_new_full (NULL, NULL, NULL, + (GDestroyNotify) g_free); + +#ifdef HAVE_NATIVE_BACKEND + /* Buttons, only can be honored this with the native backend */ + if (META_IS_BACKEND_NATIVE (backend)) + { + struct libinput_device *libinput_device; + + libinput_device = meta_input_device_native_get_libinput_device (device); + pad->n_buttons = libinput_device_tablet_pad_get_num_buttons (libinput_device); + } +#endif + + n_elems = clutter_input_device_get_n_mode_groups (pad->device); + + for (i = 0; i < n_elems; i++) + { + pad->groups = g_list_prepend (pad->groups, + meta_wayland_tablet_pad_group_new (pad)); + } + + n_elems = clutter_input_device_get_n_rings (pad->device); + + for (i = 0; i < n_elems; i++) + { + MetaWaylandTabletPadRing *ring; + + ring = meta_wayland_tablet_pad_ring_new (pad); + pad->rings = g_list_prepend (pad->rings, ring); + } + + n_elems = clutter_input_device_get_n_strips (pad->device); + + for (i = 0; i < n_elems; i++) + { + MetaWaylandTabletPadStrip *strip; + + strip = meta_wayland_tablet_pad_strip_new (pad); + pad->strips = g_list_prepend (pad->strips, strip); + } + + group_rings_strips (pad); + + return pad; +} + +void +meta_wayland_tablet_pad_free (MetaWaylandTabletPad *pad) +{ + struct wl_resource *resource, *next; + + meta_wayland_tablet_pad_set_focus (pad, NULL); + + wl_resource_for_each_safe (resource, next, &pad->resource_list) + { + zwp_tablet_pad_v2_send_removed (resource); + wl_list_remove (wl_resource_get_link (resource)); + wl_list_init (wl_resource_get_link (resource)); + } + + g_list_free_full (pad->groups, + (GDestroyNotify) meta_wayland_tablet_pad_group_free); + g_list_free_full (pad->rings, + (GDestroyNotify) meta_wayland_tablet_pad_ring_free); + g_list_free_full (pad->strips, + (GDestroyNotify) meta_wayland_tablet_pad_strip_free); + + g_hash_table_destroy (pad->feedback); + + g_slice_free (MetaWaylandTabletPad, pad); +} + +static MetaWaylandTabletPadGroup * +tablet_pad_lookup_button_group (MetaWaylandTabletPad *pad, + guint button) +{ + GList *l; + + for (l = pad->groups; l; l = l->next) + { + MetaWaylandTabletPadGroup *group = l->data; + + if (meta_wayland_tablet_pad_group_has_button (group, button)) + return group; + } + + return NULL; +} + +static void +tablet_pad_set_feedback (struct wl_client *client, + struct wl_resource *resource, + uint32_t button, + const char *str, + uint32_t serial) +{ + MetaWaylandTabletPad *pad = wl_resource_get_user_data (resource); + MetaWaylandTabletPadGroup *group = tablet_pad_lookup_button_group (pad, button); + MetaInputSettings *input_settings; + + if (!group || group->mode_switch_serial != serial) + return; + + input_settings = meta_backend_get_input_settings (meta_get_backend ()); + + if (input_settings && + meta_input_settings_is_pad_button_grabbed (input_settings, pad->device, button)) + return; + + if (meta_wayland_tablet_pad_group_is_mode_switch_button (group, button)) + return; + + g_hash_table_insert (pad->feedback, GUINT_TO_POINTER (button), g_strdup (str)); +} + +static void +tablet_pad_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static const struct zwp_tablet_pad_v2_interface pad_interface = { + tablet_pad_set_feedback, + tablet_pad_destroy, +}; + +void +meta_wayland_tablet_pad_notify (MetaWaylandTabletPad *pad, + struct wl_resource *resource) +{ + struct wl_client *client = wl_resource_get_client (resource); + const gchar *node_path; + GList *l; + + node_path = clutter_input_device_get_device_node (pad->device); + if (node_path) + zwp_tablet_pad_v2_send_path (resource, node_path); + + zwp_tablet_pad_v2_send_buttons (resource, pad->n_buttons); + + for (l = pad->groups; l; l = l->next) + { + MetaWaylandTabletPadGroup *group = l->data; + struct wl_resource *group_resource; + + group_resource = meta_wayland_tablet_pad_group_create_new_resource (group, + client, + resource, + 0); + zwp_tablet_pad_v2_send_group (resource, group_resource); + meta_wayland_tablet_pad_group_notify (group, group_resource); + } + + zwp_tablet_pad_v2_send_done (resource); +} + +struct wl_resource * +meta_wayland_tablet_pad_create_new_resource (MetaWaylandTabletPad *pad, + struct wl_client *client, + struct wl_resource *seat_resource, + uint32_t id) +{ + struct wl_resource *resource; + + resource = wl_resource_create (client, &zwp_tablet_pad_v2_interface, + wl_resource_get_version (seat_resource), id); + wl_resource_set_implementation (resource, &pad_interface, + pad, unbind_resource); + wl_resource_set_user_data (resource, pad); + wl_list_insert (&pad->resource_list, wl_resource_get_link (resource)); + + return resource; +} + +struct wl_resource * +meta_wayland_tablet_pad_lookup_resource (MetaWaylandTabletPad *pad, + struct wl_client *client) +{ + struct wl_resource *resource; + + resource = wl_resource_find_for_client (&pad->resource_list, client); + + if (!resource) + resource = wl_resource_find_for_client (&pad->focus_resource_list, client); + + return resource; +} + +static gboolean +handle_pad_button_event (MetaWaylandTabletPad *pad, + const ClutterEvent *event) +{ + enum zwp_tablet_pad_v2_button_state button_state; + struct wl_list *focus_resources = &pad->focus_resource_list; + struct wl_resource *resource; + + if (wl_list_empty (focus_resources)) + return FALSE; + + if (event->type == CLUTTER_PAD_BUTTON_PRESS) + button_state = ZWP_TABLET_PAD_V2_BUTTON_STATE_PRESSED; + else if (event->type == CLUTTER_PAD_BUTTON_RELEASE) + button_state = ZWP_TABLET_PAD_V2_BUTTON_STATE_RELEASED; + else + return FALSE; + + wl_resource_for_each (resource, focus_resources) + { + zwp_tablet_pad_v2_send_button (resource, + clutter_event_get_time (event), + event->pad_button.button, button_state); + } + + return TRUE; +} + +static gboolean +meta_wayland_tablet_pad_handle_event_action (MetaWaylandTabletPad *pad, + const ClutterEvent *event) +{ + MetaInputSettings *input_settings; + ClutterInputDevice *device; + + device = clutter_event_get_source_device (event); + input_settings = meta_backend_get_input_settings (meta_get_backend ()); + + if (input_settings && + meta_input_settings_is_pad_button_grabbed (input_settings, device, + event->pad_button.button)) + return TRUE; + + return FALSE; +} + +gboolean +meta_wayland_tablet_pad_handle_event (MetaWaylandTabletPad *pad, + const ClutterEvent *event) +{ + MetaWaylandTabletPadGroup *group; + gboolean handled = FALSE; + guint n_group; + + n_group = clutter_event_get_mode_group (event); + group = g_list_nth_data (pad->groups, n_group); + + switch (clutter_event_type (event)) + { + case CLUTTER_PAD_BUTTON_PRESS: + case CLUTTER_PAD_BUTTON_RELEASE: + if (group) + handled |= meta_wayland_tablet_pad_group_handle_event (group, event); + + handled |= meta_wayland_tablet_pad_handle_event_action (pad, event); + + if (handled) + return TRUE; + + return handle_pad_button_event (pad, event); + case CLUTTER_PAD_RING: + case CLUTTER_PAD_STRIP: + if (group) + return meta_wayland_tablet_pad_group_handle_event (group, event); + default: + return FALSE; + } +} + +static void +move_resources (struct wl_list *destination, struct wl_list *source) +{ + wl_list_insert_list (destination, source); + wl_list_init (source); +} + +static void +move_resources_for_client (struct wl_list *destination, + struct wl_list *source, + struct wl_client *client) +{ + struct wl_resource *resource, *tmp; + + wl_resource_for_each_safe (resource, tmp, source) + { + if (wl_resource_get_client (resource) == client) + { + wl_list_remove (wl_resource_get_link (resource)); + wl_list_insert (destination, wl_resource_get_link (resource)); + } + } +} + +static void +meta_wayland_tablet_pad_update_groups_focus (MetaWaylandTabletPad *pad) +{ + GList *l; + + for (l = pad->groups; l; l = l->next) + meta_wayland_tablet_pad_group_sync_focus (l->data); +} + +static void +meta_wayland_tablet_pad_broadcast_enter (MetaWaylandTabletPad *pad, + uint32_t serial, + MetaWaylandTablet *tablet, + MetaWaylandSurface *surface) +{ + struct wl_resource *resource, *tablet_resource; + struct wl_client *client; + + client = wl_resource_get_client (pad->focus_surface->resource); + tablet_resource = meta_wayland_tablet_lookup_resource (tablet, client); + + wl_resource_for_each (resource, &pad->focus_resource_list) + { + zwp_tablet_pad_v2_send_enter (resource, serial, + tablet_resource, + surface->resource); + } +} + +static void +meta_wayland_tablet_pad_broadcast_leave (MetaWaylandTabletPad *pad, + uint32_t serial, + MetaWaylandSurface *surface) +{ + struct wl_resource *resource; + + wl_resource_for_each (resource, &pad->focus_resource_list) + { + zwp_tablet_pad_v2_send_leave (resource, serial, + surface->resource); + } +} + +void +meta_wayland_tablet_pad_set_focus (MetaWaylandTabletPad *pad, + MetaWaylandSurface *surface) +{ + MetaWaylandTablet *tablet; + + if (pad->focus_surface == surface) + return; + + g_hash_table_remove_all (pad->feedback); + + if (pad->focus_surface != NULL) + { + struct wl_client *client = wl_resource_get_client (pad->focus_surface->resource); + struct wl_list *focus_resources = &pad->focus_resource_list; + + if (!wl_list_empty (focus_resources)) + { + struct wl_display *display = wl_client_get_display (client); + uint32_t serial = wl_display_next_serial (display); + + meta_wayland_tablet_pad_broadcast_leave (pad, serial, + pad->focus_surface); + move_resources (&pad->resource_list, &pad->focus_resource_list); + } + + wl_list_remove (&pad->focus_surface_listener.link); + pad->focus_surface = NULL; + } + + tablet = meta_wayland_tablet_seat_lookup_paired_tablet (pad->tablet_seat, + pad); + + if (tablet != NULL && surface != NULL) + { + struct wl_client *client; + + pad->focus_surface = surface; + wl_resource_add_destroy_listener (pad->focus_surface->resource, + &pad->focus_surface_listener); + + client = wl_resource_get_client (pad->focus_surface->resource); + move_resources_for_client (&pad->focus_resource_list, + &pad->resource_list, client); + + if (!wl_list_empty (&pad->focus_resource_list)) + { + struct wl_display *display = wl_client_get_display (client); + + pad->focus_serial = wl_display_next_serial (display); + meta_wayland_tablet_pad_broadcast_enter (pad, pad->focus_serial, + tablet, pad->focus_surface); + } + } + + meta_wayland_tablet_pad_update_groups_focus (pad); +} + +void +meta_wayland_tablet_pad_update (MetaWaylandTabletPad *pad, + const ClutterEvent *event) +{ + MetaWaylandTabletPadGroup *group; + guint n_group; + + n_group = clutter_event_get_mode_group (event); + group = g_list_nth_data (pad->groups, n_group); + + if (group) + meta_wayland_tablet_pad_group_update (group, event); +} + +static gchar * +meta_wayland_tablet_pad_label_mode_switch_button (MetaWaylandTabletPad *pad, + guint button) +{ + MetaWaylandTabletPadGroup *group; + GList *l; + + for (l = pad->groups; l; l = l->next) + { + group = l->data; + + if (meta_wayland_tablet_pad_group_is_mode_switch_button (group, button)) + return g_strdup_printf (_("Mode Switch: Mode %d"), group->current_mode + 1); + } + + return NULL; +} + +gchar * +meta_wayland_tablet_pad_get_label (MetaWaylandTabletPad *pad, + MetaPadActionType type, + guint action) +{ + const gchar *label = NULL; + gchar *mode_label; + + switch (type) + { + case META_PAD_ACTION_BUTTON: + mode_label = meta_wayland_tablet_pad_label_mode_switch_button (pad, action); + if (mode_label) + return mode_label; + + label = g_hash_table_lookup (pad->feedback, GUINT_TO_POINTER (action)); + break; + case META_PAD_ACTION_RING: + { + MetaWaylandTabletPadRing *ring; + + ring = g_list_nth_data (pad->rings, action); + if (ring) + label = ring->feedback; + break; + } + case META_PAD_ACTION_STRIP: + { + MetaWaylandTabletPadStrip *strip; + + strip = g_list_nth_data (pad->strips, action); + if (strip) + label = strip->feedback; + break; + } + } + + return g_strdup (label); +} diff --git a/src/wayland/meta-wayland-tablet-pad.h b/src/wayland/meta-wayland-tablet-pad.h new file mode 100644 index 000000000..63eaa03ed --- /dev/null +++ b/src/wayland/meta-wayland-tablet-pad.h @@ -0,0 +1,81 @@ +/* + * Wayland Support + * + * Copyright (C) 2016 Red Hat + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef META_WAYLAND_TABLET_PAD_H +#define META_WAYLAND_TABLET_PAD_H + +#include <glib.h> +#include <wayland-server.h> + +#include "backends/meta-cursor-renderer.h" +#include "wayland/meta-wayland-types.h" + +struct _MetaWaylandTabletPad +{ + MetaWaylandTabletSeat *tablet_seat; + ClutterInputDevice *device; + + struct wl_list resource_list; + struct wl_list focus_resource_list; + + MetaWaylandSurface *focus_surface; + struct wl_listener focus_surface_listener; + uint32_t focus_serial; + + uint32_t n_buttons; + GList *groups; + GList *rings; + GList *strips; + + GHashTable *feedback; + + MetaWaylandSurface *focus; +}; + +MetaWaylandTabletPad * meta_wayland_tablet_pad_new (ClutterInputDevice *device, + MetaWaylandTabletSeat *tablet_seat); +void meta_wayland_tablet_pad_free (MetaWaylandTabletPad *pad); + +struct wl_resource * + meta_wayland_tablet_pad_create_new_resource (MetaWaylandTabletPad *pad, + struct wl_client *client, + struct wl_resource *seat_resource, + uint32_t id); +struct wl_resource * + meta_wayland_tablet_pad_lookup_resource (MetaWaylandTabletPad *pad, + struct wl_client *client); + +void meta_wayland_tablet_pad_notify (MetaWaylandTabletPad *pad, + struct wl_resource *resource); + +void meta_wayland_tablet_pad_update (MetaWaylandTabletPad *pad, + const ClutterEvent *event); +gboolean meta_wayland_tablet_pad_handle_event (MetaWaylandTabletPad *pad, + const ClutterEvent *event); + +void meta_wayland_tablet_pad_set_focus (MetaWaylandTabletPad *pad, + MetaWaylandSurface *surface); + +gchar * meta_wayland_tablet_pad_get_label (MetaWaylandTabletPad *pad, + MetaPadActionType type, + guint action); + +#endif /* META_WAYLAND_TABLET_PAD_H */ diff --git a/src/wayland/meta-wayland-tablet-seat.c b/src/wayland/meta-wayland-tablet-seat.c new file mode 100644 index 000000000..1e029cb47 --- /dev/null +++ b/src/wayland/meta-wayland-tablet-seat.c @@ -0,0 +1,575 @@ +/* + * Wayland Support + * + * Copyright (C) 2015 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#include "config.h" + +#include <glib.h> +#include <wayland-server.h> + +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-wayland-tablet-pad.h" +#include "wayland/meta-wayland-tablet-seat.h" +#include "wayland/meta-wayland-tablet-tool.h" +#include "wayland/meta-wayland-tablet.h" + +#ifdef HAVE_NATIVE_BACKEND +#include "backends/native/meta-backend-native.h" +#endif + +#include "tablet-unstable-v2-server-protocol.h" + +static void +unbind_resource (struct wl_resource *resource) +{ + wl_list_remove (wl_resource_get_link (resource)); +} + +static void +notify_tool_added (MetaWaylandTabletSeat *tablet_seat, + struct wl_resource *client_resource, + MetaWaylandTabletTool *tool) +{ + struct wl_resource *tool_resource; + struct wl_client *client; + + client = wl_resource_get_client (client_resource); + tool_resource = meta_wayland_tablet_tool_lookup_resource (tool, client); + + if (!tool_resource) + return; + + zwp_tablet_seat_v2_send_tool_added (client_resource, tool_resource); +} + +static void +notify_tablet_added (MetaWaylandTabletSeat *tablet_seat, + struct wl_resource *client_resource, + ClutterInputDevice *device) +{ + struct wl_resource *resource; + MetaWaylandTablet *tablet; + struct wl_client *client; + + tablet = g_hash_table_lookup (tablet_seat->tablets, device); + + if (!tablet) + return; + + client = wl_resource_get_client (client_resource); + + if (meta_wayland_tablet_lookup_resource (tablet, client)) + return; + + resource = meta_wayland_tablet_create_new_resource (tablet, client, + client_resource, 0); + if (!resource) + return; + + zwp_tablet_seat_v2_send_tablet_added (client_resource, resource); + meta_wayland_tablet_notify (tablet, resource); +} + +static void +broadcast_tablet_added (MetaWaylandTabletSeat *tablet_seat, + ClutterInputDevice *device) +{ + struct wl_resource *resource; + + wl_resource_for_each (resource, &tablet_seat->resource_list) + { + notify_tablet_added (tablet_seat, resource, device); + } +} + +static void +notify_tablets (MetaWaylandTabletSeat *tablet_seat, + struct wl_resource *client_resource) +{ + ClutterInputDevice *device; + GHashTableIter iter; + + g_hash_table_iter_init (&iter, tablet_seat->tablets); + + while (g_hash_table_iter_next (&iter, (gpointer *) &device, NULL)) + notify_tablet_added (tablet_seat, client_resource, device); +} + +static void +notify_pad_added (MetaWaylandTabletSeat *tablet_seat, + struct wl_resource *tablet_seat_resource, + ClutterInputDevice *device) +{ + struct wl_resource *resource; + MetaWaylandTabletPad *pad; + struct wl_client *client; + + pad = g_hash_table_lookup (tablet_seat->pads, device); + + if (!pad) + return; + + client = wl_resource_get_client (tablet_seat_resource); + + if (meta_wayland_tablet_pad_lookup_resource (pad, client)) + return; + + resource = meta_wayland_tablet_pad_create_new_resource (pad, client, + tablet_seat_resource, + 0); + if (!resource) + return; + + zwp_tablet_seat_v2_send_pad_added (tablet_seat_resource, resource); + meta_wayland_tablet_pad_notify (pad, resource); +} + +static void +broadcast_pad_added (MetaWaylandTabletSeat *tablet_seat, + ClutterInputDevice *device) +{ + struct wl_resource *resource; + + wl_resource_for_each (resource, &tablet_seat->resource_list) + { + notify_pad_added (tablet_seat, resource, device); + } +} + +static void +notify_pads (MetaWaylandTabletSeat *tablet_seat, + struct wl_resource *tablet_seat_resource) +{ + ClutterInputDevice *device; + GHashTableIter iter; + + g_hash_table_iter_init (&iter, tablet_seat->pads); + + while (g_hash_table_iter_next (&iter, (gpointer *) &device, NULL)) + notify_pad_added (tablet_seat, tablet_seat_resource, device); +} + +static gboolean +is_tablet_device (ClutterInputDevice *device) +{ + ClutterInputDeviceType device_type; + + if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER) + return FALSE; + + device_type = clutter_input_device_get_device_type (device); + + return (device_type == CLUTTER_TABLET_DEVICE || + device_type == CLUTTER_PEN_DEVICE || + device_type == CLUTTER_ERASER_DEVICE || + device_type == CLUTTER_CURSOR_DEVICE); +} + +static gboolean +is_pad_device (ClutterInputDevice *device) +{ + ClutterInputDeviceType device_type; + + if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER) + return FALSE; + + device_type = clutter_input_device_get_device_type (device); + + return device_type == CLUTTER_PAD_DEVICE; +} + +static void +meta_wayland_tablet_seat_device_added (MetaWaylandTabletSeat *tablet_seat, + ClutterInputDevice *device) +{ + MetaWaylandSurface *pad_focus = tablet_seat->seat->keyboard->focus_surface; + + if (is_tablet_device (device)) + { + MetaWaylandTablet *tablet; + GList *pads, *l; + + tablet = meta_wayland_tablet_new (device, tablet_seat); + g_hash_table_insert (tablet_seat->tablets, device, tablet); + broadcast_tablet_added (tablet_seat, device); + + /* Because the insertion order is undefined, there might be already + * pads that are logically paired to this tablet. Look those up and + * refocus them. + */ + pads = meta_wayland_tablet_seat_lookup_paired_pads (tablet_seat, + tablet); + + for (l = pads; l; l = l->next) + meta_wayland_tablet_pad_set_focus (l->data, pad_focus); + + g_list_free (pads); + } + else if (is_pad_device (device)) + { + MetaWaylandTabletPad *pad; + + pad = meta_wayland_tablet_pad_new (device, tablet_seat); + g_hash_table_insert (tablet_seat->pads, device, pad); + broadcast_pad_added (tablet_seat, device); + + meta_wayland_tablet_pad_set_focus (pad, pad_focus); + } +} + +static void +meta_wayland_tablet_seat_device_removed (MetaWaylandTabletSeat *tablet_seat, + ClutterInputDevice *device) +{ + g_hash_table_remove (tablet_seat->tablets, device); + g_hash_table_remove (tablet_seat->pads, device); +} + +static void +tablet_seat_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static const struct zwp_tablet_seat_v2_interface tablet_seat_interface = { + tablet_seat_destroy +}; + +MetaWaylandTabletSeat * +meta_wayland_tablet_seat_new (MetaWaylandTabletManager *manager, + MetaWaylandSeat *seat) +{ + MetaWaylandTabletSeat *tablet_seat; + GList *devices, *l; + + tablet_seat = g_slice_new0 (MetaWaylandTabletSeat); + tablet_seat->manager = manager; + tablet_seat->seat = seat; + tablet_seat->clutter_seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); + tablet_seat->tablets = g_hash_table_new_full (NULL, NULL, NULL, + (GDestroyNotify) meta_wayland_tablet_free); + tablet_seat->tools = g_hash_table_new_full (NULL, NULL, NULL, + (GDestroyNotify) meta_wayland_tablet_tool_free); + tablet_seat->pads = g_hash_table_new_full (NULL, NULL, NULL, + (GDestroyNotify) meta_wayland_tablet_pad_free); + wl_list_init (&tablet_seat->resource_list); + + g_signal_connect_swapped (tablet_seat->clutter_seat, "device-added", + G_CALLBACK (meta_wayland_tablet_seat_device_added), + tablet_seat); + g_signal_connect_swapped (tablet_seat->clutter_seat, "device-removed", + G_CALLBACK (meta_wayland_tablet_seat_device_removed), + tablet_seat); + + devices = clutter_seat_list_devices (tablet_seat->clutter_seat); + + for (l = devices; l; l = l->next) + meta_wayland_tablet_seat_device_added (tablet_seat, l->data); + + g_list_free (devices); + + return tablet_seat; +} + +void +meta_wayland_tablet_seat_free (MetaWaylandTabletSeat *tablet_seat) +{ + struct wl_resource *resource, *next; + + wl_resource_for_each_safe (resource, next, &tablet_seat->resource_list) + { + wl_list_remove (wl_resource_get_link (resource)); + wl_list_init (wl_resource_get_link (resource)); + } + + g_signal_handlers_disconnect_by_data (tablet_seat->clutter_seat, + tablet_seat); + g_hash_table_destroy (tablet_seat->tablets); + g_hash_table_destroy (tablet_seat->tools); + g_hash_table_destroy (tablet_seat->pads); + g_slice_free (MetaWaylandTabletSeat, tablet_seat); +} + +struct wl_resource * +meta_wayland_tablet_seat_create_new_resource (MetaWaylandTabletSeat *tablet_seat, + struct wl_client *client, + struct wl_resource *manager_resource, + uint32_t id) +{ + struct wl_resource *resource; + + resource = wl_resource_create (client, &zwp_tablet_seat_v2_interface, + wl_resource_get_version (manager_resource), + id); + wl_resource_set_implementation (resource, &tablet_seat_interface, + tablet_seat, unbind_resource); + wl_resource_set_user_data (resource, tablet_seat); + wl_list_insert (&tablet_seat->resource_list, wl_resource_get_link (resource)); + + /* Notify client of all available tablets/pads */ + notify_tablets (tablet_seat, resource); + notify_pads (tablet_seat, resource); + + return resource; +} + +struct wl_resource * +meta_wayland_tablet_seat_lookup_resource (MetaWaylandTabletSeat *tablet_seat, + struct wl_client *client) +{ + return wl_resource_find_for_client (&tablet_seat->resource_list, client); +} + +MetaWaylandTablet * +meta_wayland_tablet_seat_lookup_tablet (MetaWaylandTabletSeat *tablet_seat, + ClutterInputDevice *device) +{ + return g_hash_table_lookup (tablet_seat->tablets, device); +} + +MetaWaylandTabletTool * +meta_wayland_tablet_seat_lookup_tool (MetaWaylandTabletSeat *tablet_seat, + ClutterInputDeviceTool *tool) +{ + return g_hash_table_lookup (tablet_seat->tools, tool); +} + +MetaWaylandTabletPad * +meta_wayland_tablet_seat_lookup_pad (MetaWaylandTabletSeat *tablet_seat, + ClutterInputDevice *device) +{ + return g_hash_table_lookup (tablet_seat->pads, device); +} + +static MetaWaylandTabletTool * +meta_wayland_tablet_seat_ensure_tool (MetaWaylandTabletSeat *tablet_seat, + ClutterInputDevice *device, + ClutterInputDeviceTool *device_tool) +{ + MetaWaylandTabletTool *tool; + + tool = g_hash_table_lookup (tablet_seat->tools, device_tool); + + if (!tool) + { + tool = meta_wayland_tablet_tool_new (tablet_seat, device, device_tool); + g_hash_table_insert (tablet_seat->tools, device_tool, tool); + } + + return tool; +} + +void +meta_wayland_tablet_seat_update (MetaWaylandTabletSeat *tablet_seat, + const ClutterEvent *event) +{ + ClutterInputDevice *device; + ClutterInputDeviceTool *device_tool; + MetaWaylandTabletTool *tool = NULL; + MetaWaylandTabletPad *pad = NULL; + + device = clutter_event_get_source_device (event); + + switch (event->type) + { + case CLUTTER_PROXIMITY_IN: + case CLUTTER_PROXIMITY_OUT: + case CLUTTER_BUTTON_PRESS: + case CLUTTER_BUTTON_RELEASE: + case CLUTTER_MOTION: + device_tool = clutter_event_get_device_tool (event); + + if (device && device_tool) + tool = meta_wayland_tablet_seat_ensure_tool (tablet_seat, device, device_tool); + + if (!tool) + return; + + meta_wayland_tablet_tool_update (tool, event); + break; + case CLUTTER_PAD_BUTTON_PRESS: + case CLUTTER_PAD_BUTTON_RELEASE: + case CLUTTER_PAD_RING: + case CLUTTER_PAD_STRIP: + pad = g_hash_table_lookup (tablet_seat->pads, device); + if (!pad) + return; + + return meta_wayland_tablet_pad_update (pad, event); + default: + break; + } +} + +gboolean +meta_wayland_tablet_seat_handle_event (MetaWaylandTabletSeat *tablet_seat, + const ClutterEvent *event) +{ + ClutterInputDeviceTool *device_tool; + MetaWaylandTabletTool *tool = NULL; + MetaWaylandTabletPad *pad = NULL; + + switch (event->type) + { + case CLUTTER_PROXIMITY_IN: + case CLUTTER_PROXIMITY_OUT: + case CLUTTER_BUTTON_PRESS: + case CLUTTER_BUTTON_RELEASE: + case CLUTTER_MOTION: + device_tool = clutter_event_get_device_tool (event); + + if (device_tool) + tool = g_hash_table_lookup (tablet_seat->tools, device_tool); + + if (!tool) + return CLUTTER_EVENT_PROPAGATE; + + meta_wayland_tablet_tool_handle_event (tool, event); + return CLUTTER_EVENT_PROPAGATE; + case CLUTTER_PAD_BUTTON_PRESS: + case CLUTTER_PAD_BUTTON_RELEASE: + case CLUTTER_PAD_RING: + case CLUTTER_PAD_STRIP: + pad = g_hash_table_lookup (tablet_seat->pads, + clutter_event_get_source_device (event)); + if (!pad) + return CLUTTER_EVENT_PROPAGATE; + + return meta_wayland_tablet_pad_handle_event (pad, event); + default: + return CLUTTER_EVENT_STOP; + } +} + +void +meta_wayland_tablet_seat_notify_tool (MetaWaylandTabletSeat *tablet_seat, + MetaWaylandTabletTool *tool, + struct wl_client *client) +{ + struct wl_resource *resource; + + resource = wl_resource_find_for_client (&tablet_seat->resource_list, client); + + if (resource) + notify_tool_added (tablet_seat, resource, tool); +} + +static GList * +lookup_grouped_devices (ClutterInputDevice *device, + ClutterInputDeviceType type) +{ + ClutterSeat *clutter_seat; + GList *devices, *l; + GList *group = NULL; + + clutter_seat = clutter_input_device_get_seat (device); + devices = clutter_seat_list_devices (clutter_seat); + + for (l = devices; l; l = l->next) + { + if (l->data == device) + continue; + if (clutter_input_device_get_device_type (l->data) != type) + continue; + + if (!clutter_input_device_is_grouped (device, l->data)) + continue; + + group = g_list_prepend (group, l->data); + } + + g_list_free (devices); + + return group; +} + +MetaWaylandTablet * +meta_wayland_tablet_seat_lookup_paired_tablet (MetaWaylandTabletSeat *tablet_seat, + MetaWaylandTabletPad *pad) +{ + MetaWaylandTablet *tablet; + GList *devices; + + devices = lookup_grouped_devices (pad->device, CLUTTER_TABLET_DEVICE); + + if (!devices) + return NULL; + + /* We only accept one device here */ + g_warn_if_fail (!devices->next); + + tablet = meta_wayland_tablet_seat_lookup_tablet (pad->tablet_seat, + devices->data); + g_list_free (devices); + + return tablet; +} + +GList * +meta_wayland_tablet_seat_lookup_paired_pads (MetaWaylandTabletSeat *tablet_seat, + MetaWaylandTablet *tablet) +{ + GList *l, *devices, *pads = NULL; + MetaWaylandTabletPad *pad; + + devices = lookup_grouped_devices (tablet->device, CLUTTER_PAD_DEVICE); + + for (l = devices; l; l = l->next) + { + pad = meta_wayland_tablet_seat_lookup_pad (tablet_seat, l->data); + if (pad) + pads = g_list_prepend (pads, pad); + } + + return pads; +} + +void +meta_wayland_tablet_seat_set_pad_focus (MetaWaylandTabletSeat *tablet_seat, + MetaWaylandSurface *surface) +{ + MetaWaylandTabletPad *pad; + GHashTableIter iter; + + g_hash_table_iter_init (&iter, tablet_seat->pads); + + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &pad)) + meta_wayland_tablet_pad_set_focus (pad, surface); +} + +gboolean +meta_wayland_tablet_seat_can_popup (MetaWaylandTabletSeat *tablet_seat, + uint32_t serial) +{ + MetaWaylandTabletTool *tool; + GHashTableIter iter; + + g_hash_table_iter_init (&iter, tablet_seat->tools); + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &tool)) + { + if (meta_wayland_tablet_tool_can_popup (tool, serial)) + return TRUE; + } + + return FALSE; +} diff --git a/src/wayland/meta-wayland-tablet-seat.h b/src/wayland/meta-wayland-tablet-seat.h new file mode 100644 index 000000000..e8b5a2439 --- /dev/null +++ b/src/wayland/meta-wayland-tablet-seat.h @@ -0,0 +1,81 @@ +/* + * Wayland Support + * + * Copyright (C) 2015 Red Hat + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef META_WAYLAND_TABLET_SEAT_H +#define META_WAYLAND_TABLET_SEAT_H + +#include <glib.h> +#include <wayland-server.h> + +#include "wayland/meta-wayland-types.h" + +struct _MetaWaylandTabletSeat +{ + MetaWaylandTabletManager *manager; + MetaWaylandSeat *seat; + ClutterSeat *clutter_seat; + struct wl_list resource_list; + + GHashTable *tablets; + GHashTable *tools; + GHashTable *pads; +}; + +MetaWaylandTabletSeat *meta_wayland_tablet_seat_new (MetaWaylandTabletManager *tablet_manager, + MetaWaylandSeat *seat); +void meta_wayland_tablet_seat_free (MetaWaylandTabletSeat *tablet_seat); + +struct wl_resource *meta_wayland_tablet_seat_create_new_resource (MetaWaylandTabletSeat *tablet_seat, + struct wl_client *client, + struct wl_resource *seat_resource, + uint32_t id); +struct wl_resource *meta_wayland_tablet_seat_lookup_resource (MetaWaylandTabletSeat *tablet_seat, + struct wl_client *client); + +MetaWaylandTablet *meta_wayland_tablet_seat_lookup_tablet (MetaWaylandTabletSeat *tablet_seat, + ClutterInputDevice *device); + +MetaWaylandTabletTool *meta_wayland_tablet_seat_lookup_tool (MetaWaylandTabletSeat *tablet_seat, + ClutterInputDeviceTool *tool); + +MetaWaylandTabletPad *meta_wayland_tablet_seat_lookup_pad (MetaWaylandTabletSeat *tablet_seat, + ClutterInputDevice *device); + +void meta_wayland_tablet_seat_update (MetaWaylandTabletSeat *tablet_seat, + const ClutterEvent *event); +gboolean meta_wayland_tablet_seat_handle_event (MetaWaylandTabletSeat *tablet_seat, + const ClutterEvent *event); + +void meta_wayland_tablet_seat_notify_tool (MetaWaylandTabletSeat *tablet_seat, + MetaWaylandTabletTool *tool, + struct wl_client *client); + +void meta_wayland_tablet_seat_set_pad_focus (MetaWaylandTabletSeat *tablet_seat, + MetaWaylandSurface *surface); + +MetaWaylandTablet *meta_wayland_tablet_seat_lookup_paired_tablet (MetaWaylandTabletSeat *tablet_seat, + MetaWaylandTabletPad *pad); +GList *meta_wayland_tablet_seat_lookup_paired_pads (MetaWaylandTabletSeat *tablet_seat, + MetaWaylandTablet *tablet); +gboolean meta_wayland_tablet_seat_can_popup (MetaWaylandTabletSeat *tablet_seat, + uint32_t serial); + +#endif /* META_WAYLAND_TABLET_SEAT_H */ diff --git a/src/wayland/meta-wayland-tablet-tool.c b/src/wayland/meta-wayland-tablet-tool.c new file mode 100644 index 000000000..e960cc63b --- /dev/null +++ b/src/wayland/meta-wayland-tablet-tool.c @@ -0,0 +1,1020 @@ +/* + * Wayland Support + * + * Copyright (C) 2015 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#include "config.h" + +#include "wayland/meta-wayland-tablet-tool.h" + +#include <glib.h> +#include <wayland-server.h> + +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-wayland-tablet-cursor-surface.h" +#include "compositor/meta-surface-actor-wayland.h" +#include "wayland/meta-wayland-tablet.h" +#include "wayland/meta-wayland-tablet-seat.h" +#include "backends/meta-input-settings-private.h" +#include "backends/meta-logical-monitor.h" + +#ifdef HAVE_NATIVE_BACKEND +#include <linux/input-event-codes.h> + +#include "backends/native/meta-backend-native.h" +#include "backends/native/meta-event-native.h" +#endif + +#include "tablet-unstable-v2-server-protocol.h" + +#define TABLET_AXIS_MAX 65535 + +static void +unbind_resource (struct wl_resource *resource) +{ + wl_list_remove (wl_resource_get_link (resource)); +} + +static void +move_resources (struct wl_list *destination, + struct wl_list *source) +{ + wl_list_insert_list (destination, source); + wl_list_init (source); +} + +static void +move_resources_for_client (struct wl_list *destination, + struct wl_list *source, + struct wl_client *client) +{ + struct wl_resource *resource, *tmp; + + wl_resource_for_each_safe (resource, tmp, source) + { + if (wl_resource_get_client (resource) == client) + { + wl_list_remove (wl_resource_get_link (resource)); + wl_list_insert (destination, wl_resource_get_link (resource)); + } + } +} + +static void +meta_wayland_tablet_tool_update_cursor_surface (MetaWaylandTabletTool *tool) +{ + MetaCursorSprite *cursor = NULL; + + if (tool->cursor_renderer == NULL) + return; + + if (tool->current && tool->current_tablet) + { + if (tool->cursor_surface && + meta_wayland_surface_get_buffer (tool->cursor_surface)) + { + MetaWaylandCursorSurface *cursor_surface = + META_WAYLAND_CURSOR_SURFACE (tool->cursor_surface->role); + + cursor = meta_wayland_cursor_surface_get_sprite (cursor_surface); + } + else + cursor = NULL; + } + else if (tool->current_tablet) + cursor = META_CURSOR_SPRITE (tool->default_sprite); + else + cursor = NULL; + + meta_cursor_renderer_set_cursor (tool->cursor_renderer, cursor); +} + +static void +meta_wayland_tablet_tool_set_cursor_surface (MetaWaylandTabletTool *tool, + MetaWaylandSurface *surface) +{ + if (tool->cursor_surface == surface) + return; + + if (tool->cursor_surface) + { + MetaWaylandCursorSurface *cursor_surface; + + cursor_surface = META_WAYLAND_CURSOR_SURFACE (tool->cursor_surface->role); + meta_wayland_cursor_surface_set_renderer (cursor_surface, NULL); + + meta_wayland_surface_update_outputs (tool->cursor_surface); + wl_list_remove (&tool->cursor_surface_destroy_listener.link); + } + + tool->cursor_surface = surface; + + if (tool->cursor_surface) + { + meta_wayland_surface_update_outputs (tool->cursor_surface); + wl_resource_add_destroy_listener (tool->cursor_surface->resource, + &tool->cursor_surface_destroy_listener); + } + + meta_wayland_tablet_tool_update_cursor_surface (tool); +} + +static uint32_t +input_device_get_capabilities (ClutterInputDevice *device) +{ + ClutterInputAxis axis; + guint32 capabilities = 0, i; + + for (i = 0; i < clutter_input_device_get_n_axes (device); i++) + { + axis = clutter_input_device_get_axis (device, i); + + switch (axis) + { + case CLUTTER_INPUT_AXIS_PRESSURE: + capabilities |= 1 << ZWP_TABLET_TOOL_V2_CAPABILITY_PRESSURE; + break; + case CLUTTER_INPUT_AXIS_DISTANCE: + capabilities |= 1 << ZWP_TABLET_TOOL_V2_CAPABILITY_DISTANCE; + break; + case CLUTTER_INPUT_AXIS_XTILT: + case CLUTTER_INPUT_AXIS_YTILT: + capabilities |= 1 << ZWP_TABLET_TOOL_V2_CAPABILITY_TILT; + break; + case CLUTTER_INPUT_AXIS_ROTATION: + capabilities |= 1 << ZWP_TABLET_TOOL_V2_CAPABILITY_ROTATION; + break; + case CLUTTER_INPUT_AXIS_WHEEL: + capabilities |= 1 << ZWP_TABLET_TOOL_V2_CAPABILITY_WHEEL; + break; + case CLUTTER_INPUT_AXIS_SLIDER: + capabilities |= 1 << ZWP_TABLET_TOOL_V2_CAPABILITY_SLIDER; + break; + default: + break; + } + } + + return capabilities; +} + +static enum zwp_tablet_tool_v2_type +input_device_tool_get_type (ClutterInputDeviceTool *device_tool) +{ + ClutterInputDeviceToolType tool_type; + + tool_type = clutter_input_device_tool_get_tool_type (device_tool); + + switch (tool_type) + { + case CLUTTER_INPUT_DEVICE_TOOL_NONE: + case CLUTTER_INPUT_DEVICE_TOOL_PEN: + return ZWP_TABLET_TOOL_V2_TYPE_PEN; + case CLUTTER_INPUT_DEVICE_TOOL_ERASER: + return ZWP_TABLET_TOOL_V2_TYPE_ERASER; + case CLUTTER_INPUT_DEVICE_TOOL_BRUSH: + return ZWP_TABLET_TOOL_V2_TYPE_BRUSH; + case CLUTTER_INPUT_DEVICE_TOOL_PENCIL: + return ZWP_TABLET_TOOL_V2_TYPE_PENCIL; + case CLUTTER_INPUT_DEVICE_TOOL_AIRBRUSH: + return ZWP_TABLET_TOOL_V2_TYPE_AIRBRUSH; + case CLUTTER_INPUT_DEVICE_TOOL_MOUSE: + return ZWP_TABLET_TOOL_V2_TYPE_MOUSE; + case CLUTTER_INPUT_DEVICE_TOOL_LENS: + return ZWP_TABLET_TOOL_V2_TYPE_LENS; + } + + g_assert_not_reached (); + return 0; +} + +static void +meta_wayland_tablet_tool_notify_capabilities (MetaWaylandTabletTool *tool, + struct wl_resource *resource) +{ + uint32_t capabilities; + + capabilities = input_device_get_capabilities (tool->device); + + if (capabilities & (1 << ZWP_TABLET_TOOL_V2_CAPABILITY_PRESSURE)) + zwp_tablet_tool_v2_send_capability (resource, + ZWP_TABLET_TOOL_V2_CAPABILITY_PRESSURE); + if (capabilities & (1 << ZWP_TABLET_TOOL_V2_CAPABILITY_DISTANCE)) + zwp_tablet_tool_v2_send_capability (resource, + ZWP_TABLET_TOOL_V2_CAPABILITY_DISTANCE); + if (capabilities & (1 << ZWP_TABLET_TOOL_V2_CAPABILITY_TILT)) + zwp_tablet_tool_v2_send_capability (resource, + ZWP_TABLET_TOOL_V2_CAPABILITY_TILT); + if (capabilities & (1 << ZWP_TABLET_TOOL_V2_CAPABILITY_ROTATION)) + zwp_tablet_tool_v2_send_capability (resource, + ZWP_TABLET_TOOL_V2_CAPABILITY_ROTATION); + if (capabilities & (1 << ZWP_TABLET_TOOL_V2_CAPABILITY_SLIDER)) + zwp_tablet_tool_v2_send_capability (resource, + ZWP_TABLET_TOOL_V2_CAPABILITY_SLIDER); + if (capabilities & (1 << ZWP_TABLET_TOOL_V2_CAPABILITY_WHEEL)) + zwp_tablet_tool_v2_send_capability (resource, + ZWP_TABLET_TOOL_V2_CAPABILITY_WHEEL); +} + +static void +meta_wayland_tablet_tool_notify_details (MetaWaylandTabletTool *tool, + struct wl_resource *resource) +{ + guint64 serial, id; + + zwp_tablet_tool_v2_send_type (resource, + input_device_tool_get_type (tool->device_tool)); + + serial = clutter_input_device_tool_get_serial (tool->device_tool); + zwp_tablet_tool_v2_send_hardware_serial (resource, (uint32_t) (serial >> 32), + (uint32_t) (serial & G_MAXUINT32)); + + id = clutter_input_device_tool_get_id (tool->device_tool); + zwp_tablet_tool_v2_send_hardware_id_wacom (resource, (uint32_t) (id >> 32), + (uint32_t) (id & G_MAXUINT32)); + + meta_wayland_tablet_tool_notify_capabilities (tool, resource); + + zwp_tablet_tool_v2_send_done (resource); +} + +static void +meta_wayland_tablet_tool_ensure_resource (MetaWaylandTabletTool *tool, + struct wl_client *client) +{ + struct wl_resource *seat_resource, *tool_resource; + + seat_resource = meta_wayland_tablet_seat_lookup_resource (tool->seat, client); + + if (seat_resource && + !meta_wayland_tablet_tool_lookup_resource (tool, client)) + { + tool_resource = meta_wayland_tablet_tool_create_new_resource (tool, client, + seat_resource, + 0); + + meta_wayland_tablet_seat_notify_tool (tool->seat, tool, client); + meta_wayland_tablet_tool_notify_details (tool, tool_resource); + } +} + +static void +broadcast_proximity_in (MetaWaylandTabletTool *tool) +{ + struct wl_resource *resource, *tablet_resource; + struct wl_client *client; + + client = wl_resource_get_client (tool->focus_surface->resource); + tablet_resource = meta_wayland_tablet_lookup_resource (tool->current_tablet, + client); + + wl_resource_for_each (resource, &tool->focus_resource_list) + { + zwp_tablet_tool_v2_send_proximity_in (resource, tool->proximity_serial, + tablet_resource, + tool->focus_surface->resource); + } +} + +static void +broadcast_proximity_out (MetaWaylandTabletTool *tool) +{ + struct wl_resource *resource; + + wl_resource_for_each (resource, &tool->focus_resource_list) + { + zwp_tablet_tool_v2_send_proximity_out (resource); + } +} + +static void +broadcast_frame (MetaWaylandTabletTool *tool, + const ClutterEvent *event) +{ + struct wl_resource *resource; + guint32 _time = event ? clutter_event_get_time (event) : CLUTTER_CURRENT_TIME; + + wl_resource_for_each (resource, &tool->focus_resource_list) + { + zwp_tablet_tool_v2_send_frame (resource, _time); + } +} + +static void +meta_wayland_tablet_tool_set_focus (MetaWaylandTabletTool *tool, + MetaWaylandSurface *surface, + const ClutterEvent *event) +{ + if (tool->focus_surface == surface) + return; + + if (tool->focus_surface != NULL) + { + struct wl_list *l; + + l = &tool->focus_resource_list; + if (!wl_list_empty (l)) + { + broadcast_proximity_out (tool); + broadcast_frame (tool, event); + move_resources (&tool->resource_list, &tool->focus_resource_list); + } + + wl_list_remove (&tool->focus_surface_destroy_listener.link); + tool->focus_surface = NULL; + } + + if (surface != NULL && tool->current_tablet) + { + struct wl_client *client; + struct wl_list *l; + + tool->focus_surface = surface; + client = wl_resource_get_client (tool->focus_surface->resource); + wl_resource_add_destroy_listener (tool->focus_surface->resource, + &tool->focus_surface_destroy_listener); + + move_resources_for_client (&tool->focus_resource_list, + &tool->resource_list, client); + meta_wayland_tablet_tool_ensure_resource (tool, client); + + l = &tool->focus_resource_list; + + if (!wl_list_empty (l)) + { + struct wl_client *client = wl_resource_get_client (tool->focus_surface->resource); + struct wl_display *display = wl_client_get_display (client); + + tool->proximity_serial = wl_display_next_serial (display); + + broadcast_proximity_in (tool); + broadcast_frame (tool, event); + } + } + + meta_wayland_tablet_tool_update_cursor_surface (tool); +} + +static void +tablet_tool_handle_focus_surface_destroy (struct wl_listener *listener, + void *data) +{ + MetaWaylandTabletTool *tool; + + tool = wl_container_of (listener, tool, focus_surface_destroy_listener); + meta_wayland_tablet_tool_set_focus (tool, NULL, NULL); +} + +static void +tablet_tool_handle_cursor_surface_destroy (struct wl_listener *listener, + void *data) +{ + MetaWaylandTabletTool *tool; + + tool = wl_container_of (listener, tool, cursor_surface_destroy_listener); + meta_wayland_tablet_tool_set_cursor_surface (tool, NULL); +} + +static void +tool_cursor_prepare_at (MetaCursorSpriteXcursor *sprite_xcursor, + int x, + int y, + MetaWaylandTabletTool *tool) +{ + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaLogicalMonitor *logical_monitor; + + logical_monitor = + meta_monitor_manager_get_logical_monitor_at (monitor_manager, x, y); + + /* Reload the cursor texture if the scale has changed. */ + if (logical_monitor) + { + MetaCursorSprite *cursor_sprite = META_CURSOR_SPRITE (sprite_xcursor); + float ceiled_scale; + + ceiled_scale = ceilf (logical_monitor->scale); + meta_cursor_sprite_xcursor_set_theme_scale (sprite_xcursor, + (int) ceiled_scale); + + if (meta_is_stage_views_scaled ()) + meta_cursor_sprite_set_texture_scale (cursor_sprite, + 1.0 / ceiled_scale); + else + meta_cursor_sprite_set_texture_scale (cursor_sprite, 1.0); + } +} + +MetaWaylandTabletTool * +meta_wayland_tablet_tool_new (MetaWaylandTabletSeat *seat, + ClutterInputDevice *device, + ClutterInputDeviceTool *device_tool) +{ + MetaWaylandTabletTool *tool; + + tool = g_slice_new0 (MetaWaylandTabletTool); + tool->seat = seat; + tool->device = device; + tool->device_tool = device_tool; + wl_list_init (&tool->resource_list); + wl_list_init (&tool->focus_resource_list); + + tool->focus_surface_destroy_listener.notify = tablet_tool_handle_focus_surface_destroy; + tool->cursor_surface_destroy_listener.notify = tablet_tool_handle_cursor_surface_destroy; + + tool->default_sprite = meta_cursor_sprite_xcursor_new (META_CURSOR_CROSSHAIR); + tool->prepare_at_signal_id = + g_signal_connect (tool->default_sprite, "prepare-at", + G_CALLBACK (tool_cursor_prepare_at), tool); + + return tool; +} + +void +meta_wayland_tablet_tool_free (MetaWaylandTabletTool *tool) +{ + struct wl_resource *resource, *next; + + meta_wayland_tablet_tool_set_focus (tool, NULL, NULL); + meta_wayland_tablet_tool_set_cursor_surface (tool, NULL); + g_clear_object (&tool->cursor_renderer); + + wl_resource_for_each_safe (resource, next, &tool->resource_list) + { + zwp_tablet_tool_v2_send_removed (resource); + wl_list_remove (wl_resource_get_link (resource)); + wl_list_init (wl_resource_get_link (resource)); + } + + g_clear_signal_handler (&tool->prepare_at_signal_id, tool->default_sprite); + g_object_unref (tool->default_sprite); + + g_slice_free (MetaWaylandTabletTool, tool); +} + +static void +tool_set_cursor (struct wl_client *client, + struct wl_resource *resource, + uint32_t serial, + struct wl_resource *surface_resource, + int32_t hotspot_x, + int32_t hotspot_y) +{ + MetaWaylandTabletTool *tool = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface; + + surface = (surface_resource ? wl_resource_get_user_data (surface_resource) : NULL); + + if (tool->focus_surface == NULL) + return; + if (tool->cursor_renderer == NULL) + return; + if (wl_resource_get_client (tool->focus_surface->resource) != client) + return; + if (tool->proximity_serial - serial > G_MAXUINT32 / 2) + return; + + if (surface && + !meta_wayland_surface_assign_role (surface, + META_TYPE_WAYLAND_TABLET_CURSOR_SURFACE, + NULL)) + { + wl_resource_post_error (resource, WL_POINTER_ERROR_ROLE, + "wl_surface@%d already has a different role", + wl_resource_get_id (surface_resource)); + return; + } + + if (surface) + { + MetaWaylandCursorSurface *cursor_surface; + + cursor_surface = META_WAYLAND_CURSOR_SURFACE (surface->role); + meta_wayland_cursor_surface_set_renderer (cursor_surface, + tool->cursor_renderer); + meta_wayland_cursor_surface_set_hotspot (cursor_surface, + hotspot_x, hotspot_y); + } + + meta_wayland_tablet_tool_set_cursor_surface (tool, surface); +} + +static void +tool_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static const struct zwp_tablet_tool_v2_interface tool_interface = { + tool_set_cursor, + tool_destroy +}; + +static void +emit_proximity_in (MetaWaylandTabletTool *tool, + struct wl_resource *resource) +{ + struct wl_resource *tablet_resource; + struct wl_client *client; + + if (!tool->focus_surface) + return; + + client = wl_resource_get_client (resource); + tablet_resource = meta_wayland_tablet_lookup_resource (tool->current_tablet, + client); + + zwp_tablet_tool_v2_send_proximity_in (resource, tool->proximity_serial, + tablet_resource, tool->focus_surface->resource); +} + +struct wl_resource * +meta_wayland_tablet_tool_create_new_resource (MetaWaylandTabletTool *tool, + struct wl_client *client, + struct wl_resource *seat_resource, + uint32_t id) +{ + struct wl_resource *resource; + + resource = wl_resource_create (client, &zwp_tablet_tool_v2_interface, + wl_resource_get_version (seat_resource), id); + wl_resource_set_implementation (resource, &tool_interface, + tool, unbind_resource); + wl_resource_set_user_data (resource, tool); + + if (tool->focus_surface && + wl_resource_get_client (tool->focus_surface->resource) == client) + { + wl_list_insert (&tool->focus_resource_list, wl_resource_get_link (resource)); + emit_proximity_in (tool, resource); + } + else + { + wl_list_insert (&tool->resource_list, wl_resource_get_link (resource)); + } + + return resource; +} + +struct wl_resource * +meta_wayland_tablet_tool_lookup_resource (MetaWaylandTabletTool *tool, + struct wl_client *client) +{ + struct wl_resource *resource = NULL; + + if (!wl_list_empty (&tool->resource_list)) + resource = wl_resource_find_for_client (&tool->resource_list, client); + + if (!wl_list_empty (&tool->focus_resource_list)) + resource = wl_resource_find_for_client (&tool->focus_resource_list, client); + + return resource; +} + +static void +meta_wayland_tablet_tool_account_button (MetaWaylandTabletTool *tool, + const ClutterEvent *event) +{ + if (event->type == CLUTTER_BUTTON_PRESS) + { + tool->pressed_buttons |= 1 << (event->button.button - 1); + tool->button_count++; + } + else if (event->type == CLUTTER_BUTTON_RELEASE) + { + tool->pressed_buttons &= ~(1 << (event->button.button - 1)); + tool->button_count--; + } +} + +static void +sync_focus_surface (MetaWaylandTabletTool *tool, + const ClutterEvent *event) +{ + MetaDisplay *display = meta_get_display (); + + switch (display->event_route) + { + case META_EVENT_ROUTE_WINDOW_OP: + case META_EVENT_ROUTE_COMPOSITOR_GRAB: + case META_EVENT_ROUTE_FRAME_BUTTON: + /* The compositor has a grab, so remove our focus */ + meta_wayland_tablet_tool_set_focus (tool, NULL, event); + break; + + case META_EVENT_ROUTE_NORMAL: + case META_EVENT_ROUTE_WAYLAND_POPUP: + meta_wayland_tablet_tool_set_focus (tool, tool->current, event); + break; + + default: + g_assert_not_reached (); + } +} + +static void +repick_for_event (MetaWaylandTabletTool *tool, + const ClutterEvent *for_event) +{ + ClutterActor *actor = NULL; + + actor = clutter_event_get_source (for_event); + + if (META_IS_SURFACE_ACTOR_WAYLAND (actor)) + tool->current = meta_surface_actor_wayland_get_surface (META_SURFACE_ACTOR_WAYLAND (actor)); + else + tool->current = NULL; + + sync_focus_surface (tool, for_event); + meta_wayland_tablet_tool_update_cursor_surface (tool); +} + +static void +meta_wayland_tablet_tool_get_relative_coordinates (MetaWaylandTabletTool *tool, + const ClutterEvent *event, + MetaWaylandSurface *surface, + wl_fixed_t *sx, + wl_fixed_t *sy) +{ + float xf, yf; + + clutter_event_get_coords (event, &xf, &yf); + meta_wayland_surface_get_relative_coordinates (surface, xf, yf, &xf, &yf); + + *sx = wl_fixed_from_double (xf); + *sy = wl_fixed_from_double (yf); +} + +static void +broadcast_motion (MetaWaylandTabletTool *tool, + const ClutterEvent *event) +{ + struct wl_resource *resource; + wl_fixed_t sx, sy; + + meta_wayland_tablet_tool_get_relative_coordinates (tool, event, + tool->focus_surface, + &sx, &sy); + + wl_resource_for_each (resource, &tool->focus_resource_list) + { + zwp_tablet_tool_v2_send_motion (resource, sx, sy); + } +} + +static void +broadcast_down (MetaWaylandTabletTool *tool, + const ClutterEvent *event) +{ + struct wl_resource *resource; + + tool->down_serial = wl_display_next_serial (tool->seat->manager->wl_display); + + wl_resource_for_each (resource, &tool->focus_resource_list) + { + zwp_tablet_tool_v2_send_down (resource, tool->down_serial); + } +} + +static void +broadcast_up (MetaWaylandTabletTool *tool, + const ClutterEvent *event) +{ + struct wl_resource *resource; + + wl_resource_for_each (resource, &tool->focus_resource_list) + { + zwp_tablet_tool_v2_send_up (resource); + } +} + +static void +broadcast_button (MetaWaylandTabletTool *tool, + const ClutterEvent *event) +{ + struct wl_resource *resource; + guint32 button; + +#ifdef HAVE_NATIVE_BACKEND + MetaBackend *backend = meta_get_backend (); + if (META_IS_BACKEND_NATIVE (backend)) + { + button = meta_event_native_get_event_code (event); + } + else +#endif + { + /* We can't do much better here, there's several + * different BTN_ ranges to cover. + */ + button = event->button.button; + } + + tool->button_serial = wl_display_next_serial (tool->seat->manager->wl_display); + + wl_resource_for_each (resource, &tool->focus_resource_list) + { + zwp_tablet_tool_v2_send_button (resource, tool->button_serial, button, + event->type == CLUTTER_BUTTON_PRESS ? + ZWP_TABLET_TOOL_V2_BUTTON_STATE_PRESSED : + ZWP_TABLET_TOOL_V2_BUTTON_STATE_RELEASED); + } +} + +static void +broadcast_axis (MetaWaylandTabletTool *tool, + const ClutterEvent *event, + ClutterInputAxis axis) +{ + struct wl_resource *resource; + ClutterInputDevice *source; + uint32_t value; + gdouble val; + + source = clutter_event_get_source_device (event); + + if (!clutter_input_device_get_axis_value (source, event->motion.axes, axis, &val)) + return; + + value = val * TABLET_AXIS_MAX; + + wl_resource_for_each (resource, &tool->focus_resource_list) + { + switch (axis) + { + case CLUTTER_INPUT_AXIS_PRESSURE: + zwp_tablet_tool_v2_send_pressure (resource, value); + break; + case CLUTTER_INPUT_AXIS_DISTANCE: + zwp_tablet_tool_v2_send_distance (resource, value); + break; + case CLUTTER_INPUT_AXIS_SLIDER: + zwp_tablet_tool_v2_send_slider (resource, value); + break; + default: + break; + } + } +} + +static void +broadcast_tilt (MetaWaylandTabletTool *tool, + const ClutterEvent *event) +{ + struct wl_resource *resource; + ClutterInputDevice *source; + gdouble xtilt, ytilt; + + source = clutter_event_get_source_device (event); + + if (!clutter_input_device_get_axis_value (source, event->motion.axes, + CLUTTER_INPUT_AXIS_XTILT, &xtilt) || + !clutter_input_device_get_axis_value (source, event->motion.axes, + CLUTTER_INPUT_AXIS_YTILT, &ytilt)) + return; + + wl_resource_for_each (resource, &tool->focus_resource_list) + { + zwp_tablet_tool_v2_send_tilt (resource, + wl_fixed_from_double (xtilt), + wl_fixed_from_double (ytilt)); + } +} + +static void +broadcast_rotation (MetaWaylandTabletTool *tool, + const ClutterEvent *event) +{ + struct wl_resource *resource; + ClutterInputDevice *source; + gdouble rotation; + + source = clutter_event_get_source_device (event); + + if (!clutter_input_device_get_axis_value (source, event->motion.axes, + CLUTTER_INPUT_AXIS_ROTATION, + &rotation)) + return; + + wl_resource_for_each (resource, &tool->focus_resource_list) + { + zwp_tablet_tool_v2_send_rotation (resource, + wl_fixed_from_double (rotation)); + } +} + +static void +broadcast_wheel (MetaWaylandTabletTool *tool, + const ClutterEvent *event) +{ + struct wl_resource *resource; + ClutterInputDevice *source; + gdouble angle; + gint32 clicks = 0; + + source = clutter_event_get_source_device (event); + + if (!clutter_input_device_get_axis_value (source, event->motion.axes, + CLUTTER_INPUT_AXIS_WHEEL, + &angle)) + return; + + /* FIXME: Perform proper angle-to-clicks accumulation elsewhere */ + if (angle > 0.01) + clicks = 1; + else if (angle < -0.01) + clicks = -1; + else + return; + + wl_resource_for_each (resource, &tool->focus_resource_list) + { + zwp_tablet_tool_v2_send_wheel (resource, + wl_fixed_from_double (angle), + clicks); + } +} + +static void +broadcast_axes (MetaWaylandTabletTool *tool, + const ClutterEvent *event) +{ + ClutterInputDevice *device; + guint32 capabilities; + + if (!event->motion.axes) + return; + + device = clutter_event_get_source_device (event); + capabilities = input_device_get_capabilities (device); + + if (capabilities & (1 << ZWP_TABLET_TOOL_V2_CAPABILITY_PRESSURE)) + broadcast_axis (tool, event, CLUTTER_INPUT_AXIS_PRESSURE); + if (capabilities & (1 << ZWP_TABLET_TOOL_V2_CAPABILITY_DISTANCE)) + broadcast_axis (tool, event, CLUTTER_INPUT_AXIS_DISTANCE); + if (capabilities & (1 << ZWP_TABLET_TOOL_V2_CAPABILITY_TILT)) + broadcast_tilt (tool, event); + if (capabilities & (1 << ZWP_TABLET_TOOL_V2_CAPABILITY_ROTATION)) + broadcast_rotation (tool, event); + if (capabilities & (1 << ZWP_TABLET_TOOL_V2_CAPABILITY_SLIDER)) + broadcast_axis (tool, event, CLUTTER_INPUT_AXIS_SLIDER); + if (capabilities & (1 << ZWP_TABLET_TOOL_V2_CAPABILITY_WHEEL)) + broadcast_wheel (tool, event); +} + +static void +handle_motion_event (MetaWaylandTabletTool *tool, + const ClutterEvent *event) +{ + if (!tool->focus_surface) + return; + + broadcast_motion (tool, event); + broadcast_axes (tool, event); + broadcast_frame (tool, event); +} + +static void +handle_button_event (MetaWaylandTabletTool *tool, + const ClutterEvent *event) +{ + if (!tool->focus_surface) + return; + + if (event->type == CLUTTER_BUTTON_PRESS && tool->button_count == 1) + clutter_event_get_coords (event, &tool->grab_x, &tool->grab_y); + + if (event->type == CLUTTER_BUTTON_PRESS && event->button.button == 1) + broadcast_down (tool, event); + else if (event->type == CLUTTER_BUTTON_RELEASE && event->button.button == 1) + broadcast_up (tool, event); + else + broadcast_button (tool, event); + + broadcast_frame (tool, event); +} + +void +meta_wayland_tablet_tool_update (MetaWaylandTabletTool *tool, + const ClutterEvent *event) +{ + switch (event->type) + { + case CLUTTER_BUTTON_PRESS: + case CLUTTER_BUTTON_RELEASE: + meta_wayland_tablet_tool_account_button (tool, event); + break; + case CLUTTER_MOTION: + if (!tool->pressed_buttons) + repick_for_event (tool, event); + break; + case CLUTTER_PROXIMITY_IN: + if (!tool->cursor_renderer) + tool->cursor_renderer = meta_cursor_renderer_new (); + tool->current_tablet = + meta_wayland_tablet_seat_lookup_tablet (tool->seat, + clutter_event_get_source_device (event)); + break; + case CLUTTER_PROXIMITY_OUT: + tool->current_tablet = NULL; + meta_wayland_tablet_tool_set_cursor_surface (tool, NULL); + meta_wayland_tablet_tool_update_cursor_surface (tool); + g_clear_object (&tool->cursor_renderer); + break; + default: + break; + } +} + +gboolean +meta_wayland_tablet_tool_handle_event (MetaWaylandTabletTool *tool, + const ClutterEvent *event) +{ + switch (event->type) + { + case CLUTTER_PROXIMITY_IN: + /* We don't have much info here to make anything useful out of it, + * wait until the first motion event so we have both coordinates + * and tool. + */ + break; + case CLUTTER_PROXIMITY_OUT: + meta_wayland_tablet_tool_set_focus (tool, NULL, event); + break; + case CLUTTER_MOTION: + handle_motion_event (tool, event); + break; + case CLUTTER_BUTTON_PRESS: + case CLUTTER_BUTTON_RELEASE: + handle_button_event (tool, event); + break; + default: + return CLUTTER_EVENT_PROPAGATE; + } + + return CLUTTER_EVENT_STOP; +} + +void +meta_wayland_tablet_tool_set_cursor_position (MetaWaylandTabletTool *tool, + float new_x, + float new_y) +{ + if (tool->cursor_renderer) + meta_cursor_renderer_set_position (tool->cursor_renderer, new_x, new_y); +} + +static gboolean +tablet_tool_can_grab_surface (MetaWaylandTabletTool *tool, + MetaWaylandSurface *surface) +{ + MetaWaylandSurface *subsurface; + + if (tool->focus_surface == surface) + return TRUE; + + META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (surface, subsurface) + { + if (tablet_tool_can_grab_surface (tool, subsurface)) + return TRUE; + } + + return FALSE; +} + +gboolean +meta_wayland_tablet_tool_can_grab_surface (MetaWaylandTabletTool *tool, + MetaWaylandSurface *surface, + uint32_t serial) +{ + return ((tool->down_serial == serial || tool->button_serial == serial) && + tablet_tool_can_grab_surface (tool, surface)); +} + +gboolean +meta_wayland_tablet_tool_can_popup (MetaWaylandTabletTool *tool, + uint32_t serial) +{ + return tool->down_serial == serial || tool->button_serial == serial; +} diff --git a/src/wayland/meta-wayland-tablet-tool.h b/src/wayland/meta-wayland-tablet-tool.h new file mode 100644 index 000000000..7cf1d9077 --- /dev/null +++ b/src/wayland/meta-wayland-tablet-tool.h @@ -0,0 +1,91 @@ +/* + * Wayland Support + * + * Copyright (C) 2015 Red Hat + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef META_WAYLAND_TABLET_TOOL_H +#define META_WAYLAND_TABLET_TOOL_H + +#include <glib.h> +#include <wayland-server.h> + +#include "backends/meta-cursor-renderer.h" +#include "backends/meta-cursor-sprite-xcursor.h" +#include "wayland/meta-wayland-types.h" + +struct _MetaWaylandTabletTool +{ + MetaWaylandTabletSeat *seat; + ClutterInputDevice *device; + ClutterInputDeviceTool *device_tool; + struct wl_list resource_list; + struct wl_list focus_resource_list; + + MetaWaylandSurface *focus_surface; + struct wl_listener focus_surface_destroy_listener; + + MetaWaylandSurface *cursor_surface; + struct wl_listener cursor_surface_destroy_listener; + MetaCursorRenderer *cursor_renderer; + MetaCursorSpriteXcursor *default_sprite; + gulong prepare_at_signal_id; + + MetaWaylandSurface *current; + guint32 pressed_buttons; + guint32 button_count; + + guint32 proximity_serial; + guint32 down_serial; + guint32 button_serial; + + float grab_x, grab_y; + + MetaWaylandTablet *current_tablet; +}; + +MetaWaylandTabletTool * meta_wayland_tablet_tool_new (MetaWaylandTabletSeat *seat, + ClutterInputDevice *device, + ClutterInputDeviceTool *device_tool); +void meta_wayland_tablet_tool_free (MetaWaylandTabletTool *tool); + +struct wl_resource * + meta_wayland_tablet_tool_create_new_resource (MetaWaylandTabletTool *tool, + struct wl_client *client, + struct wl_resource *seat_resource, + uint32_t id); +struct wl_resource * + meta_wayland_tablet_tool_lookup_resource (MetaWaylandTabletTool *tool, + struct wl_client *client); + +void meta_wayland_tablet_tool_update (MetaWaylandTabletTool *tool, + const ClutterEvent *event); +gboolean meta_wayland_tablet_tool_handle_event (MetaWaylandTabletTool *tool, + const ClutterEvent *event); + +void meta_wayland_tablet_tool_set_cursor_position (MetaWaylandTabletTool *tool, + float new_x, + float new_y); + +gboolean meta_wayland_tablet_tool_can_grab_surface (MetaWaylandTabletTool *tool, + MetaWaylandSurface *surface, + uint32_t serial); +gboolean meta_wayland_tablet_tool_can_popup (MetaWaylandTabletTool *tool, + uint32_t serial); + +#endif /* META_WAYLAND_TABLET_TOOL_H */ diff --git a/src/wayland/meta-wayland-tablet.c b/src/wayland/meta-wayland-tablet.c new file mode 100644 index 000000000..763f804b2 --- /dev/null +++ b/src/wayland/meta-wayland-tablet.c @@ -0,0 +1,129 @@ +/* + * Wayland Support + * + * Copyright (C) 2015 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#include "config.h" + +#include "wayland/meta-wayland-tablet.h" + +#include <glib.h> +#include <wayland-server.h> + +#include "compositor/meta-surface-actor-wayland.h" +#include "wayland/meta-wayland-private.h" + +#include "tablet-unstable-v2-server-protocol.h" + +static void +unbind_resource (struct wl_resource *resource) +{ + wl_list_remove (wl_resource_get_link (resource)); +} + +MetaWaylandTablet * +meta_wayland_tablet_new (ClutterInputDevice *device, + MetaWaylandTabletSeat *tablet_seat) +{ + MetaWaylandTablet *tablet; + + tablet = g_slice_new0 (MetaWaylandTablet); + wl_list_init (&tablet->resource_list); + tablet->device = device; + tablet->tablet_seat = tablet_seat; + + return tablet; +} + +void +meta_wayland_tablet_free (MetaWaylandTablet *tablet) +{ + struct wl_resource *resource, *next; + + wl_resource_for_each_safe (resource, next, &tablet->resource_list) + { + zwp_tablet_v2_send_removed (resource); + wl_list_remove (wl_resource_get_link (resource)); + wl_list_init (wl_resource_get_link (resource)); + } + + g_slice_free (MetaWaylandTablet, tablet); +} + +static void +tablet_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static const struct zwp_tablet_v2_interface tablet_interface = { + tablet_destroy +}; + +void +meta_wayland_tablet_notify (MetaWaylandTablet *tablet, + struct wl_resource *resource) +{ + ClutterInputDevice *device = tablet->device; + const gchar *node_path, *vendor, *product; + guint vid, pid; + + zwp_tablet_v2_send_name (resource, clutter_input_device_get_device_name (device)); + + node_path = clutter_input_device_get_device_node (device); + if (node_path) + zwp_tablet_v2_send_path (resource, node_path); + + vendor = clutter_input_device_get_vendor_id (device); + product = clutter_input_device_get_product_id (device); + + if (vendor && sscanf (vendor, "%x", &vid) == 1 && + product && sscanf (product, "%x", &pid) == 1) + zwp_tablet_v2_send_id (resource, vid, pid); + + zwp_tablet_v2_send_done (resource); +} + +struct wl_resource * +meta_wayland_tablet_create_new_resource (MetaWaylandTablet *tablet, + struct wl_client *client, + struct wl_resource *seat_resource, + uint32_t id) +{ + struct wl_resource *resource; + + resource = wl_resource_create (client, &zwp_tablet_v2_interface, + wl_resource_get_version (seat_resource), id); + wl_resource_set_implementation (resource, &tablet_interface, + tablet, unbind_resource); + wl_resource_set_user_data (resource, tablet); + wl_list_insert (&tablet->resource_list, wl_resource_get_link (resource)); + + return resource; +} + +struct wl_resource * +meta_wayland_tablet_lookup_resource (MetaWaylandTablet *tablet, + struct wl_client *client) +{ + return wl_resource_find_for_client (&tablet->resource_list, client); +} diff --git a/src/wayland/meta-wayland-tablet.h b/src/wayland/meta-wayland-tablet.h new file mode 100644 index 000000000..0bc3b87b9 --- /dev/null +++ b/src/wayland/meta-wayland-tablet.h @@ -0,0 +1,58 @@ +/* + * Wayland Support + * + * Copyright (C) 2015 Red Hat + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef META_WAYLAND_TABLET_H +#define META_WAYLAND_TABLET_H + +#include <wayland-server.h> + +#include <glib.h> + +#include "backends/meta-cursor-renderer.h" +#include "wayland/meta-wayland-types.h" + +struct _MetaWaylandTablet +{ + MetaWaylandTabletSeat *tablet_seat; + ClutterInputDevice *device; + + struct wl_list resource_list; + + MetaWaylandSurface *current; +}; + +MetaWaylandTablet * meta_wayland_tablet_new (ClutterInputDevice *device, + MetaWaylandTabletSeat *tablet_seat); +void meta_wayland_tablet_free (MetaWaylandTablet *tablet); + +struct wl_resource * + meta_wayland_tablet_create_new_resource (MetaWaylandTablet *tablet, + struct wl_client *client, + struct wl_resource *seat_resource, + uint32_t id); +struct wl_resource * + meta_wayland_tablet_lookup_resource (MetaWaylandTablet *tablet, + struct wl_client *client); + +void meta_wayland_tablet_notify (MetaWaylandTablet *tablet, + struct wl_resource *resource); + +#endif /* META_WAYLAND_TABLET_H */ diff --git a/src/wayland/meta-wayland-text-input-legacy.c b/src/wayland/meta-wayland-text-input-legacy.c new file mode 100644 index 000000000..442708e0f --- /dev/null +++ b/src/wayland/meta-wayland-text-input-legacy.c @@ -0,0 +1,633 @@ +/* + * Copyright (C) 2017, 2018 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#include "config.h" + +#include <wayland-server.h> + +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-wayland-seat.h" +#include "wayland/meta-wayland-text-input-legacy.h" +#include "wayland/meta-wayland-versions.h" + +#include "gtk-text-input-server-protocol.h" + +#define META_TYPE_WAYLAND_GTK_TEXT_INPUT_FOCUS (meta_wayland_gtk_text_input_focus_get_type ()) + +typedef enum +{ + META_WAYLAND_PENDING_STATE_NONE = 0, + META_WAYLAND_PENDING_STATE_INPUT_RECT = 1 << 0, + META_WAYLAND_PENDING_STATE_CONTENT_TYPE = 1 << 1, + META_WAYLAND_PENDING_STATE_SURROUNDING_TEXT = 1 << 2, +} MetaWaylandTextInputPendingState; + +typedef struct _MetaWaylandGtkTextInput MetaWaylandGtkTextInput; + +struct _MetaWaylandGtkTextInput +{ + MetaWaylandSeat *seat; + ClutterInputFocus *input_focus; + + struct wl_list resource_list; + struct wl_list focus_resource_list; + MetaWaylandSurface *surface; + struct wl_listener surface_listener; + uint32_t focus_serial; + + MetaWaylandTextInputPendingState pending_state; + + struct + { + char *text; + uint32_t cursor; + uint32_t anchor; + } surrounding; + + cairo_rectangle_int_t cursor_rect; + + uint32_t content_type_hint; + uint32_t content_type_purpose; +}; + +struct _MetaWaylandGtkTextInputFocus +{ + ClutterInputFocus parent_instance; + MetaWaylandGtkTextInput *text_input; +}; + +G_DECLARE_FINAL_TYPE (MetaWaylandGtkTextInputFocus, + meta_wayland_gtk_text_input_focus, + META, WAYLAND_GTK_TEXT_INPUT_FOCUS, ClutterInputFocus) +G_DEFINE_TYPE (MetaWaylandGtkTextInputFocus, meta_wayland_gtk_text_input_focus, + CLUTTER_TYPE_INPUT_FOCUS) + +static void +meta_wayland_text_input_focus_request_surrounding (ClutterInputFocus *focus) +{ + MetaWaylandGtkTextInput *text_input; + + text_input = META_WAYLAND_GTK_TEXT_INPUT_FOCUS (focus)->text_input; + clutter_input_focus_set_surrounding (focus, + text_input->surrounding.text, + text_input->surrounding.cursor, + text_input->surrounding.anchor); +} + +static void +meta_wayland_text_input_focus_delete_surrounding (ClutterInputFocus *focus, + int offset, + guint len) +{ + MetaWaylandGtkTextInput *text_input; + uint32_t before_length; + uint32_t after_length; + struct wl_resource *resource; + + text_input = META_WAYLAND_GTK_TEXT_INPUT_FOCUS (focus)->text_input; + before_length = ABS (MIN (offset, 0)); + after_length = MAX (0, offset + len); + g_warn_if_fail (ABS (offset) <= len); + + wl_resource_for_each (resource, &text_input->focus_resource_list) + { + gtk_text_input_send_delete_surrounding_text (resource, + before_length, + after_length); + } +} + +static void +meta_wayland_text_input_focus_commit_text (ClutterInputFocus *focus, + const gchar *text) +{ + MetaWaylandGtkTextInput *text_input; + struct wl_resource *resource; + + text_input = META_WAYLAND_GTK_TEXT_INPUT_FOCUS (focus)->text_input; + + wl_resource_for_each (resource, &text_input->focus_resource_list) + { + gtk_text_input_send_preedit_string (resource, NULL, 0); + gtk_text_input_send_commit_string (resource, text); + } +} + +static void +meta_wayland_text_input_focus_set_preedit_text (ClutterInputFocus *focus, + const gchar *text, + guint cursor) +{ + MetaWaylandGtkTextInput *text_input; + struct wl_resource *resource; + + text_input = META_WAYLAND_GTK_TEXT_INPUT_FOCUS (focus)->text_input; + + wl_resource_for_each (resource, &text_input->focus_resource_list) + { + gtk_text_input_send_preedit_string (resource, text, cursor); + } +} + +static void +meta_wayland_gtk_text_input_focus_class_init (MetaWaylandGtkTextInputFocusClass *klass) +{ + ClutterInputFocusClass *focus_class = CLUTTER_INPUT_FOCUS_CLASS (klass); + + focus_class->request_surrounding = meta_wayland_text_input_focus_request_surrounding; + focus_class->delete_surrounding = meta_wayland_text_input_focus_delete_surrounding; + focus_class->commit_text = meta_wayland_text_input_focus_commit_text; + focus_class->set_preedit_text = meta_wayland_text_input_focus_set_preedit_text; +} + +static void +meta_wayland_gtk_text_input_focus_init (MetaWaylandGtkTextInputFocus *focus) +{ +} + +static ClutterInputFocus * +meta_wayland_text_input_focus_new (MetaWaylandGtkTextInput *text_input) +{ + MetaWaylandGtkTextInputFocus *focus; + + focus = g_object_new (META_TYPE_WAYLAND_GTK_TEXT_INPUT_FOCUS, NULL); + focus->text_input = text_input; + + return CLUTTER_INPUT_FOCUS (focus); +} + +static void +text_input_handle_focus_surface_destroy (struct wl_listener *listener, + void *data) +{ + MetaWaylandGtkTextInput *text_input = wl_container_of (listener, text_input, + surface_listener); + + meta_wayland_gtk_text_input_set_focus (text_input, NULL); +} + +static void +move_resources (struct wl_list *destination, struct wl_list *source) +{ + wl_list_insert_list (destination, source); + wl_list_init (source); +} + +static void +move_resources_for_client (struct wl_list *destination, + struct wl_list *source, + struct wl_client *client) +{ + struct wl_resource *resource, *tmp; + wl_resource_for_each_safe (resource, tmp, source) + { + if (wl_resource_get_client (resource) == client) + { + wl_list_remove (wl_resource_get_link (resource)); + wl_list_insert (destination, wl_resource_get_link (resource)); + } + } +} + +void +meta_wayland_gtk_text_input_set_focus (MetaWaylandGtkTextInput *text_input, + MetaWaylandSurface *surface) +{ + if (text_input->surface == surface) + return; + + text_input->pending_state = META_WAYLAND_PENDING_STATE_NONE; + + if (text_input->surface) + { + if (!wl_list_empty (&text_input->focus_resource_list)) + { + ClutterInputFocus *focus = text_input->input_focus; + ClutterInputMethod *input_method; + struct wl_resource *resource; + uint32_t serial; + + if (clutter_input_focus_is_focused (focus)) + { + input_method = clutter_backend_get_input_method (clutter_get_default_backend ()); + clutter_input_method_focus_out (input_method); + } + + serial = wl_display_next_serial (text_input->seat->wl_display); + + wl_resource_for_each (resource, &text_input->focus_resource_list) + { + gtk_text_input_send_leave (resource, serial, + text_input->surface->resource); + } + + move_resources (&text_input->resource_list, + &text_input->focus_resource_list); + } + + wl_list_remove (&text_input->surface_listener.link); + text_input->surface = NULL; + } + + if (surface) + { + struct wl_resource *focus_surface_resource; + + text_input->surface = surface; + focus_surface_resource = text_input->surface->resource; + wl_resource_add_destroy_listener (focus_surface_resource, + &text_input->surface_listener); + + move_resources_for_client (&text_input->focus_resource_list, + &text_input->resource_list, + wl_resource_get_client (focus_surface_resource)); + + if (!wl_list_empty (&text_input->focus_resource_list)) + { + struct wl_resource *resource; + + text_input->focus_serial = + wl_display_next_serial (text_input->seat->wl_display); + + wl_resource_for_each (resource, &text_input->focus_resource_list) + { + gtk_text_input_send_enter (resource, text_input->focus_serial, + surface->resource); + } + } + } +} + +static void +unbind_resource (struct wl_resource *resource) +{ + wl_list_remove (wl_resource_get_link (resource)); +} + +static void +text_input_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +text_input_enable (struct wl_client *client, + struct wl_resource *resource, + uint32_t serial, + uint32_t flags) +{ + MetaWaylandGtkTextInput *text_input = wl_resource_get_user_data (resource); + ClutterInputFocus *focus = text_input->input_focus; + ClutterInputMethod *input_method; + gboolean show_preedit; + + if (serial != text_input->focus_serial) + return; + + if (!clutter_input_focus_is_focused (focus)) + { + input_method = clutter_backend_get_input_method (clutter_get_default_backend ()); + if (input_method) + clutter_input_method_focus_in (input_method, focus); + else + return; + } + + show_preedit = (flags & GTK_TEXT_INPUT_ENABLE_FLAGS_CAN_SHOW_PREEDIT) != 0; + clutter_input_focus_set_can_show_preedit (focus, show_preedit); + + if (flags & GTK_TEXT_INPUT_ENABLE_FLAGS_TOGGLE_INPUT_PANEL) + clutter_input_focus_set_input_panel_state (focus, CLUTTER_INPUT_PANEL_STATE_TOGGLE); +} + +static void +text_input_disable (struct wl_client *client, + struct wl_resource *resource) +{ + MetaWaylandGtkTextInput *text_input = wl_resource_get_user_data (resource); + ClutterInputFocus *focus = text_input->input_focus; + ClutterInputMethod *input_method; + + if (!clutter_input_focus_is_focused (focus)) + return; + + clutter_input_focus_reset (text_input->input_focus); + text_input->pending_state = META_WAYLAND_PENDING_STATE_NONE; + + input_method = clutter_backend_get_input_method (clutter_get_default_backend ()); + clutter_input_method_focus_out (input_method); +} + +static void +text_input_set_surrounding_text (struct wl_client *client, + struct wl_resource *resource, + const char *text, + int32_t cursor, + int32_t anchor) +{ + MetaWaylandGtkTextInput *text_input = wl_resource_get_user_data (resource); + + g_free (text_input->surrounding.text); + text_input->surrounding.text = g_strdup (text); + text_input->surrounding.cursor = cursor; + text_input->surrounding.anchor = anchor; + text_input->pending_state |= META_WAYLAND_PENDING_STATE_SURROUNDING_TEXT; +} + +static ClutterInputContentHintFlags +translate_hints (uint32_t hints) +{ + ClutterInputContentHintFlags clutter_hints = 0; + + if (hints & GTK_TEXT_INPUT_CONTENT_HINT_COMPLETION) + clutter_hints |= CLUTTER_INPUT_CONTENT_HINT_COMPLETION; + if (hints & GTK_TEXT_INPUT_CONTENT_HINT_SPELLCHECK) + clutter_hints |= CLUTTER_INPUT_CONTENT_HINT_SPELLCHECK; + if (hints & GTK_TEXT_INPUT_CONTENT_HINT_AUTO_CAPITALIZATION) + clutter_hints |= CLUTTER_INPUT_CONTENT_HINT_AUTO_CAPITALIZATION; + if (hints & GTK_TEXT_INPUT_CONTENT_HINT_LOWERCASE) + clutter_hints |= CLUTTER_INPUT_CONTENT_HINT_LOWERCASE; + if (hints & GTK_TEXT_INPUT_CONTENT_HINT_UPPERCASE) + clutter_hints |= CLUTTER_INPUT_CONTENT_HINT_UPPERCASE; + if (hints & GTK_TEXT_INPUT_CONTENT_HINT_TITLECASE) + clutter_hints |= CLUTTER_INPUT_CONTENT_HINT_TITLECASE; + if (hints & GTK_TEXT_INPUT_CONTENT_HINT_HIDDEN_TEXT) + clutter_hints |= CLUTTER_INPUT_CONTENT_HINT_HIDDEN_TEXT; + if (hints & GTK_TEXT_INPUT_CONTENT_HINT_SENSITIVE_DATA) + clutter_hints |= CLUTTER_INPUT_CONTENT_HINT_SENSITIVE_DATA; + if (hints & GTK_TEXT_INPUT_CONTENT_HINT_LATIN) + clutter_hints |= CLUTTER_INPUT_CONTENT_HINT_LATIN; + if (hints & GTK_TEXT_INPUT_CONTENT_HINT_MULTILINE) + clutter_hints |= CLUTTER_INPUT_CONTENT_HINT_MULTILINE; + + return clutter_hints; +} + +static ClutterInputContentPurpose +translate_purpose (uint32_t purpose) +{ + switch (purpose) + { + case GTK_TEXT_INPUT_CONTENT_PURPOSE_NORMAL: + return CLUTTER_INPUT_CONTENT_PURPOSE_NORMAL; + case GTK_TEXT_INPUT_CONTENT_PURPOSE_ALPHA: + return CLUTTER_INPUT_CONTENT_PURPOSE_ALPHA; + case GTK_TEXT_INPUT_CONTENT_PURPOSE_DIGITS: + return CLUTTER_INPUT_CONTENT_PURPOSE_DIGITS; + case GTK_TEXT_INPUT_CONTENT_PURPOSE_NUMBER: + return CLUTTER_INPUT_CONTENT_PURPOSE_NUMBER; + case GTK_TEXT_INPUT_CONTENT_PURPOSE_PHONE: + return CLUTTER_INPUT_CONTENT_PURPOSE_PHONE; + case GTK_TEXT_INPUT_CONTENT_PURPOSE_URL: + return CLUTTER_INPUT_CONTENT_PURPOSE_URL; + case GTK_TEXT_INPUT_CONTENT_PURPOSE_EMAIL: + return CLUTTER_INPUT_CONTENT_PURPOSE_EMAIL; + case GTK_TEXT_INPUT_CONTENT_PURPOSE_NAME: + return CLUTTER_INPUT_CONTENT_PURPOSE_NAME; + case GTK_TEXT_INPUT_CONTENT_PURPOSE_PASSWORD: + return CLUTTER_INPUT_CONTENT_PURPOSE_PASSWORD; + case GTK_TEXT_INPUT_CONTENT_PURPOSE_DATE: + return CLUTTER_INPUT_CONTENT_PURPOSE_DATE; + case GTK_TEXT_INPUT_CONTENT_PURPOSE_TIME: + return CLUTTER_INPUT_CONTENT_PURPOSE_TIME; + case GTK_TEXT_INPUT_CONTENT_PURPOSE_DATETIME: + return CLUTTER_INPUT_CONTENT_PURPOSE_DATETIME; + case GTK_TEXT_INPUT_CONTENT_PURPOSE_TERMINAL: + return CLUTTER_INPUT_CONTENT_PURPOSE_TERMINAL; + } + + g_warn_if_reached (); + return CLUTTER_INPUT_CONTENT_PURPOSE_NORMAL; +} + +static void +text_input_set_content_type (struct wl_client *client, + struct wl_resource *resource, + uint32_t hint, + uint32_t purpose) +{ + MetaWaylandGtkTextInput *text_input = wl_resource_get_user_data (resource); + + if (!text_input->surface) + return; + + text_input->content_type_hint = hint; + text_input->content_type_purpose = purpose; + text_input->pending_state |= META_WAYLAND_PENDING_STATE_CONTENT_TYPE; +} + +static void +text_input_set_cursor_rectangle (struct wl_client *client, + struct wl_resource *resource, + int32_t x, + int32_t y, + int32_t width, + int32_t height) +{ + MetaWaylandGtkTextInput *text_input = wl_resource_get_user_data (resource); + + if (!text_input->surface) + return; + + text_input->cursor_rect = (cairo_rectangle_int_t) { x, y, width, height }; + text_input->pending_state |= META_WAYLAND_PENDING_STATE_INPUT_RECT; +} + +static void +text_input_commit_state (struct wl_client *client, + struct wl_resource *resource) +{ + MetaWaylandGtkTextInput *text_input = wl_resource_get_user_data (resource); + ClutterInputFocus *focus = text_input->input_focus; + + if (!clutter_input_focus_is_focused (focus)) + return; + if (text_input->surface == NULL) + return; + + if (text_input->pending_state & META_WAYLAND_PENDING_STATE_CONTENT_TYPE) + { + clutter_input_focus_set_content_hints (text_input->input_focus, + translate_hints (text_input->content_type_hint)); + clutter_input_focus_set_content_purpose (text_input->input_focus, + translate_purpose (text_input->content_type_purpose)); + } + + if (text_input->pending_state & META_WAYLAND_PENDING_STATE_SURROUNDING_TEXT) + { + clutter_input_focus_set_surrounding (text_input->input_focus, + text_input->surrounding.text, + text_input->surrounding.cursor, + text_input->surrounding.anchor); + } + + if (text_input->pending_state & META_WAYLAND_PENDING_STATE_INPUT_RECT) + { + graphene_rect_t cursor_rect; + float x1, y1, x2, y2; + cairo_rectangle_int_t rect; + + rect = text_input->cursor_rect; + meta_wayland_surface_get_absolute_coordinates (text_input->surface, + rect.x, rect.y, &x1, &y1); + meta_wayland_surface_get_absolute_coordinates (text_input->surface, + rect.x + rect.width, + rect.y + rect.height, + &x2, &y2); + + graphene_rect_init (&cursor_rect, x1, y1, x2 - x1, y2 - y1); + clutter_input_focus_set_cursor_location (text_input->input_focus, + &cursor_rect); + } + + text_input->pending_state = META_WAYLAND_PENDING_STATE_NONE; +} + +static struct gtk_text_input_interface meta_text_input_interface = { + text_input_destroy, + text_input_enable, + text_input_disable, + text_input_set_surrounding_text, + text_input_set_content_type, + text_input_set_cursor_rectangle, + text_input_commit_state, +}; + +MetaWaylandGtkTextInput * +meta_wayland_gtk_text_input_new (MetaWaylandSeat *seat) +{ + MetaWaylandGtkTextInput *text_input; + + text_input = g_new0 (MetaWaylandGtkTextInput, 1); + text_input->input_focus = meta_wayland_text_input_focus_new (text_input); + text_input->seat = seat; + + wl_list_init (&text_input->resource_list); + wl_list_init (&text_input->focus_resource_list); + text_input->surface_listener.notify = text_input_handle_focus_surface_destroy; + + return text_input; +} + +void +meta_wayland_gtk_text_input_destroy (MetaWaylandGtkTextInput *text_input) +{ + meta_wayland_gtk_text_input_set_focus (text_input, NULL); + g_object_unref (text_input->input_focus); + g_free (text_input); +} + +static void +meta_wayland_text_input_create_new_resource (MetaWaylandGtkTextInput *text_input, + struct wl_client *client, + struct wl_resource *seat_resource, + uint32_t id) +{ + struct wl_resource *text_input_resource; + + text_input_resource = wl_resource_create (client, + >k_text_input_interface, + META_GTK_TEXT_INPUT_VERSION, + id); + + wl_resource_set_implementation (text_input_resource, + &meta_text_input_interface, + text_input, unbind_resource); + + if (text_input->surface && + wl_resource_get_client (text_input->surface->resource) == client) + { + wl_list_insert (&text_input->focus_resource_list, + wl_resource_get_link (text_input_resource)); + + gtk_text_input_send_enter (text_input_resource, + text_input->focus_serial, + text_input->surface->resource); + } + else + { + wl_list_insert (&text_input->resource_list, + wl_resource_get_link (text_input_resource)); + } +} + +static void +text_input_manager_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +text_input_manager_get_text_input (struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *seat_resource) +{ + MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); + + meta_wayland_text_input_create_new_resource (seat->gtk_text_input, client, + seat_resource, id); +} + +static struct gtk_text_input_manager_interface meta_text_input_manager_interface = { + text_input_manager_destroy, + text_input_manager_get_text_input, +}; + +static void +bind_text_input (struct wl_client *client, + void *data, + uint32_t version, + uint32_t id) +{ + struct wl_resource *resource; + + resource = wl_resource_create (client, + >k_text_input_manager_interface, + META_GTK_TEXT_INPUT_VERSION, + id); + wl_resource_set_implementation (resource, + &meta_text_input_manager_interface, + NULL, NULL); +} + +gboolean +meta_wayland_gtk_text_input_init (MetaWaylandCompositor *compositor) +{ + return (wl_global_create (compositor->wayland_display, + >k_text_input_manager_interface, + META_GTK_TEXT_INPUT_VERSION, + compositor->seat->gtk_text_input, + bind_text_input) != NULL); +} + +gboolean +meta_wayland_gtk_text_input_handle_event (MetaWaylandGtkTextInput *text_input, + const ClutterEvent *event) +{ + if (!text_input->surface || + !clutter_input_focus_is_focused (text_input->input_focus)) + return FALSE; + + return clutter_input_focus_filter_event (text_input->input_focus, event); +} diff --git a/src/wayland/meta-wayland-text-input-legacy.h b/src/wayland/meta-wayland-text-input-legacy.h new file mode 100644 index 000000000..55bfed809 --- /dev/null +++ b/src/wayland/meta-wayland-text-input-legacy.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef META_WAYLAND_GTK_TEXT_INPUT_H +#define META_WAYLAND_GTK_TEXT_INPUT_H + +#include <wayland-server.h> + +#include "meta/window.h" +#include "wayland/meta-wayland-types.h" + +typedef struct _MetaWaylandGtkTextInput MetaWaylandGtkTextInput; + +MetaWaylandGtkTextInput * meta_wayland_gtk_text_input_new (MetaWaylandSeat *seat); +void meta_wayland_gtk_text_input_destroy (MetaWaylandGtkTextInput *text_input); + +gboolean meta_wayland_gtk_text_input_init (MetaWaylandCompositor *compositor); + +void meta_wayland_gtk_text_input_set_focus (MetaWaylandGtkTextInput *text_input, + MetaWaylandSurface *surface); + +gboolean meta_wayland_gtk_text_input_handle_event (MetaWaylandGtkTextInput *text_input, + const ClutterEvent *event); + +#endif /* META_WAYLAND_GTK_TEXT_INPUT_H */ diff --git a/src/wayland/meta-wayland-text-input.c b/src/wayland/meta-wayland-text-input.c new file mode 100644 index 000000000..d4c377b73 --- /dev/null +++ b/src/wayland/meta-wayland-text-input.c @@ -0,0 +1,766 @@ +/* + * Copyright (C) 2017, 2018 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#include "config.h" + +#include "wayland/meta-wayland-text-input.h" + +#include <wayland-server.h> + +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-wayland-seat.h" +#include "wayland/meta-wayland-versions.h" + +#include "text-input-unstable-v3-server-protocol.h" + +#define META_TYPE_WAYLAND_TEXT_INPUT_FOCUS (meta_wayland_text_input_focus_get_type ()) + +typedef enum +{ + META_WAYLAND_PENDING_STATE_NONE = 0, + META_WAYLAND_PENDING_STATE_INPUT_RECT = 1 << 0, + META_WAYLAND_PENDING_STATE_CONTENT_TYPE = 1 << 1, + META_WAYLAND_PENDING_STATE_SURROUNDING_TEXT = 1 << 2, + META_WAYLAND_PENDING_STATE_CHANGE_CAUSE = 1 << 3, + META_WAYLAND_PENDING_STATE_ENABLED = 1 << 4, +} MetaWaylandTextInputPendingState; + +typedef struct _MetaWaylandTextInput MetaWaylandTextInput; + +struct _MetaWaylandTextInput +{ + MetaWaylandSeat *seat; + ClutterInputFocus *input_focus; + + struct wl_list resource_list; + struct wl_list focus_resource_list; + MetaWaylandSurface *surface; + struct wl_listener surface_listener; + + MetaWaylandTextInputPendingState pending_state; + + GHashTable *resource_serials; + + struct + { + char *text; + uint32_t cursor; + uint32_t anchor; + } surrounding; + + cairo_rectangle_int_t cursor_rect; + + uint32_t content_type_hint; + uint32_t content_type_purpose; + uint32_t text_change_cause; + gboolean enabled; + + guint done_idle_id; +}; + +struct _MetaWaylandTextInputFocus +{ + ClutterInputFocus parent_instance; + MetaWaylandTextInput *text_input; +}; + +G_DECLARE_FINAL_TYPE (MetaWaylandTextInputFocus, meta_wayland_text_input_focus, + META, WAYLAND_TEXT_INPUT_FOCUS, ClutterInputFocus) +G_DEFINE_TYPE (MetaWaylandTextInputFocus, meta_wayland_text_input_focus, + CLUTTER_TYPE_INPUT_FOCUS) + +static void +meta_wayland_text_input_focus_request_surrounding (ClutterInputFocus *focus) +{ + MetaWaylandTextInput *text_input; + + text_input = META_WAYLAND_TEXT_INPUT_FOCUS (focus)->text_input; + clutter_input_focus_set_surrounding (focus, + text_input->surrounding.text, + text_input->surrounding.cursor, + text_input->surrounding.anchor); +} + +static uint32_t +lookup_serial (MetaWaylandTextInput *text_input, + struct wl_resource *resource) +{ + return GPOINTER_TO_UINT (g_hash_table_lookup (text_input->resource_serials, + resource)); +} + +static void +increment_serial (MetaWaylandTextInput *text_input, + struct wl_resource *resource) +{ + uint32_t serial; + + serial = lookup_serial (text_input, resource); + g_hash_table_insert (text_input->resource_serials, resource, + GUINT_TO_POINTER (serial + 1)); +} + +static void +clutter_input_focus_send_done (ClutterInputFocus *focus) +{ + MetaWaylandTextInput *text_input; + struct wl_resource *resource; + + text_input = META_WAYLAND_TEXT_INPUT_FOCUS (focus)->text_input; + + wl_resource_for_each (resource, &text_input->focus_resource_list) + { + zwp_text_input_v3_send_done (resource, + lookup_serial (text_input, resource)); + } +} + +static gboolean +done_idle_cb (gpointer user_data) +{ + ClutterInputFocus *focus = user_data; + MetaWaylandTextInput *text_input; + + text_input = META_WAYLAND_TEXT_INPUT_FOCUS (focus)->text_input; + clutter_input_focus_send_done (focus); + + text_input->done_idle_id = 0; + return G_SOURCE_REMOVE; +} + +static void +meta_wayland_text_input_focus_defer_done (ClutterInputFocus *focus) +{ + MetaWaylandTextInput *text_input; + + text_input = META_WAYLAND_TEXT_INPUT_FOCUS (focus)->text_input; + + if (text_input->done_idle_id != 0) + return; + + /* This operates on 2 principles: + * - IM operations come as individual ClutterEvents + * - We want to run .done after them all. The slightly lower + * G_PRIORITY_DEFAULT + 1 priority should ensure we at least group + * all events seen so far. + * + * FIXME: .done may be delayed indefinitely if there's a high enough + * priority idle source in the main loop. It's unlikely that + * recurring idles run at this high priority though. + */ + text_input->done_idle_id = g_idle_add_full (CLUTTER_PRIORITY_EVENTS + 1, + done_idle_cb, focus, NULL); +} + +static void +meta_wayland_text_input_focus_flush_done (ClutterInputFocus *focus) +{ + MetaWaylandTextInput *text_input; + + text_input = META_WAYLAND_TEXT_INPUT_FOCUS (focus)->text_input; + + if (text_input->done_idle_id == 0) + return; + + g_clear_handle_id (&text_input->done_idle_id, g_source_remove); + clutter_input_focus_send_done (focus); +} + +static void +meta_wayland_text_input_focus_delete_surrounding (ClutterInputFocus *focus, + int offset, + guint len) +{ + MetaWaylandTextInput *text_input; + uint32_t before_length; + uint32_t after_length; + struct wl_resource *resource; + + text_input = META_WAYLAND_TEXT_INPUT_FOCUS (focus)->text_input; + before_length = ABS (MIN (offset, 0)); + after_length = MAX (0, offset + len); + g_warn_if_fail (ABS (offset) <= len); + + wl_resource_for_each (resource, &text_input->focus_resource_list) + { + zwp_text_input_v3_send_delete_surrounding_text (resource, + before_length, + after_length); + } + + meta_wayland_text_input_focus_defer_done (focus); +} + +static void +meta_wayland_text_input_focus_commit_text (ClutterInputFocus *focus, + const gchar *text) +{ + MetaWaylandTextInput *text_input; + struct wl_resource *resource; + + text_input = META_WAYLAND_TEXT_INPUT_FOCUS (focus)->text_input; + + wl_resource_for_each (resource, &text_input->focus_resource_list) + { + zwp_text_input_v3_send_preedit_string (resource, NULL, 0, 0); + zwp_text_input_v3_send_commit_string (resource, text); + } + + meta_wayland_text_input_focus_defer_done (focus); +} + +static void +meta_wayland_text_input_focus_set_preedit_text (ClutterInputFocus *focus, + const gchar *text, + guint cursor) +{ + MetaWaylandTextInput *text_input; + struct wl_resource *resource; + gsize pos = 0; + + text_input = META_WAYLAND_TEXT_INPUT_FOCUS (focus)->text_input; + + if (text) + pos = g_utf8_offset_to_pointer (text, cursor) - text; + + wl_resource_for_each (resource, &text_input->focus_resource_list) + { + zwp_text_input_v3_send_preedit_string (resource, text, pos, pos); + } + + meta_wayland_text_input_focus_defer_done (focus); +} + +static void +meta_wayland_text_input_focus_class_init (MetaWaylandTextInputFocusClass *klass) +{ + ClutterInputFocusClass *focus_class = CLUTTER_INPUT_FOCUS_CLASS (klass); + + focus_class->request_surrounding = meta_wayland_text_input_focus_request_surrounding; + focus_class->delete_surrounding = meta_wayland_text_input_focus_delete_surrounding; + focus_class->commit_text = meta_wayland_text_input_focus_commit_text; + focus_class->set_preedit_text = meta_wayland_text_input_focus_set_preedit_text; +} + +static void +meta_wayland_text_input_focus_init (MetaWaylandTextInputFocus *focus) +{ +} + +static ClutterInputFocus * +meta_wayland_text_input_focus_new (MetaWaylandTextInput *text_input) +{ + MetaWaylandTextInputFocus *focus; + + focus = g_object_new (META_TYPE_WAYLAND_TEXT_INPUT_FOCUS, NULL); + focus->text_input = text_input; + + return CLUTTER_INPUT_FOCUS (focus); +} + +static void +text_input_handle_focus_surface_destroy (struct wl_listener *listener, + void *data) +{ + MetaWaylandTextInput *text_input = wl_container_of (listener, text_input, + surface_listener); + + meta_wayland_text_input_set_focus (text_input, NULL); +} + +static void +move_resources (struct wl_list *destination, struct wl_list *source) +{ + wl_list_insert_list (destination, source); + wl_list_init (source); +} + +static void +move_resources_for_client (struct wl_list *destination, + struct wl_list *source, + struct wl_client *client) +{ + struct wl_resource *resource, *tmp; + wl_resource_for_each_safe (resource, tmp, source) + { + if (wl_resource_get_client (resource) == client) + { + wl_list_remove (wl_resource_get_link (resource)); + wl_list_insert (destination, wl_resource_get_link (resource)); + } + } +} + +void +meta_wayland_text_input_set_focus (MetaWaylandTextInput *text_input, + MetaWaylandSurface *surface) +{ + if (text_input->surface == surface) + return; + + text_input->pending_state = META_WAYLAND_PENDING_STATE_NONE; + + if (text_input->surface) + { + if (!wl_list_empty (&text_input->focus_resource_list)) + { + ClutterInputFocus *focus = text_input->input_focus; + ClutterInputMethod *input_method; + struct wl_resource *resource; + + if (clutter_input_focus_is_focused (focus)) + { + input_method = clutter_backend_get_input_method (clutter_get_default_backend ()); + clutter_input_method_focus_out (input_method); + } + + wl_resource_for_each (resource, &text_input->focus_resource_list) + { + zwp_text_input_v3_send_leave (resource, + text_input->surface->resource); + } + + move_resources (&text_input->resource_list, + &text_input->focus_resource_list); + } + + wl_list_remove (&text_input->surface_listener.link); + text_input->surface = NULL; + } + + if (surface) + { + struct wl_resource *focus_surface_resource; + + text_input->surface = surface; + focus_surface_resource = text_input->surface->resource; + wl_resource_add_destroy_listener (focus_surface_resource, + &text_input->surface_listener); + + move_resources_for_client (&text_input->focus_resource_list, + &text_input->resource_list, + wl_resource_get_client (focus_surface_resource)); + + if (!wl_list_empty (&text_input->focus_resource_list)) + { + struct wl_resource *resource; + + wl_resource_for_each (resource, &text_input->focus_resource_list) + { + zwp_text_input_v3_send_enter (resource, surface->resource); + } + } + } +} + +static void +text_input_destructor (struct wl_resource *resource) +{ + MetaWaylandTextInput *text_input = wl_resource_get_user_data (resource); + + g_hash_table_remove (text_input->resource_serials, resource); + wl_list_remove (wl_resource_get_link (resource)); +} + +static void +text_input_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +text_input_enable (struct wl_client *client, + struct wl_resource *resource) +{ + MetaWaylandTextInput *text_input = wl_resource_get_user_data (resource); + + text_input->enabled = TRUE; + text_input->pending_state |= META_WAYLAND_PENDING_STATE_ENABLED; +} + +static void +text_input_disable (struct wl_client *client, + struct wl_resource *resource) +{ + MetaWaylandTextInput *text_input = wl_resource_get_user_data (resource); + + text_input->enabled = FALSE; + text_input->pending_state |= META_WAYLAND_PENDING_STATE_ENABLED; +} + +static void +text_input_set_surrounding_text (struct wl_client *client, + struct wl_resource *resource, + const char *text, + int32_t cursor, + int32_t anchor) +{ + MetaWaylandTextInput *text_input = wl_resource_get_user_data (resource); + + g_free (text_input->surrounding.text); + text_input->surrounding.text = g_strdup (text); + text_input->surrounding.cursor = cursor; + text_input->surrounding.anchor = anchor; + text_input->pending_state |= META_WAYLAND_PENDING_STATE_SURROUNDING_TEXT; +} + +static void +text_input_set_text_change_cause (struct wl_client *client, + struct wl_resource *resource, + uint32_t cause) +{ + MetaWaylandTextInput *text_input = wl_resource_get_user_data (resource); + + text_input->text_change_cause = cause; + text_input->pending_state |= META_WAYLAND_PENDING_STATE_CHANGE_CAUSE; +} + +static ClutterInputContentHintFlags +translate_hints (uint32_t hints) +{ + ClutterInputContentHintFlags clutter_hints = 0; + + if (hints & ZWP_TEXT_INPUT_V3_CONTENT_HINT_COMPLETION) + clutter_hints |= CLUTTER_INPUT_CONTENT_HINT_COMPLETION; + if (hints & ZWP_TEXT_INPUT_V3_CONTENT_HINT_SPELLCHECK) + clutter_hints |= CLUTTER_INPUT_CONTENT_HINT_SPELLCHECK; + if (hints & ZWP_TEXT_INPUT_V3_CONTENT_HINT_AUTO_CAPITALIZATION) + clutter_hints |= CLUTTER_INPUT_CONTENT_HINT_AUTO_CAPITALIZATION; + if (hints & ZWP_TEXT_INPUT_V3_CONTENT_HINT_LOWERCASE) + clutter_hints |= CLUTTER_INPUT_CONTENT_HINT_LOWERCASE; + if (hints & ZWP_TEXT_INPUT_V3_CONTENT_HINT_UPPERCASE) + clutter_hints |= CLUTTER_INPUT_CONTENT_HINT_UPPERCASE; + if (hints & ZWP_TEXT_INPUT_V3_CONTENT_HINT_TITLECASE) + clutter_hints |= CLUTTER_INPUT_CONTENT_HINT_TITLECASE; + if (hints & ZWP_TEXT_INPUT_V3_CONTENT_HINT_HIDDEN_TEXT) + clutter_hints |= CLUTTER_INPUT_CONTENT_HINT_HIDDEN_TEXT; + if (hints & ZWP_TEXT_INPUT_V3_CONTENT_HINT_SENSITIVE_DATA) + clutter_hints |= CLUTTER_INPUT_CONTENT_HINT_SENSITIVE_DATA; + if (hints & ZWP_TEXT_INPUT_V3_CONTENT_HINT_LATIN) + clutter_hints |= CLUTTER_INPUT_CONTENT_HINT_LATIN; + if (hints & ZWP_TEXT_INPUT_V3_CONTENT_HINT_MULTILINE) + clutter_hints |= CLUTTER_INPUT_CONTENT_HINT_MULTILINE; + + return clutter_hints; +} + +static ClutterInputContentPurpose +translate_purpose (uint32_t purpose) +{ + switch (purpose) + { + case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NORMAL: + return CLUTTER_INPUT_CONTENT_PURPOSE_NORMAL; + case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_ALPHA: + return CLUTTER_INPUT_CONTENT_PURPOSE_ALPHA; + case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_DIGITS: + return CLUTTER_INPUT_CONTENT_PURPOSE_DIGITS; + case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NUMBER: + return CLUTTER_INPUT_CONTENT_PURPOSE_NUMBER; + case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PHONE: + return CLUTTER_INPUT_CONTENT_PURPOSE_PHONE; + case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_URL: + return CLUTTER_INPUT_CONTENT_PURPOSE_URL; + case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_EMAIL: + return CLUTTER_INPUT_CONTENT_PURPOSE_EMAIL; + case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NAME: + return CLUTTER_INPUT_CONTENT_PURPOSE_NAME; + case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PASSWORD: + return CLUTTER_INPUT_CONTENT_PURPOSE_PASSWORD; + case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_DATE: + return CLUTTER_INPUT_CONTENT_PURPOSE_DATE; + case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_TIME: + return CLUTTER_INPUT_CONTENT_PURPOSE_TIME; + case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_DATETIME: + return CLUTTER_INPUT_CONTENT_PURPOSE_DATETIME; + case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_TERMINAL: + return CLUTTER_INPUT_CONTENT_PURPOSE_TERMINAL; + } + + g_warn_if_reached (); + return CLUTTER_INPUT_CONTENT_PURPOSE_NORMAL; +} + +static void +text_input_set_content_type (struct wl_client *client, + struct wl_resource *resource, + uint32_t hint, + uint32_t purpose) +{ + MetaWaylandTextInput *text_input = wl_resource_get_user_data (resource); + + if (!text_input->surface) + return; + + text_input->content_type_hint = hint; + text_input->content_type_purpose = purpose; + text_input->pending_state |= META_WAYLAND_PENDING_STATE_CONTENT_TYPE; +} + +static void +text_input_set_cursor_rectangle (struct wl_client *client, + struct wl_resource *resource, + int32_t x, + int32_t y, + int32_t width, + int32_t height) +{ + MetaWaylandTextInput *text_input = wl_resource_get_user_data (resource); + + if (!text_input->surface) + return; + + text_input->cursor_rect = (cairo_rectangle_int_t) { x, y, width, height }; + text_input->pending_state |= META_WAYLAND_PENDING_STATE_INPUT_RECT; +} + +static void +meta_wayland_text_input_reset (MetaWaylandTextInput *text_input) +{ + g_clear_pointer (&text_input->surrounding.text, g_free); + text_input->content_type_hint = ZWP_TEXT_INPUT_V3_CONTENT_HINT_NONE; + text_input->content_type_purpose = ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NORMAL; + text_input->text_change_cause = ZWP_TEXT_INPUT_V3_CHANGE_CAUSE_INPUT_METHOD; + text_input->cursor_rect = (cairo_rectangle_int_t) { 0, 0, 0, 0 }; + text_input->pending_state = META_WAYLAND_PENDING_STATE_NONE; +} + +static void +text_input_commit_state (struct wl_client *client, + struct wl_resource *resource) +{ + MetaWaylandTextInput *text_input = wl_resource_get_user_data (resource); + ClutterInputFocus *focus = text_input->input_focus; + gboolean enable_panel = FALSE; + ClutterInputMethod *input_method; + + increment_serial (text_input, resource); + + if (text_input->surface == NULL) + return; + + input_method = clutter_backend_get_input_method (clutter_get_default_backend ()); + + if (input_method && + text_input->pending_state & META_WAYLAND_PENDING_STATE_ENABLED) + { + if (text_input->enabled) + { + if (!clutter_input_focus_is_focused (focus)) + clutter_input_method_focus_in (input_method, focus); + else + enable_panel = TRUE; + + clutter_input_focus_set_can_show_preedit (focus, TRUE); + } + else if (clutter_input_focus_is_focused (focus)) + { + text_input->pending_state = META_WAYLAND_PENDING_STATE_NONE; + clutter_input_focus_reset (text_input->input_focus); + clutter_input_method_focus_out (input_method); + } + } + + if (!clutter_input_focus_is_focused (focus)) + { + meta_wayland_text_input_reset (text_input); + return; + } + + if (text_input->pending_state & META_WAYLAND_PENDING_STATE_CONTENT_TYPE) + { + clutter_input_focus_set_content_hints (text_input->input_focus, + translate_hints (text_input->content_type_hint)); + clutter_input_focus_set_content_purpose (text_input->input_focus, + translate_purpose (text_input->content_type_purpose)); + } + + if (text_input->pending_state & META_WAYLAND_PENDING_STATE_SURROUNDING_TEXT) + { + clutter_input_focus_set_surrounding (text_input->input_focus, + text_input->surrounding.text, + text_input->surrounding.cursor, + text_input->surrounding.anchor); + } + + if (text_input->pending_state & META_WAYLAND_PENDING_STATE_INPUT_RECT) + { + graphene_rect_t cursor_rect; + float x1, y1, x2, y2; + cairo_rectangle_int_t rect; + + rect = text_input->cursor_rect; + meta_wayland_surface_get_absolute_coordinates (text_input->surface, + rect.x, rect.y, &x1, &y1); + meta_wayland_surface_get_absolute_coordinates (text_input->surface, + rect.x + rect.width, + rect.y + rect.height, + &x2, &y2); + + graphene_rect_init (&cursor_rect, x1, y1, x2 - x1, y2 - y1); + clutter_input_focus_set_cursor_location (text_input->input_focus, + &cursor_rect); + } + + meta_wayland_text_input_reset (text_input); + + if (enable_panel) + clutter_input_focus_set_input_panel_state (focus, CLUTTER_INPUT_PANEL_STATE_ON); +} + +static struct zwp_text_input_v3_interface meta_text_input_interface = { + text_input_destroy, + text_input_enable, + text_input_disable, + text_input_set_surrounding_text, + text_input_set_text_change_cause, + text_input_set_content_type, + text_input_set_cursor_rectangle, + text_input_commit_state, +}; + +MetaWaylandTextInput * +meta_wayland_text_input_new (MetaWaylandSeat *seat) +{ + MetaWaylandTextInput *text_input; + + text_input = g_new0 (MetaWaylandTextInput, 1); + text_input->input_focus = meta_wayland_text_input_focus_new (text_input); + text_input->seat = seat; + + wl_list_init (&text_input->resource_list); + wl_list_init (&text_input->focus_resource_list); + text_input->surface_listener.notify = text_input_handle_focus_surface_destroy; + + text_input->resource_serials = g_hash_table_new (NULL, NULL); + + return text_input; +} + +void +meta_wayland_text_input_destroy (MetaWaylandTextInput *text_input) +{ + meta_wayland_text_input_set_focus (text_input, NULL); + g_object_unref (text_input->input_focus); + g_hash_table_destroy (text_input->resource_serials); + g_free (text_input); +} + +static void +meta_wayland_text_input_create_new_resource (MetaWaylandTextInput *text_input, + struct wl_client *client, + struct wl_resource *seat_resource, + uint32_t id) +{ + struct wl_resource *text_input_resource; + + text_input_resource = wl_resource_create (client, + &zwp_text_input_v3_interface, + META_ZWP_TEXT_INPUT_V3_VERSION, + id); + + wl_resource_set_implementation (text_input_resource, + &meta_text_input_interface, + text_input, text_input_destructor); + + if (text_input->surface && + wl_resource_get_client (text_input->surface->resource) == client) + { + wl_list_insert (&text_input->focus_resource_list, + wl_resource_get_link (text_input_resource)); + + zwp_text_input_v3_send_enter (text_input_resource, + text_input->surface->resource); + } + else + { + wl_list_insert (&text_input->resource_list, + wl_resource_get_link (text_input_resource)); + } +} + +static void +text_input_manager_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +text_input_manager_get_text_input (struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *seat_resource) +{ + MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); + + meta_wayland_text_input_create_new_resource (seat->text_input, client, + seat_resource, id); +} + +static struct zwp_text_input_manager_v3_interface meta_text_input_manager_interface = { + text_input_manager_destroy, + text_input_manager_get_text_input, +}; + +static void +bind_text_input (struct wl_client *client, + void *data, + uint32_t version, + uint32_t id) +{ + struct wl_resource *resource; + + resource = wl_resource_create (client, + &zwp_text_input_manager_v3_interface, + META_ZWP_TEXT_INPUT_V3_VERSION, + id); + wl_resource_set_implementation (resource, + &meta_text_input_manager_interface, + NULL, NULL); +} + +gboolean +meta_wayland_text_input_init (MetaWaylandCompositor *compositor) +{ + return (wl_global_create (compositor->wayland_display, + &zwp_text_input_manager_v3_interface, + META_ZWP_TEXT_INPUT_V3_VERSION, + compositor->seat->text_input, + bind_text_input) != NULL); +} + +gboolean +meta_wayland_text_input_handle_event (MetaWaylandTextInput *text_input, + const ClutterEvent *event) +{ + if (!text_input->surface || + !clutter_input_focus_is_focused (text_input->input_focus)) + return FALSE; + + if ((event->type == CLUTTER_KEY_PRESS || + event->type == CLUTTER_KEY_RELEASE) && + clutter_event_get_flags (event) & CLUTTER_EVENT_FLAG_INPUT_METHOD) + meta_wayland_text_input_focus_flush_done (text_input->input_focus); + + return clutter_input_focus_filter_event (text_input->input_focus, event); +} diff --git a/src/wayland/meta-wayland-text-input.h b/src/wayland/meta-wayland-text-input.h new file mode 100644 index 000000000..7e3544d95 --- /dev/null +++ b/src/wayland/meta-wayland-text-input.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef META_WAYLAND_TEXT_INPUT_H +#define META_WAYLAND_TEXT_INPUT_H + +#include <wayland-server.h> + +#include "meta/window.h" +#include "wayland/meta-wayland-types.h" + +#define META_TYPE_WAYLAND_TEXT_INPUT (meta_wayland_text_input_get_type ()) +G_DECLARE_FINAL_TYPE (MetaWaylandTextInput, + meta_wayland_text_input, + META, WAYLAND_TEXT_INPUT, + GObject); + +MetaWaylandTextInput * meta_wayland_text_input_new (MetaWaylandSeat *seat); +void meta_wayland_text_input_destroy (MetaWaylandTextInput *text_input); + +gboolean meta_wayland_text_input_init (MetaWaylandCompositor *compositor); + +void meta_wayland_text_input_set_focus (MetaWaylandTextInput *text_input, + MetaWaylandSurface *surface); + +gboolean meta_wayland_text_input_handle_event (MetaWaylandTextInput *text_input, + const ClutterEvent *event); + +#endif /* META_WAYLAND_TEXT_INPUT_H */ diff --git a/src/wayland/meta-wayland-touch.c b/src/wayland/meta-wayland-touch.c new file mode 100644 index 000000000..9c2cfc9df --- /dev/null +++ b/src/wayland/meta-wayland-touch.c @@ -0,0 +1,697 @@ +/* + * Wayland Support + * + * Copyright (C) 2014 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#include "config.h" + +#include <glib.h> +#include <string.h> + +#include "compositor/meta-surface-actor-wayland.h" +#include "wayland/meta-wayland-private.h" + +#ifdef HAVE_NATIVE_BACKEND +#include <libinput.h> +#include "backends/native/meta-backend-native.h" +#include "backends/native/meta-event-native.h" +#include "backends/native/meta-seat-native.h" +#endif + +G_DEFINE_TYPE (MetaWaylandTouch, meta_wayland_touch, + META_TYPE_WAYLAND_INPUT_DEVICE) + +struct _MetaWaylandTouchSurface +{ + MetaWaylandSurface *surface; + MetaWaylandTouch *touch; + struct wl_listener surface_destroy_listener; + struct wl_list resource_list; + gint touch_count; +}; + +struct _MetaWaylandTouchInfo +{ + MetaWaylandTouchSurface *touch_surface; + guint32 slot_serial; + gint32 slot; + gfloat start_x; + gfloat start_y; + gfloat x; + gfloat y; + guint updated : 1; + guint begin_delivered : 1; +}; + +#ifdef HAVE_NATIVE_BACKEND +static void +move_resources (struct wl_list *destination, struct wl_list *source) +{ + wl_list_insert_list (destination, source); + wl_list_init (source); +} + +static void +move_resources_for_client (struct wl_list *destination, + struct wl_list *source, + struct wl_client *client) +{ + struct wl_resource *resource, *tmp; + wl_resource_for_each_safe (resource, tmp, source) + { + if (wl_resource_get_client (resource) == client) + { + wl_list_remove (wl_resource_get_link (resource)); + wl_list_insert (destination, wl_resource_get_link (resource)); + } + } +} + +static void +touch_surface_free (gpointer data) +{ + MetaWaylandTouchSurface *touch_surface = data; + MetaWaylandTouch *touch = touch_surface->touch; + + move_resources (&touch->resource_list, + &touch_surface->resource_list); + wl_list_remove (&touch_surface->surface_destroy_listener.link); + g_free (touch_surface); +} + +static MetaWaylandTouchSurface * +touch_surface_increment_touch (MetaWaylandTouchSurface *surface) +{ + surface->touch_count++; + return surface; +} + +static void +touch_surface_decrement_touch (MetaWaylandTouchSurface *touch_surface) +{ + touch_surface->touch_count--; + + if (touch_surface->touch_count == 0) + { + /* Now that there are no touches on the surface, free the + * MetaWaylandTouchSurface, the memory is actually owned by + * the touch_surface->touch_surfaces hashtable, so remove the + * item from there. + */ + MetaWaylandTouch *touch = touch_surface->touch; + g_hash_table_remove (touch->touch_surfaces, touch_surface->surface); + } +} + +static void +touch_handle_surface_destroy (struct wl_listener *listener, void *data) +{ + MetaWaylandTouchSurface *touch_surface = wl_container_of (listener, touch_surface, surface_destroy_listener); + MetaWaylandSurface *surface = touch_surface->surface; + MetaWaylandTouch *touch = touch_surface->touch; + MetaWaylandTouchInfo *touch_info; + GHashTableIter iter; + + g_hash_table_iter_init (&iter, touch->touches); + + /* Destroy all touches on the surface, this indirectly drops touch_count + * on the touch_surface to 0, also freeing touch_surface and removing + * from the touch_surfaces hashtable. + */ + while (g_hash_table_iter_next (&iter, NULL, (gpointer*) &touch_info)) + { + if (touch_info->touch_surface == touch_surface) + g_hash_table_iter_remove (&iter); + } + + /* Ensure the surface no longer exists */ + g_assert (g_hash_table_remove (touch->touch_surfaces, surface) == FALSE); +} + +static MetaWaylandTouchSurface * +touch_surface_get (MetaWaylandTouch *touch, + MetaWaylandSurface *surface) +{ + MetaWaylandTouchSurface *touch_surface; + + touch_surface = g_hash_table_lookup (touch->touch_surfaces, surface); + + if (touch_surface) + return touch_surface_increment_touch (touch_surface); + + /* Create a new one for this surface */ + touch_surface = g_new0 (MetaWaylandTouchSurface, 1); + touch_surface->touch = touch; + touch_surface->surface = surface; + touch_surface->touch_count = 1; + touch_surface->surface_destroy_listener.notify = touch_handle_surface_destroy; + wl_resource_add_destroy_listener (touch_surface->surface->resource, + &touch_surface->surface_destroy_listener); + + wl_list_init (&touch_surface->resource_list); + move_resources_for_client (&touch_surface->resource_list, + &touch->resource_list, + wl_resource_get_client (touch_surface->surface->resource)); + + g_hash_table_insert (touch->touch_surfaces, surface, touch_surface); + + return touch_surface; +} + +static MetaWaylandTouchInfo * +touch_get_info (MetaWaylandTouch *touch, + ClutterEventSequence *sequence, + gboolean create) +{ + MetaWaylandTouchInfo *touch_info; + + touch_info = g_hash_table_lookup (touch->touches, sequence); + + if (!touch_info && create) + { + touch_info = g_new0 (MetaWaylandTouchInfo, 1); + touch_info->slot = meta_event_native_sequence_get_slot (sequence); + g_hash_table_insert (touch->touches, sequence, touch_info); + } + + return touch_info; +} + +static void +touch_get_relative_coordinates (MetaWaylandTouch *touch, + MetaWaylandSurface *surface, + const ClutterEvent *event, + gfloat *x, + gfloat *y) +{ + gfloat event_x, event_y; + + clutter_event_get_coords (event, &event_x, &event_y); + + return meta_wayland_surface_get_relative_coordinates (surface, + event_x, event_y, + x, y); +} +#endif /* HAVE_NATIVE_BACKEND */ + +void +meta_wayland_touch_update (MetaWaylandTouch *touch, + const ClutterEvent *event) +{ +#ifdef HAVE_NATIVE_BACKEND + MetaWaylandTouchInfo *touch_info; + ClutterEventSequence *sequence; + + sequence = clutter_event_get_event_sequence (event); + + if (event->type == CLUTTER_TOUCH_BEGIN) + { + MetaWaylandSurface *surface = NULL; + ClutterActor *actor; + + actor = clutter_event_get_source (event); + + if (META_IS_SURFACE_ACTOR_WAYLAND (actor)) + surface = meta_surface_actor_wayland_get_surface (META_SURFACE_ACTOR_WAYLAND (actor)); + + if (!surface) + return; + + touch_info = touch_get_info (touch, sequence, TRUE); + touch_info->touch_surface = touch_surface_get (touch, surface); + clutter_event_get_coords (event, &touch_info->start_x, &touch_info->start_y); + } + else + touch_info = touch_get_info (touch, sequence, FALSE); + + if (!touch_info) + return; + + if (event->type != CLUTTER_TOUCH_BEGIN && + !touch_info->begin_delivered) + { + g_hash_table_remove (touch->touches, sequence); + return; + } + + if (event->type == CLUTTER_TOUCH_BEGIN || + event->type == CLUTTER_TOUCH_END) + { + MetaWaylandInputDevice *input_device = META_WAYLAND_INPUT_DEVICE (touch); + + touch_info->slot_serial = + meta_wayland_input_device_next_serial (input_device); + } + + touch_get_relative_coordinates (touch, touch_info->touch_surface->surface, + event, &touch_info->x, &touch_info->y); + touch_info->updated = TRUE; +#endif /* HAVE_NATIVE_BACKEND */ +} + +static void +handle_touch_begin (MetaWaylandTouch *touch, + const ClutterEvent *event) +{ +#ifdef HAVE_NATIVE_BACKEND + MetaWaylandTouchInfo *touch_info; + ClutterEventSequence *sequence; + struct wl_resource *resource; + struct wl_list *l; + + sequence = clutter_event_get_event_sequence (event); + touch_info = touch_get_info (touch, sequence, FALSE); + + if (!touch_info) + return; + + l = &touch_info->touch_surface->resource_list; + wl_resource_for_each(resource, l) + { + wl_touch_send_down (resource, touch_info->slot_serial, + clutter_event_get_time (event), + touch_info->touch_surface->surface->resource, + touch_info->slot, + wl_fixed_from_double (touch_info->x), + wl_fixed_from_double (touch_info->y)); + } + + touch_info->begin_delivered = TRUE; +#endif /* HAVE_NATIVE_BACKEND */ +} + +static void +handle_touch_update (MetaWaylandTouch *touch, + const ClutterEvent *event) +{ +#ifdef HAVE_NATIVE_BACKEND + MetaWaylandTouchInfo *touch_info; + ClutterEventSequence *sequence; + struct wl_resource *resource; + struct wl_list *l; + + sequence = clutter_event_get_event_sequence (event); + touch_info = touch_get_info (touch, sequence, FALSE); + + if (!touch_info) + return; + + l = &touch_info->touch_surface->resource_list; + wl_resource_for_each(resource, l) + { + wl_touch_send_motion (resource, + clutter_event_get_time (event), + touch_info->slot, + wl_fixed_from_double (touch_info->x), + wl_fixed_from_double (touch_info->y)); + } +#endif /* HAVE_NATIVE_BACKEND */ +} + +static void +handle_touch_end (MetaWaylandTouch *touch, + const ClutterEvent *event) +{ +#ifdef HAVE_NATIVE_BACKEND + MetaWaylandTouchInfo *touch_info; + ClutterEventSequence *sequence; + struct wl_resource *resource; + struct wl_list *l; + + sequence = clutter_event_get_event_sequence (event); + touch_info = touch_get_info (touch, sequence, FALSE); + + if (!touch_info) + return; + + l = &touch_info->touch_surface->resource_list; + wl_resource_for_each (resource, l) + { + wl_touch_send_up (resource, touch_info->slot_serial, + clutter_event_get_time (event), + touch_info->slot); + } + + g_hash_table_remove (touch->touches, sequence); +#endif /* HAVE_NATIVE_BACKEND */ +} + +static GList * +touch_get_surfaces (MetaWaylandTouch *touch, + gboolean only_updated) +{ + MetaWaylandTouchInfo *touch_info; + GList *surfaces = NULL; + GHashTableIter iter; + + g_hash_table_iter_init (&iter, touch->touches); + + while (g_hash_table_iter_next (&iter, NULL, (gpointer*) &touch_info)) + { + if (only_updated && !touch_info->updated) + continue; + if (g_list_find (surfaces, touch_info->touch_surface)) + continue; + + surfaces = g_list_prepend (surfaces, touch_info->touch_surface); + touch_info->updated = FALSE; + } + + return g_list_reverse (surfaces); +} + +static void +touch_send_frame_event (MetaWaylandTouch *touch) +{ + GList *surfaces, *s; + + surfaces = touch_get_surfaces (touch, TRUE); + + for (s = surfaces; s; s = s->next) + { + MetaWaylandTouchSurface *touch_surface = s->data; + struct wl_resource *resource; + struct wl_list *l; + + l = &touch_surface->resource_list; + wl_resource_for_each(resource, l) + { + wl_touch_send_frame (resource); + } + } + + g_list_free (surfaces); +} + +static void +check_send_frame_event (MetaWaylandTouch *touch, + const ClutterEvent *event) +{ + gboolean send_frame_event; +#ifdef HAVE_NATIVE_BACKEND + MetaBackend *backend = meta_get_backend (); + ClutterEventSequence *sequence; + gint32 slot; + + if (META_IS_BACKEND_NATIVE (backend)) + { + sequence = clutter_event_get_event_sequence (event); + slot = meta_event_native_sequence_get_slot (sequence); + touch->frame_slots &= ~(1 << slot); + + if (touch->frame_slots == 0) + send_frame_event = TRUE; + else + send_frame_event = FALSE; + } + else +#endif /* HAVE_NATIVE_BACKEND */ + { + send_frame_event = TRUE; + } + + if (send_frame_event) + touch_send_frame_event (touch); +} + +gboolean +meta_wayland_touch_handle_event (MetaWaylandTouch *touch, + const ClutterEvent *event) +{ + switch (event->type) + { + case CLUTTER_TOUCH_BEGIN: + handle_touch_begin (touch, event); + break; + + case CLUTTER_TOUCH_UPDATE: + handle_touch_update (touch, event); + break; + + case CLUTTER_TOUCH_END: + handle_touch_end (touch, event); + break; + + default: + return FALSE; + } + + check_send_frame_event (touch, event); + return FALSE; +} + +static void +unbind_resource (struct wl_resource *resource) +{ + wl_list_remove (wl_resource_get_link (resource)); +} + +static void +touch_release (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static const struct wl_touch_interface touch_interface = { + touch_release, +}; + +#ifdef HAVE_NATIVE_BACKEND +static void +touch_info_free (MetaWaylandTouchInfo *touch_info) +{ + touch_surface_decrement_touch (touch_info->touch_surface); + g_free (touch_info); +} +#endif /* HAVE_NATIVE_BACKEND */ + +void +meta_wayland_touch_cancel (MetaWaylandTouch *touch) +{ + MetaWaylandInputDevice *input_device = META_WAYLAND_INPUT_DEVICE (touch); + MetaWaylandSeat *seat = meta_wayland_input_device_get_seat (input_device); + GList *surfaces, *s; + + if (!meta_wayland_seat_has_touch (seat)) + return; + + surfaces = s = touch_get_surfaces (touch, FALSE); + + for (s = surfaces; s; s = s->next) + { + MetaWaylandTouchSurface *touch_surface = s->data; + struct wl_resource *resource; + struct wl_list *l; + + l = &touch_surface->resource_list; + wl_resource_for_each(resource, l) + wl_touch_send_cancel (resource); + } + + g_hash_table_remove_all (touch->touches); + g_list_free (surfaces); +} + +#ifdef HAVE_NATIVE_BACKEND +static gboolean +evdev_filter_func (struct libinput_event *event, + gpointer data) +{ + MetaWaylandTouch *touch = data; + + switch (libinput_event_get_type (event)) + { + case LIBINPUT_EVENT_TOUCH_DOWN: + case LIBINPUT_EVENT_TOUCH_UP: + case LIBINPUT_EVENT_TOUCH_MOTION: { + struct libinput_event_touch *touch_event; + int32_t slot; + + touch_event = libinput_event_get_touch_event (event); + slot = libinput_event_touch_get_slot (touch_event); + + /* XXX: Could theoretically overflow, 64 slots should be + * enough for most hw/usecases though. + */ + touch->frame_slots |= (1 << slot); + break; + } + case LIBINPUT_EVENT_TOUCH_CANCEL: + /* Clutter translates this into individual CLUTTER_TOUCH_CANCEL events, + * which are not so useful when sending a global signal as the protocol + * requires. + */ + meta_wayland_touch_cancel (touch); + break; + default: + break; + } + + return CLUTTER_EVENT_PROPAGATE; +} +#endif + +void +meta_wayland_touch_enable (MetaWaylandTouch *touch) +{ +#ifdef HAVE_NATIVE_BACKEND + touch->touch_surfaces = g_hash_table_new_full (NULL, NULL, NULL, + (GDestroyNotify) touch_surface_free); + touch->touches = g_hash_table_new_full (NULL, NULL, NULL, + (GDestroyNotify) touch_info_free); +#endif /* HAVE_NATIVE_BACKEND */ + + wl_list_init (&touch->resource_list); + +#ifdef HAVE_NATIVE_BACKEND + MetaBackend *backend = meta_get_backend (); + if (META_IS_BACKEND_NATIVE (backend)) + { + ClutterBackend *backend = clutter_get_default_backend (); + ClutterSeat *seat = clutter_backend_get_default_seat (backend); + + meta_seat_native_add_filter (META_SEAT_NATIVE (seat), + evdev_filter_func, touch, NULL); + } +#endif +} + +void +meta_wayland_touch_disable (MetaWaylandTouch *touch) +{ +#ifdef HAVE_NATIVE_BACKEND + MetaBackend *backend = meta_get_backend (); + if (META_IS_BACKEND_NATIVE (backend)) + { + ClutterBackend *backend = clutter_get_default_backend (); + ClutterSeat *seat = clutter_backend_get_default_seat (backend); + + meta_seat_native_remove_filter (META_SEAT_NATIVE (seat), + evdev_filter_func, touch); + } +#endif + + meta_wayland_touch_cancel (touch); + + g_clear_pointer (&touch->touch_surfaces, g_hash_table_unref); + g_clear_pointer (&touch->touches, g_hash_table_unref); +} + +void +meta_wayland_touch_create_new_resource (MetaWaylandTouch *touch, + struct wl_client *client, + struct wl_resource *seat_resource, + uint32_t id) +{ + MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); + struct wl_resource *cr; + + if (!meta_wayland_seat_has_touch (seat)) + { + wl_resource_post_error (seat_resource, WL_DISPLAY_ERROR_INVALID_METHOD, + "Cannot retrieve touch interface without touch capability"); + return; + } + + cr = wl_resource_create (client, &wl_touch_interface, wl_resource_get_version (seat_resource), id); + wl_resource_set_implementation (cr, &touch_interface, touch, unbind_resource); + wl_list_insert (&touch->resource_list, wl_resource_get_link (cr)); +} + +gboolean +meta_wayland_touch_can_popup (MetaWaylandTouch *touch, + uint32_t serial) +{ + MetaWaylandTouchInfo *touch_info; + GHashTableIter iter; + + if (!touch->touches) + return FALSE; + + g_hash_table_iter_init (&iter, touch->touches); + + while (g_hash_table_iter_next (&iter, NULL, (gpointer*) &touch_info)) + { + if (touch_info->slot_serial == serial) + return TRUE; + } + return FALSE; +} + +ClutterEventSequence * +meta_wayland_touch_find_grab_sequence (MetaWaylandTouch *touch, + MetaWaylandSurface *surface, + uint32_t serial) +{ + MetaWaylandTouchInfo *touch_info; + ClutterEventSequence *sequence; + GHashTableIter iter; + + if (!touch->touches) + return NULL; + + g_hash_table_iter_init (&iter, touch->touches); + + while (g_hash_table_iter_next (&iter, (gpointer*) &sequence, + (gpointer*) &touch_info)) + { + if (touch_info->slot_serial == serial && + touch_info->touch_surface->surface == surface) + return sequence; + } + + return NULL; +} + +gboolean +meta_wayland_touch_get_press_coords (MetaWaylandTouch *touch, + ClutterEventSequence *sequence, + gfloat *x, + gfloat *y) +{ + MetaWaylandTouchInfo *touch_info; + + if (!touch->touches) + return FALSE; + + touch_info = g_hash_table_lookup (touch->touches, sequence); + + if (!touch_info) + return FALSE; + + if (x) + *x = touch_info->start_x; + if (y) + *y = touch_info->start_y; + + return TRUE; +} + +static void +meta_wayland_touch_init (MetaWaylandTouch *touch) +{ +} + +static void +meta_wayland_touch_class_init (MetaWaylandTouchClass *klass) +{ +} diff --git a/src/wayland/meta-wayland-touch.h b/src/wayland/meta-wayland-touch.h new file mode 100644 index 000000000..f2efcb1ba --- /dev/null +++ b/src/wayland/meta-wayland-touch.h @@ -0,0 +1,79 @@ +/* + * Wayland Support + * + * Copyright (C) 2014 Red Hat + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef META_WAYLAND_TOUCH_H +#define META_WAYLAND_TOUCH_H + +#include <glib.h> +#include <wayland-server.h> + +#include "wayland/meta-wayland-types.h" + +#define META_TYPE_WAYLAND_TOUCH (meta_wayland_touch_get_type ()) +G_DECLARE_FINAL_TYPE (MetaWaylandTouch, meta_wayland_touch, + META, WAYLAND_TOUCH, + MetaWaylandInputDevice) + +typedef struct _MetaWaylandTouchSurface MetaWaylandTouchSurface; +typedef struct _MetaWaylandTouchInfo MetaWaylandTouchInfo; + +struct _MetaWaylandTouch +{ + MetaWaylandInputDevice parent; + + struct wl_list resource_list; + + GHashTable *touch_surfaces; /* HT of MetaWaylandSurface->MetaWaylandTouchSurface */ + GHashTable *touches; /* HT of sequence->MetaWaylandTouchInfo */ + + guint64 frame_slots; +}; + +void meta_wayland_touch_enable (MetaWaylandTouch *touch); + +void meta_wayland_touch_disable (MetaWaylandTouch *touch); + +void meta_wayland_touch_update (MetaWaylandTouch *touch, + const ClutterEvent *event); + +gboolean meta_wayland_touch_handle_event (MetaWaylandTouch *touch, + const ClutterEvent *event); + +void meta_wayland_touch_create_new_resource (MetaWaylandTouch *touch, + struct wl_client *client, + struct wl_resource *seat_resource, + uint32_t id); +void meta_wayland_touch_cancel (MetaWaylandTouch *touch); + + +ClutterEventSequence * meta_wayland_touch_find_grab_sequence (MetaWaylandTouch *touch, + MetaWaylandSurface *surface, + uint32_t serial); + +gboolean meta_wayland_touch_get_press_coords (MetaWaylandTouch *touch, + ClutterEventSequence *sequence, + gfloat *x, + gfloat *y); + +gboolean meta_wayland_touch_can_popup (MetaWaylandTouch *touch, + uint32_t serial); + +#endif /* META_WAYLAND_TOUCH_H */ diff --git a/src/wayland/meta-wayland-types.h b/src/wayland/meta-wayland-types.h new file mode 100644 index 000000000..00712ad1f --- /dev/null +++ b/src/wayland/meta-wayland-types.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2013 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_WAYLAND_TYPES_H +#define META_WAYLAND_TYPES_H + +typedef struct _MetaWaylandCompositor MetaWaylandCompositor; + +typedef struct _MetaWaylandSeat MetaWaylandSeat; +typedef struct _MetaWaylandInputDevice MetaWaylandInputDevice; +typedef struct _MetaWaylandPointer MetaWaylandPointer; +typedef struct _MetaWaylandPointerGrab MetaWaylandPointerGrab; +typedef struct _MetaWaylandPointerGrabInterface MetaWaylandPointerGrabInterface; +typedef struct _MetaWaylandPopupGrab MetaWaylandPopupGrab; +typedef struct _MetaWaylandPopup MetaWaylandPopup; +typedef struct _MetaWaylandPopupSurface MetaWaylandPopupSurface; +typedef struct _MetaWaylandKeyboard MetaWaylandKeyboard; +typedef struct _MetaWaylandKeyboardGrab MetaWaylandKeyboardGrab; +typedef struct _MetaWaylandKeyboardGrabInterface MetaWaylandKeyboardGrabInterface; +typedef struct _MetaWaylandTouch MetaWaylandTouch; +typedef struct _MetaWaylandDragDestFuncs MetaWaylandDragDestFuncs; +typedef struct _MetaWaylandDataOffer MetaWaylandDataOffer; +typedef struct _MetaWaylandDataDevice MetaWaylandDataDevice; +typedef struct _MetaWaylandDataDevicePrimary MetaWaylandDataDevicePrimary; +typedef struct _MetaWaylandDataDevicePrimaryLegacy MetaWaylandDataDevicePrimaryLegacy; + +typedef struct _MetaWaylandTabletManager MetaWaylandTabletManager; +typedef struct _MetaWaylandTabletSeat MetaWaylandTabletSeat; +typedef struct _MetaWaylandTabletTool MetaWaylandTabletTool; +typedef struct _MetaWaylandTablet MetaWaylandTablet; +typedef struct _MetaWaylandTabletPad MetaWaylandTabletPad; +typedef struct _MetaWaylandTabletPadGroup MetaWaylandTabletPadGroup; +typedef struct _MetaWaylandTabletPadStrip MetaWaylandTabletPadStrip; +typedef struct _MetaWaylandTabletPadRing MetaWaylandTabletPadRing; + +typedef struct _MetaWaylandBuffer MetaWaylandBuffer; +typedef struct _MetaWaylandRegion MetaWaylandRegion; + +typedef struct _MetaWaylandSurface MetaWaylandSurface; +typedef struct _MetaWaylandSurfaceState MetaWaylandSurfaceState; + +typedef struct _MetaWaylandOutput MetaWaylandOutput; + +typedef struct _MetaWaylandWindowConfiguration MetaWaylandWindowConfiguration; + +typedef struct _MetaWaylandPointerClient MetaWaylandPointerClient; + +#endif diff --git a/src/wayland/meta-wayland-versions.h b/src/wayland/meta-wayland-versions.h new file mode 100644 index 000000000..2d6ce5ace --- /dev/null +++ b/src/wayland/meta-wayland-versions.h @@ -0,0 +1,59 @@ +/* + * Wayland Support + * + * Copyright (C) 2012,2013 Intel Corporation + * 2013 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_WAYLAND_VERSIONS_H +#define META_WAYLAND_VERSIONS_H + +/* Protocol objects, will never change version */ +/* #define META_WL_DISPLAY_VERSION 1 */ +/* #define META_WL_REGISTRY_VERSION 1 */ +#define META_WL_CALLBACK_VERSION 1 + +/* Not handled by mutter-wayland directly */ +/* #define META_WL_SHM_VERSION 1 */ +/* #define META_WL_SHM_POOL_VERSION 1 */ +/* #define META_WL_DRM_VERSION 1 */ +/* #define META_WL_BUFFER_VERSION 1 */ + +/* Global/master objects (version exported by wl_registry and negotiated through bind) */ +#define META_WL_COMPOSITOR_VERSION 4 +#define META_WL_DATA_DEVICE_MANAGER_VERSION 3 +#define META_XDG_WM_BASE_VERSION 3 +#define META_ZXDG_SHELL_V6_VERSION 1 +#define META_WL_SHELL_VERSION 1 +#define META_WL_SEAT_VERSION 5 +#define META_WL_OUTPUT_VERSION 2 +#define META_XSERVER_VERSION 1 +#define META_GTK_SHELL1_VERSION 3 +#define META_WL_SUBCOMPOSITOR_VERSION 1 +#define META_ZWP_POINTER_GESTURES_V1_VERSION 1 +#define META_ZXDG_EXPORTER_V1_VERSION 1 +#define META_ZXDG_IMPORTER_V1_VERSION 1 +#define META_ZWP_LINUX_DMABUF_V1_VERSION 3 +#define META_ZWP_KEYBOARD_SHORTCUTS_INHIBIT_V1_VERSION 1 +#define META_ZXDG_OUTPUT_V1_VERSION 3 +#define META_ZWP_XWAYLAND_KEYBOARD_GRAB_V1_VERSION 1 +#define META_GTK_TEXT_INPUT_VERSION 1 +#define META_ZWP_TEXT_INPUT_V3_VERSION 1 +#define META_WP_VIEWPORTER_VERSION 1 + +#endif diff --git a/src/wayland/meta-wayland-viewporter.c b/src/wayland/meta-wayland-viewporter.c new file mode 100644 index 000000000..619f3177c --- /dev/null +++ b/src/wayland/meta-wayland-viewporter.c @@ -0,0 +1,237 @@ +/* + * Wayland Support + * + * Copyright (C) 2018-2019 Robert Mader <robert.mader@posteo.de> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#include "config.h" + +#include "meta-wayland-viewporter.h" + +#include <glib.h> + +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-wayland-subsurface.h" +#include "wayland/meta-wayland-surface.h" +#include "wayland/meta-wayland-versions.h" + +#include "viewporter-server-protocol.h" + +static void +wp_viewport_destructor (struct wl_resource *resource) +{ + MetaWaylandSurface *surface; + MetaWaylandSurfaceState *pending; + + surface = wl_resource_get_user_data (resource); + if (!surface) + return; + + g_clear_signal_handler (&surface->viewport.destroy_handler_id, surface); + + pending = meta_wayland_surface_get_pending_state (surface); + pending->viewport_src_rect.size.width = -1; + pending->viewport_dst_width = -1; + pending->has_new_viewport_src_rect = TRUE; + pending->has_new_viewport_dst_size = TRUE; + + surface->viewport.resource = NULL; +} + +static void +on_surface_destroyed (MetaWaylandSurface *surface) +{ + wl_resource_set_user_data (surface->viewport.resource, NULL); +} + +static void +wp_viewport_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +wp_viewport_set_source (struct wl_client *client, + struct wl_resource *resource, + wl_fixed_t src_x, + wl_fixed_t src_y, + wl_fixed_t src_width, + wl_fixed_t src_height) +{ + MetaWaylandSurface *surface; + float new_x; + float new_y; + float new_width; + float new_height; + + surface = wl_resource_get_user_data (resource); + if (!surface) + { + wl_resource_post_error (resource, + WP_VIEWPORT_ERROR_NO_SURFACE, + "wl_surface for this viewport no longer exists"); + return; + } + + new_x = wl_fixed_to_double (src_x); + new_y = wl_fixed_to_double (src_y); + new_width = wl_fixed_to_double (src_width); + new_height = wl_fixed_to_double (src_height); + + if ((new_x >= 0 && new_y >= 0 && + new_width > 0 && new_height > 0) || + (new_x == -1 && new_y == -1 && + new_width == -1 && new_height == -1)) + { + MetaWaylandSurfaceState *pending; + + pending = meta_wayland_surface_get_pending_state (surface); + pending->viewport_src_rect.origin.x = new_x; + pending->viewport_src_rect.origin.y = new_y; + pending->viewport_src_rect.size.width = new_width; + pending->viewport_src_rect.size.height = new_height; + pending->has_new_viewport_src_rect = TRUE; + } + else + { + wl_resource_post_error (resource, + WP_VIEWPORT_ERROR_BAD_VALUE, + "x and y values must be zero or positive and " + "width and height valuest must be positive or " + "all values must be -1 to unset the viewport"); + } +} + +static void +wp_viewport_set_destination (struct wl_client *client, + struct wl_resource *resource, + int dst_width, + int dst_height) +{ + MetaWaylandSurface *surface; + + surface = wl_resource_get_user_data (resource); + if (!surface) + { + wl_resource_post_error (resource, + WP_VIEWPORT_ERROR_NO_SURFACE, + "wl_surface for this viewport no longer exists"); + return; + } + + if ((dst_width > 0 && dst_height > 0) || + (dst_width == -1 && dst_height == -1)) + { + MetaWaylandSurfaceState *pending; + + pending = meta_wayland_surface_get_pending_state (surface); + pending->viewport_dst_width = dst_width; + pending->viewport_dst_height = dst_height; + pending->has_new_viewport_dst_size = TRUE; + } + else + { + wl_resource_post_error (resource, + WP_VIEWPORT_ERROR_BAD_VALUE, + "all values must be either positive or -1"); + } +} + +static const struct wp_viewport_interface meta_wayland_viewport_interface = { + wp_viewport_destroy, + wp_viewport_set_source, + wp_viewport_set_destination, +}; + +static void +wp_viewporter_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +wp_viewporter_get_viewport (struct wl_client *client, + struct wl_resource *resource, + uint32_t viewport_id, + struct wl_resource *surface_resource) +{ + MetaWaylandSurface *surface; + struct wl_resource *viewport_resource; + + surface = wl_resource_get_user_data (surface_resource); + if (surface->viewport.resource) + { + wl_resource_post_error (resource, + WP_VIEWPORTER_ERROR_VIEWPORT_EXISTS, + "viewport already exists on surface"); + return; + } + + viewport_resource = wl_resource_create (client, + &wp_viewport_interface, + wl_resource_get_version (resource), + viewport_id); + wl_resource_set_implementation (viewport_resource, + &meta_wayland_viewport_interface, + surface, + wp_viewport_destructor); + + surface->viewport.resource = viewport_resource; + surface->viewport.destroy_handler_id = + g_signal_connect (surface, + "destroy", + G_CALLBACK (on_surface_destroyed), + NULL); +} + +static const struct wp_viewporter_interface meta_wayland_viewporter_interface = { + wp_viewporter_destroy, + wp_viewporter_get_viewport, +}; + +static void +wp_viewporter_bind (struct wl_client *client, + void *data, + uint32_t version, + uint32_t id) +{ + struct wl_resource *resource; + + resource = wl_resource_create (client, + &wp_viewporter_interface, + version, + id); + wl_resource_set_implementation (resource, + &meta_wayland_viewporter_interface, + data, + NULL); +} + +void +meta_wayland_init_viewporter (MetaWaylandCompositor *compositor) +{ + if (wl_global_create (compositor->wayland_display, + &wp_viewporter_interface, + META_WP_VIEWPORTER_VERSION, + compositor, + wp_viewporter_bind) == NULL) + g_error ("Failed to register a global wl-viewporter object"); +} diff --git a/src/wayland/meta-wayland-viewporter.h b/src/wayland/meta-wayland-viewporter.h new file mode 100644 index 000000000..8cc099b11 --- /dev/null +++ b/src/wayland/meta-wayland-viewporter.h @@ -0,0 +1,30 @@ +/* + * Wayland Support + * + * Copyright (C) 2018-2019 Robert Mader <robert.mader@posteo.de> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#ifndef META_WAYLAND_VIEWPORTER_H +#define META_WAYLAND_VIEWPORTER_H + +#include "wayland/meta-wayland-types.h" + +void meta_wayland_init_viewporter (MetaWaylandCompositor *compositor); + +#endif /* META_WAYLAND_VIEWPORTER_H */ diff --git a/src/wayland/meta-wayland-window-configuration.c b/src/wayland/meta-wayland-window-configuration.c new file mode 100644 index 000000000..a0ee8f805 --- /dev/null +++ b/src/wayland/meta-wayland-window-configuration.c @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2019 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#include "config.h" + +#include "wayland/meta-wayland-window-configuration.h" + +static uint32_t global_serial_counter = 0; + +MetaWaylandWindowConfiguration * +meta_wayland_window_configuration_new (int x, + int y, + int width, + int height, + int scale, + MetaMoveResizeFlags flags, + MetaGravity gravity) +{ + MetaWaylandWindowConfiguration *configuration; + + configuration = g_new0 (MetaWaylandWindowConfiguration, 1); + *configuration = (MetaWaylandWindowConfiguration) { + .serial = ++global_serial_counter, + + .has_position = TRUE, + .x = x, + .y = y, + + .has_size = TRUE, + .width = width, + .height = height, + + .scale = scale, + .gravity = gravity, + .flags = flags, + }; + + return configuration; +} + +MetaWaylandWindowConfiguration * +meta_wayland_window_configuration_new_relative (int rel_x, + int rel_y, + int width, + int height, + int scale) +{ + MetaWaylandWindowConfiguration *configuration; + + configuration = g_new0 (MetaWaylandWindowConfiguration, 1); + *configuration = (MetaWaylandWindowConfiguration) { + .serial = ++global_serial_counter, + + .has_relative_position = TRUE, + .rel_x = rel_x, + .rel_y = rel_y, + + .has_size = TRUE, + .width = width, + .height = height, + + .scale = scale, + }; + + return configuration; +} + +MetaWaylandWindowConfiguration * +meta_wayland_window_configuration_new_empty (void) +{ + MetaWaylandWindowConfiguration *configuration; + + configuration = g_new0 (MetaWaylandWindowConfiguration, 1); + *configuration = (MetaWaylandWindowConfiguration) { + .serial = ++global_serial_counter, + .scale = 1, + }; + + return configuration; +} + +void +meta_wayland_window_configuration_free (MetaWaylandWindowConfiguration *configuration) +{ + g_free (configuration); +} diff --git a/src/wayland/meta-wayland-window-configuration.h b/src/wayland/meta-wayland-window-configuration.h new file mode 100644 index 000000000..b524f431f --- /dev/null +++ b/src/wayland/meta-wayland-window-configuration.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2019 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#ifndef META_WAYLAND_WINDOW_CONFIGURATION_H +#define META_WAYLAND_WINDOW_CONFIGURATION_H + +#include <glib.h> +#include <stdint.h> + +#include "core/window-private.h" +#include "wayland/meta-wayland-types.h" + +struct _MetaWaylandWindowConfiguration +{ + uint32_t serial; + + gboolean has_position; + int x; + int y; + + gboolean has_relative_position; + int rel_x; + int rel_y; + + gboolean has_size; + int width; + int height; + + int scale; + MetaGravity gravity; + MetaMoveResizeFlags flags; +}; + +MetaWaylandWindowConfiguration * meta_wayland_window_configuration_new (int x, + int y, + int width, + int height, + int scale, + MetaMoveResizeFlags flags, + MetaGravity gravity); + +MetaWaylandWindowConfiguration * meta_wayland_window_configuration_new_relative (int rel_x, + int rel_y, + int width, + int height, + int scale); + +MetaWaylandWindowConfiguration * meta_wayland_window_configuration_new_empty (void); + +void meta_wayland_window_configuration_free (MetaWaylandWindowConfiguration *configuration); + +#endif /* META_WAYLAND_WINDOW_CONFIGURATION_H */ diff --git a/src/wayland/meta-wayland-wl-shell.c b/src/wayland/meta-wayland-wl-shell.c new file mode 100644 index 000000000..d6d76195a --- /dev/null +++ b/src/wayland/meta-wayland-wl-shell.c @@ -0,0 +1,780 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2012-2013 Intel Corporation + * Copyright (C) 2013-2015 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#include "config.h" + +#include "wayland/meta-wayland-wl-shell.h" + +#include "core/window-private.h" +#include "wayland/meta-wayland-popup.h" +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-wayland-seat.h" +#include "wayland/meta-wayland-shell-surface.h" +#include "wayland/meta-wayland-surface.h" +#include "wayland/meta-wayland-versions.h" +#include "wayland/meta-wayland-window-configuration.h" +#include "wayland/meta-wayland.h" +#include "wayland/meta-window-wayland.h" + +typedef enum +{ + META_WL_SHELL_SURFACE_STATE_NONE, + META_WL_SHELL_SURFACE_STATE_TOPLEVEL, + META_WL_SHELL_SURFACE_STATE_POPUP, + META_WL_SHELL_SURFACE_STATE_TRANSIENT, + META_WL_SHELL_SURFACE_STATE_FULLSCREEN, + META_WL_SHELL_SURFACE_STATE_MAXIMIZED, +} MetaWlShellSurfaceState; + +struct _MetaWaylandWlShellSurface +{ + MetaWaylandShellSurface parent; + + struct wl_resource *resource; + + MetaWlShellSurfaceState state; + + char *title; + char *wm_class; + + MetaWaylandSurface *parent_surface; + GList *children; + + MetaWaylandSeat *popup_seat; + MetaWaylandPopup *popup; + gboolean pending_popup; + + int x; + int y; + + uint32_t emulated_ack_configure_serial; +}; + +static void +popup_surface_iface_init (MetaWaylandPopupSurfaceInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (MetaWaylandWlShellSurface, + meta_wayland_wl_shell_surface, + META_TYPE_WAYLAND_SHELL_SURFACE, + G_IMPLEMENT_INTERFACE (META_TYPE_WAYLAND_POPUP_SURFACE, + popup_surface_iface_init)); + +static MetaWaylandSurface * +surface_from_wl_shell_surface_resource (struct wl_resource *resource) +{ + MetaWaylandWlShellSurface *wl_shell_surface = + wl_resource_get_user_data (resource); + MetaWaylandSurfaceRole *surface_role = + META_WAYLAND_SURFACE_ROLE (wl_shell_surface); + + return meta_wayland_surface_role_get_surface (surface_role); +} + +static void +sync_wl_shell_parent_relationship (MetaWaylandSurface *surface, + MetaWaylandSurface *parent); + +static void +wl_shell_surface_destructor (struct wl_resource *resource) +{ + MetaWaylandWlShellSurface *wl_shell_surface = + META_WAYLAND_WL_SHELL_SURFACE (wl_resource_get_user_data (resource)); + MetaWaylandSurface *surface = + surface_from_wl_shell_surface_resource (resource); + GList *l; + + if (wl_shell_surface->popup) + meta_wayland_popup_dismiss (wl_shell_surface->popup); + + for (l = wl_shell_surface->children; l; l = l->next) + { + MetaWaylandSurface *child_surface = l->data; + MetaWaylandWlShellSurface *child_wl_shell_surface = + META_WAYLAND_WL_SHELL_SURFACE (child_surface->role); + + child_wl_shell_surface->parent_surface = NULL; + + if (child_wl_shell_surface->parent_surface == surface) + { + meta_wayland_popup_dismiss (child_wl_shell_surface->popup); + child_wl_shell_surface->parent_surface = NULL; + } + } + + if (wl_shell_surface->parent_surface) + { + MetaWaylandSurface *parent_surface = wl_shell_surface->parent_surface; + MetaWaylandWlShellSurface *parent_wl_shell_surface = + META_WAYLAND_WL_SHELL_SURFACE (parent_surface->role); + + parent_wl_shell_surface->children = + g_list_remove (parent_wl_shell_surface->children, surface); + } + + g_free (wl_shell_surface->title); + g_free (wl_shell_surface->wm_class); + + if (wl_shell_surface->popup) + { + wl_shell_surface->parent_surface = NULL; + + meta_wayland_popup_dismiss (wl_shell_surface->popup); + } + + wl_shell_surface->resource = NULL; +} + +static void +wl_shell_surface_pong (struct wl_client *client, + struct wl_resource *resource, + uint32_t serial) +{ + MetaDisplay *display = meta_get_display (); + + meta_display_pong_for_serial (display, serial); +} + +static void +wl_shell_surface_move (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *seat_resource, + uint32_t serial) +{ + MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); + MetaWaylandSurface *surface = + surface_from_wl_shell_surface_resource (resource); + gfloat x, y; + + if (!meta_wayland_seat_get_grab_info (seat, surface, serial, TRUE, &x, &y)) + return; + + meta_wayland_surface_begin_grab_op (surface, seat, META_GRAB_OP_MOVING, x, y); +} + +static MetaGrabOp +grab_op_for_wl_shell_surface_resize_edge (int edge) +{ + MetaGrabOp op = META_GRAB_OP_WINDOW_BASE; + + if (edge & WL_SHELL_SURFACE_RESIZE_TOP) + op |= META_GRAB_OP_WINDOW_DIR_NORTH; + if (edge & WL_SHELL_SURFACE_RESIZE_BOTTOM) + op |= META_GRAB_OP_WINDOW_DIR_SOUTH; + if (edge & WL_SHELL_SURFACE_RESIZE_LEFT) + op |= META_GRAB_OP_WINDOW_DIR_WEST; + if (edge & WL_SHELL_SURFACE_RESIZE_RIGHT) + op |= META_GRAB_OP_WINDOW_DIR_EAST; + + if (op == META_GRAB_OP_WINDOW_BASE) + { + g_warning ("invalid edge: %d", edge); + return META_GRAB_OP_NONE; + } + + return op; +} + +static void +wl_shell_surface_resize (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *seat_resource, + uint32_t serial, + uint32_t edges) +{ + MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); + MetaWaylandSurface *surface = + surface_from_wl_shell_surface_resource (resource); + gfloat x, y; + MetaGrabOp grab_op; + + if (!meta_wayland_seat_get_grab_info (seat, surface, serial, TRUE, &x, &y)) + return; + + grab_op = grab_op_for_wl_shell_surface_resize_edge (edges); + meta_wayland_surface_begin_grab_op (surface, seat, grab_op, x, y); +} + +static void +wl_shell_surface_set_state (MetaWaylandSurface *surface, + MetaWlShellSurfaceState state) +{ + MetaWaylandWlShellSurface *wl_shell_surface = + META_WAYLAND_WL_SHELL_SURFACE (surface->role); + MetaWlShellSurfaceState old_state = wl_shell_surface->state; + MetaWindow *window; + + wl_shell_surface->state = state; + + window = meta_wayland_surface_get_window (surface); + if (window && old_state != state) + { + if (old_state == META_WL_SHELL_SURFACE_STATE_POPUP && + wl_shell_surface->popup) + { + meta_wayland_popup_dismiss (wl_shell_surface->popup); + wl_shell_surface->popup = NULL; + } + + if (state == META_WL_SHELL_SURFACE_STATE_FULLSCREEN) + meta_window_make_fullscreen (window); + else + meta_window_unmake_fullscreen (window); + + if (state == META_WL_SHELL_SURFACE_STATE_MAXIMIZED) + meta_window_maximize (window, META_MAXIMIZE_BOTH); + else + meta_window_unmaximize (window, META_MAXIMIZE_BOTH); + } +} + +static void +wl_shell_surface_set_toplevel (struct wl_client *client, + struct wl_resource *resource) +{ + MetaWaylandSurface *surface = + surface_from_wl_shell_surface_resource (resource); + + wl_shell_surface_set_state (surface, + META_WL_SHELL_SURFACE_STATE_TOPLEVEL); +} + +static void +set_wl_shell_surface_parent (MetaWaylandSurface *surface, + MetaWaylandSurface *parent) +{ + MetaWaylandWlShellSurface *wl_shell_surface = + META_WAYLAND_WL_SHELL_SURFACE (surface->role); + MetaWaylandWlShellSurface *parent_wl_shell_surface = + META_WAYLAND_WL_SHELL_SURFACE (parent->role); + + if (wl_shell_surface->parent_surface) + { + MetaWaylandWlShellSurface *old_parent = + META_WAYLAND_WL_SHELL_SURFACE (wl_shell_surface->parent_surface->role); + + old_parent->children = g_list_remove (old_parent->children, surface); + } + + parent_wl_shell_surface->children = + g_list_append (parent_wl_shell_surface->children, surface); + wl_shell_surface->parent_surface = parent; +} + +static void +wl_shell_surface_set_transient (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *parent_resource, + int32_t x, + int32_t y, + uint32_t flags) +{ + MetaWaylandWlShellSurface *wl_shell_surface = + META_WAYLAND_WL_SHELL_SURFACE (wl_resource_get_user_data (resource)); + MetaWaylandSurface *surface = + surface_from_wl_shell_surface_resource (resource); + MetaWaylandSurface *parent_surf = wl_resource_get_user_data (parent_resource); + + wl_shell_surface_set_state (surface, + META_WL_SHELL_SURFACE_STATE_TRANSIENT); + + set_wl_shell_surface_parent (surface, parent_surf); + wl_shell_surface->x = x; + wl_shell_surface->y = y; + + if (meta_wayland_surface_get_window (surface) && + meta_wayland_surface_get_window (parent_surf)) + sync_wl_shell_parent_relationship (surface, parent_surf); +} + +static void +wl_shell_surface_set_fullscreen (struct wl_client *client, + struct wl_resource *resource, + uint32_t method, + uint32_t framerate, + struct wl_resource *output) +{ + MetaWaylandSurface *surface = + surface_from_wl_shell_surface_resource (resource); + + wl_shell_surface_set_state (surface, + META_WL_SHELL_SURFACE_STATE_FULLSCREEN); +} + +static void +meta_wayland_wl_shell_surface_create_popup (MetaWaylandWlShellSurface *wl_shell_surface) +{ + MetaWaylandPopupSurface *popup_surface = + META_WAYLAND_POPUP_SURFACE (wl_shell_surface); + MetaWaylandSeat *seat = wl_shell_surface->popup_seat; + MetaWaylandPopup *popup; + + popup = meta_wayland_pointer_start_popup_grab (seat->pointer, popup_surface); + if (!popup) + { + wl_shell_surface_send_popup_done (wl_shell_surface->resource); + return; + } + + wl_shell_surface->popup = popup; +} + +static void +wl_shell_surface_set_popup (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *seat_resource, + uint32_t serial, + struct wl_resource *parent_resource, + int32_t x, + int32_t y, + uint32_t flags) +{ + MetaWaylandWlShellSurface *wl_shell_surface = + META_WAYLAND_WL_SHELL_SURFACE (wl_resource_get_user_data (resource)); + MetaWaylandSurface *surface = + surface_from_wl_shell_surface_resource (resource); + MetaWaylandSurface *parent_surf = wl_resource_get_user_data (parent_resource); + MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); + + if (wl_shell_surface->popup) + { + wl_shell_surface->parent_surface = NULL; + + meta_wayland_popup_dismiss (wl_shell_surface->popup); + } + + wl_shell_surface_set_state (surface, + META_WL_SHELL_SURFACE_STATE_POPUP); + + if (!meta_wayland_seat_can_popup (seat, serial)) + { + wl_shell_surface_send_popup_done (resource); + return; + } + + set_wl_shell_surface_parent (surface, parent_surf); + wl_shell_surface->popup_seat = seat; + wl_shell_surface->x = x; + wl_shell_surface->y = y; + wl_shell_surface->pending_popup = TRUE; + + if (meta_wayland_surface_get_window (surface) && + meta_wayland_surface_get_window (parent_surf)) + sync_wl_shell_parent_relationship (surface, parent_surf); +} + +static void +wl_shell_surface_set_maximized (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *output) +{ + MetaWaylandSurface *surface = + surface_from_wl_shell_surface_resource (resource); + + wl_shell_surface_set_state (surface, + META_WL_SHELL_SURFACE_STATE_MAXIMIZED); +} + +static void +wl_shell_surface_set_title (struct wl_client *client, + struct wl_resource *resource, + const char *title) +{ + MetaWaylandWlShellSurface *wl_shell_surface = + META_WAYLAND_WL_SHELL_SURFACE (wl_resource_get_user_data (resource)); + MetaWaylandSurface *surface = + surface_from_wl_shell_surface_resource (resource); + MetaWindow *window; + + g_clear_pointer (&wl_shell_surface->title, g_free); + + if (!g_utf8_validate (title, -1, NULL)) + title = ""; + + wl_shell_surface->title = g_strdup (title); + + window = meta_wayland_surface_get_window (surface); + if (window) + meta_window_set_title (window, title); +} + +static void +wl_shell_surface_set_class (struct wl_client *client, + struct wl_resource *resource, + const char *class_) +{ + MetaWaylandWlShellSurface *wl_shell_surface = + META_WAYLAND_WL_SHELL_SURFACE (wl_resource_get_user_data (resource)); + MetaWaylandSurface *surface = + surface_from_wl_shell_surface_resource (resource); + MetaWindow *window; + + g_clear_pointer (&wl_shell_surface->wm_class, g_free); + + if (!g_utf8_validate (class_, -1, NULL)) + class_ = ""; + + wl_shell_surface->wm_class = g_strdup (class_); + + window = meta_wayland_surface_get_window (surface); + if (window) + meta_window_set_wm_class (window, class_, class_); +} + +static const struct wl_shell_surface_interface meta_wayland_wl_shell_surface_interface = { + wl_shell_surface_pong, + wl_shell_surface_move, + wl_shell_surface_resize, + wl_shell_surface_set_toplevel, + wl_shell_surface_set_transient, + wl_shell_surface_set_fullscreen, + wl_shell_surface_set_popup, + wl_shell_surface_set_maximized, + wl_shell_surface_set_title, + wl_shell_surface_set_class, +}; + +static void +sync_wl_shell_parent_relationship (MetaWaylandSurface *surface, + MetaWaylandSurface *parent) +{ + MetaWaylandWlShellSurface *wl_shell_surface = + META_WAYLAND_WL_SHELL_SURFACE (surface->role); + MetaWindow *window; + MetaWindow *parent_window; + + window = meta_wayland_surface_get_window (surface); + parent_window = meta_wayland_surface_get_window (parent); + meta_window_set_transient_for (window, parent_window); + + if (wl_shell_surface->state == META_WL_SHELL_SURFACE_STATE_POPUP || + wl_shell_surface->state == META_WL_SHELL_SURFACE_STATE_TRANSIENT) + meta_window_wayland_place_relative_to (window, + parent_window, + wl_shell_surface->x, + wl_shell_surface->y); + + if (wl_shell_surface->state == META_WL_SHELL_SURFACE_STATE_POPUP && + wl_shell_surface->pending_popup) + { + meta_wayland_wl_shell_surface_create_popup (wl_shell_surface); + wl_shell_surface->pending_popup = FALSE; + } +} + +static void +create_wl_shell_surface_window (MetaWaylandSurface *surface) +{ + MetaWaylandWlShellSurface *wl_shell_surface = + META_WAYLAND_WL_SHELL_SURFACE (surface->role); + MetaWaylandShellSurface *shell_surface = + META_WAYLAND_SHELL_SURFACE (wl_shell_surface); + MetaWaylandSurface *parent; + MetaWindow *window; + GList *l; + + window = meta_window_wayland_new (meta_get_display (), surface); + meta_wayland_shell_surface_set_window (shell_surface, window); + + if (wl_shell_surface->title) + meta_window_set_title (window, wl_shell_surface->title); + if (wl_shell_surface->wm_class) + meta_window_set_wm_class (window, + wl_shell_surface->wm_class, + wl_shell_surface->wm_class); + + parent = wl_shell_surface->parent_surface; + if (parent && meta_wayland_surface_get_window (parent)) + sync_wl_shell_parent_relationship (surface, parent); + + for (l = wl_shell_surface->children; l; l = l->next) + { + MetaWaylandSurface *child = l->data; + + if (meta_wayland_surface_get_window (child)) + sync_wl_shell_parent_relationship (child, surface); + } +} + +static void +wl_shell_get_shell_surface (struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *surface_resource) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + MetaWaylandWlShellSurface *wl_shell_surface; + + if (META_IS_WAYLAND_WL_SHELL_SURFACE (surface->role) && + META_WAYLAND_WL_SHELL_SURFACE (surface->role)->resource) + { + wl_resource_post_error (surface_resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "wl_shell::get_shell_surface already requested"); + return; + } + + if (!meta_wayland_surface_assign_role (surface, + META_TYPE_WAYLAND_WL_SHELL_SURFACE, + NULL)) + { + wl_resource_post_error (resource, WL_SHELL_ERROR_ROLE, + "wl_surface@%d already has a different role", + wl_resource_get_id (surface->resource)); + return; + } + + wl_shell_surface = META_WAYLAND_WL_SHELL_SURFACE (surface->role); + wl_shell_surface->resource = + wl_resource_create (client, + &wl_shell_surface_interface, + wl_resource_get_version (resource), + id); + wl_resource_set_implementation (wl_shell_surface->resource, + &meta_wayland_wl_shell_surface_interface, + wl_shell_surface, + wl_shell_surface_destructor); + + create_wl_shell_surface_window (surface); +} + +static const struct wl_shell_interface meta_wayland_wl_shell_interface = { + wl_shell_get_shell_surface, +}; + +static void +bind_wl_shell (struct wl_client *client, + void *data, + uint32_t version, + uint32_t id) +{ + struct wl_resource *resource; + + resource = wl_resource_create (client, &wl_shell_interface, version, id); + wl_resource_set_implementation (resource, &meta_wayland_wl_shell_interface, data, NULL); +} + +static void +wl_shell_surface_role_apply_state (MetaWaylandSurfaceRole *surface_role, + MetaWaylandSurfaceState *pending) +{ + MetaWaylandWlShellSurface *wl_shell_surface = + META_WAYLAND_WL_SHELL_SURFACE (surface_role); + MetaWaylandShellSurface *shell_surface = + META_WAYLAND_SHELL_SURFACE (wl_shell_surface); + MetaWaylandSurfaceRoleClass *surface_role_class; + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWindow *window = meta_wayland_surface_get_window (surface); + cairo_region_t *input_region; + MetaRectangle geom = { 0 }; + + surface_role_class = + META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_wl_shell_surface_parent_class); + surface_role_class->apply_state (surface_role, pending); + + /* For wl_shell, it's equivalent to an unmap. Semantics + * are poorly defined, so we can choose some that are + * convenient for us. */ + if (surface->buffer_ref.buffer && !window) + { + create_wl_shell_surface_window (surface); + } + else if (!surface->buffer_ref.buffer && window) + { + if (wl_shell_surface->popup) + meta_wayland_popup_dismiss (wl_shell_surface->popup); + else + meta_wayland_shell_surface_destroy_window (shell_surface); + return; + } + + if (!window) + return; + + if (!pending->newly_attached) + return; + + input_region = meta_wayland_surface_calculate_input_region (surface); + if (!cairo_region_is_empty (input_region)) + { + cairo_region_get_extents (input_region, &geom); + cairo_region_destroy (input_region); + } + else + { + meta_wayland_shell_surface_calculate_geometry (shell_surface, &geom); + } + + pending->has_acked_configure_serial = TRUE; + pending->acked_configure_serial = + wl_shell_surface->emulated_ack_configure_serial; + + meta_window_wayland_finish_move_resize (window, geom, pending); +} + +static MetaWaylandSurface * +wl_shell_surface_role_get_toplevel (MetaWaylandSurfaceRole *surface_role) +{ + MetaWaylandWlShellSurface *wl_shell_surface = + META_WAYLAND_WL_SHELL_SURFACE (surface_role); + + if (wl_shell_surface->state == META_WL_SHELL_SURFACE_STATE_POPUP && + wl_shell_surface->parent_surface) + return meta_wayland_surface_get_toplevel (wl_shell_surface->parent_surface); + else + return meta_wayland_surface_role_get_surface (surface_role); +} + +static void +wl_shell_surface_role_configure (MetaWaylandShellSurface *shell_surface, + MetaWaylandWindowConfiguration *configuration) +{ + MetaWaylandWlShellSurface *wl_shell_surface = + META_WAYLAND_WL_SHELL_SURFACE (shell_surface); + + if (!wl_shell_surface->resource) + return; + + wl_shell_surface_send_configure (wl_shell_surface->resource, + 0, + configuration->width / configuration->scale, + configuration->height / configuration->scale); + + wl_shell_surface->emulated_ack_configure_serial = configuration->serial; +} + +static void +wl_shell_surface_role_managed (MetaWaylandShellSurface *shell_surface, + MetaWindow *window) +{ + MetaWaylandWlShellSurface *wl_shell_surface = + META_WAYLAND_WL_SHELL_SURFACE (shell_surface); + + if (wl_shell_surface->state == META_WL_SHELL_SURFACE_STATE_POPUP) + meta_window_set_type (window, META_WINDOW_DROPDOWN_MENU); +} + +static void +wl_shell_surface_role_ping (MetaWaylandShellSurface *shell_surface, + guint32 serial) +{ + MetaWaylandWlShellSurface *wl_shell_surface = + META_WAYLAND_WL_SHELL_SURFACE (shell_surface); + + wl_shell_surface_send_ping (wl_shell_surface->resource, serial); +} + +static void +wl_shell_surface_role_close (MetaWaylandShellSurface *shell_surface) +{ + /* Not supported by wl_shell_surface. */ +} + +static void +meta_wayland_wl_shell_surface_popup_done (MetaWaylandPopupSurface *popup_surface) +{ + MetaWaylandWlShellSurface *wl_shell_surface = + META_WAYLAND_WL_SHELL_SURFACE (popup_surface); + + wl_shell_surface_send_popup_done (wl_shell_surface->resource); +} + +static void +meta_wayland_wl_shell_surface_popup_dismiss (MetaWaylandPopupSurface *popup_surface) +{ + MetaWaylandWlShellSurface *wl_shell_surface = + META_WAYLAND_WL_SHELL_SURFACE (popup_surface); + MetaWaylandShellSurface *shell_surface = + META_WAYLAND_SHELL_SURFACE (wl_shell_surface); + + wl_shell_surface->popup = NULL; + + meta_wayland_shell_surface_destroy_window (shell_surface); +} + +static MetaWaylandSurface * +meta_wayland_wl_shell_surface_popup_get_surface (MetaWaylandPopupSurface *popup_surface) +{ + MetaWaylandSurfaceRole *surface_role = + META_WAYLAND_SURFACE_ROLE (popup_surface); + + return meta_wayland_surface_role_get_surface (surface_role); +} + +static void +popup_surface_iface_init (MetaWaylandPopupSurfaceInterface *iface) +{ + iface->done = meta_wayland_wl_shell_surface_popup_done; + iface->dismiss = meta_wayland_wl_shell_surface_popup_dismiss; + iface->get_surface = meta_wayland_wl_shell_surface_popup_get_surface; +} + +static void +wl_shell_surface_role_finalize (GObject *object) +{ + MetaWaylandWlShellSurface *wl_shell_surface = + META_WAYLAND_WL_SHELL_SURFACE (object); + GObjectClass *object_class; + + g_clear_pointer (&wl_shell_surface->resource, wl_resource_destroy); + + object_class = + G_OBJECT_CLASS (meta_wayland_wl_shell_surface_parent_class); + object_class->finalize (object); +} + +static void +meta_wayland_wl_shell_surface_init (MetaWaylandWlShellSurface *wl_shell_surface) +{ +} + +static void +meta_wayland_wl_shell_surface_class_init (MetaWaylandWlShellSurfaceClass *klass) +{ + GObjectClass *object_class; + MetaWaylandSurfaceRoleClass *surface_role_class; + MetaWaylandShellSurfaceClass *shell_surface_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->finalize = wl_shell_surface_role_finalize; + + surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass); + surface_role_class->apply_state = wl_shell_surface_role_apply_state; + surface_role_class->get_toplevel = wl_shell_surface_role_get_toplevel; + + shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass); + shell_surface_class->configure = wl_shell_surface_role_configure; + shell_surface_class->managed = wl_shell_surface_role_managed; + shell_surface_class->ping = wl_shell_surface_role_ping; + shell_surface_class->close = wl_shell_surface_role_close; +} + +void +meta_wayland_wl_shell_init (MetaWaylandCompositor *compositor) +{ + if (wl_global_create (compositor->wayland_display, + &wl_shell_interface, + META_WL_SHELL_VERSION, + compositor, bind_wl_shell) == NULL) + g_error ("Failed to register a global wl-shell object"); +} diff --git a/src/wayland/meta-wayland-wl-shell.h b/src/wayland/meta-wayland-wl-shell.h new file mode 100644 index 000000000..4a62d8a72 --- /dev/null +++ b/src/wayland/meta-wayland-wl-shell.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2013-2015 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_WAYLAND_WL_SHELL_H +#define META_WAYLAND_WL_SHELL_H + +#include "wayland/meta-wayland-shell-surface.h" + +#define META_TYPE_WAYLAND_WL_SHELL_SURFACE (meta_wayland_wl_shell_surface_get_type ()) +G_DECLARE_FINAL_TYPE (MetaWaylandWlShellSurface, + meta_wayland_wl_shell_surface, + META, WAYLAND_WL_SHELL_SURFACE, + MetaWaylandShellSurface); + +void meta_wayland_wl_shell_init (MetaWaylandCompositor *compositor); + +#endif /* META_WAYLAND_WL_SHELL_H */ diff --git a/src/wayland/meta-wayland-xdg-foreign.c b/src/wayland/meta-wayland-xdg-foreign.c new file mode 100644 index 000000000..eb480b996 --- /dev/null +++ b/src/wayland/meta-wayland-xdg-foreign.c @@ -0,0 +1,462 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2015 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +#include "config.h" + +#include "wayland/meta-wayland-xdg-foreign.h" + +#include <wayland-server.h> + +#include "core/util-private.h" +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-wayland-versions.h" +#include "wayland/meta-wayland-xdg-shell.h" +#include "wayland/meta-wayland-legacy-xdg-shell.h" + +#include "xdg-foreign-unstable-v1-server-protocol.h" + +#define META_XDG_FOREIGN_HANDLE_LENGTH 32 + +typedef struct _MetaWaylandXdgExported MetaWaylandXdgExported; +typedef struct _MetaWaylandXdgImported MetaWaylandXdgImported; + +typedef struct _MetaWaylandXdgForeign +{ + MetaWaylandCompositor *compositor; + GRand *rand; + + GHashTable *exported_surfaces; +} MetaWaylandXdgForeign; + +struct _MetaWaylandXdgExported +{ + MetaWaylandXdgForeign *foreign; + struct wl_resource *resource; + + MetaWaylandSurface *surface; + gulong surface_unmapped_handler_id; + char *handle; + + GList *imported; +}; + +struct _MetaWaylandXdgImported +{ + MetaWaylandXdgForeign *foreign; + struct wl_resource *resource; + + MetaWaylandSurface *parent_of; + gulong parent_of_unmapped_handler_id; + + MetaWaylandXdgExported *exported; +}; + +static void +meta_wayland_xdg_imported_destroy (MetaWaylandXdgImported *imported); + +static void +xdg_exporter_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +xdg_exported_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static const struct zxdg_exported_v1_interface meta_xdg_exported_interface = { + xdg_exported_destroy, +}; + +static void +meta_wayland_xdg_exported_destroy (MetaWaylandXdgExported *exported) +{ + MetaWaylandXdgForeign *foreign = exported->foreign; + + while (exported->imported) + { + MetaWaylandXdgImported *imported = exported->imported->data; + + zxdg_imported_v1_send_destroyed (imported->resource); + meta_wayland_xdg_imported_destroy (imported); + } + + g_clear_signal_handler (&exported->surface_unmapped_handler_id, + exported->surface); + wl_resource_set_user_data (exported->resource, NULL); + + g_hash_table_remove (foreign->exported_surfaces, exported->handle); + + g_free (exported->handle); + g_free (exported); +} + +static void +xdg_exported_destructor (struct wl_resource *resource) +{ + MetaWaylandXdgExported *exported = wl_resource_get_user_data (resource); + + if (exported) + meta_wayland_xdg_exported_destroy (exported); +} + +static void +exported_surface_unmapped (MetaWaylandSurface *surface, + MetaWaylandXdgExported *exported) +{ + meta_wayland_xdg_exported_destroy (exported); +} + +static void +xdg_exporter_export (struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *surface_resource) +{ + MetaWaylandXdgForeign *foreign = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + struct wl_resource *xdg_exported_resource; + MetaWaylandXdgExported *exported; + char *handle; + + if (!surface->role || + !meta_wayland_surface_get_window (surface) || + !(META_IS_WAYLAND_XDG_SURFACE (surface->role) || + META_IS_WAYLAND_ZXDG_SURFACE_V6 (surface->role))) + { + wl_resource_post_error (resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "exported surface had an invalid role"); + return; + } + + xdg_exported_resource = + wl_resource_create (client, + &zxdg_exported_v1_interface, + wl_resource_get_version (resource), + id); + if (!xdg_exported_resource) + { + wl_client_post_no_memory (client); + return; + } + + exported = g_new0 (MetaWaylandXdgExported, 1); + exported->foreign = foreign; + exported->surface = surface; + exported->resource = xdg_exported_resource; + + exported->surface_unmapped_handler_id = + g_signal_connect (surface, "unmapped", + G_CALLBACK (exported_surface_unmapped), + exported); + + wl_resource_set_implementation (xdg_exported_resource, + &meta_xdg_exported_interface, + exported, + xdg_exported_destructor); + + while (TRUE) + { + handle = meta_generate_random_id (foreign->rand, + META_XDG_FOREIGN_HANDLE_LENGTH); + + if (!g_hash_table_contains (foreign->exported_surfaces, handle)) + { + g_hash_table_insert (foreign->exported_surfaces, handle, exported); + break; + } + + g_free (handle); + } + + exported->handle = handle; + + zxdg_exported_v1_send_handle (xdg_exported_resource, handle); +} + +static const struct zxdg_exporter_v1_interface meta_xdg_exporter_interface = { + xdg_exporter_destroy, + xdg_exporter_export, +}; + +static void +bind_xdg_exporter (struct wl_client *client, + void *data, + uint32_t version, + uint32_t id) +{ + MetaWaylandXdgForeign *foreign = data; + struct wl_resource *resource; + + resource = wl_resource_create (client, + &zxdg_exporter_v1_interface, + META_ZXDG_EXPORTER_V1_VERSION, + id); + + if (resource == NULL) + { + wl_client_post_no_memory (client); + return; + } + + wl_resource_set_implementation (resource, + &meta_xdg_exporter_interface, + foreign, NULL); +} + +static void +xdg_imported_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +imported_parent_of_unmapped (MetaWaylandSurface *surface, + MetaWaylandXdgImported *imported) +{ + imported->parent_of = NULL; +} + +static gboolean +is_valid_child (MetaWaylandSurface *surface) +{ + if (!surface) + return TRUE; + + if (!surface->role) + return FALSE; + + if (!META_IS_WAYLAND_XDG_TOPLEVEL (surface->role) && + !META_IS_WAYLAND_ZXDG_TOPLEVEL_V6 (surface->role)) + return FALSE; + + if (!meta_wayland_surface_get_window (surface)) + return FALSE; + + return TRUE; +} + +static void +xdg_imported_set_parent_of (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *surface_resource) +{ + MetaWaylandXdgImported *imported = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface; + + if (!imported) + return; + + if (surface_resource) + surface = wl_resource_get_user_data (surface_resource); + else + surface = NULL; + + if (!is_valid_child (surface)) + { + wl_resource_post_error (imported->resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "set_parent_of was called with an invalid child"); + return; + } + + if (imported->parent_of) + g_clear_signal_handler (&imported->parent_of_unmapped_handler_id, + imported->parent_of); + + imported->parent_of = surface; + + if (surface) + { + MetaWindow *window; + MetaWindow *exported_window; + + imported->parent_of_unmapped_handler_id = + g_signal_connect (surface, "unmapped", + G_CALLBACK (imported_parent_of_unmapped), + imported); + + window = meta_wayland_surface_get_window (surface); + exported_window = + meta_wayland_surface_get_window (imported->exported->surface); + meta_window_set_transient_for (window, exported_window); + } +} + +static const struct zxdg_imported_v1_interface meta_xdg_imported_interface = { + xdg_imported_destroy, + xdg_imported_set_parent_of, +}; + +static void +xdg_importer_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +meta_wayland_xdg_imported_destroy (MetaWaylandXdgImported *imported) +{ + MetaWaylandXdgExported *exported = imported->exported; + + exported->imported = g_list_remove (exported->imported, imported); + + if (imported->parent_of) + { + MetaWindow *window; + + g_clear_signal_handler (&imported->parent_of_unmapped_handler_id, + imported->parent_of); + + window = meta_wayland_surface_get_window (imported->parent_of); + if (window) + meta_window_set_transient_for (window, NULL); + } + + wl_resource_set_user_data (imported->resource, NULL); + + g_free (imported); +} + +static void +xdg_imported_destructor (struct wl_resource *resource) +{ + MetaWaylandXdgImported *imported = wl_resource_get_user_data (resource); + + if (!imported) + return; + + meta_wayland_xdg_imported_destroy (imported); +} + +static void +xdg_importer_import (struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + const char *handle) +{ + MetaWaylandXdgForeign *foreign = wl_resource_get_user_data (resource); + struct wl_resource *xdg_imported_resource; + MetaWaylandXdgImported *imported; + MetaWaylandXdgExported *exported; + + xdg_imported_resource = + wl_resource_create (client, + &zxdg_imported_v1_interface, + wl_resource_get_version (resource), + id); + if (!xdg_imported_resource) + { + wl_client_post_no_memory (client); + return; + } + + wl_resource_set_implementation (xdg_imported_resource, + &meta_xdg_imported_interface, + NULL, + xdg_imported_destructor); + + exported = g_hash_table_lookup (foreign->exported_surfaces, handle); + if (!exported || + (!META_IS_WAYLAND_XDG_SURFACE (exported->surface->role) && + !META_IS_WAYLAND_ZXDG_SURFACE_V6 (exported->surface->role))) + { + zxdg_imported_v1_send_destroyed (xdg_imported_resource); + return; + } + + imported = g_new0 (MetaWaylandXdgImported, 1); + imported->foreign = foreign; + imported->exported = exported; + imported->resource = xdg_imported_resource; + + wl_resource_set_user_data (xdg_imported_resource, imported); + + exported->imported = g_list_prepend (exported->imported, imported); +} + +static const struct zxdg_importer_v1_interface meta_xdg_importer_interface = { + xdg_importer_destroy, + xdg_importer_import, +}; + +static void +bind_xdg_importer (struct wl_client *client, + void *data, + uint32_t version, + uint32_t id) +{ + MetaWaylandXdgForeign *foreign = data; + struct wl_resource *resource; + + resource = wl_resource_create (client, + &zxdg_importer_v1_interface, + META_ZXDG_IMPORTER_V1_VERSION, + id); + + if (resource == NULL) + { + wl_client_post_no_memory (client); + return; + } + + wl_resource_set_implementation (resource, + &meta_xdg_importer_interface, + foreign, + NULL); +} + +gboolean +meta_wayland_xdg_foreign_init (MetaWaylandCompositor *compositor) +{ + MetaWaylandXdgForeign *foreign; + + foreign = g_new0 (MetaWaylandXdgForeign, 1); + + foreign->compositor = compositor; + foreign->rand = g_rand_new (); + foreign->exported_surfaces = g_hash_table_new ((GHashFunc) g_str_hash, + (GEqualFunc) g_str_equal); + + if (wl_global_create (compositor->wayland_display, + &zxdg_exporter_v1_interface, 1, + foreign, + bind_xdg_exporter) == NULL) + return FALSE; + + if (wl_global_create (compositor->wayland_display, + &zxdg_importer_v1_interface, 1, + foreign, + bind_xdg_importer) == NULL) + return FALSE; + + return TRUE; +} diff --git a/src/core/eventqueue.h b/src/wayland/meta-wayland-xdg-foreign.h similarity index 51% rename from src/core/eventqueue.h rename to src/wayland/meta-wayland-xdg-foreign.h index d89b0a4e4..5542a301e 100644 --- a/src/core/eventqueue.h +++ b/src/wayland/meta-wayland-xdg-foreign.h @@ -1,10 +1,8 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* Muffin X event source for main loop */ - -/* - * Copyright (C) 2001 Havoc Pennington - * +/* + * Copyright (C) 2015 Red Hat + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the @@ -14,27 +12,23 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> */ -#ifndef META_EVENT_QUEUE_H -#define META_EVENT_QUEUE_H +#ifndef META_WAYLAND_FOREIGN_H +#define META_WAYLAND_FOREIGN_H #include <glib.h> -#include <X11/Xlib.h> - -typedef struct _MetaEventQueue MetaEventQueue; -typedef void (* MetaEventQueueFunc) (XEvent *event, - gpointer data); +#include "wayland/meta-wayland-types.h" -MetaEventQueue* meta_event_queue_new (Display *display, - MetaEventQueueFunc func, - gpointer data); -void meta_event_queue_free (MetaEventQueue *eq); +gboolean meta_wayland_xdg_foreign_init (MetaWaylandCompositor *compositor); -#endif +#endif /* META_WAYLAND_FOREIGN_H */ diff --git a/src/wayland/meta-wayland-xdg-shell.c b/src/wayland/meta-wayland-xdg-shell.c new file mode 100644 index 000000000..67733fb8e --- /dev/null +++ b/src/wayland/meta-wayland-xdg-shell.c @@ -0,0 +1,2422 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2012-2013 Intel Corporation + * Copyright (C) 2013-2015 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#include "config.h" + +#include "wayland/meta-wayland-xdg-shell.h" + +#include "backends/meta-logical-monitor.h" +#include "core/boxes-private.h" +#include "core/window-private.h" +#include "wayland/meta-wayland-outputs.h" +#include "wayland/meta-wayland-popup.h" +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-wayland-seat.h" +#include "wayland/meta-wayland-shell-surface.h" +#include "wayland/meta-wayland-surface.h" +#include "wayland/meta-wayland-versions.h" +#include "wayland/meta-wayland-window-configuration.h" +#include "wayland/meta-wayland.h" +#include "wayland/meta-window-wayland.h" + +#include "xdg-shell-server-protocol.h" + +enum +{ + XDG_SURFACE_PROP_0, + + XDG_SURFACE_PROP_SHELL_CLIENT, + XDG_SURFACE_PROP_RESOURCE, +}; + +typedef struct _MetaWaylandXdgShellClient +{ + struct wl_resource *resource; + GList *surfaces; + GList *surface_constructors; +} MetaWaylandXdgShellClient; + +typedef struct _MetaWaylandXdgPositioner +{ + MetaRectangle anchor_rect; + int32_t width; + int32_t height; + uint32_t gravity; + uint32_t anchor; + uint32_t constraint_adjustment; + int32_t offset_x; + int32_t offset_y; + + gboolean is_reactive; + + gboolean has_parent_size; + int32_t parent_width; + int32_t parent_height; + + gboolean acked_parent_configure; + uint32_t parent_configure_serial; +} MetaWaylandXdgPositioner; + +typedef struct _MetaWaylandXdgSurfaceConstructor +{ + MetaWaylandSurface *surface; + struct wl_resource *resource; + MetaWaylandXdgShellClient *shell_client; +} MetaWaylandXdgSurfaceConstructor; + +typedef struct _MetaWaylandXdgSurfacePrivate +{ + struct wl_resource *resource; + MetaWaylandXdgShellClient *shell_client; + MetaRectangle geometry; + + guint configure_sent : 1; + guint first_buffer_attached : 1; + guint has_set_geometry : 1; +} MetaWaylandXdgSurfacePrivate; + +G_DEFINE_TYPE_WITH_PRIVATE (MetaWaylandXdgSurface, + meta_wayland_xdg_surface, + META_TYPE_WAYLAND_SHELL_SURFACE); + +struct _MetaWaylandXdgToplevel +{ + MetaWaylandXdgSurface parent; + + struct wl_resource *resource; +}; + +G_DEFINE_TYPE (MetaWaylandXdgToplevel, + meta_wayland_xdg_toplevel, + META_TYPE_WAYLAND_XDG_SURFACE); + +struct _MetaWaylandXdgPopup +{ + MetaWaylandXdgSurface parent; + + struct wl_resource *resource; + + MetaWaylandSurface *parent_surface; + gulong parent_surface_unmapped_handler_id; + + uint32_t pending_reposition_token; + gboolean pending_repositioned; + + MetaWaylandPopup *popup; + + gboolean dismissed_by_client; + + struct { + MetaWaylandSurface *parent_surface; + + /* + * The coordinates/dimensions in the placement rule are in logical pixel + * coordinate space, i.e. not scaled given what monitor the popup is on. + */ + MetaPlacementRule placement_rule; + + MetaWaylandSeat *grab_seat; + uint32_t grab_serial; + } setup; +}; + +static void +popup_surface_iface_init (MetaWaylandPopupSurfaceInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (MetaWaylandXdgPopup, + meta_wayland_xdg_popup, + META_TYPE_WAYLAND_XDG_SURFACE, + G_IMPLEMENT_INTERFACE (META_TYPE_WAYLAND_POPUP_SURFACE, + popup_surface_iface_init)); + +static MetaPlacementRule +meta_wayland_xdg_positioner_to_placement (MetaWaylandXdgPositioner *xdg_positioner, + MetaWindow *parent_window); + +static struct wl_resource * +meta_wayland_xdg_surface_get_wm_base_resource (MetaWaylandXdgSurface *xdg_surface); + +static MetaRectangle +meta_wayland_xdg_surface_get_window_geometry (MetaWaylandXdgSurface *xdg_surface); + +static void +meta_wayland_xdg_surface_send_configure (MetaWaylandXdgSurface *xdg_surface, + MetaWaylandWindowConfiguration *configuration); + +static void +scale_placement_rule (MetaPlacementRule *placement_rule, + MetaWaylandSurface *surface); + +static MetaWaylandSurface * +surface_from_xdg_surface_resource (struct wl_resource *resource) +{ + MetaWaylandSurfaceRole *surface_role = wl_resource_get_user_data (resource); + + if (!META_IS_WAYLAND_SURFACE_ROLE (surface_role)) + return NULL; + + return meta_wayland_surface_role_get_surface (surface_role); +} + +static MetaWaylandSurface * +surface_from_xdg_toplevel_resource (struct wl_resource *resource) +{ + return surface_from_xdg_surface_resource (resource); +} + +static void +meta_wayland_xdg_surface_reset (MetaWaylandXdgSurface *xdg_surface) +{ + META_WAYLAND_XDG_SURFACE_GET_CLASS (xdg_surface)->reset (xdg_surface); +} + +static void +xdg_toplevel_destructor (struct wl_resource *resource) +{ + MetaWaylandXdgToplevel *xdg_toplevel = wl_resource_get_user_data (resource); + MetaWaylandShellSurface *shell_surface = + META_WAYLAND_SHELL_SURFACE (xdg_toplevel); + + meta_wayland_shell_surface_destroy_window (shell_surface); + xdg_toplevel->resource = NULL; +} + +static void +xdg_toplevel_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +xdg_toplevel_set_parent (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *parent_resource) +{ + MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource); + MetaWindow *transient_for = NULL; + MetaWindow *window; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + if (parent_resource) + { + MetaWaylandSurface *parent_surface = + surface_from_xdg_surface_resource (parent_resource); + + transient_for = meta_wayland_surface_get_window (parent_surface); + } + + meta_window_set_transient_for (window, transient_for); +} + +static void +xdg_toplevel_set_title (struct wl_client *client, + struct wl_resource *resource, + const char *title) +{ + MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource); + MetaWindow *window; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + if (!g_utf8_validate (title, -1, NULL)) + title = ""; + + meta_window_set_title (window, title); +} + +static void +xdg_toplevel_set_app_id (struct wl_client *client, + struct wl_resource *resource, + const char *app_id) +{ + MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource); + MetaWindow *window; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + if (!g_utf8_validate (app_id, -1, NULL)) + app_id = ""; + + meta_window_set_wm_class (window, app_id, app_id); +} + +static void +xdg_toplevel_show_window_menu (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *seat_resource, + uint32_t serial, + int32_t x, + int32_t y) +{ + MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); + MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource); + MetaWindow *window; + int monitor_scale; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + if (!meta_wayland_seat_get_grab_info (seat, surface, serial, FALSE, NULL, NULL)) + return; + + monitor_scale = meta_window_wayland_get_geometry_scale (window); + meta_window_show_menu (window, META_WINDOW_MENU_WM, + window->buffer_rect.x + (x * monitor_scale), + window->buffer_rect.y + (y * monitor_scale)); +} + +static void +xdg_toplevel_move (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *seat_resource, + uint32_t serial) +{ + MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); + MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource); + MetaWindow *window; + float x, y; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + if (!meta_wayland_seat_get_grab_info (seat, surface, serial, TRUE, &x, &y)) + return; + + meta_wayland_surface_begin_grab_op (surface, seat, META_GRAB_OP_MOVING, x, y); +} + +static MetaGrabOp +grab_op_for_xdg_toplevel_resize_edge (int edge) +{ + MetaGrabOp op = META_GRAB_OP_WINDOW_BASE; + + if (edge & XDG_TOPLEVEL_RESIZE_EDGE_TOP) + op |= META_GRAB_OP_WINDOW_DIR_NORTH; + if (edge & XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM) + op |= META_GRAB_OP_WINDOW_DIR_SOUTH; + if (edge & XDG_TOPLEVEL_RESIZE_EDGE_LEFT) + op |= META_GRAB_OP_WINDOW_DIR_WEST; + if (edge & XDG_TOPLEVEL_RESIZE_EDGE_RIGHT) + op |= META_GRAB_OP_WINDOW_DIR_EAST; + + if (op == META_GRAB_OP_WINDOW_BASE) + { + g_warning ("invalid edge: %d", edge); + return META_GRAB_OP_NONE; + } + + return op; +} + +static void +xdg_toplevel_resize (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *seat_resource, + uint32_t serial, + uint32_t edges) +{ + MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); + MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource); + MetaWindow *window; + gfloat x, y; + MetaGrabOp grab_op; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + if (!meta_wayland_seat_get_grab_info (seat, surface, serial, TRUE, &x, &y)) + return; + + grab_op = grab_op_for_xdg_toplevel_resize_edge (edges); + meta_wayland_surface_begin_grab_op (surface, seat, grab_op, x, y); +} + +static void +xdg_toplevel_set_max_size (struct wl_client *client, + struct wl_resource *resource, + int32_t width, + int32_t height) +{ + MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource); + MetaWaylandSurfaceState *pending; + + if (width < 0 || height < 0) + { + wl_resource_post_error (resource, + XDG_WM_BASE_ERROR_INVALID_SURFACE_STATE, + "invalid negative max size requested %i x %i", + width, height); + return; + } + + + pending = meta_wayland_surface_get_pending_state (surface); + pending->has_new_max_size = TRUE; + pending->new_max_width = width; + pending->new_max_height = height; +} + +static void +xdg_toplevel_set_min_size (struct wl_client *client, + struct wl_resource *resource, + int32_t width, + int32_t height) +{ + MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource); + MetaWaylandSurfaceState *pending; + + if (width < 0 || height < 0) + { + wl_resource_post_error (resource, + XDG_WM_BASE_ERROR_INVALID_SURFACE_STATE, + "invalid negative min size requested %i x %i", + width, height); + return; + } + + + pending = meta_wayland_surface_get_pending_state (surface); + pending->has_new_min_size = TRUE; + pending->new_min_width = width; + pending->new_min_height = height; +} + +static void +xdg_toplevel_set_maximized (struct wl_client *client, + struct wl_resource *resource) +{ + MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource); + MetaWindow *window; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + if (!window->has_maximize_func) + return; + + meta_window_force_placement (window, TRUE); + meta_window_maximize (window, META_MAXIMIZE_BOTH); +} + +static void +xdg_toplevel_unset_maximized (struct wl_client *client, + struct wl_resource *resource) +{ + MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource); + MetaWindow *window; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + meta_window_unmaximize (window, META_MAXIMIZE_BOTH); +} + +static void +xdg_toplevel_set_fullscreen (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *output_resource) +{ + MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource); + MetaWindow *window; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + if (output_resource) + { + MetaWaylandOutput *output = wl_resource_get_user_data (output_resource); + + if (output && output->logical_monitor) + { + meta_window_move_to_monitor (window, + output->logical_monitor->number); + } + } + + meta_window_make_fullscreen (window); +} + +static void +xdg_toplevel_unset_fullscreen (struct wl_client *client, + struct wl_resource *resource) +{ + MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource); + MetaWindow *window; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + meta_window_unmake_fullscreen (window); +} + +static void +xdg_toplevel_set_minimized (struct wl_client *client, + struct wl_resource *resource) +{ + MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource); + MetaWindow *window; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + meta_window_minimize (window); +} + +static const struct xdg_toplevel_interface meta_wayland_xdg_toplevel_interface = { + xdg_toplevel_destroy, + xdg_toplevel_set_parent, + xdg_toplevel_set_title, + xdg_toplevel_set_app_id, + xdg_toplevel_show_window_menu, + xdg_toplevel_move, + xdg_toplevel_resize, + xdg_toplevel_set_max_size, + xdg_toplevel_set_min_size, + xdg_toplevel_set_maximized, + xdg_toplevel_unset_maximized, + xdg_toplevel_set_fullscreen, + xdg_toplevel_unset_fullscreen, + xdg_toplevel_set_minimized, +}; + +static void +meta_wayland_xdg_popup_unmap (MetaWaylandXdgPopup *xdg_popup) +{ + MetaWaylandShellSurface *shell_surface = + META_WAYLAND_SHELL_SURFACE (xdg_popup); + + g_assert (!xdg_popup->popup); + + if (xdg_popup->parent_surface) + { + g_clear_signal_handler (&xdg_popup->parent_surface_unmapped_handler_id, + xdg_popup->parent_surface); + xdg_popup->parent_surface = NULL; + } + + meta_wayland_shell_surface_destroy_window (shell_surface); +} + +static void +dismiss_popup (MetaWaylandXdgPopup *xdg_popup) +{ + if (xdg_popup->popup) + meta_wayland_popup_dismiss (xdg_popup->popup); + else + meta_wayland_xdg_popup_unmap (xdg_popup); +} + +static void +xdg_popup_destructor (struct wl_resource *resource) +{ + MetaWaylandXdgPopup *xdg_popup = + META_WAYLAND_XDG_POPUP (wl_resource_get_user_data (resource)); + + dismiss_popup (xdg_popup); + + xdg_popup->resource = NULL; +} + +static void +xdg_popup_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +xdg_popup_grab (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *seat_resource, + uint32_t serial) +{ + MetaWaylandXdgPopup *xdg_popup = + META_WAYLAND_XDG_POPUP (wl_resource_get_user_data (resource)); + MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); + MetaWaylandSurface *parent_surface; + + parent_surface = xdg_popup->setup.parent_surface; + if (!parent_surface) + { + wl_resource_post_error (resource, + XDG_POPUP_ERROR_INVALID_GRAB, + "tried to grab after popup was mapped"); + return; + } + + xdg_popup->setup.grab_seat = seat; + xdg_popup->setup.grab_serial = serial; +} + +static void +xdg_popup_reposition (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *positioner_resource, + uint32_t token) +{ + MetaWaylandXdgPopup *xdg_popup = + META_WAYLAND_XDG_POPUP (wl_resource_get_user_data (resource)); + MetaWaylandSurfaceRole *surface_role = + META_WAYLAND_SURFACE_ROLE (xdg_popup); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWindow *window; + MetaWindow *parent_window; + MetaWaylandXdgPositioner *xdg_positioner; + MetaPlacementRule placement_rule; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + parent_window = meta_wayland_surface_get_window (xdg_popup->parent_surface); + + xdg_positioner = wl_resource_get_user_data (positioner_resource); + placement_rule = meta_wayland_xdg_positioner_to_placement (xdg_positioner, + parent_window); + + xdg_popup->pending_reposition_token = token; + xdg_popup->pending_repositioned = TRUE; + + scale_placement_rule (&placement_rule, surface); + + meta_window_update_placement_rule (window, &placement_rule); +} + +static const struct xdg_popup_interface meta_wayland_xdg_popup_interface = { + xdg_popup_destroy, + xdg_popup_grab, + xdg_popup_reposition, +}; + +static void +on_parent_surface_unmapped (MetaWaylandSurface *parent_surface, + MetaWaylandXdgPopup *xdg_popup) +{ + MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (xdg_popup); + struct wl_resource *xdg_wm_base_resource = + meta_wayland_xdg_surface_get_wm_base_resource (xdg_surface); + MetaWaylandShellSurface *shell_surface = + META_WAYLAND_SHELL_SURFACE (xdg_popup); + + wl_resource_post_error (xdg_wm_base_resource, + XDG_WM_BASE_ERROR_NOT_THE_TOPMOST_POPUP, + "destroyed popup not top most popup"); + xdg_popup->parent_surface = NULL; + + meta_wayland_shell_surface_destroy_window (shell_surface); +} + +static void +add_state_value (struct wl_array *states, + enum xdg_toplevel_state state) +{ + uint32_t *s; + + s = wl_array_add (states, sizeof *s); + *s = state; +} + +static void +fill_states (MetaWaylandXdgToplevel *xdg_toplevel, + struct wl_array *states) +{ + MetaWaylandSurfaceRole *surface_role = + META_WAYLAND_SURFACE_ROLE (xdg_toplevel); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWindow *window = meta_wayland_surface_get_window (surface); + + if (META_WINDOW_MAXIMIZED (window)) + add_state_value (states, XDG_TOPLEVEL_STATE_MAXIMIZED); + if (meta_window_is_fullscreen (window)) + add_state_value (states, XDG_TOPLEVEL_STATE_FULLSCREEN); + if (meta_grab_op_is_resizing (window->display->grab_op)) + add_state_value (states, XDG_TOPLEVEL_STATE_RESIZING); + if (meta_window_appears_focused (window)) + add_state_value (states, XDG_TOPLEVEL_STATE_ACTIVATED); + + if (wl_resource_get_version (xdg_toplevel->resource) >= + XDG_TOPLEVEL_STATE_TILED_LEFT_SINCE_VERSION) + { + if (window->edge_constraints.top != META_EDGE_CONSTRAINT_NONE) + add_state_value (states, XDG_TOPLEVEL_STATE_TILED_TOP); + if (window->edge_constraints.right != META_EDGE_CONSTRAINT_NONE) + add_state_value (states, XDG_TOPLEVEL_STATE_TILED_RIGHT); + if (window->edge_constraints.bottom != META_EDGE_CONSTRAINT_NONE) + add_state_value (states, XDG_TOPLEVEL_STATE_TILED_BOTTOM); + if (window->edge_constraints.left != META_EDGE_CONSTRAINT_NONE) + add_state_value (states, XDG_TOPLEVEL_STATE_TILED_LEFT); + } +} + +static void +meta_wayland_xdg_toplevel_send_configure (MetaWaylandXdgToplevel *xdg_toplevel, + MetaWaylandWindowConfiguration *configuration) +{ + MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (xdg_toplevel); + struct wl_array states; + + wl_array_init (&states); + fill_states (xdg_toplevel, &states); + + xdg_toplevel_send_configure (xdg_toplevel->resource, + configuration->width / configuration->scale, + configuration->height / configuration->scale, + &states); + wl_array_release (&states); + + meta_wayland_xdg_surface_send_configure (xdg_surface, configuration); +} + +static gboolean +is_new_size_hints_valid (MetaWindow *window, + MetaWaylandSurfaceState *pending) +{ + int new_min_width, new_min_height; + int new_max_width, new_max_height; + + if (pending->has_new_min_size) + { + new_min_width = pending->new_min_width; + new_min_height = pending->new_min_height; + } + else + { + meta_window_wayland_get_min_size (window, &new_min_width, &new_min_height); + } + + if (pending->has_new_max_size) + { + new_max_width = pending->new_max_width; + new_max_height = pending->new_max_height; + } + else + { + meta_window_wayland_get_max_size (window, &new_max_width, &new_max_height); + } + /* Zero means unlimited */ + return ((new_max_width == 0 || new_min_width <= new_max_width) && + (new_max_height == 0 || new_min_height <= new_max_height)); +} + +static void +meta_wayland_xdg_toplevel_apply_state (MetaWaylandSurfaceRole *surface_role, + MetaWaylandSurfaceState *pending) +{ + MetaWaylandXdgToplevel *xdg_toplevel = META_WAYLAND_XDG_TOPLEVEL (surface_role); + MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (xdg_toplevel); + MetaWaylandXdgSurfacePrivate *xdg_surface_priv = + meta_wayland_xdg_surface_get_instance_private (xdg_surface); + MetaWaylandActorSurface *actor_surface = + META_WAYLAND_ACTOR_SURFACE (xdg_toplevel); + MetaWaylandSurfaceRoleClass *surface_role_class; + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWindow *window; + + window = meta_wayland_surface_get_window (surface); + if (!window) + { + meta_wayland_actor_surface_queue_frame_callbacks (actor_surface, pending); + return; + } + + if (!surface->buffer_ref.buffer && xdg_surface_priv->first_buffer_attached) + { + meta_wayland_xdg_surface_reset (xdg_surface); + meta_wayland_actor_surface_queue_frame_callbacks (actor_surface, + pending); + return; + } + + surface_role_class = + META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_xdg_toplevel_parent_class); + surface_role_class->apply_state (surface_role, pending); + + if (!xdg_surface_priv->configure_sent) + { + MetaWaylandWindowConfiguration *configuration; + + configuration = meta_wayland_window_configuration_new_empty (); + meta_wayland_xdg_toplevel_send_configure (xdg_toplevel, configuration); + meta_wayland_window_configuration_free (configuration); + return; + } +} + +static void +meta_wayland_xdg_toplevel_post_apply_state (MetaWaylandSurfaceRole *surface_role, + MetaWaylandSurfaceState *pending) +{ + MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (surface_role); + MetaWaylandXdgSurfacePrivate *xdg_surface_priv = + meta_wayland_xdg_surface_get_instance_private (xdg_surface); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWaylandSurfaceRoleClass *surface_role_class; + MetaWindow *window; + MetaRectangle old_geometry; + MetaRectangle window_geometry; + + gboolean geometry_changed; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + old_geometry = xdg_surface_priv->geometry; + + surface_role_class = + META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_xdg_toplevel_parent_class); + surface_role_class->post_apply_state (surface_role, pending); + + if (!pending->newly_attached) + return; + + window_geometry = meta_wayland_xdg_surface_get_window_geometry (xdg_surface); + geometry_changed = !meta_rectangle_equal (&old_geometry, &window_geometry); + + if (geometry_changed || pending->has_acked_configure_serial) + { + meta_window_wayland_finish_move_resize (window, window_geometry, pending); + } + else if (pending->dx != 0 || pending->dy != 0) + { + g_warning ("XXX: Attach-initiated move without a new geometry. " + "This is unimplemented right now."); + } + + /* When we get to this point, we ought to have valid size hints */ + if (pending->has_new_min_size || pending->has_new_max_size) + { + if (is_new_size_hints_valid (window, pending)) + { + if (pending->has_new_min_size) + meta_window_wayland_set_min_size (window, + pending->new_min_width, + pending->new_min_height); + + if (pending->has_new_max_size) + meta_window_wayland_set_max_size (window, + pending->new_max_width, + pending->new_max_height); + + meta_window_recalc_features (window); + } + else + { + wl_resource_post_error (surface->resource, + XDG_WM_BASE_ERROR_INVALID_SURFACE_STATE, + "Invalid min/max size"); + } + } +} + +static MetaWaylandSurface * +meta_wayland_xdg_toplevel_get_toplevel (MetaWaylandSurfaceRole *surface_role) +{ + return meta_wayland_surface_role_get_surface (surface_role); +} + +static void +meta_wayland_xdg_toplevel_reset (MetaWaylandXdgSurface *xdg_surface) +{ + MetaWaylandShellSurface *shell_surface = + META_WAYLAND_SHELL_SURFACE (xdg_surface); + MetaWaylandSurfaceRole *surface_role = + META_WAYLAND_SURFACE_ROLE (xdg_surface); + MetaWaylandXdgSurfaceClass *xdg_surface_class = + META_WAYLAND_XDG_SURFACE_CLASS (meta_wayland_xdg_toplevel_parent_class); + MetaWaylandSurface *surface; + MetaWindow *window; + + surface = meta_wayland_surface_role_get_surface (surface_role); + + meta_wayland_shell_surface_destroy_window (shell_surface); + + meta_wayland_actor_surface_reset_actor (META_WAYLAND_ACTOR_SURFACE (surface_role)); + window = meta_window_wayland_new (meta_get_display (), surface); + meta_wayland_shell_surface_set_window (shell_surface, window); + + xdg_surface_class->reset (xdg_surface); +} + +static void +meta_wayland_xdg_toplevel_configure (MetaWaylandShellSurface *shell_surface, + MetaWaylandWindowConfiguration *configuration) +{ + MetaWaylandXdgToplevel *xdg_toplevel = + META_WAYLAND_XDG_TOPLEVEL (shell_surface); + MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (xdg_toplevel); + MetaWaylandXdgSurfacePrivate *xdg_surface_priv = + meta_wayland_xdg_surface_get_instance_private (xdg_surface); + + if (!xdg_surface_priv->resource) + return; + + if (!xdg_toplevel->resource) + return; + + meta_wayland_xdg_toplevel_send_configure (xdg_toplevel, configuration); +} + +static void +meta_wayland_xdg_toplevel_managed (MetaWaylandShellSurface *shell_surface, + MetaWindow *window) +{ +} + +static void +meta_wayland_xdg_toplevel_close (MetaWaylandShellSurface *shell_surface) +{ + MetaWaylandXdgToplevel *xdg_toplevel = + META_WAYLAND_XDG_TOPLEVEL (shell_surface); + + xdg_toplevel_send_close (xdg_toplevel->resource); +} + +static void +meta_wayland_xdg_toplevel_shell_client_destroyed (MetaWaylandXdgSurface *xdg_surface) +{ + MetaWaylandXdgToplevel *xdg_toplevel = + META_WAYLAND_XDG_TOPLEVEL (xdg_surface); + struct wl_resource *xdg_wm_base_resource = + meta_wayland_xdg_surface_get_wm_base_resource (xdg_surface); + MetaWaylandXdgSurfaceClass *xdg_surface_class = + META_WAYLAND_XDG_SURFACE_CLASS (meta_wayland_xdg_toplevel_parent_class); + + xdg_surface_class->shell_client_destroyed (xdg_surface); + + if (xdg_toplevel->resource) + { + wl_resource_post_error (xdg_wm_base_resource, + XDG_WM_BASE_ERROR_DEFUNCT_SURFACES, + "xdg_wm_base of xdg_toplevel@%d was destroyed", + wl_resource_get_id (xdg_toplevel->resource)); + + wl_resource_destroy (xdg_toplevel->resource); + } +} + +static void +meta_wayland_xdg_toplevel_finalize (GObject *object) +{ + MetaWaylandXdgToplevel *xdg_toplevel = META_WAYLAND_XDG_TOPLEVEL (object); + + g_clear_pointer (&xdg_toplevel->resource, wl_resource_destroy); + + G_OBJECT_CLASS (meta_wayland_xdg_toplevel_parent_class)->finalize (object); +} + +static void +meta_wayland_xdg_toplevel_init (MetaWaylandXdgToplevel *role) +{ +} + +static void +meta_wayland_xdg_toplevel_class_init (MetaWaylandXdgToplevelClass *klass) +{ + GObjectClass *object_class; + MetaWaylandSurfaceRoleClass *surface_role_class; + MetaWaylandShellSurfaceClass *shell_surface_class; + MetaWaylandXdgSurfaceClass *xdg_surface_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->finalize = meta_wayland_xdg_toplevel_finalize; + + surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass); + surface_role_class->apply_state = meta_wayland_xdg_toplevel_apply_state; + surface_role_class->post_apply_state = meta_wayland_xdg_toplevel_post_apply_state; + surface_role_class->get_toplevel = meta_wayland_xdg_toplevel_get_toplevel; + + shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass); + shell_surface_class->configure = meta_wayland_xdg_toplevel_configure; + shell_surface_class->managed = meta_wayland_xdg_toplevel_managed; + shell_surface_class->close = meta_wayland_xdg_toplevel_close; + + xdg_surface_class = META_WAYLAND_XDG_SURFACE_CLASS (klass); + xdg_surface_class->shell_client_destroyed = + meta_wayland_xdg_toplevel_shell_client_destroyed; + xdg_surface_class->reset = meta_wayland_xdg_toplevel_reset; +} + +static void +scale_placement_rule (MetaPlacementRule *placement_rule, + MetaWaylandSurface *surface) +{ + MetaWindow *window = meta_wayland_surface_get_window (surface); + int geometry_scale; + + geometry_scale = meta_window_wayland_get_geometry_scale (window); + + placement_rule->anchor_rect.x *= geometry_scale; + placement_rule->anchor_rect.y *= geometry_scale; + placement_rule->anchor_rect.width *= geometry_scale; + placement_rule->anchor_rect.height *= geometry_scale; + placement_rule->offset_x *= geometry_scale; + placement_rule->offset_y *= geometry_scale; + placement_rule->width *= geometry_scale; + placement_rule->height *= geometry_scale; +} + +static void +meta_wayland_xdg_popup_place (MetaWaylandXdgPopup *xdg_popup, + MetaPlacementRule *placement_rule) +{ + MetaWaylandSurfaceRole *surface_role = META_WAYLAND_SURFACE_ROLE (xdg_popup); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaPlacementRule scaled_placement_rule; + MetaWindow *window; + + scaled_placement_rule = *placement_rule; + scale_placement_rule (&scaled_placement_rule, surface); + + window = meta_wayland_surface_get_window (surface); + meta_window_place_with_placement_rule (window, &scaled_placement_rule); +} + +static void +finish_popup_setup (MetaWaylandXdgPopup *xdg_popup) +{ + MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (xdg_popup); + MetaWaylandShellSurface *shell_surface = + META_WAYLAND_SHELL_SURFACE (xdg_surface); + MetaWaylandSurfaceRole *surface_role = META_WAYLAND_SURFACE_ROLE (xdg_popup); + struct wl_resource *xdg_wm_base_resource = + meta_wayland_xdg_surface_get_wm_base_resource (xdg_surface); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWaylandSurface *parent_surface; + MetaWaylandSeat *seat; + uint32_t serial; + MetaDisplay *display = meta_get_display (); + MetaWindow *window; + + parent_surface = xdg_popup->setup.parent_surface; + seat = xdg_popup->setup.grab_seat; + serial = xdg_popup->setup.grab_serial; + + xdg_popup->setup.parent_surface = NULL; + xdg_popup->setup.grab_seat = NULL; + + if (!meta_wayland_surface_get_window (parent_surface)) + { + xdg_popup_send_popup_done (xdg_popup->resource); + return; + } + + if (seat) + { + MetaWaylandSurface *top_popup; + + if (!meta_wayland_seat_can_popup (seat, serial)) + { + xdg_popup_send_popup_done (xdg_popup->resource); + return; + } + + top_popup = meta_wayland_pointer_get_top_popup (seat->pointer); + if (top_popup && parent_surface != top_popup) + { + wl_resource_post_error (xdg_wm_base_resource, + XDG_WM_BASE_ERROR_NOT_THE_TOPMOST_POPUP, + "parent not top most surface"); + return; + } + } + + xdg_popup->parent_surface = parent_surface; + xdg_popup->parent_surface_unmapped_handler_id = + g_signal_connect (parent_surface, "unmapped", + G_CALLBACK (on_parent_surface_unmapped), + xdg_popup); + + window = meta_window_wayland_new (display, surface); + meta_wayland_shell_surface_set_window (shell_surface, window); + + meta_wayland_xdg_popup_place (xdg_popup, &xdg_popup->setup.placement_rule); + + if (seat) + { + MetaWaylandPopupSurface *popup_surface; + MetaWaylandPopup *popup; + + meta_window_focus (window, meta_display_get_current_time (display)); + popup_surface = META_WAYLAND_POPUP_SURFACE (surface->role); + popup = meta_wayland_pointer_start_popup_grab (seat->pointer, + popup_surface); + if (popup == NULL) + { + xdg_popup_send_popup_done (xdg_popup->resource); + meta_wayland_shell_surface_destroy_window (shell_surface); + return; + } + + xdg_popup->popup = popup; + } + else + { + /* The keyboard focus semantics for non-grabbing xdg_wm_base popups + * is pretty undefined. Same applies for subsurfaces, but in practice, + * subsurfaces never receive keyboard focus, so it makes sense to + * do the same for non-grabbing popups. + * + * See https://bugzilla.gnome.org/show_bug.cgi?id=771694#c24 + */ + window->input = FALSE; + } +} + +static void +meta_wayland_xdg_popup_apply_state (MetaWaylandSurfaceRole *surface_role, + MetaWaylandSurfaceState *pending) +{ + MetaWaylandXdgPopup *xdg_popup = META_WAYLAND_XDG_POPUP (surface_role); + MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (surface_role); + MetaWaylandXdgSurfacePrivate *xdg_surface_priv = + meta_wayland_xdg_surface_get_instance_private (xdg_surface); + MetaWaylandActorSurface *actor_surface = + META_WAYLAND_ACTOR_SURFACE (xdg_popup); + MetaWaylandSurfaceRoleClass *surface_role_class; + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + + if (xdg_popup->setup.parent_surface) + finish_popup_setup (xdg_popup); + + if (!surface->buffer_ref.buffer && xdg_surface_priv->first_buffer_attached) + { + meta_wayland_xdg_surface_reset (xdg_surface); + meta_wayland_actor_surface_queue_frame_callbacks (actor_surface, pending); + return; + } + + surface_role_class = + META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_xdg_popup_parent_class); + surface_role_class->apply_state (surface_role, pending); + + if (xdg_popup->dismissed_by_client && surface->buffer_ref.buffer) + { + wl_resource_post_error (xdg_popup->resource, + XDG_WM_BASE_ERROR_INVALID_SURFACE_STATE, + "Can't commit buffer to dismissed popup"); + return; + } +} + +static void +meta_wayland_xdg_popup_post_apply_state (MetaWaylandSurfaceRole *surface_role, + MetaWaylandSurfaceState *pending) +{ + MetaWaylandXdgPopup *xdg_popup = META_WAYLAND_XDG_POPUP (surface_role); + MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (surface_role); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWaylandSurfaceRoleClass *surface_role_class = + META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_xdg_popup_parent_class); + MetaWindow *window; + MetaWindow *parent_window; + MetaRectangle buffer_rect; + MetaRectangle parent_buffer_rect; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + if (!pending->newly_attached) + return; + + if (!surface->buffer_ref.buffer) + return; + + surface_role_class->post_apply_state (surface_role, pending); + + if (pending->has_acked_configure_serial) + { + MetaRectangle window_geometry; + + window_geometry = meta_wayland_xdg_surface_get_window_geometry (xdg_surface); + meta_window_wayland_finish_move_resize (window, window_geometry, pending); + } + + parent_window = meta_wayland_surface_get_window (xdg_popup->parent_surface); + meta_window_get_buffer_rect (window, &buffer_rect); + meta_window_get_buffer_rect (parent_window, &parent_buffer_rect); + if (!meta_rectangle_overlap (&buffer_rect, &parent_buffer_rect) && + !meta_rectangle_is_adjacent_to (&buffer_rect, &parent_buffer_rect)) + { + g_warning ("Buggy client caused popup to be placed outside of " + "parent window"); + dismiss_popup (xdg_popup); + } +} + +static MetaWaylandSurface * +meta_wayland_xdg_popup_get_toplevel (MetaWaylandSurfaceRole *surface_role) +{ + MetaWaylandXdgPopup *xdg_popup = META_WAYLAND_XDG_POPUP (surface_role); + + if (xdg_popup->parent_surface) + return meta_wayland_surface_get_toplevel (xdg_popup->parent_surface); + else + return NULL; +} + +static void +meta_wayland_xdg_popup_reset (MetaWaylandXdgSurface *xdg_surface) +{ + MetaWaylandXdgPopup *xdg_popup = META_WAYLAND_XDG_POPUP (xdg_surface); + MetaWaylandXdgSurfaceClass *xdg_surface_class = + META_WAYLAND_XDG_SURFACE_CLASS (meta_wayland_xdg_popup_parent_class); + + dismiss_popup (xdg_popup); + + xdg_popup->dismissed_by_client = TRUE; + + xdg_surface_class->reset (xdg_surface); +} + +static void +meta_wayland_xdg_popup_configure (MetaWaylandShellSurface *shell_surface, + MetaWaylandWindowConfiguration *configuration) +{ + MetaWaylandXdgPopup *xdg_popup = META_WAYLAND_XDG_POPUP (shell_surface); + MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (xdg_popup); + MetaWindow *parent_window = + meta_wayland_surface_get_window (xdg_popup->parent_surface); + int geometry_scale; + int x, y; + + /* If the parent surface was destroyed, its window will be destroyed + * before the popup receives the parent-destroy signal. This means that + * the popup may potentially get temporary focus until itself is destroyed. + * If this happen, don't try to configure the xdg_popup surface. + * + * FIXME: Could maybe add a signal that is emitted before the window is + * created so that we can avoid incorrect intermediate foci. + */ + if (!parent_window) + return; + + geometry_scale = meta_window_wayland_get_geometry_scale (parent_window); + x = configuration->rel_x / geometry_scale; + y = configuration->rel_y / geometry_scale; + if (xdg_popup->pending_repositioned) + { + xdg_popup_send_repositioned (xdg_popup->resource, + xdg_popup->pending_reposition_token); + xdg_popup->pending_repositioned = FALSE; + } + xdg_popup_send_configure (xdg_popup->resource, + x, y, + configuration->width / configuration->scale, + configuration->height / configuration->scale); + + meta_wayland_xdg_surface_send_configure (xdg_surface, configuration); +} + +static void +meta_wayland_xdg_popup_managed (MetaWaylandShellSurface *shell_surface, + MetaWindow *window) +{ + MetaWaylandXdgPopup *xdg_popup = META_WAYLAND_XDG_POPUP (shell_surface); + MetaWaylandSurface *parent = xdg_popup->parent_surface; + + g_assert (parent); + + meta_window_set_transient_for (window, + meta_wayland_surface_get_window (parent)); + meta_window_set_type (window, META_WINDOW_DROPDOWN_MENU); +} + +static void +meta_wayland_xdg_popup_shell_client_destroyed (MetaWaylandXdgSurface *xdg_surface) +{ + MetaWaylandXdgPopup *xdg_popup = META_WAYLAND_XDG_POPUP (xdg_surface); + struct wl_resource *xdg_wm_base_resource = + meta_wayland_xdg_surface_get_wm_base_resource (xdg_surface); + MetaWaylandXdgSurfaceClass *xdg_surface_class = + META_WAYLAND_XDG_SURFACE_CLASS (meta_wayland_xdg_popup_parent_class); + + xdg_surface_class->shell_client_destroyed (xdg_surface); + + if (xdg_popup->resource) + { + wl_resource_post_error (xdg_wm_base_resource, + XDG_WM_BASE_ERROR_DEFUNCT_SURFACES, + "xdg_wm_base of xdg_popup@%d was destroyed", + wl_resource_get_id (xdg_popup->resource)); + + wl_resource_destroy (xdg_popup->resource); + } +} + +static void +meta_wayland_xdg_popup_done (MetaWaylandPopupSurface *popup_surface) +{ + MetaWaylandXdgPopup *xdg_popup = META_WAYLAND_XDG_POPUP (popup_surface); + + xdg_popup_send_popup_done (xdg_popup->resource); +} + +static void +meta_wayland_xdg_popup_dismiss (MetaWaylandPopupSurface *popup_surface) +{ + MetaWaylandXdgPopup *xdg_popup = META_WAYLAND_XDG_POPUP (popup_surface); + MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (xdg_popup); + struct wl_resource *xdg_wm_base_resource = + meta_wayland_xdg_surface_get_wm_base_resource (xdg_surface); + MetaWaylandSurfaceRole *surface_role = META_WAYLAND_SURFACE_ROLE (xdg_popup); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWaylandSurface *top_popup; + + top_popup = meta_wayland_popup_get_top_popup (xdg_popup->popup); + if (surface != top_popup) + { + wl_resource_post_error (xdg_wm_base_resource, + XDG_WM_BASE_ERROR_NOT_THE_TOPMOST_POPUP, + "destroyed popup not top most popup"); + } + + xdg_popup->popup = NULL; + meta_wayland_xdg_popup_unmap (xdg_popup); +} + +static MetaWaylandSurface * +meta_wayland_xdg_popup_get_surface (MetaWaylandPopupSurface *popup_surface) +{ + MetaWaylandSurfaceRole *surface_role = + META_WAYLAND_SURFACE_ROLE (popup_surface); + + return meta_wayland_surface_role_get_surface (surface_role); +} + +static void +popup_surface_iface_init (MetaWaylandPopupSurfaceInterface *iface) +{ + iface->done = meta_wayland_xdg_popup_done; + iface->dismiss = meta_wayland_xdg_popup_dismiss; + iface->get_surface = meta_wayland_xdg_popup_get_surface; +} + +static void +meta_wayland_xdg_popup_finalize (GObject *object) +{ + MetaWaylandXdgPopup *xdg_popup = META_WAYLAND_XDG_POPUP (object); + + g_clear_pointer (&xdg_popup->resource, wl_resource_destroy); + + G_OBJECT_CLASS (meta_wayland_xdg_popup_parent_class)->finalize (object); +} + +static void +meta_wayland_xdg_popup_init (MetaWaylandXdgPopup *role) +{ +} + +static void +meta_wayland_xdg_popup_class_init (MetaWaylandXdgPopupClass *klass) +{ + GObjectClass *object_class; + MetaWaylandSurfaceRoleClass *surface_role_class; + MetaWaylandShellSurfaceClass *shell_surface_class; + MetaWaylandXdgSurfaceClass *xdg_surface_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->finalize = meta_wayland_xdg_popup_finalize; + + surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass); + surface_role_class->apply_state = meta_wayland_xdg_popup_apply_state; + surface_role_class->post_apply_state = meta_wayland_xdg_popup_post_apply_state; + surface_role_class->get_toplevel = meta_wayland_xdg_popup_get_toplevel; + + shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass); + shell_surface_class->configure = meta_wayland_xdg_popup_configure; + shell_surface_class->managed = meta_wayland_xdg_popup_managed; + + xdg_surface_class = META_WAYLAND_XDG_SURFACE_CLASS (klass); + xdg_surface_class->shell_client_destroyed = + meta_wayland_xdg_popup_shell_client_destroyed; + xdg_surface_class->reset = meta_wayland_xdg_popup_reset; +} + +static struct wl_resource * +meta_wayland_xdg_surface_get_wm_base_resource (MetaWaylandXdgSurface *xdg_surface) +{ + MetaWaylandXdgSurfacePrivate *priv = + meta_wayland_xdg_surface_get_instance_private (xdg_surface); + + return priv->shell_client->resource; +} + +static MetaRectangle +meta_wayland_xdg_surface_get_window_geometry (MetaWaylandXdgSurface *xdg_surface) +{ + MetaWaylandXdgSurfacePrivate *priv = + meta_wayland_xdg_surface_get_instance_private (xdg_surface); + + return priv->geometry; +} + +static gboolean +meta_wayland_xdg_surface_is_assigned (MetaWaylandXdgSurface *xdg_surface) +{ + MetaWaylandXdgSurfacePrivate *priv = + meta_wayland_xdg_surface_get_instance_private (xdg_surface); + + return priv->resource != NULL; +} + +static void +meta_wayland_xdg_surface_send_configure (MetaWaylandXdgSurface *xdg_surface, + MetaWaylandWindowConfiguration *configuration) +{ + MetaWaylandXdgSurfacePrivate *priv = + meta_wayland_xdg_surface_get_instance_private (xdg_surface); + + xdg_surface_send_configure (priv->resource, configuration->serial); + + priv->configure_sent = TRUE; +} + +static void +xdg_surface_destructor (struct wl_resource *resource) +{ + MetaWaylandXdgSurface *xdg_surface = wl_resource_get_user_data (resource); + MetaWaylandXdgSurfacePrivate *priv = + meta_wayland_xdg_surface_get_instance_private (xdg_surface); + + priv->shell_client->surfaces = g_list_remove (priv->shell_client->surfaces, + xdg_surface); + + priv->resource = NULL; + priv->first_buffer_attached = FALSE; +} + +static void +xdg_surface_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +xdg_surface_get_toplevel (struct wl_client *client, + struct wl_resource *resource, + uint32_t id) +{ + MetaWaylandXdgSurface *xdg_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = surface_from_xdg_surface_resource (resource); + struct wl_resource *xdg_wm_base_resource = + meta_wayland_xdg_surface_get_wm_base_resource (xdg_surface); + + wl_resource_post_error (xdg_wm_base_resource, XDG_WM_BASE_ERROR_ROLE, + "wl_surface@%d already has a role assigned", + wl_resource_get_id (surface->resource)); +} + +static void +xdg_surface_get_popup (struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *parent_resource, + struct wl_resource *positioner_resource) +{ + MetaWaylandXdgSurface *xdg_surface = wl_resource_get_user_data (resource); + MetaWaylandXdgSurfacePrivate *priv = + meta_wayland_xdg_surface_get_instance_private (xdg_surface); + MetaWaylandSurface *surface = surface_from_xdg_surface_resource (resource); + + wl_resource_post_error (priv->shell_client->resource, + XDG_WM_BASE_ERROR_ROLE, + "wl_surface@%d already has a role assigned", + wl_resource_get_id (surface->resource)); +} + +static void +xdg_surface_set_window_geometry (struct wl_client *client, + struct wl_resource *resource, + int32_t x, + int32_t y, + int32_t width, + int32_t height) +{ + MetaWaylandSurface *surface = surface_from_xdg_surface_resource (resource); + MetaWaylandSurfaceState *pending; + + pending = meta_wayland_surface_get_pending_state (surface); + pending->has_new_geometry = TRUE; + pending->new_geometry.x = x; + pending->new_geometry.y = y; + pending->new_geometry.width = width; + pending->new_geometry.height = height; +} + +static void +xdg_surface_ack_configure (struct wl_client *client, + struct wl_resource *resource, + uint32_t serial) +{ + MetaWaylandSurface *surface = surface_from_xdg_surface_resource (resource); + MetaWaylandSurfaceState *pending; + + pending = meta_wayland_surface_get_pending_state (surface); + pending->has_acked_configure_serial = TRUE; + pending->acked_configure_serial = serial; +} + +static const struct xdg_surface_interface meta_wayland_xdg_surface_interface = { + xdg_surface_destroy, + xdg_surface_get_toplevel, + xdg_surface_get_popup, + xdg_surface_set_window_geometry, + xdg_surface_ack_configure, +}; + +static void +meta_wayland_xdg_surface_finalize (GObject *object) +{ + MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (object); + MetaWaylandXdgSurfacePrivate *priv = + meta_wayland_xdg_surface_get_instance_private (xdg_surface); + + g_clear_pointer (&priv->resource, wl_resource_destroy); + + G_OBJECT_CLASS (meta_wayland_xdg_surface_parent_class)->finalize (object); +} + +static void +meta_wayland_xdg_surface_real_reset (MetaWaylandXdgSurface *xdg_surface) +{ + MetaWaylandXdgSurfacePrivate *priv = + meta_wayland_xdg_surface_get_instance_private (xdg_surface); + + priv->first_buffer_attached = FALSE; + priv->configure_sent = FALSE; + priv->geometry = (MetaRectangle) { 0 }; + priv->has_set_geometry = FALSE; +} + +static void +meta_wayland_xdg_surface_apply_state (MetaWaylandSurfaceRole *surface_role, + MetaWaylandSurfaceState *pending) +{ + MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (surface_role); + MetaWaylandXdgSurfacePrivate *priv = + meta_wayland_xdg_surface_get_instance_private (xdg_surface); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWindow *window = meta_wayland_surface_get_window (surface); + MetaWaylandSurfaceRoleClass *surface_role_class; + + surface_role_class = + META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_xdg_surface_parent_class); + surface_role_class->apply_state (surface_role, pending); + + /* Ignore commits when unassigned. */ + if (!priv->resource) + return; + + if (!window) + return; + + if (surface->buffer_ref.buffer) + priv->first_buffer_attached = TRUE; +} + +static void +meta_wayland_xdg_surface_post_apply_state (MetaWaylandSurfaceRole *surface_role, + MetaWaylandSurfaceState *pending) +{ + MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (surface_role); + MetaWaylandXdgSurfacePrivate *priv = + meta_wayland_xdg_surface_get_instance_private (xdg_surface); + MetaWaylandShellSurface *shell_surface = + META_WAYLAND_SHELL_SURFACE (surface_role); + + if (pending->has_new_geometry) + { + meta_wayland_shell_surface_determine_geometry (shell_surface, + &pending->new_geometry, + &priv->geometry); + priv->has_set_geometry = TRUE; + } + else if (!priv->has_set_geometry) + { + MetaRectangle new_geometry = { 0 }; + + /* If the surface has never set any geometry, calculate + * a default one unioning the surface and all subsurfaces together. */ + + meta_wayland_shell_surface_calculate_geometry (shell_surface, + &new_geometry); + if (!meta_rectangle_equal (&new_geometry, &priv->geometry)) + { + pending->has_new_geometry = TRUE; + priv->geometry = new_geometry; + } + } +} + +static void +meta_wayland_xdg_surface_assigned (MetaWaylandSurfaceRole *surface_role) +{ + MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (surface_role); + MetaWaylandXdgSurfacePrivate *priv = + meta_wayland_xdg_surface_get_instance_private (xdg_surface); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + struct wl_resource *xdg_wm_base_resource = + meta_wayland_xdg_surface_get_wm_base_resource (xdg_surface); + MetaWaylandSurfaceRoleClass *surface_role_class; + + priv->configure_sent = FALSE; + priv->first_buffer_attached = FALSE; + + if (surface->buffer_ref.buffer) + { + wl_resource_post_error (xdg_wm_base_resource, + XDG_WM_BASE_ERROR_INVALID_SURFACE_STATE, + "wl_surface@%d already has a buffer committed", + wl_resource_get_id (surface->resource)); + return; + } + + surface_role_class = + META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_xdg_surface_parent_class); + surface_role_class->assigned (surface_role); +} + +static void +meta_wayland_xdg_surface_ping (MetaWaylandShellSurface *shell_surface, + uint32_t serial) +{ + MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (shell_surface); + MetaWaylandXdgSurfacePrivate *priv = + meta_wayland_xdg_surface_get_instance_private (xdg_surface); + + xdg_wm_base_send_ping (priv->shell_client->resource, serial); +} + +static void +meta_wayland_xdg_surface_real_shell_client_destroyed (MetaWaylandXdgSurface *xdg_surface) +{ + MetaWaylandXdgSurfacePrivate *priv = + meta_wayland_xdg_surface_get_instance_private (xdg_surface); + + if (priv->resource) + { + wl_resource_post_error (priv->shell_client->resource, + XDG_WM_BASE_ERROR_DEFUNCT_SURFACES, + "xdg_wm_base of xdg_surface@%d was destroyed", + wl_resource_get_id (priv->resource)); + + wl_resource_destroy (priv->resource); + } +} + +static void +meta_wayland_xdg_surface_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (object); + MetaWaylandXdgSurfacePrivate *priv = + meta_wayland_xdg_surface_get_instance_private (xdg_surface); + + switch (prop_id) + { + case XDG_SURFACE_PROP_SHELL_CLIENT: + priv->shell_client = g_value_get_pointer (value); + break; + + case XDG_SURFACE_PROP_RESOURCE: + priv->resource = g_value_get_pointer (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_wayland_xdg_surface_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (object); + MetaWaylandXdgSurfacePrivate *priv = + meta_wayland_xdg_surface_get_instance_private (xdg_surface); + + switch (prop_id) + { + case XDG_SURFACE_PROP_SHELL_CLIENT: + g_value_set_pointer (value, priv->shell_client); + break; + + case XDG_SURFACE_PROP_RESOURCE: + g_value_set_pointer (value, priv->resource); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_wayland_xdg_surface_init (MetaWaylandXdgSurface *xdg_surface) +{ +} + +static void +meta_wayland_xdg_surface_class_init (MetaWaylandXdgSurfaceClass *klass) +{ + GObjectClass *object_class; + MetaWaylandSurfaceRoleClass *surface_role_class; + MetaWaylandShellSurfaceClass *shell_surface_class; + GParamSpec *pspec; + + object_class = G_OBJECT_CLASS (klass); + object_class->finalize = meta_wayland_xdg_surface_finalize; + object_class->set_property = meta_wayland_xdg_surface_set_property; + object_class->get_property = meta_wayland_xdg_surface_get_property; + + surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass); + surface_role_class->apply_state = meta_wayland_xdg_surface_apply_state; + surface_role_class->post_apply_state = meta_wayland_xdg_surface_post_apply_state; + surface_role_class->assigned = meta_wayland_xdg_surface_assigned; + + shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass); + shell_surface_class->ping = meta_wayland_xdg_surface_ping; + + klass->shell_client_destroyed = + meta_wayland_xdg_surface_real_shell_client_destroyed; + klass->reset = meta_wayland_xdg_surface_real_reset; + + pspec = g_param_spec_pointer ("shell-client", + "MetaWaylandXdgShellClient", + "The shell client instance", + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, + XDG_SURFACE_PROP_SHELL_CLIENT, + pspec); + pspec = g_param_spec_pointer ("xdg-surface-resource", + "xdg_surface wl_resource", + "The xdg_surface wl_resource instance", + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, + XDG_SURFACE_PROP_RESOURCE, + pspec); +} + +static void +meta_wayland_xdg_surface_shell_client_destroyed (MetaWaylandXdgSurface *xdg_surface) +{ + MetaWaylandXdgSurfaceClass *xdg_surface_class = + META_WAYLAND_XDG_SURFACE_GET_CLASS (xdg_surface); + + xdg_surface_class->shell_client_destroyed (xdg_surface); +} + +static void +meta_wayland_xdg_surface_constructor_finalize (MetaWaylandXdgSurfaceConstructor *constructor, + MetaWaylandXdgSurface *xdg_surface) +{ + MetaWaylandXdgShellClient *shell_client = constructor->shell_client; + + shell_client->surface_constructors = + g_list_remove (shell_client->surface_constructors, constructor); + shell_client->surfaces = g_list_append (shell_client->surfaces, xdg_surface); + + wl_resource_set_implementation (constructor->resource, + &meta_wayland_xdg_surface_interface, + xdg_surface, + xdg_surface_destructor); + + g_free (constructor); +} + +static void +xdg_surface_constructor_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_post_error (resource, + XDG_SURFACE_ERROR_NOT_CONSTRUCTED, + "xdg_surface destroyed before constructed"); + wl_resource_destroy (resource); +} + +static void +xdg_surface_constructor_get_toplevel (struct wl_client *client, + struct wl_resource *resource, + uint32_t id) +{ + MetaWaylandXdgSurfaceConstructor *constructor = + wl_resource_get_user_data (resource); + MetaWaylandXdgShellClient *shell_client = constructor->shell_client; + struct wl_resource *xdg_surface_resource = constructor->resource; + MetaWaylandSurface *surface = constructor->surface; + MetaWaylandXdgToplevel *xdg_toplevel; + MetaWaylandXdgSurface *xdg_surface; + MetaWaylandShellSurface *shell_surface; + MetaWindow *window; + + if (!meta_wayland_surface_assign_role (surface, + META_TYPE_WAYLAND_XDG_TOPLEVEL, + "shell-client", shell_client, + "xdg-surface-resource", xdg_surface_resource, + NULL)) + { + wl_resource_post_error (resource, XDG_WM_BASE_ERROR_ROLE, + "wl_surface@%d already has a different role", + wl_resource_get_id (surface->resource)); + return; + } + + xdg_toplevel = META_WAYLAND_XDG_TOPLEVEL (surface->role); + xdg_toplevel->resource = wl_resource_create (client, + &xdg_toplevel_interface, + wl_resource_get_version (resource), + id); + wl_resource_set_implementation (xdg_toplevel->resource, + &meta_wayland_xdg_toplevel_interface, + xdg_toplevel, + xdg_toplevel_destructor); + + xdg_surface = META_WAYLAND_XDG_SURFACE (xdg_toplevel); + meta_wayland_xdg_surface_constructor_finalize (constructor, xdg_surface); + + window = meta_window_wayland_new (meta_get_display (), surface); + shell_surface = META_WAYLAND_SHELL_SURFACE (xdg_surface); + meta_wayland_shell_surface_set_window (shell_surface, window); +} + +static void +xdg_surface_constructor_get_popup (struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *parent_resource, + struct wl_resource *positioner_resource) +{ + MetaWaylandXdgSurfaceConstructor *constructor = + wl_resource_get_user_data (resource); + MetaWaylandXdgShellClient *shell_client = constructor->shell_client; + MetaWaylandSurface *surface = constructor->surface; + struct wl_resource *xdg_wm_base_resource = constructor->shell_client->resource; + struct wl_resource *xdg_surface_resource = constructor->resource; + MetaWaylandSurface *parent_surface; + MetaWindow *parent_window; + MetaWaylandXdgPositioner *xdg_positioner; + MetaWaylandXdgPopup *xdg_popup; + MetaWaylandXdgSurface *xdg_surface; + + if (!parent_resource) + { + wl_resource_post_error (xdg_wm_base_resource, + XDG_WM_BASE_ERROR_INVALID_POPUP_PARENT, + "Parent surface is null but Mutter does not yet " + "support specifying parent surfaces via other " + "protocols"); + return; + } + + parent_surface = surface_from_xdg_surface_resource (parent_resource); + if (!parent_surface || !META_IS_WAYLAND_XDG_SURFACE (parent_surface->role)) + { + wl_resource_post_error (xdg_wm_base_resource, + XDG_WM_BASE_ERROR_INVALID_POPUP_PARENT, + "Invalid popup parent role"); + return; + } + + parent_window = meta_wayland_surface_get_window (parent_surface); + if (!parent_window) + { + wl_resource_post_error (xdg_wm_base_resource, + XDG_WM_BASE_ERROR_INVALID_POPUP_PARENT, + "Invalid popup parent window"); + return; + } + + if (!meta_wayland_surface_assign_role (surface, + META_TYPE_WAYLAND_XDG_POPUP, + "shell-client", shell_client, + "xdg-surface-resource", xdg_surface_resource, + NULL)) + { + wl_resource_post_error (xdg_wm_base_resource, XDG_WM_BASE_ERROR_ROLE, + "wl_surface@%d already has a different role", + wl_resource_get_id (surface->resource)); + return; + } + + xdg_popup = META_WAYLAND_XDG_POPUP (surface->role); + + xdg_popup->resource = wl_resource_create (client, + &xdg_popup_interface, + wl_resource_get_version (resource), + id); + wl_resource_set_implementation (xdg_popup->resource, + &meta_wayland_xdg_popup_interface, + xdg_popup, + xdg_popup_destructor); + + xdg_surface = META_WAYLAND_XDG_SURFACE (xdg_popup); + meta_wayland_xdg_surface_constructor_finalize (constructor, xdg_surface); + + xdg_positioner = wl_resource_get_user_data (positioner_resource); + xdg_popup->setup.placement_rule = + meta_wayland_xdg_positioner_to_placement (xdg_positioner, parent_window); + xdg_popup->setup.parent_surface = parent_surface; +} + +static void +xdg_surface_constructor_set_window_geometry (struct wl_client *client, + struct wl_resource *resource, + int32_t x, + int32_t y, + int32_t width, + int32_t height) +{ + wl_resource_post_error (resource, + XDG_SURFACE_ERROR_NOT_CONSTRUCTED, + "xdg_surface::set_window_geometry called before constructed"); +} + +static void +xdg_surface_constructor_ack_configure (struct wl_client *client, + struct wl_resource *resource, + uint32_t serial) +{ + wl_resource_post_error (resource, + XDG_SURFACE_ERROR_NOT_CONSTRUCTED, + "xdg_surface::ack_configure called before constructed"); +} + +static const struct xdg_surface_interface meta_wayland_xdg_surface_constructor_interface = { + xdg_surface_constructor_destroy, + xdg_surface_constructor_get_toplevel, + xdg_surface_constructor_get_popup, + xdg_surface_constructor_set_window_geometry, + xdg_surface_constructor_ack_configure, +}; + +static void +xdg_surface_constructor_destructor (struct wl_resource *resource) +{ + MetaWaylandXdgSurfaceConstructor *constructor = + wl_resource_get_user_data (resource); + + constructor->shell_client->surface_constructors = + g_list_remove (constructor->shell_client->surface_constructors, + constructor); + + g_free (constructor); +} + +static MetaPlacementAnchor +positioner_anchor_to_placement_anchor (uint32_t anchor) +{ + switch (anchor) + { + case XDG_POSITIONER_ANCHOR_NONE: + return META_PLACEMENT_ANCHOR_NONE; + case XDG_POSITIONER_ANCHOR_TOP: + return META_PLACEMENT_ANCHOR_TOP; + case XDG_POSITIONER_ANCHOR_BOTTOM: + return META_PLACEMENT_ANCHOR_BOTTOM; + case XDG_POSITIONER_ANCHOR_LEFT: + return META_PLACEMENT_ANCHOR_LEFT; + case XDG_POSITIONER_ANCHOR_RIGHT: + return META_PLACEMENT_ANCHOR_RIGHT; + case XDG_POSITIONER_ANCHOR_TOP_LEFT: + return (META_PLACEMENT_ANCHOR_TOP | META_PLACEMENT_ANCHOR_LEFT); + case XDG_POSITIONER_ANCHOR_BOTTOM_LEFT: + return (META_PLACEMENT_ANCHOR_BOTTOM | META_PLACEMENT_ANCHOR_LEFT); + case XDG_POSITIONER_ANCHOR_TOP_RIGHT: + return (META_PLACEMENT_ANCHOR_TOP | META_PLACEMENT_ANCHOR_RIGHT); + case XDG_POSITIONER_ANCHOR_BOTTOM_RIGHT: + return (META_PLACEMENT_ANCHOR_BOTTOM | META_PLACEMENT_ANCHOR_RIGHT); + default: + g_assert_not_reached (); + return META_PLACEMENT_ANCHOR_NONE; + } +} + +static MetaPlacementGravity +positioner_gravity_to_placement_gravity (uint32_t gravity) +{ + switch (gravity) + { + case XDG_POSITIONER_GRAVITY_NONE: + return META_PLACEMENT_GRAVITY_NONE; + case XDG_POSITIONER_GRAVITY_TOP: + return META_PLACEMENT_GRAVITY_TOP; + case XDG_POSITIONER_GRAVITY_BOTTOM: + return META_PLACEMENT_GRAVITY_BOTTOM; + case XDG_POSITIONER_GRAVITY_LEFT: + return META_PLACEMENT_GRAVITY_LEFT; + case XDG_POSITIONER_GRAVITY_RIGHT: + return META_PLACEMENT_GRAVITY_RIGHT; + case XDG_POSITIONER_GRAVITY_TOP_LEFT: + return (META_PLACEMENT_GRAVITY_TOP | META_PLACEMENT_GRAVITY_LEFT); + case XDG_POSITIONER_GRAVITY_BOTTOM_LEFT: + return (META_PLACEMENT_GRAVITY_BOTTOM | META_PLACEMENT_GRAVITY_LEFT); + case XDG_POSITIONER_GRAVITY_TOP_RIGHT: + return (META_PLACEMENT_GRAVITY_TOP | META_PLACEMENT_GRAVITY_RIGHT); + case XDG_POSITIONER_GRAVITY_BOTTOM_RIGHT: + return (META_PLACEMENT_GRAVITY_BOTTOM | META_PLACEMENT_GRAVITY_RIGHT); + default: + g_assert_not_reached (); + return META_PLACEMENT_GRAVITY_NONE; + } +} + +static MetaPlacementRule +meta_wayland_xdg_positioner_to_placement (MetaWaylandXdgPositioner *xdg_positioner, + MetaWindow *parent_window) +{ + MetaRectangle parent_rect; + + meta_window_get_frame_rect (parent_window, &parent_rect); + + if (xdg_positioner->acked_parent_configure) + { + MetaWindowWayland *parent_wl_window = META_WINDOW_WAYLAND (parent_window); + uint32_t serial; + MetaWaylandWindowConfiguration *configuration; + + serial = xdg_positioner->parent_configure_serial; + configuration = meta_window_wayland_peek_configuration (parent_wl_window, + serial); + + if (configuration) + { + if (configuration->flags & META_MOVE_RESIZE_STATE_CHANGED) + { + if (configuration->has_position) + { + parent_rect.x = configuration->x; + parent_rect.y = configuration->y; + } + if (configuration->has_size) + { + parent_rect.width = + configuration->width / configuration->scale; + parent_rect.height = + configuration->height / configuration->scale; + } + } + else if (xdg_positioner->has_parent_size) + { + meta_rectangle_resize_with_gravity (&parent_rect, + &parent_rect, + configuration->gravity, + xdg_positioner->parent_width, + xdg_positioner->parent_height); + } + } + } + else if (xdg_positioner->has_parent_size) + { + meta_rectangle_resize_with_gravity (&parent_rect, + &parent_rect, + META_GRAVITY_SOUTH_EAST, + xdg_positioner->parent_width, + xdg_positioner->parent_height); + } + + return (MetaPlacementRule) { + .anchor_rect = xdg_positioner->anchor_rect, + .gravity = positioner_gravity_to_placement_gravity (xdg_positioner->gravity), + .anchor = positioner_anchor_to_placement_anchor (xdg_positioner->anchor), + .constraint_adjustment = xdg_positioner->constraint_adjustment, + .offset_x = xdg_positioner->offset_x, + .offset_y = xdg_positioner->offset_y, + .width = xdg_positioner->width, + .height = xdg_positioner->height, + + .is_reactive = xdg_positioner->is_reactive, + + .parent_rect = parent_rect, + }; +} + +static void +xdg_positioner_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +xdg_positioner_set_size (struct wl_client *client, + struct wl_resource *resource, + int32_t width, + int32_t height) +{ + MetaWaylandXdgPositioner *positioner = wl_resource_get_user_data (resource); + + if (width <= 0 || height <= 0) + { + wl_resource_post_error (resource, XDG_POSITIONER_ERROR_INVALID_INPUT, + "Invalid size"); + return; + } + + positioner->width = width; + positioner->height = height; +} + +static void +xdg_positioner_set_anchor_rect (struct wl_client *client, + struct wl_resource *resource, + int32_t x, + int32_t y, + int32_t width, + int32_t height) +{ + MetaWaylandXdgPositioner *positioner = wl_resource_get_user_data (resource); + + if (width <= 0 || height <= 0) + { + wl_resource_post_error (resource, XDG_POSITIONER_ERROR_INVALID_INPUT, + "Invalid anchor rectangle size"); + return; + } + + positioner->anchor_rect = (MetaRectangle) { + .x = x, + .y = y, + .width = width, + .height = height, + }; +} + +static void +xdg_positioner_set_anchor (struct wl_client *client, + struct wl_resource *resource, + uint32_t anchor) +{ + MetaWaylandXdgPositioner *positioner = wl_resource_get_user_data (resource); + + if (anchor > XDG_POSITIONER_ANCHOR_BOTTOM_RIGHT) + { + wl_resource_post_error (resource, XDG_POSITIONER_ERROR_INVALID_INPUT, + "Invalid anchor"); + return; + } + + positioner->anchor = anchor; +} + +static void +xdg_positioner_set_gravity (struct wl_client *client, + struct wl_resource *resource, + uint32_t gravity) +{ + MetaWaylandXdgPositioner *positioner = wl_resource_get_user_data (resource); + + if (gravity > XDG_POSITIONER_GRAVITY_BOTTOM_RIGHT) + { + wl_resource_post_error (resource, XDG_POSITIONER_ERROR_INVALID_INPUT, + "Invalid gravity"); + return; + } + + positioner->gravity = gravity; +} + +static void +xdg_positioner_set_constraint_adjustment (struct wl_client *client, + struct wl_resource *resource, + uint32_t constraint_adjustment) +{ + MetaWaylandXdgPositioner *positioner = wl_resource_get_user_data (resource); + uint32_t all_adjustments = (XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_X | + XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_X | + XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_Y | + XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_Y | + XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_RESIZE_X | + XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_RESIZE_Y); + + if ((constraint_adjustment & ~all_adjustments) != 0) + { + wl_resource_post_error (resource, XDG_POSITIONER_ERROR_INVALID_INPUT, + "Invalid constraint action"); + return; + } + + positioner->constraint_adjustment = constraint_adjustment; +} + +static void +xdg_positioner_set_offset (struct wl_client *client, + struct wl_resource *resource, + int32_t x, + int32_t y) +{ + MetaWaylandXdgPositioner *positioner = wl_resource_get_user_data (resource); + + positioner->offset_x = x; + positioner->offset_y = y; +} + +static void +xdg_positioner_set_reactive (struct wl_client *client, + struct wl_resource *resource) +{ + MetaWaylandXdgPositioner *positioner = wl_resource_get_user_data (resource); + + positioner->is_reactive = TRUE; +} + +static void +xdg_positioner_set_parent_size (struct wl_client *client, + struct wl_resource *resource, + int32_t parent_width, + int32_t parent_height) +{ + MetaWaylandXdgPositioner *positioner = wl_resource_get_user_data (resource); + + positioner->has_parent_size = TRUE; + positioner->parent_width = parent_width; + positioner->parent_height = parent_height; +} + +static void +xdg_positioner_set_parent_configure (struct wl_client *client, + struct wl_resource *resource, + uint32_t serial) +{ + MetaWaylandXdgPositioner *positioner = wl_resource_get_user_data (resource); + + positioner->acked_parent_configure = TRUE; + positioner->parent_configure_serial = serial; +} + +static const struct xdg_positioner_interface meta_wayland_xdg_positioner_interface = { + xdg_positioner_destroy, + xdg_positioner_set_size, + xdg_positioner_set_anchor_rect, + xdg_positioner_set_anchor, + xdg_positioner_set_gravity, + xdg_positioner_set_constraint_adjustment, + xdg_positioner_set_offset, + xdg_positioner_set_reactive, + xdg_positioner_set_parent_size, + xdg_positioner_set_parent_configure, +}; + +static void +xdg_positioner_destructor (struct wl_resource *resource) +{ + MetaWaylandXdgPositioner *positioner = wl_resource_get_user_data (resource); + + g_free (positioner); +} + +static void +xdg_wm_base_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + MetaWaylandXdgShellClient *shell_client = wl_resource_get_user_data (resource); + + if (shell_client->surfaces || shell_client->surface_constructors) + wl_resource_post_error (resource, XDG_WM_BASE_ERROR_DEFUNCT_SURFACES, + "xdg_wm_base destroyed before its surfaces"); + + wl_resource_destroy (resource); +} + +static void +xdg_wm_base_create_positioner (struct wl_client *client, + struct wl_resource *resource, + uint32_t id) +{ + MetaWaylandXdgPositioner *positioner; + struct wl_resource *positioner_resource; + + positioner = g_new0 (MetaWaylandXdgPositioner, 1); + positioner_resource = wl_resource_create (client, + &xdg_positioner_interface, + wl_resource_get_version (resource), + id); + wl_resource_set_implementation (positioner_resource, + &meta_wayland_xdg_positioner_interface, + positioner, + xdg_positioner_destructor); +} + +static void +xdg_wm_base_get_xdg_surface (struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *surface_resource) +{ + MetaWaylandXdgShellClient *shell_client = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + MetaWaylandXdgSurfaceConstructor *constructor; + + if (surface->role && !META_IS_WAYLAND_XDG_SURFACE (surface->role)) + { + wl_resource_post_error (resource, XDG_WM_BASE_ERROR_ROLE, + "wl_surface@%d already has a different role", + wl_resource_get_id (surface->resource)); + return; + } + + if (surface->role && META_IS_WAYLAND_XDG_SURFACE (surface->role) && + meta_wayland_xdg_surface_is_assigned (META_WAYLAND_XDG_SURFACE (surface->role))) + { + wl_resource_post_error (surface_resource, + XDG_WM_BASE_ERROR_ROLE, + "xdg_wm_base::get_xdg_surface already requested"); + return; + } + + if (surface->buffer_ref.buffer) + { + wl_resource_post_error (resource, + XDG_WM_BASE_ERROR_INVALID_SURFACE_STATE, + "wl_surface@%d already has a buffer committed", + wl_resource_get_id (surface->resource)); + return; + } + + constructor = g_new0 (MetaWaylandXdgSurfaceConstructor, 1); + constructor->surface = surface; + constructor->shell_client = shell_client; + constructor->resource = wl_resource_create (client, + &xdg_surface_interface, + wl_resource_get_version (resource), + id); + wl_resource_set_implementation (constructor->resource, + &meta_wayland_xdg_surface_constructor_interface, + constructor, + xdg_surface_constructor_destructor); + + shell_client->surface_constructors = + g_list_append (shell_client->surface_constructors, constructor); +} + +static void +xdg_wm_base_pong (struct wl_client *client, + struct wl_resource *resource, + uint32_t serial) +{ + MetaDisplay *display = meta_get_display (); + + meta_display_pong_for_serial (display, serial); +} + +static const struct xdg_wm_base_interface meta_wayland_xdg_wm_base_interface = { + xdg_wm_base_destroy, + xdg_wm_base_create_positioner, + xdg_wm_base_get_xdg_surface, + xdg_wm_base_pong, +}; + +static void +meta_wayland_xdg_shell_client_destroy (MetaWaylandXdgShellClient *shell_client) +{ + while (shell_client->surface_constructors) + { + MetaWaylandXdgSurfaceConstructor *constructor = + g_list_first (shell_client->surface_constructors)->data; + + wl_resource_destroy (constructor->resource); + } + g_list_free (shell_client->surface_constructors); + + while (shell_client->surfaces) + { + MetaWaylandXdgSurface *xdg_surface = + g_list_first (shell_client->surfaces)->data; + + meta_wayland_xdg_surface_shell_client_destroyed (xdg_surface); + } + g_list_free (shell_client->surfaces); + + g_free (shell_client); +} + +static void +xdg_wm_base_destructor (struct wl_resource *resource) +{ + MetaWaylandXdgShellClient *shell_client = + wl_resource_get_user_data (resource); + + meta_wayland_xdg_shell_client_destroy (shell_client); +} + +static void +bind_xdg_wm_base (struct wl_client *client, + void *data, + uint32_t version, + uint32_t id) +{ + MetaWaylandXdgShellClient *shell_client; + + shell_client = g_new0 (MetaWaylandXdgShellClient, 1); + + shell_client->resource = wl_resource_create (client, + &xdg_wm_base_interface, + version, id); + wl_resource_set_implementation (shell_client->resource, + &meta_wayland_xdg_wm_base_interface, + shell_client, xdg_wm_base_destructor); +} + +void +meta_wayland_xdg_shell_init (MetaWaylandCompositor *compositor) +{ + if (wl_global_create (compositor->wayland_display, + &xdg_wm_base_interface, + META_XDG_WM_BASE_VERSION, + compositor, bind_xdg_wm_base) == NULL) + g_error ("Failed to register a global xdg-shell object"); +} diff --git a/src/wayland/meta-wayland-xdg-shell.h b/src/wayland/meta-wayland-xdg-shell.h new file mode 100644 index 000000000..f90e29bea --- /dev/null +++ b/src/wayland/meta-wayland-xdg-shell.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2013-2015 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_WAYLAND_XDG_SHELL_H +#define META_WAYLAND_XDG_SHELL_H + +#include "wayland/meta-wayland-shell-surface.h" + +#define META_TYPE_WAYLAND_XDG_SURFACE (meta_wayland_xdg_surface_get_type ()) +G_DECLARE_DERIVABLE_TYPE (MetaWaylandXdgSurface, + meta_wayland_xdg_surface, + META, WAYLAND_XDG_SURFACE, + MetaWaylandShellSurface) + +struct _MetaWaylandXdgSurfaceClass +{ + MetaWaylandShellSurfaceClass parent_class; + + void (*shell_client_destroyed) (MetaWaylandXdgSurface *xdg_surface); + void (*reset) (MetaWaylandXdgSurface *xdg_surface); +}; + +#define META_TYPE_WAYLAND_XDG_TOPLEVEL (meta_wayland_xdg_toplevel_get_type ()) +G_DECLARE_FINAL_TYPE (MetaWaylandXdgToplevel, + meta_wayland_xdg_toplevel, + META, WAYLAND_XDG_TOPLEVEL, + MetaWaylandXdgSurface); + +#define META_TYPE_WAYLAND_XDG_POPUP (meta_wayland_xdg_popup_get_type ()) +G_DECLARE_FINAL_TYPE (MetaWaylandXdgPopup, + meta_wayland_xdg_popup, + META, WAYLAND_XDG_POPUP, + MetaWaylandXdgSurface); + +void meta_wayland_xdg_shell_init (MetaWaylandCompositor *compositor); + +#endif /* META_WAYLAND_XDG_SHELL_H */ diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c new file mode 100644 index 000000000..e4b09cbfc --- /dev/null +++ b/src/wayland/meta-wayland.c @@ -0,0 +1,607 @@ +/* + * Wayland Support + * + * Copyright (C) 2012,2013 Intel Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "wayland/meta-wayland.h" + +#include <sys/time.h> +#include <string.h> +#include <stdlib.h> +#include <wayland-server.h> + +#include "clutter/clutter.h" +#include "clutter/wayland/clutter-wayland-compositor.h" +#include "core/main-private.h" +#include "wayland/meta-wayland-data-device.h" +#include "wayland/meta-wayland-dma-buf.h" +#include "wayland/meta-wayland-egl-stream.h" +#include "wayland/meta-wayland-inhibit-shortcuts-dialog.h" +#include "wayland/meta-wayland-inhibit-shortcuts.h" +#include "wayland/meta-wayland-outputs.h" +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-wayland-region.h" +#include "wayland/meta-wayland-seat.h" +#include "wayland/meta-wayland-subsurface.h" +#include "wayland/meta-wayland-tablet-manager.h" +#include "wayland/meta-wayland-xdg-foreign.h" +#include "wayland/meta-xwayland-grab-keyboard.h" +#include "wayland/meta-xwayland-private.h" +#include "wayland/meta-xwayland.h" + +static char *_display_name_override; + +G_DEFINE_TYPE (MetaWaylandCompositor, meta_wayland_compositor, G_TYPE_OBJECT) + +MetaWaylandCompositor * +meta_wayland_compositor_get_default (void) +{ + MetaBackend *backend; + MetaWaylandCompositor *wayland_compositor; + + backend = meta_get_backend (); + wayland_compositor = meta_backend_get_wayland_compositor (backend); + g_assert (wayland_compositor); + + return wayland_compositor; +} + +typedef struct +{ + GSource source; + struct wl_display *display; +} WaylandEventSource; + +static gboolean +wayland_event_source_prepare (GSource *base, + int *timeout) +{ + WaylandEventSource *source = (WaylandEventSource *)base; + + *timeout = -1; + + wl_display_flush_clients (source->display); + + return FALSE; +} + +static gboolean +wayland_event_source_dispatch (GSource *base, + GSourceFunc callback, + void *data) +{ + WaylandEventSource *source = (WaylandEventSource *)base; + struct wl_event_loop *loop = wl_display_get_event_loop (source->display); + + wl_event_loop_dispatch (loop, 0); + + return TRUE; +} + +static GSourceFuncs wayland_event_source_funcs = +{ + wayland_event_source_prepare, + NULL, + wayland_event_source_dispatch, + NULL +}; + +static GSource * +wayland_event_source_new (struct wl_display *display) +{ + WaylandEventSource *source; + struct wl_event_loop *loop = wl_display_get_event_loop (display); + + source = (WaylandEventSource *) g_source_new (&wayland_event_source_funcs, + sizeof (WaylandEventSource)); + source->display = display; + g_source_add_unix_fd (&source->source, + wl_event_loop_get_fd (loop), + G_IO_IN | G_IO_ERR); + + return &source->source; +} + +void +meta_wayland_compositor_set_input_focus (MetaWaylandCompositor *compositor, + MetaWindow *window) +{ + MetaWaylandSurface *surface = window ? window->surface : NULL; + + meta_wayland_seat_set_input_focus (compositor->seat, surface); +} + +void +meta_wayland_compositor_repick (MetaWaylandCompositor *compositor) +{ + meta_wayland_seat_repick (compositor->seat); +} + +static void +wl_compositor_create_surface (struct wl_client *client, + struct wl_resource *resource, + uint32_t id) +{ + MetaWaylandCompositor *compositor = wl_resource_get_user_data (resource); + + meta_wayland_surface_create (compositor, client, resource, id); +} + +static void +wl_compositor_create_region (struct wl_client *client, + struct wl_resource *resource, + uint32_t id) +{ + MetaWaylandCompositor *compositor = wl_resource_get_user_data (resource); + + meta_wayland_region_create (compositor, client, resource, id); +} + +static const struct wl_compositor_interface meta_wayland_wl_compositor_interface = { + wl_compositor_create_surface, + wl_compositor_create_region +}; + +static void +compositor_bind (struct wl_client *client, + void *data, + uint32_t version, + uint32_t id) +{ + MetaWaylandCompositor *compositor = data; + struct wl_resource *resource; + + resource = wl_resource_create (client, &wl_compositor_interface, version, id); + wl_resource_set_implementation (resource, + &meta_wayland_wl_compositor_interface, + compositor, NULL); +} + +/** + * meta_wayland_compositor_update: + * @compositor: the #MetaWaylandCompositor instance + * @event: the #ClutterEvent used to update @seat's state + * + * This is used to update display server state like updating cursor + * position and keeping track of buttons and keys pressed. It must be + * called for all input events coming from the underlying devices. + */ +void +meta_wayland_compositor_update (MetaWaylandCompositor *compositor, + const ClutterEvent *event) +{ + if (meta_wayland_tablet_manager_consumes_event (compositor->tablet_manager, event)) + meta_wayland_tablet_manager_update (compositor->tablet_manager, event); + else + meta_wayland_seat_update (compositor->seat, event); +} + +void +meta_wayland_compositor_paint_finished (MetaWaylandCompositor *compositor) +{ + GList *l; + int64_t now_us; + + now_us = g_get_monotonic_time (); + + l = compositor->frame_callback_surfaces; + while (l) + { + GList *l_cur = l; + MetaWaylandSurface *surface = l->data; + MetaSurfaceActor *actor; + MetaWaylandActorSurface *actor_surface; + + l = l->next; + + actor = meta_wayland_surface_get_actor (surface); + if (!actor) + continue; + + if (!clutter_actor_has_mapped_clones (CLUTTER_ACTOR (actor)) && + meta_surface_actor_is_obscured (actor)) + continue; + + actor_surface = META_WAYLAND_ACTOR_SURFACE (surface->role); + meta_wayland_actor_surface_emit_frame_callbacks (actor_surface, + now_us / 1000); + + compositor->frame_callback_surfaces = + g_list_delete_link (compositor->frame_callback_surfaces, l_cur); + } +} + +/** + * meta_wayland_compositor_handle_event: + * @compositor: the #MetaWaylandCompositor instance + * @event: the #ClutterEvent to be sent + * + * This method sends events to the focused wayland client, if any. + * + * Return value: whether @event was sent to a wayland client. + */ +gboolean +meta_wayland_compositor_handle_event (MetaWaylandCompositor *compositor, + const ClutterEvent *event) +{ + if (meta_wayland_tablet_manager_handle_event (compositor->tablet_manager, + event)) + return TRUE; + + return meta_wayland_seat_handle_event (compositor->seat, event); +} + +/* meta_wayland_compositor_update_key_state: + * @compositor: the #MetaWaylandCompositor + * @key_vector: bit vector of key states + * @key_vector_len: length of @key_vector + * @offset: the key for the first evdev keycode is found at this offset in @key_vector + * + * This function is used to resynchronize the key state that Mutter + * is tracking with the actual keyboard state. This is useful, for example, + * to handle changes in key state when a nested compositor doesn't + * have focus. We need to fix up the XKB modifier tracking and deliver + * any modifier changes to clients. + */ +void +meta_wayland_compositor_update_key_state (MetaWaylandCompositor *compositor, + char *key_vector, + int key_vector_len, + int offset) +{ + meta_wayland_keyboard_update_key_state (compositor->seat->keyboard, + key_vector, key_vector_len, offset); +} + +void +meta_wayland_compositor_add_frame_callback_surface (MetaWaylandCompositor *compositor, + MetaWaylandSurface *surface) +{ + if (g_list_find (compositor->frame_callback_surfaces, surface)) + return; + + compositor->frame_callback_surfaces = + g_list_prepend (compositor->frame_callback_surfaces, surface); +} + +void +meta_wayland_compositor_remove_frame_callback_surface (MetaWaylandCompositor *compositor, + MetaWaylandSurface *surface) +{ + compositor->frame_callback_surfaces = + g_list_remove (compositor->frame_callback_surfaces, surface); +} + +static void +set_gnome_env (const char *name, + const char *value) +{ + GDBusConnection *session_bus; + GError *error = NULL; + g_autoptr (GVariant) result = NULL; + + setenv (name, value, TRUE); + + session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + g_assert (session_bus); + + result = g_dbus_connection_call_sync (session_bus, + "org.gnome.SessionManager", + "/org/gnome/SessionManager", + "org.gnome.SessionManager", + "Setenv", + g_variant_new ("(ss)", name, value), + NULL, + G_DBUS_CALL_FLAGS_NO_AUTO_START, + -1, NULL, &error); + if (error) + { + char *remote_error; + + remote_error = g_dbus_error_get_remote_error (error); + if (g_strcmp0 (remote_error, "org.gnome.SessionManager.NotInInitialization") != 0) + meta_warning ("Failed to set environment variable %s for gnome-session: %s\n", name, error->message); + + g_free (remote_error); + g_error_free (error); + } +} + +static void meta_wayland_log_func (const char *, va_list) G_GNUC_PRINTF (1, 0); + +static void +meta_wayland_log_func (const char *fmt, + va_list arg) +{ + char *str = g_strdup_vprintf (fmt, arg); + g_warning ("WL: %s", str); + g_free (str); +} + +static void +meta_wayland_compositor_init (MetaWaylandCompositor *compositor) +{ + compositor->scheduled_surface_associations = g_hash_table_new (NULL, NULL); + + wl_log_set_handler_server (meta_wayland_log_func); + + compositor->wayland_display = wl_display_create (); + if (compositor->wayland_display == NULL) + g_error ("Failed to create the global wl_display"); + + clutter_wayland_set_compositor_display (compositor->wayland_display); +} + +static void +meta_wayland_compositor_class_init (MetaWaylandCompositorClass *klass) +{ +} + +static bool +meta_xwayland_global_filter (const struct wl_client *client, + const struct wl_global *global, + void *data) +{ + MetaWaylandCompositor *compositor = (MetaWaylandCompositor *) data; + MetaXWaylandManager *xwayland_manager = &compositor->xwayland_manager; + + /* Keyboard grabbing protocol is for Xwayland only */ + if (client != xwayland_manager->client) + return (wl_global_get_interface (global) != + &zwp_xwayland_keyboard_grab_manager_v1_interface); + + /* All others are visible to all clients */ + return true; +} + +void +meta_wayland_override_display_name (const char *display_name) +{ + g_clear_pointer (&_display_name_override, g_free); + _display_name_override = g_strdup (display_name); +} + +static const char * +meta_wayland_get_xwayland_auth_file (MetaWaylandCompositor *compositor) +{ + return compositor->xwayland_manager.auth_file; +} + +MetaWaylandCompositor * +meta_wayland_compositor_new (MetaBackend *backend) +{ + MetaWaylandCompositor *compositor; + + compositor = g_object_new (META_TYPE_WAYLAND_COMPOSITOR, NULL); + compositor->backend = backend; + + return compositor; +} + +void +meta_wayland_compositor_setup (MetaWaylandCompositor *wayland_compositor) +{ + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + GSource *wayland_event_source; + + wayland_event_source = wayland_event_source_new (compositor->wayland_display); + + /* XXX: Here we are setting the wayland event source to have a + * slightly lower priority than the X event source, because we are + * much more likely to get confused being told about surface changes + * relating to X clients when we don't know what's happened to them + * according to the X protocol. + */ + g_source_set_priority (wayland_event_source, GDK_PRIORITY_EVENTS + 1); + g_source_attach (wayland_event_source, NULL); + + if (!wl_global_create (compositor->wayland_display, + &wl_compositor_interface, + META_WL_COMPOSITOR_VERSION, + compositor, compositor_bind)) + g_error ("Failed to register the global wl_compositor"); + + wl_display_init_shm (compositor->wayland_display); + + meta_wayland_outputs_init (compositor); + meta_wayland_data_device_manager_init (compositor); + meta_wayland_data_device_primary_manager_init (compositor); + meta_wayland_data_device_primary_legacy_manager_init (compositor); + meta_wayland_subsurfaces_init (compositor); + meta_wayland_shell_init (compositor); + meta_wayland_pointer_gestures_init (compositor); + meta_wayland_tablet_manager_init (compositor); + meta_wayland_seat_init (compositor); + meta_wayland_relative_pointer_init (compositor); + meta_wayland_pointer_constraints_init (compositor); + meta_wayland_xdg_foreign_init (compositor); + meta_wayland_dma_buf_init (compositor); + meta_wayland_keyboard_shortcuts_inhibit_init (compositor); + meta_wayland_surface_inhibit_shortcuts_dialog_init (); + meta_wayland_text_input_init (compositor); + meta_wayland_gtk_text_input_init (compositor); + + /* Xwayland specific protocol, needs to be filtered out for all other clients */ + if (meta_xwayland_grab_keyboard_init (compositor)) + wl_display_set_global_filter (compositor->wayland_display, + meta_xwayland_global_filter, + compositor); + +#ifdef HAVE_WAYLAND_EGLSTREAM + meta_wayland_eglstream_controller_init (compositor); +#endif + + if (meta_get_x11_display_policy () != META_DISPLAY_POLICY_DISABLED) + { + if (!meta_xwayland_init (&compositor->xwayland_manager, compositor->wayland_display)) + g_error ("Failed to start X Wayland"); + } + + if (_display_name_override) + { + compositor->display_name = g_steal_pointer (&_display_name_override); + + if (wl_display_add_socket (compositor->wayland_display, + compositor->display_name) != 0) + g_error ("Failed to create_socket"); + } + else + { + const char *display_name; + + display_name = wl_display_add_socket_auto (compositor->wayland_display); + if (!display_name) + g_error ("Failed to create socket"); + + compositor->display_name = g_strdup (display_name); + } + + if (meta_get_x11_display_policy () != META_DISPLAY_POLICY_DISABLED) + { + set_gnome_env ("GNOME_SETUP_DISPLAY", compositor->xwayland_manager.private_connection.name); + set_gnome_env ("DISPLAY", compositor->xwayland_manager.public_connection.name); + set_gnome_env ("XAUTHORITY", meta_wayland_get_xwayland_auth_file (compositor)); + } + + set_gnome_env ("WAYLAND_DISPLAY", meta_wayland_get_wayland_display_name (compositor)); +} + +const char * +meta_wayland_get_wayland_display_name (MetaWaylandCompositor *compositor) +{ + return compositor->display_name; +} + +const char * +meta_wayland_get_xwayland_display_name (MetaWaylandCompositor *compositor) +{ + return compositor->xwayland_manager.private_connection.name; +} + +void +meta_wayland_finalize (void) +{ + MetaWaylandCompositor *compositor; + + compositor = meta_wayland_compositor_get_default (); + + meta_xwayland_shutdown (&compositor->xwayland_manager); + g_clear_pointer (&compositor->display_name, g_free); +} + +void +meta_wayland_compositor_restore_shortcuts (MetaWaylandCompositor *compositor, + ClutterInputDevice *source) +{ + MetaWaylandKeyboard *keyboard; + + /* Clutter is not multi-seat aware yet, use the default seat instead */ + keyboard = compositor->seat->keyboard; + if (!keyboard || !keyboard->focus_surface) + return; + + if (!meta_wayland_surface_is_shortcuts_inhibited (keyboard->focus_surface, + compositor->seat)) + return; + + meta_wayland_surface_restore_shortcuts (keyboard->focus_surface, + compositor->seat); +} + +gboolean +meta_wayland_compositor_is_shortcuts_inhibited (MetaWaylandCompositor *compositor, + ClutterInputDevice *source) +{ + MetaWaylandKeyboard *keyboard; + + /* Clutter is not multi-seat aware yet, use the default seat instead */ + keyboard = compositor->seat->keyboard; + if (keyboard && keyboard->focus_surface != NULL) + return meta_wayland_surface_is_shortcuts_inhibited (keyboard->focus_surface, + compositor->seat); + + return FALSE; +} + +void +meta_wayland_compositor_flush_clients (MetaWaylandCompositor *compositor) +{ + wl_display_flush_clients (compositor->wayland_display); +} + +static void on_scheduled_association_unmanaged (MetaWindow *window, + gpointer user_data); + +static void +meta_wayland_compositor_remove_surface_association (MetaWaylandCompositor *compositor, + int id) +{ + MetaWindow *window; + + window = g_hash_table_lookup (compositor->scheduled_surface_associations, + GINT_TO_POINTER (id)); + if (window) + { + g_signal_handlers_disconnect_by_func (window, + on_scheduled_association_unmanaged, + GINT_TO_POINTER (id)); + g_hash_table_remove (compositor->scheduled_surface_associations, + GINT_TO_POINTER (id)); + } +} + +static void +on_scheduled_association_unmanaged (MetaWindow *window, + gpointer user_data) +{ + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + + meta_wayland_compositor_remove_surface_association (compositor, + GPOINTER_TO_INT (user_data)); +} + +void +meta_wayland_compositor_schedule_surface_association (MetaWaylandCompositor *compositor, + int id, + MetaWindow *window) +{ + g_signal_connect (window, "unmanaged", + G_CALLBACK (on_scheduled_association_unmanaged), + GINT_TO_POINTER (id)); + g_hash_table_insert (compositor->scheduled_surface_associations, + GINT_TO_POINTER (id), window); +} + +void +meta_wayland_compositor_notify_surface_id (MetaWaylandCompositor *compositor, + int id, + MetaWaylandSurface *surface) +{ + MetaWindow *window; + + window = g_hash_table_lookup (compositor->scheduled_surface_associations, + GINT_TO_POINTER (id)); + if (window) + { + meta_xwayland_associate_window_with_surface (window, surface); + meta_wayland_compositor_remove_surface_association (compositor, id); + } +} diff --git a/src/wayland/meta-wayland.h b/src/wayland/meta-wayland.h new file mode 100644 index 000000000..3549fb2d5 --- /dev/null +++ b/src/wayland/meta-wayland.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2014 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jasper St. Pierre <jstpierre@mecheye.net> + */ + +#ifndef META_WAYLAND_H +#define META_WAYLAND_H + +#include "clutter/clutter.h" +#include "core/util-private.h" +#include "meta/types.h" +#include "wayland/meta-wayland-types.h" + +META_EXPORT_TEST +void meta_wayland_override_display_name (const char *display_name); + +void meta_wayland_pre_clutter_init (void); + +void meta_wayland_init (void); + +void meta_wayland_finalize (void); + +MetaWaylandCompositor * meta_wayland_compositor_new (MetaBackend *backend); + +void meta_wayland_compositor_setup (MetaWaylandCompositor *compositor); + +META_EXPORT_TEST +MetaWaylandCompositor *meta_wayland_compositor_get_default (void); + +void meta_wayland_compositor_update (MetaWaylandCompositor *compositor, + const ClutterEvent *event); + +gboolean meta_wayland_compositor_handle_event (MetaWaylandCompositor *compositor, + const ClutterEvent *event); + +void meta_wayland_compositor_update_key_state (MetaWaylandCompositor *compositor, + char *key_vector, + int key_vector_len, + int offset); + +void meta_wayland_compositor_repick (MetaWaylandCompositor *compositor); + +void meta_wayland_compositor_set_input_focus (MetaWaylandCompositor *compositor, + MetaWindow *window); + +void meta_wayland_compositor_paint_finished (MetaWaylandCompositor *compositor); + +void meta_wayland_compositor_add_frame_callback_surface (MetaWaylandCompositor *compositor, + MetaWaylandSurface *surface); + +void meta_wayland_compositor_remove_frame_callback_surface (MetaWaylandCompositor *compositor, + MetaWaylandSurface *surface); + +META_EXPORT_TEST +const char *meta_wayland_get_wayland_display_name (MetaWaylandCompositor *compositor); + +META_EXPORT_TEST +const char *meta_wayland_get_xwayland_display_name (MetaWaylandCompositor *compositor); + +void meta_wayland_compositor_restore_shortcuts (MetaWaylandCompositor *compositor, + ClutterInputDevice *source); + +gboolean meta_wayland_compositor_is_shortcuts_inhibited (MetaWaylandCompositor *compositor, + ClutterInputDevice *source); + +void meta_wayland_compositor_flush_clients (MetaWaylandCompositor *compositor); + +void meta_wayland_compositor_schedule_surface_association (MetaWaylandCompositor *compositor, + int id, + MetaWindow *window); + +void meta_wayland_compositor_notify_surface_id (MetaWaylandCompositor *compositor, + int id, + MetaWaylandSurface *surface); + +#endif + diff --git a/src/wayland/meta-window-wayland.c b/src/wayland/meta-window-wayland.c new file mode 100644 index 000000000..ed030b937 --- /dev/null +++ b/src/wayland/meta-window-wayland.c @@ -0,0 +1,1217 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jasper St. Pierre <jstpierre@mecheye.net> + */ + +#include "config.h" + +#include "wayland/meta-window-wayland.h" + +#include <errno.h> +#include <string.h> + +#include "backends/meta-backend-private.h" +#include "backends/meta-backend-private.h" +#include "backends/meta-logical-monitor.h" +#include "compositor/meta-surface-actor-wayland.h" +#include "compositor/meta-window-actor-private.h" +#include "core/boxes-private.h" +#include "core/stack-tracker.h" +#include "core/window-private.h" +#include "meta/meta-x11-errors.h" +#include "wayland/meta-wayland-actor-surface.h" +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-wayland-surface.h" +#include "wayland/meta-wayland-window-configuration.h" +#include "wayland/meta-wayland-xdg-shell.h" + +struct _MetaWindowWayland +{ + MetaWindow parent; + + int geometry_scale; + + GList *pending_configurations; + gboolean has_pending_state_change; + + int last_sent_x; + int last_sent_y; + int last_sent_width; + int last_sent_height; + int last_sent_rel_x; + int last_sent_rel_y; + int last_sent_geometry_scale; + MetaGravity last_sent_gravity; + + gboolean has_been_shown; +}; + +struct _MetaWindowWaylandClass +{ + MetaWindowClass parent_class; +}; + +G_DEFINE_TYPE (MetaWindowWayland, meta_window_wayland, META_TYPE_WINDOW) + +static void +set_geometry_scale_for_window (MetaWindowWayland *wl_window, + int geometry_scale) +{ + MetaWindowActor *window_actor; + + wl_window->geometry_scale = geometry_scale; + + window_actor = meta_window_actor_from_window (META_WINDOW (wl_window)); + if (window_actor) + meta_window_actor_set_geometry_scale (window_actor, geometry_scale); +} + +static int +get_window_geometry_scale_for_logical_monitor (MetaLogicalMonitor *logical_monitor) +{ + g_assert (logical_monitor); + + if (meta_is_stage_views_scaled ()) + return 1; + else + return meta_logical_monitor_get_scale (logical_monitor); +} + +static void +meta_window_wayland_manage (MetaWindow *window) +{ + MetaWindowWayland *wl_window = META_WINDOW_WAYLAND (window); + MetaDisplay *display = window->display; + + wl_window->geometry_scale = meta_window_wayland_get_geometry_scale (window); + + meta_display_register_wayland_window (display, window); + + { + meta_stack_tracker_record_add (window->display->stack_tracker, + window->stamp, + 0); + } + + meta_wayland_surface_window_managed (window->surface, window); +} + +static void +meta_window_wayland_unmanage (MetaWindow *window) +{ + { + meta_stack_tracker_record_remove (window->display->stack_tracker, + window->stamp, + 0); + } + + meta_display_unregister_wayland_window (window->display, window); +} + +static void +meta_window_wayland_ping (MetaWindow *window, + guint32 serial) +{ + meta_wayland_surface_ping (window->surface, serial); +} + +static void +meta_window_wayland_delete (MetaWindow *window, + guint32 timestamp) +{ + meta_wayland_surface_delete (window->surface); +} + +static void +meta_window_wayland_kill (MetaWindow *window) +{ + MetaWaylandSurface *surface = window->surface; + struct wl_resource *resource = surface->resource; + + /* Send the client an unrecoverable error to kill the client. */ + wl_resource_post_error (resource, + WL_DISPLAY_ERROR_NO_MEMORY, + "User requested that we kill you. Sorry. Don't take it too personally."); +} + +static void +meta_window_wayland_focus (MetaWindow *window, + guint32 timestamp) +{ + if (meta_window_is_focusable (window)) + { + meta_display_set_input_focus (window->display, + window, + FALSE, + timestamp); + } +} + +static void +meta_window_wayland_configure (MetaWindowWayland *wl_window, + MetaWaylandWindowConfiguration *configuration) +{ + MetaWindow *window = META_WINDOW (wl_window); + + meta_wayland_surface_configure_notify (window->surface, configuration); + + wl_window->pending_configurations = + g_list_prepend (wl_window->pending_configurations, configuration); +} + +static void +surface_state_changed (MetaWindow *window) +{ + MetaWindowWayland *wl_window = META_WINDOW_WAYLAND (window); + MetaWaylandWindowConfiguration *configuration; + + /* don't send notify when the window is being unmanaged */ + if (window->unmanaging) + return; + + configuration = + meta_wayland_window_configuration_new (wl_window->last_sent_x, + wl_window->last_sent_y, + wl_window->last_sent_width, + wl_window->last_sent_height, + wl_window->last_sent_geometry_scale, + META_MOVE_RESIZE_STATE_CHANGED, + wl_window->last_sent_gravity); + + meta_window_wayland_configure (wl_window, configuration); +} + +static void +meta_window_wayland_grab_op_began (MetaWindow *window, + MetaGrabOp op) +{ + if (meta_grab_op_is_resizing (op)) + surface_state_changed (window); + + META_WINDOW_CLASS (meta_window_wayland_parent_class)->grab_op_began (window, op); +} + +static void +meta_window_wayland_grab_op_ended (MetaWindow *window, + MetaGrabOp op) +{ + if (meta_grab_op_is_resizing (op)) + surface_state_changed (window); + + META_WINDOW_CLASS (meta_window_wayland_parent_class)->grab_op_ended (window, op); +} + +static void +meta_window_wayland_move_resize_internal (MetaWindow *window, + MetaGravity gravity, + MetaRectangle unconstrained_rect, + MetaRectangle constrained_rect, + MetaRectangle temporary_rect, + int rel_x, + int rel_y, + MetaMoveResizeFlags flags, + MetaMoveResizeResultFlags *result) +{ + MetaWindowWayland *wl_window = META_WINDOW_WAYLAND (window); + gboolean can_move_now = FALSE; + int configured_x; + int configured_y; + int configured_width; + int configured_height; + int geometry_scale; + int new_x; + int new_y; + int new_buffer_x; + int new_buffer_y; + + g_assert (window->frame == NULL); + + /* don't do anything if we're dropping the window, see #751847 */ + if (window->unmanaging) + return; + + configured_x = constrained_rect.x; + configured_y = constrained_rect.y; + + /* The scale the window is drawn in might change depending on what monitor it + * is mainly on. Scale the configured rectangle to be in logical pixel + * coordinate space so that we can have a scale independent size to pass + * to the Wayland surface. */ + geometry_scale = meta_window_wayland_get_geometry_scale (window); + + if (flags & META_MOVE_RESIZE_UNMAXIMIZE && + !meta_window_is_fullscreen (window)) + { + configured_width = 0; + configured_height = 0; + } + else if (flags & META_MOVE_RESIZE_UNFULLSCREEN && + !meta_window_get_maximized (window) && + meta_window_get_tile_mode (window) == META_TILE_NONE) + { + configured_width = 0; + configured_height = 0; + } + else + { + configured_width = constrained_rect.width; + configured_height = constrained_rect.height; + } + + /* For wayland clients, the size is completely determined by the client, + * and while this allows to avoid some trickery with frames and the resulting + * lagging, we also need to insist a bit when the constraints would apply + * a different size than the client decides. + * + * Note that this is not generally a problem for normal toplevel windows (the + * constraints don't see the size hints, or just change the position), but + * it can be for maximized or fullscreen. + */ + + if (flags & META_MOVE_RESIZE_FORCE_MOVE) + { + can_move_now = TRUE; + } + else if (flags & META_MOVE_RESIZE_WAYLAND_FINISH_MOVE_RESIZE) + { + /* This is a call to wl_surface_commit(), ignore the constrained_rect and + * update the real client size to match the buffer size. + */ + + if (window->rect.width != unconstrained_rect.width || + window->rect.height != unconstrained_rect.height) + { + *result |= META_MOVE_RESIZE_RESULT_RESIZED; + window->rect.width = unconstrained_rect.width; + window->rect.height = unconstrained_rect.height; + } + + /* This is a commit of an attach. We should move the window to match the + * new position the client wants. */ + can_move_now = TRUE; + if (window->placement.state == META_PLACEMENT_STATE_CONSTRAINED_CONFIGURED) + window->placement.state = META_PLACEMENT_STATE_CONSTRAINED_FINISHED; + } + else + { + if (window->placement.rule) + { + switch (window->placement.state) + { + case META_PLACEMENT_STATE_UNCONSTRAINED: + case META_PLACEMENT_STATE_CONSTRAINED_CONFIGURED: + case META_PLACEMENT_STATE_INVALIDATED: + can_move_now = FALSE; + break; + case META_PLACEMENT_STATE_CONSTRAINED_PENDING: + { + if (flags & META_MOVE_RESIZE_PLACEMENT_CHANGED || + rel_x != wl_window->last_sent_rel_x || + rel_y != wl_window->last_sent_rel_y || + constrained_rect.width != window->rect.width || + constrained_rect.height != window->rect.height) + { + MetaWaylandWindowConfiguration *configuration; + + configuration = + meta_wayland_window_configuration_new_relative (rel_x, + rel_y, + configured_width, + configured_height, + geometry_scale); + meta_window_wayland_configure (wl_window, configuration); + + wl_window->last_sent_rel_x = rel_x; + wl_window->last_sent_rel_y = rel_y; + + window->placement.state = META_PLACEMENT_STATE_CONSTRAINED_CONFIGURED; + + can_move_now = FALSE; + } + else + { + window->placement.state = + META_PLACEMENT_STATE_CONSTRAINED_FINISHED; + + can_move_now = TRUE; + } + break; + } + case META_PLACEMENT_STATE_CONSTRAINED_FINISHED: + can_move_now = TRUE; + break; + } + } + else if (constrained_rect.width != window->rect.width || + constrained_rect.height != window->rect.height || + flags & META_MOVE_RESIZE_STATE_CHANGED) + { + MetaWaylandWindowConfiguration *configuration; + + /* If the constrained size is 1x1 and the unconstrained size is 0x0 + * it means that we are trying to resize a window where the client has + * not yet committed a buffer. The 1x1 constrained size is a result of + * how the constraints code works. Lets avoid trying to have the + * client configure itself to draw on a 1x1 surface. + * + * We cannot guard against only an empty unconstrained_rect here, + * because the client may have created a xdg surface without a buffer + * attached and asked it to be maximized. In such case we should let + * it know about the expected window geometry of a maximized window, + * even though there is currently no buffer attached. */ + if (unconstrained_rect.width == 0 && + unconstrained_rect.height == 0 && + constrained_rect.width == 1 && + constrained_rect.height == 1) + return; + + configuration = + meta_wayland_window_configuration_new (configured_x, + configured_y, + configured_width, + configured_height, + geometry_scale, + flags, + gravity); + meta_window_wayland_configure (wl_window, configuration); + can_move_now = FALSE; + } + else + { + can_move_now = TRUE; + } + } + + wl_window->last_sent_x = configured_x; + wl_window->last_sent_y = configured_y; + wl_window->last_sent_width = configured_width; + wl_window->last_sent_height = configured_height; + wl_window->last_sent_geometry_scale = geometry_scale; + wl_window->last_sent_gravity = gravity; + + if (can_move_now) + { + new_x = constrained_rect.x; + new_y = constrained_rect.y; + } + else + { + new_x = temporary_rect.x; + new_y = temporary_rect.y; + + wl_window->has_pending_state_change |= + !!(flags & META_MOVE_RESIZE_STATE_CHANGED); + } + + if (new_x != window->rect.x || new_y != window->rect.y) + { + *result |= META_MOVE_RESIZE_RESULT_MOVED; + window->rect.x = new_x; + window->rect.y = new_y; + } + + if (window->placement.rule && + window->placement.state == META_PLACEMENT_STATE_CONSTRAINED_FINISHED) + { + window->placement.current.rel_x = rel_x; + window->placement.current.rel_y = rel_y; + } + + new_buffer_x = new_x - window->custom_frame_extents.left; + new_buffer_y = new_y - window->custom_frame_extents.top; + + if (new_buffer_x != window->buffer_rect.x || + new_buffer_y != window->buffer_rect.y) + { + *result |= META_MOVE_RESIZE_RESULT_MOVED; + window->buffer_rect.x = new_buffer_x; + window->buffer_rect.y = new_buffer_y; + } + + if (can_move_now && + flags & META_MOVE_RESIZE_WAYLAND_STATE_CHANGED) + *result |= META_MOVE_RESIZE_RESULT_STATE_CHANGED; +} + +static void +scale_size (int *width, + int *height, + float scale) +{ + if (*width < G_MAXINT) + { + float new_width = (*width * scale); + *width = (int) MIN (new_width, G_MAXINT); + } + + if (*height < G_MAXINT) + { + float new_height = (*height * scale); + *height = (int) MIN (new_height, G_MAXINT); + } +} + +static void +scale_rect_size (MetaRectangle *rect, + float scale) +{ + scale_size (&rect->width, &rect->height, scale); +} + +static void +meta_window_wayland_update_main_monitor (MetaWindow *window, + MetaWindowUpdateMonitorFlags flags) +{ + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaWindow *toplevel_window; + MetaLogicalMonitor *from; + MetaLogicalMonitor *to; + MetaLogicalMonitor *scaled_new; + float from_scale, to_scale; + float scale; + MetaRectangle rect; + + from = window->monitor; + + /* If the window is not a toplevel window (i.e. it's a popup window) just use + * the monitor of the toplevel. */ + toplevel_window = meta_wayland_surface_get_toplevel_window (window->surface); + if (toplevel_window != window) + { + meta_window_update_monitor (toplevel_window, flags); + window->monitor = toplevel_window->monitor; + return; + } + + /* Require both the current and the new monitor would be the new main monitor, + * even given the resulting scale the window would end up having. This is + * needed to avoid jumping back and forth between the new and the old, since + * changing main monitor may cause the window to be resized so that it no + * longer have that same new main monitor. */ + to = meta_window_calculate_main_logical_monitor (window); + + if (from == to) + return; + + if (from == NULL || to == NULL) + { + window->monitor = to; + return; + } + + if (flags & META_WINDOW_UPDATE_MONITOR_FLAGS_FORCE) + { + window->monitor = to; + return; + } + + from_scale = meta_logical_monitor_get_scale (from); + to_scale = meta_logical_monitor_get_scale (to); + + if (from_scale == to_scale) + { + window->monitor = to; + return; + } + + if (meta_is_stage_views_scaled ()) + { + window->monitor = to; + return; + } + + /* To avoid a window alternating between two main monitors because scaling + * changes the main monitor, wait until both the current and the new scale + * will result in the same main monitor. */ + scale = to_scale / from_scale; + rect = window->rect; + scale_rect_size (&rect, scale); + scaled_new = + meta_monitor_manager_get_logical_monitor_from_rect (monitor_manager, &rect); + if (to != scaled_new) + return; + + window->monitor = to; +} + +static void +meta_window_wayland_main_monitor_changed (MetaWindow *window, + const MetaLogicalMonitor *old) +{ + MetaWindowWayland *wl_window = META_WINDOW_WAYLAND (window); + int old_geometry_scale = wl_window->geometry_scale; + int geometry_scale; + float scale_factor; + MetaWaylandSurface *surface; + + if (!window->monitor) + return; + + geometry_scale = meta_window_wayland_get_geometry_scale (window); + + /* This function makes sure that window geometry, window actor geometry and + * surface actor geometry gets set according the old and current main monitor + * scale. If there either is no past or current main monitor, or if the scale + * didn't change, there is nothing to do. */ + if (old == NULL || + window->monitor == NULL || + old_geometry_scale == geometry_scale) + return; + + /* MetaWindow keeps its rectangles in the physical pixel coordinate space. + * When the main monitor of a window changes, it can cause the corresponding + * window surfaces to be scaled given the monitor scale, so we need to scale + * the rectangles in MetaWindow accordingly. */ + + scale_factor = (float) geometry_scale / old_geometry_scale; + + /* Window size. */ + scale_rect_size (&window->rect, scale_factor); + scale_rect_size (&window->unconstrained_rect, scale_factor); + scale_rect_size (&window->saved_rect, scale_factor); + scale_size (&window->size_hints.min_width, &window->size_hints.min_height, scale_factor); + scale_size (&window->size_hints.max_width, &window->size_hints.max_height, scale_factor); + + /* Window geometry offset (XXX: Need a better place, see + * meta_window_wayland_finish_move_resize). */ + window->custom_frame_extents.left = + (int)(scale_factor * window->custom_frame_extents.left); + window->custom_frame_extents.top = + (int)(scale_factor * window->custom_frame_extents.top); + + /* Buffer rect. */ + scale_rect_size (&window->buffer_rect, scale_factor); + window->buffer_rect.x = + window->rect.x - window->custom_frame_extents.left; + window->buffer_rect.y = + window->rect.y - window->custom_frame_extents.top; + + meta_compositor_sync_window_geometry (window->display->compositor, + window, + TRUE); + + surface = window->surface; + if (surface) + { + MetaWaylandActorSurface *actor_surface = + META_WAYLAND_ACTOR_SURFACE (surface->role); + + meta_wayland_actor_surface_sync_actor_state (actor_surface); + } + + set_geometry_scale_for_window (wl_window, geometry_scale); + meta_window_emit_size_changed (window); +} + +static uint32_t +meta_window_wayland_get_client_pid (MetaWindow *window) +{ + MetaWaylandSurface *surface = window->surface; + struct wl_resource *resource = surface->resource; + pid_t pid; + + wl_client_get_credentials (wl_resource_get_client (resource), &pid, NULL, NULL); + return (uint32_t)pid; +} + +static void +appears_focused_changed (GObject *object, + GParamSpec *pspec, + gpointer user_data) +{ + MetaWindow *window = META_WINDOW (object); + + if (window->placement.rule) + return; + + surface_state_changed (window); +} + +static void +on_window_shown (MetaWindow *window) +{ + MetaWindowWayland *wl_window = META_WINDOW_WAYLAND (window); + gboolean has_been_shown; + + has_been_shown = wl_window->has_been_shown; + wl_window->has_been_shown = TRUE; + + if (!has_been_shown) + meta_compositor_sync_updates_frozen (window->display->compositor, window); +} + +static void +meta_window_wayland_init (MetaWindowWayland *wl_window) +{ + MetaWindow *window = META_WINDOW (wl_window); + + wl_window->geometry_scale = 1; + + g_signal_connect (window, "notify::appears-focused", + G_CALLBACK (appears_focused_changed), NULL); + g_signal_connect (window, "shown", + G_CALLBACK (on_window_shown), NULL); +} + +static void +meta_window_wayland_force_restore_shortcuts (MetaWindow *window, + ClutterInputDevice *source) +{ + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + + meta_wayland_compositor_restore_shortcuts (compositor, source); +} + +static gboolean +meta_window_wayland_shortcuts_inhibited (MetaWindow *window, + ClutterInputDevice *source) +{ + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + + return meta_wayland_compositor_is_shortcuts_inhibited (compositor, source); +} + +static gboolean +meta_window_wayland_is_focusable (MetaWindow *window) +{ + return window->input; +} + +static gboolean +meta_window_wayland_can_ping (MetaWindow *window) +{ + return TRUE; +} + +static gboolean +meta_window_wayland_is_stackable (MetaWindow *window) +{ + return meta_wayland_surface_get_buffer (window->surface) != NULL; +} + +static gboolean +meta_window_wayland_are_updates_frozen (MetaWindow *window) +{ + MetaWindowWayland *wl_window = META_WINDOW_WAYLAND (window); + + return !wl_window->has_been_shown; +} + +static gboolean +meta_window_wayland_is_focus_async (MetaWindow *window) +{ + return FALSE; +} + +static MetaStackLayer +meta_window_wayland_calculate_layer (MetaWindow *window) +{ + return meta_window_get_default_layer (window); +} + +static void +meta_window_wayland_map (MetaWindow *window) +{ +} + +static void +meta_window_wayland_unmap (MetaWindow *window) +{ +} + +static void +meta_window_wayland_finalize (GObject *object) +{ + MetaWindowWayland *wl_window = META_WINDOW_WAYLAND (object); + + g_list_free_full (wl_window->pending_configurations, + (GDestroyNotify) meta_wayland_window_configuration_free); + + G_OBJECT_CLASS (meta_window_wayland_parent_class)->finalize (object); +} + +static void +meta_window_wayland_class_init (MetaWindowWaylandClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MetaWindowClass *window_class = META_WINDOW_CLASS (klass); + + object_class->finalize = meta_window_wayland_finalize; + + window_class->manage = meta_window_wayland_manage; + window_class->unmanage = meta_window_wayland_unmanage; + window_class->ping = meta_window_wayland_ping; + window_class->delete = meta_window_wayland_delete; + window_class->kill = meta_window_wayland_kill; + window_class->focus = meta_window_wayland_focus; + window_class->grab_op_began = meta_window_wayland_grab_op_began; + window_class->grab_op_ended = meta_window_wayland_grab_op_ended; + window_class->move_resize_internal = meta_window_wayland_move_resize_internal; + window_class->update_main_monitor = meta_window_wayland_update_main_monitor; + window_class->main_monitor_changed = meta_window_wayland_main_monitor_changed; + window_class->get_client_pid = meta_window_wayland_get_client_pid; + window_class->force_restore_shortcuts = meta_window_wayland_force_restore_shortcuts; + window_class->shortcuts_inhibited = meta_window_wayland_shortcuts_inhibited; + window_class->is_focusable = meta_window_wayland_is_focusable; + window_class->is_stackable = meta_window_wayland_is_stackable; + window_class->can_ping = meta_window_wayland_can_ping; + window_class->are_updates_frozen = meta_window_wayland_are_updates_frozen; + window_class->calculate_layer = meta_window_wayland_calculate_layer; + window_class->map = meta_window_wayland_map; + window_class->unmap = meta_window_wayland_unmap; + window_class->is_focus_async = meta_window_wayland_is_focus_async; +} + +MetaWindow * +meta_window_wayland_new (MetaDisplay *display, + MetaWaylandSurface *surface) +{ + XWindowAttributes attrs = { 0 }; + MetaWindowWayland *wl_window; + MetaWindow *window; + + /* + * Set attributes used by _meta_window_shared_new, don't bother trying to fake + * X11 window attributes with the rest, since they'll be ignored anyway. + */ + attrs.x = 0; + attrs.y = 0; + attrs.width = 0; + attrs.height = 0; + attrs.depth = 24; + attrs.visual = NULL; + attrs.map_state = IsUnmapped; + attrs.override_redirect = False; + + window = _meta_window_shared_new (display, + META_WINDOW_CLIENT_TYPE_WAYLAND, + surface, + None, + WithdrawnState, + META_COMP_EFFECT_CREATE, + &attrs); + + wl_window = META_WINDOW_WAYLAND (window); + set_geometry_scale_for_window (wl_window, wl_window->geometry_scale); + + return window; +} + +MetaWaylandWindowConfiguration * +meta_window_wayland_peek_configuration (MetaWindowWayland *wl_window, + uint32_t serial) +{ + GList *l; + + for (l = wl_window->pending_configurations; l; l = l->next) + { + MetaWaylandWindowConfiguration *configuration = l->data; + + if (configuration->serial == serial) + return configuration; + } + + return NULL; +} + +static MetaWaylandWindowConfiguration * +acquire_acked_configuration (MetaWindowWayland *wl_window, + MetaWaylandSurfaceState *pending) +{ + GList *l; + + if (!pending->has_acked_configure_serial) + return NULL; + + for (l = wl_window->pending_configurations; l; l = l->next) + { + MetaWaylandWindowConfiguration *configuration = l->data; + GList *tail; + gboolean is_matching_configuration; + + if (configuration->serial > pending->acked_configure_serial) + continue; + + tail = l; + + if (tail->prev) + { + tail->prev->next = NULL; + tail->prev = NULL; + } + else + { + wl_window->pending_configurations = NULL; + } + + is_matching_configuration = + configuration->serial == pending->acked_configure_serial; + + if (is_matching_configuration) + tail = g_list_delete_link (tail, l); + g_list_free_full (tail, + (GDestroyNotify) meta_wayland_window_configuration_free); + + if (is_matching_configuration) + return configuration; + else + return NULL; + } + + return NULL; +} + +int +meta_window_wayland_get_geometry_scale (MetaWindow *window) +{ + if (!window->monitor) + return 1; + + return get_window_geometry_scale_for_logical_monitor (window->monitor); +} + +static void +calculate_offset (MetaWaylandWindowConfiguration *configuration, + MetaRectangle *geometry, + MetaRectangle *rect) +{ + int offset_x; + int offset_y; + + rect->x = configuration->x; + rect->y = configuration->y; + + offset_x = configuration->width - geometry->width; + offset_y = configuration->height - geometry->height; + switch (configuration->gravity) + { + case META_GRAVITY_SOUTH: + case META_GRAVITY_SOUTH_WEST: + rect->y += offset_y; + break; + case META_GRAVITY_EAST: + case META_GRAVITY_NORTH_EAST: + rect->x += offset_x; + break; + case META_GRAVITY_SOUTH_EAST: + rect->x += offset_x; + rect->y += offset_y; + break; + default: + break; + } +} + +/** + * meta_window_move_resize_wayland: + * + * Complete a resize operation from a wayland client. + */ +void +meta_window_wayland_finish_move_resize (MetaWindow *window, + MetaRectangle new_geom, + MetaWaylandSurfaceState *pending) +{ + MetaWindowWayland *wl_window = META_WINDOW_WAYLAND (window); + MetaDisplay *display = window->display; + int dx, dy; + int geometry_scale; + MetaGravity gravity; + MetaRectangle rect; + MetaMoveResizeFlags flags; + MetaWaylandWindowConfiguration *acked_configuration; + gboolean is_window_being_resized; + + /* new_geom is in the logical pixel coordinate space, but MetaWindow wants its + * rects to represent what in turn will end up on the stage, i.e. we need to + * scale new_geom to physical pixels given what buffer scale and texture scale + * is in use. */ + + geometry_scale = meta_window_wayland_get_geometry_scale (window); + new_geom.x *= geometry_scale; + new_geom.y *= geometry_scale; + new_geom.width *= geometry_scale; + new_geom.height *= geometry_scale; + + /* The (dx, dy) offset is also in logical pixel coordinate space and needs + * to be scaled in the same way as new_geom. */ + dx = pending->dx * geometry_scale; + dy = pending->dy * geometry_scale; + + /* XXX: Find a better place to store the window geometry offsets. */ + window->custom_frame_extents.left = new_geom.x; + window->custom_frame_extents.top = new_geom.y; + + flags = META_MOVE_RESIZE_WAYLAND_FINISH_MOVE_RESIZE; + + acked_configuration = acquire_acked_configuration (wl_window, pending); + + /* x/y are ignored when we're doing interactive resizing */ + is_window_being_resized = (meta_grab_op_is_resizing (display->grab_op) && + display->grab_window == window); + + if (!is_window_being_resized) + { + if (acked_configuration) + { + if (window->placement.rule) + { + MetaWindow *parent; + + parent = meta_window_get_transient_for (window); + rect.x = parent->rect.x + acked_configuration->rel_x; + rect.y = parent->rect.y + acked_configuration->rel_y; + } + else + { + calculate_offset (acked_configuration, &new_geom, &rect); + } + } + else + { + rect.x = window->rect.x; + rect.y = window->rect.y; + } + + rect.x += dx; + rect.y += dy; + } + else + { + if (acked_configuration) + calculate_offset (acked_configuration, &new_geom, &rect); + } + + if (rect.x != window->rect.x || rect.y != window->rect.y) + flags |= META_MOVE_RESIZE_MOVE_ACTION; + + if (wl_window->has_pending_state_change && acked_configuration) + { + flags |= META_MOVE_RESIZE_WAYLAND_STATE_CHANGED; + wl_window->has_pending_state_change = FALSE; + } + + rect.width = new_geom.width; + rect.height = new_geom.height; + + if (rect.width != window->rect.width || rect.height != window->rect.height) + flags |= META_MOVE_RESIZE_RESIZE_ACTION; + + if (window->display->grab_window == window) + gravity = meta_resize_gravity_from_grab_op (window->display->grab_op); + else + gravity = META_GRAVITY_STATIC; + meta_window_move_resize_internal (window, flags, gravity, rect); + + g_clear_pointer (&acked_configuration, meta_wayland_window_configuration_free); +} + +void +meta_window_wayland_place_relative_to (MetaWindow *window, + MetaWindow *other, + int x, + int y) +{ + int geometry_scale; + + /* If there is no monitor, we can't position the window reliably. */ + if (!other->monitor) + return; + + geometry_scale = meta_window_wayland_get_geometry_scale (other); + meta_window_move_frame (window, FALSE, + other->buffer_rect.x + (x * geometry_scale), + other->buffer_rect.y + (y * geometry_scale)); + window->placed = TRUE; +} + +void +meta_window_place_with_placement_rule (MetaWindow *window, + MetaPlacementRule *placement_rule) +{ + gboolean first_placement; + + first_placement = !window->placement.rule; + + g_clear_pointer (&window->placement.rule, g_free); + window->placement.rule = g_new0 (MetaPlacementRule, 1); + *window->placement.rule = *placement_rule; + + window->unconstrained_rect.x = window->rect.x; + window->unconstrained_rect.y = window->rect.y; + window->unconstrained_rect.width = placement_rule->width; + window->unconstrained_rect.height = placement_rule->height; + + window->calc_placement = first_placement; + meta_window_move_resize_internal (window, + (META_MOVE_RESIZE_MOVE_ACTION | + META_MOVE_RESIZE_RESIZE_ACTION | + META_MOVE_RESIZE_PLACEMENT_CHANGED), + META_GRAVITY_NORTH_WEST, + window->unconstrained_rect); + window->calc_placement = FALSE; +} + +void +meta_window_update_placement_rule (MetaWindow *window, + MetaPlacementRule *placement_rule) +{ + window->placement.state = META_PLACEMENT_STATE_INVALIDATED; + meta_window_place_with_placement_rule (window, placement_rule); +} + +void +meta_window_wayland_set_min_size (MetaWindow *window, + int width, + int height) +{ + gint64 new_width, new_height; + float scale; + + meta_topic (META_DEBUG_GEOMETRY, "Window %s sets min size %d x %d\n", + window->desc, width, height); + + if (width == 0 && height == 0) + { + window->size_hints.min_width = 0; + window->size_hints.min_height = 0; + window->size_hints.flags &= ~PMinSize; + + return; + } + + scale = (float) meta_window_wayland_get_geometry_scale (window); + scale_size (&width, &height, scale); + + new_width = width + (window->custom_frame_extents.left + + window->custom_frame_extents.right); + new_height = height + (window->custom_frame_extents.top + + window->custom_frame_extents.bottom); + + window->size_hints.min_width = (int) MIN (new_width, G_MAXINT); + window->size_hints.min_height = (int) MIN (new_height, G_MAXINT); + window->size_hints.flags |= PMinSize; +} + +void +meta_window_wayland_set_max_size (MetaWindow *window, + int width, + int height) + +{ + gint64 new_width, new_height; + float scale; + + meta_topic (META_DEBUG_GEOMETRY, "Window %s sets max size %d x %d\n", + window->desc, width, height); + + if (width == 0 && height == 0) + { + window->size_hints.max_width = G_MAXINT; + window->size_hints.max_height = G_MAXINT; + window->size_hints.flags &= ~PMaxSize; + + return; + } + + scale = (float) meta_window_wayland_get_geometry_scale (window); + scale_size (&width, &height, scale); + + new_width = width + (window->custom_frame_extents.left + + window->custom_frame_extents.right); + new_height = height + (window->custom_frame_extents.top + + window->custom_frame_extents.bottom); + + window->size_hints.max_width = (int) ((new_width > 0 && new_width < G_MAXINT) ? + new_width : G_MAXINT); + window->size_hints.max_height = (int) ((new_height > 0 && new_height < G_MAXINT) ? + new_height : G_MAXINT); + window->size_hints.flags |= PMaxSize; +} + +void +meta_window_wayland_get_min_size (MetaWindow *window, + int *width, + int *height) +{ + gint64 current_width, current_height; + float scale; + + if (!(window->size_hints.flags & PMinSize)) + { + /* Zero means unlimited */ + *width = 0; + *height = 0; + + return; + } + + current_width = window->size_hints.min_width - + (window->custom_frame_extents.left + + window->custom_frame_extents.right); + current_height = window->size_hints.min_height - + (window->custom_frame_extents.top + + window->custom_frame_extents.bottom); + + *width = MAX (current_width, 0); + *height = MAX (current_height, 0); + + scale = 1.0 / (float) meta_window_wayland_get_geometry_scale (window); + scale_size (width, height, scale); +} + +void +meta_window_wayland_get_max_size (MetaWindow *window, + int *width, + int *height) +{ + gint64 current_width = 0; + gint64 current_height = 0; + float scale; + + if (!(window->size_hints.flags & PMaxSize)) + { + /* Zero means unlimited */ + *width = 0; + *height = 0; + + return; + } + + if (window->size_hints.max_width < G_MAXINT) + current_width = window->size_hints.max_width - + (window->custom_frame_extents.left + + window->custom_frame_extents.right); + + if (window->size_hints.max_height < G_MAXINT) + current_height = window->size_hints.max_height - + (window->custom_frame_extents.top + + window->custom_frame_extents.bottom); + + *width = CLAMP (current_width, 0, G_MAXINT); + *height = CLAMP (current_height, 0, G_MAXINT); + + scale = 1.0 / (float) meta_window_wayland_get_geometry_scale (window); + scale_size (width, height, scale); +} diff --git a/src/wayland/meta-window-wayland.h b/src/wayland/meta-window-wayland.h new file mode 100644 index 000000000..db152daaa --- /dev/null +++ b/src/wayland/meta-window-wayland.h @@ -0,0 +1,80 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jasper St. Pierre <jstpierre@mecheye.net> + */ + +#ifndef META_WINDOW_WAYLAND_H +#define META_WINDOW_WAYLAND_H + +#include "core/window-private.h" +#include "meta/window.h" +#include "wayland/meta-wayland-types.h" + +G_BEGIN_DECLS + +#define META_TYPE_WINDOW_WAYLAND (meta_window_wayland_get_type()) +G_DECLARE_FINAL_TYPE (MetaWindowWayland, meta_window_wayland, + META, WINDOW_WAYLAND, + MetaWindow) + +MetaWindow * meta_window_wayland_new (MetaDisplay *display, + MetaWaylandSurface *surface); + +void meta_window_wayland_finish_move_resize (MetaWindow *window, + MetaRectangle new_geom, + MetaWaylandSurfaceState *pending); + +int meta_window_wayland_get_geometry_scale (MetaWindow *window); + +void meta_window_wayland_place_relative_to (MetaWindow *window, + MetaWindow *other, + int x, + int y); + +void meta_window_place_with_placement_rule (MetaWindow *window, + MetaPlacementRule *placement_rule); + +void meta_window_update_placement_rule (MetaWindow *window, + MetaPlacementRule *placement_rule); + +MetaWaylandWindowConfiguration * + meta_window_wayland_peek_configuration (MetaWindowWayland *wl_window, + uint32_t serial); + +void meta_window_wayland_set_min_size (MetaWindow *window, + int width, + int height); + +void meta_window_wayland_set_max_size (MetaWindow *window, + int width, + int height); + +void meta_window_wayland_get_min_size (MetaWindow *window, + int *width, + int *height); + + +void meta_window_wayland_get_max_size (MetaWindow *window, + int *width, + int *height); + +#endif diff --git a/src/wayland/meta-window-xwayland.c b/src/wayland/meta-window-xwayland.c new file mode 100644 index 000000000..0c77ca5d7 --- /dev/null +++ b/src/wayland/meta-window-xwayland.c @@ -0,0 +1,301 @@ +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + */ + +#include "config.h" + +#include "core/frame.h" +#include "meta/meta-x11-errors.h" +#include "x11/window-x11.h" +#include "x11/window-x11-private.h" +#include "x11/xprops.h" +#include "wayland/meta-window-xwayland.h" +#include "wayland/meta-wayland.h" + +enum +{ + PROP_0, + + PROP_XWAYLAND_MAY_GRAB_KEYBOARD, + + PROP_LAST +}; + +static GParamSpec *obj_props[PROP_LAST]; + +struct _MetaWindowXwayland +{ + MetaWindowX11 parent; + + gboolean xwayland_may_grab_keyboard; + int freeze_count; +}; + +struct _MetaWindowXwaylandClass +{ + MetaWindowX11Class parent_class; +}; + +G_DEFINE_TYPE (MetaWindowXwayland, meta_window_xwayland, META_TYPE_WINDOW_X11) + +static void +meta_window_xwayland_init (MetaWindowXwayland *window_xwayland) +{ +} + +/** + * meta_window_xwayland_adjust_fullscreen_monitor_rect: + * + * This function implements a workaround for X11 apps which use randr to change the + * the monitor resolution, followed by setting _NET_WM_FULLSCREEN to make the + * window-manager fullscreen them. + * + * Newer versions of Xwayland support the randr part of this by supporting randr + * resolution change emulation in combination with using WPviewport to scale the + * app's window (at the emulated resolution) to fill the entire monitor. + * + * Apps using randr in combination with NET_WM_STATE_FULLSCREEN expect the + * fullscreen window to have the size of the emulated randr resolution since + * when running on regular Xorg the resolution will actually be changed and + * after that going fullscreen through NET_WM_STATE_FULLSCREEN will size + * the window to be equal to the new resolution. + * + * We need to emulate this behavior for these apps to work correctly. + * + * Xwayland's emulated resolution is a per X11 client setting and Xwayland + * will set a special _XWAYLAND_RANDR_EMU_MONITOR_RECTS property on the + * toplevel windows of a client (and only those of that client), which has + * changed the (emulated) resolution through a randr call. + * + * Here we check for that property and if it is set we adjust the fullscreen + * monitor rect for this window to match the emulated resolution. + * + * Here is a step-by-step of such an app going fullscreen: + * 1. App changes monitor resolution with randr. + * 2. Xwayland sets the _XWAYLAND_RANDR_EMU_MONITOR_RECTS property on all the + * apps current and future windows. This property contains the origin of the + * monitor for which the emulated resolution is set and the emulated + * resolution. + * 3. App sets _NET_WM_FULLSCREEN. + * 4. We check the property and adjust the app's fullscreen size to match + * the emulated resolution. + * 5. Xwayland sees a Window at monitor origin fully covering the emulated + * monitor resolution. Xwayland sets a viewport making the emulated + * resolution sized window cover the full actual monitor resolution. + */ +static void +meta_window_xwayland_adjust_fullscreen_monitor_rect (MetaWindow *window, + MetaRectangle *fs_monitor_rect) +{ + MetaX11Display *x11_display = window->display->x11_display; + MetaRectangle win_monitor_rect; + cairo_rectangle_int_t *rects; + uint32_t *list = NULL; + int i, n_items = 0; + + if (!window->monitor) + { + g_warning ("MetaWindow does not have a monitor"); + return; + } + + win_monitor_rect = meta_logical_monitor_get_layout (window->monitor); + + if (!meta_prop_get_cardinal_list (x11_display, + window->xwindow, + x11_display->atom__XWAYLAND_RANDR_EMU_MONITOR_RECTS, + &list, &n_items)) + return; + + if (n_items % 4) + { + meta_verbose ("_XWAYLAND_RANDR_EMU_MONITOR_RECTS on %s has %d values which is not a multiple of 4", + window->desc, n_items); + g_free (list); + return; + } + + rects = (cairo_rectangle_int_t *) list; + n_items = n_items / 4; + for (i = 0; i < n_items; i++) + { + if (rects[i].x == win_monitor_rect.x && rects[i].y == win_monitor_rect.y) + { + fs_monitor_rect->width = rects[i].width; + fs_monitor_rect->height = rects[i].height; + break; + } + } + + g_free (list); +} + +static void +meta_window_xwayland_force_restore_shortcuts (MetaWindow *window, + ClutterInputDevice *source) +{ + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + + meta_wayland_compositor_restore_shortcuts (compositor, source); +} + +static gboolean +meta_window_xwayland_shortcuts_inhibited (MetaWindow *window, + ClutterInputDevice *source) +{ + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + + return meta_wayland_compositor_is_shortcuts_inhibited (compositor, source); +} + +static void +apply_allow_commits_x11_property (MetaWindowXwayland *xwayland_window, + gboolean allow_commits) +{ + MetaWindow *window = META_WINDOW (xwayland_window); + MetaDisplay *display = window->display; + MetaX11Display *x11_display = display->x11_display; + Display *xdisplay = x11_display->xdisplay; + MetaFrame *frame; + Window xwin; + guint32 property[1]; + + frame = meta_window_get_frame (window); + if (!frame) + xwin = window->xwindow; + else + xwin = meta_frame_get_xwindow (frame); + + if (!xwin) + return; + + property[0] = !!allow_commits; + + meta_x11_error_trap_push (x11_display); + XChangeProperty (xdisplay, xwin, + x11_display->atom__XWAYLAND_ALLOW_COMMITS, + XA_CARDINAL, 32, PropModeReplace, + (guchar*) &property, 1); + meta_x11_error_trap_pop (x11_display); + XFlush (xdisplay); +} + +static void +meta_window_xwayland_freeze_commits (MetaWindow *window) +{ + MetaWindowXwayland *xwayland_window = META_WINDOW_XWAYLAND (window); + + if (xwayland_window->freeze_count == 0) + apply_allow_commits_x11_property (xwayland_window, FALSE); + + xwayland_window->freeze_count++; +} + +static void +meta_window_xwayland_thaw_commits (MetaWindow *window) +{ + MetaWindowXwayland *xwayland_window = META_WINDOW_XWAYLAND (window); + + g_return_if_fail (xwayland_window->freeze_count > 0); + + xwayland_window->freeze_count--; + if (xwayland_window->freeze_count > 0) + return; + + apply_allow_commits_x11_property (xwayland_window, TRUE); +} + +static gboolean +meta_window_xwayland_always_update_shape (MetaWindow *window) +{ + /* + * On Xwayland, resizing a window will clear the corresponding Wayland + * buffer to plain solid black. + * + * Therefore, to address the black shadows which sometimes show during + * resize with Xwayland, we need to always update the window shape + * regardless of the actual frozen state of the window actor. + */ + + return TRUE; +} + +static void +meta_window_xwayland_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaWindowXwayland *window = META_WINDOW_XWAYLAND (object); + + switch (prop_id) + { + case PROP_XWAYLAND_MAY_GRAB_KEYBOARD: + g_value_set_boolean (value, window->xwayland_may_grab_keyboard); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_window_xwayland_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaWindowXwayland *window = META_WINDOW_XWAYLAND (object); + + switch (prop_id) + { + case PROP_XWAYLAND_MAY_GRAB_KEYBOARD: + window->xwayland_may_grab_keyboard = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_window_xwayland_class_init (MetaWindowXwaylandClass *klass) +{ + MetaWindowClass *window_class = META_WINDOW_CLASS (klass); + MetaWindowX11Class *window_x11_class = META_WINDOW_X11_CLASS (klass); + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + window_class->adjust_fullscreen_monitor_rect = meta_window_xwayland_adjust_fullscreen_monitor_rect; + window_class->force_restore_shortcuts = meta_window_xwayland_force_restore_shortcuts; + window_class->shortcuts_inhibited = meta_window_xwayland_shortcuts_inhibited; + + window_x11_class->freeze_commits = meta_window_xwayland_freeze_commits; + window_x11_class->thaw_commits = meta_window_xwayland_thaw_commits; + window_x11_class->always_update_shape = meta_window_xwayland_always_update_shape; + + gobject_class->get_property = meta_window_xwayland_get_property; + gobject_class->set_property = meta_window_xwayland_set_property; + + obj_props[PROP_XWAYLAND_MAY_GRAB_KEYBOARD] = + g_param_spec_boolean ("xwayland-may-grab-keyboard", + "Xwayland may use keyboard grabs", + "Whether the client may use Xwayland keyboard grabs on this window", + FALSE, + G_PARAM_READWRITE); + + g_object_class_install_properties (gobject_class, PROP_LAST, obj_props); +} diff --git a/src/wayland/meta-window-xwayland.h b/src/wayland/meta-window-xwayland.h new file mode 100644 index 000000000..5ea6041d4 --- /dev/null +++ b/src/wayland/meta-window-xwayland.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + */ + +#ifndef META_WINDOW_XWAYLAND_H +#define META_WINDOW_XWAYLAND_H + +#include "meta/window.h" +#include "x11/window-x11.h" +#include "x11/window-x11-private.h" + +G_BEGIN_DECLS + +#define META_TYPE_WINDOW_XWAYLAND (meta_window_xwayland_get_type()) +G_DECLARE_FINAL_TYPE (MetaWindowXwayland, meta_window_xwayland, + META, WINDOW_XWAYLAND, MetaWindowX11) + +G_END_DECLS + +#endif diff --git a/src/wayland/meta-xwayland-dnd-private.h b/src/wayland/meta-xwayland-dnd-private.h new file mode 100644 index 000000000..b55b4f8d3 --- /dev/null +++ b/src/wayland/meta-xwayland-dnd-private.h @@ -0,0 +1,34 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2015 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl <jadahl@gmail.com> + */ + +#ifndef META_XWAYLAND_SELECTION_PRIVATE_H +#define META_XWAYLAND_SELECTION_PRIVATE_H + +#define META_TYPE_WAYLAND_DATA_SOURCE_XWAYLAND (meta_wayland_data_source_xwayland_get_type ()) +G_DECLARE_FINAL_TYPE (MetaWaylandDataSourceXWayland, + meta_wayland_data_source_xwayland, + META, WAYLAND_DATA_SOURCE_XWAYLAND, + MetaWaylandDataSource); + +#endif /* META_XWAYLAND_SELECTION_PRIVATE_H */ diff --git a/src/wayland/meta-xwayland-dnd.c b/src/wayland/meta-xwayland-dnd.c new file mode 100644 index 000000000..eb667fde5 --- /dev/null +++ b/src/wayland/meta-xwayland-dnd.c @@ -0,0 +1,990 @@ +/* + * Copyright © 2012 Intel Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holders not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. The copyright holders make + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* The file is loosely based on xwayland/selection.c from Weston */ + +#include "config.h" + +#include <fcntl.h> +#include <unistd.h> +#include <string.h> +#include <glib-unix.h> +#include <gio/gunixoutputstream.h> +#include <gio/gunixinputstream.h> +#include <gdk/gdkx.h> +#include <X11/Xatom.h> +#include <X11/extensions/Xfixes.h> + +#include "meta/meta-x11-errors.h" +#include "wayland/meta-wayland-data-device.h" +#include "wayland/meta-xwayland-private.h" +#include "wayland/meta-xwayland-dnd-private.h" +#include "wayland/meta-xwayland.h" +#include "x11/meta-x11-display-private.h" + +#define INCR_CHUNK_SIZE (128 * 1024) +#define XDND_VERSION 5 + +struct _MetaWaylandDataSourceXWayland +{ + MetaWaylandDataSource parent; + MetaXWaylandDnd *dnd; + gboolean has_utf8_string_atom; +}; + +struct _MetaXWaylandDnd +{ + Window owner; + Time client_message_timestamp; + MetaWaylandDataSource *source; /* owned by MetaWaylandDataDevice */ + MetaWaylandSurface *focus_surface; + Window dnd_window; /* Mutter-internal window, acts as peer on wayland drop sites */ + Window dnd_dest; /* X11 drag dest window */ + guint32 last_motion_time; +}; + +enum +{ + ATOM_DND_SELECTION, + ATOM_DND_AWARE, + ATOM_DND_STATUS, + ATOM_DND_POSITION, + ATOM_DND_ENTER, + ATOM_DND_LEAVE, + ATOM_DND_DROP, + ATOM_DND_FINISHED, + ATOM_DND_PROXY, + ATOM_DND_TYPE_LIST, + ATOM_DND_ACTION_MOVE, + ATOM_DND_ACTION_COPY, + ATOM_DND_ACTION_ASK, + ATOM_DND_ACTION_PRIVATE, + N_DND_ATOMS +}; + +/* Matches order in enum above */ +const gchar *atom_names[] = { + "XdndSelection", + "XdndAware", + "XdndStatus", + "XdndPosition", + "XdndEnter", + "XdndLeave", + "XdndDrop", + "XdndFinished", + "XdndProxy", + "XdndTypeList", + "XdndActionMove", + "XdndActionCopy", + "XdndActionAsk", + "XdndActionPrivate", + NULL +}; + +Atom xdnd_atoms[N_DND_ATOMS]; + +G_DEFINE_TYPE (MetaWaylandDataSourceXWayland, meta_wayland_data_source_xwayland, + META_TYPE_WAYLAND_DATA_SOURCE); + +/* XDND helpers */ +static Atom +action_to_atom (uint32_t action) +{ + if (action & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY) + return xdnd_atoms[ATOM_DND_ACTION_COPY]; + else if (action & WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE) + return xdnd_atoms[ATOM_DND_ACTION_MOVE]; + else if (action & WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK) + return xdnd_atoms[ATOM_DND_ACTION_ASK]; + else + return None; +} + +static enum wl_data_device_manager_dnd_action +atom_to_action (Atom atom) +{ + if (atom == xdnd_atoms[ATOM_DND_ACTION_COPY] || + atom == xdnd_atoms[ATOM_DND_ACTION_PRIVATE]) + return WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY; + else if (atom == xdnd_atoms[ATOM_DND_ACTION_MOVE]) + return WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE; + else if (atom == xdnd_atoms[ATOM_DND_ACTION_ASK]) + return WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK; + else + return WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE; +} + +static void +xdnd_send_enter (MetaXWaylandDnd *dnd, + Window dest) +{ + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + MetaX11Display *x11_display = meta_get_display ()->x11_display; + Display *xdisplay = x11_display->xdisplay; + MetaWaylandDataSource *data_source; + XEvent xev = { 0 }; + gchar **p; + struct wl_array *source_mime_types; + + meta_x11_error_trap_push (x11_display); + + data_source = compositor->seat->data_device.dnd_data_source; + xev.xclient.type = ClientMessage; + xev.xclient.message_type = xdnd_atoms[ATOM_DND_ENTER]; + xev.xclient.format = 32; + xev.xclient.window = dest; + + xev.xclient.data.l[0] = x11_display->selection.xwindow; + xev.xclient.data.l[1] = XDND_VERSION << 24; /* version */ + xev.xclient.data.l[2] = xev.xclient.data.l[3] = xev.xclient.data.l[4] = 0; + + source_mime_types = meta_wayland_data_source_get_mime_types (data_source); + if (source_mime_types->size <= 3) + { + /* The mimetype atoms fit in this same message */ + gint i = 2; + + wl_array_for_each (p, source_mime_types) + { + xev.xclient.data.l[i++] = gdk_x11_get_xatom_by_name (*p); + } + } + else + { + /* We have more than 3 mimetypes, we must set up + * the mimetype list as a XdndTypeList property. + */ + g_autofree Atom *atomlist = NULL; + gint i = 0; + + xev.xclient.data.l[1] |= 1; + atomlist = g_new0 (Atom, source_mime_types->size); + + wl_array_for_each (p, source_mime_types) + { + atomlist[i++] = gdk_x11_get_xatom_by_name (*p); + } + + XChangeProperty (xdisplay, x11_display->selection.xwindow, + xdnd_atoms[ATOM_DND_TYPE_LIST], + XA_ATOM, 32, PropModeReplace, + (guchar *) atomlist, i); + } + + XSendEvent (xdisplay, dest, False, NoEventMask, &xev); + + if (meta_x11_error_trap_pop_with_return (x11_display) != Success) + g_critical ("Error sending XdndEnter"); +} + +static void +xdnd_send_leave (MetaXWaylandDnd *dnd, + Window dest) +{ + MetaX11Display *x11_display = meta_get_display ()->x11_display; + Display *xdisplay = x11_display->xdisplay; + XEvent xev = { 0 }; + + xev.xclient.type = ClientMessage; + xev.xclient.message_type = xdnd_atoms[ATOM_DND_LEAVE]; + xev.xclient.format = 32; + xev.xclient.window = dest; + xev.xclient.data.l[0] = x11_display->selection.xwindow; + + meta_x11_error_trap_push (x11_display); + XSendEvent (xdisplay, dest, False, NoEventMask, &xev); + meta_x11_error_trap_pop (x11_display); +} + +static void +xdnd_send_position (MetaXWaylandDnd *dnd, + Window dest, + uint32_t time, + int x, + int y) +{ + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + MetaWaylandDataSource *source = compositor->seat->data_device.dnd_data_source; + MetaX11Display *x11_display = meta_get_display ()->x11_display; + Display *xdisplay = x11_display->xdisplay; + uint32_t action = 0, user_action, actions; + XEvent xev = { 0 }; + + user_action = meta_wayland_data_source_get_user_action (source); + meta_wayland_data_source_get_actions (source, &actions); + + if (user_action & actions) + action = user_action; + if (!action) + action = actions; + + xev.xclient.type = ClientMessage; + xev.xclient.message_type = xdnd_atoms[ATOM_DND_POSITION]; + xev.xclient.format = 32; + xev.xclient.window = dest; + + xev.xclient.data.l[0] = x11_display->selection.xwindow; + xev.xclient.data.l[1] = 0; + xev.xclient.data.l[2] = (x << 16) | y; + xev.xclient.data.l[3] = time; + xev.xclient.data.l[4] = action_to_atom (action); + + meta_x11_error_trap_push (x11_display); + XSendEvent (xdisplay, dest, False, NoEventMask, &xev); + + if (meta_x11_error_trap_pop_with_return (x11_display) != Success) + g_critical ("Error sending XdndPosition"); +} + +static void +xdnd_send_drop (MetaXWaylandDnd *dnd, + Window dest, + uint32_t time) +{ + MetaX11Display *x11_display = meta_get_display ()->x11_display; + Display *xdisplay = x11_display->xdisplay; + XEvent xev = { 0 }; + + xev.xclient.type = ClientMessage; + xev.xclient.message_type = xdnd_atoms[ATOM_DND_DROP]; + xev.xclient.format = 32; + xev.xclient.window = dest; + + xev.xclient.data.l[0] = x11_display->selection.xwindow; + xev.xclient.data.l[2] = time; + + meta_x11_error_trap_push (x11_display); + XSendEvent (xdisplay, dest, False, NoEventMask, &xev); + + if (meta_x11_error_trap_pop_with_return (x11_display) != Success) + g_critical ("Error sending XdndDrop"); +} + +static void +xdnd_send_finished (MetaXWaylandDnd *dnd, + Window dest, + gboolean accepted) +{ + MetaX11Display *x11_display = meta_get_display ()->x11_display; + Display *xdisplay = x11_display->xdisplay; + MetaWaylandDataSource *source = dnd->source; + uint32_t action = 0; + XEvent xev = { 0 }; + + xev.xclient.type = ClientMessage; + xev.xclient.message_type = xdnd_atoms[ATOM_DND_FINISHED]; + xev.xclient.format = 32; + xev.xclient.window = dest; + + xev.xclient.data.l[0] = dnd->dnd_window; + + if (accepted) + { + action = meta_wayland_data_source_get_current_action (source); + xev.xclient.data.l[1] = 1; /* Drop successful */ + xev.xclient.data.l[2] = action_to_atom (action); + } + + meta_x11_error_trap_push (x11_display); + XSendEvent (xdisplay, dest, False, NoEventMask, &xev); + + if (meta_x11_error_trap_pop_with_return (x11_display) != Success) + g_critical ("Error sending XdndFinished"); +} + +static void +xdnd_send_status (MetaXWaylandDnd *dnd, + Window dest, + uint32_t action) +{ + MetaX11Display *x11_display = meta_get_display ()->x11_display; + Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); + XEvent xev = { 0 }; + + xev.xclient.type = ClientMessage; + xev.xclient.message_type = xdnd_atoms[ATOM_DND_STATUS]; + xev.xclient.format = 32; + xev.xclient.window = dest; + + xev.xclient.data.l[0] = dnd->dnd_window; + xev.xclient.data.l[1] = 1 << 1; /* Bit 2: dest wants XdndPosition messages */ + xev.xclient.data.l[4] = action_to_atom (action); + + if (xev.xclient.data.l[4]) + xev.xclient.data.l[1] |= 1 << 0; /* Bit 1: dest accepts the drop */ + + meta_x11_error_trap_push (x11_display); + XSendEvent (xdisplay, dest, False, NoEventMask, &xev); + + if (meta_x11_error_trap_pop_with_return (x11_display) != Success) + g_critical ("Error sending Xdndstatus"); +} + +static void +meta_xwayland_end_dnd_grab (MetaWaylandDataDevice *data_device, + gboolean success) +{ + Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + MetaXWaylandManager *manager = &compositor->xwayland_manager; + MetaWaylandDragGrab *drag_grab = compositor->seat->data_device.current_grab; + MetaXWaylandDnd *dnd = manager->dnd; + + if (drag_grab) + { + if (!success && dnd->source) + meta_wayland_data_source_set_current_offer (dnd->source, NULL); + + meta_wayland_data_device_end_drag (data_device); + } + + XMoveResizeWindow (xdisplay, dnd->dnd_window, -1, -1, 1, 1); + XUnmapWindow (xdisplay, dnd->dnd_window); +} + +static void +transfer_cb (MetaSelection *selection, + GAsyncResult *res, + GOutputStream *stream) +{ + GError *error = NULL; + + if (!meta_selection_transfer_finish (selection, res, &error)) + { + g_warning ("Could not transfer DnD selection: %s\n", error->message); + g_error_free (error); + } + + g_output_stream_close (stream, NULL, NULL); + g_object_unref (stream); +} + +static void +meta_x11_source_send (MetaWaylandDataSource *source, + const gchar *mime_type, + gint fd) +{ + MetaDisplay *display = meta_get_display (); + GOutputStream *stream; + + stream = g_unix_output_stream_new (fd, TRUE); + meta_selection_transfer_async (meta_display_get_selection (display), + META_SELECTION_DND, + mime_type, + -1, + stream, + NULL, + (GAsyncReadyCallback) transfer_cb, + stream); +} + +static void +meta_x11_source_target (MetaWaylandDataSource *source, + const gchar *mime_type) +{ + MetaWaylandDataSourceXWayland *source_xwayland = + META_WAYLAND_DATA_SOURCE_XWAYLAND (source); + MetaXWaylandDnd *dnd = source_xwayland->dnd; + uint32_t action = 0; + + if (mime_type) + action = meta_wayland_data_source_get_current_action (source); + + xdnd_send_status (dnd, dnd->owner, action); +} + +static void +meta_x11_source_cancel (MetaWaylandDataSource *source) +{ + MetaWaylandDataSourceXWayland *source_xwayland = + META_WAYLAND_DATA_SOURCE_XWAYLAND (source); + MetaXWaylandDnd *dnd = source_xwayland->dnd; + + xdnd_send_finished (dnd, dnd->owner, FALSE); +} + +static void +meta_x11_source_action (MetaWaylandDataSource *source, + uint32_t action) +{ + MetaWaylandDataSourceXWayland *source_xwayland = + META_WAYLAND_DATA_SOURCE_XWAYLAND (source); + MetaXWaylandDnd *dnd = source_xwayland->dnd; + + if (!meta_wayland_data_source_has_target (source)) + action = 0; + + xdnd_send_status (dnd, dnd->owner, action); +} + +static void +meta_x11_source_drop_performed (MetaWaylandDataSource *source) +{ +} + +static void +meta_x11_source_drag_finished (MetaWaylandDataSource *source) +{ + MetaWaylandDataSourceXWayland *source_xwayland = + META_WAYLAND_DATA_SOURCE_XWAYLAND (source); + MetaXWaylandDnd *dnd = source_xwayland->dnd; + MetaX11Display *x11_display = meta_get_display ()->x11_display; + uint32_t action = meta_wayland_data_source_get_current_action (source); + + if (action == WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE) + { + Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); + + /* Request data deletion on the drag source */ + XConvertSelection (xdisplay, + xdnd_atoms[ATOM_DND_SELECTION], + gdk_x11_get_xatom_by_name ("DELETE"), + gdk_x11_get_xatom_by_name ("_META_SELECTION"), + x11_display->selection.xwindow, + META_CURRENT_TIME); + } + + xdnd_send_finished (dnd, dnd->owner, TRUE); +} + +static void +meta_wayland_data_source_xwayland_init (MetaWaylandDataSourceXWayland *source_xwayland) +{ +} + +static void +meta_wayland_data_source_xwayland_class_init (MetaWaylandDataSourceXWaylandClass *klass) +{ + MetaWaylandDataSourceClass *data_source_class = + META_WAYLAND_DATA_SOURCE_CLASS (klass); + + data_source_class->send = meta_x11_source_send; + data_source_class->target = meta_x11_source_target; + data_source_class->cancel = meta_x11_source_cancel; + data_source_class->action = meta_x11_source_action; + data_source_class->drop_performed = meta_x11_source_drop_performed; + data_source_class->drag_finished = meta_x11_source_drag_finished; +} + +static MetaWaylandDataSource * +meta_wayland_data_source_xwayland_new (MetaXWaylandDnd *dnd) +{ + MetaWaylandDataSourceXWayland *source_xwayland; + + source_xwayland = g_object_new (META_TYPE_WAYLAND_DATA_SOURCE_XWAYLAND, NULL); + source_xwayland->dnd = dnd; + + return META_WAYLAND_DATA_SOURCE (source_xwayland); +} + +static void +meta_x11_drag_dest_focus_in (MetaWaylandDataDevice *data_device, + MetaWaylandSurface *surface, + MetaWaylandDataOffer *offer) +{ + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + MetaXWaylandDnd *dnd = compositor->xwayland_manager.dnd; + + dnd->dnd_dest = meta_wayland_surface_get_window (surface)->xwindow; + xdnd_send_enter (dnd, dnd->dnd_dest); +} + +static void +meta_x11_drag_dest_focus_out (MetaWaylandDataDevice *data_device, + MetaWaylandSurface *surface) +{ + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + MetaXWaylandDnd *dnd = compositor->xwayland_manager.dnd; + + xdnd_send_leave (dnd, dnd->dnd_dest); + dnd->dnd_dest = None; +} + +static void +meta_x11_drag_dest_motion (MetaWaylandDataDevice *data_device, + MetaWaylandSurface *surface, + const ClutterEvent *event) +{ + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + MetaXWaylandDnd *dnd = compositor->xwayland_manager.dnd; + guint32 time; + gfloat x, y; + + time = clutter_event_get_time (event); + clutter_event_get_coords (event, &x, &y); + xdnd_send_position (dnd, dnd->dnd_dest, time, x, y); +} + +static void +meta_x11_drag_dest_drop (MetaWaylandDataDevice *data_device, + MetaWaylandSurface *surface) +{ + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + MetaXWaylandDnd *dnd = compositor->xwayland_manager.dnd; + + xdnd_send_drop (dnd, dnd->dnd_dest, + meta_display_get_current_time_roundtrip (meta_get_display ())); +} + +static void +meta_x11_drag_dest_update (MetaWaylandDataDevice *data_device, + MetaWaylandSurface *surface) +{ + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + MetaXWaylandDnd *dnd = compositor->xwayland_manager.dnd; + MetaWaylandSeat *seat = compositor->seat; + graphene_point_t pos; + + clutter_input_device_get_coords (seat->pointer->device, NULL, &pos); + xdnd_send_position (dnd, dnd->dnd_dest, + clutter_get_current_event_time (), + pos.x, pos.y); +} + +static const MetaWaylandDragDestFuncs meta_x11_drag_dest_funcs = { + meta_x11_drag_dest_focus_in, + meta_x11_drag_dest_focus_out, + meta_x11_drag_dest_motion, + meta_x11_drag_dest_drop, + meta_x11_drag_dest_update +}; + +const MetaWaylandDragDestFuncs * +meta_xwayland_selection_get_drag_dest_funcs (void) +{ + return &meta_x11_drag_dest_funcs; +} + +static gboolean +meta_xwayland_data_source_fetch_mimetype_list (MetaWaylandDataSource *source, + Window window, + Atom prop) +{ + MetaWaylandDataSourceXWayland *source_xwayland = + META_WAYLAND_DATA_SOURCE_XWAYLAND (source); + Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); + gulong nitems_ret, bytes_after_ret, i; + Atom *atoms, type_ret, utf8_string; + int format_ret; + struct wl_array *source_mime_types; + + source_mime_types = meta_wayland_data_source_get_mime_types (source); + if (source_mime_types->size != 0) + return TRUE; + + utf8_string = gdk_x11_get_xatom_by_name ("UTF8_STRING"); + XGetWindowProperty (xdisplay, window, prop, + 0, /* offset */ + 0x1fffffff, /* length */ + False, /* delete */ + AnyPropertyType, + &type_ret, + &format_ret, + &nitems_ret, + &bytes_after_ret, + (guchar **) &atoms); + + if (nitems_ret == 0 || type_ret != XA_ATOM) + { + XFree (atoms); + return FALSE; + } + + for (i = 0; i < nitems_ret; i++) + { + const gchar *mime_type; + + if (atoms[i] == utf8_string) + { + meta_wayland_data_source_add_mime_type (source, + "text/plain;charset=utf-8"); + source_xwayland->has_utf8_string_atom = TRUE; + } + + mime_type = gdk_x11_get_xatom_name (atoms[i]); + meta_wayland_data_source_add_mime_type (source, mime_type); + } + + XFree (atoms); + + return TRUE; +} + +static MetaWaylandSurface * +pick_drop_surface (MetaWaylandCompositor *compositor, + const ClutterEvent *event) +{ + MetaDisplay *display = meta_get_display (); + MetaWindow *focus_window = NULL; + graphene_point_t pos; + + clutter_event_get_coords (event, &pos.x, &pos.y); + focus_window = meta_stack_get_default_focus_window_at_point (display->stack, + NULL, NULL, + pos.x, pos.y); + return focus_window ? focus_window->surface : NULL; +} + +static void +repick_drop_surface (MetaWaylandCompositor *compositor, + MetaWaylandDragGrab *drag_grab, + const ClutterEvent *event) +{ + Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); + MetaXWaylandDnd *dnd = compositor->xwayland_manager.dnd; + MetaWaylandSurface *focus = NULL; + MetaWindow *focus_window; + + focus = pick_drop_surface (compositor, event); + if (dnd->focus_surface == focus) + return; + + dnd->focus_surface = focus; + + if (focus) + focus_window = meta_wayland_surface_get_window (focus); + else + focus_window = NULL; + + if (focus_window && + focus_window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) + { + XMapRaised (xdisplay, dnd->dnd_window); + XMoveResizeWindow (xdisplay, dnd->dnd_window, + focus_window->rect.x, + focus_window->rect.y, + focus_window->rect.width, + focus_window->rect.height); + } + else + { + XMoveResizeWindow (xdisplay, dnd->dnd_window, -1, -1, 1, 1); + XUnmapWindow (xdisplay, dnd->dnd_window); + } +} + +static void +drag_xgrab_focus (MetaWaylandPointerGrab *grab, + MetaWaylandSurface *surface) +{ + /* Do not update the focus here. First, the surface may perfectly + * be the X11 source DnD icon window's, so we can only be fooled + * here. Second, delaying focus handling to XdndEnter/Leave + * makes us do the negotiation orderly on the X11 side. + */ +} + +static void +drag_xgrab_motion (MetaWaylandPointerGrab *grab, + const ClutterEvent *event) +{ + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + MetaXWaylandDnd *dnd = compositor->xwayland_manager.dnd; + MetaWaylandSeat *seat = compositor->seat; + + repick_drop_surface (compositor, + (MetaWaylandDragGrab *) grab, + event); + + dnd->last_motion_time = clutter_event_get_time (event); + meta_wayland_pointer_send_motion (seat->pointer, event); +} + +static void +drag_xgrab_button (MetaWaylandPointerGrab *grab, + const ClutterEvent *event) +{ + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + MetaWaylandSeat *seat = compositor->seat; + MetaWaylandDataSource *data_source; + + meta_wayland_pointer_send_button (seat->pointer, event); + data_source = compositor->seat->data_device.dnd_data_source; + + if (seat->pointer->button_count == 0 && + (!meta_wayland_drag_grab_get_focus ((MetaWaylandDragGrab *) grab) || + meta_wayland_data_source_get_current_action (data_source) == + WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE)) + meta_xwayland_end_dnd_grab (&seat->data_device, FALSE); +} + +static const MetaWaylandPointerGrabInterface drag_xgrab_interface = { + drag_xgrab_focus, + drag_xgrab_motion, + drag_xgrab_button, +}; + +static gboolean +meta_xwayland_dnd_handle_client_message (MetaWaylandCompositor *compositor, + XEvent *xevent) +{ + XClientMessageEvent *event = (XClientMessageEvent *) xevent; + MetaXWaylandDnd *dnd = compositor->xwayland_manager.dnd; + MetaWaylandSeat *seat = compositor->seat; + MetaX11Display *x11_display = meta_get_display ()->x11_display; + + /* Source side messages */ + if (event->window == x11_display->selection.xwindow) + { + MetaWaylandDataSource *data_source; + uint32_t action = 0; + + data_source = compositor->seat->data_device.dnd_data_source; + + if (!data_source) + return FALSE; + + if (event->message_type == xdnd_atoms[ATOM_DND_STATUS]) + { + /* The first bit in data.l[1] is set if the drag was accepted */ + meta_wayland_data_source_set_has_target (data_source, + (event->data.l[1] & 1) != 0); + + /* data.l[4] contains the action atom */ + if (event->data.l[4]) + action = atom_to_action ((Atom) event->data.l[4]); + + meta_wayland_data_source_set_current_action (data_source, action); + return TRUE; + } + else if (event->message_type == xdnd_atoms[ATOM_DND_FINISHED]) + { + /* Reject messages mid-grab */ + if (compositor->seat->data_device.current_grab) + return FALSE; + + meta_wayland_data_source_notify_finish (data_source); + return TRUE; + } + } + /* Dest side messages */ + else if (dnd->source && + compositor->seat->data_device.current_grab && + (Window) event->data.l[0] == dnd->owner) + { + MetaWaylandDragGrab *drag_grab = compositor->seat->data_device.current_grab; + MetaWaylandSurface *drag_focus = meta_wayland_drag_grab_get_focus (drag_grab); + + if (!drag_focus && + event->message_type != xdnd_atoms[ATOM_DND_ENTER]) + return FALSE; + + if (event->message_type == xdnd_atoms[ATOM_DND_ENTER]) + { + /* Bit 1 in data.l[1] determines whether there's 3 or less mimetype + * atoms (and are thus contained in this same message), or whether + * there's more than 3 and we need to check the XdndTypeList property + * for the full list. + */ + if (!(event->data.l[1] & 1)) + { + /* Mimetypes are contained in this message */ + const gchar *mimetype; + gint i; + struct wl_array *source_mime_types; + + /* We only need to fetch once */ + source_mime_types = + meta_wayland_data_source_get_mime_types (dnd->source); + if (source_mime_types->size == 0) + { + for (i = 2; i <= 4; i++) + { + if (event->data.l[i] == None) + break; + + mimetype = gdk_x11_get_xatom_name (event->data.l[i]); + meta_wayland_data_source_add_mime_type (dnd->source, + mimetype); + } + } + } + else + { + /* Fetch mimetypes from type list */ + meta_xwayland_data_source_fetch_mimetype_list (dnd->source, + event->data.l[0], + xdnd_atoms[ATOM_DND_TYPE_LIST]); + } + + meta_wayland_data_source_set_actions (dnd->source, + WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY | + WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE | + WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK); + meta_wayland_drag_grab_set_focus (drag_grab, dnd->focus_surface); + return TRUE; + } + else if (event->message_type == xdnd_atoms[ATOM_DND_POSITION]) + { + ClutterEvent *motion; + graphene_point_t pos; + uint32_t action = 0; + + dnd->client_message_timestamp = event->data.l[3]; + + motion = clutter_event_new (CLUTTER_MOTION); + clutter_input_device_get_coords (seat->pointer->device, NULL, &pos); + clutter_event_set_coords (motion, pos.x, pos.y); + clutter_event_set_device (motion, seat->pointer->device); + clutter_event_set_source_device (motion, seat->pointer->device); + clutter_event_set_time (motion, dnd->last_motion_time); + + action = atom_to_action ((Atom) event->data.l[4]); + meta_wayland_data_source_set_user_action (dnd->source, action); + + meta_wayland_surface_drag_dest_motion (drag_focus, motion); + xdnd_send_status (dnd, (Window) event->data.l[0], + meta_wayland_data_source_get_current_action (dnd->source)); + + clutter_event_free (motion); + return TRUE; + } + else if (event->message_type == xdnd_atoms[ATOM_DND_LEAVE]) + { + meta_wayland_drag_grab_set_focus (drag_grab, NULL); + return TRUE; + } + else if (event->message_type == xdnd_atoms[ATOM_DND_DROP]) + { + dnd->client_message_timestamp = event->data.l[2]; + meta_wayland_surface_drag_dest_drop (drag_focus); + meta_xwayland_end_dnd_grab (&seat->data_device, TRUE); + return TRUE; + } + } + + return FALSE; +} + +static gboolean +meta_xwayland_dnd_handle_xfixes_selection_notify (MetaWaylandCompositor *compositor, + XEvent *xevent) +{ + XFixesSelectionNotifyEvent *event = (XFixesSelectionNotifyEvent *) xevent; + MetaXWaylandDnd *dnd = compositor->xwayland_manager.dnd; + MetaWaylandDataDevice *data_device = &compositor->seat->data_device; + MetaX11Display *x11_display = meta_get_display ()->x11_display; + MetaWaylandSurface *focus; + + if (event->selection != xdnd_atoms[ATOM_DND_SELECTION]) + return FALSE; + + dnd->owner = event->owner; + focus = compositor->seat->pointer->focus_surface; + + if (event->owner != None && event->owner != x11_display->selection.xwindow && + focus && meta_xwayland_is_xwayland_surface (focus)) + { + dnd->source = meta_wayland_data_source_xwayland_new (dnd); + meta_wayland_data_device_set_dnd_source (&compositor->seat->data_device, + dnd->source); + + meta_wayland_data_device_start_drag (data_device, + wl_resource_get_client (focus->resource), + &drag_xgrab_interface, + focus, dnd->source, + NULL); + } + else if (event->owner == None) + { + meta_xwayland_end_dnd_grab (data_device, FALSE); + g_clear_object (&dnd->source); + } + + return FALSE; +} + +gboolean +meta_xwayland_dnd_handle_event (XEvent *xevent) +{ + MetaWaylandCompositor *compositor; + + compositor = meta_wayland_compositor_get_default (); + + if (!compositor->xwayland_manager.dnd) + return FALSE; + + switch (xevent->type) + { + case ClientMessage: + return meta_xwayland_dnd_handle_client_message (compositor, xevent); + default: + { + MetaX11Display *x11_display = meta_get_display ()->x11_display; + + if (xevent->type - x11_display->xfixes_event_base == XFixesSelectionNotify) + return meta_xwayland_dnd_handle_xfixes_selection_notify (compositor, xevent); + + return FALSE; + } + } +} + +void +meta_xwayland_init_dnd (Display *xdisplay) +{ + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + MetaXWaylandManager *manager = &compositor->xwayland_manager; + MetaXWaylandDnd *dnd = manager->dnd; + XSetWindowAttributes attributes; + guint32 i, version = XDND_VERSION; + + g_assert (manager->dnd == NULL); + + manager->dnd = dnd = g_slice_new0 (MetaXWaylandDnd); + + for (i = 0; i < N_DND_ATOMS; i++) + xdnd_atoms[i] = gdk_x11_get_xatom_by_name (atom_names[i]); + + attributes.event_mask = PropertyChangeMask | SubstructureNotifyMask; + attributes.override_redirect = True; + + dnd->dnd_window = XCreateWindow (xdisplay, + gdk_x11_window_get_xid (gdk_get_default_root_window ()), + -1, -1, 1, 1, + 0, /* border width */ + 0, /* depth */ + InputOnly, /* class */ + CopyFromParent, /* visual */ + CWEventMask | CWOverrideRedirect, + &attributes); + XChangeProperty (xdisplay, dnd->dnd_window, + xdnd_atoms[ATOM_DND_AWARE], + XA_ATOM, 32, PropModeReplace, + (guchar*) &version, 1); +} + +void +meta_xwayland_shutdown_dnd (Display *xdisplay) +{ + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + MetaXWaylandManager *manager = &compositor->xwayland_manager; + MetaXWaylandDnd *dnd = manager->dnd; + + g_assert (dnd != NULL); + + XDestroyWindow (xdisplay, dnd->dnd_window); + dnd->dnd_window = None; + + g_slice_free (MetaXWaylandDnd, dnd); + manager->dnd = NULL; +} diff --git a/src/wayland/meta-xwayland-grab-keyboard.c b/src/wayland/meta-xwayland-grab-keyboard.c new file mode 100644 index 000000000..c9eeca8d0 --- /dev/null +++ b/src/wayland/meta-xwayland-grab-keyboard.c @@ -0,0 +1,334 @@ +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Olivier Fourdan <ofourdan@redhat.com> + */ + +#include "config.h" + +#include <wayland-server.h> + +#include "meta/meta-backend.h" +#include "backends/meta-settings-private.h" +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-wayland-versions.h" +#include "wayland/meta-wayland-seat.h" +#include "wayland/meta-window-wayland.h" +#include "wayland/meta-xwayland-grab-keyboard.h" + +struct _MetaXwaylandKeyboardActiveGrab +{ + MetaWaylandSurface *surface; + MetaWaylandSeat *seat; + MetaWaylandKeyboardGrab keyboard_grab; + gulong surface_destroyed_handler; + gulong shortcuts_restored_handler; + gulong window_associate_handler; + struct wl_resource *resource; +}; + +static gboolean +meta_xwayland_keyboard_grab_key (MetaWaylandKeyboardGrab *grab, + const ClutterEvent *event) +{ + MetaXwaylandKeyboardActiveGrab *active_grab; + MetaWaylandKeyboard *keyboard; + + active_grab = wl_container_of (grab, active_grab, keyboard_grab); + keyboard = active_grab->keyboard_grab.keyboard; + + /* Force focus onto the surface who has the active grab on the keyboard */ + if (active_grab->surface != NULL && keyboard->focus_surface != active_grab->surface) + meta_wayland_keyboard_set_focus (keyboard, active_grab->surface); + + /* Chain-up with default keyboard handler */ + return keyboard->default_grab.interface->key (&keyboard->default_grab, event); +} + +static void +meta_xwayland_keyboard_grab_modifiers (MetaWaylandKeyboardGrab *grab, + ClutterModifierType modifiers) +{ + MetaXwaylandKeyboardActiveGrab *active_grab; + MetaWaylandKeyboard *keyboard; + + active_grab = wl_container_of (grab, active_grab, keyboard_grab); + keyboard = active_grab->keyboard_grab.keyboard; + + /* Force focus onto the surface who has the active grab on the keyboard */ + if (active_grab->surface != NULL && keyboard->focus_surface != active_grab->surface) + meta_wayland_keyboard_set_focus (keyboard, active_grab->surface); + + /* Chain-up with default keyboard handler */ + return keyboard->default_grab.interface->modifiers (&keyboard->default_grab, + modifiers); +} + +static void +meta_xwayland_keyboard_grab_end (MetaXwaylandKeyboardActiveGrab *active_grab) +{ + MetaWaylandSeat *seat = active_grab->seat; + + if (seat->keyboard->grab->interface->key == meta_xwayland_keyboard_grab_key) + { + meta_wayland_keyboard_end_grab (active_grab->keyboard_grab.keyboard); + meta_wayland_keyboard_set_focus (active_grab->keyboard_grab.keyboard, NULL); + meta_display_sync_wayland_input_focus (meta_get_display ()); + } + + if (!active_grab->surface) + return; + + g_clear_signal_handler (&active_grab->surface_destroyed_handler, + active_grab->surface); + + g_clear_signal_handler (&active_grab->shortcuts_restored_handler, + active_grab->surface); + + meta_wayland_surface_restore_shortcuts (active_grab->surface, + active_grab->seat); + + g_clear_signal_handler (&active_grab->window_associate_handler, + active_grab->surface->role); + + active_grab->surface = NULL; +} + +static const MetaWaylandKeyboardGrabInterface + keyboard_grab_interface = { + meta_xwayland_keyboard_grab_key, + meta_xwayland_keyboard_grab_modifiers + }; + +static void +zwp_xwayland_keyboard_grab_destructor (struct wl_resource *resource) +{ + MetaXwaylandKeyboardActiveGrab *active_grab; + + active_grab = wl_resource_get_user_data (resource); + meta_xwayland_keyboard_grab_end (active_grab); + + g_free (active_grab); +} + +static void +zwp_xwayland_keyboard_grab_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static const struct zwp_xwayland_keyboard_grab_v1_interface + xwayland_keyboard_grab_interface = { + zwp_xwayland_keyboard_grab_destroy, + }; + +static void +surface_destroyed_cb (MetaWaylandSurface *surface, + MetaXwaylandKeyboardActiveGrab *active_grab) +{ + active_grab->surface = NULL; +} + +static void +shortcuts_restored_cb (MetaWaylandSurface *surface, + MetaXwaylandKeyboardActiveGrab *active_grab) +{ + meta_xwayland_keyboard_grab_end (active_grab); +} + +static void +zwp_xwayland_keyboard_grab_manager_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static gboolean +application_is_in_pattern_array (MetaWindow *window, + GPtrArray *pattern_array) +{ + guint i; + + for (i = 0; pattern_array && i < pattern_array->len; i++) + { + GPatternSpec *pattern = (GPatternSpec *) g_ptr_array_index (pattern_array, i); + + if ((window->res_class && g_pattern_match_string (pattern, window->res_class)) || + (window->res_name && g_pattern_match_string (pattern, window->res_name))) + return TRUE; + } + + return FALSE; +} + +static gboolean +meta_xwayland_grab_is_granted (MetaWindow *window) +{ + MetaBackend *backend; + MetaSettings *settings; + GPtrArray *whitelist; + GPtrArray *blacklist; + gboolean may_grab; + + backend = meta_get_backend (); + settings = meta_backend_get_settings (backend); + + /* Check whether the window is blacklisted */ + meta_settings_get_xwayland_grab_patterns (settings, &whitelist, &blacklist); + + if (blacklist && application_is_in_pattern_array (window, blacklist)) + return FALSE; + + /* Check if we are dealing with good citizen Xwayland client whitelisting itself. */ + g_object_get (G_OBJECT (window), "xwayland-may-grab-keyboard", &may_grab, NULL); + if (may_grab) + return TRUE; + + /* Last resort, is it white listed. */ + if (whitelist && application_is_in_pattern_array (window, whitelist)) + return TRUE; + + return FALSE; +} + +static gboolean +meta_xwayland_grab_should_lock_focus (MetaWindow *window) +{ + MetaBackend *backend; + MetaSettings *settings; + + /* Lock focus applies to O-R windows which never receive keyboard focus otherwise */ + if (!window->override_redirect) + return FALSE; + + backend = meta_get_backend (); + settings = meta_backend_get_settings (backend); + + return meta_settings_are_xwayland_grabs_allowed (settings); +} + +static void +meta_xwayland_keyboard_grab_activate (MetaXwaylandKeyboardActiveGrab *active_grab) +{ + MetaWaylandSurface *surface = active_grab->surface; + MetaWindow *window = meta_wayland_surface_get_window (surface); + MetaWaylandSeat *seat = active_grab->seat; + + if (meta_xwayland_grab_is_granted (window)) + { + meta_verbose ("XWayland window %s has a grab granted", window->desc); + meta_wayland_surface_inhibit_shortcuts (surface, seat); + + if (meta_xwayland_grab_should_lock_focus (window)) + meta_wayland_keyboard_start_grab (seat->keyboard, &active_grab->keyboard_grab); + } + + g_clear_signal_handler (&active_grab->window_associate_handler, + active_grab->surface->role); +} + +static void +meta_xwayland_keyboard_window_associated (MetaWaylandSurfaceRole *surface_role, + MetaXwaylandKeyboardActiveGrab *active_grab) +{ + meta_xwayland_keyboard_grab_activate (active_grab); +} + +static void +zwp_xwayland_keyboard_grab_manager_grab (struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *surface_resource, + struct wl_resource *seat_resource) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + MetaWindow *window = meta_wayland_surface_get_window (surface); + MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); + MetaXwaylandKeyboardActiveGrab *active_grab; + struct wl_resource *grab_resource; + + grab_resource = wl_resource_create (client, + &zwp_xwayland_keyboard_grab_manager_v1_interface, + wl_resource_get_version (resource), + id); + + active_grab = g_new0 (MetaXwaylandKeyboardActiveGrab, 1); + active_grab->surface = surface; + active_grab->resource = grab_resource; + active_grab->seat = seat; + active_grab->keyboard_grab.interface = &keyboard_grab_interface; + active_grab->surface_destroyed_handler = + g_signal_connect (surface, "destroy", + G_CALLBACK (surface_destroyed_cb), + active_grab); + active_grab->shortcuts_restored_handler = + g_signal_connect (surface, "shortcuts-restored", + G_CALLBACK (shortcuts_restored_cb), + active_grab); + + if (window) + meta_xwayland_keyboard_grab_activate (active_grab); + else if (surface->role) + active_grab->window_associate_handler = + g_signal_connect (surface->role, "window-associated", + G_CALLBACK (meta_xwayland_keyboard_window_associated), + active_grab); + else + g_warning ("Cannot grant Xwayland grab to surface %p", surface); + + wl_resource_set_implementation (grab_resource, + &xwayland_keyboard_grab_interface, + active_grab, + zwp_xwayland_keyboard_grab_destructor); +} + +static const struct zwp_xwayland_keyboard_grab_manager_v1_interface + meta_keyboard_grab_manager_interface = { + zwp_xwayland_keyboard_grab_manager_destroy, + zwp_xwayland_keyboard_grab_manager_grab, + }; + +static void +bind_keyboard_grab (struct wl_client *client, + void *data, + uint32_t version, + uint32_t id) +{ + struct wl_resource *resource; + + resource = wl_resource_create (client, + &zwp_xwayland_keyboard_grab_manager_v1_interface, + MIN (META_ZWP_XWAYLAND_KEYBOARD_GRAB_V1_VERSION, version), + id); + + wl_resource_set_implementation (resource, + &meta_keyboard_grab_manager_interface, + NULL, NULL); +} + +gboolean +meta_xwayland_grab_keyboard_init (MetaWaylandCompositor *compositor) +{ + return (wl_global_create (compositor->wayland_display, + &zwp_xwayland_keyboard_grab_manager_v1_interface, + META_ZWP_XWAYLAND_KEYBOARD_GRAB_V1_VERSION, + NULL, + bind_keyboard_grab) != NULL); +} diff --git a/src/wayland/meta-xwayland-grab-keyboard.h b/src/wayland/meta-xwayland-grab-keyboard.h new file mode 100644 index 000000000..597854af5 --- /dev/null +++ b/src/wayland/meta-xwayland-grab-keyboard.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Olivier Fourdan <ofourdan@redhat.com> + */ + +#ifndef META_XWAYLAND_GRAB_KEYBOARD_H +#define META_XWAYLAND_GRAB_KEYBOARD_H + +#include <wayland-server.h> + +#include "wayland/meta-wayland-types.h" +#include "meta/window.h" + +#include "xwayland-keyboard-grab-unstable-v1-server-protocol.h" + +#define META_TYPE_XWAYLAND_KEYBOARD_ACTIVE_GRAB (meta_xwayland_keyboard_active_grab_get_type ()) +G_DECLARE_FINAL_TYPE (MetaXwaylandKeyboardActiveGrab, + meta_xwayland_keyboard_active_grab, + META, XWAYLAND_KEYBOARD_ACTIVE_GRAB, + GObject); + +gboolean meta_xwayland_grab_keyboard_init (MetaWaylandCompositor *compositor); + +#endif /* META_XWAYLAND_GRAB_KEYBOARD_H */ diff --git a/src/wayland/meta-xwayland-private.h b/src/wayland/meta-xwayland-private.h new file mode 100644 index 000000000..51dfa633b --- /dev/null +++ b/src/wayland/meta-xwayland-private.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2013 Intel Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_XWAYLAND_PRIVATE_H +#define META_XWAYLAND_PRIVATE_H + +#include <glib.h> + +#include "wayland/meta-wayland-private.h" + +gboolean +meta_xwayland_init (MetaXWaylandManager *manager, + struct wl_display *display); + +void +meta_xwayland_complete_init (MetaDisplay *display, + Display *xdisplay); + +void +meta_xwayland_shutdown (MetaXWaylandManager *manager); + +/* wl_data_device/X11 selection interoperation */ +void meta_xwayland_init_dnd (Display *xdisplay); +void meta_xwayland_shutdown_dnd (Display *xdisplay); +gboolean meta_xwayland_dnd_handle_event (XEvent *xevent); + +const MetaWaylandDragDestFuncs * meta_xwayland_selection_get_drag_dest_funcs (void); + +void meta_xwayland_start_xserver (MetaXWaylandManager *manager, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean meta_xwayland_start_xserver_finish (MetaXWaylandManager *manager, + GAsyncResult *result, + GError **error); + +#endif /* META_XWAYLAND_PRIVATE_H */ diff --git a/src/wayland/meta-xwayland-surface.c b/src/wayland/meta-xwayland-surface.c new file mode 100644 index 000000000..4a4615a2c --- /dev/null +++ b/src/wayland/meta-xwayland-surface.c @@ -0,0 +1,291 @@ +/* + * Copyright (C) 2013 Intel Corporation + * Copyright (C) 2013-2019 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#include "config.h" + +#include "wayland/meta-xwayland-surface.h" + +#include "compositor/meta-surface-actor-wayland.h" +#include "compositor/meta-window-actor-private.h" +#include "wayland/meta-wayland-actor-surface.h" +#include "wayland/meta-xwayland-private.h" + +enum +{ + WINDOW_ASSOCIATED, + + N_SIGNALS +}; + +static guint signals[N_SIGNALS]; + +struct _MetaXwaylandSurface +{ + MetaWaylandActorSurface parent; + + MetaWindow *window; + + gulong unmanaging_handler_id; + gulong position_changed_handler_id; + gulong effects_completed_handler_id; +}; + +G_DEFINE_TYPE (MetaXwaylandSurface, + meta_xwayland_surface, + META_TYPE_WAYLAND_ACTOR_SURFACE) + +static void +clear_window (MetaXwaylandSurface *xwayland_surface) +{ + MetaWaylandSurfaceRole *surface_role = + META_WAYLAND_SURFACE_ROLE (xwayland_surface); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWindowActor *window_actor; + MetaSurfaceActor *surface_actor; + + if (!xwayland_surface->window) + return; + + g_clear_signal_handler (&xwayland_surface->unmanaging_handler_id, + xwayland_surface->window); + g_clear_signal_handler (&xwayland_surface->position_changed_handler_id, + xwayland_surface->window); + + window_actor = meta_window_actor_from_window (xwayland_surface->window); + g_clear_signal_handler (&xwayland_surface->effects_completed_handler_id, + window_actor); + + xwayland_surface->window->surface = NULL; + xwayland_surface->window = NULL; + + surface_actor = meta_wayland_surface_get_actor (surface); + if (surface_actor) + clutter_actor_set_reactive (CLUTTER_ACTOR (surface_actor), FALSE); + + meta_wayland_surface_notify_unmapped (surface); +} + +static void +window_unmanaging (MetaWindow *window, + MetaXwaylandSurface *xwayland_surface) +{ + clear_window (xwayland_surface); +} + +static void +window_position_changed (MetaWindow *window, + MetaWaylandSurface *surface) +{ + meta_wayland_surface_update_outputs_recursively (surface); +} + +static void +window_actor_effects_completed (MetaWindowActor *window_actor, + MetaWaylandSurface *surface) +{ + meta_wayland_surface_update_outputs_recursively (surface); + meta_wayland_compositor_repick (surface->compositor); +} + +void +meta_xwayland_surface_associate_with_window (MetaXwaylandSurface *xwayland_surface, + MetaWindow *window) +{ + MetaWaylandSurfaceRole *surface_role = + META_WAYLAND_SURFACE_ROLE (xwayland_surface); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaSurfaceActor *surface_actor; + MetaWindowActor *window_actor; + + /* + * If the window has an existing surface, like if we're undecorating or + * decorating the window, then we need to detach the window from its old + * surface. + */ + if (window->surface) + { + MetaXwaylandSurface *other_xwayland_surface; + + other_xwayland_surface = META_XWAYLAND_SURFACE (window->surface->role); + clear_window (other_xwayland_surface); + } + + window->surface = surface; + xwayland_surface->window = window; + + surface_actor = meta_wayland_surface_get_actor (surface); + if (surface_actor) + clutter_actor_set_reactive (CLUTTER_ACTOR (surface_actor), TRUE); + + xwayland_surface->unmanaging_handler_id = + g_signal_connect (window, + "unmanaging", + G_CALLBACK (window_unmanaging), + xwayland_surface); + xwayland_surface->position_changed_handler_id = + g_signal_connect (window, + "position-changed", + G_CALLBACK (window_position_changed), + surface); + xwayland_surface->effects_completed_handler_id = + g_signal_connect (meta_window_actor_from_window (window), + "effects-completed", + G_CALLBACK (window_actor_effects_completed), + surface); + + g_signal_emit (xwayland_surface, signals[WINDOW_ASSOCIATED], 0); + + window_actor = meta_window_actor_from_window (window); + if (window_actor) + meta_window_actor_assign_surface_actor (window_actor, surface_actor); +} + +static void +meta_xwayland_surface_assigned (MetaWaylandSurfaceRole *surface_role) +{ + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWaylandSurfaceRoleClass *surface_role_class = + META_WAYLAND_SURFACE_ROLE_CLASS (meta_xwayland_surface_parent_class); + + surface->dnd.funcs = meta_xwayland_selection_get_drag_dest_funcs (); + + surface_role_class->assigned (surface_role); +} + +static void +meta_xwayland_surface_pre_apply_state (MetaWaylandSurfaceRole *surface_role, + MetaWaylandSurfaceState *pending) +{ + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaXwaylandSurface *xwayland_surface = META_XWAYLAND_SURFACE (surface_role); + + if (pending->newly_attached && + surface->buffer_ref.buffer && + xwayland_surface->window) + meta_window_queue (xwayland_surface->window, META_QUEUE_CALC_SHOWING); +} + +static void +meta_xwayland_surface_get_relative_coordinates (MetaWaylandSurfaceRole *surface_role, + float abs_x, + float abs_y, + float *out_sx, + float *out_sy) +{ + MetaXwaylandSurface *xwayland_surface = META_XWAYLAND_SURFACE (surface_role); + MetaRectangle window_rect = { 0 }; + + if (xwayland_surface->window) + meta_window_get_buffer_rect (xwayland_surface->window, &window_rect); + + *out_sx = abs_x - window_rect.x; + *out_sy = abs_y - window_rect.y; +} + +static MetaWaylandSurface * +meta_xwayland_surface_get_toplevel (MetaWaylandSurfaceRole *surface_role) +{ + return meta_wayland_surface_role_get_surface (surface_role); +} + +static MetaWindow * +meta_xwayland_surface_get_window (MetaWaylandSurfaceRole *surface_role) +{ + MetaXwaylandSurface *xwayland_surface = META_XWAYLAND_SURFACE (surface_role); + + return xwayland_surface->window; +} + +static double +meta_xwayland_surface_get_geometry_scale (MetaWaylandActorSurface *actor_surface) +{ + return 1; +} + +static void +meta_xwayland_surface_sync_actor_state (MetaWaylandActorSurface *actor_surface) +{ + MetaXwaylandSurface *xwayland_surface = META_XWAYLAND_SURFACE (actor_surface); + MetaWaylandActorSurfaceClass *actor_surface_class = + META_WAYLAND_ACTOR_SURFACE_CLASS (meta_xwayland_surface_parent_class); + + if (xwayland_surface->window) + { + MetaWindowActor *window_actor = + meta_window_actor_from_window (xwayland_surface->window); + + actor_surface_class->sync_actor_state (actor_surface); + meta_window_actor_update_regions (window_actor); + } +} + +static void +meta_xwayland_surface_finalize (GObject *object) +{ + MetaXwaylandSurface *xwayland_surface = META_XWAYLAND_SURFACE (object); + GObjectClass *parent_object_class = + G_OBJECT_CLASS (meta_xwayland_surface_parent_class); + + clear_window (xwayland_surface); + + parent_object_class->finalize (object); +} + +static void +meta_xwayland_surface_init (MetaXwaylandSurface *xwayland_surface) +{ +} + +static void +meta_xwayland_surface_class_init (MetaXwaylandSurfaceClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MetaWaylandSurfaceRoleClass *surface_role_class = + META_WAYLAND_SURFACE_ROLE_CLASS (klass); + MetaWaylandActorSurfaceClass *actor_surface_class = + META_WAYLAND_ACTOR_SURFACE_CLASS (klass); + + object_class->finalize = meta_xwayland_surface_finalize; + + surface_role_class->assigned = meta_xwayland_surface_assigned; + surface_role_class->pre_apply_state = meta_xwayland_surface_pre_apply_state; + surface_role_class->get_relative_coordinates = + meta_xwayland_surface_get_relative_coordinates; + surface_role_class->get_toplevel = meta_xwayland_surface_get_toplevel; + surface_role_class->get_window = meta_xwayland_surface_get_window; + + actor_surface_class->get_geometry_scale = + meta_xwayland_surface_get_geometry_scale; + actor_surface_class->sync_actor_state = + meta_xwayland_surface_sync_actor_state; + + signals[WINDOW_ASSOCIATED] = + g_signal_new ("window-associated", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} diff --git a/src/wayland/meta-xwayland-surface.h b/src/wayland/meta-xwayland-surface.h new file mode 100644 index 000000000..4bf305039 --- /dev/null +++ b/src/wayland/meta-xwayland-surface.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2013 Intel Corporation + * Copyright (C) 2013-2019 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#ifndef META_XWAYLAND_SURFACE_H +#define META_XWAYLAND_SURFACE_H + +#include "meta/types.h" +#include "wayland/meta-wayland-actor-surface.h" + +#define META_TYPE_XWAYLAND_SURFACE (meta_xwayland_surface_get_type ()) +G_DECLARE_FINAL_TYPE (MetaXwaylandSurface, + meta_xwayland_surface, + META, XWAYLAND_SURFACE, + MetaWaylandActorSurface) + +void +meta_xwayland_surface_associate_with_window (MetaXwaylandSurface *xwayland_surface, + MetaWindow *window); + +#endif /* META_XWAYLAND_SURFACE_H */ diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c new file mode 100644 index 000000000..ac55599d4 --- /dev/null +++ b/src/wayland/meta-xwayland.c @@ -0,0 +1,854 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * X Wayland Support + * + * Copyright (C) 2013 Intel Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "wayland/meta-xwayland.h" +#include "wayland/meta-xwayland-private.h" + +#include <errno.h> +#include <glib-unix.h> +#include <glib.h> +#include <sys/socket.h> +#include <sys/un.h> +#if defined(HAVE_SYS_RANDOM) +#include <sys/random.h> +#elif defined(HAVE_LINUX_RANDOM) +#include <linux/random.h> +#endif +#include <unistd.h> +#include <X11/Xauth.h> + +#include "core/main-private.h" +#include "meta/main.h" +#include "wayland/meta-xwayland-surface.h" +#include "x11/meta-x11-display-private.h" + +static int display_number_override = -1; + +static void meta_xwayland_stop_xserver (MetaXWaylandManager *manager); + +void +meta_xwayland_associate_window_with_surface (MetaWindow *window, + MetaWaylandSurface *surface) +{ + MetaDisplay *display = window->display; + MetaXwaylandSurface *xwayland_surface; + + if (!meta_wayland_surface_assign_role (surface, + META_TYPE_XWAYLAND_SURFACE, + NULL)) + { + wl_resource_post_error (surface->resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "wl_surface@%d already has a different role", + wl_resource_get_id (surface->resource)); + return; + } + + xwayland_surface = META_XWAYLAND_SURFACE (surface->role); + meta_xwayland_surface_associate_with_window (xwayland_surface, window); + + /* Now that we have a surface check if it should have focus. */ + meta_display_sync_wayland_input_focus (display); +} + +static gboolean +associate_window_with_surface_id (MetaXWaylandManager *manager, + MetaWindow *window, + guint32 surface_id) +{ + struct wl_resource *resource; + + resource = wl_client_get_object (manager->client, surface_id); + if (resource) + { + MetaWaylandSurface *surface = wl_resource_get_user_data (resource); + meta_xwayland_associate_window_with_surface (window, surface); + return TRUE; + } + else + return FALSE; +} + +void +meta_xwayland_handle_wl_surface_id (MetaWindow *window, + guint32 surface_id) +{ + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + MetaXWaylandManager *manager = &compositor->xwayland_manager; + + if (!associate_window_with_surface_id (manager, window, surface_id)) + { + /* No surface ID yet, schedule this association for whenever the + * surface is made known. + */ + meta_wayland_compositor_schedule_surface_association (compositor, + surface_id, window); + } +} + +gboolean +meta_xwayland_is_xwayland_surface (MetaWaylandSurface *surface) +{ + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + MetaXWaylandManager *manager = &compositor->xwayland_manager; + + return wl_resource_get_client (surface->resource) == manager->client; +} + +static gboolean +try_display (int display, + char **filename_out, + int *fd_out) +{ + gboolean ret = FALSE; + char *filename; + int fd; + + filename = g_strdup_printf ("/tmp/.X%d-lock", display); + + again: + fd = open (filename, O_WRONLY | O_CLOEXEC | O_CREAT | O_EXCL, 0444); + + if (fd < 0 && errno == EEXIST) + { + char pid[11]; + char *end; + pid_t other; + + fd = open (filename, O_CLOEXEC, O_RDONLY); + if (fd < 0 || read (fd, pid, 11) != 11) + { + g_warning ("can't read lock file %s: %m", filename); + goto out; + } + close (fd); + fd = -1; + + pid[10] = '\0'; + other = strtol (pid, &end, 0); + if (end != pid + 10) + { + g_warning ("can't parse lock file %s", filename); + goto out; + } + + if (kill (other, 0) < 0 && errno == ESRCH) + { + /* Process is dead. Try unlinking the lock file and trying again. */ + if (unlink (filename) < 0) + { + g_warning ("failed to unlink stale lock file %s: %m", filename); + goto out; + } + + goto again; + } + + goto out; + } + else if (fd < 0) + { + g_warning ("failed to create lock file %s: %m", filename); + goto out; + } + + ret = TRUE; + + out: + if (!ret) + { + g_free (filename); + filename = NULL; + + if (fd >= 0) + { + close (fd); + fd = -1; + } + } + + *filename_out = filename; + *fd_out = fd; + return ret; +} + +static char * +create_lock_file (int display, int *display_out) +{ + char *filename; + int fd; + + char pid[12]; + int size; + int number_of_tries = 0; + + while (!try_display (display, &filename, &fd)) + { + display++; + number_of_tries++; + + /* If we can't get a display after 50 times, then something's wrong. Just + * abort in this case. */ + if (number_of_tries >= 50) + return NULL; + } + + /* Subtle detail: we use the pid of the wayland compositor, not the xserver + * in the lock file. Another subtlety: snprintf returns the number of bytes + * it _would've_ written without either the NUL or the size clamping, hence + * the disparity in size. */ + size = snprintf (pid, 12, "%10d\n", getpid ()); + if (size != 11 || write (fd, pid, 11) != 11) + { + unlink (filename); + close (fd); + g_warning ("failed to write pid to lock file %s", filename); + g_free (filename); + return NULL; + } + + close (fd); + + *display_out = display; + return filename; +} + +static int +bind_to_abstract_socket (int display, + gboolean *fatal) +{ + struct sockaddr_un addr; + socklen_t size, name_size; + int fd; + + fd = socket (PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0); + if (fd < 0) + { + *fatal = TRUE; + g_warning ("Failed to create socket: %m"); + return -1; + } + + addr.sun_family = AF_LOCAL; + name_size = snprintf (addr.sun_path, sizeof addr.sun_path, + "%c/tmp/.X11-unix/X%d", 0, display); + size = offsetof (struct sockaddr_un, sun_path) + name_size; + if (bind (fd, (struct sockaddr *) &addr, size) < 0) + { + *fatal = errno != EADDRINUSE; + g_warning ("failed to bind to @%s: %m", addr.sun_path + 1); + close (fd); + return -1; + } + + if (listen (fd, 1) < 0) + { + *fatal = errno != EADDRINUSE; + g_warning ("Failed to listen on abstract socket @%s: %m", + addr.sun_path + 1); + close (fd); + return -1; + } + + return fd; +} + +static int +bind_to_unix_socket (int display) +{ + struct sockaddr_un addr; + socklen_t size, name_size; + int fd; + + fd = socket (PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0); + if (fd < 0) + return -1; + + addr.sun_family = AF_LOCAL; + name_size = snprintf (addr.sun_path, sizeof addr.sun_path, + "/tmp/.X11-unix/X%d", display) + 1; + size = offsetof (struct sockaddr_un, sun_path) + name_size; + unlink (addr.sun_path); + if (bind (fd, (struct sockaddr *) &addr, size) < 0) + { + g_warning ("failed to bind to %s: %m\n", addr.sun_path); + close (fd); + return -1; + } + + if (listen (fd, 1) < 0) + { + unlink (addr.sun_path); + close (fd); + return -1; + } + + return fd; +} + +static void +xserver_died (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GSubprocess *proc = G_SUBPROCESS (source); + MetaDisplay *display = meta_get_display (); + g_autoptr (GError) error = NULL; + + if (!g_subprocess_wait_finish (proc, result, &error)) + { + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + + g_warning ("Failed to finish waiting for Xwayland: %s", error->message); + } + else if (!g_subprocess_get_successful (proc)) + { + if (meta_get_x11_display_policy () == META_DISPLAY_POLICY_MANDATORY) + g_warning ("X Wayland crashed; exiting"); + else + g_warning ("X Wayland crashed; attempting to recover"); + } + + if (meta_get_x11_display_policy () == META_DISPLAY_POLICY_MANDATORY) + { + meta_exit (META_EXIT_ERROR); + } + else if (meta_get_x11_display_policy () == META_DISPLAY_POLICY_ON_DEMAND) + { + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + + if (display->x11_display) + meta_display_shutdown_x11 (display); + + if (!meta_xwayland_init (&compositor->xwayland_manager, + compositor->wayland_display)) + g_warning ("Failed to init X sockets"); + } +} + +static gboolean +shutdown_xwayland_cb (gpointer data) +{ + MetaXWaylandManager *manager = data; + + meta_verbose ("Shutting down Xwayland"); + manager->xserver_grace_period_id = 0; + meta_display_shutdown_x11 (meta_get_display ()); + meta_xwayland_stop_xserver (manager); + return G_SOURCE_REMOVE; +} + +static int +x_io_error (Display *display) +{ + g_warning ("Connection to xwayland lost"); + + if (meta_get_x11_display_policy () == META_DISPLAY_POLICY_MANDATORY) + meta_exit (META_EXIT_ERROR); + + return 0; +} + +void +meta_xwayland_override_display_number (int number) +{ + display_number_override = number; +} + +static gboolean +open_display_sockets (MetaXWaylandManager *manager, + int display_index, + int *abstract_fd_out, + int *unix_fd_out, + gboolean *fatal) +{ + int abstract_fd, unix_fd; + + abstract_fd = bind_to_abstract_socket (display_index, + fatal); + if (abstract_fd < 0) + return FALSE; + + unix_fd = bind_to_unix_socket (display_index); + if (unix_fd < 0) + { + *fatal = FALSE; + close (abstract_fd); + return FALSE; + } + + *abstract_fd_out = abstract_fd; + *unix_fd_out = unix_fd; + + return TRUE; +} + +static gboolean +choose_xdisplay (MetaXWaylandManager *manager, + MetaXWaylandConnection *connection) +{ + int display = 0; + char *lock_file = NULL; + gboolean fatal = FALSE; + + if (display_number_override != -1) + display = display_number_override; + else if (g_getenv ("RUNNING_UNDER_GDM")) + display = 1024; + + do + { + lock_file = create_lock_file (display, &display); + if (!lock_file) + { + g_warning ("Failed to create an X lock file"); + return FALSE; + } + + if (!open_display_sockets (manager, display, + &connection->abstract_fd, + &connection->unix_fd, + &fatal)) + { + unlink (lock_file); + + if (!fatal) + { + display++; + continue; + } + else + { + g_warning ("Failed to bind X11 socket"); + return FALSE; + } + } + + break; + } + while (1); + + connection->display_index = display; + connection->name = g_strdup_printf (":%d", connection->display_index); + connection->lock_file = lock_file; + + return TRUE; +} + +G_DEFINE_AUTOPTR_CLEANUP_FUNC (FILE, fclose) + +static gboolean +prepare_auth_file (MetaXWaylandManager *manager) +{ + Xauth auth_entry = { 0 }; + g_autoptr (FILE) fp = NULL; + char auth_data[16]; + int fd; + + manager->auth_file = g_build_filename (g_get_user_runtime_dir (), + ".mutter-Xwaylandauth.XXXXXX", + NULL); + + if (getrandom (auth_data, sizeof (auth_data), 0) != sizeof (auth_data)) + { + g_warning ("Failed to get random data: %s", g_strerror (errno)); + return FALSE; + } + + auth_entry.family = FamilyLocal; + auth_entry.address = (char *) g_get_host_name (); + auth_entry.address_length = strlen (auth_entry.address); + auth_entry.name = (char *) "MIT-MAGIC-COOKIE-1"; + auth_entry.name_length = strlen (auth_entry.name); + auth_entry.data = auth_data; + auth_entry.data_length = sizeof (auth_data); + + fd = g_mkstemp (manager->auth_file); + if (fd < 0) + { + g_warning ("Failed to open Xauthority file: %s", g_strerror (errno)); + return FALSE; + } + + fp = fdopen (fd, "w+"); + if (!fp) + { + g_warning ("Failed to open Xauthority stream: %s", g_strerror (errno)); + close (fd); + return FALSE; + } + + if (!XauWriteAuth (fp, &auth_entry)) + { + g_warning ("Error writing to Xauthority file: %s", g_strerror (errno)); + return FALSE; + } + + auth_entry.family = FamilyWild; + if (!XauWriteAuth (fp, &auth_entry)) + { + g_warning ("Error writing to Xauthority file: %s", g_strerror (errno)); + return FALSE; + } + + if (fflush (fp) == EOF) + { + g_warning ("Error writing to Xauthority file: %s", g_strerror (errno)); + return FALSE; + } + + return TRUE; +} + +static void +add_local_user_to_xhost (Display *xdisplay) +{ + XHostAddress host_entry; + XServerInterpretedAddress siaddr; + + siaddr.type = (char *) "localuser"; + siaddr.typelength = strlen (siaddr.type); + siaddr.value = (char *) g_get_user_name(); + siaddr.valuelength = strlen (siaddr.value); + + host_entry.family = FamilyServerInterpreted; + host_entry.address = (char *) &siaddr; + + XAddHost (xdisplay, &host_entry); +} + +static void +on_init_x11_cb (MetaDisplay *display, + GAsyncResult *result, + gpointer user_data) +{ + g_autoptr (GError) error = NULL; + + if (!meta_display_init_x11_finish (display, result, &error)) + g_warning ("Failed to initialize X11 display: %s\n", error->message); +} + +static gboolean +on_displayfd_ready (int fd, + GIOCondition condition, + gpointer user_data) +{ + GTask *task = user_data; + + /* The server writes its display name to the displayfd + * socket when it's ready. We don't care about the data + * in the socket, just that it wrote something, since + * that means it's ready. */ + g_task_return_boolean (task, TRUE); + g_object_unref (task); + + return G_SOURCE_REMOVE; +} + +void +meta_xwayland_start_xserver (MetaXWaylandManager *manager, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + int xwayland_client_fd[2]; + int displayfd[2]; + g_autoptr(GSubprocessLauncher) launcher = NULL; + GSubprocessFlags flags; + GError *error = NULL; + g_autoptr (GTask) task = NULL; + + task = g_task_new (NULL, cancellable, callback, user_data); + g_task_set_source_tag (task, meta_xwayland_start_xserver); + g_task_set_task_data (task, manager, NULL); + + /* We want xwayland to be a wayland client so we make a socketpair to setup a + * wayland protocol connection. */ + if (socketpair (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, xwayland_client_fd) < 0) + { + g_task_return_new_error (task, + G_IO_ERROR, + g_io_error_from_errno (errno), + "xwayland_client_fd socketpair failed"); + return; + } + + if (socketpair (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, displayfd) < 0) + { + g_task_return_new_error (task, + G_IO_ERROR, + g_io_error_from_errno (errno), + "displayfd socketpair failed"); + return; + } + + /* xwayland, please. */ + flags = G_SUBPROCESS_FLAGS_NONE; + + if (getenv ("XWAYLAND_STFU")) + { + flags |= G_SUBPROCESS_FLAGS_STDOUT_SILENCE; + flags |= G_SUBPROCESS_FLAGS_STDERR_SILENCE; + } + + launcher = g_subprocess_launcher_new (flags); + + g_subprocess_launcher_take_fd (launcher, xwayland_client_fd[1], 3); + g_subprocess_launcher_take_fd (launcher, manager->public_connection.abstract_fd, 4); + g_subprocess_launcher_take_fd (launcher, manager->public_connection.unix_fd, 5); + g_subprocess_launcher_take_fd (launcher, displayfd[1], 6); + g_subprocess_launcher_take_fd (launcher, manager->private_connection.abstract_fd, 7); + + g_subprocess_launcher_setenv (launcher, "WAYLAND_SOCKET", "3", TRUE); + + manager->proc = g_subprocess_launcher_spawn (launcher, &error, + XWAYLAND_PATH, + manager->public_connection.name, + "-rootless", + "-noreset", + "-accessx", + "-core", + "-auth", manager->auth_file, + "-listen", "4", + "-listen", "5", + "-displayfd", "6", +#ifdef HAVE_XWAYLAND_INITFD + "-initfd", "7", +#else + "-listen", "7", +#endif + NULL); + + if (!manager->proc) + { + g_task_return_error (task, error); + return; + } + + manager->xserver_died_cancellable = g_cancellable_new (); + g_subprocess_wait_async (manager->proc, manager->xserver_died_cancellable, + xserver_died, NULL); + g_unix_fd_add (displayfd[0], G_IO_IN, on_displayfd_ready, + g_steal_pointer (&task)); + manager->client = wl_client_create (manager->wayland_display, + xwayland_client_fd[0]); +} + +gboolean +meta_xwayland_start_xserver_finish (MetaXWaylandManager *manager, + GAsyncResult *result, + GError **error) +{ + g_assert (g_task_get_source_tag (G_TASK (result)) == + meta_xwayland_start_xserver); + + return g_task_propagate_boolean (G_TASK (result), error); +} + +static gboolean +xdisplay_connection_activity_cb (gint fd, + GIOCondition cond, + gpointer user_data) +{ + MetaDisplay *display = meta_get_display (); + + meta_display_init_x11 (display, NULL, + (GAsyncReadyCallback) on_init_x11_cb, NULL); + + return G_SOURCE_REMOVE; +} + +static void +meta_xwayland_stop_xserver_timeout (MetaXWaylandManager *manager) +{ + if (manager->xserver_grace_period_id) + return; + + manager->xserver_grace_period_id = + g_timeout_add_seconds (10, shutdown_xwayland_cb, manager); +} + +static void +window_unmanaged_cb (MetaWindow *window, + MetaXWaylandManager *manager) +{ + manager->x11_windows = g_list_remove (manager->x11_windows, window); + g_signal_handlers_disconnect_by_func (window, + window_unmanaged_cb, + manager); + if (!manager->x11_windows) + { + meta_verbose ("All X11 windows gone, setting shutdown timeout"); + meta_xwayland_stop_xserver_timeout (manager); + } +} + +static void +window_created_cb (MetaDisplay *display, + MetaWindow *window, + MetaXWaylandManager *manager) +{ + /* Ignore all internal windows */ + if (!window->xwindow || + meta_window_get_client_pid (window) == getpid ()) + return; + + manager->x11_windows = g_list_prepend (manager->x11_windows, window); + g_signal_connect (window, "unmanaged", + G_CALLBACK (window_unmanaged_cb), manager); + + g_clear_handle_id (&manager->xserver_grace_period_id, g_source_remove); +} + +static void +meta_xwayland_stop_xserver (MetaXWaylandManager *manager) +{ + if (manager->proc) + g_subprocess_send_signal (manager->proc, SIGTERM); + g_signal_handlers_disconnect_by_func (meta_get_display (), + window_created_cb, + manager); + g_clear_object (&manager->xserver_died_cancellable); + g_clear_object (&manager->proc); +} + +gboolean +meta_xwayland_init (MetaXWaylandManager *manager, + struct wl_display *wl_display) +{ + MetaDisplayPolicy policy; + gboolean fatal; + + if (!manager->public_connection.name) + { + if (!choose_xdisplay (manager, &manager->public_connection)) + return FALSE; + if (!choose_xdisplay (manager, &manager->private_connection)) + return FALSE; + + if (!prepare_auth_file (manager)) + return FALSE; + } + else + { + if (!open_display_sockets (manager, + manager->public_connection.display_index, + &manager->public_connection.abstract_fd, + &manager->public_connection.unix_fd, + &fatal)) + return FALSE; + + if (!open_display_sockets (manager, + manager->private_connection.display_index, + &manager->private_connection.abstract_fd, + &manager->private_connection.unix_fd, + &fatal)) + return FALSE; + } + + manager->wayland_display = wl_display; + policy = meta_get_x11_display_policy (); + + if (policy == META_DISPLAY_POLICY_ON_DEMAND) + { + g_unix_fd_add (manager->public_connection.abstract_fd, G_IO_IN, + xdisplay_connection_activity_cb, manager); + } + + return TRUE; +} + +static void +on_x11_display_closing (MetaDisplay *display) +{ + Display *xdisplay = meta_x11_display_get_xdisplay (display->x11_display); + + meta_xwayland_shutdown_dnd (xdisplay); + g_signal_handlers_disconnect_by_func (display, + on_x11_display_closing, + NULL); +} + +/* To be called right after connecting */ +void +meta_xwayland_complete_init (MetaDisplay *display, + Display *xdisplay) +{ + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + MetaXWaylandManager *manager = &compositor->xwayland_manager; + + /* We install an X IO error handler in addition to the child watch, + because after Xlib connects our child watch may not be called soon + enough, and therefore we won't crash when X exits (and most important + we won't reset the tty). + */ + XSetIOErrorHandler (x_io_error); + + g_signal_connect (display, "x11-display-closing", + G_CALLBACK (on_x11_display_closing), NULL); + meta_xwayland_init_dnd (xdisplay); + add_local_user_to_xhost (xdisplay); + + if (meta_get_x11_display_policy () == META_DISPLAY_POLICY_ON_DEMAND) + { + meta_xwayland_stop_xserver_timeout (manager); + g_signal_connect (meta_get_display (), "window-created", + G_CALLBACK (window_created_cb), manager); + } +} + +static void +meta_xwayland_connection_release (MetaXWaylandConnection *connection) +{ + unlink (connection->lock_file); + g_clear_pointer (&connection->lock_file, g_free); +} + +void +meta_xwayland_shutdown (MetaXWaylandManager *manager) +{ + char path[256]; + + g_cancellable_cancel (manager->xserver_died_cancellable); + + snprintf (path, sizeof path, "/tmp/.X11-unix/X%d", manager->public_connection.display_index); + unlink (path); + + snprintf (path, sizeof path, "/tmp/.X11-unix/X%d", manager->private_connection.display_index); + unlink (path); + + g_clear_pointer (&manager->public_connection.name, g_free); + g_clear_pointer (&manager->private_connection.name, g_free); + + meta_xwayland_connection_release (&manager->public_connection); + meta_xwayland_connection_release (&manager->private_connection); + + if (manager->auth_file) + { + unlink (manager->auth_file); + g_clear_pointer (&manager->auth_file, g_free); + } +} diff --git a/src/wayland/meta-xwayland.h b/src/wayland/meta-xwayland.h new file mode 100644 index 000000000..dac9c689f --- /dev/null +++ b/src/wayland/meta-xwayland.h @@ -0,0 +1,53 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jasper St. Pierre <jstpierre@mecheye.net> + */ + +#ifndef META_XWAYLAND_H +#define META_XWAYLAND_H + +#include <glib.h> + +#include "core/util-private.h" +#include "meta/types.h" +#include "wayland/meta-wayland-types.h" + +META_EXPORT_TEST +void +meta_xwayland_override_display_number (int number); + +void +meta_xwayland_handle_wl_surface_id (MetaWindow *window, + guint32 surface_id); + +gboolean +meta_xwayland_is_xwayland_surface (MetaWaylandSurface *surface); + +void +meta_xwayland_handle_xwayland_grab (MetaWindow *window, + gboolean allow); + +void +meta_xwayland_associate_window_with_surface (MetaWindow *window, + MetaWaylandSurface *surface); + +#endif /* META_XWAYLAND_H */ diff --git a/src/wayland/protocol/gtk-primary-selection.xml b/src/wayland/protocol/gtk-primary-selection.xml new file mode 100644 index 000000000..02cab94fc --- /dev/null +++ b/src/wayland/protocol/gtk-primary-selection.xml @@ -0,0 +1,225 @@ +<?xml version="1.0" encoding="UTF-8"?> +<protocol name="gtk_primary_selection"> + <copyright> + Copyright © 2015, 2016 Red Hat + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + </copyright> + + <description summary="Primary selection protocol"> + This protocol provides the ability to have a primary selection device to + match that of the X server. This primary selection is a shortcut to the + common clipboard selection, where text just needs to be selected in order + to allow copying it elsewhere. The de facto way to perform this action + is the middle mouse button, although it is not limited to this one. + + Clients wishing to honor primary selection should create a primary + selection source and set it as the selection through + wp_primary_selection_device.set_selection whenever the text selection + changes. In order to minimize calls in pointer-driven text selection, + it should happen only once after the operation finished. Similarly, + a NULL source should be set when text is unselected. + + wp_primary_selection_offer objects are first announced through the + wp_primary_selection_device.data_offer event. Immediately after this event, + the primary data offer will emit wp_primary_selection_offer.offer events + to let know of the mime types being offered. + + When the primary selection changes, the client with the keyboard focus + will receive wp_primary_selection_device.selection events. Only the client + with the keyboard focus will receive such events with a non-NULL + wp_primary_selection_offer. Across keyboard focus changes, previously + focused clients will receive wp_primary_selection_device.events with a + NULL wp_primary_selection_offer. + + In order to request the primary selection data, the client must pass + a recent serial pertaining to the press event that is triggering the + operation, if the compositor deems the serial valid and recent, the + wp_primary_selection_source.send event will happen in the other end + to let the transfer begin. The client owning the primary selection + should write the requested data, and close the file descriptor + immediately. + + If the primary selection owner client disappeared during the transfer, + the client reading the data will receive a + wp_primary_selection_device.selection event with a NULL + wp_primary_selection_offer, the client should take this as a hint + to finish the reads related to the no longer existing offer. + + The primary selection owner should be checking for errors during + writes, merely cancelling the ongoing transfer if any happened. + </description> + + <interface name="gtk_primary_selection_device_manager" version="1"> + <description summary="X primary selection emulation"> + The primary selection device manager is a singleton global object that + provides access to the primary selection. It allows to create + wp_primary_selection_source objects, as well as retrieving the per-seat + wp_primary_selection_device objects. + </description> + + <request name="create_source"> + <description summary="create a new primary selection source"> + Create a new primary selection source. + </description> + <arg name="id" type="new_id" interface="gtk_primary_selection_source"/> + </request> + + <request name="get_device"> + <description summary="create a new primary selection device"> + Create a new data device for a given seat. + </description> + <arg name="id" type="new_id" interface="gtk_primary_selection_device"/> + <arg name="seat" type="object" interface="wl_seat"/> + </request> + + <request name="destroy" type="destructor"> + <description summary="destroy the primary selection device manager"> + Destroy the primary selection device manager. + </description> + </request> + </interface> + + <interface name="gtk_primary_selection_device" version="1"> + <request name="set_selection"> + <description summary="set the primary selection"> + Replaces the current selection. The previous owner of the primary selection + will receive a wp_primary_selection_source.cancelled event. + + To unset the selection, set the source to NULL. + </description> + <arg name="source" type="object" interface="gtk_primary_selection_source" allow-null="true"/> + <arg name="serial" type="uint" summary="serial of the event that triggered this request"/> + </request> + + <event name="data_offer"> + <description summary="introduce a new wp_primary_selection_offer"> + Introduces a new wp_primary_selection_offer object that may be used + to receive the current primary selection. Immediately following this + event, the new wp_primary_selection_offer object will send + wp_primary_selection_offer.offer events to describe the offered mime + types. + </description> + <arg name="offer" type="new_id" interface="gtk_primary_selection_offer"/> + </event> + + <event name="selection"> + <description summary="advertise a new primary selection"> + The wp_primary_selection_device.selection event is sent to notify the + client of a new primary selection. This event is sent after the + wp_primary_selection.data_offer event introducing this object, and after + the offer has announced its mimetypes through + wp_primary_selection_offer.offer. + + The data_offer is valid until a new offer or NULL is received + or until the client loses keyboard focus. The client must destroy the + previous selection data_offer, if any, upon receiving this event. + </description> + <arg name="id" type="object" interface="gtk_primary_selection_offer" allow-null="true"/> + </event> + + <request name="destroy" type="destructor"> + <description summary="destroy the primary selection device"> + Destroy the primary selection device. + </description> + </request> + </interface> + + <interface name="gtk_primary_selection_offer" version="1"> + <description summary="offer to transfer primary selection contents"> + A wp_primary_selection_offer represents an offer to transfer the contents + of the primary selection clipboard to the client. Similar to + wl_data_offer, the offer also describes the mime types that the source + will transferthat the + data can be converted to and provides the mechanisms for transferring the + data directly to the client. + </description> + + <request name="receive"> + <description summary="request that the data is transferred"> + To transfer the contents of the primary selection clipboard, the client + issues this request and indicates the mime type that it wants to + receive. The transfer happens through the passed file descriptor + (typically created with the pipe system call). The source client writes + the data in the mime type representation requested and then closes the + file descriptor. + + The receiving client reads from the read end of the pipe until EOF and + closes its end, at which point the transfer is complete. + </description> + <arg name="mime_type" type="string"/> + <arg name="fd" type="fd"/> + </request> + + <request name="destroy" type="destructor"> + <description summary="destroy the primary selection offer"> + Destroy the primary selection offer. + </description> + </request> + + <event name="offer"> + <description summary="advertise offered mime type"> + Sent immediately after creating announcing the wp_primary_selection_offer + through wp_primary_selection_device.data_offer. One event is sent per + offered mime type. + </description> + <arg name="mime_type" type="string"/> + </event> + </interface> + + <interface name="gtk_primary_selection_source" version="1"> + <description summary="offer to replace the contents of the primary selection"> + The source side of a wp_primary_selection_offer, it provides a way to + describe the offered data and respond to requests to transfer the + requested contents of the primary selection clipboard. + </description> + + <request name="offer"> + <description summary="add an offered mime type"> + This request adds a mime type to the set of mime types advertised to + targets. Can be called several times to offer multiple types. + </description> + <arg name="mime_type" type="string"/> + </request> + + <request name="destroy" type="destructor"> + <description summary="destroy the primary selection source"> + Destroy the primary selection source. + </description> + </request> + + <event name="send"> + <description summary="send the primary selection contents"> + Request for the current primary selection contents from the client. + Send the specified mime type over the passed file descriptor, then + close it. + </description> + <arg name="mime_type" type="string"/> + <arg name="fd" type="fd"/> + </event> + + <event name="cancelled"> + <description summary="request for primary selection contents was canceled"> + This primary selection source is no longer valid. The client should + clean up and destroy this primary selection source. + </description> + </event> + </interface> +</protocol> diff --git a/src/wayland/protocol/gtk-shell.xml b/src/wayland/protocol/gtk-shell.xml new file mode 100644 index 000000000..fb91940b3 --- /dev/null +++ b/src/wayland/protocol/gtk-shell.xml @@ -0,0 +1,87 @@ +<protocol name="gtk"> + + <interface name="gtk_shell1" version="3"> + <description summary="gtk specific extensions"> + gtk_shell is a protocol extension providing additional features for + clients implementing it. + </description> + + <enum name="capability"> + <entry name="global_app_menu" value="1"/> + <entry name="global_menu_bar" value="2"/> + <entry name="desktop_icons" value="3"/> + </enum> + + <event name="capabilities"> + <arg name="capabilities" type="uint"/> + </event> + + <request name="get_gtk_surface"> + <arg name="gtk_surface" type="new_id" interface="gtk_surface1"/> + <arg name="surface" type="object" interface="wl_surface"/> + </request> + + <request name="set_startup_id"> + <arg name="startup_id" type="string" allow-null="true"/> + </request> + + <request name="system_bell"> + <arg name="surface" type="object" interface="gtk_surface1" allow-null="true"/> + </request> + + <!-- Version 3 additions --> + <request name="notify_launch" since="3"> + <arg name="startup_id" type="string"/> + </request> + </interface> + + <interface name="gtk_surface1" version="3"> + <request name="set_dbus_properties"> + <arg name="application_id" type="string" allow-null="true"/> + <arg name="app_menu_path" type="string" allow-null="true"/> + <arg name="menubar_path" type="string" allow-null="true"/> + <arg name="window_object_path" type="string" allow-null="true"/> + <arg name="application_object_path" type="string" allow-null="true"/> + <arg name="unique_bus_name" type="string" allow-null="true"/> + </request> + + <request name="set_modal"/> + <request name="unset_modal"/> + + <request name="present"> + <arg name="time" type="uint"/> + </request> + + <!-- Version 2 additions --> + + <enum name="state"> + <entry name="tiled" value="1"/> + + <entry name="tiled_top" value="2" since="2" /> + <entry name="tiled_right" value="3" since="2" /> + <entry name="tiled_bottom" value="4" since="2" /> + <entry name="tiled_left" value="5" since="2" /> + </enum> + + <enum name="edge_constraint" since="2"> + <entry name="resizable_top" value="1"/> + <entry name="resizable_right" value="2"/> + <entry name="resizable_bottom" value="3"/> + <entry name="resizable_left" value="4"/> + </enum> + + <event name="configure"> + <arg name="states" type="array"/> + </event> + + <event name="configure_edges" since="2"> + <arg name="constraints" type="array"/> + </event> + + <!-- Version 3 additions --> + <request name="request_focus" since="3"> + <arg name="startup_id" type="string" allow-null="true"/> + </request> + </interface> + +</protocol> diff --git a/src/wayland/protocol/gtk-text-input.xml b/src/wayland/protocol/gtk-text-input.xml new file mode 100644 index 000000000..a134a19f6 --- /dev/null +++ b/src/wayland/protocol/gtk-text-input.xml @@ -0,0 +1,302 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<protocol name="gtk_text_input"> + <copyright> + Copyright © 2012, 2013 Intel Corporation + Copyright © 2015, 2016 Jan Arne Petersen + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that copyright notice and this permission + notice appear in supporting documentation, and that the name of + the copyright holders not be used in advertising or publicity + pertaining to distribution of the software without specific, + written prior permission. The copyright holders make no + representations about the suitability of this software for any + purpose. It is provided "as is" without express or implied + warranty. + + THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + THIS SOFTWARE. + </copyright> + + <interface name="gtk_text_input" version="1"> + <description summary="text input"> + The gtk_text_input interface represents text input and input methods + associated with a seat. It provides enter/leave events to follow the + text input focus for a seat. + + Requests are used to enable/disable the text-input object and set + state information like surrounding and selected text or the content type. + The information about the entered text is sent to the text-input object + via the pre-edit and commit_string events. Using this interface removes + the need for applications to directly process hardware key events and + compose text out of them. + + Text is valid UTF-8 encoded, indices and lengths are in bytes. Indices + have to always point to the first byte of an UTF-8 encoded code point. + Lengths are not allowed to contain just a part of an UTF-8 encoded code + point. + + Focus moving throughout surfaces will result in the emission of + gtk_text_input.enter and gtk_text_input.leave events. The focused + surface must perform gtk_text_input.enable and + gtk_text_input.disable requests as the keyboard focus moves across + editable and non-editable elements of the UI. Those two requests are not + expected to be paired with each other, the compositor must be able to + handle consecutive series of the same request. + + State is sent by the state requests (set_surrounding_text, + set_content_type and set_cursor_rectangle) and a commit request. + After an enter event or disable request all state information is + invalidated and needs to be resent by the client. + + This protocol defines requests and events necessary for regular clients + to communicate with an input method. The gtk_input_method protocol + defines the interfaces necessary to implement standalone input methods. + If a compositor implements both interfaces, it will be the arbiter of the + communication between both. + + Warning! The protocol described in this file is experimental and + backward incompatible changes may be made. Backward compatible changes + may be added together with the corresponding interface version bump. + Backward incompatible changes are done by bumping the version number in + the protocol and interface names and resetting the interface version. + Once the protocol is to be declared stable, the 'z' prefix and the + version number in the protocol and interface names are removed and the + interface version number is reset. + </description> + + <request name="destroy" type="destructor"> + <description summary="Destroy the wp_text_input"> + Destroy the wp_text_input object. Also disables all surfaces enabled + through this wp_text_input object + </description> + </request> + + <enum name="enable_flags" bitfield="true"> + <description summary="enable flags"> + Content hint is a bitmask to allow to modify the behavior of the text + input. + </description> + <entry name="none" value="0x0" summary="no special behaviour"/> + <entry name="can_show_preedit" value="0x1" summary="hints that the UI is capable of showing pre-edit text"/> + <entry name="toggle_input_panel" value="0x2" summary="requests toggling input panel (eg. on-screen keyboard)"/> + </enum> + + <request name="enable"> + <description summary="Request text input to be enabled"> + Requests text input on a surface. The serial provided must be the one + received on gtk_text_input.enter. + </description> + <arg name="serial" type="uint" summary="serial of enter event"/> + <arg name="show_input_panel" type="uint" summary="details of the enable request"/> + </request> + + <request name="disable"> + <description summary="Disable text input on a surface"> + Explicitly disable text input in a surface (typically when there is no + focus on any text entry inside the surface). + </description> + </request> + + <request name="set_surrounding_text"> + <description summary="sets the surrounding text"> + Sets the plain surrounding text around the input position. Text is + UTF-8 encoded. Cursor is the byte offset within the surrounding text. + Anchor is the byte offset of the selection anchor within the + surrounding text. If there is no selected text, anchor is the same as + cursor. + + Make sure to always send some text before and after the cursor + except when the cursor is at the beginning or end of text. + + When there was a configure_surrounding_text event take the + before_cursor and after_cursor arguments into account for picking how + much surrounding text to send. + + There is a maximum length of wayland messages so text can not be + longer than 4000 bytes. + </description> + <arg name="text" type="string"/> + <arg name="cursor" type="int"/> + <arg name="anchor" type="int"/> + </request> + + <enum name="content_hint" bitfield="true"> + <description summary="content hint"> + Content hint is a bitmask to allow to modify the behavior of the text + input. + </description> + <entry name="none" value="0x0" summary="no special behaviour"/> + <entry name="completion" value="0x1" summary="suggest word completions"/> + <entry name="spellcheck" value="0x2" summary="suggest word corrections"/> + <entry name="auto_capitalization" value="0x4" summary="switch to uppercase letters at the start of a sentence"/> + <entry name="lowercase" value="0x8" summary="prefer lowercase letters"/> + <entry name="uppercase" value="0x10" summary="prefer uppercase letters"/> + <entry name="titlecase" value="0x20" summary="prefer casing for titles and headings (can be language dependent)"/> + <entry name="hidden_text" value="0x40" summary="characters should be hidden"/> + <entry name="sensitive_data" value="0x80" summary="typed text should not be stored"/> + <entry name="latin" value="0x100" summary="just latin characters should be entered"/> + <entry name="multiline" value="0x200" summary="the text input is multiline"/> + </enum> + + <enum name="content_purpose"> + <description summary="content purpose"> + The content purpose allows to specify the primary purpose of a text + input. + + This allows an input method to show special purpose input panels with + extra characters or to disallow some characters. + </description> + <entry name="normal" value="0" summary="default input, allowing all characters"/> + <entry name="alpha" value="1" summary="allow only alphabetic characters"/> + <entry name="digits" value="2" summary="allow only digits"/> + <entry name="number" value="3" summary="input a number (including decimal separator and sign)"/> + <entry name="phone" value="4" summary="input a phone number"/> + <entry name="url" value="5" summary="input an URL"/> + <entry name="email" value="6" summary="input an email address"/> + <entry name="name" value="7" summary="input a name of a person"/> + <entry name="password" value="8" summary="input a password (combine with password or sensitive_data hint)"/> + <entry name="pin" value="9" summary="input is a numeric password (combine with password or sensitive_data hint)"/> + <entry name="date" value="10" summary="input a date"/> + <entry name="time" value="11" summary="input a time"/> + <entry name="datetime" value="12" summary="input a date and time"/> + <entry name="terminal" value="13" summary="input for a terminal"/> + </enum> + + <request name="set_content_type"> + <description summary="set content purpose and hint"> + Sets the content purpose and content hint. While the purpose is the + basic purpose of an input field, the hint flags allow to modify some + of the behavior. + + When no content type is explicitly set, a normal content purpose with + none hint should be assumed. + </description> + <arg name="hint" type="uint" enum="content_hint"/> + <arg name="purpose" type="uint" enum="content_purpose"/> + </request> + + <request name="set_cursor_rectangle"> + <description summary="set cursor position"> + Sets the cursor outline as a x, y, width, height rectangle in surface + local coordinates. + + Allows the compositor to put a window with word suggestions near the + cursor. + </description> + <arg name="x" type="int"/> + <arg name="y" type="int"/> + <arg name="width" type="int"/> + <arg name="height" type="int"/> + </request> + + <request name="commit"> + <description summary="commit state"> + Allows to atomically send state updates from client. The previous + set_surrounding_text, set_content_type and set_cursor_rectangle + become effective after this call. + + Serial should be set to the serial from the last wp_text_input.enter + event. + + To make sure to not receive outdated input method events after a + state update, wl_display_sync() should be called after making this + request. + </description> + </request> + + <event name="enter"> + <description summary="enter event"> + Notification that this seat's text-input focus is on a certain surface. + + When the seat has the keyboard capability the text-input focus follows + the keyboard focus. + </description> + <arg name="serial" type="uint" summary="serial"/> + <arg name="surface" type="object" interface="wl_surface"/> + </event> + + <event name="leave"> + <description summary="leave event"> + Notification that this seat's text-input focus is no longer on + a certain surface. The client should reset any preedit string previously + set. + + The leave notification is sent before the enter notification + for the new focus. + + When the seat has the keyboard capability the text-input focus follows + the keyboard focus. + </description> + <arg name="serial" type="uint"/> + <arg name="surface" type="object" interface="wl_surface"/> + </event> + + <event name="preedit_string"> + <description summary="pre-edit"> + Notify when a new composing text (pre-edit) should be set around the + current cursor position. Any previously set composing text should + be removed. + </description> + <arg name="text" type="string" allow-null="true"/> + <arg name="cursor" type="uint"/> + </event> + + <event name="commit_string"> + <description summary="text commit"> + Notify when text should be inserted into the editor widget. The text to + commit could be either just a single character after a key press or the + result of some composing (pre-edit). + + The text argument could be also null if some text is removed (see + gtk_text_input.delete_surrounding_text). + + Any previously set composing text should be removed. + </description> + <arg name="text" type="string" allow-null="true"/> + </event> + + <event name="delete_surrounding_text"> + <description summary="delete surrounding text"> + Notify when the text around the current cursor position should be + deleted. Before_length and after_length is the length (in bytes) of text + before and after the current cursor position (excluding the selection) + to delete. + + This event should be handled as part of a following commit_string or + preedit_string event. + </description> + <arg name="before_length" type="uint" summary="length of text before current cursor position"/> + <arg name="after_length" type="uint" summary="length of text after current cursor position"/> + </event> + </interface> + + <interface name="gtk_text_input_manager" version="1"> + <description summary="text input manager"> + A factory for text-input objects. This object is a global singleton. + </description> + + <request name="destroy" type="destructor"> + <description summary="Destroy the wp_text_input_manager"> + Destroy the wp_text_input_manager object. + </description> + </request> + + <request name="get_text_input"> + <description summary="create a new text input object"> + Creates a new text-input object for a given seat. + </description> + <arg name="id" type="new_id" interface="gtk_text_input"/> + <arg name="seat" type="object" interface="wl_seat"/> + </request> + </interface> +</protocol> diff --git a/src/wm-tester/Makefile.am b/src/wm-tester/Makefile.am deleted file mode 100644 index 54d47247b..000000000 --- a/src/wm-tester/Makefile.am +++ /dev/null @@ -1,29 +0,0 @@ - -AM_CPPFLAGS=$(WARN_CFLAGS) @MUFFIN_CFLAGS@ - -wm_tester_SOURCES= \ - main.c - -test_gravity_SOURCES= \ - test-gravity.c - -focus_window_SOURCES= \ - focus-window.c - -test_resizing_SOURCES= \ - test-resizing.c - -test_size_hints_SOURCES= \ - test-size-hints.c - -test_attached_SOURCES= \ - test-attached.c - -noinst_PROGRAMS=wm-tester test-gravity test-resizing focus-window test-size-hints test-attached - -wm_tester_LDADD= @MUFFIN_LIBS@ -test_gravity_LDADD= @MUFFIN_LIBS@ -test_resizing_LDADD= @MUFFIN_LIBS@ -test_size_hints_LDADD= @MUFFIN_LIBS@ -focus_window_LDADD= @MUFFIN_LIBS@ -test_attached_LDADD= @MUFFIN_LIBS@ diff --git a/src/wm-tester/focus-window.c b/src/wm-tester/focus-window.c deleted file mode 100644 index dc33bd25d..000000000 --- a/src/wm-tester/focus-window.c +++ /dev/null @@ -1,37 +0,0 @@ -#include <X11/Xlib.h> -#include <X11/Xutil.h> -#include <stdio.h> -#include <stdlib.h> - -int main (int argc, char **argv) -{ - Display *d; - Window w; - const char *w_str; - char *end; - - if (argc != 2) - { - fprintf (stderr, "Usage: focus-window WINDOWID\n"); - exit (1); - } - - d = XOpenDisplay (NULL); - - w_str = argv[1]; - end = NULL; - - w = strtoul (w_str, &end, 16); - if (end == w_str) - { - fprintf (stderr, "Usage: focus-window WINDOWID\n"); - exit (1); - } - - printf ("Setting input focus to 0x%lx\n", w); - XSetInputFocus (d, w, RevertToPointerRoot, CurrentTime); - XFlush (d); - - return 0; -} - diff --git a/src/wm-tester/main.c b/src/wm-tester/main.c deleted file mode 100644 index fbd686346..000000000 --- a/src/wm-tester/main.c +++ /dev/null @@ -1,251 +0,0 @@ -/* WM tester main() */ - -/* - * Copyright (C) 2001 Havoc Pennington - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. - */ - -#include <gtk/gtk.h> - -#include <stdlib.h> -#include <sys/types.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> - -static void set_up_the_evil (void); -static void set_up_icon_windows (void); - -static void -usage (void) -{ - g_print ("wm-tester [--evil] [--icon-windows]\n"); - exit (0); -} - -int -main (int argc, char **argv) -{ - int i; - gboolean do_evil; - gboolean do_icon_windows; - - gtk_init (&argc, &argv); - - do_evil = FALSE; - do_icon_windows = FALSE; - - i = 1; - while (i < argc) - { - const char *arg = argv[i]; - - if (strcmp (arg, "--help") == 0 || - strcmp (arg, "-h") == 0 || - strcmp (arg, "-?") == 0) - usage (); - else if (strcmp (arg, "--evil") == 0) - do_evil = TRUE; - else if (strcmp (arg, "--icon-windows") == 0) - do_icon_windows = TRUE; - else - usage (); - - ++i; - } - - /* Be sure some option was provided */ - if (! (do_evil || do_icon_windows)) - return 1; - - if (do_evil) - set_up_the_evil (); - - if (do_icon_windows) - set_up_icon_windows (); - - gtk_main (); - - return 0; -} - -static GSList *evil_windows = NULL; - -static gint -evil_timeout (gpointer data) -{ - int i; - int n_windows; - int len; - int create_count; - int destroy_count; - - len = g_slist_length (evil_windows); - - if (len > 35) - { - create_count = 2; - destroy_count = 5; - } - else - { - create_count = 5; - destroy_count = 5; - } - - /* Create some windows */ - n_windows = g_random_int_range (0, create_count); - - i = 0; - while (i < n_windows) - { - GtkWidget *w; - GtkWidget *c; - int t; - GtkWidget *parent; - - w = gtk_window_new (GTK_WINDOW_TOPLEVEL); - - gtk_window_move (GTK_WINDOW (w), - g_random_int_range (0, - gdk_screen_width ()), - g_random_int_range (0, - gdk_screen_height ())); - - parent = NULL; - - /* set transient for random window (may create all kinds of weird cycles) */ - if (len > 0) - { - t = g_random_int_range (- (len / 3), len); - if (t >= 0) - { - parent = g_slist_nth_data (evil_windows, t); - - if (parent != NULL) - gtk_window_set_transient_for (GTK_WINDOW (w), GTK_WINDOW (parent)); - } - } - - if (parent != NULL) - c = gtk_button_new_with_label ("Evil Transient!"); - else - c = gtk_button_new_with_label ("Evil Window!"); - gtk_container_add (GTK_CONTAINER (w), c); - - gtk_widget_show_all (w); - - evil_windows = g_slist_prepend (evil_windows, w); - - ++i; - } - - /* Destroy some windows */ - if (len > destroy_count) - { - n_windows = g_random_int_range (0, destroy_count); - i = 0; - while (i < n_windows) - { - GtkWidget *w; - - w = g_slist_nth_data (evil_windows, - g_random_int_range (0, len)); - if (w) - { - --len; - evil_windows = g_slist_remove (evil_windows, w); - gtk_widget_destroy (w); - } - - ++i; - } - } - - return TRUE; -} - -static void -set_up_the_evil (void) -{ - g_timeout_add (400, evil_timeout, NULL); -} - -static void -set_up_icon_windows (void) -{ - int i; - int n_windows; - - /* Create some windows */ - n_windows = 9; - - i = 0; - while (i < n_windows) - { - GtkWidget *w; - GtkWidget *c; - GList *icons; - GtkIconTheme *theme; - GdkPixbuf *pix; - - w = gtk_window_new (GTK_WINDOW_TOPLEVEL); - c = gtk_button_new_with_label ("Icon window"); - gtk_container_add (GTK_CONTAINER (w), c); - - theme = gtk_icon_theme_get_default (); - - icons = NULL; - - pix = gtk_icon_theme_load_icon (theme, - "document-save", - 24, - 0, - NULL); - - icons = g_list_append (icons, pix); - - if (i % 2) - { - pix = gtk_icon_theme_load_icon (theme, - "document-save", - 48, - 0, - NULL); - icons = g_list_append (icons, pix); - } - - if (i % 3) - { - pix = gtk_icon_theme_load_icon (theme, - "document-save", - 16, - 0, - NULL); - icons = g_list_append (icons, pix); - } - - gtk_window_set_icon_list (GTK_WINDOW (w), icons); - - g_list_foreach (icons, (GFunc) g_object_unref, NULL); - g_list_free (icons); - - gtk_widget_show_all (w); - - ++i; - } -} diff --git a/src/wm-tester/test-attached.c b/src/wm-tester/test-attached.c deleted file mode 100644 index 60931c835..000000000 --- a/src/wm-tester/test-attached.c +++ /dev/null @@ -1,100 +0,0 @@ -#include <gtk/gtk.h> - -enum { - DESTROY_PARENT, - DETACH, - ATTACH_1, - ATTACH_2 -}; - -GtkWidget *window1, *window2; - -static void -dialog_response (GtkDialog *dialog, int response, gpointer user_data) -{ - if (response == DESTROY_PARENT) - { - GtkWidget *window = GTK_WIDGET (gtk_window_get_transient_for (GTK_WINDOW (dialog))); - - if (window == window1) - { - gtk_dialog_set_response_sensitive (dialog, ATTACH_1, FALSE); - window1 = NULL; - } - else - { - gtk_dialog_set_response_sensitive (dialog, ATTACH_2, FALSE); - window2 = NULL; - } - - gtk_dialog_set_response_sensitive (dialog, DESTROY_PARENT, FALSE); - gtk_dialog_set_response_sensitive (dialog, DETACH, FALSE); - gtk_widget_destroy (window); - } - else if (response == DETACH) - { - gtk_window_set_transient_for (GTK_WINDOW (dialog), NULL); - gtk_dialog_set_response_sensitive (dialog, DESTROY_PARENT, FALSE); - gtk_dialog_set_response_sensitive (dialog, DETACH, FALSE); - gtk_dialog_set_response_sensitive (dialog, ATTACH_1, window1 != NULL); - gtk_dialog_set_response_sensitive (dialog, ATTACH_2, window2 != NULL); - } - else if (response == ATTACH_1) - { - gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (window1)); - gtk_dialog_set_response_sensitive (dialog, DESTROY_PARENT, TRUE); - gtk_dialog_set_response_sensitive (dialog, DETACH, TRUE); - gtk_dialog_set_response_sensitive (dialog, ATTACH_1, FALSE); - gtk_dialog_set_response_sensitive (dialog, ATTACH_2, window2 != NULL); - } - else if (response == ATTACH_2) - { - gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (window2)); - gtk_dialog_set_response_sensitive (dialog, DESTROY_PARENT, TRUE); - gtk_dialog_set_response_sensitive (dialog, DETACH, TRUE); - gtk_dialog_set_response_sensitive (dialog, ATTACH_1, window1 != NULL); - gtk_dialog_set_response_sensitive (dialog, ATTACH_2, FALSE); - } - else if (response == GTK_RESPONSE_CLOSE) - gtk_main_quit (); -} - -int -main (int argc, char **argv) -{ - GtkWidget *dialog; - - gtk_init (&argc, &argv); - - window1 = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_window_set_title (GTK_WINDOW (window1), "Parent 1"); - gtk_widget_show (window1); - - window2 = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_window_set_title (GTK_WINDOW (window2), "Parent 2"); - gtk_widget_show (window2); - - dialog = gtk_dialog_new_with_buttons ("Child", - NULL, - GTK_DIALOG_MODAL, - "Destroy Parent", - DESTROY_PARENT, - "Detach", - DETACH, - "Attach to 1", - ATTACH_1, - "Attach to 2", - ATTACH_2, - "Quit", - GTK_RESPONSE_CLOSE, - NULL); - gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), DESTROY_PARENT, FALSE); - gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), DETACH, FALSE); - - g_signal_connect (dialog, "response", G_CALLBACK (dialog_response), NULL); - gtk_widget_show (dialog); - - gtk_main (); - - return 0; -} diff --git a/src/wm-tester/test-gravity.c b/src/wm-tester/test-gravity.c deleted file mode 100644 index 8e5b581c7..000000000 --- a/src/wm-tester/test-gravity.c +++ /dev/null @@ -1,308 +0,0 @@ -#include <X11/Xlib.h> -#include <X11/Xutil.h> -#include <stdio.h> -#include <string.h> - -static int gravities[10] = { - NorthWestGravity, - NorthGravity, - NorthEastGravity, - WestGravity, - CenterGravity, - EastGravity, - SouthWestGravity, - SouthGravity, - SouthEastGravity, - StaticGravity -}; - -typedef struct -{ - int x, y, width, height; -} Rectangle; - -static Window windows[10]; -static int doubled[10] = { 0, }; -static Rectangle window_rects[10]; - -#define WINDOW_WIDTH 100 -#define WINDOW_HEIGHT 100 - -static int x_offset[3] = { 0, - WINDOW_WIDTH/2, -WINDOW_WIDTH }; -static int y_offset[3] = { 0, - WINDOW_HEIGHT/2, -WINDOW_HEIGHT }; -static double screen_x_fraction[3] = { 0, 0.5, 1.0 }; -static double screen_y_fraction[3] = { 0, 0.5, 1.0 }; -static int screen_width; -static int screen_height; - -static const char* -window_gravity_to_string (int gravity) -{ - switch (gravity) - { - case NorthWestGravity: - return "NorthWestGravity"; - case NorthGravity: - return "NorthGravity"; - case NorthEastGravity: - return "NorthEastGravity"; - case WestGravity: - return "WestGravity"; - case CenterGravity: - return "CenterGravity"; - case EastGravity: - return "EastGravity"; - case SouthWestGravity: - return "SouthWestGravity"; - case SouthGravity: - return "SouthGravity"; - case SouthEastGravity: - return "SouthEastGravity"; - case StaticGravity: - return "StaticGravity"; - default: - return "NorthWestGravity"; - } -} - -static void -calculate_position (int i, int doubled, int *x, int *y) -{ - if (i == 9) - { - *x = 150; - *y = 150; - } - else - { - int xoff = x_offset[i % 3]; - int yoff = y_offset[i / 3]; - if (doubled) - { - xoff *= 2; - yoff *= 2; - } - - *x = screen_x_fraction[i % 3] * screen_width + xoff; - *y = screen_y_fraction[i / 3] * screen_height + yoff; - } -} - -static int -find_window (Window window) -{ - int i; - for (i=0; i<10; i++) - { - if (windows[i] == window) - return i; - } - - return -1; -} - -typedef struct { - unsigned long flags; - unsigned long functions; - unsigned long decorations; - long input_mode; - unsigned long status; -} MotifWmHints, MwmHints; - -#define MWM_HINTS_FUNCTIONS (1L << 0) -#define MWM_HINTS_DECORATIONS (1L << 1) -#define MWM_HINTS_INPUT_MODE (1L << 2) -#define MWM_HINTS_STATUS (1L << 3) - -int main (int argc, char **argv) -{ - Display *d; - Window w; - XSizeHints hints; - int i; - int screen; - XEvent ev; - int noframes; - - if (argc > 1 && strcmp (argv[1], "--noframes") == 0) - noframes = 1; - else - noframes = 0; - - d = XOpenDisplay (NULL); - - screen = DefaultScreen (d); - screen_width = DisplayWidth (d, screen); - screen_height = DisplayHeight (d, screen); - - for (i=0; i<10; i++) - { - int x, y; - - calculate_position (i, doubled[i], &x, &y); - - w = XCreateSimpleWindow (d, RootWindow (d, screen), - x, y, WINDOW_WIDTH, WINDOW_HEIGHT, 0, - WhitePixel (d, screen), WhitePixel (d, screen)); - - windows[i] = w; - window_rects[i].x = x; - window_rects[i].y = y; - window_rects[i].width = WINDOW_WIDTH; - window_rects[i].height = WINDOW_HEIGHT; - - XSelectInput (d, w, ButtonPressMask | ExposureMask | StructureNotifyMask); - - hints.flags = USPosition | PMinSize | PMaxSize | PWinGravity; - - hints.min_width = WINDOW_WIDTH / 2; - hints.min_height = WINDOW_HEIGHT / 2; - -#if 1 - /* we constrain max size below the "doubled" size so that - * the WM will have to deal with constraints - * at the same time it's dealing with configure request - */ - hints.max_width = WINDOW_WIDTH * 2 - WINDOW_WIDTH / 2; - hints.max_height = WINDOW_HEIGHT * 2 - WINDOW_HEIGHT / 2; -#else - hints.max_width = WINDOW_WIDTH * 2 + WINDOW_WIDTH / 2; - hints.max_height = WINDOW_HEIGHT * 2 + WINDOW_HEIGHT / 2; -#endif - hints.win_gravity = gravities[i]; - - XSetWMNormalHints (d, w, &hints); - - XStoreName (d, w, window_gravity_to_string (hints.win_gravity)); - - if (noframes) - { - MotifWmHints mwm; - Atom mwm_atom; - - mwm.decorations = 0; - mwm.flags = MWM_HINTS_DECORATIONS; - - mwm_atom = XInternAtom (d, "_MOTIF_WM_HINTS", False); - - XChangeProperty (d, w, mwm_atom, mwm_atom, - 32, PropModeReplace, - (unsigned char *)&mwm, - sizeof (MotifWmHints)/sizeof (long)); - } - - XMapWindow (d, w); - } - - while (1) - { - XNextEvent (d, &ev); - - if (ev.xany.type == ConfigureNotify) - { - i = find_window (ev.xconfigure.window); - - if (i >= 0) - { - Window ignored; - - window_rects[i].width = ev.xconfigure.width; - window_rects[i].height = ev.xconfigure.height; - - XClearArea (d, windows[i], 0, 0, - ev.xconfigure.width, - ev.xconfigure.height, - True); - - if (!ev.xconfigure.send_event) - XTranslateCoordinates (d, windows[i], DefaultRootWindow (d), - 0, 0, - &window_rects[i].x, &window_rects[i].y, - &ignored); - else - { - window_rects[i].x = ev.xconfigure.x; - window_rects[i].y = ev.xconfigure.y; - } - } - } - else if (ev.xany.type == Expose) - { - i = find_window (ev.xexpose.window); - - if (i >= 0) - { - GC gc; - XGCValues values; - char buf[256]; - - values.foreground = BlackPixel (d, screen); - - gc = XCreateGC (d, windows[i], - GCForeground, &values); - - sprintf (buf, - "%d,%d", - window_rects[i].x, - window_rects[i].y); - - XDrawString (d, windows[i], gc, 10, 15, - buf, strlen (buf)); - - sprintf (buf, - "%dx%d", - window_rects[i].width, - window_rects[i].height); - - XDrawString (d, windows[i], gc, 10, 35, - buf, strlen (buf)); - - XFreeGC (d, gc); - } - } - else if (ev.xany.type == ButtonPress) - { - i = find_window (ev.xbutton.window); - - if (i >= 0) - { - /* Button 1 = move, 2 = resize, 3 = both at once */ - - if (ev.xbutton.button == Button1) - { - int x, y; - - calculate_position (i, doubled[i], &x, &y); - XMoveWindow (d, windows[i], x, y); - } - else if (ev.xbutton.button == Button2) - { - if (doubled[i]) - XResizeWindow (d, windows[i], WINDOW_WIDTH, WINDOW_HEIGHT); - else - XResizeWindow (d, windows[i], WINDOW_WIDTH*2, WINDOW_HEIGHT*2); - - doubled[i] = !doubled[i]; - } - else if (ev.xbutton.button == Button3) - { - int x, y; - - calculate_position (i, !doubled[i], &x, &y); - - if (doubled[i]) - XMoveResizeWindow (d, windows[i], x, y, WINDOW_WIDTH, WINDOW_HEIGHT); - else - XMoveResizeWindow (d, windows[i], x, y, WINDOW_WIDTH*2, WINDOW_HEIGHT*2); - - doubled[i] = !doubled[i]; - } - } - } - } - - /* This program has an infinite loop above so a return statement would - * just cause compiler warnings. - */ -} - diff --git a/src/wm-tester/test-resizing.c b/src/wm-tester/test-resizing.c deleted file mode 100644 index 616786fea..000000000 --- a/src/wm-tester/test-resizing.c +++ /dev/null @@ -1,257 +0,0 @@ -#include <X11/Xlib.h> -#include <X11/Xutil.h> -#include <stdlib.h> -#include <glib.h> - -static void -calc_rects (XRectangle *rects, int width, int height) -{ - int w = (width - 21) / 3; - int h = (height - 21) / 3; - int i; - - i = 0; - while (i < 9) - { - rects[i].width = w; - rects[i].height = h; - ++i; - } - - /* NW */ - rects[0].x = 0; - rects[0].y = 0; - - /* N */ - rects[1].x = width / 2 - w / 2; - rects[1].y = 0; - - /* NE */ - rects[2].x = width - w; - rects[2].y = 0; - - /* E */ - rects[3].x = width - w; - rects[3].y = height / 2 - h / 2; - - /* SE */ - rects[4].x = width - w; - rects[4].y = height - h; - - /* S */ - rects[5].x = width / 2 - w / 2; - rects[5].y = height - h; - - /* SW */ - rects[6].x = 0; - rects[6].y = height - h; - - /* W */ - rects[7].x = 0; - rects[7].y = height / 2 - h / 2; - - /* Center */ - rects[8].x = width / 2 - w / 2; - rects[8].y = height / 2 - h / 2; -} - -static Bool -all_events (Display *display, - XEvent *event, - XPointer arg) -{ - return True; -} - -static void -get_size (Display *d, Drawable draw, - int *xp, int *yp, int *widthp, int *heightp) -{ - int x, y; - unsigned int width=0, height=0, border=0, depth=0; - Window root; - - XGetGeometry (d, draw, &root, &x, &y, &width, &height, &border, &depth); - - if (xp) - *xp = x; - if (yp) - *yp = y; - if (widthp) - *widthp = width; - if (heightp) - *heightp = height; -} - -int -main (int argc, char **argv) -{ - Display *d; - Window w, cw; - XSizeHints hints; - int screen; - XEvent ev; - int x, y, width, height; - Pixmap pix; - GC gc; - XGCValues gc_vals; - XSetWindowAttributes set_attrs; - XWindowChanges changes; - XRectangle rects[9]; - gboolean redraw_pending; - unsigned int mask; - - d = XOpenDisplay (NULL); - - screen = DefaultScreen (d); - - /* Print some debug spew to show how StaticGravity works */ - w = XCreateSimpleWindow (d, RootWindow (d, screen), - 0, 0, 100, 100, 0, - WhitePixel (d, screen), - WhitePixel (d, screen)); - cw = XCreateSimpleWindow (d, w, - 0, 0, 100, 100, 0, - WhitePixel (d, screen), - WhitePixel (d, screen)); - set_attrs.win_gravity = StaticGravity; - - XChangeWindowAttributes (d, cw, - CWWinGravity, - &set_attrs); - - get_size (d, w, &x, &y, &width, &height); - - g_print ("Parent is %d,%d %d x %d before configuring parent\n", - x, y, width, height); - - get_size (d, cw, &x, &y, &width, &height); - - g_print ("Child is %d,%d %d x %d before configuring parent\n", - x, y, width, height); - - changes.x = 10; - changes.y = 10; - changes.width = 110; - changes.height = 110; - /* last mask wins */ - mask = CWX | CWY; - mask = CWWidth | CWHeight; - mask = CWX | CWY | CWWidth | CWHeight; - - XConfigureWindow (d, w, mask, &changes); - XSync (d, False); - - get_size (d, w, &x, &y, &width, &height); - - g_print ("Parent is %d,%d %d x %d after configuring parent\n", - x, y, width, height); - - get_size (d, cw, &x, &y, &width, &height); - - g_print ("Child is %d,%d %d x %d after configuring parent\n", - x, y, width, height); - - XDestroyWindow (d, w); - - /* The window that gets displayed */ - - x = 20; - y = 20; - width = 100; - height = 100; - - calc_rects (rects, width, height); - - w = XCreateSimpleWindow (d, RootWindow (d, screen), - x, y, width, height, 0, - WhitePixel (d, screen), - WhitePixel (d, screen)); - - set_attrs.bit_gravity = StaticGravity; - - XChangeWindowAttributes (d, w, - CWBitGravity, - &set_attrs); - - XSelectInput (d, w, - ButtonPressMask | ExposureMask | StructureNotifyMask); - - hints.flags = PMinSize; - - hints.min_width = 100; - hints.min_height = 100; - - XSetWMNormalHints (d, w, &hints); - XMapWindow (d, w); - - redraw_pending = FALSE; - while (1) - { - XNextEvent (d, &ev); - - switch (ev.xany.type) - { - case ButtonPress: - if (ev.xbutton.button == 3) - { - g_print ("Exiting on button 3 press\n"); - exit (0); - } - break; - - case ConfigureNotify: - x = ev.xconfigure.x; - y = ev.xconfigure.y; - width = ev.xconfigure.width; - height = ev.xconfigure.height; - - redraw_pending = TRUE; - break; - - case Expose: - redraw_pending = TRUE; - break; - - default: - break; - } - - /* Primitive event compression */ - if (XCheckIfEvent (d, &ev, all_events, NULL)) - { - XPutBackEvent (d, &ev); - } - else if (redraw_pending) - { - calc_rects (rects, width, height); - - pix = XCreatePixmap (d, w, width, height, - DefaultDepth (d, screen)); - - gc_vals.foreground = WhitePixel (d, screen); - - gc = XCreateGC (d, pix, GCForeground, &gc_vals); - - XFillRectangle (d, pix, gc, 0, 0, width, height); - - /* Draw rectangles at each gravity point */ - gc_vals.foreground = BlackPixel (d, screen); - XChangeGC (d, gc, GCForeground, &gc_vals); - - XFillRectangles (d, pix, gc, rects, G_N_ELEMENTS (rects)); - - XCopyArea (d, pix, w, gc, 0, 0, width, height, 0, 0); - - XFreePixmap (d, pix); - XFreeGC (d, gc); - - redraw_pending = FALSE; - } - } - - /* This program has an infinite loop above so a return statement would - * just cause compiler warnings. - */ -} - diff --git a/src/wm-tester/test-size-hints.c b/src/wm-tester/test-size-hints.c deleted file mode 100644 index 72f1b4868..000000000 --- a/src/wm-tester/test-size-hints.c +++ /dev/null @@ -1,136 +0,0 @@ -#include <X11/Xlib.h> -#include <X11/Xutil.h> -#include <stdlib.h> -#include <glib.h> - -static Bool -all_events (Display *display, - XEvent *event, - XPointer arg) -{ - return True; -} - -#if 0 -static void -get_size (Display *d, Drawable draw, - int *xp, int *yp, int *widthp, int *heightp) -{ - int x, y; - unsigned int width, height, border, depth; - Window root; - - XGetGeometry (d, draw, &root, &x, &y, &width, &height, &border, &depth); - - if (xp) - *xp = x; - if (yp) - *yp = y; - if (widthp) - *widthp = width; - if (*heightp) - *heightp = height; -} -#endif - -int -main (int argc, char **argv) -{ - Display *d; - Window zero_min_size; - XSizeHints hints; - int screen; - XEvent ev; - int x, y, width, height; - Pixmap pix; - GC gc; - XGCValues gc_vals; - gboolean redraw_pending; - - d = XOpenDisplay (NULL); - - screen = DefaultScreen (d); - - x = 0; - y = 0; - width = 100; - height = 100; - - zero_min_size = XCreateSimpleWindow (d, RootWindow (d, screen), - x, y, width, height, 0, - WhitePixel (d, screen), - WhitePixel (d, screen)); - - XSelectInput (d, zero_min_size, - ButtonPressMask | ExposureMask | StructureNotifyMask); - - hints.flags = PMinSize; - - hints.min_width = 0; - hints.min_height = 0; - - XSetWMNormalHints (d, zero_min_size, &hints); - XMapWindow (d, zero_min_size); - - redraw_pending = FALSE; - while (1) - { - XNextEvent (d, &ev); - - switch (ev.xany.type) - { - case ButtonPress: - if (ev.xbutton.button == 1) - { - g_print ("Exiting on button 1 press\n"); - exit (0); - } - break; - - case ConfigureNotify: - x = ev.xconfigure.x; - y = ev.xconfigure.y; - width = ev.xconfigure.width; - height = ev.xconfigure.height; - - redraw_pending = TRUE; - break; - - case Expose: - redraw_pending = TRUE; - break; - - default: - break; - } - - /* Primitive event compression */ - if (XCheckIfEvent (d, &ev, all_events, NULL)) - { - XPutBackEvent (d, &ev); - } - else if (redraw_pending) - { - pix = XCreatePixmap (d, zero_min_size, width, height, - DefaultDepth (d, screen)); - - gc_vals.foreground = WhitePixel (d, screen); - - gc = XCreateGC (d, pix, GCForeground, &gc_vals); - - XFillRectangle (d, pix, gc, 0, 0, width, height); - - XCopyArea (d, pix, zero_min_size, gc, 0, 0, width, height, 0, 0); - - XFreePixmap (d, pix); - XFreeGC (d, gc); - - redraw_pending = FALSE; - } - } - - /* This program has an infinite loop above so a return statement would - * just cause compiler warnings. - */ -} - diff --git a/src/meta/atomnames.h b/src/x11/atomnames.h similarity index 88% rename from src/meta/atomnames.h rename to src/x11/atomnames.h index d10525455..4b25b099a 100644 --- a/src/meta/atomnames.h +++ b/src/x11/atomnames.h @@ -18,15 +18,13 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ -/** +/* * \file atomnames.h A list of atom names. * - * This is a list of the names of all the X atoms that Muffin uses. + * This is a list of the names of all the X atoms that Mutter uses. * Each is wrapped in a macro "item()" which is undefined here; the * idea is that when you need to make a big list of all the X atoms, * you can define item(), include this file, and then undefine it @@ -54,12 +52,8 @@ item(WM_WINDOW_ROLE) item(UTF8_STRING) item(WM_ICON_SIZE) item(_KWM_WIN_ICON) -item(_MUFFIN_RELOAD_THEME_MESSAGE) -item(_MUFFIN_SET_KEYBINDINGS_MESSAGE) -item(_MUFFIN_TOGGLE_VERBOSE) -item(_MUFFIN_HINTS) +item(_MUTTER_HINTS) item(_GTK_THEME_VARIANT) -item(_GTK_HIDE_TITLEBAR_WHEN_MAXIMIZED) item(_GTK_APPLICATION_ID) item(_GTK_UNIQUE_BUS_NAME) item(_GTK_APPLICATION_OBJECT_PATH) @@ -69,21 +63,27 @@ item(_GTK_MENUBAR_OBJECT_PATH) item(_GTK_FRAME_EXTENTS) item(_GTK_SHOW_WINDOW_MENU) item(_GTK_EDGE_CONSTRAINTS) +item(_GTK_WORKAREAS) item(_GNOME_WM_KEYBINDINGS) item(_GNOME_PANEL_ACTION) +item(_GNOME_PANEL_ACTION_MAIN_MENU) item(_GNOME_PANEL_ACTION_RUN_DIALOG) -item(_MUFFIN_SENTINEL) -item(_MUFFIN_VERSION) +item(_MUTTER_TIMESTAMP_PING) +item(_MUTTER_FOCUS_SET) +item(_MUTTER_SENTINEL) +item(_MUTTER_VERSION) item(WM_CLIENT_MACHINE) -item(_NET_WM_XAPP_ICON_NAME) -item(_NET_WM_XAPP_PROGRESS) -item(_NET_WM_XAPP_PROGRESS_PULSE) item(MANAGER) item(TARGETS) item(MULTIPLE) item(TIMESTAMP) item(VERSION) item(ATOM_PAIR) +item(_XKB_RULES_NAMES) +item(WL_SURFACE_ID) +item(_XWAYLAND_MAY_GRAB_KEYBOARD) +item(_XWAYLAND_RANDR_EMU_MONITOR_RECTS) +item(_XWAYLAND_ALLOW_COMMITS) /* Oddities: These are used, and we need atoms for them, * but when we need all _NET_WM hints (i.e. when we're making @@ -94,7 +94,6 @@ item(ATOM_PAIR) item(_NET_WM_SYNC_REQUEST) item(_NET_WM_SYNC_REQUEST_COUNTER) item(_NET_WM_VISIBLE_NAME) -item(_NET_WM_VISIBLE_ICON_NAME) item(_NET_SUPPORTING_WM_CHECK) /* But I suppose it's quite reasonable not to advertise using @@ -112,7 +111,6 @@ item(_NET_WM_STATE) item(_NET_WM_STATE_SHADED) item(_NET_WM_STATE_MAXIMIZED_HORZ) item(_NET_WM_STATE_MAXIMIZED_VERT) -item(_NET_WM_STATE_TILED) item(_NET_WM_DESKTOP) item(_NET_NUMBER_OF_DESKTOPS) item(_NET_CURRENT_DESKTOP) @@ -136,8 +134,6 @@ item(_NET_CLIENT_LIST) item(_NET_CLIENT_LIST_STACKING) item(_NET_WM_STATE_SKIP_TASKBAR) item(_NET_WM_STATE_SKIP_PAGER) -item(_NET_WM_WINDOW_TILE_INFO) -item(_NET_WM_ICON_NAME) item(_NET_WM_ICON) item(_NET_WM_ICON_GEOMETRY) item(_NET_WM_MOVERESIZE) @@ -183,6 +179,7 @@ item(_NET_WM_BYPASS_COMPOSITOR) item(_NET_WM_OPAQUE_REGION) item(_NET_WM_FRAME_DRAWN) item(_NET_WM_FRAME_TIMINGS) +item(_NET_WM_WINDOW_OPACITY) item(_NET_RESTACK_WINDOW) /* eof atomnames.h */ diff --git a/src/x11/events.c b/src/x11/events.c new file mode 100644 index 000000000..f159f1db3 --- /dev/null +++ b/src/x11/events.c @@ -0,0 +1,1925 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001 Havoc Pennington + * Copyright (C) 2002, 2003, 2004 Red Hat, Inc. + * Copyright (C) 2003, 2004 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include "x11/events.h" + +#include <X11/Xatom.h> +#include <X11/XKBlib.h> +#include <X11/extensions/Xdamage.h> +#include <X11/extensions/shape.h> + +#include "backends/meta-cursor-tracker-private.h" +#include "backends/x11/meta-backend-x11.h" +#include "compositor/meta-compositor-x11.h" +#include "cogl/cogl.h" +#include "core/bell.h" +#include "core/display-private.h" +#include "core/meta-workspace-manager-private.h" +#include "core/window-private.h" +#include "core/workspace-private.h" +#include "meta/meta-backend.h" +#include "meta/meta-x11-errors.h" +#include "x11/meta-startup-notification-x11.h" +#include "x11/meta-x11-display-private.h" +#include "x11/meta-x11-selection-private.h" +#include "x11/meta-x11-selection-input-stream-private.h" +#include "x11/meta-x11-selection-output-stream-private.h" +#include "x11/window-x11.h" +#include "x11/xprops.h" + +#ifdef HAVE_WAYLAND +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-xwayland-private.h" +#include "wayland/meta-xwayland.h" +#endif + +static XIEvent * +get_input_event (MetaX11Display *x11_display, + XEvent *event) +{ + if (event->type == GenericEvent && + event->xcookie.extension == x11_display->xinput_opcode) + { + XIEvent *input_event; + + /* NB: GDK event filters already have generic events + * allocated, so no need to do XGetEventData() on our own + */ + input_event = (XIEvent *) event->xcookie.data; + + switch (input_event->evtype) + { + case XI_Motion: + case XI_ButtonPress: + case XI_ButtonRelease: + if (((XIDeviceEvent *) input_event)->deviceid == META_VIRTUAL_CORE_POINTER_ID) + return input_event; + break; + case XI_KeyPress: + case XI_KeyRelease: + if (((XIDeviceEvent *) input_event)->deviceid == META_VIRTUAL_CORE_KEYBOARD_ID) + return input_event; + break; + case XI_FocusIn: + case XI_FocusOut: + if (((XIEnterEvent *) input_event)->deviceid == META_VIRTUAL_CORE_KEYBOARD_ID) + return input_event; + break; + case XI_Enter: + case XI_Leave: + if (((XIEnterEvent *) input_event)->deviceid == META_VIRTUAL_CORE_POINTER_ID) + return input_event; + break; + case XI_BarrierHit: + case XI_BarrierLeave: + if (((XIBarrierEvent *) input_event)->deviceid == META_VIRTUAL_CORE_POINTER_ID) + return input_event; + break; + default: + break; + } + } + + return NULL; +} + +static Window +xievent_get_modified_window (MetaX11Display *x11_display, + XIEvent *input_event) +{ + switch (input_event->evtype) + { + case XI_Motion: + case XI_ButtonPress: + case XI_ButtonRelease: + case XI_KeyPress: + case XI_KeyRelease: + return ((XIDeviceEvent *) input_event)->event; + case XI_FocusIn: + case XI_FocusOut: + case XI_Enter: + case XI_Leave: + return ((XIEnterEvent *) input_event)->event; + case XI_BarrierHit: + case XI_BarrierLeave: + return ((XIBarrierEvent *) input_event)->event; + } + + return None; +} + +/* Return the window this has to do with, if any, rather + * than the frame or root window that was selecting + * for substructure + */ +static Window +event_get_modified_window (MetaX11Display *x11_display, + XEvent *event) +{ + XIEvent *input_event = get_input_event (x11_display, event); + + if (input_event) + return xievent_get_modified_window (x11_display, input_event); + + switch (event->type) + { + case KeymapNotify: + case Expose: + case GraphicsExpose: + case NoExpose: + case VisibilityNotify: + case ResizeRequest: + case PropertyNotify: + case SelectionClear: + case SelectionRequest: + case SelectionNotify: + case ColormapNotify: + case ClientMessage: + return event->xany.window; + + case CreateNotify: + return event->xcreatewindow.window; + + case DestroyNotify: + return event->xdestroywindow.window; + + case UnmapNotify: + return event->xunmap.window; + + case MapNotify: + return event->xmap.window; + + case MapRequest: + return event->xmaprequest.window; + + case ReparentNotify: + return event->xreparent.window; + + case ConfigureNotify: + return event->xconfigure.window; + + case ConfigureRequest: + return event->xconfigurerequest.window; + + case GravityNotify: + return event->xgravity.window; + + case CirculateNotify: + return event->xcirculate.window; + + case CirculateRequest: + return event->xcirculaterequest.window; + + case MappingNotify: + return None; + + default: + if (META_X11_DISPLAY_HAS_SHAPE (x11_display) && + event->type == (x11_display->shape_event_base + ShapeNotify)) + { + XShapeEvent *sev = (XShapeEvent*) event; + return sev->window; + } + + return None; + } +} + +static guint32 +event_get_time (MetaX11Display *x11_display, + XEvent *event) +{ + XIEvent *input_event = get_input_event (x11_display, event); + + if (input_event) + return input_event->time; + + switch (event->type) + { + case PropertyNotify: + return event->xproperty.time; + + case SelectionClear: + case SelectionRequest: + case SelectionNotify: + return event->xselection.time; + + case KeymapNotify: + case Expose: + case GraphicsExpose: + case NoExpose: + case MapNotify: + case UnmapNotify: + case VisibilityNotify: + case ResizeRequest: + case ColormapNotify: + case ClientMessage: + case CreateNotify: + case DestroyNotify: + case MapRequest: + case ReparentNotify: + case ConfigureNotify: + case ConfigureRequest: + case GravityNotify: + case CirculateNotify: + case CirculateRequest: + case MappingNotify: + default: + return META_CURRENT_TIME; + } +} + +const char* +meta_event_detail_to_string (int d) +{ + const char *detail = "???"; + switch (d) + { + /* We are an ancestor in the A<->B focus change relationship */ + case XINotifyAncestor: + detail = "NotifyAncestor"; + break; + case XINotifyDetailNone: + detail = "NotifyDetailNone"; + break; + /* We are a descendant in the A<->B focus change relationship */ + case XINotifyInferior: + detail = "NotifyInferior"; + break; + case XINotifyNonlinear: + detail = "NotifyNonlinear"; + break; + case XINotifyNonlinearVirtual: + detail = "NotifyNonlinearVirtual"; + break; + case XINotifyPointer: + detail = "NotifyPointer"; + break; + case XINotifyPointerRoot: + detail = "NotifyPointerRoot"; + break; + case XINotifyVirtual: + detail = "NotifyVirtual"; + break; + } + + return detail; +} + +const char* +meta_event_mode_to_string (int m) +{ + const char *mode = "???"; + switch (m) + { + case XINotifyNormal: + mode = "NotifyNormal"; + break; + case XINotifyGrab: + mode = "NotifyGrab"; + break; + case XINotifyUngrab: + mode = "NotifyUngrab"; + break; + case XINotifyWhileGrabbed: + mode = "NotifyWhileGrabbed"; + break; + } + + return mode; +} + +G_GNUC_UNUSED static const char* +stack_mode_to_string (int mode) +{ + switch (mode) + { + case Above: + return "Above"; + case Below: + return "Below"; + case TopIf: + return "TopIf"; + case BottomIf: + return "BottomIf"; + case Opposite: + return "Opposite"; + } + + return "Unknown"; +} + +static gint64 +sync_value_to_64 (const XSyncValue *value) +{ + gint64 v; + + v = XSyncValueLow32 (*value); + v |= (((gint64)XSyncValueHigh32 (*value)) << 32); + + return v; +} + +static const char* +alarm_state_to_string (XSyncAlarmState state) +{ + switch (state) + { + case XSyncAlarmActive: + return "Active"; + case XSyncAlarmInactive: + return "Inactive"; + case XSyncAlarmDestroyed: + return "Destroyed"; + default: + return "(unknown)"; + } +} + +static void +meta_spew_xi2_event (MetaX11Display *x11_display, + XIEvent *input_event, + const char **name_p, + char **extra_p) +{ + const char *name = NULL; + char *extra = NULL; + + XIEnterEvent *enter_event = (XIEnterEvent *) input_event; + + switch (input_event->evtype) + { + case XI_FocusIn: + name = "XI_FocusIn"; + break; + case XI_FocusOut: + name = "XI_FocusOut"; + break; + case XI_Enter: + name = "XI_Enter"; + break; + case XI_Leave: + name = "XI_Leave"; + break; + case XI_BarrierHit: + name = "XI_BarrierHit"; + break; + case XI_BarrierLeave: + name = "XI_BarrierLeave"; + break; + } + + switch (input_event->evtype) + { + case XI_FocusIn: + case XI_FocusOut: + extra = g_strdup_printf ("detail: %s mode: %s\n", + meta_event_detail_to_string (enter_event->detail), + meta_event_mode_to_string (enter_event->mode)); + break; + case XI_Enter: + case XI_Leave: + extra = g_strdup_printf ("win: 0x%lx root: 0x%lx mode: %s detail: %s focus: %d x: %g y: %g", + enter_event->event, + enter_event->root, + meta_event_mode_to_string (enter_event->mode), + meta_event_detail_to_string (enter_event->detail), + enter_event->focus, + enter_event->root_x, + enter_event->root_y); + break; + } + + *name_p = name; + *extra_p = extra; +} + +static void +meta_spew_core_event (MetaX11Display *x11_display, + XEvent *event, + const char **name_p, + char **extra_p) +{ + const char *name = NULL; + char *extra = NULL; + + switch (event->type) + { + case KeymapNotify: + name = "KeymapNotify"; + break; + case Expose: + name = "Expose"; + break; + case GraphicsExpose: + name = "GraphicsExpose"; + break; + case NoExpose: + name = "NoExpose"; + break; + case VisibilityNotify: + name = "VisibilityNotify"; + break; + case CreateNotify: + name = "CreateNotify"; + extra = g_strdup_printf ("parent: 0x%lx window: 0x%lx", + event->xcreatewindow.parent, + event->xcreatewindow.window); + break; + case DestroyNotify: + name = "DestroyNotify"; + extra = g_strdup_printf ("event: 0x%lx window: 0x%lx", + event->xdestroywindow.event, + event->xdestroywindow.window); + break; + case UnmapNotify: + name = "UnmapNotify"; + extra = g_strdup_printf ("event: 0x%lx window: 0x%lx from_configure: %d", + event->xunmap.event, + event->xunmap.window, + event->xunmap.from_configure); + break; + case MapNotify: + name = "MapNotify"; + extra = g_strdup_printf ("event: 0x%lx window: 0x%lx override_redirect: %d", + event->xmap.event, + event->xmap.window, + event->xmap.override_redirect); + break; + case MapRequest: + name = "MapRequest"; + extra = g_strdup_printf ("window: 0x%lx parent: 0x%lx\n", + event->xmaprequest.window, + event->xmaprequest.parent); + break; + case ReparentNotify: + name = "ReparentNotify"; + extra = g_strdup_printf ("window: 0x%lx parent: 0x%lx event: 0x%lx\n", + event->xreparent.window, + event->xreparent.parent, + event->xreparent.event); + break; + case ConfigureNotify: + name = "ConfigureNotify"; + extra = g_strdup_printf ("x: %d y: %d w: %d h: %d above: 0x%lx override_redirect: %d", + event->xconfigure.x, + event->xconfigure.y, + event->xconfigure.width, + event->xconfigure.height, + event->xconfigure.above, + event->xconfigure.override_redirect); + break; + case ConfigureRequest: + name = "ConfigureRequest"; + extra = g_strdup_printf ("parent: 0x%lx window: 0x%lx x: %d %sy: %d %sw: %d %sh: %d %sborder: %d %sabove: %lx %sstackmode: %s %s", + event->xconfigurerequest.parent, + event->xconfigurerequest.window, + event->xconfigurerequest.x, + event->xconfigurerequest.value_mask & + CWX ? "" : "(unset) ", + event->xconfigurerequest.y, + event->xconfigurerequest.value_mask & + CWY ? "" : "(unset) ", + event->xconfigurerequest.width, + event->xconfigurerequest.value_mask & + CWWidth ? "" : "(unset) ", + event->xconfigurerequest.height, + event->xconfigurerequest.value_mask & + CWHeight ? "" : "(unset) ", + event->xconfigurerequest.border_width, + event->xconfigurerequest.value_mask & + CWBorderWidth ? "" : "(unset)", + event->xconfigurerequest.above, + event->xconfigurerequest.value_mask & + CWSibling ? "" : "(unset)", + stack_mode_to_string (event->xconfigurerequest.detail), + event->xconfigurerequest.value_mask & + CWStackMode ? "" : "(unset)"); + break; + case GravityNotify: + name = "GravityNotify"; + break; + case ResizeRequest: + name = "ResizeRequest"; + extra = g_strdup_printf ("width = %d height = %d", + event->xresizerequest.width, + event->xresizerequest.height); + break; + case CirculateNotify: + name = "CirculateNotify"; + break; + case CirculateRequest: + name = "CirculateRequest"; + break; + case PropertyNotify: + { + char *str; + const char *state; + + name = "PropertyNotify"; + + meta_x11_error_trap_push (x11_display); + str = XGetAtomName (x11_display->xdisplay, + event->xproperty.atom); + meta_x11_error_trap_pop (x11_display); + + if (event->xproperty.state == PropertyNewValue) + state = "PropertyNewValue"; + else if (event->xproperty.state == PropertyDelete) + state = "PropertyDelete"; + else + state = "???"; + + extra = g_strdup_printf ("atom: %s state: %s", + str ? str : "(unknown atom)", + state); + meta_XFree (str); + } + break; + case SelectionClear: + name = "SelectionClear"; + break; + case SelectionRequest: + name = "SelectionRequest"; + break; + case SelectionNotify: + name = "SelectionNotify"; + break; + case ColormapNotify: + name = "ColormapNotify"; + break; + case ClientMessage: + { + char *str; + name = "ClientMessage"; + meta_x11_error_trap_push (x11_display); + str = XGetAtomName (x11_display->xdisplay, + event->xclient.message_type); + meta_x11_error_trap_pop (x11_display); + extra = g_strdup_printf ("type: %s format: %d\n", + str ? str : "(unknown atom)", + event->xclient.format); + meta_XFree (str); + } + break; + case MappingNotify: + name = "MappingNotify"; + break; + default: + if (META_X11_DISPLAY_HAS_XSYNC (x11_display) && + event->type == (x11_display->xsync_event_base + XSyncAlarmNotify)) + { + XSyncAlarmNotifyEvent *aevent = (XSyncAlarmNotifyEvent*) event; + + name = "XSyncAlarmNotify"; + extra = + g_strdup_printf ("alarm: 0x%lx" + " counter_value: %" G_GINT64_FORMAT + " alarm_value: %" G_GINT64_FORMAT + " time: %u alarm state: %s", + aevent->alarm, + (gint64) sync_value_to_64 (&aevent->counter_value), + (gint64) sync_value_to_64 (&aevent->alarm_value), + (unsigned int)aevent->time, + alarm_state_to_string (aevent->state)); + } + else + if (META_X11_DISPLAY_HAS_SHAPE (x11_display) && + event->type == (x11_display->shape_event_base + ShapeNotify)) + { + XShapeEvent *sev = (XShapeEvent*) event; + + name = "ShapeNotify"; + + extra = + g_strdup_printf ("kind: %s " + "x: %d y: %d w: %u h: %u " + "shaped: %d", + sev->kind == ShapeBounding ? + "ShapeBounding" : + (sev->kind == ShapeClip ? + "ShapeClip" : "(unknown)"), + sev->x, sev->y, sev->width, sev->height, + sev->shaped); + } + else + { + name = "(Unknown event)"; + extra = g_strdup_printf ("type: %d", event->xany.type); + } + break; + } + + *name_p = name; + *extra_p = extra; +} + +static char * +meta_spew_event (MetaX11Display *x11_display, + XEvent *event) +{ + const char *name = NULL; + char *extra = NULL; + char *winname; + char *ret; + XIEvent *input_event; + + input_event = get_input_event (x11_display, event); + + if (input_event) + meta_spew_xi2_event (x11_display, input_event, &name, &extra); + else + meta_spew_core_event (x11_display, event, &name, &extra); + + if (event->xany.window == x11_display->xroot) + winname = g_strdup_printf ("root"); + else + winname = g_strdup_printf ("0x%lx", event->xany.window); + + ret = g_strdup_printf ("%s on %s%s %s %sserial %lu", name, winname, + extra ? ":" : "", extra ? extra : "", + event->xany.send_event ? "SEND " : "", + event->xany.serial); + + g_free (winname); + g_free (extra); + + return ret; +} + +G_GNUC_UNUSED static void +meta_spew_event_print (MetaX11Display *x11_display, + XEvent *event) +{ + char *event_str; + + /* filter overnumerous events */ + if (event->type == Expose || event->type == MotionNotify || + event->type == NoExpose) + return; + + if (event->type == (x11_display->damage_event_base + XDamageNotify)) + return; + + if (event->type == (x11_display->xsync_event_base + XSyncAlarmNotify)) + return; + + if (event->type == PropertyNotify && + event->xproperty.atom == x11_display->atom__NET_WM_USER_TIME) + return; + + event_str = meta_spew_event (x11_display, event); + g_print ("%s\n", event_str); + g_free (event_str); +} + +static gboolean +handle_window_focus_event (MetaX11Display *x11_display, + MetaWindow *window, + XIEnterEvent *event, + unsigned long serial) +{ + MetaDisplay *display = x11_display->display; + MetaWindow *focus_window; +#ifdef WITH_VERBOSE_MODE + const char *window_type; + + /* Note the event can be on either the window or the frame, + * we focus the frame for shaded windows + */ + if (window) + { + if (event->event == window->xwindow) + window_type = "client window"; + else if (window->frame && event->event == window->frame->xwindow) + window_type = "frame window"; + else + window_type = "unknown client window"; + } + else if (meta_x11_display_xwindow_is_a_no_focus_window (x11_display, + event->event)) + window_type = "no_focus_window"; + else if (event->event == x11_display->xroot) + window_type = "root window"; + else + window_type = "unknown window"; + + meta_topic (META_DEBUG_FOCUS, + "Focus %s event received on %s 0x%lx (%s) " + "mode %s detail %s serial %lu\n", + event->evtype == XI_FocusIn ? "in" : + event->evtype == XI_FocusOut ? "out" : + "???", + window ? window->desc : "", + event->event, window_type, + meta_event_mode_to_string (event->mode), + meta_event_detail_to_string (event->mode), + serial); +#endif + + /* FIXME our pointer tracking is broken; see how + * gtk+/gdk/x11/gdkevents-x11.c or XFree86/xc/programs/xterm/misc.c + * for how to handle it the correct way. In brief you need to track + * pointer focus and regular focus, and handle EnterNotify in + * PointerRoot mode with no window manager. However as noted above, + * accurate focus tracking will break things because we want to keep + * windows "focused" when using keybindings on them, and also we + * sometimes "focus" a window by focusing its frame or + * no_focus_window; so this all needs rethinking massively. + * + * My suggestion is to change it so that we clearly separate + * actual keyboard focus tracking using the xterm algorithm, + * and mutter's "pretend" focus window, and go through all + * the code and decide which one should be used in each place; + * a hard bit is deciding on a policy for that. + * + * http://bugzilla.gnome.org/show_bug.cgi?id=90382 + */ + + /* We ignore grabs, though this is questionable. It may be better to + * increase the intelligence of the focus window tracking. + * + * The problem is that keybindings for windows are done with + * XGrabKey, which means focus_window disappears and the front of + * the MRU list gets confused from what the user expects once a + * keybinding is used. + */ + + if (event->mode == XINotifyGrab || + event->mode == XINotifyUngrab || + /* From WindowMaker, ignore all funky pointer root events */ + event->detail > XINotifyNonlinearVirtual) + { + meta_topic (META_DEBUG_FOCUS, + "Ignoring focus event generated by a grab or other weirdness\n"); + return FALSE; + } + + if (event->evtype == XI_FocusIn) + { + x11_display->server_focus_window = event->event; + x11_display->server_focus_serial = serial; + focus_window = window; + } + else if (event->evtype == XI_FocusOut) + { + if (event->detail == XINotifyInferior) + { + /* This event means the client moved focus to a subwindow */ + meta_topic (META_DEBUG_FOCUS, + "Ignoring focus out with NotifyInferior\n"); + return FALSE; + } + + x11_display->server_focus_window = None; + x11_display->server_focus_serial = serial; + focus_window = NULL; + } + else + g_assert_not_reached (); + + /* If display->focused_by_us, then the focus_serial will be used only + * for a focus change we made and have already accounted for. + * (See request_xserver_input_focus_change().) Otherwise, we can get + * multiple focus events with the same serial. + */ + if (x11_display->server_focus_serial > x11_display->focus_serial || + (!x11_display->focused_by_us && + x11_display->server_focus_serial == x11_display->focus_serial)) + { + meta_x11_display_update_focus_window (x11_display, + focus_window ? + focus_window->xwindow : None, + x11_display->server_focus_serial, + FALSE); + meta_display_update_focus_window (display, focus_window); + return TRUE; + } + else + { + return FALSE; + } +} + +static gboolean +crossing_serial_is_ignored (MetaX11Display *x11_display, + unsigned long serial) +{ + int i; + + i = 0; + while (i < N_IGNORED_CROSSING_SERIALS) + { + if (x11_display->display->ignored_crossing_serials[i] == serial) + return TRUE; + ++i; + } + return FALSE; +} + +static gboolean +handle_input_xevent (MetaX11Display *x11_display, + XIEvent *input_event, + unsigned long serial) +{ + XIEnterEvent *enter_event = (XIEnterEvent *) input_event; + Window modified; + MetaWindow *window; + MetaDisplay *display = x11_display->display; + MetaWorkspaceManager *workspace_manager = display->workspace_manager; + + if (input_event == NULL) + return FALSE; + + switch (input_event->evtype) + { + case XI_Enter: + case XI_Leave: + case XI_FocusIn: + case XI_FocusOut: + break; + default: + return FALSE; + } + + modified = xievent_get_modified_window (x11_display, input_event); + window = modified != None ? + meta_x11_display_lookup_x_window (x11_display, modified) : + NULL; + + /* If this is an event for a GTK+ widget, let GTK+ handle it. */ + if (meta_ui_window_is_widget (x11_display->ui, modified)) + return FALSE; + + switch (input_event->evtype) + { + case XI_Enter: + if (display->event_route != META_EVENT_ROUTE_NORMAL) + break; + + /* Check if we've entered a window; do this even if window->has_focus to + * avoid races. + */ + if (window && !crossing_serial_is_ignored (x11_display, serial) && + enter_event->mode != XINotifyGrab && + enter_event->mode != XINotifyUngrab && + enter_event->detail != XINotifyInferior && + meta_x11_display_focus_sentinel_clear (x11_display)) + { + meta_window_handle_enter (window, + enter_event->time, + enter_event->root_x, + enter_event->root_y); + } + break; + case XI_Leave: + if (display->event_route != META_EVENT_ROUTE_NORMAL) + break; + + if (window != NULL && + enter_event->mode != XINotifyGrab && + enter_event->mode != XINotifyUngrab) + { + meta_window_handle_leave (window); + } + break; + case XI_FocusIn: + case XI_FocusOut: + if (handle_window_focus_event (x11_display, window, enter_event, serial) && + enter_event->event == enter_event->root) + { + if (enter_event->evtype == XI_FocusIn && + enter_event->detail == XINotifyDetailNone) + { + meta_topic (META_DEBUG_FOCUS, + "Focus got set to None, probably due to " + "brain-damage in the X protocol (see bug " + "125492). Setting the default focus window.\n"); + meta_workspace_focus_default_window (workspace_manager->active_workspace, + NULL, + meta_x11_display_get_current_time_roundtrip (x11_display)); + } + else if (enter_event->evtype == XI_FocusIn && + enter_event->mode == XINotifyNormal && + enter_event->detail == XINotifyInferior) + { + meta_topic (META_DEBUG_FOCUS, + "Focus got set to root window, probably due to " + "gnome-session logout dialog usage (see bug " + "153220). Setting the default focus window.\n"); + meta_workspace_focus_default_window (workspace_manager->active_workspace, + NULL, + meta_x11_display_get_current_time_roundtrip (x11_display)); + } + } + break; + } + + /* Don't eat events for GTK frames (we need to update the :hover state on buttons) */ + if (window && window->frame && modified == window->frame->xwindow) + return FALSE; + + /* Don't pass these events through to Clutter / GTK+ */ + return TRUE; +} + +static void +process_request_frame_extents (MetaX11Display *x11_display, + XEvent *event) +{ + /* The X window whose frame extents will be set. */ + Window xwindow = event->xclient.window; + unsigned long data[4] = { 0, 0, 0, 0 }; + + MotifWmHints *hints = NULL; + gboolean hints_set = FALSE; + + meta_verbose ("Setting frame extents for 0x%lx\n", xwindow); + + /* See if the window is decorated. */ + hints_set = meta_prop_get_motif_hints (x11_display, + xwindow, + x11_display->atom__MOTIF_WM_HINTS, + &hints); + if ((hints_set && hints->decorations) || !hints_set) + { + MetaFrameBorders borders; + + /* Return estimated frame extents for a normal window. */ + meta_ui_theme_get_frame_borders (x11_display->ui, + META_FRAME_TYPE_NORMAL, + 0, + &borders); + data[0] = borders.visible.left; + data[1] = borders.visible.right; + data[2] = borders.visible.top; + data[3] = borders.visible.bottom; + } + + meta_topic (META_DEBUG_GEOMETRY, + "Setting _NET_FRAME_EXTENTS on unmanaged window 0x%lx " + "to top = %lu, left = %lu, bottom = %lu, right = %lu\n", + xwindow, data[0], data[1], data[2], data[3]); + + meta_x11_error_trap_push (x11_display); + XChangeProperty (x11_display->xdisplay, xwindow, + x11_display->atom__NET_FRAME_EXTENTS, + XA_CARDINAL, + 32, PropModeReplace, (guchar*) data, 4); + meta_x11_error_trap_pop (x11_display); + + g_free (hints); +} + +/* from fvwm2, Copyright Matthias Clasen, Dominik Vogt */ +static gboolean +convert_property (MetaX11Display *x11_display, + Window w, + Atom target, + Atom property) +{ +#define N_TARGETS 4 + Atom conversion_targets[N_TARGETS]; + long icccm_version[] = { 2, 0 }; + + conversion_targets[0] = x11_display->atom_TARGETS; + conversion_targets[1] = x11_display->atom_MULTIPLE; + conversion_targets[2] = x11_display->atom_TIMESTAMP; + conversion_targets[3] = x11_display->atom_VERSION; + + meta_x11_error_trap_push (x11_display); + if (target == x11_display->atom_TARGETS) + XChangeProperty (x11_display->xdisplay, w, property, + XA_ATOM, 32, PropModeReplace, + (unsigned char *)conversion_targets, N_TARGETS); + else if (target == x11_display->atom_TIMESTAMP) + XChangeProperty (x11_display->xdisplay, w, property, + XA_INTEGER, 32, PropModeReplace, + (unsigned char *)&x11_display->wm_sn_timestamp, 1); + else if (target == x11_display->atom_VERSION) + XChangeProperty (x11_display->xdisplay, w, property, + XA_INTEGER, 32, PropModeReplace, + (unsigned char *)icccm_version, 2); + else + { + meta_x11_error_trap_pop_with_return (x11_display); + return FALSE; + } + + if (meta_x11_error_trap_pop_with_return (x11_display) != Success) + return FALSE; + + /* Be sure the PropertyNotify has arrived so we + * can send SelectionNotify + */ + /* FIXME the error trap pop synced anyway, right? */ + meta_topic (META_DEBUG_SYNC, "Syncing on %s\n", G_STRFUNC); + XSync (x11_display->xdisplay, False); + + return TRUE; +} + +/* from fvwm2, Copyright Matthias Clasen, Dominik Vogt */ +static void +process_selection_request (MetaX11Display *x11_display, + XEvent *event) +{ + XSelectionEvent reply; + + if (x11_display->wm_sn_selection_window != event->xselectionrequest.owner || + x11_display->wm_sn_atom != event->xselectionrequest.selection) + { + char *str; + + meta_x11_error_trap_push (x11_display); + str = XGetAtomName (x11_display->xdisplay, + event->xselectionrequest.selection); + meta_x11_error_trap_pop (x11_display); + + meta_verbose ("Selection request with selection %s window 0x%lx not a WM_Sn selection we recognize\n", + str ? str : "(bad atom)", event->xselectionrequest.owner); + + meta_XFree (str); + + return; + } + + reply.type = SelectionNotify; + reply.display = x11_display->xdisplay; + reply.requestor = event->xselectionrequest.requestor; + reply.selection = event->xselectionrequest.selection; + reply.target = event->xselectionrequest.target; + reply.property = None; + reply.time = event->xselectionrequest.time; + + if (event->xselectionrequest.target == x11_display->atom_MULTIPLE) + { + if (event->xselectionrequest.property != None) + { + Atom type, *adata; + int i, format; + unsigned long num, rest; + unsigned char *data; + + meta_x11_error_trap_push (x11_display); + if (XGetWindowProperty (x11_display->xdisplay, + event->xselectionrequest.requestor, + event->xselectionrequest.property, 0, 256, False, + x11_display->atom_ATOM_PAIR, + &type, &format, &num, &rest, &data) != Success) + { + meta_x11_error_trap_pop_with_return (x11_display); + return; + } + + if (meta_x11_error_trap_pop_with_return (x11_display) == Success) + { + /* FIXME: to be 100% correct, should deal with rest > 0, + * but since we have 4 possible targets, we will hardly ever + * meet multiple requests with a length > 8 + */ + adata = (Atom*)data; + i = 0; + while (i < (int) num) + { + if (!convert_property (x11_display, + event->xselectionrequest.requestor, + adata[i], adata[i+1])) + adata[i+1] = None; + i += 2; + } + + meta_x11_error_trap_push (x11_display); + XChangeProperty (x11_display->xdisplay, + event->xselectionrequest.requestor, + event->xselectionrequest.property, + x11_display->atom_ATOM_PAIR, + 32, PropModeReplace, data, num); + meta_x11_error_trap_pop (x11_display); + meta_XFree (data); + } + } + } + else + { + if (event->xselectionrequest.property == None) + event->xselectionrequest.property = event->xselectionrequest.target; + + if (convert_property (x11_display, + event->xselectionrequest.requestor, + event->xselectionrequest.target, + event->xselectionrequest.property)) + reply.property = event->xselectionrequest.property; + } + + XSendEvent (x11_display->xdisplay, + event->xselectionrequest.requestor, + False, 0L, (XEvent*)&reply); + + meta_verbose ("Handled selection request\n"); +} + +static gboolean +close_display_idle_cb (gpointer user_data) +{ + MetaX11Display *x11_display = META_X11_DISPLAY (user_data); + + meta_display_close (x11_display->display, + x11_display->xselectionclear_timestamp); + x11_display->display_close_idle = 0; + + return G_SOURCE_REMOVE; +} + +static gboolean +process_selection_clear (MetaX11Display *x11_display, + XEvent *event) +{ + if (x11_display->wm_sn_selection_window != event->xselectionclear.window || + x11_display->wm_sn_atom != event->xselectionclear.selection) + { + char *str; + + meta_x11_error_trap_push (x11_display); + str = XGetAtomName (x11_display->xdisplay, + event->xselectionclear.selection); + meta_x11_error_trap_pop (x11_display); + + meta_verbose ("Selection clear with selection %s window 0x%lx not a WM_Sn selection we recognize\n", + str ? str : "(bad atom)", event->xselectionclear.window); + + meta_XFree (str); + + return FALSE; + } + + meta_verbose ("Got selection clear for on display %s\n", + x11_display->name); + + /* We can't close a GdkDisplay in an even handler. */ + if (!x11_display->display_close_idle) + { + x11_display->xselectionclear_timestamp = event->xselectionclear.time; + x11_display->display_close_idle = g_idle_add (close_display_idle_cb, x11_display); + } + + return TRUE; +} + +static void +notify_bell (MetaX11Display *x11_display, + XkbAnyEvent *xkb_ev) +{ + MetaDisplay *display = x11_display->display; + XkbBellNotifyEvent *xkb_bell_event = (XkbBellNotifyEvent*) xkb_ev; + MetaWindow *window; + + window = meta_x11_display_lookup_x_window (x11_display, + xkb_bell_event->window); + if (!window && display->focus_window && display->focus_window->frame) + window = display->focus_window; + + x11_display->last_bell_time = xkb_ev->time; + if (!meta_bell_notify (display, window) && + meta_prefs_bell_is_audible ()) + { + /* Force a classic bell if the libcanberra bell failed. */ + XkbForceDeviceBell (x11_display->xdisplay, + xkb_bell_event->device, + xkb_bell_event->bell_class, + xkb_bell_event->bell_id, + xkb_bell_event->percent); + } +} + +static gboolean +handle_other_xevent (MetaX11Display *x11_display, + XEvent *event) +{ + MetaDisplay *display = x11_display->display; + MetaWorkspaceManager *workspace_manager = display->workspace_manager; + Window modified; + MetaWindow *window; + MetaWindow *property_for_window; + gboolean frame_was_receiver; + gboolean bypass_gtk = FALSE; + + modified = event_get_modified_window (x11_display, event); + window = modified != None ? meta_x11_display_lookup_x_window (x11_display, modified) : NULL; + frame_was_receiver = (window && window->frame && modified == window->frame->xwindow); + + /* We only want to respond to _NET_WM_USER_TIME property notify + * events on _NET_WM_USER_TIME_WINDOW windows; in particular, + * responding to UnmapNotify events is kind of bad. + */ + property_for_window = NULL; + if (window && modified == window->user_time_window) + { + property_for_window = window; + window = NULL; + } + + if (META_X11_DISPLAY_HAS_XSYNC (x11_display) && + event->type == (x11_display->xsync_event_base + XSyncAlarmNotify)) + { + MetaWindow *alarm_window = meta_x11_display_lookup_sync_alarm (x11_display, + ((XSyncAlarmNotifyEvent*)event)->alarm); + + if (alarm_window != NULL) + { + XSyncValue value = ((XSyncAlarmNotifyEvent*)event)->counter_value; + gint64 new_counter_value; + new_counter_value = XSyncValueLow32 (value) + ((gint64)XSyncValueHigh32 (value) << 32); + meta_window_x11_update_sync_request_counter (alarm_window, new_counter_value); + bypass_gtk = TRUE; /* GTK doesn't want to see this really */ + } + else + { + if (x11_display->alarm_filter && + x11_display->alarm_filter (x11_display, + (XSyncAlarmNotifyEvent*)event, + x11_display->alarm_filter_data)) + bypass_gtk = TRUE; + } + + goto out; + } + + if (META_X11_DISPLAY_HAS_SHAPE (x11_display) && + event->type == (x11_display->shape_event_base + ShapeNotify)) + { + bypass_gtk = TRUE; /* GTK doesn't want to see this really */ + + if (window && !frame_was_receiver) + { + XShapeEvent *sev = (XShapeEvent*) event; + + if (sev->kind == ShapeBounding) + meta_window_x11_update_shape_region (window); + else if (sev->kind == ShapeInput) + meta_window_x11_update_input_region (window); + } + else + { + meta_topic (META_DEBUG_SHAPES, + "ShapeNotify not on a client window (window %s frame_was_receiver = %d)\n", + window ? window->desc : "(none)", + frame_was_receiver); + } + + goto out; + } + + switch (event->type) + { + case KeymapNotify: + break; + case Expose: + break; + case GraphicsExpose: + break; + case NoExpose: + break; + case VisibilityNotify: + break; + case CreateNotify: + { + if (event->xcreatewindow.parent == x11_display->xroot) + meta_stack_tracker_create_event (display->stack_tracker, + &event->xcreatewindow); + } + break; + + case DestroyNotify: + { + if (event->xdestroywindow.event == x11_display->xroot) + meta_stack_tracker_destroy_event (display->stack_tracker, + &event->xdestroywindow); + } + if (window) + { + /* FIXME: It sucks that DestroyNotify events don't come with + * a timestamp; could we do something better here? Maybe X + * will change one day? + */ + guint32 timestamp; + timestamp = meta_display_get_current_time_roundtrip (display); + + if (display->grab_op != META_GRAB_OP_NONE && + display->grab_window == window) + meta_display_end_grab_op (display, timestamp); + + if (frame_was_receiver) + { + meta_warning ("Unexpected destruction of frame 0x%lx, not sure if this should silently fail or be considered a bug\n", + window->frame->xwindow); + meta_x11_error_trap_push (x11_display); + meta_window_destroy_frame (window->frame->window); + meta_x11_error_trap_pop (x11_display); + } + else + { + /* Unmanage destroyed window */ + meta_window_unmanage (window, timestamp); + window = NULL; + } + } + break; + case UnmapNotify: + if (window) + { + /* FIXME: It sucks that UnmapNotify events don't come with + * a timestamp; could we do something better here? Maybe X + * will change one day? + */ + guint32 timestamp; + timestamp = meta_display_get_current_time_roundtrip (display); + + if (display->grab_op != META_GRAB_OP_NONE && + display->grab_window == window && + window->frame == NULL) + meta_display_end_grab_op (display, timestamp); + + if (!frame_was_receiver) + { + if (window->unmaps_pending == 0) + { + meta_topic (META_DEBUG_WINDOW_STATE, + "Window %s withdrawn\n", + window->desc); + + /* Unmanage withdrawn window */ + window->withdrawn = TRUE; + meta_window_unmanage (window, timestamp); + window = NULL; + } + else + { + window->unmaps_pending -= 1; + meta_topic (META_DEBUG_WINDOW_STATE, + "Received pending unmap, %d now pending\n", + window->unmaps_pending); + } + } + } + break; + case MapNotify: + /* NB: override redirect windows wont cause a map request so we + * watch out for map notifies against any root windows too if a + * compositor is enabled: */ + if (window == NULL && event->xmap.event == x11_display->xroot) + { + window = meta_window_x11_new (display, event->xmap.window, + FALSE, META_COMP_EFFECT_CREATE); + } + else if (window && window->restore_focus_on_map && + window->reparents_pending == 0) + { + meta_window_focus (window, + meta_display_get_current_time_roundtrip (display)); + } + + break; + case MapRequest: + if (window == NULL) + { + window = meta_window_x11_new (display, event->xmaprequest.window, + FALSE, META_COMP_EFFECT_CREATE); + /* The window might have initial iconic state, but this is a + * MapRequest, fall through to ensure it is unminimized in + * that case. + */ + } + else if (frame_was_receiver) + { + meta_warning ("Map requests on the frame window are unexpected\n"); + break; + } + + /* Double check that creating the MetaWindow succeeded */ + if (window == NULL) + break; + + meta_verbose ("MapRequest on %s mapped = %d minimized = %d\n", + window->desc, window->mapped, window->minimized); + + if (window->minimized) + { + meta_window_unminimize (window); + if (window->workspace != workspace_manager->active_workspace) + { + meta_verbose ("Changing workspace due to MapRequest mapped = %d minimized = %d\n", + window->mapped, window->minimized); + meta_window_change_workspace (window, + workspace_manager->active_workspace); + } + } + break; + case ReparentNotify: + { + if (window && window->reparents_pending > 0) + window->reparents_pending -= 1; + if (event->xreparent.event == x11_display->xroot) + meta_stack_tracker_reparent_event (display->stack_tracker, + &event->xreparent); + } + break; + case ConfigureNotify: + if (event->xconfigure.event != event->xconfigure.window) + { + if (event->xconfigure.event == x11_display->xroot && + event->xconfigure.window != x11_display->composite_overlay_window) + meta_stack_tracker_configure_event (display->stack_tracker, + &event->xconfigure); + } + + if (window && window->override_redirect) + meta_window_x11_configure_notify (window, &event->xconfigure); + + break; + case ConfigureRequest: + /* This comment and code is found in both twm and fvwm */ + /* + * According to the July 27, 1988 ICCCM draft, we should ignore size and + * position fields in the WM_NORMAL_HINTS property when we map a window. + * Instead, we'll read the current geometry. Therefore, we should respond + * to configuration requests for windows which have never been mapped. + */ + if (window == NULL) + { + unsigned int xwcm; + XWindowChanges xwc; + + xwcm = event->xconfigurerequest.value_mask & + (CWX | CWY | CWWidth | CWHeight | CWBorderWidth); + + xwc.x = event->xconfigurerequest.x; + xwc.y = event->xconfigurerequest.y; + xwc.width = event->xconfigurerequest.width; + xwc.height = event->xconfigurerequest.height; + xwc.border_width = event->xconfigurerequest.border_width; + + meta_verbose ("Configuring withdrawn window to %d,%d %dx%d border %d (some values may not be in mask)\n", + xwc.x, xwc.y, xwc.width, xwc.height, xwc.border_width); + meta_x11_error_trap_push (x11_display); + XConfigureWindow (x11_display->xdisplay, event->xconfigurerequest.window, + xwcm, &xwc); + meta_x11_error_trap_pop (x11_display); + } + else + { + if (!frame_was_receiver) + meta_window_x11_configure_request (window, event); + } + break; + case GravityNotify: + break; + case ResizeRequest: + break; + case CirculateNotify: + break; + case CirculateRequest: + break; + case PropertyNotify: + { + MetaGroup *group; + + if (window && !frame_was_receiver) + meta_window_x11_property_notify (window, event); + else if (property_for_window && !frame_was_receiver) + meta_window_x11_property_notify (property_for_window, event); + + group = meta_x11_display_lookup_group (x11_display, + event->xproperty.window); + if (group != NULL) + meta_group_property_notify (group, event); + + if (event->xproperty.window == x11_display->xroot) + { + if (event->xproperty.atom == + x11_display->atom__NET_DESKTOP_LAYOUT) + meta_x11_display_update_workspace_layout (x11_display); + else if (event->xproperty.atom == + x11_display->atom__NET_DESKTOP_NAMES) + meta_x11_display_update_workspace_names (x11_display); + + /* we just use this property as a sentinel to avoid + * certain race conditions. See the comment for the + * sentinel_counter variable declaration in display.h + */ + if (event->xproperty.atom == + x11_display->atom__MUTTER_SENTINEL) + { + meta_x11_display_decrement_focus_sentinel (x11_display); + } + } + } + break; + case SelectionRequest: + process_selection_request (x11_display, event); + break; + case SelectionNotify: + break; + case ColormapNotify: + break; + case ClientMessage: + if (window) + { +#ifdef HAVE_WAYLAND + if (event->xclient.message_type == x11_display->atom_WL_SURFACE_ID) + { + guint32 surface_id = event->xclient.data.l[0]; + meta_xwayland_handle_wl_surface_id (window, surface_id); + } + else if (event->xclient.message_type == + x11_display->atom__XWAYLAND_MAY_GRAB_KEYBOARD) + { + if (meta_is_wayland_compositor ()) + g_object_set (G_OBJECT (window), + "xwayland-may-grab-keyboard", (event->xclient.data.l[0] != 0), + NULL); + } + else +#endif + if (!frame_was_receiver) + meta_window_x11_client_message (window, event); + } + else + { + if (event->xclient.window == x11_display->xroot) + { + if (event->xclient.message_type == + x11_display->atom__NET_CURRENT_DESKTOP) + { + int space; + MetaWorkspace *workspace; + guint32 time; + + space = event->xclient.data.l[0]; + time = event->xclient.data.l[1]; + + meta_verbose ("Request to change current workspace to %d with " + "specified timestamp of %u\n", + space, time); + + workspace = meta_workspace_manager_get_workspace_by_index (workspace_manager, space); + + if (workspace) + { + /* Handle clients using the older version of the spec... */ + if (time == 0) + time = meta_x11_display_get_current_time_roundtrip (x11_display); + + meta_workspace_activate (workspace, time); + } + else + { + meta_verbose ("Don't know about workspace %d\n", space); + } + } + else if (event->xclient.message_type == + x11_display->atom__NET_NUMBER_OF_DESKTOPS) + { + int num_spaces; + + num_spaces = event->xclient.data.l[0]; + + meta_verbose ("Request to set number of workspaces to %d\n", + num_spaces); + + meta_prefs_set_num_workspaces (num_spaces); + } + else if (event->xclient.message_type == + x11_display->atom__NET_SHOWING_DESKTOP) + { + gboolean showing_desktop; + guint32 timestamp; + + showing_desktop = event->xclient.data.l[0] != 0; + /* FIXME: Braindead protocol doesn't have a timestamp */ + timestamp = meta_x11_display_get_current_time_roundtrip (x11_display); + meta_verbose ("Request to %s desktop\n", + showing_desktop ? "show" : "hide"); + + if (showing_desktop) + meta_workspace_manager_show_desktop (workspace_manager, timestamp); + else + { + meta_workspace_manager_unshow_desktop (workspace_manager); + meta_workspace_focus_default_window (workspace_manager->active_workspace, NULL, timestamp); + } + } + else if (event->xclient.message_type == + x11_display->atom_WM_PROTOCOLS) + { + meta_verbose ("Received WM_PROTOCOLS message\n"); + + if ((Atom)event->xclient.data.l[0] == x11_display->atom__NET_WM_PING) + { + guint32 timestamp = event->xclient.data.l[1]; + + meta_display_pong_for_serial (display, timestamp); + + /* We don't want ping reply events going into + * the GTK+ event loop because gtk+ will treat + * them as ping requests and send more replies. + */ + bypass_gtk = TRUE; + } + } + } + + if (event->xclient.message_type == + x11_display->atom__NET_REQUEST_FRAME_EXTENTS) + { + meta_verbose ("Received _NET_REQUEST_FRAME_EXTENTS message\n"); + process_request_frame_extents (x11_display, event); + } + } + break; + case MappingNotify: + { + gboolean ignore_current; + + ignore_current = FALSE; + + /* Check whether the next event is an identical MappingNotify + * event. If it is, ignore the current event, we'll update + * when we get the next one. + */ + if (XPending (x11_display->xdisplay)) + { + XEvent next_event; + + XPeekEvent (x11_display->xdisplay, &next_event); + + if (next_event.type == MappingNotify && + next_event.xmapping.request == event->xmapping.request) + ignore_current = TRUE; + } + + if (!ignore_current) + { + /* Let XLib know that there is a new keyboard mapping. + */ + XRefreshKeyboardMapping (&event->xmapping); + } + } + break; + default: + if (event->type == x11_display->xkb_base_event_type) + { + XkbAnyEvent *xkb_ev = (XkbAnyEvent *) event; + + switch (xkb_ev->xkb_type) + { + case XkbBellNotify: + if (XSERVER_TIME_IS_BEFORE(x11_display->last_bell_time, + xkb_ev->time - 100)) + { + notify_bell (x11_display, xkb_ev); + } + break; + default: + break; + } + } + break; + } + + out: + return bypass_gtk; +} + +static gboolean +window_has_xwindow (MetaWindow *window, + Window xwindow) +{ + if (window->xwindow == xwindow) + return TRUE; + + if (window->frame && window->frame->xwindow == xwindow) + return TRUE; + + return FALSE; +} + +static gboolean +process_selection_event (MetaX11Display *x11_display, + XEvent *event) +{ + gboolean handled = FALSE; + GList *l; + + handled |= meta_x11_selection_handle_event (x11_display, event); + + for (l = x11_display->selection.input_streams; l && !handled;) + { + GList *next = l->next; + + handled |= meta_x11_selection_input_stream_xevent (l->data, event); + l = next; + } + + for (l = x11_display->selection.output_streams; l && !handled;) + { + GList *next = l->next; + + handled |= meta_x11_selection_output_stream_xevent (l->data, event); + l = next; + } + + return handled; +} + +/** + * meta_display_handle_xevent: + * @display: The MetaDisplay that events are coming from + * @event: The event that just happened + * + * This is the most important function in the whole program. It is the heart, + * it is the nexus, it is the Grand Central Station of Mutter's world. + * When we create a #MetaDisplay, we ask GDK to pass *all* events for *all* + * windows to this function. So every time anything happens that we might + * want to know about, this function gets called. You see why it gets a bit + * busy around here. Most of this function is a ginormous switch statement + * dealing with all the kinds of events that might turn up. + */ +static gboolean +meta_x11_display_handle_xevent (MetaX11Display *x11_display, + XEvent *event) +{ + MetaDisplay *display = x11_display->display; + MetaBackend *backend = meta_get_backend (); + Window modified; + gboolean bypass_compositor = FALSE, bypass_gtk = FALSE; + XIEvent *input_event; + MetaCursorTracker *cursor_tracker; + + COGL_TRACE_BEGIN_SCOPED (MetaX11DisplayHandleXevent, + "X11Display (handle X11 event)"); + +#if 0 + meta_spew_event_print (x11_display, event); +#endif + + if (meta_x11_startup_notification_handle_xevent (x11_display, event)) + { + bypass_gtk = bypass_compositor = TRUE; + goto out; + } + +#ifdef HAVE_WAYLAND + if (meta_is_wayland_compositor () && + meta_xwayland_dnd_handle_event (event)) + { + bypass_gtk = bypass_compositor = TRUE; + goto out; + } +#endif + + if (process_selection_event (x11_display, event)) + { + bypass_gtk = bypass_compositor = TRUE; + goto out; + } + + display->current_time = event_get_time (x11_display, event); + + if (META_IS_BACKEND_X11 (backend)) + meta_backend_x11_handle_event (META_BACKEND_X11 (backend), event); + + if (x11_display->focused_by_us && + event->xany.serial > x11_display->focus_serial && + display->focus_window && + !window_has_xwindow (display->focus_window, x11_display->server_focus_window)) + { + meta_topic (META_DEBUG_FOCUS, "Earlier attempt to focus %s failed\n", + display->focus_window->desc); + meta_x11_display_update_focus_window (x11_display, + x11_display->server_focus_window, + x11_display->server_focus_serial, + FALSE); + meta_display_update_focus_window (display, + meta_x11_display_lookup_x_window (x11_display, + x11_display->server_focus_window)); + } + + if (event->xany.window == x11_display->xroot) + { + cursor_tracker = meta_backend_get_cursor_tracker (backend); + if (meta_cursor_tracker_handle_xevent (cursor_tracker, event)) + { + bypass_gtk = bypass_compositor = TRUE; + goto out; + } + } + + modified = event_get_modified_window (x11_display, event); + + input_event = get_input_event (x11_display, event); + + if (event->type == UnmapNotify) + { + if (meta_ui_window_should_not_cause_focus (x11_display->xdisplay, + modified)) + { + meta_display_add_ignored_crossing_serial (display, event->xany.serial); + meta_topic (META_DEBUG_FOCUS, + "Adding EnterNotify serial %lu to ignored focus serials\n", + event->xany.serial); + } + } + + if (meta_x11_display_process_barrier_xevent (x11_display, input_event)) + { + bypass_gtk = bypass_compositor = TRUE; + goto out; + } + + if (handle_input_xevent (x11_display, input_event, event->xany.serial)) + { + bypass_gtk = bypass_compositor = TRUE; + goto out; + } + + if (handle_other_xevent (x11_display, event)) + { + bypass_gtk = TRUE; + goto out; + } + + if (event->type == SelectionClear) + { + if (process_selection_clear (x11_display, event)) + { + bypass_gtk = TRUE; + goto out; + } + } + + out: + if (!bypass_compositor && META_IS_COMPOSITOR_X11 (display->compositor)) + { + MetaCompositorX11 *compositor_x11 = + META_COMPOSITOR_X11 (display->compositor); + MetaWindow *window; + + if (modified != None) + window = meta_x11_display_lookup_x_window (x11_display, modified); + else + window = NULL; + + meta_compositor_x11_process_xevent (compositor_x11, event, window); + } + + display->current_time = META_CURRENT_TIME; + return bypass_gtk; +} + + +static GdkFilterReturn +xevent_filter (GdkXEvent *xevent, + GdkEvent *event, + gpointer data) +{ + MetaX11Display *x11_display = data; + + if (meta_x11_display_handle_xevent (x11_display, xevent)) + return GDK_FILTER_REMOVE; + else + return GDK_FILTER_CONTINUE; +} + +void +meta_x11_display_init_events (MetaX11Display *x11_display) +{ + gdk_window_add_filter (NULL, xevent_filter, x11_display); +} + +void +meta_x11_display_free_events (MetaX11Display *x11_display) +{ + gdk_window_remove_filter (NULL, xevent_filter, x11_display); +} diff --git a/src/x11/events.h b/src/x11/events.h new file mode 100644 index 000000000..7e73edab6 --- /dev/null +++ b/src/x11/events.h @@ -0,0 +1,31 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001 Havoc Pennington + * Copyright (C) 2002, 2003, 2004 Red Hat, Inc. + * Copyright (C) 2003, 2004 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "meta/display.h" + +#ifndef META_EVENTS_X11_H +#define META_EVENTS_X11_H + +void meta_x11_display_init_events (MetaX11Display *x11_display); +void meta_x11_display_free_events (MetaX11Display *x11_display); + +#endif diff --git a/src/core/group-private.h b/src/x11/group-private.h similarity index 77% rename from src/core/group-private.h rename to src/x11/group-private.h index bdadce998..f8149becc 100644 --- a/src/core/group-private.h +++ b/src/x11/group-private.h @@ -1,10 +1,10 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* Muffin window group private header */ +/* Mutter window group private header */ -/* +/* * Copyright (C) 2002 Red Hat Inc. - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the @@ -14,22 +14,20 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_GROUP_PRIVATE_H #define META_GROUP_PRIVATE_H -#include <meta/group.h> +#include "meta/group.h" struct _MetaGroup { int refcount; - MetaDisplay *display; + MetaX11Display *x11_display; GSList *windows; Window group_leader; char *startup_id; diff --git a/src/core/group-props.c b/src/x11/group-props.c similarity index 56% rename from src/core/group-props.c rename to src/x11/group-props.c index 58ea6b426..a906696c3 100644 --- a/src/core/group-props.c +++ b/src/x11/group-props.c @@ -16,22 +16,24 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ -#include <config.h> -#include "group-props.h" -#include "group-private.h" -#include "xprops.h" +#include "config.h" + +#include "x11/group-props.h" + #include <X11/Xatom.h> -typedef void (* InitValueFunc) (MetaDisplay *display, - Atom property, - MetaPropValue *value); -typedef void (* ReloadValueFunc) (MetaGroup *group, - MetaPropValue *value); +#include "x11/group-private.h" +#include "x11/meta-x11-display-private.h" +#include "x11/xprops.h" + +typedef void (* InitValueFunc) (MetaX11Display *x11_display, + Atom property, + MetaPropValue *value); +typedef void (* ReloadValueFunc) (MetaGroup *group, + MetaPropValue *value); struct _MetaGroupPropHooks { @@ -40,24 +42,22 @@ struct _MetaGroupPropHooks ReloadValueFunc reload_func; }; -static void init_prop_value (MetaDisplay *display, - Atom property, - MetaPropValue *value); -static void reload_prop_value (MetaGroup *group, - MetaPropValue *value); -static MetaGroupPropHooks* find_hooks (MetaDisplay *display, - Atom property); - - +static void init_prop_value (MetaX11Display *x11_display, + Atom property, + MetaPropValue *value); +static void reload_prop_value (MetaGroup *group, + MetaPropValue *value); +static MetaGroupPropHooks *find_hooks (MetaX11Display *x11_display, + Atom property); -LOCAL_SYMBOL void +void meta_group_reload_property (MetaGroup *group, Atom property) { meta_group_reload_properties (group, &property, 1); } -LOCAL_SYMBOL void +void meta_group_reload_properties (MetaGroup *group, const Atom *properties, int n_properties) @@ -73,11 +73,12 @@ meta_group_reload_properties (MetaGroup *group, i = 0; while (i < n_properties) { - init_prop_value (group->display, properties[i], &values[i]); + init_prop_value (group->x11_display, properties[i], &values[i]); ++i; } - meta_prop_get_values (group->display, group->group_leader, + meta_prop_get_values (group->x11_display, + group->group_leader, values, n_properties); i = 0; @@ -90,23 +91,23 @@ meta_group_reload_properties (MetaGroup *group, meta_prop_free_values (values, n_properties); - free (values); + g_free (values); } /* Fill in the MetaPropValue used to get the value of "property" */ static void -init_prop_value (MetaDisplay *display, - Atom property, - MetaPropValue *value) +init_prop_value (MetaX11Display *x11_display, + Atom property, + MetaPropValue *value) { MetaGroupPropHooks *hooks; value->type = META_PROP_VALUE_INVALID; value->atom = None; - hooks = find_hooks (display, property); + hooks = find_hooks (x11_display, property); if (hooks && hooks->init_func != NULL) - (* hooks->init_func) (display, property, value); + (* hooks->init_func) (x11_display, property, value); } static void @@ -115,25 +116,25 @@ reload_prop_value (MetaGroup *group, { MetaGroupPropHooks *hooks; - hooks = find_hooks (group->display, value->atom); + hooks = find_hooks (group->x11_display, value->atom); if (hooks && hooks->reload_func != NULL) (* hooks->reload_func) (group, value); } static void -init_wm_client_machine (MetaDisplay *display, - Atom property, - MetaPropValue *value) +init_wm_client_machine (MetaX11Display *x11_display, + Atom property, + MetaPropValue *value) { value->type = META_PROP_VALUE_STRING; - value->atom = display->atom_WM_CLIENT_MACHINE; + value->atom = x11_display->atom_WM_CLIENT_MACHINE; } static void reload_wm_client_machine (MetaGroup *group, MetaPropValue *value) { - free (group->wm_client_machine); + g_free (group->wm_client_machine); group->wm_client_machine = NULL; if (value->type != META_PROP_VALUE_INVALID) @@ -144,19 +145,19 @@ reload_wm_client_machine (MetaGroup *group, } static void -init_net_startup_id (MetaDisplay *display, - Atom property, - MetaPropValue *value) +init_net_startup_id (MetaX11Display *x11_display, + Atom property, + MetaPropValue *value) { value->type = META_PROP_VALUE_UTF8; - value->atom = display->atom__NET_STARTUP_ID; + value->atom = x11_display->atom__NET_STARTUP_ID; } static void reload_net_startup_id (MetaGroup *group, MetaPropValue *value) { - free (group->startup_id); + g_free (group->startup_id); group->startup_id = NULL; if (value->type != META_PROP_VALUE_INVALID) @@ -168,30 +169,30 @@ reload_net_startup_id (MetaGroup *group, #define N_HOOKS 3 -LOCAL_SYMBOL void -meta_display_init_group_prop_hooks (MetaDisplay *display) +void +meta_x11_display_init_group_prop_hooks (MetaX11Display *x11_display) { int i; MetaGroupPropHooks *hooks; - g_assert (display->group_prop_hooks == NULL); + g_assert (x11_display->group_prop_hooks == NULL); - display->group_prop_hooks = g_new0 (MetaGroupPropHooks, N_HOOKS); - hooks = display->group_prop_hooks; + x11_display->group_prop_hooks = g_new0 (MetaGroupPropHooks, N_HOOKS); + hooks = x11_display->group_prop_hooks; i = 0; - hooks[i].property = display->atom_WM_CLIENT_MACHINE; + hooks[i].property = x11_display->atom_WM_CLIENT_MACHINE; hooks[i].init_func = init_wm_client_machine; hooks[i].reload_func = reload_wm_client_machine; ++i; - hooks[i].property = display->atom__NET_WM_PID; + hooks[i].property = x11_display->atom__NET_WM_PID; hooks[i].init_func = NULL; hooks[i].reload_func = NULL; ++i; - hooks[i].property = display->atom__NET_STARTUP_ID; + hooks[i].property = x11_display->atom__NET_STARTUP_ID; hooks[i].init_func = init_net_startup_id; hooks[i].reload_func = reload_net_startup_id; ++i; @@ -202,18 +203,18 @@ meta_display_init_group_prop_hooks (MetaDisplay *display) } } -LOCAL_SYMBOL void -meta_display_free_group_prop_hooks (MetaDisplay *display) +void +meta_x11_display_free_group_prop_hooks (MetaX11Display *x11_display) { - g_assert (display->group_prop_hooks != NULL); + g_assert (x11_display->group_prop_hooks != NULL); - free (display->group_prop_hooks); - display->group_prop_hooks = NULL; + g_free (x11_display->group_prop_hooks); + x11_display->group_prop_hooks = NULL; } static MetaGroupPropHooks* -find_hooks (MetaDisplay *display, - Atom property) +find_hooks (MetaX11Display *x11_display, + Atom property) { int i; @@ -224,8 +225,8 @@ find_hooks (MetaDisplay *display, i = 0; while (i < N_HOOKS) { - if (display->group_prop_hooks[i].property == property) - return &display->group_prop_hooks[i]; + if (x11_display->group_prop_hooks[i].property == property) + return &x11_display->group_prop_hooks[i]; ++i; } diff --git a/src/core/group-props.h b/src/x11/group-props.h similarity index 76% rename from src/core/group-props.h rename to src/x11/group-props.h index c4a880853..19b570008 100644 --- a/src/core/group-props.h +++ b/src/x11/group-props.h @@ -2,9 +2,9 @@ /* MetaGroup property handling */ -/* +/* * Copyright (C) 2002 Red Hat, Inc. - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the @@ -14,25 +14,24 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_GROUP_PROPS_H #define META_GROUP_PROPS_H -#include <meta/group.h> -#include "window-private.h" +#include "core/window-private.h" +#include "meta/group.h" void meta_group_reload_property (MetaGroup *group, Atom property); void meta_group_reload_properties (MetaGroup *group, const Atom *properties, int n_properties); -void meta_display_init_group_prop_hooks (MetaDisplay *display); -void meta_display_free_group_prop_hooks (MetaDisplay *display); + +void meta_x11_display_init_group_prop_hooks (MetaX11Display *x11_display); +void meta_x11_display_free_group_prop_hooks (MetaX11Display *x11_display); #endif /* META_GROUP_PROPS_H */ diff --git a/src/core/group.c b/src/x11/group.c similarity index 64% rename from src/core/group.c rename to src/x11/group.c index c33fe157d..60f2d2902 100644 --- a/src/core/group.c +++ b/src/x11/group.c @@ -15,31 +15,33 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ /** * SECTION:group * @title: MetaGroup - * @short_description: Muffin window groups + * @short_description: Mutter window groups * */ +#include "config.h" -#include <config.h> -#include <meta/util.h> -#include "group-private.h" -#include "group-props.h" -#include "window-private.h" -#include <meta/window.h> +#include "x11/group-private.h" + +#include <X11/Xlib-xcb.h> + +#include "core/window-private.h" +#include "meta/util.h" +#include "meta/window.h" +#include "x11/group-props.h" +#include "x11/meta-x11-display-private.h" static MetaGroup* -meta_group_new (MetaDisplay *display, - Window group_leader) +meta_group_new (MetaX11Display *x11_display, + Window group_leader) { - MetaGroup *group; + g_autofree MetaGroup *group = NULL; #define N_INITIAL_PROPS 3 Atom initial_props[N_INITIAL_PROPS]; int i; @@ -48,26 +50,39 @@ meta_group_new (MetaDisplay *display, group = g_new0 (MetaGroup, 1); - group->display = display; + group->x11_display = x11_display; group->windows = NULL; group->group_leader = group_leader; group->refcount = 1; /* owned by caller, hash table has only weak ref */ - if (display->groups_by_leader == NULL) - display->groups_by_leader = g_hash_table_new (meta_unsigned_long_hash, - meta_unsigned_long_equal); + xcb_connection_t *xcb_conn = XGetXCBConnection (x11_display->xdisplay); + xcb_generic_error_t *e; + g_autofree xcb_get_window_attributes_reply_t *attrs = + xcb_get_window_attributes_reply (xcb_conn, + xcb_get_window_attributes (xcb_conn, group_leader), + &e); + if (e) + return NULL; + + const uint32_t events[] = { attrs->your_event_mask | XCB_EVENT_MASK_PROPERTY_CHANGE }; + xcb_change_window_attributes (xcb_conn, group_leader, + XCB_CW_EVENT_MASK, events); + + if (x11_display->groups_by_leader == NULL) + x11_display->groups_by_leader = g_hash_table_new (meta_unsigned_long_hash, + meta_unsigned_long_equal); - g_assert (g_hash_table_lookup (display->groups_by_leader, &group_leader) == NULL); + g_assert (g_hash_table_lookup (x11_display->groups_by_leader, &group_leader) == NULL); - g_hash_table_insert (display->groups_by_leader, + g_hash_table_insert (x11_display->groups_by_leader, &group->group_leader, group); /* Fill these in the order we want them to be gotten */ i = 0; - initial_props[i++] = display->atom_WM_CLIENT_MACHINE; - initial_props[i++] = display->atom__NET_WM_PID; - initial_props[i++] = display->atom__NET_STARTUP_ID; + initial_props[i++] = x11_display->atom_WM_CLIENT_MACHINE; + initial_props[i++] = x11_display->atom__NET_WM_PID; + initial_props[i++] = x11_display->atom__NET_STARTUP_ID; g_assert (N_INITIAL_PROPS == i); meta_group_reload_properties (group, initial_props, N_INITIAL_PROPS); @@ -76,7 +91,7 @@ meta_group_new (MetaDisplay *display, "Created new group with leader 0x%lx\n", group->group_leader); - return group; + return g_steal_pointer (&group); } static void @@ -91,27 +106,28 @@ meta_group_unref (MetaGroup *group) "Destroying group with leader 0x%lx\n", group->group_leader); - g_assert (group->display->groups_by_leader != NULL); + g_assert (group->x11_display->groups_by_leader != NULL); - g_hash_table_remove (group->display->groups_by_leader, + g_hash_table_remove (group->x11_display->groups_by_leader, &group->group_leader); /* mop up hash table, this is how it gets freed on display close */ - if (g_hash_table_size (group->display->groups_by_leader) == 0) + if (g_hash_table_size (group->x11_display->groups_by_leader) == 0) { - g_hash_table_destroy (group->display->groups_by_leader); - group->display->groups_by_leader = NULL; + g_hash_table_destroy (group->x11_display->groups_by_leader); + group->x11_display->groups_by_leader = NULL; } - free (group->wm_client_machine); - free (group->startup_id); + g_free (group->wm_client_machine); + g_free (group->startup_id); - free (group); + g_free (group); } } /** * meta_window_get_group: (skip) + * @window: a #MetaWindow * */ MetaGroup* @@ -128,6 +144,7 @@ meta_window_compute_group (MetaWindow* window) { MetaGroup *group; MetaWindow *ancestor; + MetaX11Display *x11_display = window->display->x11_display; /* use window->xwindow if no window->xgroup_leader */ @@ -138,15 +155,15 @@ meta_window_compute_group (MetaWindow* window) */ ancestor = meta_window_find_root_ancestor (window); - if (window->display->groups_by_leader) + if (x11_display->groups_by_leader) { if (ancestor != window) group = ancestor->group; else if (window->xgroup_leader != None) - group = g_hash_table_lookup (window->display->groups_by_leader, + group = g_hash_table_lookup (x11_display->groups_by_leader, &window->xgroup_leader); else - group = g_hash_table_lookup (window->display->groups_by_leader, + group = g_hash_table_lookup (x11_display->groups_by_leader, &window->xwindow); } @@ -158,24 +175,26 @@ meta_window_compute_group (MetaWindow* window) else { if (ancestor != window && ancestor->xgroup_leader != None) - group = meta_group_new (window->display, + group = meta_group_new (x11_display, ancestor->xgroup_leader); else if (window->xgroup_leader != None) - group = meta_group_new (window->display, + group = meta_group_new (x11_display, window->xgroup_leader); else - group = meta_group_new (window->display, + group = meta_group_new (x11_display, window->xwindow); window->group = group; } + if (!window->group) + return; + window->group->windows = g_slist_prepend (window->group->windows, window); meta_topic (META_DEBUG_GROUPS, "Adding %s to group with leader 0x%lx\n", window->desc, group->group_leader); - } static void @@ -209,19 +228,21 @@ meta_window_shutdown_group (MetaWindow *window) } /** - * meta_display_lookup_group: (skip) + * meta_x11_display_lookup_group: (skip) + * @x11_display: a #MetaX11Display + * @group_leader: a X window * */ -MetaGroup* -meta_display_lookup_group (MetaDisplay *display, - Window group_leader) +MetaGroup * +meta_x11_display_lookup_group (MetaX11Display *x11_display, + Window group_leader) { MetaGroup *group; group = NULL; - if (display->groups_by_leader) - group = g_hash_table_lookup (display->groups_by_leader, + if (x11_display->groups_by_leader) + group = g_hash_table_lookup (x11_display->groups_by_leader, &group_leader); return group; @@ -258,10 +279,10 @@ meta_group_update_layers (MetaGroup *group) * but doesn't hurt anything. have to handle * groups that span 2 screens. */ - meta_stack_freeze (window->screen->stack); - frozen_stacks = g_slist_prepend (frozen_stacks, window->screen->stack); + meta_stack_freeze (window->display->stack); + frozen_stacks = g_slist_prepend (frozen_stacks, window->display->stack); - meta_stack_update_layer (window->screen->stack, + meta_stack_update_layer (window->display->stack, window); tmp = tmp->next; @@ -285,6 +306,8 @@ meta_group_get_startup_id (MetaGroup *group) /** * meta_group_property_notify: (skip) + * @group: a #MetaGroup + * @event: a X event * */ gboolean diff --git a/src/x11/iconcache.c b/src/x11/iconcache.c new file mode 100644 index 000000000..941cf2075 --- /dev/null +++ b/src/x11/iconcache.c @@ -0,0 +1,575 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* Mutter window icons */ + +/* + * Copyright (C) 2002 Havoc Pennington + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include "x11/iconcache.h" + +#include <cairo.h> +#include <cairo-xlib.h> +#include <cairo-xlib-xrender.h> +#include <X11/Xatom.h> +#include <X11/extensions/Xrender.h> + +#include "meta/meta-x11-errors.h" +#include "x11/meta-x11-display-private.h" + +static gboolean +find_largest_sizes (gulong *data, + gulong nitems, + int *width, + int *height) +{ + *width = 0; + *height = 0; + + while (nitems > 0) + { + int w, h; + + if (nitems < 3) + return FALSE; /* no space for w, h */ + + w = data[0]; + h = data[1]; + + if (nitems < ((gulong)(w * h) + 2)) + return FALSE; /* not enough data */ + + *width = MAX (w, *width); + *height = MAX (h, *height); + + data += (w * h) + 2; + nitems -= (w * h) + 2; + } + + return TRUE; +} + +static gboolean +find_best_size (gulong *data, + gulong nitems, + int ideal_width, + int ideal_height, + int *width, + int *height, + gulong **start) +{ + int best_w; + int best_h; + gulong *best_start; + int max_width, max_height; + + *width = 0; + *height = 0; + *start = NULL; + + if (!find_largest_sizes (data, nitems, &max_width, &max_height)) + return FALSE; + + if (ideal_width < 0) + ideal_width = max_width; + if (ideal_height < 0) + ideal_height = max_height; + + best_w = 0; + best_h = 0; + best_start = NULL; + + while (nitems > 0) + { + int w, h; + gboolean replace; + + replace = FALSE; + + if (nitems < 3) + return FALSE; /* no space for w, h */ + + w = data[0]; + h = data[1]; + + if (nitems < ((gulong)(w * h) + 2)) + break; /* not enough data */ + + if (best_start == NULL) + { + replace = TRUE; + } + else + { + /* work with averages */ + const int ideal_size = (ideal_width + ideal_height) / 2; + int best_size = (best_w + best_h) / 2; + int this_size = (w + h) / 2; + + /* larger than desired is always better than smaller */ + if (best_size < ideal_size && + this_size >= ideal_size) + replace = TRUE; + /* if we have too small, pick anything bigger */ + else if (best_size < ideal_size && + this_size > best_size) + replace = TRUE; + /* if we have too large, pick anything smaller + * but still >= the ideal + */ + else if (best_size > ideal_size && + this_size >= ideal_size && + this_size < best_size) + replace = TRUE; + } + + if (replace) + { + best_start = data + 2; + best_w = w; + best_h = h; + } + + data += (w * h) + 2; + nitems -= (w * h) + 2; + } + + if (best_start) + { + *start = best_start; + *width = best_w; + *height = best_h; + return TRUE; + } + else + return FALSE; +} + +static cairo_surface_t * +argbdata_to_surface (gulong *argb_data, int w, int h) +{ + cairo_surface_t *surface; + int y, x, stride; + uint32_t *data; + + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h); + stride = cairo_image_surface_get_stride (surface) / sizeof (uint32_t); + data = (uint32_t *) cairo_image_surface_get_data (surface); + + /* One could speed this up a lot. */ + for (y = 0; y < h; y++) + { + for (x = 0; x < w; x++) + { + uint32_t *p = &data[y * stride + x]; + gulong *d = &argb_data[y * w + x]; + *p = *d; + } + } + + cairo_surface_mark_dirty (surface); + + return surface; +} + +static gboolean +read_rgb_icon (MetaX11Display *x11_display, + Window xwindow, + int ideal_width, + int ideal_height, + int ideal_mini_width, + int ideal_mini_height, + cairo_surface_t **icon, + cairo_surface_t **mini_icon) +{ + Atom type; + int format; + gulong nitems; + gulong bytes_after; + int result, err; + guchar *data; + gulong *best; + int w, h; + gulong *best_mini; + int mini_w, mini_h; + gulong *data_as_long; + + meta_x11_error_trap_push (x11_display); + type = None; + data = NULL; + result = XGetWindowProperty (x11_display->xdisplay, + xwindow, + x11_display->atom__NET_WM_ICON, + 0, G_MAXLONG, + False, XA_CARDINAL, &type, &format, &nitems, + &bytes_after, &data); + err = meta_x11_error_trap_pop_with_return (x11_display); + + if (err != Success || + result != Success) + return FALSE; + + if (type != XA_CARDINAL) + { + XFree (data); + return FALSE; + } + + data_as_long = (gulong *)data; + + if (!find_best_size (data_as_long, nitems, + ideal_width, ideal_height, + &w, &h, &best)) + { + XFree (data); + return FALSE; + } + + if (!find_best_size (data_as_long, nitems, + ideal_mini_width, ideal_mini_height, + &mini_w, &mini_h, &best_mini)) + { + XFree (data); + return FALSE; + } + + *icon = argbdata_to_surface (best, w, h); + *mini_icon = argbdata_to_surface (best_mini, mini_w, mini_h); + + XFree (data); + + return TRUE; +} + +static void +get_pixmap_geometry (MetaX11Display *x11_display, + Pixmap pixmap, + int *w, + int *h, + int *d) +{ + Window root_ignored; + int x_ignored, y_ignored; + guint width, height; + guint border_width_ignored; + guint depth; + + if (w) + *w = 1; + if (h) + *h = 1; + if (d) + *d = 1; + + XGetGeometry (x11_display->xdisplay, + pixmap, &root_ignored, &x_ignored, &y_ignored, + &width, &height, &border_width_ignored, &depth); + + if (w) + *w = width; + if (h) + *h = height; + if (d) + *d = depth; +} + +static cairo_surface_t * +surface_from_pixmap (Display *xdisplay, Pixmap xpixmap, + int width, int height) +{ + Window root_return; + XVisualInfo visual_info; + int x_ret, y_ret; + unsigned int w_ret, h_ret, bw_ret, depth_ret; + + if (!XGetGeometry (xdisplay, xpixmap, &root_return, + &x_ret, &y_ret, &w_ret, &h_ret, &bw_ret, &depth_ret)) + return NULL; + + if (!XMatchVisualInfo (xdisplay, DefaultScreen (xdisplay), + depth_ret, TrueColor, &visual_info)) + return NULL; + + return cairo_xlib_surface_create (xdisplay, xpixmap, visual_info.visual, + w_ret, h_ret); +} + +static gboolean +try_pixmap_and_mask (MetaX11Display *x11_display, + Pixmap src_pixmap, + Pixmap src_mask, + cairo_surface_t **iconp) +{ + Display *xdisplay = x11_display->xdisplay; + cairo_surface_t *icon, *mask = NULL; + int w, h, d; + + if (src_pixmap == None) + return FALSE; + + meta_x11_error_trap_push (x11_display); + + get_pixmap_geometry (x11_display, src_pixmap, &w, &h, &d); + icon = surface_from_pixmap (xdisplay, src_pixmap, w, h); + + if (icon && src_mask != None) + { + get_pixmap_geometry (x11_display, src_mask, &w, &h, &d); + + if (d == 1) + mask = surface_from_pixmap (xdisplay, src_mask, w, h); + } + + meta_x11_error_trap_pop (x11_display); + + if (icon && mask) + { + cairo_surface_t *masked; + cairo_t *cr; + + masked = cairo_surface_create_similar_image (icon, + CAIRO_FORMAT_ARGB32, + cairo_xlib_surface_get_width (icon), + cairo_xlib_surface_get_height (icon)); + cr = cairo_create (masked); + + cairo_set_source_surface (cr, icon, 0, 0); + cairo_mask_surface (cr, mask, 0, 0); + + cairo_destroy (cr); + cairo_surface_destroy (icon); + cairo_surface_destroy (mask); + + icon = masked; + } + + if (icon) + { + *iconp = icon; + return TRUE; + } + else + { + return FALSE; + } +} + +static void +get_kwm_win_icon (MetaX11Display *x11_display, + Window xwindow, + Pixmap *pixmap, + Pixmap *mask) +{ + Atom type; + int format; + gulong nitems; + gulong bytes_after; + guchar *data; + Pixmap *icons; + int err, result; + + *pixmap = None; + *mask = None; + + meta_x11_error_trap_push (x11_display); + icons = NULL; + result = XGetWindowProperty (x11_display->xdisplay, xwindow, + x11_display->atom__KWM_WIN_ICON, + 0, G_MAXLONG, + False, + x11_display->atom__KWM_WIN_ICON, + &type, &format, &nitems, + &bytes_after, &data); + icons = (Pixmap *)data; + + err = meta_x11_error_trap_pop_with_return (x11_display); + if (err != Success || + result != Success) + return; + + if (type != x11_display->atom__KWM_WIN_ICON) + { + XFree (icons); + return; + } + + *pixmap = icons[0]; + *mask = icons[1]; + + XFree (icons); + + return; +} + +void +meta_icon_cache_init (MetaIconCache *icon_cache) +{ + g_return_if_fail (icon_cache != NULL); + + icon_cache->origin = USING_NO_ICON; + icon_cache->prev_pixmap = None; + icon_cache->prev_mask = None; + icon_cache->wm_hints_dirty = TRUE; + icon_cache->kwm_win_icon_dirty = TRUE; + icon_cache->net_wm_icon_dirty = TRUE; +} + +void +meta_icon_cache_property_changed (MetaIconCache *icon_cache, + MetaX11Display *x11_display, + Atom atom) +{ + if (atom == x11_display->atom__NET_WM_ICON) + icon_cache->net_wm_icon_dirty = TRUE; + else if (atom == x11_display->atom__KWM_WIN_ICON) + icon_cache->kwm_win_icon_dirty = TRUE; + else if (atom == XA_WM_HINTS) + icon_cache->wm_hints_dirty = TRUE; +} + +gboolean +meta_icon_cache_get_icon_invalidated (MetaIconCache *icon_cache) +{ + if (icon_cache->origin <= USING_KWM_WIN_ICON && + icon_cache->kwm_win_icon_dirty) + return TRUE; + else if (icon_cache->origin <= USING_WM_HINTS && + icon_cache->wm_hints_dirty) + return TRUE; + else if (icon_cache->origin <= USING_NET_WM_ICON && + icon_cache->net_wm_icon_dirty) + return TRUE; + else if (icon_cache->origin < USING_FALLBACK_ICON) + return TRUE; + else + return FALSE; +} + +gboolean +meta_read_icons (MetaX11Display *x11_display, + Window xwindow, + MetaIconCache *icon_cache, + Pixmap wm_hints_pixmap, + Pixmap wm_hints_mask, + cairo_surface_t **iconp, + int ideal_width, + int ideal_height, + cairo_surface_t **mini_iconp, + int ideal_mini_width, + int ideal_mini_height) +{ + /* Return value is whether the icon changed */ + + g_return_val_if_fail (icon_cache != NULL, FALSE); + + *iconp = NULL; + *mini_iconp = NULL; + + if (!meta_icon_cache_get_icon_invalidated (icon_cache)) + return FALSE; /* we have no new info to use */ + + /* Our algorithm here assumes that we can't have for example origin + * < USING_NET_WM_ICON and icon_cache->net_wm_icon_dirty == FALSE + * unless we have tried to read NET_WM_ICON. + * + * Put another way, if an icon origin is not dirty, then we have + * tried to read it at the current size. If it is dirty, then + * we haven't done that since the last change. + */ + + if (icon_cache->origin <= USING_NET_WM_ICON && + icon_cache->net_wm_icon_dirty) + { + icon_cache->net_wm_icon_dirty = FALSE; + + if (read_rgb_icon (x11_display, xwindow, + ideal_width, ideal_height, + ideal_mini_width, ideal_mini_height, + iconp, mini_iconp)) + { + icon_cache->origin = USING_NET_WM_ICON; + return TRUE; + } + } + + if (icon_cache->origin <= USING_WM_HINTS && + icon_cache->wm_hints_dirty) + { + Pixmap pixmap; + Pixmap mask; + + icon_cache->wm_hints_dirty = FALSE; + + pixmap = wm_hints_pixmap; + mask = wm_hints_mask; + + /* We won't update if pixmap is unchanged; + * avoids a get_from_drawable() on every geometry + * hints change + */ + if ((pixmap != icon_cache->prev_pixmap || + mask != icon_cache->prev_mask) && + pixmap != None) + { + if (try_pixmap_and_mask (x11_display, pixmap, mask, iconp)) + { + *mini_iconp = cairo_surface_reference (*iconp); + icon_cache->prev_pixmap = pixmap; + icon_cache->prev_mask = mask; + icon_cache->origin = USING_WM_HINTS; + return TRUE; + } + } + } + + if (icon_cache->origin <= USING_KWM_WIN_ICON && + icon_cache->kwm_win_icon_dirty) + { + Pixmap pixmap; + Pixmap mask; + + icon_cache->kwm_win_icon_dirty = FALSE; + + get_kwm_win_icon (x11_display, xwindow, &pixmap, &mask); + + if ((pixmap != icon_cache->prev_pixmap || + mask != icon_cache->prev_mask) && + pixmap != None) + { + if (try_pixmap_and_mask (x11_display, pixmap, mask, iconp)) + { + *mini_iconp = cairo_surface_reference (*iconp); + icon_cache->prev_pixmap = pixmap; + icon_cache->prev_mask = mask; + icon_cache->origin = USING_KWM_WIN_ICON; + return TRUE; + } + } + } + + if (icon_cache->origin < USING_FALLBACK_ICON) + { + icon_cache->origin = USING_FALLBACK_ICON; + *iconp = NULL; + *mini_iconp = NULL; + return TRUE; + } + + /* found nothing new */ + return FALSE; +} diff --git a/src/core/iconcache.h b/src/x11/iconcache.h similarity index 60% rename from src/core/iconcache.h rename to src/x11/iconcache.h index c2b14012b..a4b63edf0 100644 --- a/src/core/iconcache.h +++ b/src/x11/iconcache.h @@ -1,10 +1,10 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* Muffin window icons */ +/* Mutter window icons */ -/* +/* * Copyright (C) 2002 Havoc Pennington - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the @@ -14,17 +14,15 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_ICON_CACHE_H #define META_ICON_CACHE_H -#include "screen-private.h" +#include "x11/meta-x11-display-private.h" typedef struct _MetaIconCache MetaIconCache; @@ -46,28 +44,29 @@ struct _MetaIconCache int origin; Pixmap prev_pixmap; Pixmap prev_mask; - guint want_fallback : 1; /* TRUE if these props have changed */ guint wm_hints_dirty : 1; guint kwm_win_icon_dirty : 1; guint net_wm_icon_dirty : 1; }; -void meta_icon_cache_init (MetaIconCache *icon_cache); -void meta_icon_cache_free (MetaIconCache *icon_cache); -void meta_icon_cache_property_changed (MetaIconCache *icon_cache, - MetaDisplay *display, - Atom atom); -gboolean meta_icon_cache_get_icon_invalidated (MetaIconCache *icon_cache); +void meta_icon_cache_init (MetaIconCache *icon_cache); +void meta_icon_cache_property_changed (MetaIconCache *icon_cache, + MetaX11Display *x11_display, + Atom atom); +gboolean meta_icon_cache_get_icon_invalidated (MetaIconCache *icon_cache); -gboolean meta_read_icons (MetaScreen *screen, - Window xwindow, - MetaIconCache *icon_cache, - Pixmap wm_hints_pixmap, - Pixmap wm_hints_mask, - GdkPixbuf **iconp, - int ideal_width, - int ideal_height); +gboolean meta_read_icons (MetaX11Display *x11_display, + Window xwindow, + MetaIconCache *icon_cache, + Pixmap wm_hints_pixmap, + Pixmap wm_hints_mask, + cairo_surface_t **iconp, + int ideal_width, + int ideal_height, + cairo_surface_t **mini_iconp, + int ideal_mini_width, + int ideal_mini_height); #endif diff --git a/src/x11/meta-selection-source-x11-private.h b/src/x11/meta-selection-source-x11-private.h new file mode 100644 index 000000000..bcd21a356 --- /dev/null +++ b/src/x11/meta-selection-source-x11-private.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2018 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef META_SELECTION_SOURCE_X11_H +#define META_SELECTION_SOURCE_X11_H + +#include "meta/meta-selection-source.h" +#include "x11/meta-x11-display-private.h" + +#define META_TYPE_SELECTION_SOURCE_X11 (meta_selection_source_x11_get_type ()) +G_DECLARE_FINAL_TYPE (MetaSelectionSourceX11, + meta_selection_source_x11, + META, SELECTION_SOURCE_X11, + MetaSelectionSource) + +void meta_selection_source_x11_new_async (MetaX11Display *display, + Window owner, + uint32_t timestamp, + Atom xselection, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +MetaSelectionSource * meta_selection_source_x11_new_finish (GAsyncResult *result, + GError **error); + +#endif /* META_SELECTION_SOURCE_X11_H */ diff --git a/src/x11/meta-selection-source-x11.c b/src/x11/meta-selection-source-x11.c new file mode 100644 index 000000000..c9fc8fbc6 --- /dev/null +++ b/src/x11/meta-selection-source-x11.c @@ -0,0 +1,275 @@ +/* + * Copyright (C) 2018 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#include "config.h" + +#include <gdk/gdkx.h> + +#include "x11/meta-x11-selection-input-stream-private.h" +#include "x11/meta-selection-source-x11-private.h" + +#define MAX_MIMETYPE_SIZE 4096 + +struct _MetaSelectionSourceX11 +{ + MetaSelectionSource parent_instance; + MetaX11Display *x11_display; + GList *mimetypes; + Window owner; + Atom xselection; + uint32_t timestamp; +}; + +G_DEFINE_TYPE (MetaSelectionSourceX11, meta_selection_source_x11, + META_TYPE_SELECTION_SOURCE) + +static void +stream_new_cb (GObject *source, + GAsyncResult *res, + GTask *task) +{ + GInputStream *stream; + GError *error = NULL; + + stream = meta_x11_selection_input_stream_new_finish (res, NULL, NULL, &error); + + if (stream) + g_task_return_pointer (task, stream, g_object_unref); + else + g_task_return_error (task, error); + + g_object_unref (task); +} + +static void +meta_selection_source_x11_finalize (GObject *object) +{ + MetaSelectionSourceX11 *source_x11 = META_SELECTION_SOURCE_X11 (object); + + g_list_free_full (source_x11->mimetypes, g_free); + + G_OBJECT_CLASS (meta_selection_source_x11_parent_class)->finalize (object); +} + +static void +meta_selection_source_x11_read_async (MetaSelectionSource *source, + const gchar *mimetype, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + MetaSelectionSourceX11 *source_x11 = META_SELECTION_SOURCE_X11 (source); + GTask *task; + + task = g_task_new (source, cancellable, callback, user_data); + g_task_set_source_tag (task, meta_selection_source_x11_read_async); + + if (strcmp (mimetype, "text/plain") == 0 && + g_list_find_custom (source_x11->mimetypes, "STRING", + (GCompareFunc) g_strcmp0)) + mimetype = "STRING"; + else if (strcmp (mimetype, "text/plain;charset=utf-8") == 0 && + g_list_find_custom (source_x11->mimetypes, "UTF8_STRING", + (GCompareFunc) g_strcmp0)) + mimetype = "UTF8_STRING"; + + meta_x11_selection_input_stream_new_async (source_x11->x11_display, + source_x11->x11_display->selection.xwindow, + gdk_x11_get_xatom_name (source_x11->xselection), + mimetype, + source_x11->timestamp, + G_PRIORITY_DEFAULT, + cancellable, + (GAsyncReadyCallback) stream_new_cb, + task); +} + +static GInputStream * +meta_selection_source_x11_read_finish (MetaSelectionSource *source, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, source), NULL); + g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == + meta_selection_source_x11_read_async, NULL); + + return g_task_propagate_pointer (G_TASK (result), error); +} + +static GList * +meta_selection_source_x11_get_mimetypes (MetaSelectionSource *source) +{ + MetaSelectionSourceX11 *source_x11 = META_SELECTION_SOURCE_X11 (source); + + return g_list_copy_deep (source_x11->mimetypes, (GCopyFunc) g_strdup, NULL); +} + +static void +meta_selection_source_x11_class_init (MetaSelectionSourceX11Class *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MetaSelectionSourceClass *source_class = META_SELECTION_SOURCE_CLASS (klass); + + object_class->finalize = meta_selection_source_x11_finalize; + + source_class->read_async = meta_selection_source_x11_read_async; + source_class->read_finish = meta_selection_source_x11_read_finish; + source_class->get_mimetypes = meta_selection_source_x11_get_mimetypes; +} + +static void +meta_selection_source_x11_init (MetaSelectionSourceX11 *source) +{ +} + +static GList * +atoms_to_mimetypes (MetaX11Display *display, + GBytes *bytes) +{ + GList *mimetypes = NULL; + const Atom *atoms; + gsize size; + guint i, n_atoms; + gboolean utf8_string_found = FALSE, utf8_text_plain_found = FALSE; + gboolean string_found = FALSE, text_plain_found = FALSE; + + atoms = g_bytes_get_data (bytes, &size); + n_atoms = size / sizeof (Atom); + + for (i = 0; i < n_atoms; i++) + { + const gchar *mimetype; + + mimetype = gdk_x11_get_xatom_name (atoms[i]); + mimetypes = g_list_prepend (mimetypes, g_strdup (mimetype)); + + utf8_text_plain_found |= strcmp (mimetype, "text/plain;charset=utf-8") == 0; + text_plain_found |= strcmp (mimetype, "text/plain") == 0; + utf8_string_found |= strcmp (mimetype, "UTF8_STRING") == 0; + string_found |= strcmp (mimetype, "STRING") == 0; + } + + /* Ensure non-x11 clients get well-known mimetypes */ + if (string_found && !text_plain_found) + mimetypes = g_list_prepend (mimetypes, g_strdup ("text/plain")); + if (utf8_string_found && !utf8_text_plain_found) + mimetypes = g_list_prepend (mimetypes, g_strdup ("text/plain;charset=utf-8")); + + return mimetypes; +} + +static void +read_mimetypes_cb (GInputStream *stream, + GAsyncResult *res, + GTask *task) +{ + MetaSelectionSourceX11 *source_x11 = g_task_get_task_data (task); + GError *error = NULL; + GBytes *bytes; + + bytes = g_input_stream_read_bytes_finish (stream, res, &error); + if (error) + { + g_task_return_error (task, error); + g_object_unref (task); + g_object_unref (stream); + return; + } + + source_x11->mimetypes = atoms_to_mimetypes (source_x11->x11_display, bytes); + g_bytes_unref (bytes); + + g_task_return_pointer (task, + g_object_ref (g_task_get_task_data (task)), + g_object_unref); + g_object_unref (task); + g_object_unref (stream); +} + +static void +get_mimetypes_cb (GObject *source, + GAsyncResult *res, + GTask *task) +{ + GInputStream *stream; + GError *error = NULL; + + stream = meta_x11_selection_input_stream_new_finish (res, NULL, NULL, &error); + if (error) + { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + g_input_stream_read_bytes_async (stream, + MAX_MIMETYPE_SIZE, + G_PRIORITY_DEFAULT, + g_task_get_cancellable (task), + (GAsyncReadyCallback) read_mimetypes_cb, + task); +} + +void +meta_selection_source_x11_new_async (MetaX11Display *x11_display, + Window owner, + uint32_t timestamp, + Atom xselection, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + MetaSelectionSourceX11 *source; + GTask *task; + + source = g_object_new (META_TYPE_SELECTION_SOURCE_X11, NULL); + source->x11_display = x11_display; + source->owner = owner; + source->timestamp = timestamp; + source->xselection = xselection; + + task = g_task_new (NULL, cancellable, callback, user_data); + g_task_set_source_tag (task, meta_selection_source_x11_new_async); + g_task_set_task_data (task, source, g_object_unref); + + meta_x11_selection_input_stream_new_async (x11_display, + x11_display->selection.xwindow, + gdk_x11_get_xatom_name (xselection), + "TARGETS", + timestamp, + G_PRIORITY_DEFAULT, + cancellable, + (GAsyncReadyCallback) get_mimetypes_cb, + task); +} + +MetaSelectionSource * +meta_selection_source_x11_new_finish (GAsyncResult *result, + GError **error) +{ + GTask *task = G_TASK (result); + + g_return_val_if_fail (g_task_is_valid (task, NULL), NULL); + g_return_val_if_fail (g_task_get_source_tag (task) == + meta_selection_source_x11_new_async, NULL); + + return g_task_propagate_pointer (task, error); +} diff --git a/src/x11/meta-startup-notification-x11.c b/src/x11/meta-startup-notification-x11.c new file mode 100644 index 000000000..da80f5e14 --- /dev/null +++ b/src/x11/meta-startup-notification-x11.c @@ -0,0 +1,376 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * Copyright (C) 2018 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" +#include "meta-startup-notification-x11.h" + +#include <gio/gdesktopappinfo.h> + +#include "core/display-private.h" +#include "core/startup-notification-private.h" +#include "meta/meta-x11-errors.h" +#include "x11/meta-x11-display-private.h" + +#ifdef HAVE_STARTUP_NOTIFICATION + +enum +{ + PROP_SEQ_X11_0, + PROP_SEQ_X11_SEQ, + N_SEQ_X11_PROPS +}; + +struct _MetaStartupSequenceX11 +{ + MetaStartupSequence parent_instance; + SnStartupSequence *seq; +}; + +struct _MetaX11StartupNotification +{ + SnDisplay *sn_display; + SnMonitorContext *sn_context; +}; + +static GParamSpec *seq_x11_props[N_SEQ_X11_PROPS]; + +G_DEFINE_TYPE (MetaStartupSequenceX11, + meta_startup_sequence_x11, + META_TYPE_STARTUP_SEQUENCE) + +static void +meta_startup_sequence_x11_complete (MetaStartupSequence *seq) +{ + MetaStartupSequenceX11 *seq_x11; + + seq_x11 = META_STARTUP_SEQUENCE_X11 (seq); + sn_startup_sequence_complete (seq_x11->seq); +} + +static void +meta_startup_sequence_x11_finalize (GObject *object) +{ + MetaStartupSequenceX11 *seq_x11; + + seq_x11 = META_STARTUP_SEQUENCE_X11 (object); + sn_startup_sequence_unref (seq_x11->seq); + + G_OBJECT_CLASS (meta_startup_sequence_x11_parent_class)->finalize (object); +} + +static void +meta_startup_sequence_x11_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaStartupSequenceX11 *seq_x11; + + seq_x11 = META_STARTUP_SEQUENCE_X11 (object); + + switch (prop_id) + { + case PROP_SEQ_X11_SEQ: + seq_x11->seq = g_value_get_pointer (value); + sn_startup_sequence_ref (seq_x11->seq); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_startup_sequence_x11_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaStartupSequenceX11 *seq_x11; + + seq_x11 = META_STARTUP_SEQUENCE_X11 (object); + + switch (prop_id) + { + case PROP_SEQ_X11_SEQ: + g_value_set_pointer (value, seq_x11->seq); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_startup_sequence_x11_init (MetaStartupSequenceX11 *seq) +{ +} + +static void +meta_startup_sequence_x11_class_init (MetaStartupSequenceX11Class *klass) +{ + MetaStartupSequenceClass *seq_class; + GObjectClass *object_class; + + seq_class = META_STARTUP_SEQUENCE_CLASS (klass); + seq_class->complete = meta_startup_sequence_x11_complete; + + object_class = G_OBJECT_CLASS (klass); + object_class->finalize = meta_startup_sequence_x11_finalize; + object_class->set_property = meta_startup_sequence_x11_set_property; + object_class->get_property = meta_startup_sequence_x11_get_property; + + seq_x11_props[PROP_SEQ_X11_SEQ] = + g_param_spec_pointer ("seq", + "Sequence", + "Sequence", + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY); + + g_object_class_install_properties (object_class, N_SEQ_X11_PROPS, + seq_x11_props); +} + +static MetaStartupSequence * +meta_startup_sequence_x11_new (SnStartupSequence *seq) +{ + gint64 timestamp; + + timestamp = sn_startup_sequence_get_timestamp (seq); + return g_object_new (META_TYPE_STARTUP_SEQUENCE_X11, + "id", sn_startup_sequence_get_id (seq), + "icon-name", sn_startup_sequence_get_icon_name (seq), + "application-id", sn_startup_sequence_get_application_id (seq), + "wmclass", sn_startup_sequence_get_wmclass (seq), + "name", sn_startup_sequence_get_name (seq), + "workspace", sn_startup_sequence_get_workspace (seq), + "timestamp", timestamp, + "seq", seq, + NULL); +} + +static void +sn_error_trap_push (SnDisplay *sn_display, + Display *xdisplay) +{ + MetaDisplay *display; + + display = meta_display_for_x_display (xdisplay); + if (display != NULL) + meta_x11_error_trap_push (display->x11_display); +} + +static void +sn_error_trap_pop (SnDisplay *sn_display, + Display *xdisplay) +{ + MetaDisplay *display; + + display = meta_display_for_x_display (xdisplay); + if (display != NULL) + meta_x11_error_trap_pop (display->x11_display); +} + +static void +meta_startup_notification_sn_event (SnMonitorEvent *event, + void *user_data) +{ + MetaX11Display *x11_display = user_data; + MetaStartupNotification *sn = x11_display->display->startup_notification; + MetaStartupSequence *seq; + SnStartupSequence *sequence; + + sequence = sn_monitor_event_get_startup_sequence (event); + + sn_startup_sequence_ref (sequence); + + switch (sn_monitor_event_get_type (event)) + { + case SN_MONITOR_EVENT_INITIATED: + { + const char *wmclass; + + wmclass = sn_startup_sequence_get_wmclass (sequence); + + meta_topic (META_DEBUG_STARTUP, + "Received startup initiated for %s wmclass %s\n", + sn_startup_sequence_get_id (sequence), + wmclass ? wmclass : "(unset)"); + + seq = meta_startup_sequence_x11_new (sequence); + meta_startup_notification_add_sequence (sn, seq); + g_object_unref (seq); + } + break; + + case SN_MONITOR_EVENT_COMPLETED: + { + meta_topic (META_DEBUG_STARTUP, + "Received startup completed for %s\n", + sn_startup_sequence_get_id (sequence)); + + seq = meta_startup_notification_lookup_sequence (sn, sn_startup_sequence_get_id (sequence)); + if (seq) + { + meta_startup_sequence_complete (seq); + meta_startup_notification_remove_sequence (sn, seq); + } + } + break; + + case SN_MONITOR_EVENT_CHANGED: + meta_topic (META_DEBUG_STARTUP, + "Received startup changed for %s\n", + sn_startup_sequence_get_id (sequence)); + break; + + case SN_MONITOR_EVENT_CANCELED: + meta_topic (META_DEBUG_STARTUP, + "Received startup canceled for %s\n", + sn_startup_sequence_get_id (sequence)); + break; + } + + sn_startup_sequence_unref (sequence); +} +#endif + +void +meta_x11_startup_notification_init (MetaX11Display *x11_display) +{ +#ifdef HAVE_STARTUP_NOTIFICATION + MetaX11StartupNotification *x11_sn; + + x11_sn = g_new0 (MetaX11StartupNotification, 1); + x11_sn->sn_display = sn_display_new (x11_display->xdisplay, + sn_error_trap_push, + sn_error_trap_pop); + x11_sn->sn_context = + sn_monitor_context_new (x11_sn->sn_display, + meta_x11_display_get_screen_number (x11_display), + meta_startup_notification_sn_event, + x11_display, + NULL); + + x11_display->startup_notification = x11_sn; +#endif +} + +void +meta_x11_startup_notification_release (MetaX11Display *x11_display) +{ +#ifdef HAVE_STARTUP_NOTIFICATION + MetaX11StartupNotification *x11_sn = x11_display->startup_notification; + + x11_display->startup_notification = NULL; + + if (x11_sn) + { + sn_monitor_context_unref (x11_sn->sn_context); + sn_display_unref (x11_sn->sn_display); + g_free (x11_sn); + } +#endif +} + +gboolean +meta_x11_startup_notification_handle_xevent (MetaX11Display *x11_display, + XEvent *xevent) +{ +#ifdef HAVE_STARTUP_NOTIFICATION + MetaX11StartupNotification *x11_sn = x11_display->startup_notification; + + if (!x11_sn) + return FALSE; + + return sn_display_process_event (x11_sn->sn_display, xevent); +#else + return FALSE; +#endif +} + +#ifdef HAVE_STARTUP_NOTIFICATION +typedef void (* SetAppIdFunc) (SnLauncherContext *context, + const char *app_id); +#endif + +gchar * +meta_x11_startup_notification_launch (MetaX11Display *x11_display, + GAppInfo *app_info, + uint32_t timestamp, + int workspace) +{ + gchar *startup_id = NULL; +#ifdef HAVE_STARTUP_NOTIFICATION + MetaX11StartupNotification *x11_sn = x11_display->startup_notification; + SnLauncherContext *sn_launcher; + int screen; + + screen = meta_x11_display_get_screen_number (x11_display); + sn_launcher = sn_launcher_context_new (x11_sn->sn_display, screen); + + sn_launcher_context_set_name (sn_launcher, g_app_info_get_name (app_info)); + sn_launcher_context_set_workspace (sn_launcher, workspace); + sn_launcher_context_set_binary_name (sn_launcher, + g_app_info_get_executable (app_info)); + + if (G_IS_DESKTOP_APP_INFO (app_info)) + { + const char *application_id; + SetAppIdFunc func = NULL; + GModule *self; + + application_id = + g_desktop_app_info_get_filename (G_DESKTOP_APP_INFO (app_info)); + self = g_module_open (NULL, G_MODULE_BIND_MASK); + + /* This here is a terrible workaround to bypass a libsn bug that is not + * likely to get fixed at this point. + * sn_launcher_context_set_application_id is correctly defined in the + * sn-launcher.h file, but it's mistakenly called + * sn_launcher_set_application_id in the C file. + * + * We look up the symbol instead, but still prefer the correctly named + * function, if one were ever to be added. + */ + if (!g_module_symbol (self, "sn_launcher_context_set_application_id", + (gpointer *) &func)) + { + g_module_symbol (self, "sn_launcher_set_application_id", + (gpointer *) &func); + } + + if (func && application_id) + func (sn_launcher, application_id); + + g_module_close (self); + } + + sn_launcher_context_initiate (sn_launcher, + g_get_prgname (), + g_app_info_get_name (app_info), + timestamp); + + startup_id = g_strdup (sn_launcher_context_get_startup_id (sn_launcher)); + + /* Fire and forget, we have a SnMonitor in addition */ + sn_launcher_context_unref (sn_launcher); +#endif /* HAVE_STARTUP_NOTIFICATION */ + + return startup_id; +} diff --git a/src/x11/meta-startup-notification-x11.h b/src/x11/meta-startup-notification-x11.h new file mode 100644 index 000000000..b46a45e5d --- /dev/null +++ b/src/x11/meta-startup-notification-x11.h @@ -0,0 +1,44 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * Copyright (C) 2018 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "meta-x11-display-private.h" + +#ifndef META_X11_STARTUP_NOTIFICATION_H +#define META_X11_STARTUP_NOTIFICATION_H + +typedef struct _MetaX11StartupNotification MetaX11StartupNotification; + +#define META_TYPE_STARTUP_SEQUENCE_X11 (meta_startup_sequence_x11_get_type ()) + +G_DECLARE_FINAL_TYPE (MetaStartupSequenceX11, + meta_startup_sequence_x11, + META, STARTUP_SEQUENCE_X11, + MetaStartupSequence) + +void meta_x11_startup_notification_init (MetaX11Display *x11_display); +void meta_x11_startup_notification_release (MetaX11Display *x11_display); + +gboolean meta_x11_startup_notification_handle_xevent (MetaX11Display *x11_display, + XEvent *xevent); + +gchar * meta_x11_startup_notification_launch (MetaX11Display *x11_display, + GAppInfo *app_info, + uint32_t timestamp, + int workspace); + +#endif /* META_X11_STARTUP_NOTIFICATION_H */ diff --git a/src/x11/meta-x11-display-private.h b/src/x11/meta-x11-display-private.h new file mode 100644 index 000000000..d53073e11 --- /dev/null +++ b/src/x11/meta-x11-display-private.h @@ -0,0 +1,261 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* Mutter X display handler */ + +/* + * Copyright (C) 2001 Havoc Pennington + * Copyright (C) 2002 Red Hat, Inc. + * Copyright (C) 2003 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef META_X11_DISPLAY_PRIVATE_H +#define META_X11_DISPLAY_PRIVATE_H + +#include <glib.h> +#include <X11/Xlib.h> + +#include "backends/meta-monitor-manager-private.h" +#include "core/display-private.h" +#include "meta/common.h" +#include "meta/meta-selection-source.h" +#include "meta/types.h" +#include "meta/meta-x11-display.h" +#include "meta-startup-notification-x11.h" +#include "meta-x11-stack-private.h" +#include "ui/ui.h" + +typedef struct _MetaGroupPropHooks MetaGroupPropHooks; +typedef struct _MetaWindowPropHooks MetaWindowPropHooks; + +typedef gboolean (*MetaAlarmFilter) (MetaX11Display *x11_display, + XSyncAlarmNotifyEvent *event, + gpointer data); + +struct _MetaX11Display +{ + GObject parent; + + MetaDisplay *display; + GdkDisplay *gdk_display; + + char *name; + char *screen_name; + + Display *xdisplay; + Window xroot; + int default_depth; + Visual *default_xvisual; + + guint32 timestamp; + + /* Pull in all the names of atoms as fields; we will intern them when the + * class is constructed. + */ +#define item(x) Atom atom_##x; +#include "x11/atomnames.h" +#undef item + + Window leader_window; + Window timestamp_pinging_window; + + /* The window and serial of the most recent FocusIn event. */ + Window server_focus_window; + gulong server_focus_serial; + + /* For windows we've focused that don't necessarily have an X window, + * like the no_focus_window or the stage X window. */ + Window focus_xwindow; + gulong focus_serial; + + /* This window holds the focus when we don't want to focus + * any actual clients + */ + Window no_focus_window; + + /* Instead of unmapping withdrawn windows we can leave them mapped + * and restack them below a guard window. When using a compositor + * this allows us to provide live previews of unmapped windows */ + Window guard_window; + + Window wm_sn_selection_window; + Atom wm_sn_atom; + guint32 wm_sn_timestamp; + + guint display_close_idle; + guint32 xselectionclear_timestamp; + + Window wm_cm_selection_window; + + Window composite_overlay_window; + + GHashTable *xids; + + gboolean has_xinerama_indices; + + /* Managed by group.c */ + GHashTable *groups_by_leader; + + /* Managed by window-props.c */ + MetaWindowPropHooks *prop_hooks_table; + GHashTable *prop_hooks; + int n_prop_hooks; + + /* Managed by group-props.c */ + MetaGroupPropHooks *group_prop_hooks; + + int xkb_base_event_type; + guint32 last_bell_time; + + MetaAlarmFilter alarm_filter; + gpointer alarm_filter_data; + + MetaUI *ui; + + struct { + Window xwindow; + guint timeout_id; + MetaSelectionSource *owners[META_N_SELECTION_TYPES]; + GCancellable *cancellables[META_N_SELECTION_TYPES]; + + GList *input_streams; + GList *output_streams; + } selection; + + /* If true, server->focus_serial refers to us changing the focus; in + * this case, we can ignore focus events that have exactly focus_serial, + * since we take care to make another request immediately afterwards. + * But if focus is being changed by another client, we have to accept + * multiple events with the same serial. + */ + guint focused_by_us : 1; + + guint keys_grabbed : 1; + + guint closing : 1; + + /* we use property updates as sentinels for certain window focus events + * to avoid some race conditions on EnterNotify events + */ + int sentinel_counter; + + int composite_event_base; + int composite_error_base; + int composite_major_version; + int composite_minor_version; + int damage_event_base; + int damage_error_base; + int xfixes_event_base; + int xfixes_error_base; + int xinput_error_base; + int xinput_event_base; + int xinput_opcode; + int xsync_event_base; + int xsync_error_base; + int shape_event_base; + int shape_error_base; + unsigned int have_xsync : 1; +#define META_X11_DISPLAY_HAS_XSYNC(x11_display) ((x11_display)->have_xsync) + unsigned int have_shape : 1; +#define META_X11_DISPLAY_HAS_SHAPE(x11_display) ((x11_display)->have_shape) + unsigned int have_composite : 1; + unsigned int have_damage : 1; +#define META_X11_DISPLAY_HAS_COMPOSITE(x11_display) ((x11_display)->have_composite) +#define META_X11_DISPLAY_HAS_DAMAGE(x11_display) ((x11_display)->have_damage) + gboolean have_xinput_23 : 1; +#define META_X11_DISPLAY_HAS_XINPUT_23(x11_display) ((x11_display)->have_xinput_23) + + MetaX11StartupNotification *startup_notification; + MetaX11Stack *x11_stack; + + XserverRegion empty_region; +}; + +MetaX11Display *meta_x11_display_new (MetaDisplay *display, GError **error); + +void meta_x11_display_restore_active_workspace (MetaX11Display *x11_display); + +Window meta_x11_display_create_offscreen_window (MetaX11Display *x11_display, + Window parent, + long valuemask); + +Cursor meta_x11_display_create_x_cursor (MetaX11Display *x11_display, + MetaCursor cursor); + +void meta_x11_display_reload_cursor (MetaX11Display *x11_display); + +MetaWindow *meta_x11_display_lookup_x_window (MetaX11Display *x11_display, + Window xwindow); +void meta_x11_display_register_x_window (MetaX11Display *x11_display, + Window *xwindowp, + MetaWindow *window); +void meta_x11_display_unregister_x_window (MetaX11Display *x11_display, + Window xwindow); + +MetaWindow *meta_x11_display_lookup_sync_alarm (MetaX11Display *x11_display, + XSyncAlarm alarm); +void meta_x11_display_register_sync_alarm (MetaX11Display *x11_display, + XSyncAlarm *alarmp, + MetaWindow *window); +void meta_x11_display_unregister_sync_alarm (MetaX11Display *x11_display, + XSyncAlarm alarm); + +gboolean meta_x11_display_process_barrier_xevent (MetaX11Display *x11_display, + XIEvent *event); + +META_EXPORT +void meta_x11_display_set_alarm_filter (MetaX11Display *x11_display, + MetaAlarmFilter filter, + gpointer data); + +void meta_x11_display_create_guard_window (MetaX11Display *x11_display); + +/* make a request to ensure the event serial has changed */ +void meta_x11_display_increment_event_serial (MetaX11Display *x11_display); + +guint32 meta_x11_display_get_current_time_roundtrip (MetaX11Display *x11_display); + +void meta_x11_display_set_input_focus_xwindow (MetaX11Display *x11_display, + Window window, + guint32 timestamp); + +int meta_x11_display_logical_monitor_to_xinerama_index (MetaX11Display *x11_display, + MetaLogicalMonitor *logical_monitor); + +MetaLogicalMonitor *meta_x11_display_xinerama_index_to_logical_monitor (MetaX11Display *x11_display, + int xinerama_index); + +void meta_x11_display_update_workspace_layout (MetaX11Display *x11_display); +void meta_x11_display_update_workspace_names (MetaX11Display *x11_display); + +void meta_x11_display_increment_focus_sentinel (MetaX11Display *x11_display); +void meta_x11_display_decrement_focus_sentinel (MetaX11Display *x11_display); +gboolean meta_x11_display_focus_sentinel_clear (MetaX11Display *x11_display); + +void meta_x11_display_update_focus_window (MetaX11Display *x11_display, + Window xwindow, + gulong serial, + gboolean focused_by_us); +void meta_x11_display_set_input_focus (MetaX11Display *x11_display, + MetaWindow *window, + gboolean focus_frame, + uint32_t timestamp); + +MetaDisplay * meta_x11_display_get_display (MetaX11Display *x11_display); + +const gchar * meta_x11_get_display_name (void); + +#endif /* META_X11_DISPLAY_PRIVATE_H */ diff --git a/src/x11/meta-x11-display.c b/src/x11/meta-x11-display.c new file mode 100644 index 000000000..335044e24 --- /dev/null +++ b/src/x11/meta-x11-display.c @@ -0,0 +1,2341 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001 Havoc Pennington + * Copyright (C) 2002, 2003, 2004 Red Hat, Inc. + * Copyright (C) 2003, 2004 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +/** + * SECTION:x11-display + * @title: MetaX11Display + * @short_description: Mutter X display handler + * + * The X11 display is represented as a #MetaX11Display struct. + */ + +#include "config.h" + +#include "core/display-private.h" +#include "x11/meta-x11-display-private.h" + +#include <gdk/gdk.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <X11/Xatom.h> +#include <X11/XKBlib.h> +#include <X11/extensions/shape.h> +#include <X11/Xcursor/Xcursor.h> +#include <X11/extensions/Xcomposite.h> +#include <X11/extensions/Xdamage.h> +#include <X11/extensions/Xfixes.h> +#include <X11/extensions/Xinerama.h> +#include <X11/extensions/Xrandr.h> + +#include "backends/meta-backend-private.h" +#include "backends/meta-dnd-private.h" +#include "backends/meta-cursor-sprite-xcursor.h" +#include "backends/meta-logical-monitor.h" +#include "backends/meta-settings-private.h" +#include "backends/x11/meta-backend-x11.h" +#include "backends/x11/meta-stage-x11.h" +#include "core/frame.h" +#include "core/meta-workspace-manager-private.h" +#include "core/util-private.h" +#include "core/workspace-private.h" +#include "meta/main.h" +#include "meta/meta-x11-errors.h" + +#include "x11/events.h" +#include "x11/group-props.h" +#include "x11/meta-x11-selection-private.h" +#include "x11/window-props.h" +#include "x11/xprops.h" + +#ifdef HAVE_WAYLAND +#include "wayland/meta-xwayland-private.h" +#endif + +G_DEFINE_TYPE (MetaX11Display, meta_x11_display, G_TYPE_OBJECT) + +static GQuark quark_x11_display_logical_monitor_data = 0; + +typedef struct _MetaX11DisplayLogicalMonitorData +{ + int xinerama_index; +} MetaX11DisplayLogicalMonitorData; + +static GdkDisplay *prepared_gdk_display = NULL; + +static const char *gnome_wm_keybindings = "Mutter"; +static const char *net_wm_name = "Mutter"; + +static char *get_screen_name (Display *xdisplay, + int number); + +static void on_monitors_changed_internal (MetaMonitorManager *monitor_manager, + MetaX11Display *x11_display); + +static void update_cursor_theme (MetaX11Display *x11_display); +static void unset_wm_check_hint (MetaX11Display *x11_display); + +static void prefs_changed_callback (MetaPreference pref, + void *data); + +static void +meta_x11_display_unmanage_windows (MetaX11Display *x11_display) +{ + GList *windows, *l; + + if (!x11_display->xids) + return; + + windows = g_hash_table_get_values (x11_display->xids); + g_list_foreach (windows, (GFunc) g_object_ref, NULL); + + for (l = windows; l; l = l->next) + { + if (META_IS_WINDOW (l->data)) + { + MetaWindow *window = l->data; + + if (!window->unmanaging) + meta_window_unmanage (window, META_CURRENT_TIME); + } + else if (META_IS_BARRIER (l->data)) + meta_barrier_destroy (META_BARRIER (l->data)); + else + g_assert_not_reached (); + } + g_list_free_full (windows, g_object_unref); +} + +static void +meta_x11_display_dispose (GObject *object) +{ + MetaX11Display *x11_display = META_X11_DISPLAY (object); + + x11_display->closing = TRUE; + + if (x11_display->empty_region != None) + { + XFixesDestroyRegion (x11_display->xdisplay, + x11_display->empty_region); + x11_display->empty_region = None; + } + + meta_x11_startup_notification_release (x11_display); + + meta_prefs_remove_listener (prefs_changed_callback, x11_display); + + meta_x11_display_ungrab_keys (x11_display); + + g_clear_object (&x11_display->x11_stack); + + meta_x11_selection_shutdown (x11_display); + meta_x11_display_unmanage_windows (x11_display); + + if (x11_display->ui) + { + meta_ui_free (x11_display->ui); + x11_display->ui = NULL; + } + + if (x11_display->no_focus_window != None) + { + XUnmapWindow (x11_display->xdisplay, x11_display->no_focus_window); + XDestroyWindow (x11_display->xdisplay, x11_display->no_focus_window); + + x11_display->no_focus_window = None; + } + + if (x11_display->composite_overlay_window != None) + { + XCompositeReleaseOverlayWindow (x11_display->xdisplay, + x11_display->composite_overlay_window); + + x11_display->composite_overlay_window = None; + } + + if (x11_display->wm_sn_selection_window != None) + { + XDestroyWindow (x11_display->xdisplay, x11_display->wm_sn_selection_window); + x11_display->wm_sn_selection_window = None; + } + + if (x11_display->timestamp_pinging_window != None) + { + XDestroyWindow (x11_display->xdisplay, x11_display->timestamp_pinging_window); + x11_display->timestamp_pinging_window = None; + } + + if (x11_display->leader_window != None) + { + XDestroyWindow (x11_display->xdisplay, x11_display->leader_window); + x11_display->leader_window = None; + } + + if (x11_display->guard_window != None) + { + XUnmapWindow (x11_display->xdisplay, x11_display->guard_window); + XDestroyWindow (x11_display->xdisplay, x11_display->guard_window); + x11_display->guard_window = None; + } + + if (x11_display->prop_hooks) + { + meta_x11_display_free_window_prop_hooks (x11_display); + x11_display->prop_hooks = NULL; + } + + if (x11_display->group_prop_hooks) + { + meta_x11_display_free_group_prop_hooks (x11_display); + x11_display->group_prop_hooks = NULL; + } + + if (x11_display->xids) + { + /* Must be after all calls to meta_window_unmanage() since they + * unregister windows + */ + g_hash_table_destroy (x11_display->xids); + x11_display->xids = NULL; + } + + if (x11_display->xroot != None) + { + unset_wm_check_hint (x11_display); + + meta_x11_error_trap_push (x11_display); + XSelectInput (x11_display->xdisplay, x11_display->xroot, 0); + if (meta_x11_error_trap_pop_with_return (x11_display) != Success) + meta_warning ("Could not release screen %d on display \"%s\"\n", + DefaultScreen (x11_display->xdisplay), + x11_display->name); + + x11_display->xroot = None; + } + + + if (x11_display->xdisplay) + { + meta_x11_display_free_events (x11_display); + + x11_display->xdisplay = NULL; + } + + if (x11_display->gdk_display) + { + gdk_display_close (x11_display->gdk_display); + x11_display->gdk_display = NULL; + } + + g_clear_handle_id (&x11_display->display_close_idle, g_source_remove); + + g_free (x11_display->name); + x11_display->name = NULL; + + g_free (x11_display->screen_name); + x11_display->screen_name = NULL; + + G_OBJECT_CLASS (meta_x11_display_parent_class)->dispose (object); +} + +static void +meta_x11_display_class_init (MetaX11DisplayClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = meta_x11_display_dispose; +} + +static void +meta_x11_display_init (MetaX11Display *x11_display) +{ + quark_x11_display_logical_monitor_data = + g_quark_from_static_string ("-meta-x11-display-logical-monitor-data"); +} + +static void +query_xsync_extension (MetaX11Display *x11_display) +{ + int major, minor; + + x11_display->have_xsync = FALSE; + + x11_display->xsync_error_base = 0; + x11_display->xsync_event_base = 0; + + /* I don't think we really have to fill these in */ + major = SYNC_MAJOR_VERSION; + minor = SYNC_MINOR_VERSION; + + if (!XSyncQueryExtension (x11_display->xdisplay, + &x11_display->xsync_event_base, + &x11_display->xsync_error_base) || + !XSyncInitialize (x11_display->xdisplay, + &major, &minor)) + { + x11_display->xsync_error_base = 0; + x11_display->xsync_event_base = 0; + } + else + { + x11_display->have_xsync = TRUE; + XSyncSetPriority (x11_display->xdisplay, None, 10); + } + + meta_verbose ("Attempted to init Xsync, found version %d.%d error base %d event base %d\n", + major, minor, + x11_display->xsync_error_base, + x11_display->xsync_event_base); +} + +static void +query_xshape_extension (MetaX11Display *x11_display) +{ + x11_display->have_shape = FALSE; + + x11_display->shape_error_base = 0; + x11_display->shape_event_base = 0; + + if (!XShapeQueryExtension (x11_display->xdisplay, + &x11_display->shape_event_base, + &x11_display->shape_error_base)) + { + x11_display->shape_error_base = 0; + x11_display->shape_event_base = 0; + } + else + x11_display->have_shape = TRUE; + + meta_verbose ("Attempted to init Shape, found error base %d event base %d\n", + x11_display->shape_error_base, + x11_display->shape_event_base); +} + +static void +query_xcomposite_extension (MetaX11Display *x11_display) +{ + x11_display->have_composite = FALSE; + + x11_display->composite_error_base = 0; + x11_display->composite_event_base = 0; + + if (!XCompositeQueryExtension (x11_display->xdisplay, + &x11_display->composite_event_base, + &x11_display->composite_error_base)) + { + x11_display->composite_error_base = 0; + x11_display->composite_event_base = 0; + } + else + { + x11_display->composite_major_version = 0; + x11_display->composite_minor_version = 0; + if (XCompositeQueryVersion (x11_display->xdisplay, + &x11_display->composite_major_version, + &x11_display->composite_minor_version)) + { + x11_display->have_composite = TRUE; + } + else + { + x11_display->composite_major_version = 0; + x11_display->composite_minor_version = 0; + } + } + + meta_verbose ("Attempted to init Composite, found error base %d event base %d " + "extn ver %d %d\n", + x11_display->composite_error_base, + x11_display->composite_event_base, + x11_display->composite_major_version, + x11_display->composite_minor_version); +} + +static void +query_xdamage_extension (MetaX11Display *x11_display) +{ + x11_display->have_damage = FALSE; + + x11_display->damage_error_base = 0; + x11_display->damage_event_base = 0; + + if (!XDamageQueryExtension (x11_display->xdisplay, + &x11_display->damage_event_base, + &x11_display->damage_error_base)) + { + x11_display->damage_error_base = 0; + x11_display->damage_event_base = 0; + } + else + x11_display->have_damage = TRUE; + + meta_verbose ("Attempted to init Damage, found error base %d event base %d\n", + x11_display->damage_error_base, + x11_display->damage_event_base); +} + +static void +query_xfixes_extension (MetaX11Display *x11_display) +{ + x11_display->xfixes_error_base = 0; + x11_display->xfixes_event_base = 0; + + if (XFixesQueryExtension (x11_display->xdisplay, + &x11_display->xfixes_event_base, + &x11_display->xfixes_error_base)) + { + int xfixes_major, xfixes_minor; + + XFixesQueryVersion (x11_display->xdisplay, &xfixes_major, &xfixes_minor); + + if (xfixes_major * 100 + xfixes_minor < 500) + meta_fatal ("Mutter requires XFixes 5.0"); + } + else + { + meta_fatal ("Mutter requires XFixes 5.0"); + } + + meta_verbose ("Attempted to init XFixes, found error base %d event base %d\n", + x11_display->xfixes_error_base, + x11_display->xfixes_event_base); +} + +static void +query_xi_extension (MetaX11Display *x11_display) +{ + int major = 2, minor = 3; + gboolean has_xi = FALSE; + + if (XQueryExtension (x11_display->xdisplay, + "XInputExtension", + &x11_display->xinput_opcode, + &x11_display->xinput_error_base, + &x11_display->xinput_event_base)) + { + if (XIQueryVersion (x11_display->xdisplay, &major, &minor) == Success) + { + int version = (major * 10) + minor; + if (version >= 22) + has_xi = TRUE; + + if (version >= 23) + x11_display->have_xinput_23 = TRUE; + } + } + + if (!has_xi) + meta_fatal ("X server doesn't have the XInput extension, version 2.2 or newer\n"); +} + +/* + * Initialises the bell subsystem. This involves intialising + * XKB (which, despite being a keyboard extension, is the + * place to look for bell notifications), then asking it + * to send us bell notifications, and then also switching + * off the audible bell if we're using a visual one ourselves. + * + * \bug There is a line of code that's never run that tells + * XKB to reset the bell status after we quit. Bill H said + * (<http://bugzilla.gnome.org/show_bug.cgi?id=99886#c12>) + * that XFree86's implementation is broken so we shouldn't + * call it, but that was in 2002. Is it working now? + */ +static void +init_x11_bell (MetaX11Display *x11_display) +{ + int xkb_base_error_type, xkb_opcode; + + if (!XkbQueryExtension (x11_display->xdisplay, &xkb_opcode, + &x11_display->xkb_base_event_type, + &xkb_base_error_type, + NULL, NULL)) + { + x11_display->xkb_base_event_type = -1; + meta_warning ("could not find XKB extension."); + } + else + { + unsigned int mask = XkbBellNotifyMask; + gboolean visual_bell_auto_reset = FALSE; + /* TRUE if and when non-broken version is available */ + XkbSelectEvents (x11_display->xdisplay, + XkbUseCoreKbd, + XkbBellNotifyMask, + XkbBellNotifyMask); + + if (visual_bell_auto_reset) + { + XkbSetAutoResetControls (x11_display->xdisplay, + XkbAudibleBellMask, + &mask, + &mask); + } + } + + /* We are playing sounds using libcanberra support, we handle the + * bell whether its an audible bell or a visible bell */ + XkbChangeEnabledControls (x11_display->xdisplay, + XkbUseCoreKbd, + XkbAudibleBellMask, + 0); +} + +/* + * \bug This is never called! If we had XkbSetAutoResetControls + * enabled in meta_x11_bell_init(), this wouldn't be a problem, + * but we don't. + */ +G_GNUC_UNUSED static void +shutdown_x11_bell (MetaX11Display *x11_display) +{ + /* TODO: persist initial bell state in display, reset here */ + XkbChangeEnabledControls (x11_display->xdisplay, + XkbUseCoreKbd, + XkbAudibleBellMask, + XkbAudibleBellMask); +} + +static void +set_desktop_geometry_hint (MetaX11Display *x11_display) +{ + unsigned long data[2]; + int monitor_width, monitor_height; + + if (x11_display->display->closing > 0) + return; + + meta_display_get_size (x11_display->display, &monitor_width, &monitor_height); + + data[0] = monitor_width; + data[1] = monitor_height; + + meta_verbose ("Setting _NET_DESKTOP_GEOMETRY to %lu, %lu\n", data[0], data[1]); + + meta_x11_error_trap_push (x11_display); + XChangeProperty (x11_display->xdisplay, + x11_display->xroot, + x11_display->atom__NET_DESKTOP_GEOMETRY, + XA_CARDINAL, + 32, PropModeReplace, (guchar*) data, 2); + meta_x11_error_trap_pop (x11_display); +} + +static void +set_desktop_viewport_hint (MetaX11Display *x11_display) +{ + unsigned long data[2]; + + if (x11_display->display->closing > 0) + return; + + /* + * Mutter does not implement viewports, so this is a fixed 0,0 + */ + data[0] = 0; + data[1] = 0; + + meta_verbose ("Setting _NET_DESKTOP_VIEWPORT to 0, 0\n"); + + meta_x11_error_trap_push (x11_display); + XChangeProperty (x11_display->xdisplay, + x11_display->xroot, + x11_display->atom__NET_DESKTOP_VIEWPORT, + XA_CARDINAL, + 32, PropModeReplace, (guchar*) data, 2); + meta_x11_error_trap_pop (x11_display); +} + +static int +set_wm_check_hint (MetaX11Display *x11_display) +{ + unsigned long data[1]; + + g_return_val_if_fail (x11_display->leader_window != None, 0); + + data[0] = x11_display->leader_window; + + XChangeProperty (x11_display->xdisplay, + x11_display->xroot, + x11_display->atom__NET_SUPPORTING_WM_CHECK, + XA_WINDOW, + 32, PropModeReplace, (guchar*) data, 1); + + return Success; +} + +static void +unset_wm_check_hint (MetaX11Display *x11_display) +{ + XDeleteProperty (x11_display->xdisplay, + x11_display->xroot, + x11_display->atom__NET_SUPPORTING_WM_CHECK); +} + +static int +set_supported_hint (MetaX11Display *x11_display) +{ + Atom atoms[] = { +#define EWMH_ATOMS_ONLY +#define item(x) x11_display->atom_##x, +#include "x11/atomnames.h" +#undef item +#undef EWMH_ATOMS_ONLY + + x11_display->atom__GTK_FRAME_EXTENTS, + x11_display->atom__GTK_SHOW_WINDOW_MENU, + x11_display->atom__GTK_EDGE_CONSTRAINTS, + x11_display->atom__GTK_WORKAREAS, + }; + + XChangeProperty (x11_display->xdisplay, + x11_display->xroot, + x11_display->atom__NET_SUPPORTED, + XA_ATOM, + 32, PropModeReplace, + (guchar*) atoms, G_N_ELEMENTS(atoms)); + + return Success; +} + +static int +set_wm_icon_size_hint (MetaX11Display *x11_display) +{ +#define N_VALS 6 + gulong vals[N_VALS]; + + /* We've bumped the real icon size up to 96x96, but + * we really should not add these sorts of constraints + * on clients still using the legacy WM_HINTS interface. + */ +#define LEGACY_ICON_SIZE 32 + + /* min width, min height, max w, max h, width inc, height inc */ + vals[0] = LEGACY_ICON_SIZE; + vals[1] = LEGACY_ICON_SIZE; + vals[2] = LEGACY_ICON_SIZE; + vals[3] = LEGACY_ICON_SIZE; + vals[4] = 0; + vals[5] = 0; +#undef LEGACY_ICON_SIZE + + XChangeProperty (x11_display->xdisplay, + x11_display->xroot, + x11_display->atom_WM_ICON_SIZE, + XA_CARDINAL, + 32, PropModeReplace, (guchar*) vals, N_VALS); + + return Success; +#undef N_VALS +} + +static Window +take_manager_selection (MetaX11Display *x11_display, + Window xroot, + Atom manager_atom, + int timestamp, + gboolean should_replace) +{ + Window current_owner, new_owner; + + current_owner = XGetSelectionOwner (x11_display->xdisplay, manager_atom); + if (current_owner != None) + { + XSetWindowAttributes attrs; + + if (should_replace) + { + /* We want to find out when the current selection owner dies */ + meta_x11_error_trap_push (x11_display); + attrs.event_mask = StructureNotifyMask; + XChangeWindowAttributes (x11_display->xdisplay, current_owner, CWEventMask, &attrs); + if (meta_x11_error_trap_pop_with_return (x11_display) != Success) + current_owner = None; /* don't wait for it to die later on */ + } + else + { + meta_warning (_("Display “%s” already has a window manager; try using the --replace option to replace the current window manager."), + x11_display->name); + return None; + } + } + + /* We need SelectionClear and SelectionRequest events on the new owner, + * but those cannot be masked, so we only need NoEventMask. + */ + new_owner = meta_x11_display_create_offscreen_window (x11_display, xroot, NoEventMask); + + XSetSelectionOwner (x11_display->xdisplay, manager_atom, new_owner, timestamp); + + if (XGetSelectionOwner (x11_display->xdisplay, manager_atom) != new_owner) + { + meta_warning ("Could not acquire selection: %s", XGetAtomName (x11_display->xdisplay, manager_atom)); + return None; + } + + { + /* Send client message indicating that we are now the selection owner */ + XClientMessageEvent ev; + + ev.type = ClientMessage; + ev.window = xroot; + ev.message_type = x11_display->atom_MANAGER; + ev.format = 32; + ev.data.l[0] = timestamp; + ev.data.l[1] = manager_atom; + + XSendEvent (x11_display->xdisplay, xroot, False, StructureNotifyMask, (XEvent *) &ev); + } + + /* Wait for old window manager to go away */ + if (current_owner != None) + { + XEvent event; + + /* We sort of block infinitely here which is probably lame. */ + + meta_verbose ("Waiting for old window manager to exit\n"); + do + XWindowEvent (x11_display->xdisplay, current_owner, StructureNotifyMask, &event); + while (event.type != DestroyNotify); + } + + return new_owner; +} + +/* Create the leader window here. Set its properties and + * use the timestamp from one of the PropertyNotify events + * that will follow. + */ +static void +init_leader_window (MetaX11Display *x11_display, + guint32 *timestamp) +{ + gulong data[1]; + XEvent event; + + /* We only care about the PropertyChangeMask in the next 30 or so lines of + * code. Note that gdk will at some point unset the PropertyChangeMask for + * this window, so we can't rely on it still being set later. See bug + * 354213 for details. + */ + x11_display->leader_window = + meta_x11_display_create_offscreen_window (x11_display, + x11_display->xroot, + PropertyChangeMask); + + meta_prop_set_utf8_string_hint (x11_display, + x11_display->leader_window, + x11_display->atom__NET_WM_NAME, + net_wm_name); + + meta_prop_set_utf8_string_hint (x11_display, + x11_display->leader_window, + x11_display->atom__GNOME_WM_KEYBINDINGS, + gnome_wm_keybindings); + + meta_prop_set_utf8_string_hint (x11_display, + x11_display->leader_window, + x11_display->atom__MUTTER_VERSION, + VERSION); + + data[0] = x11_display->leader_window; + XChangeProperty (x11_display->xdisplay, + x11_display->leader_window, + x11_display->atom__NET_SUPPORTING_WM_CHECK, + XA_WINDOW, + 32, PropModeReplace, (guchar*) data, 1); + + XWindowEvent (x11_display->xdisplay, + x11_display->leader_window, + PropertyChangeMask, + &event); + + if (timestamp) + *timestamp = event.xproperty.time; + + /* Make it painfully clear that we can't rely on PropertyNotify events on + * this window, as per bug 354213. + */ + XSelectInput (x11_display->xdisplay, + x11_display->leader_window, + NoEventMask); +} + +static void +init_event_masks (MetaX11Display *x11_display) +{ + long event_mask; + unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; + XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; + + XISetMask (mask.mask, XI_Enter); + XISetMask (mask.mask, XI_Leave); + XISetMask (mask.mask, XI_FocusIn); + XISetMask (mask.mask, XI_FocusOut); + if (META_X11_DISPLAY_HAS_XINPUT_23 (x11_display)) + { + XISetMask (mask.mask, XI_BarrierHit); + XISetMask (mask.mask, XI_BarrierLeave); + } + XISelectEvents (x11_display->xdisplay, x11_display->xroot, &mask, 1); + + event_mask = (SubstructureRedirectMask | SubstructureNotifyMask | + StructureNotifyMask | ColormapChangeMask | PropertyChangeMask); + XSelectInput (x11_display->xdisplay, x11_display->xroot, event_mask); +} + +static void +set_active_workspace_hint (MetaWorkspaceManager *workspace_manager, + MetaX11Display *x11_display) +{ + unsigned long data[1]; + + /* this is because we destroy the spaces in order, + * so we always end up setting a current desktop of + * 0 when closing a screen, so lose the current desktop + * on restart. By doing this we keep the current + * desktop on restart. + */ + if (x11_display->display->closing > 0) + return; + + data[0] = meta_workspace_index (workspace_manager->active_workspace); + + meta_verbose ("Setting _NET_CURRENT_DESKTOP to %lu\n", data[0]); + + meta_x11_error_trap_push (x11_display); + XChangeProperty (x11_display->xdisplay, + x11_display->xroot, + x11_display->atom__NET_CURRENT_DESKTOP, + XA_CARDINAL, + 32, PropModeReplace, (guchar*) data, 1); + meta_x11_error_trap_pop (x11_display); +} + +static void +set_number_of_spaces_hint (MetaWorkspaceManager *workspace_manager, + GParamSpec *pspec, + gpointer user_data) +{ + MetaX11Display *x11_display = user_data; + unsigned long data[1]; + + if (x11_display->display->closing > 0) + return; + + data[0] = meta_workspace_manager_get_n_workspaces (workspace_manager); + + meta_verbose ("Setting _NET_NUMBER_OF_DESKTOPS to %lu\n", data[0]); + + meta_x11_error_trap_push (x11_display); + XChangeProperty (x11_display->xdisplay, + x11_display->xroot, + x11_display->atom__NET_NUMBER_OF_DESKTOPS, + XA_CARDINAL, + 32, PropModeReplace, (guchar*) data, 1); + meta_x11_error_trap_pop (x11_display); +} + +static void +set_showing_desktop_hint (MetaWorkspaceManager *workspace_manager, + MetaX11Display *x11_display) +{ + unsigned long data[1]; + + data[0] = workspace_manager->active_workspace->showing_desktop ? 1 : 0; + + meta_x11_error_trap_push (x11_display); + XChangeProperty (x11_display->xdisplay, + x11_display->xroot, + x11_display->atom__NET_SHOWING_DESKTOP, + XA_CARDINAL, + 32, PropModeReplace, (guchar*) data, 1); + meta_x11_error_trap_pop (x11_display); +} + +static void +set_workspace_names (MetaX11Display *x11_display) +{ + MetaWorkspaceManager *workspace_manager; + GString *flattened; + int i; + int n_spaces; + + workspace_manager = x11_display->display->workspace_manager; + + /* flatten to nul-separated list */ + n_spaces = meta_workspace_manager_get_n_workspaces (workspace_manager); + flattened = g_string_new (""); + i = 0; + while (i < n_spaces) + { + const char *name; + + name = meta_prefs_get_workspace_name (i); + + if (name) + g_string_append_len (flattened, name, + strlen (name) + 1); + else + g_string_append_len (flattened, "", 1); + + ++i; + } + + meta_x11_error_trap_push (x11_display); + XChangeProperty (x11_display->xdisplay, + x11_display->xroot, + x11_display->atom__NET_DESKTOP_NAMES, + x11_display->atom_UTF8_STRING, + 8, PropModeReplace, + (unsigned char *)flattened->str, flattened->len); + meta_x11_error_trap_pop (x11_display); + + g_string_free (flattened, TRUE); +} + +static void +set_workspace_work_area_hint (MetaWorkspace *workspace, + MetaX11Display *x11_display) +{ + MetaMonitorManager *monitor_manager; + GList *logical_monitors; + GList *l; + int num_monitors; + unsigned long *data; + unsigned long *tmp; + g_autofree char *workarea_name; + Atom workarea_atom; + + monitor_manager = meta_backend_get_monitor_manager (meta_get_backend ()); + logical_monitors = meta_monitor_manager_get_logical_monitors (monitor_manager); + num_monitors = meta_monitor_manager_get_num_logical_monitors (monitor_manager); + + data = g_new (unsigned long, num_monitors * 4); + tmp = data; + + for (l = logical_monitors; l; l = l->next) + { + MetaRectangle area; + + meta_workspace_get_work_area_for_logical_monitor (workspace, l->data, &area); + + tmp[0] = area.x; + tmp[1] = area.y; + tmp[2] = area.width; + tmp[3] = area.height; + + tmp += 4; + } + + workarea_name = g_strdup_printf ("_GTK_WORKAREAS_D%d", + meta_workspace_index (workspace)); + + workarea_atom = XInternAtom (x11_display->xdisplay, workarea_name, False); + + meta_x11_error_trap_push (x11_display); + XChangeProperty (x11_display->xdisplay, + x11_display->xroot, + workarea_atom, + XA_CARDINAL, 32, PropModeReplace, + (guchar*) data, num_monitors * 4); + meta_x11_error_trap_pop (x11_display); + + g_free (data); +} + +static void +set_work_area_hint (MetaDisplay *display, + MetaX11Display *x11_display) +{ + MetaWorkspaceManager *workspace_manager = display->workspace_manager; + int num_workspaces; + GList *l; + unsigned long *data, *tmp; + MetaRectangle area; + + num_workspaces = meta_workspace_manager_get_n_workspaces (workspace_manager); + data = g_new (unsigned long, num_workspaces * 4); + tmp = data; + + for (l = workspace_manager->workspaces; l; l = l->next) + { + MetaWorkspace *workspace = l->data; + + meta_workspace_get_work_area_all_monitors (workspace, &area); + set_workspace_work_area_hint (workspace, x11_display); + + tmp[0] = area.x; + tmp[1] = area.y; + tmp[2] = area.width; + tmp[3] = area.height; + + tmp += 4; + } + + meta_x11_error_trap_push (x11_display); + XChangeProperty (x11_display->xdisplay, + x11_display->xroot, + x11_display->atom__NET_WORKAREA, + XA_CARDINAL, 32, PropModeReplace, + (guchar*) data, num_workspaces*4); + meta_x11_error_trap_pop (x11_display); + + g_free (data); +} + +/** + * meta_set_wm_name: (skip) + * @wm_name: value for _NET_WM_NAME + * + * Set the value to use for the _NET_WM_NAME property. To take effect, + * it is necessary to call this function before meta_init(). + */ +void +meta_set_wm_name (const char *wm_name) +{ + g_return_if_fail (meta_get_display () == NULL); + + net_wm_name = wm_name; +} + +/** + * meta_set_gnome_wm_keybindings: (skip) + * @wm_keybindings: value for _GNOME_WM_KEYBINDINGS + * + * Set the value to use for the _GNOME_WM_KEYBINDINGS property. To take + * effect, it is necessary to call this function before meta_init(). + */ +void +meta_set_gnome_wm_keybindings (const char *wm_keybindings) +{ + g_return_if_fail (meta_get_display () == NULL); + + gnome_wm_keybindings = wm_keybindings; +} + +const gchar * +meta_x11_get_display_name (void) +{ +#ifdef HAVE_WAYLAND + if (meta_is_wayland_compositor ()) + { + MetaWaylandCompositor *compositor; + + compositor = meta_wayland_compositor_get_default (); + + return meta_wayland_get_xwayland_display_name (compositor); + } + else +#endif + { + return g_getenv ("DISPLAY"); + } +} + +gboolean +meta_x11_init_gdk_display (GError **error) +{ + const char *xdisplay_name; + GdkDisplay *gdk_display; + const char *gdk_gl_env = NULL; + Display *xdisplay; + + xdisplay_name = meta_x11_get_display_name (); + if (!xdisplay_name) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Unable to open display, DISPLAY not set"); + return FALSE; + } + + gdk_set_allowed_backends ("x11"); + + gdk_gl_env = g_getenv ("GDK_GL"); + g_setenv ("GDK_GL", "disable", TRUE); + + gdk_parse_args (NULL, NULL); + if (!gtk_parse_args (NULL, NULL)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Failed to initialize gtk"); + return FALSE; + } + + gdk_display = gdk_display_open (xdisplay_name); + + if (!gdk_display) + { + meta_warning (_("Failed to initialize GDK\n")); + + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Failed to initialize GDK"); + + return FALSE; + } + + if (gdk_gl_env) + g_setenv("GDK_GL", gdk_gl_env, TRUE); + else + unsetenv("GDK_GL"); + + /* We need to be able to fully trust that the window and monitor sizes + that Gdk reports corresponds to the X ones, so we disable the automatic + scale handling */ + gdk_x11_display_set_window_scale (gdk_display, 1); + + meta_verbose ("Opening display '%s'\n", XDisplayName (NULL)); + + xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display); + + if (xdisplay == NULL) + { + meta_warning (_("Failed to open X Window System display “%s”\n"), + XDisplayName (NULL)); + + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Failed to open X11 display"); + + gdk_display_close (gdk_display); + + return FALSE; + } + + prepared_gdk_display = gdk_display; + + return TRUE; +} + +/** + * meta_x11_display_new: + * + * Opens a new X11 display, sets it up, initialises all the X extensions + * we will need. + * + * Returns: #MetaX11Display if the display was opened successfully, + * and %NULL otherwise-- that is, if the display doesn't exist or + * it already has a window manager, and sets the error appropriately. + */ +MetaX11Display * +meta_x11_display_new (MetaDisplay *display, GError **error) +{ + MetaX11Display *x11_display; + Display *xdisplay; + Screen *xscreen; + Window xroot; + int i, number; + Window new_wm_sn_owner; + gboolean replace_current_wm; + Atom wm_sn_atom; + char buf[128]; + guint32 timestamp; + Atom atom_restart_helper; + Window restart_helper_window = None; + GdkDisplay *gdk_display; + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + + /* A list of all atom names, so that we can intern them in one go. */ + const char *atom_names[] = { +#define item(x) #x, +#include "x11/atomnames.h" +#undef item + }; + Atom atoms[G_N_ELEMENTS(atom_names)]; + + if (!meta_x11_init_gdk_display (error)) + return NULL; + + g_assert (prepared_gdk_display); + gdk_display = g_steal_pointer (&prepared_gdk_display); + xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display); + +#ifdef HAVE_WAYLAND + if (meta_is_wayland_compositor ()) + meta_xwayland_complete_init (display, xdisplay); +#endif + + if (meta_is_syncing ()) + XSynchronize (xdisplay, True); + + replace_current_wm = meta_get_replace_current_wm (); + + /* According to _gdk_x11_display_open (), this will be returned + * by gdk_display_get_default_screen () + */ + number = DefaultScreen (xdisplay); + + xroot = RootWindow (xdisplay, number); + + /* FVWM checks for None here, I don't know if this + * ever actually happens + */ + if (xroot == None) + { + meta_warning (_("Screen %d on display “%s” is invalid\n"), + number, XDisplayName (NULL)); + + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Failed to open default X11 screen"); + + XFlush (xdisplay); + XCloseDisplay (xdisplay); + + gdk_display_close (gdk_display); + + return NULL; + } + + xscreen = ScreenOfDisplay (xdisplay, number); + + atom_restart_helper = XInternAtom (xdisplay, "_MUFFIN_RESTART_HELPER", False); + restart_helper_window = XGetSelectionOwner (xdisplay, atom_restart_helper); + if (restart_helper_window) + meta_set_is_restart (TRUE); + + x11_display = g_object_new (META_TYPE_X11_DISPLAY, NULL); + x11_display->gdk_display = gdk_display; + x11_display->display = display; + + /* here we use XDisplayName which is what the user + * probably put in, vs. DisplayString(display) which is + * canonicalized by XOpenDisplay() + */ + x11_display->xdisplay = xdisplay; + x11_display->xroot = xroot; + + x11_display->name = g_strdup (XDisplayName (NULL)); + x11_display->screen_name = get_screen_name (xdisplay, number); + x11_display->default_xvisual = DefaultVisualOfScreen (xscreen); + x11_display->default_depth = DefaultDepthOfScreen (xscreen); + + meta_verbose ("Creating %d atoms\n", (int) G_N_ELEMENTS (atom_names)); + XInternAtoms (xdisplay, (char **)atom_names, G_N_ELEMENTS (atom_names), + False, atoms); + + i = 0; +#define item(x) x11_display->atom_##x = atoms[i++]; +#include "x11/atomnames.h" +#undef item + + query_xsync_extension (x11_display); + query_xshape_extension (x11_display); + query_xcomposite_extension (x11_display); + query_xdamage_extension (x11_display); + query_xfixes_extension (x11_display); + query_xi_extension (x11_display); + + g_signal_connect_object (display, + "cursor-updated", + G_CALLBACK (update_cursor_theme), + x11_display, + G_CONNECT_SWAPPED); + + update_cursor_theme (x11_display); + + x11_display->xids = g_hash_table_new (meta_unsigned_long_hash, + meta_unsigned_long_equal); + + x11_display->groups_by_leader = NULL; + x11_display->ui = NULL; + x11_display->composite_overlay_window = None; + x11_display->guard_window = None; + x11_display->leader_window = None; + x11_display->timestamp_pinging_window = None; + x11_display->wm_sn_selection_window = None; + + x11_display->display_close_idle = 0; + x11_display->xselectionclear_timestamp = 0; + + x11_display->last_bell_time = 0; + x11_display->focus_serial = 0; + x11_display->server_focus_window = None; + x11_display->server_focus_serial = 0; + + x11_display->prop_hooks = NULL; + meta_x11_display_init_window_prop_hooks (x11_display); + x11_display->group_prop_hooks = NULL; + meta_x11_display_init_group_prop_hooks (x11_display); + + g_signal_connect_object (monitor_manager, + "monitors-changed-internal", + G_CALLBACK (on_monitors_changed_internal), + x11_display, + 0); + + init_leader_window (x11_display, ×tamp); + x11_display->timestamp = timestamp; + + /* Make a little window used only for pinging the server for timestamps; note + * that meta_create_offscreen_window already selects for PropertyChangeMask. + */ + x11_display->timestamp_pinging_window = + meta_x11_display_create_offscreen_window (x11_display, + xroot, + PropertyChangeMask); + + sprintf (buf, "WM_S%d", number); + + wm_sn_atom = XInternAtom (xdisplay, buf, False); + new_wm_sn_owner = take_manager_selection (x11_display, xroot, wm_sn_atom, timestamp, replace_current_wm); + if (new_wm_sn_owner == None) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Failed to acquire window manager ownership"); + + g_object_run_dispose (G_OBJECT (x11_display)); + g_clear_object (&x11_display); + + return NULL; + } + + x11_display->wm_sn_selection_window = new_wm_sn_owner; + x11_display->wm_sn_atom = wm_sn_atom; + x11_display->wm_sn_timestamp = timestamp; + + init_event_masks (x11_display); + + /* Select for cursor changes so the cursor tracker is up to date. */ + XFixesSelectCursorInput (xdisplay, xroot, XFixesDisplayCursorNotifyMask); + + /* If we're a Wayland compositor, then we don't grab the COW, since it + * will map it. */ + if (!meta_is_wayland_compositor ()) + x11_display->composite_overlay_window = XCompositeGetOverlayWindow (xdisplay, xroot); + + /* Now that we've gotten taken a reference count on the COW, we + * can close the helper that is holding on to it */ + if (meta_is_restart ()) + XSetSelectionOwner (xdisplay, atom_restart_helper, None, META_CURRENT_TIME); + + /* Handle creating a no_focus_window for this screen */ + x11_display->no_focus_window = + meta_x11_display_create_offscreen_window (x11_display, + xroot, + FocusChangeMask|KeyPressMask|KeyReleaseMask); + XMapWindow (xdisplay, x11_display->no_focus_window); + /* Done with no_focus_window stuff */ + + meta_x11_display_init_events (x11_display); + + set_wm_icon_size_hint (x11_display); + + set_supported_hint (x11_display); + + set_wm_check_hint (x11_display); + + set_desktop_viewport_hint (x11_display); + + set_desktop_geometry_hint (x11_display); + + x11_display->ui = meta_ui_new (x11_display); + x11_display->x11_stack = meta_x11_stack_new (x11_display); + + x11_display->keys_grabbed = FALSE; + meta_x11_display_grab_keys (x11_display); + + meta_x11_display_update_workspace_layout (x11_display); + + if (meta_prefs_get_dynamic_workspaces ()) + { + int num = 0; + int n_items = 0; + uint32_t *list = NULL; + + if (meta_prop_get_cardinal_list (x11_display, + x11_display->xroot, + x11_display->atom__NET_NUMBER_OF_DESKTOPS, + &list, &n_items)) + { + num = list[0]; + g_free (list); + } + + if (num > meta_workspace_manager_get_n_workspaces (display->workspace_manager)) + meta_workspace_manager_update_num_workspaces (display->workspace_manager, timestamp, num); + } + + g_signal_connect_object (display->workspace_manager, "active-workspace-changed", + G_CALLBACK (set_active_workspace_hint), + x11_display, 0); + + set_number_of_spaces_hint (display->workspace_manager, NULL, x11_display); + + g_signal_connect_object (display->workspace_manager, "notify::n-workspaces", + G_CALLBACK (set_number_of_spaces_hint), + x11_display, 0); + + set_showing_desktop_hint (display->workspace_manager, x11_display); + + g_signal_connect_object (display->workspace_manager, "showing-desktop-changed", + G_CALLBACK (set_showing_desktop_hint), + x11_display, 0); + + set_workspace_names (x11_display); + + meta_prefs_add_listener (prefs_changed_callback, x11_display); + + set_work_area_hint (display, x11_display); + + g_signal_connect_object (display, "workareas-changed", + G_CALLBACK (set_work_area_hint), + x11_display, 0); + + init_x11_bell (x11_display); + + meta_x11_startup_notification_init (x11_display); + meta_x11_selection_init (x11_display); + + if (!meta_is_wayland_compositor ()) + meta_dnd_init_xdnd (x11_display); + + return x11_display; +} + +void +meta_x11_display_restore_active_workspace (MetaX11Display *x11_display) +{ + MetaDisplay *display; + MetaWorkspace *current_workspace; + uint32_t current_workspace_index = 0; + guint32 timestamp; + + g_return_if_fail (META_IS_X11_DISPLAY (x11_display)); + + display = x11_display->display; + timestamp = x11_display->timestamp; + + /* Get current workspace */ + if (meta_prop_get_cardinal (x11_display, + x11_display->xroot, + x11_display->atom__NET_CURRENT_DESKTOP, + ¤t_workspace_index)) + { + meta_verbose ("Read existing _NET_CURRENT_DESKTOP = %d\n", + (int) current_workspace_index); + + /* Switch to the _NET_CURRENT_DESKTOP workspace */ + current_workspace = meta_workspace_manager_get_workspace_by_index (display->workspace_manager, + current_workspace_index); + + if (current_workspace != NULL) + meta_workspace_activate (current_workspace, timestamp); + } + else + { + meta_verbose ("No _NET_CURRENT_DESKTOP present\n"); + } + + set_active_workspace_hint (display->workspace_manager, x11_display); +} + +int +meta_x11_display_get_screen_number (MetaX11Display *x11_display) +{ + return DefaultScreen (x11_display->xdisplay); +} + +MetaDisplay * +meta_x11_display_get_display (MetaX11Display *x11_display) +{ + return x11_display->display; +} + +/** + * meta_x11_display_get_xdisplay: (skip) + * @x11_display: a #MetaX11Display + * + */ +Display * +meta_x11_display_get_xdisplay (MetaX11Display *x11_display) +{ + return x11_display->xdisplay; +} + +/** + * meta_x11_display_get_xroot: (skip) + * @x11_display: A #MetaX11Display + * + */ +Window +meta_x11_display_get_xroot (MetaX11Display *x11_display) +{ + return x11_display->xroot; +} + +/** + * meta_x11_display_get_xinput_opcode: (skip) + * @x11_display: a #MetaX11Display + * + */ +int +meta_x11_display_get_xinput_opcode (MetaX11Display *x11_display) +{ + return x11_display->xinput_opcode; +} + +int +meta_x11_display_get_damage_event_base (MetaX11Display *x11_display) +{ + return x11_display->damage_event_base; +} + +int +meta_x11_display_get_shape_event_base (MetaX11Display *x11_display) +{ + return x11_display->shape_event_base; +} + +gboolean +meta_x11_display_has_shape (MetaX11Display *x11_display) +{ + return META_X11_DISPLAY_HAS_SHAPE (x11_display); +} + +Window +meta_x11_display_create_offscreen_window (MetaX11Display *x11_display, + Window parent, + long valuemask) +{ + XSetWindowAttributes attrs; + + /* we want to be override redirect because sometimes we + * create a window on a screen we aren't managing. + * (but on a display we are managing at least one screen for) + */ + attrs.override_redirect = True; + attrs.event_mask = valuemask; + + return XCreateWindow (x11_display->xdisplay, + parent, + -100, -100, 1, 1, + 0, + CopyFromParent, + CopyFromParent, + (Visual *)CopyFromParent, + CWOverrideRedirect | CWEventMask, + &attrs); +} + +Cursor +meta_x11_display_create_x_cursor (MetaX11Display *x11_display, + MetaCursor cursor) +{ + return meta_create_x_cursor (x11_display->xdisplay, cursor); +} + +static char * +get_screen_name (Display *xdisplay, + int number) +{ + char *p; + char *dname; + char *scr; + + /* DisplayString gives us a sort of canonical display, + * vs. the user-entered name from XDisplayName() + */ + dname = g_strdup (DisplayString (xdisplay)); + + /* Change display name to specify this screen. + */ + p = strrchr (dname, ':'); + if (p) + { + p = strchr (p, '.'); + if (p) + *p = '\0'; + } + + scr = g_strdup_printf ("%s.%d", dname, number); + + g_free (dname); + + return scr; +} + +void +meta_x11_display_reload_cursor (MetaX11Display *x11_display) +{ + Cursor xcursor; + MetaCursor cursor = x11_display->display->current_cursor; + + /* Set a cursor for X11 applications that don't specify their own */ + xcursor = meta_x11_display_create_x_cursor (x11_display, cursor); + + XDefineCursor (x11_display->xdisplay, x11_display->xroot, xcursor); + XFlush (x11_display->xdisplay); + + if (xcursor) + XFreeCursor (x11_display->xdisplay, xcursor); +} + +static void +set_cursor_theme (Display *xdisplay) +{ + MetaBackend *backend = meta_get_backend (); + MetaSettings *settings = meta_backend_get_settings (backend); + int scale; + + scale = meta_settings_get_ui_scaling_factor (settings); + XcursorSetTheme (xdisplay, meta_prefs_get_cursor_theme ()); + XcursorSetDefaultSize (xdisplay, meta_prefs_get_cursor_size () * scale); +} + +static void +update_cursor_theme (MetaX11Display *x11_display) +{ + MetaBackend *backend = meta_get_backend (); + + set_cursor_theme (x11_display->xdisplay); + meta_x11_display_reload_cursor (x11_display); + + if (META_IS_BACKEND_X11 (backend)) + { + MetaBackendX11 *backend_x11 = META_BACKEND_X11 (backend); + Display *xdisplay = meta_backend_x11_get_xdisplay (backend_x11); + + set_cursor_theme (xdisplay); + meta_backend_x11_reload_cursor (backend_x11); + } +} + +MetaWindow * +meta_x11_display_lookup_x_window (MetaX11Display *x11_display, + Window xwindow) +{ + return g_hash_table_lookup (x11_display->xids, &xwindow); +} + +void +meta_x11_display_register_x_window (MetaX11Display *x11_display, + Window *xwindowp, + MetaWindow *window) +{ + g_return_if_fail (g_hash_table_lookup (x11_display->xids, xwindowp) == NULL); + + g_hash_table_insert (x11_display->xids, xwindowp, window); +} + +void +meta_x11_display_unregister_x_window (MetaX11Display *x11_display, + Window xwindow) +{ + g_return_if_fail (g_hash_table_lookup (x11_display->xids, &xwindow) != NULL); + + g_hash_table_remove (x11_display->xids, &xwindow); +} + + +/* We store sync alarms in the window ID hash table, because they are + * just more types of XIDs in the same global space, but we have + * typesafe functions to register/unregister for readability. + */ + +MetaWindow * +meta_x11_display_lookup_sync_alarm (MetaX11Display *x11_display, + XSyncAlarm alarm) +{ + return g_hash_table_lookup (x11_display->xids, &alarm); +} + +void +meta_x11_display_register_sync_alarm (MetaX11Display *x11_display, + XSyncAlarm *alarmp, + MetaWindow *window) +{ + g_return_if_fail (g_hash_table_lookup (x11_display->xids, alarmp) == NULL); + + g_hash_table_insert (x11_display->xids, alarmp, window); +} + +void +meta_x11_display_unregister_sync_alarm (MetaX11Display *x11_display, + XSyncAlarm alarm) +{ + g_return_if_fail (g_hash_table_lookup (x11_display->xids, &alarm) != NULL); + + g_hash_table_remove (x11_display->xids, &alarm); +} + +void +meta_x11_display_set_alarm_filter (MetaX11Display *x11_display, + MetaAlarmFilter filter, + gpointer data) +{ + g_return_if_fail (filter == NULL || x11_display->alarm_filter == NULL); + + x11_display->alarm_filter = filter; + x11_display->alarm_filter_data = data; +} + +/* The guard window allows us to leave minimized windows mapped so + * that compositor code may provide live previews of them. + * Instead of being unmapped/withdrawn, they get pushed underneath + * the guard window. We also select events on the guard window, which + * should effectively be forwarded to events on the background actor, + * providing that the scene graph is set up correctly. + */ +static Window +create_guard_window (MetaX11Display *x11_display) +{ + XSetWindowAttributes attributes; + Window guard_window; + gulong create_serial; + int display_width, display_height; + + meta_display_get_size (x11_display->display, + &display_width, + &display_height); + + attributes.event_mask = NoEventMask; + attributes.override_redirect = True; + + /* We have to call record_add() after we have the new window ID, + * so save the serial for the CreateWindow request until then */ + create_serial = XNextRequest (x11_display->xdisplay); + guard_window = + XCreateWindow (x11_display->xdisplay, + x11_display->xroot, + 0, /* x */ + 0, /* y */ + display_width, + display_height, + 0, /* border width */ + 0, /* depth */ + InputOnly, /* class */ + CopyFromParent, /* visual */ + CWEventMask | CWOverrideRedirect, + &attributes); + + /* https://bugzilla.gnome.org/show_bug.cgi?id=710346 */ + XStoreName (x11_display->xdisplay, guard_window, "mutter guard window"); + + { + if (!meta_is_wayland_compositor ()) + { + MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ()); + Display *backend_xdisplay = meta_backend_x11_get_xdisplay (backend); + unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; + XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; + + XISetMask (mask.mask, XI_ButtonPress); + XISetMask (mask.mask, XI_ButtonRelease); + XISetMask (mask.mask, XI_Motion); + + /* Sync on the connection we created the window on to + * make sure it's created before we select on it on the + * backend connection. */ + XSync (x11_display->xdisplay, False); + + XISelectEvents (backend_xdisplay, guard_window, &mask, 1); + } + } + + meta_stack_tracker_record_add (x11_display->display->stack_tracker, + guard_window, + create_serial); + + meta_stack_tracker_lower (x11_display->display->stack_tracker, + guard_window); + + XMapWindow (x11_display->xdisplay, guard_window); + return guard_window; +} + +void +meta_x11_display_create_guard_window (MetaX11Display *x11_display) +{ + if (x11_display->guard_window == None) + x11_display->guard_window = create_guard_window (x11_display); +} + +static void +on_monitors_changed_internal (MetaMonitorManager *monitor_manager, + MetaX11Display *x11_display) +{ + int display_width, display_height; + + meta_monitor_manager_get_screen_size (monitor_manager, + &display_width, + &display_height); + + set_desktop_geometry_hint (x11_display); + + /* Resize the guard window to fill the screen again. */ + if (x11_display->guard_window != None) + { + XWindowChanges changes; + + changes.x = 0; + changes.y = 0; + changes.width = display_width; + changes.height = display_height; + + XConfigureWindow (x11_display->xdisplay, + x11_display->guard_window, + CWX | CWY | CWWidth | CWHeight, + &changes); + } + + x11_display->has_xinerama_indices = FALSE; +} + +void +meta_x11_display_set_cm_selection (MetaX11Display *x11_display) +{ + char selection[32]; + Atom a; + guint32 timestamp; + + timestamp = meta_x11_display_get_current_time_roundtrip (x11_display); + g_snprintf (selection, sizeof (selection), "_NET_WM_CM_S%d", + DefaultScreen (x11_display->xdisplay)); + a = XInternAtom (x11_display->xdisplay, selection, False); + + x11_display->wm_cm_selection_window = take_manager_selection (x11_display, x11_display->xroot, a, timestamp, TRUE); +} + +static Bool +find_timestamp_predicate (Display *xdisplay, + XEvent *ev, + XPointer arg) +{ + MetaX11Display *x11_display = (MetaX11Display *) arg; + + return (ev->type == PropertyNotify && + ev->xproperty.atom == x11_display->atom__MUTTER_TIMESTAMP_PING); +} + +/* Get a timestamp, even if it means a roundtrip */ +guint32 +meta_x11_display_get_current_time_roundtrip (MetaX11Display *x11_display) +{ + guint32 timestamp; + + timestamp = meta_display_get_current_time (x11_display->display); + if (timestamp == META_CURRENT_TIME) + { + XEvent property_event; + + XChangeProperty (x11_display->xdisplay, + x11_display->timestamp_pinging_window, + x11_display->atom__MUTTER_TIMESTAMP_PING, + XA_STRING, 8, PropModeAppend, NULL, 0); + XIfEvent (x11_display->xdisplay, + &property_event, + find_timestamp_predicate, + (XPointer) x11_display); + timestamp = property_event.xproperty.time; + } + + meta_display_sanity_check_timestamps (x11_display->display, timestamp); + + return timestamp; +} + +/** + * meta_x11_display_xwindow_is_a_no_focus_window: + * @x11_display: A #MetaX11Display + * @xwindow: An X11 window + * + * Returns: %TRUE iff window is one of mutter's internal "no focus" windows + * which will have the focus when there is no actual client window focused. + */ +gboolean +meta_x11_display_xwindow_is_a_no_focus_window (MetaX11Display *x11_display, + Window xwindow) +{ + return xwindow == x11_display->no_focus_window; +} + +void +meta_x11_display_increment_event_serial (MetaX11Display *x11_display) + +{ + /* We just make some random X request */ + XDeleteProperty (x11_display->xdisplay, + x11_display->leader_window, + x11_display->atom__MOTIF_WM_HINTS); +} + +static void +meta_x11_display_update_active_window_hint (MetaX11Display *x11_display) +{ + MetaWindow *focus_window; + gulong data[1]; + + if (x11_display->display->closing) + return; /* Leave old value for a replacement */ + + focus_window = meta_x11_display_lookup_x_window (x11_display, + x11_display->focus_xwindow); + + if (focus_window) + data[0] = focus_window->xwindow; + else + data[0] = None; + + meta_x11_error_trap_push (x11_display); + XChangeProperty (x11_display->xdisplay, + x11_display->xroot, + x11_display->atom__NET_ACTIVE_WINDOW, + XA_WINDOW, + 32, PropModeReplace, (guchar*) data, 1); + meta_x11_error_trap_pop (x11_display); +} + +void +meta_x11_display_update_focus_window (MetaX11Display *x11_display, + Window xwindow, + gulong serial, + gboolean focused_by_us) +{ + x11_display->focus_serial = serial; + x11_display->focused_by_us = !!focused_by_us; + + if (x11_display->focus_xwindow == xwindow) + return; + + x11_display->focus_xwindow = xwindow; + meta_x11_display_update_active_window_hint (x11_display); +} + +static void +meta_x11_display_set_input_focus_internal (MetaX11Display *x11_display, + Window xwindow, + uint32_t timestamp) +{ + meta_x11_error_trap_push (x11_display); + + /* In order for mutter to know that the focus request succeeded, we track + * the serial of the "focus request" we made, but if we take the serial + * of the XSetInputFocus request, then there's no way to determine the + * difference between focus events as a result of the SetInputFocus and + * focus events that other clients send around the same time. Ensure that + * we know which is which by making two requests that the server will + * process at the same time. + */ + XGrabServer (x11_display->xdisplay); + + XSetInputFocus (x11_display->xdisplay, + xwindow, + RevertToPointerRoot, + timestamp); + + XChangeProperty (x11_display->xdisplay, + x11_display->timestamp_pinging_window, + x11_display->atom__MUTTER_FOCUS_SET, + XA_STRING, 8, PropModeAppend, NULL, 0); + + XUngrabServer (x11_display->xdisplay); + XFlush (x11_display->xdisplay); + + meta_x11_error_trap_pop (x11_display); +} + +void +meta_x11_display_set_input_focus (MetaX11Display *x11_display, + MetaWindow *window, + gboolean focus_frame, + uint32_t timestamp) +{ + Window xwindow; + gulong serial; + + if (window) + xwindow = focus_frame ? window->frame->xwindow : window->xwindow; + else + xwindow = x11_display->no_focus_window; + + meta_x11_error_trap_push (x11_display); + meta_x11_display_set_input_focus_internal (x11_display, xwindow, timestamp); + serial = XNextRequest (x11_display->xdisplay); + meta_x11_display_update_focus_window (x11_display, xwindow, serial, TRUE); + meta_x11_error_trap_pop (x11_display); +} + +void +meta_x11_display_set_input_focus_xwindow (MetaX11Display *x11_display, + Window window, + guint32 timestamp) +{ + gulong serial; + + if (meta_display_timestamp_too_old (x11_display->display, ×tamp)) + return; + + meta_x11_display_set_input_focus_internal (x11_display, window, timestamp); + serial = XNextRequest (x11_display->xdisplay); + meta_x11_display_update_focus_window (x11_display, window, serial, TRUE); + meta_display_update_focus_window (x11_display->display, NULL); + meta_display_remove_autoraise_callback (x11_display->display); + x11_display->display->last_focus_time = timestamp; +} + +static MetaX11DisplayLogicalMonitorData * +get_x11_display_logical_monitor_data (MetaLogicalMonitor *logical_monitor) +{ + return g_object_get_qdata (G_OBJECT (logical_monitor), + quark_x11_display_logical_monitor_data); +} + +static MetaX11DisplayLogicalMonitorData * +ensure_x11_display_logical_monitor_data (MetaLogicalMonitor *logical_monitor) +{ + MetaX11DisplayLogicalMonitorData *data; + + data = get_x11_display_logical_monitor_data (logical_monitor); + if (data) + return data; + + data = g_new0 (MetaX11DisplayLogicalMonitorData, 1); + g_object_set_qdata_full (G_OBJECT (logical_monitor), + quark_x11_display_logical_monitor_data, + data, + g_free); + + return data; +} + +static void +meta_x11_display_ensure_xinerama_indices (MetaX11Display *x11_display) +{ + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + GList *logical_monitors, *l; + XineramaScreenInfo *infos; + int n_infos, j; + + if (x11_display->has_xinerama_indices) + return; + + x11_display->has_xinerama_indices = TRUE; + + if (!XineramaIsActive (x11_display->xdisplay)) + return; + + infos = XineramaQueryScreens (x11_display->xdisplay, + &n_infos); + if (n_infos <= 0 || infos == NULL) + { + meta_XFree (infos); + return; + } + + logical_monitors = + meta_monitor_manager_get_logical_monitors (monitor_manager); + + for (l = logical_monitors; l; l = l->next) + { + MetaLogicalMonitor *logical_monitor = l->data; + + for (j = 0; j < n_infos; ++j) + { + if (logical_monitor->rect.x == infos[j].x_org && + logical_monitor->rect.y == infos[j].y_org && + logical_monitor->rect.width == infos[j].width && + logical_monitor->rect.height == infos[j].height) + { + MetaX11DisplayLogicalMonitorData *logical_monitor_data; + + logical_monitor_data = + ensure_x11_display_logical_monitor_data (logical_monitor); + logical_monitor_data->xinerama_index = j; + } + } + } + + meta_XFree (infos); +} + +int +meta_x11_display_logical_monitor_to_xinerama_index (MetaX11Display *x11_display, + MetaLogicalMonitor *logical_monitor) +{ + MetaX11DisplayLogicalMonitorData *logical_monitor_data; + + g_return_val_if_fail (logical_monitor, -1); + + meta_x11_display_ensure_xinerama_indices (x11_display); + + logical_monitor_data = get_x11_display_logical_monitor_data (logical_monitor); + + return logical_monitor_data->xinerama_index; +} + +MetaLogicalMonitor * +meta_x11_display_xinerama_index_to_logical_monitor (MetaX11Display *x11_display, + int xinerama_index) +{ + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + GList *logical_monitors, *l; + + meta_x11_display_ensure_xinerama_indices (x11_display); + + logical_monitors = + meta_monitor_manager_get_logical_monitors (monitor_manager); + + for (l = logical_monitors; l; l = l->next) + { + MetaLogicalMonitor *logical_monitor = l->data; + MetaX11DisplayLogicalMonitorData *logical_monitor_data; + + logical_monitor_data = + ensure_x11_display_logical_monitor_data (logical_monitor); + + if (logical_monitor_data->xinerama_index == xinerama_index) + return logical_monitor; + } + + return NULL; +} + +void +meta_x11_display_update_workspace_names (MetaX11Display *x11_display) +{ + char **names; + int n_names; + int i; + + /* this updates names in prefs when the root window property changes, + * iff the new property contents don't match what's already in prefs + */ + + names = NULL; + n_names = 0; + if (!meta_prop_get_utf8_list (x11_display, + x11_display->xroot, + x11_display->atom__NET_DESKTOP_NAMES, + &names, &n_names)) + { + meta_verbose ("Failed to get workspace names from root window\n"); + return; + } + + i = 0; + while (i < n_names) + { + meta_topic (META_DEBUG_PREFS, + "Setting workspace %d name to \"%s\" due to _NET_DESKTOP_NAMES change\n", + i, names[i] ? names[i] : "null"); + meta_prefs_change_workspace_name (i, names[i]); + + ++i; + } + + g_strfreev (names); +} + +#define _NET_WM_ORIENTATION_HORZ 0 +#define _NET_WM_ORIENTATION_VERT 1 + +#define _NET_WM_TOPLEFT 0 +#define _NET_WM_TOPRIGHT 1 +#define _NET_WM_BOTTOMRIGHT 2 +#define _NET_WM_BOTTOMLEFT 3 + +void +meta_x11_display_update_workspace_layout (MetaX11Display *x11_display) +{ + MetaWorkspaceManager *workspace_manager = x11_display->display->workspace_manager; + gboolean vertical_layout = FALSE; + int n_rows = -1; + int n_columns = 1; + MetaDisplayCorner starting_corner = META_DISPLAY_TOPLEFT; + uint32_t *list; + int n_items; + + if (workspace_manager->workspace_layout_overridden) + return; + + list = NULL; + n_items = 0; + + if (meta_prop_get_cardinal_list (x11_display, + x11_display->xroot, + x11_display->atom__NET_DESKTOP_LAYOUT, + &list, &n_items)) + { + if (n_items == 3 || n_items == 4) + { + int cols, rows; + + switch (list[0]) + { + case _NET_WM_ORIENTATION_HORZ: + vertical_layout = FALSE; + break; + case _NET_WM_ORIENTATION_VERT: + vertical_layout = TRUE; + break; + default: + meta_warning ("Someone set a weird orientation in _NET_DESKTOP_LAYOUT\n"); + break; + } + + cols = list[1]; + rows = list[2]; + + if (rows <= 0 && cols <= 0) + { + meta_warning ("Columns = %d rows = %d in _NET_DESKTOP_LAYOUT makes no sense\n", rows, cols); + } + else + { + if (rows > 0) + n_rows = rows; + else + n_rows = -1; + + if (cols > 0) + n_columns = cols; + else + n_columns = -1; + } + + if (n_items == 4) + { + switch (list[3]) + { + case _NET_WM_TOPLEFT: + starting_corner = META_DISPLAY_TOPLEFT; + break; + case _NET_WM_TOPRIGHT: + starting_corner = META_DISPLAY_TOPRIGHT; + break; + case _NET_WM_BOTTOMRIGHT: + starting_corner = META_DISPLAY_BOTTOMRIGHT; + break; + case _NET_WM_BOTTOMLEFT: + starting_corner = META_DISPLAY_BOTTOMLEFT; + break; + default: + meta_warning ("Someone set a weird starting corner in _NET_DESKTOP_LAYOUT\n"); + break; + } + } + } + else + { + meta_warning ("Someone set _NET_DESKTOP_LAYOUT to %d integers instead of 4 " + "(3 is accepted for backwards compat)\n", n_items); + } + + g_free (list); + + meta_workspace_manager_update_workspace_layout (workspace_manager, + starting_corner, + vertical_layout, + n_rows, + n_columns); + } +} + +static void +prefs_changed_callback (MetaPreference pref, + void *data) +{ + MetaX11Display *x11_display = data; + + if (pref == META_PREF_WORKSPACE_NAMES) + { + set_workspace_names (x11_display); + } +} + +void +meta_x11_display_increment_focus_sentinel (MetaX11Display *x11_display) +{ + unsigned long data[1]; + + data[0] = meta_display_get_current_time (x11_display->display); + + XChangeProperty (x11_display->xdisplay, + x11_display->xroot, + x11_display->atom__MUTTER_SENTINEL, + XA_CARDINAL, + 32, PropModeReplace, (guchar*) data, 1); + + x11_display->sentinel_counter += 1; +} + +void +meta_x11_display_decrement_focus_sentinel (MetaX11Display *x11_display) +{ + x11_display->sentinel_counter -= 1; + + if (x11_display->sentinel_counter < 0) + x11_display->sentinel_counter = 0; +} + +gboolean +meta_x11_display_focus_sentinel_clear (MetaX11Display *x11_display) +{ + return (x11_display->sentinel_counter == 0); +} + +void +meta_x11_display_set_stage_input_region (MetaX11Display *x11_display, + XserverRegion region) +{ + Display *xdisplay = x11_display->xdisplay; + MetaBackend *backend = meta_get_backend (); + ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend)); + Window stage_xwindow; + + g_return_if_fail (!meta_is_wayland_compositor ()); + + stage_xwindow = meta_x11_get_stage_window (stage); + XFixesSetWindowShapeRegion (xdisplay, stage_xwindow, + ShapeInput, 0, 0, region); + + /* + * It's generally a good heuristic that when a crossing event is generated + * because we reshape the overlay, we don't want it to affect + * focus-follows-mouse focus - it's not the user doing something, it's the + * environment changing under the user. + */ + meta_display_add_ignored_crossing_serial (x11_display->display, + XNextRequest (xdisplay)); + XFixesSetWindowShapeRegion (xdisplay, + x11_display->composite_overlay_window, + ShapeInput, 0, 0, region); +} + +void +meta_x11_display_clear_stage_input_region (MetaX11Display *x11_display) +{ + if (x11_display->empty_region == None) + { + x11_display->empty_region = XFixesCreateRegion (x11_display->xdisplay, + NULL, 0); + } + + meta_x11_display_set_stage_input_region (x11_display, + x11_display->empty_region); +} diff --git a/src/core/errors.c b/src/x11/meta-x11-errors.c similarity index 67% rename from src/core/errors.c rename to src/x11/meta-x11-errors.c index 7b954e6da..506769464 100644 --- a/src/core/errors.c +++ b/src/x11/meta-x11-errors.c @@ -1,11 +1,9 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* Muffin X error handling */ - -/* +/* * Copyright (C) 2001 Havoc Pennington, error trapping inspired by GDK * code copyrighted by the GTK team. - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the @@ -15,26 +13,27 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ /** * SECTION:errors * @title: Errors - * @short_description: Muffin X error handling + * @short_description: Mutter X error handling */ -#include <config.h> -#include <meta/errors.h> -#include "display-private.h" +#include "config.h" + +#include "meta/meta-x11-errors.h" + #include <errno.h> #include <stdlib.h> #include <gdk/gdkx.h> +#include "x11/meta-x11-display-private.h" + /* In GTK+-3.0, the error trapping code was significantly rewritten. The new code * has some neat features (like knowing automatically if a sync is needed or not * and handling errors asynchronously when the error code isn't needed immediately), @@ -48,25 +47,19 @@ */ void -meta_error_trap_push (MetaDisplay *display) -{ - gdk_x11_display_error_trap_push (display->gdk_display); -} - -void -meta_error_trap_pop (MetaDisplay *display) +meta_x11_error_trap_push (MetaX11Display *x11_display) { - gdk_x11_display_error_trap_pop_ignored (display->gdk_display); + gdk_x11_display_error_trap_push (x11_display->gdk_display); } void -meta_error_trap_push_with_return (MetaDisplay *display) +meta_x11_error_trap_pop (MetaX11Display *x11_display) { - gdk_x11_display_error_trap_push (display->gdk_display); + gdk_x11_display_error_trap_pop_ignored (x11_display->gdk_display); } int -meta_error_trap_pop_with_return (MetaDisplay *display) +meta_x11_error_trap_pop_with_return (MetaX11Display *x11_display) { - return gdk_x11_display_error_trap_pop (display->gdk_display); + return gdk_x11_display_error_trap_pop (x11_display->gdk_display); } diff --git a/src/x11/meta-x11-selection-input-stream-private.h b/src/x11/meta-x11-selection-input-stream-private.h new file mode 100644 index 000000000..3fcf9ffd1 --- /dev/null +++ b/src/x11/meta-x11-selection-input-stream-private.h @@ -0,0 +1,54 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2017 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see <http://www.gnu.org/licenses/>. + * + * Author: Benjamin Otte <otte@gnome.org> + * Christian Kellner <gicmo@gnome.org> + */ + +#ifndef META_X11_SELECTION_INPUT_STREAM_H +#define META_X11_SELECTION_INPUT_STREAM_H + +#include <gio/gio.h> + +#include "x11/meta-x11-display-private.h" + +#define META_TYPE_X11_SELECTION_INPUT_STREAM (meta_x11_selection_input_stream_get_type ()) +G_DECLARE_FINAL_TYPE (MetaX11SelectionInputStream, + meta_x11_selection_input_stream, + META, X11_SELECTION_INPUT_STREAM, + GInputStream) + +void meta_x11_selection_input_stream_new_async (MetaX11Display *x11_display, + Window window, + const char *selection, + const char *target, + guint32 timestamp, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GInputStream * meta_x11_selection_input_stream_new_finish (GAsyncResult *result, + const char **type, + int *format, + GError **error); + +gboolean meta_x11_selection_input_stream_xevent (MetaX11SelectionInputStream *stream, + const XEvent *xevent); + +G_END_DECLS + +#endif /* META_X11_SELECTION_INPUT_STREAM_H */ diff --git a/src/x11/meta-x11-selection-input-stream.c b/src/x11/meta-x11-selection-input-stream.c new file mode 100644 index 000000000..e8d782047 --- /dev/null +++ b/src/x11/meta-x11-selection-input-stream.c @@ -0,0 +1,572 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * Copyright (C) 2017 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see <http://www.gnu.org/licenses/>. + * + * Author: Benjamin Otte <otte@gnome.org> + * Christian Kellner <gicmo@gnome.org> + */ + +#include "config.h" + +#include "meta-x11-selection-input-stream-private.h" + +#include <gdk/gdkx.h> + +#include "meta/meta-x11-errors.h" +#include "x11/meta-x11-display-private.h" + +typedef struct MetaX11SelectionInputStreamPrivate MetaX11SelectionInputStreamPrivate; + +struct _MetaX11SelectionInputStream +{ + GInputStream parent_instance; +}; + +struct MetaX11SelectionInputStreamPrivate +{ + MetaX11Display *x11_display; + Window window; + GAsyncQueue *chunks; + char *selection; + Atom xselection; + char *target; + Atom xtarget; + char *property; + Atom xproperty; + const char *type; + Atom xtype; + int format; + + GTask *pending_task; + uint8_t *pending_data; + size_t pending_size; + + guint complete : 1; + guint incr : 1; +}; + +G_DEFINE_TYPE_WITH_PRIVATE (MetaX11SelectionInputStream, + meta_x11_selection_input_stream, + G_TYPE_INPUT_STREAM) + +static gboolean +meta_x11_selection_input_stream_has_data (MetaX11SelectionInputStream *stream) +{ + MetaX11SelectionInputStreamPrivate *priv = + meta_x11_selection_input_stream_get_instance_private (stream); + + return g_async_queue_length (priv->chunks) > 0 || priv->complete; +} + +/* NB: blocks when no data is in buffer */ +static size_t +meta_x11_selection_input_stream_fill_buffer (MetaX11SelectionInputStream *stream, + uint8_t *buffer, + size_t count) +{ + MetaX11SelectionInputStreamPrivate *priv = + meta_x11_selection_input_stream_get_instance_private (stream); + GBytes *bytes; + size_t result = 0; + + g_async_queue_lock (priv->chunks); + + for (bytes = g_async_queue_pop_unlocked (priv->chunks); + bytes != NULL && count > 0; + bytes = g_async_queue_try_pop_unlocked (priv->chunks)) + { + size_t size = g_bytes_get_size (bytes); + + if (size == 0) + { + /* EOF marker, put it back */ + g_async_queue_push_front_unlocked (priv->chunks, bytes); + bytes = NULL; + break; + } + else if (size > count) + { + GBytes *subbytes; + if (buffer) + memcpy (buffer, g_bytes_get_data (bytes, NULL), count); + subbytes = g_bytes_new_from_bytes (bytes, count, size - count); + g_async_queue_push_front_unlocked (priv->chunks, subbytes); + size = count; + } + else + { + if (buffer) + memcpy (buffer, g_bytes_get_data (bytes, NULL), size); + } + + g_bytes_unref (bytes); + result += size; + if (buffer) + buffer += size; + count -= size; + } + + if (bytes) + g_async_queue_push_front_unlocked (priv->chunks, bytes); + + g_async_queue_unlock (priv->chunks); + + return result; +} + +static void +meta_x11_selection_input_stream_flush (MetaX11SelectionInputStream *stream) +{ + MetaX11SelectionInputStreamPrivate *priv = + meta_x11_selection_input_stream_get_instance_private (stream); + gssize written; + + if (!meta_x11_selection_input_stream_has_data (stream)) + return; + + if (priv->pending_task == NULL) + return; + + written = meta_x11_selection_input_stream_fill_buffer (stream, + priv->pending_data, + priv->pending_size); + g_task_return_int (priv->pending_task, written); + + g_clear_object (&priv->pending_task); + priv->pending_data = NULL; + priv->pending_size = 0; +} + +static void +meta_x11_selection_input_stream_complete (MetaX11SelectionInputStream *stream) +{ + MetaX11SelectionInputStreamPrivate *priv = + meta_x11_selection_input_stream_get_instance_private (stream); + + if (priv->complete) + return; + + priv->complete = TRUE; + + g_async_queue_push (priv->chunks, g_bytes_new (NULL, 0)); + meta_x11_selection_input_stream_flush (stream); + + priv->x11_display->selection.input_streams = + g_list_remove (priv->x11_display->selection.input_streams, stream); + + g_object_unref (stream); +} + +static gssize +meta_x11_selection_input_stream_read (GInputStream *input_stream, + void *buffer, + size_t count, + GCancellable *cancellable, + GError **error) +{ + MetaX11SelectionInputStream *stream = + META_X11_SELECTION_INPUT_STREAM (input_stream); + + return meta_x11_selection_input_stream_fill_buffer (stream, buffer, count); +} + +static gboolean +meta_x11_selection_input_stream_close (GInputStream *stream, + GCancellable *cancellable, + GError **error) +{ + return TRUE; +} + +static void +meta_x11_selection_input_stream_read_async (GInputStream *input_stream, + void *buffer, + size_t count, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + MetaX11SelectionInputStream *stream = + META_X11_SELECTION_INPUT_STREAM (input_stream); + MetaX11SelectionInputStreamPrivate *priv = + meta_x11_selection_input_stream_get_instance_private (stream); + GTask *task; + + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_source_tag (task, meta_x11_selection_input_stream_read_async); + g_task_set_priority (task, io_priority); + + if (meta_x11_selection_input_stream_has_data (stream)) + { + gssize size; + + size = meta_x11_selection_input_stream_fill_buffer (stream, buffer, count); + g_task_return_int (task, size); + g_object_unref (task); + } + else + { + priv->pending_data = buffer; + priv->pending_size = count; + priv->pending_task = task; + } +} + +static gssize +meta_x11_selection_input_stream_read_finish (GInputStream *stream, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, stream), -1); + g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == + meta_x11_selection_input_stream_read_async, -1); + + return g_task_propagate_int (G_TASK (result), error); +} + +static void +meta_x11_selection_input_stream_close_async (GInputStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_source_tag (task, meta_x11_selection_input_stream_close_async); + g_task_return_boolean (task, TRUE); + g_object_unref (task); +} + +static gboolean +meta_x11_selection_input_stream_close_finish (GInputStream *stream, + GAsyncResult *result, + GError **error) +{ + return TRUE; +} + +static void +meta_x11_selection_input_stream_dispose (GObject *object) +{ + MetaX11SelectionInputStream *stream = + META_X11_SELECTION_INPUT_STREAM (object); + MetaX11SelectionInputStreamPrivate *priv = + meta_x11_selection_input_stream_get_instance_private (stream); + + priv->x11_display->selection.input_streams = + g_list_remove (priv->x11_display->selection.input_streams, stream); + + G_OBJECT_CLASS (meta_x11_selection_input_stream_parent_class)->dispose (object); +} + +static void +meta_x11_selection_input_stream_finalize (GObject *object) +{ + MetaX11SelectionInputStream *stream = + META_X11_SELECTION_INPUT_STREAM (object); + MetaX11SelectionInputStreamPrivate *priv = + meta_x11_selection_input_stream_get_instance_private (stream); + + g_async_queue_unref (priv->chunks); + + g_free (priv->selection); + g_free (priv->target); + g_free (priv->property); + + G_OBJECT_CLASS (meta_x11_selection_input_stream_parent_class)->finalize (object); +} + +static void +meta_x11_selection_input_stream_class_init (MetaX11SelectionInputStreamClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GInputStreamClass *istream_class = G_INPUT_STREAM_CLASS (klass); + + object_class->dispose = meta_x11_selection_input_stream_dispose; + object_class->finalize = meta_x11_selection_input_stream_finalize; + + istream_class->read_fn = meta_x11_selection_input_stream_read; + istream_class->close_fn = meta_x11_selection_input_stream_close; + + istream_class->read_async = meta_x11_selection_input_stream_read_async; + istream_class->read_finish = meta_x11_selection_input_stream_read_finish; + istream_class->close_async = meta_x11_selection_input_stream_close_async; + istream_class->close_finish = meta_x11_selection_input_stream_close_finish; +} + +static void +meta_x11_selection_input_stream_init (MetaX11SelectionInputStream *stream) +{ + MetaX11SelectionInputStreamPrivate *priv = + meta_x11_selection_input_stream_get_instance_private (stream); + + priv->chunks = g_async_queue_new_full ((GDestroyNotify) g_bytes_unref); +} + +static void +XFree_without_return_value (gpointer data) +{ + XFree (data); +} + +static GBytes * +get_selection_property (Display *xdisplay, + Window owner, + Atom property, + Atom *ret_type, + gint *ret_format) +{ + gulong nitems; + gulong nbytes; + Atom prop_type; + gint prop_format; + uint8_t *data = NULL; + + if (XGetWindowProperty (xdisplay, owner, property, + 0, 0x1FFFFFFF, False, + AnyPropertyType, &prop_type, &prop_format, + &nitems, &nbytes, &data) != Success) + goto err; + + if (prop_type != None) + { + size_t length; + + switch (prop_format) + { + case 8: + length = nitems; + break; + case 16: + length = sizeof (short) * nitems; + break; + case 32: + length = sizeof (long) * nitems; + break; + default: + g_warning ("Unknown XGetWindowProperty() format %u", prop_format); + goto err; + } + + *ret_type = prop_type; + *ret_format = prop_format; + + return g_bytes_new_with_free_func (data, + length, + XFree_without_return_value, + data); + } + +err: + if (data) + XFree (data); + + *ret_type = None; + *ret_format = 0; + + return NULL; +} + +gboolean +meta_x11_selection_input_stream_xevent (MetaX11SelectionInputStream *stream, + const XEvent *xevent) +{ + MetaX11SelectionInputStreamPrivate *priv = + meta_x11_selection_input_stream_get_instance_private (stream); + Display *xdisplay; + Window xwindow; + GBytes *bytes; + Atom type; + gint format; + + xdisplay = priv->x11_display->xdisplay; + xwindow = priv->window; + + if (xevent->xany.display != xdisplay || + xevent->xany.window != xwindow) + return FALSE; + + switch (xevent->type) + { + case PropertyNotify: + if (!priv->incr || + xevent->xproperty.atom != priv->xproperty || + xevent->xproperty.state != PropertyNewValue) + return FALSE; + + bytes = get_selection_property (xdisplay, xwindow, xevent->xproperty.atom, + &type, &format); + + if (bytes == NULL) + { + g_debug ("INCR request came out empty"); + meta_x11_selection_input_stream_complete (stream); + } + else if (g_bytes_get_size (bytes) == 0 || type == None) + { + g_bytes_unref (bytes); + meta_x11_selection_input_stream_complete (stream); + } + else + { + g_async_queue_push (priv->chunks, bytes); + meta_x11_selection_input_stream_flush (stream); + } + + XDeleteProperty (xdisplay, xwindow, xevent->xproperty.atom); + + return FALSE; + + case SelectionNotify: + { + GTask *task; + + /* selection is not for us */ + if (priv->xselection != xevent->xselection.selection || + priv->xtarget != xevent->xselection.target) + return FALSE; + + /* We already received a selectionNotify before */ + if (priv->pending_task == NULL || + g_task_get_source_tag (priv->pending_task) != meta_x11_selection_input_stream_new_async) + { + g_debug ("Misbehaving client sent a reentrant SelectionNotify"); + return FALSE; + } + + task = g_steal_pointer (&priv->pending_task); + + if (xevent->xselection.property == None) + { + g_task_return_new_error (task, + G_IO_ERROR, + G_IO_ERROR_NOT_FOUND, + _("Format %s not supported"), priv->target); + meta_x11_selection_input_stream_complete (stream); + } + else + { + bytes = get_selection_property (xdisplay, xwindow, + xevent->xselection.property, + &priv->xtype, &priv->format); + priv->type = gdk_x11_get_xatom_name (priv->xtype); + + g_task_return_pointer (task, g_object_ref (stream), g_object_unref); + + if (bytes == NULL) + { + meta_x11_selection_input_stream_complete (stream); + } + else + { + if (priv->xtype == XInternAtom (priv->x11_display->xdisplay, "INCR", False)) + { + /* The remainder of the selection will come through PropertyNotify + events on xwindow */ + priv->incr = TRUE; + meta_x11_selection_input_stream_flush (stream); + } + else + { + g_async_queue_push (priv->chunks, bytes); + + meta_x11_selection_input_stream_complete (stream); + } + } + + XDeleteProperty (xdisplay, xwindow, xevent->xselection.property); + } + + g_object_unref (task); + } + return TRUE; + + default: + return FALSE; + } +} + +void +meta_x11_selection_input_stream_new_async (MetaX11Display *x11_display, + Window window, + const char *selection, + const char *target, + guint32 timestamp, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + MetaX11SelectionInputStream *stream; + MetaX11SelectionInputStreamPrivate *priv; + + stream = g_object_new (META_TYPE_X11_SELECTION_INPUT_STREAM, NULL); + priv = meta_x11_selection_input_stream_get_instance_private (stream); + + priv->x11_display = x11_display; + x11_display->selection.input_streams = + g_list_prepend (x11_display->selection.input_streams, stream); + priv->selection = g_strdup (selection); + priv->xselection = XInternAtom (x11_display->xdisplay, priv->selection, False); + priv->target = g_strdup (target); + priv->xtarget = XInternAtom (x11_display->xdisplay, priv->target, False); + priv->property = g_strdup_printf ("META_SELECTION_%p", stream); + priv->xproperty = XInternAtom (x11_display->xdisplay, priv->property, False); + priv->window = window; + + XConvertSelection (x11_display->xdisplay, + priv->xselection, + priv->xtarget, + priv->xproperty, + window, + timestamp); + + priv->pending_task = g_task_new (NULL, cancellable, callback, user_data); + g_task_set_source_tag (priv->pending_task, meta_x11_selection_input_stream_new_async); + g_task_set_priority (priv->pending_task, io_priority); +} + +GInputStream * +meta_x11_selection_input_stream_new_finish (GAsyncResult *result, + const char **type, + int *format, + GError **error) +{ + MetaX11SelectionInputStream *stream; + MetaX11SelectionInputStreamPrivate *priv; + GTask *task; + + g_return_val_if_fail (g_task_is_valid (result, NULL), NULL); + task = G_TASK (result); + g_return_val_if_fail (g_task_get_source_tag (task) == + meta_x11_selection_input_stream_new_async, NULL); + + stream = g_task_propagate_pointer (task, error); + if (!stream) + return NULL; + + priv = meta_x11_selection_input_stream_get_instance_private (stream); + + if (type) + *type = priv->type; + if (format) + *format = priv->format; + + return G_INPUT_STREAM (stream); +} diff --git a/src/x11/meta-x11-selection-output-stream-private.h b/src/x11/meta-x11-selection-output-stream-private.h new file mode 100644 index 000000000..83390da48 --- /dev/null +++ b/src/x11/meta-x11-selection-output-stream-private.h @@ -0,0 +1,47 @@ +/* GIO - GLib Output, Output and Streaming Library + * + * Copyright (C) 2017 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see <http://www.gnu.org/licenses/>. + * + * Author: Benjamin Otte <otte@gnome.org> + * Christian Kellner <gicmo@gnome.org> + */ + +#ifndef META_X11_SELECTION_OUTPUT_STREAM_H +#define META_X11_SELECTION_OUTPUT_STREAM_H + +#include <gio/gio.h> + +#include "x11/meta-x11-display-private.h" + +#define META_TYPE_X11_SELECTION_OUTPUT_STREAM (meta_x11_selection_output_stream_get_type ()) +G_DECLARE_FINAL_TYPE (MetaX11SelectionOutputStream, + meta_x11_selection_output_stream, + META, X11_SELECTION_OUTPUT_STREAM, + GOutputStream) + +GOutputStream * meta_x11_selection_output_stream_new (MetaX11Display *x11_display, + Window window, + const char *selection, + const char *target, + const char *property, + const char *type, + int format, + gulong timestamp); + +gboolean meta_x11_selection_output_stream_xevent (MetaX11SelectionOutputStream *stream, + const XEvent *xevent); + +#endif /* META_X11_SELECTION_OUTPUT_STREAM_H */ diff --git a/src/x11/meta-x11-selection-output-stream.c b/src/x11/meta-x11-selection-output-stream.c new file mode 100644 index 000000000..41a691c9a --- /dev/null +++ b/src/x11/meta-x11-selection-output-stream.c @@ -0,0 +1,686 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * Copyright (C) 2017 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see <http://www.gnu.org/licenses/>. + * + * Author: Benjamin Otte <otte@gnome.org> + * Christian Kellner <gicmo@gnome.org> + */ + +#include "config.h" + +#include "meta-x11-selection-output-stream-private.h" + +#include "meta/meta-x11-errors.h" +#include "x11/meta-x11-display-private.h" + +typedef struct _MetaX11SelectionOutputStreamPrivate MetaX11SelectionOutputStreamPrivate; + +struct _MetaX11SelectionOutputStream +{ + GOutputStream parent_instance; +}; + +struct _MetaX11SelectionOutputStreamPrivate +{ + MetaX11Display *x11_display; + Window xwindow; + Atom xselection; + Atom xtarget; + Atom xproperty; + Atom xtype; + int format; + gulong timestamp; + + GMutex mutex; + GCond cond; + GByteArray *data; + guint flush_requested : 1; + + GTask *pending_task; + + guint incr : 1; + guint delete_pending : 1; + guint pipe_error : 1; +}; + +G_DEFINE_TYPE_WITH_PRIVATE (MetaX11SelectionOutputStream, + meta_x11_selection_output_stream, + G_TYPE_OUTPUT_STREAM); + +static size_t get_element_size (int format); + +static void +meta_x11_selection_output_stream_notify_selection (MetaX11SelectionOutputStream *stream) +{ + MetaX11SelectionOutputStreamPrivate *priv = + meta_x11_selection_output_stream_get_instance_private (stream); + XSelectionEvent event; + Display *xdisplay; + + event = (XSelectionEvent) { + .type = SelectionNotify, + .time = priv->timestamp, + .requestor = priv->xwindow, + .selection = priv->xselection, + .target = priv->xtarget, + .property = priv->xproperty, + }; + + meta_x11_error_trap_push (priv->x11_display); + + xdisplay = priv->x11_display->xdisplay; + + XSendEvent (xdisplay, + priv->xwindow, False, NoEventMask, + (XEvent *) &event); + XSync (xdisplay, False); + + meta_x11_error_trap_pop (priv->x11_display); +} + +static gboolean +meta_x11_selection_output_stream_can_flush (MetaX11SelectionOutputStream *stream) +{ + MetaX11SelectionOutputStreamPrivate *priv = + meta_x11_selection_output_stream_get_instance_private (stream); + + if (priv->delete_pending) + return FALSE; + if (!g_output_stream_is_closing (G_OUTPUT_STREAM (stream)) && + priv->data->len < get_element_size (priv->format)) + return FALSE; + + return TRUE; +} + +static size_t +get_max_request_size (MetaX11Display *display) +{ + size_t size; + + size = XExtendedMaxRequestSize (display->xdisplay); + if (size <= 0) + size = XMaxRequestSize (display->xdisplay); + + return (size - 100) * 4; +} + +static gboolean +meta_x11_selection_output_stream_needs_flush_unlocked (MetaX11SelectionOutputStream *stream) +{ + MetaX11SelectionOutputStreamPrivate *priv = + meta_x11_selection_output_stream_get_instance_private (stream); + + if (priv->data->len == 0) + { + if (priv->incr) + return g_output_stream_is_closing (G_OUTPUT_STREAM (stream)); + else + return FALSE; + } + + if (g_output_stream_is_closing (G_OUTPUT_STREAM (stream))) + return TRUE; + + if (priv->flush_requested) + return TRUE; + + return priv->data->len >= get_max_request_size (priv->x11_display); +} + +static gboolean +meta_x11_selection_output_stream_needs_flush (MetaX11SelectionOutputStream *stream) +{ + MetaX11SelectionOutputStreamPrivate *priv = + meta_x11_selection_output_stream_get_instance_private (stream); + + gboolean result; + + g_mutex_lock (&priv->mutex); + + result = meta_x11_selection_output_stream_needs_flush_unlocked (stream); + + g_mutex_unlock (&priv->mutex); + + return result; +} + +static size_t +get_element_size (int format) +{ + switch (format) + { + case 8: + return 1; + + case 16: + return sizeof (short); + + case 32: + return sizeof (long); + + default: + g_warning ("Unknown format %u", format); + return 1; + } +} + +static gboolean +meta_x11_selection_output_stream_check_pipe (MetaX11SelectionOutputStream *stream, + GError **error) +{ + MetaX11SelectionOutputStreamPrivate *priv = + meta_x11_selection_output_stream_get_instance_private (stream); + + if (priv->pipe_error) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_BROKEN_PIPE, + "Connection with client was broken"); + return FALSE; + } + + return TRUE; +} + +static void +meta_x11_selection_output_stream_perform_flush (MetaX11SelectionOutputStream *stream) +{ + MetaX11SelectionOutputStreamPrivate *priv = + meta_x11_selection_output_stream_get_instance_private (stream); + Display *xdisplay; + size_t element_size, n_elements, max_size; + gboolean first_chunk = FALSE; + int error_code; + + g_assert (!priv->delete_pending); + + xdisplay = priv->x11_display->xdisplay; + + /* We operate on a foreign window, better guard against catastrophe */ + meta_x11_error_trap_push (priv->x11_display); + + g_mutex_lock (&priv->mutex); + + element_size = get_element_size (priv->format); + n_elements = priv->data->len / element_size; + max_size = get_max_request_size (priv->x11_display); + + if (!priv->incr) + first_chunk = TRUE; + + if (!priv->incr && priv->data->len > max_size) + { + XWindowAttributes attrs; + + priv->incr = TRUE; + XGetWindowAttributes (xdisplay, + priv->xwindow, + &attrs); + if (!(attrs.your_event_mask & PropertyChangeMask)) + { + XSelectInput (xdisplay, priv->xwindow, attrs.your_event_mask | PropertyChangeMask); + } + + XChangeProperty (xdisplay, + priv->xwindow, + priv->xproperty, + XInternAtom (priv->x11_display->xdisplay, "INCR", False), + 32, + PropModeReplace, + (guchar *) &(long) { n_elements }, + 1); + priv->delete_pending = TRUE; + } + else + { + size_t copy_n_elements; + + if (priv->incr && priv->data->len > 0) + priv->delete_pending = TRUE; + + copy_n_elements = MIN (n_elements, max_size / element_size); + + XChangeProperty (xdisplay, + priv->xwindow, + priv->xproperty, + priv->xtype, + priv->format, + PropModeReplace, + priv->data->data, + copy_n_elements); + g_byte_array_remove_range (priv->data, 0, copy_n_elements * element_size); + } + + if (first_chunk) + meta_x11_selection_output_stream_notify_selection (stream); + + g_cond_broadcast (&priv->cond); + g_mutex_unlock (&priv->mutex); + + error_code = meta_x11_error_trap_pop_with_return (priv->x11_display); + + if (error_code != Success) + { + char error_str[100]; + + priv->flush_requested = FALSE; + priv->delete_pending = FALSE; + priv->pipe_error = TRUE; + + if (priv->pending_task) + { + XGetErrorText (xdisplay, error_code, error_str, sizeof (error_str)); + g_task_return_new_error (priv->pending_task, + G_IO_ERROR, + G_IO_ERROR_BROKEN_PIPE, + "Failed to flush selection output stream: %s", + error_str); + g_clear_object (&priv->pending_task); + } + } + else if (priv->pending_task && priv->data->len == 0 && !priv->delete_pending) + { + size_t result; + + priv->flush_requested = FALSE; + result = GPOINTER_TO_SIZE (g_task_get_task_data (priv->pending_task)); + g_task_return_int (priv->pending_task, result); + g_clear_object (&priv->pending_task); + } +} + +static gboolean +meta_x11_selection_output_stream_invoke_flush (gpointer data) +{ + MetaX11SelectionOutputStream *stream = + META_X11_SELECTION_OUTPUT_STREAM (data); + MetaX11SelectionOutputStreamPrivate *priv = + meta_x11_selection_output_stream_get_instance_private (stream); + + if (meta_x11_selection_output_stream_needs_flush (stream) && + meta_x11_selection_output_stream_can_flush (stream)) + meta_x11_selection_output_stream_perform_flush (stream); + + if (priv->delete_pending || priv->data->len > 0) + return G_SOURCE_CONTINUE; + else + return G_SOURCE_REMOVE; +} + +static gssize +meta_x11_selection_output_stream_write (GOutputStream *output_stream, + const void *buffer, + size_t count, + GCancellable *cancellable, + GError **error) +{ + MetaX11SelectionOutputStream *stream = + META_X11_SELECTION_OUTPUT_STREAM (output_stream); + MetaX11SelectionOutputStreamPrivate *priv = + meta_x11_selection_output_stream_get_instance_private (stream); + + if (!meta_x11_selection_output_stream_check_pipe (stream, error)) + return -1; + + g_mutex_lock (&priv->mutex); + g_byte_array_append (priv->data, buffer, count); + g_mutex_unlock (&priv->mutex); + + g_main_context_invoke (NULL, meta_x11_selection_output_stream_invoke_flush, stream); + + g_mutex_lock (&priv->mutex); + if (meta_x11_selection_output_stream_needs_flush_unlocked (stream)) + g_cond_wait (&priv->cond, &priv->mutex); + g_mutex_unlock (&priv->mutex); + + return count; +} + +static void +meta_x11_selection_output_stream_write_async (GOutputStream *output_stream, + const void *buffer, + size_t count, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + MetaX11SelectionOutputStream *stream = + META_X11_SELECTION_OUTPUT_STREAM (output_stream); + MetaX11SelectionOutputStreamPrivate *priv = + meta_x11_selection_output_stream_get_instance_private (stream); + GError *error = NULL; + GTask *task; + + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_source_tag (task, meta_x11_selection_output_stream_write_async); + g_task_set_priority (task, io_priority); + + if (!meta_x11_selection_output_stream_check_pipe (stream, &error)) + { + g_task_return_error (task, error); + return; + } + + g_mutex_lock (&priv->mutex); + g_byte_array_append (priv->data, buffer, count); + g_mutex_unlock (&priv->mutex); + + if (!meta_x11_selection_output_stream_needs_flush (stream)) + { + g_task_return_int (task, count); + g_object_unref (task); + return; + } + else + { + if (meta_x11_selection_output_stream_can_flush (stream)) + meta_x11_selection_output_stream_perform_flush (stream); + + g_task_return_int (task, count); + g_object_unref (task); + return; + } +} + +static gssize +meta_x11_selection_output_stream_write_finish (GOutputStream *stream, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, stream), -1); + g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == + meta_x11_selection_output_stream_write_async, -1); + + return g_task_propagate_int (G_TASK (result), error); +} + +static gboolean +meta_x11_selection_output_request_flush (MetaX11SelectionOutputStream *stream) +{ + MetaX11SelectionOutputStreamPrivate *priv = + meta_x11_selection_output_stream_get_instance_private (stream); + gboolean needs_flush; + + g_mutex_lock (&priv->mutex); + + if (priv->data->len > 0) + priv->flush_requested = TRUE; + + needs_flush = meta_x11_selection_output_stream_needs_flush_unlocked (stream); + g_mutex_unlock (&priv->mutex); + + return needs_flush; +} + +static gboolean +meta_x11_selection_output_stream_flush (GOutputStream *output_stream, + GCancellable *cancellable, + GError **error) +{ + MetaX11SelectionOutputStream *stream = + META_X11_SELECTION_OUTPUT_STREAM (output_stream); + MetaX11SelectionOutputStreamPrivate *priv = + meta_x11_selection_output_stream_get_instance_private (stream); + + if (!meta_x11_selection_output_stream_check_pipe (stream, error)) + return FALSE; + if (!meta_x11_selection_output_request_flush (stream)) + return TRUE; + + g_main_context_invoke (NULL, meta_x11_selection_output_stream_invoke_flush, + stream); + + g_mutex_lock (&priv->mutex); + if (meta_x11_selection_output_stream_needs_flush_unlocked (stream)) + g_cond_wait (&priv->cond, &priv->mutex); + g_mutex_unlock (&priv->mutex); + + return TRUE; +} + +static void +meta_x11_selection_output_stream_flush_async (GOutputStream *output_stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + MetaX11SelectionOutputStream *stream = + META_X11_SELECTION_OUTPUT_STREAM (output_stream); + MetaX11SelectionOutputStreamPrivate *priv = + meta_x11_selection_output_stream_get_instance_private (stream); + GError *error = NULL; + GTask *task; + + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_source_tag (task, meta_x11_selection_output_stream_flush_async); + g_task_set_priority (task, io_priority); + + if (!meta_x11_selection_output_stream_check_pipe (stream, &error)) + { + g_task_return_error (task, error); + return; + } + + if (!meta_x11_selection_output_stream_can_flush (stream)) + { + if (meta_x11_selection_output_request_flush (stream)) + { + g_assert (priv->pending_task == NULL); + priv->pending_task = task; + return; + } + else + { + g_task_return_boolean (task, TRUE); + g_object_unref (task); + return; + } + } + + g_assert (priv->pending_task == NULL); + priv->pending_task = task; + meta_x11_selection_output_stream_perform_flush (stream); +} + +static gboolean +meta_x11_selection_output_stream_flush_finish (GOutputStream *stream, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, stream), FALSE); + g_return_val_if_fail (g_async_result_is_tagged (result, meta_x11_selection_output_stream_flush_async), FALSE); + + return g_task_propagate_boolean (G_TASK (result), error); +} + +static gboolean +meta_x11_selection_output_stream_invoke_close (gpointer stream) +{ + MetaX11SelectionOutputStreamPrivate *priv = + meta_x11_selection_output_stream_get_instance_private (stream); + + priv->x11_display->selection.output_streams = + g_list_remove (priv->x11_display->selection.output_streams, stream); + + return G_SOURCE_REMOVE; +} + +static gboolean +meta_x11_selection_output_stream_close (GOutputStream *stream, + GCancellable *cancellable, + GError **error) +{ + g_main_context_invoke (NULL, meta_x11_selection_output_stream_invoke_close, stream); + + return TRUE; +} + +static void +meta_x11_selection_output_stream_close_async (GOutputStream *stream, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_source_tag (task, meta_x11_selection_output_stream_close_async); + g_task_set_priority (task, io_priority); + + meta_x11_selection_output_stream_invoke_close (stream); + g_task_return_boolean (task, TRUE); + + g_object_unref (task); +} + +static gboolean +meta_x11_selection_output_stream_close_finish (GOutputStream *stream, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, stream), FALSE); + g_return_val_if_fail (g_async_result_is_tagged (result, meta_x11_selection_output_stream_close_async), FALSE); + + return g_task_propagate_boolean (G_TASK (result), error); +} + +static void +meta_x11_selection_output_stream_dispose (GObject *object) +{ + MetaX11SelectionOutputStream *stream = + META_X11_SELECTION_OUTPUT_STREAM (object); + MetaX11SelectionOutputStreamPrivate *priv = + meta_x11_selection_output_stream_get_instance_private (stream); + + priv->x11_display->selection.output_streams = + g_list_remove (priv->x11_display->selection.output_streams, stream); + + G_OBJECT_CLASS (meta_x11_selection_output_stream_parent_class)->dispose (object); +} + +static void +meta_x11_selection_output_stream_finalize (GObject *object) +{ + MetaX11SelectionOutputStream *stream = + META_X11_SELECTION_OUTPUT_STREAM (object); + MetaX11SelectionOutputStreamPrivate *priv = + meta_x11_selection_output_stream_get_instance_private (stream); + + g_byte_array_unref (priv->data); + g_cond_clear (&priv->cond); + g_mutex_clear (&priv->mutex); + + G_OBJECT_CLASS (meta_x11_selection_output_stream_parent_class)->finalize (object); +} + +static void +meta_x11_selection_output_stream_class_init (MetaX11SelectionOutputStreamClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GOutputStreamClass *output_stream_class = G_OUTPUT_STREAM_CLASS (klass); + + object_class->dispose = meta_x11_selection_output_stream_dispose; + object_class->finalize = meta_x11_selection_output_stream_finalize; + + output_stream_class->write_fn = meta_x11_selection_output_stream_write; + output_stream_class->flush = meta_x11_selection_output_stream_flush; + output_stream_class->close_fn = meta_x11_selection_output_stream_close; + + output_stream_class->write_async = meta_x11_selection_output_stream_write_async; + output_stream_class->write_finish = meta_x11_selection_output_stream_write_finish; + output_stream_class->flush_async = meta_x11_selection_output_stream_flush_async; + output_stream_class->flush_finish = meta_x11_selection_output_stream_flush_finish; + output_stream_class->close_async = meta_x11_selection_output_stream_close_async; + output_stream_class->close_finish = meta_x11_selection_output_stream_close_finish; +} + +static void +meta_x11_selection_output_stream_init (MetaX11SelectionOutputStream *stream) +{ + MetaX11SelectionOutputStreamPrivate *priv = + meta_x11_selection_output_stream_get_instance_private (stream); + + g_mutex_init (&priv->mutex); + g_cond_init (&priv->cond); + priv->data = g_byte_array_new (); +} + +gboolean +meta_x11_selection_output_stream_xevent (MetaX11SelectionOutputStream *stream, + const XEvent *xevent) +{ + MetaX11SelectionOutputStreamPrivate *priv = + meta_x11_selection_output_stream_get_instance_private (stream); + Display *xdisplay = priv->x11_display->xdisplay; + + if (xevent->xany.display != xdisplay || + xevent->xany.window != priv->xwindow) + return FALSE; + + switch (xevent->type) + { + case PropertyNotify: + if (!priv->incr || + xevent->xproperty.atom != priv->xproperty || + xevent->xproperty.state != PropertyDelete) + return FALSE; + + priv->delete_pending = FALSE; + if (meta_x11_selection_output_stream_needs_flush (stream) && + meta_x11_selection_output_stream_can_flush (stream)) + meta_x11_selection_output_stream_perform_flush (stream); + return FALSE; + + default: + return FALSE; + } +} + +GOutputStream * +meta_x11_selection_output_stream_new (MetaX11Display *x11_display, + Window requestor, + const char *selection, + const char *target, + const char *property, + const char *type, + int format, + gulong timestamp) +{ + MetaX11SelectionOutputStream *stream; + MetaX11SelectionOutputStreamPrivate *priv; + + stream = g_object_new (META_TYPE_X11_SELECTION_OUTPUT_STREAM, NULL); + priv = meta_x11_selection_output_stream_get_instance_private (stream); + + x11_display->selection.output_streams = + g_list_prepend (x11_display->selection.output_streams, stream); + + priv->x11_display = x11_display; + priv->xwindow = requestor; + priv->xselection = XInternAtom (x11_display->xdisplay, selection, False); + priv->xtarget = XInternAtom (x11_display->xdisplay, target, False); + priv->xproperty = XInternAtom (x11_display->xdisplay, property, False); + priv->xtype = XInternAtom (x11_display->xdisplay, type, False); + priv->format = format; + priv->timestamp = timestamp; + + return G_OUTPUT_STREAM (stream); +} diff --git a/src/x11/meta-x11-selection-private.h b/src/x11/meta-x11-selection-private.h new file mode 100644 index 000000000..b551ef602 --- /dev/null +++ b/src/x11/meta-x11-selection-private.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2018 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef META_X11_SELECTION_H +#define META_X11_SELECTION_H + +#include "meta/meta-selection.h" +#include "x11/meta-x11-display-private.h" + +gboolean meta_x11_selection_handle_event (MetaX11Display *display, + XEvent *event); + +void meta_x11_selection_init (MetaX11Display *x11_display); +void meta_x11_selection_shutdown (MetaX11Display *x11_display); + +#endif /* META_X11_SELECTION_H */ diff --git a/src/x11/meta-x11-selection.c b/src/x11/meta-x11-selection.c new file mode 100644 index 000000000..f9b3607a7 --- /dev/null +++ b/src/x11/meta-x11-selection.c @@ -0,0 +1,551 @@ +/* + * Copyright (C) 2018 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#include "config.h" + +#include <gdk/gdkx.h> + +#include "core/meta-selection-private.h" +#include "meta/meta-selection-source-memory.h" +#include "x11/meta-selection-source-x11-private.h" +#include "x11/meta-x11-selection-output-stream-private.h" +#include "x11/meta-x11-selection-private.h" + +#define UTF8_STRING_MIMETYPE "text/plain;charset=utf-8" +#define STRING_MIMETYPE "text/plain" + +static gboolean +atom_to_selection_type (Display *xdisplay, + Atom selection, + MetaSelectionType *selection_type) +{ + if (selection == XInternAtom (xdisplay, "PRIMARY", False)) + *selection_type = META_SELECTION_PRIMARY; + else if (selection == XInternAtom (xdisplay, "CLIPBOARD", False)) + *selection_type = META_SELECTION_CLIPBOARD; + else if (selection == XInternAtom (xdisplay, "XdndSelection", False)) + *selection_type = META_SELECTION_DND; + else + return FALSE; + + return TRUE; +} + +static Atom +selection_to_atom (MetaSelectionType type, + Display *xdisplay) +{ + Atom atom; + + switch (type) + { + case META_SELECTION_PRIMARY: + atom = XInternAtom (xdisplay, "PRIMARY", False); + break; + case META_SELECTION_CLIPBOARD: + atom = XInternAtom (xdisplay, "CLIPBOARD", False); + break; + case META_SELECTION_DND: + atom = XInternAtom (xdisplay, "XdndSelection", False); + break; + default: + g_warn_if_reached (); + atom = None; + break; + } + + return atom; +} + +static GBytes * +mimetypes_to_bytes (GList *mimetypes, + Display *xdisplay) +{ + GArray *atoms = g_array_new (FALSE, FALSE, sizeof (Atom)); + GList *l; + char *mimetype; + Atom atom; + gboolean utf8_string_found = FALSE, utf8_string_mimetype_found = FALSE; + gboolean string_found = FALSE, string_mimetype_found = FALSE; + GBytes *bytes; + + for (l = mimetypes; l; l = l->next) + { + mimetype = l->data; + atom = XInternAtom (xdisplay, mimetype, False); + g_array_append_val (atoms, atom); + utf8_string_mimetype_found |= strcmp (mimetype, UTF8_STRING_MIMETYPE) == 0; + utf8_string_found |= strcmp (mimetype, "UTF8_STRING") == 0; + string_mimetype_found |= strcmp (mimetype, STRING_MIMETYPE) == 0; + string_found |= strcmp (mimetype, "STRING") == 0; + } + + /* Some X11 clients can only handle STRING/UTF8_STRING but not the + * corresponding mimetypes. */ + if (utf8_string_mimetype_found && !utf8_string_found) + { + atom = XInternAtom (xdisplay, "UTF8_STRING", False); + g_array_append_val (atoms, atom); + } + + if (string_mimetype_found && !string_found) + { + atom = XInternAtom (xdisplay, "STRING", False); + g_array_append_val (atoms, atom); + } + + atom = XInternAtom (xdisplay, "TARGETS", False); + g_array_append_val (atoms, atom); + + atom = XInternAtom (xdisplay, "TIMESTAMP", False); + g_array_append_val (atoms, atom); + + bytes = g_bytes_new_take (atoms->data, atoms->len * sizeof (Atom)); + g_array_free (atoms, FALSE); + + return bytes; +} + +static void +send_selection_notify (XSelectionRequestEvent *request_event, + gboolean accepted) +{ + Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); + XSelectionEvent event; + + memset(&event, 0, sizeof (XSelectionEvent)); + event.type = SelectionNotify; + event.time = request_event->time; + event.requestor = request_event->requestor; + event.selection = request_event->selection; + event.target = request_event->target; + event.property = accepted ? request_event->property : None; + + XSendEvent (xdisplay, request_event->requestor, + False, NoEventMask, (XEvent *) &event); +} + +static void +write_mimetypes_cb (GOutputStream *stream, + GAsyncResult *res, + gpointer user_data) +{ + GError *error = NULL; + + g_output_stream_write_bytes_finish (stream, res, &error); + g_output_stream_close (stream, NULL, NULL); + g_object_unref (stream); + + if (error) + { + g_warning ("Could not fetch selection mimetypes: %s\n", error->message); + g_error_free (error); + } +} + +static void +transfer_cb (MetaSelection *selection, + GAsyncResult *res, + GOutputStream *output) +{ + GError *error = NULL; + + if (!meta_selection_transfer_finish (selection, res, &error)) + { + g_warning ("Error writing data to X11 selection: %s", error->message); + g_error_free (error); + } + + g_output_stream_close (output, NULL, NULL); + g_object_unref (output); +} + +static char * +meta_x11_selection_find_target (MetaX11Display *x11_display, + MetaSelection *selection, + MetaSelectionType selection_type, + Atom selection_atom) +{ + GList* mimetypes = NULL; + const gchar *atom_name; + char *retval; + + mimetypes = meta_selection_get_mimetypes (selection, selection_type); + atom_name = gdk_x11_get_xatom_name (selection_atom); + + if (g_list_find_custom (mimetypes, atom_name, (GCompareFunc) g_strcmp0)) + { + retval = g_strdup (atom_name); + } + else if (strcmp (atom_name, "UTF8_STRING") == 0 && + g_list_find_custom (mimetypes, UTF8_STRING_MIMETYPE, + (GCompareFunc) g_strcmp0)) + { + retval = g_strdup (UTF8_STRING_MIMETYPE); + } + else if (strcmp (atom_name, "STRING") == 0 && + g_list_find_custom (mimetypes, STRING_MIMETYPE, + (GCompareFunc) g_strcmp0)) + { + retval = g_strdup (STRING_MIMETYPE); + } + else + { + retval = NULL; + } + + g_list_free_full (mimetypes, g_free); + + return retval; +} + +static gboolean +meta_x11_selection_handle_selection_request (MetaX11Display *x11_display, + XEvent *xevent) +{ + XSelectionRequestEvent *event = (XSelectionRequestEvent *) xevent; + MetaSelectionType selection_type; + MetaSelection *selection; + GOutputStream *output; + GList *mimetypes; + + if (!atom_to_selection_type (x11_display->xdisplay, event->selection, &selection_type)) + return FALSE; + if (x11_display->selection.xwindow != event->owner) + return FALSE; + + selection = meta_display_get_selection (meta_get_display ()); + + if (event->target == gdk_x11_get_xatom_by_name ("TARGETS")) + { + GBytes *bytes; + + mimetypes = meta_selection_get_mimetypes (selection, selection_type); + + if (!mimetypes) + { + send_selection_notify (event, FALSE); + return FALSE; + } + + output = meta_x11_selection_output_stream_new (x11_display, event->requestor, + gdk_x11_get_xatom_name (event->selection), + gdk_x11_get_xatom_name (event->target), + gdk_x11_get_xatom_name (event->property), + "ATOM", 32, event->time); + + bytes = mimetypes_to_bytes (mimetypes, x11_display->xdisplay); + g_list_free_full (mimetypes, g_free); + + g_output_stream_write_bytes_async (output, + bytes, + G_PRIORITY_DEFAULT, + NULL, + (GAsyncReadyCallback) write_mimetypes_cb, + output); + g_bytes_unref (bytes); + return TRUE; + } + else if (event->target == gdk_x11_get_xatom_by_name ("DELETE")) + { + /* DnD only, this is just handled through other means on our non-x11 + * sources, so just go with it. + */ + send_selection_notify (event, TRUE); + } + else + { + g_autofree char *target = NULL; + + target = meta_x11_selection_find_target (x11_display, selection, + selection_type, event->target); + + if (target != NULL) + { + output = meta_x11_selection_output_stream_new (x11_display, + event->requestor, + gdk_x11_get_xatom_name (event->selection), + gdk_x11_get_xatom_name (event->target), + gdk_x11_get_xatom_name (event->property), + gdk_x11_get_xatom_name (event->target), + 8, event->time); + + meta_selection_transfer_async (selection, + selection_type, + target, + -1, + output, + NULL, + (GAsyncReadyCallback) transfer_cb, + output); + return TRUE; + } + else + { + send_selection_notify (event, FALSE); + } + } + + return FALSE; +} + +typedef struct +{ + MetaX11Display *x11_display; + MetaSelection *selection; + MetaSelectionType selection_type; +} SourceNewData; + +static void +source_new_cb (GObject *object, + GAsyncResult *res, + gpointer user_data) +{ + MetaSelectionSource *source; + SourceNewData *data = user_data; + MetaSelection *selection = data->selection; + MetaSelectionType selection_type = data->selection_type; + MetaX11Display *x11_display = data->x11_display; + g_autoptr (GError) error = NULL; + + source = meta_selection_source_x11_new_finish (res, &error); + if (source) + { + g_set_object (&x11_display->selection.owners[selection_type], source); + meta_selection_set_owner (selection, selection_type, source); + g_object_unref (source); + } + else if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + { + g_warning ("Could not create selection source for X11: %s", + error->message); + } + + g_free (data); +} + +static gboolean +unset_clipboard_owner (gpointer data) +{ + MetaDisplay *display = meta_get_display (); + MetaSelection *selection = meta_display_get_selection (display); + MetaX11Display *x11_display = meta_display_get_x11_display (display); + + meta_selection_unset_owner (selection, META_SELECTION_CLIPBOARD, + x11_display->selection.owners[META_SELECTION_CLIPBOARD]); + g_clear_object (&x11_display->selection.owners[META_SELECTION_CLIPBOARD]); + + x11_display->selection.timeout_id = 0; + + return G_SOURCE_REMOVE; +} + +static gboolean +meta_x11_selection_handle_xfixes_selection_notify (MetaX11Display *x11_display, + XEvent *xevent) +{ + XFixesSelectionNotifyEvent *event = (XFixesSelectionNotifyEvent *) xevent; + Display *xdisplay = x11_display->xdisplay; + MetaSelectionType selection_type; + MetaSelection *selection; + + if (!atom_to_selection_type (xdisplay, event->selection, &selection_type)) + return FALSE; + + selection = meta_display_get_selection (meta_get_display ()); + + if (selection_type == META_SELECTION_CLIPBOARD) + g_clear_handle_id (&x11_display->selection.timeout_id, g_source_remove); + + if (x11_display->selection.cancellables[selection_type]) + { + g_cancellable_cancel (x11_display->selection.cancellables[selection_type]); + g_clear_object (&x11_display->selection.cancellables[selection_type]); + } + + x11_display->selection.cancellables[selection_type] = g_cancellable_new (); + + if (event->owner == None && x11_display->selection.owners[selection_type]) + { + if (event->subtype == XFixesSetSelectionOwnerNotify) + { + MetaSelectionSource *source; + + /* Replace with an empty owner */ + source = g_object_new (META_TYPE_SELECTION_SOURCE_MEMORY, NULL); + g_set_object (&x11_display->selection.owners[selection_type], source); + meta_selection_set_owner (selection, selection_type, source); + g_object_unref (source); + } + else if (event->subtype == XFixesSelectionWindowDestroyNotify && + selection_type == META_SELECTION_CLIPBOARD) + { + /* Selection window might have gotten destroyed as part of application + * shutdown. Trigger restoring clipboard, but wait a bit, because some + * clients, like wine, destroy the old window immediately before a new + * selection. Restoring the clipboard in this case would overwrite the + * new selection, so this will be cancelled when a new selection + * arrives. */ + x11_display->selection.timeout_id = g_timeout_add (10, + unset_clipboard_owner, + NULL); + } + else + { + /* An X client went away, clear the selection */ + meta_selection_unset_owner (selection, selection_type, + x11_display->selection.owners[selection_type]); + g_clear_object (&x11_display->selection.owners[selection_type]); + } + } + else if (event->owner != None && event->owner != x11_display->selection.xwindow) + { + SourceNewData *data; + + data = g_new (SourceNewData, 1); + data->x11_display = x11_display; + data->selection = selection; + data->selection_type = selection_type; + + meta_selection_source_x11_new_async (x11_display, + event->owner, + event->timestamp, + event->selection, + x11_display->selection.cancellables[selection_type], + source_new_cb, + data); + } + + return TRUE; +} + +gboolean +meta_x11_selection_handle_event (MetaX11Display *x11_display, + XEvent *xevent) +{ + if (xevent->type == SelectionRequest) + return meta_x11_selection_handle_selection_request (x11_display, xevent); + else if (xevent->type - x11_display->xfixes_event_base == XFixesSelectionNotify) + return meta_x11_selection_handle_xfixes_selection_notify (x11_display, xevent); + + return FALSE; +} + +static void +notify_selection_owner (MetaX11Display *x11_display, + MetaSelectionType selection_type, + MetaSelectionSource *new_owner) +{ + Display *xdisplay = x11_display->xdisplay; + + if (new_owner && new_owner != x11_display->selection.owners[selection_type]) + { + if (x11_display->selection.cancellables[selection_type]) + { + g_cancellable_cancel (x11_display->selection.cancellables[selection_type]); + g_clear_object (&x11_display->selection.cancellables[selection_type]); + } + + /* If the owner is non-X11, claim the selection on our selection + * window, so X11 apps can interface with it. + */ + XSetSelectionOwner (xdisplay, + selection_to_atom (selection_type, xdisplay), + x11_display->selection.xwindow, + META_CURRENT_TIME); + } +} + +void +meta_x11_selection_init (MetaX11Display *x11_display) +{ + XSetWindowAttributes attributes = { 0 }; + MetaDisplay *display = meta_get_display (); + MetaSelection *selection; + guint mask, i; + + attributes.event_mask = PropertyChangeMask | SubstructureNotifyMask; + attributes.override_redirect = True; + + x11_display->selection.timeout_id = 0; + x11_display->selection.xwindow = + XCreateWindow (x11_display->xdisplay, + x11_display->xroot, + -1, -1, 1, 1, + 0, /* border width */ + 0, /* depth */ + InputOnly, /* class */ + CopyFromParent, /* visual */ + CWEventMask | CWOverrideRedirect, + &attributes); + + mask = XFixesSetSelectionOwnerNotifyMask | + XFixesSelectionWindowDestroyNotifyMask | + XFixesSelectionClientCloseNotifyMask; + + selection = meta_display_get_selection (display); + + for (i = 0; i < META_N_SELECTION_TYPES; i++) + { + MetaSelectionSource *owner; + + XFixesSelectSelectionInput (x11_display->xdisplay, + x11_display->selection.xwindow, + selection_to_atom (i, x11_display->xdisplay), + mask); + owner = meta_selection_get_current_owner (selection, i); + notify_selection_owner (x11_display, i, owner); + } + + g_signal_connect_swapped (selection, + "owner-changed", + G_CALLBACK (notify_selection_owner), + x11_display); +} + +void +meta_x11_selection_shutdown (MetaX11Display *x11_display) +{ + MetaDisplay *display = meta_get_display (); + guint i; + + g_signal_handlers_disconnect_by_func (meta_display_get_selection (display), + notify_selection_owner, + x11_display); + + for (i = 0; i < META_N_SELECTION_TYPES; i++) + { + g_clear_object (&x11_display->selection.owners[i]); + if (x11_display->selection.cancellables[i]) + { + g_cancellable_cancel (x11_display->selection.cancellables[i]); + g_clear_object (&x11_display->selection.cancellables[i]); + } + } + + if (x11_display->selection.xwindow != None) + { + XDestroyWindow (x11_display->xdisplay, x11_display->selection.xwindow); + x11_display->selection.xwindow = None; + } + + g_clear_handle_id (&x11_display->selection.timeout_id, g_source_remove); +} diff --git a/src/x11/meta-x11-stack-private.h b/src/x11/meta-x11-stack-private.h new file mode 100644 index 000000000..a00b8e743 --- /dev/null +++ b/src/x11/meta-x11-stack-private.h @@ -0,0 +1,33 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * Copyright (C) 2019 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef META_X11_STACK_H +#define META_X11_STACK_H + +#include <glib-object.h> + +#include "meta/types.h" + +#define META_TYPE_X11_STACK (meta_x11_stack_get_type ()) +G_DECLARE_FINAL_TYPE (MetaX11Stack, meta_x11_stack, META, X11_STACK, GObject) + +typedef struct _MetaX11Stack MetaX11Stack; + +MetaX11Stack * meta_x11_stack_new (MetaX11Display *x11_display); + +#endif /* META_X11_STACK_H */ diff --git a/src/x11/meta-x11-stack.c b/src/x11/meta-x11-stack.c new file mode 100644 index 000000000..a8fb6733e --- /dev/null +++ b/src/x11/meta-x11-stack.c @@ -0,0 +1,353 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * Copyright (C) 2019 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include "core/frame.h" +#include "core/stack.h" +#include "core/window-private.h" +#include "x11/meta-x11-display-private.h" +#include "x11/meta-x11-stack-private.h" + +struct _MetaX11Stack +{ + GObject parent; + MetaX11Display *x11_display; + + /* + * A sequence of all the Windows (X handles, not MetaWindows) of the windows + * we manage, sorted in order. Suitable to be passed into _NET_CLIENT_LIST. + */ + GArray *xwindows; + + /* + * MetaWindows waiting to be added to the xwindows list, after + * being added to the MetaStack. + * + * The order of the elements in this list is not important; what is important + * is the stack_position element of each window. + */ + GList *added; + + /* + * Windows (X handles, not MetaWindows) waiting to be removed from the + * xwindows list, after being removed from the MetaStack. + * + * The order of the elements in this list is not important. + */ + GList *removed; +}; + +enum +{ + PROP_DISPLAY = 1, + N_PROPS +}; + +static GParamSpec *pspecs[N_PROPS] = { 0 }; + +G_DEFINE_TYPE (MetaX11Stack, meta_x11_stack, G_TYPE_OBJECT) + +static void +meta_x11_stack_init (MetaX11Stack *x11_stack) +{ + x11_stack->xwindows = g_array_new (FALSE, FALSE, sizeof (Window)); +} + +static void +meta_x11_stack_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaX11Stack *x11_stack = META_X11_STACK (object); + + switch (prop_id) + { + case PROP_DISPLAY: + x11_stack->x11_display = g_value_get_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meta_x11_stack_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaX11Stack *x11_stack = META_X11_STACK (object); + + switch (prop_id) + { + case PROP_DISPLAY: + g_value_set_object (value, x11_stack->x11_display); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +stack_window_added_cb (MetaStack *stack, + MetaWindow *window, + MetaX11Stack *x11_stack) +{ + if (window->client_type != META_WINDOW_CLIENT_TYPE_X11) + return; + + x11_stack->added = g_list_prepend (x11_stack->added, window); +} + +static void +stack_window_removed_cb (MetaStack *stack, + MetaWindow *window, + MetaX11Stack *x11_stack) +{ + if (window->client_type != META_WINDOW_CLIENT_TYPE_X11) + return; + + x11_stack->added = g_list_remove (x11_stack->added, window); + + x11_stack->removed = g_list_prepend (x11_stack->removed, + GUINT_TO_POINTER (window->xwindow)); + if (window->frame) + { + x11_stack->removed = g_list_prepend (x11_stack->removed, + GUINT_TO_POINTER (window->frame->xwindow)); + } +} + +/** + * stack_do_window_deletions: + * + * Go through "deleted" and take the matching windows + * out of "windows". + */ +static void +x11_stack_do_window_deletions (MetaX11Stack *x11_stack) +{ + GList *tmp; + int i; + + tmp = x11_stack->removed; + while (tmp != NULL) + { + Window xwindow; + xwindow = GPOINTER_TO_UINT (tmp->data); + + /* We go from the end figuring removals are more + * likely to be recent. + */ + i = x11_stack->xwindows->len; + while (i > 0) + { + --i; + + /* there's no guarantee we'll actually find windows to + * remove, e.g. the same xwindow could have been + * added/removed before we ever synced, and we put + * both the window->xwindow and window->frame->xwindow + * in the removal list. + */ + if (xwindow == g_array_index (x11_stack->xwindows, Window, i)) + { + g_array_remove_index (x11_stack->xwindows, i); + goto next; + } + } + + next: + tmp = tmp->next; + } + + g_clear_pointer (&x11_stack->removed, g_list_free); +} + +static void +x11_stack_do_window_additions (MetaX11Stack *x11_stack) +{ + GList *tmp; + gint n_added; + + n_added = g_list_length (x11_stack->added); + if (n_added > 0) + { + meta_topic (META_DEBUG_STACK, + "Adding %d windows to sorted list\n", + n_added); + + /* stack->added has the most recent additions at the + * front of the list, so we need to reverse it + */ + x11_stack->added = g_list_reverse (x11_stack->added); + + tmp = x11_stack->added; + while (tmp != NULL) + { + MetaWindow *w; + + w = tmp->data; + g_array_append_val (x11_stack->xwindows, w->xwindow); + tmp = tmp->next; + } + } + + g_clear_pointer (&x11_stack->added, g_list_free); +} + +/** + * x11_stack_sync_to_server: + * + * Order the windows on the X server to be the same as in our structure. + * We do this using XRestackWindows if we don't know the previous order, + * or XConfigureWindow on a few particular windows if we do and can figure + * out the minimum set of changes. After that, we set __NET_CLIENT_LIST + * and __NET_CLIENT_LIST_STACKING. + * + * FIXME: Now that we have a good view of the stacking order on the server + * with MetaStackTracker it should be possible to do a simpler and better + * job of computing the minimal set of stacking requests needed. + */ +static void +x11_stack_sync_to_xserver (MetaX11Stack *x11_stack) +{ + MetaX11Display *x11_display = x11_stack->x11_display; + MetaStack *stack = x11_display->display->stack; + GArray *x11_stacked; + GList *tmp; + GList *sorted; + + meta_topic (META_DEBUG_STACK, "Syncing window stack to server\n"); + + /* Create stacked xwindow arrays, in bottom-to-top order + */ + x11_stacked = g_array_new (FALSE, FALSE, sizeof (Window)); + + sorted = meta_stack_list_windows (stack, NULL); + + for (tmp = sorted; tmp; tmp = tmp->next) + { + MetaWindow *w = tmp->data; + + if (w->client_type == META_WINDOW_CLIENT_TYPE_X11) + g_array_append_val (x11_stacked, w->xwindow); + } + + /* Sync _NET_CLIENT_LIST and _NET_CLIENT_LIST_STACKING */ + + XChangeProperty (x11_stack->x11_display->xdisplay, + x11_stack->x11_display->xroot, + x11_stack->x11_display->atom__NET_CLIENT_LIST, + XA_WINDOW, + 32, PropModeReplace, + (unsigned char *) x11_stack->xwindows->data, + x11_stack->xwindows->len); + XChangeProperty (x11_stack->x11_display->xdisplay, + x11_stack->x11_display->xroot, + x11_stack->x11_display->atom__NET_CLIENT_LIST_STACKING, + XA_WINDOW, + 32, PropModeReplace, + (unsigned char *) x11_stacked->data, + x11_stacked->len); + + g_array_free (x11_stacked, TRUE); + g_list_free (sorted); +} + +static void +stack_changed_cb (MetaX11Stack *x11_stack) +{ + /* Do removals before adds, with paranoid idea that we might re-add + * the same window IDs. + */ + x11_stack_do_window_deletions (x11_stack); + x11_stack_do_window_additions (x11_stack); + x11_stack_sync_to_xserver (x11_stack); +} + +static void +meta_x11_stack_constructed (GObject *object) +{ + MetaX11Stack *x11_stack = META_X11_STACK (object); + MetaX11Display *x11_display = x11_stack->x11_display; + + G_OBJECT_CLASS (meta_x11_stack_parent_class)->constructed (object); + + g_signal_connect (x11_display->display->stack, + "window-added", + G_CALLBACK (stack_window_added_cb), + x11_stack); + g_signal_connect (x11_display->display->stack, + "window-removed", + G_CALLBACK (stack_window_removed_cb), + x11_stack); + g_signal_connect_swapped (x11_display->display->stack, + "changed", + G_CALLBACK (stack_changed_cb), + x11_stack); +} + +static void +meta_x11_stack_finalize (GObject *object) +{ + MetaX11Stack *x11_stack = META_X11_STACK (object); + MetaX11Display *x11_display = x11_stack->x11_display; + + if (x11_display->display && x11_display->display->stack) + { + g_signal_handlers_disconnect_by_data (x11_display->display->stack, + x11_stack); + } + + g_array_free (x11_stack->xwindows, TRUE); + g_list_free (x11_stack->added); + g_list_free (x11_stack->removed); + + G_OBJECT_CLASS (meta_x11_stack_parent_class)->finalize (object); +} + +static void +meta_x11_stack_class_init (MetaX11StackClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->set_property = meta_x11_stack_set_property; + object_class->get_property = meta_x11_stack_get_property; + object_class->constructed = meta_x11_stack_constructed; + object_class->finalize = meta_x11_stack_finalize; + + pspecs[PROP_DISPLAY] = + g_param_spec_object ("display", + "Display", + "Display", + META_TYPE_X11_DISPLAY, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + + g_object_class_install_properties (object_class, N_PROPS, pspecs); +} + +MetaX11Stack * +meta_x11_stack_new (MetaX11Display *x11_display) +{ + return g_object_new (META_TYPE_X11_STACK, + "display", x11_display, + NULL); +} diff --git a/src/x11/meta-x11-window-control.c b/src/x11/meta-x11-window-control.c new file mode 100644 index 000000000..aaf3d7fe1 --- /dev/null +++ b/src/x11/meta-x11-window-control.c @@ -0,0 +1,265 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* Mutter interface used by GTK+ UI to talk to core */ + +/* + * Copyright (C) 2001 Havoc Pennington + * Copyright (C) 2003 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include "x11/meta-x11-window-control.h" + +#include "core/frame.h" +#include "core/meta-workspace-manager-private.h" +#include "core/util-private.h" +#include "core/workspace-private.h" +#include "meta/meta-x11-errors.h" +#include "meta/prefs.h" +#include "x11/meta-x11-display-private.h" +#include "x11/window-x11-private.h" +#include "x11/window-x11.h" + +static MetaWindow * +window_from_frame (MetaX11Display *x11_display, + Window frame_xwindow) +{ + MetaWindow *window; + + window = meta_x11_display_lookup_x_window (x11_display, frame_xwindow); + if (!window || !window->frame) + { + meta_bug ("No such frame window 0x%lx!\n", frame_xwindow); + return NULL; + } + + return window; +} + +void +meta_x11_wm_queue_frame_resize (MetaX11Display *x11_display, + Window frame_xwindow) +{ + MetaWindow *window = window_from_frame (x11_display, frame_xwindow); + + meta_window_queue (window, META_QUEUE_MOVE_RESIZE); + meta_window_frame_size_changed (window); +} + +static gboolean +lower_window_and_transients (MetaWindow *window, + gpointer data) +{ + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; + + meta_window_lower (window); + + meta_window_foreach_transient (window, lower_window_and_transients, NULL); + + if (meta_prefs_get_raise_on_click ()) + { + /* Move window to the back of the focusing workspace's MRU list. + * Do extra sanity checks to avoid possible race conditions. + * (Borrowed from window.c.) + */ + if (workspace_manager->active_workspace && + meta_window_located_on_workspace (window, + workspace_manager->active_workspace)) + { + GList* link; + link = g_list_find (workspace_manager->active_workspace->mru_list, + window); + g_assert (link); + + workspace_manager->active_workspace->mru_list = + g_list_remove_link (workspace_manager->active_workspace->mru_list, + link); + g_list_free (link); + + workspace_manager->active_workspace->mru_list = + g_list_append (workspace_manager->active_workspace->mru_list, + window); + } + } + + return FALSE; +} + +void +meta_x11_wm_user_lower_and_unfocus (MetaX11Display *x11_display, + Window frame_xwindow, + uint32_t timestamp) +{ + MetaWindow *window = window_from_frame (x11_display, frame_xwindow); + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; + + lower_window_and_transients (window, NULL); + + /* Rather than try to figure that out whether we just lowered + * the focus window, assume that's always the case. (Typically, + * this will be invoked via keyboard action or by a mouse action; + * in either case the window or a modal child will have been focused.) */ + meta_workspace_focus_default_window (workspace_manager->active_workspace, + NULL, + timestamp); +} + +void +meta_x11_wm_toggle_maximize_vertically (MetaX11Display *x11_display, + Window frame_xwindow) +{ + MetaWindow *window = window_from_frame (x11_display, frame_xwindow); + + if (meta_prefs_get_raise_on_click ()) + meta_window_raise (window); + + if (META_WINDOW_MAXIMIZED_VERTICALLY (window)) + meta_window_unmaximize (window, META_MAXIMIZE_VERTICAL); + else + meta_window_maximize (window, META_MAXIMIZE_VERTICAL); +} + +void +meta_x11_wm_toggle_maximize_horizontally (MetaX11Display *x11_display, + Window frame_xwindow) +{ + MetaWindow *window = window_from_frame (x11_display, frame_xwindow); + + if (meta_prefs_get_raise_on_click ()) + meta_window_raise (window); + + if (META_WINDOW_MAXIMIZED_HORIZONTALLY (window)) + meta_window_unmaximize (window, META_MAXIMIZE_HORIZONTAL); + else + meta_window_maximize (window, META_MAXIMIZE_HORIZONTAL); +} + +void +meta_x11_wm_toggle_maximize (MetaX11Display *x11_display, + Window frame_xwindow) +{ + MetaWindow *window = window_from_frame (x11_display, frame_xwindow); + + if (meta_prefs_get_raise_on_click ()) + meta_window_raise (window); + + if (META_WINDOW_MAXIMIZED (window)) + meta_window_unmaximize (window, META_MAXIMIZE_BOTH); + else + meta_window_maximize (window, META_MAXIMIZE_BOTH); +} + +void +meta_x11_wm_show_window_menu (MetaX11Display *x11_display, + Window frame_xwindow, + MetaWindowMenuType menu, + int root_x, + int root_y, + uint32_t timestamp) +{ + MetaWindow *window = window_from_frame (x11_display, frame_xwindow); + + if (meta_prefs_get_raise_on_click ()) + meta_window_raise (window); + meta_window_focus (window, timestamp); + + meta_window_show_menu (window, menu, root_x, root_y); +} + +void +meta_x11_wm_show_window_menu_for_rect (MetaX11Display *x11_display, + Window frame_xwindow, + MetaWindowMenuType menu, + MetaRectangle *rect, + uint32_t timestamp) +{ + MetaWindow *window = window_from_frame (x11_display, frame_xwindow); + + if (meta_prefs_get_raise_on_click ()) + meta_window_raise (window); + meta_window_focus (window, timestamp); + + meta_window_show_menu_for_rect (window, menu, rect); +} + +gboolean +meta_x11_wm_begin_grab_op (MetaX11Display *x11_display, + Window frame_xwindow, + MetaGrabOp op, + gboolean pointer_already_grabbed, + gboolean frame_action, + int button, + gulong modmask, + uint32_t timestamp, + int root_x, + int root_y) +{ + MetaWindow *window = window_from_frame (x11_display, frame_xwindow); + MetaDisplay *display; + + display = meta_x11_display_get_display (x11_display); + + return meta_display_begin_grab_op (display, window, + op, pointer_already_grabbed, + frame_action, + button, modmask, + timestamp, root_x, root_y); +} + +void +meta_x11_wm_end_grab_op (MetaX11Display *x11_display, + uint32_t timestamp) +{ + MetaDisplay *display; + + display = meta_x11_display_get_display (x11_display); + + meta_display_end_grab_op (display, timestamp); +} + +MetaGrabOp +meta_x11_wm_get_grab_op (MetaX11Display *x11_display) +{ + MetaDisplay *display; + + display = meta_x11_display_get_display (x11_display); + + return display->grab_op; +} + +void +meta_x11_wm_grab_buttons (MetaX11Display *x11_display, + Window frame_xwindow) +{ + MetaDisplay *display; + + display = meta_x11_display_get_display (x11_display); + + meta_verbose ("Grabbing buttons on frame 0x%lx\n", frame_xwindow); + meta_display_grab_window_buttons (display, frame_xwindow); +} + +void +meta_x11_wm_set_screen_cursor (MetaX11Display *x11_display, + Window frame_on_screen, + MetaCursor cursor) +{ + MetaWindow *window = window_from_frame (x11_display, frame_on_screen); + + meta_frame_set_screen_cursor (window->frame, cursor); +} diff --git a/src/x11/meta-x11-window-control.h b/src/x11/meta-x11-window-control.h new file mode 100644 index 000000000..dfb66f262 --- /dev/null +++ b/src/x11/meta-x11-window-control.h @@ -0,0 +1,81 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* Mutter interface used by GTK+ UI to talk to core */ + +/* + * Copyright (C) 2001 Havoc Pennington + * Copyright (C) 2005 Elijah Newren + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef META_X11_WINDOW__CONTROL_H +#define META_X11_WINDOW__CONTROL_H + +#include <gdk/gdkx.h> + +#include "meta/boxes.h" +#include "meta/common.h" +#include "x11/meta-x11-display-private.h" + +void meta_x11_wm_queue_frame_resize (MetaX11Display *x11_display, + Window frame_xwindow); + +void meta_x11_wm_user_lower_and_unfocus (MetaX11Display *x11_display, + Window frame_xwindow, + uint32_t timestamp); + +void meta_x11_wm_toggle_maximize (MetaX11Display *x11_display, + Window frame_xwindow); +void meta_x11_wm_toggle_maximize_horizontally (MetaX11Display *xdisplay, + Window frame_xwindow); +void meta_x11_wm_toggle_maximize_vertically (MetaX11Display *x11_display, + Window frame_xwindow); + +void meta_x11_wm_show_window_menu (MetaX11Display *x11_xdisplay, + Window frame_xwindow, + MetaWindowMenuType menu, + int root_x, + int root_y, + uint32_t timestamp); + +void meta_x11_wm_show_window_menu_for_rect (MetaX11Display *x11_display, + Window frame_xwindow, + MetaWindowMenuType menu, + MetaRectangle *rect, + uint32_t timestamp); + +gboolean meta_x11_wm_begin_grab_op (MetaX11Display *x11_display, + Window frame_xwindow, + MetaGrabOp op, + gboolean pointer_already_grabbed, + gboolean frame_action, + int button, + gulong modmask, + uint32_t timestamp, + int root_x, + int root_y); +void meta_x11_wm_end_grab_op (MetaX11Display *x11_display, + uint32_t timestamp); +MetaGrabOp meta_x11_wm_get_grab_op (MetaX11Display *x11_display); + + +void meta_x11_wm_grab_buttons (MetaX11Display *x11_display, + Window frame_xwindow); + +void meta_x11_wm_set_screen_cursor (MetaX11Display *x11_display, + Window frame_on_screen, + MetaCursor cursor); + +#endif /* META_X11_WINDOW_CONTROL_H */ diff --git a/src/core/muffin-Xatomtype.h b/src/x11/mutter-Xatomtype.h similarity index 94% rename from src/core/muffin-Xatomtype.h rename to src/x11/mutter-Xatomtype.h index 3ece2fbde..ed3e1f781 100644 --- a/src/core/muffin-Xatomtype.h +++ b/src/x11/mutter-Xatomtype.h @@ -1,7 +1,7 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ /** - * \file muffin-Xatomtype.h Types for communicating with X about properties + * \file mutter-Xatomtype.h Types for communicating with X about properties * * This files defines crock C structures for calling XGetWindowProperty and * XChangeProperty. All fields must be longs as the semantics of property @@ -39,13 +39,13 @@ Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights Reserved -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in +both that copyright notice and this permission notice appear in supporting documentation, and that the name of Digital not be used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. +software without specific, written prior permission. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL @@ -60,10 +60,10 @@ SOFTWARE. #ifndef _XATOMTYPE_H_ #define _XATOMTYPE_H_ -#define BOOL long -#define SIGNEDINT long -#define UNSIGNEDINT unsigned long -#define RESOURCEID unsigned long +#define BOOL int32_t +#define SIGNEDINT int32_t +#define UNSIGNEDINT uint32_t +#define RESOURCEID uint32_t /* this structure may be extended, but do not change the order */ diff --git a/src/core/session.c b/src/x11/session.c similarity index 90% rename from src/core/session.c rename to src/x11/session.c index bc4cb793c..b1aec0b5a 100644 --- a/src/core/session.c +++ b/src/x11/session.c @@ -1,6 +1,6 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* Muffin Session Management */ +/* Mutter Session Management */ /* * Copyright (C) 2001 Havoc Pennington (some code in here from @@ -18,56 +18,58 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ -#include <config.h> +#include "config.h" -#include "util-private.h" -#include "session.h" -#include <X11/Xatom.h> +#include "x11/session.h" -#include <time.h> #include <sys/wait.h> +#include <time.h> +#include <X11/Xatom.h> + +#include "core/util-private.h" +#include "meta/main.h" +#include "x11/meta-x11-display-private.h" #ifndef HAVE_SM -LOCAL_SYMBOL void +void meta_session_init (const char *client_id, const char *save_file) { meta_topic (META_DEBUG_SM, "Compiled without session management support\n"); } -LOCAL_SYMBOL const MetaWindowSessionInfo* +const MetaWindowSessionInfo* meta_window_lookup_saved_state (MetaWindow *window) { return NULL; } -LOCAL_SYMBOL void +void meta_window_release_saved_state (const MetaWindowSessionInfo *info) { ; } #else /* HAVE_SM */ -#include <X11/ICE/ICElib.h> -#include <X11/SM/SMlib.h> -#include <unistd.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <fcntl.h> #include <errno.h> +#include <fcntl.h> #include <glib.h> -#include <string.h> -#include <stdlib.h> #include <stdio.h> -#include <meta/main.h> -#include <meta/util.h> -#include "display-private.h" -#include <meta/workspace.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> +#include <X11/ICE/ICElib.h> +#include <X11/SM/SMlib.h> + +#include "core/display-private.h" +#include "meta/main.h" +#include "meta/util.h" +#include "meta/workspace.h" static void ice_io_error_handler (IceConn connection); @@ -147,9 +149,8 @@ new_ice_connection (IceConn connection, IcePointer client_data, Bool opening, else { input_id = GPOINTER_TO_UINT ((gpointer) *watch_data); - if (input_id) { - g_source_remove (input_id); - } + + g_clear_handle_id (&input_id, g_source_remove); } } @@ -222,7 +223,7 @@ static gpointer session_connection = NULL; static ClientState current_state = STATE_DISCONNECTED; static gboolean interaction_allowed = FALSE; -LOCAL_SYMBOL void +void meta_session_init (const char *previous_client_id, const char *previous_save_file) { @@ -244,7 +245,7 @@ meta_session_init (const char *previous_client_id, { char *save_file = g_strconcat (previous_client_id, ".ms", NULL); saved_client_id = load_state (save_file); - free (save_file); + g_free (save_file); } else { @@ -314,8 +315,8 @@ meta_session_init (const char *previous_client_id, prgname = g_get_prgname (); - prop1.name = SmProgram; - prop1.type = SmARRAY8; + prop1.name = (char *)SmProgram; + prop1.type = (char *)SmARRAY8; prop1.num_vals = 1; prop1.vals = &prop1val; prop1val.value = (char *)prgname; @@ -324,38 +325,38 @@ meta_session_init (const char *previous_client_id, /* twm sets getuid() for this, but the SM spec plainly * says pw_name, twm is on crack */ - prop2.name = SmUserID; - prop2.type = SmARRAY8; + prop2.name = (char *)SmUserID; + prop2.type = (char *)SmARRAY8; prop2.num_vals = 1; prop2.vals = &prop2val; prop2val.value = (char*) g_get_user_name (); prop2val.length = strlen (prop2val.value); - prop3.name = SmRestartStyleHint; - prop3.type = SmCARD8; + prop3.name = (char *)SmRestartStyleHint; + prop3.type = (char *)SmCARD8; prop3.num_vals = 1; prop3.vals = &prop3val; prop3val.value = &hint; prop3val.length = 1; sprintf (pid, "%d", getpid ()); - prop4.name = SmProcessID; - prop4.type = SmARRAY8; + prop4.name = (char *)SmProcessID; + prop4.type = (char *)SmARRAY8; prop4.num_vals = 1; prop4.vals = &prop4val; prop4val.value = pid; prop4val.length = strlen (prop4val.value); /* Always start in home directory */ - prop5.name = SmCurrentDirectory; - prop5.type = SmARRAY8; + prop5.name = (char *)SmCurrentDirectory; + prop5.type = (char *)SmARRAY8; prop5.num_vals = 1; prop5.vals = &prop5val; prop5val.value = (char*) g_get_home_dir (); prop5val.length = strlen (prop5val.value); - prop6.name = "_GSM_Priority"; - prop6.type = SmCARD8; + prop6.name = (char *)"_GSM_Priority"; + prop6.type = (char *)SmCARD8; prop6.num_vals = 1; prop6.vals = &prop6val; prop6val.value = &priority; @@ -372,7 +373,7 @@ meta_session_init (const char *previous_client_id, } out: - free (saved_client_id); + g_free (saved_client_id); } static void @@ -533,6 +534,12 @@ die_callback (SmcConn smc_conn, SmPointer client_data) * Anything that wants us to go away outside of session management * can use kill(). */ + + /* All of that is true - unless we're a wayland compositor. In which + * case the X server won't go down until we do, so we must die first. + */ + if (meta_is_wayland_compositor ()) + meta_quit (0); } static void @@ -584,15 +591,15 @@ set_clone_restart_commands (void) /* Restart (use same client ID) */ - prop1.name = SmRestartCommand; - prop1.type = SmLISTofARRAY8; + prop1.name = (char *)SmRestartCommand; + prop1.type = (char *)SmLISTofARRAY8; g_return_if_fail (client_id); i = 0; restartv[i] = (char *)prgname; ++i; - restartv[i] = "--sm-client-id"; + restartv[i] = (char *)"--sm-client-id"; ++i; restartv[i] = client_id; ++i; @@ -615,8 +622,8 @@ set_clone_restart_commands (void) ++i; clonev[i] = NULL; - prop2.name = SmCloneCommand; - prop2.type = SmLISTofARRAY8; + prop2.name = (char *)SmCloneCommand; + prop2.type = (char *)SmLISTofARRAY8; prop2.vals = g_new (SmPropValue, i); i = 0; @@ -631,16 +638,16 @@ set_clone_restart_commands (void) /* Discard */ i = 0; - discardv[i] = "rm"; + discardv[i] = (char *)"rm"; ++i; - discardv[i] = "-f"; + discardv[i] = (char *)"-f"; ++i; discardv[i] = (char*) full_save_file (); ++i; discardv[i] = NULL; - prop3.name = SmDiscardCommand; - prop3.type = SmLISTofARRAY8; + prop3.name = (char *)SmDiscardCommand; + prop3.type = (char *)SmLISTofARRAY8; prop3.vals = g_new (SmPropValue, i); i = 0; @@ -659,9 +666,9 @@ set_clone_restart_commands (void) SmcSetProperties (session_connection, 3, props); - free (prop1.vals); - free (prop2.vals); - free (prop3.vals); + g_free (prop1.vals); + g_free (prop2.vals); + g_free (prop3.vals); } /* The remaining code in this file actually loads/saves the session, @@ -739,28 +746,28 @@ window_type_from_string (const char *str) static int window_gravity_from_string (const char *str) { - if (strcmp (str, "NorthWestGravity") == 0) - return NorthWestGravity; - else if (strcmp (str, "NorthGravity") == 0) - return NorthGravity; - else if (strcmp (str, "NorthEastGravity") == 0) - return NorthEastGravity; - else if (strcmp (str, "WestGravity") == 0) - return WestGravity; - else if (strcmp (str, "CenterGravity") == 0) - return CenterGravity; - else if (strcmp (str, "EastGravity") == 0) - return EastGravity; - else if (strcmp (str, "SouthWestGravity") == 0) - return SouthWestGravity; - else if (strcmp (str, "SouthGravity") == 0) - return SouthGravity; - else if (strcmp (str, "SouthEastGravity") == 0) - return SouthEastGravity; - else if (strcmp (str, "StaticGravity") == 0) - return StaticGravity; + if (strcmp (str, "META_GRAVITY_NORTH_WEST") == 0) + return META_GRAVITY_NORTH_WEST; + else if (strcmp (str, "META_GRAVITY_NORTH") == 0) + return META_GRAVITY_NORTH; + else if (strcmp (str, "META_GRAVITY_NORTH_EAST") == 0) + return META_GRAVITY_NORTH_EAST; + else if (strcmp (str, "META_GRAVITY_WEST") == 0) + return META_GRAVITY_WEST; + else if (strcmp (str, "META_GRAVITY_CENTER") == 0) + return META_GRAVITY_CENTER; + else if (strcmp (str, "META_GRAVITY_EAST") == 0) + return META_GRAVITY_EAST; + else if (strcmp (str, "META_GRAVITY_SOUTH_WEST") == 0) + return META_GRAVITY_SOUTH_WEST; + else if (strcmp (str, "META_GRAVITY_SOUTH") == 0) + return META_GRAVITY_SOUTH; + else if (strcmp (str, "META_GRAVITY_SOUTH_EAST") == 0) + return META_GRAVITY_SOUTH_EAST; + else if (strcmp (str, "META_GRAVITY_STATIC") == 0) + return META_GRAVITY_STATIC; else - return NorthWestGravity; + return META_GRAVITY_NORTH_WEST; } static char* @@ -812,7 +819,7 @@ decode_text_from_utf8 (const char *text) static void save_state (void) { - char *muffin_dir; + char *mutter_dir; char *session_dir; FILE *outfile; GSList *windows; @@ -831,19 +838,19 @@ save_state (void) * we probably already have full_save_path figured out and therefore * can just use the directory name from that. */ - muffin_dir = g_strconcat (g_get_user_config_dir (), - G_DIR_SEPARATOR_S "muffin", + mutter_dir = g_strconcat (g_get_user_config_dir (), + G_DIR_SEPARATOR_S "mutter", NULL); - session_dir = g_strconcat (muffin_dir, + session_dir = g_strconcat (mutter_dir, G_DIR_SEPARATOR_S "sessions", NULL); - if (mkdir (muffin_dir, 0700) < 0 && + if (mkdir (mutter_dir, 0700) < 0 && errno != EEXIST) { meta_warning ("Could not create directory '%s': %s\n", - muffin_dir, g_strerror (errno)); + mutter_dir, g_strerror (errno)); } if (mkdir (session_dir, 0700) < 0 && @@ -865,14 +872,14 @@ save_state (void) } /* The file format is: - * <muffin_session id="foo"> + * <mutter_session id="foo"> * <window id="bar" class="XTerm" name="xterm" title="/foo/bar" role="blah" type="normal" stacking="5"> * <workspace index="2"/> * <workspace index="4"/> * <sticky/> <minimized/> <maximized/> * <geometry x="100" y="100" width="200" height="200" gravity="northwest"/> * </window> - * </muffin_session> + * </mutter_session> * * Note that attributes on <window> are the match info we use to * see if the saved state applies to a restored window, and @@ -880,10 +887,11 @@ save_state (void) * */ - fprintf (outfile, "<muffin_session id=\"%s\">\n", + fprintf (outfile, "<mutter_session id=\"%s\">\n", client_id); windows = meta_display_list_windows (meta_get_display (), META_LIST_DEFAULT); + stack_position = 0; windows = g_slist_sort (windows, meta_display_stack_cmp); tmp = windows; @@ -933,15 +941,26 @@ save_state (void) window_type_to_string (window->type), stack_position); - free (sm_client_id); - free (res_class); - free (res_name); - free (role); - free (title); + g_free (sm_client_id); + g_free (res_class); + g_free (res_name); + g_free (role); + g_free (title); /* Sticky */ if (window->on_all_workspaces_requested) - fputs (" <sticky/>\n", outfile); + { + fputs (" <sticky/>\n", outfile); + } else { + int n; + if (window->workspace) + n = meta_workspace_index (window->workspace); + else + n = window->initial_workspace; + fprintf (outfile, + " <workspace index=\"%d\"/>\n", n); + } + /* Minimized */ if (window->minimized) @@ -958,18 +977,10 @@ save_state (void) window->saved_rect.height); } - /* Workspaces we're on */ - { - int n; - n = meta_workspace_index (window->workspace); - fprintf (outfile, - " <workspace index=\"%d\"/>\n", n); - } - /* Gravity */ { int x, y, w, h; - meta_window_get_geometry (window, &x, &y, &w, &h); + meta_window_get_session_geometry (window, &x, &y, &w, &h); fprintf (outfile, " <geometry x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" gravity=\"%s\"/>\n", @@ -979,20 +990,19 @@ save_state (void) fputs (" </window>\n", outfile); } -#ifdef WITH_VERBOSE_MODE else { meta_topic (META_DEBUG_SM, "Not saving window '%s', not session managed\n", window->desc); } -#endif + tmp = tmp->next; ++stack_position; } g_slist_free (windows); - fputs ("</muffin_session>\n", outfile); + fputs ("</mutter_session>\n", outfile); out: if (outfile) @@ -1010,8 +1020,8 @@ save_state (void) } } - free (muffin_dir); - free (session_dir); + g_free (mutter_dir); + g_free (session_dir); } typedef enum @@ -1049,7 +1059,7 @@ static void text_handler (GMarkupParseContext *context, gpointer user_data, GError **error); -static GMarkupParser muffin_session_parser = { +static GMarkupParser mutter_session_parser = { start_element_handler, end_element_handler, text_handler, @@ -1070,7 +1080,7 @@ load_state (const char *previous_save_file) char *session_file; session_file = g_strconcat (g_get_user_config_dir (), - G_DIR_SEPARATOR_S "muffin" + G_DIR_SEPARATOR_S "mutter" G_DIR_SEPARATOR_S "sessions" G_DIR_SEPARATOR_S, previous_save_file, NULL); @@ -1083,9 +1093,9 @@ load_state (const char *previous_save_file) { char *canonical_session_file = session_file; - /* Maybe they were doing it the old way, with ~/.muffin */ + /* Maybe they were doing it the old way, with ~/.mutter */ session_file = g_strconcat (g_get_home_dir (), - G_DIR_SEPARATOR_S ".muffin" + G_DIR_SEPARATOR_S ".mutter" G_DIR_SEPARATOR_S "sessions" G_DIR_SEPARATOR_S, previous_save_file, @@ -1099,22 +1109,22 @@ load_state (const char *previous_save_file) /* oh, just give up */ g_error_free (error); - free (session_file); - free (canonical_session_file); + g_free (session_file); + g_free (canonical_session_file); return NULL; } - free (canonical_session_file); + g_free (canonical_session_file); } meta_topic (META_DEBUG_SM, "Parsing saved session file %s\n", session_file); - free (session_file); + g_free (session_file); session_file = NULL; parse_data.info = NULL; parse_data.previous_id = NULL; - context = g_markup_parse_context_new (&muffin_session_parser, + context = g_markup_parse_context_new (&mutter_session_parser, 0, &parse_data, NULL); error = NULL; @@ -1142,12 +1152,12 @@ load_state (const char *previous_save_file) if (parse_data.info) session_info_free (parse_data.info); - free (parse_data.previous_id); + g_free (parse_data.previous_id); parse_data.previous_id = NULL; out: - free (text); + g_free (text); return parse_data.previous_id; } @@ -1165,7 +1175,7 @@ start_element_handler (GMarkupParseContext *context, pd = user_data; - if (strcmp (element_name, "muffin_session") == 0) + if (strcmp (element_name, "mutter_session") == 0) { /* Get previous ID */ int i; @@ -1184,7 +1194,7 @@ start_element_handler (GMarkupParseContext *context, g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, - "<muffin_session> attribute seen but we already have the session ID"); + "<mutter_session> attribute seen but we already have the session ID"); return; } @@ -1198,7 +1208,7 @@ start_element_handler (GMarkupParseContext *context, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, "Unknown attribute %s on <%s> element", - name, "muffin_session"); + name, "mutter_session"); return; } @@ -1383,14 +1393,13 @@ start_element_handler (GMarkupParseContext *context, ++i; } -#ifdef WITH_VERBOSE_MODE + if (pd->info->saved_rect_set) meta_topic (META_DEBUG_SM, "Saved unmaximized size %d,%d %dx%d \n", pd->info->saved_rect.x, pd->info->saved_rect.y, pd->info->saved_rect.width, pd->info->saved_rect.height); -#endif } else if (strcmp (element_name, "geometry") == 0) { @@ -1523,7 +1532,7 @@ get_possible_matches (MetaWindow *window) retval = NULL; - ignore_client_id = g_getenv ("MUFFIN_DEBUG_SM") != NULL; + ignore_client_id = g_getenv ("MUTTER_DEBUG_SM") != NULL; tmp = window_info_list; while (tmp != NULL) @@ -1626,7 +1635,7 @@ find_best_match (GSList *infos, return infos->data; } -LOCAL_SYMBOL const MetaWindowSessionInfo* +const MetaWindowSessionInfo* meta_window_lookup_saved_state (MetaWindow *window) { GSList *possibles; @@ -1661,7 +1670,7 @@ meta_window_lookup_saved_state (MetaWindow *window) return info; } -LOCAL_SYMBOL void +void meta_window_release_saved_state (const MetaWindowSessionInfo *info) { /* We don't want to use the same saved state again for another @@ -1675,15 +1684,15 @@ meta_window_release_saved_state (const MetaWindowSessionInfo *info) static void session_info_free (MetaWindowSessionInfo *info) { - free (info->id); - free (info->res_class); - free (info->res_name); - free (info->title); - free (info->role); + g_free (info->id); + g_free (info->res_class); + g_free (info->res_name); + g_free (info->title); + g_free (info->role); g_slist_free (info->workspace_indices); - free (info); + g_free (info); } static MetaWindowSessionInfo* @@ -1694,7 +1703,7 @@ session_info_new (void) info = g_new0 (MetaWindowSessionInfo, 1); info->type = META_WINDOW_NORMAL; - info->gravity = NorthWestGravity; + info->gravity = META_GRAVITY_NORTH_WEST; return info; } @@ -1704,11 +1713,11 @@ static char* full_save_path = NULL; static void regenerate_save_file (void) { - free (full_save_path); + g_free (full_save_path); if (client_id) full_save_path = g_strconcat (g_get_user_config_dir (), - G_DIR_SEPARATOR_S "muffin" + G_DIR_SEPARATOR_S "mutter" G_DIR_SEPARATOR_S "sessions" G_DIR_SEPARATOR_S, client_id, ".ms", @@ -1789,8 +1798,8 @@ warn_about_lame_clients_and_finish_interact (gboolean shutdown) return; } - columns = g_slist_prepend (columns, "Window"); - columns = g_slist_prepend (columns, "Class"); + columns = g_slist_prepend (columns, (gpointer)"Window"); + columns = g_slist_prepend (columns, (gpointer)"Class"); lame = g_slist_sort (lame, (GCompareFunc) windows_cmp_by_title); @@ -1800,7 +1809,7 @@ warn_about_lame_clients_and_finish_interact (gboolean shutdown) MetaWindow *w = tmp->data; lame_details = g_slist_prepend (lame_details, - w->res_class ? w->res_class : ""); + w->res_class ? w->res_class : (gpointer)""); lame_details = g_slist_prepend (lame_details, w->title); @@ -1809,12 +1818,12 @@ warn_about_lame_clients_and_finish_interact (gboolean shutdown) g_slist_free (lame); pid = meta_show_dialog("--list", - "These windows do not support "save current setup" " + _("These windows do not support “save current setup” " "and will have to be restarted manually next time " - "you log in.", + "you log in."), "240", - meta_get_display()->active_screen->screen_name, - NULL, NULL, + meta_get_display()->x11_display->screen_name, + NULL, NULL, NULL, None, columns, lame_details); diff --git a/src/core/session.h b/src/x11/session.h similarity index 90% rename from src/core/session.h rename to src/x11/session.h index 6ab969876..3f9c04a91 100644 --- a/src/core/session.h +++ b/src/x11/session.h @@ -9,9 +9,9 @@ * requires us to do it here. */ -/* +/* * Copyright (C) 2001 Havoc Pennington - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the @@ -21,17 +21,15 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef META_SESSION_H #define META_SESSION_H -#include "window-private.h" +#include "core/window-private.h" typedef struct _MetaWindowSessionInfo MetaWindowSessionInfo; @@ -47,17 +45,17 @@ struct _MetaWindowSessionInfo MetaWindowType type; /* Information we restore */ - - GSList *workspace_indices; + + GSList *workspace_indices; int stack_position; - + /* width/height should be multiplied by resize inc and * added to base size; position should be interpreted in * light of gravity. This preserves semantics of the * window size/pos, even if fonts/themes change, etc. */ - int gravity; + MetaGravity gravity; MetaRectangle rect; MetaRectangle saved_rect; guint on_all_workspaces : 1; diff --git a/src/core/window-props.c b/src/x11/window-props.c similarity index 62% rename from src/core/window-props.c rename to src/x11/window-props.c index fe4dc5822..5d8e8e48e 100644 --- a/src/core/window-props.c +++ b/src/x11/window-props.c @@ -1,6 +1,6 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/** +/* * SECTION:window-props * @short_description: #MetaWindow property handling * @@ -31,26 +31,29 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif -#define _SVID_SOURCE /* for gethostname() */ - -#include <config.h> -#include "window-props.h" -#include <meta/errors.h> -#include "xprops.h" -#include "frame.h" -#include <meta/group.h> +#define _XOPEN_SOURCE 600 /* for gethostname() */ + +#include "config.h" + +#include "x11/window-props.h" + #include <X11/Xatom.h> #include <unistd.h> #include <string.h> -#include "util-private.h" + +#include "core/frame.h" +#include "core/meta-workspace-manager-private.h" +#include "core/util-private.h" +#include "meta/group.h" +#include "meta/meta-x11-errors.h" +#include "x11/meta-x11-display-private.h" +#include "x11/window-x11-private.h" +#include "x11/window-x11.h" +#include "x11/xprops.h" + #ifndef HOST_NAME_MAX /* Solaris headers apparently don't define this so do so manually; #326745 */ #define HOST_NAME_MAX 255 @@ -60,13 +63,21 @@ typedef void (* ReloadValueFunc) (MetaWindow *window, MetaPropValue *value, gboolean initial); +typedef enum +{ + NONE = 0, + LOAD_INIT = (1 << 0), + INCLUDE_OR = (1 << 1), + INIT_ONLY = (1 << 2), + FORCE_INIT = (1 << 3), +} MetaPropHookFlags; + struct _MetaWindowPropHooks { Atom property; MetaPropValueType type; ReloadValueFunc reload_func; - gboolean load_initially; - gboolean include_override_redirect; + MetaPropHookFlags flags; }; static void init_prop_value (MetaWindow *window, @@ -76,95 +87,63 @@ static void reload_prop_value (MetaWindow *window, MetaWindowPropHooks *hooks, MetaPropValue *value, gboolean initial); -static MetaWindowPropHooks* find_hooks (MetaDisplay *display, - Atom property); +static MetaWindowPropHooks *find_hooks (MetaX11Display *x11_display, + Atom property); -LOCAL_SYMBOL void -meta_window_reload_property (MetaWindow *window, - Atom property, - gboolean initial) +void +meta_window_reload_property_from_xwindow (MetaWindow *window, + Window xwindow, + Atom property, + gboolean initial) { - meta_window_reload_properties (window, &property, 1, initial); -} - -LOCAL_SYMBOL void -meta_window_reload_properties (MetaWindow *window, - const Atom *properties, - int n_properties, - gboolean initial) -{ - meta_window_reload_properties_from_xwindow (window, - window->xwindow, - properties, - n_properties, - initial); -} - -LOCAL_SYMBOL void -meta_window_reload_property_from_xwindow (MetaWindow *window, - Window xwindow, - Atom property, - gboolean initial) -{ - meta_window_reload_properties_from_xwindow (window, xwindow, &property, 1, - initial); -} - -LOCAL_SYMBOL void -meta_window_reload_properties_from_xwindow (MetaWindow *window, - Window xwindow, - const Atom *properties, - int n_properties, - gboolean initial) -{ - int i; - MetaPropValue *values; - - g_return_if_fail (properties != NULL); - g_return_if_fail (n_properties > 0); + MetaPropValue value = { 0, }; + MetaWindowPropHooks *hooks; - values = g_new0 (MetaPropValue, n_properties); + hooks = find_hooks (window->display->x11_display, property); + if (!hooks) + return; - i = 0; - while (i < n_properties) - { - MetaWindowPropHooks *hooks = find_hooks (window->display, properties[i]); - init_prop_value (window, hooks, &values[i]); - ++i; - } + if ((hooks->flags & INIT_ONLY) && !initial) + return; - meta_prop_get_values (window->display, xwindow, - values, n_properties); + init_prop_value (window, hooks, &value); - i = 0; - while (i < n_properties) - { - MetaWindowPropHooks *hooks = find_hooks (window->display, properties[i]); - reload_prop_value (window, hooks, &values[i], initial); + meta_prop_get_values (window->display->x11_display, xwindow, + &value, 1); - ++i; - } + reload_prop_value (window, hooks, &value, + initial); - meta_prop_free_values (values, n_properties); + meta_prop_free_values (&value, 1); +} - free (values); +static void +meta_window_reload_property (MetaWindow *window, + Atom property, + gboolean initial) +{ + meta_window_reload_property_from_xwindow (window, + window->xwindow, + property, + initial); } -LOCAL_SYMBOL void +void meta_window_load_initial_properties (MetaWindow *window) { int i, j; MetaPropValue *values; int n_properties = 0; + MetaX11Display *x11_display = window->display->x11_display; - values = g_new0 (MetaPropValue, window->display->n_prop_hooks); + values = g_new0 (MetaPropValue, x11_display->n_prop_hooks); j = 0; - for (i = 0; i < window->display->n_prop_hooks; i++) + for (i = 0; i < x11_display->n_prop_hooks; i++) { - MetaWindowPropHooks *hooks = &window->display->prop_hooks_table[i]; - if (hooks->load_initially) + MetaWindowPropHooks *hooks = &x11_display->prop_hooks_table[i]; + if (hooks->flags & LOAD_INIT) { init_prop_value (window, hooks, &values[j]); ++j; @@ -172,20 +151,21 @@ meta_window_load_initial_properties (MetaWindow *window) } n_properties = j; - meta_prop_get_values (window->display, window->xwindow, + meta_prop_get_values (window->display->x11_display, window->xwindow, values, n_properties); j = 0; - for (i = 0; i < window->display->n_prop_hooks; i++) + for (i = 0; i < x11_display->n_prop_hooks; i++) { - MetaWindowPropHooks *hooks = &window->display->prop_hooks_table[i]; - if (hooks->load_initially) + MetaWindowPropHooks *hooks = &x11_display->prop_hooks_table[i]; + if (hooks->flags & LOAD_INIT) { /* If we didn't actually manage to load anything then we don't need * to call the reload function; this is different from a notification * where disappearance of a previously present value is significant. */ - if (values[j].type != META_PROP_VALUE_INVALID) + if (values[j].type != META_PROP_VALUE_INVALID || + hooks->flags & FORCE_INIT) reload_prop_value (window, hooks, &values[j], TRUE); ++j; } @@ -193,7 +173,7 @@ meta_window_load_initial_properties (MetaWindow *window) meta_prop_free_values (values, n_properties); - free (values); + g_free (values); } /* Fill in the MetaPropValue used to get the value of "property" */ @@ -203,7 +183,7 @@ init_prop_value (MetaWindow *window, MetaPropValue *value) { if (!hooks || hooks->type == META_PROP_VALUE_INVALID || - (window->override_redirect && !hooks->include_override_redirect)) + (window->override_redirect && !(hooks->flags & INCLUDE_OR))) { value->type = META_PROP_VALUE_INVALID; value->atom = None; @@ -221,8 +201,7 @@ reload_prop_value (MetaWindow *window, MetaPropValue *value, gboolean initial) { - if (hooks && hooks->reload_func != NULL && - !(window->override_redirect && !hooks->include_override_redirect)) + if (!(window->override_redirect && !(hooks->flags & INCLUDE_OR))) (* hooks->reload_func) (window, value, initial); } @@ -231,7 +210,7 @@ reload_wm_client_machine (MetaWindow *window, MetaPropValue *value, gboolean initial) { - free (window->wm_client_machine); + g_free (window->wm_client_machine); window->wm_client_machine = NULL; if (value->type != META_PROP_VALUE_INVALID) @@ -239,84 +218,18 @@ reload_wm_client_machine (MetaWindow *window, meta_verbose ("Window has client machine \"%s\"\n", window->wm_client_machine ? window->wm_client_machine : "unset"); -} -static void -reload_theme_icon_name (MetaWindow *window, - MetaPropValue *value, - gboolean initial) -{ - free (window->theme_icon_name); - window->theme_icon_name = NULL; - - if (value->type != META_PROP_VALUE_INVALID) - window->theme_icon_name = g_strdup (value->v.str); - - meta_verbose ("Window theme icon name or path is \"%s\"\n", - window->theme_icon_name ? window->theme_icon_name : "unset"); -} - -static void -reload_progress (MetaWindow *window, - MetaPropValue *value, - gboolean initial) -{ - if (value->type != META_PROP_VALUE_INVALID) + if (window->wm_client_machine == NULL) { - if (window->progress != value->v.cardinal) - { - window->progress = value->v.cardinal; - g_object_notify ((GObject*) window, "progress"); - - meta_topic (META_DEBUG_WINDOW_STATE, - "Read XAppGtkWindow progress prop %u for %s\n", - window->progress, window->desc); - } + window->is_remote = FALSE; } else { - if (window->progress != 0) - { - window->progress = 0; - g_object_notify ((GObject*) window, "progress"); + char hostname[HOST_NAME_MAX + 1] = ""; - meta_topic (META_DEBUG_WINDOW_STATE, - "Read XAppGtkWindow progress prop %u for %s\n", - window->progress, window->desc); - } - } -} + gethostname (hostname, HOST_NAME_MAX + 1); -static void -reload_progress_pulse (MetaWindow *window, - MetaPropValue *value, - gboolean initial) -{ - if (value->type != META_PROP_VALUE_INVALID) - { - gboolean new_val = value->v.cardinal == 1; - - if (window->progress_pulse != new_val) - { - window->progress_pulse = new_val; - g_object_notify ((GObject*) window, "progress-pulse"); - - meta_topic (META_DEBUG_WINDOW_STATE, - "Read XAppGtkWindow progress-pulse prop %s for %s\n", - window->progress_pulse ? "TRUE" : "FALSE", window->desc); - } - } - else - { - if (window->progress_pulse) - { - window->progress_pulse = FALSE; - g_object_notify ((GObject*) window, "progress-pulse"); - - meta_topic (META_DEBUG_WINDOW_STATE, - "Read XAppGtkWindow progress-pulse prop %s for %s\n", - window->progress_pulse ? "TRUE" : "FALSE", window->desc); - } + window->is_remote = g_strcmp0 (window->wm_client_machine, hostname) != 0; } } @@ -334,14 +247,56 @@ reload_net_wm_window_type (MetaWindow *window, MetaPropValue *value, gboolean initial) { - meta_window_update_net_wm_type (window); + MetaX11Display *x11_display = window->display->x11_display; + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = window_x11->priv; + + if (value->type != META_PROP_VALUE_INVALID) + { + int i; + + for (i = 0; i < value->v.atom_list.n_atoms; i++) + { + Atom atom = value->v.atom_list.atoms[i]; + + /* We break as soon as we find one we recognize, + * supposed to prefer those near the front of the list + */ + if (atom == x11_display->atom__NET_WM_WINDOW_TYPE_DESKTOP || + atom == x11_display->atom__NET_WM_WINDOW_TYPE_DOCK || + atom == x11_display->atom__NET_WM_WINDOW_TYPE_TOOLBAR || + atom == x11_display->atom__NET_WM_WINDOW_TYPE_MENU || + atom == x11_display->atom__NET_WM_WINDOW_TYPE_UTILITY || + atom == x11_display->atom__NET_WM_WINDOW_TYPE_SPLASH || + atom == x11_display->atom__NET_WM_WINDOW_TYPE_DIALOG || + atom == x11_display->atom__NET_WM_WINDOW_TYPE_DROPDOWN_MENU || + atom == x11_display->atom__NET_WM_WINDOW_TYPE_POPUP_MENU || + atom == x11_display->atom__NET_WM_WINDOW_TYPE_TOOLTIP || + atom == x11_display->atom__NET_WM_WINDOW_TYPE_NOTIFICATION || + atom == x11_display->atom__NET_WM_WINDOW_TYPE_COMBO || + atom == x11_display->atom__NET_WM_WINDOW_TYPE_DND || + atom == x11_display->atom__NET_WM_WINDOW_TYPE_NORMAL) + { + priv->type_atom = atom; + break; + } + } + } + + meta_window_x11_recalc_window_type (window); } static void reload_icon (MetaWindow *window, Atom atom) { - meta_window_icon_changed (window); + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = window_x11->priv; + + meta_icon_cache_property_changed (&priv->icon_cache, + window->display->x11_display, + atom); + meta_window_queue(window, META_QUEUE_UPDATE_ICON); } static void @@ -349,7 +304,7 @@ reload_net_wm_icon (MetaWindow *window, MetaPropValue *value, gboolean initial) { - reload_icon (window, window->display->atom__NET_WM_ICON); + reload_icon (window, window->display->x11_display->atom__NET_WM_ICON); } static void @@ -357,65 +312,101 @@ reload_kwm_win_icon (MetaWindow *window, MetaPropValue *value, gboolean initial) { - reload_icon (window, window->display->atom__KWM_WIN_ICON); + reload_icon (window, window->display->x11_display->atom__KWM_WIN_ICON); } static void -reload_gtk_frame_extents (MetaWindow *window, - MetaPropValue *value, - gboolean initial) +reload_icon_geometry (MetaWindow *window, + MetaPropValue *value, + gboolean initial) { if (value->type != META_PROP_VALUE_INVALID) { if (value->v.cardinal_list.n_cardinals != 4) { - meta_verbose ("_GTK_FRAME_EXTENTS on %s has %d values instead of 4\n", + meta_verbose ("_NET_WM_ICON_GEOMETRY on %s has %d values instead of 4\n", window->desc, value->v.cardinal_list.n_cardinals); } else { - GtkBorder *extents = &window->custom_frame_extents; + MetaRectangle geometry; + + geometry.x = (int)value->v.cardinal_list.cardinals[0]; + geometry.y = (int)value->v.cardinal_list.cardinals[1]; + geometry.width = (int)value->v.cardinal_list.cardinals[2]; + geometry.height = (int)value->v.cardinal_list.cardinals[3]; + + meta_window_set_icon_geometry (window, &geometry); + } + } + else + { + meta_window_set_icon_geometry (window, NULL); + } +} + +static void +meta_window_set_custom_frame_extents (MetaWindow *window, + GtkBorder *extents, + gboolean is_initial) +{ + if (extents) + { + if (window->has_custom_frame_extents && + memcmp (&window->custom_frame_extents, extents, sizeof (GtkBorder)) == 0) + return; + + window->has_custom_frame_extents = TRUE; + window->custom_frame_extents = *extents; - window->has_custom_frame_extents = TRUE; - extents->left = (int)value->v.cardinal_list.cardinals[0]; - extents->right = (int)value->v.cardinal_list.cardinals[1]; - extents->top = (int)value->v.cardinal_list.cardinals[2]; - extents->bottom = (int)value->v.cardinal_list.cardinals[3]; + /* If we're setting the frame extents on map, then this is telling + * us to adjust our understanding of the frame rect to match what + * GTK+ thinks it is. Future changes to the frame extents should + * trigger a resize and send a ConfigureRequest to the application. + */ + if (is_initial) + { + meta_window_client_rect_to_frame_rect (window, &window->rect, &window->rect); + meta_window_client_rect_to_frame_rect (window, &window->unconstrained_rect, &window->unconstrained_rect); } } else { + if (!window->has_custom_frame_extents) + return; + window->has_custom_frame_extents = FALSE; + memset (&window->custom_frame_extents, 0, sizeof (window->custom_frame_extents)); } + + meta_window_queue (window, META_QUEUE_MOVE_RESIZE); } static void -reload_icon_geometry (MetaWindow *window, - MetaPropValue *value, - gboolean initial) +reload_gtk_frame_extents (MetaWindow *window, + MetaPropValue *value, + gboolean initial) { if (value->type != META_PROP_VALUE_INVALID) { if (value->v.cardinal_list.n_cardinals != 4) { - meta_verbose ("_NET_WM_ICON_GEOMETRY on %s has %d values instead of 4\n", + meta_verbose ("_GTK_FRAME_EXTENTS on %s has %d values instead of 4\n", window->desc, value->v.cardinal_list.n_cardinals); } else { - MetaRectangle geometry; - - geometry.x = (int)value->v.cardinal_list.cardinals[0]; - geometry.y = (int)value->v.cardinal_list.cardinals[1]; - geometry.width = (int)value->v.cardinal_list.cardinals[2]; - geometry.height = (int)value->v.cardinal_list.cardinals[3]; - - meta_window_set_icon_geometry (window, &geometry); + GtkBorder extents; + extents.left = (int)value->v.cardinal_list.cardinals[0]; + extents.right = (int)value->v.cardinal_list.cardinals[1]; + extents.top = (int)value->v.cardinal_list.cardinals[2]; + extents.bottom = (int)value->v.cardinal_list.cardinals[3]; + meta_window_set_custom_frame_extents (window, &extents, initial); } } else { - meta_window_set_icon_geometry (window, NULL); + meta_window_set_custom_frame_extents (window, NULL, initial); } } @@ -432,7 +423,9 @@ reload_wm_window_role (MetaWindow *window, MetaPropValue *value, gboolean initial) { - meta_window_update_role (window); + g_clear_pointer (&window->role, g_free); + if (value->type != META_PROP_VALUE_INVALID) + window->role = g_strdup (value->v.str); } static void @@ -442,10 +435,10 @@ reload_net_wm_pid (MetaWindow *window, { if (value->type != META_PROP_VALUE_INVALID) { - gulong cardinal = (int) value->v.cardinal; + uint32_t cardinal = (int) value->v.cardinal; if (cardinal <= 0) - meta_warning ("Application set a bogus _NET_WM_PID %lu\n", + meta_warning ("Application set a bogus _NET_WM_PID %u\n", cardinal); else { @@ -463,7 +456,7 @@ reload_net_wm_user_time (MetaWindow *window, { if (value->type != META_PROP_VALUE_INVALID) { - gulong cardinal = value->v.cardinal; + uint32_t cardinal = value->v.cardinal; meta_window_set_user_time (window, cardinal); } } @@ -476,14 +469,15 @@ reload_net_wm_user_time_window (MetaWindow *window, if (value->type != META_PROP_VALUE_INVALID) { MetaWindow *prev_owner; + /* Unregister old NET_WM_USER_TIME_WINDOW */ if (window->user_time_window != None) { /* See the comment to the meta_display_register_x_window call below. */ - meta_display_unregister_x_window (window->display, - window->user_time_window); + meta_x11_display_unregister_x_window (window->display->x11_display, + window->user_time_window); /* Don't get events on not-managed windows */ - XSelectInput (window->display->xdisplay, + XSelectInput (window->display->x11_display->xdisplay, window->user_time_window, NoEventMask); } @@ -491,10 +485,12 @@ reload_net_wm_user_time_window (MetaWindow *window, /* Ensure the new user time window is not used on another MetaWindow, * and unset its user time window if that is the case. */ - prev_owner = meta_display_lookup_x_window (window->display, value->v.xwindow); + prev_owner = meta_x11_display_lookup_x_window (window->display->x11_display, + value->v.xwindow); if (prev_owner && prev_owner->user_time_window == value->v.xwindow) { - meta_display_unregister_x_window (window->display, value->v.xwindow); + meta_x11_display_unregister_x_window (window->display->x11_display, + value->v.xwindow); prev_owner->user_time_window = None; } @@ -514,11 +510,11 @@ reload_net_wm_user_time_window (MetaWindow *window, * than atom__NET_WM_USER_TIME ones, but I just don't care * and it's not specified in the spec anyway. */ - meta_display_register_x_window (window->display, - &window->user_time_window, - window); + meta_x11_display_register_x_window (window->display->x11_display, + &window->user_time_window, + window); /* Just listen for property notify events */ - XSelectInput (window->display->xdisplay, + XSelectInput (window->display->x11_display->xdisplay, window->user_time_window, PropertyChangeMask); @@ -529,7 +525,7 @@ reload_net_wm_user_time_window (MetaWindow *window, meta_window_reload_property_from_xwindow ( window, window->user_time_window, - window->display->atom__NET_WM_USER_TIME, + window->display->x11_display->atom__NET_WM_USER_TIME, initial); } } @@ -537,12 +533,13 @@ reload_net_wm_user_time_window (MetaWindow *window, #define MAX_TITLE_LENGTH 512 -/* - * Called by set_window_title and set_icon_title to set the value of - * *target to title. It required and atom is set, it will update the - * appropriate property. +/** + * set_title_text: + * + * Called by set_window_title() to set the value of @target to @title. + * If required and @atom is set, it will update the appropriate property. * - * Returns TRUE if a new title was set. + * Returns: %TRUE if a new title was set. */ static gboolean set_title_text (MetaWindow *window, @@ -551,13 +548,12 @@ set_title_text (MetaWindow *window, Atom atom, char **target) { - char hostname[HOST_NAME_MAX + 1]; gboolean modified = FALSE; if (!target) return FALSE; - free (*target); + g_free (*target); if (!title) *target = g_strdup (""); @@ -568,9 +564,7 @@ set_title_text (MetaWindow *window, } /* if WM_CLIENT_MACHINE indicates this machine is on a remote host * lets place that hostname in the title */ - else if (window->wm_client_machine && - !gethostname (hostname, HOST_NAME_MAX + 1) && - strcmp (hostname, window->wm_client_machine)) + else if (meta_window_is_remote (window)) { *target = g_strdup_printf (_("%s (on %s)"), title, window->wm_client_machine); @@ -580,18 +574,18 @@ set_title_text (MetaWindow *window, *target = g_strdup (title); if (modified && atom != None) - meta_prop_set_utf8_string_hint (window->display, + meta_prop_set_utf8_string_hint (window->display->x11_display, window->xwindow, atom, *target); /* Bug 330671 -- Don't forget to clear _NET_WM_VISIBLE_(ICON_)NAME */ if (!modified && previous_was_modified) { - meta_error_trap_push (window->display); - XDeleteProperty (window->display->xdisplay, + meta_x11_error_trap_push (window->display->x11_display); + XDeleteProperty (window->display->x11_display->xdisplay, window->xwindow, atom); - meta_error_trap_pop (window->display); + meta_x11_error_trap_pop (window->display->x11_display); } return modified; @@ -601,28 +595,22 @@ static void set_window_title (MetaWindow *window, const char *title) { - char *str; + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = window_x11->priv; + + char *new_title = NULL; gboolean modified = set_title_text (window, - window->using_net_wm_visible_name, + priv->using_net_wm_visible_name, title, - window->display->atom__NET_WM_VISIBLE_NAME, - &window->title); - window->using_net_wm_visible_name = modified; - - /* strndup is a hack since GNU libc has broken %.10s */ - str = g_strndup (window->title, 10); - free (window->desc); - window->desc = g_strdup_printf ("0x%lx (%s)", window->xwindow, str); - free (str); - - if (window->frame) - meta_ui_set_frame_title (window->screen->ui, - window->frame->xwindow, - window->title); - - g_object_notify (G_OBJECT (window), "title"); + window->display->x11_display->atom__NET_WM_VISIBLE_NAME, + &new_title); + priv->using_net_wm_visible_name = modified; + + meta_window_set_title (window, new_title); + + g_free (new_title); } static void @@ -630,10 +618,13 @@ reload_net_wm_name (MetaWindow *window, MetaPropValue *value, gboolean initial) { + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = window_x11->priv; + if (value->type != META_PROP_VALUE_INVALID) { set_window_title (window, value->v.str); - window->using_net_wm_name = TRUE; + priv->using_net_wm_name = TRUE; meta_verbose ("Using _NET_WM_NAME for new title of %s: \"%s\"\n", window->desc, window->title); @@ -641,7 +632,7 @@ reload_net_wm_name (MetaWindow *window, else { set_window_title (window, NULL); - window->using_net_wm_name = FALSE; + priv->using_net_wm_name = FALSE; if (!initial) meta_window_reload_property (window, XA_WM_NAME, FALSE); } @@ -652,7 +643,10 @@ reload_wm_name (MetaWindow *window, MetaPropValue *value, gboolean initial) { - if (window->using_net_wm_name) + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = window_x11->priv; + + if (priv->using_net_wm_name) { meta_verbose ("Ignoring WM_NAME \"%s\" as _NET_WM_NAME is set\n", value->v.str); @@ -696,7 +690,7 @@ reload_opaque_region (MetaWindow *window, if (value->type != META_PROP_VALUE_INVALID) { - gulong *region = value->v.cardinal_list.cardinals; + uint32_t *region = value->v.cardinal_list.cardinals; int nitems = value->v.cardinal_list.n_cardinals; cairo_rectangle_int_t *rects; @@ -732,7 +726,7 @@ reload_opaque_region (MetaWindow *window, opaque_region = cairo_region_create_rectangles (rects, nrects); - free (rects); + g_free (rects); } out: @@ -741,14 +735,14 @@ reload_opaque_region (MetaWindow *window, } static void -reload_muffin_hints (MetaWindow *window, +reload_mutter_hints (MetaWindow *window, MetaPropValue *value, gboolean initial) { if (value->type != META_PROP_VALUE_INVALID) { char *new_hints = value->v.str; - char *old_hints = window->muffin_hints; + char *old_hints = window->mutter_hints; gboolean changed = FALSE; if (new_hints) @@ -764,82 +758,22 @@ reload_muffin_hints (MetaWindow *window, if (changed) { - free (old_hints); + g_free (old_hints); if (new_hints) - window->muffin_hints = g_strdup (new_hints); + window->mutter_hints = g_strdup (new_hints); else - window->muffin_hints = NULL; + window->mutter_hints = NULL; - g_object_notify (G_OBJECT (window), "muffin-hints"); + g_object_notify (G_OBJECT (window), "mutter-hints"); } } - else if (window->muffin_hints) - { - free (window->muffin_hints); - window->muffin_hints = NULL; - - g_object_notify (G_OBJECT (window), "muffin-hints"); - } -} - -static void -set_icon_title (MetaWindow *window, - const char *title) -{ - gboolean modified = - set_title_text (window, - window->using_net_wm_visible_icon_name, - title, - window->display->atom__NET_WM_VISIBLE_ICON_NAME, - &window->icon_name); - window->using_net_wm_visible_icon_name = modified; -} - -static void -reload_net_wm_icon_name (MetaWindow *window, - MetaPropValue *value, - gboolean initial) -{ - if (value->type != META_PROP_VALUE_INVALID) - { - set_icon_title (window, value->v.str); - window->using_net_wm_icon_name = TRUE; - - meta_verbose ("Using _NET_WM_ICON_NAME for new title of %s: \"%s\"\n", - window->desc, window->title); - } - else - { - set_icon_title (window, NULL); - window->using_net_wm_icon_name = FALSE; - if (!initial) - meta_window_reload_property (window, XA_WM_ICON_NAME, FALSE); - } -} - -static void -reload_wm_icon_name (MetaWindow *window, - MetaPropValue *value, - gboolean initial) -{ - if (window->using_net_wm_icon_name) - { - meta_verbose ("Ignoring WM_ICON_NAME \"%s\" as _NET_WM_ICON_NAME is set\n", - value->v.str); - return; - } - - if (value->type != META_PROP_VALUE_INVALID) + else if (window->mutter_hints) { - set_icon_title (window, value->v.str); + g_free (window->mutter_hints); + window->mutter_hints = NULL; - meta_verbose ("Using WM_ICON_NAME for new title of %s: \"%s\"\n", - window->desc, window->title); - } - else - { - set_icon_title (window, NULL); + g_object_notify (G_OBJECT (window), "mutter-hints"); } } @@ -848,6 +782,10 @@ reload_net_wm_state (MetaWindow *window, MetaPropValue *value, gboolean initial) { + MetaX11Display *x11_display = window->display->x11_display; + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = window_x11->priv; + int i; /* We know this is only an initial window creation, @@ -860,13 +798,14 @@ reload_net_wm_state (MetaWindow *window, "the property in the first place\n"); return; } + window->shaded = FALSE; window->maximized_horizontally = FALSE; window->maximized_vertically = FALSE; window->fullscreen = FALSE; - window->wm_state_modal = FALSE; - window->wm_state_skip_taskbar = FALSE; - window->wm_state_skip_pager = FALSE; + priv->wm_state_modal = FALSE; + priv->wm_state_skip_taskbar = FALSE; + priv->wm_state_skip_pager = FALSE; window->wm_state_above = FALSE; window->wm_state_below = FALSE; window->wm_state_demands_attention = FALSE; @@ -877,47 +816,41 @@ reload_net_wm_state (MetaWindow *window, i = 0; while (i < value->v.atom_list.n_atoms) { - if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_TILED) - window->tile_after_placement = TRUE; - ++i; - } - - i = 0; - while (i < value->v.atom_list.n_atoms) - { - if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_SHADED) + if (value->v.atom_list.atoms[i] == x11_display->atom__NET_WM_STATE_SHADED) window->shaded = TRUE; - else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_MAXIMIZED_HORZ && - !window->tile_after_placement) + else if (value->v.atom_list.atoms[i] == x11_display->atom__NET_WM_STATE_MAXIMIZED_HORZ) window->maximize_horizontally_after_placement = TRUE; - else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_MAXIMIZED_VERT && - !window->tile_after_placement) + else if (value->v.atom_list.atoms[i] == x11_display->atom__NET_WM_STATE_MAXIMIZED_VERT) window->maximize_vertically_after_placement = TRUE; - else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_HIDDEN) + else if (value->v.atom_list.atoms[i] == x11_display->atom__NET_WM_STATE_HIDDEN) window->minimize_after_placement = TRUE; - else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_MODAL) - window->wm_state_modal = TRUE; - else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_SKIP_TASKBAR) - window->wm_state_skip_taskbar = TRUE; - else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_SKIP_PAGER) - window->wm_state_skip_pager = TRUE; - else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_FULLSCREEN) - window->fullscreen = TRUE; - else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_ABOVE) + else if (value->v.atom_list.atoms[i] == x11_display->atom__NET_WM_STATE_MODAL) + priv->wm_state_modal = TRUE; + else if (value->v.atom_list.atoms[i] == x11_display->atom__NET_WM_STATE_SKIP_TASKBAR) + priv->wm_state_skip_taskbar = TRUE; + else if (value->v.atom_list.atoms[i] == x11_display->atom__NET_WM_STATE_SKIP_PAGER) + priv->wm_state_skip_pager = TRUE; + else if (value->v.atom_list.atoms[i] == x11_display->atom__NET_WM_STATE_FULLSCREEN) + { + window->fullscreen = TRUE; + g_object_notify (G_OBJECT (window), "fullscreen"); + } + else if (value->v.atom_list.atoms[i] == x11_display->atom__NET_WM_STATE_ABOVE) window->wm_state_above = TRUE; - else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_BELOW) + else if (value->v.atom_list.atoms[i] == x11_display->atom__NET_WM_STATE_BELOW) window->wm_state_below = TRUE; - else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_DEMANDS_ATTENTION) + else if (value->v.atom_list.atoms[i] == x11_display->atom__NET_WM_STATE_DEMANDS_ATTENTION) window->wm_state_demands_attention = TRUE; - else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_STICKY) + else if (value->v.atom_list.atoms[i] == x11_display->atom__NET_WM_STATE_STICKY) window->on_all_workspaces_requested = TRUE; + ++i; } meta_verbose ("Reloaded _NET_WM_STATE for %s\n", window->desc); - meta_window_recalc_window_type (window); + meta_window_x11_recalc_window_type (window); meta_window_recalc_features (window); } @@ -953,7 +886,7 @@ reload_mwm_hints (MetaWindow *window, if (hints->flags & MWM_HINTS_DECORATIONS) { - meta_verbose ("Window %s sets MWM_HINTS_DECORATIONS 0x%lx\n", + meta_verbose ("Window %s sets MWM_HINTS_DECORATIONS 0x%x\n", window->desc, hints->decorations); if (hints->decorations == 0) @@ -969,7 +902,7 @@ reload_mwm_hints (MetaWindow *window, { gboolean toggle_value; - meta_verbose ("Window %s sets MWM_HINTS_FUNCTIONS 0x%lx\n", + meta_verbose ("Window %s sets MWM_HINTS_FUNCTIONS 0x%x\n", window->desc, hints->functions); /* If _ALL is specified, then other flags indicate what to turn off; @@ -1032,7 +965,7 @@ reload_mwm_hints (MetaWindow *window, meta_window_recalc_features (window); - /* We do all this anyhow at the end of meta_window_new() */ + /* We do all this anyhow at the end of meta_window_x11_new() */ if (!window->constructing) { if (window->decorated) @@ -1055,23 +988,19 @@ reload_wm_class (MetaWindow *window, MetaPropValue *value, gboolean initial) { - if (window->res_class) - free (window->res_class); - if (window->res_name) - free (window->res_name); - - window->res_class = NULL; - window->res_name = NULL; - if (value->type != META_PROP_VALUE_INVALID) { - if (value->v.class_hint.res_name) - window->res_name = g_strdup (value->v.class_hint.res_name); - - if (value->v.class_hint.res_class) - window->res_class = g_strdup (value->v.class_hint.res_class); - - g_object_notify (G_OBJECT (window), "wm-class"); + g_autofree gchar *res_class = g_convert (value->v.class_hint.res_class, -1, + "UTF-8", "LATIN1", + NULL, NULL, NULL); + g_autofree gchar *res_name = g_convert (value->v.class_hint.res_name, -1, + "UTF-8", "LATIN1", + NULL, NULL, NULL); + meta_window_set_wm_class (window, res_class, res_name); + } + else + { + meta_window_set_wm_class (window, NULL, NULL); } meta_verbose ("Window %s class: '%s' name: '%s'\n", @@ -1100,10 +1029,11 @@ reload_net_startup_id (MetaWindow *window, MetaPropValue *value, gboolean initial) { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; guint32 timestamp = window->net_wm_user_time; MetaWorkspace *workspace = NULL; - free (window->startup_id); + g_free (window->startup_id); if (value->type != META_PROP_VALUE_INVALID) window->startup_id = g_strdup (value->v.str); @@ -1116,13 +1046,14 @@ reload_net_startup_id (MetaWindow *window, window->initial_timestamp_set = 0; window->initial_workspace_set = 0; - if (meta_screen_apply_startup_properties (window->screen, window)) + if (meta_display_apply_startup_properties (window->display, window)) { if (window->initial_timestamp_set) timestamp = window->initial_timestamp; if (window->initial_workspace_set) - workspace = meta_screen_get_workspace_by_index (window->screen, window->initial_workspace); + workspace = meta_workspace_manager_get_workspace_by_index (workspace_manager, + window->initial_workspace); meta_window_activate_with_workspace (window, timestamp, workspace); } @@ -1140,9 +1071,9 @@ reload_update_counter (MetaWindow *window, { if (value->type != META_PROP_VALUE_INVALID) { - meta_window_destroy_sync_request_alarm (window); -#ifdef HAVE_XSYNC + meta_window_x11_destroy_sync_request_alarm (window); window->sync_request_counter = None; + if (value->v.xcounter_list.n_counters == 0) { meta_warning ("_NET_WM_SYNC_REQUEST_COUNTER is empty\n"); @@ -1164,18 +1095,23 @@ reload_update_counter (MetaWindow *window, window->extended_sync_request_counter ? "true" : "false"); if (window->extended_sync_request_counter) - meta_window_create_sync_request_alarm (window); -#endif + meta_window_x11_create_sync_request_alarm (window); } } +#define FLAG_IS_ON(hints,flag) \ + (((hints)->flags & (flag)) != 0) + +#define FLAG_IS_OFF(hints,flag) \ + (((hints)->flags & (flag)) == 0) + #define FLAG_TOGGLED_ON(old,new,flag) \ - (((old)->flags & (flag)) == 0 && \ - ((new)->flags & (flag)) != 0) + (FLAG_IS_OFF(old,flag) && \ + FLAG_IS_ON(new,flag)) #define FLAG_TOGGLED_OFF(old,new,flag) \ - (((old)->flags & (flag)) != 0 && \ - ((new)->flags & (flag)) == 0) + (FLAG_IS_ON(old,flag) && \ + FLAG_IS_OFF(new,flag)) #define FLAG_CHANGED(old,new,flag) \ (FLAG_TOGGLED_ON(old,new,flag) || FLAG_TOGGLED_OFF(old,new,flag)) @@ -1229,20 +1165,96 @@ spew_size_hints_differences (const XSizeHints *old, old->win_gravity, new->win_gravity); } -LOCAL_SYMBOL void +static gboolean +hints_have_changed (const XSizeHints *old, + const XSizeHints *new) +{ + /* 1. Check if the relevant values have changed if the flag is set. */ + + if (FLAG_TOGGLED_ON (old, new, USPosition) || + (FLAG_IS_ON (new, USPosition) && + (old->x != new->x || + old->y != new->y))) + return TRUE; + + if (FLAG_TOGGLED_ON (old, new, USSize) || + (FLAG_IS_ON (new, USSize) && + (old->width != new->width || + old->height != new->height))) + return TRUE; + + if (FLAG_TOGGLED_ON (old, new, PPosition) || + (FLAG_IS_ON (new, PPosition) && + (old->x != new->x || + old->y != new->y))) + return TRUE; + + if (FLAG_TOGGLED_ON (old, new, PSize) || + (FLAG_IS_ON (new, PSize) && + (old->width != new->width || + old->height != new->height))) + return TRUE; + + if (FLAG_TOGGLED_ON (old, new, PMinSize) || + (FLAG_IS_ON (new, PMinSize) && + (old->min_width != new->min_width || + old->min_height != new->min_height))) + return TRUE; + + if (FLAG_TOGGLED_ON (old, new, PMaxSize) || + (FLAG_IS_ON (new, PMaxSize) && + (old->max_width != new->max_width || + old->max_height != new->max_height))) + return TRUE; + + if (FLAG_TOGGLED_ON (old, new, PResizeInc) || + (FLAG_IS_ON (new, PResizeInc) && + (old->width_inc != new->width_inc || + old->height_inc != new->height_inc))) + return TRUE; + + if (FLAG_TOGGLED_ON (old, new, PAspect) || + (FLAG_IS_ON (new, PAspect) && + (old->min_aspect.x != new->min_aspect.x || + old->min_aspect.y != new->min_aspect.y || + old->max_aspect.x != new->max_aspect.x || + old->max_aspect.y != new->max_aspect.y))) + return TRUE; + + if (FLAG_TOGGLED_ON (old, new, PBaseSize) || + (FLAG_IS_ON (new, PBaseSize) && + (old->base_width != new->base_width || + old->base_height != new->base_height))) + return TRUE; + + if (FLAG_TOGGLED_ON (old, new, PWinGravity) || + (FLAG_IS_ON (new, PWinGravity) && + (old->win_gravity != new->win_gravity))) + return TRUE; + + /* 2. Check if the flags have been unset. */ + return FLAG_TOGGLED_OFF (old, new, USPosition) || + FLAG_TOGGLED_OFF (old, new, USSize) || + FLAG_TOGGLED_OFF (old, new, PPosition) || + FLAG_TOGGLED_OFF (old, new, PSize) || + FLAG_TOGGLED_OFF (old, new, PMinSize) || + FLAG_TOGGLED_OFF (old, new, PMaxSize) || + FLAG_TOGGLED_OFF (old, new, PResizeInc) || + FLAG_TOGGLED_OFF (old, new, PAspect) || + FLAG_TOGGLED_OFF (old, new, PBaseSize) || + FLAG_TOGGLED_OFF (old, new, PWinGravity); +} + +void meta_set_normal_hints (MetaWindow *window, XSizeHints *hints) { int x, y, w, h; double minr, maxr; - gint ui_scale; - /* Some convenience vars */ int minw, minh, maxw, maxh; /* min/max width/height */ int basew, baseh, winc, hinc; /* base width/height, width/height increment */ - ui_scale = meta_prefs_get_ui_scale (); - /* Save the last ConfigureRequest, which we put here. * Values here set in the hints are supposed to * be ignored. @@ -1341,8 +1353,8 @@ meta_set_normal_hints (MetaWindow *window, } else { - window->size_hints.width_inc = ui_scale; - window->size_hints.height_inc = ui_scale; + window->size_hints.width_inc = 1; + window->size_hints.height_inc = 1; window->size_hints.flags |= PResizeInc; } @@ -1378,58 +1390,58 @@ meta_set_normal_hints (MetaWindow *window, meta_topic (META_DEBUG_GEOMETRY, "Window %s doesn't set gravity, using NW\n", window->desc); - window->size_hints.win_gravity = NorthWestGravity; + window->size_hints.win_gravity = META_GRAVITY_NORTH_WEST; window->size_hints.flags |= PWinGravity; } /*** Lots of sanity checking ***/ /* Verify all min & max hints are at least 1 pixel */ - if (window->size_hints.min_width < ui_scale) + if (window->size_hints.min_width < 1) { /* someone is on crack */ meta_topic (META_DEBUG_GEOMETRY, "Window %s sets min width to 0, which makes no sense\n", window->desc); - window->size_hints.min_width = ui_scale; + window->size_hints.min_width = 1; } - if (window->size_hints.max_width < ui_scale) + if (window->size_hints.max_width < 1) { /* another cracksmoker */ meta_topic (META_DEBUG_GEOMETRY, "Window %s sets max width to 0, which makes no sense\n", window->desc); - window->size_hints.max_width = ui_scale; + window->size_hints.max_width = 1; } - if (window->size_hints.min_height < ui_scale) + if (window->size_hints.min_height < 1) { /* another cracksmoker */ meta_topic (META_DEBUG_GEOMETRY, "Window %s sets min height to 0, which makes no sense\n", window->desc); - window->size_hints.min_height = ui_scale; + window->size_hints.min_height = 1; } - if (window->size_hints.max_height < ui_scale) + if (window->size_hints.max_height < 1) { /* another cracksmoker */ meta_topic (META_DEBUG_GEOMETRY, "Window %s sets max height to 0, which makes no sense\n", window->desc); - window->size_hints.max_height = ui_scale; + window->size_hints.max_height = 1; } /* Verify size increment hints are at least 1 pixel */ - if (window->size_hints.width_inc < ui_scale) + if (window->size_hints.width_inc < 1) { /* app authors find so many ways to smoke crack */ - window->size_hints.width_inc = ui_scale; - meta_topic (META_DEBUG_GEOMETRY, "Corrected too-small width_inc to window scale factor\n"); + window->size_hints.width_inc = 1; + meta_topic (META_DEBUG_GEOMETRY, "Corrected 0 width_inc to 1\n"); } - if (window->size_hints.height_inc < ui_scale) + if (window->size_hints.height_inc < 1) { /* another cracksmoker */ - window->size_hints.height_inc = ui_scale; - meta_topic (META_DEBUG_GEOMETRY, "Corrected too-small height_inc to window scale factor\n"); + window->size_hints.height_inc = 1; + meta_topic (META_DEBUG_GEOMETRY, "Corrected 0 height_inc to 1\n"); } /* divide by 0 cracksmokers; note that x & y in (min|max)_aspect are * numerator & denominator @@ -1583,6 +1595,7 @@ reload_normal_hints (MetaWindow *window, if (value->type != META_PROP_VALUE_INVALID) { XSizeHints old_hints; + gboolean hints_have_differences; meta_topic (META_DEBUG_GEOMETRY, "Updating WM_NORMAL_HINTS for %s\n", window->desc); @@ -1590,12 +1603,16 @@ reload_normal_hints (MetaWindow *window, meta_set_normal_hints (window, value->v.size_hints.hints); - spew_size_hints_differences (&old_hints, &window->size_hints); - - meta_window_recalc_features (window); + hints_have_differences = hints_have_changed (&old_hints, + &window->size_hints); + if (hints_have_differences) + { + spew_size_hints_differences (&old_hints, &window->size_hints); + meta_window_recalc_features (window); - if (!initial) - meta_window_queue(window, META_QUEUE_MOVE_RESIZE); + if (!initial) + meta_window_queue (window, META_QUEUE_MOVE_RESIZE); + } } } @@ -1606,9 +1623,9 @@ reload_wm_protocols (MetaWindow *window, { int i; - window->take_focus = FALSE; - window->delete_window = FALSE; - window->net_wm_ping = FALSE; + meta_window_x11_set_wm_take_focus (window, FALSE); + meta_window_x11_set_wm_ping (window, FALSE); + meta_window_x11_set_wm_delete_window (window, FALSE); if (value->type == META_PROP_VALUE_INVALID) return; @@ -1617,14 +1634,14 @@ reload_wm_protocols (MetaWindow *window, while (i < value->v.atom_list.n_atoms) { if (value->v.atom_list.atoms[i] == - window->display->atom_WM_TAKE_FOCUS) - window->take_focus = TRUE; + window->display->x11_display->atom_WM_TAKE_FOCUS) + meta_window_x11_set_wm_take_focus (window, TRUE); else if (value->v.atom_list.atoms[i] == - window->display->atom_WM_DELETE_WINDOW) - window->delete_window = TRUE; + window->display->x11_display->atom_WM_DELETE_WINDOW) + meta_window_x11_set_wm_delete_window (window, TRUE); else if (value->v.atom_list.atoms[i] == - window->display->atom__NET_WM_PING) - window->net_wm_ping = TRUE; + window->display->x11_display->atom__NET_WM_PING) + meta_window_x11_set_wm_ping (window, TRUE); ++i; } @@ -1638,19 +1655,20 @@ reload_wm_hints (MetaWindow *window, MetaPropValue *value, gboolean initial) { + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = window_x11->priv; Window old_group_leader; - gboolean old_urgent; + gboolean urgent; old_group_leader = window->xgroup_leader; - old_urgent = window->wm_hints_urgent; /* Fill in defaults */ window->input = TRUE; window->initially_iconic = FALSE; window->xgroup_leader = None; - window->wm_hints_pixmap = None; - window->wm_hints_mask = None; - window->wm_hints_urgent = FALSE; + priv->wm_hints_pixmap = None; + priv->wm_hints_mask = None; + urgent = FALSE; if (value->type != META_PROP_VALUE_INVALID) { @@ -1666,19 +1684,19 @@ reload_wm_hints (MetaWindow *window, window->xgroup_leader = hints->window_group; if (hints->flags & IconPixmapHint) - window->wm_hints_pixmap = hints->icon_pixmap; + priv->wm_hints_pixmap = hints->icon_pixmap; if (hints->flags & IconMaskHint) - window->wm_hints_mask = hints->icon_mask; + priv->wm_hints_mask = hints->icon_mask; if (hints->flags & XUrgencyHint) - window->wm_hints_urgent = TRUE; + urgent = TRUE; meta_verbose ("Read WM_HINTS input: %d iconic: %d group leader: 0x%lx pixmap: 0x%lx mask: 0x%lx\n", window->input, window->initially_iconic, window->xgroup_leader, - window->wm_hints_pixmap, - window->wm_hints_mask); + priv->wm_hints_pixmap, + priv->wm_hints_mask); } if (window->xgroup_leader != old_group_leader) @@ -1689,113 +1707,29 @@ reload_wm_hints (MetaWindow *window, meta_window_group_leader_changed (window); } - /* - * Do not emit urgency notification on the inital property load - */ - if (!initial && (window->wm_hints_urgent != old_urgent)) - g_object_notify (G_OBJECT (window), "urgent"); + meta_window_set_urgent (window, urgent); - /* - * Do not emit signal for the initial property load, let the constructor to - * take care of it once the MetaWindow is fully constructed. - * - * Only emit if the property is both changed and set. - */ - if (!initial && window->wm_hints_urgent && !old_urgent) - g_signal_emit_by_name (window->display, "window-marked-urgent", window); - - meta_icon_cache_property_changed (&window->icon_cache, - window->display, + meta_icon_cache_property_changed (&priv->icon_cache, + window->display->x11_display, XA_WM_HINTS); - meta_window_queue (window, META_QUEUE_MOVE_RESIZE); + meta_window_queue (window, META_QUEUE_UPDATE_ICON | META_QUEUE_MOVE_RESIZE); } -static void -reload_gtk_hide_titlebar_when_maximized (MetaWindow *window, - MetaPropValue *value, - gboolean initial) +static gboolean +check_xtransient_for_loop (MetaWindow *window, + MetaWindow *parent) { - gboolean requested_value = FALSE; - gboolean current_value = window->hide_titlebar_when_maximized; - - if (meta_prefs_get_ignore_hide_titlebar_when_maximized ()) - { - return; - } - - if (value->type != META_PROP_VALUE_INVALID) - { - requested_value = ((int) value->v.cardinal == 1); - meta_verbose ("Request to hide titlebar for window %s.\n", window->desc); - } - - if (requested_value == current_value) - return; - - window->hide_titlebar_when_maximized = requested_value; - - if (META_WINDOW_MAXIMIZED (window)) + while (parent) { - meta_window_queue (window, META_QUEUE_MOVE_RESIZE); - - if (window->frame) - meta_ui_update_frame_style (window->screen->ui, window->frame->xwindow); - } -} - -typedef struct -{ - MetaWindow *window; - Window transient_for_xid; -} FindByLeaderData; - -static void -find_window_by_client_leader (MetaScreen *screen, - MetaWindow *window, - gpointer user_data) -{ - FindByLeaderData *data = (FindByLeaderData *) user_data; - - if (data->window != NULL) - { - return; - } - - if (window->xclient_leader == None) - { - return; - } - - if (window->xclient_leader == data->transient_for_xid) - { - data->window = window; - } -} - -static MetaWindow * -lookup_parent_by_client_leader (MetaWindow *transient, - Window xtransient_for) -{ - MetaWindow *parent; - FindByLeaderData *data; - - data = g_new0 (FindByLeaderData, 1); - - data->transient_for_xid = xtransient_for; + if (parent == window) + return TRUE; - meta_screen_foreach_window (transient->screen, - (MetaScreenWindowFunc) find_window_by_client_leader, - data); - - if (data != NULL) - { - parent = data->window; + parent = meta_x11_display_lookup_x_window (parent->display->x11_display, + parent->xtransient_for); } - free (data); - - return parent; + return FALSE; } static void @@ -1804,54 +1738,59 @@ reload_transient_for (MetaWindow *window, gboolean initial) { MetaWindow *parent = NULL; - Window transient_for, old_transient_for; + Window transient_for; if (value->type != META_PROP_VALUE_INVALID) { transient_for = value->v.xwindow; - parent = meta_display_lookup_x_window (window->display, transient_for); - + parent = meta_x11_display_lookup_x_window (window->display->x11_display, + transient_for); if (!parent) { - /* QT programs appear to set the transient-for hint to the program's WM_CLIENT_LEADER - * instead of the toplevel window's xid. This causes muffin to throw out their transient - * state. Since we know the client leader id of existing windows, we can do a quick search - * and match up to the correct parent so our stacking and fullscreen detection code works - * properly */ - - parent = lookup_parent_by_client_leader (window, transient_for); + meta_warning ("Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n", + transient_for, window->desc); + transient_for = None; + } + else if (parent->override_redirect) + { + const gchar *window_kind = window->override_redirect ? + "override-redirect" : "top-level"; - if (parent) + if (parent->xtransient_for != None) { - transient_for = parent->xwindow; - - meta_verbose ("WM_TRANSIENT_FOR was parent window 0x%lx's WM_CLIENT_LEADER. " - "using the xid instead for %s.\n", transient_for, window->desc); + /* We don't have to go through the parents, as per this code it is + * not possible that a window has the WM_TRANSIENT_FOR set to an + * override-redirect window anyways */ + meta_warning ("WM_TRANSIENT_FOR window %s for %s window %s is an " + "override-redirect window and this is not correct " + "according to the standard, so we'll fallback to " + "the first non-override-redirect window 0x%lx.\n", + parent->desc, window->desc, window_kind, + parent->xtransient_for); + transient_for = parent->xtransient_for; + parent = + meta_x11_display_lookup_x_window (parent->display->x11_display, + transient_for); } else { - meta_warning ("Invalid WM_TRANSIENT_FOR window 0x%lx specified " - "for %s.\n", - transient_for, window->desc); - transient_for = None; + meta_warning ("WM_TRANSIENT_FOR window %s for %s window %s is an " + "override-redirect window and this is not correct " + "according to the standard, so we'll fallback to " + "the root window.\n", parent->desc, window_kind, + window->desc); + transient_for = parent->display->x11_display->xroot; + parent = NULL; } } /* Make sure there is not a loop */ - while (parent) + if (check_xtransient_for_loop (window, parent)) { - if (parent == window) - { - meta_warning ("WM_TRANSIENT_FOR window 0x%lx for %s " - "would create loop.\n", - transient_for, window->desc); - transient_for = None; - break; - } - - parent = meta_display_lookup_x_window (parent->display, - parent->xtransient_for); + meta_warning ("WM_TRANSIENT_FOR window 0x%lx for %s would create a " + "loop.\n", transient_for, window->desc); + transient_for = None; } } else @@ -1860,61 +1799,20 @@ reload_transient_for (MetaWindow *window, if (transient_for == window->xtransient_for) return; - if (meta_window_appears_focused (window) && window->xtransient_for != None) - meta_window_propagate_focus_appearance (window, FALSE); - - old_transient_for = window->xtransient_for; window->xtransient_for = transient_for; - window->transient_parent_is_root_window = - window->xtransient_for == window->screen->xroot; - if (window->xtransient_for != None) - meta_verbose ("Window %s transient for 0x%lx (root = %d)\n", window->desc, - window->xtransient_for, window->transient_parent_is_root_window); + meta_verbose ("Window %s transient for 0x%lx\n", window->desc, window->xtransient_for); else meta_verbose ("Window %s is not transient\n", window->desc); - /* may now be a dialog */ - meta_window_recalc_window_type (window); - - if (!window->constructing) + if (window->xtransient_for == None || + window->xtransient_for == window->display->x11_display->xroot) + meta_window_set_transient_for (window, NULL); + else { - /* If the window attaches, detaches, or changes attached - * parents, we need to destroy the MetaWindow and let a new one - * be created (which happens as a side effect of - * meta_window_unmanage()). The condition below is correct - * because we know window->xtransient_for has changed. - */ - if (window->attached || meta_window_should_attach_to_parent (window)) - { - guint32 timestamp; - - window->xtransient_for = old_transient_for; - timestamp = meta_display_get_current_time_roundtrip (window->display); - meta_window_unmanage (window, timestamp); - return; - } + meta_window_set_transient_for (window, parent); } - - /* update stacking constraints */ - if (!window->override_redirect) - meta_stack_update_transient (window->screen->stack, window); - - /* possibly change its group. We treat being a window's transient as - * equivalent to making it your group leader, to work around shortcomings - * in programs such as xmms-- see #328211. - */ - if (window->xtransient_for != None && - window->xgroup_leader != None && - window->xtransient_for != window->xgroup_leader) - meta_window_group_leader_changed (window); - - if (!window->constructing && !window->override_redirect) - meta_window_queue (window, META_QUEUE_MOVE_RESIZE); - - if (meta_window_appears_focused (window) && window->xtransient_for != None) - meta_window_propagate_focus_appearance (window, TRUE); } static void @@ -1934,12 +1832,12 @@ reload_gtk_theme_variant (MetaWindow *window, if (g_strcmp0 (requested_variant, current_variant) != 0) { - free (current_variant); + g_free (current_variant); window->gtk_theme_variant = g_strdup (requested_variant); if (window->frame) - meta_ui_update_frame_style (window->screen->ui, window->frame->xwindow); + meta_frame_update_style (window->frame); } } @@ -1952,9 +1850,7 @@ reload_bypass_compositor (MetaWindow *window, int current_value = window->bypass_compositor; if (value->type != META_PROP_VALUE_INVALID) - { requested_value = (int) value->v.cardinal; - } if (requested_value == current_value) return; @@ -1969,13 +1865,27 @@ reload_bypass_compositor (MetaWindow *window, window->bypass_compositor = requested_value; } +static void +reload_window_opacity (MetaWindow *window, + MetaPropValue *value, + gboolean initial) + +{ + guint8 opacity = 0xFF; + + if (value->type != META_PROP_VALUE_INVALID) + opacity = (guint8)((gfloat)value->v.cardinal * 255.0 / ((gfloat)0xffffffff)); + + meta_window_set_opacity (window, opacity); +} + #define RELOAD_STRING(var_name, propname) \ static void \ reload_ ## var_name (MetaWindow *window, \ MetaPropValue *value, \ gboolean initial) \ { \ - free (window->var_name); \ + g_free (window->var_name); \ \ if (value->type != META_PROP_VALUE_INVALID) \ window->var_name = g_strdup (value->v.str); \ @@ -1994,7 +1904,10 @@ RELOAD_STRING (gtk_menubar_object_path, "gtk-menubar-object-path") #undef RELOAD_STRING -/* +/** + * meta_x11_display_init_window_prop_hooks: + * @x11_display: The #MetaDX11isplay + * * Initialises the property hooks system. Each row in the table named "hooks" * represents an action to take when a property is found on a newly-created * window, or when a property changes its value. @@ -2008,13 +1921,10 @@ RELOAD_STRING (gtk_menubar_object_path, "gtk-menubar-object-path") * was META_PROP_VALUE_INVALID, the callback still gets called anyway.) * This value may be NULL, in which case no callback will be called. */ -LOCAL_SYMBOL void -meta_display_init_window_prop_hooks (MetaDisplay *display) +void +meta_x11_display_init_window_prop_hooks (MetaX11Display *x11_display) { - /* INIT: load initially - * O-R: fetch for override-redirect windows - * - * The ordering here is significant for the properties we load + /* The ordering here is significant for the properties we load * initially: they are roughly ordered in the order we want them to * be gotten. We want to get window name and class first so we can * use them in error messages and such. However, name is modified @@ -2027,92 +1937,89 @@ meta_display_init_window_prop_hooks (MetaDisplay *display) * - NET_WM_WINDOW_TYPE: can be used to do appropriate handling * for different types of override-redirect windows. */ - MetaWindowPropHooks hooks[] = { /* INIT O-R */ - { display->atom_WM_CLIENT_MACHINE, META_PROP_VALUE_STRING, reload_wm_client_machine, TRUE, TRUE }, - { display->atom__NET_WM_NAME, META_PROP_VALUE_UTF8, reload_net_wm_name, TRUE, TRUE }, - { XA_WM_CLASS, META_PROP_VALUE_CLASS_HINT, reload_wm_class, TRUE, TRUE }, - { display->atom__NET_WM_PID, META_PROP_VALUE_CARDINAL, reload_net_wm_pid, TRUE, TRUE }, - { XA_WM_NAME, META_PROP_VALUE_TEXT_PROPERTY, reload_wm_name, TRUE, TRUE }, - { display->atom__MUFFIN_HINTS, META_PROP_VALUE_TEXT_PROPERTY, reload_muffin_hints, TRUE, TRUE }, - { display->atom__NET_WM_OPAQUE_REGION, META_PROP_VALUE_CARDINAL_LIST, reload_opaque_region, TRUE, TRUE }, - { display->atom__NET_WM_ICON_NAME, META_PROP_VALUE_UTF8, reload_net_wm_icon_name, TRUE, FALSE }, - { XA_WM_ICON_NAME, META_PROP_VALUE_TEXT_PROPERTY, reload_wm_icon_name, TRUE, FALSE }, - { display->atom__NET_WM_DESKTOP, META_PROP_VALUE_CARDINAL, reload_net_wm_desktop, TRUE, FALSE }, - { display->atom__NET_STARTUP_ID, META_PROP_VALUE_UTF8, reload_net_startup_id, TRUE, FALSE }, - { display->atom__NET_WM_SYNC_REQUEST_COUNTER, META_PROP_VALUE_SYNC_COUNTER_LIST, reload_update_counter, TRUE, TRUE }, - { XA_WM_NORMAL_HINTS, META_PROP_VALUE_SIZE_HINTS, reload_normal_hints, TRUE, FALSE }, - { display->atom_WM_PROTOCOLS, META_PROP_VALUE_ATOM_LIST, reload_wm_protocols, TRUE, FALSE }, - { XA_WM_HINTS, META_PROP_VALUE_WM_HINTS, reload_wm_hints, TRUE, FALSE }, - { display->atom__NET_WM_USER_TIME, META_PROP_VALUE_CARDINAL, reload_net_wm_user_time, TRUE, FALSE }, - { display->atom__NET_WM_STATE, META_PROP_VALUE_ATOM_LIST, reload_net_wm_state, TRUE, FALSE }, - { display->atom__MOTIF_WM_HINTS, META_PROP_VALUE_MOTIF_HINTS, reload_mwm_hints, TRUE, FALSE }, - { XA_WM_TRANSIENT_FOR, META_PROP_VALUE_WINDOW, reload_transient_for, TRUE, FALSE }, - { display->atom__GTK_THEME_VARIANT, META_PROP_VALUE_UTF8, reload_gtk_theme_variant, TRUE, FALSE }, - { display->atom__GTK_HIDE_TITLEBAR_WHEN_MAXIMIZED, META_PROP_VALUE_CARDINAL, reload_gtk_hide_titlebar_when_maximized, TRUE, FALSE }, - { display->atom__GTK_APPLICATION_ID, META_PROP_VALUE_UTF8, reload_gtk_application_id, TRUE, FALSE }, - { display->atom__GTK_UNIQUE_BUS_NAME, META_PROP_VALUE_UTF8, reload_gtk_unique_bus_name, TRUE, FALSE }, - { display->atom__GTK_APPLICATION_OBJECT_PATH, META_PROP_VALUE_UTF8, reload_gtk_application_object_path, TRUE, FALSE }, - { display->atom__GTK_WINDOW_OBJECT_PATH, META_PROP_VALUE_UTF8, reload_gtk_window_object_path, TRUE, FALSE }, - { display->atom__GTK_APP_MENU_OBJECT_PATH, META_PROP_VALUE_UTF8, reload_gtk_app_menu_object_path, TRUE, FALSE }, - { display->atom__GTK_MENUBAR_OBJECT_PATH, META_PROP_VALUE_UTF8, reload_gtk_menubar_object_path, TRUE, FALSE }, - { display->atom__GTK_FRAME_EXTENTS, META_PROP_VALUE_CARDINAL_LIST,reload_gtk_frame_extents, TRUE, FALSE }, - { display->atom__NET_WM_USER_TIME_WINDOW, META_PROP_VALUE_WINDOW, reload_net_wm_user_time_window, TRUE, FALSE }, - { display->atom_WM_STATE, META_PROP_VALUE_INVALID, NULL, FALSE, FALSE }, - { display->atom__NET_WM_ICON, META_PROP_VALUE_INVALID, reload_net_wm_icon, FALSE, FALSE }, - { display->atom__KWM_WIN_ICON, META_PROP_VALUE_INVALID, reload_kwm_win_icon, FALSE, FALSE }, - { display->atom__NET_WM_ICON_GEOMETRY, META_PROP_VALUE_CARDINAL_LIST, reload_icon_geometry, FALSE, FALSE }, - { display->atom_WM_CLIENT_LEADER, META_PROP_VALUE_INVALID, complain_about_broken_client, FALSE, FALSE }, - { display->atom_SM_CLIENT_ID, META_PROP_VALUE_INVALID, complain_about_broken_client, FALSE, FALSE }, - { display->atom_WM_WINDOW_ROLE, META_PROP_VALUE_INVALID, reload_wm_window_role, FALSE, FALSE }, - { display->atom__NET_WM_WINDOW_TYPE, META_PROP_VALUE_INVALID, reload_net_wm_window_type, FALSE, TRUE }, - { display->atom__NET_WM_STRUT, META_PROP_VALUE_INVALID, reload_struts, FALSE, FALSE }, - { display->atom__NET_WM_STRUT_PARTIAL, META_PROP_VALUE_INVALID, reload_struts, FALSE, FALSE }, - { display->atom__NET_WM_BYPASS_COMPOSITOR, META_PROP_VALUE_CARDINAL, reload_bypass_compositor, TRUE, TRUE }, - { display->atom__NET_WM_XAPP_ICON_NAME, META_PROP_VALUE_UTF8, reload_theme_icon_name, TRUE, TRUE }, - { display->atom__NET_WM_XAPP_PROGRESS, META_PROP_VALUE_CARDINAL, reload_progress, TRUE, TRUE }, - { display->atom__NET_WM_XAPP_PROGRESS_PULSE, META_PROP_VALUE_CARDINAL, reload_progress_pulse, TRUE, TRUE }, + MetaWindowPropHooks hooks[] = { + { x11_display->atom_WM_CLIENT_MACHINE, META_PROP_VALUE_STRING, reload_wm_client_machine, LOAD_INIT | INCLUDE_OR }, + { x11_display->atom__NET_WM_NAME, META_PROP_VALUE_UTF8, reload_net_wm_name, LOAD_INIT | INCLUDE_OR }, + { XA_WM_CLASS, META_PROP_VALUE_CLASS_HINT, reload_wm_class, LOAD_INIT | INCLUDE_OR }, + { x11_display->atom__NET_WM_PID, META_PROP_VALUE_CARDINAL, reload_net_wm_pid, LOAD_INIT | INCLUDE_OR }, + { XA_WM_NAME, META_PROP_VALUE_TEXT_PROPERTY, reload_wm_name, LOAD_INIT | INCLUDE_OR }, + { x11_display->atom__MUTTER_HINTS, META_PROP_VALUE_TEXT_PROPERTY, reload_mutter_hints, LOAD_INIT | INCLUDE_OR }, + { x11_display->atom__NET_WM_OPAQUE_REGION, META_PROP_VALUE_CARDINAL_LIST, reload_opaque_region, LOAD_INIT | INCLUDE_OR }, + { x11_display->atom__NET_WM_DESKTOP, META_PROP_VALUE_CARDINAL, reload_net_wm_desktop, LOAD_INIT | INIT_ONLY }, + { x11_display->atom__NET_STARTUP_ID, META_PROP_VALUE_UTF8, reload_net_startup_id, LOAD_INIT }, + { x11_display->atom__NET_WM_SYNC_REQUEST_COUNTER, META_PROP_VALUE_SYNC_COUNTER_LIST, reload_update_counter, LOAD_INIT | INCLUDE_OR }, + { XA_WM_NORMAL_HINTS, META_PROP_VALUE_SIZE_HINTS, reload_normal_hints, LOAD_INIT }, + { x11_display->atom_WM_PROTOCOLS, META_PROP_VALUE_ATOM_LIST, reload_wm_protocols, LOAD_INIT }, + { XA_WM_HINTS, META_PROP_VALUE_WM_HINTS, reload_wm_hints, LOAD_INIT }, + { x11_display->atom__NET_WM_USER_TIME, META_PROP_VALUE_CARDINAL, reload_net_wm_user_time, LOAD_INIT }, + { x11_display->atom__NET_WM_STATE, META_PROP_VALUE_ATOM_LIST, reload_net_wm_state, LOAD_INIT | INIT_ONLY }, + { x11_display->atom__MOTIF_WM_HINTS, META_PROP_VALUE_MOTIF_HINTS, reload_mwm_hints, LOAD_INIT }, + { XA_WM_TRANSIENT_FOR, META_PROP_VALUE_WINDOW, reload_transient_for, LOAD_INIT | INCLUDE_OR }, + { x11_display->atom__GTK_THEME_VARIANT, META_PROP_VALUE_UTF8, reload_gtk_theme_variant, LOAD_INIT }, + { x11_display->atom__GTK_APPLICATION_ID, META_PROP_VALUE_UTF8, reload_gtk_application_id, LOAD_INIT }, + { x11_display->atom__GTK_UNIQUE_BUS_NAME, META_PROP_VALUE_UTF8, reload_gtk_unique_bus_name, LOAD_INIT }, + { x11_display->atom__GTK_APPLICATION_OBJECT_PATH, META_PROP_VALUE_UTF8, reload_gtk_application_object_path, LOAD_INIT }, + { x11_display->atom__GTK_WINDOW_OBJECT_PATH, META_PROP_VALUE_UTF8, reload_gtk_window_object_path, LOAD_INIT }, + { x11_display->atom__GTK_APP_MENU_OBJECT_PATH, META_PROP_VALUE_UTF8, reload_gtk_app_menu_object_path, LOAD_INIT }, + { x11_display->atom__GTK_MENUBAR_OBJECT_PATH, META_PROP_VALUE_UTF8, reload_gtk_menubar_object_path, LOAD_INIT }, + { x11_display->atom__GTK_FRAME_EXTENTS, META_PROP_VALUE_CARDINAL_LIST,reload_gtk_frame_extents, LOAD_INIT }, + { x11_display->atom__NET_WM_USER_TIME_WINDOW, META_PROP_VALUE_WINDOW, reload_net_wm_user_time_window, LOAD_INIT }, + { x11_display->atom__NET_WM_ICON, META_PROP_VALUE_INVALID, reload_net_wm_icon, NONE }, + { x11_display->atom__KWM_WIN_ICON, META_PROP_VALUE_INVALID, reload_kwm_win_icon, NONE }, + { x11_display->atom__NET_WM_ICON_GEOMETRY, META_PROP_VALUE_CARDINAL_LIST, reload_icon_geometry, LOAD_INIT }, + { x11_display->atom_WM_CLIENT_LEADER, META_PROP_VALUE_INVALID, complain_about_broken_client, NONE }, + { x11_display->atom_SM_CLIENT_ID, META_PROP_VALUE_INVALID, complain_about_broken_client, NONE }, + { x11_display->atom_WM_WINDOW_ROLE, META_PROP_VALUE_STRING, reload_wm_window_role, LOAD_INIT | FORCE_INIT }, + { x11_display->atom__NET_WM_WINDOW_TYPE, META_PROP_VALUE_ATOM_LIST, reload_net_wm_window_type, LOAD_INIT | INCLUDE_OR | FORCE_INIT }, + { x11_display->atom__NET_WM_STRUT, META_PROP_VALUE_INVALID, reload_struts, NONE }, + { x11_display->atom__NET_WM_STRUT_PARTIAL, META_PROP_VALUE_INVALID, reload_struts, NONE }, + { x11_display->atom__NET_WM_BYPASS_COMPOSITOR, META_PROP_VALUE_CARDINAL, reload_bypass_compositor, LOAD_INIT | INCLUDE_OR }, + { x11_display->atom__NET_WM_WINDOW_OPACITY, META_PROP_VALUE_CARDINAL, reload_window_opacity, LOAD_INIT | INCLUDE_OR }, { 0 }, }; MetaWindowPropHooks *table = g_memdup (hooks, sizeof (hooks)), *cursor = table; - g_assert (display->prop_hooks == NULL); + g_assert (x11_display->prop_hooks == NULL); - display->prop_hooks_table = (gpointer) table; - display->prop_hooks = g_hash_table_new (NULL, NULL); + x11_display->prop_hooks_table = (gpointer) table; + x11_display->prop_hooks = g_hash_table_new (NULL, NULL); while (cursor->property) { /* Doing initial loading doesn't make sense if we just want notification */ - g_assert (!(hooks->load_initially && hooks->type == META_PROP_VALUE_INVALID)); + g_assert (!((cursor->flags & LOAD_INIT) && cursor->type == META_PROP_VALUE_INVALID)); + + /* Forcing initialization doesn't make sense if not loading initially */ + g_assert ((cursor->flags & LOAD_INIT) || !(cursor->flags & FORCE_INIT)); /* Atoms are safe to use with GINT_TO_POINTER because it's safe with * anything 32 bits or less, and atoms are 32 bits with the top three * bits clear. (Scheifler & Gettys, 2e, p372) */ - g_hash_table_insert (display->prop_hooks, + g_hash_table_insert (x11_display->prop_hooks, GINT_TO_POINTER (cursor->property), cursor); cursor++; } - display->n_prop_hooks = cursor - table; + x11_display->n_prop_hooks = cursor - table; } -LOCAL_SYMBOL void -meta_display_free_window_prop_hooks (MetaDisplay *display) +void +meta_x11_display_free_window_prop_hooks (MetaX11Display *x11_display) { - g_hash_table_unref (display->prop_hooks); - display->prop_hooks = NULL; + g_hash_table_unref (x11_display->prop_hooks); + x11_display->prop_hooks = NULL; - free (display->prop_hooks_table); - display->prop_hooks_table = NULL; + g_free (x11_display->prop_hooks_table); + x11_display->prop_hooks_table = NULL; } -static MetaWindowPropHooks* -find_hooks (MetaDisplay *display, - Atom property) +static MetaWindowPropHooks * +find_hooks (MetaX11Display *x11_display, + Atom property) { - return g_hash_table_lookup (display->prop_hooks, + return g_hash_table_lookup (x11_display->prop_hooks, GINT_TO_POINTER (property)); } diff --git a/src/x11/window-props.h b/src/x11/window-props.h new file mode 100644 index 000000000..4f37e0c0f --- /dev/null +++ b/src/x11/window-props.h @@ -0,0 +1,95 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/** + * SECTION:window-props + * @short_description: MetaWindow property handling + * + * A system which can inspect sets of properties of given windows + * and take appropriate action given their values. + * + * Note that all the meta_window_reload_propert* functions require a + * round trip to the server. + */ + +/* + * Copyright (C) 2001, 2002 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef META_WINDOW_PROPS_H +#define META_WINDOW_PROPS_H + +#include "core/window-private.h" + +/** + * meta_window_reload_property_from_xwindow: + * @window: A window on the same display as the one we're + * investigating (only used to find the display) + * @xwindow: The X handle for the window. + * @property: A single X atom. + * + * Requests the current values of a single property for a given + * window from the server, and deals with it appropriately. + * Does not return it to the caller (it's been dealt with!) + */ +void meta_window_reload_property_from_xwindow (MetaWindow *window, + Window xwindow, + Atom property, + gboolean initial); + +/** + * meta_window_load_initial_properties: + * @window: The window. + * + * Requests the current values for standard properties for a given + * window from the server, and deals with them appropriately. + * Does not return them to the caller (they've been dealt with!) + */ +void meta_window_load_initial_properties (MetaWindow *window); + +/** + * meta_x11_display_init_window_prop_hooks: + * @x11_display: The X11 display. + * + * Initialises the hooks used for the reload_propert* functions + * on a particular display, and stores a pointer to them in the + * x11_display. + */ +void meta_x11_display_init_window_prop_hooks (MetaX11Display *x11_display); + +/** + * meta_x11_display_free_window_prop_hooks: + * @x11_display: The X11 display. + * Frees the hooks used for the reload_propert* functions + * for a particular display. + */ +void meta_x11_display_free_window_prop_hooks (MetaX11Display *x11_display); + +/** + * meta_set_normal_hints: + * @window: The window to set the size hints on. + * @hints: Either some X size hints, or NULL for default. + * + * Sets the size hints for a window. This happens when a + * WM_NORMAL_HINTS property is set on a window, but it is public + * because the size hints are set to defaults when a window is + * created. See + * http://tronche.com/gui/x/icccm/sec-4.html#WM_NORMAL_HINTS + * for the X details. + */ +void meta_set_normal_hints (MetaWindow *window, + XSizeHints *hints); + +#endif /* META_WINDOW_PROPS_H */ diff --git a/src/x11/window-x11-private.h b/src/x11/window-x11-private.h new file mode 100644 index 000000000..906d44546 --- /dev/null +++ b/src/x11/window-x11-private.h @@ -0,0 +1,86 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001 Havoc Pennington, Anders Carlsson + * Copyright (C) 2002, 2003 Red Hat, Inc. + * Copyright (C) 2003 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef META_WINDOW_X11_PRIVATE_H +#define META_WINDOW_X11_PRIVATE_H + +#include "core/window-private.h" +#include "x11/iconcache.h" + +G_BEGIN_DECLS + +typedef struct _MetaWindowX11Private MetaWindowX11Private; + +struct _MetaWindowX11Class +{ + MetaWindowClass parent_class; + + void (*freeze_commits) (MetaWindow *window); + void (*thaw_commits) (MetaWindow *window); + gboolean (*always_update_shape) (MetaWindow *window); +}; + +struct _MetaWindowX11 +{ + MetaWindow parent; + + MetaWindowX11Private *priv; +}; + +struct _MetaWindowX11Private +{ + /* TRUE if the client forced these on */ + guint wm_state_skip_taskbar : 1; + guint wm_state_skip_pager : 1; + guint wm_take_focus : 1; + guint wm_ping : 1; + guint wm_delete_window : 1; + + /* Weird "_NET_WM_STATE_MODAL" flag */ + guint wm_state_modal : 1; + + /* Info on which props we got our attributes from */ + guint using_net_wm_name : 1; /* vs. plain wm_name */ + guint using_net_wm_visible_name : 1; /* tracked so we can clear it */ + + Atom type_atom; + + /* Requested geometry */ + int border_width; + + gboolean showing_resize_popup; + + /* These are in server coordinates. If we have a frame, it's + * relative to the frame. */ + MetaRectangle client_rect; + + MetaIconCache icon_cache; + Pixmap wm_hints_pixmap; + Pixmap wm_hints_mask; + + /* Freeze/thaw on resize (for Xwayland) */ + gboolean thaw_after_paint; +}; + +G_END_DECLS + +#endif diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c new file mode 100644 index 000000000..11a588d81 --- /dev/null +++ b/src/x11/window-x11.c @@ -0,0 +1,4121 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001 Havoc Pennington, Anders Carlsson + * Copyright (C) 2002, 2003 Red Hat, Inc. + * Copyright (C) 2003 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include "x11/window-x11.h" +#include "x11/window-x11-private.h" + +#include <string.h> +#include <X11/Xatom.h> +#include <X11/Xlibint.h> +#include <X11/Xlib-xcb.h> +#include <X11/extensions/shape.h> +#include <X11/extensions/Xcomposite.h> +#include <xcb/res.h> + +#include "backends/meta-logical-monitor.h" +#include "backends/x11/meta-backend-x11.h" +#include "core/boxes-private.h" +#include "core/frame.h" +#include "core/meta-workspace-manager-private.h" +#include "core/window-private.h" +#include "core/workspace-private.h" +#include "meta/common.h" +#include "meta/meta-cursor-tracker.h" +#include "meta/meta-x11-errors.h" +#include "meta/prefs.h" +#include "x11/meta-x11-display-private.h" +#include "x11/session.h" +#include "x11/window-props.h" +#include "x11/xprops.h" + +#define TAKE_FOCUS_FALLBACK_DELAY_MS 150 + +enum _MetaGtkEdgeConstraints +{ + META_GTK_EDGE_CONSTRAINT_TOP_TILED = 1 << 0, + META_GTK_EDGE_CONSTRAINT_TOP_RESIZABLE = 1 << 1, + META_GTK_EDGE_CONSTRAINT_RIGHT_TILED = 1 << 2, + META_GTK_EDGE_CONSTRAINT_RIGHT_RESIZABLE = 1 << 3, + META_GTK_EDGE_CONSTRAINT_BOTTOM_TILED = 1 << 4, + META_GTK_EDGE_CONSTRAINT_BOTTOM_RESIZABLE = 1 << 5, + META_GTK_EDGE_CONSTRAINT_LEFT_TILED = 1 << 6, + META_GTK_EDGE_CONSTRAINT_LEFT_RESIZABLE = 1 << 7 +} MetaGtkEdgeConstraints; + +G_DEFINE_TYPE_WITH_PRIVATE (MetaWindowX11, meta_window_x11, META_TYPE_WINDOW) + +static void +meta_window_x11_maybe_focus_delayed (MetaWindow *window, + GQueue *other_focus_candidates, + guint32 timestamp); + +static void +meta_window_x11_init (MetaWindowX11 *window_x11) +{ + window_x11->priv = meta_window_x11_get_instance_private (window_x11); +} + +static void +send_icccm_message (MetaWindow *window, + Atom atom, + guint32 timestamp) +{ + /* This comment and code are from twm, copyright + * Open Group, Evans & Sutherland, etc. + */ + + /* + * ICCCM Client Messages - Section 4.2.8 of the ICCCM dictates that all + * client messages will have the following form: + * + * event type ClientMessage + * message type _XA_WM_PROTOCOLS + * window tmp->w + * format 32 + * data[0] message atom + * data[1] time stamp + */ + + XClientMessageEvent ev; + MetaX11Display *x11_display = window->display->x11_display; + + ev.type = ClientMessage; + ev.window = window->xwindow; + ev.message_type = x11_display->atom_WM_PROTOCOLS; + ev.format = 32; + ev.data.l[0] = atom; + ev.data.l[1] = timestamp; + + meta_x11_error_trap_push (x11_display); + XSendEvent (x11_display->xdisplay, + window->xwindow, False, 0, (XEvent*) &ev); + meta_x11_error_trap_pop (x11_display); +} + +static Window +read_client_leader (MetaDisplay *display, + Window xwindow) +{ + Window retval = None; + + meta_prop_get_window (display->x11_display, xwindow, + display->x11_display->atom_WM_CLIENT_LEADER, + &retval); + + return retval; +} + +typedef struct +{ + Window leader; +} ClientLeaderData; + +static gboolean +find_client_leader_func (MetaWindow *ancestor, + void *data) +{ + ClientLeaderData *d; + + d = data; + + d->leader = read_client_leader (ancestor->display, + ancestor->xwindow); + + /* keep going if no client leader found */ + return d->leader == None; +} + +static void +update_sm_hints (MetaWindow *window) +{ + Window leader; + + window->xclient_leader = None; + window->sm_client_id = NULL; + + /* If not on the current window, we can get the client + * leader from transient parents. If we find a client + * leader, we read the SM_CLIENT_ID from it. + */ + leader = read_client_leader (window->display, window->xwindow); + if (leader == None) + { + ClientLeaderData d; + d.leader = None; + meta_window_foreach_ancestor (window, find_client_leader_func, + &d); + leader = d.leader; + } + + if (leader != None) + { + window->xclient_leader = leader; + + meta_prop_get_latin1_string (window->display->x11_display, leader, + window->display->x11_display->atom_SM_CLIENT_ID, + &window->sm_client_id); + } + else + { + meta_verbose ("Didn't find a client leader for %s\n", window->desc); + + if (!meta_prefs_get_disable_workarounds ()) + { + /* Some broken apps (kdelibs fault?) set SM_CLIENT_ID on the app + * instead of the client leader + */ + meta_prop_get_latin1_string (window->display->x11_display, window->xwindow, + window->display->x11_display->atom_SM_CLIENT_ID, + &window->sm_client_id); + + if (window->sm_client_id) + meta_warning ("Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER window as specified in the ICCCM.\n", + window->desc); + } + } + + meta_verbose ("Window %s client leader: 0x%lx SM_CLIENT_ID: '%s'\n", + window->desc, window->xclient_leader, + window->sm_client_id ? window->sm_client_id : "none"); +} + +static void +send_configure_notify (MetaWindow *window) +{ + MetaX11Display *x11_display = window->display->x11_display; + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); + XEvent event; + + g_assert (!window->override_redirect); + + /* from twm */ + + event.type = ConfigureNotify; + event.xconfigure.display = x11_display->xdisplay; + event.xconfigure.event = window->xwindow; + event.xconfigure.window = window->xwindow; + event.xconfigure.x = priv->client_rect.x - priv->border_width; + event.xconfigure.y = priv->client_rect.y - priv->border_width; + if (window->frame) + { + if (window->withdrawn) + { + MetaFrameBorders borders; + /* We reparent the client window and put it to the position + * where the visible top-left of the frame window currently is. + */ + + meta_frame_calc_borders (window->frame, &borders); + + event.xconfigure.x = window->frame->rect.x + borders.invisible.left; + event.xconfigure.y = window->frame->rect.y + borders.invisible.top; + } + else + { + /* Need to be in root window coordinates */ + event.xconfigure.x += window->frame->rect.x; + event.xconfigure.y += window->frame->rect.y; + } + } + event.xconfigure.width = priv->client_rect.width; + event.xconfigure.height = priv->client_rect.height; + event.xconfigure.border_width = priv->border_width; /* requested not actual */ + event.xconfigure.above = None; /* FIXME */ + event.xconfigure.override_redirect = False; + + meta_topic (META_DEBUG_GEOMETRY, + "Sending synthetic configure notify to %s with x: %d y: %d w: %d h: %d\n", + window->desc, + event.xconfigure.x, event.xconfigure.y, + event.xconfigure.width, event.xconfigure.height); + + meta_x11_error_trap_push (x11_display); + XSendEvent (x11_display->xdisplay, + window->xwindow, + False, StructureNotifyMask, &event); + meta_x11_error_trap_pop (x11_display); +} + +static void +adjust_for_gravity (MetaWindow *window, + gboolean coords_assume_border, + MetaGravity gravity, + MetaRectangle *rect) +{ + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); + int ref_x, ref_y; + int bw; + int child_x, child_y; + int frame_width, frame_height; + MetaFrameBorders borders; + + /* We're computing position to pass to window_move, which is + * the position of the client window (META_GRAVITY_STATIC basically) + * + * (see WM spec description of gravity computation, but note that + * their formulas assume we're honoring the border width, rather + * than compensating for having turned it off) + */ + + if (gravity == META_GRAVITY_STATIC) + return; + + if (coords_assume_border) + bw = priv->border_width; + else + bw = 0; + + meta_frame_calc_borders (window->frame, &borders); + + child_x = borders.visible.left; + child_y = borders.visible.top; + frame_width = child_x + rect->width + borders.visible.right; + frame_height = child_y + rect->height + borders.visible.bottom; + + /* Calculate the the reference point, which is the corner of the + * outer window specified by the gravity. So, META_GRAVITY_NORTH_EAST + * would have the reference point as the top-right corner of the + * outer window. */ + ref_x = rect->x; + ref_y = rect->y; + + switch (gravity) + { + case META_GRAVITY_NORTH: + case META_GRAVITY_CENTER: + case META_GRAVITY_SOUTH: + ref_x += rect->width / 2 + bw; + break; + case META_GRAVITY_NORTH_EAST: + case META_GRAVITY_EAST: + case META_GRAVITY_SOUTH_EAST: + ref_x += rect->width + bw * 2; + break; + default: + break; + } + + switch (gravity) + { + case META_GRAVITY_WEST: + case META_GRAVITY_CENTER: + case META_GRAVITY_EAST: + ref_y += rect->height / 2 + bw; + break; + case META_GRAVITY_SOUTH_WEST: + case META_GRAVITY_SOUTH: + case META_GRAVITY_SOUTH_EAST: + ref_y += rect->height + bw * 2; + break; + default: + break; + } + + /* Find the top-left corner of the outer window from + * the reference point. */ + + rect->x = ref_x; + rect->y = ref_y; + + switch (gravity) + { + case META_GRAVITY_NORTH: + case META_GRAVITY_CENTER: + case META_GRAVITY_SOUTH: + rect->x -= frame_width / 2; + break; + case META_GRAVITY_NORTH_EAST: + case META_GRAVITY_EAST: + case META_GRAVITY_SOUTH_EAST: + rect->x -= frame_width; + break; + default: + break; + } + + switch (gravity) + { + case META_GRAVITY_WEST: + case META_GRAVITY_CENTER: + case META_GRAVITY_EAST: + rect->y -= frame_height / 2; + break; + case META_GRAVITY_SOUTH_WEST: + case META_GRAVITY_SOUTH: + case META_GRAVITY_SOUTH_EAST: + rect->y -= frame_height; + break; + default: + break; + } + + /* Adjust to get the top-left corner of the inner window. */ + rect->x += child_x; + rect->y += child_y; +} + +static void +meta_window_apply_session_info (MetaWindow *window, + const MetaWindowSessionInfo *info) +{ + if (info->stack_position_set) + { + meta_topic (META_DEBUG_SM, + "Restoring stack position %d for window %s\n", + info->stack_position, window->desc); + + /* FIXME well, I'm not sure how to do this. */ + } + + if (info->minimized_set) + { + meta_topic (META_DEBUG_SM, + "Restoring minimized state %d for window %s\n", + info->minimized, window->desc); + + if (info->minimized) + meta_window_minimize (window); + } + + if (info->maximized_set) + { + meta_topic (META_DEBUG_SM, + "Restoring maximized state %d for window %s\n", + info->maximized, window->desc); + + if (window->has_maximize_func && info->maximized) + { + meta_window_maximize (window, META_MAXIMIZE_BOTH); + + if (info->saved_rect_set) + { + meta_topic (META_DEBUG_SM, + "Restoring saved rect %d,%d %dx%d for window %s\n", + info->saved_rect.x, + info->saved_rect.y, + info->saved_rect.width, + info->saved_rect.height, + window->desc); + + window->saved_rect.x = info->saved_rect.x; + window->saved_rect.y = info->saved_rect.y; + window->saved_rect.width = info->saved_rect.width; + window->saved_rect.height = info->saved_rect.height; + } + } + } + + if (info->on_all_workspaces_set) + { + window->on_all_workspaces_requested = info->on_all_workspaces; + meta_window_on_all_workspaces_changed (window); + meta_topic (META_DEBUG_SM, + "Restoring sticky state %d for window %s\n", + window->on_all_workspaces_requested, window->desc); + } + + if (info->workspace_indices) + { + GSList *tmp; + GSList *spaces; + + spaces = NULL; + + tmp = info->workspace_indices; + while (tmp != NULL) + { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; + MetaWorkspace *space; + + space = + meta_workspace_manager_get_workspace_by_index (workspace_manager, + GPOINTER_TO_INT (tmp->data)); + + if (space) + spaces = g_slist_prepend (spaces, space); + + tmp = tmp->next; + } + + if (spaces) + { + /* XXX: What should we do if there's more than one workspace + * listed? We only support one workspace for each window. + * + * For now, just choose the first one. + */ + MetaWorkspace *workspace = spaces->data; + + meta_window_change_workspace (window, workspace); + window->initial_workspace_set = TRUE; + + meta_topic (META_DEBUG_SM, + "Restoring saved window %s to workspace %d\n", + window->desc, + meta_workspace_index (workspace)); + + g_slist_free (spaces); + } + } + + if (info->geometry_set) + { + MetaRectangle rect; + MetaMoveResizeFlags flags; + MetaGravity gravity; + + window->placed = TRUE; /* don't do placement algorithms later */ + + rect.x = info->rect.x; + rect.y = info->rect.y; + + rect.width = window->size_hints.base_width + info->rect.width * window->size_hints.width_inc; + rect.height = window->size_hints.base_height + info->rect.height * window->size_hints.height_inc; + + /* Force old gravity, ignoring anything now set */ + window->size_hints.win_gravity = info->gravity; + gravity = window->size_hints.win_gravity; + + flags = META_MOVE_RESIZE_MOVE_ACTION | META_MOVE_RESIZE_RESIZE_ACTION; + + adjust_for_gravity (window, FALSE, gravity, &rect); + meta_window_client_rect_to_frame_rect (window, &rect, &rect); + meta_window_move_resize_internal (window, flags, gravity, rect); + } +} + +static void +meta_window_x11_manage (MetaWindow *window) +{ + MetaDisplay *display = window->display; + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); + + meta_icon_cache_init (&priv->icon_cache); + + meta_x11_display_register_x_window (display->x11_display, + &window->xwindow, + window); + + /* assign the window to its group, or create a new group if needed */ + window->group = NULL; + window->xgroup_leader = None; + meta_window_compute_group (window); + + meta_window_load_initial_properties (window); + + if (!window->override_redirect) + update_sm_hints (window); /* must come after transient_for */ + + if (window->decorated) + meta_window_ensure_frame (window); + + /* Now try applying saved stuff from the session */ + { + const MetaWindowSessionInfo *info; + + info = meta_window_lookup_saved_state (window); + + if (info) + { + meta_window_apply_session_info (window, info); + meta_window_release_saved_state (info); + } + } + + /* For override-redirect windows, save the client rect + * directly. window->rect was assigned from the XWindowAttributes + * in the main meta_window_shared_new. + * + * For normal windows, do a full ConfigureRequest based on the + * window hints, as that's what the ICCCM says to do. + */ + priv->client_rect = window->rect; + window->buffer_rect = window->rect; + + if (!window->override_redirect) + { + MetaRectangle rect; + MetaMoveResizeFlags flags; + MetaGravity gravity = window->size_hints.win_gravity; + + rect.x = window->size_hints.x; + rect.y = window->size_hints.y; + rect.width = window->size_hints.width; + rect.height = window->size_hints.height; + + flags = META_MOVE_RESIZE_CONFIGURE_REQUEST | META_MOVE_RESIZE_MOVE_ACTION | META_MOVE_RESIZE_RESIZE_ACTION; + + adjust_for_gravity (window, TRUE, gravity, &rect); + meta_window_client_rect_to_frame_rect (window, &rect, &rect); + meta_window_move_resize_internal (window, flags, gravity, rect); + } + + meta_window_x11_update_shape_region (window); + meta_window_x11_update_input_region (window); +} + +static void +meta_window_x11_unmanage (MetaWindow *window) +{ + MetaX11Display *x11_display = window->display->x11_display; + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); + + meta_x11_error_trap_push (x11_display); + + meta_window_x11_destroy_sync_request_alarm (window); + + if (window->withdrawn) + { + /* We need to clean off the window's state so it + * won't be restored if the app maps it again. + */ + meta_verbose ("Cleaning state from window %s\n", window->desc); + XDeleteProperty (x11_display->xdisplay, + window->xwindow, + x11_display->atom__NET_WM_DESKTOP); + XDeleteProperty (x11_display->xdisplay, + window->xwindow, + x11_display->atom__NET_WM_STATE); + XDeleteProperty (x11_display->xdisplay, + window->xwindow, + x11_display->atom__NET_WM_FULLSCREEN_MONITORS); + meta_window_x11_set_wm_state (window); + } + else + { + /* We need to put WM_STATE so that others will understand it on + * restart. + */ + if (!window->minimized) + meta_window_x11_set_wm_state (window); + + /* If we're unmanaging a window that is not withdrawn, then + * either (a) mutter is exiting, in which case we need to map + * the window so the next WM will know that it's not Withdrawn, + * or (b) we want to create a new MetaWindow to replace the + * current one, which will happen automatically if we re-map + * the X Window. + */ + XMapWindow (x11_display->xdisplay, + window->xwindow); + } + + meta_x11_display_unregister_x_window (x11_display, window->xwindow); + + /* Put back anything we messed up */ + if (priv->border_width != 0) + XSetWindowBorderWidth (x11_display->xdisplay, + window->xwindow, + priv->border_width); + + /* No save set */ + XRemoveFromSaveSet (x11_display->xdisplay, + window->xwindow); + + /* Even though the window is now unmanaged, we can't unselect events. This + * window might be a window from this process, like a GdkMenu, in + * which case it will have pointer events and so forth selected + * for it by GDK. There's no way to disentangle those events from the events + * we've selected. Even for a window from a different X client, + * GDK could also have selected events for it for IPC purposes, so we + * can't unselect in that case either. + * + * Similarly, we can't unselected for events on window->user_time_window. + * It might be our own GDK focus window, or it might be a window that a + * different client is using for multiple different things: + * _NET_WM_USER_TIME_WINDOW and IPC, perhaps. + */ + + if (window->user_time_window != None) + { + meta_x11_display_unregister_x_window (x11_display, + window->user_time_window); + window->user_time_window = None; + } + + if (META_X11_DISPLAY_HAS_SHAPE (x11_display)) + XShapeSelectInput (x11_display->xdisplay, window->xwindow, NoEventMask); + + meta_window_ungrab_keys (window); + meta_display_ungrab_window_buttons (window->display, window->xwindow); + meta_display_ungrab_focus_window_button (window->display, window); + + meta_x11_error_trap_pop (x11_display); + + if (window->frame) + { + /* The XReparentWindow call in meta_window_destroy_frame() moves the + * window so we need to send a configure notify; see bug 399552. (We + * also do this just in case a window got unmaximized.) + */ + send_configure_notify (window); + + meta_window_destroy_frame (window); + } +} + +void +meta_window_x11_set_wm_ping (MetaWindow *window, + gboolean ping) +{ + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = + meta_window_x11_get_instance_private (window_x11); + + priv->wm_ping = ping; +} + +static gboolean +meta_window_x11_can_ping (MetaWindow *window) +{ + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = + meta_window_x11_get_instance_private (window_x11); + + return priv->wm_ping; +} + +static void +meta_window_x11_ping (MetaWindow *window, + guint32 serial) +{ + MetaDisplay *display = window->display; + + send_icccm_message (window, display->x11_display->atom__NET_WM_PING, serial); +} + +void +meta_window_x11_set_wm_delete_window (MetaWindow *window, + gboolean delete_window) +{ + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = + meta_window_x11_get_instance_private (window_x11); + + priv->wm_delete_window = delete_window; +} + +static void +meta_window_x11_delete (MetaWindow *window, + guint32 timestamp) +{ + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = + meta_window_x11_get_instance_private (window_x11); + MetaX11Display *x11_display = window->display->x11_display; + + meta_x11_error_trap_push (x11_display); + if (priv->wm_delete_window) + { + meta_topic (META_DEBUG_WINDOW_OPS, + "Deleting %s with delete_window request\n", + window->desc); + send_icccm_message (window, x11_display->atom_WM_DELETE_WINDOW, timestamp); + } + else + { + meta_topic (META_DEBUG_WINDOW_OPS, + "Deleting %s with explicit kill\n", + window->desc); + XKillClient (x11_display->xdisplay, window->xwindow); + } + meta_x11_error_trap_pop (x11_display); +} + +static void +meta_window_x11_kill (MetaWindow *window) +{ + MetaX11Display *x11_display = window->display->x11_display; + + meta_topic (META_DEBUG_WINDOW_OPS, + "Disconnecting %s with XKillClient()\n", + window->desc); + + meta_x11_error_trap_push (x11_display); + XKillClient (x11_display->xdisplay, window->xwindow); + meta_x11_error_trap_pop (x11_display); +} + +static void +request_take_focus (MetaWindow *window, + guint32 timestamp) +{ + MetaDisplay *display = window->display; + + meta_topic (META_DEBUG_FOCUS, "WM_TAKE_FOCUS(%s, %u)\n", + window->desc, timestamp); + + send_icccm_message (window, display->x11_display->atom_WM_TAKE_FOCUS, timestamp); +} + +typedef struct +{ + MetaWindow *window; + GQueue *pending_focus_candidates; + guint32 timestamp; + guint timeout_id; + gulong unmanaged_id; + gulong focused_changed_id; +} MetaWindowX11DelayedFocusData; + +static void +disconnect_pending_focus_window_signals (MetaWindow *window, + GQueue *focus_candidates) +{ + g_signal_handlers_disconnect_by_func (window, g_queue_remove, + focus_candidates); +} + +static void +meta_window_x11_delayed_focus_data_free (MetaWindowX11DelayedFocusData *data) +{ + g_clear_signal_handler (&data->unmanaged_id, data->window); + g_clear_signal_handler (&data->focused_changed_id, data->window->display); + + if (data->pending_focus_candidates) + { + g_queue_foreach (data->pending_focus_candidates, + (GFunc) disconnect_pending_focus_window_signals, + data->pending_focus_candidates); + g_queue_free (data->pending_focus_candidates); + } + + g_clear_handle_id (&data->timeout_id, g_source_remove); + g_free (data); +} + +static void +focus_candidates_maybe_take_and_focus_next (GQueue **focus_candidates_ptr, + guint32 timestamp) +{ + MetaWindow *focus_window; + GQueue *focus_candidates; + + g_assert (*focus_candidates_ptr); + + if (g_queue_is_empty (*focus_candidates_ptr)) + return; + + focus_candidates = g_steal_pointer (focus_candidates_ptr); + focus_window = g_queue_pop_head (focus_candidates); + + disconnect_pending_focus_window_signals (focus_window, focus_candidates); + meta_window_x11_maybe_focus_delayed (focus_window, focus_candidates, timestamp); +} + +static gboolean +focus_window_delayed_timeout (gpointer user_data) +{ + MetaWindowX11DelayedFocusData *data = user_data; + MetaWindow *window = data->window; + guint32 timestamp = data->timestamp; + + focus_candidates_maybe_take_and_focus_next (&data->pending_focus_candidates, + timestamp); + + data->timeout_id = 0; + meta_window_x11_delayed_focus_data_free (data); + + meta_window_focus (window, timestamp); + + return G_SOURCE_REMOVE; +} + +static void +meta_window_x11_maybe_focus_delayed (MetaWindow *window, + GQueue *other_focus_candidates, + guint32 timestamp) +{ + MetaWindowX11DelayedFocusData *data; + + data = g_new0 (MetaWindowX11DelayedFocusData, 1); + data->window = window; + data->timestamp = timestamp; + data->pending_focus_candidates = other_focus_candidates; + + meta_topic (META_DEBUG_FOCUS, + "Requesting delayed focus to %s\n", window->desc); + + data->unmanaged_id = + g_signal_connect_swapped (window, "unmanaged", + G_CALLBACK (meta_window_x11_delayed_focus_data_free), + data); + + data->focused_changed_id = + g_signal_connect_swapped (window->display, "notify::focus-window", + G_CALLBACK (meta_window_x11_delayed_focus_data_free), + data); + + data->timeout_id = g_timeout_add (TAKE_FOCUS_FALLBACK_DELAY_MS, + focus_window_delayed_timeout, data); +} + +static void +maybe_focus_default_window (MetaDisplay *display, + MetaWindow *not_this_one, + guint32 timestamp) +{ + MetaWorkspace *workspace; + MetaStack *stack = display->stack; + g_autoptr (GList) focusable_windows = NULL; + g_autoptr (GQueue) focus_candidates = NULL; + GList *l; + + if (not_this_one && not_this_one->workspace) + workspace = not_this_one->workspace; + else + workspace = display->workspace_manager->active_workspace; + + /* Go through all the focusable windows and try to focus them + * in order, waiting for a delay. The first one that replies to + * the request (in case of take focus windows) changing the display + * focused window, will stop the chained requests. + */ + focusable_windows = + meta_stack_get_default_focus_candidates (stack, workspace); + focus_candidates = g_queue_new (); + + for (l = g_list_last (focusable_windows); l; l = l->prev) + { + MetaWindow *focus_window = l->data; + + if (focus_window == not_this_one) + continue; + + g_queue_push_tail (focus_candidates, focus_window); + g_signal_connect_swapped (focus_window, "unmanaged", + G_CALLBACK (g_queue_remove), + focus_candidates); + + if (!META_IS_WINDOW_X11 (focus_window)) + break; + + if (focus_window->input) + break; + + if (focus_window->shaded && focus_window->frame) + break; + } + + focus_candidates_maybe_take_and_focus_next (&focus_candidates, timestamp); +} + +static void +meta_window_x11_focus (MetaWindow *window, + guint32 timestamp) +{ + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = + meta_window_x11_get_instance_private (window_x11); + /* For output-only or shaded windows, focus the frame. + * This seems to result in the client window getting key events + * though, so I don't know if it's icccm-compliant. + * + * Still, we have to do this or keynav breaks for these windows. + */ + if (window->frame && + (window->shaded || !meta_window_is_focusable (window))) + { + meta_topic (META_DEBUG_FOCUS, + "Focusing frame of %s\n", window->desc); + meta_display_set_input_focus (window->display, + window, + TRUE, + timestamp); + } + else + { + if (window->input) + { + meta_topic (META_DEBUG_FOCUS, + "Setting input focus on %s since input = true\n", + window->desc); + meta_display_set_input_focus (window->display, + window, + FALSE, + timestamp); + } + + if (priv->wm_take_focus) + { + meta_topic (META_DEBUG_FOCUS, + "Sending WM_TAKE_FOCUS to %s since take_focus = true\n", + window->desc); + + if (!window->input) + { + /* The "Globally Active Input" window case, where the window + * doesn't want us to call XSetInputFocus on it, but does + * want us to send a WM_TAKE_FOCUS. + * + * Normally, we want to just leave the focus undisturbed until + * the window responds to WM_TAKE_FOCUS, but if we're unmanaging + * the current focus window we *need* to move the focus away, so + * we focus the no focus window before sending WM_TAKE_FOCUS, + * and eventually the default focus window excluding this one, + * if meanwhile we don't get any focus request. + */ + if (window->display->focus_window != NULL && + window->display->focus_window->unmanaging) + { + meta_display_unset_input_focus (window->display, timestamp); + maybe_focus_default_window (window->display, window, + timestamp); + } + } + + request_take_focus (window, timestamp); + } + } +} + +static void +meta_window_get_client_root_coords (MetaWindow *window, + MetaRectangle *rect) +{ + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); + + *rect = priv->client_rect; + + if (window->frame) + { + rect->x += window->frame->rect.x; + rect->y += window->frame->rect.y; + } +} + +static void +meta_window_refresh_resize_popup (MetaWindow *window) +{ + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); + + if (priv->showing_resize_popup) + { + MetaRectangle rect; + int display_w, display_h; + + meta_window_get_client_root_coords (window, &rect); + + display_w = (rect.width - window->size_hints.base_width); + if (window->size_hints.width_inc > 0) + display_w /= window->size_hints.width_inc; + + display_h = (rect.height - window->size_hints.base_height); + if (window->size_hints.height_inc > 0) + display_h /= window->size_hints.height_inc; + + meta_display_show_resize_popup (window->display, TRUE, &rect, display_w, display_h); + } + else + { + meta_display_show_resize_popup (window->display, FALSE, NULL, 0, 0); + } +} + +static void +meta_window_x11_grab_op_began (MetaWindow *window, + MetaGrabOp op) +{ + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); + + if (meta_grab_op_is_resizing (op)) + { + if (window->sync_request_counter != None) + meta_window_x11_create_sync_request_alarm (window); + + if (window->size_hints.width_inc > 2 || window->size_hints.height_inc > 2) + { + priv->showing_resize_popup = TRUE; + meta_window_refresh_resize_popup (window); + } + } + + META_WINDOW_CLASS (meta_window_x11_parent_class)->grab_op_began (window, op); +} + +static void +meta_window_x11_grab_op_ended (MetaWindow *window, + MetaGrabOp op) +{ + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); + + if (priv->showing_resize_popup) + { + priv->showing_resize_popup = FALSE; + meta_window_refresh_resize_popup (window); + } + + META_WINDOW_CLASS (meta_window_x11_parent_class)->grab_op_ended (window, op); +} + +static void +update_net_frame_extents (MetaWindow *window) +{ + MetaX11Display *x11_display = window->display->x11_display; + + unsigned long data[4]; + MetaFrameBorders borders; + + meta_frame_calc_borders (window->frame, &borders); + /* Left */ + data[0] = borders.visible.left; + /* Right */ + data[1] = borders.visible.right; + /* Top */ + data[2] = borders.visible.top; + /* Bottom */ + data[3] = borders.visible.bottom; + + meta_topic (META_DEBUG_GEOMETRY, + "Setting _NET_FRAME_EXTENTS on managed window 0x%lx " + "to left = %lu, right = %lu, top = %lu, bottom = %lu\n", + window->xwindow, data[0], data[1], data[2], data[3]); + + meta_x11_error_trap_push (x11_display); + XChangeProperty (x11_display->xdisplay, window->xwindow, + x11_display->atom__NET_FRAME_EXTENTS, + XA_CARDINAL, + 32, PropModeReplace, (guchar*) data, 4); + meta_x11_error_trap_pop (x11_display); +} + +static gboolean +is_edge_constraint_resizable (MetaEdgeConstraint constraint) +{ + switch (constraint) + { + case META_EDGE_CONSTRAINT_NONE: + case META_EDGE_CONSTRAINT_WINDOW: + return TRUE; + case META_EDGE_CONSTRAINT_MONITOR: + return FALSE; + } + + g_assert_not_reached (); + return FALSE; +} + +static gboolean +is_edge_constraint_tiled (MetaEdgeConstraint constraint) +{ + switch (constraint) + { + case META_EDGE_CONSTRAINT_NONE: + return FALSE; + case META_EDGE_CONSTRAINT_WINDOW: + case META_EDGE_CONSTRAINT_MONITOR: + return TRUE; + } + + g_assert_not_reached (); + return FALSE; +} + +static unsigned long +edge_constraints_to_gtk_edge_constraints (MetaWindow *window) +{ + unsigned long gtk_edge_constraints = 0; + + if (is_edge_constraint_tiled (window->edge_constraints.top)) + gtk_edge_constraints |= META_GTK_EDGE_CONSTRAINT_TOP_TILED; + if (is_edge_constraint_resizable (window->edge_constraints.top)) + gtk_edge_constraints |= META_GTK_EDGE_CONSTRAINT_TOP_RESIZABLE; + + if (is_edge_constraint_tiled (window->edge_constraints.right)) + gtk_edge_constraints |= META_GTK_EDGE_CONSTRAINT_RIGHT_TILED; + if (is_edge_constraint_resizable (window->edge_constraints.right)) + gtk_edge_constraints |= META_GTK_EDGE_CONSTRAINT_RIGHT_RESIZABLE; + + if (is_edge_constraint_tiled (window->edge_constraints.bottom)) + gtk_edge_constraints |= META_GTK_EDGE_CONSTRAINT_BOTTOM_TILED; + if (is_edge_constraint_resizable (window->edge_constraints.bottom)) + gtk_edge_constraints |= META_GTK_EDGE_CONSTRAINT_BOTTOM_RESIZABLE; + + if (is_edge_constraint_tiled (window->edge_constraints.left)) + gtk_edge_constraints |= META_GTK_EDGE_CONSTRAINT_LEFT_TILED; + if (is_edge_constraint_resizable (window->edge_constraints.left)) + gtk_edge_constraints |= META_GTK_EDGE_CONSTRAINT_LEFT_RESIZABLE; + + return gtk_edge_constraints; +} + +static void +update_gtk_edge_constraints (MetaWindow *window) +{ + MetaX11Display *x11_display = window->display->x11_display; + unsigned long data[1]; + + data[0] = edge_constraints_to_gtk_edge_constraints (window); + + meta_verbose ("Setting _GTK_EDGE_CONSTRAINTS to %lu\n", data[0]); + + meta_x11_error_trap_push (x11_display); + XChangeProperty (x11_display->xdisplay, + window->xwindow, + x11_display->atom__GTK_EDGE_CONSTRAINTS, + XA_CARDINAL, 32, PropModeReplace, + (guchar*) data, 1); + meta_x11_error_trap_pop (x11_display); +} + +static gboolean +sync_request_timeout (gpointer data) +{ + MetaWindow *window = data; + + window->sync_request_timeout_id = 0; + + /* We have now waited for more than a second for the + * application to respond to the sync request + */ + window->disable_sync = TRUE; + + /* Reset the wait serial, so we don't continue freezing + * window updates + */ + window->sync_request_wait_serial = 0; + meta_compositor_sync_updates_frozen (window->display->compositor, window); + + if (window == window->display->grab_window && + meta_grab_op_is_resizing (window->display->grab_op)) + { + meta_window_update_resize (window, + window->display->grab_last_user_action_was_snap, + window->display->grab_latest_motion_x, + window->display->grab_latest_motion_y, + TRUE); + } + + return FALSE; +} + +static void +send_sync_request (MetaWindow *window) +{ + MetaX11Display *x11_display = window->display->x11_display; + XClientMessageEvent ev; + gint64 wait_serial; + + /* For the old style of _NET_WM_SYNC_REQUEST_COUNTER, we just have to + * increase the value, but for the new "extended" style we need to + * pick an even (unfrozen) value sufficiently ahead of the last serial + * that we received from the client; the same code still works + * for the old style. The increment of 240 is specified by the EWMH + * and is (1 second) * (60fps) * (an increment of 4 per frame). + */ + wait_serial = window->sync_request_serial + 240; + + window->sync_request_wait_serial = wait_serial; + + ev.type = ClientMessage; + ev.window = window->xwindow; + ev.message_type = x11_display->atom_WM_PROTOCOLS; + ev.format = 32; + ev.data.l[0] = x11_display->atom__NET_WM_SYNC_REQUEST; + /* FIXME: meta_display_get_current_time() is bad, but since calls + * come from meta_window_move_resize_internal (which in turn come + * from all over), I'm not sure what we can do to fix it. Do we + * want to use _roundtrip, though? + */ + ev.data.l[1] = meta_display_get_current_time (window->display); + ev.data.l[2] = wait_serial & G_GUINT64_CONSTANT(0xffffffff); + ev.data.l[3] = wait_serial >> 32; + ev.data.l[4] = window->extended_sync_request_counter ? 1 : 0; + + /* We don't need to trap errors here as we are already + * inside an error_trap_push()/pop() pair. + */ + XSendEvent (x11_display->xdisplay, + window->xwindow, False, 0, (XEvent*) &ev); + + /* We give the window 1 sec to respond to _NET_WM_SYNC_REQUEST; + * if this time expires, we consider the window unresponsive + * and resize it unsynchonized. + */ + window->sync_request_timeout_id = g_timeout_add (1000, + sync_request_timeout, + window); + g_source_set_name_by_id (window->sync_request_timeout_id, + "[mutter] sync_request_timeout"); + + meta_compositor_sync_updates_frozen (window->display->compositor, window); +} + +static unsigned long +meta_window_get_net_wm_desktop (MetaWindow *window) +{ + if (window->on_all_workspaces) + return 0xFFFFFFFF; + else + return meta_workspace_index (window->workspace); +} + +static void +meta_window_x11_current_workspace_changed (MetaWindow *window) +{ + MetaX11Display *x11_display = window->display->x11_display; + /* FIXME if on more than one workspace, we claim to be "sticky", + * the WM spec doesn't say what to do here. + */ + unsigned long data[1]; + + if (window->workspace == NULL) + { + /* this happens when unmanaging windows */ + return; + } + + data[0] = meta_window_get_net_wm_desktop (window); + + meta_verbose ("Setting _NET_WM_DESKTOP of %s to %lu\n", + window->desc, data[0]); + + meta_x11_error_trap_push (x11_display); + XChangeProperty (x11_display->xdisplay, window->xwindow, + x11_display->atom__NET_WM_DESKTOP, + XA_CARDINAL, + 32, PropModeReplace, (guchar*) data, 1); + meta_x11_error_trap_pop (x11_display); +} + +static void +meta_window_x11_move_resize_internal (MetaWindow *window, + MetaGravity gravity, + MetaRectangle unconstrained_rect, + MetaRectangle constrained_rect, + MetaRectangle intermediate_rect, + int rel_x, + int rel_y, + MetaMoveResizeFlags flags, + MetaMoveResizeResultFlags *result) +{ + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); + MetaFrameBorders borders; + MetaRectangle client_rect; + int size_dx, size_dy; + XWindowChanges values; + unsigned int mask; + gboolean need_configure_notify; + gboolean need_move_client = FALSE; + gboolean need_move_frame = FALSE; + gboolean need_resize_client = FALSE; + gboolean need_resize_frame = FALSE; + gboolean frame_shape_changed = FALSE; + gboolean configure_frame_first; + + gboolean is_configure_request; + + is_configure_request = (flags & META_MOVE_RESIZE_CONFIGURE_REQUEST) != 0; + + meta_frame_calc_borders (window->frame, &borders); + + size_dx = constrained_rect.x - window->rect.width; + size_dy = constrained_rect.y - window->rect.height; + + window->rect = constrained_rect; + + if (window->frame) + { + int new_w, new_h; + int new_x, new_y; + + /* Compute new frame size */ + new_w = window->rect.width + borders.invisible.left + borders.invisible.right; + + if (window->shaded) + new_h = borders.total.top + borders.total.bottom; + else + new_h = window->rect.height + borders.invisible.top + borders.invisible.bottom; + + if (new_w != window->frame->rect.width || + new_h != window->frame->rect.height) + { + need_resize_frame = TRUE; + window->frame->rect.width = new_w; + window->frame->rect.height = new_h; + } + + /* Compute new frame coords */ + new_x = window->rect.x - borders.invisible.left; + new_y = window->rect.y - borders.invisible.top; + + if (new_x != window->frame->rect.x || + new_y != window->frame->rect.y) + { + need_move_frame = TRUE; + window->frame->rect.x = new_x; + window->frame->rect.y = new_y; + } + } + + /* Calculate the new client rect */ + meta_window_frame_rect_to_client_rect (window, &constrained_rect, &client_rect); + + /* The above client_rect is in root window coordinates. The + * values we need to pass to XConfigureWindow are in parent + * coordinates, so if the window is in a frame, we need to + * correct the x/y positions here. */ + if (window->frame) + { + client_rect.x = borders.total.left; + client_rect.y = borders.total.top; + } + + if (client_rect.x != priv->client_rect.x || + client_rect.y != priv->client_rect.y) + { + need_move_client = TRUE; + priv->client_rect.x = client_rect.x; + priv->client_rect.y = client_rect.y; + } + + if (client_rect.width != priv->client_rect.width || + client_rect.height != priv->client_rect.height) + { + need_resize_client = TRUE; + priv->client_rect.width = client_rect.width; + priv->client_rect.height = client_rect.height; + } + + /* If frame extents have changed, fill in other frame fields and + change frame's extents property. */ + if (window->frame && + (window->frame->child_x != borders.total.left || + window->frame->child_y != borders.total.top || + window->frame->right_width != borders.total.right || + window->frame->bottom_height != borders.total.bottom)) + { + window->frame->child_x = borders.total.left; + window->frame->child_y = borders.total.top; + window->frame->right_width = borders.total.right; + window->frame->bottom_height = borders.total.bottom; + + update_net_frame_extents (window); + } + + /* See ICCCM 4.1.5 for when to send ConfigureNotify */ + + need_configure_notify = FALSE; + + /* If this is a configure request and we change nothing, then we + * must send configure notify. + */ + if (is_configure_request && + !(need_move_client || need_move_frame || + need_resize_client || need_resize_frame || + priv->border_width != 0)) + need_configure_notify = TRUE; + + /* We must send configure notify if we move but don't resize, since + * the client window may not get a real event + */ + if ((need_move_client || need_move_frame) && + !(need_resize_client || need_resize_frame)) + need_configure_notify = TRUE; + + /* MapRequest events with a PPosition or UPosition hint with a frame + * are moved by mutter without resizing; send a configure notify + * in such cases. See #322840. (Note that window->constructing is + * only true iff this call is due to a MapRequest, and when + * PPosition/UPosition hints aren't set, mutter seems to send a + * ConfigureNotify anyway due to the above code.) + */ + if (window->constructing && window->frame && + ((window->size_hints.flags & PPosition) || + (window->size_hints.flags & USPosition))) + need_configure_notify = TRUE; + + /* If resizing, freeze commits - This is for Xwayland, and a no-op on Xorg */ + if (need_resize_client || need_resize_frame) + { + if (!meta_window_x11_should_thaw_after_paint (window)) + { + meta_window_x11_set_thaw_after_paint (window, TRUE); + meta_window_x11_freeze_commits (window); + } + } + + /* The rest of this function syncs our new size/pos with X as + * efficiently as possible + */ + + /* For nice effect, when growing the window we want to move/resize + * the frame first, when shrinking the window we want to move/resize + * the client first. If we grow one way and shrink the other, + * see which way we're moving "more" + * + * Mail from Owen subject "Suggestion: Gravity and resizing from the left" + * http://mail.gnome.org/archives/wm-spec-list/1999-November/msg00088.html + * + * An annoying fact you need to know in this code is that META_GRAVITY_STATIC + * does nothing if you _only_ resize or _only_ move the frame; + * it must move _and_ resize, otherwise you get META_GRAVITY_NORTH_WEST + * behavior. The move and resize must actually occur, it is not + * enough to set CWX | CWWidth but pass in the current size/pos. + */ + + /* Normally, we configure the frame first depending on whether + * we grow the frame more than we shrink. The idea is to avoid + * messing up the window contents by having a temporary situation + * where the frame is smaller than the window. However, if we're + * cooperating with the client to create an atomic frame upate, + * and the window is redirected, then we should always update + * the frame first, since updating the frame will force a new + * backing pixmap to be allocated, and the old backing pixmap + * will be left undisturbed for us to paint to the screen until + * the client finishes redrawing. + */ + if (window->extended_sync_request_counter) + configure_frame_first = TRUE; + else + configure_frame_first = size_dx + size_dy >= 0; + + if (configure_frame_first && window->frame) + frame_shape_changed = meta_frame_sync_to_window (window->frame, need_resize_frame); + + values.border_width = 0; + values.x = client_rect.x; + values.y = client_rect.y; + values.width = client_rect.width; + values.height = client_rect.height; + + mask = 0; + if (is_configure_request && priv->border_width != 0) + mask |= CWBorderWidth; /* must force to 0 */ + if (need_move_client) + mask |= (CWX | CWY); + if (need_resize_client) + mask |= (CWWidth | CWHeight); + + if (mask != 0) + { + meta_x11_error_trap_push (window->display->x11_display); + + if (window == window->display->grab_window && + meta_grab_op_is_resizing (window->display->grab_op) && + !window->disable_sync && + window->sync_request_counter != None && + window->sync_request_alarm != None && + window->sync_request_timeout_id == 0) + { + send_sync_request (window); + } + + XConfigureWindow (window->display->x11_display->xdisplay, + window->xwindow, + mask, + &values); + + meta_x11_error_trap_pop (window->display->x11_display); + } + + if (!configure_frame_first && window->frame) + frame_shape_changed = meta_frame_sync_to_window (window->frame, need_resize_frame); + + if (window->frame) + window->buffer_rect = window->frame->rect; + else + window->buffer_rect = client_rect; + + if (need_configure_notify) + send_configure_notify (window); + + if (priv->showing_resize_popup) + meta_window_refresh_resize_popup (window); + + if (frame_shape_changed) + *result |= META_MOVE_RESIZE_RESULT_FRAME_SHAPE_CHANGED; + if (need_move_client || need_move_frame) + *result |= META_MOVE_RESIZE_RESULT_MOVED; + if (need_resize_client || need_resize_frame) + *result |= META_MOVE_RESIZE_RESULT_RESIZED; + if (flags & META_MOVE_RESIZE_STATE_CHANGED) + *result |= META_MOVE_RESIZE_RESULT_STATE_CHANGED; + + update_gtk_edge_constraints (window); +} + +static gboolean +meta_window_x11_update_struts (MetaWindow *window) +{ + GSList *old_struts; + GSList *new_struts; + GSList *old_iter, *new_iter; + uint32_t *struts = NULL; + int nitems; + gboolean changed; + + g_return_val_if_fail (!window->override_redirect, FALSE); + + meta_verbose ("Updating struts for %s\n", window->desc); + + old_struts = window->struts; + new_struts = NULL; + + if (meta_prop_get_cardinal_list (window->display->x11_display, + window->xwindow, + window->display->x11_display->atom__NET_WM_STRUT_PARTIAL, + &struts, &nitems)) + { + if (nitems != 12) + meta_verbose ("_NET_WM_STRUT_PARTIAL on %s has %d values instead " + "of 12\n", + window->desc, nitems); + else + { + /* Pull out the strut info for each side in the hint */ + int i; + for (i=0; i<4; i++) + { + MetaStrut *temp; + int thickness, strut_begin, strut_end; + + thickness = struts[i]; + if (thickness == 0) + continue; + strut_begin = struts[4+(i*2)]; + strut_end = struts[4+(i*2)+1]; + + temp = g_new0 (MetaStrut, 1); + temp->side = 1 << i; /* See MetaSide def. Matches nicely, eh? */ + meta_display_get_size (window->display, + &temp->rect.width, &temp->rect.height); + switch (temp->side) + { + case META_SIDE_RIGHT: + temp->rect.x = BOX_RIGHT(temp->rect) - thickness; + G_GNUC_FALLTHROUGH; + case META_SIDE_LEFT: + temp->rect.width = thickness; + temp->rect.y = strut_begin; + temp->rect.height = strut_end - strut_begin + 1; + break; + case META_SIDE_BOTTOM: + temp->rect.y = BOX_BOTTOM(temp->rect) - thickness; + G_GNUC_FALLTHROUGH; + case META_SIDE_TOP: + temp->rect.height = thickness; + temp->rect.x = strut_begin; + temp->rect.width = strut_end - strut_begin + 1; + break; + default: + g_assert_not_reached (); + } + + new_struts = g_slist_prepend (new_struts, temp); + } + + meta_verbose ("_NET_WM_STRUT_PARTIAL struts %u %u %u %u for " + "window %s\n", + struts[0], struts[1], struts[2], struts[3], + window->desc); + } + g_free (struts); + } + else + { + meta_verbose ("No _NET_WM_STRUT property for %s\n", + window->desc); + } + + if (!new_struts && + meta_prop_get_cardinal_list (window->display->x11_display, + window->xwindow, + window->display->x11_display->atom__NET_WM_STRUT, + &struts, &nitems)) + { + if (nitems != 4) + meta_verbose ("_NET_WM_STRUT on %s has %d values instead of 4\n", + window->desc, nitems); + else + { + /* Pull out the strut info for each side in the hint */ + int i; + for (i=0; i<4; i++) + { + MetaStrut *temp; + int thickness; + + thickness = struts[i]; + if (thickness == 0) + continue; + + temp = g_new0 (MetaStrut, 1); + temp->side = 1 << i; + meta_display_get_size (window->display, + &temp->rect.width, &temp->rect.height); + switch (temp->side) + { + case META_SIDE_RIGHT: + temp->rect.x = BOX_RIGHT(temp->rect) - thickness; + G_GNUC_FALLTHROUGH; + case META_SIDE_LEFT: + temp->rect.width = thickness; + break; + case META_SIDE_BOTTOM: + temp->rect.y = BOX_BOTTOM(temp->rect) - thickness; + G_GNUC_FALLTHROUGH; + case META_SIDE_TOP: + temp->rect.height = thickness; + break; + default: + g_assert_not_reached (); + } + + new_struts = g_slist_prepend (new_struts, temp); + } + + meta_verbose ("_NET_WM_STRUT struts %u %u %u %u for window %s\n", + struts[0], struts[1], struts[2], struts[3], + window->desc); + } + g_free (struts); + } + else if (!new_struts) + { + meta_verbose ("No _NET_WM_STRUT property for %s\n", + window->desc); + } + + /* Determine whether old_struts and new_struts are the same */ + old_iter = old_struts; + new_iter = new_struts; + while (old_iter && new_iter) + { + MetaStrut *old_strut = (MetaStrut*) old_iter->data; + MetaStrut *new_strut = (MetaStrut*) new_iter->data; + + if (old_strut->side != new_strut->side || + !meta_rectangle_equal (&old_strut->rect, &new_strut->rect)) + break; + + old_iter = old_iter->next; + new_iter = new_iter->next; + } + changed = (old_iter != NULL || new_iter != NULL); + + /* Update appropriately */ + g_slist_free_full (old_struts, g_free); + window->struts = new_struts; + return changed; +} + +static void +meta_window_x11_get_default_skip_hints (MetaWindow *window, + gboolean *skip_taskbar_out, + gboolean *skip_pager_out) +{ + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); + + *skip_taskbar_out = priv->wm_state_skip_taskbar; + *skip_pager_out = priv->wm_state_skip_pager; +} + +static gboolean +meta_window_x11_update_icon (MetaWindow *window, + cairo_surface_t **icon, + cairo_surface_t **mini_icon) +{ + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); + + return meta_read_icons (window->display->x11_display, + window->xwindow, + &priv->icon_cache, + priv->wm_hints_pixmap, + priv->wm_hints_mask, + icon, + META_ICON_WIDTH, META_ICON_HEIGHT, + mini_icon, + META_MINI_ICON_WIDTH, META_MINI_ICON_HEIGHT); +} + +static void +meta_window_x11_update_main_monitor (MetaWindow *window, + MetaWindowUpdateMonitorFlags flags) +{ + window->monitor = meta_window_calculate_main_logical_monitor (window); +} + +static void +meta_window_x11_main_monitor_changed (MetaWindow *window, + const MetaLogicalMonitor *old) +{ +} + +static uint32_t +meta_window_x11_get_client_pid (MetaWindow *window) +{ + MetaX11Display *x11_display = window->display->x11_display; + xcb_connection_t *xcb = XGetXCBConnection (x11_display->xdisplay); + xcb_res_client_id_spec_t spec = { 0 }; + xcb_res_query_client_ids_cookie_t cookie; + xcb_res_query_client_ids_reply_t *reply = NULL; + + spec.client = window->xwindow; + spec.mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID; + + cookie = xcb_res_query_client_ids (xcb, 1, &spec); + reply = xcb_res_query_client_ids_reply (xcb, cookie, NULL); + + if (reply == NULL) + return 0; + + uint32_t pid = 0, *value; + xcb_res_client_id_value_iterator_t it; + for (it = xcb_res_query_client_ids_ids_iterator (reply); + it.rem; + xcb_res_client_id_value_next (&it)) + { + spec = it.data->spec; + if (spec.mask & XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID) + { + value = xcb_res_client_id_value_value (it.data); + pid = *value; + break; + } + } + + free (reply); + return pid; +} + +static void +meta_window_x11_force_restore_shortcuts (MetaWindow *window, + ClutterInputDevice *source) +{ + /* + * Not needed on X11 because clients can use a keyboard grab + * to bypass the compositor shortcuts. + */ +} + +static gboolean +meta_window_x11_shortcuts_inhibited (MetaWindow *window, + ClutterInputDevice *source) +{ + /* + * On X11, we don't use a shortcuts inhibitor, clients just grab + * the keyboard. + */ + return FALSE; +} + +void +meta_window_x11_set_wm_take_focus (MetaWindow *window, + gboolean take_focus) +{ + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = + meta_window_x11_get_instance_private (window_x11); + + priv->wm_take_focus = take_focus; +} + +static gboolean +meta_window_x11_is_focusable (MetaWindow *window) +{ + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = + meta_window_x11_get_instance_private (window_x11); + + return window->input || priv->wm_take_focus; +} + +static gboolean +meta_window_x11_is_stackable (MetaWindow *window) +{ + return !window->override_redirect; +} + +static gboolean +meta_window_x11_are_updates_frozen (MetaWindow *window) +{ + if (window->extended_sync_request_counter && + window->sync_request_serial % 2 == 1) + return TRUE; + + if (window->sync_request_serial < window->sync_request_wait_serial) + return TRUE; + + return FALSE; +} + +/* Get layer ignoring any transient or group relationships */ +static MetaStackLayer +get_standalone_layer (MetaWindow *window) +{ + MetaStackLayer layer; + + switch (window->type) + { + case META_WINDOW_DESKTOP: + layer = META_LAYER_DESKTOP; + break; + + case META_WINDOW_DOCK: + if (window->wm_state_below || + (window->monitor && window->monitor->in_fullscreen)) + layer = META_LAYER_BOTTOM; + else + layer = META_LAYER_DOCK; + break; + + case META_WINDOW_DROPDOWN_MENU: + case META_WINDOW_POPUP_MENU: + case META_WINDOW_TOOLTIP: + case META_WINDOW_NOTIFICATION: + case META_WINDOW_COMBO: + case META_WINDOW_OVERRIDE_OTHER: + layer = META_LAYER_OVERRIDE_REDIRECT; + break; + + default: + layer = meta_window_get_default_layer (window); + break; + } + + return layer; +} + +/* Note that this function can never use window->layer only + * get_standalone_layer, or we'd have issues. + */ +static MetaStackLayer +get_maximum_layer_in_group (MetaWindow *window) +{ + GSList *members; + MetaGroup *group; + GSList *tmp; + MetaStackLayer max; + MetaStackLayer layer; + + max = META_LAYER_DESKTOP; + + group = meta_window_get_group (window); + + if (group != NULL) + members = meta_group_list_windows (group); + else + members = NULL; + + tmp = members; + while (tmp != NULL) + { + MetaWindow *w = tmp->data; + + if (!w->override_redirect) + { + layer = get_standalone_layer (w); + if (layer > max) + max = layer; + } + + tmp = tmp->next; + } + + g_slist_free (members); + + return max; +} + +static MetaStackLayer +meta_window_x11_calculate_layer (MetaWindow *window) +{ + MetaStackLayer layer = get_standalone_layer (window); + + /* We can only do promotion-due-to-group for dialogs and other + * transients, or weird stuff happens like the desktop window and + * nautilus windows getting in the same layer, or all gnome-terminal + * windows getting in fullscreen layer if any terminal is + * fullscreen. + */ + if (layer != META_LAYER_DESKTOP && + meta_window_has_transient_type (window) && + window->transient_for == NULL) + { + /* We only do the group thing if the dialog is NOT transient for + * a particular window. Imagine a group with a normal window, a dock, + * and a dialog transient for the normal window; you don't want the dialog + * above the dock if it wouldn't normally be. + */ + + MetaStackLayer group_max; + + group_max = get_maximum_layer_in_group (window); + + if (group_max > layer) + { + meta_topic (META_DEBUG_STACK, + "Promoting window %s from layer %u to %u due to group membership\n", + window->desc, layer, group_max); + layer = group_max; + } + } + + meta_topic (META_DEBUG_STACK, "Window %s on layer %u type = %u has_focus = %d\n", + window->desc, layer, + window->type, window->has_focus); + return layer; +} + +static void +meta_window_x11_impl_freeze_commits (MetaWindow *window) +{ +} + +static void +meta_window_x11_impl_thaw_commits (MetaWindow *window) +{ +} + +static void +meta_window_x11_map (MetaWindow *window) +{ + MetaX11Display *x11_display = window->display->x11_display; + + meta_x11_error_trap_push (x11_display); + XMapWindow (x11_display->xdisplay, window->xwindow); + meta_x11_error_trap_pop (x11_display); +} + +static void +meta_window_x11_unmap (MetaWindow *window) +{ + MetaX11Display *x11_display = window->display->x11_display; + + meta_x11_error_trap_push (x11_display); + XUnmapWindow (x11_display->xdisplay, window->xwindow); + meta_x11_error_trap_pop (x11_display); + window->unmaps_pending ++; +} + +static gboolean +meta_window_x11_impl_always_update_shape (MetaWindow *window) +{ + return FALSE; +} + +static gboolean +meta_window_x11_is_focus_async (MetaWindow *window) +{ + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = + meta_window_x11_get_instance_private (window_x11); + + return !window->input && priv->wm_take_focus; +} + +static void +meta_window_x11_class_init (MetaWindowX11Class *klass) +{ + MetaWindowClass *window_class = META_WINDOW_CLASS (klass); + + window_class->manage = meta_window_x11_manage; + window_class->unmanage = meta_window_x11_unmanage; + window_class->ping = meta_window_x11_ping; + window_class->delete = meta_window_x11_delete; + window_class->kill = meta_window_x11_kill; + window_class->focus = meta_window_x11_focus; + window_class->grab_op_began = meta_window_x11_grab_op_began; + window_class->grab_op_ended = meta_window_x11_grab_op_ended; + window_class->current_workspace_changed = meta_window_x11_current_workspace_changed; + window_class->move_resize_internal = meta_window_x11_move_resize_internal; + window_class->update_struts = meta_window_x11_update_struts; + window_class->get_default_skip_hints = meta_window_x11_get_default_skip_hints; + window_class->update_icon = meta_window_x11_update_icon; + window_class->update_main_monitor = meta_window_x11_update_main_monitor; + window_class->main_monitor_changed = meta_window_x11_main_monitor_changed; + window_class->get_client_pid = meta_window_x11_get_client_pid; + window_class->force_restore_shortcuts = meta_window_x11_force_restore_shortcuts; + window_class->shortcuts_inhibited = meta_window_x11_shortcuts_inhibited; + window_class->is_focusable = meta_window_x11_is_focusable; + window_class->is_stackable = meta_window_x11_is_stackable; + window_class->can_ping = meta_window_x11_can_ping; + window_class->are_updates_frozen = meta_window_x11_are_updates_frozen; + window_class->calculate_layer = meta_window_x11_calculate_layer; + window_class->map = meta_window_x11_map; + window_class->unmap = meta_window_x11_unmap; + window_class->is_focus_async = meta_window_x11_is_focus_async; + + klass->freeze_commits = meta_window_x11_impl_freeze_commits; + klass->thaw_commits = meta_window_x11_impl_thaw_commits; + klass->always_update_shape = meta_window_x11_impl_always_update_shape; +} + +void +meta_window_x11_set_net_wm_state (MetaWindow *window) +{ + MetaX11Display *x11_display = window->display->x11_display; + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); + int i; + unsigned long data[13]; + + i = 0; + if (window->shaded) + { + data[i] = x11_display->atom__NET_WM_STATE_SHADED; + ++i; + } + if (priv->wm_state_modal) + { + data[i] = x11_display->atom__NET_WM_STATE_MODAL; + ++i; + } + if (window->skip_pager) + { + data[i] = x11_display->atom__NET_WM_STATE_SKIP_PAGER; + ++i; + } + if (window->skip_taskbar) + { + data[i] = x11_display->atom__NET_WM_STATE_SKIP_TASKBAR; + ++i; + } + if (window->maximized_horizontally) + { + data[i] = x11_display->atom__NET_WM_STATE_MAXIMIZED_HORZ; + ++i; + } + if (window->maximized_vertically) + { + data[i] = x11_display->atom__NET_WM_STATE_MAXIMIZED_VERT; + ++i; + } + if (window->fullscreen) + { + data[i] = x11_display->atom__NET_WM_STATE_FULLSCREEN; + ++i; + } + if (!meta_window_showing_on_its_workspace (window) || window->shaded) + { + data[i] = x11_display->atom__NET_WM_STATE_HIDDEN; + ++i; + } + if (window->wm_state_above) + { + data[i] = x11_display->atom__NET_WM_STATE_ABOVE; + ++i; + } + if (window->wm_state_below) + { + data[i] = x11_display->atom__NET_WM_STATE_BELOW; + ++i; + } + if (window->wm_state_demands_attention) + { + data[i] = x11_display->atom__NET_WM_STATE_DEMANDS_ATTENTION; + ++i; + } + if (window->on_all_workspaces_requested) + { + data[i] = x11_display->atom__NET_WM_STATE_STICKY; + ++i; + } + if (meta_window_appears_focused (window)) + { + data[i] = x11_display->atom__NET_WM_STATE_FOCUSED; + ++i; + } + + meta_verbose ("Setting _NET_WM_STATE with %d atoms\n", i); + + meta_x11_error_trap_push (x11_display); + XChangeProperty (x11_display->xdisplay, window->xwindow, + x11_display->atom__NET_WM_STATE, + XA_ATOM, + 32, PropModeReplace, (guchar*) data, i); + meta_x11_error_trap_pop (x11_display); + + if (window->fullscreen) + { + if (meta_window_has_fullscreen_monitors (window)) + { + data[0] = + meta_x11_display_logical_monitor_to_xinerama_index (window->display->x11_display, + window->fullscreen_monitors.top); + data[1] = + meta_x11_display_logical_monitor_to_xinerama_index (window->display->x11_display, + window->fullscreen_monitors.bottom); + data[2] = + meta_x11_display_logical_monitor_to_xinerama_index (window->display->x11_display, + window->fullscreen_monitors.left); + data[3] = + meta_x11_display_logical_monitor_to_xinerama_index (window->display->x11_display, + window->fullscreen_monitors.right); + + meta_verbose ("Setting _NET_WM_FULLSCREEN_MONITORS\n"); + meta_x11_error_trap_push (x11_display); + XChangeProperty (x11_display->xdisplay, + window->xwindow, + x11_display->atom__NET_WM_FULLSCREEN_MONITORS, + XA_CARDINAL, 32, PropModeReplace, + (guchar*) data, 4); + meta_x11_error_trap_pop (x11_display); + } + else + { + meta_verbose ("Clearing _NET_WM_FULLSCREEN_MONITORS\n"); + meta_x11_error_trap_push (x11_display); + XDeleteProperty (x11_display->xdisplay, + window->xwindow, + x11_display->atom__NET_WM_FULLSCREEN_MONITORS); + meta_x11_error_trap_pop (x11_display); + } + } + + /* Edge constraints */ + update_gtk_edge_constraints (window); +} + +static cairo_region_t * +region_create_from_x_rectangles (const XRectangle *rects, + int n_rects) +{ + int i; + cairo_rectangle_int_t *cairo_rects = g_newa (cairo_rectangle_int_t, n_rects); + + for (i = 0; i < n_rects; i ++) + { + cairo_rects[i].x = rects[i].x; + cairo_rects[i].y = rects[i].y; + cairo_rects[i].width = rects[i].width; + cairo_rects[i].height = rects[i].height; + } + + return cairo_region_create_rectangles (cairo_rects, n_rects); +} + +static void +meta_window_set_input_region (MetaWindow *window, + cairo_region_t *region) +{ + if (cairo_region_equal (window->input_region, region)) + return; + + g_clear_pointer (&window->input_region, cairo_region_destroy); + + if (region != NULL) + window->input_region = cairo_region_reference (region); + + meta_compositor_window_shape_changed (window->display->compositor, window); +} + +#if 0 +/* Print out a region; useful for debugging */ +static void +print_region (cairo_region_t *region) +{ + int n_rects; + int i; + + n_rects = cairo_region_num_rectangles (region); + g_print ("["); + for (i = 0; i < n_rects; i++) + { + cairo_rectangle_int_t rect; + cairo_region_get_rectangle (region, i, &rect); + g_print ("+%d+%dx%dx%d ", + rect.x, rect.y, rect.width, rect.height); + } + g_print ("]\n"); +} +#endif + +void +meta_window_x11_update_input_region (MetaWindow *window) +{ + MetaX11Display *x11_display = window->display->x11_display; + cairo_region_t *region = NULL; + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); + + /* Decorated windows don't have an input region, because + we don't shape the frame to match the client windows + (so the events are blocked by the frame anyway) + */ + if (window->decorated) + { + if (window->input_region) + meta_window_set_input_region (window, NULL); + return; + } + + if (META_X11_DISPLAY_HAS_SHAPE (x11_display)) + { + /* Translate the set of XShape rectangles that we + * get from the X server to a cairo_region. */ + XRectangle *rects = NULL; + int n_rects = -1, ordering; + + meta_x11_error_trap_push (x11_display); + rects = XShapeGetRectangles (x11_display->xdisplay, + window->xwindow, + ShapeInput, + &n_rects, + &ordering); + meta_x11_error_trap_pop (x11_display); + + /* XXX: The X Shape specification is quite unfortunately specified. + * + * By default, the window has a shape the same as its bounding region, + * which we consider "NULL". + * + * If the window sets an empty region, then we'll get n_rects as 0 + * and rects as NULL, which we need to transform back into an empty + * region. + * + * It would be great to have a less-broken extension for this, but + * hey, it's X11! + */ + + if (n_rects == -1) + { + /* We had an error. */ + region = NULL; + } + else if (n_rects == 0) + { + /* Client set an empty region. */ + region = cairo_region_create (); + } + else if (n_rects == 1 && + (rects[0].x == 0 && + rects[0].y == 0 && + rects[0].width == priv->client_rect.width && + rects[0].height == priv->client_rect.height)) + { + /* This is the bounding region case. Keep the + * region as NULL. */ + region = NULL; + } + else + { + /* Window has a custom shape. */ + region = region_create_from_x_rectangles (rects, n_rects); + } + + meta_XFree (rects); + } + + if (region != NULL) + { + cairo_rectangle_int_t client_area; + + client_area.x = 0; + client_area.y = 0; + client_area.width = priv->client_rect.width; + client_area.height = priv->client_rect.height; + + /* The shape we get back from the client may have coordinates + * outside of the frame. The X SHAPE Extension requires that + * the overall shape the client provides never exceeds the + * "bounding rectangle" of the window -- the shape that the + * window would have gotten if it was unshaped. In our case, + * this is simply the client area. + */ + cairo_region_intersect_rectangle (region, &client_area); + } + + meta_window_set_input_region (window, region); + cairo_region_destroy (region); +} + +static void +meta_window_set_shape_region (MetaWindow *window, + cairo_region_t *region) +{ + if (cairo_region_equal (window->shape_region, region)) + return; + + g_clear_pointer (&window->shape_region, cairo_region_destroy); + + if (region != NULL) + window->shape_region = cairo_region_reference (region); + + meta_compositor_window_shape_changed (window->display->compositor, window); +} + +void +meta_window_x11_update_shape_region (MetaWindow *window) +{ + MetaX11Display *x11_display = window->display->x11_display; + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); + cairo_region_t *region = NULL; + + if (META_X11_DISPLAY_HAS_SHAPE (x11_display)) + { + /* Translate the set of XShape rectangles that we + * get from the X server to a cairo_region. */ + XRectangle *rects = NULL; + int n_rects, ordering; + + int x_bounding, y_bounding, x_clip, y_clip; + unsigned w_bounding, h_bounding, w_clip, h_clip; + int bounding_shaped, clip_shaped; + + meta_x11_error_trap_push (x11_display); + XShapeQueryExtents (x11_display->xdisplay, window->xwindow, + &bounding_shaped, &x_bounding, &y_bounding, + &w_bounding, &h_bounding, + &clip_shaped, &x_clip, &y_clip, + &w_clip, &h_clip); + + if (bounding_shaped) + { + rects = XShapeGetRectangles (x11_display->xdisplay, + window->xwindow, + ShapeBounding, + &n_rects, + &ordering); + } + meta_x11_error_trap_pop (x11_display); + + if (rects) + { + region = region_create_from_x_rectangles (rects, n_rects); + XFree (rects); + } + } + + if (region != NULL) + { + cairo_rectangle_int_t client_area; + + client_area.x = 0; + client_area.y = 0; + client_area.width = priv->client_rect.width; + client_area.height = priv->client_rect.height; + + /* The shape we get back from the client may have coordinates + * outside of the frame. The X SHAPE Extension requires that + * the overall shape the client provides never exceeds the + * "bounding rectangle" of the window -- the shape that the + * window would have gotten if it was unshaped. In our case, + * this is simply the client area. + */ + cairo_region_intersect_rectangle (region, &client_area); + /* Some applications might explicitly set their bounding region + * to the client area. Detect these cases, and throw out the + * bounding region in this case for decorated windows. */ + if (window->decorated && + cairo_region_contains_rectangle (region, &client_area) == CAIRO_REGION_OVERLAP_IN) + g_clear_pointer (®ion, cairo_region_destroy); + } + + meta_window_set_shape_region (window, region); + cairo_region_destroy (region); +} + +/* Generally meta_window_same_application() is a better idea + * of "sameness", since it handles the case where multiple apps + * want to look like the same app or the same app wants to look + * like multiple apps, but in the case of workarounds for legacy + * applications (which likely aren't setting the group properly + * anyways), it may be desirable to check this as well. + */ +static gboolean +meta_window_same_client (MetaWindow *window, + MetaWindow *other_window) +{ + int resource_mask = window->display->x11_display->xdisplay->resource_mask; + + return ((window->xwindow & ~resource_mask) == + (other_window->xwindow & ~resource_mask)); +} + +static void +meta_window_move_resize_request (MetaWindow *window, + guint value_mask, + MetaGravity gravity, + int new_x, + int new_y, + int new_width, + int new_height) +{ + int x, y, width, height; + gboolean allow_position_change; + gboolean in_grab_op; + MetaMoveResizeFlags flags; + + /* We ignore configure requests while the user is moving/resizing + * the window, since these represent the app sucking and fighting + * the user, most likely due to a bug in the app (e.g. pfaedit + * seemed to do this) + * + * Still have to do the ConfigureNotify and all, but pretend the + * app asked for the current size/position instead of the new one. + */ + in_grab_op = (window->display->grab_window == window && + meta_grab_op_is_mouse (window->display->grab_op)); + + /* it's essential to use only the explicitly-set fields, + * and otherwise use our current up-to-date position. + * + * Otherwise you get spurious position changes when the app changes + * size, for example, if window->rect is not in sync with the + * server-side position in effect when the configure request was + * generated. + */ + meta_window_get_gravity_position (window, + gravity, + &x, &y); + + allow_position_change = FALSE; + + if (meta_prefs_get_disable_workarounds ()) + { + if (window->type == META_WINDOW_DIALOG || + window->type == META_WINDOW_MODAL_DIALOG || + window->type == META_WINDOW_SPLASHSCREEN) + ; /* No position change for these */ + else if ((window->size_hints.flags & PPosition) || + /* USPosition is just stale if window is placed; + * no --geometry involved here. + */ + ((window->size_hints.flags & USPosition) && + !window->placed)) + allow_position_change = TRUE; + } + else + { + allow_position_change = TRUE; + } + + if (in_grab_op) + allow_position_change = FALSE; + + if (allow_position_change) + { + if (value_mask & CWX) + x = new_x; + if (value_mask & CWY) + y = new_y; + if (value_mask & (CWX | CWY)) + { + /* Once manually positioned, windows shouldn't be placed + * by the window manager. + */ + window->placed = TRUE; + } + } + else + { + meta_topic (META_DEBUG_GEOMETRY, + "Not allowing position change for window %s PPosition 0x%lx USPosition 0x%lx type %u\n", + window->desc, window->size_hints.flags & PPosition, + window->size_hints.flags & USPosition, + window->type); + } + + width = window->rect.width; + height = window->rect.height; + if (!in_grab_op) + { + if (value_mask & CWWidth) + width = new_width; + + if (value_mask & CWHeight) + height = new_height; + } + + /* ICCCM 4.1.5 */ + + /* We're ignoring the value_mask here, since sizes + * not in the mask will be the current window geometry. + */ + window->size_hints.x = x; + window->size_hints.y = y; + window->size_hints.width = width; + window->size_hints.height = height; + + /* NOTE: We consider ConfigureRequests to be "user" actions in one + * way, but not in another. Explanation of the two cases are in the + * next two big comments. + */ + + /* The constraints code allows user actions to move windows + * offscreen, etc., and configure request actions would often send + * windows offscreen when users don't want it if not constrained + * (e.g. hitting a dropdown triangle in a fileselector to show more + * options, which makes the window bigger). Thus we do not set + * META_MOVE_RESIZE_USER_ACTION in flags to the + * meta_window_move_resize_internal() call. + */ + flags = META_MOVE_RESIZE_CONFIGURE_REQUEST; + if (value_mask & (CWX | CWY)) + flags |= META_MOVE_RESIZE_MOVE_ACTION; + if (value_mask & (CWWidth | CWHeight)) + flags |= META_MOVE_RESIZE_RESIZE_ACTION; + + if (flags & (META_MOVE_RESIZE_MOVE_ACTION | META_MOVE_RESIZE_RESIZE_ACTION)) + { + MetaRectangle rect; + + rect.x = x; + rect.y = y; + rect.width = width; + rect.height = height; + + if (window->monitor) + { + MetaRectangle monitor_rect; + + meta_display_get_monitor_geometry (window->display, + window->monitor->number, + &monitor_rect); + + /* Workaround braindead legacy apps that don't know how to + * fullscreen themselves properly - don't get fooled by + * windows which hide their titlebar when maximized or which are + * client decorated; that's not the same as fullscreen, even + * if there are no struts making the workarea smaller than + * the monitor. + */ + if (meta_prefs_get_force_fullscreen() && + (window->decorated || !meta_window_is_client_decorated (window)) && + meta_rectangle_equal (&rect, &monitor_rect) && + window->has_fullscreen_func && + !window->fullscreen) + { + /* + meta_topic (META_DEBUG_GEOMETRY, + */ + meta_warning ( + "Treating resize request of legacy application %s as a " + "fullscreen request\n", + window->desc); + meta_window_make_fullscreen_internal (window); + } + } + + adjust_for_gravity (window, TRUE, gravity, &rect); + meta_window_client_rect_to_frame_rect (window, &rect, &rect); + meta_window_move_resize_internal (window, flags, gravity, rect); + } +} + +static void +restack_window (MetaWindow *window, + MetaWindow *sibling, + int direction) +{ + switch (direction) + { + case Above: + if (sibling) + meta_window_stack_just_above (window, sibling); + else + meta_window_raise (window); + break; + case Below: + if (sibling) + meta_window_stack_just_below (window, sibling); + else + meta_window_lower (window); + break; + case TopIf: + case BottomIf: + case Opposite: + break; + } +} + +gboolean +meta_window_x11_configure_request (MetaWindow *window, + XEvent *event) +{ + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); + + /* Note that x, y is the corner of the window border, + * and width, height is the size of the window inside + * its border, but that we always deny border requests + * and give windows a border of 0. But we save the + * requested border here. + */ + if (event->xconfigurerequest.value_mask & CWBorderWidth) + priv->border_width = event->xconfigurerequest.border_width; + + meta_window_move_resize_request(window, + event->xconfigurerequest.value_mask, + window->size_hints.win_gravity, + event->xconfigurerequest.x, + event->xconfigurerequest.y, + event->xconfigurerequest.width, + event->xconfigurerequest.height); + + /* Handle stacking. We only handle raises/lowers, mostly because + * stack.c really can't deal with anything else. I guess we'll fix + * that if a client turns up that really requires it. Only a very + * few clients even require the raise/lower (and in fact all client + * attempts to deal with stacking order are essentially broken, + * since they have no idea what other clients are involved or how + * the stack looks). + * + * I'm pretty sure no interesting client uses TopIf, BottomIf, or + * Opposite anyway. + */ + if (event->xconfigurerequest.value_mask & CWStackMode) + { + MetaWindow *active_window; + active_window = window->display->focus_window; + if (meta_prefs_get_disable_workarounds ()) + { + meta_topic (META_DEBUG_STACK, + "%s sent an xconfigure stacking request; this is " + "broken behavior and the request is being ignored.\n", + window->desc); + } + else if (active_window && + !meta_window_same_application (window, active_window) && + !meta_window_same_client (window, active_window) && + XSERVER_TIME_IS_BEFORE (window->net_wm_user_time, + active_window->net_wm_user_time)) + { + meta_topic (META_DEBUG_STACK, + "Ignoring xconfigure stacking request from %s (with " + "user_time %u); currently active application is %s (with " + "user_time %u).\n", + window->desc, + window->net_wm_user_time, + active_window->desc, + active_window->net_wm_user_time); + if (event->xconfigurerequest.detail == Above) + meta_window_set_demands_attention(window); + } + else + { + MetaWindow *sibling = NULL; + /* Handle Above/Below with a sibling set */ + if (event->xconfigurerequest.above != None) + { + MetaDisplay *display; + + display = meta_window_get_display (window); + sibling = meta_x11_display_lookup_x_window (display->x11_display, + event->xconfigurerequest.above); + if (sibling == NULL) + return TRUE; + + meta_topic (META_DEBUG_STACK, + "xconfigure stacking request from window %s sibling %s stackmode %d\n", + window->desc, sibling->desc, event->xconfigurerequest.detail); + } + restack_window (window, sibling, event->xconfigurerequest.detail); + } + } + + return TRUE; +} + +static gboolean +process_property_notify (MetaWindow *window, + XPropertyEvent *event) +{ + Window xid = window->xwindow; + + if (meta_is_verbose ()) /* avoid looking up the name if we don't have to */ + { + char *property_name = XGetAtomName (window->display->x11_display->xdisplay, + event->atom); + + meta_verbose ("Property notify on %s for %s\n", + window->desc, property_name); + XFree (property_name); + } + + if (event->atom == window->display->x11_display->atom__NET_WM_USER_TIME && + window->user_time_window) + { + xid = window->user_time_window; + } + + meta_window_reload_property_from_xwindow (window, xid, event->atom, FALSE); + + return TRUE; +} + +gboolean +meta_window_x11_property_notify (MetaWindow *window, + XEvent *event) +{ + return process_property_notify (window, &event->xproperty); +} + +#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0 +#define _NET_WM_MOVERESIZE_SIZE_TOP 1 +#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2 +#define _NET_WM_MOVERESIZE_SIZE_RIGHT 3 +#define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4 +#define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5 +#define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6 +#define _NET_WM_MOVERESIZE_SIZE_LEFT 7 +#define _NET_WM_MOVERESIZE_MOVE 8 +#define _NET_WM_MOVERESIZE_SIZE_KEYBOARD 9 +#define _NET_WM_MOVERESIZE_MOVE_KEYBOARD 10 +#define _NET_WM_MOVERESIZE_CANCEL 11 + +static int +query_pressed_buttons (MetaWindow *window) +{ + MetaCursorTracker *tracker = meta_cursor_tracker_get_for_display (window->display); + ClutterModifierType mods; + int button = 0; + + meta_cursor_tracker_get_pointer (tracker, NULL, NULL, &mods); + + if (mods & CLUTTER_BUTTON1_MASK) + button |= 1 << 1; + if (mods & CLUTTER_BUTTON2_MASK) + button |= 1 << 2; + if (mods & CLUTTER_BUTTON3_MASK) + button |= 1 << 3; + + return button; +} + +static void +handle_net_restack_window (MetaDisplay *display, + XEvent *event) +{ + MetaWindow *window, *sibling = NULL; + + /* Ignore if this does not come from a pager, see the WM spec + */ + if (event->xclient.data.l[0] != 2) + return; + + window = meta_x11_display_lookup_x_window (display->x11_display, + event->xclient.window); + + if (window) + { + if (event->xclient.data.l[1]) + sibling = meta_x11_display_lookup_x_window (display->x11_display, + event->xclient.data.l[1]); + + restack_window (window, sibling, event->xclient.data.l[2]); + } +} + +gboolean +meta_window_x11_client_message (MetaWindow *window, + XEvent *event) +{ + MetaX11Display *x11_display = window->display->x11_display; + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); + MetaDisplay *display; + + display = window->display; + + if (window->override_redirect) + { + /* Don't warn here: we could warn on any of the messages below, + * but we might also receive other client messages that are + * part of protocols we don't know anything about. So, silently + * ignoring is simplest. + */ + return FALSE; + } + + if (event->xclient.message_type == + x11_display->atom__NET_CLOSE_WINDOW) + { + guint32 timestamp; + + if (event->xclient.data.l[0] != 0) + timestamp = event->xclient.data.l[0]; + else + { + meta_warning ("Receiving a NET_CLOSE_WINDOW message for %s without " + "a timestamp! This means some buggy (outdated) " + "application is on the loose!\n", + window->desc); + timestamp = meta_display_get_current_time (window->display); + } + + meta_window_delete (window, timestamp); + + return TRUE; + } + else if (event->xclient.message_type == + x11_display->atom__NET_WM_DESKTOP) + { + int space; + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; + MetaWorkspace *workspace; + + space = event->xclient.data.l[0]; + + meta_verbose ("Request to move %s to workspace %d\n", + window->desc, space); + + workspace = + meta_workspace_manager_get_workspace_by_index (workspace_manager, + space); + + if (workspace) + meta_window_change_workspace (window, workspace); + else if (space == (int) 0xFFFFFFFF) + meta_window_stick (window); + else + meta_verbose ("No such workspace %d for screen\n", space); + + meta_verbose ("Window %s now on_all_workspaces = %d\n", + window->desc, window->on_all_workspaces); + + return TRUE; + } + else if (event->xclient.message_type == + x11_display->atom__NET_WM_STATE) + { + gulong action; + Atom first; + Atom second; + + action = event->xclient.data.l[0]; + first = event->xclient.data.l[1]; + second = event->xclient.data.l[2]; + + if (meta_is_verbose ()) + { + char *str1; + char *str2; + + meta_x11_error_trap_push (x11_display); + str1 = XGetAtomName (x11_display->xdisplay, first); + if (meta_x11_error_trap_pop_with_return (x11_display) != Success) + str1 = NULL; + + meta_x11_error_trap_push (x11_display); + str2 = XGetAtomName (x11_display->xdisplay, second); + if (meta_x11_error_trap_pop_with_return (x11_display) != Success) + str2 = NULL; + + meta_verbose ("Request to change _NET_WM_STATE action %lu atom1: %s atom2: %s\n", + action, + str1 ? str1 : "(unknown)", + str2 ? str2 : "(unknown)"); + + meta_XFree (str1); + meta_XFree (str2); + } + + if (first == x11_display->atom__NET_WM_STATE_SHADED || + second == x11_display->atom__NET_WM_STATE_SHADED) + { + gboolean shade; + guint32 timestamp; + + /* Stupid protocol has no timestamp; of course, shading + * sucks anyway so who really cares that we're forced to do + * a roundtrip here? + */ + timestamp = meta_display_get_current_time_roundtrip (window->display); + + shade = (action == _NET_WM_STATE_ADD || + (action == _NET_WM_STATE_TOGGLE && !window->shaded)); + if (shade && window->has_shade_func) + meta_window_shade (window, timestamp); + else + meta_window_unshade (window, timestamp); + } + + if (first == x11_display->atom__NET_WM_STATE_FULLSCREEN || + second == x11_display->atom__NET_WM_STATE_FULLSCREEN) + { + gboolean make_fullscreen; + + make_fullscreen = (action == _NET_WM_STATE_ADD || + (action == _NET_WM_STATE_TOGGLE && !window->fullscreen)); + if (make_fullscreen && window->has_fullscreen_func) + meta_window_make_fullscreen (window); + else + meta_window_unmake_fullscreen (window); + } + + if (first == x11_display->atom__NET_WM_STATE_MAXIMIZED_HORZ || + second == x11_display->atom__NET_WM_STATE_MAXIMIZED_HORZ || + first == x11_display->atom__NET_WM_STATE_MAXIMIZED_VERT || + second == x11_display->atom__NET_WM_STATE_MAXIMIZED_VERT) + { + gboolean max; + MetaMaximizeFlags directions = 0; + + max = (action == _NET_WM_STATE_ADD || + (action == _NET_WM_STATE_TOGGLE && + !window->maximized_horizontally)); + + if (first == x11_display->atom__NET_WM_STATE_MAXIMIZED_HORZ || + second == x11_display->atom__NET_WM_STATE_MAXIMIZED_HORZ) + directions |= META_MAXIMIZE_HORIZONTAL; + + if (first == x11_display->atom__NET_WM_STATE_MAXIMIZED_VERT || + second == x11_display->atom__NET_WM_STATE_MAXIMIZED_VERT) + directions |= META_MAXIMIZE_VERTICAL; + + if (max && window->has_maximize_func) + { + if (meta_prefs_get_raise_on_click ()) + meta_window_raise (window); + meta_window_maximize (window, directions); + } + else + { + if (meta_prefs_get_raise_on_click ()) + meta_window_raise (window); + meta_window_unmaximize (window, directions); + } + } + + if (first == x11_display->atom__NET_WM_STATE_MODAL || + second == x11_display->atom__NET_WM_STATE_MODAL) + { + priv->wm_state_modal = + (action == _NET_WM_STATE_ADD) || + (action == _NET_WM_STATE_TOGGLE && !priv->wm_state_modal); + + meta_window_x11_recalc_window_type (window); + meta_window_queue(window, META_QUEUE_MOVE_RESIZE); + } + + if (first == x11_display->atom__NET_WM_STATE_SKIP_PAGER || + second == x11_display->atom__NET_WM_STATE_SKIP_PAGER) + { + priv->wm_state_skip_pager = + (action == _NET_WM_STATE_ADD) || + (action == _NET_WM_STATE_TOGGLE && !window->skip_pager); + + meta_window_recalc_features (window); + meta_window_x11_set_net_wm_state (window); + } + + if (first == x11_display->atom__NET_WM_STATE_SKIP_TASKBAR || + second == x11_display->atom__NET_WM_STATE_SKIP_TASKBAR) + { + priv->wm_state_skip_taskbar = + (action == _NET_WM_STATE_ADD) || + (action == _NET_WM_STATE_TOGGLE && !window->skip_taskbar); + + meta_window_recalc_features (window); + meta_window_x11_set_net_wm_state (window); + } + + if (first == x11_display->atom__NET_WM_STATE_ABOVE || + second == x11_display->atom__NET_WM_STATE_ABOVE) + { + if ((action == _NET_WM_STATE_ADD) || + (action == _NET_WM_STATE_TOGGLE && !window->wm_state_demands_attention)) + meta_window_make_above (window); + else + meta_window_unmake_above (window); + } + + if (first == x11_display->atom__NET_WM_STATE_BELOW || + second == x11_display->atom__NET_WM_STATE_BELOW) + { + window->wm_state_below = + (action == _NET_WM_STATE_ADD) || + (action == _NET_WM_STATE_TOGGLE && !window->wm_state_below); + + meta_window_update_layer (window); + meta_window_x11_set_net_wm_state (window); + } + + if (first == x11_display->atom__NET_WM_STATE_DEMANDS_ATTENTION || + second == x11_display->atom__NET_WM_STATE_DEMANDS_ATTENTION) + { + if ((action == _NET_WM_STATE_ADD) || + (action == _NET_WM_STATE_TOGGLE && !window->wm_state_demands_attention)) + meta_window_set_demands_attention (window); + else + meta_window_unset_demands_attention (window); + } + + if (first == x11_display->atom__NET_WM_STATE_STICKY || + second == x11_display->atom__NET_WM_STATE_STICKY) + { + if ((action == _NET_WM_STATE_ADD) || + (action == _NET_WM_STATE_TOGGLE && !window->on_all_workspaces_requested)) + meta_window_stick (window); + else + meta_window_unstick (window); + } + + return TRUE; + } + else if (event->xclient.message_type == + x11_display->atom_WM_CHANGE_STATE) + { + meta_verbose ("WM_CHANGE_STATE client message, state: %ld\n", + event->xclient.data.l[0]); + if (event->xclient.data.l[0] == IconicState) + meta_window_minimize (window); + + return TRUE; + } + else if (event->xclient.message_type == + x11_display->atom__NET_WM_MOVERESIZE) + { + int x_root; + int y_root; + int action; + MetaGrabOp op; + int button; + guint32 timestamp; + + /* _NET_WM_MOVERESIZE messages are almost certainly going to come from + * clients when users click on the fake "frame" that the client has, + * thus we should also treat such messages as though it were a + * "frame action". + */ + gboolean const frame_action = TRUE; + + x_root = event->xclient.data.l[0]; + y_root = event->xclient.data.l[1]; + action = event->xclient.data.l[2]; + button = event->xclient.data.l[3]; + + /* FIXME: What a braindead protocol; no timestamp?!? */ + timestamp = meta_display_get_current_time_roundtrip (display); + meta_topic (META_DEBUG_WINDOW_OPS, + "Received _NET_WM_MOVERESIZE message on %s, %d,%d action = %d, button %d\n", + window->desc, + x_root, y_root, action, button); + + op = META_GRAB_OP_NONE; + switch (action) + { + case _NET_WM_MOVERESIZE_SIZE_TOPLEFT: + op = META_GRAB_OP_RESIZING_NW; + break; + case _NET_WM_MOVERESIZE_SIZE_TOP: + op = META_GRAB_OP_RESIZING_N; + break; + case _NET_WM_MOVERESIZE_SIZE_TOPRIGHT: + op = META_GRAB_OP_RESIZING_NE; + break; + case _NET_WM_MOVERESIZE_SIZE_RIGHT: + op = META_GRAB_OP_RESIZING_E; + break; + case _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT: + op = META_GRAB_OP_RESIZING_SE; + break; + case _NET_WM_MOVERESIZE_SIZE_BOTTOM: + op = META_GRAB_OP_RESIZING_S; + break; + case _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT: + op = META_GRAB_OP_RESIZING_SW; + break; + case _NET_WM_MOVERESIZE_SIZE_LEFT: + op = META_GRAB_OP_RESIZING_W; + break; + case _NET_WM_MOVERESIZE_MOVE: + op = META_GRAB_OP_MOVING; + break; + case _NET_WM_MOVERESIZE_SIZE_KEYBOARD: + op = META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN; + break; + case _NET_WM_MOVERESIZE_MOVE_KEYBOARD: + op = META_GRAB_OP_KEYBOARD_MOVING; + break; + case _NET_WM_MOVERESIZE_CANCEL: + /* handled below */ + break; + default: + break; + } + + if (action == _NET_WM_MOVERESIZE_CANCEL) + { + meta_display_end_grab_op (window->display, timestamp); + } + else if (op != META_GRAB_OP_NONE && + ((window->has_move_func && op == META_GRAB_OP_KEYBOARD_MOVING) || + (window->has_resize_func && op == META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN))) + { + meta_window_begin_grab_op (window, op, frame_action, timestamp); + } + else if (op != META_GRAB_OP_NONE && + ((window->has_move_func && op == META_GRAB_OP_MOVING) || + (window->has_resize_func && + (op != META_GRAB_OP_MOVING && + op != META_GRAB_OP_KEYBOARD_MOVING)))) + { + int button_mask; + + meta_topic (META_DEBUG_WINDOW_OPS, + "Beginning move/resize with button = %d\n", button); + meta_display_begin_grab_op (window->display, + window, + op, + FALSE, + frame_action, + button, 0, + timestamp, + x_root, + y_root); + + button_mask = query_pressed_buttons (window); + + if (button == 0) + { + /* + * the button SHOULD already be included in the message + */ + if ((button_mask & (1 << 1)) != 0) + button = 1; + else if ((button_mask & (1 << 2)) != 0) + button = 2; + else if ((button_mask & (1 << 3)) != 0) + button = 3; + + if (button != 0) + window->display->grab_button = button; + else + meta_display_end_grab_op (window->display, + timestamp); + } + else + { + /* There is a potential race here. If the user presses and + * releases their mouse button very fast, it's possible for + * both the ButtonPress and ButtonRelease to be sent to the + * client before it can get a chance to send _NET_WM_MOVERESIZE + * to us. When that happens, we'll become stuck in a grab + * state, as we haven't received a ButtonRelease to cancel the + * grab. + * + * We can solve this by querying after we take the explicit + * pointer grab -- if the button isn't pressed, we cancel the + * drag immediately. + */ + + if ((button_mask & (1 << button)) == 0) + meta_display_end_grab_op (window->display, timestamp); + } + } + + return TRUE; + } + else if (event->xclient.message_type == + x11_display->atom__NET_MOVERESIZE_WINDOW) + { + MetaGravity gravity; + guint value_mask; + + gravity = (MetaGravity) (event->xclient.data.l[0] & 0xff); + value_mask = (event->xclient.data.l[0] & 0xf00) >> 8; + /* source = (event->xclient.data.l[0] & 0xf000) >> 12; */ + + if (gravity == 0) + gravity = window->size_hints.win_gravity; + + meta_window_move_resize_request(window, + value_mask, + gravity, + event->xclient.data.l[1], /* x */ + event->xclient.data.l[2], /* y */ + event->xclient.data.l[3], /* width */ + event->xclient.data.l[4]); /* height */ + } + else if (event->xclient.message_type == + x11_display->atom__NET_ACTIVE_WINDOW) + { + MetaClientType source_indication; + guint32 timestamp; + + meta_verbose ("_NET_ACTIVE_WINDOW request for window '%s', activating\n", + window->desc); + + source_indication = event->xclient.data.l[0]; + timestamp = event->xclient.data.l[1]; + + if (source_indication > META_CLIENT_TYPE_MAX_RECOGNIZED) + source_indication = META_CLIENT_TYPE_UNKNOWN; + + if (timestamp == 0) + { + /* Client using older EWMH _NET_ACTIVE_WINDOW without a timestamp */ + meta_warning ("Buggy client sent a _NET_ACTIVE_WINDOW message with a " + "timestamp of 0 for %s\n", + window->desc); + timestamp = meta_display_get_current_time (display); + } + + meta_window_activate_full (window, timestamp, source_indication, NULL); + return TRUE; + } + else if (event->xclient.message_type == + x11_display->atom__NET_WM_FULLSCREEN_MONITORS) + { + MetaLogicalMonitor *top, *bottom, *left, *right; + + meta_verbose ("_NET_WM_FULLSCREEN_MONITORS request for window '%s'\n", + window->desc); + + top = + meta_x11_display_xinerama_index_to_logical_monitor (window->display->x11_display, + event->xclient.data.l[0]); + bottom = + meta_x11_display_xinerama_index_to_logical_monitor (window->display->x11_display, + event->xclient.data.l[1]); + left = + meta_x11_display_xinerama_index_to_logical_monitor (window->display->x11_display, + event->xclient.data.l[2]); + right = + meta_x11_display_xinerama_index_to_logical_monitor (window->display->x11_display, + event->xclient.data.l[3]); + /* source_indication = event->xclient.data.l[4]; */ + + meta_window_update_fullscreen_monitors (window, top, bottom, left, right); + } + else if (event->xclient.message_type == + x11_display->atom__GTK_SHOW_WINDOW_MENU) + { + gulong x, y; + + /* l[0] is device_id, which we don't use */ + x = event->xclient.data.l[1]; + y = event->xclient.data.l[2]; + + meta_window_show_menu (window, META_WINDOW_MENU_WM, x, y); + } + else if (event->xclient.message_type == + x11_display->atom__NET_RESTACK_WINDOW) + { + handle_net_restack_window (display, event); + } + + return FALSE; +} + +static void +set_wm_state_on_xwindow (MetaDisplay *display, + Window xwindow, + int state) +{ + unsigned long data[2]; + + /* Mutter doesn't use icon windows, so data[1] should be None + * according to the ICCCM 2.0 Section 4.1.3.1. + */ + data[0] = state; + data[1] = None; + + meta_x11_error_trap_push (display->x11_display); + XChangeProperty (display->x11_display->xdisplay, xwindow, + display->x11_display->atom_WM_STATE, + display->x11_display->atom_WM_STATE, + 32, PropModeReplace, (guchar*) data, 2); + meta_x11_error_trap_pop (display->x11_display); +} + +void +meta_window_x11_set_wm_state (MetaWindow *window) +{ + int state; + + if (window->withdrawn) + state = WithdrawnState; + else if (window->iconic) + state = IconicState; + else + state = NormalState; + + set_wm_state_on_xwindow (window->display, window->xwindow, state); +} + +/* The MUTTER_WM_CLASS_FILTER environment variable is designed for + * performance and regression testing environments where we want to do + * tests with only a limited set of windows and ignore all other windows + * + * When it is set to a comma separated list of WM_CLASS class names, all + * windows not matching the list will be ignored. + * + * Returns TRUE if window has been filtered out and should be ignored. + */ +static gboolean +maybe_filter_xwindow (MetaDisplay *display, + Window xwindow, + gboolean must_be_viewable, + XWindowAttributes *attrs) +{ + static char **filter_wm_classes = NULL; + static gboolean initialized = FALSE; + XClassHint class_hint; + gboolean filtered; + Status success; + int i; + + if (!initialized) + { + const char *filter_string = g_getenv ("MUTTER_WM_CLASS_FILTER"); + if (filter_string) + filter_wm_classes = g_strsplit (filter_string, ",", -1); + initialized = TRUE; + } + + if (!filter_wm_classes || !filter_wm_classes[0]) + return FALSE; + + filtered = TRUE; + + meta_x11_error_trap_push (display->x11_display); + success = XGetClassHint (display->x11_display->xdisplay, + xwindow, &class_hint); + + if (success) + { + for (i = 0; filter_wm_classes[i]; i++) + { + if (strcmp (class_hint.res_class, filter_wm_classes[i]) == 0) + { + filtered = FALSE; + break; + } + } + + XFree (class_hint.res_name); + XFree (class_hint.res_class); + } + + if (filtered) + { + /* We want to try and get the window managed by the next WM that come along, + * so we need to make sure that windows that are requested to be mapped while + * Mutter is running (!must_be_viewable), or windows already viewable at startup + * get a non-withdrawn WM_STATE property. Previously unmapped windows are left + * with whatever WM_STATE property they had. + */ + if (!must_be_viewable || attrs->map_state == IsViewable) + { + uint32_t old_state; + + if (!meta_prop_get_cardinal_with_atom_type (display->x11_display, xwindow, + display->x11_display->atom_WM_STATE, + display->x11_display->atom_WM_STATE, + &old_state)) + old_state = WithdrawnState; + + if (old_state == WithdrawnState) + set_wm_state_on_xwindow (display, xwindow, NormalState); + } + + /* Make sure filtered windows are hidden from view */ + XUnmapWindow (display->x11_display->xdisplay, xwindow); + } + + meta_x11_error_trap_pop (display->x11_display); + + return filtered; +} + +static gboolean +is_our_xwindow (MetaX11Display *x11_display, + Window xwindow, + XWindowAttributes *attrs) +{ + if (xwindow == x11_display->no_focus_window) + return TRUE; + + if (xwindow == x11_display->wm_sn_selection_window) + return TRUE; + + if (xwindow == x11_display->wm_cm_selection_window) + return TRUE; + + if (xwindow == x11_display->guard_window) + return TRUE; + + if (xwindow == x11_display->composite_overlay_window) + return TRUE; + + { + MetaBackend *backend = meta_get_backend (); + + if (META_IS_BACKEND_X11 (backend)) + { + if (xwindow == meta_backend_x11_get_xwindow (META_BACKEND_X11 (backend))) + return TRUE; + } + } + + /* Any windows created via meta_create_offscreen_window */ + if (attrs->override_redirect && attrs->x == -100 && attrs->y == -100 && attrs->width == 1 && attrs->height == 1) + return TRUE; + + return FALSE; +} + +#ifdef WITH_VERBOSE_MODE +static const char* +wm_state_to_string (int state) +{ + switch (state) + { + case NormalState: + return "NormalState"; + case IconicState: + return "IconicState"; + case WithdrawnState: + return "WithdrawnState"; + } + + return "Unknown"; +} +#endif + +MetaWindow * +meta_window_x11_new (MetaDisplay *display, + Window xwindow, + gboolean must_be_viewable, + MetaCompEffect effect) +{ + MetaX11Display *x11_display = display->x11_display; + XWindowAttributes attrs; + gulong existing_wm_state; + MetaWindow *window = NULL; + gulong event_mask; + + meta_verbose ("Attempting to manage 0x%lx\n", xwindow); + + if (meta_x11_display_xwindow_is_a_no_focus_window (x11_display, xwindow)) + { + meta_verbose ("Not managing no_focus_window 0x%lx\n", + xwindow); + return NULL; + } + + meta_x11_error_trap_push (x11_display); /* Push a trap over all of window + * creation, to reduce XSync() calls + */ + /* + * This function executes without any server grabs held. This means that + * the window could have already gone away, or could go away at any point, + * so we must be careful with X error handling. + */ + + if (!XGetWindowAttributes (x11_display->xdisplay, xwindow, &attrs)) + { + meta_verbose ("Failed to get attributes for window 0x%lx\n", + xwindow); + goto error; + } + + if (attrs.root != x11_display->xroot) + { + meta_verbose ("Not on our screen\n"); + goto error; + } + + if (attrs.class == InputOnly) + { + meta_verbose ("Not managing InputOnly windows\n"); + goto error; + } + + if (is_our_xwindow (x11_display, xwindow, &attrs)) + { + meta_verbose ("Not managing our own windows\n"); + goto error; + } + + if (maybe_filter_xwindow (display, xwindow, must_be_viewable, &attrs)) + { + meta_verbose ("Not managing filtered window\n"); + goto error; + } + + existing_wm_state = WithdrawnState; + if (must_be_viewable && attrs.map_state != IsViewable) + { + /* Only manage if WM_STATE is IconicState or NormalState */ + uint32_t state; + + /* WM_STATE isn't a cardinal, it's type WM_STATE, but is an int */ + if (!(meta_prop_get_cardinal_with_atom_type (x11_display, xwindow, + x11_display->atom_WM_STATE, + x11_display->atom_WM_STATE, + &state) && + (state == IconicState || state == NormalState))) + { + meta_verbose ("Deciding not to manage unmapped or unviewable window 0x%lx\n", xwindow); + goto error; + } + + existing_wm_state = state; + meta_verbose ("WM_STATE of %lx = %s\n", xwindow, + wm_state_to_string (existing_wm_state)); + } + + /* + * XAddToSaveSet can only be called on windows created by a different + * client. with Mutter we want to be able to create manageable windows + * from within the process (such as a dummy desktop window). As we do not + * want this call failing to prevent the window from being managed, we + * call this before creating the return-checked error trap. + */ + XAddToSaveSet (x11_display->xdisplay, xwindow); + + meta_x11_error_trap_push (x11_display); + + event_mask = PropertyChangeMask; + if (attrs.override_redirect) + event_mask |= StructureNotifyMask; + + /* If the window is from this client (a menu, say) we need to augment + * the event mask, not replace it. For windows from other clients, + * attrs.your_event_mask will be empty at this point. + */ + XSelectInput (x11_display->xdisplay, xwindow, attrs.your_event_mask | event_mask); + + { + unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; + XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; + + XISetMask (mask.mask, XI_Enter); + XISetMask (mask.mask, XI_Leave); + XISetMask (mask.mask, XI_FocusIn); + XISetMask (mask.mask, XI_FocusOut); + + XISelectEvents (x11_display->xdisplay, xwindow, &mask, 1); + } + + if (META_X11_DISPLAY_HAS_SHAPE (x11_display)) + XShapeSelectInput (x11_display->xdisplay, xwindow, ShapeNotifyMask); + + /* Get rid of any borders */ + if (attrs.border_width != 0) + XSetWindowBorderWidth (x11_display->xdisplay, xwindow, 0); + + /* Get rid of weird gravities */ + if (attrs.win_gravity != NorthWestGravity) + { + XSetWindowAttributes set_attrs; + + set_attrs.win_gravity = NorthWestGravity; + + XChangeWindowAttributes (x11_display->xdisplay, + xwindow, + CWWinGravity, + &set_attrs); + } + + if (meta_x11_error_trap_pop_with_return (x11_display) != Success) + { + meta_verbose ("Window 0x%lx disappeared just as we tried to manage it\n", + xwindow); + goto error; + } + + window = _meta_window_shared_new (display, + META_WINDOW_CLIENT_TYPE_X11, + NULL, + xwindow, + existing_wm_state, + effect, + &attrs); + + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); + + priv->border_width = attrs.border_width; + + meta_window_grab_keys (window); + if (window->type != META_WINDOW_DOCK && !window->override_redirect) + { + meta_display_grab_window_buttons (window->display, window->xwindow); + meta_display_grab_focus_window_button (window->display, window); + } + + meta_x11_error_trap_pop (x11_display); /* pop the XSync()-reducing trap */ + return window; + +error: + meta_x11_error_trap_pop (x11_display); + return NULL; +} + +void +meta_window_x11_recalc_window_type (MetaWindow *window) +{ + MetaX11Display *x11_display = window->display->x11_display; + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); + MetaWindowType type; + + if (priv->type_atom != None) + { + if (priv->type_atom == x11_display->atom__NET_WM_WINDOW_TYPE_DESKTOP) + type = META_WINDOW_DESKTOP; + else if (priv->type_atom == x11_display->atom__NET_WM_WINDOW_TYPE_DOCK) + type = META_WINDOW_DOCK; + else if (priv->type_atom == x11_display->atom__NET_WM_WINDOW_TYPE_TOOLBAR) + type = META_WINDOW_TOOLBAR; + else if (priv->type_atom == x11_display->atom__NET_WM_WINDOW_TYPE_MENU) + type = META_WINDOW_MENU; + else if (priv->type_atom == x11_display->atom__NET_WM_WINDOW_TYPE_UTILITY) + type = META_WINDOW_UTILITY; + else if (priv->type_atom == x11_display->atom__NET_WM_WINDOW_TYPE_SPLASH) + type = META_WINDOW_SPLASHSCREEN; + else if (priv->type_atom == x11_display->atom__NET_WM_WINDOW_TYPE_DIALOG) + type = META_WINDOW_DIALOG; + else if (priv->type_atom == x11_display->atom__NET_WM_WINDOW_TYPE_NORMAL) + type = META_WINDOW_NORMAL; + /* The below are *typically* override-redirect windows, but the spec does + * not disallow using them for managed windows. + */ + else if (priv->type_atom == x11_display->atom__NET_WM_WINDOW_TYPE_DROPDOWN_MENU) + type = META_WINDOW_DROPDOWN_MENU; + else if (priv->type_atom == x11_display->atom__NET_WM_WINDOW_TYPE_POPUP_MENU) + type = META_WINDOW_POPUP_MENU; + else if (priv->type_atom == x11_display->atom__NET_WM_WINDOW_TYPE_TOOLTIP) + type = META_WINDOW_TOOLTIP; + else if (priv->type_atom == x11_display->atom__NET_WM_WINDOW_TYPE_NOTIFICATION) + type = META_WINDOW_NOTIFICATION; + else if (priv->type_atom == x11_display->atom__NET_WM_WINDOW_TYPE_COMBO) + type = META_WINDOW_COMBO; + else if (priv->type_atom == x11_display->atom__NET_WM_WINDOW_TYPE_DND) + type = META_WINDOW_DND; + else + { + char *atom_name; + + /* + * Fallback on a normal type, and print warning. Don't abort. + */ + type = META_WINDOW_NORMAL; + + meta_x11_error_trap_push (x11_display); + atom_name = XGetAtomName (x11_display->xdisplay, + priv->type_atom); + meta_x11_error_trap_pop (x11_display); + + meta_warning ("Unrecognized type atom [%s] set for %s \n", + atom_name ? atom_name : "unknown", + window->desc); + + if (atom_name) + XFree (atom_name); + } + } + else if (window->transient_for != NULL) + { + type = META_WINDOW_DIALOG; + } + else + { + type = META_WINDOW_NORMAL; + } + + if (type == META_WINDOW_DIALOG && priv->wm_state_modal) + type = META_WINDOW_MODAL_DIALOG; + + /* We don't want to allow override-redirect windows to have decorated-window + * types since that's just confusing. + */ + if (window->override_redirect) + { + switch (type) + { + /* Decorated types */ + case META_WINDOW_NORMAL: + case META_WINDOW_DIALOG: + case META_WINDOW_MODAL_DIALOG: + case META_WINDOW_MENU: + case META_WINDOW_UTILITY: + type = META_WINDOW_OVERRIDE_OTHER; + break; + /* Undecorated types, normally not override-redirect */ + case META_WINDOW_DESKTOP: + case META_WINDOW_DOCK: + case META_WINDOW_TOOLBAR: + case META_WINDOW_SPLASHSCREEN: + /* Undecorated types, normally override-redirect types */ + case META_WINDOW_DROPDOWN_MENU: + case META_WINDOW_POPUP_MENU: + case META_WINDOW_TOOLTIP: + case META_WINDOW_NOTIFICATION: + case META_WINDOW_COMBO: + case META_WINDOW_DND: + /* To complete enum */ + case META_WINDOW_OVERRIDE_OTHER: + break; + } + } + + meta_verbose ("Calculated type %u for %s, old type %u\n", + type, window->desc, type); + meta_window_set_type (window, type); +} + +/** + * meta_window_x11_configure_notify: (skip) + * @window: a #MetaWindow + * @event: a #XConfigureEvent + * + * This is used to notify us of an unrequested configuration + * (only applicable to override redirect windows) + */ +void +meta_window_x11_configure_notify (MetaWindow *window, + XConfigureEvent *event) +{ + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); + + g_assert (window->override_redirect); + g_assert (window->frame == NULL); + + window->rect.x = event->x; + window->rect.y = event->y; + window->rect.width = event->width; + window->rect.height = event->height; + + priv->client_rect = window->rect; + window->buffer_rect = window->rect; + + meta_window_update_monitor (window, META_WINDOW_UPDATE_MONITOR_FLAGS_NONE); + + /* Whether an override-redirect window is considered fullscreen depends + * on its geometry. + */ + if (window->override_redirect) + meta_display_queue_check_fullscreen (window->display); + + if (!event->override_redirect && !event->send_event) + meta_warning ("Unhandled change of windows override redirect status\n"); + + meta_compositor_sync_window_geometry (window->display->compositor, window, FALSE); +} + +void +meta_window_x11_set_allowed_actions_hint (MetaWindow *window) +{ + MetaX11Display *x11_display = window->display->x11_display; +#define MAX_N_ACTIONS 12 + unsigned long data[MAX_N_ACTIONS]; + int i; + + i = 0; + if (window->has_move_func) + { + data[i] = x11_display->atom__NET_WM_ACTION_MOVE; + ++i; + } + if (window->has_resize_func) + { + data[i] = x11_display->atom__NET_WM_ACTION_RESIZE; + ++i; + } + if (window->has_fullscreen_func) + { + data[i] = x11_display->atom__NET_WM_ACTION_FULLSCREEN; + ++i; + } + if (window->has_minimize_func) + { + data[i] = x11_display->atom__NET_WM_ACTION_MINIMIZE; + ++i; + } + if (window->has_shade_func) + { + data[i] = x11_display->atom__NET_WM_ACTION_SHADE; + ++i; + } + /* sticky according to EWMH is different from mutter's sticky; + * mutter doesn't support EWMH sticky + */ + if (window->has_maximize_func) + { + data[i] = x11_display->atom__NET_WM_ACTION_MAXIMIZE_HORZ; + ++i; + data[i] = x11_display->atom__NET_WM_ACTION_MAXIMIZE_VERT; + ++i; + } + /* We always allow this */ + data[i] = x11_display->atom__NET_WM_ACTION_CHANGE_DESKTOP; + ++i; + if (window->has_close_func) + { + data[i] = x11_display->atom__NET_WM_ACTION_CLOSE; + ++i; + } + + /* I guess we always allow above/below operations */ + data[i] = x11_display->atom__NET_WM_ACTION_ABOVE; + ++i; + data[i] = x11_display->atom__NET_WM_ACTION_BELOW; + ++i; + + g_assert (i <= MAX_N_ACTIONS); + + meta_verbose ("Setting _NET_WM_ALLOWED_ACTIONS with %d atoms\n", i); + + meta_x11_error_trap_push (x11_display); + XChangeProperty (x11_display->xdisplay, window->xwindow, + x11_display->atom__NET_WM_ALLOWED_ACTIONS, + XA_ATOM, + 32, PropModeReplace, (guchar*) data, i); + meta_x11_error_trap_pop (x11_display); +#undef MAX_N_ACTIONS +} + +void +meta_window_x11_create_sync_request_alarm (MetaWindow *window) +{ + MetaX11Display *x11_display = window->display->x11_display; + XSyncAlarmAttributes values; + XSyncValue init; + + if (window->sync_request_counter == None || + window->sync_request_alarm != None) + return; + + meta_x11_error_trap_push (x11_display); + + /* In the new (extended style), the counter value is initialized by + * the client before mapping the window. In the old style, we're + * responsible for setting the initial value of the counter. + */ + if (window->extended_sync_request_counter) + { + if (!XSyncQueryCounter(x11_display->xdisplay, + window->sync_request_counter, + &init)) + { + meta_x11_error_trap_pop_with_return (x11_display); + window->sync_request_counter = None; + return; + } + + window->sync_request_serial = + XSyncValueLow32 (init) + ((gint64)XSyncValueHigh32 (init) << 32); + } + else + { + XSyncIntToValue (&init, 0); + XSyncSetCounter (x11_display->xdisplay, + window->sync_request_counter, init); + window->sync_request_serial = 0; + } + + values.trigger.counter = window->sync_request_counter; + values.trigger.test_type = XSyncPositiveComparison; + + /* Initialize to one greater than the current value */ + values.trigger.value_type = XSyncRelative; + XSyncIntToValue (&values.trigger.wait_value, 1); + + /* After triggering, increment test_value by this until + * until the test condition is false */ + XSyncIntToValue (&values.delta, 1); + + /* we want events (on by default anyway) */ + values.events = True; + + window->sync_request_alarm = XSyncCreateAlarm (x11_display->xdisplay, + XSyncCACounter | + XSyncCAValueType | + XSyncCAValue | + XSyncCATestType | + XSyncCADelta | + XSyncCAEvents, + &values); + + if (meta_x11_error_trap_pop_with_return (x11_display) == Success) + meta_x11_display_register_sync_alarm (x11_display, &window->sync_request_alarm, window); + else + { + window->sync_request_alarm = None; + window->sync_request_counter = None; + } +} + +void +meta_window_x11_destroy_sync_request_alarm (MetaWindow *window) +{ + MetaX11Display *x11_display = window->display->x11_display; + + if (window->sync_request_alarm != None) + { + /* Has to be unregistered _before_ clearing the structure field */ + meta_x11_display_unregister_sync_alarm (x11_display, window->sync_request_alarm); + XSyncDestroyAlarm (x11_display->xdisplay, + window->sync_request_alarm); + window->sync_request_alarm = None; + } +} + +void +meta_window_x11_update_sync_request_counter (MetaWindow *window, + gint64 new_counter_value) +{ + gboolean needs_frame_drawn = FALSE; + gboolean no_delay_frame = FALSE; + + if (window->extended_sync_request_counter && new_counter_value % 2 == 0) + { + needs_frame_drawn = TRUE; + no_delay_frame = new_counter_value == window->sync_request_serial + 1; + } + + window->sync_request_serial = new_counter_value; + meta_compositor_sync_updates_frozen (window->display->compositor, window); + + if (new_counter_value >= window->sync_request_wait_serial && + window->sync_request_timeout_id) + { + + if (!window->extended_sync_request_counter || + new_counter_value % 2 == 0) + g_clear_handle_id (&window->sync_request_timeout_id, g_source_remove); + + if (window == window->display->grab_window && + meta_grab_op_is_resizing (window->display->grab_op) && + (!window->extended_sync_request_counter || + new_counter_value % 2 == 0)) + { + meta_topic (META_DEBUG_RESIZING, + "Alarm event received last motion x = %d y = %d\n", + window->display->grab_latest_motion_x, + window->display->grab_latest_motion_y); + + /* This means we are ready for another configure; + * no pointer round trip here, to keep in sync */ + meta_window_update_resize (window, + window->display->grab_last_user_action_was_snap, + window->display->grab_latest_motion_x, + window->display->grab_latest_motion_y, + TRUE); + } + } + + /* If sync was previously disabled, turn it back on and hope + * the application has come to its senses (maybe it was just + * busy with a pagefault or a long computation). + */ + window->disable_sync = FALSE; + + if (needs_frame_drawn) + meta_compositor_queue_frame_drawn (window->display->compositor, window, + no_delay_frame); +} + +Window +meta_window_x11_get_toplevel_xwindow (MetaWindow *window) +{ + return window->frame ? window->frame->xwindow : window->xwindow; +} + +void +meta_window_x11_freeze_commits (MetaWindow *window) +{ + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + META_WINDOW_X11_GET_CLASS (window_x11)->freeze_commits (window); +} + +void +meta_window_x11_thaw_commits (MetaWindow *window) +{ + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + META_WINDOW_X11_GET_CLASS (window_x11)->thaw_commits (window); +} + +void +meta_window_x11_set_thaw_after_paint (MetaWindow *window, + gboolean thaw_after_paint) +{ + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); + + priv->thaw_after_paint = thaw_after_paint; +} + +gboolean +meta_window_x11_should_thaw_after_paint (MetaWindow *window) +{ + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); + + return priv->thaw_after_paint; +} + +gboolean +meta_window_x11_always_update_shape (MetaWindow *window) +{ + MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); + + return META_WINDOW_X11_GET_CLASS (window_x11)->always_update_shape (window); +} + +void +meta_window_x11_surface_rect_to_frame_rect (MetaWindow *window, + MetaRectangle *surface_rect, + MetaRectangle *frame_rect) + +{ + MetaFrameBorders borders; + + g_return_if_fail (window->frame); + + meta_frame_calc_borders (window->frame, &borders); + + *frame_rect = *surface_rect; + frame_rect->x += borders.invisible.left; + frame_rect->y += borders.invisible.top; + frame_rect->width -= borders.invisible.left + borders.invisible.right; + frame_rect->height -= borders.invisible.top + borders.invisible.bottom; +} + +void +meta_window_x11_surface_rect_to_client_rect (MetaWindow *window, + MetaRectangle *surface_rect, + MetaRectangle *client_rect) +{ + MetaFrameBorders borders; + + meta_frame_calc_borders (window->frame, &borders); + + *client_rect = *surface_rect; + client_rect->x += borders.total.left; + client_rect->y += borders.total.top; + client_rect->width -= borders.total.left + borders.total.right; + client_rect->height -= borders.total.top + borders.total.bottom; +} diff --git a/src/x11/window-x11.h b/src/x11/window-x11.h new file mode 100644 index 000000000..d41d0d156 --- /dev/null +++ b/src/x11/window-x11.h @@ -0,0 +1,98 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2001 Havoc Pennington + * Copyright (C) 2002 Red Hat, Inc. + * Copyright (C) 2003, 2004 Rob Adams + * Copyright (C) 2004-2006 Elijah Newren + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef META_WINDOW_X11_H +#define META_WINDOW_X11_H + +#include <X11/Xlib.h> + +#include "meta/compositor.h" +#include "meta/window.h" + +G_BEGIN_DECLS + +#define META_TYPE_WINDOW_X11 (meta_window_x11_get_type()) +#define META_WINDOW_X11(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_WINDOW_X11, MetaWindowX11)) +#define META_WINDOW_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_WINDOW_X11, MetaWindowX11Class)) +#define META_IS_WINDOW_X11(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_WINDOW_X11)) +#define META_IS_WINDOW_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_WINDOW_X11)) +#define META_WINDOW_X11_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_WINDOW_X11, MetaWindowX11Class)) + +GType meta_window_x11_get_type (void); + +typedef struct _MetaWindowX11 MetaWindowX11; +typedef struct _MetaWindowX11Class MetaWindowX11Class; + +G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaWindowX11, g_object_unref) + +MetaWindow * meta_window_x11_new (MetaDisplay *display, + Window xwindow, + gboolean must_be_viewable, + MetaCompEffect effect); + +void meta_window_x11_set_net_wm_state (MetaWindow *window); +void meta_window_x11_set_wm_state (MetaWindow *window); +void meta_window_x11_set_wm_take_focus (MetaWindow *window, + gboolean take_focus); +void meta_window_x11_set_wm_ping (MetaWindow *window, + gboolean ping); +void meta_window_x11_set_wm_delete_window (MetaWindow *window, + gboolean delete_window); +void meta_window_x11_set_allowed_actions_hint (MetaWindow *window); + +void meta_window_x11_create_sync_request_alarm (MetaWindow *window); +void meta_window_x11_destroy_sync_request_alarm (MetaWindow *window); +void meta_window_x11_update_sync_request_counter (MetaWindow *window, + gint64 new_counter_value); + +void meta_window_x11_update_input_region (MetaWindow *window); +void meta_window_x11_update_shape_region (MetaWindow *window); + +void meta_window_x11_recalc_window_type (MetaWindow *window); + +gboolean meta_window_x11_configure_request (MetaWindow *window, + XEvent *event); +gboolean meta_window_x11_property_notify (MetaWindow *window, + XEvent *event); +gboolean meta_window_x11_client_message (MetaWindow *window, + XEvent *event); + +void meta_window_x11_configure_notify (MetaWindow *window, + XConfigureEvent *event); + +Window meta_window_x11_get_toplevel_xwindow (MetaWindow *window); + +void meta_window_x11_freeze_commits (MetaWindow *window); +void meta_window_x11_thaw_commits (MetaWindow *window); + +void meta_window_x11_set_thaw_after_paint (MetaWindow *window, + gboolean thaw_after_paint); +gboolean meta_window_x11_should_thaw_after_paint (MetaWindow *window); +gboolean meta_window_x11_always_update_shape (MetaWindow *window); + +void meta_window_x11_surface_rect_to_frame_rect (MetaWindow *window, + MetaRectangle *surface_rect, + MetaRectangle *frame_rect); +void meta_window_x11_surface_rect_to_client_rect (MetaWindow *window, + MetaRectangle *surface_rect, + MetaRectangle *client_rect); +#endif diff --git a/src/core/xprops.c b/src/x11/xprops.c similarity index 59% rename from src/core/xprops.c rename to src/x11/xprops.c index e23d5a6aa..cbf5a0604 100644 --- a/src/core/xprops.c +++ b/src/x11/xprops.c @@ -1,6 +1,6 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* Muffin X property convenience routines */ +/* Mutter X property convenience routines */ /* * Copyright (C) 2001 Havoc Pennington @@ -22,9 +22,7 @@ * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA - * 02110-1335, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ /*********************************************************** @@ -80,27 +78,32 @@ from The Open Group. */ -#include <config.h> -#include "xprops.h" -#include <meta/errors.h> -#include "util-private.h" -#include "async-getprop.h" -#include "ui.h" -#include "muffin-Xatomtype.h" -#include <X11/Xatom.h> +#include "config.h" + +#include "x11/xprops.h" + #include <string.h> -#include "window-private.h" +#include <stdlib.h> +#include <X11/Xatom.h> +#include <X11/Xlib-xcb.h> + +#include "core/util-private.h" +#include "core/window-private.h" +#include "meta/meta-x11-errors.h" +#include "ui/ui.h" +#include "x11/meta-x11-display-private.h" +#include "x11/mutter-Xatomtype.h" typedef struct { - MetaDisplay *display; - Window xwindow; - Atom xatom; - Atom type; - int format; - unsigned long n_items; - unsigned long bytes_after; - unsigned char *prop; + MetaX11Display *x11_display; + Window xwindow; + Atom xatom; + Atom type; + int format; + unsigned long n_items; + unsigned long bytes_after; + unsigned char *prop; } GetPropertyResults; static gboolean @@ -109,6 +112,7 @@ validate_or_free_results (GetPropertyResults *results, Atom expected_type, gboolean must_have_items) { + MetaX11Display *x11_display = results->x11_display; char *type_name; char *expected_name; char *prop_name; @@ -122,13 +126,13 @@ validate_or_free_results (GetPropertyResults *results, (!must_have_items || results->n_items > 0)) return TRUE; - meta_error_trap_push (results->display); - type_name = XGetAtomName (results->display->xdisplay, results->type); - expected_name = XGetAtomName (results->display->xdisplay, expected_type); - prop_name = XGetAtomName (results->display->xdisplay, results->xatom); - meta_error_trap_pop (results->display); + meta_x11_error_trap_push (x11_display); + type_name = XGetAtomName (x11_display->xdisplay, results->type); + expected_name = XGetAtomName (x11_display->xdisplay, expected_type); + prop_name = XGetAtomName (x11_display->xdisplay, results->xatom); + meta_x11_error_trap_pop (x11_display); - w = meta_display_lookup_x_window (results->display, results->xwindow); + w = meta_x11_display_lookup_x_window (x11_display, results->xwindow); if (w != NULL) { @@ -161,30 +165,75 @@ validate_or_free_results (GetPropertyResults *results, results->format, (int) results->n_items, title, res_class, res_name); - if (type_name) - XFree (type_name); - if (expected_name) - XFree (expected_name); - if (prop_name) - XFree (prop_name); + meta_XFree (type_name); + meta_XFree (expected_name); + meta_XFree (prop_name); if (results->prop) { - XFree (results->prop); + g_free (results->prop); results->prop = NULL; } return FALSE; } +static xcb_get_property_cookie_t +async_get_property (xcb_connection_t *xcb_conn, Window xwindow, + Atom xatom, Atom required_type) +{ + return xcb_get_property (xcb_conn, False, xwindow, + xatom, required_type, 0, G_MAXUINT32); +} + static gboolean -get_property (MetaDisplay *display, +async_get_property_finish (xcb_connection_t *xcb_conn, + xcb_get_property_cookie_t cookie, + GetPropertyResults *results) +{ + xcb_get_property_reply_t *reply; + xcb_generic_error_t *error; + int length; + + reply = xcb_get_property_reply (xcb_conn, cookie, &error); + if (error) + { + free (error); + return FALSE; + } + + results->n_items = reply->value_len; + results->type = reply->type; + results->bytes_after = reply->bytes_after; + results->format = reply->format; + results->prop = NULL; + + if (results->type != None) + { + length = xcb_get_property_value_length (reply); + /* Leave room for a trailing '\0' since xcb doesn't return null-terminated + * strings + */ + results->prop = g_malloc (length + 1); + memcpy (results->prop, xcb_get_property_value (reply), length); + results->prop[length] = '\0'; + } + + free (reply); + return (results->prop != NULL); +} + +static gboolean +get_property (MetaX11Display *x11_display, Window xwindow, Atom xatom, Atom req_type, GetPropertyResults *results) { - results->display = display; + xcb_get_property_cookie_t cookie; + xcb_connection_t *xcb_conn = XGetXCBConnection (x11_display->xdisplay); + + results->x11_display = x11_display; results->xwindow = xwindow; results->xatom = xatom; results->prop = NULL; @@ -193,103 +242,53 @@ get_property (MetaDisplay *display, results->bytes_after = 0; results->format = 0; - meta_error_trap_push_with_return (display); - if (XGetWindowProperty (display->xdisplay, xwindow, xatom, - 0, G_MAXLONG, - False, req_type, &results->type, &results->format, - &results->n_items, - &results->bytes_after, - &results->prop) != Success || - results->type == None) - { - if (results->prop) - XFree (results->prop); - meta_error_trap_pop_with_return (display); - return FALSE; - } - - if (meta_error_trap_pop_with_return (display) != Success) - { - if (results->prop) - XFree (results->prop); - return FALSE; - } - - return TRUE; + cookie = async_get_property (xcb_conn, xwindow, xatom, req_type); + return async_get_property_finish (xcb_conn, cookie, results); } static gboolean atom_list_from_results (GetPropertyResults *results, - Atom **atoms_p, + uint32_t **atoms_p, int *n_atoms_p) { if (!validate_or_free_results (results, 32, XA_ATOM, FALSE)) return FALSE; - *atoms_p = (Atom*) results->prop; + *atoms_p = (uint32_t*) results->prop; *n_atoms_p = results->n_items; results->prop = NULL; return TRUE; } -LOCAL_SYMBOL gboolean -meta_prop_get_atom_list (MetaDisplay *display, - Window xwindow, - Atom xatom, - Atom **atoms_p, - int *n_atoms_p) -{ - GetPropertyResults results; - - *atoms_p = NULL; - *n_atoms_p = 0; - - if (!get_property (display, xwindow, xatom, XA_ATOM, - &results)) - return FALSE; - - return atom_list_from_results (&results, atoms_p, n_atoms_p); -} - static gboolean cardinal_list_from_results (GetPropertyResults *results, - gulong **cardinals_p, + uint32_t **cardinals_p, int *n_cardinals_p) { if (!validate_or_free_results (results, 32, XA_CARDINAL, FALSE)) return FALSE; - *cardinals_p = (gulong*) results->prop; + *cardinals_p = (uint32_t *) results->prop; *n_cardinals_p = results->n_items; results->prop = NULL; -#if GLIB_SIZEOF_LONG == 8 - /* Xlib sign-extends format=32 items, but we want them unsigned */ - { - int i; - - for (i = 0; i < *n_cardinals_p; i++) - (*cardinals_p)[i] = (*cardinals_p)[i] & 0xffffffff; - } -#endif - return TRUE; } -LOCAL_SYMBOL LOCAL_SYMBOL gboolean -meta_prop_get_cardinal_list (MetaDisplay *display, - Window xwindow, - Atom xatom, - gulong **cardinals_p, - int *n_cardinals_p) +gboolean +meta_prop_get_cardinal_list (MetaX11Display *x11_display, + Window xwindow, + Atom xatom, + uint32_t **cardinals_p, + int *n_cardinals_p) { GetPropertyResults results; *cardinals_p = NULL; *n_cardinals_p = 0; - if (!get_property (display, xwindow, xatom, XA_CARDINAL, + if (!get_property (x11_display, xwindow, xatom, XA_CARDINAL, &results)) return FALSE; @@ -300,19 +299,13 @@ static gboolean motif_hints_from_results (GetPropertyResults *results, MotifWmHints **hints_p) { - int real_size, max_size; -#define MAX_ITEMS sizeof (MotifWmHints)/sizeof (gulong) - *hints_p = NULL; if (results->type == None || results->n_items <= 0) { + g_free (results->prop); + results->prop = NULL; meta_verbose ("Motif hints had unexpected type or n_items\n"); - if (results->prop) - { - XFree (results->prop); - results->prop = NULL; - } return FALSE; } @@ -320,40 +313,27 @@ motif_hints_from_results (GetPropertyResults *results, * MotifWmHints than the one we expect, apparently. I'm not sure of * the history behind it. See bug #89841 for example. */ - *hints_p = ag_Xmalloc (sizeof (MotifWmHints)); - if (*hints_p == NULL) - { - if (results->prop) - { - XFree (results->prop); - results->prop = NULL; - } - return FALSE; - } - real_size = results->n_items * sizeof (gulong); - max_size = MAX_ITEMS * sizeof (gulong); - memcpy (*hints_p, results->prop, MIN (real_size, max_size)); + *hints_p = g_new0 (MotifWmHints, 1); + memcpy(*hints_p, results->prop, MIN (sizeof (MotifWmHints), + results->n_items * sizeof (uint32_t))); - if (results->prop) - { - XFree (results->prop); - results->prop = NULL; - } + g_free (results->prop); + results->prop = NULL; return TRUE; } -LOCAL_SYMBOL gboolean -meta_prop_get_motif_hints (MetaDisplay *display, - Window xwindow, - Atom xatom, - MotifWmHints **hints_p) +gboolean +meta_prop_get_motif_hints (MetaX11Display *x11_display, + Window xwindow, + Atom xatom, + MotifWmHints **hints_p) { GetPropertyResults results; *hints_p = NULL; - if (!get_property (display, xwindow, xatom, AnyPropertyType, + if (!get_property (x11_display, xwindow, xatom, AnyPropertyType, &results)) return FALSE; @@ -369,23 +349,25 @@ latin1_string_from_results (GetPropertyResults *results, if (!validate_or_free_results (results, 8, XA_STRING, FALSE)) return FALSE; - *str_p = (char*) results->prop; + *str_p = g_strndup ((char *) results->prop, results->n_items); + + g_free (results->prop); results->prop = NULL; return TRUE; } -LOCAL_SYMBOL gboolean -meta_prop_get_latin1_string (MetaDisplay *display, - Window xwindow, - Atom xatom, - char **str_p) +gboolean +meta_prop_get_latin1_string (MetaX11Display *x11_display, + Window xwindow, + Atom xatom, + char **str_p) { GetPropertyResults results; *str_p = NULL; - if (!get_property (display, xwindow, xatom, XA_STRING, + if (!get_property (x11_display, xwindow, xatom, XA_STRING, &results)) return FALSE; @@ -399,7 +381,7 @@ utf8_string_from_results (GetPropertyResults *results, *str_p = NULL; if (!validate_or_free_results (results, 8, - results->display->atom_UTF8_STRING, FALSE)) + results->x11_display->atom_UTF8_STRING, FALSE)) return FALSE; if (results->n_items > 0 && @@ -407,41 +389,25 @@ utf8_string_from_results (GetPropertyResults *results, { char *name; - name = XGetAtomName (results->display->xdisplay, results->xatom); + name = XGetAtomName (results->x11_display->xdisplay, results->xatom); meta_warning ("Property %s on window 0x%lx contained invalid UTF-8\n", name, results->xwindow); meta_XFree (name); - XFree (results->prop); + g_free (results->prop); results->prop = NULL; return FALSE; } - *str_p = (char*) results->prop; + *str_p = g_strndup ((char *) results->prop, results->n_items); + + g_free (results->prop); results->prop = NULL; return TRUE; } -LOCAL_SYMBOL gboolean -meta_prop_get_utf8_string (MetaDisplay *display, - Window xwindow, - Atom xatom, - char **str_p) -{ - GetPropertyResults results; - - *str_p = NULL; - - if (!get_property (display, xwindow, xatom, - display->atom_UTF8_STRING, - &results)) - return FALSE; - - return utf8_string_from_results (&results, str_p); -} - -/* this one freakishly returns malloc memory */ +/* this one freakishly returns g_malloc memory */ static gboolean utf8_list_from_results (GetPropertyResults *results, char ***str_p, @@ -456,7 +422,7 @@ utf8_list_from_results (GetPropertyResults *results, *n_str_p = 0; if (!validate_or_free_results (results, 8, - results->display->atom_UTF8_STRING, FALSE)) + results->x11_display->atom_UTF8_STRING, FALSE)) return FALSE; /* I'm not sure this is right, but I'm guessing the @@ -488,13 +454,13 @@ utf8_list_from_results (GetPropertyResults *results, { char *name; - meta_error_trap_push (results->display); - name = XGetAtomName (results->display->xdisplay, results->xatom); - meta_error_trap_pop (results->display); + meta_x11_error_trap_push (results->x11_display); + name = XGetAtomName (results->x11_display->xdisplay, results->xatom); + meta_x11_error_trap_pop (results->x11_display); meta_warning ("Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n", name, results->xwindow, i); meta_XFree (name); - meta_XFree (results->prop); + g_free (results->prop); results->prop = NULL; g_strfreev (retval); @@ -510,44 +476,44 @@ utf8_list_from_results (GetPropertyResults *results, *str_p = retval; *n_str_p = i; - meta_XFree (results->prop); + g_free (results->prop); results->prop = NULL; return TRUE; } -/* returns malloc not Xmalloc memory */ -LOCAL_SYMBOL gboolean -meta_prop_get_utf8_list (MetaDisplay *display, - Window xwindow, - Atom xatom, - char ***str_p, - int *n_str_p) +/* returns g_malloc not Xmalloc memory */ +gboolean +meta_prop_get_utf8_list (MetaX11Display *x11_display, + Window xwindow, + Atom xatom, + char ***str_p, + int *n_str_p) { GetPropertyResults results; *str_p = NULL; - if (!get_property (display, xwindow, xatom, - display->atom_UTF8_STRING, + if (!get_property (x11_display, xwindow, xatom, + x11_display->atom_UTF8_STRING, &results)) return FALSE; return utf8_list_from_results (&results, str_p, n_str_p); } -LOCAL_SYMBOL void -meta_prop_set_utf8_string_hint (MetaDisplay *display, - Window xwindow, - Atom atom, - const char *val) +void +meta_prop_set_utf8_string_hint (MetaX11Display *x11_display, + Window xwindow, + Atom atom, + const char *val) { - meta_error_trap_push (display); - XChangeProperty (display->xdisplay, + meta_x11_error_trap_push (x11_display); + XChangeProperty (x11_display->xdisplay, xwindow, atom, - display->atom_UTF8_STRING, + x11_display->atom_UTF8_STRING, 8, PropModeReplace, (guchar*) val, strlen (val)); - meta_error_trap_pop (display); + meta_x11_error_trap_pop (x11_display); } static gboolean @@ -557,14 +523,13 @@ window_from_results (GetPropertyResults *results, if (!validate_or_free_results (results, 32, XA_WINDOW, TRUE)) return FALSE; - *window_p = *(Window*) results->prop; - XFree (results->prop); + *window_p = *(uint32_t *) results->prop; + g_free (results->prop); results->prop = NULL; return TRUE; } -#ifdef HAVE_XSYNC static gboolean counter_from_results (GetPropertyResults *results, XSyncCounter *counter_p) @@ -574,8 +539,8 @@ counter_from_results (GetPropertyResults *results, TRUE)) return FALSE; - *counter_p = *(XSyncCounter*) results->prop; - XFree (results->prop); + *counter_p = *(uint32_t *) results->prop; + g_free (results->prop); results->prop = NULL; return TRUE; @@ -583,7 +548,7 @@ counter_from_results (GetPropertyResults *results, static gboolean counter_list_from_results (GetPropertyResults *results, - XSyncCounter **counters_p, + uint32_t **counters_p, int *n_counters_p) { if (!validate_or_free_results (results, 32, @@ -591,78 +556,100 @@ counter_list_from_results (GetPropertyResults *results, FALSE)) return FALSE; - *counters_p = (XSyncCounter*) results->prop; + *counters_p = (uint32_t *) results->prop; *n_counters_p = results->n_items; results->prop = NULL; return TRUE; } -#endif -LOCAL_SYMBOL gboolean -meta_prop_get_window (MetaDisplay *display, - Window xwindow, - Atom xatom, - Window *window_p) +gboolean +meta_prop_get_window (MetaX11Display *x11_display, + Window xwindow, + Atom xatom, + Window *window_p) { GetPropertyResults results; *window_p = None; - if (!get_property (display, xwindow, xatom, XA_WINDOW, + if (!get_property (x11_display, xwindow, xatom, XA_WINDOW, &results)) return FALSE; return window_from_results (&results, window_p); } -LOCAL_SYMBOL gboolean -meta_prop_get_cardinal (MetaDisplay *display, - Window xwindow, - Atom xatom, - gulong *cardinal_p) +gboolean +meta_prop_get_cardinal (MetaX11Display *x11_display, + Window xwindow, + Atom xatom, + uint32_t *cardinal_p) { - return meta_prop_get_cardinal_with_atom_type (display, xwindow, xatom, + return meta_prop_get_cardinal_with_atom_type (x11_display, xwindow, xatom, XA_CARDINAL, cardinal_p); } static gboolean cardinal_with_atom_type_from_results (GetPropertyResults *results, Atom prop_type, - gulong *cardinal_p) + uint32_t *cardinal_p) { if (!validate_or_free_results (results, 32, prop_type, TRUE)) return FALSE; - *cardinal_p = *(gulong*) results->prop; -#if GLIB_SIZEOF_LONG == 8 - /* Xlib sign-extends format=32 items, but we want them unsigned */ - *cardinal_p &= 0xffffffff; -#endif - XFree (results->prop); + *cardinal_p = *((uint32_t *) results->prop); + g_free (results->prop); results->prop = NULL; return TRUE; } -LOCAL_SYMBOL gboolean -meta_prop_get_cardinal_with_atom_type (MetaDisplay *display, - Window xwindow, - Atom xatom, - Atom prop_type, - gulong *cardinal_p) +gboolean +meta_prop_get_cardinal_with_atom_type (MetaX11Display *x11_display, + Window xwindow, + Atom xatom, + Atom prop_type, + uint32_t *cardinal_p) { GetPropertyResults results; *cardinal_p = 0; - if (!get_property (display, xwindow, xatom, prop_type, + if (!get_property (x11_display, xwindow, xatom, prop_type, &results)) return FALSE; return cardinal_with_atom_type_from_results (&results, prop_type, cardinal_p); } +static char * +text_property_to_utf8 (Display *xdisplay, + const XTextProperty *prop) +{ + char *ret = NULL; + char **local_list = NULL; + const char *charset = NULL; + int count = 0; + int res; + + res = XmbTextPropertyToTextList (xdisplay, prop, &local_list, &count); + if (res == XNoMemory || res == XLocaleNotSupported || res == XConverterNotFound) + goto out; + + if (count == 0) + goto out; + + if (g_get_charset (&charset)) + ret = g_strdup (local_list[0]); + else + ret = g_convert (local_list[0], -1, "UTF-8", charset, NULL, NULL, NULL); + + out: + XFreeStringList (local_list); + return ret; +} + static gboolean text_property_from_results (GetPropertyResults *results, char **utf8_str_p) @@ -672,60 +659,17 @@ text_property_from_results (GetPropertyResults *results, *utf8_str_p = NULL; tp.value = results->prop; - results->prop = NULL; tp.encoding = results->type; tp.format = results->format; tp.nitems = results->n_items; - *utf8_str_p = meta_text_property_to_utf8 (results->display->xdisplay, - &tp); + *utf8_str_p = text_property_to_utf8 (results->x11_display->xdisplay, &tp); - if (tp.value != NULL) - XFree (tp.value); + g_clear_pointer (&results->prop, g_free); return *utf8_str_p != NULL; } -LOCAL_SYMBOL gboolean -meta_prop_get_text_property (MetaDisplay *display, - Window xwindow, - Atom xatom, - char **utf8_str_p) -{ - GetPropertyResults results; - - if (!get_property (display, xwindow, xatom, AnyPropertyType, - &results)) - return FALSE; - - return text_property_from_results (&results, utf8_str_p); -} - -/* From Xmd.h */ -#ifndef cvtINT32toInt -#if SIZEOF_VOID_P == 8 -#define cvtINT8toInt(val) ((((unsigned int)val) & 0x00000080) ? (((unsigned int)val) | 0xffffffffffffff00) : ((unsigned int)val)) -#define cvtINT16toInt(val) ((((unsigned int)val) & 0x00008000) ? (((unsigned int)val) | 0xffffffffffff0000) : ((unsigned int)val)) -#define cvtINT32toInt(val) ((((unsigned int)val) & 0x80000000) ? (((unsigned int)val) | 0xffffffff00000000) : ((unsigned int)val)) -#define cvtINT8toShort(val) cvtINT8toInt(val) -#define cvtINT16toShort(val) cvtINT16toInt(val) -#define cvtINT32toShort(val) cvtINT32toInt(val) -#define cvtINT8toLong(val) cvtINT8toInt(val) -#define cvtINT16toLong(val) cvtINT16toInt(val) -#define cvtINT32toLong(val) cvtINT32toInt(val) -#else -#define cvtINT8toInt(val) (val) -#define cvtINT16toInt(val) (val) -#define cvtINT32toInt(val) (val) -#define cvtINT8toShort(val) (val) -#define cvtINT16toShort(val) (val) -#define cvtINT32toShort(val) (val) -#define cvtINT8toLong(val) (val) -#define cvtINT16toLong(val) (val) -#define cvtINT32toLong(val) (val) -#endif /* SIZEOF_VOID_P == 8 */ -#endif /* cvtINT32toInt() */ - static gboolean wm_hints_from_results (GetPropertyResults *results, XWMHints **hints_p) @@ -745,23 +689,23 @@ wm_hints_from_results (GetPropertyResults *results, (int) results->n_items, NumPropWMHintsElements - 1); if (results->prop) { - XFree (results->prop); + g_free (results->prop); results->prop = NULL; } return FALSE; } - hints = ag_Xmalloc0 (sizeof (XWMHints)); + hints = g_new0 (XWMHints, 1); raw = (xPropWMHints*) results->prop; hints->flags = raw->flags; hints->input = (raw->input ? True : False); - hints->initial_state = cvtINT32toInt (raw->initialState); + hints->initial_state = raw->initialState; hints->icon_pixmap = raw->iconPixmap; hints->icon_window = raw->iconWindow; - hints->icon_x = cvtINT32toInt (raw->iconX); - hints->icon_y = cvtINT32toInt (raw->iconY); + hints->icon_x = raw->iconX; + hints->icon_y = raw->iconY; hints->icon_mask = raw->iconMask; if (results->n_items >= NumPropWMHintsElements) hints->window_group = raw->windowGroup; @@ -770,7 +714,7 @@ wm_hints_from_results (GetPropertyResults *results, if (results->prop) { - XFree (results->prop); + g_free (results->prop); results->prop = NULL; } @@ -779,28 +723,11 @@ wm_hints_from_results (GetPropertyResults *results, return TRUE; } -LOCAL_SYMBOL gboolean -meta_prop_get_wm_hints (MetaDisplay *display, - Window xwindow, - Atom xatom, - XWMHints **hints_p) -{ - GetPropertyResults results; - - *hints_p = NULL; - - if (!get_property (display, xwindow, xatom, XA_WM_HINTS, - &results)) - return FALSE; - - return wm_hints_from_results (&results, hints_p); -} - static gboolean class_hint_from_results (GetPropertyResults *results, XClassHint *class_hint) { - int len_name, len_class; + int len_name; class_hint->res_class = NULL; class_hint->res_name = NULL; @@ -808,56 +735,20 @@ class_hint_from_results (GetPropertyResults *results, if (!validate_or_free_results (results, 8, XA_STRING, FALSE)) return FALSE; - len_name = strlen ((char *) results->prop); - if (! (class_hint->res_name = ag_Xmalloc (len_name+1))) - { - XFree (results->prop); - results->prop = NULL; - return FALSE; - } - - strcpy (class_hint->res_name, (char *)results->prop); + class_hint->res_name = g_strdup ((char *) results->prop); + len_name = strlen (class_hint->res_name); if (len_name == (int) results->n_items) - len_name--; - - len_class = strlen ((char *)results->prop + len_name + 1); - - if (! (class_hint->res_class = ag_Xmalloc(len_class+1))) - { - XFree(class_hint->res_name); - class_hint->res_name = NULL; - XFree (results->prop); - results->prop = NULL; - return FALSE; - } - - strcpy (class_hint->res_class, (char *)results->prop + len_name + 1); + class_hint->res_class = g_strdup (""); + else + class_hint->res_class = g_strdup ((char *) results->prop + len_name + 1); - XFree (results->prop); + g_free (results->prop); results->prop = NULL; return TRUE; } -LOCAL_SYMBOL gboolean -meta_prop_get_class_hint (MetaDisplay *display, - Window xwindow, - Atom xatom, - XClassHint *class_hint) -{ - GetPropertyResults results; - - class_hint->res_class = NULL; - class_hint->res_name = NULL; - - if (!get_property (display, xwindow, xatom, XA_STRING, - &results)) - return FALSE; - - return class_hint_from_results (&results, class_hint); -} - static gboolean size_hints_from_results (GetPropertyResults *results, XSizeHints **hints_p, @@ -874,44 +765,43 @@ size_hints_from_results (GetPropertyResults *results, if (results->n_items < OldNumPropSizeElements) { - XFree (results->prop); + g_free (results->prop); results->prop = NULL; return FALSE; } raw = (xPropSizeHints*) results->prop; - hints = ag_Xmalloc (sizeof (XSizeHints)); + hints = g_new0 (XSizeHints, 1); - /* XSizeHints misdeclares these as int instead of long */ hints->flags = raw->flags; - hints->x = cvtINT32toInt (raw->x); - hints->y = cvtINT32toInt (raw->y); - hints->width = cvtINT32toInt (raw->width); - hints->height = cvtINT32toInt (raw->height); - hints->min_width = cvtINT32toInt (raw->minWidth); - hints->min_height = cvtINT32toInt (raw->minHeight); - hints->max_width = cvtINT32toInt (raw->maxWidth); - hints->max_height = cvtINT32toInt (raw->maxHeight); - hints->width_inc = cvtINT32toInt (raw->widthInc); - hints->height_inc = cvtINT32toInt (raw->heightInc); - hints->min_aspect.x = cvtINT32toInt (raw->minAspectX); - hints->min_aspect.y = cvtINT32toInt (raw->minAspectY); - hints->max_aspect.x = cvtINT32toInt (raw->maxAspectX); - hints->max_aspect.y = cvtINT32toInt (raw->maxAspectY); + hints->x = raw->x; + hints->y = raw->y; + hints->width = raw->width; + hints->height = raw->height; + hints->min_width = raw->minWidth; + hints->min_height = raw->minHeight; + hints->max_width = raw->maxWidth; + hints->max_height = raw->maxHeight; + hints->width_inc = raw->widthInc; + hints->height_inc = raw->heightInc; + hints->min_aspect.x = raw->minAspectX; + hints->min_aspect.y = raw->minAspectY; + hints->max_aspect.x = raw->maxAspectX; + hints->max_aspect.y = raw->maxAspectY; *flags_p = (USPosition | USSize | PAllHints); if (results->n_items >= NumPropSizeElements) { - hints->base_width= cvtINT32toInt (raw->baseWidth); - hints->base_height= cvtINT32toInt (raw->baseHeight); - hints->win_gravity= cvtINT32toInt (raw->winGravity); + hints->base_width = raw->baseWidth; + hints->base_height = raw->baseHeight; + hints->win_gravity = raw->winGravity; *flags_p |= (PBaseSize | PWinGravity); } hints->flags &= (*flags_p); /* get rid of unwanted bits */ - XFree (results->prop); + g_free (results->prop); results->prop = NULL; *hints_p = hints; @@ -919,37 +809,6 @@ size_hints_from_results (GetPropertyResults *results, return TRUE; } -LOCAL_SYMBOL gboolean -meta_prop_get_size_hints (MetaDisplay *display, - Window xwindow, - Atom xatom, - XSizeHints **hints_p, - gulong *flags_p) -{ - GetPropertyResults results; - - *hints_p = NULL; - *flags_p = 0; - - if (!get_property (display, xwindow, xatom, XA_WM_SIZE_HINTS, - &results)) - return FALSE; - - return size_hints_from_results (&results, hints_p, flags_p); -} - -static AgGetPropertyTask* -get_task (MetaDisplay *display, - Window xwindow, - Atom xatom, - Atom req_type) -{ - return ag_task_create (display->xdisplay, - xwindow, - xatom, 0, G_MAXLONG, - False, req_type); -} - static char* latin1_to_utf8 (const char *text) { @@ -968,14 +827,15 @@ latin1_to_utf8 (const char *text) return g_string_free (str, FALSE); } -LOCAL_SYMBOL void -meta_prop_get_values (MetaDisplay *display, - Window xwindow, - MetaPropValue *values, - int n_values) +void +meta_prop_get_values (MetaX11Display *x11_display, + Window xwindow, + MetaPropValue *values, + int n_values) { int i; - AgGetPropertyTask **tasks; + xcb_get_property_cookie_t *tasks; + xcb_connection_t *xcb_conn = XGetXCBConnection (x11_display->xdisplay); meta_verbose ("Requesting %d properties of 0x%lx at once\n", n_values, xwindow); @@ -983,7 +843,7 @@ meta_prop_get_values (MetaDisplay *display, if (n_values == 0) return; - tasks = g_new0 (AgGetPropertyTask*, n_values); + tasks = g_new0 (xcb_get_property_cookie_t, n_values); /* Start up tasks. The "values" array can have values * with atom == None, which means to ignore that element. @@ -1004,7 +864,7 @@ meta_prop_get_values (MetaDisplay *display, break; case META_PROP_VALUE_UTF8_LIST: case META_PROP_VALUE_UTF8: - values[i].required_type = display->atom_UTF8_STRING; + values[i].required_type = x11_display->atom_UTF8_STRING; break; case META_PROP_VALUE_STRING: case META_PROP_VALUE_STRING_AS_UTF8: @@ -1043,25 +903,24 @@ meta_prop_get_values (MetaDisplay *display, } if (values[i].atom != None) - tasks[i] = get_task (display, xwindow, - values[i].atom, values[i].required_type); - + tasks[i] = async_get_property (xcb_conn, xwindow, values[i].atom, values[i].required_type); ++i; } /* Get replies for all our tasks */ meta_topic (META_DEBUG_SYNC, "Syncing to get %d GetProperty replies in %s\n", n_values, G_STRFUNC); - XSync (display->xdisplay, False); + XSync (x11_display->xdisplay, False); /* Collect results, should arrive in order requested */ i = 0; while (i < n_values) { - AgGetPropertyTask *task; GetPropertyResults results; - if (tasks[i] == NULL) + /* We're relying on the fact that sequence numbers can never be zero + * in Xorg. This is a bit disgusting... */ + if (tasks[i].sequence == 0) { /* Probably values[i].type was None, or ag_task_create() * returned NULL. @@ -1070,11 +929,7 @@ meta_prop_get_values (MetaDisplay *display, goto next; } - task = ag_get_next_completed_task (display->xdisplay); - g_assert (task != NULL); - g_assert (ag_task_have_reply (task)); - - results.display = display; + results.x11_display = x11_display; results.xwindow = xwindow; results.xatom = values[i].atom; results.prop = NULL; @@ -1083,19 +938,9 @@ meta_prop_get_values (MetaDisplay *display, results.bytes_after = 0; results.format = 0; - if (ag_task_get_reply_and_free (task, - &results.type, &results.format, - &results.n_items, - &results.bytes_after, - &results.prop) != Success || - results.type == None) + if (!async_get_property_finish (xcb_conn, tasks[i], &results)) { values[i].type = META_PROP_VALUE_INVALID; - if (results.prop) - { - XFree (results.prop); - results.prop = NULL; - } goto next; } @@ -1127,18 +972,9 @@ meta_prop_get_values (MetaDisplay *display, else { char *new_str; - char *xmalloc_new_str; - new_str = latin1_to_utf8 (values[i].v.str); - xmalloc_new_str = ag_Xmalloc (strlen (new_str) + 1); - if (xmalloc_new_str != NULL) - { - strcpy (xmalloc_new_str, new_str); - meta_XFree (values[i].v.str); - values[i].v.str = xmalloc_new_str; - } - - free (new_str); + g_free (values[i].v.str); + values[i].v.str = new_str; } break; case META_PROP_VALUE_MOTIF_HINTS: @@ -1187,7 +1023,6 @@ meta_prop_get_values (MetaDisplay *display, &values[i].v.size_hints.flags)) values[i].type = META_PROP_VALUE_INVALID; break; -#ifdef HAVE_XSYNC case META_PROP_VALUE_SYNC_COUNTER: if (!counter_from_results (&results, &values[i].v.xcounter)) @@ -1199,24 +1034,13 @@ meta_prop_get_values (MetaDisplay *display, &values[i].v.xcounter_list.n_counters)) values[i].type = META_PROP_VALUE_INVALID; break; -#else - case META_PROP_VALUE_SYNC_COUNTER: - case META_PROP_VALUE_SYNC_COUNTER_LIST: - values[i].type = META_PROP_VALUE_INVALID; - if (results.prop) - { - XFree (results.prop); - results.prop = NULL; - } - break; -#endif } next: ++i; } - free (tasks); + g_free (tasks); } static void @@ -1228,49 +1052,49 @@ free_value (MetaPropValue *value) break; case META_PROP_VALUE_UTF8: case META_PROP_VALUE_STRING: + g_free (value->v.str); + break; case META_PROP_VALUE_STRING_AS_UTF8: - meta_XFree (value->v.str); + g_free (value->v.str); break; case META_PROP_VALUE_MOTIF_HINTS: - meta_XFree (value->v.motif_hints); + g_free (value->v.motif_hints); break; case META_PROP_VALUE_CARDINAL: break; case META_PROP_VALUE_WINDOW: break; case META_PROP_VALUE_ATOM_LIST: - meta_XFree (value->v.atom_list.atoms); + g_free (value->v.atom_list.atoms); break; case META_PROP_VALUE_TEXT_PROPERTY: - meta_XFree (value->v.str); + g_free (value->v.str); break; case META_PROP_VALUE_WM_HINTS: - meta_XFree (value->v.wm_hints); + g_free (value->v.wm_hints); break; case META_PROP_VALUE_CLASS_HINT: - meta_XFree (value->v.class_hint.res_class); - meta_XFree (value->v.class_hint.res_name); + g_free (value->v.class_hint.res_class); + g_free (value->v.class_hint.res_name); break; case META_PROP_VALUE_SIZE_HINTS: - meta_XFree (value->v.size_hints.hints); + g_free (value->v.size_hints.hints); break; case META_PROP_VALUE_UTF8_LIST: g_strfreev (value->v.string_list.strings); break; case META_PROP_VALUE_CARDINAL_LIST: - meta_XFree (value->v.cardinal_list.cardinals); + g_free (value->v.cardinal_list.cardinals); break; case META_PROP_VALUE_SYNC_COUNTER: break; -#ifdef HAVE_XSYNC case META_PROP_VALUE_SYNC_COUNTER_LIST: - meta_XFree (value->v.xcounter_list.counters); + g_free (value->v.xcounter_list.counters); break; -#endif } } -LOCAL_SYMBOL void +void meta_prop_free_values (MetaPropValue *values, int n_values) { diff --git a/src/x11/xprops.h b/src/x11/xprops.h new file mode 100644 index 000000000..b8d723f07 --- /dev/null +++ b/src/x11/xprops.h @@ -0,0 +1,196 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* Mutter X property convenience routines */ + +/* + * Copyright (C) 2001 Havoc Pennington + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef META_XPROPS_H +#define META_XPROPS_H + +#include <X11/Xutil.h> +#include <X11/extensions/sync.h> + +#include "meta/display.h" + +/* Copied from Lesstif by way of GTK. Rudimentary docs can be + * found in some Motif reference guides online. + */ +typedef struct { + uint32_t flags; + uint32_t functions; + uint32_t decorations; + uint32_t input_mode; + uint32_t status; +} MotifWmHints, MwmHints; + +#define MWM_HINTS_FUNCTIONS (1L << 0) +#define MWM_HINTS_DECORATIONS (1L << 1) +#define MWM_HINTS_INPUT_MODE (1L << 2) +#define MWM_HINTS_STATUS (1L << 3) + +#define MWM_FUNC_ALL (1L << 0) +#define MWM_FUNC_RESIZE (1L << 1) +#define MWM_FUNC_MOVE (1L << 2) +#define MWM_FUNC_MINIMIZE (1L << 3) +#define MWM_FUNC_MAXIMIZE (1L << 4) +#define MWM_FUNC_CLOSE (1L << 5) + +#define MWM_DECOR_ALL (1L << 0) +#define MWM_DECOR_BORDER (1L << 1) +#define MWM_DECOR_RESIZEH (1L << 2) +#define MWM_DECOR_TITLE (1L << 3) +#define MWM_DECOR_MENU (1L << 4) +#define MWM_DECOR_MINIMIZE (1L << 5) +#define MWM_DECOR_MAXIMIZE (1L << 6) + +#define MWM_INPUT_MODELESS 0 +#define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1 +#define MWM_INPUT_SYSTEM_MODAL 2 +#define MWM_INPUT_FULL_APPLICATION_MODAL 3 +#define MWM_INPUT_APPLICATION_MODAL MWM_INPUT_PRIMARY_APPLICATION_MODAL + +#define MWM_TEAROFF_WINDOW (1L<<0) + +/* These all return the memory from Xlib, so require an XFree() + * when they return TRUE. They return TRUE on success. + */ +gboolean meta_prop_get_motif_hints (MetaX11Display *x11_display, + Window xwindow, + Atom xatom, + MotifWmHints **hints_p); +gboolean meta_prop_get_cardinal_list (MetaX11Display *x11_display, + Window xwindow, + Atom xatom, + uint32_t **cardinals_p, + int *n_cardinals_p); +gboolean meta_prop_get_latin1_string (MetaX11Display *x11_display, + Window xwindow, + Atom xatom, + char **str_p); +gboolean meta_prop_get_utf8_list (MetaX11Display *x11_display, + Window xwindow, + Atom xatom, + char ***str_p, + int *n_str_p); +void meta_prop_set_utf8_string_hint + (MetaX11Display *x11_display, + Window xwindow, + Atom atom, + const char *val); +gboolean meta_prop_get_window (MetaX11Display *x11_display, + Window xwindow, + Atom xatom, + Window *window_p); +gboolean meta_prop_get_cardinal (MetaX11Display *x11_display, + Window xwindow, + Atom xatom, + uint32_t *cardinal_p); +gboolean meta_prop_get_cardinal_with_atom_type (MetaX11Display *x11_display, + Window xwindow, + Atom xatom, + Atom prop_type, + uint32_t *cardinal_p); + +typedef enum +{ + META_PROP_VALUE_INVALID, + META_PROP_VALUE_UTF8, + META_PROP_VALUE_STRING, + META_PROP_VALUE_STRING_AS_UTF8, + META_PROP_VALUE_MOTIF_HINTS, + META_PROP_VALUE_CARDINAL, + META_PROP_VALUE_WINDOW, + META_PROP_VALUE_CARDINAL_LIST, + META_PROP_VALUE_UTF8_LIST, + META_PROP_VALUE_ATOM_LIST, + META_PROP_VALUE_TEXT_PROPERTY, /* comes back as UTF-8 string */ + META_PROP_VALUE_WM_HINTS, + META_PROP_VALUE_CLASS_HINT, + META_PROP_VALUE_SIZE_HINTS, + META_PROP_VALUE_SYNC_COUNTER, /* comes back as CARDINAL */ + META_PROP_VALUE_SYNC_COUNTER_LIST /* comes back as CARDINAL */ +} MetaPropValueType; + +/* used to request/return/store property values */ +typedef struct +{ + MetaPropValueType type; + Atom atom; + Atom required_type; /* autofilled if None */ + + union + { + char *str; + MotifWmHints *motif_hints; + Window xwindow; + uint32_t cardinal; + XWMHints *wm_hints; + XClassHint class_hint; + XSyncCounter xcounter; + struct + { + uint32_t *counters; + int n_counters; + } xcounter_list; + + struct + { + XSizeHints *hints; + unsigned long flags; + } size_hints; + + struct + { + uint32_t *cardinals; + int n_cardinals; + } cardinal_list; + + struct + { + char **strings; + int n_strings; + } string_list; + + struct + { + uint32_t *atoms; + int n_atoms; + } atom_list; + + } v; + +} MetaPropValue; + +/* Each value has type and atom initialized. If there's an error, + * or property is unset, type comes back as INVALID; + * else type comes back as it originated, and the data + * is filled in. + */ +void meta_prop_get_values (MetaX11Display *x11_display, + Window xwindow, + MetaPropValue *values, + int n_values); + +void meta_prop_free_values (MetaPropValue *values, + int n_values); + +#endif + + + + diff --git a/tools/announce-wrangler.py b/tools/announce-wrangler.py new file mode 100644 index 000000000..cf9248642 --- /dev/null +++ b/tools/announce-wrangler.py @@ -0,0 +1,159 @@ +import commands +import xml.dom.minidom +import glob +import wordpresslib # http://www.blackbirdblog.it/programmazione/progetti/28 +import ConfigParser +import os +import re + +doaps = glob.glob("*.doap") + +if len(doaps)==0: + print 'Please run this from the top-level directory.' + +description=str(xml.dom.minidom.parse(doaps[0]).getElementsByTagName('shortdesc')[0].firstChild.toxml().strip()) + +program_name = doaps[0][:-5] +print program_name + +markup = { + 'text': { + 'open': ' *', + 'newline': ' ', + 'close': '', + }, + 'html': { + 'open': '<li>', + 'newline': '', + 'close': '</li>', + }, +} + +def text_list(list, type): + result = [] + for entry in list: + result.append(markup[type]['open']) + for word in entry.split(): + if len(result[-1]+word)>75: + result.append(markup[type]['newline']) + result[-1] = result[-1] + ' ' + word + if result[-1].strip()=='': + result = result[:-1] + result[-1] = result[-1] + markup[type]['close'] + return '\n'.join(result) + +news = file('NEWS') +news_entry = [] +header_count = 0 + +while header_count<2: + line = news.readline().replace('\n', '') + news_entry.append(line) + if line.startswith('='): + header_count = header_count + 1 + +news.close() + +version = news_entry[0] +news_entry = news_entry[2:-2] + +print version +majorminor = '.'.join(version.split('.')[:2]) +md5s = commands.getoutput('ssh master.gnome.org md5sum /ftp/pub/GNOME/sources/metacity/%s/%s-%s.tar*' % (majorminor, program_name, version)).split() +if len(md5s)!=4: + print 'WARNING: There were not two known tarballs' + +md5_values = {} + +for i in range(0, len(md5s), 2): + a = md5s[i+1] + md5_values[a[a.rindex('.'):]] = md5s[i] + +print md5_values + +changes = [] +translations = '' + +reading_changes = False +reading_translations = False +for line in news_entry: + line = line.replace('(#', '(GNOME bug ').strip() + if line.startswith('-'): + changes.append(line[2:]) + reading_changes = True + elif reading_changes: + if line=='': + reading_changes = False + else: + changes[-1] = changes[-1] + ' ' + line + elif line=='Translations': + reading_translations = True + elif reading_translations: + translations = translations + ' ' + line + +translations = translations[1:] + +text_links = [] +for i in ('.bz2', '.gz'): + text_links.append('%s http://download.gnome.org/sources/metacity/%s/%s-%s.tar%s' % ( + md5_values[i], majorminor, program_name, version, i)) + +text_version = """\ +What is it ? +============ +%s + +What's changed ? +================ +%s + +Translations: +%s + +Where can I get it ? +==================== +%s""" % (text_list([description], 'text'), + text_list(changes, 'text'), + text_list([translations], 'text'), + text_list(text_links, 'text')) + +print "============ x8 x8 x8 ===== SEND THIS TO gnome-announce-list" +print text_version +print "============ x8 x8 x8 ===== ENDS" + +translations = re.sub('\((.*)\)', + '(<a href="http://svn.gnome.org/viewvc/metacity/trunk/po/\\1.po">\\1</a>)', + translations) + +html_version = """\ +<b>What is it ?</b><br /> +<ul>%s</ul> + +<b>What's changed ?</b><br /> +<ul>%s</ul> + +<i>Translations:</i><br /> +<ul>%s</ul> + +<b>Where can I get it ?</b><br /> +<ul>%s</ul>""" % (text_list([description], 'html'), + text_list(changes, 'html'), + text_list([translations], 'html'), + text_list(text_links, 'html')) + +cp = ConfigParser.ConfigParser() +cp.read(os.environ['HOME']+'/.config/metacity/tools.ini') + +wp = wordpresslib.WordPressClient( + cp.get('release-wrangler', 'blogurl'), + cp.get('release-wrangler', 'bloguser'), + cp.get('release-wrangler', 'blogpass')) +wp.selectBlog(cp.getint('release-wrangler', 'blognumber')) +post = wordpresslib.WordPressPost() +post.title = '%s %s released' % (program_name, version) +post.description = html_version +# appears to have been turned off-- ask jdub +#idPost = wp.newPost(post, False) + +print html_version + diff --git a/tools/commit-wrangler.py b/tools/commit-wrangler.py new file mode 100644 index 000000000..0ec68b71d --- /dev/null +++ b/tools/commit-wrangler.py @@ -0,0 +1,111 @@ +#!/usr/bin/python +# +# commit-wrangler.py - basic script to commit patches, primarily for +# Metacity, might be useful for others. In early stages of +# development. +# +# Copyright (C) 2008 Thomas Thurman +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see <http://www.gnu.org/licenses/>. + +import time +import commands +import sys +import os +import posixpath +import ConfigParser +import re + +# FIXME: Needs tidying into separate functions. + +# FIXME: Some of this is duplicated from release-wrangler. +# This should go in a common library when the dust has settled. + +# FIXME: Some way of updating Bugzilla when we mention a bug, +# and including the revision number, would be really useful. + +# FIXME: This should co-operate with patch-wrangler in that +# p-w should find out the name of a patch's submitter from bugzilla +# and store it in a dotfile, and then we can use it here. +# Also, it should find out and store the bug number, so we can +# write it as "(Bug #nnn)", which will make the previous paragraph's +# idea even more useful. + +def get_up_to_date(): + "First step is always to get up to date." + os.system("svn up") + +def report_error(message): + print message + sys.exit(255) + +def favourite_editor(): + e = os.environ + if e.has_key('VISUAL'): return e['VISUAL'] + if e.has_key('EDITOR'): return e['EDITOR'] + if os.access('/usr/bin/nano', os.F_OK): + return '/usr/bin/nano' + report_error("I can't find an editor for you!") + +def wordwrap(str, prefix=''): + "Really simple wordwrap" + + # Ugly hack: + # We know that all open brackets are preceded by spaces. + # We don't want to split on these spaces. Therefore: + str = str.replace(' (','(') + + result = [''] + for word in str.split(): + + if result[-1]=='': + candidate = prefix + word + else: + candidate = '%s %s' % (result[-1], word) + + if len(candidate)>80: + result.append(prefix+word) + else: + result[-1] = candidate + + return '\n'.join(result).replace('(',' (') + +##################### + +change_filename = 'ChangeLog' + +get_up_to_date() + +cp = ConfigParser.ConfigParser() +cp.read(os.environ['HOME']+'/.config/metacity/tools.ini') + +os.environ['CHANGE_LOG_NAME'] = cp.get('commit-wrangler', 'name') +os.environ['CHANGE_LOG_EMAIL_ADDRESS'] = cp.get('commit-wrangler', 'address') + +print commands.getoutput('moap cl prep') + +time_before = os.stat(change_filename)[8] +os.system(favourite_editor()+' +6 %s ' % (change_filename)) + +if os.stat(change_filename)[8] == time_before: + print 'No change; aborting:' + print commands.getoutput('svn revert '+change_filename) + sys.exit(0) + +# Update the changelog + +checkin = commands.getoutput("moap cl ci") + +print re.sub(".*Committed revision (\\d+).*", 'http://svn.gnome.org/viewvc/metacity?rev=\\1&view=rev', checkin) + diff --git a/tools/patch-wrangler.py b/tools/patch-wrangler.py new file mode 100644 index 000000000..c5e80c62f --- /dev/null +++ b/tools/patch-wrangler.py @@ -0,0 +1,70 @@ +#!/usr/bin/python + +# Little script to grab a patch, compile it, and make it. + +# Copyright (C) 2008 Thomas Thurman +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see <http://www.gnu.org/licenses/>. + + +import os +import sys +import posixpath + +# FIXME: What would be lovely is an Epiphany extension to call this from Bugzilla pages + +# FIXME: Should be possible (but currently isn't) to get this from the patch number +program = 'metacity' + +if len(sys.argv)<2: + print 'Specify patch number' + sys.exit(255) + +patchnum = sys.argv[1] + +patchdir = posixpath.expanduser('~/patch/%s/%s' % (program, patchnum)) + +os.makedirs(patchdir) +os.chdir(patchdir) + +if os.system("svn co svn+ssh://svn.gnome.org/svn/%s/trunk ." % (program))!=0: + print "Checkout failed." + sys.exit(255) + +if os.system("wget http://bugzilla.gnome.org/attachment.cgi?id=%s -O - -q|patch -p 0" % (patchnum))!=0: + print "Patch failed." + sys.exit(255) + +if os.system("./autogen.sh")!=0: + print "Autogen failed." + sys.exit(255) + +if os.system("make")!=0: + print "Make failed." + sys.exit(255) + +print +print "It all seems to have worked. Don't look so surprised." +print "Dropping you into a new shell now so you're in the right" +print "directory; this does mean you'll have to exit twice when" +print "you're finished." +print + +shell = '/bin/sh' +if os.environ.has_key('SHELL'): + shell = os.environ['SHELL'] + +if os.system(shell): + print "Couldn't launch the shell, though." + sys.exit(255) diff --git a/tools/release-wrangler.py b/tools/release-wrangler.py new file mode 100644 index 000000000..1dcd5fe33 --- /dev/null +++ b/tools/release-wrangler.py @@ -0,0 +1,375 @@ +#!/usr/bin/python +# +# release-wrangler.py - very basic release system, primarily for +# Metacity, might be useful for others. In very early stages of +# development. +# +# Copyright (C) 2008 Thomas Thurman +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see <http://www.gnu.org/licenses/>. + +import os +import posixpath +import re +import sys +import commands +import time +import commands + +def report_error(message): + print message + sys.exit(255) + +def get_up_to_date(): + "First step is always to get up to date." + os.system("svn up") + +# yes, I know this is MY username. I will come back and fix it +# later, but for now there is a lot else to do. FIXME +your_username = 'Thomas Thurman <tthurman@gnome.org>' + +def changelog_and_checkin(filename, message): + changelog = open('ChangeLog.tmp', 'w') + changelog.write('%s %s\n\n * %s: %s\n\n' % ( + time.strftime('%Y-%m-%d',time.gmtime()), + your_username, + filename, + message)) + + for line in open('ChangeLog').readlines(): + changelog.write(line) + + changelog.close() + os.rename('ChangeLog.tmp', 'ChangeLog') + + if os.system('svn commit -m "%s"' % (message.replace('"','\\"')))!=0: + report_error("Could not commit; bailing.") + +def check_we_are_up_to_date(): + changed = [] + for line in commands.getoutput('/usr/bin/svn status').split('\n'): + if line!='' and (line[0]=='C' or line[0]=='M'): + if line.find('release-wrangler.py')==-1 and line.find('ChangeLog')==-1: + # we should be insensitive to changes in this script itself + # to avoid chicken-and-egg problems + changed.append(line[1:].lstrip()) + + if changed: + report_error('These files are out of date; I can\'t continue until you fix them: ' + \ + ', '.join(changed)) + +def version_numbers(): + # FIXME: This is all very metacity-specific. Compare fusa, etc + """Okay, read through configure.in and find who and where we are. + + We also try to figure out where the next micro version number + will be; some programs (e.g. Metacity) use a custom numbering + scheme, and if they have a list of numbers on the line before the + micro version then that will be used. Otherwise we will just + increment.""" + + version = {} + previous_line = '' + for line in file("configure.in").readlines(): + product_name = re.search("^AC_INIT\(\[([^\]]*)\]", line) + if product_name: + version['name'] = product_name.group(1) + + version_number = re.search("^m4_define\(\[.*_(.*)_version\], \[(\d+)\]", line) + + if version_number: + version_type = version_number.group(1) + version_value = int(version_number.group(2)) + + version[version_type] = version_value + + if version_type == 'micro': + group_of_digits = re.search("^\#\s*([0-9, ]+)\n$", previous_line) + if group_of_digits: + versions = [int(x) for x in group_of_digits.group(1).split(',')] + + if version_value in versions: + try: + version_index = versions.index(version_value)+1 + + if versions[version_index] == version['micro']: + # work around metacity giving "1" twice + version_index += 1 + + version['micro_next'] = versions[version_index] + except: + report_error("You gave a list of micro version numbers, but we've used them up!") + else: + report_error("You gave a list of micro version numbers, but the current one wasn't in it! Current is %s and your list is %s" % ( + `version_value`, `versions`)) + + previous_line = line + + if not 'micro_next' in version: + version['micro_next'] = version['micro']+1 + + version['string'] = '%(major)s.%(minor)s.%(micro)s' % (version) + version['filename'] = '%(name)s-%(string)s.tar.gz' % (version) + + return version + +def check_file_does_not_exist(version): + if os.access(version['filename'], os.F_OK): + report_error("Sorry, you already have a file called %s! Please delete it or move it first." % (version['filename'])) + +def is_date(str): + return len(str)>4 and str[4]=='-' + +def scan_changelog(version): + changelog = file("ChangeLog").readlines() + + # Find the most recent release. + + release_date = None + + for line in changelog: + if is_date(line): + release_date = line[:10] + + if "Post-release bump to" in line: + changelog = changelog[:changelog.index(line)+1] + break + + contributors = {} + thanks = '' + entries = [] + + def assumed_surname(name): + if name=='': return '' + # might get more complicated later, but for now... + return name.split()[-1] + + def assumed_forename(name): + if name=='': return '' + return name.split()[0] + + bug_re = re.compile('bug \#?(\d+)', re.IGNORECASE) + hash_re = re.compile('\#(\d+)') + + for line in changelog: + if is_date(line): + line = line[10:].lstrip() + line = line[:line.find('<')].rstrip() + contributors[assumed_surname(line)] = line + entries.append('(%s)' % (assumed_forename(line))) + else: + match = bug_re.search(line) + if not match: match = hash_re.search(line) + if match: + entries[-1] += ' (#%s)' % (match.group(1)) + + # FIXME: getting complex enough we should be returning a dictionary + return (contributors, changelog, entries, release_date) + +def wordwrap(str, prefix=''): + "Really simple wordwrap" + + # Ugly hack: + # We know that all open brackets are preceded by spaces. + # We don't want to split on these spaces. Therefore: + str = str.replace(' (','(') + + result = [''] + for word in str.split(): + + if result[-1]=='': + candidate = prefix + word + else: + candidate = '%s %s' % (result[-1], word) + + if len(candidate)>80: + result.append(prefix+word) + else: + result[-1] = candidate + + return '\n'.join(result).replace('(',' (') + +def favourite_editor(): + e = os.environ + if e.has_key('VISUAL'): return e['VISUAL'] + if e.has_key('EDITOR'): return e['EDITOR'] + if os.access('/usr/bin/nano', os.F_OK): + return '/usr/bin/nano' + report_error("I can't find an editor for you!") + +def edit_news_entry(version): + + # FIXME: still needs a lot of tidying up. Translator stuff especially needs to be + # factored out into a separate function. + + (contributors, changelog, entries, release_date) = scan_changelog(version) + + contributors_list = contributors.keys() + contributors_list.sort() + thanksline = ', '.join([contributors[x] for x in contributors_list]) + thanksline = thanksline.replace(contributors[contributors_list[-1]], 'and '+contributors[contributors_list[-1]]) + + thanks = '%s\n%s\n\n' % (version['string'], '='*len(version['string'])) + thanks += wordwrap('Thanks to %s for improvements in this version.' % (thanksline)) + thanks += '\n\n' + for line in entries: + thanks += ' - xxx %s\n' % (line) + + # and now pick up the translations. + + translations = {} + language_re = re.compile('\*\s*(.+)\.po') + + for line in file("po/ChangeLog").readlines(): + match = language_re.search(line) + if match: + translations[match.group(1)] = 1 + if is_date(line) and line[:10]<release_date: + break + + translator_list = translations.keys() + translator_list.sort() + + last_translator_re = re.compile('Last-Translator:([^<"]*)', re.IGNORECASE) + + def translator_name(language): + name = 'unknown' + + if ',' in language: + language = language[:language.find(',')].replace('.po','') + + filename = 'po/%s.po' % (language) + + if not os.access(filename, os.F_OK): + # Never mind the translator being unknown, we don't even + # know about the language! + return 'Mystery translator (%s)' % (language) + + for line in file(filename).readlines(): + match = last_translator_re.search(line) + if match: + name = match.group(1).rstrip().lstrip() + break + + return "%s (%s)" % (name, language) + + thanks += '\nTranslations\n' + thanks += wordwrap(', '.join([translator_name(x) for x in translator_list]), ' ') + thanks += '\n\n' + + changes = '## '+ ' '.join(changelog).replace('\n', '\n## ') + + filename = posixpath.expanduser("~/.release-wrangler-%(name)s-%(string)s.txt" % version) + tmp = open(filename, 'w') + tmp.write('## You are releasing %(name)s, version %(major)s.%(minor)s.%(micro)s.\n' % version) + tmp.write('## The text at the foot of the page is the part of the ChangeLog which\n') + tmp.write('## has changed since the last release. Please summarise it.\n') + tmp.write('## Anything preceded by a # is ignored.\n') + tmp.write(thanks) + tmp.write(changes) + tmp.close() + + os.system(favourite_editor()+' +6 %s ' % (filename)) + # FIXME: if they abort, would be useful to abort here too + + # Write it out to NEWS + + version['announcement'] = '' + + news_tmp = open('NEWS.tmp', 'a') + for line in open(filename, 'r').readlines(): + if line=='' or line[0]!='#': + news_tmp.write(line) + version['announcement'] += line + + for line in open('NEWS').readlines(): + news_tmp.write(line) + + news_tmp.close() + + os.rename('NEWS.tmp', 'NEWS') + changelog_and_checkin('NEWS', '%(major)s.%(minor)s.%(micro)s release.' % (version)) + +def build_it_all(version): + "Now build the thing." + autogen_prefix= '/prefix' # FIXME: this is specific to tthurman's laptop! + + # FIXME: These should use os.system + + if os.spawnl(os.P_WAIT, './autogen.sh', './autogen.sh', '--prefix', autogen_prefix) != 0: + print 'autogen failed' + sys.exit(255) + + if os.spawnl(os.P_WAIT, '/usr/bin/make', '/usr/bin/make') != 0: + print 'make failed' + sys.exit(255) + + if os.spawnl(os.P_WAIT, '/usr/bin/make', '/usr/bin/make', 'install') != 0: + print 'install failed' + sys.exit(255) + + if os.spawnl(os.P_WAIT, '/usr/bin/make', '/usr/bin/make', 'distcheck') != 0: + print 'distcheck failed' + sys.exit(255) + + if not os.access(version['filename'], os.F_OK): + print "Sorry, we don't appear to have a file called %s!" % (archive_filename) + sys.exit(255) + +def upload(version): + # No, we won't have a configuration option to set your name on master.g.o; that's + # what ~/.ssh/config is for. + + print "Uploading..." + upload_result = commands.getstatusoutput('scp %s master.gnome.org:' % (version['filename'])) + + if upload_result[0]!=0: + report_error("There appears to have been an uploading problem: %d\n%s\n" % (upload_result[0], upload_result[1])) + +def increment_version(version): + configure_in = file('configure.in.tmp', 'w') + for line in file('configure.in'): + if re.search("^m4_define\(\[.*_micro_version\], \[(\d+)\]", line): + line = line.replace('[%(micro)s]' % version, '[%(micro_next)s]' % version) + configure_in.write(line) + + configure_in.close() + os.rename('configure.in.tmp', 'configure.in') + + changelog_and_checkin('configure.in', 'Post-release bump to %(major)s.%(minor)s.%(micro_next)s.' % version) + +def tag_the_release(version): + version['ucname'] = version['name'].upper() + if os.system("svn cp -m release . svn+ssh://svn.gnome.org/svn/%(name)s/tags/%(ucname)s_%(major)s_%(minor)s_%(micro)s" % (version))!=0: + report_error("Could not tag; bailing.") + +def md5s(version): + return commands.getstatusoutput('ssh master.gnome.org "cd /ftp/pub/GNOME/sources/%(name)s/%(major)s.%(minor)s/;md5sum $(name)s-%(major)s.%(minor)s.%(micro)s.tar*"' % (version)) + +def main(): + get_up_to_date() + check_we_are_up_to_date() + version = version_numbers() + check_file_does_not_exist(version) + edit_news_entry(version) + build_it_all(version) + tag_the_release(version) + increment_version(version) + upload(version) + print version['announcement'] + print "-- Done --" + +if __name__=='__main__': + main() + From 41536813ca6deb2b3be03c57f80950e955e62919 Mon Sep 17 00:00:00 2001 From: Michael Webster <miketwebster@gmail.com> Date: Thu, 7 Oct 2021 14:55:13 -0400 Subject: [PATCH 02/36] Restore x root window backgrounds. --- data/org.cinnamon.muffin.gschema.xml.in | 16 + src/compositor/compositor.c | 30 +- src/compositor/meta-compositor-x11.c | 12 + src/core/prefs.c | 15 + src/meson.build | 4 + src/meta/common.h | 10 + src/meta/compositor-mutter.h | 3 + src/meta/meson.build | 3 +- src/meta/meta-x11-background-actor.h | 49 ++ src/meta/prefs.h | 3 + src/x11/meta-x11-background-actor-private.h | 18 + src/x11/meta-x11-background-actor.c | 694 ++++++++++++++++++++ src/x11/meta-x11-background.c | 263 ++++++++ src/x11/meta-x11-background.h | 27 + src/x11/meta-x11-display-private.h | 2 + src/x11/meta-x11-display.c | 1 + 16 files changed, 1148 insertions(+), 2 deletions(-) create mode 100644 src/meta/meta-x11-background-actor.h create mode 100644 src/x11/meta-x11-background-actor-private.h create mode 100644 src/x11/meta-x11-background-actor.c create mode 100644 src/x11/meta-x11-background.c create mode 100644 src/x11/meta-x11-background.h diff --git a/data/org.cinnamon.muffin.gschema.xml.in b/data/org.cinnamon.muffin.gschema.xml.in index 4f2d7da0c..feb4d1409 100644 --- a/data/org.cinnamon.muffin.gschema.xml.in +++ b/data/org.cinnamon.muffin.gschema.xml.in @@ -1,4 +1,10 @@ <schemalist> + <enum id="background_transition"> + <value value="0" nick="none"/> + <value value="1" nick="fade-in"/> + <value value="2" nick="blend"/> + </enum> + <schema id="org.cinnamon.muffin" path="/org/cinnamon/muffin/" gettext-domain="@GETTEXT_DOMAIN@"> @@ -102,6 +108,16 @@ </description> </key> + <key name="background-transition" enum="background_transition"> + <default>'blend'</default> + <summary>Background transition</summary> + <description>The type of animation performed when changing background. + "none" means no animation at all. + "fade-in" means the old background switches to black and the new background appears with a fade-in effect. + "blend" means the old background disappears as the new background appears with a fade-in effect. + </description> + </key> + <key name="experimental-features" type="as"> <default>[]</default> <summary>Enable experimental features</summary> diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index e56aed0b2..8329bff96 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -76,6 +76,7 @@ #include "meta/meta-background-group.h" #include "meta/meta-shadow-factory.h" #include "meta/meta-x11-errors.h" +#include "meta/meta-x11-background-actor.h" #include "meta/prefs.h" #include "meta/window.h" #include "x11/meta-x11-display-private.h" @@ -114,6 +115,8 @@ typedef struct _MetaCompositorPrivate ClutterActor *top_window_group; ClutterActor *feedback_group; + ClutterActor *background_actor; + GList *windows; CoglContext *context; @@ -572,7 +575,9 @@ meta_compositor_manage (MetaCompositor *compositor) priv->window_group = meta_window_group_new (display); priv->top_window_group = meta_window_group_new (display); priv->feedback_group = meta_window_group_new (display); + priv->background_actor = meta_x11_background_actor_new_for_display (display); + clutter_actor_add_child (priv->window_group, priv->background_actor); clutter_actor_add_child (priv->stage, priv->window_group); clutter_actor_add_child (priv->stage, priv->top_window_group); clutter_actor_add_child (priv->stage, priv->feedback_group); @@ -580,6 +585,8 @@ meta_compositor_manage (MetaCompositor *compositor) META_COMPOSITOR_GET_CLASS (compositor)->manage (compositor); priv->plugin_mgr = meta_plugin_manager_new (compositor); + + clutter_actor_show (priv->stage); } void @@ -817,7 +824,8 @@ sync_actor_stacking (MetaCompositor *compositor) ClutterActor *actor = old->data; if (META_IS_BACKGROUND_GROUP (actor) || - META_IS_BACKGROUND_ACTOR (actor)) + META_IS_BACKGROUND_ACTOR (actor) || + META_IS_X11_BACKGROUND_ACTOR (actor)) { backgrounds = g_list_prepend (backgrounds, actor); @@ -1245,6 +1253,7 @@ meta_compositor_dispose (GObject *object) g_clear_signal_handler (&priv->top_window_actor_destroy_id, priv->top_window_actor); + g_clear_pointer (&priv->background_actor, clutter_actor_destroy); g_clear_pointer (&priv->window_group, clutter_actor_destroy); g_clear_pointer (&priv->top_window_group, clutter_actor_destroy); g_clear_pointer (&priv->feedback_group, clutter_actor_destroy); @@ -1565,3 +1574,22 @@ meta_compositor_is_switching_workspace (MetaCompositor *compositor) return priv->switch_workspace_in_progress > 0; } + +/** + * meta_get_x11_background_actor_for_display: + * @display: a #MetaDisplay + * + * Gets the actor that draws the root window background under the windows. + * The root window background automatically tracks the image or color set + * by the environment. + * + * Return value: (transfer none): The background actor corresponding to @display + */ +ClutterActor * +meta_get_x11_background_actor_for_display (MetaDisplay *display) +{ + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (display->compositor); + + return priv->background_actor; +} diff --git a/src/compositor/meta-compositor-x11.c b/src/compositor/meta-compositor-x11.c index 4043d8151..2f863ad52 100644 --- a/src/compositor/meta-compositor-x11.c +++ b/src/compositor/meta-compositor-x11.c @@ -33,6 +33,7 @@ #include "core/display-private.h" #include "core/window-private.h" #include "x11/meta-x11-display-private.h" +#include "x11/meta-x11-background-actor-private.h" struct _MetaCompositorX11 { @@ -95,6 +96,17 @@ meta_compositor_x11_process_xevent (MetaCompositorX11 *compositor_x11, if (window) process_damage (compositor_x11, (XDamageNotifyEvent *) xevent, window); } + else if (xevent->type == PropertyNotify) + { + if (((XPropertyEvent *) xevent)->atom == x11_display->atom_x_root_pixmap) + { + if (((XPropertyEvent *) xevent)->window == meta_x11_display_get_xroot (x11_display)) + { + meta_x11_background_actor_update (display); + return; + } + } + } if (compositor_x11->have_x11_sync_object) meta_sync_ring_handle_event (xevent); diff --git a/src/core/prefs.c b/src/core/prefs.c index 1ddf89d34..8817ee7f4 100644 --- a/src/core/prefs.c +++ b/src/core/prefs.c @@ -126,6 +126,8 @@ static gboolean workspaces_only_on_primary = FALSE; static char *iso_next_group_option = NULL; +static MetaX11BackgroundTransition background_transition = META_X11_BACKGROUND_TRANSITION_BLEND; + static void handle_preference_update_enum (GSettings *settings, gchar *key); static gboolean update_binding (MetaKeyPref *binding, @@ -276,6 +278,13 @@ static MetaEnumPreference preferences_enum[] = }, &action_right_click_titlebar, }, + { + { "background-transition", + SCHEMA_MUTTER, + META_PREF_BACKGROUND_TRANSITION, + }, + &background_transition, + }, { { NULL, 0, 0 }, NULL }, }; @@ -2224,3 +2233,9 @@ meta_prefs_set_force_fullscreen (gboolean whether) { force_fullscreen = whether; } + +MetaX11BackgroundTransition +meta_prefs_get_background_transition (void) +{ + return background_transition; +} \ No newline at end of file diff --git a/src/meson.build b/src/meson.build index 6e1a8e759..3c89e00c2 100644 --- a/src/meson.build +++ b/src/meson.build @@ -401,6 +401,10 @@ mutter_sources = [ 'x11/meta-selection-source-x11-private.h', 'x11/meta-startup-notification-x11.c', 'x11/meta-startup-notification-x11.h', + 'x11/meta-x11-background-actor.c', + 'x11/meta-x11-background-actor-private.h', + 'x11/meta-x11-background.c', + 'x11/meta-x11-background.h', 'x11/meta-x11-display.c', 'x11/meta-x11-display-private.h', 'x11/meta-x11-errors.c', diff --git a/src/meta/common.h b/src/meta/common.h index 908dc9337..5cbea521b 100644 --- a/src/meta/common.h +++ b/src/meta/common.h @@ -548,4 +548,14 @@ typedef enum _MetaGravity META_GRAVITY_STATIC = 10, } MetaGravity; +/* + * Background transition + */ +typedef enum +{ + META_X11_BACKGROUND_TRANSITION_NONE, + META_X11_BACKGROUND_TRANSITION_FADEIN, + META_X11_BACKGROUND_TRANSITION_BLEND +} MetaX11BackgroundTransition; + #endif diff --git a/src/meta/compositor-mutter.h b/src/meta/compositor-mutter.h index 0c420882f..def9ec832 100644 --- a/src/meta/compositor-mutter.h +++ b/src/meta/compositor-mutter.h @@ -57,4 +57,7 @@ void meta_focus_stage_window (MetaDisplay *display, META_EXPORT gboolean meta_stage_is_focused (MetaDisplay *display); +META_EXPORT +ClutterActor *meta_get_x11_background_actor_for_display (MetaDisplay *display); + #endif diff --git a/src/meta/meson.build b/src/meta/meson.build index 14caec58d..50fc837f4 100644 --- a/src/meta/meson.build +++ b/src/meta/meson.build @@ -45,8 +45,9 @@ mutter_public_headers = [ if have_x11 mutter_public_headers += [ + 'meta-x11-background-actor.h', 'meta-x11-display.h', - 'meta-x11-errors.h', + 'meta-x11-errors.h' ] endif diff --git a/src/meta/meta-x11-background-actor.h b/src/meta/meta-x11-background-actor.h new file mode 100644 index 000000000..e9d175148 --- /dev/null +++ b/src/meta/meta-x11-background-actor.h @@ -0,0 +1,49 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * meta-background-actor.h: Actor for painting the root window background + * + * Copyright 2010 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA + * 02110-1335, USA. + */ + +#ifndef META_X11_BACKGROUND_ACTOR_H +#define META_X11_BACKGROUND_ACTOR_H + +#include <clutter/clutter.h> + +#include <meta/display.h> + +/** + * MetaX11BackgroundActor: + * + * This class handles tracking and painting the root window background. + * By integrating with #MetaWindowGroup we can avoid painting parts of + * the background that are obscured by other windows. + */ + +#define META_TYPE_X11_BACKGROUND_ACTOR (meta_x11_background_actor_get_type ()) + +META_EXPORT +G_DECLARE_FINAL_TYPE (MetaX11BackgroundActor, + meta_x11_background_actor, + META, X11_BACKGROUND_ACTOR, + ClutterActor) + +META_EXPORT +ClutterActor *meta_x11_background_actor_new_for_display (MetaDisplay *display); + +#endif /* META_X11_BACKGROUND_ACTOR_H */ diff --git a/src/meta/prefs.h b/src/meta/prefs.h index 049e246a0..2ef2ef3a9 100644 --- a/src/meta/prefs.h +++ b/src/meta/prefs.h @@ -106,6 +106,7 @@ typedef enum META_PREF_DRAG_THRESHOLD, META_PREF_LOCATE_POINTER, META_PREF_CHECK_ALIVE_TIMEOUT, + META_PREF_BACKGROUND_TRANSITION } MetaPreference; typedef void (* MetaPrefsChangedFunc) (MetaPreference pref, @@ -485,4 +486,6 @@ CDesktopVisualBellType meta_prefs_get_visual_bell_type (void); META_EXPORT unsigned int meta_prefs_get_check_alive_timeout (void); +MetaX11BackgroundTransition meta_prefs_get_background_transition (void); + #endif diff --git a/src/x11/meta-x11-background-actor-private.h b/src/x11/meta-x11-background-actor-private.h new file mode 100644 index 000000000..d7e369b3f --- /dev/null +++ b/src/x11/meta-x11-background-actor-private.h @@ -0,0 +1,18 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +#ifndef META_X11_BACKGROUND_ACTOR_PRIVATE_H +#define META_X11_BACKGROUND_ACTOR_PRIVATE_H + +#include <meta/display.h> +#include <meta/meta-x11-display.h> +#include <meta/meta-x11-background-actor.h> +#include "meta-x11-background.h" + +void meta_x11_background_actor_set_visible_region (MetaX11BackgroundActor *self, + cairo_region_t *visible_region); + +void meta_x11_background_actor_update (MetaDisplay *display); +void meta_x11_background_actor_screen_size_changed (MetaDisplay *display); + + +#endif /* META_X11_BACKGROUND_ACTOR_PRIVATE_H */ diff --git a/src/x11/meta-x11-background-actor.c b/src/x11/meta-x11-background-actor.c new file mode 100644 index 000000000..47d4dc724 --- /dev/null +++ b/src/x11/meta-x11-background-actor.c @@ -0,0 +1,694 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * meta-background-actor.c: Actor for painting the root window background + * + * Copyright 2009 Sander Dijkhuis + * Copyright 2010 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA + * 02110-1335, USA. + * + * Portions adapted from gnome-shell/src/shell-global.c + */ + +/** + * SECTION:meta-x11-background-actor + * @title: MetaX11BackgroundActor + * @short_description: Actor for painting the root window background + */ + +#include <config.h> + +#include <cogl/winsys/cogl-texture-pixmap-x11.h> + +#include <clutter/clutter.h> + +#include <X11/Xatom.h> + +#include "cogl/cogl.h" +#include "meta/compositor-mutter.h" +#include "meta/meta-x11-errors.h" +#include "meta/meta-x11-display.h" +#include "meta-x11-background-actor-private.h" +#include "meta-x11-display-private.h" + +#define FADE_DURATION 1500 + +/* We allow creating multiple MetaX11BackgroundActors for the same MetaScreen to + * allow different rendering options to be set for different copies. + * But we want to share the same underlying CoglTexture for efficiency and + * to avoid driver bugs that might occur if we created multiple CoglTexturePixmaps + * for the same pixmap. + * + * This structure holds common information. + */ +typedef struct _MetaDisplayBackground MetaDisplayBackground; + +struct _MetaDisplayBackground +{ + MetaDisplay *display; + MetaX11Display *x11_display; + GSList *actors; + + float texture_width; + float texture_height; + CoglTexture *texture; + CoglPipelineWrapMode wrap_mode; + guint have_pixmap : 1; +}; + +typedef struct +{ + MetaDisplayBackground *background; + ClutterActor *top_actor; + ClutterActor *bottom_actor; + cairo_region_t *visible_region; + float dim_factor; + gboolean transition_running; +} MetaX11BackgroundActorPrivate; + +struct _MetaX11BackgroundActor +{ + ClutterActor parent_instance; + + MetaX11BackgroundActorPrivate *priv; +}; + +enum +{ + PROP_0, + + PROP_DIM_FACTOR, + + PROP_LAST +}; + +static GParamSpec *obj_props[PROP_LAST]; + +G_DEFINE_TYPE_WITH_PRIVATE (MetaX11BackgroundActor, meta_x11_background_actor, CLUTTER_TYPE_ACTOR); + +static void set_texture (MetaDisplayBackground *background, + CoglTexture *texture); +static void set_texture_to_stage_color (MetaDisplayBackground *background); + +static void +on_notify_stage_color (GObject *stage, + GParamSpec *pspec, + MetaDisplayBackground *background) +{ + if (!background->have_pixmap) + set_texture_to_stage_color (background); +} + +static void +free_display_background (MetaDisplayBackground *background) +{ + set_texture (background, NULL); + + if (background->display != NULL) + { + ClutterActor *stage = meta_get_stage_for_display (background->display); + g_signal_handlers_disconnect_by_func (stage, + (gpointer) on_notify_stage_color, + background); + background->display = NULL; + } +} + +static MetaDisplayBackground * +meta_display_background_get (MetaDisplay *display) +{ + MetaDisplayBackground *background; + + background = g_object_get_data (G_OBJECT (display), "meta-display-background"); + if (background == NULL) + { + ClutterActor *stage; + + background = g_new0 (MetaDisplayBackground, 1); + + background->display = display; + background->x11_display = meta_display_get_x11_display (display); + g_object_set_data_full (G_OBJECT (display), "meta-display-background", + background, (GDestroyNotify) free_display_background); + + stage = meta_get_stage_for_display (display); + g_signal_connect (stage, "notify::background-color", + G_CALLBACK (on_notify_stage_color), background); + + meta_x11_background_actor_update (display); + } + + return background; +} + +static void +update_wrap_mode_of_actor (MetaX11BackgroundActor *self) +{ + MetaX11BackgroundActorPrivate *priv = self->priv; + + meta_x11_background_set_layer_wrap_mode (META_X11_BACKGROUND (priv->top_actor), priv->background->wrap_mode); + meta_x11_background_set_layer_wrap_mode (META_X11_BACKGROUND (priv->bottom_actor), priv->background->wrap_mode); + + /* this ensures the actors also get resized if the stage size changed */ + clutter_actor_queue_relayout (CLUTTER_ACTOR (priv->top_actor)); + clutter_actor_queue_relayout (CLUTTER_ACTOR (priv->bottom_actor)); +} + +static void +update_wrap_mode (MetaDisplayBackground *background) +{ + GSList *l; + int width, height; + + meta_display_get_size (background->display, &width, &height); + + /* We turn off repeating when we have a full-screen pixmap to keep from + * getting artifacts from one side of the image sneaking into the other + * side of the image via bilinear filtering. + */ + if (width == background->texture_width && height == background->texture_height) + background->wrap_mode = COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE; + else + background->wrap_mode = COGL_PIPELINE_WRAP_MODE_REPEAT; + + for (l = background->actors; l; l = l->next) + update_wrap_mode_of_actor (l->data); +} + +static void +cancel_transitions (MetaX11BackgroundActor *self) +{ + MetaX11BackgroundActorPrivate *priv = self->priv; + + clutter_actor_remove_all_transitions (priv->top_actor); + clutter_actor_set_opacity (priv->top_actor, 255); + meta_x11_background_set_layer (META_X11_BACKGROUND (priv->bottom_actor), priv->background->texture); + + priv->transition_running = FALSE; +} + +static void +on_transition_complete (ClutterActor *actor, + gpointer user_data) +{ + MetaX11BackgroundActor *self = (MetaX11BackgroundActor *)user_data; + MetaX11BackgroundActorPrivate *priv = self->priv; + + meta_x11_background_set_layer (META_X11_BACKGROUND (priv->bottom_actor), priv->background->texture); + priv->transition_running = FALSE; +} + +static void +set_texture_on_actors (MetaX11BackgroundActor *self) +{ + MetaX11BackgroundActorPrivate *priv = self->priv; + + meta_x11_background_set_layer (META_X11_BACKGROUND (priv->bottom_actor), priv->background->texture); + meta_x11_background_set_layer (META_X11_BACKGROUND (priv->top_actor), priv->background->texture); + + clutter_actor_queue_redraw (CLUTTER_ACTOR (self)); +} + +static void +set_texture_on_actor (MetaX11BackgroundActor *self) +{ + MetaX11BackgroundActorPrivate *priv = self->priv; + MetaX11BackgroundTransition background_transition; + + if (priv->transition_running) + cancel_transitions (self); + + background_transition = meta_prefs_get_background_transition(); + + if (background_transition == META_X11_BACKGROUND_TRANSITION_NONE) + { + // NO TRANSITION + clutter_actor_set_opacity (CLUTTER_ACTOR (priv->bottom_actor), 0); + meta_x11_background_set_layer (META_X11_BACKGROUND (priv->top_actor), priv->background->texture); + on_transition_complete (priv->top_actor, self); + } + else + { + if (background_transition == META_X11_BACKGROUND_TRANSITION_FADEIN) + { + // FADE_IN TRANSITION + clutter_actor_set_opacity (CLUTTER_ACTOR (priv->bottom_actor), 0); + } + + // BLEND TRANSITION + clutter_actor_set_opacity (CLUTTER_ACTOR (priv->top_actor), 0); + meta_x11_background_set_layer (META_X11_BACKGROUND (priv->top_actor), priv->background->texture); + + priv->transition_running = TRUE; + + clutter_actor_save_easing_state (priv->top_actor); + clutter_actor_set_easing_duration (priv->top_actor, FADE_DURATION); + clutter_actor_set_opacity (priv->top_actor, 255); + clutter_actor_restore_easing_state (priv->top_actor); + + g_signal_connect (priv->top_actor, + "transitions-completed", + G_CALLBACK (on_transition_complete), + self); + + clutter_actor_queue_redraw (CLUTTER_ACTOR (self)); + } +} + +static void +set_texture (MetaDisplayBackground *background, + CoglTexture *texture) +{ + GSList *l; + + /* This may trigger destruction of an old texture pixmap, which, if + * the underlying X pixmap is already gone has the tendency to trigger + * X errors inside DRI. For safety, trap errors */ + meta_x11_error_trap_push (background->x11_display); + if (background->texture != NULL) + { + cogl_object_unref (background->texture); + background->texture = NULL; + } + meta_x11_error_trap_pop (background->x11_display); + + if (texture != NULL) + background->texture = cogl_object_ref (texture); + + background->texture_width = cogl_texture_get_width (background->texture); + background->texture_height = cogl_texture_get_height (background->texture); + + for (l = background->actors; l; l = l->next) + set_texture_on_actor (l->data); + + update_wrap_mode (background); +} + +static CoglTexture * +create_color_texture_4ub (guint8 red, + guint8 green, + guint8 blue, + guint8 alpha, + CoglTextureFlags flags) +{ + CoglColor color; + guint8 pixel[4]; + + cogl_color_init_from_4ub (&color, red, green, blue, alpha); + cogl_color_premultiply (&color); + + pixel[0] = cogl_color_get_red_byte (&color); + pixel[1] = cogl_color_get_green_byte (&color); + pixel[2] = cogl_color_get_blue_byte (&color); + pixel[3] = cogl_color_get_alpha_byte (&color); + + return cogl_texture_new_from_data (1, 1, + flags, + COGL_PIXEL_FORMAT_RGBA_8888_PRE, + COGL_PIXEL_FORMAT_ANY, + 4, pixel); +} + +/* Sets our material to paint with a 1x1 texture of the stage's background + * color; doing this when we have no pixmap allows the application to turn + * off painting the stage. There might be a performance benefit to + * painting in this case with a solid color, but the normal solid color + * case is a 1x1 root pixmap, so we'd have to reverse-engineer that to + * actually pick up the (small?) performance win. This is just a fallback. + */ +static void +set_texture_to_stage_color (MetaDisplayBackground *background) +{ + ClutterActor *stage = meta_get_stage_for_display (background->display); + ClutterColor color; + CoglTexture *texture; + + clutter_actor_get_background_color (stage, &color); + + /* Slicing will prevent COGL from using hardware texturing for + * the tiled 1x1 pixmap, and will cause it to draw the window + * background in millions of separate 1x1 rectangles */ + texture = create_color_texture_4ub (color.red, color.green, + color.blue, 0xff, + COGL_TEXTURE_NO_SLICING); + set_texture (background, texture); + cogl_object_unref (texture); +} + +static void +meta_x11_background_actor_dispose (GObject *object) +{ + MetaX11BackgroundActor *self = META_X11_BACKGROUND_ACTOR (object); + MetaX11BackgroundActorPrivate *priv = self->priv; + + meta_x11_background_actor_set_visible_region (self, NULL); + + if (priv->background != NULL) + { + priv->background->actors = g_slist_remove (priv->background->actors, self); + priv->background = NULL; + } + + if (priv->top_actor != NULL) + priv->top_actor = NULL; + + if (priv->bottom_actor != NULL) + priv->bottom_actor = NULL; + + G_OBJECT_CLASS (meta_x11_background_actor_parent_class)->dispose (object); +} + +static void +meta_x11_background_actor_get_preferred_width (ClutterActor *actor, + gfloat for_height, + gfloat *min_width_p, + gfloat *natural_width_p) +{ + MetaX11BackgroundActor *self = META_X11_BACKGROUND_ACTOR (actor); + MetaX11BackgroundActorPrivate *priv = self->priv; + int width, height; + + meta_display_get_size (priv->background->display, &width, &height); + + if (min_width_p) + *min_width_p = width; + if (natural_width_p) + *natural_width_p = width; +} + +static void +meta_x11_background_actor_get_preferred_height (ClutterActor *actor, + gfloat for_width, + gfloat *min_height_p, + gfloat *natural_height_p) + +{ + MetaX11BackgroundActor *self = META_X11_BACKGROUND_ACTOR (actor); + MetaX11BackgroundActorPrivate *priv = self->priv; + int width, height; + + meta_display_get_size (priv->background->display, &width, &height); + + if (min_height_p) + *min_height_p = height; + if (natural_height_p) + *natural_height_p = height; +} + +static gboolean +meta_x11_background_actor_get_paint_volume (ClutterActor *actor, + ClutterPaintVolume *volume) +{ + MetaX11BackgroundActor *self = META_X11_BACKGROUND_ACTOR (actor); + MetaX11BackgroundActorPrivate *priv = self->priv; + int width, height; + + meta_display_get_size (priv->background->display, &width, &height); + + clutter_paint_volume_set_width (volume, width); + clutter_paint_volume_set_height (volume, height); + + return TRUE; +} + +static void +meta_x11_background_actor_set_dim_factor (MetaX11BackgroundActor *self, + gfloat dim_factor) +{ + MetaX11BackgroundActorPrivate *priv = self->priv; + + if (priv->dim_factor == dim_factor) + return; + + priv->dim_factor = dim_factor; + + clutter_actor_queue_redraw (CLUTTER_ACTOR (self)); + + g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_DIM_FACTOR]); +} + +static void +meta_x11_background_actor_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaX11BackgroundActor *self = META_X11_BACKGROUND_ACTOR (object); + MetaX11BackgroundActorPrivate *priv = self->priv; + + switch (prop_id) + { + case PROP_DIM_FACTOR: + g_value_set_float (value, priv->dim_factor); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_x11_background_actor_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaX11BackgroundActor *self = META_X11_BACKGROUND_ACTOR (object); + + switch (prop_id) + { + case PROP_DIM_FACTOR: + meta_x11_background_actor_set_dim_factor (self, g_value_get_float (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_x11_background_actor_class_init (MetaX11BackgroundActorClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); + GParamSpec *pspec; + + object_class->dispose = meta_x11_background_actor_dispose; + object_class->get_property = meta_x11_background_actor_get_property; + object_class->set_property = meta_x11_background_actor_set_property; + + actor_class->get_preferred_width = meta_x11_background_actor_get_preferred_width; + actor_class->get_preferred_height = meta_x11_background_actor_get_preferred_height; + actor_class->get_paint_volume = meta_x11_background_actor_get_paint_volume; + + /** + * MetaX11BackgroundActor:dim-factor: + * + * Factor to dim the background by, between 0.0 (black) and 1.0 (original + * colors) + */ + pspec = g_param_spec_float ("dim-factor", + "Dim factor", + "Factor to dim the background by", + 0.0, 1.0, + 1.0, + G_PARAM_READWRITE); + obj_props[PROP_DIM_FACTOR] = pspec; + g_object_class_install_property (object_class, PROP_DIM_FACTOR, pspec); +} + +static void +meta_x11_background_actor_init (MetaX11BackgroundActor *self) +{ + self->priv = meta_x11_background_actor_get_instance_private (self); + self->priv->dim_factor = 1.0; + self->priv->transition_running = FALSE; +} + +/** + * meta_x11_background_actor_new_for_display: + * @display: the #MetaDisplay + * + * Creates a new actor to draw the background for the given display. + * + * Return value: (transfer none): the newly created background actor + */ +ClutterActor * +meta_x11_background_actor_new_for_display (MetaDisplay *display) +{ + MetaX11BackgroundActor *self; + MetaX11BackgroundActorPrivate *priv; + + g_return_val_if_fail (META_IS_DISPLAY (display), NULL); + + self = g_object_new (META_TYPE_X11_BACKGROUND_ACTOR, NULL); + priv = self->priv; + + priv->background = meta_display_background_get (display); + priv->background->actors = g_slist_prepend (priv->background->actors, self); + + priv->bottom_actor = meta_x11_background_new (display); + clutter_actor_add_child (CLUTTER_ACTOR (self), priv->bottom_actor); + priv->top_actor = meta_x11_background_new (display); + clutter_actor_add_child (CLUTTER_ACTOR (self), priv->top_actor); + + set_texture_on_actors (self); + update_wrap_mode_of_actor (self); + + return CLUTTER_ACTOR (self); +} + +/** + * meta_x11_background_actor_update: + * @display: a #MetaDisplay + * + * Refetches the _XROOTPMAP_ID property for the root window and updates + * the contents of the background actor based on that. There's no attempt + * to optimize out pixmap values that don't change (since a root pixmap + * could be replaced by with another pixmap with the same ID under some + * circumstances), so this should only be called when we actually receive + * a PropertyNotify event for the property. + */ +void +meta_x11_background_actor_update (MetaDisplay *display) +{ + MetaX11Display *x11_display; + MetaDisplayBackground *background; + MetaCompositor *compositor; + Atom type; + int format; + gulong nitems; + gulong bytes_after; + guchar *data; + Pixmap root_pixmap_id; + + x11_display = meta_display_get_x11_display (display); + background = meta_display_background_get (display); + compositor = meta_display_get_compositor (display); + + root_pixmap_id = None; + if (!XGetWindowProperty (meta_x11_display_get_xdisplay (x11_display), + meta_x11_display_get_xroot (x11_display), + x11_display->atom_x_root_pixmap, + 0, LONG_MAX, + False, + AnyPropertyType, + &type, &format, &nitems, &bytes_after, &data) && + type != None) + { + /* Got a property. */ + if (type == XA_PIXMAP && format == 32 && nitems == 1) + { + /* Was what we expected. */ + root_pixmap_id = *(Pixmap *)data; + } + + XFree(data); + } + + if (root_pixmap_id != None) + { + CoglHandle texture; + CoglContext *context = clutter_backend_get_cogl_context (clutter_get_default_backend ()); + + GError *error = NULL; + + meta_x11_error_trap_push (x11_display); + texture = cogl_texture_pixmap_x11_new (context, root_pixmap_id, FALSE, &error); + meta_x11_error_trap_pop (x11_display); + + if (texture != NULL) + { + set_texture (background, texture); + cogl_object_unref (texture); + + background->have_pixmap = True; + return; + } + else + { + g_warning ("Failed to create background texture from pixmap: %s", + error->message); + g_error_free (error); + } + } + + background->have_pixmap = False; + set_texture_to_stage_color (background); +} + +/** + * meta_x11_background_actor_set_visible_region: + * @self: a #MetaX11BackgroundActor + * @visible_region: (allow-none): the area of the actor (in allocate-relative + * coordinates) that is visible. + * + * Sets the area of the background that is unobscured by overlapping windows. + * This is used to optimize and only paint the visible portions. + */ +void +meta_x11_background_actor_set_visible_region (MetaX11BackgroundActor *self, + cairo_region_t *visible_region) +{ + MetaX11BackgroundActorPrivate *priv; + + g_return_if_fail (META_IS_X11_BACKGROUND_ACTOR (self)); + + priv = self->priv; + + if (priv->top_actor != NULL) + meta_x11_background_set_visible_region (META_X11_BACKGROUND (priv->top_actor), visible_region); +} + +/** + * meta_x11_background_actor_screen_size_changed: + * @display: a #MetaScreen + * + * Called by the compositor when the size of the #MetaScreen changes + */ +void +meta_x11_background_actor_screen_size_changed (MetaDisplay *x11_display) +{ + MetaDisplayBackground *background = meta_display_background_get (x11_display); + + update_wrap_mode (background); +} + +static MetaDisplayBackground * +display_background_get (MetaDisplay *display) +{ + MetaDisplayBackground *background; + + background = g_object_get_data (G_OBJECT (display), "meta-display-background"); + if (background == NULL) + { + ClutterActor *stage; + + background = g_new0 (MetaDisplayBackground, 1); + + background->x11_display = meta_display_get_x11_display (display); + g_object_set_data_full (G_OBJECT (display), "meta-screen-background", + background, (GDestroyNotify) free_display_background); + + stage = meta_get_stage_for_display (display); + g_signal_connect (stage, "notify::background-color", + G_CALLBACK (on_notify_stage_color), background); + + meta_x11_background_actor_update (display); + } + + return background; +} \ No newline at end of file diff --git a/src/x11/meta-x11-background.c b/src/x11/meta-x11-background.c new file mode 100644 index 000000000..04dfb9c01 --- /dev/null +++ b/src/x11/meta-x11-background.c @@ -0,0 +1,263 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * meta-background.c: Actor used to create a background fade effect + * + * Copyright 2016 Linux Mint + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA + * 02110-1335, USA. + * + * Portions adapted from gnome-shell/src/shell-global.c + * and meta-window-actor.c + */ + +#include "config.h" + +#include <clutter/clutter.h> +#include "cogl/cogl.h" +#include <compositor/cogl-utils.h> +#include "meta/meta-x11-errors.h" +#include "meta-x11-background-actor-private.h" + +typedef struct +{ + MetaDisplay *display; + MetaX11Display *x11_display; + CoglPipeline *pipeline; + + float texture_width; + float texture_height; + + cairo_region_t *visible_region; +} MetaX11BackgroundPrivate; + +struct _MetaX11Background +{ + ClutterActor parent_instance; + + MetaX11BackgroundPrivate *priv; +}; + + +G_DEFINE_TYPE_WITH_PRIVATE (MetaX11Background, meta_x11_background, CLUTTER_TYPE_ACTOR); + +static void +meta_x11_background_dispose (GObject *object) +{ + MetaX11Background *self = META_X11_BACKGROUND (object); + MetaX11BackgroundPrivate *priv = self->priv; + + meta_x11_background_set_visible_region (self, NULL); + + if (priv->pipeline != NULL) + { + cogl_object_unref (priv->pipeline); + priv->pipeline = NULL; + } + + G_OBJECT_CLASS (meta_x11_background_parent_class)->dispose (object); +} + +static void +meta_x11_background_get_preferred_width (ClutterActor *actor, + gfloat for_height, + gfloat *min_width_p, + gfloat *natural_width_p) +{ + MetaX11Background *self = META_X11_BACKGROUND (actor); + MetaX11BackgroundPrivate *priv = self->priv; + int width, height; + + meta_display_get_size (priv->display, &width, &height); + + if (min_width_p) + *min_width_p = width; + if (natural_width_p) + *natural_width_p = width; +} + +static void +meta_x11_background_get_preferred_height (ClutterActor *actor, + gfloat for_width, + gfloat *min_height_p, + gfloat *natural_height_p) + +{ + MetaX11Background *self = META_X11_BACKGROUND (actor); + MetaX11BackgroundPrivate *priv = self->priv; + int width, height; + + meta_display_get_size (priv->display, &width, &height); + + if (min_height_p) + *min_height_p = height; + if (natural_height_p) + *natural_height_p = height; +} + +static void +meta_x11_background_paint (ClutterActor *actor, ClutterPaintContext *paint_context) +{ + MetaX11Background *self = META_X11_BACKGROUND (actor); + MetaX11BackgroundPrivate *priv = self->priv; + CoglFramebuffer *framebuffer = clutter_paint_context_get_framebuffer (paint_context); + guint8 opacity = clutter_actor_get_paint_opacity (actor); + guint8 color_component; + int width, height; + + meta_display_get_size (priv->display, &width, &height); + + color_component = (int)(0.5 + opacity); + + cogl_pipeline_set_color4ub (priv->pipeline, + color_component, + color_component, + color_component, + opacity); + + if (priv->visible_region) + { + int n_rectangles = cairo_region_num_rectangles (priv->visible_region); + int i; + + for (i = 0; i < n_rectangles; i++) + { + cairo_rectangle_int_t rect; + cairo_region_get_rectangle (priv->visible_region, i, &rect); + + cogl_framebuffer_draw_textured_rectangle (framebuffer, + priv->pipeline, + rect.x, rect.y, + rect.x + rect.width, rect.y + rect.height, + rect.x / priv->texture_width, + rect.y / priv->texture_height, + (rect.x + rect.width) / priv->texture_width, + (rect.y + rect.height) / priv->texture_height); + } + } + else + { + cogl_framebuffer_draw_textured_rectangle (framebuffer, + priv->pipeline, + 0.0f, 0.0f, + width, height, + 0.0f, 0.0f, + width / priv->texture_width, + height / priv->texture_height); + } +} + +static gboolean +meta_x11_background_get_paint_volume (ClutterActor *actor, + ClutterPaintVolume *volume) +{ + return clutter_paint_volume_set_from_allocation (volume, actor); +} + + +static void +meta_x11_background_class_init (MetaX11BackgroundClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); + + object_class->dispose = meta_x11_background_dispose; + + actor_class->get_preferred_width = meta_x11_background_get_preferred_width; + actor_class->get_preferred_height = meta_x11_background_get_preferred_height; + actor_class->get_paint_volume = meta_x11_background_get_paint_volume; + actor_class->paint = meta_x11_background_paint; +} + +static void +meta_x11_background_init (MetaX11Background *self) +{ + self->priv = meta_x11_background_get_instance_private (self); +} + +ClutterActor * +meta_x11_background_new (MetaDisplay *display) +{ + MetaX11Background *self; + MetaX11BackgroundPrivate *priv; + + self = g_object_new (META_TYPE_X11_BACKGROUND, + NULL); + priv = self->priv; + + priv->display = display; + priv->x11_display = meta_display_get_x11_display (display); + priv->pipeline = meta_create_texture_pipeline (NULL); + + return CLUTTER_ACTOR (self); +} + +void +meta_x11_background_set_layer (MetaX11Background *self, + CoglTexture *texture) +{ + MetaX11BackgroundPrivate *priv = self->priv; + + /* This may trigger destruction of an old texture pixmap, which, if + * the underlying X pixmap is already gone has the tendency to trigger + * X errors inside DRI. For safety, trap errors */ + meta_x11_error_trap_push (priv->x11_display); + cogl_pipeline_set_layer_texture (priv->pipeline, 0, texture); + meta_x11_error_trap_pop (priv->x11_display); + + priv->texture_width = cogl_texture_get_width (texture); + priv->texture_height = cogl_texture_get_height (texture); + + clutter_actor_queue_redraw (CLUTTER_ACTOR (self)); +} + +void +meta_x11_background_set_layer_wrap_mode (MetaX11Background *self, + CoglPipelineWrapMode wrap_mode) +{ + MetaX11BackgroundPrivate *priv = self->priv; + + cogl_pipeline_set_layer_wrap_mode (priv->pipeline, 0, wrap_mode); +} + +void +meta_x11_background_set_visible_region (MetaX11Background *self, + cairo_region_t *visible_region) +{ + MetaX11BackgroundPrivate *priv; + + g_return_if_fail (META_IS_X11_BACKGROUND (self)); + + priv = self->priv; + + if (priv->visible_region) + { + cairo_region_destroy (priv->visible_region); + priv->visible_region = NULL; + } + + if (visible_region) + { + cairo_rectangle_int_t screen_rect = { 0 }; + meta_display_get_size (priv->display, &screen_rect.width, &screen_rect.height); + + /* Doing the intersection here is probably unnecessary - MetaWindowGroup + * should never compute a visible area that's larger than the root screen! + * but it's not that expensive and adds some extra robustness. + */ + priv->visible_region = cairo_region_create_rectangle (&screen_rect); + cairo_region_intersect (priv->visible_region, visible_region); + } +} \ No newline at end of file diff --git a/src/x11/meta-x11-background.h b/src/x11/meta-x11-background.h new file mode 100644 index 000000000..0e2a142e3 --- /dev/null +++ b/src/x11/meta-x11-background.h @@ -0,0 +1,27 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +#ifndef META_X11_BACKGROUND_H +#define META_X11_BACKGROUND_H + +#include <clutter/clutter.h> + +#include <meta/display.h> + +#define META_TYPE_X11_BACKGROUND (meta_x11_background_get_type ()) + +META_EXPORT +G_DECLARE_FINAL_TYPE (MetaX11Background, + meta_x11_background, + META, X11_BACKGROUND, + ClutterActor) + +ClutterActor * meta_x11_background_new (MetaDisplay *display); + +void meta_x11_background_set_layer (MetaX11Background *self, + CoglTexture *texture); +void meta_x11_background_set_layer_wrap_mode (MetaX11Background *self, + CoglPipelineWrapMode wrap_mode); +void meta_x11_background_set_visible_region (MetaX11Background *self, + cairo_region_t *visible_region); + +#endif /* META_X11_BACKGROUND_H */ diff --git a/src/x11/meta-x11-display-private.h b/src/x11/meta-x11-display-private.h index d53073e11..b7a22c583 100644 --- a/src/x11/meta-x11-display-private.h +++ b/src/x11/meta-x11-display-private.h @@ -86,6 +86,8 @@ struct _MetaX11Display */ Window no_focus_window; + Atom atom_x_root_pixmap; + /* Instead of unmapping withdrawn windows we can leave them mapped * and restack them below a guard window. When using a compositor * this allows us to provide live previews of unmapped windows */ diff --git a/src/x11/meta-x11-display.c b/src/x11/meta-x11-display.c index 335044e24..f6703b3b3 100644 --- a/src/x11/meta-x11-display.c +++ b/src/x11/meta-x11-display.c @@ -1217,6 +1217,7 @@ meta_x11_display_new (MetaDisplay *display, GError **error) x11_display = g_object_new (META_TYPE_X11_DISPLAY, NULL); x11_display->gdk_display = gdk_display; x11_display->display = display; + x11_display->atom_x_root_pixmap = XInternAtom (xdisplay, "_XROOTPMAP_ID", False); /* here we use XDisplayName which is what the user * probably put in, vs. DisplayString(display) which is From d2da9df40ec094addaac7dff1c68e07038310cc0 Mon Sep 17 00:00:00 2001 From: Michael Webster <miketwebster@gmail.com> Date: Sun, 10 Oct 2021 12:27:19 -0400 Subject: [PATCH 03/36] Allow custom and mod-only keybindings. --- data/org.cinnamon.muffin.gschema.xml.in | 11 ++----- src/core/events.c | 3 +- src/core/keybindings-private.h | 3 +- src/core/keybindings.c | 44 ++++++++++++++++++++++--- src/core/prefs.c | 36 +++++++++++++------- src/meta/display.h | 8 +++++ 6 files changed, 78 insertions(+), 27 deletions(-) diff --git a/data/org.cinnamon.muffin.gschema.xml.in b/data/org.cinnamon.muffin.gschema.xml.in index feb4d1409..d0b555ab7 100644 --- a/data/org.cinnamon.muffin.gschema.xml.in +++ b/data/org.cinnamon.muffin.gschema.xml.in @@ -9,15 +9,10 @@ gettext-domain="@GETTEXT_DOMAIN@"> <key name="overlay-key" type="s"> - <default>'Super_L'</default> - <summary>Modifier to use for extended window management operations</summary> + <default>''</default> + <summary>DO NOT USE</summary> <description> - This key will initiate the “overlay”, which is a combination window - overview and application launching system. The default is intended - to be the “Windows key” on PC hardware. - - It’s expected that this binding either the default or set to - the empty string. + Use keybinding mechanisms in cinnamon instead. </description> </key> diff --git a/src/core/events.c b/src/core/events.c index e50b52d0d..85e54ffda 100644 --- a/src/core/events.c +++ b/src/core/events.c @@ -358,7 +358,8 @@ meta_display_handle_event (MetaDisplay *display, * in a keyboard-grabbed mode like moving a window, we don't * want to pass the key event to the compositor or Wayland at all. */ - if (meta_keybindings_process_event (display, window, event)) + if (display->event_route != META_EVENT_ROUTE_COMPOSITOR_GRAB && + meta_keybindings_process_event (display, window, event)) { bypass_clutter = TRUE; bypass_wayland = TRUE; diff --git a/src/core/keybindings-private.h b/src/core/keybindings-private.h index ab1ab52fe..81c23e1cf 100644 --- a/src/core/keybindings-private.h +++ b/src/core/keybindings-private.h @@ -112,10 +112,8 @@ typedef struct xkb_mod_mask_t virtual_meta_mask; MetaKeyCombo overlay_key_combo; MetaResolvedKeyCombo overlay_resolved_key_combo; - gboolean overlay_key_only_pressed; MetaKeyCombo locate_pointer_key_combo; MetaResolvedKeyCombo locate_pointer_resolved_key_combo; - gboolean locate_pointer_key_only_pressed; MetaResolvedKeyCombo iso_next_group_combo[2]; int n_iso_next_group_combos; @@ -145,6 +143,7 @@ ClutterModifierType meta_display_get_window_grab_modifiers (MetaDisplay *display gboolean meta_prefs_add_keybinding (const char *name, GSettings *settings, + const gchar **bindings, MetaKeyBindingAction action, MetaKeyBindingFlags flags); diff --git a/src/core/keybindings.c b/src/core/keybindings.c index d2740be52..1afdf746b 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -587,8 +587,9 @@ index_binding (MetaKeyBindingManager *keys, if (i > 0) continue; - meta_warning ("Overwriting existing binding of keysym %x" + meta_warning ("%s - Overwriting existing binding of keysym %x" " with keysym %x (keycode %x).\n", + binding->name, binding->combo.keysym, existing->combo.keysym, binding->resolved_combo.keycodes[i]); @@ -958,6 +959,7 @@ static gboolean add_keybinding_internal (MetaDisplay *display, const char *name, GSettings *settings, + const char **bindings, MetaKeyBindingFlags flags, MetaKeyBindingAction action, MetaKeyHandlerFunc func, @@ -967,7 +969,7 @@ add_keybinding_internal (MetaDisplay *display, { MetaKeyHandler *handler; - if (!meta_prefs_add_keybinding (name, settings, action, flags)) + if (!meta_prefs_add_keybinding (name, settings, bindings, action, flags)) return FALSE; handler = g_new0 (MetaKeyHandler, 1); @@ -993,7 +995,7 @@ add_builtin_keybinding (MetaDisplay *display, MetaKeyHandlerFunc handler, int handler_arg) { - return add_keybinding_internal (display, name, settings, + return add_keybinding_internal (display, name, settings, NULL, flags | META_KEY_BINDING_BUILTIN, action, handler, handler_arg, NULL, NULL); } @@ -1032,7 +1034,39 @@ meta_display_add_keybinding (MetaDisplay *display, { guint new_action = next_dynamic_keybinding_action (); - if (!add_keybinding_internal (display, name, settings, flags, new_action, + if (!add_keybinding_internal (display, name, settings, NULL, flags, new_action, + handler, 0, user_data, free_data)) + return META_KEYBINDING_ACTION_NONE; + + return new_action; +} + +/** + * meta_display_add_custom_keybinding: + * @display: a #MetaDisplay + * @name: the binding's unique name + * @bindings: (allow-none) (array zero-terminated=1): array of parseable keystrokes + * @callback: function to run when the keybinding is invoked + * @user_data: the data to pass to @handler + * @free_data: function to free @user_data + * + * + * Use meta_display_remove_custom_keybinding() to remove the binding. + * + * Returns: %TRUE if the keybinding was added successfully, + * otherwise %FALSE + */ +guint +meta_display_add_custom_keybinding (MetaDisplay *display, + const char *name, + const char **bindings, + MetaKeyHandlerFunc handler, + gpointer user_data, + GDestroyNotify free_data) +{ + guint new_action = next_dynamic_keybinding_action (); + + if (!add_keybinding_internal (display, name, NULL, bindings, META_KEY_BINDING_PER_WINDOW, new_action, handler, 0, user_data, free_data)) return META_KEYBINDING_ACTION_NONE; @@ -1062,7 +1096,7 @@ meta_display_remove_keybinding (MetaDisplay *display, return TRUE; } -static guint +guint get_keybinding_action (MetaKeyBindingManager *keys, MetaResolvedKeyCombo *resolved_combo) { diff --git a/src/core/prefs.c b/src/core/prefs.c index 8817ee7f4..da37e3d8d 100644 --- a/src/core/prefs.c +++ b/src/core/prefs.c @@ -1793,7 +1793,7 @@ meta_key_pref_free (MetaKeyPref *pref) update_binding (pref, NULL); g_free (pref->name); - g_object_unref (pref->settings); + g_clear_object (&pref->settings); g_free (pref); } @@ -2008,11 +2008,12 @@ meta_prefs_get_visual_bell_type (void) gboolean meta_prefs_add_keybinding (const char *name, GSettings *settings, + const gchar **bindings, MetaKeyBindingAction action, MetaKeyBindingFlags flags) { MetaKeyPref *pref; - char **strokes; + char **strokes = NULL; guint id; if (g_hash_table_lookup (key_bindings, name)) @@ -2023,7 +2024,7 @@ meta_prefs_add_keybinding (const char *name, pref = g_new0 (MetaKeyPref, 1); pref->name = g_strdup (name); - pref->settings = g_object_ref (settings); + pref->settings = settings != NULL ? g_object_ref (settings) : NULL; pref->action = action; pref->combos = NULL; pref->builtin = (flags & META_KEY_BINDING_BUILTIN) != 0; @@ -2036,20 +2037,30 @@ meta_prefs_add_keybinding (const char *name, G_CALLBACK (bindings_changed), NULL); g_object_set_data (G_OBJECT (settings), "changed-signal", GUINT_TO_POINTER (id)); } + + strokes = g_settings_get_strv (settings, name); } else { - char *changed_signal = g_strdup_printf ("changed::%s", name); - id = g_signal_connect (settings, changed_signal, - G_CALLBACK (bindings_changed), NULL); - g_free (changed_signal); + if (pref->settings != NULL) + { + char *changed_signal = g_strdup_printf ("changed::%s", name); + id = g_signal_connect (settings, changed_signal, + G_CALLBACK (bindings_changed), NULL); + g_free (changed_signal); - g_object_set_data (G_OBJECT (settings), name, GUINT_TO_POINTER (id)); + g_object_set_data (G_OBJECT (settings), name, GUINT_TO_POINTER (id)); + + strokes = g_settings_get_strv (settings, name); + } + else + { + strokes = g_strdupv (bindings); + } queue_changed (META_PREF_KEYBINDINGS); } - strokes = g_settings_get_strv (settings, name); update_binding (pref, strokes); g_strfreev (strokes); @@ -2077,8 +2088,11 @@ meta_prefs_remove_keybinding (const char *name) return FALSE; } - id = GPOINTER_TO_UINT (g_object_steal_data (G_OBJECT (pref->settings), name)); - g_clear_signal_handler (&id, pref->settings); + if (pref->settings != NULL) + { + id = GPOINTER_TO_UINT (g_object_steal_data (G_OBJECT (pref->settings), name)); + g_clear_signal_handler (&id, pref->settings); + } g_hash_table_remove (key_bindings, name); diff --git a/src/meta/display.h b/src/meta/display.h index 5cf99cfea..8c2356fed 100644 --- a/src/meta/display.h +++ b/src/meta/display.h @@ -152,6 +152,14 @@ guint meta_display_add_keybinding (MetaDisplay *display, gpointer user_data, GDestroyNotify free_data); +META_EXPORT +guint meta_display_add_custom_keybinding (MetaDisplay *display, + const char *name, + const char **bindings, + MetaKeyHandlerFunc callback, + gpointer user_data, + GDestroyNotify free_data); + META_EXPORT gboolean meta_display_remove_keybinding (MetaDisplay *display, const char *name); From 32caa549e8692b8a00e551b8738c57c721ee338b Mon Sep 17 00:00:00 2001 From: Michael Webster <miketwebster@gmail.com> Date: Sun, 10 Oct 2021 20:23:59 -0400 Subject: [PATCH 04/36] Reintroduce the bottom window group. This keeps the desktop window (nemo-desktop) underneath the desklets layer. Restore public toggle-desktop. --- src/compositor/compositor.c | 27 +++++++++++++++++++++++ src/core/meta-workspace-manager-private.h | 5 ----- src/core/meta-workspace-manager.c | 17 ++++++++++++++ src/meta/compositor-mutter.h | 3 +++ src/meta/meta-workspace-manager.h | 11 +++++++++ 5 files changed, 58 insertions(+), 5 deletions(-) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 8329bff96..807d4c16e 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -114,6 +114,7 @@ typedef struct _MetaCompositorPrivate ClutterActor *window_group; ClutterActor *top_window_group; ClutterActor *feedback_group; + ClutterActor *bottom_window_group; ClutterActor *background_actor; @@ -283,6 +284,27 @@ meta_get_feedback_group_for_display (MetaDisplay *display) return priv->feedback_group; } +/** + * meta_get_bottom_window_group_for_display: + * @display: a #MetaDisplay + * + * Returns: (transfer none): The bottom window group corresponding to @display + */ +ClutterActor * +meta_get_bottom_window_group_for_display (MetaDisplay *display) +{ + MetaCompositor *compositor; + MetaCompositorPrivate *priv; + + g_return_val_if_fail (display, NULL); + + compositor = get_compositor_for_display (display); + g_return_val_if_fail (compositor, NULL); + priv = meta_compositor_get_instance_private (compositor); + + return priv->bottom_window_group; +} + /** * meta_get_window_actors: * @display: a #MetaDisplay @@ -574,12 +596,14 @@ meta_compositor_manage (MetaCompositor *compositor) priv->window_group = meta_window_group_new (display); priv->top_window_group = meta_window_group_new (display); + priv->bottom_window_group = meta_window_group_new (display); priv->feedback_group = meta_window_group_new (display); priv->background_actor = meta_x11_background_actor_new_for_display (display); clutter_actor_add_child (priv->window_group, priv->background_actor); clutter_actor_add_child (priv->stage, priv->window_group); clutter_actor_add_child (priv->stage, priv->top_window_group); + clutter_actor_add_child (priv->stage, priv->bottom_window_group); clutter_actor_add_child (priv->stage, priv->feedback_group); META_COMPOSITOR_GET_CLASS (compositor)->manage (compositor); @@ -628,6 +652,8 @@ meta_compositor_add_window (MetaCompositor *compositor, if (window->layer == META_LAYER_OVERRIDE_REDIRECT) window_group = priv->top_window_group; + else if (window->type == META_WINDOW_DESKTOP) + window_group = priv->bottom_window_group; else window_group = priv->window_group; @@ -1256,6 +1282,7 @@ meta_compositor_dispose (GObject *object) g_clear_pointer (&priv->background_actor, clutter_actor_destroy); g_clear_pointer (&priv->window_group, clutter_actor_destroy); g_clear_pointer (&priv->top_window_group, clutter_actor_destroy); + g_clear_pointer (&priv->bottom_window_group, clutter_actor_destroy); g_clear_pointer (&priv->feedback_group, clutter_actor_destroy); g_clear_pointer (&priv->windows, g_list_free); diff --git a/src/core/meta-workspace-manager-private.h b/src/core/meta-workspace-manager-private.h index 261c4d47c..7a5126bb6 100644 --- a/src/core/meta-workspace-manager-private.h +++ b/src/core/meta-workspace-manager-private.h @@ -79,11 +79,6 @@ void meta_workspace_manager_free_workspace_layout (MetaWorkspaceLayout *layout); void meta_workspace_manager_minimize_all_on_active_workspace_except (MetaWorkspaceManager *workspace_manager, MetaWindow *keep); -/* Show/hide the desktop (temporarily hide all windows) */ -void meta_workspace_manager_show_desktop (MetaWorkspaceManager *workspace_manager, - guint32 timestamp); -void meta_workspace_manager_unshow_desktop (MetaWorkspaceManager *workspace_manager); - void meta_workspace_manager_workspace_switched (MetaWorkspaceManager *workspace_manager, int from, int to, diff --git a/src/core/meta-workspace-manager.c b/src/core/meta-workspace-manager.c index 36d0b9bcd..c38d750eb 100644 --- a/src/core/meta-workspace-manager.c +++ b/src/core/meta-workspace-manager.c @@ -993,6 +993,23 @@ meta_workspace_manager_unshow_desktop (MetaWorkspaceManager *workspace_manager) 0, NULL); } +void +meta_workspace_manager_toggle_desktop (MetaWorkspaceManager *workspace_manager, + guint32 timestamp) +{ + if (workspace_manager->active_workspace->showing_desktop) + { + meta_workspace_manager_unshow_desktop (workspace_manager); + meta_workspace_focus_default_window (workspace_manager->active_workspace, + NULL, + timestamp); + } + else + { + meta_workspace_manager_show_desktop (workspace_manager, timestamp); + } +} + /** * meta_workspace_manager_get_workspaces: (skip) * @workspace_manager: a #MetaWorkspaceManager diff --git a/src/meta/compositor-mutter.h b/src/meta/compositor-mutter.h index def9ec832..20c05e507 100644 --- a/src/meta/compositor-mutter.h +++ b/src/meta/compositor-mutter.h @@ -41,6 +41,9 @@ ClutterActor *meta_get_window_group_for_display (MetaDisplay *display); META_EXPORT ClutterActor *meta_get_top_window_group_for_display (MetaDisplay *display); +META_EXPORT +ClutterActor *meta_get_bottom_window_group_for_display (MetaDisplay *display); + META_EXPORT ClutterActor *meta_get_feedback_group_for_display (MetaDisplay *display); diff --git a/src/meta/meta-workspace-manager.h b/src/meta/meta-workspace-manager.h index 92cd68191..52a15b613 100644 --- a/src/meta/meta-workspace-manager.h +++ b/src/meta/meta-workspace-manager.h @@ -75,4 +75,15 @@ void meta_workspace_manager_override_workspace_layout (MetaWorkspaceManager *wor gboolean vertical_layout, int n_rows, int n_columns); + +/* Show/hide the desktop (temporarily hide all windows) */ +META_EXPORT +void meta_workspace_manager_show_desktop (MetaWorkspaceManager *workspace_manager, + guint32 timestamp); +META_EXPORT +void meta_workspace_manager_unshow_desktop (MetaWorkspaceManager *workspace_manager); +META_EXPORT +void meta_workspace_manager_toggle_desktop (MetaWorkspaceManager *workspace_manager, + guint32 timestamp); + #endif /* META_WORKSPACE_MANAGER_H */ From dc1538a44e110175456dee05106bf58271749047 Mon Sep 17 00:00:00 2001 From: Fabio Fantoni <fantonifabio@tiscali.it> Date: Fri, 8 Oct 2021 14:37:59 +0200 Subject: [PATCH 05/36] debian/control: restore something removed in 8dbf865 --- debian/control | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/debian/control b/debian/control index e2d460d25..b2f8f3352 100644 --- a/debian/control +++ b/debian/control @@ -75,6 +75,7 @@ Standards-Version: 4.5.0 Package: gir1.2-meta-muffin-0.0 Section: introspection Architecture: any +Multi-Arch: same Breaks: gir1.2-muffin-3.0 Replaces: gir1.2-muffin-3.0 Depends: libmuffin0 (= ${binary:Version}), @@ -91,9 +92,15 @@ Description: GObject introspection data for Muffin Package: libmuffin0 Section: libs Architecture: any -Replaces: muffin-doc +Multi-Arch: same Pre-Depends: ${misc:Pre-Depends} -Depends: muffin-common (= ${source:Version}), ${misc:Depends}, ${shlibs:Depends} +Depends: adwaita-icon-theme, + gsettings-desktop-schemas (>= 3.33.0), + muffin-common (>= ${source:Version}), + ${misc:Depends}, + ${shlibs:Depends} +Replaces: muffin-doc +Breaks: apparmor (<< 2.13.3-5~) Description: window and compositing manager (shared library) Muffin is a window manager performing compositing as well based on GTK+ and Clutter and used in Cinnamon desktop environment. @@ -103,13 +110,14 @@ Description: window and compositing manager (shared library) Package: muffin Architecture: any Pre-Depends: ${misc:Pre-Depends} -Depends: - muffin-common (= ${source:Version}), - zenity, - ${misc:Depends}, - ${shlibs:Depends}, +Depends: adwaita-icon-theme, + gsettings-desktop-schemas (>= 3.33.0), + muffin-common (>= ${source:Version}), + zenity, + ${misc:Depends}, + ${shlibs:Depends} Provides: x-window-manager -Suggests: gnome-themes, xdg-user-dirs +Suggests: xdg-user-dirs Description: window and compositing manager Muffin is a window manager performing compositing as well based on GTK+ and Clutter and used in Cinnamon desktop environment. @@ -119,6 +127,7 @@ Description: window and compositing manager Package: muffin-common Section: misc Architecture: all +Multi-Arch: foreign Depends: ${misc:Depends} Description: window and compositing manager (data files) Muffin is a window manager performing compositing as well based on From 14c51f3782e28a336209f4cbae98dabb2aa7ded7 Mon Sep 17 00:00:00 2001 From: Fabio Fantoni <fantonifabio@tiscali.it> Date: Fri, 8 Oct 2021 15:10:04 +0200 Subject: [PATCH 06/36] debian/tests: mutter->muffin --- debian/tests/control | 4 ++-- debian/tests/{libmutter-6-dev => libmuffin-dev} | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename debian/tests/{libmutter-6-dev => libmuffin-dev} (89%) diff --git a/debian/tests/control b/debian/tests/control index 2c0cd2457..7d5194395 100644 --- a/debian/tests/control +++ b/debian/tests/control @@ -1,7 +1,7 @@ -Tests: libmutter-6-dev +Tests: libmuffin-dev Depends: build-essential, dbus, - libmutter-6-dev, + libmuffin-dev, xauth, xvfb Restrictions: allow-stderr superficial diff --git a/debian/tests/libmutter-6-dev b/debian/tests/libmuffin-dev similarity index 89% rename from debian/tests/libmutter-6-dev rename to debian/tests/libmuffin-dev index ea89a7427..ca4b078c4 100755 --- a/debian/tests/libmutter-6-dev +++ b/debian/tests/libmuffin-dev @@ -1,5 +1,5 @@ #!/bin/sh -# autopkgtest check: Build and run a program against libmutter, to verify +# autopkgtest check: Build and run a program against libmuffin, to verify # that the headers and pkg-config file are installed correctly # (C) 2012 Canonical Ltd. # (C) 2018-2019 Simon McVittie @@ -34,7 +34,7 @@ EOF # Deliberately word-splitting pkg-config's output: # shellcheck disable=SC2046 -"${CROSS_COMPILE}gcc" -o trivial trivial.c $("${CROSS_COMPILE}pkg-config" --cflags --libs libmutter-6) +"${CROSS_COMPILE}gcc" -o trivial trivial.c $("${CROSS_COMPILE}pkg-config" --cflags --libs libmuffin) echo "build: OK" [ -x trivial ] xvfb-run -a dbus-run-session -- ./trivial From 90cb0cb6376c3ca0ffc20f64c628c5b7c57db974 Mon Sep 17 00:00:00 2001 From: Michael Webster <miketwebster@gmail.com> Date: Wed, 27 Oct 2021 22:10:49 -0400 Subject: [PATCH 07/36] Make a couple of methods public to restore some old MetaScreen functionality we rely on. --- src/core/display-private.h | 11 ----------- src/core/display.c | 2 +- src/core/window-private.h | 2 -- src/meta/display.h | 11 +++++++++++ src/meta/window.h | 3 +++ 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/core/display-private.h b/src/core/display-private.h index 251e9e2a8..60713b3af 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -52,13 +52,6 @@ typedef struct _MetaUISlave MetaUISlave; typedef struct MetaEdgeResistanceData MetaEdgeResistanceData; -typedef enum -{ - META_LIST_DEFAULT = 0, /* normal windows */ - META_LIST_INCLUDE_OVERRIDE_REDIRECT = 1 << 0, /* normal and O-R */ - META_LIST_SORTED = 1 << 1, /* sort list by mru */ -} MetaListWindowsFlags; - #define _NET_WM_STATE_REMOVE 0 /* remove/unset property */ #define _NET_WM_STATE_ADD 1 /* add/set property */ #define _NET_WM_STATE_TOGGLE 2 /* toggle property */ @@ -304,10 +297,6 @@ void meta_display_unregister_wayland_window (MetaDisplay *display, void meta_display_notify_window_created (MetaDisplay *display, MetaWindow *window); -META_EXPORT_TEST -GSList* meta_display_list_windows (MetaDisplay *display, - MetaListWindowsFlags flags); - MetaDisplay* meta_display_for_x_display (Display *xdisplay); META_EXPORT_TEST diff --git a/src/core/display.c b/src/core/display.c index 0917f4693..de97381ea 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -995,7 +995,7 @@ ptrcmp (gconstpointer a, gconstpointer b) * now determines whether override-redirect windows will be * included. * - * Return value: (transfer container): the list of windows. + * Return value: (transfer container) (element-type MetaWindow): the list of windows. */ GSList* meta_display_list_windows (MetaDisplay *display, diff --git a/src/core/window-private.h b/src/core/window-private.h index 273675900..8abaf8a25 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -829,8 +829,6 @@ gboolean meta_window_handle_ui_frame_event (MetaWindow *window, void meta_window_handle_ungrabbed_event (MetaWindow *window, const ClutterEvent *event); -uint32_t meta_window_get_client_pid (MetaWindow *window); - void meta_window_get_client_area_rect (const MetaWindow *window, cairo_rectangle_int_t *rect); void meta_window_get_titlebar_rect (MetaWindow *window, diff --git a/src/meta/display.h b/src/meta/display.h index 8c2356fed..7fe2febaf 100644 --- a/src/meta/display.h +++ b/src/meta/display.h @@ -314,4 +314,15 @@ META_EXPORT void meta_display_unset_input_focus (MetaDisplay *display, guint32 timestamp); +typedef enum +{ + META_LIST_DEFAULT = 0, /* normal windows */ + META_LIST_INCLUDE_OVERRIDE_REDIRECT = 1 << 0, /* normal and O-R */ + META_LIST_SORTED = 1 << 1, /* sort list by mru */ +} MetaListWindowsFlags; + +META_EXPORT +GSList* meta_display_list_windows (MetaDisplay *display, + MetaListWindowsFlags flags); + #endif diff --git a/src/meta/window.h b/src/meta/window.h index dda5acea1..78fe920ed 100644 --- a/src/meta/window.h +++ b/src/meta/window.h @@ -333,6 +333,9 @@ guint meta_window_get_stable_sequence (MetaWindow *window); META_EXPORT guint32 meta_window_get_user_time (MetaWindow *window); +META_EXPORT +uint32_t meta_window_get_client_pid (MetaWindow *window); + META_EXPORT int meta_window_get_pid (MetaWindow *window); From 8258225c6bfca9cb33fe688bf8fd541059d12bdd Mon Sep 17 00:00:00 2001 From: Michael Webster <miketwebster@gmail.com> Date: Thu, 27 Jan 2022 09:01:52 -0500 Subject: [PATCH 08/36] XApp themed icon names, progress. --- src/core/window-private.h | 6 +++ src/core/window.c | 46 +++++++++++++++++++++- src/meta/window.h | 3 ++ src/x11/atomnames.h | 4 +- src/x11/window-props.c | 82 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 139 insertions(+), 2 deletions(-) diff --git a/src/core/window-private.h b/src/core/window-private.h index 8abaf8a25..ca5d2f404 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -186,6 +186,12 @@ struct _MetaWindow cairo_surface_t *icon; cairo_surface_t *mini_icon; + /* XAppGtkWindow */ + char *theme_icon_name; + guint progress; + guint progress_pulse : 1; + /* /XappGtkWindow */ + MetaWindowType type; /* NOTE these five are not in UTF-8, we just treat them as random diff --git a/src/core/window.c b/src/core/window.c index f20eece4f..1057d93b4 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -212,7 +212,8 @@ enum PROP_GTK_APP_MENU_OBJECT_PATH, PROP_GTK_MENUBAR_OBJECT_PATH, PROP_ON_ALL_WORKSPACES, - + PROP_PROGRESS, + PROP_PROGRESS_PULSE, PROP_LAST, }; @@ -435,6 +436,12 @@ meta_window_get_property(GObject *object, case PROP_ON_ALL_WORKSPACES: g_value_set_boolean (value, win->on_all_workspaces); break; + case PROP_PROGRESS: + g_value_set_uint (value, win->progress); + break; + case PROP_PROGRESS_PULSE: + g_value_set_boolean (value, win->progress_pulse); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -624,6 +631,20 @@ meta_window_class_init (MetaWindowClass *klass) "Whether the window is set to appear on all workspaces", FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_props[PROP_PROGRESS] = + g_param_spec_uint ("progress", + "Progress", + "The progress of some long-running operation", + 0, + 100, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_props[PROP_PROGRESS_PULSE] = + g_param_spec_boolean ("progress-pulse", + "Indeterminate progress", + "Show indeterminate or ongoing progress of an operation.", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, PROP_LAST, obj_props); @@ -1069,6 +1090,7 @@ _meta_window_shared_new (MetaDisplay *display, window->title = NULL; window->icon = NULL; window->mini_icon = NULL; + window->theme_icon_name = NULL; window->frame = NULL; window->has_focus = FALSE; @@ -8658,3 +8680,25 @@ meta_window_get_client_type (MetaWindow *window) { return window->client_type; } + +/** + * meta_window_get_icon_name: + * @window: a #MetaWindow + * + * Returns the currently set icon name or icon path for the window. + * + * Note: + * + * This will currently only be non-NULL for programs that use XAppGtkWindow + * in place of GtkWindow and use xapp_gtk_window_set_icon_name() or + * set_icon_from_file(). These methods will need to be used explicitly in + * C programs, but for introspection use you should not need to treat it any + * differently (except for using the correct window class.) + */ +const char * +meta_window_get_icon_name (MetaWindow *window) +{ + g_return_val_if_fail (META_IS_WINDOW (window), NULL); + + return window->theme_icon_name; +} diff --git a/src/meta/window.h b/src/meta/window.h index 78fe920ed..42e4d60da 100644 --- a/src/meta/window.h +++ b/src/meta/window.h @@ -455,4 +455,7 @@ uint64_t meta_window_get_id (MetaWindow *window); META_EXPORT MetaWindowClientType meta_window_get_client_type (MetaWindow *window); +META_EXPORT +const char *meta_window_get_icon_name (MetaWindow *window); + #endif diff --git a/src/x11/atomnames.h b/src/x11/atomnames.h index 4b25b099a..6bc245df9 100644 --- a/src/x11/atomnames.h +++ b/src/x11/atomnames.h @@ -181,6 +181,8 @@ item(_NET_WM_FRAME_DRAWN) item(_NET_WM_FRAME_TIMINGS) item(_NET_WM_WINDOW_OPACITY) item(_NET_RESTACK_WINDOW) - +item(_NET_WM_XAPP_ICON_NAME) +item(_NET_WM_XAPP_PROGRESS) +item(_NET_WM_XAPP_PROGRESS_PULSE) /* eof atomnames.h */ diff --git a/src/x11/window-props.c b/src/x11/window-props.c index 5d8e8e48e..6884567bf 100644 --- a/src/x11/window-props.c +++ b/src/x11/window-props.c @@ -1879,6 +1879,85 @@ reload_window_opacity (MetaWindow *window, meta_window_set_opacity (window, opacity); } +static void +reload_theme_icon_name (MetaWindow *window, + MetaPropValue *value, + gboolean initial) +{ + free (window->theme_icon_name); + window->theme_icon_name = NULL; + + if (value->type != META_PROP_VALUE_INVALID) + window->theme_icon_name = g_strdup (value->v.str); + + meta_verbose ("Window theme icon name or path is \"%s\"\n", + window->theme_icon_name ? window->theme_icon_name : "unset"); +} + +static void +reload_progress (MetaWindow *window, + MetaPropValue *value, + gboolean initial) +{ + if (value->type != META_PROP_VALUE_INVALID) + { + if (window->progress != value->v.cardinal) + { + window->progress = value->v.cardinal; + g_object_notify ((GObject*) window, "progress"); + + meta_topic (META_DEBUG_WINDOW_STATE, + "Read XAppGtkWindow progress prop %u for %s\n", + window->progress, window->desc); + } + } + else + { + if (window->progress != 0) + { + window->progress = 0; + g_object_notify ((GObject*) window, "progress"); + + meta_topic (META_DEBUG_WINDOW_STATE, + "Read XAppGtkWindow progress prop %u for %s\n", + window->progress, window->desc); + } + } +} + +static void +reload_progress_pulse (MetaWindow *window, + MetaPropValue *value, + gboolean initial) +{ + if (value->type != META_PROP_VALUE_INVALID) + { + gboolean new_val = value->v.cardinal == 1; + + if (window->progress_pulse != new_val) + { + window->progress_pulse = new_val; + g_object_notify ((GObject*) window, "progress-pulse"); + + meta_topic (META_DEBUG_WINDOW_STATE, + "Read XAppGtkWindow progress-pulse prop %s for %s\n", + window->progress_pulse ? "TRUE" : "FALSE", window->desc); + } + } + else + { + if (window->progress_pulse) + { + window->progress_pulse = FALSE; + g_object_notify ((GObject*) window, "progress-pulse"); + + meta_topic (META_DEBUG_WINDOW_STATE, + "Read XAppGtkWindow progress-pulse prop %s for %s\n", + window->progress_pulse ? "TRUE" : "FALSE", window->desc); + } + } +} + #define RELOAD_STRING(var_name, propname) \ static void \ reload_ ## var_name (MetaWindow *window, \ @@ -1975,6 +2054,9 @@ meta_x11_display_init_window_prop_hooks (MetaX11Display *x11_display) { x11_display->atom__NET_WM_STRUT_PARTIAL, META_PROP_VALUE_INVALID, reload_struts, NONE }, { x11_display->atom__NET_WM_BYPASS_COMPOSITOR, META_PROP_VALUE_CARDINAL, reload_bypass_compositor, LOAD_INIT | INCLUDE_OR }, { x11_display->atom__NET_WM_WINDOW_OPACITY, META_PROP_VALUE_CARDINAL, reload_window_opacity, LOAD_INIT | INCLUDE_OR }, + { x11_display->atom__NET_WM_XAPP_ICON_NAME, META_PROP_VALUE_UTF8, reload_theme_icon_name, LOAD_INIT | INCLUDE_OR }, + { x11_display->atom__NET_WM_XAPP_PROGRESS, META_PROP_VALUE_CARDINAL, reload_progress, LOAD_INIT | INCLUDE_OR }, + { x11_display->atom__NET_WM_XAPP_PROGRESS_PULSE, META_PROP_VALUE_CARDINAL, reload_progress_pulse, LOAD_INIT | INCLUDE_OR }, { 0 }, }; From 26e537b4f4ba12c278e80d537ec6cb05c961d871 Mon Sep 17 00:00:00 2001 From: Michael Webster <miketwebster@gmail.com> Date: Mon, 31 Jan 2022 13:01:39 -0500 Subject: [PATCH 09/36] x11 backend: Don't let muffin reset the keyboard layout any time some outside force tries to change it (libgnomekbd). --- src/backends/x11/cm/meta-backend-x11-cm.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/backends/x11/cm/meta-backend-x11-cm.c b/src/backends/x11/cm/meta-backend-x11-cm.c index e5ebd68f2..fb1cdf86c 100644 --- a/src/backends/x11/cm/meta-backend-x11-cm.c +++ b/src/backends/x11/cm/meta-backend-x11-cm.c @@ -360,9 +360,10 @@ meta_backend_x11_cm_handle_host_xevent (MetaBackendX11 *backend_x11, case XkbStateNotify: if (xkb_ev->state.changed & XkbGroupLockMask) { - if (x11_cm->locked_group != xkb_ev->state.locked_group) - XkbLockGroup (xdisplay, XkbUseCoreKbd, - x11_cm->locked_group); + // TODO: Restore this, ditch libgnomekbd + // if (x11_cm->locked_group != xkb_ev->state.locked_group) + // XkbLockGroup (xdisplay, XkbUseCoreKbd, + // x11_cm->locked_group); } break; default: From ceb6fc72e6dcb7a5d0b0040197bdccdb344cdc7d Mon Sep 17 00:00:00 2001 From: Michael Webster <miketwebster@gmail.com> Date: Tue, 1 Feb 2022 21:11:01 -0500 Subject: [PATCH 10/36] Freeze the window actor during unminimize. Otherwise the window position gets reset before the effect can start, breaking the animation. (most observable with terminal emulator for some reason). --- src/compositor/meta-window-actor.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 31e0cb607..919da582a 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -568,6 +568,7 @@ is_freeze_thaw_effect (MetaPluginEffect event) { case META_PLUGIN_DESTROY: case META_PLUGIN_SIZE_CHANGE: + case META_PLUGIN_UNMINIMIZE: return TRUE; break; default: From 3ba51ff0725cdda1a065e86b9a726fae47c99e31 Mon Sep 17 00:00:00 2001 From: Michael Webster <miketwebster@gmail.com> Date: Thu, 24 Feb 2022 12:26:56 -0500 Subject: [PATCH 11/36] Restore 'unredirect-fullscreen-windows' --- data/org.cinnamon.muffin.gschema.xml.in | 8 +++++ src/compositor/meta-surface-actor-x11.c | 2 +- src/core/prefs.c | 47 +++++++++++++++++-------- src/meta/prefs.h | 6 +++- 4 files changed, 46 insertions(+), 17 deletions(-) diff --git a/data/org.cinnamon.muffin.gschema.xml.in b/data/org.cinnamon.muffin.gschema.xml.in index d0b555ab7..d42a88759 100644 --- a/data/org.cinnamon.muffin.gschema.xml.in +++ b/data/org.cinnamon.muffin.gschema.xml.in @@ -46,6 +46,14 @@ </description> </key> + <key name="unredirect-fullscreen-windows" type="b"> + <default>false</default> + <summary>Fullscreen windows are unredirected (i.e. they bypass compositing)</summary> + <description> + Determines whether fullscreen windows bypass compositing. False is better for vsync/screen-tearing, True gives games and apps i + </description> + </key> + <key name="workspaces-only-on-primary" type="b"> <default>false</default> <summary>Workspaces only on primary</summary> diff --git a/src/compositor/meta-surface-actor-x11.c b/src/compositor/meta-surface-actor-x11.c index 33d393a5b..7b2a742fd 100644 --- a/src/compositor/meta-surface-actor-x11.c +++ b/src/compositor/meta-surface-actor-x11.c @@ -277,7 +277,7 @@ meta_surface_actor_x11_should_unredirect (MetaSurfaceActorX11 *self) if (meta_window_is_override_redirect (window)) return TRUE; - if (self->does_full_damage) + if (self->does_full_damage && meta_prefs_get_unredirect_fullscreen_windows ()) return TRUE; return FALSE; diff --git a/src/core/prefs.c b/src/core/prefs.c index da37e3d8d..2f1736d0d 100644 --- a/src/core/prefs.c +++ b/src/core/prefs.c @@ -65,7 +65,7 @@ /* These are the different schemas we are keeping * a GSettings instance for */ #define SCHEMA_GENERAL "org.cinnamon.desktop.wm.preferences" -#define SCHEMA_MUTTER "org.cinnamon.muffin" +#define SCHEMA_MUFFIN "org.cinnamon.muffin" #define SCHEMA_INTERFACE "org.cinnamon.desktop.interface" #define SCHEMA_INPUT_SOURCES "org.cinnamon.desktop.input-sources" #define SCHEMA_MOUSE "org.cinnamon.desktop.peripherals.mouse" @@ -127,6 +127,7 @@ static gboolean workspaces_only_on_primary = FALSE; static char *iso_next_group_option = NULL; static MetaX11BackgroundTransition background_transition = META_X11_BACKGROUND_TRANSITION_BLEND; +static gboolean unredirect_fullscreen_windows = FALSE; static void handle_preference_update_enum (GSettings *settings, gchar *key); @@ -280,7 +281,7 @@ static MetaEnumPreference preferences_enum[] = }, { { "background-transition", - SCHEMA_MUTTER, + SCHEMA_MUFFIN, META_PREF_BACKGROUND_TRANSITION, }, &background_transition, @@ -292,14 +293,14 @@ static MetaBoolPreference preferences_bool[] = { { { "attach-modal-dialogs", - SCHEMA_MUTTER, + SCHEMA_MUFFIN, META_PREF_ATTACH_MODAL_DIALOGS, }, &attach_modal_dialogs, }, { { "center-new-windows", - SCHEMA_MUTTER, + SCHEMA_MUFFIN, META_PREF_CENTER_NEW_WINDOWS, }, ¢er_new_windows, @@ -320,7 +321,7 @@ static MetaBoolPreference preferences_bool[] = }, { { "dynamic-workspaces", - SCHEMA_MUTTER, + SCHEMA_MUFFIN, META_PREF_DYNAMIC_WORKSPACES, }, &dynamic_workspaces, @@ -341,7 +342,7 @@ static MetaBoolPreference preferences_bool[] = }, { { "focus-change-on-pointer-rest", - SCHEMA_MUTTER, + SCHEMA_MUFFIN, META_PREF_FOCUS_CHANGE_ON_POINTER_REST, }, &focus_change_on_pointer_rest @@ -383,21 +384,21 @@ static MetaBoolPreference preferences_bool[] = }, { { "edge-tiling", - SCHEMA_MUTTER, + SCHEMA_MUFFIN, META_PREF_EDGE_TILING, }, &edge_tiling, }, { { "workspaces-only-on-primary", - SCHEMA_MUTTER, + SCHEMA_MUFFIN, META_PREF_WORKSPACES_ONLY_ON_PRIMARY, }, &workspaces_only_on_primary, }, { { "auto-maximize", - SCHEMA_MUTTER, + SCHEMA_MUFFIN, META_PREF_AUTO_MAXIMIZE, }, &auto_maximize, @@ -409,6 +410,13 @@ static MetaBoolPreference preferences_bool[] = }, &locate_pointer_is_enabled, }, + { + { "unredirect-fullscreen-windows", + SCHEMA_MUFFIN, + META_PREF_UNREDIRECT_FULLSCREEN_WINDOWS, + }, + &unredirect_fullscreen_windows, + }, { { NULL, 0, 0 }, NULL }, }; @@ -448,7 +456,7 @@ static MetaStringPreference preferences_string[] = }, { { "overlay-key", - SCHEMA_MUTTER, + SCHEMA_MUFFIN, META_PREF_KEYBINDINGS, }, overlay_key_handler, @@ -456,7 +464,7 @@ static MetaStringPreference preferences_string[] = }, { { "locate-pointer-key", - SCHEMA_MUTTER, + SCHEMA_MUFFIN, META_PREF_KEYBINDINGS, }, locate_pointer_key_handler, @@ -504,7 +512,7 @@ static MetaIntPreference preferences_int[] = }, { { "draggable-border-width", - SCHEMA_MUTTER, + SCHEMA_MUFFIN, META_PREF_DRAGGABLE_BORDER_WIDTH, }, &draggable_border_width @@ -530,7 +538,7 @@ static MetaUintPreference preferences_uint[] = { { { "check-alive-timeout", - SCHEMA_MUTTER, + SCHEMA_MUFFIN, META_PREF_CHECK_ALIVE_TIMEOUT, }, &check_alive_timeout, @@ -1016,9 +1024,9 @@ meta_prefs_init (void) g_signal_connect (settings, "changed", G_CALLBACK (settings_changed), NULL); g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_GENERAL), settings); - settings = g_settings_new (SCHEMA_MUTTER); + settings = g_settings_new (SCHEMA_MUFFIN); g_signal_connect (settings, "changed", G_CALLBACK (settings_changed), NULL); - g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_MUTTER), settings); + g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_MUFFIN), settings); settings = g_settings_new (SCHEMA_MOUSE); g_signal_connect (settings, "changed", G_CALLBACK (settings_changed), NULL); @@ -1654,6 +1662,12 @@ meta_prefs_get_disable_workarounds (void) return disable_workarounds; } +gboolean +meta_prefs_get_unredirect_fullscreen_windows (void) +{ + return unredirect_fullscreen_windows; +} + #ifdef WITH_VERBOSE_MODE const char* meta_preference_to_string (MetaPreference pref) @@ -1765,6 +1779,9 @@ meta_preference_to_string (MetaPreference pref) case META_PREF_CHECK_ALIVE_TIMEOUT: return "CHECK_ALIVE_TIMEOUT"; + + case META_PREF_UNREDIRECT_FULLSCREEN_WINDOWS: + return "UNREDIRECT_FULLSCREEN_WINDOWS"; } return "(unknown)"; diff --git a/src/meta/prefs.h b/src/meta/prefs.h index 2ef2ef3a9..8c56b2e6d 100644 --- a/src/meta/prefs.h +++ b/src/meta/prefs.h @@ -106,7 +106,8 @@ typedef enum META_PREF_DRAG_THRESHOLD, META_PREF_LOCATE_POINTER, META_PREF_CHECK_ALIVE_TIMEOUT, - META_PREF_BACKGROUND_TRANSITION + META_PREF_BACKGROUND_TRANSITION, + META_PREF_UNREDIRECT_FULLSCREEN_WINDOWS } MetaPreference; typedef void (* MetaPrefsChangedFunc) (MetaPreference pref, @@ -237,6 +238,9 @@ int meta_prefs_get_draggable_border_width (void); META_EXPORT int meta_prefs_get_drag_threshold (void); +META_EXPORT +gboolean meta_prefs_get_unredirect_fullscreen_windows (void); + /** * MetaKeyBindingAction: * @META_KEYBINDING_ACTION_NONE: FILLME From e9e4b4da6a9922d25ae97e7ba8f4f32d7b2a4241 Mon Sep 17 00:00:00 2001 From: Michael Webster <miketwebster@gmail.com> Date: Thu, 24 Feb 2022 13:02:59 -0500 Subject: [PATCH 12/36] Restore workspace wraparound. --- data/org.cinnamon.muffin.gschema.xml.in | 9 ++ src/core/prefs.c | 17 +++ src/core/workspace.c | 160 ++++++++++++++++++------ src/meta/prefs.h | 5 +- src/meta/workspace.h | 6 + 5 files changed, 155 insertions(+), 42 deletions(-) diff --git a/data/org.cinnamon.muffin.gschema.xml.in b/data/org.cinnamon.muffin.gschema.xml.in index d42a88759..0641b085d 100644 --- a/data/org.cinnamon.muffin.gschema.xml.in +++ b/data/org.cinnamon.muffin.gschema.xml.in @@ -46,6 +46,15 @@ </description> </key> + <key name="workspace-cycle" type="b"> + <default>false</default> + <summary>Allow cycling through workspaces</summary> + <description> + Allows cycling through workspaces, going to the workspace at the other end + if you are at the left-most or right-most one. + </description> + </key> + <key name="unredirect-fullscreen-windows" type="b"> <default>false</default> <summary>Fullscreen windows are unredirected (i.e. they bypass compositing)</summary> diff --git a/src/core/prefs.c b/src/core/prefs.c index 2f1736d0d..df0d4ce04 100644 --- a/src/core/prefs.c +++ b/src/core/prefs.c @@ -88,6 +88,7 @@ static gboolean raise_on_click = TRUE; static gboolean center_new_windows = FALSE; static gboolean attach_modal_dialogs = FALSE; static int num_workspaces = 4; +static gboolean workspace_cycle = FALSE; static CDesktopTitlebarAction action_double_click_titlebar = C_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE; static CDesktopTitlebarAction action_middle_click_titlebar = C_DESKTOP_TITLEBAR_ACTION_LOWER; static CDesktopTitlebarAction action_right_click_titlebar = C_DESKTOP_TITLEBAR_ACTION_MENU; @@ -417,6 +418,13 @@ static MetaBoolPreference preferences_bool[] = }, &unredirect_fullscreen_windows, }, + { + { "workspace-cycle", + SCHEMA_MUFFIN, + META_PREF_WORKSPACE_CYCLE, + }, + &workspace_cycle, + }, { { NULL, 0, 0 }, NULL }, }; @@ -1668,6 +1676,12 @@ meta_prefs_get_unredirect_fullscreen_windows (void) return unredirect_fullscreen_windows; } +gboolean +meta_prefs_get_workspace_cycle (void) +{ + return workspace_cycle; +} + #ifdef WITH_VERBOSE_MODE const char* meta_preference_to_string (MetaPreference pref) @@ -1782,6 +1796,9 @@ meta_preference_to_string (MetaPreference pref) case META_PREF_UNREDIRECT_FULLSCREEN_WINDOWS: return "UNREDIRECT_FULLSCREEN_WINDOWS"; + + case META_PREF_WORKSPACE_CYCLE: + return "WORKSPACE_CYCLE"; } return "(unknown)"; diff --git a/src/core/workspace.c b/src/core/workspace.c index c437b1929..b83d3d359 100644 --- a/src/core/workspace.c +++ b/src/core/workspace.c @@ -437,29 +437,72 @@ meta_workspace_queue_calc_showing (MetaWorkspace *workspace) meta_window_queue (l->data, META_QUEUE_CALC_SHOWING); } -/** - * meta_workspace_activate_with_focus: - * @workspace: a #MetaWorkspace - * @focus_this: the #MetaWindow to be focused, or %NULL - * @timestamp: timestamp for @focus_this - * - * Switches to @workspace and possibly activates the window @focus_this. - * - * The window @focus_this is activated by calling meta_window_activate() - * which will unminimize it and transient parents, raise it and give it - * the focus. - * - * If a window is currently being moved by the user, it will be - * moved to @workspace. - * - * The advantage of calling this function instead of meta_workspace_activate() - * followed by meta_window_activate() is that it happens as a unit, so - * no other window gets focused first before @focus_this. - */ -void -meta_workspace_activate_with_focus (MetaWorkspace *workspace, - MetaWindow *focus_this, - guint32 timestamp) +static MetaMotionDirection +get_wrapped_horizontal_direction (gint from, + gint to, + MetaMotionDirection suggested_dir, + gint num_workspaces) +{ + MetaMotionDirection ret = 0; + gboolean wrap = meta_prefs_get_workspace_cycle(); + + if (suggested_dir != 0 && wrap) + { + if (meta_get_locale_direction () == META_LOCALE_DIRECTION_RTL) + { + if (suggested_dir == META_MOTION_LEFT) + suggested_dir = META_MOTION_RIGHT; + else + if (suggested_dir == META_MOTION_RIGHT) + suggested_dir = META_MOTION_LEFT; + } + + return suggested_dir; + } + + if (meta_get_locale_direction () == META_LOCALE_DIRECTION_RTL) + { + if (from < to) + { + if (wrap) + ret = (to - from) <= ((num_workspaces - to) + from) ? META_MOTION_LEFT : META_MOTION_RIGHT; + else + ret = META_MOTION_LEFT; + } + else if (from > to) + { + if (wrap) + ret = (from - to) <= ((num_workspaces - from) + to) ? META_MOTION_RIGHT : META_MOTION_LEFT; + else + ret = META_MOTION_RIGHT; + } + } + else + { + if (from < to) + { + if (wrap) + ret = (to - from) <= ((num_workspaces - to) + from) ? META_MOTION_RIGHT : META_MOTION_LEFT; + else + ret = META_MOTION_RIGHT; + } + else if (from > to) + { + if (wrap) + ret = (from - to) <= ((num_workspaces - from) + to) ? META_MOTION_LEFT : META_MOTION_RIGHT; + else + ret = META_MOTION_LEFT; + } + } + + return ret; +} + +static void +meta_workspace_activate_internal (MetaWorkspace *workspace, + MetaWindow *focus_this, + MetaMotionDirection suggested_dir, + guint32 timestamp) { MetaWorkspace *old; MetaWindow *move_window; @@ -534,20 +577,7 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace, meta_workspace_manager_calc_workspace_layout (workspace->manager, num_workspaces, new_space, &layout2); - if (meta_get_locale_direction () == META_LOCALE_DIRECTION_RTL) - { - if (layout1.current_col > layout2.current_col) - direction = META_MOTION_RIGHT; - else if (layout1.current_col < layout2.current_col) - direction = META_MOTION_LEFT; - } - else - { - if (layout1.current_col < layout2.current_col) - direction = META_MOTION_RIGHT; - else if (layout1.current_col > layout2.current_col) - direction = META_MOTION_LEFT; - } + direction = get_wrapped_horizontal_direction (layout1.current_col, layout2.current_col, suggested_dir, num_workspaces); if (layout1.current_row < layout2.current_row) { @@ -597,11 +627,57 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace, new_space, direction); } +/** + * meta_workspace_activate_with_focus: + * @workspace: a #MetaWorkspace + * @focus_this: the #MetaWindow to be focused, or %NULL + * @timestamp: timestamp for @focus_this + * + * Switches to @workspace and possibly activates the window @focus_this. + * + * The window @focus_this is activated by calling meta_window_activate() + * which will unminimize it and transient parents, raise it and give it + * the focus. + * + * If a window is currently being moved by the user, it will be + * moved to @workspace. + * + * The advantage of calling this function instead of meta_workspace_activate() + * followed by meta_window_activate() is that it happens as a unit, so + * no other window gets focused first before @focus_this. + */ +void +meta_workspace_activate_with_focus (MetaWorkspace *workspace, + MetaWindow *focus_this, + guint32 timestamp) +{ + meta_workspace_activate_internal (workspace, focus_this, 0, timestamp); +} + void meta_workspace_activate (MetaWorkspace *workspace, guint32 timestamp) { - meta_workspace_activate_with_focus (workspace, NULL, timestamp); + meta_workspace_activate_internal (workspace, NULL, 0, timestamp); +} + +/** + * meta_workspace_activate_with_direction_hint: + * @workspace: a #MetaWorkspace + * @direction: the suggested #MetaMotionDirection + * @timestamp: timestamp for @focus_this + * + * Switches to @workspace in the specified @direction (if possible) + */ + +void +meta_workspace_activate_with_direction_hint (MetaWorkspace *workspace, + MetaMotionDirection direction, + guint32 timestamp) +{ + g_return_if_fail (META_IS_WORKSPACE (workspace)); + + meta_workspace_activate_internal (workspace, NULL, direction, timestamp); } int @@ -1145,13 +1221,15 @@ meta_workspace_get_neighbor (MetaWorkspace *workspace, { MetaWorkspaceLayout layout; int i, current_space, num_workspaces; - gboolean ltr; + gboolean ltr, cycle; current_space = meta_workspace_index (workspace); num_workspaces = meta_workspace_manager_get_n_workspaces (workspace->manager); meta_workspace_manager_calc_workspace_layout (workspace->manager, num_workspaces, current_space, &layout); + cycle = meta_prefs_get_workspace_cycle(); + meta_verbose ("Getting neighbor of %d in direction %s\n", current_space, meta_motion_direction_to_string (direction)); @@ -1175,9 +1253,9 @@ meta_workspace_get_neighbor (MetaWorkspace *workspace, } if (layout.current_col < 0) - layout.current_col = 0; + layout.current_col = (cycle == 1) ? layout.cols - 1 : 0; if (layout.current_col >= layout.cols) - layout.current_col = layout.cols - 1; + layout.current_col = (cycle == 1) ? 0 : layout.cols - 1; if (layout.current_row < 0) layout.current_row = 0; if (layout.current_row >= layout.rows) diff --git a/src/meta/prefs.h b/src/meta/prefs.h index 8c56b2e6d..ca59340e5 100644 --- a/src/meta/prefs.h +++ b/src/meta/prefs.h @@ -107,7 +107,8 @@ typedef enum META_PREF_LOCATE_POINTER, META_PREF_CHECK_ALIVE_TIMEOUT, META_PREF_BACKGROUND_TRANSITION, - META_PREF_UNREDIRECT_FULLSCREEN_WINDOWS + META_PREF_UNREDIRECT_FULLSCREEN_WINDOWS, + META_PREF_WORKSPACE_CYCLE } MetaPreference; typedef void (* MetaPrefsChangedFunc) (MetaPreference pref, @@ -241,6 +242,8 @@ int meta_prefs_get_drag_threshold (void); META_EXPORT gboolean meta_prefs_get_unredirect_fullscreen_windows (void); +META_EXPORT +gboolean meta_prefs_get_workspace_cycle (void); /** * MetaKeyBindingAction: * @META_KEYBINDING_ACTION_NONE: FILLME diff --git a/src/meta/workspace.h b/src/meta/workspace.h index 99aebee5d..3986feca7 100644 --- a/src/meta/workspace.h +++ b/src/meta/workspace.h @@ -62,6 +62,12 @@ void meta_workspace_activate_with_focus (MetaWorkspace *workspace, MetaWindow *focus_this, guint32 timestamp); +META_EXPORT +void +meta_workspace_activate_with_direction_hint (MetaWorkspace *workspace, + MetaMotionDirection direction, + guint32 timestamp); + META_EXPORT void meta_workspace_set_builtin_struts (MetaWorkspace *workspace, GSList *struts); From f10470da12782fccb6f2724f294bda1ee48c03dc Mon Sep 17 00:00:00 2001 From: Michael Webster <miketwebster@gmail.com> Date: Fri, 25 Feb 2022 13:12:29 -0500 Subject: [PATCH 13/36] Restore additional titlebar actions. --- src/core/prefs.c | 56 +++++++++++++++++++- src/core/window-private.h | 3 ++ src/core/window.c | 19 +++++++ src/meta/prefs.h | 12 ++++- src/ui/frames.c | 104 +++++++++++++++++++++++++++++++++++++- 5 files changed, 190 insertions(+), 4 deletions(-) diff --git a/src/core/prefs.c b/src/core/prefs.c index df0d4ce04..cce148027 100644 --- a/src/core/prefs.c +++ b/src/core/prefs.c @@ -92,6 +92,8 @@ static gboolean workspace_cycle = FALSE; static CDesktopTitlebarAction action_double_click_titlebar = C_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE; static CDesktopTitlebarAction action_middle_click_titlebar = C_DESKTOP_TITLEBAR_ACTION_LOWER; static CDesktopTitlebarAction action_right_click_titlebar = C_DESKTOP_TITLEBAR_ACTION_MENU; +static CDesktopTitlebarScrollAction action_scroll_titlebar = C_DESKTOP_TITLEBAR_SCROLL_ACTION_NONE; +static int min_window_opacity = 0; static gboolean dynamic_workspaces = FALSE; static gboolean disable_workarounds = FALSE; static gboolean auto_raise = FALSE; @@ -136,6 +138,8 @@ static gboolean update_binding (MetaKeyPref *binding, gchar **strokes); static gboolean update_key_binding (const char *key, gchar **strokes); +static void update_min_win_opacity (void); + static void settings_changed (GSettings *settings, gchar *key, @@ -280,6 +284,13 @@ static MetaEnumPreference preferences_enum[] = }, &action_right_click_titlebar, }, + { + { "action-scroll-titlebar", + SCHEMA_GENERAL, + META_PREF_ACTION_SCROLL_WHEEL_TITLEBAR, + }, + &action_scroll_titlebar, + }, { { "background-transition", SCHEMA_MUFFIN, @@ -1067,6 +1078,7 @@ meta_prefs_init (void) handle_preference_init_string_array (); handle_preference_init_int (); handle_preference_init_uint (); + update_min_win_opacity (); init_bindings (); } @@ -1119,7 +1131,17 @@ settings_changed (GSettings *settings, if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN)) handle_preference_update_bool (settings, key); else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32)) - handle_preference_update_int (settings, key); + { + if (strcmp (key, "min-window-opacity") == 0) + { + update_min_win_opacity (); + queue_changed (META_PREF_MIN_WIN_OPACITY); + } + else + { + handle_preference_update_int (settings, key); + } + } else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32)) handle_preference_update_uint (settings, key); else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING_ARRAY)) @@ -1728,6 +1750,9 @@ meta_preference_to_string (MetaPreference pref) case META_PREF_ACTION_RIGHT_CLICK_TITLEBAR: return "ACTION_RIGHT_CLICK_TITLEBAR"; + case META_PREF_ACTION_SCROLL_WHEEL_TITLEBAR: + return "ACTION_SCROLL_WHEEL_TITLEBAR"; + case META_PREF_AUTO_RAISE: return "AUTO_RAISE"; @@ -1799,6 +1824,9 @@ meta_preference_to_string (MetaPreference pref) case META_PREF_WORKSPACE_CYCLE: return "WORKSPACE_CYCLE"; + + case META_PREF_MIN_WIN_OPACITY: + return "MIN_WIN_OPACITY"; } return "(unknown)"; @@ -1941,6 +1969,18 @@ update_key_binding (const char *key, return FALSE; } +static void +update_min_win_opacity (void) +{ + int pct; + int mapped; + + pct = g_settings_get_int (SETTINGS (SCHEMA_GENERAL), "min-window-opacity"); + mapped = (int)(((double)pct / 100.0) * 255.0); + + min_window_opacity = CLAMP (mapped, 0, 255); +} + const char* meta_prefs_get_workspace_name (int i) { @@ -2189,6 +2229,12 @@ meta_prefs_get_action_right_click_titlebar (void) return action_right_click_titlebar; } +CDesktopTitlebarScrollAction +meta_prefs_get_action_scroll_wheel_titlebar (void) +{ + return action_scroll_titlebar; +} + gboolean meta_prefs_get_auto_raise (void) { @@ -2286,4 +2332,10 @@ MetaX11BackgroundTransition meta_prefs_get_background_transition (void) { return background_transition; -} \ No newline at end of file +} + +gint +meta_prefs_get_min_win_opacity (void) +{ + return min_window_opacity; +} diff --git a/src/core/window-private.h b/src/core/window-private.h index ca5d2f404..2526736cc 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -823,6 +823,9 @@ void meta_window_set_transient_for (MetaWindow *window, void meta_window_set_opacity (MetaWindow *window, guint8 opacity); +void meta_window_increase_opacity (MetaWindow *window); +void meta_window_decrease_opacity (MetaWindow *window); + void meta_window_handle_enter (MetaWindow *window, guint32 timestamp, guint root_x, diff --git a/src/core/window.c b/src/core/window.c index 1057d93b4..781ae422e 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -8131,6 +8131,25 @@ meta_window_set_opacity (MetaWindow *window, meta_compositor_window_opacity_changed (window->display->compositor, window); } +#define OPACITY_STEP 32 + +void +meta_window_increase_opacity (MetaWindow *window) +{ + window->opacity = MIN (255, window->opacity + OPACITY_STEP); + + meta_compositor_window_opacity_changed (window->display->compositor, window); +} + +void +meta_window_decrease_opacity (MetaWindow *window) +{ + window->opacity = MAX (meta_prefs_get_min_win_opacity (), + window->opacity - OPACITY_STEP); + + meta_compositor_window_opacity_changed (window->display->compositor, window); +} + static void reset_ignored_crossing_serials (MetaDisplay *display) { diff --git a/src/meta/prefs.h b/src/meta/prefs.h index ca59340e5..a203f31d2 100644 --- a/src/meta/prefs.h +++ b/src/meta/prefs.h @@ -40,6 +40,7 @@ * @META_PREF_ACTION_DOUBLE_CLICK_TITLEBAR: action double click titlebar * @META_PREF_ACTION_MIDDLE_CLICK_TITLEBAR: action middle click titlebar * @META_PREF_ACTION_RIGHT_CLICK_TITLEBAR: action right click titlebar + * @META_PREF_ACTION_SCROLL_WHEEL_TITLEBAR: action scroll wheel titlebar * @META_PREF_AUTO_RAISE: auto-raise * @META_PREF_AUTO_RAISE_DELAY: auto-raise delay * @META_PREF_FOCUS_CHANGE_ON_POINTER_REST: focus change on pointer rest @@ -79,6 +80,7 @@ typedef enum META_PREF_ACTION_DOUBLE_CLICK_TITLEBAR, META_PREF_ACTION_MIDDLE_CLICK_TITLEBAR, META_PREF_ACTION_RIGHT_CLICK_TITLEBAR, + META_PREF_ACTION_SCROLL_WHEEL_TITLEBAR, META_PREF_AUTO_RAISE, META_PREF_AUTO_RAISE_DELAY, META_PREF_FOCUS_CHANGE_ON_POINTER_REST, @@ -108,7 +110,8 @@ typedef enum META_PREF_CHECK_ALIVE_TIMEOUT, META_PREF_BACKGROUND_TRANSITION, META_PREF_UNREDIRECT_FULLSCREEN_WINDOWS, - META_PREF_WORKSPACE_CYCLE + META_PREF_WORKSPACE_CYCLE, + META_PREF_MIN_WIN_OPACITY } MetaPreference; typedef void (* MetaPrefsChangedFunc) (MetaPreference pref, @@ -205,6 +208,9 @@ CDesktopTitlebarAction meta_prefs_get_action_middle_click_titlebar (void); META_EXPORT CDesktopTitlebarAction meta_prefs_get_action_right_click_titlebar (void); +META_EXPORT +CDesktopTitlebarScrollAction meta_prefs_get_action_scroll_wheel_titlebar (void); + META_EXPORT void meta_prefs_set_num_workspaces (int n_workspaces); @@ -244,6 +250,10 @@ gboolean meta_prefs_get_unredirect_fullscreen_windows (void); META_EXPORT gboolean meta_prefs_get_workspace_cycle (void); + +META_EXPORT +gint meta_prefs_get_min_win_opacity (void); + /** * MetaKeyBindingAction: * @META_KEYBINDING_ACTION_NONE: FILLME diff --git a/src/ui/frames.c b/src/ui/frames.c index 0486dad91..1ee53e74a 100644 --- a/src/ui/frames.c +++ b/src/ui/frames.c @@ -77,6 +77,7 @@ enum META_ACTION_RIGHT_CLICK, META_ACTION_MIDDLE_CLICK, META_ACTION_DOUBLE_CLICK, + META_ACTION_SCROLL, META_ACTION_IGNORE }; @@ -774,7 +775,8 @@ meta_frame_titlebar_event (MetaUIFrame *frame, float x, y; g_assert (event->type == CLUTTER_BUTTON_PRESS || - event->type == CLUTTER_TOUCH_BEGIN); + event->type == CLUTTER_TOUCH_BEGIN || + event->type == CLUTTER_SCROLL); x11_display = frame->frames->x11_display; @@ -842,12 +844,69 @@ meta_frame_titlebar_event (MetaUIFrame *frame, evtime); break; + case C_DESKTOP_TITLEBAR_ACTION_TOGGLE_STUCK: + { + if (flags & META_FRAME_STUCK) + { + meta_window_unstick (frame->meta_window); + } + else + { + meta_window_stick (frame->meta_window); + } + } + break; + + case C_DESKTOP_TITLEBAR_ACTION_TOGGLE_ABOVE: + { + if (flags & META_FRAME_ABOVE) + { + meta_window_unmake_above (frame->meta_window); + } + else + { + meta_window_make_above (frame->meta_window); + } + } + break; + case C_DESKTOP_TITLEBAR_ACTION_MENU: meta_x11_wm_show_window_menu (x11_display, frame->xwindow, META_WINDOW_MENU_WM, x, y, evtime); break; + + case C_DESKTOP_TITLEBAR_SCROLL_ACTION_SHADE: + { + if (flags & META_FRAME_ALLOWS_SHADE) + { + if (event->scroll.direction == CLUTTER_SCROLL_UP && !(flags & META_FRAME_SHADED)) + { + meta_window_shade (frame->meta_window, evtime); + } + else + if (event->scroll.direction == CLUTTER_SCROLL_DOWN && (flags & META_FRAME_SHADED)) + { + meta_window_unshade (frame->meta_window, evtime); + } + } + } + break; + + case C_DESKTOP_TITLEBAR_SCROLL_ACTION_OPACITY: + { + if (event->scroll.direction == CLUTTER_SCROLL_UP) + { + meta_window_increase_opacity (frame->meta_window); + } + else + if (event->scroll.direction == CLUTTER_SCROLL_DOWN) + { + meta_window_decrease_opacity (frame->meta_window); + } + } + break; } return TRUE; @@ -882,6 +941,16 @@ meta_frame_right_click_event (MetaUIFrame *frame, action); } +static gboolean +meta_frame_scroll_event (MetaUIFrame *frame, + ClutterScrollEvent *event) +{ + int action = meta_prefs_get_action_scroll_wheel_titlebar(); + + return meta_frame_titlebar_event (frame, (const ClutterEvent *) event, + action); +} + static gboolean meta_frames_try_grab_op (MetaUIFrame *frame, MetaGrabOp op, @@ -999,6 +1068,10 @@ get_action (const ClutterEvent *event) { return META_ACTION_CLICK; } + else if (event->type == CLUTTER_SCROLL) + { + return META_ACTION_SCROLL; + } return META_ACTION_IGNORE; } @@ -1237,6 +1310,33 @@ handle_release_event (MetaUIFrame *frame, return TRUE; } +static gboolean +handle_scroll_event (MetaUIFrame *frame, + const ClutterEvent *event) +{ + MetaFrameControl control; + uint32_t action; + float x, y; + g_assert (event->type == CLUTTER_SCROLL); + + action = get_action (event); + if (action == META_ACTION_IGNORE) + return FALSE; + + clutter_event_get_coords (event, &x, &y); + control = get_control (frame, x, y); + + if (control != META_FRAME_CONTROL_TITLE) + { + return FALSE; + } + + if (meta_x11_wm_get_grab_op (frame->frames->x11_display) != META_GRAB_OP_NONE) + return FALSE; /* already up to something */ + + return meta_frame_scroll_event (frame, (ClutterScrollEvent *) event); +} + static void meta_ui_frame_update_prelit_control (MetaUIFrame *frame, MetaFrameControl control) @@ -1660,6 +1760,8 @@ meta_ui_frame_handle_event (MetaUIFrame *frame, case CLUTTER_BUTTON_RELEASE: case CLUTTER_TOUCH_END: return handle_release_event (frame, event); + case CLUTTER_SCROLL: + return handle_scroll_event (frame, event); case CLUTTER_MOTION: case CLUTTER_TOUCH_UPDATE: return handle_motion_event (frame, event); From 808f3cc29c5a1974b789ed24f6e074ccb66419fb Mon Sep 17 00:00:00 2001 From: Michael Webster <miketwebster@gmail.com> Date: Sat, 26 Feb 2022 12:19:33 -0500 Subject: [PATCH 14/36] Restore desktop zoom mousewheel handling. --- src/core/display-private.h | 2 + src/core/display.c | 22 ++++++++++ src/core/events.c | 20 ++++++++++ src/core/keybindings-private.h | 5 ++- src/core/keybindings.c | 64 +++++++++++++++++++++++++++-- src/core/prefs.c | 73 +++++++++++++++++++++++++++++++--- src/meta/prefs.h | 11 ++++- 7 files changed, 186 insertions(+), 11 deletions(-) diff --git a/src/core/display-private.h b/src/core/display-private.h index 60713b3af..81998130b 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -425,4 +425,6 @@ gboolean meta_display_init_x11_finish (MetaDisplay *display, void meta_display_shutdown_x11 (MetaDisplay *display); +void meta_display_a11y_zoom (MetaDisplay *display, gboolean in); + #endif diff --git a/src/core/display.c b/src/core/display.c index de97381ea..011e6d28b 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -159,6 +159,8 @@ enum WORKAREAS_CHANGED, CLOSING, INIT_XSERVER, + ZOOM_SCROLL_IN, + ZOOM_SCROLL_OUT, LAST_SIGNAL }; @@ -511,6 +513,20 @@ meta_display_class_init (MetaDisplayClass *klass) NULL, NULL, G_TYPE_BOOLEAN, 1, G_TYPE_TASK); + display_signals[ZOOM_SCROLL_IN] = + g_signal_new ("zoom-scroll-in", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 0); + + display_signals[ZOOM_SCROLL_OUT] = + g_signal_new ("zoom-scroll-out", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 0); + g_object_class_install_property (object_class, PROP_FOCUS_WINDOW, g_param_spec_object ("focus-window", @@ -3871,3 +3887,9 @@ meta_display_get_selection (MetaDisplay *display) { return display->selection; } + +void +meta_display_a11y_zoom (MetaDisplay *display, gboolean in) +{ + g_signal_emit (display, display_signals[in ? ZOOM_SCROLL_IN : ZOOM_SCROLL_OUT], 0); +} diff --git a/src/core/events.c b/src/core/events.c index 85e54ffda..0fae9ec02 100644 --- a/src/core/events.c +++ b/src/core/events.c @@ -271,6 +271,26 @@ meta_display_handle_event (MetaDisplay *display, } } + if (event->type == CLUTTER_SCROLL) + { + if (meta_prefs_get_mouse_zoom_enabled () && + ((event->scroll.modifier_state & ~meta_keybindings_get_ignored_modifier_mask (display)) == meta_keybindings_get_mouse_zoom_modifiers (display))) + { + if (clutter_event_get_scroll_direction (event) == CLUTTER_SCROLL_UP) + { + meta_display_a11y_zoom (display, TRUE); + } + else + if (clutter_event_get_scroll_direction (event) == CLUTTER_SCROLL_DOWN) + { + meta_display_a11y_zoom (display, FALSE); + } + + bypass_wayland = bypass_clutter = TRUE; + goto out; + } + } + if (event->type != CLUTTER_DEVICE_ADDED && event->type != CLUTTER_DEVICE_REMOVED) { diff --git a/src/core/keybindings-private.h b/src/core/keybindings-private.h index 81c23e1cf..1d42a8c55 100644 --- a/src/core/keybindings-private.h +++ b/src/core/keybindings-private.h @@ -125,6 +125,7 @@ typedef struct /* Alt+click button grabs */ ClutterModifierType window_grab_modifiers; + ClutterModifierType mouse_zoom_modifiers; } MetaKeyBindingManager; void meta_display_init_keys (MetaDisplay *display); @@ -138,9 +139,11 @@ void meta_window_ungrab_all_keys (MetaWindow *window, gboolean meta_keybindings_process_event (MetaDisplay *display, MetaWindow *window, const ClutterEvent *event); - +int meta_keybindings_get_mouse_zoom_modifiers (MetaDisplay *display); ClutterModifierType meta_display_get_window_grab_modifiers (MetaDisplay *display); +uint meta_keybindings_get_ignored_modifier_mask (MetaDisplay *display); + gboolean meta_prefs_add_keybinding (const char *name, GSettings *settings, const gchar **bindings, diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 1afdf746b..0182b1a76 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -1274,6 +1274,8 @@ meta_display_grab_window_buttons (MetaDisplay *display, * Grab Alt + button2 for resizing window. * Grab Alt + button3 for popping up window menu. * Grab Alt + Shift + button1 for snap-moving window. + * Grab Alt + button4 for scrolling in + * Grab Alt + button5 for scrolling out */ meta_verbose ("Grabbing window buttons for 0x%lx\n", xwindow); @@ -1298,6 +1300,18 @@ meta_display_grab_window_buttons (MetaDisplay *display, FALSE, 1, keys->window_grab_modifiers | ShiftMask); } + + if (meta_prefs_get_mouse_zoom_enabled () && keys->mouse_zoom_modifiers != 0) + { + int i; + for (i = 4; i < 6; i++) + { + meta_change_button_grab (keys, xwindow, + TRUE, + FALSE, + i, keys->mouse_zoom_modifiers); + } + } } void @@ -1306,11 +1320,21 @@ meta_display_ungrab_window_buttons (MetaDisplay *display, { MetaKeyBindingManager *keys = &display->key_binding_manager; - if (keys->window_grab_modifiers == 0) - return; + if (keys->window_grab_modifiers != 0) + { + meta_change_buttons_grab (keys, xwindow, FALSE, FALSE, + keys->window_grab_modifiers); + } + + int i = 4; + while (i < 6) + { + meta_change_button_grab (keys, xwindow, + FALSE, FALSE, i, + keys->mouse_zoom_modifiers); - meta_change_buttons_grab (keys, xwindow, FALSE, FALSE, - keys->window_grab_modifiers); + ++i; + } } static void @@ -1325,6 +1349,18 @@ update_window_grab_modifiers (MetaKeyBindingManager *keys) keys->window_grab_modifiers = mods; } +static void +update_mouse_zoom_modifiers (MetaKeyBindingManager *keys) +{ + MetaVirtualModifier virtual_mods; + unsigned int mods; + + virtual_mods = meta_prefs_get_mouse_button_zoom_mods (); + devirtualize_modifiers (keys, virtual_mods, &mods); + + keys->mouse_zoom_modifiers = mods; +} + void meta_display_grab_focus_window_button (MetaDisplay *display, MetaWindow *window) @@ -1383,6 +1419,8 @@ prefs_changed_callback (MetaPreference pref, grab_key_bindings (display); break; case META_PREF_MOUSE_BUTTON_MODS: + case META_PREF_MOUSE_BUTTON_ZOOM_MODS: + case META_PREF_MOUSE_ZOOM_ENABLED: { GSList *windows, *l; windows = meta_display_list_windows (display, META_LIST_DEFAULT); @@ -1394,6 +1432,7 @@ prefs_changed_callback (MetaPreference pref, } update_window_grab_modifiers (keys); + update_mouse_zoom_modifiers (keys); for (l = windows; l; l = l->next) { @@ -3732,6 +3771,22 @@ meta_keybindings_set_custom_handler (const gchar *name, return TRUE; } +int +meta_keybindings_get_mouse_zoom_modifiers (MetaDisplay *display) +{ + MetaKeyBindingManager *keys = &display->key_binding_manager; + + return keys->mouse_zoom_modifiers; +} + +uint +meta_keybindings_get_ignored_modifier_mask (MetaDisplay *display) +{ + MetaKeyBindingManager *keys = &display->key_binding_manager; + + return keys->ignored_modifier_mask; +} + static void init_builtin_key_bindings (MetaDisplay *display) { @@ -4563,6 +4618,7 @@ meta_display_init_keys (MetaDisplay *display) reload_combos (keys); update_window_grab_modifiers (keys); + update_mouse_zoom_modifiers (keys); /* Keys are actually grabbed in meta_screen_grab_keys() */ diff --git a/src/core/prefs.c b/src/core/prefs.c index cce148027..28432d6b2 100644 --- a/src/core/prefs.c +++ b/src/core/prefs.c @@ -58,6 +58,8 @@ #define KEY_GNOME_CURSOR_SIZE "cursor-size" #define KEY_XKB_OPTIONS "xkb-options" +#define KEY_MOUSEWHEEL_ZOOM_ENABLED "screen-magnifier-enabled" + #define KEY_OVERLAY_KEY "overlay-key" #define KEY_WORKSPACES_ONLY_ON_PRIMARY "workspaces-only-on-primary" #define KEY_LOCATE_POINTER "locate-pointer" @@ -69,6 +71,7 @@ #define SCHEMA_INTERFACE "org.cinnamon.desktop.interface" #define SCHEMA_INPUT_SOURCES "org.cinnamon.desktop.input-sources" #define SCHEMA_MOUSE "org.cinnamon.desktop.peripherals.mouse" +#define SCHEMA_A11Y_APPLICATIONS "org.cinnamon.desktop.a11y.applications" #define SETTINGS(s) g_hash_table_lookup (settings_schemas, (s)) @@ -80,6 +83,8 @@ static GHashTable *settings_schemas; static gboolean use_system_font = FALSE; static PangoFontDescription *titlebar_font = NULL; static MetaVirtualModifier mouse_button_mods = Mod1Mask; +static MetaVirtualModifier mouse_button_zoom_mods = Mod1Mask; +static gboolean mouse_zoom_enabled = FALSE; static MetaKeyCombo overlay_key_combo = { 0, 0, 0 }; static MetaKeyCombo locate_pointer_key_combo = { 0, 0, 0 }; static CDesktopFocusMode focus_mode = C_DESKTOP_FOCUS_MODE_CLICK; @@ -154,6 +159,7 @@ static void maybe_give_disable_workarounds_warning (void); static gboolean titlebar_handler (GVariant*, gpointer*, gpointer); static gboolean mouse_button_mods_handler (GVariant*, gpointer*, gpointer); +static gboolean mouse_button_mods_zoom_handler (GVariant*, gpointer*, gpointer); static gboolean button_layout_handler (GVariant*, gpointer*, gpointer); static gboolean overlay_key_handler (GVariant*, gpointer*, gpointer); static gboolean locate_pointer_key_handler (GVariant*, gpointer*, gpointer); @@ -436,6 +442,13 @@ static MetaBoolPreference preferences_bool[] = }, &workspace_cycle, }, + { + { KEY_MOUSEWHEEL_ZOOM_ENABLED, + SCHEMA_A11Y_APPLICATIONS, + META_PREF_MOUSE_ZOOM_ENABLED, + }, + &mouse_zoom_enabled, + }, { { NULL, 0, 0 }, NULL }, }; @@ -449,6 +462,14 @@ static MetaStringPreference preferences_string[] = mouse_button_mods_handler, NULL, }, + { + { "mouse-button-zoom-modifier", + SCHEMA_GENERAL, + META_PREF_MOUSE_BUTTON_ZOOM_MODS, + }, + mouse_button_mods_zoom_handler, + NULL, + }, { { KEY_TITLEBAR_FONT, SCHEMA_GENERAL, @@ -1051,6 +1072,12 @@ meta_prefs_init (void) g_signal_connect (settings, "changed", G_CALLBACK (settings_changed), NULL); g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_MOUSE), settings); + settings = g_settings_new (SCHEMA_A11Y_APPLICATIONS); + g_signal_connect (settings, "changed::" KEY_MOUSEWHEEL_ZOOM_ENABLED, + G_CALLBACK (settings_changed), NULL); + + g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_A11Y_APPLICATIONS), settings); + /* Individual keys we watch outside of our schemas */ settings = g_settings_new (SCHEMA_INTERFACE); g_signal_connect (settings, "changed::" KEY_GNOME_ACCESSIBILITY, @@ -1214,6 +1241,18 @@ meta_prefs_get_mouse_button_mods (void) return mouse_button_mods; } +MetaVirtualModifier +meta_prefs_get_mouse_button_zoom_mods (void) +{ + return mouse_button_zoom_mods; +} + +gboolean +meta_prefs_get_mouse_zoom_enabled (void) +{ + return mouse_zoom_enabled; +} + CDesktopFocusMode meta_prefs_get_focus_mode (void) { @@ -1320,9 +1359,11 @@ titlebar_handler (GVariant *value, } static gboolean -mouse_button_mods_handler (GVariant *value, +real_button_mods_handler (GVariant *value, gpointer *result, - gpointer data) + gpointer data, + MetaVirtualModifier *modifier, + MetaPreference pref_id) { MetaVirtualModifier mods; const gchar *string_value; @@ -1346,15 +1387,31 @@ mouse_button_mods_handler (GVariant *value, "Mouse button modifier has new GSettings value \"%s\"\n", string_value); - if (mods != mouse_button_mods) + if (mods != *modifier) { - mouse_button_mods = mods; - queue_changed (META_PREF_MOUSE_BUTTON_MODS); + *modifier = mods; + queue_changed (pref_id); } return TRUE; } +static gboolean +mouse_button_mods_handler (GVariant *value, + gpointer *result, + gpointer data) +{ + return real_button_mods_handler (value, result, data, &mouse_button_mods, META_PREF_MOUSE_BUTTON_MODS); +} + +static gboolean +mouse_button_mods_zoom_handler (GVariant *value, + gpointer *result, + gpointer data) +{ + return real_button_mods_handler (value, result, data, &mouse_button_zoom_mods, META_PREF_MOUSE_BUTTON_ZOOM_MODS); +} + static gboolean button_layout_equal (const MetaButtonLayout *a, const MetaButtonLayout *b) @@ -1714,6 +1771,12 @@ meta_preference_to_string (MetaPreference pref) case META_PREF_MOUSE_BUTTON_MODS: return "MOUSE_BUTTON_MODS"; + case META_PREF_MOUSE_BUTTON_ZOOM_MODS: + return "MOUSE_BUTTON_ZOOM_MODS"; + + case META_PREF_MOUSE_ZOOM_ENABLED: + return "MOUSE_ZOOM_ENABLED"; + case META_PREF_FOCUS_MODE: return "FOCUS_MODE"; diff --git a/src/meta/prefs.h b/src/meta/prefs.h index a203f31d2..1ab7d5095 100644 --- a/src/meta/prefs.h +++ b/src/meta/prefs.h @@ -33,6 +33,7 @@ /** * MetaPreference: * @META_PREF_MOUSE_BUTTON_MODS: mouse button modifiers + * @META_PREF_MOUSE_BUTTON_ZOOM_MODS: mouse button zoom modifiers * @META_PREF_FOCUS_MODE: focus mode * @META_PREF_FOCUS_NEW_WINDOWS: focus new windows * @META_PREF_ATTACH_MODAL_DIALOGS: attach modal dialogs @@ -73,6 +74,7 @@ typedef enum { META_PREF_MOUSE_BUTTON_MODS, + META_PREF_MOUSE_BUTTON_ZOOM_MODS, META_PREF_FOCUS_MODE, META_PREF_FOCUS_NEW_WINDOWS, META_PREF_ATTACH_MODAL_DIALOGS, @@ -111,7 +113,8 @@ typedef enum META_PREF_BACKGROUND_TRANSITION, META_PREF_UNREDIRECT_FULLSCREEN_WINDOWS, META_PREF_WORKSPACE_CYCLE, - META_PREF_MIN_WIN_OPACITY + META_PREF_MIN_WIN_OPACITY, + META_PREF_MOUSE_ZOOM_ENABLED } MetaPreference; typedef void (* MetaPrefsChangedFunc) (MetaPreference pref, @@ -134,6 +137,12 @@ const char* meta_preference_to_string (MetaPreference pref); META_EXPORT MetaVirtualModifier meta_prefs_get_mouse_button_mods (void); +META_EXPORT +MetaVirtualModifier meta_prefs_get_mouse_button_zoom_mods (void); + +META_EXPORT +gboolean meta_prefs_get_mouse_zoom_enabled (void); + META_EXPORT gint meta_prefs_get_mouse_button_resize (void); From 369dbf667e5efdc76e008500d04a79239954c7da Mon Sep 17 00:00:00 2001 From: Michael Webster <miketwebster@gmail.com> Date: Thu, 3 Mar 2022 14:19:08 -0500 Subject: [PATCH 15/36] Add MUFFIN_NO_SHADOWS support. --- src/compositor/meta-window-actor-x11.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/compositor/meta-window-actor-x11.c b/src/compositor/meta-window-actor-x11.c index 1974f6f27..d14fbd292 100644 --- a/src/compositor/meta-window-actor-x11.c +++ b/src/compositor/meta-window-actor-x11.c @@ -103,6 +103,8 @@ struct _MetaWindowActorX11 gboolean is_frozen; }; +static MetaShadowMode user_shadow_mode = META_SHADOW_MODE_AUTO; + static MetaCullableInterface *cullable_parent_iface; static void cullable_iface_init (MetaCullableInterface *iface); @@ -1628,6 +1630,8 @@ meta_window_actor_x11_class_init (MetaWindowActorX11Class *klass) g_object_class_install_property (object_class, PROP_SHADOW_CLASS, pspec); + + user_shadow_mode = (g_strcmp0 ("1", g_getenv ("MUFFIN_NO_SHADOWS")) == 0) ? META_SHADOW_MODE_FORCED_OFF : META_SHADOW_MODE_AUTO; } static void @@ -1642,4 +1646,6 @@ meta_window_actor_x11_init (MetaWindowActorX11 *self) "changed", G_CALLBACK (invalidate_shadow), self); + + self->shadow_mode = user_shadow_mode; } From 032eefc89e41ee490df900b253179f969a1f0e01 Mon Sep 17 00:00:00 2001 From: Michael Webster <miketwebster@gmail.com> Date: Wed, 9 Mar 2022 12:50:20 -0500 Subject: [PATCH 16/36] Implement migration from old cinnamon-monitors.xml Fractional scaling should be picked up ok, but base scale is dropped - muffin can figure out where this should be - maybe we'll revisit it. This hasn't been tested against complex, multi-monitor, multi- scale configurations, but should work fine. --- src/backends/meta-monitor-config-migration.c | 28 +++++++++++--------- src/backends/meta-monitor-config-migration.h | 1 + src/backends/meta-monitor-config-store.c | 5 ++-- src/backends/meta-monitor-manager.c | 7 ++++- 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/backends/meta-monitor-config-migration.c b/src/backends/meta-monitor-config-migration.c index 69c426cd7..b678cf2b7 100644 --- a/src/backends/meta-monitor-config-migration.c +++ b/src/backends/meta-monitor-config-migration.c @@ -69,6 +69,7 @@ typedef struct gboolean enabled; MetaRectangle rect; float refresh_rate; + float scale; MetaMonitorTransform transform; gboolean is_primary; @@ -268,7 +269,7 @@ handle_start_element (GMarkupParseContext *context, memset (&parser->key, 0, sizeof (MetaOutputKey)); memset (&parser->output, 0, sizeof (MetaOutputConfig)); - + parser->output.scale = -1.0f; parser->key.connector = g_strdup (name); parser->state = STATE_OUTPUT; } @@ -295,7 +296,8 @@ handle_start_element (GMarkupParseContext *context, strcmp (element_name, "reflect_y") == 0 || strcmp (element_name, "primary") == 0 || strcmp (element_name, "presentation") == 0 || - strcmp (element_name, "underscanning") == 0) && + strcmp (element_name, "underscanning") == 0 || + strcmp (element_name, "scale") == 0) && parser->unknown_count == 0) { parser->state = STATE_OUTPUT_FIELD; @@ -605,6 +607,8 @@ handle_text (GMarkupParseContext *context, parser->output.is_presentation = read_bool (text, text_len, error); else if (strcmp (parser->output_field, "underscanning") == 0) parser->output.is_underscanning = read_bool (text, text_len, error); + else if (strcmp (parser->output_field, "scale") == 0) + read_float (text, text_len, &parser->output.scale, error); else g_assert_not_reached (); return; @@ -935,7 +939,7 @@ ensure_logical_monitor (GList **logical_monitor_configs, .is_primary = output_config->is_primary, .is_presentation = output_config->is_presentation, .transform = output_config->transform, - .scale = -1.0, + .scale = output_config->scale, }; *logical_monitor_configs = g_list_append (*logical_monitor_configs, @@ -1152,16 +1156,13 @@ meta_migrate_old_monitors_config (MetaMonitorConfigStore *config_store, gboolean meta_migrate_old_user_monitors_config (MetaMonitorConfigStore *config_store, + const gchar *user_file_path, GError **error) { g_autofree char *backup_path = NULL; g_autoptr (GFile) backup_file = NULL; - g_autofree char *user_file_path = NULL; g_autoptr (GFile) user_file = NULL; - user_file_path = g_build_filename (g_get_user_config_dir (), - "monitors.xml", - NULL); user_file = g_file_new_for_path (user_file_path); backup_path = g_build_filename (g_get_user_config_dir (), "monitors-v1-backup.xml", @@ -1217,11 +1218,14 @@ meta_finish_monitors_config_migration (MetaMonitorManager *monitor_manager, return FALSE; } - logical_monitor_config->scale = - meta_monitor_manager_calculate_monitor_mode_scale (monitor_manager, - layout_mode, - monitor, - monitor_mode); + if (logical_monitor_config->scale < 0.0f) + { + logical_monitor_config->scale = + meta_monitor_manager_calculate_monitor_mode_scale (monitor_manager, + layout_mode, + monitor, + monitor_mode); + } } config->layout_mode = layout_mode; diff --git a/src/backends/meta-monitor-config-migration.h b/src/backends/meta-monitor-config-migration.h index 7b338ace2..e9eb9c8cd 100644 --- a/src/backends/meta-monitor-config-migration.h +++ b/src/backends/meta-monitor-config-migration.h @@ -31,6 +31,7 @@ gboolean meta_migrate_old_monitors_config (MetaMonitorConfigStore *config_store, META_EXPORT_TEST gboolean meta_migrate_old_user_monitors_config (MetaMonitorConfigStore *config_store, + const gchar *user_file_path, GError **error); META_EXPORT_TEST diff --git a/src/backends/meta-monitor-config-store.c b/src/backends/meta-monitor-config-store.c index 16cfc132b..8e9dc56ad 100644 --- a/src/backends/meta-monitor-config-store.c +++ b/src/backends/meta-monitor-config-store.c @@ -1559,8 +1559,9 @@ meta_monitor_config_store_constructed (GObject *object) } user_file_path = g_build_filename (g_get_user_config_dir (), - "monitors.xml", + "cinnamon-monitors.xml", NULL); + config_store->user_file = g_file_new_for_path (user_file_path); if (g_file_test (user_file_path, G_FILE_TEST_EXISTS)) @@ -1574,7 +1575,7 @@ meta_monitor_config_store_constructed (GObject *object) error->code == META_MONITOR_CONFIG_STORE_ERROR_NEEDS_MIGRATION) { g_clear_error (&error); - if (!meta_migrate_old_user_monitors_config (config_store, &error)) + if (!meta_migrate_old_user_monitors_config (config_store, user_file_path, &error)) { g_warning ("Failed to migrate old monitors config file: %s", error->message); diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c index 98ea9def4..9cc9cc985 100644 --- a/src/backends/meta-monitor-manager.c +++ b/src/backends/meta-monitor-manager.c @@ -62,6 +62,11 @@ #define DEFAULT_DISPLAY_CONFIGURATION_TIMEOUT 20 +// Fractional scales in cinnamon-monitors.xml are only stored to 6 digits, +// So migrating from 1.503759 to 1.5037590265274048 will fail because FLT_EPSILON +// is 0.00000011920928955078 which is less than the difference of those two scales. +#define CINNAMON_SCALE_EPSILON 0.000001f + enum { PROP_0, @@ -1872,7 +1877,7 @@ meta_monitor_manager_is_scale_supported (MetaMonitorManager *manager, monitor, monitor_mode, scale, - FLT_EPSILON, + CINNAMON_SCALE_EPSILON, NULL); } From a930ce6fd9cbc8c02c2f3cd1c9961b580b7248ae Mon Sep 17 00:00:00 2001 From: Michael Webster <miketwebster@gmail.com> Date: Wed, 9 Mar 2022 13:04:05 -0500 Subject: [PATCH 17/36] Enabled xrandr scaling by default. --- data/org.cinnamon.muffin.gschema.xml.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/org.cinnamon.muffin.gschema.xml.in b/data/org.cinnamon.muffin.gschema.xml.in index 0641b085d..d9b272dea 100644 --- a/data/org.cinnamon.muffin.gschema.xml.in +++ b/data/org.cinnamon.muffin.gschema.xml.in @@ -131,7 +131,7 @@ </key> <key name="experimental-features" type="as"> - <default>[]</default> + <default>['x11-randr-fractional-scaling']</default> <summary>Enable experimental features</summary> <description> To enable experimental features, add the feature keyword to the list. From 32fbf8783e8c66dc5652dd7f1cb7cab98edebe11 Mon Sep 17 00:00:00 2001 From: Michael Webster <miketwebster@gmail.com> Date: Fri, 18 Mar 2022 08:03:33 -0400 Subject: [PATCH 18/36] Re-implement corner/top/bottom tiling. --- data/org.cinnamon.muffin.gschema.xml.in | 22 +- src/compositor/meta-window-actor-x11.c | 2 +- src/core/constraints.c | 8 +- src/core/display-private.h | 8 +- src/core/display.c | 8 +- src/core/edge-resistance.c | 17 +- src/core/frame.c | 22 +- src/core/keybindings.c | 170 ++++++- src/core/prefs.c | 23 +- src/core/stack.c | 2 +- src/core/window-private.h | 40 +- src/core/window.c | 561 ++++++++++++++++++++---- src/meta/common.h | 19 +- src/meta/prefs.h | 18 +- src/meta/window.h | 2 +- src/ui/frames.c | 12 +- src/ui/theme.c | 6 +- 17 files changed, 793 insertions(+), 147 deletions(-) diff --git a/data/org.cinnamon.muffin.gschema.xml.in b/data/org.cinnamon.muffin.gschema.xml.in index d9b272dea..048c7c4de 100644 --- a/data/org.cinnamon.muffin.gschema.xml.in +++ b/data/org.cinnamon.muffin.gschema.xml.in @@ -27,7 +27,7 @@ </key> <key name="edge-tiling" type="b"> - <default>false</default> + <default>true</default> <summary>Enable edge tiling when dropping windows on screen edges</summary> <description> If enabled, dropping windows on vertical screen edges maximizes them @@ -36,6 +36,14 @@ </description> </key> + <key name="tile-maximize" type="b"> + <default>false</default> + <summary>Sets maximize as the tile action for the top edge of the screen</summary> + <description> + Makes tiling to the top maximize the window + </description> + </key> + <key name="dynamic-workspaces" type="b"> <default>false</default> <summary>Workspaces are managed dynamically</summary> @@ -184,14 +192,22 @@ </schema> <schema id="org.cinnamon.muffin.keybindings" path="/org/cinnamon/muffin/keybindings/"> - <key name="toggle-tiled-left" type="as"> + <key name="push-tile-left" type="as"> <default><![CDATA[['<Super>Left']]]></default> </key> - <key name="toggle-tiled-right" type="as"> + <key name="push-tile-right" type="as"> <default><![CDATA[['<Super>Right']]]></default> </key> + <key name="push-tile-up" type="as"> + <default><![CDATA[['<Super>Up']]]></default> + </key> + + <key name="push-tile-down" type="as"> + <default><![CDATA[['<Super>Down']]]></default> + </key> + <key name="tab-popup-select" type="as"> <default>[]</default> <summary>Select window from tab popup</summary> diff --git a/src/compositor/meta-window-actor-x11.c b/src/compositor/meta-window-actor-x11.c index d14fbd292..541537a44 100644 --- a/src/compositor/meta-window-actor-x11.c +++ b/src/compositor/meta-window-actor-x11.c @@ -518,7 +518,7 @@ has_shadow (MetaWindowActorX11 *actor_x11) * If we have two snap-tiled windows, we don't want the shadow to obstruct * the other window. */ - if (meta_window_get_tile_match (window)) + if (meta_window_get_tile_match (window, TRUE) || meta_window_get_tile_match (window, FALSE)) return FALSE; /* diff --git a/src/core/constraints.c b/src/core/constraints.c index 225ea3a85..4c4fdd3a5 100644 --- a/src/core/constraints.c +++ b/src/core/constraints.c @@ -1157,7 +1157,7 @@ constrain_maximization (MetaWindow *window, /* Determine whether constraint applies; exit if it doesn't */ if ((!window->maximized_horizontally && !window->maximized_vertically) || - META_WINDOW_TILED_SIDE_BY_SIDE (window)) + META_WINDOW_TILED (window)) return TRUE; /* Calculate target_size = maximized size of (window + frame) */ @@ -1244,7 +1244,7 @@ constrain_tiling (MetaWindow *window, return TRUE; /* Determine whether constraint applies; exit if it doesn't */ - if (!META_WINDOW_TILED_SIDE_BY_SIDE (window)) + if (!META_WINDOW_TILED (window)) return TRUE; /* Calculate target_size - as the tile previews need this as well, we @@ -1332,7 +1332,7 @@ constrain_size_increments (MetaWindow *window, /* Determine whether constraint applies; exit if it doesn't */ if (META_WINDOW_MAXIMIZED (window) || window->fullscreen || - META_WINDOW_TILED_SIDE_BY_SIDE (window) || + META_WINDOW_TILED (window) || info->action_type == ACTION_MOVE) return TRUE; @@ -1463,7 +1463,7 @@ constrain_aspect_ratio (MetaWindow *window, constraints_are_inconsistent = minr > maxr; if (constraints_are_inconsistent || META_WINDOW_MAXIMIZED (window) || window->fullscreen || - META_WINDOW_TILED_SIDE_BY_SIDE (window) || + META_WINDOW_TILED (window) || info->action_type == ACTION_MOVE) return TRUE; diff --git a/src/core/display-private.h b/src/core/display-private.h index 81998130b..fc922c020 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -70,6 +70,12 @@ typedef enum META_TILE_NONE, META_TILE_LEFT, META_TILE_RIGHT, + META_TILE_ULC, + META_TILE_LLC, + META_TILE_URC, + META_TILE_LRC, + META_TILE_TOP, + META_TILE_BOTTOM, META_TILE_MAXIMIZED } MetaTileMode; @@ -217,7 +223,7 @@ struct _MetaDisplay MetaStackTracker *stack_tracker; guint tile_preview_timeout_id; - guint preview_tile_mode : 2; + guint preview_tile_mode : 4; GSList *startup_sequences; diff --git a/src/core/display.c b/src/core/display.c index 011e6d28b..56929ca99 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -3223,7 +3223,13 @@ meta_display_update_tile_preview_timeout (gpointer data) { case META_TILE_LEFT: case META_TILE_RIGHT: - if (!META_WINDOW_TILED_SIDE_BY_SIDE (window)) + case META_TILE_TOP: + case META_TILE_BOTTOM: + case META_TILE_ULC: + case META_TILE_URC: + case META_TILE_LRC: + case META_TILE_LLC: + if (!META_WINDOW_TILED (window)) needs_preview = TRUE; break; diff --git a/src/core/edge-resistance.c b/src/core/edge-resistance.c index cf23e2604..f79e23a29 100644 --- a/src/core/edge-resistance.c +++ b/src/core/edge-resistance.c @@ -556,7 +556,7 @@ apply_edge_resistance_to_each_side (MetaDisplay *display, edge_data = display->grab_edge_resistance_data; - if (auto_snap && !META_WINDOW_TILED_SIDE_BY_SIDE (window)) + if (auto_snap && !META_WINDOW_TILED (window)) { /* Do the auto snapping instead of normal edge resistance; in all * cases, we allow snapping to opposite kinds of edges (e.g. left @@ -591,7 +591,7 @@ apply_edge_resistance_to_each_side (MetaDisplay *display, FALSE, keyboard_op); } - else if (auto_snap && META_WINDOW_TILED_SIDE_BY_SIDE (window)) + else if (auto_snap && META_WINDOW_TILED (window)) { MetaRectangle workarea; guint i; @@ -622,6 +622,7 @@ apply_edge_resistance_to_each_side (MetaDisplay *display, for (i = 0; i < G_N_ELEMENTS (tile_edges); i++) { guint horizontal_point = workarea.x + floor (workarea.width * tile_edges[i]); + guint vertical_point = workarea.y + floor (workarea.height * tile_edges[i]); if (ABS (horizontal_point - new_left) < 16) { @@ -633,6 +634,18 @@ apply_edge_resistance_to_each_side (MetaDisplay *display, new_left = workarea.x; new_right = horizontal_point; } + + + if (ABS (vertical_point - new_left) < 16) + { + new_top = vertical_point; + new_bottom = workarea.y + workarea.height; + } + else if (ABS (vertical_point - new_bottom) < 16) + { + new_top = workarea.y; + new_bottom = vertical_point; + } } } else diff --git a/src/core/frame.c b/src/core/frame.c index b58ad1173..d1047c84c 100644 --- a/src/core/frame.c +++ b/src/core/frame.c @@ -294,12 +294,30 @@ meta_frame_get_flags (MetaFrame *frame) if (META_WINDOW_MAXIMIZED (frame->window)) flags |= META_FRAME_MAXIMIZED; - if (META_WINDOW_TILED_LEFT (frame->window)) - flags |= META_FRAME_TILED_LEFT; + if (META_WINDOW_TILED_TOP (frame->window)) + flags |= META_FRAME_TILED_TOP; if (META_WINDOW_TILED_RIGHT (frame->window)) flags |= META_FRAME_TILED_RIGHT; + if (META_WINDOW_TILED_BOTTOM (frame->window)) + flags |= META_FRAME_TILED_BOTTOM; + + if (META_WINDOW_TILED_LEFT (frame->window)) + flags |= META_FRAME_TILED_LEFT; + + if (META_WINDOW_TILED_ULC (frame->window)) + flags |= META_FRAME_TILED_ULC; + + if (META_WINDOW_TILED_URC (frame->window)) + flags |= META_FRAME_TILED_URC; + + if (META_WINDOW_TILED_LRC (frame->window)) + flags |= META_FRAME_TILED_LRC; + + if (META_WINDOW_TILED_LLC (frame->window)) + flags |= META_FRAME_TILED_LLC; + if (frame->window->fullscreen) flags |= META_FRAME_FULLSCREEN; diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 0182b1a76..7bd13a301 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -3340,29 +3340,134 @@ handle_toggle_above (MetaDisplay *display, meta_window_make_above (window); } +static MetaTileMode +get_new_tile_mode (MetaTileMode direction, + MetaTileMode current) +{ + MetaTileMode ret = META_TILE_NONE; + switch (current) { + case META_TILE_NONE: + ret = direction; + break; + case META_TILE_MAXIMIZED: + if (direction == META_TILE_LEFT) + ret = META_TILE_LEFT; + else if (direction == META_TILE_RIGHT) + ret = META_TILE_RIGHT; + else if (direction == META_TILE_TOP) + ret = direction; + else if (direction == META_TILE_BOTTOM) + ret = META_TILE_TOP; + else + ret = META_TILE_NONE; + break; + case META_TILE_LEFT: + if (direction == META_TILE_LEFT) + ret = META_TILE_LEFT; + else if (direction == META_TILE_RIGHT) + ret = META_TILE_NONE; + else if (direction == META_TILE_TOP) + ret = META_TILE_ULC; + else + ret = META_TILE_LLC; + break; + case META_TILE_RIGHT: + if (direction == META_TILE_LEFT) + ret = META_TILE_NONE; + else if (direction == META_TILE_RIGHT) + ret = META_TILE_RIGHT; + else if (direction == META_TILE_TOP) + ret = META_TILE_URC; + else + ret = META_TILE_LRC; + break; + case META_TILE_TOP: + if (direction == META_TILE_LEFT) + ret = META_TILE_ULC; + else if (direction == META_TILE_RIGHT) + ret = META_TILE_URC; + else if (direction == META_TILE_TOP) + ret = META_TILE_MAXIMIZED; + else + ret = META_TILE_NONE; + break; + case META_TILE_BOTTOM: + if (direction == META_TILE_LEFT) + ret = META_TILE_LLC; + else if (direction == META_TILE_RIGHT) + ret = META_TILE_LRC; + else if (direction == META_TILE_TOP) + ret = META_TILE_NONE; + else + ret = META_TILE_BOTTOM; + break; + case META_TILE_ULC: + if (direction == META_TILE_LEFT) + ret = META_TILE_ULC; + else if (direction == META_TILE_RIGHT) + ret = META_TILE_TOP; + else if (direction == META_TILE_TOP) + ret = META_TILE_ULC; + else + ret = META_TILE_LEFT; + break; + case META_TILE_LLC: + if (direction == META_TILE_LEFT) + ret = META_TILE_LLC; + else if (direction == META_TILE_RIGHT) + ret = META_TILE_BOTTOM; + else if (direction == META_TILE_TOP) + ret = META_TILE_LEFT; + else + ret = META_TILE_LLC; + break; + case META_TILE_URC: + if (direction == META_TILE_LEFT) + ret = META_TILE_TOP; + else if (direction == META_TILE_RIGHT) + ret = META_TILE_URC; + else if (direction == META_TILE_TOP) + ret = META_TILE_URC; + else + ret = META_TILE_RIGHT; + break; + case META_TILE_LRC: + if (direction == META_TILE_LEFT) + ret = META_TILE_BOTTOM; + else if (direction == META_TILE_RIGHT) + ret = META_TILE_LRC; + else if (direction == META_TILE_TOP) + ret = META_TILE_RIGHT; + else + ret = META_TILE_LRC; + break; + default: + ret = current; + break; + } + return ret; +} + static void -handle_toggle_tiled (MetaDisplay *display, - MetaWindow *window, - ClutterKeyEvent *event, - MetaKeyBinding *binding, - gpointer dummy) +handle_tile_action (MetaDisplay *display, + MetaWindow *window, + ClutterKeyEvent *event, + MetaKeyBinding *binding, + gpointer dummy) { MetaTileMode mode = binding->handler->data; + MetaTileMode new_mode; - if ((META_WINDOW_TILED_LEFT (window) && mode == META_TILE_LEFT) || - (META_WINDOW_TILED_RIGHT (window) && mode == META_TILE_RIGHT)) - { - window->tile_monitor_number = window->saved_maximize ? window->monitor->number - : -1; - window->tile_mode = window->saved_maximize ? META_TILE_MAXIMIZED - : META_TILE_NONE; + new_mode = get_new_tile_mode (mode, META_WINDOW_MAXIMIZED (window) ? META_TILE_MAXIMIZED : window->tile_mode); - if (window->saved_maximize) - meta_window_maximize (window, META_MAXIMIZE_BOTH); - else - meta_window_unmaximize (window, META_MAXIMIZE_BOTH); + if (new_mode == window->tile_mode) + return; + + if (new_mode == META_TILE_NONE) + { + meta_window_unmaximize (window, META_MAXIMIZE_BOTH); } - else if (meta_window_can_tile_side_by_side (window)) + else { window->tile_monitor_number = window->monitor->number; /* Maximization constraints beat tiling constraints, so if the window @@ -3372,7 +3477,8 @@ handle_toggle_tiled (MetaDisplay *display, * save an additional roundtrip. */ window->maximized_horizontally = FALSE; - meta_window_tile (window, mode); + window->maximized_vertically = FALSE; + meta_window_tile (window, new_mode); } } @@ -4194,20 +4300,36 @@ init_builtin_key_bindings (MetaDisplay *display) handle_toggle_maximized, 0); add_builtin_keybinding (display, - "toggle-tiled-left", + "push-tile-left", + mutter_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, + META_KEYBINDING_ACTION_PUSH_TILE_LEFT, + handle_tile_action, META_TILE_LEFT); + + add_builtin_keybinding (display, + "push-tile-right", + mutter_keybindings, + META_KEY_BINDING_PER_WINDOW | + META_KEY_BINDING_IGNORE_AUTOREPEAT, + META_KEYBINDING_ACTION_PUSH_TILE_RIGHT, + handle_tile_action, META_TILE_RIGHT); + + add_builtin_keybinding (display, + "push-tile-up", mutter_keybindings, META_KEY_BINDING_PER_WINDOW | META_KEY_BINDING_IGNORE_AUTOREPEAT, - META_KEYBINDING_ACTION_TOGGLE_TILED_LEFT, - handle_toggle_tiled, META_TILE_LEFT); + META_KEYBINDING_ACTION_PUSH_TILE_UP, + handle_tile_action, META_TILE_TOP); add_builtin_keybinding (display, - "toggle-tiled-right", + "push-tile-down", mutter_keybindings, META_KEY_BINDING_PER_WINDOW | META_KEY_BINDING_IGNORE_AUTOREPEAT, - META_KEYBINDING_ACTION_TOGGLE_TILED_RIGHT, - handle_toggle_tiled, META_TILE_RIGHT); + META_KEYBINDING_ACTION_PUSH_TILE_DOWN, + handle_tile_action, META_TILE_BOTTOM); add_builtin_keybinding (display, "toggle-above", diff --git a/src/core/prefs.c b/src/core/prefs.c index 28432d6b2..5dd806bc7 100644 --- a/src/core/prefs.c +++ b/src/core/prefs.c @@ -136,6 +136,7 @@ static char *iso_next_group_option = NULL; static MetaX11BackgroundTransition background_transition = META_X11_BACKGROUND_TRANSITION_BLEND; static gboolean unredirect_fullscreen_windows = FALSE; +static gboolean tile_maximize = FALSE; static void handle_preference_update_enum (GSettings *settings, gchar *key); @@ -449,6 +450,13 @@ static MetaBoolPreference preferences_bool[] = }, &mouse_zoom_enabled, }, + { + { "tile-maximize", + SCHEMA_MUFFIN, + META_PREF_TILE_MAXIMIZE, + }, + &tile_maximize, + }, { { NULL, 0, 0 }, NULL }, }; @@ -1774,9 +1782,6 @@ meta_preference_to_string (MetaPreference pref) case META_PREF_MOUSE_BUTTON_ZOOM_MODS: return "MOUSE_BUTTON_ZOOM_MODS"; - case META_PREF_MOUSE_ZOOM_ENABLED: - return "MOUSE_ZOOM_ENABLED"; - case META_PREF_FOCUS_MODE: return "FOCUS_MODE"; @@ -1890,6 +1895,12 @@ meta_preference_to_string (MetaPreference pref) case META_PREF_MIN_WIN_OPACITY: return "MIN_WIN_OPACITY"; + + case META_PREF_MOUSE_ZOOM_ENABLED: + return "MOUSE_ZOOM_ENABLED"; + + case META_PREF_TILE_MAXIMIZE: + return "TILE_MAXIMIZE"; } return "(unknown)"; @@ -2334,6 +2345,12 @@ meta_prefs_get_edge_tiling (void) return edge_tiling; } +gboolean +meta_prefs_get_tile_maximize (void) +{ + return tile_maximize; +} + gboolean meta_prefs_get_auto_maximize (void) { diff --git a/src/core/stack.c b/src/core/stack.c index f7e0f1b90..ff143b953 100644 --- a/src/core/stack.c +++ b/src/core/stack.c @@ -434,7 +434,7 @@ meta_stack_update_window_tile_matches (MetaStack *stack, tmp = windows; while (tmp) { - meta_window_compute_tile_match ((MetaWindow *) tmp->data); + meta_window_compute_tile_matches ((MetaWindow *) tmp->data); tmp = tmp->next; } diff --git a/src/core/window-private.h b/src/core/window-private.h index 2526736cc..c992a44ad 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -255,6 +255,7 @@ struct _MetaWindow } edge_constraints; double tile_hfraction; + double tile_vfraction; uint64_t preferred_output_winsys_id; @@ -542,8 +543,11 @@ struct _MetaWindow /* Focused window that is (directly or indirectly) attached to this one */ MetaWindow *attached_focus_window; - /* The currently complementary tiled window, if any */ - MetaWindow *tile_match; + /* The currently complementary tiled windows, if any. */ + MetaWindow *vtile_match; + MetaWindow *htile_match; + + // MetaWindow *tile_match; /* Bypass compositor hints */ guint bypass_compositor; @@ -633,13 +637,29 @@ struct _MetaWindowClass (w)->maximized_vertically) #define META_WINDOW_MAXIMIZED_VERTICALLY(w) ((w)->maximized_vertically) #define META_WINDOW_MAXIMIZED_HORIZONTALLY(w) ((w)->maximized_horizontally) -#define META_WINDOW_TILED_SIDE_BY_SIDE(w) ((w)->maximized_vertically && \ - !(w)->maximized_horizontally && \ - (w)->tile_mode != META_TILE_NONE) -#define META_WINDOW_TILED_LEFT(w) (META_WINDOW_TILED_SIDE_BY_SIDE(w) && \ +#define META_WINDOW_TILED(w) ((w)->maximized_vertically && \ + !(w)->maximized_horizontally && \ + (w)->tile_mode != META_TILE_NONE) +#define META_WINDOW_TILED_LEFT(w) (META_WINDOW_TILED(w) && \ (w)->tile_mode == META_TILE_LEFT) -#define META_WINDOW_TILED_RIGHT(w) (META_WINDOW_TILED_SIDE_BY_SIDE(w) && \ +#define META_WINDOW_TILED_RIGHT(w) (META_WINDOW_TILED(w) && \ (w)->tile_mode == META_TILE_RIGHT) +#define META_WINDOW_TILED_LEFT_RIGHT(w) (META_WINDOW_TILED_LEFT(w) || META_WINDOW_TILED_RIGHT(w)) +#define META_WINDOW_TILED_TOP(w) (META_WINDOW_TILED(w) && \ + (w)->tile_mode == META_TILE_TOP) +#define META_WINDOW_TILED_BOTTOM(w) (META_WINDOW_TILED(w) && \ + (w)->tile_mode == META_TILE_BOTTOM) +#define META_WINDOW_TILED_TOP_BOTTOM(w) (META_WINDOW_TILED_TOP(w) || META_WINDOW_TILED_BOTTOM(w)) +#define META_WINDOW_TILED_ULC(w) (META_WINDOW_TILED(w) && \ + (w)->tile_mode == META_TILE_ULC) +#define META_WINDOW_TILED_URC(w) (META_WINDOW_TILED(w) && \ + (w)->tile_mode == META_TILE_URC) +#define META_WINDOW_TILED_LRC(w) (META_WINDOW_TILED(w) && \ + (w)->tile_mode == META_TILE_LRC) +#define META_WINDOW_TILED_LLC(w) (META_WINDOW_TILED(w) && \ + (w)->tile_mode == META_TILE_LLC) +#define META_WINDOW_TILED_CORNER(w) (META_WINDOW_TILED_ULC(w) || META_WINDOW_TILED_URC(w) || \ + META_WINDOW_TILED_LRC(w) || META_WINDOW_TILED_LLC(w)) #define META_WINDOW_TILED_MAXIMIZED(w)(META_WINDOW_MAXIMIZED(w) && \ (w)->tile_mode == META_TILE_MAXIMIZED) #define META_WINDOW_ALLOWS_MOVE(w) ((w)->has_move_func && !(w)->fullscreen) @@ -796,9 +816,11 @@ void meta_window_update_for_monitors_changed (MetaWindow *window); void meta_window_on_all_workspaces_changed (MetaWindow *window); gboolean meta_window_should_attach_to_parent (MetaWindow *window); -gboolean meta_window_can_tile_side_by_side (MetaWindow *window); +gboolean meta_window_can_tile_left_right (MetaWindow *window); +gboolean meta_window_can_tile_top_bottom (MetaWindow *window); +gboolean meta_window_can_tile_corner (MetaWindow *window); -void meta_window_compute_tile_match (MetaWindow *window); +void meta_window_compute_tile_matches (MetaWindow *window); gboolean meta_window_updates_are_frozen (MetaWindow *window); diff --git a/src/core/window.c b/src/core/window.c index 781ae422e..02d18640f 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -166,8 +166,9 @@ static void set_workspace_state (MetaWindow *window, gboolean on_all_workspaces, MetaWorkspace *workspace); -static MetaWindow * meta_window_find_tile_match (MetaWindow *window, - MetaTileMode mode); +static MetaWindow *meta_window_find_tile_match (MetaWindow *window, + MetaTileMode mode, + gboolean vertical); static void update_edge_constraints (MetaWindow *window); /* Idle handlers for the three queues (run with meta_later_add()). The @@ -1109,6 +1110,7 @@ _meta_window_shared_new (MetaDisplay *display, window->on_all_workspaces_requested = FALSE; window->tile_mode = META_TILE_NONE; window->tile_monitor_number = -1; + window->tile_vfraction = -1.; window->tile_hfraction = -1.; window->shaded = FALSE; window->initially_iconic = FALSE; @@ -1212,7 +1214,8 @@ _meta_window_shared_new (MetaDisplay *display, else window->preferred_output_winsys_id = UINT_MAX; - window->tile_match = NULL; + window->vtile_match = NULL; + window->htile_match = NULL; /* Assign this #MetaWindow a sequence number which can be used * for sorting. @@ -2831,7 +2834,7 @@ ensure_size_hints_satisfied (MetaRectangle *rect, static void meta_window_save_rect (MetaWindow *window) { - if (!(META_WINDOW_MAXIMIZED (window) || META_WINDOW_TILED_SIDE_BY_SIDE (window) || window->fullscreen)) + if (!(META_WINDOW_MAXIMIZED (window) || META_WINDOW_TILED (window) || window->fullscreen)) { /* save size/pos as appropriate args for move_resize */ if (!window->maximized_horizontally) @@ -3089,52 +3092,128 @@ meta_window_requested_dont_bypass_compositor (MetaWindow *window) } static void -meta_window_get_tile_fraction (MetaWindow *window, +get_default_tile_fractions (MetaTileMode for_mode, + double *hfraction, + double *vfraction) +{ + switch (for_mode) + { + case META_TILE_LEFT: + case META_TILE_RIGHT: + { + *hfraction = 0.5; + *vfraction = 1.0; + break; + } + case META_TILE_TOP: + case META_TILE_BOTTOM: + { + *hfraction = 1.0; + *vfraction = 0.5; + break; + } + case META_TILE_ULC: + case META_TILE_URC: + case META_TILE_LRC: + case META_TILE_LLC: + default: + { + *hfraction = 0.5; + *vfraction = 0.5; + break; + } + } +} + +static void +meta_window_get_tile_fractions (MetaWindow *window, MetaTileMode tile_mode, - double *fraction) + double *hfraction, + double *vfraction) { - MetaWindow *tile_match; + MetaWindow *htile_match, *vtile_match; + double new_hfraction, new_vfraction; /* Make sure the tile match is up-to-date and matches the * passed in mode rather than the current state */ - tile_match = meta_window_find_tile_match (window, tile_mode); if (tile_mode == META_TILE_NONE) - *fraction = -1.; + { + *hfraction = -1.; + *vfraction = -1.; + return; + } else if (tile_mode == META_TILE_MAXIMIZED) - *fraction = 1.; - else if (tile_match) - *fraction = 1. - tile_match->tile_hfraction; - else if (META_WINDOW_TILED_SIDE_BY_SIDE (window)) + { + *hfraction = 1.; + *vfraction = 1.; + return; + } + + // FIXME: should we fill both or just vtile if htile fails - both i think. + htile_match = meta_window_find_tile_match (window, tile_mode, FALSE); + vtile_match = meta_window_find_tile_match (window, tile_mode, TRUE); + + get_default_tile_fractions (tile_mode, &new_hfraction, &new_vfraction); + + if (vtile_match) + { + new_vfraction = 1. - vtile_match->tile_vfraction; + } + + if (htile_match) + { + new_hfraction = 1. - htile_match->tile_hfraction; + } + + if (META_WINDOW_TILED (window)) { if (window->tile_mode != tile_mode) - *fraction = 1. - window->tile_hfraction; + { + new_hfraction = 1. - window->tile_hfraction; + new_vfraction = 1. - window->tile_vfraction; + } else - *fraction = window->tile_hfraction; + { + if (!htile_match) + { + new_hfraction = window->tile_hfraction; + } + if (!vtile_match) + { + new_vfraction = window->tile_vfraction; + } + } } - else - *fraction = .5; + + *hfraction = new_hfraction; + *vfraction = new_vfraction; } static void -meta_window_update_tile_fraction (MetaWindow *window, - int new_w, - int new_h) +meta_window_update_tile_fractions (MetaWindow *window, + int new_w, + int new_h) { - MetaWindow *tile_match = window->tile_match; + MetaWindow *vtile_match = window->vtile_match; + MetaWindow *htile_match = window->htile_match; MetaRectangle work_area; - if (!META_WINDOW_TILED_SIDE_BY_SIDE (window)) + if (!META_WINDOW_TILED (window)) return; meta_window_get_work_area_for_monitor (window, window->tile_monitor_number, &work_area); window->tile_hfraction = (double)new_w / work_area.width; + window->tile_vfraction = (double)new_h / work_area.height; - if (tile_match && window->display->grab_window == window) - meta_window_tile (tile_match, tile_match->tile_mode); + if (htile_match && window->display->grab_window == window) + meta_window_tile (htile_match, htile_match->tile_mode); + + if (vtile_match && window->display->grab_window == window) + meta_window_tile (vtile_match, vtile_match->tile_mode); } static void @@ -3159,7 +3238,7 @@ update_edge_constraints (MetaWindow *window) case META_TILE_LEFT: window->edge_constraints.top = META_EDGE_CONSTRAINT_MONITOR; - if (window->tile_match) + if (window->htile_match) window->edge_constraints.right = META_EDGE_CONSTRAINT_WINDOW; else window->edge_constraints.right = META_EDGE_CONSTRAINT_NONE; @@ -3173,13 +3252,101 @@ update_edge_constraints (MetaWindow *window) window->edge_constraints.right = META_EDGE_CONSTRAINT_MONITOR; window->edge_constraints.bottom = META_EDGE_CONSTRAINT_MONITOR; - if (window->tile_match) + if (window->htile_match) + window->edge_constraints.left = META_EDGE_CONSTRAINT_WINDOW; + else + window->edge_constraints.left = META_EDGE_CONSTRAINT_NONE; + break; + + case META_TILE_TOP: + window->edge_constraints.top = META_EDGE_CONSTRAINT_MONITOR; + window->edge_constraints.right = META_EDGE_CONSTRAINT_MONITOR; + + if (window->vtile_match) + window->edge_constraints.bottom = META_EDGE_CONSTRAINT_WINDOW; + else + window->edge_constraints.bottom = META_EDGE_CONSTRAINT_NONE; + + window->edge_constraints.left = META_EDGE_CONSTRAINT_MONITOR; + + break; + + case META_TILE_BOTTOM: + if (window->vtile_match) + window->edge_constraints.top = META_EDGE_CONSTRAINT_WINDOW; + else + window->edge_constraints.top = META_EDGE_CONSTRAINT_NONE; + + window->edge_constraints.right = META_EDGE_CONSTRAINT_MONITOR; + window->edge_constraints.bottom = META_EDGE_CONSTRAINT_MONITOR; + window->edge_constraints.left = META_EDGE_CONSTRAINT_MONITOR; + break; + + case META_TILE_ULC: + window->edge_constraints.top = META_EDGE_CONSTRAINT_MONITOR; + + if (window->htile_match) + window->edge_constraints.right = META_EDGE_CONSTRAINT_WINDOW; + else + window->edge_constraints.right = META_EDGE_CONSTRAINT_NONE; + + if (window->vtile_match) + window->edge_constraints.bottom = META_EDGE_CONSTRAINT_WINDOW; + else + window->edge_constraints.bottom = META_EDGE_CONSTRAINT_NONE; + + window->edge_constraints.left = META_EDGE_CONSTRAINT_MONITOR; + break; + + case META_TILE_LLC: + if (window->vtile_match) + window->edge_constraints.top = META_EDGE_CONSTRAINT_WINDOW; + else + window->edge_constraints.top = META_EDGE_CONSTRAINT_NONE; + + if (window->htile_match) + window->edge_constraints.right = META_EDGE_CONSTRAINT_WINDOW; + else + window->edge_constraints.right = META_EDGE_CONSTRAINT_NONE; + + window->edge_constraints.bottom = META_EDGE_CONSTRAINT_MONITOR; + window->edge_constraints.left = META_EDGE_CONSTRAINT_MONITOR; + break; + + case META_TILE_URC: + window->edge_constraints.top = META_EDGE_CONSTRAINT_MONITOR; + window->edge_constraints.right = META_EDGE_CONSTRAINT_MONITOR; + + if (window->vtile_match) + window->edge_constraints.bottom = META_EDGE_CONSTRAINT_WINDOW; + else + window->edge_constraints.bottom = META_EDGE_CONSTRAINT_NONE; + + if (window->htile_match) + window->edge_constraints.left = META_EDGE_CONSTRAINT_WINDOW; + else + window->edge_constraints.left = META_EDGE_CONSTRAINT_NONE; + break; + + case META_TILE_LRC: + if (window->vtile_match) + window->edge_constraints.top = META_EDGE_CONSTRAINT_WINDOW; + else + window->edge_constraints.top = META_EDGE_CONSTRAINT_NONE; + + window->edge_constraints.right = META_EDGE_CONSTRAINT_MONITOR; + window->edge_constraints.bottom = META_EDGE_CONSTRAINT_MONITOR; + + if (window->htile_match) window->edge_constraints.left = META_EDGE_CONSTRAINT_WINDOW; else window->edge_constraints.left = META_EDGE_CONSTRAINT_NONE; break; } + if (window->tile_mode != META_TILE_NONE) + return; + /* h/vmaximize also modify the edge constraints */ if (window->maximized_vertically) { @@ -3200,8 +3367,9 @@ meta_window_tile (MetaWindow *window, { MetaMaximizeFlags directions; MetaRectangle old_frame_rect, old_buffer_rect; + gboolean was_already_tiled = window->tile_mode != META_TILE_NONE && window->tile_mode != META_TILE_NONE; - meta_window_get_tile_fraction (window, tile_mode, &window->tile_hfraction); + meta_window_get_tile_fractions (window, tile_mode, &window->tile_hfraction, &window->tile_vfraction); window->tile_mode = tile_mode; /* Don't do anything if no tiling is requested */ @@ -3216,7 +3384,7 @@ meta_window_tile (MetaWindow *window, else directions = META_MAXIMIZE_VERTICAL; - meta_window_maximize_internal (window, directions, NULL); + meta_window_maximize_internal (window, directions, was_already_tiled ? &window->saved_rect : NULL); meta_display_update_tile_preview (window->display, FALSE); /* Setup the edge constraints */ @@ -3252,7 +3420,7 @@ meta_window_restore_tile (MetaWindow *window, int width, int height) { - meta_window_update_tile_fraction (window, width, height); + meta_window_update_tile_fractions (window, width, height); meta_window_tile (window, mode); } @@ -3262,12 +3430,13 @@ meta_window_can_tile_maximized (MetaWindow *window) return window->has_maximize_func; } -gboolean -meta_window_can_tile_side_by_side (MetaWindow *window) +static gboolean +is_valid_tile_mode (MetaWindow *window, MetaTileMode mode) { int monitor; MetaRectangle tile_area; MetaRectangle client_rect; + double hfraction, vfraction; if (!meta_window_can_tile_maximized (window)) return FALSE; @@ -3279,7 +3448,10 @@ meta_window_can_tile_side_by_side (MetaWindow *window) if (tile_area.height > tile_area.width) return FALSE; - tile_area.width /= 2; + get_default_tile_fractions (mode, &hfraction, &vfraction); + + tile_area.width *= hfraction; + tile_area.height *= vfraction; meta_window_frame_rect_to_client_rect (window, &tile_area, &client_rect); @@ -3287,6 +3459,24 @@ meta_window_can_tile_side_by_side (MetaWindow *window) client_rect.height >= window->size_hints.min_height; } +gboolean +meta_window_can_tile_left_right (MetaWindow *window) +{ + return is_valid_tile_mode (window, META_TILE_LEFT); +} + +gboolean +meta_window_can_tile_top_bottom (MetaWindow *window) +{ + return is_valid_tile_mode (window, META_TILE_TOP); +} + +gboolean +meta_window_can_tile_corner (MetaWindow *window) +{ + return is_valid_tile_mode (window, META_TILE_ULC); +} + static void unmaximize_window_before_freeing (MetaWindow *window) { @@ -4354,10 +4544,11 @@ adjust_size_for_tile_match (MetaWindow *window, int *new_w, int *new_h) { - MetaRectangle work_area, rect; - MetaWindow *tile_match = window->tile_match; + MetaRectangle work_area, rect, match_rect; + MetaWindow *vtile_match = window->vtile_match; + MetaWindow *htile_match = window->htile_match; - if (!META_WINDOW_TILED_SIDE_BY_SIDE (window) || !tile_match) + if (!META_WINDOW_TILED (window) || (!vtile_match && !htile_match)) return; meta_window_get_work_area_for_monitor (window, window->tile_monitor_number, &work_area); @@ -4365,16 +4556,30 @@ adjust_size_for_tile_match (MetaWindow *window, /* Make sure the resize does not break minimum sizes */ rect = work_area; rect.width = *new_w; + rect.height = *new_h; meta_window_frame_rect_to_client_rect (window, &rect, &rect); *new_w += MAX(0, window->size_hints.min_width - rect.width); + *new_h += MAX(0, window->size_hints.min_height - rect.height); /* Make sure we're not resizing the tile match below its min width */ rect = work_area; rect.width = work_area.width - *new_w; + rect.height = work_area.height - *new_h; + + if (vtile_match) + { + meta_window_frame_rect_to_client_rect (vtile_match, &rect, &match_rect); + + *new_h -= MAX(0, vtile_match->size_hints.min_height - match_rect.height); + } + + if (htile_match) + { + meta_window_frame_rect_to_client_rect (htile_match, &rect, &match_rect); - meta_window_frame_rect_to_client_rect (tile_match, &rect, &rect); - *new_w -= MAX(0, tile_match->size_hints.min_width - rect.width); + *new_w -= MAX(0, htile_match->size_hints.min_width - match_rect.width); + } } void @@ -4397,7 +4602,7 @@ meta_window_resize_frame_with_gravity (MetaWindow *window, */ if (window->display->grab_window == window) adjust_size_for_tile_match (window, &w, &h); - meta_window_update_tile_fraction (window, w, h); + meta_window_update_tile_fractions (window, w, h); } flags = (user_op ? META_MOVE_RESIZE_USER_ACTION : 0) | META_MOVE_RESIZE_RESIZE_ACTION; @@ -6040,6 +6245,37 @@ update_move_timeout (gpointer data) return FALSE; } +enum { + ZONE_NONE = 0, + ZONE_TOP = 1 << 0, + ZONE_RIGHT = 1 << 1, + ZONE_BOTTOM = 1 << 2, + ZONE_LEFT = 1 << 3 +}; + +static gint +get_tile_zone_at_pointer (MetaLogicalMonitor *logical_monitor, + MetaRectangle *work_area, + int shake_threshold, + int x, + int y) +{ + gint zones = ZONE_NONE; + + if (x >= logical_monitor->rect.x && x < (work_area->x + shake_threshold)) + zones |= ZONE_LEFT; + if (x >= work_area->x + work_area->width - shake_threshold && + x < (logical_monitor->rect.x + logical_monitor->rect.width)) + zones |= ZONE_RIGHT; + if (y >= logical_monitor->rect.y && y < (work_area->y + shake_threshold)) + zones |= ZONE_TOP; + if (y >= work_area->y + work_area->height - shake_threshold && + y < (logical_monitor->rect.y + logical_monitor->rect.height)) + zones |= ZONE_BOTTOM; + + return zones; +} + static void update_move_maybe_tile (MetaWindow *window, int shake_threshold, @@ -6078,16 +6314,31 @@ update_move_maybe_tile (MetaWindow *window, /* Check if the cursor is in a position which triggers tiling * and set tile_mode accordingly. */ - if (meta_window_can_tile_side_by_side (window) && - x >= logical_monitor->rect.x && x < (work_area.x + shake_threshold)) + if (meta_window_can_tile_left_right (window) && + get_tile_zone_at_pointer (logical_monitor, &work_area, shake_threshold, x, y) == ZONE_LEFT) display->preview_tile_mode = META_TILE_LEFT; - else if (meta_window_can_tile_side_by_side (window) && - x >= work_area.x + work_area.width - shake_threshold && - x < (logical_monitor->rect.x + logical_monitor->rect.width)) + else if (meta_window_can_tile_left_right (window) && + get_tile_zone_at_pointer (logical_monitor, &work_area, shake_threshold, x, y) == ZONE_RIGHT) display->preview_tile_mode = META_TILE_RIGHT; - else if (meta_window_can_tile_maximized (window) && - y >= logical_monitor->rect.y && y <= work_area.y) - display->preview_tile_mode = META_TILE_MAXIMIZED; + else if (meta_window_can_tile_top_bottom (window) && + // TODO: Handle maximize/tile preference + get_tile_zone_at_pointer (logical_monitor, &work_area, shake_threshold, x, y) == ZONE_TOP) + display->preview_tile_mode = meta_prefs_get_tile_maximize() ? META_TILE_MAXIMIZED : META_TILE_TOP; + else if (meta_window_can_tile_top_bottom (window) && + get_tile_zone_at_pointer (logical_monitor, &work_area, shake_threshold, x, y) == ZONE_BOTTOM) + display->preview_tile_mode = META_TILE_BOTTOM; + else if (meta_window_can_tile_corner (window) && + get_tile_zone_at_pointer (logical_monitor, &work_area, shake_threshold, x, y) == (ZONE_LEFT | ZONE_TOP)) + display->preview_tile_mode = META_TILE_ULC; + else if (meta_window_can_tile_corner (window) && + get_tile_zone_at_pointer (logical_monitor, &work_area, shake_threshold, x, y) == (ZONE_RIGHT | ZONE_TOP)) + display->preview_tile_mode = META_TILE_URC; + else if (meta_window_can_tile_corner (window) && + get_tile_zone_at_pointer (logical_monitor, &work_area, shake_threshold, x, y) == (ZONE_RIGHT | ZONE_BOTTOM)) + display->preview_tile_mode = META_TILE_LRC; + else if (meta_window_can_tile_corner (window) && + get_tile_zone_at_pointer (logical_monitor, &work_area, shake_threshold, x, y) == (ZONE_LEFT | ZONE_BOTTOM)) + display->preview_tile_mode = META_TILE_LLC; else display->preview_tile_mode = META_TILE_NONE; @@ -6148,7 +6399,7 @@ update_move (MetaWindow *window, } else if (meta_prefs_get_edge_tiling () && !META_WINDOW_MAXIMIZED (window) && - !META_WINDOW_TILED_SIDE_BY_SIDE (window)) + !META_WINDOW_TILED (window)) { update_move_maybe_tile (window, shake_threshold, x, y); } @@ -6159,7 +6410,7 @@ update_move (MetaWindow *window, */ if ((META_WINDOW_MAXIMIZED (window) && ABS (dy) >= shake_threshold) || - (META_WINDOW_TILED_SIDE_BY_SIDE (window) && (MAX (ABS (dx), ABS (dy)) >= shake_threshold))) + (META_WINDOW_TILED (window) && (MAX (ABS (dx), ABS (dy)) >= shake_threshold))) { double prop; @@ -6198,7 +6449,7 @@ update_move (MetaWindow *window, * loose or it is still maximized (then move straight) */ else if ((window->shaken_loose || META_WINDOW_MAXIMIZED (window)) && - window->tile_mode != META_TILE_LEFT && window->tile_mode != META_TILE_RIGHT) + (window->tile_mode == META_TILE_NONE || window->tile_mode == META_TILE_MAXIMIZED)) { MetaBackend *backend = meta_get_backend (); MetaMonitorManager *monitor_manager = @@ -6265,9 +6516,9 @@ update_move (MetaWindow *window, meta_window_get_frame_rect (window, &old); /* Don't allow movement in the maximized directions or while tiled */ - if (window->maximized_horizontally || META_WINDOW_TILED_SIDE_BY_SIDE (window)) + if (window->maximized_horizontally || META_WINDOW_TILED (window)) new_x = old.x; - if (window->maximized_vertically) + if (window->maximized_vertically || META_WINDOW_TILED (window)) new_y = old.y; /* Do any edge resistance/snapping */ @@ -6433,7 +6684,7 @@ maybe_maximize_tiled_window (MetaWindow *window) MetaRectangle work_area; gint shake_threshold; - if (!META_WINDOW_TILED_SIDE_BY_SIDE (window)) + if (!META_WINDOW_TILED (window)) return; shake_threshold = meta_prefs_get_drag_threshold (); @@ -6485,10 +6736,10 @@ end_grab_op (MetaWindow *window, else if (meta_grab_op_is_resizing (window->display->grab_op)) { update_resize (window, - modifiers & CLUTTER_SHIFT_MASK || window->tile_match != NULL, + modifiers & CLUTTER_SHIFT_MASK || (window->htile_match != NULL || window->vtile_match != NULL), x, y, TRUE); - maybe_maximize_tiled_window (window); + // maybe_maximize_tiled_window (window); } } window->display->preview_tile_mode = META_TILE_NONE; @@ -6562,7 +6813,7 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window, else if (meta_grab_op_is_resizing (window->display->grab_op)) { update_resize (window, - modifier_state & CLUTTER_SHIFT_MASK || window->tile_match != NULL, + modifier_state & CLUTTER_SHIFT_MASK || (window->htile_match != NULL || window->vtile_match != NULL), x, y, FALSE); } @@ -6706,20 +6957,36 @@ meta_window_get_tile_area (MetaWindow *window, { MetaRectangle work_area; int tile_monitor_number; - double fraction; + double vfraction, hfraction; g_return_if_fail (tile_mode != META_TILE_NONE); tile_monitor_number = meta_window_get_current_tile_monitor_number (window); meta_window_get_work_area_for_monitor (window, tile_monitor_number, &work_area); - meta_window_get_tile_fraction (window, tile_mode, &fraction); - + meta_window_get_tile_fractions (window, tile_mode, &hfraction, &vfraction); *tile_area = work_area; - tile_area->width = round (tile_area->width * fraction); - if (tile_mode == META_TILE_RIGHT) - tile_area->x += work_area.width - tile_area->width; + tile_area->width = round (tile_area->width * hfraction); + tile_area->height = round (tile_area->height * vfraction); + + switch (tile_mode) + { + case META_TILE_RIGHT: + case META_TILE_URC: + tile_area->x += work_area.width - tile_area->width; + break; + case META_TILE_BOTTOM: + case META_TILE_LLC: + tile_area->y += work_area.height - tile_area->height; + break; + case META_TILE_LRC: + tile_area->x += work_area.width - tile_area->width; + tile_area->y += work_area.height - tile_area->height; + break; + default: + break; + } } gboolean @@ -7854,38 +8121,148 @@ meta_window_is_attached_dialog (MetaWindow *window) * - there is no 3rd window stacked between both tiled windows that's * partially visible in the common edge. * - * Return value: (transfer none) (nullable): the matching tiled window or - * %NULL if it doesn't exist. + * Return value: (transfer none) (nullable) (element-type MetaWindow): An array of matching tiled windows or + * %NULL if none exist. */ + MetaWindow * -meta_window_get_tile_match (MetaWindow *window) +meta_window_get_tile_match (MetaWindow *window, gboolean vertical) { - return window->tile_match; + return vertical ? window->vtile_match : + window->htile_match; } void -meta_window_compute_tile_match (MetaWindow *window) +meta_window_compute_tile_matches (MetaWindow *window) +{ + window->vtile_match = meta_window_find_tile_match (window, window->tile_mode, TRUE); + window->htile_match = meta_window_find_tile_match (window, window->tile_mode, FALSE); +} + +static gint LEFT_VMATCHES[] = { META_TILE_NONE, -1 }; +static gint LEFT_HMATCHES[] = { META_TILE_RIGHT, META_TILE_URC, META_TILE_LRC, -1 }; +static gint RIGHT_VMATCHES[] = { META_TILE_NONE, -1 }; +static gint RIGHT_HMATCHES[] = { META_TILE_LEFT, META_TILE_ULC, META_TILE_LLC, -1 }; +static gint TOP_VMATCHES[] = { META_TILE_BOTTOM, META_TILE_LLC, META_TILE_LRC, -1 }; +static gint TOP_HMATCHES[] = { META_TILE_NONE, -1 }; +static gint BOTTOM_VMATCHES[] = { META_TILE_TOP, META_TILE_ULC, META_TILE_URC, -1 }; +static gint BOTTOM_HMATCHES[] = { META_TILE_NONE, -1 }; +static gint ULC_VMATCHES[] = { META_TILE_LLC, META_TILE_LRC, META_TILE_BOTTOM, -1 }; +static gint ULC_HMATCHES[] = { META_TILE_URC, META_TILE_LRC, META_TILE_RIGHT, -1 }; +static gint URC_VMATCHES[] = { META_TILE_LLC, META_TILE_LRC, META_TILE_BOTTOM, -1 }; +static gint URC_HMATCHES[] = { META_TILE_LLC, META_TILE_ULC, META_TILE_LEFT, -1 }; +static gint LRC_VMATCHES[] = { META_TILE_ULC, META_TILE_URC, META_TILE_TOP, -1 }; +static gint LRC_HMATCHES[] = { META_TILE_ULC, META_TILE_LLC, META_TILE_LEFT, -1 }; +static gint LLC_VMATCHES[] = { META_TILE_ULC, META_TILE_URC, META_TILE_TOP, -1 }; +static gint LLC_HMATCHES[] = { META_TILE_URC, META_TILE_LRC, META_TILE_RIGHT, -1 }; + +static gboolean +can_match_mode (MetaWindow *match, + gint *modes) +{ + gint i = 0; + + while (modes[i] != -1) + { + if (modes[i++] == match->tile_mode) + return TRUE; + } + + return FALSE; +} + +static gboolean +vert_overlap (const MetaRectangle *rect1, + const MetaRectangle *rect2) +{ + return (rect1->y < rect2->y + rect2->height - meta_prefs_get_drag_threshold () && + rect2->y < rect1->y + rect1->height - meta_prefs_get_drag_threshold ()); +} + +static gboolean +horiz_overlap (const MetaRectangle *rect1, + const MetaRectangle *rect2) { - window->tile_match = meta_window_find_tile_match (window, window->tile_mode); + return (rect1->x < rect2->x + rect2->width - meta_prefs_get_drag_threshold () && + rect2->x < rect1->x + rect1->width - meta_prefs_get_drag_threshold ()); } static MetaWindow * meta_window_find_tile_match (MetaWindow *window, - MetaTileMode current_mode) + MetaTileMode current_mode, + gboolean vertical) { MetaWindow *match; MetaStack *stack; - MetaTileMode match_tile_mode = META_TILE_NONE; + gint *match_tile_modes; if (window->shaded || window->minimized) return NULL; - if (current_mode == META_TILE_LEFT) - match_tile_mode = META_TILE_RIGHT; - else if (current_mode == META_TILE_RIGHT) - match_tile_mode = META_TILE_LEFT; + if (vertical) + { + switch (current_mode) + { + case META_TILE_LEFT: + match_tile_modes = LEFT_VMATCHES; + break; + case META_TILE_RIGHT: + match_tile_modes = RIGHT_VMATCHES; + break; + case META_TILE_TOP: + match_tile_modes = TOP_VMATCHES; + break; + case META_TILE_BOTTOM: + match_tile_modes = BOTTOM_VMATCHES; + break; + case META_TILE_ULC: + match_tile_modes = ULC_VMATCHES; + break; + case META_TILE_LLC: + match_tile_modes = LLC_VMATCHES; + break; + case META_TILE_URC: + match_tile_modes = URC_VMATCHES; + break; + case META_TILE_LRC: + match_tile_modes = LRC_VMATCHES; + break; + default: + return NULL; + } + } else - return NULL; + { + switch (current_mode) + { + case META_TILE_LEFT: + match_tile_modes = LEFT_HMATCHES; + break; + case META_TILE_RIGHT: + match_tile_modes = RIGHT_HMATCHES; + break; + case META_TILE_TOP: + match_tile_modes = TOP_HMATCHES; + break; + case META_TILE_BOTTOM: + match_tile_modes = BOTTOM_HMATCHES; + break; + case META_TILE_ULC: + match_tile_modes = ULC_HMATCHES; + break; + case META_TILE_LLC: + match_tile_modes = LLC_HMATCHES; + break; + case META_TILE_URC: + match_tile_modes = URC_HMATCHES; + break; + case META_TILE_LRC: + match_tile_modes = LRC_HMATCHES; + break; + default: + return NULL; + } + } stack = window->display->stack; @@ -7895,7 +8272,9 @@ meta_window_find_tile_match (MetaWindow *window, { if (!match->shaded && !match->minimized && - match->tile_mode == match_tile_mode && + META_WINDOW_TILED (match) && + can_match_mode (match, match_tile_modes) && + (window != match) && match->tile_monitor_number == window->tile_monitor_number && meta_window_get_workspace (match) == meta_window_get_workspace (window)) break; @@ -7920,20 +8299,44 @@ meta_window_find_tile_match (MetaWindow *window, meta_window_get_frame_rect (bottommost, &bottommost_rect); meta_window_get_frame_rect (topmost, &topmost_rect); + /* + * Don't extend window edges to infinity when looking for matches. Tiling + * in a given direction requires some amount of overlap in the other. + */ + + if (!vert_overlap (&bottommost_rect, &topmost_rect) && !horiz_overlap (&bottommost_rect, &topmost_rect)) + return NULL; + /* * If we are looking for a tile match while actually being tiled, * rather than a match for a potential tile mode, then discard * windows with too much gap or overlap */ + gboolean have_match = vertical ? window->vtile_match != NULL : + window->htile_match != NULL; + if (window->tile_mode == current_mode && !(meta_grab_op_is_resizing (window->display->grab_op) && window->display->grab_window == window && - window->tile_match != NULL)) + have_match)) { int threshold = meta_prefs_get_drag_threshold (); - if (ABS (topmost_rect.x - bottommost_rect.x - bottommost_rect.width) > threshold && - ABS (bottommost_rect.x - topmost_rect.x - topmost_rect.width) > threshold) - return NULL; + + if (!vertical) + { + if (ABS (topmost_rect.x - bottommost_rect.x - bottommost_rect.width) > threshold && + ABS (bottommost_rect.x - topmost_rect.x - topmost_rect.width) > threshold) + { + return NULL; + + } + } + else + { + if (ABS (topmost_rect.y - bottommost_rect.y - bottommost_rect.height) > threshold && + ABS (bottommost_rect.y - topmost_rect.y - topmost_rect.height) > threshold) + return NULL; + } } /* diff --git a/src/meta/common.h b/src/meta/common.h index 5cbea521b..783169aa5 100644 --- a/src/meta/common.h +++ b/src/meta/common.h @@ -84,9 +84,26 @@ typedef enum META_FRAME_FULLSCREEN = 1 << 12, META_FRAME_ABOVE = 1 << 13, META_FRAME_TILED_LEFT = 1 << 14, - META_FRAME_TILED_RIGHT = 1 << 15 + META_FRAME_TILED_RIGHT = 1 << 15, + META_FRAME_TILED_TOP = 1 << 16, + META_FRAME_TILED_BOTTOM = 1 << 17, + META_FRAME_TILED_ULC = 1 << 18, + META_FRAME_TILED_URC = 1 << 19, + META_FRAME_TILED_LRC = 1 << 20, + META_FRAME_TILED_LLC = 1 << 21, } MetaFrameFlags; + +#define META_FRAME_TILED_TOP_EDGES (META_FRAME_TILED_TOP | META_FRAME_TILED_ULC | META_FRAME_TILED_URC) +#define META_FRAME_TILED_BOTTOM_EDGES (META_FRAME_TILED_BOTTOM | META_FRAME_TILED_LLC | META_FRAME_TILED_LRC) +#define META_FRAME_TILED_RIGHT_EDGES (META_FRAME_TILED_LEFT | META_FRAME_TILED_ULC | META_FRAME_TILED_LLC) +#define META_FRAME_TILED_LEFT_EDGES (META_FRAME_TILED_RIGHT | META_FRAME_TILED_URC | META_FRAME_TILED_LRC) + +#define META_FRAME_TILED_ANY (META_FRAME_TILED_LEFT | META_FRAME_TILED_RIGHT | \ + META_FRAME_TILED_TOP | META_FRAME_TILED_BOTTOM | \ + META_FRAME_TILED_ULC | META_FRAME_TILED_URC | \ + META_FRAME_TILED_LLC | META_FRAME_TILED_LRC) + /** * MetaGrabOp: * @META_GRAB_OP_NONE: None diff --git a/src/meta/prefs.h b/src/meta/prefs.h index 1ab7d5095..7bbe1d572 100644 --- a/src/meta/prefs.h +++ b/src/meta/prefs.h @@ -114,7 +114,8 @@ typedef enum META_PREF_UNREDIRECT_FULLSCREEN_WINDOWS, META_PREF_WORKSPACE_CYCLE, META_PREF_MIN_WIN_OPACITY, - META_PREF_MOUSE_ZOOM_ENABLED + META_PREF_MOUSE_ZOOM_ENABLED, + META_PREF_TILE_MAXIMIZE } MetaPreference; typedef void (* MetaPrefsChangedFunc) (MetaPreference pref, @@ -192,6 +193,9 @@ gboolean meta_prefs_get_gnome_animations (void); META_EXPORT gboolean meta_prefs_get_edge_tiling (void); +META_EXPORT +gboolean meta_prefs_get_tile_maximize (void); + META_EXPORT gboolean meta_prefs_get_auto_maximize (void); @@ -305,8 +309,10 @@ gint meta_prefs_get_min_win_opacity (void); * @META_KEYBINDING_ACTION_ACTIVATE_WINDOW_MENU: FILLME * @META_KEYBINDING_ACTION_TOGGLE_FULLSCREEN: FILLME * @META_KEYBINDING_ACTION_TOGGLE_MAXIMIZED: FILLME - * @META_KEYBINDING_ACTION_TOGGLE_TILED_LEFT: FILLME - * @META_KEYBINDING_ACTION_TOGGLE_TILED_RIGHT: FILLME + * @META_KEYBINDING_ACTION_PUSH_TILE_LEFT: FILLME + * @META_KEYBINDING_ACTION_PUSH_TILE_RIGHT: FILLME + * @META_KEYBINDING_ACTION_PUSH_TILE_UP: FILLME + * @META_KEYBINDING_ACTION_PUSH_TILE_DOWN: FILLME * @META_KEYBINDING_ACTION_TOGGLE_ABOVE: FILLME * @META_KEYBINDING_ACTION_MAXIMIZE: FILLME * @META_KEYBINDING_ACTION_UNMAXIMIZE: FILLME @@ -403,8 +409,10 @@ typedef enum _MetaKeyBindingAction META_KEYBINDING_ACTION_ACTIVATE_WINDOW_MENU, META_KEYBINDING_ACTION_TOGGLE_FULLSCREEN, META_KEYBINDING_ACTION_TOGGLE_MAXIMIZED, - META_KEYBINDING_ACTION_TOGGLE_TILED_LEFT, - META_KEYBINDING_ACTION_TOGGLE_TILED_RIGHT, + META_KEYBINDING_ACTION_PUSH_TILE_LEFT, + META_KEYBINDING_ACTION_PUSH_TILE_RIGHT, + META_KEYBINDING_ACTION_PUSH_TILE_UP, + META_KEYBINDING_ACTION_PUSH_TILE_DOWN, META_KEYBINDING_ACTION_TOGGLE_ABOVE, META_KEYBINDING_ACTION_MAXIMIZE, META_KEYBINDING_ACTION_UNMAXIMIZE, diff --git a/src/meta/window.h b/src/meta/window.h index 42e4d60da..6a4165f62 100644 --- a/src/meta/window.h +++ b/src/meta/window.h @@ -358,7 +358,7 @@ META_EXPORT cairo_region_t *meta_window_get_frame_bounds (MetaWindow *window); META_EXPORT -MetaWindow *meta_window_get_tile_match (MetaWindow *window); +MetaWindow *meta_window_get_tile_match (MetaWindow *window, gboolean vertical); META_EXPORT void meta_window_make_fullscreen (MetaWindow *window); diff --git a/src/ui/frames.c b/src/ui/frames.c index 1ee53e74a..8f9c24ca8 100644 --- a/src/ui/frames.c +++ b/src/ui/frames.c @@ -1864,12 +1864,12 @@ get_control (MetaUIFrame *frame, int root_x, int root_y) has_vert = (flags & META_FRAME_ALLOWS_VERTICAL_RESIZE) != 0; has_horiz = (flags & META_FRAME_ALLOWS_HORIZONTAL_RESIZE) != 0; - if (flags & META_FRAME_TILED_LEFT || flags & META_FRAME_TILED_RIGHT) + if (flags & META_FRAME_TILED_ANY) has_vert = has_horiz = FALSE; if (META_POINT_IN_RECT (x, y, fgeom.title_rect)) { - if (has_vert && y <= TOP_RESIZE_HEIGHT && has_north_resize) + if (has_vert && y <= TOP_RESIZE_HEIGHT && !(flags & META_FRAME_TILED_TOP_EDGES) && has_north_resize) return META_FRAME_CONTROL_RESIZE_N; else return META_FRAME_CONTROL_TITLE; @@ -1929,22 +1929,22 @@ get_control (MetaUIFrame *frame, int root_x, int root_y) } else if (y < (fgeom.borders.invisible.top + TOP_RESIZE_HEIGHT)) { - if (has_vert && has_north_resize) + if ((has_vert || flags & (META_FRAME_TILED_BOTTOM | META_FRAME_TILED_LLC | META_FRAME_TILED_LRC)) && has_north_resize) return META_FRAME_CONTROL_RESIZE_N; } else if (y >= (fgeom.height - fgeom.borders.total.bottom)) { - if (has_vert) + if (has_vert || flags & (META_FRAME_TILED_TOP | META_FRAME_TILED_ULC | META_FRAME_TILED_URC)) return META_FRAME_CONTROL_RESIZE_S; } else if (x <= fgeom.borders.total.left) { - if (has_horiz || flags & META_FRAME_TILED_RIGHT) + if (has_horiz || flags & (META_FRAME_TILED_RIGHT | META_FRAME_TILED_URC | META_FRAME_TILED_LRC)) return META_FRAME_CONTROL_RESIZE_W; } else if (x >= (fgeom.width - fgeom.borders.total.right)) { - if (has_horiz || flags & META_FRAME_TILED_LEFT) + if (has_horiz || flags & (META_FRAME_TILED_LEFT | META_FRAME_TILED_ULC | META_FRAME_TILED_LLC)) return META_FRAME_CONTROL_RESIZE_E; } diff --git a/src/ui/theme.c b/src/ui/theme.c index 3f8d728e8..1e187d491 100644 --- a/src/ui/theme.c +++ b/src/ui/theme.c @@ -553,8 +553,7 @@ meta_frame_layout_calc_geometry (MetaFrameLayout *layout, rect->visible.height = button_height; if (flags & META_FRAME_MAXIMIZED || - flags & META_FRAME_TILED_LEFT || - flags & META_FRAME_TILED_RIGHT) + flags & META_FRAME_TILED_ANY) { rect->clickable.x = rect->visible.x; rect->clickable.y = 0; @@ -1195,8 +1194,7 @@ meta_style_info_set_flags (MetaStyleInfo *style_info, if (flags & META_FRAME_MAXIMIZED) class_name = "maximized"; - else if (flags & META_FRAME_TILED_LEFT || - flags & META_FRAME_TILED_RIGHT) + else if (flags & META_FRAME_TILED_ANY) class_name = "tiled"; for (i = 0; i < META_STYLE_ELEMENT_LAST; i++) From e7524b38664181f318b7dd98d49641ec37b78db8 Mon Sep 17 00:00:00 2001 From: Michael Webster <miketwebster@gmail.com> Date: Sat, 14 May 2022 20:41:13 -0400 Subject: [PATCH 19/36] Disable ssd shadows when tiled, even without matching windows. --- src/compositor/meta-window-actor-x11.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/compositor/meta-window-actor-x11.c b/src/compositor/meta-window-actor-x11.c index 541537a44..ff511cf09 100644 --- a/src/compositor/meta-window-actor-x11.c +++ b/src/compositor/meta-window-actor-x11.c @@ -507,18 +507,12 @@ has_shadow (MetaWindowActorX11 *actor_x11) if (actor_x11->shadow_mode == META_SHADOW_MODE_FORCED_ON) return TRUE; - /* Leaving out shadows for maximized and fullscreen windows is an effeciency + /* Leaving out shadows for tiled, maximized and fullscreen windows is an effeciency * win and also prevents the unsightly effect of the shadow of maximized * window appearing on an adjacent window */ if ((meta_window_get_maximized (window) == META_MAXIMIZE_BOTH) || - meta_window_is_fullscreen (window)) - return FALSE; - - /* - * If we have two snap-tiled windows, we don't want the shadow to obstruct - * the other window. - */ - if (meta_window_get_tile_match (window, TRUE) || meta_window_get_tile_match (window, FALSE)) + meta_window_is_fullscreen (window) || + META_WINDOW_TILED (window)) return FALSE; /* From 71b38d1c6706992f82c462fd5b5c642bc369e212 Mon Sep 17 00:00:00 2001 From: JosephMcc <mccullarjoseph@gmail.com> Date: Tue, 19 Apr 2022 18:15:00 -0700 Subject: [PATCH 20/36] window.c: Reduce the tile area along the top edge of the screen Currently this is 48px by default which is triggered too easily just moving windows normally around the screen. Change it so that it's only triggered when moving the mouse right against the top edge. --- src/core/window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/window.c b/src/core/window.c index 02d18640f..006ae0350 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -6267,7 +6267,7 @@ get_tile_zone_at_pointer (MetaLogicalMonitor *logical_monitor, if (x >= work_area->x + work_area->width - shake_threshold && x < (logical_monitor->rect.x + logical_monitor->rect.width)) zones |= ZONE_RIGHT; - if (y >= logical_monitor->rect.y && y < (work_area->y + shake_threshold)) + if (y >= logical_monitor->rect.y && y <= work_area->y) zones |= ZONE_TOP; if (y >= work_area->y + work_area->height - shake_threshold && y < (logical_monitor->rect.y + logical_monitor->rect.height)) From d6e22e061ce284ba95d94607884698e5787e1b5d Mon Sep 17 00:00:00 2001 From: Michael Webster <miketwebster@gmail.com> Date: Sat, 4 Jun 2022 15:08:34 -0400 Subject: [PATCH 21/36] Expose a window's tile mode. Fix tile zone calculation. Instead of it being based on the shake-loose threshold, it's traditionally been 1px wide on extreme edges and 5px on shared edges. This restores that behavior. --- src/core/display-private.h | 14 ----- src/core/window.c | 106 ++++++++++++++++++++++++++++++------- src/meta/display.h | 14 +++++ 3 files changed, 102 insertions(+), 32 deletions(-) diff --git a/src/core/display-private.h b/src/core/display-private.h index fc922c020..215df6c56 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -65,20 +65,6 @@ typedef struct MetaEdgeResistanceData MetaEdgeResistanceData; */ #define N_IGNORED_CROSSING_SERIALS 10 -typedef enum -{ - META_TILE_NONE, - META_TILE_LEFT, - META_TILE_RIGHT, - META_TILE_ULC, - META_TILE_LLC, - META_TILE_URC, - META_TILE_LRC, - META_TILE_TOP, - META_TILE_BOTTOM, - META_TILE_MAXIMIZED -} MetaTileMode; - typedef enum { /* Normal interaction where you're interacting with windows. diff --git a/src/core/window.c b/src/core/window.c index 006ae0350..4bd3a949a 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -215,6 +215,7 @@ enum PROP_ON_ALL_WORKSPACES, PROP_PROGRESS, PROP_PROGRESS_PULSE, + PROP_TILE_MODE, PROP_LAST, }; @@ -443,6 +444,9 @@ meta_window_get_property(GObject *object, case PROP_PROGRESS_PULSE: g_value_set_boolean (value, win->progress_pulse); break; + case PROP_TILE_MODE: + g_value_set_enum (value, win->tile_mode); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -647,6 +651,14 @@ meta_window_class_init (MetaWindowClass *klass) FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_props[PROP_TILE_MODE] = + g_param_spec_enum ("tile-mode", + "Window Tile Mode", + "The tile state of the window", + META_TYPE_TILE_MODE, + META_TILE_NONE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_object_class_install_properties (object_class, PROP_LAST, obj_props); window_signals[WORKSPACE_CHANGED] = @@ -6253,24 +6265,82 @@ enum { ZONE_LEFT = 1 << 3 }; +#define BOX_CENTER_X(box) ((box).x + (box).width / 2) /* Center in X */ +#define BOX_CENTER_Y(box) ((box).y + (box).height / 2) /* Center in Y */ + +#define ORIGIN_CONSTANT 1 +#define EXTREME_CONSTANT 2 +#define COMMON_EDGE_PADDING 5 + +static void +get_extra_padding_for_common_monitor_edges (MetaWindow *window, + gint monitor_num, + MetaRectangle cur_rect, + gint *left_shift, + gint *right_shift, + gint *up_shift, + gint *down_shift) +{ + gint num_mons; + gint i; + MetaRectangle other_rect; + num_mons = meta_display_get_n_monitors (window->display); + + if (num_mons == 1) + return; + + for (i = 0; i < num_mons; i++) { + if (i == monitor_num) + continue; + + meta_display_get_monitor_geometry (window->display, i, &other_rect); + + if (BOX_CENTER_X (other_rect) < BOX_LEFT (cur_rect)) { + *left_shift = COMMON_EDGE_PADDING; + continue; + } + if (BOX_CENTER_X (other_rect) > BOX_RIGHT (cur_rect)) { + *right_shift = COMMON_EDGE_PADDING; + continue; + } + if (BOX_CENTER_Y (other_rect) < BOX_TOP (cur_rect)) { + *up_shift = COMMON_EDGE_PADDING; + continue; + } + if (BOX_CENTER_Y (other_rect) > BOX_BOTTOM (cur_rect)) { + *down_shift = COMMON_EDGE_PADDING; + continue; + } + } +} + static gint -get_tile_zone_at_pointer (MetaLogicalMonitor *logical_monitor, - MetaRectangle *work_area, - int shake_threshold, +get_tile_zone_at_pointer (MetaWindow *window, + MetaLogicalMonitor *logical_monitor, + MetaRectangle work_area, int x, int y) { gint zones = ZONE_NONE; - - if (x >= logical_monitor->rect.x && x < (work_area->x + shake_threshold)) + gint left_shift, right_shift, up_shift, down_shift; + left_shift = right_shift = up_shift = down_shift = 0; + MetaRectangle lm_rect = logical_monitor->rect; + + get_extra_padding_for_common_monitor_edges (window, + logical_monitor->number, + work_area, + &left_shift, + &right_shift, + &up_shift, + &down_shift); + + if (x >= BOX_LEFT (lm_rect) && x <= (BOX_LEFT (work_area) + ORIGIN_CONSTANT + left_shift)) zones |= ZONE_LEFT; - if (x >= work_area->x + work_area->width - shake_threshold && - x < (logical_monitor->rect.x + logical_monitor->rect.width)) + if ((x >= BOX_RIGHT (work_area) - EXTREME_CONSTANT - right_shift) && x < BOX_RIGHT (lm_rect)) zones |= ZONE_RIGHT; - if (y >= logical_monitor->rect.y && y <= work_area->y) + if (y >= BOX_TOP (lm_rect) && y <= (BOX_TOP (work_area) + ORIGIN_CONSTANT + up_shift)) zones |= ZONE_TOP; - if (y >= work_area->y + work_area->height - shake_threshold && - y < (logical_monitor->rect.y + logical_monitor->rect.height)) + if ((y >= BOX_BOTTOM (work_area) - EXTREME_CONSTANT - down_shift) && y < BOX_RIGHT (lm_rect)) zones |= ZONE_BOTTOM; return zones; @@ -6315,29 +6385,29 @@ update_move_maybe_tile (MetaWindow *window, * and set tile_mode accordingly. */ if (meta_window_can_tile_left_right (window) && - get_tile_zone_at_pointer (logical_monitor, &work_area, shake_threshold, x, y) == ZONE_LEFT) + get_tile_zone_at_pointer (window, logical_monitor, work_area, x, y) == ZONE_LEFT) display->preview_tile_mode = META_TILE_LEFT; else if (meta_window_can_tile_left_right (window) && - get_tile_zone_at_pointer (logical_monitor, &work_area, shake_threshold, x, y) == ZONE_RIGHT) + get_tile_zone_at_pointer (window, logical_monitor, work_area, x, y) == ZONE_RIGHT) display->preview_tile_mode = META_TILE_RIGHT; else if (meta_window_can_tile_top_bottom (window) && // TODO: Handle maximize/tile preference - get_tile_zone_at_pointer (logical_monitor, &work_area, shake_threshold, x, y) == ZONE_TOP) + get_tile_zone_at_pointer (window, logical_monitor, work_area, x, y) == ZONE_TOP) display->preview_tile_mode = meta_prefs_get_tile_maximize() ? META_TILE_MAXIMIZED : META_TILE_TOP; else if (meta_window_can_tile_top_bottom (window) && - get_tile_zone_at_pointer (logical_monitor, &work_area, shake_threshold, x, y) == ZONE_BOTTOM) + get_tile_zone_at_pointer (window, logical_monitor, work_area, x, y) == ZONE_BOTTOM) display->preview_tile_mode = META_TILE_BOTTOM; else if (meta_window_can_tile_corner (window) && - get_tile_zone_at_pointer (logical_monitor, &work_area, shake_threshold, x, y) == (ZONE_LEFT | ZONE_TOP)) + get_tile_zone_at_pointer (window, logical_monitor, work_area, x, y) == (ZONE_LEFT | ZONE_TOP)) display->preview_tile_mode = META_TILE_ULC; else if (meta_window_can_tile_corner (window) && - get_tile_zone_at_pointer (logical_monitor, &work_area, shake_threshold, x, y) == (ZONE_RIGHT | ZONE_TOP)) + get_tile_zone_at_pointer (window, logical_monitor, work_area, x, y) == (ZONE_RIGHT | ZONE_TOP)) display->preview_tile_mode = META_TILE_URC; else if (meta_window_can_tile_corner (window) && - get_tile_zone_at_pointer (logical_monitor, &work_area, shake_threshold, x, y) == (ZONE_RIGHT | ZONE_BOTTOM)) + get_tile_zone_at_pointer (window, logical_monitor, work_area, x, y) == (ZONE_RIGHT | ZONE_BOTTOM)) display->preview_tile_mode = META_TILE_LRC; else if (meta_window_can_tile_corner (window) && - get_tile_zone_at_pointer (logical_monitor, &work_area, shake_threshold, x, y) == (ZONE_LEFT | ZONE_BOTTOM)) + get_tile_zone_at_pointer (window, logical_monitor, work_area, x, y) == (ZONE_LEFT | ZONE_BOTTOM)) display->preview_tile_mode = META_TILE_LLC; else display->preview_tile_mode = META_TILE_NONE; diff --git a/src/meta/display.h b/src/meta/display.h index 7fe2febaf..4d291f873 100644 --- a/src/meta/display.h +++ b/src/meta/display.h @@ -63,6 +63,20 @@ typedef enum META_PAD_ACTION_STRIP, /* Action is a strip */ } MetaPadActionType; +typedef enum +{ + META_TILE_NONE, + META_TILE_LEFT, + META_TILE_RIGHT, + META_TILE_ULC, + META_TILE_LLC, + META_TILE_URC, + META_TILE_LRC, + META_TILE_TOP, + META_TILE_BOTTOM, + META_TILE_MAXIMIZED +} MetaTileMode; + typedef struct _MetaDisplayClass MetaDisplayClass; #define META_TYPE_DISPLAY (meta_display_get_type ()) From 8f0c5ddfe16eaa1646d404cbb1afc92f1e8156cd Mon Sep 17 00:00:00 2001 From: Michael Webster <miketwebster@gmail.com> Date: Tue, 1 Feb 2022 21:12:07 -0500 Subject: [PATCH 22/36] Fix random crash when clicking the frame of a tiled window. --- src/ui/frames.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ui/frames.c b/src/ui/frames.c index 8f9c24ca8..8ddf86275 100644 --- a/src/ui/frames.c +++ b/src/ui/frames.c @@ -1182,6 +1182,9 @@ meta_frame_left_click_event (MetaUIFrame *frame, /* We can get this for example when trying to resize window * that cannot be resized (e. g. it is maximized and the theme * currently used has borders for maximized windows), see #751884 */ + case META_FRAME_CONTROL_CLIENT_AREA: + /* See https://gitlab.gnome.org/GNOME/mutter/-/issues/1668#note_1046828. + * This can happen when clicking on the frame of a tiles, unfocused window. */ return FALSE; default: g_assert_not_reached (); From d4d057282dbdbdedb3ab54f027fa040ef3c4f014 Mon Sep 17 00:00:00 2001 From: Michael Webster <miketwebster@gmail.com> Date: Thu, 31 Mar 2022 10:10:24 -0400 Subject: [PATCH 23/36] Cleanup deps, build flags - remove unused build options, set remaining ones to our preferred defaults. - clean up debian/rules some more --- data/meson.build | 3 ++- debian/control | 13 +----------- debian/rules | 38 ++-------------------------------- meson.build | 23 +++++++++++++++------ meson_options.txt | 52 ++--------------------------------------------- 5 files changed, 24 insertions(+), 105 deletions(-) diff --git a/data/meson.build b/data/meson.build index d08933351..34960c1b2 100644 --- a/data/meson.build +++ b/data/meson.build @@ -14,7 +14,8 @@ custom_target('muffin.desktop', install_dir: join_paths(datadir, 'applications'), ) -xwayland_grab_default_access_rules = get_option('xwayland_grab_default_access_rules') +#xwayland_grab_default_access_rules = get_option('xwayland_grab_default_access_rules') +xwayland_grab_default_access_rules = '' gschema_config = configuration_data() gschema_config.set('GETTEXT_DOMAIN', meson.project_name()) diff --git a/debian/control b/debian/control index b2f8f3352..bac6d7493 100644 --- a/debian/control +++ b/debian/control @@ -21,7 +21,6 @@ Build-Depends: libegl-dev, libegl1-mesa-dev (>= 17) [linux-any], libfribidi-dev (>= 1.0.0), - libgbm-dev (>= 10.3) [linux-any], libgirepository1.0-dev (>= 0.9.12), libgl1-mesa-dev (>= 7.1~rc3-1~), libgles2-mesa-dev (>= 7.1~rc3-1~) | libgles2-dev, @@ -33,15 +32,12 @@ Build-Depends: libice-dev, libinput-dev (>= 1.7) [linux-any], libjson-glib-dev (>= 0.13.2-1~), - libnvidia-egl-wayland-dev [linux-any], libpam0g-dev, libpango1.0-dev (>= 1.2.0), - libpipewire-0.3-dev (>= 0.3.19) [linux-any], + libpipewire-0.2-dev | libpipewire-0.3-dev, libsm-dev, libstartup-notification0-dev (>= 0.7), libsystemd-dev (>= 212) [linux-any], - libwacom-dev (>= 0.13) [linux-any], - libwayland-dev (>= 1.13.0) [linux-any], libxau-dev, libx11-dev, libx11-xcb-dev, @@ -62,12 +58,10 @@ Build-Depends: libxt-dev, meson (>= 0.50), pkg-config (>= 0.22), - wayland-protocols (>= 1.19) [linux-any], xauth <!nocheck>, xkb-data, xserver-xorg-core [linux-any], xvfb <!nocheck>, - xwayland [linux-any], zenity Rules-Requires-Root: no Standards-Version: 4.5.0 @@ -95,7 +89,6 @@ Architecture: any Multi-Arch: same Pre-Depends: ${misc:Pre-Depends} Depends: adwaita-icon-theme, - gsettings-desktop-schemas (>= 3.33.0), muffin-common (>= ${source:Version}), ${misc:Depends}, ${shlibs:Depends} @@ -111,7 +104,6 @@ Package: muffin Architecture: any Pre-Depends: ${misc:Pre-Depends} Depends: adwaita-icon-theme, - gsettings-desktop-schemas (>= 3.33.0), muffin-common (>= ${source:Version}), zenity, ${misc:Depends}, @@ -156,12 +148,10 @@ Multi-Arch: same Breaks: libmuffin0 (<< 5.1) Replaces: libmuffin0 (<< 5.1) Depends: gir1.2-meta-muffin-0.0 (= ${binary:Version}), - gsettings-desktop-schemas-dev (>= 3.33.0), libatk1.0-dev, libcairo2-dev, libdrm-dev, libegl1-mesa-dev, - libgbm-dev, libgdk-pixbuf2.0-dev, libgles2-mesa-dev (>= 7.1~rc3-1~) | libgles2-dev, libglib2.0-dev, @@ -172,7 +162,6 @@ Depends: gir1.2-meta-muffin-0.0 (= ${binary:Version}), libmuffin0 (= ${binary:Version}), libpango1.0-dev, libudev-dev, - libwayland-dev, libx11-dev, libxcomposite-dev, libxdamage-dev, diff --git a/debian/rules b/debian/rules index aa09acf54..7f1f73b71 100755 --- a/debian/rules +++ b/debian/rules @@ -9,47 +9,13 @@ export DEB_LDFLAGS_MAINT_APPEND = -Wl,-O1 -Wl,--as-needed override_dh_autoreconf: dh_autoreconf --as-needed -ifeq ($(DEB_HOST_ARCH_OS),linux) CONFFLAGS = \ - -Degl_device=true \ - -Dwayland=true \ - -Dwayland_eglstream=true \ - -Dnative_backend=true -else -CONFFLAGS += \ - -Dudev=false \ - -Dlibwacom=false \ - -Dwayland=false \ - -Dcore_tests=false \ - -Dnative_backend=false \ + -Dprofiler=false \ + -Ddefault_driver=gl \ -Dremote_desktop=false -endif - -ifeq ($(DEB_HOST_ARCH),$(findstring $(DEB_HOST_ARCH),armel armhf)) -CONFFLAGS += \ - -Ddefault_driver=gles2 -else -CONFFLAGS += \ - -Ddefault_driver=gl -endif - -# pipewire is not in Ubuntu main yet -ifeq ($(DEB_HOST_ARCH_OS),linux) -ifeq ($(shell dpkg-vendor --query vendor),Ubuntu) - CONFFLAGS += -Dremote_desktop=false -else - CONFFLAGS += -Dremote_desktop=true -endif -endif override_dh_auto_configure: dh_auto_configure -- \ - -Dstartup_notification=true \ - -Degl=true \ - -Dgles2=true \ - -Dgles2_libname=libGLESv2.so.2 \ - -Dinstalled_tests=false \ - -Dprofiler=false \ $(CONFFLAGS) # Use meson test directly as it allows us to use the timeout multiplier diff --git a/meson.build b/meson.build index 2fdec9736..7aeb98877 100644 --- a/meson.build +++ b/meson.build @@ -161,7 +161,9 @@ if have_gles2 endif endif -have_wayland = get_option('wayland') +#have_wayland = get_option('wayland') +have_wayland = false + if have_wayland wayland_server_dep = dependency('wayland-server', version: wayland_server_req) wayland_client_dep = dependency('wayland-client', version: wayland_server_req) @@ -180,7 +182,9 @@ if have_libgudev gudev_dep = dependency('gudev-1.0', version: gudev_req) endif -have_native_backend = get_option('native_backend') +# have_native_backend = get_option('native_backend') +have_native_backend = false + if have_native_backend libdrm_dep = dependency('libdrm') libgbm_dep = dependency('gbm', version: gbm_req) @@ -206,9 +210,12 @@ if have_native_backend endif endif -have_egl_device = get_option('egl_device') +#have_egl_device = get_option('egl_device') +have_egl_device = false + +#have_wayland_eglstream = get_option('wayland_eglstream') +have_wayland_eglstream = false -have_wayland_eglstream = get_option('wayland_eglstream') if have_wayland_eglstream wayland_eglstream_protocols_dep = dependency('wayland-eglstream-protocols') dl_dep = cc.find_library('dl', required: true) @@ -225,7 +232,9 @@ if have_sm sm_dep = dependency('sm') endif -have_libwacom = get_option('libwacom') +#have_libwacom = get_option('libwacom') +have_libwacom = false + if have_libwacom libwacom_dep = dependency('libwacom', version: libwacom_req) endif @@ -406,7 +415,9 @@ if have_wayland endif endif -xwayland_grab_default_access_rules = get_option('xwayland_grab_default_access_rules') +#xwayland_grab_default_access_rules = get_option('xwayland_grab_default_access_rules') +xwayland_grab_default_access_rules = '' + cdata.set_quoted('XWAYLAND_GRAB_DEFAULT_ACCESS_RULES', xwayland_grab_default_access_rules) diff --git a/meson_options.txt b/meson_options.txt index ba0313cd1..ba97afae4 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -33,48 +33,18 @@ option('glx', description: 'Enable GLX support' ) -option('wayland', - type: 'boolean', - value: true, - description: 'Enable Wayland support' -) - -option('native_backend', - type: 'boolean', - value: true, - description: 'Enable the native backend' -) - option('remote_desktop', type: 'boolean', value: true, description: 'Enable remote desktop and screen cast support' ) -option('egl_device', - type: 'boolean', - value: false, - description: 'Enable EGLDevice and EGLStream renderer support' -) - -option('wayland_eglstream', - type: 'boolean', - value: false, - description: 'Enable Wayland EGLStream support client support' -) - option('udev', type: 'boolean', value: true, description: 'Enable udev support when using the X11 backend' ) -option('libwacom', - type: 'boolean', - value: true, - description: 'Enable libwacom support' -) - option('pango_ft2', type: 'boolean', value: true, @@ -125,7 +95,7 @@ option('tests', option('profiler', type: 'boolean', - value: true, + value: false, description: 'Enable Sysprof tracing' ) @@ -141,26 +111,8 @@ option('verbose', description: 'Enable verbose logging ability' ) -option('xwayland_path', - type: 'string', - value: '', - description: 'Path to Xwayland executable' -) - -option('xwayland_grab_default_access_rules', - type: 'string', - value: 'gnome-boxes,remote-viewer,virt-viewer,virt-manager,vinagre,vncviewer,Xephyr', - description: 'Comma delimited list of applications ressources or class allowed to issue X11 grabs in Xwayland' -) - -option('xwayland_initfd', - type: 'feature', - value: 'auto', - description: 'Whether -initfd argument is passed to Xwayland to guarantee services (e.g. gsd-xsettings) startup before applications' -) - option('default_driver', type: 'combo', choices: ['auto', 'gl', 'gl3', 'gles2', 'nop'], - value: 'auto' + value: 'gl' ) From 364b8e10eeecd5859bfbdaa49e412ba71b56dd02 Mon Sep 17 00:00:00 2001 From: Michael Webster <miketwebster@gmail.com> Date: Fri, 1 Apr 2022 09:46:32 -0400 Subject: [PATCH 24/36] Work around an issue with nvidia sync waiting ref: https://gitlab.gnome.org/GNOME/mutter/-/commit/2afe3e922344a77f42afd388ad6c2ac456b314ce --- clutter/clutter/clutter-stage-private.h | 5 +- clutter/clutter/clutter-stage.c | 70 ++++++++++++++++++++++- clutter/clutter/cogl/clutter-stage-cogl.c | 18 +++++- src/compositor/meta-compositor-x11.c | 49 ++++++++++++---- src/compositor/meta-window-actor-x11.c | 3 +- 5 files changed, 127 insertions(+), 18 deletions(-) diff --git a/clutter/clutter/clutter-stage-private.h b/clutter/clutter/clutter-stage-private.h index 0bda81d9a..448fd3ef7 100644 --- a/clutter/clutter/clutter-stage-private.h +++ b/clutter/clutter/clutter-stage-private.h @@ -40,7 +40,10 @@ void clutter_stage_paint_view (ClutterStage ClutterStageView *view, const cairo_region_t *redraw_clip); -void _clutter_stage_emit_after_paint (ClutterStage *stage); +void clutter_stage_emit_before_update (ClutterStage *stage); +void clutter_stage_emit_before_paint (ClutterStage *stage); +void clutter_stage_emit_after_paint (ClutterStage *stage); +void clutter_stage_emit_after_update (ClutterStage *stage); CLUTTER_EXPORT void _clutter_stage_set_window (ClutterStage *stage, diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c index 9723ce49e..ca8e05866 100644 --- a/clutter/clutter/clutter-stage.c +++ b/clutter/clutter/clutter-stage.c @@ -179,7 +179,10 @@ enum ACTIVATE, DEACTIVATE, DELETE_EVENT, + BEFORE_UPDATE, + BEFORE_PAINT, AFTER_PAINT, + AFTER_UPDATE, PAINT_VIEW, PRESENTED, @@ -968,10 +971,27 @@ clutter_stage_paint_view (ClutterStage *stage, CLUTTER_STAGE_GET_CLASS (stage)->paint_view (stage, view, redraw_clip); } +clutter_stage_emit_before_update (ClutterStage *stage) +{ + g_signal_emit (stage, stage_signals[BEFORE_UPDATE], 0); +} + +void +clutter_stage_emit_before_paint (ClutterStage *stage) +{ + g_signal_emit (stage, stage_signals[BEFORE_PAINT], 0); +} + +void +clutter_stage_emit_after_paint (ClutterStage *stage) +{ + g_signal_emit (stage, stage_signals[AFTER_PAINT], 0); +} + void -_clutter_stage_emit_after_paint (ClutterStage *stage) +clutter_stage_emit_after_update (ClutterStage *stage) { - g_signal_emit (stage, stage_signals[AFTER_PAINT], 0); + g_signal_emit (stage, stage_signals[AFTER_UPDATE], 0); } /* If we don't implement this here, we get the paint function @@ -1522,6 +1542,8 @@ _clutter_stage_do_update (ClutterStage *stage) COGL_TRACE_BEGIN_SCOPED (ClutterStageDoUpdate, "Update"); + clutter_stage_emit_before_update (stage); + /* NB: We need to ensure we have an up to date layout *before* we * check or clear the pending redraws flag since a relayout may * queue a redraw. @@ -1533,7 +1555,10 @@ _clutter_stage_do_update (ClutterStage *stage) COGL_TRACE_END (ClutterStageRelayout); if (!priv->redraw_pending) - return FALSE; + { + clutter_stage_emit_after_update (stage); + return FALSE; + } if (stage_was_relayout) pointers = _clutter_stage_check_updated_pointers (stage); @@ -1568,6 +1593,8 @@ _clutter_stage_do_update (ClutterStage *stage) COGL_TRACE_END (ClutterStagePick); + clutter_stage_emit_after_update (stage); + return TRUE; } @@ -2208,6 +2235,31 @@ clutter_stage_class_init (ClutterStageClass *klass) G_TYPE_BOOLEAN, 1, CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); + /** + * ClutterStage::before-update: + * @stage: the #ClutterStage + */ + stage_signals[BEFORE_UPDATE] = + g_signal_new (I_("before-update"), + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); + + /** + * ClutterStage::before-paint: + * @stage: the stage that received the event + * + * The ::before-paint signal is emitted before the stage is painted. + */ + stage_signals[BEFORE_PAINT] = + g_signal_new (I_("before-paint"), + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); /** * ClutterStage::after-paint: * @stage: the stage that received the event @@ -2226,6 +2278,18 @@ clutter_stage_class_init (ClutterStageClass *klass) NULL, NULL, NULL, G_TYPE_NONE, 0); + /** + * ClutterStage::after-update: + * @stage: the #ClutterStage + */ + stage_signals[AFTER_UPDATE] = + g_signal_new (I_("after-update"), + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); + /** * ClutterStage::paint-view: * @stage: the stage that received the event diff --git a/clutter/clutter/cogl/clutter-stage-cogl.c b/clutter/clutter/cogl/clutter-stage-cogl.c index 0d99ba4bc..bda49ee4d 100644 --- a/clutter/clutter/cogl/clutter-stage-cogl.c +++ b/clutter/clutter/cogl/clutter-stage-cogl.c @@ -993,11 +993,26 @@ static void clutter_stage_cogl_redraw (ClutterStageWindow *stage_window) { ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window); + gboolean has_redraw_clip = FALSE; gboolean swap_event = FALSE; GList *l; COGL_TRACE_BEGIN (ClutterStageCoglRedraw, "Paint (Cogl Redraw)"); + for (l = _clutter_stage_window_get_views (stage_window); l; l = l->next) + { + ClutterStageView *view = l->data; + + if (!clutter_stage_view_has_redraw_clip (view)) + continue; + + has_redraw_clip = TRUE; + break; + } + + if (has_redraw_clip) + clutter_stage_emit_before_paint (stage_cogl->wrapper); + for (l = _clutter_stage_window_get_views (stage_window); l; l = l->next) { ClutterStageView *view = l->data; @@ -1008,7 +1023,8 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window) swap_event |= clutter_stage_cogl_redraw_view (stage_window, view); } - _clutter_stage_emit_after_paint (stage_cogl->wrapper); + if (has_redraw_clip) + clutter_stage_emit_after_paint (stage_cogl->wrapper); _clutter_stage_window_finish_frame (stage_window); diff --git a/src/compositor/meta-compositor-x11.c b/src/compositor/meta-compositor-x11.c index 2f863ad52..8ad1d0069 100644 --- a/src/compositor/meta-compositor-x11.c +++ b/src/compositor/meta-compositor-x11.c @@ -41,6 +41,9 @@ struct _MetaCompositorX11 Window output; + gulong before_update_handler_id; + gulong after_update_handler_id; + gboolean frame_has_updated_xsurfaces; gboolean have_x11_sync_object; @@ -55,6 +58,12 @@ struct _MetaCompositorX11 G_DEFINE_TYPE (MetaCompositorX11, meta_compositor_x11, META_TYPE_COMPOSITOR) +static void on_before_update (ClutterStage *stage, + MetaCompositor *compositor); + +static void on_after_update (ClutterStage *stage, + MetaCompositor *compositor); + static void process_damage (MetaCompositorX11 *compositor_x11, XDamageNotifyEvent *damage_xevent, @@ -183,6 +192,15 @@ meta_compositor_x11_manage (MetaCompositor *compositor) */ XMapWindow (xdisplay, compositor_x11->output); + ClutterStage *stage = meta_compositor_get_stage (compositor); + + compositor_x11->before_update_handler_id = + g_signal_connect (stage, "before-update", + G_CALLBACK (on_before_update), compositor); + compositor_x11->after_update_handler_id = + g_signal_connect (stage, "after-update", + G_CALLBACK (on_after_update), compositor); + compositor_x11->have_x11_sync_object = meta_sync_ring_init (xdisplay); meta_compositor_redirect_x11_windows (META_COMPOSITOR (compositor)); @@ -384,15 +402,10 @@ maybe_unredirect_top_window (MetaCompositorX11 *compositor_x11) } static void -meta_compositor_x11_pre_paint (MetaCompositor *compositor) +on_before_update (ClutterStage *stage, + MetaCompositor *compositor) { MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (compositor); - MetaCompositorClass *parent_class; - - maybe_unredirect_top_window (compositor_x11); - - parent_class = META_COMPOSITOR_CLASS (meta_compositor_x11_parent_class); - parent_class->pre_paint (compositor); if (compositor_x11->frame_has_updated_xsurfaces) { @@ -426,10 +439,10 @@ meta_compositor_x11_pre_paint (MetaCompositor *compositor) } static void -meta_compositor_x11_post_paint (MetaCompositor *compositor) +on_after_update (ClutterStage *stage, + MetaCompositor *compositor) { MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (compositor); - MetaCompositorClass *parent_class; if (compositor_x11->frame_has_updated_xsurfaces) { @@ -438,11 +451,21 @@ meta_compositor_x11_post_paint (MetaCompositor *compositor) compositor_x11->frame_has_updated_xsurfaces = FALSE; } +} + +static void +meta_compositor_x11_pre_paint (MetaCompositor *compositor) +{ + MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (compositor); + MetaCompositorClass *parent_class; + + maybe_unredirect_top_window (compositor_x11); parent_class = META_COMPOSITOR_CLASS (meta_compositor_x11_parent_class); - parent_class->post_paint (compositor); + parent_class->pre_paint (compositor); } + static void meta_compositor_x11_remove_window (MetaCompositor *compositor, MetaWindow *window) @@ -506,6 +529,8 @@ static void meta_compositor_x11_dispose (GObject *object) { MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (object); + MetaCompositor *compositor = META_COMPOSITOR (compositor_x11); + ClutterStage *stage = meta_compositor_get_stage (compositor); if (compositor_x11->have_x11_sync_object) { @@ -513,6 +538,9 @@ meta_compositor_x11_dispose (GObject *object) compositor_x11->have_x11_sync_object = FALSE; } + g_clear_signal_handler (&compositor_x11->before_update_handler_id, stage); + g_clear_signal_handler (&compositor_x11->after_update_handler_id, stage); + G_OBJECT_CLASS (meta_compositor_x11_parent_class)->dispose (object); } @@ -532,7 +560,6 @@ meta_compositor_x11_class_init (MetaCompositorX11Class *klass) compositor_class->manage = meta_compositor_x11_manage; compositor_class->unmanage = meta_compositor_x11_unmanage; compositor_class->pre_paint = meta_compositor_x11_pre_paint; - compositor_class->post_paint = meta_compositor_x11_post_paint; compositor_class->remove_window = meta_compositor_x11_remove_window; compositor_class->monotonic_to_high_res_xserver_time = meta_compositor_x11_monotonic_to_high_res_xserver_time; diff --git a/src/compositor/meta-window-actor-x11.c b/src/compositor/meta-window-actor-x11.c index ff511cf09..91b51c7ea 100644 --- a/src/compositor/meta-window-actor-x11.c +++ b/src/compositor/meta-window-actor-x11.c @@ -489,8 +489,7 @@ meta_window_actor_x11_queue_frame_drawn (MetaWindowActor *actor, } else if (surface) { - const cairo_rectangle_int_t clip = { 0, 0, 1, 1 }; - clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (surface), &clip); + clutter_actor_queue_redraw (CLUTTER_ACTOR (surface)); actor_x11->repaint_scheduled = TRUE; } } From f7436696c66becc88a1ab62180ed575985d19a76 Mon Sep 17 00:00:00 2001 From: Michael Webster <miketwebster@gmail.com> Date: Wed, 20 Apr 2022 14:21:04 -0400 Subject: [PATCH 25/36] Manage stacking for the desklet and desktop actors in the compositor so they can be managed properly with the background. Add a way to control the desklet container level. This wasn't an issue before, as the desklet container wasn't part of the window group, but now it is so we need to handle it during stack updating. --- src/compositor/compositor-private.h | 2 ++ src/compositor/compositor.c | 54 +++++++++++++++++++++++++++-- src/core/display-private.h | 2 ++ src/core/display.c | 27 +++++++++++++++ src/core/window.c | 2 +- src/meta/compositor-mutter.h | 3 ++ src/meta/display.h | 8 +++++ 7 files changed, 95 insertions(+), 3 deletions(-) diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h index 081f93e2c..488a8cc4c 100644 --- a/src/compositor/compositor-private.h +++ b/src/compositor/compositor-private.h @@ -69,6 +69,8 @@ ClutterStage * meta_compositor_get_stage (MetaCompositor *compositor); gboolean meta_compositor_is_switching_workspace (MetaCompositor *compositor); +void meta_update_desklet_stacking (MetaCompositor *compositor); + static inline int64_t us (int64_t us) { diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 807d4c16e..e93f20f50 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -69,6 +69,7 @@ #include "core/frame.h" #include "core/util-private.h" #include "core/window-private.h" +#include "core/meta-workspace-manager-private.h" #include "meta/compositor-mutter.h" #include "meta/main.h" #include "meta/meta-backend.h" @@ -117,6 +118,7 @@ typedef struct _MetaCompositorPrivate ClutterActor *bottom_window_group; ClutterActor *background_actor; + ClutterActor *desklet_container; GList *windows; @@ -600,10 +602,16 @@ meta_compositor_manage (MetaCompositor *compositor) priv->feedback_group = meta_window_group_new (display); priv->background_actor = meta_x11_background_actor_new_for_display (display); + // This needs to remain stacked just above the background actor in the window group. + // So sync_actor_stacking() has to be able to reference it. The deskletManager + // will take this and finish setting it up. + priv->desklet_container = clutter_actor_new (); + clutter_actor_add_child (priv->window_group, priv->background_actor); + clutter_actor_add_child (priv->window_group, priv->bottom_window_group); + clutter_actor_add_child (priv->window_group, priv->desklet_container); clutter_actor_add_child (priv->stage, priv->window_group); clutter_actor_add_child (priv->stage, priv->top_window_group); - clutter_actor_add_child (priv->stage, priv->bottom_window_group); clutter_actor_add_child (priv->stage, priv->feedback_group); META_COMPOSITOR_GET_CLASS (compositor)->manage (compositor); @@ -891,6 +899,21 @@ sync_actor_stacking (MetaCompositor *compositor) clutter_actor_set_child_below_sibling (parent, actor, NULL); } + // Place the desklet container above or below windows. + if (priv->display->desklets_above) + { + clutter_actor_set_child_above_sibling (priv->window_group, priv->desklet_container, NULL); + } + else + { + clutter_actor_set_child_below_sibling (priv->window_group, priv->desklet_container, NULL); + } + + // Then the bottom window group (which META_WINDOW_DESKTOP windows like nemo-desktop's get placed in). + clutter_actor_set_child_below_sibling (priv->window_group, priv->bottom_window_group, NULL); + + // and finally backgrounds.. + /* we prepended the backgrounds above so the last actor in the list * should get lowered to the bottom last. */ @@ -1280,6 +1303,7 @@ meta_compositor_dispose (GObject *object) priv->top_window_actor); g_clear_pointer (&priv->background_actor, clutter_actor_destroy); + g_clear_pointer (&priv->desklet_container, clutter_actor_destroy); g_clear_pointer (&priv->window_group, clutter_actor_destroy); g_clear_pointer (&priv->top_window_group, clutter_actor_destroy); g_clear_pointer (&priv->bottom_window_group, clutter_actor_destroy); @@ -1610,7 +1634,7 @@ meta_compositor_is_switching_workspace (MetaCompositor *compositor) * The root window background automatically tracks the image or color set * by the environment. * - * Return value: (transfer none): The background actor corresponding to @display + * Returns: (transfer none): The background actor corresponding to @display */ ClutterActor * meta_get_x11_background_actor_for_display (MetaDisplay *display) @@ -1620,3 +1644,29 @@ meta_get_x11_background_actor_for_display (MetaDisplay *display) return priv->background_actor; } + +/** + * meta_get_desklet_container_for_display: + * @display: a #MetaDisplay + * + * Returns the desklet container actor. + * + * Return value: (transfer none): The desklet container actor. + */ +ClutterActor * +meta_get_desklet_container_for_display (MetaDisplay *display) +{ + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (display->compositor); + + return priv->desklet_container; +} + +void +meta_update_desklet_stacking (MetaCompositor *compositor) +{ + MetaCompositorPrivate *priv = + meta_compositor_get_instance_private (compositor); + + meta_stack_tracker_queue_sync_stack (priv->display->stack_tracker); +} diff --git a/src/core/display-private.h b/src/core/display-private.h index 215df6c56..6d943bed5 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -225,6 +225,8 @@ struct _MetaDisplay GBytes *saved_clipboard; gchar *saved_clipboard_mimetype; MetaSelection *selection; + + gboolean desklets_above; }; struct _MetaDisplayClass diff --git a/src/core/display.c b/src/core/display.c index 56929ca99..ab8bcfa6f 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -3899,3 +3899,30 @@ meta_display_a11y_zoom (MetaDisplay *display, gboolean in) { g_signal_emit (display, display_signals[in ? ZOOM_SCROLL_IN : ZOOM_SCROLL_OUT], 0); } + +/** + * meta_display_set_desklets_above: + * @display: a #MetaDisplay + * @above: Whether to set above or not + * + * Raises the desklet container to the top of the stage temporatily. + */ +void +meta_display_set_desklets_above (MetaDisplay *display, gboolean above) +{ + display->desklets_above = above; + + meta_update_desklet_stacking (display->compositor); +} + +/** + * meta_display_get_desklets_above: + * @display: a #MetaDisplay + * + * Returns: Whether or not desklets are currently raised to the top. + */ +gboolean +meta_display_get_desklets_above (MetaDisplay *display) +{ + return display->desklets_above; +} \ No newline at end of file diff --git a/src/core/window.c b/src/core/window.c index 4bd3a949a..0fe7cbb79 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -8191,7 +8191,7 @@ meta_window_is_attached_dialog (MetaWindow *window) * - there is no 3rd window stacked between both tiled windows that's * partially visible in the common edge. * - * Return value: (transfer none) (nullable) (element-type MetaWindow): An array of matching tiled windows or + * Return value: (transfer none) (nullable): An array of matching tiled windows or * %NULL if none exist. */ diff --git a/src/meta/compositor-mutter.h b/src/meta/compositor-mutter.h index 20c05e507..b2db65522 100644 --- a/src/meta/compositor-mutter.h +++ b/src/meta/compositor-mutter.h @@ -63,4 +63,7 @@ gboolean meta_stage_is_focused (MetaDisplay *display); META_EXPORT ClutterActor *meta_get_x11_background_actor_for_display (MetaDisplay *display); +META_EXPORT +ClutterActor *meta_get_desklet_container_for_display (MetaDisplay *display); + #endif diff --git a/src/meta/display.h b/src/meta/display.h index 4d291f873..fa208f2f4 100644 --- a/src/meta/display.h +++ b/src/meta/display.h @@ -339,4 +339,12 @@ META_EXPORT GSList* meta_display_list_windows (MetaDisplay *display, MetaListWindowsFlags flags); +META_EXPORT +void meta_display_set_desklets_above (MetaDisplay *display, gboolean above); + +META_EXPORT +gboolean meta_display_get_desklets_above (MetaDisplay *display); + #endif + + From 5d9323a60fbab5e7486260a32b545de4bf742a6d Mon Sep 17 00:00:00 2001 From: Stephen Collins <scrivera64@gmail.com> Date: Mon, 2 May 2022 16:03:27 -0600 Subject: [PATCH 26/36] x11 input settings: Fix middle click emulation setting not working right --- src/backends/x11/meta-input-settings-x11.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backends/x11/meta-input-settings-x11.c b/src/backends/x11/meta-input-settings-x11.c index 506966174..3e6492895 100644 --- a/src/backends/x11/meta-input-settings-x11.c +++ b/src/backends/x11/meta-input-settings-x11.c @@ -959,7 +959,7 @@ meta_input_settings_x11_set_mouse_middle_click_emulation (MetaInputSettings *se if (!is_mouse (settings, device)) return; - change_property (device, "libinput Middle Click Emulation Enabled", + change_property (device, "libinput Middle Emulation Enabled", XA_INTEGER, 8, &value, 1); } @@ -973,7 +973,7 @@ meta_input_settings_x11_set_touchpad_middle_click_emulation (MetaInputSettings if (!meta_input_settings_x11_is_touchpad_device (settings, device)) return; - change_property (device, "libinput Middle Click Emulation Enabled", + change_property (device, "libinput Middle Emulation Enabled", XA_INTEGER, 8, &value, 1); } @@ -987,7 +987,7 @@ meta_input_settings_x11_set_trackball_middle_click_emulation (MetaInputSettings if (!meta_input_settings_x11_is_trackball_device (settings, device)) return; - change_property (device, "libinput Middle Click Emulation Enabled", + change_property (device, "libinput Middle Emulation Enabled", XA_INTEGER, 8, &value, 1); } From 258365ba8851ba17e15c6cb17e1973f2b2485b67 Mon Sep 17 00:00:00 2001 From: Michael Webster <miketwebster@gmail.com> Date: Thu, 5 May 2022 13:41:32 -0400 Subject: [PATCH 27/36] Fix a couple of build warnings --- clutter/clutter/clutter-stage.c | 1 + src/core/window.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c index ca8e05866..fa20b8e28 100644 --- a/clutter/clutter/clutter-stage.c +++ b/clutter/clutter/clutter-stage.c @@ -971,6 +971,7 @@ clutter_stage_paint_view (ClutterStage *stage, CLUTTER_STAGE_GET_CLASS (stage)->paint_view (stage, view, redraw_clip); } +void clutter_stage_emit_before_update (ClutterStage *stage) { g_signal_emit (stage, stage_signals[BEFORE_UPDATE], 0); diff --git a/src/core/window.c b/src/core/window.c index 0fe7cbb79..867e93445 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -3379,7 +3379,7 @@ meta_window_tile (MetaWindow *window, { MetaMaximizeFlags directions; MetaRectangle old_frame_rect, old_buffer_rect; - gboolean was_already_tiled = window->tile_mode != META_TILE_NONE && window->tile_mode != META_TILE_NONE; + gboolean was_already_tiled = window->tile_mode != META_TILE_NONE; meta_window_get_tile_fractions (window, tile_mode, &window->tile_hfraction, &window->tile_vfraction); window->tile_mode = tile_mode; From 33463480da355e1edf4696d53110327ea3223b57 Mon Sep 17 00:00:00 2001 From: Fabio Fantoni <fantonifabio@tiscali.it> Date: Fri, 6 May 2022 19:40:54 +0200 Subject: [PATCH 28/36] debian: restore kfreebsd support d/rules: restore armel and armhf default_driver change --- debian/control | 2 +- debian/rules | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/debian/control b/debian/control index bac6d7493..55ec3b6fd 100644 --- a/debian/control +++ b/debian/control @@ -34,7 +34,7 @@ Build-Depends: libjson-glib-dev (>= 0.13.2-1~), libpam0g-dev, libpango1.0-dev (>= 1.2.0), - libpipewire-0.2-dev | libpipewire-0.3-dev, + libpipewire-0.3-dev [linux-any] | libpipewire-0.2-dev [linux-any], libsm-dev, libstartup-notification0-dev (>= 0.7), libsystemd-dev (>= 212) [linux-any], diff --git a/debian/rules b/debian/rules index 7f1f73b71..a46a3c468 100755 --- a/debian/rules +++ b/debian/rules @@ -11,9 +11,22 @@ override_dh_autoreconf: CONFFLAGS = \ -Dprofiler=false \ - -Ddefault_driver=gl \ -Dremote_desktop=false +ifneq ($(DEB_HOST_ARCH_OS),linux) +CONFFLAGS += \ + -Dudev=false \ + -Dcore_tests=false +endif + +ifeq ($(DEB_HOST_ARCH),$(findstring $(DEB_HOST_ARCH),armel armhf)) +CONFFLAGS += \ + -Ddefault_driver=gles2 +else +CONFFLAGS += \ + -Ddefault_driver=gl +endif + override_dh_auto_configure: dh_auto_configure -- \ $(CONFFLAGS) From 6ef52e31274de406f8c88eabc0caed03a7194b42 Mon Sep 17 00:00:00 2001 From: Michael Webster <miketwebster@gmail.com> Date: Sun, 15 May 2022 00:04:15 -0400 Subject: [PATCH 29/36] Don't terminate on a bad allocation. --- clutter/clutter/clutter-box-layout.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/clutter/clutter/clutter-box-layout.c b/clutter/clutter/clutter-box-layout.c index 223b5204c..73eefe477 100644 --- a/clutter/clutter/clutter-box-layout.c +++ b/clutter/clutter/clutter-box-layout.c @@ -1036,7 +1036,8 @@ clutter_box_layout_allocate (ClutterLayoutManager *layout, /* Assert the api is working properly */ if (sizes[i].minimum_size < 0) - g_error ("ClutterBoxLayout child %s minimum %s: %f < 0 for %s %f", + { + g_critical ("ClutterBoxLayout child %s minimum %s: %f < 0 for %s %f", _clutter_actor_get_debug_name (child), priv->orientation == CLUTTER_ORIENTATION_VERTICAL ? "height" @@ -1049,8 +1050,12 @@ clutter_box_layout_allocate (ClutterLayoutManager *layout, ? box->x2 - box->x1 : box->y2 - box->y1); + sizes[i].minimum_size = 0; + } + if (sizes[i].natural_size < sizes[i].minimum_size) - g_error ("ClutterBoxLayout child %s natural %s: %f < minimum %f for %s %f", + { + g_critical ("ClutterBoxLayout child %s natural %s: %f < minimum %f for %s %f", _clutter_actor_get_debug_name (child), priv->orientation == CLUTTER_ORIENTATION_VERTICAL ? "height" @@ -1064,6 +1069,9 @@ clutter_box_layout_allocate (ClutterLayoutManager *layout, ? box->x2 - box->x1 : box->y2 - box->y1); + sizes[i].natural_size = sizes[i].minimum_size; + } + size -= sizes[i].minimum_size; sizes[i].actor = child; From e02d7e05378047008312b8026e3d7279b9399704 Mon Sep 17 00:00:00 2001 From: Michael Webster <miketwebster@gmail.com> Date: Wed, 18 May 2022 15:58:04 -0400 Subject: [PATCH 30/36] x11 backend: Don't rebuild all keybindings every time a different keyboard device is used. ref: https://gitlab.gnome.org/GNOME/mutter/-/issues/398 New muffin uses xinput2 instead of xlib for doing key grabs, and is incredibly slow at it in comparison. NewKeyboardNotify can be sent when using auxillary mouse buttons or the volume encoder on a keyboard. It ends up causing a very noticeable UI freeze when it happens. This seems to only affect nvidia. --- src/backends/x11/meta-backend-x11.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c index e18e6a1ab..adb427c6d 100644 --- a/src/backends/x11/meta-backend-x11.c +++ b/src/backends/x11/meta-backend-x11.c @@ -395,7 +395,6 @@ handle_host_xevent (MetaBackend *backend, { switch (xkb_ev->any.xkb_type) { - case XkbNewKeyboardNotify: case XkbMapNotify: keymap_changed (backend); break; From 45c205d3bb1f67ce211f550ff9be359e716fd334 Mon Sep 17 00:00:00 2001 From: Michael Webster <miketwebster@gmail.com> Date: Thu, 19 May 2022 11:32:43 -0400 Subject: [PATCH 31/36] Use cinnamon for interface names. --- src/backends/meta-idle-monitor-dbus.c | 8 ++++---- src/backends/meta-monitor-manager-private.h | 4 ++-- src/backends/meta-monitor-manager.c | 6 +++--- src/backends/meta-remote-desktop-session.c | 2 +- src/backends/meta-remote-desktop.c | 4 ++-- src/backends/meta-screen-cast-session.c | 2 +- src/backends/meta-screen-cast-stream.c | 4 ++-- src/backends/meta-screen-cast.c | 4 ++-- src/meson.build | 16 ++++++++-------- ...xml => org.cinnamon.Muffin.DisplayConfig.xml} | 4 ++-- ...r.xml => org.cinnamon.Muffin.IdleMonitor.xml} | 4 ++-- ...xml => org.cinnamon.Muffin.RemoteDesktop.xml} | 8 ++++---- ...st.xml => org.cinnamon.Muffin.ScreenCast.xml} | 12 ++++++------ 13 files changed, 39 insertions(+), 39 deletions(-) rename src/{org.gnome.Mutter.DisplayConfig.xml => org.cinnamon.Muffin.DisplayConfig.xml} (99%) rename src/{org.gnome.Mutter.IdleMonitor.xml => org.cinnamon.Muffin.IdleMonitor.xml} (90%) rename src/{org.gnome.Mutter.RemoteDesktop.xml => org.cinnamon.Muffin.RemoteDesktop.xml} (95%) rename src/{org.gnome.Mutter.ScreenCast.xml => org.cinnamon.Muffin.ScreenCast.xml} (92%) diff --git a/src/backends/meta-idle-monitor-dbus.c b/src/backends/meta-idle-monitor-dbus.c index 3fa0018bd..c3a64c07a 100644 --- a/src/backends/meta-idle-monitor-dbus.c +++ b/src/backends/meta-idle-monitor-dbus.c @@ -97,7 +97,7 @@ dbus_idle_callback (MetaIdleMonitor *monitor, g_dbus_connection_emit_signal (g_dbus_interface_skeleton_get_connection (skeleton), watch->dbus_name, g_dbus_interface_skeleton_get_object_path (skeleton), - "org.gnome.Mutter.IdleMonitor", + "org.cinnamon.Muffin.IdleMonitor", "WatchFired", g_variant_new ("(u)", watch_id), NULL); @@ -218,12 +218,12 @@ on_bus_acquired (GDBusConnection *connection, MetaIdleMonitor *monitor; char *path; - manager = g_dbus_object_manager_server_new ("/org/gnome/Mutter/IdleMonitor"); + manager = g_dbus_object_manager_server_new ("/org/cinnamon/Muffin/IdleMonitor"); /* We never clear the core monitor, as that's supposed to cumulate idle times from all devices */ monitor = meta_idle_monitor_get_core (); - path = g_strdup ("/org/gnome/Mutter/IdleMonitor/Core"); + path = g_strdup ("/org/cinnamon/Muffin/IdleMonitor/Core"); create_monitor_skeleton (manager, monitor, path); g_free (path); @@ -255,7 +255,7 @@ meta_idle_monitor_init_dbus (void) return; dbus_name_id = g_bus_own_name (G_BUS_TYPE_SESSION, - "org.gnome.Mutter.IdleMonitor", + "org.cinnamon.Muffin.IdleMonitor", G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT | (meta_get_replace_current_wm () ? G_BUS_NAME_OWNER_FLAGS_REPLACE : 0), diff --git a/src/backends/meta-monitor-manager-private.h b/src/backends/meta-monitor-manager-private.h index f86abe938..e9858f3b6 100644 --- a/src/backends/meta-monitor-manager-private.h +++ b/src/backends/meta-monitor-manager-private.h @@ -49,7 +49,7 @@ typedef enum _MetaMonitorManagerCapability META_MONITOR_MANAGER_CAPABILITY_NATIVE_OUTPUT_SCALING = (1 << 3), } MetaMonitorManagerCapability; -/* Equivalent to the 'method' enum in org.gnome.Mutter.DisplayConfig */ +/* Equivalent to the 'method' enum in org.cinnamon.Muffin.DisplayConfig */ typedef enum _MetaMonitorsConfigMethod { META_MONITORS_CONFIG_METHOD_VERIFY = 0, @@ -57,7 +57,7 @@ typedef enum _MetaMonitorsConfigMethod META_MONITORS_CONFIG_METHOD_PERSISTENT = 2 } MetaMonitorsConfigMethod; -/* Equivalent to the 'layout-mode' enum in org.gnome.Mutter.DisplayConfig */ +/* Equivalent to the 'layout-mode' enum in org.cinnamon.Muffin.DisplayConfig */ typedef enum _MetaLogicalMonitorLayoutMode { META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL = 1, diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c index 9cc9cc985..6be317e12 100644 --- a/src/backends/meta-monitor-manager.c +++ b/src/backends/meta-monitor-manager.c @@ -33,7 +33,7 @@ * (#MetaGpu). Its functions include reading and/or changing the current * configuration and available capabiliies. * - * The #MetaMonitorManager also provides the "org.gnome.Mutter.DisplayConfig" + * The #MetaMonitorManager also provides the "org.cinnamon.Muffin.DisplayConfig" * DBus service, so apps like GNOME Settings can use this functionality. */ @@ -2729,7 +2729,7 @@ on_bus_acquired (GDBusConnection *connection, g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (manager->display_config), connection, - "/org/gnome/Mutter/DisplayConfig", + "/org/cinnamon/Muffin/DisplayConfig", NULL); } @@ -2753,7 +2753,7 @@ static void initialize_dbus_interface (MetaMonitorManager *manager) { manager->dbus_name_id = g_bus_own_name (G_BUS_TYPE_SESSION, - "org.gnome.Mutter.DisplayConfig", + "org.cinnamon.Muffin.DisplayConfig", G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT | (meta_get_replace_current_wm () ? G_BUS_NAME_OWNER_FLAGS_REPLACE : 0), diff --git a/src/backends/meta-remote-desktop-session.c b/src/backends/meta-remote-desktop-session.c index 28191a1e0..b0157c98c 100644 --- a/src/backends/meta-remote-desktop-session.c +++ b/src/backends/meta-remote-desktop-session.c @@ -37,7 +37,7 @@ #include "meta-dbus-remote-desktop.h" -#define META_REMOTE_DESKTOP_SESSION_DBUS_PATH "/org/gnome/Mutter/RemoteDesktop/Session" +#define META_REMOTE_DESKTOP_SESSION_DBUS_PATH "/org/cinnamon/Muffin/RemoteDesktop/Session" enum _MetaRemoteDesktopNotifyAxisFlags { diff --git a/src/backends/meta-remote-desktop.c b/src/backends/meta-remote-desktop.c index b94055885..7bf306e5d 100644 --- a/src/backends/meta-remote-desktop.c +++ b/src/backends/meta-remote-desktop.c @@ -38,8 +38,8 @@ #include "meta-dbus-remote-desktop.h" -#define META_REMOTE_DESKTOP_DBUS_SERVICE "org.gnome.Mutter.RemoteDesktop" -#define META_REMOTE_DESKTOP_DBUS_PATH "/org/gnome/Mutter/RemoteDesktop" +#define META_REMOTE_DESKTOP_DBUS_SERVICE "org.cinnamon.Muffin.RemoteDesktop" +#define META_REMOTE_DESKTOP_DBUS_PATH "/org/cinnamon/Muffin/RemoteDesktop" #define META_REMOTE_DESKTOP_API_VERSION 1 typedef enum _MetaRemoteDesktopDeviceTypes diff --git a/src/backends/meta-screen-cast-session.c b/src/backends/meta-screen-cast-session.c index 7a1b8e07a..545a7da86 100644 --- a/src/backends/meta-screen-cast-session.c +++ b/src/backends/meta-screen-cast-session.c @@ -32,7 +32,7 @@ #include "backends/meta-screen-cast-window-stream.h" #include "core/display-private.h" -#define META_SCREEN_CAST_SESSION_DBUS_PATH "/org/gnome/Mutter/ScreenCast/Session" +#define META_SCREEN_CAST_SESSION_DBUS_PATH "/org/cinnamon/Muffin/ScreenCast/Session" struct _MetaScreenCastSession { diff --git a/src/backends/meta-screen-cast-stream.c b/src/backends/meta-screen-cast-stream.c index e7bc7f216..2781ad6a6 100644 --- a/src/backends/meta-screen-cast-stream.c +++ b/src/backends/meta-screen-cast-stream.c @@ -26,8 +26,8 @@ #include "backends/meta-screen-cast-session.h" -#define META_SCREEN_CAST_STREAM_DBUS_IFACE "org.gnome.Mutter.ScreenCast.Stream" -#define META_SCREEN_CAST_STREAM_DBUS_PATH "/org/gnome/Mutter/ScreenCast/Stream" +#define META_SCREEN_CAST_STREAM_DBUS_IFACE "org.cinnamon.Muffin.ScreenCast.Stream" +#define META_SCREEN_CAST_STREAM_DBUS_PATH "/org/cinnamon/Muffin/ScreenCast/Stream" enum { diff --git a/src/backends/meta-screen-cast.c b/src/backends/meta-screen-cast.c index b473aa8eb..53411e833 100644 --- a/src/backends/meta-screen-cast.c +++ b/src/backends/meta-screen-cast.c @@ -30,8 +30,8 @@ #include "backends/meta-remote-desktop-session.h" #include "backends/meta-screen-cast-session.h" -#define META_SCREEN_CAST_DBUS_SERVICE "org.gnome.Mutter.ScreenCast" -#define META_SCREEN_CAST_DBUS_PATH "/org/gnome/Mutter/ScreenCast" +#define META_SCREEN_CAST_DBUS_SERVICE "org.cinnamon.Muffin.ScreenCast" +#define META_SCREEN_CAST_DBUS_PATH "/org/cinnamon/Muffin/ScreenCast" #define META_SCREEN_CAST_API_VERSION 3 struct _MetaScreenCast diff --git a/src/meson.build b/src/meson.build index 3c89e00c2..cb15dd47b 100644 --- a/src/meson.build +++ b/src/meson.build @@ -706,15 +706,15 @@ endif mutter_built_sources = [] dbus_display_config_built_sources = gnome.gdbus_codegen('meta-dbus-display-config', - 'org.gnome.Mutter.DisplayConfig.xml', - interface_prefix: 'org.gnome.Mutter.', + 'org.cinnamon.Muffin.DisplayConfig.xml', + interface_prefix: 'org.cinnamon.Muffin.', namespace: 'MetaDBus', ) mutter_built_sources += dbus_display_config_built_sources dbus_idle_monitor_built_sources = gnome.gdbus_codegen('meta-dbus-idle-monitor', - 'org.gnome.Mutter.IdleMonitor.xml', - interface_prefix: 'org.gnome.Mutter.', + 'org.cinnamon.Muffin.IdleMonitor.xml', + interface_prefix: 'org.cinnamon.Muffin.', namespace: 'MetaDBus', object_manager: true, ) @@ -777,15 +777,15 @@ endif if have_remote_desktop dbus_remote_desktop_built_sources = gnome.gdbus_codegen('meta-dbus-remote-desktop', - 'org.gnome.Mutter.RemoteDesktop.xml', - interface_prefix: 'org.gnome.Mutter.', + 'org.cinnamon.Muffin.RemoteDesktop.xml', + interface_prefix: 'org.cinnamon.Muffin.', namespace: 'MetaDBus', ) mutter_built_sources += dbus_remote_desktop_built_sources dbus_screen_cast_built_sources = gnome.gdbus_codegen('meta-dbus-screen-cast', - 'org.gnome.Mutter.ScreenCast.xml', - interface_prefix: 'org.gnome.Mutter.', + 'org.cinnamon.Muffin.ScreenCast.xml', + interface_prefix: 'org.cinnamon.Muffin.', namespace: 'MetaDBus', ) mutter_built_sources += dbus_screen_cast_built_sources diff --git a/src/org.gnome.Mutter.DisplayConfig.xml b/src/org.cinnamon.Muffin.DisplayConfig.xml similarity index 99% rename from src/org.gnome.Mutter.DisplayConfig.xml rename to src/org.cinnamon.Muffin.DisplayConfig.xml index 4ec6cd4dc..66591b7d4 100644 --- a/src/org.gnome.Mutter.DisplayConfig.xml +++ b/src/org.cinnamon.Muffin.DisplayConfig.xml @@ -3,14 +3,14 @@ 'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'> <node> <!-- - org.gnome.Mutter.DisplayConfig: + org.cinnamon.Muffin.DisplayConfig: @short_description: display configuration interface This interface is used by mutter and gnome-settings-daemon to apply multiple monitor configuration. --> - <interface name="org.gnome.Mutter.DisplayConfig"> + <interface name="org.cinnamon.Muffin.DisplayConfig"> <!-- GetResources: diff --git a/src/org.gnome.Mutter.IdleMonitor.xml b/src/org.cinnamon.Muffin.IdleMonitor.xml similarity index 90% rename from src/org.gnome.Mutter.IdleMonitor.xml rename to src/org.cinnamon.Muffin.IdleMonitor.xml index 374af4dc4..c1f13840b 100644 --- a/src/org.gnome.Mutter.IdleMonitor.xml +++ b/src/org.cinnamon.Muffin.IdleMonitor.xml @@ -3,14 +3,14 @@ 'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'> <node> <!-- - org.gnome.Mutter.IdleMonitor: + org.cinnamon.Muffin.IdleMonitor: @short_description: idle monitor interface This interface is used by gnome-desktop to implement user activity monitoring. --> - <interface name="org.gnome.Mutter.IdleMonitor"> + <interface name="org.cinnamon.Muffin.IdleMonitor"> <method name="GetIdletime"> <arg name="idletime" direction="out" type="t"/> </method> diff --git a/src/org.gnome.Mutter.RemoteDesktop.xml b/src/org.cinnamon.Muffin.RemoteDesktop.xml similarity index 95% rename from src/org.gnome.Mutter.RemoteDesktop.xml rename to src/org.cinnamon.Muffin.RemoteDesktop.xml index a07aefe27..b0211f030 100644 --- a/src/org.gnome.Mutter.RemoteDesktop.xml +++ b/src/org.cinnamon.Muffin.RemoteDesktop.xml @@ -4,14 +4,14 @@ <node> <!-- - org.gnome.Mutter.RemoteDesktop: + org.cinnamon.Muffin.RemoteDesktop: @short_description: Remote desktop interface This API is private and not intended to be used outside of the integrated system that uses libmutter. No compatibility between versions are promised. --> - <interface name="org.gnome.Mutter.RemoteDesktop"> + <interface name="org.cinnamon.Muffin.RemoteDesktop"> <!-- CreateSession: @@ -41,10 +41,10 @@ </interface> <!-- - org.gnome.Mutter.RemoteDesktop.Session: + org.cinnamon.Muffin.RemoteDesktop.Session: @short_description: Remote desktop session --> - <interface name="org.gnome.Mutter.RemoteDesktop.Session"> + <interface name="org.cinnamon.Muffin.RemoteDesktop.Session"> <!-- SessionId: diff --git a/src/org.gnome.Mutter.ScreenCast.xml b/src/org.cinnamon.Muffin.ScreenCast.xml similarity index 92% rename from src/org.gnome.Mutter.ScreenCast.xml rename to src/org.cinnamon.Muffin.ScreenCast.xml index 1d9fa598e..98a8e35b6 100644 --- a/src/org.gnome.Mutter.ScreenCast.xml +++ b/src/org.cinnamon.Muffin.ScreenCast.xml @@ -4,14 +4,14 @@ <node> <!-- - org.gnome.Mutter.ScreenCast: + org.cinnamon.Muffin.ScreenCast: @short_description: Screen cast interface This API is private and not intended to be used outside of the integrated system that uses libmutter. No compatibility between versions are promised. --> - <interface name="org.gnome.Mutter.ScreenCast"> + <interface name="org.cinnamon.Muffin.ScreenCast"> <!-- CreateSession: @@ -41,10 +41,10 @@ </interface> <!-- - org.gnome.Mutter.ScreenCast.Session: + org.cinnamon.Muffin.ScreenCast.Session: @short_description: Screen cast session --> - <interface name="org.gnome.Mutter.ScreenCast.Session"> + <interface name="org.cinnamon.Muffin.ScreenCast.Session"> <!-- Start: @@ -114,10 +114,10 @@ </interface> <!-- - org.gnome.Mutter.ScreenCast.Stream: + org.cinnamon.Muffin.ScreenCast.Stream: @short_description: Screen cast stream --> - <interface name="org.gnome.Mutter.ScreenCast.Stream"> + <interface name="org.cinnamon.Muffin.ScreenCast.Stream"> <!-- PipeWireStreamAdded: From 50aa5354797eba410cadf1349276ca0132804c9e Mon Sep 17 00:00:00 2001 From: Michael Webster <miketwebster@gmail.com> Date: Fri, 20 May 2022 16:00:15 -0400 Subject: [PATCH 32/36] Remove some unused files, dependency. --- clutter/clutter/mutter-clutter.pc.in | 24 ------------------------ cogl/cogl-pango/mutter-cogl-pango.pc.in | 13 ------------- cogl/cogl-path/mutter-cogl-path.pc.in | 13 ------------- cogl/cogl/mutter-cogl.pc.in | 13 ------------- debian/control | 1 - src/libmutter.pc.in | 14 -------------- 6 files changed, 78 deletions(-) delete mode 100644 clutter/clutter/mutter-clutter.pc.in delete mode 100644 cogl/cogl-pango/mutter-cogl-pango.pc.in delete mode 100644 cogl/cogl-path/mutter-cogl-path.pc.in delete mode 100644 cogl/cogl/mutter-cogl.pc.in delete mode 100644 src/libmutter.pc.in diff --git a/clutter/clutter/mutter-clutter.pc.in b/clutter/clutter/mutter-clutter.pc.in deleted file mode 100644 index 6509dfc95..000000000 --- a/clutter/clutter/mutter-clutter.pc.in +++ /dev/null @@ -1,24 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -apiversion=@LIBMUTTER_API_VERSION@ -libdir=@libdir@/mutter-${apiversion} -includedir=@includedir@/mutter-${apiversion} - -requires=@CLUTTER_REQUIRES@ mutter-cogl-${apiversion} -requires_private=@CLUTTER_REQUIRES_PRIVATE@ -backends=@CLUTTER_BACKENDS@ - -# only kept for backward compatibility -soname_infix=@CLUTTER_SONAME_INFIX@ -winsys=@CLUTTER_WINSYS@ -backend=@CLUTTER_WINSYS@ -cogl=deprecated -cogl_driver=deprecated - -Name: Mutter Clutter -Description: Mutter's Clutter Private Library -Version: @MUTTER_VERSION@ -Libs: -L${libdir} -lmutter-clutter-${apiversion} -Cflags: -I${includedir}/clutter -Requires: ${requires} -Requires.private: ${requires_private} diff --git a/cogl/cogl-pango/mutter-cogl-pango.pc.in b/cogl/cogl-pango/mutter-cogl-pango.pc.in deleted file mode 100644 index d0ab7c45f..000000000 --- a/cogl/cogl-pango/mutter-cogl-pango.pc.in +++ /dev/null @@ -1,13 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -apiversion=@LIBMUTTER_API_VERSION@ -libdir=@libdir@/mutter-${apiversion} -includedir=@includedir@/mutter-${apiversion} -requires=@COGL_PKG_REQUIRES@ mutter-cogl-${apiversion} - -Name: Cogl -Description: An object oriented GL/GLES Abstraction/Utility Layer -Version: @MUTTER_VERSION@ -Libs: -L${libdir} -lmutter-cogl-pango-${apiversion} -Cflags: -I${includedir}/cogl -Requires: ${requires} diff --git a/cogl/cogl-path/mutter-cogl-path.pc.in b/cogl/cogl-path/mutter-cogl-path.pc.in deleted file mode 100644 index 5618bba9a..000000000 --- a/cogl/cogl-path/mutter-cogl-path.pc.in +++ /dev/null @@ -1,13 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -apiversion=@LIBMUTTER_API_VERSION@ -libdir=@libdir@/mutter-${apiversion} -includedir=@includedir@/mutter-${apiversion} -requires=@COGL_PKG_REQUIRES@ mutter-cogl-${apiversion} - -Name: Cogl -Description: A 2D path drawing library for Cogl -Version: @MUTTER_VERSION@ -Libs: -L${libdir} -lmutter-cogl-path-${apiversion} -Cflags: -I${includedir}/cogl -Requires: ${requires} diff --git a/cogl/cogl/mutter-cogl.pc.in b/cogl/cogl/mutter-cogl.pc.in deleted file mode 100644 index 797eef3d2..000000000 --- a/cogl/cogl/mutter-cogl.pc.in +++ /dev/null @@ -1,13 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -apiversion=@LIBMUTTER_API_VERSION@ -libdir=@libdir@/mutter-${apiversion} -includedir=@includedir@/mutter-${apiversion} -requires=@COGL_PKG_REQUIRES@ - -Name: Cogl -Description: An object oriented GL/GLES Abstraction/Utility Layer -Version: @MUTTER_VERSION@ -Libs: -L${libdir} -lmutter-cogl-${apiversion} -Cflags: -I${includedir}/cogl -Requires: ${requires} diff --git a/debian/control b/debian/control index 55ec3b6fd..e08a468e4 100644 --- a/debian/control +++ b/debian/control @@ -10,7 +10,6 @@ Build-Depends: cinnamon-desktop-data (>= 5.3.0), dbus <!nocheck>, dmz-cursor-theme <!nocheck>, - gnome-control-center-data, gnome-pkg-tools (>= 0.10), cinnamon-settings-daemon <!nocheck>, gobject-introspection (>= 1.41.3), diff --git a/src/libmutter.pc.in b/src/libmutter.pc.in deleted file mode 100644 index 8ad9bdb5c..000000000 --- a/src/libmutter.pc.in +++ /dev/null @@ -1,14 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ -apiversion=@LIBMUTTER_API_VERSION@ -girdir=@libdir@/mutter-${apiversion} -typelibdir=@libdir@/mutter-${apiversion} - -Name: libmutter -Description: Mutter window manager library -Requires: gsettings-desktop-schemas gtk+-3.0 mutter-clutter-${apiversion} x11 -Version: @VERSION@ -Libs: -L${libdir} -lmutter-${apiversion} -Cflags: -I${includedir}/mutter-${apiversion} From c9aa957d439f52dffb4a3d2e91b045ac46668400 Mon Sep 17 00:00:00 2001 From: Michael Webster <miketwebster@gmail.com> Date: Wed, 25 May 2022 11:24:42 -0400 Subject: [PATCH 33/36] rules: disable dh_dwz (build warnings) --- debian/rules | 2 ++ 1 file changed, 2 insertions(+) diff --git a/debian/rules b/debian/rules index a46a3c468..00abf4ca6 100755 --- a/debian/rules +++ b/debian/rules @@ -86,3 +86,5 @@ override_dh_shlibdeps: override_dh_strip: dh_strip --dbg-package=muffin-dbg + +override_dh_dwz: From 09cc71d29c39a6b32eb98c2d132ef754ee73aa5a Mon Sep 17 00:00:00 2001 From: Michael Webster <miketwebster@gmail.com> Date: Mon, 30 May 2022 10:41:54 -0400 Subject: [PATCH 34/36] Catch gtk theme name changes instead of simply relying on monitored style classes and elements changing. Muffin only uses a very narrow set of theme elements, and they chain from the ssd window background changing. This doesn't happen when we switch from Mint-Y to Mint-Y-Blue, for example, as they all have the same background. --- src/core/prefs.c | 16 ++++++++++++++++ src/meta/prefs.h | 4 +++- src/ui/frames.c | 3 +++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/core/prefs.c b/src/core/prefs.c index 5dd806bc7..7effd7e10 100644 --- a/src/core/prefs.c +++ b/src/core/prefs.c @@ -64,6 +64,8 @@ #define KEY_WORKSPACES_ONLY_ON_PRIMARY "workspaces-only-on-primary" #define KEY_LOCATE_POINTER "locate-pointer" +#define KEY_GTK_THEME "gtk-theme" + /* These are the different schemas we are keeping * a GSettings instance for */ #define SCHEMA_GENERAL "org.cinnamon.desktop.wm.preferences" @@ -137,6 +139,7 @@ static char *iso_next_group_option = NULL; static MetaX11BackgroundTransition background_transition = META_X11_BACKGROUND_TRANSITION_BLEND; static gboolean unredirect_fullscreen_windows = FALSE; static gboolean tile_maximize = FALSE; +static char *gtk_theme = NULL; static void handle_preference_update_enum (GSettings *settings, gchar *key); @@ -518,6 +521,14 @@ static MetaStringPreference preferences_string[] = locate_pointer_key_handler, NULL, }, + { + { "gtk-theme", + SCHEMA_INTERFACE, + META_PREF_GTK_THEME, + }, + NULL, + >k_theme, + }, { { NULL, 0, 0 }, NULL }, }; @@ -1098,6 +1109,8 @@ meta_prefs_init (void) G_CALLBACK (settings_changed), NULL); g_signal_connect (settings, "changed::" KEY_LOCATE_POINTER, G_CALLBACK (settings_changed), NULL); + g_signal_connect (settings, "changed::" KEY_GTK_THEME, + G_CALLBACK (settings_changed), NULL); g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_INTERFACE), settings); settings = g_settings_new (SCHEMA_INPUT_SOURCES); @@ -1901,6 +1914,9 @@ meta_preference_to_string (MetaPreference pref) case META_PREF_TILE_MAXIMIZE: return "TILE_MAXIMIZE"; + + case META_PREF_GTK_THEME: + return "GTK_THEME"; } return "(unknown)"; diff --git a/src/meta/prefs.h b/src/meta/prefs.h index 7bbe1d572..51edc1ca4 100644 --- a/src/meta/prefs.h +++ b/src/meta/prefs.h @@ -68,6 +68,7 @@ * @META_PREF_CENTER_NEW_WINDOWS: center new windows * @META_PREF_DRAG_THRESHOLD: drag threshold * @META_PREF_LOCATE_POINTER: show pointer location + * @META_PREF_GTK_THEME: gtk theme name */ /* Keep in sync with GSettings schemas! */ @@ -115,7 +116,8 @@ typedef enum META_PREF_WORKSPACE_CYCLE, META_PREF_MIN_WIN_OPACITY, META_PREF_MOUSE_ZOOM_ENABLED, - META_PREF_TILE_MAXIMIZE + META_PREF_TILE_MAXIMIZE, + META_PREF_GTK_THEME } MetaPreference; typedef void (* MetaPrefsChangedFunc) (MetaPreference pref, diff --git a/src/ui/frames.c b/src/ui/frames.c index 8ddf86275..9c41a2aa3 100644 --- a/src/ui/frames.c +++ b/src/ui/frames.c @@ -150,6 +150,9 @@ prefs_changed_callback (MetaPreference pref, case META_PREF_BUTTON_LAYOUT: meta_frames_button_layout_changed (META_FRAMES (data)); break; + case META_PREF_GTK_THEME: + meta_frames_style_updated (GTK_WIDGET (data)); + break; default: break; } From fc96eea56ec492c47ae94a99a5c5bf774c673875 Mon Sep 17 00:00:00 2001 From: Michael Webster <miketwebster@gmail.com> Date: Thu, 2 Jun 2022 13:44:45 -0400 Subject: [PATCH 35/36] Move some keybindings, re-enable monitor switch, rotate. --- data/org.cinnamon.muffin.gschema.xml.in | 27 -------------------- src/core/keybindings.c | 34 +++++++++++++------------ 2 files changed, 18 insertions(+), 43 deletions(-) diff --git a/data/org.cinnamon.muffin.gschema.xml.in b/data/org.cinnamon.muffin.gschema.xml.in index 048c7c4de..300232ebc 100644 --- a/data/org.cinnamon.muffin.gschema.xml.in +++ b/data/org.cinnamon.muffin.gschema.xml.in @@ -192,22 +192,6 @@ </schema> <schema id="org.cinnamon.muffin.keybindings" path="/org/cinnamon/muffin/keybindings/"> - <key name="push-tile-left" type="as"> - <default><![CDATA[['<Super>Left']]]></default> - </key> - - <key name="push-tile-right" type="as"> - <default><![CDATA[['<Super>Right']]]></default> - </key> - - <key name="push-tile-up" type="as"> - <default><![CDATA[['<Super>Up']]]></default> - </key> - - <key name="push-tile-down" type="as"> - <default><![CDATA[['<Super>Down']]]></default> - </key> - <key name="tab-popup-select" type="as"> <default>[]</default> <summary>Select window from tab popup</summary> @@ -217,16 +201,5 @@ <default>[]</default> <summary>Cancel tab popup</summary> </key> - - <key name="switch-monitor" type="as"> - <default><![CDATA[['<Super>p','XF86Display']]]></default> - <summary>Switch monitor configurations</summary> - </key> - - <key name="rotate-monitor" type="as"> - <default><![CDATA[['XF86RotateWindows']]]></default> - <summary>Rotates the built-in monitor configuration</summary> - </key> - </schema> </schemalist> diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 7bd13a301..d6f046fad 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -4158,19 +4158,19 @@ init_builtin_key_bindings (MetaDisplay *display) META_KEYBINDING_ACTION_TOGGLE_RECORDING, NULL, 0); - // add_builtin_keybinding (display, - // "switch-monitor", - // mutter_keybindings, - // META_KEY_BINDING_NONE, - // META_KEYBINDING_ACTION_SWITCH_MONITOR, - // handle_switch_monitor, 0); + add_builtin_keybinding (display, + "switch-monitor", + common_keybindings, + META_KEY_BINDING_NONE, + META_KEYBINDING_ACTION_SWITCH_MONITOR, + handle_switch_monitor, 0); - // add_builtin_keybinding (display, - // "rotate-monitor", - // mutter_keybindings, - // META_KEY_BINDING_NONE, - // META_KEYBINDING_ACTION_ROTATE_MONITOR, - // handle_rotate_monitor, 0); + add_builtin_keybinding (display, + "rotate-monitor", + common_keybindings, + META_KEY_BINDING_NONE, + META_KEYBINDING_ACTION_ROTATE_MONITOR, + handle_rotate_monitor, 0); #ifdef HAVE_NATIVE_BACKEND MetaBackend *backend = meta_get_backend (); @@ -4301,7 +4301,7 @@ init_builtin_key_bindings (MetaDisplay *display) add_builtin_keybinding (display, "push-tile-left", - mutter_keybindings, + common_keybindings, META_KEY_BINDING_PER_WINDOW | META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_PUSH_TILE_LEFT, @@ -4309,7 +4309,7 @@ init_builtin_key_bindings (MetaDisplay *display) add_builtin_keybinding (display, "push-tile-right", - mutter_keybindings, + common_keybindings, META_KEY_BINDING_PER_WINDOW | META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_PUSH_TILE_RIGHT, @@ -4317,7 +4317,7 @@ init_builtin_key_bindings (MetaDisplay *display) add_builtin_keybinding (display, "push-tile-up", - mutter_keybindings, + common_keybindings, META_KEY_BINDING_PER_WINDOW | META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_PUSH_TILE_UP, @@ -4325,7 +4325,7 @@ init_builtin_key_bindings (MetaDisplay *display) add_builtin_keybinding (display, "push-tile-down", - mutter_keybindings, + common_keybindings, META_KEY_BINDING_PER_WINDOW | META_KEY_BINDING_IGNORE_AUTOREPEAT, META_KEYBINDING_ACTION_PUSH_TILE_DOWN, @@ -4595,6 +4595,8 @@ init_builtin_key_bindings (MetaDisplay *display) META_KEYBINDING_ACTION_MAXIMIZE_HORIZONTALLY, handle_maximize_horizontally, 0); + /* Handled already by toggle_above */ + // add_builtin_keybinding (display, // "always-on-top", // common_keybindings, From 559c421e0d5c52caa1b8475f7cb31735e29bc814 Mon Sep 17 00:00:00 2001 From: Michael Webster <miketwebster@gmail.com> Date: Sat, 28 May 2022 20:57:51 -0400 Subject: [PATCH 36/36] Add some api for the display applet. display: Add helper functions for translating between logical and xinerama monitor numbers. Monitor 0 is traditionally the primary monitor. Logical monitors don't work this way - if you change the primary, its number stays the same. Fortunately the underlying x number is still available. This may eventually be complicated by monitors that allow multiple logical inputs (tiling), but I have none to test with. --- src/backends/meta-monitor-manager.c | 147 ++++++++++++++++++++++++++++ src/core/display.c | 36 +++++++ src/meta/display.h | 8 ++ src/meta/meta-monitor-manager.h | 16 +++ 4 files changed, 207 insertions(+) diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c index 6be317e12..725530cad 100644 --- a/src/backends/meta-monitor-manager.c +++ b/src/backends/meta-monitor-manager.c @@ -3564,3 +3564,150 @@ meta_monitor_manager_get_vendor_name (MetaMonitorManager *manager, return gnome_pnp_ids_get_pnp_id (manager->pnp_ids, vendor); } + +#define META_MONITOR_TRANSFORM_INVALID -1 + +MetaMonitorTransform +xrandr_to_monitor_transform (MetaXrandrRotation rotation) +{ + switch (rotation) + { + case META_XRANDR_ROTATION_NORMAL: + return META_MONITOR_TRANSFORM_NORMAL; + case META_XRANDR_ROTATION_LEFT: + return META_MONITOR_TRANSFORM_90; + case META_XRANDR_ROTATION_FLIPPED: + return META_MONITOR_TRANSFORM_180; + case META_XRANDR_ROTATION_RIGHT: + return META_MONITOR_TRANSFORM_270; + + default: + g_return_val_if_reached (META_MONITOR_TRANSFORM_INVALID); + } +} + +gboolean +meta_monitor_manager_can_apply_rotation (MetaMonitorManager *manager, + MetaXrandrRotation rotation) +{ + gboolean ret = FALSE; + + if (!meta_monitor_manager_get_is_builtin_display_on (manager)) + return FALSE; + + MetaOrientation orientation = xrandr_to_monitor_transform (rotation); + + if (orientation == META_MONITOR_TRANSFORM_INVALID) + { + meta_warning ("Invalid orientation requested."); + return ret; + } + + MetaMonitorsConfig *config = meta_monitor_config_manager_create_for_orientation (manager->config_manager, orientation); + + ret = config != NULL; + + g_clear_object (&config); + + if (ret) + return TRUE; + + MetaXrandrRotation current_rotation; + meta_monitor_manager_get_current_rotation (manager, ¤t_rotation); + + if (current_rotation == rotation) + return TRUE; + + return FALSE; +} + +gboolean +meta_monitor_manager_apply_temporary_rotation (MetaMonitorManager *manager, + MetaXrandrRotation rotation) +{ + MetaOrientation orientation = xrandr_to_monitor_transform (rotation); + + if (orientation == META_MONITOR_TRANSFORM_INVALID) + { + meta_warning ("Invalid orientation requested."); + return FALSE; + } + + GError *error = NULL; + MetaMonitorsConfig *config = meta_monitor_config_manager_create_for_orientation (manager->config_manager, orientation); + + if (!config) + { + meta_warning ("Could not create config for rotation."); + return FALSE; + } + + if (!meta_monitor_manager_apply_monitors_config (manager, + config, + META_MONITORS_CONFIG_METHOD_TEMPORARY, + &error)) + { + g_warning ("Failed to use rotate monitor configuration: %s", + error->message); + g_error_free (error); + g_object_unref (config); + return FALSE; + } + + g_object_unref (config); + + return TRUE; +} + +MetaXrandrRotation +monitor_transform_to_xrandr_rotation (MetaMonitorTransform transform) +{ + switch (transform) + { + case META_MONITOR_TRANSFORM_NORMAL: + return META_XRANDR_ROTATION_NORMAL; + case META_MONITOR_TRANSFORM_90: + return META_XRANDR_ROTATION_LEFT; + case META_MONITOR_TRANSFORM_180: + return META_XRANDR_ROTATION_FLIPPED; + case META_MONITOR_TRANSFORM_270: + return META_XRANDR_ROTATION_RIGHT; + default: + g_return_val_if_reached (META_XRANDR_ROTATION_NORMAL); + } +} + +/** + * meta_monitor_manager_get_current_rotation: + * @manager: A #MetaMonitorManager object + * @rotation: (out): The current #MetaXrandrRotation applied to the laptop panel. + * + * Returns %TRUE if there is a laptop panel and its current rotation + * can be determined, otherwise %FALSE + */ +gboolean +meta_monitor_manager_get_current_rotation (MetaMonitorManager *manager, + MetaXrandrRotation *rotation) +{ + MetaMonitor *monitor; + MetaLogicalMonitor *logical_monitor; + + *rotation = META_XRANDR_ROTATION_NORMAL; + monitor = meta_monitor_manager_get_laptop_panel (manager); + + if (monitor == NULL || !meta_monitor_is_active (monitor)) + { + return FALSE; + } + + logical_monitor = meta_monitor_get_logical_monitor (monitor); + + if (logical_monitor != NULL) + { + MetaMonitorTransform transform = meta_logical_monitor_get_transform (logical_monitor); + *rotation = monitor_transform_to_xrandr_rotation (transform); + return TRUE; + } + + return FALSE; +} diff --git a/src/core/display.c b/src/core/display.c index ab8bcfa6f..3743e03bb 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -3925,4 +3925,40 @@ gboolean meta_display_get_desklets_above (MetaDisplay *display) { return display->desklets_above; +} + +gint +meta_display_xinerama_index_to_logical_index (MetaDisplay *display, + gint x_index) +{ + MetaLogicalMonitor *monitor; + + monitor = meta_x11_display_xinerama_index_to_logical_monitor (display->x11_display, x_index); + + if (monitor == NULL) + { + return 0; + } + + return monitor->number; +} + +gint +meta_display_logical_index_to_xinerama_index (MetaDisplay *display, + gint log_index) +{ + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *manager; + MetaLogicalMonitor *monitor; + + manager = meta_backend_get_monitor_manager (backend); + monitor = meta_monitor_manager_get_logical_monitor_from_number (manager, log_index); + + if (monitor == NULL) + { + return 0; + } + + return meta_x11_display_logical_monitor_to_xinerama_index (display->x11_display, monitor); + } \ No newline at end of file diff --git a/src/meta/display.h b/src/meta/display.h index fa208f2f4..961d8b38d 100644 --- a/src/meta/display.h +++ b/src/meta/display.h @@ -289,6 +289,14 @@ META_EXPORT void meta_display_focus_default_window (MetaDisplay *display, guint32 timestamp); +META_EXPORT +gint meta_display_xinerama_index_to_logical_index (MetaDisplay *display, + gint x_index); + +META_EXPORT +gint meta_display_logical_index_to_xinerama_index (MetaDisplay *display, + gint log_index); + /** * MetaDisplayCorner: * @META_DISPLAY_TOPLEFT: top-left corner diff --git a/src/meta/meta-monitor-manager.h b/src/meta/meta-monitor-manager.h index 033309cc8..95c539ce1 100644 --- a/src/meta/meta-monitor-manager.h +++ b/src/meta/meta-monitor-manager.h @@ -33,6 +33,14 @@ typedef enum META_MONITOR_SWITCH_CONFIG_UNKNOWN, } MetaMonitorSwitchConfigType; +typedef enum +{ + META_XRANDR_ROTATION_NORMAL, + META_XRANDR_ROTATION_LEFT, + META_XRANDR_ROTATION_FLIPPED, + META_XRANDR_ROTATION_RIGHT +} MetaXrandrRotation; + typedef struct _MetaMonitorManagerClass MetaMonitorManagerClass; typedef struct _MetaMonitorManager MetaMonitorManager; @@ -62,4 +70,12 @@ MetaMonitorSwitchConfigType meta_monitor_manager_get_switch_config (MetaMonitorM META_EXPORT gint meta_monitor_manager_get_display_configuration_timeout (void); +META_EXPORT +gboolean meta_monitor_manager_can_apply_rotation (MetaMonitorManager *manager, MetaXrandrRotation rotation); + +META_EXPORT +gboolean meta_monitor_manager_apply_temporary_rotation (MetaMonitorManager *manager, MetaXrandrRotation rotation); + +META_EXPORT +gboolean meta_monitor_manager_get_current_rotation (MetaMonitorManager *manager, MetaXrandrRotation *rotation); #endif /* META_MONITOR_MANAGER_H */